Cross-merge bpf fixes after downstream PR. No conflicts. Adjacent changes in: include/linux/bpf.h include/uapi/linux/bpf.h kernel/bpf/btf.c kernel/bpf/helpers.c kernel/bpf/syscall.c kernel/bpf/verifier.c kernel/trace/bpf_trace.c mm/slab_common.c tools/include/uapi/linux/bpf.h tools/testing/selftests/bpf/Makefile
Unified · Split
| @@ -73,6 +73,8 @@ Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> · 72 unmodified lines | ||
| 73 | 73 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> |
| 74 | 74 | André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> |
| 75 | 75 | Andy Adamson <andros@citi.umich.edu> |
| 76 | +Andy Chiu <andybnac@gmail.com> <andy.chiu@sifive.com> | |
| 77 | +Andy Chiu <andybnac@gmail.com> <taochiu@synology.com> | |
| 76 | 78 | Andy Shevchenko <andy@kernel.org> <andy@smile.org.ua> |
| 77 | 79 | Andy Shevchenko <andy@kernel.org> <ext-andriy.shevchenko@nokia.com> |
| 78 | 80 | Anilkumar Kolli <quic_akolli@quicinc.com> <akolli@codeaurora.org> |
| @@ -203,12 +205,16 @@ Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> <ezequiel@collabora.com> · 124 unmodified lines | ||
| 203 | 205 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net> |
| 204 | 206 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@intel.com> |
| 205 | 207 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com> |
| 208 | +Fangrui Song <i@maskray.me> <maskray@google.com> | |
| 206 | 209 | Felipe W Damasio <felipewd@terra.com.br> |
| 207 | 210 | Felix Kuhling <fxkuehl@gmx.de> |
| 208 | 211 | Felix Moeller <felix@derklecks.de> |
| 209 | 212 | Fenglin Wu <quic_fenglinw@quicinc.com> <fenglinw@codeaurora.org> |
| 210 | 213 | Filipe Lautert <filipe@icewall.org> |
| 211 | 214 | Finn Thain <fthain@linux-m68k.org> <fthain@telegraphics.com.au> |
| 215 | +Fiona Behrens <me@kloenk.dev> | |
| 216 | +Fiona Behrens <me@kloenk.dev> <me@kloenk.de> | |
| 217 | +Fiona Behrens <me@kloenk.dev> <fin@nyantec.com> | |
| 212 | 218 | Franck Bui-Huu <vagabon.xyz@gmail.com> |
| 213 | 219 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> |
| 214 | 220 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@sony.com> |
| @@ -300,6 +306,11 @@ Jens Axboe <axboe@kernel.dk> <axboe@fb.com> · 85 unmodified lines | ||
| 300 | 306 | Jens Axboe <axboe@kernel.dk> <axboe@meta.com> |
| 301 | 307 | Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
| 302 | 308 | Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net> |
| 309 | +Jesper Dangaard Brouer <hawk@kernel.org> <brouer@redhat.com> | |
| 310 | +Jesper Dangaard Brouer <hawk@kernel.org> <hawk@comx.dk> | |
| 311 | +Jesper Dangaard Brouer <hawk@kernel.org> <jbrouer@redhat.com> | |
| 312 | +Jesper Dangaard Brouer <hawk@kernel.org> <jdb@comx.dk> | |
| 313 | +Jesper Dangaard Brouer <hawk@kernel.org> <netoptimizer@brouer.com> | |
| 303 | 314 | Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org> |
| 304 | 315 | Jilai Wang <quic_jilaiw@quicinc.com> <jilaiw@codeaurora.org> |
| 305 | 316 | Jiri Kosina <jikos@kernel.org> <jikos@jikos.cz> |
| @@ -1358,10 +1358,6 @@ D: Major kbuild rework during the 2.5 cycle · 1357 unmodified lines | ||
| 1358 | 1358 | D: ISDN Maintainer |
| 1359 | 1359 | S: USA |
| 1360 | 1360 | |
| 1361 | −N: Gerrit Renker | |
| 1362 | −E: gerrit@erg.abdn.ac.uk | |
| 1363 | −D: DCCP protocol support. | |
| 1364 | − | |
| 1365 | 1361 | N: Philip Gladstone |
| 1366 | 1362 | E: philip@gladstonefamily.net |
| 1367 | 1363 | D: Kernel / timekeeping stuff |
| @@ -1677,11 +1673,6 @@ W: http://www.carumba.com/ · 309 unmodified lines | ||
| 1677 | 1673 | D: bug toaster (A1 sauce makes all the difference) |
| 1678 | 1674 | D: Random linux hacker |
| 1679 | 1675 | |
| 1680 | −N: James Hogan | |
| 1681 | −E: jhogan@kernel.org | |
| 1682 | −D: Metag architecture maintainer | |
| 1683 | −D: TZ1090 SoC maintainer | |
| 1684 | − | |
| 1685 | 1676 | N: Tim Hockin |
| 1686 | 1677 | E: thockin@hockin.org |
| 1687 | 1678 | W: http://www.hockin.org/~thockin |
| @@ -1697,6 +1688,11 @@ D: hwmon subsystem maintainer · 9 unmodified lines | ||
| 1697 | 1688 | D: i2c-sis96x and i2c-stub SMBus drivers |
| 1698 | 1689 | S: USA |
| 1699 | 1690 | |
| 1691 | +N: James Hogan | |
| 1692 | +E: jhogan@kernel.org | |
| 1693 | +D: Metag architecture maintainer | |
| 1694 | +D: TZ1090 SoC maintainer | |
| 1695 | + | |
| 1700 | 1696 | N: Dirk Hohndel |
| 1701 | 1697 | E: hohndel@suse.de |
| 1702 | 1698 | D: The XFree86[tm] Project |
| @@ -1872,6 +1868,10 @@ S: K osmidomkum 723 · 169 unmodified lines | ||
| 1872 | 1868 | S: 160 00 Praha 6 |
| 1873 | 1869 | S: Czech Republic |
| 1874 | 1870 | |
| 1871 | +N: Seth Jennings | |
| 1872 | +E: sjenning@redhat.com | |
| 1873 | +D: Creation and maintenance of zswap | |
| 1874 | + | |
| 1875 | 1875 | N: Jeremy Kerr |
| 1876 | 1876 | D: Maintainer of SPU File System |
| 1877 | 1877 | |
| @@ -2188,19 +2188,6 @@ N: Mike Kravetz · 310 unmodified lines | ||
| 2188 | 2188 | E: mike.kravetz@oracle.com |
| 2189 | 2189 | D: Maintenance and development of the hugetlb subsystem |
| 2190 | 2190 | |
| 2191 | −N: Seth Jennings | |
| 2192 | −E: sjenning@redhat.com | |
| 2193 | −D: Creation and maintenance of zswap | |
| 2194 | − | |
| 2195 | −N: Dan Streetman | |
| 2196 | −E: ddstreet@ieee.org | |
| 2197 | −D: Maintenance and development of zswap | |
| 2198 | −D: Creation and maintenance of the zpool API | |
| 2199 | − | |
| 2200 | −N: Vitaly Wool | |
| 2201 | −E: vitaly.wool@konsulko.com | |
| 2202 | −D: Maintenance and development of zswap | |
| 2203 | − | |
| 2204 | 2191 | N: Andreas S. Krebs |
| 2205 | 2192 | E: akrebs@altavista.net |
| 2206 | 2193 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards |
| @@ -3191,6 +3178,11 @@ N: Ken Pizzini · 984 unmodified lines | ||
| 3191 | 3178 | E: ken@halcyon.com |
| 3192 | 3179 | D: CDROM driver "sonycd535" (Sony CDU-535/531) |
| 3193 | 3180 | |
| 3181 | +N: Mathieu Poirier | |
| 3182 | +E: mathieu.poirier@linaro.org | |
| 3183 | +D: CoreSight kernel subsystem, Maintainer 2014-2022 | |
| 3184 | +D: Perf tool support for CoreSight | |
| 3185 | + | |
| 3194 | 3186 | N: Stelian Pop |
| 3195 | 3187 | E: stelian@popies.net |
| 3196 | 3188 | P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0 D3F7 7185 9E7A EDBB 6147 |
| @@ -3300,6 +3292,10 @@ S: Schlossbergring 9 · 103 unmodified lines | ||
| 3300 | 3292 | S: 79098 Freiburg |
| 3301 | 3293 | S: Germany |
| 3302 | 3294 | |
| 3295 | +N: Gerrit Renker | |
| 3296 | +E: gerrit@erg.abdn.ac.uk | |
| 3297 | +D: DCCP protocol support. | |
| 3298 | + | |
| 3303 | 3299 | N: Thomas Renninger |
| 3304 | 3300 | E: trenn@suse.de |
| 3305 | 3301 | D: cpupowerutils |
| @@ -3576,11 +3572,6 @@ D: several improvements to system programs · 270 unmodified lines | ||
| 3576 | 3572 | S: Oldenburg |
| 3577 | 3573 | S: Germany |
| 3578 | 3574 | |
| 3579 | −N: Mathieu Poirier | |
| 3580 | −E: mathieu.poirier@linaro.org | |
| 3581 | −D: CoreSight kernel subsystem, Maintainer 2014-2022 | |
| 3582 | −D: Perf tool support for CoreSight | |
| 3583 | − | |
| 3584 | 3575 | N: Robert Schwebel |
| 3585 | 3576 | E: robert@schwebel.de |
| 3586 | 3577 | W: https://www.schwebel.de |
| @@ -3771,6 +3762,11 @@ S: Chr. Winthersvej 1 B, st.th. · 184 unmodified lines | ||
| 3771 | 3762 | S: DK-1860 Frederiksberg C |
| 3772 | 3763 | S: Denmark |
| 3773 | 3764 | |
| 3765 | +N: Dan Streetman | |
| 3766 | +E: ddstreet@ieee.org | |
| 3767 | +D: Maintenance and development of zswap | |
| 3768 | +D: Creation and maintenance of the zpool API | |
| 3769 | + | |
| 3774 | 3770 | N: Drew Sullivan |
| 3775 | 3771 | E: drew@ss.org |
| 3776 | 3772 | W: http://www.ss.org/ |
| @@ -4286,6 +4282,10 @@ S: Pipers Way · 509 unmodified lines | ||
| 4286 | 4282 | S: Swindon. SN3 1RJ |
| 4287 | 4283 | S: England |
| 4288 | 4284 | |
| 4285 | +N: Vitaly Wool | |
| 4286 | +E: vitaly.wool@konsulko.com | |
| 4287 | +D: Maintenance and development of zswap | |
| 4288 | + | |
| 4289 | 4289 | N: Chris Wright |
| 4290 | 4290 | E: chrisw@sous-sol.org |
| 4291 | 4291 | D: hacking on LSM framework and security modules. |
| @@ -223,7 +223,10 @@ are signed through the PKCS#7 message format to enforce some level of · 222 unmodified lines | ||
| 223 | 223 | authorization of the policies (prohibiting an attacker from gaining |
| 224 | 224 | unconstrained root, and deploying an "allow all" policy). These |
| 225 | 225 | policies must be signed by a certificate that chains to the |
| 226 | −``SYSTEM_TRUSTED_KEYRING``. With openssl, the policy can be signed by:: | |
| 226 | +``SYSTEM_TRUSTED_KEYRING``, or to the secondary and/or platform keyrings if | |
| 227 | +``CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING`` and/or | |
| 228 | +``CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING`` are enabled, respectively. | |
| 229 | +With openssl, the policy can be signed by:: | |
| 227 | 230 | |
| 228 | 231 | openssl smime -sign \ |
| 229 | 232 | -in "$MY_POLICY" \ |
| @@ -266,7 +269,7 @@ in the kernel. This file is write-only and accepts a PKCS#7 signed · 36 unmodified lines | ||
| 266 | 269 | policy. Two checks will always be performed on this policy: First, the |
| 267 | 270 | ``policy_names`` must match with the updated version and the existing |
| 268 | 271 | version. Second the updated policy must have a policy version greater than |
| 269 | −or equal to the currently-running version. This is to prevent rollback attacks. | |
| 272 | +the currently-running version. This is to prevent rollback attacks. | |
| 270 | 273 | |
| 271 | 274 | The ``delete`` file is used to remove a policy that is no longer needed. |
| 272 | 275 | This file is write-only and accepts a value of ``1`` to delete the policy. |
| @@ -146,6 +146,8 @@ stable kernels. · 145 unmodified lines | ||
| 146 | 146 | +----------------+-----------------+-----------------+-----------------------------+ |
| 147 | 147 | | ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 | |
| 148 | 148 | +----------------+-----------------+-----------------+-----------------------------+ |
| 149 | +| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 | | |
| 150 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 149 | 151 | | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | |
| 150 | 152 | +----------------+-----------------+-----------------+-----------------------------+ |
| 151 | 153 | | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | |
| @@ -186,6 +188,8 @@ stable kernels. · 34 unmodified lines | ||
| 186 | 188 | +----------------+-----------------+-----------------+-----------------------------+ |
| 187 | 189 | | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | |
| 188 | 190 | +----------------+-----------------+-----------------+-----------------------------+ |
| 191 | +| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 | | |
| 192 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 189 | 193 | | ARM | Neoverse-V1 | #1619801 | N/A | |
| 190 | 194 | +----------------+-----------------+-----------------+-----------------------------+ |
| 191 | 195 | | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | |
| @@ -289,3 +293,5 @@ stable kernels. · 97 unmodified lines | ||
| 289 | 293 | +----------------+-----------------+-----------------+-----------------------------+ |
| 290 | 294 | | Microsoft | Azure Cobalt 100| #2253138 | ARM64_ERRATUM_2253138 | |
| 291 | 295 | +----------------+-----------------+-----------------+-----------------------------+ |
| 296 | +| Microsoft | Azure Cobalt 100| #3324339 | ARM64_ERRATUM_3194386 | | |
| 297 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| @@ -12,7 +12,10 @@ Pkeys Userspace (PKU) is a feature which can be found on: · 11 unmodified lines | ||
| 12 | 12 | * Intel server CPUs, Skylake and later |
| 13 | 13 | * Intel client CPUs, Tiger Lake (11th Gen Core) and later |
| 14 | 14 | * Future AMD CPUs |
| 15 | + * arm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE) | |
| 15 | 16 | |
| 17 | +x86_64 | |
| 18 | +====== | |
| 16 | 19 | Pkeys work by dedicating 4 previously Reserved bits in each page table entry to |
| 17 | 20 | a "protection key", giving 16 possible keys. |
| 18 | 21 | |
| @@ -28,6 +31,22 @@ register. The feature is only available in 64-bit mode, even though there is · 9 unmodified lines | ||
| 28 | 31 | theoretically space in the PAE PTEs. These permissions are enforced on data |
| 29 | 32 | access only and have no effect on instruction fetches. |
| 30 | 33 | |
| 34 | +arm64 | |
| 35 | +===== | |
| 36 | + | |
| 37 | +Pkeys use 3 bits in each page table entry, to encode a "protection key index", | |
| 38 | +giving 8 possible keys. | |
| 39 | + | |
| 40 | +Protections for each key are defined with a per-CPU user-writable system | |
| 41 | +register (POR_EL0). This is a 64-bit register encoding read, write and execute | |
| 42 | +overlay permissions for each protection key index. | |
| 43 | + | |
| 44 | +Being a CPU register, POR_EL0 is inherently thread-local, potentially giving | |
| 45 | +each thread a different set of protections from every other thread. | |
| 46 | + | |
| 47 | +Unlike x86_64, the protection key permissions also apply to instruction | |
| 48 | +fetches. | |
| 49 | + | |
| 31 | 50 | Syscalls |
| 32 | 51 | ======== |
| 33 | 52 | |
| @@ -38,11 +57,10 @@ There are 3 system calls which directly interact with pkeys:: · 4 unmodified lines | ||
| 38 | 57 | int pkey_mprotect(unsigned long start, size_t len, |
| 39 | 58 | unsigned long prot, int pkey); |
| 40 | 59 | |
| 41 | −Before a pkey can be used, it must first be allocated with | |
| 42 | −pkey_alloc(). An application calls the WRPKRU instruction | |
| 43 | −directly in order to change access permissions to memory covered | |
| 44 | −with a key. In this example WRPKRU is wrapped by a C function | |
| 45 | −called pkey_set(). | |
| 60 | +Before a pkey can be used, it must first be allocated with pkey_alloc(). An | |
| 61 | +application writes to the architecture specific CPU register directly in order | |
| 62 | +to change access permissions to memory covered with a key. In this example | |
| 63 | +this is wrapped by a C function called pkey_set(). | |
| 46 | 64 | :: |
| 47 | 65 | |
| 48 | 66 | int real_prot = PROT_READ|PROT_WRITE; |
| @@ -64,9 +82,9 @@ is no longer in use:: · 15 unmodified lines | ||
| 64 | 82 | munmap(ptr, PAGE_SIZE); |
| 65 | 83 | pkey_free(pkey); |
| 66 | 84 | |
| 67 | −.. note:: pkey_set() is a wrapper for the RDPKRU and WRPKRU instructions. | |
| 68 | − An example implementation can be found in | |
| 69 | − tools/testing/selftests/x86/protection_keys.c. | |
| 85 | +.. note:: pkey_set() is a wrapper around writing to the CPU register. | |
| 86 | + Example implementations can be found in | |
| 87 | + tools/testing/selftests/mm/pkey-{arm64,powerpc,x86}.h | |
| 70 | 88 | |
| 71 | 89 | Behavior |
| 72 | 90 | ======== |
| @@ -96,3 +114,7 @@ with a read():: · 23 unmodified lines | ||
| 96 | 114 | The kernel will send a SIGSEGV in both cases, but si_code will be set |
| 97 | 115 | to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when |
| 98 | 116 | the plain mprotect() permissions are violated. |
| 117 | + | |
| 118 | +Note that kernel accesses from a kthread (such as io_uring) will use a default | |
| 119 | +value for the protection key register and so will not be consistent with | |
| 120 | +userspace's value of the register or mprotect(). | |
| @@ -0,0 +1,54 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/display/elgin,jg10309-01.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Elgin JG10309-01 SPI-controlled display | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Fabio Estevam <festevam@gmail.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + The Elgin JG10309-01 SPI-controlled display is used on the RV1108-Elgin-r1 | |
| 14 | + board and is a custom display. | |
| 15 | + | |
| 16 | +allOf: | |
| 17 | + - $ref: /schemas/spi/spi-peripheral-props.yaml# | |
| 18 | + | |
| 19 | +properties: | |
| 20 | + compatible: | |
| 21 | + const: elgin,jg10309-01 | |
| 22 | + | |
| 23 | + reg: | |
| 24 | + maxItems: 1 | |
| 25 | + | |
| 26 | + spi-max-frequency: | |
| 27 | + maximum: 24000000 | |
| 28 | + | |
| 29 | + spi-cpha: true | |
| 30 | + | |
| 31 | + spi-cpol: true | |
| 32 | + | |
| 33 | +required: | |
| 34 | + - compatible | |
| 35 | + - reg | |
| 36 | + - spi-cpha | |
| 37 | + - spi-cpol | |
| 38 | + | |
| 39 | +additionalProperties: false | |
| 40 | + | |
| 41 | +examples: | |
| 42 | + - | | |
| 43 | + spi { | |
| 44 | + #address-cells = <1>; | |
| 45 | + #size-cells = <0>; | |
| 46 | + | |
| 47 | + display@0 { | |
| 48 | + compatible = "elgin,jg10309-01"; | |
| 49 | + reg = <0>; | |
| 50 | + spi-max-frequency = <24000000>; | |
| 51 | + spi-cpha; | |
| 52 | + spi-cpol; | |
| 53 | + }; | |
| 54 | + }; | |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml# |
| 5 | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | |
| 7 | −title: Analog Devices AD5360 and similar DACs | |
| 7 | +title: Analog Devices AD5360 and similar SPI DACs | |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | 10 | - Michael Hennerich <michael.hennerich@analog.com> |
| @@ -12,41 +12,22 @@ maintainers: · 1 unmodified line | ||
| 12 | 12 | |
| 13 | 13 | properties: |
| 14 | 14 | compatible: |
| 15 | − oneOf: | |
| 16 | − - description: SPI devices | |
| 17 | − enum: | |
| 18 | − - adi,ad5310r | |
| 19 | − - adi,ad5672r | |
| 20 | − - adi,ad5674r | |
| 21 | − - adi,ad5676 | |
| 22 | − - adi,ad5676r | |
| 23 | − - adi,ad5679r | |
| 24 | − - adi,ad5681r | |
| 25 | − - adi,ad5682r | |
| 26 | − - adi,ad5683 | |
| 27 | − - adi,ad5683r | |
| 28 | − - adi,ad5684 | |
| 29 | − - adi,ad5684r | |
| 30 | − - adi,ad5685r | |
| 31 | − - adi,ad5686 | |
| 32 | − - adi,ad5686r | |
| 33 | − - description: I2C devices | |
| 34 | − enum: | |
| 35 | − - adi,ad5311r | |
| 36 | − - adi,ad5337r | |
| 37 | − - adi,ad5338r | |
| 38 | − - adi,ad5671r | |
| 39 | − - adi,ad5675r | |
| 40 | − - adi,ad5691r | |
| 41 | − - adi,ad5692r | |
| 42 | − - adi,ad5693 | |
| 43 | − - adi,ad5693r | |
| 44 | − - adi,ad5694 | |
| 45 | − - adi,ad5694r | |
| 46 | − - adi,ad5695r | |
| 47 | − - adi,ad5696 | |
| 48 | − - adi,ad5696r | |
| 49 | − | |
| 15 | + enum: | |
| 16 | + - adi,ad5310r | |
| 17 | + - adi,ad5672r | |
| 18 | + - adi,ad5674r | |
| 19 | + - adi,ad5676 | |
| 20 | + - adi,ad5676r | |
| 21 | + - adi,ad5679r | |
| 22 | + - adi,ad5681r | |
| 23 | + - adi,ad5682r | |
| 24 | + - adi,ad5683 | |
| 25 | + - adi,ad5683r | |
| 26 | + - adi,ad5684 | |
| 27 | + - adi,ad5684r | |
| 28 | + - adi,ad5685r | |
| 29 | + - adi,ad5686 | |
| 30 | + - adi,ad5686r | |
| 50 | 31 | |
| 51 | 32 | reg: |
| 52 | 33 | maxItems: 1 |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5696.yaml# |
| 5 | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | |
| 7 | −title: Analog Devices AD5696 and similar multi-channel DACs | |
| 7 | +title: Analog Devices AD5696 and similar I2C multi-channel DACs | |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | 10 | - Michael Auchter <michael.auchter@ni.com> |
| @@ -16,6 +16,7 @@ properties: · 5 unmodified lines | ||
| 16 | 16 | compatible: |
| 17 | 17 | enum: |
| 18 | 18 | - adi,ad5311r |
| 19 | + - adi,ad5337r | |
| 19 | 20 | - adi,ad5338r |
| 20 | 21 | - adi,ad5671r |
| 21 | 22 | - adi,ad5675r |
| @@ -82,9 +82,6 @@ allOf: · 81 unmodified lines | ||
| 82 | 82 | enum: |
| 83 | 83 | - fsl,ls1043a-extirq |
| 84 | 84 | - fsl,ls1046a-extirq |
| 85 | − - fsl,ls1088a-extirq | |
| 86 | − - fsl,ls2080a-extirq | |
| 87 | − - fsl,lx2160a-extirq | |
| 88 | 85 | then: |
| 89 | 86 | properties: |
| 90 | 87 | interrupt-map: |
| @@ -95,6 +92,29 @@ allOf: · 4 unmodified lines | ||
| 95 | 92 | - const: 0xf |
| 96 | 93 | - const: 0 |
| 97 | 94 | |
| 95 | + - if: | |
| 96 | + properties: | |
| 97 | + compatible: | |
| 98 | + contains: | |
| 99 | + enum: | |
| 100 | + - fsl,ls1088a-extirq | |
| 101 | + - fsl,ls2080a-extirq | |
| 102 | + - fsl,lx2160a-extirq | |
| 103 | +# The driver(drivers/irqchip/irq-ls-extirq.c) have not use standard DT | |
| 104 | +# function to parser interrupt-map. So it doesn't consider '#address-size' | |
| 105 | +# in parent interrupt controller, such as GIC. | |
| 106 | +# | |
| 107 | +# When dt-binding verify interrupt-map, item data matrix is spitted at | |
| 108 | +# incorrect position. Remove interrupt-map restriction because it always | |
| 109 | +# wrong. | |
| 110 | + | |
| 111 | + then: | |
| 112 | + properties: | |
| 113 | + interrupt-map-mask: | |
| 114 | + items: | |
| 115 | + - const: 0xf | |
| 116 | + - const: 0 | |
| 117 | + | |
| 98 | 118 | additionalProperties: false |
| 99 | 119 | |
| 100 | 120 | examples: |
| @@ -113,7 +113,7 @@ properties: · 112 unmodified lines | ||
| 113 | 113 | |
| 114 | 114 | msi-parent: |
| 115 | 115 | deprecated: true |
| 116 | − $ref: /schemas/types.yaml#/definitions/phandle | |
| 116 | + maxItems: 1 | |
| 117 | 117 | description: |
| 118 | 118 | Describes the MSI controller node handling message |
| 119 | 119 | interrupts for the MC. When there is no translation |
| @@ -26,6 +26,7 @@ properties: · 25 unmodified lines | ||
| 26 | 26 | - brcm,asp-v2.1-mdio |
| 27 | 27 | - brcm,asp-v2.2-mdio |
| 28 | 28 | - brcm,unimac-mdio |
| 29 | + - brcm,bcm6846-mdio | |
| 29 | 30 | |
| 30 | 31 | reg: |
| 31 | 32 | minItems: 1 |
| @@ -102,7 +102,7 @@ properties: · 101 unmodified lines | ||
| 102 | 102 | default: 2 |
| 103 | 103 | |
| 104 | 104 | interrupts: |
| 105 | − anyOf: | |
| 105 | + oneOf: | |
| 106 | 106 | - minItems: 1 |
| 107 | 107 | items: |
| 108 | 108 | - description: TX interrupt |
| @@ -30,6 +30,7 @@ properties: · 29 unmodified lines | ||
| 30 | 30 | - qcom,apq8096-sndcard |
| 31 | 31 | - qcom,qcm6490-idp-sndcard |
| 32 | 32 | - qcom,qcs6490-rb3gen2-sndcard |
| 33 | + - qcom,qrb4210-rb2-sndcard | |
| 33 | 34 | - qcom,qrb5165-rb5-sndcard |
| 34 | 35 | - qcom,sc7180-qdsp6-sndcard |
| 35 | 36 | - qcom,sc8280xp-sndcard |
| @@ -302,7 +302,7 @@ allOf: · 301 unmodified lines | ||
| 302 | 302 | reg-names: |
| 303 | 303 | items: |
| 304 | 304 | enum: |
| 305 | − - scu | |
| 305 | + - sru | |
| 306 | 306 | - ssi |
| 307 | 307 | - adg |
| 308 | 308 | # for Gen2/Gen3 |
| @@ -101,8 +101,6 @@ properties: · 100 unmodified lines | ||
| 101 | 101 | - domintech,dmard09 |
| 102 | 102 | # DMARD10: 3-axis Accelerometer |
| 103 | 103 | - domintech,dmard10 |
| 104 | − # Elgin SPI-controlled LCD | |
| 105 | − - elgin,jg10309-01 | |
| 106 | 104 | # MMA7660FC: 3-Axis Orientation/Motion Detection Sensor |
| 107 | 105 | - fsl,mma7660 |
| 108 | 106 | # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer |
| @@ -7,12 +7,11 @@ WMI Driver API · 6 unmodified lines | ||
| 7 | 7 | The WMI driver core supports a more modern bus-based interface for interacting |
| 8 | 8 | with WMI devices, and an older GUID-based interface. The latter interface is |
| 9 | 9 | considered to be deprecated, so new WMI drivers should generally avoid it since |
| 10 | −it has some issues with multiple WMI devices and events sharing the same GUIDs | |
| 11 | −and/or notification IDs. The modern bus-based interface instead maps each | |
| 12 | −WMI device to a :c:type:`struct wmi_device <wmi_device>`, so it supports | |
| 13 | −WMI devices sharing GUIDs and/or notification IDs. Drivers can then register | |
| 14 | −a :c:type:`struct wmi_driver <wmi_driver>`, which will be bound to compatible | |
| 15 | −WMI devices by the driver core. | |
| 10 | +it has some issues with multiple WMI devices sharing the same GUID. | |
| 11 | +The modern bus-based interface instead maps each WMI device to a | |
| 12 | +:c:type:`struct wmi_device <wmi_device>`, so it supports WMI devices sharing the | |
| 13 | +same GUID. Drivers can then register a :c:type:`struct wmi_driver <wmi_driver>` | |
| 14 | +which will be bound to compatible WMI devices by the driver core. | |
| 16 | 15 | |
| 17 | 16 | .. kernel-doc:: include/linux/wmi.h |
| 18 | 17 | :internal: |
| @@ -208,7 +208,7 @@ The filesystem must arrange to `cancel · 207 unmodified lines | ||
| 208 | 208 | such `reservations |
| 209 | 209 | <https://lore.kernel.org/linux-xfs/20220817093627.GZ3600936@dread.disaster.area/>`_ |
| 210 | 210 | because writeback will not consume the reservation. |
| 211 | −The ``iomap_file_buffered_write_punch_delalloc`` can be called from a | |
| 211 | +The ``iomap_write_delalloc_release`` can be called from a | |
| 212 | 212 | ``->iomap_end`` function to find all the clean areas of the folios |
| 213 | 213 | caching a fresh (``IOMAP_F_NEW``) delalloc mapping. |
| 214 | 214 | It takes the ``invalidate_lock``. |
| @@ -592,4 +592,3 @@ API Function Reference · 591 unmodified lines | ||
| 592 | 592 | |
| 593 | 593 | .. kernel-doc:: include/linux/netfs.h |
| 594 | 594 | .. kernel-doc:: fs/netfs/buffered_read.c |
| 595 | −.. kernel-doc:: fs/netfs/io.c | |
| @@ -181,7 +181,7 @@ Bridge Operations · 180 unmodified lines | ||
| 181 | 181 | Bridge Connector Helper |
| 182 | 182 | ----------------------- |
| 183 | 183 | |
| 184 | −.. kernel-doc:: drivers/gpu/drm/drm_bridge_connector.c | |
| 184 | +.. kernel-doc:: drivers/gpu/drm/display/drm_bridge_connector.c | |
| 185 | 185 | :doc: overview |
| 186 | 186 | |
| 187 | 187 | |
| @@ -204,7 +204,7 @@ MIPI-DSI bridge operation · 16 unmodified lines | ||
| 204 | 204 | Bridge Connector Helper Reference |
| 205 | 205 | --------------------------------- |
| 206 | 206 | |
| 207 | −.. kernel-doc:: drivers/gpu/drm/drm_bridge_connector.c | |
| 207 | +.. kernel-doc:: drivers/gpu/drm/display/drm_bridge_connector.c | |
| 208 | 208 | :export: |
| 209 | 209 | |
| 210 | 210 | Panel-Bridge Helper Reference |
| @@ -7,26 +7,26 @@ The DAMON subsystem covers the files that are listed in 'DATA ACCESS MONITOR' · 6 unmodified lines | ||
| 7 | 7 | section of 'MAINTAINERS' file. |
| 8 | 8 | |
| 9 | 9 | The mailing lists for the subsystem are damon@lists.linux.dev and |
| 10 | −linux-mm@kvack.org. Patches should be made against the mm-unstable `tree | |
| 11 | −<https://git.kernel.org/akpm/mm/h/mm-unstable>` whenever possible and posted to | |
| 12 | −the mailing lists. | |
| 10 | +linux-mm@kvack.org. Patches should be made against the `mm-unstable tree | |
| 11 | +<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ whenever possible and posted | |
| 12 | +to the mailing lists. | |
| 13 | 13 | |
| 14 | 14 | SCM Trees |
| 15 | 15 | --------- |
| 16 | 16 | |
| 17 | 17 | There are multiple Linux trees for DAMON development. Patches under |
| 18 | 18 | development or testing are queued in `damon/next |
| 19 | −<https://git.kernel.org/sj/h/damon/next>` by the DAMON maintainer. | |
| 19 | +<https://git.kernel.org/sj/h/damon/next>`_ by the DAMON maintainer. | |
| 20 | 20 | Sufficiently reviewed patches will be queued in `mm-unstable |
| 21 | −<https://git.kernel.org/akpm/mm/h/mm-unstable>` by the memory management | |
| 21 | +<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ by the memory management | |
| 22 | 22 | subsystem maintainer. After more sufficient tests, the patches will be queued |
| 23 | −in `mm-stable <https://git.kernel.org/akpm/mm/h/mm-stable>` , and finally | |
| 23 | +in `mm-stable <https://git.kernel.org/akpm/mm/h/mm-stable>`_, and finally | |
| 24 | 24 | pull-requested to the mainline by the memory management subsystem maintainer. |
| 25 | 25 | |
| 26 | −Note again the patches for mm-unstable `tree | |
| 27 | −<https://git.kernel.org/akpm/mm/h/mm-unstable>` are queued by the memory | |
| 26 | +Note again the patches for `mm-unstable tree | |
| 27 | +<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ are queued by the memory | |
| 28 | 28 | management subsystem maintainer. If the patches requires some patches in |
| 29 | −damon/next `tree <https://git.kernel.org/sj/h/damon/next>` which not yet merged | |
| 29 | +`damon/next tree <https://git.kernel.org/sj/h/damon/next>`_ which not yet merged | |
| 30 | 30 | in mm-unstable, please make sure the requirement is clearly specified. |
| 31 | 31 | |
| 32 | 32 | Submit checklist addendum |
| @@ -37,25 +37,25 @@ When making DAMON changes, you should do below. · 4 unmodified lines | ||
| 37 | 37 | - Build changes related outputs including kernel and documents. |
| 38 | 38 | - Ensure the builds introduce no new errors or warnings. |
| 39 | 39 | - Run and ensure no new failures for DAMON `selftests |
| 40 | − <https://github.com/awslabs/damon-tests/blob/master/corr/run.sh#L49>` and | |
| 40 | + <https://github.com/damonitor/damon-tests/blob/master/corr/run.sh#L49>`_ and | |
| 41 | 41 | `kunittests |
| 42 | − <https://github.com/awslabs/damon-tests/blob/master/corr/tests/kunit.sh>`. | |
| 42 | + <https://github.com/damonitor/damon-tests/blob/master/corr/tests/kunit.sh>`_. | |
| 43 | 43 | |
| 44 | 44 | Further doing below and putting the results will be helpful. |
| 45 | 45 | |
| 46 | 46 | - Run `damon-tests/corr |
| 47 | − <https://github.com/awslabs/damon-tests/tree/master/corr>` for normal | |
| 47 | + <https://github.com/damonitor/damon-tests/tree/master/corr>`_ for normal | |
| 48 | 48 | changes. |
| 49 | 49 | - Run `damon-tests/perf |
| 50 | − <https://github.com/awslabs/damon-tests/tree/master/perf>` for performance | |
| 50 | + <https://github.com/damonitor/damon-tests/tree/master/perf>`_ for performance | |
| 51 | 51 | changes. |
| 52 | 52 | |
| 53 | 53 | Key cycle dates |
| 54 | 54 | --------------- |
| 55 | 55 | |
| 56 | 56 | Patches can be sent anytime. Key cycle dates of the `mm-unstable |
| 57 | −<https://git.kernel.org/akpm/mm/h/mm-unstable>` and `mm-stable | |
| 58 | −<https://git.kernel.org/akpm/mm/h/mm-stable>` trees depend on the memory | |
| 57 | +<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ and `mm-stable | |
| 58 | +<https://git.kernel.org/akpm/mm/h/mm-stable>`_ trees depend on the memory | |
| 59 | 59 | management subsystem maintainer. |
| 60 | 60 | |
| 61 | 61 | Review cadence |
| @@ -72,13 +72,13 @@ Mailing tool · 10 unmodified lines | ||
| 72 | 72 | Like many other Linux kernel subsystems, DAMON uses the mailing lists |
| 73 | 73 | (damon@lists.linux.dev and linux-mm@kvack.org) as the major communication |
| 74 | 74 | channel. There is a simple tool called `HacKerMaiL |
| 75 | −<https://github.com/damonitor/hackermail>` (``hkml``), which is for people who | |
| 75 | +<https://github.com/damonitor/hackermail>`_ (``hkml``), which is for people who | |
| 76 | 76 | are not very familiar with the mailing lists based communication. The tool |
| 77 | 77 | could be particularly helpful for DAMON community members since it is developed |
| 78 | 78 | and maintained by DAMON maintainer. The tool is also officially announced to |
| 79 | 79 | support DAMON and general Linux kernel development workflow. |
| 80 | 80 | |
| 81 | −In other words, `hkml <https://github.com/damonitor/hackermail>` is a mailing | |
| 81 | +In other words, `hkml <https://github.com/damonitor/hackermail>`_ is a mailing | |
| 82 | 82 | tool for DAMON community, which DAMON maintainer is committed to support. |
| 83 | 83 | Please feel free to try and report issues or feature requests for the tool to |
| 84 | 84 | the maintainer. |
| @@ -98,8 +98,8 @@ slots, and attendees should reserve one of those at least 24 hours before the · 13 unmodified lines | ||
| 98 | 98 | time slot, by reaching out to the maintainer. |
| 99 | 99 | |
| 100 | 100 | Schedules and available reservation time slots are available at the Google `doc |
| 101 | −<https://docs.google.com/document/d/1v43Kcj3ly4CYqmAkMaZzLiM2GEnWfgdGbZAH3mi2vpM/edit?usp=sharing>`. | |
| 101 | +<https://docs.google.com/document/d/1v43Kcj3ly4CYqmAkMaZzLiM2GEnWfgdGbZAH3mi2vpM/edit?usp=sharing>`_. | |
| 102 | 102 | There is also a public Google `calendar |
| 103 | −<https://calendar.google.com/calendar/u/0?cid=ZDIwOTA4YTMxNjc2MDQ3NTIyMmUzYTM5ZmQyM2U4NDA0ZGIwZjBiYmJlZGQxNDM0MmY4ZTRjOTE0NjdhZDRiY0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t>` | |
| 103 | +<https://calendar.google.com/calendar/u/0?cid=ZDIwOTA4YTMxNjc2MDQ3NTIyMmUzYTM5ZmQyM2U4NDA0ZGIwZjBiYmJlZGQxNDM0MmY4ZTRjOTE0NjdhZDRiY0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t>`_ | |
| 104 | 104 | that has the events. Anyone can subscribe it. DAMON maintainer will also |
| 105 | 105 | provide periodic reminder to the mailing list (damon@lists.linux.dev). |
| @@ -9,7 +9,7 @@ segments between trusted peers. It adds a new TCP header option with · 8 unmodified lines | ||
| 9 | 9 | a Message Authentication Code (MAC). MACs are produced from the content |
| 10 | 10 | of a TCP segment using a hashing function with a password known to both peers. |
| 11 | 11 | The intent of TCP-AO is to deprecate TCP-MD5 providing better security, |
| 12 | −key rotation and support for variety of hashing algorithms. | |
| 12 | +key rotation and support for a variety of hashing algorithms. | |
| 13 | 13 | |
| 14 | 14 | 1. Introduction |
| 15 | 15 | =============== |
| @@ -164,9 +164,9 @@ A: It should not, no action needs to be performed [7.5.2.e]:: · 148 unmodified lines | ||
| 164 | 164 | is not available, no action is required (RNextKeyID of a received |
| 165 | 165 | segment needs to match the MKT’s SendID). |
| 166 | 166 | |
| 167 | −Q: How current_key is set and when does it change? It is a user-triggered | |
| 168 | −change, or is it by a request from the remote peer? Is it set by the user | |
| 169 | −explicitly, or by a matching rule? | |
| 167 | +Q: How is current_key set, and when does it change? Is it a user-triggered | |
| 168 | +change, or is it triggered by a request from the remote peer? Is it set by the | |
| 169 | +user explicitly, or by a matching rule? | |
| 170 | 170 | |
| 171 | 171 | A: current_key is set by RNextKeyID [6.1]:: |
| 172 | 172 | |
| @@ -233,8 +233,8 @@ always have one current_key [3.3]:: · 60 unmodified lines | ||
| 233 | 233 | |
| 234 | 234 | Q: Can a non-TCP-AO connection become a TCP-AO-enabled one? |
| 235 | 235 | |
| 236 | −A: No: for already established non-TCP-AO connection it would be impossible | |
| 237 | −to switch using TCP-AO as the traffic key generation requires the initial | |
| 236 | +A: No: for an already established non-TCP-AO connection it would be impossible | |
| 237 | +to switch to using TCP-AO, as the traffic key generation requires the initial | |
| 238 | 238 | sequence numbers. Paraphrasing, starting using TCP-AO would require |
| 239 | 239 | re-establishing the TCP connection. |
| 240 | 240 | |
| @@ -292,7 +292,7 @@ no transparency is really needed and modern BGP daemons already have · 51 unmodified lines | ||
| 292 | 292 | |
| 293 | 293 | Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let |
| 294 | 294 | userspace manage TCP-AO on a per-socket basis. In order to add/delete MKTs |
| 295 | −``TCP_AO_ADD_KEY`` and ``TCP_AO_DEL_KEY`` TCP socket options must be used | |
| 295 | +``TCP_AO_ADD_KEY`` and ``TCP_AO_DEL_KEY`` TCP socket options must be used. | |
| 296 | 296 | It is not allowed to add a key on an established non-TCP-AO connection |
| 297 | 297 | as well as to remove the last key from TCP-AO connection. |
| 298 | 298 | |
| @@ -361,7 +361,7 @@ not implemented. · 62 unmodified lines | ||
| 361 | 361 | 4. ``setsockopt()`` vs ``accept()`` race |
| 362 | 362 | ======================================== |
| 363 | 363 | |
| 364 | −In contrast with TCP-MD5 established connection which has just one key, | |
| 364 | +In contrast with an established TCP-MD5 connection which has just one key, | |
| 365 | 365 | TCP-AO connections may have many keys, which means that accepted connections |
| 366 | 366 | on a listen socket may have any amount of keys as well. As copying all those |
| 367 | 367 | keys on a first properly signed SYN would make the request socket bigger, that |
| @@ -374,7 +374,7 @@ keys from sockets that were already established, but not yet ``accept()``'ed, · 6 unmodified lines | ||
| 374 | 374 | hanging in the accept queue. |
| 375 | 375 | |
| 376 | 376 | The reverse is valid as well: if userspace adds a new key for a peer on |
| 377 | −a listener socket, the established sockets in accept queue won't | |
| 377 | +a listener socket, the established sockets in the accept queue won't | |
| 378 | 378 | have the new keys. |
| 379 | 379 | |
| 380 | 380 | At this moment, the resolution for the two races: |
| @@ -382,7 +382,7 @@ At this moment, the resolution for the two races: · 1 unmodified line | ||
| 382 | 382 | and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace. |
| 383 | 383 | This means that it's expected that userspace would check the MKTs on the socket |
| 384 | 384 | that was returned by ``accept()`` to verify that any key rotation that |
| 385 | −happened on listen socket is reflected on the newly established connection. | |
| 385 | +happened on the listen socket is reflected on the newly established connection. | |
| 386 | 386 | |
| 387 | 387 | This is a similar "do-nothing" approach to TCP-MD5 from the kernel side and |
| 388 | 388 | may be changed later by introducing new flags to ``tcp_ao_add`` |
| @@ -355,6 +355,8 @@ just do it. As a result, a sequence of smaller series gets merged quicker and · 354 unmodified lines | ||
| 355 | 355 | with better review coverage. Re-posting large series also increases the mailing |
| 356 | 356 | list traffic. |
| 357 | 357 | |
| 358 | +.. _rcs: | |
| 359 | + | |
| 358 | 360 | Local variable ordering ("reverse xmas tree", "RCS") |
| 359 | 361 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 360 | 362 | |
| @@ -391,6 +393,21 @@ APIs and helpers, especially scoped iterators. However, direct use of · 30 unmodified lines | ||
| 391 | 393 | ``__free()`` within networking core and drivers is discouraged. |
| 392 | 394 | Similar guidance applies to declaring variables mid-function. |
| 393 | 395 | |
| 396 | +Clean-up patches | |
| 397 | +~~~~~~~~~~~~~~~~ | |
| 398 | + | |
| 399 | +Netdev discourages patches which perform simple clean-ups, which are not in | |
| 400 | +the context of other work. For example: | |
| 401 | + | |
| 402 | +* Addressing ``checkpatch.pl`` warnings | |
| 403 | +* Addressing :ref:`Local variable ordering<rcs>` issues | |
| 404 | +* Conversions to device-managed APIs (``devm_`` helpers) | |
| 405 | + | |
| 406 | +This is because it is felt that the churn that such changes produce comes | |
| 407 | +at a greater cost than the value of such clean-ups. | |
| 408 | + | |
| 409 | +Conversely, spelling and grammar fixes are not discouraged. | |
| 410 | + | |
| 394 | 411 | Resending after review |
| 395 | 412 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 396 | 413 | |
| @@ -30,10 +30,13 @@ tree as a dedicated branch covering multiple subsystems. · 29 unmodified lines | ||
| 30 | 30 | The main SoC tree is housed on git.kernel.org: |
| 31 | 31 | https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/ |
| 32 | 32 | |
| 33 | +Maintainers | |
| 34 | +----------- | |
| 35 | + | |
| 33 | 36 | Clearly this is quite a wide range of topics, which no one person, or even |
| 34 | 37 | small group of people are capable of maintaining. Instead, the SoC subsystem |
| 35 | −is comprised of many submaintainers, each taking care of individual platforms | |
| 36 | −and driver subdirectories. | |
| 38 | +is comprised of many submaintainers (platform maintainers), each taking care of | |
| 39 | +individual platforms and driver subdirectories. | |
| 37 | 40 | In this regard, "platform" usually refers to a series of SoCs from a given |
| 38 | 41 | vendor, for example, Nvidia's series of Tegra SoCs. Many submaintainers operate |
| 39 | 42 | on a vendor level, responsible for multiple product lines. For several reasons, |
| @@ -43,14 +46,43 @@ MAINTAINERS file. · 3 unmodified lines | ||
| 43 | 46 | |
| 44 | 47 | Most of these submaintainers have their own trees where they stage patches, |
| 45 | 48 | sending pull requests to the main SoC tree. These trees are usually, but not |
| 46 | −always, listed in MAINTAINERS. The main SoC maintainers can be reached via the | |
| 47 | −alias soc@kernel.org if there is no platform-specific maintainer, or if they | |
| 48 | −are unresponsive. | |
| 49 | +always, listed in MAINTAINERS. | |
| 49 | 50 | |
| 50 | 51 | What the SoC tree is not, however, is a location for architecture-specific code |
| 51 | 52 | changes. Each architecture has its own maintainers that are responsible for |
| 52 | 53 | architectural details, CPU errata and the like. |
| 53 | 54 | |
| 55 | +Submitting Patches for Given SoC | |
| 56 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 57 | + | |
| 58 | +All typical platform related patches should be sent via SoC submaintainers | |
| 59 | +(platform-specific maintainers). This includes also changes to per-platform or | |
| 60 | +shared defconfigs (scripts/get_maintainer.pl might not provide correct | |
| 61 | +addresses in such case). | |
| 62 | + | |
| 63 | +Submitting Patches to the Main SoC Maintainers | |
| 64 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 65 | + | |
| 66 | +The main SoC maintainers can be reached via the alias soc@kernel.org only in | |
| 67 | +following cases: | |
| 68 | + | |
| 69 | +1. There are no platform-specific maintainers. | |
| 70 | + | |
| 71 | +2. Platform-specific maintainers are unresponsive. | |
| 72 | + | |
| 73 | +3. Introducing a completely new SoC platform. Such new SoC work should be sent | |
| 74 | + first to common mailing lists, pointed out by scripts/get_maintainer.pl, for | |
| 75 | + community review. After positive community review, work should be sent to | |
| 76 | + soc@kernel.org in one patchset containing new arch/foo/Kconfig entry, DTS | |
| 77 | + files, MAINTAINERS file entry and optionally initial drivers with their | |
| 78 | + Devicetree bindings. The MAINTAINERS file entry should list new | |
| 79 | + platform-specific maintainers, who are going to be responsible for handling | |
| 80 | + patches for the platform from now on. | |
| 81 | + | |
| 82 | +Note that the soc@kernel.org is usually not the place to discuss the patches, | |
| 83 | +thus work sent to this address should be already considered as acceptable by | |
| 84 | +the community. | |
| 85 | + | |
| 54 | 86 | Information for (new) Submaintainers |
| 55 | 87 | ------------------------------------ |
| 56 | 88 | |
| @@ -66,7 +66,7 @@ BPF scheduler and reverts all tasks back to CFS. · 65 unmodified lines | ||
| 66 | 66 | .. code-block:: none |
| 67 | 67 | |
| 68 | 68 | # make -j16 -C tools/sched_ext |
| 69 | − # tools/sched_ext/scx_simple | |
| 69 | + # tools/sched_ext/build/bin/scx_simple | |
| 70 | 70 | local=0 global=3 |
| 71 | 71 | local=5 global=24 |
| 72 | 72 | local=9 global=44 |
| @@ -8098,13 +8098,15 @@ KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS By default, KVM emulates MONITOR/MWAIT (if · 8097 unmodified lines | ||
| 8098 | 8098 | KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is |
| 8099 | 8099 | disabled. |
| 8100 | 8100 | |
| 8101 | −KVM_X86_QUIRK_SLOT_ZAP_ALL By default, KVM invalidates all SPTEs in | |
| 8102 | − fast way for memslot deletion when VM type | |
| 8103 | − is KVM_X86_DEFAULT_VM. | |
| 8104 | − When this quirk is disabled or when VM type | |
| 8105 | − is other than KVM_X86_DEFAULT_VM, KVM zaps | |
| 8106 | − only leaf SPTEs that are within the range of | |
| 8107 | − the memslot being deleted. | |
| 8101 | +KVM_X86_QUIRK_SLOT_ZAP_ALL By default, for KVM_X86_DEFAULT_VM VMs, KVM | |
| 8102 | + invalidates all SPTEs in all memslots and | |
| 8103 | + address spaces when a memslot is deleted or | |
| 8104 | + moved. When this quirk is disabled (or the | |
| 8105 | + VM type isn't KVM_X86_DEFAULT_VM), KVM only | |
| 8106 | + ensures the backing memory of the deleted | |
| 8107 | + or moved memslot isn't reachable, i.e KVM | |
| 8108 | + _may_ invalidate only SPTEs related to the | |
| 8109 | + memslot. | |
| 8108 | 8110 | =================================== ============================================ |
| 8109 | 8111 | |
| 8110 | 8112 | 7.32 KVM_CAP_MAX_VCPU_ID |
| @@ -136,7 +136,7 @@ For direct sp, we can easily avoid it since the spte of direct sp is fixed · 135 unmodified lines | ||
| 136 | 136 | to gfn. For indirect sp, we disabled fast page fault for simplicity. |
| 137 | 137 | |
| 138 | 138 | A solution for indirect sp could be to pin the gfn, for example via |
| 139 | −kvm_vcpu_gfn_to_pfn_atomic, before the cmpxchg. After the pinning: | |
| 139 | +gfn_to_pfn_memslot_atomic, before the cmpxchg. After the pinning: | |
| 140 | 140 | |
| 141 | 141 | - We have held the refcount of pfn; that means the pfn can not be freed and |
| 142 | 142 | be reused for another gfn. |
| @@ -8,7 +8,7 @@ Introduction · 7 unmodified lines | ||
| 8 | 8 | ============ |
| 9 | 9 | |
| 10 | 10 | Many Dell notebooks made after ~2020 support a WMI-based interface for |
| 11 | −retrieving various system data like battery temperature, ePPID, diagostic data | |
| 11 | +retrieving various system data like battery temperature, ePPID, diagnostic data | |
| 12 | 12 | and fan/thermal sensor data. |
| 13 | 13 | |
| 14 | 14 | This interface is likely used by the `Dell Data Vault` software on Windows, |
| @@ -277,7 +277,7 @@ Reverse-Engineering the DDV WMI interface · 262 unmodified lines | ||
| 277 | 277 | 4. Try to deduce the meaning of a certain WMI method by comparing the control |
| 278 | 278 | flow with other ACPI methods (_BIX or _BIF for battery related methods |
| 279 | 279 | for example). |
| 280 | −5. Use the built-in UEFI diagostics to view sensor types/values for fan/thermal | |
| 280 | +5. Use the built-in UEFI diagnostics to view sensor types/values for fan/thermal | |
| 281 | 281 | related methods (sometimes overwriting static ACPI data fields can be used |
| 282 | 282 | to test different sensor type values, since on some machines this data is |
| 283 | 283 | not reinitialized upon a warm reset). |
| @@ -258,12 +258,6 @@ L: linux-acenic@sunsite.dk · 257 unmodified lines | ||
| 258 | 258 | S: Maintained |
| 259 | 259 | F: drivers/net/ethernet/alteon/acenic* |
| 260 | 260 | |
| 261 | −ACER ASPIRE 1 EMBEDDED CONTROLLER DRIVER | |
| 262 | −M: Nikita Travkin <nikita@trvn.ru> | |
| 263 | −S: Maintained | |
| 264 | −F: Documentation/devicetree/bindings/platform/acer,aspire1-ec.yaml | |
| 265 | −F: drivers/platform/arm64/acer-aspire1-ec.c | |
| 266 | − | |
| 267 | 261 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER |
| 268 | 262 | M: Peter Kaestle <peter@piie.net> |
| 269 | 263 | L: platform-driver-x86@vger.kernel.org |
| @@ -860,7 +854,7 @@ F: drivers/crypto/allwinner/ · 590 unmodified lines | ||
| 860 | 854 | |
| 861 | 855 | ALLWINNER DMIC DRIVERS |
| 862 | 856 | M: Ban Tao <fengzheng923@gmail.com> |
| 863 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 857 | +L: linux-sound@vger.kernel.org | |
| 864 | 858 | S: Maintained |
| 865 | 859 | F: Documentation/devicetree/bindings/sound/allwinner,sun50i-h6-dmic.yaml |
| 866 | 860 | F: sound/soc/sunxi/sun50i-dmic.c |
| @@ -888,7 +882,6 @@ F: drivers/staging/media/sunxi/cedrus/ · 21 unmodified lines | ||
| 888 | 882 | |
| 889 | 883 | ALPHA PORT |
| 890 | 884 | M: Richard Henderson <richard.henderson@linaro.org> |
| 891 | −M: Ivan Kokshaysky <ink@jurassic.park.msu.ru> | |
| 892 | 885 | M: Matt Turner <mattst88@gmail.com> |
| 893 | 886 | L: linux-alpha@vger.kernel.org |
| 894 | 887 | S: Odd Fixes |
| @@ -1517,7 +1510,7 @@ F: drivers/iio/gyro/adxrs290.c · 622 unmodified lines | ||
| 1517 | 1510 | ANALOG DEVICES INC ASOC CODEC DRIVERS |
| 1518 | 1511 | M: Lars-Peter Clausen <lars@metafoo.de> |
| 1519 | 1512 | M: Nuno Sá <nuno.sa@analog.com> |
| 1520 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 1513 | +L: linux-sound@vger.kernel.org | |
| 1521 | 1514 | S: Supported |
| 1522 | 1515 | W: http://wiki.analog.com/ |
| 1523 | 1516 | W: https://ez.analog.com/linux-software-drivers |
| @@ -1594,7 +1587,7 @@ F: drivers/rtc/rtc-goldfish.c · 70 unmodified lines | ||
| 1594 | 1587 | AOA (Apple Onboard Audio) ALSA DRIVER |
| 1595 | 1588 | M: Johannes Berg <johannes@sipsolutions.net> |
| 1596 | 1589 | L: linuxppc-dev@lists.ozlabs.org |
| 1597 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 1590 | +L: linux-sound@vger.kernel.org | |
| 1598 | 1591 | S: Maintained |
| 1599 | 1592 | F: sound/aoa/ |
| 1600 | 1593 | |
| @@ -1761,8 +1754,8 @@ F: include/uapi/linux/if_arcnet.h · 160 unmodified lines | ||
| 1761 | 1754 | ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS) |
| 1762 | 1755 | M: Arnd Bergmann <arnd@arndb.de> |
| 1763 | 1756 | M: Olof Johansson <olof@lixom.net> |
| 1764 | −M: soc@kernel.org | |
| 1765 | 1757 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1758 | +L: soc@lists.linux.dev | |
| 1766 | 1759 | S: Maintained |
| 1767 | 1760 | P: Documentation/process/maintainer-soc.rst |
| 1768 | 1761 | C: irc://irc.libera.chat/armlinux |
| @@ -2091,7 +2084,7 @@ F: drivers/crypto/amlogic/ · 322 unmodified lines | ||
| 2091 | 2084 | |
| 2092 | 2085 | ARM/Amlogic Meson SoC Sound Drivers |
| 2093 | 2086 | M: Jerome Brunet <jbrunet@baylibre.com> |
| 2094 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 2087 | +L: linux-sound@vger.kernel.org | |
| 2095 | 2088 | S: Maintained |
| 2096 | 2089 | F: Documentation/devicetree/bindings/sound/amlogic* |
| 2097 | 2090 | F: sound/soc/meson/ |
| @@ -2129,7 +2122,7 @@ F: drivers/*/*alpine* · 31 unmodified lines | ||
| 2129 | 2122 | ARM/APPLE MACHINE SOUND DRIVERS |
| 2130 | 2123 | M: Martin Povišer <povik+lin@cutebit.org> |
| 2131 | 2124 | L: asahi@lists.linux.dev |
| 2132 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 2125 | +L: linux-sound@vger.kernel.org | |
| 2133 | 2126 | S: Maintained |
| 2134 | 2127 | F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml |
| 2135 | 2128 | F: Documentation/devicetree/bindings/sound/apple,* |
| @@ -2263,12 +2256,6 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) · 127 unmodified lines | ||
| 2263 | 2256 | S: Maintained |
| 2264 | 2257 | F: arch/arm/mach-ep93xx/ts72xx.c |
| 2265 | 2258 | |
| 2266 | −ARM/CIRRUS LOGIC CLPS711X ARM ARCHITECTURE | |
| 2267 | −M: Alexander Shiyan <shc_work@mail.ru> | |
| 2268 | −L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 2269 | −S: Odd Fixes | |
| 2270 | −N: clps711x | |
| 2271 | − | |
| 2272 | 2259 | ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE |
| 2273 | 2260 | M: Hartley Sweeten <hsweeten@visionengravers.com> |
| 2274 | 2261 | M: Alexander Sverdlin <alexander.sverdlin@gmail.com> |
| @@ -3732,7 +3719,7 @@ F: arch/arm/boot/dts/microchip/at91-tse850-3.dts · 1457 unmodified lines | ||
| 3732 | 3719 | |
| 3733 | 3720 | AXENTIA ASOC DRIVERS |
| 3734 | 3721 | M: Peter Rosin <peda@axentia.se> |
| 3735 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 3722 | +L: linux-sound@vger.kernel.org | |
| 3736 | 3723 | S: Maintained |
| 3737 | 3724 | F: Documentation/devicetree/bindings/sound/axentia,* |
| 3738 | 3725 | F: sound/soc/atmel/tse850-pcm5142.c |
| @@ -3815,14 +3802,6 @@ F: drivers/video/backlight/ · 76 unmodified lines | ||
| 3815 | 3802 | F: include/linux/backlight.h |
| 3816 | 3803 | F: include/linux/pwm_backlight.h |
| 3817 | 3804 | |
| 3818 | −BAIKAL-T1 PVT HARDWARE MONITOR DRIVER | |
| 3819 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 3820 | −L: linux-hwmon@vger.kernel.org | |
| 3821 | −S: Supported | |
| 3822 | −F: Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml | |
| 3823 | −F: Documentation/hwmon/bt1-pvt.rst | |
| 3824 | −F: drivers/hwmon/bt1-pvt.[ch] | |
| 3825 | − | |
| 3826 | 3805 | BARCO P50 GPIO DRIVER |
| 3827 | 3806 | M: Santosh Kumar Yadav <santoshkumar.yadav@barco.com> |
| 3828 | 3807 | M: Peter Korsgaard <peter.korsgaard@barco.com> |
| @@ -4851,7 +4830,7 @@ F: include/uapi/linux/bsg.h · 1022 unmodified lines | ||
| 4851 | 4830 | |
| 4852 | 4831 | BT87X AUDIO DRIVER |
| 4853 | 4832 | M: Clemens Ladisch <clemens@ladisch.de> |
| 4854 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 4833 | +L: linux-sound@vger.kernel.org | |
| 4855 | 4834 | S: Maintained |
| 4856 | 4835 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 4857 | 4836 | F: Documentation/sound/cards/bt87x.rst |
| @@ -4913,7 +4892,7 @@ F: drivers/net/can/bxcan.c · 55 unmodified lines | ||
| 4913 | 4892 | |
| 4914 | 4893 | C-MEDIA CMI8788 DRIVER |
| 4915 | 4894 | M: Clemens Ladisch <clemens@ladisch.de> |
| 4916 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 4895 | +L: linux-sound@vger.kernel.org | |
| 4917 | 4896 | S: Maintained |
| 4918 | 4897 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 4919 | 4898 | F: sound/pci/oxygen/ |
| @@ -6476,7 +6455,6 @@ F: drivers/mtd/nand/raw/denali* · 1556 unmodified lines | ||
| 6476 | 6455 | |
| 6477 | 6456 | DESIGNWARE EDMA CORE IP DRIVER |
| 6478 | 6457 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| 6479 | −R: Serge Semin <fancer.lancer@gmail.com> | |
| 6480 | 6458 | L: dmaengine@vger.kernel.org |
| 6481 | 6459 | S: Maintained |
| 6482 | 6460 | F: drivers/dma/dw-edma/ |
| @@ -7832,6 +7810,8 @@ F: drivers/gpu/drm/xlnx/ · 1349 unmodified lines | ||
| 7832 | 7810 | DRM GPU SCHEDULER |
| 7833 | 7811 | M: Luben Tuikov <ltuikov89@gmail.com> |
| 7834 | 7812 | M: Matthew Brost <matthew.brost@intel.com> |
| 7813 | +M: Danilo Krummrich <dakr@kernel.org> | |
| 7814 | +M: Philipp Stanner <pstanner@redhat.com> | |
| 7835 | 7815 | L: dri-devel@lists.freedesktop.org |
| 7836 | 7816 | S: Maintained |
| 7837 | 7817 | T: git https://gitlab.freedesktop.org/drm/misc/kernel.git |
| @@ -8252,7 +8232,7 @@ F: drivers/edac/ti_edac.c · 414 unmodified lines | ||
| 8252 | 8232 | |
| 8253 | 8233 | EDIROL UA-101/UA-1000 DRIVER |
| 8254 | 8234 | M: Clemens Ladisch <clemens@ladisch.de> |
| 8255 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 8235 | +L: linux-sound@vger.kernel.org | |
| 8256 | 8236 | S: Maintained |
| 8257 | 8237 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 8258 | 8238 | F: sound/usb/misc/ua101.c |
| @@ -8814,7 +8794,7 @@ F: drivers/net/can/usb/f81604.c · 555 unmodified lines | ||
| 8814 | 8794 | FIREWIRE AUDIO DRIVERS and IEC 61883-1/6 PACKET STREAMING ENGINE |
| 8815 | 8795 | M: Clemens Ladisch <clemens@ladisch.de> |
| 8816 | 8796 | M: Takashi Sakamoto <o-takashi@sakamocchi.jp> |
| 8817 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 8797 | +L: linux-sound@vger.kernel.org | |
| 8818 | 8798 | S: Maintained |
| 8819 | 8799 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 8820 | 8800 | F: include/uapi/sound/firewire.h |
| @@ -8888,7 +8868,7 @@ F: drivers/input/joystick/fsia6b.c · 67 unmodified lines | ||
| 8888 | 8868 | |
| 8889 | 8869 | FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett) |
| 8890 | 8870 | M: Geoffrey D. Bennett <g@b4.vu> |
| 8891 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 8871 | +L: linux-sound@vger.kernel.org | |
| 8892 | 8872 | S: Maintained |
| 8893 | 8873 | W: https://github.com/geoffreybennett/scarlett-gen2 |
| 8894 | 8874 | B: https://github.com/geoffreybennett/scarlett-gen2/issues |
| @@ -8912,6 +8892,7 @@ F: include/linux/fortify-string.h · 17 unmodified lines | ||
| 8912 | 8892 | F: lib/fortify_kunit.c |
| 8913 | 8893 | F: lib/memcpy_kunit.c |
| 8914 | 8894 | F: lib/test_fortify/* |
| 8895 | +K: \bunsafe_memcpy\b | |
| 8915 | 8896 | K: \b__NO_FORTIFY\b |
| 8916 | 8897 | |
| 8917 | 8898 | FPGA DFL DRIVERS |
| @@ -9209,7 +9190,7 @@ M: Shengjiu Wang <shengjiu.wang@gmail.com> · 291 unmodified lines | ||
| 9209 | 9190 | M: Xiubo Li <Xiubo.Lee@gmail.com> |
| 9210 | 9191 | R: Fabio Estevam <festevam@gmail.com> |
| 9211 | 9192 | R: Nicolin Chen <nicoleotsuka@gmail.com> |
| 9212 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 9193 | +L: linux-sound@vger.kernel.org | |
| 9213 | 9194 | L: linuxppc-dev@lists.ozlabs.org |
| 9214 | 9195 | S: Maintained |
| 9215 | 9196 | F: sound/soc/fsl/fsl* |
| @@ -9219,7 +9200,7 @@ FREESCALE SOC LPC32XX SOUND DRIVERS · 3 unmodified lines | ||
| 9219 | 9200 | M: J.M.B. Downing <jonathan.downing@nautel.com> |
| 9220 | 9201 | M: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com> |
| 9221 | 9202 | R: Vladimir Zapolskiy <vz@mleia.com> |
| 9222 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 9203 | +L: linux-sound@vger.kernel.org | |
| 9223 | 9204 | L: linuxppc-dev@lists.ozlabs.org |
| 9224 | 9205 | S: Maintained |
| 9225 | 9206 | F: Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml |
| @@ -9227,7 +9208,7 @@ F: sound/soc/fsl/lpc3xxx-* · 1 unmodified line | ||
| 9227 | 9208 | |
| 9228 | 9209 | FREESCALE SOC SOUND QMC DRIVER |
| 9229 | 9210 | M: Herve Codina <herve.codina@bootlin.com> |
| 9230 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 9211 | +L: linux-sound@vger.kernel.org | |
| 9231 | 9212 | L: linuxppc-dev@lists.ozlabs.org |
| 9232 | 9213 | S: Maintained |
| 9233 | 9214 | F: Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml |
| @@ -9756,14 +9737,6 @@ F: drivers/gpio/gpiolib-cdev.c · 522 unmodified lines | ||
| 9756 | 9737 | F: include/uapi/linux/gpio.h |
| 9757 | 9738 | F: tools/gpio/ |
| 9758 | 9739 | |
| 9759 | −GRE DEMULTIPLEXER DRIVER | |
| 9760 | −M: Dmitry Kozlov <xeb@mail.ru> | |
| 9761 | −L: netdev@vger.kernel.org | |
| 9762 | −S: Maintained | |
| 9763 | −F: include/net/gre.h | |
| 9764 | −F: net/ipv4/gre_demux.c | |
| 9765 | −F: net/ipv4/gre_offload.c | |
| 9766 | − | |
| 9767 | 9740 | GRETH 10/100/1G Ethernet MAC device driver |
| 9768 | 9741 | M: Andreas Larsson <andreas@gaisler.com> |
| 9769 | 9742 | L: netdev@vger.kernel.org |
| @@ -10267,7 +10240,7 @@ F: Documentation/devicetree/bindings/arm/hisilicon/low-pin-count.yaml · 497 unmodified lines | ||
| 10267 | 10240 | F: drivers/bus/hisi_lpc.c |
| 10268 | 10241 | |
| 10269 | 10242 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) |
| 10270 | −M: Yisen Zhuang <yisen.zhuang@huawei.com> | |
| 10243 | +M: Jian Shen <shenjian15@huawei.com> | |
| 10271 | 10244 | M: Salil Mehta <salil.mehta@huawei.com> |
| 10272 | 10245 | M: Jijie Shao <shaojijie@huawei.com> |
| 10273 | 10246 | L: netdev@vger.kernel.org |
| @@ -10276,7 +10249,7 @@ W: http://www.hisilicon.com · 2 unmodified lines | ||
| 10276 | 10249 | F: drivers/net/ethernet/hisilicon/hns3/ |
| 10277 | 10250 | |
| 10278 | 10251 | HISILICON NETWORK SUBSYSTEM DRIVER |
| 10279 | −M: Yisen Zhuang <yisen.zhuang@huawei.com> | |
| 10252 | +M: Jian Shen <shenjian15@huawei.com> | |
| 10280 | 10253 | M: Salil Mehta <salil.mehta@huawei.com> |
| 10281 | 10254 | L: netdev@vger.kernel.org |
| 10282 | 10255 | S: Maintained |
| @@ -11154,7 +11127,7 @@ F: drivers/iio/pressure/dps310.c · 871 unmodified lines | ||
| 11154 | 11127 | |
| 11155 | 11128 | INFINEON PEB2466 ASoC CODEC |
| 11156 | 11129 | M: Herve Codina <herve.codina@bootlin.com> |
| 11157 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 11130 | +L: linux-sound@vger.kernel.org | |
| 11158 | 11131 | S: Maintained |
| 11159 | 11132 | F: Documentation/devicetree/bindings/sound/infineon,peb2466.yaml |
| 11160 | 11133 | F: sound/soc/codecs/peb2466.c |
| @@ -11280,10 +11253,10 @@ F: security/integrity/ · 119 unmodified lines | ||
| 11280 | 11253 | F: security/integrity/ima/ |
| 11281 | 11254 | |
| 11282 | 11255 | INTEGRITY POLICY ENFORCEMENT (IPE) |
| 11283 | −M: Fan Wu <wufan@linux.microsoft.com> | |
| 11256 | +M: Fan Wu <wufan@kernel.org> | |
| 11284 | 11257 | L: linux-security-module@vger.kernel.org |
| 11285 | 11258 | S: Supported |
| 11286 | −T: git https://github.com/microsoft/ipe.git | |
| 11259 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe.git | |
| 11287 | 11260 | F: Documentation/admin-guide/LSM/ipe.rst |
| 11288 | 11261 | F: Documentation/security/ipe.rst |
| 11289 | 11262 | F: scripts/ipe/ |
| @@ -11317,7 +11290,7 @@ M: Bard Liao <yung-chuan.liao@linux.intel.com> · 27 unmodified lines | ||
| 11317 | 11290 | M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> |
| 11318 | 11291 | M: Kai Vehmanen <kai.vehmanen@linux.intel.com> |
| 11319 | 11292 | R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> |
| 11320 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 11293 | +L: linux-sound@vger.kernel.org | |
| 11321 | 11294 | S: Supported |
| 11322 | 11295 | F: sound/soc/intel/ |
| 11323 | 11296 | |
| @@ -11496,7 +11469,7 @@ F: include/uapi/linux/idxd.h · 172 unmodified lines | ||
| 11496 | 11469 | |
| 11497 | 11470 | INTEL IN FIELD SCAN (IFS) DEVICE |
| 11498 | 11471 | M: Jithu Joseph <jithu.joseph@intel.com> |
| 11499 | −R: Ashok Raj <ashok.raj@intel.com> | |
| 11472 | +R: Ashok Raj <ashok.raj.linux@gmail.com> | |
| 11500 | 11473 | R: Tony Luck <tony.luck@intel.com> |
| 11501 | 11474 | S: Maintained |
| 11502 | 11475 | F: drivers/platform/x86/intel/ifs |
| @@ -11601,6 +11574,16 @@ F: drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c · 98 unmodified lines | ||
| 11601 | 11574 | F: drivers/crypto/intel/keembay/ocs-hcu.c |
| 11602 | 11575 | F: drivers/crypto/intel/keembay/ocs-hcu.h |
| 11603 | 11576 | |
| 11577 | +INTEL LA JOLLA COVE ADAPTER (LJCA) USB I/O EXPANDER DRIVERS | |
| 11578 | +M: Wentong Wu <wentong.wu@intel.com> | |
| 11579 | +M: Sakari Ailus <sakari.ailus@linux.intel.com> | |
| 11580 | +S: Maintained | |
| 11581 | +F: drivers/gpio/gpio-ljca.c | |
| 11582 | +F: drivers/i2c/busses/i2c-ljca.c | |
| 11583 | +F: drivers/spi/spi-ljca.c | |
| 11584 | +F: drivers/usb/misc/usb-ljca.c | |
| 11585 | +F: include/linux/usb/ljca.h | |
| 11586 | + | |
| 11604 | 11587 | INTEL MANAGEMENT ENGINE (mei) |
| 11605 | 11588 | M: Tomas Winkler <tomas.winkler@intel.com> |
| 11606 | 11589 | L: linux-kernel@vger.kernel.org |
| @@ -12001,7 +11984,7 @@ F: drivers/tty/ipwireless/ · 394 unmodified lines | ||
| 12001 | 11984 | |
| 12002 | 11985 | IRON DEVICE AUDIO CODEC DRIVERS |
| 12003 | 11986 | M: Kiseok Jo <kiseok.jo@irondevice.com> |
| 12004 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 11987 | +L: linux-sound@vger.kernel.org | |
| 12005 | 11988 | S: Maintained |
| 12006 | 11989 | F: Documentation/devicetree/bindings/sound/irondevice,* |
| 12007 | 11990 | F: sound/soc/codecs/sma* |
| @@ -12239,6 +12222,7 @@ R: Dmitry Vyukov <dvyukov@google.com> · 231 unmodified lines | ||
| 12239 | 12222 | R: Vincenzo Frascino <vincenzo.frascino@arm.com> |
| 12240 | 12223 | L: kasan-dev@googlegroups.com |
| 12241 | 12224 | S: Maintained |
| 12225 | +B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management | |
| 12242 | 12226 | F: Documentation/dev-tools/kasan.rst |
| 12243 | 12227 | F: arch/*/include/asm/*kasan.h |
| 12244 | 12228 | F: arch/*/mm/kasan_init* |
| @@ -12262,6 +12246,7 @@ R: Dmitry Vyukov <dvyukov@google.com> · 17 unmodified lines | ||
| 12262 | 12246 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 12263 | 12247 | L: kasan-dev@googlegroups.com |
| 12264 | 12248 | S: Maintained |
| 12249 | +B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management | |
| 12265 | 12250 | F: Documentation/dev-tools/kcov.rst |
| 12266 | 12251 | F: include/linux/kcov.h |
| 12267 | 12252 | F: include/uapi/linux/kcov.h |
| @@ -12343,6 +12328,7 @@ F: include/linux/randomize_kstack.h · 75 unmodified lines | ||
| 12343 | 12328 | F: kernel/configs/hardening.config |
| 12344 | 12329 | F: lib/usercopy_kunit.c |
| 12345 | 12330 | F: mm/usercopy.c |
| 12331 | +F: security/Kconfig.hardening | |
| 12346 | 12332 | K: \b(add|choose)_random_kstack_offset\b |
| 12347 | 12333 | K: \b__check_(object_size|heap_object)\b |
| 12348 | 12334 | K: \b__counted_by\b |
| @@ -12459,7 +12445,7 @@ F: virt/kvm/* · 110 unmodified lines | ||
| 12459 | 12445 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) |
| 12460 | 12446 | M: Marc Zyngier <maz@kernel.org> |
| 12461 | 12447 | M: Oliver Upton <oliver.upton@linux.dev> |
| 12462 | −R: James Morse <james.morse@arm.com> | |
| 12448 | +R: Joey Gouly <joey.gouly@arm.com> | |
| 12463 | 12449 | R: Suzuki K Poulose <suzuki.poulose@arm.com> |
| 12464 | 12450 | R: Zenghui Yu <yuzenghui@huawei.com> |
| 12465 | 12451 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -12940,49 +12926,29 @@ LIBATA PATA ARASAN COMPACT FLASH CONTROLLER · 474 unmodified lines | ||
| 12940 | 12926 | M: Viresh Kumar <vireshk@kernel.org> |
| 12941 | 12927 | L: linux-ide@vger.kernel.org |
| 12942 | 12928 | S: Maintained |
| 12943 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | |
| 12944 | 12929 | F: drivers/ata/pata_arasan_cf.c |
| 12945 | 12930 | F: include/linux/pata_arasan_cf_data.h |
| 12946 | 12931 | |
| 12947 | −LIBATA PATA DRIVERS | |
| 12948 | −R: Sergey Shtylyov <s.shtylyov@omp.ru> | |
| 12949 | −L: linux-ide@vger.kernel.org | |
| 12950 | −F: drivers/ata/ata_*.c | |
| 12951 | −F: drivers/ata/pata_*.c | |
| 12952 | − | |
| 12953 | 12932 | LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS |
| 12954 | 12933 | M: Linus Walleij <linus.walleij@linaro.org> |
| 12955 | 12934 | L: linux-ide@vger.kernel.org |
| 12956 | 12935 | S: Maintained |
| 12957 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | |
| 12958 | 12936 | F: drivers/ata/pata_ftide010.c |
| 12959 | 12937 | F: drivers/ata/sata_gemini.c |
| 12960 | 12938 | F: drivers/ata/sata_gemini.h |
| 12961 | 12939 | |
| 12962 | 12940 | LIBATA SATA AHCI PLATFORM devices support |
| 12963 | 12941 | M: Hans de Goede <hdegoede@redhat.com> |
| 12964 | −M: Jens Axboe <axboe@kernel.dk> | |
| 12965 | 12942 | L: linux-ide@vger.kernel.org |
| 12966 | 12943 | S: Maintained |
| 12967 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | |
| 12968 | 12944 | F: drivers/ata/ahci_platform.c |
| 12969 | 12945 | F: drivers/ata/libahci_platform.c |
| 12970 | 12946 | F: include/linux/ahci_platform.h |
| 12971 | 12947 | |
| 12972 | −LIBATA SATA AHCI SYNOPSYS DWC CONTROLLER DRIVER | |
| 12973 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 12974 | −L: linux-ide@vger.kernel.org | |
| 12975 | −S: Maintained | |
| 12976 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git | |
| 12977 | −F: Documentation/devicetree/bindings/ata/baikal,bt1-ahci.yaml | |
| 12978 | −F: Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml | |
| 12979 | −F: drivers/ata/ahci_dwc.c | |
| 12980 | − | |
| 12981 | 12948 | LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER |
| 12982 | 12949 | M: Mikael Pettersson <mikpelinux@gmail.com> |
| 12983 | 12950 | L: linux-ide@vger.kernel.org |
| 12984 | 12951 | S: Maintained |
| 12985 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | |
| 12986 | 12952 | F: drivers/ata/sata_promise.* |
| 12987 | 12953 | |
| 12988 | 12954 | LIBATA SUBSYSTEM (Serial and Parallel ATA drivers) |
| @@ -13952,7 +13918,7 @@ F: drivers/media/i2c/max96717.c · 963 unmodified lines | ||
| 13952 | 13918 | |
| 13953 | 13919 | MAX9860 MONO AUDIO VOICE CODEC DRIVER |
| 13954 | 13920 | M: Peter Rosin <peda@axentia.se> |
| 13955 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 13921 | +L: linux-sound@vger.kernel.org | |
| 13956 | 13922 | S: Maintained |
| 13957 | 13923 | F: Documentation/devicetree/bindings/sound/max9860.txt |
| 13958 | 13924 | F: sound/soc/codecs/max9860.* |
| @@ -14174,16 +14140,6 @@ S: Maintained · 215 unmodified lines | ||
| 14174 | 14140 | T: git git://linuxtv.org/media_tree.git |
| 14175 | 14141 | F: drivers/media/platform/nxp/imx-pxp.[ch] |
| 14176 | 14142 | |
| 14177 | −MEDIA DRIVERS FOR ASCOT2E | |
| 14178 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14179 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14180 | −L: linux-media@vger.kernel.org | |
| 14181 | −S: Supported | |
| 14182 | −W: https://linuxtv.org | |
| 14183 | −W: http://netup.tv/ | |
| 14184 | −T: git git://linuxtv.org/media_tree.git | |
| 14185 | −F: drivers/media/dvb-frontends/ascot2e* | |
| 14186 | − | |
| 14187 | 14143 | MEDIA DRIVERS FOR CXD2099AR CI CONTROLLERS |
| 14188 | 14144 | M: Jasmin Jessich <jasmin@anw.at> |
| 14189 | 14145 | L: linux-media@vger.kernel.org |
| @@ -14192,16 +14148,6 @@ W: https://linuxtv.org · 2 unmodified lines | ||
| 14192 | 14148 | T: git git://linuxtv.org/media_tree.git |
| 14193 | 14149 | F: drivers/media/dvb-frontends/cxd2099* |
| 14194 | 14150 | |
| 14195 | −MEDIA DRIVERS FOR CXD2841ER | |
| 14196 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14197 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14198 | −L: linux-media@vger.kernel.org | |
| 14199 | −S: Supported | |
| 14200 | −W: https://linuxtv.org | |
| 14201 | −W: http://netup.tv/ | |
| 14202 | −T: git git://linuxtv.org/media_tree.git | |
| 14203 | −F: drivers/media/dvb-frontends/cxd2841er* | |
| 14204 | − | |
| 14205 | 14151 | MEDIA DRIVERS FOR CXD2880 |
| 14206 | 14152 | M: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com> |
| 14207 | 14153 | L: linux-media@vger.kernel.org |
| @@ -14246,35 +14192,6 @@ F: drivers/media/platform/nxp/imx-mipi-csis.c · 38 unmodified lines | ||
| 14246 | 14192 | F: drivers/media/platform/nxp/imx7-media-csi.c |
| 14247 | 14193 | F: drivers/media/platform/nxp/imx8mq-mipi-csi2.c |
| 14248 | 14194 | |
| 14249 | −MEDIA DRIVERS FOR HELENE | |
| 14250 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14251 | −L: linux-media@vger.kernel.org | |
| 14252 | −S: Supported | |
| 14253 | −W: https://linuxtv.org | |
| 14254 | −W: http://netup.tv/ | |
| 14255 | −T: git git://linuxtv.org/media_tree.git | |
| 14256 | −F: drivers/media/dvb-frontends/helene* | |
| 14257 | − | |
| 14258 | −MEDIA DRIVERS FOR HORUS3A | |
| 14259 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14260 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14261 | −L: linux-media@vger.kernel.org | |
| 14262 | −S: Supported | |
| 14263 | −W: https://linuxtv.org | |
| 14264 | −W: http://netup.tv/ | |
| 14265 | −T: git git://linuxtv.org/media_tree.git | |
| 14266 | −F: drivers/media/dvb-frontends/horus3a* | |
| 14267 | − | |
| 14268 | −MEDIA DRIVERS FOR LNBH25 | |
| 14269 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14270 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14271 | −L: linux-media@vger.kernel.org | |
| 14272 | −S: Supported | |
| 14273 | −W: https://linuxtv.org | |
| 14274 | −W: http://netup.tv/ | |
| 14275 | −T: git git://linuxtv.org/media_tree.git | |
| 14276 | −F: drivers/media/dvb-frontends/lnbh25* | |
| 14277 | − | |
| 14278 | 14195 | MEDIA DRIVERS FOR MXL5XX TUNER DEMODULATORS |
| 14279 | 14196 | L: linux-media@vger.kernel.org |
| 14280 | 14197 | S: Orphan |
| @@ -14282,16 +14199,6 @@ W: https://linuxtv.org · 1 unmodified line | ||
| 14282 | 14199 | T: git git://linuxtv.org/media_tree.git |
| 14283 | 14200 | F: drivers/media/dvb-frontends/mxl5xx* |
| 14284 | 14201 | |
| 14285 | −MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices | |
| 14286 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14287 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14288 | −L: linux-media@vger.kernel.org | |
| 14289 | −S: Supported | |
| 14290 | −W: https://linuxtv.org | |
| 14291 | −W: http://netup.tv/ | |
| 14292 | −T: git git://linuxtv.org/media_tree.git | |
| 14293 | −F: drivers/media/pci/netup_unidvb/* | |
| 14294 | − | |
| 14295 | 14202 | MEDIA DRIVERS FOR NVIDIA TEGRA - VDE |
| 14296 | 14203 | M: Dmitry Osipenko <digetx@gmail.com> |
| 14297 | 14204 | L: linux-media@vger.kernel.org |
| @@ -14909,9 +14816,10 @@ N: include/linux/page[-_]* · 611 unmodified lines | ||
| 14909 | 14816 | |
| 14910 | 14817 | MEMORY MAPPING |
| 14911 | 14818 | M: Andrew Morton <akpm@linux-foundation.org> |
| 14912 | −R: Liam R. Howlett <Liam.Howlett@oracle.com> | |
| 14819 | +M: Liam R. Howlett <Liam.Howlett@oracle.com> | |
| 14820 | +M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 14913 | 14821 | R: Vlastimil Babka <vbabka@suse.cz> |
| 14914 | −R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 14822 | +R: Jann Horn <jannh@google.com> | |
| 14915 | 14823 | L: linux-mm@kvack.org |
| 14916 | 14824 | S: Maintained |
| 14917 | 14825 | W: http://www.linux-mm.org |
| @@ -14934,13 +14842,6 @@ F: drivers/mtd/ · 16 unmodified lines | ||
| 14934 | 14842 | F: include/linux/mtd/ |
| 14935 | 14843 | F: include/uapi/mtd/ |
| 14936 | 14844 | |
| 14937 | −MEMSENSING MICROSYSTEMS MSA311 DRIVER | |
| 14938 | −M: Dmitry Rokosov <ddrokosov@sberdevices.ru> | |
| 14939 | −L: linux-iio@vger.kernel.org | |
| 14940 | −S: Maintained | |
| 14941 | −F: Documentation/devicetree/bindings/iio/accel/memsensing,msa311.yaml | |
| 14942 | −F: drivers/iio/accel/msa311.c | |
| 14943 | − | |
| 14944 | 14845 | MEN A21 WATCHDOG DRIVER |
| 14945 | 14846 | M: Johannes Thumshirn <morbidrsa@gmail.com> |
| 14946 | 14847 | L: linux-watchdog@vger.kernel.org |
| @@ -15085,7 +14986,7 @@ F: drivers/spi/spi-at91-usart.c · 138 unmodified lines | ||
| 15085 | 14986 | |
| 15086 | 14987 | MICROCHIP AUDIO ASOC DRIVERS |
| 15087 | 14988 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> |
| 15088 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 14989 | +L: linux-sound@vger.kernel.org | |
| 15089 | 14990 | S: Supported |
| 15090 | 14991 | F: Documentation/devicetree/bindings/sound/atmel* |
| 15091 | 14992 | F: Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt |
| @@ -15274,7 +15175,6 @@ F: drivers/tty/serial/8250/8250_pci1xxxx.c · 182 unmodified lines | ||
| 15274 | 15175 | |
| 15275 | 15176 | MICROCHIP POLARFIRE FPGA DRIVERS |
| 15276 | 15177 | M: Conor Dooley <conor.dooley@microchip.com> |
| 15277 | −R: Vladimir Georgiev <v.georgiev@metrotek.ru> | |
| 15278 | 15178 | L: linux-fpga@vger.kernel.org |
| 15279 | 15179 | S: Supported |
| 15280 | 15180 | F: Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml |
| @@ -15529,17 +15429,6 @@ F: arch/mips/ · 248 unmodified lines | ||
| 15529 | 15429 | F: drivers/platform/mips/ |
| 15530 | 15430 | F: include/dt-bindings/mips/ |
| 15531 | 15431 | |
| 15532 | −MIPS BAIKAL-T1 PLATFORM | |
| 15533 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 15534 | −L: linux-mips@vger.kernel.org | |
| 15535 | −S: Supported | |
| 15536 | −F: Documentation/devicetree/bindings/bus/baikal,bt1-*.yaml | |
| 15537 | −F: Documentation/devicetree/bindings/clock/baikal,bt1-*.yaml | |
| 15538 | −F: drivers/bus/bt1-*.c | |
| 15539 | −F: drivers/clk/baikal-t1/ | |
| 15540 | −F: drivers/memory/bt1-l2-ctl.c | |
| 15541 | −F: drivers/mtd/maps/physmap-bt1-rom.[ch] | |
| 15542 | − | |
| 15543 | 15432 | MIPS BOSTON DEVELOPMENT BOARD |
| 15544 | 15433 | M: Paul Burton <paulburton@kernel.org> |
| 15545 | 15434 | L: linux-mips@vger.kernel.org |
| @@ -15552,7 +15441,6 @@ F: include/dt-bindings/clock/boston-clock.h · 6 unmodified lines | ||
| 15552 | 15441 | |
| 15553 | 15442 | MIPS CORE DRIVERS |
| 15554 | 15443 | M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> |
| 15555 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 15556 | 15444 | L: linux-mips@vger.kernel.org |
| 15557 | 15445 | S: Supported |
| 15558 | 15446 | F: drivers/bus/mips_cdmm.c |
| @@ -15957,7 +15845,7 @@ F: include/linux/mtd/*nand*.h · 398 unmodified lines | ||
| 15957 | 15845 | |
| 15958 | 15846 | NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER |
| 15959 | 15847 | M: Daniel Mack <zonque@gmail.com> |
| 15960 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 15848 | +L: linux-sound@vger.kernel.org | |
| 15961 | 15849 | S: Maintained |
| 15962 | 15850 | W: http://www.native-instruments.com |
| 15963 | 15851 | F: sound/usb/caiaq/ |
| @@ -16088,6 +15976,7 @@ F: include/uapi/linux/net_dropmon.h · 124 unmodified lines | ||
| 16088 | 15976 | F: net/core/drop_monitor.c |
| 16089 | 15977 | |
| 16090 | 15978 | NETWORKING DRIVERS |
| 15979 | +M: Andrew Lunn <andrew+netdev@lunn.ch> | |
| 16091 | 15980 | M: "David S. Miller" <davem@davemloft.net> |
| 16092 | 15981 | M: Eric Dumazet <edumazet@google.com> |
| 16093 | 15982 | M: Jakub Kicinski <kuba@kernel.org> |
| @@ -16153,6 +16042,7 @@ M: "David S. Miller" <davem@davemloft.net> · 59 unmodified lines | ||
| 16153 | 16042 | M: Eric Dumazet <edumazet@google.com> |
| 16154 | 16043 | M: Jakub Kicinski <kuba@kernel.org> |
| 16155 | 16044 | M: Paolo Abeni <pabeni@redhat.com> |
| 16045 | +R: Simon Horman <horms@kernel.org> | |
| 16156 | 16046 | L: netdev@vger.kernel.org |
| 16157 | 16047 | S: Maintained |
| 16158 | 16048 | P: Documentation/process/maintainer-netdev.rst |
| @@ -16195,10 +16085,22 @@ F: include/uapi/linux/rtnetlink.h · 36 unmodified lines | ||
| 16195 | 16085 | F: lib/net_utils.c |
| 16196 | 16086 | F: lib/random32.c |
| 16197 | 16087 | F: net/ |
| 16088 | +F: samples/pktgen/ | |
| 16198 | 16089 | F: tools/net/ |
| 16199 | 16090 | F: tools/testing/selftests/net/ |
| 16091 | +X: Documentation/networking/mac80211-injection.rst | |
| 16092 | +X: Documentation/networking/mac80211_hwsim/ | |
| 16093 | +X: Documentation/networking/regulatory.rst | |
| 16094 | +X: include/net/cfg80211.h | |
| 16095 | +X: include/net/ieee80211_radiotap.h | |
| 16096 | +X: include/net/iw_handler.h | |
| 16097 | +X: include/net/mac80211.h | |
| 16098 | +X: include/net/wext.h | |
| 16200 | 16099 | X: net/9p/ |
| 16201 | 16100 | X: net/bluetooth/ |
| 16101 | +X: net/mac80211/ | |
| 16102 | +X: net/rfkill/ | |
| 16103 | +X: net/wireless/ | |
| 16202 | 16104 | |
| 16203 | 16105 | NETWORKING [IPSEC] |
| 16204 | 16106 | M: Steffen Klassert <steffen.klassert@secunet.com> |
| @@ -16508,12 +16410,6 @@ F: include/linux/ntb.h · 303 unmodified lines | ||
| 16508 | 16410 | F: include/linux/ntb_transport.h |
| 16509 | 16411 | F: tools/testing/selftests/ntb/ |
| 16510 | 16412 | |
| 16511 | −NTB IDT DRIVER | |
| 16512 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 16513 | −L: ntb@lists.linux.dev | |
| 16514 | −S: Supported | |
| 16515 | −F: drivers/ntb/hw/idt/ | |
| 16516 | − | |
| 16517 | 16413 | NTB INTEL DRIVER |
| 16518 | 16414 | M: Dave Jiang <dave.jiang@intel.com> |
| 16519 | 16415 | L: ntb@lists.linux.dev |
| @@ -16728,7 +16624,7 @@ F: drivers/extcon/extcon-ptn5150.c · 208 unmodified lines | ||
| 16728 | 16624 | |
| 16729 | 16625 | NXP SGTL5000 DRIVER |
| 16730 | 16626 | M: Fabio Estevam <festevam@gmail.com> |
| 16731 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 16627 | +L: linux-sound@vger.kernel.org | |
| 16732 | 16628 | S: Maintained |
| 16733 | 16629 | F: Documentation/devicetree/bindings/sound/fsl,sgtl5000.yaml |
| 16734 | 16630 | F: sound/soc/codecs/sgtl5000* |
| @@ -16752,7 +16648,7 @@ K: "nxp,tda998x" · 17 unmodified lines | ||
| 16752 | 16648 | |
| 16753 | 16649 | NXP TFA9879 DRIVER |
| 16754 | 16650 | M: Peter Rosin <peda@axentia.se> |
| 16755 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 16651 | +L: linux-sound@vger.kernel.org | |
| 16756 | 16652 | S: Maintained |
| 16757 | 16653 | F: Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml |
| 16758 | 16654 | F: sound/soc/codecs/tfa9879* |
| @@ -16764,7 +16660,7 @@ F: drivers/nfc/nxp-nci · 5 unmodified lines | ||
| 16764 | 16660 | |
| 16765 | 16661 | NXP/Goodix TFA989X (TFA1) DRIVER |
| 16766 | 16662 | M: Stephan Gerhold <stephan@gerhold.net> |
| 16767 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 16663 | +L: linux-sound@vger.kernel.org | |
| 16768 | 16664 | S: Maintained |
| 16769 | 16665 | F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml |
| 16770 | 16666 | F: sound/soc/codecs/tfa989x.c |
| @@ -16850,7 +16746,7 @@ F: include/uapi/misc/ocxl.h · 79 unmodified lines | ||
| 16850 | 16746 | OMAP AUDIO SUPPORT |
| 16851 | 16747 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 16852 | 16748 | M: Jarkko Nikula <jarkko.nikula@bitmer.com> |
| 16853 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 16749 | +L: linux-sound@vger.kernel.org | |
| 16854 | 16750 | L: linux-omap@vger.kernel.org |
| 16855 | 16751 | S: Maintained |
| 16856 | 16752 | F: sound/soc/ti/n810.c |
| @@ -17407,7 +17303,7 @@ F: include/linux/pm_opp.h · 550 unmodified lines | ||
| 17407 | 17303 | |
| 17408 | 17304 | OPL4 DRIVER |
| 17409 | 17305 | M: Clemens Ladisch <clemens@ladisch.de> |
| 17410 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 17306 | +L: linux-sound@vger.kernel.org | |
| 17411 | 17307 | S: Maintained |
| 17412 | 17308 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 17413 | 17309 | F: sound/drivers/opl4/ |
| @@ -18534,13 +18430,6 @@ F: drivers/pps/ · 1120 unmodified lines | ||
| 18534 | 18430 | F: include/linux/pps*.h |
| 18535 | 18431 | F: include/uapi/linux/pps.h |
| 18536 | 18432 | |
| 18537 | −PPTP DRIVER | |
| 18538 | −M: Dmitry Kozlov <xeb@mail.ru> | |
| 18539 | −L: netdev@vger.kernel.org | |
| 18540 | −S: Maintained | |
| 18541 | −W: http://sourceforge.net/projects/accel-pptp | |
| 18542 | −F: drivers/net/ppp/pptp.c | |
| 18543 | − | |
| 18544 | 18433 | PRESSURE STALL INFORMATION (PSI) |
| 18545 | 18434 | M: Johannes Weiner <hannes@cmpxchg.org> |
| 18546 | 18435 | M: Suren Baghdasaryan <surenb@google.com> |
| @@ -18790,7 +18679,7 @@ F: drivers/crypto/intel/qat/ · 243 unmodified lines | ||
| 18790 | 18679 | |
| 18791 | 18680 | QCOM AUDIO (ASoC) DRIVERS |
| 18792 | 18681 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> |
| 18793 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 18682 | +L: linux-sound@vger.kernel.org | |
| 18794 | 18683 | L: linux-arm-msm@vger.kernel.org |
| 18795 | 18684 | S: Supported |
| 18796 | 18685 | F: Documentation/devicetree/bindings/soc/qcom/qcom,apr* |
| @@ -19514,6 +19403,14 @@ S: Maintained · 717 unmodified lines | ||
| 19514 | 19403 | F: Documentation/tools/rtla/ |
| 19515 | 19404 | F: tools/tracing/rtla/ |
| 19516 | 19405 | |
| 19406 | +Real-time Linux (PREEMPT_RT) | |
| 19407 | +M: Sebastian Andrzej Siewior <bigeasy@linutronix.de> | |
| 19408 | +M: Clark Williams <clrkwllms@kernel.org> | |
| 19409 | +M: Steven Rostedt <rostedt@goodmis.org> | |
| 19410 | +L: linux-rt-devel@lists.linux.dev | |
| 19411 | +S: Supported | |
| 19412 | +K: PREEMPT_RT | |
| 19413 | + | |
| 19517 | 19414 | REALTEK AUDIO CODECS |
| 19518 | 19415 | M: Oder Chiou <oder_chiou@realtek.com> |
| 19519 | 19416 | S: Maintained |
| @@ -19623,15 +19520,6 @@ S: Supported · 103 unmodified lines | ||
| 19623 | 19520 | F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml |
| 19624 | 19521 | F: drivers/i2c/busses/i2c-emev2.c |
| 19625 | 19522 | |
| 19626 | −RENESAS ETHERNET AVB DRIVER | |
| 19627 | −R: Sergey Shtylyov <s.shtylyov@omp.ru> | |
| 19628 | −L: netdev@vger.kernel.org | |
| 19629 | −L: linux-renesas-soc@vger.kernel.org | |
| 19630 | −F: Documentation/devicetree/bindings/net/renesas,etheravb.yaml | |
| 19631 | −F: drivers/net/ethernet/renesas/Kconfig | |
| 19632 | −F: drivers/net/ethernet/renesas/Makefile | |
| 19633 | −F: drivers/net/ethernet/renesas/ravb* | |
| 19634 | − | |
| 19635 | 19523 | RENESAS ETHERNET SWITCH DRIVER |
| 19636 | 19524 | R: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| 19637 | 19525 | L: netdev@vger.kernel.org |
| @@ -19652,7 +19540,7 @@ F: drivers/net/ethernet/renesas/rtsn.* · 14 unmodified lines | ||
| 19652 | 19540 | |
| 19653 | 19541 | RENESAS IDT821034 ASoC CODEC |
| 19654 | 19542 | M: Herve Codina <herve.codina@bootlin.com> |
| 19655 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 19543 | +L: linux-sound@vger.kernel.org | |
| 19656 | 19544 | S: Maintained |
| 19657 | 19545 | F: Documentation/devicetree/bindings/sound/renesas,idt821034.yaml |
| 19658 | 19546 | F: sound/soc/codecs/idt821034.c |
| @@ -19681,14 +19569,6 @@ F: Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml · 22 unmodified lines | ||
| 19681 | 19569 | F: drivers/i2c/busses/i2c-rcar.c |
| 19682 | 19570 | F: drivers/i2c/busses/i2c-sh_mobile.c |
| 19683 | 19571 | |
| 19684 | −RENESAS R-CAR SATA DRIVER | |
| 19685 | −R: Sergey Shtylyov <s.shtylyov@omp.ru> | |
| 19686 | −L: linux-ide@vger.kernel.org | |
| 19687 | −L: linux-renesas-soc@vger.kernel.org | |
| 19688 | −S: Supported | |
| 19689 | −F: Documentation/devicetree/bindings/ata/renesas,rcar-sata.yaml | |
| 19690 | −F: drivers/ata/sata_rcar.c | |
| 19691 | − | |
| 19692 | 19572 | RENESAS R-CAR THERMAL DRIVERS |
| 19693 | 19573 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> |
| 19694 | 19574 | L: linux-renesas-soc@vger.kernel.org |
| @@ -19764,16 +19644,6 @@ S: Supported · 69 unmodified lines | ||
| 19764 | 19644 | F: Documentation/devicetree/bindings/i2c/renesas,rzv2m.yaml |
| 19765 | 19645 | F: drivers/i2c/busses/i2c-rzv2m.c |
| 19766 | 19646 | |
| 19767 | −RENESAS SUPERH ETHERNET DRIVER | |
| 19768 | −R: Sergey Shtylyov <s.shtylyov@omp.ru> | |
| 19769 | −L: netdev@vger.kernel.org | |
| 19770 | −L: linux-renesas-soc@vger.kernel.org | |
| 19771 | −F: Documentation/devicetree/bindings/net/renesas,ether.yaml | |
| 19772 | −F: drivers/net/ethernet/renesas/Kconfig | |
| 19773 | −F: drivers/net/ethernet/renesas/Makefile | |
| 19774 | −F: drivers/net/ethernet/renesas/sh_eth* | |
| 19775 | −F: include/linux/sh_eth.h | |
| 19776 | − | |
| 19777 | 19647 | RENESAS USB PHY DRIVER |
| 19778 | 19648 | M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| 19779 | 19649 | L: linux-renesas-soc@vger.kernel.org |
| @@ -20403,7 +20273,7 @@ F: security/safesetid/ · 623 unmodified lines | ||
| 20403 | 20273 | |
| 20404 | 20274 | SAMSUNG AUDIO (ASoC) DRIVERS |
| 20405 | 20275 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> |
| 20406 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 20276 | +L: linux-sound@vger.kernel.org | |
| 20407 | 20277 | S: Maintained |
| 20408 | 20278 | B: mailto:linux-samsung-soc@vger.kernel.org |
| 20409 | 20279 | F: Documentation/devicetree/bindings/sound/samsung* |
| @@ -20939,7 +20809,7 @@ F: drivers/media/rc/serial_ir.c · 529 unmodified lines | ||
| 20939 | 20809 | |
| 20940 | 20810 | SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus) |
| 20941 | 20811 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> |
| 20942 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 20812 | +L: linux-sound@vger.kernel.org | |
| 20943 | 20813 | S: Maintained |
| 20944 | 20814 | F: Documentation/devicetree/bindings/slimbus/ |
| 20945 | 20815 | F: drivers/slimbus/ |
| @@ -21373,7 +21243,7 @@ F: Documentation/devicetree/bindings/i2c/socionext,synquacer-i2c.yaml · 427 unmodified lines | ||
| 21373 | 21243 | F: drivers/i2c/busses/i2c-synquacer.c |
| 21374 | 21244 | |
| 21375 | 21245 | SOCIONEXT UNIPHIER SOUND DRIVER |
| 21376 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 21246 | +L: linux-sound@vger.kernel.org | |
| 21377 | 21247 | S: Orphan |
| 21378 | 21248 | F: sound/soc/uniphier/ |
| 21379 | 21249 | |
| @@ -21632,7 +21502,7 @@ F: tools/testing/selftests/alsa · 252 unmodified lines | ||
| 21632 | 21502 | |
| 21633 | 21503 | SOUND - COMPRESSED AUDIO |
| 21634 | 21504 | M: Vinod Koul <vkoul@kernel.org> |
| 21635 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 21505 | +L: linux-sound@vger.kernel.org | |
| 21636 | 21506 | S: Supported |
| 21637 | 21507 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 21638 | 21508 | F: Documentation/sound/designs/compress-offload.rst |
| @@ -21695,7 +21565,7 @@ M: Vinod Koul <vkoul@kernel.org> · 56 unmodified lines | ||
| 21695 | 21565 | M: Bard Liao <yung-chuan.liao@linux.intel.com> |
| 21696 | 21566 | R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> |
| 21697 | 21567 | R: Sanyog Kale <sanyog.r.kale@intel.com> |
| 21698 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 21568 | +L: linux-sound@vger.kernel.org | |
| 21699 | 21569 | S: Supported |
| 21700 | 21570 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git |
| 21701 | 21571 | F: Documentation/driver-api/soundwire/ |
| @@ -21768,8 +21638,8 @@ F: drivers/accessibility/speakup/ · 66 unmodified lines | ||
| 21768 | 21638 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT |
| 21769 | 21639 | M: Viresh Kumar <vireshk@kernel.org> |
| 21770 | 21640 | M: Shiraz Hashim <shiraz.linux.kernel@gmail.com> |
| 21771 | −M: soc@kernel.org | |
| 21772 | 21641 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 21642 | +L: soc@lists.linux.dev | |
| 21773 | 21643 | S: Maintained |
| 21774 | 21644 | W: http://www.st.com/spear |
| 21775 | 21645 | F: arch/arm/boot/dts/st/spear* |
| @@ -22168,7 +22038,7 @@ F: kernel/static_call.c · 392 unmodified lines | ||
| 22168 | 22038 | |
| 22169 | 22039 | STI AUDIO (ASoC) DRIVERS |
| 22170 | 22040 | M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> |
| 22171 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 22041 | +L: linux-sound@vger.kernel.org | |
| 22172 | 22042 | S: Maintained |
| 22173 | 22043 | F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt |
| 22174 | 22044 | F: sound/soc/sti/ |
| @@ -22189,7 +22059,7 @@ F: drivers/media/usb/stk1160/ · 14 unmodified lines | ||
| 22189 | 22059 | STM32 AUDIO (ASoC) DRIVERS |
| 22190 | 22060 | M: Olivier Moysan <olivier.moysan@foss.st.com> |
| 22191 | 22061 | M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> |
| 22192 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 22062 | +L: linux-sound@vger.kernel.org | |
| 22193 | 22063 | S: Maintained |
| 22194 | 22064 | F: Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml |
| 22195 | 22065 | F: Documentation/devicetree/bindings/sound/st,stm32-*.yaml |
| @@ -22427,19 +22297,11 @@ F: drivers/tty/serial/8250/8250_lpss.c · 231 unmodified lines | ||
| 22427 | 22297 | |
| 22428 | 22298 | SYNOPSYS DESIGNWARE APB GPIO DRIVER |
| 22429 | 22299 | M: Hoan Tran <hoan@os.amperecomputing.com> |
| 22430 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 22431 | 22300 | L: linux-gpio@vger.kernel.org |
| 22432 | 22301 | S: Maintained |
| 22433 | 22302 | F: Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml |
| 22434 | 22303 | F: drivers/gpio/gpio-dwapb.c |
| 22435 | 22304 | |
| 22436 | −SYNOPSYS DESIGNWARE APB SSI DRIVER | |
| 22437 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 22438 | −L: linux-spi@vger.kernel.org | |
| 22439 | −S: Supported | |
| 22440 | −F: Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml | |
| 22441 | −F: drivers/spi/spi-dw* | |
| 22442 | − | |
| 22443 | 22305 | SYNOPSYS DESIGNWARE AXI DMAC DRIVER |
| 22444 | 22306 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
| 22445 | 22307 | S: Maintained |
| @@ -22892,7 +22754,7 @@ F: drivers/irqchip/irq-xtensa-* · 446 unmodified lines | ||
| 22892 | 22754 | |
| 22893 | 22755 | TEXAS INSTRUMENTS ASoC DRIVERS |
| 22894 | 22756 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 22895 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 22757 | +L: linux-sound@vger.kernel.org | |
| 22896 | 22758 | S: Maintained |
| 22897 | 22759 | F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml |
| 22898 | 22760 | F: sound/soc/ti/ |
| @@ -22901,7 +22763,7 @@ TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS · 2 unmodified lines | ||
| 22901 | 22763 | M: Shenghao Ding <shenghao-ding@ti.com> |
| 22902 | 22764 | M: Kevin Lu <kevin-lu@ti.com> |
| 22903 | 22765 | M: Baojun Xu <baojun.xu@ti.com> |
| 22904 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 22766 | +L: linux-sound@vger.kernel.org | |
| 22905 | 22767 | S: Maintained |
| 22906 | 22768 | F: Documentation/devicetree/bindings/sound/tas2552.txt |
| 22907 | 22769 | F: Documentation/devicetree/bindings/sound/ti,tas2562.yaml |
| @@ -23269,7 +23131,7 @@ F: drivers/soc/ti/* · 361 unmodified lines | ||
| 23269 | 23131 | TI LM49xxx FAMILY ASoC CODEC DRIVERS |
| 23270 | 23132 | M: M R Swami Reddy <mr.swami.reddy@ti.com> |
| 23271 | 23133 | M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com> |
| 23272 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 23134 | +L: linux-sound@vger.kernel.org | |
| 23273 | 23135 | S: Maintained |
| 23274 | 23136 | F: sound/soc/codecs/isabelle* |
| 23275 | 23137 | F: sound/soc/codecs/lm49453* |
| @@ -23284,14 +23146,14 @@ F: drivers/iio/adc/ti-lmp92064.c · 8 unmodified lines | ||
| 23284 | 23146 | |
| 23285 | 23147 | TI PCM3060 ASoC CODEC DRIVER |
| 23286 | 23148 | M: Kirill Marinushkin <kmarinushkin@birdec.com> |
| 23287 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 23149 | +L: linux-sound@vger.kernel.org | |
| 23288 | 23150 | S: Maintained |
| 23289 | 23151 | F: Documentation/devicetree/bindings/sound/pcm3060.txt |
| 23290 | 23152 | F: sound/soc/codecs/pcm3060* |
| 23291 | 23153 | |
| 23292 | 23154 | TI TAS571X FAMILY ASoC CODEC DRIVER |
| 23293 | 23155 | M: Kevin Cernekee <cernekee@chromium.org> |
| 23294 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 23156 | +L: linux-sound@vger.kernel.org | |
| 23295 | 23157 | S: Odd Fixes |
| 23296 | 23158 | F: sound/soc/codecs/tas571x* |
| 23297 | 23159 | |
| @@ -23319,7 +23181,7 @@ F: drivers/iio/adc/ti-tsc2046.c · 21 unmodified lines | ||
| 23319 | 23181 | |
| 23320 | 23182 | TI TWL4030 SERIES SOC CODEC DRIVER |
| 23321 | 23183 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 23322 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 23184 | +L: linux-sound@vger.kernel.org | |
| 23323 | 23185 | S: Maintained |
| 23324 | 23186 | F: sound/soc/codecs/twl4030* |
| 23325 | 23187 | |
| @@ -23749,12 +23611,6 @@ L: linux-input@vger.kernel.org · 423 unmodified lines | ||
| 23749 | 23611 | S: Maintained |
| 23750 | 23612 | F: drivers/hid/hid-udraw-ps3.c |
| 23751 | 23613 | |
| 23752 | −UFS FILESYSTEM | |
| 23753 | −M: Evgeniy Dushistov <dushistov@mail.ru> | |
| 23754 | −S: Maintained | |
| 23755 | −F: Documentation/admin-guide/ufs.rst | |
| 23756 | −F: fs/ufs/ | |
| 23757 | − | |
| 23758 | 23614 | UHID USERSPACE HID IO DRIVER |
| 23759 | 23615 | M: David Rheinsberg <david@readahead.eu> |
| 23760 | 23616 | L: linux-input@vger.kernel.org |
| @@ -23995,7 +23851,7 @@ F: drivers/usb/storage/ · 234 unmodified lines | ||
| 23995 | 23851 | |
| 23996 | 23852 | USB MIDI DRIVER |
| 23997 | 23853 | M: Clemens Ladisch <clemens@ladisch.de> |
| 23998 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 23854 | +L: linux-sound@vger.kernel.org | |
| 23999 | 23855 | S: Maintained |
| 24000 | 23856 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 24001 | 23857 | F: sound/usb/midi.* |
| @@ -24057,6 +23913,7 @@ USB RAW GADGET DRIVER · 55 unmodified lines | ||
| 24057 | 23913 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 24058 | 23914 | L: linux-usb@vger.kernel.org |
| 24059 | 23915 | S: Maintained |
| 23916 | +B: https://github.com/xairy/raw-gadget/issues | |
| 24060 | 23917 | F: Documentation/usb/raw-gadget.rst |
| 24061 | 23918 | F: drivers/usb/gadget/legacy/raw_gadget.c |
| 24062 | 23919 | F: include/uapi/linux/usb/raw_gadget.h |
| @@ -24173,8 +24030,12 @@ F: drivers/usb/host/xhci* · 110 unmodified lines | ||
| 24173 | 24030 | |
| 24174 | 24031 | USER DATAGRAM PROTOCOL (UDP) |
| 24175 | 24032 | M: Willem de Bruijn <willemdebruijn.kernel@gmail.com> |
| 24033 | +L: netdev@vger.kernel.org | |
| 24176 | 24034 | S: Maintained |
| 24177 | 24035 | F: include/linux/udp.h |
| 24036 | +F: include/net/udp.h | |
| 24037 | +F: include/trace/events/udp.h | |
| 24038 | +F: include/uapi/linux/udp.h | |
| 24178 | 24039 | F: net/ipv4/udp.c |
| 24179 | 24040 | F: net/ipv6/udp.c |
| 24180 | 24041 | |
| @@ -24655,7 +24516,7 @@ VIRTIO SOUND DRIVER · 474 unmodified lines | ||
| 24655 | 24516 | M: Anton Yakovlev <anton.yakovlev@opensynergy.com> |
| 24656 | 24517 | M: "Michael S. Tsirkin" <mst@redhat.com> |
| 24657 | 24518 | L: virtualization@lists.linux.dev |
| 24658 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 24519 | +L: linux-sound@vger.kernel.org | |
| 24659 | 24520 | S: Maintained |
| 24660 | 24521 | F: include/uapi/linux/virtio_snd.h |
| 24661 | 24522 | F: sound/virtio/* |
| @@ -24724,9 +24585,10 @@ F: tools/testing/vsock/ · 62 unmodified lines | ||
| 24724 | 24585 | |
| 24725 | 24586 | VMA |
| 24726 | 24587 | M: Andrew Morton <akpm@linux-foundation.org> |
| 24727 | −R: Liam R. Howlett <Liam.Howlett@oracle.com> | |
| 24588 | +M: Liam R. Howlett <Liam.Howlett@oracle.com> | |
| 24589 | +M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 24728 | 24590 | R: Vlastimil Babka <vbabka@suse.cz> |
| 24729 | −R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 24591 | +R: Jann Horn <jannh@google.com> | |
| 24730 | 24592 | L: linux-mm@kvack.org |
| 24731 | 24593 | S: Maintained |
| 24732 | 24594 | W: https://www.linux-mm.org |
| @@ -25384,7 +25246,7 @@ F: include/xen/interface/io/usbif.h · 651 unmodified lines | ||
| 25384 | 25246 | XEN SOUND FRONTEND DRIVER |
| 25385 | 25247 | M: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> |
| 25386 | 25248 | L: xen-devel@lists.xenproject.org (moderated for non-subscribers) |
| 25387 | −L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |
| 25249 | +L: linux-sound@vger.kernel.org | |
| 25388 | 25250 | S: Supported |
| 25389 | 25251 | F: sound/xen/* |
| 25390 | 25252 | |
| @@ -25400,7 +25262,7 @@ F: include/xen/arm/swiotlb-xen.h · 9 unmodified lines | ||
| 25400 | 25262 | F: include/xen/swiotlb-xen.h |
| 25401 | 25263 | |
| 25402 | 25264 | XFS FILESYSTEM |
| 25403 | −M: Chandan Babu R <chandan.babu@oracle.com> | |
| 25265 | +M: Carlos Maiolino <cem@kernel.org> | |
| 25404 | 25266 | R: Darrick J. Wong <djwong@kernel.org> |
| 25405 | 25267 | L: linux-xfs@vger.kernel.org |
| 25406 | 25268 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 12 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc1 | |
| 5 | +EXTRAVERSION = -rc4 | |
| 6 | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -1645,7 +1645,7 @@ help: · 1636 unmodified lines | ||
| 1645 | 1645 | echo '* dtbs - Build device tree blobs for enabled boards'; \ |
| 1646 | 1646 | echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)'; \ |
| 1647 | 1647 | echo ' dt_binding_check - Validate device tree binding documents and examples'; \ |
| 1648 | − echo ' dt_binding_schema - Build processed device tree binding schemas'; \ | |
| 1648 | + echo ' dt_binding_schemas - Build processed device tree binding schemas'; \ | |
| 1649 | 1649 | echo ' dtbs_check - Validate device tree source files';\ |
| 1650 | 1650 | echo '') |
| 1651 | 1651 | |
| @@ -838,7 +838,7 @@ config CFI_CLANG · 837 unmodified lines | ||
| 838 | 838 | config CFI_ICALL_NORMALIZE_INTEGERS |
| 839 | 839 | bool "Normalize CFI tags for integers" |
| 840 | 840 | depends on CFI_CLANG |
| 841 | − depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS | |
| 841 | + depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG | |
| 842 | 842 | help |
| 843 | 843 | This option normalizes the CFI tags for integer types so that all |
| 844 | 844 | integer types of the same size and signedness receive the same CFI |
| @@ -851,21 +851,19 @@ config CFI_ICALL_NORMALIZE_INTEGERS · 6 unmodified lines | ||
| 851 | 851 | |
| 852 | 852 | This option is necessary for using CFI with Rust. If unsure, say N. |
| 853 | 853 | |
| 854 | −config HAVE_CFI_ICALL_NORMALIZE_INTEGERS | |
| 855 | − def_bool !GCOV_KERNEL && !KASAN | |
| 856 | − depends on CFI_CLANG | |
| 854 | +config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG | |
| 855 | + def_bool y | |
| 857 | 856 | depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) |
| 858 | − help | |
| 859 | − Is CFI_ICALL_NORMALIZE_INTEGERS supported with the set of compilers | |
| 860 | − currently in use? | |
| 857 | + # With GCOV/KASAN we need this fix: https://github.com/llvm/llvm-project/pull/104826 | |
| 858 | + depends on CLANG_VERSION >= 190000 || (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS) | |
| 861 | 859 | |
| 862 | − This option defaults to false if GCOV or KASAN is enabled, as there is | |
| 863 | − an LLVM bug that makes normalized integers tags incompatible with | |
| 864 | − KASAN and GCOV. Kconfig currently does not have the infrastructure to | |
| 865 | − detect whether your rustc compiler contains the fix for this bug, so | |
| 866 | − it is assumed that it doesn't. If your compiler has the fix, you can | |
| 867 | − explicitly enable this option in your config file. The Kconfig logic | |
| 868 | − needed to detect this will be added in a future kernel release. | |
| 860 | +config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC | |
| 861 | + def_bool y | |
| 862 | + depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG | |
| 863 | + depends on RUSTC_VERSION >= 107900 | |
| 864 | + # With GCOV/KASAN we need this fix: https://github.com/rust-lang/rust/pull/129373 | |
| 865 | + depends on (RUSTC_LLVM_VERSION >= 190000 && RUSTC_VERSION >= 108200) || \ | |
| 866 | + (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS) | |
| 869 | 867 | |
| 870 | 868 | config CFI_PERMISSIVE |
| 871 | 869 | bool "Use CFI in permissive mode" |
| @@ -77,7 +77,7 @@ · 76 unmodified lines | ||
| 77 | 77 | }; |
| 78 | 78 | |
| 79 | 79 | &hdmi { |
| 80 | − hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; | |
| 80 | + hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>; | |
| 81 | 81 | power-domains = <&power RPI_POWER_DOMAIN_HDMI>; |
| 82 | 82 | status = "okay"; |
| 83 | 83 | }; |
| @@ -200,7 +200,8 @@ config ARM64 · 199 unmodified lines | ||
| 200 | 200 | select HAVE_DMA_CONTIGUOUS |
| 201 | 201 | select HAVE_DYNAMIC_FTRACE |
| 202 | 202 | select HAVE_DYNAMIC_FTRACE_WITH_ARGS \ |
| 203 | − if $(cc-option,-fpatchable-function-entry=2) | |
| 203 | + if (GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS || \ | |
| 204 | + CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS) | |
| 204 | 205 | select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \ |
| 205 | 206 | if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS |
| 206 | 207 | select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \ |
| @@ -286,12 +287,10 @@ config CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS · 79 unmodified lines | ||
| 286 | 287 | def_bool CC_IS_CLANG |
| 287 | 288 | # https://github.com/ClangBuiltLinux/linux/issues/1507 |
| 288 | 289 | depends on AS_IS_GNU || (AS_IS_LLVM && (LD_IS_LLD || LD_VERSION >= 23600)) |
| 289 | − select HAVE_DYNAMIC_FTRACE_WITH_ARGS | |
| 290 | 290 | |
| 291 | 291 | config GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS |
| 292 | 292 | def_bool CC_IS_GCC |
| 293 | 293 | depends on $(cc-option,-fpatchable-function-entry=2) |
| 294 | − select HAVE_DYNAMIC_FTRACE_WITH_ARGS | |
| 295 | 294 | |
| 296 | 295 | config 64BIT |
| 297 | 296 | def_bool y |
| @@ -1097,6 +1096,7 @@ config ARM64_ERRATUM_3194386 · 799 unmodified lines | ||
| 1097 | 1096 | * ARM Cortex-A78C erratum 3324346 |
| 1098 | 1097 | * ARM Cortex-A78C erratum 3324347 |
| 1099 | 1098 | * ARM Cortex-A710 erratam 3324338 |
| 1099 | + * ARM Cortex-A715 errartum 3456084 | |
| 1100 | 1100 | * ARM Cortex-A720 erratum 3456091 |
| 1101 | 1101 | * ARM Cortex-A725 erratum 3456106 |
| 1102 | 1102 | * ARM Cortex-X1 erratum 3324344 |
| @@ -1107,6 +1107,7 @@ config ARM64_ERRATUM_3194386 · 4 unmodified lines | ||
| 1107 | 1107 | * ARM Cortex-X925 erratum 3324334 |
| 1108 | 1108 | * ARM Neoverse-N1 erratum 3324349 |
| 1109 | 1109 | * ARM Neoverse N2 erratum 3324339 |
| 1110 | + * ARM Neoverse-N3 erratum 3456111 | |
| 1110 | 1111 | * ARM Neoverse-V1 erratum 3324341 |
| 1111 | 1112 | * ARM Neoverse V2 erratum 3324336 |
| 1112 | 1113 | * ARM Neoverse-V3 erratum 3312417 |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | # |
| 11 | 11 | # Copyright (C) 1995-2001 by Russell King |
| 12 | 12 | |
| 13 | −LDFLAGS_vmlinux :=--no-undefined -X | |
| 13 | +LDFLAGS_vmlinux :=--no-undefined -X --pic-veneer | |
| 14 | 14 | |
| 15 | 15 | ifeq ($(CONFIG_RELOCATABLE), y) |
| 16 | 16 | # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour |
| @@ -136,7 +136,7 @@ · 135 unmodified lines | ||
| 136 | 136 | }; |
| 137 | 137 | |
| 138 | 138 | cp0_mdio_pins: cp0-mdio-pins { |
| 139 | − marvell,pins = "mpp40", "mpp41"; | |
| 139 | + marvell,pins = "mpp0", "mpp1"; | |
| 140 | 140 | marvell,function = "ge"; |
| 141 | 141 | }; |
| 142 | 142 | |
| @@ -94,6 +94,7 @@ · 93 unmodified lines | ||
| 94 | 94 | #define ARM_CPU_PART_NEOVERSE_V3 0xD84 |
| 95 | 95 | #define ARM_CPU_PART_CORTEX_X925 0xD85 |
| 96 | 96 | #define ARM_CPU_PART_CORTEX_A725 0xD87 |
| 97 | +#define ARM_CPU_PART_NEOVERSE_N3 0xD8E | |
| 97 | 98 | |
| 98 | 99 | #define APM_CPU_PART_XGENE 0x000 |
| 99 | 100 | #define APM_CPU_VAR_POTENZA 0x00 |
| @@ -176,6 +177,7 @@ · 76 unmodified lines | ||
| 176 | 177 | #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) |
| 177 | 178 | #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) |
| 178 | 179 | #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) |
| 180 | +#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3) | |
| 179 | 181 | #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) |
| 180 | 182 | #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) |
| 181 | 183 | #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) |
| @@ -178,6 +178,7 @@ struct kvm_nvhe_init_params { · 177 unmodified lines | ||
| 178 | 178 | unsigned long hcr_el2; |
| 179 | 179 | unsigned long vttbr; |
| 180 | 180 | unsigned long vtcr; |
| 181 | + unsigned long tmp; | |
| 181 | 182 | }; |
| 182 | 183 | |
| 183 | 184 | /* |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | ||
| 51 | 51 | #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) |
| 52 | 52 | #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6) |
| 53 | 53 | #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7) |
| 54 | +#define KVM_REQ_NESTED_S2_UNMAP KVM_ARCH_REQ(8) | |
| 54 | 55 | |
| 55 | 56 | #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ |
| 56 | 57 | KVM_DIRTY_LOG_INITIALLY_SET) |
| @@ -211,6 +212,12 @@ struct kvm_s2_mmu { · 154 unmodified lines | ||
| 211 | 212 | */ |
| 212 | 213 | bool nested_stage2_enabled; |
| 213 | 214 | |
| 215 | + /* | |
| 216 | + * true when this MMU needs to be unmapped before being used for a new | |
| 217 | + * purpose. | |
| 218 | + */ | |
| 219 | + bool pending_unmap; | |
| 220 | + | |
| 214 | 221 | /* |
| 215 | 222 | * 0: Nobody is currently using this, check vttbr for validity |
| 216 | 223 | * >0: Somebody is actively using this. |
| @@ -1441,11 +1448,6 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); · 1224 unmodified lines | ||
| 1441 | 1448 | sign_extend64(__val, id##_##fld##_WIDTH - 1); \ |
| 1442 | 1449 | }) |
| 1443 | 1450 | |
| 1444 | −#define expand_field_sign(id, fld, val) \ | |
| 1445 | − (id##_##fld##_SIGNED ? \ | |
| 1446 | − __expand_field_sign_signed(id, fld, val) : \ | |
| 1447 | − __expand_field_sign_unsigned(id, fld, val)) | |
| 1448 | − | |
| 1449 | 1451 | #define get_idreg_field_unsigned(kvm, id, fld) \ |
| 1450 | 1452 | ({ \ |
| 1451 | 1453 | u64 __val = kvm_read_vm_id_reg((kvm), SYS_##id); \ |
| @@ -1461,20 +1463,26 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); · 9 unmodified lines | ||
| 1461 | 1463 | #define get_idreg_field_enum(kvm, id, fld) \ |
| 1462 | 1464 | get_idreg_field_unsigned(kvm, id, fld) |
| 1463 | 1465 | |
| 1464 | −#define get_idreg_field(kvm, id, fld) \ | |
| 1466 | +#define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ | |
| 1467 | + (get_idreg_field_signed((kvm), id, fld) op __expand_field_sign_signed(id, fld, limit)) | |
| 1468 | + | |
| 1469 | +#define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit) \ | |
| 1470 | + (get_idreg_field_unsigned((kvm), id, fld) op __expand_field_sign_unsigned(id, fld, limit)) | |
| 1471 | + | |
| 1472 | +#define kvm_cmp_feat(kvm, id, fld, op, limit) \ | |
| 1465 | 1473 | (id##_##fld##_SIGNED ? \ |
| 1466 | − get_idreg_field_signed(kvm, id, fld) : \ | |
| 1467 | − get_idreg_field_unsigned(kvm, id, fld)) | |
| 1474 | + kvm_cmp_feat_signed(kvm, id, fld, op, limit) : \ | |
| 1475 | + kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)) | |
| 1468 | 1476 | |
| 1469 | 1477 | #define kvm_has_feat(kvm, id, fld, limit) \ |
| 1470 | − (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit)) | |
| 1478 | + kvm_cmp_feat(kvm, id, fld, >=, limit) | |
| 1471 | 1479 | |
| 1472 | 1480 | #define kvm_has_feat_enum(kvm, id, fld, val) \ |
| 1473 | − (get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val)) | |
| 1481 | + kvm_cmp_feat_unsigned(kvm, id, fld, ==, val) | |
| 1474 | 1482 | |
| 1475 | 1483 | #define kvm_has_feat_range(kvm, id, fld, min, max) \ |
| 1476 | − (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \ | |
| 1477 | − get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max)) | |
| 1484 | + (kvm_cmp_feat(kvm, id, fld, >=, min) && \ | |
| 1485 | + kvm_cmp_feat(kvm, id, fld, <=, max)) | |
| 1478 | 1486 | |
| 1479 | 1487 | /* Check for a given level of PAuth support */ |
| 1480 | 1488 | #define kvm_has_pauth(k, l) \ |
| @@ -166,7 +166,8 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size, · 165 unmodified lines | ||
| 166 | 166 | int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr); |
| 167 | 167 | void __init free_hyp_pgds(void); |
| 168 | 168 | |
| 169 | −void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size); | |
| 169 | +void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, | |
| 170 | + u64 size, bool may_block); | |
| 170 | 171 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); |
| 171 | 172 | void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); |
| 172 | 173 | |
| @@ -78,6 +78,8 @@ extern void kvm_s2_mmu_iterate_by_vmid(struct kvm *kvm, u16 vmid, · 77 unmodified lines | ||
| 78 | 78 | extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu); |
| 79 | 79 | extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu); |
| 80 | 80 | |
| 81 | +extern void check_nested_vcpu_requests(struct kvm_vcpu *vcpu); | |
| 82 | + | |
| 81 | 83 | struct kvm_s2_trans { |
| 82 | 84 | phys_addr_t output; |
| 83 | 85 | unsigned long block_size; |
| @@ -124,7 +126,7 @@ extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, · 40 unmodified lines | ||
| 124 | 126 | struct kvm_s2_trans *trans); |
| 125 | 127 | extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2); |
| 126 | 128 | extern void kvm_nested_s2_wp(struct kvm *kvm); |
| 127 | −extern void kvm_nested_s2_unmap(struct kvm *kvm); | |
| 129 | +extern void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block); | |
| 128 | 130 | extern void kvm_nested_s2_flush(struct kvm *kvm); |
| 129 | 131 | |
| 130 | 132 | unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val); |
| @@ -10,11 +10,9 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <asm/insn.h> |
| 11 | 11 | #include <asm/probes.h> |
| 12 | 12 | |
| 13 | −#define MAX_UINSN_BYTES AARCH64_INSN_SIZE | |
| 14 | − | |
| 15 | 13 | #define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES) |
| 16 | 14 | #define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE |
| 17 | −#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES | |
| 15 | +#define UPROBE_XOL_SLOT_BYTES AARCH64_INSN_SIZE | |
| 18 | 16 | |
| 19 | 17 | typedef __le32 uprobe_opcode_t; |
| 20 | 18 | |
| @@ -23,8 +21,8 @@ struct arch_uprobe_task { · 2 unmodified lines | ||
| 23 | 21 | |
| 24 | 22 | struct arch_uprobe { |
| 25 | 23 | union { |
| 26 | − u8 insn[MAX_UINSN_BYTES]; | |
| 27 | − u8 ixol[MAX_UINSN_BYTES]; | |
| 24 | + __le32 insn; | |
| 25 | + __le32 ixol; | |
| 28 | 26 | }; |
| 29 | 27 | struct arch_probe_insn api; |
| 30 | 28 | bool simulate; |
| @@ -146,6 +146,7 @@ int main(void) · 145 unmodified lines | ||
| 146 | 146 | DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2)); |
| 147 | 147 | DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr)); |
| 148 | 148 | DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr)); |
| 149 | + DEFINE(NVHE_INIT_TMP, offsetof(struct kvm_nvhe_init_params, tmp)); | |
| 149 | 150 | #endif |
| 150 | 151 | #ifdef CONFIG_CPU_PM |
| 151 | 152 | DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp)); |
| @@ -439,6 +439,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = { · 438 unmodified lines | ||
| 439 | 439 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), |
| 440 | 440 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), |
| 441 | 441 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), |
| 442 | + MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), | |
| 442 | 443 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), |
| 443 | 444 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), |
| 444 | 445 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), |
| @@ -447,8 +448,10 @@ static const struct midr_range erratum_spec_ssbs_list[] = { · 2 unmodified lines | ||
| 447 | 448 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), |
| 448 | 449 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), |
| 449 | 450 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), |
| 451 | + MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100), | |
| 450 | 452 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), |
| 451 | 453 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), |
| 454 | + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3), | |
| 452 | 455 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), |
| 453 | 456 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), |
| 454 | 457 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), |
| @@ -99,10 +99,6 @@ arm_probe_decode_insn(probe_opcode_t insn, struct arch_probe_insn *api) · 98 unmodified lines | ||
| 99 | 99 | aarch64_insn_is_blr(insn) || |
| 100 | 100 | aarch64_insn_is_ret(insn)) { |
| 101 | 101 | api->handler = simulate_br_blr_ret; |
| 102 | − } else if (aarch64_insn_is_ldr_lit(insn)) { | |
| 103 | − api->handler = simulate_ldr_literal; | |
| 104 | − } else if (aarch64_insn_is_ldrsw_lit(insn)) { | |
| 105 | − api->handler = simulate_ldrsw_literal; | |
| 106 | 102 | } else { |
| 107 | 103 | /* |
| 108 | 104 | * Instruction cannot be stepped out-of-line and we don't |
| @@ -140,6 +136,17 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi) · 31 unmodified lines | ||
| 140 | 136 | probe_opcode_t insn = le32_to_cpu(*addr); |
| 141 | 137 | probe_opcode_t *scan_end = NULL; |
| 142 | 138 | unsigned long size = 0, offset = 0; |
| 139 | + struct arch_probe_insn *api = &asi->api; | |
| 140 | + | |
| 141 | + if (aarch64_insn_is_ldr_lit(insn)) { | |
| 142 | + api->handler = simulate_ldr_literal; | |
| 143 | + decoded = INSN_GOOD_NO_SLOT; | |
| 144 | + } else if (aarch64_insn_is_ldrsw_lit(insn)) { | |
| 145 | + api->handler = simulate_ldrsw_literal; | |
| 146 | + decoded = INSN_GOOD_NO_SLOT; | |
| 147 | + } else { | |
| 148 | + decoded = arm_probe_decode_insn(insn, &asi->api); | |
| 149 | + } | |
| 143 | 150 | |
| 144 | 151 | /* |
| 145 | 152 | * If there's a symbol defined in front of and near enough to |
| @@ -157,7 +164,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi) · 11 unmodified lines | ||
| 157 | 164 | else |
| 158 | 165 | scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; |
| 159 | 166 | } |
| 160 | − decoded = arm_probe_decode_insn(insn, &asi->api); | |
| 161 | 167 | |
| 162 | 168 | if (decoded != INSN_REJECTED && scan_end) |
| 163 | 169 | if (is_probed_address_atomic(addr - 1, scan_end)) |
| @@ -171,17 +171,15 @@ simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs) · 170 unmodified lines | ||
| 171 | 171 | void __kprobes |
| 172 | 172 | simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) |
| 173 | 173 | { |
| 174 | − u64 *load_addr; | |
| 174 | + unsigned long load_addr; | |
| 175 | 175 | int xn = opcode & 0x1f; |
| 176 | − int disp; | |
| 177 | 176 | |
| 178 | − disp = ldr_displacement(opcode); | |
| 179 | − load_addr = (u64 *) (addr + disp); | |
| 177 | + load_addr = addr + ldr_displacement(opcode); | |
| 180 | 178 | |
| 181 | 179 | if (opcode & (1 << 30)) /* x0-x30 */ |
| 182 | − set_x_reg(regs, xn, *load_addr); | |
| 180 | + set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr)); | |
| 183 | 181 | else /* w0-w30 */ |
| 184 | − set_w_reg(regs, xn, *load_addr); | |
| 182 | + set_w_reg(regs, xn, READ_ONCE(*(u32 *)load_addr)); | |
| 185 | 183 | |
| 186 | 184 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); |
| 187 | 185 | } |
| @@ -189,14 +187,12 @@ simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) · 1 unmodified line | ||
| 189 | 187 | void __kprobes |
| 190 | 188 | simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) |
| 191 | 189 | { |
| 192 | − s32 *load_addr; | |
| 190 | + unsigned long load_addr; | |
| 193 | 191 | int xn = opcode & 0x1f; |
| 194 | − int disp; | |
| 195 | 192 | |
| 196 | − disp = ldr_displacement(opcode); | |
| 197 | − load_addr = (s32 *) (addr + disp); | |
| 193 | + load_addr = addr + ldr_displacement(opcode); | |
| 198 | 194 | |
| 199 | − set_x_reg(regs, xn, *load_addr); | |
| 195 | + set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr)); | |
| 200 | 196 | |
| 201 | 197 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); |
| 202 | 198 | } |
| @@ -42,7 +42,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, · 41 unmodified lines | ||
| 42 | 42 | else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) |
| 43 | 43 | return -EINVAL; |
| 44 | 44 | |
| 45 | − insn = *(probe_opcode_t *)(&auprobe->insn[0]); | |
| 45 | + insn = le32_to_cpu(auprobe->insn); | |
| 46 | 46 | |
| 47 | 47 | switch (arm_probe_decode_insn(insn, &auprobe->api)) { |
| 48 | 48 | case INSN_REJECTED: |
| @@ -108,7 +108,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) · 59 unmodified lines | ||
| 108 | 108 | if (!auprobe->simulate) |
| 109 | 109 | return false; |
| 110 | 110 | |
| 111 | − insn = *(probe_opcode_t *)(&auprobe->insn[0]); | |
| 111 | + insn = le32_to_cpu(auprobe->insn); | |
| 112 | 112 | addr = instruction_pointer(regs); |
| 113 | 113 | |
| 114 | 114 | if (auprobe->api.handler) |
| @@ -412,6 +412,9 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 411 unmodified lines | ||
| 412 | 412 | |
| 413 | 413 | p->thread.cpu_context.x19 = (unsigned long)args->fn; |
| 414 | 414 | p->thread.cpu_context.x20 = (unsigned long)args->fn_arg; |
| 415 | + | |
| 416 | + if (system_supports_poe()) | |
| 417 | + p->thread.por_el0 = POR_EL0_INIT; | |
| 415 | 418 | } |
| 416 | 419 | p->thread.cpu_context.pc = (unsigned long)ret_from_fork; |
| 417 | 420 | p->thread.cpu_context.sp = (unsigned long)childregs; |
| @@ -997,6 +997,9 @@ static int kvm_vcpu_suspend(struct kvm_vcpu *vcpu) · 996 unmodified lines | ||
| 997 | 997 | static int check_vcpu_requests(struct kvm_vcpu *vcpu) |
| 998 | 998 | { |
| 999 | 999 | if (kvm_request_pending(vcpu)) { |
| 1000 | + if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu)) | |
| 1001 | + return -EIO; | |
| 1002 | + | |
| 1000 | 1003 | if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) |
| 1001 | 1004 | kvm_vcpu_sleep(vcpu); |
| 1002 | 1005 | |
| @@ -1031,6 +1034,8 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu) · 28 unmodified lines | ||
| 1031 | 1034 | |
| 1032 | 1035 | if (kvm_dirty_ring_check_request(vcpu)) |
| 1033 | 1036 | return 0; |
| 1037 | + | |
| 1038 | + check_nested_vcpu_requests(vcpu); | |
| 1034 | 1039 | } |
| 1035 | 1040 | |
| 1036 | 1041 | return 1; |
| @@ -338,7 +338,7 @@ static inline void __hyp_sve_save_host(void) · 337 unmodified lines | ||
| 338 | 338 | struct cpu_sve_state *sve_state = *host_data_ptr(sve_state); |
| 339 | 339 | |
| 340 | 340 | sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR); |
| 341 | − write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); | |
| 341 | + write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); | |
| 342 | 342 | __sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), |
| 343 | 343 | &sve_state->fpsr, |
| 344 | 344 | true); |
| @@ -24,28 +24,25 @@ · 23 unmodified lines | ||
| 24 | 24 | .align 11 |
| 25 | 25 | |
| 26 | 26 | SYM_CODE_START(__kvm_hyp_init) |
| 27 | − ventry __invalid // Synchronous EL2t | |
| 28 | − ventry __invalid // IRQ EL2t | |
| 29 | − ventry __invalid // FIQ EL2t | |
| 30 | − ventry __invalid // Error EL2t | |
| 27 | + ventry . // Synchronous EL2t | |
| 28 | + ventry . // IRQ EL2t | |
| 29 | + ventry . // FIQ EL2t | |
| 30 | + ventry . // Error EL2t | |
| 31 | 31 | |
| 32 | − ventry __invalid // Synchronous EL2h | |
| 33 | − ventry __invalid // IRQ EL2h | |
| 34 | − ventry __invalid // FIQ EL2h | |
| 35 | − ventry __invalid // Error EL2h | |
| 32 | + ventry . // Synchronous EL2h | |
| 33 | + ventry . // IRQ EL2h | |
| 34 | + ventry . // FIQ EL2h | |
| 35 | + ventry . // Error EL2h | |
| 36 | 36 | |
| 37 | 37 | ventry __do_hyp_init // Synchronous 64-bit EL1 |
| 38 | − ventry __invalid // IRQ 64-bit EL1 | |
| 39 | − ventry __invalid // FIQ 64-bit EL1 | |
| 40 | − ventry __invalid // Error 64-bit EL1 | |
| 38 | + ventry . // IRQ 64-bit EL1 | |
| 39 | + ventry . // FIQ 64-bit EL1 | |
| 40 | + ventry . // Error 64-bit EL1 | |
| 41 | 41 | |
| 42 | − ventry __invalid // Synchronous 32-bit EL1 | |
| 43 | − ventry __invalid // IRQ 32-bit EL1 | |
| 44 | − ventry __invalid // FIQ 32-bit EL1 | |
| 45 | − ventry __invalid // Error 32-bit EL1 | |
| 46 | − | |
| 47 | −__invalid: | |
| 48 | − b . | |
| 42 | + ventry . // Synchronous 32-bit EL1 | |
| 43 | + ventry . // IRQ 32-bit EL1 | |
| 44 | + ventry . // FIQ 32-bit EL1 | |
| 45 | + ventry . // Error 32-bit EL1 | |
| 49 | 46 | |
| 50 | 47 | /* |
| 51 | 48 | * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers. |
| @@ -76,6 +73,13 @@ __do_hyp_init: · 24 unmodified lines | ||
| 76 | 73 | eret |
| 77 | 74 | SYM_CODE_END(__kvm_hyp_init) |
| 78 | 75 | |
| 76 | +SYM_CODE_START_LOCAL(__kvm_init_el2_state) | |
| 77 | + /* Initialize EL2 CPU state to sane values. */ | |
| 78 | + init_el2_state // Clobbers x0..x2 | |
| 79 | + finalise_el2_state | |
| 80 | + ret | |
| 81 | +SYM_CODE_END(__kvm_init_el2_state) | |
| 82 | + | |
| 79 | 83 | /* |
| 80 | 84 | * Initialize the hypervisor in EL2. |
| 81 | 85 | * |
| @@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init) · 20 unmodified lines | ||
| 102 | 106 | // TPIDR_EL2 is used to preserve x0 across the macro maze... |
| 103 | 107 | isb |
| 104 | 108 | msr tpidr_el2, x0 |
| 105 | − init_el2_state | |
| 106 | − finalise_el2_state | |
| 109 | + str lr, [x0, #NVHE_INIT_TMP] | |
| 110 | + | |
| 111 | + bl __kvm_init_el2_state | |
| 112 | + | |
| 107 | 113 | mrs x0, tpidr_el2 |
| 114 | + ldr lr, [x0, #NVHE_INIT_TMP] | |
| 108 | 115 | |
| 109 | 116 | 1: |
| 110 | 117 | ldr x1, [x0, #NVHE_INIT_TPIDR_EL2] |
| @@ -199,9 +206,8 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) · 88 unmodified lines | ||
| 199 | 206 | |
| 200 | 207 | 2: msr SPsel, #1 // We want to use SP_EL{1,2} |
| 201 | 208 | |
| 202 | − /* Initialize EL2 CPU state to sane values. */ | |
| 203 | − init_el2_state // Clobbers x0..x2 | |
| 204 | − finalise_el2_state | |
| 209 | + bl __kvm_init_el2_state | |
| 210 | + | |
| 205 | 211 | __init_el2_nvhe_prepare_eret |
| 206 | 212 | |
| 207 | 213 | /* Enable MMU, set vectors and stack. */ |
| @@ -33,7 +33,7 @@ static void __hyp_sve_save_guest(struct kvm_vcpu *vcpu) · 32 unmodified lines | ||
| 33 | 33 | */ |
| 34 | 34 | sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2); |
| 35 | 35 | __sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true); |
| 36 | − write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); | |
| 36 | + write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); | |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | static void __hyp_sve_restore_host(void) |
| @@ -45,10 +45,11 @@ static void __hyp_sve_restore_host(void) · 5 unmodified lines | ||
| 45 | 45 | * the host. The layout of the data when saving the sve state depends |
| 46 | 46 | * on the VL, so use a consistent (i.e., the maximum) host VL. |
| 47 | 47 | * |
| 48 | − * Setting ZCR_EL2 to ZCR_ELx_LEN_MASK sets the effective length | |
| 49 | − * supported by the system (or limited at EL3). | |
| 48 | + * Note that this constrains the PE to the maximum shared VL | |
| 49 | + * that was discovered, if we wish to use larger VLs this will | |
| 50 | + * need to be revisited. | |
| 50 | 51 | */ |
| 51 | − write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); | |
| 52 | + write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); | |
| 52 | 53 | __sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), |
| 53 | 54 | &sve_state->fpsr, |
| 54 | 55 | true); |
| @@ -488,7 +489,8 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) · 433 unmodified lines | ||
| 488 | 489 | case ESR_ELx_EC_SVE: |
| 489 | 490 | cpacr_clear_set(0, CPACR_ELx_ZEN); |
| 490 | 491 | isb(); |
| 491 | − sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); | |
| 492 | + sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, | |
| 493 | + SYS_ZCR_EL2); | |
| 492 | 494 | break; |
| 493 | 495 | case ESR_ELx_EC_IABT_LOW: |
| 494 | 496 | case ESR_ELx_EC_DABT_LOW: |
| @@ -574,12 +574,14 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu, · 573 unmodified lines | ||
| 574 | 574 | unlock: |
| 575 | 575 | hyp_spin_unlock(&vm_table_lock); |
| 576 | 576 | |
| 577 | − if (ret) | |
| 577 | + if (ret) { | |
| 578 | 578 | unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu)); |
| 579 | + return ret; | |
| 580 | + } | |
| 579 | 581 | |
| 580 | 582 | hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu); |
| 581 | 583 | |
| 582 | − return ret; | |
| 584 | + return 0; | |
| 583 | 585 | } |
| 584 | 586 | |
| 585 | 587 | static void |
| @@ -317,7 +317,7 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu) · 316 unmodified lines | ||
| 317 | 317 | * to the guest, and hide SSBS so that the |
| 318 | 318 | * guest stays protected. |
| 319 | 319 | */ |
| 320 | − if (cpus_have_final_cap(ARM64_SSBS)) | |
| 320 | + if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP)) | |
| 321 | 321 | break; |
| 322 | 322 | fallthrough; |
| 323 | 323 | case SPECTRE_UNAFFECTED: |
| @@ -428,7 +428,7 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) · 104 unmodified lines | ||
| 428 | 428 | * Convert the workaround level into an easy-to-compare number, where higher |
| 429 | 429 | * values mean better protection. |
| 430 | 430 | */ |
| 431 | −static int get_kernel_wa_level(u64 regid) | |
| 431 | +static int get_kernel_wa_level(struct kvm_vcpu *vcpu, u64 regid) | |
| 432 | 432 | { |
| 433 | 433 | switch (regid) { |
| 434 | 434 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: |
| @@ -449,7 +449,7 @@ static int get_kernel_wa_level(u64 regid) · 14 unmodified lines | ||
| 449 | 449 | * don't have any FW mitigation if SSBS is there at |
| 450 | 450 | * all times. |
| 451 | 451 | */ |
| 452 | − if (cpus_have_final_cap(ARM64_SSBS)) | |
| 452 | + if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP)) | |
| 453 | 453 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; |
| 454 | 454 | fallthrough; |
| 455 | 455 | case SPECTRE_UNAFFECTED: |
| @@ -486,7 +486,7 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 30 unmodified lines | ||
| 486 | 486 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: |
| 487 | 487 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: |
| 488 | 488 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: |
| 489 | − val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; | |
| 489 | + val = get_kernel_wa_level(vcpu, reg->id) & KVM_REG_FEATURE_LEVEL_MASK; | |
| 490 | 490 | break; |
| 491 | 491 | case KVM_REG_ARM_STD_BMAP: |
| 492 | 492 | val = READ_ONCE(smccc_feat->std_bmap); |
| @@ -588,7 +588,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 95 unmodified lines | ||
| 588 | 588 | if (val & ~KVM_REG_FEATURE_LEVEL_MASK) |
| 589 | 589 | return -EINVAL; |
| 590 | 590 | |
| 591 | − if (get_kernel_wa_level(reg->id) < val) | |
| 591 | + if (get_kernel_wa_level(vcpu, reg->id) < val) | |
| 592 | 592 | return -EINVAL; |
| 593 | 593 | |
| 594 | 594 | return 0; |
| @@ -624,7 +624,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 29 unmodified lines | ||
| 624 | 624 | * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the |
| 625 | 625 | * other way around. |
| 626 | 626 | */ |
| 627 | − if (get_kernel_wa_level(reg->id) < wa_level) | |
| 627 | + if (get_kernel_wa_level(vcpu, reg->id) < wa_level) | |
| 628 | 628 | return -EINVAL; |
| 629 | 629 | |
| 630 | 630 | return 0; |
| @@ -328,9 +328,10 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 · 327 unmodified lines | ||
| 328 | 328 | may_block)); |
| 329 | 329 | } |
| 330 | 330 | |
| 331 | −void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size) | |
| 331 | +void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, | |
| 332 | + u64 size, bool may_block) | |
| 332 | 333 | { |
| 333 | − __unmap_stage2_range(mmu, start, size, true); | |
| 334 | + __unmap_stage2_range(mmu, start, size, may_block); | |
| 334 | 335 | } |
| 335 | 336 | |
| 336 | 337 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end) |
| @@ -1015,7 +1016,7 @@ static void stage2_unmap_memslot(struct kvm *kvm, · 678 unmodified lines | ||
| 1015 | 1016 | |
| 1016 | 1017 | if (!(vma->vm_flags & VM_PFNMAP)) { |
| 1017 | 1018 | gpa_t gpa = addr + (vm_start - memslot->userspace_addr); |
| 1018 | − kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, vm_end - vm_start); | |
| 1019 | + kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, vm_end - vm_start, true); | |
| 1019 | 1020 | } |
| 1020 | 1021 | hva = vm_end; |
| 1021 | 1022 | } while (hva < reg_end); |
| @@ -1042,7 +1043,7 @@ void stage2_unmap_vm(struct kvm *kvm) · 20 unmodified lines | ||
| 1042 | 1043 | kvm_for_each_memslot(memslot, bkt, slots) |
| 1043 | 1044 | stage2_unmap_memslot(kvm, memslot); |
| 1044 | 1045 | |
| 1045 | − kvm_nested_s2_unmap(kvm); | |
| 1046 | + kvm_nested_s2_unmap(kvm, true); | |
| 1046 | 1047 | |
| 1047 | 1048 | write_unlock(&kvm->mmu_lock); |
| 1048 | 1049 | mmap_read_unlock(current->mm); |
| @@ -1912,7 +1913,7 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) · 863 unmodified lines | ||
| 1912 | 1913 | (range->end - range->start) << PAGE_SHIFT, |
| 1913 | 1914 | range->may_block); |
| 1914 | 1915 | |
| 1915 | − kvm_nested_s2_unmap(kvm); | |
| 1916 | + kvm_nested_s2_unmap(kvm, range->may_block); | |
| 1916 | 1917 | return false; |
| 1917 | 1918 | } |
| 1918 | 1919 | |
| @@ -2179,8 +2180,8 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, · 260 unmodified lines | ||
| 2179 | 2180 | phys_addr_t size = slot->npages << PAGE_SHIFT; |
| 2180 | 2181 | |
| 2181 | 2182 | write_lock(&kvm->mmu_lock); |
| 2182 | − kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size); | |
| 2183 | − kvm_nested_s2_unmap(kvm); | |
| 2183 | + kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size, true); | |
| 2184 | + kvm_nested_s2_unmap(kvm, true); | |
| 2184 | 2185 | write_unlock(&kvm->mmu_lock); |
| 2185 | 2186 | } |
| 2186 | 2187 | |
| @@ -632,9 +632,9 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu) · 631 unmodified lines | ||
| 632 | 632 | /* Set the scene for the next search */ |
| 633 | 633 | kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size; |
| 634 | 634 | |
| 635 | − /* Clear the old state */ | |
| 635 | + /* Make sure we don't forget to do the laundry */ | |
| 636 | 636 | if (kvm_s2_mmu_valid(s2_mmu)) |
| 637 | − kvm_stage2_unmap_range(s2_mmu, 0, kvm_phys_size(s2_mmu)); | |
| 637 | + s2_mmu->pending_unmap = true; | |
| 638 | 638 | |
| 639 | 639 | /* |
| 640 | 640 | * The virtual VMID (modulo CnP) will be used as a key when matching |
| @@ -650,6 +650,16 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu) · 9 unmodified lines | ||
| 650 | 650 | |
| 651 | 651 | out: |
| 652 | 652 | atomic_inc(&s2_mmu->refcnt); |
| 653 | + | |
| 654 | + /* | |
| 655 | + * Set the vCPU request to perform an unmap, even if the pending unmap | |
| 656 | + * originates from another vCPU. This guarantees that the MMU has been | |
| 657 | + * completely unmapped before any vCPU actually uses it, and allows | |
| 658 | + * multiple vCPUs to lend a hand with completing the unmap. | |
| 659 | + */ | |
| 660 | + if (s2_mmu->pending_unmap) | |
| 661 | + kvm_make_request(KVM_REQ_NESTED_S2_UNMAP, vcpu); | |
| 662 | + | |
| 653 | 663 | return s2_mmu; |
| 654 | 664 | } |
| 655 | 665 | |
| @@ -663,6 +673,13 @@ void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu) · 7 unmodified lines | ||
| 663 | 673 | |
| 664 | 674 | void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu) |
| 665 | 675 | { |
| 676 | + /* | |
| 677 | + * The vCPU kept its reference on the MMU after the last put, keep | |
| 678 | + * rolling with it. | |
| 679 | + */ | |
| 680 | + if (vcpu->arch.hw_mmu) | |
| 681 | + return; | |
| 682 | + | |
| 666 | 683 | if (is_hyp_ctxt(vcpu)) { |
| 667 | 684 | vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; |
| 668 | 685 | } else { |
| @@ -674,10 +691,18 @@ void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu) · 5 unmodified lines | ||
| 674 | 691 | |
| 675 | 692 | void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu) |
| 676 | 693 | { |
| 677 | − if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu)) { | |
| 694 | + /* | |
| 695 | + * Keep a reference on the associated stage-2 MMU if the vCPU is | |
| 696 | + * scheduling out and not in WFI emulation, suggesting it is likely to | |
| 697 | + * reuse the MMU sometime soon. | |
| 698 | + */ | |
| 699 | + if (vcpu->scheduled_out && !vcpu_get_flag(vcpu, IN_WFI)) | |
| 700 | + return; | |
| 701 | + | |
| 702 | + if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu)) | |
| 678 | 703 | atomic_dec(&vcpu->arch.hw_mmu->refcnt); |
| 679 | − vcpu->arch.hw_mmu = NULL; | |
| 680 | − } | |
| 704 | + | |
| 705 | + vcpu->arch.hw_mmu = NULL; | |
| 681 | 706 | } |
| 682 | 707 | |
| 683 | 708 | /* |
| @@ -730,7 +755,7 @@ void kvm_nested_s2_wp(struct kvm *kvm) · 46 unmodified lines | ||
| 730 | 755 | } |
| 731 | 756 | } |
| 732 | 757 | |
| 733 | −void kvm_nested_s2_unmap(struct kvm *kvm) | |
| 758 | +void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block) | |
| 734 | 759 | { |
| 735 | 760 | int i; |
| 736 | 761 | |
| @@ -740,7 +765,7 @@ void kvm_nested_s2_unmap(struct kvm *kvm) · 3 unmodified lines | ||
| 740 | 765 | struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i]; |
| 741 | 766 | |
| 742 | 767 | if (kvm_s2_mmu_valid(mmu)) |
| 743 | − kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu)); | |
| 768 | + kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), may_block); | |
| 744 | 769 | } |
| 745 | 770 | } |
| 746 | 771 | |
| @@ -1184,3 +1209,17 @@ int kvm_init_nv_sysregs(struct kvm *kvm) · 437 unmodified lines | ||
| 1184 | 1209 | |
| 1185 | 1210 | return 0; |
| 1186 | 1211 | } |
| 1212 | + | |
| 1213 | +void check_nested_vcpu_requests(struct kvm_vcpu *vcpu) | |
| 1214 | +{ | |
| 1215 | + if (kvm_check_request(KVM_REQ_NESTED_S2_UNMAP, vcpu)) { | |
| 1216 | + struct kvm_s2_mmu *mmu = vcpu->arch.hw_mmu; | |
| 1217 | + | |
| 1218 | + write_lock(&vcpu->kvm->mmu_lock); | |
| 1219 | + if (mmu->pending_unmap) { | |
| 1220 | + kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), true); | |
| 1221 | + mmu->pending_unmap = false; | |
| 1222 | + } | |
| 1223 | + write_unlock(&vcpu->kvm->mmu_lock); | |
| 1224 | + } | |
| 1225 | +} | |
| @@ -1527,6 +1527,14 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, · 1526 unmodified lines | ||
| 1527 | 1527 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE); |
| 1528 | 1528 | |
| 1529 | 1529 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME); |
| 1530 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_RNDR_trap); | |
| 1531 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_NMI); | |
| 1532 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE_frac); | |
| 1533 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_GCS); | |
| 1534 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_THE); | |
| 1535 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTEX); | |
| 1536 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_DF2); | |
| 1537 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_PFAR); | |
| 1530 | 1538 | break; |
| 1531 | 1539 | case SYS_ID_AA64PFR2_EL1: |
| 1532 | 1540 | /* We only expose FPMR */ |
| @@ -1550,7 +1558,8 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, · 17 unmodified lines | ||
| 1550 | 1558 | val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK; |
| 1551 | 1559 | break; |
| 1552 | 1560 | case SYS_ID_AA64MMFR3_EL1: |
| 1553 | − val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1POE; | |
| 1561 | + val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1POE | | |
| 1562 | + ID_AA64MMFR3_EL1_S1PIE; | |
| 1554 | 1563 | break; |
| 1555 | 1564 | case SYS_ID_MMFR4_EL1: |
| 1556 | 1565 | val &= ~ARM64_FEATURE_MASK(ID_MMFR4_EL1_CCIDX); |
| @@ -1985,7 +1994,7 @@ static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) · 428 unmodified lines | ||
| 1985 | 1994 | * one cache line. |
| 1986 | 1995 | */ |
| 1987 | 1996 | if (kvm_has_mte(vcpu->kvm)) |
| 1988 | − clidr |= 2 << CLIDR_TTYPE_SHIFT(loc); | |
| 1997 | + clidr |= 2ULL << CLIDR_TTYPE_SHIFT(loc); | |
| 1989 | 1998 | |
| 1990 | 1999 | __vcpu_sys_reg(vcpu, r->reg) = clidr; |
| 1991 | 2000 | |
| @@ -2376,7 +2385,19 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 384 unmodified lines | ||
| 2376 | 2385 | ID_AA64PFR0_EL1_RAS | |
| 2377 | 2386 | ID_AA64PFR0_EL1_AdvSIMD | |
| 2378 | 2387 | ID_AA64PFR0_EL1_FP), }, |
| 2379 | − ID_SANITISED(ID_AA64PFR1_EL1), | |
| 2388 | + ID_WRITABLE(ID_AA64PFR1_EL1, ~(ID_AA64PFR1_EL1_PFAR | | |
| 2389 | + ID_AA64PFR1_EL1_DF2 | | |
| 2390 | + ID_AA64PFR1_EL1_MTEX | | |
| 2391 | + ID_AA64PFR1_EL1_THE | | |
| 2392 | + ID_AA64PFR1_EL1_GCS | | |
| 2393 | + ID_AA64PFR1_EL1_MTE_frac | | |
| 2394 | + ID_AA64PFR1_EL1_NMI | | |
| 2395 | + ID_AA64PFR1_EL1_RNDR_trap | | |
| 2396 | + ID_AA64PFR1_EL1_SME | | |
| 2397 | + ID_AA64PFR1_EL1_RES0 | | |
| 2398 | + ID_AA64PFR1_EL1_MPAM_frac | | |
| 2399 | + ID_AA64PFR1_EL1_RAS_frac | | |
| 2400 | + ID_AA64PFR1_EL1_MTE)), | |
| 2380 | 2401 | ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR), |
| 2381 | 2402 | ID_UNALLOCATED(4,3), |
| 2382 | 2403 | ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0), |
| @@ -2390,7 +2411,21 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 7 unmodified lines | ||
| 2390 | 2411 | .get_user = get_id_reg, |
| 2391 | 2412 | .set_user = set_id_aa64dfr0_el1, |
| 2392 | 2413 | .reset = read_sanitised_id_aa64dfr0_el1, |
| 2393 | − .val = ID_AA64DFR0_EL1_PMUVer_MASK | | |
| 2414 | + /* | |
| 2415 | + * Prior to FEAT_Debugv8.9, the architecture defines context-aware | |
| 2416 | + * breakpoints (CTX_CMPs) as the highest numbered breakpoints (BRPs). | |
| 2417 | + * KVM does not trap + emulate the breakpoint registers, and as such | |
| 2418 | + * cannot support a layout that misaligns with the underlying hardware. | |
| 2419 | + * While it may be possible to describe a subset that aligns with | |
| 2420 | + * hardware, just prevent changes to BRPs and CTX_CMPs altogether for | |
| 2421 | + * simplicity. | |
| 2422 | + * | |
| 2423 | + * See DDI0487K.a, section D2.8.3 Breakpoint types and linking | |
| 2424 | + * of breakpoints for more details. | |
| 2425 | + */ | |
| 2426 | + .val = ID_AA64DFR0_EL1_DoubleLock_MASK | | |
| 2427 | + ID_AA64DFR0_EL1_WRPs_MASK | | |
| 2428 | + ID_AA64DFR0_EL1_PMUVer_MASK | | |
| 2394 | 2429 | ID_AA64DFR0_EL1_DebugVer_MASK, }, |
| 2395 | 2430 | ID_SANITISED(ID_AA64DFR1_EL1), |
| 2396 | 2431 | ID_UNALLOCATED(5,2), |
| @@ -2433,6 +2468,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 36 unmodified lines | ||
| 2433 | 2468 | ID_AA64MMFR2_EL1_NV | |
| 2434 | 2469 | ID_AA64MMFR2_EL1_CCIDX)), |
| 2435 | 2470 | ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX | |
| 2471 | + ID_AA64MMFR3_EL1_S1PIE | | |
| 2436 | 2472 | ID_AA64MMFR3_EL1_S1POE)), |
| 2437 | 2473 | ID_SANITISED(ID_AA64MMFR4_EL1), |
| 2438 | 2474 | ID_UNALLOCATED(7,5), |
| @@ -2903,7 +2939,7 @@ static bool handle_alle1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 464 unmodified lines | ||
| 2903 | 2939 | * Drop all shadow S2s, resulting in S1/S2 TLBIs for each of the |
| 2904 | 2940 | * corresponding VMIDs. |
| 2905 | 2941 | */ |
| 2906 | − kvm_nested_s2_unmap(vcpu->kvm); | |
| 2942 | + kvm_nested_s2_unmap(vcpu->kvm, true); | |
| 2907 | 2943 | |
| 2908 | 2944 | write_unlock(&vcpu->kvm->mmu_lock); |
| 2909 | 2945 | |
| @@ -2955,7 +2991,30 @@ union tlbi_info { · 45 unmodified lines | ||
| 2955 | 2991 | static void s2_mmu_unmap_range(struct kvm_s2_mmu *mmu, |
| 2956 | 2992 | const union tlbi_info *info) |
| 2957 | 2993 | { |
| 2958 | − kvm_stage2_unmap_range(mmu, info->range.start, info->range.size); | |
| 2994 | + /* | |
| 2995 | + * The unmap operation is allowed to drop the MMU lock and block, which | |
| 2996 | + * means that @mmu could be used for a different context than the one | |
| 2997 | + * currently being invalidated. | |
| 2998 | + * | |
| 2999 | + * This behavior is still safe, as: | |
| 3000 | + * | |
| 3001 | + * 1) The vCPU(s) that recycled the MMU are responsible for invalidating | |
| 3002 | + * the entire MMU before reusing it, which still honors the intent | |
| 3003 | + * of a TLBI. | |
| 3004 | + * | |
| 3005 | + * 2) Until the guest TLBI instruction is 'retired' (i.e. increment PC | |
| 3006 | + * and ERET to the guest), other vCPUs are allowed to use stale | |
| 3007 | + * translations. | |
| 3008 | + * | |
| 3009 | + * 3) Accidentally unmapping an unrelated MMU context is nonfatal, and | |
| 3010 | + * at worst may cause more aborts for shadow stage-2 fills. | |
| 3011 | + * | |
| 3012 | + * Dropping the MMU lock also implies that shadow stage-2 fills could | |
| 3013 | + * happen behind the back of the TLBI. This is still safe, though, as | |
| 3014 | + * the L1 needs to put its stage-2 in a consistent state before doing | |
| 3015 | + * the TLBI. | |
| 3016 | + */ | |
| 3017 | + kvm_stage2_unmap_range(mmu, info->range.start, info->range.size, true); | |
| 2959 | 3018 | } |
| 2960 | 3019 | |
| 2961 | 3020 | static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| @@ -3050,7 +3109,11 @@ static void s2_mmu_unmap_ipa(struct kvm_s2_mmu *mmu, · 88 unmodified lines | ||
| 3050 | 3109 | max_size = compute_tlb_inval_range(mmu, info->ipa.addr); |
| 3051 | 3110 | base_addr &= ~(max_size - 1); |
| 3052 | 3111 | |
| 3053 | − kvm_stage2_unmap_range(mmu, base_addr, max_size); | |
| 3112 | + /* | |
| 3113 | + * See comment in s2_mmu_unmap_range() for why this is allowed to | |
| 3114 | + * reschedule. | |
| 3115 | + */ | |
| 3116 | + kvm_stage2_unmap_range(mmu, base_addr, max_size, true); | |
| 3054 | 3117 | } |
| 3055 | 3118 | |
| 3056 | 3119 | static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| @@ -417,8 +417,28 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) · 416 unmodified lines | ||
| 417 | 417 | kfree(vgic_cpu->private_irqs); |
| 418 | 418 | vgic_cpu->private_irqs = NULL; |
| 419 | 419 | |
| 420 | − if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) | |
| 420 | + if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { | |
| 421 | + /* | |
| 422 | + * If this vCPU is being destroyed because of a failed creation | |
| 423 | + * then unregister the redistributor to avoid leaving behind a | |
| 424 | + * dangling pointer to the vCPU struct. | |
| 425 | + * | |
| 426 | + * vCPUs that have been successfully created (i.e. added to | |
| 427 | + * kvm->vcpu_array) get unregistered in kvm_vgic_destroy(), as | |
| 428 | + * this function gets called while holding kvm->arch.config_lock | |
| 429 | + * in the VM teardown path and would otherwise introduce a lock | |
| 430 | + * inversion w.r.t. kvm->srcu. | |
| 431 | + * | |
| 432 | + * vCPUs that failed creation are torn down outside of the | |
| 433 | + * kvm->arch.config_lock and do not get unregistered in | |
| 434 | + * kvm_vgic_destroy(), meaning it is both safe and necessary to | |
| 435 | + * do so here. | |
| 436 | + */ | |
| 437 | + if (kvm_get_vcpu_by_id(vcpu->kvm, vcpu->vcpu_id) != vcpu) | |
| 438 | + vgic_unregister_redist_iodev(vcpu); | |
| 439 | + | |
| 421 | 440 | vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; |
| 441 | + } | |
| 422 | 442 | } |
| 423 | 443 | |
| 424 | 444 | void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) |
| @@ -524,22 +544,31 @@ int kvm_vgic_map_resources(struct kvm *kvm) · 99 unmodified lines | ||
| 524 | 544 | if (ret) |
| 525 | 545 | goto out; |
| 526 | 546 | |
| 527 | − dist->ready = true; | |
| 528 | 547 | dist_base = dist->vgic_dist_base; |
| 529 | 548 | mutex_unlock(&kvm->arch.config_lock); |
| 530 | 549 | |
| 531 | 550 | ret = vgic_register_dist_iodev(kvm, dist_base, type); |
| 532 | − if (ret) | |
| 551 | + if (ret) { | |
| 533 | 552 | kvm_err("Unable to register VGIC dist MMIO regions\n"); |
| 553 | + goto out_slots; | |
| 554 | + } | |
| 534 | 555 | |
| 556 | + /* | |
| 557 | + * kvm_io_bus_register_dev() guarantees all readers see the new MMIO | |
| 558 | + * registration before returning through synchronize_srcu(), which also | |
| 559 | + * implies a full memory barrier. As such, marking the distributor as | |
| 560 | + * 'ready' here is guaranteed to be ordered after all vCPUs having seen | |
| 561 | + * a completely configured distributor. | |
| 562 | + */ | |
| 563 | + dist->ready = true; | |
| 535 | 564 | goto out_slots; |
| 536 | 565 | out: |
| 537 | 566 | mutex_unlock(&kvm->arch.config_lock); |
| 538 | 567 | out_slots: |
| 539 | − mutex_unlock(&kvm->slots_lock); | |
| 540 | − | |
| 541 | 568 | if (ret) |
| 542 | − kvm_vgic_destroy(kvm); | |
| 569 | + kvm_vm_dead(kvm); | |
| 570 | + | |
| 571 | + mutex_unlock(&kvm->slots_lock); | |
| 543 | 572 | |
| 544 | 573 | return ret; |
| 545 | 574 | } |
| @@ -236,7 +236,12 @@ static int vgic_set_common_attr(struct kvm_device *dev, · 235 unmodified lines | ||
| 236 | 236 | |
| 237 | 237 | mutex_lock(&dev->kvm->arch.config_lock); |
| 238 | 238 | |
| 239 | − if (vgic_ready(dev->kvm) || dev->kvm->arch.vgic.nr_spis) | |
| 239 | + /* | |
| 240 | + * Either userspace has already configured NR_IRQS or | |
| 241 | + * the vgic has already been initialized and vgic_init() | |
| 242 | + * supplied a default amount of SPIs. | |
| 243 | + */ | |
| 244 | + if (dev->kvm->arch.vgic.nr_spis) | |
| 240 | 245 | ret = -EBUSY; |
| 241 | 246 | else |
| 242 | 247 | dev->kvm->arch.vgic.nr_spis = |
| @@ -2220,7 +2220,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im, · 2219 unmodified lines | ||
| 2220 | 2220 | emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx); |
| 2221 | 2221 | |
| 2222 | 2222 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 2223 | − emit_a64_mov_i64(A64_R(0), (const u64)im, ctx); | |
| 2223 | + /* for the first pass, assume the worst case */ | |
| 2224 | + if (!ctx->image) | |
| 2225 | + ctx->idx += 4; | |
| 2226 | + else | |
| 2227 | + emit_a64_mov_i64(A64_R(0), (const u64)im, ctx); | |
| 2224 | 2228 | emit_call((const u64)__bpf_tramp_enter, ctx); |
| 2225 | 2229 | } |
| 2226 | 2230 | |
| @@ -2264,7 +2268,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im, · 37 unmodified lines | ||
| 2264 | 2268 | |
| 2265 | 2269 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 2266 | 2270 | im->ip_epilogue = ctx->ro_image + ctx->idx; |
| 2267 | − emit_a64_mov_i64(A64_R(0), (const u64)im, ctx); | |
| 2271 | + /* for the first pass, assume the worst case */ | |
| 2272 | + if (!ctx->image) | |
| 2273 | + ctx->idx += 4; | |
| 2274 | + else | |
| 2275 | + emit_a64_mov_i64(A64_R(0), (const u64)im, ctx); | |
| 2268 | 2276 | emit_call((const u64)__bpf_tramp_exit, ctx); |
| 2269 | 2277 | } |
| 2270 | 2278 | |
| @@ -26,6 +26,10 @@ struct loongson_board_info { · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #define NR_WORDS DIV_ROUND_UP(NR_CPUS, BITS_PER_LONG) |
| 28 | 28 | |
| 29 | +/* | |
| 30 | + * The "core" of cores_per_node and cores_per_package stands for a | |
| 31 | + * logical core, which means in a SMT system it stands for a thread. | |
| 32 | + */ | |
| 29 | 33 | struct loongson_system_configuration { |
| 30 | 34 | int nr_cpus; |
| 31 | 35 | int nr_nodes; |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #define XRANGE_SHIFT (48) |
| 17 | 17 | |
| 18 | 18 | /* Valid address length */ |
| 19 | −#define XRANGE_SHADOW_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3) | |
| 19 | +#define XRANGE_SHADOW_SHIFT min(cpu_vabits, VA_BITS) | |
| 20 | 20 | /* Used for taking out the valid address */ |
| 21 | 21 | #define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0) |
| 22 | 22 | /* One segment whole address space size */ |
| @@ -250,7 +250,7 @@ · 249 unmodified lines | ||
| 250 | 250 | #define CSR_ESTAT_IS_WIDTH 15 |
| 251 | 251 | #define CSR_ESTAT_IS (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT) |
| 252 | 252 | |
| 253 | −#define LOONGARCH_CSR_ERA 0x6 /* ERA */ | |
| 253 | +#define LOONGARCH_CSR_ERA 0x6 /* Exception return address */ | |
| 254 | 254 | |
| 255 | 255 | #define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */ |
| 256 | 256 | |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #define __HAVE_ARCH_PMD_ALLOC_ONE |
| 12 | 12 | #define __HAVE_ARCH_PUD_ALLOC_ONE |
| 13 | +#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL | |
| 13 | 14 | #include <asm-generic/pgalloc.h> |
| 14 | 15 | |
| 15 | 16 | static inline void pmd_populate_kernel(struct mm_struct *mm, |
| @@ -44,6 +45,16 @@ extern void pagetable_init(void); · 28 unmodified lines | ||
| 44 | 45 | |
| 45 | 46 | extern pgd_t *pgd_alloc(struct mm_struct *mm); |
| 46 | 47 | |
| 48 | +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) | |
| 49 | +{ | |
| 50 | + pte_t *pte = __pte_alloc_one_kernel(mm); | |
| 51 | + | |
| 52 | + if (pte) | |
| 53 | + kernel_pte_init(pte); | |
| 54 | + | |
| 55 | + return pte; | |
| 56 | +} | |
| 57 | + | |
| 47 | 58 | #define __pte_free_tlb(tlb, pte, address) \ |
| 48 | 59 | do { \ |
| 49 | 60 | pagetable_pte_dtor(page_ptdesc(pte)); \ |
| @@ -269,6 +269,7 @@ extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pm · 268 unmodified lines | ||
| 269 | 269 | extern void pgd_init(void *addr); |
| 270 | 270 | extern void pud_init(void *addr); |
| 271 | 271 | extern void pmd_init(void *addr); |
| 272 | +extern void kernel_pte_init(void *addr); | |
| 272 | 273 | |
| 273 | 274 | /* |
| 274 | 275 | * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that |
| @@ -325,39 +326,17 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) · 50 unmodified lines | ||
| 325 | 326 | { |
| 326 | 327 | WRITE_ONCE(*ptep, pteval); |
| 327 | 328 | |
| 328 | − if (pte_val(pteval) & _PAGE_GLOBAL) { | |
| 329 | − pte_t *buddy = ptep_buddy(ptep); | |
| 330 | − /* | |
| 331 | − * Make sure the buddy is global too (if it's !none, | |
| 332 | − * it better already be global) | |
| 333 | − */ | |
| 334 | − if (pte_none(ptep_get(buddy))) { | |
| 335 | 329 | #ifdef CONFIG_SMP |
| 336 | − /* | |
| 337 | − * For SMP, multiple CPUs can race, so we need | |
| 338 | − * to do this atomically. | |
| 339 | − */ | |
| 340 | − __asm__ __volatile__( | |
| 341 | − __AMOR "$zero, %[global], %[buddy] \n" | |
| 342 | − : [buddy] "+ZB" (buddy->pte) | |
| 343 | − : [global] "r" (_PAGE_GLOBAL) | |
| 344 | − : "memory"); | |
| 345 | − | |
| 346 | − DBAR(0b11000); /* o_wrw = 0b11000 */ | |
| 347 | −#else /* !CONFIG_SMP */ | |
| 348 | − WRITE_ONCE(*buddy, __pte(pte_val(ptep_get(buddy)) | _PAGE_GLOBAL)); | |
| 349 | −#endif /* CONFIG_SMP */ | |
| 350 | − } | |
| 351 | − } | |
| 330 | + if (pte_val(pteval) & _PAGE_GLOBAL) | |
| 331 | + DBAR(0b11000); /* o_wrw = 0b11000 */ | |
| 332 | +#endif | |
| 352 | 333 | } |
| 353 | 334 | |
| 354 | 335 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
| 355 | 336 | { |
| 356 | − /* Preserve global status for the pair */ | |
| 357 | − if (pte_val(ptep_get(ptep_buddy(ptep))) & _PAGE_GLOBAL) | |
| 358 | − set_pte(ptep, __pte(_PAGE_GLOBAL)); | |
| 359 | − else | |
| 360 | − set_pte(ptep, __pte(0)); | |
| 337 | + pte_t pte = ptep_get(ptep); | |
| 338 | + pte_val(pte) &= _PAGE_GLOBAL; | |
| 339 | + set_pte(ptep, pte); | |
| 361 | 340 | } |
| 362 | 341 | |
| 363 | 342 | #define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) |
| @@ -293,13 +293,15 @@ unsigned long stack_top(void) · 292 unmodified lines | ||
| 293 | 293 | { |
| 294 | 294 | unsigned long top = TASK_SIZE & PAGE_MASK; |
| 295 | 295 | |
| 296 | − /* Space for the VDSO & data page */ | |
| 297 | − top -= PAGE_ALIGN(current->thread.vdso->size); | |
| 298 | − top -= VVAR_SIZE; | |
| 299 | − | |
| 300 | − /* Space to randomize the VDSO base */ | |
| 301 | − if (current->flags & PF_RANDOMIZE) | |
| 302 | − top -= VDSO_RANDOMIZE_SIZE; | |
| 296 | + if (current->thread.vdso) { | |
| 297 | + /* Space for the VDSO & data page */ | |
| 298 | + top -= PAGE_ALIGN(current->thread.vdso->size); | |
| 299 | + top -= VVAR_SIZE; | |
| 300 | + | |
| 301 | + /* Space to randomize the VDSO base */ | |
| 302 | + if (current->flags & PF_RANDOMIZE) | |
| 303 | + top -= VDSO_RANDOMIZE_SIZE; | |
| 304 | + } | |
| 303 | 305 | |
| 304 | 306 | return top; |
| 305 | 307 | } |
| @@ -55,6 +55,7 @@ · 54 unmodified lines | ||
| 55 | 55 | #define SMBIOS_FREQHIGH_OFFSET 0x17 |
| 56 | 56 | #define SMBIOS_FREQLOW_MASK 0xFF |
| 57 | 57 | #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 |
| 58 | +#define SMBIOS_THREAD_PACKAGE_OFFSET 0x25 | |
| 58 | 59 | #define LOONGSON_EFI_ENABLE (1 << 3) |
| 59 | 60 | |
| 60 | 61 | unsigned long fw_arg0, fw_arg1, fw_arg2; |
| @@ -125,7 +126,7 @@ static void __init parse_cpu_table(const struct dmi_header *dm) · 64 unmodified lines | ||
| 125 | 126 | cpu_clock_freq = freq_temp * 1000000; |
| 126 | 127 | |
| 127 | 128 | loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]); |
| 128 | − loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_CORE_PACKAGE_OFFSET); | |
| 129 | + loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET); | |
| 129 | 130 | |
| 130 | 131 | pr_info("CpuClock = %llu\n", cpu_clock_freq); |
| 131 | 132 | } |
| @@ -555,6 +555,9 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs) · 554 unmodified lines | ||
| 555 | 555 | #else |
| 556 | 556 | unsigned int *pc; |
| 557 | 557 | |
| 558 | + if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 559 | + local_irq_enable(); | |
| 560 | + | |
| 558 | 561 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); |
| 559 | 562 | |
| 560 | 563 | /* |
| @@ -579,6 +582,8 @@ sigbus: · 18 unmodified lines | ||
| 579 | 582 | die_if_kernel("Kernel ale access", regs); |
| 580 | 583 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); |
| 581 | 584 | out: |
| 585 | + if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 586 | + local_irq_disable(); | |
| 582 | 587 | #endif |
| 583 | 588 | irqentry_exit(regs, state); |
| 584 | 589 | } |
| @@ -34,7 +34,6 @@ static union { · 33 unmodified lines | ||
| 34 | 34 | struct loongarch_vdso_data vdata; |
| 35 | 35 | } loongarch_vdso_data __page_aligned_data; |
| 36 | 36 | |
| 37 | −static struct page *vdso_pages[] = { NULL }; | |
| 38 | 37 | struct vdso_data *vdso_data = generic_vdso_data.data; |
| 39 | 38 | struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata; |
| 40 | 39 | struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data; |
| @@ -85,10 +84,8 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, · 44 unmodified lines | ||
| 85 | 84 | |
| 86 | 85 | struct loongarch_vdso_info vdso_info = { |
| 87 | 86 | .vdso = vdso_start, |
| 88 | − .size = PAGE_SIZE, | |
| 89 | 87 | .code_mapping = { |
| 90 | 88 | .name = "[vdso]", |
| 91 | − .pages = vdso_pages, | |
| 92 | 89 | .mremap = vdso_mremap, |
| 93 | 90 | }, |
| 94 | 91 | .data_mapping = { |
| @@ -103,11 +100,14 @@ static int __init init_vdso(void) · 8 unmodified lines | ||
| 103 | 100 | unsigned long i, cpu, pfn; |
| 104 | 101 | |
| 105 | 102 | BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); |
| 106 | − BUG_ON(!PAGE_ALIGNED(vdso_info.size)); | |
| 107 | 103 | |
| 108 | 104 | for_each_possible_cpu(cpu) |
| 109 | 105 | vdso_pdata[cpu].node = cpu_to_node(cpu); |
| 110 | 106 | |
| 107 | + vdso_info.size = PAGE_ALIGN(vdso_end - vdso_start); | |
| 108 | + vdso_info.code_mapping.pages = | |
| 109 | + kcalloc(vdso_info.size / PAGE_SIZE, sizeof(struct page *), GFP_KERNEL); | |
| 110 | + | |
| 111 | 111 | pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso)); |
| 112 | 112 | for (i = 0; i < vdso_info.size / PAGE_SIZE; i++) |
| 113 | 113 | vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i); |
| @@ -161,10 +161,11 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu) · 160 unmodified lines | ||
| 161 | 161 | if (kvm_vcpu_is_blocking(vcpu)) { |
| 162 | 162 | |
| 163 | 163 | /* |
| 164 | − * HRTIMER_MODE_PINNED is suggested since vcpu may run in | |
| 165 | − * the same physical cpu in next time | |
| 164 | + * HRTIMER_MODE_PINNED_HARD is suggested since vcpu may run in | |
| 165 | + * the same physical cpu in next time, and the timer should run | |
| 166 | + * in hardirq context even in the PREEMPT_RT case. | |
| 166 | 167 | */ |
| 167 | − hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED); | |
| 168 | + hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED_HARD); | |
| 168 | 169 | } |
| 169 | 170 | } |
| 170 | 171 | |
| @@ -1457,7 +1457,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 1456 unmodified lines | ||
| 1457 | 1457 | vcpu->arch.vpid = 0; |
| 1458 | 1458 | vcpu->arch.flush_gpa = INVALID_GPA; |
| 1459 | 1459 | |
| 1460 | − hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); | |
| 1460 | + hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD); | |
| 1461 | 1461 | vcpu->arch.swtimer.function = kvm_swtimer_wakeup; |
| 1462 | 1462 | |
| 1463 | 1463 | vcpu->arch.handle_exit = kvm_handle_exit; |
| @@ -201,7 +201,9 @@ pte_t * __init populate_kernel_pte(unsigned long addr) · 200 unmodified lines | ||
| 201 | 201 | pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); |
| 202 | 202 | if (!pte) |
| 203 | 203 | panic("%s: Failed to allocate memory\n", __func__); |
| 204 | + | |
| 204 | 205 | pmd_populate_kernel(&init_mm, pmd, pte); |
| 206 | + kernel_pte_init(pte); | |
| 205 | 207 | } |
| 206 | 208 | |
| 207 | 209 | return pte_offset_kernel(pmd, addr); |
| @@ -116,6 +116,26 @@ void pud_init(void *addr) · 115 unmodified lines | ||
| 116 | 116 | EXPORT_SYMBOL_GPL(pud_init); |
| 117 | 117 | #endif |
| 118 | 118 | |
| 119 | +void kernel_pte_init(void *addr) | |
| 120 | +{ | |
| 121 | + unsigned long *p, *end; | |
| 122 | + | |
| 123 | + p = (unsigned long *)addr; | |
| 124 | + end = p + PTRS_PER_PTE; | |
| 125 | + | |
| 126 | + do { | |
| 127 | + p[0] = _PAGE_GLOBAL; | |
| 128 | + p[1] = _PAGE_GLOBAL; | |
| 129 | + p[2] = _PAGE_GLOBAL; | |
| 130 | + p[3] = _PAGE_GLOBAL; | |
| 131 | + p[4] = _PAGE_GLOBAL; | |
| 132 | + p += 8; | |
| 133 | + p[-3] = _PAGE_GLOBAL; | |
| 134 | + p[-2] = _PAGE_GLOBAL; | |
| 135 | + p[-1] = _PAGE_GLOBAL; | |
| 136 | + } while (p != end); | |
| 137 | +} | |
| 138 | + | |
| 119 | 139 | pmd_t mk_pmd(struct page *page, pgprot_t prot) |
| 120 | 140 | { |
| 121 | 141 | pmd_t pmd; |
| @@ -494,6 +494,7 @@ FixupDAR:/* Entry point for dcbx workaround. */ · 493 unmodified lines | ||
| 494 | 494 | bctr /* jump into table */ |
| 495 | 495 | 152: |
| 496 | 496 | mfdar r11 |
| 497 | + mtdar r10 | |
| 497 | 498 | mtctr r11 /* restore ctr reg from DAR */ |
| 498 | 499 | mfspr r11, SPRN_SPRG_THREAD |
| 499 | 500 | stw r10, DAR(r11) |
| @@ -22,7 +22,7 @@ endif · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | ifneq ($(c-getrandom-y),) |
| 24 | 24 | CFLAGS_vgetrandom-32.o += -include $(c-getrandom-y) |
| 25 | − CFLAGS_vgetrandom-64.o += -include $(c-getrandom-y) $(call cc-option, -ffixed-r30) | |
| 25 | + CFLAGS_vgetrandom-64.o += -include $(c-getrandom-y) | |
| 26 | 26 | endif |
| 27 | 27 | |
| 28 | 28 | # Build rules |
| @@ -282,6 +282,7 @@ int __init opal_event_init(void) · 281 unmodified lines | ||
| 282 | 282 | name, NULL); |
| 283 | 283 | if (rc) { |
| 284 | 284 | pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start); |
| 285 | + kfree(name); | |
| 285 | 286 | continue; |
| 286 | 287 | } |
| 287 | 288 | } |
| @@ -777,8 +777,7 @@ config IRQ_STACKS · 776 unmodified lines | ||
| 777 | 777 | config THREAD_SIZE_ORDER |
| 778 | 778 | int "Kernel stack size (in power-of-two numbers of page size)" if VMAP_STACK && EXPERT |
| 779 | 779 | range 0 4 |
| 780 | − default 1 if 32BIT && !KASAN | |
| 781 | − default 3 if 64BIT && KASAN | |
| 780 | + default 1 if 32BIT | |
| 782 | 781 | default 2 |
| 783 | 782 | help |
| 784 | 783 | Specify the Pages of thread stack size (from 4KB to 64KB), which also |
| @@ -13,7 +13,12 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/sizes.h> |
| 14 | 14 | |
| 15 | 15 | /* thread information allocation */ |
| 16 | −#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER | |
| 16 | +#ifdef CONFIG_KASAN | |
| 17 | +#define KASAN_STACK_ORDER 1 | |
| 18 | +#else | |
| 19 | +#define KASAN_STACK_ORDER 0 | |
| 20 | +#endif | |
| 21 | +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER) | |
| 17 | 22 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
| 18 | 23 | |
| 19 | 24 | /* |
| @@ -55,7 +55,7 @@ struct imsic { · 54 unmodified lines | ||
| 55 | 55 | /* IMSIC SW-file */ |
| 56 | 56 | struct imsic_mrif *swfile; |
| 57 | 57 | phys_addr_t swfile_pa; |
| 58 | − spinlock_t swfile_extirq_lock; | |
| 58 | + raw_spinlock_t swfile_extirq_lock; | |
| 59 | 59 | }; |
| 60 | 60 | |
| 61 | 61 | #define imsic_vs_csr_read(__c) \ |
| @@ -622,7 +622,7 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu) · 560 unmodified lines | ||
| 622 | 622 | * interruptions between reading topei and updating pending status. |
| 623 | 623 | */ |
| 624 | 624 | |
| 625 | − spin_lock_irqsave(&imsic->swfile_extirq_lock, flags); | |
| 625 | + raw_spin_lock_irqsave(&imsic->swfile_extirq_lock, flags); | |
| 626 | 626 | |
| 627 | 627 | if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) && |
| 628 | 628 | imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis)) |
| @@ -630,7 +630,7 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 630 | 630 | else |
| 631 | 631 | kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT); |
| 632 | 632 | |
| 633 | − spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags); | |
| 633 | + raw_spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags); | |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | 636 | static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear, |
| @@ -1051,7 +1051,7 @@ int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu) · 414 unmodified lines | ||
| 1051 | 1051 | } |
| 1052 | 1052 | imsic->swfile = page_to_virt(swfile_page); |
| 1053 | 1053 | imsic->swfile_pa = page_to_phys(swfile_page); |
| 1054 | − spin_lock_init(&imsic->swfile_extirq_lock); | |
| 1054 | + raw_spin_lock_init(&imsic->swfile_extirq_lock); | |
| 1055 | 1055 | |
| 1056 | 1056 | /* Setup IO device */ |
| 1057 | 1057 | kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #define RV_MAX_REG_ARGS 8 |
| 19 | 19 | #define RV_FENTRY_NINSNS 2 |
| 20 | 20 | #define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4) |
| 21 | +#define RV_KCFI_NINSNS (IS_ENABLED(CONFIG_CFI_CLANG) ? 1 : 0) | |
| 21 | 22 | /* imm that allows emit_imm to emit max count insns */ |
| 22 | 23 | #define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF |
| 23 | 24 | |
| @@ -271,7 +272,8 @@ static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx) · 247 unmodified lines | ||
| 271 | 272 | if (!is_tail_call) |
| 272 | 273 | emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx); |
| 273 | 274 | emit_jalr(RV_REG_ZERO, is_tail_call ? RV_REG_T3 : RV_REG_RA, |
| 274 | − is_tail_call ? (RV_FENTRY_NINSNS + 1) * 4 : 0, /* skip reserved nops and TCC init */ | |
| 275 | + /* kcfi, fentry and TCC init insns will be skipped on tailcall */ | |
| 276 | + is_tail_call ? (RV_KCFI_NINSNS + RV_FENTRY_NINSNS + 1) * 4 : 0, | |
| 275 | 277 | ctx); |
| 276 | 278 | } |
| 277 | 279 | |
| @@ -548,8 +550,8 @@ static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64, · 270 unmodified lines | ||
| 548 | 550 | rv_lr_w(r0, 0, rd, 0, 0), ctx); |
| 549 | 551 | jmp_offset = ninsns_rvoff(8); |
| 550 | 552 | emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx); |
| 551 | − emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 0) : | |
| 552 | − rv_sc_w(RV_REG_T3, rs, rd, 0, 0), ctx); | |
| 553 | + emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 1) : | |
| 554 | + rv_sc_w(RV_REG_T3, rs, rd, 0, 1), ctx); | |
| 553 | 555 | jmp_offset = ninsns_rvoff(-6); |
| 554 | 556 | emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx); |
| 555 | 557 | emit(rv_fence(0x3, 0x3), ctx); |
| @@ -50,7 +50,6 @@ CONFIG_NUMA=y · 49 unmodified lines | ||
| 50 | 50 | CONFIG_HZ_100=y |
| 51 | 51 | CONFIG_CERT_STORE=y |
| 52 | 52 | CONFIG_EXPOLINE=y |
| 53 | −# CONFIG_EXPOLINE_EXTERN is not set | |
| 54 | 53 | CONFIG_EXPOLINE_AUTO=y |
| 55 | 54 | CONFIG_CHSC_SCH=y |
| 56 | 55 | CONFIG_VFIO_CCW=m |
| @@ -95,6 +94,7 @@ CONFIG_BINFMT_MISC=m · 38 unmodified lines | ||
| 95 | 94 | CONFIG_ZSWAP=y |
| 96 | 95 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y |
| 97 | 96 | CONFIG_ZSMALLOC_STAT=y |
| 97 | +CONFIG_SLAB_BUCKETS=y | |
| 98 | 98 | CONFIG_SLUB_STATS=y |
| 99 | 99 | # CONFIG_COMPAT_BRK is not set |
| 100 | 100 | CONFIG_MEMORY_HOTPLUG=y |
| @@ -426,6 +426,13 @@ CONFIG_DEVTMPFS_SAFE=y · 325 unmodified lines | ||
| 426 | 426 | # CONFIG_FW_LOADER is not set |
| 427 | 427 | CONFIG_CONNECTOR=y |
| 428 | 428 | CONFIG_ZRAM=y |
| 429 | +CONFIG_ZRAM_BACKEND_LZ4=y | |
| 430 | +CONFIG_ZRAM_BACKEND_LZ4HC=y | |
| 431 | +CONFIG_ZRAM_BACKEND_ZSTD=y | |
| 432 | +CONFIG_ZRAM_BACKEND_DEFLATE=y | |
| 433 | +CONFIG_ZRAM_BACKEND_842=y | |
| 434 | +CONFIG_ZRAM_BACKEND_LZO=y | |
| 435 | +CONFIG_ZRAM_DEF_COMP_DEFLATE=y | |
| 429 | 436 | CONFIG_BLK_DEV_LOOP=m |
| 430 | 437 | CONFIG_BLK_DEV_DRBD=m |
| 431 | 438 | CONFIG_BLK_DEV_NBD=m |
| @@ -486,6 +493,7 @@ CONFIG_DM_UEVENT=y · 54 unmodified lines | ||
| 486 | 493 | CONFIG_DM_FLAKEY=m |
| 487 | 494 | CONFIG_DM_VERITY=m |
| 488 | 495 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y |
| 496 | +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | |
| 489 | 497 | CONFIG_DM_SWITCH=m |
| 490 | 498 | CONFIG_DM_INTEGRITY=m |
| 491 | 499 | CONFIG_DM_VDO=m |
| @@ -535,6 +543,7 @@ CONFIG_NLMON=m · 43 unmodified lines | ||
| 535 | 543 | CONFIG_MLX4_EN=m |
| 536 | 544 | CONFIG_MLX5_CORE=m |
| 537 | 545 | CONFIG_MLX5_CORE_EN=y |
| 546 | +# CONFIG_NET_VENDOR_META is not set | |
| 538 | 547 | # CONFIG_NET_VENDOR_MICREL is not set |
| 539 | 548 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 540 | 549 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -695,6 +704,7 @@ CONFIG_NFSD=m · 154 unmodified lines | ||
| 695 | 704 | CONFIG_NFSD_V3_ACL=y |
| 696 | 705 | CONFIG_NFSD_V4=y |
| 697 | 706 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 707 | +# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set | |
| 698 | 708 | CONFIG_CIFS=m |
| 699 | 709 | CONFIG_CIFS_UPCALL=y |
| 700 | 710 | CONFIG_CIFS_XATTR=y |
| @@ -740,7 +750,6 @@ CONFIG_CRYPTO_DH=m · 39 unmodified lines | ||
| 740 | 750 | CONFIG_CRYPTO_ECDH=m |
| 741 | 751 | CONFIG_CRYPTO_ECDSA=m |
| 742 | 752 | CONFIG_CRYPTO_ECRDSA=m |
| 743 | −CONFIG_CRYPTO_SM2=m | |
| 744 | 753 | CONFIG_CRYPTO_CURVE25519=m |
| 745 | 754 | CONFIG_CRYPTO_AES_TI=m |
| 746 | 755 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -48,7 +48,6 @@ CONFIG_NUMA=y · 47 unmodified lines | ||
| 48 | 48 | CONFIG_HZ_100=y |
| 49 | 49 | CONFIG_CERT_STORE=y |
| 50 | 50 | CONFIG_EXPOLINE=y |
| 51 | −# CONFIG_EXPOLINE_EXTERN is not set | |
| 52 | 51 | CONFIG_EXPOLINE_AUTO=y |
| 53 | 52 | CONFIG_CHSC_SCH=y |
| 54 | 53 | CONFIG_VFIO_CCW=m |
| @@ -89,6 +88,7 @@ CONFIG_BINFMT_MISC=m · 34 unmodified lines | ||
| 89 | 88 | CONFIG_ZSWAP=y |
| 90 | 89 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y |
| 91 | 90 | CONFIG_ZSMALLOC_STAT=y |
| 91 | +CONFIG_SLAB_BUCKETS=y | |
| 92 | 92 | # CONFIG_COMPAT_BRK is not set |
| 93 | 93 | CONFIG_MEMORY_HOTPLUG=y |
| 94 | 94 | CONFIG_MEMORY_HOTREMOVE=y |
| @@ -416,6 +416,13 @@ CONFIG_DEVTMPFS_SAFE=y · 321 unmodified lines | ||
| 416 | 416 | # CONFIG_FW_LOADER is not set |
| 417 | 417 | CONFIG_CONNECTOR=y |
| 418 | 418 | CONFIG_ZRAM=y |
| 419 | +CONFIG_ZRAM_BACKEND_LZ4=y | |
| 420 | +CONFIG_ZRAM_BACKEND_LZ4HC=y | |
| 421 | +CONFIG_ZRAM_BACKEND_ZSTD=y | |
| 422 | +CONFIG_ZRAM_BACKEND_DEFLATE=y | |
| 423 | +CONFIG_ZRAM_BACKEND_842=y | |
| 424 | +CONFIG_ZRAM_BACKEND_LZO=y | |
| 425 | +CONFIG_ZRAM_DEF_COMP_DEFLATE=y | |
| 419 | 426 | CONFIG_BLK_DEV_LOOP=m |
| 420 | 427 | CONFIG_BLK_DEV_DRBD=m |
| 421 | 428 | CONFIG_BLK_DEV_NBD=m |
| @@ -476,6 +483,7 @@ CONFIG_DM_UEVENT=y · 54 unmodified lines | ||
| 476 | 483 | CONFIG_DM_FLAKEY=m |
| 477 | 484 | CONFIG_DM_VERITY=m |
| 478 | 485 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y |
| 486 | +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | |
| 479 | 487 | CONFIG_DM_SWITCH=m |
| 480 | 488 | CONFIG_DM_INTEGRITY=m |
| 481 | 489 | CONFIG_DM_VDO=m |
| @@ -525,6 +533,7 @@ CONFIG_NLMON=m · 43 unmodified lines | ||
| 525 | 533 | CONFIG_MLX4_EN=m |
| 526 | 534 | CONFIG_MLX5_CORE=m |
| 527 | 535 | CONFIG_MLX5_CORE_EN=y |
| 536 | +# CONFIG_NET_VENDOR_META is not set | |
| 528 | 537 | # CONFIG_NET_VENDOR_MICREL is not set |
| 529 | 538 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 530 | 539 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -682,6 +691,7 @@ CONFIG_NFSD=m · 151 unmodified lines | ||
| 682 | 691 | CONFIG_NFSD_V3_ACL=y |
| 683 | 692 | CONFIG_NFSD_V4=y |
| 684 | 693 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 694 | +# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set | |
| 685 | 695 | CONFIG_CIFS=m |
| 686 | 696 | CONFIG_CIFS_UPCALL=y |
| 687 | 697 | CONFIG_CIFS_XATTR=y |
| @@ -726,7 +736,6 @@ CONFIG_CRYPTO_DH=m · 38 unmodified lines | ||
| 726 | 736 | CONFIG_CRYPTO_ECDH=m |
| 727 | 737 | CONFIG_CRYPTO_ECDSA=m |
| 728 | 738 | CONFIG_CRYPTO_ECRDSA=m |
| 729 | −CONFIG_CRYPTO_SM2=m | |
| 730 | 739 | CONFIG_CRYPTO_CURVE25519=m |
| 731 | 740 | CONFIG_CRYPTO_AES_TI=m |
| 732 | 741 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -767,6 +776,7 @@ CONFIG_CRYPTO_LZ4=m · 34 unmodified lines | ||
| 767 | 776 | CONFIG_CRYPTO_LZ4HC=m |
| 768 | 777 | CONFIG_CRYPTO_ZSTD=m |
| 769 | 778 | CONFIG_CRYPTO_ANSI_CPRNG=m |
| 779 | +CONFIG_CRYPTO_JITTERENTROPY_OSR=1 | |
| 770 | 780 | CONFIG_CRYPTO_USER_API_HASH=m |
| 771 | 781 | CONFIG_CRYPTO_USER_API_SKCIPHER=m |
| 772 | 782 | CONFIG_CRYPTO_USER_API_RNG=m |
| @@ -49,6 +49,7 @@ CONFIG_ZFCP=y · 48 unmodified lines | ||
| 49 | 49 | # CONFIG_HVC_IUCV is not set |
| 50 | 50 | # CONFIG_HW_RANDOM_S390 is not set |
| 51 | 51 | # CONFIG_HMC_DRV is not set |
| 52 | +# CONFIG_S390_UV_UAPI is not set | |
| 52 | 53 | # CONFIG_S390_TAPE is not set |
| 53 | 54 | # CONFIG_VMCP is not set |
| 54 | 55 | # CONFIG_MONWRITER is not set |
| @@ -16,8 +16,10 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <asm/pci_io.h> |
| 17 | 17 | |
| 18 | 18 | #define xlate_dev_mem_ptr xlate_dev_mem_ptr |
| 19 | +#define kc_xlate_dev_mem_ptr xlate_dev_mem_ptr | |
| 19 | 20 | void *xlate_dev_mem_ptr(phys_addr_t phys); |
| 20 | 21 | #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr |
| 22 | +#define kc_unxlate_dev_mem_ptr unxlate_dev_mem_ptr | |
| 21 | 23 | void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); |
| 22 | 24 | |
| 23 | 25 | #define IO_SPACE_LIMIT 0 |
| @@ -49,6 +49,7 @@ struct perf_sf_sde_regs { · 48 unmodified lines | ||
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | 51 | #define perf_arch_fetch_caller_regs(regs, __ip) do { \ |
| 52 | + (regs)->psw.mask = 0; \ | |
| 52 | 53 | (regs)->psw.addr = (__ip); \ |
| 53 | 54 | (regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) - \ |
| 54 | 55 | offsetof(struct stack_frame, back_chain); \ |
| @@ -77,7 +77,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu) · 76 unmodified lines | ||
| 77 | 77 | vcpu->stat.instruction_diagnose_258++; |
| 78 | 78 | if (vcpu->run->s.regs.gprs[rx] & 7) |
| 79 | 79 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
| 80 | − rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm)); | |
| 80 | + rc = read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm)); | |
| 81 | 81 | if (rc) |
| 82 | 82 | return kvm_s390_inject_prog_cond(vcpu, rc); |
| 83 | 83 | if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) |
| @@ -828,6 +828,8 @@ static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa, · 827 unmodified lines | ||
| 828 | 828 | const gfn_t gfn = gpa_to_gfn(gpa); |
| 829 | 829 | int rc; |
| 830 | 830 | |
| 831 | + if (!gfn_to_memslot(kvm, gfn)) | |
| 832 | + return PGM_ADDRESSING; | |
| 831 | 833 | if (mode == GACC_STORE) |
| 832 | 834 | rc = kvm_write_guest_page(kvm, gfn, data, offset, len); |
| 833 | 835 | else |
| @@ -985,6 +987,8 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, · 151 unmodified lines | ||
| 985 | 987 | gra += fragment_len; |
| 986 | 988 | data += fragment_len; |
| 987 | 989 | } |
| 990 | + if (rc > 0) | |
| 991 | + vcpu->arch.pgm.code = rc; | |
| 988 | 992 | return rc; |
| 989 | 993 | } |
| 990 | 994 | |
| @@ -405,11 +405,12 @@ int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data, · 404 unmodified lines | ||
| 405 | 405 | * @len: number of bytes to copy |
| 406 | 406 | * |
| 407 | 407 | * Copy @len bytes from @data (kernel space) to @gra (guest real address). |
| 408 | − * It is up to the caller to ensure that the entire guest memory range is | |
| 409 | − * valid memory before calling this function. | |
| 410 | 408 | * Guest low address and key protection are not checked. |
| 411 | 409 | * |
| 412 | − * Returns zero on success or -EFAULT on error. | |
| 410 | + * Returns zero on success, -EFAULT when copying from @data failed, or | |
| 411 | + * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info | |
| 412 | + * is also stored to allow injecting into the guest (if applicable) using | |
| 413 | + * kvm_s390_inject_prog_cond(). | |
| 413 | 414 | * |
| 414 | 415 | * If an error occurs data may have been copied partially to guest memory. |
| 415 | 416 | */ |
| @@ -428,11 +429,12 @@ int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data, · 12 unmodified lines | ||
| 428 | 429 | * @len: number of bytes to copy |
| 429 | 430 | * |
| 430 | 431 | * Copy @len bytes from @gra (guest real address) to @data (kernel space). |
| 431 | − * It is up to the caller to ensure that the entire guest memory range is | |
| 432 | − * valid memory before calling this function. | |
| 433 | 432 | * Guest key protection is not checked. |
| 434 | 433 | * |
| 435 | − * Returns zero on success or -EFAULT on error. | |
| 434 | + * Returns zero on success, -EFAULT when copying to @data failed, or | |
| 435 | + * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info | |
| 436 | + * is also stored to allow injecting into the guest (if applicable) using | |
| 437 | + * kvm_s390_inject_prog_cond(). | |
| 436 | 438 | * |
| 437 | 439 | * If an error occurs data may have been copied partially to kernel space. |
| 438 | 440 | */ |
| @@ -280,18 +280,19 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf) · 279 unmodified lines | ||
| 280 | 280 | goto no_pdev; |
| 281 | 281 | |
| 282 | 282 | switch (ccdf->pec) { |
| 283 | − case 0x003a: /* Service Action or Error Recovery Successful */ | |
| 283 | + case 0x002a: /* Error event concerns FMB */ | |
| 284 | + case 0x002b: | |
| 285 | + case 0x002c: | |
| 286 | + break; | |
| 287 | + case 0x0040: /* Service Action or Error Recovery Failed */ | |
| 288 | + case 0x003b: | |
| 289 | + zpci_event_io_failure(pdev, pci_channel_io_perm_failure); | |
| 290 | + break; | |
| 291 | + default: /* PCI function left in the error state attempt to recover */ | |
| 284 | 292 | ers_res = zpci_event_attempt_error_recovery(pdev); |
| 285 | 293 | if (ers_res != PCI_ERS_RESULT_RECOVERED) |
| 286 | 294 | zpci_event_io_failure(pdev, pci_channel_io_perm_failure); |
| 287 | 295 | break; |
| 288 | − default: | |
| 289 | − /* | |
| 290 | − * Mark as frozen not permanently failed because the device | |
| 291 | − * could be subsequently recovered by the platform. | |
| 292 | − */ | |
| 293 | − zpci_event_io_failure(pdev, pci_channel_io_frozen); | |
| 294 | − break; | |
| 295 | 296 | } |
| 296 | 297 | pci_dev_put(pdev); |
| 297 | 298 | no_pdev: |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <asm/unwind_hints.h> |
| 10 | 10 | #include <asm/segment.h> |
| 11 | 11 | #include <asm/cache.h> |
| 12 | +#include <asm/cpufeatures.h> | |
| 13 | +#include <asm/nospec-branch.h> | |
| 12 | 14 | |
| 13 | 15 | #include "calling.h" |
| 14 | 16 | |
| @@ -19,6 +21,9 @@ SYM_FUNC_START(entry_ibpb) · 4 unmodified lines | ||
| 19 | 21 | movl $PRED_CMD_IBPB, %eax |
| 20 | 22 | xorl %edx, %edx |
| 21 | 23 | wrmsr |
| 24 | + | |
| 25 | + /* Make sure IBPB clears return stack preductions too. */ | |
| 26 | + FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_BUG_IBPB_NO_RET | |
| 22 | 27 | RET |
| 23 | 28 | SYM_FUNC_END(entry_ibpb) |
| 24 | 29 | /* For KVM */ |
| @@ -871,6 +871,8 @@ SYM_FUNC_START(entry_SYSENTER_32) · 870 unmodified lines | ||
| 871 | 871 | |
| 872 | 872 | /* Now ready to switch the cr3 */ |
| 873 | 873 | SWITCH_TO_USER_CR3 scratch_reg=%eax |
| 874 | + /* Clobbers ZF */ | |
| 875 | + CLEAR_CPU_BUFFERS | |
| 874 | 876 | |
| 875 | 877 | /* |
| 876 | 878 | * Restore all flags except IF. (We restore IF separately because |
| @@ -881,7 +883,6 @@ SYM_FUNC_START(entry_SYSENTER_32) · 4 unmodified lines | ||
| 881 | 883 | BUG_IF_WRONG_CR3 no_user_check=1 |
| 882 | 884 | popfl |
| 883 | 885 | popl %eax |
| 884 | − CLEAR_CPU_BUFFERS | |
| 885 | 886 | |
| 886 | 887 | /* |
| 887 | 888 | * Return back to the vDSO, which will pop ecx and edx. |
| @@ -1144,7 +1145,6 @@ SYM_CODE_START(asm_exc_nmi) · 256 unmodified lines | ||
| 1144 | 1145 | |
| 1145 | 1146 | /* Not on SYSENTER stack. */ |
| 1146 | 1147 | call exc_nmi |
| 1147 | − CLEAR_CPU_BUFFERS | |
| 1148 | 1148 | jmp .Lnmi_return |
| 1149 | 1149 | |
| 1150 | 1150 | .Lnmi_from_sysenter_stack: |
| @@ -1165,6 +1165,7 @@ SYM_CODE_START(asm_exc_nmi) · 14 unmodified lines | ||
| 1165 | 1165 | |
| 1166 | 1166 | CHECK_AND_APPLY_ESPFIX |
| 1167 | 1167 | RESTORE_ALL_NMI cr3_reg=%edi pop=4 |
| 1168 | + CLEAR_CPU_BUFFERS | |
| 1168 | 1169 | jmp .Lirq_return |
| 1169 | 1170 | |
| 1170 | 1171 | #ifdef CONFIG_X86_ESPFIX32 |
| @@ -1206,6 +1207,7 @@ SYM_CODE_START(asm_exc_nmi) · 35 unmodified lines | ||
| 1206 | 1207 | * 1 - orig_ax |
| 1207 | 1208 | */ |
| 1208 | 1209 | lss (1+5+6)*4(%esp), %esp # back to espfix stack |
| 1210 | + CLEAR_CPU_BUFFERS | |
| 1209 | 1211 | jmp .Lirq_return |
| 1210 | 1212 | #endif |
| 1211 | 1213 | SYM_CODE_END(asm_exc_nmi) |
| @@ -215,7 +215,7 @@ · 214 unmodified lines | ||
| 215 | 215 | #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* Disable Speculative Store Bypass. */ |
| 216 | 216 | #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* AMD SSBD implementation via LS_CFG MSR */ |
| 217 | 217 | #define X86_FEATURE_IBRS ( 7*32+25) /* "ibrs" Indirect Branch Restricted Speculation */ |
| 218 | −#define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier */ | |
| 218 | +#define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier without a guaranteed RSB flush */ | |
| 219 | 219 | #define X86_FEATURE_STIBP ( 7*32+27) /* "stibp" Single Thread Indirect Branch Predictors */ |
| 220 | 220 | #define X86_FEATURE_ZEN ( 7*32+28) /* Generic flag for all Zen and newer */ |
| 221 | 221 | #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* L1TF workaround PTE inversion */ |
| @@ -348,6 +348,7 @@ · 126 unmodified lines | ||
| 348 | 348 | #define X86_FEATURE_CPPC (13*32+27) /* "cppc" Collaborative Processor Performance Control */ |
| 349 | 349 | #define X86_FEATURE_AMD_PSFD (13*32+28) /* Predictive Store Forwarding Disable */ |
| 350 | 350 | #define X86_FEATURE_BTC_NO (13*32+29) /* Not vulnerable to Branch Type Confusion */ |
| 351 | +#define X86_FEATURE_AMD_IBPB_RET (13*32+30) /* IBPB clears return address predictor */ | |
| 351 | 352 | #define X86_FEATURE_BRS (13*32+31) /* "brs" Branch Sampling available */ |
| 352 | 353 | |
| 353 | 354 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ |
| @@ -523,4 +524,5 @@ · 169 unmodified lines | ||
| 523 | 524 | #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */ |
| 524 | 525 | #define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */ |
| 525 | 526 | #define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */ |
| 527 | +#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */ | |
| 526 | 528 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -2,6 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _ASM_X86_FTRACE_H |
| 3 | 3 | #define _ASM_X86_FTRACE_H |
| 4 | 4 | |
| 5 | +#include <asm/ptrace.h> | |
| 6 | + | |
| 5 | 7 | #ifdef CONFIG_FUNCTION_TRACER |
| 6 | 8 | #ifndef CC_USING_FENTRY |
| 7 | 9 | # error Compiler does not support fentry? |
| @@ -323,7 +323,16 @@ · 322 unmodified lines | ||
| 323 | 323 | * Note: Only the memory operand variant of VERW clears the CPU buffers. |
| 324 | 324 | */ |
| 325 | 325 | .macro CLEAR_CPU_BUFFERS |
| 326 | − ALTERNATIVE "", __stringify(verw _ASM_RIP(mds_verw_sel)), X86_FEATURE_CLEAR_CPU_BUF | |
| 326 | +#ifdef CONFIG_X86_64 | |
| 327 | + ALTERNATIVE "", "verw mds_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF | |
| 328 | +#else | |
| 329 | + /* | |
| 330 | + * In 32bit mode, the memory operand must be a %cs reference. The data | |
| 331 | + * segments may not be usable (vm86 mode), and the stack segment may not | |
| 332 | + * be flat (ESPFIX32). | |
| 333 | + */ | |
| 334 | + ALTERNATIVE "", "verw %cs:mds_verw_sel", X86_FEATURE_CLEAR_CPU_BUF | |
| 335 | +#endif | |
| 327 | 336 | .endm |
| 328 | 337 | |
| 329 | 338 | #ifdef CONFIG_X86_64 |
| @@ -26,7 +26,7 @@ void __noreturn machine_real_restart(unsigned int type); · 25 unmodified lines | ||
| 26 | 26 | #define MRR_APM 1 |
| 27 | 27 | |
| 28 | 28 | typedef void (cpu_emergency_virt_cb)(void); |
| 29 | −#if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD) | |
| 29 | +#if IS_ENABLED(CONFIG_KVM_X86) | |
| 30 | 30 | void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); |
| 31 | 31 | void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback); |
| 32 | 32 | void cpu_emergency_disable_virtualization(void); |
| @@ -34,7 +34,7 @@ void cpu_emergency_disable_virtualization(void); · 1 unmodified line | ||
| 34 | 34 | static inline void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) {} |
| 35 | 35 | static inline void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) {} |
| 36 | 36 | static inline void cpu_emergency_disable_virtualization(void) {} |
| 37 | −#endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */ | |
| 37 | +#endif /* CONFIG_KVM_X86 */ | |
| 38 | 38 | |
| 39 | 39 | typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); |
| 40 | 40 | void nmi_shootdown_cpus(nmi_shootdown_cb callback); |
| @@ -44,6 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4 |
| 45 | 45 | #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc |
| 46 | 46 | #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4 |
| 47 | +#define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4 0x16fc | |
| 47 | 48 | #define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4 0x124c |
| 48 | 49 | #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4 0x12bc |
| 49 | 50 | #define PCI_DEVICE_ID_AMD_MI200_DF_F4 0x14d4 |
| @@ -127,6 +128,7 @@ static const struct pci_device_id amd_nb_link_ids[] = { · 77 unmodified lines | ||
| 127 | 128 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, |
| 128 | 129 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, |
| 129 | 130 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) }, |
| 131 | + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4) }, | |
| 130 | 132 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) }, |
| 131 | 133 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) }, |
| 132 | 134 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) }, |
| @@ -440,7 +440,19 @@ static int lapic_timer_shutdown(struct clock_event_device *evt) · 439 unmodified lines | ||
| 440 | 440 | v = apic_read(APIC_LVTT); |
| 441 | 441 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); |
| 442 | 442 | apic_write(APIC_LVTT, v); |
| 443 | − apic_write(APIC_TMICT, 0); | |
| 443 | + | |
| 444 | + /* | |
| 445 | + * Setting APIC_LVT_MASKED (above) should be enough to tell | |
| 446 | + * the hardware that this timer will never fire. But AMD | |
| 447 | + * erratum 411 and some Intel CPU behavior circa 2024 say | |
| 448 | + * otherwise. Time for belt and suspenders programming: mask | |
| 449 | + * the timer _and_ zero the counter registers: | |
| 450 | + */ | |
| 451 | + if (v & APIC_LVT_TIMER_TSCDEADLINE) | |
| 452 | + wrmsrl(MSR_IA32_TSC_DEADLINE, 0); | |
| 453 | + else | |
| 454 | + apic_write(APIC_TMICT, 0); | |
| 455 | + | |
| 444 | 456 | return 0; |
| 445 | 457 | } |
| 446 | 458 | |
| @@ -1202,5 +1202,6 @@ void amd_check_microcode(void) · 1201 unmodified lines | ||
| 1202 | 1202 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
| 1203 | 1203 | return; |
| 1204 | 1204 | |
| 1205 | − on_each_cpu(zenbleed_check_cpu, NULL, 1); | |
| 1205 | + if (cpu_feature_enabled(X86_FEATURE_ZEN2)) | |
| 1206 | + on_each_cpu(zenbleed_check_cpu, NULL, 1); | |
| 1206 | 1207 | } |
| @@ -1115,8 +1115,25 @@ do_cmd_auto: · 1114 unmodified lines | ||
| 1115 | 1115 | |
| 1116 | 1116 | case RETBLEED_MITIGATION_IBPB: |
| 1117 | 1117 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); |
| 1118 | + | |
| 1119 | + /* | |
| 1120 | + * IBPB on entry already obviates the need for | |
| 1121 | + * software-based untraining so clear those in case some | |
| 1122 | + * other mitigation like SRSO has selected them. | |
| 1123 | + */ | |
| 1124 | + setup_clear_cpu_cap(X86_FEATURE_UNRET); | |
| 1125 | + setup_clear_cpu_cap(X86_FEATURE_RETHUNK); | |
| 1126 | + | |
| 1118 | 1127 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); |
| 1119 | 1128 | mitigate_smt = true; |
| 1129 | + | |
| 1130 | + /* | |
| 1131 | + * There is no need for RSB filling: entry_ibpb() ensures | |
| 1132 | + * all predictions, including the RSB, are invalidated, | |
| 1133 | + * regardless of IBPB implementation. | |
| 1134 | + */ | |
| 1135 | + setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT); | |
| 1136 | + | |
| 1120 | 1137 | break; |
| 1121 | 1138 | |
| 1122 | 1139 | case RETBLEED_MITIGATION_STUFF: |
| @@ -2627,6 +2644,14 @@ static void __init srso_select_mitigation(void) · 1504 unmodified lines | ||
| 2627 | 2644 | if (has_microcode) { |
| 2628 | 2645 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); |
| 2629 | 2646 | srso_mitigation = SRSO_MITIGATION_IBPB; |
| 2647 | + | |
| 2648 | + /* | |
| 2649 | + * IBPB on entry already obviates the need for | |
| 2650 | + * software-based untraining so clear those in case some | |
| 2651 | + * other mitigation like Retbleed has selected them. | |
| 2652 | + */ | |
| 2653 | + setup_clear_cpu_cap(X86_FEATURE_UNRET); | |
| 2654 | + setup_clear_cpu_cap(X86_FEATURE_RETHUNK); | |
| 2630 | 2655 | } |
| 2631 | 2656 | } else { |
| 2632 | 2657 | pr_err("WARNING: kernel not compiled with MITIGATION_IBPB_ENTRY.\n"); |
| @@ -2638,6 +2663,13 @@ static void __init srso_select_mitigation(void) · 5 unmodified lines | ||
| 2638 | 2663 | if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { |
| 2639 | 2664 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); |
| 2640 | 2665 | srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; |
| 2666 | + | |
| 2667 | + /* | |
| 2668 | + * There is no need for RSB filling: entry_ibpb() ensures | |
| 2669 | + * all predictions, including the RSB, are invalidated, | |
| 2670 | + * regardless of IBPB implementation. | |
| 2671 | + */ | |
| 2672 | + setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT); | |
| 2641 | 2673 | } |
| 2642 | 2674 | } else { |
| 2643 | 2675 | pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n"); |
| @@ -1443,6 +1443,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) · 1442 unmodified lines | ||
| 1443 | 1443 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) |
| 1444 | 1444 | setup_force_cpu_bug(X86_BUG_BHI); |
| 1445 | 1445 | |
| 1446 | + if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET)) | |
| 1447 | + setup_force_cpu_bug(X86_BUG_IBPB_NO_RET); | |
| 1448 | + | |
| 1446 | 1449 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1447 | 1450 | return; |
| 1448 | 1451 | |
| @@ -207,7 +207,7 @@ static inline bool rdt_get_mb_table(struct rdt_resource *r) · 206 unmodified lines | ||
| 207 | 207 | return false; |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | −static bool __get_mem_config_intel(struct rdt_resource *r) | |
| 210 | +static __init bool __get_mem_config_intel(struct rdt_resource *r) | |
| 211 | 211 | { |
| 212 | 212 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 213 | 213 | union cpuid_0x10_3_eax eax; |
| @@ -241,7 +241,7 @@ static bool __get_mem_config_intel(struct rdt_resource *r) · 27 unmodified lines | ||
| 241 | 241 | return true; |
| 242 | 242 | } |
| 243 | 243 | |
| 244 | −static bool __rdt_get_mem_config_amd(struct rdt_resource *r) | |
| 244 | +static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r) | |
| 245 | 245 | { |
| 246 | 246 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 247 | 247 | u32 eax, ebx, ecx, edx, subleaf; |
| @@ -29,10 +29,10 @@ · 28 unmodified lines | ||
| 29 | 29 | * hardware. The allocated bandwidth percentage is rounded to the next |
| 30 | 30 | * control step available on the hardware. |
| 31 | 31 | */ |
| 32 | −static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) | |
| 32 | +static bool bw_validate(char *buf, u32 *data, struct rdt_resource *r) | |
| 33 | 33 | { |
| 34 | − unsigned long bw; | |
| 35 | 34 | int ret; |
| 35 | + u32 bw; | |
| 36 | 36 | |
| 37 | 37 | /* |
| 38 | 38 | * Only linear delay values is supported for current Intel SKUs. |
| @@ -42,16 +42,21 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) · 3 unmodified lines | ||
| 42 | 42 | return false; |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | − ret = kstrtoul(buf, 10, &bw); | |
| 45 | + ret = kstrtou32(buf, 10, &bw); | |
| 46 | 46 | if (ret) { |
| 47 | − rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf); | |
| 47 | + rdt_last_cmd_printf("Invalid MB value %s\n", buf); | |
| 48 | 48 | return false; |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | − if ((bw < r->membw.min_bw || bw > r->default_ctrl) && | |
| 52 | − !is_mba_sc(r)) { | |
| 53 | − rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw, | |
| 54 | − r->membw.min_bw, r->default_ctrl); | |
| 51 | + /* Nothing else to do if software controller is enabled. */ | |
| 52 | + if (is_mba_sc(r)) { | |
| 53 | + *data = bw; | |
| 54 | + return true; | |
| 55 | + } | |
| 56 | + | |
| 57 | + if (bw < r->membw.min_bw || bw > r->default_ctrl) { | |
| 58 | + rdt_last_cmd_printf("MB value %u out of range [%d,%d]\n", | |
| 59 | + bw, r->membw.min_bw, r->default_ctrl); | |
| 55 | 60 | return false; |
| 56 | 61 | } |
| 57 | 62 | |
| @@ -65,7 +70,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, · 7 unmodified lines | ||
| 65 | 70 | struct resctrl_staged_config *cfg; |
| 66 | 71 | u32 closid = data->rdtgrp->closid; |
| 67 | 72 | struct rdt_resource *r = s->res; |
| 68 | − unsigned long bw_val; | |
| 73 | + u32 bw_val; | |
| 69 | 74 | |
| 70 | 75 | cfg = &d->staged_config[s->conf_type]; |
| 71 | 76 | if (cfg->have_new_ctrl) { |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <asm/apic.h> |
| 38 | 38 | #include <asm/apicdef.h> |
| 39 | 39 | #include <asm/hypervisor.h> |
| 40 | +#include <asm/mtrr.h> | |
| 40 | 41 | #include <asm/tlb.h> |
| 41 | 42 | #include <asm/cpuidle_haltpoll.h> |
| 42 | 43 | #include <asm/ptrace.h> |
| @@ -980,6 +981,9 @@ static void __init kvm_init_platform(void) · 937 unmodified lines | ||
| 980 | 981 | } |
| 981 | 982 | kvmclock_init(); |
| 982 | 983 | x86_platform.apic_post_init = kvm_apic_init; |
| 984 | + | |
| 985 | + /* Set WB as the default cache mode for SEV-SNP and TDX */ | |
| 986 | + mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK); | |
| 983 | 987 | } |
| 984 | 988 | |
| 985 | 989 | #if defined(CONFIG_AMD_MEM_ENCRYPT) |
| @@ -530,7 +530,7 @@ static inline void kb_wait(void) · 529 unmodified lines | ||
| 530 | 530 | |
| 531 | 531 | static inline void nmi_shootdown_cpus_on_restart(void); |
| 532 | 532 | |
| 533 | −#if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD) | |
| 533 | +#if IS_ENABLED(CONFIG_KVM_X86) | |
| 534 | 534 | /* RCU-protected callback to disable virtualization prior to reboot. */ |
| 535 | 535 | static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback; |
| 536 | 536 | |
| @@ -600,7 +600,7 @@ static void emergency_reboot_disable_virtualization(void) · 63 unmodified lines | ||
| 600 | 600 | } |
| 601 | 601 | #else |
| 602 | 602 | static void emergency_reboot_disable_virtualization(void) { } |
| 603 | −#endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */ | |
| 603 | +#endif /* CONFIG_KVM_X86 */ | |
| 604 | 604 | |
| 605 | 605 | void __attribute__((weak)) mach_reboot_fixups(void) |
| 606 | 606 | { |
| @@ -17,8 +17,8 @@ menuconfig VIRTUALIZATION · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | if VIRTUALIZATION |
| 19 | 19 | |
| 20 | −config KVM | |
| 21 | − tristate "Kernel-based Virtual Machine (KVM) support" | |
| 20 | +config KVM_X86 | |
| 21 | + def_tristate KVM if KVM_INTEL || KVM_AMD | |
| 22 | 22 | depends on X86_LOCAL_APIC |
| 23 | 23 | select KVM_COMMON |
| 24 | 24 | select KVM_GENERIC_MMU_NOTIFIER |
| @@ -44,7 +44,11 @@ config KVM · 19 unmodified lines | ||
| 44 | 44 | select HAVE_KVM_PM_NOTIFIER if PM |
| 45 | 45 | select KVM_GENERIC_HARDWARE_ENABLING |
| 46 | 46 | select KVM_GENERIC_PRE_FAULT_MEMORY |
| 47 | + select KVM_GENERIC_PRIVATE_MEM if KVM_SW_PROTECTED_VM | |
| 47 | 48 | select KVM_WERROR if WERROR |
| 49 | + | |
| 50 | +config KVM | |
| 51 | + tristate "Kernel-based Virtual Machine (KVM) support" | |
| 48 | 52 | help |
| 49 | 53 | Support hosting fully virtualized guest machines using hardware |
| 50 | 54 | virtualization extensions. You will need a fairly recent |
| @@ -77,7 +81,6 @@ config KVM_SW_PROTECTED_VM · 26 unmodified lines | ||
| 77 | 81 | bool "Enable support for KVM software-protected VMs" |
| 78 | 82 | depends on EXPERT |
| 79 | 83 | depends on KVM && X86_64 |
| 80 | − select KVM_GENERIC_PRIVATE_MEM | |
| 81 | 84 | help |
| 82 | 85 | Enable support for KVM software-protected VMs. Currently, software- |
| 83 | 86 | protected VMs are purely a development and testing vehicle for |
| @@ -32,7 +32,7 @@ kvm-intel-y += vmx/vmx_onhyperv.o vmx/hyperv_evmcs.o · 31 unmodified lines | ||
| 32 | 32 | kvm-amd-y += svm/svm_onhyperv.o |
| 33 | 33 | endif |
| 34 | 34 | |
| 35 | −obj-$(CONFIG_KVM) += kvm.o | |
| 35 | +obj-$(CONFIG_KVM_X86) += kvm.o | |
| 36 | 36 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o |
| 37 | 37 | obj-$(CONFIG_KVM_AMD) += kvm-amd.o |
| 38 | 38 | |
| @@ -1556,6 +1556,17 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) · 1555 unmodified lines | ||
| 1556 | 1556 | { |
| 1557 | 1557 | bool flush = false; |
| 1558 | 1558 | |
| 1559 | + /* | |
| 1560 | + * To prevent races with vCPUs faulting in a gfn using stale data, | |
| 1561 | + * zapping a gfn range must be protected by mmu_invalidate_in_progress | |
| 1562 | + * (and mmu_invalidate_seq). The only exception is memslot deletion; | |
| 1563 | + * in that case, SRCU synchronization ensures that SPTEs are zapped | |
| 1564 | + * after all vCPUs have unlocked SRCU, guaranteeing that vCPUs see the | |
| 1565 | + * invalid slot. | |
| 1566 | + */ | |
| 1567 | + lockdep_assert_once(kvm->mmu_invalidate_in_progress || | |
| 1568 | + lockdep_is_held(&kvm->slots_lock)); | |
| 1569 | + | |
| 1559 | 1570 | if (kvm_memslots_have_rmaps(kvm)) |
| 1560 | 1571 | flush = __kvm_rmap_zap_gfn_range(kvm, range->slot, |
| 1561 | 1572 | range->start, range->end, |
| @@ -7047,14 +7058,42 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) · 5485 unmodified lines | ||
| 7047 | 7058 | kvm_mmu_zap_all(kvm); |
| 7048 | 7059 | } |
| 7049 | 7060 | |
| 7050 | −/* | |
| 7051 | − * Zapping leaf SPTEs with memslot range when a memslot is moved/deleted. | |
| 7052 | − * | |
| 7053 | − * Zapping non-leaf SPTEs, a.k.a. not-last SPTEs, isn't required, worst | |
| 7054 | − * case scenario we'll have unused shadow pages lying around until they | |
| 7055 | − * are recycled due to age or when the VM is destroyed. | |
| 7056 | − */ | |
| 7057 | −static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *slot) | |
| 7061 | +static void kvm_mmu_zap_memslot_pages_and_flush(struct kvm *kvm, | |
| 7062 | + struct kvm_memory_slot *slot, | |
| 7063 | + bool flush) | |
| 7064 | +{ | |
| 7065 | + LIST_HEAD(invalid_list); | |
| 7066 | + unsigned long i; | |
| 7067 | + | |
| 7068 | + if (list_empty(&kvm->arch.active_mmu_pages)) | |
| 7069 | + goto out_flush; | |
| 7070 | + | |
| 7071 | + /* | |
| 7072 | + * Since accounting information is stored in struct kvm_arch_memory_slot, | |
| 7073 | + * all MMU pages that are shadowing guest PTEs must be zapped before the | |
| 7074 | + * memslot is deleted, as freeing such pages after the memslot is freed | |
| 7075 | + * will result in use-after-free, e.g. in unaccount_shadowed(). | |
| 7076 | + */ | |
| 7077 | + for (i = 0; i < slot->npages; i++) { | |
| 7078 | + struct kvm_mmu_page *sp; | |
| 7079 | + gfn_t gfn = slot->base_gfn + i; | |
| 7080 | + | |
| 7081 | + for_each_gfn_valid_sp_with_gptes(kvm, sp, gfn) | |
| 7082 | + kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); | |
| 7083 | + | |
| 7084 | + if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) { | |
| 7085 | + kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush); | |
| 7086 | + flush = false; | |
| 7087 | + cond_resched_rwlock_write(&kvm->mmu_lock); | |
| 7088 | + } | |
| 7089 | + } | |
| 7090 | + | |
| 7091 | +out_flush: | |
| 7092 | + kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush); | |
| 7093 | +} | |
| 7094 | + | |
| 7095 | +static void kvm_mmu_zap_memslot(struct kvm *kvm, | |
| 7096 | + struct kvm_memory_slot *slot) | |
| 7058 | 7097 | { |
| 7059 | 7098 | struct kvm_gfn_range range = { |
| 7060 | 7099 | .slot = slot, |
| @@ -7062,11 +7101,11 @@ static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *s · 1 unmodified line | ||
| 7062 | 7101 | .end = slot->base_gfn + slot->npages, |
| 7063 | 7102 | .may_block = true, |
| 7064 | 7103 | }; |
| 7104 | + bool flush; | |
| 7065 | 7105 | |
| 7066 | 7106 | write_lock(&kvm->mmu_lock); |
| 7067 | − if (kvm_unmap_gfn_range(kvm, &range)) | |
| 7068 | − kvm_flush_remote_tlbs_memslot(kvm, slot); | |
| 7069 | − | |
| 7107 | + flush = kvm_unmap_gfn_range(kvm, &range); | |
| 7108 | + kvm_mmu_zap_memslot_pages_and_flush(kvm, slot, flush); | |
| 7070 | 7109 | write_unlock(&kvm->mmu_lock); |
| 7071 | 7110 | } |
| 7072 | 7111 | |
| @@ -7082,7 +7121,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, · 9 unmodified lines | ||
| 7082 | 7121 | if (kvm_memslot_flush_zap_all(kvm)) |
| 7083 | 7122 | kvm_mmu_zap_all_fast(kvm); |
| 7084 | 7123 | else |
| 7085 | − kvm_mmu_zap_memslot_leafs(kvm, slot); | |
| 7124 | + kvm_mmu_zap_memslot(kvm, slot); | |
| 7086 | 7125 | } |
| 7087 | 7126 | |
| 7088 | 7127 | void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen) |
| @@ -63,8 +63,12 @@ static u64 nested_svm_get_tdp_pdptr(struct kvm_vcpu *vcpu, int index) · 62 unmodified lines | ||
| 63 | 63 | u64 pdpte; |
| 64 | 64 | int ret; |
| 65 | 65 | |
| 66 | + /* | |
| 67 | + * Note, nCR3 is "assumed" to be 32-byte aligned, i.e. the CPU ignores | |
| 68 | + * nCR3[4:0] when loading PDPTEs from memory. | |
| 69 | + */ | |
| 66 | 70 | ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(cr3), &pdpte, |
| 67 | − offset_in_page(cr3) + index * 8, 8); | |
| 71 | + (cr3 & GENMASK(11, 5)) + index * 8, 8); | |
| 68 | 72 | if (ret) |
| 69 | 73 | return 0; |
| 70 | 74 | return pdpte; |
| @@ -4888,9 +4888,6 @@ void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 4887 unmodified lines | ||
| 4888 | 4888 | vmx->hv_deadline_tsc = -1; |
| 4889 | 4889 | kvm_set_cr8(vcpu, 0); |
| 4890 | 4890 | |
| 4891 | − vmx_segment_cache_clear(vmx); | |
| 4892 | − kvm_register_mark_available(vcpu, VCPU_EXREG_SEGMENTS); | |
| 4893 | − | |
| 4894 | 4891 | seg_setup(VCPU_SREG_CS); |
| 4895 | 4892 | vmcs_write16(GUEST_CS_SELECTOR, 0xf000); |
| 4896 | 4893 | vmcs_writel(GUEST_CS_BASE, 0xffff0000ul); |
| @@ -4917,6 +4914,9 @@ void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 20 unmodified lines | ||
| 4917 | 4914 | vmcs_writel(GUEST_IDTR_BASE, 0); |
| 4918 | 4915 | vmcs_write32(GUEST_IDTR_LIMIT, 0xffff); |
| 4919 | 4916 | |
| 4917 | + vmx_segment_cache_clear(vmx); | |
| 4918 | + kvm_register_mark_available(vcpu, VCPU_EXREG_SEGMENTS); | |
| 4919 | + | |
| 4920 | 4920 | vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); |
| 4921 | 4921 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); |
| 4922 | 4922 | vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, 0); |
| @@ -1032,6 +1032,10 @@ static u64 xen_do_read_msr(unsigned int msr, int *err) · 1031 unmodified lines | ||
| 1032 | 1032 | switch (msr) { |
| 1033 | 1033 | case MSR_IA32_APICBASE: |
| 1034 | 1034 | val &= ~X2APIC_ENABLE; |
| 1035 | + if (smp_processor_id() == 0) | |
| 1036 | + val |= MSR_IA32_APICBASE_BSP; | |
| 1037 | + else | |
| 1038 | + val &= ~MSR_IA32_APICBASE_BSP; | |
| 1035 | 1039 | break; |
| 1036 | 1040 | } |
| 1037 | 1041 | return val; |
| @@ -56,8 +56,7 @@ new_segment: · 55 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | /** |
| 58 | 58 | * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist |
| 59 | − * @q: request queue | |
| 60 | − * @bio: bio with integrity metadata attached | |
| 59 | + * @rq: request to map | |
| 61 | 60 | * @sglist: target scatterlist |
| 62 | 61 | * |
| 63 | 62 | * Description: Map the integrity vectors in request into a |
| @@ -3166,7 +3166,7 @@ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd, · 3165 unmodified lines | ||
| 3166 | 3166 | if (!dname) |
| 3167 | 3167 | return 0; |
| 3168 | 3168 | |
| 3169 | − spin_lock_irq(&ioc->lock); | |
| 3169 | + spin_lock(&ioc->lock); | |
| 3170 | 3170 | seq_printf(sf, "%s enable=%d ctrl=%s rpct=%u.%02u rlat=%u wpct=%u.%02u wlat=%u min=%u.%02u max=%u.%02u\n", |
| 3171 | 3171 | dname, ioc->enabled, ioc->user_qos_params ? "user" : "auto", |
| 3172 | 3172 | ioc->params.qos[QOS_RPPM] / 10000, |
| @@ -3179,7 +3179,7 @@ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd, · 6 unmodified lines | ||
| 3179 | 3179 | ioc->params.qos[QOS_MIN] % 10000 / 100, |
| 3180 | 3180 | ioc->params.qos[QOS_MAX] / 10000, |
| 3181 | 3181 | ioc->params.qos[QOS_MAX] % 10000 / 100); |
| 3182 | − spin_unlock_irq(&ioc->lock); | |
| 3182 | + spin_unlock(&ioc->lock); | |
| 3183 | 3183 | return 0; |
| 3184 | 3184 | } |
| 3185 | 3185 | |
| @@ -3366,14 +3366,14 @@ static u64 ioc_cost_model_prfill(struct seq_file *sf, · 180 unmodified lines | ||
| 3366 | 3366 | if (!dname) |
| 3367 | 3367 | return 0; |
| 3368 | 3368 | |
| 3369 | − spin_lock_irq(&ioc->lock); | |
| 3369 | + spin_lock(&ioc->lock); | |
| 3370 | 3370 | seq_printf(sf, "%s ctrl=%s model=linear " |
| 3371 | 3371 | "rbps=%llu rseqiops=%llu rrandiops=%llu " |
| 3372 | 3372 | "wbps=%llu wseqiops=%llu wrandiops=%llu\n", |
| 3373 | 3373 | dname, ioc->user_cost_model ? "user" : "auto", |
| 3374 | 3374 | u[I_LCOEF_RBPS], u[I_LCOEF_RSEQIOPS], u[I_LCOEF_RRANDIOPS], |
| 3375 | 3375 | u[I_LCOEF_WBPS], u[I_LCOEF_WSEQIOPS], u[I_LCOEF_WRANDIOPS]); |
| 3376 | − spin_unlock_irq(&ioc->lock); | |
| 3376 | + spin_unlock(&ioc->lock); | |
| 3377 | 3377 | return 0; |
| 3378 | 3378 | } |
| 3379 | 3379 | |
| @@ -4310,6 +4310,12 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, · 4309 unmodified lines | ||
| 4310 | 4310 | /* mark the queue as mq asap */ |
| 4311 | 4311 | q->mq_ops = set->ops; |
| 4312 | 4312 | |
| 4313 | + /* | |
| 4314 | + * ->tag_set has to be setup before initialize hctx, which cpuphp | |
| 4315 | + * handler needs it for checking queue mapping | |
| 4316 | + */ | |
| 4317 | + q->tag_set = set; | |
| 4318 | + | |
| 4313 | 4319 | if (blk_mq_alloc_ctxs(q)) |
| 4314 | 4320 | goto err_exit; |
| 4315 | 4321 | |
| @@ -4328,8 +4334,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, · 12 unmodified lines | ||
| 4328 | 4334 | INIT_WORK(&q->timeout_work, blk_mq_timeout_work); |
| 4329 | 4335 | blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); |
| 4330 | 4336 | |
| 4331 | − q->tag_set = set; | |
| 4332 | − | |
| 4333 | 4337 | q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; |
| 4334 | 4338 | |
| 4335 | 4339 | INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work); |
| @@ -219,8 +219,8 @@ static int rq_qos_wake_function(struct wait_queue_entry *curr, · 218 unmodified lines | ||
| 219 | 219 | |
| 220 | 220 | data->got_token = true; |
| 221 | 221 | smp_wmb(); |
| 222 | − list_del_init(&curr->entry); | |
| 223 | 222 | wake_up_process(data->task); |
| 223 | + list_del_init_careful(&curr->entry); | |
| 224 | 224 | return 1; |
| 225 | 225 | } |
| 226 | 226 | |
| @@ -106,8 +106,7 @@ static struct elevator_type *__elevator_find(const char *name) · 105 unmodified lines | ||
| 106 | 106 | return NULL; |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | −static struct elevator_type *elevator_find_get(struct request_queue *q, | |
| 110 | − const char *name) | |
| 109 | +static struct elevator_type *elevator_find_get(const char *name) | |
| 111 | 110 | { |
| 112 | 111 | struct elevator_type *e; |
| 113 | 112 | |
| @@ -551,7 +550,7 @@ EXPORT_SYMBOL_GPL(elv_unregister); · 437 unmodified lines | ||
| 551 | 550 | static inline bool elv_support_iosched(struct request_queue *q) |
| 552 | 551 | { |
| 553 | 552 | if (!queue_is_mq(q) || |
| 554 | − (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED))) | |
| 553 | + (q->tag_set->flags & BLK_MQ_F_NO_SCHED)) | |
| 555 | 554 | return false; |
| 556 | 555 | return true; |
| 557 | 556 | } |
| @@ -562,14 +561,14 @@ static inline bool elv_support_iosched(struct request_queue *q) · 4 unmodified lines | ||
| 562 | 561 | */ |
| 563 | 562 | static struct elevator_type *elevator_get_default(struct request_queue *q) |
| 564 | 563 | { |
| 565 | − if (q->tag_set && q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT) | |
| 564 | + if (q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT) | |
| 566 | 565 | return NULL; |
| 567 | 566 | |
| 568 | 567 | if (q->nr_hw_queues != 1 && |
| 569 | 568 | !blk_mq_is_shared_tags(q->tag_set->flags)) |
| 570 | 569 | return NULL; |
| 571 | 570 | |
| 572 | − return elevator_find_get(q, "mq-deadline"); | |
| 571 | + return elevator_find_get("mq-deadline"); | |
| 573 | 572 | } |
| 574 | 573 | |
| 575 | 574 | /* |
| @@ -697,7 +696,7 @@ static int elevator_change(struct request_queue *q, const char *elevator_name) · 121 unmodified lines | ||
| 697 | 696 | if (q->elevator && elevator_match(q->elevator->type, elevator_name)) |
| 698 | 697 | return 0; |
| 699 | 698 | |
| 700 | − e = elevator_find_get(q, elevator_name); | |
| 699 | + e = elevator_find_get(elevator_name); | |
| 701 | 700 | if (!e) |
| 702 | 701 | return -EINVAL; |
| 703 | 702 | ret = elevator_switch(q, e); |
| @@ -709,13 +708,21 @@ int elv_iosched_load_module(struct gendisk *disk, const char *buf, · 5 unmodified lines | ||
| 709 | 708 | size_t count) |
| 710 | 709 | { |
| 711 | 710 | char elevator_name[ELV_NAME_MAX]; |
| 711 | + struct elevator_type *found; | |
| 712 | + const char *name; | |
| 712 | 713 | |
| 713 | 714 | if (!elv_support_iosched(disk->queue)) |
| 714 | 715 | return -EOPNOTSUPP; |
| 715 | 716 | |
| 716 | 717 | strscpy(elevator_name, buf, sizeof(elevator_name)); |
| 718 | + name = strstrip(elevator_name); | |
| 717 | 719 | |
| 718 | − request_module("%s-iosched", strstrip(elevator_name)); | |
| 720 | + spin_lock(&elv_list_lock); | |
| 721 | + found = __elevator_find(name); | |
| 722 | + spin_unlock(&elv_list_lock); | |
| 723 | + | |
| 724 | + if (!found) | |
| 725 | + request_module("%s-iosched", name); | |
| 719 | 726 | |
| 720 | 727 | return 0; |
| 721 | 728 | } |
| @@ -373,7 +373,7 @@ found: · 372 unmodified lines | ||
| 373 | 373 | q->cra_flags |= CRYPTO_ALG_DEAD; |
| 374 | 374 | alg = test->adult; |
| 375 | 375 | |
| 376 | − if (list_empty(&alg->cra_list)) | |
| 376 | + if (crypto_is_dead(alg)) | |
| 377 | 377 | goto complete; |
| 378 | 378 | |
| 379 | 379 | if (err == -ECANCELED) |
| @@ -1940,7 +1940,7 @@ static int __alg_test_hash(const struct hash_testvec *vecs, · 1939 unmodified lines | ||
| 1940 | 1940 | atfm = crypto_alloc_ahash(driver, type, mask); |
| 1941 | 1941 | if (IS_ERR(atfm)) { |
| 1942 | 1942 | if (PTR_ERR(atfm) == -ENOENT) |
| 1943 | − return -ENOENT; | |
| 1943 | + return 0; | |
| 1944 | 1944 | pr_err("alg: hash: failed to allocate transform for %s: %ld\n", |
| 1945 | 1945 | driver, PTR_ERR(atfm)); |
| 1946 | 1946 | return PTR_ERR(atfm); |
| @@ -2706,7 +2706,7 @@ static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, · 759 unmodified lines | ||
| 2706 | 2706 | tfm = crypto_alloc_aead(driver, type, mask); |
| 2707 | 2707 | if (IS_ERR(tfm)) { |
| 2708 | 2708 | if (PTR_ERR(tfm) == -ENOENT) |
| 2709 | − return -ENOENT; | |
| 2709 | + return 0; | |
| 2710 | 2710 | pr_err("alg: aead: failed to allocate transform for %s: %ld\n", |
| 2711 | 2711 | driver, PTR_ERR(tfm)); |
| 2712 | 2712 | return PTR_ERR(tfm); |
| @@ -3285,7 +3285,7 @@ static int alg_test_skcipher(const struct alg_test_desc *desc, · 572 unmodified lines | ||
| 3285 | 3285 | tfm = crypto_alloc_skcipher(driver, type, mask); |
| 3286 | 3286 | if (IS_ERR(tfm)) { |
| 3287 | 3287 | if (PTR_ERR(tfm) == -ENOENT) |
| 3288 | − return -ENOENT; | |
| 3288 | + return 0; | |
| 3289 | 3289 | pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", |
| 3290 | 3290 | driver, PTR_ERR(tfm)); |
| 3291 | 3291 | return PTR_ERR(tfm); |
| @@ -3700,7 +3700,7 @@ static int alg_test_cipher(const struct alg_test_desc *desc, · 408 unmodified lines | ||
| 3700 | 3700 | tfm = crypto_alloc_cipher(driver, type, mask); |
| 3701 | 3701 | if (IS_ERR(tfm)) { |
| 3702 | 3702 | if (PTR_ERR(tfm) == -ENOENT) |
| 3703 | − return -ENOENT; | |
| 3703 | + return 0; | |
| 3704 | 3704 | printk(KERN_ERR "alg: cipher: Failed to load transform for " |
| 3705 | 3705 | "%s: %ld\n", driver, PTR_ERR(tfm)); |
| 3706 | 3706 | return PTR_ERR(tfm); |
| @@ -3726,7 +3726,7 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, · 19 unmodified lines | ||
| 3726 | 3726 | acomp = crypto_alloc_acomp(driver, type, mask); |
| 3727 | 3727 | if (IS_ERR(acomp)) { |
| 3728 | 3728 | if (PTR_ERR(acomp) == -ENOENT) |
| 3729 | − return -ENOENT; | |
| 3729 | + return 0; | |
| 3730 | 3730 | pr_err("alg: acomp: Failed to load transform for %s: %ld\n", |
| 3731 | 3731 | driver, PTR_ERR(acomp)); |
| 3732 | 3732 | return PTR_ERR(acomp); |
| @@ -3740,7 +3740,7 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, · 7 unmodified lines | ||
| 3740 | 3740 | comp = crypto_alloc_comp(driver, type, mask); |
| 3741 | 3741 | if (IS_ERR(comp)) { |
| 3742 | 3742 | if (PTR_ERR(comp) == -ENOENT) |
| 3743 | − return -ENOENT; | |
| 3743 | + return 0; | |
| 3744 | 3744 | pr_err("alg: comp: Failed to load transform for %s: %ld\n", |
| 3745 | 3745 | driver, PTR_ERR(comp)); |
| 3746 | 3746 | return PTR_ERR(comp); |
| @@ -3818,7 +3818,7 @@ static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, · 71 unmodified lines | ||
| 3818 | 3818 | rng = crypto_alloc_rng(driver, type, mask); |
| 3819 | 3819 | if (IS_ERR(rng)) { |
| 3820 | 3820 | if (PTR_ERR(rng) == -ENOENT) |
| 3821 | − return -ENOENT; | |
| 3821 | + return 0; | |
| 3822 | 3822 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " |
| 3823 | 3823 | "%ld\n", driver, PTR_ERR(rng)); |
| 3824 | 3824 | return PTR_ERR(rng); |
| @@ -3846,12 +3846,11 @@ static int drbg_cavs_test(const struct drbg_testvec *test, int pr, · 21 unmodified lines | ||
| 3846 | 3846 | |
| 3847 | 3847 | drng = crypto_alloc_rng(driver, type, mask); |
| 3848 | 3848 | if (IS_ERR(drng)) { |
| 3849 | + kfree_sensitive(buf); | |
| 3849 | 3850 | if (PTR_ERR(drng) == -ENOENT) |
| 3850 | − goto out_no_rng; | |
| 3851 | + return 0; | |
| 3851 | 3852 | printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " |
| 3852 | 3853 | "%s\n", driver); |
| 3853 | −out_no_rng: | |
| 3854 | − kfree_sensitive(buf); | |
| 3855 | 3854 | return PTR_ERR(drng); |
| 3856 | 3855 | } |
| 3857 | 3856 | |
| @@ -4095,7 +4094,7 @@ static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, · 237 unmodified lines | ||
| 4095 | 4094 | tfm = crypto_alloc_kpp(driver, type, mask); |
| 4096 | 4095 | if (IS_ERR(tfm)) { |
| 4097 | 4096 | if (PTR_ERR(tfm) == -ENOENT) |
| 4098 | − return -ENOENT; | |
| 4097 | + return 0; | |
| 4099 | 4098 | pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", |
| 4100 | 4099 | driver, PTR_ERR(tfm)); |
| 4101 | 4100 | return PTR_ERR(tfm); |
| @@ -4325,7 +4324,7 @@ static int alg_test_akcipher(const struct alg_test_desc *desc, · 223 unmodified lines | ||
| 4325 | 4324 | tfm = crypto_alloc_akcipher(driver, type, mask); |
| 4326 | 4325 | if (IS_ERR(tfm)) { |
| 4327 | 4326 | if (PTR_ERR(tfm) == -ENOENT) |
| 4328 | − return -ENOENT; | |
| 4327 | + return 0; | |
| 4329 | 4328 | pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", |
| 4330 | 4329 | driver, PTR_ERR(tfm)); |
| 4331 | 4330 | return PTR_ERR(tfm); |
| @@ -496,7 +496,7 @@ static int encode_addr_size_pairs(struct dma_xfer *xfer, struct wrapper_list *wr · 495 unmodified lines | ||
| 496 | 496 | nents = sgt->nents; |
| 497 | 497 | nents_dma = nents; |
| 498 | 498 | *size = QAIC_MANAGE_EXT_MSG_LENGTH - msg_hdr_len - sizeof(**out_trans); |
| 499 | − for_each_sgtable_sg(sgt, sg, i) { | |
| 499 | + for_each_sgtable_dma_sg(sgt, sg, i) { | |
| 500 | 500 | *size -= sizeof(*asp); |
| 501 | 501 | /* Save 1K for possible follow-up transactions. */ |
| 502 | 502 | if (*size < SZ_1K) { |
| @@ -184,7 +184,7 @@ static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_tabl · 183 unmodified lines | ||
| 184 | 184 | nents = 0; |
| 185 | 185 | |
| 186 | 186 | size = size ? size : PAGE_SIZE; |
| 187 | − for (sg = sgt_in->sgl; sg; sg = sg_next(sg)) { | |
| 187 | + for_each_sgtable_dma_sg(sgt_in, sg, j) { | |
| 188 | 188 | len = sg_dma_len(sg); |
| 189 | 189 | |
| 190 | 190 | if (!len) |
| @@ -221,7 +221,7 @@ static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_tabl · 30 unmodified lines | ||
| 221 | 221 | |
| 222 | 222 | /* copy relevant sg node and fix page and length */ |
| 223 | 223 | sgn = sgf; |
| 224 | − for_each_sgtable_sg(sgt, sg, j) { | |
| 224 | + for_each_sgtable_dma_sg(sgt, sg, j) { | |
| 225 | 225 | memcpy(sg, sgn, sizeof(*sg)); |
| 226 | 226 | if (sgn == sgf) { |
| 227 | 227 | sg_dma_address(sg) += offf; |
| @@ -301,7 +301,7 @@ static int encode_reqs(struct qaic_device *qdev, struct bo_slice *slice, · 73 unmodified lines | ||
| 301 | 301 | * fence. |
| 302 | 302 | */ |
| 303 | 303 | dev_addr = req->dev_addr; |
| 304 | − for_each_sgtable_sg(slice->sgt, sg, i) { | |
| 304 | + for_each_sgtable_dma_sg(slice->sgt, sg, i) { | |
| 305 | 305 | slice->reqs[i].cmd = cmd; |
| 306 | 306 | slice->reqs[i].src_addr = cpu_to_le64(slice->dir == DMA_TO_DEVICE ? |
| 307 | 307 | sg_dma_address(sg) : dev_addr); |
| @@ -63,7 +63,7 @@ static int cxl_dport_get_sbdf(struct pci_dev *dport_dev, u64 *sbdf) · 62 unmodified lines | ||
| 63 | 63 | seg = bridge->domain_nr; |
| 64 | 64 | |
| 65 | 65 | bus = pbus->number; |
| 66 | − *sbdf = (seg << 24) | (bus << 16) | dport_dev->devfn; | |
| 66 | + *sbdf = (seg << 24) | (bus << 16) | (dport_dev->devfn << 8); | |
| 67 | 67 | |
| 68 | 68 | return 0; |
| 69 | 69 | } |
| @@ -703,28 +703,35 @@ static LIST_HEAD(acpi_battery_list); · 702 unmodified lines | ||
| 703 | 703 | static LIST_HEAD(battery_hook_list); |
| 704 | 704 | static DEFINE_MUTEX(hook_mutex); |
| 705 | 705 | |
| 706 | −static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock) | |
| 706 | +static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook) | |
| 707 | 707 | { |
| 708 | 708 | struct acpi_battery *battery; |
| 709 | + | |
| 709 | 710 | /* |
| 710 | 711 | * In order to remove a hook, we first need to |
| 711 | 712 | * de-register all the batteries that are registered. |
| 712 | 713 | */ |
| 713 | − if (lock) | |
| 714 | − mutex_lock(&hook_mutex); | |
| 715 | 714 | list_for_each_entry(battery, &acpi_battery_list, list) { |
| 716 | 715 | if (!hook->remove_battery(battery->bat, hook)) |
| 717 | 716 | power_supply_changed(battery->bat); |
| 718 | 717 | } |
| 719 | − list_del(&hook->list); | |
| 720 | − if (lock) | |
| 721 | − mutex_unlock(&hook_mutex); | |
| 718 | + list_del_init(&hook->list); | |
| 719 | + | |
| 722 | 720 | pr_info("extension unregistered: %s\n", hook->name); |
| 723 | 721 | } |
| 724 | 722 | |
| 725 | 723 | void battery_hook_unregister(struct acpi_battery_hook *hook) |
| 726 | 724 | { |
| 727 | − __battery_hook_unregister(hook, 1); | |
| 725 | + mutex_lock(&hook_mutex); | |
| 726 | + /* | |
| 727 | + * Ignore already unregistered battery hooks. This might happen | |
| 728 | + * if a battery hook was previously unloaded due to an error when | |
| 729 | + * adding a new battery. | |
| 730 | + */ | |
| 731 | + if (!list_empty(&hook->list)) | |
| 732 | + battery_hook_unregister_unlocked(hook); | |
| 733 | + | |
| 734 | + mutex_unlock(&hook_mutex); | |
| 728 | 735 | } |
| 729 | 736 | EXPORT_SYMBOL_GPL(battery_hook_unregister); |
| 730 | 737 | |
| @@ -733,7 +740,6 @@ void battery_hook_register(struct acpi_battery_hook *hook) · 2 unmodified lines | ||
| 733 | 740 | struct acpi_battery *battery; |
| 734 | 741 | |
| 735 | 742 | mutex_lock(&hook_mutex); |
| 736 | − INIT_LIST_HEAD(&hook->list); | |
| 737 | 743 | list_add(&hook->list, &battery_hook_list); |
| 738 | 744 | /* |
| 739 | 745 | * Now that the driver is registered, we need |
| @@ -750,7 +756,7 @@ void battery_hook_register(struct acpi_battery_hook *hook) · 10 unmodified lines | ||
| 750 | 756 | * hooks. |
| 751 | 757 | */ |
| 752 | 758 | pr_err("extension failed to load: %s", hook->name); |
| 753 | − __battery_hook_unregister(hook, 0); | |
| 759 | + battery_hook_unregister_unlocked(hook); | |
| 754 | 760 | goto end; |
| 755 | 761 | } |
| 756 | 762 | |
| @@ -804,7 +810,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery) · 47 unmodified lines | ||
| 804 | 810 | */ |
| 805 | 811 | pr_err("error in extension, unloading: %s", |
| 806 | 812 | hook_node->name); |
| 807 | − __battery_hook_unregister(hook_node, 0); | |
| 813 | + battery_hook_unregister_unlocked(hook_node); | |
| 808 | 814 | } |
| 809 | 815 | } |
| 810 | 816 | mutex_unlock(&hook_mutex); |
| @@ -837,7 +843,7 @@ static void __exit battery_hook_exit(void) · 26 unmodified lines | ||
| 837 | 843 | * need to remove the hooks. |
| 838 | 844 | */ |
| 839 | 845 | list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { |
| 840 | − __battery_hook_unregister(hook, 1); | |
| 846 | + battery_hook_unregister(hook); | |
| 841 | 847 | } |
| 842 | 848 | mutex_destroy(&hook_mutex); |
| 843 | 849 | } |
| @@ -441,108 +441,59 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { · 440 unmodified lines | ||
| 441 | 441 | }, |
| 442 | 442 | }, |
| 443 | 443 | { |
| 444 | − /* Asus ExpertBook B1402CBA */ | |
| 444 | + /* Asus Vivobook X1704VAP */ | |
| 445 | 445 | .matches = { |
| 446 | 446 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 447 | − DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"), | |
| 447 | + DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"), | |
| 448 | 448 | }, |
| 449 | 449 | }, |
| 450 | 450 | { |
| 451 | − /* Asus ExpertBook B1402CVA */ | |
| 451 | + /* Asus ExpertBook B1402C* */ | |
| 452 | 452 | .matches = { |
| 453 | 453 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 454 | − DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"), | |
| 454 | + DMI_MATCH(DMI_BOARD_NAME, "B1402C"), | |
| 455 | 455 | }, |
| 456 | 456 | }, |
| 457 | 457 | { |
| 458 | − /* Asus ExpertBook B1502CBA */ | |
| 458 | + /* Asus ExpertBook B1502C* */ | |
| 459 | 459 | .matches = { |
| 460 | 460 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 461 | − DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"), | |
| 461 | + DMI_MATCH(DMI_BOARD_NAME, "B1502C"), | |
| 462 | 462 | }, |
| 463 | 463 | }, |
| 464 | 464 | { |
| 465 | − /* Asus ExpertBook B1502CGA */ | |
| 465 | + /* Asus ExpertBook B2402 (B2402CBA / B2402FBA / B2402CVA / B2402FVA) */ | |
| 466 | 466 | .matches = { |
| 467 | 467 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 468 | − DMI_MATCH(DMI_BOARD_NAME, "B1502CGA"), | |
| 468 | + DMI_MATCH(DMI_BOARD_NAME, "B2402"), | |
| 469 | 469 | }, |
| 470 | 470 | }, |
| 471 | − { | |
| 472 | − /* Asus ExpertBook B1502CVA */ | |
| 473 | − .matches = { | |
| 474 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 475 | − DMI_MATCH(DMI_BOARD_NAME, "B1502CVA"), | |
| 476 | − }, | |
| 477 | − }, | |
| 478 | 471 | { |
| 479 | − /* Asus ExpertBook B2402CBA */ | |
| 472 | + /* Asus ExpertBook B2502 (B2502CBA / B2502FBA / B2502CVA / B2502FVA) */ | |
| 480 | 473 | .matches = { |
| 481 | 474 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 482 | − DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"), | |
| 475 | + DMI_MATCH(DMI_BOARD_NAME, "B2502"), | |
| 483 | 476 | }, |
| 484 | 477 | }, |
| 485 | 478 | { |
| 486 | − /* Asus ExpertBook B2402FBA */ | |
| 479 | + /* Asus Vivobook Go E1404GA* */ | |
| 487 | 480 | .matches = { |
| 488 | 481 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 489 | − DMI_MATCH(DMI_BOARD_NAME, "B2402FBA"), | |
| 482 | + DMI_MATCH(DMI_BOARD_NAME, "E1404GA"), | |
| 490 | 483 | }, |
| 491 | 484 | }, |
| 492 | 485 | { |
| 493 | − /* Asus ExpertBook B2502 */ | |
| 494 | − .matches = { | |
| 495 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 496 | − DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"), | |
| 497 | − }, | |
| 498 | − }, | |
| 499 | − { | |
| 500 | − /* Asus ExpertBook B2502FBA */ | |
| 501 | − .matches = { | |
| 502 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 503 | − DMI_MATCH(DMI_BOARD_NAME, "B2502FBA"), | |
| 504 | − }, | |
| 505 | − }, | |
| 506 | − { | |
| 507 | − /* Asus Vivobook Go E1404GAB */ | |
| 508 | − .matches = { | |
| 509 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 510 | − DMI_MATCH(DMI_BOARD_NAME, "E1404GAB"), | |
| 511 | − }, | |
| 512 | − }, | |
| 513 | − { | |
| 514 | − /* Asus Vivobook E1504GA */ | |
| 486 | + /* Asus Vivobook E1504GA* */ | |
| 515 | 487 | .matches = { |
| 516 | 488 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 517 | 489 | DMI_MATCH(DMI_BOARD_NAME, "E1504GA"), |
| 518 | 490 | }, |
| 519 | 491 | }, |
| 520 | 492 | { |
| 521 | − /* Asus Vivobook E1504GAB */ | |
| 522 | − .matches = { | |
| 523 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 524 | − DMI_MATCH(DMI_BOARD_NAME, "E1504GAB"), | |
| 525 | − }, | |
| 526 | − }, | |
| 527 | − { | |
| 528 | − /* Asus Vivobook Pro N6506MV */ | |
| 529 | − .matches = { | |
| 530 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 531 | − DMI_MATCH(DMI_BOARD_NAME, "N6506MV"), | |
| 532 | − }, | |
| 533 | − }, | |
| 534 | − { | |
| 535 | − /* Asus Vivobook Pro N6506MU */ | |
| 536 | − .matches = { | |
| 537 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 538 | − DMI_MATCH(DMI_BOARD_NAME, "N6506MU"), | |
| 539 | − }, | |
| 540 | − }, | |
| 541 | − { | |
| 542 | − /* Asus Vivobook Pro N6506MJ */ | |
| 493 | + /* Asus Vivobook Pro N6506M* */ | |
| 543 | 494 | .matches = { |
| 544 | 495 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 545 | − DMI_MATCH(DMI_BOARD_NAME, "N6506MJ"), | |
| 496 | + DMI_MATCH(DMI_BOARD_NAME, "N6506M"), | |
| 546 | 497 | }, |
| 547 | 498 | }, |
| 548 | 499 | { |
| @@ -844,6 +844,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { · 843 unmodified lines | ||
| 844 | 844 | * controller board in their ACPI tables (and may even have one), but |
| 845 | 845 | * which need native backlight control nevertheless. |
| 846 | 846 | */ |
| 847 | + { | |
| 848 | + /* https://github.com/zabbly/linux/issues/26 */ | |
| 849 | + .callback = video_detect_force_native, | |
| 850 | + /* Dell OptiPlex 5480 AIO */ | |
| 851 | + .matches = { | |
| 852 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 853 | + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 5480 AIO"), | |
| 854 | + }, | |
| 855 | + }, | |
| 847 | 856 | { |
| 848 | 857 | /* https://bugzilla.redhat.com/show_bug.cgi?id=2303936 */ |
| 849 | 858 | .callback = video_detect_force_native, |
| @@ -4099,10 +4099,20 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) · 4098 unmodified lines | ||
| 4099 | 4099 | |
| 4100 | 4100 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); |
| 4101 | 4101 | |
| 4102 | − /* Set all devices attached to the port in standby mode */ | |
| 4103 | − ata_for_each_link(link, ap, HOST_FIRST) { | |
| 4104 | − ata_for_each_dev(dev, link, ENABLED) | |
| 4105 | − ata_dev_power_set_standby(dev); | |
| 4102 | + /* | |
| 4103 | + * We will reach this point for all of the PM events: | |
| 4104 | + * PM_EVENT_SUSPEND (if runtime pm, PM_EVENT_AUTO will also be set) | |
| 4105 | + * PM_EVENT_FREEZE, and PM_EVENT_HIBERNATE. | |
| 4106 | + * | |
| 4107 | + * We do not want to perform disk spin down for PM_EVENT_FREEZE. | |
| 4108 | + * (Spin down will be performed by the subsequent PM_EVENT_HIBERNATE.) | |
| 4109 | + */ | |
| 4110 | + if (!(ap->pm_mesg.event & PM_EVENT_FREEZE)) { | |
| 4111 | + /* Set all devices attached to the port in standby mode */ | |
| 4112 | + ata_for_each_link(link, ap, HOST_FIRST) { | |
| 4113 | + ata_for_each_dev(dev, link, ENABLED) | |
| 4114 | + ata_dev_power_set_standby(dev); | |
| 4115 | + } | |
| 4106 | 4116 | } |
| 4107 | 4117 | |
| 4108 | 4118 | /* |
| @@ -195,6 +195,7 @@ int dev_pm_domain_attach_list(struct device *dev, · 194 unmodified lines | ||
| 195 | 195 | struct device *pd_dev = NULL; |
| 196 | 196 | int ret, i, num_pds = 0; |
| 197 | 197 | bool by_id = true; |
| 198 | + size_t size; | |
| 198 | 199 | u32 pd_flags = data ? data->pd_flags : 0; |
| 199 | 200 | u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 : |
| 200 | 201 | DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; |
| @@ -217,19 +218,17 @@ int dev_pm_domain_attach_list(struct device *dev, · 16 unmodified lines | ||
| 217 | 218 | if (num_pds <= 0) |
| 218 | 219 | return 0; |
| 219 | 220 | |
| 220 | − pds = devm_kzalloc(dev, sizeof(*pds), GFP_KERNEL); | |
| 221 | + pds = kzalloc(sizeof(*pds), GFP_KERNEL); | |
| 221 | 222 | if (!pds) |
| 222 | 223 | return -ENOMEM; |
| 223 | 224 | |
| 224 | − pds->pd_devs = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_devs), | |
| 225 | − GFP_KERNEL); | |
| 226 | − if (!pds->pd_devs) | |
| 227 | − return -ENOMEM; | |
| 228 | − | |
| 229 | − pds->pd_links = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_links), | |
| 230 | − GFP_KERNEL); | |
| 231 | − if (!pds->pd_links) | |
| 232 | − return -ENOMEM; | |
| 225 | + size = sizeof(*pds->pd_devs) + sizeof(*pds->pd_links); | |
| 226 | + pds->pd_devs = kcalloc(num_pds, size, GFP_KERNEL); | |
| 227 | + if (!pds->pd_devs) { | |
| 228 | + ret = -ENOMEM; | |
| 229 | + goto free_pds; | |
| 230 | + } | |
| 231 | + pds->pd_links = (void *)(pds->pd_devs + num_pds); | |
| 233 | 232 | |
| 234 | 233 | if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON) |
| 235 | 234 | link_flags |= DL_FLAG_RPM_ACTIVE; |
| @@ -272,6 +271,9 @@ err_attach: · 36 unmodified lines | ||
| 272 | 271 | device_link_del(pds->pd_links[i]); |
| 273 | 272 | dev_pm_domain_detach(pds->pd_devs[i], true); |
| 274 | 273 | } |
| 274 | + kfree(pds->pd_devs); | |
| 275 | +free_pds: | |
| 276 | + kfree(pds); | |
| 275 | 277 | return ret; |
| 276 | 278 | } |
| 277 | 279 | EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list); |
| @@ -363,6 +365,9 @@ void dev_pm_domain_detach_list(struct dev_pm_domain_list *list) · 85 unmodified lines | ||
| 363 | 365 | device_link_del(list->pd_links[i]); |
| 364 | 366 | dev_pm_domain_detach(list->pd_devs[i], true); |
| 365 | 367 | } |
| 368 | + | |
| 369 | + kfree(list->pd_devs); | |
| 370 | + kfree(list); | |
| 366 | 371 | } |
| 367 | 372 | EXPORT_SYMBOL_GPL(dev_pm_domain_detach_list); |
| 368 | 373 | |
| @@ -361,6 +361,7 @@ ata_rw_frameinit(struct frame *f) · 360 unmodified lines | ||
| 361 | 361 | } |
| 362 | 362 | |
| 363 | 363 | ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit; |
| 364 | + dev_hold(t->ifp->nd); | |
| 364 | 365 | skb->dev = t->ifp->nd; |
| 365 | 366 | } |
| 366 | 367 | |
| @@ -401,6 +402,8 @@ aoecmd_ata_rw(struct aoedev *d) · 34 unmodified lines | ||
| 401 | 402 | __skb_queue_head_init(&queue); |
| 402 | 403 | __skb_queue_tail(&queue, skb); |
| 403 | 404 | aoenet_xmit(&queue); |
| 405 | + } else { | |
| 406 | + dev_put(f->t->ifp->nd); | |
| 404 | 407 | } |
| 405 | 408 | return 1; |
| 406 | 409 | } |
| @@ -483,10 +486,13 @@ resend(struct aoedev *d, struct frame *f) · 76 unmodified lines | ||
| 483 | 486 | memcpy(h->dst, t->addr, sizeof h->dst); |
| 484 | 487 | memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); |
| 485 | 488 | |
| 489 | + dev_hold(t->ifp->nd); | |
| 486 | 490 | skb->dev = t->ifp->nd; |
| 487 | 491 | skb = skb_clone(skb, GFP_ATOMIC); |
| 488 | − if (skb == NULL) | |
| 492 | + if (skb == NULL) { | |
| 493 | + dev_put(t->ifp->nd); | |
| 489 | 494 | return; |
| 495 | + } | |
| 490 | 496 | f->sent = ktime_get(); |
| 491 | 497 | __skb_queue_head_init(&queue); |
| 492 | 498 | __skb_queue_tail(&queue, skb); |
| @@ -617,6 +623,8 @@ probe(struct aoetgt *t) · 124 unmodified lines | ||
| 617 | 623 | __skb_queue_head_init(&queue); |
| 618 | 624 | __skb_queue_tail(&queue, skb); |
| 619 | 625 | aoenet_xmit(&queue); |
| 626 | + } else { | |
| 627 | + dev_put(f->t->ifp->nd); | |
| 620 | 628 | } |
| 621 | 629 | } |
| 622 | 630 | |
| @@ -1395,6 +1403,7 @@ aoecmd_ata_id(struct aoedev *d) · 772 unmodified lines | ||
| 1395 | 1403 | ah->cmdstat = ATA_CMD_ID_ATA; |
| 1396 | 1404 | ah->lba3 = 0xa0; |
| 1397 | 1405 | |
| 1406 | + dev_hold(t->ifp->nd); | |
| 1398 | 1407 | skb->dev = t->ifp->nd; |
| 1399 | 1408 | |
| 1400 | 1409 | d->rttavg = RTTAVG_INIT; |
| @@ -1404,6 +1413,8 @@ aoecmd_ata_id(struct aoedev *d) · 3 unmodified lines | ||
| 1404 | 1413 | skb = skb_clone(skb, GFP_ATOMIC); |
| 1405 | 1414 | if (skb) |
| 1406 | 1415 | f->sent = ktime_get(); |
| 1416 | + else | |
| 1417 | + dev_put(t->ifp->nd); | |
| 1407 | 1418 | |
| 1408 | 1419 | return skb; |
| 1409 | 1420 | } |
| @@ -1364,7 +1364,6 @@ extern struct bio_set drbd_io_bio_set; · 1363 unmodified lines | ||
| 1364 | 1364 | |
| 1365 | 1365 | extern struct mutex resources_mutex; |
| 1366 | 1366 | |
| 1367 | −extern int conn_lowest_minor(struct drbd_connection *connection); | |
| 1368 | 1367 | extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor); |
| 1369 | 1368 | extern void drbd_destroy_device(struct kref *kref); |
| 1370 | 1369 | extern void drbd_delete_device(struct drbd_device *device); |
| @@ -471,20 +471,6 @@ void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait) · 470 unmodified lines | ||
| 471 | 471 | wait_for_completion(&thi->stop); |
| 472 | 472 | } |
| 473 | 473 | |
| 474 | −int conn_lowest_minor(struct drbd_connection *connection) | |
| 475 | −{ | |
| 476 | − struct drbd_peer_device *peer_device; | |
| 477 | − int vnr = 0, minor = -1; | |
| 478 | − | |
| 479 | − rcu_read_lock(); | |
| 480 | − peer_device = idr_get_next(&connection->peer_devices, &vnr); | |
| 481 | − if (peer_device) | |
| 482 | − minor = device_to_minor(peer_device->device); | |
| 483 | − rcu_read_unlock(); | |
| 484 | − | |
| 485 | − return minor; | |
| 486 | −} | |
| 487 | − | |
| 488 | 474 | #ifdef CONFIG_SMP |
| 489 | 475 | /* |
| 490 | 476 | * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs |
| @@ -2380,10 +2380,19 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) · 2379 unmodified lines | ||
| 2380 | 2380 | * TODO: provide forward progress for RECOVERY handler, so that |
| 2381 | 2381 | * unprivileged device can benefit from it |
| 2382 | 2382 | */ |
| 2383 | − if (info.flags & UBLK_F_UNPRIVILEGED_DEV) | |
| 2383 | + if (info.flags & UBLK_F_UNPRIVILEGED_DEV) { | |
| 2384 | 2384 | info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE | |
| 2385 | 2385 | UBLK_F_USER_RECOVERY); |
| 2386 | 2386 | |
| 2387 | + /* | |
| 2388 | + * For USER_COPY, we depends on userspace to fill request | |
| 2389 | + * buffer by pwrite() to ublk char device, which can't be | |
| 2390 | + * used for unprivileged device | |
| 2391 | + */ | |
| 2392 | + if (info.flags & UBLK_F_USER_COPY) | |
| 2393 | + return -EINVAL; | |
| 2394 | + } | |
| 2395 | + | |
| 2387 | 2396 | /* the created device is always owned by current user */ |
| 2388 | 2397 | ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid); |
| 2389 | 2398 | |
| @@ -1345,10 +1345,15 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) · 1344 unmodified lines | ||
| 1345 | 1345 | if (!urb) |
| 1346 | 1346 | return -ENOMEM; |
| 1347 | 1347 | |
| 1348 | − /* Use maximum HCI Event size so the USB stack handles | |
| 1349 | − * ZPL/short-transfer automatically. | |
| 1350 | − */ | |
| 1351 | − size = HCI_MAX_EVENT_SIZE; | |
| 1348 | + if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 && | |
| 1349 | + le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001) | |
| 1350 | + /* Fake CSR devices don't seem to support sort-transter */ | |
| 1351 | + size = le16_to_cpu(data->intr_ep->wMaxPacketSize); | |
| 1352 | + else | |
| 1353 | + /* Use maximum HCI Event size so the USB stack handles | |
| 1354 | + * ZPL/short-transfer automatically. | |
| 1355 | + */ | |
| 1356 | + size = HCI_MAX_EVENT_SIZE; | |
| 1352 | 1357 | |
| 1353 | 1358 | buf = kmalloc(size, mem_flags); |
| 1354 | 1359 | if (!buf) { |
| @@ -4041,8 +4046,10 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) · 2686 unmodified lines | ||
| 4041 | 4046 | |
| 4042 | 4047 | BT_DBG("intf %p", intf); |
| 4043 | 4048 | |
| 4044 | − /* Don't suspend if there are connections */ | |
| 4045 | − if (hci_conn_count(data->hdev)) | |
| 4049 | + /* Don't auto-suspend if there are connections; external suspend calls | |
| 4050 | + * shall never fail. | |
| 4051 | + */ | |
| 4052 | + if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev)) | |
| 4046 | 4053 | return -EBUSY; |
| 4047 | 4054 | |
| 4048 | 4055 | if (data->suspend_count++) |
| @@ -2313,7 +2313,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, · 2312 unmodified lines | ||
| 2313 | 2313 | return -EINVAL; |
| 2314 | 2314 | |
| 2315 | 2315 | /* Prevent arg from speculatively bypassing the length check */ |
| 2316 | − barrier_nospec(); | |
| 2316 | + arg = array_index_nospec(arg, cdi->capacity); | |
| 2317 | 2317 | |
| 2318 | 2318 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
| 2319 | 2319 | if (!info) |
| @@ -2006,25 +2006,27 @@ static int virtcons_probe(struct virtio_device *vdev) · 2005 unmodified lines | ||
| 2006 | 2006 | multiport = true; |
| 2007 | 2007 | } |
| 2008 | 2008 | |
| 2009 | − err = init_vqs(portdev); | |
| 2010 | − if (err < 0) { | |
| 2011 | − dev_err(&vdev->dev, "Error %d initializing vqs\n", err); | |
| 2012 | − goto free_chrdev; | |
| 2013 | − } | |
| 2014 | − | |
| 2015 | 2009 | spin_lock_init(&portdev->ports_lock); |
| 2016 | 2010 | INIT_LIST_HEAD(&portdev->ports); |
| 2017 | 2011 | INIT_LIST_HEAD(&portdev->list); |
| 2018 | 2012 | |
| 2019 | − virtio_device_ready(portdev->vdev); | |
| 2020 | − | |
| 2021 | 2013 | INIT_WORK(&portdev->config_work, &config_work_handler); |
| 2022 | 2014 | INIT_WORK(&portdev->control_work, &control_work_handler); |
| 2023 | 2015 | |
| 2024 | 2016 | if (multiport) { |
| 2025 | 2017 | spin_lock_init(&portdev->c_ivq_lock); |
| 2026 | 2018 | spin_lock_init(&portdev->c_ovq_lock); |
| 2019 | + } | |
| 2027 | 2020 | |
| 2021 | + err = init_vqs(portdev); | |
| 2022 | + if (err < 0) { | |
| 2023 | + dev_err(&vdev->dev, "Error %d initializing vqs\n", err); | |
| 2024 | + goto free_chrdev; | |
| 2025 | + } | |
| 2026 | + | |
| 2027 | + virtio_device_ready(portdev->vdev); | |
| 2028 | + | |
| 2029 | + if (multiport) { | |
| 2028 | 2030 | err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); |
| 2029 | 2031 | if (err < 0) { |
| 2030 | 2032 | dev_err(&vdev->dev, |
| @@ -473,7 +473,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 472 unmodified lines | ||
| 473 | 473 | &clk_dummy_rate_ops, |
| 474 | 474 | 0); |
| 475 | 475 | ctx->parents_ctx[0].rate = DUMMY_CLOCK_RATE_1; |
| 476 | − ret = clk_hw_register(NULL, &ctx->parents_ctx[0].hw); | |
| 476 | + ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[0].hw); | |
| 477 | 477 | if (ret) |
| 478 | 478 | return ret; |
| 479 | 479 | |
| @@ -481,7 +481,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 1 unmodified line | ||
| 481 | 481 | &clk_dummy_rate_ops, |
| 482 | 482 | 0); |
| 483 | 483 | ctx->parents_ctx[1].rate = DUMMY_CLOCK_RATE_2; |
| 484 | − ret = clk_hw_register(NULL, &ctx->parents_ctx[1].hw); | |
| 484 | + ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[1].hw); | |
| 485 | 485 | if (ret) |
| 486 | 486 | return ret; |
| 487 | 487 | |
| @@ -489,23 +489,13 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 1 unmodified line | ||
| 489 | 489 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-mux", parents, |
| 490 | 490 | &clk_multiple_parents_mux_ops, |
| 491 | 491 | CLK_SET_RATE_PARENT); |
| 492 | − ret = clk_hw_register(NULL, &ctx->hw); | |
| 492 | + ret = clk_hw_register_kunit(test, NULL, &ctx->hw); | |
| 493 | 493 | if (ret) |
| 494 | 494 | return ret; |
| 495 | 495 | |
| 496 | 496 | return 0; |
| 497 | 497 | } |
| 498 | 498 | |
| 499 | −static void | |
| 500 | −clk_multiple_parents_mux_test_exit(struct kunit *test) | |
| 501 | −{ | |
| 502 | − struct clk_multiple_parent_ctx *ctx = test->priv; | |
| 503 | − | |
| 504 | − clk_hw_unregister(&ctx->hw); | |
| 505 | − clk_hw_unregister(&ctx->parents_ctx[0].hw); | |
| 506 | − clk_hw_unregister(&ctx->parents_ctx[1].hw); | |
| 507 | −} | |
| 508 | − | |
| 509 | 499 | /* |
| 510 | 500 | * Test that for a clock with multiple parents, clk_get_parent() |
| 511 | 501 | * actually returns the current one. |
| @@ -561,18 +551,18 @@ clk_test_multiple_parents_mux_set_range_set_parent_get_rate(struct kunit *test) · 49 unmodified lines | ||
| 561 | 551 | { |
| 562 | 552 | struct clk_multiple_parent_ctx *ctx = test->priv; |
| 563 | 553 | struct clk_hw *hw = &ctx->hw; |
| 564 | − struct clk *clk = clk_hw_get_clk(hw, NULL); | |
| 554 | + struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL); | |
| 565 | 555 | struct clk *parent1, *parent2; |
| 566 | 556 | unsigned long rate; |
| 567 | 557 | int ret; |
| 568 | 558 | |
| 569 | 559 | kunit_skip(test, "This needs to be fixed in the core."); |
| 570 | 560 | |
| 571 | − parent1 = clk_hw_get_clk(&ctx->parents_ctx[0].hw, NULL); | |
| 561 | + parent1 = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[0].hw, NULL); | |
| 572 | 562 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent1); |
| 573 | 563 | KUNIT_ASSERT_TRUE(test, clk_is_match(clk_get_parent(clk), parent1)); |
| 574 | 564 | |
| 575 | − parent2 = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL); | |
| 565 | + parent2 = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[1].hw, NULL); | |
| 576 | 566 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent2); |
| 577 | 567 | |
| 578 | 568 | ret = clk_set_rate(parent1, DUMMY_CLOCK_RATE_1); |
| @@ -593,10 +583,6 @@ clk_test_multiple_parents_mux_set_range_set_parent_get_rate(struct kunit *test) · 14 unmodified lines | ||
| 593 | 583 | KUNIT_ASSERT_GT(test, rate, 0); |
| 594 | 584 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1 - 1000); |
| 595 | 585 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_1 + 1000); |
| 596 | − | |
| 597 | − clk_put(parent2); | |
| 598 | − clk_put(parent1); | |
| 599 | − clk_put(clk); | |
| 600 | 586 | } |
| 601 | 587 | |
| 602 | 588 | static struct kunit_case clk_multiple_parents_mux_test_cases[] = { |
| @@ -617,7 +603,6 @@ static struct kunit_suite · 14 unmodified lines | ||
| 617 | 603 | clk_multiple_parents_mux_test_suite = { |
| 618 | 604 | .name = "clk-multiple-parents-mux-test", |
| 619 | 605 | .init = clk_multiple_parents_mux_test_init, |
| 620 | − .exit = clk_multiple_parents_mux_test_exit, | |
| 621 | 606 | .test_cases = clk_multiple_parents_mux_test_cases, |
| 622 | 607 | }; |
| 623 | 608 | |
| @@ -637,29 +622,20 @@ clk_orphan_transparent_multiple_parent_mux_test_init(struct kunit *test) · 13 unmodified lines | ||
| 637 | 622 | &clk_dummy_rate_ops, |
| 638 | 623 | 0); |
| 639 | 624 | ctx->parents_ctx[1].rate = DUMMY_CLOCK_INIT_RATE; |
| 640 | − ret = clk_hw_register(NULL, &ctx->parents_ctx[1].hw); | |
| 625 | + ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[1].hw); | |
| 641 | 626 | if (ret) |
| 642 | 627 | return ret; |
| 643 | 628 | |
| 644 | 629 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-orphan-mux", parents, |
| 645 | 630 | &clk_multiple_parents_mux_ops, |
| 646 | 631 | CLK_SET_RATE_PARENT); |
| 647 | − ret = clk_hw_register(NULL, &ctx->hw); | |
| 632 | + ret = clk_hw_register_kunit(test, NULL, &ctx->hw); | |
| 648 | 633 | if (ret) |
| 649 | 634 | return ret; |
| 650 | 635 | |
| 651 | 636 | return 0; |
| 652 | 637 | } |
| 653 | 638 | |
| 654 | −static void | |
| 655 | −clk_orphan_transparent_multiple_parent_mux_test_exit(struct kunit *test) | |
| 656 | −{ | |
| 657 | − struct clk_multiple_parent_ctx *ctx = test->priv; | |
| 658 | − | |
| 659 | − clk_hw_unregister(&ctx->hw); | |
| 660 | − clk_hw_unregister(&ctx->parents_ctx[1].hw); | |
| 661 | −} | |
| 662 | − | |
| 663 | 639 | /* |
| 664 | 640 | * Test that, for a mux whose current parent hasn't been registered yet and is |
| 665 | 641 | * thus orphan, clk_get_parent() will return NULL. |
| @@ -912,7 +888,7 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st · 246 unmodified lines | ||
| 912 | 888 | { |
| 913 | 889 | struct clk_multiple_parent_ctx *ctx = test->priv; |
| 914 | 890 | struct clk_hw *hw = &ctx->hw; |
| 915 | − struct clk *clk = clk_hw_get_clk(hw, NULL); | |
| 891 | + struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL); | |
| 916 | 892 | struct clk *parent; |
| 917 | 893 | unsigned long rate; |
| 918 | 894 | int ret; |
| @@ -921,7 +897,7 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st · 2 unmodified lines | ||
| 921 | 897 | |
| 922 | 898 | clk_hw_set_rate_range(hw, DUMMY_CLOCK_RATE_1, DUMMY_CLOCK_RATE_2); |
| 923 | 899 | |
| 924 | − parent = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL); | |
| 900 | + parent = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[1].hw, NULL); | |
| 925 | 901 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent); |
| 926 | 902 | |
| 927 | 903 | ret = clk_set_parent(clk, parent); |
| @@ -931,9 +907,6 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st · 3 unmodified lines | ||
| 931 | 907 | KUNIT_ASSERT_GT(test, rate, 0); |
| 932 | 908 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1); |
| 933 | 909 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2); |
| 934 | − | |
| 935 | − clk_put(parent); | |
| 936 | − clk_put(clk); | |
| 937 | 910 | } |
| 938 | 911 | |
| 939 | 912 | static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[] = { |
| @@ -961,7 +934,6 @@ static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[] · 21 unmodified lines | ||
| 961 | 934 | static struct kunit_suite clk_orphan_transparent_multiple_parent_mux_test_suite = { |
| 962 | 935 | .name = "clk-orphan-transparent-multiple-parent-mux-test", |
| 963 | 936 | .init = clk_orphan_transparent_multiple_parent_mux_test_init, |
| 964 | − .exit = clk_orphan_transparent_multiple_parent_mux_test_exit, | |
| 965 | 937 | .test_cases = clk_orphan_transparent_multiple_parent_mux_test_cases, |
| 966 | 938 | }; |
| 967 | 939 | |
| @@ -986,7 +958,7 @@ static int clk_single_parent_mux_test_init(struct kunit *test) · 18 unmodified lines | ||
| 986 | 958 | &clk_dummy_rate_ops, |
| 987 | 959 | 0); |
| 988 | 960 | |
| 989 | − ret = clk_hw_register(NULL, &ctx->parent_ctx.hw); | |
| 961 | + ret = clk_hw_register_kunit(test, NULL, &ctx->parent_ctx.hw); | |
| 990 | 962 | if (ret) |
| 991 | 963 | return ret; |
| 992 | 964 | |
| @@ -994,7 +966,7 @@ static int clk_single_parent_mux_test_init(struct kunit *test) · 1 unmodified line | ||
| 994 | 966 | &clk_dummy_single_parent_ops, |
| 995 | 967 | CLK_SET_RATE_PARENT); |
| 996 | 968 | |
| 997 | − ret = clk_hw_register(NULL, &ctx->hw); | |
| 969 | + ret = clk_hw_register_kunit(test, NULL, &ctx->hw); | |
| 998 | 970 | if (ret) |
| 999 | 971 | return ret; |
| 1000 | 972 | |
| @@ -1060,7 +1032,7 @@ clk_test_single_parent_mux_set_range_disjoint_child_last(struct kunit *test) · 59 unmodified lines | ||
| 1060 | 1032 | { |
| 1061 | 1033 | struct clk_single_parent_ctx *ctx = test->priv; |
| 1062 | 1034 | struct clk_hw *hw = &ctx->hw; |
| 1063 | − struct clk *clk = clk_hw_get_clk(hw, NULL); | |
| 1035 | + struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL); | |
| 1064 | 1036 | struct clk *parent; |
| 1065 | 1037 | int ret; |
| 1066 | 1038 | |
| @@ -1074,8 +1046,6 @@ clk_test_single_parent_mux_set_range_disjoint_child_last(struct kunit *test) · 7 unmodified lines | ||
| 1074 | 1046 | |
| 1075 | 1047 | ret = clk_set_rate_range(clk, 3000, 4000); |
| 1076 | 1048 | KUNIT_EXPECT_LT(test, ret, 0); |
| 1077 | − | |
| 1078 | − clk_put(clk); | |
| 1079 | 1049 | } |
| 1080 | 1050 | |
| 1081 | 1051 | /* |
| @@ -1092,7 +1062,7 @@ clk_test_single_parent_mux_set_range_disjoint_parent_last(struct kunit *test) · 10 unmodified lines | ||
| 1092 | 1062 | { |
| 1093 | 1063 | struct clk_single_parent_ctx *ctx = test->priv; |
| 1094 | 1064 | struct clk_hw *hw = &ctx->hw; |
| 1095 | − struct clk *clk = clk_hw_get_clk(hw, NULL); | |
| 1065 | + struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL); | |
| 1096 | 1066 | struct clk *parent; |
| 1097 | 1067 | int ret; |
| 1098 | 1068 | |
| @@ -1106,8 +1076,6 @@ clk_test_single_parent_mux_set_range_disjoint_parent_last(struct kunit *test) · 7 unmodified lines | ||
| 1106 | 1076 | |
| 1107 | 1077 | ret = clk_set_rate_range(parent, 3000, 4000); |
| 1108 | 1078 | KUNIT_EXPECT_LT(test, ret, 0); |
| 1109 | − | |
| 1110 | − clk_put(clk); | |
| 1111 | 1079 | } |
| 1112 | 1080 | |
| 1113 | 1081 | /* |
| @@ -1238,7 +1206,6 @@ static struct kunit_suite · 124 unmodified lines | ||
| 1238 | 1206 | clk_single_parent_mux_test_suite = { |
| 1239 | 1207 | .name = "clk-single-parent-mux-test", |
| 1240 | 1208 | .init = clk_single_parent_mux_test_init, |
| 1241 | − .exit = clk_single_parent_mux_test_exit, | |
| 1242 | 1209 | .test_cases = clk_single_parent_mux_test_cases, |
| 1243 | 1210 | }; |
| 1244 | 1211 | |
| @@ -439,7 +439,7 @@ unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list, · 438 unmodified lines | ||
| 439 | 439 | if (list->id > max) |
| 440 | 440 | max = list->id; |
| 441 | 441 | if (list->child && list->child->id > max) |
| 442 | − max = list->id; | |
| 442 | + max = list->child->id; | |
| 443 | 443 | } |
| 444 | 444 | |
| 445 | 445 | return max; |
| @@ -1155,6 +1155,7 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { · 1154 unmodified lines | ||
| 1155 | 1155 | .compatible = "samsung,exynosautov920-cmu-peric0", |
| 1156 | 1156 | .data = &peric0_cmu_info, |
| 1157 | 1157 | }, |
| 1158 | + { } | |
| 1158 | 1159 | }; |
| 1159 | 1160 | |
| 1160 | 1161 | static struct platform_driver exynosautov920_cmu_driver __refdata = { |
| @@ -536,11 +536,16 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy) · 535 unmodified lines | ||
| 536 | 536 | |
| 537 | 537 | static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy) |
| 538 | 538 | { |
| 539 | − u32 max_limit_perf, min_limit_perf, lowest_perf; | |
| 539 | + u32 max_limit_perf, min_limit_perf, lowest_perf, max_perf; | |
| 540 | 540 | struct amd_cpudata *cpudata = policy->driver_data; |
| 541 | 541 | |
| 542 | − max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | |
| 543 | − min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | |
| 542 | + if (cpudata->boost_supported && !policy->boost_enabled) | |
| 543 | + max_perf = READ_ONCE(cpudata->nominal_perf); | |
| 544 | + else | |
| 545 | + max_perf = READ_ONCE(cpudata->highest_perf); | |
| 546 | + | |
| 547 | + max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq); | |
| 548 | + min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq); | |
| 544 | 549 | |
| 545 | 550 | lowest_perf = READ_ONCE(cpudata->lowest_perf); |
| 546 | 551 | if (min_limit_perf < lowest_perf) |
| @@ -1201,11 +1206,21 @@ static int amd_pstate_register_driver(int mode) · 654 unmodified lines | ||
| 1201 | 1206 | return -EINVAL; |
| 1202 | 1207 | |
| 1203 | 1208 | cppc_state = mode; |
| 1209 | + | |
| 1210 | + ret = amd_pstate_enable(true); | |
| 1211 | + if (ret) { | |
| 1212 | + pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n", | |
| 1213 | + ret); | |
| 1214 | + amd_pstate_driver_cleanup(); | |
| 1215 | + return ret; | |
| 1216 | + } | |
| 1217 | + | |
| 1204 | 1218 | ret = cpufreq_register_driver(current_pstate_driver); |
| 1205 | 1219 | if (ret) { |
| 1206 | 1220 | amd_pstate_driver_cleanup(); |
| 1207 | 1221 | return ret; |
| 1208 | 1222 | } |
| 1223 | + | |
| 1209 | 1224 | return 0; |
| 1210 | 1225 | } |
| 1211 | 1226 | |
| @@ -1496,10 +1511,13 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) · 284 unmodified lines | ||
| 1496 | 1511 | u64 value; |
| 1497 | 1512 | s16 epp; |
| 1498 | 1513 | |
| 1499 | − max_perf = READ_ONCE(cpudata->highest_perf); | |
| 1514 | + if (cpudata->boost_supported && !policy->boost_enabled) | |
| 1515 | + max_perf = READ_ONCE(cpudata->nominal_perf); | |
| 1516 | + else | |
| 1517 | + max_perf = READ_ONCE(cpudata->highest_perf); | |
| 1500 | 1518 | min_perf = READ_ONCE(cpudata->lowest_perf); |
| 1501 | − max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | |
| 1502 | − min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | |
| 1519 | + max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq); | |
| 1520 | + min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq); | |
| 1503 | 1521 | |
| 1504 | 1522 | if (min_limit_perf < min_perf) |
| 1505 | 1523 | min_limit_perf = min_perf; |
| @@ -1845,7 +1845,7 @@ static void intel_pstate_notify_work(struct work_struct *work) · 1844 unmodified lines | ||
| 1845 | 1845 | wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0); |
| 1846 | 1846 | } |
| 1847 | 1847 | |
| 1848 | −static DEFINE_SPINLOCK(hwp_notify_lock); | |
| 1848 | +static DEFINE_RAW_SPINLOCK(hwp_notify_lock); | |
| 1849 | 1849 | static cpumask_t hwp_intr_enable_mask; |
| 1850 | 1850 | |
| 1851 | 1851 | #define HWP_GUARANTEED_PERF_CHANGE_STATUS BIT(0) |
| @@ -1868,7 +1868,7 @@ void notify_hwp_interrupt(void) · 16 unmodified lines | ||
| 1868 | 1868 | if (!(value & status_mask)) |
| 1869 | 1869 | return; |
| 1870 | 1870 | |
| 1871 | − spin_lock_irqsave(&hwp_notify_lock, flags); | |
| 1871 | + raw_spin_lock_irqsave(&hwp_notify_lock, flags); | |
| 1872 | 1872 | |
| 1873 | 1873 | if (!cpumask_test_cpu(this_cpu, &hwp_intr_enable_mask)) |
| 1874 | 1874 | goto ack_intr; |
| @@ -1876,13 +1876,13 @@ void notify_hwp_interrupt(void) · 1 unmodified line | ||
| 1876 | 1876 | schedule_delayed_work(&all_cpu_data[this_cpu]->hwp_notify_work, |
| 1877 | 1877 | msecs_to_jiffies(10)); |
| 1878 | 1878 | |
| 1879 | − spin_unlock_irqrestore(&hwp_notify_lock, flags); | |
| 1879 | + raw_spin_unlock_irqrestore(&hwp_notify_lock, flags); | |
| 1880 | 1880 | |
| 1881 | 1881 | return; |
| 1882 | 1882 | |
| 1883 | 1883 | ack_intr: |
| 1884 | 1884 | wrmsrl_safe(MSR_HWP_STATUS, 0); |
| 1885 | − spin_unlock_irqrestore(&hwp_notify_lock, flags); | |
| 1885 | + raw_spin_unlock_irqrestore(&hwp_notify_lock, flags); | |
| 1886 | 1886 | } |
| 1887 | 1887 | |
| 1888 | 1888 | static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata) |
| @@ -1895,9 +1895,9 @@ static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata) · 6 unmodified lines | ||
| 1895 | 1895 | /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */ |
| 1896 | 1896 | wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00); |
| 1897 | 1897 | |
| 1898 | − spin_lock_irq(&hwp_notify_lock); | |
| 1898 | + raw_spin_lock_irq(&hwp_notify_lock); | |
| 1899 | 1899 | cancel_work = cpumask_test_and_clear_cpu(cpudata->cpu, &hwp_intr_enable_mask); |
| 1900 | − spin_unlock_irq(&hwp_notify_lock); | |
| 1900 | + raw_spin_unlock_irq(&hwp_notify_lock); | |
| 1901 | 1901 | |
| 1902 | 1902 | if (cancel_work) |
| 1903 | 1903 | cancel_delayed_work_sync(&cpudata->hwp_notify_work); |
| @@ -1912,10 +1912,10 @@ static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata) · 8 unmodified lines | ||
| 1912 | 1912 | if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) { |
| 1913 | 1913 | u64 interrupt_mask = HWP_GUARANTEED_PERF_CHANGE_REQ; |
| 1914 | 1914 | |
| 1915 | − spin_lock_irq(&hwp_notify_lock); | |
| 1915 | + raw_spin_lock_irq(&hwp_notify_lock); | |
| 1916 | 1916 | INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work); |
| 1917 | 1917 | cpumask_set_cpu(cpudata->cpu, &hwp_intr_enable_mask); |
| 1918 | − spin_unlock_irq(&hwp_notify_lock); | |
| 1918 | + raw_spin_unlock_irq(&hwp_notify_lock); | |
| 1919 | 1919 | |
| 1920 | 1920 | if (cpu_feature_enabled(X86_FEATURE_HWP_HIGHEST_PERF_CHANGE)) |
| 1921 | 1921 | interrupt_mask |= HWP_HIGHEST_PERF_CHANGE_REQ; |
| @@ -947,7 +947,7 @@ struct ahash_alg mv_md5_alg = { · 946 unmodified lines | ||
| 947 | 947 | .base = { |
| 948 | 948 | .cra_name = "md5", |
| 949 | 949 | .cra_driver_name = "mv-md5", |
| 950 | − .cra_priority = 300, | |
| 950 | + .cra_priority = 0, | |
| 951 | 951 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 952 | 952 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 953 | 953 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1018,7 +1018,7 @@ struct ahash_alg mv_sha1_alg = { · 64 unmodified lines | ||
| 1018 | 1018 | .base = { |
| 1019 | 1019 | .cra_name = "sha1", |
| 1020 | 1020 | .cra_driver_name = "mv-sha1", |
| 1021 | − .cra_priority = 300, | |
| 1021 | + .cra_priority = 0, | |
| 1022 | 1022 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1023 | 1023 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1024 | 1024 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1092,7 +1092,7 @@ struct ahash_alg mv_sha256_alg = { · 67 unmodified lines | ||
| 1092 | 1092 | .base = { |
| 1093 | 1093 | .cra_name = "sha256", |
| 1094 | 1094 | .cra_driver_name = "mv-sha256", |
| 1095 | − .cra_priority = 300, | |
| 1095 | + .cra_priority = 0, | |
| 1096 | 1096 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1097 | 1097 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1098 | 1098 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1302,7 +1302,7 @@ struct ahash_alg mv_ahmac_md5_alg = { · 203 unmodified lines | ||
| 1302 | 1302 | .base = { |
| 1303 | 1303 | .cra_name = "hmac(md5)", |
| 1304 | 1304 | .cra_driver_name = "mv-hmac-md5", |
| 1305 | − .cra_priority = 300, | |
| 1305 | + .cra_priority = 0, | |
| 1306 | 1306 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1307 | 1307 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1308 | 1308 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1373,7 +1373,7 @@ struct ahash_alg mv_ahmac_sha1_alg = { · 64 unmodified lines | ||
| 1373 | 1373 | .base = { |
| 1374 | 1374 | .cra_name = "hmac(sha1)", |
| 1375 | 1375 | .cra_driver_name = "mv-hmac-sha1", |
| 1376 | − .cra_priority = 300, | |
| 1376 | + .cra_priority = 0, | |
| 1377 | 1377 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1378 | 1378 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1379 | 1379 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1444,7 +1444,7 @@ struct ahash_alg mv_ahmac_sha256_alg = { · 64 unmodified lines | ||
| 1444 | 1444 | .base = { |
| 1445 | 1445 | .cra_name = "hmac(sha256)", |
| 1446 | 1446 | .cra_driver_name = "mv-hmac-sha256", |
| 1447 | − .cra_priority = 300, | |
| 1447 | + .cra_priority = 0, | |
| 1448 | 1448 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1449 | 1449 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1450 | 1450 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -86,7 +86,7 @@ static void dax_set_mapping(struct vm_fault *vmf, pfn_t pfn, · 85 unmodified lines | ||
| 86 | 86 | nr_pages = 1; |
| 87 | 87 | |
| 88 | 88 | pgoff = linear_page_index(vmf->vma, |
| 89 | − ALIGN(vmf->address, fault_size)); | |
| 89 | + ALIGN_DOWN(vmf->address, fault_size)); | |
| 90 | 90 | |
| 91 | 91 | for (i = 0; i < nr_pages; i++) { |
| 92 | 92 | struct page *page = pfn_to_page(pfn_t_to_pfn(pfn) + i); |
| @@ -1391,11 +1391,12 @@ static struct ep93xx_dma_engine *ep93xx_dma_of_probe(struct platform_device *pde · 1390 unmodified lines | ||
| 1391 | 1391 | INIT_LIST_HEAD(&dma_dev->channels); |
| 1392 | 1392 | for (i = 0; i < edma->num_channels; i++) { |
| 1393 | 1393 | struct ep93xx_dma_chan *edmac = &edma->channels[i]; |
| 1394 | + int len; | |
| 1394 | 1395 | |
| 1395 | 1396 | edmac->chan.device = dma_dev; |
| 1396 | 1397 | edmac->regs = devm_platform_ioremap_resource(pdev, i); |
| 1397 | 1398 | if (IS_ERR(edmac->regs)) |
| 1398 | − return edmac->regs; | |
| 1399 | + return ERR_CAST(edmac->regs); | |
| 1399 | 1400 | |
| 1400 | 1401 | edmac->irq = fwnode_irq_get(dev_fwnode(dev), i); |
| 1401 | 1402 | if (edmac->irq < 0) |
| @@ -1404,9 +1405,11 @@ static struct ep93xx_dma_engine *ep93xx_dma_of_probe(struct platform_device *pde · 2 unmodified lines | ||
| 1404 | 1405 | edmac->edma = edma; |
| 1405 | 1406 | |
| 1406 | 1407 | if (edma->m2m) |
| 1407 | − snprintf(dma_clk_name, sizeof(dma_clk_name), "m2m%u", i); | |
| 1408 | + len = snprintf(dma_clk_name, sizeof(dma_clk_name), "m2m%u", i); | |
| 1408 | 1409 | else |
| 1409 | − snprintf(dma_clk_name, sizeof(dma_clk_name), "m2p%u", i); | |
| 1410 | + len = snprintf(dma_clk_name, sizeof(dma_clk_name), "m2p%u", i); | |
| 1411 | + if (len >= sizeof(dma_clk_name)) | |
| 1412 | + return ERR_PTR(-ENOBUFS); | |
| 1410 | 1413 | |
| 1411 | 1414 | edmac->clk = devm_clk_get(dev, dma_clk_name); |
| 1412 | 1415 | if (IS_ERR(edmac->clk)) { |
| @@ -481,11 +481,16 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid, · 480 unmodified lines | ||
| 481 | 481 | struct ffa_send_direct_data2 *data) |
| 482 | 482 | { |
| 483 | 483 | u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id); |
| 484 | + union { | |
| 485 | + uuid_t uuid; | |
| 486 | + __le64 regs[2]; | |
| 487 | + } uuid_regs = { .uuid = *uuid }; | |
| 484 | 488 | ffa_value_t ret, args = { |
| 485 | − .a0 = FFA_MSG_SEND_DIRECT_REQ2, .a1 = src_dst_ids, | |
| 489 | + .a0 = FFA_MSG_SEND_DIRECT_REQ2, | |
| 490 | + .a1 = src_dst_ids, | |
| 491 | + .a2 = le64_to_cpu(uuid_regs.regs[0]), | |
| 492 | + .a3 = le64_to_cpu(uuid_regs.regs[1]), | |
| 486 | 493 | }; |
| 487 | − | |
| 488 | − export_uuid((u8 *)&args.a2, uuid); | |
| 489 | 494 | memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data)); |
| 490 | 495 | |
| 491 | 496 | invoke_ffa_fn(args, &ret); |
| @@ -496,7 +501,7 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid, · 4 unmodified lines | ||
| 496 | 501 | return ffa_to_linux_errno((int)ret.a2); |
| 497 | 502 | |
| 498 | 503 | if (ret.a0 == FFA_MSG_SEND_DIRECT_RESP2) { |
| 499 | − memcpy(data, &ret.a4, sizeof(*data)); | |
| 504 | + memcpy(data, (void *)&ret + offsetof(ffa_value_t, a4), sizeof(*data)); | |
| 500 | 505 | return 0; |
| 501 | 506 | } |
| 502 | 507 | |
| @@ -2976,10 +2976,8 @@ static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info) · 2975 unmodified lines | ||
| 2976 | 2976 | dbg->top_dentry = top_dentry; |
| 2977 | 2977 | |
| 2978 | 2978 | if (devm_add_action_or_reset(info->dev, |
| 2979 | − scmi_debugfs_common_cleanup, dbg)) { | |
| 2980 | − scmi_debugfs_common_cleanup(dbg); | |
| 2979 | + scmi_debugfs_common_cleanup, dbg)) | |
| 2981 | 2980 | return NULL; |
| 2982 | − } | |
| 2983 | 2981 | |
| 2984 | 2982 | return dbg; |
| 2985 | 2983 | } |
| @@ -1,8 +1,10 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | −scmi_transport_mailbox-objs := mailbox.o | |
| 3 | −obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o | |
| 2 | +# Keep before scmi_transport_mailbox.o to allow precedence | |
| 3 | +# while matching the compatible. | |
| 4 | 4 | scmi_transport_smc-objs := smc.o |
| 5 | 5 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += scmi_transport_smc.o |
| 6 | +scmi_transport_mailbox-objs := mailbox.o | |
| 7 | +obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o | |
| 6 | 8 | scmi_transport_optee-objs := optee.o |
| 7 | 9 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o |
| 8 | 10 | scmi_transport_virtio-objs := virtio.o |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel |
| 26 | 26 | * @cinfo: SCMI channel info |
| 27 | 27 | * @shmem: Transmit/Receive shared memory area |
| 28 | + * @chan_lock: Lock that prevents multiple xfers from being queued | |
| 28 | 29 | */ |
| 29 | 30 | struct scmi_mailbox { |
| 30 | 31 | struct mbox_client cl; |
| @@ -33,6 +34,7 @@ struct scmi_mailbox { · 2 unmodified lines | ||
| 33 | 34 | struct mbox_chan *chan_platform_receiver; |
| 34 | 35 | struct scmi_chan_info *cinfo; |
| 35 | 36 | struct scmi_shared_mem __iomem *shmem; |
| 37 | + struct mutex chan_lock; | |
| 36 | 38 | }; |
| 37 | 39 | |
| 38 | 40 | #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl) |
| @@ -238,6 +240,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 199 unmodified lines | ||
| 238 | 240 | |
| 239 | 241 | cinfo->transport_info = smbox; |
| 240 | 242 | smbox->cinfo = cinfo; |
| 243 | + mutex_init(&smbox->chan_lock); | |
| 241 | 244 | |
| 242 | 245 | return 0; |
| 243 | 246 | } |
| @@ -267,13 +270,23 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo, · 23 unmodified lines | ||
| 267 | 270 | struct scmi_mailbox *smbox = cinfo->transport_info; |
| 268 | 271 | int ret; |
| 269 | 272 | |
| 270 | − ret = mbox_send_message(smbox->chan, xfer); | |
| 273 | + /* | |
| 274 | + * The mailbox layer has its own queue. However the mailbox queue | |
| 275 | + * confuses the per message SCMI timeouts since the clock starts when | |
| 276 | + * the message is submitted into the mailbox queue. So when multiple | |
| 277 | + * messages are queued up the clock starts on all messages instead of | |
| 278 | + * only the one inflight. | |
| 279 | + */ | |
| 280 | + mutex_lock(&smbox->chan_lock); | |
| 271 | 281 | |
| 272 | − /* mbox_send_message returns non-negative value on success, so reset */ | |
| 273 | − if (ret > 0) | |
| 274 | − ret = 0; | |
| 282 | + ret = mbox_send_message(smbox->chan, xfer); | |
| 283 | + /* mbox_send_message returns non-negative value on success */ | |
| 284 | + if (ret < 0) { | |
| 285 | + mutex_unlock(&smbox->chan_lock); | |
| 286 | + return ret; | |
| 287 | + } | |
| 275 | 288 | |
| 276 | − return ret; | |
| 289 | + return 0; | |
| 277 | 290 | } |
| 278 | 291 | |
| 279 | 292 | static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret, |
| @@ -281,13 +294,10 @@ static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret, · 1 unmodified line | ||
| 281 | 294 | { |
| 282 | 295 | struct scmi_mailbox *smbox = cinfo->transport_info; |
| 283 | 296 | |
| 284 | − /* | |
| 285 | − * NOTE: we might prefer not to need the mailbox ticker to manage the | |
| 286 | − * transfer queueing since the protocol layer queues things by itself. | |
| 287 | − * Unfortunately, we have to kick the mailbox framework after we have | |
| 288 | − * received our message. | |
| 289 | − */ | |
| 290 | 297 | mbox_client_txdone(smbox->chan, ret); |
| 298 | + | |
| 299 | + /* Release channel */ | |
| 300 | + mutex_unlock(&smbox->chan_lock); | |
| 291 | 301 | } |
| 292 | 302 | |
| 293 | 303 | static void mailbox_fetch_response(struct scmi_chan_info *cinfo, |
| @@ -67,9 +67,11 @@ static bool sysfb_unregister(void) · 66 unmodified lines | ||
| 67 | 67 | void sysfb_disable(struct device *dev) |
| 68 | 68 | { |
| 69 | 69 | struct screen_info *si = &screen_info; |
| 70 | + struct device *parent; | |
| 70 | 71 | |
| 71 | 72 | mutex_lock(&disable_lock); |
| 72 | − if (!dev || dev == sysfb_parent_dev(si)) { | |
| 73 | + parent = sysfb_parent_dev(si); | |
| 74 | + if (!dev || !parent || dev == parent) { | |
| 73 | 75 | sysfb_unregister(); |
| 74 | 76 | disabled = true; |
| 75 | 77 | } |
| @@ -406,6 +406,8 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, · 405 unmodified lines | ||
| 406 | 406 | gpio->dcache[GPIO_BANK(offset)] = reg; |
| 407 | 407 | |
| 408 | 408 | iowrite32(reg, addr); |
| 409 | + /* Flush write */ | |
| 410 | + ioread32(addr); | |
| 409 | 411 | } |
| 410 | 412 | |
| 411 | 413 | static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, |
| @@ -1191,7 +1193,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) · 779 unmodified lines | ||
| 1191 | 1193 | if (!gpio_id) |
| 1192 | 1194 | return -EINVAL; |
| 1193 | 1195 | |
| 1194 | − gpio->clk = of_clk_get(pdev->dev.of_node, 0); | |
| 1196 | + gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL); | |
| 1195 | 1197 | if (IS_ERR(gpio->clk)) { |
| 1196 | 1198 | dev_warn(&pdev->dev, |
| 1197 | 1199 | "Failed to get clock from devicetree, debouncing disabled\n"); |
| @@ -253,7 +253,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) · 252 unmodified lines | ||
| 253 | 253 | * serve as EDMA event triggers. |
| 254 | 254 | */ |
| 255 | 255 | |
| 256 | −static void gpio_irq_disable(struct irq_data *d) | |
| 256 | +static void gpio_irq_mask(struct irq_data *d) | |
| 257 | 257 | { |
| 258 | 258 | struct davinci_gpio_regs __iomem *g = irq2regs(d); |
| 259 | 259 | uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); |
| @@ -262,7 +262,7 @@ static void gpio_irq_disable(struct irq_data *d) · 2 unmodified lines | ||
| 262 | 262 | writel_relaxed(mask, &g->clr_rising); |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | −static void gpio_irq_enable(struct irq_data *d) | |
| 265 | +static void gpio_irq_unmask(struct irq_data *d) | |
| 266 | 266 | { |
| 267 | 267 | struct davinci_gpio_regs __iomem *g = irq2regs(d); |
| 268 | 268 | uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); |
| @@ -288,8 +288,8 @@ static int gpio_irq_type(struct irq_data *d, unsigned trigger) · 19 unmodified lines | ||
| 288 | 288 | |
| 289 | 289 | static struct irq_chip gpio_irqchip = { |
| 290 | 290 | .name = "GPIO", |
| 291 | − .irq_enable = gpio_irq_enable, | |
| 292 | − .irq_disable = gpio_irq_disable, | |
| 291 | + .irq_unmask = gpio_irq_unmask, | |
| 292 | + .irq_mask = gpio_irq_mask, | |
| 293 | 293 | .irq_set_type = gpio_irq_type, |
| 294 | 294 | .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE, |
| 295 | 295 | }; |
| @@ -472,7 +472,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) · 176 unmodified lines | ||
| 472 | 472 | return PTR_ERR(clk); |
| 473 | 473 | } |
| 474 | 474 | |
| 475 | − if (chips->gpio_unbanked) { | |
| 475 | + if (!chips->gpio_unbanked) { | |
| 476 | 476 | irq = devm_irq_alloc_descs(dev, -1, 0, ngpio, 0); |
| 477 | 477 | if (irq < 0) { |
| 478 | 478 | dev_err(dev, "Couldn't allocate IRQ numbers\n"); |
| @@ -114,12 +114,12 @@ const char *gpiod_get_label(struct gpio_desc *desc) · 113 unmodified lines | ||
| 114 | 114 | srcu_read_lock_held(&desc->gdev->desc_srcu)); |
| 115 | 115 | |
| 116 | 116 | if (test_bit(FLAG_USED_AS_IRQ, &flags)) |
| 117 | − return label->str ?: "interrupt"; | |
| 117 | + return label ? label->str : "interrupt"; | |
| 118 | 118 | |
| 119 | 119 | if (!test_bit(FLAG_REQUESTED, &flags)) |
| 120 | 120 | return NULL; |
| 121 | 121 | |
| 122 | − return label->str; | |
| 122 | + return label ? label->str : NULL; | |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | static void desc_free_label(struct rcu_head *rh) |
| @@ -1439,8 +1439,8 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, · 1438 unmodified lines | ||
| 1439 | 1439 | list_add_tail(&vm->vm_list_node, |
| 1440 | 1440 | &(vm->process_info->vm_list_head)); |
| 1441 | 1441 | vm->process_info->n_vms++; |
| 1442 | − | |
| 1443 | − *ef = dma_fence_get(&vm->process_info->eviction_fence->base); | |
| 1442 | + if (ef) | |
| 1443 | + *ef = dma_fence_get(&vm->process_info->eviction_fence->base); | |
| 1444 | 1444 | mutex_unlock(&vm->process_info->lock); |
| 1445 | 1445 | |
| 1446 | 1446 | return 0; |
| @@ -265,7 +265,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, · 264 unmodified lines | ||
| 265 | 265 | |
| 266 | 266 | /* Only a single BO list is allowed to simplify handling. */ |
| 267 | 267 | if (p->bo_list) |
| 268 | − ret = -EINVAL; | |
| 268 | + goto free_partial_kdata; | |
| 269 | 269 | |
| 270 | 270 | ret = amdgpu_cs_p1_bo_handles(p, p->chunks[i].kdata); |
| 271 | 271 | if (ret) |
| @@ -1635,11 +1635,9 @@ int amdgpu_gfx_sysfs_isolation_shader_init(struct amdgpu_device *adev) · 1634 unmodified lines | ||
| 1635 | 1635 | { |
| 1636 | 1636 | int r; |
| 1637 | 1637 | |
| 1638 | − if (!amdgpu_sriov_vf(adev)) { | |
| 1639 | − r = device_create_file(adev->dev, &dev_attr_enforce_isolation); | |
| 1640 | − if (r) | |
| 1641 | − return r; | |
| 1642 | − } | |
| 1638 | + r = device_create_file(adev->dev, &dev_attr_enforce_isolation); | |
| 1639 | + if (r) | |
| 1640 | + return r; | |
| 1643 | 1641 | |
| 1644 | 1642 | r = device_create_file(adev->dev, &dev_attr_run_cleaner_shader); |
| 1645 | 1643 | if (r) |
| @@ -1650,8 +1648,7 @@ int amdgpu_gfx_sysfs_isolation_shader_init(struct amdgpu_device *adev) · 4 unmodified lines | ||
| 1650 | 1648 | |
| 1651 | 1649 | void amdgpu_gfx_sysfs_isolation_shader_fini(struct amdgpu_device *adev) |
| 1652 | 1650 | { |
| 1653 | − if (!amdgpu_sriov_vf(adev)) | |
| 1654 | − device_remove_file(adev->dev, &dev_attr_enforce_isolation); | |
| 1651 | + device_remove_file(adev->dev, &dev_attr_enforce_isolation); | |
| 1655 | 1652 | device_remove_file(adev->dev, &dev_attr_run_cleaner_shader); |
| 1656 | 1653 | } |
| 1657 | 1654 | |
| @@ -1203,8 +1203,10 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id, · 1202 unmodified lines | ||
| 1203 | 1203 | |
| 1204 | 1204 | r = amdgpu_ring_init(adev, ring, 1024, NULL, 0, |
| 1205 | 1205 | AMDGPU_RING_PRIO_DEFAULT, NULL); |
| 1206 | − if (r) | |
| 1206 | + if (r) { | |
| 1207 | + amdgpu_mes_unlock(&adev->mes); | |
| 1207 | 1208 | goto clean_up_memory; |
| 1209 | + } | |
| 1208 | 1210 | |
| 1209 | 1211 | amdgpu_mes_ring_to_queue_props(adev, ring, &qprops); |
| 1210 | 1212 | |
| @@ -1237,7 +1239,6 @@ clean_up_ring: · 26 unmodified lines | ||
| 1237 | 1239 | amdgpu_ring_fini(ring); |
| 1238 | 1240 | clean_up_memory: |
| 1239 | 1241 | kfree(ring); |
| 1240 | − amdgpu_mes_unlock(&adev->mes); | |
| 1241 | 1242 | return r; |
| 1242 | 1243 | } |
| 1243 | 1244 | |
| @@ -621,7 +621,7 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) · 620 unmodified lines | ||
| 621 | 621 | |
| 622 | 622 | if (amdgpu_mes_log_enable) { |
| 623 | 623 | mes_set_hw_res_pkt.enable_mes_event_int_logging = 1; |
| 624 | − mes_set_hw_res_pkt.event_intr_history_gpu_mc_ptr = mes->event_log_gpu_addr; | |
| 624 | + mes_set_hw_res_pkt.event_intr_history_gpu_mc_ptr = mes->event_log_gpu_addr + pipe * AMDGPU_MES_LOG_BUFFER_SIZE; | |
| 625 | 625 | } |
| 626 | 626 | |
| 627 | 627 | return mes_v12_0_submit_pkt_and_poll_completion(mes, pipe, |
| @@ -1336,7 +1336,7 @@ static int mes_v12_0_sw_init(void *handle) · 708 unmodified lines | ||
| 1336 | 1336 | adev->mes.kiq_hw_fini = &mes_v12_0_kiq_hw_fini; |
| 1337 | 1337 | adev->mes.enable_legacy_queue_map = true; |
| 1338 | 1338 | |
| 1339 | − adev->mes.event_log_size = AMDGPU_MES_LOG_BUFFER_SIZE; | |
| 1339 | + adev->mes.event_log_size = adev->enable_uni_mes ? (AMDGPU_MAX_MES_PIPES * AMDGPU_MES_LOG_BUFFER_SIZE) : AMDGPU_MES_LOG_BUFFER_SIZE; | |
| 1340 | 1340 | |
| 1341 | 1341 | r = amdgpu_mes_init(adev); |
| 1342 | 1342 | if (r) |
| @@ -1148,7 +1148,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, · 1147 unmodified lines | ||
| 1148 | 1148 | |
| 1149 | 1149 | if (flags & KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM) |
| 1150 | 1150 | size >>= 1; |
| 1151 | − WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + PAGE_ALIGN(size)); | |
| 1151 | + atomic64_add(PAGE_ALIGN(size), &pdd->vram_usage); | |
| 1152 | 1152 | } |
| 1153 | 1153 | |
| 1154 | 1154 | mutex_unlock(&p->mutex); |
| @@ -1219,7 +1219,7 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep, · 64 unmodified lines | ||
| 1219 | 1219 | kfd_process_device_remove_obj_handle( |
| 1220 | 1220 | pdd, GET_IDR_HANDLE(args->handle)); |
| 1221 | 1221 | |
| 1222 | − WRITE_ONCE(pdd->vram_usage, pdd->vram_usage - size); | |
| 1222 | + atomic64_sub(size, &pdd->vram_usage); | |
| 1223 | 1223 | |
| 1224 | 1224 | err_unlock: |
| 1225 | 1225 | err_pdd: |
| @@ -2347,7 +2347,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd, · 1121 unmodified lines | ||
| 2347 | 2347 | } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) { |
| 2348 | 2348 | bo_bucket->restored_offset = offset; |
| 2349 | 2349 | /* Update the VRAM usage count */ |
| 2350 | − WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + bo_bucket->size); | |
| 2350 | + atomic64_add(bo_bucket->size, &pdd->vram_usage); | |
| 2351 | 2351 | } |
| 2352 | 2352 | return 0; |
| 2353 | 2353 | } |
| @@ -775,7 +775,7 @@ struct kfd_process_device { · 774 unmodified lines | ||
| 775 | 775 | enum kfd_pdd_bound bound; |
| 776 | 776 | |
| 777 | 777 | /* VRAM usage */ |
| 778 | − uint64_t vram_usage; | |
| 778 | + atomic64_t vram_usage; | |
| 779 | 779 | struct attribute attr_vram; |
| 780 | 780 | char vram_filename[MAX_SYSFS_FILENAME_LEN]; |
| 781 | 781 | |
| @@ -332,7 +332,7 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr, · 331 unmodified lines | ||
| 332 | 332 | } else if (strncmp(attr->name, "vram_", 5) == 0) { |
| 333 | 333 | struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device, |
| 334 | 334 | attr_vram); |
| 335 | − return snprintf(buffer, PAGE_SIZE, "%llu\n", READ_ONCE(pdd->vram_usage)); | |
| 335 | + return snprintf(buffer, PAGE_SIZE, "%llu\n", atomic64_read(&pdd->vram_usage)); | |
| 336 | 336 | } else if (strncmp(attr->name, "sdma_", 5) == 0) { |
| 337 | 337 | struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device, |
| 338 | 338 | attr_sdma); |
| @@ -1625,7 +1625,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_node *dev, · 1286 unmodified lines | ||
| 1625 | 1625 | pdd->bound = PDD_UNBOUND; |
| 1626 | 1626 | pdd->already_dequeued = false; |
| 1627 | 1627 | pdd->runtime_inuse = false; |
| 1628 | − pdd->vram_usage = 0; | |
| 1628 | + atomic64_set(&pdd->vram_usage, 0); | |
| 1629 | 1629 | pdd->sdma_past_activity_counter = 0; |
| 1630 | 1630 | pdd->user_gpu_id = dev->id; |
| 1631 | 1631 | atomic64_set(&pdd->evict_duration_counter, 0); |
| @@ -1702,12 +1702,15 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd, · 70 unmodified lines | ||
| 1702 | 1702 | |
| 1703 | 1703 | ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(dev->adev, avm, |
| 1704 | 1704 | &p->kgd_process_info, |
| 1705 | − &ef); | |
| 1705 | + p->ef ? NULL : &ef); | |
| 1706 | 1706 | if (ret) { |
| 1707 | 1707 | dev_err(dev->adev->dev, "Failed to create process VM object\n"); |
| 1708 | 1708 | return ret; |
| 1709 | 1709 | } |
| 1710 | − RCU_INIT_POINTER(p->ef, ef); | |
| 1710 | + | |
| 1711 | + if (!p->ef) | |
| 1712 | + RCU_INIT_POINTER(p->ef, ef); | |
| 1713 | + | |
| 1711 | 1714 | pdd->drm_priv = drm_file->private_data; |
| 1712 | 1715 | |
| 1713 | 1716 | ret = kfd_process_device_reserve_ib_mem(pdd); |
| @@ -405,6 +405,27 @@ static void svm_range_bo_release(struct kref *kref) · 404 unmodified lines | ||
| 405 | 405 | spin_lock(&svm_bo->list_lock); |
| 406 | 406 | } |
| 407 | 407 | spin_unlock(&svm_bo->list_lock); |
| 408 | + | |
| 409 | + if (mmget_not_zero(svm_bo->eviction_fence->mm)) { | |
| 410 | + struct kfd_process_device *pdd; | |
| 411 | + struct kfd_process *p; | |
| 412 | + struct mm_struct *mm; | |
| 413 | + | |
| 414 | + mm = svm_bo->eviction_fence->mm; | |
| 415 | + /* | |
| 416 | + * The forked child process takes svm_bo device pages ref, svm_bo could be | |
| 417 | + * released after parent process is gone. | |
| 418 | + */ | |
| 419 | + p = kfd_lookup_process_by_mm(mm); | |
| 420 | + if (p) { | |
| 421 | + pdd = kfd_get_process_device_data(svm_bo->node, p); | |
| 422 | + if (pdd) | |
| 423 | + atomic64_sub(amdgpu_bo_size(svm_bo->bo), &pdd->vram_usage); | |
| 424 | + kfd_unref_process(p); | |
| 425 | + } | |
| 426 | + mmput(mm); | |
| 427 | + } | |
| 428 | + | |
| 408 | 429 | if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) |
| 409 | 430 | /* We're not in the eviction worker. Signal the fence. */ |
| 410 | 431 | dma_fence_signal(&svm_bo->eviction_fence->base); |
| @@ -532,6 +553,7 @@ int · 121 unmodified lines | ||
| 532 | 553 | svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange, |
| 533 | 554 | bool clear) |
| 534 | 555 | { |
| 556 | + struct kfd_process_device *pdd; | |
| 535 | 557 | struct amdgpu_bo_param bp; |
| 536 | 558 | struct svm_range_bo *svm_bo; |
| 537 | 559 | struct amdgpu_bo_user *ubo; |
| @@ -623,6 +645,10 @@ svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange, · 85 unmodified lines | ||
| 623 | 645 | list_add(&prange->svm_bo_list, &svm_bo->range_list); |
| 624 | 646 | spin_unlock(&svm_bo->list_lock); |
| 625 | 647 | |
| 648 | + pdd = svm_range_get_pdd_by_node(prange, node); | |
| 649 | + if (pdd) | |
| 650 | + atomic64_add(amdgpu_bo_size(bo), &pdd->vram_usage); | |
| 651 | + | |
| 626 | 652 | return 0; |
| 627 | 653 | |
| 628 | 654 | reserve_bo_failed: |
| @@ -770,6 +770,12 @@ static void dmub_hpd_callback(struct amdgpu_device *adev, · 769 unmodified lines | ||
| 770 | 770 | return; |
| 771 | 771 | } |
| 772 | 772 | |
| 773 | + /* Skip DMUB HPD IRQ in suspend/resume. We will probe them later. */ | |
| 774 | + if (notify->type == DMUB_NOTIFICATION_HPD && adev->in_suspend) { | |
| 775 | + DRM_INFO("Skip DMUB HPD IRQ callback in suspend/resume\n"); | |
| 776 | + return; | |
| 777 | + } | |
| 778 | + | |
| 773 | 779 | link_index = notify->link_index; |
| 774 | 780 | link = adev->dm.dc->links[link_index]; |
| 775 | 781 | dev = adev->dm.ddev; |
| @@ -2026,7 +2032,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 1250 unmodified lines | ||
| 2026 | 2032 | DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n"); |
| 2027 | 2033 | } |
| 2028 | 2034 | |
| 2029 | − if (adev->dm.dc->caps.ips_support && adev->dm.dc->config.disable_ips == DMUB_IPS_ENABLE) | |
| 2035 | + if (adev->dm.dc->caps.ips_support && | |
| 2036 | + adev->dm.dc->config.disable_ips != DMUB_IPS_DISABLE_ALL) | |
| 2030 | 2037 | adev->dm.idle_workqueue = idle_create_workqueue(adev); |
| 2031 | 2038 | |
| 2032 | 2039 | if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) { |
| @@ -2965,10 +2972,11 @@ static int dm_suspend(void *handle) · 932 unmodified lines | ||
| 2965 | 2972 | |
| 2966 | 2973 | hpd_rx_irq_work_suspend(dm); |
| 2967 | 2974 | |
| 2968 | − if (adev->dm.dc->caps.ips_support) | |
| 2969 | − dc_allow_idle_optimizations(adev->dm.dc, true); | |
| 2970 | − | |
| 2971 | 2975 | dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3); |
| 2976 | + | |
| 2977 | + if (dm->dc->caps.ips_support && adev->in_s0ix) | |
| 2978 | + dc_allow_idle_optimizations(dm->dc, true); | |
| 2979 | + | |
| 2972 | 2980 | dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D3); |
| 2973 | 2981 | |
| 2974 | 2982 | return 0; |
| @@ -6735,12 +6743,21 @@ create_stream_for_sink(struct drm_connector *connector, · 3760 unmodified lines | ||
| 6735 | 6743 | if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || |
| 6736 | 6744 | stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST || |
| 6737 | 6745 | stream->signal == SIGNAL_TYPE_EDP) { |
| 6746 | + const struct dc_edid_caps *edid_caps; | |
| 6747 | + unsigned int disable_colorimetry = 0; | |
| 6748 | + | |
| 6749 | + if (aconnector->dc_sink) { | |
| 6750 | + edid_caps = &aconnector->dc_sink->edid_caps; | |
| 6751 | + disable_colorimetry = edid_caps->panel_patch.disable_colorimetry; | |
| 6752 | + } | |
| 6753 | + | |
| 6738 | 6754 | // |
| 6739 | 6755 | // should decide stream support vsc sdp colorimetry capability |
| 6740 | 6756 | // before building vsc info packet |
| 6741 | 6757 | // |
| 6742 | 6758 | stream->use_vsc_sdp_for_colorimetry = stream->link->dpcd_caps.dpcd_rev.raw >= 0x14 && |
| 6743 | − stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED; | |
| 6759 | + stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED && | |
| 6760 | + !disable_colorimetry; | |
| 6744 | 6761 | |
| 6745 | 6762 | if (stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22) |
| 6746 | 6763 | tf = TRANSFER_FUNC_GAMMA_22; |
| @@ -73,6 +73,10 @@ static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps) · 72 unmodified lines | ||
| 73 | 73 | DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id); |
| 74 | 74 | edid_caps->panel_patch.remove_sink_ext_caps = true; |
| 75 | 75 | break; |
| 76 | + case drm_edid_encode_panel_id('S', 'D', 'C', 0x4154): | |
| 77 | + DRM_DEBUG_DRIVER("Disabling VSC on monitor with panel id %X\n", panel_id); | |
| 78 | + edid_caps->panel_patch.disable_colorimetry = true; | |
| 79 | + break; | |
| 76 | 80 | default: |
| 77 | 81 | return; |
| 78 | 82 | } |
| @@ -1027,6 +1027,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, · 1026 unmodified lines | ||
| 1027 | 1027 | int remaining_to_try = 0; |
| 1028 | 1028 | int ret; |
| 1029 | 1029 | uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); |
| 1030 | + int var_pbn; | |
| 1030 | 1031 | |
| 1031 | 1032 | for (i = 0; i < count; i++) { |
| 1032 | 1033 | if (vars[i + k].dsc_enabled |
| @@ -1057,13 +1058,18 @@ static int try_disable_dsc(struct drm_atomic_state *state, · 24 unmodified lines | ||
| 1057 | 1058 | break; |
| 1058 | 1059 | |
| 1059 | 1060 | DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index); |
| 1061 | + var_pbn = vars[next_index].pbn; | |
| 1060 | 1062 | vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000); |
| 1061 | 1063 | ret = drm_dp_atomic_find_time_slots(state, |
| 1062 | 1064 | params[next_index].port->mgr, |
| 1063 | 1065 | params[next_index].port, |
| 1064 | 1066 | vars[next_index].pbn); |
| 1065 | − if (ret < 0) | |
| 1067 | + if (ret < 0) { | |
| 1068 | + DRM_DEBUG_DRIVER("%s:%d MST_DSC index #%d, failed to set pbn to the state, %d\n", | |
| 1069 | + __func__, __LINE__, next_index, ret); | |
| 1070 | + vars[next_index].pbn = var_pbn; | |
| 1066 | 1071 | return ret; |
| 1072 | + } | |
| 1067 | 1073 | |
| 1068 | 1074 | ret = drm_dp_mst_atomic_check(state); |
| 1069 | 1075 | if (ret == 0) { |
| @@ -1071,14 +1077,17 @@ static int try_disable_dsc(struct drm_atomic_state *state, · 1 unmodified line | ||
| 1071 | 1077 | vars[next_index].dsc_enabled = false; |
| 1072 | 1078 | vars[next_index].bpp_x16 = 0; |
| 1073 | 1079 | } else { |
| 1074 | − DRM_DEBUG_DRIVER("MST_DSC index #%d, restore minimum compression\n", next_index); | |
| 1075 | − vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000); | |
| 1080 | + DRM_DEBUG_DRIVER("MST_DSC index #%d, restore optimized pbn value\n", next_index); | |
| 1081 | + vars[next_index].pbn = var_pbn; | |
| 1076 | 1082 | ret = drm_dp_atomic_find_time_slots(state, |
| 1077 | 1083 | params[next_index].port->mgr, |
| 1078 | 1084 | params[next_index].port, |
| 1079 | 1085 | vars[next_index].pbn); |
| 1080 | − if (ret < 0) | |
| 1086 | + if (ret < 0) { | |
| 1087 | + DRM_DEBUG_DRIVER("%s:%d MST_DSC index #%d, failed to set pbn to the state, %d\n", | |
| 1088 | + __func__, __LINE__, next_index, ret); | |
| 1081 | 1089 | return ret; |
| 1090 | + } | |
| 1082 | 1091 | } |
| 1083 | 1092 | |
| 1084 | 1093 | tried[next_index] = true; |
| @@ -5065,11 +5065,26 @@ static bool update_planes_and_stream_v3(struct dc *dc, · 5064 unmodified lines | ||
| 5065 | 5065 | return true; |
| 5066 | 5066 | } |
| 5067 | 5067 | |
| 5068 | +static void clear_update_flags(struct dc_surface_update *srf_updates, | |
| 5069 | + int surface_count, struct dc_stream_state *stream) | |
| 5070 | +{ | |
| 5071 | + int i; | |
| 5072 | + | |
| 5073 | + if (stream) | |
| 5074 | + stream->update_flags.raw = 0; | |
| 5075 | + | |
| 5076 | + for (i = 0; i < surface_count; i++) | |
| 5077 | + if (srf_updates[i].surface) | |
| 5078 | + srf_updates[i].surface->update_flags.raw = 0; | |
| 5079 | +} | |
| 5080 | + | |
| 5068 | 5081 | bool dc_update_planes_and_stream(struct dc *dc, |
| 5069 | 5082 | struct dc_surface_update *srf_updates, int surface_count, |
| 5070 | 5083 | struct dc_stream_state *stream, |
| 5071 | 5084 | struct dc_stream_update *stream_update) |
| 5072 | 5085 | { |
| 5086 | + bool ret = false; | |
| 5087 | + | |
| 5073 | 5088 | dc_exit_ips_for_hw_access(dc); |
| 5074 | 5089 | /* |
| 5075 | 5090 | * update planes and stream version 3 separates FULL and FAST updates |
| @@ -5086,10 +5101,16 @@ bool dc_update_planes_and_stream(struct dc *dc, · 10 unmodified lines | ||
| 5086 | 5101 | * features as they are now transparent to the new sequence. |
| 5087 | 5102 | */ |
| 5088 | 5103 | if (dc->ctx->dce_version >= DCN_VERSION_4_01) |
| 5089 | − return update_planes_and_stream_v3(dc, srf_updates, | |
| 5104 | + ret = update_planes_and_stream_v3(dc, srf_updates, | |
| 5090 | 5105 | surface_count, stream, stream_update); |
| 5091 | − return update_planes_and_stream_v2(dc, srf_updates, | |
| 5106 | + else | |
| 5107 | + ret = update_planes_and_stream_v2(dc, srf_updates, | |
| 5092 | 5108 | surface_count, stream, stream_update); |
| 5109 | + | |
| 5110 | + if (ret) | |
| 5111 | + clear_update_flags(srf_updates, surface_count, stream); | |
| 5112 | + | |
| 5113 | + return ret; | |
| 5093 | 5114 | } |
| 5094 | 5115 | |
| 5095 | 5116 | void dc_commit_updates_for_stream(struct dc *dc, |
| @@ -5099,6 +5120,8 @@ void dc_commit_updates_for_stream(struct dc *dc, · 3 unmodified lines | ||
| 5099 | 5120 | struct dc_stream_update *stream_update, |
| 5100 | 5121 | struct dc_state *state) |
| 5101 | 5122 | { |
| 5123 | + bool ret = false; | |
| 5124 | + | |
| 5102 | 5125 | dc_exit_ips_for_hw_access(dc); |
| 5103 | 5126 | /* TODO: Since change commit sequence can have a huge impact, |
| 5104 | 5127 | * we decided to only enable it for DCN3x. However, as soon as |
| @@ -5106,17 +5129,17 @@ void dc_commit_updates_for_stream(struct dc *dc, · 1 unmodified line | ||
| 5106 | 5129 | * the new sequence for all ASICs. |
| 5107 | 5130 | */ |
| 5108 | 5131 | if (dc->ctx->dce_version >= DCN_VERSION_4_01) { |
| 5109 | − update_planes_and_stream_v3(dc, srf_updates, surface_count, | |
| 5132 | + ret = update_planes_and_stream_v3(dc, srf_updates, surface_count, | |
| 5110 | 5133 | stream, stream_update); |
| 5111 | − return; | |
| 5112 | − } | |
| 5113 | − if (dc->ctx->dce_version >= DCN_VERSION_3_2) { | |
| 5114 | − update_planes_and_stream_v2(dc, srf_updates, surface_count, | |
| 5134 | + } else if (dc->ctx->dce_version >= DCN_VERSION_3_2) { | |
| 5135 | + ret = update_planes_and_stream_v2(dc, srf_updates, surface_count, | |
| 5115 | 5136 | stream, stream_update); |
| 5116 | − return; | |
| 5117 | − } | |
| 5118 | − update_planes_and_stream_v1(dc, srf_updates, surface_count, stream, | |
| 5119 | − stream_update, state); | |
| 5137 | + } else | |
| 5138 | + ret = update_planes_and_stream_v1(dc, srf_updates, surface_count, stream, | |
| 5139 | + stream_update, state); | |
| 5140 | + | |
| 5141 | + if (ret) | |
| 5142 | + clear_update_flags(srf_updates, surface_count, stream); | |
| 5120 | 5143 | } |
| 5121 | 5144 | |
| 5122 | 5145 | uint8_t dc_get_current_stream_count(struct dc *dc) |
| @@ -178,6 +178,7 @@ struct dc_panel_patch { · 177 unmodified lines | ||
| 178 | 178 | unsigned int skip_avmute; |
| 179 | 179 | unsigned int mst_start_top_delay; |
| 180 | 180 | unsigned int remove_sink_ext_caps; |
| 181 | + unsigned int disable_colorimetry; | |
| 181 | 182 | }; |
| 182 | 183 | |
| 183 | 184 | struct dc_edid_caps { |
| @@ -303,7 +303,6 @@ void build_unoptimized_policy_settings(enum dml_project_id project, struct dml_m · 302 unmodified lines | ||
| 303 | 303 | if (project == dml_project_dcn35 || |
| 304 | 304 | project == dml_project_dcn351) { |
| 305 | 305 | policy->DCCProgrammingAssumesScanDirectionUnknownFinal = false; |
| 306 | − policy->EnhancedPrefetchScheduleAccelerationFinal = 0; | |
| 307 | 306 | policy->AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter_if_possible; /*new*/ |
| 308 | 307 | policy->UseOnlyMaxPrefetchModes = 1; |
| 309 | 308 | } |
| @@ -766,6 +766,7 @@ static const struct dc_debug_options debug_defaults_drv = { · 765 unmodified lines | ||
| 766 | 766 | .disable_dmub_reallow_idle = false, |
| 767 | 767 | .static_screen_wait_frames = 2, |
| 768 | 768 | .notify_dpia_hr_bw = true, |
| 769 | + .min_disp_clk_khz = 50000, | |
| 769 | 770 | }; |
| 770 | 771 | |
| 771 | 772 | static const struct dc_panel_config panel_config_defaults = { |
| @@ -60,7 +60,7 @@ struct vi_dpm_level { · 59 unmodified lines | ||
| 60 | 60 | |
| 61 | 61 | struct vi_dpm_table { |
| 62 | 62 | uint32_t count; |
| 63 | − struct vi_dpm_level dpm_level[] __counted_by(count); | |
| 63 | + struct vi_dpm_level dpm_level[]; | |
| 64 | 64 | }; |
| 65 | 65 | |
| 66 | 66 | #define PCIE_PERF_REQ_REMOVE_REGISTRY 0 |
| @@ -91,7 +91,7 @@ struct phm_set_power_state_input { · 24 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | struct phm_clock_array { |
| 93 | 93 | uint32_t count; |
| 94 | − uint32_t values[] __counted_by(count); | |
| 94 | + uint32_t values[]; | |
| 95 | 95 | }; |
| 96 | 96 | |
| 97 | 97 | struct phm_clock_voltage_dependency_record { |
| @@ -123,7 +123,7 @@ struct phm_acpclock_voltage_dependency_record { · 25 unmodified lines | ||
| 123 | 123 | |
| 124 | 124 | struct phm_clock_voltage_dependency_table { |
| 125 | 125 | uint32_t count; |
| 126 | − struct phm_clock_voltage_dependency_record entries[] __counted_by(count); | |
| 126 | + struct phm_clock_voltage_dependency_record entries[]; | |
| 127 | 127 | }; |
| 128 | 128 | |
| 129 | 129 | struct phm_phase_shedding_limits_record { |
| @@ -140,7 +140,7 @@ struct phm_uvd_clock_voltage_dependency_record { · 10 unmodified lines | ||
| 140 | 140 | |
| 141 | 141 | struct phm_uvd_clock_voltage_dependency_table { |
| 142 | 142 | uint8_t count; |
| 143 | − struct phm_uvd_clock_voltage_dependency_record entries[] __counted_by(count); | |
| 143 | + struct phm_uvd_clock_voltage_dependency_record entries[]; | |
| 144 | 144 | }; |
| 145 | 145 | |
| 146 | 146 | struct phm_acp_clock_voltage_dependency_record { |
| @@ -150,7 +150,7 @@ struct phm_acp_clock_voltage_dependency_record { · 3 unmodified lines | ||
| 150 | 150 | |
| 151 | 151 | struct phm_acp_clock_voltage_dependency_table { |
| 152 | 152 | uint32_t count; |
| 153 | − struct phm_acp_clock_voltage_dependency_record entries[] __counted_by(count); | |
| 153 | + struct phm_acp_clock_voltage_dependency_record entries[]; | |
| 154 | 154 | }; |
| 155 | 155 | |
| 156 | 156 | struct phm_vce_clock_voltage_dependency_record { |
| @@ -161,32 +161,32 @@ struct phm_vce_clock_voltage_dependency_record { · 4 unmodified lines | ||
| 161 | 161 | |
| 162 | 162 | struct phm_phase_shedding_limits_table { |
| 163 | 163 | uint32_t count; |
| 164 | − struct phm_phase_shedding_limits_record entries[] __counted_by(count); | |
| 164 | + struct phm_phase_shedding_limits_record entries[]; | |
| 165 | 165 | }; |
| 166 | 166 | |
| 167 | 167 | struct phm_vceclock_voltage_dependency_table { |
| 168 | 168 | uint8_t count; |
| 169 | − struct phm_vceclock_voltage_dependency_record entries[] __counted_by(count); | |
| 169 | + struct phm_vceclock_voltage_dependency_record entries[]; | |
| 170 | 170 | }; |
| 171 | 171 | |
| 172 | 172 | struct phm_uvdclock_voltage_dependency_table { |
| 173 | 173 | uint8_t count; |
| 174 | − struct phm_uvdclock_voltage_dependency_record entries[] __counted_by(count); | |
| 174 | + struct phm_uvdclock_voltage_dependency_record entries[]; | |
| 175 | 175 | }; |
| 176 | 176 | |
| 177 | 177 | struct phm_samuclock_voltage_dependency_table { |
| 178 | 178 | uint8_t count; |
| 179 | − struct phm_samuclock_voltage_dependency_record entries[] __counted_by(count); | |
| 179 | + struct phm_samuclock_voltage_dependency_record entries[]; | |
| 180 | 180 | }; |
| 181 | 181 | |
| 182 | 182 | struct phm_acpclock_voltage_dependency_table { |
| 183 | 183 | uint32_t count; |
| 184 | − struct phm_acpclock_voltage_dependency_record entries[] __counted_by(count); | |
| 184 | + struct phm_acpclock_voltage_dependency_record entries[]; | |
| 185 | 185 | }; |
| 186 | 186 | |
| 187 | 187 | struct phm_vce_clock_voltage_dependency_table { |
| 188 | 188 | uint8_t count; |
| 189 | − struct phm_vce_clock_voltage_dependency_record entries[] __counted_by(count); | |
| 189 | + struct phm_vce_clock_voltage_dependency_record entries[]; | |
| 190 | 190 | }; |
| 191 | 191 | |
| 192 | 192 | |
| @@ -393,7 +393,7 @@ union phm_cac_leakage_record { · 200 unmodified lines | ||
| 393 | 393 | |
| 394 | 394 | struct phm_cac_leakage_table { |
| 395 | 395 | uint32_t count; |
| 396 | − union phm_cac_leakage_record entries[] __counted_by(count); | |
| 396 | + union phm_cac_leakage_record entries[]; | |
| 397 | 397 | }; |
| 398 | 398 | |
| 399 | 399 | struct phm_samu_clock_voltage_dependency_record { |
| @@ -404,7 +404,7 @@ struct phm_samu_clock_voltage_dependency_record { · 4 unmodified lines | ||
| 404 | 404 | |
| 405 | 405 | struct phm_samu_clock_voltage_dependency_table { |
| 406 | 406 | uint8_t count; |
| 407 | − struct phm_samu_clock_voltage_dependency_record entries[] __counted_by(count); | |
| 407 | + struct phm_samu_clock_voltage_dependency_record entries[]; | |
| 408 | 408 | }; |
| 409 | 409 | |
| 410 | 410 | struct phm_cac_tdp_table { |
| @@ -1264,7 +1264,11 @@ static int smu_sw_init(void *handle) · 1263 unmodified lines | ||
| 1264 | 1264 | smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4; |
| 1265 | 1265 | smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5; |
| 1266 | 1266 | smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6; |
| 1267 | − smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; | |
| 1267 | + | |
| 1268 | + if (smu->is_apu) | |
| 1269 | + smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; | |
| 1270 | + else | |
| 1271 | + smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D]; | |
| 1268 | 1272 | |
| 1269 | 1273 | smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; |
| 1270 | 1274 | smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D; |
| @@ -2226,7 +2230,7 @@ static int smu_bump_power_profile_mode(struct smu_context *smu, · 955 unmodified lines | ||
| 2226 | 2230 | static int smu_adjust_power_state_dynamic(struct smu_context *smu, |
| 2227 | 2231 | enum amd_dpm_forced_level level, |
| 2228 | 2232 | bool skip_display_settings, |
| 2229 | − bool force_update) | |
| 2233 | + bool init) | |
| 2230 | 2234 | { |
| 2231 | 2235 | int ret = 0; |
| 2232 | 2236 | int index = 0; |
| @@ -2255,7 +2259,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, · 22 unmodified lines | ||
| 2255 | 2259 | } |
| 2256 | 2260 | } |
| 2257 | 2261 | |
| 2258 | − if (force_update || smu_dpm_ctx->dpm_level != level) { | |
| 2262 | + if (smu_dpm_ctx->dpm_level != level) { | |
| 2259 | 2263 | ret = smu_asic_set_performance_level(smu, level); |
| 2260 | 2264 | if (ret) { |
| 2261 | 2265 | dev_err(smu->adev->dev, "Failed to set performance level!"); |
| @@ -2272,7 +2276,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, · 10 unmodified lines | ||
| 2272 | 2276 | index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; |
| 2273 | 2277 | workload[0] = smu->workload_setting[index]; |
| 2274 | 2278 | |
| 2275 | − if (force_update || smu->power_profile_mode != workload[0]) | |
| 2279 | + if (init || smu->power_profile_mode != workload[0]) | |
| 2276 | 2280 | smu_bump_power_profile_mode(smu, workload, 0); |
| 2277 | 2281 | } |
| 2278 | 2282 | |
| @@ -2555,18 +2555,16 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, · 2554 unmodified lines | ||
| 2555 | 2555 | workload_mask = 1 << workload_type; |
| 2556 | 2556 | |
| 2557 | 2557 | /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */ |
| 2558 | − if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE) { | |
| 2559 | − if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) && | |
| 2560 | − ((smu->adev->pm.fw_version == 0x004e6601) || | |
| 2561 | − (smu->adev->pm.fw_version >= 0x004e7300))) || | |
| 2562 | − (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) && | |
| 2563 | − smu->adev->pm.fw_version >= 0x00504500)) { | |
| 2564 | − workload_type = smu_cmn_to_asic_specific_index(smu, | |
| 2565 | − CMN2ASIC_MAPPING_WORKLOAD, | |
| 2566 | − PP_SMC_POWER_PROFILE_POWERSAVING); | |
| 2567 | − if (workload_type >= 0) | |
| 2568 | − workload_mask |= 1 << workload_type; | |
| 2569 | − } | |
| 2558 | + if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) && | |
| 2559 | + ((smu->adev->pm.fw_version == 0x004e6601) || | |
| 2560 | + (smu->adev->pm.fw_version >= 0x004e7300))) || | |
| 2561 | + (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) && | |
| 2562 | + smu->adev->pm.fw_version >= 0x00504500)) { | |
| 2563 | + workload_type = smu_cmn_to_asic_specific_index(smu, | |
| 2564 | + CMN2ASIC_MAPPING_WORKLOAD, | |
| 2565 | + PP_SMC_POWER_PROFILE_POWERSAVING); | |
| 2566 | + if (workload_type >= 0) | |
| 2567 | + workload_mask |= 1 << workload_type; | |
| 2570 | 2568 | } |
| 2571 | 2569 | |
| 2572 | 2570 | ret = smu_cmn_send_smc_msg_with_param(smu, |
| @@ -29,6 +29,8 @@ static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector · 28 unmodified lines | ||
| 29 | 29 | if (ast_connector->physical_status == connector_status_connected) { |
| 30 | 30 | count = drm_connector_helper_get_modes(connector); |
| 31 | 31 | } else { |
| 32 | + drm_edid_connector_update(connector, NULL); | |
| 33 | + | |
| 32 | 34 | /* |
| 33 | 35 | * There's no EDID data without a connected monitor. Set BMC- |
| 34 | 36 | * compatible modes in this case. The XGA default resolution |
| @@ -29,6 +29,8 @@ static int ast_vga_connector_helper_get_modes(struct drm_connector *connector) · 28 unmodified lines | ||
| 29 | 29 | if (ast_connector->physical_status == connector_status_connected) { |
| 30 | 30 | count = drm_connector_helper_get_modes(connector); |
| 31 | 31 | } else { |
| 32 | + drm_edid_connector_update(connector, NULL); | |
| 33 | + | |
| 32 | 34 | /* |
| 33 | 35 | * There's no EDID data without a connected monitor. Set BMC- |
| 34 | 36 | * compatible modes in this case. The XGA default resolution |
| @@ -6083,6 +6083,7 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) · 6082 unmodified lines | ||
| 6083 | 6083 | struct drm_dp_aux *immediate_upstream_aux; |
| 6084 | 6084 | struct drm_dp_mst_port *fec_port; |
| 6085 | 6085 | struct drm_dp_desc desc = {}; |
| 6086 | + u8 upstream_dsc; | |
| 6086 | 6087 | u8 endpoint_fec; |
| 6087 | 6088 | u8 endpoint_dsc; |
| 6088 | 6089 | |
| @@ -6109,8 +6110,6 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) · 20 unmodified lines | ||
| 6109 | 6110 | |
| 6110 | 6111 | /* DP-to-DP peer device */ |
| 6111 | 6112 | if (drm_dp_mst_is_virtual_dpcd(immediate_upstream_port)) { |
| 6112 | − u8 upstream_dsc; | |
| 6113 | − | |
| 6114 | 6113 | if (drm_dp_dpcd_read(&port->aux, |
| 6115 | 6114 | DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1) |
| 6116 | 6115 | return NULL; |
| @@ -6156,6 +6155,13 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) · 39 unmodified lines | ||
| 6156 | 6155 | if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) { |
| 6157 | 6156 | u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; |
| 6158 | 6157 | |
| 6158 | + if (drm_dp_dpcd_read(immediate_upstream_aux, | |
| 6159 | + DP_DSC_SUPPORT, &upstream_dsc, 1) != 1) | |
| 6160 | + return NULL; | |
| 6161 | + | |
| 6162 | + if (!(upstream_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED)) | |
| 6163 | + return NULL; | |
| 6164 | + | |
| 6159 | 6165 | if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0) |
| 6160 | 6166 | return NULL; |
| 6161 | 6167 | |
| @@ -521,8 +521,6 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, · 520 unmodified lines | ||
| 521 | 521 | } |
| 522 | 522 | EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); |
| 523 | 523 | |
| 524 | −#define HDMI_MAX_INFOFRAME_SIZE 29 | |
| 525 | − | |
| 526 | 524 | static int clear_device_infoframe(struct drm_connector *connector, |
| 527 | 525 | enum hdmi_infoframe_type type) |
| 528 | 526 | { |
| @@ -563,7 +561,7 @@ static int write_device_infoframe(struct drm_connector *connector, · 34 unmodified lines | ||
| 563 | 561 | { |
| 564 | 562 | const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; |
| 565 | 563 | struct drm_device *dev = connector->dev; |
| 566 | − u8 buffer[HDMI_MAX_INFOFRAME_SIZE]; | |
| 564 | + u8 buffer[HDMI_INFOFRAME_SIZE(MAX)]; | |
| 567 | 565 | int ret; |
| 568 | 566 | int len; |
| 569 | 567 | |
| @@ -543,7 +543,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, · 542 unmodified lines | ||
| 543 | 543 | &state->fb_damage_clips, |
| 544 | 544 | val, |
| 545 | 545 | -1, |
| 546 | − sizeof(struct drm_rect), | |
| 546 | + sizeof(struct drm_mode_rect), | |
| 547 | 547 | &replaced); |
| 548 | 548 | return ret; |
| 549 | 549 | } else if (property == plane->scaling_filter_property) { |
| @@ -520,8 +520,6 @@ static const struct file_operations drm_connector_fops = { · 519 unmodified lines | ||
| 520 | 520 | .write = connector_write |
| 521 | 521 | }; |
| 522 | 522 | |
| 523 | −#define HDMI_MAX_INFOFRAME_SIZE 29 | |
| 524 | − | |
| 525 | 523 | static ssize_t |
| 526 | 524 | audio_infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos) |
| 527 | 525 | { |
| @@ -579,7 +577,7 @@ static ssize_t _f##_read_infoframe(struct file *filp, \ · 51 unmodified lines | ||
| 579 | 577 | struct drm_connector *connector; \ |
| 580 | 578 | union hdmi_infoframe *frame; \ |
| 581 | 579 | struct drm_device *dev; \ |
| 582 | − u8 buf[HDMI_MAX_INFOFRAME_SIZE]; \ | |
| 580 | + u8 buf[HDMI_INFOFRAME_SIZE(MAX)]; \ | |
| 583 | 581 | ssize_t len = 0; \ |
| 584 | 582 | \ |
| 585 | 583 | connector = filp->private_data; \ |
| @@ -50,7 +50,8 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info) · 49 unmodified lines | ||
| 50 | 50 | if (!fb_helper->dev) |
| 51 | 51 | return; |
| 52 | 52 | |
| 53 | − fb_deferred_io_cleanup(info); | |
| 53 | + if (info->fbdefio) | |
| 54 | + fb_deferred_io_cleanup(info); | |
| 54 | 55 | drm_fb_helper_fini(fb_helper); |
| 55 | 56 | |
| 56 | 57 | drm_client_buffer_vunmap(fb_helper->buffer); |
| @@ -89,25 +89,19 @@ static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, |
| 91 | 91 | const struct intel_connector *connector, |
| 92 | − bool ssc, bool dsc, int bpp_x16) | |
| 92 | + bool ssc, int dsc_slice_count, int bpp_x16) | |
| 93 | 93 | { |
| 94 | 94 | const struct drm_display_mode *adjusted_mode = |
| 95 | 95 | &crtc_state->hw.adjusted_mode; |
| 96 | 96 | unsigned long flags = DRM_DP_BW_OVERHEAD_MST; |
| 97 | − int dsc_slice_count = 0; | |
| 98 | 97 | int overhead; |
| 99 | 98 | |
| 100 | 99 | flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0; |
| 101 | 100 | flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0; |
| 102 | 101 | flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; |
| 103 | 102 | |
| 104 | − if (dsc) { | |
| 103 | + if (dsc_slice_count) | |
| 105 | 104 | flags |= DRM_DP_BW_OVERHEAD_DSC; |
| 106 | − dsc_slice_count = intel_dp_dsc_get_slice_count(connector, | |
| 107 | − adjusted_mode->clock, | |
| 108 | − adjusted_mode->hdisplay, | |
| 109 | − crtc_state->joiner_pipes); | |
| 110 | − } | |
| 111 | 105 | |
| 112 | 106 | overhead = drm_dp_bw_overhead(crtc_state->lane_count, |
| 113 | 107 | adjusted_mode->hdisplay, |
| @@ -153,6 +147,19 @@ static int intel_dp_mst_calc_pbn(int pixel_clock, int bpp_x16, int bw_overhead) · 39 unmodified lines | ||
| 153 | 147 | return DIV_ROUND_UP(effective_data_rate * 64, 54 * 1000); |
| 154 | 148 | } |
| 155 | 149 | |
| 150 | +static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connector, | |
| 151 | + const struct intel_crtc_state *crtc_state) | |
| 152 | +{ | |
| 153 | + const struct drm_display_mode *adjusted_mode = | |
| 154 | + &crtc_state->hw.adjusted_mode; | |
| 155 | + int num_joined_pipes = crtc_state->joiner_pipes; | |
| 156 | + | |
| 157 | + return intel_dp_dsc_get_slice_count(connector, | |
| 158 | + adjusted_mode->clock, | |
| 159 | + adjusted_mode->hdisplay, | |
| 160 | + num_joined_pipes); | |
| 161 | +} | |
| 162 | + | |
| 156 | 163 | static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, |
| 157 | 164 | struct intel_crtc_state *crtc_state, |
| 158 | 165 | int max_bpp, |
| @@ -172,6 +179,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, · 13 unmodified lines | ||
| 172 | 179 | const struct drm_display_mode *adjusted_mode = |
| 173 | 180 | &crtc_state->hw.adjusted_mode; |
| 174 | 181 | int bpp, slots = -EINVAL; |
| 182 | + int dsc_slice_count = 0; | |
| 175 | 183 | int max_dpt_bpp; |
| 176 | 184 | int ret = 0; |
| 177 | 185 | |
| @@ -203,6 +211,15 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, · 25 unmodified lines | ||
| 203 | 211 | drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n", |
| 204 | 212 | min_bpp, max_bpp); |
| 205 | 213 | |
| 214 | + if (dsc) { | |
| 215 | + dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state); | |
| 216 | + if (!dsc_slice_count) { | |
| 217 | + drm_dbg_kms(&i915->drm, "Can't get valid DSC slice count\n"); | |
| 218 | + | |
| 219 | + return -ENOSPC; | |
| 220 | + } | |
| 221 | + } | |
| 222 | + | |
| 206 | 223 | for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { |
| 207 | 224 | int local_bw_overhead; |
| 208 | 225 | int remote_bw_overhead; |
| @@ -216,9 +233,9 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, · 7 unmodified lines | ||
| 216 | 233 | intel_dp_output_bpp(crtc_state->output_format, bpp)); |
| 217 | 234 | |
| 218 | 235 | local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, |
| 219 | − false, dsc, link_bpp_x16); | |
| 236 | + false, dsc_slice_count, link_bpp_x16); | |
| 220 | 237 | remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, |
| 221 | − true, dsc, link_bpp_x16); | |
| 238 | + true, dsc_slice_count, link_bpp_x16); | |
| 222 | 239 | |
| 223 | 240 | intel_dp_mst_compute_m_n(crtc_state, connector, |
| 224 | 241 | local_bw_overhead, |
| @@ -449,6 +466,9 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, · 224 unmodified lines | ||
| 449 | 466 | if (mode_hblank_period_ns(adjusted_mode) > hblank_limit) |
| 450 | 467 | return false; |
| 451 | 468 | |
| 469 | + if (!intel_dp_mst_dsc_get_slice_count(connector, crtc_state)) | |
| 470 | + return false; | |
| 471 | + | |
| 452 | 472 | return true; |
| 453 | 473 | } |
| 454 | 474 | |
| @@ -438,6 +438,19 @@ bool intel_fb_needs_64k_phys(u64 modifier) · 437 unmodified lines | ||
| 438 | 438 | INTEL_PLANE_CAP_NEED64K_PHYS); |
| 439 | 439 | } |
| 440 | 440 | |
| 441 | +/** | |
| 442 | + * intel_fb_is_tile4_modifier: Check if a modifier is a tile4 modifier type | |
| 443 | + * @modifier: Modifier to check | |
| 444 | + * | |
| 445 | + * Returns: | |
| 446 | + * Returns %true if @modifier is a tile4 modifier. | |
| 447 | + */ | |
| 448 | +bool intel_fb_is_tile4_modifier(u64 modifier) | |
| 449 | +{ | |
| 450 | + return plane_caps_contain_any(lookup_modifier(modifier)->plane_caps, | |
| 451 | + INTEL_PLANE_CAP_TILING_4); | |
| 452 | +} | |
| 453 | + | |
| 441 | 454 | static bool check_modifier_display_ver_range(const struct intel_modifier_desc *md, |
| 442 | 455 | u8 display_ver_from, u8 display_ver_until) |
| 443 | 456 | { |
| @@ -35,6 +35,7 @@ bool intel_fb_is_ccs_modifier(u64 modifier); · 34 unmodified lines | ||
| 35 | 35 | bool intel_fb_is_rc_ccs_cc_modifier(u64 modifier); |
| 36 | 36 | bool intel_fb_is_mc_ccs_modifier(u64 modifier); |
| 37 | 37 | bool intel_fb_needs_64k_phys(u64 modifier); |
| 38 | +bool intel_fb_is_tile4_modifier(u64 modifier); | |
| 38 | 39 | |
| 39 | 40 | bool intel_fb_is_ccs_aux_plane(const struct drm_framebuffer *fb, int color_plane); |
| 40 | 41 | int intel_fb_rc_ccs_cc_plane(const struct drm_framebuffer *fb); |
| @@ -1094,7 +1094,8 @@ static void intel_hdcp_update_value(struct intel_connector *connector, · 1093 unmodified lines | ||
| 1094 | 1094 | hdcp->value = value; |
| 1095 | 1095 | if (update_property) { |
| 1096 | 1096 | drm_connector_get(&connector->base); |
| 1097 | − queue_work(i915->unordered_wq, &hdcp->prop_work); | |
| 1097 | + if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) | |
| 1098 | + drm_connector_put(&connector->base); | |
| 1098 | 1099 | } |
| 1099 | 1100 | } |
| 1100 | 1101 | |
| @@ -2524,7 +2525,8 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, · 1423 unmodified lines | ||
| 2524 | 2525 | mutex_lock(&hdcp->mutex); |
| 2525 | 2526 | hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; |
| 2526 | 2527 | drm_connector_get(&connector->base); |
| 2527 | − queue_work(i915->unordered_wq, &hdcp->prop_work); | |
| 2528 | + if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) | |
| 2529 | + drm_connector_put(&connector->base); | |
| 2528 | 2530 | mutex_unlock(&hdcp->mutex); |
| 2529 | 2531 | } |
| 2530 | 2532 | |
| @@ -2541,7 +2543,9 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, · 10 unmodified lines | ||
| 2541 | 2543 | */ |
| 2542 | 2544 | if (!desired_and_not_enabled && !content_protection_type_changed) { |
| 2543 | 2545 | drm_connector_get(&connector->base); |
| 2544 | − queue_work(i915->unordered_wq, &hdcp->prop_work); | |
| 2546 | + if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) | |
| 2547 | + drm_connector_put(&connector->base); | |
| 2548 | + | |
| 2545 | 2549 | } |
| 2546 | 2550 | } |
| 2547 | 2551 | |
| @@ -1591,6 +1591,17 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, · 1590 unmodified lines | ||
| 1591 | 1591 | return -EINVAL; |
| 1592 | 1592 | } |
| 1593 | 1593 | |
| 1594 | + /* | |
| 1595 | + * Display20 onward tile4 hflip is not supported | |
| 1596 | + */ | |
| 1597 | + if (rotation & DRM_MODE_REFLECT_X && | |
| 1598 | + intel_fb_is_tile4_modifier(fb->modifier) && | |
| 1599 | + DISPLAY_VER(dev_priv) >= 20) { | |
| 1600 | + drm_dbg_kms(&dev_priv->drm, | |
| 1601 | + "horizontal flip is not supported with tile4 surface formats\n"); | |
| 1602 | + return -EINVAL; | |
| 1603 | + } | |
| 1604 | + | |
| 1594 | 1605 | if (drm_rotation_90_or_270(rotation)) { |
| 1595 | 1606 | if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) { |
| 1596 | 1607 | drm_dbg_kms(&dev_priv->drm, |
| @@ -1131,7 +1131,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) · 1130 unmodified lines | ||
| 1131 | 1131 | GEM_WARN_ON(!i915_ttm_cpu_maps_iomem(bo->resource)); |
| 1132 | 1132 | } |
| 1133 | 1133 | |
| 1134 | − if (wakeref & CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND) | |
| 1134 | + if (wakeref && CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND != 0) | |
| 1135 | 1135 | intel_wakeref_auto(&to_i915(obj->base.dev)->runtime_pm.userfault_wakeref, |
| 1136 | 1136 | msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)); |
| 1137 | 1137 | |
| @@ -18,7 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <drm/drm_managed.h> |
| 19 | 19 | #include <drm/drm_module.h> |
| 20 | 20 | #include <drm/drm_pciids.h> |
| 21 | −#include <drm/drm_vblank.h> | |
| 22 | 21 | |
| 23 | 22 | #include "mgag200_drv.h" |
| 24 | 23 | |
| @@ -85,34 +84,6 @@ resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size) · 60 unmodified lines | ||
| 85 | 84 | return offset - 65536; |
| 86 | 85 | } |
| 87 | 86 | |
| 88 | −static irqreturn_t mgag200_irq_handler(int irq, void *arg) | |
| 89 | −{ | |
| 90 | − struct drm_device *dev = arg; | |
| 91 | − struct mga_device *mdev = to_mga_device(dev); | |
| 92 | − struct drm_crtc *crtc; | |
| 93 | − u32 status, ien; | |
| 94 | − | |
| 95 | − status = RREG32(MGAREG_STATUS); | |
| 96 | − | |
| 97 | − if (status & MGAREG_STATUS_VLINEPEN) { | |
| 98 | − ien = RREG32(MGAREG_IEN); | |
| 99 | − if (!(ien & MGAREG_IEN_VLINEIEN)) | |
| 100 | − goto out; | |
| 101 | − | |
| 102 | − crtc = drm_crtc_from_index(dev, 0); | |
| 103 | − if (WARN_ON_ONCE(!crtc)) | |
| 104 | − goto out; | |
| 105 | − drm_crtc_handle_vblank(crtc); | |
| 106 | − | |
| 107 | − WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR); | |
| 108 | − | |
| 109 | − return IRQ_HANDLED; | |
| 110 | − } | |
| 111 | − | |
| 112 | −out: | |
| 113 | − return IRQ_NONE; | |
| 114 | −} | |
| 115 | − | |
| 116 | 87 | /* |
| 117 | 88 | * DRM driver |
| 118 | 89 | */ |
| @@ -196,7 +167,6 @@ int mgag200_device_init(struct mga_device *mdev, · 77 unmodified lines | ||
| 196 | 167 | const struct mgag200_device_funcs *funcs) |
| 197 | 168 | { |
| 198 | 169 | struct drm_device *dev = &mdev->base; |
| 199 | − struct pci_dev *pdev = to_pci_dev(dev->dev); | |
| 200 | 170 | u8 crtcext3, misc; |
| 201 | 171 | int ret; |
| 202 | 172 | |
| @@ -223,14 +193,6 @@ int mgag200_device_init(struct mga_device *mdev, · 20 unmodified lines | ||
| 223 | 193 | mutex_unlock(&mdev->rmmio_lock); |
| 224 | 194 | |
| 225 | 195 | WREG32(MGAREG_IEN, 0); |
| 226 | − WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR); | |
| 227 | − | |
| 228 | − ret = devm_request_irq(&pdev->dev, pdev->irq, mgag200_irq_handler, IRQF_SHARED, | |
| 229 | − dev->driver->name, dev); | |
| 230 | − if (ret) { | |
| 231 | − drm_err(dev, "Failed to acquire interrupt, error %d\n", ret); | |
| 232 | − return ret; | |
| 233 | − } | |
| 234 | 196 | |
| 235 | 197 | return 0; |
| 236 | 198 | } |
| @@ -391,24 +391,17 @@ int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_st · 390 unmodified lines | ||
| 391 | 391 | void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 392 | 392 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 393 | 393 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 394 | −bool mgag200_crtc_helper_get_scanout_position(struct drm_crtc *crtc, bool in_vblank_irq, | |
| 395 | − int *vpos, int *hpos, | |
| 396 | − ktime_t *stime, ktime_t *etime, | |
| 397 | − const struct drm_display_mode *mode); | |
| 398 | 394 | |
| 399 | 395 | #define MGAG200_CRTC_HELPER_FUNCS \ |
| 400 | 396 | .mode_valid = mgag200_crtc_helper_mode_valid, \ |
| 401 | 397 | .atomic_check = mgag200_crtc_helper_atomic_check, \ |
| 402 | 398 | .atomic_flush = mgag200_crtc_helper_atomic_flush, \ |
| 403 | 399 | .atomic_enable = mgag200_crtc_helper_atomic_enable, \ |
| 404 | − .atomic_disable = mgag200_crtc_helper_atomic_disable, \ | |
| 405 | − .get_scanout_position = mgag200_crtc_helper_get_scanout_position | |
| 400 | + .atomic_disable = mgag200_crtc_helper_atomic_disable | |
| 406 | 401 | |
| 407 | 402 | void mgag200_crtc_reset(struct drm_crtc *crtc); |
| 408 | 403 | struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc); |
| 409 | 404 | void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state); |
| 410 | −int mgag200_crtc_enable_vblank(struct drm_crtc *crtc); | |
| 411 | −void mgag200_crtc_disable_vblank(struct drm_crtc *crtc); | |
| 412 | 405 | |
| 413 | 406 | #define MGAG200_CRTC_FUNCS \ |
| 414 | 407 | .reset = mgag200_crtc_reset, \ |
| @@ -416,10 +409,7 @@ void mgag200_crtc_disable_vblank(struct drm_crtc *crtc); · 1 unmodified line | ||
| 416 | 409 | .set_config = drm_atomic_helper_set_config, \ |
| 417 | 410 | .page_flip = drm_atomic_helper_page_flip, \ |
| 418 | 411 | .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \ |
| 419 | − .atomic_destroy_state = mgag200_crtc_atomic_destroy_state, \ | |
| 420 | − .enable_vblank = mgag200_crtc_enable_vblank, \ | |
| 421 | − .disable_vblank = mgag200_crtc_disable_vblank, \ | |
| 422 | − .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp | |
| 412 | + .atomic_destroy_state = mgag200_crtc_atomic_destroy_state | |
| 423 | 413 | |
| 424 | 414 | void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode, |
| 425 | 415 | bool set_vidrst); |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -404,9 +403,5 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct · 389 unmodified lines | ||
| 404 | 403 | drm_mode_config_reset(dev); |
| 405 | 404 | drm_kms_helper_poll_init(dev); |
| 406 | 405 | |
| 407 | − ret = drm_vblank_init(dev, 1); | |
| 408 | − if (ret) | |
| 409 | − return ERR_PTR(ret); | |
| 410 | − | |
| 411 | 406 | return mdev; |
| 412 | 407 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -276,9 +275,5 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru · 261 unmodified lines | ||
| 276 | 275 | drm_mode_config_reset(dev); |
| 277 | 276 | drm_kms_helper_poll_init(dev); |
| 278 | 277 | |
| 279 | − ret = drm_vblank_init(dev, 1); | |
| 280 | − if (ret) | |
| 281 | − return ERR_PTR(ret); | |
| 282 | − | |
| 283 | 278 | return mdev; |
| 284 | 279 | } |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <drm/drm_drv.h> |
| 8 | 8 | #include <drm/drm_gem_atomic_helper.h> |
| 9 | 9 | #include <drm/drm_probe_helper.h> |
| 10 | −#include <drm/drm_vblank.h> | |
| 11 | 10 | |
| 12 | 11 | #include "mgag200_drv.h" |
| 13 | 12 | |
| @@ -181,9 +180,5 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, · 167 unmodified lines | ||
| 181 | 180 | drm_mode_config_reset(dev); |
| 182 | 181 | drm_kms_helper_poll_init(dev); |
| 183 | 182 | |
| 184 | − ret = drm_vblank_init(dev, 1); | |
| 185 | − if (ret) | |
| 186 | − return ERR_PTR(ret); | |
| 187 | − | |
| 188 | 183 | return mdev; |
| 189 | 184 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -206,8 +205,6 @@ static void mgag200_g200er_crtc_helper_atomic_enable(struct drm_crtc *crtc, · 191 unmodified lines | ||
| 206 | 205 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 207 | 206 | |
| 208 | 207 | mgag200_enable_display(mdev); |
| 209 | − | |
| 210 | − drm_crtc_vblank_on(crtc); | |
| 211 | 208 | } |
| 212 | 209 | |
| 213 | 210 | static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = { |
| @@ -215,8 +212,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = { · 1 unmodified line | ||
| 215 | 212 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 216 | 213 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 217 | 214 | .atomic_enable = mgag200_g200er_crtc_helper_atomic_enable, |
| 218 | − .atomic_disable = mgag200_crtc_helper_atomic_disable, | |
| 219 | − .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | |
| 215 | + .atomic_disable = mgag200_crtc_helper_atomic_disable | |
| 220 | 216 | }; |
| 221 | 217 | |
| 222 | 218 | static const struct drm_crtc_funcs mgag200_g200er_crtc_funcs = { |
| @@ -312,9 +308,5 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru · 89 unmodified lines | ||
| 312 | 308 | drm_mode_config_reset(dev); |
| 313 | 309 | drm_kms_helper_poll_init(dev); |
| 314 | 310 | |
| 315 | − ret = drm_vblank_init(dev, 1); | |
| 316 | − if (ret) | |
| 317 | − return ERR_PTR(ret); | |
| 318 | − | |
| 319 | 311 | return mdev; |
| 320 | 312 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -207,8 +206,6 @@ static void mgag200_g200ev_crtc_helper_atomic_enable(struct drm_crtc *crtc, · 192 unmodified lines | ||
| 207 | 206 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 208 | 207 | |
| 209 | 208 | mgag200_enable_display(mdev); |
| 210 | − | |
| 211 | − drm_crtc_vblank_on(crtc); | |
| 212 | 209 | } |
| 213 | 210 | |
| 214 | 211 | static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = { |
| @@ -216,8 +213,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = { · 1 unmodified line | ||
| 216 | 213 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 217 | 214 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 218 | 215 | .atomic_enable = mgag200_g200ev_crtc_helper_atomic_enable, |
| 219 | − .atomic_disable = mgag200_crtc_helper_atomic_disable, | |
| 220 | − .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | |
| 216 | + .atomic_disable = mgag200_crtc_helper_atomic_disable | |
| 221 | 217 | }; |
| 222 | 218 | |
| 223 | 219 | static const struct drm_crtc_funcs mgag200_g200ev_crtc_funcs = { |
| @@ -317,9 +313,5 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru · 93 unmodified lines | ||
| 317 | 313 | drm_mode_config_reset(dev); |
| 318 | 314 | drm_kms_helper_poll_init(dev); |
| 319 | 315 | |
| 320 | − ret = drm_vblank_init(dev, 1); | |
| 321 | − if (ret) | |
| 322 | − return ERR_PTR(ret); | |
| 323 | − | |
| 324 | 316 | return mdev; |
| 325 | 317 | } |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <drm/drm_drv.h> |
| 8 | 8 | #include <drm/drm_gem_atomic_helper.h> |
| 9 | 9 | #include <drm/drm_probe_helper.h> |
| 10 | −#include <drm/drm_vblank.h> | |
| 11 | 10 | |
| 12 | 11 | #include "mgag200_drv.h" |
| 13 | 12 | |
| @@ -199,9 +198,5 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, · 185 unmodified lines | ||
| 199 | 198 | drm_mode_config_reset(dev); |
| 200 | 199 | drm_kms_helper_poll_init(dev); |
| 201 | 200 | |
| 202 | − ret = drm_vblank_init(dev, 1); | |
| 203 | − if (ret) | |
| 204 | − return ERR_PTR(ret); | |
| 205 | − | |
| 206 | 201 | return mdev; |
| 207 | 202 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -338,8 +337,6 @@ static void mgag200_g200se_crtc_helper_atomic_enable(struct drm_crtc *crtc, · 323 unmodified lines | ||
| 338 | 337 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 339 | 338 | |
| 340 | 339 | mgag200_enable_display(mdev); |
| 341 | − | |
| 342 | − drm_crtc_vblank_on(crtc); | |
| 343 | 340 | } |
| 344 | 341 | |
| 345 | 342 | static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = { |
| @@ -347,8 +344,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = { · 1 unmodified line | ||
| 347 | 344 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 348 | 345 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 349 | 346 | .atomic_enable = mgag200_g200se_crtc_helper_atomic_enable, |
| 350 | − .atomic_disable = mgag200_crtc_helper_atomic_disable, | |
| 351 | − .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | |
| 347 | + .atomic_disable = mgag200_crtc_helper_atomic_disable | |
| 352 | 348 | }; |
| 353 | 349 | |
| 354 | 350 | static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = { |
| @@ -517,9 +513,5 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru · 162 unmodified lines | ||
| 517 | 513 | drm_mode_config_reset(dev); |
| 518 | 514 | drm_kms_helper_poll_init(dev); |
| 519 | 515 | |
| 520 | − ret = drm_vblank_init(dev, 1); | |
| 521 | − if (ret) | |
| 522 | − return ERR_PTR(ret); | |
| 523 | − | |
| 524 | 516 | return mdev; |
| 525 | 517 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -323,9 +322,5 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru · 308 unmodified lines | ||
| 323 | 322 | drm_mode_config_reset(dev); |
| 324 | 323 | drm_kms_helper_poll_init(dev); |
| 325 | 324 | |
| 326 | − ret = drm_vblank_init(dev, 1); | |
| 327 | − if (ret) | |
| 328 | − return ERR_PTR(ret); | |
| 329 | − | |
| 330 | 325 | return mdev; |
| 331 | 326 | } |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <drm/drm_gem_framebuffer_helper.h> |
| 23 | 23 | #include <drm/drm_panic.h> |
| 24 | 24 | #include <drm/drm_print.h> |
| 25 | −#include <drm/drm_vblank.h> | |
| 26 | 25 | |
| 27 | 26 | #include "mgag200_ddc.h" |
| 28 | 27 | #include "mgag200_drv.h" |
| @@ -227,14 +226,7 @@ void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mod · 198 unmodified lines | ||
| 227 | 226 | vblkstr = mode->crtc_vblank_start; |
| 228 | 227 | vblkend = vtotal + 1; |
| 229 | 228 | |
| 230 | − /* | |
| 231 | − * There's no VBLANK interrupt on Matrox chipsets, so we use | |
| 232 | − * the VLINE interrupt instead. It triggers when the current | |
| 233 | − * <linecomp> has been reached. For VBLANK, this is the first | |
| 234 | − * non-visible line at the bottom of the screen. Therefore, | |
| 235 | − * keep <linecomp> in sync with <vblkstr>. | |
| 236 | − */ | |
| 237 | − linecomp = vblkstr; | |
| 229 | + linecomp = vdispend; | |
| 238 | 230 | |
| 239 | 231 | misc = RREG8(MGA_MISC_IN); |
| 240 | 232 | |
| @@ -645,8 +637,6 @@ void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_s · 404 unmodified lines | ||
| 645 | 637 | struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); |
| 646 | 638 | struct drm_device *dev = crtc->dev; |
| 647 | 639 | struct mga_device *mdev = to_mga_device(dev); |
| 648 | − struct drm_pending_vblank_event *event; | |
| 649 | − unsigned long flags; | |
| 650 | 640 | |
| 651 | 641 | if (crtc_state->enable && crtc_state->color_mgmt_changed) { |
| 652 | 642 | const struct drm_format_info *format = mgag200_crtc_state->format; |
| @@ -656,18 +646,6 @@ void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_s · 3 unmodified lines | ||
| 656 | 646 | else |
| 657 | 647 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 658 | 648 | } |
| 659 | − | |
| 660 | − event = crtc->state->event; | |
| 661 | − if (event) { | |
| 662 | − crtc->state->event = NULL; | |
| 663 | − | |
| 664 | − spin_lock_irqsave(&dev->event_lock, flags); | |
| 665 | − if (drm_crtc_vblank_get(crtc) != 0) | |
| 666 | − drm_crtc_send_vblank_event(crtc, event); | |
| 667 | − else | |
| 668 | − drm_crtc_arm_vblank_event(crtc, event); | |
| 669 | − spin_unlock_irqrestore(&dev->event_lock, flags); | |
| 670 | − } | |
| 671 | 649 | } |
| 672 | 650 | |
| 673 | 651 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) |
| @@ -692,44 +670,15 @@ void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_ · 18 unmodified lines | ||
| 692 | 670 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 693 | 671 | |
| 694 | 672 | mgag200_enable_display(mdev); |
| 695 | − | |
| 696 | − drm_crtc_vblank_on(crtc); | |
| 697 | 673 | } |
| 698 | 674 | |
| 699 | 675 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) |
| 700 | 676 | { |
| 701 | 677 | struct mga_device *mdev = to_mga_device(crtc->dev); |
| 702 | 678 | |
| 703 | − drm_crtc_vblank_off(crtc); | |
| 704 | − | |
| 705 | 679 | mgag200_disable_display(mdev); |
| 706 | 680 | } |
| 707 | 681 | |
| 708 | −bool mgag200_crtc_helper_get_scanout_position(struct drm_crtc *crtc, bool in_vblank_irq, | |
| 709 | − int *vpos, int *hpos, | |
| 710 | − ktime_t *stime, ktime_t *etime, | |
| 711 | − const struct drm_display_mode *mode) | |
| 712 | −{ | |
| 713 | − struct mga_device *mdev = to_mga_device(crtc->dev); | |
| 714 | − u32 vcount; | |
| 715 | − | |
| 716 | − if (stime) | |
| 717 | − *stime = ktime_get(); | |
| 718 | − | |
| 719 | − if (vpos) { | |
| 720 | − vcount = RREG32(MGAREG_VCOUNT); | |
| 721 | − *vpos = vcount & GENMASK(11, 0); | |
| 722 | − } | |
| 723 | − | |
| 724 | − if (hpos) | |
| 725 | − *hpos = mode->htotal >> 1; // near middle of scanline on average | |
| 726 | − | |
| 727 | − if (etime) | |
| 728 | − *etime = ktime_get(); | |
| 729 | − | |
| 730 | − return true; | |
| 731 | −} | |
| 732 | − | |
| 733 | 682 | void mgag200_crtc_reset(struct drm_crtc *crtc) |
| 734 | 683 | { |
| 735 | 684 | struct mgag200_crtc_state *mgag200_crtc_state; |
| @@ -774,30 +723,6 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st · 38 unmodified lines | ||
| 774 | 723 | kfree(mgag200_crtc_state); |
| 775 | 724 | } |
| 776 | 725 | |
| 777 | −int mgag200_crtc_enable_vblank(struct drm_crtc *crtc) | |
| 778 | −{ | |
| 779 | − struct mga_device *mdev = to_mga_device(crtc->dev); | |
| 780 | − u32 ien; | |
| 781 | − | |
| 782 | − WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR); | |
| 783 | − | |
| 784 | − ien = RREG32(MGAREG_IEN); | |
| 785 | − ien |= MGAREG_IEN_VLINEIEN; | |
| 786 | − WREG32(MGAREG_IEN, ien); | |
| 787 | − | |
| 788 | − return 0; | |
| 789 | −} | |
| 790 | − | |
| 791 | −void mgag200_crtc_disable_vblank(struct drm_crtc *crtc) | |
| 792 | −{ | |
| 793 | − struct mga_device *mdev = to_mga_device(crtc->dev); | |
| 794 | − u32 ien; | |
| 795 | − | |
| 796 | − ien = RREG32(MGAREG_IEN); | |
| 797 | − ien &= ~(MGAREG_IEN_VLINEIEN); | |
| 798 | − WREG32(MGAREG_IEN, ien); | |
| 799 | −} | |
| 800 | − | |
| 801 | 726 | /* |
| 802 | 727 | * Mode config |
| 803 | 728 | */ |
| @@ -101,9 +101,10 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter, · 100 unmodified lines | ||
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, |
| 104 | − struct msm_ringbuffer *ring, struct msm_file_private *ctx) | |
| 104 | + struct msm_ringbuffer *ring, struct msm_gem_submit *submit) | |
| 105 | 105 | { |
| 106 | 106 | bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1; |
| 107 | + struct msm_file_private *ctx = submit->queue->ctx; | |
| 107 | 108 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; |
| 108 | 109 | phys_addr_t ttbr; |
| 109 | 110 | u32 asid; |
| @@ -115,6 +116,15 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, · 5 unmodified lines | ||
| 115 | 116 | if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) |
| 116 | 117 | return; |
| 117 | 118 | |
| 119 | + if (adreno_gpu->info->family >= ADRENO_7XX_GEN1) { | |
| 120 | + /* Wait for previous submit to complete before continuing: */ | |
| 121 | + OUT_PKT7(ring, CP_WAIT_TIMESTAMP, 4); | |
| 122 | + OUT_RING(ring, 0); | |
| 123 | + OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence))); | |
| 124 | + OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence))); | |
| 125 | + OUT_RING(ring, submit->seqno - 1); | |
| 126 | + } | |
| 127 | + | |
| 118 | 128 | if (!sysprof) { |
| 119 | 129 | if (!adreno_is_a7xx(adreno_gpu)) { |
| 120 | 130 | /* Turn off protected mode to write to special registers */ |
| @@ -193,7 +203,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) · 72 unmodified lines | ||
| 193 | 203 | struct msm_ringbuffer *ring = submit->ring; |
| 194 | 204 | unsigned int i, ibs = 0; |
| 195 | 205 | |
| 196 | − a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx); | |
| 206 | + a6xx_set_pagetable(a6xx_gpu, ring, submit); | |
| 197 | 207 | |
| 198 | 208 | get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0), |
| 199 | 209 | rbmemptr_stats(ring, index, cpcycles_start)); |
| @@ -283,7 +293,7 @@ static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) · 83 unmodified lines | ||
| 283 | 293 | OUT_PKT7(ring, CP_THREAD_CONTROL, 1); |
| 284 | 294 | OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR); |
| 285 | 295 | |
| 286 | − a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx); | |
| 296 | + a6xx_set_pagetable(a6xx_gpu, ring, submit); | |
| 287 | 297 | |
| 288 | 298 | get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0), |
| 289 | 299 | rbmemptr_stats(ring, index, cpcycles_start)); |
| @@ -711,12 +711,13 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc) · 710 unmodified lines | ||
| 711 | 711 | _dpu_crtc_complete_flip(crtc); |
| 712 | 712 | } |
| 713 | 713 | |
| 714 | −static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, | |
| 714 | +static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc, | |
| 715 | 715 | struct drm_crtc_state *state) |
| 716 | 716 | { |
| 717 | 717 | struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); |
| 718 | 718 | struct drm_display_mode *adj_mode = &state->adjusted_mode; |
| 719 | 719 | u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers; |
| 720 | + struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); | |
| 720 | 721 | int i; |
| 721 | 722 | |
| 722 | 723 | for (i = 0; i < cstate->num_mixers; i++) { |
| @@ -727,7 +728,12 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, · 4 unmodified lines | ||
| 727 | 728 | r->y2 = adj_mode->vdisplay; |
| 728 | 729 | |
| 729 | 730 | trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r); |
| 731 | + | |
| 732 | + if (drm_rect_width(r) > dpu_kms->catalog->caps->max_mixer_width) | |
| 733 | + return -E2BIG; | |
| 730 | 734 | } |
| 735 | + | |
| 736 | + return 0; | |
| 731 | 737 | } |
| 732 | 738 | |
| 733 | 739 | static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state, |
| @@ -803,7 +809,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, · 69 unmodified lines | ||
| 803 | 809 | |
| 804 | 810 | DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id); |
| 805 | 811 | |
| 806 | − _dpu_crtc_setup_lm_bounds(crtc, crtc->state); | |
| 812 | + _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc->state); | |
| 807 | 813 | |
| 808 | 814 | /* encoder will trigger pending mask now */ |
| 809 | 815 | drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) |
| @@ -1091,9 +1097,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, · 281 unmodified lines | ||
| 1091 | 1097 | |
| 1092 | 1098 | dpu_core_perf_crtc_update(crtc, 0); |
| 1093 | 1099 | |
| 1094 | − memset(cstate->mixers, 0, sizeof(cstate->mixers)); | |
| 1095 | − cstate->num_mixers = 0; | |
| 1096 | − | |
| 1097 | 1100 | /* disable clk & bw control until clk & bw properties are set */ |
| 1098 | 1101 | cstate->bw_control = false; |
| 1099 | 1102 | cstate->bw_split_vote = false; |
| @@ -1192,8 +1195,11 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, · 92 unmodified lines | ||
| 1192 | 1195 | if (crtc_state->active_changed) |
| 1193 | 1196 | crtc_state->mode_changed = true; |
| 1194 | 1197 | |
| 1195 | − if (cstate->num_mixers) | |
| 1196 | − _dpu_crtc_setup_lm_bounds(crtc, crtc_state); | |
| 1198 | + if (cstate->num_mixers) { | |
| 1199 | + rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state); | |
| 1200 | + if (rc) | |
| 1201 | + return rc; | |
| 1202 | + } | |
| 1197 | 1203 | |
| 1198 | 1204 | /* FIXME: move this to dpu_plane_atomic_check? */ |
| 1199 | 1205 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { |
| @@ -624,6 +624,40 @@ static struct msm_display_topology dpu_encoder_get_topology( · 623 unmodified lines | ||
| 624 | 624 | return topology; |
| 625 | 625 | } |
| 626 | 626 | |
| 627 | +static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms, | |
| 628 | + struct drm_encoder *drm_enc, | |
| 629 | + struct dpu_global_state *global_state, | |
| 630 | + struct drm_crtc_state *crtc_state) | |
| 631 | +{ | |
| 632 | + struct dpu_crtc_state *cstate; | |
| 633 | + struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; | |
| 634 | + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; | |
| 635 | + struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC]; | |
| 636 | + int num_lm, num_ctl, num_dspp, i; | |
| 637 | + | |
| 638 | + cstate = to_dpu_crtc_state(crtc_state); | |
| 639 | + | |
| 640 | + memset(cstate->mixers, 0, sizeof(cstate->mixers)); | |
| 641 | + | |
| 642 | + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 643 | + drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); | |
| 644 | + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 645 | + drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); | |
| 646 | + num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 647 | + drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp, | |
| 648 | + ARRAY_SIZE(hw_dspp)); | |
| 649 | + | |
| 650 | + for (i = 0; i < num_lm; i++) { | |
| 651 | + int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); | |
| 652 | + | |
| 653 | + cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); | |
| 654 | + cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); | |
| 655 | + cstate->mixers[i].hw_dspp = i < num_dspp ? to_dpu_hw_dspp(hw_dspp[i]) : NULL; | |
| 656 | + } | |
| 657 | + | |
| 658 | + cstate->num_mixers = num_lm; | |
| 659 | +} | |
| 660 | + | |
| 627 | 661 | static int dpu_encoder_virt_atomic_check( |
| 628 | 662 | struct drm_encoder *drm_enc, |
| 629 | 663 | struct drm_crtc_state *crtc_state, |
| @@ -692,6 +726,9 @@ static int dpu_encoder_virt_atomic_check( · 62 unmodified lines | ||
| 692 | 726 | if (!crtc_state->active_changed || crtc_state->enable) |
| 693 | 727 | ret = dpu_rm_reserve(&dpu_kms->rm, global_state, |
| 694 | 728 | drm_enc, crtc_state, topology); |
| 729 | + if (!ret) | |
| 730 | + dpu_encoder_assign_crtc_resources(dpu_kms, drm_enc, | |
| 731 | + global_state, crtc_state); | |
| 695 | 732 | } |
| 696 | 733 | |
| 697 | 734 | trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); |
| @@ -1093,14 +1130,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, · 395 unmodified lines | ||
| 1093 | 1130 | struct dpu_encoder_virt *dpu_enc; |
| 1094 | 1131 | struct msm_drm_private *priv; |
| 1095 | 1132 | struct dpu_kms *dpu_kms; |
| 1096 | − struct dpu_crtc_state *cstate; | |
| 1097 | 1133 | struct dpu_global_state *global_state; |
| 1098 | 1134 | struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; |
| 1099 | 1135 | struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; |
| 1100 | − struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; | |
| 1101 | − struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL }; | |
| 1102 | 1136 | struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC]; |
| 1103 | − int num_lm, num_ctl, num_pp, num_dsc; | |
| 1137 | + int num_ctl, num_pp, num_dsc; | |
| 1104 | 1138 | unsigned int dsc_mask = 0; |
| 1105 | 1139 | int i; |
| 1106 | 1140 | |
| @@ -1129,11 +1163,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, · 22 unmodified lines | ||
| 1129 | 1163 | ARRAY_SIZE(hw_pp)); |
| 1130 | 1164 | num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, |
| 1131 | 1165 | drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); |
| 1132 | − num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 1133 | − drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); | |
| 1134 | − dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 1135 | − drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp, | |
| 1136 | − ARRAY_SIZE(hw_dspp)); | |
| 1137 | 1166 | |
| 1138 | 1167 | for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) |
| 1139 | 1168 | dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) |
| @@ -1159,36 +1188,23 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, · 19 unmodified lines | ||
| 1159 | 1188 | dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL; |
| 1160 | 1189 | } |
| 1161 | 1190 | |
| 1162 | − cstate = to_dpu_crtc_state(crtc_state); | |
| 1163 | − | |
| 1164 | − for (i = 0; i < num_lm; i++) { | |
| 1165 | − int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); | |
| 1166 | − | |
| 1167 | − cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); | |
| 1168 | − cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); | |
| 1169 | − cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]); | |
| 1170 | − } | |
| 1171 | − | |
| 1172 | − cstate->num_mixers = num_lm; | |
| 1173 | − | |
| 1174 | 1191 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { |
| 1175 | 1192 | struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; |
| 1176 | 1193 | |
| 1177 | − if (!dpu_enc->hw_pp[i]) { | |
| 1194 | + phys->hw_pp = dpu_enc->hw_pp[i]; | |
| 1195 | + if (!phys->hw_pp) { | |
| 1178 | 1196 | DPU_ERROR_ENC(dpu_enc, |
| 1179 | 1197 | "no pp block assigned at idx: %d\n", i); |
| 1180 | 1198 | return; |
| 1181 | 1199 | } |
| 1182 | 1200 | |
| 1183 | − if (!hw_ctl[i]) { | |
| 1201 | + phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL; | |
| 1202 | + if (!phys->hw_ctl) { | |
| 1184 | 1203 | DPU_ERROR_ENC(dpu_enc, |
| 1185 | 1204 | "no ctl block assigned at idx: %d\n", i); |
| 1186 | 1205 | return; |
| 1187 | 1206 | } |
| 1188 | 1207 | |
| 1189 | − phys->hw_pp = dpu_enc->hw_pp[i]; | |
| 1190 | − phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); | |
| 1191 | − | |
| 1192 | 1208 | phys->cached_mode = crtc_state->adjusted_mode; |
| 1193 | 1209 | if (phys->ops.atomic_mode_set) |
| 1194 | 1210 | phys->ops.atomic_mode_set(phys, crtc_state, conn_state); |
| @@ -302,7 +302,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine( · 301 unmodified lines | ||
| 302 | 302 | intf_cfg.stream_sel = 0; /* Don't care value for video mode */ |
| 303 | 303 | intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); |
| 304 | 304 | intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); |
| 305 | − if (phys_enc->hw_pp->merge_3d) | |
| 305 | + if (intf_cfg.mode_3d && phys_enc->hw_pp->merge_3d) | |
| 306 | 306 | intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; |
| 307 | 307 | |
| 308 | 308 | spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); |
| @@ -440,10 +440,12 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) · 131 unmodified lines | ||
| 440 | 440 | struct dpu_hw_ctl *ctl; |
| 441 | 441 | const struct msm_format *fmt; |
| 442 | 442 | u32 fmt_fourcc; |
| 443 | + u32 mode_3d; | |
| 443 | 444 | |
| 444 | 445 | ctl = phys_enc->hw_ctl; |
| 445 | 446 | fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc); |
| 446 | 447 | fmt = mdp_get_format(&phys_enc->dpu_kms->base, fmt_fourcc, 0); |
| 448 | + mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); | |
| 447 | 449 | |
| 448 | 450 | DPU_DEBUG_VIDENC(phys_enc, "\n"); |
| 449 | 451 | |
| @@ -466,7 +468,8 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) · 16 unmodified lines | ||
| 466 | 468 | goto skip_flush; |
| 467 | 469 | |
| 468 | 470 | ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); |
| 469 | − if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d) | |
| 471 | + if (mode_3d && ctl->ops.update_pending_flush_merge_3d && | |
| 472 | + phys_enc->hw_pp->merge_3d) | |
| 470 | 473 | ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); |
| 471 | 474 | |
| 472 | 475 | if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm) |
| @@ -275,6 +275,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 274 unmodified lines | ||
| 275 | 275 | struct dpu_hw_pingpong *hw_pp; |
| 276 | 276 | struct dpu_hw_cdm *hw_cdm; |
| 277 | 277 | u32 pending_flush = 0; |
| 278 | + u32 mode_3d; | |
| 278 | 279 | |
| 279 | 280 | if (!phys_enc) |
| 280 | 281 | return; |
| @@ -283,6 +284,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 2 unmodified lines | ||
| 283 | 284 | hw_pp = phys_enc->hw_pp; |
| 284 | 285 | hw_ctl = phys_enc->hw_ctl; |
| 285 | 286 | hw_cdm = phys_enc->hw_cdm; |
| 287 | + mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); | |
| 286 | 288 | |
| 287 | 289 | DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); |
| 288 | 290 | |
| @@ -294,7 +296,8 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 5 unmodified lines | ||
| 294 | 296 | if (hw_ctl->ops.update_pending_flush_wb) |
| 295 | 297 | hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx); |
| 296 | 298 | |
| 297 | − if (hw_ctl->ops.update_pending_flush_merge_3d && hw_pp && hw_pp->merge_3d) | |
| 299 | + if (mode_3d && hw_ctl->ops.update_pending_flush_merge_3d && | |
| 300 | + hw_pp && hw_pp->merge_3d) | |
| 298 | 301 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, |
| 299 | 302 | hw_pp->merge_3d->idx); |
| 300 | 303 | |
| @@ -26,7 +26,7 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b · 25 unmodified lines | ||
| 26 | 26 | end_addr = base_addr + aligned_len; |
| 27 | 27 | |
| 28 | 28 | if (!(*reg)) |
| 29 | − *reg = kzalloc(len_padded, GFP_KERNEL); | |
| 29 | + *reg = kvzalloc(len_padded, GFP_KERNEL); | |
| 30 | 30 | |
| 31 | 31 | if (*reg) |
| 32 | 32 | dump_addr = *reg; |
| @@ -48,20 +48,21 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b · 15 unmodified lines | ||
| 48 | 48 | } |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | −static void msm_disp_state_print_regs(u32 **reg, u32 len, void __iomem *base_addr, | |
| 52 | − struct drm_printer *p) | |
| 51 | +static void msm_disp_state_print_regs(const u32 *dump_addr, u32 len, | |
| 52 | + void __iomem *base_addr, struct drm_printer *p) | |
| 53 | 53 | { |
| 54 | 54 | int i; |
| 55 | − u32 *dump_addr = NULL; | |
| 56 | 55 | void __iomem *addr; |
| 57 | 56 | u32 num_rows; |
| 58 | 57 | |
| 58 | + if (!dump_addr) { | |
| 59 | + drm_printf(p, "Registers not stored\n"); | |
| 60 | + return; | |
| 61 | + } | |
| 62 | + | |
| 59 | 63 | addr = base_addr; |
| 60 | 64 | num_rows = len / REG_DUMP_ALIGN; |
| 61 | 65 | |
| 62 | − if (*reg) | |
| 63 | − dump_addr = *reg; | |
| 64 | − | |
| 65 | 66 | for (i = 0; i < num_rows; i++) { |
| 66 | 67 | drm_printf(p, "0x%lx : %08x %08x %08x %08x\n", |
| 67 | 68 | (unsigned long)(addr - base_addr), |
| @@ -89,7 +90,7 @@ void msm_disp_state_print(struct msm_disp_state *state, struct drm_printer *p) · 21 unmodified lines | ||
| 89 | 90 | |
| 90 | 91 | list_for_each_entry_safe(block, tmp, &state->blocks, node) { |
| 91 | 92 | drm_printf(p, "====================%s================\n", block->name); |
| 92 | − msm_disp_state_print_regs(&block->state, block->size, block->base_addr, p); | |
| 93 | + msm_disp_state_print_regs(block->state, block->size, block->base_addr, p); | |
| 93 | 94 | } |
| 94 | 95 | |
| 95 | 96 | drm_printf(p, "===================dpu drm state================\n"); |
| @@ -161,7 +162,7 @@ void msm_disp_state_free(void *data) · 65 unmodified lines | ||
| 161 | 162 | |
| 162 | 163 | list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) { |
| 163 | 164 | list_del(&block->node); |
| 164 | − kfree(block->state); | |
| 165 | + kvfree(block->state); | |
| 165 | 166 | kfree(block); |
| 166 | 167 | } |
| 167 | 168 | |
| @@ -542,7 +542,7 @@ static unsigned long dsi_adjust_pclk_for_compression(const struct drm_display_mo · 541 unmodified lines | ||
| 542 | 542 | |
| 543 | 543 | int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay; |
| 544 | 544 | |
| 545 | − return new_htotal * mode->vtotal * drm_mode_vrefresh(mode); | |
| 545 | + return mult_frac(mode->clock * 1000u, new_htotal, mode->htotal); | |
| 546 | 546 | } |
| 547 | 547 | |
| 548 | 548 | static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, |
| @@ -550,7 +550,7 @@ static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, · 1 unmodified line | ||
| 550 | 550 | { |
| 551 | 551 | unsigned long pclk_rate; |
| 552 | 552 | |
| 553 | − pclk_rate = mode->clock * 1000; | |
| 553 | + pclk_rate = mode->clock * 1000u; | |
| 554 | 554 | |
| 555 | 555 | if (dsc) |
| 556 | 556 | pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc); |
| @@ -153,15 +153,6 @@ static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk) · 152 unmodified lines | ||
| 153 | 153 | return dividend - 1; |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | −static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk) | |
| 157 | −{ | |
| 158 | − u64 fdata = ((u64)pll_cmp) * ref_clk * 10; | |
| 159 | − | |
| 160 | − do_div(fdata, HDMI_PLL_CMP_CNT); | |
| 161 | − | |
| 162 | − return fdata; | |
| 163 | −} | |
| 164 | − | |
| 165 | 156 | #define HDMI_REF_CLOCK_HZ ((u64)19200000) |
| 166 | 157 | #define HDMI_MHZ_TO_HZ ((u64)1000000) |
| 167 | 158 | static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk) |
| @@ -210,7 +210,7 @@ struct nvkm_gsp { · 209 unmodified lines | ||
| 210 | 210 | } *rm; |
| 211 | 211 | |
| 212 | 212 | struct { |
| 213 | − struct mutex mutex;; | |
| 213 | + struct mutex mutex; | |
| 214 | 214 | struct idr idr; |
| 215 | 215 | } client_id; |
| 216 | 216 | |
| @@ -193,7 +193,7 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf) · 192 unmodified lines | ||
| 193 | 193 | if (!spage || !(src & MIGRATE_PFN_MIGRATE)) |
| 194 | 194 | goto done; |
| 195 | 195 | |
| 196 | − dpage = alloc_page_vma(GFP_HIGHUSER, vmf->vma, vmf->address); | |
| 196 | + dpage = alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vmf->vma, vmf->address); | |
| 197 | 197 | if (!dpage) |
| 198 | 198 | goto done; |
| 199 | 199 | |
| @@ -331,7 +331,7 @@ nouveau_accel_ce_init(struct nouveau_drm *drm) · 330 unmodified lines | ||
| 331 | 331 | return; |
| 332 | 332 | } |
| 333 | 333 | |
| 334 | − ret = nouveau_channel_new(&drm->client, false, runm, NvDmaFB, NvDmaTT, &drm->cechan); | |
| 334 | + ret = nouveau_channel_new(&drm->client, true, runm, NvDmaFB, NvDmaTT, &drm->cechan); | |
| 335 | 335 | if (ret) |
| 336 | 336 | NV_ERROR(drm, "failed to create ce channel, %d\n", ret); |
| 337 | 337 | } |
| @@ -298,7 +298,7 @@ static int ivo_t109nw41_init(struct hx83102 *ctx) · 297 unmodified lines | ||
| 298 | 298 | msleep(60); |
| 299 | 299 | |
| 300 | 300 | hx83102_enable_extended_cmds(&dsi_ctx, true); |
| 301 | − mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xed, 0xed, 0x0f, 0xcf, 0x42, | |
| 301 | + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xed, 0xed, 0x27, 0xe7, 0x52, | |
| 302 | 302 | 0xf5, 0x39, 0x36, 0x36, 0x36, 0x36, 0x32, 0x8b, 0x11, 0x65, 0x00, 0x88, |
| 303 | 303 | 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0xd6, 0x33); |
| 304 | 304 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x00, 0x47, 0xb0, 0x80, 0x00, 0x12, |
| @@ -343,11 +343,11 @@ static int ivo_t109nw41_init(struct hx83102 *ctx) · 38 unmodified lines | ||
| 343 | 343 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 344 | 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 345 | 345 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| 346 | − mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, | |
| 347 | − 0x12, 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, | |
| 348 | − 0x7a, 0x41, 0x50, 0x68, 0x73, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, 0x12, | |
| 349 | − 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, 0x7a, | |
| 350 | − 0x41, 0x50, 0x68, 0x73); | |
| 346 | + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, | |
| 347 | + 0x48, 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, | |
| 348 | + 0x9c, 0x4d, 0x56, 0x5d, 0x73, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, 0x48, | |
| 349 | + 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, 0x9c, | |
| 350 | + 0x4d, 0x56, 0x5d, 0x73); | |
| 351 | 351 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e, |
| 352 | 352 | 0x00, 0x4f, 0xa0, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0a, 0x02, |
| 353 | 353 | 0x02, 0x00, 0x33, 0x02, 0x04, 0x18, 0x01); |
| @@ -1383,6 +1383,7 @@ static const struct file_operations panthor_drm_driver_fops = { · 1382 unmodified lines | ||
| 1383 | 1383 | .read = drm_read, |
| 1384 | 1384 | .llseek = noop_llseek, |
| 1385 | 1385 | .mmap = panthor_mmap, |
| 1386 | + .fop_flags = FOP_UNSIGNED_OFFSET, | |
| 1386 | 1387 | }; |
| 1387 | 1388 | |
| 1388 | 1389 | #ifdef CONFIG_DEBUG_FS |
| @@ -1251,9 +1251,17 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx, · 1250 unmodified lines | ||
| 1251 | 1251 | goto err_cleanup; |
| 1252 | 1252 | } |
| 1253 | 1253 | |
| 1254 | + /* drm_gpuvm_bo_obtain_prealloc() will call drm_gpuvm_bo_put() on our | |
| 1255 | + * pre-allocated BO if the <BO,VM> association exists. Given we | |
| 1256 | + * only have one ref on preallocated_vm_bo, drm_gpuvm_bo_destroy() will | |
| 1257 | + * be called immediately, and we have to hold the VM resv lock when | |
| 1258 | + * calling this function. | |
| 1259 | + */ | |
| 1260 | + dma_resv_lock(panthor_vm_resv(vm), NULL); | |
| 1254 | 1261 | mutex_lock(&bo->gpuva_list_lock); |
| 1255 | 1262 | op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo); |
| 1256 | 1263 | mutex_unlock(&bo->gpuva_list_lock); |
| 1264 | + dma_resv_unlock(panthor_vm_resv(vm)); | |
| 1257 | 1265 | |
| 1258 | 1266 | /* If the a vm_bo for this <VM,BO> combination exists, it already |
| 1259 | 1267 | * retains a pin ref, and we can release the one we took earlier. |
| @@ -1103,7 +1103,13 @@ cs_slot_sync_queue_state_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs · 1102 unmodified lines | ||
| 1103 | 1103 | list_move_tail(&group->wait_node, |
| 1104 | 1104 | &group->ptdev->scheduler->groups.waiting); |
| 1105 | 1105 | } |
| 1106 | − group->blocked_queues |= BIT(cs_id); | |
| 1106 | + | |
| 1107 | + /* The queue is only blocked if there's no deferred operation | |
| 1108 | + * pending, which can be checked through the scoreboard status. | |
| 1109 | + */ | |
| 1110 | + if (!cs_iface->output->status_scoreboards) | |
| 1111 | + group->blocked_queues |= BIT(cs_id); | |
| 1112 | + | |
| 1107 | 1113 | queue->syncwait.gpu_va = cs_iface->output->status_wait_sync_ptr; |
| 1108 | 1114 | queue->syncwait.ref = cs_iface->output->status_wait_sync_value; |
| 1109 | 1115 | status_wait_cond = cs_iface->output->status_wait & CS_STATUS_WAIT_SYNC_COND_MASK; |
| @@ -2046,6 +2052,7 @@ static void · 936 unmodified lines | ||
| 2046 | 2052 | tick_ctx_cleanup(struct panthor_scheduler *sched, |
| 2047 | 2053 | struct panthor_sched_tick_ctx *ctx) |
| 2048 | 2054 | { |
| 2055 | + struct panthor_device *ptdev = sched->ptdev; | |
| 2049 | 2056 | struct panthor_group *group, *tmp; |
| 2050 | 2057 | u32 i; |
| 2051 | 2058 | |
| @@ -2054,7 +2061,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched, · 2 unmodified lines | ||
| 2054 | 2061 | /* If everything went fine, we should only have groups |
| 2055 | 2062 | * to be terminated in the old_groups lists. |
| 2056 | 2063 | */ |
| 2057 | − drm_WARN_ON(&group->ptdev->base, !ctx->csg_upd_failed_mask && | |
| 2064 | + drm_WARN_ON(&ptdev->base, !ctx->csg_upd_failed_mask && | |
| 2058 | 2065 | group_can_run(group)); |
| 2059 | 2066 | |
| 2060 | 2067 | if (!group_can_run(group)) { |
| @@ -2077,7 +2084,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched, · 16 unmodified lines | ||
| 2077 | 2084 | /* If everything went fine, the groups to schedule lists should |
| 2078 | 2085 | * be empty. |
| 2079 | 2086 | */ |
| 2080 | − drm_WARN_ON(&group->ptdev->base, | |
| 2087 | + drm_WARN_ON(&ptdev->base, | |
| 2081 | 2088 | !ctx->csg_upd_failed_mask && !list_empty(&ctx->groups[i])); |
| 2082 | 2089 | |
| 2083 | 2090 | list_for_each_entry_safe(group, tmp, &ctx->groups[i], run_node) { |
| @@ -3242,6 +3249,18 @@ int panthor_group_destroy(struct panthor_file *pfile, u32 group_handle) · 1158 unmodified lines | ||
| 3242 | 3249 | return 0; |
| 3243 | 3250 | } |
| 3244 | 3251 | |
| 3252 | +static struct panthor_group *group_from_handle(struct panthor_group_pool *pool, | |
| 3253 | + u32 group_handle) | |
| 3254 | +{ | |
| 3255 | + struct panthor_group *group; | |
| 3256 | + | |
| 3257 | + xa_lock(&pool->xa); | |
| 3258 | + group = group_get(xa_load(&pool->xa, group_handle)); | |
| 3259 | + xa_unlock(&pool->xa); | |
| 3260 | + | |
| 3261 | + return group; | |
| 3262 | +} | |
| 3263 | + | |
| 3245 | 3264 | int panthor_group_get_state(struct panthor_file *pfile, |
| 3246 | 3265 | struct drm_panthor_group_get_state *get_state) |
| 3247 | 3266 | { |
| @@ -3253,7 +3272,7 @@ int panthor_group_get_state(struct panthor_file *pfile, · 5 unmodified lines | ||
| 3253 | 3272 | if (get_state->pad) |
| 3254 | 3273 | return -EINVAL; |
| 3255 | 3274 | |
| 3256 | − group = group_get(xa_load(&gpool->xa, get_state->group_handle)); | |
| 3275 | + group = group_from_handle(gpool, get_state->group_handle); | |
| 3257 | 3276 | if (!group) |
| 3258 | 3277 | return -EINVAL; |
| 3259 | 3278 | |
| @@ -3384,7 +3403,7 @@ panthor_job_create(struct panthor_file *pfile, · 124 unmodified lines | ||
| 3384 | 3403 | job->call_info.latest_flush = qsubmit->latest_flush; |
| 3385 | 3404 | INIT_LIST_HEAD(&job->node); |
| 3386 | 3405 | |
| 3387 | − job->group = group_get(xa_load(&gpool->xa, group_handle)); | |
| 3406 | + job->group = group_from_handle(gpool, group_handle); | |
| 3388 | 3407 | if (!job->group) { |
| 3389 | 3408 | ret = -EINVAL; |
| 3390 | 3409 | goto err_put_job; |
| @@ -3424,13 +3443,8 @@ void panthor_job_update_resvs(struct drm_exec *exec, struct drm_sched_job *sched · 33 unmodified lines | ||
| 3424 | 3443 | { |
| 3425 | 3444 | struct panthor_job *job = container_of(sched_job, struct panthor_job, base); |
| 3426 | 3445 | |
| 3427 | − /* Still not sure why we want USAGE_WRITE for external objects, since I | |
| 3428 | − * was assuming this would be handled through explicit syncs being imported | |
| 3429 | − * to external BOs with DMA_BUF_IOCTL_IMPORT_SYNC_FILE, but other drivers | |
| 3430 | − * seem to pass DMA_RESV_USAGE_WRITE, so there must be a good reason. | |
| 3431 | − */ | |
| 3432 | 3446 | panthor_vm_update_resvs(job->group->vm, exec, &sched_job->s_fence->finished, |
| 3433 | − DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_WRITE); | |
| 3447 | + DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_BOOKKEEP); | |
| 3434 | 3448 | } |
| 3435 | 3449 | |
| 3436 | 3450 | void panthor_sched_unplug(struct panthor_device *ptdev) |
| @@ -228,10 +228,8 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector) · 227 unmodified lines | ||
| 228 | 228 | { |
| 229 | 229 | struct drm_device *dev = radeon_connector->base.dev; |
| 230 | 230 | struct radeon_device *rdev = dev->dev_private; |
| 231 | − int ret; | |
| 232 | 231 | |
| 233 | 232 | radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd; |
| 234 | − radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; | |
| 235 | 233 | radeon_connector->ddc_bus->aux.drm_dev = radeon_connector->base.dev; |
| 236 | 234 | if (ASIC_IS_DCE5(rdev)) { |
| 237 | 235 | if (radeon_auxch) |
| @@ -242,11 +240,8 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector) · 4 unmodified lines | ||
| 242 | 240 | radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom; |
| 243 | 241 | } |
| 244 | 242 | |
| 245 | − ret = drm_dp_aux_register(&radeon_connector->ddc_bus->aux); | |
| 246 | − if (!ret) | |
| 247 | − radeon_connector->ddc_bus->has_aux = true; | |
| 248 | − | |
| 249 | − WARN(ret, "drm_dp_aux_register() failed with error %d\n", ret); | |
| 243 | + drm_dp_aux_init(&radeon_connector->ddc_bus->aux); | |
| 244 | + radeon_connector->ddc_bus->has_aux = true; | |
| 250 | 245 | } |
| 251 | 246 | |
| 252 | 247 | /***** general DP utility functions *****/ |
| @@ -1786,6 +1786,20 @@ static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector · 1785 unmodified lines | ||
| 1786 | 1786 | return MODE_OK; |
| 1787 | 1787 | } |
| 1788 | 1788 | |
| 1789 | +static int | |
| 1790 | +radeon_connector_late_register(struct drm_connector *connector) | |
| 1791 | +{ | |
| 1792 | + struct radeon_connector *radeon_connector = to_radeon_connector(connector); | |
| 1793 | + int r = 0; | |
| 1794 | + | |
| 1795 | + if (radeon_connector->ddc_bus->has_aux) { | |
| 1796 | + radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; | |
| 1797 | + r = drm_dp_aux_register(&radeon_connector->ddc_bus->aux); | |
| 1798 | + } | |
| 1799 | + | |
| 1800 | + return r; | |
| 1801 | +} | |
| 1802 | + | |
| 1789 | 1803 | static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { |
| 1790 | 1804 | .get_modes = radeon_dp_get_modes, |
| 1791 | 1805 | .mode_valid = radeon_dp_mode_valid, |
| @@ -1800,6 +1814,7 @@ static const struct drm_connector_funcs radeon_dp_connector_funcs = { · 8 unmodified lines | ||
| 1800 | 1814 | .early_unregister = radeon_connector_unregister, |
| 1801 | 1815 | .destroy = radeon_connector_destroy, |
| 1802 | 1816 | .force = radeon_dvi_force, |
| 1817 | + .late_register = radeon_connector_late_register, | |
| 1803 | 1818 | }; |
| 1804 | 1819 | |
| 1805 | 1820 | static const struct drm_connector_funcs radeon_edp_connector_funcs = { |
| @@ -1810,6 +1825,7 @@ static const struct drm_connector_funcs radeon_edp_connector_funcs = { · 4 unmodified lines | ||
| 1810 | 1825 | .early_unregister = radeon_connector_unregister, |
| 1811 | 1826 | .destroy = radeon_connector_destroy, |
| 1812 | 1827 | .force = radeon_dvi_force, |
| 1828 | + .late_register = radeon_connector_late_register, | |
| 1813 | 1829 | }; |
| 1814 | 1830 | |
| 1815 | 1831 | static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = { |
| @@ -1820,6 +1836,7 @@ static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = { · 4 unmodified lines | ||
| 1820 | 1836 | .early_unregister = radeon_connector_unregister, |
| 1821 | 1837 | .destroy = radeon_connector_destroy, |
| 1822 | 1838 | .force = radeon_dvi_force, |
| 1839 | + .late_register = radeon_connector_late_register, | |
| 1823 | 1840 | }; |
| 1824 | 1841 | |
| 1825 | 1842 | void |
| @@ -43,7 +43,7 @@ static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) · 42 unmodified lines | ||
| 43 | 43 | struct radeon_device *rdev = dev->dev_private; |
| 44 | 44 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 45 | 45 | struct drm_encoder *clone_encoder; |
| 46 | − uint32_t index_mask = 0; | |
| 46 | + uint32_t index_mask = drm_encoder_mask(encoder); | |
| 47 | 47 | int count; |
| 48 | 48 | |
| 49 | 49 | /* DIG routing gets problematic */ |
| @@ -44,8 +44,6 @@ struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj); · 43 unmodified lines | ||
| 44 | 44 | int radeon_gem_prime_pin(struct drm_gem_object *obj); |
| 45 | 45 | void radeon_gem_prime_unpin(struct drm_gem_object *obj); |
| 46 | 46 | |
| 47 | −const struct drm_gem_object_funcs radeon_gem_object_funcs; | |
| 48 | − | |
| 49 | 47 | static vm_fault_t radeon_gem_fault(struct vm_fault *vmf) |
| 50 | 48 | { |
| 51 | 49 | struct ttm_buffer_object *bo = vmf->vma->vm_private_data; |
| @@ -132,7 +130,6 @@ retry: · 80 unmodified lines | ||
| 132 | 130 | return r; |
| 133 | 131 | } |
| 134 | 132 | *obj = &robj->tbo.base; |
| 135 | − (*obj)->funcs = &radeon_gem_object_funcs; | |
| 136 | 133 | robj->pid = task_pid_nr(current); |
| 137 | 134 | |
| 138 | 135 | mutex_lock(&rdev->gem.mutex); |
| @@ -151,6 +151,7 @@ int radeon_bo_create(struct radeon_device *rdev, · 150 unmodified lines | ||
| 151 | 151 | if (bo == NULL) |
| 152 | 152 | return -ENOMEM; |
| 153 | 153 | drm_gem_private_object_init(rdev_to_drm(rdev), &bo->tbo.base, size); |
| 154 | + bo->tbo.base.funcs = &radeon_gem_object_funcs; | |
| 154 | 155 | bo->rdev = rdev; |
| 155 | 156 | bo->surface_reg = -1; |
| 156 | 157 | INIT_LIST_HEAD(&bo->list); |
| @@ -133,8 +133,10 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity, · 132 unmodified lines | ||
| 133 | 133 | { |
| 134 | 134 | WARN_ON(!num_sched_list || !sched_list); |
| 135 | 135 | |
| 136 | + spin_lock(&entity->rq_lock); | |
| 136 | 137 | entity->sched_list = sched_list; |
| 137 | 138 | entity->num_sched_list = num_sched_list; |
| 139 | + spin_unlock(&entity->rq_lock); | |
| 138 | 140 | } |
| 139 | 141 | EXPORT_SYMBOL(drm_sched_entity_modify_sched); |
| 140 | 142 | |
| @@ -380,7 +382,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f, · 239 unmodified lines | ||
| 380 | 382 | container_of(cb, struct drm_sched_entity, cb); |
| 381 | 383 | |
| 382 | 384 | drm_sched_entity_clear_dep(f, cb); |
| 383 | − drm_sched_wakeup(entity->rq->sched, entity); | |
| 385 | + drm_sched_wakeup(entity->rq->sched); | |
| 384 | 386 | } |
| 385 | 387 | |
| 386 | 388 | /** |
| @@ -597,6 +599,9 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) · 210 unmodified lines | ||
| 597 | 599 | |
| 598 | 600 | /* first job wakes up scheduler */ |
| 599 | 601 | if (first) { |
| 602 | + struct drm_gpu_scheduler *sched; | |
| 603 | + struct drm_sched_rq *rq; | |
| 604 | + | |
| 600 | 605 | /* Add the entity to the run queue */ |
| 601 | 606 | spin_lock(&entity->rq_lock); |
| 602 | 607 | if (entity->stopped) { |
| @@ -606,13 +611,16 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) · 3 unmodified lines | ||
| 606 | 611 | return; |
| 607 | 612 | } |
| 608 | 613 | |
| 609 | − drm_sched_rq_add_entity(entity->rq, entity); | |
| 614 | + rq = entity->rq; | |
| 615 | + sched = rq->sched; | |
| 616 | + | |
| 617 | + drm_sched_rq_add_entity(rq, entity); | |
| 610 | 618 | spin_unlock(&entity->rq_lock); |
| 611 | 619 | |
| 612 | 620 | if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) |
| 613 | 621 | drm_sched_rq_update_fifo(entity, submit_ts); |
| 614 | 622 | |
| 615 | − drm_sched_wakeup(entity->rq->sched, entity); | |
| 623 | + drm_sched_wakeup(sched); | |
| 616 | 624 | } |
| 617 | 625 | } |
| 618 | 626 | EXPORT_SYMBOL(drm_sched_entity_push_job); |
| @@ -87,6 +87,12 @@ · 86 unmodified lines | ||
| 87 | 87 | #define CREATE_TRACE_POINTS |
| 88 | 88 | #include "gpu_scheduler_trace.h" |
| 89 | 89 | |
| 90 | +#ifdef CONFIG_LOCKDEP | |
| 91 | +static struct lockdep_map drm_sched_lockdep_map = { | |
| 92 | + .name = "drm_sched_lockdep_map" | |
| 93 | +}; | |
| 94 | +#endif | |
| 95 | + | |
| 90 | 96 | #define to_drm_sched_job(sched_job) \ |
| 91 | 97 | container_of((sched_job), struct drm_sched_job, queue_node) |
| 92 | 98 | |
| @@ -1013,15 +1019,12 @@ EXPORT_SYMBOL(drm_sched_job_cleanup); · 920 unmodified lines | ||
| 1013 | 1019 | /** |
| 1014 | 1020 | * drm_sched_wakeup - Wake up the scheduler if it is ready to queue |
| 1015 | 1021 | * @sched: scheduler instance |
| 1016 | − * @entity: the scheduler entity | |
| 1017 | 1022 | * |
| 1018 | 1023 | * Wake up the scheduler if we can queue jobs. |
| 1019 | 1024 | */ |
| 1020 | −void drm_sched_wakeup(struct drm_gpu_scheduler *sched, | |
| 1021 | − struct drm_sched_entity *entity) | |
| 1025 | +void drm_sched_wakeup(struct drm_gpu_scheduler *sched) | |
| 1022 | 1026 | { |
| 1023 | − if (drm_sched_can_queue(sched, entity)) | |
| 1024 | − drm_sched_run_job_queue(sched); | |
| 1027 | + drm_sched_run_job_queue(sched); | |
| 1025 | 1028 | } |
| 1026 | 1029 | |
| 1027 | 1030 | /** |
| @@ -1272,7 +1275,12 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, · 244 unmodified lines | ||
| 1272 | 1275 | sched->submit_wq = submit_wq; |
| 1273 | 1276 | sched->own_submit_wq = false; |
| 1274 | 1277 | } else { |
| 1278 | +#ifdef CONFIG_LOCKDEP | |
| 1279 | + sched->submit_wq = alloc_ordered_workqueue_lockdep_map(name, 0, | |
| 1280 | + &drm_sched_lockdep_map); | |
| 1281 | +#else | |
| 1275 | 1282 | sched->submit_wq = alloc_ordered_workqueue(name, 0); |
| 1283 | +#endif | |
| 1276 | 1284 | if (!sched->submit_wq) |
| 1277 | 1285 | return -ENOMEM; |
| 1278 | 1286 | |
| @@ -46,7 +46,6 @@ struct gr3d { · 45 unmodified lines | ||
| 46 | 46 | unsigned int nclocks; |
| 47 | 47 | struct reset_control_bulk_data resets[RST_GR3D_MAX]; |
| 48 | 48 | unsigned int nresets; |
| 49 | − struct dev_pm_domain_list *pd_list; | |
| 50 | 49 | |
| 51 | 50 | DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); |
| 52 | 51 | }; |
| @@ -370,12 +369,18 @@ static int gr3d_power_up_legacy_domain(struct device *dev, const char *name, · 317 unmodified lines | ||
| 370 | 369 | return 0; |
| 371 | 370 | } |
| 372 | 371 | |
| 372 | +static void gr3d_del_link(void *link) | |
| 373 | +{ | |
| 374 | + device_link_del(link); | |
| 375 | +} | |
| 376 | + | |
| 373 | 377 | static int gr3d_init_power(struct device *dev, struct gr3d *gr3d) |
| 374 | 378 | { |
| 375 | − struct dev_pm_domain_attach_data pd_data = { | |
| 376 | − .pd_names = (const char *[]) { "3d0", "3d1" }, | |
| 377 | − .num_pd_names = 2, | |
| 378 | − }; | |
| 379 | + static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL }; | |
| 380 | + const u32 link_flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; | |
| 381 | + struct device **opp_virt_devs, *pd_dev; | |
| 382 | + struct device_link *link; | |
| 383 | + unsigned int i; | |
| 379 | 384 | int err; |
| 380 | 385 | |
| 381 | 386 | err = of_count_phandle_with_args(dev->of_node, "power-domains", |
| @@ -409,10 +414,29 @@ static int gr3d_init_power(struct device *dev, struct gr3d *gr3d) · 27 unmodified lines | ||
| 409 | 414 | if (dev->pm_domain) |
| 410 | 415 | return 0; |
| 411 | 416 | |
| 412 | − err = dev_pm_domain_attach_list(dev, &pd_data, &gr3d->pd_list); | |
| 413 | − if (err < 0) | |
| 417 | + err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs); | |
| 418 | + if (err) | |
| 414 | 419 | return err; |
| 415 | 420 | |
| 421 | + for (i = 0; opp_genpd_names[i]; i++) { | |
| 422 | + pd_dev = opp_virt_devs[i]; | |
| 423 | + if (!pd_dev) { | |
| 424 | + dev_err(dev, "failed to get %s power domain\n", | |
| 425 | + opp_genpd_names[i]); | |
| 426 | + return -EINVAL; | |
| 427 | + } | |
| 428 | + | |
| 429 | + link = device_link_add(dev, pd_dev, link_flags); | |
| 430 | + if (!link) { | |
| 431 | + dev_err(dev, "failed to link to %s\n", dev_name(pd_dev)); | |
| 432 | + return -EINVAL; | |
| 433 | + } | |
| 434 | + | |
| 435 | + err = devm_add_action_or_reset(dev, gr3d_del_link, link); | |
| 436 | + if (err) | |
| 437 | + return err; | |
| 438 | + } | |
| 439 | + | |
| 416 | 440 | return 0; |
| 417 | 441 | } |
| 418 | 442 | |
| @@ -503,13 +527,13 @@ static int gr3d_probe(struct platform_device *pdev) · 84 unmodified lines | ||
| 503 | 527 | |
| 504 | 528 | err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); |
| 505 | 529 | if (err) |
| 506 | − goto err; | |
| 530 | + return err; | |
| 507 | 531 | |
| 508 | 532 | err = host1x_client_register(&gr3d->client.base); |
| 509 | 533 | if (err < 0) { |
| 510 | 534 | dev_err(&pdev->dev, "failed to register host1x client: %d\n", |
| 511 | 535 | err); |
| 512 | − goto err; | |
| 536 | + return err; | |
| 513 | 537 | } |
| 514 | 538 | |
| 515 | 539 | /* initialize address register map */ |
| @@ -517,9 +541,6 @@ static int gr3d_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 517 | 541 | set_bit(gr3d_addr_regs[i], gr3d->addr_regs); |
| 518 | 542 | |
| 519 | 543 | return 0; |
| 520 | −err: | |
| 521 | − dev_pm_domain_detach_list(gr3d->pd_list); | |
| 522 | − return err; | |
| 523 | 544 | } |
| 524 | 545 | |
| 525 | 546 | static void gr3d_remove(struct platform_device *pdev) |
| @@ -528,7 +549,6 @@ static void gr3d_remove(struct platform_device *pdev) · 2 unmodified lines | ||
| 528 | 549 | |
| 529 | 550 | pm_runtime_disable(&pdev->dev); |
| 530 | 551 | host1x_client_unregister(&gr3d->client.base); |
| 531 | − dev_pm_domain_detach_list(gr3d->pd_list); | |
| 532 | 552 | } |
| 533 | 553 | |
| 534 | 554 | static int __maybe_unused gr3d_runtime_suspend(struct device *dev) |
| @@ -306,6 +306,11 @@ void v3d_perfmon_open_file(struct v3d_file_priv *v3d_priv) · 305 unmodified lines | ||
| 306 | 306 | static int v3d_perfmon_idr_del(int id, void *elem, void *data) |
| 307 | 307 | { |
| 308 | 308 | struct v3d_perfmon *perfmon = elem; |
| 309 | + struct v3d_dev *v3d = (struct v3d_dev *)data; | |
| 310 | + | |
| 311 | + /* If the active perfmon is being destroyed, stop it first */ | |
| 312 | + if (perfmon == v3d->active_perfmon) | |
| 313 | + v3d_perfmon_stop(v3d, perfmon, false); | |
| 309 | 314 | |
| 310 | 315 | v3d_perfmon_put(perfmon); |
| 311 | 316 | |
| @@ -314,8 +319,10 @@ static int v3d_perfmon_idr_del(int id, void *elem, void *data) · 2 unmodified lines | ||
| 314 | 319 | |
| 315 | 320 | void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv) |
| 316 | 321 | { |
| 322 | + struct v3d_dev *v3d = v3d_priv->v3d; | |
| 323 | + | |
| 317 | 324 | mutex_lock(&v3d_priv->perfmon.lock); |
| 318 | − idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, NULL); | |
| 325 | + idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, v3d); | |
| 319 | 326 | idr_destroy(&v3d_priv->perfmon.idr); |
| 320 | 327 | mutex_unlock(&v3d_priv->perfmon.lock); |
| 321 | 328 | mutex_destroy(&v3d_priv->perfmon.lock); |
| @@ -139,7 +139,15 @@ int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags, · 138 unmodified lines | ||
| 139 | 139 | flags |= VBOX_MOUSE_POINTER_VISIBLE; |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | − p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA, | |
| 142 | + /* | |
| 143 | + * The 4 extra bytes come from switching struct vbva_mouse_pointer_shape | |
| 144 | + * from having a 4 bytes fixed array at the end to using a proper VLA | |
| 145 | + * at the end. These 4 extra bytes were not subtracted from sizeof(*p) | |
| 146 | + * before the switch to the VLA, so this way the behavior is unchanged. | |
| 147 | + * Chances are these 4 extra bytes are not necessary but they are kept | |
| 148 | + * to avoid regressions. | |
| 149 | + */ | |
| 150 | + p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len + 4, HGSMI_CH_VBVA, | |
| 143 | 151 | VBVA_MOUSE_POINTER_SHAPE); |
| 144 | 152 | if (!p) |
| 145 | 153 | return -ENOMEM; |
| @@ -351,10 +351,8 @@ struct vbva_mouse_pointer_shape { · 350 unmodified lines | ||
| 351 | 351 | * Bytes in the gap between the AND and the XOR mask are undefined. |
| 352 | 352 | * XOR mask scanlines have no gap between them and size of XOR mask is: |
| 353 | 353 | * xor_len = width * 4 * height. |
| 354 | − * | |
| 355 | − * Preallocate 4 bytes for accessing actual data as p->data. | |
| 356 | 354 | */ |
| 357 | − u8 data[4]; | |
| 355 | + u8 data[]; | |
| 358 | 356 | } __packed; |
| 359 | 357 | |
| 360 | 358 | /* pointer is visible */ |
| @@ -116,6 +116,11 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file) · 115 unmodified lines | ||
| 116 | 116 | static int vc4_perfmon_idr_del(int id, void *elem, void *data) |
| 117 | 117 | { |
| 118 | 118 | struct vc4_perfmon *perfmon = elem; |
| 119 | + struct vc4_dev *vc4 = (struct vc4_dev *)data; | |
| 120 | + | |
| 121 | + /* If the active perfmon is being destroyed, stop it first */ | |
| 122 | + if (perfmon == vc4->active_perfmon) | |
| 123 | + vc4_perfmon_stop(vc4, perfmon, false); | |
| 119 | 124 | |
| 120 | 125 | vc4_perfmon_put(perfmon); |
| 121 | 126 | |
| @@ -130,7 +135,7 @@ void vc4_perfmon_close_file(struct vc4_file *vc4file) · 8 unmodified lines | ||
| 130 | 135 | return; |
| 131 | 136 | |
| 132 | 137 | mutex_lock(&vc4file->perfmon.lock); |
| 133 | − idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL); | |
| 138 | + idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, vc4); | |
| 134 | 139 | idr_destroy(&vc4file->perfmon.idr); |
| 135 | 140 | mutex_unlock(&vc4file->perfmon.lock); |
| 136 | 141 | mutex_destroy(&vc4file->perfmon.lock); |
| @@ -635,10 +635,8 @@ out: · 634 unmodified lines | ||
| 635 | 635 | kunmap_atomic(d.src_addr); |
| 636 | 636 | if (d.dst_addr) |
| 637 | 637 | kunmap_atomic(d.dst_addr); |
| 638 | − if (src_pages) | |
| 639 | − kvfree(src_pages); | |
| 640 | − if (dst_pages) | |
| 641 | − kvfree(dst_pages); | |
| 638 | + kvfree(src_pages); | |
| 639 | + kvfree(dst_pages); | |
| 642 | 640 | |
| 643 | 641 | return ret; |
| 644 | 642 | } |
| @@ -62,7 +62,7 @@ · 61 unmodified lines | ||
| 62 | 62 | #define VMWGFX_DRIVER_MINOR 20 |
| 63 | 63 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
| 64 | 64 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
| 65 | −#define VMWGFX_MAX_DISPLAYS 16 | |
| 65 | +#define VMWGFX_NUM_DISPLAY_UNITS 8 | |
| 66 | 66 | #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768 |
| 67 | 67 | |
| 68 | 68 | #define VMWGFX_MIN_INITIAL_WIDTH 1280 |
| @@ -82,7 +82,7 @@ · 13 unmodified lines | ||
| 82 | 82 | #define VMWGFX_NUM_GB_CONTEXT 256 |
| 83 | 83 | #define VMWGFX_NUM_GB_SHADER 20000 |
| 84 | 84 | #define VMWGFX_NUM_GB_SURFACE 32768 |
| 85 | −#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_MAX_DISPLAYS | |
| 85 | +#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_NUM_DISPLAY_UNITS | |
| 86 | 86 | #define VMWGFX_NUM_DXCONTEXT 256 |
| 87 | 87 | #define VMWGFX_NUM_DXQUERY 512 |
| 88 | 88 | #define VMWGFX_NUM_MOB (VMWGFX_NUM_GB_CONTEXT +\ |
| @@ -1283,7 +1283,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, · 1282 unmodified lines | ||
| 1283 | 1283 | { |
| 1284 | 1284 | struct drm_device *dev = &dev_priv->drm; |
| 1285 | 1285 | struct vmw_framebuffer_surface *vfbs; |
| 1286 | − enum SVGA3dSurfaceFormat format; | |
| 1287 | 1286 | struct vmw_surface *surface; |
| 1288 | 1287 | int ret; |
| 1289 | 1288 | |
| @@ -1320,34 +1319,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, · 30 unmodified lines | ||
| 1320 | 1319 | return -EINVAL; |
| 1321 | 1320 | } |
| 1322 | 1321 | |
| 1323 | − switch (mode_cmd->pixel_format) { | |
| 1324 | − case DRM_FORMAT_ARGB8888: | |
| 1325 | − format = SVGA3D_A8R8G8B8; | |
| 1326 | − break; | |
| 1327 | − case DRM_FORMAT_XRGB8888: | |
| 1328 | − format = SVGA3D_X8R8G8B8; | |
| 1329 | − break; | |
| 1330 | − case DRM_FORMAT_RGB565: | |
| 1331 | − format = SVGA3D_R5G6B5; | |
| 1332 | − break; | |
| 1333 | − case DRM_FORMAT_XRGB1555: | |
| 1334 | − format = SVGA3D_A1R5G5B5; | |
| 1335 | − break; | |
| 1336 | − default: | |
| 1337 | − DRM_ERROR("Invalid pixel format: %p4cc\n", | |
| 1338 | − &mode_cmd->pixel_format); | |
| 1339 | − return -EINVAL; | |
| 1340 | − } | |
| 1341 | − | |
| 1342 | − /* | |
| 1343 | − * For DX, surface format validation is done when surface->scanout | |
| 1344 | − * is set. | |
| 1345 | − */ | |
| 1346 | − if (!has_sm4_context(dev_priv) && format != surface->metadata.format) { | |
| 1347 | − DRM_ERROR("Invalid surface format for requested mode.\n"); | |
| 1348 | − return -EINVAL; | |
| 1349 | − } | |
| 1350 | − | |
| 1351 | 1322 | vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL); |
| 1352 | 1323 | if (!vfbs) { |
| 1353 | 1324 | ret = -ENOMEM; |
| @@ -1539,6 +1510,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, · 185 unmodified lines | ||
| 1539 | 1510 | DRM_ERROR("Surface size cannot exceed %dx%d\n", |
| 1540 | 1511 | dev_priv->texture_max_width, |
| 1541 | 1512 | dev_priv->texture_max_height); |
| 1513 | + ret = -EINVAL; | |
| 1542 | 1514 | goto err_out; |
| 1543 | 1515 | } |
| 1544 | 1516 | |
| @@ -2225,7 +2197,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, · 680 unmodified lines | ||
| 2225 | 2197 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 2226 | 2198 | struct drm_vmw_update_layout_arg *arg = |
| 2227 | 2199 | (struct drm_vmw_update_layout_arg *)data; |
| 2228 | − void __user *user_rects; | |
| 2200 | + const void __user *user_rects; | |
| 2229 | 2201 | struct drm_vmw_rect *rects; |
| 2230 | 2202 | struct drm_rect *drm_rects; |
| 2231 | 2203 | unsigned rects_size; |
| @@ -2237,6 +2209,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, · 5 unmodified lines | ||
| 2237 | 2209 | VMWGFX_MIN_INITIAL_HEIGHT}; |
| 2238 | 2210 | vmw_du_update_layout(dev_priv, 1, &def_rect); |
| 2239 | 2211 | return 0; |
| 2212 | + } else if (arg->num_outputs > VMWGFX_NUM_DISPLAY_UNITS) { | |
| 2213 | + return -E2BIG; | |
| 2240 | 2214 | } |
| 2241 | 2215 | |
| 2242 | 2216 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); |
| @@ -199,9 +199,6 @@ struct vmw_kms_dirty { · 198 unmodified lines | ||
| 199 | 199 | s32 unit_y2; |
| 200 | 200 | }; |
| 201 | 201 | |
| 202 | −#define VMWGFX_NUM_DISPLAY_UNITS 8 | |
| 203 | − | |
| 204 | − | |
| 205 | 202 | #define vmw_framebuffer_to_vfb(x) \ |
| 206 | 203 | container_of(x, struct vmw_framebuffer, base) |
| 207 | 204 | #define vmw_framebuffer_to_vfbs(x) \ |
| @@ -886,6 +886,10 @@ static int vmw_stdu_connector_atomic_check(struct drm_connector *conn, · 885 unmodified lines | ||
| 886 | 886 | struct drm_crtc_state *new_crtc_state; |
| 887 | 887 | |
| 888 | 888 | conn_state = drm_atomic_get_connector_state(state, conn); |
| 889 | + | |
| 890 | + if (IS_ERR(conn_state)) | |
| 891 | + return PTR_ERR(conn_state); | |
| 892 | + | |
| 889 | 893 | du = vmw_connector_to_stdu(conn); |
| 890 | 894 | |
| 891 | 895 | if (!conn_state->crtc) |
| @@ -2276,9 +2276,12 @@ int vmw_dumb_create(struct drm_file *file_priv, · 2275 unmodified lines | ||
| 2276 | 2276 | const struct SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format); |
| 2277 | 2277 | SVGA3dSurfaceAllFlags flags = SVGA3D_SURFACE_HINT_TEXTURE | |
| 2278 | 2278 | SVGA3D_SURFACE_HINT_RENDERTARGET | |
| 2279 | − SVGA3D_SURFACE_SCREENTARGET | | |
| 2280 | − SVGA3D_SURFACE_BIND_SHADER_RESOURCE | | |
| 2281 | − SVGA3D_SURFACE_BIND_RENDER_TARGET; | |
| 2279 | + SVGA3D_SURFACE_SCREENTARGET; | |
| 2280 | + | |
| 2281 | + if (vmw_surface_is_dx_screen_target_format(format)) { | |
| 2282 | + flags |= SVGA3D_SURFACE_BIND_SHADER_RESOURCE | | |
| 2283 | + SVGA3D_SURFACE_BIND_RENDER_TARGET; | |
| 2284 | + } | |
| 2282 | 2285 | |
| 2283 | 2286 | /* |
| 2284 | 2287 | * Without mob support we're just going to use raw memory buffer |
| @@ -169,6 +169,8 @@ · 168 unmodified lines | ||
| 169 | 169 | #define XEHP_SLICE_COMMON_ECO_CHICKEN1 XE_REG_MCR(0x731c, XE_REG_OPTION_MASKED) |
| 170 | 170 | #define MSC_MSAA_REODER_BUF_BYPASS_DISABLE REG_BIT(14) |
| 171 | 171 | |
| 172 | +#define XE2LPM_CCCHKNREG1 XE_REG(0x82a8) | |
| 173 | + | |
| 172 | 174 | #define VF_PREEMPTION XE_REG(0x83a4, XE_REG_OPTION_MASKED) |
| 173 | 175 | #define PREEMPTION_VERTEX_COUNT REG_GENMASK(15, 0) |
| 174 | 176 | |
| @@ -378,6 +380,9 @@ · 203 unmodified lines | ||
| 378 | 380 | #define L3SQCREG3 XE_REG_MCR(0xb108) |
| 379 | 381 | #define COMPPWOVERFETCHEN REG_BIT(28) |
| 380 | 382 | |
| 383 | +#define SCRATCH3_LBCF XE_REG_MCR(0xb154) | |
| 384 | +#define RWFLUSHALLEN REG_BIT(17) | |
| 385 | + | |
| 381 | 386 | #define XEHP_L3SQCREG5 XE_REG_MCR(0xb158) |
| 382 | 387 | #define L3_PWM_TIMER_INIT_VAL_MASK REG_GENMASK(9, 0) |
| 383 | 388 | |
| @@ -388,8 +393,11 @@ · 4 unmodified lines | ||
| 388 | 393 | |
| 389 | 394 | #define XE2_GLOBAL_INVAL XE_REG(0xb404) |
| 390 | 395 | |
| 391 | −#define SCRATCH1LPFC XE_REG(0xb474) | |
| 392 | −#define EN_L3_RW_CCS_CACHE_FLUSH REG_BIT(0) | |
| 396 | +#define XE2LPM_L3SQCREG2 XE_REG_MCR(0xb604) | |
| 397 | + | |
| 398 | +#define XE2LPM_L3SQCREG3 XE_REG_MCR(0xb608) | |
| 399 | + | |
| 400 | +#define XE2LPM_SCRATCH3_LBCF XE_REG_MCR(0xb654) | |
| 393 | 401 | |
| 394 | 402 | #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) |
| 395 | 403 | |
| @@ -680,8 +680,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict, · 679 unmodified lines | ||
| 680 | 680 | tt_has_data = ttm && (ttm_tt_is_populated(ttm) || |
| 681 | 681 | (ttm->page_flags & TTM_TT_FLAG_SWAPPED)); |
| 682 | 682 | |
| 683 | − move_lacks_source = handle_system_ccs ? (!bo->ccs_cleared) : | |
| 684 | − (!mem_type_is_vram(old_mem_type) && !tt_has_data); | |
| 683 | + move_lacks_source = !old_mem || (handle_system_ccs ? (!bo->ccs_cleared) : | |
| 684 | + (!mem_type_is_vram(old_mem_type) && !tt_has_data)); | |
| 685 | 685 | |
| 686 | 686 | needs_clear = (ttm && ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) || |
| 687 | 687 | (!ttm && ttm_bo->type == ttm_bo_type_device); |
| @@ -187,7 +187,7 @@ void xe_debugfs_register(struct xe_device *xe) · 186 unmodified lines | ||
| 187 | 187 | debugfs_create_file("forcewake_all", 0400, root, xe, |
| 188 | 188 | &forcewake_all_fops); |
| 189 | 189 | |
| 190 | − debugfs_create_file("wedged_mode", 0400, root, xe, | |
| 190 | + debugfs_create_file("wedged_mode", 0600, root, xe, | |
| 191 | 191 | &wedged_mode_fops); |
| 192 | 192 | |
| 193 | 193 | for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) { |
| @@ -171,10 +171,8 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file) · 170 unmodified lines | ||
| 171 | 171 | xe_exec_queue_kill(q); |
| 172 | 172 | xe_exec_queue_put(q); |
| 173 | 173 | } |
| 174 | − mutex_lock(&xef->vm.lock); | |
| 175 | 174 | xa_for_each(&xef->vm.xa, idx, vm) |
| 176 | 175 | xe_vm_close_and_put(vm); |
| 177 | − mutex_unlock(&xef->vm.lock); | |
| 178 | 176 | |
| 179 | 177 | xe_file_put(xef); |
| 180 | 178 | |
| @@ -298,6 +296,9 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy) · 117 unmodified lines | ||
| 298 | 296 | if (xe->unordered_wq) |
| 299 | 297 | destroy_workqueue(xe->unordered_wq); |
| 300 | 298 | |
| 299 | + if (xe->destroy_wq) | |
| 300 | + destroy_workqueue(xe->destroy_wq); | |
| 301 | + | |
| 301 | 302 | ttm_device_fini(&xe->ttm); |
| 302 | 303 | } |
| 303 | 304 | |
| @@ -336,9 +337,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, · 32 unmodified lines | ||
| 336 | 337 | |
| 337 | 338 | init_waitqueue_head(&xe->ufence_wq); |
| 338 | 339 | |
| 339 | − err = drmm_mutex_init(&xe->drm, &xe->usm.lock); | |
| 340 | − if (err) | |
| 341 | − goto err; | |
| 340 | + init_rwsem(&xe->usm.lock); | |
| 342 | 341 | |
| 343 | 342 | xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC); |
| 344 | 343 | |
| @@ -363,8 +362,9 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, · 18 unmodified lines | ||
| 363 | 362 | xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0); |
| 364 | 363 | xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0); |
| 365 | 364 | xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0); |
| 365 | + xe->destroy_wq = alloc_workqueue("xe-destroy-wq", 0, 0); | |
| 366 | 366 | if (!xe->ordered_wq || !xe->unordered_wq || |
| 367 | − !xe->preempt_fence_wq) { | |
| 367 | + !xe->preempt_fence_wq || !xe->destroy_wq) { | |
| 368 | 368 | /* |
| 369 | 369 | * Cleanup done in xe_device_destroy via |
| 370 | 370 | * drmm_add_action_or_reset register above |
| @@ -980,13 +980,13 @@ void xe_device_declare_wedged(struct xe_device *xe) · 609 unmodified lines | ||
| 980 | 980 | return; |
| 981 | 981 | } |
| 982 | 982 | |
| 983 | + xe_pm_runtime_get_noresume(xe); | |
| 984 | + | |
| 983 | 985 | if (drmm_add_action_or_reset(&xe->drm, xe_device_wedged_fini, xe)) { |
| 984 | 986 | drm_err(&xe->drm, "Failed to register xe_device_wedged_fini clean-up. Although device is wedged.\n"); |
| 985 | 987 | return; |
| 986 | 988 | } |
| 987 | 989 | |
| 988 | − xe_pm_runtime_get_noresume(xe); | |
| 989 | − | |
| 990 | 990 | if (!atomic_xchg(&xe->wedged.flag, 1)) { |
| 991 | 991 | xe->needs_flr_on_fini = true; |
| 992 | 992 | drm_err(&xe->drm, |
| @@ -369,7 +369,7 @@ struct xe_device { · 368 unmodified lines | ||
| 369 | 369 | /** @usm.next_asid: next ASID, used to cyclical alloc asids */ |
| 370 | 370 | u32 next_asid; |
| 371 | 371 | /** @usm.lock: protects UM state */ |
| 372 | − struct mutex lock; | |
| 372 | + struct rw_semaphore lock; | |
| 373 | 373 | } usm; |
| 374 | 374 | |
| 375 | 375 | /** @pinned: pinned BO state */ |
| @@ -396,6 +396,9 @@ struct xe_device { · 20 unmodified lines | ||
| 396 | 396 | /** @unordered_wq: used to serialize unordered work, mostly display */ |
| 397 | 397 | struct workqueue_struct *unordered_wq; |
| 398 | 398 | |
| 399 | + /** @destroy_wq: used to serialize user destroy work, like queue */ | |
| 400 | + struct workqueue_struct *destroy_wq; | |
| 401 | + | |
| 399 | 402 | /** @tiles: device tiles */ |
| 400 | 403 | struct xe_tile tiles[XE_MAX_TILES_PER_DEVICE]; |
| 401 | 404 | |
| @@ -567,15 +570,23 @@ struct xe_file { · 165 unmodified lines | ||
| 567 | 570 | struct { |
| 568 | 571 | /** @vm.xe: xarray to store VMs */ |
| 569 | 572 | struct xarray xa; |
| 570 | − /** @vm.lock: protects file VM state */ | |
| 573 | + /** | |
| 574 | + * @vm.lock: Protects VM lookup + reference and removal a from | |
| 575 | + * file xarray. Not an intended to be an outer lock which does | |
| 576 | + * thing while being held. | |
| 577 | + */ | |
| 571 | 578 | struct mutex lock; |
| 572 | 579 | } vm; |
| 573 | 580 | |
| 574 | 581 | /** @exec_queue: Submission exec queue state for file */ |
| 575 | 582 | struct { |
| 576 | − /** @exec_queue.xe: xarray to store engines */ | |
| 583 | + /** @exec_queue.xa: xarray to store exece queues */ | |
| 577 | 584 | struct xarray xa; |
| 578 | − /** @exec_queue.lock: protects file engine state */ | |
| 585 | + /** | |
| 586 | + * @exec_queue.lock: Protects exec queue lookup + reference and | |
| 587 | + * removal a frommfile xarray. Not an intended to be an outer | |
| 588 | + * lock which does thing while being held. | |
| 589 | + */ | |
| 579 | 590 | struct mutex lock; |
| 580 | 591 | } exec_queue; |
| 581 | 592 | |
| @@ -283,8 +283,15 @@ static void show_run_ticks(struct drm_printer *p, struct drm_file *file) · 282 unmodified lines | ||
| 283 | 283 | |
| 284 | 284 | /* Accumulate all the exec queues from this client */ |
| 285 | 285 | mutex_lock(&xef->exec_queue.lock); |
| 286 | − xa_for_each(&xef->exec_queue.xa, i, q) | |
| 286 | + xa_for_each(&xef->exec_queue.xa, i, q) { | |
| 287 | + xe_exec_queue_get(q); | |
| 288 | + mutex_unlock(&xef->exec_queue.lock); | |
| 289 | + | |
| 287 | 290 | xe_exec_queue_update_run_ticks(q); |
| 291 | + | |
| 292 | + mutex_lock(&xef->exec_queue.lock); | |
| 293 | + xe_exec_queue_put(q); | |
| 294 | + } | |
| 288 | 295 | mutex_unlock(&xef->exec_queue.lock); |
| 289 | 296 | |
| 290 | 297 | /* Get the total GPU cycles */ |
| @@ -41,11 +41,6 @@ · 40 unmodified lines | ||
| 41 | 41 | * user knows an exec writes to a BO and reads from the BO in the next exec, it |
| 42 | 42 | * is the user's responsibility to pass in / out fence between the two execs). |
| 43 | 43 | * |
| 44 | − * Implicit dependencies for external BOs are handled by using the dma-buf | |
| 45 | − * implicit dependency uAPI (TODO: add link). To make this works each exec must | |
| 46 | − * install the job's fence into the DMA_RESV_USAGE_WRITE slot of every external | |
| 47 | − * BO mapped in the VM. | |
| 48 | − * | |
| 49 | 44 | * We do not allow a user to trigger a bind at exec time rather we have a VM |
| 50 | 45 | * bind IOCTL which uses the same in / out fence interface as exec. In that |
| 51 | 46 | * sense, a VM bind is basically the same operation as an exec from the user |
| @@ -59,8 +54,8 @@ · 7 unmodified lines | ||
| 59 | 54 | * behind any pending kernel operations on any external BOs in VM or any BOs |
| 60 | 55 | * private to the VM. This is accomplished by the rebinds waiting on BOs |
| 61 | 56 | * DMA_RESV_USAGE_KERNEL slot (kernel ops) and kernel ops waiting on all BOs |
| 62 | − * slots (inflight execs are in the DMA_RESV_USAGE_BOOKING for private BOs and | |
| 63 | − * in DMA_RESV_USAGE_WRITE for external BOs). | |
| 57 | + * slots (inflight execs are in the DMA_RESV_USAGE_BOOKKEEP for private BOs and | |
| 58 | + * for external BOs). | |
| 64 | 59 | * |
| 65 | 60 | * Rebinds / dma-resv usage applies to non-compute mode VMs only as for compute |
| 66 | 61 | * mode VMs we use preempt fences and a rebind worker (TODO: add link). |
| @@ -304,7 +299,8 @@ retry: · 237 unmodified lines | ||
| 304 | 299 | xe_sched_job_arm(job); |
| 305 | 300 | if (!xe_vm_in_lr_mode(vm)) |
| 306 | 301 | drm_gpuvm_resv_add_fence(&vm->gpuvm, exec, &job->drm.s_fence->finished, |
| 307 | − DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_WRITE); | |
| 302 | + DMA_RESV_USAGE_BOOKKEEP, | |
| 303 | + DMA_RESV_USAGE_BOOKKEEP); | |
| 308 | 304 | |
| 309 | 305 | for (i = 0; i < num_syncs; i++) { |
| 310 | 306 | xe_sync_entry_signal(&syncs[i], &job->drm.s_fence->finished); |
| @@ -635,14 +635,14 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data, · 634 unmodified lines | ||
| 635 | 635 | } |
| 636 | 636 | } |
| 637 | 637 | |
| 638 | − mutex_lock(&xef->exec_queue.lock); | |
| 638 | + q->xef = xe_file_get(xef); | |
| 639 | + | |
| 640 | + /* user id alloc must always be last in ioctl to prevent UAF */ | |
| 639 | 641 | err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL); |
| 640 | − mutex_unlock(&xef->exec_queue.lock); | |
| 641 | 642 | if (err) |
| 642 | 643 | goto kill_exec_queue; |
| 643 | 644 | |
| 644 | 645 | args->exec_queue_id = id; |
| 645 | − q->xef = xe_file_get(xef); | |
| 646 | 646 | |
| 647 | 647 | return 0; |
| 648 | 648 | |
| @@ -90,6 +90,11 @@ void xe_sched_submission_stop(struct xe_gpu_scheduler *sched) · 89 unmodified lines | ||
| 90 | 90 | cancel_work_sync(&sched->work_process_msg); |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | +void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched) | |
| 94 | +{ | |
| 95 | + drm_sched_resume_timeout(&sched->base, sched->base.timeout); | |
| 96 | +} | |
| 97 | + | |
| 93 | 98 | void xe_sched_add_msg(struct xe_gpu_scheduler *sched, |
| 94 | 99 | struct xe_sched_msg *msg) |
| 95 | 100 | { |
| @@ -22,6 +22,8 @@ void xe_sched_fini(struct xe_gpu_scheduler *sched); · 21 unmodified lines | ||
| 22 | 22 | void xe_sched_submission_start(struct xe_gpu_scheduler *sched); |
| 23 | 23 | void xe_sched_submission_stop(struct xe_gpu_scheduler *sched); |
| 24 | 24 | |
| 25 | +void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched); | |
| 26 | + | |
| 25 | 27 | void xe_sched_add_msg(struct xe_gpu_scheduler *sched, |
| 26 | 28 | struct xe_sched_msg *msg); |
| 27 | 29 | void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched, |
| @@ -61,7 +63,9 @@ xe_sched_invalidate_job(struct xe_sched_job *job, int threshold) · 33 unmodified lines | ||
| 61 | 63 | static inline void xe_sched_add_pending_job(struct xe_gpu_scheduler *sched, |
| 62 | 64 | struct xe_sched_job *job) |
| 63 | 65 | { |
| 66 | + spin_lock(&sched->base.job_list_lock); | |
| 64 | 67 | list_add(&job->drm.list, &sched->base.pending_list); |
| 68 | + spin_unlock(&sched->base.job_list_lock); | |
| 65 | 69 | } |
| 66 | 70 | |
| 67 | 71 | static inline |
| @@ -108,7 +108,6 @@ static void xe_gt_enable_host_l2_vram(struct xe_gt *gt) · 107 unmodified lines | ||
| 108 | 108 | return; |
| 109 | 109 | |
| 110 | 110 | if (!xe_gt_is_media_type(gt)) { |
| 111 | − xe_mmio_write32(gt, SCRATCH1LPFC, EN_L3_RW_CCS_CACHE_FLUSH); | |
| 112 | 111 | reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL); |
| 113 | 112 | reg |= CG_DIS_CNTLBUS; |
| 114 | 113 | xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg); |
| @@ -874,7 +873,9 @@ int xe_gt_sanitize_freq(struct xe_gt *gt) · 759 unmodified lines | ||
| 874 | 873 | int ret = 0; |
| 875 | 874 | |
| 876 | 875 | if ((!xe_uc_fw_is_available(>->uc.gsc.fw) || |
| 877 | − xe_uc_fw_is_loaded(>->uc.gsc.fw)) && XE_WA(gt, 22019338487)) | |
| 876 | + xe_uc_fw_is_loaded(>->uc.gsc.fw) || | |
| 877 | + xe_uc_fw_is_in_error_state(>->uc.gsc.fw)) && | |
| 878 | + XE_WA(gt, 22019338487)) | |
| 878 | 879 | ret = xe_guc_pc_restore_stashed_freq(>->uc.guc.pc); |
| 879 | 880 | |
| 880 | 881 | return ret; |
| @@ -237,11 +237,11 @@ int xe_gt_freq_init(struct xe_gt *gt) · 236 unmodified lines | ||
| 237 | 237 | if (!gt->freq) |
| 238 | 238 | return -ENOMEM; |
| 239 | 239 | |
| 240 | − err = devm_add_action(xe->drm.dev, freq_fini, gt->freq); | |
| 240 | + err = sysfs_create_files(gt->freq, freq_attrs); | |
| 241 | 241 | if (err) |
| 242 | 242 | return err; |
| 243 | 243 | |
| 244 | − err = sysfs_create_files(gt->freq, freq_attrs); | |
| 244 | + err = devm_add_action_or_reset(xe->drm.dev, freq_fini, gt->freq); | |
| 245 | 245 | if (err) |
| 246 | 246 | return err; |
| 247 | 247 | |
| @@ -439,7 +439,7 @@ void xe_gt_mcr_init(struct xe_gt *gt) · 438 unmodified lines | ||
| 439 | 439 | if (gt->info.type == XE_GT_TYPE_MEDIA) { |
| 440 | 440 | drm_WARN_ON(&xe->drm, MEDIA_VER(xe) < 13); |
| 441 | 441 | |
| 442 | − if (MEDIA_VER(xe) >= 20) { | |
| 442 | + if (MEDIA_VERx100(xe) >= 1301) { | |
| 443 | 443 | gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table; |
| 444 | 444 | gt->steering[INSTANCE0].ranges = xe2lpm_instance0_steering_table; |
| 445 | 445 | } else { |
| @@ -185,6 +185,21 @@ unlock_dma_resv: · 184 unmodified lines | ||
| 185 | 185 | return err; |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | +static struct xe_vm *asid_to_vm(struct xe_device *xe, u32 asid) | |
| 189 | +{ | |
| 190 | + struct xe_vm *vm; | |
| 191 | + | |
| 192 | + down_read(&xe->usm.lock); | |
| 193 | + vm = xa_load(&xe->usm.asid_to_vm, asid); | |
| 194 | + if (vm && xe_vm_in_fault_mode(vm)) | |
| 195 | + xe_vm_get(vm); | |
| 196 | + else | |
| 197 | + vm = ERR_PTR(-EINVAL); | |
| 198 | + up_read(&xe->usm.lock); | |
| 199 | + | |
| 200 | + return vm; | |
| 201 | +} | |
| 202 | + | |
| 188 | 203 | static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) |
| 189 | 204 | { |
| 190 | 205 | struct xe_device *xe = gt_to_xe(gt); |
| @@ -197,16 +212,9 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) · 6 unmodified lines | ||
| 197 | 212 | if (pf->trva_fault) |
| 198 | 213 | return -EFAULT; |
| 199 | 214 | |
| 200 | − /* ASID to VM */ | |
| 201 | − mutex_lock(&xe->usm.lock); | |
| 202 | − vm = xa_load(&xe->usm.asid_to_vm, pf->asid); | |
| 203 | − if (vm && xe_vm_in_fault_mode(vm)) | |
| 204 | − xe_vm_get(vm); | |
| 205 | − else | |
| 206 | − vm = NULL; | |
| 207 | − mutex_unlock(&xe->usm.lock); | |
| 208 | − if (!vm) | |
| 209 | − return -EINVAL; | |
| 215 | + vm = asid_to_vm(xe, pf->asid); | |
| 216 | + if (IS_ERR(vm)) | |
| 217 | + return PTR_ERR(vm); | |
| 210 | 218 | |
| 211 | 219 | /* |
| 212 | 220 | * TODO: Change to read lock? Using write lock for simplicity. |
| @@ -548,14 +556,9 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc) · 335 unmodified lines | ||
| 548 | 556 | if (acc->access_type != ACC_TRIGGER) |
| 549 | 557 | return -EINVAL; |
| 550 | 558 | |
| 551 | − /* ASID to VM */ | |
| 552 | − mutex_lock(&xe->usm.lock); | |
| 553 | − vm = xa_load(&xe->usm.asid_to_vm, acc->asid); | |
| 554 | − if (vm) | |
| 555 | − xe_vm_get(vm); | |
| 556 | − mutex_unlock(&xe->usm.lock); | |
| 557 | − if (!vm || !xe_vm_in_fault_mode(vm)) | |
| 558 | − return -EINVAL; | |
| 559 | + vm = asid_to_vm(xe, acc->asid); | |
| 560 | + if (IS_ERR(vm)) | |
| 561 | + return PTR_ERR(vm); | |
| 559 | 562 | |
| 560 | 563 | down_read(&vm->lock); |
| 561 | 564 | |
| @@ -51,5 +51,5 @@ int xe_gt_sysfs_init(struct xe_gt *gt) · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | gt->sysfs = &kg->base; |
| 53 | 53 | |
| 54 | − return devm_add_action(xe->drm.dev, gt_sysfs_fini, gt); | |
| 54 | + return devm_add_action_or_reset(xe->drm.dev, gt_sysfs_fini, gt); | |
| 55 | 55 | } |
| @@ -37,6 +37,15 @@ static long tlb_timeout_jiffies(struct xe_gt *gt) · 36 unmodified lines | ||
| 37 | 37 | return hw_tlb_timeout + 2 * delay; |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | +static void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence) | |
| 41 | +{ | |
| 42 | + if (WARN_ON_ONCE(!fence->gt)) | |
| 43 | + return; | |
| 44 | + | |
| 45 | + xe_pm_runtime_put(gt_to_xe(fence->gt)); | |
| 46 | + fence->gt = NULL; /* fini() should be called once */ | |
| 47 | +} | |
| 48 | + | |
| 40 | 49 | static void |
| 41 | 50 | __invalidation_fence_signal(struct xe_device *xe, struct xe_gt_tlb_invalidation_fence *fence) |
| 42 | 51 | { |
| @@ -204,7 +213,7 @@ static int send_tlb_invalidation(struct xe_guc *guc, · 161 unmodified lines | ||
| 204 | 213 | tlb_timeout_jiffies(gt)); |
| 205 | 214 | } |
| 206 | 215 | spin_unlock_irq(>->tlb_invalidation.pending_lock); |
| 207 | − } else if (ret < 0) { | |
| 216 | + } else { | |
| 208 | 217 | __invalidation_fence_signal(xe, fence); |
| 209 | 218 | } |
| 210 | 219 | if (!ret) { |
| @@ -267,10 +276,8 @@ int xe_gt_tlb_invalidation_ggtt(struct xe_gt *gt) · 56 unmodified lines | ||
| 267 | 276 | |
| 268 | 277 | xe_gt_tlb_invalidation_fence_init(gt, &fence, true); |
| 269 | 278 | ret = xe_gt_tlb_invalidation_guc(gt, &fence); |
| 270 | − if (ret < 0) { | |
| 271 | − xe_gt_tlb_invalidation_fence_fini(&fence); | |
| 279 | + if (ret) | |
| 272 | 280 | return ret; |
| 273 | − } | |
| 274 | 281 | |
| 275 | 282 | xe_gt_tlb_invalidation_fence_wait(&fence); |
| 276 | 283 | } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) { |
| @@ -496,7 +503,8 @@ static const struct dma_fence_ops invalidation_fence_ops = { · 219 unmodified lines | ||
| 496 | 503 | * @stack: fence is stack variable |
| 497 | 504 | * |
| 498 | 505 | * Initialize TLB invalidation fence for use. xe_gt_tlb_invalidation_fence_fini |
| 499 | − * must be called if fence is not signaled. | |
| 506 | + * will be automatically called when fence is signalled (all fences must signal), | |
| 507 | + * even on error. | |
| 500 | 508 | */ |
| 501 | 509 | void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, |
| 502 | 510 | struct xe_gt_tlb_invalidation_fence *fence, |
| @@ -516,14 +524,3 @@ void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, · 13 unmodified lines | ||
| 516 | 524 | dma_fence_get(&fence->base); |
| 517 | 525 | fence->gt = gt; |
| 518 | 526 | } |
| 519 | − | |
| 520 | −/** | |
| 521 | − * xe_gt_tlb_invalidation_fence_fini - Finalize TLB invalidation fence | |
| 522 | − * @fence: TLB invalidation fence to finalize | |
| 523 | − * | |
| 524 | − * Drop PM ref which fence took durinig init. | |
| 525 | − */ | |
| 526 | −void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence) | |
| 527 | −{ | |
| 528 | − xe_pm_runtime_put(gt_to_xe(fence->gt)); | |
| 529 | −} | |
| @@ -28,7 +28,6 @@ int xe_guc_tlb_invalidation_done_handler(struct xe_guc *guc, u32 *msg, u32 len); · 27 unmodified lines | ||
| 28 | 28 | void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, |
| 29 | 29 | struct xe_gt_tlb_invalidation_fence *fence, |
| 30 | 30 | bool stack); |
| 31 | −void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence); | |
| 32 | 31 | |
| 33 | 32 | static inline void |
| 34 | 33 | xe_gt_tlb_invalidation_fence_wait(struct xe_gt_tlb_invalidation_fence *fence) |
| @@ -667,16 +667,12 @@ static int __guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action, · 666 unmodified lines | ||
| 667 | 667 | num_g2h = 1; |
| 668 | 668 | |
| 669 | 669 | if (g2h_fence_needs_alloc(g2h_fence)) { |
| 670 | − void *ptr; | |
| 671 | − | |
| 672 | 670 | g2h_fence->seqno = next_ct_seqno(ct, true); |
| 673 | − ptr = xa_store(&ct->fence_lookup, | |
| 674 | − g2h_fence->seqno, | |
| 675 | − g2h_fence, GFP_ATOMIC); | |
| 676 | − if (IS_ERR(ptr)) { | |
| 677 | − ret = PTR_ERR(ptr); | |
| 671 | + ret = xa_err(xa_store(&ct->fence_lookup, | |
| 672 | + g2h_fence->seqno, g2h_fence, | |
| 673 | + GFP_ATOMIC)); | |
| 674 | + if (ret) | |
| 678 | 675 | goto out; |
| 679 | − } | |
| 680 | 676 | } |
| 681 | 677 | |
| 682 | 678 | seqno = g2h_fence->seqno; |
| @@ -879,14 +875,11 @@ retry: · 196 unmodified lines | ||
| 879 | 875 | retry_same_fence: |
| 880 | 876 | ret = guc_ct_send(ct, action, len, 0, 0, &g2h_fence); |
| 881 | 877 | if (unlikely(ret == -ENOMEM)) { |
| 882 | − void *ptr; | |
| 883 | − | |
| 884 | 878 | /* Retry allocation /w GFP_KERNEL */ |
| 885 | − ptr = xa_store(&ct->fence_lookup, | |
| 886 | − g2h_fence.seqno, | |
| 887 | − &g2h_fence, GFP_KERNEL); | |
| 888 | − if (IS_ERR(ptr)) | |
| 889 | − return PTR_ERR(ptr); | |
| 879 | + ret = xa_err(xa_store(&ct->fence_lookup, g2h_fence.seqno, | |
| 880 | + &g2h_fence, GFP_KERNEL)); | |
| 881 | + if (ret) | |
| 882 | + return ret; | |
| 890 | 883 | |
| 891 | 884 | goto retry_same_fence; |
| 892 | 885 | } else if (unlikely(ret)) { |
| @@ -903,16 +896,26 @@ retry_same_fence: · 10 unmodified lines | ||
| 903 | 896 | } |
| 904 | 897 | |
| 905 | 898 | ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ); |
| 899 | + | |
| 900 | + /* | |
| 901 | + * Ensure we serialize with completion side to prevent UAF with fence going out of scope on | |
| 902 | + * the stack, since we have no clue if it will fire after the timeout before we can erase | |
| 903 | + * from the xa. Also we have some dependent loads and stores below for which we need the | |
| 904 | + * correct ordering, and we lack the needed barriers. | |
| 905 | + */ | |
| 906 | + mutex_lock(&ct->lock); | |
| 906 | 907 | if (!ret) { |
| 907 | − xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x", | |
| 908 | − g2h_fence.seqno, action[0]); | |
| 908 | + xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x, done %s", | |
| 909 | + g2h_fence.seqno, action[0], str_yes_no(g2h_fence.done)); | |
| 909 | 910 | xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno); |
| 911 | + mutex_unlock(&ct->lock); | |
| 910 | 912 | return -ETIME; |
| 911 | 913 | } |
| 912 | 914 | |
| 913 | 915 | if (g2h_fence.retry) { |
| 914 | 916 | xe_gt_dbg(gt, "H2G action %#x retrying: reason %#x\n", |
| 915 | 917 | action[0], g2h_fence.reason); |
| 918 | + mutex_unlock(&ct->lock); | |
| 916 | 919 | goto retry; |
| 917 | 920 | } |
| 918 | 921 | if (g2h_fence.fail) { |
| @@ -921,7 +924,12 @@ retry_same_fence: · 2 unmodified lines | ||
| 921 | 924 | ret = -EIO; |
| 922 | 925 | } |
| 923 | 926 | |
| 924 | − return ret > 0 ? response_buffer ? g2h_fence.response_len : g2h_fence.response_data : ret; | |
| 927 | + if (ret > 0) | |
| 928 | + ret = response_buffer ? g2h_fence.response_len : g2h_fence.response_data; | |
| 929 | + | |
| 930 | + mutex_unlock(&ct->lock); | |
| 931 | + | |
| 932 | + return ret; | |
| 925 | 933 | } |
| 926 | 934 | |
| 927 | 935 | /** |
| @@ -224,64 +224,11 @@ static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q) · 223 unmodified lines | ||
| 224 | 224 | EXEC_QUEUE_STATE_BANNED)); |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | −#ifdef CONFIG_PROVE_LOCKING | |
| 228 | −static int alloc_submit_wq(struct xe_guc *guc) | |
| 229 | −{ | |
| 230 | − int i; | |
| 231 | − | |
| 232 | − for (i = 0; i < NUM_SUBMIT_WQ; ++i) { | |
| 233 | − guc->submission_state.submit_wq_pool[i] = | |
| 234 | − alloc_ordered_workqueue("submit_wq", 0); | |
| 235 | − if (!guc->submission_state.submit_wq_pool[i]) | |
| 236 | − goto err_free; | |
| 237 | − } | |
| 238 | − | |
| 239 | − return 0; | |
| 240 | − | |
| 241 | −err_free: | |
| 242 | − while (i) | |
| 243 | − destroy_workqueue(guc->submission_state.submit_wq_pool[--i]); | |
| 244 | − | |
| 245 | − return -ENOMEM; | |
| 246 | −} | |
| 247 | − | |
| 248 | −static void free_submit_wq(struct xe_guc *guc) | |
| 249 | −{ | |
| 250 | − int i; | |
| 251 | − | |
| 252 | − for (i = 0; i < NUM_SUBMIT_WQ; ++i) | |
| 253 | − destroy_workqueue(guc->submission_state.submit_wq_pool[i]); | |
| 254 | −} | |
| 255 | − | |
| 256 | −static struct workqueue_struct *get_submit_wq(struct xe_guc *guc) | |
| 257 | −{ | |
| 258 | − int idx = guc->submission_state.submit_wq_idx++ % NUM_SUBMIT_WQ; | |
| 259 | − | |
| 260 | − return guc->submission_state.submit_wq_pool[idx]; | |
| 261 | −} | |
| 262 | −#else | |
| 263 | −static int alloc_submit_wq(struct xe_guc *guc) | |
| 264 | −{ | |
| 265 | − return 0; | |
| 266 | −} | |
| 267 | − | |
| 268 | −static void free_submit_wq(struct xe_guc *guc) | |
| 269 | −{ | |
| 270 | − | |
| 271 | −} | |
| 272 | − | |
| 273 | −static struct workqueue_struct *get_submit_wq(struct xe_guc *guc) | |
| 274 | −{ | |
| 275 | − return NULL; | |
| 276 | −} | |
| 277 | −#endif | |
| 278 | − | |
| 279 | 227 | static void guc_submit_fini(struct drm_device *drm, void *arg) |
| 280 | 228 | { |
| 281 | 229 | struct xe_guc *guc = arg; |
| 282 | 230 | |
| 283 | 231 | xa_destroy(&guc->submission_state.exec_queue_lookup); |
| 284 | − free_submit_wq(guc); | |
| 285 | 232 | } |
| 286 | 233 | |
| 287 | 234 | static void guc_submit_wedged_fini(void *arg) |
| @@ -290,9 +237,15 @@ static void guc_submit_wedged_fini(void *arg) · 2 unmodified lines | ||
| 290 | 237 | struct xe_exec_queue *q; |
| 291 | 238 | unsigned long index; |
| 292 | 239 | |
| 293 | − xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) | |
| 294 | − if (exec_queue_wedged(q)) | |
| 240 | + mutex_lock(&guc->submission_state.lock); | |
| 241 | + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { | |
| 242 | + if (exec_queue_wedged(q)) { | |
| 243 | + mutex_unlock(&guc->submission_state.lock); | |
| 295 | 244 | xe_exec_queue_put(q); |
| 245 | + mutex_lock(&guc->submission_state.lock); | |
| 246 | + } | |
| 247 | + } | |
| 248 | + mutex_unlock(&guc->submission_state.lock); | |
| 296 | 249 | } |
| 297 | 250 | |
| 298 | 251 | static const struct xe_exec_queue_ops guc_exec_queue_ops; |
| @@ -337,14 +290,12 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids) · 38 unmodified lines | ||
| 337 | 290 | if (err) |
| 338 | 291 | return err; |
| 339 | 292 | |
| 340 | − err = alloc_submit_wq(guc); | |
| 341 | − if (err) | |
| 342 | − return err; | |
| 343 | − | |
| 344 | 293 | gt->exec_queue_ops = &guc_exec_queue_ops; |
| 345 | 294 | |
| 346 | 295 | xa_init(&guc->submission_state.exec_queue_lookup); |
| 347 | 296 | |
| 297 | + init_waitqueue_head(&guc->submission_state.fini_wq); | |
| 298 | + | |
| 348 | 299 | primelockdep(guc); |
| 349 | 300 | |
| 350 | 301 | return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc); |
| @@ -361,12 +312,14 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa · 10 unmodified lines | ||
| 361 | 312 | |
| 362 | 313 | xe_guc_id_mgr_release_locked(&guc->submission_state.idm, |
| 363 | 314 | q->guc->id, q->width); |
| 315 | + | |
| 316 | + if (xa_empty(&guc->submission_state.exec_queue_lookup)) | |
| 317 | + wake_up(&guc->submission_state.fini_wq); | |
| 364 | 318 | } |
| 365 | 319 | |
| 366 | 320 | static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q) |
| 367 | 321 | { |
| 368 | 322 | int ret; |
| 369 | − void *ptr; | |
| 370 | 323 | int i; |
| 371 | 324 | |
| 372 | 325 | /* |
| @@ -386,12 +339,10 @@ static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q) · 13 unmodified lines | ||
| 386 | 339 | q->guc->id = ret; |
| 387 | 340 | |
| 388 | 341 | for (i = 0; i < q->width; ++i) { |
| 389 | − ptr = xa_store(&guc->submission_state.exec_queue_lookup, | |
| 390 | − q->guc->id + i, q, GFP_NOWAIT); | |
| 391 | − if (IS_ERR(ptr)) { | |
| 392 | − ret = PTR_ERR(ptr); | |
| 342 | + ret = xa_err(xa_store(&guc->submission_state.exec_queue_lookup, | |
| 343 | + q->guc->id + i, q, GFP_NOWAIT)); | |
| 344 | + if (ret) | |
| 393 | 345 | goto err_release; |
| 394 | − } | |
| 395 | 346 | } |
| 396 | 347 | |
| 397 | 348 | return 0; |
| @@ -1079,10 +1030,13 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job) · 681 unmodified lines | ||
| 1079 | 1030 | |
| 1080 | 1031 | /* |
| 1081 | 1032 | * TDR has fired before free job worker. Common if exec queue |
| 1082 | − * immediately closed after last fence signaled. | |
| 1033 | + * immediately closed after last fence signaled. Add back to pending | |
| 1034 | + * list so job can be freed and kick scheduler ensuring free job is not | |
| 1035 | + * lost. | |
| 1083 | 1036 | */ |
| 1084 | 1037 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &job->fence->flags)) { |
| 1085 | − guc_exec_queue_free_job(drm_job); | |
| 1038 | + xe_sched_add_pending_job(sched, job); | |
| 1039 | + xe_sched_submission_start(sched); | |
| 1086 | 1040 | |
| 1087 | 1041 | return DRM_GPU_SCHED_STAT_NOMINAL; |
| 1088 | 1042 | } |
| @@ -1268,13 +1222,16 @@ static void __guc_exec_queue_fini_async(struct work_struct *w) · 179 unmodified lines | ||
| 1268 | 1222 | |
| 1269 | 1223 | static void guc_exec_queue_fini_async(struct xe_exec_queue *q) |
| 1270 | 1224 | { |
| 1225 | + struct xe_guc *guc = exec_queue_to_guc(q); | |
| 1226 | + struct xe_device *xe = guc_to_xe(guc); | |
| 1227 | + | |
| 1271 | 1228 | INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async); |
| 1272 | 1229 | |
| 1273 | 1230 | /* We must block on kernel engines so slabs are empty on driver unload */ |
| 1274 | 1231 | if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q)) |
| 1275 | 1232 | __guc_exec_queue_fini_async(&q->guc->fini_async); |
| 1276 | 1233 | else |
| 1277 | − queue_work(system_wq, &q->guc->fini_async); | |
| 1234 | + queue_work(xe->destroy_wq, &q->guc->fini_async); | |
| 1278 | 1235 | } |
| 1279 | 1236 | |
| 1280 | 1237 | static void __guc_exec_queue_fini(struct xe_guc *guc, struct xe_exec_queue *q) |
| @@ -1452,8 +1409,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q) · 171 unmodified lines | ||
| 1452 | 1409 | timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT : |
| 1453 | 1410 | msecs_to_jiffies(q->sched_props.job_timeout_ms); |
| 1454 | 1411 | err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops, |
| 1455 | − get_submit_wq(guc), | |
| 1456 | − q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64, | |
| 1412 | + NULL, q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64, | |
| 1457 | 1413 | timeout, guc_to_gt(guc)->ordered_wq, NULL, |
| 1458 | 1414 | q->name, gt_to_xe(q->gt)->drm.dev); |
| 1459 | 1415 | if (err) |
| @@ -1796,6 +1752,7 @@ static void guc_exec_queue_start(struct xe_exec_queue *q) · 336 unmodified lines | ||
| 1796 | 1752 | } |
| 1797 | 1753 | |
| 1798 | 1754 | xe_sched_submission_start(sched); |
| 1755 | + xe_sched_submission_resume_tdr(sched); | |
| 1799 | 1756 | } |
| 1800 | 1757 | |
| 1801 | 1758 | int xe_guc_submit_start(struct xe_guc *guc) |
| @@ -72,15 +72,10 @@ struct xe_guc { · 71 unmodified lines | ||
| 72 | 72 | atomic_t stopped; |
| 73 | 73 | /** @submission_state.lock: protects submission state */ |
| 74 | 74 | struct mutex lock; |
| 75 | −#ifdef CONFIG_PROVE_LOCKING | |
| 76 | −#define NUM_SUBMIT_WQ 256 | |
| 77 | − /** @submission_state.submit_wq_pool: submission ordered workqueues pool */ | |
| 78 | − struct workqueue_struct *submit_wq_pool[NUM_SUBMIT_WQ]; | |
| 79 | − /** @submission_state.submit_wq_idx: submission ordered workqueue index */ | |
| 80 | − int submit_wq_idx; | |
| 81 | −#endif | |
| 82 | 75 | /** @submission_state.enabled: submission is enabled */ |
| 83 | 76 | bool enabled; |
| 77 | + /** @submission_state.fini_wq: submit fini wait queue */ | |
| 78 | + wait_queue_head_t fini_wq; | |
| 84 | 79 | } submission_state; |
| 85 | 80 | /** @hwconfig: Hardware config state */ |
| 86 | 81 | struct { |
| @@ -709,8 +709,7 @@ static int xe_oa_configure_oar_context(struct xe_oa_stream *stream, bool enable) · 708 unmodified lines | ||
| 709 | 709 | { |
| 710 | 710 | RING_CONTEXT_CONTROL(stream->hwe->mmio_base), |
| 711 | 711 | regs_offset + CTX_CONTEXT_CONTROL, |
| 712 | − _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE, | |
| 713 | − enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) | |
| 712 | + _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE), | |
| 714 | 713 | }, |
| 715 | 714 | }; |
| 716 | 715 | struct xe_oa_reg reg_lri = { OAR_OACONTROL, oacontrol }; |
| @@ -742,10 +741,8 @@ static int xe_oa_configure_oac_context(struct xe_oa_stream *stream, bool enable) · 25 unmodified lines | ||
| 742 | 741 | { |
| 743 | 742 | RING_CONTEXT_CONTROL(stream->hwe->mmio_base), |
| 744 | 743 | regs_offset + CTX_CONTEXT_CONTROL, |
| 745 | − _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE, | |
| 746 | − enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) | | |
| 747 | − _MASKED_FIELD(CTX_CTRL_RUN_ALONE, | |
| 748 | − enable ? CTX_CTRL_RUN_ALONE : 0), | |
| 744 | + _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE) | | |
| 745 | + _MASKED_FIELD(CTX_CTRL_RUN_ALONE, enable ? CTX_CTRL_RUN_ALONE : 0), | |
| 749 | 746 | }, |
| 750 | 747 | }; |
| 751 | 748 | struct xe_oa_reg reg_lri = { OAC_OACONTROL, oacontrol }; |
| @@ -924,6 +924,8 @@ static int xe_pci_resume(struct device *dev) · 923 unmodified lines | ||
| 924 | 924 | if (err) |
| 925 | 925 | return err; |
| 926 | 926 | |
| 927 | + pci_restore_state(pdev); | |
| 928 | + | |
| 927 | 929 | err = pci_enable_device(pdev); |
| 928 | 930 | if (err) |
| 929 | 931 | return err; |
| @@ -2188,5 +2188,5 @@ void xe_pt_update_ops_abort(struct xe_tile *tile, struct xe_vma_ops *vops) · 2187 unmodified lines | ||
| 2188 | 2188 | pt_op->num_entries); |
| 2189 | 2189 | } |
| 2190 | 2190 | |
| 2191 | − xe_bo_put_commit(&vops->pt_update_ops[tile->id].deferred); | |
| 2191 | + xe_pt_update_ops_fini(tile, vops); | |
| 2192 | 2192 | } |
| @@ -161,7 +161,11 @@ query_engine_cycles(struct xe_device *xe, · 160 unmodified lines | ||
| 161 | 161 | cpu_clock); |
| 162 | 162 | |
| 163 | 163 | xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); |
| 164 | − resp.width = 36; | |
| 164 | + | |
| 165 | + if (GRAPHICS_VER(xe) >= 20) | |
| 166 | + resp.width = 64; | |
| 167 | + else | |
| 168 | + resp.width = 36; | |
| 165 | 169 | |
| 166 | 170 | /* Only write to the output fields of user query */ |
| 167 | 171 | if (put_user(resp.cpu_timestamp, &query_ptr->cpu_timestamp)) |
| @@ -58,7 +58,7 @@ static struct xe_user_fence *user_fence_create(struct xe_device *xe, u64 addr, · 57 unmodified lines | ||
| 58 | 58 | if (!access_ok(ptr, sizeof(*ptr))) |
| 59 | 59 | return ERR_PTR(-EFAULT); |
| 60 | 60 | |
| 61 | − ufence = kmalloc(sizeof(*ufence), GFP_KERNEL); | |
| 61 | + ufence = kzalloc(sizeof(*ufence), GFP_KERNEL); | |
| 62 | 62 | if (!ufence) |
| 63 | 63 | return ERR_PTR(-ENOMEM); |
| 64 | 64 | |
| @@ -42,20 +42,48 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { · 41 unmodified lines | ||
| 42 | 42 | XE_RTP_ACTIONS(CLR(CCCHKNREG1, ENCOMPPERFFIX), |
| 43 | 43 | SET(CCCHKNREG1, L3CMPCTRL)) |
| 44 | 44 | }, |
| 45 | + { XE_RTP_NAME("Tuning: Compression Overfetch - media"), | |
| 46 | + XE_RTP_RULES(MEDIA_VERSION(2000)), | |
| 47 | + XE_RTP_ACTIONS(CLR(XE2LPM_CCCHKNREG1, ENCOMPPERFFIX), | |
| 48 | + SET(XE2LPM_CCCHKNREG1, L3CMPCTRL)) | |
| 49 | + }, | |
| 45 | 50 | { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3"), |
| 46 | 51 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), |
| 47 | 52 | XE_RTP_ACTIONS(SET(L3SQCREG3, COMPPWOVERFETCHEN)) |
| 48 | 53 | }, |
| 54 | + { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3 - media"), | |
| 55 | + XE_RTP_RULES(MEDIA_VERSION(2000)), | |
| 56 | + XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG3, COMPPWOVERFETCHEN)) | |
| 57 | + }, | |
| 49 | 58 | { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only"), |
| 50 | 59 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), |
| 51 | 60 | XE_RTP_ACTIONS(SET(L3SQCREG2, |
| 52 | 61 | COMPMEMRD256BOVRFETCHEN)) |
| 53 | 62 | }, |
| 63 | + { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only - media"), | |
| 64 | + XE_RTP_RULES(MEDIA_VERSION(2000)), | |
| 65 | + XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG2, | |
| 66 | + COMPMEMRD256BOVRFETCHEN)) | |
| 67 | + }, | |
| 54 | 68 | { XE_RTP_NAME("Tuning: Stateless compression control"), |
| 55 | 69 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), |
| 56 | 70 | XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, |
| 57 | 71 | REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) |
| 58 | 72 | }, |
| 73 | + { XE_RTP_NAME("Tuning: Stateless compression control - media"), | |
| 74 | + XE_RTP_RULES(MEDIA_VERSION_RANGE(1301, 2000)), | |
| 75 | + XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, | |
| 76 | + REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) | |
| 77 | + }, | |
| 78 | + { XE_RTP_NAME("Tuning: L3 RW flush all Cache"), | |
| 79 | + XE_RTP_RULES(GRAPHICS_VERSION(2004)), | |
| 80 | + XE_RTP_ACTIONS(SET(SCRATCH3_LBCF, RWFLUSHALLEN)) | |
| 81 | + }, | |
| 82 | + { XE_RTP_NAME("Tuning: L3 RW flush all cache - media"), | |
| 83 | + XE_RTP_RULES(MEDIA_VERSION(2000)), | |
| 84 | + XE_RTP_ACTIONS(SET(XE2LPM_SCRATCH3_LBCF, RWFLUSHALLEN)) | |
| 85 | + }, | |
| 86 | + | |
| 59 | 87 | {} |
| 60 | 88 | }; |
| 61 | 89 | |
| @@ -1613,7 +1613,7 @@ void xe_vm_close_and_put(struct xe_vm *vm) · 1612 unmodified lines | ||
| 1613 | 1613 | |
| 1614 | 1614 | up_write(&vm->lock); |
| 1615 | 1615 | |
| 1616 | − mutex_lock(&xe->usm.lock); | |
| 1616 | + down_write(&xe->usm.lock); | |
| 1617 | 1617 | if (vm->usm.asid) { |
| 1618 | 1618 | void *lookup; |
| 1619 | 1619 | |
| @@ -1623,7 +1623,7 @@ void xe_vm_close_and_put(struct xe_vm *vm) · 3 unmodified lines | ||
| 1623 | 1623 | lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid); |
| 1624 | 1624 | xe_assert(xe, lookup == vm); |
| 1625 | 1625 | } |
| 1626 | − mutex_unlock(&xe->usm.lock); | |
| 1626 | + up_write(&xe->usm.lock); | |
| 1627 | 1627 | |
| 1628 | 1628 | for_each_tile(tile, xe, id) |
| 1629 | 1629 | xe_range_fence_tree_fini(&vm->rftree[id]); |
| @@ -1765,25 +1765,18 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, · 135 unmodified lines | ||
| 1765 | 1765 | if (IS_ERR(vm)) |
| 1766 | 1766 | return PTR_ERR(vm); |
| 1767 | 1767 | |
| 1768 | − mutex_lock(&xef->vm.lock); | |
| 1769 | − err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); | |
| 1770 | − mutex_unlock(&xef->vm.lock); | |
| 1771 | − if (err) | |
| 1772 | − goto err_close_and_put; | |
| 1773 | − | |
| 1774 | 1768 | if (xe->info.has_asid) { |
| 1775 | − mutex_lock(&xe->usm.lock); | |
| 1769 | + down_write(&xe->usm.lock); | |
| 1776 | 1770 | err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, |
| 1777 | 1771 | XA_LIMIT(1, XE_MAX_ASID - 1), |
| 1778 | 1772 | &xe->usm.next_asid, GFP_KERNEL); |
| 1779 | − mutex_unlock(&xe->usm.lock); | |
| 1773 | + up_write(&xe->usm.lock); | |
| 1780 | 1774 | if (err < 0) |
| 1781 | − goto err_free_id; | |
| 1775 | + goto err_close_and_put; | |
| 1782 | 1776 | |
| 1783 | 1777 | vm->usm.asid = asid; |
| 1784 | 1778 | } |
| 1785 | 1779 | |
| 1786 | − args->vm_id = id; | |
| 1787 | 1780 | vm->xef = xe_file_get(xef); |
| 1788 | 1781 | |
| 1789 | 1782 | /* Record BO memory for VM pagetable created against client */ |
| @@ -1796,12 +1789,15 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, · 6 unmodified lines | ||
| 1796 | 1789 | args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE); |
| 1797 | 1790 | #endif |
| 1798 | 1791 | |
| 1792 | + /* user id alloc must always be last in ioctl to prevent UAF */ | |
| 1793 | + err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); | |
| 1794 | + if (err) | |
| 1795 | + goto err_close_and_put; | |
| 1796 | + | |
| 1797 | + args->vm_id = id; | |
| 1798 | + | |
| 1799 | 1799 | return 0; |
| 1800 | 1800 | |
| 1801 | −err_free_id: | |
| 1802 | − mutex_lock(&xef->vm.lock); | |
| 1803 | − xa_erase(&xef->vm.xa, id); | |
| 1804 | − mutex_unlock(&xef->vm.lock); | |
| 1805 | 1801 | err_close_and_put: |
| 1806 | 1802 | xe_vm_close_and_put(vm); |
| 1807 | 1803 | |
| @@ -3203,10 +3199,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma) · 1395 unmodified lines | ||
| 3203 | 3199 | |
| 3204 | 3200 | ret = xe_gt_tlb_invalidation_vma(tile->primary_gt, |
| 3205 | 3201 | &fence[fence_id], vma); |
| 3206 | − if (ret < 0) { | |
| 3207 | − xe_gt_tlb_invalidation_fence_fini(&fence[fence_id]); | |
| 3202 | + if (ret) | |
| 3208 | 3203 | goto wait; |
| 3209 | − } | |
| 3210 | 3204 | ++fence_id; |
| 3211 | 3205 | |
| 3212 | 3206 | if (!tile->media_gt) |
| @@ -3218,10 +3212,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma) · 5 unmodified lines | ||
| 3218 | 3212 | |
| 3219 | 3213 | ret = xe_gt_tlb_invalidation_vma(tile->media_gt, |
| 3220 | 3214 | &fence[fence_id], vma); |
| 3221 | − if (ret < 0) { | |
| 3222 | − xe_gt_tlb_invalidation_fence_fini(&fence[fence_id]); | |
| 3215 | + if (ret) | |
| 3223 | 3216 | goto wait; |
| 3224 | − } | |
| 3225 | 3217 | ++fence_id; |
| 3226 | 3218 | } |
| 3227 | 3219 | } |
| @@ -710,6 +710,10 @@ static const struct xe_rtp_entry_sr lrc_was[] = { · 709 unmodified lines | ||
| 710 | 710 | DIS_PARTIAL_AUTOSTRIP | |
| 711 | 711 | DIS_AUTOSTRIP)) |
| 712 | 712 | }, |
| 713 | + { XE_RTP_NAME("15016589081"), | |
| 714 | + XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)), | |
| 715 | + XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX)) | |
| 716 | + }, | |
| 713 | 717 | |
| 714 | 718 | /* Xe2_HPG */ |
| 715 | 719 | { XE_RTP_NAME("15010599737"), |
| @@ -169,9 +169,6 @@ int xe_wait_user_fence_ioctl(struct drm_device *dev, void *data, · 168 unmodified lines | ||
| 169 | 169 | args->timeout = 0; |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | − if (!timeout && !(err < 0)) | |
| 173 | − err = -ETIME; | |
| 174 | − | |
| 175 | 172 | if (q) |
| 176 | 173 | xe_exec_queue_put(q); |
| 177 | 174 | |
| @@ -58,6 +58,7 @@ int host1x_memory_context_list_init(struct host1x *host1x) · 57 unmodified lines | ||
| 58 | 58 | ctx->dev.parent = host1x->dev; |
| 59 | 59 | ctx->dev.release = host1x_memory_context_release; |
| 60 | 60 | |
| 61 | + ctx->dev.dma_parms = &ctx->dma_parms; | |
| 61 | 62 | dma_set_max_seg_size(&ctx->dev, UINT_MAX); |
| 62 | 63 | |
| 63 | 64 | err = device_add(&ctx->dev); |
| @@ -625,12 +625,6 @@ static int host1x_probe(struct platform_device *pdev) · 624 unmodified lines | ||
| 625 | 625 | goto free_contexts; |
| 626 | 626 | } |
| 627 | 627 | |
| 628 | − err = host1x_intr_init(host); | |
| 629 | − if (err) { | |
| 630 | − dev_err(&pdev->dev, "failed to initialize interrupts\n"); | |
| 631 | − goto deinit_syncpt; | |
| 632 | − } | |
| 633 | − | |
| 634 | 628 | pm_runtime_enable(&pdev->dev); |
| 635 | 629 | |
| 636 | 630 | err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); |
| @@ -642,6 +636,12 @@ static int host1x_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 642 | 636 | if (err) |
| 643 | 637 | goto pm_disable; |
| 644 | 638 | |
| 639 | + err = host1x_intr_init(host); | |
| 640 | + if (err) { | |
| 641 | + dev_err(&pdev->dev, "failed to initialize interrupts\n"); | |
| 642 | + goto pm_put; | |
| 643 | + } | |
| 644 | + | |
| 645 | 645 | host1x_debug_init(host); |
| 646 | 646 | |
| 647 | 647 | err = host1x_register(host); |
| @@ -658,13 +658,11 @@ unregister: · 10 unmodified lines | ||
| 658 | 658 | host1x_unregister(host); |
| 659 | 659 | deinit_debugfs: |
| 660 | 660 | host1x_debug_deinit(host); |
| 661 | − | |
| 661 | + host1x_intr_deinit(host); | |
| 662 | +pm_put: | |
| 662 | 663 | pm_runtime_put_sync_suspend(&pdev->dev); |
| 663 | 664 | pm_disable: |
| 664 | 665 | pm_runtime_disable(&pdev->dev); |
| 665 | − | |
| 666 | − host1x_intr_deinit(host); | |
| 667 | −deinit_syncpt: | |
| 668 | 666 | host1x_syncpt_deinit(host); |
| 669 | 667 | free_contexts: |
| 670 | 668 | host1x_memory_context_list_free(&host->context_list); |
| @@ -236,9 +236,9 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) · 235 unmodified lines | ||
| 236 | 236 | cl_data->in_data = in_data; |
| 237 | 237 | |
| 238 | 238 | for (i = 0; i < cl_data->num_hid_devices; i++) { |
| 239 | − in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8, | |
| 240 | − &cl_data->sensor_dma_addr[i], | |
| 241 | − GFP_KERNEL); | |
| 239 | + in_data->sensor_virt_addr[i] = dmam_alloc_coherent(dev, sizeof(int) * 8, | |
| 240 | + &cl_data->sensor_dma_addr[i], | |
| 241 | + GFP_KERNEL); | |
| 242 | 242 | if (!in_data->sensor_virt_addr[i]) { |
| 243 | 243 | rc = -ENOMEM; |
| 244 | 244 | goto cleanup; |
| @@ -331,7 +331,6 @@ cleanup: · 86 unmodified lines | ||
| 331 | 331 | int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) |
| 332 | 332 | { |
| 333 | 333 | struct amdtp_cl_data *cl_data = privdata->cl_data; |
| 334 | − struct amd_input_data *in_data = cl_data->in_data; | |
| 335 | 334 | int i, status; |
| 336 | 335 | |
| 337 | 336 | for (i = 0; i < cl_data->num_hid_devices; i++) { |
| @@ -351,12 +350,5 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) · 13 unmodified lines | ||
| 351 | 350 | cancel_delayed_work_sync(&cl_data->work_buffer); |
| 352 | 351 | amdtp_hid_remove(cl_data); |
| 353 | 352 | |
| 354 | − for (i = 0; i < cl_data->num_hid_devices; i++) { | |
| 355 | − if (in_data->sensor_virt_addr[i]) { | |
| 356 | − dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), | |
| 357 | − in_data->sensor_virt_addr[i], | |
| 358 | − cl_data->sensor_dma_addr[i]); | |
| 359 | − } | |
| 360 | − } | |
| 361 | 353 | return 0; |
| 362 | 354 | } |
| @@ -509,6 +509,7 @@ · 508 unmodified lines | ||
| 509 | 509 | #define I2C_DEVICE_ID_GOODIX_01E8 0x01e8 |
| 510 | 510 | #define I2C_DEVICE_ID_GOODIX_01E9 0x01e9 |
| 511 | 511 | #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 |
| 512 | +#define I2C_DEVICE_ID_GOODIX_0D42 0x0d42 | |
| 512 | 513 | |
| 513 | 514 | #define USB_VENDOR_ID_GOODTOUCH 0x1aad |
| 514 | 515 | #define USB_DEVICE_ID_GOODTOUCH_000f 0x000f |
| @@ -868,6 +869,7 @@ · 353 unmodified lines | ||
| 868 | 869 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539 |
| 869 | 870 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f |
| 870 | 871 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a |
| 872 | +#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548 | |
| 871 | 873 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 |
| 872 | 874 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 |
| 873 | 875 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 |
| @@ -1036,6 +1038,8 @@ · 162 unmodified lines | ||
| 1036 | 1038 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056 |
| 1037 | 1039 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057 |
| 1038 | 1040 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058 |
| 1041 | +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES 0x430c | |
| 1042 | +#define USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES 0x431e | |
| 1039 | 1043 | |
| 1040 | 1044 | #define USB_VENDOR_ID_PANASONIC 0x04da |
| 1041 | 1045 | #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 |
| @@ -473,6 +473,7 @@ static int lenovo_input_mapping(struct hid_device *hdev, · 472 unmodified lines | ||
| 473 | 473 | return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, |
| 474 | 474 | usage, bit, max); |
| 475 | 475 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 476 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 476 | 477 | return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); |
| 477 | 478 | default: |
| 478 | 479 | return 0; |
| @@ -583,6 +584,7 @@ static ssize_t attr_fn_lock_store(struct device *dev, · 104 unmodified lines | ||
| 583 | 584 | break; |
| 584 | 585 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 585 | 586 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 587 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 586 | 588 | ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); |
| 587 | 589 | if (ret) |
| 588 | 590 | return ret; |
| @@ -776,6 +778,7 @@ static int lenovo_event(struct hid_device *hdev, struct hid_field *field, · 187 unmodified lines | ||
| 776 | 778 | return lenovo_event_cptkbd(hdev, field, usage, value); |
| 777 | 779 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 778 | 780 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 781 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 779 | 782 | return lenovo_event_tp10ubkbd(hdev, field, usage, value); |
| 780 | 783 | default: |
| 781 | 784 | return 0; |
| @@ -1056,6 +1059,7 @@ static int lenovo_led_brightness_set(struct led_classdev *led_cdev, · 274 unmodified lines | ||
| 1056 | 1059 | break; |
| 1057 | 1060 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1058 | 1061 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1062 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 1059 | 1063 | ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); |
| 1060 | 1064 | break; |
| 1061 | 1065 | } |
| @@ -1286,6 +1290,7 @@ static int lenovo_probe(struct hid_device *hdev, · 224 unmodified lines | ||
| 1286 | 1290 | break; |
| 1287 | 1291 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1288 | 1292 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1293 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 1289 | 1294 | ret = lenovo_probe_tp10ubkbd(hdev); |
| 1290 | 1295 | break; |
| 1291 | 1296 | default: |
| @@ -1372,6 +1377,7 @@ static void lenovo_remove(struct hid_device *hdev) · 80 unmodified lines | ||
| 1372 | 1377 | break; |
| 1373 | 1378 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1374 | 1379 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1380 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 1375 | 1381 | lenovo_remove_tp10ubkbd(hdev); |
| 1376 | 1382 | break; |
| 1377 | 1383 | } |
| @@ -1421,6 +1427,8 @@ static const struct hid_device_id lenovo_devices[] = { · 43 unmodified lines | ||
| 1421 | 1427 | */ |
| 1422 | 1428 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 1423 | 1429 | USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB) }, |
| 1430 | + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | |
| 1431 | + USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB3) }, | |
| 1424 | 1432 | { } |
| 1425 | 1433 | }; |
| 1426 | 1434 | |
| @@ -2026,6 +2026,10 @@ static const struct hid_device_id mt_devices[] = { · 2025 unmodified lines | ||
| 2026 | 2026 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2027 | 2027 | USB_VENDOR_ID_ELAN, 0x3148) }, |
| 2028 | 2028 | |
| 2029 | + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, | |
| 2030 | + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | |
| 2031 | + USB_VENDOR_ID_ELAN, 0x32ae) }, | |
| 2032 | + | |
| 2029 | 2033 | /* Elitegroup panel */ |
| 2030 | 2034 | { .driver_data = MT_CLS_SERIAL, |
| 2031 | 2035 | MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP, |
| @@ -2095,6 +2099,11 @@ static const struct hid_device_id mt_devices[] = { · 63 unmodified lines | ||
| 2095 | 2099 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2096 | 2100 | 0x347d, 0x7853) }, |
| 2097 | 2101 | |
| 2102 | + /* HONOR MagicBook Art 14 touchpad */ | |
| 2103 | + { .driver_data = MT_CLS_VTL, | |
| 2104 | + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | |
| 2105 | + 0x35cc, 0x0104) }, | |
| 2106 | + | |
| 2098 | 2107 | /* Ilitek dual touch panel */ |
| 2099 | 2108 | { .driver_data = MT_CLS_NSMU, |
| 2100 | 2109 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, |
| @@ -2137,6 +2146,10 @@ static const struct hid_device_id mt_devices[] = { · 36 unmodified lines | ||
| 2137 | 2146 | HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8, |
| 2138 | 2147 | USB_VENDOR_ID_LOGITECH, |
| 2139 | 2148 | USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) }, |
| 2149 | + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, | |
| 2150 | + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, | |
| 2151 | + USB_VENDOR_ID_LOGITECH, | |
| 2152 | + USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER) }, | |
| 2140 | 2153 | |
| 2141 | 2154 | /* MosArt panels */ |
| 2142 | 2155 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
| @@ -38,8 +38,10 @@ · 37 unmodified lines | ||
| 38 | 38 | (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) |
| 39 | 39 | |
| 40 | 40 | #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0) |
| 41 | +#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1) | |
| 41 | 42 | |
| 42 | 43 | #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */ |
| 44 | +#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */ | |
| 43 | 45 | |
| 44 | 46 | struct plt_drv_data { |
| 45 | 47 | unsigned long device_type; |
| @@ -137,6 +139,21 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field, · 91 unmodified lines | ||
| 137 | 139 | |
| 138 | 140 | drv_data->last_volume_key_ts = cur_ts; |
| 139 | 141 | } |
| 142 | + if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) { | |
| 143 | + unsigned long prev_ts, cur_ts; | |
| 144 | + | |
| 145 | + /* Usages are filtered in plantronics_usages. */ | |
| 146 | + | |
| 147 | + if (!value) /* Handle key presses only. */ | |
| 148 | + return 0; | |
| 149 | + | |
| 150 | + prev_ts = drv_data->last_volume_key_ts; | |
| 151 | + cur_ts = jiffies; | |
| 152 | + if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT) | |
| 153 | + return 1; /* Ignore the followed opposite volume key. */ | |
| 154 | + | |
| 155 | + drv_data->last_volume_key_ts = cur_ts; | |
| 156 | + } | |
| 140 | 157 | |
| 141 | 158 | return 0; |
| 142 | 159 | } |
| @@ -210,6 +227,12 @@ static const struct hid_device_id plantronics_devices[] = { · 67 unmodified lines | ||
| 210 | 227 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, |
| 211 | 228 | USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES), |
| 212 | 229 | .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, |
| 230 | + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, | |
| 231 | + USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES), | |
| 232 | + .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS }, | |
| 233 | + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, | |
| 234 | + USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES), | |
| 235 | + .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS }, | |
| 213 | 236 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, |
| 214 | 237 | { } |
| 215 | 238 | }; |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3) |
| 51 | 51 | #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4) |
| 52 | 52 | #define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND BIT(5) |
| 53 | +#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME BIT(6) | |
| 53 | 54 | |
| 54 | 55 | /* Command opcodes */ |
| 55 | 56 | #define I2C_HID_OPCODE_RESET 0x01 |
| @@ -140,6 +141,8 @@ static const struct i2c_hid_quirks { · 84 unmodified lines | ||
| 140 | 141 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, |
| 141 | 142 | I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | |
| 142 | 143 | I2C_HID_QUIRK_BOGUS_IRQ }, |
| 144 | + { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42, | |
| 145 | + I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME }, | |
| 143 | 146 | { 0, 0 } |
| 144 | 147 | }; |
| 145 | 148 | |
| @@ -981,6 +984,13 @@ static int i2c_hid_core_resume(struct i2c_hid *ihid) · 835 unmodified lines | ||
| 981 | 984 | return -ENXIO; |
| 982 | 985 | } |
| 983 | 986 | |
| 987 | + /* On Goodix 27c6:0d42 wait extra time before device wakeup. | |
| 988 | + * It's not clear why but if we send wakeup too early, the device will | |
| 989 | + * never trigger input interrupts. | |
| 990 | + */ | |
| 991 | + if (ihid->quirks & I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME) | |
| 992 | + msleep(1500); | |
| 993 | + | |
| 984 | 994 | /* Instead of resetting device, simply powers the device on. This |
| 985 | 995 | * solves "incomplete reports" on Raydium devices 2386:3118 and |
| 986 | 996 | * 2386:4B33 and fixes various SIS touchscreens no longer sending |
| @@ -635,7 +635,7 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data, · 634 unmodified lines | ||
| 635 | 635 | const struct firmware *fw, |
| 636 | 636 | const struct shim_fw_info fw_info) |
| 637 | 637 | { |
| 638 | − int rv; | |
| 638 | + int rv = 0; | |
| 639 | 639 | void *dma_buf; |
| 640 | 640 | dma_addr_t dma_buf_phy; |
| 641 | 641 | u32 fragment_offset, fragment_size, payload_max_size; |
| @@ -2567,6 +2567,8 @@ static void wacom_wac_pen_report(struct hid_device *hdev, · 2566 unmodified lines | ||
| 2567 | 2567 | /* Going into range select tool */ |
| 2568 | 2568 | if (wacom_wac->hid_data.invert_state) |
| 2569 | 2569 | wacom_wac->tool[0] = BTN_TOOL_RUBBER; |
| 2570 | + else if (wacom_wac->features.quirks & WACOM_QUIRK_AESPEN) | |
| 2571 | + wacom_wac->tool[0] = BTN_TOOL_PEN; | |
| 2570 | 2572 | else if (wacom_wac->id[0]) |
| 2571 | 2573 | wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]); |
| 2572 | 2574 | else |
| @@ -162,6 +162,7 @@ config SENSORS_ADM9240 · 161 unmodified lines | ||
| 162 | 162 | tristate "Analog Devices ADM9240 and compatibles" |
| 163 | 163 | depends on I2C |
| 164 | 164 | select HWMON_VID |
| 165 | + select REGMAP_I2C | |
| 165 | 166 | help |
| 166 | 167 | If you say yes here you get support for Analog Devices ADM9240, |
| 167 | 168 | Dallas DS1780, National Semiconductor LM81 sensor chips. |
| @@ -223,6 +224,7 @@ config SENSORS_ADT7462 · 55 unmodified lines | ||
| 223 | 224 | config SENSORS_ADT7470 |
| 224 | 225 | tristate "Analog Devices ADT7470" |
| 225 | 226 | depends on I2C |
| 227 | + select REGMAP_I2C | |
| 226 | 228 | help |
| 227 | 229 | If you say yes here you get support for the Analog Devices |
| 228 | 230 | ADT7470 temperature monitoring chips. |
| @@ -999,6 +1001,7 @@ config SENSORS_LTC2990 · 770 unmodified lines | ||
| 999 | 1001 | config SENSORS_LTC2991 |
| 1000 | 1002 | tristate "Analog Devices LTC2991" |
| 1001 | 1003 | depends on I2C |
| 1004 | + select REGMAP_I2C | |
| 1002 | 1005 | help |
| 1003 | 1006 | If you say yes here you get support for Analog Devices LTC2991 |
| 1004 | 1007 | Octal I2C Voltage, Current, and Temperature Monitor. The LTC2991 |
| @@ -1146,6 +1149,7 @@ config SENSORS_MAX1619 · 141 unmodified lines | ||
| 1146 | 1149 | config SENSORS_MAX1668 |
| 1147 | 1150 | tristate "Maxim MAX1668 and compatibles" |
| 1148 | 1151 | depends on I2C |
| 1152 | + select REGMAP_I2C | |
| 1149 | 1153 | help |
| 1150 | 1154 | If you say yes here you get support for MAX1668, MAX1989 and |
| 1151 | 1155 | MAX1805 chips. |
| @@ -1275,6 +1279,7 @@ config SENSORS_MAX31790 · 123 unmodified lines | ||
| 1275 | 1279 | config SENSORS_MC34VR500 |
| 1276 | 1280 | tristate "NXP MC34VR500 hardware monitoring driver" |
| 1277 | 1281 | depends on I2C |
| 1282 | + select REGMAP_I2C | |
| 1278 | 1283 | help |
| 1279 | 1284 | If you say yes here you get support for the temperature and input |
| 1280 | 1285 | voltage sensors of the NXP MC34VR500. |
| @@ -2312,6 +2317,7 @@ config SENSORS_TMP464 · 1031 unmodified lines | ||
| 2312 | 2317 | config SENSORS_TMP513 |
| 2313 | 2318 | tristate "Texas Instruments TMP513 and compatibles" |
| 2314 | 2319 | depends on I2C |
| 2320 | + select REGMAP_I2C | |
| 2315 | 2321 | help |
| 2316 | 2322 | If you say yes here you get support for Texas Instruments TMP512, |
| 2317 | 2323 | and TMP513 temperature and power supply sensor chips. |
| @@ -1735,11 +1735,10 @@ static int adt7475_pwm_properties_parse_args(struct fwnode_handle *fwnode, · 1734 unmodified lines | ||
| 1735 | 1735 | static int adt7475_fan_pwm_config(struct i2c_client *client) |
| 1736 | 1736 | { |
| 1737 | 1737 | struct adt7475_data *data = i2c_get_clientdata(client); |
| 1738 | − struct fwnode_handle *child; | |
| 1739 | 1738 | struct adt7475_pwm_config cfg = {}; |
| 1740 | 1739 | int ret; |
| 1741 | 1740 | |
| 1742 | − device_for_each_child_node(&client->dev, child) { | |
| 1741 | + device_for_each_child_node_scoped(&client->dev, child) { | |
| 1743 | 1742 | if (!fwnode_property_present(child, "pwms")) |
| 1744 | 1743 | continue; |
| 1745 | 1744 | |
| @@ -358,7 +358,7 @@ static const struct m10bmc_sdata n6000bmc_temp_tbl[] = { · 357 unmodified lines | ||
| 358 | 358 | { 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" }, |
| 359 | 359 | { 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" }, |
| 360 | 360 | { 0x508, 0x50c, 0x510, 0x52c, 0x0, 500, "Board Top East Near VRs Temperature" }, |
| 361 | − { 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "Columbiaville Die Temperature" }, | |
| 361 | + { 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "CVL Die Temperature" }, | |
| 362 | 362 | { 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" }, |
| 363 | 363 | { 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" }, |
| 364 | 364 | { 0x53c, 0x540, 0x544, 0x0, 0x0, 500, "QSFP1 Case Temperature" }, |
| @@ -417,7 +417,7 @@ static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) · 416 unmodified lines | ||
| 417 | 417 | return -ENODEV; |
| 418 | 418 | |
| 419 | 419 | if ((devid & TSE2004_DEVID_MASK) == TSE2004_DEVID && |
| 420 | − (cap & 0x00e7) != 0x00e7) | |
| 420 | + (cap & 0x0062) != 0x0062) | |
| 421 | 421 | return -ENODEV; |
| 422 | 422 | |
| 423 | 423 | for (i = 0; i < ARRAY_SIZE(jc42_chips); i++) { |
| @@ -2395,7 +2395,7 @@ static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev) · 2394 unmodified lines | ||
| 2395 | 2395 | struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
| 2396 | 2396 | |
| 2397 | 2397 | if (!stm32f7_i2c_is_slave_registered(i2c_dev)) |
| 2398 | − clk_disable_unprepare(i2c_dev->clk); | |
| 2398 | + clk_disable(i2c_dev->clk); | |
| 2399 | 2399 | |
| 2400 | 2400 | return 0; |
| 2401 | 2401 | } |
| @@ -2406,9 +2406,9 @@ static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev) · 4 unmodified lines | ||
| 2406 | 2406 | int ret; |
| 2407 | 2407 | |
| 2408 | 2408 | if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { |
| 2409 | − ret = clk_prepare_enable(i2c_dev->clk); | |
| 2409 | + ret = clk_enable(i2c_dev->clk); | |
| 2410 | 2410 | if (ret) { |
| 2411 | − dev_err(dev, "failed to prepare_enable clock\n"); | |
| 2411 | + dev_err(dev, "failed to enable clock\n"); | |
| 2412 | 2412 | return ret; |
| 2413 | 2413 | } |
| 2414 | 2414 | } |
| @@ -447,6 +447,8 @@ config IIO_ST_ACCEL_SPI_3AXIS · 446 unmodified lines | ||
| 447 | 447 | |
| 448 | 448 | config IIO_KX022A |
| 449 | 449 | tristate |
| 450 | + select IIO_BUFFER | |
| 451 | + select IIO_TRIGGERED_BUFFER | |
| 450 | 452 | |
| 451 | 453 | config IIO_KX022A_SPI |
| 452 | 454 | tristate "Kionix KX022A tri-axis digital accelerometer SPI interface" |
| @@ -1218,7 +1218,8 @@ static int bma400_activity_event_en(struct bma400_data *data, · 1217 unmodified lines | ||
| 1218 | 1218 | static int bma400_tap_event_en(struct bma400_data *data, |
| 1219 | 1219 | enum iio_event_direction dir, int state) |
| 1220 | 1220 | { |
| 1221 | − unsigned int mask, field_value; | |
| 1221 | + unsigned int mask; | |
| 1222 | + unsigned int field_value = 0; | |
| 1222 | 1223 | int ret; |
| 1223 | 1224 | |
| 1224 | 1225 | /* |
| @@ -52,6 +52,8 @@ config AD4695 · 51 unmodified lines | ||
| 52 | 52 | tristate "Analog Device AD4695 ADC Driver" |
| 53 | 53 | depends on SPI |
| 54 | 54 | select REGMAP_SPI |
| 55 | + select IIO_BUFFER | |
| 56 | + select IIO_TRIGGERED_BUFFER | |
| 55 | 57 | help |
| 56 | 58 | Say yes here to build support for Analog Devices AD4695 and similar |
| 57 | 59 | analog to digital converters (ADC). |
| @@ -328,6 +330,8 @@ config AD7923 · 270 unmodified lines | ||
| 328 | 330 | config AD7944 |
| 329 | 331 | tristate "Analog Devices AD7944 and similar ADCs driver" |
| 330 | 332 | depends on SPI |
| 333 | + select IIO_BUFFER | |
| 334 | + select IIO_TRIGGERED_BUFFER | |
| 331 | 335 | help |
| 332 | 336 | Say yes here to build support for Analog Devices |
| 333 | 337 | AD7944, AD7985, AD7986 ADCs. |
| @@ -1481,6 +1485,8 @@ config TI_ADS8344 · 1147 unmodified lines | ||
| 1481 | 1485 | config TI_ADS8688 |
| 1482 | 1486 | tristate "Texas Instruments ADS8688" |
| 1483 | 1487 | depends on SPI |
| 1488 | + select IIO_BUFFER | |
| 1489 | + select IIO_TRIGGERED_BUFFER | |
| 1484 | 1490 | help |
| 1485 | 1491 | If you say yes here you get support for Texas Instruments ADS8684 and |
| 1486 | 1492 | and ADS8688 ADC chips |
| @@ -1491,6 +1497,8 @@ config TI_ADS8688 · 4 unmodified lines | ||
| 1491 | 1497 | config TI_ADS124S08 |
| 1492 | 1498 | tristate "Texas Instruments ADS124S08" |
| 1493 | 1499 | depends on SPI |
| 1500 | + select IIO_BUFFER | |
| 1501 | + select IIO_TRIGGERED_BUFFER | |
| 1494 | 1502 | help |
| 1495 | 1503 | If you say yes here you get support for Texas Instruments ADS124S08 |
| 1496 | 1504 | and ADS124S06 ADC chips |
| @@ -1525,6 +1533,9 @@ config TI_AM335X_ADC · 28 unmodified lines | ||
| 1525 | 1533 | config TI_LMP92064 |
| 1526 | 1534 | tristate "Texas Instruments LMP92064 ADC driver" |
| 1527 | 1535 | depends on SPI |
| 1536 | + select REGMAP_SPI | |
| 1537 | + select IIO_BUFFER | |
| 1538 | + select IIO_TRIGGERED_BUFFER | |
| 1528 | 1539 | help |
| 1529 | 1540 | Say yes here to build support for the LMP92064 Precision Current and Voltage |
| 1530 | 1541 | sensor. |
| @@ -27,6 +27,7 @@ config AD8366 · 26 unmodified lines | ||
| 27 | 27 | config ADA4250 |
| 28 | 28 | tristate "Analog Devices ADA4250 Instrumentation Amplifier" |
| 29 | 29 | depends on SPI |
| 30 | + select REGMAP_SPI | |
| 30 | 31 | help |
| 31 | 32 | Say yes here to build support for Analog Devices ADA4250 |
| 32 | 33 | SPI Amplifier's support. The driver provides direct access via |
| @@ -80,6 +80,8 @@ config ENS160 · 79 unmodified lines | ||
| 80 | 80 | tristate "ScioSense ENS160 sensor driver" |
| 81 | 81 | depends on (I2C || SPI) |
| 82 | 82 | select REGMAP |
| 83 | + select IIO_BUFFER | |
| 84 | + select IIO_TRIGGERED_BUFFER | |
| 83 | 85 | select ENS160_I2C if I2C |
| 84 | 86 | select ENS160_SPI if SPI |
| 85 | 87 | help |
| @@ -32,7 +32,7 @@ static ssize_t _hid_sensor_set_report_latency(struct device *dev, · 31 unmodified lines | ||
| 32 | 32 | latency = integer * 1000 + fract / 1000; |
| 33 | 33 | ret = hid_sensor_set_report_latency(attrb, latency); |
| 34 | 34 | if (ret < 0) |
| 35 | − return len; | |
| 35 | + return ret; | |
| 36 | 36 | |
| 37 | 37 | attrb->latency_ms = hid_sensor_get_report_latency(attrb); |
| 38 | 38 | |
| @@ -9,6 +9,8 @@ menu "Digital to analog converters" · 8 unmodified lines | ||
| 9 | 9 | config AD3552R |
| 10 | 10 | tristate "Analog Devices AD3552R DAC driver" |
| 11 | 11 | depends on SPI_MASTER |
| 12 | + select IIO_BUFFER | |
| 13 | + select IIO_TRIGGERED_BUFFER | |
| 12 | 14 | help |
| 13 | 15 | Say yes here to build support for Analog Devices AD3552R |
| 14 | 16 | Digital to Analog Converter. |
| @@ -252,6 +254,8 @@ config AD5764 · 237 unmodified lines | ||
| 252 | 254 | config AD5766 |
| 253 | 255 | tristate "Analog Devices AD5766/AD5767 DAC driver" |
| 254 | 256 | depends on SPI_MASTER |
| 257 | + select IIO_BUFFER | |
| 258 | + select IIO_TRIGGERED_BUFFER | |
| 255 | 259 | help |
| 256 | 260 | Say yes here to build support for Analog Devices AD5766, AD5767 |
| 257 | 261 | Digital to Analog Converter. |
| @@ -262,6 +266,7 @@ config AD5766 · 4 unmodified lines | ||
| 262 | 266 | config AD5770R |
| 263 | 267 | tristate "Analog Devices AD5770R IDAC driver" |
| 264 | 268 | depends on SPI_MASTER |
| 269 | + select REGMAP_SPI | |
| 265 | 270 | help |
| 266 | 271 | Say yes here to build support for Analog Devices AD5770R Digital to |
| 267 | 272 | Analog Converter. |
| @@ -353,6 +358,7 @@ config LPC18XX_DAC · 85 unmodified lines | ||
| 353 | 358 | config LTC1660 |
| 354 | 359 | tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver" |
| 355 | 360 | depends on SPI |
| 361 | + select REGMAP_SPI | |
| 356 | 362 | help |
| 357 | 363 | Say yes here to build support for Linear Technology |
| 358 | 364 | LTC1660 and LTC1665 Digital to Analog Converters. |
| @@ -483,6 +489,7 @@ config STM32_DAC · 124 unmodified lines | ||
| 483 | 489 | |
| 484 | 490 | config STM32_DAC_CORE |
| 485 | 491 | tristate |
| 492 | + select REGMAP_MMIO | |
| 486 | 493 | |
| 487 | 494 | config TI_DAC082S085 |
| 488 | 495 | tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver" |
| @@ -516,7 +516,7 @@ static int ltc2664_channel_config(struct ltc2664_state *st) · 515 unmodified lines | ||
| 516 | 516 | const struct ltc2664_chip_info *chip_info = st->chip_info; |
| 517 | 517 | struct device *dev = &st->spi->dev; |
| 518 | 518 | u32 reg, tmp[2], mspan; |
| 519 | − int ret, span = 0; | |
| 519 | + int ret; | |
| 520 | 520 | |
| 521 | 521 | mspan = LTC2664_MSPAN_SOFTSPAN; |
| 522 | 522 | ret = device_property_read_u32(dev, "adi,manual-span-operation-config", |
| @@ -579,20 +579,21 @@ static int ltc2664_channel_config(struct ltc2664_state *st) · 56 unmodified lines | ||
| 579 | 579 | ret = fwnode_property_read_u32_array(child, "output-range-microvolt", |
| 580 | 580 | tmp, ARRAY_SIZE(tmp)); |
| 581 | 581 | if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) { |
| 582 | − chan->span = ltc2664_set_span(st, tmp[0] / 1000, | |
| 583 | − tmp[1] / 1000, reg); | |
| 584 | − if (span < 0) | |
| 585 | − return dev_err_probe(dev, span, | |
| 582 | + ret = ltc2664_set_span(st, tmp[0] / 1000, tmp[1] / 1000, reg); | |
| 583 | + if (ret < 0) | |
| 584 | + return dev_err_probe(dev, ret, | |
| 586 | 585 | "Failed to set span\n"); |
| 586 | + chan->span = ret; | |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | 589 | ret = fwnode_property_read_u32_array(child, "output-range-microamp", |
| 590 | 590 | tmp, ARRAY_SIZE(tmp)); |
| 591 | 591 | if (!ret) { |
| 592 | − chan->span = ltc2664_set_span(st, 0, tmp[1] / 1000, reg); | |
| 593 | − if (span < 0) | |
| 594 | − return dev_err_probe(dev, span, | |
| 592 | + ret = ltc2664_set_span(st, 0, tmp[1] / 1000, reg); | |
| 593 | + if (ret < 0) | |
| 594 | + return dev_err_probe(dev, ret, | |
| 595 | 595 | "Failed to set span\n"); |
| 596 | + chan->span = ret; | |
| 596 | 597 | } |
| 597 | 598 | } |
| 598 | 599 | |
| @@ -53,6 +53,7 @@ config ADF4371 · 52 unmodified lines | ||
| 53 | 53 | config ADF4377 |
| 54 | 54 | tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer" |
| 55 | 55 | depends on SPI && COMMON_CLK |
| 56 | + select REGMAP_SPI | |
| 56 | 57 | help |
| 57 | 58 | Say yes here to build support for Analog Devices ADF4377 Microwave |
| 58 | 59 | Wideband Synthesizer. |
| @@ -91,25 +92,26 @@ config ADMV1014 · 32 unmodified lines | ||
| 91 | 92 | module will be called admv1014. |
| 92 | 93 | |
| 93 | 94 | config ADMV4420 |
| 94 | − tristate "Analog Devices ADMV4420 K Band Downconverter" | |
| 95 | − depends on SPI | |
| 96 | − help | |
| 97 | − Say yes here to build support for Analog Devices K Band | |
| 98 | − Downconverter with integrated Fractional-N PLL and VCO. | |
| 95 | + tristate "Analog Devices ADMV4420 K Band Downconverter" | |
| 96 | + depends on SPI | |
| 97 | + select REGMAP_SPI | |
| 98 | + help | |
| 99 | + Say yes here to build support for Analog Devices K Band | |
| 100 | + Downconverter with integrated Fractional-N PLL and VCO. | |
| 99 | 101 | |
| 100 | − To compile this driver as a module, choose M here: the | |
| 101 | − module will be called admv4420. | |
| 102 | + To compile this driver as a module, choose M here: the | |
| 103 | + module will be called admv4420. | |
| 102 | 104 | |
| 103 | 105 | config ADRF6780 |
| 104 | − tristate "Analog Devices ADRF6780 Microwave Upconverter" | |
| 105 | − depends on SPI | |
| 106 | − depends on COMMON_CLK | |
| 107 | − help | |
| 108 | − Say yes here to build support for Analog Devices ADRF6780 | |
| 109 | − 5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter. | |
| 110 | − | |
| 111 | − To compile this driver as a module, choose M here: the | |
| 112 | − module will be called adrf6780. | |
| 106 | + tristate "Analog Devices ADRF6780 Microwave Upconverter" | |
| 107 | + depends on SPI | |
| 108 | + depends on COMMON_CLK | |
| 109 | + help | |
| 110 | + Say yes here to build support for Analog Devices ADRF6780 | |
| 111 | + 5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter. | |
| 112 | + | |
| 113 | + To compile this driver as a module, choose M here: the | |
| 114 | + module will be called adrf6780. | |
| 113 | 115 | |
| 114 | 116 | endmenu |
| 115 | 117 | endmenu |
| @@ -2172,7 +2172,6 @@ int bmi323_core_probe(struct device *dev) · 2171 unmodified lines | ||
| 2172 | 2172 | } |
| 2173 | 2173 | EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); |
| 2174 | 2174 | |
| 2175 | −#if defined(CONFIG_PM) | |
| 2176 | 2175 | static int bmi323_core_runtime_suspend(struct device *dev) |
| 2177 | 2176 | { |
| 2178 | 2177 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
| @@ -2199,12 +2198,12 @@ static int bmi323_core_runtime_suspend(struct device *dev) · 20 unmodified lines | ||
| 2199 | 2198 | } |
| 2200 | 2199 | |
| 2201 | 2200 | for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { |
| 2202 | − ret = bmi323_read_ext_reg(data, bmi323_reg_savestate[i], | |
| 2203 | − &savestate->reg_settings[i]); | |
| 2201 | + ret = bmi323_read_ext_reg(data, bmi323_ext_reg_savestate[i], | |
| 2202 | + &savestate->ext_reg_settings[i]); | |
| 2204 | 2203 | if (ret) { |
| 2205 | 2204 | dev_err(data->dev, |
| 2206 | 2205 | "Error reading bmi323 external reg 0x%x: %d\n", |
| 2207 | − bmi323_reg_savestate[i], ret); | |
| 2206 | + bmi323_ext_reg_savestate[i], ret); | |
| 2208 | 2207 | return ret; |
| 2209 | 2208 | } |
| 2210 | 2209 | } |
| @@ -2232,8 +2231,10 @@ static int bmi323_core_runtime_resume(struct device *dev) · 21 unmodified lines | ||
| 2232 | 2231 | * after being reset in the lower power state by runtime-pm. |
| 2233 | 2232 | */ |
| 2234 | 2233 | ret = bmi323_init(data); |
| 2235 | − if (!ret) | |
| 2234 | + if (ret) { | |
| 2235 | + dev_err(data->dev, "Device power-on and init failed: %d", ret); | |
| 2236 | 2236 | return ret; |
| 2237 | + } | |
| 2237 | 2238 | |
| 2238 | 2239 | /* Register must be cleared before changing an active config */ |
| 2239 | 2240 | ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0); |
| @@ -2243,12 +2244,12 @@ static int bmi323_core_runtime_resume(struct device *dev) · 3 unmodified lines | ||
| 2243 | 2244 | } |
| 2244 | 2245 | |
| 2245 | 2246 | for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { |
| 2246 | − ret = bmi323_write_ext_reg(data, bmi323_reg_savestate[i], | |
| 2247 | − savestate->reg_settings[i]); | |
| 2247 | + ret = bmi323_write_ext_reg(data, bmi323_ext_reg_savestate[i], | |
| 2248 | + savestate->ext_reg_settings[i]); | |
| 2248 | 2249 | if (ret) { |
| 2249 | 2250 | dev_err(data->dev, |
| 2250 | 2251 | "Error writing bmi323 external reg 0x%x: %d\n", |
| 2251 | − bmi323_reg_savestate[i], ret); | |
| 2252 | + bmi323_ext_reg_savestate[i], ret); | |
| 2252 | 2253 | return ret; |
| 2253 | 2254 | } |
| 2254 | 2255 | } |
| @@ -2293,11 +2294,9 @@ static int bmi323_core_runtime_resume(struct device *dev) · 38 unmodified lines | ||
| 2293 | 2294 | return iio_device_resume_triggering(indio_dev); |
| 2294 | 2295 | } |
| 2295 | 2296 | |
| 2296 | −#endif | |
| 2297 | − | |
| 2298 | 2297 | const struct dev_pm_ops bmi323_core_pm_ops = { |
| 2299 | − SET_RUNTIME_PM_OPS(bmi323_core_runtime_suspend, | |
| 2300 | − bmi323_core_runtime_resume, NULL) | |
| 2298 | + RUNTIME_PM_OPS(bmi323_core_runtime_suspend, | |
| 2299 | + bmi323_core_runtime_resume, NULL) | |
| 2301 | 2300 | }; |
| 2302 | 2301 | EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, IIO_BMI323); |
| 2303 | 2302 | |
| @@ -335,6 +335,8 @@ config ROHM_BU27008 · 334 unmodified lines | ||
| 335 | 335 | depends on I2C |
| 336 | 336 | select REGMAP_I2C |
| 337 | 337 | select IIO_GTS_HELPER |
| 338 | + select IIO_BUFFER | |
| 339 | + select IIO_TRIGGERED_BUFFER | |
| 338 | 340 | help |
| 339 | 341 | Enable support for the ROHM BU27008 color sensor. |
| 340 | 342 | The ROHM BU27008 is a sensor with 5 photodiodes (red, green, |
| @@ -138,6 +138,10 @@ static const struct opt3001_scale opt3001_scales[] = { · 137 unmodified lines | ||
| 138 | 138 | .val = 20966, |
| 139 | 139 | .val2 = 400000, |
| 140 | 140 | }, |
| 141 | + { | |
| 142 | + .val = 41932, | |
| 143 | + .val2 = 800000, | |
| 144 | + }, | |
| 141 | 145 | { |
| 142 | 146 | .val = 83865, |
| 143 | 147 | .val2 = 600000, |
| @@ -99,9 +99,8 @@ static const char * const period_values[] = { · 98 unmodified lines | ||
| 99 | 99 | static ssize_t in_illuminance_period_available_show(struct device *dev, |
| 100 | 100 | struct device_attribute *attr, char *buf) |
| 101 | 101 | { |
| 102 | + struct veml6030_data *data = iio_priv(dev_to_iio_dev(dev)); | |
| 102 | 103 | int ret, reg, x; |
| 103 | − struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | |
| 104 | − struct veml6030_data *data = iio_priv(indio_dev); | |
| 105 | 104 | |
| 106 | 105 | ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); |
| 107 | 106 | if (ret) { |
| @@ -780,7 +779,7 @@ static int veml6030_hw_init(struct iio_dev *indio_dev) · 672 unmodified lines | ||
| 780 | 779 | |
| 781 | 780 | /* Cache currently active measurement parameters */ |
| 782 | 781 | data->cur_gain = 3; |
| 783 | − data->cur_resolution = 4608; | |
| 782 | + data->cur_resolution = 5376; | |
| 784 | 783 | data->cur_integration_time = 3; |
| 785 | 784 | |
| 786 | 785 | return ret; |
| @@ -11,6 +11,8 @@ config AF8133J · 10 unmodified lines | ||
| 11 | 11 | depends on I2C |
| 12 | 12 | depends on OF |
| 13 | 13 | select REGMAP_I2C |
| 14 | + select IIO_BUFFER | |
| 15 | + select IIO_TRIGGERED_BUFFER | |
| 14 | 16 | help |
| 15 | 17 | Say yes here to build support for Voltafield AF8133J I2C-based |
| 16 | 18 | 3-axis magnetometer chip. |
| @@ -19,6 +19,9 @@ config ABP060MG · 18 unmodified lines | ||
| 19 | 19 | config ROHM_BM1390 |
| 20 | 20 | tristate "ROHM BM1390GLV-Z pressure sensor driver" |
| 21 | 21 | depends on I2C |
| 22 | + select REGMAP_I2C | |
| 23 | + select IIO_BUFFER | |
| 24 | + select IIO_TRIGGERED_BUFFER | |
| 22 | 25 | help |
| 23 | 26 | Support for the ROHM BM1390 pressure sensor. The BM1390GLV-Z |
| 24 | 27 | can measure pressures ranging from 300 hPa to 1300 hPa with |
| @@ -253,6 +256,7 @@ config MS5637 · 228 unmodified lines | ||
| 253 | 256 | config SDP500 |
| 254 | 257 | tristate "Sensirion SDP500 differential pressure sensor I2C driver" |
| 255 | 258 | depends on I2C |
| 259 | + select CRC8 | |
| 256 | 260 | help |
| 257 | 261 | Say Y here to build support for Sensirion SDP500 differential pressure |
| 258 | 262 | sensor I2C driver. |
| @@ -86,6 +86,8 @@ config LIDAR_LITE_V2 · 85 unmodified lines | ||
| 86 | 86 | config MB1232 |
| 87 | 87 | tristate "MaxSonar I2CXL family ultrasonic sensors" |
| 88 | 88 | depends on I2C |
| 89 | + select IIO_BUFFER | |
| 90 | + select IIO_TRIGGERED_BUFFER | |
| 89 | 91 | help |
| 90 | 92 | Say Y to build a driver for the ultrasonic sensors I2CXL of |
| 91 | 93 | MaxBotix which have an i2c interface. It can be used to measure |
| @@ -31,6 +31,9 @@ config AD2S1210 · 30 unmodified lines | ||
| 31 | 31 | depends on SPI |
| 32 | 32 | depends on COMMON_CLK |
| 33 | 33 | depends on GPIOLIB || COMPILE_TEST |
| 34 | + select REGMAP | |
| 35 | + select IIO_BUFFER | |
| 36 | + select IIO_TRIGGERED_BUFFER | |
| 34 | 37 | help |
| 35 | 38 | Say yes here to build support for Analog Devices spi resolver |
| 36 | 39 | to digital converters, ad2s1210, provides direct access via sysfs. |
| @@ -269,6 +269,8 @@ rdma_find_ndev_for_src_ip_rcu(struct net *net, const struct sockaddr *src_in) · 268 unmodified lines | ||
| 269 | 269 | break; |
| 270 | 270 | #endif |
| 271 | 271 | } |
| 272 | + if (!ret && dev && is_vlan_dev(dev)) | |
| 273 | + dev = vlan_dev_real_dev(dev); | |
| 272 | 274 | return ret ? ERR_PTR(ret) : dev; |
| 273 | 275 | } |
| 274 | 276 | |
| @@ -2816,6 +2816,8 @@ int rdma_nl_notify_event(struct ib_device *device, u32 port_num, · 2815 unmodified lines | ||
| 2816 | 2816 | nlh = nlmsg_put(skb, 0, 0, |
| 2817 | 2817 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_MONITOR), |
| 2818 | 2818 | 0, 0); |
| 2819 | + if (!nlh) | |
| 2820 | + goto err_free; | |
| 2819 | 2821 | |
| 2820 | 2822 | switch (type) { |
| 2821 | 2823 | case RDMA_REGISTER_EVENT: |
| @@ -366,7 +366,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev, · 365 unmodified lines | ||
| 366 | 366 | goto done; |
| 367 | 367 | } |
| 368 | 368 | } |
| 369 | − if (rdev->pacing.dbr_pacing) | |
| 369 | + if (rdev->pacing.dbr_pacing && bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) | |
| 370 | 370 | bnxt_re_copy_db_pacing_stats(rdev, stats); |
| 371 | 371 | } |
| 372 | 372 | |
| @@ -1307,7 +1307,11 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, · 1306 unmodified lines | ||
| 1307 | 1307 | 0 : BNXT_QPLIB_RESERVED_QP_WRS; |
| 1308 | 1308 | entries = bnxt_re_init_depth(entries + diff + 1, uctx); |
| 1309 | 1309 | sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1); |
| 1310 | − sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true); | |
| 1310 | + if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) | |
| 1311 | + sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true); | |
| 1312 | + else | |
| 1313 | + sq->max_sw_wqe = sq->max_wqe; | |
| 1314 | + | |
| 1311 | 1315 | } |
| 1312 | 1316 | sq->q_full_delta = diff + 1; |
| 1313 | 1317 | /* |
| @@ -188,8 +188,11 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev) · 187 unmodified lines | ||
| 188 | 188 | |
| 189 | 189 | bnxt_re_set_db_offset(rdev); |
| 190 | 190 | rc = bnxt_qplib_map_db_bar(&rdev->qplib_res); |
| 191 | − if (rc) | |
| 191 | + if (rc) { | |
| 192 | + kfree(rdev->chip_ctx); | |
| 193 | + rdev->chip_ctx = NULL; | |
| 192 | 194 | return rc; |
| 195 | + } | |
| 193 | 196 | |
| 194 | 197 | if (bnxt_qplib_determine_atomics(en_dev->pdev)) |
| 195 | 198 | ibdev_info(&rdev->ibdev, |
| @@ -531,6 +534,7 @@ static bool is_dbr_fifo_full(struct bnxt_re_dev *rdev) · 335 unmodified lines | ||
| 531 | 534 | static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) |
| 532 | 535 | { |
| 533 | 536 | struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data; |
| 537 | + u32 retry_fifo_check = 1000; | |
| 534 | 538 | u32 fifo_occup; |
| 535 | 539 | |
| 536 | 540 | /* loop shouldn't run infintely as the occupancy usually goes |
| @@ -544,6 +548,14 @@ static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) · 7 unmodified lines | ||
| 544 | 548 | |
| 545 | 549 | if (fifo_occup < pacing_data->pacing_th) |
| 546 | 550 | break; |
| 551 | + if (!retry_fifo_check--) { | |
| 552 | + dev_info_once(rdev_to_dev(rdev), | |
| 553 | + "%s: fifo_occup = 0x%xfifo_max_depth = 0x%x pacing_th = 0x%x\n", | |
| 554 | + __func__, fifo_occup, pacing_data->fifo_max_depth, | |
| 555 | + pacing_data->pacing_th); | |
| 556 | + break; | |
| 557 | + } | |
| 558 | + | |
| 547 | 559 | } |
| 548 | 560 | } |
| 549 | 561 | |
| @@ -957,7 +969,7 @@ static int bnxt_re_register_ib(struct bnxt_re_dev *rdev) · 407 unmodified lines | ||
| 957 | 969 | return ib_register_device(ibdev, "bnxt_re%d", &rdev->en_dev->pdev->dev); |
| 958 | 970 | } |
| 959 | 971 | |
| 960 | −static struct bnxt_re_dev *bnxt_re_dev_add(struct bnxt_aux_priv *aux_priv, | |
| 972 | +static struct bnxt_re_dev *bnxt_re_dev_add(struct auxiliary_device *adev, | |
| 961 | 973 | struct bnxt_en_dev *en_dev) |
| 962 | 974 | { |
| 963 | 975 | struct bnxt_re_dev *rdev; |
| @@ -973,6 +985,7 @@ static struct bnxt_re_dev *bnxt_re_dev_add(struct bnxt_aux_priv *aux_priv, · 9 unmodified lines | ||
| 973 | 985 | rdev->nb.notifier_call = NULL; |
| 974 | 986 | rdev->netdev = en_dev->net; |
| 975 | 987 | rdev->en_dev = en_dev; |
| 988 | + rdev->adev = adev; | |
| 976 | 989 | rdev->id = rdev->en_dev->pdev->devfn; |
| 977 | 990 | INIT_LIST_HEAD(&rdev->qp_list); |
| 978 | 991 | mutex_init(&rdev->qp_lock); |
| @@ -1025,12 +1038,15 @@ static int bnxt_re_handle_unaffi_async_event(struct creq_func_event · 46 unmodified lines | ||
| 1025 | 1038 | static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event, |
| 1026 | 1039 | struct bnxt_re_qp *qp) |
| 1027 | 1040 | { |
| 1028 | − struct bnxt_re_srq *srq = container_of(qp->qplib_qp.srq, struct bnxt_re_srq, | |
| 1029 | − qplib_srq); | |
| 1030 | 1041 | struct creq_qp_error_notification *err_event; |
| 1042 | + struct bnxt_re_srq *srq = NULL; | |
| 1031 | 1043 | struct ib_event event = {}; |
| 1032 | 1044 | unsigned int flags; |
| 1033 | 1045 | |
| 1046 | + if (qp->qplib_qp.srq) | |
| 1047 | + srq = container_of(qp->qplib_qp.srq, struct bnxt_re_srq, | |
| 1048 | + qplib_srq); | |
| 1049 | + | |
| 1034 | 1050 | if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR && |
| 1035 | 1051 | rdma_is_kernel_res(&qp->ib_qp.res)) { |
| 1036 | 1052 | flags = bnxt_re_lock_cqs(qp); |
| @@ -1258,15 +1274,9 @@ static int bnxt_re_cqn_handler(struct bnxt_qplib_nq *nq, · 221 unmodified lines | ||
| 1258 | 1274 | { |
| 1259 | 1275 | struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq, |
| 1260 | 1276 | qplib_cq); |
| 1261 | − u32 *cq_ptr; | |
| 1262 | 1277 | |
| 1263 | − if (cq->ib_cq.comp_handler) { | |
| 1264 | − if (cq->uctx_cq_page) { | |
| 1265 | − cq_ptr = (u32 *)cq->uctx_cq_page; | |
| 1266 | − *cq_ptr = cq->qplib_cq.toggle; | |
| 1267 | − } | |
| 1278 | + if (cq->ib_cq.comp_handler) | |
| 1268 | 1279 | (*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context); |
| 1269 | − } | |
| 1270 | 1280 | |
| 1271 | 1281 | return 0; |
| 1272 | 1282 | } |
| @@ -1823,7 +1833,6 @@ static void bnxt_re_update_en_info_rdev(struct bnxt_re_dev *rdev, · 550 unmodified lines | ||
| 1823 | 1833 | */ |
| 1824 | 1834 | rtnl_lock(); |
| 1825 | 1835 | en_info->rdev = rdev; |
| 1826 | − rdev->adev = adev; | |
| 1827 | 1836 | rtnl_unlock(); |
| 1828 | 1837 | } |
| 1829 | 1838 | |
| @@ -1840,7 +1849,7 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type) · 10 unmodified lines | ||
| 1840 | 1849 | en_dev = en_info->en_dev; |
| 1841 | 1850 | |
| 1842 | 1851 | |
| 1843 | − rdev = bnxt_re_dev_add(aux_priv, en_dev); | |
| 1852 | + rdev = bnxt_re_dev_add(adev, en_dev); | |
| 1844 | 1853 | if (!rdev || !rdev_to_dev(rdev)) { |
| 1845 | 1854 | rc = -ENOMEM; |
| 1846 | 1855 | goto exit; |
| @@ -1865,12 +1874,14 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type) · 18 unmodified lines | ||
| 1865 | 1874 | rdev->nb.notifier_call = NULL; |
| 1866 | 1875 | pr_err("%s: Cannot register to netdevice_notifier", |
| 1867 | 1876 | ROCE_DRV_MODULE_NAME); |
| 1868 | − return rc; | |
| 1877 | + goto re_dev_unreg; | |
| 1869 | 1878 | } |
| 1870 | 1879 | bnxt_re_setup_cc(rdev, true); |
| 1871 | 1880 | |
| 1872 | 1881 | return 0; |
| 1873 | 1882 | |
| 1883 | +re_dev_unreg: | |
| 1884 | + ib_unregister_device(&rdev->ibdev); | |
| 1874 | 1885 | re_dev_uninit: |
| 1875 | 1886 | bnxt_re_update_en_info_rdev(NULL, en_info, adev); |
| 1876 | 1887 | bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE); |
| @@ -2014,15 +2025,7 @@ static int bnxt_re_probe(struct auxiliary_device *adev, · 137 unmodified lines | ||
| 2014 | 2025 | auxiliary_set_drvdata(adev, en_info); |
| 2015 | 2026 | |
| 2016 | 2027 | rc = bnxt_re_add_device(adev, BNXT_RE_COMPLETE_INIT); |
| 2017 | − if (rc) | |
| 2018 | − goto err; | |
| 2019 | 2028 | mutex_unlock(&bnxt_re_mutex); |
| 2020 | − return 0; | |
| 2021 | − | |
| 2022 | −err: | |
| 2023 | − mutex_unlock(&bnxt_re_mutex); | |
| 2024 | − bnxt_re_remove(adev); | |
| 2025 | − | |
| 2026 | 2029 | return rc; |
| 2027 | 2030 | } |
| 2028 | 2031 | |
| @@ -327,6 +327,7 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t) · 326 unmodified lines | ||
| 327 | 327 | case NQ_BASE_TYPE_CQ_NOTIFICATION: |
| 328 | 328 | { |
| 329 | 329 | struct nq_cn *nqcne = (struct nq_cn *)nqe; |
| 330 | + struct bnxt_re_cq *cq_p; | |
| 330 | 331 | |
| 331 | 332 | q_handle = le32_to_cpu(nqcne->cq_handle_low); |
| 332 | 333 | q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high) |
| @@ -337,6 +338,10 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t) · 4 unmodified lines | ||
| 337 | 338 | cq->toggle = (le16_to_cpu(nqe->info10_type) & |
| 338 | 339 | NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT; |
| 339 | 340 | cq->dbinfo.toggle = cq->toggle; |
| 341 | + cq_p = container_of(cq, struct bnxt_re_cq, qplib_cq); | |
| 342 | + if (cq_p->uctx_cq_page) | |
| 343 | + *((u32 *)cq_p->uctx_cq_page) = cq->toggle; | |
| 344 | + | |
| 340 | 345 | bnxt_qplib_armen_db(&cq->dbinfo, |
| 341 | 346 | DBC_DBC_TYPE_CQ_ARMENA); |
| 342 | 347 | spin_lock_bh(&cq->compl_lock); |
| @@ -170,7 +170,7 @@ struct bnxt_qplib_swqe { · 169 unmodified lines | ||
| 170 | 170 | }; |
| 171 | 171 | u32 q_key; |
| 172 | 172 | u32 dst_qp; |
| 173 | − u16 avid; | |
| 173 | + u32 avid; | |
| 174 | 174 | } send; |
| 175 | 175 | |
| 176 | 176 | /* Send Raw Ethernet and QP1 */ |
| @@ -525,7 +525,7 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, · 524 unmodified lines | ||
| 525 | 525 | /* failed with status */ |
| 526 | 526 | dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n", |
| 527 | 527 | cookie, opcode, evnt->status); |
| 528 | − rc = -EFAULT; | |
| 528 | + rc = -EIO; | |
| 529 | 529 | } |
| 530 | 530 | |
| 531 | 531 | return rc; |
| @@ -244,6 +244,8 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, · 243 unmodified lines | ||
| 244 | 244 | sginfo.pgsize = npde * pg_size; |
| 245 | 245 | sginfo.npages = 1; |
| 246 | 246 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); |
| 247 | + if (rc) | |
| 248 | + goto fail; | |
| 247 | 249 | |
| 248 | 250 | /* Alloc PBL pages */ |
| 249 | 251 | sginfo.npages = npbl; |
| @@ -255,22 +257,9 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, · 5 unmodified lines | ||
| 255 | 257 | dst_virt_ptr = |
| 256 | 258 | (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; |
| 257 | 259 | src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; |
| 258 | − if (hwq_attr->type == HWQ_TYPE_MR) { | |
| 259 | − /* For MR it is expected that we supply only 1 contigous | |
| 260 | − * page i.e only 1 entry in the PDL that will contain | |
| 261 | − * all the PBLs for the user supplied memory region | |
| 262 | − */ | |
| 263 | − for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; | |
| 264 | − i++) | |
| 265 | − dst_virt_ptr[0][i] = src_phys_ptr[i] | | |
| 266 | − flag; | |
| 267 | − } else { | |
| 268 | − for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; | |
| 269 | − i++) | |
| 270 | − dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] = | |
| 271 | − src_phys_ptr[i] | | |
| 272 | − PTU_PDE_VALID; | |
| 273 | − } | |
| 260 | + for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) | |
| 261 | + dst_virt_ptr[0][i] = src_phys_ptr[i] | flag; | |
| 262 | + | |
| 274 | 263 | /* Alloc or init PTEs */ |
| 275 | 264 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2], |
| 276 | 265 | hwq_attr->sginfo); |
| @@ -140,6 +140,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, · 139 unmodified lines | ||
| 140 | 140 | min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; |
| 141 | 141 | attr->max_cq = le32_to_cpu(sb->max_cq); |
| 142 | 142 | attr->max_cq_wqes = le32_to_cpu(sb->max_cqe); |
| 143 | + if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) | |
| 144 | + attr->max_cq_wqes = min_t(u32, BNXT_QPLIB_MAX_CQ_WQES, attr->max_cq_wqes); | |
| 143 | 145 | attr->max_cq_sges = attr->max_qp_sges; |
| 144 | 146 | attr->max_mr = le32_to_cpu(sb->max_mr); |
| 145 | 147 | attr->max_mw = le32_to_cpu(sb->max_mw); |
| @@ -157,7 +159,14 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, · 11 unmodified lines | ||
| 157 | 159 | if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) |
| 158 | 160 | attr->l2_db_size = (sb->l2_db_space_size + 1) * |
| 159 | 161 | (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); |
| 160 | − attr->max_sgid = BNXT_QPLIB_NUM_GIDS_SUPPORTED; | |
| 162 | + /* | |
| 163 | + * Read the max gid supported by HW. | |
| 164 | + * For each entry in HW GID in HW table, we consume 2 | |
| 165 | + * GID entries in the kernel GID table. So max_gid reported | |
| 166 | + * to stack can be up to twice the value reported by the HW, up to 256 gids. | |
| 167 | + */ | |
| 168 | + attr->max_sgid = le32_to_cpu(sb->max_gid); | |
| 169 | + attr->max_sgid = min_t(u32, BNXT_QPLIB_NUM_GIDS_SUPPORTED, 2 * attr->max_sgid); | |
| 161 | 170 | attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags); |
| 162 | 171 | attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2); |
| 163 | 172 | |
| @@ -56,6 +56,7 @@ struct bnxt_qplib_dev_attr { · 55 unmodified lines | ||
| 56 | 56 | u32 max_qp_wqes; |
| 57 | 57 | u32 max_qp_sges; |
| 58 | 58 | u32 max_cq; |
| 59 | +#define BNXT_QPLIB_MAX_CQ_WQES 0xfffff | |
| 59 | 60 | u32 max_cq_wqes; |
| 60 | 61 | u32 max_cq_sges; |
| 61 | 62 | u32 max_mr; |
| @@ -2086,7 +2086,7 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, · 2085 unmodified lines | ||
| 2086 | 2086 | err = -ENOMEM; |
| 2087 | 2087 | if (n->dev->flags & IFF_LOOPBACK) { |
| 2088 | 2088 | if (iptype == 4) |
| 2089 | − pdev = ip_dev_find(&init_net, *(__be32 *)peer_ip); | |
| 2089 | + pdev = __ip_dev_find(&init_net, *(__be32 *)peer_ip, false); | |
| 2090 | 2090 | else if (IS_ENABLED(CONFIG_IPV6)) |
| 2091 | 2091 | for_each_netdev(&init_net, pdev) { |
| 2092 | 2092 | if (ipv6_chk_addr(&init_net, |
| @@ -2101,12 +2101,12 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, · 8 unmodified lines | ||
| 2101 | 2101 | err = -ENODEV; |
| 2102 | 2102 | goto out; |
| 2103 | 2103 | } |
| 2104 | + if (is_vlan_dev(pdev)) | |
| 2105 | + pdev = vlan_dev_real_dev(pdev); | |
| 2104 | 2106 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
| 2105 | 2107 | n, pdev, rt_tos2priority(tos)); |
| 2106 | − if (!ep->l2t) { | |
| 2107 | − dev_put(pdev); | |
| 2108 | + if (!ep->l2t) | |
| 2108 | 2109 | goto out; |
| 2109 | − } | |
| 2110 | 2110 | ep->mtu = pdev->mtu; |
| 2111 | 2111 | ep->tx_chan = cxgb4_port_chan(pdev); |
| 2112 | 2112 | ep->smac_idx = ((struct port_info *)netdev_priv(pdev))->smt_idx; |
| @@ -2119,7 +2119,6 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, · 6 unmodified lines | ||
| 2119 | 2119 | ep->rss_qid = cdev->rdev.lldi.rxq_ids[ |
| 2120 | 2120 | cxgb4_port_idx(pdev) * step]; |
| 2121 | 2121 | set_tcp_window(ep, (struct port_info *)netdev_priv(pdev)); |
| 2122 | − dev_put(pdev); | |
| 2123 | 2122 | } else { |
| 2124 | 2123 | pdev = get_real_dev(n->dev); |
| 2125 | 2124 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
| @@ -3631,7 +3631,7 @@ void irdma_free_lsmm_rsrc(struct irdma_qp *iwqp) · 3630 unmodified lines | ||
| 3631 | 3631 | /** |
| 3632 | 3632 | * irdma_accept - registered call for connection to be accepted |
| 3633 | 3633 | * @cm_id: cm information for passive connection |
| 3634 | − * @conn_param: accpet parameters | |
| 3634 | + * @conn_param: accept parameters | |
| 3635 | 3635 | */ |
| 3636 | 3636 | int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) |
| 3637 | 3637 | { |
| @@ -331,6 +331,8 @@ static int siw_tcp_sendpages(struct socket *s, struct page **page, int offset, · 330 unmodified lines | ||
| 331 | 331 | msg.msg_flags &= ~MSG_MORE; |
| 332 | 332 | |
| 333 | 333 | tcp_rate_check_app_limited(sk); |
| 334 | + if (!sendpage_ok(page[i])) | |
| 335 | + msg.msg_flags &= ~MSG_SPLICE_PAGES; | |
| 334 | 336 | bvec_set_page(&bvec, page[i], bytes, offset); |
| 335 | 337 | iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); |
| 336 | 338 | |
| @@ -68,6 +68,8 @@ MODULE_LICENSE("Dual BSD/GPL"); · 67 unmodified lines | ||
| 68 | 68 | static u64 srpt_service_guid; |
| 69 | 69 | static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */ |
| 70 | 70 | static LIST_HEAD(srpt_dev_list); /* List of srpt_device structures. */ |
| 71 | +static DEFINE_MUTEX(srpt_mc_mutex); /* Protects srpt_memory_caches. */ | |
| 72 | +static DEFINE_XARRAY(srpt_memory_caches); /* See also srpt_memory_cache_entry */ | |
| 71 | 73 | |
| 72 | 74 | static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE; |
| 73 | 75 | module_param(srp_max_req_size, int, 0444); |
| @@ -105,6 +107,63 @@ static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc); · 31 unmodified lines | ||
| 105 | 107 | static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc); |
| 106 | 108 | static void srpt_process_wait_list(struct srpt_rdma_ch *ch); |
| 107 | 109 | |
| 110 | +/* Type of the entries in srpt_memory_caches. */ | |
| 111 | +struct srpt_memory_cache_entry { | |
| 112 | + refcount_t ref; | |
| 113 | + struct kmem_cache *c; | |
| 114 | +}; | |
| 115 | + | |
| 116 | +static struct kmem_cache *srpt_cache_get(unsigned int object_size) | |
| 117 | +{ | |
| 118 | + struct srpt_memory_cache_entry *e; | |
| 119 | + char name[32]; | |
| 120 | + void *res; | |
| 121 | + | |
| 122 | + guard(mutex)(&srpt_mc_mutex); | |
| 123 | + e = xa_load(&srpt_memory_caches, object_size); | |
| 124 | + if (e) { | |
| 125 | + refcount_inc(&e->ref); | |
| 126 | + return e->c; | |
| 127 | + } | |
| 128 | + snprintf(name, sizeof(name), "srpt-%u", object_size); | |
| 129 | + e = kmalloc(sizeof(*e), GFP_KERNEL); | |
| 130 | + if (!e) | |
| 131 | + return NULL; | |
| 132 | + refcount_set(&e->ref, 1); | |
| 133 | + e->c = kmem_cache_create(name, object_size, /*align=*/512, 0, NULL); | |
| 134 | + if (!e->c) | |
| 135 | + goto free_entry; | |
| 136 | + res = xa_store(&srpt_memory_caches, object_size, e, GFP_KERNEL); | |
| 137 | + if (xa_is_err(res)) | |
| 138 | + goto destroy_cache; | |
| 139 | + return e->c; | |
| 140 | + | |
| 141 | +destroy_cache: | |
| 142 | + kmem_cache_destroy(e->c); | |
| 143 | + | |
| 144 | +free_entry: | |
| 145 | + kfree(e); | |
| 146 | + return NULL; | |
| 147 | +} | |
| 148 | + | |
| 149 | +static void srpt_cache_put(struct kmem_cache *c) | |
| 150 | +{ | |
| 151 | + struct srpt_memory_cache_entry *e = NULL; | |
| 152 | + unsigned long object_size; | |
| 153 | + | |
| 154 | + guard(mutex)(&srpt_mc_mutex); | |
| 155 | + xa_for_each(&srpt_memory_caches, object_size, e) | |
| 156 | + if (e->c == c) | |
| 157 | + break; | |
| 158 | + if (WARN_ON_ONCE(!e)) | |
| 159 | + return; | |
| 160 | + if (!refcount_dec_and_test(&e->ref)) | |
| 161 | + return; | |
| 162 | + WARN_ON_ONCE(xa_erase(&srpt_memory_caches, object_size) != e); | |
| 163 | + kmem_cache_destroy(e->c); | |
| 164 | + kfree(e); | |
| 165 | +} | |
| 166 | + | |
| 108 | 167 | /* |
| 109 | 168 | * The only allowed channel state changes are those that change the channel |
| 110 | 169 | * state into a state with a higher numerical value. Hence the new > prev test. |
| @@ -2119,13 +2178,13 @@ static void srpt_release_channel_work(struct work_struct *w) · 2008 unmodified lines | ||
| 2119 | 2178 | ch->sport->sdev, ch->rq_size, |
| 2120 | 2179 | ch->rsp_buf_cache, DMA_TO_DEVICE); |
| 2121 | 2180 | |
| 2122 | − kmem_cache_destroy(ch->rsp_buf_cache); | |
| 2181 | + srpt_cache_put(ch->rsp_buf_cache); | |
| 2123 | 2182 | |
| 2124 | 2183 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring, |
| 2125 | 2184 | sdev, ch->rq_size, |
| 2126 | 2185 | ch->req_buf_cache, DMA_FROM_DEVICE); |
| 2127 | 2186 | |
| 2128 | − kmem_cache_destroy(ch->req_buf_cache); | |
| 2187 | + srpt_cache_put(ch->req_buf_cache); | |
| 2129 | 2188 | |
| 2130 | 2189 | kref_put(&ch->kref, srpt_free_ch); |
| 2131 | 2190 | } |
| @@ -2245,8 +2304,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, · 113 unmodified lines | ||
| 2245 | 2304 | INIT_LIST_HEAD(&ch->cmd_wait_list); |
| 2246 | 2305 | ch->max_rsp_size = ch->sport->port_attrib.srp_max_rsp_size; |
| 2247 | 2306 | |
| 2248 | − ch->rsp_buf_cache = kmem_cache_create("srpt-rsp-buf", ch->max_rsp_size, | |
| 2249 | − 512, 0, NULL); | |
| 2307 | + ch->rsp_buf_cache = srpt_cache_get(ch->max_rsp_size); | |
| 2250 | 2308 | if (!ch->rsp_buf_cache) |
| 2251 | 2309 | goto free_ch; |
| 2252 | 2310 | |
| @@ -2280,8 +2338,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, · 27 unmodified lines | ||
| 2280 | 2338 | alignment_offset = round_up(imm_data_offset, 512) - |
| 2281 | 2339 | imm_data_offset; |
| 2282 | 2340 | req_sz = alignment_offset + imm_data_offset + srp_max_req_size; |
| 2283 | − ch->req_buf_cache = kmem_cache_create("srpt-req-buf", req_sz, | |
| 2284 | − 512, 0, NULL); | |
| 2341 | + ch->req_buf_cache = srpt_cache_get(req_sz); | |
| 2285 | 2342 | if (!ch->req_buf_cache) |
| 2286 | 2343 | goto free_rsp_ring; |
| 2287 | 2344 | |
| @@ -2478,7 +2535,7 @@ free_recv_ring: · 190 unmodified lines | ||
| 2478 | 2535 | ch->req_buf_cache, DMA_FROM_DEVICE); |
| 2479 | 2536 | |
| 2480 | 2537 | free_recv_cache: |
| 2481 | − kmem_cache_destroy(ch->req_buf_cache); | |
| 2538 | + srpt_cache_put(ch->req_buf_cache); | |
| 2482 | 2539 | |
| 2483 | 2540 | free_rsp_ring: |
| 2484 | 2541 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, |
| @@ -2486,7 +2543,7 @@ free_rsp_ring: · 1 unmodified line | ||
| 2486 | 2543 | ch->rsp_buf_cache, DMA_TO_DEVICE); |
| 2487 | 2544 | |
| 2488 | 2545 | free_rsp_cache: |
| 2489 | − kmem_cache_destroy(ch->rsp_buf_cache); | |
| 2546 | + srpt_cache_put(ch->rsp_buf_cache); | |
| 2490 | 2547 | |
| 2491 | 2548 | free_ch: |
| 2492 | 2549 | if (rdma_cm_id) |
| @@ -3055,7 +3112,7 @@ static void srpt_free_srq(struct srpt_device *sdev) · 562 unmodified lines | ||
| 3055 | 3112 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, |
| 3056 | 3113 | sdev->srq_size, sdev->req_buf_cache, |
| 3057 | 3114 | DMA_FROM_DEVICE); |
| 3058 | − kmem_cache_destroy(sdev->req_buf_cache); | |
| 3115 | + srpt_cache_put(sdev->req_buf_cache); | |
| 3059 | 3116 | sdev->srq = NULL; |
| 3060 | 3117 | } |
| 3061 | 3118 | |
| @@ -3082,8 +3139,7 @@ static int srpt_alloc_srq(struct srpt_device *sdev) · 20 unmodified lines | ||
| 3082 | 3139 | pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size, |
| 3083 | 3140 | sdev->device->attrs.max_srq_wr, dev_name(&device->dev)); |
| 3084 | 3141 | |
| 3085 | − sdev->req_buf_cache = kmem_cache_create("srpt-srq-req-buf", | |
| 3086 | − srp_max_req_size, 0, 0, NULL); | |
| 3142 | + sdev->req_buf_cache = srpt_cache_get(srp_max_req_size); | |
| 3087 | 3143 | if (!sdev->req_buf_cache) |
| 3088 | 3144 | goto free_srq; |
| 3089 | 3145 | |
| @@ -3105,7 +3161,7 @@ static int srpt_alloc_srq(struct srpt_device *sdev) · 15 unmodified lines | ||
| 3105 | 3161 | return 0; |
| 3106 | 3162 | |
| 3107 | 3163 | free_cache: |
| 3108 | − kmem_cache_destroy(sdev->req_buf_cache); | |
| 3164 | + srpt_cache_put(sdev->req_buf_cache); | |
| 3109 | 3165 | |
| 3110 | 3166 | free_srq: |
| 3111 | 3167 | ib_destroy_srq(srq); |
| @@ -218,6 +218,7 @@ static const struct xpad_device { · 217 unmodified lines | ||
| 218 | 218 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
| 219 | 219 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, |
| 220 | 220 | { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
| 221 | + { 0x0db0, 0x1901, "Micro Star International Xbox360 Controller for Windows", 0, XTYPE_XBOX360 }, | |
| 221 | 222 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, |
| 222 | 223 | { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX }, |
| 223 | 224 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, |
| @@ -373,6 +374,7 @@ static const struct xpad_device { · 149 unmodified lines | ||
| 373 | 374 | { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, |
| 374 | 375 | { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, |
| 375 | 376 | { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, |
| 377 | + { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 }, | |
| 376 | 378 | { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, |
| 377 | 379 | { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, |
| 378 | 380 | { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, |
| @@ -492,6 +494,7 @@ static const struct usb_device_id xpad_table[] = { · 113 unmodified lines | ||
| 492 | 494 | XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz Gamepad */ |
| 493 | 495 | XPAD_XBOXONE_VENDOR(0x0b05), /* ASUS controllers */ |
| 494 | 496 | XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ |
| 497 | + XPAD_XBOX360_VENDOR(0x0db0), /* Micro Star International X-Box 360 controllers */ | |
| 495 | 498 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f Xbox 360 controllers */ |
| 496 | 499 | XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f Xbox One controllers */ |
| 497 | 500 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori controllers */ |
| @@ -645,19 +645,29 @@ static int zinitix_ts_probe(struct i2c_client *client) · 644 unmodified lines | ||
| 645 | 645 | return error; |
| 646 | 646 | } |
| 647 | 647 | |
| 648 | − bt541->num_keycodes = device_property_count_u32(&client->dev, "linux,keycodes"); | |
| 649 | − if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) { | |
| 650 | − dev_err(&client->dev, "too many keys defined (%d)\n", bt541->num_keycodes); | |
| 651 | − return -EINVAL; | |
| 652 | − } | |
| 648 | + if (device_property_present(&client->dev, "linux,keycodes")) { | |
| 649 | + bt541->num_keycodes = device_property_count_u32(&client->dev, | |
| 650 | + "linux,keycodes"); | |
| 651 | + if (bt541->num_keycodes < 0) { | |
| 652 | + dev_err(&client->dev, "Failed to count keys (%d)\n", | |
| 653 | + bt541->num_keycodes); | |
| 654 | + return bt541->num_keycodes; | |
| 655 | + } else if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) { | |
| 656 | + dev_err(&client->dev, "Too many keys defined (%d)\n", | |
| 657 | + bt541->num_keycodes); | |
| 658 | + return -EINVAL; | |
| 659 | + } | |
| 653 | 660 | |
| 654 | − error = device_property_read_u32_array(&client->dev, "linux,keycodes", | |
| 655 | − bt541->keycodes, | |
| 656 | − bt541->num_keycodes); | |
| 657 | − if (error) { | |
| 658 | − dev_err(&client->dev, | |
| 659 | − "Unable to parse \"linux,keycodes\" property: %d\n", error); | |
| 660 | − return error; | |
| 661 | + error = device_property_read_u32_array(&client->dev, | |
| 662 | + "linux,keycodes", | |
| 663 | + bt541->keycodes, | |
| 664 | + bt541->num_keycodes); | |
| 665 | + if (error) { | |
| 666 | + dev_err(&client->dev, | |
| 667 | + "Unable to parse \"linux,keycodes\" property: %d\n", | |
| 668 | + error); | |
| 669 | + return error; | |
| 670 | + } | |
| 661 | 671 | } |
| 662 | 672 | |
| 663 | 673 | error = zinitix_init_input_dev(bt541); |
| @@ -1420,7 +1420,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) · 1419 unmodified lines | ||
| 1420 | 1420 | cd_table->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; |
| 1421 | 1421 | cd_table->linear.num_ents = max_contexts; |
| 1422 | 1422 | |
| 1423 | − l1size = max_contexts * sizeof(struct arm_smmu_cd), | |
| 1423 | + l1size = max_contexts * sizeof(struct arm_smmu_cd); | |
| 1424 | 1424 | cd_table->linear.table = dma_alloc_coherent(smmu->dev, l1size, |
| 1425 | 1425 | &cd_table->cdtab_dma, |
| 1426 | 1426 | GFP_KERNEL); |
| @@ -3625,7 +3625,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) · 2198 unmodified lines | ||
| 3625 | 3625 | u32 l1size; |
| 3626 | 3626 | struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; |
| 3627 | 3627 | unsigned int last_sid_idx = |
| 3628 | − arm_smmu_strtab_l1_idx((1 << smmu->sid_bits) - 1); | |
| 3628 | + arm_smmu_strtab_l1_idx((1ULL << smmu->sid_bits) - 1); | |
| 3629 | 3629 | |
| 3630 | 3630 | /* Calculate the L1 size, capped to the SIDSIZE. */ |
| 3631 | 3631 | cfg->l2.num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES); |
| @@ -130,7 +130,7 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu) · 129 unmodified lines | ||
| 130 | 130 | |
| 131 | 131 | /* |
| 132 | 132 | * Disable MMU-500's not-particularly-beneficial next-page |
| 133 | − * prefetcher for the sake of errata #841119 and #826419. | |
| 133 | + * prefetcher for the sake of at least 5 known errata. | |
| 134 | 134 | */ |
| 135 | 135 | for (i = 0; i < smmu->num_context_banks; ++i) { |
| 136 | 136 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); |
| @@ -138,7 +138,7 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu) · 1 unmodified line | ||
| 138 | 138 | arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg); |
| 139 | 139 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); |
| 140 | 140 | if (reg & ARM_MMU500_ACTLR_CPRE) |
| 141 | − dev_warn_once(smmu->dev, "Failed to disable prefetcher [errata #841119 and #826419], check ACR.CACHE_LOCK\n"); | |
| 141 | + dev_warn_once(smmu->dev, "Failed to disable prefetcher for errata workarounds, check SACR.CACHE_LOCK\n"); | |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | return 0; |
| @@ -3340,8 +3340,10 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op · 3339 unmodified lines | ||
| 3340 | 3340 | */ |
| 3341 | 3341 | static void domain_context_clear(struct device_domain_info *info) |
| 3342 | 3342 | { |
| 3343 | − if (!dev_is_pci(info->dev)) | |
| 3343 | + if (!dev_is_pci(info->dev)) { | |
| 3344 | 3344 | domain_context_clear_one(info, info->bus, info->devfn); |
| 3345 | + return; | |
| 3346 | + } | |
| 3345 | 3347 | |
| 3346 | 3348 | pci_for_each_dma_alias(to_pci_dev(info->dev), |
| 3347 | 3349 | &domain_context_clear_one_cb, info); |
| @@ -45,13 +45,6 @@ config ARM_GIC_V3_ITS · 44 unmodified lines | ||
| 45 | 45 | select IRQ_MSI_LIB |
| 46 | 46 | default ARM_GIC_V3 |
| 47 | 47 | |
| 48 | −config ARM_GIC_V3_ITS_PCI | |
| 49 | − bool | |
| 50 | − depends on ARM_GIC_V3_ITS | |
| 51 | − depends on PCI | |
| 52 | − depends on PCI_MSI | |
| 53 | − default ARM_GIC_V3_ITS | |
| 54 | − | |
| 55 | 48 | config ARM_GIC_V3_ITS_FSL_MC |
| 56 | 49 | bool |
| 57 | 50 | depends on ARM_GIC_V3_ITS |
| @@ -797,8 +797,8 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, · 796 unmodified lines | ||
| 797 | 797 | its_encode_valid(cmd, desc->its_vmapp_cmd.valid); |
| 798 | 798 | |
| 799 | 799 | if (!desc->its_vmapp_cmd.valid) { |
| 800 | + alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); | |
| 800 | 801 | if (is_v4_1(its)) { |
| 801 | − alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); | |
| 802 | 802 | its_encode_alloc(cmd, alloc); |
| 803 | 803 | /* |
| 804 | 804 | * Unmapping a VPE is self-synchronizing on GICv4.1, |
| @@ -817,13 +817,13 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, · 12 unmodified lines | ||
| 817 | 817 | its_encode_vpt_addr(cmd, vpt_addr); |
| 818 | 818 | its_encode_vpt_size(cmd, LPI_NRBITS - 1); |
| 819 | 819 | |
| 820 | + alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count); | |
| 821 | + | |
| 820 | 822 | if (!is_v4_1(its)) |
| 821 | 823 | goto out; |
| 822 | 824 | |
| 823 | 825 | vconf_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->its_vm->vprop_page)); |
| 824 | 826 | |
| 825 | − alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count); | |
| 826 | − | |
| 827 | 827 | its_encode_alloc(cmd, alloc); |
| 828 | 828 | |
| 829 | 829 | /* |
| @@ -3806,6 +3806,13 @@ static int its_vpe_set_affinity(struct irq_data *d, · 2976 unmodified lines | ||
| 3806 | 3806 | struct cpumask *table_mask; |
| 3807 | 3807 | unsigned long flags; |
| 3808 | 3808 | |
| 3809 | + /* | |
| 3810 | + * Check if we're racing against a VPE being destroyed, for | |
| 3811 | + * which we don't want to allow a VMOVP. | |
| 3812 | + */ | |
| 3813 | + if (!atomic_read(&vpe->vmapp_count)) | |
| 3814 | + return -EINVAL; | |
| 3815 | + | |
| 3809 | 3816 | /* |
| 3810 | 3817 | * Changing affinity is mega expensive, so let's be as lazy as |
| 3811 | 3818 | * we can and only do it if we really have to. Also, if mapped |
| @@ -4463,9 +4470,8 @@ static int its_vpe_init(struct its_vpe *vpe) · 651 unmodified lines | ||
| 4463 | 4470 | raw_spin_lock_init(&vpe->vpe_lock); |
| 4464 | 4471 | vpe->vpe_id = vpe_id; |
| 4465 | 4472 | vpe->vpt_page = vpt_page; |
| 4466 | − if (gic_rdists->has_rvpeid) | |
| 4467 | − atomic_set(&vpe->vmapp_count, 0); | |
| 4468 | − else | |
| 4473 | + atomic_set(&vpe->vmapp_count, 0); | |
| 4474 | + if (!gic_rdists->has_rvpeid) | |
| 4469 | 4475 | vpe->vpe_proxy_event = -1; |
| 4470 | 4476 | |
| 4471 | 4477 | return 0; |
| @@ -37,7 +37,7 @@ static struct chip_props ocelot_props = { · 36 unmodified lines | ||
| 37 | 37 | .reg_off_ena_clr = 0x1c, |
| 38 | 38 | .reg_off_ena_set = 0x20, |
| 39 | 39 | .reg_off_ident = 0x38, |
| 40 | − .reg_off_trigger = 0x5c, | |
| 40 | + .reg_off_trigger = 0x4, | |
| 41 | 41 | .n_irq = 24, |
| 42 | 42 | }; |
| 43 | 43 | |
| @@ -70,7 +70,7 @@ static struct chip_props jaguar2_props = { · 26 unmodified lines | ||
| 70 | 70 | .reg_off_ena_clr = 0x1c, |
| 71 | 71 | .reg_off_ena_set = 0x20, |
| 72 | 72 | .reg_off_ident = 0x38, |
| 73 | − .reg_off_trigger = 0x5c, | |
| 73 | + .reg_off_trigger = 0x4, | |
| 74 | 74 | .n_irq = 29, |
| 75 | 75 | }; |
| 76 | 76 | |
| @@ -84,6 +84,12 @@ static void ocelot_irq_unmask(struct irq_data *data) · 7 unmodified lines | ||
| 84 | 84 | u32 val; |
| 85 | 85 | |
| 86 | 86 | irq_gc_lock(gc); |
| 87 | + /* | |
| 88 | + * Clear sticky bits for edge mode interrupts. | |
| 89 | + * Serval has only one trigger register replication, but the adjacent | |
| 90 | + * register is always read as zero, so there's no need to handle this | |
| 91 | + * case separately. | |
| 92 | + */ | |
| 87 | 93 | val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) | |
| 88 | 94 | irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1)); |
| 89 | 95 | if (!(val & mask)) |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | 10 | #include <linux/bitfield.h> |
| 11 | +#include <linux/cleanup.h> | |
| 11 | 12 | #include <linux/clk.h> |
| 12 | 13 | #include <linux/err.h> |
| 13 | 14 | #include <linux/io.h> |
| @@ -530,12 +531,12 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv, · 516 unmodified lines | ||
| 530 | 531 | static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent, |
| 531 | 532 | const struct irq_chip *irq_chip) |
| 532 | 533 | { |
| 534 | + struct platform_device *pdev = of_find_device_by_node(node); | |
| 535 | + struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL; | |
| 533 | 536 | struct irq_domain *irq_domain, *parent_domain; |
| 534 | − struct platform_device *pdev; | |
| 535 | 537 | struct reset_control *resetn; |
| 536 | 538 | int ret; |
| 537 | 539 | |
| 538 | − pdev = of_find_device_by_node(node); | |
| 539 | 540 | if (!pdev) |
| 540 | 541 | return -ENODEV; |
| 541 | 542 | |
| @@ -591,6 +592,17 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node * · 49 unmodified lines | ||
| 591 | 592 | |
| 592 | 593 | register_syscore_ops(&rzg2l_irqc_syscore_ops); |
| 593 | 594 | |
| 595 | + /* | |
| 596 | + * Prevent the cleanup function from invoking put_device by assigning | |
| 597 | + * NULL to dev. | |
| 598 | + * | |
| 599 | + * make coccicheck will complain about missing put_device calls, but | |
| 600 | + * those are false positives, as dev will be automatically "put" via | |
| 601 | + * __free_put_device on the failing path. | |
| 602 | + * On the successful path we don't actually want to "put" dev. | |
| 603 | + */ | |
| 604 | + dev = NULL; | |
| 605 | + | |
| 594 | 606 | return 0; |
| 595 | 607 | |
| 596 | 608 | pm_put: |
| @@ -341,7 +341,7 @@ int imsic_irqdomain_init(void) · 340 unmodified lines | ||
| 341 | 341 | imsic->fwnode, global->hart_index_bits, global->guest_index_bits); |
| 342 | 342 | pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n", |
| 343 | 343 | imsic->fwnode, global->group_index_bits, global->group_index_shift); |
| 344 | − pr_info("%pfwP: per-CPU IDs %d at base PPN %pa\n", | |
| 344 | + pr_info("%pfwP: per-CPU IDs %d at base address %pa\n", | |
| 345 | 345 | imsic->fwnode, global->nr_ids, &global->base_addr); |
| 346 | 346 | pr_info("%pfwP: total %d interrupts available\n", |
| 347 | 347 | imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1)); |
| @@ -265,7 +265,7 @@ struct rintc_data { · 264 unmodified lines | ||
| 265 | 265 | }; |
| 266 | 266 | |
| 267 | 267 | static u32 nr_rintc; |
| 268 | −static struct rintc_data *rintc_acpi_data[NR_CPUS]; | |
| 268 | +static struct rintc_data **rintc_acpi_data; | |
| 269 | 269 | |
| 270 | 270 | #define for_each_matching_plic(_plic_id) \ |
| 271 | 271 | unsigned int _plic; \ |
| @@ -329,13 +329,30 @@ int acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res) · 57 unmodified lines | ||
| 329 | 329 | return 0; |
| 330 | 330 | } |
| 331 | 331 | |
| 332 | +static int __init riscv_intc_acpi_match(union acpi_subtable_headers *header, | |
| 333 | + const unsigned long end) | |
| 334 | +{ | |
| 335 | + return 0; | |
| 336 | +} | |
| 337 | + | |
| 332 | 338 | static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, |
| 333 | 339 | const unsigned long end) |
| 334 | 340 | { |
| 335 | 341 | struct acpi_madt_rintc *rintc; |
| 336 | 342 | struct fwnode_handle *fn; |
| 343 | + int count; | |
| 337 | 344 | int rc; |
| 338 | 345 | |
| 346 | + if (!rintc_acpi_data) { | |
| 347 | + count = acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, riscv_intc_acpi_match, 0); | |
| 348 | + if (count <= 0) | |
| 349 | + return -EINVAL; | |
| 350 | + | |
| 351 | + rintc_acpi_data = kcalloc(count, sizeof(*rintc_acpi_data), GFP_KERNEL); | |
| 352 | + if (!rintc_acpi_data) | |
| 353 | + return -ENOMEM; | |
| 354 | + } | |
| 355 | + | |
| 339 | 356 | rintc = (struct acpi_madt_rintc *)header; |
| 340 | 357 | rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL); |
| 341 | 358 | if (!rintc_acpi_data[nr_rintc]) |
| @@ -126,16 +126,6 @@ static inline void plic_irq_toggle(const struct cpumask *mask, · 125 unmodified lines | ||
| 126 | 126 | } |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | −static void plic_irq_enable(struct irq_data *d) | |
| 130 | −{ | |
| 131 | − plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1); | |
| 132 | −} | |
| 133 | − | |
| 134 | −static void plic_irq_disable(struct irq_data *d) | |
| 135 | −{ | |
| 136 | − plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0); | |
| 137 | −} | |
| 138 | − | |
| 139 | 129 | static void plic_irq_unmask(struct irq_data *d) |
| 140 | 130 | { |
| 141 | 131 | struct plic_priv *priv = irq_data_get_irq_chip_data(d); |
| @@ -150,6 +140,17 @@ static void plic_irq_mask(struct irq_data *d) · 8 unmodified lines | ||
| 150 | 140 | writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); |
| 151 | 141 | } |
| 152 | 142 | |
| 143 | +static void plic_irq_enable(struct irq_data *d) | |
| 144 | +{ | |
| 145 | + plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1); | |
| 146 | + plic_irq_unmask(d); | |
| 147 | +} | |
| 148 | + | |
| 149 | +static void plic_irq_disable(struct irq_data *d) | |
| 150 | +{ | |
| 151 | + plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0); | |
| 152 | +} | |
| 153 | + | |
| 153 | 154 | static void plic_irq_eoi(struct irq_data *d) |
| 154 | 155 | { |
| 155 | 156 | struct plic_handler *handler = this_cpu_ptr(&plic_handlers); |
| @@ -626,8 +627,10 @@ static int plic_probe(struct fwnode_handle *fwnode) · 470 unmodified lines | ||
| 626 | 627 | |
| 627 | 628 | handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), |
| 628 | 629 | sizeof(*handler->enable_save), GFP_KERNEL); |
| 629 | − if (!handler->enable_save) | |
| 630 | + if (!handler->enable_save) { | |
| 631 | + error = -ENOMEM; | |
| 630 | 632 | goto fail_cleanup_contexts; |
| 633 | + } | |
| 631 | 634 | done: |
| 632 | 635 | for (hwirq = 1; hwirq <= nr_irqs; hwirq++) { |
| 633 | 636 | plic_toggle(handler, hwirq, 0); |
| @@ -639,8 +642,10 @@ done: · 5 unmodified lines | ||
| 639 | 642 | |
| 640 | 643 | priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1, |
| 641 | 644 | &plic_irqdomain_ops, priv); |
| 642 | − if (WARN_ON(!priv->irqdomain)) | |
| 645 | + if (WARN_ON(!priv->irqdomain)) { | |
| 646 | + error = -ENOMEM; | |
| 643 | 647 | goto fail_cleanup_contexts; |
| 648 | + } | |
| 644 | 649 | |
| 645 | 650 | /* |
| 646 | 651 | * We can have multiple PLIC instances so setup global state |
| @@ -16,7 +16,8 @@ config MISC_RTSX_PCI · 15 unmodified lines | ||
| 16 | 16 | select MFD_CORE |
| 17 | 17 | help |
| 18 | 18 | This supports for Realtek PCI-Express card reader including rts5209, |
| 19 | − rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, rts5260. | |
| 19 | + rts5227, rts5228, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, | |
| 20 | + rts5260, rts5261, rts5264. | |
| 20 | 21 | Realtek card readers support access to many types of memory cards, |
| 21 | 22 | such as Memory Stick, Memory Stick Pro, Secure Digital and |
| 22 | 23 | MultiMediaCard. |
| @@ -364,6 +364,7 @@ static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev, · 363 unmodified lines | ||
| 364 | 364 | if (is_eeprom_responsive(priv)) { |
| 365 | 365 | priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM; |
| 366 | 366 | priv->nvmem_config_eeprom.name = EEPROM_NAME; |
| 367 | + priv->nvmem_config_eeprom.id = NVMEM_DEVID_AUTO; | |
| 367 | 368 | priv->nvmem_config_eeprom.dev = &aux_dev->dev; |
| 368 | 369 | priv->nvmem_config_eeprom.owner = THIS_MODULE; |
| 369 | 370 | priv->nvmem_config_eeprom.reg_read = pci1xxxx_eeprom_read; |
| @@ -383,6 +384,7 @@ static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev, · 13 unmodified lines | ||
| 383 | 384 | |
| 384 | 385 | priv->nvmem_config_otp.type = NVMEM_TYPE_OTP; |
| 385 | 386 | priv->nvmem_config_otp.name = OTP_NAME; |
| 387 | + priv->nvmem_config_otp.id = NVMEM_DEVID_AUTO; | |
| 386 | 388 | priv->nvmem_config_otp.dev = &aux_dev->dev; |
| 387 | 389 | priv->nvmem_config_otp.owner = THIS_MODULE; |
| 388 | 390 | priv->nvmem_config_otp.reg_read = pci1xxxx_otp_read; |
| @@ -258,7 +258,6 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr) · 257 unmodified lines | ||
| 258 | 258 | int lcpu; |
| 259 | 259 | |
| 260 | 260 | BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); |
| 261 | − preempt_disable(); | |
| 262 | 261 | bs = gru_lock_kernel_context(-1); |
| 263 | 262 | lcpu = uv_blade_processor_id(); |
| 264 | 263 | *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE; |
| @@ -272,7 +271,6 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr) · 7 unmodified lines | ||
| 272 | 271 | static void gru_free_cpu_resources(void *cb, void *dsr) |
| 273 | 272 | { |
| 274 | 273 | gru_unlock_kernel_context(uv_numa_blade_id()); |
| 275 | − preempt_enable(); | |
| 276 | 274 | } |
| 277 | 275 | |
| 278 | 276 | /* |
| @@ -937,10 +937,8 @@ vm_fault_t gru_fault(struct vm_fault *vmf) · 936 unmodified lines | ||
| 937 | 937 | |
| 938 | 938 | again: |
| 939 | 939 | mutex_lock(>s->ts_ctxlock); |
| 940 | − preempt_disable(); | |
| 941 | 940 | |
| 942 | 941 | if (gru_check_context_placement(gts)) { |
| 943 | − preempt_enable(); | |
| 944 | 942 | mutex_unlock(>s->ts_ctxlock); |
| 945 | 943 | gru_unload_context(gts, 1); |
| 946 | 944 | return VM_FAULT_NOPAGE; |
| @@ -949,7 +947,6 @@ again: · 2 unmodified lines | ||
| 949 | 947 | if (!gts->ts_gru) { |
| 950 | 948 | STAT(load_user_context); |
| 951 | 949 | if (!gru_assign_gru_context(gts)) { |
| 952 | − preempt_enable(); | |
| 953 | 950 | mutex_unlock(>s->ts_ctxlock); |
| 954 | 951 | set_current_state(TASK_INTERRUPTIBLE); |
| 955 | 952 | schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ |
| @@ -965,7 +962,6 @@ again: · 9 unmodified lines | ||
| 965 | 962 | vma->vm_page_prot); |
| 966 | 963 | } |
| 967 | 964 | |
| 968 | − preempt_enable(); | |
| 969 | 965 | mutex_unlock(>s->ts_ctxlock); |
| 970 | 966 | |
| 971 | 967 | return VM_FAULT_NOPAGE; |
| @@ -65,7 +65,6 @@ static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state · 64 unmodified lines | ||
| 65 | 65 | struct gru_tlb_global_handle *tgh; |
| 66 | 66 | int n; |
| 67 | 67 | |
| 68 | − preempt_disable(); | |
| 69 | 68 | if (uv_numa_blade_id() == gru->gs_blade_id) |
| 70 | 69 | n = get_on_blade_tgh(gru); |
| 71 | 70 | else |
| @@ -79,7 +78,6 @@ static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state · 7 unmodified lines | ||
| 79 | 78 | static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh) |
| 80 | 79 | { |
| 81 | 80 | unlock_tgh_handle(tgh); |
| 82 | − preempt_enable(); | |
| 83 | 81 | } |
| 84 | 82 | |
| 85 | 83 | /* |
| @@ -388,7 +388,8 @@ static struct gendisk *mmc_alloc_disk(struct mmc_queue *mq, · 387 unmodified lines | ||
| 388 | 388 | |
| 389 | 389 | blk_queue_rq_timeout(mq->queue, 60 * HZ); |
| 390 | 390 | |
| 391 | − dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue)); | |
| 391 | + if (mmc_dev(host)->dma_parms) | |
| 392 | + dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue)); | |
| 392 | 393 | |
| 393 | 394 | INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler); |
| 394 | 395 | INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); |
| @@ -38,9 +38,8 @@ struct mvsd_host { · 37 unmodified lines | ||
| 38 | 38 | unsigned int xfer_mode; |
| 39 | 39 | unsigned int intr_en; |
| 40 | 40 | unsigned int ctrl; |
| 41 | − bool use_pio; | |
| 42 | − struct sg_mapping_iter sg_miter; | |
| 43 | 41 | unsigned int pio_size; |
| 42 | + void *pio_ptr; | |
| 44 | 43 | unsigned int sg_frags; |
| 45 | 44 | unsigned int ns_per_clk; |
| 46 | 45 | unsigned int clock; |
| @@ -115,18 +114,11 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data) · 68 unmodified lines | ||
| 115 | 114 | * data when the buffer is not aligned on a 64 byte |
| 116 | 115 | * boundary. |
| 117 | 116 | */ |
| 118 | − unsigned int miter_flags = SG_MITER_ATOMIC; /* Used from IRQ */ | |
| 119 | − | |
| 120 | − if (data->flags & MMC_DATA_READ) | |
| 121 | − miter_flags |= SG_MITER_TO_SG; | |
| 122 | − else | |
| 123 | − miter_flags |= SG_MITER_FROM_SG; | |
| 124 | − | |
| 125 | 117 | host->pio_size = data->blocks * data->blksz; |
| 126 | − sg_miter_start(&host->sg_miter, data->sg, data->sg_len, miter_flags); | |
| 118 | + host->pio_ptr = sg_virt(data->sg); | |
| 127 | 119 | if (!nodma) |
| 128 | − dev_dbg(host->dev, "fallback to PIO for data\n"); | |
| 129 | − host->use_pio = true; | |
| 120 | + dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n", | |
| 121 | + host->pio_ptr, host->pio_size); | |
| 130 | 122 | return 1; |
| 131 | 123 | } else { |
| 132 | 124 | dma_addr_t phys_addr; |
| @@ -137,7 +129,6 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data) · 4 unmodified lines | ||
| 137 | 129 | phys_addr = sg_dma_address(data->sg); |
| 138 | 130 | mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff); |
| 139 | 131 | mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16); |
| 140 | − host->use_pio = false; | |
| 141 | 132 | return 0; |
| 142 | 133 | } |
| 143 | 134 | } |
| @@ -297,8 +288,8 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data, · 153 unmodified lines | ||
| 297 | 288 | { |
| 298 | 289 | void __iomem *iobase = host->base; |
| 299 | 290 | |
| 300 | − if (host->use_pio) { | |
| 301 | − sg_miter_stop(&host->sg_miter); | |
| 291 | + if (host->pio_ptr) { | |
| 292 | + host->pio_ptr = NULL; | |
| 302 | 293 | host->pio_size = 0; |
| 303 | 294 | } else { |
| 304 | 295 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags, |
| @@ -353,12 +344,9 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data, · 48 unmodified lines | ||
| 353 | 344 | static irqreturn_t mvsd_irq(int irq, void *dev) |
| 354 | 345 | { |
| 355 | 346 | struct mvsd_host *host = dev; |
| 356 | − struct sg_mapping_iter *sgm = &host->sg_miter; | |
| 357 | 347 | void __iomem *iobase = host->base; |
| 358 | 348 | u32 intr_status, intr_done_mask; |
| 359 | 349 | int irq_handled = 0; |
| 360 | − u16 *p; | |
| 361 | − int s; | |
| 362 | 350 | |
| 363 | 351 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 364 | 352 | dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n", |
| @@ -382,36 +370,15 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 17 unmodified lines | ||
| 382 | 370 | spin_lock(&host->lock); |
| 383 | 371 | |
| 384 | 372 | /* PIO handling, if needed. Messy business... */ |
| 385 | − if (host->use_pio) { | |
| 386 | − /* | |
| 387 | − * As we set sgm->consumed this always gives a valid buffer | |
| 388 | − * position. | |
| 389 | − */ | |
| 390 | − if (!sg_miter_next(sgm)) { | |
| 391 | − /* This should not happen */ | |
| 392 | − dev_err(host->dev, "ran out of scatter segments\n"); | |
| 393 | − spin_unlock(&host->lock); | |
| 394 | − host->intr_en &= | |
| 395 | − ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W | | |
| 396 | − MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W); | |
| 397 | − mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); | |
| 398 | − return IRQ_HANDLED; | |
| 399 | − } | |
| 400 | − p = sgm->addr; | |
| 401 | − s = sgm->length; | |
| 402 | − if (s > host->pio_size) | |
| 403 | − s = host->pio_size; | |
| 404 | − } | |
| 405 | − | |
| 406 | − if (host->use_pio && | |
| 373 | + if (host->pio_size && | |
| 407 | 374 | (intr_status & host->intr_en & |
| 408 | 375 | (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) { |
| 409 | − | |
| 376 | + u16 *p = host->pio_ptr; | |
| 377 | + int s = host->pio_size; | |
| 410 | 378 | while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) { |
| 411 | 379 | readsw(iobase + MVSD_FIFO, p, 16); |
| 412 | 380 | p += 16; |
| 413 | 381 | s -= 32; |
| 414 | − sgm->consumed += 32; | |
| 415 | 382 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 416 | 383 | } |
| 417 | 384 | /* |
| @@ -424,7 +391,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 6 unmodified lines | ||
| 424 | 391 | put_unaligned(mvsd_read(MVSD_FIFO), p++); |
| 425 | 392 | put_unaligned(mvsd_read(MVSD_FIFO), p++); |
| 426 | 393 | s -= 4; |
| 427 | − sgm->consumed += 4; | |
| 428 | 394 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 429 | 395 | } |
| 430 | 396 | if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) { |
| @@ -432,13 +398,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 1 unmodified line | ||
| 432 | 398 | val[0] = mvsd_read(MVSD_FIFO); |
| 433 | 399 | val[1] = mvsd_read(MVSD_FIFO); |
| 434 | 400 | memcpy(p, ((void *)&val) + 4 - s, s); |
| 435 | − sgm->consumed += s; | |
| 436 | 401 | s = 0; |
| 437 | 402 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 438 | 403 | } |
| 439 | − /* PIO transfer done */ | |
| 440 | − host->pio_size -= sgm->consumed; | |
| 441 | − if (host->pio_size == 0) { | |
| 404 | + if (s == 0) { | |
| 442 | 405 | host->intr_en &= |
| 443 | 406 | ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W); |
| 444 | 407 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); |
| @@ -450,10 +413,14 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 5 unmodified lines | ||
| 450 | 413 | } |
| 451 | 414 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", |
| 452 | 415 | s, intr_status, mvsd_read(MVSD_HW_STATE)); |
| 416 | + host->pio_ptr = p; | |
| 417 | + host->pio_size = s; | |
| 453 | 418 | irq_handled = 1; |
| 454 | − } else if (host->use_pio && | |
| 419 | + } else if (host->pio_size && | |
| 455 | 420 | (intr_status & host->intr_en & |
| 456 | 421 | (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) { |
| 422 | + u16 *p = host->pio_ptr; | |
| 423 | + int s = host->pio_size; | |
| 457 | 424 | /* |
| 458 | 425 | * The TX_FIFO_8W bit is unreliable. When set, bursting |
| 459 | 426 | * 16 halfwords all at once in the FIFO drops data. Actually |
| @@ -464,7 +431,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 4 unmodified lines | ||
| 464 | 431 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); |
| 465 | 432 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); |
| 466 | 433 | s -= 4; |
| 467 | − sgm->consumed += 4; | |
| 468 | 434 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 469 | 435 | } |
| 470 | 436 | if (s < 4) { |
| @@ -473,13 +439,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 2 unmodified lines | ||
| 473 | 439 | memcpy(((void *)&val) + 4 - s, p, s); |
| 474 | 440 | mvsd_write(MVSD_FIFO, val[0]); |
| 475 | 441 | mvsd_write(MVSD_FIFO, val[1]); |
| 476 | − sgm->consumed += s; | |
| 477 | 442 | s = 0; |
| 478 | 443 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 479 | 444 | } |
| 480 | − /* PIO transfer done */ | |
| 481 | − host->pio_size -= sgm->consumed; | |
| 482 | − if (host->pio_size == 0) { | |
| 445 | + if (s == 0) { | |
| 483 | 446 | host->intr_en &= |
| 484 | 447 | ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W); |
| 485 | 448 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); |
| @@ -487,6 +450,8 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 1 unmodified line | ||
| 487 | 450 | } |
| 488 | 451 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", |
| 489 | 452 | s, intr_status, mvsd_read(MVSD_HW_STATE)); |
| 453 | + host->pio_ptr = p; | |
| 454 | + host->pio_size = s; | |
| 490 | 455 | irq_handled = 1; |
| 491 | 456 | } |
| 492 | 457 | |
| @@ -852,6 +852,14 @@ static void th1520_sdhci_reset(struct sdhci_host *host, u8 mask) · 851 unmodified lines | ||
| 852 | 852 | |
| 853 | 853 | sdhci_reset(host, mask); |
| 854 | 854 | |
| 855 | + /* The T-Head 1520 SoC does not comply with the SDHCI specification | |
| 856 | + * regarding the "Software Reset for CMD line should clear 'Command | |
| 857 | + * Complete' in the Normal Interrupt Status Register." Clear the bit | |
| 858 | + * here to compensate for this quirk. | |
| 859 | + */ | |
| 860 | + if (mask & SDHCI_RESET_CMD) | |
| 861 | + sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS); | |
| 862 | + | |
| 855 | 863 | if (priv->flags & FLAG_IO_FIXED_1V8) { |
| 856 | 864 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| 857 | 865 | if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/phylink.h> |
| 28 | 28 | #include <linux/etherdevice.h> |
| 29 | 29 | #include <linux/if_bridge.h> |
| 30 | +#include <linux/if_vlan.h> | |
| 30 | 31 | #include <net/dsa.h> |
| 31 | 32 | |
| 32 | 33 | #include "b53_regs.h" |
| @@ -224,6 +225,9 @@ static const struct b53_mib_desc b53_mibs_58xx[] = { · 191 unmodified lines | ||
| 224 | 225 | |
| 225 | 226 | #define B53_MIBS_58XX_SIZE ARRAY_SIZE(b53_mibs_58xx) |
| 226 | 227 | |
| 228 | +#define B53_MAX_MTU_25 (1536 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) | |
| 229 | +#define B53_MAX_MTU (9720 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) | |
| 230 | + | |
| 227 | 231 | static int b53_do_vlan_op(struct b53_device *dev, u8 op) |
| 228 | 232 | { |
| 229 | 233 | unsigned int i; |
| @@ -2254,20 +2258,25 @@ static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) · 2024 unmodified lines | ||
| 2254 | 2258 | bool allow_10_100; |
| 2255 | 2259 | |
| 2256 | 2260 | if (is5325(dev) || is5365(dev)) |
| 2257 | − return -EOPNOTSUPP; | |
| 2261 | + return 0; | |
| 2258 | 2262 | |
| 2259 | 2263 | if (!dsa_is_cpu_port(ds, port)) |
| 2260 | 2264 | return 0; |
| 2261 | 2265 | |
| 2262 | − enable_jumbo = (mtu >= JMS_MIN_SIZE); | |
| 2263 | − allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); | |
| 2266 | + enable_jumbo = (mtu > ETH_DATA_LEN); | |
| 2267 | + allow_10_100 = !is63xx(dev); | |
| 2264 | 2268 | |
| 2265 | 2269 | return b53_set_jumbo(dev, enable_jumbo, allow_10_100); |
| 2266 | 2270 | } |
| 2267 | 2271 | |
| 2268 | 2272 | static int b53_get_max_mtu(struct dsa_switch *ds, int port) |
| 2269 | 2273 | { |
| 2270 | − return JMS_MAX_SIZE; | |
| 2274 | + struct b53_device *dev = ds->priv; | |
| 2275 | + | |
| 2276 | + if (is5325(dev) || is5365(dev)) | |
| 2277 | + return B53_MAX_MTU_25; | |
| 2278 | + | |
| 2279 | + return B53_MAX_MTU; | |
| 2271 | 2280 | } |
| 2272 | 2281 | |
| 2273 | 2282 | static const struct phylink_mac_ops b53_phylink_mac_ops = { |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/module.h> |
| 7 | 7 | #include <linux/gpio/consumer.h> |
| 8 | 8 | #include <linux/regmap.h> |
| 9 | +#include <linux/iopoll.h> | |
| 9 | 10 | #include <linux/mutex.h> |
| 10 | 11 | #include <linux/mii.h> |
| 11 | 12 | #include <linux/of.h> |
| @@ -839,6 +840,8 @@ static void lan9303_handle_reset(struct lan9303 *chip) · 827 unmodified lines | ||
| 839 | 840 | if (!chip->reset_gpio) |
| 840 | 841 | return; |
| 841 | 842 | |
| 843 | + gpiod_set_value_cansleep(chip->reset_gpio, 1); | |
| 844 | + | |
| 842 | 845 | if (chip->reset_duration != 0) |
| 843 | 846 | msleep(chip->reset_duration); |
| 844 | 847 | |
| @@ -864,8 +867,34 @@ static int lan9303_disable_processing(struct lan9303 *chip) · 19 unmodified lines | ||
| 864 | 867 | static int lan9303_check_device(struct lan9303 *chip) |
| 865 | 868 | { |
| 866 | 869 | int ret; |
| 870 | + int err; | |
| 867 | 871 | u32 reg; |
| 868 | 872 | |
| 873 | + /* In I2C-managed configurations this polling loop will clash with | |
| 874 | + * switch's reading of EEPROM right after reset and this behaviour is | |
| 875 | + * not configurable. While lan9303_read() already has quite long retry | |
| 876 | + * timeout, seems not all cases are being detected as arbitration error. | |
| 877 | + * | |
| 878 | + * According to datasheet, EEPROM loader has 30ms timeout (in case of | |
| 879 | + * missing EEPROM). | |
| 880 | + * | |
| 881 | + * Loading of the largest supported EEPROM is expected to take at least | |
| 882 | + * 5.9s. | |
| 883 | + */ | |
| 884 | + err = read_poll_timeout(lan9303_read, ret, | |
| 885 | + !ret && reg & LAN9303_HW_CFG_READY, | |
| 886 | + 20000, 6000000, false, | |
| 887 | + chip->regmap, LAN9303_HW_CFG, ®); | |
| 888 | + if (ret) { | |
| 889 | + dev_err(chip->dev, "failed to read HW_CFG reg: %pe\n", | |
| 890 | + ERR_PTR(ret)); | |
| 891 | + return ret; | |
| 892 | + } | |
| 893 | + if (err) { | |
| 894 | + dev_err(chip->dev, "HW_CFG not ready: 0x%08x\n", reg); | |
| 895 | + return err; | |
| 896 | + } | |
| 897 | + | |
| 869 | 898 | ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, ®); |
| 870 | 899 | if (ret) { |
| 871 | 900 | dev_err(chip->dev, "failed to read chip revision register: %d\n", |
| @@ -2733,26 +2733,27 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port) · 2732 unmodified lines | ||
| 2733 | 2733 | return MICREL_KSZ8_P1_ERRATA; |
| 2734 | 2734 | break; |
| 2735 | 2735 | case KSZ8567_CHIP_ID: |
| 2736 | + /* KSZ8567R Errata DS80000752C Module 4 */ | |
| 2737 | + case KSZ8765_CHIP_ID: | |
| 2738 | + case KSZ8794_CHIP_ID: | |
| 2739 | + case KSZ8795_CHIP_ID: | |
| 2740 | + /* KSZ879x/KSZ877x/KSZ876x Errata DS80000687C Module 2 */ | |
| 2736 | 2741 | case KSZ9477_CHIP_ID: |
| 2742 | + /* KSZ9477S Errata DS80000754A Module 4 */ | |
| 2737 | 2743 | case KSZ9567_CHIP_ID: |
| 2744 | + /* KSZ9567S Errata DS80000756A Module 4 */ | |
| 2738 | 2745 | case KSZ9896_CHIP_ID: |
| 2746 | + /* KSZ9896C Errata DS80000757A Module 3 */ | |
| 2739 | 2747 | case KSZ9897_CHIP_ID: |
| 2740 | − /* KSZ9477 Errata DS80000754C | |
| 2741 | − * | |
| 2742 | − * Module 4: Energy Efficient Ethernet (EEE) feature select must | |
| 2743 | − * be manually disabled | |
| 2748 | + /* KSZ9897R Errata DS80000758C Module 4 */ | |
| 2749 | + /* Energy Efficient Ethernet (EEE) feature select must be manually disabled | |
| 2744 | 2750 | * The EEE feature is enabled by default, but it is not fully |
| 2745 | 2751 | * operational. It must be manually disabled through register |
| 2746 | 2752 | * controls. If not disabled, the PHY ports can auto-negotiate |
| 2747 | 2753 | * to enable EEE, and this feature can cause link drops when |
| 2748 | 2754 | * linked to another device supporting EEE. |
| 2749 | 2755 | * |
| 2750 | − * The same item appears in the errata for the KSZ9567, KSZ9896, | |
| 2751 | − * and KSZ9897. | |
| 2752 | − * | |
| 2753 | − * A similar item appears in the errata for the KSZ8567, but | |
| 2754 | − * provides an alternative workaround. For now, use the simple | |
| 2755 | − * workaround of disabling the EEE feature for this device too. | |
| 2756 | + * The same item appears in the errata for all switches above. | |
| 2756 | 2757 | */ |
| 2757 | 2758 | return MICREL_NO_EEE; |
| 2758 | 2759 | } |
| @@ -6347,7 +6347,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { · 6346 unmodified lines | ||
| 6347 | 6347 | .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), |
| 6348 | 6348 | .num_internal_phys = 5, |
| 6349 | 6349 | .internal_phys_offset = 3, |
| 6350 | − .max_vid = 4095, | |
| 6350 | + .max_vid = 8191, | |
| 6351 | 6351 | .max_sid = 63, |
| 6352 | 6352 | .port_base_addr = 0x0, |
| 6353 | 6353 | .phy_base_addr = 0x0, |
| @@ -206,6 +206,7 @@ struct mv88e6xxx_gpio_ops; · 205 unmodified lines | ||
| 206 | 206 | struct mv88e6xxx_avb_ops; |
| 207 | 207 | struct mv88e6xxx_ptp_ops; |
| 208 | 208 | struct mv88e6xxx_pcs_ops; |
| 209 | +struct mv88e6xxx_cc_coeffs; | |
| 209 | 210 | |
| 210 | 211 | struct mv88e6xxx_irq { |
| 211 | 212 | u16 masked; |
| @@ -408,6 +409,7 @@ struct mv88e6xxx_chip { · 196 unmodified lines | ||
| 408 | 409 | struct cyclecounter tstamp_cc; |
| 409 | 410 | struct timecounter tstamp_tc; |
| 410 | 411 | struct delayed_work overflow_work; |
| 412 | + const struct mv88e6xxx_cc_coeffs *cc_coeffs; | |
| 411 | 413 | |
| 412 | 414 | struct ptp_clock *ptp_clock; |
| 413 | 415 | struct ptp_clock_info ptp_clock_info; |
| @@ -731,10 +733,6 @@ struct mv88e6xxx_ptp_ops { · 317 unmodified lines | ||
| 731 | 733 | int arr1_sts_reg; |
| 732 | 734 | int dep_sts_reg; |
| 733 | 735 | u32 rx_filters; |
| 734 | − u32 cc_shift; | |
| 735 | − u32 cc_mult; | |
| 736 | − u32 cc_mult_num; | |
| 737 | − u32 cc_mult_dem; | |
| 738 | 736 | }; |
| 739 | 737 | |
| 740 | 738 | struct mv88e6xxx_pcs_ops { |
| @@ -1713,6 +1713,7 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port, · 1712 unmodified lines | ||
| 1713 | 1713 | ptr = shift / 8; |
| 1714 | 1714 | shift %= 8; |
| 1715 | 1715 | mask >>= ptr * 8; |
| 1716 | + ptr <<= 8; | |
| 1716 | 1717 | |
| 1717 | 1718 | err = mv88e6393x_port_policy_read(chip, port, ptr, ®); |
| 1718 | 1719 | if (err) |
| @@ -18,6 +18,13 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #define MV88E6XXX_MAX_ADJ_PPB 1000000 |
| 20 | 20 | |
| 21 | +struct mv88e6xxx_cc_coeffs { | |
| 22 | + u32 cc_shift; | |
| 23 | + u32 cc_mult; | |
| 24 | + u32 cc_mult_num; | |
| 25 | + u32 cc_mult_dem; | |
| 26 | +}; | |
| 27 | + | |
| 21 | 28 | /* Family MV88E6250: |
| 22 | 29 | * Raw timestamps are in units of 10-ns clock periods. |
| 23 | 30 | * |
| @@ -25,22 +32,43 @@ · 1 unmodified line | ||
| 25 | 32 | * simplifies to |
| 26 | 33 | * clkadj = scaled_ppm * 2^7 / 5^5 |
| 27 | 34 | */ |
| 28 | −#define MV88E6250_CC_SHIFT 28 | |
| 29 | −#define MV88E6250_CC_MULT (10 << MV88E6250_CC_SHIFT) | |
| 30 | −#define MV88E6250_CC_MULT_NUM (1 << 7) | |
| 31 | −#define MV88E6250_CC_MULT_DEM 3125ULL | |
| 35 | +#define MV88E6XXX_CC_10NS_SHIFT 28 | |
| 36 | +static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = { | |
| 37 | + .cc_shift = MV88E6XXX_CC_10NS_SHIFT, | |
| 38 | + .cc_mult = 10 << MV88E6XXX_CC_10NS_SHIFT, | |
| 39 | + .cc_mult_num = 1 << 7, | |
| 40 | + .cc_mult_dem = 3125ULL, | |
| 41 | +}; | |
| 32 | 42 | |
| 33 | −/* Other families: | |
| 43 | +/* Other families except MV88E6393X in internal clock mode: | |
| 34 | 44 | * Raw timestamps are in units of 8-ns clock periods. |
| 35 | 45 | * |
| 36 | 46 | * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16) |
| 37 | 47 | * simplifies to |
| 38 | 48 | * clkadj = scaled_ppm * 2^9 / 5^6 |
| 39 | 49 | */ |
| 40 | −#define MV88E6XXX_CC_SHIFT 28 | |
| 41 | −#define MV88E6XXX_CC_MULT (8 << MV88E6XXX_CC_SHIFT) | |
| 42 | −#define MV88E6XXX_CC_MULT_NUM (1 << 9) | |
| 43 | −#define MV88E6XXX_CC_MULT_DEM 15625ULL | |
| 50 | +#define MV88E6XXX_CC_8NS_SHIFT 28 | |
| 51 | +static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = { | |
| 52 | + .cc_shift = MV88E6XXX_CC_8NS_SHIFT, | |
| 53 | + .cc_mult = 8 << MV88E6XXX_CC_8NS_SHIFT, | |
| 54 | + .cc_mult_num = 1 << 9, | |
| 55 | + .cc_mult_dem = 15625ULL | |
| 56 | +}; | |
| 57 | + | |
| 58 | +/* Family MV88E6393X using internal clock: | |
| 59 | + * Raw timestamps are in units of 4-ns clock periods. | |
| 60 | + * | |
| 61 | + * clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16) | |
| 62 | + * simplifies to | |
| 63 | + * clkadj = scaled_ppm * 2^8 / 5^6 | |
| 64 | + */ | |
| 65 | +#define MV88E6XXX_CC_4NS_SHIFT 28 | |
| 66 | +static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_4ns_coeffs = { | |
| 67 | + .cc_shift = MV88E6XXX_CC_4NS_SHIFT, | |
| 68 | + .cc_mult = 4 << MV88E6XXX_CC_4NS_SHIFT, | |
| 69 | + .cc_mult_num = 1 << 8, | |
| 70 | + .cc_mult_dem = 15625ULL | |
| 71 | +}; | |
| 44 | 72 | |
| 45 | 73 | #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100) |
| 46 | 74 | |
| @@ -83,6 +111,33 @@ static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin, · 36 unmodified lines | ||
| 83 | 111 | return chip->info->ops->gpio_ops->set_pctl(chip, pin, func); |
| 84 | 112 | } |
| 85 | 113 | |
| 114 | +static const struct mv88e6xxx_cc_coeffs * | |
| 115 | +mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip *chip) | |
| 116 | +{ | |
| 117 | + u16 period_ps; | |
| 118 | + int err; | |
| 119 | + | |
| 120 | + err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_CLOCK_PERIOD, &period_ps, 1); | |
| 121 | + if (err) { | |
| 122 | + dev_err(chip->dev, "failed to read cycle counter period: %d\n", | |
| 123 | + err); | |
| 124 | + return ERR_PTR(err); | |
| 125 | + } | |
| 126 | + | |
| 127 | + switch (period_ps) { | |
| 128 | + case 4000: | |
| 129 | + return &mv88e6xxx_cc_4ns_coeffs; | |
| 130 | + case 8000: | |
| 131 | + return &mv88e6xxx_cc_8ns_coeffs; | |
| 132 | + case 10000: | |
| 133 | + return &mv88e6xxx_cc_10ns_coeffs; | |
| 134 | + default: | |
| 135 | + dev_err(chip->dev, "unexpected cycle counter period of %u ps\n", | |
| 136 | + period_ps); | |
| 137 | + return ERR_PTR(-ENODEV); | |
| 138 | + } | |
| 139 | +} | |
| 140 | + | |
| 86 | 141 | static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc) |
| 87 | 142 | { |
| 88 | 143 | struct mv88e6xxx_chip *chip = cc_to_chip(cc); |
| @@ -204,7 +259,6 @@ out: · 115 unmodified lines | ||
| 204 | 259 | static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) |
| 205 | 260 | { |
| 206 | 261 | struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); |
| 207 | − const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; | |
| 208 | 262 | int neg_adj = 0; |
| 209 | 263 | u32 diff, mult; |
| 210 | 264 | u64 adj; |
| @@ -214,10 +268,10 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) · 3 unmodified lines | ||
| 214 | 268 | scaled_ppm = -scaled_ppm; |
| 215 | 269 | } |
| 216 | 270 | |
| 217 | − mult = ptp_ops->cc_mult; | |
| 218 | − adj = ptp_ops->cc_mult_num; | |
| 271 | + mult = chip->cc_coeffs->cc_mult; | |
| 272 | + adj = chip->cc_coeffs->cc_mult_num; | |
| 219 | 273 | adj *= scaled_ppm; |
| 220 | − diff = div_u64(adj, ptp_ops->cc_mult_dem); | |
| 274 | + diff = div_u64(adj, chip->cc_coeffs->cc_mult_dem); | |
| 221 | 275 | |
| 222 | 276 | mv88e6xxx_reg_lock(chip); |
| 223 | 277 | |
| @@ -364,10 +418,6 @@ const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = { · 140 unmodified lines | ||
| 364 | 418 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 365 | 419 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 366 | 420 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), |
| 367 | − .cc_shift = MV88E6XXX_CC_SHIFT, | |
| 368 | − .cc_mult = MV88E6XXX_CC_MULT, | |
| 369 | − .cc_mult_num = MV88E6XXX_CC_MULT_NUM, | |
| 370 | − .cc_mult_dem = MV88E6XXX_CC_MULT_DEM, | |
| 371 | 421 | }; |
| 372 | 422 | |
| 373 | 423 | const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = { |
| @@ -391,10 +441,6 @@ const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = { · 17 unmodified lines | ||
| 391 | 441 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 392 | 442 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 393 | 443 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), |
| 394 | − .cc_shift = MV88E6250_CC_SHIFT, | |
| 395 | − .cc_mult = MV88E6250_CC_MULT, | |
| 396 | − .cc_mult_num = MV88E6250_CC_MULT_NUM, | |
| 397 | − .cc_mult_dem = MV88E6250_CC_MULT_DEM, | |
| 398 | 444 | }; |
| 399 | 445 | |
| 400 | 446 | const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { |
| @@ -418,10 +464,6 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { · 17 unmodified lines | ||
| 418 | 464 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 419 | 465 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 420 | 466 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), |
| 421 | − .cc_shift = MV88E6XXX_CC_SHIFT, | |
| 422 | − .cc_mult = MV88E6XXX_CC_MULT, | |
| 423 | − .cc_mult_num = MV88E6XXX_CC_MULT_NUM, | |
| 424 | − .cc_mult_dem = MV88E6XXX_CC_MULT_DEM, | |
| 425 | 467 | }; |
| 426 | 468 | |
| 427 | 469 | const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = { |
| @@ -446,10 +488,6 @@ const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = { · 18 unmodified lines | ||
| 446 | 488 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 447 | 489 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 448 | 490 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), |
| 449 | − .cc_shift = MV88E6XXX_CC_SHIFT, | |
| 450 | − .cc_mult = MV88E6XXX_CC_MULT, | |
| 451 | − .cc_mult_num = MV88E6XXX_CC_MULT_NUM, | |
| 452 | − .cc_mult_dem = MV88E6XXX_CC_MULT_DEM, | |
| 453 | 491 | }; |
| 454 | 492 | |
| 455 | 493 | static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) |
| @@ -462,10 +500,10 @@ static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) · 6 unmodified lines | ||
| 462 | 500 | return 0; |
| 463 | 501 | } |
| 464 | 502 | |
| 465 | −/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3 | |
| 503 | +/* With a 250MHz input clock, the 32-bit timestamp counter overflows in ~17.2 | |
| 466 | 504 | * seconds; this task forces periodic reads so that we don't miss any. |
| 467 | 505 | */ |
| 468 | −#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16) | |
| 506 | +#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8) | |
| 469 | 507 | static void mv88e6xxx_ptp_overflow_check(struct work_struct *work) |
| 470 | 508 | { |
| 471 | 509 | struct delayed_work *dw = to_delayed_work(work); |
| @@ -484,11 +522,15 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip) · 12 unmodified lines | ||
| 484 | 522 | int i; |
| 485 | 523 | |
| 486 | 524 | /* Set up the cycle counter */ |
| 525 | + chip->cc_coeffs = mv88e6xxx_cc_coeff_get(chip); | |
| 526 | + if (IS_ERR(chip->cc_coeffs)) | |
| 527 | + return PTR_ERR(chip->cc_coeffs); | |
| 528 | + | |
| 487 | 529 | memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc)); |
| 488 | 530 | chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read; |
| 489 | 531 | chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32); |
| 490 | − chip->tstamp_cc.mult = ptp_ops->cc_mult; | |
| 491 | − chip->tstamp_cc.shift = ptp_ops->cc_shift; | |
| 532 | + chip->tstamp_cc.mult = chip->cc_coeffs->cc_mult; | |
| 533 | + chip->tstamp_cc.shift = chip->cc_coeffs->cc_shift; | |
| 492 | 534 | |
| 493 | 535 | timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, |
| 494 | 536 | ktime_to_ns(ktime_get_real())); |
| @@ -3158,7 +3158,6 @@ static int sja1105_setup(struct dsa_switch *ds) · 3157 unmodified lines | ||
| 3158 | 3158 | * TPID is ETH_P_SJA1105, and the VLAN ID is the port pvid. |
| 3159 | 3159 | */ |
| 3160 | 3160 | ds->vlan_filtering_is_global = true; |
| 3161 | − ds->untag_bridge_pvid = true; | |
| 3162 | 3161 | ds->fdb_isolation = true; |
| 3163 | 3162 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; |
| 3164 | 3163 | |
| @@ -851,7 +851,6 @@ static int vsc73xx_setup(struct dsa_switch *ds) · 850 unmodified lines | ||
| 851 | 851 | |
| 852 | 852 | dev_info(vsc->dev, "set up the switch\n"); |
| 853 | 853 | |
| 854 | − ds->untag_bridge_pvid = true; | |
| 855 | 854 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; |
| 856 | 855 | ds->fdb_isolation = true; |
| 857 | 856 | |
| @@ -318,11 +318,11 @@ static int adin1110_read_fifo(struct adin1110_port_priv *port_priv) · 317 unmodified lines | ||
| 318 | 318 | * from the ADIN1110 frame header. |
| 319 | 319 | */ |
| 320 | 320 | if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN) |
| 321 | − return ret; | |
| 321 | + return -EINVAL; | |
| 322 | 322 | |
| 323 | 323 | round_len = adin1110_round_len(frame_size); |
| 324 | 324 | if (round_len < 0) |
| 325 | − return ret; | |
| 325 | + return -EINVAL; | |
| 326 | 326 | |
| 327 | 327 | frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN; |
| 328 | 328 | memset(priv->data, 0, ADIN1110_RD_HEADER_LEN); |
| @@ -484,7 +484,7 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) · 483 unmodified lines | ||
| 484 | 484 | |
| 485 | 485 | if (unlikely(skb->len > MAX_FRAME_SIZE)) { |
| 486 | 486 | dev->stats.tx_errors++; |
| 487 | − goto out; | |
| 487 | + goto len_error; | |
| 488 | 488 | } |
| 489 | 489 | |
| 490 | 490 | /* Save skb pointer. */ |
| @@ -575,6 +575,7 @@ frag_map_error: · 84 unmodified lines | ||
| 575 | 575 | map_error: |
| 576 | 576 | if (net_ratelimit()) |
| 577 | 577 | dev_warn(greth->dev, "Could not create TX DMA mapping\n"); |
| 578 | +len_error: | |
| 578 | 579 | dev_kfree_skb(skb); |
| 579 | 580 | out: |
| 580 | 581 | return err; |
| @@ -105,10 +105,6 @@ static struct net_device * __init mvme147lance_probe(void) · 104 unmodified lines | ||
| 105 | 105 | macaddr[3] = address&0xff; |
| 106 | 106 | eth_hw_addr_set(dev, macaddr); |
| 107 | 107 | |
| 108 | − printk("%s: MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n", | |
| 109 | − dev->name, dev->base_addr, MVME147_LANCE_IRQ, | |
| 110 | − dev->dev_addr); | |
| 111 | − | |
| 112 | 108 | lp = netdev_priv(dev); |
| 113 | 109 | lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */ |
| 114 | 110 | if (!lp->ram) { |
| @@ -138,6 +134,9 @@ static struct net_device * __init mvme147lance_probe(void) · 23 unmodified lines | ||
| 138 | 134 | return ERR_PTR(err); |
| 139 | 135 | } |
| 140 | 136 | |
| 137 | + netdev_info(dev, "MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n", | |
| 138 | + dev->base_addr, MVME147_LANCE_IRQ, dev->dev_addr); | |
| 139 | + | |
| 141 | 140 | return dev; |
| 142 | 141 | } |
| 143 | 142 | |
| @@ -322,6 +322,7 @@ static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev) · 321 unmodified lines | ||
| 322 | 322 | } |
| 323 | 323 | /* Rewind so we do not have a hole */ |
| 324 | 324 | spb_index = intf->tx_spb_index; |
| 325 | + dev_kfree_skb(skb); | |
| 325 | 326 | return NETDEV_TX_OK; |
| 326 | 327 | } |
| 327 | 328 | |
| @@ -1359,6 +1359,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb, · 1358 unmodified lines | ||
| 1359 | 1359 | netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n", |
| 1360 | 1360 | skb->data, skb_len); |
| 1361 | 1361 | ret = NETDEV_TX_OK; |
| 1362 | + dev_kfree_skb_any(skb); | |
| 1362 | 1363 | goto out; |
| 1363 | 1364 | } |
| 1364 | 1365 | |
| @@ -2254,10 +2254,11 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, · 2253 unmodified lines | ||
| 2254 | 2254 | |
| 2255 | 2255 | if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { |
| 2256 | 2256 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 2257 | + unsigned long flags; | |
| 2257 | 2258 | |
| 2258 | − spin_lock_bh(&ptp->ptp_lock); | |
| 2259 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 2259 | 2260 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 2260 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 2261 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 2261 | 2262 | memset(skb_hwtstamps(skb), 0, |
| 2262 | 2263 | sizeof(*skb_hwtstamps(skb))); |
| 2263 | 2264 | skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); |
| @@ -2757,17 +2758,18 @@ static int bnxt_async_event_process(struct bnxt *bp, · 493 unmodified lines | ||
| 2757 | 2758 | case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE: |
| 2758 | 2759 | if (BNXT_PTP_USE_RTC(bp)) { |
| 2759 | 2760 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 2761 | + unsigned long flags; | |
| 2760 | 2762 | u64 ns; |
| 2761 | 2763 | |
| 2762 | 2764 | if (!ptp) |
| 2763 | 2765 | goto async_event_process_exit; |
| 2764 | 2766 | |
| 2765 | − spin_lock_bh(&ptp->ptp_lock); | |
| 2767 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 2766 | 2768 | bnxt_ptp_update_current_time(bp); |
| 2767 | 2769 | ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) << |
| 2768 | 2770 | BNXT_PHC_BITS) | ptp->current_time); |
| 2769 | 2771 | bnxt_ptp_rtc_timecounter_init(ptp, ns); |
| 2770 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 2772 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 2771 | 2773 | } |
| 2772 | 2774 | break; |
| 2773 | 2775 | } |
| @@ -13494,9 +13496,11 @@ static void bnxt_force_fw_reset(struct bnxt *bp) · 10720 unmodified lines | ||
| 13494 | 13496 | return; |
| 13495 | 13497 | |
| 13496 | 13498 | if (ptp) { |
| 13497 | − spin_lock_bh(&ptp->ptp_lock); | |
| 13499 | + unsigned long flags; | |
| 13500 | + | |
| 13501 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 13498 | 13502 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 13499 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 13503 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 13500 | 13504 | } else { |
| 13501 | 13505 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 13502 | 13506 | } |
| @@ -13561,9 +13565,11 @@ void bnxt_fw_reset(struct bnxt *bp) · 58 unmodified lines | ||
| 13561 | 13565 | int n = 0, tmo; |
| 13562 | 13566 | |
| 13563 | 13567 | if (ptp) { |
| 13564 | − spin_lock_bh(&ptp->ptp_lock); | |
| 13568 | + unsigned long flags; | |
| 13569 | + | |
| 13570 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 13565 | 13571 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 13566 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 13572 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 13567 | 13573 | } else { |
| 13568 | 13574 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 13569 | 13575 | } |
| @@ -62,13 +62,14 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info, · 61 unmodified lines | ||
| 62 | 62 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 63 | 63 | ptp_info); |
| 64 | 64 | u64 ns = timespec64_to_ns(ts); |
| 65 | + unsigned long flags; | |
| 65 | 66 | |
| 66 | 67 | if (BNXT_PTP_USE_RTC(ptp->bp)) |
| 67 | 68 | return bnxt_ptp_cfg_settime(ptp->bp, ns); |
| 68 | 69 | |
| 69 | − spin_lock_bh(&ptp->ptp_lock); | |
| 70 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 70 | 71 | timecounter_init(&ptp->tc, &ptp->cc, ns); |
| 71 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 72 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 72 | 73 | return 0; |
| 73 | 74 | } |
| 74 | 75 | |
| @@ -100,13 +101,14 @@ static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts, · 25 unmodified lines | ||
| 100 | 101 | static void bnxt_ptp_get_current_time(struct bnxt *bp) |
| 101 | 102 | { |
| 102 | 103 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 104 | + unsigned long flags; | |
| 103 | 105 | |
| 104 | 106 | if (!ptp) |
| 105 | 107 | return; |
| 106 | − spin_lock_bh(&ptp->ptp_lock); | |
| 108 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 107 | 109 | WRITE_ONCE(ptp->old_time, ptp->current_time); |
| 108 | 110 | bnxt_refclk_read(bp, NULL, &ptp->current_time); |
| 109 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 111 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 110 | 112 | } |
| 111 | 113 | |
| 112 | 114 | static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts, |
| @@ -149,17 +151,18 @@ static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info, · 36 unmodified lines | ||
| 149 | 151 | { |
| 150 | 152 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 151 | 153 | ptp_info); |
| 154 | + unsigned long flags; | |
| 152 | 155 | u64 ns, cycles; |
| 153 | 156 | int rc; |
| 154 | 157 | |
| 155 | − spin_lock_bh(&ptp->ptp_lock); | |
| 158 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 156 | 159 | rc = bnxt_refclk_read(ptp->bp, sts, &cycles); |
| 157 | 160 | if (rc) { |
| 158 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 161 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 159 | 162 | return rc; |
| 160 | 163 | } |
| 161 | 164 | ns = timecounter_cyc2time(&ptp->tc, cycles); |
| 162 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 165 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 163 | 166 | *ts = ns_to_timespec64(ns); |
| 164 | 167 | |
| 165 | 168 | return 0; |
| @@ -177,6 +180,7 @@ void bnxt_ptp_update_current_time(struct bnxt *bp) · 11 unmodified lines | ||
| 177 | 180 | static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) |
| 178 | 181 | { |
| 179 | 182 | struct hwrm_port_mac_cfg_input *req; |
| 183 | + unsigned long flags; | |
| 180 | 184 | int rc; |
| 181 | 185 | |
| 182 | 186 | rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG); |
| @@ -190,9 +194,9 @@ static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) · 7 unmodified lines | ||
| 190 | 194 | if (rc) { |
| 191 | 195 | netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc); |
| 192 | 196 | } else { |
| 193 | − spin_lock_bh(&ptp->ptp_lock); | |
| 197 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 194 | 198 | bnxt_ptp_update_current_time(ptp->bp); |
| 195 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 199 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 196 | 200 | } |
| 197 | 201 | |
| 198 | 202 | return rc; |
| @@ -202,13 +206,14 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) · 3 unmodified lines | ||
| 202 | 206 | { |
| 203 | 207 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 204 | 208 | ptp_info); |
| 209 | + unsigned long flags; | |
| 205 | 210 | |
| 206 | 211 | if (BNXT_PTP_USE_RTC(ptp->bp)) |
| 207 | 212 | return bnxt_ptp_adjphc(ptp, delta); |
| 208 | 213 | |
| 209 | − spin_lock_bh(&ptp->ptp_lock); | |
| 214 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 210 | 215 | timecounter_adjtime(&ptp->tc, delta); |
| 211 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 216 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 212 | 217 | return 0; |
| 213 | 218 | } |
| 214 | 219 | |
| @@ -236,14 +241,15 @@ static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) · 21 unmodified lines | ||
| 236 | 241 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 237 | 242 | ptp_info); |
| 238 | 243 | struct bnxt *bp = ptp->bp; |
| 244 | + unsigned long flags; | |
| 239 | 245 | |
| 240 | 246 | if (!BNXT_MH(bp)) |
| 241 | 247 | return bnxt_ptp_adjfine_rtc(bp, scaled_ppm); |
| 242 | 248 | |
| 243 | − spin_lock_bh(&ptp->ptp_lock); | |
| 249 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 244 | 250 | timecounter_read(&ptp->tc); |
| 245 | 251 | ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm); |
| 246 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 252 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 247 | 253 | return 0; |
| 248 | 254 | } |
| 249 | 255 | |
| @@ -251,12 +257,13 @@ void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2) · 1 unmodified line | ||
| 251 | 257 | { |
| 252 | 258 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 253 | 259 | struct ptp_clock_event event; |
| 260 | + unsigned long flags; | |
| 254 | 261 | u64 ns, pps_ts; |
| 255 | 262 | |
| 256 | 263 | pps_ts = EVENT_PPS_TS(data2, data1); |
| 257 | − spin_lock_bh(&ptp->ptp_lock); | |
| 264 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 258 | 265 | ns = timecounter_cyc2time(&ptp->tc, pps_ts); |
| 259 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 266 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 260 | 267 | |
| 261 | 268 | switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) { |
| 262 | 269 | case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL: |
| @@ -393,16 +400,17 @@ static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns, · 130 unmodified lines | ||
| 393 | 400 | { |
| 394 | 401 | u64 cycles_now; |
| 395 | 402 | u64 nsec_now, nsec_delta; |
| 403 | + unsigned long flags; | |
| 396 | 404 | int rc; |
| 397 | 405 | |
| 398 | − spin_lock_bh(&ptp->ptp_lock); | |
| 406 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 399 | 407 | rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now); |
| 400 | 408 | if (rc) { |
| 401 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 409 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 402 | 410 | return rc; |
| 403 | 411 | } |
| 404 | 412 | nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now); |
| 405 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 413 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 406 | 414 | |
| 407 | 415 | nsec_delta = target_ns - nsec_now; |
| 408 | 416 | *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult); |
| @@ -689,6 +697,7 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) · 280 unmodified lines | ||
| 689 | 697 | struct skb_shared_hwtstamps timestamp; |
| 690 | 698 | struct bnxt_ptp_tx_req *txts_req; |
| 691 | 699 | unsigned long now = jiffies; |
| 700 | + unsigned long flags; | |
| 692 | 701 | u64 ts = 0, ns = 0; |
| 693 | 702 | u32 tmo = 0; |
| 694 | 703 | int rc; |
| @@ -702,9 +711,9 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) · 7 unmodified lines | ||
| 702 | 711 | tmo, slot); |
| 703 | 712 | if (!rc) { |
| 704 | 713 | memset(×tamp, 0, sizeof(timestamp)); |
| 705 | − spin_lock_bh(&ptp->ptp_lock); | |
| 714 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 706 | 715 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 707 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 716 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 708 | 717 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 709 | 718 | skb_tstamp_tx(txts_req->tx_skb, ×tamp); |
| 710 | 719 | ptp->stats.ts_pkts++; |
| @@ -730,6 +739,7 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) · 19 unmodified lines | ||
| 730 | 739 | unsigned long now = jiffies; |
| 731 | 740 | struct bnxt *bp = ptp->bp; |
| 732 | 741 | u16 cons = ptp->txts_cons; |
| 742 | + unsigned long flags; | |
| 733 | 743 | u32 num_requests; |
| 734 | 744 | int rc = 0; |
| 735 | 745 | |
| @@ -757,9 +767,9 @@ next_slot: · 21 unmodified lines | ||
| 757 | 767 | bnxt_ptp_get_current_time(bp); |
| 758 | 768 | ptp->next_period = now + HZ; |
| 759 | 769 | if (time_after_eq(now, ptp->next_overflow_check)) { |
| 760 | − spin_lock_bh(&ptp->ptp_lock); | |
| 770 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 761 | 771 | timecounter_read(&ptp->tc); |
| 762 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 772 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 763 | 773 | ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; |
| 764 | 774 | } |
| 765 | 775 | if (rc == -EAGAIN) |
| @@ -819,6 +829,7 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, · 53 unmodified lines | ||
| 819 | 829 | u32 opaque = tscmp->tx_ts_cmp_opaque; |
| 820 | 830 | struct bnxt_tx_ring_info *txr; |
| 821 | 831 | struct bnxt_sw_tx_bd *tx_buf; |
| 832 | + unsigned long flags; | |
| 822 | 833 | u64 ts, ns; |
| 823 | 834 | u16 cons; |
| 824 | 835 | |
| @@ -833,9 +844,9 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, · 8 unmodified lines | ||
| 833 | 844 | le32_to_cpu(tscmp->tx_ts_cmp_flags_type), |
| 834 | 845 | le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); |
| 835 | 846 | } else { |
| 836 | − spin_lock_bh(&ptp->ptp_lock); | |
| 847 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 837 | 848 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 838 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 849 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 839 | 850 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 840 | 851 | skb_tstamp_tx(tx_buf->skb, ×tamp); |
| 841 | 852 | } |
| @@ -975,6 +986,7 @@ void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns) · 133 unmodified lines | ||
| 975 | 986 | int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) |
| 976 | 987 | { |
| 977 | 988 | struct timespec64 tsp; |
| 989 | + unsigned long flags; | |
| 978 | 990 | u64 ns; |
| 979 | 991 | int rc; |
| 980 | 992 | |
| @@ -993,9 +1005,9 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) · 12 unmodified lines | ||
| 993 | 1005 | if (rc) |
| 994 | 1006 | return rc; |
| 995 | 1007 | } |
| 996 | − spin_lock_bh(&bp->ptp_cfg->ptp_lock); | |
| 1008 | + spin_lock_irqsave(&bp->ptp_cfg->ptp_lock, flags); | |
| 997 | 1009 | bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns); |
| 998 | − spin_unlock_bh(&bp->ptp_cfg->ptp_lock); | |
| 1010 | + spin_unlock_irqrestore(&bp->ptp_cfg->ptp_lock, flags); | |
| 999 | 1011 | |
| 1000 | 1012 | return 0; |
| 1001 | 1013 | } |
| @@ -1063,10 +1075,12 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) · 61 unmodified lines | ||
| 1063 | 1075 | atomic64_set(&ptp->stats.ts_err, 0); |
| 1064 | 1076 | |
| 1065 | 1077 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { |
| 1066 | − spin_lock_bh(&ptp->ptp_lock); | |
| 1078 | + unsigned long flags; | |
| 1079 | + | |
| 1080 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 1067 | 1081 | bnxt_refclk_read(bp, NULL, &ptp->current_time); |
| 1068 | 1082 | WRITE_ONCE(ptp->old_time, ptp->current_time); |
| 1069 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 1083 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 1070 | 1084 | ptp_schedule_worker(ptp->ptp_clock, 0); |
| 1071 | 1085 | } |
| 1072 | 1086 | ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO; |
| @@ -146,11 +146,13 @@ struct bnxt_ptp_cfg { · 145 unmodified lines | ||
| 146 | 146 | }; |
| 147 | 147 | |
| 148 | 148 | #if BITS_PER_LONG == 32 |
| 149 | −#define BNXT_READ_TIME64(ptp, dst, src) \ | |
| 150 | −do { \ | |
| 151 | − spin_lock_bh(&(ptp)->ptp_lock); \ | |
| 152 | − (dst) = (src); \ | |
| 153 | − spin_unlock_bh(&(ptp)->ptp_lock); \ | |
| 149 | +#define BNXT_READ_TIME64(ptp, dst, src) \ | |
| 150 | +do { \ | |
| 151 | + unsigned long flags; \ | |
| 152 | + \ | |
| 153 | + spin_lock_irqsave(&(ptp)->ptp_lock, flags); \ | |
| 154 | + (dst) = (src); \ | |
| 155 | + spin_unlock_irqrestore(&(ptp)->ptp_lock, flags); \ | |
| 154 | 156 | } while (0) |
| 155 | 157 | #else |
| 156 | 158 | #define BNXT_READ_TIME64(ptp, dst, src) \ |
| @@ -930,9 +930,6 @@ static int macb_mdiobus_register(struct macb *bp) · 929 unmodified lines | ||
| 930 | 930 | return ret; |
| 931 | 931 | } |
| 932 | 932 | |
| 933 | − if (of_phy_is_fixed_link(np)) | |
| 934 | − return mdiobus_register(bp->mii_bus); | |
| 935 | − | |
| 936 | 933 | /* Only create the PHY from the device tree if at least one PHY is |
| 937 | 934 | * described. Otherwise scan the entire MDIO bus. We do this to support |
| 938 | 935 | * old device tree that did not follow the best practices and did not |
| @@ -953,8 +950,19 @@ static int macb_mdiobus_register(struct macb *bp) · 14 unmodified lines | ||
| 953 | 950 | |
| 954 | 951 | static int macb_mii_init(struct macb *bp) |
| 955 | 952 | { |
| 953 | + struct device_node *child, *np = bp->pdev->dev.of_node; | |
| 956 | 954 | int err = -ENXIO; |
| 957 | 955 | |
| 956 | + /* With fixed-link, we don't need to register the MDIO bus, | |
| 957 | + * except if we have a child named "mdio" in the device tree. | |
| 958 | + * In that case, some devices may be attached to the MACB's MDIO bus. | |
| 959 | + */ | |
| 960 | + child = of_get_child_by_name(np, "mdio"); | |
| 961 | + if (child) | |
| 962 | + of_node_put(child); | |
| 963 | + else if (of_phy_is_fixed_link(np)) | |
| 964 | + return macb_mii_probe(bp->dev); | |
| 965 | + | |
| 958 | 966 | /* Enable management port */ |
| 959 | 967 | macb_writel(bp, NCR, MACB_BIT(MPE)); |
| 960 | 968 | |
| @@ -1381,10 +1381,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) · 1380 unmodified lines | ||
| 1381 | 1381 | be_get_wrb_params_from_skb(adapter, skb, &wrb_params); |
| 1382 | 1382 | |
| 1383 | 1383 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); |
| 1384 | − if (unlikely(!wrb_cnt)) { | |
| 1385 | − dev_kfree_skb_any(skb); | |
| 1386 | − goto drop; | |
| 1387 | − } | |
| 1384 | + if (unlikely(!wrb_cnt)) | |
| 1385 | + goto drop_skb; | |
| 1388 | 1386 | |
| 1389 | 1387 | /* if os2bmc is enabled and if the pkt is destined to bmc, |
| 1390 | 1388 | * enqueue the pkt a 2nd time with mgmt bit set. |
| @@ -1393,7 +1391,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) · 2 unmodified lines | ||
| 1393 | 1391 | BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); |
| 1394 | 1392 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); |
| 1395 | 1393 | if (unlikely(!wrb_cnt)) |
| 1396 | − goto drop; | |
| 1394 | + goto drop_skb; | |
| 1397 | 1395 | else |
| 1398 | 1396 | skb_get(skb); |
| 1399 | 1397 | } |
| @@ -1407,6 +1405,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) · 7 unmodified lines | ||
| 1407 | 1405 | be_xmit_flush(adapter, txo); |
| 1408 | 1406 | |
| 1409 | 1407 | return NETDEV_TX_OK; |
| 1408 | +drop_skb: | |
| 1409 | + dev_kfree_skb_any(skb); | |
| 1410 | 1410 | drop: |
| 1411 | 1411 | tx_stats(txo)->tx_drv_drops++; |
| 1412 | 1412 | /* Flush the already enqueued tx requests */ |
| @@ -1906,7 +1906,12 @@ static int ftgmac100_probe(struct platform_device *pdev) · 1905 unmodified lines | ||
| 1906 | 1906 | goto err_phy_connect; |
| 1907 | 1907 | } |
| 1908 | 1908 | |
| 1909 | − phydev = fixed_phy_register(PHY_POLL, &ncsi_phy_status, NULL); | |
| 1909 | + phydev = fixed_phy_register(PHY_POLL, &ncsi_phy_status, np); | |
| 1910 | + if (IS_ERR(phydev)) { | |
| 1911 | + dev_err(&pdev->dev, "failed to register fixed PHY device\n"); | |
| 1912 | + err = PTR_ERR(phydev); | |
| 1913 | + goto err_phy_connect; | |
| 1914 | + } | |
| 1910 | 1915 | err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link, |
| 1911 | 1916 | PHY_INTERFACE_MODE_MII); |
| 1912 | 1917 | if (err) { |
| @@ -902,6 +902,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget) · 901 unmodified lines | ||
| 902 | 902 | |
| 903 | 903 | if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) && |
| 904 | 904 | __netif_subqueue_stopped(ndev, tx_ring->index) && |
| 905 | + !test_bit(ENETC_TX_DOWN, &priv->flags) && | |
| 905 | 906 | (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) { |
| 906 | 907 | netif_wake_subqueue(ndev, tx_ring->index); |
| 907 | 908 | } |
| @@ -1377,6 +1378,9 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames, · 469 unmodified lines | ||
| 1377 | 1378 | int xdp_tx_bd_cnt, i, k; |
| 1378 | 1379 | int xdp_tx_frm_cnt = 0; |
| 1379 | 1380 | |
| 1381 | + if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) | |
| 1382 | + return -ENETDOWN; | |
| 1383 | + | |
| 1380 | 1384 | enetc_lock_mdio(); |
| 1381 | 1385 | |
| 1382 | 1386 | tx_ring = priv->xdp_tx_ring[smp_processor_id()]; |
| @@ -1521,7 +1525,6 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first, · 138 unmodified lines | ||
| 1521 | 1525 | &rx_ring->rx_swbd[rx_ring_first]); |
| 1522 | 1526 | enetc_bdr_idx_inc(rx_ring, &rx_ring_first); |
| 1523 | 1527 | } |
| 1524 | − rx_ring->stats.xdp_drops++; | |
| 1525 | 1528 | } |
| 1526 | 1529 | |
| 1527 | 1530 | static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, |
| @@ -1586,6 +1589,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 58 unmodified lines | ||
| 1586 | 1589 | fallthrough; |
| 1587 | 1590 | case XDP_DROP: |
| 1588 | 1591 | enetc_xdp_drop(rx_ring, orig_i, i); |
| 1592 | + rx_ring->stats.xdp_drops++; | |
| 1589 | 1593 | break; |
| 1590 | 1594 | case XDP_PASS: |
| 1591 | 1595 | rxbd = orig_rxbd; |
| @@ -1602,6 +1606,12 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 10 unmodified lines | ||
| 1602 | 1606 | break; |
| 1603 | 1607 | case XDP_TX: |
| 1604 | 1608 | tx_ring = priv->xdp_tx_ring[rx_ring->index]; |
| 1609 | + if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) { | |
| 1610 | + enetc_xdp_drop(rx_ring, orig_i, i); | |
| 1611 | + tx_ring->stats.xdp_tx_drops++; | |
| 1612 | + break; | |
| 1613 | + } | |
| 1614 | + | |
| 1605 | 1615 | xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr, |
| 1606 | 1616 | rx_ring, |
| 1607 | 1617 | orig_i, i); |
| @@ -2223,18 +2233,24 @@ static void enetc_enable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) · 615 unmodified lines | ||
| 2223 | 2233 | enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); |
| 2224 | 2234 | } |
| 2225 | 2235 | |
| 2226 | −static void enetc_enable_bdrs(struct enetc_ndev_priv *priv) | |
| 2236 | +static void enetc_enable_rx_bdrs(struct enetc_ndev_priv *priv) | |
| 2227 | 2237 | { |
| 2228 | 2238 | struct enetc_hw *hw = &priv->si->hw; |
| 2229 | 2239 | int i; |
| 2230 | 2240 | |
| 2231 | − for (i = 0; i < priv->num_tx_rings; i++) | |
| 2232 | − enetc_enable_txbdr(hw, priv->tx_ring[i]); | |
| 2233 | − | |
| 2234 | 2241 | for (i = 0; i < priv->num_rx_rings; i++) |
| 2235 | 2242 | enetc_enable_rxbdr(hw, priv->rx_ring[i]); |
| 2236 | 2243 | } |
| 2237 | 2244 | |
| 2245 | +static void enetc_enable_tx_bdrs(struct enetc_ndev_priv *priv) | |
| 2246 | +{ | |
| 2247 | + struct enetc_hw *hw = &priv->si->hw; | |
| 2248 | + int i; | |
| 2249 | + | |
| 2250 | + for (i = 0; i < priv->num_tx_rings; i++) | |
| 2251 | + enetc_enable_txbdr(hw, priv->tx_ring[i]); | |
| 2252 | +} | |
| 2253 | + | |
| 2238 | 2254 | static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) |
| 2239 | 2255 | { |
| 2240 | 2256 | int idx = rx_ring->index; |
| @@ -2251,18 +2267,24 @@ static void enetc_disable_txbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) · 10 unmodified lines | ||
| 2251 | 2267 | enetc_txbdr_wr(hw, idx, ENETC_TBMR, 0); |
| 2252 | 2268 | } |
| 2253 | 2269 | |
| 2254 | −static void enetc_disable_bdrs(struct enetc_ndev_priv *priv) | |
| 2270 | +static void enetc_disable_rx_bdrs(struct enetc_ndev_priv *priv) | |
| 2255 | 2271 | { |
| 2256 | 2272 | struct enetc_hw *hw = &priv->si->hw; |
| 2257 | 2273 | int i; |
| 2258 | 2274 | |
| 2259 | − for (i = 0; i < priv->num_tx_rings; i++) | |
| 2260 | − enetc_disable_txbdr(hw, priv->tx_ring[i]); | |
| 2261 | − | |
| 2262 | 2275 | for (i = 0; i < priv->num_rx_rings; i++) |
| 2263 | 2276 | enetc_disable_rxbdr(hw, priv->rx_ring[i]); |
| 2264 | 2277 | } |
| 2265 | 2278 | |
| 2279 | +static void enetc_disable_tx_bdrs(struct enetc_ndev_priv *priv) | |
| 2280 | +{ | |
| 2281 | + struct enetc_hw *hw = &priv->si->hw; | |
| 2282 | + int i; | |
| 2283 | + | |
| 2284 | + for (i = 0; i < priv->num_tx_rings; i++) | |
| 2285 | + enetc_disable_txbdr(hw, priv->tx_ring[i]); | |
| 2286 | +} | |
| 2287 | + | |
| 2266 | 2288 | static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring) |
| 2267 | 2289 | { |
| 2268 | 2290 | int delay = 8, timeout = 100; |
| @@ -2460,9 +2482,13 @@ void enetc_start(struct net_device *ndev) · 191 unmodified lines | ||
| 2460 | 2482 | enable_irq(irq); |
| 2461 | 2483 | } |
| 2462 | 2484 | |
| 2463 | − enetc_enable_bdrs(priv); | |
| 2485 | + enetc_enable_tx_bdrs(priv); | |
| 2486 | + | |
| 2487 | + enetc_enable_rx_bdrs(priv); | |
| 2464 | 2488 | |
| 2465 | 2489 | netif_tx_start_all_queues(ndev); |
| 2490 | + | |
| 2491 | + clear_bit(ENETC_TX_DOWN, &priv->flags); | |
| 2466 | 2492 | } |
| 2467 | 2493 | EXPORT_SYMBOL_GPL(enetc_start); |
| 2468 | 2494 | |
| @@ -2520,9 +2546,15 @@ void enetc_stop(struct net_device *ndev) · 51 unmodified lines | ||
| 2520 | 2546 | struct enetc_ndev_priv *priv = netdev_priv(ndev); |
| 2521 | 2547 | int i; |
| 2522 | 2548 | |
| 2549 | + set_bit(ENETC_TX_DOWN, &priv->flags); | |
| 2550 | + | |
| 2523 | 2551 | netif_tx_stop_all_queues(ndev); |
| 2524 | 2552 | |
| 2525 | − enetc_disable_bdrs(priv); | |
| 2553 | + enetc_disable_rx_bdrs(priv); | |
| 2554 | + | |
| 2555 | + enetc_wait_bdrs(priv); | |
| 2556 | + | |
| 2557 | + enetc_disable_tx_bdrs(priv); | |
| 2526 | 2558 | |
| 2527 | 2559 | for (i = 0; i < priv->bdr_int_num; i++) { |
| 2528 | 2560 | int irq = pci_irq_vector(priv->si->pdev, |
| @@ -2533,8 +2565,6 @@ void enetc_stop(struct net_device *ndev) · 4 unmodified lines | ||
| 2533 | 2565 | napi_disable(&priv->int_vector[i]->napi); |
| 2534 | 2566 | } |
| 2535 | 2567 | |
| 2536 | − enetc_wait_bdrs(priv); | |
| 2537 | − | |
| 2538 | 2568 | enetc_clear_interrupts(priv); |
| 2539 | 2569 | } |
| 2540 | 2570 | EXPORT_SYMBOL_GPL(enetc_stop); |
| @@ -325,6 +325,7 @@ enum enetc_active_offloads { · 324 unmodified lines | ||
| 325 | 325 | |
| 326 | 326 | enum enetc_flags_bit { |
| 327 | 327 | ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0, |
| 328 | + ENETC_TX_DOWN, | |
| 328 | 329 | }; |
| 329 | 330 | |
| 330 | 331 | /* interrupt coalescing modes */ |
| @@ -1077,7 +1077,8 @@ fec_restart(struct net_device *ndev) · 1076 unmodified lines | ||
| 1077 | 1077 | u32 rcntl = OPT_FRAME_SIZE | 0x04; |
| 1078 | 1078 | u32 ecntl = FEC_ECR_ETHEREN; |
| 1079 | 1079 | |
| 1080 | − fec_ptp_save_state(fep); | |
| 1080 | + if (fep->bufdesc_ex) | |
| 1081 | + fec_ptp_save_state(fep); | |
| 1081 | 1082 | |
| 1082 | 1083 | /* Whack a reset. We should wait for this. |
| 1083 | 1084 | * For i.MX6SX SOC, enet use AXI bus, we use disable MAC |
| @@ -1340,7 +1341,8 @@ fec_stop(struct net_device *ndev) · 256 unmodified lines | ||
| 1340 | 1341 | netdev_err(ndev, "Graceful transmit stop did not complete!\n"); |
| 1341 | 1342 | } |
| 1342 | 1343 | |
| 1343 | − fec_ptp_save_state(fep); | |
| 1344 | + if (fep->bufdesc_ex) | |
| 1345 | + fec_ptp_save_state(fep); | |
| 1344 | 1346 | |
| 1345 | 1347 | /* Whack a reset. We should wait for this. |
| 1346 | 1348 | * For i.MX6SX SOC, enet use AXI bus, we use disable MAC |
| @@ -197,55 +197,67 @@ static int mac_probe(struct platform_device *_of_dev) · 196 unmodified lines | ||
| 197 | 197 | err = -EINVAL; |
| 198 | 198 | goto _return_of_node_put; |
| 199 | 199 | } |
| 200 | + mac_dev->fman_dev = &of_dev->dev; | |
| 200 | 201 | |
| 201 | 202 | /* Get the FMan cell-index */ |
| 202 | 203 | err = of_property_read_u32(dev_node, "cell-index", &val); |
| 203 | 204 | if (err) { |
| 204 | 205 | dev_err(dev, "failed to read cell-index for %pOF\n", dev_node); |
| 205 | 206 | err = -EINVAL; |
| 206 | − goto _return_of_node_put; | |
| 207 | + goto _return_dev_put; | |
| 207 | 208 | } |
| 208 | 209 | /* cell-index 0 => FMan id 1 */ |
| 209 | 210 | fman_id = (u8)(val + 1); |
| 210 | 211 | |
| 211 | − priv->fman = fman_bind(&of_dev->dev); | |
| 212 | + priv->fman = fman_bind(mac_dev->fman_dev); | |
| 212 | 213 | if (!priv->fman) { |
| 213 | 214 | dev_err(dev, "fman_bind(%pOF) failed\n", dev_node); |
| 214 | 215 | err = -ENODEV; |
| 215 | − goto _return_of_node_put; | |
| 216 | + goto _return_dev_put; | |
| 216 | 217 | } |
| 217 | 218 | |
| 219 | + /* Two references have been taken in of_find_device_by_node() | |
| 220 | + * and fman_bind(). Release one of them here. The second one | |
| 221 | + * will be released in mac_remove(). | |
| 222 | + */ | |
| 223 | + put_device(mac_dev->fman_dev); | |
| 218 | 224 | of_node_put(dev_node); |
| 225 | + dev_node = NULL; | |
| 219 | 226 | |
| 220 | 227 | /* Get the address of the memory mapped registers */ |
| 221 | 228 | mac_dev->res = platform_get_mem_or_io(_of_dev, 0); |
| 222 | 229 | if (!mac_dev->res) { |
| 223 | 230 | dev_err(dev, "could not get registers\n"); |
| 224 | − return -EINVAL; | |
| 231 | + err = -EINVAL; | |
| 232 | + goto _return_dev_put; | |
| 225 | 233 | } |
| 226 | 234 | |
| 227 | 235 | err = devm_request_resource(dev, fman_get_mem_region(priv->fman), |
| 228 | 236 | mac_dev->res); |
| 229 | 237 | if (err) { |
| 230 | 238 | dev_err_probe(dev, err, "could not request resource\n"); |
| 231 | − return err; | |
| 239 | + goto _return_dev_put; | |
| 232 | 240 | } |
| 233 | 241 | |
| 234 | 242 | mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start, |
| 235 | 243 | resource_size(mac_dev->res)); |
| 236 | 244 | if (!mac_dev->vaddr) { |
| 237 | 245 | dev_err(dev, "devm_ioremap() failed\n"); |
| 238 | − return -EIO; | |
| 246 | + err = -EIO; | |
| 247 | + goto _return_dev_put; | |
| 239 | 248 | } |
| 240 | 249 | |
| 241 | − if (!of_device_is_available(mac_node)) | |
| 242 | − return -ENODEV; | |
| 250 | + if (!of_device_is_available(mac_node)) { | |
| 251 | + err = -ENODEV; | |
| 252 | + goto _return_dev_put; | |
| 253 | + } | |
| 243 | 254 | |
| 244 | 255 | /* Get the cell-index */ |
| 245 | 256 | err = of_property_read_u32(mac_node, "cell-index", &val); |
| 246 | 257 | if (err) { |
| 247 | 258 | dev_err(dev, "failed to read cell-index for %pOF\n", mac_node); |
| 248 | − return -EINVAL; | |
| 259 | + err = -EINVAL; | |
| 260 | + goto _return_dev_put; | |
| 249 | 261 | } |
| 250 | 262 | priv->cell_index = (u8)val; |
| 251 | 263 | |
| @@ -259,22 +271,26 @@ static int mac_probe(struct platform_device *_of_dev) · 7 unmodified lines | ||
| 259 | 271 | if (unlikely(nph < 0)) { |
| 260 | 272 | dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n", |
| 261 | 273 | mac_node); |
| 262 | − return nph; | |
| 274 | + err = nph; | |
| 275 | + goto _return_dev_put; | |
| 263 | 276 | } |
| 264 | 277 | |
| 265 | 278 | if (nph != ARRAY_SIZE(mac_dev->port)) { |
| 266 | 279 | dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n", |
| 267 | 280 | mac_node); |
| 268 | − return -EINVAL; | |
| 281 | + err = -EINVAL; | |
| 282 | + goto _return_dev_put; | |
| 269 | 283 | } |
| 270 | 284 | |
| 271 | − for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) { | |
| 285 | + /* PORT_NUM determines the size of the port array */ | |
| 286 | + for (i = 0; i < PORT_NUM; i++) { | |
| 272 | 287 | /* Find the port node */ |
| 273 | 288 | dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i); |
| 274 | 289 | if (!dev_node) { |
| 275 | 290 | dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n", |
| 276 | 291 | mac_node); |
| 277 | − return -EINVAL; | |
| 292 | + err = -EINVAL; | |
| 293 | + goto _return_dev_arr_put; | |
| 278 | 294 | } |
| 279 | 295 | |
| 280 | 296 | of_dev = of_find_device_by_node(dev_node); |
| @@ -282,17 +298,24 @@ static int mac_probe(struct platform_device *_of_dev) · 1 unmodified line | ||
| 282 | 298 | dev_err(dev, "of_find_device_by_node(%pOF) failed\n", |
| 283 | 299 | dev_node); |
| 284 | 300 | err = -EINVAL; |
| 285 | − goto _return_of_node_put; | |
| 301 | + goto _return_dev_arr_put; | |
| 286 | 302 | } |
| 303 | + mac_dev->fman_port_devs[i] = &of_dev->dev; | |
| 287 | 304 | |
| 288 | − mac_dev->port[i] = fman_port_bind(&of_dev->dev); | |
| 305 | + mac_dev->port[i] = fman_port_bind(mac_dev->fman_port_devs[i]); | |
| 289 | 306 | if (!mac_dev->port[i]) { |
| 290 | 307 | dev_err(dev, "dev_get_drvdata(%pOF) failed\n", |
| 291 | 308 | dev_node); |
| 292 | 309 | err = -EINVAL; |
| 293 | − goto _return_of_node_put; | |
| 310 | + goto _return_dev_arr_put; | |
| 294 | 311 | } |
| 312 | + /* Two references have been taken in of_find_device_by_node() | |
| 313 | + * and fman_port_bind(). Release one of them here. The second | |
| 314 | + * one will be released in mac_remove(). | |
| 315 | + */ | |
| 316 | + put_device(mac_dev->fman_port_devs[i]); | |
| 295 | 317 | of_node_put(dev_node); |
| 318 | + dev_node = NULL; | |
| 296 | 319 | } |
| 297 | 320 | |
| 298 | 321 | /* Get the PHY connection type */ |
| @@ -312,7 +335,7 @@ static int mac_probe(struct platform_device *_of_dev) · 13 unmodified lines | ||
| 312 | 335 | |
| 313 | 336 | err = init(mac_dev, mac_node, ¶ms); |
| 314 | 337 | if (err < 0) |
| 315 | − return err; | |
| 338 | + goto _return_dev_arr_put; | |
| 316 | 339 | |
| 317 | 340 | if (!is_zero_ether_addr(mac_dev->addr)) |
| 318 | 341 | dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr); |
| @@ -327,6 +350,12 @@ static int mac_probe(struct platform_device *_of_dev) · 8 unmodified lines | ||
| 327 | 350 | |
| 328 | 351 | return err; |
| 329 | 352 | |
| 353 | +_return_dev_arr_put: | |
| 354 | + /* mac_dev is kzalloc'ed */ | |
| 355 | + for (i = 0; i < PORT_NUM; i++) | |
| 356 | + put_device(mac_dev->fman_port_devs[i]); | |
| 357 | +_return_dev_put: | |
| 358 | + put_device(mac_dev->fman_dev); | |
| 330 | 359 | _return_of_node_put: |
| 331 | 360 | of_node_put(dev_node); |
| 332 | 361 | return err; |
| @@ -335,6 +364,11 @@ _return_of_node_put: · 2 unmodified lines | ||
| 335 | 364 | static void mac_remove(struct platform_device *pdev) |
| 336 | 365 | { |
| 337 | 366 | struct mac_device *mac_dev = platform_get_drvdata(pdev); |
| 367 | + int i; | |
| 368 | + | |
| 369 | + for (i = 0; i < PORT_NUM; i++) | |
| 370 | + put_device(mac_dev->fman_port_devs[i]); | |
| 371 | + put_device(mac_dev->fman_dev); | |
| 338 | 372 | |
| 339 | 373 | platform_device_unregister(mac_dev->priv->eth_dev); |
| 340 | 374 | } |
| @@ -19,12 +19,13 @@ · 18 unmodified lines | ||
| 19 | 19 | struct fman_mac; |
| 20 | 20 | struct mac_priv_s; |
| 21 | 21 | |
| 22 | +#define PORT_NUM 2 | |
| 22 | 23 | struct mac_device { |
| 23 | 24 | void __iomem *vaddr; |
| 24 | 25 | struct device *dev; |
| 25 | 26 | struct resource *res; |
| 26 | 27 | u8 addr[ETH_ALEN]; |
| 27 | − struct fman_port *port[2]; | |
| 28 | + struct fman_port *port[PORT_NUM]; | |
| 28 | 29 | struct phylink *phylink; |
| 29 | 30 | struct phylink_config phylink_config; |
| 30 | 31 | phy_interface_t phy_if; |
| @@ -52,6 +53,9 @@ struct mac_device { · 21 unmodified lines | ||
| 52 | 53 | |
| 53 | 54 | struct fman_mac *fman_mac; |
| 54 | 55 | struct mac_priv_s *priv; |
| 56 | + | |
| 57 | + struct device *fman_dev; | |
| 58 | + struct device *fman_port_devs[PORT_NUM]; | |
| 55 | 59 | }; |
| 56 | 60 | |
| 57 | 61 | static inline struct mac_device |
| @@ -1012,6 +1012,7 @@ sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev) · 1011 unmodified lines | ||
| 1012 | 1012 | if(skb->len > XMIT_BUFF_SIZE) |
| 1013 | 1013 | { |
| 1014 | 1014 | printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len); |
| 1015 | + dev_kfree_skb(skb); | |
| 1015 | 1016 | return NETDEV_TX_OK; |
| 1016 | 1017 | } |
| 1017 | 1018 | |
| @@ -578,7 +578,7 @@ static int mal_probe(struct platform_device *ofdev) · 577 unmodified lines | ||
| 578 | 578 | printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n", |
| 579 | 579 | ofdev->dev.of_node); |
| 580 | 580 | err = -ENODEV; |
| 581 | − goto fail; | |
| 581 | + goto fail_unmap; | |
| 582 | 582 | #endif |
| 583 | 583 | } |
| 584 | 584 | |
| @@ -742,6 +742,8 @@ static void mal_remove(struct platform_device *ofdev) · 157 unmodified lines | ||
| 742 | 742 | |
| 743 | 743 | free_netdev(mal->dummy_dev); |
| 744 | 744 | |
| 745 | + dcr_unmap(mal->dcr_host, 0x100); | |
| 746 | + | |
| 745 | 747 | dma_free_coherent(&ofdev->dev, |
| 746 | 748 | sizeof(struct mal_descriptor) * |
| 747 | 749 | (NUM_TX_BUFF * mal->num_tx_chans + |
| @@ -2472,9 +2472,11 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) · 2471 unmodified lines | ||
| 2472 | 2472 | /* if we are going to send_subcrq_direct this then we need to |
| 2473 | 2473 | * update the checksum before copying the data into ltb. Essentially |
| 2474 | 2474 | * these packets force disable CSO so that we can guarantee that |
| 2475 | − * FW does not need header info and we can send direct. | |
| 2475 | + * FW does not need header info and we can send direct. Also, vnic | |
| 2476 | + * server must be able to xmit standard packets without header data | |
| 2476 | 2477 | */ |
| 2477 | − if (!skb_is_gso(skb) && !ind_bufp->index && !netdev_xmit_more()) { | |
| 2478 | + if (*hdrs == 0 && !skb_is_gso(skb) && | |
| 2479 | + !ind_bufp->index && !netdev_xmit_more()) { | |
| 2478 | 2480 | use_scrq_send_direct = true; |
| 2479 | 2481 | if (skb->ip_summed == CHECKSUM_PARTIAL && |
| 2480 | 2482 | skb_checksum_help(skb)) |
| @@ -108,8 +108,8 @@ struct e1000_hw; · 107 unmodified lines | ||
| 108 | 108 | #define E1000_DEV_ID_PCH_RPL_I219_V22 0x0DC8 |
| 109 | 109 | #define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A |
| 110 | 110 | #define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B |
| 111 | −#define E1000_DEV_ID_PCH_MTP_I219_LM19 0x550C | |
| 112 | −#define E1000_DEV_ID_PCH_MTP_I219_V19 0x550D | |
| 111 | +#define E1000_DEV_ID_PCH_ADP_I219_LM19 0x550C | |
| 112 | +#define E1000_DEV_ID_PCH_ADP_I219_V19 0x550D | |
| 113 | 113 | #define E1000_DEV_ID_PCH_LNP_I219_LM20 0x550E |
| 114 | 114 | #define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F |
| 115 | 115 | #define E1000_DEV_ID_PCH_LNP_I219_LM21 0x5510 |
| @@ -7899,10 +7899,10 @@ static const struct pci_device_id e1000_pci_tbl[] = { · 7898 unmodified lines | ||
| 7899 | 7899 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp }, |
| 7900 | 7900 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp }, |
| 7901 | 7901 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_adp }, |
| 7902 | + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM19), board_pch_adp }, | |
| 7903 | + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V19), board_pch_adp }, | |
| 7902 | 7904 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp }, |
| 7903 | 7905 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_mtp }, |
| 7904 | − { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_mtp }, | |
| 7905 | − { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_mtp }, | |
| 7906 | 7906 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp }, |
| 7907 | 7907 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp }, |
| 7908 | 7908 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_mtp }, |
| @@ -1734,6 +1734,7 @@ struct i40e_mac_filter *i40e_add_mac_filter(struct i40e_vsi *vsi, · 1733 unmodified lines | ||
| 1734 | 1734 | struct hlist_node *h; |
| 1735 | 1735 | int bkt; |
| 1736 | 1736 | |
| 1737 | + lockdep_assert_held(&vsi->mac_filter_hash_lock); | |
| 1737 | 1738 | if (vsi->info.pvid) |
| 1738 | 1739 | return i40e_add_filter(vsi, macaddr, |
| 1739 | 1740 | le16_to_cpu(vsi->info.pvid)); |
| @@ -2213,8 +2213,10 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) · 2212 unmodified lines | ||
| 2213 | 2213 | vfres->vsi_res[0].qset_handle |
| 2214 | 2214 | = le16_to_cpu(vsi->info.qs_handle[0]); |
| 2215 | 2215 | if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) { |
| 2216 | + spin_lock_bh(&vsi->mac_filter_hash_lock); | |
| 2216 | 2217 | i40e_del_mac_filter(vsi, vf->default_lan_addr.addr); |
| 2217 | 2218 | eth_zero_addr(vf->default_lan_addr.addr); |
| 2219 | + spin_unlock_bh(&vsi->mac_filter_hash_lock); | |
| 2218 | 2220 | } |
| 2219 | 2221 | ether_addr_copy(vfres->vsi_res[0].default_mac_addr, |
| 2220 | 2222 | vf->default_lan_addr.addr); |
| @@ -31,7 +31,7 @@ static const struct ice_tunnel_type_scan tnls[] = { · 30 unmodified lines | ||
| 31 | 31 | * Verifies various attributes of the package file, including length, format |
| 32 | 32 | * version, and the requirement of at least one segment. |
| 33 | 33 | */ |
| 34 | −static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len) | |
| 34 | +static enum ice_ddp_state ice_verify_pkg(const struct ice_pkg_hdr *pkg, u32 len) | |
| 35 | 35 | { |
| 36 | 36 | u32 seg_count; |
| 37 | 37 | u32 i; |
| @@ -57,13 +57,13 @@ static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len) · 19 unmodified lines | ||
| 57 | 57 | /* all segments must fit within length */ |
| 58 | 58 | for (i = 0; i < seg_count; i++) { |
| 59 | 59 | u32 off = le32_to_cpu(pkg->seg_offset[i]); |
| 60 | − struct ice_generic_seg_hdr *seg; | |
| 60 | + const struct ice_generic_seg_hdr *seg; | |
| 61 | 61 | |
| 62 | 62 | /* segment header must fit */ |
| 63 | 63 | if (len < off + sizeof(*seg)) |
| 64 | 64 | return ICE_DDP_PKG_INVALID_FILE; |
| 65 | 65 | |
| 66 | − seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off); | |
| 66 | + seg = (void *)pkg + off; | |
| 67 | 67 | |
| 68 | 68 | /* segment body must fit */ |
| 69 | 69 | if (len < off + le32_to_cpu(seg->seg_size)) |
| @@ -119,13 +119,13 @@ static enum ice_ddp_state ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver) · 49 unmodified lines | ||
| 119 | 119 | * |
| 120 | 120 | * This helper function validates a buffer's header. |
| 121 | 121 | */ |
| 122 | −static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf) | |
| 122 | +static const struct ice_buf_hdr *ice_pkg_val_buf(const struct ice_buf *buf) | |
| 123 | 123 | { |
| 124 | − struct ice_buf_hdr *hdr; | |
| 124 | + const struct ice_buf_hdr *hdr; | |
| 125 | 125 | u16 section_count; |
| 126 | 126 | u16 data_end; |
| 127 | 127 | |
| 128 | − hdr = (struct ice_buf_hdr *)buf->buf; | |
| 128 | + hdr = (const struct ice_buf_hdr *)buf->buf; | |
| 129 | 129 | /* verify data */ |
| 130 | 130 | section_count = le16_to_cpu(hdr->section_count); |
| 131 | 131 | if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT) |
| @@ -165,8 +165,8 @@ static struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg) · 33 unmodified lines | ||
| 165 | 165 | * unexpected value has been detected (for example an invalid section count or |
| 166 | 166 | * an invalid buffer end value). |
| 167 | 167 | */ |
| 168 | −static struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg, | |
| 169 | − struct ice_pkg_enum *state) | |
| 168 | +static const struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg, | |
| 169 | + struct ice_pkg_enum *state) | |
| 170 | 170 | { |
| 171 | 171 | if (ice_seg) { |
| 172 | 172 | state->buf_table = ice_find_buf_table(ice_seg); |
| @@ -1800,9 +1800,9 @@ int ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count) · 1627 unmodified lines | ||
| 1800 | 1800 | * success it returns a pointer to the segment header, otherwise it will |
| 1801 | 1801 | * return NULL. |
| 1802 | 1802 | */ |
| 1803 | −static struct ice_generic_seg_hdr * | |
| 1803 | +static const struct ice_generic_seg_hdr * | |
| 1804 | 1804 | ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type, |
| 1805 | − struct ice_pkg_hdr *pkg_hdr) | |
| 1805 | + const struct ice_pkg_hdr *pkg_hdr) | |
| 1806 | 1806 | { |
| 1807 | 1807 | u32 i; |
| 1808 | 1808 | |
| @@ -1813,11 +1813,9 @@ ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type, · 4 unmodified lines | ||
| 1813 | 1813 | |
| 1814 | 1814 | /* Search all package segments for the requested segment type */ |
| 1815 | 1815 | for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) { |
| 1816 | − struct ice_generic_seg_hdr *seg; | |
| 1816 | + const struct ice_generic_seg_hdr *seg; | |
| 1817 | 1817 | |
| 1818 | − seg = (struct ice_generic_seg_hdr | |
| 1819 | − *)((u8 *)pkg_hdr + | |
| 1820 | − le32_to_cpu(pkg_hdr->seg_offset[i])); | |
| 1818 | + seg = (void *)pkg_hdr + le32_to_cpu(pkg_hdr->seg_offset[i]); | |
| 1821 | 1819 | |
| 1822 | 1820 | if (le32_to_cpu(seg->seg_type) == seg_type) |
| 1823 | 1821 | return seg; |
| @@ -2354,12 +2352,12 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size, · 530 unmodified lines | ||
| 2354 | 2352 | * |
| 2355 | 2353 | * Return: zero when update was successful, negative values otherwise. |
| 2356 | 2354 | */ |
| 2357 | −int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) | |
| 2355 | +int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) | |
| 2358 | 2356 | { |
| 2359 | − u8 *current_topo, *new_topo = NULL; | |
| 2360 | − struct ice_run_time_cfg_seg *seg; | |
| 2361 | − struct ice_buf_hdr *section; | |
| 2362 | − struct ice_pkg_hdr *pkg_hdr; | |
| 2357 | + u8 *new_topo = NULL, *topo __free(kfree) = NULL; | |
| 2358 | + const struct ice_run_time_cfg_seg *seg; | |
| 2359 | + const struct ice_buf_hdr *section; | |
| 2360 | + const struct ice_pkg_hdr *pkg_hdr; | |
| 2363 | 2361 | enum ice_ddp_state state; |
| 2364 | 2362 | u16 offset, size = 0; |
| 2365 | 2363 | u32 reg = 0; |
| @@ -2375,15 +2373,13 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) · 9 unmodified lines | ||
| 2375 | 2373 | return -EOPNOTSUPP; |
| 2376 | 2374 | } |
| 2377 | 2375 | |
| 2378 | − current_topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); | |
| 2379 | − if (!current_topo) | |
| 2376 | + topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); | |
| 2377 | + if (!topo) | |
| 2380 | 2378 | return -ENOMEM; |
| 2381 | 2379 | |
| 2382 | − /* Get the current Tx topology */ | |
| 2383 | − status = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL, | |
| 2384 | − &flags, false); | |
| 2385 | − | |
| 2386 | − kfree(current_topo); | |
| 2380 | + /* Get the current Tx topology flags */ | |
| 2381 | + status = ice_get_set_tx_topo(hw, topo, ICE_AQ_MAX_BUF_LEN, NULL, &flags, | |
| 2382 | + false); | |
| 2387 | 2383 | |
| 2388 | 2384 | if (status) { |
| 2389 | 2385 | ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n"); |
| @@ -2419,7 +2415,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) · 29 unmodified lines | ||
| 2419 | 2415 | goto update_topo; |
| 2420 | 2416 | } |
| 2421 | 2417 | |
| 2422 | − pkg_hdr = (struct ice_pkg_hdr *)buf; | |
| 2418 | + pkg_hdr = (const struct ice_pkg_hdr *)buf; | |
| 2423 | 2419 | state = ice_verify_pkg(pkg_hdr, len); |
| 2424 | 2420 | if (state) { |
| 2425 | 2421 | ice_debug(hw, ICE_DBG_INIT, "Failed to verify pkg (err: %d)\n", |
| @@ -2428,7 +2424,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) · 2 unmodified lines | ||
| 2428 | 2424 | } |
| 2429 | 2425 | |
| 2430 | 2426 | /* Find runtime configuration segment */ |
| 2431 | − seg = (struct ice_run_time_cfg_seg *) | |
| 2427 | + seg = (const struct ice_run_time_cfg_seg *) | |
| 2432 | 2428 | ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr); |
| 2433 | 2429 | if (!seg) { |
| 2434 | 2430 | ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n"); |
| @@ -2461,8 +2457,10 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) · 26 unmodified lines | ||
| 2461 | 2457 | return -EIO; |
| 2462 | 2458 | } |
| 2463 | 2459 | |
| 2464 | − /* Get the new topology buffer */ | |
| 2465 | − new_topo = ((u8 *)section) + offset; | |
| 2460 | + /* Get the new topology buffer, reuse current topo copy mem */ | |
| 2461 | + static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN); | |
| 2462 | + new_topo = topo; | |
| 2463 | + memcpy(new_topo, (u8 *)section + offset, size); | |
| 2466 | 2464 | |
| 2467 | 2465 | update_topo: |
| 2468 | 2466 | /* Acquire global lock to make sure that set topology issued |
| @@ -438,7 +438,7 @@ struct ice_pkg_enum { · 437 unmodified lines | ||
| 438 | 438 | u32 buf_idx; |
| 439 | 439 | |
| 440 | 440 | u32 type; |
| 441 | − struct ice_buf_hdr *buf; | |
| 441 | + const struct ice_buf_hdr *buf; | |
| 442 | 442 | u32 sect_idx; |
| 443 | 443 | void *sect; |
| 444 | 444 | u32 sect_type; |
| @@ -467,6 +467,6 @@ ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state, · 22 unmodified lines | ||
| 467 | 467 | void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state, |
| 468 | 468 | u32 sect_type); |
| 469 | 469 | |
| 470 | −int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len); | |
| 470 | +int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len); | |
| 471 | 471 | |
| 472 | 472 | #endif |
| @@ -656,6 +656,8 @@ ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv, · 655 unmodified lines | ||
| 656 | 656 | struct ice_dpll_pin *p = pin_priv; |
| 657 | 657 | struct ice_dpll *d = dpll_priv; |
| 658 | 658 | |
| 659 | + if (state == DPLL_PIN_STATE_SELECTABLE) | |
| 660 | + return -EINVAL; | |
| 659 | 661 | if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED) |
| 660 | 662 | return 0; |
| 661 | 663 | |
| @@ -1843,6 +1845,8 @@ ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin, · 1181 unmodified lines | ||
| 1843 | 1845 | struct dpll_pin *parent; |
| 1844 | 1846 | int ret, i; |
| 1845 | 1847 | |
| 1848 | + if (WARN_ON((!vsi || !vsi->netdev))) | |
| 1849 | + return -EINVAL; | |
| 1846 | 1850 | ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF, |
| 1847 | 1851 | pf->dplls.clock_id); |
| 1848 | 1852 | if (ret) |
| @@ -1858,8 +1862,6 @@ ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin, · 9 unmodified lines | ||
| 1858 | 1862 | if (ret) |
| 1859 | 1863 | goto unregister_pins; |
| 1860 | 1864 | } |
| 1861 | − if (WARN_ON((!vsi || !vsi->netdev))) | |
| 1862 | − return -EINVAL; | |
| 1863 | 1865 | dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin); |
| 1864 | 1866 | |
| 1865 | 1867 | return 0; |
| @@ -582,10 +582,13 @@ ice_eswitch_br_switchdev_event(struct notifier_block *nb, · 581 unmodified lines | ||
| 582 | 582 | return NOTIFY_DONE; |
| 583 | 583 | } |
| 584 | 584 | |
| 585 | −static void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge) | |
| 585 | +void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge) | |
| 586 | 586 | { |
| 587 | 587 | struct ice_esw_br_fdb_entry *entry, *tmp; |
| 588 | 588 | |
| 589 | + if (!bridge) | |
| 590 | + return; | |
| 591 | + | |
| 589 | 592 | list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) |
| 590 | 593 | ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); |
| 591 | 594 | } |
| @@ -117,5 +117,6 @@ void · 116 unmodified lines | ||
| 117 | 117 | ice_eswitch_br_offloads_deinit(struct ice_pf *pf); |
| 118 | 118 | int |
| 119 | 119 | ice_eswitch_br_offloads_init(struct ice_pf *pf); |
| 120 | +void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge); | |
| 120 | 121 | |
| 121 | 122 | #endif /* _ICE_ESWITCH_BR_H_ */ |
| @@ -87,7 +87,8 @@ ice_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch, · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | bool netif_is_ice(const struct net_device *dev) |
| 89 | 89 | { |
| 90 | − return dev && (dev->netdev_ops == &ice_netdev_ops); | |
| 90 | + return dev && (dev->netdev_ops == &ice_netdev_ops || | |
| 91 | + dev->netdev_ops == &ice_netdev_safe_mode_ops); | |
| 91 | 92 | } |
| 92 | 93 | |
| 93 | 94 | /** |
| @@ -520,25 +521,6 @@ static void ice_pf_dis_all_vsi(struct ice_pf *pf, bool locked) · 426 unmodified lines | ||
| 520 | 521 | pf->vf_agg_node[node].num_vsis = 0; |
| 521 | 522 | } |
| 522 | 523 | |
| 523 | −/** | |
| 524 | − * ice_clear_sw_switch_recipes - clear switch recipes | |
| 525 | − * @pf: board private structure | |
| 526 | − * | |
| 527 | − * Mark switch recipes as not created in sw structures. There are cases where | |
| 528 | − * rules (especially advanced rules) need to be restored, either re-read from | |
| 529 | − * hardware or added again. For example after the reset. 'recp_created' flag | |
| 530 | − * prevents from doing that and need to be cleared upfront. | |
| 531 | − */ | |
| 532 | −static void ice_clear_sw_switch_recipes(struct ice_pf *pf) | |
| 533 | −{ | |
| 534 | − struct ice_sw_recipe *recp; | |
| 535 | − u8 i; | |
| 536 | − | |
| 537 | − recp = pf->hw.switch_info->recp_list; | |
| 538 | − for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) | |
| 539 | − recp[i].recp_created = false; | |
| 540 | −} | |
| 541 | − | |
| 542 | 524 | /** |
| 543 | 525 | * ice_prepare_for_reset - prep for reset |
| 544 | 526 | * @pf: board private structure |
| @@ -575,8 +557,9 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type) · 30 unmodified lines | ||
| 575 | 557 | mutex_unlock(&pf->vfs.table_lock); |
| 576 | 558 | |
| 577 | 559 | if (ice_is_eswitch_mode_switchdev(pf)) { |
| 578 | − if (reset_type != ICE_RESET_PFR) | |
| 579 | − ice_clear_sw_switch_recipes(pf); | |
| 560 | + rtnl_lock(); | |
| 561 | + ice_eswitch_br_fdb_flush(pf->eswitch.br_offloads->bridge); | |
| 562 | + rtnl_unlock(); | |
| 580 | 563 | } |
| 581 | 564 | |
| 582 | 565 | /* release ADQ specific HW and SW resources */ |
| @@ -4536,16 +4519,10 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware) · 3953 unmodified lines | ||
| 4536 | 4519 | u8 num_tx_sched_layers = hw->num_tx_sched_layers; |
| 4537 | 4520 | struct ice_pf *pf = hw->back; |
| 4538 | 4521 | struct device *dev; |
| 4539 | − u8 *buf_copy; | |
| 4540 | 4522 | int err; |
| 4541 | 4523 | |
| 4542 | 4524 | dev = ice_pf_to_dev(pf); |
| 4543 | − /* ice_cfg_tx_topo buf argument is not a constant, | |
| 4544 | − * so we have to make a copy | |
| 4545 | − */ | |
| 4546 | − buf_copy = kmemdup(firmware->data, firmware->size, GFP_KERNEL); | |
| 4547 | − | |
| 4548 | − err = ice_cfg_tx_topo(hw, buf_copy, firmware->size); | |
| 4525 | + err = ice_cfg_tx_topo(hw, firmware->data, firmware->size); | |
| 4549 | 4526 | if (!err) { |
| 4550 | 4527 | if (hw->num_tx_sched_layers > num_tx_sched_layers) |
| 4551 | 4528 | dev_info(dev, "Tx scheduling layers switching feature disabled\n"); |
| @@ -4773,14 +4750,12 @@ int ice_init_dev(struct ice_pf *pf) · 221 unmodified lines | ||
| 4773 | 4750 | ice_init_feature_support(pf); |
| 4774 | 4751 | |
| 4775 | 4752 | err = ice_init_ddp_config(hw, pf); |
| 4776 | − if (err) | |
| 4777 | − return err; | |
| 4778 | 4753 | |
| 4779 | 4754 | /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be |
| 4780 | 4755 | * set in pf->state, which will cause ice_is_safe_mode to return |
| 4781 | 4756 | * true |
| 4782 | 4757 | */ |
| 4783 | − if (ice_is_safe_mode(pf)) { | |
| 4758 | + if (err || ice_is_safe_mode(pf)) { | |
| 4784 | 4759 | /* we already got function/device capabilities but these don't |
| 4785 | 4760 | * reflect what the driver needs to do in safe mode. Instead of |
| 4786 | 4761 | * adding conditional logic everywhere to ignore these |
| @@ -1096,8 +1096,10 @@ int ice_sriov_set_msix_vec_count(struct pci_dev *vf_dev, int msix_vec_count) · 1095 unmodified lines | ||
| 1096 | 1096 | return -ENOENT; |
| 1097 | 1097 | |
| 1098 | 1098 | vsi = ice_get_vf_vsi(vf); |
| 1099 | − if (!vsi) | |
| 1099 | + if (!vsi) { | |
| 1100 | + ice_put_vf(vf); | |
| 1100 | 1101 | return -ENOENT; |
| 1102 | + } | |
| 1101 | 1103 | |
| 1102 | 1104 | prev_msix = vf->num_msix; |
| 1103 | 1105 | prev_queues = vf->num_vf_qs; |
| @@ -1119,7 +1121,10 @@ int ice_sriov_set_msix_vec_count(struct pci_dev *vf_dev, int msix_vec_count) · 15 unmodified lines | ||
| 1119 | 1121 | if (vf->first_vector_idx < 0) |
| 1120 | 1122 | goto unroll; |
| 1121 | 1123 | |
| 1122 | − if (ice_vf_reconfig_vsi(vf) || ice_vf_init_host_cfg(vf, vsi)) { | |
| 1124 | + vsi->req_txq = queues; | |
| 1125 | + vsi->req_rxq = queues; | |
| 1126 | + | |
| 1127 | + if (ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT)) { | |
| 1123 | 1128 | /* Try to rebuild with previous values */ |
| 1124 | 1129 | needs_rebuild = true; |
| 1125 | 1130 | goto unroll; |
| @@ -1142,12 +1147,16 @@ unroll: · 16 unmodified lines | ||
| 1142 | 1147 | vf->num_msix = prev_msix; |
| 1143 | 1148 | vf->num_vf_qs = prev_queues; |
| 1144 | 1149 | vf->first_vector_idx = ice_sriov_get_irqs(pf, vf->num_msix); |
| 1145 | − if (vf->first_vector_idx < 0) | |
| 1150 | + if (vf->first_vector_idx < 0) { | |
| 1151 | + ice_put_vf(vf); | |
| 1146 | 1152 | return -EINVAL; |
| 1153 | + } | |
| 1147 | 1154 | |
| 1148 | 1155 | if (needs_rebuild) { |
| 1149 | − ice_vf_reconfig_vsi(vf); | |
| 1150 | − ice_vf_init_host_cfg(vf, vsi); | |
| 1156 | + vsi->req_txq = prev_queues; | |
| 1157 | + vsi->req_rxq = prev_queues; | |
| 1158 | + | |
| 1159 | + ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT); | |
| 1151 | 1160 | } |
| 1152 | 1161 | |
| 1153 | 1162 | ice_ena_vf_mappings(vf); |
| @@ -6322,8 +6322,6 @@ ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id, · 6321 unmodified lines | ||
| 6322 | 6322 | if (!itr->vsi_list_info || |
| 6323 | 6323 | !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) |
| 6324 | 6324 | continue; |
| 6325 | − /* Clearing it so that the logic can add it back */ | |
| 6326 | − clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); | |
| 6327 | 6325 | f_entry.fltr_info.vsi_handle = vsi_handle; |
| 6328 | 6326 | f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; |
| 6329 | 6327 | /* update the src in case it is VSI num */ |
| @@ -819,6 +819,17 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr) · 818 unmodified lines | ||
| 819 | 819 | rule_info.sw_act.flag |= ICE_FLTR_TX; |
| 820 | 820 | rule_info.sw_act.src = vsi->idx; |
| 821 | 821 | rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE; |
| 822 | + /* This is a specific case. The destination VSI index is | |
| 823 | + * overwritten by the source VSI index. This type of filter | |
| 824 | + * should allow the packet to go to the LAN, not to the | |
| 825 | + * VSI passed here. It should set LAN_EN bit only. However, | |
| 826 | + * the VSI must be a valid one. Setting source VSI index | |
| 827 | + * here is safe. Even if the result from switch is set LAN_EN | |
| 828 | + * and LB_EN (which normally will pass the packet to this VSI) | |
| 829 | + * packet won't be seen on the VSI, because local loopback is | |
| 830 | + * turned off. | |
| 831 | + */ | |
| 832 | + rule_info.sw_act.vsi_handle = vsi->idx; | |
| 822 | 833 | } else { |
| 823 | 834 | /* VF to VF */ |
| 824 | 835 | rule_info.sw_act.flag |= ICE_FLTR_TX; |
| @@ -256,7 +256,7 @@ static void ice_vf_pre_vsi_rebuild(struct ice_vf *vf) · 255 unmodified lines | ||
| 256 | 256 | * |
| 257 | 257 | * It brings the VSI down and then reconfigures it with the hardware. |
| 258 | 258 | */ |
| 259 | −int ice_vf_reconfig_vsi(struct ice_vf *vf) | |
| 259 | +static int ice_vf_reconfig_vsi(struct ice_vf *vf) | |
| 260 | 260 | { |
| 261 | 261 | struct ice_vsi *vsi = ice_get_vf_vsi(vf); |
| 262 | 262 | struct ice_pf *pf = vf->pf; |
| @@ -335,6 +335,13 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf, struct ice_vsi *vsi) · 72 unmodified lines | ||
| 335 | 335 | |
| 336 | 336 | err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info); |
| 337 | 337 | } else { |
| 338 | + /* clear possible previous port vlan config */ | |
| 339 | + err = ice_vsi_clear_port_vlan(vsi); | |
| 340 | + if (err) { | |
| 341 | + dev_err(dev, "failed to clear port VLAN via VSI parameters for VF %u, error %d\n", | |
| 342 | + vf->vf_id, err); | |
| 343 | + return err; | |
| 344 | + } | |
| 338 | 345 | err = ice_vsi_add_vlan_zero(vsi); |
| 339 | 346 | } |
| 340 | 347 | |
| @@ -23,7 +23,6 @@ · 22 unmodified lines | ||
| 23 | 23 | #warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | −int ice_vf_reconfig_vsi(struct ice_vf *vf); | |
| 27 | 26 | void ice_initialize_vf_entry(struct ice_vf *vf); |
| 28 | 27 | void ice_dis_vf_qs(struct ice_vf *vf); |
| 29 | 28 | int ice_check_vf_init(struct ice_vf *vf); |
| @@ -787,3 +787,60 @@ int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi) · 786 unmodified lines | ||
| 787 | 787 | kfree(ctxt); |
| 788 | 788 | return err; |
| 789 | 789 | } |
| 790 | + | |
| 791 | +int ice_vsi_clear_port_vlan(struct ice_vsi *vsi) | |
| 792 | +{ | |
| 793 | + struct ice_hw *hw = &vsi->back->hw; | |
| 794 | + struct ice_vsi_ctx *ctxt; | |
| 795 | + int err; | |
| 796 | + | |
| 797 | + ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); | |
| 798 | + if (!ctxt) | |
| 799 | + return -ENOMEM; | |
| 800 | + | |
| 801 | + ctxt->info = vsi->info; | |
| 802 | + | |
| 803 | + ctxt->info.port_based_outer_vlan = 0; | |
| 804 | + ctxt->info.port_based_inner_vlan = 0; | |
| 805 | + | |
| 806 | + ctxt->info.inner_vlan_flags = | |
| 807 | + FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_TX_MODE_M, | |
| 808 | + ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL); | |
| 809 | + if (ice_is_dvm_ena(hw)) { | |
| 810 | + ctxt->info.inner_vlan_flags |= | |
| 811 | + FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M, | |
| 812 | + ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING); | |
| 813 | + ctxt->info.outer_vlan_flags = | |
| 814 | + FIELD_PREP(ICE_AQ_VSI_OUTER_VLAN_TX_MODE_M, | |
| 815 | + ICE_AQ_VSI_OUTER_VLAN_TX_MODE_ALL); | |
| 816 | + ctxt->info.outer_vlan_flags |= | |
| 817 | + FIELD_PREP(ICE_AQ_VSI_OUTER_TAG_TYPE_M, | |
| 818 | + ICE_AQ_VSI_OUTER_TAG_VLAN_8100); | |
| 819 | + ctxt->info.outer_vlan_flags |= | |
| 820 | + ICE_AQ_VSI_OUTER_VLAN_EMODE_NOTHING << | |
| 821 | + ICE_AQ_VSI_OUTER_VLAN_EMODE_S; | |
| 822 | + } | |
| 823 | + | |
| 824 | + ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA; | |
| 825 | + ctxt->info.valid_sections = | |
| 826 | + cpu_to_le16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID | | |
| 827 | + ICE_AQ_VSI_PROP_VLAN_VALID | | |
| 828 | + ICE_AQ_VSI_PROP_SW_VALID); | |
| 829 | + | |
| 830 | + err = ice_update_vsi(hw, vsi->idx, ctxt, NULL); | |
| 831 | + if (err) { | |
| 832 | + dev_err(ice_pf_to_dev(vsi->back), "update VSI for clearing port based VLAN failed, err %d aq_err %s\n", | |
| 833 | + err, ice_aq_str(hw->adminq.sq_last_status)); | |
| 834 | + } else { | |
| 835 | + vsi->info.port_based_outer_vlan = | |
| 836 | + ctxt->info.port_based_outer_vlan; | |
| 837 | + vsi->info.port_based_inner_vlan = | |
| 838 | + ctxt->info.port_based_inner_vlan; | |
| 839 | + vsi->info.outer_vlan_flags = ctxt->info.outer_vlan_flags; | |
| 840 | + vsi->info.inner_vlan_flags = ctxt->info.inner_vlan_flags; | |
| 841 | + vsi->info.sw_flags2 = ctxt->info.sw_flags2; | |
| 842 | + } | |
| 843 | + | |
| 844 | + kfree(ctxt); | |
| 845 | + return err; | |
| 846 | +} | |
| @@ -36,5 +36,6 @@ int ice_vsi_ena_outer_insertion(struct ice_vsi *vsi, u16 tpid); · 35 unmodified lines | ||
| 36 | 36 | int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi); |
| 37 | 37 | int ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan); |
| 38 | 38 | int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi); |
| 39 | +int ice_vsi_clear_port_vlan(struct ice_vsi *vsi); | |
| 39 | 40 | |
| 40 | 41 | #endif /* _ICE_VSI_VLAN_LIB_H_ */ |
| @@ -99,6 +99,7 @@ static int idpf_vf_intr_reg_init(struct idpf_vport *vport) · 98 unmodified lines | ||
| 99 | 99 | intr->dyn_ctl_intena_m = VF_INT_DYN_CTLN_INTENA_M; |
| 100 | 100 | intr->dyn_ctl_intena_msk_m = VF_INT_DYN_CTLN_INTENA_MSK_M; |
| 101 | 101 | intr->dyn_ctl_itridx_s = VF_INT_DYN_CTLN_ITR_INDX_S; |
| 102 | + intr->dyn_ctl_intrvl_s = VF_INT_DYN_CTLN_INTERVAL_S; | |
| 102 | 103 | intr->dyn_ctl_wb_on_itr_m = VF_INT_DYN_CTLN_WB_ON_ITR_M; |
| 103 | 104 | |
| 104 | 105 | spacing = IDPF_ITR_IDX_SPACING(reg_vals[vec_id].itrn_index_spacing, |
| @@ -666,7 +666,7 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter, · 665 unmodified lines | ||
| 666 | 666 | |
| 667 | 667 | if (ctlq_msg->data_len) { |
| 668 | 668 | payload = ctlq_msg->ctx.indirect.payload->va; |
| 669 | − payload_size = ctlq_msg->ctx.indirect.payload->size; | |
| 669 | + payload_size = ctlq_msg->data_len; | |
| 670 | 670 | } |
| 671 | 671 | |
| 672 | 672 | xn->reply_sz = payload_size; |
| @@ -1295,10 +1295,6 @@ int idpf_send_create_vport_msg(struct idpf_adapter *adapter, · 622 unmodified lines | ||
| 1295 | 1295 | err = reply_sz; |
| 1296 | 1296 | goto free_vport_params; |
| 1297 | 1297 | } |
| 1298 | − if (reply_sz < IDPF_CTLQ_MAX_BUF_LEN) { | |
| 1299 | − err = -EIO; | |
| 1300 | − goto free_vport_params; | |
| 1301 | − } | |
| 1302 | 1298 | |
| 1303 | 1299 | return 0; |
| 1304 | 1300 | |
| @@ -2602,9 +2598,6 @@ int idpf_send_get_rx_ptype_msg(struct idpf_vport *vport) · 1297 unmodified lines | ||
| 2602 | 2598 | if (reply_sz < 0) |
| 2603 | 2599 | return reply_sz; |
| 2604 | 2600 | |
| 2605 | − if (reply_sz < IDPF_CTLQ_MAX_BUF_LEN) | |
| 2606 | − return -EIO; | |
| 2607 | − | |
| 2608 | 2601 | ptypes_recvd += le16_to_cpu(ptype_info->num_ptypes); |
| 2609 | 2602 | if (ptypes_recvd > max_ptype) |
| 2610 | 2603 | return -EINVAL; |
| @@ -3088,9 +3081,9 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter) · 477 unmodified lines | ||
| 3088 | 3081 | if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags)) |
| 3089 | 3082 | return; |
| 3090 | 3083 | |
| 3091 | − idpf_vc_xn_shutdown(adapter->vcxn_mngr); | |
| 3092 | 3084 | idpf_deinit_task(adapter); |
| 3093 | 3085 | idpf_intr_rel(adapter); |
| 3086 | + idpf_vc_xn_shutdown(adapter->vcxn_mngr); | |
| 3094 | 3087 | |
| 3095 | 3088 | cancel_delayed_work_sync(&adapter->serv_task); |
| 3096 | 3089 | cancel_delayed_work_sync(&adapter->mbx_task); |
| @@ -9651,6 +9651,10 @@ static void igb_io_resume(struct pci_dev *pdev) · 9650 unmodified lines | ||
| 9651 | 9651 | struct igb_adapter *adapter = netdev_priv(netdev); |
| 9652 | 9652 | |
| 9653 | 9653 | if (netif_running(netdev)) { |
| 9654 | + if (!test_bit(__IGB_DOWN, &adapter->state)) { | |
| 9655 | + dev_dbg(&pdev->dev, "Resuming from non-fatal error, do nothing.\n"); | |
| 9656 | + return; | |
| 9657 | + } | |
| 9654 | 9658 | if (igb_up(adapter)) { |
| 9655 | 9659 | dev_err(&pdev->dev, "igb_up failed after reset\n"); |
| 9656 | 9660 | return; |
| @@ -336,6 +336,51 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct, · 335 unmodified lines | ||
| 336 | 336 | return new_pkts; |
| 337 | 337 | } |
| 338 | 338 | |
| 339 | +/** | |
| 340 | + * octep_oq_next_pkt() - Move to the next packet in Rx queue. | |
| 341 | + * | |
| 342 | + * @oq: Octeon Rx queue data structure. | |
| 343 | + * @buff_info: Current packet buffer info. | |
| 344 | + * @read_idx: Current packet index in the ring. | |
| 345 | + * @desc_used: Current packet descriptor number. | |
| 346 | + * | |
| 347 | + * Free the resources associated with a packet. | |
| 348 | + * Increment packet index in the ring and packet descriptor number. | |
| 349 | + */ | |
| 350 | +static void octep_oq_next_pkt(struct octep_oq *oq, | |
| 351 | + struct octep_rx_buffer *buff_info, | |
| 352 | + u32 *read_idx, u32 *desc_used) | |
| 353 | +{ | |
| 354 | + dma_unmap_page(oq->dev, oq->desc_ring[*read_idx].buffer_ptr, | |
| 355 | + PAGE_SIZE, DMA_FROM_DEVICE); | |
| 356 | + buff_info->page = NULL; | |
| 357 | + (*read_idx)++; | |
| 358 | + (*desc_used)++; | |
| 359 | + if (*read_idx == oq->max_count) | |
| 360 | + *read_idx = 0; | |
| 361 | +} | |
| 362 | + | |
| 363 | +/** | |
| 364 | + * octep_oq_drop_rx() - Free the resources associated with a packet. | |
| 365 | + * | |
| 366 | + * @oq: Octeon Rx queue data structure. | |
| 367 | + * @buff_info: Current packet buffer info. | |
| 368 | + * @read_idx: Current packet index in the ring. | |
| 369 | + * @desc_used: Current packet descriptor number. | |
| 370 | + * | |
| 371 | + */ | |
| 372 | +static void octep_oq_drop_rx(struct octep_oq *oq, | |
| 373 | + struct octep_rx_buffer *buff_info, | |
| 374 | + u32 *read_idx, u32 *desc_used) | |
| 375 | +{ | |
| 376 | + int data_len = buff_info->len - oq->max_single_buffer_size; | |
| 377 | + | |
| 378 | + while (data_len > 0) { | |
| 379 | + octep_oq_next_pkt(oq, buff_info, read_idx, desc_used); | |
| 380 | + data_len -= oq->buffer_size; | |
| 381 | + }; | |
| 382 | +} | |
| 383 | + | |
| 339 | 384 | /** |
| 340 | 385 | * __octep_oq_process_rx() - Process hardware Rx queue and push to stack. |
| 341 | 386 | * |
| @@ -367,10 +412,7 @@ static int __octep_oq_process_rx(struct octep_device *oct, · 25 unmodified lines | ||
| 367 | 412 | desc_used = 0; |
| 368 | 413 | for (pkt = 0; pkt < pkts_to_process; pkt++) { |
| 369 | 414 | buff_info = (struct octep_rx_buffer *)&oq->buff_info[read_idx]; |
| 370 | − dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr, | |
| 371 | − PAGE_SIZE, DMA_FROM_DEVICE); | |
| 372 | 415 | resp_hw = page_address(buff_info->page); |
| 373 | − buff_info->page = NULL; | |
| 374 | 416 | |
| 375 | 417 | /* Swap the length field that is in Big-Endian to CPU */ |
| 376 | 418 | buff_info->len = be64_to_cpu(resp_hw->length); |
| @@ -394,36 +436,33 @@ static int __octep_oq_process_rx(struct octep_device *oct, · 17 unmodified lines | ||
| 394 | 436 | data_offset = OCTEP_OQ_RESP_HW_SIZE; |
| 395 | 437 | rx_ol_flags = 0; |
| 396 | 438 | } |
| 439 | + | |
| 440 | + octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used); | |
| 441 | + | |
| 442 | + skb = build_skb((void *)resp_hw, PAGE_SIZE); | |
| 443 | + if (!skb) { | |
| 444 | + octep_oq_drop_rx(oq, buff_info, | |
| 445 | + &read_idx, &desc_used); | |
| 446 | + oq->stats.alloc_failures++; | |
| 447 | + continue; | |
| 448 | + } | |
| 449 | + skb_reserve(skb, data_offset); | |
| 450 | + | |
| 397 | 451 | rx_bytes += buff_info->len; |
| 398 | 452 | |
| 399 | 453 | if (buff_info->len <= oq->max_single_buffer_size) { |
| 400 | − skb = build_skb((void *)resp_hw, PAGE_SIZE); | |
| 401 | − skb_reserve(skb, data_offset); | |
| 402 | 454 | skb_put(skb, buff_info->len); |
| 403 | − read_idx++; | |
| 404 | − desc_used++; | |
| 405 | − if (read_idx == oq->max_count) | |
| 406 | − read_idx = 0; | |
| 407 | 455 | } else { |
| 408 | 456 | struct skb_shared_info *shinfo; |
| 409 | 457 | u16 data_len; |
| 410 | 458 | |
| 411 | − skb = build_skb((void *)resp_hw, PAGE_SIZE); | |
| 412 | − skb_reserve(skb, data_offset); | |
| 413 | 459 | /* Head fragment includes response header(s); |
| 414 | 460 | * subsequent fragments contains only data. |
| 415 | 461 | */ |
| 416 | 462 | skb_put(skb, oq->max_single_buffer_size); |
| 417 | − read_idx++; | |
| 418 | − desc_used++; | |
| 419 | − if (read_idx == oq->max_count) | |
| 420 | − read_idx = 0; | |
| 421 | − | |
| 422 | 463 | shinfo = skb_shinfo(skb); |
| 423 | 464 | data_len = buff_info->len - oq->max_single_buffer_size; |
| 424 | 465 | while (data_len) { |
| 425 | − dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr, | |
| 426 | − PAGE_SIZE, DMA_FROM_DEVICE); | |
| 427 | 466 | buff_info = (struct octep_rx_buffer *) |
| 428 | 467 | &oq->buff_info[read_idx]; |
| 429 | 468 | if (data_len < oq->buffer_size) { |
| @@ -438,11 +477,8 @@ static int __octep_oq_process_rx(struct octep_device *oct, · 8 unmodified lines | ||
| 438 | 477 | buff_info->page, 0, |
| 439 | 478 | buff_info->len, |
| 440 | 479 | buff_info->len); |
| 441 | − buff_info->page = NULL; | |
| 442 | − read_idx++; | |
| 443 | − desc_used++; | |
| 444 | − if (read_idx == oq->max_count) | |
| 445 | − read_idx = 0; | |
| 480 | + | |
| 481 | + octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used); | |
| 446 | 482 | } |
| 447 | 483 | } |
| 448 | 484 | |
| @@ -2411,7 +2411,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, · 2410 unmodified lines | ||
| 2411 | 2411 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); |
| 2412 | 2412 | if (!(cfg & BIT_ULL(12))) |
| 2413 | 2413 | continue; |
| 2414 | − bmap |= (1 << i); | |
| 2414 | + bmap |= BIT_ULL(i); | |
| 2415 | 2415 | cfg &= ~BIT_ULL(12); |
| 2416 | 2416 | rvu_write64(rvu, blkaddr, |
| 2417 | 2417 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link), cfg); |
| @@ -2432,7 +2432,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, · 14 unmodified lines | ||
| 2432 | 2432 | |
| 2433 | 2433 | /* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */ |
| 2434 | 2434 | for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) { |
| 2435 | − if (!(bmap & (1 << i))) | |
| 2435 | + if (!(bmap & BIT_ULL(i))) | |
| 2436 | 2436 | continue; |
| 2437 | 2437 | cfg = rvu_read64(rvu, blkaddr, |
| 2438 | 2438 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); |
| @@ -2471,10 +2471,6 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, · 2470 unmodified lines | ||
| 2471 | 2471 | e->dma_addr = addr; |
| 2472 | 2472 | e->dma_len = len; |
| 2473 | 2473 | |
| 2474 | − airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), | |
| 2475 | − TX_RING_CPU_IDX_MASK, | |
| 2476 | − FIELD_PREP(TX_RING_CPU_IDX_MASK, index)); | |
| 2477 | − | |
| 2478 | 2474 | data = skb_frag_address(frag); |
| 2479 | 2475 | len = skb_frag_size(frag); |
| 2480 | 2476 | } |
| @@ -2483,6 +2479,11 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, · 2 unmodified lines | ||
| 2483 | 2479 | q->queued += i; |
| 2484 | 2480 | |
| 2485 | 2481 | skb_tx_timestamp(skb); |
| 2482 | + if (!netdev_xmit_more()) | |
| 2483 | + airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), | |
| 2484 | + TX_RING_CPU_IDX_MASK, | |
| 2485 | + FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); | |
| 2486 | + | |
| 2486 | 2487 | if (q->ndesc - q->queued < q->free_thr) |
| 2487 | 2488 | netif_tx_stop_queue(txq); |
| 2488 | 2489 | |
| @@ -1171,7 +1171,7 @@ static int mtk_init_fq_dma(struct mtk_eth *eth) · 1170 unmodified lines | ||
| 1171 | 1171 | if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) |
| 1172 | 1172 | return -ENOMEM; |
| 1173 | 1173 | |
| 1174 | − for (i = 0; i < cnt; i++) { | |
| 1174 | + for (i = 0; i < len; i++) { | |
| 1175 | 1175 | struct mtk_tx_dma_v2 *txd; |
| 1176 | 1176 | |
| 1177 | 1177 | txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size; |
| @@ -1765,6 +1765,10 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force · 1764 unmodified lines | ||
| 1765 | 1765 | } |
| 1766 | 1766 | } |
| 1767 | 1767 | |
| 1768 | +#define MLX5_MAX_MANAGE_PAGES_CMD_ENT 1 | |
| 1769 | +#define MLX5_CMD_MASK ((1UL << (cmd->vars.max_reg_cmds + \ | |
| 1770 | + MLX5_MAX_MANAGE_PAGES_CMD_ENT)) - 1) | |
| 1771 | + | |
| 1768 | 1772 | static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) |
| 1769 | 1773 | { |
| 1770 | 1774 | struct mlx5_cmd *cmd = &dev->cmd; |
| @@ -1776,7 +1780,7 @@ static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) · 5 unmodified lines | ||
| 1776 | 1780 | /* wait for pending handlers to complete */ |
| 1777 | 1781 | mlx5_eq_synchronize_cmd_irq(dev); |
| 1778 | 1782 | spin_lock_irqsave(&dev->cmd.alloc_lock, flags); |
| 1779 | − vector = ~dev->cmd.vars.bitmask & ((1ul << (1 << dev->cmd.vars.log_sz)) - 1); | |
| 1783 | + vector = ~dev->cmd.vars.bitmask & MLX5_CMD_MASK; | |
| 1780 | 1784 | if (!vector) |
| 1781 | 1785 | goto no_trig; |
| 1782 | 1786 | |
| @@ -2361,7 +2365,7 @@ int mlx5_cmd_enable(struct mlx5_core_dev *dev) · 578 unmodified lines | ||
| 2361 | 2365 | |
| 2362 | 2366 | cmd->state = MLX5_CMDIF_STATE_DOWN; |
| 2363 | 2367 | cmd->vars.max_reg_cmds = (1 << cmd->vars.log_sz) - 1; |
| 2364 | − cmd->vars.bitmask = (1UL << cmd->vars.max_reg_cmds) - 1; | |
| 2368 | + cmd->vars.bitmask = MLX5_CMD_MASK; | |
| 2365 | 2369 | |
| 2366 | 2370 | sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds); |
| 2367 | 2371 | sema_init(&cmd->vars.pages_sem, 1); |
| @@ -6509,7 +6509,9 @@ static void _mlx5e_remove(struct auxiliary_device *adev) · 6508 unmodified lines | ||
| 6509 | 6509 | mlx5e_dcbnl_delete_app(priv); |
| 6510 | 6510 | unregister_netdev(priv->netdev); |
| 6511 | 6511 | _mlx5e_suspend(adev, false); |
| 6512 | − priv->profile->cleanup(priv); | |
| 6512 | + /* Avoid cleanup if profile rollback failed. */ | |
| 6513 | + if (priv->profile) | |
| 6514 | + priv->profile->cleanup(priv); | |
| 6513 | 6515 | mlx5e_destroy_netdev(priv); |
| 6514 | 6516 | mlx5e_devlink_port_unregister(mlx5e_dev); |
| 6515 | 6517 | mlx5e_destroy_devlink(mlx5e_dev); |
| @@ -1061,6 +1061,12 @@ int mlx5_comp_eqn_get(struct mlx5_core_dev *dev, u16 vecidx, int *eqn) · 1060 unmodified lines | ||
| 1061 | 1061 | struct mlx5_eq_comp *eq; |
| 1062 | 1062 | int ret = 0; |
| 1063 | 1063 | |
| 1064 | + if (vecidx >= table->max_comp_eqs) { | |
| 1065 | + mlx5_core_dbg(dev, "Requested vector index %u should be less than %u", | |
| 1066 | + vecidx, table->max_comp_eqs); | |
| 1067 | + return -EINVAL; | |
| 1068 | + } | |
| 1069 | + | |
| 1064 | 1070 | mutex_lock(&table->comp_lock); |
| 1065 | 1071 | eq = xa_load(&table->comp_eqs, vecidx); |
| 1066 | 1072 | if (eq) { |
| @@ -1489,7 +1489,7 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) · 1488 unmodified lines | ||
| 1489 | 1489 | } |
| 1490 | 1490 | |
| 1491 | 1491 | if (err) |
| 1492 | − goto abort; | |
| 1492 | + goto err_esw_enable; | |
| 1493 | 1493 | |
| 1494 | 1494 | esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED; |
| 1495 | 1495 | |
| @@ -1503,7 +1503,8 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) · 7 unmodified lines | ||
| 1503 | 1503 | |
| 1504 | 1504 | return 0; |
| 1505 | 1505 | |
| 1506 | −abort: | |
| 1506 | +err_esw_enable: | |
| 1507 | + mlx5_eq_notifier_unregister(esw->dev, &esw->nb); | |
| 1507 | 1508 | mlx5_esw_acls_ns_cleanup(esw); |
| 1508 | 1509 | return err; |
| 1509 | 1510 | } |
| @@ -691,7 +691,6 @@ static int hws_bwc_matcher_move(struct mlx5hws_bwc_matcher *bwc_matcher) · 690 unmodified lines | ||
| 691 | 691 | static int |
| 692 | 692 | hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) |
| 693 | 693 | { |
| 694 | − u32 num_of_rules; | |
| 695 | 694 | int ret; |
| 696 | 695 | |
| 697 | 696 | /* If the current matcher size is already at its max size, we can't |
| @@ -705,8 +704,7 @@ hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) · 7 unmodified lines | ||
| 705 | 704 | * Need to check again if we really need rehash. |
| 706 | 705 | * If the reason for rehash was size, but not any more - skip rehash. |
| 707 | 706 | */ |
| 708 | − num_of_rules = __atomic_load_n(&bwc_matcher->num_of_rules, __ATOMIC_RELAXED); | |
| 709 | − if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules)) | |
| 707 | + if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, bwc_matcher->num_of_rules)) | |
| 710 | 708 | return 0; |
| 711 | 709 | |
| 712 | 710 | /* Now we're done all the checking - do the rehash: |
| @@ -46,6 +46,7 @@ struct mlx5hws_context { · 45 unmodified lines | ||
| 46 | 46 | struct mlx5hws_send_engine *send_queue; |
| 47 | 47 | size_t queues; |
| 48 | 48 | struct mutex *bwc_send_queue_locks; /* protect BWC queues */ |
| 49 | + struct lock_class_key *bwc_lock_class_keys; | |
| 49 | 50 | struct list_head tbl_list; |
| 50 | 51 | struct mlx5hws_context_debug_info debug_info; |
| 51 | 52 | struct xarray peer_ctx_xa; |
| @@ -1925,7 +1925,7 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx, · 1924 unmodified lines | ||
| 1925 | 1925 | ret = hws_definer_conv_match_params_to_hl(ctx, mt, match_hl); |
| 1926 | 1926 | if (ret) { |
| 1927 | 1927 | mlx5hws_err(ctx, "Failed to convert items to header layout\n"); |
| 1928 | − goto free_fc; | |
| 1928 | + goto free_match_hl; | |
| 1929 | 1929 | } |
| 1930 | 1930 | |
| 1931 | 1931 | /* Find the match definer layout for header layout match union */ |
| @@ -1946,7 +1946,7 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx, · 14 unmodified lines | ||
| 1946 | 1946 | |
| 1947 | 1947 | free_fc: |
| 1948 | 1948 | kfree(mt->fc); |
| 1949 | − | |
| 1949 | +free_match_hl: | |
| 1950 | 1950 | kfree(match_hl); |
| 1951 | 1951 | return ret; |
| 1952 | 1952 | } |
| @@ -941,14 +941,18 @@ static void __hws_send_queues_close(struct mlx5hws_context *ctx, u16 queues) · 940 unmodified lines | ||
| 941 | 941 | |
| 942 | 942 | static void hws_send_queues_bwc_locks_destroy(struct mlx5hws_context *ctx) |
| 943 | 943 | { |
| 944 | − int bwc_queues = ctx->queues - 1; | |
| 944 | + int bwc_queues = mlx5hws_bwc_queues(ctx); | |
| 945 | 945 | int i; |
| 946 | 946 | |
| 947 | 947 | if (!mlx5hws_context_bwc_supported(ctx)) |
| 948 | 948 | return; |
| 949 | 949 | |
| 950 | − for (i = 0; i < bwc_queues; i++) | |
| 950 | + for (i = 0; i < bwc_queues; i++) { | |
| 951 | 951 | mutex_destroy(&ctx->bwc_send_queue_locks[i]); |
| 952 | + lockdep_unregister_key(ctx->bwc_lock_class_keys + i); | |
| 953 | + } | |
| 954 | + | |
| 955 | + kfree(ctx->bwc_lock_class_keys); | |
| 952 | 956 | kfree(ctx->bwc_send_queue_locks); |
| 953 | 957 | } |
| 954 | 958 | |
| @@ -977,10 +981,22 @@ static int hws_bwc_send_queues_init(struct mlx5hws_context *ctx) · 22 unmodified lines | ||
| 977 | 981 | if (!ctx->bwc_send_queue_locks) |
| 978 | 982 | return -ENOMEM; |
| 979 | 983 | |
| 980 | − for (i = 0; i < bwc_queues; i++) | |
| 984 | + ctx->bwc_lock_class_keys = kcalloc(bwc_queues, | |
| 985 | + sizeof(*ctx->bwc_lock_class_keys), | |
| 986 | + GFP_KERNEL); | |
| 987 | + if (!ctx->bwc_lock_class_keys) | |
| 988 | + goto err_lock_class_keys; | |
| 989 | + | |
| 990 | + for (i = 0; i < bwc_queues; i++) { | |
| 981 | 991 | mutex_init(&ctx->bwc_send_queue_locks[i]); |
| 992 | + lockdep_register_key(ctx->bwc_lock_class_keys + i); | |
| 993 | + } | |
| 982 | 994 | |
| 983 | 995 | return 0; |
| 996 | + | |
| 997 | +err_lock_class_keys: | |
| 998 | + kfree(ctx->bwc_send_queue_locks); | |
| 999 | + return -ENOMEM; | |
| 984 | 1000 | } |
| 985 | 1001 | |
| 986 | 1002 | int mlx5hws_send_queues_open(struct mlx5hws_context *ctx, |
| @@ -3197,7 +3197,6 @@ mlxsw_sp_nexthop_sh_counter_get(struct mlxsw_sp *mlxsw_sp, · 3196 unmodified lines | ||
| 3197 | 3197 | { |
| 3198 | 3198 | struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp; |
| 3199 | 3199 | struct mlxsw_sp_nexthop_counter *nhct; |
| 3200 | − void *ptr; | |
| 3201 | 3200 | int err; |
| 3202 | 3201 | |
| 3203 | 3202 | nhct = xa_load(&nh_grp->nhgi->nexthop_counters, nh->id); |
| @@ -3210,12 +3209,10 @@ mlxsw_sp_nexthop_sh_counter_get(struct mlxsw_sp *mlxsw_sp, · 6 unmodified lines | ||
| 3210 | 3209 | if (IS_ERR(nhct)) |
| 3211 | 3210 | return nhct; |
| 3212 | 3211 | |
| 3213 | − ptr = xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct, | |
| 3214 | − GFP_KERNEL); | |
| 3215 | − if (IS_ERR(ptr)) { | |
| 3216 | − err = PTR_ERR(ptr); | |
| 3212 | + err = xa_err(xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct, | |
| 3213 | + GFP_KERNEL)); | |
| 3214 | + if (err) | |
| 3217 | 3215 | goto err_store; |
| 3218 | − } | |
| 3219 | 3216 | |
| 3220 | 3217 | return nhct; |
| 3221 | 3218 | |
| @@ -401,28 +401,21 @@ static int lan743x_ptpci_settime64(struct ptp_clock_info *ptpci, · 400 unmodified lines | ||
| 401 | 401 | u32 nano_seconds = 0; |
| 402 | 402 | u32 seconds = 0; |
| 403 | 403 | |
| 404 | − if (ts) { | |
| 405 | − if (ts->tv_sec > 0xFFFFFFFFLL || | |
| 406 | − ts->tv_sec < 0) { | |
| 407 | − netif_warn(adapter, drv, adapter->netdev, | |
| 408 | − "ts->tv_sec out of range, %lld\n", | |
| 409 | − ts->tv_sec); | |
| 410 | − return -ERANGE; | |
| 411 | − } | |
| 412 | − if (ts->tv_nsec >= 1000000000L || | |
| 413 | − ts->tv_nsec < 0) { | |
| 414 | − netif_warn(adapter, drv, adapter->netdev, | |
| 415 | − "ts->tv_nsec out of range, %ld\n", | |
| 416 | − ts->tv_nsec); | |
| 417 | − return -ERANGE; | |
| 418 | − } | |
| 419 | − seconds = ts->tv_sec; | |
| 420 | − nano_seconds = ts->tv_nsec; | |
| 421 | − lan743x_ptp_clock_set(adapter, seconds, nano_seconds, 0); | |
| 422 | − } else { | |
| 423 | − netif_warn(adapter, drv, adapter->netdev, "ts == NULL\n"); | |
| 424 | − return -EINVAL; | |
| 404 | + if (ts->tv_sec > 0xFFFFFFFFLL) { | |
| 405 | + netif_warn(adapter, drv, adapter->netdev, | |
| 406 | + "ts->tv_sec out of range, %lld\n", | |
| 407 | + ts->tv_sec); | |
| 408 | + return -ERANGE; | |
| 409 | + } | |
| 410 | + if (ts->tv_nsec < 0) { | |
| 411 | + netif_warn(adapter, drv, adapter->netdev, | |
| 412 | + "ts->tv_nsec out of range, %ld\n", | |
| 413 | + ts->tv_nsec); | |
| 414 | + return -ERANGE; | |
| 425 | 415 | } |
| 416 | + seconds = ts->tv_sec; | |
| 417 | + nano_seconds = ts->tv_nsec; | |
| 418 | + lan743x_ptp_clock_set(adapter, seconds, nano_seconds, 0); | |
| 426 | 419 | |
| 427 | 420 | return 0; |
| 428 | 421 | } |
| @@ -31,10 +31,10 @@ static u64 sparx5_mirror_port_get(struct sparx5 *sparx5, u32 idx) · 30 unmodified lines | ||
| 31 | 31 | /* Add port to mirror (only front ports) */ |
| 32 | 32 | static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno) |
| 33 | 33 | { |
| 34 | − u32 val, reg = portno; | |
| 34 | + u64 reg = portno; | |
| 35 | + u32 val; | |
| 35 | 36 | |
| 36 | − reg = portno / BITS_PER_BYTE; | |
| 37 | − val = BIT(portno % BITS_PER_BYTE); | |
| 37 | + val = BIT(do_div(reg, 32)); | |
| 38 | 38 | |
| 39 | 39 | if (reg == 0) |
| 40 | 40 | return spx5_rmw(val, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); |
| @@ -45,10 +45,10 @@ static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno) · 4 unmodified lines | ||
| 45 | 45 | /* Delete port from mirror (only front ports) */ |
| 46 | 46 | static void sparx5_mirror_port_del(struct sparx5 *sparx5, u32 idx, u32 portno) |
| 47 | 47 | { |
| 48 | − u32 val, reg = portno; | |
| 48 | + u64 reg = portno; | |
| 49 | + u32 val; | |
| 49 | 50 | |
| 50 | − reg = portno / BITS_PER_BYTE; | |
| 51 | − val = BIT(portno % BITS_PER_BYTE); | |
| 51 | + val = BIT(do_div(reg, 32)); | |
| 52 | 52 | |
| 53 | 53 | if (reg == 0) |
| 54 | 54 | return spx5_rmw(0, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); |
| @@ -1444,6 +1444,8 @@ static void vcap_api_encode_rule_test(struct kunit *test) · 1443 unmodified lines | ||
| 1444 | 1444 | |
| 1445 | 1445 | ret = vcap_del_rule(&test_vctrl, &test_netdev, id); |
| 1446 | 1446 | KUNIT_EXPECT_EQ(test, 0, ret); |
| 1447 | + | |
| 1448 | + vcap_free_rule(rule); | |
| 1447 | 1449 | } |
| 1448 | 1450 | |
| 1449 | 1451 | static void vcap_api_set_rule_counter_test(struct kunit *test) |
| @@ -4682,7 +4682,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) · 4681 unmodified lines | ||
| 4682 | 4682 | if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask)) |
| 4683 | 4683 | return IRQ_NONE; |
| 4684 | 4684 | |
| 4685 | − if (unlikely(status & SYSErr)) { | |
| 4685 | + /* At least RTL8168fp may unexpectedly set the SYSErr bit */ | |
| 4686 | + if (unlikely(status & SYSErr && | |
| 4687 | + tp->mac_version <= RTL_GIGA_MAC_VER_06)) { | |
| 4686 | 4688 | rtl8169_pcierr_interrupt(tp->dev); |
| 4687 | 4689 | goto out; |
| 4688 | 4690 | } |
| @@ -1750,20 +1750,19 @@ static int ravb_get_ts_info(struct net_device *ndev, · 1749 unmodified lines | ||
| 1750 | 1750 | struct ravb_private *priv = netdev_priv(ndev); |
| 1751 | 1751 | const struct ravb_hw_info *hw_info = priv->info; |
| 1752 | 1752 | |
| 1753 | − info->so_timestamping = | |
| 1754 | − SOF_TIMESTAMPING_TX_SOFTWARE | | |
| 1755 | − SOF_TIMESTAMPING_TX_HARDWARE | | |
| 1756 | − SOF_TIMESTAMPING_RX_HARDWARE | | |
| 1757 | − SOF_TIMESTAMPING_RAW_HARDWARE; | |
| 1758 | − info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); | |
| 1759 | − info->rx_filters = | |
| 1760 | − (1 << HWTSTAMP_FILTER_NONE) | | |
| 1761 | − (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | | |
| 1762 | − (1 << HWTSTAMP_FILTER_ALL); | |
| 1763 | − if (hw_info->gptp || hw_info->ccc_gac) | |
| 1753 | + if (hw_info->gptp || hw_info->ccc_gac) { | |
| 1754 | + info->so_timestamping = | |
| 1755 | + SOF_TIMESTAMPING_TX_SOFTWARE | | |
| 1756 | + SOF_TIMESTAMPING_TX_HARDWARE | | |
| 1757 | + SOF_TIMESTAMPING_RX_HARDWARE | | |
| 1758 | + SOF_TIMESTAMPING_RAW_HARDWARE; | |
| 1759 | + info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); | |
| 1760 | + info->rx_filters = | |
| 1761 | + (1 << HWTSTAMP_FILTER_NONE) | | |
| 1762 | + (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | | |
| 1763 | + (1 << HWTSTAMP_FILTER_ALL); | |
| 1764 | 1764 | info->phc_index = ptp_clock_index(priv->ptp.clock); |
| 1765 | − else | |
| 1766 | − info->phc_index = 0; | |
| 1765 | + } | |
| 1767 | 1766 | |
| 1768 | 1767 | return 0; |
| 1769 | 1768 | } |
| @@ -1057,6 +1057,7 @@ static netdev_tx_t rtsn_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1056 unmodified lines | ||
| 1057 | 1057 | if (skb->len >= TX_DS) { |
| 1058 | 1058 | priv->stats.tx_dropped++; |
| 1059 | 1059 | priv->stats.tx_errors++; |
| 1060 | + dev_kfree_skb_any(skb); | |
| 1060 | 1061 | goto out; |
| 1061 | 1062 | } |
| 1062 | 1063 | |
| @@ -1260,7 +1260,8 @@ static int efx_poll(struct napi_struct *napi, int budget) · 1259 unmodified lines | ||
| 1260 | 1260 | |
| 1261 | 1261 | spent = efx_process_channel(channel, budget); |
| 1262 | 1262 | |
| 1263 | − xdp_do_flush(); | |
| 1263 | + if (budget) | |
| 1264 | + xdp_do_flush(); | |
| 1264 | 1265 | |
| 1265 | 1266 | if (spent < budget) { |
| 1266 | 1267 | if (efx_channel_has_rx_queue(channel) && |
| @@ -1285,7 +1285,8 @@ static int efx_poll(struct napi_struct *napi, int budget) · 1284 unmodified lines | ||
| 1285 | 1285 | |
| 1286 | 1286 | spent = efx_process_channel(channel, budget); |
| 1287 | 1287 | |
| 1288 | − xdp_do_flush(); | |
| 1288 | + if (budget) | |
| 1289 | + xdp_do_flush(); | |
| 1289 | 1290 | |
| 1290 | 1291 | if (spent < budget) { |
| 1291 | 1292 | if (efx_channel_has_rx_queue(channel) && |
| @@ -127,10 +127,12 @@ static int mgbe_uphy_lane_bringup_serdes_up(struct net_device *ndev, void *mgbe_ · 126 unmodified lines | ||
| 127 | 127 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ; |
| 128 | 128 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 129 | 129 | |
| 130 | + usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | |
| 130 | 131 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 131 | 132 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP; |
| 132 | 133 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 133 | 134 | |
| 135 | + usleep_range(10, 20); /* 500ns min delay needed as per HW design */ | |
| 134 | 136 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 135 | 137 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN; |
| 136 | 138 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| @@ -143,22 +145,30 @@ static int mgbe_uphy_lane_bringup_serdes_up(struct net_device *ndev, void *mgbe_ · 6 unmodified lines | ||
| 143 | 145 | return err; |
| 144 | 146 | } |
| 145 | 147 | |
| 148 | + usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | |
| 146 | 149 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 147 | 150 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN; |
| 148 | 151 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 149 | 152 | |
| 150 | 153 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 151 | − value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET; | |
| 154 | + value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY; | |
| 152 | 155 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 153 | 156 | |
| 157 | + usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | |
| 154 | 158 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 155 | − value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET; | |
| 159 | + value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET; | |
| 156 | 160 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 157 | 161 | |
| 162 | + usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | |
| 158 | 163 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 159 | 164 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY; |
| 160 | 165 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 161 | 166 | |
| 167 | + msleep(30); /* 30ms delay needed as per HW design */ | |
| 168 | + value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | |
| 169 | + value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET; | |
| 170 | + writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | |
| 171 | + | |
| 162 | 172 | err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_IRQ_STATUS, value, |
| 163 | 173 | value & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS, |
| 164 | 174 | 500, 500 * 2000); |
| @@ -2035,7 +2035,7 @@ static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, · 2034 unmodified lines | ||
| 2035 | 2035 | rx_q->queue_index = queue; |
| 2036 | 2036 | rx_q->priv_data = priv; |
| 2037 | 2037 | |
| 2038 | − pp_params.flags = PP_FLAG_DMA_MAP | (xdp_prog ? PP_FLAG_DMA_SYNC_DEV : 0); | |
| 2038 | + pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV; | |
| 2039 | 2039 | pp_params.pool_size = dma_conf->dma_rx_size; |
| 2040 | 2040 | num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE); |
| 2041 | 2041 | pp_params.order = ilog2(num_pages); |
| @@ -2744,10 +2744,9 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) · 2743 unmodified lines | ||
| 2744 | 2744 | return 0; |
| 2745 | 2745 | |
| 2746 | 2746 | /* alloc netdev */ |
| 2747 | − port->ndev = devm_alloc_etherdev_mqs(common->dev, | |
| 2748 | − sizeof(struct am65_cpsw_ndev_priv), | |
| 2749 | − AM65_CPSW_MAX_QUEUES, | |
| 2750 | − AM65_CPSW_MAX_QUEUES); | |
| 2747 | + port->ndev = alloc_etherdev_mqs(sizeof(struct am65_cpsw_ndev_priv), | |
| 2748 | + AM65_CPSW_MAX_QUEUES, | |
| 2749 | + AM65_CPSW_MAX_QUEUES); | |
| 2751 | 2750 | if (!port->ndev) { |
| 2752 | 2751 | dev_err(dev, "error allocating slave net_device %u\n", |
| 2753 | 2752 | port->port_id); |
| @@ -2868,8 +2867,12 @@ static void am65_cpsw_nuss_cleanup_ndev(struct am65_cpsw_common *common) · 114 unmodified lines | ||
| 2868 | 2867 | |
| 2869 | 2868 | for (i = 0; i < common->port_num; i++) { |
| 2870 | 2869 | port = &common->ports[i]; |
| 2871 | − if (port->ndev && port->ndev->reg_state == NETREG_REGISTERED) | |
| 2870 | + if (!port->ndev) | |
| 2871 | + continue; | |
| 2872 | + if (port->ndev->reg_state == NETREG_REGISTERED) | |
| 2872 | 2873 | unregister_netdev(port->ndev); |
| 2874 | + free_netdev(port->ndev); | |
| 2875 | + port->ndev = NULL; | |
| 2873 | 2876 | } |
| 2874 | 2877 | } |
| 2875 | 2878 | |
| @@ -3613,16 +3616,17 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev) · 737 unmodified lines | ||
| 3613 | 3616 | |
| 3614 | 3617 | ret = am65_cpsw_nuss_init_ndevs(common); |
| 3615 | 3618 | if (ret) |
| 3616 | − goto err_free_phylink; | |
| 3619 | + goto err_ndevs_clear; | |
| 3617 | 3620 | |
| 3618 | 3621 | ret = am65_cpsw_nuss_register_ndevs(common); |
| 3619 | 3622 | if (ret) |
| 3620 | − goto err_free_phylink; | |
| 3623 | + goto err_ndevs_clear; | |
| 3621 | 3624 | |
| 3622 | 3625 | pm_runtime_put(dev); |
| 3623 | 3626 | return 0; |
| 3624 | 3627 | |
| 3625 | −err_free_phylink: | |
| 3628 | +err_ndevs_clear: | |
| 3629 | + am65_cpsw_nuss_cleanup_ndev(common); | |
| 3626 | 3630 | am65_cpsw_nuss_phylink_cleanup(common); |
| 3627 | 3631 | am65_cpts_release(common->cpts); |
| 3628 | 3632 | err_of_clear: |
| @@ -3652,13 +3656,13 @@ static void am65_cpsw_nuss_remove(struct platform_device *pdev) · 23 unmodified lines | ||
| 3652 | 3656 | return; |
| 3653 | 3657 | } |
| 3654 | 3658 | |
| 3655 | − am65_cpsw_unregister_devlink(common); | |
| 3656 | 3659 | am65_cpsw_unregister_notifiers(common); |
| 3657 | 3660 | |
| 3658 | 3661 | /* must unregister ndevs here because DD release_driver routine calls |
| 3659 | 3662 | * dma_deconfigure(dev) before devres_release_all(dev) |
| 3660 | 3663 | */ |
| 3661 | 3664 | am65_cpsw_nuss_cleanup_ndev(common); |
| 3665 | + am65_cpsw_unregister_devlink(common); | |
| 3662 | 3666 | am65_cpsw_nuss_phylink_cleanup(common); |
| 3663 | 3667 | am65_cpts_release(common->cpts); |
| 3664 | 3668 | am65_cpsw_disable_serdes_phy(common); |
| @@ -735,6 +735,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask, · 734 unmodified lines | ||
| 735 | 735 | u8 fid_c1; |
| 736 | 736 | |
| 737 | 737 | tbl = prueth->vlan_tbl; |
| 738 | + spin_lock(&prueth->vtbl_lock); | |
| 738 | 739 | fid_c1 = tbl[vid].fid_c1; |
| 739 | 740 | |
| 740 | 741 | /* FID_C1: bit0..2 port membership mask, |
| @@ -750,6 +751,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask, · 9 unmodified lines | ||
| 750 | 751 | } |
| 751 | 752 | |
| 752 | 753 | tbl[vid].fid_c1 = fid_c1; |
| 754 | + spin_unlock(&prueth->vtbl_lock); | |
| 753 | 755 | } |
| 754 | 756 | EXPORT_SYMBOL_GPL(icssg_vtbl_modify); |
| 755 | 757 | |
| @@ -1442,6 +1442,7 @@ static int prueth_probe(struct platform_device *pdev) · 1441 unmodified lines | ||
| 1442 | 1442 | icss_iep_init_fw(prueth->iep1); |
| 1443 | 1443 | } |
| 1444 | 1444 | |
| 1445 | + spin_lock_init(&prueth->vtbl_lock); | |
| 1445 | 1446 | /* setup netdev interfaces */ |
| 1446 | 1447 | if (eth0_node) { |
| 1447 | 1448 | ret = prueth_netdev_init(prueth, eth0_node); |
| @@ -296,6 +296,8 @@ struct prueth { · 295 unmodified lines | ||
| 296 | 296 | bool is_switchmode_supported; |
| 297 | 297 | unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; |
| 298 | 298 | int default_vlan; |
| 299 | + /** @vtbl_lock: Lock for vtbl in shared memory */ | |
| 300 | + spinlock_t vtbl_lock; | |
| 299 | 301 | }; |
| 300 | 302 | |
| 301 | 303 | struct emac_tx_ts_response { |
| @@ -1051,6 +1051,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1050 unmodified lines | ||
| 1051 | 1051 | if (net_ratelimit()) |
| 1052 | 1052 | netdev_err(ndev, "TX DMA mapping error\n"); |
| 1053 | 1053 | ndev->stats.tx_dropped++; |
| 1054 | + dev_kfree_skb_any(skb); | |
| 1054 | 1055 | return NETDEV_TX_OK; |
| 1055 | 1056 | } |
| 1056 | 1057 | desc_set_phys_addr(lp, phys, cur_p); |
| @@ -1071,6 +1072,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 14 unmodified lines | ||
| 1071 | 1072 | ndev->stats.tx_dropped++; |
| 1072 | 1073 | axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1, |
| 1073 | 1074 | true, NULL, 0); |
| 1075 | + dev_kfree_skb_any(skb); | |
| 1074 | 1076 | return NETDEV_TX_OK; |
| 1075 | 1077 | } |
| 1076 | 1078 | desc_set_phys_addr(lp, phys, cur_p); |
| @@ -2798,6 +2798,31 @@ static struct hv_driver netvsc_drv = { · 2797 unmodified lines | ||
| 2798 | 2798 | }, |
| 2799 | 2799 | }; |
| 2800 | 2800 | |
| 2801 | +/* Set VF's namespace same as the synthetic NIC */ | |
| 2802 | +static void netvsc_event_set_vf_ns(struct net_device *ndev) | |
| 2803 | +{ | |
| 2804 | + struct net_device_context *ndev_ctx = netdev_priv(ndev); | |
| 2805 | + struct net_device *vf_netdev; | |
| 2806 | + int ret; | |
| 2807 | + | |
| 2808 | + vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev); | |
| 2809 | + if (!vf_netdev) | |
| 2810 | + return; | |
| 2811 | + | |
| 2812 | + if (!net_eq(dev_net(ndev), dev_net(vf_netdev))) { | |
| 2813 | + ret = dev_change_net_namespace(vf_netdev, dev_net(ndev), | |
| 2814 | + "eth%d"); | |
| 2815 | + if (ret) | |
| 2816 | + netdev_err(vf_netdev, | |
| 2817 | + "Cannot move to same namespace as %s: %d\n", | |
| 2818 | + ndev->name, ret); | |
| 2819 | + else | |
| 2820 | + netdev_info(vf_netdev, | |
| 2821 | + "Moved VF to namespace with: %s\n", | |
| 2822 | + ndev->name); | |
| 2823 | + } | |
| 2824 | +} | |
| 2825 | + | |
| 2801 | 2826 | /* |
| 2802 | 2827 | * On Hyper-V, every VF interface is matched with a corresponding |
| 2803 | 2828 | * synthetic interface. The synthetic interface is presented first |
| @@ -2810,6 +2835,11 @@ static int netvsc_netdev_event(struct notifier_block *this, · 6 unmodified lines | ||
| 2810 | 2835 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); |
| 2811 | 2836 | int ret = 0; |
| 2812 | 2837 | |
| 2838 | + if (event_dev->netdev_ops == &device_ops && event == NETDEV_REGISTER) { | |
| 2839 | + netvsc_event_set_vf_ns(event_dev); | |
| 2840 | + return NOTIFY_DONE; | |
| 2841 | + } | |
| 2842 | + | |
| 2813 | 2843 | ret = check_dev_is_matching_vf(event_dev); |
| 2814 | 2844 | if (ret != 0) |
| 2815 | 2845 | return NOTIFY_DONE; |
| @@ -154,19 +154,6 @@ static struct macsec_rx_sa *macsec_rxsa_get(struct macsec_rx_sa __rcu *ptr) · 153 unmodified lines | ||
| 154 | 154 | return sa; |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | −static struct macsec_rx_sa *macsec_active_rxsa_get(struct macsec_rx_sc *rx_sc) | |
| 158 | −{ | |
| 159 | − struct macsec_rx_sa *sa = NULL; | |
| 160 | − int an; | |
| 161 | − | |
| 162 | − for (an = 0; an < MACSEC_NUM_AN; an++) { | |
| 163 | − sa = macsec_rxsa_get(rx_sc->sa[an]); | |
| 164 | − if (sa) | |
| 165 | − break; | |
| 166 | − } | |
| 167 | − return sa; | |
| 168 | −} | |
| 169 | − | |
| 170 | 157 | static void free_rx_sc_rcu(struct rcu_head *head) |
| 171 | 158 | { |
| 172 | 159 | struct macsec_rx_sc *rx_sc = container_of(head, struct macsec_rx_sc, rcu_head); |
| @@ -1208,15 +1195,12 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) · 1035 unmodified lines | ||
| 1208 | 1195 | /* If validateFrames is Strict or the C bit in the |
| 1209 | 1196 | * SecTAG is set, discard |
| 1210 | 1197 | */ |
| 1211 | − struct macsec_rx_sa *active_rx_sa = macsec_active_rxsa_get(rx_sc); | |
| 1212 | 1198 | if (hdr->tci_an & MACSEC_TCI_C || |
| 1213 | 1199 | secy->validate_frames == MACSEC_VALIDATE_STRICT) { |
| 1214 | 1200 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1215 | 1201 | rxsc_stats->stats.InPktsNotUsingSA++; |
| 1216 | 1202 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1217 | 1203 | DEV_STATS_INC(secy->netdev, rx_errors); |
| 1218 | − if (active_rx_sa) | |
| 1219 | − this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA); | |
| 1220 | 1204 | goto drop_nosa; |
| 1221 | 1205 | } |
| 1222 | 1206 | |
| @@ -1226,8 +1210,6 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) · 3 unmodified lines | ||
| 1226 | 1210 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1227 | 1211 | rxsc_stats->stats.InPktsUnusedSA++; |
| 1228 | 1212 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1229 | − if (active_rx_sa) | |
| 1230 | − this_cpu_inc(active_rx_sa->stats->InPktsUnusedSA); | |
| 1231 | 1213 | goto deliver; |
| 1232 | 1214 | } |
| 1233 | 1215 | |
| @@ -337,6 +337,7 @@ static const struct of_device_id unimac_mdio_ids[] = { · 336 unmodified lines | ||
| 337 | 337 | { .compatible = "brcm,asp-v2.2-mdio", }, |
| 338 | 338 | { .compatible = "brcm,asp-v2.1-mdio", }, |
| 339 | 339 | { .compatible = "brcm,asp-v2.0-mdio", }, |
| 340 | + { .compatible = "brcm,bcm6846-mdio", }, | |
| 340 | 341 | { .compatible = "brcm,genet-mdio-v5", }, |
| 341 | 342 | { .compatible = "brcm,genet-mdio-v4", }, |
| 342 | 343 | { .compatible = "brcm,genet-mdio-v3", }, |
| @@ -1161,8 +1161,14 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg, · 1160 unmodified lines | ||
| 1161 | 1161 | |
| 1162 | 1162 | this_chunk = min(userdata_len - sent_userdata, |
| 1163 | 1163 | MAX_PRINT_CHUNK - preceding_bytes); |
| 1164 | − if (WARN_ON_ONCE(this_chunk <= 0)) | |
| 1164 | + if (WARN_ON_ONCE(this_chunk < 0)) | |
| 1165 | + /* this_chunk could be zero if all the previous | |
| 1166 | + * message used all the buffer. This is not a | |
| 1167 | + * problem, userdata will be sent in the next | |
| 1168 | + * iteration | |
| 1169 | + */ | |
| 1165 | 1170 | return; |
| 1171 | + | |
| 1166 | 1172 | memcpy(buf + this_header + this_offset, |
| 1167 | 1173 | userdata + sent_userdata, |
| 1168 | 1174 | this_chunk); |
| @@ -836,7 +836,8 @@ static void nsim_dev_trap_report_work(struct work_struct *work) · 835 unmodified lines | ||
| 836 | 836 | nsim_dev = nsim_trap_data->nsim_dev; |
| 837 | 837 | |
| 838 | 838 | if (!devl_trylock(priv_to_devlink(nsim_dev))) { |
| 839 | − schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 1); | |
| 839 | + queue_delayed_work(system_unbound_wq, | |
| 840 | + &nsim_dev->trap_data->trap_report_dw, 1); | |
| 840 | 841 | return; |
| 841 | 842 | } |
| 842 | 843 | |
| @@ -848,11 +849,12 @@ static void nsim_dev_trap_report_work(struct work_struct *work) · 5 unmodified lines | ||
| 848 | 849 | continue; |
| 849 | 850 | |
| 850 | 851 | nsim_dev_trap_report(nsim_dev_port); |
| 852 | + cond_resched(); | |
| 851 | 853 | } |
| 852 | 854 | devl_unlock(priv_to_devlink(nsim_dev)); |
| 853 | − | |
| 854 | − schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, | |
| 855 | − msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | |
| 855 | + queue_delayed_work(system_unbound_wq, | |
| 856 | + &nsim_dev->trap_data->trap_report_dw, | |
| 857 | + msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | |
| 856 | 858 | } |
| 857 | 859 | |
| 858 | 860 | static int nsim_dev_traps_init(struct devlink *devlink) |
| @@ -907,8 +909,9 @@ static int nsim_dev_traps_init(struct devlink *devlink) · 48 unmodified lines | ||
| 907 | 909 | |
| 908 | 910 | INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw, |
| 909 | 911 | nsim_dev_trap_report_work); |
| 910 | − schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, | |
| 911 | − msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | |
| 912 | + queue_delayed_work(system_unbound_wq, | |
| 913 | + &nsim_dev->trap_data->trap_report_dw, | |
| 914 | + msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | |
| 912 | 915 | |
| 913 | 916 | return 0; |
| 914 | 917 | |
| @@ -537,12 +537,6 @@ static int aqcs109_config_init(struct phy_device *phydev) · 536 unmodified lines | ||
| 537 | 537 | if (!ret) |
| 538 | 538 | aqr107_chip_info(phydev); |
| 539 | 539 | |
| 540 | − /* AQCS109 belongs to a chip family partially supporting 10G and 5G. | |
| 541 | − * PMA speed ability bits are the same for all members of the family, | |
| 542 | − * AQCS109 however supports speeds up to 2.5G only. | |
| 543 | − */ | |
| 544 | − phy_set_max_speed(phydev, SPEED_2500); | |
| 545 | − | |
| 546 | 540 | return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); |
| 547 | 541 | } |
| 548 | 542 | |
| @@ -731,6 +725,31 @@ static int aqr113c_fill_interface_modes(struct phy_device *phydev) · 182 unmodified lines | ||
| 731 | 725 | return aqr107_fill_interface_modes(phydev); |
| 732 | 726 | } |
| 733 | 727 | |
| 728 | +static int aqr115c_get_features(struct phy_device *phydev) | |
| 729 | +{ | |
| 730 | + unsigned long *supported = phydev->supported; | |
| 731 | + | |
| 732 | + /* PHY supports speeds up to 2.5G with autoneg. PMA capabilities | |
| 733 | + * are not useful. | |
| 734 | + */ | |
| 735 | + linkmode_or(supported, supported, phy_gbit_features); | |
| 736 | + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported); | |
| 737 | + | |
| 738 | + return 0; | |
| 739 | +} | |
| 740 | + | |
| 741 | +static int aqr111_get_features(struct phy_device *phydev) | |
| 742 | +{ | |
| 743 | + /* PHY supports speeds up to 5G with autoneg. PMA capabilities | |
| 744 | + * are not useful. | |
| 745 | + */ | |
| 746 | + aqr115c_get_features(phydev); | |
| 747 | + linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, | |
| 748 | + phydev->supported); | |
| 749 | + | |
| 750 | + return 0; | |
| 751 | +} | |
| 752 | + | |
| 734 | 753 | static int aqr113c_config_init(struct phy_device *phydev) |
| 735 | 754 | { |
| 736 | 755 | int ret; |
| @@ -767,15 +786,6 @@ static int aqr107_probe(struct phy_device *phydev) · 30 unmodified lines | ||
| 767 | 786 | return aqr_hwmon_probe(phydev); |
| 768 | 787 | } |
| 769 | 788 | |
| 770 | −static int aqr111_config_init(struct phy_device *phydev) | |
| 771 | −{ | |
| 772 | − /* AQR111 reports supporting speed up to 10G, | |
| 773 | − * however only speeds up to 5G are supported. | |
| 774 | − */ | |
| 775 | − phy_set_max_speed(phydev, SPEED_5000); | |
| 776 | − | |
| 777 | − return aqr107_config_init(phydev); | |
| 778 | −} | |
| 779 | 789 | |
| 780 | 790 | static struct phy_driver aqr_driver[] = { |
| 781 | 791 | { |
| @@ -853,6 +863,7 @@ static struct phy_driver aqr_driver[] = { · 71 unmodified lines | ||
| 853 | 863 | .get_sset_count = aqr107_get_sset_count, |
| 854 | 864 | .get_strings = aqr107_get_strings, |
| 855 | 865 | .get_stats = aqr107_get_stats, |
| 866 | + .get_features = aqr115c_get_features, | |
| 856 | 867 | .link_change_notify = aqr107_link_change_notify, |
| 857 | 868 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 858 | 869 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -865,7 +876,7 @@ static struct phy_driver aqr_driver[] = { · 6 unmodified lines | ||
| 865 | 876 | .name = "Aquantia AQR111", |
| 866 | 877 | .probe = aqr107_probe, |
| 867 | 878 | .get_rate_matching = aqr107_get_rate_matching, |
| 868 | − .config_init = aqr111_config_init, | |
| 879 | + .config_init = aqr107_config_init, | |
| 869 | 880 | .config_aneg = aqr_config_aneg, |
| 870 | 881 | .config_intr = aqr_config_intr, |
| 871 | 882 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -877,6 +888,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | ||
| 877 | 888 | .get_sset_count = aqr107_get_sset_count, |
| 878 | 889 | .get_strings = aqr107_get_strings, |
| 879 | 890 | .get_stats = aqr107_get_stats, |
| 891 | + .get_features = aqr111_get_features, | |
| 880 | 892 | .link_change_notify = aqr107_link_change_notify, |
| 881 | 893 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 882 | 894 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -889,7 +901,7 @@ static struct phy_driver aqr_driver[] = { · 6 unmodified lines | ||
| 889 | 901 | .name = "Aquantia AQR111B0", |
| 890 | 902 | .probe = aqr107_probe, |
| 891 | 903 | .get_rate_matching = aqr107_get_rate_matching, |
| 892 | − .config_init = aqr111_config_init, | |
| 904 | + .config_init = aqr107_config_init, | |
| 893 | 905 | .config_aneg = aqr_config_aneg, |
| 894 | 906 | .config_intr = aqr_config_intr, |
| 895 | 907 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -901,6 +913,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | ||
| 901 | 913 | .get_sset_count = aqr107_get_sset_count, |
| 902 | 914 | .get_strings = aqr107_get_strings, |
| 903 | 915 | .get_stats = aqr107_get_stats, |
| 916 | + .get_features = aqr111_get_features, | |
| 904 | 917 | .link_change_notify = aqr107_link_change_notify, |
| 905 | 918 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 906 | 919 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -1010,7 +1023,7 @@ static struct phy_driver aqr_driver[] = { · 103 unmodified lines | ||
| 1010 | 1023 | .name = "Aquantia AQR114C", |
| 1011 | 1024 | .probe = aqr107_probe, |
| 1012 | 1025 | .get_rate_matching = aqr107_get_rate_matching, |
| 1013 | − .config_init = aqr111_config_init, | |
| 1026 | + .config_init = aqr107_config_init, | |
| 1014 | 1027 | .config_aneg = aqr_config_aneg, |
| 1015 | 1028 | .config_intr = aqr_config_intr, |
| 1016 | 1029 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -1022,6 +1035,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | ||
| 1022 | 1035 | .get_sset_count = aqr107_get_sset_count, |
| 1023 | 1036 | .get_strings = aqr107_get_strings, |
| 1024 | 1037 | .get_stats = aqr107_get_stats, |
| 1038 | + .get_features = aqr111_get_features, | |
| 1025 | 1039 | .link_change_notify = aqr107_link_change_notify, |
| 1026 | 1040 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 1027 | 1041 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -1046,6 +1060,7 @@ static struct phy_driver aqr_driver[] = { · 18 unmodified lines | ||
| 1046 | 1060 | .get_sset_count = aqr107_get_sset_count, |
| 1047 | 1061 | .get_strings = aqr107_get_strings, |
| 1048 | 1062 | .get_stats = aqr107_get_stats, |
| 1063 | + .get_features = aqr115c_get_features, | |
| 1049 | 1064 | .link_change_notify = aqr107_link_change_notify, |
| 1050 | 1065 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 1051 | 1066 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -132,7 +132,7 @@ static int bcm84881_aneg_done(struct phy_device *phydev) · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); |
| 134 | 134 | if (bmsr < 0) |
| 135 | − return val; | |
| 135 | + return bmsr; | |
| 136 | 136 | |
| 137 | 137 | return !!(val & MDIO_AN_STAT1_COMPLETE) && |
| 138 | 138 | !!(bmsr & BMSR_ANEGCOMPLETE); |
| @@ -158,7 +158,7 @@ static int bcm84881_read_status(struct phy_device *phydev) · 19 unmodified lines | ||
| 158 | 158 | |
| 159 | 159 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); |
| 160 | 160 | if (bmsr < 0) |
| 161 | − return val; | |
| 161 | + return bmsr; | |
| 162 | 162 | |
| 163 | 163 | phydev->autoneg_complete = !!(val & MDIO_AN_STAT1_COMPLETE) && |
| 164 | 164 | !!(bmsr & BMSR_ANEGCOMPLETE); |
| @@ -45,8 +45,8 @@ · 44 unmodified lines | ||
| 45 | 45 | /* Control Register 2 bits */ |
| 46 | 46 | #define DP83822_FX_ENABLE BIT(14) |
| 47 | 47 | |
| 48 | −#define DP83822_HW_RESET BIT(15) | |
| 49 | −#define DP83822_SW_RESET BIT(14) | |
| 48 | +#define DP83822_SW_RESET BIT(15) | |
| 49 | +#define DP83822_DIG_RESTART BIT(14) | |
| 50 | 50 | |
| 51 | 51 | /* PHY STS bits */ |
| 52 | 52 | #define DP83822_PHYSTS_DUPLEX BIT(2) |
| @@ -645,7 +645,6 @@ static int dp83869_configure_fiber(struct phy_device *phydev, · 644 unmodified lines | ||
| 645 | 645 | phydev->supported); |
| 646 | 646 | |
| 647 | 647 | linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); |
| 648 | − linkmode_set_bit(ADVERTISED_FIBRE, phydev->advertising); | |
| 649 | 648 | |
| 650 | 649 | if (dp83869->mode == DP83869_RGMII_1000_BASE) { |
| 651 | 650 | linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, |
| @@ -3326,10 +3326,11 @@ static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev, · 3325 unmodified lines | ||
| 3326 | 3326 | |
| 3327 | 3327 | static void phy_leds_unregister(struct phy_device *phydev) |
| 3328 | 3328 | { |
| 3329 | − struct phy_led *phyled; | |
| 3329 | + struct phy_led *phyled, *tmp; | |
| 3330 | 3330 | |
| 3331 | − list_for_each_entry(phyled, &phydev->leds, list) { | |
| 3331 | + list_for_each_entry_safe(phyled, tmp, &phydev->leds, list) { | |
| 3332 | 3332 | led_classdev_unregister(&phyled->led_cdev); |
| 3333 | + list_del(&phyled->list); | |
| 3333 | 3334 | } |
| 3334 | 3335 | } |
| 3335 | 3336 | |
| @@ -1081,6 +1081,16 @@ static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev) · 1080 unmodified lines | ||
| 1081 | 1081 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); |
| 1082 | 1082 | } |
| 1083 | 1083 | |
| 1084 | +static int rtl8251b_c22_match_phy_device(struct phy_device *phydev) | |
| 1085 | +{ | |
| 1086 | + return rtlgen_is_c45_match(phydev, RTL_8251B, false); | |
| 1087 | +} | |
| 1088 | + | |
| 1089 | +static int rtl8251b_c45_match_phy_device(struct phy_device *phydev) | |
| 1090 | +{ | |
| 1091 | + return rtlgen_is_c45_match(phydev, RTL_8251B, true); | |
| 1092 | +} | |
| 1093 | + | |
| 1084 | 1094 | static int rtlgen_resume(struct phy_device *phydev) |
| 1085 | 1095 | { |
| 1086 | 1096 | int ret = genphy_resume(phydev); |
| @@ -1418,7 +1428,7 @@ static struct phy_driver realtek_drvs[] = { · 331 unmodified lines | ||
| 1418 | 1428 | .suspend = genphy_c45_pma_suspend, |
| 1419 | 1429 | .resume = rtlgen_c45_resume, |
| 1420 | 1430 | }, { |
| 1421 | − PHY_ID_MATCH_EXACT(0x001cc862), | |
| 1431 | + .match_phy_device = rtl8251b_c45_match_phy_device, | |
| 1422 | 1432 | .name = "RTL8251B 5Gbps PHY", |
| 1423 | 1433 | .get_features = rtl822x_get_features, |
| 1424 | 1434 | .config_aneg = rtl822x_config_aneg, |
| @@ -1427,6 +1437,18 @@ static struct phy_driver realtek_drvs[] = { · 2 unmodified lines | ||
| 1427 | 1437 | .resume = rtlgen_resume, |
| 1428 | 1438 | .read_page = rtl821x_read_page, |
| 1429 | 1439 | .write_page = rtl821x_write_page, |
| 1440 | + }, { | |
| 1441 | + .match_phy_device = rtl8251b_c22_match_phy_device, | |
| 1442 | + .name = "RTL8126A-internal 5Gbps PHY", | |
| 1443 | + .get_features = rtl822x_get_features, | |
| 1444 | + .config_aneg = rtl822x_config_aneg, | |
| 1445 | + .read_status = rtl822x_read_status, | |
| 1446 | + .suspend = genphy_suspend, | |
| 1447 | + .resume = rtlgen_resume, | |
| 1448 | + .read_page = rtl821x_read_page, | |
| 1449 | + .write_page = rtl821x_write_page, | |
| 1450 | + .read_mmd = rtl822x_read_mmd, | |
| 1451 | + .write_mmd = rtl822x_write_mmd, | |
| 1430 | 1452 | }, { |
| 1431 | 1453 | PHY_ID_MATCH_EXACT(0x001ccad0), |
| 1432 | 1454 | .name = "RTL8224 2.5Gbps PHY", |
| @@ -815,7 +815,7 @@ plip_send_packet(struct net_device *dev, struct net_local *nl, · 814 unmodified lines | ||
| 815 | 815 | return HS_TIMEOUT; |
| 816 | 816 | } |
| 817 | 817 | } |
| 818 | − break; | |
| 818 | + fallthrough; | |
| 819 | 819 | |
| 820 | 820 | case PLIP_PK_LENGTH_LSB: |
| 821 | 821 | if (plip_send(nibble_timeout, dev, |
| @@ -542,7 +542,7 @@ ppp_async_encode(struct asyncppp *ap) · 541 unmodified lines | ||
| 542 | 542 | * and 7 (code-reject) must be sent as though no options |
| 543 | 543 | * had been negotiated. |
| 544 | 544 | */ |
| 545 | − islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7; | |
| 545 | + islcp = proto == PPP_LCP && count >= 3 && 1 <= data[2] && data[2] <= 7; | |
| 546 | 546 | |
| 547 | 547 | if (i == 0) { |
| 548 | 548 | if (islcp) |
| @@ -113,7 +113,7 @@ static void pse_release_pis(struct pse_controller_dev *pcdev) · 112 unmodified lines | ||
| 113 | 113 | { |
| 114 | 114 | int i; |
| 115 | 115 | |
| 116 | − for (i = 0; i <= pcdev->nr_lines; i++) { | |
| 116 | + for (i = 0; i < pcdev->nr_lines; i++) { | |
| 117 | 117 | of_node_put(pcdev->pi[i].pairset[0].np); |
| 118 | 118 | of_node_put(pcdev->pi[i].pairset[1].np); |
| 119 | 119 | of_node_put(pcdev->pi[i].np); |
| @@ -647,7 +647,7 @@ static int of_pse_match_pi(struct pse_controller_dev *pcdev, · 527 unmodified lines | ||
| 647 | 647 | { |
| 648 | 648 | int i; |
| 649 | 649 | |
| 650 | − for (i = 0; i <= pcdev->nr_lines; i++) { | |
| 650 | + for (i = 0; i < pcdev->nr_lines; i++) { | |
| 651 | 651 | if (pcdev->pi[i].np == np) |
| 652 | 652 | return i; |
| 653 | 653 | } |
| @@ -785,6 +785,17 @@ static int pse_ethtool_c33_set_config(struct pse_control *psec, · 131 unmodified lines | ||
| 785 | 785 | */ |
| 786 | 786 | switch (config->c33_admin_control) { |
| 787 | 787 | case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED: |
| 788 | + /* We could have mismatch between admin_state_enabled and | |
| 789 | + * state reported by regulator_is_enabled. This can occur when | |
| 790 | + * the PI is forcibly turn off by the controller. Call | |
| 791 | + * regulator_disable on that case to fix the counters state. | |
| 792 | + */ | |
| 793 | + if (psec->pcdev->pi[psec->id].admin_state_enabled && | |
| 794 | + !regulator_is_enabled(psec->ps)) { | |
| 795 | + err = regulator_disable(psec->ps); | |
| 796 | + if (err) | |
| 797 | + break; | |
| 798 | + } | |
| 788 | 799 | if (!psec->pcdev->pi[psec->id].admin_state_enabled) |
| 789 | 800 | err = regulator_enable(psec->ps); |
| 790 | 801 | break; |
| @@ -643,46 +643,57 @@ bad: · 642 unmodified lines | ||
| 643 | 643 | int |
| 644 | 644 | slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) |
| 645 | 645 | { |
| 646 | − struct cstate *cs; | |
| 647 | − unsigned ihl; | |
| 648 | − | |
| 646 | + const struct tcphdr *th; | |
| 649 | 647 | unsigned char index; |
| 648 | + struct iphdr *iph; | |
| 649 | + struct cstate *cs; | |
| 650 | + unsigned int ihl; | |
| 650 | 651 | |
| 651 | − if(isize < 20) { | |
| 652 | − /* The packet is shorter than a legal IP header */ | |
| 652 | + /* The packet is shorter than a legal IP header. | |
| 653 | + * Also make sure isize is positive. | |
| 654 | + */ | |
| 655 | + if (isize < (int)sizeof(struct iphdr)) { | |
| 656 | +runt: | |
| 653 | 657 | comp->sls_i_runt++; |
| 654 | − return slhc_toss( comp ); | |
| 658 | + return slhc_toss(comp); | |
| 655 | 659 | } |
| 660 | + iph = (struct iphdr *)icp; | |
| 656 | 661 | /* Peek at the IP header's IHL field to find its length */ |
| 657 | − ihl = icp[0] & 0xf; | |
| 658 | − if(ihl < 20 / 4){ | |
| 659 | − /* The IP header length field is too small */ | |
| 660 | − comp->sls_i_runt++; | |
| 661 | − return slhc_toss( comp ); | |
| 662 | − } | |
| 663 | − index = icp[9]; | |
| 664 | − icp[9] = IPPROTO_TCP; | |
| 662 | + ihl = iph->ihl; | |
| 663 | + /* The IP header length field is too small, | |
| 664 | + * or packet is shorter than the IP header followed | |
| 665 | + * by minimal tcp header. | |
| 666 | + */ | |
| 667 | + if (ihl < 5 || isize < ihl * 4 + sizeof(struct tcphdr)) | |
| 668 | + goto runt; | |
| 669 | + | |
| 670 | + index = iph->protocol; | |
| 671 | + iph->protocol = IPPROTO_TCP; | |
| 665 | 672 | |
| 666 | 673 | if (ip_fast_csum(icp, ihl)) { |
| 667 | 674 | /* Bad IP header checksum; discard */ |
| 668 | 675 | comp->sls_i_badcheck++; |
| 669 | − return slhc_toss( comp ); | |
| 676 | + return slhc_toss(comp); | |
| 670 | 677 | } |
| 671 | − if(index > comp->rslot_limit) { | |
| 678 | + if (index > comp->rslot_limit) { | |
| 672 | 679 | comp->sls_i_error++; |
| 673 | 680 | return slhc_toss(comp); |
| 674 | 681 | } |
| 675 | − | |
| 682 | + th = (struct tcphdr *)(icp + ihl * 4); | |
| 683 | + if (th->doff < sizeof(struct tcphdr) / 4) | |
| 684 | + goto runt; | |
| 685 | + if (isize < ihl * 4 + th->doff * 4) | |
| 686 | + goto runt; | |
| 676 | 687 | /* Update local state */ |
| 677 | 688 | cs = &comp->rstate[comp->recv_current = index]; |
| 678 | 689 | comp->flags &=~ SLF_TOSS; |
| 679 | − memcpy(&cs->cs_ip,icp,20); | |
| 680 | − memcpy(&cs->cs_tcp,icp + ihl*4,20); | |
| 690 | + memcpy(&cs->cs_ip, iph, sizeof(*iph)); | |
| 691 | + memcpy(&cs->cs_tcp, th, sizeof(*th)); | |
| 681 | 692 | if (ihl > 5) |
| 682 | − memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); | |
| 683 | − if (cs->cs_tcp.doff > 5) | |
| 684 | − memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); | |
| 685 | − cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; | |
| 693 | + memcpy(cs->cs_ipopt, &iph[1], (ihl - 5) * 4); | |
| 694 | + if (th->doff > 5) | |
| 695 | + memcpy(cs->cs_tcpopt, &th[1], (th->doff - 5) * 4); | |
| 696 | + cs->cs_hsize = ihl*2 + th->doff*2; | |
| 686 | 697 | cs->initialized = true; |
| 687 | 698 | /* Put headers back on packet |
| 688 | 699 | * Neither header checksum is recalculated |
| @@ -1426,6 +1426,7 @@ static const struct usb_device_id products[] = { · 1425 unmodified lines | ||
| 1426 | 1426 | {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ |
| 1427 | 1427 | {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ |
| 1428 | 1428 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ |
| 1429 | + {QMI_QUIRK_SET_DTR(0x2cb7, 0x0112, 0)}, /* Fibocom FG132 */ | |
| 1429 | 1430 | {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ |
| 1430 | 1431 | {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ |
| 1431 | 1432 | {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ |
| @@ -1767,7 +1767,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) · 1766 unmodified lines | ||
| 1767 | 1767 | // can rename the link if it knows better. |
| 1768 | 1768 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && |
| 1769 | 1769 | ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || |
| 1770 | − (net->dev_addr [0] & 0x02) == 0)) | |
| 1770 | + /* somebody touched it*/ | |
| 1771 | + !is_zero_ether_addr(net->dev_addr))) | |
| 1771 | 1772 | strscpy(net->name, "eth%d", sizeof(net->name)); |
| 1772 | 1773 | /* WLAN devices should always be named "wlan%d" */ |
| 1773 | 1774 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) |
| @@ -1870,6 +1871,7 @@ out1: · 96 unmodified lines | ||
| 1870 | 1871 | * may trigger an error resubmitting itself and, worse, |
| 1871 | 1872 | * schedule a timer. So we kill it all just in case. |
| 1872 | 1873 | */ |
| 1874 | + usbnet_mark_going_away(dev); | |
| 1873 | 1875 | cancel_work_sync(&dev->kevent); |
| 1874 | 1876 | del_timer_sync(&dev->delay); |
| 1875 | 1877 | free_netdev(net); |
| @@ -4155,7 +4155,7 @@ struct virtnet_stats_ctx { · 4154 unmodified lines | ||
| 4155 | 4155 | u32 desc_num[3]; |
| 4156 | 4156 | |
| 4157 | 4157 | /* The actual supported stat types. */ |
| 4158 | − u32 bitmap[3]; | |
| 4158 | + u64 bitmap[3]; | |
| 4159 | 4159 | |
| 4160 | 4160 | /* Used to calculate the reply buffer size. */ |
| 4161 | 4161 | u32 size[3]; |
| @@ -148,7 +148,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, · 147 unmodified lines | ||
| 148 | 148 | } else { /* XDP buffer from page pool */ |
| 149 | 149 | page = virt_to_page(xdpf->data); |
| 150 | 150 | tbi->dma_addr = page_pool_get_dma_addr(page) + |
| 151 | − VMXNET3_XDP_HEADROOM; | |
| 151 | + (xdpf->data - (void *)xdpf); | |
| 152 | 152 | dma_sync_single_for_device(&adapter->pdev->dev, |
| 153 | 153 | tbi->dma_addr, buf_size, |
| 154 | 154 | DMA_TO_DEVICE); |
| @@ -4913,9 +4913,13 @@ static int __init vxlan_init_module(void) · 4912 unmodified lines | ||
| 4913 | 4913 | if (rc) |
| 4914 | 4914 | goto out4; |
| 4915 | 4915 | |
| 4916 | − vxlan_vnifilter_init(); | |
| 4916 | + rc = vxlan_vnifilter_init(); | |
| 4917 | + if (rc) | |
| 4918 | + goto out5; | |
| 4917 | 4919 | |
| 4918 | 4920 | return 0; |
| 4921 | +out5: | |
| 4922 | + rtnl_link_unregister(&vxlan_link_ops); | |
| 4919 | 4923 | out4: |
| 4920 | 4924 | unregister_switchdev_notifier(&vxlan_switchdev_notifier_block); |
| 4921 | 4925 | out3: |
| @@ -202,7 +202,7 @@ int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan, · 201 unmodified lines | ||
| 202 | 202 | int vxlan_vnigroup_init(struct vxlan_dev *vxlan); |
| 203 | 203 | void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan); |
| 204 | 204 | |
| 205 | −void vxlan_vnifilter_init(void); | |
| 205 | +int vxlan_vnifilter_init(void); | |
| 206 | 206 | void vxlan_vnifilter_uninit(void); |
| 207 | 207 | void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni, |
| 208 | 208 | struct vxlan_vni_node *vninode, |
| @@ -992,19 +992,18 @@ static int vxlan_vnifilter_process(struct sk_buff *skb, struct nlmsghdr *nlh, · 991 unmodified lines | ||
| 992 | 992 | return err; |
| 993 | 993 | } |
| 994 | 994 | |
| 995 | −void vxlan_vnifilter_init(void) | |
| 995 | +static const struct rtnl_msg_handler vxlan_vnifilter_rtnl_msg_handlers[] = { | |
| 996 | + {THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL, vxlan_vnifilter_dump, 0}, | |
| 997 | + {THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL, vxlan_vnifilter_process, NULL, 0}, | |
| 998 | + {THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL, vxlan_vnifilter_process, NULL, 0}, | |
| 999 | +}; | |
| 1000 | + | |
| 1001 | +int vxlan_vnifilter_init(void) | |
| 996 | 1002 | { |
| 997 | − rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL, | |
| 998 | − vxlan_vnifilter_dump, 0); | |
| 999 | − rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL, | |
| 1000 | − vxlan_vnifilter_process, NULL, 0); | |
| 1001 | − rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL, | |
| 1002 | − vxlan_vnifilter_process, NULL, 0); | |
| 1003 | + return rtnl_register_many(vxlan_vnifilter_rtnl_msg_handlers); | |
| 1003 | 1004 | } |
| 1004 | 1005 | |
| 1005 | 1006 | void vxlan_vnifilter_uninit(void) |
| 1006 | 1007 | { |
| 1007 | − rtnl_unregister(PF_BRIDGE, RTM_GETTUNNEL); | |
| 1008 | − rtnl_unregister(PF_BRIDGE, RTM_NEWTUNNEL); | |
| 1009 | − rtnl_unregister(PF_BRIDGE, RTM_DELTUNNEL); | |
| 1008 | + rtnl_unregister_many(vxlan_vnifilter_rtnl_msg_handlers); | |
| 1010 | 1009 | } |
| @@ -1038,7 +1038,7 @@ static const struct nla_policy wwan_rtnl_policy[IFLA_WWAN_MAX + 1] = { · 1037 unmodified lines | ||
| 1038 | 1038 | |
| 1039 | 1039 | static struct rtnl_link_ops wwan_rtnl_link_ops __read_mostly = { |
| 1040 | 1040 | .kind = "wwan", |
| 1041 | − .maxtype = __IFLA_WWAN_MAX, | |
| 1041 | + .maxtype = IFLA_WWAN_MAX, | |
| 1042 | 1042 | .alloc = wwan_rtnl_alloc, |
| 1043 | 1043 | .validate = wwan_rtnl_validate, |
| 1044 | 1044 | .newlink = wwan_rtnl_newlink, |
| @@ -1292,14 +1292,12 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl) · 1291 unmodified lines | ||
| 1292 | 1292 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); |
| 1293 | 1293 | } |
| 1294 | 1294 | |
| 1295 | −static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq, | |
| 1296 | − blk_status_t status) | |
| 1295 | +static void nvme_keep_alive_finish(struct request *rq, | |
| 1296 | + blk_status_t status, struct nvme_ctrl *ctrl) | |
| 1297 | 1297 | { |
| 1298 | − struct nvme_ctrl *ctrl = rq->end_io_data; | |
| 1299 | − unsigned long flags; | |
| 1300 | − bool startka = false; | |
| 1301 | 1298 | unsigned long rtt = jiffies - (rq->deadline - rq->timeout); |
| 1302 | 1299 | unsigned long delay = nvme_keep_alive_work_period(ctrl); |
| 1300 | + enum nvme_ctrl_state state = nvme_ctrl_state(ctrl); | |
| 1303 | 1301 | |
| 1304 | 1302 | /* |
| 1305 | 1303 | * Subtract off the keepalive RTT so nvme_keep_alive_work runs |
| @@ -1313,25 +1311,17 @@ static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq, · 7 unmodified lines | ||
| 1313 | 1311 | delay = 0; |
| 1314 | 1312 | } |
| 1315 | 1313 | |
| 1316 | − blk_mq_free_request(rq); | |
| 1317 | − | |
| 1318 | 1314 | if (status) { |
| 1319 | 1315 | dev_err(ctrl->device, |
| 1320 | 1316 | "failed nvme_keep_alive_end_io error=%d\n", |
| 1321 | 1317 | status); |
| 1322 | − return RQ_END_IO_NONE; | |
| 1318 | + return; | |
| 1323 | 1319 | } |
| 1324 | 1320 | |
| 1325 | 1321 | ctrl->ka_last_check_time = jiffies; |
| 1326 | 1322 | ctrl->comp_seen = false; |
| 1327 | − spin_lock_irqsave(&ctrl->lock, flags); | |
| 1328 | − if (ctrl->state == NVME_CTRL_LIVE || | |
| 1329 | − ctrl->state == NVME_CTRL_CONNECTING) | |
| 1330 | − startka = true; | |
| 1331 | − spin_unlock_irqrestore(&ctrl->lock, flags); | |
| 1332 | − if (startka) | |
| 1323 | + if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING) | |
| 1333 | 1324 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); |
| 1334 | − return RQ_END_IO_NONE; | |
| 1335 | 1325 | } |
| 1336 | 1326 | |
| 1337 | 1327 | static void nvme_keep_alive_work(struct work_struct *work) |
| @@ -1340,6 +1330,7 @@ static void nvme_keep_alive_work(struct work_struct *work) · 2 unmodified lines | ||
| 1340 | 1330 | struct nvme_ctrl, ka_work); |
| 1341 | 1331 | bool comp_seen = ctrl->comp_seen; |
| 1342 | 1332 | struct request *rq; |
| 1333 | + blk_status_t status; | |
| 1343 | 1334 | |
| 1344 | 1335 | ctrl->ka_last_check_time = jiffies; |
| 1345 | 1336 | |
| @@ -1362,9 +1353,9 @@ static void nvme_keep_alive_work(struct work_struct *work) · 16 unmodified lines | ||
| 1362 | 1353 | nvme_init_request(rq, &ctrl->ka_cmd); |
| 1363 | 1354 | |
| 1364 | 1355 | rq->timeout = ctrl->kato * HZ; |
| 1365 | − rq->end_io = nvme_keep_alive_end_io; | |
| 1366 | − rq->end_io_data = ctrl; | |
| 1367 | − blk_execute_rq_nowait(rq, false); | |
| 1356 | + status = blk_execute_rq(rq, false); | |
| 1357 | + nvme_keep_alive_finish(rq, status, ctrl); | |
| 1358 | + blk_mq_free_request(rq); | |
| 1368 | 1359 | } |
| 1369 | 1360 | |
| 1370 | 1361 | static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) |
| @@ -2458,8 +2449,13 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) · 1087 unmodified lines | ||
| 2458 | 2449 | else |
| 2459 | 2450 | ctrl->ctrl_config = NVME_CC_CSS_NVM; |
| 2460 | 2451 | |
| 2461 | − if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS) | |
| 2462 | − ctrl->ctrl_config |= NVME_CC_CRIME; | |
| 2452 | + /* | |
| 2453 | + * Setting CRIME results in CSTS.RDY before the media is ready. This | |
| 2454 | + * makes it possible for media related commands to return the error | |
| 2455 | + * NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY. Until the driver is | |
| 2456 | + * restructured to handle retries, disable CC.CRIME. | |
| 2457 | + */ | |
| 2458 | + ctrl->ctrl_config &= ~NVME_CC_CRIME; | |
| 2463 | 2459 | |
| 2464 | 2460 | ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; |
| 2465 | 2461 | ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; |
| @@ -2489,10 +2485,7 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) · 23 unmodified lines | ||
| 2489 | 2485 | * devices are known to get this wrong. Use the larger of the |
| 2490 | 2486 | * two values. |
| 2491 | 2487 | */ |
| 2492 | − if (ctrl->ctrl_config & NVME_CC_CRIME) | |
| 2493 | − ready_timeout = NVME_CRTO_CRIMT(crto); | |
| 2494 | − else | |
| 2495 | − ready_timeout = NVME_CRTO_CRWMT(crto); | |
| 2488 | + ready_timeout = NVME_CRTO_CRWMT(crto); | |
| 2496 | 2489 | |
| 2497 | 2490 | if (ready_timeout < timeout) |
| 2498 | 2491 | dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n", |
| @@ -431,7 +431,6 @@ static bool nvme_available_path(struct nvme_ns_head *head) · 430 unmodified lines | ||
| 431 | 431 | case NVME_CTRL_LIVE: |
| 432 | 432 | case NVME_CTRL_RESETTING: |
| 433 | 433 | case NVME_CTRL_CONNECTING: |
| 434 | − /* fallthru */ | |
| 435 | 434 | return true; |
| 436 | 435 | default: |
| 437 | 436 | break; |
| @@ -580,6 +579,20 @@ static int nvme_add_ns_head_cdev(struct nvme_ns_head *head) · 142 unmodified lines | ||
| 580 | 579 | return ret; |
| 581 | 580 | } |
| 582 | 581 | |
| 582 | +static void nvme_partition_scan_work(struct work_struct *work) | |
| 583 | +{ | |
| 584 | + struct nvme_ns_head *head = | |
| 585 | + container_of(work, struct nvme_ns_head, partition_scan_work); | |
| 586 | + | |
| 587 | + if (WARN_ON_ONCE(!test_and_clear_bit(GD_SUPPRESS_PART_SCAN, | |
| 588 | + &head->disk->state))) | |
| 589 | + return; | |
| 590 | + | |
| 591 | + mutex_lock(&head->disk->open_mutex); | |
| 592 | + bdev_disk_changed(head->disk, false); | |
| 593 | + mutex_unlock(&head->disk->open_mutex); | |
| 594 | +} | |
| 595 | + | |
| 583 | 596 | static void nvme_requeue_work(struct work_struct *work) |
| 584 | 597 | { |
| 585 | 598 | struct nvme_ns_head *head = |
| @@ -606,6 +619,7 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head) · 20 unmodified lines | ||
| 606 | 619 | bio_list_init(&head->requeue_list); |
| 607 | 620 | spin_lock_init(&head->requeue_lock); |
| 608 | 621 | INIT_WORK(&head->requeue_work, nvme_requeue_work); |
| 622 | + INIT_WORK(&head->partition_scan_work, nvme_partition_scan_work); | |
| 609 | 623 | |
| 610 | 624 | /* |
| 611 | 625 | * Add a multipath node if the subsystems supports multiple controllers. |
| @@ -629,6 +643,16 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head) · 17 unmodified lines | ||
| 629 | 643 | return PTR_ERR(head->disk); |
| 630 | 644 | head->disk->fops = &nvme_ns_head_ops; |
| 631 | 645 | head->disk->private_data = head; |
| 646 | + | |
| 647 | + /* | |
| 648 | + * We need to suppress the partition scan from occuring within the | |
| 649 | + * controller's scan_work context. If a path error occurs here, the IO | |
| 650 | + * will wait until a path becomes available or all paths are torn down, | |
| 651 | + * but that action also occurs within scan_work, so it would deadlock. | |
| 652 | + * Defer the partion scan to a different context that does not block | |
| 653 | + * scan_work. | |
| 654 | + */ | |
| 655 | + set_bit(GD_SUPPRESS_PART_SCAN, &head->disk->state); | |
| 632 | 656 | sprintf(head->disk->disk_name, "nvme%dn%d", |
| 633 | 657 | ctrl->subsys->instance, head->instance); |
| 634 | 658 | return 0; |
| @@ -655,6 +679,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) · 20 unmodified lines | ||
| 655 | 679 | return; |
| 656 | 680 | } |
| 657 | 681 | nvme_add_ns_head_cdev(head); |
| 682 | + kblockd_schedule_work(&head->partition_scan_work); | |
| 658 | 683 | } |
| 659 | 684 | |
| 660 | 685 | mutex_lock(&head->lock); |
| @@ -974,14 +999,14 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head) · 313 unmodified lines | ||
| 974 | 999 | return; |
| 975 | 1000 | if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { |
| 976 | 1001 | nvme_cdev_del(&head->cdev, &head->cdev_device); |
| 1002 | + /* | |
| 1003 | + * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared | |
| 1004 | + * to allow multipath to fail all I/O. | |
| 1005 | + */ | |
| 1006 | + synchronize_srcu(&head->srcu); | |
| 1007 | + kblockd_schedule_work(&head->requeue_work); | |
| 977 | 1008 | del_gendisk(head->disk); |
| 978 | 1009 | } |
| 979 | − /* | |
| 980 | − * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared | |
| 981 | − * to allow multipath to fail all I/O. | |
| 982 | − */ | |
| 983 | − synchronize_srcu(&head->srcu); | |
| 984 | − kblockd_schedule_work(&head->requeue_work); | |
| 985 | 1010 | } |
| 986 | 1011 | |
| 987 | 1012 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) |
| @@ -991,6 +1016,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) · 3 unmodified lines | ||
| 991 | 1016 | /* make sure all pending bios are cleaned up */ |
| 992 | 1017 | kblockd_schedule_work(&head->requeue_work); |
| 993 | 1018 | flush_work(&head->requeue_work); |
| 1019 | + flush_work(&head->partition_scan_work); | |
| 994 | 1020 | put_disk(head->disk); |
| 995 | 1021 | } |
| 996 | 1022 | |
| @@ -494,6 +494,7 @@ struct nvme_ns_head { · 493 unmodified lines | ||
| 494 | 494 | struct bio_list requeue_list; |
| 495 | 495 | spinlock_t requeue_lock; |
| 496 | 496 | struct work_struct requeue_work; |
| 497 | + struct work_struct partition_scan_work; | |
| 497 | 498 | struct mutex lock; |
| 498 | 499 | unsigned long flags; |
| 499 | 500 | #define NVME_NSHEAD_DISK_LIVE 0 |
| @@ -2506,17 +2506,29 @@ static unsigned int nvme_pci_nr_maps(struct nvme_dev *dev) · 2505 unmodified lines | ||
| 2506 | 2506 | return 1; |
| 2507 | 2507 | } |
| 2508 | 2508 | |
| 2509 | −static void nvme_pci_update_nr_queues(struct nvme_dev *dev) | |
| 2509 | +static bool nvme_pci_update_nr_queues(struct nvme_dev *dev) | |
| 2510 | 2510 | { |
| 2511 | 2511 | if (!dev->ctrl.tagset) { |
| 2512 | 2512 | nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, |
| 2513 | 2513 | nvme_pci_nr_maps(dev), sizeof(struct nvme_iod)); |
| 2514 | − return; | |
| 2514 | + return true; | |
| 2515 | + } | |
| 2516 | + | |
| 2517 | + /* Give up if we are racing with nvme_dev_disable() */ | |
| 2518 | + if (!mutex_trylock(&dev->shutdown_lock)) | |
| 2519 | + return false; | |
| 2520 | + | |
| 2521 | + /* Check if nvme_dev_disable() has been executed already */ | |
| 2522 | + if (!dev->online_queues) { | |
| 2523 | + mutex_unlock(&dev->shutdown_lock); | |
| 2524 | + return false; | |
| 2515 | 2525 | } |
| 2516 | 2526 | |
| 2517 | 2527 | blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); |
| 2518 | 2528 | /* free previously allocated queues that are no longer usable */ |
| 2519 | 2529 | nvme_free_queues(dev, dev->online_queues); |
| 2530 | + mutex_unlock(&dev->shutdown_lock); | |
| 2531 | + return true; | |
| 2520 | 2532 | } |
| 2521 | 2533 | |
| 2522 | 2534 | static int nvme_pci_enable(struct nvme_dev *dev) |
| @@ -2797,7 +2809,8 @@ static void nvme_reset_work(struct work_struct *work) · 274 unmodified lines | ||
| 2797 | 2809 | nvme_dbbuf_set(dev); |
| 2798 | 2810 | nvme_unquiesce_io_queues(&dev->ctrl); |
| 2799 | 2811 | nvme_wait_freeze(&dev->ctrl); |
| 2800 | − nvme_pci_update_nr_queues(dev); | |
| 2812 | + if (!nvme_pci_update_nr_queues(dev)) | |
| 2813 | + goto out; | |
| 2801 | 2814 | nvme_unfreeze(&dev->ctrl); |
| 2802 | 2815 | } else { |
| 2803 | 2816 | dev_warn(dev->ctrl.device, "IO queues lost\n"); |
| @@ -2644,10 +2644,11 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size) · 2643 unmodified lines | ||
| 2644 | 2644 | |
| 2645 | 2645 | len = nvmf_get_address(ctrl, buf, size); |
| 2646 | 2646 | |
| 2647 | + if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags)) | |
| 2648 | + return len; | |
| 2649 | + | |
| 2647 | 2650 | mutex_lock(&queue->queue_lock); |
| 2648 | 2651 | |
| 2649 | − if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags)) | |
| 2650 | − goto done; | |
| 2651 | 2652 | ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr); |
| 2652 | 2653 | if (ret > 0) { |
| 2653 | 2654 | if (len > 0) |
| @@ -2655,7 +2656,7 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size) · 1 unmodified line | ||
| 2655 | 2656 | len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n", |
| 2656 | 2657 | (len) ? "," : "", &src_addr); |
| 2657 | 2658 | } |
| 2658 | −done: | |
| 2659 | + | |
| 2659 | 2660 | mutex_unlock(&queue->queue_lock); |
| 2660 | 2661 | |
| 2661 | 2662 | return len; |
| @@ -265,6 +265,13 @@ static void nvme_loop_destroy_admin_queue(struct nvme_loop_ctrl *ctrl) · 264 unmodified lines | ||
| 265 | 265 | { |
| 266 | 266 | if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags)) |
| 267 | 267 | return; |
| 268 | + /* | |
| 269 | + * It's possible that some requests might have been added | |
| 270 | + * after admin queue is stopped/quiesced. So now start the | |
| 271 | + * queue to flush these requests to the completion. | |
| 272 | + */ | |
| 273 | + nvme_unquiesce_admin_queue(&ctrl->ctrl); | |
| 274 | + | |
| 268 | 275 | nvmet_sq_destroy(&ctrl->queues[0].nvme_sq); |
| 269 | 276 | nvme_remove_admin_tag_set(&ctrl->ctrl); |
| 270 | 277 | } |
| @@ -297,6 +304,12 @@ static void nvme_loop_destroy_io_queues(struct nvme_loop_ctrl *ctrl) · 26 unmodified lines | ||
| 297 | 304 | nvmet_sq_destroy(&ctrl->queues[i].nvme_sq); |
| 298 | 305 | } |
| 299 | 306 | ctrl->ctrl.queue_count = 1; |
| 307 | + /* | |
| 308 | + * It's possible that some requests might have been added | |
| 309 | + * after io queue is stopped/quiesced. So now start the | |
| 310 | + * queue to flush these requests to the completion. | |
| 311 | + */ | |
| 312 | + nvme_unquiesce_io_queues(&ctrl->ctrl); | |
| 300 | 313 | } |
| 301 | 314 | |
| 302 | 315 | static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl) |
| @@ -535,10 +535,6 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) · 534 unmodified lines | ||
| 535 | 535 | break; |
| 536 | 536 | case nvme_admin_identify: |
| 537 | 537 | switch (req->cmd->identify.cns) { |
| 538 | − case NVME_ID_CNS_CTRL: | |
| 539 | − req->execute = nvmet_passthru_execute_cmd; | |
| 540 | − req->p.use_workqueue = true; | |
| 541 | − return NVME_SC_SUCCESS; | |
| 542 | 538 | case NVME_ID_CNS_CS_CTRL: |
| 543 | 539 | switch (req->cmd->identify.csi) { |
| 544 | 540 | case NVME_CSI_ZNS: |
| @@ -547,7 +543,9 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) · 2 unmodified lines | ||
| 547 | 543 | return NVME_SC_SUCCESS; |
| 548 | 544 | } |
| 549 | 545 | return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; |
| 546 | + case NVME_ID_CNS_CTRL: | |
| 550 | 547 | case NVME_ID_CNS_NS: |
| 548 | + case NVME_ID_CNS_NS_DESC_LIST: | |
| 551 | 549 | req->execute = nvmet_passthru_execute_cmd; |
| 552 | 550 | req->p.use_workqueue = true; |
| 553 | 551 | return NVME_SC_SUCCESS; |
| @@ -39,6 +39,8 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define NVMET_RDMA_BACKLOG 128 |
| 41 | 41 | |
| 42 | +#define NVMET_RDMA_DISCRETE_RSP_TAG -1 | |
| 43 | + | |
| 42 | 44 | struct nvmet_rdma_srq; |
| 43 | 45 | |
| 44 | 46 | struct nvmet_rdma_cmd { |
| @@ -75,7 +77,7 @@ struct nvmet_rdma_rsp { · 30 unmodified lines | ||
| 75 | 77 | u32 invalidate_rkey; |
| 76 | 78 | |
| 77 | 79 | struct list_head wait_list; |
| 78 | − struct list_head free_list; | |
| 80 | + int tag; | |
| 79 | 81 | }; |
| 80 | 82 | |
| 81 | 83 | enum nvmet_rdma_queue_state { |
| @@ -98,8 +100,7 @@ struct nvmet_rdma_queue { · 16 unmodified lines | ||
| 98 | 100 | struct nvmet_sq nvme_sq; |
| 99 | 101 | |
| 100 | 102 | struct nvmet_rdma_rsp *rsps; |
| 101 | − struct list_head free_rsps; | |
| 102 | − spinlock_t rsps_lock; | |
| 103 | + struct sbitmap rsp_tags; | |
| 103 | 104 | struct nvmet_rdma_cmd *cmds; |
| 104 | 105 | |
| 105 | 106 | struct work_struct release_work; |
| @@ -172,7 +173,8 @@ static void nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue); · 66 unmodified lines | ||
| 172 | 173 | static void nvmet_rdma_free_rsp(struct nvmet_rdma_device *ndev, |
| 173 | 174 | struct nvmet_rdma_rsp *r); |
| 174 | 175 | static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, |
| 175 | − struct nvmet_rdma_rsp *r); | |
| 176 | + struct nvmet_rdma_rsp *r, | |
| 177 | + int tag); | |
| 176 | 178 | |
| 177 | 179 | static const struct nvmet_fabrics_ops nvmet_rdma_ops; |
| 178 | 180 | |
| @@ -210,15 +212,12 @@ static inline bool nvmet_rdma_need_data_out(struct nvmet_rdma_rsp *rsp) · 31 unmodified lines | ||
| 210 | 212 | static inline struct nvmet_rdma_rsp * |
| 211 | 213 | nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) |
| 212 | 214 | { |
| 213 | − struct nvmet_rdma_rsp *rsp; | |
| 214 | − unsigned long flags; | |
| 215 | + struct nvmet_rdma_rsp *rsp = NULL; | |
| 216 | + int tag; | |
| 215 | 217 | |
| 216 | − spin_lock_irqsave(&queue->rsps_lock, flags); | |
| 217 | − rsp = list_first_entry_or_null(&queue->free_rsps, | |
| 218 | − struct nvmet_rdma_rsp, free_list); | |
| 219 | − if (likely(rsp)) | |
| 220 | − list_del(&rsp->free_list); | |
| 221 | − spin_unlock_irqrestore(&queue->rsps_lock, flags); | |
| 218 | + tag = sbitmap_get(&queue->rsp_tags); | |
| 219 | + if (tag >= 0) | |
| 220 | + rsp = &queue->rsps[tag]; | |
| 222 | 221 | |
| 223 | 222 | if (unlikely(!rsp)) { |
| 224 | 223 | int ret; |
| @@ -226,13 +225,12 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) · 1 unmodified line | ||
| 226 | 225 | rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); |
| 227 | 226 | if (unlikely(!rsp)) |
| 228 | 227 | return NULL; |
| 229 | − ret = nvmet_rdma_alloc_rsp(queue->dev, rsp); | |
| 228 | + ret = nvmet_rdma_alloc_rsp(queue->dev, rsp, | |
| 229 | + NVMET_RDMA_DISCRETE_RSP_TAG); | |
| 230 | 230 | if (unlikely(ret)) { |
| 231 | 231 | kfree(rsp); |
| 232 | 232 | return NULL; |
| 233 | 233 | } |
| 234 | − | |
| 235 | − rsp->allocated = true; | |
| 236 | 234 | } |
| 237 | 235 | |
| 238 | 236 | return rsp; |
| @@ -241,17 +239,13 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) · 2 unmodified lines | ||
| 241 | 239 | static inline void |
| 242 | 240 | nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp) |
| 243 | 241 | { |
| 244 | − unsigned long flags; | |
| 245 | − | |
| 246 | − if (unlikely(rsp->allocated)) { | |
| 242 | + if (unlikely(rsp->tag == NVMET_RDMA_DISCRETE_RSP_TAG)) { | |
| 247 | 243 | nvmet_rdma_free_rsp(rsp->queue->dev, rsp); |
| 248 | 244 | kfree(rsp); |
| 249 | 245 | return; |
| 250 | 246 | } |
| 251 | 247 | |
| 252 | − spin_lock_irqsave(&rsp->queue->rsps_lock, flags); | |
| 253 | − list_add_tail(&rsp->free_list, &rsp->queue->free_rsps); | |
| 254 | − spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags); | |
| 248 | + sbitmap_clear_bit(&rsp->queue->rsp_tags, rsp->tag); | |
| 255 | 249 | } |
| 256 | 250 | |
| 257 | 251 | static void nvmet_rdma_free_inline_pages(struct nvmet_rdma_device *ndev, |
| @@ -404,7 +398,7 @@ static void nvmet_rdma_free_cmds(struct nvmet_rdma_device *ndev, · 146 unmodified lines | ||
| 404 | 398 | } |
| 405 | 399 | |
| 406 | 400 | static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, |
| 407 | − struct nvmet_rdma_rsp *r) | |
| 401 | + struct nvmet_rdma_rsp *r, int tag) | |
| 408 | 402 | { |
| 409 | 403 | /* NVMe CQE / RDMA SEND */ |
| 410 | 404 | r->req.cqe = kmalloc(sizeof(*r->req.cqe), GFP_KERNEL); |
| @@ -432,6 +426,7 @@ static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, · 21 unmodified lines | ||
| 432 | 426 | r->read_cqe.done = nvmet_rdma_read_data_done; |
| 433 | 427 | /* Data Out / RDMA WRITE */ |
| 434 | 428 | r->write_cqe.done = nvmet_rdma_write_data_done; |
| 429 | + r->tag = tag; | |
| 435 | 430 | |
| 436 | 431 | return 0; |
| 437 | 432 | |
| @@ -454,21 +449,23 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue) · 16 unmodified lines | ||
| 454 | 449 | { |
| 455 | 450 | struct nvmet_rdma_device *ndev = queue->dev; |
| 456 | 451 | int nr_rsps = queue->recv_queue_size * 2; |
| 457 | − int ret = -EINVAL, i; | |
| 452 | + int ret = -ENOMEM, i; | |
| 453 | + | |
| 454 | + if (sbitmap_init_node(&queue->rsp_tags, nr_rsps, -1, GFP_KERNEL, | |
| 455 | + NUMA_NO_NODE, false, true)) | |
| 456 | + goto out; | |
| 458 | 457 | |
| 459 | 458 | queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), |
| 460 | 459 | GFP_KERNEL); |
| 461 | 460 | if (!queue->rsps) |
| 462 | − goto out; | |
| 461 | + goto out_free_sbitmap; | |
| 463 | 462 | |
| 464 | 463 | for (i = 0; i < nr_rsps; i++) { |
| 465 | 464 | struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; |
| 466 | 465 | |
| 467 | − ret = nvmet_rdma_alloc_rsp(ndev, rsp); | |
| 466 | + ret = nvmet_rdma_alloc_rsp(ndev, rsp, i); | |
| 468 | 467 | if (ret) |
| 469 | 468 | goto out_free; |
| 470 | − | |
| 471 | − list_add_tail(&rsp->free_list, &queue->free_rsps); | |
| 472 | 469 | } |
| 473 | 470 | |
| 474 | 471 | return 0; |
| @@ -477,6 +474,8 @@ out_free: · 2 unmodified lines | ||
| 477 | 474 | while (--i >= 0) |
| 478 | 475 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); |
| 479 | 476 | kfree(queue->rsps); |
| 477 | +out_free_sbitmap: | |
| 478 | + sbitmap_free(&queue->rsp_tags); | |
| 480 | 479 | out: |
| 481 | 480 | return ret; |
| 482 | 481 | } |
| @@ -489,6 +488,7 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue) · 6 unmodified lines | ||
| 489 | 488 | for (i = 0; i < nr_rsps; i++) |
| 490 | 489 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); |
| 491 | 490 | kfree(queue->rsps); |
| 491 | + sbitmap_free(&queue->rsp_tags); | |
| 492 | 492 | } |
| 493 | 493 | |
| 494 | 494 | static int nvmet_rdma_post_recv(struct nvmet_rdma_device *ndev, |
| @@ -1447,8 +1447,6 @@ nvmet_rdma_alloc_queue(struct nvmet_rdma_device *ndev, · 952 unmodified lines | ||
| 1447 | 1447 | INIT_LIST_HEAD(&queue->rsp_wait_list); |
| 1448 | 1448 | INIT_LIST_HEAD(&queue->rsp_wr_wait_list); |
| 1449 | 1449 | spin_lock_init(&queue->rsp_wr_wait_lock); |
| 1450 | − INIT_LIST_HEAD(&queue->free_rsps); | |
| 1451 | − spin_lock_init(&queue->rsps_lock); | |
| 1452 | 1450 | INIT_LIST_HEAD(&queue->queue_list); |
| 1453 | 1451 | |
| 1454 | 1452 | queue->idx = ida_alloc(&nvmet_rdma_queue_ida, GFP_KERNEL); |
| @@ -10,6 +10,19 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <kunit/test.h> |
| 11 | 11 | #include <kunit/resource.h> |
| 12 | 12 | |
| 13 | +#include "of_private.h" | |
| 14 | + | |
| 15 | +/** | |
| 16 | + * of_root_kunit_skip() - Skip test if the root node isn't populated | |
| 17 | + * @test: test to skip if the root node isn't populated | |
| 18 | + */ | |
| 19 | +void of_root_kunit_skip(struct kunit *test) | |
| 20 | +{ | |
| 21 | + if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ACPI) && !of_root) | |
| 22 | + kunit_skip(test, "arm64+acpi doesn't populate a root node"); | |
| 23 | +} | |
| 24 | +EXPORT_SYMBOL_GPL(of_root_kunit_skip); | |
| 25 | + | |
| 13 | 26 | #if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE) |
| 14 | 27 | |
| 15 | 28 | static void of_overlay_fdt_apply_kunit_exit(void *ovcs_id) |
| @@ -36,6 +49,8 @@ int of_overlay_fdt_apply_kunit(struct kunit *test, void *overlay_fdt, · 20 unmodified lines | ||
| 36 | 49 | int ret; |
| 37 | 50 | int *copy_id; |
| 38 | 51 | |
| 52 | + of_root_kunit_skip(test); | |
| 53 | + | |
| 39 | 54 | copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL); |
| 40 | 55 | if (!copy_id) |
| 41 | 56 | return -ENOMEM; |
| @@ -42,6 +42,9 @@ extern raw_spinlock_t devtree_lock; · 41 unmodified lines | ||
| 42 | 42 | extern struct list_head aliases_lookup; |
| 43 | 43 | extern struct kset *of_kset; |
| 44 | 44 | |
| 45 | +struct kunit; | |
| 46 | +extern void of_root_kunit_skip(struct kunit *test); | |
| 47 | + | |
| 45 | 48 | #if defined(CONFIG_OF_DYNAMIC) |
| 46 | 49 | extern int of_property_notify(int action, struct device_node *np, |
| 47 | 50 | struct property *prop, struct property *old_prop); |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <kunit/test.h> |
| 9 | 9 | |
| 10 | +#include "of_private.h" | |
| 11 | + | |
| 10 | 12 | /* |
| 11 | 13 | * Test that the root node "/" can be found by path. |
| 12 | 14 | */ |
| @@ -36,6 +38,7 @@ static struct kunit_case of_dtb_test_cases[] = { · 23 unmodified lines | ||
| 36 | 38 | |
| 37 | 39 | static int of_dtb_test_init(struct kunit *test) |
| 38 | 40 | { |
| 41 | + of_root_kunit_skip(test); | |
| 39 | 42 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) |
| 40 | 43 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE"); |
| 41 | 44 | |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <kunit/of.h> |
| 12 | 12 | #include <kunit/test.h> |
| 13 | 13 | |
| 14 | +#include "of_private.h" | |
| 15 | + | |
| 14 | 16 | static const char * const kunit_node_name = "kunit-test"; |
| 15 | 17 | static const char * const kunit_compatible = "test,empty"; |
| 16 | 18 | |
| @@ -62,6 +64,7 @@ static void of_overlay_apply_kunit_cleanup(struct kunit *test) · 45 unmodified lines | ||
| 62 | 64 | struct device *dev; |
| 63 | 65 | struct device_node *np; |
| 64 | 66 | |
| 67 | + of_root_kunit_skip(test); | |
| 65 | 68 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) |
| 66 | 69 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE for root node"); |
| 67 | 70 | |
| @@ -73,7 +76,7 @@ static void of_overlay_apply_kunit_cleanup(struct kunit *test) · 5 unmodified lines | ||
| 73 | 76 | |
| 74 | 77 | np = of_find_node_by_name(NULL, kunit_node_name); |
| 75 | 78 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np); |
| 76 | − of_node_put_kunit(test, np); | |
| 79 | + of_node_put_kunit(&fake, np); | |
| 77 | 80 | |
| 78 | 81 | pdev = of_find_device_by_node(np); |
| 79 | 82 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); |
| @@ -2630,8 +2630,10 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) · 2629 unmodified lines | ||
| 2630 | 2630 | |
| 2631 | 2631 | /* Attach genpds */ |
| 2632 | 2632 | if (config->genpd_names) { |
| 2633 | − if (config->required_devs) | |
| 2633 | + if (config->required_devs) { | |
| 2634 | + ret = -EINVAL; | |
| 2634 | 2635 | goto err; |
| 2636 | + } | |
| 2635 | 2637 | |
| 2636 | 2638 | ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, |
| 2637 | 2639 | config->virt_devs); |
| @@ -51,12 +51,12 @@ static int do_active_device(const struct ctl_table *table, int write, · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | for (dev = port->devices; dev ; dev = dev->next) { |
| 53 | 53 | if(dev == port->cad) { |
| 54 | − len += snprintf(buffer, sizeof(buffer), "%s\n", dev->name); | |
| 54 | + len += scnprintf(buffer, sizeof(buffer), "%s\n", dev->name); | |
| 55 | 55 | } |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | if(!len) { |
| 59 | − len += snprintf(buffer, sizeof(buffer), "%s\n", "none"); | |
| 59 | + len += scnprintf(buffer, sizeof(buffer), "%s\n", "none"); | |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | if (len > *lenp) |
| @@ -87,19 +87,19 @@ static int do_autoprobe(const struct ctl_table *table, int write, · 24 unmodified lines | ||
| 87 | 87 | } |
| 88 | 88 | |
| 89 | 89 | if ((str = info->class_name) != NULL) |
| 90 | − len += snprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); | |
| 90 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); | |
| 91 | 91 | |
| 92 | 92 | if ((str = info->model) != NULL) |
| 93 | − len += snprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); | |
| 93 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); | |
| 94 | 94 | |
| 95 | 95 | if ((str = info->mfr) != NULL) |
| 96 | − len += snprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); | |
| 96 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); | |
| 97 | 97 | |
| 98 | 98 | if ((str = info->description) != NULL) |
| 99 | − len += snprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); | |
| 99 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); | |
| 100 | 100 | |
| 101 | 101 | if ((str = info->cmdset) != NULL) |
| 102 | − len += snprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); | |
| 102 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); | |
| 103 | 103 | |
| 104 | 104 | if (len > *lenp) |
| 105 | 105 | len = *lenp; |
| @@ -128,7 +128,7 @@ static int do_hardware_base_addr(const struct ctl_table *table, int write, · 22 unmodified lines | ||
| 128 | 128 | if (write) /* permissions prevent this anyway */ |
| 129 | 129 | return -EACCES; |
| 130 | 130 | |
| 131 | − len += snprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); | |
| 131 | + len += scnprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); | |
| 132 | 132 | |
| 133 | 133 | if (len > *lenp) |
| 134 | 134 | len = *lenp; |
| @@ -155,7 +155,7 @@ static int do_hardware_irq(const struct ctl_table *table, int write, · 20 unmodified lines | ||
| 155 | 155 | if (write) /* permissions prevent this anyway */ |
| 156 | 156 | return -EACCES; |
| 157 | 157 | |
| 158 | − len += snprintf (buffer, sizeof(buffer), "%d\n", port->irq); | |
| 158 | + len += scnprintf (buffer, sizeof(buffer), "%d\n", port->irq); | |
| 159 | 159 | |
| 160 | 160 | if (len > *lenp) |
| 161 | 161 | len = *lenp; |
| @@ -182,7 +182,7 @@ static int do_hardware_dma(const struct ctl_table *table, int write, · 20 unmodified lines | ||
| 182 | 182 | if (write) /* permissions prevent this anyway */ |
| 183 | 183 | return -EACCES; |
| 184 | 184 | |
| 185 | − len += snprintf (buffer, sizeof(buffer), "%d\n", port->dma); | |
| 185 | + len += scnprintf (buffer, sizeof(buffer), "%d\n", port->dma); | |
| 186 | 186 | |
| 187 | 187 | if (len > *lenp) |
| 188 | 188 | len = *lenp; |
| @@ -213,7 +213,7 @@ static int do_hardware_modes(const struct ctl_table *table, int write, · 24 unmodified lines | ||
| 213 | 213 | #define printmode(x) \ |
| 214 | 214 | do { \ |
| 215 | 215 | if (port->modes & PARPORT_MODE_##x) \ |
| 216 | − len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ | |
| 216 | + len += scnprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ | |
| 217 | 217 | } while (0) |
| 218 | 218 | int f = 0; |
| 219 | 219 | printmode(PCSPP); |
| @@ -22,13 +22,13 @@ static int pmu_legacy_ctr_get_idx(struct perf_event *event) · 21 unmodified lines | ||
| 22 | 22 | struct perf_event_attr *attr = &event->attr; |
| 23 | 23 | |
| 24 | 24 | if (event->attr.type != PERF_TYPE_HARDWARE) |
| 25 | − return -EOPNOTSUPP; | |
| 25 | + return -ENOENT; | |
| 26 | 26 | if (attr->config == PERF_COUNT_HW_CPU_CYCLES) |
| 27 | 27 | return RISCV_PMU_LEGACY_CYCLE; |
| 28 | 28 | else if (attr->config == PERF_COUNT_HW_INSTRUCTIONS) |
| 29 | 29 | return RISCV_PMU_LEGACY_INSTRET; |
| 30 | 30 | else |
| 31 | − return -EOPNOTSUPP; | |
| 31 | + return -ENOENT; | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | /* For legacy config & counter index are same */ |
| @@ -309,7 +309,7 @@ static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata) · 308 unmodified lines | ||
| 309 | 309 | ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0); |
| 310 | 310 | } else if (ret.error == SBI_ERR_NOT_SUPPORTED) { |
| 311 | 311 | /* This event cannot be monitored by any counter */ |
| 312 | − edata->event_idx = -EINVAL; | |
| 312 | + edata->event_idx = -ENOENT; | |
| 313 | 313 | } |
| 314 | 314 | } |
| 315 | 315 | |
| @@ -556,7 +556,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig) · 240 unmodified lines | ||
| 556 | 556 | } |
| 557 | 557 | break; |
| 558 | 558 | default: |
| 559 | − ret = -EINVAL; | |
| 559 | + ret = -ENOENT; | |
| 560 | 560 | break; |
| 561 | 561 | } |
| 562 | 562 | |
| @@ -46,6 +46,7 @@ config PINCTRL_INTEL_PLATFORM · 45 unmodified lines | ||
| 46 | 46 | of Intel PCH pins and using them as GPIOs. Currently the following |
| 47 | 47 | Intel SoCs / platforms require this to be functional: |
| 48 | 48 | - Lunar Lake |
| 49 | + - Panther Lake | |
| 49 | 50 | |
| 50 | 51 | config PINCTRL_ALDERLAKE |
| 51 | 52 | tristate "Intel Alder Lake pinctrl and GPIO driver" |
| @@ -90,7 +90,6 @@ static int intel_platform_pinctrl_prepare_community(struct device *dev, · 89 unmodified lines | ||
| 90 | 90 | struct intel_community *community, |
| 91 | 91 | struct intel_platform_pins *pins) |
| 92 | 92 | { |
| 93 | − struct fwnode_handle *child; | |
| 94 | 93 | struct intel_padgroup *gpps; |
| 95 | 94 | unsigned int group; |
| 96 | 95 | size_t ngpps; |
| @@ -131,7 +130,7 @@ static int intel_platform_pinctrl_prepare_community(struct device *dev, · 34 unmodified lines | ||
| 131 | 130 | return -ENOMEM; |
| 132 | 131 | |
| 133 | 132 | group = 0; |
| 134 | − device_for_each_child_node(dev, child) { | |
| 133 | + device_for_each_child_node_scoped(dev, child) { | |
| 135 | 134 | struct intel_padgroup *gpp = &gpps[group]; |
| 136 | 135 | |
| 137 | 136 | gpp->reg_num = group; |
| @@ -159,7 +158,7 @@ static int intel_platform_pinctrl_prepare_soc_data(struct device *dev, · 21 unmodified lines | ||
| 159 | 158 | int ret; |
| 160 | 159 | |
| 161 | 160 | /* Version 1.0 of the specification assumes only a single community per device node */ |
| 162 | − ncommunities = 1, | |
| 161 | + ncommunities = 1; | |
| 163 | 162 | communities = devm_kcalloc(dev, ncommunities, sizeof(*communities), GFP_KERNEL); |
| 164 | 163 | if (!communities) |
| 165 | 164 | return -ENOMEM; |
| @@ -218,7 +218,7 @@ static int ma35_pinctrl_dt_node_to_map_func(struct pinctrl_dev *pctldev, · 217 unmodified lines | ||
| 218 | 218 | } |
| 219 | 219 | |
| 220 | 220 | map_num += grp->npins; |
| 221 | − new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), GFP_KERNEL); | |
| 221 | + new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); | |
| 222 | 222 | if (!new_map) |
| 223 | 223 | return -ENOMEM; |
| 224 | 224 | |
| @@ -474,6 +474,9 @@ static int apple_gpio_pinctrl_probe(struct platform_device *pdev) · 473 unmodified lines | ||
| 474 | 474 | for (i = 0; i < npins; i++) { |
| 475 | 475 | pins[i].number = i; |
| 476 | 476 | pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i); |
| 477 | + if (!pins[i].name) | |
| 478 | + return -ENOMEM; | |
| 479 | + | |
| 477 | 480 | pins[i].drv_data = pctl; |
| 478 | 481 | pin_names[i] = pins[i].name; |
| 479 | 482 | pin_nums[i] = i; |
| @@ -987,8 +987,10 @@ static int aw9523_probe(struct i2c_client *client) · 986 unmodified lines | ||
| 987 | 987 | lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter)); |
| 988 | 988 | |
| 989 | 989 | pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); |
| 990 | − if (!pdesc) | |
| 991 | − return -ENOMEM; | |
| 990 | + if (!pdesc) { | |
| 991 | + ret = -ENOMEM; | |
| 992 | + goto err_disable_vregs; | |
| 993 | + } | |
| 992 | 994 | |
| 993 | 995 | ret = aw9523_hw_init(awi); |
| 994 | 996 | if (ret) |
| @@ -1955,21 +1955,21 @@ static void ocelot_irq_handler(struct irq_desc *desc) · 1954 unmodified lines | ||
| 1955 | 1955 | unsigned int reg = 0, irq, i; |
| 1956 | 1956 | unsigned long irqs; |
| 1957 | 1957 | |
| 1958 | + chained_irq_enter(parent_chip, desc); | |
| 1959 | + | |
| 1958 | 1960 | for (i = 0; i < info->stride; i++) { |
| 1959 | 1961 | regmap_read(info->map, id_reg + 4 * i, ®); |
| 1960 | 1962 | if (!reg) |
| 1961 | 1963 | continue; |
| 1962 | 1964 | |
| 1963 | − chained_irq_enter(parent_chip, desc); | |
| 1964 | − | |
| 1965 | 1965 | irqs = reg; |
| 1966 | 1966 | |
| 1967 | 1967 | for_each_set_bit(irq, &irqs, |
| 1968 | 1968 | min(32U, info->desc->npins - 32 * i)) |
| 1969 | 1969 | generic_handle_domain_irq(chip->irq.domain, irq + 32 * i); |
| 1970 | − | |
| 1971 | − chained_irq_exit(parent_chip, desc); | |
| 1972 | 1970 | } |
| 1971 | + | |
| 1972 | + chained_irq_exit(parent_chip, desc); | |
| 1973 | 1973 | } |
| 1974 | 1974 | |
| 1975 | 1975 | static int ocelot_gpiochip_register(struct platform_device *pdev, |
| @@ -221,7 +221,7 @@ static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, · 220 unmodified lines | ||
| 221 | 221 | if (!grpnames) |
| 222 | 222 | return -ENOMEM; |
| 223 | 223 | |
| 224 | − map = devm_kcalloc(dev, ngroups * 2, sizeof(*map), GFP_KERNEL); | |
| 224 | + map = kcalloc(ngroups * 2, sizeof(*map), GFP_KERNEL); | |
| 225 | 225 | if (!map) |
| 226 | 226 | return -ENOMEM; |
| 227 | 227 | |
| @@ -1374,10 +1374,15 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode · 1373 unmodified lines | ||
| 1374 | 1374 | |
| 1375 | 1375 | for (i = 0; i < npins; i++) { |
| 1376 | 1376 | stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); |
| 1377 | − if (stm32_pin && stm32_pin->pin.name) | |
| 1377 | + if (stm32_pin && stm32_pin->pin.name) { | |
| 1378 | 1378 | names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name); |
| 1379 | − else | |
| 1379 | + if (!names[i]) { | |
| 1380 | + err = -ENOMEM; | |
| 1381 | + goto err_clk; | |
| 1382 | + } | |
| 1383 | + } else { | |
| 1380 | 1384 | names[i] = NULL; |
| 1385 | + } | |
| 1381 | 1386 | } |
| 1382 | 1387 | |
| 1383 | 1388 | bank->gpio_chip.names = (const char * const *)names; |
| @@ -2391,12 +2391,18 @@ static struct attribute *dell_battery_attrs[] = { · 2390 unmodified lines | ||
| 2391 | 2391 | }; |
| 2392 | 2392 | ATTRIBUTE_GROUPS(dell_battery); |
| 2393 | 2393 | |
| 2394 | +static bool dell_battery_supported(struct power_supply *battery) | |
| 2395 | +{ | |
| 2396 | + /* We currently only support the primary battery */ | |
| 2397 | + return strcmp(battery->desc->name, "BAT0") == 0; | |
| 2398 | +} | |
| 2399 | + | |
| 2394 | 2400 | static int dell_battery_add(struct power_supply *battery, |
| 2395 | 2401 | struct acpi_battery_hook *hook) |
| 2396 | 2402 | { |
| 2397 | − /* this currently only supports the primary battery */ | |
| 2398 | − if (strcmp(battery->desc->name, "BAT0") != 0) | |
| 2399 | − return -ENODEV; | |
| 2403 | + /* Return 0 instead of an error to avoid being unloaded */ | |
| 2404 | + if (!dell_battery_supported(battery)) | |
| 2405 | + return 0; | |
| 2400 | 2406 | |
| 2401 | 2407 | return device_add_groups(&battery->dev, dell_battery_groups); |
| 2402 | 2408 | } |
| @@ -2404,6 +2410,9 @@ static int dell_battery_add(struct power_supply *battery, · 1 unmodified line | ||
| 2404 | 2410 | static int dell_battery_remove(struct power_supply *battery, |
| 2405 | 2411 | struct acpi_battery_hook *hook) |
| 2406 | 2412 | { |
| 2413 | + if (!dell_battery_supported(battery)) | |
| 2414 | + return 0; | |
| 2415 | + | |
| 2407 | 2416 | device_remove_groups(&battery->dev, dell_battery_groups); |
| 2408 | 2417 | return 0; |
| 2409 | 2418 | } |
| @@ -521,6 +521,7 @@ static int __init sysman_init(void) · 520 unmodified lines | ||
| 521 | 521 | int ret = 0; |
| 522 | 522 | |
| 523 | 523 | if (!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL) && |
| 524 | + !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Alienware", NULL) && | |
| 524 | 525 | !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) { |
| 525 | 526 | pr_err("Unable to run on non-Dell system\n"); |
| 526 | 527 | return -ENODEV; |
| @@ -130,8 +130,6 @@ const struct pmc_reg_map spt_reg_map = { · 129 unmodified lines | ||
| 130 | 130 | .ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES, |
| 131 | 131 | .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET, |
| 132 | 132 | .pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT, |
| 133 | − .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, | |
| 134 | − .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, | |
| 135 | 133 | .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED, |
| 136 | 134 | .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, |
| 137 | 135 | }; |
| @@ -316,7 +316,9 @@ static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn · 315 unmodified lines | ||
| 316 | 316 | cpu >= nr_cpu_ids || cpu >= num_possible_cpus()) |
| 317 | 317 | return NULL; |
| 318 | 318 | |
| 319 | − pkg_id = topology_physical_package_id(cpu); | |
| 319 | + pkg_id = topology_logical_package_id(cpu); | |
| 320 | + if (pkg_id >= topology_max_packages()) | |
| 321 | + return NULL; | |
| 320 | 322 | |
| 321 | 323 | bus_number = isst_cpu_info[cpu].bus_info[bus_no]; |
| 322 | 324 | if (bus_number < 0) |
| @@ -807,6 +809,7 @@ static const struct x86_cpu_id isst_cpu_ids[] = { · 484 unmodified lines | ||
| 807 | 809 | X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, SST_HPM_SUPPORTED), |
| 808 | 810 | X86_MATCH_VFM(INTEL_ICELAKE_D, 0), |
| 809 | 811 | X86_MATCH_VFM(INTEL_ICELAKE_X, 0), |
| 812 | + X86_MATCH_VFM(INTEL_PANTHERCOVE_X, SST_HPM_SUPPORTED), | |
| 810 | 813 | X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0), |
| 811 | 814 | X86_MATCH_VFM(INTEL_SKYLAKE_X, SST_MBOX_SUPPORTED), |
| 812 | 815 | {} |
| @@ -82,6 +82,7 @@ static const struct x86_cpu_id tpmi_cpu_ids[] = { · 81 unmodified lines | ||
| 82 | 82 | X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, NULL), |
| 83 | 83 | X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, NULL), |
| 84 | 84 | X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, NULL), |
| 85 | + X86_MATCH_VFM(INTEL_PANTHERCOVE_X, NULL), | |
| 85 | 86 | {} |
| 86 | 87 | }; |
| 87 | 88 | MODULE_DEVICE_TABLE(x86cpu, tpmi_cpu_ids); |
| @@ -390,8 +390,9 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) · 389 unmodified lines | ||
| 390 | 390 | for (i = 0; i < pdev_count; i++) { |
| 391 | 391 | pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); |
| 392 | 392 | if (IS_ERR(pdevs[i])) { |
| 393 | + ret = PTR_ERR(pdevs[i]); | |
| 393 | 394 | x86_android_tablet_remove(pdev); |
| 394 | − return PTR_ERR(pdevs[i]); | |
| 395 | + return ret; | |
| 395 | 396 | } |
| 396 | 397 | } |
| 397 | 398 | |
| @@ -443,8 +444,9 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) · 45 unmodified lines | ||
| 443 | 444 | PLATFORM_DEVID_AUTO, |
| 444 | 445 | &pdata, sizeof(pdata)); |
| 445 | 446 | if (IS_ERR(pdevs[pdev_count])) { |
| 447 | + ret = PTR_ERR(pdevs[pdev_count]); | |
| 446 | 448 | x86_android_tablet_remove(pdev); |
| 447 | − return PTR_ERR(pdevs[pdev_count]); | |
| 449 | + return ret; | |
| 448 | 450 | } |
| 449 | 451 | pdev_count++; |
| 450 | 452 | } |
| @@ -1052,7 +1052,7 @@ static unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref, · 1051 unmodified lines | ||
| 1052 | 1052 | of_parse_phandle(child_np, "required-opps", 0); |
| 1053 | 1053 | |
| 1054 | 1054 | if (child_req_np == ref_np) { |
| 1055 | − u64 rate; | |
| 1055 | + u64 rate = 0; | |
| 1056 | 1056 | |
| 1057 | 1057 | of_property_read_u64(child_np, "opp-hz", &rate); |
| 1058 | 1058 | return (unsigned long) rate; |
| @@ -147,6 +147,8 @@ static const struct x86_cpu_id pl4_support_ids[] = { · 146 unmodified lines | ||
| 147 | 147 | X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL), |
| 148 | 148 | X86_MATCH_VFM(INTEL_METEORLAKE, NULL), |
| 149 | 149 | X86_MATCH_VFM(INTEL_METEORLAKE_L, NULL), |
| 150 | + X86_MATCH_VFM(INTEL_ARROWLAKE_U, NULL), | |
| 151 | + X86_MATCH_VFM(INTEL_ARROWLAKE_H, NULL), | |
| 150 | 152 | {} |
| 151 | 153 | }; |
| 152 | 154 | |
| @@ -15,7 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/module.h> |
| 16 | 16 | #include <linux/slab.h> |
| 17 | 17 | |
| 18 | −#define TPMI_RAPL_VERSION 1 | |
| 18 | +#define TPMI_RAPL_MAJOR_VERSION 0 | |
| 19 | +#define TPMI_RAPL_MINOR_VERSION 1 | |
| 19 | 20 | |
| 20 | 21 | /* 1 header + 10 registers + 5 reserved. 8 bytes for each. */ |
| 21 | 22 | #define TPMI_RAPL_DOMAIN_SIZE 128 |
| @@ -154,11 +155,21 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) · 132 unmodified lines | ||
| 154 | 155 | tpmi_domain_size = tpmi_domain_header >> 16 & 0xff; |
| 155 | 156 | tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; |
| 156 | 157 | |
| 157 | − if (tpmi_domain_version != TPMI_RAPL_VERSION) { | |
| 158 | − pr_warn(FW_BUG "Unsupported version:%d\n", tpmi_domain_version); | |
| 158 | + if (tpmi_domain_version == TPMI_VERSION_INVALID) { | |
| 159 | + pr_warn(FW_BUG "Invalid version\n"); | |
| 159 | 160 | return -ENODEV; |
| 160 | 161 | } |
| 161 | 162 | |
| 163 | + if (TPMI_MAJOR_VERSION(tpmi_domain_version) != TPMI_RAPL_MAJOR_VERSION) { | |
| 164 | + pr_warn(FW_BUG "Unsupported major version:%ld\n", | |
| 165 | + TPMI_MAJOR_VERSION(tpmi_domain_version)); | |
| 166 | + return -ENODEV; | |
| 167 | + } | |
| 168 | + | |
| 169 | + if (TPMI_MINOR_VERSION(tpmi_domain_version) > TPMI_RAPL_MINOR_VERSION) | |
| 170 | + pr_info("Ignore: Unsupported minor version:%ld\n", | |
| 171 | + TPMI_MINOR_VERSION(tpmi_domain_version)); | |
| 172 | + | |
| 162 | 173 | /* Domain size: in unit of 128 Bytes */ |
| 163 | 174 | if (tpmi_domain_size != 1) { |
| 164 | 175 | pr_warn(FW_BUG "Invalid Domain size %d\n", tpmi_domain_size); |
| @@ -181,7 +192,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) · 16 unmodified lines | ||
| 181 | 192 | pr_warn(FW_BUG "System domain must support Domain Info register\n"); |
| 182 | 193 | return -ENODEV; |
| 183 | 194 | } |
| 184 | − tpmi_domain_info = readq(trp->base + offset + TPMI_RAPL_REG_DOMAIN_INFO); | |
| 195 | + tpmi_domain_info = readq(trp->base + offset + TPMI_RAPL_REG_DOMAIN_INFO * 8); | |
| 185 | 196 | if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT)) |
| 186 | 197 | return 0; |
| 187 | 198 | domain_type = RAPL_DOMAIN_PLATFORM; |
| @@ -405,8 +405,8 @@ static int npcm_rc_probe(struct platform_device *pdev) · 404 unmodified lines | ||
| 405 | 405 | if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number", |
| 406 | 406 | &rc->sw_reset_number)) { |
| 407 | 407 | if (rc->sw_reset_number && rc->sw_reset_number < 5) { |
| 408 | − rc->restart_nb.priority = 192, | |
| 409 | − rc->restart_nb.notifier_call = npcm_rc_restart, | |
| 408 | + rc->restart_nb.priority = 192; | |
| 409 | + rc->restart_nb.notifier_call = npcm_rc_restart; | |
| 410 | 410 | ret = register_restart_handler(&rc->restart_nb); |
| 411 | 411 | if (ret) |
| 412 | 412 | dev_warn(&pdev->dev, "failed to register restart handler\n"); |
| @@ -94,6 +94,9 @@ static int jh71x0_reset_status(struct reset_controller_dev *rcdev, · 93 unmodified lines | ||
| 94 | 94 | void __iomem *reg_status = data->status + offset * sizeof(u32); |
| 95 | 95 | u32 value = readl(reg_status); |
| 96 | 96 | |
| 97 | + if (!data->asserted) | |
| 98 | + return !(value & mask); | |
| 99 | + | |
| 97 | 100 | return !((value ^ data->asserted[offset]) & mask); |
| 98 | 101 | } |
| 99 | 102 | |
| @@ -1195,7 +1195,8 @@ sclp_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) · 1194 unmodified lines | ||
| 1195 | 1195 | } |
| 1196 | 1196 | |
| 1197 | 1197 | static struct notifier_block sclp_reboot_notifier = { |
| 1198 | − .notifier_call = sclp_reboot_event | |
| 1198 | + .notifier_call = sclp_reboot_event, | |
| 1199 | + .priority = INT_MIN, | |
| 1199 | 1200 | }; |
| 1200 | 1201 | |
| 1201 | 1202 | static ssize_t con_pages_show(struct device_driver *dev, char *buf) |
| @@ -319,7 +319,7 @@ sclp_vt220_add_msg(struct sclp_vt220_request *request, · 318 unmodified lines | ||
| 319 | 319 | buffer = (void *) ((addr_t) sccb + sccb->header.length); |
| 320 | 320 | |
| 321 | 321 | if (convertlf) { |
| 322 | − /* Perform Linefeed conversion (0x0a -> 0x0a 0x0d)*/ | |
| 322 | + /* Perform Linefeed conversion (0x0a -> 0x0d 0x0a)*/ | |
| 323 | 323 | for (from=0, to=0; |
| 324 | 324 | (from < count) && (to < sclp_vt220_space_left(request)); |
| 325 | 325 | from++) { |
| @@ -328,8 +328,8 @@ sclp_vt220_add_msg(struct sclp_vt220_request *request, · 2 unmodified lines | ||
| 328 | 328 | /* Perform conversion */ |
| 329 | 329 | if (c == 0x0a) { |
| 330 | 330 | if (to + 1 < sclp_vt220_space_left(request)) { |
| 331 | − ((unsigned char *) buffer)[to++] = c; | |
| 332 | 331 | ((unsigned char *) buffer)[to++] = 0x0d; |
| 332 | + ((unsigned char *) buffer)[to++] = c; | |
| 333 | 333 | } else |
| 334 | 334 | break; |
| 335 | 335 | |
| @@ -1864,13 +1864,12 @@ static inline void ap_scan_domains(struct ap_card *ac) · 1863 unmodified lines | ||
| 1864 | 1864 | } |
| 1865 | 1865 | /* if no queue device exists, create a new one */ |
| 1866 | 1866 | if (!aq) { |
| 1867 | − aq = ap_queue_create(qid, ac->ap_dev.device_type); | |
| 1867 | + aq = ap_queue_create(qid, ac); | |
| 1868 | 1868 | if (!aq) { |
| 1869 | 1869 | AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n", |
| 1870 | 1870 | __func__, ac->id, dom); |
| 1871 | 1871 | continue; |
| 1872 | 1872 | } |
| 1873 | − aq->card = ac; | |
| 1874 | 1873 | aq->config = !decfg; |
| 1875 | 1874 | aq->chkstop = chkstop; |
| 1876 | 1875 | aq->se_bstate = hwinfo.bs; |
| @@ -272,7 +272,7 @@ int ap_test_config_usage_domain(unsigned int domain); · 271 unmodified lines | ||
| 272 | 272 | int ap_test_config_ctrl_domain(unsigned int domain); |
| 273 | 273 | |
| 274 | 274 | void ap_queue_init_reply(struct ap_queue *aq, struct ap_message *ap_msg); |
| 275 | −struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type); | |
| 275 | +struct ap_queue *ap_queue_create(ap_qid_t qid, struct ap_card *ac); | |
| 276 | 276 | void ap_queue_prepare_remove(struct ap_queue *aq); |
| 277 | 277 | void ap_queue_remove(struct ap_queue *aq); |
| 278 | 278 | void ap_queue_init_state(struct ap_queue *aq); |
| @@ -22,6 +22,11 @@ static void __ap_flush_queue(struct ap_queue *aq); · 21 unmodified lines | ||
| 22 | 22 | * some AP queue helper functions |
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | +static inline bool ap_q_supported_in_se(struct ap_queue *aq) | |
| 26 | +{ | |
| 27 | + return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; | |
| 28 | +} | |
| 29 | + | |
| 25 | 30 | static inline bool ap_q_supports_bind(struct ap_queue *aq) |
| 26 | 31 | { |
| 27 | 32 | return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; |
| @@ -1104,18 +1109,19 @@ static void ap_queue_device_release(struct device *dev) · 1076 unmodified lines | ||
| 1104 | 1109 | kfree(aq); |
| 1105 | 1110 | } |
| 1106 | 1111 | |
| 1107 | −struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type) | |
| 1112 | +struct ap_queue *ap_queue_create(ap_qid_t qid, struct ap_card *ac) | |
| 1108 | 1113 | { |
| 1109 | 1114 | struct ap_queue *aq; |
| 1110 | 1115 | |
| 1111 | 1116 | aq = kzalloc(sizeof(*aq), GFP_KERNEL); |
| 1112 | 1117 | if (!aq) |
| 1113 | 1118 | return NULL; |
| 1119 | + aq->card = ac; | |
| 1114 | 1120 | aq->ap_dev.device.release = ap_queue_device_release; |
| 1115 | 1121 | aq->ap_dev.device.type = &ap_queue_type; |
| 1116 | − aq->ap_dev.device_type = device_type; | |
| 1117 | − // add optional SE secure binding attributes group | |
| 1118 | − if (ap_sb_available() && is_prot_virt_guest()) | |
| 1122 | + aq->ap_dev.device_type = ac->ap_dev.device_type; | |
| 1123 | + /* in SE environment add bind/associate attributes group */ | |
| 1124 | + if (ap_is_se_guest() && ap_q_supported_in_se(aq)) | |
| 1119 | 1125 | aq->ap_dev.device.groups = ap_queue_dev_sb_attr_groups; |
| 1120 | 1126 | aq->qid = qid; |
| 1121 | 1127 | spin_lock_init(&aq->lock); |
| @@ -1196,10 +1202,16 @@ bool ap_queue_usable(struct ap_queue *aq) · 74 unmodified lines | ||
| 1196 | 1202 | } |
| 1197 | 1203 | |
| 1198 | 1204 | /* SE guest's queues additionally need to be bound */ |
| 1199 | − if (ap_q_needs_bind(aq) && | |
| 1200 | − !(aq->se_bstate == AP_BS_Q_USABLE || | |
| 1201 | − aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) | |
| 1202 | − rc = false; | |
| 1205 | + if (ap_is_se_guest()) { | |
| 1206 | + if (!ap_q_supported_in_se(aq)) { | |
| 1207 | + rc = false; | |
| 1208 | + goto unlock_and_out; | |
| 1209 | + } | |
| 1210 | + if (ap_q_needs_bind(aq) && | |
| 1211 | + !(aq->se_bstate == AP_BS_Q_USABLE || | |
| 1212 | + aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) | |
| 1213 | + rc = false; | |
| 1214 | + } | |
| 1203 | 1215 | |
| 1204 | 1216 | unlock_and_out: |
| 1205 | 1217 | spin_unlock_bh(&aq->lock); |
| @@ -324,6 +324,7 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen, · 323 unmodified lines | ||
| 324 | 324 | memcpy(protkey, t->protkey, t->len); |
| 325 | 325 | *protkeylen = t->len; |
| 326 | 326 | *protkeytype = t->keytype; |
| 327 | + rc = 0; | |
| 327 | 328 | break; |
| 328 | 329 | } |
| 329 | 330 | case TOKVER_CLEAR_KEY: { |
| @@ -830,7 +830,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 829 unmodified lines | ||
| 830 | 830 | spin_lock_init(&fnic->vlans_lock); |
| 831 | 831 | INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); |
| 832 | 832 | INIT_WORK(&fnic->event_work, fnic_handle_event); |
| 833 | − INIT_WORK(&fnic->flush_work, fnic_flush_tx); | |
| 834 | 833 | skb_queue_head_init(&fnic->fip_frame_queue); |
| 835 | 834 | INIT_LIST_HEAD(&fnic->evlist); |
| 836 | 835 | INIT_LIST_HEAD(&fnic->vlans); |
| @@ -948,6 +947,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 111 unmodified lines | ||
| 948 | 947 | |
| 949 | 948 | INIT_WORK(&fnic->link_work, fnic_handle_link); |
| 950 | 949 | INIT_WORK(&fnic->frame_work, fnic_handle_frame); |
| 950 | + INIT_WORK(&fnic->flush_work, fnic_flush_tx); | |
| 951 | 951 | skb_queue_head_init(&fnic->frame_queue); |
| 952 | 952 | skb_queue_head_init(&fnic->tx_queue); |
| 953 | 953 | |
| @@ -542,8 +542,8 @@ struct mpi3mr_hba_port { · 541 unmodified lines | ||
| 542 | 542 | * @port_list: List of ports belonging to a SAS node |
| 543 | 543 | * @num_phys: Number of phys associated with port |
| 544 | 544 | * @marked_responding: used while refresing the sas ports |
| 545 | − * @lowest_phy: lowest phy ID of current sas port | |
| 546 | − * @phy_mask: phy_mask of current sas port | |
| 545 | + * @lowest_phy: lowest phy ID of current sas port, valid for controller port | |
| 546 | + * @phy_mask: phy_mask of current sas port, valid for controller port | |
| 547 | 547 | * @hba_port: HBA port entry |
| 548 | 548 | * @remote_identify: Attached device identification |
| 549 | 549 | * @rphy: SAS transport layer rphy object |
| @@ -590,12 +590,13 @@ static enum sas_linkrate mpi3mr_convert_phy_link_rate(u8 link_rate) · 589 unmodified lines | ||
| 590 | 590 | * @mrioc: Adapter instance reference |
| 591 | 591 | * @mr_sas_port: Internal Port object |
| 592 | 592 | * @mr_sas_phy: Internal Phy object |
| 593 | + * @host_node: Flag to indicate this is a host_node | |
| 593 | 594 | * |
| 594 | 595 | * Return: None. |
| 595 | 596 | */ |
| 596 | 597 | static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, |
| 597 | 598 | struct mpi3mr_sas_port *mr_sas_port, |
| 598 | − struct mpi3mr_sas_phy *mr_sas_phy) | |
| 599 | + struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node) | |
| 599 | 600 | { |
| 600 | 601 | u64 sas_address = mr_sas_port->remote_identify.sas_address; |
| 601 | 602 | |
| @@ -605,9 +606,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, · 3 unmodified lines | ||
| 605 | 606 | |
| 606 | 607 | list_del(&mr_sas_phy->port_siblings); |
| 607 | 608 | mr_sas_port->num_phys--; |
| 608 | − mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); | |
| 609 | − if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) | |
| 610 | − mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 609 | + | |
| 610 | + if (host_node) { | |
| 611 | + mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); | |
| 612 | + | |
| 613 | + if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) | |
| 614 | + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 615 | + } | |
| 611 | 616 | sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); |
| 612 | 617 | mr_sas_phy->phy_belongs_to_port = 0; |
| 613 | 618 | } |
| @@ -617,12 +622,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, · 3 unmodified lines | ||
| 617 | 622 | * @mrioc: Adapter instance reference |
| 618 | 623 | * @mr_sas_port: Internal Port object |
| 619 | 624 | * @mr_sas_phy: Internal Phy object |
| 625 | + * @host_node: Flag to indicate this is a host_node | |
| 620 | 626 | * |
| 621 | 627 | * Return: None. |
| 622 | 628 | */ |
| 623 | 629 | static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, |
| 624 | 630 | struct mpi3mr_sas_port *mr_sas_port, |
| 625 | − struct mpi3mr_sas_phy *mr_sas_phy) | |
| 631 | + struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node) | |
| 626 | 632 | { |
| 627 | 633 | u64 sas_address = mr_sas_port->remote_identify.sas_address; |
| 628 | 634 | |
| @@ -632,9 +638,12 @@ static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, · 3 unmodified lines | ||
| 632 | 638 | |
| 633 | 639 | list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); |
| 634 | 640 | mr_sas_port->num_phys++; |
| 635 | − mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); | |
| 636 | − if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) | |
| 637 | − mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 641 | + if (host_node) { | |
| 642 | + mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); | |
| 643 | + | |
| 644 | + if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) | |
| 645 | + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 646 | + } | |
| 638 | 647 | sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); |
| 639 | 648 | mr_sas_phy->phy_belongs_to_port = 1; |
| 640 | 649 | } |
| @@ -675,7 +684,7 @@ static void mpi3mr_add_phy_to_an_existing_port(struct mpi3mr_ioc *mrioc, · 34 unmodified lines | ||
| 675 | 684 | if (srch_phy == mr_sas_phy) |
| 676 | 685 | return; |
| 677 | 686 | } |
| 678 | − mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy); | |
| 687 | + mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy, mr_sas_node->host_node); | |
| 679 | 688 | return; |
| 680 | 689 | } |
| 681 | 690 | } |
| @@ -736,7 +745,7 @@ static void mpi3mr_del_phy_from_an_existing_port(struct mpi3mr_ioc *mrioc, · 54 unmodified lines | ||
| 736 | 745 | mpi3mr_delete_sas_port(mrioc, mr_sas_port); |
| 737 | 746 | else |
| 738 | 747 | mpi3mr_delete_sas_phy(mrioc, mr_sas_port, |
| 739 | − mr_sas_phy); | |
| 748 | + mr_sas_phy, mr_sas_node->host_node); | |
| 740 | 749 | return; |
| 741 | 750 | } |
| 742 | 751 | } |
| @@ -1028,7 +1037,7 @@ mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id) · 285 unmodified lines | ||
| 1028 | 1037 | /** |
| 1029 | 1038 | * mpi3mr_get_hba_port_by_id - find hba port by id |
| 1030 | 1039 | * @mrioc: Adapter instance reference |
| 1031 | − * @port_id - Port ID to search | |
| 1040 | + * @port_id: Port ID to search | |
| 1032 | 1041 | * |
| 1033 | 1042 | * Return: mpi3mr_hba_port reference for the matched port |
| 1034 | 1043 | */ |
| @@ -1367,7 +1376,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, · 332 unmodified lines | ||
| 1367 | 1376 | mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node, |
| 1368 | 1377 | mr_sas_port->remote_identify.sas_address, hba_port); |
| 1369 | 1378 | |
| 1370 | − if (mr_sas_node->num_phys >= sizeof(mr_sas_port->phy_mask) * 8) | |
| 1379 | + if (mr_sas_node->host_node && mr_sas_node->num_phys >= | |
| 1380 | + sizeof(mr_sas_port->phy_mask) * 8) | |
| 1371 | 1381 | ioc_info(mrioc, "max port count %u could be too high\n", |
| 1372 | 1382 | mr_sas_node->num_phys); |
| 1373 | 1383 | |
| @@ -1377,7 +1387,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, · 3 unmodified lines | ||
| 1377 | 1387 | (mr_sas_node->phy[i].hba_port != hba_port)) |
| 1378 | 1388 | continue; |
| 1379 | 1389 | |
| 1380 | − if (i >= sizeof(mr_sas_port->phy_mask) * 8) { | |
| 1390 | + if (mr_sas_node->host_node && (i >= sizeof(mr_sas_port->phy_mask) * 8)) { | |
| 1381 | 1391 | ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n", |
| 1382 | 1392 | i, sizeof(mr_sas_port->phy_mask) * 8); |
| 1383 | 1393 | goto out_fail; |
| @@ -1385,7 +1395,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, · 1 unmodified line | ||
| 1385 | 1395 | list_add_tail(&mr_sas_node->phy[i].port_siblings, |
| 1386 | 1396 | &mr_sas_port->phy_list); |
| 1387 | 1397 | mr_sas_port->num_phys++; |
| 1388 | − mr_sas_port->phy_mask |= (1 << i); | |
| 1398 | + if (mr_sas_node->host_node) | |
| 1399 | + mr_sas_port->phy_mask |= (1 << i); | |
| 1389 | 1400 | } |
| 1390 | 1401 | |
| 1391 | 1402 | if (!mr_sas_port->num_phys) { |
| @@ -1394,7 +1405,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, · 2 unmodified lines | ||
| 1394 | 1405 | goto out_fail; |
| 1395 | 1406 | } |
| 1396 | 1407 | |
| 1397 | − mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 1408 | + if (mr_sas_node->host_node) | |
| 1409 | + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 1398 | 1410 | |
| 1399 | 1411 | if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { |
| 1400 | 1412 | tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc, |
| @@ -1250,7 +1250,7 @@ static ssize_t fc_rport_set_marginal_state(struct device *dev, · 1249 unmodified lines | ||
| 1250 | 1250 | */ |
| 1251 | 1251 | if (rport->port_state == FC_PORTSTATE_ONLINE) |
| 1252 | 1252 | rport->port_state = port_state; |
| 1253 | − else | |
| 1253 | + else if (port_state != rport->port_state) | |
| 1254 | 1254 | return -EINVAL; |
| 1255 | 1255 | } else if (port_state == FC_PORTSTATE_ONLINE) { |
| 1256 | 1256 | /* |
| @@ -1260,7 +1260,7 @@ static ssize_t fc_rport_set_marginal_state(struct device *dev, · 3 unmodified lines | ||
| 1260 | 1260 | */ |
| 1261 | 1261 | if (rport->port_state == FC_PORTSTATE_MARGINAL) |
| 1262 | 1262 | rport->port_state = port_state; |
| 1263 | − else | |
| 1263 | + else if (port_state != rport->port_state) | |
| 1264 | 1264 | return -EINVAL; |
| 1265 | 1265 | } else |
| 1266 | 1266 | return -EINVAL; |
| @@ -831,7 +831,7 @@ wd33c93_intr(struct Scsi_Host *instance) · 830 unmodified lines | ||
| 831 | 831 | /* construct an IDENTIFY message with correct disconnect bit */ |
| 832 | 832 | |
| 833 | 833 | hostdata->outgoing_msg[0] = IDENTIFY(0, cmd->device->lun); |
| 834 | − if (scsi_pointer->phase) | |
| 834 | + if (WD33C93_scsi_pointer(cmd)->phase) | |
| 835 | 835 | hostdata->outgoing_msg[0] |= 0x40; |
| 836 | 836 | |
| 837 | 837 | if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) { |
| @@ -1761,10 +1761,9 @@ static int qmc_qe_init_resources(struct qmc *qmc, struct platform_device *pdev) · 1760 unmodified lines | ||
| 1761 | 1761 | */ |
| 1762 | 1762 | info = devm_qe_muram_alloc(qmc->dev, UCC_SLOW_PRAM_SIZE + 2 * 64, |
| 1763 | 1763 | ALIGNMENT_OF_UCC_SLOW_PRAM); |
| 1764 | − if (IS_ERR_VALUE(info)) { | |
| 1765 | − dev_err(qmc->dev, "cannot allocate MURAM for PRAM"); | |
| 1766 | − return -ENOMEM; | |
| 1767 | − } | |
| 1764 | + if (info < 0) | |
| 1765 | + return info; | |
| 1766 | + | |
| 1768 | 1767 | if (!qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, qmc->qe_subblock, |
| 1769 | 1768 | QE_CR_PROTOCOL_UNSPECIFIED, info)) { |
| 1770 | 1769 | dev_err(qmc->dev, "QE_ASSIGN_PAGE_TO_DEVICE cmd failed"); |
| @@ -2056,7 +2055,7 @@ static void qmc_remove(struct platform_device *pdev) · 285 unmodified lines | ||
| 2056 | 2055 | qmc_exit_xcc(qmc); |
| 2057 | 2056 | } |
| 2058 | 2057 | |
| 2059 | −static const struct qmc_data qmc_data_cpm1 = { | |
| 2058 | +static const struct qmc_data qmc_data_cpm1 __maybe_unused = { | |
| 2060 | 2059 | .version = QMC_CPM1, |
| 2061 | 2060 | .tstate = 0x30000000, |
| 2062 | 2061 | .rstate = 0x31000000, |
| @@ -2066,7 +2065,7 @@ static const struct qmc_data qmc_data_cpm1 = { · 3 unmodified lines | ||
| 2066 | 2065 | .rpack = 0x00000000, |
| 2067 | 2066 | }; |
| 2068 | 2067 | |
| 2069 | −static const struct qmc_data qmc_data_qe = { | |
| 2068 | +static const struct qmc_data qmc_data_qe __maybe_unused = { | |
| 2070 | 2069 | .version = QMC_QE, |
| 2071 | 2070 | .tstate = 0x30000000, |
| 2072 | 2071 | .rstate = 0x30000000, |
| @@ -377,7 +377,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, · 376 unmodified lines | ||
| 377 | 377 | */ |
| 378 | 378 | if (!(aq->mr & QSPI_MR_SMM)) { |
| 379 | 379 | aq->mr |= QSPI_MR_SMM; |
| 380 | − atmel_qspi_write(aq->scr, aq, QSPI_MR); | |
| 380 | + atmel_qspi_write(aq->mr, aq, QSPI_MR); | |
| 381 | 381 | } |
| 382 | 382 | |
| 383 | 383 | /* Clear pending interrupts */ |
| @@ -678,8 +678,8 @@ static int cdns_spi_probe(struct platform_device *pdev) · 677 unmodified lines | ||
| 678 | 678 | |
| 679 | 679 | clk_dis_all: |
| 680 | 680 | if (!spi_controller_is_target(ctlr)) { |
| 681 | − pm_runtime_set_suspended(&pdev->dev); | |
| 682 | 681 | pm_runtime_disable(&pdev->dev); |
| 682 | + pm_runtime_set_suspended(&pdev->dev); | |
| 683 | 683 | } |
| 684 | 684 | remove_ctlr: |
| 685 | 685 | spi_controller_put(ctlr); |
| @@ -701,8 +701,10 @@ static void cdns_spi_remove(struct platform_device *pdev) · 15 unmodified lines | ||
| 701 | 701 | |
| 702 | 702 | cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE); |
| 703 | 703 | |
| 704 | − pm_runtime_set_suspended(&pdev->dev); | |
| 705 | − pm_runtime_disable(&pdev->dev); | |
| 704 | + if (!spi_controller_is_target(ctlr)) { | |
| 705 | + pm_runtime_disable(&pdev->dev); | |
| 706 | + pm_runtime_set_suspended(&pdev->dev); | |
| 707 | + } | |
| 706 | 708 | |
| 707 | 709 | spi_unregister_controller(ctlr); |
| 708 | 710 | } |
| @@ -1865,8 +1865,8 @@ out_register_controller: · 1864 unmodified lines | ||
| 1865 | 1865 | spi_imx_sdma_exit(spi_imx); |
| 1866 | 1866 | out_runtime_pm_put: |
| 1867 | 1867 | pm_runtime_dont_use_autosuspend(spi_imx->dev); |
| 1868 | − pm_runtime_set_suspended(&pdev->dev); | |
| 1869 | 1868 | pm_runtime_disable(spi_imx->dev); |
| 1869 | + pm_runtime_set_suspended(&pdev->dev); | |
| 1870 | 1870 | |
| 1871 | 1871 | clk_disable_unprepare(spi_imx->clk_ipg); |
| 1872 | 1872 | out_put_per: |
| @@ -245,7 +245,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) · 244 unmodified lines | ||
| 245 | 245 | loops = msecs_to_loops(1); |
| 246 | 246 | do { |
| 247 | 247 | val = readl(regs + S3C64XX_SPI_STATUS); |
| 248 | − } while (TX_FIFO_LVL(val, sdd) && loops--); | |
| 248 | + } while (TX_FIFO_LVL(val, sdd) && --loops); | |
| 249 | 249 | |
| 250 | 250 | if (loops == 0) |
| 251 | 251 | dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); |
| @@ -258,7 +258,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) · 6 unmodified lines | ||
| 258 | 258 | readl(regs + S3C64XX_SPI_RX_DATA); |
| 259 | 259 | else |
| 260 | 260 | break; |
| 261 | − } while (loops--); | |
| 261 | + } while (--loops); | |
| 262 | 262 | |
| 263 | 263 | if (loops == 0) |
| 264 | 264 | dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); |
| @@ -691,7 +691,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) · 690 unmodified lines | ||
| 691 | 691 | |
| 692 | 692 | dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); |
| 693 | 693 | if (!dev->queues) { |
| 694 | − dev->transport->free_device(dev); | |
| 694 | + hba->backend->ops->free_device(dev); | |
| 695 | 695 | return NULL; |
| 696 | 696 | } |
| 697 | 697 | |
| @@ -2130,7 +2130,7 @@ static int tcmu_netlink_event_send(struct tcmu_dev *udev, · 2129 unmodified lines | ||
| 2130 | 2130 | } |
| 2131 | 2131 | |
| 2132 | 2132 | ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0, |
| 2133 | − TCMU_MCGRP_CONFIG, GFP_KERNEL); | |
| 2133 | + TCMU_MCGRP_CONFIG); | |
| 2134 | 2134 | |
| 2135 | 2135 | /* Wait during an add as the listener may not be up yet */ |
| 2136 | 2136 | if (ret == 0 || |
| @@ -416,7 +416,6 @@ err_del_legacy: · 415 unmodified lines | ||
| 416 | 416 | if (!pci_info->no_legacy) |
| 417 | 417 | proc_thermal_remove(proc_priv); |
| 418 | 418 | proc_thermal_mmio_remove(pdev, proc_priv); |
| 419 | − pci_disable_device(pdev); | |
| 420 | 419 | |
| 421 | 420 | return ret; |
| 422 | 421 | } |
| @@ -438,7 +437,6 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev) · 15 unmodified lines | ||
| 438 | 437 | proc_thermal_mmio_remove(pdev, pci_info->proc_priv); |
| 439 | 438 | if (!pci_info->no_legacy) |
| 440 | 439 | proc_thermal_remove(proc_priv); |
| 441 | − pci_disable_device(pdev); | |
| 442 | 440 | } |
| 443 | 441 | |
| 444 | 442 | #ifdef CONFIG_PM_SLEEP |
| @@ -13,48 +13,12 @@ static struct rapl_if_priv rapl_mmio_priv; · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | static const struct rapl_mmio_regs rapl_mmio_default = { |
| 15 | 15 | .reg_unit = 0x5938, |
| 16 | − .regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930}, | |
| 16 | + .regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930, 0x59b0}, | |
| 17 | 17 | .regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0}, |
| 18 | − .limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2), | |
| 18 | + .limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2) | BIT(POWER_LIMIT4), | |
| 19 | 19 | .limits[RAPL_DOMAIN_DRAM] = BIT(POWER_LIMIT2), |
| 20 | 20 | }; |
| 21 | 21 | |
| 22 | −static int rapl_mmio_cpu_online(unsigned int cpu) | |
| 23 | −{ | |
| 24 | − struct rapl_package *rp; | |
| 25 | − | |
| 26 | − /* mmio rapl supports package 0 only for now */ | |
| 27 | − if (topology_physical_package_id(cpu)) | |
| 28 | − return 0; | |
| 29 | − | |
| 30 | − rp = rapl_find_package_domain_cpuslocked(cpu, &rapl_mmio_priv, true); | |
| 31 | − if (!rp) { | |
| 32 | − rp = rapl_add_package_cpuslocked(cpu, &rapl_mmio_priv, true); | |
| 33 | − if (IS_ERR(rp)) | |
| 34 | − return PTR_ERR(rp); | |
| 35 | − } | |
| 36 | − cpumask_set_cpu(cpu, &rp->cpumask); | |
| 37 | − return 0; | |
| 38 | −} | |
| 39 | − | |
| 40 | −static int rapl_mmio_cpu_down_prep(unsigned int cpu) | |
| 41 | −{ | |
| 42 | − struct rapl_package *rp; | |
| 43 | − int lead_cpu; | |
| 44 | − | |
| 45 | − rp = rapl_find_package_domain_cpuslocked(cpu, &rapl_mmio_priv, true); | |
| 46 | − if (!rp) | |
| 47 | − return 0; | |
| 48 | − | |
| 49 | − cpumask_clear_cpu(cpu, &rp->cpumask); | |
| 50 | − lead_cpu = cpumask_first(&rp->cpumask); | |
| 51 | − if (lead_cpu >= nr_cpu_ids) | |
| 52 | − rapl_remove_package_cpuslocked(rp); | |
| 53 | − else if (rp->lead_cpu == cpu) | |
| 54 | − rp->lead_cpu = lead_cpu; | |
| 55 | − return 0; | |
| 56 | −} | |
| 57 | − | |
| 58 | 22 | static int rapl_mmio_read_raw(int cpu, struct reg_action *ra) |
| 59 | 23 | { |
| 60 | 24 | if (!ra->reg.mmio) |
| @@ -82,6 +46,7 @@ static int rapl_mmio_write_raw(int cpu, struct reg_action *ra) · 21 unmodified lines | ||
| 82 | 46 | int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) |
| 83 | 47 | { |
| 84 | 48 | const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default; |
| 49 | + struct rapl_package *rp; | |
| 85 | 50 | enum rapl_domain_reg_id reg; |
| 86 | 51 | enum rapl_domain_type domain; |
| 87 | 52 | int ret; |
| @@ -109,25 +74,38 @@ int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc · 21 unmodified lines | ||
| 109 | 74 | return PTR_ERR(rapl_mmio_priv.control_type); |
| 110 | 75 | } |
| 111 | 76 | |
| 112 | − ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powercap/rapl:online", | |
| 113 | − rapl_mmio_cpu_online, rapl_mmio_cpu_down_prep); | |
| 114 | − if (ret < 0) { | |
| 115 | − powercap_unregister_control_type(rapl_mmio_priv.control_type); | |
| 116 | − rapl_mmio_priv.control_type = NULL; | |
| 117 | − return ret; | |
| 77 | + /* Register a RAPL package device for package 0 which is always online */ | |
| 78 | + rp = rapl_find_package_domain(0, &rapl_mmio_priv, false); | |
| 79 | + if (rp) { | |
| 80 | + ret = -EEXIST; | |
| 81 | + goto err; | |
| 82 | + } | |
| 83 | + | |
| 84 | + rp = rapl_add_package(0, &rapl_mmio_priv, false); | |
| 85 | + if (IS_ERR(rp)) { | |
| 86 | + ret = PTR_ERR(rp); | |
| 87 | + goto err; | |
| 118 | 88 | } |
| 119 | − rapl_mmio_priv.pcap_rapl_online = ret; | |
| 120 | 89 | |
| 121 | 90 | return 0; |
| 91 | + | |
| 92 | +err: | |
| 93 | + powercap_unregister_control_type(rapl_mmio_priv.control_type); | |
| 94 | + rapl_mmio_priv.control_type = NULL; | |
| 95 | + return ret; | |
| 122 | 96 | } |
| 123 | 97 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_add); |
| 124 | 98 | |
| 125 | 99 | void proc_thermal_rapl_remove(void) |
| 126 | 100 | { |
| 101 | + struct rapl_package *rp; | |
| 102 | + | |
| 127 | 103 | if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type)) |
| 128 | 104 | return; |
| 129 | 105 | |
| 130 | − cpuhp_remove_state(rapl_mmio_priv.pcap_rapl_online); | |
| 106 | + rp = rapl_find_package_domain(0, &rapl_mmio_priv, false); | |
| 107 | + if (rp) | |
| 108 | + rapl_remove_package(rp); | |
| 131 | 109 | powercap_unregister_control_type(rapl_mmio_priv.control_type); |
| 132 | 110 | } |
| 133 | 111 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_remove); |
| @@ -728,6 +728,7 @@ struct thermal_zone_device *thermal_zone_get_by_id(int id) · 727 unmodified lines | ||
| 728 | 728 | mutex_lock(&thermal_list_lock); |
| 729 | 729 | list_for_each_entry(tz, &thermal_tz_list, node) { |
| 730 | 730 | if (tz->id == id) { |
| 731 | + get_device(&tz->device); | |
| 731 | 732 | match = tz; |
| 732 | 733 | break; |
| 733 | 734 | } |
| @@ -1605,14 +1606,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) · 871 unmodified lines | ||
| 1605 | 1606 | ida_destroy(&tz->ida); |
| 1606 | 1607 | |
| 1607 | 1608 | device_del(&tz->device); |
| 1608 | − | |
| 1609 | − kfree(tz->tzp); | |
| 1610 | − | |
| 1611 | 1609 | put_device(&tz->device); |
| 1612 | 1610 | |
| 1613 | 1611 | thermal_notify_tz_delete(tz); |
| 1614 | 1612 | |
| 1615 | 1613 | wait_for_completion(&tz->removal); |
| 1614 | + kfree(tz->tzp); | |
| 1616 | 1615 | kfree(tz); |
| 1617 | 1616 | } |
| 1618 | 1617 | EXPORT_SYMBOL_GPL(thermal_zone_device_unregister); |
| @@ -194,6 +194,9 @@ int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *), · 193 unmodified lines | ||
| 194 | 194 | |
| 195 | 195 | struct thermal_zone_device *thermal_zone_get_by_id(int id); |
| 196 | 196 | |
| 197 | +DEFINE_CLASS(thermal_zone_get_by_id, struct thermal_zone_device *, | |
| 198 | + if (_T) put_device(&_T->device), thermal_zone_get_by_id(id), int id) | |
| 199 | + | |
| 197 | 200 | static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) |
| 198 | 201 | { |
| 199 | 202 | return cdev->ops->get_requested_power && cdev->ops->state2power && |
| @@ -443,7 +443,6 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) · 442 unmodified lines | ||
| 443 | 443 | { |
| 444 | 444 | struct sk_buff *msg = p->msg; |
| 445 | 445 | const struct thermal_trip_desc *td; |
| 446 | − struct thermal_zone_device *tz; | |
| 447 | 446 | struct nlattr *start_trip; |
| 448 | 447 | int id; |
| 449 | 448 | |
| @@ -452,7 +451,7 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) · 2 unmodified lines | ||
| 452 | 451 | |
| 453 | 452 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); |
| 454 | 453 | |
| 455 | − tz = thermal_zone_get_by_id(id); | |
| 454 | + CLASS(thermal_zone_get_by_id, tz)(id); | |
| 456 | 455 | if (!tz) |
| 457 | 456 | return -EINVAL; |
| 458 | 457 | |
| @@ -488,7 +487,6 @@ out_cancel_nest: · 29 unmodified lines | ||
| 488 | 487 | static int thermal_genl_cmd_tz_get_temp(struct param *p) |
| 489 | 488 | { |
| 490 | 489 | struct sk_buff *msg = p->msg; |
| 491 | − struct thermal_zone_device *tz; | |
| 492 | 490 | int temp, ret, id; |
| 493 | 491 | |
| 494 | 492 | if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) |
| @@ -496,7 +494,7 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p) · 1 unmodified line | ||
| 496 | 494 | |
| 497 | 495 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); |
| 498 | 496 | |
| 499 | − tz = thermal_zone_get_by_id(id); | |
| 497 | + CLASS(thermal_zone_get_by_id, tz)(id); | |
| 500 | 498 | if (!tz) |
| 501 | 499 | return -EINVAL; |
| 502 | 500 | |
| @@ -514,7 +512,6 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p) · 11 unmodified lines | ||
| 514 | 512 | static int thermal_genl_cmd_tz_get_gov(struct param *p) |
| 515 | 513 | { |
| 516 | 514 | struct sk_buff *msg = p->msg; |
| 517 | − struct thermal_zone_device *tz; | |
| 518 | 515 | int id, ret = 0; |
| 519 | 516 | |
| 520 | 517 | if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) |
| @@ -522,7 +519,7 @@ static int thermal_genl_cmd_tz_get_gov(struct param *p) · 1 unmodified line | ||
| 522 | 519 | |
| 523 | 520 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); |
| 524 | 521 | |
| 525 | − tz = thermal_zone_get_by_id(id); | |
| 522 | + CLASS(thermal_zone_get_by_id, tz)(id); | |
| 526 | 523 | if (!tz) |
| 527 | 524 | return -EINVAL; |
| 528 | 525 | |
| @@ -3157,6 +3157,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) · 3156 unmodified lines | ||
| 3157 | 3157 | mutex_unlock(&gsm->mutex); |
| 3158 | 3158 | /* Now wipe the queues */ |
| 3159 | 3159 | tty_ldisc_flush(gsm->tty); |
| 3160 | + | |
| 3161 | + guard(spinlock_irqsave)(&gsm->tx_lock); | |
| 3160 | 3162 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list) |
| 3161 | 3163 | kfree(txq); |
| 3162 | 3164 | INIT_LIST_HEAD(&gsm->tx_ctrl_list); |
| @@ -762,6 +762,21 @@ static irqreturn_t __imx_uart_rtsint(int irq, void *dev_id) · 761 unmodified lines | ||
| 762 | 762 | |
| 763 | 763 | imx_uart_writel(sport, USR1_RTSD, USR1); |
| 764 | 764 | usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS; |
| 765 | + /* | |
| 766 | + * Update sport->old_status here, so any follow-up calls to | |
| 767 | + * imx_uart_mctrl_check() will be able to recognize that RTS | |
| 768 | + * state changed since last imx_uart_mctrl_check() call. | |
| 769 | + * | |
| 770 | + * In case RTS has been detected as asserted here and later on | |
| 771 | + * deasserted by the time imx_uart_mctrl_check() was called, | |
| 772 | + * imx_uart_mctrl_check() can detect the RTS state change and | |
| 773 | + * trigger uart_handle_cts_change() to unblock the port for | |
| 774 | + * further TX transfers. | |
| 775 | + */ | |
| 776 | + if (usr1 & USR1_RTSS) | |
| 777 | + sport->old_status |= TIOCM_CTS; | |
| 778 | + else | |
| 779 | + sport->old_status &= ~TIOCM_CTS; | |
| 765 | 780 | uart_handle_cts_change(&sport->port, usr1); |
| 766 | 781 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
| 767 | 782 | |
| @@ -147,6 +147,7 @@ static struct uart_driver qcom_geni_uart_driver; · 146 unmodified lines | ||
| 147 | 147 | |
| 148 | 148 | static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); |
| 149 | 149 | static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); |
| 150 | +static int qcom_geni_serial_port_setup(struct uart_port *uport); | |
| 150 | 151 | |
| 151 | 152 | static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport) |
| 152 | 153 | { |
| @@ -395,6 +396,23 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport, · 242 unmodified lines | ||
| 395 | 396 | writel(c, uport->membase + SE_GENI_TX_FIFOn); |
| 396 | 397 | qcom_geni_serial_poll_tx_done(uport); |
| 397 | 398 | } |
| 399 | + | |
| 400 | +static int qcom_geni_serial_poll_init(struct uart_port *uport) | |
| 401 | +{ | |
| 402 | + struct qcom_geni_serial_port *port = to_dev_port(uport); | |
| 403 | + int ret; | |
| 404 | + | |
| 405 | + if (!port->setup) { | |
| 406 | + ret = qcom_geni_serial_port_setup(uport); | |
| 407 | + if (ret) | |
| 408 | + return ret; | |
| 409 | + } | |
| 410 | + | |
| 411 | + if (!qcom_geni_serial_secondary_active(uport)) | |
| 412 | + geni_se_setup_s_cmd(&port->se, UART_START_READ, 0); | |
| 413 | + | |
| 414 | + return 0; | |
| 415 | +} | |
| 398 | 416 | #endif |
| 399 | 417 | |
| 400 | 418 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE |
| @@ -562,7 +580,7 @@ static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop) · 161 unmodified lines | ||
| 562 | 580 | } |
| 563 | 581 | #endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */ |
| 564 | 582 | |
| 565 | −static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) | |
| 583 | +static void handle_rx_uart(struct uart_port *uport, u32 bytes) | |
| 566 | 584 | { |
| 567 | 585 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 568 | 586 | struct tty_port *tport = &uport->state->port; |
| @@ -570,9 +588,8 @@ static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) · 1 unmodified line | ||
| 570 | 588 | |
| 571 | 589 | ret = tty_insert_flip_string(tport, port->rx_buf, bytes); |
| 572 | 590 | if (ret != bytes) { |
| 573 | − dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n", | |
| 574 | − __func__, ret, bytes); | |
| 575 | − WARN_ON_ONCE(1); | |
| 591 | + dev_err_ratelimited(uport->dev, "failed to push data (%d < %u)\n", | |
| 592 | + ret, bytes); | |
| 576 | 593 | } |
| 577 | 594 | uport->icount.rx += ret; |
| 578 | 595 | tty_flip_buffer_push(tport); |
| @@ -787,17 +804,27 @@ static void qcom_geni_serial_start_rx_fifo(struct uart_port *uport) · 208 unmodified lines | ||
| 787 | 804 | static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport) |
| 788 | 805 | { |
| 789 | 806 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 807 | + bool done; | |
| 790 | 808 | |
| 791 | 809 | if (!qcom_geni_serial_secondary_active(uport)) |
| 792 | 810 | return; |
| 793 | 811 | |
| 794 | 812 | geni_se_cancel_s_cmd(&port->se); |
| 795 | − qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS, | |
| 796 | − S_CMD_CANCEL_EN, true); | |
| 797 | − | |
| 798 | − if (qcom_geni_serial_secondary_active(uport)) | |
| 813 | + done = qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT, | |
| 814 | + RX_EOT, true); | |
| 815 | + if (done) { | |
| 816 | + writel(RX_EOT | RX_DMA_DONE, | |
| 817 | + uport->membase + SE_DMA_RX_IRQ_CLR); | |
| 818 | + } else { | |
| 799 | 819 | qcom_geni_serial_abort_rx(uport); |
| 800 | 820 | |
| 821 | + writel(1, uport->membase + SE_DMA_RX_FSM_RST); | |
| 822 | + qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT, | |
| 823 | + RX_RESET_DONE, true); | |
| 824 | + writel(RX_RESET_DONE | RX_DMA_DONE, | |
| 825 | + uport->membase + SE_DMA_RX_IRQ_CLR); | |
| 826 | + } | |
| 827 | + | |
| 801 | 828 | if (port->rx_dma_addr) { |
| 802 | 829 | geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, |
| 803 | 830 | DMA_RX_BUF_SIZE); |
| @@ -846,7 +873,7 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop) · 42 unmodified lines | ||
| 846 | 873 | } |
| 847 | 874 | |
| 848 | 875 | if (!drop) |
| 849 | − handle_rx_uart(uport, rx_in, drop); | |
| 876 | + handle_rx_uart(uport, rx_in); | |
| 850 | 877 | |
| 851 | 878 | ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, |
| 852 | 879 | DMA_RX_BUF_SIZE, |
| @@ -1096,10 +1123,12 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport) · 243 unmodified lines | ||
| 1096 | 1123 | { |
| 1097 | 1124 | disable_irq(uport->irq); |
| 1098 | 1125 | |
| 1126 | + uart_port_lock_irq(uport); | |
| 1099 | 1127 | qcom_geni_serial_stop_tx(uport); |
| 1100 | 1128 | qcom_geni_serial_stop_rx(uport); |
| 1101 | 1129 | |
| 1102 | 1130 | qcom_geni_serial_cancel_tx_cmd(uport); |
| 1131 | + uart_port_unlock_irq(uport); | |
| 1103 | 1132 | } |
| 1104 | 1133 | |
| 1105 | 1134 | static void qcom_geni_serial_flush_buffer(struct uart_port *uport) |
| @@ -1152,7 +1181,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) · 46 unmodified lines | ||
| 1152 | 1181 | false, true, true); |
| 1153 | 1182 | geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); |
| 1154 | 1183 | geni_se_select_mode(&port->se, port->dev_data->mode); |
| 1155 | − qcom_geni_serial_start_rx(uport); | |
| 1156 | 1184 | port->setup = true; |
| 1157 | 1185 | |
| 1158 | 1186 | return 0; |
| @@ -1168,6 +1196,11 @@ static int qcom_geni_serial_startup(struct uart_port *uport) · 9 unmodified lines | ||
| 1168 | 1196 | if (ret) |
| 1169 | 1197 | return ret; |
| 1170 | 1198 | } |
| 1199 | + | |
| 1200 | + uart_port_lock_irq(uport); | |
| 1201 | + qcom_geni_serial_start_rx(uport); | |
| 1202 | + uart_port_unlock_irq(uport); | |
| 1203 | + | |
| 1171 | 1204 | enable_irq(uport->irq); |
| 1172 | 1205 | |
| 1173 | 1206 | return 0; |
| @@ -1253,7 +1286,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, · 79 unmodified lines | ||
| 1253 | 1286 | unsigned int avg_bw_core; |
| 1254 | 1287 | unsigned long timeout; |
| 1255 | 1288 | |
| 1256 | − qcom_geni_serial_stop_rx(uport); | |
| 1257 | 1289 | /* baud rate */ |
| 1258 | 1290 | baud = uart_get_baud_rate(uport, termios, old, 300, 4000000); |
| 1259 | 1291 | |
| @@ -1269,7 +1301,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, · 9 unmodified lines | ||
| 1269 | 1301 | dev_err(port->se.dev, |
| 1270 | 1302 | "Couldn't find suitable clock rate for %u\n", |
| 1271 | 1303 | baud * sampling_rate); |
| 1272 | − goto out_restart_rx; | |
| 1304 | + return; | |
| 1273 | 1305 | } |
| 1274 | 1306 | |
| 1275 | 1307 | dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n", |
| @@ -1360,8 +1392,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, · 84 unmodified lines | ||
| 1360 | 1392 | writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); |
| 1361 | 1393 | writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); |
| 1362 | 1394 | writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG); |
| 1363 | −out_restart_rx: | |
| 1364 | − qcom_geni_serial_start_rx(uport); | |
| 1365 | 1395 | } |
| 1366 | 1396 | |
| 1367 | 1397 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE |
| @@ -1582,7 +1612,7 @@ static const struct uart_ops qcom_geni_console_pops = { · 214 unmodified lines | ||
| 1582 | 1612 | #ifdef CONFIG_CONSOLE_POLL |
| 1583 | 1613 | .poll_get_char = qcom_geni_serial_get_char, |
| 1584 | 1614 | .poll_put_char = qcom_geni_serial_poll_put_char, |
| 1585 | − .poll_init = qcom_geni_serial_port_setup, | |
| 1615 | + .poll_init = qcom_geni_serial_poll_init, | |
| 1586 | 1616 | #endif |
| 1587 | 1617 | .pm = qcom_geni_serial_pm, |
| 1588 | 1618 | }; |
| @@ -1749,7 +1779,7 @@ static void qcom_geni_serial_remove(struct platform_device *pdev) · 160 unmodified lines | ||
| 1749 | 1779 | uart_remove_one_port(drv, &port->uport); |
| 1750 | 1780 | } |
| 1751 | 1781 | |
| 1752 | −static int qcom_geni_serial_sys_suspend(struct device *dev) | |
| 1782 | +static int qcom_geni_serial_suspend(struct device *dev) | |
| 1753 | 1783 | { |
| 1754 | 1784 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
| 1755 | 1785 | struct uart_port *uport = &port->uport; |
| @@ -1766,7 +1796,7 @@ static int qcom_geni_serial_sys_suspend(struct device *dev) · 10 unmodified lines | ||
| 1766 | 1796 | return uart_suspend_port(private_data->drv, uport); |
| 1767 | 1797 | } |
| 1768 | 1798 | |
| 1769 | −static int qcom_geni_serial_sys_resume(struct device *dev) | |
| 1799 | +static int qcom_geni_serial_resume(struct device *dev) | |
| 1770 | 1800 | { |
| 1771 | 1801 | int ret; |
| 1772 | 1802 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
| @@ -1781,38 +1811,6 @@ static int qcom_geni_serial_sys_resume(struct device *dev) · 8 unmodified lines | ||
| 1781 | 1811 | return ret; |
| 1782 | 1812 | } |
| 1783 | 1813 | |
| 1784 | −static int qcom_geni_serial_sys_hib_resume(struct device *dev) | |
| 1785 | −{ | |
| 1786 | − int ret = 0; | |
| 1787 | − struct uart_port *uport; | |
| 1788 | − struct qcom_geni_private_data *private_data; | |
| 1789 | − struct qcom_geni_serial_port *port = dev_get_drvdata(dev); | |
| 1790 | − | |
| 1791 | − uport = &port->uport; | |
| 1792 | − private_data = uport->private_data; | |
| 1793 | − | |
| 1794 | − if (uart_console(uport)) { | |
| 1795 | − geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS); | |
| 1796 | − geni_icc_set_bw(&port->se); | |
| 1797 | − ret = uart_resume_port(private_data->drv, uport); | |
| 1798 | − /* | |
| 1799 | − * For hibernation usecase clients for | |
| 1800 | − * console UART won't call port setup during restore, | |
| 1801 | − * hence call port setup for console uart. | |
| 1802 | − */ | |
| 1803 | − qcom_geni_serial_port_setup(uport); | |
| 1804 | − } else { | |
| 1805 | − /* | |
| 1806 | − * Peripheral register settings are lost during hibernation. | |
| 1807 | − * Update setup flag such that port setup happens again | |
| 1808 | − * during next session. Clients of HS-UART will close and | |
| 1809 | − * open the port during hibernation. | |
| 1810 | − */ | |
| 1811 | − port->setup = false; | |
| 1812 | − } | |
| 1813 | − return ret; | |
| 1814 | −} | |
| 1815 | − | |
| 1816 | 1814 | static const struct qcom_geni_device_data qcom_geni_console_data = { |
| 1817 | 1815 | .console = true, |
| 1818 | 1816 | .mode = GENI_SE_FIFO, |
| @@ -1824,12 +1822,7 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = { · 5 unmodified lines | ||
| 1824 | 1822 | }; |
| 1825 | 1823 | |
| 1826 | 1824 | static const struct dev_pm_ops qcom_geni_serial_pm_ops = { |
| 1827 | − .suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend), | |
| 1828 | − .resume = pm_sleep_ptr(qcom_geni_serial_sys_resume), | |
| 1829 | − .freeze = pm_sleep_ptr(qcom_geni_serial_sys_suspend), | |
| 1830 | − .poweroff = pm_sleep_ptr(qcom_geni_serial_sys_suspend), | |
| 1831 | − .restore = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume), | |
| 1832 | − .thaw = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume), | |
| 1825 | + SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume) | |
| 1833 | 1826 | }; |
| 1834 | 1827 | |
| 1835 | 1828 | static const struct of_device_id qcom_geni_serial_match_table[] = { |
| @@ -4726,7 +4726,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) · 4725 unmodified lines | ||
| 4726 | 4726 | return -EINVAL; |
| 4727 | 4727 | |
| 4728 | 4728 | if (op->data) { |
| 4729 | − font.data = kvmalloc(max_font_size, GFP_KERNEL); | |
| 4729 | + font.data = kvzalloc(max_font_size, GFP_KERNEL); | |
| 4730 | 4730 | if (!font.data) |
| 4731 | 4731 | return -ENOMEM; |
| 4732 | 4732 | } else |
| @@ -539,7 +539,7 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag) · 538 unmodified lines | ||
| 539 | 539 | struct scsi_cmnd *cmd = lrbp->cmd; |
| 540 | 540 | struct ufs_hw_queue *hwq; |
| 541 | 541 | void __iomem *reg, *opr_sqd_base; |
| 542 | − u32 nexus, id, val; | |
| 542 | + u32 nexus, id, val, rtc; | |
| 543 | 543 | int err; |
| 544 | 544 | |
| 545 | 545 | if (hba->quirks & UFSHCD_QUIRK_MCQ_BROKEN_RTC) |
| @@ -569,17 +569,18 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag) · 23 unmodified lines | ||
| 569 | 569 | opr_sqd_base = mcq_opr_base(hba, OPR_SQD, id); |
| 570 | 570 | writel(nexus, opr_sqd_base + REG_SQCTI); |
| 571 | 571 | |
| 572 | − /* SQRTCy.ICU = 1 */ | |
| 573 | − writel(SQ_ICU, opr_sqd_base + REG_SQRTC); | |
| 572 | + /* Initiate Cleanup */ | |
| 573 | + writel(readl(opr_sqd_base + REG_SQRTC) | SQ_ICU, | |
| 574 | + opr_sqd_base + REG_SQRTC); | |
| 574 | 575 | |
| 575 | 576 | /* Poll SQRTSy.CUS = 1. Return result from SQRTSy.RTC */ |
| 576 | 577 | reg = opr_sqd_base + REG_SQRTS; |
| 577 | 578 | err = read_poll_timeout(readl, val, val & SQ_CUS, 20, |
| 578 | 579 | MCQ_POLL_US, false, reg); |
| 579 | − if (err) | |
| 580 | − dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%ld\n", | |
| 581 | − __func__, id, task_tag, | |
| 582 | − FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg))); | |
| 580 | + rtc = FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg)); | |
| 581 | + if (err || rtc) | |
| 582 | + dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%d RTC=%d\n", | |
| 583 | + __func__, id, task_tag, err, rtc); | |
| 583 | 584 | |
| 584 | 585 | if (ufshcd_mcq_sq_start(hba, hwq)) |
| 585 | 586 | err = -ETIMEDOUT; |
| @@ -2933,9 +2933,8 @@ static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i) · 2932 unmodified lines | ||
| 2933 | 2933 | struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr; |
| 2934 | 2934 | dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr + |
| 2935 | 2935 | i * ufshcd_get_ucd_size(hba); |
| 2936 | − u16 response_offset = offsetof(struct utp_transfer_cmd_desc, | |
| 2937 | − response_upiu); | |
| 2938 | − u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table); | |
| 2936 | + u16 response_offset = le16_to_cpu(utrdlp[i].response_upiu_offset); | |
| 2937 | + u16 prdt_offset = le16_to_cpu(utrdlp[i].prd_table_offset); | |
| 2939 | 2938 | |
| 2940 | 2939 | lrb->utr_descriptor_ptr = utrdlp + i; |
| 2941 | 2940 | lrb->utrd_dma_addr = hba->utrdl_dma_addr + |
| @@ -5417,10 +5416,12 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, · 2475 unmodified lines | ||
| 5417 | 5416 | } |
| 5418 | 5417 | break; |
| 5419 | 5418 | case OCS_ABORTED: |
| 5420 | − result |= DID_ABORT << 16; | |
| 5421 | − break; | |
| 5422 | 5419 | case OCS_INVALID_COMMAND_STATUS: |
| 5423 | 5420 | result |= DID_REQUEUE << 16; |
| 5421 | + dev_warn(hba->dev, | |
| 5422 | + "OCS %s from controller for tag %d\n", | |
| 5423 | + (ocs == OCS_ABORTED ? "aborted" : "invalid"), | |
| 5424 | + lrbp->task_tag); | |
| 5424 | 5425 | break; |
| 5425 | 5426 | case OCS_INVALID_CMD_TABLE_ATTR: |
| 5426 | 5427 | case OCS_INVALID_PRDT_ATTR: |
| @@ -6466,26 +6467,12 @@ static bool ufshcd_abort_one(struct request *rq, void *priv) · 1039 unmodified lines | ||
| 6466 | 6467 | struct scsi_device *sdev = cmd->device; |
| 6467 | 6468 | struct Scsi_Host *shost = sdev->host; |
| 6468 | 6469 | struct ufs_hba *hba = shost_priv(shost); |
| 6469 | − struct ufshcd_lrb *lrbp = &hba->lrb[tag]; | |
| 6470 | − struct ufs_hw_queue *hwq; | |
| 6471 | − unsigned long flags; | |
| 6472 | 6470 | |
| 6473 | 6471 | *ret = ufshcd_try_to_abort_task(hba, tag); |
| 6474 | 6472 | dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag, |
| 6475 | 6473 | hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1, |
| 6476 | 6474 | *ret ? "failed" : "succeeded"); |
| 6477 | 6475 | |
| 6478 | − /* Release cmd in MCQ mode if abort succeeds */ | |
| 6479 | − if (hba->mcq_enabled && (*ret == 0)) { | |
| 6480 | − hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(lrbp->cmd)); | |
| 6481 | − if (!hwq) | |
| 6482 | − return 0; | |
| 6483 | − spin_lock_irqsave(&hwq->cq_lock, flags); | |
| 6484 | − if (ufshcd_cmd_inflight(lrbp->cmd)) | |
| 6485 | − ufshcd_release_scsi_cmd(hba, lrbp); | |
| 6486 | − spin_unlock_irqrestore(&hwq->cq_lock, flags); | |
| 6487 | − } | |
| 6488 | − | |
| 6489 | 6476 | return *ret == 0; |
| 6490 | 6477 | } |
| 6491 | 6478 | |
| @@ -10210,7 +10197,9 @@ static void ufshcd_wl_shutdown(struct device *dev) · 3718 unmodified lines | ||
| 10210 | 10197 | shost_for_each_device(sdev, hba->host) { |
| 10211 | 10198 | if (sdev == hba->ufs_device_wlun) |
| 10212 | 10199 | continue; |
| 10213 | − scsi_device_quiesce(sdev); | |
| 10200 | + mutex_lock(&sdev->state_mutex); | |
| 10201 | + scsi_device_set_state(sdev, SDEV_OFFLINE); | |
| 10202 | + mutex_unlock(&sdev->state_mutex); | |
| 10214 | 10203 | } |
| 10215 | 10204 | __ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM); |
| 10216 | 10205 | |
| @@ -544,6 +544,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length) · 543 unmodified lines | ||
| 544 | 544 | int dwc3_event_buffers_setup(struct dwc3 *dwc) |
| 545 | 545 | { |
| 546 | 546 | struct dwc3_event_buffer *evt; |
| 547 | + u32 reg; | |
| 547 | 548 | |
| 548 | 549 | if (!dwc->ev_buf) |
| 549 | 550 | return 0; |
| @@ -556,8 +557,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) · 6 unmodified lines | ||
| 556 | 557 | upper_32_bits(evt->dma)); |
| 557 | 558 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), |
| 558 | 559 | DWC3_GEVNTSIZ_SIZE(evt->length)); |
| 559 | − dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0); | |
| 560 | 560 | |
| 561 | + /* Clear any stale event */ | |
| 562 | + reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); | |
| 563 | + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg); | |
| 561 | 564 | return 0; |
| 562 | 565 | } |
| 563 | 566 | |
| @@ -584,7 +587,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) · 20 unmodified lines | ||
| 584 | 587 | dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0); |
| 585 | 588 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK |
| 586 | 589 | | DWC3_GEVNTSIZ_SIZE(0)); |
| 587 | − dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0); | |
| 590 | + | |
| 591 | + /* Clear any stale event */ | |
| 592 | + reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); | |
| 593 | + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg); | |
| 588 | 594 | } |
| 589 | 595 | |
| 590 | 596 | static void dwc3_core_num_eps(struct dwc3 *dwc) |
| @@ -2336,6 +2342,11 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) · 1745 unmodified lines | ||
| 2336 | 2342 | u32 reg; |
| 2337 | 2343 | int i; |
| 2338 | 2344 | |
| 2345 | + dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & | |
| 2346 | + DWC3_GUSB2PHYCFG_SUSPHY) || | |
| 2347 | + (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) & | |
| 2348 | + DWC3_GUSB3PIPECTL_SUSPHY); | |
| 2349 | + | |
| 2339 | 2350 | switch (dwc->current_dr_role) { |
| 2340 | 2351 | case DWC3_GCTL_PRTCAP_DEVICE: |
| 2341 | 2352 | if (pm_runtime_suspended(dwc->dev)) |
| @@ -2387,6 +2398,15 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) · 45 unmodified lines | ||
| 2387 | 2398 | break; |
| 2388 | 2399 | } |
| 2389 | 2400 | |
| 2401 | + if (!PMSG_IS_AUTO(msg)) { | |
| 2402 | + /* | |
| 2403 | + * TI AM62 platform requires SUSPHY to be | |
| 2404 | + * enabled for system suspend to work. | |
| 2405 | + */ | |
| 2406 | + if (!dwc->susphy_state) | |
| 2407 | + dwc3_enable_susphy(dwc, true); | |
| 2408 | + } | |
| 2409 | + | |
| 2390 | 2410 | return 0; |
| 2391 | 2411 | } |
| 2392 | 2412 | |
| @@ -2454,6 +2474,11 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) · 61 unmodified lines | ||
| 2454 | 2474 | break; |
| 2455 | 2475 | } |
| 2456 | 2476 | |
| 2477 | + if (!PMSG_IS_AUTO(msg)) { | |
| 2478 | + /* restore SUSPHY state to that before system suspend. */ | |
| 2479 | + dwc3_enable_susphy(dwc, dwc->susphy_state); | |
| 2480 | + } | |
| 2481 | + | |
| 2457 | 2482 | return 0; |
| 2458 | 2483 | } |
| 2459 | 2484 | |
| @@ -2499,7 +2524,11 @@ static int dwc3_runtime_resume(struct device *dev) · 39 unmodified lines | ||
| 2499 | 2524 | |
| 2500 | 2525 | switch (dwc->current_dr_role) { |
| 2501 | 2526 | case DWC3_GCTL_PRTCAP_DEVICE: |
| 2502 | − dwc3_gadget_process_pending_events(dwc); | |
| 2527 | + if (dwc->pending_events) { | |
| 2528 | + pm_runtime_put(dwc->dev); | |
| 2529 | + dwc->pending_events = false; | |
| 2530 | + enable_irq(dwc->irq_gadget); | |
| 2531 | + } | |
| 2503 | 2532 | break; |
| 2504 | 2533 | case DWC3_GCTL_PRTCAP_HOST: |
| 2505 | 2534 | default: |
| @@ -2552,7 +2581,7 @@ static int dwc3_suspend(struct device *dev) · 46 unmodified lines | ||
| 2552 | 2581 | static int dwc3_resume(struct device *dev) |
| 2553 | 2582 | { |
| 2554 | 2583 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 2555 | − int ret; | |
| 2584 | + int ret = 0; | |
| 2556 | 2585 | |
| 2557 | 2586 | pinctrl_pm_select_default_state(dev); |
| 2558 | 2587 | |
| @@ -2560,14 +2589,12 @@ static int dwc3_resume(struct device *dev) · 1 unmodified line | ||
| 2560 | 2589 | pm_runtime_set_active(dev); |
| 2561 | 2590 | |
| 2562 | 2591 | ret = dwc3_resume_common(dwc, PMSG_RESUME); |
| 2563 | − if (ret) { | |
| 2592 | + if (ret) | |
| 2564 | 2593 | pm_runtime_set_suspended(dev); |
| 2565 | − return ret; | |
| 2566 | − } | |
| 2567 | 2594 | |
| 2568 | 2595 | pm_runtime_enable(dev); |
| 2569 | 2596 | |
| 2570 | − return 0; | |
| 2597 | + return ret; | |
| 2571 | 2598 | } |
| 2572 | 2599 | |
| 2573 | 2600 | static void dwc3_complete(struct device *dev) |
| @@ -2589,6 +2616,12 @@ static void dwc3_complete(struct device *dev) · 15 unmodified lines | ||
| 2589 | 2616 | static const struct dev_pm_ops dwc3_dev_pm_ops = { |
| 2590 | 2617 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) |
| 2591 | 2618 | .complete = dwc3_complete, |
| 2619 | + | |
| 2620 | + /* | |
| 2621 | + * Runtime suspend halts the controller on disconnection. It relies on | |
| 2622 | + * platforms with custom connection notification to start the controller | |
| 2623 | + * again. | |
| 2624 | + */ | |
| 2592 | 2625 | SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, |
| 2593 | 2626 | dwc3_runtime_idle) |
| 2594 | 2627 | }; |
| @@ -1150,6 +1150,8 @@ struct dwc3_scratchpad_array { · 1149 unmodified lines | ||
| 1150 | 1150 | * @sys_wakeup: set if the device may do system wakeup. |
| 1151 | 1151 | * @wakeup_configured: set if the device is configured for remote wakeup. |
| 1152 | 1152 | * @suspended: set to track suspend event due to U3/L2. |
| 1153 | + * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY | |
| 1154 | + * before PM suspend. | |
| 1153 | 1155 | * @imod_interval: set the interrupt moderation interval in 250ns |
| 1154 | 1156 | * increments or 0 to disable. |
| 1155 | 1157 | * @max_cfg_eps: current max number of IN eps used across all USB configs. |
| @@ -1382,6 +1384,7 @@ struct dwc3 { · 226 unmodified lines | ||
| 1382 | 1384 | unsigned sys_wakeup:1; |
| 1383 | 1385 | unsigned wakeup_configured:1; |
| 1384 | 1386 | unsigned suspended:1; |
| 1387 | + unsigned susphy_state:1; | |
| 1385 | 1388 | |
| 1386 | 1389 | u16 imod_interval; |
| 1387 | 1390 | |
| @@ -1675,7 +1678,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc) · 287 unmodified lines | ||
| 1675 | 1678 | #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) |
| 1676 | 1679 | int dwc3_gadget_suspend(struct dwc3 *dwc); |
| 1677 | 1680 | int dwc3_gadget_resume(struct dwc3 *dwc); |
| 1678 | −void dwc3_gadget_process_pending_events(struct dwc3 *dwc); | |
| 1679 | 1681 | #else |
| 1680 | 1682 | static inline int dwc3_gadget_suspend(struct dwc3 *dwc) |
| 1681 | 1683 | { |
| @@ -1687,9 +1689,6 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc) · 5 unmodified lines | ||
| 1687 | 1689 | return 0; |
| 1688 | 1690 | } |
| 1689 | 1691 | |
| 1690 | −static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc) | |
| 1691 | −{ | |
| 1692 | −} | |
| 1693 | 1692 | #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ |
| 1694 | 1693 | |
| 1695 | 1694 | #if IS_ENABLED(CONFIG_USB_DWC3_ULPI) |
| @@ -438,6 +438,10 @@ skip_status: · 437 unmodified lines | ||
| 438 | 438 | dwc3_gadget_ep_get_transfer_index(dep); |
| 439 | 439 | } |
| 440 | 440 | |
| 441 | + if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER && | |
| 442 | + !(cmd & DWC3_DEPCMD_CMDIOC)) | |
| 443 | + mdelay(1); | |
| 444 | + | |
| 441 | 445 | if (saved_config) { |
| 442 | 446 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
| 443 | 447 | reg |= saved_config; |
| @@ -1715,12 +1719,10 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int · 1271 unmodified lines | ||
| 1715 | 1719 | WARN_ON_ONCE(ret); |
| 1716 | 1720 | dep->resource_index = 0; |
| 1717 | 1721 | |
| 1718 | − if (!interrupt) { | |
| 1719 | − mdelay(1); | |
| 1722 | + if (!interrupt) | |
| 1720 | 1723 | dep->flags &= ~DWC3_EP_TRANSFER_STARTED; |
| 1721 | − } else if (!ret) { | |
| 1724 | + else if (!ret) | |
| 1722 | 1725 | dep->flags |= DWC3_EP_END_TRANSFER_PENDING; |
| 1723 | − } | |
| 1724 | 1726 | |
| 1725 | 1727 | dep->flags &= ~DWC3_EP_DELAY_STOP; |
| 1726 | 1728 | return ret; |
| @@ -4728,14 +4730,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc) · 3001 unmodified lines | ||
| 4728 | 4730 | |
| 4729 | 4731 | return dwc3_gadget_soft_connect(dwc); |
| 4730 | 4732 | } |
| 4731 | − | |
| 4732 | −void dwc3_gadget_process_pending_events(struct dwc3 *dwc) | |
| 4733 | −{ | |
| 4734 | − if (dwc->pending_events) { | |
| 4735 | − dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf); | |
| 4736 | − dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf); | |
| 4737 | − pm_runtime_put(dwc->dev); | |
| 4738 | − dwc->pending_events = false; | |
| 4739 | − enable_irq(dwc->irq_gadget); | |
| 4740 | − } | |
| 4741 | −} | |
| @@ -2061,7 +2061,7 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ · 2060 unmodified lines | ||
| 2061 | 2061 | const char *page, size_t len) \ |
| 2062 | 2062 | { \ |
| 2063 | 2063 | struct f_uac2_opts *opts = to_f_uac2_opts(item); \ |
| 2064 | − int ret = 0; \ | |
| 2064 | + int ret = len; \ | |
| 2065 | 2065 | \ |
| 2066 | 2066 | mutex_lock(&opts->lock); \ |
| 2067 | 2067 | if (opts->refcnt) { \ |
| @@ -2072,8 +2072,8 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ · 4 unmodified lines | ||
| 2072 | 2072 | if (len && page[len - 1] == '\n') \ |
| 2073 | 2073 | len--; \ |
| 2074 | 2074 | \ |
| 2075 | − ret = scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ | |
| 2076 | − "%s", page); \ | |
| 2075 | + scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ | |
| 2076 | + "%s", page); \ | |
| 2077 | 2077 | \ |
| 2078 | 2078 | end: \ |
| 2079 | 2079 | mutex_unlock(&opts->lock); \ |
| @@ -1696,6 +1696,7 @@ int usb_gadget_register_driver_owner(struct usb_gadget_driver *driver, · 1695 unmodified lines | ||
| 1696 | 1696 | driver->driver.bus = &gadget_bus_type; |
| 1697 | 1697 | driver->driver.owner = owner; |
| 1698 | 1698 | driver->driver.mod_name = mod_name; |
| 1699 | + driver->driver.probe_type = PROBE_FORCE_SYNCHRONOUS; | |
| 1699 | 1700 | ret = driver_register(&driver->driver); |
| 1700 | 1701 | if (ret) { |
| 1701 | 1702 | pr_warn("%s: driver registration failed: %d\n", |
| @@ -254,6 +254,7 @@ struct dummy_hcd { · 253 unmodified lines | ||
| 254 | 254 | u32 stream_en_ep; |
| 255 | 255 | u8 num_stream[30 / 2]; |
| 256 | 256 | |
| 257 | + unsigned timer_pending:1; | |
| 257 | 258 | unsigned active:1; |
| 258 | 259 | unsigned old_active:1; |
| 259 | 260 | unsigned resuming:1; |
| @@ -1303,9 +1304,11 @@ static int dummy_urb_enqueue( · 1043 unmodified lines | ||
| 1303 | 1304 | urb->error_count = 1; /* mark as a new urb */ |
| 1304 | 1305 | |
| 1305 | 1306 | /* kick the scheduler, it'll do the rest */ |
| 1306 | − if (!hrtimer_active(&dum_hcd->timer)) | |
| 1307 | + if (!dum_hcd->timer_pending) { | |
| 1308 | + dum_hcd->timer_pending = 1; | |
| 1307 | 1309 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), |
| 1308 | 1310 | HRTIMER_MODE_REL_SOFT); |
| 1311 | + } | |
| 1309 | 1312 | |
| 1310 | 1313 | done: |
| 1311 | 1314 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
| @@ -1324,9 +1327,10 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) · 12 unmodified lines | ||
| 1324 | 1327 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
| 1325 | 1328 | |
| 1326 | 1329 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
| 1327 | − if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING && | |
| 1328 | − !list_empty(&dum_hcd->urbp_list)) | |
| 1330 | + if (rc == 0 && !dum_hcd->timer_pending) { | |
| 1331 | + dum_hcd->timer_pending = 1; | |
| 1329 | 1332 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); |
| 1333 | + } | |
| 1330 | 1334 | |
| 1331 | 1335 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
| 1332 | 1336 | return rc; |
| @@ -1813,6 +1817,7 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t) · 480 unmodified lines | ||
| 1813 | 1817 | |
| 1814 | 1818 | /* look at each urb queued by the host side driver */ |
| 1815 | 1819 | spin_lock_irqsave(&dum->lock, flags); |
| 1820 | + dum_hcd->timer_pending = 0; | |
| 1816 | 1821 | |
| 1817 | 1822 | if (!dum_hcd->udev) { |
| 1818 | 1823 | dev_err(dummy_dev(dum_hcd), |
| @@ -1994,8 +1999,10 @@ return_urb: · 175 unmodified lines | ||
| 1994 | 1999 | if (list_empty(&dum_hcd->urbp_list)) { |
| 1995 | 2000 | usb_put_dev(dum_hcd->udev); |
| 1996 | 2001 | dum_hcd->udev = NULL; |
| 1997 | − } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { | |
| 2002 | + } else if (!dum_hcd->timer_pending && | |
| 2003 | + dum_hcd->rh_state == DUMMY_RH_RUNNING) { | |
| 1998 | 2004 | /* want a 1 msec delay here */ |
| 2005 | + dum_hcd->timer_pending = 1; | |
| 1999 | 2006 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), |
| 2000 | 2007 | HRTIMER_MODE_REL_SOFT); |
| 2001 | 2008 | } |
| @@ -2390,8 +2397,10 @@ static int dummy_bus_resume(struct usb_hcd *hcd) · 388 unmodified lines | ||
| 2390 | 2397 | } else { |
| 2391 | 2398 | dum_hcd->rh_state = DUMMY_RH_RUNNING; |
| 2392 | 2399 | set_link_state(dum_hcd); |
| 2393 | − if (!list_empty(&dum_hcd->urbp_list)) | |
| 2400 | + if (!list_empty(&dum_hcd->urbp_list)) { | |
| 2401 | + dum_hcd->timer_pending = 1; | |
| 2394 | 2402 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); |
| 2403 | + } | |
| 2395 | 2404 | hcd->state = HC_STATE_RUNNING; |
| 2396 | 2405 | } |
| 2397 | 2406 | spin_unlock_irq(&dum_hcd->dum->lock); |
| @@ -2522,6 +2531,7 @@ static void dummy_stop(struct usb_hcd *hcd) · 124 unmodified lines | ||
| 2522 | 2531 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
| 2523 | 2532 | |
| 2524 | 2533 | hrtimer_cancel(&dum_hcd->timer); |
| 2534 | + dum_hcd->timer_pending = 0; | |
| 2525 | 2535 | device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs); |
| 2526 | 2536 | dev_info(dummy_dev(dum_hcd), "stopped\n"); |
| 2527 | 2537 | } |
| @@ -110,6 +110,7 @@ struct dbc_port { · 109 unmodified lines | ||
| 110 | 110 | struct tasklet_struct push; |
| 111 | 111 | |
| 112 | 112 | struct list_head write_pool; |
| 113 | + unsigned int tx_boundary; | |
| 113 | 114 | |
| 114 | 115 | bool registered; |
| 115 | 116 | }; |
| @@ -24,6 +24,29 @@ static inline struct dbc_port *dbc_to_port(struct xhci_dbc *dbc) · 23 unmodified lines | ||
| 24 | 24 | return dbc->priv; |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | +static unsigned int | |
| 28 | +dbc_kfifo_to_req(struct dbc_port *port, char *packet) | |
| 29 | +{ | |
| 30 | + unsigned int len; | |
| 31 | + | |
| 32 | + len = kfifo_len(&port->port.xmit_fifo); | |
| 33 | + | |
| 34 | + if (len == 0) | |
| 35 | + return 0; | |
| 36 | + | |
| 37 | + len = min(len, DBC_MAX_PACKET); | |
| 38 | + | |
| 39 | + if (port->tx_boundary) | |
| 40 | + len = min(port->tx_boundary, len); | |
| 41 | + | |
| 42 | + len = kfifo_out(&port->port.xmit_fifo, packet, len); | |
| 43 | + | |
| 44 | + if (port->tx_boundary) | |
| 45 | + port->tx_boundary -= len; | |
| 46 | + | |
| 47 | + return len; | |
| 48 | +} | |
| 49 | + | |
| 27 | 50 | static int dbc_start_tx(struct dbc_port *port) |
| 28 | 51 | __releases(&port->port_lock) |
| 29 | 52 | __acquires(&port->port_lock) |
| @@ -36,7 +59,7 @@ static int dbc_start_tx(struct dbc_port *port) · 6 unmodified lines | ||
| 36 | 59 | |
| 37 | 60 | while (!list_empty(pool)) { |
| 38 | 61 | req = list_entry(pool->next, struct dbc_request, list_pool); |
| 39 | − len = kfifo_out(&port->port.xmit_fifo, req->buf, DBC_MAX_PACKET); | |
| 62 | + len = dbc_kfifo_to_req(port, req->buf); | |
| 40 | 63 | if (len == 0) |
| 41 | 64 | break; |
| 42 | 65 | do_tty_wake = true; |
| @@ -200,14 +223,32 @@ static ssize_t dbc_tty_write(struct tty_struct *tty, const u8 *buf, · 157 unmodified lines | ||
| 200 | 223 | { |
| 201 | 224 | struct dbc_port *port = tty->driver_data; |
| 202 | 225 | unsigned long flags; |
| 226 | + unsigned int written = 0; | |
| 203 | 227 | |
| 204 | 228 | spin_lock_irqsave(&port->port_lock, flags); |
| 205 | − if (count) | |
| 206 | − count = kfifo_in(&port->port.xmit_fifo, buf, count); | |
| 207 | − dbc_start_tx(port); | |
| 229 | + | |
| 230 | + /* | |
| 231 | + * Treat tty write as one usb transfer. Make sure the writes are turned | |
| 232 | + * into TRB request having the same size boundaries as the tty writes. | |
| 233 | + * Don't add data to kfifo before previous write is turned into TRBs | |
| 234 | + */ | |
| 235 | + if (port->tx_boundary) { | |
| 236 | + spin_unlock_irqrestore(&port->port_lock, flags); | |
| 237 | + return 0; | |
| 238 | + } | |
| 239 | + | |
| 240 | + if (count) { | |
| 241 | + written = kfifo_in(&port->port.xmit_fifo, buf, count); | |
| 242 | + | |
| 243 | + if (written == count) | |
| 244 | + port->tx_boundary = kfifo_len(&port->port.xmit_fifo); | |
| 245 | + | |
| 246 | + dbc_start_tx(port); | |
| 247 | + } | |
| 248 | + | |
| 208 | 249 | spin_unlock_irqrestore(&port->port_lock, flags); |
| 209 | 250 | |
| 210 | − return count; | |
| 251 | + return written; | |
| 211 | 252 | } |
| 212 | 253 | |
| 213 | 254 | static int dbc_tty_put_char(struct tty_struct *tty, u8 ch) |
| @@ -241,6 +282,10 @@ static unsigned int dbc_tty_write_room(struct tty_struct *tty) · 27 unmodified lines | ||
| 241 | 282 | |
| 242 | 283 | spin_lock_irqsave(&port->port_lock, flags); |
| 243 | 284 | room = kfifo_avail(&port->port.xmit_fifo); |
| 285 | + | |
| 286 | + if (port->tx_boundary) | |
| 287 | + room = 0; | |
| 288 | + | |
| 244 | 289 | spin_unlock_irqrestore(&port->port_lock, flags); |
| 245 | 290 | |
| 246 | 291 | return room; |
| @@ -79,6 +79,7 @@ · 78 unmodified lines | ||
| 79 | 79 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 |
| 80 | 80 | #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 |
| 81 | 81 | #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 |
| 82 | +#define PCI_DEVICE_ID_ASMEDIA_3042_XHCI 0x3042 | |
| 82 | 83 | #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 |
| 83 | 84 | |
| 84 | 85 | #define PCI_DEVICE_ID_CADENCE 0x17CD |
| @@ -451,6 +452,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 366 unmodified lines | ||
| 451 | 452 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) |
| 452 | 453 | xhci->quirks |= XHCI_ASMEDIA_MODIFY_FLOWCONTROL; |
| 453 | 454 | |
| 455 | + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && | |
| 456 | + pdev->device == PCI_DEVICE_ID_ASMEDIA_3042_XHCI) | |
| 457 | + xhci->quirks |= XHCI_RESET_ON_RESUME; | |
| 458 | + | |
| 454 | 459 | if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) |
| 455 | 460 | xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; |
| 456 | 461 | |
| @@ -1023,7 +1023,7 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) · 1022 unmodified lines | ||
| 1023 | 1023 | td_to_noop(xhci, ring, cached_td, false); |
| 1024 | 1024 | cached_td->cancel_status = TD_CLEARED; |
| 1025 | 1025 | } |
| 1026 | − | |
| 1026 | + td_to_noop(xhci, ring, td, false); | |
| 1027 | 1027 | td->cancel_status = TD_CLEARING_CACHE; |
| 1028 | 1028 | cached_td = td; |
| 1029 | 1029 | break; |
| @@ -2775,6 +2775,29 @@ static int handle_tx_event(struct xhci_hcd *xhci, · 1745 unmodified lines | ||
| 2775 | 2775 | return 0; |
| 2776 | 2776 | } |
| 2777 | 2777 | |
| 2778 | + /* | |
| 2779 | + * xhci 4.10.2 states isoc endpoints should continue | |
| 2780 | + * processing the next TD if there was an error mid TD. | |
| 2781 | + * So host like NEC don't generate an event for the last | |
| 2782 | + * isoc TRB even if the IOC flag is set. | |
| 2783 | + * xhci 4.9.1 states that if there are errors in mult-TRB | |
| 2784 | + * TDs xHC should generate an error for that TRB, and if xHC | |
| 2785 | + * proceeds to the next TD it should genete an event for | |
| 2786 | + * any TRB with IOC flag on the way. Other host follow this. | |
| 2787 | + * | |
| 2788 | + * We wait for the final IOC event, but if we get an event | |
| 2789 | + * anywhere outside this TD, just give it back already. | |
| 2790 | + */ | |
| 2791 | + td = list_first_entry_or_null(&ep_ring->td_list, struct xhci_td, td_list); | |
| 2792 | + | |
| 2793 | + if (td && td->error_mid_td && !trb_in_td(xhci, td, ep_trb_dma, false)) { | |
| 2794 | + xhci_dbg(xhci, "Missing TD completion event after mid TD error\n"); | |
| 2795 | + ep_ring->dequeue = td->last_trb; | |
| 2796 | + ep_ring->deq_seg = td->last_trb_seg; | |
| 2797 | + inc_deq(xhci, ep_ring); | |
| 2798 | + xhci_td_cleanup(xhci, td, ep_ring, td->status); | |
| 2799 | + } | |
| 2800 | + | |
| 2778 | 2801 | if (list_empty(&ep_ring->td_list)) { |
| 2779 | 2802 | /* |
| 2780 | 2803 | * Don't print wanings if ring is empty due to a stopped endpoint generating an |
| @@ -2836,44 +2859,13 @@ static int handle_tx_event(struct xhci_hcd *xhci, · 55 unmodified lines | ||
| 2836 | 2859 | return 0; |
| 2837 | 2860 | } |
| 2838 | 2861 | |
| 2839 | − /* | |
| 2840 | − * xhci 4.10.2 states isoc endpoints should continue | |
| 2841 | − * processing the next TD if there was an error mid TD. | |
| 2842 | − * So host like NEC don't generate an event for the last | |
| 2843 | − * isoc TRB even if the IOC flag is set. | |
| 2844 | − * xhci 4.9.1 states that if there are errors in mult-TRB | |
| 2845 | − * TDs xHC should generate an error for that TRB, and if xHC | |
| 2846 | − * proceeds to the next TD it should genete an event for | |
| 2847 | − * any TRB with IOC flag on the way. Other host follow this. | |
| 2848 | − * So this event might be for the next TD. | |
| 2849 | − */ | |
| 2850 | − if (td->error_mid_td && | |
| 2851 | − !list_is_last(&td->td_list, &ep_ring->td_list)) { | |
| 2852 | − struct xhci_td *td_next = list_next_entry(td, td_list); | |
| 2853 | − | |
| 2854 | − ep_seg = trb_in_td(xhci, td_next, ep_trb_dma, false); | |
| 2855 | − if (ep_seg) { | |
| 2856 | − /* give back previous TD, start handling new */ | |
| 2857 | − xhci_dbg(xhci, "Missing TD completion event after mid TD error\n"); | |
| 2858 | − ep_ring->dequeue = td->last_trb; | |
| 2859 | − ep_ring->deq_seg = td->last_trb_seg; | |
| 2860 | − inc_deq(xhci, ep_ring); | |
| 2861 | − xhci_td_cleanup(xhci, td, ep_ring, td->status); | |
| 2862 | − td = td_next; | |
| 2863 | − } | |
| 2864 | − } | |
| 2865 | − | |
| 2866 | − if (!ep_seg) { | |
| 2867 | − /* HC is busted, give up! */ | |
| 2868 | − xhci_err(xhci, | |
| 2869 | − "ERROR Transfer event TRB DMA ptr not " | |
| 2870 | − "part of current TD ep_index %d " | |
| 2871 | − "comp_code %u\n", ep_index, | |
| 2872 | − trb_comp_code); | |
| 2873 | − trb_in_td(xhci, td, ep_trb_dma, true); | |
| 2862 | + /* HC is busted, give up! */ | |
| 2863 | + xhci_err(xhci, | |
| 2864 | + "ERROR Transfer event TRB DMA ptr not part of current TD ep_index %d comp_code %u\n", | |
| 2865 | + ep_index, trb_comp_code); | |
| 2866 | + trb_in_td(xhci, td, ep_trb_dma, true); | |
| 2874 | 2867 | |
| 2875 | − return -ESHUTDOWN; | |
| 2876 | − } | |
| 2868 | + return -ESHUTDOWN; | |
| 2877 | 2869 | } |
| 2878 | 2870 | |
| 2879 | 2871 | if (ep->skip) { |
| @@ -2183,7 +2183,7 @@ static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool runtime) · 2182 unmodified lines | ||
| 2183 | 2183 | goto out; |
| 2184 | 2184 | } |
| 2185 | 2185 | |
| 2186 | − for (i = 0; i < tegra->num_usb_phys; i++) { | |
| 2186 | + for (i = 0; i < xhci->usb2_rhub.num_ports; i++) { | |
| 2187 | 2187 | if (!xhci->usb2_rhub.ports[i]) |
| 2188 | 2188 | continue; |
| 2189 | 2189 | portsc = readl(xhci->usb2_rhub.ports[i]->addr); |
| @@ -1001,7 +1001,7 @@ enum xhci_setup_dev { · 1000 unmodified lines | ||
| 1001 | 1001 | /* Set TR Dequeue Pointer command TRB fields, 6.4.3.9 */ |
| 1002 | 1002 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) |
| 1003 | 1003 | #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) |
| 1004 | −#define SCT_FOR_TRB(p) (((p) << 1) & 0x7) | |
| 1004 | +#define SCT_FOR_TRB(p) (((p) & 0x7) << 1) | |
| 1005 | 1005 | |
| 1006 | 1006 | /* Link TRB specific fields */ |
| 1007 | 1007 | #define TRB_TC (1<<1) |
| @@ -331,3 +331,15 @@ config USB_ONBOARD_DEV · 330 unmodified lines | ||
| 331 | 331 | this config will enable the driver and it will automatically |
| 332 | 332 | match the state of the USB subsystem. If this driver is a |
| 333 | 333 | module it will be called onboard_usb_dev. |
| 334 | + | |
| 335 | +config USB_ONBOARD_DEV_USB5744 | |
| 336 | + bool "Onboard USB Microchip usb5744 hub with SMBus support" | |
| 337 | + depends on (USB_ONBOARD_DEV && I2C=y) || (USB_ONBOARD_DEV=m && I2C=m) | |
| 338 | + help | |
| 339 | + Say Y here if you want to support onboard USB Microchip usb5744 | |
| 340 | + hub that requires SMBus initialization. | |
| 341 | + | |
| 342 | + This options enables usb5744 i2c default initialization sequence | |
| 343 | + during hub start-up configuration stage. It is must to enable this | |
| 344 | + option on AMD Kria KR260 Robotics Starter Kit as this hub is | |
| 345 | + connected to USB-SD converter which mounts the root filesystem. | |
| @@ -311,7 +311,7 @@ static void onboard_dev_attach_usb_driver(struct work_struct *work) · 310 unmodified lines | ||
| 311 | 311 | |
| 312 | 312 | static int onboard_dev_5744_i2c_init(struct i2c_client *client) |
| 313 | 313 | { |
| 314 | −#if IS_ENABLED(CONFIG_I2C) | |
| 314 | +#if IS_ENABLED(CONFIG_USB_ONBOARD_DEV_USB5744) | |
| 315 | 315 | struct device *dev = &client->dev; |
| 316 | 316 | int ret; |
| 317 | 317 | |
| @@ -394,9 +394,11 @@ static int onboard_dev_probe(struct platform_device *pdev) · 76 unmodified lines | ||
| 394 | 394 | |
| 395 | 395 | i2c_node = of_parse_phandle(pdev->dev.of_node, "i2c-bus", 0); |
| 396 | 396 | if (i2c_node) { |
| 397 | − struct i2c_client *client; | |
| 397 | + struct i2c_client *client = NULL; | |
| 398 | 398 | |
| 399 | +#if IS_ENABLED(CONFIG_USB_ONBOARD_DEV_USB5744) | |
| 399 | 400 | client = of_find_i2c_device_by_node(i2c_node); |
| 401 | +#endif | |
| 400 | 402 | of_node_put(i2c_node); |
| 401 | 403 | |
| 402 | 404 | if (!client) { |
| @@ -34,8 +34,6 @@ · 33 unmodified lines | ||
| 34 | 34 | #define YUREX_BUF_SIZE 8 |
| 35 | 35 | #define YUREX_WRITE_TIMEOUT (HZ*2) |
| 36 | 36 | |
| 37 | −#define MAX_S64_STRLEN 20 /* {-}922337203685477580{7,8} */ | |
| 38 | − | |
| 39 | 37 | /* table of devices that work with this driver */ |
| 40 | 38 | static struct usb_device_id yurex_table[] = { |
| 41 | 39 | { USB_DEVICE(YUREX_VENDOR_ID, YUREX_PRODUCT_ID) }, |
| @@ -402,8 +400,9 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, · 360 unmodified lines | ||
| 402 | 400 | loff_t *ppos) |
| 403 | 401 | { |
| 404 | 402 | struct usb_yurex *dev; |
| 405 | − int len = 0; | |
| 406 | − char in_buffer[MAX_S64_STRLEN]; | |
| 403 | + int len; | |
| 404 | + char in_buffer[20]; | |
| 405 | + unsigned long flags; | |
| 407 | 406 | |
| 408 | 407 | dev = file->private_data; |
| 409 | 408 | |
| @@ -413,16 +412,14 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, · 3 unmodified lines | ||
| 413 | 412 | return -ENODEV; |
| 414 | 413 | } |
| 415 | 414 | |
| 416 | − if (WARN_ON_ONCE(dev->bbu > S64_MAX || dev->bbu < S64_MIN)) { | |
| 417 | − mutex_unlock(&dev->io_mutex); | |
| 418 | − return -EIO; | |
| 419 | − } | |
| 420 | − | |
| 421 | − spin_lock_irq(&dev->lock); | |
| 422 | − scnprintf(in_buffer, MAX_S64_STRLEN, "%lld\n", dev->bbu); | |
| 423 | − spin_unlock_irq(&dev->lock); | |
| 415 | + spin_lock_irqsave(&dev->lock, flags); | |
| 416 | + len = snprintf(in_buffer, 20, "%lld\n", dev->bbu); | |
| 417 | + spin_unlock_irqrestore(&dev->lock, flags); | |
| 424 | 418 | mutex_unlock(&dev->io_mutex); |
| 425 | 419 | |
| 420 | + if (WARN_ON_ONCE(len >= sizeof(in_buffer))) | |
| 421 | + return -EIO; | |
| 422 | + | |
| 426 | 423 | return simple_read_from_buffer(buffer, count, ppos, in_buffer, len); |
| 427 | 424 | } |
| 428 | 425 | |
| @@ -279,6 +279,7 @@ static void option_instat_callback(struct urb *urb); · 278 unmodified lines | ||
| 279 | 279 | #define QUECTEL_PRODUCT_EG912Y 0x6001 |
| 280 | 280 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 |
| 281 | 281 | #define QUECTEL_PRODUCT_EC200A 0x6005 |
| 282 | +#define QUECTEL_PRODUCT_EG916Q 0x6007 | |
| 282 | 283 | #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 |
| 283 | 284 | #define QUECTEL_PRODUCT_EM061K_LCN 0x6009 |
| 284 | 285 | #define QUECTEL_PRODUCT_EC200T 0x6026 |
| @@ -1270,6 +1271,7 @@ static const struct usb_device_id option_ids[] = { · 985 unmodified lines | ||
| 1270 | 1271 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, |
| 1271 | 1272 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, |
| 1272 | 1273 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG912Y, 0xff, 0, 0) }, |
| 1274 | + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG916Q, 0xff, 0x00, 0x00) }, | |
| 1273 | 1275 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, |
| 1274 | 1276 | |
| 1275 | 1277 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, |
| @@ -1380,10 +1382,16 @@ static const struct usb_device_id option_ids[] = { · 104 unmodified lines | ||
| 1380 | 1382 | .driver_info = NCTRL(0) | RSVD(1) }, |
| 1381 | 1383 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */ |
| 1382 | 1384 | .driver_info = RSVD(0) | NCTRL(3) }, |
| 1385 | + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff), /* Telit FN920C04 (MBIM) */ | |
| 1386 | + .driver_info = NCTRL(4) }, | |
| 1383 | 1387 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ |
| 1384 | 1388 | .driver_info = RSVD(0) | NCTRL(3) }, |
| 1389 | + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff), /* Telit FN920C04 (MBIM) */ | |
| 1390 | + .driver_info = NCTRL(4) }, | |
| 1385 | 1391 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */ |
| 1386 | 1392 | .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, |
| 1393 | + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */ | |
| 1394 | + .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, | |
| 1387 | 1395 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), |
| 1388 | 1396 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, |
| 1389 | 1397 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), |
| @@ -2423,6 +2423,17 @@ UNUSUAL_DEV( 0xc251, 0x4003, 0x0100, 0x0100, · 2422 unmodified lines | ||
| 2423 | 2423 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 2424 | 2424 | US_FL_NOT_LOCKABLE), |
| 2425 | 2425 | |
| 2426 | +/* | |
| 2427 | + * Reported by Icenowy Zheng <uwu@icenowy.me> | |
| 2428 | + * This is an interface for vendor-specific cryptic commands instead | |
| 2429 | + * of real USB storage device. | |
| 2430 | + */ | |
| 2431 | +UNUSUAL_DEV( 0xe5b7, 0x0811, 0x0100, 0x0100, | |
| 2432 | + "ZhuHai JieLi Technology", | |
| 2433 | + "JieLi BR21", | |
| 2434 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 2435 | + US_FL_IGNORE_DEVICE), | |
| 2436 | + | |
| 2426 | 2437 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ |
| 2427 | 2438 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, |
| 2428 | 2439 | "DataStor", |
| @@ -519,6 +519,7 @@ static void typec_altmode_release(struct device *dev) · 518 unmodified lines | ||
| 519 | 519 | typec_altmode_put_partner(alt); |
| 520 | 520 | |
| 521 | 521 | altmode_id_remove(alt->adev.dev.parent, alt->id); |
| 522 | + put_device(alt->adev.dev.parent); | |
| 522 | 523 | kfree(alt); |
| 523 | 524 | } |
| 524 | 525 | |
| @@ -568,6 +569,8 @@ typec_register_altmode(struct device *parent, · 43 unmodified lines | ||
| 568 | 569 | alt->adev.dev.type = &typec_altmode_dev_type; |
| 569 | 570 | dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); |
| 570 | 571 | |
| 572 | + get_device(alt->adev.dev.parent); | |
| 573 | + | |
| 571 | 574 | /* Link partners and plugs with the ports */ |
| 572 | 575 | if (!is_port) |
| 573 | 576 | typec_altmode_set_partner(alt); |
| @@ -432,7 +432,6 @@ static int qcom_pmic_typec_port_get_cc(struct tcpc_dev *tcpc, · 431 unmodified lines | ||
| 432 | 432 | val = TYPEC_CC_RP_DEF; |
| 433 | 433 | break; |
| 434 | 434 | } |
| 435 | − val = TYPEC_CC_RP_DEF; | |
| 436 | 435 | } |
| 437 | 436 | |
| 438 | 437 | if (misc & CC_ORIENTATION) |
| @@ -475,11 +475,11 @@ int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev) · 474 unmodified lines | ||
| 475 | 475 | dev_err(dev, "Incomplete PCI capabilities"); |
| 476 | 476 | return -EIO; |
| 477 | 477 | } |
| 478 | − dev_info(dev, "common cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->common_cfg); | |
| 479 | − dev_info(dev, "device cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->dev_cfg); | |
| 480 | − dev_info(dev, "isr cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->isr); | |
| 481 | − dev_info(dev, "notify base: 0x%016llx, notify off multiplier: %u\n", | |
| 482 | − (u64)(uintptr_t)oct_hw->notify_base, oct_hw->notify_off_multiplier); | |
| 478 | + dev_info(dev, "common cfg mapped at: %p\n", oct_hw->common_cfg); | |
| 479 | + dev_info(dev, "device cfg mapped at: %p\n", oct_hw->dev_cfg); | |
| 480 | + dev_info(dev, "isr cfg mapped at: %p\n", oct_hw->isr); | |
| 481 | + dev_info(dev, "notify base: %p, notify off multiplier: %u\n", | |
| 482 | + oct_hw->notify_base, oct_hw->notify_off_multiplier); | |
| 483 | 483 | |
| 484 | 484 | oct_hw->config_size = octep_get_config_size(oct_hw); |
| 485 | 485 | oct_hw->features = octep_hw_get_dev_features(oct_hw); |
| @@ -511,7 +511,7 @@ int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev) · 25 unmodified lines | ||
| 511 | 511 | } |
| 512 | 512 | mbox = octep_get_mbox(oct_hw); |
| 513 | 513 | octep_mbox_init(mbox); |
| 514 | − dev_info(dev, "mbox mapped at: 0x%016llx\n", (u64)(uintptr_t)mbox); | |
| 514 | + dev_info(dev, "mbox mapped at: %p\n", mbox); | |
| 515 | 515 | |
| 516 | 516 | return 0; |
| 517 | 517 | } |
| @@ -1029,20 +1029,23 @@ vhost_scsi_get_req(struct vhost_virtqueue *vq, struct vhost_scsi_ctx *vc, · 1028 unmodified lines | ||
| 1029 | 1029 | /* virtio-scsi spec requires byte 0 of the lun to be 1 */ |
| 1030 | 1030 | vq_err(vq, "Illegal virtio-scsi lun: %u\n", *vc->lunp); |
| 1031 | 1031 | } else { |
| 1032 | − struct vhost_scsi_tpg **vs_tpg, *tpg; | |
| 1033 | − | |
| 1034 | − vs_tpg = vhost_vq_get_backend(vq); /* validated at handler entry */ | |
| 1035 | − | |
| 1036 | − tpg = READ_ONCE(vs_tpg[*vc->target]); | |
| 1037 | − if (unlikely(!tpg)) { | |
| 1038 | − vq_err(vq, "Target 0x%x does not exist\n", *vc->target); | |
| 1039 | − } else { | |
| 1040 | − if (tpgp) | |
| 1041 | − *tpgp = tpg; | |
| 1042 | − ret = 0; | |
| 1032 | + struct vhost_scsi_tpg **vs_tpg, *tpg = NULL; | |
| 1033 | + | |
| 1034 | + if (vc->target) { | |
| 1035 | + /* validated at handler entry */ | |
| 1036 | + vs_tpg = vhost_vq_get_backend(vq); | |
| 1037 | + tpg = READ_ONCE(vs_tpg[*vc->target]); | |
| 1038 | + if (unlikely(!tpg)) { | |
| 1039 | + vq_err(vq, "Target 0x%x does not exist\n", *vc->target); | |
| 1040 | + goto out; | |
| 1041 | + } | |
| 1043 | 1042 | } |
| 1044 | − } | |
| 1045 | 1043 | |
| 1044 | + if (tpgp) | |
| 1045 | + *tpgp = tpg; | |
| 1046 | + ret = 0; | |
| 1047 | + } | |
| 1048 | +out: | |
| 1046 | 1049 | return ret; |
| 1047 | 1050 | } |
| 1048 | 1051 | |
| @@ -3774,8 +3774,8 @@ static void __exit amifb_remove(struct platform_device *pdev) · 3773 unmodified lines | ||
| 3774 | 3774 | * triggers a section mismatch warning. |
| 3775 | 3775 | */ |
| 3776 | 3776 | static struct platform_driver amifb_driver __refdata = { |
| 3777 | − .remove_new = __exit_p(amifb_remove), | |
| 3778 | − .driver = { | |
| 3777 | + .remove = __exit_p(amifb_remove), | |
| 3778 | + .driver = { | |
| 3779 | 3779 | .name = "amiga-video", |
| 3780 | 3780 | }, |
| 3781 | 3781 | }; |
| @@ -548,7 +548,7 @@ static void arcfb_remove(struct platform_device *dev) · 547 unmodified lines | ||
| 548 | 548 | |
| 549 | 549 | static struct platform_driver arcfb_driver = { |
| 550 | 550 | .probe = arcfb_probe, |
| 551 | − .remove_new = arcfb_remove, | |
| 551 | + .remove = arcfb_remove, | |
| 552 | 552 | .driver = { |
| 553 | 553 | .name = "arcfb", |
| 554 | 554 | }, |
| @@ -1299,7 +1299,7 @@ static int atmel_lcdfb_resume(struct platform_device *pdev) · 1298 unmodified lines | ||
| 1299 | 1299 | |
| 1300 | 1300 | static struct platform_driver atmel_lcdfb_driver = { |
| 1301 | 1301 | .probe = atmel_lcdfb_probe, |
| 1302 | − .remove_new = atmel_lcdfb_remove, | |
| 1302 | + .remove = atmel_lcdfb_remove, | |
| 1303 | 1303 | .suspend = atmel_lcdfb_suspend, |
| 1304 | 1304 | .resume = atmel_lcdfb_resume, |
| 1305 | 1305 | .driver = { |
| @@ -588,7 +588,7 @@ static struct platform_driver au1100fb_driver = { · 587 unmodified lines | ||
| 588 | 588 | .name = "au1100-lcd", |
| 589 | 589 | }, |
| 590 | 590 | .probe = au1100fb_drv_probe, |
| 591 | − .remove_new = au1100fb_drv_remove, | |
| 591 | + .remove = au1100fb_drv_remove, | |
| 592 | 592 | .suspend = au1100fb_drv_suspend, |
| 593 | 593 | .resume = au1100fb_drv_resume, |
| 594 | 594 | }; |
| @@ -1833,7 +1833,7 @@ static struct platform_driver au1200fb_driver = { · 1832 unmodified lines | ||
| 1833 | 1833 | .pm = AU1200FB_PMOPS, |
| 1834 | 1834 | }, |
| 1835 | 1835 | .probe = au1200fb_drv_probe, |
| 1836 | − .remove_new = au1200fb_drv_remove, | |
| 1836 | + .remove = au1200fb_drv_remove, | |
| 1837 | 1837 | }; |
| 1838 | 1838 | module_platform_driver(au1200fb_driver); |
| 1839 | 1839 | |
| @@ -1151,7 +1151,7 @@ static void broadsheetfb_remove(struct platform_device *dev) · 1150 unmodified lines | ||
| 1151 | 1151 | |
| 1152 | 1152 | static struct platform_driver broadsheetfb_driver = { |
| 1153 | 1153 | .probe = broadsheetfb_probe, |
| 1154 | − .remove_new = broadsheetfb_remove, | |
| 1154 | + .remove = broadsheetfb_remove, | |
| 1155 | 1155 | .driver = { |
| 1156 | 1156 | .name = "broadsheetfb", |
| 1157 | 1157 | }, |
| @@ -372,7 +372,7 @@ static struct platform_driver bw2_driver = { · 371 unmodified lines | ||
| 372 | 372 | .of_match_table = bw2_match, |
| 373 | 373 | }, |
| 374 | 374 | .probe = bw2_probe, |
| 375 | − .remove_new = bw2_remove, | |
| 375 | + .remove = bw2_remove, | |
| 376 | 376 | }; |
| 377 | 377 | |
| 378 | 378 | static int __init bw2_init(void) |
| @@ -590,7 +590,7 @@ static struct platform_driver cg14_driver = { · 589 unmodified lines | ||
| 590 | 590 | .of_match_table = cg14_match, |
| 591 | 591 | }, |
| 592 | 592 | .probe = cg14_probe, |
| 593 | − .remove_new = cg14_remove, | |
| 593 | + .remove = cg14_remove, | |
| 594 | 594 | }; |
| 595 | 595 | |
| 596 | 596 | static int __init cg14_init(void) |
| @@ -458,7 +458,7 @@ static struct platform_driver cg3_driver = { · 457 unmodified lines | ||
| 458 | 458 | .of_match_table = cg3_match, |
| 459 | 459 | }, |
| 460 | 460 | .probe = cg3_probe, |
| 461 | − .remove_new = cg3_remove, | |
| 461 | + .remove = cg3_remove, | |
| 462 | 462 | }; |
| 463 | 463 | |
| 464 | 464 | static int __init cg3_init(void) |
| @@ -858,7 +858,7 @@ static struct platform_driver cg6_driver = { · 857 unmodified lines | ||
| 858 | 858 | .of_match_table = cg6_match, |
| 859 | 859 | }, |
| 860 | 860 | .probe = cg6_probe, |
| 861 | − .remove_new = cg6_remove, | |
| 861 | + .remove = cg6_remove, | |
| 862 | 862 | }; |
| 863 | 863 | |
| 864 | 864 | static int __init cg6_init(void) |
| @@ -371,7 +371,7 @@ static struct platform_driver clps711x_fb_driver = { · 370 unmodified lines | ||
| 371 | 371 | .of_match_table = clps711x_fb_dt_ids, |
| 372 | 372 | }, |
| 373 | 373 | .probe = clps711x_fb_probe, |
| 374 | − .remove_new = clps711x_fb_remove, | |
| 374 | + .remove = clps711x_fb_remove, | |
| 375 | 375 | }; |
| 376 | 376 | module_platform_driver(clps711x_fb_driver); |
| 377 | 377 | |
| @@ -344,7 +344,7 @@ static void cobalt_lcdfb_remove(struct platform_device *dev) · 343 unmodified lines | ||
| 344 | 344 | |
| 345 | 345 | static struct platform_driver cobalt_lcdfb_driver = { |
| 346 | 346 | .probe = cobalt_lcdfb_probe, |
| 347 | − .remove_new = cobalt_lcdfb_remove, | |
| 347 | + .remove = cobalt_lcdfb_remove, | |
| 348 | 348 | .driver = { |
| 349 | 349 | .name = "cobalt-lcd", |
| 350 | 350 | }, |
| @@ -1652,7 +1652,7 @@ static SIMPLE_DEV_PM_OPS(fb_pm_ops, fb_suspend, fb_resume); · 1651 unmodified lines | ||
| 1652 | 1652 | |
| 1653 | 1653 | static struct platform_driver da8xx_fb_driver = { |
| 1654 | 1654 | .probe = fb_probe, |
| 1655 | − .remove_new = fb_remove, | |
| 1655 | + .remove = fb_remove, | |
| 1656 | 1656 | .driver = { |
| 1657 | 1657 | .name = DRIVER_NAME, |
| 1658 | 1658 | .pm = &fb_pm_ops, |
| @@ -592,7 +592,7 @@ static void ep93xxfb_remove(struct platform_device *pdev) · 591 unmodified lines | ||
| 592 | 592 | |
| 593 | 593 | static struct platform_driver ep93xxfb_driver = { |
| 594 | 594 | .probe = ep93xxfb_probe, |
| 595 | − .remove_new = ep93xxfb_remove, | |
| 595 | + .remove = ep93xxfb_remove, | |
| 596 | 596 | .driver = { |
| 597 | 597 | .name = "ep93xx-fb", |
| 598 | 598 | }, |
| @@ -1053,7 +1053,7 @@ static struct platform_driver ffb_driver = { · 1052 unmodified lines | ||
| 1053 | 1053 | .of_match_table = ffb_match, |
| 1054 | 1054 | }, |
| 1055 | 1055 | .probe = ffb_probe, |
| 1056 | − .remove_new = ffb_remove, | |
| 1056 | + .remove = ffb_remove, | |
| 1057 | 1057 | }; |
| 1058 | 1058 | |
| 1059 | 1059 | static int __init ffb_init(void) |
| @@ -1876,12 +1876,12 @@ static const struct of_device_id fsl_diu_match[] = { · 1875 unmodified lines | ||
| 1876 | 1876 | MODULE_DEVICE_TABLE(of, fsl_diu_match); |
| 1877 | 1877 | |
| 1878 | 1878 | static struct platform_driver fsl_diu_driver = { |
| 1879 | − .driver = { | |
| 1879 | + .driver = { | |
| 1880 | 1880 | .name = "fsl-diu-fb", |
| 1881 | 1881 | .of_match_table = fsl_diu_match, |
| 1882 | 1882 | }, |
| 1883 | − .probe = fsl_diu_probe, | |
| 1884 | − .remove_new = fsl_diu_remove, | |
| 1883 | + .probe = fsl_diu_probe, | |
| 1884 | + .remove = fsl_diu_remove, | |
| 1885 | 1885 | .suspend = fsl_diu_suspend, |
| 1886 | 1886 | .resume = fsl_diu_resume, |
| 1887 | 1887 | }; |
| @@ -1247,10 +1247,10 @@ static void gbefb_remove(struct platform_device* p_dev) · 1246 unmodified lines | ||
| 1247 | 1247 | |
| 1248 | 1248 | static struct platform_driver gbefb_driver = { |
| 1249 | 1249 | .probe = gbefb_probe, |
| 1250 | − .remove_new = gbefb_remove, | |
| 1251 | − .driver = { | |
| 1250 | + .remove = gbefb_remove, | |
| 1251 | + .driver = { | |
| 1252 | 1252 | .name = "gbefb", |
| 1253 | − .dev_groups = gbefb_groups, | |
| 1253 | + .dev_groups = gbefb_groups, | |
| 1254 | 1254 | }, |
| 1255 | 1255 | }; |
| 1256 | 1256 | |
| @@ -311,7 +311,7 @@ MODULE_DEVICE_TABLE(acpi, goldfish_fb_acpi_match); · 310 unmodified lines | ||
| 311 | 311 | |
| 312 | 312 | static struct platform_driver goldfish_fb_driver = { |
| 313 | 313 | .probe = goldfish_fb_probe, |
| 314 | − .remove_new = goldfish_fb_remove, | |
| 314 | + .remove = goldfish_fb_remove, | |
| 315 | 315 | .driver = { |
| 316 | 316 | .name = "goldfish_fb", |
| 317 | 317 | .of_match_table = goldfish_fb_of_match, |
| @@ -540,7 +540,7 @@ static struct platform_driver grvga_driver = { · 539 unmodified lines | ||
| 540 | 540 | .of_match_table = svgactrl_of_match, |
| 541 | 541 | }, |
| 542 | 542 | .probe = grvga_probe, |
| 543 | − .remove_new = grvga_remove, | |
| 543 | + .remove = grvga_remove, | |
| 544 | 544 | }; |
| 545 | 545 | |
| 546 | 546 | module_platform_driver(grvga_driver); |
| @@ -235,7 +235,7 @@ static void hecubafb_remove(struct platform_device *dev) · 234 unmodified lines | ||
| 235 | 235 | |
| 236 | 236 | static struct platform_driver hecubafb_driver = { |
| 237 | 237 | .probe = hecubafb_probe, |
| 238 | − .remove_new = hecubafb_remove, | |
| 238 | + .remove = hecubafb_remove, | |
| 239 | 239 | .driver = { |
| 240 | 240 | .name = "hecubafb", |
| 241 | 241 | }, |
| @@ -629,7 +629,7 @@ static void hgafb_remove(struct platform_device *pdev) · 628 unmodified lines | ||
| 629 | 629 | |
| 630 | 630 | static struct platform_driver hgafb_driver = { |
| 631 | 631 | .probe = hgafb_probe, |
| 632 | − .remove_new = hgafb_remove, | |
| 632 | + .remove = hgafb_remove, | |
| 633 | 633 | .driver = { |
| 634 | 634 | .name = "hgafb", |
| 635 | 635 | }, |
| @@ -476,7 +476,7 @@ static const struct dev_pm_ops hitfb_dev_pm_ops = { · 475 unmodified lines | ||
| 476 | 476 | |
| 477 | 477 | static struct platform_driver hitfb_driver = { |
| 478 | 478 | .probe = hitfb_probe, |
| 479 | − .remove_new = hitfb_remove, | |
| 479 | + .remove = hitfb_remove, | |
| 480 | 480 | .driver = { |
| 481 | 481 | .name = "hitfb", |
| 482 | 482 | .pm = &hitfb_dev_pm_ops, |
| @@ -1105,7 +1105,7 @@ static struct platform_driver imxfb_driver = { · 1104 unmodified lines | ||
| 1105 | 1105 | .pm = pm_sleep_ptr(&imxfb_pm_ops), |
| 1106 | 1106 | }, |
| 1107 | 1107 | .probe = imxfb_probe, |
| 1108 | − .remove_new = imxfb_remove, | |
| 1108 | + .remove = imxfb_remove, | |
| 1109 | 1109 | .id_table = imxfb_devtype, |
| 1110 | 1110 | }; |
| 1111 | 1111 | module_platform_driver(imxfb_driver); |
| @@ -657,7 +657,7 @@ static struct platform_driver leo_driver = { · 656 unmodified lines | ||
| 657 | 657 | .of_match_table = leo_match, |
| 658 | 658 | }, |
| 659 | 659 | .probe = leo_probe, |
| 660 | − .remove_new = leo_remove, | |
| 660 | + .remove = leo_remove, | |
| 661 | 661 | }; |
| 662 | 662 | |
| 663 | 663 | static int __init leo_init(void) |
| @@ -834,7 +834,7 @@ static struct platform_driver of_platform_mb862xxfb_driver = { · 833 unmodified lines | ||
| 834 | 834 | .of_match_table = of_platform_mb862xx_tbl, |
| 835 | 835 | }, |
| 836 | 836 | .probe = of_platform_mb862xx_probe, |
| 837 | − .remove_new = of_platform_mb862xx_remove, | |
| 837 | + .remove = of_platform_mb862xx_remove, | |
| 838 | 838 | }; |
| 839 | 839 | #endif |
| 840 | 840 | |
| @@ -707,7 +707,7 @@ static void metronomefb_remove(struct platform_device *dev) · 706 unmodified lines | ||
| 707 | 707 | |
| 708 | 708 | static struct platform_driver metronomefb_driver = { |
| 709 | 709 | .probe = metronomefb_probe, |
| 710 | − .remove_new = metronomefb_remove, | |
| 710 | + .remove = metronomefb_remove, | |
| 711 | 711 | .driver = { |
| 712 | 712 | .name = "metronomefb", |
| 713 | 713 | }, |
| @@ -391,7 +391,7 @@ MODULE_DEVICE_TABLE(of, ocfb_match); · 390 unmodified lines | ||
| 391 | 391 | |
| 392 | 392 | static struct platform_driver ocfb_driver = { |
| 393 | 393 | .probe = ocfb_probe, |
| 394 | − .remove_new = ocfb_remove, | |
| 394 | + .remove = ocfb_remove, | |
| 395 | 395 | .driver = { |
| 396 | 396 | .name = "ocfb_fb", |
| 397 | 397 | .of_match_table = ocfb_match, |
| @@ -673,7 +673,7 @@ static struct platform_driver offb_driver_bootx_noscreen = { · 672 unmodified lines | ||
| 673 | 673 | .name = "bootx-noscreen", |
| 674 | 674 | }, |
| 675 | 675 | .probe = offb_probe_bootx_noscreen, |
| 676 | − .remove_new = offb_remove, | |
| 676 | + .remove = offb_remove, | |
| 677 | 677 | }; |
| 678 | 678 | |
| 679 | 679 | static int offb_probe_display(struct platform_device *pdev) |
| @@ -695,7 +695,7 @@ static struct platform_driver offb_driver_display = { · 15 unmodified lines | ||
| 695 | 695 | .of_match_table = offb_of_match_display, |
| 696 | 696 | }, |
| 697 | 697 | .probe = offb_probe_display, |
| 698 | − .remove_new = offb_remove, | |
| 698 | + .remove = offb_remove, | |
| 699 | 699 | }; |
| 700 | 700 | |
| 701 | 701 | static int __init offb_init(void) |
| @@ -1825,7 +1825,7 @@ static int omapfb_resume(struct platform_device *pdev) · 1824 unmodified lines | ||
| 1825 | 1825 | |
| 1826 | 1826 | static struct platform_driver omapfb_driver = { |
| 1827 | 1827 | .probe = omapfb_probe, |
| 1828 | − .remove_new = omapfb_remove, | |
| 1828 | + .remove = omapfb_remove, | |
| 1829 | 1829 | .suspend = omapfb_suspend, |
| 1830 | 1830 | .resume = omapfb_resume, |
| 1831 | 1831 | .driver = { |
| @@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, tvc_of_match); · 244 unmodified lines | ||
| 245 | 245 | |
| 246 | 246 | static struct platform_driver tvc_connector_driver = { |
| 247 | 247 | .probe = tvc_probe, |
| 248 | − .remove_new = tvc_remove, | |
| 248 | + .remove = tvc_remove, | |
| 249 | 249 | .driver = { |
| 250 | 250 | .name = "connector-analog-tv", |
| 251 | 251 | .of_match_table = tvc_of_match, |
| @@ -328,7 +328,7 @@ MODULE_DEVICE_TABLE(of, dvic_of_match); · 327 unmodified lines | ||
| 328 | 328 | |
| 329 | 329 | static struct platform_driver dvi_connector_driver = { |
| 330 | 330 | .probe = dvic_probe, |
| 331 | − .remove_new = dvic_remove, | |
| 331 | + .remove = dvic_remove, | |
| 332 | 332 | .driver = { |
| 333 | 333 | .name = "connector-dvi", |
| 334 | 334 | .of_match_table = dvic_of_match, |
| @@ -272,7 +272,7 @@ MODULE_DEVICE_TABLE(of, hdmic_of_match); · 271 unmodified lines | ||
| 272 | 272 | |
| 273 | 273 | static struct platform_driver hdmi_connector_driver = { |
| 274 | 274 | .probe = hdmic_probe, |
| 275 | − .remove_new = hdmic_remove, | |
| 275 | + .remove = hdmic_remove, | |
| 276 | 276 | .driver = { |
| 277 | 277 | .name = "connector-hdmi", |
| 278 | 278 | .of_match_table = hdmic_of_match, |
| @@ -258,7 +258,7 @@ MODULE_DEVICE_TABLE(of, opa362_of_match); · 257 unmodified lines | ||
| 258 | 258 | |
| 259 | 259 | static struct platform_driver opa362_driver = { |
| 260 | 260 | .probe = opa362_probe, |
| 261 | − .remove_new = opa362_remove, | |
| 261 | + .remove = opa362_remove, | |
| 262 | 262 | .driver = { |
| 263 | 263 | .name = "amplifier-opa362", |
| 264 | 264 | .of_match_table = opa362_of_match, |
| @@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, tfp410_of_match); · 244 unmodified lines | ||
| 245 | 245 | |
| 246 | 246 | static struct platform_driver tfp410_driver = { |
| 247 | 247 | .probe = tfp410_probe, |
| 248 | − .remove_new = tfp410_remove, | |
| 248 | + .remove = tfp410_remove, | |
| 249 | 249 | .driver = { |
| 250 | 250 | .name = "tfp410", |
| 251 | 251 | .of_match_table = tfp410_of_match, |
| @@ -311,7 +311,7 @@ MODULE_DEVICE_TABLE(of, tpd_of_match); · 310 unmodified lines | ||
| 311 | 311 | |
| 312 | 312 | static struct platform_driver tpd_driver = { |
| 313 | 313 | .probe = tpd_probe, |
| 314 | − .remove_new = tpd_remove, | |
| 314 | + .remove = tpd_remove, | |
| 315 | 315 | .driver = { |
| 316 | 316 | .name = "tpd12s015", |
| 317 | 317 | .of_match_table = tpd_of_match, |
| @@ -234,7 +234,7 @@ MODULE_DEVICE_TABLE(of, panel_dpi_of_match); · 233 unmodified lines | ||
| 234 | 234 | |
| 235 | 235 | static struct platform_driver panel_dpi_driver = { |
| 236 | 236 | .probe = panel_dpi_probe, |
| 237 | − .remove_new = panel_dpi_remove, | |
| 237 | + .remove = panel_dpi_remove, | |
| 238 | 238 | .driver = { |
| 239 | 239 | .name = "panel-dpi", |
| 240 | 240 | .of_match_table = panel_dpi_of_match, |
| @@ -1275,7 +1275,7 @@ MODULE_DEVICE_TABLE(of, dsicm_of_match); · 1274 unmodified lines | ||
| 1275 | 1275 | |
| 1276 | 1276 | static struct platform_driver dsicm_driver = { |
| 1277 | 1277 | .probe = dsicm_probe, |
| 1278 | − .remove_new = dsicm_remove, | |
| 1278 | + .remove = dsicm_remove, | |
| 1279 | 1279 | .driver = { |
| 1280 | 1280 | .name = "panel-dsi-cm", |
| 1281 | 1281 | .of_match_table = dsicm_of_match, |
| @@ -315,7 +315,7 @@ MODULE_DEVICE_TABLE(of, sharp_ls_of_match); · 314 unmodified lines | ||
| 315 | 315 | |
| 316 | 316 | static struct platform_driver sharp_ls_driver = { |
| 317 | 317 | .probe = sharp_ls_probe, |
| 318 | − .remove_new = sharp_ls_remove, | |
| 318 | + .remove = sharp_ls_remove, | |
| 319 | 319 | .driver = { |
| 320 | 320 | .name = "panel-sharp-ls037v7dw01", |
| 321 | 321 | .of_match_table = sharp_ls_of_match, |
| @@ -185,10 +185,10 @@ static void omap_dss_shutdown(struct platform_device *pdev) · 184 unmodified lines | ||
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | static struct platform_driver omap_dss_driver = { |
| 188 | − .remove_new = omap_dss_remove, | |
| 188 | + .remove = omap_dss_remove, | |
| 189 | 189 | .shutdown = omap_dss_shutdown, |
| 190 | − .driver = { | |
| 191 | − .name = "omapdss", | |
| 190 | + .driver = { | |
| 191 | + .name = "omapdss", | |
| 192 | 192 | }, |
| 193 | 193 | }; |
| 194 | 194 | |
| @@ -4072,7 +4072,7 @@ static const struct of_device_id dispc_of_match[] = { · 4071 unmodified lines | ||
| 4072 | 4072 | |
| 4073 | 4073 | static struct platform_driver omap_dispchw_driver = { |
| 4074 | 4074 | .probe = dispc_probe, |
| 4075 | − .remove_new = dispc_remove, | |
| 4075 | + .remove = dispc_remove, | |
| 4076 | 4076 | .driver = { |
| 4077 | 4077 | .name = "omapdss_dispc", |
| 4078 | 4078 | .pm = &dispc_pm_ops, |
| @@ -817,8 +817,8 @@ static void dpi_remove(struct platform_device *pdev) · 816 unmodified lines | ||
| 817 | 817 | |
| 818 | 818 | static struct platform_driver omap_dpi_driver = { |
| 819 | 819 | .probe = dpi_probe, |
| 820 | − .remove_new = dpi_remove, | |
| 821 | − .driver = { | |
| 820 | + .remove = dpi_remove, | |
| 821 | + .driver = { | |
| 822 | 822 | .name = "omapdss_dpi", |
| 823 | 823 | .suppress_bind_attrs = true, |
| 824 | 824 | }, |
| @@ -5565,7 +5565,7 @@ static const struct of_device_id dsi_of_match[] = { · 5564 unmodified lines | ||
| 5565 | 5565 | |
| 5566 | 5566 | static struct platform_driver omap_dsihw_driver = { |
| 5567 | 5567 | .probe = dsi_probe, |
| 5568 | − .remove_new = dsi_remove, | |
| 5568 | + .remove = dsi_remove, | |
| 5569 | 5569 | .driver = { |
| 5570 | 5570 | .name = "omapdss_dsi", |
| 5571 | 5571 | .pm = &dsi_pm_ops, |
| @@ -1278,7 +1278,7 @@ MODULE_DEVICE_TABLE(of, dss_of_match); · 1277 unmodified lines | ||
| 1278 | 1278 | |
| 1279 | 1279 | static struct platform_driver omap_dsshw_driver = { |
| 1280 | 1280 | .probe = dss_probe, |
| 1281 | − .remove_new = dss_remove, | |
| 1281 | + .remove = dss_remove, | |
| 1282 | 1282 | .driver = { |
| 1283 | 1283 | .name = "omapdss_dss", |
| 1284 | 1284 | .pm = &dss_pm_ops, |
| @@ -792,9 +792,9 @@ static const struct of_device_id hdmi_of_match[] = { · 791 unmodified lines | ||
| 792 | 792 | |
| 793 | 793 | static struct platform_driver omapdss_hdmihw_driver = { |
| 794 | 794 | .probe = hdmi4_probe, |
| 795 | − .remove_new = hdmi4_remove, | |
| 796 | − .driver = { | |
| 797 | − .name = "omapdss_hdmi", | |
| 795 | + .remove = hdmi4_remove, | |
| 796 | + .driver = { | |
| 797 | + .name = "omapdss_hdmi", | |
| 798 | 798 | .pm = &hdmi_pm_ops, |
| 799 | 799 | .of_match_table = hdmi_of_match, |
| 800 | 800 | .suppress_bind_attrs = true, |
| @@ -834,7 +834,7 @@ static const struct of_device_id hdmi_of_match[] = { · 833 unmodified lines | ||
| 834 | 834 | |
| 835 | 835 | static struct platform_driver omapdss_hdmihw_driver = { |
| 836 | 836 | .probe = hdmi5_probe, |
| 837 | − .remove_new = hdmi5_remove, | |
| 837 | + .remove = hdmi5_remove, | |
| 838 | 838 | .driver = { |
| 839 | 839 | .name = "omapdss_hdmi5", |
| 840 | 840 | .pm = &hdmi_pm_ops, |
| @@ -382,9 +382,9 @@ static void sdi_remove(struct platform_device *pdev) · 381 unmodified lines | ||
| 382 | 382 | |
| 383 | 383 | static struct platform_driver omap_sdi_driver = { |
| 384 | 384 | .probe = sdi_probe, |
| 385 | − .remove_new = sdi_remove, | |
| 386 | − .driver = { | |
| 387 | − .name = "omapdss_sdi", | |
| 385 | + .remove = sdi_remove, | |
| 386 | + .driver = { | |
| 387 | + .name = "omapdss_sdi", | |
| 388 | 388 | .suppress_bind_attrs = true, |
| 389 | 389 | }, |
| 390 | 390 | }; |
| @@ -920,9 +920,9 @@ static const struct of_device_id venc_of_match[] = { · 919 unmodified lines | ||
| 920 | 920 | |
| 921 | 921 | static struct platform_driver omap_venchw_driver = { |
| 922 | 922 | .probe = venc_probe, |
| 923 | − .remove_new = venc_remove, | |
| 924 | − .driver = { | |
| 925 | − .name = "omapdss_venc", | |
| 923 | + .remove = venc_remove, | |
| 924 | + .driver = { | |
| 925 | + .name = "omapdss_venc", | |
| 926 | 926 | .pm = &venc_pm_ops, |
| 927 | 927 | .of_match_table = venc_of_match, |
| 928 | 928 | .suppress_bind_attrs = true, |
| @@ -2614,7 +2614,7 @@ static void omapfb_remove(struct platform_device *pdev) · 2613 unmodified lines | ||
| 2614 | 2614 | |
| 2615 | 2615 | static struct platform_driver omapfb_driver = { |
| 2616 | 2616 | .probe = omapfb_probe, |
| 2617 | − .remove_new = omapfb_remove, | |
| 2617 | + .remove = omapfb_remove, | |
| 2618 | 2618 | .driver = { |
| 2619 | 2619 | .name = "omapfb", |
| 2620 | 2620 | }, |
| @@ -347,7 +347,7 @@ static struct platform_driver p9100_driver = { · 346 unmodified lines | ||
| 347 | 347 | .of_match_table = p9100_match, |
| 348 | 348 | }, |
| 349 | 349 | .probe = p9100_probe, |
| 350 | − .remove_new = p9100_remove, | |
| 350 | + .remove = p9100_remove, | |
| 351 | 351 | }; |
| 352 | 352 | |
| 353 | 353 | static int __init p9100_init(void) |
| @@ -668,7 +668,7 @@ static struct platform_driver platinum_driver = · 667 unmodified lines | ||
| 668 | 668 | .of_match_table = platinumfb_match, |
| 669 | 669 | }, |
| 670 | 670 | .probe = platinumfb_probe, |
| 671 | − .remove_new = platinumfb_remove, | |
| 671 | + .remove = platinumfb_remove, | |
| 672 | 672 | }; |
| 673 | 673 | |
| 674 | 674 | static int __init platinumfb_init(void) |
| @@ -799,7 +799,7 @@ static struct platform_driver pxa168fb_driver = { · 798 unmodified lines | ||
| 799 | 799 | .name = "pxa168-fb", |
| 800 | 800 | }, |
| 801 | 801 | .probe = pxa168fb_probe, |
| 802 | − .remove_new = pxa168fb_remove, | |
| 802 | + .remove = pxa168fb_remove, | |
| 803 | 803 | }; |
| 804 | 804 | |
| 805 | 805 | module_platform_driver(pxa168fb_driver); |
| @@ -696,10 +696,10 @@ MODULE_DEVICE_TABLE(of, pxa3xx_gcu_of_match); · 695 unmodified lines | ||
| 696 | 696 | #endif |
| 697 | 697 | |
| 698 | 698 | static struct platform_driver pxa3xx_gcu_driver = { |
| 699 | − .probe = pxa3xx_gcu_probe, | |
| 700 | − .remove_new = pxa3xx_gcu_remove, | |
| 701 | − .driver = { | |
| 702 | − .name = DRV_NAME, | |
| 699 | + .probe = pxa3xx_gcu_probe, | |
| 700 | + .remove = pxa3xx_gcu_remove, | |
| 701 | + .driver = { | |
| 702 | + .name = DRV_NAME, | |
| 703 | 703 | .of_match_table = of_match_ptr(pxa3xx_gcu_of_match), |
| 704 | 704 | }, |
| 705 | 705 | }; |
| @@ -2427,7 +2427,7 @@ MODULE_DEVICE_TABLE(of, pxafb_of_dev_id); · 2426 unmodified lines | ||
| 2427 | 2427 | |
| 2428 | 2428 | static struct platform_driver pxafb_driver = { |
| 2429 | 2429 | .probe = pxafb_probe, |
| 2430 | − .remove_new = pxafb_remove, | |
| 2430 | + .remove = pxafb_remove, | |
| 2431 | 2431 | .driver = { |
| 2432 | 2432 | .name = "pxa2xx-fb", |
| 2433 | 2433 | .of_match_table = pxafb_of_dev_id, |
| @@ -1001,7 +1001,7 @@ static int s1d13xxxfb_resume(struct platform_device *dev) · 1000 unmodified lines | ||
| 1001 | 1001 | |
| 1002 | 1002 | static struct platform_driver s1d13xxxfb_driver = { |
| 1003 | 1003 | .probe = s1d13xxxfb_probe, |
| 1004 | − .remove_new = s1d13xxxfb_remove, | |
| 1004 | + .remove = s1d13xxxfb_remove, | |
| 1005 | 1005 | #ifdef CONFIG_PM |
| 1006 | 1006 | .suspend = s1d13xxxfb_suspend, |
| 1007 | 1007 | .resume = s1d13xxxfb_resume, |
| @@ -1789,7 +1789,7 @@ static const struct dev_pm_ops s3cfb_pm_ops = { · 1788 unmodified lines | ||
| 1789 | 1789 | |
| 1790 | 1790 | static struct platform_driver s3c_fb_driver = { |
| 1791 | 1791 | .probe = s3c_fb_probe, |
| 1792 | − .remove_new = s3c_fb_remove, | |
| 1792 | + .remove = s3c_fb_remove, | |
| 1793 | 1793 | .id_table = s3c_fb_driver_ids, |
| 1794 | 1794 | .driver = { |
| 1795 | 1795 | .name = "s3c-fb", |
| @@ -575,7 +575,7 @@ static struct platform_driver sh7760_lcdc_driver = { · 574 unmodified lines | ||
| 575 | 575 | .name = "sh7760-lcdc", |
| 576 | 576 | }, |
| 577 | 577 | .probe = sh7760fb_probe, |
| 578 | − .remove_new = sh7760fb_remove, | |
| 578 | + .remove = sh7760fb_remove, | |
| 579 | 579 | }; |
| 580 | 580 | |
| 581 | 581 | module_platform_driver(sh7760_lcdc_driver); |
| @@ -2648,7 +2648,7 @@ static struct platform_driver sh_mobile_lcdc_driver = { · 2647 unmodified lines | ||
| 2648 | 2648 | .pm = &sh_mobile_lcdc_dev_pm_ops, |
| 2649 | 2649 | }, |
| 2650 | 2650 | .probe = sh_mobile_lcdc_probe, |
| 2651 | − .remove_new = sh_mobile_lcdc_remove, | |
| 2651 | + .remove = sh_mobile_lcdc_remove, | |
| 2652 | 2652 | }; |
| 2653 | 2653 | |
| 2654 | 2654 | module_platform_driver(sh_mobile_lcdc_driver); |
| @@ -677,7 +677,7 @@ static struct platform_driver simplefb_driver = { · 676 unmodified lines | ||
| 677 | 677 | .of_match_table = simplefb_of_match, |
| 678 | 678 | }, |
| 679 | 679 | .probe = simplefb_probe, |
| 680 | − .remove_new = simplefb_remove, | |
| 680 | + .remove = simplefb_remove, | |
| 681 | 681 | }; |
| 682 | 682 | |
| 683 | 683 | module_platform_driver(simplefb_driver); |
| @@ -2211,7 +2211,7 @@ static int sm501fb_resume(struct platform_device *pdev) · 2210 unmodified lines | ||
| 2211 | 2211 | |
| 2212 | 2212 | static struct platform_driver sm501fb_driver = { |
| 2213 | 2213 | .probe = sm501fb_probe, |
| 2214 | − .remove_new = sm501fb_remove, | |
| 2214 | + .remove = sm501fb_remove, | |
| 2215 | 2215 | .suspend = sm501fb_suspend, |
| 2216 | 2216 | .resume = sm501fb_resume, |
| 2217 | 2217 | .driver = { |
| @@ -505,7 +505,7 @@ static struct platform_driver tcx_driver = { · 504 unmodified lines | ||
| 505 | 505 | .of_match_table = tcx_match, |
| 506 | 506 | }, |
| 507 | 507 | .probe = tcx_probe, |
| 508 | − .remove_new = tcx_remove, | |
| 508 | + .remove = tcx_remove, | |
| 509 | 509 | }; |
| 510 | 510 | |
| 511 | 511 | static int __init tcx_init(void) |
| @@ -1794,7 +1794,7 @@ static void uvesafb_remove(struct platform_device *dev) · 1793 unmodified lines | ||
| 1794 | 1794 | |
| 1795 | 1795 | static struct platform_driver uvesafb_driver = { |
| 1796 | 1796 | .probe = uvesafb_probe, |
| 1797 | − .remove_new = uvesafb_remove, | |
| 1797 | + .remove = uvesafb_remove, | |
| 1798 | 1798 | .driver = { |
| 1799 | 1799 | .name = "uvesafb", |
| 1800 | 1800 | }, |
| @@ -515,7 +515,7 @@ static struct platform_driver vesafb_driver = { · 514 unmodified lines | ||
| 515 | 515 | .name = "vesa-framebuffer", |
| 516 | 516 | }, |
| 517 | 517 | .probe = vesafb_probe, |
| 518 | − .remove_new = vesafb_remove, | |
| 518 | + .remove = vesafb_remove, | |
| 519 | 519 | }; |
| 520 | 520 | |
| 521 | 521 | module_platform_driver(vesafb_driver); |
| @@ -493,7 +493,7 @@ static void vfb_remove(struct platform_device *dev) · 492 unmodified lines | ||
| 493 | 493 | |
| 494 | 494 | static struct platform_driver vfb_driver = { |
| 495 | 495 | .probe = vfb_probe, |
| 496 | − .remove_new = vfb_remove, | |
| 496 | + .remove = vfb_remove, | |
| 497 | 497 | .driver = { |
| 498 | 498 | .name = "vfb", |
| 499 | 499 | }, |
| @@ -1417,7 +1417,7 @@ MODULE_DEVICE_TABLE(platform, vga16fb_driver_id_table); · 1416 unmodified lines | ||
| 1417 | 1417 | |
| 1418 | 1418 | static struct platform_driver vga16fb_driver = { |
| 1419 | 1419 | .probe = vga16fb_probe, |
| 1420 | − .remove_new = vga16fb_remove, | |
| 1420 | + .remove = vga16fb_remove, | |
| 1421 | 1421 | .driver = { |
| 1422 | 1422 | .name = "vga16fb", |
| 1423 | 1423 | }, |
| @@ -292,7 +292,7 @@ static struct platform_driver via_gpio_driver = { · 291 unmodified lines | ||
| 292 | 292 | .name = "viafb-gpio", |
| 293 | 293 | }, |
| 294 | 294 | .probe = viafb_gpio_probe, |
| 295 | − .remove_new = viafb_gpio_remove, | |
| 295 | + .remove = viafb_gpio_remove, | |
| 296 | 296 | }; |
| 297 | 297 | |
| 298 | 298 | int viafb_gpio_init(void) |
| @@ -265,7 +265,7 @@ static struct platform_driver via_i2c_driver = { · 264 unmodified lines | ||
| 265 | 265 | .name = "viafb-i2c", |
| 266 | 266 | }, |
| 267 | 267 | .probe = viafb_i2c_probe, |
| 268 | − .remove_new = viafb_i2c_remove, | |
| 268 | + .remove = viafb_i2c_remove, | |
| 269 | 269 | }; |
| 270 | 270 | |
| 271 | 271 | int viafb_i2c_init(void) |
| @@ -471,7 +471,7 @@ static const struct of_device_id via_dt_ids[] = { · 470 unmodified lines | ||
| 471 | 471 | |
| 472 | 472 | static struct platform_driver vt8500lcd_driver = { |
| 473 | 473 | .probe = vt8500lcd_probe, |
| 474 | − .remove_new = vt8500lcd_remove, | |
| 474 | + .remove = vt8500lcd_remove, | |
| 475 | 475 | .driver = { |
| 476 | 476 | .name = "vt8500-lcd", |
| 477 | 477 | .of_match_table = of_match_ptr(via_dt_ids), |
| @@ -392,7 +392,7 @@ static const struct of_device_id wmt_dt_ids[] = { · 391 unmodified lines | ||
| 392 | 392 | |
| 393 | 393 | static struct platform_driver wm8505fb_driver = { |
| 394 | 394 | .probe = wm8505fb_probe, |
| 395 | − .remove_new = wm8505fb_remove, | |
| 395 | + .remove = wm8505fb_remove, | |
| 396 | 396 | .driver = { |
| 397 | 397 | .name = DRIVER_NAME, |
| 398 | 398 | .of_match_table = wmt_dt_ids, |
| @@ -159,7 +159,7 @@ static const struct of_device_id wmt_dt_ids[] = { · 158 unmodified lines | ||
| 159 | 159 | |
| 160 | 160 | static struct platform_driver wmt_ge_rops_driver = { |
| 161 | 161 | .probe = wmt_ge_rops_probe, |
| 162 | − .remove_new = wmt_ge_rops_remove, | |
| 162 | + .remove = wmt_ge_rops_remove, | |
| 163 | 163 | .driver = { |
| 164 | 164 | .name = "wmt_ge_rops", |
| 165 | 165 | .of_match_table = wmt_dt_ids, |
| @@ -488,7 +488,7 @@ MODULE_DEVICE_TABLE(of, xilinxfb_of_match); · 487 unmodified lines | ||
| 488 | 488 | |
| 489 | 489 | static struct platform_driver xilinxfb_of_driver = { |
| 490 | 490 | .probe = xilinxfb_of_probe, |
| 491 | − .remove_new = xilinxfb_of_remove, | |
| 491 | + .remove = xilinxfb_of_remove, | |
| 492 | 492 | .driver = { |
| 493 | 493 | .name = DRIVER_NAME, |
| 494 | 494 | .of_match_table = xilinxfb_of_match, |
| @@ -2588,7 +2588,7 @@ irqreturn_t vring_interrupt(int irq, void *_vq) · 2587 unmodified lines | ||
| 2588 | 2588 | |
| 2589 | 2589 | /* Just a hint for performance: so it's ok that this can be racy! */ |
| 2590 | 2590 | if (vq->event) |
| 2591 | − vq->event_triggered = true; | |
| 2591 | + data_race(vq->event_triggered = true); | |
| 2592 | 2592 | |
| 2593 | 2593 | pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback); |
| 2594 | 2594 | if (vq->vq.callback) |
| @@ -261,7 +261,6 @@ config XEN_SCSI_BACKEND · 260 unmodified lines | ||
| 261 | 261 | config XEN_PRIVCMD |
| 262 | 262 | tristate "Xen hypercall passthrough driver" |
| 263 | 263 | depends on XEN |
| 264 | − imply CONFIG_XEN_PCIDEV_BACKEND | |
| 265 | 264 | default m |
| 266 | 265 | help |
| 267 | 266 | The hypercall passthrough driver allows privileged user programs to |
| @@ -125,3 +125,27 @@ int xen_acpi_get_gsi_info(struct pci_dev *dev, · 124 unmodified lines | ||
| 125 | 125 | return 0; |
| 126 | 126 | } |
| 127 | 127 | EXPORT_SYMBOL_GPL(xen_acpi_get_gsi_info); |
| 128 | + | |
| 129 | +static get_gsi_from_sbdf_t get_gsi_from_sbdf; | |
| 130 | +static DEFINE_RWLOCK(get_gsi_from_sbdf_lock); | |
| 131 | + | |
| 132 | +void xen_acpi_register_get_gsi_func(get_gsi_from_sbdf_t func) | |
| 133 | +{ | |
| 134 | + write_lock(&get_gsi_from_sbdf_lock); | |
| 135 | + get_gsi_from_sbdf = func; | |
| 136 | + write_unlock(&get_gsi_from_sbdf_lock); | |
| 137 | +} | |
| 138 | +EXPORT_SYMBOL_GPL(xen_acpi_register_get_gsi_func); | |
| 139 | + | |
| 140 | +int xen_acpi_get_gsi_from_sbdf(u32 sbdf) | |
| 141 | +{ | |
| 142 | + int ret = -EOPNOTSUPP; | |
| 143 | + | |
| 144 | + read_lock(&get_gsi_from_sbdf_lock); | |
| 145 | + if (get_gsi_from_sbdf) | |
| 146 | + ret = get_gsi_from_sbdf(sbdf); | |
| 147 | + read_unlock(&get_gsi_from_sbdf_lock); | |
| 148 | + | |
| 149 | + return ret; | |
| 150 | +} | |
| 151 | +EXPORT_SYMBOL_GPL(xen_acpi_get_gsi_from_sbdf); | |
| @@ -850,15 +850,13 @@ out: · 849 unmodified lines | ||
| 850 | 850 | static long privcmd_ioctl_pcidev_get_gsi(struct file *file, void __user *udata) |
| 851 | 851 | { |
| 852 | 852 | #if defined(CONFIG_XEN_ACPI) |
| 853 | − int rc = -EINVAL; | |
| 853 | + int rc; | |
| 854 | 854 | struct privcmd_pcidev_get_gsi kdata; |
| 855 | 855 | |
| 856 | 856 | if (copy_from_user(&kdata, udata, sizeof(kdata))) |
| 857 | 857 | return -EFAULT; |
| 858 | 858 | |
| 859 | − if (IS_REACHABLE(CONFIG_XEN_PCIDEV_BACKEND)) | |
| 860 | − rc = pcistub_get_gsi_from_sbdf(kdata.sbdf); | |
| 861 | − | |
| 859 | + rc = xen_acpi_get_gsi_from_sbdf(kdata.sbdf); | |
| 862 | 860 | if (rc < 0) |
| 863 | 861 | return rc; |
| 864 | 862 | |
| @@ -227,7 +227,7 @@ static struct pci_dev *pcistub_device_get_pci_dev(struct xen_pcibk_device *pdev, · 226 unmodified lines | ||
| 227 | 227 | } |
| 228 | 228 | |
| 229 | 229 | #ifdef CONFIG_XEN_ACPI |
| 230 | −int pcistub_get_gsi_from_sbdf(unsigned int sbdf) | |
| 230 | +static int pcistub_get_gsi_from_sbdf(unsigned int sbdf) | |
| 231 | 231 | { |
| 232 | 232 | struct pcistub_device *psdev; |
| 233 | 233 | int domain = (sbdf >> 16) & 0xffff; |
| @@ -242,7 +242,6 @@ int pcistub_get_gsi_from_sbdf(unsigned int sbdf) · 8 unmodified lines | ||
| 242 | 242 | |
| 243 | 243 | return psdev->gsi; |
| 244 | 244 | } |
| 245 | −EXPORT_SYMBOL_GPL(pcistub_get_gsi_from_sbdf); | |
| 246 | 245 | #endif |
| 247 | 246 | |
| 248 | 247 | struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev, |
| @@ -1757,11 +1756,19 @@ static int __init xen_pcibk_init(void) · 1508 unmodified lines | ||
| 1757 | 1756 | bus_register_notifier(&pci_bus_type, &pci_stub_nb); |
| 1758 | 1757 | #endif |
| 1759 | 1758 | |
| 1759 | +#ifdef CONFIG_XEN_ACPI | |
| 1760 | + xen_acpi_register_get_gsi_func(pcistub_get_gsi_from_sbdf); | |
| 1761 | +#endif | |
| 1762 | + | |
| 1760 | 1763 | return err; |
| 1761 | 1764 | } |
| 1762 | 1765 | |
| 1763 | 1766 | static void __exit xen_pcibk_cleanup(void) |
| 1764 | 1767 | { |
| 1768 | +#ifdef CONFIG_XEN_ACPI | |
| 1769 | + xen_acpi_register_get_gsi_func(NULL); | |
| 1770 | +#endif | |
| 1771 | + | |
| 1765 | 1772 | #ifdef CONFIG_PCI_IOV |
| 1766 | 1773 | bus_unregister_notifier(&pci_bus_type, &pci_stub_nb); |
| 1767 | 1774 | #endif |
| @@ -131,10 +131,9 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) · 130 unmodified lines | ||
| 131 | 131 | } |
| 132 | 132 | } |
| 133 | 133 | spin_unlock(&dentry->d_lock); |
| 134 | − } else { | |
| 135 | − if (dentry->d_inode) | |
| 136 | − ret = v9fs_fid_find_inode(dentry->d_inode, false, uid, any); | |
| 137 | 134 | } |
| 135 | + if (!ret && dentry->d_inode) | |
| 136 | + ret = v9fs_fid_find_inode(dentry->d_inode, false, uid, any); | |
| 138 | 137 | |
| 139 | 138 | return ret; |
| 140 | 139 | } |
| @@ -388,7 +388,7 @@ config NFS_COMMON · 387 unmodified lines | ||
| 388 | 388 | |
| 389 | 389 | config NFS_COMMON_LOCALIO_SUPPORT |
| 390 | 390 | tristate |
| 391 | − default n | |
| 391 | + depends on NFS_LOCALIO | |
| 392 | 392 | default y if NFSD=y || NFS_FS=y |
| 393 | 393 | default m if NFSD=m && NFS_FS=m |
| 394 | 394 | select SUNRPC |
| @@ -130,6 +130,7 @@ struct afs_call { · 129 unmodified lines | ||
| 130 | 130 | wait_queue_head_t waitq; /* processes awaiting completion */ |
| 131 | 131 | struct work_struct async_work; /* async I/O processor */ |
| 132 | 132 | struct work_struct work; /* actual work processor */ |
| 133 | + struct work_struct free_work; /* Deferred free processor */ | |
| 133 | 134 | struct rxrpc_call *rxcall; /* RxRPC call handle */ |
| 134 | 135 | struct rxrpc_peer *peer; /* Remote endpoint */ |
| 135 | 136 | struct key *key; /* security for this call */ |
| @@ -1331,6 +1332,7 @@ extern int __net_init afs_open_socket(struct afs_net *); · 1195 unmodified lines | ||
| 1331 | 1332 | extern void __net_exit afs_close_socket(struct afs_net *); |
| 1332 | 1333 | extern void afs_charge_preallocation(struct work_struct *); |
| 1333 | 1334 | extern void afs_put_call(struct afs_call *); |
| 1335 | +void afs_deferred_put_call(struct afs_call *call); | |
| 1334 | 1336 | void afs_make_call(struct afs_call *call, gfp_t gfp); |
| 1335 | 1337 | void afs_wait_for_call_to_complete(struct afs_call *call); |
| 1336 | 1338 | extern struct afs_call *afs_alloc_flat_call(struct afs_net *, |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | struct workqueue_struct *afs_async_calls; |
| 20 | 20 | |
| 21 | +static void afs_deferred_free_worker(struct work_struct *work); | |
| 21 | 22 | static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); |
| 22 | 23 | static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); |
| 23 | 24 | static void afs_process_async_call(struct work_struct *); |
| @@ -149,6 +150,7 @@ static struct afs_call *afs_alloc_call(struct afs_net *net, · 125 unmodified lines | ||
| 149 | 150 | call->debug_id = atomic_inc_return(&rxrpc_debug_id); |
| 150 | 151 | refcount_set(&call->ref, 1); |
| 151 | 152 | INIT_WORK(&call->async_work, afs_process_async_call); |
| 153 | + INIT_WORK(&call->free_work, afs_deferred_free_worker); | |
| 152 | 154 | init_waitqueue_head(&call->waitq); |
| 153 | 155 | spin_lock_init(&call->state_lock); |
| 154 | 156 | call->iter = &call->def_iter; |
| @@ -159,6 +161,36 @@ static struct afs_call *afs_alloc_call(struct afs_net *net, · 4 unmodified lines | ||
| 159 | 161 | return call; |
| 160 | 162 | } |
| 161 | 163 | |
| 164 | +static void afs_free_call(struct afs_call *call) | |
| 165 | +{ | |
| 166 | + struct afs_net *net = call->net; | |
| 167 | + int o; | |
| 168 | + | |
| 169 | + ASSERT(!work_pending(&call->async_work)); | |
| 170 | + | |
| 171 | + rxrpc_kernel_put_peer(call->peer); | |
| 172 | + | |
| 173 | + if (call->rxcall) { | |
| 174 | + rxrpc_kernel_shutdown_call(net->socket, call->rxcall); | |
| 175 | + rxrpc_kernel_put_call(net->socket, call->rxcall); | |
| 176 | + call->rxcall = NULL; | |
| 177 | + } | |
| 178 | + if (call->type->destructor) | |
| 179 | + call->type->destructor(call); | |
| 180 | + | |
| 181 | + afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call); | |
| 182 | + kfree(call->request); | |
| 183 | + | |
| 184 | + o = atomic_read(&net->nr_outstanding_calls); | |
| 185 | + trace_afs_call(call->debug_id, afs_call_trace_free, 0, o, | |
| 186 | + __builtin_return_address(0)); | |
| 187 | + kfree(call); | |
| 188 | + | |
| 189 | + o = atomic_dec_return(&net->nr_outstanding_calls); | |
| 190 | + if (o == 0) | |
| 191 | + wake_up_var(&net->nr_outstanding_calls); | |
| 192 | +} | |
| 193 | + | |
| 162 | 194 | /* |
| 163 | 195 | * Dispose of a reference on a call. |
| 164 | 196 | */ |
| @@ -173,32 +205,34 @@ void afs_put_call(struct afs_call *call) · 8 unmodified lines | ||
| 173 | 205 | o = atomic_read(&net->nr_outstanding_calls); |
| 174 | 206 | trace_afs_call(debug_id, afs_call_trace_put, r - 1, o, |
| 175 | 207 | __builtin_return_address(0)); |
| 208 | + if (zero) | |
| 209 | + afs_free_call(call); | |
| 210 | +} | |
| 176 | 211 | |
| 177 | − if (zero) { | |
| 178 | − ASSERT(!work_pending(&call->async_work)); | |
| 179 | − ASSERT(call->type->name != NULL); | |
| 180 | − | |
| 181 | − rxrpc_kernel_put_peer(call->peer); | |
| 182 | − | |
| 183 | − if (call->rxcall) { | |
| 184 | − rxrpc_kernel_shutdown_call(net->socket, call->rxcall); | |
| 185 | − rxrpc_kernel_put_call(net->socket, call->rxcall); | |
| 186 | − call->rxcall = NULL; | |
| 187 | − } | |
| 188 | − if (call->type->destructor) | |
| 189 | − call->type->destructor(call); | |
| 212 | +static void afs_deferred_free_worker(struct work_struct *work) | |
| 213 | +{ | |
| 214 | + struct afs_call *call = container_of(work, struct afs_call, free_work); | |
| 190 | 215 | |
| 191 | − afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call); | |
| 192 | − kfree(call->request); | |
| 216 | + afs_free_call(call); | |
| 217 | +} | |
| 193 | 218 | |
| 194 | − trace_afs_call(call->debug_id, afs_call_trace_free, 0, o, | |
| 195 | − __builtin_return_address(0)); | |
| 196 | − kfree(call); | |
| 219 | +/* | |
| 220 | + * Dispose of a reference on a call, deferring the cleanup to a workqueue | |
| 221 | + * to avoid lock recursion. | |
| 222 | + */ | |
| 223 | +void afs_deferred_put_call(struct afs_call *call) | |
| 224 | +{ | |
| 225 | + struct afs_net *net = call->net; | |
| 226 | + unsigned int debug_id = call->debug_id; | |
| 227 | + bool zero; | |
| 228 | + int r, o; | |
| 197 | 229 | |
| 198 | − o = atomic_dec_return(&net->nr_outstanding_calls); | |
| 199 | − if (o == 0) | |
| 200 | − wake_up_var(&net->nr_outstanding_calls); | |
| 201 | − } | |
| 230 | + zero = __refcount_dec_and_test(&call->ref, &r); | |
| 231 | + o = atomic_read(&net->nr_outstanding_calls); | |
| 232 | + trace_afs_call(debug_id, afs_call_trace_put, r - 1, o, | |
| 233 | + __builtin_return_address(0)); | |
| 234 | + if (zero) | |
| 235 | + schedule_work(&call->free_work); | |
| 202 | 236 | } |
| 203 | 237 | |
| 204 | 238 | static struct afs_call *afs_get_call(struct afs_call *call, |
| @@ -640,7 +674,8 @@ static void afs_wake_up_call_waiter(struct sock *sk, struct rxrpc_call *rxcall, · 435 unmodified lines | ||
| 640 | 674 | } |
| 641 | 675 | |
| 642 | 676 | /* |
| 643 | − * wake up an asynchronous call | |
| 677 | + * Wake up an asynchronous call. The caller is holding the call notify | |
| 678 | + * spinlock around this, so we can't call afs_put_call(). | |
| 644 | 679 | */ |
| 645 | 680 | static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall, |
| 646 | 681 | unsigned long call_user_ID) |
| @@ -657,7 +692,7 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall, · 10 unmodified lines | ||
| 657 | 692 | __builtin_return_address(0)); |
| 658 | 693 | |
| 659 | 694 | if (!queue_work(afs_async_calls, &call->async_work)) |
| 660 | − afs_put_call(call); | |
| 695 | + afs_deferred_put_call(call); | |
| 661 | 696 | } |
| 662 | 697 | } |
| 663 | 698 | |
| @@ -332,7 +332,6 @@ void bch2_alloc_v4_swab(struct bkey_s k) · 331 unmodified lines | ||
| 332 | 332 | a->io_time[1] = swab64(a->io_time[1]); |
| 333 | 333 | a->stripe = swab32(a->stripe); |
| 334 | 334 | a->nr_external_backpointers = swab32(a->nr_external_backpointers); |
| 335 | − a->fragmentation_lru = swab64(a->fragmentation_lru); | |
| 336 | 335 | a->stripe_sectors = swab32(a->stripe_sectors); |
| 337 | 336 | |
| 338 | 337 | bps = alloc_v4_backpointers(a); |
| @@ -347,6 +346,7 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c · 8 unmodified lines | ||
| 347 | 346 | { |
| 348 | 347 | struct bch_alloc_v4 _a; |
| 349 | 348 | const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a); |
| 349 | + struct bch_dev *ca = c ? bch2_dev_bucket_tryget_noerror(c, k.k->p) : NULL; | |
| 350 | 350 | |
| 351 | 351 | prt_newline(out); |
| 352 | 352 | printbuf_indent_add(out, 2); |
| @@ -364,9 +364,13 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c · 11 unmodified lines | ||
| 364 | 364 | prt_printf(out, "stripe_redundancy %u\n", a->stripe_redundancy); |
| 365 | 365 | prt_printf(out, "io_time[READ] %llu\n", a->io_time[READ]); |
| 366 | 366 | prt_printf(out, "io_time[WRITE] %llu\n", a->io_time[WRITE]); |
| 367 | − prt_printf(out, "fragmentation %llu\n", a->fragmentation_lru); | |
| 367 | + | |
| 368 | + if (ca) | |
| 369 | + prt_printf(out, "fragmentation %llu\n", alloc_lru_idx_fragmentation(*a, ca)); | |
| 368 | 370 | prt_printf(out, "bp_start %llu\n", BCH_ALLOC_V4_BACKPOINTERS_START(a)); |
| 369 | 371 | printbuf_indent_sub(out, 2); |
| 372 | + | |
| 373 | + bch2_dev_put(ca); | |
| 370 | 374 | } |
| 371 | 375 | |
| 372 | 376 | void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out) |
| @@ -635,6 +639,16 @@ int bch2_alloc_read(struct bch_fs *c) · 262 unmodified lines | ||
| 635 | 639 | continue; |
| 636 | 640 | } |
| 637 | 641 | |
| 642 | + if (k.k->p.offset < ca->mi.first_bucket) { | |
| 643 | + bch2_btree_iter_set_pos(&iter, POS(k.k->p.inode, ca->mi.first_bucket)); | |
| 644 | + continue; | |
| 645 | + } | |
| 646 | + | |
| 647 | + if (k.k->p.offset >= ca->mi.nbuckets) { | |
| 648 | + bch2_btree_iter_set_pos(&iter, POS(k.k->p.inode + 1, 0)); | |
| 649 | + continue; | |
| 650 | + } | |
| 651 | + | |
| 638 | 652 | struct bch_alloc_v4 a; |
| 639 | 653 | *bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen; |
| 640 | 654 | 0; |
| @@ -882,12 +896,13 @@ int bch2_trigger_alloc(struct btree_trans *trans, · 241 unmodified lines | ||
| 882 | 896 | goto err; |
| 883 | 897 | } |
| 884 | 898 | |
| 885 | − new_a->fragmentation_lru = alloc_lru_idx_fragmentation(*new_a, ca); | |
| 886 | − if (old_a->fragmentation_lru != new_a->fragmentation_lru) { | |
| 899 | + old_lru = alloc_lru_idx_fragmentation(*old_a, ca); | |
| 900 | + new_lru = alloc_lru_idx_fragmentation(*new_a, ca); | |
| 901 | + if (old_lru != new_lru) { | |
| 887 | 902 | ret = bch2_lru_change(trans, |
| 888 | 903 | BCH_LRU_FRAGMENTATION_START, |
| 889 | 904 | bucket_to_u64(new.k->p), |
| 890 | − old_a->fragmentation_lru, new_a->fragmentation_lru); | |
| 905 | + old_lru, new_lru); | |
| 891 | 906 | if (ret) |
| 892 | 907 | goto err; |
| 893 | 908 | } |
| @@ -1629,18 +1644,22 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans, · 735 unmodified lines | ||
| 1629 | 1644 | if (ret) |
| 1630 | 1645 | return ret; |
| 1631 | 1646 | |
| 1647 | + struct bch_dev *ca = bch2_dev_tryget_noerror(c, alloc_k.k->p.inode); | |
| 1648 | + if (!ca) | |
| 1649 | + return 0; | |
| 1650 | + | |
| 1632 | 1651 | a = bch2_alloc_to_v4(alloc_k, &a_convert); |
| 1633 | 1652 | |
| 1634 | − if (a->fragmentation_lru) { | |
| 1653 | + u64 lru_idx = alloc_lru_idx_fragmentation(*a, ca); | |
| 1654 | + if (lru_idx) { | |
| 1635 | 1655 | ret = bch2_lru_check_set(trans, BCH_LRU_FRAGMENTATION_START, |
| 1636 | − a->fragmentation_lru, | |
| 1637 | − alloc_k, last_flushed); | |
| 1656 | + lru_idx, alloc_k, last_flushed); | |
| 1638 | 1657 | if (ret) |
| 1639 | − return ret; | |
| 1658 | + goto err; | |
| 1640 | 1659 | } |
| 1641 | 1660 | |
| 1642 | 1661 | if (a->data_type != BCH_DATA_cached) |
| 1643 | − return 0; | |
| 1662 | + goto err; | |
| 1644 | 1663 | |
| 1645 | 1664 | if (fsck_err_on(!a->io_time[READ], |
| 1646 | 1665 | trans, alloc_key_cached_but_read_time_zero, |
| @@ -1669,6 +1688,7 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans, · 22 unmodified lines | ||
| 1669 | 1688 | goto err; |
| 1670 | 1689 | err: |
| 1671 | 1690 | fsck_err: |
| 1691 | + bch2_dev_put(ca); | |
| 1672 | 1692 | printbuf_exit(&buf); |
| 1673 | 1693 | return ret; |
| 1674 | 1694 | } |
| @@ -1957,7 +1977,7 @@ static void bch2_do_discards_fast_work(struct work_struct *work) · 282 unmodified lines | ||
| 1957 | 1977 | ca->mi.bucket_size, |
| 1958 | 1978 | GFP_KERNEL); |
| 1959 | 1979 | |
| 1960 | − int ret = bch2_trans_do(c, NULL, NULL, | |
| 1980 | + int ret = bch2_trans_commit_do(c, NULL, NULL, | |
| 1961 | 1981 | BCH_WATERMARK_btree| |
| 1962 | 1982 | BCH_TRANS_COMMIT_no_enospc, |
| 1963 | 1983 | bch2_clear_bucket_needs_discard(trans, POS(ca->dev_idx, bucket))); |
| @@ -2117,14 +2137,15 @@ static void bch2_do_invalidates_work(struct work_struct *work) · 153 unmodified lines | ||
| 2117 | 2137 | |
| 2118 | 2138 | struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped); |
| 2119 | 2139 | ret = bkey_err(k); |
| 2120 | − if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) | |
| 2121 | − continue; | |
| 2122 | 2140 | if (ret) |
| 2123 | − break; | |
| 2141 | + goto restart_err; | |
| 2124 | 2142 | if (!k.k) |
| 2125 | 2143 | break; |
| 2126 | 2144 | |
| 2127 | 2145 | ret = invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate); |
| 2146 | +restart_err: | |
| 2147 | + if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) | |
| 2148 | + continue; | |
| 2128 | 2149 | if (ret) |
| 2129 | 2150 | break; |
| 2130 | 2151 | |
| @@ -2330,24 +2351,19 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca) · 199 unmodified lines | ||
| 2330 | 2351 | |
| 2331 | 2352 | /* Bucket IO clocks: */ |
| 2332 | 2353 | |
| 2333 | −int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev, | |
| 2334 | − size_t bucket_nr, int rw) | |
| 2354 | +static int __bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev, | |
| 2355 | + size_t bucket_nr, int rw) | |
| 2335 | 2356 | { |
| 2336 | 2357 | struct bch_fs *c = trans->c; |
| 2337 | − struct btree_iter iter; | |
| 2338 | − struct bkey_i_alloc_v4 *a; | |
| 2339 | − u64 now; | |
| 2340 | − int ret = 0; | |
| 2341 | 2358 | |
| 2342 | − if (bch2_trans_relock(trans)) | |
| 2343 | − bch2_trans_begin(trans); | |
| 2344 | − | |
| 2345 | − a = bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(dev, bucket_nr)); | |
| 2346 | − ret = PTR_ERR_OR_ZERO(a); | |
| 2359 | + struct btree_iter iter; | |
| 2360 | + struct bkey_i_alloc_v4 *a = | |
| 2361 | + bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(dev, bucket_nr)); | |
| 2362 | + int ret = PTR_ERR_OR_ZERO(a); | |
| 2347 | 2363 | if (ret) |
| 2348 | 2364 | return ret; |
| 2349 | 2365 | |
| 2350 | − now = bch2_current_io_time(c, rw); | |
| 2366 | + u64 now = bch2_current_io_time(c, rw); | |
| 2351 | 2367 | if (a->v.io_time[rw] == now) |
| 2352 | 2368 | goto out; |
| 2353 | 2369 | |
| @@ -2360,6 +2376,15 @@ out: · 6 unmodified lines | ||
| 2360 | 2376 | return ret; |
| 2361 | 2377 | } |
| 2362 | 2378 | |
| 2379 | +int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev, | |
| 2380 | + size_t bucket_nr, int rw) | |
| 2381 | +{ | |
| 2382 | + if (bch2_trans_relock(trans)) | |
| 2383 | + bch2_trans_begin(trans); | |
| 2384 | + | |
| 2385 | + return nested_lockrestart_do(trans, __bch2_bucket_io_time_reset(trans, dev, bucket_nr, rw)); | |
| 2386 | +} | |
| 2387 | + | |
| 2363 | 2388 | /* Startup/shutdown (ro/rw): */ |
| 2364 | 2389 | |
| 2365 | 2390 | void bch2_recalc_capacity(struct bch_fs *c) |
| @@ -70,7 +70,7 @@ struct bch_alloc_v4 { · 69 unmodified lines | ||
| 70 | 70 | __u32 stripe; |
| 71 | 71 | __u32 nr_external_backpointers; |
| 72 | 72 | /* end of fields in original version of alloc_v4 */ |
| 73 | − __u64 fragmentation_lru; | |
| 73 | + __u64 _fragmentation_lru; /* obsolete */ | |
| 74 | 74 | __u32 stripe_sectors; |
| 75 | 75 | __u32 pad; |
| 76 | 76 | } __packed __aligned(8); |
| @@ -684,7 +684,7 @@ struct open_bucket *bch2_bucket_alloc(struct bch_fs *c, struct bch_dev *ca, · 683 unmodified lines | ||
| 684 | 684 | struct bch_dev_usage usage; |
| 685 | 685 | struct open_bucket *ob; |
| 686 | 686 | |
| 687 | − bch2_trans_do(c, NULL, NULL, 0, | |
| 687 | + bch2_trans_do(c, | |
| 688 | 688 | PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(trans, ca, watermark, |
| 689 | 689 | data_type, cl, false, &usage))); |
| 690 | 690 | return ob; |
| @@ -678,7 +678,8 @@ struct bch_sb_field_ext { · 677 unmodified lines | ||
| 678 | 678 | x(disk_accounting_v2, BCH_VERSION(1, 9)) \ |
| 679 | 679 | x(disk_accounting_v3, BCH_VERSION(1, 10)) \ |
| 680 | 680 | x(disk_accounting_inum, BCH_VERSION(1, 11)) \ |
| 681 | − x(rebalance_work_acct_fix, BCH_VERSION(1, 12)) | |
| 681 | + x(rebalance_work_acct_fix, BCH_VERSION(1, 12)) \ | |
| 682 | + x(inode_has_child_snapshots, BCH_VERSION(1, 13)) | |
| 682 | 683 | |
| 683 | 684 | enum bcachefs_metadata_version { |
| 684 | 685 | bcachefs_metadata_version_min = 9, |
| @@ -820,15 +820,23 @@ static int bch2_alloc_write_key(struct btree_trans *trans, · 819 unmodified lines | ||
| 820 | 820 | * fix that here: |
| 821 | 821 | */ |
| 822 | 822 | alloc_data_type_set(&gc, gc.data_type); |
| 823 | − | |
| 824 | 823 | if (gc.data_type != old_gc.data_type || |
| 825 | 824 | gc.dirty_sectors != old_gc.dirty_sectors) { |
| 826 | 825 | ret = bch2_alloc_key_to_dev_counters(trans, ca, &old_gc, &gc, BTREE_TRIGGER_gc); |
| 827 | 826 | if (ret) |
| 828 | 827 | return ret; |
| 829 | − } | |
| 830 | 828 | |
| 831 | − gc.fragmentation_lru = alloc_lru_idx_fragmentation(gc, ca); | |
| 829 | + /* | |
| 830 | + * Ugly: alloc_key_to_dev_counters(..., BTREE_TRIGGER_gc) is not | |
| 831 | + * safe w.r.t. transaction restarts, so fixup the gc_bucket so | |
| 832 | + * we don't run it twice: | |
| 833 | + */ | |
| 834 | + percpu_down_read(&c->mark_lock); | |
| 835 | + struct bucket *gc_m = gc_bucket(ca, iter->pos.offset); | |
| 836 | + gc_m->data_type = gc.data_type; | |
| 837 | + gc_m->dirty_sectors = gc.dirty_sectors; | |
| 838 | + percpu_up_read(&c->mark_lock); | |
| 839 | + } | |
| 832 | 840 | |
| 833 | 841 | if (fsck_err_on(new.data_type != gc.data_type, |
| 834 | 842 | trans, alloc_key_data_type_wrong, |
| @@ -857,7 +865,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans, · 22 unmodified lines | ||
| 857 | 865 | copy_bucket_field(alloc_key_cached_sectors_wrong, cached_sectors); |
| 858 | 866 | copy_bucket_field(alloc_key_stripe_wrong, stripe); |
| 859 | 867 | copy_bucket_field(alloc_key_stripe_redundancy_wrong, stripe_redundancy); |
| 860 | − copy_bucket_field(alloc_key_fragmentation_lru_wrong, fragmentation_lru); | |
| 861 | 868 | #undef copy_bucket_field |
| 862 | 869 | |
| 863 | 870 | if (!bch2_alloc_v4_cmp(*old, new)) |
| @@ -1227,17 +1234,20 @@ int bch2_gc_gens(struct bch_fs *c) · 363 unmodified lines | ||
| 1227 | 1234 | u64 b, start_time = local_clock(); |
| 1228 | 1235 | int ret; |
| 1229 | 1236 | |
| 1230 | − /* | |
| 1231 | − * Ideally we would be using state_lock and not gc_gens_lock here, but that | |
| 1232 | − * introduces a deadlock in the RO path - we currently take the state | |
| 1233 | − * lock at the start of going RO, thus the gc thread may get stuck: | |
| 1234 | − */ | |
| 1235 | 1237 | if (!mutex_trylock(&c->gc_gens_lock)) |
| 1236 | 1238 | return 0; |
| 1237 | 1239 | |
| 1238 | 1240 | trace_and_count(c, gc_gens_start, c); |
| 1239 | 1241 | |
| 1240 | − down_read(&c->state_lock); | |
| 1242 | + /* | |
| 1243 | + * We have to use trylock here. Otherwise, we would | |
| 1244 | + * introduce a deadlock in the RO path - we take the | |
| 1245 | + * state lock at the start of going RO. | |
| 1246 | + */ | |
| 1247 | + if (!down_read_trylock(&c->state_lock)) { | |
| 1248 | + mutex_unlock(&c->gc_gens_lock); | |
| 1249 | + return 0; | |
| 1250 | + } | |
| 1241 | 1251 | |
| 1242 | 1252 | for_each_member_device(c, ca) { |
| 1243 | 1253 | struct bucket_gens *gens = bucket_gens(ca); |
| @@ -1838,10 +1838,11 @@ static void btree_node_write_done(struct bch_fs *c, struct btree *b) · 1837 unmodified lines | ||
| 1838 | 1838 | struct btree_trans *trans = bch2_trans_get(c); |
| 1839 | 1839 | |
| 1840 | 1840 | btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read); |
| 1841 | − __btree_node_write_done(c, b); | |
| 1842 | − six_unlock_read(&b->c.lock); | |
| 1843 | 1841 | |
| 1842 | + /* we don't need transaction context anymore after we got the lock. */ | |
| 1844 | 1843 | bch2_trans_put(trans); |
| 1844 | + __btree_node_write_done(c, b); | |
| 1845 | + six_unlock_read(&b->c.lock); | |
| 1845 | 1846 | } |
| 1846 | 1847 | |
| 1847 | 1848 | static void btree_node_write_work(struct work_struct *work) |
| @@ -1870,7 +1871,7 @@ static void btree_node_write_work(struct work_struct *work) · 22 unmodified lines | ||
| 1870 | 1871 | |
| 1871 | 1872 | } |
| 1872 | 1873 | } else { |
| 1873 | − ret = bch2_trans_do(c, NULL, NULL, 0, | |
| 1874 | + ret = bch2_trans_do(c, | |
| 1874 | 1875 | bch2_btree_node_update_key_get_iter(trans, b, &wbio->key, |
| 1875 | 1876 | BCH_WATERMARK_interior_updates| |
| 1876 | 1877 | BCH_TRANS_COMMIT_journal_reclaim| |
| @@ -2381,9 +2381,9 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e · 2380 unmodified lines | ||
| 2381 | 2381 | else |
| 2382 | 2382 | iter_pos = bkey_max(iter->pos, bkey_start_pos(k.k)); |
| 2383 | 2383 | |
| 2384 | − if (unlikely(!(iter->flags & BTREE_ITER_is_extents) | |
| 2385 | − ? bkey_gt(iter_pos, end) | |
| 2386 | − : bkey_ge(iter_pos, end))) | |
| 2384 | + if (unlikely(iter->flags & BTREE_ITER_all_snapshots ? bpos_gt(iter_pos, end) : | |
| 2385 | + iter->flags & BTREE_ITER_is_extents ? bkey_ge(iter_pos, end) : | |
| 2386 | + bkey_gt(iter_pos, end))) | |
| 2387 | 2387 | goto end; |
| 2388 | 2388 | |
| 2389 | 2389 | break; |
| @@ -857,6 +857,14 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *); · 856 unmodified lines | ||
| 857 | 857 | for_each_btree_key_upto_norestart(_trans, _iter, _btree_id, _start,\ |
| 858 | 858 | SPOS_MAX, _flags, _k, _ret) |
| 859 | 859 | |
| 860 | +#define for_each_btree_key_reverse_norestart(_trans, _iter, _btree_id, \ | |
| 861 | + _start, _flags, _k, _ret) \ | |
| 862 | + for (bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \ | |
| 863 | + (_start), (_flags)); \ | |
| 864 | + (_k) = bch2_btree_iter_peek_prev_type(&(_iter), _flags), \ | |
| 865 | + !((_ret) = bkey_err(_k)) && (_k).k; \ | |
| 866 | + bch2_btree_iter_rewind(&(_iter))) | |
| 867 | + | |
| 860 | 868 | #define for_each_btree_key_continue_norestart(_iter, _flags, _k, _ret) \ |
| 861 | 869 | for_each_btree_key_upto_continue_norestart(_iter, SPOS_MAX, _flags, _k, _ret) |
| 862 | 870 | |
| @@ -904,6 +912,8 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *); · 41 unmodified lines | ||
| 904 | 912 | _ret; \ |
| 905 | 913 | }) |
| 906 | 914 | |
| 915 | +#define bch2_trans_do(_c, _do) bch2_trans_run(_c, lockrestart_do(trans, _do)) | |
| 916 | + | |
| 907 | 917 | struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned); |
| 908 | 918 | void bch2_trans_put(struct btree_trans *); |
| 909 | 919 | |
| @@ -171,6 +171,9 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca, · 170 unmodified lines | ||
| 171 | 171 | if (BTREE_NODE_LEVEL(bn) >= BTREE_MAX_DEPTH) |
| 172 | 172 | return; |
| 173 | 173 | |
| 174 | + if (BTREE_NODE_ID(bn) >= BTREE_ID_NR_MAX) | |
| 175 | + return; | |
| 176 | + | |
| 174 | 177 | rcu_read_lock(); |
| 175 | 178 | struct found_btree_node n = { |
| 176 | 179 | .btree_id = BTREE_NODE_ID(bn), |
| @@ -832,7 +832,8 @@ revert_fs_usage: · 831 unmodified lines | ||
| 832 | 832 | for (struct jset_entry *entry2 = trans->journal_entries; |
| 833 | 833 | entry2 != entry; |
| 834 | 834 | entry2 = vstruct_next(entry2)) |
| 835 | − if (jset_entry_is_key(entry2) && entry2->start->k.type == KEY_TYPE_accounting) { | |
| 835 | + if (entry2->type == BCH_JSET_ENTRY_write_buffer_keys && | |
| 836 | + entry2->start->k.type == KEY_TYPE_accounting) { | |
| 836 | 837 | struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start); |
| 837 | 838 | |
| 838 | 839 | bch2_accounting_neg(a); |
| @@ -668,7 +668,7 @@ int bch2_btree_insert(struct bch_fs *c, enum btree_id id, struct bkey_i *k, · 667 unmodified lines | ||
| 668 | 668 | struct disk_reservation *disk_res, int flags, |
| 669 | 669 | enum btree_iter_update_trigger_flags iter_flags) |
| 670 | 670 | { |
| 671 | − return bch2_trans_do(c, disk_res, NULL, flags, | |
| 671 | + return bch2_trans_commit_do(c, disk_res, NULL, flags, | |
| 672 | 672 | bch2_btree_insert_trans(trans, id, k, iter_flags)); |
| 673 | 673 | } |
| 674 | 674 | |
| @@ -865,7 +865,7 @@ __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt, · 190 unmodified lines | ||
| 865 | 865 | memcpy(l->d, buf.buf, buf.pos); |
| 866 | 866 | c->journal.early_journal_entries.nr += jset_u64s(u64s); |
| 867 | 867 | } else { |
| 868 | − ret = bch2_trans_do(c, NULL, NULL, | |
| 868 | + ret = bch2_trans_commit_do(c, NULL, NULL, | |
| 869 | 869 | BCH_TRANS_COMMIT_lazy_rw|commit_flags, |
| 870 | 870 | __bch2_trans_log_msg(trans, &buf, u64s)); |
| 871 | 871 | } |
| @@ -192,7 +192,7 @@ static inline int bch2_trans_commit(struct btree_trans *trans, · 191 unmodified lines | ||
| 192 | 192 | nested_lockrestart_do(_trans, _do ?: bch2_trans_commit(_trans, (_disk_res),\ |
| 193 | 193 | (_journal_seq), (_flags))) |
| 194 | 194 | |
| 195 | −#define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do) \ | |
| 195 | +#define bch2_trans_commit_do(_c, _disk_res, _journal_seq, _flags, _do) \ | |
| 196 | 196 | bch2_trans_run(_c, commit_do(trans, _disk_res, _journal_seq, _flags, _do)) |
| 197 | 197 | |
| 198 | 198 | #define trans_for_each_update(_trans, _i) \ |
| @@ -2239,10 +2239,8 @@ static void async_btree_node_rewrite_work(struct work_struct *work) · 2238 unmodified lines | ||
| 2239 | 2239 | struct async_btree_rewrite *a = |
| 2240 | 2240 | container_of(work, struct async_btree_rewrite, work); |
| 2241 | 2241 | struct bch_fs *c = a->c; |
| 2242 | − int ret; | |
| 2243 | 2242 | |
| 2244 | − ret = bch2_trans_do(c, NULL, NULL, 0, | |
| 2245 | − async_btree_node_rewrite_trans(trans, a)); | |
| 2243 | + int ret = bch2_trans_do(c, async_btree_node_rewrite_trans(trans, a)); | |
| 2246 | 2244 | bch_err_fn_ratelimited(c, ret); |
| 2247 | 2245 | bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite); |
| 2248 | 2246 | kfree(a); |
| @@ -1160,11 +1160,11 @@ int bch2_trans_mark_dev_sbs(struct bch_fs *c) · 1159 unmodified lines | ||
| 1160 | 1160 | #define SECTORS_CACHE 1024 |
| 1161 | 1161 | |
| 1162 | 1162 | int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res, |
| 1163 | − u64 sectors, int flags) | |
| 1163 | + u64 sectors, enum bch_reservation_flags flags) | |
| 1164 | 1164 | { |
| 1165 | 1165 | struct bch_fs_pcpu *pcpu; |
| 1166 | 1166 | u64 old, get; |
| 1167 | − s64 sectors_available; | |
| 1167 | + u64 sectors_available; | |
| 1168 | 1168 | int ret; |
| 1169 | 1169 | |
| 1170 | 1170 | percpu_down_read(&c->mark_lock); |
| @@ -1202,6 +1202,9 @@ recalculate: · 31 unmodified lines | ||
| 1202 | 1202 | percpu_u64_set(&c->pcpu->sectors_available, 0); |
| 1203 | 1203 | sectors_available = avail_factor(__bch2_fs_usage_read_short(c).free); |
| 1204 | 1204 | |
| 1205 | + if (sectors_available && (flags & BCH_DISK_RESERVATION_PARTIAL)) | |
| 1206 | + sectors = min(sectors, sectors_available); | |
| 1207 | + | |
| 1205 | 1208 | if (sectors <= sectors_available || |
| 1206 | 1209 | (flags & BCH_DISK_RESERVATION_NOFAIL)) { |
| 1207 | 1210 | atomic64_set(&c->sectors_available, |
| @@ -344,14 +344,16 @@ static inline void bch2_disk_reservation_put(struct bch_fs *c, · 343 unmodified lines | ||
| 344 | 344 | } |
| 345 | 345 | } |
| 346 | 346 | |
| 347 | −#define BCH_DISK_RESERVATION_NOFAIL (1 << 0) | |
| 347 | +enum bch_reservation_flags { | |
| 348 | + BCH_DISK_RESERVATION_NOFAIL = 1 << 0, | |
| 349 | + BCH_DISK_RESERVATION_PARTIAL = 1 << 1, | |
| 350 | +}; | |
| 348 | 351 | |
| 349 | −int __bch2_disk_reservation_add(struct bch_fs *, | |
| 350 | − struct disk_reservation *, | |
| 351 | − u64, int); | |
| 352 | +int __bch2_disk_reservation_add(struct bch_fs *, struct disk_reservation *, | |
| 353 | + u64, enum bch_reservation_flags); | |
| 352 | 354 | |
| 353 | 355 | static inline int bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res, |
| 354 | − u64 sectors, int flags) | |
| 356 | + u64 sectors, enum bch_reservation_flags flags) | |
| 355 | 357 | { |
| 356 | 358 | #ifdef __KERNEL__ |
| 357 | 359 | u64 old, new; |
| @@ -225,6 +225,7 @@ static long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *user_a · 224 unmodified lines | ||
| 225 | 225 | |
| 226 | 226 | opt_set(thr->opts, stdio, (u64)(unsigned long)&thr->thr.stdio); |
| 227 | 227 | opt_set(thr->opts, read_only, 1); |
| 228 | + opt_set(thr->opts, ratelimit_errors, 0); | |
| 228 | 229 | |
| 229 | 230 | /* We need request_key() to be called before we punt to kthread: */ |
| 230 | 231 | opt_set(thr->opts, nostart, true); |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | #include <linux/log2.h> |
| 4 | 4 | #include <linux/slab.h> |
| 5 | +#include <linux/vmalloc.h> | |
| 5 | 6 | #include "darray.h" |
| 6 | 7 | |
| 7 | 8 | int __bch2_darray_resize_noprof(darray_char *d, size_t element_size, size_t new_size, gfp_t gfp) |
| @@ -9,7 +10,19 @@ int __bch2_darray_resize_noprof(darray_char *d, size_t element_size, size_t new_ · 1 unmodified line | ||
| 9 | 10 | if (new_size > d->size) { |
| 10 | 11 | new_size = roundup_pow_of_two(new_size); |
| 11 | 12 | |
| 12 | − void *data = kvmalloc_array_noprof(new_size, element_size, gfp); | |
| 13 | + /* | |
| 14 | + * This is a workaround: kvmalloc() doesn't support > INT_MAX | |
| 15 | + * allocations, but vmalloc() does. | |
| 16 | + * The limit needs to be lifted from kvmalloc, and when it does | |
| 17 | + * we'll go back to just using that. | |
| 18 | + */ | |
| 19 | + size_t bytes; | |
| 20 | + if (unlikely(check_mul_overflow(new_size, element_size, &bytes))) | |
| 21 | + return -ENOMEM; | |
| 22 | + | |
| 23 | + void *data = likely(bytes < INT_MAX) | |
| 24 | + ? kvmalloc_noprof(bytes, gfp) | |
| 25 | + : vmalloc_noprof(bytes); | |
| 13 | 26 | if (!data) |
| 14 | 27 | return -ENOMEM; |
| 15 | 28 | |
| @@ -80,6 +80,7 @@ static bool bkey_nocow_lock(struct bch_fs *c, struct moving_context *ctxt, struc · 79 unmodified lines | ||
| 80 | 80 | if (ptr2 == ptr) |
| 81 | 81 | break; |
| 82 | 82 | |
| 83 | + ca = bch2_dev_have_ref(c, ptr2->dev); | |
| 83 | 84 | bucket = PTR_BUCKET_POS(ca, ptr2); |
| 84 | 85 | bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0); |
| 85 | 86 | } |
| @@ -250,13 +250,6 @@ int bch2_dirent_create(struct btree_trans *trans, subvol_inum dir, · 249 unmodified lines | ||
| 250 | 250 | return ret; |
| 251 | 251 | } |
| 252 | 252 | |
| 253 | −static void dirent_copy_target(struct bkey_i_dirent *dst, | |
| 254 | − struct bkey_s_c_dirent src) | |
| 255 | −{ | |
| 256 | − dst->v.d_inum = src.v->d_inum; | |
| 257 | − dst->v.d_type = src.v->d_type; | |
| 258 | −} | |
| 259 | − | |
| 260 | 253 | int bch2_dirent_read_target(struct btree_trans *trans, subvol_inum dir, |
| 261 | 254 | struct bkey_s_c_dirent d, subvol_inum *target) |
| 262 | 255 | { |
| @@ -34,6 +34,13 @@ static inline unsigned dirent_val_u64s(unsigned len) · 33 unmodified lines | ||
| 34 | 34 | int bch2_dirent_read_target(struct btree_trans *, subvol_inum, |
| 35 | 35 | struct bkey_s_c_dirent, subvol_inum *); |
| 36 | 36 | |
| 37 | +static inline void dirent_copy_target(struct bkey_i_dirent *dst, | |
| 38 | + struct bkey_s_c_dirent src) | |
| 39 | +{ | |
| 40 | + dst->v.d_inum = src.v->d_inum; | |
| 41 | + dst->v.d_type = src.v->d_type; | |
| 42 | +} | |
| 43 | + | |
| 37 | 44 | int bch2_dirent_create_snapshot(struct btree_trans *, u32, u64, u32, |
| 38 | 45 | const struct bch_hash_info *, u8, |
| 39 | 46 | const struct qstr *, u64, u64 *, |
| @@ -242,6 +242,14 @@ void bch2_accounting_swab(struct bkey_s k) · 241 unmodified lines | ||
| 242 | 242 | *p = swab64(*p); |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | +static inline void __accounting_to_replicas(struct bch_replicas_entry_v1 *r, | |
| 246 | + struct disk_accounting_pos acc) | |
| 247 | +{ | |
| 248 | + unsafe_memcpy(r, &acc.replicas, | |
| 249 | + replicas_entry_bytes(&acc.replicas), | |
| 250 | + "variable length struct"); | |
| 251 | +} | |
| 252 | + | |
| 245 | 253 | static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struct bpos p) |
| 246 | 254 | { |
| 247 | 255 | struct disk_accounting_pos acc_k; |
| @@ -249,9 +257,7 @@ static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struc · 1 unmodified line | ||
| 249 | 257 | |
| 250 | 258 | switch (acc_k.type) { |
| 251 | 259 | case BCH_DISK_ACCOUNTING_replicas: |
| 252 | − unsafe_memcpy(r, &acc_k.replicas, | |
| 253 | − replicas_entry_bytes(&acc_k.replicas), | |
| 254 | − "variable length struct"); | |
| 260 | + __accounting_to_replicas(r, acc_k); | |
| 255 | 261 | return true; |
| 256 | 262 | default: |
| 257 | 263 | return false; |
| @@ -608,6 +614,81 @@ static int accounting_read_key(struct btree_trans *trans, struct bkey_s_c k) · 350 unmodified lines | ||
| 608 | 614 | return ret; |
| 609 | 615 | } |
| 610 | 616 | |
| 617 | +static int bch2_disk_accounting_validate_late(struct btree_trans *trans, | |
| 618 | + struct disk_accounting_pos acc, | |
| 619 | + u64 *v, unsigned nr) | |
| 620 | +{ | |
| 621 | + struct bch_fs *c = trans->c; | |
| 622 | + struct printbuf buf = PRINTBUF; | |
| 623 | + int ret = 0, invalid_dev = -1; | |
| 624 | + | |
| 625 | + switch (acc.type) { | |
| 626 | + case BCH_DISK_ACCOUNTING_replicas: { | |
| 627 | + struct bch_replicas_padded r; | |
| 628 | + __accounting_to_replicas(&r.e, acc); | |
| 629 | + | |
| 630 | + for (unsigned i = 0; i < r.e.nr_devs; i++) | |
| 631 | + if (r.e.devs[i] != BCH_SB_MEMBER_INVALID && | |
| 632 | + !bch2_dev_exists(c, r.e.devs[i])) { | |
| 633 | + invalid_dev = r.e.devs[i]; | |
| 634 | + goto invalid_device; | |
| 635 | + } | |
| 636 | + | |
| 637 | + /* | |
| 638 | + * All replicas entry checks except for invalid device are done | |
| 639 | + * in bch2_accounting_validate | |
| 640 | + */ | |
| 641 | + BUG_ON(bch2_replicas_entry_validate(&r.e, c, &buf)); | |
| 642 | + | |
| 643 | + if (fsck_err_on(!bch2_replicas_marked_locked(c, &r.e), | |
| 644 | + trans, accounting_replicas_not_marked, | |
| 645 | + "accounting not marked in superblock replicas\n %s", | |
| 646 | + (printbuf_reset(&buf), | |
| 647 | + bch2_accounting_key_to_text(&buf, &acc), | |
| 648 | + buf.buf))) { | |
| 649 | + /* | |
| 650 | + * We're not RW yet and still single threaded, dropping | |
| 651 | + * and retaking lock is ok: | |
| 652 | + */ | |
| 653 | + percpu_up_write(&c->mark_lock); | |
| 654 | + ret = bch2_mark_replicas(c, &r.e); | |
| 655 | + if (ret) | |
| 656 | + goto fsck_err; | |
| 657 | + percpu_down_write(&c->mark_lock); | |
| 658 | + } | |
| 659 | + break; | |
| 660 | + } | |
| 661 | + | |
| 662 | + case BCH_DISK_ACCOUNTING_dev_data_type: | |
| 663 | + if (!bch2_dev_exists(c, acc.dev_data_type.dev)) { | |
| 664 | + invalid_dev = acc.dev_data_type.dev; | |
| 665 | + goto invalid_device; | |
| 666 | + } | |
| 667 | + break; | |
| 668 | + } | |
| 669 | + | |
| 670 | +fsck_err: | |
| 671 | + printbuf_exit(&buf); | |
| 672 | + return ret; | |
| 673 | +invalid_device: | |
| 674 | + if (fsck_err(trans, accounting_to_invalid_device, | |
| 675 | + "accounting entry points to invalid device %i\n %s", | |
| 676 | + invalid_dev, | |
| 677 | + (printbuf_reset(&buf), | |
| 678 | + bch2_accounting_key_to_text(&buf, &acc), | |
| 679 | + buf.buf))) { | |
| 680 | + for (unsigned i = 0; i < nr; i++) | |
| 681 | + v[i] = -v[i]; | |
| 682 | + | |
| 683 | + ret = commit_do(trans, NULL, NULL, 0, | |
| 684 | + bch2_disk_accounting_mod(trans, &acc, v, nr, false)) ?: | |
| 685 | + -BCH_ERR_remove_disk_accounting_entry; | |
| 686 | + } else { | |
| 687 | + ret = -BCH_ERR_remove_disk_accounting_entry; | |
| 688 | + } | |
| 689 | + goto fsck_err; | |
| 690 | +} | |
| 691 | + | |
| 611 | 692 | /* |
| 612 | 693 | * At startup time, initialize the in memory accounting from the btree (and |
| 613 | 694 | * journal) |
| @@ -666,44 +747,42 @@ int bch2_accounting_read(struct bch_fs *c) · 52 unmodified lines | ||
| 666 | 747 | } |
| 667 | 748 | keys->gap = keys->nr = dst - keys->data; |
| 668 | 749 | |
| 669 | − percpu_down_read(&c->mark_lock); | |
| 670 | − for (unsigned i = 0; i < acc->k.nr; i++) { | |
| 671 | − u64 v[BCH_ACCOUNTING_MAX_COUNTERS]; | |
| 672 | − bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false); | |
| 750 | + percpu_down_write(&c->mark_lock); | |
| 751 | + unsigned i = 0; | |
| 752 | + while (i < acc->k.nr) { | |
| 753 | + unsigned idx = inorder_to_eytzinger0(i, acc->k.nr); | |
| 673 | 754 | |
| 674 | − if (bch2_is_zero(v, sizeof(v[0]) * acc->k.data[i].nr_counters)) | |
| 675 | − continue; | |
| 755 | + struct disk_accounting_pos acc_k; | |
| 756 | + bpos_to_disk_accounting_pos(&acc_k, acc->k.data[idx].pos); | |
| 676 | 757 | |
| 677 | − struct bch_replicas_padded r; | |
| 678 | − if (!accounting_to_replicas(&r.e, acc->k.data[i].pos)) | |
| 679 | − continue; | |
| 758 | + u64 v[BCH_ACCOUNTING_MAX_COUNTERS]; | |
| 759 | + bch2_accounting_mem_read_counters(acc, idx, v, ARRAY_SIZE(v), false); | |
| 680 | 760 | |
| 681 | 761 | /* |
| 682 | − * If the replicas entry is invalid it'll get cleaned up by | |
| 683 | − * check_allocations: | |
| 762 | + * If the entry counters are zeroed, it should be treated as | |
| 763 | + * nonexistent - it might point to an invalid device. | |
| 764 | + * | |
| 765 | + * Remove it, so that if it's re-added it gets re-marked in the | |
| 766 | + * superblock: | |
| 684 | 767 | */ |
| 685 | − if (bch2_replicas_entry_validate(&r.e, c, &buf)) | |
| 768 | + ret = bch2_is_zero(v, sizeof(v[0]) * acc->k.data[idx].nr_counters) | |
| 769 | + ? -BCH_ERR_remove_disk_accounting_entry | |
| 770 | + : bch2_disk_accounting_validate_late(trans, acc_k, | |
| 771 | + v, acc->k.data[idx].nr_counters); | |
| 772 | + | |
| 773 | + if (ret == -BCH_ERR_remove_disk_accounting_entry) { | |
| 774 | + free_percpu(acc->k.data[idx].v[0]); | |
| 775 | + free_percpu(acc->k.data[idx].v[1]); | |
| 776 | + darray_remove_item(&acc->k, &acc->k.data[idx]); | |
| 777 | + eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]), | |
| 778 | + accounting_pos_cmp, NULL); | |
| 779 | + ret = 0; | |
| 686 | 780 | continue; |
| 687 | − | |
| 688 | − struct disk_accounting_pos k; | |
| 689 | − bpos_to_disk_accounting_pos(&k, acc->k.data[i].pos); | |
| 690 | − | |
| 691 | − if (fsck_err_on(!bch2_replicas_marked_locked(c, &r.e), | |
| 692 | − trans, accounting_replicas_not_marked, | |
| 693 | − "accounting not marked in superblock replicas\n %s", | |
| 694 | − (printbuf_reset(&buf), | |
| 695 | − bch2_accounting_key_to_text(&buf, &k), | |
| 696 | − buf.buf))) { | |
| 697 | − /* | |
| 698 | − * We're not RW yet and still single threaded, dropping | |
| 699 | − * and retaking lock is ok: | |
| 700 | − */ | |
| 701 | − percpu_up_read(&c->mark_lock); | |
| 702 | − ret = bch2_mark_replicas(c, &r.e); | |
| 703 | − if (ret) | |
| 704 | − goto fsck_err; | |
| 705 | − percpu_down_read(&c->mark_lock); | |
| 706 | 781 | } |
| 782 | + | |
| 783 | + if (ret) | |
| 784 | + goto fsck_err; | |
| 785 | + i++; | |
| 707 | 786 | } |
| 708 | 787 | |
| 709 | 788 | preempt_disable(); |
| @@ -742,7 +821,7 @@ int bch2_accounting_read(struct bch_fs *c) · 32 unmodified lines | ||
| 742 | 821 | } |
| 743 | 822 | preempt_enable(); |
| 744 | 823 | fsck_err: |
| 745 | − percpu_up_read(&c->mark_lock); | |
| 824 | + percpu_up_write(&c->mark_lock); | |
| 746 | 825 | err: |
| 747 | 826 | printbuf_exit(&buf); |
| 748 | 827 | bch2_trans_put(trans); |
| @@ -777,8 +856,10 @@ int bch2_dev_usage_init(struct bch_dev *ca, bool gc) · 28 unmodified lines | ||
| 777 | 856 | }; |
| 778 | 857 | u64 v[3] = { ca->mi.nbuckets - ca->mi.first_bucket, 0, 0 }; |
| 779 | 858 | |
| 780 | − int ret = bch2_trans_do(c, NULL, NULL, 0, | |
| 781 | − bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc)); | |
| 859 | + int ret = bch2_trans_do(c, ({ | |
| 860 | + bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc) ?: | |
| 861 | + (!gc ? bch2_trans_commit(trans, NULL, NULL, 0) : 0); | |
| 862 | + })); | |
| 782 | 863 | bch_err_fn(c, ret); |
| 783 | 864 | return ret; |
| 784 | 865 | } |
| @@ -124,6 +124,11 @@ int bch2_stripe_validate(struct bch_fs *c, struct bkey_s_c k, · 123 unmodified lines | ||
| 124 | 124 | "incorrect value size (%zu < %u)", |
| 125 | 125 | bkey_val_u64s(k.k), stripe_val_u64s(s)); |
| 126 | 126 | |
| 127 | + bkey_fsck_err_on(s->csum_granularity_bits >= 64, | |
| 128 | + c, stripe_csum_granularity_bad, | |
| 129 | + "invalid csum granularity (%u >= 64)", | |
| 130 | + s->csum_granularity_bits); | |
| 131 | + | |
| 127 | 132 | ret = bch2_bkey_ptrs_validate(c, k, flags); |
| 128 | 133 | fsck_err: |
| 129 | 134 | return ret; |
| @@ -145,7 +150,11 @@ void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c, · 15 unmodified lines | ||
| 145 | 150 | nr_data, |
| 146 | 151 | s.nr_redundant); |
| 147 | 152 | bch2_prt_csum_type(out, s.csum_type); |
| 148 | − prt_printf(out, " gran %u", 1U << s.csum_granularity_bits); | |
| 153 | + prt_str(out, " gran "); | |
| 154 | + if (s.csum_granularity_bits < 64) | |
| 155 | + prt_printf(out, "%llu", 1ULL << s.csum_granularity_bits); | |
| 156 | + else | |
| 157 | + prt_printf(out, "(invalid shift %u)", s.csum_granularity_bits); | |
| 149 | 158 | |
| 150 | 159 | if (s.disk_label) { |
| 151 | 160 | prt_str(out, " label"); |
| @@ -257,12 +266,12 @@ static int __mark_stripe_bucket(struct btree_trans *trans, · 105 unmodified lines | ||
| 257 | 266 | if (!deleting) { |
| 258 | 267 | a->stripe = s.k->p.offset; |
| 259 | 268 | a->stripe_redundancy = s.v->nr_redundant; |
| 269 | + alloc_data_type_set(a, data_type); | |
| 260 | 270 | } else { |
| 261 | 271 | a->stripe = 0; |
| 262 | 272 | a->stripe_redundancy = 0; |
| 273 | + alloc_data_type_set(a, BCH_DATA_user); | |
| 263 | 274 | } |
| 264 | − | |
| 265 | − alloc_data_type_set(a, data_type); | |
| 266 | 275 | err: |
| 267 | 276 | printbuf_exit(&buf); |
| 268 | 277 | return ret; |
| @@ -1177,7 +1186,7 @@ static void ec_stripe_delete_work(struct work_struct *work) · 908 unmodified lines | ||
| 1177 | 1186 | if (!idx) |
| 1178 | 1187 | break; |
| 1179 | 1188 | |
| 1180 | − int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, | |
| 1189 | + int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, | |
| 1181 | 1190 | ec_stripe_delete(trans, idx)); |
| 1182 | 1191 | bch_err_fn(c, ret); |
| 1183 | 1192 | if (ret) |
| @@ -1197,47 +1206,62 @@ void bch2_do_stripe_deletes(struct bch_fs *c) · 13 unmodified lines | ||
| 1197 | 1206 | /* stripe creation: */ |
| 1198 | 1207 | |
| 1199 | 1208 | static int ec_stripe_key_update(struct btree_trans *trans, |
| 1200 | − struct bkey_i_stripe *new, | |
| 1201 | − bool create) | |
| 1209 | + struct bkey_i_stripe *old, | |
| 1210 | + struct bkey_i_stripe *new) | |
| 1202 | 1211 | { |
| 1203 | 1212 | struct bch_fs *c = trans->c; |
| 1204 | − struct btree_iter iter; | |
| 1205 | − struct bkey_s_c k; | |
| 1206 | − int ret; | |
| 1213 | + bool create = !old; | |
| 1207 | 1214 | |
| 1208 | − k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes, | |
| 1209 | − new->k.p, BTREE_ITER_intent); | |
| 1210 | − ret = bkey_err(k); | |
| 1215 | + struct btree_iter iter; | |
| 1216 | + struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes, | |
| 1217 | + new->k.p, BTREE_ITER_intent); | |
| 1218 | + int ret = bkey_err(k); | |
| 1211 | 1219 | if (ret) |
| 1212 | 1220 | goto err; |
| 1213 | 1221 | |
| 1214 | − if (k.k->type != (create ? KEY_TYPE_deleted : KEY_TYPE_stripe)) { | |
| 1215 | − bch2_fs_inconsistent(c, "error %s stripe: got existing key type %s", | |
| 1216 | − create ? "creating" : "updating", | |
| 1217 | − bch2_bkey_types[k.k->type]); | |
| 1222 | + if (bch2_fs_inconsistent_on(k.k->type != (create ? KEY_TYPE_deleted : KEY_TYPE_stripe), | |
| 1223 | + c, "error %s stripe: got existing key type %s", | |
| 1224 | + create ? "creating" : "updating", | |
| 1225 | + bch2_bkey_types[k.k->type])) { | |
| 1218 | 1226 | ret = -EINVAL; |
| 1219 | 1227 | goto err; |
| 1220 | 1228 | } |
| 1221 | 1229 | |
| 1222 | 1230 | if (k.k->type == KEY_TYPE_stripe) { |
| 1223 | − const struct bch_stripe *old = bkey_s_c_to_stripe(k).v; | |
| 1224 | − unsigned i; | |
| 1231 | + const struct bch_stripe *v = bkey_s_c_to_stripe(k).v; | |
| 1225 | 1232 | |
| 1226 | − if (old->nr_blocks != new->v.nr_blocks) { | |
| 1227 | − bch_err(c, "error updating stripe: nr_blocks does not match"); | |
| 1228 | − ret = -EINVAL; | |
| 1229 | − goto err; | |
| 1230 | − } | |
| 1233 | + BUG_ON(old->v.nr_blocks != new->v.nr_blocks); | |
| 1234 | + BUG_ON(old->v.nr_blocks != v->nr_blocks); | |
| 1231 | 1235 | |
| 1232 | − for (i = 0; i < new->v.nr_blocks; i++) { | |
| 1233 | − unsigned v = stripe_blockcount_get(old, i); | |
| 1236 | + for (unsigned i = 0; i < new->v.nr_blocks; i++) { | |
| 1237 | + unsigned sectors = stripe_blockcount_get(v, i); | |
| 1234 | 1238 | |
| 1235 | − BUG_ON(v && | |
| 1236 | − (old->ptrs[i].dev != new->v.ptrs[i].dev || | |
| 1237 | − old->ptrs[i].gen != new->v.ptrs[i].gen || | |
| 1238 | − old->ptrs[i].offset != new->v.ptrs[i].offset)); | |
| 1239 | + if (!bch2_extent_ptr_eq(old->v.ptrs[i], new->v.ptrs[i]) && sectors) { | |
| 1240 | + struct printbuf buf = PRINTBUF; | |
| 1239 | 1241 | |
| 1240 | − stripe_blockcount_set(&new->v, i, v); | |
| 1242 | + prt_printf(&buf, "stripe changed nonempty block %u", i); | |
| 1243 | + prt_str(&buf, "\nold: "); | |
| 1244 | + bch2_bkey_val_to_text(&buf, c, k); | |
| 1245 | + prt_str(&buf, "\nnew: "); | |
| 1246 | + bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&new->k_i)); | |
| 1247 | + bch2_fs_inconsistent(c, "%s", buf.buf); | |
| 1248 | + printbuf_exit(&buf); | |
| 1249 | + ret = -EINVAL; | |
| 1250 | + goto err; | |
| 1251 | + } | |
| 1252 | + | |
| 1253 | + /* | |
| 1254 | + * If the stripe ptr changed underneath us, it must have | |
| 1255 | + * been dev_remove_stripes() -> * invalidate_stripe_to_dev() | |
| 1256 | + */ | |
| 1257 | + if (!bch2_extent_ptr_eq(old->v.ptrs[i], v->ptrs[i])) { | |
| 1258 | + BUG_ON(v->ptrs[i].dev != BCH_SB_MEMBER_INVALID); | |
| 1259 | + | |
| 1260 | + if (bch2_extent_ptr_eq(old->v.ptrs[i], new->v.ptrs[i])) | |
| 1261 | + new->v.ptrs[i].dev = BCH_SB_MEMBER_INVALID; | |
| 1262 | + } | |
| 1263 | + | |
| 1264 | + stripe_blockcount_set(&new->v, i, sectors); | |
| 1241 | 1265 | } |
| 1242 | 1266 | } |
| 1243 | 1267 | |
| @@ -1495,12 +1519,14 @@ static void ec_stripe_create(struct ec_stripe_new *s) · 251 unmodified lines | ||
| 1495 | 1519 | goto err; |
| 1496 | 1520 | } |
| 1497 | 1521 | |
| 1498 | − ret = bch2_trans_do(c, &s->res, NULL, | |
| 1499 | − BCH_TRANS_COMMIT_no_check_rw| | |
| 1500 | − BCH_TRANS_COMMIT_no_enospc, | |
| 1501 | − ec_stripe_key_update(trans, | |
| 1502 | − bkey_i_to_stripe(&s->new_stripe.key), | |
| 1503 | − !s->have_existing_stripe)); | |
| 1522 | + ret = bch2_trans_commit_do(c, &s->res, NULL, | |
| 1523 | + BCH_TRANS_COMMIT_no_check_rw| | |
| 1524 | + BCH_TRANS_COMMIT_no_enospc, | |
| 1525 | + ec_stripe_key_update(trans, | |
| 1526 | + s->have_existing_stripe | |
| 1527 | + ? bkey_i_to_stripe(&s->existing_stripe.key) | |
| 1528 | + : NULL, | |
| 1529 | + bkey_i_to_stripe(&s->new_stripe.key))); | |
| 1504 | 1530 | bch_err_msg(c, ret, "creating stripe key"); |
| 1505 | 1531 | if (ret) { |
| 1506 | 1532 | goto err; |
| @@ -1876,7 +1902,15 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_ · 369 unmodified lines | ||
| 1876 | 1902 | bitmap_and(devs.d, devs.d, c->rw_devs[BCH_DATA_user].d, BCH_SB_MEMBERS_MAX); |
| 1877 | 1903 | |
| 1878 | 1904 | for_each_set_bit(i, h->s->blocks_gotten, v->nr_blocks) { |
| 1879 | − __clear_bit(v->ptrs[i].dev, devs.d); | |
| 1905 | + /* | |
| 1906 | + * Note: we don't yet repair invalid blocks (failed/removed | |
| 1907 | + * devices) when reusing stripes - we still need a codepath to | |
| 1908 | + * walk backpointers and update all extents that point to that | |
| 1909 | + * block when updating the stripe | |
| 1910 | + */ | |
| 1911 | + if (v->ptrs[i].dev != BCH_SB_MEMBER_INVALID) | |
| 1912 | + __clear_bit(v->ptrs[i].dev, devs.d); | |
| 1913 | + | |
| 1880 | 1914 | if (i < h->s->nr_data) |
| 1881 | 1915 | nr_have_data++; |
| 1882 | 1916 | else |
| @@ -268,7 +268,8 @@ · 267 unmodified lines | ||
| 268 | 268 | x(BCH_ERR_nopromote, nopromote_no_writes) \ |
| 269 | 269 | x(BCH_ERR_nopromote, nopromote_enomem) \ |
| 270 | 270 | x(0, invalid_snapshot_node) \ |
| 271 | − x(0, option_needs_open_fs) | |
| 271 | + x(0, option_needs_open_fs) \ | |
| 272 | + x(0, remove_disk_accounting_entry) | |
| 272 | 273 | |
| 273 | 274 | enum bch_errcode { |
| 274 | 275 | BCH_ERR_START = 2048, |
| @@ -251,7 +251,10 @@ int __bch2_fsck_err(struct bch_fs *c, · 250 unmodified lines | ||
| 251 | 251 | * delete the key) |
| 252 | 252 | * - and we don't need to warn if we're not prompting |
| 253 | 253 | */ |
| 254 | − WARN_ON(!(flags & FSCK_AUTOFIX) && !trans && bch2_current_has_btree_trans(c)); | |
| 254 | + WARN_ON((flags & FSCK_CAN_FIX) && | |
| 255 | + !(flags & FSCK_AUTOFIX) && | |
| 256 | + !trans && | |
| 257 | + bch2_current_has_btree_trans(c)); | |
| 255 | 258 | |
| 256 | 259 | if ((flags & FSCK_CAN_FIX) && |
| 257 | 260 | test_bit(err, c->sb.errors_silent)) |
| @@ -393,6 +396,14 @@ int __bch2_fsck_err(struct bch_fs *c, · 135 unmodified lines | ||
| 393 | 396 | !(flags & FSCK_CAN_IGNORE))) |
| 394 | 397 | ret = -BCH_ERR_fsck_errors_not_fixed; |
| 395 | 398 | |
| 399 | + bool exiting = | |
| 400 | + test_bit(BCH_FS_fsck_running, &c->flags) && | |
| 401 | + (ret != -BCH_ERR_fsck_fix && | |
| 402 | + ret != -BCH_ERR_fsck_ignore); | |
| 403 | + | |
| 404 | + if (exiting) | |
| 405 | + print = true; | |
| 406 | + | |
| 396 | 407 | if (print) { |
| 397 | 408 | if (bch2_fs_stdio_redirect(c)) |
| 398 | 409 | bch2_print(c, "%s\n", out->buf); |
| @@ -400,9 +411,7 @@ int __bch2_fsck_err(struct bch_fs *c, · 1 unmodified line | ||
| 400 | 411 | bch2_print_string_as_lines(KERN_ERR, out->buf); |
| 401 | 412 | } |
| 402 | 413 | |
| 403 | − if (test_bit(BCH_FS_fsck_running, &c->flags) && | |
| 404 | − (ret != -BCH_ERR_fsck_fix && | |
| 405 | − ret != -BCH_ERR_fsck_ignore)) | |
| 414 | + if (exiting) | |
| 406 | 415 | bch_err(c, "Unable to continue, halting"); |
| 407 | 416 | else if (suppressing) |
| 408 | 417 | bch_err(c, "Ratelimiting new instances of previous error"); |
| @@ -430,10 +439,17 @@ err: · 21 unmodified lines | ||
| 430 | 439 | |
| 431 | 440 | int __bch2_bkey_fsck_err(struct bch_fs *c, |
| 432 | 441 | struct bkey_s_c k, |
| 433 | − enum bch_fsck_flags flags, | |
| 442 | + enum bch_validate_flags validate_flags, | |
| 434 | 443 | enum bch_sb_error_id err, |
| 435 | 444 | const char *fmt, ...) |
| 436 | 445 | { |
| 446 | + if (validate_flags & BCH_VALIDATE_silent) | |
| 447 | + return -BCH_ERR_fsck_delete_bkey; | |
| 448 | + | |
| 449 | + unsigned fsck_flags = 0; | |
| 450 | + if (!(validate_flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit))) | |
| 451 | + fsck_flags |= FSCK_AUTOFIX|FSCK_CAN_FIX; | |
| 452 | + | |
| 437 | 453 | struct printbuf buf = PRINTBUF; |
| 438 | 454 | va_list args; |
| 439 | 455 | |
| @@ -445,7 +461,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *c, · 5 unmodified lines | ||
| 445 | 461 | va_end(args); |
| 446 | 462 | prt_str(&buf, ": delete?"); |
| 447 | 463 | |
| 448 | − int ret = __bch2_fsck_err(c, NULL, flags, err, "%s", buf.buf); | |
| 464 | + int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s", buf.buf); | |
| 449 | 465 | printbuf_exit(&buf); |
| 450 | 466 | return ret; |
| 451 | 467 | } |
| @@ -167,10 +167,11 @@ void bch2_flush_fsck_errs(struct bch_fs *); · 166 unmodified lines | ||
| 167 | 167 | #define fsck_err_on(cond, c, _err_type, ...) \ |
| 168 | 168 | __fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__) |
| 169 | 169 | |
| 170 | +enum bch_validate_flags; | |
| 170 | 171 | __printf(5, 6) |
| 171 | 172 | int __bch2_bkey_fsck_err(struct bch_fs *, |
| 172 | 173 | struct bkey_s_c, |
| 173 | − enum bch_fsck_flags, | |
| 174 | + enum bch_validate_flags, | |
| 174 | 175 | enum bch_sb_error_id, |
| 175 | 176 | const char *, ...); |
| 176 | 177 | |
| @@ -180,11 +181,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *, · 3 unmodified lines | ||
| 180 | 181 | */ |
| 181 | 182 | #define bkey_fsck_err(c, _err_type, _err_msg, ...) \ |
| 182 | 183 | do { \ |
| 183 | − if ((flags & BCH_VALIDATE_silent)) { \ | |
| 184 | − ret = -BCH_ERR_fsck_delete_bkey; \ | |
| 185 | − goto fsck_err; \ | |
| 186 | − } \ | |
| 187 | − int _ret = __bch2_bkey_fsck_err(c, k, FSCK_CAN_FIX|FSCK_AUTOFIX,\ | |
| 184 | + int _ret = __bch2_bkey_fsck_err(c, k, flags, \ | |
| 188 | 185 | BCH_FSCK_ERR_##_err_type, \ |
| 189 | 186 | _err_msg, ##__VA_ARGS__); \ |
| 190 | 187 | if (_ret != -BCH_ERR_fsck_fix && \ |
| @@ -695,6 +695,16 @@ void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *, · 694 unmodified lines | ||
| 695 | 695 | int bch2_bkey_ptrs_validate(struct bch_fs *, struct bkey_s_c, |
| 696 | 696 | enum bch_validate_flags); |
| 697 | 697 | |
| 698 | +static inline bool bch2_extent_ptr_eq(struct bch_extent_ptr ptr1, | |
| 699 | + struct bch_extent_ptr ptr2) | |
| 700 | +{ | |
| 701 | + return (ptr1.cached == ptr2.cached && | |
| 702 | + ptr1.unwritten == ptr2.unwritten && | |
| 703 | + ptr1.offset == ptr2.offset && | |
| 704 | + ptr1.dev == ptr2.dev && | |
| 705 | + ptr1.dev == ptr2.dev); | |
| 706 | +} | |
| 707 | + | |
| 698 | 708 | void bch2_ptr_swab(struct bkey_s); |
| 699 | 709 | |
| 700 | 710 | const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c); |
| @@ -856,6 +856,12 @@ static int __bch2_buffered_write(struct bch_inode_info *inode, · 855 unmodified lines | ||
| 856 | 856 | folios_trunc(&fs, fi); |
| 857 | 857 | end = min(end, folio_end_pos(darray_last(fs))); |
| 858 | 858 | } else { |
| 859 | + if (!folio_test_uptodate(f)) { | |
| 860 | + ret = bch2_read_single_folio(f, mapping); | |
| 861 | + if (ret) | |
| 862 | + goto out; | |
| 863 | + } | |
| 864 | + | |
| 859 | 865 | folios_trunc(&fs, fi + 1); |
| 860 | 866 | end = f_pos + f_reserved; |
| 861 | 867 | } |
| @@ -369,6 +369,7 @@ static noinline void bch2_dio_write_flush(struct dio_write *dio) · 368 unmodified lines | ||
| 369 | 369 | |
| 370 | 370 | static __always_inline long bch2_dio_write_done(struct dio_write *dio) |
| 371 | 371 | { |
| 372 | + struct bch_fs *c = dio->op.c; | |
| 372 | 373 | struct kiocb *req = dio->req; |
| 373 | 374 | struct bch_inode_info *inode = dio->inode; |
| 374 | 375 | bool sync = dio->sync; |
| @@ -387,7 +388,7 @@ static __always_inline long bch2_dio_write_done(struct dio_write *dio) · 12 unmodified lines | ||
| 387 | 388 | ret = dio->op.error ?: ((long) dio->written << 9); |
| 388 | 389 | bio_put(&dio->op.wbio.bio); |
| 389 | 390 | |
| 390 | − bch2_write_ref_put(dio->op.c, BCH_WRITE_REF_dio_write); | |
| 391 | + bch2_write_ref_put(c, BCH_WRITE_REF_dio_write); | |
| 391 | 392 | |
| 392 | 393 | /* inode->i_dio_count is our ref on inode and thus bch_fs */ |
| 393 | 394 | inode_dio_end(&inode->v); |
| @@ -399,14 +399,17 @@ void bch2_folio_reservation_put(struct bch_fs *c, · 398 unmodified lines | ||
| 399 | 399 | bch2_quota_reservation_put(c, inode, &res->quota); |
| 400 | 400 | } |
| 401 | 401 | |
| 402 | −int bch2_folio_reservation_get(struct bch_fs *c, | |
| 402 | +static int __bch2_folio_reservation_get(struct bch_fs *c, | |
| 403 | 403 | struct bch_inode_info *inode, |
| 404 | 404 | struct folio *folio, |
| 405 | 405 | struct bch2_folio_reservation *res, |
| 406 | − size_t offset, size_t len) | |
| 406 | + size_t offset, size_t len, | |
| 407 | + bool partial) | |
| 407 | 408 | { |
| 408 | 409 | struct bch_folio *s = bch2_folio_create(folio, 0); |
| 409 | 410 | unsigned i, disk_sectors = 0, quota_sectors = 0; |
| 411 | + struct disk_reservation disk_res = {}; | |
| 412 | + size_t reserved = len; | |
| 410 | 413 | int ret; |
| 411 | 414 | |
| 412 | 415 | if (!s) |
| @@ -422,48 +425,65 @@ int bch2_folio_reservation_get(struct bch_fs *c, · 9 unmodified lines | ||
| 422 | 425 | } |
| 423 | 426 | |
| 424 | 427 | if (disk_sectors) { |
| 425 | − ret = bch2_disk_reservation_add(c, &res->disk, disk_sectors, 0); | |
| 428 | + ret = bch2_disk_reservation_add(c, &disk_res, disk_sectors, | |
| 429 | + partial ? BCH_DISK_RESERVATION_PARTIAL : 0); | |
| 426 | 430 | if (unlikely(ret)) |
| 427 | 431 | return ret; |
| 432 | + | |
| 433 | + if (unlikely(disk_res.sectors != disk_sectors)) { | |
| 434 | + disk_sectors = quota_sectors = 0; | |
| 435 | + | |
| 436 | + for (i = round_down(offset, block_bytes(c)) >> 9; | |
| 437 | + i < round_up(offset + len, block_bytes(c)) >> 9; | |
| 438 | + i++) { | |
| 439 | + disk_sectors += sectors_to_reserve(&s->s[i], res->disk.nr_replicas); | |
| 440 | + if (disk_sectors > disk_res.sectors) { | |
| 441 | + /* | |
| 442 | + * Make sure to get a reservation that's | |
| 443 | + * aligned to the filesystem blocksize: | |
| 444 | + */ | |
| 445 | + unsigned reserved_offset = round_down(i << 9, block_bytes(c)); | |
| 446 | + reserved = clamp(reserved_offset, offset, offset + len) - offset; | |
| 447 | + | |
| 448 | + if (!reserved) { | |
| 449 | + bch2_disk_reservation_put(c, &disk_res); | |
| 450 | + return -BCH_ERR_ENOSPC_disk_reservation; | |
| 451 | + } | |
| 452 | + break; | |
| 453 | + } | |
| 454 | + quota_sectors += s->s[i].state == SECTOR_unallocated; | |
| 455 | + } | |
| 456 | + } | |
| 428 | 457 | } |
| 429 | 458 | |
| 430 | 459 | if (quota_sectors) { |
| 431 | 460 | ret = bch2_quota_reservation_add(c, inode, &res->quota, quota_sectors, true); |
| 432 | 461 | if (unlikely(ret)) { |
| 433 | − struct disk_reservation tmp = { .sectors = disk_sectors }; | |
| 434 | − | |
| 435 | − bch2_disk_reservation_put(c, &tmp); | |
| 436 | − res->disk.sectors -= disk_sectors; | |
| 462 | + bch2_disk_reservation_put(c, &disk_res); | |
| 437 | 463 | return ret; |
| 438 | 464 | } |
| 439 | 465 | } |
| 440 | 466 | |
| 441 | − return 0; | |
| 467 | + res->disk.sectors += disk_res.sectors; | |
| 468 | + return partial ? reserved : 0; | |
| 442 | 469 | } |
| 443 | 470 | |
| 444 | −ssize_t bch2_folio_reservation_get_partial(struct bch_fs *c, | |
| 471 | +int bch2_folio_reservation_get(struct bch_fs *c, | |
| 445 | 472 | struct bch_inode_info *inode, |
| 446 | 473 | struct folio *folio, |
| 447 | 474 | struct bch2_folio_reservation *res, |
| 448 | 475 | size_t offset, size_t len) |
| 449 | 476 | { |
| 450 | − size_t l, reserved = 0; | |
| 451 | − int ret; | |
| 452 | − | |
| 453 | − while ((l = len - reserved)) { | |
| 454 | − while ((ret = bch2_folio_reservation_get(c, inode, folio, res, offset, l))) { | |
| 455 | − if ((offset & (block_bytes(c) - 1)) + l <= block_bytes(c)) | |
| 456 | − return reserved ?: ret; | |
| 457 | − | |
| 458 | − len = reserved + l; | |
| 459 | − l /= 2; | |
| 460 | − } | |
| 461 | − | |
| 462 | − offset += l; | |
| 463 | − reserved += l; | |
| 464 | − } | |
| 477 | + return __bch2_folio_reservation_get(c, inode, folio, res, offset, len, false); | |
| 478 | +} | |
| 465 | 479 | |
| 466 | − return reserved; | |
| 480 | +ssize_t bch2_folio_reservation_get_partial(struct bch_fs *c, | |
| 481 | + struct bch_inode_info *inode, | |
| 482 | + struct folio *folio, | |
| 483 | + struct bch2_folio_reservation *res, | |
| 484 | + size_t offset, size_t len) | |
| 485 | +{ | |
| 486 | + return __bch2_folio_reservation_get(c, inode, folio, res, offset, len, true); | |
| 467 | 487 | } |
| 468 | 488 | |
| 469 | 489 | static void bch2_clear_folio_bits(struct folio *folio) |
| @@ -182,7 +182,7 @@ static int bch2_flush_inode(struct bch_fs *c, · 181 unmodified lines | ||
| 182 | 182 | |
| 183 | 183 | struct bch_inode_unpacked u; |
| 184 | 184 | int ret = bch2_inode_find_by_inum(c, inode_inum(inode), &u) ?: |
| 185 | − bch2_journal_flush_seq(&c->journal, u.bi_journal_seq) ?: | |
| 185 | + bch2_journal_flush_seq(&c->journal, u.bi_journal_seq, TASK_INTERRUPTIBLE) ?: | |
| 186 | 186 | bch2_inode_flush_nocow_writes(c, inode); |
| 187 | 187 | bch2_write_ref_put(c, BCH_WRITE_REF_fsync); |
| 188 | 188 | return ret; |
| @@ -157,6 +157,20 @@ static bool subvol_inum_eq(subvol_inum a, subvol_inum b) · 156 unmodified lines | ||
| 157 | 157 | return a.subvol == b.subvol && a.inum == b.inum; |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | +static u32 bch2_vfs_inode_hash_fn(const void *data, u32 len, u32 seed) | |
| 161 | +{ | |
| 162 | + const subvol_inum *inum = data; | |
| 163 | + | |
| 164 | + return jhash(&inum->inum, sizeof(inum->inum), seed); | |
| 165 | +} | |
| 166 | + | |
| 167 | +static u32 bch2_vfs_inode_obj_hash_fn(const void *data, u32 len, u32 seed) | |
| 168 | +{ | |
| 169 | + const struct bch_inode_info *inode = data; | |
| 170 | + | |
| 171 | + return bch2_vfs_inode_hash_fn(&inode->ei_inum, sizeof(inode->ei_inum), seed); | |
| 172 | +} | |
| 173 | + | |
| 160 | 174 | static int bch2_vfs_inode_cmp_fn(struct rhashtable_compare_arg *arg, |
| 161 | 175 | const void *obj) |
| 162 | 176 | { |
| @@ -170,26 +184,111 @@ static const struct rhashtable_params bch2_vfs_inodes_params = { · 7 unmodified lines | ||
| 170 | 184 | .head_offset = offsetof(struct bch_inode_info, hash), |
| 171 | 185 | .key_offset = offsetof(struct bch_inode_info, ei_inum), |
| 172 | 186 | .key_len = sizeof(subvol_inum), |
| 187 | + .hashfn = bch2_vfs_inode_hash_fn, | |
| 188 | + .obj_hashfn = bch2_vfs_inode_obj_hash_fn, | |
| 173 | 189 | .obj_cmpfn = bch2_vfs_inode_cmp_fn, |
| 174 | 190 | .automatic_shrinking = true, |
| 175 | 191 | }; |
| 176 | 192 | |
| 177 | −static void __wait_on_freeing_inode(struct inode *inode) | |
| 193 | +int bch2_inode_or_descendents_is_open(struct btree_trans *trans, struct bpos p) | |
| 178 | 194 | { |
| 179 | − wait_queue_head_t *wq; | |
| 180 | − DEFINE_WAIT_BIT(wait, &inode->i_state, __I_NEW); | |
| 181 | − wq = bit_waitqueue(&inode->i_state, __I_NEW); | |
| 182 | − prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE); | |
| 183 | − spin_unlock(&inode->i_lock); | |
| 184 | − schedule(); | |
| 185 | − finish_wait(wq, &wait.wq_entry); | |
| 195 | + struct bch_fs *c = trans->c; | |
| 196 | + struct rhashtable *ht = &c->vfs_inodes_table; | |
| 197 | + subvol_inum inum = (subvol_inum) { .inum = p.offset }; | |
| 198 | + DARRAY(u32) subvols; | |
| 199 | + int ret = 0; | |
| 200 | + | |
| 201 | + if (!test_bit(BCH_FS_started, &c->flags)) | |
| 202 | + return false; | |
| 203 | + | |
| 204 | + darray_init(&subvols); | |
| 205 | +restart_from_top: | |
| 206 | + | |
| 207 | + /* | |
| 208 | + * Tweaked version of __rhashtable_lookup(); we need to get a list of | |
| 209 | + * subvolumes in which the given inode number is open. | |
| 210 | + * | |
| 211 | + * For this to work, we don't include the subvolume ID in the key that | |
| 212 | + * we hash - all inodes with the same inode number regardless of | |
| 213 | + * subvolume will hash to the same slot. | |
| 214 | + * | |
| 215 | + * This will be less than ideal if the same file is ever open | |
| 216 | + * simultaneously in many different snapshots: | |
| 217 | + */ | |
| 218 | + rcu_read_lock(); | |
| 219 | + struct rhash_lock_head __rcu *const *bkt; | |
| 220 | + struct rhash_head *he; | |
| 221 | + unsigned int hash; | |
| 222 | + struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht); | |
| 223 | +restart: | |
| 224 | + hash = rht_key_hashfn(ht, tbl, &inum, bch2_vfs_inodes_params); | |
| 225 | + bkt = rht_bucket(tbl, hash); | |
| 226 | + do { | |
| 227 | + struct bch_inode_info *inode; | |
| 228 | + | |
| 229 | + rht_for_each_entry_rcu_from(inode, he, rht_ptr_rcu(bkt), tbl, hash, hash) { | |
| 230 | + if (inode->ei_inum.inum == inum.inum) { | |
| 231 | + ret = darray_push_gfp(&subvols, inode->ei_inum.subvol, | |
| 232 | + GFP_NOWAIT|__GFP_NOWARN); | |
| 233 | + if (ret) { | |
| 234 | + rcu_read_unlock(); | |
| 235 | + ret = darray_make_room(&subvols, 1); | |
| 236 | + if (ret) | |
| 237 | + goto err; | |
| 238 | + subvols.nr = 0; | |
| 239 | + goto restart_from_top; | |
| 240 | + } | |
| 241 | + } | |
| 242 | + } | |
| 243 | + /* An object might have been moved to a different hash chain, | |
| 244 | + * while we walk along it - better check and retry. | |
| 245 | + */ | |
| 246 | + } while (he != RHT_NULLS_MARKER(bkt)); | |
| 247 | + | |
| 248 | + /* Ensure we see any new tables. */ | |
| 249 | + smp_rmb(); | |
| 250 | + | |
| 251 | + tbl = rht_dereference_rcu(tbl->future_tbl, ht); | |
| 252 | + if (unlikely(tbl)) | |
| 253 | + goto restart; | |
| 254 | + rcu_read_unlock(); | |
| 255 | + | |
| 256 | + darray_for_each(subvols, i) { | |
| 257 | + u32 snap; | |
| 258 | + ret = bch2_subvolume_get_snapshot(trans, *i, &snap); | |
| 259 | + if (ret) | |
| 260 | + goto err; | |
| 261 | + | |
| 262 | + ret = bch2_snapshot_is_ancestor(c, snap, p.snapshot); | |
| 263 | + if (ret) | |
| 264 | + break; | |
| 265 | + } | |
| 266 | +err: | |
| 267 | + darray_exit(&subvols); | |
| 268 | + return ret; | |
| 186 | 269 | } |
| 187 | 270 | |
| 188 | −struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum) | |
| 271 | +static struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum) | |
| 189 | 272 | { |
| 190 | 273 | return rhashtable_lookup_fast(&c->vfs_inodes_table, &inum, bch2_vfs_inodes_params); |
| 191 | 274 | } |
| 192 | 275 | |
| 276 | +static void __wait_on_freeing_inode(struct bch_fs *c, | |
| 277 | + struct bch_inode_info *inode, | |
| 278 | + subvol_inum inum) | |
| 279 | +{ | |
| 280 | + wait_queue_head_t *wq; | |
| 281 | + struct wait_bit_queue_entry wait; | |
| 282 | + | |
| 283 | + wq = inode_bit_waitqueue(&wait, &inode->v, __I_NEW); | |
| 284 | + prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE); | |
| 285 | + spin_unlock(&inode->v.i_lock); | |
| 286 | + | |
| 287 | + if (__bch2_inode_hash_find(c, inum) == inode) | |
| 288 | + schedule_timeout(HZ * 10); | |
| 289 | + finish_wait(wq, &wait.wq_entry); | |
| 290 | +} | |
| 291 | + | |
| 193 | 292 | static struct bch_inode_info *bch2_inode_hash_find(struct bch_fs *c, struct btree_trans *trans, |
| 194 | 293 | subvol_inum inum) |
| 195 | 294 | { |
| @@ -204,10 +303,10 @@ repeat: · 8 unmodified lines | ||
| 204 | 303 | } |
| 205 | 304 | if ((inode->v.i_state & (I_FREEING|I_WILL_FREE))) { |
| 206 | 305 | if (!trans) { |
| 207 | − __wait_on_freeing_inode(&inode->v); | |
| 306 | + __wait_on_freeing_inode(c, inode, inum); | |
| 208 | 307 | } else { |
| 209 | 308 | bch2_trans_unlock(trans); |
| 210 | − __wait_on_freeing_inode(&inode->v); | |
| 309 | + __wait_on_freeing_inode(c, inode, inum); | |
| 211 | 310 | int ret = bch2_trans_relock(trans); |
| 212 | 311 | if (ret) |
| 213 | 312 | return ERR_PTR(ret); |
| @@ -232,6 +331,11 @@ static void bch2_inode_hash_remove(struct bch_fs *c, struct bch_inode_info *inod · 18 unmodified lines | ||
| 232 | 331 | &inode->hash, bch2_vfs_inodes_params); |
| 233 | 332 | BUG_ON(ret); |
| 234 | 333 | inode->v.i_hash.pprev = NULL; |
| 334 | + /* | |
| 335 | + * This pairs with the bch2_inode_hash_find() -> | |
| 336 | + * __wait_on_freeing_inode() path | |
| 337 | + */ | |
| 338 | + inode_wake_up_bit(&inode->v, __I_NEW); | |
| 235 | 339 | } |
| 236 | 340 | } |
| 237 | 341 | |
| @@ -243,7 +347,8 @@ static struct bch_inode_info *bch2_inode_hash_insert(struct bch_fs *c, · 5 unmodified lines | ||
| 243 | 347 | |
| 244 | 348 | set_bit(EI_INODE_HASHED, &inode->ei_flags); |
| 245 | 349 | retry: |
| 246 | − if (unlikely(rhashtable_lookup_insert_fast(&c->vfs_inodes_table, | |
| 350 | + if (unlikely(rhashtable_lookup_insert_key(&c->vfs_inodes_table, | |
| 351 | + &inode->ei_inum, | |
| 247 | 352 | &inode->hash, |
| 248 | 353 | bch2_vfs_inodes_params))) { |
| 249 | 354 | old = bch2_inode_hash_find(c, trans, inode->ei_inum); |
| @@ -291,10 +396,10 @@ static struct inode *bch2_alloc_inode(struct super_block *sb) · 41 unmodified lines | ||
| 291 | 396 | BUG(); |
| 292 | 397 | } |
| 293 | 398 | |
| 294 | −static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c) | |
| 399 | +static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c, gfp_t gfp) | |
| 295 | 400 | { |
| 296 | 401 | struct bch_inode_info *inode = alloc_inode_sb(c->vfs_sb, |
| 297 | − bch2_inode_cache, GFP_NOFS); | |
| 402 | + bch2_inode_cache, gfp); | |
| 298 | 403 | if (!inode) |
| 299 | 404 | return NULL; |
| 300 | 405 | |
| @@ -306,7 +411,7 @@ static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c) · 5 unmodified lines | ||
| 306 | 411 | mutex_init(&inode->ei_quota_lock); |
| 307 | 412 | memset(&inode->ei_devs_need_flush, 0, sizeof(inode->ei_devs_need_flush)); |
| 308 | 413 | |
| 309 | − if (unlikely(inode_init_always(c->vfs_sb, &inode->v))) { | |
| 414 | + if (unlikely(inode_init_always_gfp(c->vfs_sb, &inode->v, gfp))) { | |
| 310 | 415 | kmem_cache_free(bch2_inode_cache, inode); |
| 311 | 416 | return NULL; |
| 312 | 417 | } |
| @@ -319,12 +424,10 @@ static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c) · 6 unmodified lines | ||
| 319 | 424 | */ |
| 320 | 425 | static struct bch_inode_info *bch2_new_inode(struct btree_trans *trans) |
| 321 | 426 | { |
| 322 | − struct bch_inode_info *inode = | |
| 323 | − memalloc_flags_do(PF_MEMALLOC_NORECLAIM|PF_MEMALLOC_NOWARN, | |
| 324 | − __bch2_new_inode(trans->c)); | |
| 427 | + struct bch_inode_info *inode = __bch2_new_inode(trans->c, GFP_NOWAIT); | |
| 325 | 428 | |
| 326 | 429 | if (unlikely(!inode)) { |
| 327 | − int ret = drop_locks_do(trans, (inode = __bch2_new_inode(trans->c)) ? 0 : -ENOMEM); | |
| 430 | + int ret = drop_locks_do(trans, (inode = __bch2_new_inode(trans->c, GFP_NOFS)) ? 0 : -ENOMEM); | |
| 328 | 431 | if (ret && inode) { |
| 329 | 432 | __destroy_inode(&inode->v); |
| 330 | 433 | kmem_cache_free(bch2_inode_cache, inode); |
| @@ -398,7 +501,7 @@ __bch2_create(struct mnt_idmap *idmap, · 67 unmodified lines | ||
| 398 | 501 | if (ret) |
| 399 | 502 | return ERR_PTR(ret); |
| 400 | 503 | #endif |
| 401 | − inode = __bch2_new_inode(c); | |
| 504 | + inode = __bch2_new_inode(c, GFP_NOFS); | |
| 402 | 505 | if (unlikely(!inode)) { |
| 403 | 506 | inode = ERR_PTR(-ENOMEM); |
| 404 | 507 | goto err; |
| @@ -553,7 +656,7 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry, · 148 unmodified lines | ||
| 553 | 656 | struct bch_hash_info hash = bch2_hash_info_init(c, &dir->ei_inode); |
| 554 | 657 | |
| 555 | 658 | struct bch_inode_info *inode; |
| 556 | − bch2_trans_do(c, NULL, NULL, 0, | |
| 659 | + bch2_trans_do(c, | |
| 557 | 660 | PTR_ERR_OR_ZERO(inode = bch2_lookup_trans(trans, inode_inum(dir), |
| 558 | 661 | &hash, &dentry->d_name))); |
| 559 | 662 | if (IS_ERR(inode)) |
| @@ -766,7 +869,7 @@ static int bch2_rename2(struct mnt_idmap *idmap, · 206 unmodified lines | ||
| 766 | 869 | ret = bch2_subvol_is_ro_trans(trans, src_dir->ei_inum.subvol) ?: |
| 767 | 870 | bch2_subvol_is_ro_trans(trans, dst_dir->ei_inum.subvol); |
| 768 | 871 | if (ret) |
| 769 | − goto err; | |
| 872 | + goto err_tx_restart; | |
| 770 | 873 | |
| 771 | 874 | if (inode_attr_changing(dst_dir, src_inode, Inode_opt_project)) { |
| 772 | 875 | ret = bch2_fs_quota_transfer(c, src_inode, |
| @@ -1163,7 +1266,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, · 390 unmodified lines | ||
| 1163 | 1266 | bch2_trans_iter_init(trans, &iter, BTREE_ID_extents, |
| 1164 | 1267 | POS(ei->v.i_ino, start), 0); |
| 1165 | 1268 | |
| 1166 | − while (true) { | |
| 1269 | + while (!ret || bch2_err_matches(ret, BCH_ERR_transaction_restart)) { | |
| 1167 | 1270 | enum btree_id data_btree = BTREE_ID_extents; |
| 1168 | 1271 | |
| 1169 | 1272 | bch2_trans_begin(trans); |
| @@ -1171,14 +1274,14 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, · 1 unmodified line | ||
| 1171 | 1274 | u32 snapshot; |
| 1172 | 1275 | ret = bch2_subvolume_get_snapshot(trans, ei->ei_inum.subvol, &snapshot); |
| 1173 | 1276 | if (ret) |
| 1174 | − goto err; | |
| 1277 | + continue; | |
| 1175 | 1278 | |
| 1176 | 1279 | bch2_btree_iter_set_snapshot(&iter, snapshot); |
| 1177 | 1280 | |
| 1178 | 1281 | k = bch2_btree_iter_peek_upto(&iter, end); |
| 1179 | 1282 | ret = bkey_err(k); |
| 1180 | 1283 | if (ret) |
| 1181 | − goto err; | |
| 1284 | + continue; | |
| 1182 | 1285 | |
| 1183 | 1286 | if (!k.k) |
| 1184 | 1287 | break; |
| @@ -1198,7 +1301,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, · 13 unmodified lines | ||
| 1198 | 1301 | ret = bch2_read_indirect_extent(trans, &data_btree, |
| 1199 | 1302 | &offset_into_extent, &cur); |
| 1200 | 1303 | if (ret) |
| 1201 | − break; | |
| 1304 | + continue; | |
| 1202 | 1305 | |
| 1203 | 1306 | k = bkey_i_to_s_c(cur.k); |
| 1204 | 1307 | bch2_bkey_buf_realloc(&prev, c, k.k->u64s); |
| @@ -1226,10 +1329,6 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, · 21 unmodified lines | ||
| 1226 | 1329 | |
| 1227 | 1330 | bch2_btree_iter_set_pos(&iter, |
| 1228 | 1331 | POS(iter.pos.inode, iter.pos.offset + sectors)); |
| 1229 | −err: | |
| 1230 | − if (ret && | |
| 1231 | − !bch2_err_matches(ret, BCH_ERR_transaction_restart)) | |
| 1232 | − break; | |
| 1233 | 1332 | } |
| 1234 | 1333 | bch2_trans_iter_exit(trans, &iter); |
| 1235 | 1334 | |
| @@ -1937,7 +2036,7 @@ static int bch2_show_options(struct seq_file *seq, struct dentry *root) · 701 unmodified lines | ||
| 1937 | 2036 | bch2_opts_to_text(&buf, c->opts, c, c->disk_sb.sb, |
| 1938 | 2037 | OPT_MOUNT, OPT_HIDDEN, OPT_SHOW_MOUNT_STYLE); |
| 1939 | 2038 | printbuf_nul_terminate(&buf); |
| 1940 | − seq_puts(seq, buf.buf); | |
| 2039 | + seq_printf(seq, ",%s", buf.buf); | |
| 1941 | 2040 | |
| 1942 | 2041 | int ret = buf.allocation_failure ? -ENOMEM : 0; |
| 1943 | 2042 | printbuf_exit(&buf); |
| @@ -54,8 +54,6 @@ static inline subvol_inum inode_inum(struct bch_inode_info *inode) · 53 unmodified lines | ||
| 54 | 54 | return inode->ei_inum; |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | −struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *, subvol_inum); | |
| 58 | − | |
| 59 | 57 | /* |
| 60 | 58 | * Set if we've gotten a btree error for this inode, and thus the vfs inode and |
| 61 | 59 | * btree inode may be inconsistent: |
| @@ -148,6 +146,8 @@ struct bch_inode_info * · 86 unmodified lines | ||
| 148 | 146 | __bch2_create(struct mnt_idmap *, struct bch_inode_info *, |
| 149 | 147 | struct dentry *, umode_t, dev_t, subvol_inum, unsigned); |
| 150 | 148 | |
| 149 | +int bch2_inode_or_descendents_is_open(struct btree_trans *trans, struct bpos p); | |
| 150 | + | |
| 151 | 151 | int bch2_fs_quota_transfer(struct bch_fs *, |
| 152 | 152 | struct bch_inode_info *, |
| 153 | 153 | struct bch_qid, |
| @@ -198,10 +198,7 @@ int bch2_vfs_init(void); · 44 unmodified lines | ||
| 198 | 198 | |
| 199 | 199 | #define bch2_inode_update_after_write(_trans, _inode, _inode_u, _fields) ({ do {} while (0); }) |
| 200 | 200 | |
| 201 | −static inline struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum) | |
| 202 | −{ | |
| 203 | − return NULL; | |
| 204 | −} | |
| 201 | +static inline int bch2_inode_or_descendents_is_open(struct btree_trans *trans, struct bpos p) { return 0; } | |
| 205 | 202 | |
| 206 | 203 | static inline void bch2_evict_subvolume_inodes(struct bch_fs *c, |
| 207 | 204 | snapshot_id_list *s) {} |
| @@ -28,8 +28,8 @@ static bool inode_points_to_dirent(struct bch_inode_unpacked *inode, · 27 unmodified lines | ||
| 28 | 28 | inode->bi_dir_offset == d.k->p.offset; |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | −static bool dirent_points_to_inode_nowarn(struct bkey_s_c_dirent d, | |
| 32 | − struct bch_inode_unpacked *inode) | |
| 31 | +static int dirent_points_to_inode_nowarn(struct bkey_s_c_dirent d, | |
| 32 | + struct bch_inode_unpacked *inode) | |
| 33 | 33 | { |
| 34 | 34 | if (d.v->d_type == DT_SUBVOL |
| 35 | 35 | ? le32_to_cpu(d.v->d_child_subvol) == inode->bi_subvol |
| @@ -137,16 +137,15 @@ found: · 101 unmodified lines | ||
| 137 | 137 | return ret; |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | −static int lookup_inode(struct btree_trans *trans, u64 inode_nr, | |
| 141 | − struct bch_inode_unpacked *inode, | |
| 142 | − u32 *snapshot) | |
| 140 | +static int lookup_inode(struct btree_trans *trans, u64 inode_nr, u32 snapshot, | |
| 141 | + struct bch_inode_unpacked *inode) | |
| 143 | 142 | { |
| 144 | 143 | struct btree_iter iter; |
| 145 | 144 | struct bkey_s_c k; |
| 146 | 145 | int ret; |
| 147 | 146 | |
| 148 | 147 | k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes, |
| 149 | − SPOS(0, inode_nr, *snapshot), 0); | |
| 148 | + SPOS(0, inode_nr, snapshot), 0); | |
| 150 | 149 | ret = bkey_err(k); |
| 151 | 150 | if (ret) |
| 152 | 151 | goto err; |
| @@ -154,8 +153,6 @@ static int lookup_inode(struct btree_trans *trans, u64 inode_nr, · 1 unmodified line | ||
| 154 | 153 | ret = bkey_is_inode(k.k) |
| 155 | 154 | ? bch2_inode_unpack(k, inode) |
| 156 | 155 | : -BCH_ERR_ENOENT_inode; |
| 157 | − if (!ret) | |
| 158 | − *snapshot = iter.pos.snapshot; | |
| 159 | 156 | err: |
| 160 | 157 | bch2_trans_iter_exit(trans, &iter); |
| 161 | 158 | return ret; |
| @@ -250,8 +247,7 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, · 88 unmodified lines | ||
| 250 | 247 | |
| 251 | 248 | struct bch_inode_unpacked root_inode; |
| 252 | 249 | struct bch_hash_info root_hash_info; |
| 253 | − u32 root_inode_snapshot = snapshot; | |
| 254 | − ret = lookup_inode(trans, root_inum.inum, &root_inode, &root_inode_snapshot); | |
| 250 | + ret = lookup_inode(trans, root_inum.inum, snapshot, &root_inode); | |
| 255 | 251 | bch_err_msg(c, ret, "looking up root inode %llu for subvol %u", |
| 256 | 252 | root_inum.inum, le32_to_cpu(st.master_subvol)); |
| 257 | 253 | if (ret) |
| @@ -277,17 +273,23 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, · 19 unmodified lines | ||
| 277 | 273 | * The bch2_check_dirents pass has already run, dangling dirents |
| 278 | 274 | * shouldn't exist here: |
| 279 | 275 | */ |
| 280 | − ret = lookup_inode(trans, inum, lostfound, &snapshot); | |
| 276 | + ret = lookup_inode(trans, inum, snapshot, lostfound); | |
| 281 | 277 | bch_err_msg(c, ret, "looking up lost+found %llu:%u in (root inode %llu, snapshot root %u)", |
| 282 | 278 | inum, snapshot, root_inum.inum, bch2_snapshot_root(c, snapshot)); |
| 283 | 279 | return ret; |
| 284 | 280 | |
| 285 | 281 | create_lostfound: |
| 282 | + /* | |
| 283 | + * we always create lost+found in the root snapshot; we don't want | |
| 284 | + * different branches of the snapshot tree to have different lost+found | |
| 285 | + */ | |
| 286 | + snapshot = le32_to_cpu(st.root_snapshot); | |
| 286 | 287 | /* |
| 287 | 288 | * XXX: we could have a nicer log message here if we had a nice way to |
| 288 | 289 | * walk backpointers to print a path |
| 289 | 290 | */ |
| 290 | − bch_notice(c, "creating lost+found in snapshot %u", le32_to_cpu(st.root_snapshot)); | |
| 291 | + bch_notice(c, "creating lost+found in subvol %llu snapshot %u", | |
| 292 | + root_inum.subvol, le32_to_cpu(st.root_snapshot)); | |
| 291 | 293 | |
| 292 | 294 | u64 now = bch2_current_time(c); |
| 293 | 295 | struct btree_iter lostfound_iter = { NULL }; |
| @@ -296,6 +298,7 @@ create_lostfound: · 2 unmodified lines | ||
| 296 | 298 | bch2_inode_init_early(c, lostfound); |
| 297 | 299 | bch2_inode_init_late(lostfound, now, 0, 0, S_IFDIR|0700, 0, &root_inode); |
| 298 | 300 | lostfound->bi_dir = root_inode.bi_inum; |
| 301 | + lostfound->bi_snapshot = le32_to_cpu(st.root_snapshot); | |
| 299 | 302 | |
| 300 | 303 | root_inode.bi_nlink++; |
| 301 | 304 | |
| @@ -323,19 +326,54 @@ err: · 21 unmodified lines | ||
| 323 | 326 | return ret; |
| 324 | 327 | } |
| 325 | 328 | |
| 326 | −static int reattach_inode(struct btree_trans *trans, | |
| 327 | − struct bch_inode_unpacked *inode, | |
| 328 | − u32 inode_snapshot) | |
| 329 | +static inline bool inode_should_reattach(struct bch_inode_unpacked *inode) | |
| 330 | +{ | |
| 331 | + if (inode->bi_inum == BCACHEFS_ROOT_INO && | |
| 332 | + inode->bi_subvol == BCACHEFS_ROOT_SUBVOL) | |
| 333 | + return false; | |
| 334 | + | |
| 335 | + return !inode->bi_dir && !(inode->bi_flags & BCH_INODE_unlinked); | |
| 336 | +} | |
| 337 | + | |
| 338 | +static int maybe_delete_dirent(struct btree_trans *trans, struct bpos d_pos, u32 snapshot) | |
| 339 | +{ | |
| 340 | + struct btree_iter iter; | |
| 341 | + struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_dirents, | |
| 342 | + SPOS(d_pos.inode, d_pos.offset, snapshot), | |
| 343 | + BTREE_ITER_intent| | |
| 344 | + BTREE_ITER_with_updates); | |
| 345 | + int ret = bkey_err(k); | |
| 346 | + if (ret) | |
| 347 | + return ret; | |
| 348 | + | |
| 349 | + if (bpos_eq(k.k->p, d_pos)) { | |
| 350 | + /* | |
| 351 | + * delet_at() doesn't work because the update path doesn't | |
| 352 | + * internally use BTREE_ITER_with_updates yet | |
| 353 | + */ | |
| 354 | + struct bkey_i *k = bch2_trans_kmalloc(trans, sizeof(*k)); | |
| 355 | + ret = PTR_ERR_OR_ZERO(k); | |
| 356 | + if (ret) | |
| 357 | + goto err; | |
| 358 | + | |
| 359 | + bkey_init(&k->k); | |
| 360 | + k->k.type = KEY_TYPE_whiteout; | |
| 361 | + k->k.p = iter.pos; | |
| 362 | + ret = bch2_trans_update(trans, &iter, k, BTREE_UPDATE_internal_snapshot_node); | |
| 363 | + } | |
| 364 | +err: | |
| 365 | + bch2_trans_iter_exit(trans, &iter); | |
| 366 | + return ret; | |
| 367 | +} | |
| 368 | + | |
| 369 | +static int reattach_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode) | |
| 329 | 370 | { |
| 330 | 371 | struct bch_fs *c = trans->c; |
| 331 | − struct bch_hash_info dir_hash; | |
| 332 | 372 | struct bch_inode_unpacked lostfound; |
| 333 | 373 | char name_buf[20]; |
| 334 | − struct qstr name; | |
| 335 | − u64 dir_offset = 0; | |
| 336 | − u32 dirent_snapshot = inode_snapshot; | |
| 337 | 374 | int ret; |
| 338 | 375 | |
| 376 | + u32 dirent_snapshot = inode->bi_snapshot; | |
| 339 | 377 | if (inode->bi_subvol) { |
| 340 | 378 | inode->bi_parent_subvol = BCACHEFS_ROOT_SUBVOL; |
| 341 | 379 | |
| @@ -354,17 +392,22 @@ static int reattach_inode(struct btree_trans *trans, · 12 unmodified lines | ||
| 354 | 392 | if (ret) |
| 355 | 393 | return ret; |
| 356 | 394 | |
| 357 | − if (S_ISDIR(inode->bi_mode)) { | |
| 358 | − lostfound.bi_nlink++; | |
| 395 | + lostfound.bi_nlink += S_ISDIR(inode->bi_mode); | |
| 359 | 396 | |
| 360 | − ret = __bch2_fsck_write_inode(trans, &lostfound, U32_MAX); | |
| 361 | − if (ret) | |
| 362 | − return ret; | |
| 397 | + /* ensure lost+found inode is also present in inode snapshot */ | |
| 398 | + if (!inode->bi_subvol) { | |
| 399 | + BUG_ON(!bch2_snapshot_is_ancestor(c, inode->bi_snapshot, lostfound.bi_snapshot)); | |
| 400 | + lostfound.bi_snapshot = inode->bi_snapshot; | |
| 363 | 401 | } |
| 364 | 402 | |
| 365 | − dir_hash = bch2_hash_info_init(c, &lostfound); | |
| 403 | + ret = __bch2_fsck_write_inode(trans, &lostfound); | |
| 404 | + if (ret) | |
| 405 | + return ret; | |
| 406 | + | |
| 407 | + struct bch_hash_info dir_hash = bch2_hash_info_init(c, &lostfound); | |
| 408 | + struct qstr name = (struct qstr) QSTR(name_buf); | |
| 366 | 409 | |
| 367 | − name = (struct qstr) QSTR(name_buf); | |
| 410 | + inode->bi_dir = lostfound.bi_inum; | |
| 368 | 411 | |
| 369 | 412 | ret = bch2_dirent_create_snapshot(trans, |
| 370 | 413 | inode->bi_parent_subvol, lostfound.bi_inum, |
| @@ -373,17 +416,70 @@ static int reattach_inode(struct btree_trans *trans, · 2 unmodified lines | ||
| 373 | 416 | inode_d_type(inode), |
| 374 | 417 | &name, |
| 375 | 418 | inode->bi_subvol ?: inode->bi_inum, |
| 376 | − &dir_offset, | |
| 419 | + &inode->bi_dir_offset, | |
| 377 | 420 | STR_HASH_must_create); |
| 378 | 421 | if (ret) { |
| 379 | 422 | bch_err_msg(c, ret, "error creating dirent"); |
| 380 | 423 | return ret; |
| 381 | 424 | } |
| 382 | 425 | |
| 383 | − inode->bi_dir = lostfound.bi_inum; | |
| 384 | − inode->bi_dir_offset = dir_offset; | |
| 426 | + ret = __bch2_fsck_write_inode(trans, inode); | |
| 427 | + if (ret) | |
| 428 | + return ret; | |
| 429 | + | |
| 430 | + /* | |
| 431 | + * Fix up inodes in child snapshots: if they should also be reattached | |
| 432 | + * update the backpointer field, if they should not be we need to emit | |
| 433 | + * whiteouts for the dirent we just created. | |
| 434 | + */ | |
| 435 | + if (!inode->bi_subvol && bch2_snapshot_is_leaf(c, inode->bi_snapshot) <= 0) { | |
| 436 | + snapshot_id_list whiteouts_done; | |
| 437 | + struct btree_iter iter; | |
| 438 | + struct bkey_s_c k; | |
| 439 | + | |
| 440 | + darray_init(&whiteouts_done); | |
| 441 | + | |
| 442 | + for_each_btree_key_reverse_norestart(trans, iter, | |
| 443 | + BTREE_ID_inodes, SPOS(0, inode->bi_inum, inode->bi_snapshot - 1), | |
| 444 | + BTREE_ITER_all_snapshots|BTREE_ITER_intent, k, ret) { | |
| 445 | + if (k.k->p.offset != inode->bi_inum) | |
| 446 | + break; | |
| 447 | + | |
| 448 | + if (!bkey_is_inode(k.k) || | |
| 449 | + !bch2_snapshot_is_ancestor(c, k.k->p.snapshot, inode->bi_snapshot) || | |
| 450 | + snapshot_list_has_ancestor(c, &whiteouts_done, k.k->p.snapshot)) | |
| 451 | + continue; | |
| 452 | + | |
| 453 | + struct bch_inode_unpacked child_inode; | |
| 454 | + bch2_inode_unpack(k, &child_inode); | |
| 455 | + | |
| 456 | + if (!inode_should_reattach(&child_inode)) { | |
| 457 | + ret = maybe_delete_dirent(trans, | |
| 458 | + SPOS(lostfound.bi_inum, inode->bi_dir_offset, | |
| 459 | + dirent_snapshot), | |
| 460 | + k.k->p.snapshot); | |
| 461 | + if (ret) | |
| 462 | + break; | |
| 463 | + | |
| 464 | + ret = snapshot_list_add(c, &whiteouts_done, k.k->p.snapshot); | |
| 465 | + if (ret) | |
| 466 | + break; | |
| 467 | + } else { | |
| 468 | + iter.snapshot = k.k->p.snapshot; | |
| 469 | + child_inode.bi_dir = inode->bi_dir; | |
| 470 | + child_inode.bi_dir_offset = inode->bi_dir_offset; | |
| 471 | + | |
| 472 | + ret = bch2_inode_write_flags(trans, &iter, &child_inode, | |
| 473 | + BTREE_UPDATE_internal_snapshot_node); | |
| 474 | + if (ret) | |
| 475 | + break; | |
| 476 | + } | |
| 477 | + } | |
| 478 | + darray_exit(&whiteouts_done); | |
| 479 | + bch2_trans_iter_exit(trans, &iter); | |
| 480 | + } | |
| 385 | 481 | |
| 386 | − return __bch2_fsck_write_inode(trans, inode, inode_snapshot); | |
| 482 | + return ret; | |
| 387 | 483 | } |
| 388 | 484 | |
| 389 | 485 | static int remove_backpointer(struct btree_trans *trans, |
| @@ -422,7 +518,7 @@ static int reattach_subvol(struct btree_trans *trans, struct bkey_s_c_subvolume · 32 unmodified lines | ||
| 422 | 518 | if (ret) |
| 423 | 519 | return ret; |
| 424 | 520 | |
| 425 | − ret = reattach_inode(trans, &inode, le32_to_cpu(s.v->snapshot)); | |
| 521 | + ret = reattach_inode(trans, &inode); | |
| 426 | 522 | bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum); |
| 427 | 523 | return ret; |
| 428 | 524 | } |
| @@ -540,8 +636,9 @@ static int reconstruct_inode(struct btree_trans *trans, enum btree_id btree, u32 · 111 unmodified lines | ||
| 540 | 636 | bch2_inode_init_late(&new_inode, bch2_current_time(c), 0, 0, i_mode|0600, 0, NULL); |
| 541 | 637 | new_inode.bi_size = i_size; |
| 542 | 638 | new_inode.bi_inum = inum; |
| 639 | + new_inode.bi_snapshot = snapshot; | |
| 543 | 640 | |
| 544 | − return __bch2_fsck_write_inode(trans, &new_inode, snapshot); | |
| 641 | + return __bch2_fsck_write_inode(trans, &new_inode); | |
| 545 | 642 | } |
| 546 | 643 | |
| 547 | 644 | struct snapshots_seen { |
| @@ -832,35 +929,138 @@ static int get_visible_inodes(struct btree_trans *trans, · 284 unmodified lines | ||
| 832 | 929 | return ret; |
| 833 | 930 | } |
| 834 | 931 | |
| 835 | −static int hash_redo_key(struct btree_trans *trans, | |
| 836 | − const struct bch_hash_desc desc, | |
| 837 | − struct bch_hash_info *hash_info, | |
| 838 | − struct btree_iter *k_iter, struct bkey_s_c k) | |
| 932 | +static int dirent_has_target(struct btree_trans *trans, struct bkey_s_c_dirent d) | |
| 839 | 933 | { |
| 840 | − struct bkey_i *delete; | |
| 841 | − struct bkey_i *tmp; | |
| 934 | + if (d.v->d_type == DT_SUBVOL) { | |
| 935 | + u32 snap; | |
| 936 | + u64 inum; | |
| 937 | + int ret = subvol_lookup(trans, le32_to_cpu(d.v->d_child_subvol), &snap, &inum); | |
| 938 | + if (ret && !bch2_err_matches(ret, ENOENT)) | |
| 939 | + return ret; | |
| 940 | + return !ret; | |
| 941 | + } else { | |
| 942 | + struct btree_iter iter; | |
| 943 | + struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes, | |
| 944 | + SPOS(0, le64_to_cpu(d.v->d_inum), d.k->p.snapshot), 0); | |
| 945 | + int ret = bkey_err(k); | |
| 946 | + if (ret) | |
| 947 | + return ret; | |
| 948 | + | |
| 949 | + ret = bkey_is_inode(k.k); | |
| 950 | + bch2_trans_iter_exit(trans, &iter); | |
| 951 | + return ret; | |
| 952 | + } | |
| 953 | +} | |
| 842 | 954 | |
| 843 | − delete = bch2_trans_kmalloc(trans, sizeof(*delete)); | |
| 844 | − if (IS_ERR(delete)) | |
| 845 | − return PTR_ERR(delete); | |
| 955 | +/* | |
| 956 | + * Prefer to delete the first one, since that will be the one at the wrong | |
| 957 | + * offset: | |
| 958 | + * return value: 0 -> delete k1, 1 -> delete k2 | |
| 959 | + */ | |
| 960 | +static int hash_pick_winner(struct btree_trans *trans, | |
| 961 | + const struct bch_hash_desc desc, | |
| 962 | + struct bch_hash_info *hash_info, | |
| 963 | + struct bkey_s_c k1, | |
| 964 | + struct bkey_s_c k2) | |
| 965 | +{ | |
| 966 | + if (bkey_val_bytes(k1.k) == bkey_val_bytes(k2.k) && | |
| 967 | + !memcmp(k1.v, k2.v, bkey_val_bytes(k1.k))) | |
| 968 | + return 0; | |
| 846 | 969 | |
| 847 | − tmp = bch2_bkey_make_mut_noupdate(trans, k); | |
| 848 | − if (IS_ERR(tmp)) | |
| 849 | − return PTR_ERR(tmp); | |
| 970 | + switch (desc.btree_id) { | |
| 971 | + case BTREE_ID_dirents: { | |
| 972 | + int ret = dirent_has_target(trans, bkey_s_c_to_dirent(k1)); | |
| 973 | + if (ret < 0) | |
| 974 | + return ret; | |
| 975 | + if (!ret) | |
| 976 | + return 0; | |
| 850 | 977 | |
| 851 | − bkey_init(&delete->k); | |
| 852 | − delete->k.p = k_iter->pos; | |
| 853 | − return bch2_btree_iter_traverse(k_iter) ?: | |
| 854 | − bch2_trans_update(trans, k_iter, delete, 0) ?: | |
| 855 | − bch2_hash_set_in_snapshot(trans, desc, hash_info, | |
| 856 | − (subvol_inum) { 0, k.k->p.inode }, | |
| 857 | − k.k->p.snapshot, tmp, | |
| 858 | − STR_HASH_must_create| | |
| 859 | − BTREE_UPDATE_internal_snapshot_node) ?: | |
| 860 | − bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc); | |
| 978 | + ret = dirent_has_target(trans, bkey_s_c_to_dirent(k2)); | |
| 979 | + if (ret < 0) | |
| 980 | + return ret; | |
| 981 | + if (!ret) | |
| 982 | + return 1; | |
| 983 | + return 2; | |
| 984 | + } | |
| 985 | + default: | |
| 986 | + return 0; | |
| 987 | + } | |
| 988 | +} | |
| 989 | + | |
| 990 | +static int fsck_update_backpointers(struct btree_trans *trans, | |
| 991 | + struct snapshots_seen *s, | |
| 992 | + const struct bch_hash_desc desc, | |
| 993 | + struct bch_hash_info *hash_info, | |
| 994 | + struct bkey_i *new) | |
| 995 | +{ | |
| 996 | + if (new->k.type != KEY_TYPE_dirent) | |
| 997 | + return 0; | |
| 998 | + | |
| 999 | + struct bkey_i_dirent *d = bkey_i_to_dirent(new); | |
| 1000 | + struct inode_walker target = inode_walker_init(); | |
| 1001 | + int ret = 0; | |
| 1002 | + | |
| 1003 | + if (d->v.d_type == DT_SUBVOL) { | |
| 1004 | + BUG(); | |
| 1005 | + } else { | |
| 1006 | + ret = get_visible_inodes(trans, &target, s, le64_to_cpu(d->v.d_inum)); | |
| 1007 | + if (ret) | |
| 1008 | + goto err; | |
| 1009 | + | |
| 1010 | + darray_for_each(target.inodes, i) { | |
| 1011 | + i->inode.bi_dir_offset = d->k.p.offset; | |
| 1012 | + ret = __bch2_fsck_write_inode(trans, &i->inode); | |
| 1013 | + if (ret) | |
| 1014 | + goto err; | |
| 1015 | + } | |
| 1016 | + } | |
| 1017 | +err: | |
| 1018 | + inode_walker_exit(&target); | |
| 1019 | + return ret; | |
| 1020 | +} | |
| 1021 | + | |
| 1022 | +static int fsck_rename_dirent(struct btree_trans *trans, | |
| 1023 | + struct snapshots_seen *s, | |
| 1024 | + const struct bch_hash_desc desc, | |
| 1025 | + struct bch_hash_info *hash_info, | |
| 1026 | + struct bkey_s_c_dirent old) | |
| 1027 | +{ | |
| 1028 | + struct qstr old_name = bch2_dirent_get_name(old); | |
| 1029 | + struct bkey_i_dirent *new = bch2_trans_kmalloc(trans, bkey_bytes(old.k) + 32); | |
| 1030 | + int ret = PTR_ERR_OR_ZERO(new); | |
| 1031 | + if (ret) | |
| 1032 | + return ret; | |
| 1033 | + | |
| 1034 | + bkey_dirent_init(&new->k_i); | |
| 1035 | + dirent_copy_target(new, old); | |
| 1036 | + new->k.p = old.k->p; | |
| 1037 | + | |
| 1038 | + for (unsigned i = 0; i < 1000; i++) { | |
| 1039 | + unsigned len = sprintf(new->v.d_name, "%.*s.fsck_renamed-%u", | |
| 1040 | + old_name.len, old_name.name, i); | |
| 1041 | + unsigned u64s = BKEY_U64s + dirent_val_u64s(len); | |
| 1042 | + | |
| 1043 | + if (u64s > U8_MAX) | |
| 1044 | + return -EINVAL; | |
| 1045 | + | |
| 1046 | + new->k.u64s = u64s; | |
| 1047 | + | |
| 1048 | + ret = bch2_hash_set_in_snapshot(trans, bch2_dirent_hash_desc, hash_info, | |
| 1049 | + (subvol_inum) { 0, old.k->p.inode }, | |
| 1050 | + old.k->p.snapshot, &new->k_i, | |
| 1051 | + BTREE_UPDATE_internal_snapshot_node); | |
| 1052 | + if (!bch2_err_matches(ret, EEXIST)) | |
| 1053 | + break; | |
| 1054 | + } | |
| 1055 | + | |
| 1056 | + if (ret) | |
| 1057 | + return ret; | |
| 1058 | + | |
| 1059 | + return fsck_update_backpointers(trans, s, desc, hash_info, &new->k_i); | |
| 861 | 1060 | } |
| 862 | 1061 | |
| 863 | 1062 | static int hash_check_key(struct btree_trans *trans, |
| 1063 | + struct snapshots_seen *s, | |
| 864 | 1064 | const struct bch_hash_desc desc, |
| 865 | 1065 | struct bch_hash_info *hash_info, |
| 866 | 1066 | struct btree_iter *k_iter, struct bkey_s_c hash_k) |
| @@ -889,16 +1089,9 @@ static int hash_check_key(struct btree_trans *trans, · 22 unmodified lines | ||
| 889 | 1089 | if (bkey_eq(k.k->p, hash_k.k->p)) |
| 890 | 1090 | break; |
| 891 | 1091 | |
| 892 | − if (fsck_err_on(k.k->type == desc.key_type && | |
| 893 | − !desc.cmp_bkey(k, hash_k), | |
| 894 | − trans, hash_table_key_duplicate, | |
| 895 | − "duplicate hash table keys:\n%s", | |
| 896 | − (printbuf_reset(&buf), | |
| 897 | − bch2_bkey_val_to_text(&buf, c, hash_k), | |
| 898 | − buf.buf))) { | |
| 899 | − ret = bch2_hash_delete_at(trans, desc, hash_info, k_iter, 0) ?: 1; | |
| 900 | − break; | |
| 901 | − } | |
| 1092 | + if (k.k->type == desc.key_type && | |
| 1093 | + !desc.cmp_bkey(k, hash_k)) | |
| 1094 | + goto duplicate_entries; | |
| 902 | 1095 | |
| 903 | 1096 | if (bkey_deleted(k.k)) { |
| 904 | 1097 | bch2_trans_iter_exit(trans, &iter); |
| @@ -911,18 +1104,66 @@ out: · 6 unmodified lines | ||
| 911 | 1104 | return ret; |
| 912 | 1105 | bad_hash: |
| 913 | 1106 | if (fsck_err(trans, hash_table_key_wrong_offset, |
| 914 | − "hash table key at wrong offset: btree %s inode %llu offset %llu, hashed to %llu\n%s", | |
| 1107 | + "hash table key at wrong offset: btree %s inode %llu offset %llu, hashed to %llu\n %s", | |
| 915 | 1108 | bch2_btree_id_str(desc.btree_id), hash_k.k->p.inode, hash_k.k->p.offset, hash, |
| 916 | 1109 | (printbuf_reset(&buf), |
| 917 | 1110 | bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf))) { |
| 918 | − ret = hash_redo_key(trans, desc, hash_info, k_iter, hash_k); | |
| 919 | − bch_err_fn(c, ret); | |
| 1111 | + struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, hash_k); | |
| 1112 | + if (IS_ERR(new)) | |
| 1113 | + return PTR_ERR(new); | |
| 1114 | + | |
| 1115 | + k = bch2_hash_set_or_get_in_snapshot(trans, &iter, desc, hash_info, | |
| 1116 | + (subvol_inum) { 0, hash_k.k->p.inode }, | |
| 1117 | + hash_k.k->p.snapshot, new, | |
| 1118 | + STR_HASH_must_create| | |
| 1119 | + BTREE_ITER_with_updates| | |
| 1120 | + BTREE_UPDATE_internal_snapshot_node); | |
| 1121 | + ret = bkey_err(k); | |
| 920 | 1122 | if (ret) |
| 921 | − return ret; | |
| 922 | − ret = -BCH_ERR_transaction_restart_nested; | |
| 1123 | + goto out; | |
| 1124 | + if (k.k) | |
| 1125 | + goto duplicate_entries; | |
| 1126 | + | |
| 1127 | + ret = bch2_hash_delete_at(trans, desc, hash_info, k_iter, | |
| 1128 | + BTREE_UPDATE_internal_snapshot_node) ?: | |
| 1129 | + fsck_update_backpointers(trans, s, desc, hash_info, new) ?: | |
| 1130 | + bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc) ?: | |
| 1131 | + -BCH_ERR_transaction_restart_nested; | |
| 1132 | + goto out; | |
| 923 | 1133 | } |
| 924 | 1134 | fsck_err: |
| 925 | 1135 | goto out; |
| 1136 | +duplicate_entries: | |
| 1137 | + ret = hash_pick_winner(trans, desc, hash_info, hash_k, k); | |
| 1138 | + if (ret < 0) | |
| 1139 | + goto out; | |
| 1140 | + | |
| 1141 | + if (!fsck_err(trans, hash_table_key_duplicate, | |
| 1142 | + "duplicate hash table keys%s:\n%s", | |
| 1143 | + ret != 2 ? "" : ", both point to valid inodes", | |
| 1144 | + (printbuf_reset(&buf), | |
| 1145 | + bch2_bkey_val_to_text(&buf, c, hash_k), | |
| 1146 | + prt_newline(&buf), | |
| 1147 | + bch2_bkey_val_to_text(&buf, c, k), | |
| 1148 | + buf.buf))) | |
| 1149 | + goto out; | |
| 1150 | + | |
| 1151 | + switch (ret) { | |
| 1152 | + case 0: | |
| 1153 | + ret = bch2_hash_delete_at(trans, desc, hash_info, k_iter, 0); | |
| 1154 | + break; | |
| 1155 | + case 1: | |
| 1156 | + ret = bch2_hash_delete_at(trans, desc, hash_info, &iter, 0); | |
| 1157 | + break; | |
| 1158 | + case 2: | |
| 1159 | + ret = fsck_rename_dirent(trans, s, desc, hash_info, bkey_s_c_to_dirent(hash_k)) ?: | |
| 1160 | + bch2_hash_delete_at(trans, desc, hash_info, k_iter, 0); | |
| 1161 | + goto out; | |
| 1162 | + } | |
| 1163 | + | |
| 1164 | + ret = bch2_trans_commit(trans, NULL, NULL, 0) ?: | |
| 1165 | + -BCH_ERR_transaction_restart_nested; | |
| 1166 | + goto out; | |
| 926 | 1167 | } |
| 927 | 1168 | |
| 928 | 1169 | static struct bkey_s_c_dirent dirent_get_by_pos(struct btree_trans *trans, |
| @@ -988,7 +1229,6 @@ static int check_inode_dirent_inode(struct btree_trans *trans, · 59 unmodified lines | ||
| 988 | 1229 | */ |
| 989 | 1230 | inode->bi_dir = 0; |
| 990 | 1231 | inode->bi_dir_offset = 0; |
| 991 | − inode->bi_flags &= ~BCH_INODE_backptr_untrusted; | |
| 992 | 1232 | *write_inode = true; |
| 993 | 1233 | } |
| 994 | 1234 | |
| @@ -1000,30 +1240,40 @@ fsck_err: · 5 unmodified lines | ||
| 1000 | 1240 | return ret; |
| 1001 | 1241 | } |
| 1002 | 1242 | |
| 1003 | −static bool bch2_inode_is_open(struct bch_fs *c, struct bpos p) | |
| 1243 | +static int get_snapshot_root_inode(struct btree_trans *trans, | |
| 1244 | + struct bch_inode_unpacked *root, | |
| 1245 | + u64 inum) | |
| 1004 | 1246 | { |
| 1005 | − subvol_inum inum = { | |
| 1006 | − .subvol = snapshot_t(c, p.snapshot)->subvol, | |
| 1007 | − .inum = p.offset, | |
| 1008 | − }; | |
| 1247 | + struct btree_iter iter; | |
| 1248 | + struct bkey_s_c k; | |
| 1249 | + int ret = 0; | |
| 1009 | 1250 | |
| 1010 | − /* snapshot tree corruption, can't safely delete */ | |
| 1011 | − if (!inum.subvol) { | |
| 1012 | − bch_warn_ratelimited(c, "%s(): snapshot %u has no subvol, unlinked but can't safely delete", __func__, p.snapshot); | |
| 1013 | − return true; | |
| 1251 | + for_each_btree_key_reverse_norestart(trans, iter, BTREE_ID_inodes, | |
| 1252 | + SPOS(0, inum, U32_MAX), | |
| 1253 | + BTREE_ITER_all_snapshots, k, ret) { | |
| 1254 | + if (k.k->p.offset != inum) | |
| 1255 | + break; | |
| 1256 | + if (bkey_is_inode(k.k)) | |
| 1257 | + goto found_root; | |
| 1014 | 1258 | } |
| 1015 | − | |
| 1016 | − return __bch2_inode_hash_find(c, inum) != NULL; | |
| 1259 | + if (ret) | |
| 1260 | + goto err; | |
| 1261 | + BUG(); | |
| 1262 | +found_root: | |
| 1263 | + BUG_ON(bch2_inode_unpack(k, root)); | |
| 1264 | +err: | |
| 1265 | + bch2_trans_iter_exit(trans, &iter); | |
| 1266 | + return ret; | |
| 1017 | 1267 | } |
| 1018 | 1268 | |
| 1019 | 1269 | static int check_inode(struct btree_trans *trans, |
| 1020 | 1270 | struct btree_iter *iter, |
| 1021 | 1271 | struct bkey_s_c k, |
| 1022 | − struct bch_inode_unpacked *prev, | |
| 1023 | − struct snapshots_seen *s, | |
| 1024 | − bool full) | |
| 1272 | + struct bch_inode_unpacked *snapshot_root, | |
| 1273 | + struct snapshots_seen *s) | |
| 1025 | 1274 | { |
| 1026 | 1275 | struct bch_fs *c = trans->c; |
| 1276 | + struct printbuf buf = PRINTBUF; | |
| 1027 | 1277 | struct bch_inode_unpacked u; |
| 1028 | 1278 | bool do_update = false; |
| 1029 | 1279 | int ret; |
| @@ -1043,45 +1293,75 @@ static int check_inode(struct btree_trans *trans, · 13 unmodified lines | ||
| 1043 | 1293 | |
| 1044 | 1294 | BUG_ON(bch2_inode_unpack(k, &u)); |
| 1045 | 1295 | |
| 1046 | − if (!full && | |
| 1047 | − !(u.bi_flags & (BCH_INODE_i_size_dirty| | |
| 1048 | − BCH_INODE_i_sectors_dirty| | |
| 1049 | − BCH_INODE_unlinked))) | |
| 1050 | − return 0; | |
| 1051 | − | |
| 1052 | − if (prev->bi_inum != u.bi_inum) | |
| 1053 | − *prev = u; | |
| 1296 | + if (snapshot_root->bi_inum != u.bi_inum) { | |
| 1297 | + ret = get_snapshot_root_inode(trans, snapshot_root, u.bi_inum); | |
| 1298 | + if (ret) | |
| 1299 | + goto err; | |
| 1300 | + } | |
| 1054 | 1301 | |
| 1055 | − if (fsck_err_on(prev->bi_hash_seed != u.bi_hash_seed || | |
| 1056 | − inode_d_type(prev) != inode_d_type(&u), | |
| 1302 | + if (fsck_err_on(u.bi_hash_seed != snapshot_root->bi_hash_seed || | |
| 1303 | + INODE_STR_HASH(&u) != INODE_STR_HASH(snapshot_root), | |
| 1057 | 1304 | trans, inode_snapshot_mismatch, |
| 1058 | 1305 | "inodes in different snapshots don't match")) { |
| 1059 | − bch_err(c, "repair not implemented yet"); | |
| 1060 | − return -BCH_ERR_fsck_repair_unimplemented; | |
| 1306 | + u.bi_hash_seed = snapshot_root->bi_hash_seed; | |
| 1307 | + SET_INODE_STR_HASH(&u, INODE_STR_HASH(snapshot_root)); | |
| 1308 | + do_update = true; | |
| 1061 | 1309 | } |
| 1062 | 1310 | |
| 1063 | − if ((u.bi_flags & (BCH_INODE_i_size_dirty|BCH_INODE_unlinked)) && | |
| 1064 | − bch2_key_has_snapshot_overwrites(trans, BTREE_ID_inodes, k.k->p)) { | |
| 1065 | − struct bpos new_min_pos; | |
| 1066 | − | |
| 1067 | − ret = bch2_propagate_key_to_snapshot_leaves(trans, iter->btree_id, k, &new_min_pos); | |
| 1311 | + if (u.bi_dir || u.bi_dir_offset) { | |
| 1312 | + ret = check_inode_dirent_inode(trans, &u, &do_update); | |
| 1068 | 1313 | if (ret) |
| 1069 | 1314 | goto err; |
| 1315 | + } | |
| 1070 | 1316 | |
| 1071 | − u.bi_flags &= ~BCH_INODE_i_size_dirty|BCH_INODE_unlinked; | |
| 1317 | + if (fsck_err_on(u.bi_dir && (u.bi_flags & BCH_INODE_unlinked), | |
| 1318 | + trans, inode_unlinked_but_has_dirent, | |
| 1319 | + "inode unlinked but has dirent\n%s", | |
| 1320 | + (printbuf_reset(&buf), | |
| 1321 | + bch2_inode_unpacked_to_text(&buf, &u), | |
| 1322 | + buf.buf))) { | |
| 1323 | + u.bi_flags &= ~BCH_INODE_unlinked; | |
| 1324 | + do_update = true; | |
| 1325 | + } | |
| 1072 | 1326 | |
| 1073 | − ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot); | |
| 1327 | + if (S_ISDIR(u.bi_mode) && (u.bi_flags & BCH_INODE_unlinked)) { | |
| 1328 | + /* Check for this early so that check_unreachable_inode() will reattach it */ | |
| 1074 | 1329 | |
| 1075 | − bch_err_msg(c, ret, "in fsck updating inode"); | |
| 1076 | − if (ret) | |
| 1077 | − return ret; | |
| 1330 | + ret = bch2_empty_dir_snapshot(trans, k.k->p.offset, 0, k.k->p.snapshot); | |
| 1331 | + if (ret && ret != -BCH_ERR_ENOTEMPTY_dir_not_empty) | |
| 1332 | + goto err; | |
| 1078 | 1333 | |
| 1079 | − if (!bpos_eq(new_min_pos, POS_MIN)) | |
| 1080 | − bch2_btree_iter_set_pos(iter, bpos_predecessor(new_min_pos)); | |
| 1081 | − return 0; | |
| 1334 | + fsck_err_on(ret, trans, inode_dir_unlinked_but_not_empty, | |
| 1335 | + "dir unlinked but not empty\n%s", | |
| 1336 | + (printbuf_reset(&buf), | |
| 1337 | + bch2_inode_unpacked_to_text(&buf, &u), | |
| 1338 | + buf.buf)); | |
| 1339 | + u.bi_flags &= ~BCH_INODE_unlinked; | |
| 1340 | + do_update = true; | |
| 1341 | + ret = 0; | |
| 1342 | + } | |
| 1343 | + | |
| 1344 | + ret = bch2_inode_has_child_snapshots(trans, k.k->p); | |
| 1345 | + if (ret < 0) | |
| 1346 | + goto err; | |
| 1347 | + | |
| 1348 | + if (fsck_err_on(ret != !!(u.bi_flags & BCH_INODE_has_child_snapshot), | |
| 1349 | + trans, inode_has_child_snapshots_wrong, | |
| 1350 | + "inode has_child_snapshots flag wrong (should be %u)\n%s", | |
| 1351 | + ret, | |
| 1352 | + (printbuf_reset(&buf), | |
| 1353 | + bch2_inode_unpacked_to_text(&buf, &u), | |
| 1354 | + buf.buf))) { | |
| 1355 | + if (ret) | |
| 1356 | + u.bi_flags |= BCH_INODE_has_child_snapshot; | |
| 1357 | + else | |
| 1358 | + u.bi_flags &= ~BCH_INODE_has_child_snapshot; | |
| 1359 | + do_update = true; | |
| 1082 | 1360 | } |
| 1361 | + ret = 0; | |
| 1083 | 1362 | |
| 1084 | − if (u.bi_flags & BCH_INODE_unlinked) { | |
| 1363 | + if ((u.bi_flags & BCH_INODE_unlinked) && | |
| 1364 | + !(u.bi_flags & BCH_INODE_has_child_snapshot)) { | |
| 1085 | 1365 | if (!test_bit(BCH_FS_started, &c->flags)) { |
| 1086 | 1366 | /* |
| 1087 | 1367 | * If we're not in online fsck, don't delete unlinked |
| @@ -1095,7 +1375,7 @@ static int check_inode(struct btree_trans *trans, · 7 unmodified lines | ||
| 1095 | 1375 | */ |
| 1096 | 1376 | ret = check_inode_deleted_list(trans, k.k->p); |
| 1097 | 1377 | if (ret < 0) |
| 1098 | − return ret; | |
| 1378 | + goto err_noprint; | |
| 1099 | 1379 | |
| 1100 | 1380 | fsck_err_on(!ret, |
| 1101 | 1381 | trans, unlinked_inode_not_on_deleted_list, |
| @@ -1106,83 +1386,22 @@ static int check_inode(struct btree_trans *trans, · 4 unmodified lines | ||
| 1106 | 1386 | if (ret) |
| 1107 | 1387 | goto err; |
| 1108 | 1388 | } else { |
| 1109 | − if (fsck_err_on(bch2_inode_is_open(c, k.k->p), | |
| 1389 | + ret = bch2_inode_or_descendents_is_open(trans, k.k->p); | |
| 1390 | + if (ret < 0) | |
| 1391 | + goto err; | |
| 1392 | + | |
| 1393 | + if (fsck_err_on(!ret, | |
| 1110 | 1394 | trans, inode_unlinked_and_not_open, |
| 1111 | 1395 | "inode %llu%u unlinked and not open", |
| 1112 | 1396 | u.bi_inum, u.bi_snapshot)) { |
| 1113 | 1397 | ret = bch2_inode_rm_snapshot(trans, u.bi_inum, iter->pos.snapshot); |
| 1114 | 1398 | bch_err_msg(c, ret, "in fsck deleting inode"); |
| 1115 | − return ret; | |
| 1399 | + goto err_noprint; | |
| 1116 | 1400 | } |
| 1401 | + ret = 0; | |
| 1117 | 1402 | } |
| 1118 | 1403 | } |
| 1119 | 1404 | |
| 1120 | − /* i_size_dirty is vestigal, since we now have logged ops for truncate * */ | |
| 1121 | − if (u.bi_flags & BCH_INODE_i_size_dirty && | |
| 1122 | − (!test_bit(BCH_FS_clean_recovery, &c->flags) || | |
| 1123 | − fsck_err(trans, inode_i_size_dirty_but_clean, | |
| 1124 | − "filesystem marked clean, but inode %llu has i_size dirty", | |
| 1125 | − u.bi_inum))) { | |
| 1126 | − bch_verbose(c, "truncating inode %llu", u.bi_inum); | |
| 1127 | − | |
| 1128 | − /* | |
| 1129 | − * XXX: need to truncate partial blocks too here - or ideally | |
| 1130 | − * just switch units to bytes and that issue goes away | |
| 1131 | − */ | |
| 1132 | − ret = bch2_btree_delete_range_trans(trans, BTREE_ID_extents, | |
| 1133 | − SPOS(u.bi_inum, round_up(u.bi_size, block_bytes(c)) >> 9, | |
| 1134 | − iter->pos.snapshot), | |
| 1135 | − POS(u.bi_inum, U64_MAX), | |
| 1136 | − 0, NULL); | |
| 1137 | − bch_err_msg(c, ret, "in fsck truncating inode"); | |
| 1138 | − if (ret) | |
| 1139 | − return ret; | |
| 1140 | − | |
| 1141 | − /* | |
| 1142 | − * We truncated without our normal sector accounting hook, just | |
| 1143 | − * make sure we recalculate it: | |
| 1144 | − */ | |
| 1145 | − u.bi_flags |= BCH_INODE_i_sectors_dirty; | |
| 1146 | − | |
| 1147 | − u.bi_flags &= ~BCH_INODE_i_size_dirty; | |
| 1148 | − do_update = true; | |
| 1149 | − } | |
| 1150 | − | |
| 1151 | − /* i_sectors_dirty is vestigal, i_sectors is always updated transactionally */ | |
| 1152 | − if (u.bi_flags & BCH_INODE_i_sectors_dirty && | |
| 1153 | − (!test_bit(BCH_FS_clean_recovery, &c->flags) || | |
| 1154 | − fsck_err(trans, inode_i_sectors_dirty_but_clean, | |
| 1155 | − "filesystem marked clean, but inode %llu has i_sectors dirty", | |
| 1156 | − u.bi_inum))) { | |
| 1157 | − s64 sectors; | |
| 1158 | − | |
| 1159 | − bch_verbose(c, "recounting sectors for inode %llu", | |
| 1160 | − u.bi_inum); | |
| 1161 | − | |
| 1162 | − sectors = bch2_count_inode_sectors(trans, u.bi_inum, iter->pos.snapshot); | |
| 1163 | − if (sectors < 0) { | |
| 1164 | − bch_err_msg(c, sectors, "in fsck recounting inode sectors"); | |
| 1165 | − return sectors; | |
| 1166 | − } | |
| 1167 | − | |
| 1168 | − u.bi_sectors = sectors; | |
| 1169 | − u.bi_flags &= ~BCH_INODE_i_sectors_dirty; | |
| 1170 | − do_update = true; | |
| 1171 | − } | |
| 1172 | − | |
| 1173 | − if (u.bi_flags & BCH_INODE_backptr_untrusted) { | |
| 1174 | − u.bi_dir = 0; | |
| 1175 | − u.bi_dir_offset = 0; | |
| 1176 | − u.bi_flags &= ~BCH_INODE_backptr_untrusted; | |
| 1177 | − do_update = true; | |
| 1178 | − } | |
| 1179 | − | |
| 1180 | − if (u.bi_dir || u.bi_dir_offset) { | |
| 1181 | − ret = check_inode_dirent_inode(trans, &u, &do_update); | |
| 1182 | − if (ret) | |
| 1183 | − goto err; | |
| 1184 | − } | |
| 1185 | − | |
| 1186 | 1405 | if (fsck_err_on(u.bi_parent_subvol && |
| 1187 | 1406 | (u.bi_subvol == 0 || |
| 1188 | 1407 | u.bi_subvol == BCACHEFS_ROOT_SUBVOL), |
| @@ -1224,21 +1443,22 @@ static int check_inode(struct btree_trans *trans, · 35 unmodified lines | ||
| 1224 | 1443 | } |
| 1225 | 1444 | do_update: |
| 1226 | 1445 | if (do_update) { |
| 1227 | − ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot); | |
| 1446 | + ret = __bch2_fsck_write_inode(trans, &u); | |
| 1228 | 1447 | bch_err_msg(c, ret, "in fsck updating inode"); |
| 1229 | 1448 | if (ret) |
| 1230 | − return ret; | |
| 1449 | + goto err_noprint; | |
| 1231 | 1450 | } |
| 1232 | 1451 | err: |
| 1233 | 1452 | fsck_err: |
| 1234 | 1453 | bch_err_fn(c, ret); |
| 1454 | +err_noprint: | |
| 1455 | + printbuf_exit(&buf); | |
| 1235 | 1456 | return ret; |
| 1236 | 1457 | } |
| 1237 | 1458 | |
| 1238 | 1459 | int bch2_check_inodes(struct bch_fs *c) |
| 1239 | 1460 | { |
| 1240 | − bool full = c->opts.fsck; | |
| 1241 | − struct bch_inode_unpacked prev = { 0 }; | |
| 1461 | + struct bch_inode_unpacked snapshot_root = {}; | |
| 1242 | 1462 | struct snapshots_seen s; |
| 1243 | 1463 | |
| 1244 | 1464 | snapshots_seen_init(&s); |
| @@ -1248,13 +1468,104 @@ int bch2_check_inodes(struct bch_fs *c) · 3 unmodified lines | ||
| 1248 | 1468 | POS_MIN, |
| 1249 | 1469 | BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, |
| 1250 | 1470 | NULL, NULL, BCH_TRANS_COMMIT_no_enospc, |
| 1251 | − check_inode(trans, &iter, k, &prev, &s, full))); | |
| 1471 | + check_inode(trans, &iter, k, &snapshot_root, &s))); | |
| 1252 | 1472 | |
| 1253 | 1473 | snapshots_seen_exit(&s); |
| 1254 | 1474 | bch_err_fn(c, ret); |
| 1255 | 1475 | return ret; |
| 1256 | 1476 | } |
| 1257 | 1477 | |
| 1478 | +static int find_oldest_inode_needs_reattach(struct btree_trans *trans, | |
| 1479 | + struct bch_inode_unpacked *inode) | |
| 1480 | +{ | |
| 1481 | + struct bch_fs *c = trans->c; | |
| 1482 | + struct btree_iter iter; | |
| 1483 | + struct bkey_s_c k; | |
| 1484 | + int ret = 0; | |
| 1485 | + | |
| 1486 | + /* | |
| 1487 | + * We look for inodes to reattach in natural key order, leaves first, | |
| 1488 | + * but we should do the reattach at the oldest version that needs to be | |
| 1489 | + * reattached: | |
| 1490 | + */ | |
| 1491 | + for_each_btree_key_norestart(trans, iter, | |
| 1492 | + BTREE_ID_inodes, | |
| 1493 | + SPOS(0, inode->bi_inum, inode->bi_snapshot + 1), | |
| 1494 | + BTREE_ITER_all_snapshots, k, ret) { | |
| 1495 | + if (k.k->p.offset != inode->bi_inum) | |
| 1496 | + break; | |
| 1497 | + | |
| 1498 | + if (!bch2_snapshot_is_ancestor(c, inode->bi_snapshot, k.k->p.snapshot)) | |
| 1499 | + continue; | |
| 1500 | + | |
| 1501 | + if (!bkey_is_inode(k.k)) | |
| 1502 | + break; | |
| 1503 | + | |
| 1504 | + struct bch_inode_unpacked parent_inode; | |
| 1505 | + bch2_inode_unpack(k, &parent_inode); | |
| 1506 | + | |
| 1507 | + if (!inode_should_reattach(&parent_inode)) | |
| 1508 | + break; | |
| 1509 | + | |
| 1510 | + *inode = parent_inode; | |
| 1511 | + } | |
| 1512 | + bch2_trans_iter_exit(trans, &iter); | |
| 1513 | + | |
| 1514 | + return ret; | |
| 1515 | +} | |
| 1516 | + | |
| 1517 | +static int check_unreachable_inode(struct btree_trans *trans, | |
| 1518 | + struct btree_iter *iter, | |
| 1519 | + struct bkey_s_c k) | |
| 1520 | +{ | |
| 1521 | + struct printbuf buf = PRINTBUF; | |
| 1522 | + int ret = 0; | |
| 1523 | + | |
| 1524 | + if (!bkey_is_inode(k.k)) | |
| 1525 | + return 0; | |
| 1526 | + | |
| 1527 | + struct bch_inode_unpacked inode; | |
| 1528 | + BUG_ON(bch2_inode_unpack(k, &inode)); | |
| 1529 | + | |
| 1530 | + if (!inode_should_reattach(&inode)) | |
| 1531 | + return 0; | |
| 1532 | + | |
| 1533 | + ret = find_oldest_inode_needs_reattach(trans, &inode); | |
| 1534 | + if (ret) | |
| 1535 | + return ret; | |
| 1536 | + | |
| 1537 | + if (fsck_err(trans, inode_unreachable, | |
| 1538 | + "unreachable inode:\n%s", | |
| 1539 | + (bch2_inode_unpacked_to_text(&buf, &inode), | |
| 1540 | + buf.buf))) | |
| 1541 | + ret = reattach_inode(trans, &inode); | |
| 1542 | +fsck_err: | |
| 1543 | + printbuf_exit(&buf); | |
| 1544 | + return ret; | |
| 1545 | +} | |
| 1546 | + | |
| 1547 | +/* | |
| 1548 | + * Reattach unreachable (but not unlinked) inodes | |
| 1549 | + * | |
| 1550 | + * Run after check_inodes() and check_dirents(), so we node that inode | |
| 1551 | + * backpointer fields point to valid dirents, and every inode that has a dirent | |
| 1552 | + * that points to it has its backpointer field set - so we're just looking for | |
| 1553 | + * non-unlinked inodes without backpointers: | |
| 1554 | + * | |
| 1555 | + * XXX: this is racy w.r.t. hardlink removal in online fsck | |
| 1556 | + */ | |
| 1557 | +int bch2_check_unreachable_inodes(struct bch_fs *c) | |
| 1558 | +{ | |
| 1559 | + int ret = bch2_trans_run(c, | |
| 1560 | + for_each_btree_key_commit(trans, iter, BTREE_ID_inodes, | |
| 1561 | + POS_MIN, | |
| 1562 | + BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, | |
| 1563 | + NULL, NULL, BCH_TRANS_COMMIT_no_enospc, | |
| 1564 | + check_unreachable_inode(trans, &iter, k))); | |
| 1565 | + bch_err_fn(c, ret); | |
| 1566 | + return ret; | |
| 1567 | +} | |
| 1568 | + | |
| 1258 | 1569 | static inline bool btree_matches_i_mode(enum btree_id btree, unsigned mode) |
| 1259 | 1570 | { |
| 1260 | 1571 | switch (btree) { |
| @@ -1347,7 +1658,7 @@ static int check_i_sectors_notnested(struct btree_trans *trans, struct inode_wal · 86 unmodified lines | ||
| 1347 | 1658 | w->last_pos.inode, i->snapshot, |
| 1348 | 1659 | i->inode.bi_sectors, i->count)) { |
| 1349 | 1660 | i->inode.bi_sectors = i->count; |
| 1350 | − ret = bch2_fsck_write_inode(trans, &i->inode, i->snapshot); | |
| 1661 | + ret = bch2_fsck_write_inode(trans, &i->inode); | |
| 1351 | 1662 | if (ret) |
| 1352 | 1663 | break; |
| 1353 | 1664 | } |
| @@ -1657,8 +1968,7 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter, · 303 unmodified lines | ||
| 1657 | 1968 | !key_visible_in_snapshot(c, s, i->snapshot, k.k->p.snapshot)) |
| 1658 | 1969 | continue; |
| 1659 | 1970 | |
| 1660 | − if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_i_size_dirty) && | |
| 1661 | − k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 && | |
| 1971 | + if (fsck_err_on(k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 && | |
| 1662 | 1972 | !bkey_extent_is_reservation(k), |
| 1663 | 1973 | trans, extent_past_end_of_inode, |
| 1664 | 1974 | "extent type past end of inode %llu:%u, i_size %llu\n %s", |
| @@ -1789,7 +2099,7 @@ static int check_subdir_count_notnested(struct btree_trans *trans, struct inode_ · 124 unmodified lines | ||
| 1789 | 2099 | "directory %llu:%u with wrong i_nlink: got %u, should be %llu", |
| 1790 | 2100 | w->last_pos.inode, i->snapshot, i->inode.bi_nlink, i->count)) { |
| 1791 | 2101 | i->inode.bi_nlink = i->count; |
| 1792 | − ret = bch2_fsck_write_inode(trans, &i->inode, i->snapshot); | |
| 2102 | + ret = bch2_fsck_write_inode(trans, &i->inode); | |
| 1793 | 2103 | if (ret) |
| 1794 | 2104 | break; |
| 1795 | 2105 | } |
| @@ -1810,8 +2120,7 @@ noinline_for_stack · 14 unmodified lines | ||
| 1810 | 2120 | static int check_dirent_inode_dirent(struct btree_trans *trans, |
| 1811 | 2121 | struct btree_iter *iter, |
| 1812 | 2122 | struct bkey_s_c_dirent d, |
| 1813 | − struct bch_inode_unpacked *target, | |
| 1814 | − u32 target_snapshot) | |
| 2123 | + struct bch_inode_unpacked *target) | |
| 1815 | 2124 | { |
| 1816 | 2125 | struct bch_fs *c = trans->c; |
| 1817 | 2126 | struct printbuf buf = PRINTBUF; |
| @@ -1821,6 +2130,32 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, · 3 unmodified lines | ||
| 1821 | 2130 | if (inode_points_to_dirent(target, d)) |
| 1822 | 2131 | return 0; |
| 1823 | 2132 | |
| 2133 | + if (!target->bi_dir && | |
| 2134 | + !target->bi_dir_offset) { | |
| 2135 | + fsck_err_on(S_ISDIR(target->bi_mode), | |
| 2136 | + trans, inode_dir_missing_backpointer, | |
| 2137 | + "directory with missing backpointer\n%s", | |
| 2138 | + (printbuf_reset(&buf), | |
| 2139 | + bch2_bkey_val_to_text(&buf, c, d.s_c), | |
| 2140 | + prt_printf(&buf, "\n"), | |
| 2141 | + bch2_inode_unpacked_to_text(&buf, target), | |
| 2142 | + buf.buf)); | |
| 2143 | + | |
| 2144 | + fsck_err_on(target->bi_flags & BCH_INODE_unlinked, | |
| 2145 | + trans, inode_unlinked_but_has_dirent, | |
| 2146 | + "inode unlinked but has dirent\n%s", | |
| 2147 | + (printbuf_reset(&buf), | |
| 2148 | + bch2_bkey_val_to_text(&buf, c, d.s_c), | |
| 2149 | + prt_printf(&buf, "\n"), | |
| 2150 | + bch2_inode_unpacked_to_text(&buf, target), | |
| 2151 | + buf.buf)); | |
| 2152 | + | |
| 2153 | + target->bi_flags &= ~BCH_INODE_unlinked; | |
| 2154 | + target->bi_dir = d.k->p.inode; | |
| 2155 | + target->bi_dir_offset = d.k->p.offset; | |
| 2156 | + return __bch2_fsck_write_inode(trans, target); | |
| 2157 | + } | |
| 2158 | + | |
| 1824 | 2159 | if (bch2_inode_should_have_bp(target) && |
| 1825 | 2160 | !fsck_err(trans, inode_wrong_backpointer, |
| 1826 | 2161 | "dirent points to inode that does not point back:\n %s", |
| @@ -1830,15 +2165,8 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, · 3 unmodified lines | ||
| 1830 | 2165 | buf.buf))) |
| 1831 | 2166 | goto err; |
| 1832 | 2167 | |
| 1833 | − if (!target->bi_dir && | |
| 1834 | − !target->bi_dir_offset) { | |
| 1835 | − target->bi_dir = d.k->p.inode; | |
| 1836 | − target->bi_dir_offset = d.k->p.offset; | |
| 1837 | − return __bch2_fsck_write_inode(trans, target, target_snapshot); | |
| 1838 | − } | |
| 1839 | − | |
| 1840 | 2168 | struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter, |
| 1841 | − SPOS(target->bi_dir, target->bi_dir_offset, target_snapshot)); | |
| 2169 | + SPOS(target->bi_dir, target->bi_dir_offset, target->bi_snapshot)); | |
| 1842 | 2170 | ret = bkey_err(bp_dirent); |
| 1843 | 2171 | if (ret && !bch2_err_matches(ret, ENOENT)) |
| 1844 | 2172 | goto err; |
| @@ -1851,14 +2179,14 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, · 6 unmodified lines | ||
| 1851 | 2179 | "inode %llu:%u has wrong backpointer:\n" |
| 1852 | 2180 | "got %llu:%llu\n" |
| 1853 | 2181 | "should be %llu:%llu", |
| 1854 | − target->bi_inum, target_snapshot, | |
| 2182 | + target->bi_inum, target->bi_snapshot, | |
| 1855 | 2183 | target->bi_dir, |
| 1856 | 2184 | target->bi_dir_offset, |
| 1857 | 2185 | d.k->p.inode, |
| 1858 | 2186 | d.k->p.offset)) { |
| 1859 | 2187 | target->bi_dir = d.k->p.inode; |
| 1860 | 2188 | target->bi_dir_offset = d.k->p.offset; |
| 1861 | − ret = __bch2_fsck_write_inode(trans, target, target_snapshot); | |
| 2189 | + ret = __bch2_fsck_write_inode(trans, target); | |
| 1862 | 2190 | goto out; |
| 1863 | 2191 | } |
| 1864 | 2192 | |
| @@ -1873,7 +2201,7 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, · 8 unmodified lines | ||
| 1873 | 2201 | trans, inode_dir_multiple_links, |
| 1874 | 2202 | "%s %llu:%u with multiple links\n%s", |
| 1875 | 2203 | S_ISDIR(target->bi_mode) ? "directory" : "subvolume", |
| 1876 | − target->bi_inum, target_snapshot, buf.buf)) { | |
| 2204 | + target->bi_inum, target->bi_snapshot, buf.buf)) { | |
| 1877 | 2205 | ret = __remove_dirent(trans, d.k->p); |
| 1878 | 2206 | goto out; |
| 1879 | 2207 | } |
| @@ -1886,10 +2214,10 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, · 6 unmodified lines | ||
| 1886 | 2214 | if (fsck_err_on(backpointer_exists && !target->bi_nlink, |
| 1887 | 2215 | trans, inode_multiple_links_but_nlink_0, |
| 1888 | 2216 | "inode %llu:%u type %s has multiple links but i_nlink 0\n%s", |
| 1889 | − target->bi_inum, target_snapshot, bch2_d_types[d.v->d_type], buf.buf)) { | |
| 2217 | + target->bi_inum, target->bi_snapshot, bch2_d_types[d.v->d_type], buf.buf)) { | |
| 1890 | 2218 | target->bi_nlink++; |
| 1891 | 2219 | target->bi_flags &= ~BCH_INODE_unlinked; |
| 1892 | − ret = __bch2_fsck_write_inode(trans, target, target_snapshot); | |
| 2220 | + ret = __bch2_fsck_write_inode(trans, target); | |
| 1893 | 2221 | if (ret) |
| 1894 | 2222 | goto err; |
| 1895 | 2223 | } |
| @@ -1906,15 +2234,14 @@ noinline_for_stack · 10 unmodified lines | ||
| 1906 | 2234 | static int check_dirent_target(struct btree_trans *trans, |
| 1907 | 2235 | struct btree_iter *iter, |
| 1908 | 2236 | struct bkey_s_c_dirent d, |
| 1909 | − struct bch_inode_unpacked *target, | |
| 1910 | − u32 target_snapshot) | |
| 2237 | + struct bch_inode_unpacked *target) | |
| 1911 | 2238 | { |
| 1912 | 2239 | struct bch_fs *c = trans->c; |
| 1913 | 2240 | struct bkey_i_dirent *n; |
204 more lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 526 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 159 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 312 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 286 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 475 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 6765 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 274 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 301 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 494 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 367 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.