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 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> | 73 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> |
| 74 | André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> | 74 | André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> |
| 75 | Andy Adamson <andros@citi.umich.edu> | 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 | Andy Shevchenko <andy@kernel.org> <andy@smile.org.ua> | 78 | Andy Shevchenko <andy@kernel.org> <andy@smile.org.ua> |
| 77 | Andy Shevchenko <andy@kernel.org> <ext-andriy.shevchenko@nokia.com> | 79 | Andy Shevchenko <andy@kernel.org> <ext-andriy.shevchenko@nokia.com> |
| 78 | Anilkumar Kolli <quic_akolli@quicinc.com> <akolli@codeaurora.org> | 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 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net> | 205 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net> |
| 204 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@intel.com> | 206 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@intel.com> |
| 205 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com> | 207 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com> |
| 208 | Fangrui Song <i@maskray.me> <maskray@google.com> | ||
| 206 | Felipe W Damasio <felipewd@terra.com.br> | 209 | Felipe W Damasio <felipewd@terra.com.br> |
| 207 | Felix Kuhling <fxkuehl@gmx.de> | 210 | Felix Kuhling <fxkuehl@gmx.de> |
| 208 | Felix Moeller <felix@derklecks.de> | 211 | Felix Moeller <felix@derklecks.de> |
| 209 | Fenglin Wu <quic_fenglinw@quicinc.com> <fenglinw@codeaurora.org> | 212 | Fenglin Wu <quic_fenglinw@quicinc.com> <fenglinw@codeaurora.org> |
| 210 | Filipe Lautert <filipe@icewall.org> | 213 | Filipe Lautert <filipe@icewall.org> |
| 211 | Finn Thain <fthain@linux-m68k.org> <fthain@telegraphics.com.au> | 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 | Franck Bui-Huu <vagabon.xyz@gmail.com> | 218 | Franck Bui-Huu <vagabon.xyz@gmail.com> |
| 213 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> | 219 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> |
| 214 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@sony.com> | 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 | Jens Axboe <axboe@kernel.dk> <axboe@meta.com> | 306 | Jens Axboe <axboe@kernel.dk> <axboe@meta.com> |
| 301 | Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | 307 | Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
| 302 | Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net> | 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 | Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org> | 314 | Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org> |
| 304 | Jilai Wang <quic_jilaiw@quicinc.com> <jilaiw@codeaurora.org> | 315 | Jilai Wang <quic_jilaiw@quicinc.com> <jilaiw@codeaurora.org> |
| 305 | Jiri Kosina <jikos@kernel.org> <jikos@jikos.cz> | 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 | D: ISDN Maintainer | 1358 | D: ISDN Maintainer |
| 1359 | S: USA | 1359 | S: USA |
| 1360 | 1360 | ||
| 1361 | N: Gerrit Renker | ||
| 1362 | E: gerrit@erg.abdn.ac.uk | ||
| 1363 | D: DCCP protocol support. | ||
| 1364 | |||
| 1365 | N: Philip Gladstone | 1361 | N: Philip Gladstone |
| 1366 | E: philip@gladstonefamily.net | 1362 | E: philip@gladstonefamily.net |
| 1367 | D: Kernel / timekeeping stuff | 1363 | D: Kernel / timekeeping stuff |
| @@ -1677,11 +1673,6 @@ W: http://www.carumba.com/ · 309 unmodified lines | |||
| 1677 | D: bug toaster (A1 sauce makes all the difference) | 1673 | D: bug toaster (A1 sauce makes all the difference) |
| 1678 | D: Random linux hacker | 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 | N: Tim Hockin | 1676 | N: Tim Hockin |
| 1686 | E: thockin@hockin.org | 1677 | E: thockin@hockin.org |
| 1687 | W: http://www.hockin.org/~thockin | 1678 | W: http://www.hockin.org/~thockin |
| @@ -1697,6 +1688,11 @@ D: hwmon subsystem maintainer · 9 unmodified lines | |||
| 1697 | D: i2c-sis96x and i2c-stub SMBus drivers | 1688 | D: i2c-sis96x and i2c-stub SMBus drivers |
| 1698 | S: USA | 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 | N: Dirk Hohndel | 1696 | N: Dirk Hohndel |
| 1701 | E: hohndel@suse.de | 1697 | E: hohndel@suse.de |
| 1702 | D: The XFree86[tm] Project | 1698 | D: The XFree86[tm] Project |
| @@ -1872,6 +1868,10 @@ S: K osmidomkum 723 · 169 unmodified lines | |||
| 1872 | S: 160 00 Praha 6 | 1868 | S: 160 00 Praha 6 |
| 1873 | S: Czech Republic | 1869 | S: Czech Republic |
| 1874 | 1870 | ||
| 1871 | N: Seth Jennings | ||
| 1872 | E: sjenning@redhat.com | ||
| 1873 | D: Creation and maintenance of zswap | ||
| 1874 | |||
| 1875 | N: Jeremy Kerr | 1875 | N: Jeremy Kerr |
| 1876 | D: Maintainer of SPU File System | 1876 | D: Maintainer of SPU File System |
| 1877 | 1877 | ||
| @@ -2188,19 +2188,6 @@ N: Mike Kravetz · 310 unmodified lines | |||
| 2188 | E: mike.kravetz@oracle.com | 2188 | E: mike.kravetz@oracle.com |
| 2189 | D: Maintenance and development of the hugetlb subsystem | 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 | N: Andreas S. Krebs | 2191 | N: Andreas S. Krebs |
| 2205 | E: akrebs@altavista.net | 2192 | E: akrebs@altavista.net |
| 2206 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards | 2193 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards |
| @@ -3191,6 +3178,11 @@ N: Ken Pizzini · 984 unmodified lines | |||
| 3191 | E: ken@halcyon.com | 3178 | E: ken@halcyon.com |
| 3192 | D: CDROM driver "sonycd535" (Sony CDU-535/531) | 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 | N: Stelian Pop | 3186 | N: Stelian Pop |
| 3195 | E: stelian@popies.net | 3187 | E: stelian@popies.net |
| 3196 | P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0 D3F7 7185 9E7A EDBB 6147 | 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 | S: 79098 Freiburg | 3292 | S: 79098 Freiburg |
| 3301 | S: Germany | 3293 | S: Germany |
| 3302 | 3294 | ||
| 3295 | N: Gerrit Renker | ||
| 3296 | E: gerrit@erg.abdn.ac.uk | ||
| 3297 | D: DCCP protocol support. | ||
| 3298 | |||
| 3303 | N: Thomas Renninger | 3299 | N: Thomas Renninger |
| 3304 | E: trenn@suse.de | 3300 | E: trenn@suse.de |
| 3305 | D: cpupowerutils | 3301 | D: cpupowerutils |
| @@ -3576,11 +3572,6 @@ D: several improvements to system programs · 270 unmodified lines | |||
| 3576 | S: Oldenburg | 3572 | S: Oldenburg |
| 3577 | S: Germany | 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 | N: Robert Schwebel | 3575 | N: Robert Schwebel |
| 3585 | E: robert@schwebel.de | 3576 | E: robert@schwebel.de |
| 3586 | W: https://www.schwebel.de | 3577 | W: https://www.schwebel.de |
| @@ -3771,6 +3762,11 @@ S: Chr. Winthersvej 1 B, st.th. · 184 unmodified lines | |||
| 3771 | S: DK-1860 Frederiksberg C | 3762 | S: DK-1860 Frederiksberg C |
| 3772 | S: Denmark | 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 | N: Drew Sullivan | 3770 | N: Drew Sullivan |
| 3775 | E: drew@ss.org | 3771 | E: drew@ss.org |
| 3776 | W: http://www.ss.org/ | 3772 | W: http://www.ss.org/ |
| @@ -4286,6 +4282,10 @@ S: Pipers Way · 509 unmodified lines | |||
| 4286 | S: Swindon. SN3 1RJ | 4282 | S: Swindon. SN3 1RJ |
| 4287 | S: England | 4283 | S: England |
| 4288 | 4284 | ||
| 4285 | N: Vitaly Wool | ||
| 4286 | E: vitaly.wool@konsulko.com | ||
| 4287 | D: Maintenance and development of zswap | ||
| 4288 | |||
| 4289 | N: Chris Wright | 4289 | N: Chris Wright |
| 4290 | E: chrisw@sous-sol.org | 4290 | E: chrisw@sous-sol.org |
| 4291 | D: hacking on LSM framework and security modules. | 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 | authorization of the policies (prohibiting an attacker from gaining | 223 | authorization of the policies (prohibiting an attacker from gaining |
| 224 | unconstrained root, and deploying an "allow all" policy). These | 224 | unconstrained root, and deploying an "allow all" policy). These |
| 225 | policies must be signed by a certificate that chains to the | 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 | openssl smime -sign \ | 231 | openssl smime -sign \ |
| 229 | -in "$MY_POLICY" \ | 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 | policy. Two checks will always be performed on this policy: First, the | 269 | policy. Two checks will always be performed on this policy: First, the |
| 267 | ``policy_names`` must match with the updated version and the existing | 270 | ``policy_names`` must match with the updated version and the existing |
| 268 | version. Second the updated policy must have a policy version greater than | 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 | The ``delete`` file is used to remove a policy that is no longer needed. | 274 | The ``delete`` file is used to remove a policy that is no longer needed. |
| 272 | This file is write-only and accepts a value of ``1`` to delete the policy. | 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 | | ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 | | 147 | | ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 | |
| 148 | +----------------+-----------------+-----------------+-----------------------------+ | 148 | +----------------+-----------------+-----------------+-----------------------------+ |
| 149 | | ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 | | ||
| 150 | +----------------+-----------------+-----------------+-----------------------------+ | ||
| 149 | | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | | 151 | | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | |
| 150 | +----------------+-----------------+-----------------+-----------------------------+ | 152 | +----------------+-----------------+-----------------+-----------------------------+ |
| 151 | | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | | 153 | | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | |
| @@ -186,6 +188,8 @@ stable kernels. · 34 unmodified lines | |||
| 186 | +----------------+-----------------+-----------------+-----------------------------+ | 188 | +----------------+-----------------+-----------------+-----------------------------+ |
| 187 | | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | | 189 | | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | |
| 188 | +----------------+-----------------+-----------------+-----------------------------+ | 190 | +----------------+-----------------+-----------------+-----------------------------+ |
| 191 | | ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 | | ||
| 192 | +----------------+-----------------+-----------------+-----------------------------+ | ||
| 189 | | ARM | Neoverse-V1 | #1619801 | N/A | | 193 | | ARM | Neoverse-V1 | #1619801 | N/A | |
| 190 | +----------------+-----------------+-----------------+-----------------------------+ | 194 | +----------------+-----------------+-----------------+-----------------------------+ |
| 191 | | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | | 195 | | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | |
| @@ -289,3 +293,5 @@ stable kernels. · 97 unmodified lines | |||
| 289 | +----------------+-----------------+-----------------+-----------------------------+ | 293 | +----------------+-----------------+-----------------+-----------------------------+ |
| 290 | | Microsoft | Azure Cobalt 100| #2253138 | ARM64_ERRATUM_2253138 | | 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 | * Intel server CPUs, Skylake and later | 12 | * Intel server CPUs, Skylake and later |
| 13 | * Intel client CPUs, Tiger Lake (11th Gen Core) and later | 13 | * Intel client CPUs, Tiger Lake (11th Gen Core) and later |
| 14 | * Future AMD CPUs | 14 | * Future AMD CPUs |
| 15 | * arm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE) | ||
| 15 | 16 | ||
| 17 | x86_64 | ||
| 18 | ====== | ||
| 16 | Pkeys work by dedicating 4 previously Reserved bits in each page table entry to | 19 | Pkeys work by dedicating 4 previously Reserved bits in each page table entry to |
| 17 | a "protection key", giving 16 possible keys. | 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 | theoretically space in the PAE PTEs. These permissions are enforced on data | 31 | theoretically space in the PAE PTEs. These permissions are enforced on data |
| 29 | access only and have no effect on instruction fetches. | 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 | Syscalls | 50 | Syscalls |
| 32 | ======== | 51 | ======== |
| 33 | 52 | ||
| @@ -38,11 +57,10 @@ There are 3 system calls which directly interact with pkeys:: · 4 unmodified lines | |||
| 38 | int pkey_mprotect(unsigned long start, size_t len, | 57 | int pkey_mprotect(unsigned long start, size_t len, |
| 39 | unsigned long prot, int pkey); | 58 | unsigned long prot, int pkey); |
| 40 | 59 | ||
| 41 | Before a pkey can be used, it must first be allocated with | 60 | Before a pkey can be used, it must first be allocated with pkey_alloc(). An |
| 42 | pkey_alloc(). An application calls the WRPKRU instruction | 61 | application writes to the architecture specific CPU register directly in order |
| 43 | directly in order to change access permissions to memory covered | 62 | to change access permissions to memory covered with a key. In this example |
| 44 | with a key. In this example WRPKRU is wrapped by a C function | 63 | this is wrapped by a C function called pkey_set(). |
| 45 | called pkey_set(). | ||
| 46 | :: | 64 | :: |
| 47 | 65 | ||
| 48 | int real_prot = PROT_READ|PROT_WRITE; | 66 | int real_prot = PROT_READ|PROT_WRITE; |
| @@ -64,9 +82,9 @@ is no longer in use:: · 15 unmodified lines | |||
| 64 | munmap(ptr, PAGE_SIZE); | 82 | munmap(ptr, PAGE_SIZE); |
| 65 | pkey_free(pkey); | 83 | pkey_free(pkey); |
| 66 | 84 | ||
| 67 | .. note:: pkey_set() is a wrapper for the RDPKRU and WRPKRU instructions. | 85 | .. note:: pkey_set() is a wrapper around writing to the CPU register. |
| 68 | An example implementation can be found in | 86 | Example implementations can be found in |
| 69 | tools/testing/selftests/x86/protection_keys.c. | 87 | tools/testing/selftests/mm/pkey-{arm64,powerpc,x86}.h |
| 70 | 88 | ||
| 71 | Behavior | 89 | Behavior |
| 72 | ======== | 90 | ======== |
| @@ -96,3 +114,7 @@ with a read():: · 23 unmodified lines | |||
| 96 | The kernel will send a SIGSEGV in both cases, but si_code will be set | 114 | The kernel will send a SIGSEGV in both cases, but si_code will be set |
| 97 | to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when | 115 | to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when |
| 98 | the plain mprotect() permissions are violated. | 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 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml# | 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml# |
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | 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 | maintainers: | 9 | maintainers: |
| 10 | - Michael Hennerich <michael.hennerich@analog.com> | 10 | - Michael Hennerich <michael.hennerich@analog.com> |
| @@ -12,41 +12,22 @@ maintainers: · 1 unmodified line | |||
| 12 | 12 | ||
| 13 | properties: | 13 | properties: |
| 14 | compatible: | 14 | compatible: |
| 15 | oneOf: | 15 | enum: |
| 16 | - description: SPI devices | 16 | - adi,ad5310r |
| 17 | enum: | 17 | - adi,ad5672r |
| 18 | - adi,ad5310r | 18 | - adi,ad5674r |
| 19 | - adi,ad5672r | 19 | - adi,ad5676 |
| 20 | - adi,ad5674r | 20 | - adi,ad5676r |
| 21 | - adi,ad5676 | 21 | - adi,ad5679r |
| 22 | - adi,ad5676r | 22 | - adi,ad5681r |
| 23 | - adi,ad5679r | 23 | - adi,ad5682r |
| 24 | - adi,ad5681r | 24 | - adi,ad5683 |
| 25 | - adi,ad5682r | 25 | - adi,ad5683r |
| 26 | - adi,ad5683 | 26 | - adi,ad5684 |
| 27 | - adi,ad5683r | 27 | - adi,ad5684r |
| 28 | - adi,ad5684 | 28 | - adi,ad5685r |
| 29 | - adi,ad5684r | 29 | - adi,ad5686 |
| 30 | - adi,ad5685r | 30 | - adi,ad5686r |
| 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 | |||
| 50 | 31 | ||
| 51 | reg: | 32 | reg: |
| 52 | maxItems: 1 | 33 | maxItems: 1 |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | |||
| 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5696.yaml# | 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5696.yaml# |
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | 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 | maintainers: | 9 | maintainers: |
| 10 | - Michael Auchter <michael.auchter@ni.com> | 10 | - Michael Auchter <michael.auchter@ni.com> |
| @@ -16,6 +16,7 @@ properties: · 5 unmodified lines | |||
| 16 | compatible: | 16 | compatible: |
| 17 | enum: | 17 | enum: |
| 18 | - adi,ad5311r | 18 | - adi,ad5311r |
| 19 | - adi,ad5337r | ||
| 19 | - adi,ad5338r | 20 | - adi,ad5338r |
| 20 | - adi,ad5671r | 21 | - adi,ad5671r |
| 21 | - adi,ad5675r | 22 | - adi,ad5675r |
| @@ -82,9 +82,6 @@ allOf: · 81 unmodified lines | |||
| 82 | enum: | 82 | enum: |
| 83 | - fsl,ls1043a-extirq | 83 | - fsl,ls1043a-extirq |
| 84 | - fsl,ls1046a-extirq | 84 | - fsl,ls1046a-extirq |
| 85 | - fsl,ls1088a-extirq | ||
| 86 | - fsl,ls2080a-extirq | ||
| 87 | - fsl,lx2160a-extirq | ||
| 88 | then: | 85 | then: |
| 89 | properties: | 86 | properties: |
| 90 | interrupt-map: | 87 | interrupt-map: |
| @@ -95,6 +92,29 @@ allOf: · 4 unmodified lines | |||
| 95 | - const: 0xf | 92 | - const: 0xf |
| 96 | - const: 0 | 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 | additionalProperties: false | 118 | additionalProperties: false |
| 99 | 119 | ||
| 100 | examples: | 120 | examples: |
| @@ -113,7 +113,7 @@ properties: · 112 unmodified lines | |||
| 113 | 113 | ||
| 114 | msi-parent: | 114 | msi-parent: |
| 115 | deprecated: true | 115 | deprecated: true |
| 116 | $ref: /schemas/types.yaml#/definitions/phandle | 116 | maxItems: 1 |
| 117 | description: | 117 | description: |
| 118 | Describes the MSI controller node handling message | 118 | Describes the MSI controller node handling message |
| 119 | interrupts for the MC. When there is no translation | 119 | interrupts for the MC. When there is no translation |
| @@ -26,6 +26,7 @@ properties: · 25 unmodified lines | |||
| 26 | - brcm,asp-v2.1-mdio | 26 | - brcm,asp-v2.1-mdio |
| 27 | - brcm,asp-v2.2-mdio | 27 | - brcm,asp-v2.2-mdio |
| 28 | - brcm,unimac-mdio | 28 | - brcm,unimac-mdio |
| 29 | - brcm,bcm6846-mdio | ||
| 29 | 30 | ||
| 30 | reg: | 31 | reg: |
| 31 | minItems: 1 | 32 | minItems: 1 |
| @@ -102,7 +102,7 @@ properties: · 101 unmodified lines | |||
| 102 | default: 2 | 102 | default: 2 |
| 103 | 103 | ||
| 104 | interrupts: | 104 | interrupts: |
| 105 | anyOf: | 105 | oneOf: |
| 106 | - minItems: 1 | 106 | - minItems: 1 |
| 107 | items: | 107 | items: |
| 108 | - description: TX interrupt | 108 | - description: TX interrupt |
| @@ -30,6 +30,7 @@ properties: · 29 unmodified lines | |||
| 30 | - qcom,apq8096-sndcard | 30 | - qcom,apq8096-sndcard |
| 31 | - qcom,qcm6490-idp-sndcard | 31 | - qcom,qcm6490-idp-sndcard |
| 32 | - qcom,qcs6490-rb3gen2-sndcard | 32 | - qcom,qcs6490-rb3gen2-sndcard |
| 33 | - qcom,qrb4210-rb2-sndcard | ||
| 33 | - qcom,qrb5165-rb5-sndcard | 34 | - qcom,qrb5165-rb5-sndcard |
| 34 | - qcom,sc7180-qdsp6-sndcard | 35 | - qcom,sc7180-qdsp6-sndcard |
| 35 | - qcom,sc8280xp-sndcard | 36 | - qcom,sc8280xp-sndcard |
| @@ -302,7 +302,7 @@ allOf: · 301 unmodified lines | |||
| 302 | reg-names: | 302 | reg-names: |
| 303 | items: | 303 | items: |
| 304 | enum: | 304 | enum: |
| 305 | - scu | 305 | - sru |
| 306 | - ssi | 306 | - ssi |
| 307 | - adg | 307 | - adg |
| 308 | # for Gen2/Gen3 | 308 | # for Gen2/Gen3 |
| @@ -101,8 +101,6 @@ properties: · 100 unmodified lines | |||
| 101 | - domintech,dmard09 | 101 | - domintech,dmard09 |
| 102 | # DMARD10: 3-axis Accelerometer | 102 | # DMARD10: 3-axis Accelerometer |
| 103 | - domintech,dmard10 | 103 | - domintech,dmard10 |
| 104 | # Elgin SPI-controlled LCD | ||
| 105 | - elgin,jg10309-01 | ||
| 106 | # MMA7660FC: 3-Axis Orientation/Motion Detection Sensor | 104 | # MMA7660FC: 3-Axis Orientation/Motion Detection Sensor |
| 107 | - fsl,mma7660 | 105 | - fsl,mma7660 |
| 108 | # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer | 106 | # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer |
| @@ -7,12 +7,11 @@ WMI Driver API · 6 unmodified lines | |||
| 7 | The WMI driver core supports a more modern bus-based interface for interacting | 7 | The WMI driver core supports a more modern bus-based interface for interacting |
| 8 | with WMI devices, and an older GUID-based interface. The latter interface is | 8 | with WMI devices, and an older GUID-based interface. The latter interface is |
| 9 | considered to be deprecated, so new WMI drivers should generally avoid it since | 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 | 10 | it has some issues with multiple WMI devices sharing the same GUID. |
| 11 | and/or notification IDs. The modern bus-based interface instead maps each | 11 | The modern bus-based interface instead maps each WMI device to a |
| 12 | WMI device to a :c:type:`struct wmi_device <wmi_device>`, so it supports | 12 | :c:type:`struct wmi_device <wmi_device>`, so it supports WMI devices sharing the |
| 13 | WMI devices sharing GUIDs and/or notification IDs. Drivers can then register | 13 | same GUID. Drivers can then register a :c:type:`struct wmi_driver <wmi_driver>` |
| 14 | a :c:type:`struct wmi_driver <wmi_driver>`, which will be bound to compatible | 14 | which will be bound to compatible WMI devices by the driver core. |
| 15 | WMI devices by the driver core. | ||
| 16 | 15 | ||
| 17 | .. kernel-doc:: include/linux/wmi.h | 16 | .. kernel-doc:: include/linux/wmi.h |
| 18 | :internal: | 17 | :internal: |
| @@ -208,7 +208,7 @@ The filesystem must arrange to `cancel · 207 unmodified lines | |||
| 208 | such `reservations | 208 | such `reservations |
| 209 | <https://lore.kernel.org/linux-xfs/20220817093627.GZ3600936@dread.disaster.area/>`_ | 209 | <https://lore.kernel.org/linux-xfs/20220817093627.GZ3600936@dread.disaster.area/>`_ |
| 210 | because writeback will not consume the reservation. | 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 | ``->iomap_end`` function to find all the clean areas of the folios | 212 | ``->iomap_end`` function to find all the clean areas of the folios |
| 213 | caching a fresh (``IOMAP_F_NEW``) delalloc mapping. | 213 | caching a fresh (``IOMAP_F_NEW``) delalloc mapping. |
| 214 | It takes the ``invalidate_lock``. | 214 | It takes the ``invalidate_lock``. |
| @@ -592,4 +592,3 @@ API Function Reference · 591 unmodified lines | |||
| 592 | 592 | ||
| 593 | .. kernel-doc:: include/linux/netfs.h | 593 | .. kernel-doc:: include/linux/netfs.h |
| 594 | .. kernel-doc:: fs/netfs/buffered_read.c | 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 | Bridge Connector Helper | 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 | :doc: overview | 185 | :doc: overview |
| 186 | 186 | ||
| 187 | 187 | ||
| @@ -204,7 +204,7 @@ MIPI-DSI bridge operation · 16 unmodified lines | |||
| 204 | Bridge Connector Helper Reference | 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 | :export: | 208 | :export: |
| 209 | 209 | ||
| 210 | Panel-Bridge Helper Reference | 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 | section of 'MAINTAINERS' file. | 7 | section of 'MAINTAINERS' file. |
| 8 | 8 | ||
| 9 | The mailing lists for the subsystem are damon@lists.linux.dev and | 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 | 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 | 11 | <https://git.kernel.org/akpm/mm/h/mm-unstable>`_ whenever possible and posted |
| 12 | the mailing lists. | 12 | to the mailing lists. |
| 13 | 13 | ||
| 14 | SCM Trees | 14 | SCM Trees |
| 15 | --------- | 15 | --------- |
| 16 | 16 | ||
| 17 | There are multiple Linux trees for DAMON development. Patches under | 17 | There are multiple Linux trees for DAMON development. Patches under |
| 18 | development or testing are queued in `damon/next | 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 | Sufficiently reviewed patches will be queued in `mm-unstable | 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 | subsystem maintainer. After more sufficient tests, the patches will be queued | 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 | pull-requested to the mainline by the memory management subsystem maintainer. | 24 | pull-requested to the mainline by the memory management subsystem maintainer. |
| 25 | 25 | ||
| 26 | Note again the patches for mm-unstable `tree | 26 | Note again the patches for `mm-unstable tree |
| 27 | <https://git.kernel.org/akpm/mm/h/mm-unstable>` are queued by the memory | 27 | <https://git.kernel.org/akpm/mm/h/mm-unstable>`_ are queued by the memory |
| 28 | management subsystem maintainer. If the patches requires some patches in | 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 | in mm-unstable, please make sure the requirement is clearly specified. | 30 | in mm-unstable, please make sure the requirement is clearly specified. |
| 31 | 31 | ||
| 32 | Submit checklist addendum | 32 | Submit checklist addendum |
| @@ -37,25 +37,25 @@ When making DAMON changes, you should do below. · 4 unmodified lines | |||
| 37 | - Build changes related outputs including kernel and documents. | 37 | - Build changes related outputs including kernel and documents. |
| 38 | - Ensure the builds introduce no new errors or warnings. | 38 | - Ensure the builds introduce no new errors or warnings. |
| 39 | - Run and ensure no new failures for DAMON `selftests | 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 | `kunittests | 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 | Further doing below and putting the results will be helpful. | 44 | Further doing below and putting the results will be helpful. |
| 45 | 45 | ||
| 46 | - Run `damon-tests/corr | 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 | changes. | 48 | changes. |
| 49 | - Run `damon-tests/perf | 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 | changes. | 51 | changes. |
| 52 | 52 | ||
| 53 | Key cycle dates | 53 | Key cycle dates |
| 54 | --------------- | 54 | --------------- |
| 55 | 55 | ||
| 56 | Patches can be sent anytime. Key cycle dates of the `mm-unstable | 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 | 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 | 58 | <https://git.kernel.org/akpm/mm/h/mm-stable>`_ trees depend on the memory |
| 59 | management subsystem maintainer. | 59 | management subsystem maintainer. |
| 60 | 60 | ||
| 61 | Review cadence | 61 | Review cadence |
| @@ -72,13 +72,13 @@ Mailing tool · 10 unmodified lines | |||
| 72 | Like many other Linux kernel subsystems, DAMON uses the mailing lists | 72 | Like many other Linux kernel subsystems, DAMON uses the mailing lists |
| 73 | (damon@lists.linux.dev and linux-mm@kvack.org) as the major communication | 73 | (damon@lists.linux.dev and linux-mm@kvack.org) as the major communication |
| 74 | channel. There is a simple tool called `HacKerMaiL | 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 | are not very familiar with the mailing lists based communication. The tool | 76 | are not very familiar with the mailing lists based communication. The tool |
| 77 | could be particularly helpful for DAMON community members since it is developed | 77 | could be particularly helpful for DAMON community members since it is developed |
| 78 | and maintained by DAMON maintainer. The tool is also officially announced to | 78 | and maintained by DAMON maintainer. The tool is also officially announced to |
| 79 | support DAMON and general Linux kernel development workflow. | 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 | tool for DAMON community, which DAMON maintainer is committed to support. | 82 | tool for DAMON community, which DAMON maintainer is committed to support. |
| 83 | Please feel free to try and report issues or feature requests for the tool to | 83 | Please feel free to try and report issues or feature requests for the tool to |
| 84 | the maintainer. | 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 | time slot, by reaching out to the maintainer. | 98 | time slot, by reaching out to the maintainer. |
| 99 | 99 | ||
| 100 | Schedules and available reservation time slots are available at the Google `doc | 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 | There is also a public Google `calendar | 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 | that has the events. Anyone can subscribe it. DAMON maintainer will also | 104 | that has the events. Anyone can subscribe it. DAMON maintainer will also |
| 105 | provide periodic reminder to the mailing list (damon@lists.linux.dev). | 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 | a Message Authentication Code (MAC). MACs are produced from the content | 9 | a Message Authentication Code (MAC). MACs are produced from the content |
| 10 | of a TCP segment using a hashing function with a password known to both peers. | 10 | of a TCP segment using a hashing function with a password known to both peers. |
| 11 | The intent of TCP-AO is to deprecate TCP-MD5 providing better security, | 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 | 1. Introduction | 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 | is not available, no action is required (RNextKeyID of a received | 164 | is not available, no action is required (RNextKeyID of a received |
| 165 | segment needs to match the MKT’s SendID). | 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 | 167 | Q: How is current_key set, and when does it change? Is it a user-triggered |
| 168 | change, or is it by a request from the remote peer? Is it set by the user | 168 | change, or is it triggered by a request from the remote peer? Is it set by the |
| 169 | explicitly, or by a matching rule? | 169 | user explicitly, or by a matching rule? |
| 170 | 170 | ||
| 171 | A: current_key is set by RNextKeyID [6.1]:: | 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 | Q: Can a non-TCP-AO connection become a TCP-AO-enabled one? | 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 | 236 | A: No: for an already established non-TCP-AO connection it would be impossible |
| 237 | to switch using TCP-AO as the traffic key generation requires the initial | 237 | to switch to using TCP-AO, as the traffic key generation requires the initial |
| 238 | sequence numbers. Paraphrasing, starting using TCP-AO would require | 238 | sequence numbers. Paraphrasing, starting using TCP-AO would require |
| 239 | re-establishing the TCP connection. | 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 | Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let | 293 | Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let |
| 294 | userspace manage TCP-AO on a per-socket basis. In order to add/delete MKTs | 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 | It is not allowed to add a key on an established non-TCP-AO connection | 296 | It is not allowed to add a key on an established non-TCP-AO connection |
| 297 | as well as to remove the last key from TCP-AO connection. | 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 | 4. ``setsockopt()`` vs ``accept()`` race | 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 | TCP-AO connections may have many keys, which means that accepted connections | 365 | TCP-AO connections may have many keys, which means that accepted connections |
| 366 | on a listen socket may have any amount of keys as well. As copying all those | 366 | on a listen socket may have any amount of keys as well. As copying all those |
| 367 | keys on a first properly signed SYN would make the request socket bigger, that | 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 | hanging in the accept queue. | 374 | hanging in the accept queue. |
| 375 | 375 | ||
| 376 | The reverse is valid as well: if userspace adds a new key for a peer on | 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 | have the new keys. | 378 | have the new keys. |
| 379 | 379 | ||
| 380 | At this moment, the resolution for the two races: | 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 | and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace. | 382 | and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace. |
| 383 | This means that it's expected that userspace would check the MKTs on the socket | 383 | This means that it's expected that userspace would check the MKTs on the socket |
| 384 | that was returned by ``accept()`` to verify that any key rotation that | 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 | This is a similar "do-nothing" approach to TCP-MD5 from the kernel side and | 387 | This is a similar "do-nothing" approach to TCP-MD5 from the kernel side and |
| 388 | may be changed later by introducing new flags to ``tcp_ao_add`` | 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 | with better review coverage. Re-posting large series also increases the mailing | 355 | with better review coverage. Re-posting large series also increases the mailing |
| 356 | list traffic. | 356 | list traffic. |
| 357 | 357 | ||
| 358 | .. _rcs: | ||
| 359 | |||
| 358 | Local variable ordering ("reverse xmas tree", "RCS") | 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 | ``__free()`` within networking core and drivers is discouraged. | 393 | ``__free()`` within networking core and drivers is discouraged. |
| 392 | Similar guidance applies to declaring variables mid-function. | 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 | Resending after review | 411 | Resending after review |
| 395 | ~~~~~~~~~~~~~~~~~~~~~~ | 412 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 396 | 413 | ||
| @@ -30,10 +30,13 @@ tree as a dedicated branch covering multiple subsystems. · 29 unmodified lines | |||
| 30 | The main SoC tree is housed on git.kernel.org: | 30 | The main SoC tree is housed on git.kernel.org: |
| 31 | https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/ | 31 | https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/ |
| 32 | 32 | ||
| 33 | Maintainers | ||
| 34 | ----------- | ||
| 35 | |||
| 33 | Clearly this is quite a wide range of topics, which no one person, or even | 36 | Clearly this is quite a wide range of topics, which no one person, or even |
| 34 | small group of people are capable of maintaining. Instead, the SoC subsystem | 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 | 38 | is comprised of many submaintainers (platform maintainers), each taking care of |
| 36 | and driver subdirectories. | 39 | individual platforms and driver subdirectories. |
| 37 | In this regard, "platform" usually refers to a series of SoCs from a given | 40 | In this regard, "platform" usually refers to a series of SoCs from a given |
| 38 | vendor, for example, Nvidia's series of Tegra SoCs. Many submaintainers operate | 41 | vendor, for example, Nvidia's series of Tegra SoCs. Many submaintainers operate |
| 39 | on a vendor level, responsible for multiple product lines. For several reasons, | 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 | Most of these submaintainers have their own trees where they stage patches, | 47 | Most of these submaintainers have their own trees where they stage patches, |
| 45 | sending pull requests to the main SoC tree. These trees are usually, but not | 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 | 49 | always, listed in MAINTAINERS. |
| 47 | alias soc@kernel.org if there is no platform-specific maintainer, or if they | ||
| 48 | are unresponsive. | ||
| 49 | 50 | ||
| 50 | What the SoC tree is not, however, is a location for architecture-specific code | 51 | What the SoC tree is not, however, is a location for architecture-specific code |
| 51 | changes. Each architecture has its own maintainers that are responsible for | 52 | changes. Each architecture has its own maintainers that are responsible for |
| 52 | architectural details, CPU errata and the like. | 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 | Information for (new) Submaintainers | 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 | .. code-block:: none | 66 | .. code-block:: none |
| 67 | 67 | ||
| 68 | # make -j16 -C tools/sched_ext | 68 | # make -j16 -C tools/sched_ext |
| 69 | # tools/sched_ext/scx_simple | 69 | # tools/sched_ext/build/bin/scx_simple |
| 70 | local=0 global=3 | 70 | local=0 global=3 |
| 71 | local=5 global=24 | 71 | local=5 global=24 |
| 72 | local=9 global=44 | 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 | KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is | 8098 | KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is |
| 8099 | disabled. | 8099 | disabled. |
| 8100 | 8100 | ||
| 8101 | KVM_X86_QUIRK_SLOT_ZAP_ALL By default, KVM invalidates all SPTEs in | 8101 | KVM_X86_QUIRK_SLOT_ZAP_ALL By default, for KVM_X86_DEFAULT_VM VMs, KVM |
| 8102 | fast way for memslot deletion when VM type | 8102 | invalidates all SPTEs in all memslots and |
| 8103 | is KVM_X86_DEFAULT_VM. | 8103 | address spaces when a memslot is deleted or |
| 8104 | When this quirk is disabled or when VM type | 8104 | moved. When this quirk is disabled (or the |
| 8105 | is other than KVM_X86_DEFAULT_VM, KVM zaps | 8105 | VM type isn't KVM_X86_DEFAULT_VM), KVM only |
| 8106 | only leaf SPTEs that are within the range of | 8106 | ensures the backing memory of the deleted |
| 8107 | the memslot being 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 | 7.32 KVM_CAP_MAX_VCPU_ID | 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 | to gfn. For indirect sp, we disabled fast page fault for simplicity. | 136 | to gfn. For indirect sp, we disabled fast page fault for simplicity. |
| 137 | 137 | ||
| 138 | A solution for indirect sp could be to pin the gfn, for example via | 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 | - We have held the refcount of pfn; that means the pfn can not be freed and | 141 | - We have held the refcount of pfn; that means the pfn can not be freed and |
| 142 | be reused for another gfn. | 142 | be reused for another gfn. |
| @@ -8,7 +8,7 @@ Introduction · 7 unmodified lines | |||
| 8 | ============ | 8 | ============ |
| 9 | 9 | ||
| 10 | Many Dell notebooks made after ~2020 support a WMI-based interface for | 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 | and fan/thermal sensor data. | 12 | and fan/thermal sensor data. |
| 13 | 13 | ||
| 14 | This interface is likely used by the `Dell Data Vault` software on Windows, | 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 | 4. Try to deduce the meaning of a certain WMI method by comparing the control | 277 | 4. Try to deduce the meaning of a certain WMI method by comparing the control |
| 278 | flow with other ACPI methods (_BIX or _BIF for battery related methods | 278 | flow with other ACPI methods (_BIX or _BIF for battery related methods |
| 279 | for example). | 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 | related methods (sometimes overwriting static ACPI data fields can be used | 281 | related methods (sometimes overwriting static ACPI data fields can be used |
| 282 | to test different sensor type values, since on some machines this data is | 282 | to test different sensor type values, since on some machines this data is |
| 283 | not reinitialized upon a warm reset). | 283 | not reinitialized upon a warm reset). |
| @@ -258,12 +258,6 @@ L: linux-acenic@sunsite.dk · 257 unmodified lines | |||
| 258 | S: Maintained | 258 | S: Maintained |
| 259 | F: drivers/net/ethernet/alteon/acenic* | 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 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER | 261 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER |
| 268 | M: Peter Kaestle <peter@piie.net> | 262 | M: Peter Kaestle <peter@piie.net> |
| 269 | L: platform-driver-x86@vger.kernel.org | 263 | L: platform-driver-x86@vger.kernel.org |
| @@ -860,7 +854,7 @@ F: drivers/crypto/allwinner/ · 590 unmodified lines | |||
| 860 | 854 | ||
| 861 | ALLWINNER DMIC DRIVERS | 855 | ALLWINNER DMIC DRIVERS |
| 862 | M: Ban Tao <fengzheng923@gmail.com> | 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 | S: Maintained | 858 | S: Maintained |
| 865 | F: Documentation/devicetree/bindings/sound/allwinner,sun50i-h6-dmic.yaml | 859 | F: Documentation/devicetree/bindings/sound/allwinner,sun50i-h6-dmic.yaml |
| 866 | F: sound/soc/sunxi/sun50i-dmic.c | 860 | F: sound/soc/sunxi/sun50i-dmic.c |
| @@ -888,7 +882,6 @@ F: drivers/staging/media/sunxi/cedrus/ · 21 unmodified lines | |||
| 888 | 882 | ||
| 889 | ALPHA PORT | 883 | ALPHA PORT |
| 890 | M: Richard Henderson <richard.henderson@linaro.org> | 884 | M: Richard Henderson <richard.henderson@linaro.org> |
| 891 | M: Ivan Kokshaysky <ink@jurassic.park.msu.ru> | ||
| 892 | M: Matt Turner <mattst88@gmail.com> | 885 | M: Matt Turner <mattst88@gmail.com> |
| 893 | L: linux-alpha@vger.kernel.org | 886 | L: linux-alpha@vger.kernel.org |
| 894 | S: Odd Fixes | 887 | S: Odd Fixes |
| @@ -1517,7 +1510,7 @@ F: drivers/iio/gyro/adxrs290.c · 622 unmodified lines | |||
| 1517 | ANALOG DEVICES INC ASOC CODEC DRIVERS | 1510 | ANALOG DEVICES INC ASOC CODEC DRIVERS |
| 1518 | M: Lars-Peter Clausen <lars@metafoo.de> | 1511 | M: Lars-Peter Clausen <lars@metafoo.de> |
| 1519 | M: Nuno Sá <nuno.sa@analog.com> | 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 | S: Supported | 1514 | S: Supported |
| 1522 | W: http://wiki.analog.com/ | 1515 | W: http://wiki.analog.com/ |
| 1523 | W: https://ez.analog.com/linux-software-drivers | 1516 | W: https://ez.analog.com/linux-software-drivers |
| @@ -1594,7 +1587,7 @@ F: drivers/rtc/rtc-goldfish.c · 70 unmodified lines | |||
| 1594 | AOA (Apple Onboard Audio) ALSA DRIVER | 1587 | AOA (Apple Onboard Audio) ALSA DRIVER |
| 1595 | M: Johannes Berg <johannes@sipsolutions.net> | 1588 | M: Johannes Berg <johannes@sipsolutions.net> |
| 1596 | L: linuxppc-dev@lists.ozlabs.org | 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 | S: Maintained | 1591 | S: Maintained |
| 1599 | F: sound/aoa/ | 1592 | F: sound/aoa/ |
| 1600 | 1593 | ||
| @@ -1761,8 +1754,8 @@ F: include/uapi/linux/if_arcnet.h · 160 unmodified lines | |||
| 1761 | ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS) | 1754 | ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS) |
| 1762 | M: Arnd Bergmann <arnd@arndb.de> | 1755 | M: Arnd Bergmann <arnd@arndb.de> |
| 1763 | M: Olof Johansson <olof@lixom.net> | 1756 | M: Olof Johansson <olof@lixom.net> |
| 1764 | M: soc@kernel.org | ||
| 1765 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1757 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1758 | L: soc@lists.linux.dev | ||
| 1766 | S: Maintained | 1759 | S: Maintained |
| 1767 | P: Documentation/process/maintainer-soc.rst | 1760 | P: Documentation/process/maintainer-soc.rst |
| 1768 | C: irc://irc.libera.chat/armlinux | 1761 | C: irc://irc.libera.chat/armlinux |
| @@ -2091,7 +2084,7 @@ F: drivers/crypto/amlogic/ · 322 unmodified lines | |||
| 2091 | 2084 | ||
| 2092 | ARM/Amlogic Meson SoC Sound Drivers | 2085 | ARM/Amlogic Meson SoC Sound Drivers |
| 2093 | M: Jerome Brunet <jbrunet@baylibre.com> | 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 | S: Maintained | 2088 | S: Maintained |
| 2096 | F: Documentation/devicetree/bindings/sound/amlogic* | 2089 | F: Documentation/devicetree/bindings/sound/amlogic* |
| 2097 | F: sound/soc/meson/ | 2090 | F: sound/soc/meson/ |
| @@ -2129,7 +2122,7 @@ F: drivers/*/*alpine* · 31 unmodified lines | |||
| 2129 | ARM/APPLE MACHINE SOUND DRIVERS | 2122 | ARM/APPLE MACHINE SOUND DRIVERS |
| 2130 | M: Martin Povišer <povik+lin@cutebit.org> | 2123 | M: Martin Povišer <povik+lin@cutebit.org> |
| 2131 | L: asahi@lists.linux.dev | 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 | S: Maintained | 2126 | S: Maintained |
| 2134 | F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml | 2127 | F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml |
| 2135 | F: Documentation/devicetree/bindings/sound/apple,* | 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 | S: Maintained | 2256 | S: Maintained |
| 2264 | F: arch/arm/mach-ep93xx/ts72xx.c | 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 | ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE | 2259 | ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE |
| 2273 | M: Hartley Sweeten <hsweeten@visionengravers.com> | 2260 | M: Hartley Sweeten <hsweeten@visionengravers.com> |
| 2274 | M: Alexander Sverdlin <alexander.sverdlin@gmail.com> | 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 | AXENTIA ASOC DRIVERS | 3720 | AXENTIA ASOC DRIVERS |
| 3734 | M: Peter Rosin <peda@axentia.se> | 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 | S: Maintained | 3723 | S: Maintained |
| 3737 | F: Documentation/devicetree/bindings/sound/axentia,* | 3724 | F: Documentation/devicetree/bindings/sound/axentia,* |
| 3738 | F: sound/soc/atmel/tse850-pcm5142.c | 3725 | F: sound/soc/atmel/tse850-pcm5142.c |
| @@ -3815,14 +3802,6 @@ F: drivers/video/backlight/ · 76 unmodified lines | |||
| 3815 | F: include/linux/backlight.h | 3802 | F: include/linux/backlight.h |
| 3816 | F: include/linux/pwm_backlight.h | 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 | BARCO P50 GPIO DRIVER | 3805 | BARCO P50 GPIO DRIVER |
| 3827 | M: Santosh Kumar Yadav <santoshkumar.yadav@barco.com> | 3806 | M: Santosh Kumar Yadav <santoshkumar.yadav@barco.com> |
| 3828 | M: Peter Korsgaard <peter.korsgaard@barco.com> | 3807 | M: Peter Korsgaard <peter.korsgaard@barco.com> |
| @@ -4851,7 +4830,7 @@ F: include/uapi/linux/bsg.h · 1022 unmodified lines | |||
| 4851 | 4830 | ||
| 4852 | BT87X AUDIO DRIVER | 4831 | BT87X AUDIO DRIVER |
| 4853 | M: Clemens Ladisch <clemens@ladisch.de> | 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 | S: Maintained | 4834 | S: Maintained |
| 4856 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 4835 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 4857 | F: Documentation/sound/cards/bt87x.rst | 4836 | F: Documentation/sound/cards/bt87x.rst |
| @@ -4913,7 +4892,7 @@ F: drivers/net/can/bxcan.c · 55 unmodified lines | |||
| 4913 | 4892 | ||
| 4914 | C-MEDIA CMI8788 DRIVER | 4893 | C-MEDIA CMI8788 DRIVER |
| 4915 | M: Clemens Ladisch <clemens@ladisch.de> | 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 | S: Maintained | 4896 | S: Maintained |
| 4918 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 4897 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 4919 | F: sound/pci/oxygen/ | 4898 | F: sound/pci/oxygen/ |
| @@ -6476,7 +6455,6 @@ F: drivers/mtd/nand/raw/denali* · 1556 unmodified lines | |||
| 6476 | 6455 | ||
| 6477 | DESIGNWARE EDMA CORE IP DRIVER | 6456 | DESIGNWARE EDMA CORE IP DRIVER |
| 6478 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | 6457 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| 6479 | R: Serge Semin <fancer.lancer@gmail.com> | ||
| 6480 | L: dmaengine@vger.kernel.org | 6458 | L: dmaengine@vger.kernel.org |
| 6481 | S: Maintained | 6459 | S: Maintained |
| 6482 | F: drivers/dma/dw-edma/ | 6460 | F: drivers/dma/dw-edma/ |
| @@ -7832,6 +7810,8 @@ F: drivers/gpu/drm/xlnx/ · 1349 unmodified lines | |||
| 7832 | DRM GPU SCHEDULER | 7810 | DRM GPU SCHEDULER |
| 7833 | M: Luben Tuikov <ltuikov89@gmail.com> | 7811 | M: Luben Tuikov <ltuikov89@gmail.com> |
| 7834 | M: Matthew Brost <matthew.brost@intel.com> | 7812 | M: Matthew Brost <matthew.brost@intel.com> |
| 7813 | M: Danilo Krummrich <dakr@kernel.org> | ||
| 7814 | M: Philipp Stanner <pstanner@redhat.com> | ||
| 7835 | L: dri-devel@lists.freedesktop.org | 7815 | L: dri-devel@lists.freedesktop.org |
| 7836 | S: Maintained | 7816 | S: Maintained |
| 7837 | T: git https://gitlab.freedesktop.org/drm/misc/kernel.git | 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 | EDIROL UA-101/UA-1000 DRIVER | 8233 | EDIROL UA-101/UA-1000 DRIVER |
| 8254 | M: Clemens Ladisch <clemens@ladisch.de> | 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 | S: Maintained | 8236 | S: Maintained |
| 8257 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 8237 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 8258 | F: sound/usb/misc/ua101.c | 8238 | F: sound/usb/misc/ua101.c |
| @@ -8814,7 +8794,7 @@ F: drivers/net/can/usb/f81604.c · 555 unmodified lines | |||
| 8814 | FIREWIRE AUDIO DRIVERS and IEC 61883-1/6 PACKET STREAMING ENGINE | 8794 | FIREWIRE AUDIO DRIVERS and IEC 61883-1/6 PACKET STREAMING ENGINE |
| 8815 | M: Clemens Ladisch <clemens@ladisch.de> | 8795 | M: Clemens Ladisch <clemens@ladisch.de> |
| 8816 | M: Takashi Sakamoto <o-takashi@sakamocchi.jp> | 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 | S: Maintained | 8798 | S: Maintained |
| 8819 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 8799 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 8820 | F: include/uapi/sound/firewire.h | 8800 | F: include/uapi/sound/firewire.h |
| @@ -8888,7 +8868,7 @@ F: drivers/input/joystick/fsia6b.c · 67 unmodified lines | |||
| 8888 | 8868 | ||
| 8889 | FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett) | 8869 | FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett) |
| 8890 | M: Geoffrey D. Bennett <g@b4.vu> | 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 | S: Maintained | 8872 | S: Maintained |
| 8893 | W: https://github.com/geoffreybennett/scarlett-gen2 | 8873 | W: https://github.com/geoffreybennett/scarlett-gen2 |
| 8894 | B: https://github.com/geoffreybennett/scarlett-gen2/issues | 8874 | B: https://github.com/geoffreybennett/scarlett-gen2/issues |
| @@ -8912,6 +8892,7 @@ F: include/linux/fortify-string.h · 17 unmodified lines | |||
| 8912 | F: lib/fortify_kunit.c | 8892 | F: lib/fortify_kunit.c |
| 8913 | F: lib/memcpy_kunit.c | 8893 | F: lib/memcpy_kunit.c |
| 8914 | F: lib/test_fortify/* | 8894 | F: lib/test_fortify/* |
| 8895 | K: \bunsafe_memcpy\b | ||
| 8915 | K: \b__NO_FORTIFY\b | 8896 | K: \b__NO_FORTIFY\b |
| 8916 | 8897 | ||
| 8917 | FPGA DFL DRIVERS | 8898 | FPGA DFL DRIVERS |
| @@ -9209,7 +9190,7 @@ M: Shengjiu Wang <shengjiu.wang@gmail.com> · 291 unmodified lines | |||
| 9209 | M: Xiubo Li <Xiubo.Lee@gmail.com> | 9190 | M: Xiubo Li <Xiubo.Lee@gmail.com> |
| 9210 | R: Fabio Estevam <festevam@gmail.com> | 9191 | R: Fabio Estevam <festevam@gmail.com> |
| 9211 | R: Nicolin Chen <nicoleotsuka@gmail.com> | 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 | L: linuxppc-dev@lists.ozlabs.org | 9194 | L: linuxppc-dev@lists.ozlabs.org |
| 9214 | S: Maintained | 9195 | S: Maintained |
| 9215 | F: sound/soc/fsl/fsl* | 9196 | F: sound/soc/fsl/fsl* |
| @@ -9219,7 +9200,7 @@ FREESCALE SOC LPC32XX SOUND DRIVERS · 3 unmodified lines | |||
| 9219 | M: J.M.B. Downing <jonathan.downing@nautel.com> | 9200 | M: J.M.B. Downing <jonathan.downing@nautel.com> |
| 9220 | M: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com> | 9201 | M: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com> |
| 9221 | R: Vladimir Zapolskiy <vz@mleia.com> | 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 | L: linuxppc-dev@lists.ozlabs.org | 9204 | L: linuxppc-dev@lists.ozlabs.org |
| 9224 | S: Maintained | 9205 | S: Maintained |
| 9225 | F: Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml | 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 | FREESCALE SOC SOUND QMC DRIVER | 9209 | FREESCALE SOC SOUND QMC DRIVER |
| 9229 | M: Herve Codina <herve.codina@bootlin.com> | 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 | L: linuxppc-dev@lists.ozlabs.org | 9212 | L: linuxppc-dev@lists.ozlabs.org |
| 9232 | S: Maintained | 9213 | S: Maintained |
| 9233 | F: Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml | 9214 | F: Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml |
| @@ -9756,14 +9737,6 @@ F: drivers/gpio/gpiolib-cdev.c · 522 unmodified lines | |||
| 9756 | F: include/uapi/linux/gpio.h | 9737 | F: include/uapi/linux/gpio.h |
| 9757 | F: tools/gpio/ | 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 | GRETH 10/100/1G Ethernet MAC device driver | 9740 | GRETH 10/100/1G Ethernet MAC device driver |
| 9768 | M: Andreas Larsson <andreas@gaisler.com> | 9741 | M: Andreas Larsson <andreas@gaisler.com> |
| 9769 | L: netdev@vger.kernel.org | 9742 | L: netdev@vger.kernel.org |
| @@ -10267,7 +10240,7 @@ F: Documentation/devicetree/bindings/arm/hisilicon/low-pin-count.yaml · 497 unmodified lines | |||
| 10267 | F: drivers/bus/hisi_lpc.c | 10240 | F: drivers/bus/hisi_lpc.c |
| 10268 | 10241 | ||
| 10269 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) | 10242 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) |
| 10270 | M: Yisen Zhuang <yisen.zhuang@huawei.com> | 10243 | M: Jian Shen <shenjian15@huawei.com> |
| 10271 | M: Salil Mehta <salil.mehta@huawei.com> | 10244 | M: Salil Mehta <salil.mehta@huawei.com> |
| 10272 | M: Jijie Shao <shaojijie@huawei.com> | 10245 | M: Jijie Shao <shaojijie@huawei.com> |
| 10273 | L: netdev@vger.kernel.org | 10246 | L: netdev@vger.kernel.org |
| @@ -10276,7 +10249,7 @@ W: http://www.hisilicon.com · 2 unmodified lines | |||
| 10276 | F: drivers/net/ethernet/hisilicon/hns3/ | 10249 | F: drivers/net/ethernet/hisilicon/hns3/ |
| 10277 | 10250 | ||
| 10278 | HISILICON NETWORK SUBSYSTEM DRIVER | 10251 | HISILICON NETWORK SUBSYSTEM DRIVER |
| 10279 | M: Yisen Zhuang <yisen.zhuang@huawei.com> | 10252 | M: Jian Shen <shenjian15@huawei.com> |
| 10280 | M: Salil Mehta <salil.mehta@huawei.com> | 10253 | M: Salil Mehta <salil.mehta@huawei.com> |
| 10281 | L: netdev@vger.kernel.org | 10254 | L: netdev@vger.kernel.org |
| 10282 | S: Maintained | 10255 | S: Maintained |
| @@ -11154,7 +11127,7 @@ F: drivers/iio/pressure/dps310.c · 871 unmodified lines | |||
| 11154 | 11127 | ||
| 11155 | INFINEON PEB2466 ASoC CODEC | 11128 | INFINEON PEB2466 ASoC CODEC |
| 11156 | M: Herve Codina <herve.codina@bootlin.com> | 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 | S: Maintained | 11131 | S: Maintained |
| 11159 | F: Documentation/devicetree/bindings/sound/infineon,peb2466.yaml | 11132 | F: Documentation/devicetree/bindings/sound/infineon,peb2466.yaml |
| 11160 | F: sound/soc/codecs/peb2466.c | 11133 | F: sound/soc/codecs/peb2466.c |
| @@ -11280,10 +11253,10 @@ F: security/integrity/ · 119 unmodified lines | |||
| 11280 | F: security/integrity/ima/ | 11253 | F: security/integrity/ima/ |
| 11281 | 11254 | ||
| 11282 | INTEGRITY POLICY ENFORCEMENT (IPE) | 11255 | INTEGRITY POLICY ENFORCEMENT (IPE) |
| 11283 | M: Fan Wu <wufan@linux.microsoft.com> | 11256 | M: Fan Wu <wufan@kernel.org> |
| 11284 | L: linux-security-module@vger.kernel.org | 11257 | L: linux-security-module@vger.kernel.org |
| 11285 | S: Supported | 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 | F: Documentation/admin-guide/LSM/ipe.rst | 11260 | F: Documentation/admin-guide/LSM/ipe.rst |
| 11288 | F: Documentation/security/ipe.rst | 11261 | F: Documentation/security/ipe.rst |
| 11289 | F: scripts/ipe/ | 11262 | F: scripts/ipe/ |
| @@ -11317,7 +11290,7 @@ M: Bard Liao <yung-chuan.liao@linux.intel.com> · 27 unmodified lines | |||
| 11317 | M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> | 11290 | M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> |
| 11318 | M: Kai Vehmanen <kai.vehmanen@linux.intel.com> | 11291 | M: Kai Vehmanen <kai.vehmanen@linux.intel.com> |
| 11319 | R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> | 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 | S: Supported | 11294 | S: Supported |
| 11322 | F: sound/soc/intel/ | 11295 | F: sound/soc/intel/ |
| 11323 | 11296 | ||
| @@ -11496,7 +11469,7 @@ F: include/uapi/linux/idxd.h · 172 unmodified lines | |||
| 11496 | 11469 | ||
| 11497 | INTEL IN FIELD SCAN (IFS) DEVICE | 11470 | INTEL IN FIELD SCAN (IFS) DEVICE |
| 11498 | M: Jithu Joseph <jithu.joseph@intel.com> | 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 | R: Tony Luck <tony.luck@intel.com> | 11473 | R: Tony Luck <tony.luck@intel.com> |
| 11501 | S: Maintained | 11474 | S: Maintained |
| 11502 | F: drivers/platform/x86/intel/ifs | 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 | F: drivers/crypto/intel/keembay/ocs-hcu.c | 11574 | F: drivers/crypto/intel/keembay/ocs-hcu.c |
| 11602 | F: drivers/crypto/intel/keembay/ocs-hcu.h | 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 | INTEL MANAGEMENT ENGINE (mei) | 11587 | INTEL MANAGEMENT ENGINE (mei) |
| 11605 | M: Tomas Winkler <tomas.winkler@intel.com> | 11588 | M: Tomas Winkler <tomas.winkler@intel.com> |
| 11606 | L: linux-kernel@vger.kernel.org | 11589 | L: linux-kernel@vger.kernel.org |
| @@ -12001,7 +11984,7 @@ F: drivers/tty/ipwireless/ · 394 unmodified lines | |||
| 12001 | 11984 | ||
| 12002 | IRON DEVICE AUDIO CODEC DRIVERS | 11985 | IRON DEVICE AUDIO CODEC DRIVERS |
| 12003 | M: Kiseok Jo <kiseok.jo@irondevice.com> | 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 | S: Maintained | 11988 | S: Maintained |
| 12006 | F: Documentation/devicetree/bindings/sound/irondevice,* | 11989 | F: Documentation/devicetree/bindings/sound/irondevice,* |
| 12007 | F: sound/soc/codecs/sma* | 11990 | F: sound/soc/codecs/sma* |
| @@ -12239,6 +12222,7 @@ R: Dmitry Vyukov <dvyukov@google.com> · 231 unmodified lines | |||
| 12239 | R: Vincenzo Frascino <vincenzo.frascino@arm.com> | 12222 | R: Vincenzo Frascino <vincenzo.frascino@arm.com> |
| 12240 | L: kasan-dev@googlegroups.com | 12223 | L: kasan-dev@googlegroups.com |
| 12241 | S: Maintained | 12224 | S: Maintained |
| 12225 | B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management | ||
| 12242 | F: Documentation/dev-tools/kasan.rst | 12226 | F: Documentation/dev-tools/kasan.rst |
| 12243 | F: arch/*/include/asm/*kasan.h | 12227 | F: arch/*/include/asm/*kasan.h |
| 12244 | F: arch/*/mm/kasan_init* | 12228 | F: arch/*/mm/kasan_init* |
| @@ -12262,6 +12246,7 @@ R: Dmitry Vyukov <dvyukov@google.com> · 17 unmodified lines | |||
| 12262 | R: Andrey Konovalov <andreyknvl@gmail.com> | 12246 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 12263 | L: kasan-dev@googlegroups.com | 12247 | L: kasan-dev@googlegroups.com |
| 12264 | S: Maintained | 12248 | S: Maintained |
| 12249 | B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management | ||
| 12265 | F: Documentation/dev-tools/kcov.rst | 12250 | F: Documentation/dev-tools/kcov.rst |
| 12266 | F: include/linux/kcov.h | 12251 | F: include/linux/kcov.h |
| 12267 | F: include/uapi/linux/kcov.h | 12252 | F: include/uapi/linux/kcov.h |
| @@ -12343,6 +12328,7 @@ F: include/linux/randomize_kstack.h · 75 unmodified lines | |||
| 12343 | F: kernel/configs/hardening.config | 12328 | F: kernel/configs/hardening.config |
| 12344 | F: lib/usercopy_kunit.c | 12329 | F: lib/usercopy_kunit.c |
| 12345 | F: mm/usercopy.c | 12330 | F: mm/usercopy.c |
| 12331 | F: security/Kconfig.hardening | ||
| 12346 | K: \b(add|choose)_random_kstack_offset\b | 12332 | K: \b(add|choose)_random_kstack_offset\b |
| 12347 | K: \b__check_(object_size|heap_object)\b | 12333 | K: \b__check_(object_size|heap_object)\b |
| 12348 | K: \b__counted_by\b | 12334 | K: \b__counted_by\b |
| @@ -12459,7 +12445,7 @@ F: virt/kvm/* · 110 unmodified lines | |||
| 12459 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) | 12445 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) |
| 12460 | M: Marc Zyngier <maz@kernel.org> | 12446 | M: Marc Zyngier <maz@kernel.org> |
| 12461 | M: Oliver Upton <oliver.upton@linux.dev> | 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 | R: Suzuki K Poulose <suzuki.poulose@arm.com> | 12449 | R: Suzuki K Poulose <suzuki.poulose@arm.com> |
| 12464 | R: Zenghui Yu <yuzenghui@huawei.com> | 12450 | R: Zenghui Yu <yuzenghui@huawei.com> |
| 12465 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 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 | M: Viresh Kumar <vireshk@kernel.org> | 12926 | M: Viresh Kumar <vireshk@kernel.org> |
| 12941 | L: linux-ide@vger.kernel.org | 12927 | L: linux-ide@vger.kernel.org |
| 12942 | S: Maintained | 12928 | S: Maintained |
| 12943 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | ||
| 12944 | F: drivers/ata/pata_arasan_cf.c | 12929 | F: drivers/ata/pata_arasan_cf.c |
| 12945 | F: include/linux/pata_arasan_cf_data.h | 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 | LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS | 12932 | LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS |
| 12954 | M: Linus Walleij <linus.walleij@linaro.org> | 12933 | M: Linus Walleij <linus.walleij@linaro.org> |
| 12955 | L: linux-ide@vger.kernel.org | 12934 | L: linux-ide@vger.kernel.org |
| 12956 | S: Maintained | 12935 | S: Maintained |
| 12957 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | ||
| 12958 | F: drivers/ata/pata_ftide010.c | 12936 | F: drivers/ata/pata_ftide010.c |
| 12959 | F: drivers/ata/sata_gemini.c | 12937 | F: drivers/ata/sata_gemini.c |
| 12960 | F: drivers/ata/sata_gemini.h | 12938 | F: drivers/ata/sata_gemini.h |
| 12961 | 12939 | ||
| 12962 | LIBATA SATA AHCI PLATFORM devices support | 12940 | LIBATA SATA AHCI PLATFORM devices support |
| 12963 | M: Hans de Goede <hdegoede@redhat.com> | 12941 | M: Hans de Goede <hdegoede@redhat.com> |
| 12964 | M: Jens Axboe <axboe@kernel.dk> | ||
| 12965 | L: linux-ide@vger.kernel.org | 12942 | L: linux-ide@vger.kernel.org |
| 12966 | S: Maintained | 12943 | S: Maintained |
| 12967 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | ||
| 12968 | F: drivers/ata/ahci_platform.c | 12944 | F: drivers/ata/ahci_platform.c |
| 12969 | F: drivers/ata/libahci_platform.c | 12945 | F: drivers/ata/libahci_platform.c |
| 12970 | F: include/linux/ahci_platform.h | 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 | LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER | 12948 | LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER |
| 12982 | M: Mikael Pettersson <mikpelinux@gmail.com> | 12949 | M: Mikael Pettersson <mikpelinux@gmail.com> |
| 12983 | L: linux-ide@vger.kernel.org | 12950 | L: linux-ide@vger.kernel.org |
| 12984 | S: Maintained | 12951 | S: Maintained |
| 12985 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | ||
| 12986 | F: drivers/ata/sata_promise.* | 12952 | F: drivers/ata/sata_promise.* |
| 12987 | 12953 | ||
| 12988 | LIBATA SUBSYSTEM (Serial and Parallel ATA drivers) | 12954 | LIBATA SUBSYSTEM (Serial and Parallel ATA drivers) |
| @@ -13952,7 +13918,7 @@ F: drivers/media/i2c/max96717.c · 963 unmodified lines | |||
| 13952 | 13918 | ||
| 13953 | MAX9860 MONO AUDIO VOICE CODEC DRIVER | 13919 | MAX9860 MONO AUDIO VOICE CODEC DRIVER |
| 13954 | M: Peter Rosin <peda@axentia.se> | 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 | S: Maintained | 13922 | S: Maintained |
| 13957 | F: Documentation/devicetree/bindings/sound/max9860.txt | 13923 | F: Documentation/devicetree/bindings/sound/max9860.txt |
| 13958 | F: sound/soc/codecs/max9860.* | 13924 | F: sound/soc/codecs/max9860.* |
| @@ -14174,16 +14140,6 @@ S: Maintained · 215 unmodified lines | |||
| 14174 | T: git git://linuxtv.org/media_tree.git | 14140 | T: git git://linuxtv.org/media_tree.git |
| 14175 | F: drivers/media/platform/nxp/imx-pxp.[ch] | 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 | MEDIA DRIVERS FOR CXD2099AR CI CONTROLLERS | 14143 | MEDIA DRIVERS FOR CXD2099AR CI CONTROLLERS |
| 14188 | M: Jasmin Jessich <jasmin@anw.at> | 14144 | M: Jasmin Jessich <jasmin@anw.at> |
| 14189 | L: linux-media@vger.kernel.org | 14145 | L: linux-media@vger.kernel.org |
| @@ -14192,16 +14148,6 @@ W: https://linuxtv.org · 2 unmodified lines | |||
| 14192 | T: git git://linuxtv.org/media_tree.git | 14148 | T: git git://linuxtv.org/media_tree.git |
| 14193 | F: drivers/media/dvb-frontends/cxd2099* | 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 | MEDIA DRIVERS FOR CXD2880 | 14151 | MEDIA DRIVERS FOR CXD2880 |
| 14206 | M: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com> | 14152 | M: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com> |
| 14207 | L: linux-media@vger.kernel.org | 14153 | L: linux-media@vger.kernel.org |
| @@ -14246,35 +14192,6 @@ F: drivers/media/platform/nxp/imx-mipi-csis.c · 38 unmodified lines | |||
| 14246 | F: drivers/media/platform/nxp/imx7-media-csi.c | 14192 | F: drivers/media/platform/nxp/imx7-media-csi.c |
| 14247 | F: drivers/media/platform/nxp/imx8mq-mipi-csi2.c | 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 | MEDIA DRIVERS FOR MXL5XX TUNER DEMODULATORS | 14195 | MEDIA DRIVERS FOR MXL5XX TUNER DEMODULATORS |
| 14279 | L: linux-media@vger.kernel.org | 14196 | L: linux-media@vger.kernel.org |
| 14280 | S: Orphan | 14197 | S: Orphan |
| @@ -14282,16 +14199,6 @@ W: https://linuxtv.org · 1 unmodified line | |||
| 14282 | T: git git://linuxtv.org/media_tree.git | 14199 | T: git git://linuxtv.org/media_tree.git |
| 14283 | F: drivers/media/dvb-frontends/mxl5xx* | 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 | MEDIA DRIVERS FOR NVIDIA TEGRA - VDE | 14202 | MEDIA DRIVERS FOR NVIDIA TEGRA - VDE |
| 14296 | M: Dmitry Osipenko <digetx@gmail.com> | 14203 | M: Dmitry Osipenko <digetx@gmail.com> |
| 14297 | L: linux-media@vger.kernel.org | 14204 | L: linux-media@vger.kernel.org |
| @@ -14909,9 +14816,10 @@ N: include/linux/page[-_]* · 611 unmodified lines | |||
| 14909 | 14816 | ||
| 14910 | MEMORY MAPPING | 14817 | MEMORY MAPPING |
| 14911 | M: Andrew Morton <akpm@linux-foundation.org> | 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 | R: Vlastimil Babka <vbabka@suse.cz> | 14821 | R: Vlastimil Babka <vbabka@suse.cz> |
| 14914 | R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | 14822 | R: Jann Horn <jannh@google.com> |
| 14915 | L: linux-mm@kvack.org | 14823 | L: linux-mm@kvack.org |
| 14916 | S: Maintained | 14824 | S: Maintained |
| 14917 | W: http://www.linux-mm.org | 14825 | W: http://www.linux-mm.org |
| @@ -14934,13 +14842,6 @@ F: drivers/mtd/ · 16 unmodified lines | |||
| 14934 | F: include/linux/mtd/ | 14842 | F: include/linux/mtd/ |
| 14935 | F: include/uapi/mtd/ | 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 | MEN A21 WATCHDOG DRIVER | 14845 | MEN A21 WATCHDOG DRIVER |
| 14945 | M: Johannes Thumshirn <morbidrsa@gmail.com> | 14846 | M: Johannes Thumshirn <morbidrsa@gmail.com> |
| 14946 | L: linux-watchdog@vger.kernel.org | 14847 | L: linux-watchdog@vger.kernel.org |
| @@ -15085,7 +14986,7 @@ F: drivers/spi/spi-at91-usart.c · 138 unmodified lines | |||
| 15085 | 14986 | ||
| 15086 | MICROCHIP AUDIO ASOC DRIVERS | 14987 | MICROCHIP AUDIO ASOC DRIVERS |
| 15087 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | 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 | S: Supported | 14990 | S: Supported |
| 15090 | F: Documentation/devicetree/bindings/sound/atmel* | 14991 | F: Documentation/devicetree/bindings/sound/atmel* |
| 15091 | F: Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt | 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 | MICROCHIP POLARFIRE FPGA DRIVERS | 15176 | MICROCHIP POLARFIRE FPGA DRIVERS |
| 15276 | M: Conor Dooley <conor.dooley@microchip.com> | 15177 | M: Conor Dooley <conor.dooley@microchip.com> |
| 15277 | R: Vladimir Georgiev <v.georgiev@metrotek.ru> | ||
| 15278 | L: linux-fpga@vger.kernel.org | 15178 | L: linux-fpga@vger.kernel.org |
| 15279 | S: Supported | 15179 | S: Supported |
| 15280 | F: Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml | 15180 | F: Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml |
| @@ -15529,17 +15429,6 @@ F: arch/mips/ · 248 unmodified lines | |||
| 15529 | F: drivers/platform/mips/ | 15429 | F: drivers/platform/mips/ |
| 15530 | F: include/dt-bindings/mips/ | 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 | MIPS BOSTON DEVELOPMENT BOARD | 15432 | MIPS BOSTON DEVELOPMENT BOARD |
| 15544 | M: Paul Burton <paulburton@kernel.org> | 15433 | M: Paul Burton <paulburton@kernel.org> |
| 15545 | L: linux-mips@vger.kernel.org | 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 | MIPS CORE DRIVERS | 15442 | MIPS CORE DRIVERS |
| 15554 | M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 15443 | M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> |
| 15555 | M: Serge Semin <fancer.lancer@gmail.com> | ||
| 15556 | L: linux-mips@vger.kernel.org | 15444 | L: linux-mips@vger.kernel.org |
| 15557 | S: Supported | 15445 | S: Supported |
| 15558 | F: drivers/bus/mips_cdmm.c | 15446 | F: drivers/bus/mips_cdmm.c |
| @@ -15957,7 +15845,7 @@ F: include/linux/mtd/*nand*.h · 398 unmodified lines | |||
| 15957 | 15845 | ||
| 15958 | NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER | 15846 | NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER |
| 15959 | M: Daniel Mack <zonque@gmail.com> | 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 | S: Maintained | 15849 | S: Maintained |
| 15962 | W: http://www.native-instruments.com | 15850 | W: http://www.native-instruments.com |
| 15963 | F: sound/usb/caiaq/ | 15851 | F: sound/usb/caiaq/ |
| @@ -16088,6 +15976,7 @@ F: include/uapi/linux/net_dropmon.h · 124 unmodified lines | |||
| 16088 | F: net/core/drop_monitor.c | 15976 | F: net/core/drop_monitor.c |
| 16089 | 15977 | ||
| 16090 | NETWORKING DRIVERS | 15978 | NETWORKING DRIVERS |
| 15979 | M: Andrew Lunn <andrew+netdev@lunn.ch> | ||
| 16091 | M: "David S. Miller" <davem@davemloft.net> | 15980 | M: "David S. Miller" <davem@davemloft.net> |
| 16092 | M: Eric Dumazet <edumazet@google.com> | 15981 | M: Eric Dumazet <edumazet@google.com> |
| 16093 | M: Jakub Kicinski <kuba@kernel.org> | 15982 | M: Jakub Kicinski <kuba@kernel.org> |
| @@ -16153,6 +16042,7 @@ M: "David S. Miller" <davem@davemloft.net> · 59 unmodified lines | |||
| 16153 | M: Eric Dumazet <edumazet@google.com> | 16042 | M: Eric Dumazet <edumazet@google.com> |
| 16154 | M: Jakub Kicinski <kuba@kernel.org> | 16043 | M: Jakub Kicinski <kuba@kernel.org> |
| 16155 | M: Paolo Abeni <pabeni@redhat.com> | 16044 | M: Paolo Abeni <pabeni@redhat.com> |
| 16045 | R: Simon Horman <horms@kernel.org> | ||
| 16156 | L: netdev@vger.kernel.org | 16046 | L: netdev@vger.kernel.org |
| 16157 | S: Maintained | 16047 | S: Maintained |
| 16158 | P: Documentation/process/maintainer-netdev.rst | 16048 | P: Documentation/process/maintainer-netdev.rst |
| @@ -16195,10 +16085,22 @@ F: include/uapi/linux/rtnetlink.h · 36 unmodified lines | |||
| 16195 | F: lib/net_utils.c | 16085 | F: lib/net_utils.c |
| 16196 | F: lib/random32.c | 16086 | F: lib/random32.c |
| 16197 | F: net/ | 16087 | F: net/ |
| 16088 | F: samples/pktgen/ | ||
| 16198 | F: tools/net/ | 16089 | F: tools/net/ |
| 16199 | F: tools/testing/selftests/net/ | 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 | X: net/9p/ | 16099 | X: net/9p/ |
| 16201 | X: net/bluetooth/ | 16100 | X: net/bluetooth/ |
| 16101 | X: net/mac80211/ | ||
| 16102 | X: net/rfkill/ | ||
| 16103 | X: net/wireless/ | ||
| 16202 | 16104 | ||
| 16203 | NETWORKING [IPSEC] | 16105 | NETWORKING [IPSEC] |
| 16204 | M: Steffen Klassert <steffen.klassert@secunet.com> | 16106 | M: Steffen Klassert <steffen.klassert@secunet.com> |
| @@ -16508,12 +16410,6 @@ F: include/linux/ntb.h · 303 unmodified lines | |||
| 16508 | F: include/linux/ntb_transport.h | 16410 | F: include/linux/ntb_transport.h |
| 16509 | F: tools/testing/selftests/ntb/ | 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 | NTB INTEL DRIVER | 16413 | NTB INTEL DRIVER |
| 16518 | M: Dave Jiang <dave.jiang@intel.com> | 16414 | M: Dave Jiang <dave.jiang@intel.com> |
| 16519 | L: ntb@lists.linux.dev | 16415 | L: ntb@lists.linux.dev |
| @@ -16728,7 +16624,7 @@ F: drivers/extcon/extcon-ptn5150.c · 208 unmodified lines | |||
| 16728 | 16624 | ||
| 16729 | NXP SGTL5000 DRIVER | 16625 | NXP SGTL5000 DRIVER |
| 16730 | M: Fabio Estevam <festevam@gmail.com> | 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 | S: Maintained | 16628 | S: Maintained |
| 16733 | F: Documentation/devicetree/bindings/sound/fsl,sgtl5000.yaml | 16629 | F: Documentation/devicetree/bindings/sound/fsl,sgtl5000.yaml |
| 16734 | F: sound/soc/codecs/sgtl5000* | 16630 | F: sound/soc/codecs/sgtl5000* |
| @@ -16752,7 +16648,7 @@ K: "nxp,tda998x" · 17 unmodified lines | |||
| 16752 | 16648 | ||
| 16753 | NXP TFA9879 DRIVER | 16649 | NXP TFA9879 DRIVER |
| 16754 | M: Peter Rosin <peda@axentia.se> | 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 | S: Maintained | 16652 | S: Maintained |
| 16757 | F: Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml | 16653 | F: Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml |
| 16758 | F: sound/soc/codecs/tfa9879* | 16654 | F: sound/soc/codecs/tfa9879* |
| @@ -16764,7 +16660,7 @@ F: drivers/nfc/nxp-nci · 5 unmodified lines | |||
| 16764 | 16660 | ||
| 16765 | NXP/Goodix TFA989X (TFA1) DRIVER | 16661 | NXP/Goodix TFA989X (TFA1) DRIVER |
| 16766 | M: Stephan Gerhold <stephan@gerhold.net> | 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 | S: Maintained | 16664 | S: Maintained |
| 16769 | F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml | 16665 | F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml |
| 16770 | F: sound/soc/codecs/tfa989x.c | 16666 | F: sound/soc/codecs/tfa989x.c |
| @@ -16850,7 +16746,7 @@ F: include/uapi/misc/ocxl.h · 79 unmodified lines | |||
| 16850 | OMAP AUDIO SUPPORT | 16746 | OMAP AUDIO SUPPORT |
| 16851 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | 16747 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> |
| 16852 | M: Jarkko Nikula <jarkko.nikula@bitmer.com> | 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 | L: linux-omap@vger.kernel.org | 16750 | L: linux-omap@vger.kernel.org |
| 16855 | S: Maintained | 16751 | S: Maintained |
| 16856 | F: sound/soc/ti/n810.c | 16752 | F: sound/soc/ti/n810.c |
| @@ -17407,7 +17303,7 @@ F: include/linux/pm_opp.h · 550 unmodified lines | |||
| 17407 | 17303 | ||
| 17408 | OPL4 DRIVER | 17304 | OPL4 DRIVER |
| 17409 | M: Clemens Ladisch <clemens@ladisch.de> | 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 | S: Maintained | 17307 | S: Maintained |
| 17412 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 17308 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 17413 | F: sound/drivers/opl4/ | 17309 | F: sound/drivers/opl4/ |
| @@ -18534,13 +18430,6 @@ F: drivers/pps/ · 1120 unmodified lines | |||
| 18534 | F: include/linux/pps*.h | 18430 | F: include/linux/pps*.h |
| 18535 | F: include/uapi/linux/pps.h | 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 | PRESSURE STALL INFORMATION (PSI) | 18433 | PRESSURE STALL INFORMATION (PSI) |
| 18545 | M: Johannes Weiner <hannes@cmpxchg.org> | 18434 | M: Johannes Weiner <hannes@cmpxchg.org> |
| 18546 | M: Suren Baghdasaryan <surenb@google.com> | 18435 | M: Suren Baghdasaryan <surenb@google.com> |
| @@ -18790,7 +18679,7 @@ F: drivers/crypto/intel/qat/ · 243 unmodified lines | |||
| 18790 | 18679 | ||
| 18791 | QCOM AUDIO (ASoC) DRIVERS | 18680 | QCOM AUDIO (ASoC) DRIVERS |
| 18792 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 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 | L: linux-arm-msm@vger.kernel.org | 18683 | L: linux-arm-msm@vger.kernel.org |
| 18795 | S: Supported | 18684 | S: Supported |
| 18796 | F: Documentation/devicetree/bindings/soc/qcom/qcom,apr* | 18685 | F: Documentation/devicetree/bindings/soc/qcom/qcom,apr* |
| @@ -19514,6 +19403,14 @@ S: Maintained · 717 unmodified lines | |||
| 19514 | F: Documentation/tools/rtla/ | 19403 | F: Documentation/tools/rtla/ |
| 19515 | F: tools/tracing/rtla/ | 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 | REALTEK AUDIO CODECS | 19414 | REALTEK AUDIO CODECS |
| 19518 | M: Oder Chiou <oder_chiou@realtek.com> | 19415 | M: Oder Chiou <oder_chiou@realtek.com> |
| 19519 | S: Maintained | 19416 | S: Maintained |
| @@ -19623,15 +19520,6 @@ S: Supported · 103 unmodified lines | |||
| 19623 | F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml | 19520 | F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml |
| 19624 | F: drivers/i2c/busses/i2c-emev2.c | 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 | RENESAS ETHERNET SWITCH DRIVER | 19523 | RENESAS ETHERNET SWITCH DRIVER |
| 19636 | R: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 19524 | R: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| 19637 | L: netdev@vger.kernel.org | 19525 | L: netdev@vger.kernel.org |
| @@ -19652,7 +19540,7 @@ F: drivers/net/ethernet/renesas/rtsn.* · 14 unmodified lines | |||
| 19652 | 19540 | ||
| 19653 | RENESAS IDT821034 ASoC CODEC | 19541 | RENESAS IDT821034 ASoC CODEC |
| 19654 | M: Herve Codina <herve.codina@bootlin.com> | 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 | S: Maintained | 19544 | S: Maintained |
| 19657 | F: Documentation/devicetree/bindings/sound/renesas,idt821034.yaml | 19545 | F: Documentation/devicetree/bindings/sound/renesas,idt821034.yaml |
| 19658 | F: sound/soc/codecs/idt821034.c | 19546 | F: sound/soc/codecs/idt821034.c |
| @@ -19681,14 +19569,6 @@ F: Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml · 22 unmodified lines | |||
| 19681 | F: drivers/i2c/busses/i2c-rcar.c | 19569 | F: drivers/i2c/busses/i2c-rcar.c |
| 19682 | F: drivers/i2c/busses/i2c-sh_mobile.c | 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 | RENESAS R-CAR THERMAL DRIVERS | 19572 | RENESAS R-CAR THERMAL DRIVERS |
| 19693 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> | 19573 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> |
| 19694 | L: linux-renesas-soc@vger.kernel.org | 19574 | L: linux-renesas-soc@vger.kernel.org |
| @@ -19764,16 +19644,6 @@ S: Supported · 69 unmodified lines | |||
| 19764 | F: Documentation/devicetree/bindings/i2c/renesas,rzv2m.yaml | 19644 | F: Documentation/devicetree/bindings/i2c/renesas,rzv2m.yaml |
| 19765 | F: drivers/i2c/busses/i2c-rzv2m.c | 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 | RENESAS USB PHY DRIVER | 19647 | RENESAS USB PHY DRIVER |
| 19778 | M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 19648 | M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| 19779 | L: linux-renesas-soc@vger.kernel.org | 19649 | L: linux-renesas-soc@vger.kernel.org |
| @@ -20403,7 +20273,7 @@ F: security/safesetid/ · 623 unmodified lines | |||
| 20403 | 20273 | ||
| 20404 | SAMSUNG AUDIO (ASoC) DRIVERS | 20274 | SAMSUNG AUDIO (ASoC) DRIVERS |
| 20405 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> | 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 | S: Maintained | 20277 | S: Maintained |
| 20408 | B: mailto:linux-samsung-soc@vger.kernel.org | 20278 | B: mailto:linux-samsung-soc@vger.kernel.org |
| 20409 | F: Documentation/devicetree/bindings/sound/samsung* | 20279 | F: Documentation/devicetree/bindings/sound/samsung* |
| @@ -20939,7 +20809,7 @@ F: drivers/media/rc/serial_ir.c · 529 unmodified lines | |||
| 20939 | 20809 | ||
| 20940 | SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus) | 20810 | SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus) |
| 20941 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 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 | S: Maintained | 20813 | S: Maintained |
| 20944 | F: Documentation/devicetree/bindings/slimbus/ | 20814 | F: Documentation/devicetree/bindings/slimbus/ |
| 20945 | F: drivers/slimbus/ | 20815 | F: drivers/slimbus/ |
| @@ -21373,7 +21243,7 @@ F: Documentation/devicetree/bindings/i2c/socionext,synquacer-i2c.yaml · 427 unmodified lines | |||
| 21373 | F: drivers/i2c/busses/i2c-synquacer.c | 21243 | F: drivers/i2c/busses/i2c-synquacer.c |
| 21374 | 21244 | ||
| 21375 | SOCIONEXT UNIPHIER SOUND DRIVER | 21245 | SOCIONEXT UNIPHIER SOUND DRIVER |
| 21376 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 21246 | L: linux-sound@vger.kernel.org |
| 21377 | S: Orphan | 21247 | S: Orphan |
| 21378 | F: sound/soc/uniphier/ | 21248 | F: sound/soc/uniphier/ |
| 21379 | 21249 | ||
| @@ -21632,7 +21502,7 @@ F: tools/testing/selftests/alsa · 252 unmodified lines | |||
| 21632 | 21502 | ||
| 21633 | SOUND - COMPRESSED AUDIO | 21503 | SOUND - COMPRESSED AUDIO |
| 21634 | M: Vinod Koul <vkoul@kernel.org> | 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 | S: Supported | 21506 | S: Supported |
| 21637 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 21507 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 21638 | F: Documentation/sound/designs/compress-offload.rst | 21508 | F: Documentation/sound/designs/compress-offload.rst |
| @@ -21695,7 +21565,7 @@ M: Vinod Koul <vkoul@kernel.org> · 56 unmodified lines | |||
| 21695 | M: Bard Liao <yung-chuan.liao@linux.intel.com> | 21565 | M: Bard Liao <yung-chuan.liao@linux.intel.com> |
| 21696 | R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> | 21566 | R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> |
| 21697 | R: Sanyog Kale <sanyog.r.kale@intel.com> | 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 | S: Supported | 21569 | S: Supported |
| 21700 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git | 21570 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git |
| 21701 | F: Documentation/driver-api/soundwire/ | 21571 | F: Documentation/driver-api/soundwire/ |
| @@ -21768,8 +21638,8 @@ F: drivers/accessibility/speakup/ · 66 unmodified lines | |||
| 21768 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT | 21638 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT |
| 21769 | M: Viresh Kumar <vireshk@kernel.org> | 21639 | M: Viresh Kumar <vireshk@kernel.org> |
| 21770 | M: Shiraz Hashim <shiraz.linux.kernel@gmail.com> | 21640 | M: Shiraz Hashim <shiraz.linux.kernel@gmail.com> |
| 21771 | M: soc@kernel.org | ||
| 21772 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 21641 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 21642 | L: soc@lists.linux.dev | ||
| 21773 | S: Maintained | 21643 | S: Maintained |
| 21774 | W: http://www.st.com/spear | 21644 | W: http://www.st.com/spear |
| 21775 | F: arch/arm/boot/dts/st/spear* | 21645 | F: arch/arm/boot/dts/st/spear* |
| @@ -22168,7 +22038,7 @@ F: kernel/static_call.c · 392 unmodified lines | |||
| 22168 | 22038 | ||
| 22169 | STI AUDIO (ASoC) DRIVERS | 22039 | STI AUDIO (ASoC) DRIVERS |
| 22170 | M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> | 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 | S: Maintained | 22042 | S: Maintained |
| 22173 | F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt | 22043 | F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt |
| 22174 | F: sound/soc/sti/ | 22044 | F: sound/soc/sti/ |
| @@ -22189,7 +22059,7 @@ F: drivers/media/usb/stk1160/ · 14 unmodified lines | |||
| 22189 | STM32 AUDIO (ASoC) DRIVERS | 22059 | STM32 AUDIO (ASoC) DRIVERS |
| 22190 | M: Olivier Moysan <olivier.moysan@foss.st.com> | 22060 | M: Olivier Moysan <olivier.moysan@foss.st.com> |
| 22191 | M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> | 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 | S: Maintained | 22063 | S: Maintained |
| 22194 | F: Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml | 22064 | F: Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml |
| 22195 | F: Documentation/devicetree/bindings/sound/st,stm32-*.yaml | 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 | SYNOPSYS DESIGNWARE APB GPIO DRIVER | 22298 | SYNOPSYS DESIGNWARE APB GPIO DRIVER |
| 22429 | M: Hoan Tran <hoan@os.amperecomputing.com> | 22299 | M: Hoan Tran <hoan@os.amperecomputing.com> |
| 22430 | M: Serge Semin <fancer.lancer@gmail.com> | ||
| 22431 | L: linux-gpio@vger.kernel.org | 22300 | L: linux-gpio@vger.kernel.org |
| 22432 | S: Maintained | 22301 | S: Maintained |
| 22433 | F: Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml | 22302 | F: Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml |
| 22434 | F: drivers/gpio/gpio-dwapb.c | 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 | SYNOPSYS DESIGNWARE AXI DMAC DRIVER | 22305 | SYNOPSYS DESIGNWARE AXI DMAC DRIVER |
| 22444 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> | 22306 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
| 22445 | S: Maintained | 22307 | S: Maintained |
| @@ -22892,7 +22754,7 @@ F: drivers/irqchip/irq-xtensa-* · 446 unmodified lines | |||
| 22892 | 22754 | ||
| 22893 | TEXAS INSTRUMENTS ASoC DRIVERS | 22755 | TEXAS INSTRUMENTS ASoC DRIVERS |
| 22894 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | 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 | S: Maintained | 22758 | S: Maintained |
| 22897 | F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml | 22759 | F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml |
| 22898 | F: sound/soc/ti/ | 22760 | F: sound/soc/ti/ |
| @@ -22901,7 +22763,7 @@ TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS · 2 unmodified lines | |||
| 22901 | M: Shenghao Ding <shenghao-ding@ti.com> | 22763 | M: Shenghao Ding <shenghao-ding@ti.com> |
| 22902 | M: Kevin Lu <kevin-lu@ti.com> | 22764 | M: Kevin Lu <kevin-lu@ti.com> |
| 22903 | M: Baojun Xu <baojun.xu@ti.com> | 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 | S: Maintained | 22767 | S: Maintained |
| 22906 | F: Documentation/devicetree/bindings/sound/tas2552.txt | 22768 | F: Documentation/devicetree/bindings/sound/tas2552.txt |
| 22907 | F: Documentation/devicetree/bindings/sound/ti,tas2562.yaml | 22769 | F: Documentation/devicetree/bindings/sound/ti,tas2562.yaml |
| @@ -23269,7 +23131,7 @@ F: drivers/soc/ti/* · 361 unmodified lines | |||
| 23269 | TI LM49xxx FAMILY ASoC CODEC DRIVERS | 23131 | TI LM49xxx FAMILY ASoC CODEC DRIVERS |
| 23270 | M: M R Swami Reddy <mr.swami.reddy@ti.com> | 23132 | M: M R Swami Reddy <mr.swami.reddy@ti.com> |
| 23271 | M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com> | 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 | S: Maintained | 23135 | S: Maintained |
| 23274 | F: sound/soc/codecs/isabelle* | 23136 | F: sound/soc/codecs/isabelle* |
| 23275 | F: sound/soc/codecs/lm49453* | 23137 | F: sound/soc/codecs/lm49453* |
| @@ -23284,14 +23146,14 @@ F: drivers/iio/adc/ti-lmp92064.c · 8 unmodified lines | |||
| 23284 | 23146 | ||
| 23285 | TI PCM3060 ASoC CODEC DRIVER | 23147 | TI PCM3060 ASoC CODEC DRIVER |
| 23286 | M: Kirill Marinushkin <kmarinushkin@birdec.com> | 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 | S: Maintained | 23150 | S: Maintained |
| 23289 | F: Documentation/devicetree/bindings/sound/pcm3060.txt | 23151 | F: Documentation/devicetree/bindings/sound/pcm3060.txt |
| 23290 | F: sound/soc/codecs/pcm3060* | 23152 | F: sound/soc/codecs/pcm3060* |
| 23291 | 23153 | ||
| 23292 | TI TAS571X FAMILY ASoC CODEC DRIVER | 23154 | TI TAS571X FAMILY ASoC CODEC DRIVER |
| 23293 | M: Kevin Cernekee <cernekee@chromium.org> | 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 | S: Odd Fixes | 23157 | S: Odd Fixes |
| 23296 | F: sound/soc/codecs/tas571x* | 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 | TI TWL4030 SERIES SOC CODEC DRIVER | 23182 | TI TWL4030 SERIES SOC CODEC DRIVER |
| 23321 | M: Peter Ujfalusi <peter.ujfalusi@gmail.com> | 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 | S: Maintained | 23185 | S: Maintained |
| 23324 | F: sound/soc/codecs/twl4030* | 23186 | F: sound/soc/codecs/twl4030* |
| 23325 | 23187 | ||
| @@ -23749,12 +23611,6 @@ L: linux-input@vger.kernel.org · 423 unmodified lines | |||
| 23749 | S: Maintained | 23611 | S: Maintained |
| 23750 | F: drivers/hid/hid-udraw-ps3.c | 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 | UHID USERSPACE HID IO DRIVER | 23614 | UHID USERSPACE HID IO DRIVER |
| 23759 | M: David Rheinsberg <david@readahead.eu> | 23615 | M: David Rheinsberg <david@readahead.eu> |
| 23760 | L: linux-input@vger.kernel.org | 23616 | L: linux-input@vger.kernel.org |
| @@ -23995,7 +23851,7 @@ F: drivers/usb/storage/ · 234 unmodified lines | |||
| 23995 | 23851 | ||
| 23996 | USB MIDI DRIVER | 23852 | USB MIDI DRIVER |
| 23997 | M: Clemens Ladisch <clemens@ladisch.de> | 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 | S: Maintained | 23855 | S: Maintained |
| 24000 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 23856 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 24001 | F: sound/usb/midi.* | 23857 | F: sound/usb/midi.* |
| @@ -24057,6 +23913,7 @@ USB RAW GADGET DRIVER · 55 unmodified lines | |||
| 24057 | R: Andrey Konovalov <andreyknvl@gmail.com> | 23913 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 24058 | L: linux-usb@vger.kernel.org | 23914 | L: linux-usb@vger.kernel.org |
| 24059 | S: Maintained | 23915 | S: Maintained |
| 23916 | B: https://github.com/xairy/raw-gadget/issues | ||
| 24060 | F: Documentation/usb/raw-gadget.rst | 23917 | F: Documentation/usb/raw-gadget.rst |
| 24061 | F: drivers/usb/gadget/legacy/raw_gadget.c | 23918 | F: drivers/usb/gadget/legacy/raw_gadget.c |
| 24062 | F: include/uapi/linux/usb/raw_gadget.h | 23919 | F: include/uapi/linux/usb/raw_gadget.h |
| @@ -24173,8 +24030,12 @@ F: drivers/usb/host/xhci* · 110 unmodified lines | |||
| 24173 | 24030 | ||
| 24174 | USER DATAGRAM PROTOCOL (UDP) | 24031 | USER DATAGRAM PROTOCOL (UDP) |
| 24175 | M: Willem de Bruijn <willemdebruijn.kernel@gmail.com> | 24032 | M: Willem de Bruijn <willemdebruijn.kernel@gmail.com> |
| 24033 | L: netdev@vger.kernel.org | ||
| 24176 | S: Maintained | 24034 | S: Maintained |
| 24177 | F: include/linux/udp.h | 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 | F: net/ipv4/udp.c | 24039 | F: net/ipv4/udp.c |
| 24179 | F: net/ipv6/udp.c | 24040 | F: net/ipv6/udp.c |
| 24180 | 24041 | ||
| @@ -24655,7 +24516,7 @@ VIRTIO SOUND DRIVER · 474 unmodified lines | |||
| 24655 | M: Anton Yakovlev <anton.yakovlev@opensynergy.com> | 24516 | M: Anton Yakovlev <anton.yakovlev@opensynergy.com> |
| 24656 | M: "Michael S. Tsirkin" <mst@redhat.com> | 24517 | M: "Michael S. Tsirkin" <mst@redhat.com> |
| 24657 | L: virtualization@lists.linux.dev | 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 | S: Maintained | 24520 | S: Maintained |
| 24660 | F: include/uapi/linux/virtio_snd.h | 24521 | F: include/uapi/linux/virtio_snd.h |
| 24661 | F: sound/virtio/* | 24522 | F: sound/virtio/* |
| @@ -24724,9 +24585,10 @@ F: tools/testing/vsock/ · 62 unmodified lines | |||
| 24724 | 24585 | ||
| 24725 | VMA | 24586 | VMA |
| 24726 | M: Andrew Morton <akpm@linux-foundation.org> | 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 | R: Vlastimil Babka <vbabka@suse.cz> | 24590 | R: Vlastimil Babka <vbabka@suse.cz> |
| 24729 | R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | 24591 | R: Jann Horn <jannh@google.com> |
| 24730 | L: linux-mm@kvack.org | 24592 | L: linux-mm@kvack.org |
| 24731 | S: Maintained | 24593 | S: Maintained |
| 24732 | W: https://www.linux-mm.org | 24594 | W: https://www.linux-mm.org |
| @@ -25384,7 +25246,7 @@ F: include/xen/interface/io/usbif.h · 651 unmodified lines | |||
| 25384 | XEN SOUND FRONTEND DRIVER | 25246 | XEN SOUND FRONTEND DRIVER |
| 25385 | M: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> | 25247 | M: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> |
| 25386 | L: xen-devel@lists.xenproject.org (moderated for non-subscribers) | 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 | S: Supported | 25250 | S: Supported |
| 25389 | F: sound/xen/* | 25251 | F: sound/xen/* |
| 25390 | 25252 | ||
| @@ -25400,7 +25262,7 @@ F: include/xen/arm/swiotlb-xen.h · 9 unmodified lines | |||
| 25400 | F: include/xen/swiotlb-xen.h | 25262 | F: include/xen/swiotlb-xen.h |
| 25401 | 25263 | ||
| 25402 | XFS FILESYSTEM | 25264 | XFS FILESYSTEM |
| 25403 | M: Chandan Babu R <chandan.babu@oracle.com> | 25265 | M: Carlos Maiolino <cem@kernel.org> |
| 25404 | R: Darrick J. Wong <djwong@kernel.org> | 25266 | R: Darrick J. Wong <djwong@kernel.org> |
| 25405 | L: linux-xfs@vger.kernel.org | 25267 | L: linux-xfs@vger.kernel.org |
| 25406 | S: Supported | 25268 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 6 | 2 | VERSION = 6 |
| 3 | PATCHLEVEL = 12 | 3 | PATCHLEVEL = 12 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc1 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Baby Opossum Posse | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -1645,7 +1645,7 @@ help: · 1636 unmodified lines | |||
| 1645 | echo '* dtbs - Build device tree blobs for enabled boards'; \ | 1645 | echo '* dtbs - Build device tree blobs for enabled boards'; \ |
| 1646 | echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)'; \ | 1646 | echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)'; \ |
| 1647 | echo ' dt_binding_check - Validate device tree binding documents and examples'; \ | 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 | echo ' dtbs_check - Validate device tree source files';\ | 1649 | echo ' dtbs_check - Validate device tree source files';\ |
| 1650 | echo '') | 1650 | echo '') |
| 1651 | 1651 | ||
| @@ -838,7 +838,7 @@ config CFI_CLANG · 837 unmodified lines | |||
| 838 | config CFI_ICALL_NORMALIZE_INTEGERS | 838 | config CFI_ICALL_NORMALIZE_INTEGERS |
| 839 | bool "Normalize CFI tags for integers" | 839 | bool "Normalize CFI tags for integers" |
| 840 | depends on CFI_CLANG | 840 | depends on CFI_CLANG |
| 841 | depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS | 841 | depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG |
| 842 | help | 842 | help |
| 843 | This option normalizes the CFI tags for integer types so that all | 843 | This option normalizes the CFI tags for integer types so that all |
| 844 | integer types of the same size and signedness receive the same CFI | 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 | This option is necessary for using CFI with Rust. If unsure, say N. | 852 | This option is necessary for using CFI with Rust. If unsure, say N. |
| 853 | 853 | ||
| 854 | config HAVE_CFI_ICALL_NORMALIZE_INTEGERS | 854 | config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG |
| 855 | def_bool !GCOV_KERNEL && !KASAN | 855 | def_bool y |
| 856 | depends on CFI_CLANG | ||
| 857 | depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) | 856 | depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) |
| 858 | help | 857 | # With GCOV/KASAN we need this fix: https://github.com/llvm/llvm-project/pull/104826 |
| 859 | Is CFI_ICALL_NORMALIZE_INTEGERS supported with the set of compilers | 858 | depends on CLANG_VERSION >= 190000 || (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS) |
| 860 | currently in use? | ||
| 861 | 859 | ||
| 862 | This option defaults to false if GCOV or KASAN is enabled, as there is | 860 | config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC |
| 863 | an LLVM bug that makes normalized integers tags incompatible with | 861 | def_bool y |
| 864 | KASAN and GCOV. Kconfig currently does not have the infrastructure to | 862 | depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG |
| 865 | detect whether your rustc compiler contains the fix for this bug, so | 863 | depends on RUSTC_VERSION >= 107900 |
| 866 | it is assumed that it doesn't. If your compiler has the fix, you can | 864 | # With GCOV/KASAN we need this fix: https://github.com/rust-lang/rust/pull/129373 |
| 867 | explicitly enable this option in your config file. The Kconfig logic | 865 | depends on (RUSTC_LLVM_VERSION >= 190000 && RUSTC_VERSION >= 108200) || \ |
| 868 | needed to detect this will be added in a future kernel release. | 866 | (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS) |
| 869 | 867 | ||
| 870 | config CFI_PERMISSIVE | 868 | config CFI_PERMISSIVE |
| 871 | bool "Use CFI in permissive mode" | 869 | bool "Use CFI in permissive mode" |
| @@ -77,7 +77,7 @@ · 76 unmodified lines | |||
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | &hdmi { | 79 | &hdmi { |
| 80 | hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; | 80 | hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>; |
| 81 | power-domains = <&power RPI_POWER_DOMAIN_HDMI>; | 81 | power-domains = <&power RPI_POWER_DOMAIN_HDMI>; |
| 82 | status = "okay"; | 82 | status = "okay"; |
| 83 | }; | 83 | }; |
| @@ -200,7 +200,8 @@ config ARM64 · 199 unmodified lines | |||
| 200 | select HAVE_DMA_CONTIGUOUS | 200 | select HAVE_DMA_CONTIGUOUS |
| 201 | select HAVE_DYNAMIC_FTRACE | 201 | select HAVE_DYNAMIC_FTRACE |
| 202 | select HAVE_DYNAMIC_FTRACE_WITH_ARGS \ | 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 | select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \ | 205 | select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \ |
| 205 | if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS | 206 | if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS |
| 206 | select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \ | 207 | select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \ |
| @@ -286,12 +287,10 @@ config CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS · 79 unmodified lines | |||
| 286 | def_bool CC_IS_CLANG | 287 | def_bool CC_IS_CLANG |
| 287 | # https://github.com/ClangBuiltLinux/linux/issues/1507 | 288 | # https://github.com/ClangBuiltLinux/linux/issues/1507 |
| 288 | depends on AS_IS_GNU || (AS_IS_LLVM && (LD_IS_LLD || LD_VERSION >= 23600)) | 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 | config GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS | 291 | config GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS |
| 292 | def_bool CC_IS_GCC | 292 | def_bool CC_IS_GCC |
| 293 | depends on $(cc-option,-fpatchable-function-entry=2) | 293 | depends on $(cc-option,-fpatchable-function-entry=2) |
| 294 | select HAVE_DYNAMIC_FTRACE_WITH_ARGS | ||
| 295 | 294 | ||
| 296 | config 64BIT | 295 | config 64BIT |
| 297 | def_bool y | 296 | def_bool y |
| @@ -1097,6 +1096,7 @@ config ARM64_ERRATUM_3194386 · 799 unmodified lines | |||
| 1097 | * ARM Cortex-A78C erratum 3324346 | 1096 | * ARM Cortex-A78C erratum 3324346 |
| 1098 | * ARM Cortex-A78C erratum 3324347 | 1097 | * ARM Cortex-A78C erratum 3324347 |
| 1099 | * ARM Cortex-A710 erratam 3324338 | 1098 | * ARM Cortex-A710 erratam 3324338 |
| 1099 | * ARM Cortex-A715 errartum 3456084 | ||
| 1100 | * ARM Cortex-A720 erratum 3456091 | 1100 | * ARM Cortex-A720 erratum 3456091 |
| 1101 | * ARM Cortex-A725 erratum 3456106 | 1101 | * ARM Cortex-A725 erratum 3456106 |
| 1102 | * ARM Cortex-X1 erratum 3324344 | 1102 | * ARM Cortex-X1 erratum 3324344 |
| @@ -1107,6 +1107,7 @@ config ARM64_ERRATUM_3194386 · 4 unmodified lines | |||
| 1107 | * ARM Cortex-X925 erratum 3324334 | 1107 | * ARM Cortex-X925 erratum 3324334 |
| 1108 | * ARM Neoverse-N1 erratum 3324349 | 1108 | * ARM Neoverse-N1 erratum 3324349 |
| 1109 | * ARM Neoverse N2 erratum 3324339 | 1109 | * ARM Neoverse N2 erratum 3324339 |
| 1110 | * ARM Neoverse-N3 erratum 3456111 | ||
| 1110 | * ARM Neoverse-V1 erratum 3324341 | 1111 | * ARM Neoverse-V1 erratum 3324341 |
| 1111 | * ARM Neoverse V2 erratum 3324336 | 1112 | * ARM Neoverse V2 erratum 3324336 |
| 1112 | * ARM Neoverse-V3 erratum 3312417 | 1113 | * ARM Neoverse-V3 erratum 3312417 |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | # | 10 | # |
| 11 | # Copyright (C) 1995-2001 by Russell King | 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 | ifeq ($(CONFIG_RELOCATABLE), y) | 15 | ifeq ($(CONFIG_RELOCATABLE), y) |
| 16 | # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour | 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 | cp0_mdio_pins: cp0-mdio-pins { | 138 | cp0_mdio_pins: cp0-mdio-pins { |
| 139 | marvell,pins = "mpp40", "mpp41"; | 139 | marvell,pins = "mpp0", "mpp1"; |
| 140 | marvell,function = "ge"; | 140 | marvell,function = "ge"; |
| 141 | }; | 141 | }; |
| 142 | 142 | ||
| @@ -94,6 +94,7 @@ · 93 unmodified lines | |||
| 94 | #define ARM_CPU_PART_NEOVERSE_V3 0xD84 | 94 | #define ARM_CPU_PART_NEOVERSE_V3 0xD84 |
| 95 | #define ARM_CPU_PART_CORTEX_X925 0xD85 | 95 | #define ARM_CPU_PART_CORTEX_X925 0xD85 |
| 96 | #define ARM_CPU_PART_CORTEX_A725 0xD87 | 96 | #define ARM_CPU_PART_CORTEX_A725 0xD87 |
| 97 | #define ARM_CPU_PART_NEOVERSE_N3 0xD8E | ||
| 97 | 98 | ||
| 98 | #define APM_CPU_PART_XGENE 0x000 | 99 | #define APM_CPU_PART_XGENE 0x000 |
| 99 | #define APM_CPU_VAR_POTENZA 0x00 | 100 | #define APM_CPU_VAR_POTENZA 0x00 |
| @@ -176,6 +177,7 @@ · 76 unmodified lines | |||
| 176 | #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) | 177 | #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) |
| 177 | #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) | 178 | #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) |
| 178 | #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) | 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 | #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) | 181 | #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) |
| 180 | #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) | 182 | #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) |
| 181 | #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) | 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 | unsigned long hcr_el2; | 178 | unsigned long hcr_el2; |
| 179 | unsigned long vttbr; | 179 | unsigned long vttbr; |
| 180 | unsigned long vtcr; | 180 | unsigned long vtcr; |
| 181 | unsigned long tmp; | ||
| 181 | }; | 182 | }; |
| 182 | 183 | ||
| 183 | /* | 184 | /* |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | |||
| 51 | #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) | 51 | #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) |
| 52 | #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6) | 52 | #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6) |
| 53 | #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7) | 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 | #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ | 56 | #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ |
| 56 | KVM_DIRTY_LOG_INITIALLY_SET) | 57 | KVM_DIRTY_LOG_INITIALLY_SET) |
| @@ -211,6 +212,12 @@ struct kvm_s2_mmu { · 154 unmodified lines | |||
| 211 | */ | 212 | */ |
| 212 | bool nested_stage2_enabled; | 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 | * 0: Nobody is currently using this, check vttbr for validity | 222 | * 0: Nobody is currently using this, check vttbr for validity |
| 216 | * >0: Somebody is actively using this. | 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 | sign_extend64(__val, id##_##fld##_WIDTH - 1); \ | 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 | #define get_idreg_field_unsigned(kvm, id, fld) \ | 1451 | #define get_idreg_field_unsigned(kvm, id, fld) \ |
| 1450 | ({ \ | 1452 | ({ \ |
| 1451 | u64 __val = kvm_read_vm_id_reg((kvm), SYS_##id); \ | 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 | #define get_idreg_field_enum(kvm, id, fld) \ | 1463 | #define get_idreg_field_enum(kvm, id, fld) \ |
| 1462 | get_idreg_field_unsigned(kvm, id, fld) | 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 | (id##_##fld##_SIGNED ? \ | 1473 | (id##_##fld##_SIGNED ? \ |
| 1466 | get_idreg_field_signed(kvm, id, fld) : \ | 1474 | kvm_cmp_feat_signed(kvm, id, fld, op, limit) : \ |
| 1467 | get_idreg_field_unsigned(kvm, id, fld)) | 1475 | kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)) |
| 1468 | 1476 | ||
| 1469 | #define kvm_has_feat(kvm, id, fld, limit) \ | 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 | #define kvm_has_feat_enum(kvm, id, fld, val) \ | 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 | #define kvm_has_feat_range(kvm, id, fld, min, max) \ | 1483 | #define kvm_has_feat_range(kvm, id, fld, min, max) \ |
| 1476 | (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \ | 1484 | (kvm_cmp_feat(kvm, id, fld, >=, min) && \ |
| 1477 | get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max)) | 1485 | kvm_cmp_feat(kvm, id, fld, <=, max)) |
| 1478 | 1486 | ||
| 1479 | /* Check for a given level of PAuth support */ | 1487 | /* Check for a given level of PAuth support */ |
| 1480 | #define kvm_has_pauth(k, l) \ | 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 | int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr); | 166 | int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr); |
| 167 | void __init free_hyp_pgds(void); | 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 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); | 171 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); |
| 171 | void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); | 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 | extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu); | 78 | extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu); |
| 79 | extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu); | 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 | struct kvm_s2_trans { | 83 | struct kvm_s2_trans { |
| 82 | phys_addr_t output; | 84 | phys_addr_t output; |
| 83 | unsigned long block_size; | 85 | unsigned long block_size; |
| @@ -124,7 +126,7 @@ extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, · 40 unmodified lines | |||
| 124 | struct kvm_s2_trans *trans); | 126 | struct kvm_s2_trans *trans); |
| 125 | extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2); | 127 | extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2); |
| 126 | extern void kvm_nested_s2_wp(struct kvm *kvm); | 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 | extern void kvm_nested_s2_flush(struct kvm *kvm); | 130 | extern void kvm_nested_s2_flush(struct kvm *kvm); |
| 129 | 131 | ||
| 130 | unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val); | 132 | unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val); |
| @@ -10,11 +10,9 @@ · 9 unmodified lines | |||
| 10 | #include <asm/insn.h> | 10 | #include <asm/insn.h> |
| 11 | #include <asm/probes.h> | 11 | #include <asm/probes.h> |
| 12 | 12 | ||
| 13 | #define MAX_UINSN_BYTES AARCH64_INSN_SIZE | ||
| 14 | |||
| 15 | #define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES) | 13 | #define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES) |
| 16 | #define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE | 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 | typedef __le32 uprobe_opcode_t; | 17 | typedef __le32 uprobe_opcode_t; |
| 20 | 18 | ||
| @@ -23,8 +21,8 @@ struct arch_uprobe_task { · 2 unmodified lines | |||
| 23 | 21 | ||
| 24 | struct arch_uprobe { | 22 | struct arch_uprobe { |
| 25 | union { | 23 | union { |
| 26 | u8 insn[MAX_UINSN_BYTES]; | 24 | __le32 insn; |
| 27 | u8 ixol[MAX_UINSN_BYTES]; | 25 | __le32 ixol; |
| 28 | }; | 26 | }; |
| 29 | struct arch_probe_insn api; | 27 | struct arch_probe_insn api; |
| 30 | bool simulate; | 28 | bool simulate; |
| @@ -146,6 +146,7 @@ int main(void) · 145 unmodified lines | |||
| 146 | DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2)); | 146 | DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2)); |
| 147 | DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr)); | 147 | DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr)); |
| 148 | DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr)); | 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 | #endif | 150 | #endif |
| 150 | #ifdef CONFIG_CPU_PM | 151 | #ifdef CONFIG_CPU_PM |
| 151 | DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp)); | 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 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), | 439 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), |
| 440 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), | 440 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), |
| 441 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), | 441 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), |
| 442 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), | ||
| 442 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), | 443 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), |
| 443 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), | 444 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), |
| 444 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), | 445 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), |
| @@ -447,8 +448,10 @@ static const struct midr_range erratum_spec_ssbs_list[] = { · 2 unmodified lines | |||
| 447 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), | 448 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), |
| 448 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), | 449 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), |
| 449 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), | 450 | MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), |
| 451 | MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100), | ||
| 450 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), | 452 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), |
| 451 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), | 453 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), |
| 454 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3), | ||
| 452 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), | 455 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), |
| 453 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), | 456 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), |
| 454 | MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), | 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 | aarch64_insn_is_blr(insn) || | 99 | aarch64_insn_is_blr(insn) || |
| 100 | aarch64_insn_is_ret(insn)) { | 100 | aarch64_insn_is_ret(insn)) { |
| 101 | api->handler = simulate_br_blr_ret; | 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 | } else { | 102 | } else { |
| 107 | /* | 103 | /* |
| 108 | * Instruction cannot be stepped out-of-line and we don't | 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 | probe_opcode_t insn = le32_to_cpu(*addr); | 136 | probe_opcode_t insn = le32_to_cpu(*addr); |
| 141 | probe_opcode_t *scan_end = NULL; | 137 | probe_opcode_t *scan_end = NULL; |
| 142 | unsigned long size = 0, offset = 0; | 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 | * If there's a symbol defined in front of and near enough to | 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 | else | 164 | else |
| 158 | scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; | 165 | scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; |
| 159 | } | 166 | } |
| 160 | decoded = arm_probe_decode_insn(insn, &asi->api); | ||
| 161 | 167 | ||
| 162 | if (decoded != INSN_REJECTED && scan_end) | 168 | if (decoded != INSN_REJECTED && scan_end) |
| 163 | if (is_probed_address_atomic(addr - 1, scan_end)) | 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 | void __kprobes | 171 | void __kprobes |
| 172 | simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) | 172 | simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) |
| 173 | { | 173 | { |
| 174 | u64 *load_addr; | 174 | unsigned long load_addr; |
| 175 | int xn = opcode & 0x1f; | 175 | int xn = opcode & 0x1f; |
| 176 | int disp; | ||
| 177 | 176 | ||
| 178 | disp = ldr_displacement(opcode); | 177 | load_addr = addr + ldr_displacement(opcode); |
| 179 | load_addr = (u64 *) (addr + disp); | ||
| 180 | 178 | ||
| 181 | if (opcode & (1 << 30)) /* x0-x30 */ | 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 | else /* w0-w30 */ | 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 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); | 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 | void __kprobes | 187 | void __kprobes |
| 190 | simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) | 188 | simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) |
| 191 | { | 189 | { |
| 192 | s32 *load_addr; | 190 | unsigned long load_addr; |
| 193 | int xn = opcode & 0x1f; | 191 | int xn = opcode & 0x1f; |
| 194 | int disp; | ||
| 195 | 192 | ||
| 196 | disp = ldr_displacement(opcode); | 193 | load_addr = addr + ldr_displacement(opcode); |
| 197 | load_addr = (s32 *) (addr + disp); | ||
| 198 | 194 | ||
| 199 | set_x_reg(regs, xn, *load_addr); | 195 | set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr)); |
| 200 | 196 | ||
| 201 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); | 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 | else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) | 42 | else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) |
| 43 | return -EINVAL; | 43 | return -EINVAL; |
| 44 | 44 | ||
| 45 | insn = *(probe_opcode_t *)(&auprobe->insn[0]); | 45 | insn = le32_to_cpu(auprobe->insn); |
| 46 | 46 | ||
| 47 | switch (arm_probe_decode_insn(insn, &auprobe->api)) { | 47 | switch (arm_probe_decode_insn(insn, &auprobe->api)) { |
| 48 | case INSN_REJECTED: | 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 | if (!auprobe->simulate) | 108 | if (!auprobe->simulate) |
| 109 | return false; | 109 | return false; |
| 110 | 110 | ||
| 111 | insn = *(probe_opcode_t *)(&auprobe->insn[0]); | 111 | insn = le32_to_cpu(auprobe->insn); |
| 112 | addr = instruction_pointer(regs); | 112 | addr = instruction_pointer(regs); |
| 113 | 113 | ||
| 114 | if (auprobe->api.handler) | 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 | p->thread.cpu_context.x19 = (unsigned long)args->fn; | 413 | p->thread.cpu_context.x19 = (unsigned long)args->fn; |
| 414 | p->thread.cpu_context.x20 = (unsigned long)args->fn_arg; | 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 | p->thread.cpu_context.pc = (unsigned long)ret_from_fork; | 419 | p->thread.cpu_context.pc = (unsigned long)ret_from_fork; |
| 417 | p->thread.cpu_context.sp = (unsigned long)childregs; | 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 | static int check_vcpu_requests(struct kvm_vcpu *vcpu) | 997 | static int check_vcpu_requests(struct kvm_vcpu *vcpu) |
| 998 | { | 998 | { |
| 999 | if (kvm_request_pending(vcpu)) { | 999 | if (kvm_request_pending(vcpu)) { |
| 1000 | if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu)) | ||
| 1001 | return -EIO; | ||
| 1002 | |||
| 1000 | if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) | 1003 | if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) |
| 1001 | kvm_vcpu_sleep(vcpu); | 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 | if (kvm_dirty_ring_check_request(vcpu)) | 1035 | if (kvm_dirty_ring_check_request(vcpu)) |
| 1033 | return 0; | 1036 | return 0; |
| 1037 | |||
| 1038 | check_nested_vcpu_requests(vcpu); | ||
| 1034 | } | 1039 | } |
| 1035 | 1040 | ||
| 1036 | return 1; | 1041 | return 1; |
| @@ -338,7 +338,7 @@ static inline void __hyp_sve_save_host(void) · 337 unmodified lines | |||
| 338 | struct cpu_sve_state *sve_state = *host_data_ptr(sve_state); | 338 | struct cpu_sve_state *sve_state = *host_data_ptr(sve_state); |
| 339 | 339 | ||
| 340 | sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR); | 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 | __sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), | 342 | __sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), |
| 343 | &sve_state->fpsr, | 343 | &sve_state->fpsr, |
| 344 | true); | 344 | true); |
| @@ -24,28 +24,25 @@ · 23 unmodified lines | |||
| 24 | .align 11 | 24 | .align 11 |
| 25 | 25 | ||
| 26 | SYM_CODE_START(__kvm_hyp_init) | 26 | SYM_CODE_START(__kvm_hyp_init) |
| 27 | ventry __invalid // Synchronous EL2t | 27 | ventry . // Synchronous EL2t |
| 28 | ventry __invalid // IRQ EL2t | 28 | ventry . // IRQ EL2t |
| 29 | ventry __invalid // FIQ EL2t | 29 | ventry . // FIQ EL2t |
| 30 | ventry __invalid // Error EL2t | 30 | ventry . // Error EL2t |
| 31 | 31 | ||
| 32 | ventry __invalid // Synchronous EL2h | 32 | ventry . // Synchronous EL2h |
| 33 | ventry __invalid // IRQ EL2h | 33 | ventry . // IRQ EL2h |
| 34 | ventry __invalid // FIQ EL2h | 34 | ventry . // FIQ EL2h |
| 35 | ventry __invalid // Error EL2h | 35 | ventry . // Error EL2h |
| 36 | 36 | ||
| 37 | ventry __do_hyp_init // Synchronous 64-bit EL1 | 37 | ventry __do_hyp_init // Synchronous 64-bit EL1 |
| 38 | ventry __invalid // IRQ 64-bit EL1 | 38 | ventry . // IRQ 64-bit EL1 |
| 39 | ventry __invalid // FIQ 64-bit EL1 | 39 | ventry . // FIQ 64-bit EL1 |
| 40 | ventry __invalid // Error 64-bit EL1 | 40 | ventry . // Error 64-bit EL1 |
| 41 | 41 | ||
| 42 | ventry __invalid // Synchronous 32-bit EL1 | 42 | ventry . // Synchronous 32-bit EL1 |
| 43 | ventry __invalid // IRQ 32-bit EL1 | 43 | ventry . // IRQ 32-bit EL1 |
| 44 | ventry __invalid // FIQ 32-bit EL1 | 44 | ventry . // FIQ 32-bit EL1 |
| 45 | ventry __invalid // Error 32-bit EL1 | 45 | ventry . // Error 32-bit EL1 |
| 46 | |||
| 47 | __invalid: | ||
| 48 | b . | ||
| 49 | 46 | ||
| 50 | /* | 47 | /* |
| 51 | * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers. | 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 | eret | 73 | eret |
| 77 | SYM_CODE_END(__kvm_hyp_init) | 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 | * Initialize the hypervisor in EL2. | 84 | * Initialize the hypervisor in EL2. |
| 81 | * | 85 | * |
| @@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init) · 20 unmodified lines | |||
| 102 | // TPIDR_EL2 is used to preserve x0 across the macro maze... | 106 | // TPIDR_EL2 is used to preserve x0 across the macro maze... |
| 103 | isb | 107 | isb |
| 104 | msr tpidr_el2, x0 | 108 | msr tpidr_el2, x0 |
| 105 | init_el2_state | 109 | str lr, [x0, #NVHE_INIT_TMP] |
| 106 | finalise_el2_state | 110 | |
| 111 | bl __kvm_init_el2_state | ||
| 112 | |||
| 107 | mrs x0, tpidr_el2 | 113 | mrs x0, tpidr_el2 |
| 114 | ldr lr, [x0, #NVHE_INIT_TMP] | ||
| 108 | 115 | ||
| 109 | 1: | 116 | 1: |
| 110 | ldr x1, [x0, #NVHE_INIT_TPIDR_EL2] | 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 | 2: msr SPsel, #1 // We want to use SP_EL{1,2} | 207 | 2: msr SPsel, #1 // We want to use SP_EL{1,2} |
| 201 | 208 | ||
| 202 | /* Initialize EL2 CPU state to sane values. */ | 209 | bl __kvm_init_el2_state |
| 203 | init_el2_state // Clobbers x0..x2 | 210 | |
| 204 | finalise_el2_state | ||
| 205 | __init_el2_nvhe_prepare_eret | 211 | __init_el2_nvhe_prepare_eret |
| 206 | 212 | ||
| 207 | /* Enable MMU, set vectors and stack. */ | 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 | sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2); | 34 | sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2); |
| 35 | __sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true); | 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 | static void __hyp_sve_restore_host(void) | 39 | static void __hyp_sve_restore_host(void) |
| @@ -45,10 +45,11 @@ static void __hyp_sve_restore_host(void) · 5 unmodified lines | |||
| 45 | * the host. The layout of the data when saving the sve state depends | 45 | * the host. The layout of the data when saving the sve state depends |
| 46 | * on the VL, so use a consistent (i.e., the maximum) host VL. | 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 | 48 | * Note that this constrains the PE to the maximum shared VL |
| 49 | * supported by the system (or limited at EL3). | 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 | __sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), | 53 | __sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), |
| 53 | &sve_state->fpsr, | 54 | &sve_state->fpsr, |
| 54 | true); | 55 | true); |
| @@ -488,7 +489,8 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) · 433 unmodified lines | |||
| 488 | case ESR_ELx_EC_SVE: | 489 | case ESR_ELx_EC_SVE: |
| 489 | cpacr_clear_set(0, CPACR_ELx_ZEN); | 490 | cpacr_clear_set(0, CPACR_ELx_ZEN); |
| 490 | isb(); | 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 | break; | 494 | break; |
| 493 | case ESR_ELx_EC_IABT_LOW: | 495 | case ESR_ELx_EC_IABT_LOW: |
| 494 | case ESR_ELx_EC_DABT_LOW: | 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 | unlock: | 574 | unlock: |
| 575 | hyp_spin_unlock(&vm_table_lock); | 575 | hyp_spin_unlock(&vm_table_lock); |
| 576 | 576 | ||
| 577 | if (ret) | 577 | if (ret) { |
| 578 | unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu)); | 578 | unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu)); |
| 579 | return ret; | ||
| 580 | } | ||
| 579 | 581 | ||
| 580 | hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu); | 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 | static void | 587 | static void |
| @@ -317,7 +317,7 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu) · 316 unmodified lines | |||
| 317 | * to the guest, and hide SSBS so that the | 317 | * to the guest, and hide SSBS so that the |
| 318 | * guest stays protected. | 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 | break; | 321 | break; |
| 322 | fallthrough; | 322 | fallthrough; |
| 323 | case SPECTRE_UNAFFECTED: | 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 | * Convert the workaround level into an easy-to-compare number, where higher | 428 | * Convert the workaround level into an easy-to-compare number, where higher |
| 429 | * values mean better protection. | 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 | switch (regid) { | 433 | switch (regid) { |
| 434 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: | 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 | * don't have any FW mitigation if SSBS is there at | 449 | * don't have any FW mitigation if SSBS is there at |
| 450 | * all times. | 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 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; | 453 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; |
| 454 | fallthrough; | 454 | fallthrough; |
| 455 | case SPECTRE_UNAFFECTED: | 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 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: | 486 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: |
| 487 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: | 487 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: |
| 488 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: | 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 | break; | 490 | break; |
| 491 | case KVM_REG_ARM_STD_BMAP: | 491 | case KVM_REG_ARM_STD_BMAP: |
| 492 | val = READ_ONCE(smccc_feat->std_bmap); | 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 | if (val & ~KVM_REG_FEATURE_LEVEL_MASK) | 588 | if (val & ~KVM_REG_FEATURE_LEVEL_MASK) |
| 589 | return -EINVAL; | 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 | return -EINVAL; | 592 | return -EINVAL; |
| 593 | 593 | ||
| 594 | return 0; | 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 | * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the | 624 | * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the |
| 625 | * other way around. | 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 | return -EINVAL; | 628 | return -EINVAL; |
| 629 | 629 | ||
| 630 | return 0; | 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 | may_block)); | 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 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end) | 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 | if (!(vma->vm_flags & VM_PFNMAP)) { | 1017 | if (!(vma->vm_flags & VM_PFNMAP)) { |
| 1017 | gpa_t gpa = addr + (vm_start - memslot->userspace_addr); | 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 | hva = vm_end; | 1021 | hva = vm_end; |
| 1021 | } while (hva < reg_end); | 1022 | } while (hva < reg_end); |
| @@ -1042,7 +1043,7 @@ void stage2_unmap_vm(struct kvm *kvm) · 20 unmodified lines | |||
| 1042 | kvm_for_each_memslot(memslot, bkt, slots) | 1043 | kvm_for_each_memslot(memslot, bkt, slots) |
| 1043 | stage2_unmap_memslot(kvm, memslot); | 1044 | stage2_unmap_memslot(kvm, memslot); |
| 1044 | 1045 | ||
| 1045 | kvm_nested_s2_unmap(kvm); | 1046 | kvm_nested_s2_unmap(kvm, true); |
| 1046 | 1047 | ||
| 1047 | write_unlock(&kvm->mmu_lock); | 1048 | write_unlock(&kvm->mmu_lock); |
| 1048 | mmap_read_unlock(current->mm); | 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 | (range->end - range->start) << PAGE_SHIFT, | 1913 | (range->end - range->start) << PAGE_SHIFT, |
| 1913 | range->may_block); | 1914 | range->may_block); |
| 1914 | 1915 | ||
| 1915 | kvm_nested_s2_unmap(kvm); | 1916 | kvm_nested_s2_unmap(kvm, range->may_block); |
| 1916 | return false; | 1917 | return false; |
| 1917 | } | 1918 | } |
| 1918 | 1919 | ||
| @@ -2179,8 +2180,8 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, · 260 unmodified lines | |||
| 2179 | phys_addr_t size = slot->npages << PAGE_SHIFT; | 2180 | phys_addr_t size = slot->npages << PAGE_SHIFT; |
| 2180 | 2181 | ||
| 2181 | write_lock(&kvm->mmu_lock); | 2182 | write_lock(&kvm->mmu_lock); |
| 2182 | kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size); | 2183 | kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size, true); |
| 2183 | kvm_nested_s2_unmap(kvm); | 2184 | kvm_nested_s2_unmap(kvm, true); |
| 2184 | write_unlock(&kvm->mmu_lock); | 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 | /* Set the scene for the next search */ | 632 | /* Set the scene for the next search */ |
| 633 | kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size; | 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 | if (kvm_s2_mmu_valid(s2_mmu)) | 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 | * The virtual VMID (modulo CnP) will be used as a key when matching | 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 | out: | 651 | out: |
| 652 | atomic_inc(&s2_mmu->refcnt); | 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 | return s2_mmu; | 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 | void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu) | 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 | if (is_hyp_ctxt(vcpu)) { | 683 | if (is_hyp_ctxt(vcpu)) { |
| 667 | vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; | 684 | vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; |
| 668 | } else { | 685 | } else { |
| @@ -674,10 +691,18 @@ void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu) · 5 unmodified lines | |||
| 674 | 691 | ||
| 675 | void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu) | 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 | atomic_dec(&vcpu->arch.hw_mmu->refcnt); | 703 | atomic_dec(&vcpu->arch.hw_mmu->refcnt); |
| 679 | vcpu->arch.hw_mmu = NULL; | 704 | |
| 680 | } | 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 | int i; | 760 | int i; |
| 736 | 761 | ||
| @@ -740,7 +765,7 @@ void kvm_nested_s2_unmap(struct kvm *kvm) · 3 unmodified lines | |||
| 740 | struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i]; | 765 | struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i]; |
| 741 | 766 | ||
| 742 | if (kvm_s2_mmu_valid(mmu)) | 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 | return 0; | 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 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE); | 1527 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE); |
| 1528 | 1528 | ||
| 1529 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME); | 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 | break; | 1538 | break; |
| 1531 | case SYS_ID_AA64PFR2_EL1: | 1539 | case SYS_ID_AA64PFR2_EL1: |
| 1532 | /* We only expose FPMR */ | 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 | val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK; | 1558 | val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK; |
| 1551 | break; | 1559 | break; |
| 1552 | case SYS_ID_AA64MMFR3_EL1: | 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 | break; | 1563 | break; |
| 1555 | case SYS_ID_MMFR4_EL1: | 1564 | case SYS_ID_MMFR4_EL1: |
| 1556 | val &= ~ARM64_FEATURE_MASK(ID_MMFR4_EL1_CCIDX); | 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 | * one cache line. | 1994 | * one cache line. |
| 1986 | */ | 1995 | */ |
| 1987 | if (kvm_has_mte(vcpu->kvm)) | 1996 | if (kvm_has_mte(vcpu->kvm)) |
| 1988 | clidr |= 2 << CLIDR_TTYPE_SHIFT(loc); | 1997 | clidr |= 2ULL << CLIDR_TTYPE_SHIFT(loc); |
| 1989 | 1998 | ||
| 1990 | __vcpu_sys_reg(vcpu, r->reg) = clidr; | 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 | ID_AA64PFR0_EL1_RAS | | 2385 | ID_AA64PFR0_EL1_RAS | |
| 2377 | ID_AA64PFR0_EL1_AdvSIMD | | 2386 | ID_AA64PFR0_EL1_AdvSIMD | |
| 2378 | ID_AA64PFR0_EL1_FP), }, | 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 | ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR), | 2401 | ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR), |
| 2381 | ID_UNALLOCATED(4,3), | 2402 | ID_UNALLOCATED(4,3), |
| 2382 | ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0), | 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 | .get_user = get_id_reg, | 2411 | .get_user = get_id_reg, |
| 2391 | .set_user = set_id_aa64dfr0_el1, | 2412 | .set_user = set_id_aa64dfr0_el1, |
| 2392 | .reset = read_sanitised_id_aa64dfr0_el1, | 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 | ID_AA64DFR0_EL1_DebugVer_MASK, }, | 2429 | ID_AA64DFR0_EL1_DebugVer_MASK, }, |
| 2395 | ID_SANITISED(ID_AA64DFR1_EL1), | 2430 | ID_SANITISED(ID_AA64DFR1_EL1), |
| 2396 | ID_UNALLOCATED(5,2), | 2431 | ID_UNALLOCATED(5,2), |
| @@ -2433,6 +2468,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 36 unmodified lines | |||
| 2433 | ID_AA64MMFR2_EL1_NV | | 2468 | ID_AA64MMFR2_EL1_NV | |
| 2434 | ID_AA64MMFR2_EL1_CCIDX)), | 2469 | ID_AA64MMFR2_EL1_CCIDX)), |
| 2435 | ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX | | 2470 | ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX | |
| 2471 | ID_AA64MMFR3_EL1_S1PIE | | ||
| 2436 | ID_AA64MMFR3_EL1_S1POE)), | 2472 | ID_AA64MMFR3_EL1_S1POE)), |
| 2437 | ID_SANITISED(ID_AA64MMFR4_EL1), | 2473 | ID_SANITISED(ID_AA64MMFR4_EL1), |
| 2438 | ID_UNALLOCATED(7,5), | 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 | * Drop all shadow S2s, resulting in S1/S2 TLBIs for each of the | 2939 | * Drop all shadow S2s, resulting in S1/S2 TLBIs for each of the |
| 2904 | * corresponding VMIDs. | 2940 | * corresponding VMIDs. |
| 2905 | */ | 2941 | */ |
| 2906 | kvm_nested_s2_unmap(vcpu->kvm); | 2942 | kvm_nested_s2_unmap(vcpu->kvm, true); |
| 2907 | 2943 | ||
| 2908 | write_unlock(&vcpu->kvm->mmu_lock); | 2944 | write_unlock(&vcpu->kvm->mmu_lock); |
| 2909 | 2945 | ||
| @@ -2955,7 +2991,30 @@ union tlbi_info { · 45 unmodified lines | |||
| 2955 | static void s2_mmu_unmap_range(struct kvm_s2_mmu *mmu, | 2991 | static void s2_mmu_unmap_range(struct kvm_s2_mmu *mmu, |
| 2956 | const union tlbi_info *info) | 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 | static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | 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 | max_size = compute_tlb_inval_range(mmu, info->ipa.addr); | 3109 | max_size = compute_tlb_inval_range(mmu, info->ipa.addr); |
| 3051 | base_addr &= ~(max_size - 1); | 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 | static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | 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 | kfree(vgic_cpu->private_irqs); | 417 | kfree(vgic_cpu->private_irqs); |
| 418 | vgic_cpu->private_irqs = NULL; | 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 | vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; | 440 | vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; |
| 441 | } | ||
| 422 | } | 442 | } |
| 423 | 443 | ||
| 424 | void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) | 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 | if (ret) | 544 | if (ret) |
| 525 | goto out; | 545 | goto out; |
| 526 | 546 | ||
| 527 | dist->ready = true; | ||
| 528 | dist_base = dist->vgic_dist_base; | 547 | dist_base = dist->vgic_dist_base; |
| 529 | mutex_unlock(&kvm->arch.config_lock); | 548 | mutex_unlock(&kvm->arch.config_lock); |
| 530 | 549 | ||
| 531 | ret = vgic_register_dist_iodev(kvm, dist_base, type); | 550 | ret = vgic_register_dist_iodev(kvm, dist_base, type); |
| 532 | if (ret) | 551 | if (ret) { |
| 533 | kvm_err("Unable to register VGIC dist MMIO regions\n"); | 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 | goto out_slots; | 564 | goto out_slots; |
| 536 | out: | 565 | out: |
| 537 | mutex_unlock(&kvm->arch.config_lock); | 566 | mutex_unlock(&kvm->arch.config_lock); |
| 538 | out_slots: | 567 | out_slots: |
| 539 | mutex_unlock(&kvm->slots_lock); | ||
| 540 | |||
| 541 | if (ret) | 568 | if (ret) |
| 542 | kvm_vgic_destroy(kvm); | 569 | kvm_vm_dead(kvm); |
| 570 | |||
| 571 | mutex_unlock(&kvm->slots_lock); | ||
| 543 | 572 | ||
| 544 | return ret; | 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 | mutex_lock(&dev->kvm->arch.config_lock); | 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 | ret = -EBUSY; | 245 | ret = -EBUSY; |
| 241 | else | 246 | else |
| 242 | dev->kvm->arch.vgic.nr_spis = | 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 | emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx); | 2220 | emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx); |
| 2221 | 2221 | ||
| 2222 | if (flags & BPF_TRAMP_F_CALL_ORIG) { | 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 | emit_call((const u64)__bpf_tramp_enter, ctx); | 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 | if (flags & BPF_TRAMP_F_CALL_ORIG) { | 2269 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 2266 | im->ip_epilogue = ctx->ro_image + ctx->idx; | 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 | emit_call((const u64)__bpf_tramp_exit, ctx); | 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 | #define NR_WORDS DIV_ROUND_UP(NR_CPUS, BITS_PER_LONG) | 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 | struct loongson_system_configuration { | 33 | struct loongson_system_configuration { |
| 30 | int nr_cpus; | 34 | int nr_cpus; |
| 31 | int nr_nodes; | 35 | int nr_nodes; |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | |||
| 16 | #define XRANGE_SHIFT (48) | 16 | #define XRANGE_SHIFT (48) |
| 17 | 17 | ||
| 18 | /* Valid address length */ | 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 | /* Used for taking out the valid address */ | 20 | /* Used for taking out the valid address */ |
| 21 | #define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0) | 21 | #define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0) |
| 22 | /* One segment whole address space size */ | 22 | /* One segment whole address space size */ |
| @@ -250,7 +250,7 @@ · 249 unmodified lines | |||
| 250 | #define CSR_ESTAT_IS_WIDTH 15 | 250 | #define CSR_ESTAT_IS_WIDTH 15 |
| 251 | #define CSR_ESTAT_IS (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT) | 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 | #define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */ | 255 | #define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */ |
| 256 | 256 | ||
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | #define __HAVE_ARCH_PMD_ALLOC_ONE | 11 | #define __HAVE_ARCH_PMD_ALLOC_ONE |
| 12 | #define __HAVE_ARCH_PUD_ALLOC_ONE | 12 | #define __HAVE_ARCH_PUD_ALLOC_ONE |
| 13 | #define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL | ||
| 13 | #include <asm-generic/pgalloc.h> | 14 | #include <asm-generic/pgalloc.h> |
| 14 | 15 | ||
| 15 | static inline void pmd_populate_kernel(struct mm_struct *mm, | 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 | extern pgd_t *pgd_alloc(struct mm_struct *mm); | 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 | #define __pte_free_tlb(tlb, pte, address) \ | 58 | #define __pte_free_tlb(tlb, pte, address) \ |
| 48 | do { \ | 59 | do { \ |
| 49 | pagetable_pte_dtor(page_ptdesc(pte)); \ | 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 | extern void pgd_init(void *addr); | 269 | extern void pgd_init(void *addr); |
| 270 | extern void pud_init(void *addr); | 270 | extern void pud_init(void *addr); |
| 271 | extern void pmd_init(void *addr); | 271 | extern void pmd_init(void *addr); |
| 272 | extern void kernel_pte_init(void *addr); | ||
| 272 | 273 | ||
| 273 | /* | 274 | /* |
| 274 | * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that | 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 | WRITE_ONCE(*ptep, pteval); | 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 | #ifdef CONFIG_SMP | 329 | #ifdef CONFIG_SMP |
| 336 | /* | 330 | if (pte_val(pteval) & _PAGE_GLOBAL) |
| 337 | * For SMP, multiple CPUs can race, so we need | 331 | DBAR(0b11000); /* o_wrw = 0b11000 */ |
| 338 | * to do this atomically. | 332 | #endif |
| 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 | } | ||
| 352 | } | 333 | } |
| 353 | 334 | ||
| 354 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 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 */ | 337 | pte_t pte = ptep_get(ptep); |
| 357 | if (pte_val(ptep_get(ptep_buddy(ptep))) & _PAGE_GLOBAL) | 338 | pte_val(pte) &= _PAGE_GLOBAL; |
| 358 | set_pte(ptep, __pte(_PAGE_GLOBAL)); | 339 | set_pte(ptep, pte); |
| 359 | else | ||
| 360 | set_pte(ptep, __pte(0)); | ||
| 361 | } | 340 | } |
| 362 | 341 | ||
| 363 | #define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) | 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 | unsigned long top = TASK_SIZE & PAGE_MASK; | 294 | unsigned long top = TASK_SIZE & PAGE_MASK; |
| 295 | 295 | ||
| 296 | /* Space for the VDSO & data page */ | 296 | if (current->thread.vdso) { |
| 297 | top -= PAGE_ALIGN(current->thread.vdso->size); | 297 | /* Space for the VDSO & data page */ |
| 298 | top -= VVAR_SIZE; | 298 | top -= PAGE_ALIGN(current->thread.vdso->size); |
| 299 | 299 | top -= VVAR_SIZE; | |
| 300 | /* Space to randomize the VDSO base */ | 300 | |
| 301 | if (current->flags & PF_RANDOMIZE) | 301 | /* Space to randomize the VDSO base */ |
| 302 | top -= VDSO_RANDOMIZE_SIZE; | 302 | if (current->flags & PF_RANDOMIZE) |
| 303 | top -= VDSO_RANDOMIZE_SIZE; | ||
| 304 | } | ||
| 303 | 305 | ||
| 304 | return top; | 306 | return top; |
| 305 | } | 307 | } |
| @@ -55,6 +55,7 @@ · 54 unmodified lines | |||
| 55 | #define SMBIOS_FREQHIGH_OFFSET 0x17 | 55 | #define SMBIOS_FREQHIGH_OFFSET 0x17 |
| 56 | #define SMBIOS_FREQLOW_MASK 0xFF | 56 | #define SMBIOS_FREQLOW_MASK 0xFF |
| 57 | #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 | 57 | #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 |
| 58 | #define SMBIOS_THREAD_PACKAGE_OFFSET 0x25 | ||
| 58 | #define LOONGSON_EFI_ENABLE (1 << 3) | 59 | #define LOONGSON_EFI_ENABLE (1 << 3) |
| 59 | 60 | ||
| 60 | unsigned long fw_arg0, fw_arg1, fw_arg2; | 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 | cpu_clock_freq = freq_temp * 1000000; | 126 | cpu_clock_freq = freq_temp * 1000000; |
| 126 | 127 | ||
| 127 | loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]); | 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 | pr_info("CpuClock = %llu\n", cpu_clock_freq); | 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 | #else | 555 | #else |
| 556 | unsigned int *pc; | 556 | unsigned int *pc; |
| 557 | 557 | ||
| 558 | if (regs->csr_prmd & CSR_PRMD_PIE) | ||
| 559 | local_irq_enable(); | ||
| 560 | |||
| 558 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); | 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 | die_if_kernel("Kernel ale access", regs); | 582 | die_if_kernel("Kernel ale access", regs); |
| 580 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); | 583 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); |
| 581 | out: | 584 | out: |
| 585 | if (regs->csr_prmd & CSR_PRMD_PIE) | ||
| 586 | local_irq_disable(); | ||
| 582 | #endif | 587 | #endif |
| 583 | irqentry_exit(regs, state); | 588 | irqentry_exit(regs, state); |
| 584 | } | 589 | } |
| @@ -34,7 +34,6 @@ static union { · 33 unmodified lines | |||
| 34 | struct loongarch_vdso_data vdata; | 34 | struct loongarch_vdso_data vdata; |
| 35 | } loongarch_vdso_data __page_aligned_data; | 35 | } loongarch_vdso_data __page_aligned_data; |
| 36 | 36 | ||
| 37 | static struct page *vdso_pages[] = { NULL }; | ||
| 38 | struct vdso_data *vdso_data = generic_vdso_data.data; | 37 | struct vdso_data *vdso_data = generic_vdso_data.data; |
| 39 | struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata; | 38 | struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata; |
| 40 | struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data; | 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 | struct loongarch_vdso_info vdso_info = { | 85 | struct loongarch_vdso_info vdso_info = { |
| 87 | .vdso = vdso_start, | 86 | .vdso = vdso_start, |
| 88 | .size = PAGE_SIZE, | ||
| 89 | .code_mapping = { | 87 | .code_mapping = { |
| 90 | .name = "[vdso]", | 88 | .name = "[vdso]", |
| 91 | .pages = vdso_pages, | ||
| 92 | .mremap = vdso_mremap, | 89 | .mremap = vdso_mremap, |
| 93 | }, | 90 | }, |
| 94 | .data_mapping = { | 91 | .data_mapping = { |
| @@ -103,11 +100,14 @@ static int __init init_vdso(void) · 8 unmodified lines | |||
| 103 | unsigned long i, cpu, pfn; | 100 | unsigned long i, cpu, pfn; |
| 104 | 101 | ||
| 105 | BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); | 102 | BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); |
| 106 | BUG_ON(!PAGE_ALIGNED(vdso_info.size)); | ||
| 107 | 103 | ||
| 108 | for_each_possible_cpu(cpu) | 104 | for_each_possible_cpu(cpu) |
| 109 | vdso_pdata[cpu].node = cpu_to_node(cpu); | 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 | pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso)); | 111 | pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso)); |
| 112 | for (i = 0; i < vdso_info.size / PAGE_SIZE; i++) | 112 | for (i = 0; i < vdso_info.size / PAGE_SIZE; i++) |
| 113 | vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i); | 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 | if (kvm_vcpu_is_blocking(vcpu)) { | 161 | if (kvm_vcpu_is_blocking(vcpu)) { |
| 162 | 162 | ||
| 163 | /* | 163 | /* |
| 164 | * HRTIMER_MODE_PINNED is suggested since vcpu may run in | 164 | * HRTIMER_MODE_PINNED_HARD is suggested since vcpu may run in |
| 165 | * the same physical cpu in next time | 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 | vcpu->arch.vpid = 0; | 1457 | vcpu->arch.vpid = 0; |
| 1458 | vcpu->arch.flush_gpa = INVALID_GPA; | 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 | vcpu->arch.swtimer.function = kvm_swtimer_wakeup; | 1461 | vcpu->arch.swtimer.function = kvm_swtimer_wakeup; |
| 1462 | 1462 | ||
| 1463 | vcpu->arch.handle_exit = kvm_handle_exit; | 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 | pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); | 201 | pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); |
| 202 | if (!pte) | 202 | if (!pte) |
| 203 | panic("%s: Failed to allocate memory\n", __func__); | 203 | panic("%s: Failed to allocate memory\n", __func__); |
| 204 | |||
| 204 | pmd_populate_kernel(&init_mm, pmd, pte); | 205 | pmd_populate_kernel(&init_mm, pmd, pte); |
| 206 | kernel_pte_init(pte); | ||
| 205 | } | 207 | } |
| 206 | 208 | ||
| 207 | return pte_offset_kernel(pmd, addr); | 209 | return pte_offset_kernel(pmd, addr); |
| @@ -116,6 +116,26 @@ void pud_init(void *addr) · 115 unmodified lines | |||
| 116 | EXPORT_SYMBOL_GPL(pud_init); | 116 | EXPORT_SYMBOL_GPL(pud_init); |
| 117 | #endif | 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 | pmd_t mk_pmd(struct page *page, pgprot_t prot) | 139 | pmd_t mk_pmd(struct page *page, pgprot_t prot) |
| 120 | { | 140 | { |
| 121 | pmd_t pmd; | 141 | pmd_t pmd; |
| @@ -494,6 +494,7 @@ FixupDAR:/* Entry point for dcbx workaround. */ · 493 unmodified lines | |||
| 494 | bctr /* jump into table */ | 494 | bctr /* jump into table */ |
| 495 | 152: | 495 | 152: |
| 496 | mfdar r11 | 496 | mfdar r11 |
| 497 | mtdar r10 | ||
| 497 | mtctr r11 /* restore ctr reg from DAR */ | 498 | mtctr r11 /* restore ctr reg from DAR */ |
| 498 | mfspr r11, SPRN_SPRG_THREAD | 499 | mfspr r11, SPRN_SPRG_THREAD |
| 499 | stw r10, DAR(r11) | 500 | stw r10, DAR(r11) |
| @@ -22,7 +22,7 @@ endif · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | ifneq ($(c-getrandom-y),) | 23 | ifneq ($(c-getrandom-y),) |
| 24 | CFLAGS_vgetrandom-32.o += -include $(c-getrandom-y) | 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 | endif | 26 | endif |
| 27 | 27 | ||
| 28 | # Build rules | 28 | # Build rules |
| @@ -282,6 +282,7 @@ int __init opal_event_init(void) · 281 unmodified lines | |||
| 282 | name, NULL); | 282 | name, NULL); |
| 283 | if (rc) { | 283 | if (rc) { |
| 284 | pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start); | 284 | pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start); |
| 285 | kfree(name); | ||
| 285 | continue; | 286 | continue; |
| 286 | } | 287 | } |
| 287 | } | 288 | } |
| @@ -777,8 +777,7 @@ config IRQ_STACKS · 776 unmodified lines | |||
| 777 | config THREAD_SIZE_ORDER | 777 | config THREAD_SIZE_ORDER |
| 778 | int "Kernel stack size (in power-of-two numbers of page size)" if VMAP_STACK && EXPERT | 778 | int "Kernel stack size (in power-of-two numbers of page size)" if VMAP_STACK && EXPERT |
| 779 | range 0 4 | 779 | range 0 4 |
| 780 | default 1 if 32BIT && !KASAN | 780 | default 1 if 32BIT |
| 781 | default 3 if 64BIT && KASAN | ||
| 782 | default 2 | 781 | default 2 |
| 783 | help | 782 | help |
| 784 | Specify the Pages of thread stack size (from 4KB to 64KB), which also | 783 | Specify the Pages of thread stack size (from 4KB to 64KB), which also |
| @@ -13,7 +13,12 @@ · 12 unmodified lines | |||
| 13 | #include <linux/sizes.h> | 13 | #include <linux/sizes.h> |
| 14 | 14 | ||
| 15 | /* thread information allocation */ | 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 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) | 22 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
| 18 | 23 | ||
| 19 | /* | 24 | /* |
| @@ -55,7 +55,7 @@ struct imsic { · 54 unmodified lines | |||
| 55 | /* IMSIC SW-file */ | 55 | /* IMSIC SW-file */ |
| 56 | struct imsic_mrif *swfile; | 56 | struct imsic_mrif *swfile; |
| 57 | phys_addr_t swfile_pa; | 57 | phys_addr_t swfile_pa; |
| 58 | spinlock_t swfile_extirq_lock; | 58 | raw_spinlock_t swfile_extirq_lock; |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | #define imsic_vs_csr_read(__c) \ | 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 | * interruptions between reading topei and updating pending status. | 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 | if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) && | 627 | if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) && |
| 628 | imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis)) | 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 | else | 630 | else |
| 631 | kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT); | 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 | static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear, | 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 | imsic->swfile = page_to_virt(swfile_page); | 1052 | imsic->swfile = page_to_virt(swfile_page); |
| 1053 | imsic->swfile_pa = page_to_phys(swfile_page); | 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 | /* Setup IO device */ | 1056 | /* Setup IO device */ |
| 1057 | kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops); | 1057 | kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #define RV_MAX_REG_ARGS 8 | 18 | #define RV_MAX_REG_ARGS 8 |
| 19 | #define RV_FENTRY_NINSNS 2 | 19 | #define RV_FENTRY_NINSNS 2 |
| 20 | #define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4) | 20 | #define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4) |
| 21 | #define RV_KCFI_NINSNS (IS_ENABLED(CONFIG_CFI_CLANG) ? 1 : 0) | ||
| 21 | /* imm that allows emit_imm to emit max count insns */ | 22 | /* imm that allows emit_imm to emit max count insns */ |
| 22 | #define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF | 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 | if (!is_tail_call) | 272 | if (!is_tail_call) |
| 272 | emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx); | 273 | emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx); |
| 273 | emit_jalr(RV_REG_ZERO, is_tail_call ? RV_REG_T3 : RV_REG_RA, | 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 | ctx); | 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 | rv_lr_w(r0, 0, rd, 0, 0), ctx); | 550 | rv_lr_w(r0, 0, rd, 0, 0), ctx); |
| 549 | jmp_offset = ninsns_rvoff(8); | 551 | jmp_offset = ninsns_rvoff(8); |
| 550 | emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx); | 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) : | 553 | emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 1) : |
| 552 | rv_sc_w(RV_REG_T3, rs, rd, 0, 0), ctx); | 554 | rv_sc_w(RV_REG_T3, rs, rd, 0, 1), ctx); |
| 553 | jmp_offset = ninsns_rvoff(-6); | 555 | jmp_offset = ninsns_rvoff(-6); |
| 554 | emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx); | 556 | emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx); |
| 555 | emit(rv_fence(0x3, 0x3), ctx); | 557 | emit(rv_fence(0x3, 0x3), ctx); |
| @@ -50,7 +50,6 @@ CONFIG_NUMA=y · 49 unmodified lines | |||
| 50 | CONFIG_HZ_100=y | 50 | CONFIG_HZ_100=y |
| 51 | CONFIG_CERT_STORE=y | 51 | CONFIG_CERT_STORE=y |
| 52 | CONFIG_EXPOLINE=y | 52 | CONFIG_EXPOLINE=y |
| 53 | # CONFIG_EXPOLINE_EXTERN is not set | ||
| 54 | CONFIG_EXPOLINE_AUTO=y | 53 | CONFIG_EXPOLINE_AUTO=y |
| 55 | CONFIG_CHSC_SCH=y | 54 | CONFIG_CHSC_SCH=y |
| 56 | CONFIG_VFIO_CCW=m | 55 | CONFIG_VFIO_CCW=m |
| @@ -95,6 +94,7 @@ CONFIG_BINFMT_MISC=m · 38 unmodified lines | |||
| 95 | CONFIG_ZSWAP=y | 94 | CONFIG_ZSWAP=y |
| 96 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y | 95 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y |
| 97 | CONFIG_ZSMALLOC_STAT=y | 96 | CONFIG_ZSMALLOC_STAT=y |
| 97 | CONFIG_SLAB_BUCKETS=y | ||
| 98 | CONFIG_SLUB_STATS=y | 98 | CONFIG_SLUB_STATS=y |
| 99 | # CONFIG_COMPAT_BRK is not set | 99 | # CONFIG_COMPAT_BRK is not set |
| 100 | CONFIG_MEMORY_HOTPLUG=y | 100 | CONFIG_MEMORY_HOTPLUG=y |
| @@ -426,6 +426,13 @@ CONFIG_DEVTMPFS_SAFE=y · 325 unmodified lines | |||
| 426 | # CONFIG_FW_LOADER is not set | 426 | # CONFIG_FW_LOADER is not set |
| 427 | CONFIG_CONNECTOR=y | 427 | CONFIG_CONNECTOR=y |
| 428 | CONFIG_ZRAM=y | 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 | CONFIG_BLK_DEV_LOOP=m | 436 | CONFIG_BLK_DEV_LOOP=m |
| 430 | CONFIG_BLK_DEV_DRBD=m | 437 | CONFIG_BLK_DEV_DRBD=m |
| 431 | CONFIG_BLK_DEV_NBD=m | 438 | CONFIG_BLK_DEV_NBD=m |
| @@ -486,6 +493,7 @@ CONFIG_DM_UEVENT=y · 54 unmodified lines | |||
| 486 | CONFIG_DM_FLAKEY=m | 493 | CONFIG_DM_FLAKEY=m |
| 487 | CONFIG_DM_VERITY=m | 494 | CONFIG_DM_VERITY=m |
| 488 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y | 495 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y |
| 496 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | ||
| 489 | CONFIG_DM_SWITCH=m | 497 | CONFIG_DM_SWITCH=m |
| 490 | CONFIG_DM_INTEGRITY=m | 498 | CONFIG_DM_INTEGRITY=m |
| 491 | CONFIG_DM_VDO=m | 499 | CONFIG_DM_VDO=m |
| @@ -535,6 +543,7 @@ CONFIG_NLMON=m · 43 unmodified lines | |||
| 535 | CONFIG_MLX4_EN=m | 543 | CONFIG_MLX4_EN=m |
| 536 | CONFIG_MLX5_CORE=m | 544 | CONFIG_MLX5_CORE=m |
| 537 | CONFIG_MLX5_CORE_EN=y | 545 | CONFIG_MLX5_CORE_EN=y |
| 546 | # CONFIG_NET_VENDOR_META is not set | ||
| 538 | # CONFIG_NET_VENDOR_MICREL is not set | 547 | # CONFIG_NET_VENDOR_MICREL is not set |
| 539 | # CONFIG_NET_VENDOR_MICROCHIP is not set | 548 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 540 | # CONFIG_NET_VENDOR_MICROSEMI is not set | 549 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -695,6 +704,7 @@ CONFIG_NFSD=m · 154 unmodified lines | |||
| 695 | CONFIG_NFSD_V3_ACL=y | 704 | CONFIG_NFSD_V3_ACL=y |
| 696 | CONFIG_NFSD_V4=y | 705 | CONFIG_NFSD_V4=y |
| 697 | CONFIG_NFSD_V4_SECURITY_LABEL=y | 706 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 707 | # CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set | ||
| 698 | CONFIG_CIFS=m | 708 | CONFIG_CIFS=m |
| 699 | CONFIG_CIFS_UPCALL=y | 709 | CONFIG_CIFS_UPCALL=y |
| 700 | CONFIG_CIFS_XATTR=y | 710 | CONFIG_CIFS_XATTR=y |
| @@ -740,7 +750,6 @@ CONFIG_CRYPTO_DH=m · 39 unmodified lines | |||
| 740 | CONFIG_CRYPTO_ECDH=m | 750 | CONFIG_CRYPTO_ECDH=m |
| 741 | CONFIG_CRYPTO_ECDSA=m | 751 | CONFIG_CRYPTO_ECDSA=m |
| 742 | CONFIG_CRYPTO_ECRDSA=m | 752 | CONFIG_CRYPTO_ECRDSA=m |
| 743 | CONFIG_CRYPTO_SM2=m | ||
| 744 | CONFIG_CRYPTO_CURVE25519=m | 753 | CONFIG_CRYPTO_CURVE25519=m |
| 745 | CONFIG_CRYPTO_AES_TI=m | 754 | CONFIG_CRYPTO_AES_TI=m |
| 746 | CONFIG_CRYPTO_ANUBIS=m | 755 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -48,7 +48,6 @@ CONFIG_NUMA=y · 47 unmodified lines | |||
| 48 | CONFIG_HZ_100=y | 48 | CONFIG_HZ_100=y |
| 49 | CONFIG_CERT_STORE=y | 49 | CONFIG_CERT_STORE=y |
| 50 | CONFIG_EXPOLINE=y | 50 | CONFIG_EXPOLINE=y |
| 51 | # CONFIG_EXPOLINE_EXTERN is not set | ||
| 52 | CONFIG_EXPOLINE_AUTO=y | 51 | CONFIG_EXPOLINE_AUTO=y |
| 53 | CONFIG_CHSC_SCH=y | 52 | CONFIG_CHSC_SCH=y |
| 54 | CONFIG_VFIO_CCW=m | 53 | CONFIG_VFIO_CCW=m |
| @@ -89,6 +88,7 @@ CONFIG_BINFMT_MISC=m · 34 unmodified lines | |||
| 89 | CONFIG_ZSWAP=y | 88 | CONFIG_ZSWAP=y |
| 90 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y | 89 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y |
| 91 | CONFIG_ZSMALLOC_STAT=y | 90 | CONFIG_ZSMALLOC_STAT=y |
| 91 | CONFIG_SLAB_BUCKETS=y | ||
| 92 | # CONFIG_COMPAT_BRK is not set | 92 | # CONFIG_COMPAT_BRK is not set |
| 93 | CONFIG_MEMORY_HOTPLUG=y | 93 | CONFIG_MEMORY_HOTPLUG=y |
| 94 | CONFIG_MEMORY_HOTREMOVE=y | 94 | CONFIG_MEMORY_HOTREMOVE=y |
| @@ -416,6 +416,13 @@ CONFIG_DEVTMPFS_SAFE=y · 321 unmodified lines | |||
| 416 | # CONFIG_FW_LOADER is not set | 416 | # CONFIG_FW_LOADER is not set |
| 417 | CONFIG_CONNECTOR=y | 417 | CONFIG_CONNECTOR=y |
| 418 | CONFIG_ZRAM=y | 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 | CONFIG_BLK_DEV_LOOP=m | 426 | CONFIG_BLK_DEV_LOOP=m |
| 420 | CONFIG_BLK_DEV_DRBD=m | 427 | CONFIG_BLK_DEV_DRBD=m |
| 421 | CONFIG_BLK_DEV_NBD=m | 428 | CONFIG_BLK_DEV_NBD=m |
| @@ -476,6 +483,7 @@ CONFIG_DM_UEVENT=y · 54 unmodified lines | |||
| 476 | CONFIG_DM_FLAKEY=m | 483 | CONFIG_DM_FLAKEY=m |
| 477 | CONFIG_DM_VERITY=m | 484 | CONFIG_DM_VERITY=m |
| 478 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y | 485 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y |
| 486 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | ||
| 479 | CONFIG_DM_SWITCH=m | 487 | CONFIG_DM_SWITCH=m |
| 480 | CONFIG_DM_INTEGRITY=m | 488 | CONFIG_DM_INTEGRITY=m |
| 481 | CONFIG_DM_VDO=m | 489 | CONFIG_DM_VDO=m |
| @@ -525,6 +533,7 @@ CONFIG_NLMON=m · 43 unmodified lines | |||
| 525 | CONFIG_MLX4_EN=m | 533 | CONFIG_MLX4_EN=m |
| 526 | CONFIG_MLX5_CORE=m | 534 | CONFIG_MLX5_CORE=m |
| 527 | CONFIG_MLX5_CORE_EN=y | 535 | CONFIG_MLX5_CORE_EN=y |
| 536 | # CONFIG_NET_VENDOR_META is not set | ||
| 528 | # CONFIG_NET_VENDOR_MICREL is not set | 537 | # CONFIG_NET_VENDOR_MICREL is not set |
| 529 | # CONFIG_NET_VENDOR_MICROCHIP is not set | 538 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 530 | # CONFIG_NET_VENDOR_MICROSEMI is not set | 539 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -682,6 +691,7 @@ CONFIG_NFSD=m · 151 unmodified lines | |||
| 682 | CONFIG_NFSD_V3_ACL=y | 691 | CONFIG_NFSD_V3_ACL=y |
| 683 | CONFIG_NFSD_V4=y | 692 | CONFIG_NFSD_V4=y |
| 684 | CONFIG_NFSD_V4_SECURITY_LABEL=y | 693 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 694 | # CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set | ||
| 685 | CONFIG_CIFS=m | 695 | CONFIG_CIFS=m |
| 686 | CONFIG_CIFS_UPCALL=y | 696 | CONFIG_CIFS_UPCALL=y |
| 687 | CONFIG_CIFS_XATTR=y | 697 | CONFIG_CIFS_XATTR=y |
| @@ -726,7 +736,6 @@ CONFIG_CRYPTO_DH=m · 38 unmodified lines | |||
| 726 | CONFIG_CRYPTO_ECDH=m | 736 | CONFIG_CRYPTO_ECDH=m |
| 727 | CONFIG_CRYPTO_ECDSA=m | 737 | CONFIG_CRYPTO_ECDSA=m |
| 728 | CONFIG_CRYPTO_ECRDSA=m | 738 | CONFIG_CRYPTO_ECRDSA=m |
| 729 | CONFIG_CRYPTO_SM2=m | ||
| 730 | CONFIG_CRYPTO_CURVE25519=m | 739 | CONFIG_CRYPTO_CURVE25519=m |
| 731 | CONFIG_CRYPTO_AES_TI=m | 740 | CONFIG_CRYPTO_AES_TI=m |
| 732 | CONFIG_CRYPTO_ANUBIS=m | 741 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -767,6 +776,7 @@ CONFIG_CRYPTO_LZ4=m · 34 unmodified lines | |||
| 767 | CONFIG_CRYPTO_LZ4HC=m | 776 | CONFIG_CRYPTO_LZ4HC=m |
| 768 | CONFIG_CRYPTO_ZSTD=m | 777 | CONFIG_CRYPTO_ZSTD=m |
| 769 | CONFIG_CRYPTO_ANSI_CPRNG=m | 778 | CONFIG_CRYPTO_ANSI_CPRNG=m |
| 779 | CONFIG_CRYPTO_JITTERENTROPY_OSR=1 | ||
| 770 | CONFIG_CRYPTO_USER_API_HASH=m | 780 | CONFIG_CRYPTO_USER_API_HASH=m |
| 771 | CONFIG_CRYPTO_USER_API_SKCIPHER=m | 781 | CONFIG_CRYPTO_USER_API_SKCIPHER=m |
| 772 | CONFIG_CRYPTO_USER_API_RNG=m | 782 | CONFIG_CRYPTO_USER_API_RNG=m |
| @@ -49,6 +49,7 @@ CONFIG_ZFCP=y · 48 unmodified lines | |||
| 49 | # CONFIG_HVC_IUCV is not set | 49 | # CONFIG_HVC_IUCV is not set |
| 50 | # CONFIG_HW_RANDOM_S390 is not set | 50 | # CONFIG_HW_RANDOM_S390 is not set |
| 51 | # CONFIG_HMC_DRV is not set | 51 | # CONFIG_HMC_DRV is not set |
| 52 | # CONFIG_S390_UV_UAPI is not set | ||
| 52 | # CONFIG_S390_TAPE is not set | 53 | # CONFIG_S390_TAPE is not set |
| 53 | # CONFIG_VMCP is not set | 54 | # CONFIG_VMCP is not set |
| 54 | # CONFIG_MONWRITER is not set | 55 | # CONFIG_MONWRITER is not set |
| @@ -16,8 +16,10 @@ · 15 unmodified lines | |||
| 16 | #include <asm/pci_io.h> | 16 | #include <asm/pci_io.h> |
| 17 | 17 | ||
| 18 | #define xlate_dev_mem_ptr xlate_dev_mem_ptr | 18 | #define xlate_dev_mem_ptr xlate_dev_mem_ptr |
| 19 | #define kc_xlate_dev_mem_ptr xlate_dev_mem_ptr | ||
| 19 | void *xlate_dev_mem_ptr(phys_addr_t phys); | 20 | void *xlate_dev_mem_ptr(phys_addr_t phys); |
| 20 | #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr | 21 | #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr |
| 22 | #define kc_unxlate_dev_mem_ptr unxlate_dev_mem_ptr | ||
| 21 | void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); | 23 | void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); |
| 22 | 24 | ||
| 23 | #define IO_SPACE_LIMIT 0 | 25 | #define IO_SPACE_LIMIT 0 |
| @@ -49,6 +49,7 @@ struct perf_sf_sde_regs { · 48 unmodified lines | |||
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | #define perf_arch_fetch_caller_regs(regs, __ip) do { \ | 51 | #define perf_arch_fetch_caller_regs(regs, __ip) do { \ |
| 52 | (regs)->psw.mask = 0; \ | ||
| 52 | (regs)->psw.addr = (__ip); \ | 53 | (regs)->psw.addr = (__ip); \ |
| 53 | (regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) - \ | 54 | (regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) - \ |
| 54 | offsetof(struct stack_frame, back_chain); \ | 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 | vcpu->stat.instruction_diagnose_258++; | 77 | vcpu->stat.instruction_diagnose_258++; |
| 78 | if (vcpu->run->s.regs.gprs[rx] & 7) | 78 | if (vcpu->run->s.regs.gprs[rx] & 7) |
| 79 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 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 | if (rc) | 81 | if (rc) |
| 82 | return kvm_s390_inject_prog_cond(vcpu, rc); | 82 | return kvm_s390_inject_prog_cond(vcpu, rc); |
| 83 | if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) | 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 | const gfn_t gfn = gpa_to_gfn(gpa); | 828 | const gfn_t gfn = gpa_to_gfn(gpa); |
| 829 | int rc; | 829 | int rc; |
| 830 | 830 | ||
| 831 | if (!gfn_to_memslot(kvm, gfn)) | ||
| 832 | return PGM_ADDRESSING; | ||
| 831 | if (mode == GACC_STORE) | 833 | if (mode == GACC_STORE) |
| 832 | rc = kvm_write_guest_page(kvm, gfn, data, offset, len); | 834 | rc = kvm_write_guest_page(kvm, gfn, data, offset, len); |
| 833 | else | 835 | else |
| @@ -985,6 +987,8 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, · 151 unmodified lines | |||
| 985 | gra += fragment_len; | 987 | gra += fragment_len; |
| 986 | data += fragment_len; | 988 | data += fragment_len; |
| 987 | } | 989 | } |
| 990 | if (rc > 0) | ||
| 991 | vcpu->arch.pgm.code = rc; | ||
| 988 | return rc; | 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 | * @len: number of bytes to copy | 405 | * @len: number of bytes to copy |
| 406 | * | 406 | * |
| 407 | * Copy @len bytes from @data (kernel space) to @gra (guest real address). | 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 | * Guest low address and key protection are not checked. | 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 | * If an error occurs data may have been copied partially to guest memory. | 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 | * @len: number of bytes to copy | 429 | * @len: number of bytes to copy |
| 429 | * | 430 | * |
| 430 | * Copy @len bytes from @gra (guest real address) to @data (kernel space). | 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 | * Guest key protection is not checked. | 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 | * If an error occurs data may have been copied partially to kernel space. | 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 | goto no_pdev; | 280 | goto no_pdev; |
| 281 | 281 | ||
| 282 | switch (ccdf->pec) { | 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 | ers_res = zpci_event_attempt_error_recovery(pdev); | 292 | ers_res = zpci_event_attempt_error_recovery(pdev); |
| 285 | if (ers_res != PCI_ERS_RESULT_RECOVERED) | 293 | if (ers_res != PCI_ERS_RESULT_RECOVERED) |
| 286 | zpci_event_io_failure(pdev, pci_channel_io_perm_failure); | 294 | zpci_event_io_failure(pdev, pci_channel_io_perm_failure); |
| 287 | break; | 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 | pci_dev_put(pdev); | 297 | pci_dev_put(pdev); |
| 297 | no_pdev: | 298 | no_pdev: |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | |||
| 9 | #include <asm/unwind_hints.h> | 9 | #include <asm/unwind_hints.h> |
| 10 | #include <asm/segment.h> | 10 | #include <asm/segment.h> |
| 11 | #include <asm/cache.h> | 11 | #include <asm/cache.h> |
| 12 | #include <asm/cpufeatures.h> | ||
| 13 | #include <asm/nospec-branch.h> | ||
| 12 | 14 | ||
| 13 | #include "calling.h" | 15 | #include "calling.h" |
| 14 | 16 | ||
| @@ -19,6 +21,9 @@ SYM_FUNC_START(entry_ibpb) · 4 unmodified lines | |||
| 19 | movl $PRED_CMD_IBPB, %eax | 21 | movl $PRED_CMD_IBPB, %eax |
| 20 | xorl %edx, %edx | 22 | xorl %edx, %edx |
| 21 | wrmsr | 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 | RET | 27 | RET |
| 23 | SYM_FUNC_END(entry_ibpb) | 28 | SYM_FUNC_END(entry_ibpb) |
| 24 | /* For KVM */ | 29 | /* For KVM */ |
| @@ -871,6 +871,8 @@ SYM_FUNC_START(entry_SYSENTER_32) · 870 unmodified lines | |||
| 871 | 871 | ||
| 872 | /* Now ready to switch the cr3 */ | 872 | /* Now ready to switch the cr3 */ |
| 873 | SWITCH_TO_USER_CR3 scratch_reg=%eax | 873 | SWITCH_TO_USER_CR3 scratch_reg=%eax |
| 874 | /* Clobbers ZF */ | ||
| 875 | CLEAR_CPU_BUFFERS | ||
| 874 | 876 | ||
| 875 | /* | 877 | /* |
| 876 | * Restore all flags except IF. (We restore IF separately because | 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 | BUG_IF_WRONG_CR3 no_user_check=1 | 883 | BUG_IF_WRONG_CR3 no_user_check=1 |
| 882 | popfl | 884 | popfl |
| 883 | popl %eax | 885 | popl %eax |
| 884 | CLEAR_CPU_BUFFERS | ||
| 885 | 886 | ||
| 886 | /* | 887 | /* |
| 887 | * Return back to the vDSO, which will pop ecx and edx. | 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 | /* Not on SYSENTER stack. */ | 1146 | /* Not on SYSENTER stack. */ |
| 1146 | call exc_nmi | 1147 | call exc_nmi |
| 1147 | CLEAR_CPU_BUFFERS | ||
| 1148 | jmp .Lnmi_return | 1148 | jmp .Lnmi_return |
| 1149 | 1149 | ||
| 1150 | .Lnmi_from_sysenter_stack: | 1150 | .Lnmi_from_sysenter_stack: |
| @@ -1165,6 +1165,7 @@ SYM_CODE_START(asm_exc_nmi) · 14 unmodified lines | |||
| 1165 | 1165 | ||
| 1166 | CHECK_AND_APPLY_ESPFIX | 1166 | CHECK_AND_APPLY_ESPFIX |
| 1167 | RESTORE_ALL_NMI cr3_reg=%edi pop=4 | 1167 | RESTORE_ALL_NMI cr3_reg=%edi pop=4 |
| 1168 | CLEAR_CPU_BUFFERS | ||
| 1168 | jmp .Lirq_return | 1169 | jmp .Lirq_return |
| 1169 | 1170 | ||
| 1170 | #ifdef CONFIG_X86_ESPFIX32 | 1171 | #ifdef CONFIG_X86_ESPFIX32 |
| @@ -1206,6 +1207,7 @@ SYM_CODE_START(asm_exc_nmi) · 35 unmodified lines | |||
| 1206 | * 1 - orig_ax | 1207 | * 1 - orig_ax |
| 1207 | */ | 1208 | */ |
| 1208 | lss (1+5+6)*4(%esp), %esp # back to espfix stack | 1209 | lss (1+5+6)*4(%esp), %esp # back to espfix stack |
| 1210 | CLEAR_CPU_BUFFERS | ||
| 1209 | jmp .Lirq_return | 1211 | jmp .Lirq_return |
| 1210 | #endif | 1212 | #endif |
| 1211 | SYM_CODE_END(asm_exc_nmi) | 1213 | SYM_CODE_END(asm_exc_nmi) |
| @@ -215,7 +215,7 @@ · 214 unmodified lines | |||
| 215 | #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* Disable Speculative Store Bypass. */ | 215 | #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* Disable Speculative Store Bypass. */ |
| 216 | #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* AMD SSBD implementation via LS_CFG MSR */ | 216 | #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* AMD SSBD implementation via LS_CFG MSR */ |
| 217 | #define X86_FEATURE_IBRS ( 7*32+25) /* "ibrs" Indirect Branch Restricted Speculation */ | 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 | #define X86_FEATURE_STIBP ( 7*32+27) /* "stibp" Single Thread Indirect Branch Predictors */ | 219 | #define X86_FEATURE_STIBP ( 7*32+27) /* "stibp" Single Thread Indirect Branch Predictors */ |
| 220 | #define X86_FEATURE_ZEN ( 7*32+28) /* Generic flag for all Zen and newer */ | 220 | #define X86_FEATURE_ZEN ( 7*32+28) /* Generic flag for all Zen and newer */ |
| 221 | #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* L1TF workaround PTE inversion */ | 221 | #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* L1TF workaround PTE inversion */ |
| @@ -348,6 +348,7 @@ · 126 unmodified lines | |||
| 348 | #define X86_FEATURE_CPPC (13*32+27) /* "cppc" Collaborative Processor Performance Control */ | 348 | #define X86_FEATURE_CPPC (13*32+27) /* "cppc" Collaborative Processor Performance Control */ |
| 349 | #define X86_FEATURE_AMD_PSFD (13*32+28) /* Predictive Store Forwarding Disable */ | 349 | #define X86_FEATURE_AMD_PSFD (13*32+28) /* Predictive Store Forwarding Disable */ |
| 350 | #define X86_FEATURE_BTC_NO (13*32+29) /* Not vulnerable to Branch Type Confusion */ | 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 | #define X86_FEATURE_BRS (13*32+31) /* "brs" Branch Sampling available */ | 352 | #define X86_FEATURE_BRS (13*32+31) /* "brs" Branch Sampling available */ |
| 352 | 353 | ||
| 353 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ | 354 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ |
| @@ -523,4 +524,5 @@ · 169 unmodified lines | |||
| 523 | #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */ | 524 | #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */ |
| 524 | #define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */ | 525 | #define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */ |
| 525 | #define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */ | 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 | #endif /* _ASM_X86_CPUFEATURES_H */ | 528 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -2,6 +2,8 @@ · 1 unmodified line | |||
| 2 | #ifndef _ASM_X86_FTRACE_H | 2 | #ifndef _ASM_X86_FTRACE_H |
| 3 | #define _ASM_X86_FTRACE_H | 3 | #define _ASM_X86_FTRACE_H |
| 4 | 4 | ||
| 5 | #include <asm/ptrace.h> | ||
| 6 | |||
| 5 | #ifdef CONFIG_FUNCTION_TRACER | 7 | #ifdef CONFIG_FUNCTION_TRACER |
| 6 | #ifndef CC_USING_FENTRY | 8 | #ifndef CC_USING_FENTRY |
| 7 | # error Compiler does not support fentry? | 9 | # error Compiler does not support fentry? |
| @@ -323,7 +323,16 @@ · 322 unmodified lines | |||
| 323 | * Note: Only the memory operand variant of VERW clears the CPU buffers. | 323 | * Note: Only the memory operand variant of VERW clears the CPU buffers. |
| 324 | */ | 324 | */ |
| 325 | .macro CLEAR_CPU_BUFFERS | 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 | .endm | 336 | .endm |
| 328 | 337 | ||
| 329 | #ifdef CONFIG_X86_64 | 338 | #ifdef CONFIG_X86_64 |
| @@ -26,7 +26,7 @@ void __noreturn machine_real_restart(unsigned int type); · 25 unmodified lines | |||
| 26 | #define MRR_APM 1 | 26 | #define MRR_APM 1 |
| 27 | 27 | ||
| 28 | typedef void (cpu_emergency_virt_cb)(void); | 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 | void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); | 30 | void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); |
| 31 | void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback); | 31 | void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback); |
| 32 | void cpu_emergency_disable_virtualization(void); | 32 | void cpu_emergency_disable_virtualization(void); |
| @@ -34,7 +34,7 @@ void cpu_emergency_disable_virtualization(void); · 1 unmodified line | |||
| 34 | static inline void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) {} | 34 | static inline void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) {} |
| 35 | static inline void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) {} | 35 | static inline void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) {} |
| 36 | static inline void cpu_emergency_disable_virtualization(void) {} | 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 | typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); | 39 | typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); |
| 40 | void nmi_shootdown_cpus(nmi_shootdown_cb callback); | 40 | void nmi_shootdown_cpus(nmi_shootdown_cb callback); |
| @@ -44,6 +44,7 @@ · 43 unmodified lines | |||
| 44 | #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4 | 44 | #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4 |
| 45 | #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc | 45 | #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc |
| 46 | #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4 | 46 | #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4 |
| 47 | #define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4 0x16fc | ||
| 47 | #define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4 0x124c | 48 | #define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4 0x124c |
| 48 | #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4 0x12bc | 49 | #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4 0x12bc |
| 49 | #define PCI_DEVICE_ID_AMD_MI200_DF_F4 0x14d4 | 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 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, | 128 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, |
| 128 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, | 129 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, |
| 129 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) }, | 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 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) }, | 132 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) }, |
| 131 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) }, | 133 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) }, |
| 132 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) }, | 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 | v = apic_read(APIC_LVTT); | 440 | v = apic_read(APIC_LVTT); |
| 441 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); | 441 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); |
| 442 | apic_write(APIC_LVTT, v); | 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 | return 0; | 456 | return 0; |
| 445 | } | 457 | } |
| 446 | 458 | ||
| @@ -1202,5 +1202,6 @@ void amd_check_microcode(void) · 1201 unmodified lines | |||
| 1202 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) | 1202 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
| 1203 | return; | 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 | case RETBLEED_MITIGATION_IBPB: | 1116 | case RETBLEED_MITIGATION_IBPB: |
| 1117 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); | 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 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); | 1127 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); |
| 1119 | mitigate_smt = true; | 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 | break; | 1137 | break; |
| 1121 | 1138 | ||
| 1122 | case RETBLEED_MITIGATION_STUFF: | 1139 | case RETBLEED_MITIGATION_STUFF: |
| @@ -2627,6 +2644,14 @@ static void __init srso_select_mitigation(void) · 1504 unmodified lines | |||
| 2627 | if (has_microcode) { | 2644 | if (has_microcode) { |
| 2628 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); | 2645 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); |
| 2629 | srso_mitigation = SRSO_MITIGATION_IBPB; | 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 | } else { | 2656 | } else { |
| 2632 | pr_err("WARNING: kernel not compiled with MITIGATION_IBPB_ENTRY.\n"); | 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 | if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { | 2663 | if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { |
| 2639 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); | 2664 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); |
| 2640 | srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; | 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 | } else { | 2674 | } else { |
| 2643 | pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n"); | 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 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) | 1443 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) |
| 1444 | setup_force_cpu_bug(X86_BUG_BHI); | 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 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) | 1449 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1447 | return; | 1450 | return; |
| 1448 | 1451 | ||
| @@ -207,7 +207,7 @@ static inline bool rdt_get_mb_table(struct rdt_resource *r) · 206 unmodified lines | |||
| 207 | return false; | 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 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); | 212 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 213 | union cpuid_0x10_3_eax eax; | 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 | return true; | 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 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); | 246 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 247 | u32 eax, ebx, ecx, edx, subleaf; | 247 | u32 eax, ebx, ecx, edx, subleaf; |
| @@ -29,10 +29,10 @@ · 28 unmodified lines | |||
| 29 | * hardware. The allocated bandwidth percentage is rounded to the next | 29 | * hardware. The allocated bandwidth percentage is rounded to the next |
| 30 | * control step available on the hardware. | 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 | int ret; | 34 | int ret; |
| 35 | u32 bw; | ||
| 36 | 36 | ||
| 37 | /* | 37 | /* |
| 38 | * Only linear delay values is supported for current Intel SKUs. | 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 | return false; | 42 | return false; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | ret = kstrtoul(buf, 10, &bw); | 45 | ret = kstrtou32(buf, 10, &bw); |
| 46 | if (ret) { | 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 | return false; | 48 | return false; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | if ((bw < r->membw.min_bw || bw > r->default_ctrl) && | 51 | /* Nothing else to do if software controller is enabled. */ |
| 52 | !is_mba_sc(r)) { | 52 | if (is_mba_sc(r)) { |
| 53 | rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw, | 53 | *data = bw; |
| 54 | r->membw.min_bw, r->default_ctrl); | 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 | return false; | 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 | struct resctrl_staged_config *cfg; | 70 | struct resctrl_staged_config *cfg; |
| 66 | u32 closid = data->rdtgrp->closid; | 71 | u32 closid = data->rdtgrp->closid; |
| 67 | struct rdt_resource *r = s->res; | 72 | struct rdt_resource *r = s->res; |
| 68 | unsigned long bw_val; | 73 | u32 bw_val; |
| 69 | 74 | ||
| 70 | cfg = &d->staged_config[s->conf_type]; | 75 | cfg = &d->staged_config[s->conf_type]; |
| 71 | if (cfg->have_new_ctrl) { | 76 | if (cfg->have_new_ctrl) { |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #include <asm/apic.h> | 37 | #include <asm/apic.h> |
| 38 | #include <asm/apicdef.h> | 38 | #include <asm/apicdef.h> |
| 39 | #include <asm/hypervisor.h> | 39 | #include <asm/hypervisor.h> |
| 40 | #include <asm/mtrr.h> | ||
| 40 | #include <asm/tlb.h> | 41 | #include <asm/tlb.h> |
| 41 | #include <asm/cpuidle_haltpoll.h> | 42 | #include <asm/cpuidle_haltpoll.h> |
| 42 | #include <asm/ptrace.h> | 43 | #include <asm/ptrace.h> |
| @@ -980,6 +981,9 @@ static void __init kvm_init_platform(void) · 937 unmodified lines | |||
| 980 | } | 981 | } |
| 981 | kvmclock_init(); | 982 | kvmclock_init(); |
| 982 | x86_platform.apic_post_init = kvm_apic_init; | 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 | #if defined(CONFIG_AMD_MEM_ENCRYPT) | 989 | #if defined(CONFIG_AMD_MEM_ENCRYPT) |
| @@ -530,7 +530,7 @@ static inline void kb_wait(void) · 529 unmodified lines | |||
| 530 | 530 | ||
| 531 | static inline void nmi_shootdown_cpus_on_restart(void); | 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 | /* RCU-protected callback to disable virtualization prior to reboot. */ | 534 | /* RCU-protected callback to disable virtualization prior to reboot. */ |
| 535 | static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback; | 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 | #else | 601 | #else |
| 602 | static void emergency_reboot_disable_virtualization(void) { } | 602 | static void emergency_reboot_disable_virtualization(void) { } |
| 603 | #endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */ | 603 | #endif /* CONFIG_KVM_X86 */ |
| 604 | 604 | ||
| 605 | void __attribute__((weak)) mach_reboot_fixups(void) | 605 | void __attribute__((weak)) mach_reboot_fixups(void) |
| 606 | { | 606 | { |
| @@ -17,8 +17,8 @@ menuconfig VIRTUALIZATION · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | if VIRTUALIZATION | 18 | if VIRTUALIZATION |
| 19 | 19 | ||
| 20 | config KVM | 20 | config KVM_X86 |
| 21 | tristate "Kernel-based Virtual Machine (KVM) support" | 21 | def_tristate KVM if KVM_INTEL || KVM_AMD |
| 22 | depends on X86_LOCAL_APIC | 22 | depends on X86_LOCAL_APIC |
| 23 | select KVM_COMMON | 23 | select KVM_COMMON |
| 24 | select KVM_GENERIC_MMU_NOTIFIER | 24 | select KVM_GENERIC_MMU_NOTIFIER |
| @@ -44,7 +44,11 @@ config KVM · 19 unmodified lines | |||
| 44 | select HAVE_KVM_PM_NOTIFIER if PM | 44 | select HAVE_KVM_PM_NOTIFIER if PM |
| 45 | select KVM_GENERIC_HARDWARE_ENABLING | 45 | select KVM_GENERIC_HARDWARE_ENABLING |
| 46 | select KVM_GENERIC_PRE_FAULT_MEMORY | 46 | select KVM_GENERIC_PRE_FAULT_MEMORY |
| 47 | select KVM_GENERIC_PRIVATE_MEM if KVM_SW_PROTECTED_VM | ||
| 47 | select KVM_WERROR if WERROR | 48 | select KVM_WERROR if WERROR |
| 49 | |||
| 50 | config KVM | ||
| 51 | tristate "Kernel-based Virtual Machine (KVM) support" | ||
| 48 | help | 52 | help |
| 49 | Support hosting fully virtualized guest machines using hardware | 53 | Support hosting fully virtualized guest machines using hardware |
| 50 | virtualization extensions. You will need a fairly recent | 54 | virtualization extensions. You will need a fairly recent |
| @@ -77,7 +81,6 @@ config KVM_SW_PROTECTED_VM · 26 unmodified lines | |||
| 77 | bool "Enable support for KVM software-protected VMs" | 81 | bool "Enable support for KVM software-protected VMs" |
| 78 | depends on EXPERT | 82 | depends on EXPERT |
| 79 | depends on KVM && X86_64 | 83 | depends on KVM && X86_64 |
| 80 | select KVM_GENERIC_PRIVATE_MEM | ||
| 81 | help | 84 | help |
| 82 | Enable support for KVM software-protected VMs. Currently, software- | 85 | Enable support for KVM software-protected VMs. Currently, software- |
| 83 | protected VMs are purely a development and testing vehicle for | 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 | kvm-amd-y += svm/svm_onhyperv.o | 32 | kvm-amd-y += svm/svm_onhyperv.o |
| 33 | endif | 33 | endif |
| 34 | 34 | ||
| 35 | obj-$(CONFIG_KVM) += kvm.o | 35 | obj-$(CONFIG_KVM_X86) += kvm.o |
| 36 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o | 36 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o |
| 37 | obj-$(CONFIG_KVM_AMD) += kvm-amd.o | 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 | bool flush = false; | 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 | if (kvm_memslots_have_rmaps(kvm)) | 1570 | if (kvm_memslots_have_rmaps(kvm)) |
| 1560 | flush = __kvm_rmap_zap_gfn_range(kvm, range->slot, | 1571 | flush = __kvm_rmap_zap_gfn_range(kvm, range->slot, |
| 1561 | range->start, range->end, | 1572 | range->start, range->end, |
| @@ -7047,14 +7058,42 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) · 5485 unmodified lines | |||
| 7047 | kvm_mmu_zap_all(kvm); | 7058 | kvm_mmu_zap_all(kvm); |
| 7048 | } | 7059 | } |
| 7049 | 7060 | ||
| 7050 | /* | 7061 | static void kvm_mmu_zap_memslot_pages_and_flush(struct kvm *kvm, |
| 7051 | * Zapping leaf SPTEs with memslot range when a memslot is moved/deleted. | 7062 | struct kvm_memory_slot *slot, |
| 7052 | * | 7063 | bool flush) |
| 7053 | * Zapping non-leaf SPTEs, a.k.a. not-last SPTEs, isn't required, worst | 7064 | { |
| 7054 | * case scenario we'll have unused shadow pages lying around until they | 7065 | LIST_HEAD(invalid_list); |
| 7055 | * are recycled due to age or when the VM is destroyed. | 7066 | unsigned long i; |
| 7056 | */ | 7067 | |
| 7057 | static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *slot) | 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 | struct kvm_gfn_range range = { | 7098 | struct kvm_gfn_range range = { |
| 7060 | .slot = slot, | 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 | .end = slot->base_gfn + slot->npages, | 7101 | .end = slot->base_gfn + slot->npages, |
| 7063 | .may_block = true, | 7102 | .may_block = true, |
| 7064 | }; | 7103 | }; |
| 7104 | bool flush; | ||
| 7065 | 7105 | ||
| 7066 | write_lock(&kvm->mmu_lock); | 7106 | write_lock(&kvm->mmu_lock); |
| 7067 | if (kvm_unmap_gfn_range(kvm, &range)) | 7107 | flush = kvm_unmap_gfn_range(kvm, &range); |
| 7068 | kvm_flush_remote_tlbs_memslot(kvm, slot); | 7108 | kvm_mmu_zap_memslot_pages_and_flush(kvm, slot, flush); |
| 7069 | |||
| 7070 | write_unlock(&kvm->mmu_lock); | 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 | if (kvm_memslot_flush_zap_all(kvm)) | 7121 | if (kvm_memslot_flush_zap_all(kvm)) |
| 7083 | kvm_mmu_zap_all_fast(kvm); | 7122 | kvm_mmu_zap_all_fast(kvm); |
| 7084 | else | 7123 | else |
| 7085 | kvm_mmu_zap_memslot_leafs(kvm, slot); | 7124 | kvm_mmu_zap_memslot(kvm, slot); |
| 7086 | } | 7125 | } |
| 7087 | 7126 | ||
| 7088 | void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen) | 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 | u64 pdpte; | 63 | u64 pdpte; |
| 64 | int ret; | 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 | ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(cr3), &pdpte, | 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 | if (ret) | 72 | if (ret) |
| 69 | return 0; | 73 | return 0; |
| 70 | return pdpte; | 74 | return pdpte; |
| @@ -4888,9 +4888,6 @@ void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 4887 unmodified lines | |||
| 4888 | vmx->hv_deadline_tsc = -1; | 4888 | vmx->hv_deadline_tsc = -1; |
| 4889 | kvm_set_cr8(vcpu, 0); | 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 | seg_setup(VCPU_SREG_CS); | 4891 | seg_setup(VCPU_SREG_CS); |
| 4895 | vmcs_write16(GUEST_CS_SELECTOR, 0xf000); | 4892 | vmcs_write16(GUEST_CS_SELECTOR, 0xf000); |
| 4896 | vmcs_writel(GUEST_CS_BASE, 0xffff0000ul); | 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 | vmcs_writel(GUEST_IDTR_BASE, 0); | 4914 | vmcs_writel(GUEST_IDTR_BASE, 0); |
| 4918 | vmcs_write32(GUEST_IDTR_LIMIT, 0xffff); | 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 | vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); | 4920 | vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); |
| 4921 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); | 4921 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); |
| 4922 | vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, 0); | 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 | switch (msr) { | 1032 | switch (msr) { |
| 1033 | case MSR_IA32_APICBASE: | 1033 | case MSR_IA32_APICBASE: |
| 1034 | val &= ~X2APIC_ENABLE; | 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 | break; | 1039 | break; |
| 1036 | } | 1040 | } |
| 1037 | return val; | 1041 | return val; |
| @@ -56,8 +56,7 @@ new_segment: · 55 unmodified lines | |||
| 56 | 56 | ||
| 57 | /** | 57 | /** |
| 58 | * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist | 58 | * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist |
| 59 | * @q: request queue | 59 | * @rq: request to map |
| 60 | * @bio: bio with integrity metadata attached | ||
| 61 | * @sglist: target scatterlist | 60 | * @sglist: target scatterlist |
| 62 | * | 61 | * |
| 63 | * Description: Map the integrity vectors in request into a | 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 | if (!dname) | 3166 | if (!dname) |
| 3167 | return 0; | 3167 | return 0; |
| 3168 | 3168 | ||
| 3169 | spin_lock_irq(&ioc->lock); | 3169 | spin_lock(&ioc->lock); |
| 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", | 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 | dname, ioc->enabled, ioc->user_qos_params ? "user" : "auto", | 3171 | dname, ioc->enabled, ioc->user_qos_params ? "user" : "auto", |
| 3172 | ioc->params.qos[QOS_RPPM] / 10000, | 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 | ioc->params.qos[QOS_MIN] % 10000 / 100, | 3179 | ioc->params.qos[QOS_MIN] % 10000 / 100, |
| 3180 | ioc->params.qos[QOS_MAX] / 10000, | 3180 | ioc->params.qos[QOS_MAX] / 10000, |
| 3181 | ioc->params.qos[QOS_MAX] % 10000 / 100); | 3181 | ioc->params.qos[QOS_MAX] % 10000 / 100); |
| 3182 | spin_unlock_irq(&ioc->lock); | 3182 | spin_unlock(&ioc->lock); |
| 3183 | return 0; | 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 | if (!dname) | 3366 | if (!dname) |
| 3367 | return 0; | 3367 | return 0; |
| 3368 | 3368 | ||
| 3369 | spin_lock_irq(&ioc->lock); | 3369 | spin_lock(&ioc->lock); |
| 3370 | seq_printf(sf, "%s ctrl=%s model=linear " | 3370 | seq_printf(sf, "%s ctrl=%s model=linear " |
| 3371 | "rbps=%llu rseqiops=%llu rrandiops=%llu " | 3371 | "rbps=%llu rseqiops=%llu rrandiops=%llu " |
| 3372 | "wbps=%llu wseqiops=%llu wrandiops=%llu\n", | 3372 | "wbps=%llu wseqiops=%llu wrandiops=%llu\n", |
| 3373 | dname, ioc->user_cost_model ? "user" : "auto", | 3373 | dname, ioc->user_cost_model ? "user" : "auto", |
| 3374 | u[I_LCOEF_RBPS], u[I_LCOEF_RSEQIOPS], u[I_LCOEF_RRANDIOPS], | 3374 | u[I_LCOEF_RBPS], u[I_LCOEF_RSEQIOPS], u[I_LCOEF_RRANDIOPS], |
| 3375 | u[I_LCOEF_WBPS], u[I_LCOEF_WSEQIOPS], u[I_LCOEF_WRANDIOPS]); | 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 | return 0; | 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 | /* mark the queue as mq asap */ | 4310 | /* mark the queue as mq asap */ |
| 4311 | q->mq_ops = set->ops; | 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 | if (blk_mq_alloc_ctxs(q)) | 4319 | if (blk_mq_alloc_ctxs(q)) |
| 4314 | goto err_exit; | 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 | INIT_WORK(&q->timeout_work, blk_mq_timeout_work); | 4334 | INIT_WORK(&q->timeout_work, blk_mq_timeout_work); |
| 4329 | blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); | 4335 | blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); |
| 4330 | 4336 | ||
| 4331 | q->tag_set = set; | ||
| 4332 | |||
| 4333 | q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; | 4337 | q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; |
| 4334 | 4338 | ||
| 4335 | INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work); | 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 | data->got_token = true; | 220 | data->got_token = true; |
| 221 | smp_wmb(); | 221 | smp_wmb(); |
| 222 | list_del_init(&curr->entry); | ||
| 223 | wake_up_process(data->task); | 222 | wake_up_process(data->task); |
| 223 | list_del_init_careful(&curr->entry); | ||
| 224 | return 1; | 224 | return 1; |
| 225 | } | 225 | } |
| 226 | 226 | ||
| @@ -106,8 +106,7 @@ static struct elevator_type *__elevator_find(const char *name) · 105 unmodified lines | |||
| 106 | return NULL; | 106 | return NULL; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static struct elevator_type *elevator_find_get(struct request_queue *q, | 109 | static struct elevator_type *elevator_find_get(const char *name) |
| 110 | const char *name) | ||
| 111 | { | 110 | { |
| 112 | struct elevator_type *e; | 111 | struct elevator_type *e; |
| 113 | 112 | ||
| @@ -551,7 +550,7 @@ EXPORT_SYMBOL_GPL(elv_unregister); · 437 unmodified lines | |||
| 551 | static inline bool elv_support_iosched(struct request_queue *q) | 550 | static inline bool elv_support_iosched(struct request_queue *q) |
| 552 | { | 551 | { |
| 553 | if (!queue_is_mq(q) || | 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 | return false; | 554 | return false; |
| 556 | return true; | 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 | static struct elevator_type *elevator_get_default(struct request_queue *q) | 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 | return NULL; | 565 | return NULL; |
| 567 | 566 | ||
| 568 | if (q->nr_hw_queues != 1 && | 567 | if (q->nr_hw_queues != 1 && |
| 569 | !blk_mq_is_shared_tags(q->tag_set->flags)) | 568 | !blk_mq_is_shared_tags(q->tag_set->flags)) |
| 570 | return NULL; | 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 | if (q->elevator && elevator_match(q->elevator->type, elevator_name)) | 696 | if (q->elevator && elevator_match(q->elevator->type, elevator_name)) |
| 698 | return 0; | 697 | return 0; |
| 699 | 698 | ||
| 700 | e = elevator_find_get(q, elevator_name); | 699 | e = elevator_find_get(elevator_name); |
| 701 | if (!e) | 700 | if (!e) |
| 702 | return -EINVAL; | 701 | return -EINVAL; |
| 703 | ret = elevator_switch(q, e); | 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 | size_t count) | 708 | size_t count) |
| 710 | { | 709 | { |
| 711 | char elevator_name[ELV_NAME_MAX]; | 710 | char elevator_name[ELV_NAME_MAX]; |
| 711 | struct elevator_type *found; | ||
| 712 | const char *name; | ||
| 712 | 713 | ||
| 713 | if (!elv_support_iosched(disk->queue)) | 714 | if (!elv_support_iosched(disk->queue)) |
| 714 | return -EOPNOTSUPP; | 715 | return -EOPNOTSUPP; |
| 715 | 716 | ||
| 716 | strscpy(elevator_name, buf, sizeof(elevator_name)); | 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 | return 0; | 727 | return 0; |
| 721 | } | 728 | } |
| @@ -373,7 +373,7 @@ found: · 372 unmodified lines | |||
| 373 | q->cra_flags |= CRYPTO_ALG_DEAD; | 373 | q->cra_flags |= CRYPTO_ALG_DEAD; |
| 374 | alg = test->adult; | 374 | alg = test->adult; |
| 375 | 375 | ||
| 376 | if (list_empty(&alg->cra_list)) | 376 | if (crypto_is_dead(alg)) |
| 377 | goto complete; | 377 | goto complete; |
| 378 | 378 | ||
| 379 | if (err == -ECANCELED) | 379 | if (err == -ECANCELED) |
| @@ -1940,7 +1940,7 @@ static int __alg_test_hash(const struct hash_testvec *vecs, · 1939 unmodified lines | |||
| 1940 | atfm = crypto_alloc_ahash(driver, type, mask); | 1940 | atfm = crypto_alloc_ahash(driver, type, mask); |
| 1941 | if (IS_ERR(atfm)) { | 1941 | if (IS_ERR(atfm)) { |
| 1942 | if (PTR_ERR(atfm) == -ENOENT) | 1942 | if (PTR_ERR(atfm) == -ENOENT) |
| 1943 | return -ENOENT; | 1943 | return 0; |
| 1944 | pr_err("alg: hash: failed to allocate transform for %s: %ld\n", | 1944 | pr_err("alg: hash: failed to allocate transform for %s: %ld\n", |
| 1945 | driver, PTR_ERR(atfm)); | 1945 | driver, PTR_ERR(atfm)); |
| 1946 | return PTR_ERR(atfm); | 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 | tfm = crypto_alloc_aead(driver, type, mask); | 2706 | tfm = crypto_alloc_aead(driver, type, mask); |
| 2707 | if (IS_ERR(tfm)) { | 2707 | if (IS_ERR(tfm)) { |
| 2708 | if (PTR_ERR(tfm) == -ENOENT) | 2708 | if (PTR_ERR(tfm) == -ENOENT) |
| 2709 | return -ENOENT; | 2709 | return 0; |
| 2710 | pr_err("alg: aead: failed to allocate transform for %s: %ld\n", | 2710 | pr_err("alg: aead: failed to allocate transform for %s: %ld\n", |
| 2711 | driver, PTR_ERR(tfm)); | 2711 | driver, PTR_ERR(tfm)); |
| 2712 | return PTR_ERR(tfm); | 2712 | return PTR_ERR(tfm); |
| @@ -3285,7 +3285,7 @@ static int alg_test_skcipher(const struct alg_test_desc *desc, · 572 unmodified lines | |||
| 3285 | tfm = crypto_alloc_skcipher(driver, type, mask); | 3285 | tfm = crypto_alloc_skcipher(driver, type, mask); |
| 3286 | if (IS_ERR(tfm)) { | 3286 | if (IS_ERR(tfm)) { |
| 3287 | if (PTR_ERR(tfm) == -ENOENT) | 3287 | if (PTR_ERR(tfm) == -ENOENT) |
| 3288 | return -ENOENT; | 3288 | return 0; |
| 3289 | pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", | 3289 | pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", |
| 3290 | driver, PTR_ERR(tfm)); | 3290 | driver, PTR_ERR(tfm)); |
| 3291 | return PTR_ERR(tfm); | 3291 | return PTR_ERR(tfm); |
| @@ -3700,7 +3700,7 @@ static int alg_test_cipher(const struct alg_test_desc *desc, · 408 unmodified lines | |||
| 3700 | tfm = crypto_alloc_cipher(driver, type, mask); | 3700 | tfm = crypto_alloc_cipher(driver, type, mask); |
| 3701 | if (IS_ERR(tfm)) { | 3701 | if (IS_ERR(tfm)) { |
| 3702 | if (PTR_ERR(tfm) == -ENOENT) | 3702 | if (PTR_ERR(tfm) == -ENOENT) |
| 3703 | return -ENOENT; | 3703 | return 0; |
| 3704 | printk(KERN_ERR "alg: cipher: Failed to load transform for " | 3704 | printk(KERN_ERR "alg: cipher: Failed to load transform for " |
| 3705 | "%s: %ld\n", driver, PTR_ERR(tfm)); | 3705 | "%s: %ld\n", driver, PTR_ERR(tfm)); |
| 3706 | return PTR_ERR(tfm); | 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 | acomp = crypto_alloc_acomp(driver, type, mask); | 3726 | acomp = crypto_alloc_acomp(driver, type, mask); |
| 3727 | if (IS_ERR(acomp)) { | 3727 | if (IS_ERR(acomp)) { |
| 3728 | if (PTR_ERR(acomp) == -ENOENT) | 3728 | if (PTR_ERR(acomp) == -ENOENT) |
| 3729 | return -ENOENT; | 3729 | return 0; |
| 3730 | pr_err("alg: acomp: Failed to load transform for %s: %ld\n", | 3730 | pr_err("alg: acomp: Failed to load transform for %s: %ld\n", |
| 3731 | driver, PTR_ERR(acomp)); | 3731 | driver, PTR_ERR(acomp)); |
| 3732 | return PTR_ERR(acomp); | 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 | comp = crypto_alloc_comp(driver, type, mask); | 3740 | comp = crypto_alloc_comp(driver, type, mask); |
| 3741 | if (IS_ERR(comp)) { | 3741 | if (IS_ERR(comp)) { |
| 3742 | if (PTR_ERR(comp) == -ENOENT) | 3742 | if (PTR_ERR(comp) == -ENOENT) |
| 3743 | return -ENOENT; | 3743 | return 0; |
| 3744 | pr_err("alg: comp: Failed to load transform for %s: %ld\n", | 3744 | pr_err("alg: comp: Failed to load transform for %s: %ld\n", |
| 3745 | driver, PTR_ERR(comp)); | 3745 | driver, PTR_ERR(comp)); |
| 3746 | return PTR_ERR(comp); | 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 | rng = crypto_alloc_rng(driver, type, mask); | 3818 | rng = crypto_alloc_rng(driver, type, mask); |
| 3819 | if (IS_ERR(rng)) { | 3819 | if (IS_ERR(rng)) { |
| 3820 | if (PTR_ERR(rng) == -ENOENT) | 3820 | if (PTR_ERR(rng) == -ENOENT) |
| 3821 | return -ENOENT; | 3821 | return 0; |
| 3822 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " | 3822 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " |
| 3823 | "%ld\n", driver, PTR_ERR(rng)); | 3823 | "%ld\n", driver, PTR_ERR(rng)); |
| 3824 | return PTR_ERR(rng); | 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 | drng = crypto_alloc_rng(driver, type, mask); | 3847 | drng = crypto_alloc_rng(driver, type, mask); |
| 3848 | if (IS_ERR(drng)) { | 3848 | if (IS_ERR(drng)) { |
| 3849 | kfree_sensitive(buf); | ||
| 3849 | if (PTR_ERR(drng) == -ENOENT) | 3850 | if (PTR_ERR(drng) == -ENOENT) |
| 3850 | goto out_no_rng; | 3851 | return 0; |
| 3851 | printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " | 3852 | printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " |
| 3852 | "%s\n", driver); | 3853 | "%s\n", driver); |
| 3853 | out_no_rng: | ||
| 3854 | kfree_sensitive(buf); | ||
| 3855 | return PTR_ERR(drng); | 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 | tfm = crypto_alloc_kpp(driver, type, mask); | 4094 | tfm = crypto_alloc_kpp(driver, type, mask); |
| 4096 | if (IS_ERR(tfm)) { | 4095 | if (IS_ERR(tfm)) { |
| 4097 | if (PTR_ERR(tfm) == -ENOENT) | 4096 | if (PTR_ERR(tfm) == -ENOENT) |
| 4098 | return -ENOENT; | 4097 | return 0; |
| 4099 | pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", | 4098 | pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", |
| 4100 | driver, PTR_ERR(tfm)); | 4099 | driver, PTR_ERR(tfm)); |
| 4101 | return PTR_ERR(tfm); | 4100 | return PTR_ERR(tfm); |
| @@ -4325,7 +4324,7 @@ static int alg_test_akcipher(const struct alg_test_desc *desc, · 223 unmodified lines | |||
| 4325 | tfm = crypto_alloc_akcipher(driver, type, mask); | 4324 | tfm = crypto_alloc_akcipher(driver, type, mask); |
| 4326 | if (IS_ERR(tfm)) { | 4325 | if (IS_ERR(tfm)) { |
| 4327 | if (PTR_ERR(tfm) == -ENOENT) | 4326 | if (PTR_ERR(tfm) == -ENOENT) |
| 4328 | return -ENOENT; | 4327 | return 0; |
| 4329 | pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", | 4328 | pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", |
| 4330 | driver, PTR_ERR(tfm)); | 4329 | driver, PTR_ERR(tfm)); |
| 4331 | return PTR_ERR(tfm); | 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 | nents = sgt->nents; | 496 | nents = sgt->nents; |
| 497 | nents_dma = nents; | 497 | nents_dma = nents; |
| 498 | *size = QAIC_MANAGE_EXT_MSG_LENGTH - msg_hdr_len - sizeof(**out_trans); | 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 | *size -= sizeof(*asp); | 500 | *size -= sizeof(*asp); |
| 501 | /* Save 1K for possible follow-up transactions. */ | 501 | /* Save 1K for possible follow-up transactions. */ |
| 502 | if (*size < SZ_1K) { | 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 | nents = 0; | 184 | nents = 0; |
| 185 | 185 | ||
| 186 | size = size ? size : PAGE_SIZE; | 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 | len = sg_dma_len(sg); | 188 | len = sg_dma_len(sg); |
| 189 | 189 | ||
| 190 | if (!len) | 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 | /* copy relevant sg node and fix page and length */ | 222 | /* copy relevant sg node and fix page and length */ |
| 223 | sgn = sgf; | 223 | sgn = sgf; |
| 224 | for_each_sgtable_sg(sgt, sg, j) { | 224 | for_each_sgtable_dma_sg(sgt, sg, j) { |
| 225 | memcpy(sg, sgn, sizeof(*sg)); | 225 | memcpy(sg, sgn, sizeof(*sg)); |
| 226 | if (sgn == sgf) { | 226 | if (sgn == sgf) { |
| 227 | sg_dma_address(sg) += offf; | 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 | * fence. | 301 | * fence. |
| 302 | */ | 302 | */ |
| 303 | dev_addr = req->dev_addr; | 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 | slice->reqs[i].cmd = cmd; | 305 | slice->reqs[i].cmd = cmd; |
| 306 | slice->reqs[i].src_addr = cpu_to_le64(slice->dir == DMA_TO_DEVICE ? | 306 | slice->reqs[i].src_addr = cpu_to_le64(slice->dir == DMA_TO_DEVICE ? |
| 307 | sg_dma_address(sg) : dev_addr); | 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 | seg = bridge->domain_nr; | 63 | seg = bridge->domain_nr; |
| 64 | 64 | ||
| 65 | bus = pbus->number; | 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 | return 0; | 68 | return 0; |
| 69 | } | 69 | } |
| @@ -703,28 +703,35 @@ static LIST_HEAD(acpi_battery_list); · 702 unmodified lines | |||
| 703 | static LIST_HEAD(battery_hook_list); | 703 | static LIST_HEAD(battery_hook_list); |
| 704 | static DEFINE_MUTEX(hook_mutex); | 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 | struct acpi_battery *battery; | 708 | struct acpi_battery *battery; |
| 709 | |||
| 709 | /* | 710 | /* |
| 710 | * In order to remove a hook, we first need to | 711 | * In order to remove a hook, we first need to |
| 711 | * de-register all the batteries that are registered. | 712 | * de-register all the batteries that are registered. |
| 712 | */ | 713 | */ |
| 713 | if (lock) | ||
| 714 | mutex_lock(&hook_mutex); | ||
| 715 | list_for_each_entry(battery, &acpi_battery_list, list) { | 714 | list_for_each_entry(battery, &acpi_battery_list, list) { |
| 716 | if (!hook->remove_battery(battery->bat, hook)) | 715 | if (!hook->remove_battery(battery->bat, hook)) |
| 717 | power_supply_changed(battery->bat); | 716 | power_supply_changed(battery->bat); |
| 718 | } | 717 | } |
| 719 | list_del(&hook->list); | 718 | list_del_init(&hook->list); |
| 720 | if (lock) | 719 | |
| 721 | mutex_unlock(&hook_mutex); | ||
| 722 | pr_info("extension unregistered: %s\n", hook->name); | 720 | pr_info("extension unregistered: %s\n", hook->name); |
| 723 | } | 721 | } |
| 724 | 722 | ||
| 725 | void battery_hook_unregister(struct acpi_battery_hook *hook) | 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 | EXPORT_SYMBOL_GPL(battery_hook_unregister); | 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 | struct acpi_battery *battery; | 740 | struct acpi_battery *battery; |
| 734 | 741 | ||
| 735 | mutex_lock(&hook_mutex); | 742 | mutex_lock(&hook_mutex); |
| 736 | INIT_LIST_HEAD(&hook->list); | ||
| 737 | list_add(&hook->list, &battery_hook_list); | 743 | list_add(&hook->list, &battery_hook_list); |
| 738 | /* | 744 | /* |
| 739 | * Now that the driver is registered, we need | 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 | * hooks. | 756 | * hooks. |
| 751 | */ | 757 | */ |
| 752 | pr_err("extension failed to load: %s", hook->name); | 758 | pr_err("extension failed to load: %s", hook->name); |
| 753 | __battery_hook_unregister(hook, 0); | 759 | battery_hook_unregister_unlocked(hook); |
| 754 | goto end; | 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 | pr_err("error in extension, unloading: %s", | 811 | pr_err("error in extension, unloading: %s", |
| 806 | hook_node->name); | 812 | hook_node->name); |
| 807 | __battery_hook_unregister(hook_node, 0); | 813 | battery_hook_unregister_unlocked(hook_node); |
| 808 | } | 814 | } |
| 809 | } | 815 | } |
| 810 | mutex_unlock(&hook_mutex); | 816 | mutex_unlock(&hook_mutex); |
| @@ -837,7 +843,7 @@ static void __exit battery_hook_exit(void) · 26 unmodified lines | |||
| 837 | * need to remove the hooks. | 843 | * need to remove the hooks. |
| 838 | */ | 844 | */ |
| 839 | list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { | 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 | mutex_destroy(&hook_mutex); | 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 | .matches = { | 445 | .matches = { |
| 446 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 452 | .matches = { |
| 453 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 459 | .matches = { |
| 460 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 466 | .matches = { |
| 467 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 473 | .matches = { |
| 481 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 480 | .matches = { |
| 488 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 */ | 486 | /* Asus Vivobook E1504GA* */ |
| 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 */ | ||
| 515 | .matches = { | 487 | .matches = { |
| 516 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 488 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 517 | DMI_MATCH(DMI_BOARD_NAME, "E1504GA"), | 489 | DMI_MATCH(DMI_BOARD_NAME, "E1504GA"), |
| 518 | }, | 490 | }, |
| 519 | }, | 491 | }, |
| 520 | { | 492 | { |
| 521 | /* Asus Vivobook E1504GAB */ | 493 | /* Asus Vivobook Pro N6506M* */ |
| 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 */ | ||
| 543 | .matches = { | 494 | .matches = { |
| 544 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | * controller board in their ACPI tables (and may even have one), but | 844 | * controller board in their ACPI tables (and may even have one), but |
| 845 | * which need native backlight control nevertheless. | 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 | /* https://bugzilla.redhat.com/show_bug.cgi?id=2303936 */ | 857 | /* https://bugzilla.redhat.com/show_bug.cgi?id=2303936 */ |
| 849 | .callback = video_detect_force_native, | 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 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); | 4100 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); |
| 4101 | 4101 | ||
| 4102 | /* Set all devices attached to the port in standby mode */ | 4102 | /* |
| 4103 | ata_for_each_link(link, ap, HOST_FIRST) { | 4103 | * We will reach this point for all of the PM events: |
| 4104 | ata_for_each_dev(dev, link, ENABLED) | 4104 | * PM_EVENT_SUSPEND (if runtime pm, PM_EVENT_AUTO will also be set) |
| 4105 | ata_dev_power_set_standby(dev); | 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 | struct device *pd_dev = NULL; | 195 | struct device *pd_dev = NULL; |
| 196 | int ret, i, num_pds = 0; | 196 | int ret, i, num_pds = 0; |
| 197 | bool by_id = true; | 197 | bool by_id = true; |
| 198 | size_t size; | ||
| 198 | u32 pd_flags = data ? data->pd_flags : 0; | 199 | u32 pd_flags = data ? data->pd_flags : 0; |
| 199 | u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 : | 200 | u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 : |
| 200 | DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; | 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 | if (num_pds <= 0) | 218 | if (num_pds <= 0) |
| 218 | return 0; | 219 | return 0; |
| 219 | 220 | ||
| 220 | pds = devm_kzalloc(dev, sizeof(*pds), GFP_KERNEL); | 221 | pds = kzalloc(sizeof(*pds), GFP_KERNEL); |
| 221 | if (!pds) | 222 | if (!pds) |
| 222 | return -ENOMEM; | 223 | return -ENOMEM; |
| 223 | 224 | ||
| 224 | pds->pd_devs = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_devs), | 225 | size = sizeof(*pds->pd_devs) + sizeof(*pds->pd_links); |
| 225 | GFP_KERNEL); | 226 | pds->pd_devs = kcalloc(num_pds, size, GFP_KERNEL); |
| 226 | if (!pds->pd_devs) | 227 | if (!pds->pd_devs) { |
| 227 | return -ENOMEM; | 228 | ret = -ENOMEM; |
| 228 | 229 | goto free_pds; | |
| 229 | pds->pd_links = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_links), | 230 | } |
| 230 | GFP_KERNEL); | 231 | pds->pd_links = (void *)(pds->pd_devs + num_pds); |
| 231 | if (!pds->pd_links) | ||
| 232 | return -ENOMEM; | ||
| 233 | 232 | ||
| 234 | if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON) | 233 | if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON) |
| 235 | link_flags |= DL_FLAG_RPM_ACTIVE; | 234 | link_flags |= DL_FLAG_RPM_ACTIVE; |
| @@ -272,6 +271,9 @@ err_attach: · 36 unmodified lines | |||
| 272 | device_link_del(pds->pd_links[i]); | 271 | device_link_del(pds->pd_links[i]); |
| 273 | dev_pm_domain_detach(pds->pd_devs[i], true); | 272 | dev_pm_domain_detach(pds->pd_devs[i], true); |
| 274 | } | 273 | } |
| 274 | kfree(pds->pd_devs); | ||
| 275 | free_pds: | ||
| 276 | kfree(pds); | ||
| 275 | return ret; | 277 | return ret; |
| 276 | } | 278 | } |
| 277 | EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list); | 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 | device_link_del(list->pd_links[i]); | 365 | device_link_del(list->pd_links[i]); |
| 364 | dev_pm_domain_detach(list->pd_devs[i], true); | 366 | dev_pm_domain_detach(list->pd_devs[i], true); |
| 365 | } | 367 | } |
| 368 | |||
| 369 | kfree(list->pd_devs); | ||
| 370 | kfree(list); | ||
| 366 | } | 371 | } |
| 367 | EXPORT_SYMBOL_GPL(dev_pm_domain_detach_list); | 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 | ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit; | 363 | ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit; |
| 364 | dev_hold(t->ifp->nd); | ||
| 364 | skb->dev = t->ifp->nd; | 365 | skb->dev = t->ifp->nd; |
| 365 | } | 366 | } |
| 366 | 367 | ||
| @@ -401,6 +402,8 @@ aoecmd_ata_rw(struct aoedev *d) · 34 unmodified lines | |||
| 401 | __skb_queue_head_init(&queue); | 402 | __skb_queue_head_init(&queue); |
| 402 | __skb_queue_tail(&queue, skb); | 403 | __skb_queue_tail(&queue, skb); |
| 403 | aoenet_xmit(&queue); | 404 | aoenet_xmit(&queue); |
| 405 | } else { | ||
| 406 | dev_put(f->t->ifp->nd); | ||
| 404 | } | 407 | } |
| 405 | return 1; | 408 | return 1; |
| 406 | } | 409 | } |
| @@ -483,10 +486,13 @@ resend(struct aoedev *d, struct frame *f) · 76 unmodified lines | |||
| 483 | memcpy(h->dst, t->addr, sizeof h->dst); | 486 | memcpy(h->dst, t->addr, sizeof h->dst); |
| 484 | memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); | 487 | memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); |
| 485 | 488 | ||
| 489 | dev_hold(t->ifp->nd); | ||
| 486 | skb->dev = t->ifp->nd; | 490 | skb->dev = t->ifp->nd; |
| 487 | skb = skb_clone(skb, GFP_ATOMIC); | 491 | skb = skb_clone(skb, GFP_ATOMIC); |
| 488 | if (skb == NULL) | 492 | if (skb == NULL) { |
| 493 | dev_put(t->ifp->nd); | ||
| 489 | return; | 494 | return; |
| 495 | } | ||
| 490 | f->sent = ktime_get(); | 496 | f->sent = ktime_get(); |
| 491 | __skb_queue_head_init(&queue); | 497 | __skb_queue_head_init(&queue); |
| 492 | __skb_queue_tail(&queue, skb); | 498 | __skb_queue_tail(&queue, skb); |
| @@ -617,6 +623,8 @@ probe(struct aoetgt *t) · 124 unmodified lines | |||
| 617 | __skb_queue_head_init(&queue); | 623 | __skb_queue_head_init(&queue); |
| 618 | __skb_queue_tail(&queue, skb); | 624 | __skb_queue_tail(&queue, skb); |
| 619 | aoenet_xmit(&queue); | 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 | ah->cmdstat = ATA_CMD_ID_ATA; | 1403 | ah->cmdstat = ATA_CMD_ID_ATA; |
| 1396 | ah->lba3 = 0xa0; | 1404 | ah->lba3 = 0xa0; |
| 1397 | 1405 | ||
| 1406 | dev_hold(t->ifp->nd); | ||
| 1398 | skb->dev = t->ifp->nd; | 1407 | skb->dev = t->ifp->nd; |
| 1399 | 1408 | ||
| 1400 | d->rttavg = RTTAVG_INIT; | 1409 | d->rttavg = RTTAVG_INIT; |
| @@ -1404,6 +1413,8 @@ aoecmd_ata_id(struct aoedev *d) · 3 unmodified lines | |||
| 1404 | skb = skb_clone(skb, GFP_ATOMIC); | 1413 | skb = skb_clone(skb, GFP_ATOMIC); |
| 1405 | if (skb) | 1414 | if (skb) |
| 1406 | f->sent = ktime_get(); | 1415 | f->sent = ktime_get(); |
| 1416 | else | ||
| 1417 | dev_put(t->ifp->nd); | ||
| 1407 | 1418 | ||
| 1408 | return skb; | 1419 | return skb; |
| 1409 | } | 1420 | } |
| @@ -1364,7 +1364,6 @@ extern struct bio_set drbd_io_bio_set; · 1363 unmodified lines | |||
| 1364 | 1364 | ||
| 1365 | extern struct mutex resources_mutex; | 1365 | extern struct mutex resources_mutex; |
| 1366 | 1366 | ||
| 1367 | extern int conn_lowest_minor(struct drbd_connection *connection); | ||
| 1368 | extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor); | 1367 | extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor); |
| 1369 | extern void drbd_destroy_device(struct kref *kref); | 1368 | extern void drbd_destroy_device(struct kref *kref); |
| 1370 | extern void drbd_delete_device(struct drbd_device *device); | 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 | wait_for_completion(&thi->stop); | 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 | #ifdef CONFIG_SMP | 474 | #ifdef CONFIG_SMP |
| 489 | /* | 475 | /* |
| 490 | * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs | 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 | * TODO: provide forward progress for RECOVERY handler, so that | 2380 | * TODO: provide forward progress for RECOVERY handler, so that |
| 2381 | * unprivileged device can benefit from it | 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 | info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE | | 2384 | info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE | |
| 2385 | UBLK_F_USER_RECOVERY); | 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 | /* the created device is always owned by current user */ | 2396 | /* the created device is always owned by current user */ |
| 2388 | ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid); | 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 | if (!urb) | 1345 | if (!urb) |
| 1346 | return -ENOMEM; | 1346 | return -ENOMEM; |
| 1347 | 1347 | ||
| 1348 | /* Use maximum HCI Event size so the USB stack handles | 1348 | if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 && |
| 1349 | * ZPL/short-transfer automatically. | 1349 | le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001) |
| 1350 | */ | 1350 | /* Fake CSR devices don't seem to support sort-transter */ |
| 1351 | size = HCI_MAX_EVENT_SIZE; | 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 | buf = kmalloc(size, mem_flags); | 1358 | buf = kmalloc(size, mem_flags); |
| 1354 | if (!buf) { | 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 | BT_DBG("intf %p", intf); | 4047 | BT_DBG("intf %p", intf); |
| 4043 | 4048 | ||
| 4044 | /* Don't suspend if there are connections */ | 4049 | /* Don't auto-suspend if there are connections; external suspend calls |
| 4045 | if (hci_conn_count(data->hdev)) | 4050 | * shall never fail. |
| 4051 | */ | ||
| 4052 | if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev)) | ||
| 4046 | return -EBUSY; | 4053 | return -EBUSY; |
| 4047 | 4054 | ||
| 4048 | if (data->suspend_count++) | 4055 | if (data->suspend_count++) |
| @@ -2313,7 +2313,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, · 2312 unmodified lines | |||
| 2313 | return -EINVAL; | 2313 | return -EINVAL; |
| 2314 | 2314 | ||
| 2315 | /* Prevent arg from speculatively bypassing the length check */ | 2315 | /* Prevent arg from speculatively bypassing the length check */ |
| 2316 | barrier_nospec(); | 2316 | arg = array_index_nospec(arg, cdi->capacity); |
| 2317 | 2317 | ||
| 2318 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 2318 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
| 2319 | if (!info) | 2319 | if (!info) |
| @@ -2006,25 +2006,27 @@ static int virtcons_probe(struct virtio_device *vdev) · 2005 unmodified lines | |||
| 2006 | multiport = true; | 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 | spin_lock_init(&portdev->ports_lock); | 2009 | spin_lock_init(&portdev->ports_lock); |
| 2016 | INIT_LIST_HEAD(&portdev->ports); | 2010 | INIT_LIST_HEAD(&portdev->ports); |
| 2017 | INIT_LIST_HEAD(&portdev->list); | 2011 | INIT_LIST_HEAD(&portdev->list); |
| 2018 | 2012 | ||
| 2019 | virtio_device_ready(portdev->vdev); | ||
| 2020 | |||
| 2021 | INIT_WORK(&portdev->config_work, &config_work_handler); | 2013 | INIT_WORK(&portdev->config_work, &config_work_handler); |
| 2022 | INIT_WORK(&portdev->control_work, &control_work_handler); | 2014 | INIT_WORK(&portdev->control_work, &control_work_handler); |
| 2023 | 2015 | ||
| 2024 | if (multiport) { | 2016 | if (multiport) { |
| 2025 | spin_lock_init(&portdev->c_ivq_lock); | 2017 | spin_lock_init(&portdev->c_ivq_lock); |
| 2026 | spin_lock_init(&portdev->c_ovq_lock); | 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 | err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); | 2030 | err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); |
| 2029 | if (err < 0) { | 2031 | if (err < 0) { |
| 2030 | dev_err(&vdev->dev, | 2032 | dev_err(&vdev->dev, |
| @@ -473,7 +473,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 472 unmodified lines | |||
| 473 | &clk_dummy_rate_ops, | 473 | &clk_dummy_rate_ops, |
| 474 | 0); | 474 | 0); |
| 475 | ctx->parents_ctx[0].rate = DUMMY_CLOCK_RATE_1; | 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 | if (ret) | 477 | if (ret) |
| 478 | return ret; | 478 | return ret; |
| 479 | 479 | ||
| @@ -481,7 +481,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 1 unmodified line | |||
| 481 | &clk_dummy_rate_ops, | 481 | &clk_dummy_rate_ops, |
| 482 | 0); | 482 | 0); |
| 483 | ctx->parents_ctx[1].rate = DUMMY_CLOCK_RATE_2; | 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 | if (ret) | 485 | if (ret) |
| 486 | return ret; | 486 | return ret; |
| 487 | 487 | ||
| @@ -489,23 +489,13 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 1 unmodified line | |||
| 489 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-mux", parents, | 489 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-mux", parents, |
| 490 | &clk_multiple_parents_mux_ops, | 490 | &clk_multiple_parents_mux_ops, |
| 491 | CLK_SET_RATE_PARENT); | 491 | CLK_SET_RATE_PARENT); |
| 492 | ret = clk_hw_register(NULL, &ctx->hw); | 492 | ret = clk_hw_register_kunit(test, NULL, &ctx->hw); |
| 493 | if (ret) | 493 | if (ret) |
| 494 | return ret; | 494 | return ret; |
| 495 | 495 | ||
| 496 | return 0; | 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 | * Test that for a clock with multiple parents, clk_get_parent() | 500 | * Test that for a clock with multiple parents, clk_get_parent() |
| 511 | * actually returns the current one. | 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 | struct clk_multiple_parent_ctx *ctx = test->priv; | 552 | struct clk_multiple_parent_ctx *ctx = test->priv; |
| 563 | struct clk_hw *hw = &ctx->hw; | 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 | struct clk *parent1, *parent2; | 555 | struct clk *parent1, *parent2; |
| 566 | unsigned long rate; | 556 | unsigned long rate; |
| 567 | int ret; | 557 | int ret; |
| 568 | 558 | ||
| 569 | kunit_skip(test, "This needs to be fixed in the core."); | 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 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent1); | 562 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent1); |
| 573 | KUNIT_ASSERT_TRUE(test, clk_is_match(clk_get_parent(clk), parent1)); | 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 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent2); | 566 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent2); |
| 577 | 567 | ||
| 578 | ret = clk_set_rate(parent1, DUMMY_CLOCK_RATE_1); | 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 | KUNIT_ASSERT_GT(test, rate, 0); | 583 | KUNIT_ASSERT_GT(test, rate, 0); |
| 594 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1 - 1000); | 584 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1 - 1000); |
| 595 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_1 + 1000); | 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 | static struct kunit_case clk_multiple_parents_mux_test_cases[] = { | 588 | static struct kunit_case clk_multiple_parents_mux_test_cases[] = { |
| @@ -617,7 +603,6 @@ static struct kunit_suite · 14 unmodified lines | |||
| 617 | clk_multiple_parents_mux_test_suite = { | 603 | clk_multiple_parents_mux_test_suite = { |
| 618 | .name = "clk-multiple-parents-mux-test", | 604 | .name = "clk-multiple-parents-mux-test", |
| 619 | .init = clk_multiple_parents_mux_test_init, | 605 | .init = clk_multiple_parents_mux_test_init, |
| 620 | .exit = clk_multiple_parents_mux_test_exit, | ||
| 621 | .test_cases = clk_multiple_parents_mux_test_cases, | 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 | &clk_dummy_rate_ops, | 622 | &clk_dummy_rate_ops, |
| 638 | 0); | 623 | 0); |
| 639 | ctx->parents_ctx[1].rate = DUMMY_CLOCK_INIT_RATE; | 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 | if (ret) | 626 | if (ret) |
| 642 | return ret; | 627 | return ret; |
| 643 | 628 | ||
| 644 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-orphan-mux", parents, | 629 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-orphan-mux", parents, |
| 645 | &clk_multiple_parents_mux_ops, | 630 | &clk_multiple_parents_mux_ops, |
| 646 | CLK_SET_RATE_PARENT); | 631 | CLK_SET_RATE_PARENT); |
| 647 | ret = clk_hw_register(NULL, &ctx->hw); | 632 | ret = clk_hw_register_kunit(test, NULL, &ctx->hw); |
| 648 | if (ret) | 633 | if (ret) |
| 649 | return ret; | 634 | return ret; |
| 650 | 635 | ||
| 651 | return 0; | 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 | * Test that, for a mux whose current parent hasn't been registered yet and is | 640 | * Test that, for a mux whose current parent hasn't been registered yet and is |
| 665 | * thus orphan, clk_get_parent() will return NULL. | 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 | struct clk_multiple_parent_ctx *ctx = test->priv; | 889 | struct clk_multiple_parent_ctx *ctx = test->priv; |
| 914 | struct clk_hw *hw = &ctx->hw; | 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 | struct clk *parent; | 892 | struct clk *parent; |
| 917 | unsigned long rate; | 893 | unsigned long rate; |
| 918 | int ret; | 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 | clk_hw_set_rate_range(hw, DUMMY_CLOCK_RATE_1, DUMMY_CLOCK_RATE_2); | 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 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent); | 901 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent); |
| 926 | 902 | ||
| 927 | ret = clk_set_parent(clk, parent); | 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 | KUNIT_ASSERT_GT(test, rate, 0); | 907 | KUNIT_ASSERT_GT(test, rate, 0); |
| 932 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1); | 908 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1); |
| 933 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2); | 909 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2); |
| 934 | |||
| 935 | clk_put(parent); | ||
| 936 | clk_put(clk); | ||
| 937 | } | 910 | } |
| 938 | 911 | ||
| 939 | static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[] = { | 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 | static struct kunit_suite clk_orphan_transparent_multiple_parent_mux_test_suite = { | 934 | static struct kunit_suite clk_orphan_transparent_multiple_parent_mux_test_suite = { |
| 962 | .name = "clk-orphan-transparent-multiple-parent-mux-test", | 935 | .name = "clk-orphan-transparent-multiple-parent-mux-test", |
| 963 | .init = clk_orphan_transparent_multiple_parent_mux_test_init, | 936 | .init = clk_orphan_transparent_multiple_parent_mux_test_init, |
| 964 | .exit = clk_orphan_transparent_multiple_parent_mux_test_exit, | ||
| 965 | .test_cases = clk_orphan_transparent_multiple_parent_mux_test_cases, | 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 | &clk_dummy_rate_ops, | 958 | &clk_dummy_rate_ops, |
| 987 | 0); | 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 | if (ret) | 962 | if (ret) |
| 991 | return ret; | 963 | return ret; |
| 992 | 964 | ||
| @@ -994,7 +966,7 @@ static int clk_single_parent_mux_test_init(struct kunit *test) · 1 unmodified line | |||
| 994 | &clk_dummy_single_parent_ops, | 966 | &clk_dummy_single_parent_ops, |
| 995 | CLK_SET_RATE_PARENT); | 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 | if (ret) | 970 | if (ret) |
| 999 | return ret; | 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 | struct clk_single_parent_ctx *ctx = test->priv; | 1033 | struct clk_single_parent_ctx *ctx = test->priv; |
| 1062 | struct clk_hw *hw = &ctx->hw; | 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 | struct clk *parent; | 1036 | struct clk *parent; |
| 1065 | int ret; | 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 | ret = clk_set_rate_range(clk, 3000, 4000); | 1047 | ret = clk_set_rate_range(clk, 3000, 4000); |
| 1076 | KUNIT_EXPECT_LT(test, ret, 0); | 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 | struct clk_single_parent_ctx *ctx = test->priv; | 1063 | struct clk_single_parent_ctx *ctx = test->priv; |
| 1094 | struct clk_hw *hw = &ctx->hw; | 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 | struct clk *parent; | 1066 | struct clk *parent; |
| 1097 | int ret; | 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 | ret = clk_set_rate_range(parent, 3000, 4000); | 1077 | ret = clk_set_rate_range(parent, 3000, 4000); |
| 1108 | KUNIT_EXPECT_LT(test, ret, 0); | 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 | clk_single_parent_mux_test_suite = { | 1206 | clk_single_parent_mux_test_suite = { |
| 1239 | .name = "clk-single-parent-mux-test", | 1207 | .name = "clk-single-parent-mux-test", |
| 1240 | .init = clk_single_parent_mux_test_init, | 1208 | .init = clk_single_parent_mux_test_init, |
| 1241 | .exit = clk_single_parent_mux_test_exit, | ||
| 1242 | .test_cases = clk_single_parent_mux_test_cases, | 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 | if (list->id > max) | 439 | if (list->id > max) |
| 440 | max = list->id; | 440 | max = list->id; |
| 441 | if (list->child && list->child->id > max) | 441 | if (list->child && list->child->id > max) |
| 442 | max = list->id; | 442 | max = list->child->id; |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | return max; | 445 | return max; |
| @@ -1155,6 +1155,7 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { · 1154 unmodified lines | |||
| 1155 | .compatible = "samsung,exynosautov920-cmu-peric0", | 1155 | .compatible = "samsung,exynosautov920-cmu-peric0", |
| 1156 | .data = &peric0_cmu_info, | 1156 | .data = &peric0_cmu_info, |
| 1157 | }, | 1157 | }, |
| 1158 | { } | ||
| 1158 | }; | 1159 | }; |
| 1159 | 1160 | ||
| 1160 | static struct platform_driver exynosautov920_cmu_driver __refdata = { | 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 | static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy) | 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 | struct amd_cpudata *cpudata = policy->driver_data; | 540 | struct amd_cpudata *cpudata = policy->driver_data; |
| 541 | 541 | ||
| 542 | max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | 542 | if (cpudata->boost_supported && !policy->boost_enabled) |
| 543 | min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | 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 | lowest_perf = READ_ONCE(cpudata->lowest_perf); | 550 | lowest_perf = READ_ONCE(cpudata->lowest_perf); |
| 546 | if (min_limit_perf < lowest_perf) | 551 | if (min_limit_perf < lowest_perf) |
| @@ -1201,11 +1206,21 @@ static int amd_pstate_register_driver(int mode) · 654 unmodified lines | |||
| 1201 | return -EINVAL; | 1206 | return -EINVAL; |
| 1202 | 1207 | ||
| 1203 | cppc_state = mode; | 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 | ret = cpufreq_register_driver(current_pstate_driver); | 1218 | ret = cpufreq_register_driver(current_pstate_driver); |
| 1205 | if (ret) { | 1219 | if (ret) { |
| 1206 | amd_pstate_driver_cleanup(); | 1220 | amd_pstate_driver_cleanup(); |
| 1207 | return ret; | 1221 | return ret; |
| 1208 | } | 1222 | } |
| 1223 | |||
| 1209 | return 0; | 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 | u64 value; | 1511 | u64 value; |
| 1497 | s16 epp; | 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 | min_perf = READ_ONCE(cpudata->lowest_perf); | 1518 | min_perf = READ_ONCE(cpudata->lowest_perf); |
| 1501 | max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | 1519 | max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq); |
| 1502 | min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | 1520 | min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq); |
| 1503 | 1521 | ||
| 1504 | if (min_limit_perf < min_perf) | 1522 | if (min_limit_perf < min_perf) |
| 1505 | min_limit_perf = min_perf; | 1523 | min_limit_perf = min_perf; |
| @@ -1845,7 +1845,7 @@ static void intel_pstate_notify_work(struct work_struct *work) · 1844 unmodified lines | |||
| 1845 | wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0); | 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 | static cpumask_t hwp_intr_enable_mask; | 1849 | static cpumask_t hwp_intr_enable_mask; |
| 1850 | 1850 | ||
| 1851 | #define HWP_GUARANTEED_PERF_CHANGE_STATUS BIT(0) | 1851 | #define HWP_GUARANTEED_PERF_CHANGE_STATUS BIT(0) |
| @@ -1868,7 +1868,7 @@ void notify_hwp_interrupt(void) · 16 unmodified lines | |||
| 1868 | if (!(value & status_mask)) | 1868 | if (!(value & status_mask)) |
| 1869 | return; | 1869 | return; |
| 1870 | 1870 | ||
| 1871 | spin_lock_irqsave(&hwp_notify_lock, flags); | 1871 | raw_spin_lock_irqsave(&hwp_notify_lock, flags); |
| 1872 | 1872 | ||
| 1873 | if (!cpumask_test_cpu(this_cpu, &hwp_intr_enable_mask)) | 1873 | if (!cpumask_test_cpu(this_cpu, &hwp_intr_enable_mask)) |
| 1874 | goto ack_intr; | 1874 | goto ack_intr; |
| @@ -1876,13 +1876,13 @@ void notify_hwp_interrupt(void) · 1 unmodified line | |||
| 1876 | schedule_delayed_work(&all_cpu_data[this_cpu]->hwp_notify_work, | 1876 | schedule_delayed_work(&all_cpu_data[this_cpu]->hwp_notify_work, |
| 1877 | msecs_to_jiffies(10)); | 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 | return; | 1881 | return; |
| 1882 | 1882 | ||
| 1883 | ack_intr: | 1883 | ack_intr: |
| 1884 | wrmsrl_safe(MSR_HWP_STATUS, 0); | 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 | static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata) | 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 | /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */ | 1895 | /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */ |
| 1896 | wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00); | 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 | cancel_work = cpumask_test_and_clear_cpu(cpudata->cpu, &hwp_intr_enable_mask); | 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 | if (cancel_work) | 1902 | if (cancel_work) |
| 1903 | cancel_delayed_work_sync(&cpudata->hwp_notify_work); | 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 | if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) { | 1912 | if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) { |
| 1913 | u64 interrupt_mask = HWP_GUARANTEED_PERF_CHANGE_REQ; | 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 | INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work); | 1916 | INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work); |
| 1917 | cpumask_set_cpu(cpudata->cpu, &hwp_intr_enable_mask); | 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 | if (cpu_feature_enabled(X86_FEATURE_HWP_HIGHEST_PERF_CHANGE)) | 1920 | if (cpu_feature_enabled(X86_FEATURE_HWP_HIGHEST_PERF_CHANGE)) |
| 1921 | interrupt_mask |= HWP_HIGHEST_PERF_CHANGE_REQ; | 1921 | interrupt_mask |= HWP_HIGHEST_PERF_CHANGE_REQ; |
| @@ -947,7 +947,7 @@ struct ahash_alg mv_md5_alg = { · 946 unmodified lines | |||
| 947 | .base = { | 947 | .base = { |
| 948 | .cra_name = "md5", | 948 | .cra_name = "md5", |
| 949 | .cra_driver_name = "mv-md5", | 949 | .cra_driver_name = "mv-md5", |
| 950 | .cra_priority = 300, | 950 | .cra_priority = 0, |
| 951 | .cra_flags = CRYPTO_ALG_ASYNC | | 951 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 952 | CRYPTO_ALG_ALLOCATES_MEMORY | | 952 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 953 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 953 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1018,7 +1018,7 @@ struct ahash_alg mv_sha1_alg = { · 64 unmodified lines | |||
| 1018 | .base = { | 1018 | .base = { |
| 1019 | .cra_name = "sha1", | 1019 | .cra_name = "sha1", |
| 1020 | .cra_driver_name = "mv-sha1", | 1020 | .cra_driver_name = "mv-sha1", |
| 1021 | .cra_priority = 300, | 1021 | .cra_priority = 0, |
| 1022 | .cra_flags = CRYPTO_ALG_ASYNC | | 1022 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1023 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1023 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1024 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1024 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1092,7 +1092,7 @@ struct ahash_alg mv_sha256_alg = { · 67 unmodified lines | |||
| 1092 | .base = { | 1092 | .base = { |
| 1093 | .cra_name = "sha256", | 1093 | .cra_name = "sha256", |
| 1094 | .cra_driver_name = "mv-sha256", | 1094 | .cra_driver_name = "mv-sha256", |
| 1095 | .cra_priority = 300, | 1095 | .cra_priority = 0, |
| 1096 | .cra_flags = CRYPTO_ALG_ASYNC | | 1096 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1097 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1097 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1098 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1098 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1302,7 +1302,7 @@ struct ahash_alg mv_ahmac_md5_alg = { · 203 unmodified lines | |||
| 1302 | .base = { | 1302 | .base = { |
| 1303 | .cra_name = "hmac(md5)", | 1303 | .cra_name = "hmac(md5)", |
| 1304 | .cra_driver_name = "mv-hmac-md5", | 1304 | .cra_driver_name = "mv-hmac-md5", |
| 1305 | .cra_priority = 300, | 1305 | .cra_priority = 0, |
| 1306 | .cra_flags = CRYPTO_ALG_ASYNC | | 1306 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1307 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1307 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1308 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1308 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1373,7 +1373,7 @@ struct ahash_alg mv_ahmac_sha1_alg = { · 64 unmodified lines | |||
| 1373 | .base = { | 1373 | .base = { |
| 1374 | .cra_name = "hmac(sha1)", | 1374 | .cra_name = "hmac(sha1)", |
| 1375 | .cra_driver_name = "mv-hmac-sha1", | 1375 | .cra_driver_name = "mv-hmac-sha1", |
| 1376 | .cra_priority = 300, | 1376 | .cra_priority = 0, |
| 1377 | .cra_flags = CRYPTO_ALG_ASYNC | | 1377 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1378 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1378 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1379 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1379 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1444,7 +1444,7 @@ struct ahash_alg mv_ahmac_sha256_alg = { · 64 unmodified lines | |||
| 1444 | .base = { | 1444 | .base = { |
| 1445 | .cra_name = "hmac(sha256)", | 1445 | .cra_name = "hmac(sha256)", |
| 1446 | .cra_driver_name = "mv-hmac-sha256", | 1446 | .cra_driver_name = "mv-hmac-sha256", |
| 1447 | .cra_priority = 300, | 1447 | .cra_priority = 0, |
| 1448 | .cra_flags = CRYPTO_ALG_ASYNC | | 1448 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1449 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1449 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1450 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 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 | nr_pages = 1; | 86 | nr_pages = 1; |
| 87 | 87 | ||
| 88 | pgoff = linear_page_index(vmf->vma, | 88 | pgoff = linear_page_index(vmf->vma, |
| 89 | ALIGN(vmf->address, fault_size)); | 89 | ALIGN_DOWN(vmf->address, fault_size)); |
| 90 | 90 | ||
| 91 | for (i = 0; i < nr_pages; i++) { | 91 | for (i = 0; i < nr_pages; i++) { |
| 92 | struct page *page = pfn_to_page(pfn_t_to_pfn(pfn) + i); | 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 | INIT_LIST_HEAD(&dma_dev->channels); | 1391 | INIT_LIST_HEAD(&dma_dev->channels); |
| 1392 | for (i = 0; i < edma->num_channels; i++) { | 1392 | for (i = 0; i < edma->num_channels; i++) { |
| 1393 | struct ep93xx_dma_chan *edmac = &edma->channels[i]; | 1393 | struct ep93xx_dma_chan *edmac = &edma->channels[i]; |
| 1394 | int len; | ||
| 1394 | 1395 | ||
| 1395 | edmac->chan.device = dma_dev; | 1396 | edmac->chan.device = dma_dev; |
| 1396 | edmac->regs = devm_platform_ioremap_resource(pdev, i); | 1397 | edmac->regs = devm_platform_ioremap_resource(pdev, i); |
| 1397 | if (IS_ERR(edmac->regs)) | 1398 | if (IS_ERR(edmac->regs)) |
| 1398 | return edmac->regs; | 1399 | return ERR_CAST(edmac->regs); |
| 1399 | 1400 | ||
| 1400 | edmac->irq = fwnode_irq_get(dev_fwnode(dev), i); | 1401 | edmac->irq = fwnode_irq_get(dev_fwnode(dev), i); |
| 1401 | if (edmac->irq < 0) | 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 | edmac->edma = edma; | 1405 | edmac->edma = edma; |
| 1405 | 1406 | ||
| 1406 | if (edma->m2m) | 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 | else | 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 | edmac->clk = devm_clk_get(dev, dma_clk_name); | 1414 | edmac->clk = devm_clk_get(dev, dma_clk_name); |
| 1412 | if (IS_ERR(edmac->clk)) { | 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 | struct ffa_send_direct_data2 *data) | 481 | struct ffa_send_direct_data2 *data) |
| 482 | { | 482 | { |
| 483 | u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id); | 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 | ffa_value_t ret, args = { | 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 | memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data)); | 494 | memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data)); |
| 490 | 495 | ||
| 491 | invoke_ffa_fn(args, &ret); | 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 | return ffa_to_linux_errno((int)ret.a2); | 501 | return ffa_to_linux_errno((int)ret.a2); |
| 497 | 502 | ||
| 498 | if (ret.a0 == FFA_MSG_SEND_DIRECT_RESP2) { | 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 | return 0; | 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 | dbg->top_dentry = top_dentry; | 2976 | dbg->top_dentry = top_dentry; |
| 2977 | 2977 | ||
| 2978 | if (devm_add_action_or_reset(info->dev, | 2978 | if (devm_add_action_or_reset(info->dev, |
| 2979 | scmi_debugfs_common_cleanup, dbg)) { | 2979 | scmi_debugfs_common_cleanup, dbg)) |
| 2980 | scmi_debugfs_common_cleanup(dbg); | ||
| 2981 | return NULL; | 2980 | return NULL; |
| 2982 | } | ||
| 2983 | 2981 | ||
| 2984 | return dbg; | 2982 | return dbg; |
| 2985 | } | 2983 | } |
| @@ -1,8 +1,10 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | scmi_transport_mailbox-objs := mailbox.o | 2 | # Keep before scmi_transport_mailbox.o to allow precedence |
| 3 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o | 3 | # while matching the compatible. |
| 4 | scmi_transport_smc-objs := smc.o | 4 | scmi_transport_smc-objs := smc.o |
| 5 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += scmi_transport_smc.o | 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 | scmi_transport_optee-objs := optee.o | 8 | scmi_transport_optee-objs := optee.o |
| 7 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o | 9 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o |
| 8 | scmi_transport_virtio-objs := virtio.o | 10 | scmi_transport_virtio-objs := virtio.o |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 25 | * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel | 25 | * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel |
| 26 | * @cinfo: SCMI channel info | 26 | * @cinfo: SCMI channel info |
| 27 | * @shmem: Transmit/Receive shared memory area | 27 | * @shmem: Transmit/Receive shared memory area |
| 28 | * @chan_lock: Lock that prevents multiple xfers from being queued | ||
| 28 | */ | 29 | */ |
| 29 | struct scmi_mailbox { | 30 | struct scmi_mailbox { |
| 30 | struct mbox_client cl; | 31 | struct mbox_client cl; |
| @@ -33,6 +34,7 @@ struct scmi_mailbox { · 2 unmodified lines | |||
| 33 | struct mbox_chan *chan_platform_receiver; | 34 | struct mbox_chan *chan_platform_receiver; |
| 34 | struct scmi_chan_info *cinfo; | 35 | struct scmi_chan_info *cinfo; |
| 35 | struct scmi_shared_mem __iomem *shmem; | 36 | struct scmi_shared_mem __iomem *shmem; |
| 37 | struct mutex chan_lock; | ||
| 36 | }; | 38 | }; |
| 37 | 39 | ||
| 38 | #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl) | 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 | cinfo->transport_info = smbox; | 241 | cinfo->transport_info = smbox; |
| 240 | smbox->cinfo = cinfo; | 242 | smbox->cinfo = cinfo; |
| 243 | mutex_init(&smbox->chan_lock); | ||
| 241 | 244 | ||
| 242 | return 0; | 245 | return 0; |
| 243 | } | 246 | } |
| @@ -267,13 +270,23 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo, · 23 unmodified lines | |||
| 267 | struct scmi_mailbox *smbox = cinfo->transport_info; | 270 | struct scmi_mailbox *smbox = cinfo->transport_info; |
| 268 | int ret; | 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 */ | 282 | ret = mbox_send_message(smbox->chan, xfer); |
| 273 | if (ret > 0) | 283 | /* mbox_send_message returns non-negative value on success */ |
| 274 | ret = 0; | 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 | static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret, | 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 | struct scmi_mailbox *smbox = cinfo->transport_info; | 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 | mbox_client_txdone(smbox->chan, ret); | 297 | mbox_client_txdone(smbox->chan, ret); |
| 298 | |||
| 299 | /* Release channel */ | ||
| 300 | mutex_unlock(&smbox->chan_lock); | ||
| 291 | } | 301 | } |
| 292 | 302 | ||
| 293 | static void mailbox_fetch_response(struct scmi_chan_info *cinfo, | 303 | static void mailbox_fetch_response(struct scmi_chan_info *cinfo, |
| @@ -67,9 +67,11 @@ static bool sysfb_unregister(void) · 66 unmodified lines | |||
| 67 | void sysfb_disable(struct device *dev) | 67 | void sysfb_disable(struct device *dev) |
| 68 | { | 68 | { |
| 69 | struct screen_info *si = &screen_info; | 69 | struct screen_info *si = &screen_info; |
| 70 | struct device *parent; | ||
| 70 | 71 | ||
| 71 | mutex_lock(&disable_lock); | 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 | sysfb_unregister(); | 75 | sysfb_unregister(); |
| 74 | disabled = true; | 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 | gpio->dcache[GPIO_BANK(offset)] = reg; | 406 | gpio->dcache[GPIO_BANK(offset)] = reg; |
| 407 | 407 | ||
| 408 | iowrite32(reg, addr); | 408 | iowrite32(reg, addr); |
| 409 | /* Flush write */ | ||
| 410 | ioread32(addr); | ||
| 409 | } | 411 | } |
| 410 | 412 | ||
| 411 | static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, | 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 | if (!gpio_id) | 1193 | if (!gpio_id) |
| 1192 | return -EINVAL; | 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 | if (IS_ERR(gpio->clk)) { | 1197 | if (IS_ERR(gpio->clk)) { |
| 1196 | dev_warn(&pdev->dev, | 1198 | dev_warn(&pdev->dev, |
| 1197 | "Failed to get clock from devicetree, debouncing disabled\n"); | 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 | * serve as EDMA event triggers. | 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 | struct davinci_gpio_regs __iomem *g = irq2regs(d); | 258 | struct davinci_gpio_regs __iomem *g = irq2regs(d); |
| 259 | uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); | 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 | writel_relaxed(mask, &g->clr_rising); | 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 | struct davinci_gpio_regs __iomem *g = irq2regs(d); | 267 | struct davinci_gpio_regs __iomem *g = irq2regs(d); |
| 268 | uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); | 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 | static struct irq_chip gpio_irqchip = { | 289 | static struct irq_chip gpio_irqchip = { |
| 290 | .name = "GPIO", | 290 | .name = "GPIO", |
| 291 | .irq_enable = gpio_irq_enable, | 291 | .irq_unmask = gpio_irq_unmask, |
| 292 | .irq_disable = gpio_irq_disable, | 292 | .irq_mask = gpio_irq_mask, |
| 293 | .irq_set_type = gpio_irq_type, | 293 | .irq_set_type = gpio_irq_type, |
| 294 | .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE, | 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 | return PTR_ERR(clk); | 472 | return PTR_ERR(clk); |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | if (chips->gpio_unbanked) { | 475 | if (!chips->gpio_unbanked) { |
| 476 | irq = devm_irq_alloc_descs(dev, -1, 0, ngpio, 0); | 476 | irq = devm_irq_alloc_descs(dev, -1, 0, ngpio, 0); |
| 477 | if (irq < 0) { | 477 | if (irq < 0) { |
| 478 | dev_err(dev, "Couldn't allocate IRQ numbers\n"); | 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 | srcu_read_lock_held(&desc->gdev->desc_srcu)); | 114 | srcu_read_lock_held(&desc->gdev->desc_srcu)); |
| 115 | 115 | ||
| 116 | if (test_bit(FLAG_USED_AS_IRQ, &flags)) | 116 | if (test_bit(FLAG_USED_AS_IRQ, &flags)) |
| 117 | return label->str ?: "interrupt"; | 117 | return label ? label->str : "interrupt"; |
| 118 | 118 | ||
| 119 | if (!test_bit(FLAG_REQUESTED, &flags)) | 119 | if (!test_bit(FLAG_REQUESTED, &flags)) |
| 120 | return NULL; | 120 | return NULL; |
| 121 | 121 | ||
| 122 | return label->str; | 122 | return label ? label->str : NULL; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | static void desc_free_label(struct rcu_head *rh) | 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 | list_add_tail(&vm->vm_list_node, | 1439 | list_add_tail(&vm->vm_list_node, |
| 1440 | &(vm->process_info->vm_list_head)); | 1440 | &(vm->process_info->vm_list_head)); |
| 1441 | vm->process_info->n_vms++; | 1441 | vm->process_info->n_vms++; |
| 1442 | 1442 | if (ef) | |
| 1443 | *ef = dma_fence_get(&vm->process_info->eviction_fence->base); | 1443 | *ef = dma_fence_get(&vm->process_info->eviction_fence->base); |
| 1444 | mutex_unlock(&vm->process_info->lock); | 1444 | mutex_unlock(&vm->process_info->lock); |
| 1445 | 1445 | ||
| 1446 | return 0; | 1446 | return 0; |
| @@ -265,7 +265,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, · 264 unmodified lines | |||
| 265 | 265 | ||
| 266 | /* Only a single BO list is allowed to simplify handling. */ | 266 | /* Only a single BO list is allowed to simplify handling. */ |
| 267 | if (p->bo_list) | 267 | if (p->bo_list) |
| 268 | ret = -EINVAL; | 268 | goto free_partial_kdata; |
| 269 | 269 | ||
| 270 | ret = amdgpu_cs_p1_bo_handles(p, p->chunks[i].kdata); | 270 | ret = amdgpu_cs_p1_bo_handles(p, p->chunks[i].kdata); |
| 271 | if (ret) | 271 | if (ret) |
| @@ -1635,11 +1635,9 @@ int amdgpu_gfx_sysfs_isolation_shader_init(struct amdgpu_device *adev) · 1634 unmodified lines | |||
| 1635 | { | 1635 | { |
| 1636 | int r; | 1636 | int r; |
| 1637 | 1637 | ||
| 1638 | if (!amdgpu_sriov_vf(adev)) { | 1638 | r = device_create_file(adev->dev, &dev_attr_enforce_isolation); |
| 1639 | r = device_create_file(adev->dev, &dev_attr_enforce_isolation); | 1639 | if (r) |
| 1640 | if (r) | 1640 | return r; |
| 1641 | return r; | ||
| 1642 | } | ||
| 1643 | 1641 | ||
| 1644 | r = device_create_file(adev->dev, &dev_attr_run_cleaner_shader); | 1642 | r = device_create_file(adev->dev, &dev_attr_run_cleaner_shader); |
| 1645 | if (r) | 1643 | if (r) |
| @@ -1650,8 +1648,7 @@ int amdgpu_gfx_sysfs_isolation_shader_init(struct amdgpu_device *adev) · 4 unmodified lines | |||
| 1650 | 1648 | ||
| 1651 | void amdgpu_gfx_sysfs_isolation_shader_fini(struct amdgpu_device *adev) | 1649 | void amdgpu_gfx_sysfs_isolation_shader_fini(struct amdgpu_device *adev) |
| 1652 | { | 1650 | { |
| 1653 | if (!amdgpu_sriov_vf(adev)) | 1651 | device_remove_file(adev->dev, &dev_attr_enforce_isolation); |
| 1654 | device_remove_file(adev->dev, &dev_attr_enforce_isolation); | ||
| 1655 | device_remove_file(adev->dev, &dev_attr_run_cleaner_shader); | 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 | r = amdgpu_ring_init(adev, ring, 1024, NULL, 0, | 1204 | r = amdgpu_ring_init(adev, ring, 1024, NULL, 0, |
| 1205 | AMDGPU_RING_PRIO_DEFAULT, NULL); | 1205 | AMDGPU_RING_PRIO_DEFAULT, NULL); |
| 1206 | if (r) | 1206 | if (r) { |
| 1207 | amdgpu_mes_unlock(&adev->mes); | ||
| 1207 | goto clean_up_memory; | 1208 | goto clean_up_memory; |
| 1209 | } | ||
| 1208 | 1210 | ||
| 1209 | amdgpu_mes_ring_to_queue_props(adev, ring, &qprops); | 1211 | amdgpu_mes_ring_to_queue_props(adev, ring, &qprops); |
| 1210 | 1212 | ||
| @@ -1237,7 +1239,6 @@ clean_up_ring: · 26 unmodified lines | |||
| 1237 | amdgpu_ring_fini(ring); | 1239 | amdgpu_ring_fini(ring); |
| 1238 | clean_up_memory: | 1240 | clean_up_memory: |
| 1239 | kfree(ring); | 1241 | kfree(ring); |
| 1240 | amdgpu_mes_unlock(&adev->mes); | ||
| 1241 | return r; | 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 | if (amdgpu_mes_log_enable) { | 622 | if (amdgpu_mes_log_enable) { |
| 623 | mes_set_hw_res_pkt.enable_mes_event_int_logging = 1; | 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 | return mes_v12_0_submit_pkt_and_poll_completion(mes, pipe, | 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 | adev->mes.kiq_hw_fini = &mes_v12_0_kiq_hw_fini; | 1336 | adev->mes.kiq_hw_fini = &mes_v12_0_kiq_hw_fini; |
| 1337 | adev->mes.enable_legacy_queue_map = true; | 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 | r = amdgpu_mes_init(adev); | 1341 | r = amdgpu_mes_init(adev); |
| 1342 | if (r) | 1342 | if (r) |
| @@ -1148,7 +1148,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, · 1147 unmodified lines | |||
| 1148 | 1148 | ||
| 1149 | if (flags & KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM) | 1149 | if (flags & KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM) |
| 1150 | size >>= 1; | 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 | mutex_unlock(&p->mutex); | 1154 | mutex_unlock(&p->mutex); |
| @@ -1219,7 +1219,7 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep, · 64 unmodified lines | |||
| 1219 | kfd_process_device_remove_obj_handle( | 1219 | kfd_process_device_remove_obj_handle( |
| 1220 | pdd, GET_IDR_HANDLE(args->handle)); | 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 | err_unlock: | 1224 | err_unlock: |
| 1225 | err_pdd: | 1225 | err_pdd: |
| @@ -2347,7 +2347,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd, · 1121 unmodified lines | |||
| 2347 | } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) { | 2347 | } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) { |
| 2348 | bo_bucket->restored_offset = offset; | 2348 | bo_bucket->restored_offset = offset; |
| 2349 | /* Update the VRAM usage count */ | 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 | return 0; | 2352 | return 0; |
| 2353 | } | 2353 | } |
| @@ -775,7 +775,7 @@ struct kfd_process_device { · 774 unmodified lines | |||
| 775 | enum kfd_pdd_bound bound; | 775 | enum kfd_pdd_bound bound; |
| 776 | 776 | ||
| 777 | /* VRAM usage */ | 777 | /* VRAM usage */ |
| 778 | uint64_t vram_usage; | 778 | atomic64_t vram_usage; |
| 779 | struct attribute attr_vram; | 779 | struct attribute attr_vram; |
| 780 | char vram_filename[MAX_SYSFS_FILENAME_LEN]; | 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 | } else if (strncmp(attr->name, "vram_", 5) == 0) { | 332 | } else if (strncmp(attr->name, "vram_", 5) == 0) { |
| 333 | struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device, | 333 | struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device, |
| 334 | attr_vram); | 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 | } else if (strncmp(attr->name, "sdma_", 5) == 0) { | 336 | } else if (strncmp(attr->name, "sdma_", 5) == 0) { |
| 337 | struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device, | 337 | struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device, |
| 338 | attr_sdma); | 338 | attr_sdma); |
| @@ -1625,7 +1625,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_node *dev, · 1286 unmodified lines | |||
| 1625 | pdd->bound = PDD_UNBOUND; | 1625 | pdd->bound = PDD_UNBOUND; |
| 1626 | pdd->already_dequeued = false; | 1626 | pdd->already_dequeued = false; |
| 1627 | pdd->runtime_inuse = false; | 1627 | pdd->runtime_inuse = false; |
| 1628 | pdd->vram_usage = 0; | 1628 | atomic64_set(&pdd->vram_usage, 0); |
| 1629 | pdd->sdma_past_activity_counter = 0; | 1629 | pdd->sdma_past_activity_counter = 0; |
| 1630 | pdd->user_gpu_id = dev->id; | 1630 | pdd->user_gpu_id = dev->id; |
| 1631 | atomic64_set(&pdd->evict_duration_counter, 0); | 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 | ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(dev->adev, avm, | 1703 | ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(dev->adev, avm, |
| 1704 | &p->kgd_process_info, | 1704 | &p->kgd_process_info, |
| 1705 | &ef); | 1705 | p->ef ? NULL : &ef); |
| 1706 | if (ret) { | 1706 | if (ret) { |
| 1707 | dev_err(dev->adev->dev, "Failed to create process VM object\n"); | 1707 | dev_err(dev->adev->dev, "Failed to create process VM object\n"); |
| 1708 | return ret; | 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 | pdd->drm_priv = drm_file->private_data; | 1714 | pdd->drm_priv = drm_file->private_data; |
| 1712 | 1715 | ||
| 1713 | ret = kfd_process_device_reserve_ib_mem(pdd); | 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 | spin_lock(&svm_bo->list_lock); | 405 | spin_lock(&svm_bo->list_lock); |
| 406 | } | 406 | } |
| 407 | spin_unlock(&svm_bo->list_lock); | 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 | if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) | 429 | if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) |
| 409 | /* We're not in the eviction worker. Signal the fence. */ | 430 | /* We're not in the eviction worker. Signal the fence. */ |
| 410 | dma_fence_signal(&svm_bo->eviction_fence->base); | 431 | dma_fence_signal(&svm_bo->eviction_fence->base); |
| @@ -532,6 +553,7 @@ int · 121 unmodified lines | |||
| 532 | svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange, | 553 | svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange, |
| 533 | bool clear) | 554 | bool clear) |
| 534 | { | 555 | { |
| 556 | struct kfd_process_device *pdd; | ||
| 535 | struct amdgpu_bo_param bp; | 557 | struct amdgpu_bo_param bp; |
| 536 | struct svm_range_bo *svm_bo; | 558 | struct svm_range_bo *svm_bo; |
| 537 | struct amdgpu_bo_user *ubo; | 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 | list_add(&prange->svm_bo_list, &svm_bo->range_list); | 645 | list_add(&prange->svm_bo_list, &svm_bo->range_list); |
| 624 | spin_unlock(&svm_bo->list_lock); | 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 | return 0; | 652 | return 0; |
| 627 | 653 | ||
| 628 | reserve_bo_failed: | 654 | reserve_bo_failed: |
| @@ -770,6 +770,12 @@ static void dmub_hpd_callback(struct amdgpu_device *adev, · 769 unmodified lines | |||
| 770 | return; | 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 | link_index = notify->link_index; | 779 | link_index = notify->link_index; |
| 774 | link = adev->dm.dc->links[link_index]; | 780 | link = adev->dm.dc->links[link_index]; |
| 775 | dev = adev->dm.ddev; | 781 | dev = adev->dm.ddev; |
| @@ -2026,7 +2032,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 1250 unmodified lines | |||
| 2026 | DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n"); | 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 | adev->dm.idle_workqueue = idle_create_workqueue(adev); | 2037 | adev->dm.idle_workqueue = idle_create_workqueue(adev); |
| 2031 | 2038 | ||
| 2032 | if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) { | 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 | hpd_rx_irq_work_suspend(dm); | 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 | dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3); | 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 | dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D3); | 2980 | dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D3); |
| 2973 | 2981 | ||
| 2974 | return 0; | 2982 | return 0; |
| @@ -6735,12 +6743,21 @@ create_stream_for_sink(struct drm_connector *connector, · 3760 unmodified lines | |||
| 6735 | if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || | 6743 | if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || |
| 6736 | stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST || | 6744 | stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST || |
| 6737 | stream->signal == SIGNAL_TYPE_EDP) { | 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 | // should decide stream support vsc sdp colorimetry capability | 6755 | // should decide stream support vsc sdp colorimetry capability |
| 6740 | // before building vsc info packet | 6756 | // before building vsc info packet |
| 6741 | // | 6757 | // |
| 6742 | stream->use_vsc_sdp_for_colorimetry = stream->link->dpcd_caps.dpcd_rev.raw >= 0x14 && | 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 | if (stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22) | 6762 | if (stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22) |
| 6746 | tf = TRANSFER_FUNC_GAMMA_22; | 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 | DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id); | 73 | DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id); |
| 74 | edid_caps->panel_patch.remove_sink_ext_caps = true; | 74 | edid_caps->panel_patch.remove_sink_ext_caps = true; |
| 75 | break; | 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 | default: | 80 | default: |
| 77 | return; | 81 | return; |
| 78 | } | 82 | } |
| @@ -1027,6 +1027,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, · 1026 unmodified lines | |||
| 1027 | int remaining_to_try = 0; | 1027 | int remaining_to_try = 0; |
| 1028 | int ret; | 1028 | int ret; |
| 1029 | uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); | 1029 | uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); |
| 1030 | int var_pbn; | ||
| 1030 | 1031 | ||
| 1031 | for (i = 0; i < count; i++) { | 1032 | for (i = 0; i < count; i++) { |
| 1032 | if (vars[i + k].dsc_enabled | 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 | break; | 1058 | break; |
| 1058 | 1059 | ||
| 1059 | DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index); | 1060 | DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index); |
| 1061 | var_pbn = vars[next_index].pbn; | ||
| 1060 | vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000); | 1062 | vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000); |
| 1061 | ret = drm_dp_atomic_find_time_slots(state, | 1063 | ret = drm_dp_atomic_find_time_slots(state, |
| 1062 | params[next_index].port->mgr, | 1064 | params[next_index].port->mgr, |
| 1063 | params[next_index].port, | 1065 | params[next_index].port, |
| 1064 | vars[next_index].pbn); | 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 | return ret; | 1071 | return ret; |
| 1072 | } | ||
| 1067 | 1073 | ||
| 1068 | ret = drm_dp_mst_atomic_check(state); | 1074 | ret = drm_dp_mst_atomic_check(state); |
| 1069 | if (ret == 0) { | 1075 | if (ret == 0) { |
| @@ -1071,14 +1077,17 @@ static int try_disable_dsc(struct drm_atomic_state *state, · 1 unmodified line | |||
| 1071 | vars[next_index].dsc_enabled = false; | 1077 | vars[next_index].dsc_enabled = false; |
| 1072 | vars[next_index].bpp_x16 = 0; | 1078 | vars[next_index].bpp_x16 = 0; |
| 1073 | } else { | 1079 | } else { |
| 1074 | DRM_DEBUG_DRIVER("MST_DSC index #%d, restore minimum compression\n", next_index); | 1080 | DRM_DEBUG_DRIVER("MST_DSC index #%d, restore optimized pbn value\n", next_index); |
| 1075 | vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000); | 1081 | vars[next_index].pbn = var_pbn; |
| 1076 | ret = drm_dp_atomic_find_time_slots(state, | 1082 | ret = drm_dp_atomic_find_time_slots(state, |
| 1077 | params[next_index].port->mgr, | 1083 | params[next_index].port->mgr, |
| 1078 | params[next_index].port, | 1084 | params[next_index].port, |
| 1079 | vars[next_index].pbn); | 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 | return ret; | 1089 | return ret; |
| 1090 | } | ||
| 1082 | } | 1091 | } |
| 1083 | 1092 | ||
| 1084 | tried[next_index] = true; | 1093 | tried[next_index] = true; |
| @@ -5065,11 +5065,26 @@ static bool update_planes_and_stream_v3(struct dc *dc, · 5064 unmodified lines | |||
| 5065 | return true; | 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 | bool dc_update_planes_and_stream(struct dc *dc, | 5081 | bool dc_update_planes_and_stream(struct dc *dc, |
| 5069 | struct dc_surface_update *srf_updates, int surface_count, | 5082 | struct dc_surface_update *srf_updates, int surface_count, |
| 5070 | struct dc_stream_state *stream, | 5083 | struct dc_stream_state *stream, |
| 5071 | struct dc_stream_update *stream_update) | 5084 | struct dc_stream_update *stream_update) |
| 5072 | { | 5085 | { |
| 5086 | bool ret = false; | ||
| 5087 | |||
| 5073 | dc_exit_ips_for_hw_access(dc); | 5088 | dc_exit_ips_for_hw_access(dc); |
| 5074 | /* | 5089 | /* |
| 5075 | * update planes and stream version 3 separates FULL and FAST updates | 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 | * features as they are now transparent to the new sequence. | 5101 | * features as they are now transparent to the new sequence. |
| 5087 | */ | 5102 | */ |
| 5088 | if (dc->ctx->dce_version >= DCN_VERSION_4_01) | 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 | surface_count, stream, stream_update); | 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 | surface_count, stream, stream_update); | 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 | void dc_commit_updates_for_stream(struct dc *dc, | 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 | struct dc_stream_update *stream_update, | 5120 | struct dc_stream_update *stream_update, |
| 5100 | struct dc_state *state) | 5121 | struct dc_state *state) |
| 5101 | { | 5122 | { |
| 5123 | bool ret = false; | ||
| 5124 | |||
| 5102 | dc_exit_ips_for_hw_access(dc); | 5125 | dc_exit_ips_for_hw_access(dc); |
| 5103 | /* TODO: Since change commit sequence can have a huge impact, | 5126 | /* TODO: Since change commit sequence can have a huge impact, |
| 5104 | * we decided to only enable it for DCN3x. However, as soon as | 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 | * the new sequence for all ASICs. | 5129 | * the new sequence for all ASICs. |
| 5107 | */ | 5130 | */ |
| 5108 | if (dc->ctx->dce_version >= DCN_VERSION_4_01) { | 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 | stream, stream_update); | 5133 | stream, stream_update); |
| 5111 | return; | 5134 | } else if (dc->ctx->dce_version >= DCN_VERSION_3_2) { |
| 5112 | } | 5135 | ret = update_planes_and_stream_v2(dc, srf_updates, surface_count, |
| 5113 | if (dc->ctx->dce_version >= DCN_VERSION_3_2) { | ||
| 5114 | update_planes_and_stream_v2(dc, srf_updates, surface_count, | ||
| 5115 | stream, stream_update); | 5136 | stream, stream_update); |
| 5116 | return; | 5137 | } else |
| 5117 | } | 5138 | ret = update_planes_and_stream_v1(dc, srf_updates, surface_count, stream, |
| 5118 | update_planes_and_stream_v1(dc, srf_updates, surface_count, stream, | 5139 | stream_update, state); |
| 5119 | stream_update, state); | 5140 | |
| 5141 | if (ret) | ||
| 5142 | clear_update_flags(srf_updates, surface_count, stream); | ||
| 5120 | } | 5143 | } |
| 5121 | 5144 | ||
| 5122 | uint8_t dc_get_current_stream_count(struct dc *dc) | 5145 | uint8_t dc_get_current_stream_count(struct dc *dc) |
| @@ -178,6 +178,7 @@ struct dc_panel_patch { · 177 unmodified lines | |||
| 178 | unsigned int skip_avmute; | 178 | unsigned int skip_avmute; |
| 179 | unsigned int mst_start_top_delay; | 179 | unsigned int mst_start_top_delay; |
| 180 | unsigned int remove_sink_ext_caps; | 180 | unsigned int remove_sink_ext_caps; |
| 181 | unsigned int disable_colorimetry; | ||
| 181 | }; | 182 | }; |
| 182 | 183 | ||
| 183 | struct dc_edid_caps { | 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 | if (project == dml_project_dcn35 || | 303 | if (project == dml_project_dcn35 || |
| 304 | project == dml_project_dcn351) { | 304 | project == dml_project_dcn351) { |
| 305 | policy->DCCProgrammingAssumesScanDirectionUnknownFinal = false; | 305 | policy->DCCProgrammingAssumesScanDirectionUnknownFinal = false; |
| 306 | policy->EnhancedPrefetchScheduleAccelerationFinal = 0; | ||
| 307 | policy->AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter_if_possible; /*new*/ | 306 | policy->AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter_if_possible; /*new*/ |
| 308 | policy->UseOnlyMaxPrefetchModes = 1; | 307 | policy->UseOnlyMaxPrefetchModes = 1; |
| 309 | } | 308 | } |
| @@ -766,6 +766,7 @@ static const struct dc_debug_options debug_defaults_drv = { · 765 unmodified lines | |||
| 766 | .disable_dmub_reallow_idle = false, | 766 | .disable_dmub_reallow_idle = false, |
| 767 | .static_screen_wait_frames = 2, | 767 | .static_screen_wait_frames = 2, |
| 768 | .notify_dpia_hr_bw = true, | 768 | .notify_dpia_hr_bw = true, |
| 769 | .min_disp_clk_khz = 50000, | ||
| 769 | }; | 770 | }; |
| 770 | 771 | ||
| 771 | static const struct dc_panel_config panel_config_defaults = { | 772 | static const struct dc_panel_config panel_config_defaults = { |
| @@ -60,7 +60,7 @@ struct vi_dpm_level { · 59 unmodified lines | |||
| 60 | 60 | ||
| 61 | struct vi_dpm_table { | 61 | struct vi_dpm_table { |
| 62 | uint32_t count; | 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 | #define PCIE_PERF_REQ_REMOVE_REGISTRY 0 | 66 | #define PCIE_PERF_REQ_REMOVE_REGISTRY 0 |
| @@ -91,7 +91,7 @@ struct phm_set_power_state_input { · 24 unmodified lines | |||
| 91 | 91 | ||
| 92 | struct phm_clock_array { | 92 | struct phm_clock_array { |
| 93 | uint32_t count; | 93 | uint32_t count; |
| 94 | uint32_t values[] __counted_by(count); | 94 | uint32_t values[]; |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | struct phm_clock_voltage_dependency_record { | 97 | struct phm_clock_voltage_dependency_record { |
| @@ -123,7 +123,7 @@ struct phm_acpclock_voltage_dependency_record { · 25 unmodified lines | |||
| 123 | 123 | ||
| 124 | struct phm_clock_voltage_dependency_table { | 124 | struct phm_clock_voltage_dependency_table { |
| 125 | uint32_t count; | 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 | struct phm_phase_shedding_limits_record { | 129 | struct phm_phase_shedding_limits_record { |
| @@ -140,7 +140,7 @@ struct phm_uvd_clock_voltage_dependency_record { · 10 unmodified lines | |||
| 140 | 140 | ||
| 141 | struct phm_uvd_clock_voltage_dependency_table { | 141 | struct phm_uvd_clock_voltage_dependency_table { |
| 142 | uint8_t count; | 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 | struct phm_acp_clock_voltage_dependency_record { | 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 | struct phm_acp_clock_voltage_dependency_table { | 151 | struct phm_acp_clock_voltage_dependency_table { |
| 152 | uint32_t count; | 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 | struct phm_vce_clock_voltage_dependency_record { | 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 | struct phm_phase_shedding_limits_table { | 162 | struct phm_phase_shedding_limits_table { |
| 163 | uint32_t count; | 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 | struct phm_vceclock_voltage_dependency_table { | 167 | struct phm_vceclock_voltage_dependency_table { |
| 168 | uint8_t count; | 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 | struct phm_uvdclock_voltage_dependency_table { | 172 | struct phm_uvdclock_voltage_dependency_table { |
| 173 | uint8_t count; | 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 | struct phm_samuclock_voltage_dependency_table { | 177 | struct phm_samuclock_voltage_dependency_table { |
| 178 | uint8_t count; | 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 | struct phm_acpclock_voltage_dependency_table { | 182 | struct phm_acpclock_voltage_dependency_table { |
| 183 | uint32_t count; | 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 | struct phm_vce_clock_voltage_dependency_table { | 187 | struct phm_vce_clock_voltage_dependency_table { |
| 188 | uint8_t count; | 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 | struct phm_cac_leakage_table { | 394 | struct phm_cac_leakage_table { |
| 395 | uint32_t count; | 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 | struct phm_samu_clock_voltage_dependency_record { | 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 | struct phm_samu_clock_voltage_dependency_table { | 405 | struct phm_samu_clock_voltage_dependency_table { |
| 406 | uint8_t count; | 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 | struct phm_cac_tdp_table { | 410 | struct phm_cac_tdp_table { |
| @@ -1264,7 +1264,11 @@ static int smu_sw_init(void *handle) · 1263 unmodified lines | |||
| 1264 | smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4; | 1264 | smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4; |
| 1265 | smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5; | 1265 | smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5; |
| 1266 | smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6; | 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 | smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; | 1273 | smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; |
| 1270 | smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D; | 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 | static int smu_adjust_power_state_dynamic(struct smu_context *smu, | 2230 | static int smu_adjust_power_state_dynamic(struct smu_context *smu, |
| 2227 | enum amd_dpm_forced_level level, | 2231 | enum amd_dpm_forced_level level, |
| 2228 | bool skip_display_settings, | 2232 | bool skip_display_settings, |
| 2229 | bool force_update) | 2233 | bool init) |
| 2230 | { | 2234 | { |
| 2231 | int ret = 0; | 2235 | int ret = 0; |
| 2232 | int index = 0; | 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 | ret = smu_asic_set_performance_level(smu, level); | 2263 | ret = smu_asic_set_performance_level(smu, level); |
| 2260 | if (ret) { | 2264 | if (ret) { |
| 2261 | dev_err(smu->adev->dev, "Failed to set performance level!"); | 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 | index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; | 2276 | index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; |
| 2273 | workload[0] = smu->workload_setting[index]; | 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 | smu_bump_power_profile_mode(smu, workload, 0); | 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 | workload_mask = 1 << workload_type; | 2555 | workload_mask = 1 << workload_type; |
| 2556 | 2556 | ||
| 2557 | /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */ | 2557 | /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */ |
| 2558 | if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE) { | 2558 | if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) && |
| 2559 | 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 == 0x004e6601) || | 2560 | (smu->adev->pm.fw_version >= 0x004e7300))) || |
| 2561 | (smu->adev->pm.fw_version >= 0x004e7300))) || | 2561 | (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) && |
| 2562 | (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) && | 2562 | smu->adev->pm.fw_version >= 0x00504500)) { |
| 2563 | smu->adev->pm.fw_version >= 0x00504500)) { | 2563 | workload_type = smu_cmn_to_asic_specific_index(smu, |
| 2564 | workload_type = smu_cmn_to_asic_specific_index(smu, | 2564 | CMN2ASIC_MAPPING_WORKLOAD, |
| 2565 | CMN2ASIC_MAPPING_WORKLOAD, | 2565 | PP_SMC_POWER_PROFILE_POWERSAVING); |
| 2566 | PP_SMC_POWER_PROFILE_POWERSAVING); | 2566 | if (workload_type >= 0) |
| 2567 | if (workload_type >= 0) | 2567 | workload_mask |= 1 << workload_type; |
| 2568 | workload_mask |= 1 << workload_type; | ||
| 2569 | } | ||
| 2570 | } | 2568 | } |
| 2571 | 2569 | ||
| 2572 | ret = smu_cmn_send_smc_msg_with_param(smu, | 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 | if (ast_connector->physical_status == connector_status_connected) { | 29 | if (ast_connector->physical_status == connector_status_connected) { |
| 30 | count = drm_connector_helper_get_modes(connector); | 30 | count = drm_connector_helper_get_modes(connector); |
| 31 | } else { | 31 | } else { |
| 32 | drm_edid_connector_update(connector, NULL); | ||
| 33 | |||
| 32 | /* | 34 | /* |
| 33 | * There's no EDID data without a connected monitor. Set BMC- | 35 | * There's no EDID data without a connected monitor. Set BMC- |
| 34 | * compatible modes in this case. The XGA default resolution | 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 | if (ast_connector->physical_status == connector_status_connected) { | 29 | if (ast_connector->physical_status == connector_status_connected) { |
| 30 | count = drm_connector_helper_get_modes(connector); | 30 | count = drm_connector_helper_get_modes(connector); |
| 31 | } else { | 31 | } else { |
| 32 | drm_edid_connector_update(connector, NULL); | ||
| 33 | |||
| 32 | /* | 34 | /* |
| 33 | * There's no EDID data without a connected monitor. Set BMC- | 35 | * There's no EDID data without a connected monitor. Set BMC- |
| 34 | * compatible modes in this case. The XGA default resolution | 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 | struct drm_dp_aux *immediate_upstream_aux; | 6083 | struct drm_dp_aux *immediate_upstream_aux; |
| 6084 | struct drm_dp_mst_port *fec_port; | 6084 | struct drm_dp_mst_port *fec_port; |
| 6085 | struct drm_dp_desc desc = {}; | 6085 | struct drm_dp_desc desc = {}; |
| 6086 | u8 upstream_dsc; | ||
| 6086 | u8 endpoint_fec; | 6087 | u8 endpoint_fec; |
| 6087 | u8 endpoint_dsc; | 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 | /* DP-to-DP peer device */ | 6111 | /* DP-to-DP peer device */ |
| 6111 | if (drm_dp_mst_is_virtual_dpcd(immediate_upstream_port)) { | 6112 | if (drm_dp_mst_is_virtual_dpcd(immediate_upstream_port)) { |
| 6112 | u8 upstream_dsc; | ||
| 6113 | |||
| 6114 | if (drm_dp_dpcd_read(&port->aux, | 6113 | if (drm_dp_dpcd_read(&port->aux, |
| 6115 | DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1) | 6114 | DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1) |
| 6116 | return NULL; | 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 | if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) { | 6155 | if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) { |
| 6157 | u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; | 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 | if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0) | 6165 | if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0) |
| 6160 | return NULL; | 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 | EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); | 522 | EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); |
| 523 | 523 | ||
| 524 | #define HDMI_MAX_INFOFRAME_SIZE 29 | ||
| 525 | |||
| 526 | static int clear_device_infoframe(struct drm_connector *connector, | 524 | static int clear_device_infoframe(struct drm_connector *connector, |
| 527 | enum hdmi_infoframe_type type) | 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 | const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; | 562 | const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; |
| 565 | struct drm_device *dev = connector->dev; | 563 | struct drm_device *dev = connector->dev; |
| 566 | u8 buffer[HDMI_MAX_INFOFRAME_SIZE]; | 564 | u8 buffer[HDMI_INFOFRAME_SIZE(MAX)]; |
| 567 | int ret; | 565 | int ret; |
| 568 | int len; | 566 | int len; |
| 569 | 567 | ||
| @@ -543,7 +543,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, · 542 unmodified lines | |||
| 543 | &state->fb_damage_clips, | 543 | &state->fb_damage_clips, |
| 544 | val, | 544 | val, |
| 545 | -1, | 545 | -1, |
| 546 | sizeof(struct drm_rect), | 546 | sizeof(struct drm_mode_rect), |
| 547 | &replaced); | 547 | &replaced); |
| 548 | return ret; | 548 | return ret; |
| 549 | } else if (property == plane->scaling_filter_property) { | 549 | } else if (property == plane->scaling_filter_property) { |
| @@ -520,8 +520,6 @@ static const struct file_operations drm_connector_fops = { · 519 unmodified lines | |||
| 520 | .write = connector_write | 520 | .write = connector_write |
| 521 | }; | 521 | }; |
| 522 | 522 | ||
| 523 | #define HDMI_MAX_INFOFRAME_SIZE 29 | ||
| 524 | |||
| 525 | static ssize_t | 523 | static ssize_t |
| 526 | audio_infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos) | 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 | struct drm_connector *connector; \ | 577 | struct drm_connector *connector; \ |
| 580 | union hdmi_infoframe *frame; \ | 578 | union hdmi_infoframe *frame; \ |
| 581 | struct drm_device *dev; \ | 579 | struct drm_device *dev; \ |
| 582 | u8 buf[HDMI_MAX_INFOFRAME_SIZE]; \ | 580 | u8 buf[HDMI_INFOFRAME_SIZE(MAX)]; \ |
| 583 | ssize_t len = 0; \ | 581 | ssize_t len = 0; \ |
| 584 | \ | 582 | \ |
| 585 | connector = filp->private_data; \ | 583 | connector = filp->private_data; \ |
| @@ -50,7 +50,8 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info) · 49 unmodified lines | |||
| 50 | if (!fb_helper->dev) | 50 | if (!fb_helper->dev) |
| 51 | return; | 51 | return; |
| 52 | 52 | ||
| 53 | fb_deferred_io_cleanup(info); | 53 | if (info->fbdefio) |
| 54 | fb_deferred_io_cleanup(info); | ||
| 54 | drm_fb_helper_fini(fb_helper); | 55 | drm_fb_helper_fini(fb_helper); |
| 55 | 56 | ||
| 56 | drm_client_buffer_vunmap(fb_helper->buffer); | 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 | static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, | 90 | static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, |
| 91 | const struct intel_connector *connector, | 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 | const struct drm_display_mode *adjusted_mode = | 94 | const struct drm_display_mode *adjusted_mode = |
| 95 | &crtc_state->hw.adjusted_mode; | 95 | &crtc_state->hw.adjusted_mode; |
| 96 | unsigned long flags = DRM_DP_BW_OVERHEAD_MST; | 96 | unsigned long flags = DRM_DP_BW_OVERHEAD_MST; |
| 97 | int dsc_slice_count = 0; | ||
| 98 | int overhead; | 97 | int overhead; |
| 99 | 98 | ||
| 100 | flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0; | 99 | flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0; |
| 101 | flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0; | 100 | flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0; |
| 102 | flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; | 101 | flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; |
| 103 | 102 | ||
| 104 | if (dsc) { | 103 | if (dsc_slice_count) |
| 105 | flags |= DRM_DP_BW_OVERHEAD_DSC; | 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 | overhead = drm_dp_bw_overhead(crtc_state->lane_count, | 106 | overhead = drm_dp_bw_overhead(crtc_state->lane_count, |
| 113 | adjusted_mode->hdisplay, | 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 | return DIV_ROUND_UP(effective_data_rate * 64, 54 * 1000); | 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 | static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, | 163 | static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, |
| 157 | struct intel_crtc_state *crtc_state, | 164 | struct intel_crtc_state *crtc_state, |
| 158 | int max_bpp, | 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 | const struct drm_display_mode *adjusted_mode = | 179 | const struct drm_display_mode *adjusted_mode = |
| 173 | &crtc_state->hw.adjusted_mode; | 180 | &crtc_state->hw.adjusted_mode; |
| 174 | int bpp, slots = -EINVAL; | 181 | int bpp, slots = -EINVAL; |
| 182 | int dsc_slice_count = 0; | ||
| 175 | int max_dpt_bpp; | 183 | int max_dpt_bpp; |
| 176 | int ret = 0; | 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 | drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n", | 211 | drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n", |
| 204 | min_bpp, max_bpp); | 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 | for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { | 223 | for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { |
| 207 | int local_bw_overhead; | 224 | int local_bw_overhead; |
| 208 | int remote_bw_overhead; | 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 | intel_dp_output_bpp(crtc_state->output_format, bpp)); | 233 | intel_dp_output_bpp(crtc_state->output_format, bpp)); |
| 217 | 234 | ||
| 218 | local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, | 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 | remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, | 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 | intel_dp_mst_compute_m_n(crtc_state, connector, | 240 | intel_dp_mst_compute_m_n(crtc_state, connector, |
| 224 | local_bw_overhead, | 241 | local_bw_overhead, |
| @@ -449,6 +466,9 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, · 224 unmodified lines | |||
| 449 | if (mode_hblank_period_ns(adjusted_mode) > hblank_limit) | 466 | if (mode_hblank_period_ns(adjusted_mode) > hblank_limit) |
| 450 | return false; | 467 | return false; |
| 451 | 468 | ||
| 469 | if (!intel_dp_mst_dsc_get_slice_count(connector, crtc_state)) | ||
| 470 | return false; | ||
| 471 | |||
| 452 | return true; | 472 | return true; |
| 453 | } | 473 | } |
| 454 | 474 | ||
| @@ -438,6 +438,19 @@ bool intel_fb_needs_64k_phys(u64 modifier) · 437 unmodified lines | |||
| 438 | INTEL_PLANE_CAP_NEED64K_PHYS); | 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 | static bool check_modifier_display_ver_range(const struct intel_modifier_desc *md, | 454 | static bool check_modifier_display_ver_range(const struct intel_modifier_desc *md, |
| 442 | u8 display_ver_from, u8 display_ver_until) | 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 | bool intel_fb_is_rc_ccs_cc_modifier(u64 modifier); | 35 | bool intel_fb_is_rc_ccs_cc_modifier(u64 modifier); |
| 36 | bool intel_fb_is_mc_ccs_modifier(u64 modifier); | 36 | bool intel_fb_is_mc_ccs_modifier(u64 modifier); |
| 37 | bool intel_fb_needs_64k_phys(u64 modifier); | 37 | bool intel_fb_needs_64k_phys(u64 modifier); |
| 38 | bool intel_fb_is_tile4_modifier(u64 modifier); | ||
| 38 | 39 | ||
| 39 | bool intel_fb_is_ccs_aux_plane(const struct drm_framebuffer *fb, int color_plane); | 40 | bool intel_fb_is_ccs_aux_plane(const struct drm_framebuffer *fb, int color_plane); |
| 40 | int intel_fb_rc_ccs_cc_plane(const struct drm_framebuffer *fb); | 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 | hdcp->value = value; | 1094 | hdcp->value = value; |
| 1095 | if (update_property) { | 1095 | if (update_property) { |
| 1096 | drm_connector_get(&connector->base); | 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 | mutex_lock(&hdcp->mutex); | 2525 | mutex_lock(&hdcp->mutex); |
| 2525 | hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; | 2526 | hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; |
| 2526 | drm_connector_get(&connector->base); | 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 | mutex_unlock(&hdcp->mutex); | 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 | if (!desired_and_not_enabled && !content_protection_type_changed) { | 2544 | if (!desired_and_not_enabled && !content_protection_type_changed) { |
| 2543 | drm_connector_get(&connector->base); | 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 | return -EINVAL; | 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 | if (drm_rotation_90_or_270(rotation)) { | 1605 | if (drm_rotation_90_or_270(rotation)) { |
| 1595 | if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) { | 1606 | if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) { |
| 1596 | drm_dbg_kms(&dev_priv->drm, | 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 | GEM_WARN_ON(!i915_ttm_cpu_maps_iomem(bo->resource)); | 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 | intel_wakeref_auto(&to_i915(obj->base.dev)->runtime_pm.userfault_wakeref, | 1135 | intel_wakeref_auto(&to_i915(obj->base.dev)->runtime_pm.userfault_wakeref, |
| 1136 | msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)); | 1136 | msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)); |
| 1137 | 1137 | ||
| @@ -18,7 +18,6 @@ · 17 unmodified lines | |||
| 18 | #include <drm/drm_managed.h> | 18 | #include <drm/drm_managed.h> |
| 19 | #include <drm/drm_module.h> | 19 | #include <drm/drm_module.h> |
| 20 | #include <drm/drm_pciids.h> | 20 | #include <drm/drm_pciids.h> |
| 21 | #include <drm/drm_vblank.h> | ||
| 22 | 21 | ||
| 23 | #include "mgag200_drv.h" | 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 | return offset - 65536; | 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 | * DRM driver | 88 | * DRM driver |
| 118 | */ | 89 | */ |
| @@ -196,7 +167,6 @@ int mgag200_device_init(struct mga_device *mdev, · 77 unmodified lines | |||
| 196 | const struct mgag200_device_funcs *funcs) | 167 | const struct mgag200_device_funcs *funcs) |
| 197 | { | 168 | { |
| 198 | struct drm_device *dev = &mdev->base; | 169 | struct drm_device *dev = &mdev->base; |
| 199 | struct pci_dev *pdev = to_pci_dev(dev->dev); | ||
| 200 | u8 crtcext3, misc; | 170 | u8 crtcext3, misc; |
| 201 | int ret; | 171 | int ret; |
| 202 | 172 | ||
| @@ -223,14 +193,6 @@ int mgag200_device_init(struct mga_device *mdev, · 20 unmodified lines | |||
| 223 | mutex_unlock(&mdev->rmmio_lock); | 193 | mutex_unlock(&mdev->rmmio_lock); |
| 224 | 194 | ||
| 225 | WREG32(MGAREG_IEN, 0); | 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 | return 0; | 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 | void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state); | 391 | void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 392 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); | 392 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 393 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); | 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 | #define MGAG200_CRTC_HELPER_FUNCS \ | 395 | #define MGAG200_CRTC_HELPER_FUNCS \ |
| 400 | .mode_valid = mgag200_crtc_helper_mode_valid, \ | 396 | .mode_valid = mgag200_crtc_helper_mode_valid, \ |
| 401 | .atomic_check = mgag200_crtc_helper_atomic_check, \ | 397 | .atomic_check = mgag200_crtc_helper_atomic_check, \ |
| 402 | .atomic_flush = mgag200_crtc_helper_atomic_flush, \ | 398 | .atomic_flush = mgag200_crtc_helper_atomic_flush, \ |
| 403 | .atomic_enable = mgag200_crtc_helper_atomic_enable, \ | 399 | .atomic_enable = mgag200_crtc_helper_atomic_enable, \ |
| 404 | .atomic_disable = mgag200_crtc_helper_atomic_disable, \ | 400 | .atomic_disable = mgag200_crtc_helper_atomic_disable |
| 405 | .get_scanout_position = mgag200_crtc_helper_get_scanout_position | ||
| 406 | 401 | ||
| 407 | void mgag200_crtc_reset(struct drm_crtc *crtc); | 402 | void mgag200_crtc_reset(struct drm_crtc *crtc); |
| 408 | struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc); | 403 | struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc); |
| 409 | void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state); | 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 | #define MGAG200_CRTC_FUNCS \ | 406 | #define MGAG200_CRTC_FUNCS \ |
| 414 | .reset = mgag200_crtc_reset, \ | 407 | .reset = mgag200_crtc_reset, \ |
| @@ -416,10 +409,7 @@ void mgag200_crtc_disable_vblank(struct drm_crtc *crtc); · 1 unmodified line | |||
| 416 | .set_config = drm_atomic_helper_set_config, \ | 409 | .set_config = drm_atomic_helper_set_config, \ |
| 417 | .page_flip = drm_atomic_helper_page_flip, \ | 410 | .page_flip = drm_atomic_helper_page_flip, \ |
| 418 | .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \ | 411 | .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \ |
| 419 | .atomic_destroy_state = mgag200_crtc_atomic_destroy_state, \ | 412 | .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 | ||
| 423 | 413 | ||
| 424 | void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode, | 414 | void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode, |
| 425 | bool set_vidrst); | 415 | bool set_vidrst); |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 403 | drm_mode_config_reset(dev); |
| 405 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 406 | return mdev; |
| 412 | } | 407 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 275 | drm_mode_config_reset(dev); |
| 277 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 278 | return mdev; |
| 284 | } | 279 | } |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include <drm/drm_drv.h> | 7 | #include <drm/drm_drv.h> |
| 8 | #include <drm/drm_gem_atomic_helper.h> | 8 | #include <drm/drm_gem_atomic_helper.h> |
| 9 | #include <drm/drm_probe_helper.h> | 9 | #include <drm/drm_probe_helper.h> |
| 10 | #include <drm/drm_vblank.h> | ||
| 11 | 10 | ||
| 12 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 180 | drm_mode_config_reset(dev); |
| 182 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 183 | return mdev; |
| 189 | } | 184 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | mgag200_crtc_set_gamma_linear(mdev, format); | 205 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 207 | 206 | ||
| 208 | mgag200_enable_display(mdev); | 207 | mgag200_enable_display(mdev); |
| 209 | |||
| 210 | drm_crtc_vblank_on(crtc); | ||
| 211 | } | 208 | } |
| 212 | 209 | ||
| 213 | static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = { | 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 | .atomic_check = mgag200_crtc_helper_atomic_check, | 212 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 216 | .atomic_flush = mgag200_crtc_helper_atomic_flush, | 213 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 217 | .atomic_enable = mgag200_g200er_crtc_helper_atomic_enable, | 214 | .atomic_enable = mgag200_g200er_crtc_helper_atomic_enable, |
| 218 | .atomic_disable = mgag200_crtc_helper_atomic_disable, | 215 | .atomic_disable = mgag200_crtc_helper_atomic_disable |
| 219 | .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | ||
| 220 | }; | 216 | }; |
| 221 | 217 | ||
| 222 | static const struct drm_crtc_funcs mgag200_g200er_crtc_funcs = { | 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 | drm_mode_config_reset(dev); | 308 | drm_mode_config_reset(dev); |
| 313 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 311 | return mdev; |
| 320 | } | 312 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | mgag200_crtc_set_gamma_linear(mdev, format); | 206 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 208 | 207 | ||
| 209 | mgag200_enable_display(mdev); | 208 | mgag200_enable_display(mdev); |
| 210 | |||
| 211 | drm_crtc_vblank_on(crtc); | ||
| 212 | } | 209 | } |
| 213 | 210 | ||
| 214 | static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = { | 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 | .atomic_check = mgag200_crtc_helper_atomic_check, | 213 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 217 | .atomic_flush = mgag200_crtc_helper_atomic_flush, | 214 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 218 | .atomic_enable = mgag200_g200ev_crtc_helper_atomic_enable, | 215 | .atomic_enable = mgag200_g200ev_crtc_helper_atomic_enable, |
| 219 | .atomic_disable = mgag200_crtc_helper_atomic_disable, | 216 | .atomic_disable = mgag200_crtc_helper_atomic_disable |
| 220 | .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | ||
| 221 | }; | 217 | }; |
| 222 | 218 | ||
| 223 | static const struct drm_crtc_funcs mgag200_g200ev_crtc_funcs = { | 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 | drm_mode_config_reset(dev); | 313 | drm_mode_config_reset(dev); |
| 318 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 316 | return mdev; |
| 325 | } | 317 | } |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include <drm/drm_drv.h> | 7 | #include <drm/drm_drv.h> |
| 8 | #include <drm/drm_gem_atomic_helper.h> | 8 | #include <drm/drm_gem_atomic_helper.h> |
| 9 | #include <drm/drm_probe_helper.h> | 9 | #include <drm/drm_probe_helper.h> |
| 10 | #include <drm/drm_vblank.h> | ||
| 11 | 10 | ||
| 12 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 198 | drm_mode_config_reset(dev); |
| 200 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 201 | return mdev; |
| 207 | } | 202 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | mgag200_crtc_set_gamma_linear(mdev, format); | 337 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 339 | 338 | ||
| 340 | mgag200_enable_display(mdev); | 339 | mgag200_enable_display(mdev); |
| 341 | |||
| 342 | drm_crtc_vblank_on(crtc); | ||
| 343 | } | 340 | } |
| 344 | 341 | ||
| 345 | static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = { | 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 | .atomic_check = mgag200_crtc_helper_atomic_check, | 344 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 348 | .atomic_flush = mgag200_crtc_helper_atomic_flush, | 345 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 349 | .atomic_enable = mgag200_g200se_crtc_helper_atomic_enable, | 346 | .atomic_enable = mgag200_g200se_crtc_helper_atomic_enable, |
| 350 | .atomic_disable = mgag200_crtc_helper_atomic_disable, | 347 | .atomic_disable = mgag200_crtc_helper_atomic_disable |
| 351 | .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | ||
| 352 | }; | 348 | }; |
| 353 | 349 | ||
| 354 | static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = { | 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 | drm_mode_config_reset(dev); | 513 | drm_mode_config_reset(dev); |
| 518 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 516 | return mdev; |
| 525 | } | 517 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 322 | drm_mode_config_reset(dev); |
| 324 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 325 | return mdev; |
| 331 | } | 326 | } |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | |||
| 22 | #include <drm/drm_gem_framebuffer_helper.h> | 22 | #include <drm/drm_gem_framebuffer_helper.h> |
| 23 | #include <drm/drm_panic.h> | 23 | #include <drm/drm_panic.h> |
| 24 | #include <drm/drm_print.h> | 24 | #include <drm/drm_print.h> |
| 25 | #include <drm/drm_vblank.h> | ||
| 26 | 25 | ||
| 27 | #include "mgag200_ddc.h" | 26 | #include "mgag200_ddc.h" |
| 28 | #include "mgag200_drv.h" | 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 | vblkstr = mode->crtc_vblank_start; | 226 | vblkstr = mode->crtc_vblank_start; |
| 228 | vblkend = vtotal + 1; | 227 | vblkend = vtotal + 1; |
| 229 | 228 | ||
| 230 | /* | 229 | linecomp = vdispend; |
| 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; | ||
| 238 | 230 | ||
| 239 | misc = RREG8(MGA_MISC_IN); | 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 | struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); | 637 | struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); |
| 646 | struct drm_device *dev = crtc->dev; | 638 | struct drm_device *dev = crtc->dev; |
| 647 | struct mga_device *mdev = to_mga_device(dev); | 639 | struct mga_device *mdev = to_mga_device(dev); |
| 648 | struct drm_pending_vblank_event *event; | ||
| 649 | unsigned long flags; | ||
| 650 | 640 | ||
| 651 | if (crtc_state->enable && crtc_state->color_mgmt_changed) { | 641 | if (crtc_state->enable && crtc_state->color_mgmt_changed) { |
| 652 | const struct drm_format_info *format = mgag200_crtc_state->format; | 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 | else | 646 | else |
| 657 | mgag200_crtc_set_gamma_linear(mdev, format); | 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 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) | 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 | mgag200_crtc_set_gamma_linear(mdev, format); | 670 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 693 | 671 | ||
| 694 | mgag200_enable_display(mdev); | 672 | mgag200_enable_display(mdev); |
| 695 | |||
| 696 | drm_crtc_vblank_on(crtc); | ||
| 697 | } | 673 | } |
| 698 | 674 | ||
| 699 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) | 675 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) |
| 700 | { | 676 | { |
| 701 | struct mga_device *mdev = to_mga_device(crtc->dev); | 677 | struct mga_device *mdev = to_mga_device(crtc->dev); |
| 702 | 678 | ||
| 703 | drm_crtc_vblank_off(crtc); | ||
| 704 | |||
| 705 | mgag200_disable_display(mdev); | 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 | void mgag200_crtc_reset(struct drm_crtc *crtc) | 682 | void mgag200_crtc_reset(struct drm_crtc *crtc) |
| 734 | { | 683 | { |
| 735 | struct mgag200_crtc_state *mgag200_crtc_state; | 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 | kfree(mgag200_crtc_state); | 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 | * Mode config | 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 | static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, | 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 | bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1; | 106 | bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1; |
| 107 | struct msm_file_private *ctx = submit->queue->ctx; | ||
| 107 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; | 108 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; |
| 108 | phys_addr_t ttbr; | 109 | phys_addr_t ttbr; |
| 109 | u32 asid; | 110 | u32 asid; |
| @@ -115,6 +116,15 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, · 5 unmodified lines | |||
| 115 | if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) | 116 | if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) |
| 116 | return; | 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 | if (!sysprof) { | 128 | if (!sysprof) { |
| 119 | if (!adreno_is_a7xx(adreno_gpu)) { | 129 | if (!adreno_is_a7xx(adreno_gpu)) { |
| 120 | /* Turn off protected mode to write to special registers */ | 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 | struct msm_ringbuffer *ring = submit->ring; | 203 | struct msm_ringbuffer *ring = submit->ring; |
| 194 | unsigned int i, ibs = 0; | 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 | get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0), | 208 | get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0), |
| 199 | rbmemptr_stats(ring, index, cpcycles_start)); | 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 | OUT_PKT7(ring, CP_THREAD_CONTROL, 1); | 293 | OUT_PKT7(ring, CP_THREAD_CONTROL, 1); |
| 284 | OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR); | 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 | get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0), | 298 | get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0), |
| 289 | rbmemptr_stats(ring, index, cpcycles_start)); | 299 | rbmemptr_stats(ring, index, cpcycles_start)); |
| @@ -711,12 +711,13 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc) · 710 unmodified lines | |||
| 711 | _dpu_crtc_complete_flip(crtc); | 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 | struct drm_crtc_state *state) | 715 | struct drm_crtc_state *state) |
| 716 | { | 716 | { |
| 717 | struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); | 717 | struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); |
| 718 | struct drm_display_mode *adj_mode = &state->adjusted_mode; | 718 | struct drm_display_mode *adj_mode = &state->adjusted_mode; |
| 719 | u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers; | 719 | u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers; |
| 720 | struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); | ||
| 720 | int i; | 721 | int i; |
| 721 | 722 | ||
| 722 | for (i = 0; i < cstate->num_mixers; i++) { | 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 | r->y2 = adj_mode->vdisplay; | 728 | r->y2 = adj_mode->vdisplay; |
| 728 | 729 | ||
| 729 | trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r); | 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 | static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state, | 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 | DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id); | 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 | /* encoder will trigger pending mask now */ | 814 | /* encoder will trigger pending mask now */ |
| 809 | drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) | 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 | dpu_core_perf_crtc_update(crtc, 0); | 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 | /* disable clk & bw control until clk & bw properties are set */ | 1100 | /* disable clk & bw control until clk & bw properties are set */ |
| 1098 | cstate->bw_control = false; | 1101 | cstate->bw_control = false; |
| 1099 | cstate->bw_split_vote = false; | 1102 | cstate->bw_split_vote = false; |
| @@ -1192,8 +1195,11 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, · 92 unmodified lines | |||
| 1192 | if (crtc_state->active_changed) | 1195 | if (crtc_state->active_changed) |
| 1193 | crtc_state->mode_changed = true; | 1196 | crtc_state->mode_changed = true; |
| 1194 | 1197 | ||
| 1195 | if (cstate->num_mixers) | 1198 | if (cstate->num_mixers) { |
| 1196 | _dpu_crtc_setup_lm_bounds(crtc, crtc_state); | 1199 | rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state); |
| 1200 | if (rc) | ||
| 1201 | return rc; | ||
| 1202 | } | ||
| 1197 | 1203 | ||
| 1198 | /* FIXME: move this to dpu_plane_atomic_check? */ | 1204 | /* FIXME: move this to dpu_plane_atomic_check? */ |
| 1199 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { | 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 | return topology; | 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 | static int dpu_encoder_virt_atomic_check( | 661 | static int dpu_encoder_virt_atomic_check( |
| 628 | struct drm_encoder *drm_enc, | 662 | struct drm_encoder *drm_enc, |
| 629 | struct drm_crtc_state *crtc_state, | 663 | struct drm_crtc_state *crtc_state, |
| @@ -692,6 +726,9 @@ static int dpu_encoder_virt_atomic_check( · 62 unmodified lines | |||
| 692 | if (!crtc_state->active_changed || crtc_state->enable) | 726 | if (!crtc_state->active_changed || crtc_state->enable) |
| 693 | ret = dpu_rm_reserve(&dpu_kms->rm, global_state, | 727 | ret = dpu_rm_reserve(&dpu_kms->rm, global_state, |
| 694 | drm_enc, crtc_state, topology); | 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 | trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); | 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 | struct dpu_encoder_virt *dpu_enc; | 1130 | struct dpu_encoder_virt *dpu_enc; |
| 1094 | struct msm_drm_private *priv; | 1131 | struct msm_drm_private *priv; |
| 1095 | struct dpu_kms *dpu_kms; | 1132 | struct dpu_kms *dpu_kms; |
| 1096 | struct dpu_crtc_state *cstate; | ||
| 1097 | struct dpu_global_state *global_state; | 1133 | struct dpu_global_state *global_state; |
| 1098 | struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; | 1134 | struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; |
| 1099 | struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; | 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 | struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC]; | 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 | unsigned int dsc_mask = 0; | 1138 | unsigned int dsc_mask = 0; |
| 1105 | int i; | 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 | ARRAY_SIZE(hw_pp)); | 1163 | ARRAY_SIZE(hw_pp)); |
| 1130 | num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | 1164 | num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, |
| 1131 | drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); | 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 | for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) | 1167 | for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) |
| 1139 | dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) | 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 | dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL; | 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 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { | 1191 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { |
| 1175 | struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; | 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 | DPU_ERROR_ENC(dpu_enc, | 1196 | DPU_ERROR_ENC(dpu_enc, |
| 1179 | "no pp block assigned at idx: %d\n", i); | 1197 | "no pp block assigned at idx: %d\n", i); |
| 1180 | return; | 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 | DPU_ERROR_ENC(dpu_enc, | 1203 | DPU_ERROR_ENC(dpu_enc, |
| 1185 | "no ctl block assigned at idx: %d\n", i); | 1204 | "no ctl block assigned at idx: %d\n", i); |
| 1186 | return; | 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 | phys->cached_mode = crtc_state->adjusted_mode; | 1208 | phys->cached_mode = crtc_state->adjusted_mode; |
| 1193 | if (phys->ops.atomic_mode_set) | 1209 | if (phys->ops.atomic_mode_set) |
| 1194 | phys->ops.atomic_mode_set(phys, crtc_state, conn_state); | 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 | intf_cfg.stream_sel = 0; /* Don't care value for video mode */ | 302 | intf_cfg.stream_sel = 0; /* Don't care value for video mode */ |
| 303 | intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); | 303 | intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); |
| 304 | intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); | 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 | intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; | 306 | intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; |
| 307 | 307 | ||
| 308 | spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); | 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 | struct dpu_hw_ctl *ctl; | 440 | struct dpu_hw_ctl *ctl; |
| 441 | const struct msm_format *fmt; | 441 | const struct msm_format *fmt; |
| 442 | u32 fmt_fourcc; | 442 | u32 fmt_fourcc; |
| 443 | u32 mode_3d; | ||
| 443 | 444 | ||
| 444 | ctl = phys_enc->hw_ctl; | 445 | ctl = phys_enc->hw_ctl; |
| 445 | fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc); | 446 | fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc); |
| 446 | fmt = mdp_get_format(&phys_enc->dpu_kms->base, fmt_fourcc, 0); | 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 | DPU_DEBUG_VIDENC(phys_enc, "\n"); | 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 | goto skip_flush; | 468 | goto skip_flush; |
| 467 | 469 | ||
| 468 | ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); | 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 | ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); | 473 | ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); |
| 471 | 474 | ||
| 472 | if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm) | 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 | struct dpu_hw_pingpong *hw_pp; | 275 | struct dpu_hw_pingpong *hw_pp; |
| 276 | struct dpu_hw_cdm *hw_cdm; | 276 | struct dpu_hw_cdm *hw_cdm; |
| 277 | u32 pending_flush = 0; | 277 | u32 pending_flush = 0; |
| 278 | u32 mode_3d; | ||
| 278 | 279 | ||
| 279 | if (!phys_enc) | 280 | if (!phys_enc) |
| 280 | return; | 281 | return; |
| @@ -283,6 +284,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 2 unmodified lines | |||
| 283 | hw_pp = phys_enc->hw_pp; | 284 | hw_pp = phys_enc->hw_pp; |
| 284 | hw_ctl = phys_enc->hw_ctl; | 285 | hw_ctl = phys_enc->hw_ctl; |
| 285 | hw_cdm = phys_enc->hw_cdm; | 286 | hw_cdm = phys_enc->hw_cdm; |
| 287 | mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); | ||
| 286 | 288 | ||
| 287 | DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); | 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 | if (hw_ctl->ops.update_pending_flush_wb) | 296 | if (hw_ctl->ops.update_pending_flush_wb) |
| 295 | hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx); | 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 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, | 301 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, |
| 299 | hw_pp->merge_3d->idx); | 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 | end_addr = base_addr + aligned_len; | 26 | end_addr = base_addr + aligned_len; |
| 27 | 27 | ||
| 28 | if (!(*reg)) | 28 | if (!(*reg)) |
| 29 | *reg = kzalloc(len_padded, GFP_KERNEL); | 29 | *reg = kvzalloc(len_padded, GFP_KERNEL); |
| 30 | 30 | ||
| 31 | if (*reg) | 31 | if (*reg) |
| 32 | dump_addr = *reg; | 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, | 51 | static void msm_disp_state_print_regs(const u32 *dump_addr, u32 len, |
| 52 | struct drm_printer *p) | 52 | void __iomem *base_addr, struct drm_printer *p) |
| 53 | { | 53 | { |
| 54 | int i; | 54 | int i; |
| 55 | u32 *dump_addr = NULL; | ||
| 56 | void __iomem *addr; | 55 | void __iomem *addr; |
| 57 | u32 num_rows; | 56 | u32 num_rows; |
| 58 | 57 | ||
| 58 | if (!dump_addr) { | ||
| 59 | drm_printf(p, "Registers not stored\n"); | ||
| 60 | return; | ||
| 61 | } | ||
| 62 | |||
| 59 | addr = base_addr; | 63 | addr = base_addr; |
| 60 | num_rows = len / REG_DUMP_ALIGN; | 64 | num_rows = len / REG_DUMP_ALIGN; |
| 61 | 65 | ||
| 62 | if (*reg) | ||
| 63 | dump_addr = *reg; | ||
| 64 | |||
| 65 | for (i = 0; i < num_rows; i++) { | 66 | for (i = 0; i < num_rows; i++) { |
| 66 | drm_printf(p, "0x%lx : %08x %08x %08x %08x\n", | 67 | drm_printf(p, "0x%lx : %08x %08x %08x %08x\n", |
| 67 | (unsigned long)(addr - base_addr), | 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 | list_for_each_entry_safe(block, tmp, &state->blocks, node) { | 91 | list_for_each_entry_safe(block, tmp, &state->blocks, node) { |
| 91 | drm_printf(p, "====================%s================\n", block->name); | 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 | drm_printf(p, "===================dpu drm state================\n"); | 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 | list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) { | 163 | list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) { |
| 163 | list_del(&block->node); | 164 | list_del(&block->node); |
| 164 | kfree(block->state); | 165 | kvfree(block->state); |
| 165 | kfree(block); | 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 | int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay; | 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 | static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, | 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 | unsigned long pclk_rate; | 551 | unsigned long pclk_rate; |
| 552 | 552 | ||
| 553 | pclk_rate = mode->clock * 1000; | 553 | pclk_rate = mode->clock * 1000u; |
| 554 | 554 | ||
| 555 | if (dsc) | 555 | if (dsc) |
| 556 | pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc); | 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 | return dividend - 1; | 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 | #define HDMI_REF_CLOCK_HZ ((u64)19200000) | 156 | #define HDMI_REF_CLOCK_HZ ((u64)19200000) |
| 166 | #define HDMI_MHZ_TO_HZ ((u64)1000000) | 157 | #define HDMI_MHZ_TO_HZ ((u64)1000000) |
| 167 | static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk) | 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 | } *rm; | 210 | } *rm; |
| 211 | 211 | ||
| 212 | struct { | 212 | struct { |
| 213 | struct mutex mutex;; | 213 | struct mutex mutex; |
| 214 | struct idr idr; | 214 | struct idr idr; |
| 215 | } client_id; | 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 | if (!spage || !(src & MIGRATE_PFN_MIGRATE)) | 193 | if (!spage || !(src & MIGRATE_PFN_MIGRATE)) |
| 194 | goto done; | 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 | if (!dpage) | 197 | if (!dpage) |
| 198 | goto done; | 198 | goto done; |
| 199 | 199 | ||
| @@ -331,7 +331,7 @@ nouveau_accel_ce_init(struct nouveau_drm *drm) · 330 unmodified lines | |||
| 331 | return; | 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 | if (ret) | 335 | if (ret) |
| 336 | NV_ERROR(drm, "failed to create ce channel, %d\n", ret); | 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 | msleep(60); | 298 | msleep(60); |
| 299 | 299 | ||
| 300 | hx83102_enable_extended_cmds(&dsi_ctx, true); | 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 | 0xf5, 0x39, 0x36, 0x36, 0x36, 0x36, 0x32, 0x8b, 0x11, 0x65, 0x00, 0x88, | 302 | 0xf5, 0x39, 0x36, 0x36, 0x36, 0x36, 0x32, 0x8b, 0x11, 0x65, 0x00, 0x88, |
| 303 | 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0xd6, 0x33); | 303 | 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0xd6, 0x33); |
| 304 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x00, 0x47, 0xb0, 0x80, 0x00, 0x12, | 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 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 343 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 345 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); | 345 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| 346 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, | 346 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, |
| 347 | 0x12, 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, | 347 | 0x48, 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, |
| 348 | 0x7a, 0x41, 0x50, 0x68, 0x73, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, 0x12, | 348 | 0x9c, 0x4d, 0x56, 0x5d, 0x73, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, 0x48, |
| 349 | 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, 0x7a, | 349 | 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, 0x9c, |
| 350 | 0x41, 0x50, 0x68, 0x73); | 350 | 0x4d, 0x56, 0x5d, 0x73); |
| 351 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e, | 351 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e, |
| 352 | 0x00, 0x4f, 0xa0, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0a, 0x02, | 352 | 0x00, 0x4f, 0xa0, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0a, 0x02, |
| 353 | 0x02, 0x00, 0x33, 0x02, 0x04, 0x18, 0x01); | 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 | .read = drm_read, | 1383 | .read = drm_read, |
| 1384 | .llseek = noop_llseek, | 1384 | .llseek = noop_llseek, |
| 1385 | .mmap = panthor_mmap, | 1385 | .mmap = panthor_mmap, |
| 1386 | .fop_flags = FOP_UNSIGNED_OFFSET, | ||
| 1386 | }; | 1387 | }; |
| 1387 | 1388 | ||
| 1388 | #ifdef CONFIG_DEBUG_FS | 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 | goto err_cleanup; | 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 | mutex_lock(&bo->gpuva_list_lock); | 1261 | mutex_lock(&bo->gpuva_list_lock); |
| 1255 | op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo); | 1262 | op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo); |
| 1256 | mutex_unlock(&bo->gpuva_list_lock); | 1263 | mutex_unlock(&bo->gpuva_list_lock); |
| 1264 | dma_resv_unlock(panthor_vm_resv(vm)); | ||
| 1257 | 1265 | ||
| 1258 | /* If the a vm_bo for this <VM,BO> combination exists, it already | 1266 | /* If the a vm_bo for this <VM,BO> combination exists, it already |
| 1259 | * retains a pin ref, and we can release the one we took earlier. | 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 | list_move_tail(&group->wait_node, | 1103 | list_move_tail(&group->wait_node, |
| 1104 | &group->ptdev->scheduler->groups.waiting); | 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 | queue->syncwait.gpu_va = cs_iface->output->status_wait_sync_ptr; | 1113 | queue->syncwait.gpu_va = cs_iface->output->status_wait_sync_ptr; |
| 1108 | queue->syncwait.ref = cs_iface->output->status_wait_sync_value; | 1114 | queue->syncwait.ref = cs_iface->output->status_wait_sync_value; |
| 1109 | status_wait_cond = cs_iface->output->status_wait & CS_STATUS_WAIT_SYNC_COND_MASK; | 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 | tick_ctx_cleanup(struct panthor_scheduler *sched, | 2052 | tick_ctx_cleanup(struct panthor_scheduler *sched, |
| 2047 | struct panthor_sched_tick_ctx *ctx) | 2053 | struct panthor_sched_tick_ctx *ctx) |
| 2048 | { | 2054 | { |
| 2055 | struct panthor_device *ptdev = sched->ptdev; | ||
| 2049 | struct panthor_group *group, *tmp; | 2056 | struct panthor_group *group, *tmp; |
| 2050 | u32 i; | 2057 | u32 i; |
| 2051 | 2058 | ||
| @@ -2054,7 +2061,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched, · 2 unmodified lines | |||
| 2054 | /* If everything went fine, we should only have groups | 2061 | /* If everything went fine, we should only have groups |
| 2055 | * to be terminated in the old_groups lists. | 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 | group_can_run(group)); | 2065 | group_can_run(group)); |
| 2059 | 2066 | ||
| 2060 | if (!group_can_run(group)) { | 2067 | if (!group_can_run(group)) { |
| @@ -2077,7 +2084,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched, · 16 unmodified lines | |||
| 2077 | /* If everything went fine, the groups to schedule lists should | 2084 | /* If everything went fine, the groups to schedule lists should |
| 2078 | * be empty. | 2085 | * be empty. |
| 2079 | */ | 2086 | */ |
| 2080 | drm_WARN_ON(&group->ptdev->base, | 2087 | drm_WARN_ON(&ptdev->base, |
| 2081 | !ctx->csg_upd_failed_mask && !list_empty(&ctx->groups[i])); | 2088 | !ctx->csg_upd_failed_mask && !list_empty(&ctx->groups[i])); |
| 2082 | 2089 | ||
| 2083 | list_for_each_entry_safe(group, tmp, &ctx->groups[i], run_node) { | 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 | return 0; | 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 | int panthor_group_get_state(struct panthor_file *pfile, | 3264 | int panthor_group_get_state(struct panthor_file *pfile, |
| 3246 | struct drm_panthor_group_get_state *get_state) | 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 | if (get_state->pad) | 3272 | if (get_state->pad) |
| 3254 | return -EINVAL; | 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 | if (!group) | 3276 | if (!group) |
| 3258 | return -EINVAL; | 3277 | return -EINVAL; |
| 3259 | 3278 | ||
| @@ -3384,7 +3403,7 @@ panthor_job_create(struct panthor_file *pfile, · 124 unmodified lines | |||
| 3384 | job->call_info.latest_flush = qsubmit->latest_flush; | 3403 | job->call_info.latest_flush = qsubmit->latest_flush; |
| 3385 | INIT_LIST_HEAD(&job->node); | 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 | if (!job->group) { | 3407 | if (!job->group) { |
| 3389 | ret = -EINVAL; | 3408 | ret = -EINVAL; |
| 3390 | goto err_put_job; | 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 | struct panthor_job *job = container_of(sched_job, struct panthor_job, base); | 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 | panthor_vm_update_resvs(job->group->vm, exec, &sched_job->s_fence->finished, | 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 | void panthor_sched_unplug(struct panthor_device *ptdev) | 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 | struct drm_device *dev = radeon_connector->base.dev; | 229 | struct drm_device *dev = radeon_connector->base.dev; |
| 230 | struct radeon_device *rdev = dev->dev_private; | 230 | struct radeon_device *rdev = dev->dev_private; |
| 231 | int ret; | ||
| 232 | 231 | ||
| 233 | radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd; | 232 | radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd; |
| 234 | radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; | ||
| 235 | radeon_connector->ddc_bus->aux.drm_dev = radeon_connector->base.dev; | 233 | radeon_connector->ddc_bus->aux.drm_dev = radeon_connector->base.dev; |
| 236 | if (ASIC_IS_DCE5(rdev)) { | 234 | if (ASIC_IS_DCE5(rdev)) { |
| 237 | if (radeon_auxch) | 235 | if (radeon_auxch) |
| @@ -242,11 +240,8 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector) · 4 unmodified lines | |||
| 242 | radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom; | 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); | 243 | drm_dp_aux_init(&radeon_connector->ddc_bus->aux); |
| 246 | if (!ret) | 244 | radeon_connector->ddc_bus->has_aux = true; |
| 247 | radeon_connector->ddc_bus->has_aux = true; | ||
| 248 | |||
| 249 | WARN(ret, "drm_dp_aux_register() failed with error %d\n", ret); | ||
| 250 | } | 245 | } |
| 251 | 246 | ||
| 252 | /***** general DP utility functions *****/ | 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 | return MODE_OK; | 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 | static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { | 1803 | static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { |
| 1790 | .get_modes = radeon_dp_get_modes, | 1804 | .get_modes = radeon_dp_get_modes, |
| 1791 | .mode_valid = radeon_dp_mode_valid, | 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 | .early_unregister = radeon_connector_unregister, | 1814 | .early_unregister = radeon_connector_unregister, |
| 1801 | .destroy = radeon_connector_destroy, | 1815 | .destroy = radeon_connector_destroy, |
| 1802 | .force = radeon_dvi_force, | 1816 | .force = radeon_dvi_force, |
| 1817 | .late_register = radeon_connector_late_register, | ||
| 1803 | }; | 1818 | }; |
| 1804 | 1819 | ||
| 1805 | static const struct drm_connector_funcs radeon_edp_connector_funcs = { | 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 | .early_unregister = radeon_connector_unregister, | 1825 | .early_unregister = radeon_connector_unregister, |
| 1811 | .destroy = radeon_connector_destroy, | 1826 | .destroy = radeon_connector_destroy, |
| 1812 | .force = radeon_dvi_force, | 1827 | .force = radeon_dvi_force, |
| 1828 | .late_register = radeon_connector_late_register, | ||
| 1813 | }; | 1829 | }; |
| 1814 | 1830 | ||
| 1815 | static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = { | 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 | .early_unregister = radeon_connector_unregister, | 1836 | .early_unregister = radeon_connector_unregister, |
| 1821 | .destroy = radeon_connector_destroy, | 1837 | .destroy = radeon_connector_destroy, |
| 1822 | .force = radeon_dvi_force, | 1838 | .force = radeon_dvi_force, |
| 1839 | .late_register = radeon_connector_late_register, | ||
| 1823 | }; | 1840 | }; |
| 1824 | 1841 | ||
| 1825 | void | 1842 | void |
| @@ -43,7 +43,7 @@ static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) · 42 unmodified lines | |||
| 43 | struct radeon_device *rdev = dev->dev_private; | 43 | struct radeon_device *rdev = dev->dev_private; |
| 44 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 44 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 45 | struct drm_encoder *clone_encoder; | 45 | struct drm_encoder *clone_encoder; |
| 46 | uint32_t index_mask = 0; | 46 | uint32_t index_mask = drm_encoder_mask(encoder); |
| 47 | int count; | 47 | int count; |
| 48 | 48 | ||
| 49 | /* DIG routing gets problematic */ | 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 | int radeon_gem_prime_pin(struct drm_gem_object *obj); | 44 | int radeon_gem_prime_pin(struct drm_gem_object *obj); |
| 45 | void radeon_gem_prime_unpin(struct drm_gem_object *obj); | 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 | static vm_fault_t radeon_gem_fault(struct vm_fault *vmf) | 47 | static vm_fault_t radeon_gem_fault(struct vm_fault *vmf) |
| 50 | { | 48 | { |
| 51 | struct ttm_buffer_object *bo = vmf->vma->vm_private_data; | 49 | struct ttm_buffer_object *bo = vmf->vma->vm_private_data; |
| @@ -132,7 +130,6 @@ retry: · 80 unmodified lines | |||
| 132 | return r; | 130 | return r; |
| 133 | } | 131 | } |
| 134 | *obj = &robj->tbo.base; | 132 | *obj = &robj->tbo.base; |
| 135 | (*obj)->funcs = &radeon_gem_object_funcs; | ||
| 136 | robj->pid = task_pid_nr(current); | 133 | robj->pid = task_pid_nr(current); |
| 137 | 134 | ||
| 138 | mutex_lock(&rdev->gem.mutex); | 135 | mutex_lock(&rdev->gem.mutex); |
| @@ -151,6 +151,7 @@ int radeon_bo_create(struct radeon_device *rdev, · 150 unmodified lines | |||
| 151 | if (bo == NULL) | 151 | if (bo == NULL) |
| 152 | return -ENOMEM; | 152 | return -ENOMEM; |
| 153 | drm_gem_private_object_init(rdev_to_drm(rdev), &bo->tbo.base, size); | 153 | drm_gem_private_object_init(rdev_to_drm(rdev), &bo->tbo.base, size); |
| 154 | bo->tbo.base.funcs = &radeon_gem_object_funcs; | ||
| 154 | bo->rdev = rdev; | 155 | bo->rdev = rdev; |
| 155 | bo->surface_reg = -1; | 156 | bo->surface_reg = -1; |
| 156 | INIT_LIST_HEAD(&bo->list); | 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 | WARN_ON(!num_sched_list || !sched_list); | 134 | WARN_ON(!num_sched_list || !sched_list); |
| 135 | 135 | ||
| 136 | spin_lock(&entity->rq_lock); | ||
| 136 | entity->sched_list = sched_list; | 137 | entity->sched_list = sched_list; |
| 137 | entity->num_sched_list = num_sched_list; | 138 | entity->num_sched_list = num_sched_list; |
| 139 | spin_unlock(&entity->rq_lock); | ||
| 138 | } | 140 | } |
| 139 | EXPORT_SYMBOL(drm_sched_entity_modify_sched); | 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 | container_of(cb, struct drm_sched_entity, cb); | 382 | container_of(cb, struct drm_sched_entity, cb); |
| 381 | 383 | ||
| 382 | drm_sched_entity_clear_dep(f, cb); | 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 | /* first job wakes up scheduler */ | 600 | /* first job wakes up scheduler */ |
| 599 | if (first) { | 601 | if (first) { |
| 602 | struct drm_gpu_scheduler *sched; | ||
| 603 | struct drm_sched_rq *rq; | ||
| 604 | |||
| 600 | /* Add the entity to the run queue */ | 605 | /* Add the entity to the run queue */ |
| 601 | spin_lock(&entity->rq_lock); | 606 | spin_lock(&entity->rq_lock); |
| 602 | if (entity->stopped) { | 607 | if (entity->stopped) { |
| @@ -606,13 +611,16 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) · 3 unmodified lines | |||
| 606 | return; | 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 | spin_unlock(&entity->rq_lock); | 618 | spin_unlock(&entity->rq_lock); |
| 611 | 619 | ||
| 612 | if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) | 620 | if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) |
| 613 | drm_sched_rq_update_fifo(entity, submit_ts); | 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 | EXPORT_SYMBOL(drm_sched_entity_push_job); | 626 | EXPORT_SYMBOL(drm_sched_entity_push_job); |
| @@ -87,6 +87,12 @@ · 86 unmodified lines | |||
| 87 | #define CREATE_TRACE_POINTS | 87 | #define CREATE_TRACE_POINTS |
| 88 | #include "gpu_scheduler_trace.h" | 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 | #define to_drm_sched_job(sched_job) \ | 96 | #define to_drm_sched_job(sched_job) \ |
| 91 | container_of((sched_job), struct drm_sched_job, queue_node) | 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 | * drm_sched_wakeup - Wake up the scheduler if it is ready to queue | 1020 | * drm_sched_wakeup - Wake up the scheduler if it is ready to queue |
| 1015 | * @sched: scheduler instance | 1021 | * @sched: scheduler instance |
| 1016 | * @entity: the scheduler entity | ||
| 1017 | * | 1022 | * |
| 1018 | * Wake up the scheduler if we can queue jobs. | 1023 | * Wake up the scheduler if we can queue jobs. |
| 1019 | */ | 1024 | */ |
| 1020 | void drm_sched_wakeup(struct drm_gpu_scheduler *sched, | 1025 | void drm_sched_wakeup(struct drm_gpu_scheduler *sched) |
| 1021 | struct drm_sched_entity *entity) | ||
| 1022 | { | 1026 | { |
| 1023 | if (drm_sched_can_queue(sched, entity)) | 1027 | drm_sched_run_job_queue(sched); |
| 1024 | 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 | sched->submit_wq = submit_wq; | 1275 | sched->submit_wq = submit_wq; |
| 1273 | sched->own_submit_wq = false; | 1276 | sched->own_submit_wq = false; |
| 1274 | } else { | 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 | sched->submit_wq = alloc_ordered_workqueue(name, 0); | 1282 | sched->submit_wq = alloc_ordered_workqueue(name, 0); |
| 1283 | #endif | ||
| 1276 | if (!sched->submit_wq) | 1284 | if (!sched->submit_wq) |
| 1277 | return -ENOMEM; | 1285 | return -ENOMEM; |
| 1278 | 1286 | ||
| @@ -46,7 +46,6 @@ struct gr3d { · 45 unmodified lines | |||
| 46 | unsigned int nclocks; | 46 | unsigned int nclocks; |
| 47 | struct reset_control_bulk_data resets[RST_GR3D_MAX]; | 47 | struct reset_control_bulk_data resets[RST_GR3D_MAX]; |
| 48 | unsigned int nresets; | 48 | unsigned int nresets; |
| 49 | struct dev_pm_domain_list *pd_list; | ||
| 50 | 49 | ||
| 51 | DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); | 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 | return 0; | 369 | return 0; |
| 371 | } | 370 | } |
| 372 | 371 | ||
| 372 | static void gr3d_del_link(void *link) | ||
| 373 | { | ||
| 374 | device_link_del(link); | ||
| 375 | } | ||
| 376 | |||
| 373 | static int gr3d_init_power(struct device *dev, struct gr3d *gr3d) | 377 | static int gr3d_init_power(struct device *dev, struct gr3d *gr3d) |
| 374 | { | 378 | { |
| 375 | struct dev_pm_domain_attach_data pd_data = { | 379 | static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL }; |
| 376 | .pd_names = (const char *[]) { "3d0", "3d1" }, | 380 | const u32 link_flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; |
| 377 | .num_pd_names = 2, | 381 | struct device **opp_virt_devs, *pd_dev; |
| 378 | }; | 382 | struct device_link *link; |
| 383 | unsigned int i; | ||
| 379 | int err; | 384 | int err; |
| 380 | 385 | ||
| 381 | err = of_count_phandle_with_args(dev->of_node, "power-domains", | 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 | if (dev->pm_domain) | 414 | if (dev->pm_domain) |
| 410 | return 0; | 415 | return 0; |
| 411 | 416 | ||
| 412 | err = dev_pm_domain_attach_list(dev, &pd_data, &gr3d->pd_list); | 417 | err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs); |
| 413 | if (err < 0) | 418 | if (err) |
| 414 | return err; | 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 | return 0; | 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 | err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); | 528 | err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); |
| 505 | if (err) | 529 | if (err) |
| 506 | goto err; | 530 | return err; |
| 507 | 531 | ||
| 508 | err = host1x_client_register(&gr3d->client.base); | 532 | err = host1x_client_register(&gr3d->client.base); |
| 509 | if (err < 0) { | 533 | if (err < 0) { |
| 510 | dev_err(&pdev->dev, "failed to register host1x client: %d\n", | 534 | dev_err(&pdev->dev, "failed to register host1x client: %d\n", |
| 511 | err); | 535 | err); |
| 512 | goto err; | 536 | return err; |
| 513 | } | 537 | } |
| 514 | 538 | ||
| 515 | /* initialize address register map */ | 539 | /* initialize address register map */ |
| @@ -517,9 +541,6 @@ static int gr3d_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 517 | set_bit(gr3d_addr_regs[i], gr3d->addr_regs); | 541 | set_bit(gr3d_addr_regs[i], gr3d->addr_regs); |
| 518 | 542 | ||
| 519 | return 0; | 543 | return 0; |
| 520 | err: | ||
| 521 | dev_pm_domain_detach_list(gr3d->pd_list); | ||
| 522 | return err; | ||
| 523 | } | 544 | } |
| 524 | 545 | ||
| 525 | static void gr3d_remove(struct platform_device *pdev) | 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 | pm_runtime_disable(&pdev->dev); | 550 | pm_runtime_disable(&pdev->dev); |
| 530 | host1x_client_unregister(&gr3d->client.base); | 551 | host1x_client_unregister(&gr3d->client.base); |
| 531 | dev_pm_domain_detach_list(gr3d->pd_list); | ||
| 532 | } | 552 | } |
| 533 | 553 | ||
| 534 | static int __maybe_unused gr3d_runtime_suspend(struct device *dev) | 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 | static int v3d_perfmon_idr_del(int id, void *elem, void *data) | 306 | static int v3d_perfmon_idr_del(int id, void *elem, void *data) |
| 307 | { | 307 | { |
| 308 | struct v3d_perfmon *perfmon = elem; | 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 | v3d_perfmon_put(perfmon); | 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 | void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv) | 320 | void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv) |
| 316 | { | 321 | { |
| 322 | struct v3d_dev *v3d = v3d_priv->v3d; | ||
| 323 | |||
| 317 | mutex_lock(&v3d_priv->perfmon.lock); | 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 | idr_destroy(&v3d_priv->perfmon.idr); | 326 | idr_destroy(&v3d_priv->perfmon.idr); |
| 320 | mutex_unlock(&v3d_priv->perfmon.lock); | 327 | mutex_unlock(&v3d_priv->perfmon.lock); |
| 321 | mutex_destroy(&v3d_priv->perfmon.lock); | 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 | flags |= VBOX_MOUSE_POINTER_VISIBLE; | 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 | VBVA_MOUSE_POINTER_SHAPE); | 151 | VBVA_MOUSE_POINTER_SHAPE); |
| 144 | if (!p) | 152 | if (!p) |
| 145 | return -ENOMEM; | 153 | return -ENOMEM; |
| @@ -351,10 +351,8 @@ struct vbva_mouse_pointer_shape { · 350 unmodified lines | |||
| 351 | * Bytes in the gap between the AND and the XOR mask are undefined. | 351 | * Bytes in the gap between the AND and the XOR mask are undefined. |
| 352 | * XOR mask scanlines have no gap between them and size of XOR mask is: | 352 | * XOR mask scanlines have no gap between them and size of XOR mask is: |
| 353 | * xor_len = width * 4 * height. | 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 | } __packed; | 356 | } __packed; |
| 359 | 357 | ||
| 360 | /* pointer is visible */ | 358 | /* pointer is visible */ |
| @@ -116,6 +116,11 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file) · 115 unmodified lines | |||
| 116 | static int vc4_perfmon_idr_del(int id, void *elem, void *data) | 116 | static int vc4_perfmon_idr_del(int id, void *elem, void *data) |
| 117 | { | 117 | { |
| 118 | struct vc4_perfmon *perfmon = elem; | 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 | vc4_perfmon_put(perfmon); | 125 | vc4_perfmon_put(perfmon); |
| 121 | 126 | ||
| @@ -130,7 +135,7 @@ void vc4_perfmon_close_file(struct vc4_file *vc4file) · 8 unmodified lines | |||
| 130 | return; | 135 | return; |
| 131 | 136 | ||
| 132 | mutex_lock(&vc4file->perfmon.lock); | 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 | idr_destroy(&vc4file->perfmon.idr); | 139 | idr_destroy(&vc4file->perfmon.idr); |
| 135 | mutex_unlock(&vc4file->perfmon.lock); | 140 | mutex_unlock(&vc4file->perfmon.lock); |
| 136 | mutex_destroy(&vc4file->perfmon.lock); | 141 | mutex_destroy(&vc4file->perfmon.lock); |
| @@ -635,10 +635,8 @@ out: · 634 unmodified lines | |||
| 635 | kunmap_atomic(d.src_addr); | 635 | kunmap_atomic(d.src_addr); |
| 636 | if (d.dst_addr) | 636 | if (d.dst_addr) |
| 637 | kunmap_atomic(d.dst_addr); | 637 | kunmap_atomic(d.dst_addr); |
| 638 | if (src_pages) | 638 | kvfree(src_pages); |
| 639 | kvfree(src_pages); | 639 | kvfree(dst_pages); |
| 640 | if (dst_pages) | ||
| 641 | kvfree(dst_pages); | ||
| 642 | 640 | ||
| 643 | return ret; | 641 | return ret; |
| 644 | } | 642 | } |
| @@ -62,7 +62,7 @@ · 61 unmodified lines | |||
| 62 | #define VMWGFX_DRIVER_MINOR 20 | 62 | #define VMWGFX_DRIVER_MINOR 20 |
| 63 | #define VMWGFX_DRIVER_PATCHLEVEL 0 | 63 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
| 64 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) | 64 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
| 65 | #define VMWGFX_MAX_DISPLAYS 16 | 65 | #define VMWGFX_NUM_DISPLAY_UNITS 8 |
| 66 | #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768 | 66 | #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768 |
| 67 | 67 | ||
| 68 | #define VMWGFX_MIN_INITIAL_WIDTH 1280 | 68 | #define VMWGFX_MIN_INITIAL_WIDTH 1280 |
| @@ -82,7 +82,7 @@ · 13 unmodified lines | |||
| 82 | #define VMWGFX_NUM_GB_CONTEXT 256 | 82 | #define VMWGFX_NUM_GB_CONTEXT 256 |
| 83 | #define VMWGFX_NUM_GB_SHADER 20000 | 83 | #define VMWGFX_NUM_GB_SHADER 20000 |
| 84 | #define VMWGFX_NUM_GB_SURFACE 32768 | 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 | #define VMWGFX_NUM_DXCONTEXT 256 | 86 | #define VMWGFX_NUM_DXCONTEXT 256 |
| 87 | #define VMWGFX_NUM_DXQUERY 512 | 87 | #define VMWGFX_NUM_DXQUERY 512 |
| 88 | #define VMWGFX_NUM_MOB (VMWGFX_NUM_GB_CONTEXT +\ | 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 | struct drm_device *dev = &dev_priv->drm; | 1284 | struct drm_device *dev = &dev_priv->drm; |
| 1285 | struct vmw_framebuffer_surface *vfbs; | 1285 | struct vmw_framebuffer_surface *vfbs; |
| 1286 | enum SVGA3dSurfaceFormat format; | ||
| 1287 | struct vmw_surface *surface; | 1286 | struct vmw_surface *surface; |
| 1288 | int ret; | 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 | return -EINVAL; | 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 | vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL); | 1322 | vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL); |
| 1352 | if (!vfbs) { | 1323 | if (!vfbs) { |
| 1353 | ret = -ENOMEM; | 1324 | ret = -ENOMEM; |
| @@ -1539,6 +1510,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, · 185 unmodified lines | |||
| 1539 | DRM_ERROR("Surface size cannot exceed %dx%d\n", | 1510 | DRM_ERROR("Surface size cannot exceed %dx%d\n", |
| 1540 | dev_priv->texture_max_width, | 1511 | dev_priv->texture_max_width, |
| 1541 | dev_priv->texture_max_height); | 1512 | dev_priv->texture_max_height); |
| 1513 | ret = -EINVAL; | ||
| 1542 | goto err_out; | 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 | struct drm_mode_config *mode_config = &dev->mode_config; | 2197 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 2226 | struct drm_vmw_update_layout_arg *arg = | 2198 | struct drm_vmw_update_layout_arg *arg = |
| 2227 | (struct drm_vmw_update_layout_arg *)data; | 2199 | (struct drm_vmw_update_layout_arg *)data; |
| 2228 | void __user *user_rects; | 2200 | const void __user *user_rects; |
| 2229 | struct drm_vmw_rect *rects; | 2201 | struct drm_vmw_rect *rects; |
| 2230 | struct drm_rect *drm_rects; | 2202 | struct drm_rect *drm_rects; |
| 2231 | unsigned rects_size; | 2203 | unsigned rects_size; |
| @@ -2237,6 +2209,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, · 5 unmodified lines | |||
| 2237 | VMWGFX_MIN_INITIAL_HEIGHT}; | 2209 | VMWGFX_MIN_INITIAL_HEIGHT}; |
| 2238 | vmw_du_update_layout(dev_priv, 1, &def_rect); | 2210 | vmw_du_update_layout(dev_priv, 1, &def_rect); |
| 2239 | return 0; | 2211 | return 0; |
| 2212 | } else if (arg->num_outputs > VMWGFX_NUM_DISPLAY_UNITS) { | ||
| 2213 | return -E2BIG; | ||
| 2240 | } | 2214 | } |
| 2241 | 2215 | ||
| 2242 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); | 2216 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); |
| @@ -199,9 +199,6 @@ struct vmw_kms_dirty { · 198 unmodified lines | |||
| 199 | s32 unit_y2; | 199 | s32 unit_y2; |
| 200 | }; | 200 | }; |
| 201 | 201 | ||
| 202 | #define VMWGFX_NUM_DISPLAY_UNITS 8 | ||
| 203 | |||
| 204 | |||
| 205 | #define vmw_framebuffer_to_vfb(x) \ | 202 | #define vmw_framebuffer_to_vfb(x) \ |
| 206 | container_of(x, struct vmw_framebuffer, base) | 203 | container_of(x, struct vmw_framebuffer, base) |
| 207 | #define vmw_framebuffer_to_vfbs(x) \ | 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 | struct drm_crtc_state *new_crtc_state; | 886 | struct drm_crtc_state *new_crtc_state; |
| 887 | 887 | ||
| 888 | conn_state = drm_atomic_get_connector_state(state, conn); | 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 | du = vmw_connector_to_stdu(conn); | 893 | du = vmw_connector_to_stdu(conn); |
| 890 | 894 | ||
| 891 | if (!conn_state->crtc) | 895 | if (!conn_state->crtc) |
| @@ -2276,9 +2276,12 @@ int vmw_dumb_create(struct drm_file *file_priv, · 2275 unmodified lines | |||
| 2276 | const struct SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format); | 2276 | const struct SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format); |
| 2277 | SVGA3dSurfaceAllFlags flags = SVGA3D_SURFACE_HINT_TEXTURE | | 2277 | SVGA3dSurfaceAllFlags flags = SVGA3D_SURFACE_HINT_TEXTURE | |
| 2278 | SVGA3D_SURFACE_HINT_RENDERTARGET | | 2278 | SVGA3D_SURFACE_HINT_RENDERTARGET | |
| 2279 | SVGA3D_SURFACE_SCREENTARGET | | 2279 | SVGA3D_SURFACE_SCREENTARGET; |
| 2280 | SVGA3D_SURFACE_BIND_SHADER_RESOURCE | | 2280 | |
| 2281 | SVGA3D_SURFACE_BIND_RENDER_TARGET; | 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 | * Without mob support we're just going to use raw memory buffer | 2287 | * Without mob support we're just going to use raw memory buffer |
| @@ -169,6 +169,8 @@ · 168 unmodified lines | |||
| 169 | #define XEHP_SLICE_COMMON_ECO_CHICKEN1 XE_REG_MCR(0x731c, XE_REG_OPTION_MASKED) | 169 | #define XEHP_SLICE_COMMON_ECO_CHICKEN1 XE_REG_MCR(0x731c, XE_REG_OPTION_MASKED) |
| 170 | #define MSC_MSAA_REODER_BUF_BYPASS_DISABLE REG_BIT(14) | 170 | #define MSC_MSAA_REODER_BUF_BYPASS_DISABLE REG_BIT(14) |
| 171 | 171 | ||
| 172 | #define XE2LPM_CCCHKNREG1 XE_REG(0x82a8) | ||
| 173 | |||
| 172 | #define VF_PREEMPTION XE_REG(0x83a4, XE_REG_OPTION_MASKED) | 174 | #define VF_PREEMPTION XE_REG(0x83a4, XE_REG_OPTION_MASKED) |
| 173 | #define PREEMPTION_VERTEX_COUNT REG_GENMASK(15, 0) | 175 | #define PREEMPTION_VERTEX_COUNT REG_GENMASK(15, 0) |
| 174 | 176 | ||
| @@ -378,6 +380,9 @@ · 203 unmodified lines | |||
| 378 | #define L3SQCREG3 XE_REG_MCR(0xb108) | 380 | #define L3SQCREG3 XE_REG_MCR(0xb108) |
| 379 | #define COMPPWOVERFETCHEN REG_BIT(28) | 381 | #define COMPPWOVERFETCHEN REG_BIT(28) |
| 380 | 382 | ||
| 383 | #define SCRATCH3_LBCF XE_REG_MCR(0xb154) | ||
| 384 | #define RWFLUSHALLEN REG_BIT(17) | ||
| 385 | |||
| 381 | #define XEHP_L3SQCREG5 XE_REG_MCR(0xb158) | 386 | #define XEHP_L3SQCREG5 XE_REG_MCR(0xb158) |
| 382 | #define L3_PWM_TIMER_INIT_VAL_MASK REG_GENMASK(9, 0) | 387 | #define L3_PWM_TIMER_INIT_VAL_MASK REG_GENMASK(9, 0) |
| 383 | 388 | ||
| @@ -388,8 +393,11 @@ · 4 unmodified lines | |||
| 388 | 393 | ||
| 389 | #define XE2_GLOBAL_INVAL XE_REG(0xb404) | 394 | #define XE2_GLOBAL_INVAL XE_REG(0xb404) |
| 390 | 395 | ||
| 391 | #define SCRATCH1LPFC XE_REG(0xb474) | 396 | #define XE2LPM_L3SQCREG2 XE_REG_MCR(0xb604) |
| 392 | #define EN_L3_RW_CCS_CACHE_FLUSH REG_BIT(0) | 397 | |
| 398 | #define XE2LPM_L3SQCREG3 XE_REG_MCR(0xb608) | ||
| 399 | |||
| 400 | #define XE2LPM_SCRATCH3_LBCF XE_REG_MCR(0xb654) | ||
| 393 | 401 | ||
| 394 | #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) | 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 | tt_has_data = ttm && (ttm_tt_is_populated(ttm) || | 680 | tt_has_data = ttm && (ttm_tt_is_populated(ttm) || |
| 681 | (ttm->page_flags & TTM_TT_FLAG_SWAPPED)); | 681 | (ttm->page_flags & TTM_TT_FLAG_SWAPPED)); |
| 682 | 682 | ||
| 683 | move_lacks_source = handle_system_ccs ? (!bo->ccs_cleared) : | 683 | move_lacks_source = !old_mem || (handle_system_ccs ? (!bo->ccs_cleared) : |
| 684 | (!mem_type_is_vram(old_mem_type) && !tt_has_data); | 684 | (!mem_type_is_vram(old_mem_type) && !tt_has_data)); |
| 685 | 685 | ||
| 686 | needs_clear = (ttm && ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) || | 686 | needs_clear = (ttm && ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) || |
| 687 | (!ttm && ttm_bo->type == ttm_bo_type_device); | 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 | debugfs_create_file("forcewake_all", 0400, root, xe, | 187 | debugfs_create_file("forcewake_all", 0400, root, xe, |
| 188 | &forcewake_all_fops); | 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 | &wedged_mode_fops); | 191 | &wedged_mode_fops); |
| 192 | 192 | ||
| 193 | for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) { | 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 | xe_exec_queue_kill(q); | 171 | xe_exec_queue_kill(q); |
| 172 | xe_exec_queue_put(q); | 172 | xe_exec_queue_put(q); |
| 173 | } | 173 | } |
| 174 | mutex_lock(&xef->vm.lock); | ||
| 175 | xa_for_each(&xef->vm.xa, idx, vm) | 174 | xa_for_each(&xef->vm.xa, idx, vm) |
| 176 | xe_vm_close_and_put(vm); | 175 | xe_vm_close_and_put(vm); |
| 177 | mutex_unlock(&xef->vm.lock); | ||
| 178 | 176 | ||
| 179 | xe_file_put(xef); | 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 | if (xe->unordered_wq) | 296 | if (xe->unordered_wq) |
| 299 | destroy_workqueue(xe->unordered_wq); | 297 | destroy_workqueue(xe->unordered_wq); |
| 300 | 298 | ||
| 299 | if (xe->destroy_wq) | ||
| 300 | destroy_workqueue(xe->destroy_wq); | ||
| 301 | |||
| 301 | ttm_device_fini(&xe->ttm); | 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 | init_waitqueue_head(&xe->ufence_wq); | 338 | init_waitqueue_head(&xe->ufence_wq); |
| 338 | 339 | ||
| 339 | err = drmm_mutex_init(&xe->drm, &xe->usm.lock); | 340 | init_rwsem(&xe->usm.lock); |
| 340 | if (err) | ||
| 341 | goto err; | ||
| 342 | 341 | ||
| 343 | xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC); | 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 | xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0); | 362 | xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0); |
| 364 | xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0); | 363 | xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0); |
| 365 | xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0); | 364 | xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0); |
| 365 | xe->destroy_wq = alloc_workqueue("xe-destroy-wq", 0, 0); | ||
| 366 | if (!xe->ordered_wq || !xe->unordered_wq || | 366 | if (!xe->ordered_wq || !xe->unordered_wq || |
| 367 | !xe->preempt_fence_wq) { | 367 | !xe->preempt_fence_wq || !xe->destroy_wq) { |
| 368 | /* | 368 | /* |
| 369 | * Cleanup done in xe_device_destroy via | 369 | * Cleanup done in xe_device_destroy via |
| 370 | * drmm_add_action_or_reset register above | 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 | return; | 980 | return; |
| 981 | } | 981 | } |
| 982 | 982 | ||
| 983 | xe_pm_runtime_get_noresume(xe); | ||
| 984 | |||
| 983 | if (drmm_add_action_or_reset(&xe->drm, xe_device_wedged_fini, xe)) { | 985 | if (drmm_add_action_or_reset(&xe->drm, xe_device_wedged_fini, xe)) { |
| 984 | drm_err(&xe->drm, "Failed to register xe_device_wedged_fini clean-up. Although device is wedged.\n"); | 986 | drm_err(&xe->drm, "Failed to register xe_device_wedged_fini clean-up. Although device is wedged.\n"); |
| 985 | return; | 987 | return; |
| 986 | } | 988 | } |
| 987 | 989 | ||
| 988 | xe_pm_runtime_get_noresume(xe); | ||
| 989 | |||
| 990 | if (!atomic_xchg(&xe->wedged.flag, 1)) { | 990 | if (!atomic_xchg(&xe->wedged.flag, 1)) { |
| 991 | xe->needs_flr_on_fini = true; | 991 | xe->needs_flr_on_fini = true; |
| 992 | drm_err(&xe->drm, | 992 | drm_err(&xe->drm, |
| @@ -369,7 +369,7 @@ struct xe_device { · 368 unmodified lines | |||
| 369 | /** @usm.next_asid: next ASID, used to cyclical alloc asids */ | 369 | /** @usm.next_asid: next ASID, used to cyclical alloc asids */ |
| 370 | u32 next_asid; | 370 | u32 next_asid; |
| 371 | /** @usm.lock: protects UM state */ | 371 | /** @usm.lock: protects UM state */ |
| 372 | struct mutex lock; | 372 | struct rw_semaphore lock; |
| 373 | } usm; | 373 | } usm; |
| 374 | 374 | ||
| 375 | /** @pinned: pinned BO state */ | 375 | /** @pinned: pinned BO state */ |
| @@ -396,6 +396,9 @@ struct xe_device { · 20 unmodified lines | |||
| 396 | /** @unordered_wq: used to serialize unordered work, mostly display */ | 396 | /** @unordered_wq: used to serialize unordered work, mostly display */ |
| 397 | struct workqueue_struct *unordered_wq; | 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 | /** @tiles: device tiles */ | 402 | /** @tiles: device tiles */ |
| 400 | struct xe_tile tiles[XE_MAX_TILES_PER_DEVICE]; | 403 | struct xe_tile tiles[XE_MAX_TILES_PER_DEVICE]; |
| 401 | 404 | ||
| @@ -567,15 +570,23 @@ struct xe_file { · 165 unmodified lines | |||
| 567 | struct { | 570 | struct { |
| 568 | /** @vm.xe: xarray to store VMs */ | 571 | /** @vm.xe: xarray to store VMs */ |
| 569 | struct xarray xa; | 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 | struct mutex lock; | 578 | struct mutex lock; |
| 572 | } vm; | 579 | } vm; |
| 573 | 580 | ||
| 574 | /** @exec_queue: Submission exec queue state for file */ | 581 | /** @exec_queue: Submission exec queue state for file */ |
| 575 | struct { | 582 | struct { |
| 576 | /** @exec_queue.xe: xarray to store engines */ | 583 | /** @exec_queue.xa: xarray to store exece queues */ |
| 577 | struct xarray xa; | 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 | struct mutex lock; | 590 | struct mutex lock; |
| 580 | } exec_queue; | 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 | /* Accumulate all the exec queues from this client */ | 284 | /* Accumulate all the exec queues from this client */ |
| 285 | mutex_lock(&xef->exec_queue.lock); | 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 | xe_exec_queue_update_run_ticks(q); | 290 | xe_exec_queue_update_run_ticks(q); |
| 291 | |||
| 292 | mutex_lock(&xef->exec_queue.lock); | ||
| 293 | xe_exec_queue_put(q); | ||
| 294 | } | ||
| 288 | mutex_unlock(&xef->exec_queue.lock); | 295 | mutex_unlock(&xef->exec_queue.lock); |
| 289 | 296 | ||
| 290 | /* Get the total GPU cycles */ | 297 | /* Get the total GPU cycles */ |
| @@ -41,11 +41,6 @@ · 40 unmodified lines | |||
| 41 | * user knows an exec writes to a BO and reads from the BO in the next exec, it | 41 | * user knows an exec writes to a BO and reads from the BO in the next exec, it |
| 42 | * is the user's responsibility to pass in / out fence between the two execs). | 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 | * We do not allow a user to trigger a bind at exec time rather we have a VM | 44 | * We do not allow a user to trigger a bind at exec time rather we have a VM |
| 50 | * bind IOCTL which uses the same in / out fence interface as exec. In that | 45 | * bind IOCTL which uses the same in / out fence interface as exec. In that |
| 51 | * sense, a VM bind is basically the same operation as an exec from the user | 46 | * sense, a VM bind is basically the same operation as an exec from the user |
| @@ -59,8 +54,8 @@ · 7 unmodified lines | |||
| 59 | * behind any pending kernel operations on any external BOs in VM or any BOs | 54 | * behind any pending kernel operations on any external BOs in VM or any BOs |
| 60 | * private to the VM. This is accomplished by the rebinds waiting on BOs | 55 | * private to the VM. This is accomplished by the rebinds waiting on BOs |
| 61 | * DMA_RESV_USAGE_KERNEL slot (kernel ops) and kernel ops waiting on all BOs | 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 | 57 | * slots (inflight execs are in the DMA_RESV_USAGE_BOOKKEEP for private BOs and |
| 63 | * in DMA_RESV_USAGE_WRITE for external BOs). | 58 | * for external BOs). |
| 64 | * | 59 | * |
| 65 | * Rebinds / dma-resv usage applies to non-compute mode VMs only as for compute | 60 | * Rebinds / dma-resv usage applies to non-compute mode VMs only as for compute |
| 66 | * mode VMs we use preempt fences and a rebind worker (TODO: add link). | 61 | * mode VMs we use preempt fences and a rebind worker (TODO: add link). |
| @@ -304,7 +299,8 @@ retry: · 237 unmodified lines | |||
| 304 | xe_sched_job_arm(job); | 299 | xe_sched_job_arm(job); |
| 305 | if (!xe_vm_in_lr_mode(vm)) | 300 | if (!xe_vm_in_lr_mode(vm)) |
| 306 | drm_gpuvm_resv_add_fence(&vm->gpuvm, exec, &job->drm.s_fence->finished, | 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 | for (i = 0; i < num_syncs; i++) { | 305 | for (i = 0; i < num_syncs; i++) { |
| 310 | xe_sync_entry_signal(&syncs[i], &job->drm.s_fence->finished); | 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 | err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL); | 641 | err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL); |
| 640 | mutex_unlock(&xef->exec_queue.lock); | ||
| 641 | if (err) | 642 | if (err) |
| 642 | goto kill_exec_queue; | 643 | goto kill_exec_queue; |
| 643 | 644 | ||
| 644 | args->exec_queue_id = id; | 645 | args->exec_queue_id = id; |
| 645 | q->xef = xe_file_get(xef); | ||
| 646 | 646 | ||
| 647 | return 0; | 647 | return 0; |
| 648 | 648 | ||
| @@ -90,6 +90,11 @@ void xe_sched_submission_stop(struct xe_gpu_scheduler *sched) · 89 unmodified lines | |||
| 90 | cancel_work_sync(&sched->work_process_msg); | 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 | void xe_sched_add_msg(struct xe_gpu_scheduler *sched, | 98 | void xe_sched_add_msg(struct xe_gpu_scheduler *sched, |
| 94 | struct xe_sched_msg *msg) | 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 | void xe_sched_submission_start(struct xe_gpu_scheduler *sched); | 22 | void xe_sched_submission_start(struct xe_gpu_scheduler *sched); |
| 23 | void xe_sched_submission_stop(struct xe_gpu_scheduler *sched); | 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 | void xe_sched_add_msg(struct xe_gpu_scheduler *sched, | 27 | void xe_sched_add_msg(struct xe_gpu_scheduler *sched, |
| 26 | struct xe_sched_msg *msg); | 28 | struct xe_sched_msg *msg); |
| 27 | void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched, | 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 | static inline void xe_sched_add_pending_job(struct xe_gpu_scheduler *sched, | 63 | static inline void xe_sched_add_pending_job(struct xe_gpu_scheduler *sched, |
| 62 | struct xe_sched_job *job) | 64 | struct xe_sched_job *job) |
| 63 | { | 65 | { |
| 66 | spin_lock(&sched->base.job_list_lock); | ||
| 64 | list_add(&job->drm.list, &sched->base.pending_list); | 67 | list_add(&job->drm.list, &sched->base.pending_list); |
| 68 | spin_unlock(&sched->base.job_list_lock); | ||
| 65 | } | 69 | } |
| 66 | 70 | ||
| 67 | static inline | 71 | static inline |
| @@ -108,7 +108,6 @@ static void xe_gt_enable_host_l2_vram(struct xe_gt *gt) · 107 unmodified lines | |||
| 108 | return; | 108 | return; |
| 109 | 109 | ||
| 110 | if (!xe_gt_is_media_type(gt)) { | 110 | if (!xe_gt_is_media_type(gt)) { |
| 111 | xe_mmio_write32(gt, SCRATCH1LPFC, EN_L3_RW_CCS_CACHE_FLUSH); | ||
| 112 | reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL); | 111 | reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL); |
| 113 | reg |= CG_DIS_CNTLBUS; | 112 | reg |= CG_DIS_CNTLBUS; |
| 114 | xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg); | 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 | int ret = 0; | 873 | int ret = 0; |
| 875 | 874 | ||
| 876 | if ((!xe_uc_fw_is_available(>->uc.gsc.fw) || | 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 | ret = xe_guc_pc_restore_stashed_freq(>->uc.guc.pc); | 879 | ret = xe_guc_pc_restore_stashed_freq(>->uc.guc.pc); |
| 879 | 880 | ||
| 880 | return ret; | 881 | return ret; |
| @@ -237,11 +237,11 @@ int xe_gt_freq_init(struct xe_gt *gt) · 236 unmodified lines | |||
| 237 | if (!gt->freq) | 237 | if (!gt->freq) |
| 238 | return -ENOMEM; | 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 | if (err) | 241 | if (err) |
| 242 | return err; | 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 | if (err) | 245 | if (err) |
| 246 | return err; | 246 | return err; |
| 247 | 247 | ||
| @@ -439,7 +439,7 @@ void xe_gt_mcr_init(struct xe_gt *gt) · 438 unmodified lines | |||
| 439 | if (gt->info.type == XE_GT_TYPE_MEDIA) { | 439 | if (gt->info.type == XE_GT_TYPE_MEDIA) { |
| 440 | drm_WARN_ON(&xe->drm, MEDIA_VER(xe) < 13); | 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 | gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table; | 443 | gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table; |
| 444 | gt->steering[INSTANCE0].ranges = xe2lpm_instance0_steering_table; | 444 | gt->steering[INSTANCE0].ranges = xe2lpm_instance0_steering_table; |
| 445 | } else { | 445 | } else { |
| @@ -185,6 +185,21 @@ unlock_dma_resv: · 184 unmodified lines | |||
| 185 | return err; | 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 | static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) | 203 | static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) |
| 189 | { | 204 | { |
| 190 | struct xe_device *xe = gt_to_xe(gt); | 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 | if (pf->trva_fault) | 212 | if (pf->trva_fault) |
| 198 | return -EFAULT; | 213 | return -EFAULT; |
| 199 | 214 | ||
| 200 | /* ASID to VM */ | 215 | vm = asid_to_vm(xe, pf->asid); |
| 201 | mutex_lock(&xe->usm.lock); | 216 | if (IS_ERR(vm)) |
| 202 | vm = xa_load(&xe->usm.asid_to_vm, pf->asid); | 217 | return PTR_ERR(vm); |
| 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; | ||
| 210 | 218 | ||
| 211 | /* | 219 | /* |
| 212 | * TODO: Change to read lock? Using write lock for simplicity. | 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 | if (acc->access_type != ACC_TRIGGER) | 556 | if (acc->access_type != ACC_TRIGGER) |
| 549 | return -EINVAL; | 557 | return -EINVAL; |
| 550 | 558 | ||
| 551 | /* ASID to VM */ | 559 | vm = asid_to_vm(xe, acc->asid); |
| 552 | mutex_lock(&xe->usm.lock); | 560 | if (IS_ERR(vm)) |
| 553 | vm = xa_load(&xe->usm.asid_to_vm, acc->asid); | 561 | return PTR_ERR(vm); |
| 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 | 562 | ||
| 560 | down_read(&vm->lock); | 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 | gt->sysfs = &kg->base; | 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 | return hw_tlb_timeout + 2 * delay; | 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 | static void | 49 | static void |
| 41 | __invalidation_fence_signal(struct xe_device *xe, struct xe_gt_tlb_invalidation_fence *fence) | 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 | tlb_timeout_jiffies(gt)); | 213 | tlb_timeout_jiffies(gt)); |
| 205 | } | 214 | } |
| 206 | spin_unlock_irq(>->tlb_invalidation.pending_lock); | 215 | spin_unlock_irq(>->tlb_invalidation.pending_lock); |
| 207 | } else if (ret < 0) { | 216 | } else { |
| 208 | __invalidation_fence_signal(xe, fence); | 217 | __invalidation_fence_signal(xe, fence); |
| 209 | } | 218 | } |
| 210 | if (!ret) { | 219 | if (!ret) { |
| @@ -267,10 +276,8 @@ int xe_gt_tlb_invalidation_ggtt(struct xe_gt *gt) · 56 unmodified lines | |||
| 267 | 276 | ||
| 268 | xe_gt_tlb_invalidation_fence_init(gt, &fence, true); | 277 | xe_gt_tlb_invalidation_fence_init(gt, &fence, true); |
| 269 | ret = xe_gt_tlb_invalidation_guc(gt, &fence); | 278 | ret = xe_gt_tlb_invalidation_guc(gt, &fence); |
| 270 | if (ret < 0) { | 279 | if (ret) |
| 271 | xe_gt_tlb_invalidation_fence_fini(&fence); | ||
| 272 | return ret; | 280 | return ret; |
| 273 | } | ||
| 274 | 281 | ||
| 275 | xe_gt_tlb_invalidation_fence_wait(&fence); | 282 | xe_gt_tlb_invalidation_fence_wait(&fence); |
| 276 | } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) { | 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 | * @stack: fence is stack variable | 503 | * @stack: fence is stack variable |
| 497 | * | 504 | * |
| 498 | * Initialize TLB invalidation fence for use. xe_gt_tlb_invalidation_fence_fini | 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 | void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, | 509 | void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, |
| 502 | struct xe_gt_tlb_invalidation_fence *fence, | 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 | dma_fence_get(&fence->base); | 524 | dma_fence_get(&fence->base); |
| 517 | fence->gt = gt; | 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 | void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, | 28 | void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, |
| 29 | struct xe_gt_tlb_invalidation_fence *fence, | 29 | struct xe_gt_tlb_invalidation_fence *fence, |
| 30 | bool stack); | 30 | bool stack); |
| 31 | void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence); | ||
| 32 | 31 | ||
| 33 | static inline void | 32 | static inline void |
| 34 | xe_gt_tlb_invalidation_fence_wait(struct xe_gt_tlb_invalidation_fence *fence) | 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 | num_g2h = 1; | 667 | num_g2h = 1; |
| 668 | 668 | ||
| 669 | if (g2h_fence_needs_alloc(g2h_fence)) { | 669 | if (g2h_fence_needs_alloc(g2h_fence)) { |
| 670 | void *ptr; | ||
| 671 | |||
| 672 | g2h_fence->seqno = next_ct_seqno(ct, true); | 670 | g2h_fence->seqno = next_ct_seqno(ct, true); |
| 673 | ptr = xa_store(&ct->fence_lookup, | 671 | ret = xa_err(xa_store(&ct->fence_lookup, |
| 674 | g2h_fence->seqno, | 672 | g2h_fence->seqno, g2h_fence, |
| 675 | g2h_fence, GFP_ATOMIC); | 673 | GFP_ATOMIC)); |
| 676 | if (IS_ERR(ptr)) { | 674 | if (ret) |
| 677 | ret = PTR_ERR(ptr); | ||
| 678 | goto out; | 675 | goto out; |
| 679 | } | ||
| 680 | } | 676 | } |
| 681 | 677 | ||
| 682 | seqno = g2h_fence->seqno; | 678 | seqno = g2h_fence->seqno; |
| @@ -879,14 +875,11 @@ retry: · 196 unmodified lines | |||
| 879 | retry_same_fence: | 875 | retry_same_fence: |
| 880 | ret = guc_ct_send(ct, action, len, 0, 0, &g2h_fence); | 876 | ret = guc_ct_send(ct, action, len, 0, 0, &g2h_fence); |
| 881 | if (unlikely(ret == -ENOMEM)) { | 877 | if (unlikely(ret == -ENOMEM)) { |
| 882 | void *ptr; | ||
| 883 | |||
| 884 | /* Retry allocation /w GFP_KERNEL */ | 878 | /* Retry allocation /w GFP_KERNEL */ |
| 885 | ptr = xa_store(&ct->fence_lookup, | 879 | ret = xa_err(xa_store(&ct->fence_lookup, g2h_fence.seqno, |
| 886 | g2h_fence.seqno, | 880 | &g2h_fence, GFP_KERNEL)); |
| 887 | &g2h_fence, GFP_KERNEL); | 881 | if (ret) |
| 888 | if (IS_ERR(ptr)) | 882 | return ret; |
| 889 | return PTR_ERR(ptr); | ||
| 890 | 883 | ||
| 891 | goto retry_same_fence; | 884 | goto retry_same_fence; |
| 892 | } else if (unlikely(ret)) { | 885 | } else if (unlikely(ret)) { |
| @@ -903,16 +896,26 @@ retry_same_fence: · 10 unmodified lines | |||
| 903 | } | 896 | } |
| 904 | 897 | ||
| 905 | ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ); | 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 | if (!ret) { | 907 | if (!ret) { |
| 907 | xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x", | 908 | xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x, done %s", |
| 908 | g2h_fence.seqno, action[0]); | 909 | g2h_fence.seqno, action[0], str_yes_no(g2h_fence.done)); |
| 909 | xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno); | 910 | xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno); |
| 911 | mutex_unlock(&ct->lock); | ||
| 910 | return -ETIME; | 912 | return -ETIME; |
| 911 | } | 913 | } |
| 912 | 914 | ||
| 913 | if (g2h_fence.retry) { | 915 | if (g2h_fence.retry) { |
| 914 | xe_gt_dbg(gt, "H2G action %#x retrying: reason %#x\n", | 916 | xe_gt_dbg(gt, "H2G action %#x retrying: reason %#x\n", |
| 915 | action[0], g2h_fence.reason); | 917 | action[0], g2h_fence.reason); |
| 918 | mutex_unlock(&ct->lock); | ||
| 916 | goto retry; | 919 | goto retry; |
| 917 | } | 920 | } |
| 918 | if (g2h_fence.fail) { | 921 | if (g2h_fence.fail) { |
| @@ -921,7 +924,12 @@ retry_same_fence: · 2 unmodified lines | |||
| 921 | ret = -EIO; | 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 | EXEC_QUEUE_STATE_BANNED)); | 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 | static void guc_submit_fini(struct drm_device *drm, void *arg) | 227 | static void guc_submit_fini(struct drm_device *drm, void *arg) |
| 280 | { | 228 | { |
| 281 | struct xe_guc *guc = arg; | 229 | struct xe_guc *guc = arg; |
| 282 | 230 | ||
| 283 | xa_destroy(&guc->submission_state.exec_queue_lookup); | 231 | xa_destroy(&guc->submission_state.exec_queue_lookup); |
| 284 | free_submit_wq(guc); | ||
| 285 | } | 232 | } |
| 286 | 233 | ||
| 287 | static void guc_submit_wedged_fini(void *arg) | 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 | struct xe_exec_queue *q; | 237 | struct xe_exec_queue *q; |
| 291 | unsigned long index; | 238 | unsigned long index; |
| 292 | 239 | ||
| 293 | xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) | 240 | mutex_lock(&guc->submission_state.lock); |
| 294 | if (exec_queue_wedged(q)) | 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 | xe_exec_queue_put(q); | 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 | static const struct xe_exec_queue_ops guc_exec_queue_ops; | 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 | if (err) | 290 | if (err) |
| 338 | return err; | 291 | return err; |
| 339 | 292 | ||
| 340 | err = alloc_submit_wq(guc); | ||
| 341 | if (err) | ||
| 342 | return err; | ||
| 343 | |||
| 344 | gt->exec_queue_ops = &guc_exec_queue_ops; | 293 | gt->exec_queue_ops = &guc_exec_queue_ops; |
| 345 | 294 | ||
| 346 | xa_init(&guc->submission_state.exec_queue_lookup); | 295 | xa_init(&guc->submission_state.exec_queue_lookup); |
| 347 | 296 | ||
| 297 | init_waitqueue_head(&guc->submission_state.fini_wq); | ||
| 298 | |||
| 348 | primelockdep(guc); | 299 | primelockdep(guc); |
| 349 | 300 | ||
| 350 | return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc); | 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 | xe_guc_id_mgr_release_locked(&guc->submission_state.idm, | 313 | xe_guc_id_mgr_release_locked(&guc->submission_state.idm, |
| 363 | q->guc->id, q->width); | 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 | static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q) | 320 | static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q) |
| 367 | { | 321 | { |
| 368 | int ret; | 322 | int ret; |
| 369 | void *ptr; | ||
| 370 | int i; | 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 | q->guc->id = ret; | 339 | q->guc->id = ret; |
| 387 | 340 | ||
| 388 | for (i = 0; i < q->width; ++i) { | 341 | for (i = 0; i < q->width; ++i) { |
| 389 | ptr = xa_store(&guc->submission_state.exec_queue_lookup, | 342 | ret = xa_err(xa_store(&guc->submission_state.exec_queue_lookup, |
| 390 | q->guc->id + i, q, GFP_NOWAIT); | 343 | q->guc->id + i, q, GFP_NOWAIT)); |
| 391 | if (IS_ERR(ptr)) { | 344 | if (ret) |
| 392 | ret = PTR_ERR(ptr); | ||
| 393 | goto err_release; | 345 | goto err_release; |
| 394 | } | ||
| 395 | } | 346 | } |
| 396 | 347 | ||
| 397 | return 0; | 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 | * TDR has fired before free job worker. Common if exec queue | 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 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &job->fence->flags)) { | 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 | return DRM_GPU_SCHED_STAT_NOMINAL; | 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 | static void guc_exec_queue_fini_async(struct xe_exec_queue *q) | 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 | INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async); | 1228 | INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async); |
| 1272 | 1229 | ||
| 1273 | /* We must block on kernel engines so slabs are empty on driver unload */ | 1230 | /* We must block on kernel engines so slabs are empty on driver unload */ |
| 1274 | if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q)) | 1231 | if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q)) |
| 1275 | __guc_exec_queue_fini_async(&q->guc->fini_async); | 1232 | __guc_exec_queue_fini_async(&q->guc->fini_async); |
| 1276 | else | 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 | static void __guc_exec_queue_fini(struct xe_guc *guc, struct xe_exec_queue *q) | 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 | timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT : | 1409 | timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT : |
| 1453 | msecs_to_jiffies(q->sched_props.job_timeout_ms); | 1410 | msecs_to_jiffies(q->sched_props.job_timeout_ms); |
| 1454 | err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops, | 1411 | err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops, |
| 1455 | get_submit_wq(guc), | 1412 | NULL, q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64, |
| 1456 | q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64, | ||
| 1457 | timeout, guc_to_gt(guc)->ordered_wq, NULL, | 1413 | timeout, guc_to_gt(guc)->ordered_wq, NULL, |
| 1458 | q->name, gt_to_xe(q->gt)->drm.dev); | 1414 | q->name, gt_to_xe(q->gt)->drm.dev); |
| 1459 | if (err) | 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 | xe_sched_submission_start(sched); | 1754 | xe_sched_submission_start(sched); |
| 1755 | xe_sched_submission_resume_tdr(sched); | ||
| 1799 | } | 1756 | } |
| 1800 | 1757 | ||
| 1801 | int xe_guc_submit_start(struct xe_guc *guc) | 1758 | int xe_guc_submit_start(struct xe_guc *guc) |
| @@ -72,15 +72,10 @@ struct xe_guc { · 71 unmodified lines | |||
| 72 | atomic_t stopped; | 72 | atomic_t stopped; |
| 73 | /** @submission_state.lock: protects submission state */ | 73 | /** @submission_state.lock: protects submission state */ |
| 74 | struct mutex lock; | 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 | /** @submission_state.enabled: submission is enabled */ | 75 | /** @submission_state.enabled: submission is enabled */ |
| 83 | bool enabled; | 76 | bool enabled; |
| 77 | /** @submission_state.fini_wq: submit fini wait queue */ | ||
| 78 | wait_queue_head_t fini_wq; | ||
| 84 | } submission_state; | 79 | } submission_state; |
| 85 | /** @hwconfig: Hardware config state */ | 80 | /** @hwconfig: Hardware config state */ |
| 86 | struct { | 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 | RING_CONTEXT_CONTROL(stream->hwe->mmio_base), | 710 | RING_CONTEXT_CONTROL(stream->hwe->mmio_base), |
| 711 | regs_offset + CTX_CONTEXT_CONTROL, | 711 | regs_offset + CTX_CONTEXT_CONTROL, |
| 712 | _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE, | 712 | _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE), |
| 713 | enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) | ||
| 714 | }, | 713 | }, |
| 715 | }; | 714 | }; |
| 716 | struct xe_oa_reg reg_lri = { OAR_OACONTROL, oacontrol }; | 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 | RING_CONTEXT_CONTROL(stream->hwe->mmio_base), | 742 | RING_CONTEXT_CONTROL(stream->hwe->mmio_base), |
| 744 | regs_offset + CTX_CONTEXT_CONTROL, | 743 | regs_offset + CTX_CONTEXT_CONTROL, |
| 745 | _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE, | 744 | _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE) | |
| 746 | enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) | | 745 | _MASKED_FIELD(CTX_CTRL_RUN_ALONE, enable ? CTX_CTRL_RUN_ALONE : 0), |
| 747 | _MASKED_FIELD(CTX_CTRL_RUN_ALONE, | ||
| 748 | enable ? CTX_CTRL_RUN_ALONE : 0), | ||
| 749 | }, | 746 | }, |
| 750 | }; | 747 | }; |
| 751 | struct xe_oa_reg reg_lri = { OAC_OACONTROL, oacontrol }; | 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 | if (err) | 924 | if (err) |
| 925 | return err; | 925 | return err; |
| 926 | 926 | ||
| 927 | pci_restore_state(pdev); | ||
| 928 | |||
| 927 | err = pci_enable_device(pdev); | 929 | err = pci_enable_device(pdev); |
| 928 | if (err) | 930 | if (err) |
| 929 | return err; | 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 | pt_op->num_entries); | 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 | cpu_clock); | 161 | cpu_clock); |
| 162 | 162 | ||
| 163 | xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); | 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 | /* Only write to the output fields of user query */ | 170 | /* Only write to the output fields of user query */ |
| 167 | if (put_user(resp.cpu_timestamp, &query_ptr->cpu_timestamp)) | 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 | if (!access_ok(ptr, sizeof(*ptr))) | 58 | if (!access_ok(ptr, sizeof(*ptr))) |
| 59 | return ERR_PTR(-EFAULT); | 59 | return ERR_PTR(-EFAULT); |
| 60 | 60 | ||
| 61 | ufence = kmalloc(sizeof(*ufence), GFP_KERNEL); | 61 | ufence = kzalloc(sizeof(*ufence), GFP_KERNEL); |
| 62 | if (!ufence) | 62 | if (!ufence) |
| 63 | return ERR_PTR(-ENOMEM); | 63 | return ERR_PTR(-ENOMEM); |
| 64 | 64 | ||
| @@ -42,20 +42,48 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { · 41 unmodified lines | |||
| 42 | XE_RTP_ACTIONS(CLR(CCCHKNREG1, ENCOMPPERFFIX), | 42 | XE_RTP_ACTIONS(CLR(CCCHKNREG1, ENCOMPPERFFIX), |
| 43 | SET(CCCHKNREG1, L3CMPCTRL)) | 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 | { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3"), | 50 | { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3"), |
| 46 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), | 51 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), |
| 47 | XE_RTP_ACTIONS(SET(L3SQCREG3, COMPPWOVERFETCHEN)) | 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 | { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only"), | 58 | { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only"), |
| 50 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), | 59 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), |
| 51 | XE_RTP_ACTIONS(SET(L3SQCREG2, | 60 | XE_RTP_ACTIONS(SET(L3SQCREG2, |
| 52 | COMPMEMRD256BOVRFETCHEN)) | 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 | { XE_RTP_NAME("Tuning: Stateless compression control"), | 68 | { XE_RTP_NAME("Tuning: Stateless compression control"), |
| 55 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), | 69 | XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), |
| 56 | XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, | 70 | XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, |
| 57 | REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) | 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 | up_write(&vm->lock); | 1614 | up_write(&vm->lock); |
| 1615 | 1615 | ||
| 1616 | mutex_lock(&xe->usm.lock); | 1616 | down_write(&xe->usm.lock); |
| 1617 | if (vm->usm.asid) { | 1617 | if (vm->usm.asid) { |
| 1618 | void *lookup; | 1618 | void *lookup; |
| 1619 | 1619 | ||
| @@ -1623,7 +1623,7 @@ void xe_vm_close_and_put(struct xe_vm *vm) · 3 unmodified lines | |||
| 1623 | lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid); | 1623 | lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid); |
| 1624 | xe_assert(xe, lookup == vm); | 1624 | xe_assert(xe, lookup == vm); |
| 1625 | } | 1625 | } |
| 1626 | mutex_unlock(&xe->usm.lock); | 1626 | up_write(&xe->usm.lock); |
| 1627 | 1627 | ||
| 1628 | for_each_tile(tile, xe, id) | 1628 | for_each_tile(tile, xe, id) |
| 1629 | xe_range_fence_tree_fini(&vm->rftree[id]); | 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 | if (IS_ERR(vm)) | 1765 | if (IS_ERR(vm)) |
| 1766 | return PTR_ERR(vm); | 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 | if (xe->info.has_asid) { | 1768 | if (xe->info.has_asid) { |
| 1775 | mutex_lock(&xe->usm.lock); | 1769 | down_write(&xe->usm.lock); |
| 1776 | err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, | 1770 | err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, |
| 1777 | XA_LIMIT(1, XE_MAX_ASID - 1), | 1771 | XA_LIMIT(1, XE_MAX_ASID - 1), |
| 1778 | &xe->usm.next_asid, GFP_KERNEL); | 1772 | &xe->usm.next_asid, GFP_KERNEL); |
| 1779 | mutex_unlock(&xe->usm.lock); | 1773 | up_write(&xe->usm.lock); |
| 1780 | if (err < 0) | 1774 | if (err < 0) |
| 1781 | goto err_free_id; | 1775 | goto err_close_and_put; |
| 1782 | 1776 | ||
| 1783 | vm->usm.asid = asid; | 1777 | vm->usm.asid = asid; |
| 1784 | } | 1778 | } |
| 1785 | 1779 | ||
| 1786 | args->vm_id = id; | ||
| 1787 | vm->xef = xe_file_get(xef); | 1780 | vm->xef = xe_file_get(xef); |
| 1788 | 1781 | ||
| 1789 | /* Record BO memory for VM pagetable created against client */ | 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 | args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE); | 1789 | args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE); |
| 1797 | #endif | 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 | return 0; | 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 | err_close_and_put: | 1801 | err_close_and_put: |
| 1806 | xe_vm_close_and_put(vm); | 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 | ret = xe_gt_tlb_invalidation_vma(tile->primary_gt, | 3200 | ret = xe_gt_tlb_invalidation_vma(tile->primary_gt, |
| 3205 | &fence[fence_id], vma); | 3201 | &fence[fence_id], vma); |
| 3206 | if (ret < 0) { | 3202 | if (ret) |
| 3207 | xe_gt_tlb_invalidation_fence_fini(&fence[fence_id]); | ||
| 3208 | goto wait; | 3203 | goto wait; |
| 3209 | } | ||
| 3210 | ++fence_id; | 3204 | ++fence_id; |
| 3211 | 3205 | ||
| 3212 | if (!tile->media_gt) | 3206 | if (!tile->media_gt) |
| @@ -3218,10 +3212,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma) · 5 unmodified lines | |||
| 3218 | 3212 | ||
| 3219 | ret = xe_gt_tlb_invalidation_vma(tile->media_gt, | 3213 | ret = xe_gt_tlb_invalidation_vma(tile->media_gt, |
| 3220 | &fence[fence_id], vma); | 3214 | &fence[fence_id], vma); |
| 3221 | if (ret < 0) { | 3215 | if (ret) |
| 3222 | xe_gt_tlb_invalidation_fence_fini(&fence[fence_id]); | ||
| 3223 | goto wait; | 3216 | goto wait; |
| 3224 | } | ||
| 3225 | ++fence_id; | 3217 | ++fence_id; |
| 3226 | } | 3218 | } |
| 3227 | } | 3219 | } |
| @@ -710,6 +710,10 @@ static const struct xe_rtp_entry_sr lrc_was[] = { · 709 unmodified lines | |||
| 710 | DIS_PARTIAL_AUTOSTRIP | | 710 | DIS_PARTIAL_AUTOSTRIP | |
| 711 | DIS_AUTOSTRIP)) | 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 | /* Xe2_HPG */ | 718 | /* Xe2_HPG */ |
| 715 | { XE_RTP_NAME("15010599737"), | 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 | args->timeout = 0; | 169 | args->timeout = 0; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | if (!timeout && !(err < 0)) | ||
| 173 | err = -ETIME; | ||
| 174 | |||
| 175 | if (q) | 172 | if (q) |
| 176 | xe_exec_queue_put(q); | 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 | ctx->dev.parent = host1x->dev; | 58 | ctx->dev.parent = host1x->dev; |
| 59 | ctx->dev.release = host1x_memory_context_release; | 59 | ctx->dev.release = host1x_memory_context_release; |
| 60 | 60 | ||
| 61 | ctx->dev.dma_parms = &ctx->dma_parms; | ||
| 61 | dma_set_max_seg_size(&ctx->dev, UINT_MAX); | 62 | dma_set_max_seg_size(&ctx->dev, UINT_MAX); |
| 62 | 63 | ||
| 63 | err = device_add(&ctx->dev); | 64 | err = device_add(&ctx->dev); |
| @@ -625,12 +625,6 @@ static int host1x_probe(struct platform_device *pdev) · 624 unmodified lines | |||
| 625 | goto free_contexts; | 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 | pm_runtime_enable(&pdev->dev); | 628 | pm_runtime_enable(&pdev->dev); |
| 635 | 629 | ||
| 636 | err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); | 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 | if (err) | 636 | if (err) |
| 643 | goto pm_disable; | 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 | host1x_debug_init(host); | 645 | host1x_debug_init(host); |
| 646 | 646 | ||
| 647 | err = host1x_register(host); | 647 | err = host1x_register(host); |
| @@ -658,13 +658,11 @@ unregister: · 10 unmodified lines | |||
| 658 | host1x_unregister(host); | 658 | host1x_unregister(host); |
| 659 | deinit_debugfs: | 659 | deinit_debugfs: |
| 660 | host1x_debug_deinit(host); | 660 | host1x_debug_deinit(host); |
| 661 | 661 | host1x_intr_deinit(host); | |
| 662 | pm_put: | ||
| 662 | pm_runtime_put_sync_suspend(&pdev->dev); | 663 | pm_runtime_put_sync_suspend(&pdev->dev); |
| 663 | pm_disable: | 664 | pm_disable: |
| 664 | pm_runtime_disable(&pdev->dev); | 665 | pm_runtime_disable(&pdev->dev); |
| 665 | |||
| 666 | host1x_intr_deinit(host); | ||
| 667 | deinit_syncpt: | ||
| 668 | host1x_syncpt_deinit(host); | 666 | host1x_syncpt_deinit(host); |
| 669 | free_contexts: | 667 | free_contexts: |
| 670 | host1x_memory_context_list_free(&host->context_list); | 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 | cl_data->in_data = in_data; | 236 | cl_data->in_data = in_data; |
| 237 | 237 | ||
| 238 | for (i = 0; i < cl_data->num_hid_devices; i++) { | 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, | 239 | in_data->sensor_virt_addr[i] = dmam_alloc_coherent(dev, sizeof(int) * 8, |
| 240 | &cl_data->sensor_dma_addr[i], | 240 | &cl_data->sensor_dma_addr[i], |
| 241 | GFP_KERNEL); | 241 | GFP_KERNEL); |
| 242 | if (!in_data->sensor_virt_addr[i]) { | 242 | if (!in_data->sensor_virt_addr[i]) { |
| 243 | rc = -ENOMEM; | 243 | rc = -ENOMEM; |
| 244 | goto cleanup; | 244 | goto cleanup; |
| @@ -331,7 +331,6 @@ cleanup: · 86 unmodified lines | |||
| 331 | int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) | 331 | int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) |
| 332 | { | 332 | { |
| 333 | struct amdtp_cl_data *cl_data = privdata->cl_data; | 333 | struct amdtp_cl_data *cl_data = privdata->cl_data; |
| 334 | struct amd_input_data *in_data = cl_data->in_data; | ||
| 335 | int i, status; | 334 | int i, status; |
| 336 | 335 | ||
| 337 | for (i = 0; i < cl_data->num_hid_devices; i++) { | 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 | cancel_delayed_work_sync(&cl_data->work_buffer); | 350 | cancel_delayed_work_sync(&cl_data->work_buffer); |
| 352 | amdtp_hid_remove(cl_data); | 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 | return 0; | 353 | return 0; |
| 362 | } | 354 | } |
| @@ -509,6 +509,7 @@ · 508 unmodified lines | |||
| 509 | #define I2C_DEVICE_ID_GOODIX_01E8 0x01e8 | 509 | #define I2C_DEVICE_ID_GOODIX_01E8 0x01e8 |
| 510 | #define I2C_DEVICE_ID_GOODIX_01E9 0x01e9 | 510 | #define I2C_DEVICE_ID_GOODIX_01E9 0x01e9 |
| 511 | #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 | 511 | #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 |
| 512 | #define I2C_DEVICE_ID_GOODIX_0D42 0x0d42 | ||
| 512 | 513 | ||
| 513 | #define USB_VENDOR_ID_GOODTOUCH 0x1aad | 514 | #define USB_VENDOR_ID_GOODTOUCH 0x1aad |
| 514 | #define USB_DEVICE_ID_GOODTOUCH_000f 0x000f | 515 | #define USB_DEVICE_ID_GOODTOUCH_000f 0x000f |
| @@ -868,6 +869,7 @@ · 353 unmodified lines | |||
| 868 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539 | 869 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539 |
| 869 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f | 870 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f |
| 870 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a | 871 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a |
| 872 | #define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548 | ||
| 871 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 | 873 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 |
| 872 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 | 874 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 |
| 873 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 | 875 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 |
| @@ -1036,6 +1038,8 @@ · 162 unmodified lines | |||
| 1036 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056 | 1038 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056 |
| 1037 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057 | 1039 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057 |
| 1038 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058 | 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 | #define USB_VENDOR_ID_PANASONIC 0x04da | 1044 | #define USB_VENDOR_ID_PANASONIC 0x04da |
| 1041 | #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 | 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 | return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, | 473 | return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, |
| 474 | usage, bit, max); | 474 | usage, bit, max); |
| 475 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 475 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 476 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 476 | return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); | 477 | return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); |
| 477 | default: | 478 | default: |
| 478 | return 0; | 479 | return 0; |
| @@ -583,6 +584,7 @@ static ssize_t attr_fn_lock_store(struct device *dev, · 104 unmodified lines | |||
| 583 | break; | 584 | break; |
| 584 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 585 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 585 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 586 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 587 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 586 | ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); | 588 | ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); |
| 587 | if (ret) | 589 | if (ret) |
| 588 | return ret; | 590 | return ret; |
| @@ -776,6 +778,7 @@ static int lenovo_event(struct hid_device *hdev, struct hid_field *field, · 187 unmodified lines | |||
| 776 | return lenovo_event_cptkbd(hdev, field, usage, value); | 778 | return lenovo_event_cptkbd(hdev, field, usage, value); |
| 777 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 779 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 778 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 780 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 781 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 779 | return lenovo_event_tp10ubkbd(hdev, field, usage, value); | 782 | return lenovo_event_tp10ubkbd(hdev, field, usage, value); |
| 780 | default: | 783 | default: |
| 781 | return 0; | 784 | return 0; |
| @@ -1056,6 +1059,7 @@ static int lenovo_led_brightness_set(struct led_classdev *led_cdev, · 274 unmodified lines | |||
| 1056 | break; | 1059 | break; |
| 1057 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 1060 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1058 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 1061 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1062 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 1059 | ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); | 1063 | ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); |
| 1060 | break; | 1064 | break; |
| 1061 | } | 1065 | } |
| @@ -1286,6 +1290,7 @@ static int lenovo_probe(struct hid_device *hdev, · 224 unmodified lines | |||
| 1286 | break; | 1290 | break; |
| 1287 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 1291 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1288 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 1292 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1293 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 1289 | ret = lenovo_probe_tp10ubkbd(hdev); | 1294 | ret = lenovo_probe_tp10ubkbd(hdev); |
| 1290 | break; | 1295 | break; |
| 1291 | default: | 1296 | default: |
| @@ -1372,6 +1377,7 @@ static void lenovo_remove(struct hid_device *hdev) · 80 unmodified lines | |||
| 1372 | break; | 1377 | break; |
| 1373 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 1378 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1374 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 1379 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1380 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 1375 | lenovo_remove_tp10ubkbd(hdev); | 1381 | lenovo_remove_tp10ubkbd(hdev); |
| 1376 | break; | 1382 | break; |
| 1377 | } | 1383 | } |
| @@ -1421,6 +1427,8 @@ static const struct hid_device_id lenovo_devices[] = { · 43 unmodified lines | |||
| 1421 | */ | 1427 | */ |
| 1422 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 1428 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 1423 | USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB) }, | 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 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | 2026 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2027 | USB_VENDOR_ID_ELAN, 0x3148) }, | 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 | /* Elitegroup panel */ | 2033 | /* Elitegroup panel */ |
| 2030 | { .driver_data = MT_CLS_SERIAL, | 2034 | { .driver_data = MT_CLS_SERIAL, |
| 2031 | MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP, | 2035 | MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP, |
| @@ -2095,6 +2099,11 @@ static const struct hid_device_id mt_devices[] = { · 63 unmodified lines | |||
| 2095 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | 2099 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2096 | 0x347d, 0x7853) }, | 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 | /* Ilitek dual touch panel */ | 2107 | /* Ilitek dual touch panel */ |
| 2099 | { .driver_data = MT_CLS_NSMU, | 2108 | { .driver_data = MT_CLS_NSMU, |
| 2100 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, | 2109 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, |
| @@ -2137,6 +2146,10 @@ static const struct hid_device_id mt_devices[] = { · 36 unmodified lines | |||
| 2137 | HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8, | 2146 | HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8, |
| 2138 | USB_VENDOR_ID_LOGITECH, | 2147 | USB_VENDOR_ID_LOGITECH, |
| 2139 | USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) }, | 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 | /* MosArt panels */ | 2154 | /* MosArt panels */ |
| 2142 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 2155 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
| @@ -38,8 +38,10 @@ · 37 unmodified lines | |||
| 38 | (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) | 38 | (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) |
| 39 | 39 | ||
| 40 | #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0) | 40 | #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0) |
| 41 | #define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1) | ||
| 41 | 42 | ||
| 42 | #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */ | 43 | #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */ |
| 44 | #define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */ | ||
| 43 | 45 | ||
| 44 | struct plt_drv_data { | 46 | struct plt_drv_data { |
| 45 | unsigned long device_type; | 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 | drv_data->last_volume_key_ts = cur_ts; | 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 | return 0; | 158 | return 0; |
| 142 | } | 159 | } |
| @@ -210,6 +227,12 @@ static const struct hid_device_id plantronics_devices[] = { · 67 unmodified lines | |||
| 210 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, | 227 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, |
| 211 | USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES), | 228 | USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES), |
| 212 | .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, | 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 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, | 236 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, |
| 214 | { } | 237 | { } |
| 215 | }; | 238 | }; |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | |||
| 50 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3) | 50 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3) |
| 51 | #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4) | 51 | #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4) |
| 52 | #define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND BIT(5) | 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 | /* Command opcodes */ | 55 | /* Command opcodes */ |
| 55 | #define I2C_HID_OPCODE_RESET 0x01 | 56 | #define I2C_HID_OPCODE_RESET 0x01 |
| @@ -140,6 +141,8 @@ static const struct i2c_hid_quirks { · 84 unmodified lines | |||
| 140 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, | 141 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, |
| 141 | I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | | 142 | I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | |
| 142 | I2C_HID_QUIRK_BOGUS_IRQ }, | 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 | { 0, 0 } | 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 | return -ENXIO; | 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 | /* Instead of resetting device, simply powers the device on. This | 994 | /* Instead of resetting device, simply powers the device on. This |
| 985 | * solves "incomplete reports" on Raydium devices 2386:3118 and | 995 | * solves "incomplete reports" on Raydium devices 2386:3118 and |
| 986 | * 2386:4B33 and fixes various SIS touchscreens no longer sending | 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 | const struct firmware *fw, | 635 | const struct firmware *fw, |
| 636 | const struct shim_fw_info fw_info) | 636 | const struct shim_fw_info fw_info) |
| 637 | { | 637 | { |
| 638 | int rv; | 638 | int rv = 0; |
| 639 | void *dma_buf; | 639 | void *dma_buf; |
| 640 | dma_addr_t dma_buf_phy; | 640 | dma_addr_t dma_buf_phy; |
| 641 | u32 fragment_offset, fragment_size, payload_max_size; | 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 | /* Going into range select tool */ | 2567 | /* Going into range select tool */ |
| 2568 | if (wacom_wac->hid_data.invert_state) | 2568 | if (wacom_wac->hid_data.invert_state) |
| 2569 | wacom_wac->tool[0] = BTN_TOOL_RUBBER; | 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 | else if (wacom_wac->id[0]) | 2572 | else if (wacom_wac->id[0]) |
| 2571 | wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]); | 2573 | wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]); |
| 2572 | else | 2574 | else |
| @@ -162,6 +162,7 @@ config SENSORS_ADM9240 · 161 unmodified lines | |||
| 162 | tristate "Analog Devices ADM9240 and compatibles" | 162 | tristate "Analog Devices ADM9240 and compatibles" |
| 163 | depends on I2C | 163 | depends on I2C |
| 164 | select HWMON_VID | 164 | select HWMON_VID |
| 165 | select REGMAP_I2C | ||
| 165 | help | 166 | help |
| 166 | If you say yes here you get support for Analog Devices ADM9240, | 167 | If you say yes here you get support for Analog Devices ADM9240, |
| 167 | Dallas DS1780, National Semiconductor LM81 sensor chips. | 168 | Dallas DS1780, National Semiconductor LM81 sensor chips. |
| @@ -223,6 +224,7 @@ config SENSORS_ADT7462 · 55 unmodified lines | |||
| 223 | config SENSORS_ADT7470 | 224 | config SENSORS_ADT7470 |
| 224 | tristate "Analog Devices ADT7470" | 225 | tristate "Analog Devices ADT7470" |
| 225 | depends on I2C | 226 | depends on I2C |
| 227 | select REGMAP_I2C | ||
| 226 | help | 228 | help |
| 227 | If you say yes here you get support for the Analog Devices | 229 | If you say yes here you get support for the Analog Devices |
| 228 | ADT7470 temperature monitoring chips. | 230 | ADT7470 temperature monitoring chips. |
| @@ -999,6 +1001,7 @@ config SENSORS_LTC2990 · 770 unmodified lines | |||
| 999 | config SENSORS_LTC2991 | 1001 | config SENSORS_LTC2991 |
| 1000 | tristate "Analog Devices LTC2991" | 1002 | tristate "Analog Devices LTC2991" |
| 1001 | depends on I2C | 1003 | depends on I2C |
| 1004 | select REGMAP_I2C | ||
| 1002 | help | 1005 | help |
| 1003 | If you say yes here you get support for Analog Devices LTC2991 | 1006 | If you say yes here you get support for Analog Devices LTC2991 |
| 1004 | Octal I2C Voltage, Current, and Temperature Monitor. The LTC2991 | 1007 | Octal I2C Voltage, Current, and Temperature Monitor. The LTC2991 |
| @@ -1146,6 +1149,7 @@ config SENSORS_MAX1619 · 141 unmodified lines | |||
| 1146 | config SENSORS_MAX1668 | 1149 | config SENSORS_MAX1668 |
| 1147 | tristate "Maxim MAX1668 and compatibles" | 1150 | tristate "Maxim MAX1668 and compatibles" |
| 1148 | depends on I2C | 1151 | depends on I2C |
| 1152 | select REGMAP_I2C | ||
| 1149 | help | 1153 | help |
| 1150 | If you say yes here you get support for MAX1668, MAX1989 and | 1154 | If you say yes here you get support for MAX1668, MAX1989 and |
| 1151 | MAX1805 chips. | 1155 | MAX1805 chips. |
| @@ -1275,6 +1279,7 @@ config SENSORS_MAX31790 · 123 unmodified lines | |||
| 1275 | config SENSORS_MC34VR500 | 1279 | config SENSORS_MC34VR500 |
| 1276 | tristate "NXP MC34VR500 hardware monitoring driver" | 1280 | tristate "NXP MC34VR500 hardware monitoring driver" |
| 1277 | depends on I2C | 1281 | depends on I2C |
| 1282 | select REGMAP_I2C | ||
| 1278 | help | 1283 | help |
| 1279 | If you say yes here you get support for the temperature and input | 1284 | If you say yes here you get support for the temperature and input |
| 1280 | voltage sensors of the NXP MC34VR500. | 1285 | voltage sensors of the NXP MC34VR500. |
| @@ -2312,6 +2317,7 @@ config SENSORS_TMP464 · 1031 unmodified lines | |||
| 2312 | config SENSORS_TMP513 | 2317 | config SENSORS_TMP513 |
| 2313 | tristate "Texas Instruments TMP513 and compatibles" | 2318 | tristate "Texas Instruments TMP513 and compatibles" |
| 2314 | depends on I2C | 2319 | depends on I2C |
| 2320 | select REGMAP_I2C | ||
| 2315 | help | 2321 | help |
| 2316 | If you say yes here you get support for Texas Instruments TMP512, | 2322 | If you say yes here you get support for Texas Instruments TMP512, |
| 2317 | and TMP513 temperature and power supply sensor chips. | 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 | static int adt7475_fan_pwm_config(struct i2c_client *client) | 1735 | static int adt7475_fan_pwm_config(struct i2c_client *client) |
| 1736 | { | 1736 | { |
| 1737 | struct adt7475_data *data = i2c_get_clientdata(client); | 1737 | struct adt7475_data *data = i2c_get_clientdata(client); |
| 1738 | struct fwnode_handle *child; | ||
| 1739 | struct adt7475_pwm_config cfg = {}; | 1738 | struct adt7475_pwm_config cfg = {}; |
| 1740 | int ret; | 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 | if (!fwnode_property_present(child, "pwms")) | 1742 | if (!fwnode_property_present(child, "pwms")) |
| 1744 | continue; | 1743 | continue; |
| 1745 | 1744 | ||
| @@ -358,7 +358,7 @@ static const struct m10bmc_sdata n6000bmc_temp_tbl[] = { · 357 unmodified lines | |||
| 358 | { 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" }, | 358 | { 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" }, |
| 359 | { 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" }, | 359 | { 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" }, |
| 360 | { 0x508, 0x50c, 0x510, 0x52c, 0x0, 500, "Board Top East Near VRs Temperature" }, | 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 | { 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" }, | 362 | { 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" }, |
| 363 | { 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" }, | 363 | { 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" }, |
| 364 | { 0x53c, 0x540, 0x544, 0x0, 0x0, 500, "QSFP1 Case Temperature" }, | 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 | return -ENODEV; | 417 | return -ENODEV; |
| 418 | 418 | ||
| 419 | if ((devid & TSE2004_DEVID_MASK) == TSE2004_DEVID && | 419 | if ((devid & TSE2004_DEVID_MASK) == TSE2004_DEVID && |
| 420 | (cap & 0x00e7) != 0x00e7) | 420 | (cap & 0x0062) != 0x0062) |
| 421 | return -ENODEV; | 421 | return -ENODEV; |
| 422 | 422 | ||
| 423 | for (i = 0; i < ARRAY_SIZE(jc42_chips); i++) { | 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 | struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); | 2395 | struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
| 2396 | 2396 | ||
| 2397 | if (!stm32f7_i2c_is_slave_registered(i2c_dev)) | 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 | return 0; | 2400 | return 0; |
| 2401 | } | 2401 | } |
| @@ -2406,9 +2406,9 @@ static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev) · 4 unmodified lines | |||
| 2406 | int ret; | 2406 | int ret; |
| 2407 | 2407 | ||
| 2408 | if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { | 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 | if (ret) { | 2410 | if (ret) { |
| 2411 | dev_err(dev, "failed to prepare_enable clock\n"); | 2411 | dev_err(dev, "failed to enable clock\n"); |
| 2412 | return ret; | 2412 | return ret; |
| 2413 | } | 2413 | } |
| 2414 | } | 2414 | } |
| @@ -447,6 +447,8 @@ config IIO_ST_ACCEL_SPI_3AXIS · 446 unmodified lines | |||
| 447 | 447 | ||
| 448 | config IIO_KX022A | 448 | config IIO_KX022A |
| 449 | tristate | 449 | tristate |
| 450 | select IIO_BUFFER | ||
| 451 | select IIO_TRIGGERED_BUFFER | ||
| 450 | 452 | ||
| 451 | config IIO_KX022A_SPI | 453 | config IIO_KX022A_SPI |
| 452 | tristate "Kionix KX022A tri-axis digital accelerometer SPI interface" | 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 | static int bma400_tap_event_en(struct bma400_data *data, | 1218 | static int bma400_tap_event_en(struct bma400_data *data, |
| 1219 | enum iio_event_direction dir, int state) | 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 | int ret; | 1223 | int ret; |
| 1223 | 1224 | ||
| 1224 | /* | 1225 | /* |
| @@ -52,6 +52,8 @@ config AD4695 · 51 unmodified lines | |||
| 52 | tristate "Analog Device AD4695 ADC Driver" | 52 | tristate "Analog Device AD4695 ADC Driver" |
| 53 | depends on SPI | 53 | depends on SPI |
| 54 | select REGMAP_SPI | 54 | select REGMAP_SPI |
| 55 | select IIO_BUFFER | ||
| 56 | select IIO_TRIGGERED_BUFFER | ||
| 55 | help | 57 | help |
| 56 | Say yes here to build support for Analog Devices AD4695 and similar | 58 | Say yes here to build support for Analog Devices AD4695 and similar |
| 57 | analog to digital converters (ADC). | 59 | analog to digital converters (ADC). |
| @@ -328,6 +330,8 @@ config AD7923 · 270 unmodified lines | |||
| 328 | config AD7944 | 330 | config AD7944 |
| 329 | tristate "Analog Devices AD7944 and similar ADCs driver" | 331 | tristate "Analog Devices AD7944 and similar ADCs driver" |
| 330 | depends on SPI | 332 | depends on SPI |
| 333 | select IIO_BUFFER | ||
| 334 | select IIO_TRIGGERED_BUFFER | ||
| 331 | help | 335 | help |
| 332 | Say yes here to build support for Analog Devices | 336 | Say yes here to build support for Analog Devices |
| 333 | AD7944, AD7985, AD7986 ADCs. | 337 | AD7944, AD7985, AD7986 ADCs. |
| @@ -1481,6 +1485,8 @@ config TI_ADS8344 · 1147 unmodified lines | |||
| 1481 | config TI_ADS8688 | 1485 | config TI_ADS8688 |
| 1482 | tristate "Texas Instruments ADS8688" | 1486 | tristate "Texas Instruments ADS8688" |
| 1483 | depends on SPI | 1487 | depends on SPI |
| 1488 | select IIO_BUFFER | ||
| 1489 | select IIO_TRIGGERED_BUFFER | ||
| 1484 | help | 1490 | help |
| 1485 | If you say yes here you get support for Texas Instruments ADS8684 and | 1491 | If you say yes here you get support for Texas Instruments ADS8684 and |
| 1486 | and ADS8688 ADC chips | 1492 | and ADS8688 ADC chips |
| @@ -1491,6 +1497,8 @@ config TI_ADS8688 · 4 unmodified lines | |||
| 1491 | config TI_ADS124S08 | 1497 | config TI_ADS124S08 |
| 1492 | tristate "Texas Instruments ADS124S08" | 1498 | tristate "Texas Instruments ADS124S08" |
| 1493 | depends on SPI | 1499 | depends on SPI |
| 1500 | select IIO_BUFFER | ||
| 1501 | select IIO_TRIGGERED_BUFFER | ||
| 1494 | help | 1502 | help |
| 1495 | If you say yes here you get support for Texas Instruments ADS124S08 | 1503 | If you say yes here you get support for Texas Instruments ADS124S08 |
| 1496 | and ADS124S06 ADC chips | 1504 | and ADS124S06 ADC chips |
| @@ -1525,6 +1533,9 @@ config TI_AM335X_ADC · 28 unmodified lines | |||
| 1525 | config TI_LMP92064 | 1533 | config TI_LMP92064 |
| 1526 | tristate "Texas Instruments LMP92064 ADC driver" | 1534 | tristate "Texas Instruments LMP92064 ADC driver" |
| 1527 | depends on SPI | 1535 | depends on SPI |
| 1536 | select REGMAP_SPI | ||
| 1537 | select IIO_BUFFER | ||
| 1538 | select IIO_TRIGGERED_BUFFER | ||
| 1528 | help | 1539 | help |
| 1529 | Say yes here to build support for the LMP92064 Precision Current and Voltage | 1540 | Say yes here to build support for the LMP92064 Precision Current and Voltage |
| 1530 | sensor. | 1541 | sensor. |
| @@ -27,6 +27,7 @@ config AD8366 · 26 unmodified lines | |||
| 27 | config ADA4250 | 27 | config ADA4250 |
| 28 | tristate "Analog Devices ADA4250 Instrumentation Amplifier" | 28 | tristate "Analog Devices ADA4250 Instrumentation Amplifier" |
| 29 | depends on SPI | 29 | depends on SPI |
| 30 | select REGMAP_SPI | ||
| 30 | help | 31 | help |
| 31 | Say yes here to build support for Analog Devices ADA4250 | 32 | Say yes here to build support for Analog Devices ADA4250 |
| 32 | SPI Amplifier's support. The driver provides direct access via | 33 | SPI Amplifier's support. The driver provides direct access via |
| @@ -80,6 +80,8 @@ config ENS160 · 79 unmodified lines | |||
| 80 | tristate "ScioSense ENS160 sensor driver" | 80 | tristate "ScioSense ENS160 sensor driver" |
| 81 | depends on (I2C || SPI) | 81 | depends on (I2C || SPI) |
| 82 | select REGMAP | 82 | select REGMAP |
| 83 | select IIO_BUFFER | ||
| 84 | select IIO_TRIGGERED_BUFFER | ||
| 83 | select ENS160_I2C if I2C | 85 | select ENS160_I2C if I2C |
| 84 | select ENS160_SPI if SPI | 86 | select ENS160_SPI if SPI |
| 85 | help | 87 | help |
| @@ -32,7 +32,7 @@ static ssize_t _hid_sensor_set_report_latency(struct device *dev, · 31 unmodified lines | |||
| 32 | latency = integer * 1000 + fract / 1000; | 32 | latency = integer * 1000 + fract / 1000; |
| 33 | ret = hid_sensor_set_report_latency(attrb, latency); | 33 | ret = hid_sensor_set_report_latency(attrb, latency); |
| 34 | if (ret < 0) | 34 | if (ret < 0) |
| 35 | return len; | 35 | return ret; |
| 36 | 36 | ||
| 37 | attrb->latency_ms = hid_sensor_get_report_latency(attrb); | 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 | config AD3552R | 9 | config AD3552R |
| 10 | tristate "Analog Devices AD3552R DAC driver" | 10 | tristate "Analog Devices AD3552R DAC driver" |
| 11 | depends on SPI_MASTER | 11 | depends on SPI_MASTER |
| 12 | select IIO_BUFFER | ||
| 13 | select IIO_TRIGGERED_BUFFER | ||
| 12 | help | 14 | help |
| 13 | Say yes here to build support for Analog Devices AD3552R | 15 | Say yes here to build support for Analog Devices AD3552R |
| 14 | Digital to Analog Converter. | 16 | Digital to Analog Converter. |
| @@ -252,6 +254,8 @@ config AD5764 · 237 unmodified lines | |||
| 252 | config AD5766 | 254 | config AD5766 |
| 253 | tristate "Analog Devices AD5766/AD5767 DAC driver" | 255 | tristate "Analog Devices AD5766/AD5767 DAC driver" |
| 254 | depends on SPI_MASTER | 256 | depends on SPI_MASTER |
| 257 | select IIO_BUFFER | ||
| 258 | select IIO_TRIGGERED_BUFFER | ||
| 255 | help | 259 | help |
| 256 | Say yes here to build support for Analog Devices AD5766, AD5767 | 260 | Say yes here to build support for Analog Devices AD5766, AD5767 |
| 257 | Digital to Analog Converter. | 261 | Digital to Analog Converter. |
| @@ -262,6 +266,7 @@ config AD5766 · 4 unmodified lines | |||
| 262 | config AD5770R | 266 | config AD5770R |
| 263 | tristate "Analog Devices AD5770R IDAC driver" | 267 | tristate "Analog Devices AD5770R IDAC driver" |
| 264 | depends on SPI_MASTER | 268 | depends on SPI_MASTER |
| 269 | select REGMAP_SPI | ||
| 265 | help | 270 | help |
| 266 | Say yes here to build support for Analog Devices AD5770R Digital to | 271 | Say yes here to build support for Analog Devices AD5770R Digital to |
| 267 | Analog Converter. | 272 | Analog Converter. |
| @@ -353,6 +358,7 @@ config LPC18XX_DAC · 85 unmodified lines | |||
| 353 | config LTC1660 | 358 | config LTC1660 |
| 354 | tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver" | 359 | tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver" |
| 355 | depends on SPI | 360 | depends on SPI |
| 361 | select REGMAP_SPI | ||
| 356 | help | 362 | help |
| 357 | Say yes here to build support for Linear Technology | 363 | Say yes here to build support for Linear Technology |
| 358 | LTC1660 and LTC1665 Digital to Analog Converters. | 364 | LTC1660 and LTC1665 Digital to Analog Converters. |
| @@ -483,6 +489,7 @@ config STM32_DAC · 124 unmodified lines | |||
| 483 | 489 | ||
| 484 | config STM32_DAC_CORE | 490 | config STM32_DAC_CORE |
| 485 | tristate | 491 | tristate |
| 492 | select REGMAP_MMIO | ||
| 486 | 493 | ||
| 487 | config TI_DAC082S085 | 494 | config TI_DAC082S085 |
| 488 | tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver" | 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 | const struct ltc2664_chip_info *chip_info = st->chip_info; | 516 | const struct ltc2664_chip_info *chip_info = st->chip_info; |
| 517 | struct device *dev = &st->spi->dev; | 517 | struct device *dev = &st->spi->dev; |
| 518 | u32 reg, tmp[2], mspan; | 518 | u32 reg, tmp[2], mspan; |
| 519 | int ret, span = 0; | 519 | int ret; |
| 520 | 520 | ||
| 521 | mspan = LTC2664_MSPAN_SOFTSPAN; | 521 | mspan = LTC2664_MSPAN_SOFTSPAN; |
| 522 | ret = device_property_read_u32(dev, "adi,manual-span-operation-config", | 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 | ret = fwnode_property_read_u32_array(child, "output-range-microvolt", | 579 | ret = fwnode_property_read_u32_array(child, "output-range-microvolt", |
| 580 | tmp, ARRAY_SIZE(tmp)); | 580 | tmp, ARRAY_SIZE(tmp)); |
| 581 | if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) { | 581 | if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) { |
| 582 | chan->span = ltc2664_set_span(st, tmp[0] / 1000, | 582 | ret = ltc2664_set_span(st, tmp[0] / 1000, tmp[1] / 1000, reg); |
| 583 | tmp[1] / 1000, reg); | 583 | if (ret < 0) |
| 584 | if (span < 0) | 584 | return dev_err_probe(dev, ret, |
| 585 | return dev_err_probe(dev, span, | ||
| 586 | "Failed to set span\n"); | 585 | "Failed to set span\n"); |
| 586 | chan->span = ret; | ||
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | ret = fwnode_property_read_u32_array(child, "output-range-microamp", | 589 | ret = fwnode_property_read_u32_array(child, "output-range-microamp", |
| 590 | tmp, ARRAY_SIZE(tmp)); | 590 | tmp, ARRAY_SIZE(tmp)); |
| 591 | if (!ret) { | 591 | if (!ret) { |
| 592 | chan->span = ltc2664_set_span(st, 0, tmp[1] / 1000, reg); | 592 | ret = ltc2664_set_span(st, 0, tmp[1] / 1000, reg); |
| 593 | if (span < 0) | 593 | if (ret < 0) |
| 594 | return dev_err_probe(dev, span, | 594 | return dev_err_probe(dev, ret, |
| 595 | "Failed to set span\n"); | 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 | config ADF4377 | 53 | config ADF4377 |
| 54 | tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer" | 54 | tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer" |
| 55 | depends on SPI && COMMON_CLK | 55 | depends on SPI && COMMON_CLK |
| 56 | select REGMAP_SPI | ||
| 56 | help | 57 | help |
| 57 | Say yes here to build support for Analog Devices ADF4377 Microwave | 58 | Say yes here to build support for Analog Devices ADF4377 Microwave |
| 58 | Wideband Synthesizer. | 59 | Wideband Synthesizer. |
| @@ -91,25 +92,26 @@ config ADMV1014 · 32 unmodified lines | |||
| 91 | module will be called admv1014. | 92 | module will be called admv1014. |
| 92 | 93 | ||
| 93 | config ADMV4420 | 94 | config ADMV4420 |
| 94 | tristate "Analog Devices ADMV4420 K Band Downconverter" | 95 | tristate "Analog Devices ADMV4420 K Band Downconverter" |
| 95 | depends on SPI | 96 | depends on SPI |
| 96 | help | 97 | select REGMAP_SPI |
| 97 | Say yes here to build support for Analog Devices K Band | 98 | help |
| 98 | Downconverter with integrated Fractional-N PLL and VCO. | 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 | 102 | To compile this driver as a module, choose M here: the |
| 101 | module will be called admv4420. | 103 | module will be called admv4420. |
| 102 | 104 | ||
| 103 | config ADRF6780 | 105 | config ADRF6780 |
| 104 | tristate "Analog Devices ADRF6780 Microwave Upconverter" | 106 | tristate "Analog Devices ADRF6780 Microwave Upconverter" |
| 105 | depends on SPI | 107 | depends on SPI |
| 106 | depends on COMMON_CLK | 108 | depends on COMMON_CLK |
| 107 | help | 109 | help |
| 108 | Say yes here to build support for Analog Devices ADRF6780 | 110 | Say yes here to build support for Analog Devices ADRF6780 |
| 109 | 5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter. | 111 | 5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter. |
| 110 | 112 | ||
| 111 | To compile this driver as a module, choose M here: the | 113 | To compile this driver as a module, choose M here: the |
| 112 | module will be called adrf6780. | 114 | module will be called adrf6780. |
| 113 | 115 | ||
| 114 | endmenu | 116 | endmenu |
| 115 | endmenu | 117 | endmenu |
| @@ -2172,7 +2172,6 @@ int bmi323_core_probe(struct device *dev) · 2171 unmodified lines | |||
| 2172 | } | 2172 | } |
| 2173 | EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); | 2173 | EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); |
| 2174 | 2174 | ||
| 2175 | #if defined(CONFIG_PM) | ||
| 2176 | static int bmi323_core_runtime_suspend(struct device *dev) | 2175 | static int bmi323_core_runtime_suspend(struct device *dev) |
| 2177 | { | 2176 | { |
| 2178 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | 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 | for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { | 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], | 2201 | ret = bmi323_read_ext_reg(data, bmi323_ext_reg_savestate[i], |
| 2203 | &savestate->reg_settings[i]); | 2202 | &savestate->ext_reg_settings[i]); |
| 2204 | if (ret) { | 2203 | if (ret) { |
| 2205 | dev_err(data->dev, | 2204 | dev_err(data->dev, |
| 2206 | "Error reading bmi323 external reg 0x%x: %d\n", | 2205 | "Error reading bmi323 external reg 0x%x: %d\n", |
| 2207 | bmi323_reg_savestate[i], ret); | 2206 | bmi323_ext_reg_savestate[i], ret); |
| 2208 | return ret; | 2207 | return ret; |
| 2209 | } | 2208 | } |
| 2210 | } | 2209 | } |
| @@ -2232,8 +2231,10 @@ static int bmi323_core_runtime_resume(struct device *dev) · 21 unmodified lines | |||
| 2232 | * after being reset in the lower power state by runtime-pm. | 2231 | * after being reset in the lower power state by runtime-pm. |
| 2233 | */ | 2232 | */ |
| 2234 | ret = bmi323_init(data); | 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 | return ret; | 2236 | return ret; |
| 2237 | } | ||
| 2237 | 2238 | ||
| 2238 | /* Register must be cleared before changing an active config */ | 2239 | /* Register must be cleared before changing an active config */ |
| 2239 | ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0); | 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 | for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { | 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 | ret = bmi323_write_ext_reg(data, bmi323_ext_reg_savestate[i], |
| 2247 | savestate->reg_settings[i]); | 2248 | savestate->ext_reg_settings[i]); |
| 2248 | if (ret) { | 2249 | if (ret) { |
| 2249 | dev_err(data->dev, | 2250 | dev_err(data->dev, |
| 2250 | "Error writing bmi323 external reg 0x%x: %d\n", | 2251 | "Error writing bmi323 external reg 0x%x: %d\n", |
| 2251 | bmi323_reg_savestate[i], ret); | 2252 | bmi323_ext_reg_savestate[i], ret); |
| 2252 | return ret; | 2253 | return ret; |
| 2253 | } | 2254 | } |
| 2254 | } | 2255 | } |
| @@ -2293,11 +2294,9 @@ static int bmi323_core_runtime_resume(struct device *dev) · 38 unmodified lines | |||
| 2293 | return iio_device_resume_triggering(indio_dev); | 2294 | return iio_device_resume_triggering(indio_dev); |
| 2294 | } | 2295 | } |
| 2295 | 2296 | ||
| 2296 | #endif | ||
| 2297 | |||
| 2298 | const struct dev_pm_ops bmi323_core_pm_ops = { | 2297 | const struct dev_pm_ops bmi323_core_pm_ops = { |
| 2299 | SET_RUNTIME_PM_OPS(bmi323_core_runtime_suspend, | 2298 | RUNTIME_PM_OPS(bmi323_core_runtime_suspend, |
| 2300 | bmi323_core_runtime_resume, NULL) | 2299 | bmi323_core_runtime_resume, NULL) |
| 2301 | }; | 2300 | }; |
| 2302 | EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, IIO_BMI323); | 2301 | EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, IIO_BMI323); |
| 2303 | 2302 | ||
| @@ -335,6 +335,8 @@ config ROHM_BU27008 · 334 unmodified lines | |||
| 335 | depends on I2C | 335 | depends on I2C |
| 336 | select REGMAP_I2C | 336 | select REGMAP_I2C |
| 337 | select IIO_GTS_HELPER | 337 | select IIO_GTS_HELPER |
| 338 | select IIO_BUFFER | ||
| 339 | select IIO_TRIGGERED_BUFFER | ||
| 338 | help | 340 | help |
| 339 | Enable support for the ROHM BU27008 color sensor. | 341 | Enable support for the ROHM BU27008 color sensor. |
| 340 | The ROHM BU27008 is a sensor with 5 photodiodes (red, green, | 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 | .val = 20966, | 138 | .val = 20966, |
| 139 | .val2 = 400000, | 139 | .val2 = 400000, |
| 140 | }, | 140 | }, |
| 141 | { | ||
| 142 | .val = 41932, | ||
| 143 | .val2 = 800000, | ||
| 144 | }, | ||
| 141 | { | 145 | { |
| 142 | .val = 83865, | 146 | .val = 83865, |
| 143 | .val2 = 600000, | 147 | .val2 = 600000, |
| @@ -99,9 +99,8 @@ static const char * const period_values[] = { · 98 unmodified lines | |||
| 99 | static ssize_t in_illuminance_period_available_show(struct device *dev, | 99 | static ssize_t in_illuminance_period_available_show(struct device *dev, |
| 100 | struct device_attribute *attr, char *buf) | 100 | struct device_attribute *attr, char *buf) |
| 101 | { | 101 | { |
| 102 | struct veml6030_data *data = iio_priv(dev_to_iio_dev(dev)); | ||
| 102 | int ret, reg, x; | 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 | ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); | 105 | ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); |
| 107 | if (ret) { | 106 | if (ret) { |
| @@ -780,7 +779,7 @@ static int veml6030_hw_init(struct iio_dev *indio_dev) · 672 unmodified lines | |||
| 780 | 779 | ||
| 781 | /* Cache currently active measurement parameters */ | 780 | /* Cache currently active measurement parameters */ |
| 782 | data->cur_gain = 3; | 781 | data->cur_gain = 3; |
| 783 | data->cur_resolution = 4608; | 782 | data->cur_resolution = 5376; |
| 784 | data->cur_integration_time = 3; | 783 | data->cur_integration_time = 3; |
| 785 | 784 | ||
| 786 | return ret; | 785 | return ret; |
| @@ -11,6 +11,8 @@ config AF8133J · 10 unmodified lines | |||
| 11 | depends on I2C | 11 | depends on I2C |
| 12 | depends on OF | 12 | depends on OF |
| 13 | select REGMAP_I2C | 13 | select REGMAP_I2C |
| 14 | select IIO_BUFFER | ||
| 15 | select IIO_TRIGGERED_BUFFER | ||
| 14 | help | 16 | help |
| 15 | Say yes here to build support for Voltafield AF8133J I2C-based | 17 | Say yes here to build support for Voltafield AF8133J I2C-based |
| 16 | 3-axis magnetometer chip. | 18 | 3-axis magnetometer chip. |
| @@ -19,6 +19,9 @@ config ABP060MG · 18 unmodified lines | |||
| 19 | config ROHM_BM1390 | 19 | config ROHM_BM1390 |
| 20 | tristate "ROHM BM1390GLV-Z pressure sensor driver" | 20 | tristate "ROHM BM1390GLV-Z pressure sensor driver" |
| 21 | depends on I2C | 21 | depends on I2C |
| 22 | select REGMAP_I2C | ||
| 23 | select IIO_BUFFER | ||
| 24 | select IIO_TRIGGERED_BUFFER | ||
| 22 | help | 25 | help |
| 23 | Support for the ROHM BM1390 pressure sensor. The BM1390GLV-Z | 26 | Support for the ROHM BM1390 pressure sensor. The BM1390GLV-Z |
| 24 | can measure pressures ranging from 300 hPa to 1300 hPa with | 27 | can measure pressures ranging from 300 hPa to 1300 hPa with |
| @@ -253,6 +256,7 @@ config MS5637 · 228 unmodified lines | |||
| 253 | config SDP500 | 256 | config SDP500 |
| 254 | tristate "Sensirion SDP500 differential pressure sensor I2C driver" | 257 | tristate "Sensirion SDP500 differential pressure sensor I2C driver" |
| 255 | depends on I2C | 258 | depends on I2C |
| 259 | select CRC8 | ||
| 256 | help | 260 | help |
| 257 | Say Y here to build support for Sensirion SDP500 differential pressure | 261 | Say Y here to build support for Sensirion SDP500 differential pressure |
| 258 | sensor I2C driver. | 262 | sensor I2C driver. |
| @@ -86,6 +86,8 @@ config LIDAR_LITE_V2 · 85 unmodified lines | |||
| 86 | config MB1232 | 86 | config MB1232 |
| 87 | tristate "MaxSonar I2CXL family ultrasonic sensors" | 87 | tristate "MaxSonar I2CXL family ultrasonic sensors" |
| 88 | depends on I2C | 88 | depends on I2C |
| 89 | select IIO_BUFFER | ||
| 90 | select IIO_TRIGGERED_BUFFER | ||
| 89 | help | 91 | help |
| 90 | Say Y to build a driver for the ultrasonic sensors I2CXL of | 92 | Say Y to build a driver for the ultrasonic sensors I2CXL of |
| 91 | MaxBotix which have an i2c interface. It can be used to measure | 93 | MaxBotix which have an i2c interface. It can be used to measure |
| @@ -31,6 +31,9 @@ config AD2S1210 · 30 unmodified lines | |||
| 31 | depends on SPI | 31 | depends on SPI |
| 32 | depends on COMMON_CLK | 32 | depends on COMMON_CLK |
| 33 | depends on GPIOLIB || COMPILE_TEST | 33 | depends on GPIOLIB || COMPILE_TEST |
| 34 | select REGMAP | ||
| 35 | select IIO_BUFFER | ||
| 36 | select IIO_TRIGGERED_BUFFER | ||
| 34 | help | 37 | help |
| 35 | Say yes here to build support for Analog Devices spi resolver | 38 | Say yes here to build support for Analog Devices spi resolver |
| 36 | to digital converters, ad2s1210, provides direct access via sysfs. | 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 | break; | 269 | break; |
| 270 | #endif | 270 | #endif |
| 271 | } | 271 | } |
| 272 | if (!ret && dev && is_vlan_dev(dev)) | ||
| 273 | dev = vlan_dev_real_dev(dev); | ||
| 272 | return ret ? ERR_PTR(ret) : dev; | 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 | nlh = nlmsg_put(skb, 0, 0, | 2816 | nlh = nlmsg_put(skb, 0, 0, |
| 2817 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_MONITOR), | 2817 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_MONITOR), |
| 2818 | 0, 0); | 2818 | 0, 0); |
| 2819 | if (!nlh) | ||
| 2820 | goto err_free; | ||
| 2819 | 2821 | ||
| 2820 | switch (type) { | 2822 | switch (type) { |
| 2821 | case RDMA_REGISTER_EVENT: | 2823 | case RDMA_REGISTER_EVENT: |
| @@ -366,7 +366,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev, · 365 unmodified lines | |||
| 366 | goto done; | 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 | bnxt_re_copy_db_pacing_stats(rdev, stats); | 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 | 0 : BNXT_QPLIB_RESERVED_QP_WRS; | 1307 | 0 : BNXT_QPLIB_RESERVED_QP_WRS; |
| 1308 | entries = bnxt_re_init_depth(entries + diff + 1, uctx); | 1308 | entries = bnxt_re_init_depth(entries + diff + 1, uctx); |
| 1309 | sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1); | 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 | sq->q_full_delta = diff + 1; | 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 | bnxt_re_set_db_offset(rdev); | 189 | bnxt_re_set_db_offset(rdev); |
| 190 | rc = bnxt_qplib_map_db_bar(&rdev->qplib_res); | 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 | return rc; | 194 | return rc; |
| 195 | } | ||
| 193 | 196 | ||
| 194 | if (bnxt_qplib_determine_atomics(en_dev->pdev)) | 197 | if (bnxt_qplib_determine_atomics(en_dev->pdev)) |
| 195 | ibdev_info(&rdev->ibdev, | 198 | ibdev_info(&rdev->ibdev, |
| @@ -531,6 +534,7 @@ static bool is_dbr_fifo_full(struct bnxt_re_dev *rdev) · 335 unmodified lines | |||
| 531 | static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) | 534 | static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) |
| 532 | { | 535 | { |
| 533 | struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data; | 536 | struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data; |
| 537 | u32 retry_fifo_check = 1000; | ||
| 534 | u32 fifo_occup; | 538 | u32 fifo_occup; |
| 535 | 539 | ||
| 536 | /* loop shouldn't run infintely as the occupancy usually goes | 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 | if (fifo_occup < pacing_data->pacing_th) | 549 | if (fifo_occup < pacing_data->pacing_th) |
| 546 | break; | 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 | return ib_register_device(ibdev, "bnxt_re%d", &rdev->en_dev->pdev->dev); | 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 | struct bnxt_en_dev *en_dev) | 973 | struct bnxt_en_dev *en_dev) |
| 962 | { | 974 | { |
| 963 | struct bnxt_re_dev *rdev; | 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 | rdev->nb.notifier_call = NULL; | 985 | rdev->nb.notifier_call = NULL; |
| 974 | rdev->netdev = en_dev->net; | 986 | rdev->netdev = en_dev->net; |
| 975 | rdev->en_dev = en_dev; | 987 | rdev->en_dev = en_dev; |
| 988 | rdev->adev = adev; | ||
| 976 | rdev->id = rdev->en_dev->pdev->devfn; | 989 | rdev->id = rdev->en_dev->pdev->devfn; |
| 977 | INIT_LIST_HEAD(&rdev->qp_list); | 990 | INIT_LIST_HEAD(&rdev->qp_list); |
| 978 | mutex_init(&rdev->qp_lock); | 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 | static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event, | 1038 | static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event, |
| 1026 | struct bnxt_re_qp *qp) | 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 | struct creq_qp_error_notification *err_event; | 1041 | struct creq_qp_error_notification *err_event; |
| 1042 | struct bnxt_re_srq *srq = NULL; | ||
| 1031 | struct ib_event event = {}; | 1043 | struct ib_event event = {}; |
| 1032 | unsigned int flags; | 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 | if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR && | 1050 | if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR && |
| 1035 | rdma_is_kernel_res(&qp->ib_qp.res)) { | 1051 | rdma_is_kernel_res(&qp->ib_qp.res)) { |
| 1036 | flags = bnxt_re_lock_cqs(qp); | 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 | struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq, | 1275 | struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq, |
| 1260 | qplib_cq); | 1276 | qplib_cq); |
| 1261 | u32 *cq_ptr; | ||
| 1262 | 1277 | ||
| 1263 | if (cq->ib_cq.comp_handler) { | 1278 | 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 | } | ||
| 1268 | (*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context); | 1279 | (*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context); |
| 1269 | } | ||
| 1270 | 1280 | ||
| 1271 | return 0; | 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 | rtnl_lock(); | 1834 | rtnl_lock(); |
| 1825 | en_info->rdev = rdev; | 1835 | en_info->rdev = rdev; |
| 1826 | rdev->adev = adev; | ||
| 1827 | rtnl_unlock(); | 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 | en_dev = en_info->en_dev; | 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 | if (!rdev || !rdev_to_dev(rdev)) { | 1853 | if (!rdev || !rdev_to_dev(rdev)) { |
| 1845 | rc = -ENOMEM; | 1854 | rc = -ENOMEM; |
| 1846 | goto exit; | 1855 | goto exit; |
| @@ -1865,12 +1874,14 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type) · 18 unmodified lines | |||
| 1865 | rdev->nb.notifier_call = NULL; | 1874 | rdev->nb.notifier_call = NULL; |
| 1866 | pr_err("%s: Cannot register to netdevice_notifier", | 1875 | pr_err("%s: Cannot register to netdevice_notifier", |
| 1867 | ROCE_DRV_MODULE_NAME); | 1876 | ROCE_DRV_MODULE_NAME); |
| 1868 | return rc; | 1877 | goto re_dev_unreg; |
| 1869 | } | 1878 | } |
| 1870 | bnxt_re_setup_cc(rdev, true); | 1879 | bnxt_re_setup_cc(rdev, true); |
| 1871 | 1880 | ||
| 1872 | return 0; | 1881 | return 0; |
| 1873 | 1882 | ||
| 1883 | re_dev_unreg: | ||
| 1884 | ib_unregister_device(&rdev->ibdev); | ||
| 1874 | re_dev_uninit: | 1885 | re_dev_uninit: |
| 1875 | bnxt_re_update_en_info_rdev(NULL, en_info, adev); | 1886 | bnxt_re_update_en_info_rdev(NULL, en_info, adev); |
| 1876 | bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE); | 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 | auxiliary_set_drvdata(adev, en_info); | 2025 | auxiliary_set_drvdata(adev, en_info); |
| 2015 | 2026 | ||
| 2016 | rc = bnxt_re_add_device(adev, BNXT_RE_COMPLETE_INIT); | 2027 | rc = bnxt_re_add_device(adev, BNXT_RE_COMPLETE_INIT); |
| 2017 | if (rc) | ||
| 2018 | goto err; | ||
| 2019 | mutex_unlock(&bnxt_re_mutex); | 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 | return rc; | 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 | case NQ_BASE_TYPE_CQ_NOTIFICATION: | 327 | case NQ_BASE_TYPE_CQ_NOTIFICATION: |
| 328 | { | 328 | { |
| 329 | struct nq_cn *nqcne = (struct nq_cn *)nqe; | 329 | struct nq_cn *nqcne = (struct nq_cn *)nqe; |
| 330 | struct bnxt_re_cq *cq_p; | ||
| 330 | 331 | ||
| 331 | q_handle = le32_to_cpu(nqcne->cq_handle_low); | 332 | q_handle = le32_to_cpu(nqcne->cq_handle_low); |
| 332 | q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high) | 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 | cq->toggle = (le16_to_cpu(nqe->info10_type) & | 338 | cq->toggle = (le16_to_cpu(nqe->info10_type) & |
| 338 | NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT; | 339 | NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT; |
| 339 | cq->dbinfo.toggle = cq->toggle; | 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 | bnxt_qplib_armen_db(&cq->dbinfo, | 345 | bnxt_qplib_armen_db(&cq->dbinfo, |
| 341 | DBC_DBC_TYPE_CQ_ARMENA); | 346 | DBC_DBC_TYPE_CQ_ARMENA); |
| 342 | spin_lock_bh(&cq->compl_lock); | 347 | spin_lock_bh(&cq->compl_lock); |
| @@ -170,7 +170,7 @@ struct bnxt_qplib_swqe { · 169 unmodified lines | |||
| 170 | }; | 170 | }; |
| 171 | u32 q_key; | 171 | u32 q_key; |
| 172 | u32 dst_qp; | 172 | u32 dst_qp; |
| 173 | u16 avid; | 173 | u32 avid; |
| 174 | } send; | 174 | } send; |
| 175 | 175 | ||
| 176 | /* Send Raw Ethernet and QP1 */ | 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 | /* failed with status */ | 525 | /* failed with status */ |
| 526 | dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n", | 526 | dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n", |
| 527 | cookie, opcode, evnt->status); | 527 | cookie, opcode, evnt->status); |
| 528 | rc = -EFAULT; | 528 | rc = -EIO; |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | return rc; | 531 | return rc; |
| @@ -244,6 +244,8 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, · 243 unmodified lines | |||
| 244 | sginfo.pgsize = npde * pg_size; | 244 | sginfo.pgsize = npde * pg_size; |
| 245 | sginfo.npages = 1; | 245 | sginfo.npages = 1; |
| 246 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); | 246 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); |
| 247 | if (rc) | ||
| 248 | goto fail; | ||
| 247 | 249 | ||
| 248 | /* Alloc PBL pages */ | 250 | /* Alloc PBL pages */ |
| 249 | sginfo.npages = npbl; | 251 | sginfo.npages = npbl; |
| @@ -255,22 +257,9 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, · 5 unmodified lines | |||
| 255 | dst_virt_ptr = | 257 | dst_virt_ptr = |
| 256 | (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; | 258 | (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; |
| 257 | src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; | 259 | src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; |
| 258 | if (hwq_attr->type == HWQ_TYPE_MR) { | 260 | for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) |
| 259 | /* For MR it is expected that we supply only 1 contigous | 261 | dst_virt_ptr[0][i] = src_phys_ptr[i] | flag; |
| 260 | * page i.e only 1 entry in the PDL that will contain | 262 | |
| 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 | } | ||
| 274 | /* Alloc or init PTEs */ | 263 | /* Alloc or init PTEs */ |
| 275 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2], | 264 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2], |
| 276 | hwq_attr->sginfo); | 265 | hwq_attr->sginfo); |
| @@ -140,6 +140,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, · 139 unmodified lines | |||
| 140 | min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; | 140 | min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; |
| 141 | attr->max_cq = le32_to_cpu(sb->max_cq); | 141 | attr->max_cq = le32_to_cpu(sb->max_cq); |
| 142 | attr->max_cq_wqes = le32_to_cpu(sb->max_cqe); | 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 | attr->max_cq_sges = attr->max_qp_sges; | 145 | attr->max_cq_sges = attr->max_qp_sges; |
| 144 | attr->max_mr = le32_to_cpu(sb->max_mr); | 146 | attr->max_mr = le32_to_cpu(sb->max_mr); |
| 145 | attr->max_mw = le32_to_cpu(sb->max_mw); | 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 | if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) | 159 | if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) |
| 158 | attr->l2_db_size = (sb->l2_db_space_size + 1) * | 160 | attr->l2_db_size = (sb->l2_db_space_size + 1) * |
| 159 | (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); | 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 | attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags); | 170 | attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags); |
| 162 | attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2); | 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 | u32 max_qp_wqes; | 56 | u32 max_qp_wqes; |
| 57 | u32 max_qp_sges; | 57 | u32 max_qp_sges; |
| 58 | u32 max_cq; | 58 | u32 max_cq; |
| 59 | #define BNXT_QPLIB_MAX_CQ_WQES 0xfffff | ||
| 59 | u32 max_cq_wqes; | 60 | u32 max_cq_wqes; |
| 60 | u32 max_cq_sges; | 61 | u32 max_cq_sges; |
| 61 | u32 max_mr; | 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 | err = -ENOMEM; | 2086 | err = -ENOMEM; |
| 2087 | if (n->dev->flags & IFF_LOOPBACK) { | 2087 | if (n->dev->flags & IFF_LOOPBACK) { |
| 2088 | if (iptype == 4) | 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 | else if (IS_ENABLED(CONFIG_IPV6)) | 2090 | else if (IS_ENABLED(CONFIG_IPV6)) |
| 2091 | for_each_netdev(&init_net, pdev) { | 2091 | for_each_netdev(&init_net, pdev) { |
| 2092 | if (ipv6_chk_addr(&init_net, | 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 | err = -ENODEV; | 2101 | err = -ENODEV; |
| 2102 | goto out; | 2102 | goto out; |
| 2103 | } | 2103 | } |
| 2104 | if (is_vlan_dev(pdev)) | ||
| 2105 | pdev = vlan_dev_real_dev(pdev); | ||
| 2104 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, | 2106 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
| 2105 | n, pdev, rt_tos2priority(tos)); | 2107 | n, pdev, rt_tos2priority(tos)); |
| 2106 | if (!ep->l2t) { | 2108 | if (!ep->l2t) |
| 2107 | dev_put(pdev); | ||
| 2108 | goto out; | 2109 | goto out; |
| 2109 | } | ||
| 2110 | ep->mtu = pdev->mtu; | 2110 | ep->mtu = pdev->mtu; |
| 2111 | ep->tx_chan = cxgb4_port_chan(pdev); | 2111 | ep->tx_chan = cxgb4_port_chan(pdev); |
| 2112 | ep->smac_idx = ((struct port_info *)netdev_priv(pdev))->smt_idx; | 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 | ep->rss_qid = cdev->rdev.lldi.rxq_ids[ | 2119 | ep->rss_qid = cdev->rdev.lldi.rxq_ids[ |
| 2120 | cxgb4_port_idx(pdev) * step]; | 2120 | cxgb4_port_idx(pdev) * step]; |
| 2121 | set_tcp_window(ep, (struct port_info *)netdev_priv(pdev)); | 2121 | set_tcp_window(ep, (struct port_info *)netdev_priv(pdev)); |
| 2122 | dev_put(pdev); | ||
| 2123 | } else { | 2122 | } else { |
| 2124 | pdev = get_real_dev(n->dev); | 2123 | pdev = get_real_dev(n->dev); |
| 2125 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, | 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 | * irdma_accept - registered call for connection to be accepted | 3632 | * irdma_accept - registered call for connection to be accepted |
| 3633 | * @cm_id: cm information for passive connection | 3633 | * @cm_id: cm information for passive connection |
| 3634 | * @conn_param: accpet parameters | 3634 | * @conn_param: accept parameters |
| 3635 | */ | 3635 | */ |
| 3636 | int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | 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 | msg.msg_flags &= ~MSG_MORE; | 331 | msg.msg_flags &= ~MSG_MORE; |
| 332 | 332 | ||
| 333 | tcp_rate_check_app_limited(sk); | 333 | tcp_rate_check_app_limited(sk); |
| 334 | if (!sendpage_ok(page[i])) | ||
| 335 | msg.msg_flags &= ~MSG_SPLICE_PAGES; | ||
| 334 | bvec_set_page(&bvec, page[i], bytes, offset); | 336 | bvec_set_page(&bvec, page[i], bytes, offset); |
| 335 | iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); | 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 | static u64 srpt_service_guid; | 68 | static u64 srpt_service_guid; |
| 69 | static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */ | 69 | static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */ |
| 70 | static LIST_HEAD(srpt_dev_list); /* List of srpt_device structures. */ | 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 | static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE; | 74 | static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE; |
| 73 | module_param(srp_max_req_size, int, 0444); | 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 | static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc); | 107 | static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc); |
| 106 | static void srpt_process_wait_list(struct srpt_rdma_ch *ch); | 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 | * The only allowed channel state changes are those that change the channel | 168 | * The only allowed channel state changes are those that change the channel |
| 110 | * state into a state with a higher numerical value. Hence the new > prev test. | 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 | ch->sport->sdev, ch->rq_size, | 2178 | ch->sport->sdev, ch->rq_size, |
| 2120 | ch->rsp_buf_cache, DMA_TO_DEVICE); | 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 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring, | 2183 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring, |
| 2125 | sdev, ch->rq_size, | 2184 | sdev, ch->rq_size, |
| 2126 | ch->req_buf_cache, DMA_FROM_DEVICE); | 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 | kref_put(&ch->kref, srpt_free_ch); | 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 | INIT_LIST_HEAD(&ch->cmd_wait_list); | 2304 | INIT_LIST_HEAD(&ch->cmd_wait_list); |
| 2246 | ch->max_rsp_size = ch->sport->port_attrib.srp_max_rsp_size; | 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, | 2307 | ch->rsp_buf_cache = srpt_cache_get(ch->max_rsp_size); |
| 2249 | 512, 0, NULL); | ||
| 2250 | if (!ch->rsp_buf_cache) | 2308 | if (!ch->rsp_buf_cache) |
| 2251 | goto free_ch; | 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 | alignment_offset = round_up(imm_data_offset, 512) - | 2338 | alignment_offset = round_up(imm_data_offset, 512) - |
| 2281 | imm_data_offset; | 2339 | imm_data_offset; |
| 2282 | req_sz = alignment_offset + imm_data_offset + srp_max_req_size; | 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, | 2341 | ch->req_buf_cache = srpt_cache_get(req_sz); |
| 2284 | 512, 0, NULL); | ||
| 2285 | if (!ch->req_buf_cache) | 2342 | if (!ch->req_buf_cache) |
| 2286 | goto free_rsp_ring; | 2343 | goto free_rsp_ring; |
| 2287 | 2344 | ||
| @@ -2478,7 +2535,7 @@ free_recv_ring: · 190 unmodified lines | |||
| 2478 | ch->req_buf_cache, DMA_FROM_DEVICE); | 2535 | ch->req_buf_cache, DMA_FROM_DEVICE); |
| 2479 | 2536 | ||
| 2480 | free_recv_cache: | 2537 | free_recv_cache: |
| 2481 | kmem_cache_destroy(ch->req_buf_cache); | 2538 | srpt_cache_put(ch->req_buf_cache); |
| 2482 | 2539 | ||
| 2483 | free_rsp_ring: | 2540 | free_rsp_ring: |
| 2484 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, | 2541 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, |
| @@ -2486,7 +2543,7 @@ free_rsp_ring: · 1 unmodified line | |||
| 2486 | ch->rsp_buf_cache, DMA_TO_DEVICE); | 2543 | ch->rsp_buf_cache, DMA_TO_DEVICE); |
| 2487 | 2544 | ||
| 2488 | free_rsp_cache: | 2545 | free_rsp_cache: |
| 2489 | kmem_cache_destroy(ch->rsp_buf_cache); | 2546 | srpt_cache_put(ch->rsp_buf_cache); |
| 2490 | 2547 | ||
| 2491 | free_ch: | 2548 | free_ch: |
| 2492 | if (rdma_cm_id) | 2549 | if (rdma_cm_id) |
| @@ -3055,7 +3112,7 @@ static void srpt_free_srq(struct srpt_device *sdev) · 562 unmodified lines | |||
| 3055 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, | 3112 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, |
| 3056 | sdev->srq_size, sdev->req_buf_cache, | 3113 | sdev->srq_size, sdev->req_buf_cache, |
| 3057 | DMA_FROM_DEVICE); | 3114 | DMA_FROM_DEVICE); |
| 3058 | kmem_cache_destroy(sdev->req_buf_cache); | 3115 | srpt_cache_put(sdev->req_buf_cache); |
| 3059 | sdev->srq = NULL; | 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 | pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size, | 3139 | pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size, |
| 3083 | sdev->device->attrs.max_srq_wr, dev_name(&device->dev)); | 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", | 3142 | sdev->req_buf_cache = srpt_cache_get(srp_max_req_size); |
| 3086 | srp_max_req_size, 0, 0, NULL); | ||
| 3087 | if (!sdev->req_buf_cache) | 3143 | if (!sdev->req_buf_cache) |
| 3088 | goto free_srq; | 3144 | goto free_srq; |
| 3089 | 3145 | ||
| @@ -3105,7 +3161,7 @@ static int srpt_alloc_srq(struct srpt_device *sdev) · 15 unmodified lines | |||
| 3105 | return 0; | 3161 | return 0; |
| 3106 | 3162 | ||
| 3107 | free_cache: | 3163 | free_cache: |
| 3108 | kmem_cache_destroy(sdev->req_buf_cache); | 3164 | srpt_cache_put(sdev->req_buf_cache); |
| 3109 | 3165 | ||
| 3110 | free_srq: | 3166 | free_srq: |
| 3111 | ib_destroy_srq(srq); | 3167 | ib_destroy_srq(srq); |
| @@ -218,6 +218,7 @@ static const struct xpad_device { · 217 unmodified lines | |||
| 218 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, | 218 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
| 219 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, | 219 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, |
| 220 | { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 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 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, | 222 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, |
| 222 | { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX }, | 223 | { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX }, |
| 223 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, | 224 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, |
| @@ -373,6 +374,7 @@ static const struct xpad_device { · 149 unmodified lines | |||
| 373 | { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, | 374 | { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, |
| 374 | { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, | 375 | { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, |
| 375 | { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, | 376 | { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, |
| 377 | { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 }, | ||
| 376 | { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, | 378 | { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, |
| 377 | { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, | 379 | { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, |
| 378 | { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, | 380 | { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, |
| @@ -492,6 +494,7 @@ static const struct usb_device_id xpad_table[] = { · 113 unmodified lines | |||
| 492 | XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz Gamepad */ | 494 | XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz Gamepad */ |
| 493 | XPAD_XBOXONE_VENDOR(0x0b05), /* ASUS controllers */ | 495 | XPAD_XBOXONE_VENDOR(0x0b05), /* ASUS controllers */ |
| 494 | XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ | 496 | XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ |
| 497 | XPAD_XBOX360_VENDOR(0x0db0), /* Micro Star International X-Box 360 controllers */ | ||
| 495 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f Xbox 360 controllers */ | 498 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f Xbox 360 controllers */ |
| 496 | XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f Xbox One controllers */ | 499 | XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f Xbox One controllers */ |
| 497 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori controllers */ | 500 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori controllers */ |
| @@ -645,19 +645,29 @@ static int zinitix_ts_probe(struct i2c_client *client) · 644 unmodified lines | |||
| 645 | return error; | 645 | return error; |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | bt541->num_keycodes = device_property_count_u32(&client->dev, "linux,keycodes"); | 648 | if (device_property_present(&client->dev, "linux,keycodes")) { |
| 649 | if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) { | 649 | bt541->num_keycodes = device_property_count_u32(&client->dev, |
| 650 | dev_err(&client->dev, "too many keys defined (%d)\n", bt541->num_keycodes); | 650 | "linux,keycodes"); |
| 651 | return -EINVAL; | 651 | if (bt541->num_keycodes < 0) { |
| 652 | } | 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", | 661 | error = device_property_read_u32_array(&client->dev, |
| 655 | bt541->keycodes, | 662 | "linux,keycodes", |
| 656 | bt541->num_keycodes); | 663 | bt541->keycodes, |
| 657 | if (error) { | 664 | bt541->num_keycodes); |
| 658 | dev_err(&client->dev, | 665 | if (error) { |
| 659 | "Unable to parse \"linux,keycodes\" property: %d\n", error); | 666 | dev_err(&client->dev, |
| 660 | return error; | 667 | "Unable to parse \"linux,keycodes\" property: %d\n", |
| 668 | error); | ||
| 669 | return error; | ||
| 670 | } | ||
| 661 | } | 671 | } |
| 662 | 672 | ||
| 663 | error = zinitix_init_input_dev(bt541); | 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 | cd_table->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; | 1420 | cd_table->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; |
| 1421 | cd_table->linear.num_ents = max_contexts; | 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 | cd_table->linear.table = dma_alloc_coherent(smmu->dev, l1size, | 1424 | cd_table->linear.table = dma_alloc_coherent(smmu->dev, l1size, |
| 1425 | &cd_table->cdtab_dma, | 1425 | &cd_table->cdtab_dma, |
| 1426 | GFP_KERNEL); | 1426 | GFP_KERNEL); |
| @@ -3625,7 +3625,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) · 2198 unmodified lines | |||
| 3625 | u32 l1size; | 3625 | u32 l1size; |
| 3626 | struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; | 3626 | struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; |
| 3627 | unsigned int last_sid_idx = | 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 | /* Calculate the L1 size, capped to the SIDSIZE. */ | 3630 | /* Calculate the L1 size, capped to the SIDSIZE. */ |
| 3631 | cfg->l2.num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES); | 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 | * Disable MMU-500's not-particularly-beneficial next-page | 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 | for (i = 0; i < smmu->num_context_banks; ++i) { | 135 | for (i = 0; i < smmu->num_context_banks; ++i) { |
| 136 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); | 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 | arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg); | 138 | arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg); |
| 139 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); | 139 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); |
| 140 | if (reg & ARM_MMU500_ACTLR_CPRE) | 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 | return 0; | 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 | static void domain_context_clear(struct device_domain_info *info) | 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 | domain_context_clear_one(info, info->bus, info->devfn); | 3344 | domain_context_clear_one(info, info->bus, info->devfn); |
| 3345 | return; | ||
| 3346 | } | ||
| 3345 | 3347 | ||
| 3346 | pci_for_each_dma_alias(to_pci_dev(info->dev), | 3348 | pci_for_each_dma_alias(to_pci_dev(info->dev), |
| 3347 | &domain_context_clear_one_cb, info); | 3349 | &domain_context_clear_one_cb, info); |
| @@ -45,13 +45,6 @@ config ARM_GIC_V3_ITS · 44 unmodified lines | |||
| 45 | select IRQ_MSI_LIB | 45 | select IRQ_MSI_LIB |
| 46 | default ARM_GIC_V3 | 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 | config ARM_GIC_V3_ITS_FSL_MC | 48 | config ARM_GIC_V3_ITS_FSL_MC |
| 56 | bool | 49 | bool |
| 57 | depends on ARM_GIC_V3_ITS | 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 | its_encode_valid(cmd, desc->its_vmapp_cmd.valid); | 797 | its_encode_valid(cmd, desc->its_vmapp_cmd.valid); |
| 798 | 798 | ||
| 799 | if (!desc->its_vmapp_cmd.valid) { | 799 | if (!desc->its_vmapp_cmd.valid) { |
| 800 | alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); | ||
| 800 | if (is_v4_1(its)) { | 801 | if (is_v4_1(its)) { |
| 801 | alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); | ||
| 802 | its_encode_alloc(cmd, alloc); | 802 | its_encode_alloc(cmd, alloc); |
| 803 | /* | 803 | /* |
| 804 | * Unmapping a VPE is self-synchronizing on GICv4.1, | 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 | its_encode_vpt_addr(cmd, vpt_addr); | 817 | its_encode_vpt_addr(cmd, vpt_addr); |
| 818 | its_encode_vpt_size(cmd, LPI_NRBITS - 1); | 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 | if (!is_v4_1(its)) | 822 | if (!is_v4_1(its)) |
| 821 | goto out; | 823 | goto out; |
| 822 | 824 | ||
| 823 | vconf_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->its_vm->vprop_page)); | 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 | its_encode_alloc(cmd, alloc); | 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 | struct cpumask *table_mask; | 3806 | struct cpumask *table_mask; |
| 3807 | unsigned long flags; | 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 | * Changing affinity is mega expensive, so let's be as lazy as | 3817 | * Changing affinity is mega expensive, so let's be as lazy as |
| 3811 | * we can and only do it if we really have to. Also, if mapped | 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 | raw_spin_lock_init(&vpe->vpe_lock); | 4470 | raw_spin_lock_init(&vpe->vpe_lock); |
| 4464 | vpe->vpe_id = vpe_id; | 4471 | vpe->vpe_id = vpe_id; |
| 4465 | vpe->vpt_page = vpt_page; | 4472 | vpe->vpt_page = vpt_page; |
| 4466 | if (gic_rdists->has_rvpeid) | 4473 | atomic_set(&vpe->vmapp_count, 0); |
| 4467 | atomic_set(&vpe->vmapp_count, 0); | 4474 | if (!gic_rdists->has_rvpeid) |
| 4468 | else | ||
| 4469 | vpe->vpe_proxy_event = -1; | 4475 | vpe->vpe_proxy_event = -1; |
| 4470 | 4476 | ||
| 4471 | return 0; | 4477 | return 0; |
| @@ -37,7 +37,7 @@ static struct chip_props ocelot_props = { · 36 unmodified lines | |||
| 37 | .reg_off_ena_clr = 0x1c, | 37 | .reg_off_ena_clr = 0x1c, |
| 38 | .reg_off_ena_set = 0x20, | 38 | .reg_off_ena_set = 0x20, |
| 39 | .reg_off_ident = 0x38, | 39 | .reg_off_ident = 0x38, |
| 40 | .reg_off_trigger = 0x5c, | 40 | .reg_off_trigger = 0x4, |
| 41 | .n_irq = 24, | 41 | .n_irq = 24, |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| @@ -70,7 +70,7 @@ static struct chip_props jaguar2_props = { · 26 unmodified lines | |||
| 70 | .reg_off_ena_clr = 0x1c, | 70 | .reg_off_ena_clr = 0x1c, |
| 71 | .reg_off_ena_set = 0x20, | 71 | .reg_off_ena_set = 0x20, |
| 72 | .reg_off_ident = 0x38, | 72 | .reg_off_ident = 0x38, |
| 73 | .reg_off_trigger = 0x5c, | 73 | .reg_off_trigger = 0x4, |
| 74 | .n_irq = 29, | 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 | u32 val; | 84 | u32 val; |
| 85 | 85 | ||
| 86 | irq_gc_lock(gc); | 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 | val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) | | 93 | val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) | |
| 88 | irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1)); | 94 | irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1)); |
| 89 | if (!(val & mask)) | 95 | if (!(val & mask)) |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/bitfield.h> | 10 | #include <linux/bitfield.h> |
| 11 | #include <linux/cleanup.h> | ||
| 11 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
| 12 | #include <linux/err.h> | 13 | #include <linux/err.h> |
| 13 | #include <linux/io.h> | 14 | #include <linux/io.h> |
| @@ -530,12 +531,12 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv, · 516 unmodified lines | |||
| 530 | static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent, | 531 | static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent, |
| 531 | const struct irq_chip *irq_chip) | 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 | struct irq_domain *irq_domain, *parent_domain; | 536 | struct irq_domain *irq_domain, *parent_domain; |
| 534 | struct platform_device *pdev; | ||
| 535 | struct reset_control *resetn; | 537 | struct reset_control *resetn; |
| 536 | int ret; | 538 | int ret; |
| 537 | 539 | ||
| 538 | pdev = of_find_device_by_node(node); | ||
| 539 | if (!pdev) | 540 | if (!pdev) |
| 540 | return -ENODEV; | 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 | register_syscore_ops(&rzg2l_irqc_syscore_ops); | 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 | return 0; | 606 | return 0; |
| 595 | 607 | ||
| 596 | pm_put: | 608 | pm_put: |
| @@ -341,7 +341,7 @@ int imsic_irqdomain_init(void) · 340 unmodified lines | |||
| 341 | imsic->fwnode, global->hart_index_bits, global->guest_index_bits); | 341 | imsic->fwnode, global->hart_index_bits, global->guest_index_bits); |
| 342 | pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n", | 342 | pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n", |
| 343 | imsic->fwnode, global->group_index_bits, global->group_index_shift); | 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 | imsic->fwnode, global->nr_ids, &global->base_addr); | 345 | imsic->fwnode, global->nr_ids, &global->base_addr); |
| 346 | pr_info("%pfwP: total %d interrupts available\n", | 346 | pr_info("%pfwP: total %d interrupts available\n", |
| 347 | imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1)); | 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 | static u32 nr_rintc; | 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 | #define for_each_matching_plic(_plic_id) \ | 270 | #define for_each_matching_plic(_plic_id) \ |
| 271 | unsigned int _plic; \ | 271 | unsigned int _plic; \ |
| @@ -329,13 +329,30 @@ int acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res) · 57 unmodified lines | |||
| 329 | return 0; | 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 | static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, | 338 | static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, |
| 333 | const unsigned long end) | 339 | const unsigned long end) |
| 334 | { | 340 | { |
| 335 | struct acpi_madt_rintc *rintc; | 341 | struct acpi_madt_rintc *rintc; |
| 336 | struct fwnode_handle *fn; | 342 | struct fwnode_handle *fn; |
| 343 | int count; | ||
| 337 | int rc; | 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 | rintc = (struct acpi_madt_rintc *)header; | 356 | rintc = (struct acpi_madt_rintc *)header; |
| 340 | rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL); | 357 | rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL); |
| 341 | if (!rintc_acpi_data[nr_rintc]) | 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 | static void plic_irq_unmask(struct irq_data *d) | 129 | static void plic_irq_unmask(struct irq_data *d) |
| 140 | { | 130 | { |
| 141 | struct plic_priv *priv = irq_data_get_irq_chip_data(d); | 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 | writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); | 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 | static void plic_irq_eoi(struct irq_data *d) | 154 | static void plic_irq_eoi(struct irq_data *d) |
| 154 | { | 155 | { |
| 155 | struct plic_handler *handler = this_cpu_ptr(&plic_handlers); | 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 | handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), | 628 | handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), |
| 628 | sizeof(*handler->enable_save), GFP_KERNEL); | 629 | sizeof(*handler->enable_save), GFP_KERNEL); |
| 629 | if (!handler->enable_save) | 630 | if (!handler->enable_save) { |
| 631 | error = -ENOMEM; | ||
| 630 | goto fail_cleanup_contexts; | 632 | goto fail_cleanup_contexts; |
| 633 | } | ||
| 631 | done: | 634 | done: |
| 632 | for (hwirq = 1; hwirq <= nr_irqs; hwirq++) { | 635 | for (hwirq = 1; hwirq <= nr_irqs; hwirq++) { |
| 633 | plic_toggle(handler, hwirq, 0); | 636 | plic_toggle(handler, hwirq, 0); |
| @@ -639,8 +642,10 @@ done: · 5 unmodified lines | |||
| 639 | 642 | ||
| 640 | priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1, | 643 | priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1, |
| 641 | &plic_irqdomain_ops, priv); | 644 | &plic_irqdomain_ops, priv); |
| 642 | if (WARN_ON(!priv->irqdomain)) | 645 | if (WARN_ON(!priv->irqdomain)) { |
| 646 | error = -ENOMEM; | ||
| 643 | goto fail_cleanup_contexts; | 647 | goto fail_cleanup_contexts; |
| 648 | } | ||
| 644 | 649 | ||
| 645 | /* | 650 | /* |
| 646 | * We can have multiple PLIC instances so setup global state | 651 | * We can have multiple PLIC instances so setup global state |
| @@ -16,7 +16,8 @@ config MISC_RTSX_PCI · 15 unmodified lines | |||
| 16 | select MFD_CORE | 16 | select MFD_CORE |
| 17 | help | 17 | help |
| 18 | This supports for Realtek PCI-Express card reader including rts5209, | 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 | Realtek card readers support access to many types of memory cards, | 21 | Realtek card readers support access to many types of memory cards, |
| 21 | such as Memory Stick, Memory Stick Pro, Secure Digital and | 22 | such as Memory Stick, Memory Stick Pro, Secure Digital and |
| 22 | MultiMediaCard. | 23 | MultiMediaCard. |
| @@ -364,6 +364,7 @@ static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev, · 363 unmodified lines | |||
| 364 | if (is_eeprom_responsive(priv)) { | 364 | if (is_eeprom_responsive(priv)) { |
| 365 | priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM; | 365 | priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM; |
| 366 | priv->nvmem_config_eeprom.name = EEPROM_NAME; | 366 | priv->nvmem_config_eeprom.name = EEPROM_NAME; |
| 367 | priv->nvmem_config_eeprom.id = NVMEM_DEVID_AUTO; | ||
| 367 | priv->nvmem_config_eeprom.dev = &aux_dev->dev; | 368 | priv->nvmem_config_eeprom.dev = &aux_dev->dev; |
| 368 | priv->nvmem_config_eeprom.owner = THIS_MODULE; | 369 | priv->nvmem_config_eeprom.owner = THIS_MODULE; |
| 369 | priv->nvmem_config_eeprom.reg_read = pci1xxxx_eeprom_read; | 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 | priv->nvmem_config_otp.type = NVMEM_TYPE_OTP; | 385 | priv->nvmem_config_otp.type = NVMEM_TYPE_OTP; |
| 385 | priv->nvmem_config_otp.name = OTP_NAME; | 386 | priv->nvmem_config_otp.name = OTP_NAME; |
| 387 | priv->nvmem_config_otp.id = NVMEM_DEVID_AUTO; | ||
| 386 | priv->nvmem_config_otp.dev = &aux_dev->dev; | 388 | priv->nvmem_config_otp.dev = &aux_dev->dev; |
| 387 | priv->nvmem_config_otp.owner = THIS_MODULE; | 389 | priv->nvmem_config_otp.owner = THIS_MODULE; |
| 388 | priv->nvmem_config_otp.reg_read = pci1xxxx_otp_read; | 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 | int lcpu; | 258 | int lcpu; |
| 259 | 259 | ||
| 260 | BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); | 260 | BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); |
| 261 | preempt_disable(); | ||
| 262 | bs = gru_lock_kernel_context(-1); | 261 | bs = gru_lock_kernel_context(-1); |
| 263 | lcpu = uv_blade_processor_id(); | 262 | lcpu = uv_blade_processor_id(); |
| 264 | *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE; | 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 | static void gru_free_cpu_resources(void *cb, void *dsr) | 271 | static void gru_free_cpu_resources(void *cb, void *dsr) |
| 273 | { | 272 | { |
| 274 | gru_unlock_kernel_context(uv_numa_blade_id()); | 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 | again: | 938 | again: |
| 939 | mutex_lock(>s->ts_ctxlock); | 939 | mutex_lock(>s->ts_ctxlock); |
| 940 | preempt_disable(); | ||
| 941 | 940 | ||
| 942 | if (gru_check_context_placement(gts)) { | 941 | if (gru_check_context_placement(gts)) { |
| 943 | preempt_enable(); | ||
| 944 | mutex_unlock(>s->ts_ctxlock); | 942 | mutex_unlock(>s->ts_ctxlock); |
| 945 | gru_unload_context(gts, 1); | 943 | gru_unload_context(gts, 1); |
| 946 | return VM_FAULT_NOPAGE; | 944 | return VM_FAULT_NOPAGE; |
| @@ -949,7 +947,6 @@ again: · 2 unmodified lines | |||
| 949 | if (!gts->ts_gru) { | 947 | if (!gts->ts_gru) { |
| 950 | STAT(load_user_context); | 948 | STAT(load_user_context); |
| 951 | if (!gru_assign_gru_context(gts)) { | 949 | if (!gru_assign_gru_context(gts)) { |
| 952 | preempt_enable(); | ||
| 953 | mutex_unlock(>s->ts_ctxlock); | 950 | mutex_unlock(>s->ts_ctxlock); |
| 954 | set_current_state(TASK_INTERRUPTIBLE); | 951 | set_current_state(TASK_INTERRUPTIBLE); |
| 955 | schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ | 952 | schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ |
| @@ -965,7 +962,6 @@ again: · 9 unmodified lines | |||
| 965 | vma->vm_page_prot); | 962 | vma->vm_page_prot); |
| 966 | } | 963 | } |
| 967 | 964 | ||
| 968 | preempt_enable(); | ||
| 969 | mutex_unlock(>s->ts_ctxlock); | 965 | mutex_unlock(>s->ts_ctxlock); |
| 970 | 966 | ||
| 971 | return VM_FAULT_NOPAGE; | 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 | struct gru_tlb_global_handle *tgh; | 65 | struct gru_tlb_global_handle *tgh; |
| 66 | int n; | 66 | int n; |
| 67 | 67 | ||
| 68 | preempt_disable(); | ||
| 69 | if (uv_numa_blade_id() == gru->gs_blade_id) | 68 | if (uv_numa_blade_id() == gru->gs_blade_id) |
| 70 | n = get_on_blade_tgh(gru); | 69 | n = get_on_blade_tgh(gru); |
| 71 | else | 70 | else |
| @@ -79,7 +78,6 @@ static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state · 7 unmodified lines | |||
| 79 | static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh) | 78 | static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh) |
| 80 | { | 79 | { |
| 81 | unlock_tgh_handle(tgh); | 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 | blk_queue_rq_timeout(mq->queue, 60 * HZ); | 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 | INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler); | 394 | INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler); |
| 394 | INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); | 395 | INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); |
| @@ -38,9 +38,8 @@ struct mvsd_host { · 37 unmodified lines | |||
| 38 | unsigned int xfer_mode; | 38 | unsigned int xfer_mode; |
| 39 | unsigned int intr_en; | 39 | unsigned int intr_en; |
| 40 | unsigned int ctrl; | 40 | unsigned int ctrl; |
| 41 | bool use_pio; | ||
| 42 | struct sg_mapping_iter sg_miter; | ||
| 43 | unsigned int pio_size; | 41 | unsigned int pio_size; |
| 42 | void *pio_ptr; | ||
| 44 | unsigned int sg_frags; | 43 | unsigned int sg_frags; |
| 45 | unsigned int ns_per_clk; | 44 | unsigned int ns_per_clk; |
| 46 | unsigned int clock; | 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 | * data when the buffer is not aligned on a 64 byte | 114 | * data when the buffer is not aligned on a 64 byte |
| 116 | * boundary. | 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 | host->pio_size = data->blocks * data->blksz; | 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 | if (!nodma) | 119 | if (!nodma) |
| 128 | dev_dbg(host->dev, "fallback to PIO for data\n"); | 120 | dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n", |
| 129 | host->use_pio = true; | 121 | host->pio_ptr, host->pio_size); |
| 130 | return 1; | 122 | return 1; |
| 131 | } else { | 123 | } else { |
| 132 | dma_addr_t phys_addr; | 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 | phys_addr = sg_dma_address(data->sg); | 129 | phys_addr = sg_dma_address(data->sg); |
| 138 | mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff); | 130 | mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff); |
| 139 | mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16); | 131 | mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16); |
| 140 | host->use_pio = false; | ||
| 141 | return 0; | 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 | void __iomem *iobase = host->base; | 289 | void __iomem *iobase = host->base; |
| 299 | 290 | ||
| 300 | if (host->use_pio) { | 291 | if (host->pio_ptr) { |
| 301 | sg_miter_stop(&host->sg_miter); | 292 | host->pio_ptr = NULL; |
| 302 | host->pio_size = 0; | 293 | host->pio_size = 0; |
| 303 | } else { | 294 | } else { |
| 304 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags, | 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 | static irqreturn_t mvsd_irq(int irq, void *dev) | 344 | static irqreturn_t mvsd_irq(int irq, void *dev) |
| 354 | { | 345 | { |
| 355 | struct mvsd_host *host = dev; | 346 | struct mvsd_host *host = dev; |
| 356 | struct sg_mapping_iter *sgm = &host->sg_miter; | ||
| 357 | void __iomem *iobase = host->base; | 347 | void __iomem *iobase = host->base; |
| 358 | u32 intr_status, intr_done_mask; | 348 | u32 intr_status, intr_done_mask; |
| 359 | int irq_handled = 0; | 349 | int irq_handled = 0; |
| 360 | u16 *p; | ||
| 361 | int s; | ||
| 362 | 350 | ||
| 363 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 351 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 364 | dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n", | 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 | spin_lock(&host->lock); | 370 | spin_lock(&host->lock); |
| 383 | 371 | ||
| 384 | /* PIO handling, if needed. Messy business... */ | 372 | /* PIO handling, if needed. Messy business... */ |
| 385 | if (host->use_pio) { | 373 | if (host->pio_size && |
| 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 && | ||
| 407 | (intr_status & host->intr_en & | 374 | (intr_status & host->intr_en & |
| 408 | (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) { | 375 | (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) { |
| 409 | 376 | u16 *p = host->pio_ptr; | |
| 377 | int s = host->pio_size; | ||
| 410 | while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) { | 378 | while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) { |
| 411 | readsw(iobase + MVSD_FIFO, p, 16); | 379 | readsw(iobase + MVSD_FIFO, p, 16); |
| 412 | p += 16; | 380 | p += 16; |
| 413 | s -= 32; | 381 | s -= 32; |
| 414 | sgm->consumed += 32; | ||
| 415 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 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 | put_unaligned(mvsd_read(MVSD_FIFO), p++); | 391 | put_unaligned(mvsd_read(MVSD_FIFO), p++); |
| 425 | put_unaligned(mvsd_read(MVSD_FIFO), p++); | 392 | put_unaligned(mvsd_read(MVSD_FIFO), p++); |
| 426 | s -= 4; | 393 | s -= 4; |
| 427 | sgm->consumed += 4; | ||
| 428 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 394 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 429 | } | 395 | } |
| 430 | if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) { | 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 | val[0] = mvsd_read(MVSD_FIFO); | 398 | val[0] = mvsd_read(MVSD_FIFO); |
| 433 | val[1] = mvsd_read(MVSD_FIFO); | 399 | val[1] = mvsd_read(MVSD_FIFO); |
| 434 | memcpy(p, ((void *)&val) + 4 - s, s); | 400 | memcpy(p, ((void *)&val) + 4 - s, s); |
| 435 | sgm->consumed += s; | ||
| 436 | s = 0; | 401 | s = 0; |
| 437 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 402 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 438 | } | 403 | } |
| 439 | /* PIO transfer done */ | 404 | if (s == 0) { |
| 440 | host->pio_size -= sgm->consumed; | ||
| 441 | if (host->pio_size == 0) { | ||
| 442 | host->intr_en &= | 405 | host->intr_en &= |
| 443 | ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W); | 406 | ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W); |
| 444 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); | 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 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", | 414 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", |
| 452 | s, intr_status, mvsd_read(MVSD_HW_STATE)); | 415 | s, intr_status, mvsd_read(MVSD_HW_STATE)); |
| 416 | host->pio_ptr = p; | ||
| 417 | host->pio_size = s; | ||
| 453 | irq_handled = 1; | 418 | irq_handled = 1; |
| 454 | } else if (host->use_pio && | 419 | } else if (host->pio_size && |
| 455 | (intr_status & host->intr_en & | 420 | (intr_status & host->intr_en & |
| 456 | (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) { | 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 | * The TX_FIFO_8W bit is unreliable. When set, bursting | 425 | * The TX_FIFO_8W bit is unreliable. When set, bursting |
| 459 | * 16 halfwords all at once in the FIFO drops data. Actually | 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 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); | 431 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); |
| 465 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); | 432 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); |
| 466 | s -= 4; | 433 | s -= 4; |
| 467 | sgm->consumed += 4; | ||
| 468 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 434 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 469 | } | 435 | } |
| 470 | if (s < 4) { | 436 | if (s < 4) { |
| @@ -473,13 +439,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 2 unmodified lines | |||
| 473 | memcpy(((void *)&val) + 4 - s, p, s); | 439 | memcpy(((void *)&val) + 4 - s, p, s); |
| 474 | mvsd_write(MVSD_FIFO, val[0]); | 440 | mvsd_write(MVSD_FIFO, val[0]); |
| 475 | mvsd_write(MVSD_FIFO, val[1]); | 441 | mvsd_write(MVSD_FIFO, val[1]); |
| 476 | sgm->consumed += s; | ||
| 477 | s = 0; | 442 | s = 0; |
| 478 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 443 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 479 | } | 444 | } |
| 480 | /* PIO transfer done */ | 445 | if (s == 0) { |
| 481 | host->pio_size -= sgm->consumed; | ||
| 482 | if (host->pio_size == 0) { | ||
| 483 | host->intr_en &= | 446 | host->intr_en &= |
| 484 | ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W); | 447 | ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W); |
| 485 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); | 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 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", | 451 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", |
| 489 | s, intr_status, mvsd_read(MVSD_HW_STATE)); | 452 | s, intr_status, mvsd_read(MVSD_HW_STATE)); |
| 453 | host->pio_ptr = p; | ||
| 454 | host->pio_size = s; | ||
| 490 | irq_handled = 1; | 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 | sdhci_reset(host, mask); | 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 | if (priv->flags & FLAG_IO_FIXED_1V8) { | 863 | if (priv->flags & FLAG_IO_FIXED_1V8) { |
| 856 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 864 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| 857 | if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) { | 865 | if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #include <linux/phylink.h> | 27 | #include <linux/phylink.h> |
| 28 | #include <linux/etherdevice.h> | 28 | #include <linux/etherdevice.h> |
| 29 | #include <linux/if_bridge.h> | 29 | #include <linux/if_bridge.h> |
| 30 | #include <linux/if_vlan.h> | ||
| 30 | #include <net/dsa.h> | 31 | #include <net/dsa.h> |
| 31 | 32 | ||
| 32 | #include "b53_regs.h" | 33 | #include "b53_regs.h" |
| @@ -224,6 +225,9 @@ static const struct b53_mib_desc b53_mibs_58xx[] = { · 191 unmodified lines | |||
| 224 | 225 | ||
| 225 | #define B53_MIBS_58XX_SIZE ARRAY_SIZE(b53_mibs_58xx) | 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 | static int b53_do_vlan_op(struct b53_device *dev, u8 op) | 231 | static int b53_do_vlan_op(struct b53_device *dev, u8 op) |
| 228 | { | 232 | { |
| 229 | unsigned int i; | 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 | bool allow_10_100; | 2258 | bool allow_10_100; |
| 2255 | 2259 | ||
| 2256 | if (is5325(dev) || is5365(dev)) | 2260 | if (is5325(dev) || is5365(dev)) |
| 2257 | return -EOPNOTSUPP; | 2261 | return 0; |
| 2258 | 2262 | ||
| 2259 | if (!dsa_is_cpu_port(ds, port)) | 2263 | if (!dsa_is_cpu_port(ds, port)) |
| 2260 | return 0; | 2264 | return 0; |
| 2261 | 2265 | ||
| 2262 | enable_jumbo = (mtu >= JMS_MIN_SIZE); | 2266 | enable_jumbo = (mtu > ETH_DATA_LEN); |
| 2263 | allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); | 2267 | allow_10_100 = !is63xx(dev); |
| 2264 | 2268 | ||
| 2265 | return b53_set_jumbo(dev, enable_jumbo, allow_10_100); | 2269 | return b53_set_jumbo(dev, enable_jumbo, allow_10_100); |
| 2266 | } | 2270 | } |
| 2267 | 2271 | ||
| 2268 | static int b53_get_max_mtu(struct dsa_switch *ds, int port) | 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 | static const struct phylink_mac_ops b53_phylink_mac_ops = { | 2282 | static const struct phylink_mac_ops b53_phylink_mac_ops = { |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
| 7 | #include <linux/gpio/consumer.h> | 7 | #include <linux/gpio/consumer.h> |
| 8 | #include <linux/regmap.h> | 8 | #include <linux/regmap.h> |
| 9 | #include <linux/iopoll.h> | ||
| 9 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
| 10 | #include <linux/mii.h> | 11 | #include <linux/mii.h> |
| 11 | #include <linux/of.h> | 12 | #include <linux/of.h> |
| @@ -839,6 +840,8 @@ static void lan9303_handle_reset(struct lan9303 *chip) · 827 unmodified lines | |||
| 839 | if (!chip->reset_gpio) | 840 | if (!chip->reset_gpio) |
| 840 | return; | 841 | return; |
| 841 | 842 | ||
| 843 | gpiod_set_value_cansleep(chip->reset_gpio, 1); | ||
| 844 | |||
| 842 | if (chip->reset_duration != 0) | 845 | if (chip->reset_duration != 0) |
| 843 | msleep(chip->reset_duration); | 846 | msleep(chip->reset_duration); |
| 844 | 847 | ||
| @@ -864,8 +867,34 @@ static int lan9303_disable_processing(struct lan9303 *chip) · 19 unmodified lines | |||
| 864 | static int lan9303_check_device(struct lan9303 *chip) | 867 | static int lan9303_check_device(struct lan9303 *chip) |
| 865 | { | 868 | { |
| 866 | int ret; | 869 | int ret; |
| 870 | int err; | ||
| 867 | u32 reg; | 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 | ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, ®); | 898 | ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, ®); |
| 870 | if (ret) { | 899 | if (ret) { |
| 871 | dev_err(chip->dev, "failed to read chip revision register: %d\n", | 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 | return MICREL_KSZ8_P1_ERRATA; | 2733 | return MICREL_KSZ8_P1_ERRATA; |
| 2734 | break; | 2734 | break; |
| 2735 | case KSZ8567_CHIP_ID: | 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 | case KSZ9477_CHIP_ID: | 2741 | case KSZ9477_CHIP_ID: |
| 2742 | /* KSZ9477S Errata DS80000754A Module 4 */ | ||
| 2737 | case KSZ9567_CHIP_ID: | 2743 | case KSZ9567_CHIP_ID: |
| 2744 | /* KSZ9567S Errata DS80000756A Module 4 */ | ||
| 2738 | case KSZ9896_CHIP_ID: | 2745 | case KSZ9896_CHIP_ID: |
| 2746 | /* KSZ9896C Errata DS80000757A Module 3 */ | ||
| 2739 | case KSZ9897_CHIP_ID: | 2747 | case KSZ9897_CHIP_ID: |
| 2740 | /* KSZ9477 Errata DS80000754C | 2748 | /* KSZ9897R Errata DS80000758C Module 4 */ |
| 2741 | * | 2749 | /* Energy Efficient Ethernet (EEE) feature select must be manually disabled |
| 2742 | * Module 4: Energy Efficient Ethernet (EEE) feature select must | ||
| 2743 | * be manually disabled | ||
| 2744 | * The EEE feature is enabled by default, but it is not fully | 2750 | * The EEE feature is enabled by default, but it is not fully |
| 2745 | * operational. It must be manually disabled through register | 2751 | * operational. It must be manually disabled through register |
| 2746 | * controls. If not disabled, the PHY ports can auto-negotiate | 2752 | * controls. If not disabled, the PHY ports can auto-negotiate |
| 2747 | * to enable EEE, and this feature can cause link drops when | 2753 | * to enable EEE, and this feature can cause link drops when |
| 2748 | * linked to another device supporting EEE. | 2754 | * linked to another device supporting EEE. |
| 2749 | * | 2755 | * |
| 2750 | * The same item appears in the errata for the KSZ9567, KSZ9896, | 2756 | * The same item appears in the errata for all switches above. |
| 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 | */ | 2757 | */ |
| 2757 | return MICREL_NO_EEE; | 2758 | return MICREL_NO_EEE; |
| 2758 | } | 2759 | } |
| @@ -6347,7 +6347,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { · 6346 unmodified lines | |||
| 6347 | .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), | 6347 | .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), |
| 6348 | .num_internal_phys = 5, | 6348 | .num_internal_phys = 5, |
| 6349 | .internal_phys_offset = 3, | 6349 | .internal_phys_offset = 3, |
| 6350 | .max_vid = 4095, | 6350 | .max_vid = 8191, |
| 6351 | .max_sid = 63, | 6351 | .max_sid = 63, |
| 6352 | .port_base_addr = 0x0, | 6352 | .port_base_addr = 0x0, |
| 6353 | .phy_base_addr = 0x0, | 6353 | .phy_base_addr = 0x0, |
| @@ -206,6 +206,7 @@ struct mv88e6xxx_gpio_ops; · 205 unmodified lines | |||
| 206 | struct mv88e6xxx_avb_ops; | 206 | struct mv88e6xxx_avb_ops; |
| 207 | struct mv88e6xxx_ptp_ops; | 207 | struct mv88e6xxx_ptp_ops; |
| 208 | struct mv88e6xxx_pcs_ops; | 208 | struct mv88e6xxx_pcs_ops; |
| 209 | struct mv88e6xxx_cc_coeffs; | ||
| 209 | 210 | ||
| 210 | struct mv88e6xxx_irq { | 211 | struct mv88e6xxx_irq { |
| 211 | u16 masked; | 212 | u16 masked; |
| @@ -408,6 +409,7 @@ struct mv88e6xxx_chip { · 196 unmodified lines | |||
| 408 | struct cyclecounter tstamp_cc; | 409 | struct cyclecounter tstamp_cc; |
| 409 | struct timecounter tstamp_tc; | 410 | struct timecounter tstamp_tc; |
| 410 | struct delayed_work overflow_work; | 411 | struct delayed_work overflow_work; |
| 412 | const struct mv88e6xxx_cc_coeffs *cc_coeffs; | ||
| 411 | 413 | ||
| 412 | struct ptp_clock *ptp_clock; | 414 | struct ptp_clock *ptp_clock; |
| 413 | struct ptp_clock_info ptp_clock_info; | 415 | struct ptp_clock_info ptp_clock_info; |
| @@ -731,10 +733,6 @@ struct mv88e6xxx_ptp_ops { · 317 unmodified lines | |||
| 731 | int arr1_sts_reg; | 733 | int arr1_sts_reg; |
| 732 | int dep_sts_reg; | 734 | int dep_sts_reg; |
| 733 | u32 rx_filters; | 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 | struct mv88e6xxx_pcs_ops { | 738 | struct mv88e6xxx_pcs_ops { |
| @@ -1713,6 +1713,7 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port, · 1712 unmodified lines | |||
| 1713 | ptr = shift / 8; | 1713 | ptr = shift / 8; |
| 1714 | shift %= 8; | 1714 | shift %= 8; |
| 1715 | mask >>= ptr * 8; | 1715 | mask >>= ptr * 8; |
| 1716 | ptr <<= 8; | ||
| 1716 | 1717 | ||
| 1717 | err = mv88e6393x_port_policy_read(chip, port, ptr, ®); | 1718 | err = mv88e6393x_port_policy_read(chip, port, ptr, ®); |
| 1718 | if (err) | 1719 | if (err) |
| @@ -18,6 +18,13 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define MV88E6XXX_MAX_ADJ_PPB 1000000 | 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 | /* Family MV88E6250: | 28 | /* Family MV88E6250: |
| 22 | * Raw timestamps are in units of 10-ns clock periods. | 29 | * Raw timestamps are in units of 10-ns clock periods. |
| 23 | * | 30 | * |
| @@ -25,22 +32,43 @@ · 1 unmodified line | |||
| 25 | * simplifies to | 32 | * simplifies to |
| 26 | * clkadj = scaled_ppm * 2^7 / 5^5 | 33 | * clkadj = scaled_ppm * 2^7 / 5^5 |
| 27 | */ | 34 | */ |
| 28 | #define MV88E6250_CC_SHIFT 28 | 35 | #define MV88E6XXX_CC_10NS_SHIFT 28 |
| 29 | #define MV88E6250_CC_MULT (10 << MV88E6250_CC_SHIFT) | 36 | static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = { |
| 30 | #define MV88E6250_CC_MULT_NUM (1 << 7) | 37 | .cc_shift = MV88E6XXX_CC_10NS_SHIFT, |
| 31 | #define MV88E6250_CC_MULT_DEM 3125ULL | 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 | * Raw timestamps are in units of 8-ns clock periods. | 44 | * Raw timestamps are in units of 8-ns clock periods. |
| 35 | * | 45 | * |
| 36 | * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16) | 46 | * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16) |
| 37 | * simplifies to | 47 | * simplifies to |
| 38 | * clkadj = scaled_ppm * 2^9 / 5^6 | 48 | * clkadj = scaled_ppm * 2^9 / 5^6 |
| 39 | */ | 49 | */ |
| 40 | #define MV88E6XXX_CC_SHIFT 28 | 50 | #define MV88E6XXX_CC_8NS_SHIFT 28 |
| 41 | #define MV88E6XXX_CC_MULT (8 << MV88E6XXX_CC_SHIFT) | 51 | static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = { |
| 42 | #define MV88E6XXX_CC_MULT_NUM (1 << 9) | 52 | .cc_shift = MV88E6XXX_CC_8NS_SHIFT, |
| 43 | #define MV88E6XXX_CC_MULT_DEM 15625ULL | 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 | #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100) | 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 | return chip->info->ops->gpio_ops->set_pctl(chip, pin, func); | 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 | static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc) | 141 | static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc) |
| 87 | { | 142 | { |
| 88 | struct mv88e6xxx_chip *chip = cc_to_chip(cc); | 143 | struct mv88e6xxx_chip *chip = cc_to_chip(cc); |
| @@ -204,7 +259,6 @@ out: · 115 unmodified lines | |||
| 204 | static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) | 259 | static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) |
| 205 | { | 260 | { |
| 206 | struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); | 261 | struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); |
| 207 | const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; | ||
| 208 | int neg_adj = 0; | 262 | int neg_adj = 0; |
| 209 | u32 diff, mult; | 263 | u32 diff, mult; |
| 210 | u64 adj; | 264 | u64 adj; |
| @@ -214,10 +268,10 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) · 3 unmodified lines | |||
| 214 | scaled_ppm = -scaled_ppm; | 268 | scaled_ppm = -scaled_ppm; |
| 215 | } | 269 | } |
| 216 | 270 | ||
| 217 | mult = ptp_ops->cc_mult; | 271 | mult = chip->cc_coeffs->cc_mult; |
| 218 | adj = ptp_ops->cc_mult_num; | 272 | adj = chip->cc_coeffs->cc_mult_num; |
| 219 | adj *= scaled_ppm; | 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 | mv88e6xxx_reg_lock(chip); | 276 | mv88e6xxx_reg_lock(chip); |
| 223 | 277 | ||
| @@ -364,10 +418,6 @@ const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = { · 140 unmodified lines | |||
| 364 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | 418 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 365 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | 419 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 366 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), | 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 | const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = { | 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 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | 441 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 392 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | 442 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 393 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), | 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 | const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { | 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 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | 464 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 419 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | 465 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 420 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), | 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 | const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = { | 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 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | 488 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 447 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | 489 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 448 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), | 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 | static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) | 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 | return 0; | 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 | * seconds; this task forces periodic reads so that we don't miss any. | 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 | static void mv88e6xxx_ptp_overflow_check(struct work_struct *work) | 507 | static void mv88e6xxx_ptp_overflow_check(struct work_struct *work) |
| 470 | { | 508 | { |
| 471 | struct delayed_work *dw = to_delayed_work(work); | 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 | int i; | 522 | int i; |
| 485 | 523 | ||
| 486 | /* Set up the cycle counter */ | 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 | memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc)); | 529 | memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc)); |
| 488 | chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read; | 530 | chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read; |
| 489 | chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32); | 531 | chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32); |
| 490 | chip->tstamp_cc.mult = ptp_ops->cc_mult; | 532 | chip->tstamp_cc.mult = chip->cc_coeffs->cc_mult; |
| 491 | chip->tstamp_cc.shift = ptp_ops->cc_shift; | 533 | chip->tstamp_cc.shift = chip->cc_coeffs->cc_shift; |
| 492 | 534 | ||
| 493 | timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, | 535 | timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, |
| 494 | ktime_to_ns(ktime_get_real())); | 536 | ktime_to_ns(ktime_get_real())); |
| @@ -3158,7 +3158,6 @@ static int sja1105_setup(struct dsa_switch *ds) · 3157 unmodified lines | |||
| 3158 | * TPID is ETH_P_SJA1105, and the VLAN ID is the port pvid. | 3158 | * TPID is ETH_P_SJA1105, and the VLAN ID is the port pvid. |
| 3159 | */ | 3159 | */ |
| 3160 | ds->vlan_filtering_is_global = true; | 3160 | ds->vlan_filtering_is_global = true; |
| 3161 | ds->untag_bridge_pvid = true; | ||
| 3162 | ds->fdb_isolation = true; | 3161 | ds->fdb_isolation = true; |
| 3163 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; | 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 | dev_info(vsc->dev, "set up the switch\n"); | 852 | dev_info(vsc->dev, "set up the switch\n"); |
| 853 | 853 | ||
| 854 | ds->untag_bridge_pvid = true; | ||
| 855 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; | 854 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; |
| 856 | ds->fdb_isolation = true; | 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 | * from the ADIN1110 frame header. | 318 | * from the ADIN1110 frame header. |
| 319 | */ | 319 | */ |
| 320 | if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN) | 320 | if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN) |
| 321 | return ret; | 321 | return -EINVAL; |
| 322 | 322 | ||
| 323 | round_len = adin1110_round_len(frame_size); | 323 | round_len = adin1110_round_len(frame_size); |
| 324 | if (round_len < 0) | 324 | if (round_len < 0) |
| 325 | return ret; | 325 | return -EINVAL; |
| 326 | 326 | ||
| 327 | frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN; | 327 | frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN; |
| 328 | memset(priv->data, 0, ADIN1110_RD_HEADER_LEN); | 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 | if (unlikely(skb->len > MAX_FRAME_SIZE)) { | 485 | if (unlikely(skb->len > MAX_FRAME_SIZE)) { |
| 486 | dev->stats.tx_errors++; | 486 | dev->stats.tx_errors++; |
| 487 | goto out; | 487 | goto len_error; |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | /* Save skb pointer. */ | 490 | /* Save skb pointer. */ |
| @@ -575,6 +575,7 @@ frag_map_error: · 84 unmodified lines | |||
| 575 | map_error: | 575 | map_error: |
| 576 | if (net_ratelimit()) | 576 | if (net_ratelimit()) |
| 577 | dev_warn(greth->dev, "Could not create TX DMA mapping\n"); | 577 | dev_warn(greth->dev, "Could not create TX DMA mapping\n"); |
| 578 | len_error: | ||
| 578 | dev_kfree_skb(skb); | 579 | dev_kfree_skb(skb); |
| 579 | out: | 580 | out: |
| 580 | return err; | 581 | return err; |
| @@ -105,10 +105,6 @@ static struct net_device * __init mvme147lance_probe(void) · 104 unmodified lines | |||
| 105 | macaddr[3] = address&0xff; | 105 | macaddr[3] = address&0xff; |
| 106 | eth_hw_addr_set(dev, macaddr); | 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 | lp = netdev_priv(dev); | 108 | lp = netdev_priv(dev); |
| 113 | lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */ | 109 | lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */ |
| 114 | if (!lp->ram) { | 110 | if (!lp->ram) { |
| @@ -138,6 +134,9 @@ static struct net_device * __init mvme147lance_probe(void) · 23 unmodified lines | |||
| 138 | return ERR_PTR(err); | 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 | return dev; | 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 | /* Rewind so we do not have a hole */ | 323 | /* Rewind so we do not have a hole */ |
| 324 | spb_index = intf->tx_spb_index; | 324 | spb_index = intf->tx_spb_index; |
| 325 | dev_kfree_skb(skb); | ||
| 325 | return NETDEV_TX_OK; | 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 | netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n", | 1359 | netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n", |
| 1360 | skb->data, skb_len); | 1360 | skb->data, skb_len); |
| 1361 | ret = NETDEV_TX_OK; | 1361 | ret = NETDEV_TX_OK; |
| 1362 | dev_kfree_skb_any(skb); | ||
| 1362 | goto out; | 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 | if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { | 2255 | if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { |
| 2256 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | 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 | ns = timecounter_cyc2time(&ptp->tc, ts); | 2260 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 2260 | spin_unlock_bh(&ptp->ptp_lock); | 2261 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 2261 | memset(skb_hwtstamps(skb), 0, | 2262 | memset(skb_hwtstamps(skb), 0, |
| 2262 | sizeof(*skb_hwtstamps(skb))); | 2263 | sizeof(*skb_hwtstamps(skb))); |
| 2263 | skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); | 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 | case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE: | 2758 | case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE: |
| 2758 | if (BNXT_PTP_USE_RTC(bp)) { | 2759 | if (BNXT_PTP_USE_RTC(bp)) { |
| 2759 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | 2760 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 2761 | unsigned long flags; | ||
| 2760 | u64 ns; | 2762 | u64 ns; |
| 2761 | 2763 | ||
| 2762 | if (!ptp) | 2764 | if (!ptp) |
| 2763 | goto async_event_process_exit; | 2765 | goto async_event_process_exit; |
| 2764 | 2766 | ||
| 2765 | spin_lock_bh(&ptp->ptp_lock); | 2767 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 2766 | bnxt_ptp_update_current_time(bp); | 2768 | bnxt_ptp_update_current_time(bp); |
| 2767 | ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) << | 2769 | ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) << |
| 2768 | BNXT_PHC_BITS) | ptp->current_time); | 2770 | BNXT_PHC_BITS) | ptp->current_time); |
| 2769 | bnxt_ptp_rtc_timecounter_init(ptp, ns); | 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 | break; | 2774 | break; |
| 2773 | } | 2775 | } |
| @@ -13494,9 +13496,11 @@ static void bnxt_force_fw_reset(struct bnxt *bp) · 10720 unmodified lines | |||
| 13494 | return; | 13496 | return; |
| 13495 | 13497 | ||
| 13496 | if (ptp) { | 13498 | if (ptp) { |
| 13497 | spin_lock_bh(&ptp->ptp_lock); | 13499 | unsigned long flags; |
| 13500 | |||
| 13501 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ||
| 13498 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 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 | } else { | 13504 | } else { |
| 13501 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 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 | int n = 0, tmo; | 13565 | int n = 0, tmo; |
| 13562 | 13566 | ||
| 13563 | if (ptp) { | 13567 | if (ptp) { |
| 13564 | spin_lock_bh(&ptp->ptp_lock); | 13568 | unsigned long flags; |
| 13569 | |||
| 13570 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ||
| 13565 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 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 | } else { | 13573 | } else { |
| 13568 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 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 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, | 62 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 63 | ptp_info); | 63 | ptp_info); |
| 64 | u64 ns = timespec64_to_ns(ts); | 64 | u64 ns = timespec64_to_ns(ts); |
| 65 | unsigned long flags; | ||
| 65 | 66 | ||
| 66 | if (BNXT_PTP_USE_RTC(ptp->bp)) | 67 | if (BNXT_PTP_USE_RTC(ptp->bp)) |
| 67 | return bnxt_ptp_cfg_settime(ptp->bp, ns); | 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 | timecounter_init(&ptp->tc, &ptp->cc, ns); | 71 | timecounter_init(&ptp->tc, &ptp->cc, ns); |
| 71 | spin_unlock_bh(&ptp->ptp_lock); | 72 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 72 | return 0; | 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 | static void bnxt_ptp_get_current_time(struct bnxt *bp) | 101 | static void bnxt_ptp_get_current_time(struct bnxt *bp) |
| 101 | { | 102 | { |
| 102 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | 103 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 104 | unsigned long flags; | ||
| 103 | 105 | ||
| 104 | if (!ptp) | 106 | if (!ptp) |
| 105 | return; | 107 | return; |
| 106 | spin_lock_bh(&ptp->ptp_lock); | 108 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 107 | WRITE_ONCE(ptp->old_time, ptp->current_time); | 109 | WRITE_ONCE(ptp->old_time, ptp->current_time); |
| 108 | bnxt_refclk_read(bp, NULL, &ptp->current_time); | 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 | static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts, | 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 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, | 152 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 151 | ptp_info); | 153 | ptp_info); |
| 154 | unsigned long flags; | ||
| 152 | u64 ns, cycles; | 155 | u64 ns, cycles; |
| 153 | int rc; | 156 | int rc; |
| 154 | 157 | ||
| 155 | spin_lock_bh(&ptp->ptp_lock); | 158 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 156 | rc = bnxt_refclk_read(ptp->bp, sts, &cycles); | 159 | rc = bnxt_refclk_read(ptp->bp, sts, &cycles); |
| 157 | if (rc) { | 160 | if (rc) { |
| 158 | spin_unlock_bh(&ptp->ptp_lock); | 161 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 159 | return rc; | 162 | return rc; |
| 160 | } | 163 | } |
| 161 | ns = timecounter_cyc2time(&ptp->tc, cycles); | 164 | ns = timecounter_cyc2time(&ptp->tc, cycles); |
| 162 | spin_unlock_bh(&ptp->ptp_lock); | 165 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 163 | *ts = ns_to_timespec64(ns); | 166 | *ts = ns_to_timespec64(ns); |
| 164 | 167 | ||
| 165 | return 0; | 168 | return 0; |
| @@ -177,6 +180,7 @@ void bnxt_ptp_update_current_time(struct bnxt *bp) · 11 unmodified lines | |||
| 177 | static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) | 180 | static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) |
| 178 | { | 181 | { |
| 179 | struct hwrm_port_mac_cfg_input *req; | 182 | struct hwrm_port_mac_cfg_input *req; |
| 183 | unsigned long flags; | ||
| 180 | int rc; | 184 | int rc; |
| 181 | 185 | ||
| 182 | rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG); | 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 | if (rc) { | 194 | if (rc) { |
| 191 | netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc); | 195 | netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc); |
| 192 | } else { | 196 | } else { |
| 193 | spin_lock_bh(&ptp->ptp_lock); | 197 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 194 | bnxt_ptp_update_current_time(ptp->bp); | 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 | return rc; | 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 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, | 207 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 204 | ptp_info); | 208 | ptp_info); |
| 209 | unsigned long flags; | ||
| 205 | 210 | ||
| 206 | if (BNXT_PTP_USE_RTC(ptp->bp)) | 211 | if (BNXT_PTP_USE_RTC(ptp->bp)) |
| 207 | return bnxt_ptp_adjphc(ptp, delta); | 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 | timecounter_adjtime(&ptp->tc, delta); | 215 | timecounter_adjtime(&ptp->tc, delta); |
| 211 | spin_unlock_bh(&ptp->ptp_lock); | 216 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 212 | return 0; | 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 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, | 241 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 237 | ptp_info); | 242 | ptp_info); |
| 238 | struct bnxt *bp = ptp->bp; | 243 | struct bnxt *bp = ptp->bp; |
| 244 | unsigned long flags; | ||
| 239 | 245 | ||
| 240 | if (!BNXT_MH(bp)) | 246 | if (!BNXT_MH(bp)) |
| 241 | return bnxt_ptp_adjfine_rtc(bp, scaled_ppm); | 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 | timecounter_read(&ptp->tc); | 250 | timecounter_read(&ptp->tc); |
| 245 | ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm); | 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 | return 0; | 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 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | 258 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 253 | struct ptp_clock_event event; | 259 | struct ptp_clock_event event; |
| 260 | unsigned long flags; | ||
| 254 | u64 ns, pps_ts; | 261 | u64 ns, pps_ts; |
| 255 | 262 | ||
| 256 | pps_ts = EVENT_PPS_TS(data2, data1); | 263 | pps_ts = EVENT_PPS_TS(data2, data1); |
| 257 | spin_lock_bh(&ptp->ptp_lock); | 264 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 258 | ns = timecounter_cyc2time(&ptp->tc, pps_ts); | 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 | switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) { | 268 | switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) { |
| 262 | case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL: | 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 | u64 cycles_now; | 401 | u64 cycles_now; |
| 395 | u64 nsec_now, nsec_delta; | 402 | u64 nsec_now, nsec_delta; |
| 403 | unsigned long flags; | ||
| 396 | int rc; | 404 | int rc; |
| 397 | 405 | ||
| 398 | spin_lock_bh(&ptp->ptp_lock); | 406 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 399 | rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now); | 407 | rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now); |
| 400 | if (rc) { | 408 | if (rc) { |
| 401 | spin_unlock_bh(&ptp->ptp_lock); | 409 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 402 | return rc; | 410 | return rc; |
| 403 | } | 411 | } |
| 404 | nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now); | 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 | nsec_delta = target_ns - nsec_now; | 415 | nsec_delta = target_ns - nsec_now; |
| 408 | *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult); | 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 | struct skb_shared_hwtstamps timestamp; | 697 | struct skb_shared_hwtstamps timestamp; |
| 690 | struct bnxt_ptp_tx_req *txts_req; | 698 | struct bnxt_ptp_tx_req *txts_req; |
| 691 | unsigned long now = jiffies; | 699 | unsigned long now = jiffies; |
| 700 | unsigned long flags; | ||
| 692 | u64 ts = 0, ns = 0; | 701 | u64 ts = 0, ns = 0; |
| 693 | u32 tmo = 0; | 702 | u32 tmo = 0; |
| 694 | int rc; | 703 | int rc; |
| @@ -702,9 +711,9 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) · 7 unmodified lines | |||
| 702 | tmo, slot); | 711 | tmo, slot); |
| 703 | if (!rc) { | 712 | if (!rc) { |
| 704 | memset(×tamp, 0, sizeof(timestamp)); | 713 | memset(×tamp, 0, sizeof(timestamp)); |
| 705 | spin_lock_bh(&ptp->ptp_lock); | 714 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 706 | ns = timecounter_cyc2time(&ptp->tc, ts); | 715 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 707 | spin_unlock_bh(&ptp->ptp_lock); | 716 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 708 | timestamp.hwtstamp = ns_to_ktime(ns); | 717 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 709 | skb_tstamp_tx(txts_req->tx_skb, ×tamp); | 718 | skb_tstamp_tx(txts_req->tx_skb, ×tamp); |
| 710 | ptp->stats.ts_pkts++; | 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 | unsigned long now = jiffies; | 739 | unsigned long now = jiffies; |
| 731 | struct bnxt *bp = ptp->bp; | 740 | struct bnxt *bp = ptp->bp; |
| 732 | u16 cons = ptp->txts_cons; | 741 | u16 cons = ptp->txts_cons; |
| 742 | unsigned long flags; | ||
| 733 | u32 num_requests; | 743 | u32 num_requests; |
| 734 | int rc = 0; | 744 | int rc = 0; |
| 735 | 745 | ||
| @@ -757,9 +767,9 @@ next_slot: · 21 unmodified lines | |||
| 757 | bnxt_ptp_get_current_time(bp); | 767 | bnxt_ptp_get_current_time(bp); |
| 758 | ptp->next_period = now + HZ; | 768 | ptp->next_period = now + HZ; |
| 759 | if (time_after_eq(now, ptp->next_overflow_check)) { | 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 | timecounter_read(&ptp->tc); | 771 | timecounter_read(&ptp->tc); |
| 762 | spin_unlock_bh(&ptp->ptp_lock); | 772 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 763 | ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; | 773 | ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; |
| 764 | } | 774 | } |
| 765 | if (rc == -EAGAIN) | 775 | if (rc == -EAGAIN) |
| @@ -819,6 +829,7 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, · 53 unmodified lines | |||
| 819 | u32 opaque = tscmp->tx_ts_cmp_opaque; | 829 | u32 opaque = tscmp->tx_ts_cmp_opaque; |
| 820 | struct bnxt_tx_ring_info *txr; | 830 | struct bnxt_tx_ring_info *txr; |
| 821 | struct bnxt_sw_tx_bd *tx_buf; | 831 | struct bnxt_sw_tx_bd *tx_buf; |
| 832 | unsigned long flags; | ||
| 822 | u64 ts, ns; | 833 | u64 ts, ns; |
| 823 | u16 cons; | 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 | le32_to_cpu(tscmp->tx_ts_cmp_flags_type), | 844 | le32_to_cpu(tscmp->tx_ts_cmp_flags_type), |
| 834 | le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); | 845 | le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); |
| 835 | } else { | 846 | } else { |
| 836 | spin_lock_bh(&ptp->ptp_lock); | 847 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 837 | ns = timecounter_cyc2time(&ptp->tc, ts); | 848 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 838 | spin_unlock_bh(&ptp->ptp_lock); | 849 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 839 | timestamp.hwtstamp = ns_to_ktime(ns); | 850 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 840 | skb_tstamp_tx(tx_buf->skb, ×tamp); | 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 | int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) | 986 | int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) |
| 976 | { | 987 | { |
| 977 | struct timespec64 tsp; | 988 | struct timespec64 tsp; |
| 989 | unsigned long flags; | ||
| 978 | u64 ns; | 990 | u64 ns; |
| 979 | int rc; | 991 | int rc; |
| 980 | 992 | ||
| @@ -993,9 +1005,9 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) · 12 unmodified lines | |||
| 993 | if (rc) | 1005 | if (rc) |
| 994 | return rc; | 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 | bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns); | 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 | return 0; | 1012 | return 0; |
| 1001 | } | 1013 | } |
| @@ -1063,10 +1075,12 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) · 61 unmodified lines | |||
| 1063 | atomic64_set(&ptp->stats.ts_err, 0); | 1075 | atomic64_set(&ptp->stats.ts_err, 0); |
| 1064 | 1076 | ||
| 1065 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { | 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 | bnxt_refclk_read(bp, NULL, &ptp->current_time); | 1081 | bnxt_refclk_read(bp, NULL, &ptp->current_time); |
| 1068 | WRITE_ONCE(ptp->old_time, ptp->current_time); | 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 | ptp_schedule_worker(ptp->ptp_clock, 0); | 1084 | ptp_schedule_worker(ptp->ptp_clock, 0); |
| 1071 | } | 1085 | } |
| 1072 | ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO; | 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 | #if BITS_PER_LONG == 32 | 148 | #if BITS_PER_LONG == 32 |
| 149 | #define BNXT_READ_TIME64(ptp, dst, src) \ | 149 | #define BNXT_READ_TIME64(ptp, dst, src) \ |
| 150 | do { \ | 150 | do { \ |
| 151 | spin_lock_bh(&(ptp)->ptp_lock); \ | 151 | unsigned long flags; \ |
| 152 | (dst) = (src); \ | 152 | \ |
| 153 | spin_unlock_bh(&(ptp)->ptp_lock); \ | 153 | spin_lock_irqsave(&(ptp)->ptp_lock, flags); \ |
| 154 | (dst) = (src); \ | ||
| 155 | spin_unlock_irqrestore(&(ptp)->ptp_lock, flags); \ | ||
| 154 | } while (0) | 156 | } while (0) |
| 155 | #else | 157 | #else |
| 156 | #define BNXT_READ_TIME64(ptp, dst, src) \ | 158 | #define BNXT_READ_TIME64(ptp, dst, src) \ |
| @@ -930,9 +930,6 @@ static int macb_mdiobus_register(struct macb *bp) · 929 unmodified lines | |||
| 930 | return ret; | 930 | return ret; |
| 931 | } | 931 | } |
| 932 | 932 | ||
| 933 | if (of_phy_is_fixed_link(np)) | ||
| 934 | return mdiobus_register(bp->mii_bus); | ||
| 935 | |||
| 936 | /* Only create the PHY from the device tree if at least one PHY is | 933 | /* Only create the PHY from the device tree if at least one PHY is |
| 937 | * described. Otherwise scan the entire MDIO bus. We do this to support | 934 | * described. Otherwise scan the entire MDIO bus. We do this to support |
| 938 | * old device tree that did not follow the best practices and did not | 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 | static int macb_mii_init(struct macb *bp) | 951 | static int macb_mii_init(struct macb *bp) |
| 955 | { | 952 | { |
| 953 | struct device_node *child, *np = bp->pdev->dev.of_node; | ||
| 956 | int err = -ENXIO; | 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 | /* Enable management port */ | 966 | /* Enable management port */ |
| 959 | macb_writel(bp, NCR, MACB_BIT(MPE)); | 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 | be_get_wrb_params_from_skb(adapter, skb, &wrb_params); | 1381 | be_get_wrb_params_from_skb(adapter, skb, &wrb_params); |
| 1382 | 1382 | ||
| 1383 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); | 1383 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); |
| 1384 | if (unlikely(!wrb_cnt)) { | 1384 | if (unlikely(!wrb_cnt)) |
| 1385 | dev_kfree_skb_any(skb); | 1385 | goto drop_skb; |
| 1386 | goto drop; | ||
| 1387 | } | ||
| 1388 | 1386 | ||
| 1389 | /* if os2bmc is enabled and if the pkt is destined to bmc, | 1387 | /* if os2bmc is enabled and if the pkt is destined to bmc, |
| 1390 | * enqueue the pkt a 2nd time with mgmt bit set. | 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 | BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); | 1391 | BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); |
| 1394 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); | 1392 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); |
| 1395 | if (unlikely(!wrb_cnt)) | 1393 | if (unlikely(!wrb_cnt)) |
| 1396 | goto drop; | 1394 | goto drop_skb; |
| 1397 | else | 1395 | else |
| 1398 | skb_get(skb); | 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 | be_xmit_flush(adapter, txo); | 1405 | be_xmit_flush(adapter, txo); |
| 1408 | 1406 | ||
| 1409 | return NETDEV_TX_OK; | 1407 | return NETDEV_TX_OK; |
| 1408 | drop_skb: | ||
| 1409 | dev_kfree_skb_any(skb); | ||
| 1410 | drop: | 1410 | drop: |
| 1411 | tx_stats(txo)->tx_drv_drops++; | 1411 | tx_stats(txo)->tx_drv_drops++; |
| 1412 | /* Flush the already enqueued tx requests */ | 1412 | /* Flush the already enqueued tx requests */ |
| @@ -1906,7 +1906,12 @@ static int ftgmac100_probe(struct platform_device *pdev) · 1905 unmodified lines | |||
| 1906 | goto err_phy_connect; | 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 | err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link, | 1915 | err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link, |
| 1911 | PHY_INTERFACE_MODE_MII); | 1916 | PHY_INTERFACE_MODE_MII); |
| 1912 | if (err) { | 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 | if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) && | 903 | if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) && |
| 904 | __netif_subqueue_stopped(ndev, tx_ring->index) && | 904 | __netif_subqueue_stopped(ndev, tx_ring->index) && |
| 905 | !test_bit(ENETC_TX_DOWN, &priv->flags) && | ||
| 905 | (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) { | 906 | (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) { |
| 906 | netif_wake_subqueue(ndev, tx_ring->index); | 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 | int xdp_tx_bd_cnt, i, k; | 1378 | int xdp_tx_bd_cnt, i, k; |
| 1378 | int xdp_tx_frm_cnt = 0; | 1379 | int xdp_tx_frm_cnt = 0; |
| 1379 | 1380 | ||
| 1381 | if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) | ||
| 1382 | return -ENETDOWN; | ||
| 1383 | |||
| 1380 | enetc_lock_mdio(); | 1384 | enetc_lock_mdio(); |
| 1381 | 1385 | ||
| 1382 | tx_ring = priv->xdp_tx_ring[smp_processor_id()]; | 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 | &rx_ring->rx_swbd[rx_ring_first]); | 1525 | &rx_ring->rx_swbd[rx_ring_first]); |
| 1522 | enetc_bdr_idx_inc(rx_ring, &rx_ring_first); | 1526 | enetc_bdr_idx_inc(rx_ring, &rx_ring_first); |
| 1523 | } | 1527 | } |
| 1524 | rx_ring->stats.xdp_drops++; | ||
| 1525 | } | 1528 | } |
| 1526 | 1529 | ||
| 1527 | static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, | 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 | fallthrough; | 1589 | fallthrough; |
| 1587 | case XDP_DROP: | 1590 | case XDP_DROP: |
| 1588 | enetc_xdp_drop(rx_ring, orig_i, i); | 1591 | enetc_xdp_drop(rx_ring, orig_i, i); |
| 1592 | rx_ring->stats.xdp_drops++; | ||
| 1589 | break; | 1593 | break; |
| 1590 | case XDP_PASS: | 1594 | case XDP_PASS: |
| 1591 | rxbd = orig_rxbd; | 1595 | rxbd = orig_rxbd; |
| @@ -1602,6 +1606,12 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 10 unmodified lines | |||
| 1602 | break; | 1606 | break; |
| 1603 | case XDP_TX: | 1607 | case XDP_TX: |
| 1604 | tx_ring = priv->xdp_tx_ring[rx_ring->index]; | 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 | xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr, | 1615 | xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr, |
| 1606 | rx_ring, | 1616 | rx_ring, |
| 1607 | orig_i, i); | 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 | enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); | 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 | struct enetc_hw *hw = &priv->si->hw; | 2238 | struct enetc_hw *hw = &priv->si->hw; |
| 2229 | int i; | 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 | for (i = 0; i < priv->num_rx_rings; i++) | 2241 | for (i = 0; i < priv->num_rx_rings; i++) |
| 2235 | enetc_enable_rxbdr(hw, priv->rx_ring[i]); | 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 | static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) | 2254 | static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) |
| 2239 | { | 2255 | { |
| 2240 | int idx = rx_ring->index; | 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 | enetc_txbdr_wr(hw, idx, ENETC_TBMR, 0); | 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 | struct enetc_hw *hw = &priv->si->hw; | 2272 | struct enetc_hw *hw = &priv->si->hw; |
| 2257 | int i; | 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 | for (i = 0; i < priv->num_rx_rings; i++) | 2275 | for (i = 0; i < priv->num_rx_rings; i++) |
| 2263 | enetc_disable_rxbdr(hw, priv->rx_ring[i]); | 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 | static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring) | 2288 | static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring) |
| 2267 | { | 2289 | { |
| 2268 | int delay = 8, timeout = 100; | 2290 | int delay = 8, timeout = 100; |
| @@ -2460,9 +2482,13 @@ void enetc_start(struct net_device *ndev) · 191 unmodified lines | |||
| 2460 | enable_irq(irq); | 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 | netif_tx_start_all_queues(ndev); | 2489 | netif_tx_start_all_queues(ndev); |
| 2490 | |||
| 2491 | clear_bit(ENETC_TX_DOWN, &priv->flags); | ||
| 2466 | } | 2492 | } |
| 2467 | EXPORT_SYMBOL_GPL(enetc_start); | 2493 | EXPORT_SYMBOL_GPL(enetc_start); |
| 2468 | 2494 | ||
| @@ -2520,9 +2546,15 @@ void enetc_stop(struct net_device *ndev) · 51 unmodified lines | |||
| 2520 | struct enetc_ndev_priv *priv = netdev_priv(ndev); | 2546 | struct enetc_ndev_priv *priv = netdev_priv(ndev); |
| 2521 | int i; | 2547 | int i; |
| 2522 | 2548 | ||
| 2549 | set_bit(ENETC_TX_DOWN, &priv->flags); | ||
| 2550 | |||
| 2523 | netif_tx_stop_all_queues(ndev); | 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 | for (i = 0; i < priv->bdr_int_num; i++) { | 2559 | for (i = 0; i < priv->bdr_int_num; i++) { |
| 2528 | int irq = pci_irq_vector(priv->si->pdev, | 2560 | int irq = pci_irq_vector(priv->si->pdev, |
| @@ -2533,8 +2565,6 @@ void enetc_stop(struct net_device *ndev) · 4 unmodified lines | |||
| 2533 | napi_disable(&priv->int_vector[i]->napi); | 2565 | napi_disable(&priv->int_vector[i]->napi); |
| 2534 | } | 2566 | } |
| 2535 | 2567 | ||
| 2536 | enetc_wait_bdrs(priv); | ||
| 2537 | |||
| 2538 | enetc_clear_interrupts(priv); | 2568 | enetc_clear_interrupts(priv); |
| 2539 | } | 2569 | } |
| 2540 | EXPORT_SYMBOL_GPL(enetc_stop); | 2570 | EXPORT_SYMBOL_GPL(enetc_stop); |
| @@ -325,6 +325,7 @@ enum enetc_active_offloads { · 324 unmodified lines | |||
| 325 | 325 | ||
| 326 | enum enetc_flags_bit { | 326 | enum enetc_flags_bit { |
| 327 | ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0, | 327 | ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0, |
| 328 | ENETC_TX_DOWN, | ||
| 328 | }; | 329 | }; |
| 329 | 330 | ||
| 330 | /* interrupt coalescing modes */ | 331 | /* interrupt coalescing modes */ |
| @@ -1077,7 +1077,8 @@ fec_restart(struct net_device *ndev) · 1076 unmodified lines | |||
| 1077 | u32 rcntl = OPT_FRAME_SIZE | 0x04; | 1077 | u32 rcntl = OPT_FRAME_SIZE | 0x04; |
| 1078 | u32 ecntl = FEC_ECR_ETHEREN; | 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 | /* Whack a reset. We should wait for this. | 1083 | /* Whack a reset. We should wait for this. |
| 1083 | * For i.MX6SX SOC, enet use AXI bus, we use disable MAC | 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 | netdev_err(ndev, "Graceful transmit stop did not complete!\n"); | 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 | /* Whack a reset. We should wait for this. | 1347 | /* Whack a reset. We should wait for this. |
| 1346 | * For i.MX6SX SOC, enet use AXI bus, we use disable MAC | 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 | err = -EINVAL; | 197 | err = -EINVAL; |
| 198 | goto _return_of_node_put; | 198 | goto _return_of_node_put; |
| 199 | } | 199 | } |
| 200 | mac_dev->fman_dev = &of_dev->dev; | ||
| 200 | 201 | ||
| 201 | /* Get the FMan cell-index */ | 202 | /* Get the FMan cell-index */ |
| 202 | err = of_property_read_u32(dev_node, "cell-index", &val); | 203 | err = of_property_read_u32(dev_node, "cell-index", &val); |
| 203 | if (err) { | 204 | if (err) { |
| 204 | dev_err(dev, "failed to read cell-index for %pOF\n", dev_node); | 205 | dev_err(dev, "failed to read cell-index for %pOF\n", dev_node); |
| 205 | err = -EINVAL; | 206 | err = -EINVAL; |
| 206 | goto _return_of_node_put; | 207 | goto _return_dev_put; |
| 207 | } | 208 | } |
| 208 | /* cell-index 0 => FMan id 1 */ | 209 | /* cell-index 0 => FMan id 1 */ |
| 209 | fman_id = (u8)(val + 1); | 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 | if (!priv->fman) { | 213 | if (!priv->fman) { |
| 213 | dev_err(dev, "fman_bind(%pOF) failed\n", dev_node); | 214 | dev_err(dev, "fman_bind(%pOF) failed\n", dev_node); |
| 214 | err = -ENODEV; | 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 | of_node_put(dev_node); | 224 | of_node_put(dev_node); |
| 225 | dev_node = NULL; | ||
| 219 | 226 | ||
| 220 | /* Get the address of the memory mapped registers */ | 227 | /* Get the address of the memory mapped registers */ |
| 221 | mac_dev->res = platform_get_mem_or_io(_of_dev, 0); | 228 | mac_dev->res = platform_get_mem_or_io(_of_dev, 0); |
| 222 | if (!mac_dev->res) { | 229 | if (!mac_dev->res) { |
| 223 | dev_err(dev, "could not get registers\n"); | 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 | err = devm_request_resource(dev, fman_get_mem_region(priv->fman), | 235 | err = devm_request_resource(dev, fman_get_mem_region(priv->fman), |
| 228 | mac_dev->res); | 236 | mac_dev->res); |
| 229 | if (err) { | 237 | if (err) { |
| 230 | dev_err_probe(dev, err, "could not request resource\n"); | 238 | dev_err_probe(dev, err, "could not request resource\n"); |
| 231 | return err; | 239 | goto _return_dev_put; |
| 232 | } | 240 | } |
| 233 | 241 | ||
| 234 | mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start, | 242 | mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start, |
| 235 | resource_size(mac_dev->res)); | 243 | resource_size(mac_dev->res)); |
| 236 | if (!mac_dev->vaddr) { | 244 | if (!mac_dev->vaddr) { |
| 237 | dev_err(dev, "devm_ioremap() failed\n"); | 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)) | 250 | if (!of_device_is_available(mac_node)) { |
| 242 | return -ENODEV; | 251 | err = -ENODEV; |
| 252 | goto _return_dev_put; | ||
| 253 | } | ||
| 243 | 254 | ||
| 244 | /* Get the cell-index */ | 255 | /* Get the cell-index */ |
| 245 | err = of_property_read_u32(mac_node, "cell-index", &val); | 256 | err = of_property_read_u32(mac_node, "cell-index", &val); |
| 246 | if (err) { | 257 | if (err) { |
| 247 | dev_err(dev, "failed to read cell-index for %pOF\n", mac_node); | 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 | priv->cell_index = (u8)val; | 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 | if (unlikely(nph < 0)) { | 271 | if (unlikely(nph < 0)) { |
| 260 | dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n", | 272 | dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n", |
| 261 | mac_node); | 273 | mac_node); |
| 262 | return nph; | 274 | err = nph; |
| 275 | goto _return_dev_put; | ||
| 263 | } | 276 | } |
| 264 | 277 | ||
| 265 | if (nph != ARRAY_SIZE(mac_dev->port)) { | 278 | if (nph != ARRAY_SIZE(mac_dev->port)) { |
| 266 | dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n", | 279 | dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n", |
| 267 | mac_node); | 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 | /* Find the port node */ | 287 | /* Find the port node */ |
| 273 | dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i); | 288 | dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i); |
| 274 | if (!dev_node) { | 289 | if (!dev_node) { |
| 275 | dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n", | 290 | dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n", |
| 276 | mac_node); | 291 | mac_node); |
| 277 | return -EINVAL; | 292 | err = -EINVAL; |
| 293 | goto _return_dev_arr_put; | ||
| 278 | } | 294 | } |
| 279 | 295 | ||
| 280 | of_dev = of_find_device_by_node(dev_node); | 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 | dev_err(dev, "of_find_device_by_node(%pOF) failed\n", | 298 | dev_err(dev, "of_find_device_by_node(%pOF) failed\n", |
| 283 | dev_node); | 299 | dev_node); |
| 284 | err = -EINVAL; | 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 | if (!mac_dev->port[i]) { | 306 | if (!mac_dev->port[i]) { |
| 290 | dev_err(dev, "dev_get_drvdata(%pOF) failed\n", | 307 | dev_err(dev, "dev_get_drvdata(%pOF) failed\n", |
| 291 | dev_node); | 308 | dev_node); |
| 292 | err = -EINVAL; | 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 | of_node_put(dev_node); | 317 | of_node_put(dev_node); |
| 318 | dev_node = NULL; | ||
| 296 | } | 319 | } |
| 297 | 320 | ||
| 298 | /* Get the PHY connection type */ | 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 | err = init(mac_dev, mac_node, ¶ms); | 336 | err = init(mac_dev, mac_node, ¶ms); |
| 314 | if (err < 0) | 337 | if (err < 0) |
| 315 | return err; | 338 | goto _return_dev_arr_put; |
| 316 | 339 | ||
| 317 | if (!is_zero_ether_addr(mac_dev->addr)) | 340 | if (!is_zero_ether_addr(mac_dev->addr)) |
| 318 | dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr); | 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 | return err; | 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 | _return_of_node_put: | 359 | _return_of_node_put: |
| 331 | of_node_put(dev_node); | 360 | of_node_put(dev_node); |
| 332 | return err; | 361 | return err; |
| @@ -335,6 +364,11 @@ _return_of_node_put: · 2 unmodified lines | |||
| 335 | static void mac_remove(struct platform_device *pdev) | 364 | static void mac_remove(struct platform_device *pdev) |
| 336 | { | 365 | { |
| 337 | struct mac_device *mac_dev = platform_get_drvdata(pdev); | 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 | platform_device_unregister(mac_dev->priv->eth_dev); | 373 | platform_device_unregister(mac_dev->priv->eth_dev); |
| 340 | } | 374 | } |
| @@ -19,12 +19,13 @@ · 18 unmodified lines | |||
| 19 | struct fman_mac; | 19 | struct fman_mac; |
| 20 | struct mac_priv_s; | 20 | struct mac_priv_s; |
| 21 | 21 | ||
| 22 | #define PORT_NUM 2 | ||
| 22 | struct mac_device { | 23 | struct mac_device { |
| 23 | void __iomem *vaddr; | 24 | void __iomem *vaddr; |
| 24 | struct device *dev; | 25 | struct device *dev; |
| 25 | struct resource *res; | 26 | struct resource *res; |
| 26 | u8 addr[ETH_ALEN]; | 27 | u8 addr[ETH_ALEN]; |
| 27 | struct fman_port *port[2]; | 28 | struct fman_port *port[PORT_NUM]; |
| 28 | struct phylink *phylink; | 29 | struct phylink *phylink; |
| 29 | struct phylink_config phylink_config; | 30 | struct phylink_config phylink_config; |
| 30 | phy_interface_t phy_if; | 31 | phy_interface_t phy_if; |
| @@ -52,6 +53,9 @@ struct mac_device { · 21 unmodified lines | |||
| 52 | 53 | ||
| 53 | struct fman_mac *fman_mac; | 54 | struct fman_mac *fman_mac; |
| 54 | struct mac_priv_s *priv; | 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 | static inline struct mac_device | 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 | if(skb->len > XMIT_BUFF_SIZE) | 1012 | if(skb->len > XMIT_BUFF_SIZE) |
| 1013 | { | 1013 | { |
| 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); | 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 | return NETDEV_TX_OK; | 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 | printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n", | 578 | printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n", |
| 579 | ofdev->dev.of_node); | 579 | ofdev->dev.of_node); |
| 580 | err = -ENODEV; | 580 | err = -ENODEV; |
| 581 | goto fail; | 581 | goto fail_unmap; |
| 582 | #endif | 582 | #endif |
| 583 | } | 583 | } |
| 584 | 584 | ||
| @@ -742,6 +742,8 @@ static void mal_remove(struct platform_device *ofdev) · 157 unmodified lines | |||
| 742 | 742 | ||
| 743 | free_netdev(mal->dummy_dev); | 743 | free_netdev(mal->dummy_dev); |
| 744 | 744 | ||
| 745 | dcr_unmap(mal->dcr_host, 0x100); | ||
| 746 | |||
| 745 | dma_free_coherent(&ofdev->dev, | 747 | dma_free_coherent(&ofdev->dev, |
| 746 | sizeof(struct mal_descriptor) * | 748 | sizeof(struct mal_descriptor) * |
| 747 | (NUM_TX_BUFF * mal->num_tx_chans + | 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 | /* if we are going to send_subcrq_direct this then we need to | 2472 | /* if we are going to send_subcrq_direct this then we need to |
| 2473 | * update the checksum before copying the data into ltb. Essentially | 2473 | * update the checksum before copying the data into ltb. Essentially |
| 2474 | * these packets force disable CSO so that we can guarantee that | 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 | use_scrq_send_direct = true; | 2480 | use_scrq_send_direct = true; |
| 2479 | if (skb->ip_summed == CHECKSUM_PARTIAL && | 2481 | if (skb->ip_summed == CHECKSUM_PARTIAL && |
| 2480 | skb_checksum_help(skb)) | 2482 | skb_checksum_help(skb)) |
| @@ -108,8 +108,8 @@ struct e1000_hw; · 107 unmodified lines | |||
| 108 | #define E1000_DEV_ID_PCH_RPL_I219_V22 0x0DC8 | 108 | #define E1000_DEV_ID_PCH_RPL_I219_V22 0x0DC8 |
| 109 | #define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A | 109 | #define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A |
| 110 | #define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B | 110 | #define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B |
| 111 | #define E1000_DEV_ID_PCH_MTP_I219_LM19 0x550C | 111 | #define E1000_DEV_ID_PCH_ADP_I219_LM19 0x550C |
| 112 | #define E1000_DEV_ID_PCH_MTP_I219_V19 0x550D | 112 | #define E1000_DEV_ID_PCH_ADP_I219_V19 0x550D |
| 113 | #define E1000_DEV_ID_PCH_LNP_I219_LM20 0x550E | 113 | #define E1000_DEV_ID_PCH_LNP_I219_LM20 0x550E |
| 114 | #define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F | 114 | #define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F |
| 115 | #define E1000_DEV_ID_PCH_LNP_I219_LM21 0x5510 | 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 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp }, | 7899 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp }, |
| 7900 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp }, | 7900 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp }, |
| 7901 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_adp }, | 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 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp }, | 7904 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp }, |
| 7903 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_mtp }, | 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 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp }, | 7906 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp }, |
| 7907 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp }, | 7907 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp }, |
| 7908 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_mtp }, | 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 | struct hlist_node *h; | 1734 | struct hlist_node *h; |
| 1735 | int bkt; | 1735 | int bkt; |
| 1736 | 1736 | ||
| 1737 | lockdep_assert_held(&vsi->mac_filter_hash_lock); | ||
| 1737 | if (vsi->info.pvid) | 1738 | if (vsi->info.pvid) |
| 1738 | return i40e_add_filter(vsi, macaddr, | 1739 | return i40e_add_filter(vsi, macaddr, |
| 1739 | le16_to_cpu(vsi->info.pvid)); | 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 | vfres->vsi_res[0].qset_handle | 2213 | vfres->vsi_res[0].qset_handle |
| 2214 | = le16_to_cpu(vsi->info.qs_handle[0]); | 2214 | = le16_to_cpu(vsi->info.qs_handle[0]); |
| 2215 | if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) { | 2215 | if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) { |
| 2216 | spin_lock_bh(&vsi->mac_filter_hash_lock); | ||
| 2216 | i40e_del_mac_filter(vsi, vf->default_lan_addr.addr); | 2217 | i40e_del_mac_filter(vsi, vf->default_lan_addr.addr); |
| 2217 | eth_zero_addr(vf->default_lan_addr.addr); | 2218 | eth_zero_addr(vf->default_lan_addr.addr); |
| 2219 | spin_unlock_bh(&vsi->mac_filter_hash_lock); | ||
| 2218 | } | 2220 | } |
| 2219 | ether_addr_copy(vfres->vsi_res[0].default_mac_addr, | 2221 | ether_addr_copy(vfres->vsi_res[0].default_mac_addr, |
| 2220 | vf->default_lan_addr.addr); | 2222 | vf->default_lan_addr.addr); |
| @@ -31,7 +31,7 @@ static const struct ice_tunnel_type_scan tnls[] = { · 30 unmodified lines | |||
| 31 | * Verifies various attributes of the package file, including length, format | 31 | * Verifies various attributes of the package file, including length, format |
| 32 | * version, and the requirement of at least one segment. | 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 | u32 seg_count; | 36 | u32 seg_count; |
| 37 | u32 i; | 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 | /* all segments must fit within length */ | 57 | /* all segments must fit within length */ |
| 58 | for (i = 0; i < seg_count; i++) { | 58 | for (i = 0; i < seg_count; i++) { |
| 59 | u32 off = le32_to_cpu(pkg->seg_offset[i]); | 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 | /* segment header must fit */ | 62 | /* segment header must fit */ |
| 63 | if (len < off + sizeof(*seg)) | 63 | if (len < off + sizeof(*seg)) |
| 64 | return ICE_DDP_PKG_INVALID_FILE; | 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 | /* segment body must fit */ | 68 | /* segment body must fit */ |
| 69 | if (len < off + le32_to_cpu(seg->seg_size)) | 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 | * This helper function validates a buffer's header. | 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 | u16 section_count; | 125 | u16 section_count; |
| 126 | u16 data_end; | 126 | u16 data_end; |
| 127 | 127 | ||
| 128 | hdr = (struct ice_buf_hdr *)buf->buf; | 128 | hdr = (const struct ice_buf_hdr *)buf->buf; |
| 129 | /* verify data */ | 129 | /* verify data */ |
| 130 | section_count = le16_to_cpu(hdr->section_count); | 130 | section_count = le16_to_cpu(hdr->section_count); |
| 131 | if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT) | 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 | * unexpected value has been detected (for example an invalid section count or | 165 | * unexpected value has been detected (for example an invalid section count or |
| 166 | * an invalid buffer end value). | 166 | * an invalid buffer end value). |
| 167 | */ | 167 | */ |
| 168 | static struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg, | 168 | static const struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg, |
| 169 | struct ice_pkg_enum *state) | 169 | struct ice_pkg_enum *state) |
| 170 | { | 170 | { |
| 171 | if (ice_seg) { | 171 | if (ice_seg) { |
| 172 | state->buf_table = ice_find_buf_table(ice_seg); | 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 | * success it returns a pointer to the segment header, otherwise it will | 1800 | * success it returns a pointer to the segment header, otherwise it will |
| 1801 | * return NULL. | 1801 | * return NULL. |
| 1802 | */ | 1802 | */ |
| 1803 | static struct ice_generic_seg_hdr * | 1803 | static const struct ice_generic_seg_hdr * |
| 1804 | ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type, | 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 | u32 i; | 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 | /* Search all package segments for the requested segment type */ | 1814 | /* Search all package segments for the requested segment type */ |
| 1815 | for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) { | 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 | 1818 | seg = (void *)pkg_hdr + le32_to_cpu(pkg_hdr->seg_offset[i]); |
| 1819 | *)((u8 *)pkg_hdr + | ||
| 1820 | le32_to_cpu(pkg_hdr->seg_offset[i])); | ||
| 1821 | 1819 | ||
| 1822 | if (le32_to_cpu(seg->seg_type) == seg_type) | 1820 | if (le32_to_cpu(seg->seg_type) == seg_type) |
| 1823 | return seg; | 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 | * Return: zero when update was successful, negative values otherwise. | 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; | 2357 | u8 *new_topo = NULL, *topo __free(kfree) = NULL; |
| 2360 | struct ice_run_time_cfg_seg *seg; | 2358 | const struct ice_run_time_cfg_seg *seg; |
| 2361 | struct ice_buf_hdr *section; | 2359 | const struct ice_buf_hdr *section; |
| 2362 | struct ice_pkg_hdr *pkg_hdr; | 2360 | const struct ice_pkg_hdr *pkg_hdr; |
| 2363 | enum ice_ddp_state state; | 2361 | enum ice_ddp_state state; |
| 2364 | u16 offset, size = 0; | 2362 | u16 offset, size = 0; |
| 2365 | u32 reg = 0; | 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 | return -EOPNOTSUPP; | 2373 | return -EOPNOTSUPP; |
| 2376 | } | 2374 | } |
| 2377 | 2375 | ||
| 2378 | current_topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); | 2376 | topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); |
| 2379 | if (!current_topo) | 2377 | if (!topo) |
| 2380 | return -ENOMEM; | 2378 | return -ENOMEM; |
| 2381 | 2379 | ||
| 2382 | /* Get the current Tx topology */ | 2380 | /* Get the current Tx topology flags */ |
| 2383 | status = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL, | 2381 | status = ice_get_set_tx_topo(hw, topo, ICE_AQ_MAX_BUF_LEN, NULL, &flags, |
| 2384 | &flags, false); | 2382 | false); |
| 2385 | |||
| 2386 | kfree(current_topo); | ||
| 2387 | 2383 | ||
| 2388 | if (status) { | 2384 | if (status) { |
| 2389 | ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n"); | 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 | goto update_topo; | 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 | state = ice_verify_pkg(pkg_hdr, len); | 2419 | state = ice_verify_pkg(pkg_hdr, len); |
| 2424 | if (state) { | 2420 | if (state) { |
| 2425 | ice_debug(hw, ICE_DBG_INIT, "Failed to verify pkg (err: %d)\n", | 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 | /* Find runtime configuration segment */ | 2426 | /* Find runtime configuration segment */ |
| 2431 | seg = (struct ice_run_time_cfg_seg *) | 2427 | seg = (const struct ice_run_time_cfg_seg *) |
| 2432 | ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr); | 2428 | ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr); |
| 2433 | if (!seg) { | 2429 | if (!seg) { |
| 2434 | ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n"); | 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 | return -EIO; | 2457 | return -EIO; |
| 2462 | } | 2458 | } |
| 2463 | 2459 | ||
| 2464 | /* Get the new topology buffer */ | 2460 | /* Get the new topology buffer, reuse current topo copy mem */ |
| 2465 | new_topo = ((u8 *)section) + offset; | 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 | update_topo: | 2465 | update_topo: |
| 2468 | /* Acquire global lock to make sure that set topology issued | 2466 | /* Acquire global lock to make sure that set topology issued |
| @@ -438,7 +438,7 @@ struct ice_pkg_enum { · 437 unmodified lines | |||
| 438 | u32 buf_idx; | 438 | u32 buf_idx; |
| 439 | 439 | ||
| 440 | u32 type; | 440 | u32 type; |
| 441 | struct ice_buf_hdr *buf; | 441 | const struct ice_buf_hdr *buf; |
| 442 | u32 sect_idx; | 442 | u32 sect_idx; |
| 443 | void *sect; | 443 | void *sect; |
| 444 | u32 sect_type; | 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 | void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state, | 467 | void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state, |
| 468 | u32 sect_type); | 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 | #endif | 472 | #endif |
| @@ -656,6 +656,8 @@ ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv, · 655 unmodified lines | |||
| 656 | struct ice_dpll_pin *p = pin_priv; | 656 | struct ice_dpll_pin *p = pin_priv; |
| 657 | struct ice_dpll *d = dpll_priv; | 657 | struct ice_dpll *d = dpll_priv; |
| 658 | 658 | ||
| 659 | if (state == DPLL_PIN_STATE_SELECTABLE) | ||
| 660 | return -EINVAL; | ||
| 659 | if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED) | 661 | if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED) |
| 660 | return 0; | 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 | struct dpll_pin *parent; | 1845 | struct dpll_pin *parent; |
| 1844 | int ret, i; | 1846 | int ret, i; |
| 1845 | 1847 | ||
| 1848 | if (WARN_ON((!vsi || !vsi->netdev))) | ||
| 1849 | return -EINVAL; | ||
| 1846 | ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF, | 1850 | ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF, |
| 1847 | pf->dplls.clock_id); | 1851 | pf->dplls.clock_id); |
| 1848 | if (ret) | 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 | if (ret) | 1862 | if (ret) |
| 1859 | goto unregister_pins; | 1863 | goto unregister_pins; |
| 1860 | } | 1864 | } |
| 1861 | if (WARN_ON((!vsi || !vsi->netdev))) | ||
| 1862 | return -EINVAL; | ||
| 1863 | dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin); | 1865 | dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin); |
| 1864 | 1866 | ||
| 1865 | return 0; | 1867 | return 0; |
| @@ -582,10 +582,13 @@ ice_eswitch_br_switchdev_event(struct notifier_block *nb, · 581 unmodified lines | |||
| 582 | return NOTIFY_DONE; | 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 | struct ice_esw_br_fdb_entry *entry, *tmp; | 587 | struct ice_esw_br_fdb_entry *entry, *tmp; |
| 588 | 588 | ||
| 589 | if (!bridge) | ||
| 590 | return; | ||
| 591 | |||
| 589 | list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) | 592 | list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) |
| 590 | ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); | 593 | ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); |
| 591 | } | 594 | } |
| @@ -117,5 +117,6 @@ void · 116 unmodified lines | |||
| 117 | ice_eswitch_br_offloads_deinit(struct ice_pf *pf); | 117 | ice_eswitch_br_offloads_deinit(struct ice_pf *pf); |
| 118 | int | 118 | int |
| 119 | ice_eswitch_br_offloads_init(struct ice_pf *pf); | 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 | #endif /* _ICE_ESWITCH_BR_H_ */ | 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 | bool netif_is_ice(const struct net_device *dev) | 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 | pf->vf_agg_node[node].num_vsis = 0; | 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 | * ice_prepare_for_reset - prep for reset | 525 | * ice_prepare_for_reset - prep for reset |
| 544 | * @pf: board private structure | 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 | mutex_unlock(&pf->vfs.table_lock); | 557 | mutex_unlock(&pf->vfs.table_lock); |
| 576 | 558 | ||
| 577 | if (ice_is_eswitch_mode_switchdev(pf)) { | 559 | if (ice_is_eswitch_mode_switchdev(pf)) { |
| 578 | if (reset_type != ICE_RESET_PFR) | 560 | rtnl_lock(); |
| 579 | ice_clear_sw_switch_recipes(pf); | 561 | ice_eswitch_br_fdb_flush(pf->eswitch.br_offloads->bridge); |
| 562 | rtnl_unlock(); | ||
| 580 | } | 563 | } |
| 581 | 564 | ||
| 582 | /* release ADQ specific HW and SW resources */ | 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 | u8 num_tx_sched_layers = hw->num_tx_sched_layers; | 4519 | u8 num_tx_sched_layers = hw->num_tx_sched_layers; |
| 4537 | struct ice_pf *pf = hw->back; | 4520 | struct ice_pf *pf = hw->back; |
| 4538 | struct device *dev; | 4521 | struct device *dev; |
| 4539 | u8 *buf_copy; | ||
| 4540 | int err; | 4522 | int err; |
| 4541 | 4523 | ||
| 4542 | dev = ice_pf_to_dev(pf); | 4524 | dev = ice_pf_to_dev(pf); |
| 4543 | /* ice_cfg_tx_topo buf argument is not a constant, | 4525 | err = ice_cfg_tx_topo(hw, firmware->data, firmware->size); |
| 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); | ||
| 4549 | if (!err) { | 4526 | if (!err) { |
| 4550 | if (hw->num_tx_sched_layers > num_tx_sched_layers) | 4527 | if (hw->num_tx_sched_layers > num_tx_sched_layers) |
| 4551 | dev_info(dev, "Tx scheduling layers switching feature disabled\n"); | 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 | ice_init_feature_support(pf); | 4750 | ice_init_feature_support(pf); |
| 4774 | 4751 | ||
| 4775 | err = ice_init_ddp_config(hw, pf); | 4752 | err = ice_init_ddp_config(hw, pf); |
| 4776 | if (err) | ||
| 4777 | return err; | ||
| 4778 | 4753 | ||
| 4779 | /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be | 4754 | /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be |
| 4780 | * set in pf->state, which will cause ice_is_safe_mode to return | 4755 | * set in pf->state, which will cause ice_is_safe_mode to return |
| 4781 | * true | 4756 | * true |
| 4782 | */ | 4757 | */ |
| 4783 | if (ice_is_safe_mode(pf)) { | 4758 | if (err || ice_is_safe_mode(pf)) { |
| 4784 | /* we already got function/device capabilities but these don't | 4759 | /* we already got function/device capabilities but these don't |
| 4785 | * reflect what the driver needs to do in safe mode. Instead of | 4760 | * reflect what the driver needs to do in safe mode. Instead of |
| 4786 | * adding conditional logic everywhere to ignore these | 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 | return -ENOENT; | 1096 | return -ENOENT; |
| 1097 | 1097 | ||
| 1098 | vsi = ice_get_vf_vsi(vf); | 1098 | vsi = ice_get_vf_vsi(vf); |
| 1099 | if (!vsi) | 1099 | if (!vsi) { |
| 1100 | ice_put_vf(vf); | ||
| 1100 | return -ENOENT; | 1101 | return -ENOENT; |
| 1102 | } | ||
| 1101 | 1103 | ||
| 1102 | prev_msix = vf->num_msix; | 1104 | prev_msix = vf->num_msix; |
| 1103 | prev_queues = vf->num_vf_qs; | 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 | if (vf->first_vector_idx < 0) | 1121 | if (vf->first_vector_idx < 0) |
| 1120 | goto unroll; | 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 | /* Try to rebuild with previous values */ | 1128 | /* Try to rebuild with previous values */ |
| 1124 | needs_rebuild = true; | 1129 | needs_rebuild = true; |
| 1125 | goto unroll; | 1130 | goto unroll; |
| @@ -1142,12 +1147,16 @@ unroll: · 16 unmodified lines | |||
| 1142 | vf->num_msix = prev_msix; | 1147 | vf->num_msix = prev_msix; |
| 1143 | vf->num_vf_qs = prev_queues; | 1148 | vf->num_vf_qs = prev_queues; |
| 1144 | vf->first_vector_idx = ice_sriov_get_irqs(pf, vf->num_msix); | 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 | return -EINVAL; | 1152 | return -EINVAL; |
| 1153 | } | ||
| 1147 | 1154 | ||
| 1148 | if (needs_rebuild) { | 1155 | if (needs_rebuild) { |
| 1149 | ice_vf_reconfig_vsi(vf); | 1156 | vsi->req_txq = prev_queues; |
| 1150 | ice_vf_init_host_cfg(vf, vsi); | 1157 | vsi->req_rxq = prev_queues; |
| 1158 | |||
| 1159 | ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT); | ||
| 1151 | } | 1160 | } |
| 1152 | 1161 | ||
| 1153 | ice_ena_vf_mappings(vf); | 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 | if (!itr->vsi_list_info || | 6322 | if (!itr->vsi_list_info || |
| 6323 | !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) | 6323 | !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) |
| 6324 | continue; | 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 | f_entry.fltr_info.vsi_handle = vsi_handle; | 6325 | f_entry.fltr_info.vsi_handle = vsi_handle; |
| 6328 | f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; | 6326 | f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; |
| 6329 | /* update the src in case it is VSI num */ | 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 | rule_info.sw_act.flag |= ICE_FLTR_TX; | 819 | rule_info.sw_act.flag |= ICE_FLTR_TX; |
| 820 | rule_info.sw_act.src = vsi->idx; | 820 | rule_info.sw_act.src = vsi->idx; |
| 821 | rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE; | 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 | } else { | 833 | } else { |
| 823 | /* VF to VF */ | 834 | /* VF to VF */ |
| 824 | rule_info.sw_act.flag |= ICE_FLTR_TX; | 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 | * It brings the VSI down and then reconfigures it with the hardware. | 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 | struct ice_vsi *vsi = ice_get_vf_vsi(vf); | 261 | struct ice_vsi *vsi = ice_get_vf_vsi(vf); |
| 262 | struct ice_pf *pf = vf->pf; | 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 | err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info); | 336 | err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info); |
| 337 | } else { | 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 | err = ice_vsi_add_vlan_zero(vsi); | 345 | err = ice_vsi_add_vlan_zero(vsi); |
| 339 | } | 346 | } |
| 340 | 347 | ||
| @@ -23,7 +23,6 @@ · 22 unmodified lines | |||
| 23 | #warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files" | 23 | #warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files" |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | int ice_vf_reconfig_vsi(struct ice_vf *vf); | ||
| 27 | void ice_initialize_vf_entry(struct ice_vf *vf); | 26 | void ice_initialize_vf_entry(struct ice_vf *vf); |
| 28 | void ice_dis_vf_qs(struct ice_vf *vf); | 27 | void ice_dis_vf_qs(struct ice_vf *vf); |
| 29 | int ice_check_vf_init(struct ice_vf *vf); | 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 | kfree(ctxt); | 787 | kfree(ctxt); |
| 788 | return err; | 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 | int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi); | 36 | int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi); |
| 37 | int ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan); | 37 | int ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan); |
| 38 | int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi); | 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 | #endif /* _ICE_VSI_VLAN_LIB_H_ */ | 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 | intr->dyn_ctl_intena_m = VF_INT_DYN_CTLN_INTENA_M; | 99 | intr->dyn_ctl_intena_m = VF_INT_DYN_CTLN_INTENA_M; |
| 100 | intr->dyn_ctl_intena_msk_m = VF_INT_DYN_CTLN_INTENA_MSK_M; | 100 | intr->dyn_ctl_intena_msk_m = VF_INT_DYN_CTLN_INTENA_MSK_M; |
| 101 | intr->dyn_ctl_itridx_s = VF_INT_DYN_CTLN_ITR_INDX_S; | 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 | intr->dyn_ctl_wb_on_itr_m = VF_INT_DYN_CTLN_WB_ON_ITR_M; | 103 | intr->dyn_ctl_wb_on_itr_m = VF_INT_DYN_CTLN_WB_ON_ITR_M; |
| 103 | 104 | ||
| 104 | spacing = IDPF_ITR_IDX_SPACING(reg_vals[vec_id].itrn_index_spacing, | 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 | if (ctlq_msg->data_len) { | 667 | if (ctlq_msg->data_len) { |
| 668 | payload = ctlq_msg->ctx.indirect.payload->va; | 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 | xn->reply_sz = payload_size; | 672 | xn->reply_sz = payload_size; |
| @@ -1295,10 +1295,6 @@ int idpf_send_create_vport_msg(struct idpf_adapter *adapter, · 622 unmodified lines | |||
| 1295 | err = reply_sz; | 1295 | err = reply_sz; |
| 1296 | goto free_vport_params; | 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 | return 0; | 1299 | return 0; |
| 1304 | 1300 | ||
| @@ -2602,9 +2598,6 @@ int idpf_send_get_rx_ptype_msg(struct idpf_vport *vport) · 1297 unmodified lines | |||
| 2602 | if (reply_sz < 0) | 2598 | if (reply_sz < 0) |
| 2603 | return reply_sz; | 2599 | return reply_sz; |
| 2604 | 2600 | ||
| 2605 | if (reply_sz < IDPF_CTLQ_MAX_BUF_LEN) | ||
| 2606 | return -EIO; | ||
| 2607 | |||
| 2608 | ptypes_recvd += le16_to_cpu(ptype_info->num_ptypes); | 2601 | ptypes_recvd += le16_to_cpu(ptype_info->num_ptypes); |
| 2609 | if (ptypes_recvd > max_ptype) | 2602 | if (ptypes_recvd > max_ptype) |
| 2610 | return -EINVAL; | 2603 | return -EINVAL; |
| @@ -3088,9 +3081,9 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter) · 477 unmodified lines | |||
| 3088 | if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags)) | 3081 | if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags)) |
| 3089 | return; | 3082 | return; |
| 3090 | 3083 | ||
| 3091 | idpf_vc_xn_shutdown(adapter->vcxn_mngr); | ||
| 3092 | idpf_deinit_task(adapter); | 3084 | idpf_deinit_task(adapter); |
| 3093 | idpf_intr_rel(adapter); | 3085 | idpf_intr_rel(adapter); |
| 3086 | idpf_vc_xn_shutdown(adapter->vcxn_mngr); | ||
| 3094 | 3087 | ||
| 3095 | cancel_delayed_work_sync(&adapter->serv_task); | 3088 | cancel_delayed_work_sync(&adapter->serv_task); |
| 3096 | cancel_delayed_work_sync(&adapter->mbx_task); | 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 | struct igb_adapter *adapter = netdev_priv(netdev); | 9651 | struct igb_adapter *adapter = netdev_priv(netdev); |
| 9652 | 9652 | ||
| 9653 | if (netif_running(netdev)) { | 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 | if (igb_up(adapter)) { | 9658 | if (igb_up(adapter)) { |
| 9655 | dev_err(&pdev->dev, "igb_up failed after reset\n"); | 9659 | dev_err(&pdev->dev, "igb_up failed after reset\n"); |
| 9656 | return; | 9660 | return; |
| @@ -336,6 +336,51 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct, · 335 unmodified lines | |||
| 336 | return new_pkts; | 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 | * __octep_oq_process_rx() - Process hardware Rx queue and push to stack. | 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 | desc_used = 0; | 412 | desc_used = 0; |
| 368 | for (pkt = 0; pkt < pkts_to_process; pkt++) { | 413 | for (pkt = 0; pkt < pkts_to_process; pkt++) { |
| 369 | buff_info = (struct octep_rx_buffer *)&oq->buff_info[read_idx]; | 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 | resp_hw = page_address(buff_info->page); | 415 | resp_hw = page_address(buff_info->page); |
| 373 | buff_info->page = NULL; | ||
| 374 | 416 | ||
| 375 | /* Swap the length field that is in Big-Endian to CPU */ | 417 | /* Swap the length field that is in Big-Endian to CPU */ |
| 376 | buff_info->len = be64_to_cpu(resp_hw->length); | 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 | data_offset = OCTEP_OQ_RESP_HW_SIZE; | 436 | data_offset = OCTEP_OQ_RESP_HW_SIZE; |
| 395 | rx_ol_flags = 0; | 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 | rx_bytes += buff_info->len; | 451 | rx_bytes += buff_info->len; |
| 398 | 452 | ||
| 399 | if (buff_info->len <= oq->max_single_buffer_size) { | 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 | skb_put(skb, buff_info->len); | 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 | } else { | 455 | } else { |
| 408 | struct skb_shared_info *shinfo; | 456 | struct skb_shared_info *shinfo; |
| 409 | u16 data_len; | 457 | u16 data_len; |
| 410 | 458 | ||
| 411 | skb = build_skb((void *)resp_hw, PAGE_SIZE); | ||
| 412 | skb_reserve(skb, data_offset); | ||
| 413 | /* Head fragment includes response header(s); | 459 | /* Head fragment includes response header(s); |
| 414 | * subsequent fragments contains only data. | 460 | * subsequent fragments contains only data. |
| 415 | */ | 461 | */ |
| 416 | skb_put(skb, oq->max_single_buffer_size); | 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 | shinfo = skb_shinfo(skb); | 463 | shinfo = skb_shinfo(skb); |
| 423 | data_len = buff_info->len - oq->max_single_buffer_size; | 464 | data_len = buff_info->len - oq->max_single_buffer_size; |
| 424 | while (data_len) { | 465 | while (data_len) { |
| 425 | dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr, | ||
| 426 | PAGE_SIZE, DMA_FROM_DEVICE); | ||
| 427 | buff_info = (struct octep_rx_buffer *) | 466 | buff_info = (struct octep_rx_buffer *) |
| 428 | &oq->buff_info[read_idx]; | 467 | &oq->buff_info[read_idx]; |
| 429 | if (data_len < oq->buffer_size) { | 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 | buff_info->page, 0, | 477 | buff_info->page, 0, |
| 439 | buff_info->len, | 478 | buff_info->len, |
| 440 | buff_info->len); | 479 | buff_info->len); |
| 441 | buff_info->page = NULL; | 480 | |
| 442 | read_idx++; | 481 | octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used); |
| 443 | desc_used++; | ||
| 444 | if (read_idx == oq->max_count) | ||
| 445 | read_idx = 0; | ||
| 446 | } | 482 | } |
| 447 | } | 483 | } |
| 448 | 484 | ||
| @@ -2411,7 +2411,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, · 2410 unmodified lines | |||
| 2411 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); | 2411 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); |
| 2412 | if (!(cfg & BIT_ULL(12))) | 2412 | if (!(cfg & BIT_ULL(12))) |
| 2413 | continue; | 2413 | continue; |
| 2414 | bmap |= (1 << i); | 2414 | bmap |= BIT_ULL(i); |
| 2415 | cfg &= ~BIT_ULL(12); | 2415 | cfg &= ~BIT_ULL(12); |
| 2416 | rvu_write64(rvu, blkaddr, | 2416 | rvu_write64(rvu, blkaddr, |
| 2417 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link), cfg); | 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 | /* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */ | 2433 | /* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */ |
| 2434 | for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) { | 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 | continue; | 2436 | continue; |
| 2437 | cfg = rvu_read64(rvu, blkaddr, | 2437 | cfg = rvu_read64(rvu, blkaddr, |
| 2438 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); | 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 | e->dma_addr = addr; | 2471 | e->dma_addr = addr; |
| 2472 | e->dma_len = len; | 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 | data = skb_frag_address(frag); | 2474 | data = skb_frag_address(frag); |
| 2479 | len = skb_frag_size(frag); | 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 | q->queued += i; | 2479 | q->queued += i; |
| 2484 | 2480 | ||
| 2485 | skb_tx_timestamp(skb); | 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 | if (q->ndesc - q->queued < q->free_thr) | 2487 | if (q->ndesc - q->queued < q->free_thr) |
| 2487 | netif_tx_stop_queue(txq); | 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 | if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) | 1171 | if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) |
| 1172 | return -ENOMEM; | 1172 | return -ENOMEM; |
| 1173 | 1173 | ||
| 1174 | for (i = 0; i < cnt; i++) { | 1174 | for (i = 0; i < len; i++) { |
| 1175 | struct mtk_tx_dma_v2 *txd; | 1175 | struct mtk_tx_dma_v2 *txd; |
| 1176 | 1176 | ||
| 1177 | txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size; | 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 | static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) | 1772 | static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) |
| 1769 | { | 1773 | { |
| 1770 | struct mlx5_cmd *cmd = &dev->cmd; | 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 | /* wait for pending handlers to complete */ | 1780 | /* wait for pending handlers to complete */ |
| 1777 | mlx5_eq_synchronize_cmd_irq(dev); | 1781 | mlx5_eq_synchronize_cmd_irq(dev); |
| 1778 | spin_lock_irqsave(&dev->cmd.alloc_lock, flags); | 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 | if (!vector) | 1784 | if (!vector) |
| 1781 | goto no_trig; | 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 | cmd->state = MLX5_CMDIF_STATE_DOWN; | 2366 | cmd->state = MLX5_CMDIF_STATE_DOWN; |
| 2363 | cmd->vars.max_reg_cmds = (1 << cmd->vars.log_sz) - 1; | 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 | sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds); | 2370 | sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds); |
| 2367 | sema_init(&cmd->vars.pages_sem, 1); | 2371 | sema_init(&cmd->vars.pages_sem, 1); |
| @@ -6509,7 +6509,9 @@ static void _mlx5e_remove(struct auxiliary_device *adev) · 6508 unmodified lines | |||
| 6509 | mlx5e_dcbnl_delete_app(priv); | 6509 | mlx5e_dcbnl_delete_app(priv); |
| 6510 | unregister_netdev(priv->netdev); | 6510 | unregister_netdev(priv->netdev); |
| 6511 | _mlx5e_suspend(adev, false); | 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 | mlx5e_destroy_netdev(priv); | 6515 | mlx5e_destroy_netdev(priv); |
| 6514 | mlx5e_devlink_port_unregister(mlx5e_dev); | 6516 | mlx5e_devlink_port_unregister(mlx5e_dev); |
| 6515 | mlx5e_destroy_devlink(mlx5e_dev); | 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 | struct mlx5_eq_comp *eq; | 1061 | struct mlx5_eq_comp *eq; |
| 1062 | int ret = 0; | 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 | mutex_lock(&table->comp_lock); | 1070 | mutex_lock(&table->comp_lock); |
| 1065 | eq = xa_load(&table->comp_eqs, vecidx); | 1071 | eq = xa_load(&table->comp_eqs, vecidx); |
| 1066 | if (eq) { | 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 | if (err) | 1491 | if (err) |
| 1492 | goto abort; | 1492 | goto err_esw_enable; |
| 1493 | 1493 | ||
| 1494 | esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED; | 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 | return 0; | 1504 | return 0; |
| 1505 | 1505 | ||
| 1506 | abort: | 1506 | err_esw_enable: |
| 1507 | mlx5_eq_notifier_unregister(esw->dev, &esw->nb); | ||
| 1507 | mlx5_esw_acls_ns_cleanup(esw); | 1508 | mlx5_esw_acls_ns_cleanup(esw); |
| 1508 | return err; | 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 | static int | 691 | static int |
| 692 | hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) | 692 | hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) |
| 693 | { | 693 | { |
| 694 | u32 num_of_rules; | ||
| 695 | int ret; | 694 | int ret; |
| 696 | 695 | ||
| 697 | /* If the current matcher size is already at its max size, we can't | 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 | * Need to check again if we really need rehash. | 704 | * Need to check again if we really need rehash. |
| 706 | * If the reason for rehash was size, but not any more - skip rehash. | 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); | 707 | if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, bwc_matcher->num_of_rules)) |
| 709 | if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules)) | ||
| 710 | return 0; | 708 | return 0; |
| 711 | 709 | ||
| 712 | /* Now we're done all the checking - do the rehash: | 710 | /* Now we're done all the checking - do the rehash: |
| @@ -46,6 +46,7 @@ struct mlx5hws_context { · 45 unmodified lines | |||
| 46 | struct mlx5hws_send_engine *send_queue; | 46 | struct mlx5hws_send_engine *send_queue; |
| 47 | size_t queues; | 47 | size_t queues; |
| 48 | struct mutex *bwc_send_queue_locks; /* protect BWC queues */ | 48 | struct mutex *bwc_send_queue_locks; /* protect BWC queues */ |
| 49 | struct lock_class_key *bwc_lock_class_keys; | ||
| 49 | struct list_head tbl_list; | 50 | struct list_head tbl_list; |
| 50 | struct mlx5hws_context_debug_info debug_info; | 51 | struct mlx5hws_context_debug_info debug_info; |
| 51 | struct xarray peer_ctx_xa; | 52 | struct xarray peer_ctx_xa; |
| @@ -1925,7 +1925,7 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx, · 1924 unmodified lines | |||
| 1925 | ret = hws_definer_conv_match_params_to_hl(ctx, mt, match_hl); | 1925 | ret = hws_definer_conv_match_params_to_hl(ctx, mt, match_hl); |
| 1926 | if (ret) { | 1926 | if (ret) { |
| 1927 | mlx5hws_err(ctx, "Failed to convert items to header layout\n"); | 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 | /* Find the match definer layout for header layout match union */ | 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 | free_fc: | 1947 | free_fc: |
| 1948 | kfree(mt->fc); | 1948 | kfree(mt->fc); |
| 1949 | 1949 | free_match_hl: | |
| 1950 | kfree(match_hl); | 1950 | kfree(match_hl); |
| 1951 | return ret; | 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 | static void hws_send_queues_bwc_locks_destroy(struct mlx5hws_context *ctx) | 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 | int i; | 945 | int i; |
| 946 | 946 | ||
| 947 | if (!mlx5hws_context_bwc_supported(ctx)) | 947 | if (!mlx5hws_context_bwc_supported(ctx)) |
| 948 | return; | 948 | return; |
| 949 | 949 | ||
| 950 | for (i = 0; i < bwc_queues; i++) | 950 | for (i = 0; i < bwc_queues; i++) { |
| 951 | mutex_destroy(&ctx->bwc_send_queue_locks[i]); | 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 | kfree(ctx->bwc_send_queue_locks); | 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 | if (!ctx->bwc_send_queue_locks) | 981 | if (!ctx->bwc_send_queue_locks) |
| 978 | return -ENOMEM; | 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 | mutex_init(&ctx->bwc_send_queue_locks[i]); | 991 | mutex_init(&ctx->bwc_send_queue_locks[i]); |
| 992 | lockdep_register_key(ctx->bwc_lock_class_keys + i); | ||
| 993 | } | ||
| 982 | 994 | ||
| 983 | return 0; | 995 | return 0; |
| 996 | |||
| 997 | err_lock_class_keys: | ||
| 998 | kfree(ctx->bwc_send_queue_locks); | ||
| 999 | return -ENOMEM; | ||
| 984 | } | 1000 | } |
| 985 | 1001 | ||
| 986 | int mlx5hws_send_queues_open(struct mlx5hws_context *ctx, | 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 | struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp; | 3198 | struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp; |
| 3199 | struct mlxsw_sp_nexthop_counter *nhct; | 3199 | struct mlxsw_sp_nexthop_counter *nhct; |
| 3200 | void *ptr; | ||
| 3201 | int err; | 3200 | int err; |
| 3202 | 3201 | ||
| 3203 | nhct = xa_load(&nh_grp->nhgi->nexthop_counters, nh->id); | 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 | if (IS_ERR(nhct)) | 3209 | if (IS_ERR(nhct)) |
| 3211 | return nhct; | 3210 | return nhct; |
| 3212 | 3211 | ||
| 3213 | ptr = xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct, | 3212 | err = xa_err(xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct, |
| 3214 | GFP_KERNEL); | 3213 | GFP_KERNEL)); |
| 3215 | if (IS_ERR(ptr)) { | 3214 | if (err) |
| 3216 | err = PTR_ERR(ptr); | ||
| 3217 | goto err_store; | 3215 | goto err_store; |
| 3218 | } | ||
| 3219 | 3216 | ||
| 3220 | return nhct; | 3217 | return nhct; |
| 3221 | 3218 | ||
| @@ -401,28 +401,21 @@ static int lan743x_ptpci_settime64(struct ptp_clock_info *ptpci, · 400 unmodified lines | |||
| 401 | u32 nano_seconds = 0; | 401 | u32 nano_seconds = 0; |
| 402 | u32 seconds = 0; | 402 | u32 seconds = 0; |
| 403 | 403 | ||
| 404 | if (ts) { | 404 | if (ts->tv_sec > 0xFFFFFFFFLL) { |
| 405 | if (ts->tv_sec > 0xFFFFFFFFLL || | 405 | netif_warn(adapter, drv, adapter->netdev, |
| 406 | ts->tv_sec < 0) { | 406 | "ts->tv_sec out of range, %lld\n", |
| 407 | netif_warn(adapter, drv, adapter->netdev, | 407 | ts->tv_sec); |
| 408 | "ts->tv_sec out of range, %lld\n", | 408 | return -ERANGE; |
| 409 | ts->tv_sec); | 409 | } |
| 410 | return -ERANGE; | 410 | if (ts->tv_nsec < 0) { |
| 411 | } | 411 | netif_warn(adapter, drv, adapter->netdev, |
| 412 | if (ts->tv_nsec >= 1000000000L || | 412 | "ts->tv_nsec out of range, %ld\n", |
| 413 | ts->tv_nsec < 0) { | 413 | ts->tv_nsec); |
| 414 | netif_warn(adapter, drv, adapter->netdev, | 414 | return -ERANGE; |
| 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; | ||
| 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 | return 0; | 420 | return 0; |
| 428 | } | 421 | } |
| @@ -31,10 +31,10 @@ static u64 sparx5_mirror_port_get(struct sparx5 *sparx5, u32 idx) · 30 unmodified lines | |||
| 31 | /* Add port to mirror (only front ports) */ | 31 | /* Add port to mirror (only front ports) */ |
| 32 | static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno) | 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(do_div(reg, 32)); |
| 37 | val = BIT(portno % BITS_PER_BYTE); | ||
| 38 | 38 | ||
| 39 | if (reg == 0) | 39 | if (reg == 0) |
| 40 | return spx5_rmw(val, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); | 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 | /* Delete port from mirror (only front ports) */ | 45 | /* Delete port from mirror (only front ports) */ |
| 46 | static void sparx5_mirror_port_del(struct sparx5 *sparx5, u32 idx, u32 portno) | 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(do_div(reg, 32)); |
| 51 | val = BIT(portno % BITS_PER_BYTE); | ||
| 52 | 52 | ||
| 53 | if (reg == 0) | 53 | if (reg == 0) |
| 54 | return spx5_rmw(0, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); | 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 | ret = vcap_del_rule(&test_vctrl, &test_netdev, id); | 1445 | ret = vcap_del_rule(&test_vctrl, &test_netdev, id); |
| 1446 | KUNIT_EXPECT_EQ(test, 0, ret); | 1446 | KUNIT_EXPECT_EQ(test, 0, ret); |
| 1447 | |||
| 1448 | vcap_free_rule(rule); | ||
| 1447 | } | 1449 | } |
| 1448 | 1450 | ||
| 1449 | static void vcap_api_set_rule_counter_test(struct kunit *test) | 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 | if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask)) | 4682 | if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask)) |
| 4683 | return IRQ_NONE; | 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 | rtl8169_pcierr_interrupt(tp->dev); | 4688 | rtl8169_pcierr_interrupt(tp->dev); |
| 4687 | goto out; | 4689 | goto out; |
| 4688 | } | 4690 | } |
| @@ -1750,20 +1750,19 @@ static int ravb_get_ts_info(struct net_device *ndev, · 1749 unmodified lines | |||
| 1750 | struct ravb_private *priv = netdev_priv(ndev); | 1750 | struct ravb_private *priv = netdev_priv(ndev); |
| 1751 | const struct ravb_hw_info *hw_info = priv->info; | 1751 | const struct ravb_hw_info *hw_info = priv->info; |
| 1752 | 1752 | ||
| 1753 | info->so_timestamping = | 1753 | if (hw_info->gptp || hw_info->ccc_gac) { |
| 1754 | SOF_TIMESTAMPING_TX_SOFTWARE | | 1754 | info->so_timestamping = |
| 1755 | SOF_TIMESTAMPING_TX_HARDWARE | | 1755 | SOF_TIMESTAMPING_TX_SOFTWARE | |
| 1756 | SOF_TIMESTAMPING_RX_HARDWARE | | 1756 | SOF_TIMESTAMPING_TX_HARDWARE | |
| 1757 | SOF_TIMESTAMPING_RAW_HARDWARE; | 1757 | SOF_TIMESTAMPING_RX_HARDWARE | |
| 1758 | info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); | 1758 | SOF_TIMESTAMPING_RAW_HARDWARE; |
| 1759 | info->rx_filters = | 1759 | info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); |
| 1760 | (1 << HWTSTAMP_FILTER_NONE) | | 1760 | info->rx_filters = |
| 1761 | (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | | 1761 | (1 << HWTSTAMP_FILTER_NONE) | |
| 1762 | (1 << HWTSTAMP_FILTER_ALL); | 1762 | (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | |
| 1763 | if (hw_info->gptp || hw_info->ccc_gac) | 1763 | (1 << HWTSTAMP_FILTER_ALL); |
| 1764 | info->phc_index = ptp_clock_index(priv->ptp.clock); | 1764 | info->phc_index = ptp_clock_index(priv->ptp.clock); |
| 1765 | else | 1765 | } |
| 1766 | info->phc_index = 0; | ||
| 1767 | 1766 | ||
| 1768 | return 0; | 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 | if (skb->len >= TX_DS) { | 1057 | if (skb->len >= TX_DS) { |
| 1058 | priv->stats.tx_dropped++; | 1058 | priv->stats.tx_dropped++; |
| 1059 | priv->stats.tx_errors++; | 1059 | priv->stats.tx_errors++; |
| 1060 | dev_kfree_skb_any(skb); | ||
| 1060 | goto out; | 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 | spent = efx_process_channel(channel, budget); | 1261 | spent = efx_process_channel(channel, budget); |
| 1262 | 1262 | ||
| 1263 | xdp_do_flush(); | 1263 | if (budget) |
| 1264 | xdp_do_flush(); | ||
| 1264 | 1265 | ||
| 1265 | if (spent < budget) { | 1266 | if (spent < budget) { |
| 1266 | if (efx_channel_has_rx_queue(channel) && | 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 | spent = efx_process_channel(channel, budget); | 1286 | spent = efx_process_channel(channel, budget); |
| 1287 | 1287 | ||
| 1288 | xdp_do_flush(); | 1288 | if (budget) |
| 1289 | xdp_do_flush(); | ||
| 1289 | 1290 | ||
| 1290 | if (spent < budget) { | 1291 | if (spent < budget) { |
| 1291 | if (efx_channel_has_rx_queue(channel) && | 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 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ; | 127 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ; |
| 128 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 131 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 131 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP; | 132 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP; |
| 132 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 136 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 135 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN; | 137 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN; |
| 136 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | return err; | 145 | return err; |
| 144 | } | 146 | } |
| 145 | 147 | ||
| 148 | usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | ||
| 146 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 149 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 147 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN; | 150 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN; |
| 148 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 151 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 149 | 152 | ||
| 150 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 163 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 159 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY; | 164 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY; |
| 160 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_IRQ_STATUS, value, | 172 | err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_IRQ_STATUS, value, |
| 163 | value & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS, | 173 | value & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS, |
| 164 | 500, 500 * 2000); | 174 | 500, 500 * 2000); |
| @@ -2035,7 +2035,7 @@ static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, · 2034 unmodified lines | |||
| 2035 | rx_q->queue_index = queue; | 2035 | rx_q->queue_index = queue; |
| 2036 | rx_q->priv_data = priv; | 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 | pp_params.pool_size = dma_conf->dma_rx_size; | 2039 | pp_params.pool_size = dma_conf->dma_rx_size; |
| 2040 | num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE); | 2040 | num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE); |
| 2041 | pp_params.order = ilog2(num_pages); | 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 | return 0; | 2744 | return 0; |
| 2745 | 2745 | ||
| 2746 | /* alloc netdev */ | 2746 | /* alloc netdev */ |
| 2747 | port->ndev = devm_alloc_etherdev_mqs(common->dev, | 2747 | port->ndev = alloc_etherdev_mqs(sizeof(struct am65_cpsw_ndev_priv), |
| 2748 | sizeof(struct am65_cpsw_ndev_priv), | 2748 | AM65_CPSW_MAX_QUEUES, |
| 2749 | AM65_CPSW_MAX_QUEUES, | 2749 | AM65_CPSW_MAX_QUEUES); |
| 2750 | AM65_CPSW_MAX_QUEUES); | ||
| 2751 | if (!port->ndev) { | 2750 | if (!port->ndev) { |
| 2752 | dev_err(dev, "error allocating slave net_device %u\n", | 2751 | dev_err(dev, "error allocating slave net_device %u\n", |
| 2753 | port->port_id); | 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 | for (i = 0; i < common->port_num; i++) { | 2868 | for (i = 0; i < common->port_num; i++) { |
| 2870 | port = &common->ports[i]; | 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 | unregister_netdev(port->ndev); | 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 | ret = am65_cpsw_nuss_init_ndevs(common); | 3617 | ret = am65_cpsw_nuss_init_ndevs(common); |
| 3615 | if (ret) | 3618 | if (ret) |
| 3616 | goto err_free_phylink; | 3619 | goto err_ndevs_clear; |
| 3617 | 3620 | ||
| 3618 | ret = am65_cpsw_nuss_register_ndevs(common); | 3621 | ret = am65_cpsw_nuss_register_ndevs(common); |
| 3619 | if (ret) | 3622 | if (ret) |
| 3620 | goto err_free_phylink; | 3623 | goto err_ndevs_clear; |
| 3621 | 3624 | ||
| 3622 | pm_runtime_put(dev); | 3625 | pm_runtime_put(dev); |
| 3623 | return 0; | 3626 | return 0; |
| 3624 | 3627 | ||
| 3625 | err_free_phylink: | 3628 | err_ndevs_clear: |
| 3629 | am65_cpsw_nuss_cleanup_ndev(common); | ||
| 3626 | am65_cpsw_nuss_phylink_cleanup(common); | 3630 | am65_cpsw_nuss_phylink_cleanup(common); |
| 3627 | am65_cpts_release(common->cpts); | 3631 | am65_cpts_release(common->cpts); |
| 3628 | err_of_clear: | 3632 | err_of_clear: |
| @@ -3652,13 +3656,13 @@ static void am65_cpsw_nuss_remove(struct platform_device *pdev) · 23 unmodified lines | |||
| 3652 | return; | 3656 | return; |
| 3653 | } | 3657 | } |
| 3654 | 3658 | ||
| 3655 | am65_cpsw_unregister_devlink(common); | ||
| 3656 | am65_cpsw_unregister_notifiers(common); | 3659 | am65_cpsw_unregister_notifiers(common); |
| 3657 | 3660 | ||
| 3658 | /* must unregister ndevs here because DD release_driver routine calls | 3661 | /* must unregister ndevs here because DD release_driver routine calls |
| 3659 | * dma_deconfigure(dev) before devres_release_all(dev) | 3662 | * dma_deconfigure(dev) before devres_release_all(dev) |
| 3660 | */ | 3663 | */ |
| 3661 | am65_cpsw_nuss_cleanup_ndev(common); | 3664 | am65_cpsw_nuss_cleanup_ndev(common); |
| 3665 | am65_cpsw_unregister_devlink(common); | ||
| 3662 | am65_cpsw_nuss_phylink_cleanup(common); | 3666 | am65_cpsw_nuss_phylink_cleanup(common); |
| 3663 | am65_cpts_release(common->cpts); | 3667 | am65_cpts_release(common->cpts); |
| 3664 | am65_cpsw_disable_serdes_phy(common); | 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 | u8 fid_c1; | 735 | u8 fid_c1; |
| 736 | 736 | ||
| 737 | tbl = prueth->vlan_tbl; | 737 | tbl = prueth->vlan_tbl; |
| 738 | spin_lock(&prueth->vtbl_lock); | ||
| 738 | fid_c1 = tbl[vid].fid_c1; | 739 | fid_c1 = tbl[vid].fid_c1; |
| 739 | 740 | ||
| 740 | /* FID_C1: bit0..2 port membership mask, | 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 | tbl[vid].fid_c1 = fid_c1; | 753 | tbl[vid].fid_c1 = fid_c1; |
| 754 | spin_unlock(&prueth->vtbl_lock); | ||
| 753 | } | 755 | } |
| 754 | EXPORT_SYMBOL_GPL(icssg_vtbl_modify); | 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 | icss_iep_init_fw(prueth->iep1); | 1442 | icss_iep_init_fw(prueth->iep1); |
| 1443 | } | 1443 | } |
| 1444 | 1444 | ||
| 1445 | spin_lock_init(&prueth->vtbl_lock); | ||
| 1445 | /* setup netdev interfaces */ | 1446 | /* setup netdev interfaces */ |
| 1446 | if (eth0_node) { | 1447 | if (eth0_node) { |
| 1447 | ret = prueth_netdev_init(prueth, eth0_node); | 1448 | ret = prueth_netdev_init(prueth, eth0_node); |
| @@ -296,6 +296,8 @@ struct prueth { · 295 unmodified lines | |||
| 296 | bool is_switchmode_supported; | 296 | bool is_switchmode_supported; |
| 297 | unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; | 297 | unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; |
| 298 | int default_vlan; | 298 | int default_vlan; |
| 299 | /** @vtbl_lock: Lock for vtbl in shared memory */ | ||
| 300 | spinlock_t vtbl_lock; | ||
| 299 | }; | 301 | }; |
| 300 | 302 | ||
| 301 | struct emac_tx_ts_response { | 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 | if (net_ratelimit()) | 1051 | if (net_ratelimit()) |
| 1052 | netdev_err(ndev, "TX DMA mapping error\n"); | 1052 | netdev_err(ndev, "TX DMA mapping error\n"); |
| 1053 | ndev->stats.tx_dropped++; | 1053 | ndev->stats.tx_dropped++; |
| 1054 | dev_kfree_skb_any(skb); | ||
| 1054 | return NETDEV_TX_OK; | 1055 | return NETDEV_TX_OK; |
| 1055 | } | 1056 | } |
| 1056 | desc_set_phys_addr(lp, phys, cur_p); | 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 | ndev->stats.tx_dropped++; | 1072 | ndev->stats.tx_dropped++; |
| 1072 | axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1, | 1073 | axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1, |
| 1073 | true, NULL, 0); | 1074 | true, NULL, 0); |
| 1075 | dev_kfree_skb_any(skb); | ||
| 1074 | return NETDEV_TX_OK; | 1076 | return NETDEV_TX_OK; |
| 1075 | } | 1077 | } |
| 1076 | desc_set_phys_addr(lp, phys, cur_p); | 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 | * On Hyper-V, every VF interface is matched with a corresponding | 2827 | * On Hyper-V, every VF interface is matched with a corresponding |
| 2803 | * synthetic interface. The synthetic interface is presented first | 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 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); | 2835 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); |
| 2811 | int ret = 0; | 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 | ret = check_dev_is_matching_vf(event_dev); | 2843 | ret = check_dev_is_matching_vf(event_dev); |
| 2814 | if (ret != 0) | 2844 | if (ret != 0) |
| 2815 | return NOTIFY_DONE; | 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 | return sa; | 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 | static void free_rx_sc_rcu(struct rcu_head *head) | 157 | static void free_rx_sc_rcu(struct rcu_head *head) |
| 171 | { | 158 | { |
| 172 | struct macsec_rx_sc *rx_sc = container_of(head, struct macsec_rx_sc, rcu_head); | 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 | /* If validateFrames is Strict or the C bit in the | 1195 | /* If validateFrames is Strict or the C bit in the |
| 1209 | * SecTAG is set, discard | 1196 | * SecTAG is set, discard |
| 1210 | */ | 1197 | */ |
| 1211 | struct macsec_rx_sa *active_rx_sa = macsec_active_rxsa_get(rx_sc); | ||
| 1212 | if (hdr->tci_an & MACSEC_TCI_C || | 1198 | if (hdr->tci_an & MACSEC_TCI_C || |
| 1213 | secy->validate_frames == MACSEC_VALIDATE_STRICT) { | 1199 | secy->validate_frames == MACSEC_VALIDATE_STRICT) { |
| 1214 | u64_stats_update_begin(&rxsc_stats->syncp); | 1200 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1215 | rxsc_stats->stats.InPktsNotUsingSA++; | 1201 | rxsc_stats->stats.InPktsNotUsingSA++; |
| 1216 | u64_stats_update_end(&rxsc_stats->syncp); | 1202 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1217 | DEV_STATS_INC(secy->netdev, rx_errors); | 1203 | DEV_STATS_INC(secy->netdev, rx_errors); |
| 1218 | if (active_rx_sa) | ||
| 1219 | this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA); | ||
| 1220 | goto drop_nosa; | 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 | u64_stats_update_begin(&rxsc_stats->syncp); | 1210 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1227 | rxsc_stats->stats.InPktsUnusedSA++; | 1211 | rxsc_stats->stats.InPktsUnusedSA++; |
| 1228 | u64_stats_update_end(&rxsc_stats->syncp); | 1212 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1229 | if (active_rx_sa) | ||
| 1230 | this_cpu_inc(active_rx_sa->stats->InPktsUnusedSA); | ||
| 1231 | goto deliver; | 1213 | goto deliver; |
| 1232 | } | 1214 | } |
| 1233 | 1215 | ||
| @@ -337,6 +337,7 @@ static const struct of_device_id unimac_mdio_ids[] = { · 336 unmodified lines | |||
| 337 | { .compatible = "brcm,asp-v2.2-mdio", }, | 337 | { .compatible = "brcm,asp-v2.2-mdio", }, |
| 338 | { .compatible = "brcm,asp-v2.1-mdio", }, | 338 | { .compatible = "brcm,asp-v2.1-mdio", }, |
| 339 | { .compatible = "brcm,asp-v2.0-mdio", }, | 339 | { .compatible = "brcm,asp-v2.0-mdio", }, |
| 340 | { .compatible = "brcm,bcm6846-mdio", }, | ||
| 340 | { .compatible = "brcm,genet-mdio-v5", }, | 341 | { .compatible = "brcm,genet-mdio-v5", }, |
| 341 | { .compatible = "brcm,genet-mdio-v4", }, | 342 | { .compatible = "brcm,genet-mdio-v4", }, |
| 342 | { .compatible = "brcm,genet-mdio-v3", }, | 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 | this_chunk = min(userdata_len - sent_userdata, | 1162 | this_chunk = min(userdata_len - sent_userdata, |
| 1163 | MAX_PRINT_CHUNK - preceding_bytes); | 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 | return; | 1170 | return; |
| 1171 | |||
| 1166 | memcpy(buf + this_header + this_offset, | 1172 | memcpy(buf + this_header + this_offset, |
| 1167 | userdata + sent_userdata, | 1173 | userdata + sent_userdata, |
| 1168 | this_chunk); | 1174 | this_chunk); |
| @@ -836,7 +836,8 @@ static void nsim_dev_trap_report_work(struct work_struct *work) · 835 unmodified lines | |||
| 836 | nsim_dev = nsim_trap_data->nsim_dev; | 836 | nsim_dev = nsim_trap_data->nsim_dev; |
| 837 | 837 | ||
| 838 | if (!devl_trylock(priv_to_devlink(nsim_dev))) { | 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 | return; | 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 | continue; | 849 | continue; |
| 849 | 850 | ||
| 850 | nsim_dev_trap_report(nsim_dev_port); | 851 | nsim_dev_trap_report(nsim_dev_port); |
| 852 | cond_resched(); | ||
| 851 | } | 853 | } |
| 852 | devl_unlock(priv_to_devlink(nsim_dev)); | 854 | devl_unlock(priv_to_devlink(nsim_dev)); |
| 853 | 855 | queue_delayed_work(system_unbound_wq, | |
| 854 | schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, | 856 | &nsim_dev->trap_data->trap_report_dw, |
| 855 | msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | 857 | msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); |
| 856 | } | 858 | } |
| 857 | 859 | ||
| 858 | static int nsim_dev_traps_init(struct devlink *devlink) | 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 | INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw, | 910 | INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw, |
| 909 | nsim_dev_trap_report_work); | 911 | nsim_dev_trap_report_work); |
| 910 | schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, | 912 | queue_delayed_work(system_unbound_wq, |
| 911 | msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | 913 | &nsim_dev->trap_data->trap_report_dw, |
| 914 | msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | ||
| 912 | 915 | ||
| 913 | return 0; | 916 | return 0; |
| 914 | 917 | ||
| @@ -537,12 +537,6 @@ static int aqcs109_config_init(struct phy_device *phydev) · 536 unmodified lines | |||
| 537 | if (!ret) | 537 | if (!ret) |
| 538 | aqr107_chip_info(phydev); | 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 | return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); | 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 | return aqr107_fill_interface_modes(phydev); | 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 | static int aqr113c_config_init(struct phy_device *phydev) | 753 | static int aqr113c_config_init(struct phy_device *phydev) |
| 735 | { | 754 | { |
| 736 | int ret; | 755 | int ret; |
| @@ -767,15 +786,6 @@ static int aqr107_probe(struct phy_device *phydev) · 30 unmodified lines | |||
| 767 | return aqr_hwmon_probe(phydev); | 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 | static struct phy_driver aqr_driver[] = { | 790 | static struct phy_driver aqr_driver[] = { |
| 781 | { | 791 | { |
| @@ -853,6 +863,7 @@ static struct phy_driver aqr_driver[] = { · 71 unmodified lines | |||
| 853 | .get_sset_count = aqr107_get_sset_count, | 863 | .get_sset_count = aqr107_get_sset_count, |
| 854 | .get_strings = aqr107_get_strings, | 864 | .get_strings = aqr107_get_strings, |
| 855 | .get_stats = aqr107_get_stats, | 865 | .get_stats = aqr107_get_stats, |
| 866 | .get_features = aqr115c_get_features, | ||
| 856 | .link_change_notify = aqr107_link_change_notify, | 867 | .link_change_notify = aqr107_link_change_notify, |
| 857 | .led_brightness_set = aqr_phy_led_brightness_set, | 868 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 858 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | .name = "Aquantia AQR111", | 876 | .name = "Aquantia AQR111", |
| 866 | .probe = aqr107_probe, | 877 | .probe = aqr107_probe, |
| 867 | .get_rate_matching = aqr107_get_rate_matching, | 878 | .get_rate_matching = aqr107_get_rate_matching, |
| 868 | .config_init = aqr111_config_init, | 879 | .config_init = aqr107_config_init, |
| 869 | .config_aneg = aqr_config_aneg, | 880 | .config_aneg = aqr_config_aneg, |
| 870 | .config_intr = aqr_config_intr, | 881 | .config_intr = aqr_config_intr, |
| 871 | .handle_interrupt = aqr_handle_interrupt, | 882 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -877,6 +888,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | |||
| 877 | .get_sset_count = aqr107_get_sset_count, | 888 | .get_sset_count = aqr107_get_sset_count, |
| 878 | .get_strings = aqr107_get_strings, | 889 | .get_strings = aqr107_get_strings, |
| 879 | .get_stats = aqr107_get_stats, | 890 | .get_stats = aqr107_get_stats, |
| 891 | .get_features = aqr111_get_features, | ||
| 880 | .link_change_notify = aqr107_link_change_notify, | 892 | .link_change_notify = aqr107_link_change_notify, |
| 881 | .led_brightness_set = aqr_phy_led_brightness_set, | 893 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 882 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | .name = "Aquantia AQR111B0", | 901 | .name = "Aquantia AQR111B0", |
| 890 | .probe = aqr107_probe, | 902 | .probe = aqr107_probe, |
| 891 | .get_rate_matching = aqr107_get_rate_matching, | 903 | .get_rate_matching = aqr107_get_rate_matching, |
| 892 | .config_init = aqr111_config_init, | 904 | .config_init = aqr107_config_init, |
| 893 | .config_aneg = aqr_config_aneg, | 905 | .config_aneg = aqr_config_aneg, |
| 894 | .config_intr = aqr_config_intr, | 906 | .config_intr = aqr_config_intr, |
| 895 | .handle_interrupt = aqr_handle_interrupt, | 907 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -901,6 +913,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | |||
| 901 | .get_sset_count = aqr107_get_sset_count, | 913 | .get_sset_count = aqr107_get_sset_count, |
| 902 | .get_strings = aqr107_get_strings, | 914 | .get_strings = aqr107_get_strings, |
| 903 | .get_stats = aqr107_get_stats, | 915 | .get_stats = aqr107_get_stats, |
| 916 | .get_features = aqr111_get_features, | ||
| 904 | .link_change_notify = aqr107_link_change_notify, | 917 | .link_change_notify = aqr107_link_change_notify, |
| 905 | .led_brightness_set = aqr_phy_led_brightness_set, | 918 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 906 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | .name = "Aquantia AQR114C", | 1023 | .name = "Aquantia AQR114C", |
| 1011 | .probe = aqr107_probe, | 1024 | .probe = aqr107_probe, |
| 1012 | .get_rate_matching = aqr107_get_rate_matching, | 1025 | .get_rate_matching = aqr107_get_rate_matching, |
| 1013 | .config_init = aqr111_config_init, | 1026 | .config_init = aqr107_config_init, |
| 1014 | .config_aneg = aqr_config_aneg, | 1027 | .config_aneg = aqr_config_aneg, |
| 1015 | .config_intr = aqr_config_intr, | 1028 | .config_intr = aqr_config_intr, |
| 1016 | .handle_interrupt = aqr_handle_interrupt, | 1029 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -1022,6 +1035,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | |||
| 1022 | .get_sset_count = aqr107_get_sset_count, | 1035 | .get_sset_count = aqr107_get_sset_count, |
| 1023 | .get_strings = aqr107_get_strings, | 1036 | .get_strings = aqr107_get_strings, |
| 1024 | .get_stats = aqr107_get_stats, | 1037 | .get_stats = aqr107_get_stats, |
| 1038 | .get_features = aqr111_get_features, | ||
| 1025 | .link_change_notify = aqr107_link_change_notify, | 1039 | .link_change_notify = aqr107_link_change_notify, |
| 1026 | .led_brightness_set = aqr_phy_led_brightness_set, | 1040 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 1027 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | .get_sset_count = aqr107_get_sset_count, | 1060 | .get_sset_count = aqr107_get_sset_count, |
| 1047 | .get_strings = aqr107_get_strings, | 1061 | .get_strings = aqr107_get_strings, |
| 1048 | .get_stats = aqr107_get_stats, | 1062 | .get_stats = aqr107_get_stats, |
| 1063 | .get_features = aqr115c_get_features, | ||
| 1049 | .link_change_notify = aqr107_link_change_notify, | 1064 | .link_change_notify = aqr107_link_change_notify, |
| 1050 | .led_brightness_set = aqr_phy_led_brightness_set, | 1065 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 1051 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); | 133 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); |
| 134 | if (bmsr < 0) | 134 | if (bmsr < 0) |
| 135 | return val; | 135 | return bmsr; |
| 136 | 136 | ||
| 137 | return !!(val & MDIO_AN_STAT1_COMPLETE) && | 137 | return !!(val & MDIO_AN_STAT1_COMPLETE) && |
| 138 | !!(bmsr & BMSR_ANEGCOMPLETE); | 138 | !!(bmsr & BMSR_ANEGCOMPLETE); |
| @@ -158,7 +158,7 @@ static int bcm84881_read_status(struct phy_device *phydev) · 19 unmodified lines | |||
| 158 | 158 | ||
| 159 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); | 159 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); |
| 160 | if (bmsr < 0) | 160 | if (bmsr < 0) |
| 161 | return val; | 161 | return bmsr; |
| 162 | 162 | ||
| 163 | phydev->autoneg_complete = !!(val & MDIO_AN_STAT1_COMPLETE) && | 163 | phydev->autoneg_complete = !!(val & MDIO_AN_STAT1_COMPLETE) && |
| 164 | !!(bmsr & BMSR_ANEGCOMPLETE); | 164 | !!(bmsr & BMSR_ANEGCOMPLETE); |
| @@ -45,8 +45,8 @@ · 44 unmodified lines | |||
| 45 | /* Control Register 2 bits */ | 45 | /* Control Register 2 bits */ |
| 46 | #define DP83822_FX_ENABLE BIT(14) | 46 | #define DP83822_FX_ENABLE BIT(14) |
| 47 | 47 | ||
| 48 | #define DP83822_HW_RESET BIT(15) | 48 | #define DP83822_SW_RESET BIT(15) |
| 49 | #define DP83822_SW_RESET BIT(14) | 49 | #define DP83822_DIG_RESTART BIT(14) |
| 50 | 50 | ||
| 51 | /* PHY STS bits */ | 51 | /* PHY STS bits */ |
| 52 | #define DP83822_PHYSTS_DUPLEX BIT(2) | 52 | #define DP83822_PHYSTS_DUPLEX BIT(2) |
| @@ -645,7 +645,6 @@ static int dp83869_configure_fiber(struct phy_device *phydev, · 644 unmodified lines | |||
| 645 | phydev->supported); | 645 | phydev->supported); |
| 646 | 646 | ||
| 647 | linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); | 647 | linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); |
| 648 | linkmode_set_bit(ADVERTISED_FIBRE, phydev->advertising); | ||
| 649 | 648 | ||
| 650 | if (dp83869->mode == DP83869_RGMII_1000_BASE) { | 649 | if (dp83869->mode == DP83869_RGMII_1000_BASE) { |
| 651 | linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, | 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 | static void phy_leds_unregister(struct phy_device *phydev) | 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 | led_classdev_unregister(&phyled->led_cdev); | 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 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); | 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 | static int rtlgen_resume(struct phy_device *phydev) | 1094 | static int rtlgen_resume(struct phy_device *phydev) |
| 1085 | { | 1095 | { |
| 1086 | int ret = genphy_resume(phydev); | 1096 | int ret = genphy_resume(phydev); |
| @@ -1418,7 +1428,7 @@ static struct phy_driver realtek_drvs[] = { · 331 unmodified lines | |||
| 1418 | .suspend = genphy_c45_pma_suspend, | 1428 | .suspend = genphy_c45_pma_suspend, |
| 1419 | .resume = rtlgen_c45_resume, | 1429 | .resume = rtlgen_c45_resume, |
| 1420 | }, { | 1430 | }, { |
| 1421 | PHY_ID_MATCH_EXACT(0x001cc862), | 1431 | .match_phy_device = rtl8251b_c45_match_phy_device, |
| 1422 | .name = "RTL8251B 5Gbps PHY", | 1432 | .name = "RTL8251B 5Gbps PHY", |
| 1423 | .get_features = rtl822x_get_features, | 1433 | .get_features = rtl822x_get_features, |
| 1424 | .config_aneg = rtl822x_config_aneg, | 1434 | .config_aneg = rtl822x_config_aneg, |
| @@ -1427,6 +1437,18 @@ static struct phy_driver realtek_drvs[] = { · 2 unmodified lines | |||
| 1427 | .resume = rtlgen_resume, | 1437 | .resume = rtlgen_resume, |
| 1428 | .read_page = rtl821x_read_page, | 1438 | .read_page = rtl821x_read_page, |
| 1429 | .write_page = rtl821x_write_page, | 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 | PHY_ID_MATCH_EXACT(0x001ccad0), | 1453 | PHY_ID_MATCH_EXACT(0x001ccad0), |
| 1432 | .name = "RTL8224 2.5Gbps PHY", | 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 | return HS_TIMEOUT; | 815 | return HS_TIMEOUT; |
| 816 | } | 816 | } |
| 817 | } | 817 | } |
| 818 | break; | 818 | fallthrough; |
| 819 | 819 | ||
| 820 | case PLIP_PK_LENGTH_LSB: | 820 | case PLIP_PK_LENGTH_LSB: |
| 821 | if (plip_send(nibble_timeout, dev, | 821 | if (plip_send(nibble_timeout, dev, |
| @@ -542,7 +542,7 @@ ppp_async_encode(struct asyncppp *ap) · 541 unmodified lines | |||
| 542 | * and 7 (code-reject) must be sent as though no options | 542 | * and 7 (code-reject) must be sent as though no options |
| 543 | * had been negotiated. | 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 | if (i == 0) { | 547 | if (i == 0) { |
| 548 | if (islcp) | 548 | if (islcp) |
| @@ -113,7 +113,7 @@ static void pse_release_pis(struct pse_controller_dev *pcdev) · 112 unmodified lines | |||
| 113 | { | 113 | { |
| 114 | int i; | 114 | int i; |
| 115 | 115 | ||
| 116 | for (i = 0; i <= pcdev->nr_lines; i++) { | 116 | for (i = 0; i < pcdev->nr_lines; i++) { |
| 117 | of_node_put(pcdev->pi[i].pairset[0].np); | 117 | of_node_put(pcdev->pi[i].pairset[0].np); |
| 118 | of_node_put(pcdev->pi[i].pairset[1].np); | 118 | of_node_put(pcdev->pi[i].pairset[1].np); |
| 119 | of_node_put(pcdev->pi[i].np); | 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 | int i; | 648 | int i; |
| 649 | 649 | ||
| 650 | for (i = 0; i <= pcdev->nr_lines; i++) { | 650 | for (i = 0; i < pcdev->nr_lines; i++) { |
| 651 | if (pcdev->pi[i].np == np) | 651 | if (pcdev->pi[i].np == np) |
| 652 | return i; | 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 | switch (config->c33_admin_control) { | 786 | switch (config->c33_admin_control) { |
| 787 | case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED: | 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 | if (!psec->pcdev->pi[psec->id].admin_state_enabled) | 799 | if (!psec->pcdev->pi[psec->id].admin_state_enabled) |
| 789 | err = regulator_enable(psec->ps); | 800 | err = regulator_enable(psec->ps); |
| 790 | break; | 801 | break; |
| @@ -643,46 +643,57 @@ bad: · 642 unmodified lines | |||
| 643 | int | 643 | int |
| 644 | slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) | 644 | slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) |
| 645 | { | 645 | { |
| 646 | struct cstate *cs; | 646 | const struct tcphdr *th; |
| 647 | unsigned ihl; | ||
| 648 | |||
| 649 | unsigned char index; | 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 | comp->sls_i_runt++; | 657 | comp->sls_i_runt++; |
| 654 | return slhc_toss( comp ); | 658 | return slhc_toss(comp); |
| 655 | } | 659 | } |
| 660 | iph = (struct iphdr *)icp; | ||
| 656 | /* Peek at the IP header's IHL field to find its length */ | 661 | /* Peek at the IP header's IHL field to find its length */ |
| 657 | ihl = icp[0] & 0xf; | 662 | ihl = iph->ihl; |
| 658 | if(ihl < 20 / 4){ | 663 | /* The IP header length field is too small, |
| 659 | /* The IP header length field is too small */ | 664 | * or packet is shorter than the IP header followed |
| 660 | comp->sls_i_runt++; | 665 | * by minimal tcp header. |
| 661 | return slhc_toss( comp ); | 666 | */ |
| 662 | } | 667 | if (ihl < 5 || isize < ihl * 4 + sizeof(struct tcphdr)) |
| 663 | index = icp[9]; | 668 | goto runt; |
| 664 | icp[9] = IPPROTO_TCP; | 669 | |
| 670 | index = iph->protocol; | ||
| 671 | iph->protocol = IPPROTO_TCP; | ||
| 665 | 672 | ||
| 666 | if (ip_fast_csum(icp, ihl)) { | 673 | if (ip_fast_csum(icp, ihl)) { |
| 667 | /* Bad IP header checksum; discard */ | 674 | /* Bad IP header checksum; discard */ |
| 668 | comp->sls_i_badcheck++; | 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 | comp->sls_i_error++; | 679 | comp->sls_i_error++; |
| 673 | return slhc_toss(comp); | 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 | /* Update local state */ | 687 | /* Update local state */ |
| 677 | cs = &comp->rstate[comp->recv_current = index]; | 688 | cs = &comp->rstate[comp->recv_current = index]; |
| 678 | comp->flags &=~ SLF_TOSS; | 689 | comp->flags &=~ SLF_TOSS; |
| 679 | memcpy(&cs->cs_ip,icp,20); | 690 | memcpy(&cs->cs_ip, iph, sizeof(*iph)); |
| 680 | memcpy(&cs->cs_tcp,icp + ihl*4,20); | 691 | memcpy(&cs->cs_tcp, th, sizeof(*th)); |
| 681 | if (ihl > 5) | 692 | if (ihl > 5) |
| 682 | memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); | 693 | memcpy(cs->cs_ipopt, &iph[1], (ihl - 5) * 4); |
| 683 | if (cs->cs_tcp.doff > 5) | 694 | if (th->doff > 5) |
| 684 | memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); | 695 | memcpy(cs->cs_tcpopt, &th[1], (th->doff - 5) * 4); |
| 685 | cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; | 696 | cs->cs_hsize = ihl*2 + th->doff*2; |
| 686 | cs->initialized = true; | 697 | cs->initialized = true; |
| 687 | /* Put headers back on packet | 698 | /* Put headers back on packet |
| 688 | * Neither header checksum is recalculated | 699 | * Neither header checksum is recalculated |
| @@ -1426,6 +1426,7 @@ static const struct usb_device_id products[] = { · 1425 unmodified lines | |||
| 1426 | {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ | 1426 | {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ |
| 1427 | {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ | 1427 | {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ |
| 1428 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ | 1428 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ |
| 1429 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0112, 0)}, /* Fibocom FG132 */ | ||
| 1429 | {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ | 1430 | {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ |
| 1430 | {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ | 1431 | {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ |
| 1431 | {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ | 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 | // can rename the link if it knows better. | 1767 | // can rename the link if it knows better. |
| 1768 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && | 1768 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && |
| 1769 | ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || | 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 | strscpy(net->name, "eth%d", sizeof(net->name)); | 1772 | strscpy(net->name, "eth%d", sizeof(net->name)); |
| 1772 | /* WLAN devices should always be named "wlan%d" */ | 1773 | /* WLAN devices should always be named "wlan%d" */ |
| 1773 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) | 1774 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) |
| @@ -1870,6 +1871,7 @@ out1: · 96 unmodified lines | |||
| 1870 | * may trigger an error resubmitting itself and, worse, | 1871 | * may trigger an error resubmitting itself and, worse, |
| 1871 | * schedule a timer. So we kill it all just in case. | 1872 | * schedule a timer. So we kill it all just in case. |
| 1872 | */ | 1873 | */ |
| 1874 | usbnet_mark_going_away(dev); | ||
| 1873 | cancel_work_sync(&dev->kevent); | 1875 | cancel_work_sync(&dev->kevent); |
| 1874 | del_timer_sync(&dev->delay); | 1876 | del_timer_sync(&dev->delay); |
| 1875 | free_netdev(net); | 1877 | free_netdev(net); |
| @@ -4155,7 +4155,7 @@ struct virtnet_stats_ctx { · 4154 unmodified lines | |||
| 4155 | u32 desc_num[3]; | 4155 | u32 desc_num[3]; |
| 4156 | 4156 | ||
| 4157 | /* The actual supported stat types. */ | 4157 | /* The actual supported stat types. */ |
| 4158 | u32 bitmap[3]; | 4158 | u64 bitmap[3]; |
| 4159 | 4159 | ||
| 4160 | /* Used to calculate the reply buffer size. */ | 4160 | /* Used to calculate the reply buffer size. */ |
| 4161 | u32 size[3]; | 4161 | u32 size[3]; |
| @@ -148,7 +148,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, · 147 unmodified lines | |||
| 148 | } else { /* XDP buffer from page pool */ | 148 | } else { /* XDP buffer from page pool */ |
| 149 | page = virt_to_page(xdpf->data); | 149 | page = virt_to_page(xdpf->data); |
| 150 | tbi->dma_addr = page_pool_get_dma_addr(page) + | 150 | tbi->dma_addr = page_pool_get_dma_addr(page) + |
| 151 | VMXNET3_XDP_HEADROOM; | 151 | (xdpf->data - (void *)xdpf); |
| 152 | dma_sync_single_for_device(&adapter->pdev->dev, | 152 | dma_sync_single_for_device(&adapter->pdev->dev, |
| 153 | tbi->dma_addr, buf_size, | 153 | tbi->dma_addr, buf_size, |
| 154 | DMA_TO_DEVICE); | 154 | DMA_TO_DEVICE); |
| @@ -4913,9 +4913,13 @@ static int __init vxlan_init_module(void) · 4912 unmodified lines | |||
| 4913 | if (rc) | 4913 | if (rc) |
| 4914 | goto out4; | 4914 | goto out4; |
| 4915 | 4915 | ||
| 4916 | vxlan_vnifilter_init(); | 4916 | rc = vxlan_vnifilter_init(); |
| 4917 | if (rc) | ||
| 4918 | goto out5; | ||
| 4917 | 4919 | ||
| 4918 | return 0; | 4920 | return 0; |
| 4921 | out5: | ||
| 4922 | rtnl_link_unregister(&vxlan_link_ops); | ||
| 4919 | out4: | 4923 | out4: |
| 4920 | unregister_switchdev_notifier(&vxlan_switchdev_notifier_block); | 4924 | unregister_switchdev_notifier(&vxlan_switchdev_notifier_block); |
| 4921 | out3: | 4925 | out3: |
| @@ -202,7 +202,7 @@ int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan, · 201 unmodified lines | |||
| 202 | int vxlan_vnigroup_init(struct vxlan_dev *vxlan); | 202 | int vxlan_vnigroup_init(struct vxlan_dev *vxlan); |
| 203 | void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan); | 203 | void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan); |
| 204 | 204 | ||
| 205 | void vxlan_vnifilter_init(void); | 205 | int vxlan_vnifilter_init(void); |
| 206 | void vxlan_vnifilter_uninit(void); | 206 | void vxlan_vnifilter_uninit(void); |
| 207 | void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni, | 207 | void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni, |
| 208 | struct vxlan_vni_node *vninode, | 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 | return err; | 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, | 1003 | return rtnl_register_many(vxlan_vnifilter_rtnl_msg_handlers); |
| 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 | } | 1004 | } |
| 1004 | 1005 | ||
| 1005 | void vxlan_vnifilter_uninit(void) | 1006 | void vxlan_vnifilter_uninit(void) |
| 1006 | { | 1007 | { |
| 1007 | rtnl_unregister(PF_BRIDGE, RTM_GETTUNNEL); | 1008 | rtnl_unregister_many(vxlan_vnifilter_rtnl_msg_handlers); |
| 1008 | rtnl_unregister(PF_BRIDGE, RTM_NEWTUNNEL); | ||
| 1009 | rtnl_unregister(PF_BRIDGE, RTM_DELTUNNEL); | ||
| 1010 | } | 1009 | } |
| @@ -1038,7 +1038,7 @@ static const struct nla_policy wwan_rtnl_policy[IFLA_WWAN_MAX + 1] = { · 1037 unmodified lines | |||
| 1038 | 1038 | ||
| 1039 | static struct rtnl_link_ops wwan_rtnl_link_ops __read_mostly = { | 1039 | static struct rtnl_link_ops wwan_rtnl_link_ops __read_mostly = { |
| 1040 | .kind = "wwan", | 1040 | .kind = "wwan", |
| 1041 | .maxtype = __IFLA_WWAN_MAX, | 1041 | .maxtype = IFLA_WWAN_MAX, |
| 1042 | .alloc = wwan_rtnl_alloc, | 1042 | .alloc = wwan_rtnl_alloc, |
| 1043 | .validate = wwan_rtnl_validate, | 1043 | .validate = wwan_rtnl_validate, |
| 1044 | .newlink = wwan_rtnl_newlink, | 1044 | .newlink = wwan_rtnl_newlink, |
| @@ -1292,14 +1292,12 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl) · 1291 unmodified lines | |||
| 1292 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); | 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, | 1295 | static void nvme_keep_alive_finish(struct request *rq, |
| 1296 | blk_status_t status) | 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 | unsigned long rtt = jiffies - (rq->deadline - rq->timeout); | 1298 | unsigned long rtt = jiffies - (rq->deadline - rq->timeout); |
| 1302 | unsigned long delay = nvme_keep_alive_work_period(ctrl); | 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 | * Subtract off the keepalive RTT so nvme_keep_alive_work runs | 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 | delay = 0; | 1311 | delay = 0; |
| 1314 | } | 1312 | } |
| 1315 | 1313 | ||
| 1316 | blk_mq_free_request(rq); | ||
| 1317 | |||
| 1318 | if (status) { | 1314 | if (status) { |
| 1319 | dev_err(ctrl->device, | 1315 | dev_err(ctrl->device, |
| 1320 | "failed nvme_keep_alive_end_io error=%d\n", | 1316 | "failed nvme_keep_alive_end_io error=%d\n", |
| 1321 | status); | 1317 | status); |
| 1322 | return RQ_END_IO_NONE; | 1318 | return; |
| 1323 | } | 1319 | } |
| 1324 | 1320 | ||
| 1325 | ctrl->ka_last_check_time = jiffies; | 1321 | ctrl->ka_last_check_time = jiffies; |
| 1326 | ctrl->comp_seen = false; | 1322 | ctrl->comp_seen = false; |
| 1327 | spin_lock_irqsave(&ctrl->lock, flags); | 1323 | if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING) |
| 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) | ||
| 1333 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); | 1324 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); |
| 1334 | return RQ_END_IO_NONE; | ||
| 1335 | } | 1325 | } |
| 1336 | 1326 | ||
| 1337 | static void nvme_keep_alive_work(struct work_struct *work) | 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 | struct nvme_ctrl, ka_work); | 1330 | struct nvme_ctrl, ka_work); |
| 1341 | bool comp_seen = ctrl->comp_seen; | 1331 | bool comp_seen = ctrl->comp_seen; |
| 1342 | struct request *rq; | 1332 | struct request *rq; |
| 1333 | blk_status_t status; | ||
| 1343 | 1334 | ||
| 1344 | ctrl->ka_last_check_time = jiffies; | 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 | nvme_init_request(rq, &ctrl->ka_cmd); | 1353 | nvme_init_request(rq, &ctrl->ka_cmd); |
| 1363 | 1354 | ||
| 1364 | rq->timeout = ctrl->kato * HZ; | 1355 | rq->timeout = ctrl->kato * HZ; |
| 1365 | rq->end_io = nvme_keep_alive_end_io; | 1356 | status = blk_execute_rq(rq, false); |
| 1366 | rq->end_io_data = ctrl; | 1357 | nvme_keep_alive_finish(rq, status, ctrl); |
| 1367 | blk_execute_rq_nowait(rq, false); | 1358 | blk_mq_free_request(rq); |
| 1368 | } | 1359 | } |
| 1369 | 1360 | ||
| 1370 | static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) | 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 | else | 2449 | else |
| 2459 | ctrl->ctrl_config = NVME_CC_CSS_NVM; | 2450 | ctrl->ctrl_config = NVME_CC_CSS_NVM; |
| 2460 | 2451 | ||
| 2461 | if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS) | 2452 | /* |
| 2462 | ctrl->ctrl_config |= NVME_CC_CRIME; | 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 | ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; | 2460 | ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; |
| 2465 | ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; | 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 | * devices are known to get this wrong. Use the larger of the | 2485 | * devices are known to get this wrong. Use the larger of the |
| 2490 | * two values. | 2486 | * two values. |
| 2491 | */ | 2487 | */ |
| 2492 | if (ctrl->ctrl_config & NVME_CC_CRIME) | 2488 | ready_timeout = NVME_CRTO_CRWMT(crto); |
| 2493 | ready_timeout = NVME_CRTO_CRIMT(crto); | ||
| 2494 | else | ||
| 2495 | ready_timeout = NVME_CRTO_CRWMT(crto); | ||
| 2496 | 2489 | ||
| 2497 | if (ready_timeout < timeout) | 2490 | if (ready_timeout < timeout) |
| 2498 | dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n", | 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 | case NVME_CTRL_LIVE: | 431 | case NVME_CTRL_LIVE: |
| 432 | case NVME_CTRL_RESETTING: | 432 | case NVME_CTRL_RESETTING: |
| 433 | case NVME_CTRL_CONNECTING: | 433 | case NVME_CTRL_CONNECTING: |
| 434 | /* fallthru */ | ||
| 435 | return true; | 434 | return true; |
| 436 | default: | 435 | default: |
| 437 | break; | 436 | break; |
| @@ -580,6 +579,20 @@ static int nvme_add_ns_head_cdev(struct nvme_ns_head *head) · 142 unmodified lines | |||
| 580 | return ret; | 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 | static void nvme_requeue_work(struct work_struct *work) | 596 | static void nvme_requeue_work(struct work_struct *work) |
| 584 | { | 597 | { |
| 585 | struct nvme_ns_head *head = | 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 | bio_list_init(&head->requeue_list); | 619 | bio_list_init(&head->requeue_list); |
| 607 | spin_lock_init(&head->requeue_lock); | 620 | spin_lock_init(&head->requeue_lock); |
| 608 | INIT_WORK(&head->requeue_work, nvme_requeue_work); | 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 | * Add a multipath node if the subsystems supports multiple controllers. | 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 | return PTR_ERR(head->disk); | 643 | return PTR_ERR(head->disk); |
| 630 | head->disk->fops = &nvme_ns_head_ops; | 644 | head->disk->fops = &nvme_ns_head_ops; |
| 631 | head->disk->private_data = head; | 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 | sprintf(head->disk->disk_name, "nvme%dn%d", | 656 | sprintf(head->disk->disk_name, "nvme%dn%d", |
| 633 | ctrl->subsys->instance, head->instance); | 657 | ctrl->subsys->instance, head->instance); |
| 634 | return 0; | 658 | return 0; |
| @@ -655,6 +679,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) · 20 unmodified lines | |||
| 655 | return; | 679 | return; |
| 656 | } | 680 | } |
| 657 | nvme_add_ns_head_cdev(head); | 681 | nvme_add_ns_head_cdev(head); |
| 682 | kblockd_schedule_work(&head->partition_scan_work); | ||
| 658 | } | 683 | } |
| 659 | 684 | ||
| 660 | mutex_lock(&head->lock); | 685 | mutex_lock(&head->lock); |
| @@ -974,14 +999,14 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head) · 313 unmodified lines | |||
| 974 | return; | 999 | return; |
| 975 | if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { | 1000 | if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { |
| 976 | nvme_cdev_del(&head->cdev, &head->cdev_device); | 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 | del_gendisk(head->disk); | 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 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) | 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 | /* make sure all pending bios are cleaned up */ | 1016 | /* make sure all pending bios are cleaned up */ |
| 992 | kblockd_schedule_work(&head->requeue_work); | 1017 | kblockd_schedule_work(&head->requeue_work); |
| 993 | flush_work(&head->requeue_work); | 1018 | flush_work(&head->requeue_work); |
| 1019 | flush_work(&head->partition_scan_work); | ||
| 994 | put_disk(head->disk); | 1020 | put_disk(head->disk); |
| 995 | } | 1021 | } |
| 996 | 1022 | ||
| @@ -494,6 +494,7 @@ struct nvme_ns_head { · 493 unmodified lines | |||
| 494 | struct bio_list requeue_list; | 494 | struct bio_list requeue_list; |
| 495 | spinlock_t requeue_lock; | 495 | spinlock_t requeue_lock; |
| 496 | struct work_struct requeue_work; | 496 | struct work_struct requeue_work; |
| 497 | struct work_struct partition_scan_work; | ||
| 497 | struct mutex lock; | 498 | struct mutex lock; |
| 498 | unsigned long flags; | 499 | unsigned long flags; |
| 499 | #define NVME_NSHEAD_DISK_LIVE 0 | 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 | return 1; | 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 | if (!dev->ctrl.tagset) { | 2511 | if (!dev->ctrl.tagset) { |
| 2512 | nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, | 2512 | nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, |
| 2513 | nvme_pci_nr_maps(dev), sizeof(struct nvme_iod)); | 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 | blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); | 2527 | blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); |
| 2518 | /* free previously allocated queues that are no longer usable */ | 2528 | /* free previously allocated queues that are no longer usable */ |
| 2519 | nvme_free_queues(dev, dev->online_queues); | 2529 | nvme_free_queues(dev, dev->online_queues); |
| 2530 | mutex_unlock(&dev->shutdown_lock); | ||
| 2531 | return true; | ||
| 2520 | } | 2532 | } |
| 2521 | 2533 | ||
| 2522 | static int nvme_pci_enable(struct nvme_dev *dev) | 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 | nvme_dbbuf_set(dev); | 2809 | nvme_dbbuf_set(dev); |
| 2798 | nvme_unquiesce_io_queues(&dev->ctrl); | 2810 | nvme_unquiesce_io_queues(&dev->ctrl); |
| 2799 | nvme_wait_freeze(&dev->ctrl); | 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 | nvme_unfreeze(&dev->ctrl); | 2814 | nvme_unfreeze(&dev->ctrl); |
| 2802 | } else { | 2815 | } else { |
| 2803 | dev_warn(dev->ctrl.device, "IO queues lost\n"); | 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 | len = nvmf_get_address(ctrl, buf, size); | 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 | mutex_lock(&queue->queue_lock); | 2650 | mutex_lock(&queue->queue_lock); |
| 2648 | 2651 | ||
| 2649 | if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags)) | ||
| 2650 | goto done; | ||
| 2651 | ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr); | 2652 | ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr); |
| 2652 | if (ret > 0) { | 2653 | if (ret > 0) { |
| 2653 | if (len > 0) | 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 | len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n", | 2656 | len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n", |
| 2656 | (len) ? "," : "", &src_addr); | 2657 | (len) ? "," : "", &src_addr); |
| 2657 | } | 2658 | } |
| 2658 | done: | 2659 | |
| 2659 | mutex_unlock(&queue->queue_lock); | 2660 | mutex_unlock(&queue->queue_lock); |
| 2660 | 2661 | ||
| 2661 | return len; | 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 | if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags)) | 266 | if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags)) |
| 267 | return; | 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 | nvmet_sq_destroy(&ctrl->queues[0].nvme_sq); | 275 | nvmet_sq_destroy(&ctrl->queues[0].nvme_sq); |
| 269 | nvme_remove_admin_tag_set(&ctrl->ctrl); | 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 | nvmet_sq_destroy(&ctrl->queues[i].nvme_sq); | 304 | nvmet_sq_destroy(&ctrl->queues[i].nvme_sq); |
| 298 | } | 305 | } |
| 299 | ctrl->ctrl.queue_count = 1; | 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 | static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl) | 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 | break; | 535 | break; |
| 536 | case nvme_admin_identify: | 536 | case nvme_admin_identify: |
| 537 | switch (req->cmd->identify.cns) { | 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 | case NVME_ID_CNS_CS_CTRL: | 538 | case NVME_ID_CNS_CS_CTRL: |
| 543 | switch (req->cmd->identify.csi) { | 539 | switch (req->cmd->identify.csi) { |
| 544 | case NVME_CSI_ZNS: | 540 | case NVME_CSI_ZNS: |
| @@ -547,7 +543,9 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) · 2 unmodified lines | |||
| 547 | return NVME_SC_SUCCESS; | 543 | return NVME_SC_SUCCESS; |
| 548 | } | 544 | } |
| 549 | return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; | 545 | return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; |
| 546 | case NVME_ID_CNS_CTRL: | ||
| 550 | case NVME_ID_CNS_NS: | 547 | case NVME_ID_CNS_NS: |
| 548 | case NVME_ID_CNS_NS_DESC_LIST: | ||
| 551 | req->execute = nvmet_passthru_execute_cmd; | 549 | req->execute = nvmet_passthru_execute_cmd; |
| 552 | req->p.use_workqueue = true; | 550 | req->p.use_workqueue = true; |
| 553 | return NVME_SC_SUCCESS; | 551 | return NVME_SC_SUCCESS; |
| @@ -39,6 +39,8 @@ · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | #define NVMET_RDMA_BACKLOG 128 | 40 | #define NVMET_RDMA_BACKLOG 128 |
| 41 | 41 | ||
| 42 | #define NVMET_RDMA_DISCRETE_RSP_TAG -1 | ||
| 43 | |||
| 42 | struct nvmet_rdma_srq; | 44 | struct nvmet_rdma_srq; |
| 43 | 45 | ||
| 44 | struct nvmet_rdma_cmd { | 46 | struct nvmet_rdma_cmd { |
| @@ -75,7 +77,7 @@ struct nvmet_rdma_rsp { · 30 unmodified lines | |||
| 75 | u32 invalidate_rkey; | 77 | u32 invalidate_rkey; |
| 76 | 78 | ||
| 77 | struct list_head wait_list; | 79 | struct list_head wait_list; |
| 78 | struct list_head free_list; | 80 | int tag; |
| 79 | }; | 81 | }; |
| 80 | 82 | ||
| 81 | enum nvmet_rdma_queue_state { | 83 | enum nvmet_rdma_queue_state { |
| @@ -98,8 +100,7 @@ struct nvmet_rdma_queue { · 16 unmodified lines | |||
| 98 | struct nvmet_sq nvme_sq; | 100 | struct nvmet_sq nvme_sq; |
| 99 | 101 | ||
| 100 | struct nvmet_rdma_rsp *rsps; | 102 | struct nvmet_rdma_rsp *rsps; |
| 101 | struct list_head free_rsps; | 103 | struct sbitmap rsp_tags; |
| 102 | spinlock_t rsps_lock; | ||
| 103 | struct nvmet_rdma_cmd *cmds; | 104 | struct nvmet_rdma_cmd *cmds; |
| 104 | 105 | ||
| 105 | struct work_struct release_work; | 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 | static void nvmet_rdma_free_rsp(struct nvmet_rdma_device *ndev, | 173 | static void nvmet_rdma_free_rsp(struct nvmet_rdma_device *ndev, |
| 173 | struct nvmet_rdma_rsp *r); | 174 | struct nvmet_rdma_rsp *r); |
| 174 | static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, | 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 | static const struct nvmet_fabrics_ops nvmet_rdma_ops; | 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 | static inline struct nvmet_rdma_rsp * | 212 | static inline struct nvmet_rdma_rsp * |
| 211 | nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) | 213 | nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) |
| 212 | { | 214 | { |
| 213 | struct nvmet_rdma_rsp *rsp; | 215 | struct nvmet_rdma_rsp *rsp = NULL; |
| 214 | unsigned long flags; | 216 | int tag; |
| 215 | 217 | ||
| 216 | spin_lock_irqsave(&queue->rsps_lock, flags); | 218 | tag = sbitmap_get(&queue->rsp_tags); |
| 217 | rsp = list_first_entry_or_null(&queue->free_rsps, | 219 | if (tag >= 0) |
| 218 | struct nvmet_rdma_rsp, free_list); | 220 | rsp = &queue->rsps[tag]; |
| 219 | if (likely(rsp)) | ||
| 220 | list_del(&rsp->free_list); | ||
| 221 | spin_unlock_irqrestore(&queue->rsps_lock, flags); | ||
| 222 | 221 | ||
| 223 | if (unlikely(!rsp)) { | 222 | if (unlikely(!rsp)) { |
| 224 | int ret; | 223 | int ret; |
| @@ -226,13 +225,12 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) · 1 unmodified line | |||
| 226 | rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); | 225 | rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); |
| 227 | if (unlikely(!rsp)) | 226 | if (unlikely(!rsp)) |
| 228 | return NULL; | 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 | if (unlikely(ret)) { | 230 | if (unlikely(ret)) { |
| 231 | kfree(rsp); | 231 | kfree(rsp); |
| 232 | return NULL; | 232 | return NULL; |
| 233 | } | 233 | } |
| 234 | |||
| 235 | rsp->allocated = true; | ||
| 236 | } | 234 | } |
| 237 | 235 | ||
| 238 | return rsp; | 236 | return rsp; |
| @@ -241,17 +239,13 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) · 2 unmodified lines | |||
| 241 | static inline void | 239 | static inline void |
| 242 | nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp) | 240 | nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp) |
| 243 | { | 241 | { |
| 244 | unsigned long flags; | 242 | if (unlikely(rsp->tag == NVMET_RDMA_DISCRETE_RSP_TAG)) { |
| 245 | |||
| 246 | if (unlikely(rsp->allocated)) { | ||
| 247 | nvmet_rdma_free_rsp(rsp->queue->dev, rsp); | 243 | nvmet_rdma_free_rsp(rsp->queue->dev, rsp); |
| 248 | kfree(rsp); | 244 | kfree(rsp); |
| 249 | return; | 245 | return; |
| 250 | } | 246 | } |
| 251 | 247 | ||
| 252 | spin_lock_irqsave(&rsp->queue->rsps_lock, flags); | 248 | sbitmap_clear_bit(&rsp->queue->rsp_tags, rsp->tag); |
| 253 | list_add_tail(&rsp->free_list, &rsp->queue->free_rsps); | ||
| 254 | spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags); | ||
| 255 | } | 249 | } |
| 256 | 250 | ||
| 257 | static void nvmet_rdma_free_inline_pages(struct nvmet_rdma_device *ndev, | 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 | static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, | 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 | /* NVMe CQE / RDMA SEND */ | 403 | /* NVMe CQE / RDMA SEND */ |
| 410 | r->req.cqe = kmalloc(sizeof(*r->req.cqe), GFP_KERNEL); | 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 | r->read_cqe.done = nvmet_rdma_read_data_done; | 426 | r->read_cqe.done = nvmet_rdma_read_data_done; |
| 433 | /* Data Out / RDMA WRITE */ | 427 | /* Data Out / RDMA WRITE */ |
| 434 | r->write_cqe.done = nvmet_rdma_write_data_done; | 428 | r->write_cqe.done = nvmet_rdma_write_data_done; |
| 429 | r->tag = tag; | ||
| 435 | 430 | ||
| 436 | return 0; | 431 | return 0; |
| 437 | 432 | ||
| @@ -454,21 +449,23 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue) · 16 unmodified lines | |||
| 454 | { | 449 | { |
| 455 | struct nvmet_rdma_device *ndev = queue->dev; | 450 | struct nvmet_rdma_device *ndev = queue->dev; |
| 456 | int nr_rsps = queue->recv_queue_size * 2; | 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 | queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), | 458 | queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), |
| 460 | GFP_KERNEL); | 459 | GFP_KERNEL); |
| 461 | if (!queue->rsps) | 460 | if (!queue->rsps) |
| 462 | goto out; | 461 | goto out_free_sbitmap; |
| 463 | 462 | ||
| 464 | for (i = 0; i < nr_rsps; i++) { | 463 | for (i = 0; i < nr_rsps; i++) { |
| 465 | struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; | 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 | if (ret) | 467 | if (ret) |
| 469 | goto out_free; | 468 | goto out_free; |
| 470 | |||
| 471 | list_add_tail(&rsp->free_list, &queue->free_rsps); | ||
| 472 | } | 469 | } |
| 473 | 470 | ||
| 474 | return 0; | 471 | return 0; |
| @@ -477,6 +474,8 @@ out_free: · 2 unmodified lines | |||
| 477 | while (--i >= 0) | 474 | while (--i >= 0) |
| 478 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); | 475 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); |
| 479 | kfree(queue->rsps); | 476 | kfree(queue->rsps); |
| 477 | out_free_sbitmap: | ||
| 478 | sbitmap_free(&queue->rsp_tags); | ||
| 480 | out: | 479 | out: |
| 481 | return ret; | 480 | return ret; |
| 482 | } | 481 | } |
| @@ -489,6 +488,7 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue) · 6 unmodified lines | |||
| 489 | for (i = 0; i < nr_rsps; i++) | 488 | for (i = 0; i < nr_rsps; i++) |
| 490 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); | 489 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); |
| 491 | kfree(queue->rsps); | 490 | kfree(queue->rsps); |
| 491 | sbitmap_free(&queue->rsp_tags); | ||
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | static int nvmet_rdma_post_recv(struct nvmet_rdma_device *ndev, | 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 | INIT_LIST_HEAD(&queue->rsp_wait_list); | 1447 | INIT_LIST_HEAD(&queue->rsp_wait_list); |
| 1448 | INIT_LIST_HEAD(&queue->rsp_wr_wait_list); | 1448 | INIT_LIST_HEAD(&queue->rsp_wr_wait_list); |
| 1449 | spin_lock_init(&queue->rsp_wr_wait_lock); | 1449 | spin_lock_init(&queue->rsp_wr_wait_lock); |
| 1450 | INIT_LIST_HEAD(&queue->free_rsps); | ||
| 1451 | spin_lock_init(&queue->rsps_lock); | ||
| 1452 | INIT_LIST_HEAD(&queue->queue_list); | 1450 | INIT_LIST_HEAD(&queue->queue_list); |
| 1453 | 1451 | ||
| 1454 | queue->idx = ida_alloc(&nvmet_rdma_queue_ida, GFP_KERNEL); | 1452 | queue->idx = ida_alloc(&nvmet_rdma_queue_ida, GFP_KERNEL); |
| @@ -10,6 +10,19 @@ · 9 unmodified lines | |||
| 10 | #include <kunit/test.h> | 10 | #include <kunit/test.h> |
| 11 | #include <kunit/resource.h> | 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 | #if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE) | 26 | #if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE) |
| 14 | 27 | ||
| 15 | static void of_overlay_fdt_apply_kunit_exit(void *ovcs_id) | 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 | int ret; | 49 | int ret; |
| 37 | int *copy_id; | 50 | int *copy_id; |
| 38 | 51 | ||
| 52 | of_root_kunit_skip(test); | ||
| 53 | |||
| 39 | copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL); | 54 | copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL); |
| 40 | if (!copy_id) | 55 | if (!copy_id) |
| 41 | return -ENOMEM; | 56 | return -ENOMEM; |
| @@ -42,6 +42,9 @@ extern raw_spinlock_t devtree_lock; · 41 unmodified lines | |||
| 42 | extern struct list_head aliases_lookup; | 42 | extern struct list_head aliases_lookup; |
| 43 | extern struct kset *of_kset; | 43 | extern struct kset *of_kset; |
| 44 | 44 | ||
| 45 | struct kunit; | ||
| 46 | extern void of_root_kunit_skip(struct kunit *test); | ||
| 47 | |||
| 45 | #if defined(CONFIG_OF_DYNAMIC) | 48 | #if defined(CONFIG_OF_DYNAMIC) |
| 46 | extern int of_property_notify(int action, struct device_node *np, | 49 | extern int of_property_notify(int action, struct device_node *np, |
| 47 | struct property *prop, struct property *old_prop); | 50 | struct property *prop, struct property *old_prop); |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #include <kunit/test.h> | 8 | #include <kunit/test.h> |
| 9 | 9 | ||
| 10 | #include "of_private.h" | ||
| 11 | |||
| 10 | /* | 12 | /* |
| 11 | * Test that the root node "/" can be found by path. | 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 | static int of_dtb_test_init(struct kunit *test) | 39 | static int of_dtb_test_init(struct kunit *test) |
| 38 | { | 40 | { |
| 41 | of_root_kunit_skip(test); | ||
| 39 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) | 42 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) |
| 40 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE"); | 43 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE"); |
| 41 | 44 | ||
| @@ -11,6 +11,8 @@ · 10 unmodified lines | |||
| 11 | #include <kunit/of.h> | 11 | #include <kunit/of.h> |
| 12 | #include <kunit/test.h> | 12 | #include <kunit/test.h> |
| 13 | 13 | ||
| 14 | #include "of_private.h" | ||
| 15 | |||
| 14 | static const char * const kunit_node_name = "kunit-test"; | 16 | static const char * const kunit_node_name = "kunit-test"; |
| 15 | static const char * const kunit_compatible = "test,empty"; | 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 | struct device *dev; | 64 | struct device *dev; |
| 63 | struct device_node *np; | 65 | struct device_node *np; |
| 64 | 66 | ||
| 67 | of_root_kunit_skip(test); | ||
| 65 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) | 68 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) |
| 66 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE for root node"); | 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 | np = of_find_node_by_name(NULL, kunit_node_name); | 77 | np = of_find_node_by_name(NULL, kunit_node_name); |
| 75 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np); | 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 | pdev = of_find_device_by_node(np); | 81 | pdev = of_find_device_by_node(np); |
| 79 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); | 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 | /* Attach genpds */ | 2631 | /* Attach genpds */ |
| 2632 | if (config->genpd_names) { | 2632 | if (config->genpd_names) { |
| 2633 | if (config->required_devs) | 2633 | if (config->required_devs) { |
| 2634 | ret = -EINVAL; | ||
| 2634 | goto err; | 2635 | goto err; |
| 2636 | } | ||
| 2635 | 2637 | ||
| 2636 | ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, | 2638 | ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, |
| 2637 | config->virt_devs); | 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 | for (dev = port->devices; dev ; dev = dev->next) { | 52 | for (dev = port->devices; dev ; dev = dev->next) { |
| 53 | if(dev == port->cad) { | 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 | if(!len) { | 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 | if (len > *lenp) | 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 | if ((str = info->class_name) != NULL) | 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 | if ((str = info->model) != NULL) | 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 | if ((str = info->mfr) != NULL) | 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 | if ((str = info->description) != NULL) | 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 | if ((str = info->cmdset) != NULL) | 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 | if (len > *lenp) | 104 | if (len > *lenp) |
| 105 | len = *lenp; | 105 | len = *lenp; |
| @@ -128,7 +128,7 @@ static int do_hardware_base_addr(const struct ctl_table *table, int write, · 22 unmodified lines | |||
| 128 | if (write) /* permissions prevent this anyway */ | 128 | if (write) /* permissions prevent this anyway */ |
| 129 | return -EACCES; | 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 | if (len > *lenp) | 133 | if (len > *lenp) |
| 134 | len = *lenp; | 134 | len = *lenp; |
| @@ -155,7 +155,7 @@ static int do_hardware_irq(const struct ctl_table *table, int write, · 20 unmodified lines | |||
| 155 | if (write) /* permissions prevent this anyway */ | 155 | if (write) /* permissions prevent this anyway */ |
| 156 | return -EACCES; | 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 | if (len > *lenp) | 160 | if (len > *lenp) |
| 161 | len = *lenp; | 161 | len = *lenp; |
| @@ -182,7 +182,7 @@ static int do_hardware_dma(const struct ctl_table *table, int write, · 20 unmodified lines | |||
| 182 | if (write) /* permissions prevent this anyway */ | 182 | if (write) /* permissions prevent this anyway */ |
| 183 | return -EACCES; | 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 | if (len > *lenp) | 187 | if (len > *lenp) |
| 188 | len = *lenp; | 188 | len = *lenp; |
| @@ -213,7 +213,7 @@ static int do_hardware_modes(const struct ctl_table *table, int write, · 24 unmodified lines | |||
| 213 | #define printmode(x) \ | 213 | #define printmode(x) \ |
| 214 | do { \ | 214 | do { \ |
| 215 | if (port->modes & PARPORT_MODE_##x) \ | 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 | } while (0) | 217 | } while (0) |
| 218 | int f = 0; | 218 | int f = 0; |
| 219 | printmode(PCSPP); | 219 | printmode(PCSPP); |
| @@ -22,13 +22,13 @@ static int pmu_legacy_ctr_get_idx(struct perf_event *event) · 21 unmodified lines | |||
| 22 | struct perf_event_attr *attr = &event->attr; | 22 | struct perf_event_attr *attr = &event->attr; |
| 23 | 23 | ||
| 24 | if (event->attr.type != PERF_TYPE_HARDWARE) | 24 | if (event->attr.type != PERF_TYPE_HARDWARE) |
| 25 | return -EOPNOTSUPP; | 25 | return -ENOENT; |
| 26 | if (attr->config == PERF_COUNT_HW_CPU_CYCLES) | 26 | if (attr->config == PERF_COUNT_HW_CPU_CYCLES) |
| 27 | return RISCV_PMU_LEGACY_CYCLE; | 27 | return RISCV_PMU_LEGACY_CYCLE; |
| 28 | else if (attr->config == PERF_COUNT_HW_INSTRUCTIONS) | 28 | else if (attr->config == PERF_COUNT_HW_INSTRUCTIONS) |
| 29 | return RISCV_PMU_LEGACY_INSTRET; | 29 | return RISCV_PMU_LEGACY_INSTRET; |
| 30 | else | 30 | else |
| 31 | return -EOPNOTSUPP; | 31 | return -ENOENT; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | /* For legacy config & counter index are same */ | 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 | ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0); | 309 | ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0); |
| 310 | } else if (ret.error == SBI_ERR_NOT_SUPPORTED) { | 310 | } else if (ret.error == SBI_ERR_NOT_SUPPORTED) { |
| 311 | /* This event cannot be monitored by any counter */ | 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 | break; | 557 | break; |
| 558 | default: | 558 | default: |
| 559 | ret = -EINVAL; | 559 | ret = -ENOENT; |
| 560 | break; | 560 | break; |
| 561 | } | 561 | } |
| 562 | 562 | ||
| @@ -46,6 +46,7 @@ config PINCTRL_INTEL_PLATFORM · 45 unmodified lines | |||
| 46 | of Intel PCH pins and using them as GPIOs. Currently the following | 46 | of Intel PCH pins and using them as GPIOs. Currently the following |
| 47 | Intel SoCs / platforms require this to be functional: | 47 | Intel SoCs / platforms require this to be functional: |
| 48 | - Lunar Lake | 48 | - Lunar Lake |
| 49 | - Panther Lake | ||
| 49 | 50 | ||
| 50 | config PINCTRL_ALDERLAKE | 51 | config PINCTRL_ALDERLAKE |
| 51 | tristate "Intel Alder Lake pinctrl and GPIO driver" | 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 | struct intel_community *community, | 90 | struct intel_community *community, |
| 91 | struct intel_platform_pins *pins) | 91 | struct intel_platform_pins *pins) |
| 92 | { | 92 | { |
| 93 | struct fwnode_handle *child; | ||
| 94 | struct intel_padgroup *gpps; | 93 | struct intel_padgroup *gpps; |
| 95 | unsigned int group; | 94 | unsigned int group; |
| 96 | size_t ngpps; | 95 | size_t ngpps; |
| @@ -131,7 +130,7 @@ static int intel_platform_pinctrl_prepare_community(struct device *dev, · 34 unmodified lines | |||
| 131 | return -ENOMEM; | 130 | return -ENOMEM; |
| 132 | 131 | ||
| 133 | group = 0; | 132 | group = 0; |
| 134 | device_for_each_child_node(dev, child) { | 133 | device_for_each_child_node_scoped(dev, child) { |
| 135 | struct intel_padgroup *gpp = &gpps[group]; | 134 | struct intel_padgroup *gpp = &gpps[group]; |
| 136 | 135 | ||
| 137 | gpp->reg_num = group; | 136 | gpp->reg_num = group; |
| @@ -159,7 +158,7 @@ static int intel_platform_pinctrl_prepare_soc_data(struct device *dev, · 21 unmodified lines | |||
| 159 | int ret; | 158 | int ret; |
| 160 | 159 | ||
| 161 | /* Version 1.0 of the specification assumes only a single community per device node */ | 160 | /* Version 1.0 of the specification assumes only a single community per device node */ |
| 162 | ncommunities = 1, | 161 | ncommunities = 1; |
| 163 | communities = devm_kcalloc(dev, ncommunities, sizeof(*communities), GFP_KERNEL); | 162 | communities = devm_kcalloc(dev, ncommunities, sizeof(*communities), GFP_KERNEL); |
| 164 | if (!communities) | 163 | if (!communities) |
| 165 | return -ENOMEM; | 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 | map_num += grp->npins; | 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 | if (!new_map) | 222 | if (!new_map) |
| 223 | return -ENOMEM; | 223 | return -ENOMEM; |
| 224 | 224 | ||
| @@ -474,6 +474,9 @@ static int apple_gpio_pinctrl_probe(struct platform_device *pdev) · 473 unmodified lines | |||
| 474 | for (i = 0; i < npins; i++) { | 474 | for (i = 0; i < npins; i++) { |
| 475 | pins[i].number = i; | 475 | pins[i].number = i; |
| 476 | pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i); | 476 | pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i); |
| 477 | if (!pins[i].name) | ||
| 478 | return -ENOMEM; | ||
| 479 | |||
| 477 | pins[i].drv_data = pctl; | 480 | pins[i].drv_data = pctl; |
| 478 | pin_names[i] = pins[i].name; | 481 | pin_names[i] = pins[i].name; |
| 479 | pin_nums[i] = i; | 482 | pin_nums[i] = i; |
| @@ -987,8 +987,10 @@ static int aw9523_probe(struct i2c_client *client) · 986 unmodified lines | |||
| 987 | lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter)); | 987 | lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter)); |
| 988 | 988 | ||
| 989 | pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); | 989 | pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); |
| 990 | if (!pdesc) | 990 | if (!pdesc) { |
| 991 | return -ENOMEM; | 991 | ret = -ENOMEM; |
| 992 | goto err_disable_vregs; | ||
| 993 | } | ||
| 992 | 994 | ||
| 993 | ret = aw9523_hw_init(awi); | 995 | ret = aw9523_hw_init(awi); |
| 994 | if (ret) | 996 | if (ret) |
| @@ -1955,21 +1955,21 @@ static void ocelot_irq_handler(struct irq_desc *desc) · 1954 unmodified lines | |||
| 1955 | unsigned int reg = 0, irq, i; | 1955 | unsigned int reg = 0, irq, i; |
| 1956 | unsigned long irqs; | 1956 | unsigned long irqs; |
| 1957 | 1957 | ||
| 1958 | chained_irq_enter(parent_chip, desc); | ||
| 1959 | |||
| 1958 | for (i = 0; i < info->stride; i++) { | 1960 | for (i = 0; i < info->stride; i++) { |
| 1959 | regmap_read(info->map, id_reg + 4 * i, ®); | 1961 | regmap_read(info->map, id_reg + 4 * i, ®); |
| 1960 | if (!reg) | 1962 | if (!reg) |
| 1961 | continue; | 1963 | continue; |
| 1962 | 1964 | ||
| 1963 | chained_irq_enter(parent_chip, desc); | ||
| 1964 | |||
| 1965 | irqs = reg; | 1965 | irqs = reg; |
| 1966 | 1966 | ||
| 1967 | for_each_set_bit(irq, &irqs, | 1967 | for_each_set_bit(irq, &irqs, |
| 1968 | min(32U, info->desc->npins - 32 * i)) | 1968 | min(32U, info->desc->npins - 32 * i)) |
| 1969 | generic_handle_domain_irq(chip->irq.domain, irq + 32 * i); | 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 | static int ocelot_gpiochip_register(struct platform_device *pdev, | 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 | if (!grpnames) | 221 | if (!grpnames) |
| 222 | return -ENOMEM; | 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 | if (!map) | 225 | if (!map) |
| 226 | return -ENOMEM; | 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 | for (i = 0; i < npins; i++) { | 1375 | for (i = 0; i < npins; i++) { |
| 1376 | stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); | 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 | names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name); | 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 | names[i] = NULL; | 1384 | names[i] = NULL; |
| 1385 | } | ||
| 1381 | } | 1386 | } |
| 1382 | 1387 | ||
| 1383 | bank->gpio_chip.names = (const char * const *)names; | 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 | ATTRIBUTE_GROUPS(dell_battery); | 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 | static int dell_battery_add(struct power_supply *battery, | 2400 | static int dell_battery_add(struct power_supply *battery, |
| 2395 | struct acpi_battery_hook *hook) | 2401 | struct acpi_battery_hook *hook) |
| 2396 | { | 2402 | { |
| 2397 | /* this currently only supports the primary battery */ | 2403 | /* Return 0 instead of an error to avoid being unloaded */ |
| 2398 | if (strcmp(battery->desc->name, "BAT0") != 0) | 2404 | if (!dell_battery_supported(battery)) |
| 2399 | return -ENODEV; | 2405 | return 0; |
| 2400 | 2406 | ||
| 2401 | return device_add_groups(&battery->dev, dell_battery_groups); | 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 | static int dell_battery_remove(struct power_supply *battery, | 2410 | static int dell_battery_remove(struct power_supply *battery, |
| 2405 | struct acpi_battery_hook *hook) | 2411 | struct acpi_battery_hook *hook) |
| 2406 | { | 2412 | { |
| 2413 | if (!dell_battery_supported(battery)) | ||
| 2414 | return 0; | ||
| 2415 | |||
| 2407 | device_remove_groups(&battery->dev, dell_battery_groups); | 2416 | device_remove_groups(&battery->dev, dell_battery_groups); |
| 2408 | return 0; | 2417 | return 0; |
| 2409 | } | 2418 | } |
| @@ -521,6 +521,7 @@ static int __init sysman_init(void) · 520 unmodified lines | |||
| 521 | int ret = 0; | 521 | int ret = 0; |
| 522 | 522 | ||
| 523 | if (!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL) && | 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 | !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) { | 525 | !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) { |
| 525 | pr_err("Unable to run on non-Dell system\n"); | 526 | pr_err("Unable to run on non-Dell system\n"); |
| 526 | return -ENODEV; | 527 | return -ENODEV; |
| @@ -130,8 +130,6 @@ const struct pmc_reg_map spt_reg_map = { · 129 unmodified lines | |||
| 130 | .ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES, | 130 | .ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES, |
| 131 | .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET, | 131 | .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET, |
| 132 | .pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT, | 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 | .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED, | 133 | .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED, |
| 136 | .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, | 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 | cpu >= nr_cpu_ids || cpu >= num_possible_cpus()) | 316 | cpu >= nr_cpu_ids || cpu >= num_possible_cpus()) |
| 317 | return NULL; | 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 | bus_number = isst_cpu_info[cpu].bus_info[bus_no]; | 323 | bus_number = isst_cpu_info[cpu].bus_info[bus_no]; |
| 322 | if (bus_number < 0) | 324 | if (bus_number < 0) |
| @@ -807,6 +809,7 @@ static const struct x86_cpu_id isst_cpu_ids[] = { · 484 unmodified lines | |||
| 807 | X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, SST_HPM_SUPPORTED), | 809 | X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, SST_HPM_SUPPORTED), |
| 808 | X86_MATCH_VFM(INTEL_ICELAKE_D, 0), | 810 | X86_MATCH_VFM(INTEL_ICELAKE_D, 0), |
| 809 | X86_MATCH_VFM(INTEL_ICELAKE_X, 0), | 811 | X86_MATCH_VFM(INTEL_ICELAKE_X, 0), |
| 812 | X86_MATCH_VFM(INTEL_PANTHERCOVE_X, SST_HPM_SUPPORTED), | ||
| 810 | X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0), | 813 | X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0), |
| 811 | X86_MATCH_VFM(INTEL_SKYLAKE_X, SST_MBOX_SUPPORTED), | 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 | X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, NULL), | 82 | X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, NULL), |
| 83 | X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, NULL), | 83 | X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, NULL), |
| 84 | X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, NULL), | 84 | X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, NULL), |
| 85 | X86_MATCH_VFM(INTEL_PANTHERCOVE_X, NULL), | ||
| 85 | {} | 86 | {} |
| 86 | }; | 87 | }; |
| 87 | MODULE_DEVICE_TABLE(x86cpu, tpmi_cpu_ids); | 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 | for (i = 0; i < pdev_count; i++) { | 390 | for (i = 0; i < pdev_count; i++) { |
| 391 | pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); | 391 | pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); |
| 392 | if (IS_ERR(pdevs[i])) { | 392 | if (IS_ERR(pdevs[i])) { |
| 393 | ret = PTR_ERR(pdevs[i]); | ||
| 393 | x86_android_tablet_remove(pdev); | 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 | PLATFORM_DEVID_AUTO, | 444 | PLATFORM_DEVID_AUTO, |
| 444 | &pdata, sizeof(pdata)); | 445 | &pdata, sizeof(pdata)); |
| 445 | if (IS_ERR(pdevs[pdev_count])) { | 446 | if (IS_ERR(pdevs[pdev_count])) { |
| 447 | ret = PTR_ERR(pdevs[pdev_count]); | ||
| 446 | x86_android_tablet_remove(pdev); | 448 | x86_android_tablet_remove(pdev); |
| 447 | return PTR_ERR(pdevs[pdev_count]); | 449 | return ret; |
| 448 | } | 450 | } |
| 449 | pdev_count++; | 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 | of_parse_phandle(child_np, "required-opps", 0); | 1052 | of_parse_phandle(child_np, "required-opps", 0); |
| 1053 | 1053 | ||
| 1054 | if (child_req_np == ref_np) { | 1054 | if (child_req_np == ref_np) { |
| 1055 | u64 rate; | 1055 | u64 rate = 0; |
| 1056 | 1056 | ||
| 1057 | of_property_read_u64(child_np, "opp-hz", &rate); | 1057 | of_property_read_u64(child_np, "opp-hz", &rate); |
| 1058 | return (unsigned long) rate; | 1058 | return (unsigned long) rate; |
| @@ -147,6 +147,8 @@ static const struct x86_cpu_id pl4_support_ids[] = { · 146 unmodified lines | |||
| 147 | X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL), | 147 | X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL), |
| 148 | X86_MATCH_VFM(INTEL_METEORLAKE, NULL), | 148 | X86_MATCH_VFM(INTEL_METEORLAKE, NULL), |
| 149 | X86_MATCH_VFM(INTEL_METEORLAKE_L, NULL), | 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 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/slab.h> | 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 | /* 1 header + 10 registers + 5 reserved. 8 bytes for each. */ | 21 | /* 1 header + 10 registers + 5 reserved. 8 bytes for each. */ |
| 21 | #define TPMI_RAPL_DOMAIN_SIZE 128 | 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 | tpmi_domain_size = tpmi_domain_header >> 16 & 0xff; | 155 | tpmi_domain_size = tpmi_domain_header >> 16 & 0xff; |
| 155 | tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; | 156 | tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; |
| 156 | 157 | ||
| 157 | if (tpmi_domain_version != TPMI_RAPL_VERSION) { | 158 | if (tpmi_domain_version == TPMI_VERSION_INVALID) { |
| 158 | pr_warn(FW_BUG "Unsupported version:%d\n", tpmi_domain_version); | 159 | pr_warn(FW_BUG "Invalid version\n"); |
| 159 | return -ENODEV; | 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 | /* Domain size: in unit of 128 Bytes */ | 173 | /* Domain size: in unit of 128 Bytes */ |
| 163 | if (tpmi_domain_size != 1) { | 174 | if (tpmi_domain_size != 1) { |
| 164 | pr_warn(FW_BUG "Invalid Domain size %d\n", tpmi_domain_size); | 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 | pr_warn(FW_BUG "System domain must support Domain Info register\n"); | 192 | pr_warn(FW_BUG "System domain must support Domain Info register\n"); |
| 182 | return -ENODEV; | 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 | if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT)) | 196 | if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT)) |
| 186 | return 0; | 197 | return 0; |
| 187 | domain_type = RAPL_DOMAIN_PLATFORM; | 198 | domain_type = RAPL_DOMAIN_PLATFORM; |
| @@ -405,8 +405,8 @@ static int npcm_rc_probe(struct platform_device *pdev) · 404 unmodified lines | |||
| 405 | if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number", | 405 | if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number", |
| 406 | &rc->sw_reset_number)) { | 406 | &rc->sw_reset_number)) { |
| 407 | if (rc->sw_reset_number && rc->sw_reset_number < 5) { | 407 | if (rc->sw_reset_number && rc->sw_reset_number < 5) { |
| 408 | rc->restart_nb.priority = 192, | 408 | rc->restart_nb.priority = 192; |
| 409 | rc->restart_nb.notifier_call = npcm_rc_restart, | 409 | rc->restart_nb.notifier_call = npcm_rc_restart; |
| 410 | ret = register_restart_handler(&rc->restart_nb); | 410 | ret = register_restart_handler(&rc->restart_nb); |
| 411 | if (ret) | 411 | if (ret) |
| 412 | dev_warn(&pdev->dev, "failed to register restart handler\n"); | 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 | void __iomem *reg_status = data->status + offset * sizeof(u32); | 94 | void __iomem *reg_status = data->status + offset * sizeof(u32); |
| 95 | u32 value = readl(reg_status); | 95 | u32 value = readl(reg_status); |
| 96 | 96 | ||
| 97 | if (!data->asserted) | ||
| 98 | return !(value & mask); | ||
| 99 | |||
| 97 | return !((value ^ data->asserted[offset]) & mask); | 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 | static struct notifier_block sclp_reboot_notifier = { | 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 | static ssize_t con_pages_show(struct device_driver *dev, char *buf) | 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 | buffer = (void *) ((addr_t) sccb + sccb->header.length); | 319 | buffer = (void *) ((addr_t) sccb + sccb->header.length); |
| 320 | 320 | ||
| 321 | if (convertlf) { | 321 | if (convertlf) { |
| 322 | /* Perform Linefeed conversion (0x0a -> 0x0a 0x0d)*/ | 322 | /* Perform Linefeed conversion (0x0a -> 0x0d 0x0a)*/ |
| 323 | for (from=0, to=0; | 323 | for (from=0, to=0; |
| 324 | (from < count) && (to < sclp_vt220_space_left(request)); | 324 | (from < count) && (to < sclp_vt220_space_left(request)); |
| 325 | from++) { | 325 | from++) { |
| @@ -328,8 +328,8 @@ sclp_vt220_add_msg(struct sclp_vt220_request *request, · 2 unmodified lines | |||
| 328 | /* Perform conversion */ | 328 | /* Perform conversion */ |
| 329 | if (c == 0x0a) { | 329 | if (c == 0x0a) { |
| 330 | if (to + 1 < sclp_vt220_space_left(request)) { | 330 | if (to + 1 < sclp_vt220_space_left(request)) { |
| 331 | ((unsigned char *) buffer)[to++] = c; | ||
| 332 | ((unsigned char *) buffer)[to++] = 0x0d; | 331 | ((unsigned char *) buffer)[to++] = 0x0d; |
| 332 | ((unsigned char *) buffer)[to++] = c; | ||
| 333 | } else | 333 | } else |
| 334 | break; | 334 | break; |
| 335 | 335 | ||
| @@ -1864,13 +1864,12 @@ static inline void ap_scan_domains(struct ap_card *ac) · 1863 unmodified lines | |||
| 1864 | } | 1864 | } |
| 1865 | /* if no queue device exists, create a new one */ | 1865 | /* if no queue device exists, create a new one */ |
| 1866 | if (!aq) { | 1866 | if (!aq) { |
| 1867 | aq = ap_queue_create(qid, ac->ap_dev.device_type); | 1867 | aq = ap_queue_create(qid, ac); |
| 1868 | if (!aq) { | 1868 | if (!aq) { |
| 1869 | AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n", | 1869 | AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n", |
| 1870 | __func__, ac->id, dom); | 1870 | __func__, ac->id, dom); |
| 1871 | continue; | 1871 | continue; |
| 1872 | } | 1872 | } |
| 1873 | aq->card = ac; | ||
| 1874 | aq->config = !decfg; | 1873 | aq->config = !decfg; |
| 1875 | aq->chkstop = chkstop; | 1874 | aq->chkstop = chkstop; |
| 1876 | aq->se_bstate = hwinfo.bs; | 1875 | aq->se_bstate = hwinfo.bs; |
| @@ -272,7 +272,7 @@ int ap_test_config_usage_domain(unsigned int domain); · 271 unmodified lines | |||
| 272 | int ap_test_config_ctrl_domain(unsigned int domain); | 272 | int ap_test_config_ctrl_domain(unsigned int domain); |
| 273 | 273 | ||
| 274 | void ap_queue_init_reply(struct ap_queue *aq, struct ap_message *ap_msg); | 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 | void ap_queue_prepare_remove(struct ap_queue *aq); | 276 | void ap_queue_prepare_remove(struct ap_queue *aq); |
| 277 | void ap_queue_remove(struct ap_queue *aq); | 277 | void ap_queue_remove(struct ap_queue *aq); |
| 278 | void ap_queue_init_state(struct ap_queue *aq); | 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 | * some AP queue helper functions | 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 | static inline bool ap_q_supports_bind(struct ap_queue *aq) | 30 | static inline bool ap_q_supports_bind(struct ap_queue *aq) |
| 26 | { | 31 | { |
| 27 | return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; | 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 | kfree(aq); | 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 | struct ap_queue *aq; | 1114 | struct ap_queue *aq; |
| 1110 | 1115 | ||
| 1111 | aq = kzalloc(sizeof(*aq), GFP_KERNEL); | 1116 | aq = kzalloc(sizeof(*aq), GFP_KERNEL); |
| 1112 | if (!aq) | 1117 | if (!aq) |
| 1113 | return NULL; | 1118 | return NULL; |
| 1119 | aq->card = ac; | ||
| 1114 | aq->ap_dev.device.release = ap_queue_device_release; | 1120 | aq->ap_dev.device.release = ap_queue_device_release; |
| 1115 | aq->ap_dev.device.type = &ap_queue_type; | 1121 | aq->ap_dev.device.type = &ap_queue_type; |
| 1116 | aq->ap_dev.device_type = device_type; | 1122 | aq->ap_dev.device_type = ac->ap_dev.device_type; |
| 1117 | // add optional SE secure binding attributes group | 1123 | /* in SE environment add bind/associate attributes group */ |
| 1118 | if (ap_sb_available() && is_prot_virt_guest()) | 1124 | if (ap_is_se_guest() && ap_q_supported_in_se(aq)) |
| 1119 | aq->ap_dev.device.groups = ap_queue_dev_sb_attr_groups; | 1125 | aq->ap_dev.device.groups = ap_queue_dev_sb_attr_groups; |
| 1120 | aq->qid = qid; | 1126 | aq->qid = qid; |
| 1121 | spin_lock_init(&aq->lock); | 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 | /* SE guest's queues additionally need to be bound */ | 1204 | /* SE guest's queues additionally need to be bound */ |
| 1199 | if (ap_q_needs_bind(aq) && | 1205 | if (ap_is_se_guest()) { |
| 1200 | !(aq->se_bstate == AP_BS_Q_USABLE || | 1206 | if (!ap_q_supported_in_se(aq)) { |
| 1201 | aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) | 1207 | rc = false; |
| 1202 | 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 | unlock_and_out: | 1216 | unlock_and_out: |
| 1205 | spin_unlock_bh(&aq->lock); | 1217 | spin_unlock_bh(&aq->lock); |
| @@ -324,6 +324,7 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen, · 323 unmodified lines | |||
| 324 | memcpy(protkey, t->protkey, t->len); | 324 | memcpy(protkey, t->protkey, t->len); |
| 325 | *protkeylen = t->len; | 325 | *protkeylen = t->len; |
| 326 | *protkeytype = t->keytype; | 326 | *protkeytype = t->keytype; |
| 327 | rc = 0; | ||
| 327 | break; | 328 | break; |
| 328 | } | 329 | } |
| 329 | case TOKVER_CLEAR_KEY: { | 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 | spin_lock_init(&fnic->vlans_lock); | 830 | spin_lock_init(&fnic->vlans_lock); |
| 831 | INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); | 831 | INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); |
| 832 | INIT_WORK(&fnic->event_work, fnic_handle_event); | 832 | INIT_WORK(&fnic->event_work, fnic_handle_event); |
| 833 | INIT_WORK(&fnic->flush_work, fnic_flush_tx); | ||
| 834 | skb_queue_head_init(&fnic->fip_frame_queue); | 833 | skb_queue_head_init(&fnic->fip_frame_queue); |
| 835 | INIT_LIST_HEAD(&fnic->evlist); | 834 | INIT_LIST_HEAD(&fnic->evlist); |
| 836 | INIT_LIST_HEAD(&fnic->vlans); | 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 | INIT_WORK(&fnic->link_work, fnic_handle_link); | 948 | INIT_WORK(&fnic->link_work, fnic_handle_link); |
| 950 | INIT_WORK(&fnic->frame_work, fnic_handle_frame); | 949 | INIT_WORK(&fnic->frame_work, fnic_handle_frame); |
| 950 | INIT_WORK(&fnic->flush_work, fnic_flush_tx); | ||
| 951 | skb_queue_head_init(&fnic->frame_queue); | 951 | skb_queue_head_init(&fnic->frame_queue); |
| 952 | skb_queue_head_init(&fnic->tx_queue); | 952 | skb_queue_head_init(&fnic->tx_queue); |
| 953 | 953 | ||
| @@ -542,8 +542,8 @@ struct mpi3mr_hba_port { · 541 unmodified lines | |||
| 542 | * @port_list: List of ports belonging to a SAS node | 542 | * @port_list: List of ports belonging to a SAS node |
| 543 | * @num_phys: Number of phys associated with port | 543 | * @num_phys: Number of phys associated with port |
| 544 | * @marked_responding: used while refresing the sas ports | 544 | * @marked_responding: used while refresing the sas ports |
| 545 | * @lowest_phy: lowest phy ID 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 | 546 | * @phy_mask: phy_mask of current sas port, valid for controller port |
| 547 | * @hba_port: HBA port entry | 547 | * @hba_port: HBA port entry |
| 548 | * @remote_identify: Attached device identification | 548 | * @remote_identify: Attached device identification |
| 549 | * @rphy: SAS transport layer rphy object | 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 | * @mrioc: Adapter instance reference | 590 | * @mrioc: Adapter instance reference |
| 591 | * @mr_sas_port: Internal Port object | 591 | * @mr_sas_port: Internal Port object |
| 592 | * @mr_sas_phy: Internal Phy object | 592 | * @mr_sas_phy: Internal Phy object |
| 593 | * @host_node: Flag to indicate this is a host_node | ||
| 593 | * | 594 | * |
| 594 | * Return: None. | 595 | * Return: None. |
| 595 | */ | 596 | */ |
| 596 | static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, | 597 | static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, |
| 597 | struct mpi3mr_sas_port *mr_sas_port, | 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 | u64 sas_address = mr_sas_port->remote_identify.sas_address; | 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 | list_del(&mr_sas_phy->port_siblings); | 607 | list_del(&mr_sas_phy->port_siblings); |
| 607 | mr_sas_port->num_phys--; | 608 | mr_sas_port->num_phys--; |
| 608 | mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); | 609 | |
| 609 | if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) | 610 | if (host_node) { |
| 610 | mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | 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 | sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); | 616 | sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); |
| 612 | mr_sas_phy->phy_belongs_to_port = 0; | 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 | * @mrioc: Adapter instance reference | 622 | * @mrioc: Adapter instance reference |
| 618 | * @mr_sas_port: Internal Port object | 623 | * @mr_sas_port: Internal Port object |
| 619 | * @mr_sas_phy: Internal Phy object | 624 | * @mr_sas_phy: Internal Phy object |
| 625 | * @host_node: Flag to indicate this is a host_node | ||
| 620 | * | 626 | * |
| 621 | * Return: None. | 627 | * Return: None. |
| 622 | */ | 628 | */ |
| 623 | static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, | 629 | static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, |
| 624 | struct mpi3mr_sas_port *mr_sas_port, | 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 | u64 sas_address = mr_sas_port->remote_identify.sas_address; | 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 | list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); | 639 | list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); |
| 634 | mr_sas_port->num_phys++; | 640 | mr_sas_port->num_phys++; |
| 635 | mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); | 641 | if (host_node) { |
| 636 | if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) | 642 | mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); |
| 637 | mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | 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 | sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); | 647 | sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); |
| 639 | mr_sas_phy->phy_belongs_to_port = 1; | 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 | if (srch_phy == mr_sas_phy) | 684 | if (srch_phy == mr_sas_phy) |
| 676 | return; | 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 | return; | 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 | mpi3mr_delete_sas_port(mrioc, mr_sas_port); | 745 | mpi3mr_delete_sas_port(mrioc, mr_sas_port); |
| 737 | else | 746 | else |
| 738 | mpi3mr_delete_sas_phy(mrioc, mr_sas_port, | 747 | mpi3mr_delete_sas_phy(mrioc, mr_sas_port, |
| 739 | mr_sas_phy); | 748 | mr_sas_phy, mr_sas_node->host_node); |
| 740 | return; | 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 | * mpi3mr_get_hba_port_by_id - find hba port by id | 1038 | * mpi3mr_get_hba_port_by_id - find hba port by id |
| 1030 | * @mrioc: Adapter instance reference | 1039 | * @mrioc: Adapter instance reference |
| 1031 | * @port_id - Port ID to search | 1040 | * @port_id: Port ID to search |
| 1032 | * | 1041 | * |
| 1033 | * Return: mpi3mr_hba_port reference for the matched port | 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 | mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node, | 1376 | mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node, |
| 1368 | mr_sas_port->remote_identify.sas_address, hba_port); | 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 | ioc_info(mrioc, "max port count %u could be too high\n", | 1381 | ioc_info(mrioc, "max port count %u could be too high\n", |
| 1372 | mr_sas_node->num_phys); | 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 | (mr_sas_node->phy[i].hba_port != hba_port)) | 1387 | (mr_sas_node->phy[i].hba_port != hba_port)) |
| 1378 | continue; | 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 | ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n", | 1391 | ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n", |
| 1382 | i, sizeof(mr_sas_port->phy_mask) * 8); | 1392 | i, sizeof(mr_sas_port->phy_mask) * 8); |
| 1383 | goto out_fail; | 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 | list_add_tail(&mr_sas_node->phy[i].port_siblings, | 1395 | list_add_tail(&mr_sas_node->phy[i].port_siblings, |
| 1386 | &mr_sas_port->phy_list); | 1396 | &mr_sas_port->phy_list); |
| 1387 | mr_sas_port->num_phys++; | 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 | if (!mr_sas_port->num_phys) { | 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 | goto out_fail; | 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 | if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { | 1411 | if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { |
| 1400 | tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc, | 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 | if (rport->port_state == FC_PORTSTATE_ONLINE) | 1251 | if (rport->port_state == FC_PORTSTATE_ONLINE) |
| 1252 | rport->port_state = port_state; | 1252 | rport->port_state = port_state; |
| 1253 | else | 1253 | else if (port_state != rport->port_state) |
| 1254 | return -EINVAL; | 1254 | return -EINVAL; |
| 1255 | } else if (port_state == FC_PORTSTATE_ONLINE) { | 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 | if (rport->port_state == FC_PORTSTATE_MARGINAL) | 1261 | if (rport->port_state == FC_PORTSTATE_MARGINAL) |
| 1262 | rport->port_state = port_state; | 1262 | rport->port_state = port_state; |
| 1263 | else | 1263 | else if (port_state != rport->port_state) |
| 1264 | return -EINVAL; | 1264 | return -EINVAL; |
| 1265 | } else | 1265 | } else |
| 1266 | return -EINVAL; | 1266 | return -EINVAL; |
| @@ -831,7 +831,7 @@ wd33c93_intr(struct Scsi_Host *instance) · 830 unmodified lines | |||
| 831 | /* construct an IDENTIFY message with correct disconnect bit */ | 831 | /* construct an IDENTIFY message with correct disconnect bit */ |
| 832 | 832 | ||
| 833 | hostdata->outgoing_msg[0] = IDENTIFY(0, cmd->device->lun); | 833 | hostdata->outgoing_msg[0] = IDENTIFY(0, cmd->device->lun); |
| 834 | if (scsi_pointer->phase) | 834 | if (WD33C93_scsi_pointer(cmd)->phase) |
| 835 | hostdata->outgoing_msg[0] |= 0x40; | 835 | hostdata->outgoing_msg[0] |= 0x40; |
| 836 | 836 | ||
| 837 | if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) { | 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 | info = devm_qe_muram_alloc(qmc->dev, UCC_SLOW_PRAM_SIZE + 2 * 64, | 1762 | info = devm_qe_muram_alloc(qmc->dev, UCC_SLOW_PRAM_SIZE + 2 * 64, |
| 1763 | ALIGNMENT_OF_UCC_SLOW_PRAM); | 1763 | ALIGNMENT_OF_UCC_SLOW_PRAM); |
| 1764 | if (IS_ERR_VALUE(info)) { | 1764 | if (info < 0) |
| 1765 | dev_err(qmc->dev, "cannot allocate MURAM for PRAM"); | 1765 | return info; |
| 1766 | return -ENOMEM; | 1766 | |
| 1767 | } | ||
| 1768 | if (!qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, qmc->qe_subblock, | 1767 | if (!qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, qmc->qe_subblock, |
| 1769 | QE_CR_PROTOCOL_UNSPECIFIED, info)) { | 1768 | QE_CR_PROTOCOL_UNSPECIFIED, info)) { |
| 1770 | dev_err(qmc->dev, "QE_ASSIGN_PAGE_TO_DEVICE cmd failed"); | 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 | qmc_exit_xcc(qmc); | 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 | .version = QMC_CPM1, | 2059 | .version = QMC_CPM1, |
| 2061 | .tstate = 0x30000000, | 2060 | .tstate = 0x30000000, |
| 2062 | .rstate = 0x31000000, | 2061 | .rstate = 0x31000000, |
| @@ -2066,7 +2065,7 @@ static const struct qmc_data qmc_data_cpm1 = { · 3 unmodified lines | |||
| 2066 | .rpack = 0x00000000, | 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 | .version = QMC_QE, | 2069 | .version = QMC_QE, |
| 2071 | .tstate = 0x30000000, | 2070 | .tstate = 0x30000000, |
| 2072 | .rstate = 0x30000000, | 2071 | .rstate = 0x30000000, |
| @@ -377,7 +377,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, · 376 unmodified lines | |||
| 377 | */ | 377 | */ |
| 378 | if (!(aq->mr & QSPI_MR_SMM)) { | 378 | if (!(aq->mr & QSPI_MR_SMM)) { |
| 379 | aq->mr |= QSPI_MR_SMM; | 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 | /* Clear pending interrupts */ | 383 | /* Clear pending interrupts */ |
| @@ -678,8 +678,8 @@ static int cdns_spi_probe(struct platform_device *pdev) · 677 unmodified lines | |||
| 678 | 678 | ||
| 679 | clk_dis_all: | 679 | clk_dis_all: |
| 680 | if (!spi_controller_is_target(ctlr)) { | 680 | if (!spi_controller_is_target(ctlr)) { |
| 681 | pm_runtime_set_suspended(&pdev->dev); | ||
| 682 | pm_runtime_disable(&pdev->dev); | 681 | pm_runtime_disable(&pdev->dev); |
| 682 | pm_runtime_set_suspended(&pdev->dev); | ||
| 683 | } | 683 | } |
| 684 | remove_ctlr: | 684 | remove_ctlr: |
| 685 | spi_controller_put(ctlr); | 685 | spi_controller_put(ctlr); |
| @@ -701,8 +701,10 @@ static void cdns_spi_remove(struct platform_device *pdev) · 15 unmodified lines | |||
| 701 | 701 | ||
| 702 | cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE); | 702 | cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE); |
| 703 | 703 | ||
| 704 | pm_runtime_set_suspended(&pdev->dev); | 704 | if (!spi_controller_is_target(ctlr)) { |
| 705 | pm_runtime_disable(&pdev->dev); | 705 | pm_runtime_disable(&pdev->dev); |
| 706 | pm_runtime_set_suspended(&pdev->dev); | ||
| 707 | } | ||
| 706 | 708 | ||
| 707 | spi_unregister_controller(ctlr); | 709 | spi_unregister_controller(ctlr); |
| 708 | } | 710 | } |
| @@ -1865,8 +1865,8 @@ out_register_controller: · 1864 unmodified lines | |||
| 1865 | spi_imx_sdma_exit(spi_imx); | 1865 | spi_imx_sdma_exit(spi_imx); |
| 1866 | out_runtime_pm_put: | 1866 | out_runtime_pm_put: |
| 1867 | pm_runtime_dont_use_autosuspend(spi_imx->dev); | 1867 | pm_runtime_dont_use_autosuspend(spi_imx->dev); |
| 1868 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1869 | pm_runtime_disable(spi_imx->dev); | 1868 | pm_runtime_disable(spi_imx->dev); |
| 1869 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1870 | 1870 | ||
| 1871 | clk_disable_unprepare(spi_imx->clk_ipg); | 1871 | clk_disable_unprepare(spi_imx->clk_ipg); |
| 1872 | out_put_per: | 1872 | out_put_per: |
| @@ -245,7 +245,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) · 244 unmodified lines | |||
| 245 | loops = msecs_to_loops(1); | 245 | loops = msecs_to_loops(1); |
| 246 | do { | 246 | do { |
| 247 | val = readl(regs + S3C64XX_SPI_STATUS); | 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 | if (loops == 0) | 250 | if (loops == 0) |
| 251 | dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); | 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 | readl(regs + S3C64XX_SPI_RX_DATA); | 258 | readl(regs + S3C64XX_SPI_RX_DATA); |
| 259 | else | 259 | else |
| 260 | break; | 260 | break; |
| 261 | } while (loops--); | 261 | } while (--loops); |
| 262 | 262 | ||
| 263 | if (loops == 0) | 263 | if (loops == 0) |
| 264 | dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); | 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 | dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); | 692 | dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); |
| 693 | if (!dev->queues) { | 693 | if (!dev->queues) { |
| 694 | dev->transport->free_device(dev); | 694 | hba->backend->ops->free_device(dev); |
| 695 | return NULL; | 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 | ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0, | 2132 | ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0, |
| 2133 | TCMU_MCGRP_CONFIG, GFP_KERNEL); | 2133 | TCMU_MCGRP_CONFIG); |
| 2134 | 2134 | ||
| 2135 | /* Wait during an add as the listener may not be up yet */ | 2135 | /* Wait during an add as the listener may not be up yet */ |
| 2136 | if (ret == 0 || | 2136 | if (ret == 0 || |
| @@ -416,7 +416,6 @@ err_del_legacy: · 415 unmodified lines | |||
| 416 | if (!pci_info->no_legacy) | 416 | if (!pci_info->no_legacy) |
| 417 | proc_thermal_remove(proc_priv); | 417 | proc_thermal_remove(proc_priv); |
| 418 | proc_thermal_mmio_remove(pdev, proc_priv); | 418 | proc_thermal_mmio_remove(pdev, proc_priv); |
| 419 | pci_disable_device(pdev); | ||
| 420 | 419 | ||
| 421 | return ret; | 420 | return ret; |
| 422 | } | 421 | } |
| @@ -438,7 +437,6 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev) · 15 unmodified lines | |||
| 438 | proc_thermal_mmio_remove(pdev, pci_info->proc_priv); | 437 | proc_thermal_mmio_remove(pdev, pci_info->proc_priv); |
| 439 | if (!pci_info->no_legacy) | 438 | if (!pci_info->no_legacy) |
| 440 | proc_thermal_remove(proc_priv); | 439 | proc_thermal_remove(proc_priv); |
| 441 | pci_disable_device(pdev); | ||
| 442 | } | 440 | } |
| 443 | 441 | ||
| 444 | #ifdef CONFIG_PM_SLEEP | 442 | #ifdef CONFIG_PM_SLEEP |
| @@ -13,48 +13,12 @@ static struct rapl_if_priv rapl_mmio_priv; · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | static const struct rapl_mmio_regs rapl_mmio_default = { | 14 | static const struct rapl_mmio_regs rapl_mmio_default = { |
| 15 | .reg_unit = 0x5938, | 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 | .regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0}, | 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 | .limits[RAPL_DOMAIN_DRAM] = BIT(POWER_LIMIT2), | 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 | static int rapl_mmio_read_raw(int cpu, struct reg_action *ra) | 22 | static int rapl_mmio_read_raw(int cpu, struct reg_action *ra) |
| 59 | { | 23 | { |
| 60 | if (!ra->reg.mmio) | 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 | int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) | 46 | int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) |
| 83 | { | 47 | { |
| 84 | const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default; | 48 | const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default; |
| 49 | struct rapl_package *rp; | ||
| 85 | enum rapl_domain_reg_id reg; | 50 | enum rapl_domain_reg_id reg; |
| 86 | enum rapl_domain_type domain; | 51 | enum rapl_domain_type domain; |
| 87 | int ret; | 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 | return PTR_ERR(rapl_mmio_priv.control_type); | 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", | 77 | /* Register a RAPL package device for package 0 which is always online */ |
| 113 | rapl_mmio_cpu_online, rapl_mmio_cpu_down_prep); | 78 | rp = rapl_find_package_domain(0, &rapl_mmio_priv, false); |
| 114 | if (ret < 0) { | 79 | if (rp) { |
| 115 | powercap_unregister_control_type(rapl_mmio_priv.control_type); | 80 | ret = -EEXIST; |
| 116 | rapl_mmio_priv.control_type = NULL; | 81 | goto err; |
| 117 | return ret; | 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 | return 0; | 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 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_add); | 97 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_add); |
| 124 | 98 | ||
| 125 | void proc_thermal_rapl_remove(void) | 99 | void proc_thermal_rapl_remove(void) |
| 126 | { | 100 | { |
| 101 | struct rapl_package *rp; | ||
| 102 | |||
| 127 | if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type)) | 103 | if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type)) |
| 128 | return; | 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 | powercap_unregister_control_type(rapl_mmio_priv.control_type); | 109 | powercap_unregister_control_type(rapl_mmio_priv.control_type); |
| 132 | } | 110 | } |
| 133 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_remove); | 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 | mutex_lock(&thermal_list_lock); | 728 | mutex_lock(&thermal_list_lock); |
| 729 | list_for_each_entry(tz, &thermal_tz_list, node) { | 729 | list_for_each_entry(tz, &thermal_tz_list, node) { |
| 730 | if (tz->id == id) { | 730 | if (tz->id == id) { |
| 731 | get_device(&tz->device); | ||
| 731 | match = tz; | 732 | match = tz; |
| 732 | break; | 733 | break; |
| 733 | } | 734 | } |
| @@ -1605,14 +1606,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) · 871 unmodified lines | |||
| 1605 | ida_destroy(&tz->ida); | 1606 | ida_destroy(&tz->ida); |
| 1606 | 1607 | ||
| 1607 | device_del(&tz->device); | 1608 | device_del(&tz->device); |
| 1608 | |||
| 1609 | kfree(tz->tzp); | ||
| 1610 | |||
| 1611 | put_device(&tz->device); | 1609 | put_device(&tz->device); |
| 1612 | 1610 | ||
| 1613 | thermal_notify_tz_delete(tz); | 1611 | thermal_notify_tz_delete(tz); |
| 1614 | 1612 | ||
| 1615 | wait_for_completion(&tz->removal); | 1613 | wait_for_completion(&tz->removal); |
| 1614 | kfree(tz->tzp); | ||
| 1616 | kfree(tz); | 1615 | kfree(tz); |
| 1617 | } | 1616 | } |
| 1618 | EXPORT_SYMBOL_GPL(thermal_zone_device_unregister); | 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 | struct thermal_zone_device *thermal_zone_get_by_id(int id); | 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 | static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) | 200 | static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) |
| 198 | { | 201 | { |
| 199 | return cdev->ops->get_requested_power && cdev->ops->state2power && | 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 | struct sk_buff *msg = p->msg; | 444 | struct sk_buff *msg = p->msg; |
| 445 | const struct thermal_trip_desc *td; | 445 | const struct thermal_trip_desc *td; |
| 446 | struct thermal_zone_device *tz; | ||
| 447 | struct nlattr *start_trip; | 446 | struct nlattr *start_trip; |
| 448 | int id; | 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 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); | 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 | if (!tz) | 455 | if (!tz) |
| 457 | return -EINVAL; | 456 | return -EINVAL; |
| 458 | 457 | ||
| @@ -488,7 +487,6 @@ out_cancel_nest: · 29 unmodified lines | |||
| 488 | static int thermal_genl_cmd_tz_get_temp(struct param *p) | 487 | static int thermal_genl_cmd_tz_get_temp(struct param *p) |
| 489 | { | 488 | { |
| 490 | struct sk_buff *msg = p->msg; | 489 | struct sk_buff *msg = p->msg; |
| 491 | struct thermal_zone_device *tz; | ||
| 492 | int temp, ret, id; | 490 | int temp, ret, id; |
| 493 | 491 | ||
| 494 | if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) | 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 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); | 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 | if (!tz) | 498 | if (!tz) |
| 501 | return -EINVAL; | 499 | return -EINVAL; |
| 502 | 500 | ||
| @@ -514,7 +512,6 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p) · 11 unmodified lines | |||
| 514 | static int thermal_genl_cmd_tz_get_gov(struct param *p) | 512 | static int thermal_genl_cmd_tz_get_gov(struct param *p) |
| 515 | { | 513 | { |
| 516 | struct sk_buff *msg = p->msg; | 514 | struct sk_buff *msg = p->msg; |
| 517 | struct thermal_zone_device *tz; | ||
| 518 | int id, ret = 0; | 515 | int id, ret = 0; |
| 519 | 516 | ||
| 520 | if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) | 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 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); | 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 | if (!tz) | 523 | if (!tz) |
| 527 | return -EINVAL; | 524 | return -EINVAL; |
| 528 | 525 | ||
| @@ -3157,6 +3157,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) · 3156 unmodified lines | |||
| 3157 | mutex_unlock(&gsm->mutex); | 3157 | mutex_unlock(&gsm->mutex); |
| 3158 | /* Now wipe the queues */ | 3158 | /* Now wipe the queues */ |
| 3159 | tty_ldisc_flush(gsm->tty); | 3159 | tty_ldisc_flush(gsm->tty); |
| 3160 | |||
| 3161 | guard(spinlock_irqsave)(&gsm->tx_lock); | ||
| 3160 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list) | 3162 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list) |
| 3161 | kfree(txq); | 3163 | kfree(txq); |
| 3162 | INIT_LIST_HEAD(&gsm->tx_ctrl_list); | 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 | imx_uart_writel(sport, USR1_RTSD, USR1); | 763 | imx_uart_writel(sport, USR1_RTSD, USR1); |
| 764 | usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS; | 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 | uart_handle_cts_change(&sport->port, usr1); | 780 | uart_handle_cts_change(&sport->port, usr1); |
| 766 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); | 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 | static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); | 148 | static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); |
| 149 | static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); | 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 | static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport) | 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 | writel(c, uport->membase + SE_GENI_TX_FIFOn); | 396 | writel(c, uport->membase + SE_GENI_TX_FIFOn); |
| 396 | qcom_geni_serial_poll_tx_done(uport); | 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 | #endif | 416 | #endif |
| 399 | 417 | ||
| 400 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE | 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 | #endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */ | 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 | struct qcom_geni_serial_port *port = to_dev_port(uport); | 585 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 568 | struct tty_port *tport = &uport->state->port; | 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 | ret = tty_insert_flip_string(tport, port->rx_buf, bytes); | 589 | ret = tty_insert_flip_string(tport, port->rx_buf, bytes); |
| 572 | if (ret != bytes) { | 590 | if (ret != bytes) { |
| 573 | dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n", | 591 | dev_err_ratelimited(uport->dev, "failed to push data (%d < %u)\n", |
| 574 | __func__, ret, bytes); | 592 | ret, bytes); |
| 575 | WARN_ON_ONCE(1); | ||
| 576 | } | 593 | } |
| 577 | uport->icount.rx += ret; | 594 | uport->icount.rx += ret; |
| 578 | tty_flip_buffer_push(tport); | 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 | static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport) | 804 | static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport) |
| 788 | { | 805 | { |
| 789 | struct qcom_geni_serial_port *port = to_dev_port(uport); | 806 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 807 | bool done; | ||
| 790 | 808 | ||
| 791 | if (!qcom_geni_serial_secondary_active(uport)) | 809 | if (!qcom_geni_serial_secondary_active(uport)) |
| 792 | return; | 810 | return; |
| 793 | 811 | ||
| 794 | geni_se_cancel_s_cmd(&port->se); | 812 | geni_se_cancel_s_cmd(&port->se); |
| 795 | qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS, | 813 | done = qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT, |
| 796 | S_CMD_CANCEL_EN, true); | 814 | RX_EOT, true); |
| 797 | 815 | if (done) { | |
| 798 | if (qcom_geni_serial_secondary_active(uport)) | 816 | writel(RX_EOT | RX_DMA_DONE, |
| 817 | uport->membase + SE_DMA_RX_IRQ_CLR); | ||
| 818 | } else { | ||
| 799 | qcom_geni_serial_abort_rx(uport); | 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 | if (port->rx_dma_addr) { | 828 | if (port->rx_dma_addr) { |
| 802 | geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, | 829 | geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, |
| 803 | DMA_RX_BUF_SIZE); | 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 | if (!drop) | 875 | if (!drop) |
| 849 | handle_rx_uart(uport, rx_in, drop); | 876 | handle_rx_uart(uport, rx_in); |
| 850 | 877 | ||
| 851 | ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, | 878 | ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, |
| 852 | DMA_RX_BUF_SIZE, | 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 | disable_irq(uport->irq); | 1124 | disable_irq(uport->irq); |
| 1098 | 1125 | ||
| 1126 | uart_port_lock_irq(uport); | ||
| 1099 | qcom_geni_serial_stop_tx(uport); | 1127 | qcom_geni_serial_stop_tx(uport); |
| 1100 | qcom_geni_serial_stop_rx(uport); | 1128 | qcom_geni_serial_stop_rx(uport); |
| 1101 | 1129 | ||
| 1102 | qcom_geni_serial_cancel_tx_cmd(uport); | 1130 | qcom_geni_serial_cancel_tx_cmd(uport); |
| 1131 | uart_port_unlock_irq(uport); | ||
| 1103 | } | 1132 | } |
| 1104 | 1133 | ||
| 1105 | static void qcom_geni_serial_flush_buffer(struct uart_port *uport) | 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 | false, true, true); | 1181 | false, true, true); |
| 1153 | geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); | 1182 | geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); |
| 1154 | geni_se_select_mode(&port->se, port->dev_data->mode); | 1183 | geni_se_select_mode(&port->se, port->dev_data->mode); |
| 1155 | qcom_geni_serial_start_rx(uport); | ||
| 1156 | port->setup = true; | 1184 | port->setup = true; |
| 1157 | 1185 | ||
| 1158 | return 0; | 1186 | return 0; |
| @@ -1168,6 +1196,11 @@ static int qcom_geni_serial_startup(struct uart_port *uport) · 9 unmodified lines | |||
| 1168 | if (ret) | 1196 | if (ret) |
| 1169 | return ret; | 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 | enable_irq(uport->irq); | 1204 | enable_irq(uport->irq); |
| 1172 | 1205 | ||
| 1173 | return 0; | 1206 | return 0; |
| @@ -1253,7 +1286,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, · 79 unmodified lines | |||
| 1253 | unsigned int avg_bw_core; | 1286 | unsigned int avg_bw_core; |
| 1254 | unsigned long timeout; | 1287 | unsigned long timeout; |
| 1255 | 1288 | ||
| 1256 | qcom_geni_serial_stop_rx(uport); | ||
| 1257 | /* baud rate */ | 1289 | /* baud rate */ |
| 1258 | baud = uart_get_baud_rate(uport, termios, old, 300, 4000000); | 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 | dev_err(port->se.dev, | 1301 | dev_err(port->se.dev, |
| 1270 | "Couldn't find suitable clock rate for %u\n", | 1302 | "Couldn't find suitable clock rate for %u\n", |
| 1271 | baud * sampling_rate); | 1303 | baud * sampling_rate); |
| 1272 | goto out_restart_rx; | 1304 | return; |
| 1273 | } | 1305 | } |
| 1274 | 1306 | ||
| 1275 | dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n", | 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 | writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); | 1392 | writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); |
| 1361 | writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); | 1393 | writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); |
| 1362 | writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG); | 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 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE | 1397 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE |
| @@ -1582,7 +1612,7 @@ static const struct uart_ops qcom_geni_console_pops = { · 214 unmodified lines | |||
| 1582 | #ifdef CONFIG_CONSOLE_POLL | 1612 | #ifdef CONFIG_CONSOLE_POLL |
| 1583 | .poll_get_char = qcom_geni_serial_get_char, | 1613 | .poll_get_char = qcom_geni_serial_get_char, |
| 1584 | .poll_put_char = qcom_geni_serial_poll_put_char, | 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 | #endif | 1616 | #endif |
| 1587 | .pm = qcom_geni_serial_pm, | 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 | uart_remove_one_port(drv, &port->uport); | 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 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); | 1784 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
| 1755 | struct uart_port *uport = &port->uport; | 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 | return uart_suspend_port(private_data->drv, uport); | 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 | int ret; | 1801 | int ret; |
| 1772 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); | 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 | return ret; | 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 | static const struct qcom_geni_device_data qcom_geni_console_data = { | 1814 | static const struct qcom_geni_device_data qcom_geni_console_data = { |
| 1817 | .console = true, | 1815 | .console = true, |
| 1818 | .mode = GENI_SE_FIFO, | 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 | static const struct dev_pm_ops qcom_geni_serial_pm_ops = { | 1824 | static const struct dev_pm_ops qcom_geni_serial_pm_ops = { |
| 1827 | .suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend), | 1825 | SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume) |
| 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), | ||
| 1833 | }; | 1826 | }; |
| 1834 | 1827 | ||
| 1835 | static const struct of_device_id qcom_geni_serial_match_table[] = { | 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 | return -EINVAL; | 4726 | return -EINVAL; |
| 4727 | 4727 | ||
| 4728 | if (op->data) { | 4728 | if (op->data) { |
| 4729 | font.data = kvmalloc(max_font_size, GFP_KERNEL); | 4729 | font.data = kvzalloc(max_font_size, GFP_KERNEL); |
| 4730 | if (!font.data) | 4730 | if (!font.data) |
| 4731 | return -ENOMEM; | 4731 | return -ENOMEM; |
| 4732 | } else | 4732 | } else |
| @@ -539,7 +539,7 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag) · 538 unmodified lines | |||
| 539 | struct scsi_cmnd *cmd = lrbp->cmd; | 539 | struct scsi_cmnd *cmd = lrbp->cmd; |
| 540 | struct ufs_hw_queue *hwq; | 540 | struct ufs_hw_queue *hwq; |
| 541 | void __iomem *reg, *opr_sqd_base; | 541 | void __iomem *reg, *opr_sqd_base; |
| 542 | u32 nexus, id, val; | 542 | u32 nexus, id, val, rtc; |
| 543 | int err; | 543 | int err; |
| 544 | 544 | ||
| 545 | if (hba->quirks & UFSHCD_QUIRK_MCQ_BROKEN_RTC) | 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 | opr_sqd_base = mcq_opr_base(hba, OPR_SQD, id); | 569 | opr_sqd_base = mcq_opr_base(hba, OPR_SQD, id); |
| 570 | writel(nexus, opr_sqd_base + REG_SQCTI); | 570 | writel(nexus, opr_sqd_base + REG_SQCTI); |
| 571 | 571 | ||
| 572 | /* SQRTCy.ICU = 1 */ | 572 | /* Initiate Cleanup */ |
| 573 | writel(SQ_ICU, opr_sqd_base + REG_SQRTC); | 573 | writel(readl(opr_sqd_base + REG_SQRTC) | SQ_ICU, |
| 574 | opr_sqd_base + REG_SQRTC); | ||
| 574 | 575 | ||
| 575 | /* Poll SQRTSy.CUS = 1. Return result from SQRTSy.RTC */ | 576 | /* Poll SQRTSy.CUS = 1. Return result from SQRTSy.RTC */ |
| 576 | reg = opr_sqd_base + REG_SQRTS; | 577 | reg = opr_sqd_base + REG_SQRTS; |
| 577 | err = read_poll_timeout(readl, val, val & SQ_CUS, 20, | 578 | err = read_poll_timeout(readl, val, val & SQ_CUS, 20, |
| 578 | MCQ_POLL_US, false, reg); | 579 | MCQ_POLL_US, false, reg); |
| 579 | if (err) | 580 | rtc = FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg)); |
| 580 | dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%ld\n", | 581 | if (err || rtc) |
| 581 | __func__, id, task_tag, | 582 | dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%d RTC=%d\n", |
| 582 | FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg))); | 583 | __func__, id, task_tag, err, rtc); |
| 583 | 584 | ||
| 584 | if (ufshcd_mcq_sq_start(hba, hwq)) | 585 | if (ufshcd_mcq_sq_start(hba, hwq)) |
| 585 | err = -ETIMEDOUT; | 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 | struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr; | 2933 | struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr; |
| 2934 | dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr + | 2934 | dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr + |
| 2935 | i * ufshcd_get_ucd_size(hba); | 2935 | i * ufshcd_get_ucd_size(hba); |
| 2936 | u16 response_offset = offsetof(struct utp_transfer_cmd_desc, | 2936 | u16 response_offset = le16_to_cpu(utrdlp[i].response_upiu_offset); |
| 2937 | response_upiu); | 2937 | u16 prdt_offset = le16_to_cpu(utrdlp[i].prd_table_offset); |
| 2938 | u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table); | ||
| 2939 | 2938 | ||
| 2940 | lrb->utr_descriptor_ptr = utrdlp + i; | 2939 | lrb->utr_descriptor_ptr = utrdlp + i; |
| 2941 | lrb->utrd_dma_addr = hba->utrdl_dma_addr + | 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 | break; | 5417 | break; |
| 5419 | case OCS_ABORTED: | 5418 | case OCS_ABORTED: |
| 5420 | result |= DID_ABORT << 16; | ||
| 5421 | break; | ||
| 5422 | case OCS_INVALID_COMMAND_STATUS: | 5419 | case OCS_INVALID_COMMAND_STATUS: |
| 5423 | result |= DID_REQUEUE << 16; | 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 | break; | 5425 | break; |
| 5425 | case OCS_INVALID_CMD_TABLE_ATTR: | 5426 | case OCS_INVALID_CMD_TABLE_ATTR: |
| 5426 | case OCS_INVALID_PRDT_ATTR: | 5427 | case OCS_INVALID_PRDT_ATTR: |
| @@ -6466,26 +6467,12 @@ static bool ufshcd_abort_one(struct request *rq, void *priv) · 1039 unmodified lines | |||
| 6466 | struct scsi_device *sdev = cmd->device; | 6467 | struct scsi_device *sdev = cmd->device; |
| 6467 | struct Scsi_Host *shost = sdev->host; | 6468 | struct Scsi_Host *shost = sdev->host; |
| 6468 | struct ufs_hba *hba = shost_priv(shost); | 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 | *ret = ufshcd_try_to_abort_task(hba, tag); | 6471 | *ret = ufshcd_try_to_abort_task(hba, tag); |
| 6474 | dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag, | 6472 | dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag, |
| 6475 | hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1, | 6473 | hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1, |
| 6476 | *ret ? "failed" : "succeeded"); | 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 | return *ret == 0; | 6476 | return *ret == 0; |
| 6490 | } | 6477 | } |
| 6491 | 6478 | ||
| @@ -10210,7 +10197,9 @@ static void ufshcd_wl_shutdown(struct device *dev) · 3718 unmodified lines | |||
| 10210 | shost_for_each_device(sdev, hba->host) { | 10197 | shost_for_each_device(sdev, hba->host) { |
| 10211 | if (sdev == hba->ufs_device_wlun) | 10198 | if (sdev == hba->ufs_device_wlun) |
| 10212 | continue; | 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 | __ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM); | 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 | int dwc3_event_buffers_setup(struct dwc3 *dwc) | 544 | int dwc3_event_buffers_setup(struct dwc3 *dwc) |
| 545 | { | 545 | { |
| 546 | struct dwc3_event_buffer *evt; | 546 | struct dwc3_event_buffer *evt; |
| 547 | u32 reg; | ||
| 547 | 548 | ||
| 548 | if (!dwc->ev_buf) | 549 | if (!dwc->ev_buf) |
| 549 | return 0; | 550 | return 0; |
| @@ -556,8 +557,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) · 6 unmodified lines | |||
| 556 | upper_32_bits(evt->dma)); | 557 | upper_32_bits(evt->dma)); |
| 557 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), | 558 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), |
| 558 | DWC3_GEVNTSIZ_SIZE(evt->length)); | 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 | return 0; | 564 | return 0; |
| 562 | } | 565 | } |
| 563 | 566 | ||
| @@ -584,7 +587,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) · 20 unmodified lines | |||
| 584 | dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0); | 587 | dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0); |
| 585 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK | 588 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK |
| 586 | | DWC3_GEVNTSIZ_SIZE(0)); | 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 | static void dwc3_core_num_eps(struct dwc3 *dwc) | 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 | u32 reg; | 2342 | u32 reg; |
| 2337 | int i; | 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 | switch (dwc->current_dr_role) { | 2350 | switch (dwc->current_dr_role) { |
| 2340 | case DWC3_GCTL_PRTCAP_DEVICE: | 2351 | case DWC3_GCTL_PRTCAP_DEVICE: |
| 2341 | if (pm_runtime_suspended(dwc->dev)) | 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 | break; | 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 | return 0; | 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 | break; | 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 | return 0; | 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 | switch (dwc->current_dr_role) { | 2525 | switch (dwc->current_dr_role) { |
| 2501 | case DWC3_GCTL_PRTCAP_DEVICE: | 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 | break; | 2532 | break; |
| 2504 | case DWC3_GCTL_PRTCAP_HOST: | 2533 | case DWC3_GCTL_PRTCAP_HOST: |
| 2505 | default: | 2534 | default: |
| @@ -2552,7 +2581,7 @@ static int dwc3_suspend(struct device *dev) · 46 unmodified lines | |||
| 2552 | static int dwc3_resume(struct device *dev) | 2581 | static int dwc3_resume(struct device *dev) |
| 2553 | { | 2582 | { |
| 2554 | struct dwc3 *dwc = dev_get_drvdata(dev); | 2583 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 2555 | int ret; | 2584 | int ret = 0; |
| 2556 | 2585 | ||
| 2557 | pinctrl_pm_select_default_state(dev); | 2586 | pinctrl_pm_select_default_state(dev); |
| 2558 | 2587 | ||
| @@ -2560,14 +2589,12 @@ static int dwc3_resume(struct device *dev) · 1 unmodified line | |||
| 2560 | pm_runtime_set_active(dev); | 2589 | pm_runtime_set_active(dev); |
| 2561 | 2590 | ||
| 2562 | ret = dwc3_resume_common(dwc, PMSG_RESUME); | 2591 | ret = dwc3_resume_common(dwc, PMSG_RESUME); |
| 2563 | if (ret) { | 2592 | if (ret) |
| 2564 | pm_runtime_set_suspended(dev); | 2593 | pm_runtime_set_suspended(dev); |
| 2565 | return ret; | ||
| 2566 | } | ||
| 2567 | 2594 | ||
| 2568 | pm_runtime_enable(dev); | 2595 | pm_runtime_enable(dev); |
| 2569 | 2596 | ||
| 2570 | return 0; | 2597 | return ret; |
| 2571 | } | 2598 | } |
| 2572 | 2599 | ||
| 2573 | static void dwc3_complete(struct device *dev) | 2600 | static void dwc3_complete(struct device *dev) |
| @@ -2589,6 +2616,12 @@ static void dwc3_complete(struct device *dev) · 15 unmodified lines | |||
| 2589 | static const struct dev_pm_ops dwc3_dev_pm_ops = { | 2616 | static const struct dev_pm_ops dwc3_dev_pm_ops = { |
| 2590 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) | 2617 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) |
| 2591 | .complete = dwc3_complete, | 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 | SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, | 2625 | SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, |
| 2593 | dwc3_runtime_idle) | 2626 | dwc3_runtime_idle) |
| 2594 | }; | 2627 | }; |
| @@ -1150,6 +1150,8 @@ struct dwc3_scratchpad_array { · 1149 unmodified lines | |||
| 1150 | * @sys_wakeup: set if the device may do system wakeup. | 1150 | * @sys_wakeup: set if the device may do system wakeup. |
| 1151 | * @wakeup_configured: set if the device is configured for remote wakeup. | 1151 | * @wakeup_configured: set if the device is configured for remote wakeup. |
| 1152 | * @suspended: set to track suspend event due to U3/L2. | 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 | * @imod_interval: set the interrupt moderation interval in 250ns | 1155 | * @imod_interval: set the interrupt moderation interval in 250ns |
| 1154 | * increments or 0 to disable. | 1156 | * increments or 0 to disable. |
| 1155 | * @max_cfg_eps: current max number of IN eps used across all USB configs. | 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 | unsigned sys_wakeup:1; | 1384 | unsigned sys_wakeup:1; |
| 1383 | unsigned wakeup_configured:1; | 1385 | unsigned wakeup_configured:1; |
| 1384 | unsigned suspended:1; | 1386 | unsigned suspended:1; |
| 1387 | unsigned susphy_state:1; | ||
| 1385 | 1388 | ||
| 1386 | u16 imod_interval; | 1389 | u16 imod_interval; |
| 1387 | 1390 | ||
| @@ -1675,7 +1678,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc) · 287 unmodified lines | |||
| 1675 | #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) | 1678 | #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) |
| 1676 | int dwc3_gadget_suspend(struct dwc3 *dwc); | 1679 | int dwc3_gadget_suspend(struct dwc3 *dwc); |
| 1677 | int dwc3_gadget_resume(struct dwc3 *dwc); | 1680 | int dwc3_gadget_resume(struct dwc3 *dwc); |
| 1678 | void dwc3_gadget_process_pending_events(struct dwc3 *dwc); | ||
| 1679 | #else | 1681 | #else |
| 1680 | static inline int dwc3_gadget_suspend(struct dwc3 *dwc) | 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 | return 0; | 1689 | return 0; |
| 1688 | } | 1690 | } |
| 1689 | 1691 | ||
| 1690 | static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc) | ||
| 1691 | { | ||
| 1692 | } | ||
| 1693 | #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ | 1692 | #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ |
| 1694 | 1693 | ||
| 1695 | #if IS_ENABLED(CONFIG_USB_DWC3_ULPI) | 1694 | #if IS_ENABLED(CONFIG_USB_DWC3_ULPI) |
| @@ -438,6 +438,10 @@ skip_status: · 437 unmodified lines | |||
| 438 | dwc3_gadget_ep_get_transfer_index(dep); | 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 | if (saved_config) { | 445 | if (saved_config) { |
| 442 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | 446 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
| 443 | reg |= saved_config; | 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 | WARN_ON_ONCE(ret); | 1719 | WARN_ON_ONCE(ret); |
| 1716 | dep->resource_index = 0; | 1720 | dep->resource_index = 0; |
| 1717 | 1721 | ||
| 1718 | if (!interrupt) { | 1722 | if (!interrupt) |
| 1719 | mdelay(1); | ||
| 1720 | dep->flags &= ~DWC3_EP_TRANSFER_STARTED; | 1723 | dep->flags &= ~DWC3_EP_TRANSFER_STARTED; |
| 1721 | } else if (!ret) { | 1724 | else if (!ret) |
| 1722 | dep->flags |= DWC3_EP_END_TRANSFER_PENDING; | 1725 | dep->flags |= DWC3_EP_END_TRANSFER_PENDING; |
| 1723 | } | ||
| 1724 | 1726 | ||
| 1725 | dep->flags &= ~DWC3_EP_DELAY_STOP; | 1727 | dep->flags &= ~DWC3_EP_DELAY_STOP; |
| 1726 | return ret; | 1728 | return ret; |
| @@ -4728,14 +4730,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc) · 3001 unmodified lines | |||
| 4728 | 4730 | ||
| 4729 | return dwc3_gadget_soft_connect(dwc); | 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 | const char *page, size_t len) \ | 2061 | const char *page, size_t len) \ |
| 2062 | { \ | 2062 | { \ |
| 2063 | struct f_uac2_opts *opts = to_f_uac2_opts(item); \ | 2063 | struct f_uac2_opts *opts = to_f_uac2_opts(item); \ |
| 2064 | int ret = 0; \ | 2064 | int ret = len; \ |
| 2065 | \ | 2065 | \ |
| 2066 | mutex_lock(&opts->lock); \ | 2066 | mutex_lock(&opts->lock); \ |
| 2067 | if (opts->refcnt) { \ | 2067 | if (opts->refcnt) { \ |
| @@ -2072,8 +2072,8 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ · 4 unmodified lines | |||
| 2072 | if (len && page[len - 1] == '\n') \ | 2072 | if (len && page[len - 1] == '\n') \ |
| 2073 | len--; \ | 2073 | len--; \ |
| 2074 | \ | 2074 | \ |
| 2075 | ret = scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ | 2075 | scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ |
| 2076 | "%s", page); \ | 2076 | "%s", page); \ |
| 2077 | \ | 2077 | \ |
| 2078 | end: \ | 2078 | end: \ |
| 2079 | mutex_unlock(&opts->lock); \ | 2079 | mutex_unlock(&opts->lock); \ |
| @@ -1696,6 +1696,7 @@ int usb_gadget_register_driver_owner(struct usb_gadget_driver *driver, · 1695 unmodified lines | |||
| 1696 | driver->driver.bus = &gadget_bus_type; | 1696 | driver->driver.bus = &gadget_bus_type; |
| 1697 | driver->driver.owner = owner; | 1697 | driver->driver.owner = owner; |
| 1698 | driver->driver.mod_name = mod_name; | 1698 | driver->driver.mod_name = mod_name; |
| 1699 | driver->driver.probe_type = PROBE_FORCE_SYNCHRONOUS; | ||
| 1699 | ret = driver_register(&driver->driver); | 1700 | ret = driver_register(&driver->driver); |
| 1700 | if (ret) { | 1701 | if (ret) { |
| 1701 | pr_warn("%s: driver registration failed: %d\n", | 1702 | pr_warn("%s: driver registration failed: %d\n", |
| @@ -254,6 +254,7 @@ struct dummy_hcd { · 253 unmodified lines | |||
| 254 | u32 stream_en_ep; | 254 | u32 stream_en_ep; |
| 255 | u8 num_stream[30 / 2]; | 255 | u8 num_stream[30 / 2]; |
| 256 | 256 | ||
| 257 | unsigned timer_pending:1; | ||
| 257 | unsigned active:1; | 258 | unsigned active:1; |
| 258 | unsigned old_active:1; | 259 | unsigned old_active:1; |
| 259 | unsigned resuming:1; | 260 | unsigned resuming:1; |
| @@ -1303,9 +1304,11 @@ static int dummy_urb_enqueue( · 1043 unmodified lines | |||
| 1303 | urb->error_count = 1; /* mark as a new urb */ | 1304 | urb->error_count = 1; /* mark as a new urb */ |
| 1304 | 1305 | ||
| 1305 | /* kick the scheduler, it'll do the rest */ | 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 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), | 1309 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), |
| 1308 | HRTIMER_MODE_REL_SOFT); | 1310 | HRTIMER_MODE_REL_SOFT); |
| 1311 | } | ||
| 1309 | 1312 | ||
| 1310 | done: | 1313 | done: |
| 1311 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); | 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 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); | 1327 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
| 1325 | 1328 | ||
| 1326 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | 1329 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
| 1327 | if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING && | 1330 | if (rc == 0 && !dum_hcd->timer_pending) { |
| 1328 | !list_empty(&dum_hcd->urbp_list)) | 1331 | dum_hcd->timer_pending = 1; |
| 1329 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); | 1332 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); |
| 1333 | } | ||
| 1330 | 1334 | ||
| 1331 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); | 1335 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
| 1332 | return rc; | 1336 | return rc; |
| @@ -1813,6 +1817,7 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t) · 480 unmodified lines | |||
| 1813 | 1817 | ||
| 1814 | /* look at each urb queued by the host side driver */ | 1818 | /* look at each urb queued by the host side driver */ |
| 1815 | spin_lock_irqsave(&dum->lock, flags); | 1819 | spin_lock_irqsave(&dum->lock, flags); |
| 1820 | dum_hcd->timer_pending = 0; | ||
| 1816 | 1821 | ||
| 1817 | if (!dum_hcd->udev) { | 1822 | if (!dum_hcd->udev) { |
| 1818 | dev_err(dummy_dev(dum_hcd), | 1823 | dev_err(dummy_dev(dum_hcd), |
| @@ -1994,8 +1999,10 @@ return_urb: · 175 unmodified lines | |||
| 1994 | if (list_empty(&dum_hcd->urbp_list)) { | 1999 | if (list_empty(&dum_hcd->urbp_list)) { |
| 1995 | usb_put_dev(dum_hcd->udev); | 2000 | usb_put_dev(dum_hcd->udev); |
| 1996 | dum_hcd->udev = NULL; | 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 | /* want a 1 msec delay here */ | 2004 | /* want a 1 msec delay here */ |
| 2005 | dum_hcd->timer_pending = 1; | ||
| 1999 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), | 2006 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), |
| 2000 | HRTIMER_MODE_REL_SOFT); | 2007 | HRTIMER_MODE_REL_SOFT); |
| 2001 | } | 2008 | } |
| @@ -2390,8 +2397,10 @@ static int dummy_bus_resume(struct usb_hcd *hcd) · 388 unmodified lines | |||
| 2390 | } else { | 2397 | } else { |
| 2391 | dum_hcd->rh_state = DUMMY_RH_RUNNING; | 2398 | dum_hcd->rh_state = DUMMY_RH_RUNNING; |
| 2392 | set_link_state(dum_hcd); | 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 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); | 2402 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); |
| 2403 | } | ||
| 2395 | hcd->state = HC_STATE_RUNNING; | 2404 | hcd->state = HC_STATE_RUNNING; |
| 2396 | } | 2405 | } |
| 2397 | spin_unlock_irq(&dum_hcd->dum->lock); | 2406 | spin_unlock_irq(&dum_hcd->dum->lock); |
| @@ -2522,6 +2531,7 @@ static void dummy_stop(struct usb_hcd *hcd) · 124 unmodified lines | |||
| 2522 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); | 2531 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
| 2523 | 2532 | ||
| 2524 | hrtimer_cancel(&dum_hcd->timer); | 2533 | hrtimer_cancel(&dum_hcd->timer); |
| 2534 | dum_hcd->timer_pending = 0; | ||
| 2525 | device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs); | 2535 | device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs); |
| 2526 | dev_info(dummy_dev(dum_hcd), "stopped\n"); | 2536 | dev_info(dummy_dev(dum_hcd), "stopped\n"); |
| 2527 | } | 2537 | } |
| @@ -110,6 +110,7 @@ struct dbc_port { · 109 unmodified lines | |||
| 110 | struct tasklet_struct push; | 110 | struct tasklet_struct push; |
| 111 | 111 | ||
| 112 | struct list_head write_pool; | 112 | struct list_head write_pool; |
| 113 | unsigned int tx_boundary; | ||
| 113 | 114 | ||
| 114 | bool registered; | 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 | return dbc->priv; | 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 | static int dbc_start_tx(struct dbc_port *port) | 50 | static int dbc_start_tx(struct dbc_port *port) |
| 28 | __releases(&port->port_lock) | 51 | __releases(&port->port_lock) |
| 29 | __acquires(&port->port_lock) | 52 | __acquires(&port->port_lock) |
| @@ -36,7 +59,7 @@ static int dbc_start_tx(struct dbc_port *port) · 6 unmodified lines | |||
| 36 | 59 | ||
| 37 | while (!list_empty(pool)) { | 60 | while (!list_empty(pool)) { |
| 38 | req = list_entry(pool->next, struct dbc_request, list_pool); | 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 | if (len == 0) | 63 | if (len == 0) |
| 41 | break; | 64 | break; |
| 42 | do_tty_wake = true; | 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 | struct dbc_port *port = tty->driver_data; | 224 | struct dbc_port *port = tty->driver_data; |
| 202 | unsigned long flags; | 225 | unsigned long flags; |
| 226 | unsigned int written = 0; | ||
| 203 | 227 | ||
| 204 | spin_lock_irqsave(&port->port_lock, flags); | 228 | spin_lock_irqsave(&port->port_lock, flags); |
| 205 | if (count) | 229 | |
| 206 | count = kfifo_in(&port->port.xmit_fifo, buf, count); | 230 | /* |
| 207 | dbc_start_tx(port); | 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 | spin_unlock_irqrestore(&port->port_lock, flags); | 249 | spin_unlock_irqrestore(&port->port_lock, flags); |
| 209 | 250 | ||
| 210 | return count; | 251 | return written; |
| 211 | } | 252 | } |
| 212 | 253 | ||
| 213 | static int dbc_tty_put_char(struct tty_struct *tty, u8 ch) | 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 | spin_lock_irqsave(&port->port_lock, flags); | 283 | spin_lock_irqsave(&port->port_lock, flags); |
| 243 | room = kfifo_avail(&port->port.xmit_fifo); | 284 | room = kfifo_avail(&port->port.xmit_fifo); |
| 285 | |||
| 286 | if (port->tx_boundary) | ||
| 287 | room = 0; | ||
| 288 | |||
| 244 | spin_unlock_irqrestore(&port->port_lock, flags); | 289 | spin_unlock_irqrestore(&port->port_lock, flags); |
| 245 | 290 | ||
| 246 | return room; | 291 | return room; |
| @@ -79,6 +79,7 @@ · 78 unmodified lines | |||
| 79 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 | 79 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 |
| 80 | #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 | 80 | #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 |
| 81 | #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 | 81 | #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 |
| 82 | #define PCI_DEVICE_ID_ASMEDIA_3042_XHCI 0x3042 | ||
| 82 | #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 | 83 | #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 |
| 83 | 84 | ||
| 84 | #define PCI_DEVICE_ID_CADENCE 0x17CD | 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 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) | 452 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) |
| 452 | xhci->quirks |= XHCI_ASMEDIA_MODIFY_FLOWCONTROL; | 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 | if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) | 459 | if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) |
| 455 | xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; | 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 | td_to_noop(xhci, ring, cached_td, false); | 1023 | td_to_noop(xhci, ring, cached_td, false); |
| 1024 | cached_td->cancel_status = TD_CLEARED; | 1024 | cached_td->cancel_status = TD_CLEARED; |
| 1025 | } | 1025 | } |
| 1026 | 1026 | td_to_noop(xhci, ring, td, false); | |
| 1027 | td->cancel_status = TD_CLEARING_CACHE; | 1027 | td->cancel_status = TD_CLEARING_CACHE; |
| 1028 | cached_td = td; | 1028 | cached_td = td; |
| 1029 | break; | 1029 | break; |
| @@ -2775,6 +2775,29 @@ static int handle_tx_event(struct xhci_hcd *xhci, · 1745 unmodified lines | |||
| 2775 | return 0; | 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 | if (list_empty(&ep_ring->td_list)) { | 2801 | if (list_empty(&ep_ring->td_list)) { |
| 2779 | /* | 2802 | /* |
| 2780 | * Don't print wanings if ring is empty due to a stopped endpoint generating an | 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 | return 0; | 2859 | return 0; |
| 2837 | } | 2860 | } |
| 2838 | 2861 | ||
| 2839 | /* | 2862 | /* HC is busted, give up! */ |
| 2840 | * xhci 4.10.2 states isoc endpoints should continue | 2863 | xhci_err(xhci, |
| 2841 | * processing the next TD if there was an error mid TD. | 2864 | "ERROR Transfer event TRB DMA ptr not part of current TD ep_index %d comp_code %u\n", |
| 2842 | * So host like NEC don't generate an event for the last | 2865 | ep_index, trb_comp_code); |
| 2843 | * isoc TRB even if the IOC flag is set. | 2866 | trb_in_td(xhci, td, ep_trb_dma, true); |
| 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); | ||
| 2874 | 2867 | ||
| 2875 | return -ESHUTDOWN; | 2868 | return -ESHUTDOWN; |
| 2876 | } | ||
| 2877 | } | 2869 | } |
| 2878 | 2870 | ||
| 2879 | if (ep->skip) { | 2871 | if (ep->skip) { |
| @@ -2183,7 +2183,7 @@ static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool runtime) · 2182 unmodified lines | |||
| 2183 | goto out; | 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 | if (!xhci->usb2_rhub.ports[i]) | 2187 | if (!xhci->usb2_rhub.ports[i]) |
| 2188 | continue; | 2188 | continue; |
| 2189 | portsc = readl(xhci->usb2_rhub.ports[i]->addr); | 2189 | portsc = readl(xhci->usb2_rhub.ports[i]->addr); |
| @@ -1001,7 +1001,7 @@ enum xhci_setup_dev { · 1000 unmodified lines | |||
| 1001 | /* Set TR Dequeue Pointer command TRB fields, 6.4.3.9 */ | 1001 | /* Set TR Dequeue Pointer command TRB fields, 6.4.3.9 */ |
| 1002 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) | 1002 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) |
| 1003 | #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) | 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 | /* Link TRB specific fields */ | 1006 | /* Link TRB specific fields */ |
| 1007 | #define TRB_TC (1<<1) | 1007 | #define TRB_TC (1<<1) |
| @@ -331,3 +331,15 @@ config USB_ONBOARD_DEV · 330 unmodified lines | |||
| 331 | this config will enable the driver and it will automatically | 331 | this config will enable the driver and it will automatically |
| 332 | match the state of the USB subsystem. If this driver is a | 332 | match the state of the USB subsystem. If this driver is a |
| 333 | module it will be called onboard_usb_dev. | 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 | static int onboard_dev_5744_i2c_init(struct i2c_client *client) | 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 | struct device *dev = &client->dev; | 315 | struct device *dev = &client->dev; |
| 316 | int ret; | 316 | int ret; |
| 317 | 317 | ||
| @@ -394,9 +394,11 @@ static int onboard_dev_probe(struct platform_device *pdev) · 76 unmodified lines | |||
| 394 | 394 | ||
| 395 | i2c_node = of_parse_phandle(pdev->dev.of_node, "i2c-bus", 0); | 395 | i2c_node = of_parse_phandle(pdev->dev.of_node, "i2c-bus", 0); |
| 396 | if (i2c_node) { | 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 | client = of_find_i2c_device_by_node(i2c_node); | 400 | client = of_find_i2c_device_by_node(i2c_node); |
| 401 | #endif | ||
| 400 | of_node_put(i2c_node); | 402 | of_node_put(i2c_node); |
| 401 | 403 | ||
| 402 | if (!client) { | 404 | if (!client) { |
| @@ -34,8 +34,6 @@ · 33 unmodified lines | |||
| 34 | #define YUREX_BUF_SIZE 8 | 34 | #define YUREX_BUF_SIZE 8 |
| 35 | #define YUREX_WRITE_TIMEOUT (HZ*2) | 35 | #define YUREX_WRITE_TIMEOUT (HZ*2) |
| 36 | 36 | ||
| 37 | #define MAX_S64_STRLEN 20 /* {-}922337203685477580{7,8} */ | ||
| 38 | |||
| 39 | /* table of devices that work with this driver */ | 37 | /* table of devices that work with this driver */ |
| 40 | static struct usb_device_id yurex_table[] = { | 38 | static struct usb_device_id yurex_table[] = { |
| 41 | { USB_DEVICE(YUREX_VENDOR_ID, YUREX_PRODUCT_ID) }, | 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 | loff_t *ppos) | 400 | loff_t *ppos) |
| 403 | { | 401 | { |
| 404 | struct usb_yurex *dev; | 402 | struct usb_yurex *dev; |
| 405 | int len = 0; | 403 | int len; |
| 406 | char in_buffer[MAX_S64_STRLEN]; | 404 | char in_buffer[20]; |
| 405 | unsigned long flags; | ||
| 407 | 406 | ||
| 408 | dev = file->private_data; | 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 | return -ENODEV; | 412 | return -ENODEV; |
| 414 | } | 413 | } |
| 415 | 414 | ||
| 416 | if (WARN_ON_ONCE(dev->bbu > S64_MAX || dev->bbu < S64_MIN)) { | 415 | spin_lock_irqsave(&dev->lock, flags); |
| 417 | mutex_unlock(&dev->io_mutex); | 416 | len = snprintf(in_buffer, 20, "%lld\n", dev->bbu); |
| 418 | return -EIO; | 417 | spin_unlock_irqrestore(&dev->lock, flags); |
| 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); | ||
| 424 | mutex_unlock(&dev->io_mutex); | 418 | mutex_unlock(&dev->io_mutex); |
| 425 | 419 | ||
| 420 | if (WARN_ON_ONCE(len >= sizeof(in_buffer))) | ||
| 421 | return -EIO; | ||
| 422 | |||
| 426 | return simple_read_from_buffer(buffer, count, ppos, in_buffer, len); | 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 | #define QUECTEL_PRODUCT_EG912Y 0x6001 | 279 | #define QUECTEL_PRODUCT_EG912Y 0x6001 |
| 280 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 | 280 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 |
| 281 | #define QUECTEL_PRODUCT_EC200A 0x6005 | 281 | #define QUECTEL_PRODUCT_EC200A 0x6005 |
| 282 | #define QUECTEL_PRODUCT_EG916Q 0x6007 | ||
| 282 | #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 | 283 | #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 |
| 283 | #define QUECTEL_PRODUCT_EM061K_LCN 0x6009 | 284 | #define QUECTEL_PRODUCT_EM061K_LCN 0x6009 |
| 284 | #define QUECTEL_PRODUCT_EC200T 0x6026 | 285 | #define QUECTEL_PRODUCT_EC200T 0x6026 |
| @@ -1270,6 +1271,7 @@ static const struct usb_device_id option_ids[] = { · 985 unmodified lines | |||
| 1270 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, | 1271 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, |
| 1271 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, | 1272 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, |
| 1272 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG912Y, 0xff, 0, 0) }, | 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 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, | 1275 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, |
| 1274 | 1276 | ||
| 1275 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, | 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 | .driver_info = NCTRL(0) | RSVD(1) }, | 1382 | .driver_info = NCTRL(0) | RSVD(1) }, |
| 1381 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */ | 1383 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */ |
| 1382 | .driver_info = RSVD(0) | NCTRL(3) }, | 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 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ | 1387 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ |
| 1384 | .driver_info = RSVD(0) | NCTRL(3) }, | 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 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */ | 1391 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */ |
| 1386 | .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, | 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 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), | 1395 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), |
| 1388 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, | 1396 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, |
| 1389 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), | 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 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 2423 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 2424 | US_FL_NOT_LOCKABLE), | 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 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ | 2437 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ |
| 2427 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, | 2438 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, |
| 2428 | "DataStor", | 2439 | "DataStor", |
| @@ -519,6 +519,7 @@ static void typec_altmode_release(struct device *dev) · 518 unmodified lines | |||
| 519 | typec_altmode_put_partner(alt); | 519 | typec_altmode_put_partner(alt); |
| 520 | 520 | ||
| 521 | altmode_id_remove(alt->adev.dev.parent, alt->id); | 521 | altmode_id_remove(alt->adev.dev.parent, alt->id); |
| 522 | put_device(alt->adev.dev.parent); | ||
| 522 | kfree(alt); | 523 | kfree(alt); |
| 523 | } | 524 | } |
| 524 | 525 | ||
| @@ -568,6 +569,8 @@ typec_register_altmode(struct device *parent, · 43 unmodified lines | |||
| 568 | alt->adev.dev.type = &typec_altmode_dev_type; | 569 | alt->adev.dev.type = &typec_altmode_dev_type; |
| 569 | dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); | 570 | dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); |
| 570 | 571 | ||
| 572 | get_device(alt->adev.dev.parent); | ||
| 573 | |||
| 571 | /* Link partners and plugs with the ports */ | 574 | /* Link partners and plugs with the ports */ |
| 572 | if (!is_port) | 575 | if (!is_port) |
| 573 | typec_altmode_set_partner(alt); | 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 | val = TYPEC_CC_RP_DEF; | 432 | val = TYPEC_CC_RP_DEF; |
| 433 | break; | 433 | break; |
| 434 | } | 434 | } |
| 435 | val = TYPEC_CC_RP_DEF; | ||
| 436 | } | 435 | } |
| 437 | 436 | ||
| 438 | if (misc & CC_ORIENTATION) | 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 | dev_err(dev, "Incomplete PCI capabilities"); | 475 | dev_err(dev, "Incomplete PCI capabilities"); |
| 476 | return -EIO; | 476 | return -EIO; |
| 477 | } | 477 | } |
| 478 | dev_info(dev, "common cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->common_cfg); | 478 | dev_info(dev, "common cfg mapped at: %p\n", oct_hw->common_cfg); |
| 479 | dev_info(dev, "device cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->dev_cfg); | 479 | dev_info(dev, "device cfg mapped at: %p\n", oct_hw->dev_cfg); |
| 480 | dev_info(dev, "isr cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->isr); | 480 | dev_info(dev, "isr cfg mapped at: %p\n", oct_hw->isr); |
| 481 | dev_info(dev, "notify base: 0x%016llx, notify off multiplier: %u\n", | 481 | dev_info(dev, "notify base: %p, notify off multiplier: %u\n", |
| 482 | (u64)(uintptr_t)oct_hw->notify_base, oct_hw->notify_off_multiplier); | 482 | oct_hw->notify_base, oct_hw->notify_off_multiplier); |
| 483 | 483 | ||
| 484 | oct_hw->config_size = octep_get_config_size(oct_hw); | 484 | oct_hw->config_size = octep_get_config_size(oct_hw); |
| 485 | oct_hw->features = octep_hw_get_dev_features(oct_hw); | 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 | mbox = octep_get_mbox(oct_hw); | 512 | mbox = octep_get_mbox(oct_hw); |
| 513 | octep_mbox_init(mbox); | 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 | return 0; | 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 | /* virtio-scsi spec requires byte 0 of the lun to be 1 */ | 1029 | /* virtio-scsi spec requires byte 0 of the lun to be 1 */ |
| 1030 | vq_err(vq, "Illegal virtio-scsi lun: %u\n", *vc->lunp); | 1030 | vq_err(vq, "Illegal virtio-scsi lun: %u\n", *vc->lunp); |
| 1031 | } else { | 1031 | } else { |
| 1032 | struct vhost_scsi_tpg **vs_tpg, *tpg; | 1032 | struct vhost_scsi_tpg **vs_tpg, *tpg = NULL; |
| 1033 | 1033 | ||
| 1034 | vs_tpg = vhost_vq_get_backend(vq); /* validated at handler entry */ | 1034 | if (vc->target) { |
| 1035 | 1035 | /* validated at handler entry */ | |
| 1036 | tpg = READ_ONCE(vs_tpg[*vc->target]); | 1036 | vs_tpg = vhost_vq_get_backend(vq); |
| 1037 | if (unlikely(!tpg)) { | 1037 | tpg = READ_ONCE(vs_tpg[*vc->target]); |
| 1038 | vq_err(vq, "Target 0x%x does not exist\n", *vc->target); | 1038 | if (unlikely(!tpg)) { |
| 1039 | } else { | 1039 | vq_err(vq, "Target 0x%x does not exist\n", *vc->target); |
| 1040 | if (tpgp) | 1040 | goto out; |
| 1041 | *tpgp = tpg; | 1041 | } |
| 1042 | ret = 0; | ||
| 1043 | } | 1042 | } |
| 1044 | } | ||
| 1045 | 1043 | ||
| 1044 | if (tpgp) | ||
| 1045 | *tpgp = tpg; | ||
| 1046 | ret = 0; | ||
| 1047 | } | ||
| 1048 | out: | ||
| 1046 | return ret; | 1049 | return ret; |
| 1047 | } | 1050 | } |
| 1048 | 1051 | ||
| @@ -3774,8 +3774,8 @@ static void __exit amifb_remove(struct platform_device *pdev) · 3773 unmodified lines | |||
| 3774 | * triggers a section mismatch warning. | 3774 | * triggers a section mismatch warning. |
| 3775 | */ | 3775 | */ |
| 3776 | static struct platform_driver amifb_driver __refdata = { | 3776 | static struct platform_driver amifb_driver __refdata = { |
| 3777 | .remove_new = __exit_p(amifb_remove), | 3777 | .remove = __exit_p(amifb_remove), |
| 3778 | .driver = { | 3778 | .driver = { |
| 3779 | .name = "amiga-video", | 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 | static struct platform_driver arcfb_driver = { | 549 | static struct platform_driver arcfb_driver = { |
| 550 | .probe = arcfb_probe, | 550 | .probe = arcfb_probe, |
| 551 | .remove_new = arcfb_remove, | 551 | .remove = arcfb_remove, |
| 552 | .driver = { | 552 | .driver = { |
| 553 | .name = "arcfb", | 553 | .name = "arcfb", |
| 554 | }, | 554 | }, |
| @@ -1299,7 +1299,7 @@ static int atmel_lcdfb_resume(struct platform_device *pdev) · 1298 unmodified lines | |||
| 1299 | 1299 | ||
| 1300 | static struct platform_driver atmel_lcdfb_driver = { | 1300 | static struct platform_driver atmel_lcdfb_driver = { |
| 1301 | .probe = atmel_lcdfb_probe, | 1301 | .probe = atmel_lcdfb_probe, |
| 1302 | .remove_new = atmel_lcdfb_remove, | 1302 | .remove = atmel_lcdfb_remove, |
| 1303 | .suspend = atmel_lcdfb_suspend, | 1303 | .suspend = atmel_lcdfb_suspend, |
| 1304 | .resume = atmel_lcdfb_resume, | 1304 | .resume = atmel_lcdfb_resume, |
| 1305 | .driver = { | 1305 | .driver = { |
| @@ -588,7 +588,7 @@ static struct platform_driver au1100fb_driver = { · 587 unmodified lines | |||
| 588 | .name = "au1100-lcd", | 588 | .name = "au1100-lcd", |
| 589 | }, | 589 | }, |
| 590 | .probe = au1100fb_drv_probe, | 590 | .probe = au1100fb_drv_probe, |
| 591 | .remove_new = au1100fb_drv_remove, | 591 | .remove = au1100fb_drv_remove, |
| 592 | .suspend = au1100fb_drv_suspend, | 592 | .suspend = au1100fb_drv_suspend, |
| 593 | .resume = au1100fb_drv_resume, | 593 | .resume = au1100fb_drv_resume, |
| 594 | }; | 594 | }; |
| @@ -1833,7 +1833,7 @@ static struct platform_driver au1200fb_driver = { · 1832 unmodified lines | |||
| 1833 | .pm = AU1200FB_PMOPS, | 1833 | .pm = AU1200FB_PMOPS, |
| 1834 | }, | 1834 | }, |
| 1835 | .probe = au1200fb_drv_probe, | 1835 | .probe = au1200fb_drv_probe, |
| 1836 | .remove_new = au1200fb_drv_remove, | 1836 | .remove = au1200fb_drv_remove, |
| 1837 | }; | 1837 | }; |
| 1838 | module_platform_driver(au1200fb_driver); | 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 | static struct platform_driver broadsheetfb_driver = { | 1152 | static struct platform_driver broadsheetfb_driver = { |
| 1153 | .probe = broadsheetfb_probe, | 1153 | .probe = broadsheetfb_probe, |
| 1154 | .remove_new = broadsheetfb_remove, | 1154 | .remove = broadsheetfb_remove, |
| 1155 | .driver = { | 1155 | .driver = { |
| 1156 | .name = "broadsheetfb", | 1156 | .name = "broadsheetfb", |
| 1157 | }, | 1157 | }, |
| @@ -372,7 +372,7 @@ static struct platform_driver bw2_driver = { · 371 unmodified lines | |||
| 372 | .of_match_table = bw2_match, | 372 | .of_match_table = bw2_match, |
| 373 | }, | 373 | }, |
| 374 | .probe = bw2_probe, | 374 | .probe = bw2_probe, |
| 375 | .remove_new = bw2_remove, | 375 | .remove = bw2_remove, |
| 376 | }; | 376 | }; |
| 377 | 377 | ||
| 378 | static int __init bw2_init(void) | 378 | static int __init bw2_init(void) |
| @@ -590,7 +590,7 @@ static struct platform_driver cg14_driver = { · 589 unmodified lines | |||
| 590 | .of_match_table = cg14_match, | 590 | .of_match_table = cg14_match, |
| 591 | }, | 591 | }, |
| 592 | .probe = cg14_probe, | 592 | .probe = cg14_probe, |
| 593 | .remove_new = cg14_remove, | 593 | .remove = cg14_remove, |
| 594 | }; | 594 | }; |
| 595 | 595 | ||
| 596 | static int __init cg14_init(void) | 596 | static int __init cg14_init(void) |
| @@ -458,7 +458,7 @@ static struct platform_driver cg3_driver = { · 457 unmodified lines | |||
| 458 | .of_match_table = cg3_match, | 458 | .of_match_table = cg3_match, |
| 459 | }, | 459 | }, |
| 460 | .probe = cg3_probe, | 460 | .probe = cg3_probe, |
| 461 | .remove_new = cg3_remove, | 461 | .remove = cg3_remove, |
| 462 | }; | 462 | }; |
| 463 | 463 | ||
| 464 | static int __init cg3_init(void) | 464 | static int __init cg3_init(void) |
| @@ -858,7 +858,7 @@ static struct platform_driver cg6_driver = { · 857 unmodified lines | |||
| 858 | .of_match_table = cg6_match, | 858 | .of_match_table = cg6_match, |
| 859 | }, | 859 | }, |
| 860 | .probe = cg6_probe, | 860 | .probe = cg6_probe, |
| 861 | .remove_new = cg6_remove, | 861 | .remove = cg6_remove, |
| 862 | }; | 862 | }; |
| 863 | 863 | ||
| 864 | static int __init cg6_init(void) | 864 | static int __init cg6_init(void) |
| @@ -371,7 +371,7 @@ static struct platform_driver clps711x_fb_driver = { · 370 unmodified lines | |||
| 371 | .of_match_table = clps711x_fb_dt_ids, | 371 | .of_match_table = clps711x_fb_dt_ids, |
| 372 | }, | 372 | }, |
| 373 | .probe = clps711x_fb_probe, | 373 | .probe = clps711x_fb_probe, |
| 374 | .remove_new = clps711x_fb_remove, | 374 | .remove = clps711x_fb_remove, |
| 375 | }; | 375 | }; |
| 376 | module_platform_driver(clps711x_fb_driver); | 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 | static struct platform_driver cobalt_lcdfb_driver = { | 345 | static struct platform_driver cobalt_lcdfb_driver = { |
| 346 | .probe = cobalt_lcdfb_probe, | 346 | .probe = cobalt_lcdfb_probe, |
| 347 | .remove_new = cobalt_lcdfb_remove, | 347 | .remove = cobalt_lcdfb_remove, |
| 348 | .driver = { | 348 | .driver = { |
| 349 | .name = "cobalt-lcd", | 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 | static struct platform_driver da8xx_fb_driver = { | 1653 | static struct platform_driver da8xx_fb_driver = { |
| 1654 | .probe = fb_probe, | 1654 | .probe = fb_probe, |
| 1655 | .remove_new = fb_remove, | 1655 | .remove = fb_remove, |
| 1656 | .driver = { | 1656 | .driver = { |
| 1657 | .name = DRIVER_NAME, | 1657 | .name = DRIVER_NAME, |
| 1658 | .pm = &fb_pm_ops, | 1658 | .pm = &fb_pm_ops, |
| @@ -592,7 +592,7 @@ static void ep93xxfb_remove(struct platform_device *pdev) · 591 unmodified lines | |||
| 592 | 592 | ||
| 593 | static struct platform_driver ep93xxfb_driver = { | 593 | static struct platform_driver ep93xxfb_driver = { |
| 594 | .probe = ep93xxfb_probe, | 594 | .probe = ep93xxfb_probe, |
| 595 | .remove_new = ep93xxfb_remove, | 595 | .remove = ep93xxfb_remove, |
| 596 | .driver = { | 596 | .driver = { |
| 597 | .name = "ep93xx-fb", | 597 | .name = "ep93xx-fb", |
| 598 | }, | 598 | }, |
| @@ -1053,7 +1053,7 @@ static struct platform_driver ffb_driver = { · 1052 unmodified lines | |||
| 1053 | .of_match_table = ffb_match, | 1053 | .of_match_table = ffb_match, |
| 1054 | }, | 1054 | }, |
| 1055 | .probe = ffb_probe, | 1055 | .probe = ffb_probe, |
| 1056 | .remove_new = ffb_remove, | 1056 | .remove = ffb_remove, |
| 1057 | }; | 1057 | }; |
| 1058 | 1058 | ||
| 1059 | static int __init ffb_init(void) | 1059 | static int __init ffb_init(void) |
| @@ -1876,12 +1876,12 @@ static const struct of_device_id fsl_diu_match[] = { · 1875 unmodified lines | |||
| 1876 | MODULE_DEVICE_TABLE(of, fsl_diu_match); | 1876 | MODULE_DEVICE_TABLE(of, fsl_diu_match); |
| 1877 | 1877 | ||
| 1878 | static struct platform_driver fsl_diu_driver = { | 1878 | static struct platform_driver fsl_diu_driver = { |
| 1879 | .driver = { | 1879 | .driver = { |
| 1880 | .name = "fsl-diu-fb", | 1880 | .name = "fsl-diu-fb", |
| 1881 | .of_match_table = fsl_diu_match, | 1881 | .of_match_table = fsl_diu_match, |
| 1882 | }, | 1882 | }, |
| 1883 | .probe = fsl_diu_probe, | 1883 | .probe = fsl_diu_probe, |
| 1884 | .remove_new = fsl_diu_remove, | 1884 | .remove = fsl_diu_remove, |
| 1885 | .suspend = fsl_diu_suspend, | 1885 | .suspend = fsl_diu_suspend, |
| 1886 | .resume = fsl_diu_resume, | 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 | static struct platform_driver gbefb_driver = { | 1248 | static struct platform_driver gbefb_driver = { |
| 1249 | .probe = gbefb_probe, | 1249 | .probe = gbefb_probe, |
| 1250 | .remove_new = gbefb_remove, | 1250 | .remove = gbefb_remove, |
| 1251 | .driver = { | 1251 | .driver = { |
| 1252 | .name = "gbefb", | 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 | static struct platform_driver goldfish_fb_driver = { | 312 | static struct platform_driver goldfish_fb_driver = { |
| 313 | .probe = goldfish_fb_probe, | 313 | .probe = goldfish_fb_probe, |
| 314 | .remove_new = goldfish_fb_remove, | 314 | .remove = goldfish_fb_remove, |
| 315 | .driver = { | 315 | .driver = { |
| 316 | .name = "goldfish_fb", | 316 | .name = "goldfish_fb", |
| 317 | .of_match_table = goldfish_fb_of_match, | 317 | .of_match_table = goldfish_fb_of_match, |
| @@ -540,7 +540,7 @@ static struct platform_driver grvga_driver = { · 539 unmodified lines | |||
| 540 | .of_match_table = svgactrl_of_match, | 540 | .of_match_table = svgactrl_of_match, |
| 541 | }, | 541 | }, |
| 542 | .probe = grvga_probe, | 542 | .probe = grvga_probe, |
| 543 | .remove_new = grvga_remove, | 543 | .remove = grvga_remove, |
| 544 | }; | 544 | }; |
| 545 | 545 | ||
| 546 | module_platform_driver(grvga_driver); | 546 | module_platform_driver(grvga_driver); |
| @@ -235,7 +235,7 @@ static void hecubafb_remove(struct platform_device *dev) · 234 unmodified lines | |||
| 235 | 235 | ||
| 236 | static struct platform_driver hecubafb_driver = { | 236 | static struct platform_driver hecubafb_driver = { |
| 237 | .probe = hecubafb_probe, | 237 | .probe = hecubafb_probe, |
| 238 | .remove_new = hecubafb_remove, | 238 | .remove = hecubafb_remove, |
| 239 | .driver = { | 239 | .driver = { |
| 240 | .name = "hecubafb", | 240 | .name = "hecubafb", |
| 241 | }, | 241 | }, |
| @@ -629,7 +629,7 @@ static void hgafb_remove(struct platform_device *pdev) · 628 unmodified lines | |||
| 629 | 629 | ||
| 630 | static struct platform_driver hgafb_driver = { | 630 | static struct platform_driver hgafb_driver = { |
| 631 | .probe = hgafb_probe, | 631 | .probe = hgafb_probe, |
| 632 | .remove_new = hgafb_remove, | 632 | .remove = hgafb_remove, |
| 633 | .driver = { | 633 | .driver = { |
| 634 | .name = "hgafb", | 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 | static struct platform_driver hitfb_driver = { | 477 | static struct platform_driver hitfb_driver = { |
| 478 | .probe = hitfb_probe, | 478 | .probe = hitfb_probe, |
| 479 | .remove_new = hitfb_remove, | 479 | .remove = hitfb_remove, |
| 480 | .driver = { | 480 | .driver = { |
| 481 | .name = "hitfb", | 481 | .name = "hitfb", |
| 482 | .pm = &hitfb_dev_pm_ops, | 482 | .pm = &hitfb_dev_pm_ops, |
| @@ -1105,7 +1105,7 @@ static struct platform_driver imxfb_driver = { · 1104 unmodified lines | |||
| 1105 | .pm = pm_sleep_ptr(&imxfb_pm_ops), | 1105 | .pm = pm_sleep_ptr(&imxfb_pm_ops), |
| 1106 | }, | 1106 | }, |
| 1107 | .probe = imxfb_probe, | 1107 | .probe = imxfb_probe, |
| 1108 | .remove_new = imxfb_remove, | 1108 | .remove = imxfb_remove, |
| 1109 | .id_table = imxfb_devtype, | 1109 | .id_table = imxfb_devtype, |
| 1110 | }; | 1110 | }; |
| 1111 | module_platform_driver(imxfb_driver); | 1111 | module_platform_driver(imxfb_driver); |
| @@ -657,7 +657,7 @@ static struct platform_driver leo_driver = { · 656 unmodified lines | |||
| 657 | .of_match_table = leo_match, | 657 | .of_match_table = leo_match, |
| 658 | }, | 658 | }, |
| 659 | .probe = leo_probe, | 659 | .probe = leo_probe, |
| 660 | .remove_new = leo_remove, | 660 | .remove = leo_remove, |
| 661 | }; | 661 | }; |
| 662 | 662 | ||
| 663 | static int __init leo_init(void) | 663 | static int __init leo_init(void) |
| @@ -834,7 +834,7 @@ static struct platform_driver of_platform_mb862xxfb_driver = { · 833 unmodified lines | |||
| 834 | .of_match_table = of_platform_mb862xx_tbl, | 834 | .of_match_table = of_platform_mb862xx_tbl, |
| 835 | }, | 835 | }, |
| 836 | .probe = of_platform_mb862xx_probe, | 836 | .probe = of_platform_mb862xx_probe, |
| 837 | .remove_new = of_platform_mb862xx_remove, | 837 | .remove = of_platform_mb862xx_remove, |
| 838 | }; | 838 | }; |
| 839 | #endif | 839 | #endif |
| 840 | 840 | ||
| @@ -707,7 +707,7 @@ static void metronomefb_remove(struct platform_device *dev) · 706 unmodified lines | |||
| 707 | 707 | ||
| 708 | static struct platform_driver metronomefb_driver = { | 708 | static struct platform_driver metronomefb_driver = { |
| 709 | .probe = metronomefb_probe, | 709 | .probe = metronomefb_probe, |
| 710 | .remove_new = metronomefb_remove, | 710 | .remove = metronomefb_remove, |
| 711 | .driver = { | 711 | .driver = { |
| 712 | .name = "metronomefb", | 712 | .name = "metronomefb", |
| 713 | }, | 713 | }, |
| @@ -391,7 +391,7 @@ MODULE_DEVICE_TABLE(of, ocfb_match); · 390 unmodified lines | |||
| 391 | 391 | ||
| 392 | static struct platform_driver ocfb_driver = { | 392 | static struct platform_driver ocfb_driver = { |
| 393 | .probe = ocfb_probe, | 393 | .probe = ocfb_probe, |
| 394 | .remove_new = ocfb_remove, | 394 | .remove = ocfb_remove, |
| 395 | .driver = { | 395 | .driver = { |
| 396 | .name = "ocfb_fb", | 396 | .name = "ocfb_fb", |
| 397 | .of_match_table = ocfb_match, | 397 | .of_match_table = ocfb_match, |
| @@ -673,7 +673,7 @@ static struct platform_driver offb_driver_bootx_noscreen = { · 672 unmodified lines | |||
| 673 | .name = "bootx-noscreen", | 673 | .name = "bootx-noscreen", |
| 674 | }, | 674 | }, |
| 675 | .probe = offb_probe_bootx_noscreen, | 675 | .probe = offb_probe_bootx_noscreen, |
| 676 | .remove_new = offb_remove, | 676 | .remove = offb_remove, |
| 677 | }; | 677 | }; |
| 678 | 678 | ||
| 679 | static int offb_probe_display(struct platform_device *pdev) | 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 | .of_match_table = offb_of_match_display, | 695 | .of_match_table = offb_of_match_display, |
| 696 | }, | 696 | }, |
| 697 | .probe = offb_probe_display, | 697 | .probe = offb_probe_display, |
| 698 | .remove_new = offb_remove, | 698 | .remove = offb_remove, |
| 699 | }; | 699 | }; |
| 700 | 700 | ||
| 701 | static int __init offb_init(void) | 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 | static struct platform_driver omapfb_driver = { | 1826 | static struct platform_driver omapfb_driver = { |
| 1827 | .probe = omapfb_probe, | 1827 | .probe = omapfb_probe, |
| 1828 | .remove_new = omapfb_remove, | 1828 | .remove = omapfb_remove, |
| 1829 | .suspend = omapfb_suspend, | 1829 | .suspend = omapfb_suspend, |
| 1830 | .resume = omapfb_resume, | 1830 | .resume = omapfb_resume, |
| 1831 | .driver = { | 1831 | .driver = { |
| @@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, tvc_of_match); · 244 unmodified lines | |||
| 245 | 245 | ||
| 246 | static struct platform_driver tvc_connector_driver = { | 246 | static struct platform_driver tvc_connector_driver = { |
| 247 | .probe = tvc_probe, | 247 | .probe = tvc_probe, |
| 248 | .remove_new = tvc_remove, | 248 | .remove = tvc_remove, |
| 249 | .driver = { | 249 | .driver = { |
| 250 | .name = "connector-analog-tv", | 250 | .name = "connector-analog-tv", |
| 251 | .of_match_table = tvc_of_match, | 251 | .of_match_table = tvc_of_match, |
| @@ -328,7 +328,7 @@ MODULE_DEVICE_TABLE(of, dvic_of_match); · 327 unmodified lines | |||
| 328 | 328 | ||
| 329 | static struct platform_driver dvi_connector_driver = { | 329 | static struct platform_driver dvi_connector_driver = { |
| 330 | .probe = dvic_probe, | 330 | .probe = dvic_probe, |
| 331 | .remove_new = dvic_remove, | 331 | .remove = dvic_remove, |
| 332 | .driver = { | 332 | .driver = { |
| 333 | .name = "connector-dvi", | 333 | .name = "connector-dvi", |
| 334 | .of_match_table = dvic_of_match, | 334 | .of_match_table = dvic_of_match, |
| @@ -272,7 +272,7 @@ MODULE_DEVICE_TABLE(of, hdmic_of_match); · 271 unmodified lines | |||
| 272 | 272 | ||
| 273 | static struct platform_driver hdmi_connector_driver = { | 273 | static struct platform_driver hdmi_connector_driver = { |
| 274 | .probe = hdmic_probe, | 274 | .probe = hdmic_probe, |
| 275 | .remove_new = hdmic_remove, | 275 | .remove = hdmic_remove, |
| 276 | .driver = { | 276 | .driver = { |
| 277 | .name = "connector-hdmi", | 277 | .name = "connector-hdmi", |
| 278 | .of_match_table = hdmic_of_match, | 278 | .of_match_table = hdmic_of_match, |
| @@ -258,7 +258,7 @@ MODULE_DEVICE_TABLE(of, opa362_of_match); · 257 unmodified lines | |||
| 258 | 258 | ||
| 259 | static struct platform_driver opa362_driver = { | 259 | static struct platform_driver opa362_driver = { |
| 260 | .probe = opa362_probe, | 260 | .probe = opa362_probe, |
| 261 | .remove_new = opa362_remove, | 261 | .remove = opa362_remove, |
| 262 | .driver = { | 262 | .driver = { |
| 263 | .name = "amplifier-opa362", | 263 | .name = "amplifier-opa362", |
| 264 | .of_match_table = opa362_of_match, | 264 | .of_match_table = opa362_of_match, |
| @@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, tfp410_of_match); · 244 unmodified lines | |||
| 245 | 245 | ||
| 246 | static struct platform_driver tfp410_driver = { | 246 | static struct platform_driver tfp410_driver = { |
| 247 | .probe = tfp410_probe, | 247 | .probe = tfp410_probe, |
| 248 | .remove_new = tfp410_remove, | 248 | .remove = tfp410_remove, |
| 249 | .driver = { | 249 | .driver = { |
| 250 | .name = "tfp410", | 250 | .name = "tfp410", |
| 251 | .of_match_table = tfp410_of_match, | 251 | .of_match_table = tfp410_of_match, |
| @@ -311,7 +311,7 @@ MODULE_DEVICE_TABLE(of, tpd_of_match); · 310 unmodified lines | |||
| 311 | 311 | ||
| 312 | static struct platform_driver tpd_driver = { | 312 | static struct platform_driver tpd_driver = { |
| 313 | .probe = tpd_probe, | 313 | .probe = tpd_probe, |
| 314 | .remove_new = tpd_remove, | 314 | .remove = tpd_remove, |
| 315 | .driver = { | 315 | .driver = { |
| 316 | .name = "tpd12s015", | 316 | .name = "tpd12s015", |
| 317 | .of_match_table = tpd_of_match, | 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 | static struct platform_driver panel_dpi_driver = { | 235 | static struct platform_driver panel_dpi_driver = { |
| 236 | .probe = panel_dpi_probe, | 236 | .probe = panel_dpi_probe, |
| 237 | .remove_new = panel_dpi_remove, | 237 | .remove = panel_dpi_remove, |
| 238 | .driver = { | 238 | .driver = { |
| 239 | .name = "panel-dpi", | 239 | .name = "panel-dpi", |
| 240 | .of_match_table = panel_dpi_of_match, | 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 | static struct platform_driver dsicm_driver = { | 1276 | static struct platform_driver dsicm_driver = { |
| 1277 | .probe = dsicm_probe, | 1277 | .probe = dsicm_probe, |
| 1278 | .remove_new = dsicm_remove, | 1278 | .remove = dsicm_remove, |
| 1279 | .driver = { | 1279 | .driver = { |
| 1280 | .name = "panel-dsi-cm", | 1280 | .name = "panel-dsi-cm", |
| 1281 | .of_match_table = dsicm_of_match, | 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 | static struct platform_driver sharp_ls_driver = { | 316 | static struct platform_driver sharp_ls_driver = { |
| 317 | .probe = sharp_ls_probe, | 317 | .probe = sharp_ls_probe, |
| 318 | .remove_new = sharp_ls_remove, | 318 | .remove = sharp_ls_remove, |
| 319 | .driver = { | 319 | .driver = { |
| 320 | .name = "panel-sharp-ls037v7dw01", | 320 | .name = "panel-sharp-ls037v7dw01", |
| 321 | .of_match_table = sharp_ls_of_match, | 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 | static struct platform_driver omap_dss_driver = { | 187 | static struct platform_driver omap_dss_driver = { |
| 188 | .remove_new = omap_dss_remove, | 188 | .remove = omap_dss_remove, |
| 189 | .shutdown = omap_dss_shutdown, | 189 | .shutdown = omap_dss_shutdown, |
| 190 | .driver = { | 190 | .driver = { |
| 191 | .name = "omapdss", | 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 | static struct platform_driver omap_dispchw_driver = { | 4073 | static struct platform_driver omap_dispchw_driver = { |
| 4074 | .probe = dispc_probe, | 4074 | .probe = dispc_probe, |
| 4075 | .remove_new = dispc_remove, | 4075 | .remove = dispc_remove, |
| 4076 | .driver = { | 4076 | .driver = { |
| 4077 | .name = "omapdss_dispc", | 4077 | .name = "omapdss_dispc", |
| 4078 | .pm = &dispc_pm_ops, | 4078 | .pm = &dispc_pm_ops, |
| @@ -817,8 +817,8 @@ static void dpi_remove(struct platform_device *pdev) · 816 unmodified lines | |||
| 817 | 817 | ||
| 818 | static struct platform_driver omap_dpi_driver = { | 818 | static struct platform_driver omap_dpi_driver = { |
| 819 | .probe = dpi_probe, | 819 | .probe = dpi_probe, |
| 820 | .remove_new = dpi_remove, | 820 | .remove = dpi_remove, |
| 821 | .driver = { | 821 | .driver = { |
| 822 | .name = "omapdss_dpi", | 822 | .name = "omapdss_dpi", |
| 823 | .suppress_bind_attrs = true, | 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 | static struct platform_driver omap_dsihw_driver = { | 5566 | static struct platform_driver omap_dsihw_driver = { |
| 5567 | .probe = dsi_probe, | 5567 | .probe = dsi_probe, |
| 5568 | .remove_new = dsi_remove, | 5568 | .remove = dsi_remove, |
| 5569 | .driver = { | 5569 | .driver = { |
| 5570 | .name = "omapdss_dsi", | 5570 | .name = "omapdss_dsi", |
| 5571 | .pm = &dsi_pm_ops, | 5571 | .pm = &dsi_pm_ops, |
| @@ -1278,7 +1278,7 @@ MODULE_DEVICE_TABLE(of, dss_of_match); · 1277 unmodified lines | |||
| 1278 | 1278 | ||
| 1279 | static struct platform_driver omap_dsshw_driver = { | 1279 | static struct platform_driver omap_dsshw_driver = { |
| 1280 | .probe = dss_probe, | 1280 | .probe = dss_probe, |
| 1281 | .remove_new = dss_remove, | 1281 | .remove = dss_remove, |
| 1282 | .driver = { | 1282 | .driver = { |
| 1283 | .name = "omapdss_dss", | 1283 | .name = "omapdss_dss", |
| 1284 | .pm = &dss_pm_ops, | 1284 | .pm = &dss_pm_ops, |
| @@ -792,9 +792,9 @@ static const struct of_device_id hdmi_of_match[] = { · 791 unmodified lines | |||
| 792 | 792 | ||
| 793 | static struct platform_driver omapdss_hdmihw_driver = { | 793 | static struct platform_driver omapdss_hdmihw_driver = { |
| 794 | .probe = hdmi4_probe, | 794 | .probe = hdmi4_probe, |
| 795 | .remove_new = hdmi4_remove, | 795 | .remove = hdmi4_remove, |
| 796 | .driver = { | 796 | .driver = { |
| 797 | .name = "omapdss_hdmi", | 797 | .name = "omapdss_hdmi", |
| 798 | .pm = &hdmi_pm_ops, | 798 | .pm = &hdmi_pm_ops, |
| 799 | .of_match_table = hdmi_of_match, | 799 | .of_match_table = hdmi_of_match, |
| 800 | .suppress_bind_attrs = true, | 800 | .suppress_bind_attrs = true, |
| @@ -834,7 +834,7 @@ static const struct of_device_id hdmi_of_match[] = { · 833 unmodified lines | |||
| 834 | 834 | ||
| 835 | static struct platform_driver omapdss_hdmihw_driver = { | 835 | static struct platform_driver omapdss_hdmihw_driver = { |
| 836 | .probe = hdmi5_probe, | 836 | .probe = hdmi5_probe, |
| 837 | .remove_new = hdmi5_remove, | 837 | .remove = hdmi5_remove, |
| 838 | .driver = { | 838 | .driver = { |
| 839 | .name = "omapdss_hdmi5", | 839 | .name = "omapdss_hdmi5", |
| 840 | .pm = &hdmi_pm_ops, | 840 | .pm = &hdmi_pm_ops, |
| @@ -382,9 +382,9 @@ static void sdi_remove(struct platform_device *pdev) · 381 unmodified lines | |||
| 382 | 382 | ||
| 383 | static struct platform_driver omap_sdi_driver = { | 383 | static struct platform_driver omap_sdi_driver = { |
| 384 | .probe = sdi_probe, | 384 | .probe = sdi_probe, |
| 385 | .remove_new = sdi_remove, | 385 | .remove = sdi_remove, |
| 386 | .driver = { | 386 | .driver = { |
| 387 | .name = "omapdss_sdi", | 387 | .name = "omapdss_sdi", |
| 388 | .suppress_bind_attrs = true, | 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 | static struct platform_driver omap_venchw_driver = { | 921 | static struct platform_driver omap_venchw_driver = { |
| 922 | .probe = venc_probe, | 922 | .probe = venc_probe, |
| 923 | .remove_new = venc_remove, | 923 | .remove = venc_remove, |
| 924 | .driver = { | 924 | .driver = { |
| 925 | .name = "omapdss_venc", | 925 | .name = "omapdss_venc", |
| 926 | .pm = &venc_pm_ops, | 926 | .pm = &venc_pm_ops, |
| 927 | .of_match_table = venc_of_match, | 927 | .of_match_table = venc_of_match, |
| 928 | .suppress_bind_attrs = true, | 928 | .suppress_bind_attrs = true, |
| @@ -2614,7 +2614,7 @@ static void omapfb_remove(struct platform_device *pdev) · 2613 unmodified lines | |||
| 2614 | 2614 | ||
| 2615 | static struct platform_driver omapfb_driver = { | 2615 | static struct platform_driver omapfb_driver = { |
| 2616 | .probe = omapfb_probe, | 2616 | .probe = omapfb_probe, |
| 2617 | .remove_new = omapfb_remove, | 2617 | .remove = omapfb_remove, |
| 2618 | .driver = { | 2618 | .driver = { |
| 2619 | .name = "omapfb", | 2619 | .name = "omapfb", |
| 2620 | }, | 2620 | }, |
| @@ -347,7 +347,7 @@ static struct platform_driver p9100_driver = { · 346 unmodified lines | |||
| 347 | .of_match_table = p9100_match, | 347 | .of_match_table = p9100_match, |
| 348 | }, | 348 | }, |
| 349 | .probe = p9100_probe, | 349 | .probe = p9100_probe, |
| 350 | .remove_new = p9100_remove, | 350 | .remove = p9100_remove, |
| 351 | }; | 351 | }; |
| 352 | 352 | ||
| 353 | static int __init p9100_init(void) | 353 | static int __init p9100_init(void) |
| @@ -668,7 +668,7 @@ static struct platform_driver platinum_driver = · 667 unmodified lines | |||
| 668 | .of_match_table = platinumfb_match, | 668 | .of_match_table = platinumfb_match, |
| 669 | }, | 669 | }, |
| 670 | .probe = platinumfb_probe, | 670 | .probe = platinumfb_probe, |
| 671 | .remove_new = platinumfb_remove, | 671 | .remove = platinumfb_remove, |
| 672 | }; | 672 | }; |
| 673 | 673 | ||
| 674 | static int __init platinumfb_init(void) | 674 | static int __init platinumfb_init(void) |
| @@ -799,7 +799,7 @@ static struct platform_driver pxa168fb_driver = { · 798 unmodified lines | |||
| 799 | .name = "pxa168-fb", | 799 | .name = "pxa168-fb", |
| 800 | }, | 800 | }, |
| 801 | .probe = pxa168fb_probe, | 801 | .probe = pxa168fb_probe, |
| 802 | .remove_new = pxa168fb_remove, | 802 | .remove = pxa168fb_remove, |
| 803 | }; | 803 | }; |
| 804 | 804 | ||
| 805 | module_platform_driver(pxa168fb_driver); | 805 | module_platform_driver(pxa168fb_driver); |
| @@ -696,10 +696,10 @@ MODULE_DEVICE_TABLE(of, pxa3xx_gcu_of_match); · 695 unmodified lines | |||
| 696 | #endif | 696 | #endif |
| 697 | 697 | ||
| 698 | static struct platform_driver pxa3xx_gcu_driver = { | 698 | static struct platform_driver pxa3xx_gcu_driver = { |
| 699 | .probe = pxa3xx_gcu_probe, | 699 | .probe = pxa3xx_gcu_probe, |
| 700 | .remove_new = pxa3xx_gcu_remove, | 700 | .remove = pxa3xx_gcu_remove, |
| 701 | .driver = { | 701 | .driver = { |
| 702 | .name = DRV_NAME, | 702 | .name = DRV_NAME, |
| 703 | .of_match_table = of_match_ptr(pxa3xx_gcu_of_match), | 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 | static struct platform_driver pxafb_driver = { | 2428 | static struct platform_driver pxafb_driver = { |
| 2429 | .probe = pxafb_probe, | 2429 | .probe = pxafb_probe, |
| 2430 | .remove_new = pxafb_remove, | 2430 | .remove = pxafb_remove, |
| 2431 | .driver = { | 2431 | .driver = { |
| 2432 | .name = "pxa2xx-fb", | 2432 | .name = "pxa2xx-fb", |
| 2433 | .of_match_table = pxafb_of_dev_id, | 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 | static struct platform_driver s1d13xxxfb_driver = { | 1002 | static struct platform_driver s1d13xxxfb_driver = { |
| 1003 | .probe = s1d13xxxfb_probe, | 1003 | .probe = s1d13xxxfb_probe, |
| 1004 | .remove_new = s1d13xxxfb_remove, | 1004 | .remove = s1d13xxxfb_remove, |
| 1005 | #ifdef CONFIG_PM | 1005 | #ifdef CONFIG_PM |
| 1006 | .suspend = s1d13xxxfb_suspend, | 1006 | .suspend = s1d13xxxfb_suspend, |
| 1007 | .resume = s1d13xxxfb_resume, | 1007 | .resume = s1d13xxxfb_resume, |
| @@ -1789,7 +1789,7 @@ static const struct dev_pm_ops s3cfb_pm_ops = { · 1788 unmodified lines | |||
| 1789 | 1789 | ||
| 1790 | static struct platform_driver s3c_fb_driver = { | 1790 | static struct platform_driver s3c_fb_driver = { |
| 1791 | .probe = s3c_fb_probe, | 1791 | .probe = s3c_fb_probe, |
| 1792 | .remove_new = s3c_fb_remove, | 1792 | .remove = s3c_fb_remove, |
| 1793 | .id_table = s3c_fb_driver_ids, | 1793 | .id_table = s3c_fb_driver_ids, |
| 1794 | .driver = { | 1794 | .driver = { |
| 1795 | .name = "s3c-fb", | 1795 | .name = "s3c-fb", |
| @@ -575,7 +575,7 @@ static struct platform_driver sh7760_lcdc_driver = { · 574 unmodified lines | |||
| 575 | .name = "sh7760-lcdc", | 575 | .name = "sh7760-lcdc", |
| 576 | }, | 576 | }, |
| 577 | .probe = sh7760fb_probe, | 577 | .probe = sh7760fb_probe, |
| 578 | .remove_new = sh7760fb_remove, | 578 | .remove = sh7760fb_remove, |
| 579 | }; | 579 | }; |
| 580 | 580 | ||
| 581 | module_platform_driver(sh7760_lcdc_driver); | 581 | module_platform_driver(sh7760_lcdc_driver); |
| @@ -2648,7 +2648,7 @@ static struct platform_driver sh_mobile_lcdc_driver = { · 2647 unmodified lines | |||
| 2648 | .pm = &sh_mobile_lcdc_dev_pm_ops, | 2648 | .pm = &sh_mobile_lcdc_dev_pm_ops, |
| 2649 | }, | 2649 | }, |
| 2650 | .probe = sh_mobile_lcdc_probe, | 2650 | .probe = sh_mobile_lcdc_probe, |
| 2651 | .remove_new = sh_mobile_lcdc_remove, | 2651 | .remove = sh_mobile_lcdc_remove, |
| 2652 | }; | 2652 | }; |
| 2653 | 2653 | ||
| 2654 | module_platform_driver(sh_mobile_lcdc_driver); | 2654 | module_platform_driver(sh_mobile_lcdc_driver); |
| @@ -677,7 +677,7 @@ static struct platform_driver simplefb_driver = { · 676 unmodified lines | |||
| 677 | .of_match_table = simplefb_of_match, | 677 | .of_match_table = simplefb_of_match, |
| 678 | }, | 678 | }, |
| 679 | .probe = simplefb_probe, | 679 | .probe = simplefb_probe, |
| 680 | .remove_new = simplefb_remove, | 680 | .remove = simplefb_remove, |
| 681 | }; | 681 | }; |
| 682 | 682 | ||
| 683 | module_platform_driver(simplefb_driver); | 683 | module_platform_driver(simplefb_driver); |
| @@ -2211,7 +2211,7 @@ static int sm501fb_resume(struct platform_device *pdev) · 2210 unmodified lines | |||
| 2211 | 2211 | ||
| 2212 | static struct platform_driver sm501fb_driver = { | 2212 | static struct platform_driver sm501fb_driver = { |
| 2213 | .probe = sm501fb_probe, | 2213 | .probe = sm501fb_probe, |
| 2214 | .remove_new = sm501fb_remove, | 2214 | .remove = sm501fb_remove, |
| 2215 | .suspend = sm501fb_suspend, | 2215 | .suspend = sm501fb_suspend, |
| 2216 | .resume = sm501fb_resume, | 2216 | .resume = sm501fb_resume, |
| 2217 | .driver = { | 2217 | .driver = { |
| @@ -505,7 +505,7 @@ static struct platform_driver tcx_driver = { · 504 unmodified lines | |||
| 505 | .of_match_table = tcx_match, | 505 | .of_match_table = tcx_match, |
| 506 | }, | 506 | }, |
| 507 | .probe = tcx_probe, | 507 | .probe = tcx_probe, |
| 508 | .remove_new = tcx_remove, | 508 | .remove = tcx_remove, |
| 509 | }; | 509 | }; |
| 510 | 510 | ||
| 511 | static int __init tcx_init(void) | 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 | static struct platform_driver uvesafb_driver = { | 1795 | static struct platform_driver uvesafb_driver = { |
| 1796 | .probe = uvesafb_probe, | 1796 | .probe = uvesafb_probe, |
| 1797 | .remove_new = uvesafb_remove, | 1797 | .remove = uvesafb_remove, |
| 1798 | .driver = { | 1798 | .driver = { |
| 1799 | .name = "uvesafb", | 1799 | .name = "uvesafb", |
| 1800 | }, | 1800 | }, |
| @@ -515,7 +515,7 @@ static struct platform_driver vesafb_driver = { · 514 unmodified lines | |||
| 515 | .name = "vesa-framebuffer", | 515 | .name = "vesa-framebuffer", |
| 516 | }, | 516 | }, |
| 517 | .probe = vesafb_probe, | 517 | .probe = vesafb_probe, |
| 518 | .remove_new = vesafb_remove, | 518 | .remove = vesafb_remove, |
| 519 | }; | 519 | }; |
| 520 | 520 | ||
| 521 | module_platform_driver(vesafb_driver); | 521 | module_platform_driver(vesafb_driver); |
| @@ -493,7 +493,7 @@ static void vfb_remove(struct platform_device *dev) · 492 unmodified lines | |||
| 493 | 493 | ||
| 494 | static struct platform_driver vfb_driver = { | 494 | static struct platform_driver vfb_driver = { |
| 495 | .probe = vfb_probe, | 495 | .probe = vfb_probe, |
| 496 | .remove_new = vfb_remove, | 496 | .remove = vfb_remove, |
| 497 | .driver = { | 497 | .driver = { |
| 498 | .name = "vfb", | 498 | .name = "vfb", |
| 499 | }, | 499 | }, |
| @@ -1417,7 +1417,7 @@ MODULE_DEVICE_TABLE(platform, vga16fb_driver_id_table); · 1416 unmodified lines | |||
| 1417 | 1417 | ||
| 1418 | static struct platform_driver vga16fb_driver = { | 1418 | static struct platform_driver vga16fb_driver = { |
| 1419 | .probe = vga16fb_probe, | 1419 | .probe = vga16fb_probe, |
| 1420 | .remove_new = vga16fb_remove, | 1420 | .remove = vga16fb_remove, |
| 1421 | .driver = { | 1421 | .driver = { |
| 1422 | .name = "vga16fb", | 1422 | .name = "vga16fb", |
| 1423 | }, | 1423 | }, |
| @@ -292,7 +292,7 @@ static struct platform_driver via_gpio_driver = { · 291 unmodified lines | |||
| 292 | .name = "viafb-gpio", | 292 | .name = "viafb-gpio", |
| 293 | }, | 293 | }, |
| 294 | .probe = viafb_gpio_probe, | 294 | .probe = viafb_gpio_probe, |
| 295 | .remove_new = viafb_gpio_remove, | 295 | .remove = viafb_gpio_remove, |
| 296 | }; | 296 | }; |
| 297 | 297 | ||
| 298 | int viafb_gpio_init(void) | 298 | int viafb_gpio_init(void) |
| @@ -265,7 +265,7 @@ static struct platform_driver via_i2c_driver = { · 264 unmodified lines | |||
| 265 | .name = "viafb-i2c", | 265 | .name = "viafb-i2c", |
| 266 | }, | 266 | }, |
| 267 | .probe = viafb_i2c_probe, | 267 | .probe = viafb_i2c_probe, |
| 268 | .remove_new = viafb_i2c_remove, | 268 | .remove = viafb_i2c_remove, |
| 269 | }; | 269 | }; |
| 270 | 270 | ||
| 271 | int viafb_i2c_init(void) | 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 | static struct platform_driver vt8500lcd_driver = { | 472 | static struct platform_driver vt8500lcd_driver = { |
| 473 | .probe = vt8500lcd_probe, | 473 | .probe = vt8500lcd_probe, |
| 474 | .remove_new = vt8500lcd_remove, | 474 | .remove = vt8500lcd_remove, |
| 475 | .driver = { | 475 | .driver = { |
| 476 | .name = "vt8500-lcd", | 476 | .name = "vt8500-lcd", |
| 477 | .of_match_table = of_match_ptr(via_dt_ids), | 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 | static struct platform_driver wm8505fb_driver = { | 393 | static struct platform_driver wm8505fb_driver = { |
| 394 | .probe = wm8505fb_probe, | 394 | .probe = wm8505fb_probe, |
| 395 | .remove_new = wm8505fb_remove, | 395 | .remove = wm8505fb_remove, |
| 396 | .driver = { | 396 | .driver = { |
| 397 | .name = DRIVER_NAME, | 397 | .name = DRIVER_NAME, |
| 398 | .of_match_table = wmt_dt_ids, | 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 | static struct platform_driver wmt_ge_rops_driver = { | 160 | static struct platform_driver wmt_ge_rops_driver = { |
| 161 | .probe = wmt_ge_rops_probe, | 161 | .probe = wmt_ge_rops_probe, |
| 162 | .remove_new = wmt_ge_rops_remove, | 162 | .remove = wmt_ge_rops_remove, |
| 163 | .driver = { | 163 | .driver = { |
| 164 | .name = "wmt_ge_rops", | 164 | .name = "wmt_ge_rops", |
| 165 | .of_match_table = wmt_dt_ids, | 165 | .of_match_table = wmt_dt_ids, |
| @@ -488,7 +488,7 @@ MODULE_DEVICE_TABLE(of, xilinxfb_of_match); · 487 unmodified lines | |||
| 488 | 488 | ||
| 489 | static struct platform_driver xilinxfb_of_driver = { | 489 | static struct platform_driver xilinxfb_of_driver = { |
| 490 | .probe = xilinxfb_of_probe, | 490 | .probe = xilinxfb_of_probe, |
| 491 | .remove_new = xilinxfb_of_remove, | 491 | .remove = xilinxfb_of_remove, |
| 492 | .driver = { | 492 | .driver = { |
| 493 | .name = DRIVER_NAME, | 493 | .name = DRIVER_NAME, |
| 494 | .of_match_table = xilinxfb_of_match, | 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 | /* Just a hint for performance: so it's ok that this can be racy! */ | 2589 | /* Just a hint for performance: so it's ok that this can be racy! */ |
| 2590 | if (vq->event) | 2590 | if (vq->event) |
| 2591 | vq->event_triggered = true; | 2591 | data_race(vq->event_triggered = true); |
| 2592 | 2592 | ||
| 2593 | pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback); | 2593 | pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback); |
| 2594 | if (vq->vq.callback) | 2594 | if (vq->vq.callback) |
| @@ -261,7 +261,6 @@ config XEN_SCSI_BACKEND · 260 unmodified lines | |||
| 261 | config XEN_PRIVCMD | 261 | config XEN_PRIVCMD |
| 262 | tristate "Xen hypercall passthrough driver" | 262 | tristate "Xen hypercall passthrough driver" |
| 263 | depends on XEN | 263 | depends on XEN |
| 264 | imply CONFIG_XEN_PCIDEV_BACKEND | ||
| 265 | default m | 264 | default m |
| 266 | help | 265 | help |
| 267 | The hypercall passthrough driver allows privileged user programs to | 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 | return 0; | 125 | return 0; |
| 126 | } | 126 | } |
| 127 | EXPORT_SYMBOL_GPL(xen_acpi_get_gsi_info); | 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 | static long privcmd_ioctl_pcidev_get_gsi(struct file *file, void __user *udata) | 850 | static long privcmd_ioctl_pcidev_get_gsi(struct file *file, void __user *udata) |
| 851 | { | 851 | { |
| 852 | #if defined(CONFIG_XEN_ACPI) | 852 | #if defined(CONFIG_XEN_ACPI) |
| 853 | int rc = -EINVAL; | 853 | int rc; |
| 854 | struct privcmd_pcidev_get_gsi kdata; | 854 | struct privcmd_pcidev_get_gsi kdata; |
| 855 | 855 | ||
| 856 | if (copy_from_user(&kdata, udata, sizeof(kdata))) | 856 | if (copy_from_user(&kdata, udata, sizeof(kdata))) |
| 857 | return -EFAULT; | 857 | return -EFAULT; |
| 858 | 858 | ||
| 859 | if (IS_REACHABLE(CONFIG_XEN_PCIDEV_BACKEND)) | 859 | rc = xen_acpi_get_gsi_from_sbdf(kdata.sbdf); |
| 860 | rc = pcistub_get_gsi_from_sbdf(kdata.sbdf); | ||
| 861 | |||
| 862 | if (rc < 0) | 860 | if (rc < 0) |
| 863 | return rc; | 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 | #ifdef CONFIG_XEN_ACPI | 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 | struct pcistub_device *psdev; | 232 | struct pcistub_device *psdev; |
| 233 | int domain = (sbdf >> 16) & 0xffff; | 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 | return psdev->gsi; | 243 | return psdev->gsi; |
| 244 | } | 244 | } |
| 245 | EXPORT_SYMBOL_GPL(pcistub_get_gsi_from_sbdf); | ||
| 246 | #endif | 245 | #endif |
| 247 | 246 | ||
| 248 | struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev, | 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 | bus_register_notifier(&pci_bus_type, &pci_stub_nb); | 1756 | bus_register_notifier(&pci_bus_type, &pci_stub_nb); |
| 1758 | #endif | 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 | return err; | 1763 | return err; |
| 1761 | } | 1764 | } |
| 1762 | 1765 | ||
| 1763 | static void __exit xen_pcibk_cleanup(void) | 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 | #ifdef CONFIG_PCI_IOV | 1772 | #ifdef CONFIG_PCI_IOV |
| 1766 | bus_unregister_notifier(&pci_bus_type, &pci_stub_nb); | 1773 | bus_unregister_notifier(&pci_bus_type, &pci_stub_nb); |
| 1767 | #endif | 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 | spin_unlock(&dentry->d_lock); | 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 | return ret; | 138 | return ret; |
| 140 | } | 139 | } |
| @@ -388,7 +388,7 @@ config NFS_COMMON · 387 unmodified lines | |||
| 388 | 388 | ||
| 389 | config NFS_COMMON_LOCALIO_SUPPORT | 389 | config NFS_COMMON_LOCALIO_SUPPORT |
| 390 | tristate | 390 | tristate |
| 391 | default n | 391 | depends on NFS_LOCALIO |
| 392 | default y if NFSD=y || NFS_FS=y | 392 | default y if NFSD=y || NFS_FS=y |
| 393 | default m if NFSD=m && NFS_FS=m | 393 | default m if NFSD=m && NFS_FS=m |
| 394 | select SUNRPC | 394 | select SUNRPC |
| @@ -130,6 +130,7 @@ struct afs_call { · 129 unmodified lines | |||
| 130 | wait_queue_head_t waitq; /* processes awaiting completion */ | 130 | wait_queue_head_t waitq; /* processes awaiting completion */ |
| 131 | struct work_struct async_work; /* async I/O processor */ | 131 | struct work_struct async_work; /* async I/O processor */ |
| 132 | struct work_struct work; /* actual work processor */ | 132 | struct work_struct work; /* actual work processor */ |
| 133 | struct work_struct free_work; /* Deferred free processor */ | ||
| 133 | struct rxrpc_call *rxcall; /* RxRPC call handle */ | 134 | struct rxrpc_call *rxcall; /* RxRPC call handle */ |
| 134 | struct rxrpc_peer *peer; /* Remote endpoint */ | 135 | struct rxrpc_peer *peer; /* Remote endpoint */ |
| 135 | struct key *key; /* security for this call */ | 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 | extern void __net_exit afs_close_socket(struct afs_net *); | 1332 | extern void __net_exit afs_close_socket(struct afs_net *); |
| 1332 | extern void afs_charge_preallocation(struct work_struct *); | 1333 | extern void afs_charge_preallocation(struct work_struct *); |
| 1333 | extern void afs_put_call(struct afs_call *); | 1334 | extern void afs_put_call(struct afs_call *); |
| 1335 | void afs_deferred_put_call(struct afs_call *call); | ||
| 1334 | void afs_make_call(struct afs_call *call, gfp_t gfp); | 1336 | void afs_make_call(struct afs_call *call, gfp_t gfp); |
| 1335 | void afs_wait_for_call_to_complete(struct afs_call *call); | 1337 | void afs_wait_for_call_to_complete(struct afs_call *call); |
| 1336 | extern struct afs_call *afs_alloc_flat_call(struct afs_net *, | 1338 | extern struct afs_call *afs_alloc_flat_call(struct afs_net *, |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | struct workqueue_struct *afs_async_calls; | 19 | struct workqueue_struct *afs_async_calls; |
| 20 | 20 | ||
| 21 | static void afs_deferred_free_worker(struct work_struct *work); | ||
| 21 | static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); | 22 | static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); |
| 22 | static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); | 23 | static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); |
| 23 | static void afs_process_async_call(struct work_struct *); | 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 | call->debug_id = atomic_inc_return(&rxrpc_debug_id); | 150 | call->debug_id = atomic_inc_return(&rxrpc_debug_id); |
| 150 | refcount_set(&call->ref, 1); | 151 | refcount_set(&call->ref, 1); |
| 151 | INIT_WORK(&call->async_work, afs_process_async_call); | 152 | INIT_WORK(&call->async_work, afs_process_async_call); |
| 153 | INIT_WORK(&call->free_work, afs_deferred_free_worker); | ||
| 152 | init_waitqueue_head(&call->waitq); | 154 | init_waitqueue_head(&call->waitq); |
| 153 | spin_lock_init(&call->state_lock); | 155 | spin_lock_init(&call->state_lock); |
| 154 | call->iter = &call->def_iter; | 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 | return call; | 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 | * Dispose of a reference on a call. | 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 | o = atomic_read(&net->nr_outstanding_calls); | 205 | o = atomic_read(&net->nr_outstanding_calls); |
| 174 | trace_afs_call(debug_id, afs_call_trace_put, r - 1, o, | 206 | trace_afs_call(debug_id, afs_call_trace_put, r - 1, o, |
| 175 | __builtin_return_address(0)); | 207 | __builtin_return_address(0)); |
| 208 | if (zero) | ||
| 209 | afs_free_call(call); | ||
| 210 | } | ||
| 176 | 211 | ||
| 177 | if (zero) { | 212 | static void afs_deferred_free_worker(struct work_struct *work) |
| 178 | ASSERT(!work_pending(&call->async_work)); | 213 | { |
| 179 | ASSERT(call->type->name != NULL); | 214 | struct afs_call *call = container_of(work, struct afs_call, free_work); |
| 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); | ||
| 190 | 215 | ||
| 191 | afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call); | 216 | afs_free_call(call); |
| 192 | kfree(call->request); | 217 | } |
| 193 | 218 | ||
| 194 | trace_afs_call(call->debug_id, afs_call_trace_free, 0, o, | 219 | /* |
| 195 | __builtin_return_address(0)); | 220 | * Dispose of a reference on a call, deferring the cleanup to a workqueue |
| 196 | kfree(call); | 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); | 230 | zero = __refcount_dec_and_test(&call->ref, &r); |
| 199 | if (o == 0) | 231 | o = atomic_read(&net->nr_outstanding_calls); |
| 200 | wake_up_var(&net->nr_outstanding_calls); | 232 | trace_afs_call(debug_id, afs_call_trace_put, r - 1, o, |
| 201 | } | 233 | __builtin_return_address(0)); |
| 234 | if (zero) | ||
| 235 | schedule_work(&call->free_work); | ||
| 202 | } | 236 | } |
| 203 | 237 | ||
| 204 | static struct afs_call *afs_get_call(struct afs_call *call, | 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 | static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall, | 680 | static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall, |
| 646 | unsigned long call_user_ID) | 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 | __builtin_return_address(0)); | 692 | __builtin_return_address(0)); |
| 658 | 693 | ||
| 659 | if (!queue_work(afs_async_calls, &call->async_work)) | 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 | a->io_time[1] = swab64(a->io_time[1]); | 332 | a->io_time[1] = swab64(a->io_time[1]); |
| 333 | a->stripe = swab32(a->stripe); | 333 | a->stripe = swab32(a->stripe); |
| 334 | a->nr_external_backpointers = swab32(a->nr_external_backpointers); | 334 | a->nr_external_backpointers = swab32(a->nr_external_backpointers); |
| 335 | a->fragmentation_lru = swab64(a->fragmentation_lru); | ||
| 336 | a->stripe_sectors = swab32(a->stripe_sectors); | 335 | a->stripe_sectors = swab32(a->stripe_sectors); |
| 337 | 336 | ||
| 338 | bps = alloc_v4_backpointers(a); | 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 | struct bch_alloc_v4 _a; | 347 | struct bch_alloc_v4 _a; |
| 349 | const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a); | 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 | prt_newline(out); | 351 | prt_newline(out); |
| 352 | printbuf_indent_add(out, 2); | 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 | prt_printf(out, "stripe_redundancy %u\n", a->stripe_redundancy); | 364 | prt_printf(out, "stripe_redundancy %u\n", a->stripe_redundancy); |
| 365 | prt_printf(out, "io_time[READ] %llu\n", a->io_time[READ]); | 365 | prt_printf(out, "io_time[READ] %llu\n", a->io_time[READ]); |
| 366 | prt_printf(out, "io_time[WRITE] %llu\n", a->io_time[WRITE]); | 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 | prt_printf(out, "bp_start %llu\n", BCH_ALLOC_V4_BACKPOINTERS_START(a)); | 370 | prt_printf(out, "bp_start %llu\n", BCH_ALLOC_V4_BACKPOINTERS_START(a)); |
| 369 | printbuf_indent_sub(out, 2); | 371 | printbuf_indent_sub(out, 2); |
| 372 | |||
| 373 | bch2_dev_put(ca); | ||
| 370 | } | 374 | } |
| 371 | 375 | ||
| 372 | void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out) | 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 | continue; | 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 | struct bch_alloc_v4 a; | 652 | struct bch_alloc_v4 a; |
| 639 | *bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen; | 653 | *bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen; |
| 640 | 0; | 654 | 0; |
| @@ -882,12 +896,13 @@ int bch2_trigger_alloc(struct btree_trans *trans, · 241 unmodified lines | |||
| 882 | goto err; | 896 | goto err; |
| 883 | } | 897 | } |
| 884 | 898 | ||
| 885 | new_a->fragmentation_lru = alloc_lru_idx_fragmentation(*new_a, ca); | 899 | old_lru = alloc_lru_idx_fragmentation(*old_a, ca); |
| 886 | if (old_a->fragmentation_lru != new_a->fragmentation_lru) { | 900 | new_lru = alloc_lru_idx_fragmentation(*new_a, ca); |
| 901 | if (old_lru != new_lru) { | ||
| 887 | ret = bch2_lru_change(trans, | 902 | ret = bch2_lru_change(trans, |
| 888 | BCH_LRU_FRAGMENTATION_START, | 903 | BCH_LRU_FRAGMENTATION_START, |
| 889 | bucket_to_u64(new.k->p), | 904 | bucket_to_u64(new.k->p), |
| 890 | old_a->fragmentation_lru, new_a->fragmentation_lru); | 905 | old_lru, new_lru); |
| 891 | if (ret) | 906 | if (ret) |
| 892 | goto err; | 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 | if (ret) | 1644 | if (ret) |
| 1630 | return ret; | 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 | a = bch2_alloc_to_v4(alloc_k, &a_convert); | 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 | ret = bch2_lru_check_set(trans, BCH_LRU_FRAGMENTATION_START, | 1655 | ret = bch2_lru_check_set(trans, BCH_LRU_FRAGMENTATION_START, |
| 1636 | a->fragmentation_lru, | 1656 | lru_idx, alloc_k, last_flushed); |
| 1637 | alloc_k, last_flushed); | ||
| 1638 | if (ret) | 1657 | if (ret) |
| 1639 | return ret; | 1658 | goto err; |
| 1640 | } | 1659 | } |
| 1641 | 1660 | ||
| 1642 | if (a->data_type != BCH_DATA_cached) | 1661 | if (a->data_type != BCH_DATA_cached) |
| 1643 | return 0; | 1662 | goto err; |
| 1644 | 1663 | ||
| 1645 | if (fsck_err_on(!a->io_time[READ], | 1664 | if (fsck_err_on(!a->io_time[READ], |
| 1646 | trans, alloc_key_cached_but_read_time_zero, | 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 | goto err; | 1688 | goto err; |
| 1670 | err: | 1689 | err: |
| 1671 | fsck_err: | 1690 | fsck_err: |
| 1691 | bch2_dev_put(ca); | ||
| 1672 | printbuf_exit(&buf); | 1692 | printbuf_exit(&buf); |
| 1673 | return ret; | 1693 | return ret; |
| 1674 | } | 1694 | } |
| @@ -1957,7 +1977,7 @@ static void bch2_do_discards_fast_work(struct work_struct *work) · 282 unmodified lines | |||
| 1957 | ca->mi.bucket_size, | 1977 | ca->mi.bucket_size, |
| 1958 | GFP_KERNEL); | 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 | BCH_WATERMARK_btree| | 1981 | BCH_WATERMARK_btree| |
| 1962 | BCH_TRANS_COMMIT_no_enospc, | 1982 | BCH_TRANS_COMMIT_no_enospc, |
| 1963 | bch2_clear_bucket_needs_discard(trans, POS(ca->dev_idx, bucket))); | 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 | struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped); | 2138 | struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped); |
| 2119 | ret = bkey_err(k); | 2139 | ret = bkey_err(k); |
| 2120 | if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) | ||
| 2121 | continue; | ||
| 2122 | if (ret) | 2140 | if (ret) |
| 2123 | break; | 2141 | goto restart_err; |
| 2124 | if (!k.k) | 2142 | if (!k.k) |
| 2125 | break; | 2143 | break; |
| 2126 | 2144 | ||
| 2127 | ret = invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate); | 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 | if (ret) | 2149 | if (ret) |
| 2129 | break; | 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 | /* Bucket IO clocks: */ | 2352 | /* Bucket IO clocks: */ |
| 2332 | 2353 | ||
| 2333 | int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev, | 2354 | static int __bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev, |
| 2334 | size_t bucket_nr, int rw) | 2355 | size_t bucket_nr, int rw) |
| 2335 | { | 2356 | { |
| 2336 | struct bch_fs *c = trans->c; | 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)) | 2359 | struct btree_iter iter; |
| 2343 | bch2_trans_begin(trans); | 2360 | struct bkey_i_alloc_v4 *a = |
| 2344 | 2361 | bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(dev, bucket_nr)); | |
| 2345 | a = bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(dev, bucket_nr)); | 2362 | int ret = PTR_ERR_OR_ZERO(a); |
| 2346 | ret = PTR_ERR_OR_ZERO(a); | ||
| 2347 | if (ret) | 2363 | if (ret) |
| 2348 | return ret; | 2364 | return ret; |
| 2349 | 2365 | ||
| 2350 | now = bch2_current_io_time(c, rw); | 2366 | u64 now = bch2_current_io_time(c, rw); |
| 2351 | if (a->v.io_time[rw] == now) | 2367 | if (a->v.io_time[rw] == now) |
| 2352 | goto out; | 2368 | goto out; |
| 2353 | 2369 | ||
| @@ -2360,6 +2376,15 @@ out: · 6 unmodified lines | |||
| 2360 | return ret; | 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 | /* Startup/shutdown (ro/rw): */ | 2388 | /* Startup/shutdown (ro/rw): */ |
| 2364 | 2389 | ||
| 2365 | void bch2_recalc_capacity(struct bch_fs *c) | 2390 | void bch2_recalc_capacity(struct bch_fs *c) |
| @@ -70,7 +70,7 @@ struct bch_alloc_v4 { · 69 unmodified lines | |||
| 70 | __u32 stripe; | 70 | __u32 stripe; |
| 71 | __u32 nr_external_backpointers; | 71 | __u32 nr_external_backpointers; |
| 72 | /* end of fields in original version of alloc_v4 */ | 72 | /* end of fields in original version of alloc_v4 */ |
| 73 | __u64 fragmentation_lru; | 73 | __u64 _fragmentation_lru; /* obsolete */ |
| 74 | __u32 stripe_sectors; | 74 | __u32 stripe_sectors; |
| 75 | __u32 pad; | 75 | __u32 pad; |
| 76 | } __packed __aligned(8); | 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 | struct bch_dev_usage usage; | 684 | struct bch_dev_usage usage; |
| 685 | struct open_bucket *ob; | 685 | struct open_bucket *ob; |
| 686 | 686 | ||
| 687 | bch2_trans_do(c, NULL, NULL, 0, | 687 | bch2_trans_do(c, |
| 688 | PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(trans, ca, watermark, | 688 | PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(trans, ca, watermark, |
| 689 | data_type, cl, false, &usage))); | 689 | data_type, cl, false, &usage))); |
| 690 | return ob; | 690 | return ob; |
| @@ -678,7 +678,8 @@ struct bch_sb_field_ext { · 677 unmodified lines | |||
| 678 | x(disk_accounting_v2, BCH_VERSION(1, 9)) \ | 678 | x(disk_accounting_v2, BCH_VERSION(1, 9)) \ |
| 679 | x(disk_accounting_v3, BCH_VERSION(1, 10)) \ | 679 | x(disk_accounting_v3, BCH_VERSION(1, 10)) \ |
| 680 | x(disk_accounting_inum, BCH_VERSION(1, 11)) \ | 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 | enum bcachefs_metadata_version { | 684 | enum bcachefs_metadata_version { |
| 684 | bcachefs_metadata_version_min = 9, | 685 | bcachefs_metadata_version_min = 9, |
| @@ -820,15 +820,23 @@ static int bch2_alloc_write_key(struct btree_trans *trans, · 819 unmodified lines | |||
| 820 | * fix that here: | 820 | * fix that here: |
| 821 | */ | 821 | */ |
| 822 | alloc_data_type_set(&gc, gc.data_type); | 822 | alloc_data_type_set(&gc, gc.data_type); |
| 823 | |||
| 824 | if (gc.data_type != old_gc.data_type || | 823 | if (gc.data_type != old_gc.data_type || |
| 825 | gc.dirty_sectors != old_gc.dirty_sectors) { | 824 | gc.dirty_sectors != old_gc.dirty_sectors) { |
| 826 | ret = bch2_alloc_key_to_dev_counters(trans, ca, &old_gc, &gc, BTREE_TRIGGER_gc); | 825 | ret = bch2_alloc_key_to_dev_counters(trans, ca, &old_gc, &gc, BTREE_TRIGGER_gc); |
| 827 | if (ret) | 826 | if (ret) |
| 828 | return ret; | 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 | if (fsck_err_on(new.data_type != gc.data_type, | 841 | if (fsck_err_on(new.data_type != gc.data_type, |
| 834 | trans, alloc_key_data_type_wrong, | 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 | copy_bucket_field(alloc_key_cached_sectors_wrong, cached_sectors); | 865 | copy_bucket_field(alloc_key_cached_sectors_wrong, cached_sectors); |
| 858 | copy_bucket_field(alloc_key_stripe_wrong, stripe); | 866 | copy_bucket_field(alloc_key_stripe_wrong, stripe); |
| 859 | copy_bucket_field(alloc_key_stripe_redundancy_wrong, stripe_redundancy); | 867 | copy_bucket_field(alloc_key_stripe_redundancy_wrong, stripe_redundancy); |
| 860 | copy_bucket_field(alloc_key_fragmentation_lru_wrong, fragmentation_lru); | ||
| 861 | #undef copy_bucket_field | 868 | #undef copy_bucket_field |
| 862 | 869 | ||
| 863 | if (!bch2_alloc_v4_cmp(*old, new)) | 870 | if (!bch2_alloc_v4_cmp(*old, new)) |
| @@ -1227,17 +1234,20 @@ int bch2_gc_gens(struct bch_fs *c) · 363 unmodified lines | |||
| 1227 | u64 b, start_time = local_clock(); | 1234 | u64 b, start_time = local_clock(); |
| 1228 | int ret; | 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 | if (!mutex_trylock(&c->gc_gens_lock)) | 1237 | if (!mutex_trylock(&c->gc_gens_lock)) |
| 1236 | return 0; | 1238 | return 0; |
| 1237 | 1239 | ||
| 1238 | trace_and_count(c, gc_gens_start, c); | 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 | for_each_member_device(c, ca) { | 1252 | for_each_member_device(c, ca) { |
| 1243 | struct bucket_gens *gens = bucket_gens(ca); | 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 | struct btree_trans *trans = bch2_trans_get(c); | 1838 | struct btree_trans *trans = bch2_trans_get(c); |
| 1839 | 1839 | ||
| 1840 | btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read); | 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 | bch2_trans_put(trans); | 1843 | bch2_trans_put(trans); |
| 1844 | __btree_node_write_done(c, b); | ||
| 1845 | six_unlock_read(&b->c.lock); | ||
| 1845 | } | 1846 | } |
| 1846 | 1847 | ||
| 1847 | static void btree_node_write_work(struct work_struct *work) | 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 | } else { | 1873 | } else { |
| 1873 | ret = bch2_trans_do(c, NULL, NULL, 0, | 1874 | ret = bch2_trans_do(c, |
| 1874 | bch2_btree_node_update_key_get_iter(trans, b, &wbio->key, | 1875 | bch2_btree_node_update_key_get_iter(trans, b, &wbio->key, |
| 1875 | BCH_WATERMARK_interior_updates| | 1876 | BCH_WATERMARK_interior_updates| |
| 1876 | BCH_TRANS_COMMIT_journal_reclaim| | 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 | else | 2381 | else |
| 2382 | iter_pos = bkey_max(iter->pos, bkey_start_pos(k.k)); | 2382 | iter_pos = bkey_max(iter->pos, bkey_start_pos(k.k)); |
| 2383 | 2383 | ||
| 2384 | if (unlikely(!(iter->flags & BTREE_ITER_is_extents) | 2384 | if (unlikely(iter->flags & BTREE_ITER_all_snapshots ? bpos_gt(iter_pos, end) : |
| 2385 | ? bkey_gt(iter_pos, end) | 2385 | iter->flags & BTREE_ITER_is_extents ? bkey_ge(iter_pos, end) : |
| 2386 | : bkey_ge(iter_pos, end))) | 2386 | bkey_gt(iter_pos, end))) |
| 2387 | goto end; | 2387 | goto end; |
| 2388 | 2388 | ||
| 2389 | break; | 2389 | break; |
| @@ -857,6 +857,14 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *); · 856 unmodified lines | |||
| 857 | for_each_btree_key_upto_norestart(_trans, _iter, _btree_id, _start,\ | 857 | for_each_btree_key_upto_norestart(_trans, _iter, _btree_id, _start,\ |
| 858 | SPOS_MAX, _flags, _k, _ret) | 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 | #define for_each_btree_key_continue_norestart(_iter, _flags, _k, _ret) \ | 868 | #define for_each_btree_key_continue_norestart(_iter, _flags, _k, _ret) \ |
| 861 | for_each_btree_key_upto_continue_norestart(_iter, SPOS_MAX, _flags, _k, _ret) | 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 | _ret; \ | 912 | _ret; \ |
| 905 | }) | 913 | }) |
| 906 | 914 | ||
| 915 | #define bch2_trans_do(_c, _do) bch2_trans_run(_c, lockrestart_do(trans, _do)) | ||
| 916 | |||
| 907 | struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned); | 917 | struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned); |
| 908 | void bch2_trans_put(struct btree_trans *); | 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 | if (BTREE_NODE_LEVEL(bn) >= BTREE_MAX_DEPTH) | 171 | if (BTREE_NODE_LEVEL(bn) >= BTREE_MAX_DEPTH) |
| 172 | return; | 172 | return; |
| 173 | 173 | ||
| 174 | if (BTREE_NODE_ID(bn) >= BTREE_ID_NR_MAX) | ||
| 175 | return; | ||
| 176 | |||
| 174 | rcu_read_lock(); | 177 | rcu_read_lock(); |
| 175 | struct found_btree_node n = { | 178 | struct found_btree_node n = { |
| 176 | .btree_id = BTREE_NODE_ID(bn), | 179 | .btree_id = BTREE_NODE_ID(bn), |
| @@ -832,7 +832,8 @@ revert_fs_usage: · 831 unmodified lines | |||
| 832 | for (struct jset_entry *entry2 = trans->journal_entries; | 832 | for (struct jset_entry *entry2 = trans->journal_entries; |
| 833 | entry2 != entry; | 833 | entry2 != entry; |
| 834 | entry2 = vstruct_next(entry2)) | 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 | struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start); | 837 | struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start); |
| 837 | 838 | ||
| 838 | bch2_accounting_neg(a); | 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 | struct disk_reservation *disk_res, int flags, | 668 | struct disk_reservation *disk_res, int flags, |
| 669 | enum btree_iter_update_trigger_flags iter_flags) | 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 | bch2_btree_insert_trans(trans, id, k, iter_flags)); | 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 | memcpy(l->d, buf.buf, buf.pos); | 865 | memcpy(l->d, buf.buf, buf.pos); |
| 866 | c->journal.early_journal_entries.nr += jset_u64s(u64s); | 866 | c->journal.early_journal_entries.nr += jset_u64s(u64s); |
| 867 | } else { | 867 | } else { |
| 868 | ret = bch2_trans_do(c, NULL, NULL, | 868 | ret = bch2_trans_commit_do(c, NULL, NULL, |
| 869 | BCH_TRANS_COMMIT_lazy_rw|commit_flags, | 869 | BCH_TRANS_COMMIT_lazy_rw|commit_flags, |
| 870 | __bch2_trans_log_msg(trans, &buf, u64s)); | 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 | nested_lockrestart_do(_trans, _do ?: bch2_trans_commit(_trans, (_disk_res),\ | 192 | nested_lockrestart_do(_trans, _do ?: bch2_trans_commit(_trans, (_disk_res),\ |
| 193 | (_journal_seq), (_flags))) | 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 | bch2_trans_run(_c, commit_do(trans, _disk_res, _journal_seq, _flags, _do)) | 196 | bch2_trans_run(_c, commit_do(trans, _disk_res, _journal_seq, _flags, _do)) |
| 197 | 197 | ||
| 198 | #define trans_for_each_update(_trans, _i) \ | 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 | struct async_btree_rewrite *a = | 2239 | struct async_btree_rewrite *a = |
| 2240 | container_of(work, struct async_btree_rewrite, work); | 2240 | container_of(work, struct async_btree_rewrite, work); |
| 2241 | struct bch_fs *c = a->c; | 2241 | struct bch_fs *c = a->c; |
| 2242 | int ret; | ||
| 2243 | 2242 | ||
| 2244 | ret = bch2_trans_do(c, NULL, NULL, 0, | 2243 | int ret = bch2_trans_do(c, async_btree_node_rewrite_trans(trans, a)); |
| 2245 | async_btree_node_rewrite_trans(trans, a)); | ||
| 2246 | bch_err_fn_ratelimited(c, ret); | 2244 | bch_err_fn_ratelimited(c, ret); |
| 2247 | bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite); | 2245 | bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite); |
| 2248 | kfree(a); | 2246 | kfree(a); |
| @@ -1160,11 +1160,11 @@ int bch2_trans_mark_dev_sbs(struct bch_fs *c) · 1159 unmodified lines | |||
| 1160 | #define SECTORS_CACHE 1024 | 1160 | #define SECTORS_CACHE 1024 |
| 1161 | 1161 | ||
| 1162 | int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res, | 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 | struct bch_fs_pcpu *pcpu; | 1165 | struct bch_fs_pcpu *pcpu; |
| 1166 | u64 old, get; | 1166 | u64 old, get; |
| 1167 | s64 sectors_available; | 1167 | u64 sectors_available; |
| 1168 | int ret; | 1168 | int ret; |
| 1169 | 1169 | ||
| 1170 | percpu_down_read(&c->mark_lock); | 1170 | percpu_down_read(&c->mark_lock); |
| @@ -1202,6 +1202,9 @@ recalculate: · 31 unmodified lines | |||
| 1202 | percpu_u64_set(&c->pcpu->sectors_available, 0); | 1202 | percpu_u64_set(&c->pcpu->sectors_available, 0); |
| 1203 | sectors_available = avail_factor(__bch2_fs_usage_read_short(c).free); | 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 | if (sectors <= sectors_available || | 1208 | if (sectors <= sectors_available || |
| 1206 | (flags & BCH_DISK_RESERVATION_NOFAIL)) { | 1209 | (flags & BCH_DISK_RESERVATION_NOFAIL)) { |
| 1207 | atomic64_set(&c->sectors_available, | 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 *, | 352 | int __bch2_disk_reservation_add(struct bch_fs *, struct disk_reservation *, |
| 350 | struct disk_reservation *, | 353 | u64, enum bch_reservation_flags); |
| 351 | u64, int); | ||
| 352 | 354 | ||
| 353 | static inline int bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res, | 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 | #ifdef __KERNEL__ | 358 | #ifdef __KERNEL__ |
| 357 | u64 old, new; | 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 | opt_set(thr->opts, stdio, (u64)(unsigned long)&thr->thr.stdio); | 226 | opt_set(thr->opts, stdio, (u64)(unsigned long)&thr->thr.stdio); |
| 227 | opt_set(thr->opts, read_only, 1); | 227 | opt_set(thr->opts, read_only, 1); |
| 228 | opt_set(thr->opts, ratelimit_errors, 0); | ||
| 228 | 229 | ||
| 229 | /* We need request_key() to be called before we punt to kthread: */ | 230 | /* We need request_key() to be called before we punt to kthread: */ |
| 230 | opt_set(thr->opts, nostart, true); | 231 | opt_set(thr->opts, nostart, true); |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | #include <linux/log2.h> | 3 | #include <linux/log2.h> |
| 4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
| 5 | #include <linux/vmalloc.h> | ||
| 5 | #include "darray.h" | 6 | #include "darray.h" |
| 6 | 7 | ||
| 7 | int __bch2_darray_resize_noprof(darray_char *d, size_t element_size, size_t new_size, gfp_t gfp) | 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 | if (new_size > d->size) { | 10 | if (new_size > d->size) { |
| 10 | new_size = roundup_pow_of_two(new_size); | 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 | if (!data) | 26 | if (!data) |
| 14 | return -ENOMEM; | 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 | if (ptr2 == ptr) | 80 | if (ptr2 == ptr) |
| 81 | break; | 81 | break; |
| 82 | 82 | ||
| 83 | ca = bch2_dev_have_ref(c, ptr2->dev); | ||
| 83 | bucket = PTR_BUCKET_POS(ca, ptr2); | 84 | bucket = PTR_BUCKET_POS(ca, ptr2); |
| 84 | bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0); | 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 | return ret; | 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 | int bch2_dirent_read_target(struct btree_trans *trans, subvol_inum dir, | 253 | int bch2_dirent_read_target(struct btree_trans *trans, subvol_inum dir, |
| 261 | struct bkey_s_c_dirent d, subvol_inum *target) | 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 | int bch2_dirent_read_target(struct btree_trans *, subvol_inum, | 34 | int bch2_dirent_read_target(struct btree_trans *, subvol_inum, |
| 35 | struct bkey_s_c_dirent, subvol_inum *); | 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 | int bch2_dirent_create_snapshot(struct btree_trans *, u32, u64, u32, | 44 | int bch2_dirent_create_snapshot(struct btree_trans *, u32, u64, u32, |
| 38 | const struct bch_hash_info *, u8, | 45 | const struct bch_hash_info *, u8, |
| 39 | const struct qstr *, u64, u64 *, | 46 | const struct qstr *, u64, u64 *, |
| @@ -242,6 +242,14 @@ void bch2_accounting_swab(struct bkey_s k) · 241 unmodified lines | |||
| 242 | *p = swab64(*p); | 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 | static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struct bpos p) | 253 | static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struct bpos p) |
| 246 | { | 254 | { |
| 247 | struct disk_accounting_pos acc_k; | 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 | switch (acc_k.type) { | 258 | switch (acc_k.type) { |
| 251 | case BCH_DISK_ACCOUNTING_replicas: | 259 | case BCH_DISK_ACCOUNTING_replicas: |
| 252 | unsafe_memcpy(r, &acc_k.replicas, | 260 | __accounting_to_replicas(r, acc_k); |
| 253 | replicas_entry_bytes(&acc_k.replicas), | ||
| 254 | "variable length struct"); | ||
| 255 | return true; | 261 | return true; |
| 256 | default: | 262 | default: |
| 257 | return false; | 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 | return ret; | 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 | * At startup time, initialize the in memory accounting from the btree (and | 693 | * At startup time, initialize the in memory accounting from the btree (and |
| 613 | * journal) | 694 | * journal) |
| @@ -666,44 +747,42 @@ int bch2_accounting_read(struct bch_fs *c) · 52 unmodified lines | |||
| 666 | } | 747 | } |
| 667 | keys->gap = keys->nr = dst - keys->data; | 748 | keys->gap = keys->nr = dst - keys->data; |
| 668 | 749 | ||
| 669 | percpu_down_read(&c->mark_lock); | 750 | percpu_down_write(&c->mark_lock); |
| 670 | for (unsigned i = 0; i < acc->k.nr; i++) { | 751 | unsigned i = 0; |
| 671 | u64 v[BCH_ACCOUNTING_MAX_COUNTERS]; | 752 | while (i < acc->k.nr) { |
| 672 | bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false); | 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)) | 755 | struct disk_accounting_pos acc_k; |
| 675 | continue; | 756 | bpos_to_disk_accounting_pos(&acc_k, acc->k.data[idx].pos); |
| 676 | 757 | ||
| 677 | struct bch_replicas_padded r; | 758 | u64 v[BCH_ACCOUNTING_MAX_COUNTERS]; |
| 678 | if (!accounting_to_replicas(&r.e, acc->k.data[i].pos)) | 759 | bch2_accounting_mem_read_counters(acc, idx, v, ARRAY_SIZE(v), false); |
| 679 | continue; | ||
| 680 | 760 | ||
| 681 | /* | 761 | /* |
| 682 | * If the replicas entry is invalid it'll get cleaned up by | 762 | * If the entry counters are zeroed, it should be treated as |
| 683 | * check_allocations: | 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 | continue; | 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 | preempt_disable(); | 788 | preempt_disable(); |
| @@ -742,7 +821,7 @@ int bch2_accounting_read(struct bch_fs *c) · 32 unmodified lines | |||
| 742 | } | 821 | } |
| 743 | preempt_enable(); | 822 | preempt_enable(); |
| 744 | fsck_err: | 823 | fsck_err: |
| 745 | percpu_up_read(&c->mark_lock); | 824 | percpu_up_write(&c->mark_lock); |
| 746 | err: | 825 | err: |
| 747 | printbuf_exit(&buf); | 826 | printbuf_exit(&buf); |
| 748 | bch2_trans_put(trans); | 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 | u64 v[3] = { ca->mi.nbuckets - ca->mi.first_bucket, 0, 0 }; | 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, | 859 | int ret = bch2_trans_do(c, ({ |
| 781 | bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc)); | 860 | bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc) ?: |
| 861 | (!gc ? bch2_trans_commit(trans, NULL, NULL, 0) : 0); | ||
| 862 | })); | ||
| 782 | bch_err_fn(c, ret); | 863 | bch_err_fn(c, ret); |
| 783 | return ret; | 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 | "incorrect value size (%zu < %u)", | 124 | "incorrect value size (%zu < %u)", |
| 125 | bkey_val_u64s(k.k), stripe_val_u64s(s)); | 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 | ret = bch2_bkey_ptrs_validate(c, k, flags); | 132 | ret = bch2_bkey_ptrs_validate(c, k, flags); |
| 128 | fsck_err: | 133 | fsck_err: |
| 129 | return ret; | 134 | return ret; |
| @@ -145,7 +150,11 @@ void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c, · 15 unmodified lines | |||
| 145 | nr_data, | 150 | nr_data, |
| 146 | s.nr_redundant); | 151 | s.nr_redundant); |
| 147 | bch2_prt_csum_type(out, s.csum_type); | 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 | if (s.disk_label) { | 159 | if (s.disk_label) { |
| 151 | prt_str(out, " label"); | 160 | prt_str(out, " label"); |
| @@ -257,12 +266,12 @@ static int __mark_stripe_bucket(struct btree_trans *trans, · 105 unmodified lines | |||
| 257 | if (!deleting) { | 266 | if (!deleting) { |
| 258 | a->stripe = s.k->p.offset; | 267 | a->stripe = s.k->p.offset; |
| 259 | a->stripe_redundancy = s.v->nr_redundant; | 268 | a->stripe_redundancy = s.v->nr_redundant; |
| 269 | alloc_data_type_set(a, data_type); | ||
| 260 | } else { | 270 | } else { |
| 261 | a->stripe = 0; | 271 | a->stripe = 0; |
| 262 | a->stripe_redundancy = 0; | 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 | err: | 275 | err: |
| 267 | printbuf_exit(&buf); | 276 | printbuf_exit(&buf); |
| 268 | return ret; | 277 | return ret; |
| @@ -1177,7 +1186,7 @@ static void ec_stripe_delete_work(struct work_struct *work) · 908 unmodified lines | |||
| 1177 | if (!idx) | 1186 | if (!idx) |
| 1178 | break; | 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 | ec_stripe_delete(trans, idx)); | 1190 | ec_stripe_delete(trans, idx)); |
| 1182 | bch_err_fn(c, ret); | 1191 | bch_err_fn(c, ret); |
| 1183 | if (ret) | 1192 | if (ret) |
| @@ -1197,47 +1206,62 @@ void bch2_do_stripe_deletes(struct bch_fs *c) · 13 unmodified lines | |||
| 1197 | /* stripe creation: */ | 1206 | /* stripe creation: */ |
| 1198 | 1207 | ||
| 1199 | static int ec_stripe_key_update(struct btree_trans *trans, | 1208 | static int ec_stripe_key_update(struct btree_trans *trans, |
| 1200 | struct bkey_i_stripe *new, | 1209 | struct bkey_i_stripe *old, |
| 1201 | bool create) | 1210 | struct bkey_i_stripe *new) |
| 1202 | { | 1211 | { |
| 1203 | struct bch_fs *c = trans->c; | 1212 | struct bch_fs *c = trans->c; |
| 1204 | struct btree_iter iter; | 1213 | bool create = !old; |
| 1205 | struct bkey_s_c k; | ||
| 1206 | int ret; | ||
| 1207 | 1214 | ||
| 1208 | k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes, | 1215 | struct btree_iter iter; |
| 1209 | new->k.p, BTREE_ITER_intent); | 1216 | struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes, |
| 1210 | ret = bkey_err(k); | 1217 | new->k.p, BTREE_ITER_intent); |
| 1218 | int ret = bkey_err(k); | ||
| 1211 | if (ret) | 1219 | if (ret) |
| 1212 | goto err; | 1220 | goto err; |
| 1213 | 1221 | ||
| 1214 | if (k.k->type != (create ? KEY_TYPE_deleted : KEY_TYPE_stripe)) { | 1222 | if (bch2_fs_inconsistent_on(k.k->type != (create ? KEY_TYPE_deleted : KEY_TYPE_stripe), |
| 1215 | bch2_fs_inconsistent(c, "error %s stripe: got existing key type %s", | 1223 | c, "error %s stripe: got existing key type %s", |
| 1216 | create ? "creating" : "updating", | 1224 | create ? "creating" : "updating", |
| 1217 | bch2_bkey_types[k.k->type]); | 1225 | bch2_bkey_types[k.k->type])) { |
| 1218 | ret = -EINVAL; | 1226 | ret = -EINVAL; |
| 1219 | goto err; | 1227 | goto err; |
| 1220 | } | 1228 | } |
| 1221 | 1229 | ||
| 1222 | if (k.k->type == KEY_TYPE_stripe) { | 1230 | if (k.k->type == KEY_TYPE_stripe) { |
| 1223 | const struct bch_stripe *old = bkey_s_c_to_stripe(k).v; | 1231 | const struct bch_stripe *v = bkey_s_c_to_stripe(k).v; |
| 1224 | unsigned i; | ||
| 1225 | 1232 | ||
| 1226 | if (old->nr_blocks != new->v.nr_blocks) { | 1233 | BUG_ON(old->v.nr_blocks != new->v.nr_blocks); |
| 1227 | bch_err(c, "error updating stripe: nr_blocks does not match"); | 1234 | BUG_ON(old->v.nr_blocks != v->nr_blocks); |
| 1228 | ret = -EINVAL; | ||
| 1229 | goto err; | ||
| 1230 | } | ||
| 1231 | 1235 | ||
| 1232 | for (i = 0; i < new->v.nr_blocks; i++) { | 1236 | for (unsigned i = 0; i < new->v.nr_blocks; i++) { |
| 1233 | unsigned v = stripe_blockcount_get(old, i); | 1237 | unsigned sectors = stripe_blockcount_get(v, i); |
| 1234 | 1238 | ||
| 1235 | BUG_ON(v && | 1239 | if (!bch2_extent_ptr_eq(old->v.ptrs[i], new->v.ptrs[i]) && sectors) { |
| 1236 | (old->ptrs[i].dev != new->v.ptrs[i].dev || | 1240 | struct printbuf buf = PRINTBUF; |
| 1237 | old->ptrs[i].gen != new->v.ptrs[i].gen || | ||
| 1238 | old->ptrs[i].offset != new->v.ptrs[i].offset)); | ||
| 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 | goto err; | 1519 | goto err; |
| 1496 | } | 1520 | } |
| 1497 | 1521 | ||
| 1498 | ret = bch2_trans_do(c, &s->res, NULL, | 1522 | ret = bch2_trans_commit_do(c, &s->res, NULL, |
| 1499 | BCH_TRANS_COMMIT_no_check_rw| | 1523 | BCH_TRANS_COMMIT_no_check_rw| |
| 1500 | BCH_TRANS_COMMIT_no_enospc, | 1524 | BCH_TRANS_COMMIT_no_enospc, |
| 1501 | ec_stripe_key_update(trans, | 1525 | ec_stripe_key_update(trans, |
| 1502 | bkey_i_to_stripe(&s->new_stripe.key), | 1526 | s->have_existing_stripe |
| 1503 | !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 | bch_err_msg(c, ret, "creating stripe key"); | 1530 | bch_err_msg(c, ret, "creating stripe key"); |
| 1505 | if (ret) { | 1531 | if (ret) { |
| 1506 | goto err; | 1532 | goto err; |
| @@ -1876,7 +1902,15 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_ · 369 unmodified lines | |||
| 1876 | bitmap_and(devs.d, devs.d, c->rw_devs[BCH_DATA_user].d, BCH_SB_MEMBERS_MAX); | 1902 | bitmap_and(devs.d, devs.d, c->rw_devs[BCH_DATA_user].d, BCH_SB_MEMBERS_MAX); |
| 1877 | 1903 | ||
| 1878 | for_each_set_bit(i, h->s->blocks_gotten, v->nr_blocks) { | 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 | if (i < h->s->nr_data) | 1914 | if (i < h->s->nr_data) |
| 1881 | nr_have_data++; | 1915 | nr_have_data++; |
| 1882 | else | 1916 | else |
| @@ -268,7 +268,8 @@ · 267 unmodified lines | |||
| 268 | x(BCH_ERR_nopromote, nopromote_no_writes) \ | 268 | x(BCH_ERR_nopromote, nopromote_no_writes) \ |
| 269 | x(BCH_ERR_nopromote, nopromote_enomem) \ | 269 | x(BCH_ERR_nopromote, nopromote_enomem) \ |
| 270 | x(0, invalid_snapshot_node) \ | 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 | enum bch_errcode { | 274 | enum bch_errcode { |
| 274 | BCH_ERR_START = 2048, | 275 | BCH_ERR_START = 2048, |
| @@ -251,7 +251,10 @@ int __bch2_fsck_err(struct bch_fs *c, · 250 unmodified lines | |||
| 251 | * delete the key) | 251 | * delete the key) |
| 252 | * - and we don't need to warn if we're not prompting | 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 | if ((flags & FSCK_CAN_FIX) && | 259 | if ((flags & FSCK_CAN_FIX) && |
| 257 | test_bit(err, c->sb.errors_silent)) | 260 | test_bit(err, c->sb.errors_silent)) |
| @@ -393,6 +396,14 @@ int __bch2_fsck_err(struct bch_fs *c, · 135 unmodified lines | |||
| 393 | !(flags & FSCK_CAN_IGNORE))) | 396 | !(flags & FSCK_CAN_IGNORE))) |
| 394 | ret = -BCH_ERR_fsck_errors_not_fixed; | 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 | if (print) { | 407 | if (print) { |
| 397 | if (bch2_fs_stdio_redirect(c)) | 408 | if (bch2_fs_stdio_redirect(c)) |
| 398 | bch2_print(c, "%s\n", out->buf); | 409 | bch2_print(c, "%s\n", out->buf); |
| @@ -400,9 +411,7 @@ int __bch2_fsck_err(struct bch_fs *c, · 1 unmodified line | |||
| 400 | bch2_print_string_as_lines(KERN_ERR, out->buf); | 411 | bch2_print_string_as_lines(KERN_ERR, out->buf); |
| 401 | } | 412 | } |
| 402 | 413 | ||
| 403 | if (test_bit(BCH_FS_fsck_running, &c->flags) && | 414 | if (exiting) |
| 404 | (ret != -BCH_ERR_fsck_fix && | ||
| 405 | ret != -BCH_ERR_fsck_ignore)) | ||
| 406 | bch_err(c, "Unable to continue, halting"); | 415 | bch_err(c, "Unable to continue, halting"); |
| 407 | else if (suppressing) | 416 | else if (suppressing) |
| 408 | bch_err(c, "Ratelimiting new instances of previous error"); | 417 | bch_err(c, "Ratelimiting new instances of previous error"); |
| @@ -430,10 +439,17 @@ err: · 21 unmodified lines | |||
| 430 | 439 | ||
| 431 | int __bch2_bkey_fsck_err(struct bch_fs *c, | 440 | int __bch2_bkey_fsck_err(struct bch_fs *c, |
| 432 | struct bkey_s_c k, | 441 | struct bkey_s_c k, |
| 433 | enum bch_fsck_flags flags, | 442 | enum bch_validate_flags validate_flags, |
| 434 | enum bch_sb_error_id err, | 443 | enum bch_sb_error_id err, |
| 435 | const char *fmt, ...) | 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 | struct printbuf buf = PRINTBUF; | 453 | struct printbuf buf = PRINTBUF; |
| 438 | va_list args; | 454 | va_list args; |
| 439 | 455 | ||
| @@ -445,7 +461,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *c, · 5 unmodified lines | |||
| 445 | va_end(args); | 461 | va_end(args); |
| 446 | prt_str(&buf, ": delete?"); | 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 | printbuf_exit(&buf); | 465 | printbuf_exit(&buf); |
| 450 | return ret; | 466 | return ret; |
| 451 | } | 467 | } |
| @@ -167,10 +167,11 @@ void bch2_flush_fsck_errs(struct bch_fs *); · 166 unmodified lines | |||
| 167 | #define fsck_err_on(cond, c, _err_type, ...) \ | 167 | #define fsck_err_on(cond, c, _err_type, ...) \ |
| 168 | __fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__) | 168 | __fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__) |
| 169 | 169 | ||
| 170 | enum bch_validate_flags; | ||
| 170 | __printf(5, 6) | 171 | __printf(5, 6) |
| 171 | int __bch2_bkey_fsck_err(struct bch_fs *, | 172 | int __bch2_bkey_fsck_err(struct bch_fs *, |
| 172 | struct bkey_s_c, | 173 | struct bkey_s_c, |
| 173 | enum bch_fsck_flags, | 174 | enum bch_validate_flags, |
| 174 | enum bch_sb_error_id, | 175 | enum bch_sb_error_id, |
| 175 | const char *, ...); | 176 | const char *, ...); |
| 176 | 177 | ||
| @@ -180,11 +181,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *, · 3 unmodified lines | |||
| 180 | */ | 181 | */ |
| 181 | #define bkey_fsck_err(c, _err_type, _err_msg, ...) \ | 182 | #define bkey_fsck_err(c, _err_type, _err_msg, ...) \ |
| 182 | do { \ | 183 | do { \ |
| 183 | if ((flags & BCH_VALIDATE_silent)) { \ | 184 | int _ret = __bch2_bkey_fsck_err(c, k, flags, \ |
| 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,\ | ||
| 188 | BCH_FSCK_ERR_##_err_type, \ | 185 | BCH_FSCK_ERR_##_err_type, \ |
| 189 | _err_msg, ##__VA_ARGS__); \ | 186 | _err_msg, ##__VA_ARGS__); \ |
| 190 | if (_ret != -BCH_ERR_fsck_fix && \ | 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 | int bch2_bkey_ptrs_validate(struct bch_fs *, struct bkey_s_c, | 695 | int bch2_bkey_ptrs_validate(struct bch_fs *, struct bkey_s_c, |
| 696 | enum bch_validate_flags); | 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 | void bch2_ptr_swab(struct bkey_s); | 708 | void bch2_ptr_swab(struct bkey_s); |
| 699 | 709 | ||
| 700 | const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c); | 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 | folios_trunc(&fs, fi); | 856 | folios_trunc(&fs, fi); |
| 857 | end = min(end, folio_end_pos(darray_last(fs))); | 857 | end = min(end, folio_end_pos(darray_last(fs))); |
| 858 | } else { | 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 | folios_trunc(&fs, fi + 1); | 865 | folios_trunc(&fs, fi + 1); |
| 860 | end = f_pos + f_reserved; | 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 | static __always_inline long bch2_dio_write_done(struct dio_write *dio) | 370 | static __always_inline long bch2_dio_write_done(struct dio_write *dio) |
| 371 | { | 371 | { |
| 372 | struct bch_fs *c = dio->op.c; | ||
| 372 | struct kiocb *req = dio->req; | 373 | struct kiocb *req = dio->req; |
| 373 | struct bch_inode_info *inode = dio->inode; | 374 | struct bch_inode_info *inode = dio->inode; |
| 374 | bool sync = dio->sync; | 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 | ret = dio->op.error ?: ((long) dio->written << 9); | 388 | ret = dio->op.error ?: ((long) dio->written << 9); |
| 388 | bio_put(&dio->op.wbio.bio); | 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 | /* inode->i_dio_count is our ref on inode and thus bch_fs */ | 393 | /* inode->i_dio_count is our ref on inode and thus bch_fs */ |
| 393 | inode_dio_end(&inode->v); | 394 | inode_dio_end(&inode->v); |
| @@ -399,14 +399,17 @@ void bch2_folio_reservation_put(struct bch_fs *c, · 398 unmodified lines | |||
| 399 | bch2_quota_reservation_put(c, inode, &res->quota); | 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 | struct bch_inode_info *inode, | 403 | struct bch_inode_info *inode, |
| 404 | struct folio *folio, | 404 | struct folio *folio, |
| 405 | struct bch2_folio_reservation *res, | 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 | struct bch_folio *s = bch2_folio_create(folio, 0); | 409 | struct bch_folio *s = bch2_folio_create(folio, 0); |
| 409 | unsigned i, disk_sectors = 0, quota_sectors = 0; | 410 | unsigned i, disk_sectors = 0, quota_sectors = 0; |
| 411 | struct disk_reservation disk_res = {}; | ||
| 412 | size_t reserved = len; | ||
| 410 | int ret; | 413 | int ret; |
| 411 | 414 | ||
| 412 | if (!s) | 415 | if (!s) |
| @@ -422,48 +425,65 @@ int bch2_folio_reservation_get(struct bch_fs *c, · 9 unmodified lines | |||
| 422 | } | 425 | } |
| 423 | 426 | ||
| 424 | if (disk_sectors) { | 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 | if (unlikely(ret)) | 430 | if (unlikely(ret)) |
| 427 | return ret; | 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 | if (quota_sectors) { | 459 | if (quota_sectors) { |
| 431 | ret = bch2_quota_reservation_add(c, inode, &res->quota, quota_sectors, true); | 460 | ret = bch2_quota_reservation_add(c, inode, &res->quota, quota_sectors, true); |
| 432 | if (unlikely(ret)) { | 461 | if (unlikely(ret)) { |
| 433 | struct disk_reservation tmp = { .sectors = disk_sectors }; | 462 | bch2_disk_reservation_put(c, &disk_res); |
| 434 | |||
| 435 | bch2_disk_reservation_put(c, &tmp); | ||
| 436 | res->disk.sectors -= disk_sectors; | ||
| 437 | return ret; | 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 | struct bch_inode_info *inode, | 472 | struct bch_inode_info *inode, |
| 446 | struct folio *folio, | 473 | struct folio *folio, |
| 447 | struct bch2_folio_reservation *res, | 474 | struct bch2_folio_reservation *res, |
| 448 | size_t offset, size_t len) | 475 | size_t offset, size_t len) |
| 449 | { | 476 | { |
| 450 | size_t l, reserved = 0; | 477 | return __bch2_folio_reservation_get(c, inode, folio, res, offset, len, false); |
| 451 | int ret; | 478 | } |
| 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 | } | ||
| 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 | static void bch2_clear_folio_bits(struct folio *folio) | 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 | struct bch_inode_unpacked u; | 183 | struct bch_inode_unpacked u; |
| 184 | int ret = bch2_inode_find_by_inum(c, inode_inum(inode), &u) ?: | 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 | bch2_inode_flush_nocow_writes(c, inode); | 186 | bch2_inode_flush_nocow_writes(c, inode); |
| 187 | bch2_write_ref_put(c, BCH_WRITE_REF_fsync); | 187 | bch2_write_ref_put(c, BCH_WRITE_REF_fsync); |
| 188 | return ret; | 188 | return ret; |
| @@ -157,6 +157,20 @@ static bool subvol_inum_eq(subvol_inum a, subvol_inum b) · 156 unmodified lines | |||
| 157 | return a.subvol == b.subvol && a.inum == b.inum; | 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 | static int bch2_vfs_inode_cmp_fn(struct rhashtable_compare_arg *arg, | 174 | static int bch2_vfs_inode_cmp_fn(struct rhashtable_compare_arg *arg, |
| 161 | const void *obj) | 175 | const void *obj) |
| 162 | { | 176 | { |
| @@ -170,26 +184,111 @@ static const struct rhashtable_params bch2_vfs_inodes_params = { · 7 unmodified lines | |||
| 170 | .head_offset = offsetof(struct bch_inode_info, hash), | 184 | .head_offset = offsetof(struct bch_inode_info, hash), |
| 171 | .key_offset = offsetof(struct bch_inode_info, ei_inum), | 185 | .key_offset = offsetof(struct bch_inode_info, ei_inum), |
| 172 | .key_len = sizeof(subvol_inum), | 186 | .key_len = sizeof(subvol_inum), |
| 187 | .hashfn = bch2_vfs_inode_hash_fn, | ||
| 188 | .obj_hashfn = bch2_vfs_inode_obj_hash_fn, | ||
| 173 | .obj_cmpfn = bch2_vfs_inode_cmp_fn, | 189 | .obj_cmpfn = bch2_vfs_inode_cmp_fn, |
| 174 | .automatic_shrinking = true, | 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; | 195 | struct bch_fs *c = trans->c; |
| 180 | DEFINE_WAIT_BIT(wait, &inode->i_state, __I_NEW); | 196 | struct rhashtable *ht = &c->vfs_inodes_table; |
| 181 | wq = bit_waitqueue(&inode->i_state, __I_NEW); | 197 | subvol_inum inum = (subvol_inum) { .inum = p.offset }; |
| 182 | prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE); | 198 | DARRAY(u32) subvols; |
| 183 | spin_unlock(&inode->i_lock); | 199 | int ret = 0; |
| 184 | schedule(); | 200 | |
| 185 | finish_wait(wq, &wait.wq_entry); | 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 | return rhashtable_lookup_fast(&c->vfs_inodes_table, &inum, bch2_vfs_inodes_params); | 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 | static struct bch_inode_info *bch2_inode_hash_find(struct bch_fs *c, struct btree_trans *trans, | 292 | static struct bch_inode_info *bch2_inode_hash_find(struct bch_fs *c, struct btree_trans *trans, |
| 194 | subvol_inum inum) | 293 | subvol_inum inum) |
| 195 | { | 294 | { |
| @@ -204,10 +303,10 @@ repeat: · 8 unmodified lines | |||
| 204 | } | 303 | } |
| 205 | if ((inode->v.i_state & (I_FREEING|I_WILL_FREE))) { | 304 | if ((inode->v.i_state & (I_FREEING|I_WILL_FREE))) { |
| 206 | if (!trans) { | 305 | if (!trans) { |
| 207 | __wait_on_freeing_inode(&inode->v); | 306 | __wait_on_freeing_inode(c, inode, inum); |
| 208 | } else { | 307 | } else { |
| 209 | bch2_trans_unlock(trans); | 308 | bch2_trans_unlock(trans); |
| 210 | __wait_on_freeing_inode(&inode->v); | 309 | __wait_on_freeing_inode(c, inode, inum); |
| 211 | int ret = bch2_trans_relock(trans); | 310 | int ret = bch2_trans_relock(trans); |
| 212 | if (ret) | 311 | if (ret) |
| 213 | return ERR_PTR(ret); | 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 | &inode->hash, bch2_vfs_inodes_params); | 331 | &inode->hash, bch2_vfs_inodes_params); |
| 233 | BUG_ON(ret); | 332 | BUG_ON(ret); |
| 234 | inode->v.i_hash.pprev = NULL; | 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 | set_bit(EI_INODE_HASHED, &inode->ei_flags); | 348 | set_bit(EI_INODE_HASHED, &inode->ei_flags); |
| 245 | retry: | 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 | &inode->hash, | 352 | &inode->hash, |
| 248 | bch2_vfs_inodes_params))) { | 353 | bch2_vfs_inodes_params))) { |
| 249 | old = bch2_inode_hash_find(c, trans, inode->ei_inum); | 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 | BUG(); | 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 | struct bch_inode_info *inode = alloc_inode_sb(c->vfs_sb, | 401 | struct bch_inode_info *inode = alloc_inode_sb(c->vfs_sb, |
| 297 | bch2_inode_cache, GFP_NOFS); | 402 | bch2_inode_cache, gfp); |
| 298 | if (!inode) | 403 | if (!inode) |
| 299 | return NULL; | 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 | mutex_init(&inode->ei_quota_lock); | 411 | mutex_init(&inode->ei_quota_lock); |
| 307 | memset(&inode->ei_devs_need_flush, 0, sizeof(inode->ei_devs_need_flush)); | 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 | kmem_cache_free(bch2_inode_cache, inode); | 415 | kmem_cache_free(bch2_inode_cache, inode); |
| 311 | return NULL; | 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 | static struct bch_inode_info *bch2_new_inode(struct btree_trans *trans) | 425 | static struct bch_inode_info *bch2_new_inode(struct btree_trans *trans) |
| 321 | { | 426 | { |
| 322 | struct bch_inode_info *inode = | 427 | struct bch_inode_info *inode = __bch2_new_inode(trans->c, GFP_NOWAIT); |
| 323 | memalloc_flags_do(PF_MEMALLOC_NORECLAIM|PF_MEMALLOC_NOWARN, | ||
| 324 | __bch2_new_inode(trans->c)); | ||
| 325 | 428 | ||
| 326 | if (unlikely(!inode)) { | 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 | if (ret && inode) { | 431 | if (ret && inode) { |
| 329 | __destroy_inode(&inode->v); | 432 | __destroy_inode(&inode->v); |
| 330 | kmem_cache_free(bch2_inode_cache, inode); | 433 | kmem_cache_free(bch2_inode_cache, inode); |
| @@ -398,7 +501,7 @@ __bch2_create(struct mnt_idmap *idmap, · 67 unmodified lines | |||
| 398 | if (ret) | 501 | if (ret) |
| 399 | return ERR_PTR(ret); | 502 | return ERR_PTR(ret); |
| 400 | #endif | 503 | #endif |
| 401 | inode = __bch2_new_inode(c); | 504 | inode = __bch2_new_inode(c, GFP_NOFS); |
| 402 | if (unlikely(!inode)) { | 505 | if (unlikely(!inode)) { |
| 403 | inode = ERR_PTR(-ENOMEM); | 506 | inode = ERR_PTR(-ENOMEM); |
| 404 | goto err; | 507 | goto err; |
| @@ -553,7 +656,7 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry, · 148 unmodified lines | |||
| 553 | struct bch_hash_info hash = bch2_hash_info_init(c, &dir->ei_inode); | 656 | struct bch_hash_info hash = bch2_hash_info_init(c, &dir->ei_inode); |
| 554 | 657 | ||
| 555 | struct bch_inode_info *inode; | 658 | struct bch_inode_info *inode; |
| 556 | bch2_trans_do(c, NULL, NULL, 0, | 659 | bch2_trans_do(c, |
| 557 | PTR_ERR_OR_ZERO(inode = bch2_lookup_trans(trans, inode_inum(dir), | 660 | PTR_ERR_OR_ZERO(inode = bch2_lookup_trans(trans, inode_inum(dir), |
| 558 | &hash, &dentry->d_name))); | 661 | &hash, &dentry->d_name))); |
| 559 | if (IS_ERR(inode)) | 662 | if (IS_ERR(inode)) |
| @@ -766,7 +869,7 @@ static int bch2_rename2(struct mnt_idmap *idmap, · 206 unmodified lines | |||
| 766 | ret = bch2_subvol_is_ro_trans(trans, src_dir->ei_inum.subvol) ?: | 869 | ret = bch2_subvol_is_ro_trans(trans, src_dir->ei_inum.subvol) ?: |
| 767 | bch2_subvol_is_ro_trans(trans, dst_dir->ei_inum.subvol); | 870 | bch2_subvol_is_ro_trans(trans, dst_dir->ei_inum.subvol); |
| 768 | if (ret) | 871 | if (ret) |
| 769 | goto err; | 872 | goto err_tx_restart; |
| 770 | 873 | ||
| 771 | if (inode_attr_changing(dst_dir, src_inode, Inode_opt_project)) { | 874 | if (inode_attr_changing(dst_dir, src_inode, Inode_opt_project)) { |
| 772 | ret = bch2_fs_quota_transfer(c, src_inode, | 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 | bch2_trans_iter_init(trans, &iter, BTREE_ID_extents, | 1266 | bch2_trans_iter_init(trans, &iter, BTREE_ID_extents, |
| 1164 | POS(ei->v.i_ino, start), 0); | 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 | enum btree_id data_btree = BTREE_ID_extents; | 1270 | enum btree_id data_btree = BTREE_ID_extents; |
| 1168 | 1271 | ||
| 1169 | bch2_trans_begin(trans); | 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 | u32 snapshot; | 1274 | u32 snapshot; |
| 1172 | ret = bch2_subvolume_get_snapshot(trans, ei->ei_inum.subvol, &snapshot); | 1275 | ret = bch2_subvolume_get_snapshot(trans, ei->ei_inum.subvol, &snapshot); |
| 1173 | if (ret) | 1276 | if (ret) |
| 1174 | goto err; | 1277 | continue; |
| 1175 | 1278 | ||
| 1176 | bch2_btree_iter_set_snapshot(&iter, snapshot); | 1279 | bch2_btree_iter_set_snapshot(&iter, snapshot); |
| 1177 | 1280 | ||
| 1178 | k = bch2_btree_iter_peek_upto(&iter, end); | 1281 | k = bch2_btree_iter_peek_upto(&iter, end); |
| 1179 | ret = bkey_err(k); | 1282 | ret = bkey_err(k); |
| 1180 | if (ret) | 1283 | if (ret) |
| 1181 | goto err; | 1284 | continue; |
| 1182 | 1285 | ||
| 1183 | if (!k.k) | 1286 | if (!k.k) |
| 1184 | break; | 1287 | break; |
| @@ -1198,7 +1301,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, · 13 unmodified lines | |||
| 1198 | ret = bch2_read_indirect_extent(trans, &data_btree, | 1301 | ret = bch2_read_indirect_extent(trans, &data_btree, |
| 1199 | &offset_into_extent, &cur); | 1302 | &offset_into_extent, &cur); |
| 1200 | if (ret) | 1303 | if (ret) |
| 1201 | break; | 1304 | continue; |
| 1202 | 1305 | ||
| 1203 | k = bkey_i_to_s_c(cur.k); | 1306 | k = bkey_i_to_s_c(cur.k); |
| 1204 | bch2_bkey_buf_realloc(&prev, c, k.k->u64s); | 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 | bch2_btree_iter_set_pos(&iter, | 1330 | bch2_btree_iter_set_pos(&iter, |
| 1228 | POS(iter.pos.inode, iter.pos.offset + sectors)); | 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 | bch2_trans_iter_exit(trans, &iter); | 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 | bch2_opts_to_text(&buf, c->opts, c, c->disk_sb.sb, | 2036 | bch2_opts_to_text(&buf, c->opts, c, c->disk_sb.sb, |
| 1938 | OPT_MOUNT, OPT_HIDDEN, OPT_SHOW_MOUNT_STYLE); | 2037 | OPT_MOUNT, OPT_HIDDEN, OPT_SHOW_MOUNT_STYLE); |
| 1939 | printbuf_nul_terminate(&buf); | 2038 | printbuf_nul_terminate(&buf); |
| 1940 | seq_puts(seq, buf.buf); | 2039 | seq_printf(seq, ",%s", buf.buf); |
| 1941 | 2040 | ||
| 1942 | int ret = buf.allocation_failure ? -ENOMEM : 0; | 2041 | int ret = buf.allocation_failure ? -ENOMEM : 0; |
| 1943 | printbuf_exit(&buf); | 2042 | printbuf_exit(&buf); |
| @@ -54,8 +54,6 @@ static inline subvol_inum inode_inum(struct bch_inode_info *inode) · 53 unmodified lines | |||
| 54 | return inode->ei_inum; | 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 | * Set if we've gotten a btree error for this inode, and thus the vfs inode and | 58 | * Set if we've gotten a btree error for this inode, and thus the vfs inode and |
| 61 | * btree inode may be inconsistent: | 59 | * btree inode may be inconsistent: |
| @@ -148,6 +146,8 @@ struct bch_inode_info * · 86 unmodified lines | |||
| 148 | __bch2_create(struct mnt_idmap *, struct bch_inode_info *, | 146 | __bch2_create(struct mnt_idmap *, struct bch_inode_info *, |
| 149 | struct dentry *, umode_t, dev_t, subvol_inum, unsigned); | 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 | int bch2_fs_quota_transfer(struct bch_fs *, | 151 | int bch2_fs_quota_transfer(struct bch_fs *, |
| 152 | struct bch_inode_info *, | 152 | struct bch_inode_info *, |
| 153 | struct bch_qid, | 153 | struct bch_qid, |
| @@ -198,10 +198,7 @@ int bch2_vfs_init(void); · 44 unmodified lines | |||
| 198 | 198 | ||
| 199 | #define bch2_inode_update_after_write(_trans, _inode, _inode_u, _fields) ({ do {} while (0); }) | 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) | 201 | static inline int bch2_inode_or_descendents_is_open(struct btree_trans *trans, struct bpos p) { return 0; } |
| 202 | { | ||
| 203 | return NULL; | ||
| 204 | } | ||
| 205 | 202 | ||
| 206 | static inline void bch2_evict_subvolume_inodes(struct bch_fs *c, | 203 | static inline void bch2_evict_subvolume_inodes(struct bch_fs *c, |
| 207 | snapshot_id_list *s) {} | 204 | snapshot_id_list *s) {} |
| @@ -28,8 +28,8 @@ static bool inode_points_to_dirent(struct bch_inode_unpacked *inode, · 27 unmodified lines | |||
| 28 | inode->bi_dir_offset == d.k->p.offset; | 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, | 31 | static int dirent_points_to_inode_nowarn(struct bkey_s_c_dirent d, |
| 32 | struct bch_inode_unpacked *inode) | 32 | struct bch_inode_unpacked *inode) |
| 33 | { | 33 | { |
| 34 | if (d.v->d_type == DT_SUBVOL | 34 | if (d.v->d_type == DT_SUBVOL |
| 35 | ? le32_to_cpu(d.v->d_child_subvol) == inode->bi_subvol | 35 | ? le32_to_cpu(d.v->d_child_subvol) == inode->bi_subvol |
| @@ -137,16 +137,15 @@ found: · 101 unmodified lines | |||
| 137 | return ret; | 137 | return ret; |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | static int lookup_inode(struct btree_trans *trans, u64 inode_nr, | 140 | static int lookup_inode(struct btree_trans *trans, u64 inode_nr, u32 snapshot, |
| 141 | struct bch_inode_unpacked *inode, | 141 | struct bch_inode_unpacked *inode) |
| 142 | u32 *snapshot) | ||
| 143 | { | 142 | { |
| 144 | struct btree_iter iter; | 143 | struct btree_iter iter; |
| 145 | struct bkey_s_c k; | 144 | struct bkey_s_c k; |
| 146 | int ret; | 145 | int ret; |
| 147 | 146 | ||
| 148 | k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes, | 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 | ret = bkey_err(k); | 149 | ret = bkey_err(k); |
| 151 | if (ret) | 150 | if (ret) |
| 152 | goto err; | 151 | goto err; |
| @@ -154,8 +153,6 @@ static int lookup_inode(struct btree_trans *trans, u64 inode_nr, · 1 unmodified line | |||
| 154 | ret = bkey_is_inode(k.k) | 153 | ret = bkey_is_inode(k.k) |
| 155 | ? bch2_inode_unpack(k, inode) | 154 | ? bch2_inode_unpack(k, inode) |
| 156 | : -BCH_ERR_ENOENT_inode; | 155 | : -BCH_ERR_ENOENT_inode; |
| 157 | if (!ret) | ||
| 158 | *snapshot = iter.pos.snapshot; | ||
| 159 | err: | 156 | err: |
| 160 | bch2_trans_iter_exit(trans, &iter); | 157 | bch2_trans_iter_exit(trans, &iter); |
| 161 | return ret; | 158 | return ret; |
| @@ -250,8 +247,7 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, · 88 unmodified lines | |||
| 250 | 247 | ||
| 251 | struct bch_inode_unpacked root_inode; | 248 | struct bch_inode_unpacked root_inode; |
| 252 | struct bch_hash_info root_hash_info; | 249 | struct bch_hash_info root_hash_info; |
| 253 | u32 root_inode_snapshot = snapshot; | 250 | ret = lookup_inode(trans, root_inum.inum, snapshot, &root_inode); |
| 254 | ret = lookup_inode(trans, root_inum.inum, &root_inode, &root_inode_snapshot); | ||
| 255 | bch_err_msg(c, ret, "looking up root inode %llu for subvol %u", | 251 | bch_err_msg(c, ret, "looking up root inode %llu for subvol %u", |
| 256 | root_inum.inum, le32_to_cpu(st.master_subvol)); | 252 | root_inum.inum, le32_to_cpu(st.master_subvol)); |
| 257 | if (ret) | 253 | if (ret) |
| @@ -277,17 +273,23 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, · 19 unmodified lines | |||
| 277 | * The bch2_check_dirents pass has already run, dangling dirents | 273 | * The bch2_check_dirents pass has already run, dangling dirents |
| 278 | * shouldn't exist here: | 274 | * shouldn't exist here: |
| 279 | */ | 275 | */ |
| 280 | ret = lookup_inode(trans, inum, lostfound, &snapshot); | 276 | ret = lookup_inode(trans, inum, snapshot, lostfound); |
| 281 | bch_err_msg(c, ret, "looking up lost+found %llu:%u in (root inode %llu, snapshot root %u)", | 277 | bch_err_msg(c, ret, "looking up lost+found %llu:%u in (root inode %llu, snapshot root %u)", |
| 282 | inum, snapshot, root_inum.inum, bch2_snapshot_root(c, snapshot)); | 278 | inum, snapshot, root_inum.inum, bch2_snapshot_root(c, snapshot)); |
| 283 | return ret; | 279 | return ret; |
| 284 | 280 | ||
| 285 | create_lostfound: | 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 | * XXX: we could have a nicer log message here if we had a nice way to | 288 | * XXX: we could have a nicer log message here if we had a nice way to |
| 288 | * walk backpointers to print a path | 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 | u64 now = bch2_current_time(c); | 294 | u64 now = bch2_current_time(c); |
| 293 | struct btree_iter lostfound_iter = { NULL }; | 295 | struct btree_iter lostfound_iter = { NULL }; |
| @@ -296,6 +298,7 @@ create_lostfound: · 2 unmodified lines | |||
| 296 | bch2_inode_init_early(c, lostfound); | 298 | bch2_inode_init_early(c, lostfound); |
| 297 | bch2_inode_init_late(lostfound, now, 0, 0, S_IFDIR|0700, 0, &root_inode); | 299 | bch2_inode_init_late(lostfound, now, 0, 0, S_IFDIR|0700, 0, &root_inode); |
| 298 | lostfound->bi_dir = root_inode.bi_inum; | 300 | lostfound->bi_dir = root_inode.bi_inum; |
| 301 | lostfound->bi_snapshot = le32_to_cpu(st.root_snapshot); | ||
| 299 | 302 | ||
| 300 | root_inode.bi_nlink++; | 303 | root_inode.bi_nlink++; |
| 301 | 304 | ||
| @@ -323,19 +326,54 @@ err: · 21 unmodified lines | |||
| 323 | return ret; | 326 | return ret; |
| 324 | } | 327 | } |
| 325 | 328 | ||
| 326 | static int reattach_inode(struct btree_trans *trans, | 329 | static inline bool inode_should_reattach(struct bch_inode_unpacked *inode) |
| 327 | struct bch_inode_unpacked *inode, | 330 | { |
| 328 | u32 inode_snapshot) | 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 | struct bch_fs *c = trans->c; | 371 | struct bch_fs *c = trans->c; |
| 331 | struct bch_hash_info dir_hash; | ||
| 332 | struct bch_inode_unpacked lostfound; | 372 | struct bch_inode_unpacked lostfound; |
| 333 | char name_buf[20]; | 373 | char name_buf[20]; |
| 334 | struct qstr name; | ||
| 335 | u64 dir_offset = 0; | ||
| 336 | u32 dirent_snapshot = inode_snapshot; | ||
| 337 | int ret; | 374 | int ret; |
| 338 | 375 | ||
| 376 | u32 dirent_snapshot = inode->bi_snapshot; | ||
| 339 | if (inode->bi_subvol) { | 377 | if (inode->bi_subvol) { |
| 340 | inode->bi_parent_subvol = BCACHEFS_ROOT_SUBVOL; | 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 | if (ret) | 392 | if (ret) |
| 355 | return ret; | 393 | return ret; |
| 356 | 394 | ||
| 357 | if (S_ISDIR(inode->bi_mode)) { | 395 | lostfound.bi_nlink += S_ISDIR(inode->bi_mode); |
| 358 | lostfound.bi_nlink++; | ||
| 359 | 396 | ||
| 360 | ret = __bch2_fsck_write_inode(trans, &lostfound, U32_MAX); | 397 | /* ensure lost+found inode is also present in inode snapshot */ |
| 361 | if (ret) | 398 | if (!inode->bi_subvol) { |
| 362 | return ret; | 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 | ret = bch2_dirent_create_snapshot(trans, | 412 | ret = bch2_dirent_create_snapshot(trans, |
| 370 | inode->bi_parent_subvol, lostfound.bi_inum, | 413 | inode->bi_parent_subvol, lostfound.bi_inum, |
| @@ -373,17 +416,70 @@ static int reattach_inode(struct btree_trans *trans, · 2 unmodified lines | |||
| 373 | inode_d_type(inode), | 416 | inode_d_type(inode), |
| 374 | &name, | 417 | &name, |
| 375 | inode->bi_subvol ?: inode->bi_inum, | 418 | inode->bi_subvol ?: inode->bi_inum, |
| 376 | &dir_offset, | 419 | &inode->bi_dir_offset, |
| 377 | STR_HASH_must_create); | 420 | STR_HASH_must_create); |
| 378 | if (ret) { | 421 | if (ret) { |
| 379 | bch_err_msg(c, ret, "error creating dirent"); | 422 | bch_err_msg(c, ret, "error creating dirent"); |
| 380 | return ret; | 423 | return ret; |
| 381 | } | 424 | } |
| 382 | 425 | ||
| 383 | inode->bi_dir = lostfound.bi_inum; | 426 | ret = __bch2_fsck_write_inode(trans, inode); |
| 384 | inode->bi_dir_offset = dir_offset; | 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 | static int remove_backpointer(struct btree_trans *trans, | 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 | if (ret) | 518 | if (ret) |
| 423 | return ret; | 519 | return ret; |
| 424 | 520 | ||
| 425 | ret = reattach_inode(trans, &inode, le32_to_cpu(s.v->snapshot)); | 521 | ret = reattach_inode(trans, &inode); |
| 426 | bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum); | 522 | bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum); |
| 427 | return ret; | 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 | bch2_inode_init_late(&new_inode, bch2_current_time(c), 0, 0, i_mode|0600, 0, NULL); | 636 | bch2_inode_init_late(&new_inode, bch2_current_time(c), 0, 0, i_mode|0600, 0, NULL); |
| 541 | new_inode.bi_size = i_size; | 637 | new_inode.bi_size = i_size; |
| 542 | new_inode.bi_inum = inum; | 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 | struct snapshots_seen { | 644 | struct snapshots_seen { |
| @@ -832,35 +929,138 @@ static int get_visible_inodes(struct btree_trans *trans, · 284 unmodified lines | |||
| 832 | return ret; | 929 | return ret; |
| 833 | } | 930 | } |
| 834 | 931 | ||
| 835 | static int hash_redo_key(struct btree_trans *trans, | 932 | static int dirent_has_target(struct btree_trans *trans, struct bkey_s_c_dirent d) |
| 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) | ||
| 839 | { | 933 | { |
| 840 | struct bkey_i *delete; | 934 | if (d.v->d_type == DT_SUBVOL) { |
| 841 | struct bkey_i *tmp; | 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)); | 955 | /* |
| 844 | if (IS_ERR(delete)) | 956 | * Prefer to delete the first one, since that will be the one at the wrong |
| 845 | return PTR_ERR(delete); | 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); | 970 | switch (desc.btree_id) { |
| 848 | if (IS_ERR(tmp)) | 971 | case BTREE_ID_dirents: { |
| 849 | return PTR_ERR(tmp); | 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); | 978 | ret = dirent_has_target(trans, bkey_s_c_to_dirent(k2)); |
| 852 | delete->k.p = k_iter->pos; | 979 | if (ret < 0) |
| 853 | return bch2_btree_iter_traverse(k_iter) ?: | 980 | return ret; |
| 854 | bch2_trans_update(trans, k_iter, delete, 0) ?: | 981 | if (!ret) |
| 855 | bch2_hash_set_in_snapshot(trans, desc, hash_info, | 982 | return 1; |
| 856 | (subvol_inum) { 0, k.k->p.inode }, | 983 | return 2; |
| 857 | k.k->p.snapshot, tmp, | 984 | } |
| 858 | STR_HASH_must_create| | 985 | default: |
| 859 | BTREE_UPDATE_internal_snapshot_node) ?: | 986 | return 0; |
| 860 | bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc); | 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 | static int hash_check_key(struct btree_trans *trans, | 1062 | static int hash_check_key(struct btree_trans *trans, |
| 1063 | struct snapshots_seen *s, | ||
| 864 | const struct bch_hash_desc desc, | 1064 | const struct bch_hash_desc desc, |
| 865 | struct bch_hash_info *hash_info, | 1065 | struct bch_hash_info *hash_info, |
| 866 | struct btree_iter *k_iter, struct bkey_s_c hash_k) | 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 | if (bkey_eq(k.k->p, hash_k.k->p)) | 1089 | if (bkey_eq(k.k->p, hash_k.k->p)) |
| 890 | break; | 1090 | break; |
| 891 | 1091 | ||
| 892 | if (fsck_err_on(k.k->type == desc.key_type && | 1092 | if (k.k->type == desc.key_type && |
| 893 | !desc.cmp_bkey(k, hash_k), | 1093 | !desc.cmp_bkey(k, hash_k)) |
| 894 | trans, hash_table_key_duplicate, | 1094 | goto duplicate_entries; |
| 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 | } | ||
| 902 | 1095 | ||
| 903 | if (bkey_deleted(k.k)) { | 1096 | if (bkey_deleted(k.k)) { |
| 904 | bch2_trans_iter_exit(trans, &iter); | 1097 | bch2_trans_iter_exit(trans, &iter); |
| @@ -911,18 +1104,66 @@ out: · 6 unmodified lines | |||
| 911 | return ret; | 1104 | return ret; |
| 912 | bad_hash: | 1105 | bad_hash: |
| 913 | if (fsck_err(trans, hash_table_key_wrong_offset, | 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 | bch2_btree_id_str(desc.btree_id), hash_k.k->p.inode, hash_k.k->p.offset, hash, | 1108 | bch2_btree_id_str(desc.btree_id), hash_k.k->p.inode, hash_k.k->p.offset, hash, |
| 916 | (printbuf_reset(&buf), | 1109 | (printbuf_reset(&buf), |
| 917 | bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf))) { | 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); | 1111 | struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, hash_k); |
| 919 | bch_err_fn(c, ret); | 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 | if (ret) | 1122 | if (ret) |
| 921 | return ret; | 1123 | goto out; |
| 922 | ret = -BCH_ERR_transaction_restart_nested; | 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 | fsck_err: | 1134 | fsck_err: |
| 925 | goto out; | 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 | static struct bkey_s_c_dirent dirent_get_by_pos(struct btree_trans *trans, | 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 | inode->bi_dir = 0; | 1230 | inode->bi_dir = 0; |
| 990 | inode->bi_dir_offset = 0; | 1231 | inode->bi_dir_offset = 0; |
| 991 | inode->bi_flags &= ~BCH_INODE_backptr_untrusted; | ||
| 992 | *write_inode = true; | 1232 | *write_inode = true; |
| 993 | } | 1233 | } |
| 994 | 1234 | ||
| @@ -1000,30 +1240,40 @@ fsck_err: · 5 unmodified lines | |||
| 1000 | return ret; | 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 = { | 1247 | struct btree_iter iter; |
| 1006 | .subvol = snapshot_t(c, p.snapshot)->subvol, | 1248 | struct bkey_s_c k; |
| 1007 | .inum = p.offset, | 1249 | int ret = 0; |
| 1008 | }; | ||
| 1009 | 1250 | ||
| 1010 | /* snapshot tree corruption, can't safely delete */ | 1251 | for_each_btree_key_reverse_norestart(trans, iter, BTREE_ID_inodes, |
| 1011 | if (!inum.subvol) { | 1252 | SPOS(0, inum, U32_MAX), |
| 1012 | bch_warn_ratelimited(c, "%s(): snapshot %u has no subvol, unlinked but can't safely delete", __func__, p.snapshot); | 1253 | BTREE_ITER_all_snapshots, k, ret) { |
| 1013 | return true; | 1254 | if (k.k->p.offset != inum) |
| 1255 | break; | ||
| 1256 | if (bkey_is_inode(k.k)) | ||
| 1257 | goto found_root; | ||
| 1014 | } | 1258 | } |
| 1015 | 1259 | if (ret) | |
| 1016 | return __bch2_inode_hash_find(c, inum) != NULL; | 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 | static int check_inode(struct btree_trans *trans, | 1269 | static int check_inode(struct btree_trans *trans, |
| 1020 | struct btree_iter *iter, | 1270 | struct btree_iter *iter, |
| 1021 | struct bkey_s_c k, | 1271 | struct bkey_s_c k, |
| 1022 | struct bch_inode_unpacked *prev, | 1272 | struct bch_inode_unpacked *snapshot_root, |
| 1023 | struct snapshots_seen *s, | 1273 | struct snapshots_seen *s) |
| 1024 | bool full) | ||
| 1025 | { | 1274 | { |
| 1026 | struct bch_fs *c = trans->c; | 1275 | struct bch_fs *c = trans->c; |
| 1276 | struct printbuf buf = PRINTBUF; | ||
| 1027 | struct bch_inode_unpacked u; | 1277 | struct bch_inode_unpacked u; |
| 1028 | bool do_update = false; | 1278 | bool do_update = false; |
| 1029 | int ret; | 1279 | int ret; |
| @@ -1043,45 +1293,75 @@ static int check_inode(struct btree_trans *trans, · 13 unmodified lines | |||
| 1043 | 1293 | ||
| 1044 | BUG_ON(bch2_inode_unpack(k, &u)); | 1294 | BUG_ON(bch2_inode_unpack(k, &u)); |
| 1045 | 1295 | ||
| 1046 | if (!full && | 1296 | if (snapshot_root->bi_inum != u.bi_inum) { |
| 1047 | !(u.bi_flags & (BCH_INODE_i_size_dirty| | 1297 | ret = get_snapshot_root_inode(trans, snapshot_root, u.bi_inum); |
| 1048 | BCH_INODE_i_sectors_dirty| | 1298 | if (ret) |
| 1049 | BCH_INODE_unlinked))) | 1299 | goto err; |
| 1050 | return 0; | 1300 | } |
| 1051 | |||
| 1052 | if (prev->bi_inum != u.bi_inum) | ||
| 1053 | *prev = u; | ||
| 1054 | 1301 | ||
| 1055 | if (fsck_err_on(prev->bi_hash_seed != u.bi_hash_seed || | 1302 | if (fsck_err_on(u.bi_hash_seed != snapshot_root->bi_hash_seed || |
| 1056 | inode_d_type(prev) != inode_d_type(&u), | 1303 | INODE_STR_HASH(&u) != INODE_STR_HASH(snapshot_root), |
| 1057 | trans, inode_snapshot_mismatch, | 1304 | trans, inode_snapshot_mismatch, |
| 1058 | "inodes in different snapshots don't match")) { | 1305 | "inodes in different snapshots don't match")) { |
| 1059 | bch_err(c, "repair not implemented yet"); | 1306 | u.bi_hash_seed = snapshot_root->bi_hash_seed; |
| 1060 | return -BCH_ERR_fsck_repair_unimplemented; | 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)) && | 1311 | if (u.bi_dir || u.bi_dir_offset) { |
| 1064 | bch2_key_has_snapshot_overwrites(trans, BTREE_ID_inodes, k.k->p)) { | 1312 | ret = check_inode_dirent_inode(trans, &u, &do_update); |
| 1065 | struct bpos new_min_pos; | ||
| 1066 | |||
| 1067 | ret = bch2_propagate_key_to_snapshot_leaves(trans, iter->btree_id, k, &new_min_pos); | ||
| 1068 | if (ret) | 1313 | if (ret) |
| 1069 | goto err; | 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"); | 1330 | ret = bch2_empty_dir_snapshot(trans, k.k->p.offset, 0, k.k->p.snapshot); |
| 1076 | if (ret) | 1331 | if (ret && ret != -BCH_ERR_ENOTEMPTY_dir_not_empty) |
| 1077 | return ret; | 1332 | goto err; |
| 1078 | 1333 | ||
| 1079 | if (!bpos_eq(new_min_pos, POS_MIN)) | 1334 | fsck_err_on(ret, trans, inode_dir_unlinked_but_not_empty, |
| 1080 | bch2_btree_iter_set_pos(iter, bpos_predecessor(new_min_pos)); | 1335 | "dir unlinked but not empty\n%s", |
| 1081 | return 0; | 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 | if (!test_bit(BCH_FS_started, &c->flags)) { | 1365 | if (!test_bit(BCH_FS_started, &c->flags)) { |
| 1086 | /* | 1366 | /* |
| 1087 | * If we're not in online fsck, don't delete unlinked | 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 | ret = check_inode_deleted_list(trans, k.k->p); | 1376 | ret = check_inode_deleted_list(trans, k.k->p); |
| 1097 | if (ret < 0) | 1377 | if (ret < 0) |
| 1098 | return ret; | 1378 | goto err_noprint; |
| 1099 | 1379 | ||
| 1100 | fsck_err_on(!ret, | 1380 | fsck_err_on(!ret, |
| 1101 | trans, unlinked_inode_not_on_deleted_list, | 1381 | trans, unlinked_inode_not_on_deleted_list, |
| @@ -1106,83 +1386,22 @@ static int check_inode(struct btree_trans *trans, · 4 unmodified lines | |||
| 1106 | if (ret) | 1386 | if (ret) |
| 1107 | goto err; | 1387 | goto err; |
| 1108 | } else { | 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 | trans, inode_unlinked_and_not_open, | 1394 | trans, inode_unlinked_and_not_open, |
| 1111 | "inode %llu%u unlinked and not open", | 1395 | "inode %llu%u unlinked and not open", |
| 1112 | u.bi_inum, u.bi_snapshot)) { | 1396 | u.bi_inum, u.bi_snapshot)) { |
| 1113 | ret = bch2_inode_rm_snapshot(trans, u.bi_inum, iter->pos.snapshot); | 1397 | ret = bch2_inode_rm_snapshot(trans, u.bi_inum, iter->pos.snapshot); |
| 1114 | bch_err_msg(c, ret, "in fsck deleting inode"); | 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 | if (fsck_err_on(u.bi_parent_subvol && | 1405 | if (fsck_err_on(u.bi_parent_subvol && |
| 1187 | (u.bi_subvol == 0 || | 1406 | (u.bi_subvol == 0 || |
| 1188 | u.bi_subvol == BCACHEFS_ROOT_SUBVOL), | 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 | do_update: | 1444 | do_update: |
| 1226 | if (do_update) { | 1445 | if (do_update) { |
| 1227 | ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot); | 1446 | ret = __bch2_fsck_write_inode(trans, &u); |
| 1228 | bch_err_msg(c, ret, "in fsck updating inode"); | 1447 | bch_err_msg(c, ret, "in fsck updating inode"); |
| 1229 | if (ret) | 1448 | if (ret) |
| 1230 | return ret; | 1449 | goto err_noprint; |
| 1231 | } | 1450 | } |
| 1232 | err: | 1451 | err: |
| 1233 | fsck_err: | 1452 | fsck_err: |
| 1234 | bch_err_fn(c, ret); | 1453 | bch_err_fn(c, ret); |
| 1454 | err_noprint: | ||
| 1455 | printbuf_exit(&buf); | ||
| 1235 | return ret; | 1456 | return ret; |
| 1236 | } | 1457 | } |
| 1237 | 1458 | ||
| 1238 | int bch2_check_inodes(struct bch_fs *c) | 1459 | int bch2_check_inodes(struct bch_fs *c) |
| 1239 | { | 1460 | { |
| 1240 | bool full = c->opts.fsck; | 1461 | struct bch_inode_unpacked snapshot_root = {}; |
| 1241 | struct bch_inode_unpacked prev = { 0 }; | ||
| 1242 | struct snapshots_seen s; | 1462 | struct snapshots_seen s; |
| 1243 | 1463 | ||
| 1244 | snapshots_seen_init(&s); | 1464 | snapshots_seen_init(&s); |
| @@ -1248,13 +1468,104 @@ int bch2_check_inodes(struct bch_fs *c) · 3 unmodified lines | |||
| 1248 | POS_MIN, | 1468 | POS_MIN, |
| 1249 | BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, | 1469 | BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, |
| 1250 | NULL, NULL, BCH_TRANS_COMMIT_no_enospc, | 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 | snapshots_seen_exit(&s); | 1473 | snapshots_seen_exit(&s); |
| 1254 | bch_err_fn(c, ret); | 1474 | bch_err_fn(c, ret); |
| 1255 | return ret; | 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 | static inline bool btree_matches_i_mode(enum btree_id btree, unsigned mode) | 1569 | static inline bool btree_matches_i_mode(enum btree_id btree, unsigned mode) |
| 1259 | { | 1570 | { |
| 1260 | switch (btree) { | 1571 | switch (btree) { |
| @@ -1347,7 +1658,7 @@ static int check_i_sectors_notnested(struct btree_trans *trans, struct inode_wal · 86 unmodified lines | |||
| 1347 | w->last_pos.inode, i->snapshot, | 1658 | w->last_pos.inode, i->snapshot, |
| 1348 | i->inode.bi_sectors, i->count)) { | 1659 | i->inode.bi_sectors, i->count)) { |
| 1349 | i->inode.bi_sectors = i->count; | 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 | if (ret) | 1662 | if (ret) |
| 1352 | break; | 1663 | break; |
| 1353 | } | 1664 | } |
| @@ -1657,8 +1968,7 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter, · 303 unmodified lines | |||
| 1657 | !key_visible_in_snapshot(c, s, i->snapshot, k.k->p.snapshot)) | 1968 | !key_visible_in_snapshot(c, s, i->snapshot, k.k->p.snapshot)) |
| 1658 | continue; | 1969 | continue; |
| 1659 | 1970 | ||
| 1660 | if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_i_size_dirty) && | 1971 | if (fsck_err_on(k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 && |
| 1661 | k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 && | ||
| 1662 | !bkey_extent_is_reservation(k), | 1972 | !bkey_extent_is_reservation(k), |
| 1663 | trans, extent_past_end_of_inode, | 1973 | trans, extent_past_end_of_inode, |
| 1664 | "extent type past end of inode %llu:%u, i_size %llu\n %s", | 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 | "directory %llu:%u with wrong i_nlink: got %u, should be %llu", | 2099 | "directory %llu:%u with wrong i_nlink: got %u, should be %llu", |
| 1790 | w->last_pos.inode, i->snapshot, i->inode.bi_nlink, i->count)) { | 2100 | w->last_pos.inode, i->snapshot, i->inode.bi_nlink, i->count)) { |
| 1791 | i->inode.bi_nlink = i->count; | 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 | if (ret) | 2103 | if (ret) |
| 1794 | break; | 2104 | break; |
| 1795 | } | 2105 | } |
| @@ -1810,8 +2120,7 @@ noinline_for_stack · 14 unmodified lines | |||
| 1810 | static int check_dirent_inode_dirent(struct btree_trans *trans, | 2120 | static int check_dirent_inode_dirent(struct btree_trans *trans, |
| 1811 | struct btree_iter *iter, | 2121 | struct btree_iter *iter, |
| 1812 | struct bkey_s_c_dirent d, | 2122 | struct bkey_s_c_dirent d, |
| 1813 | struct bch_inode_unpacked *target, | 2123 | struct bch_inode_unpacked *target) |
| 1814 | u32 target_snapshot) | ||
| 1815 | { | 2124 | { |
| 1816 | struct bch_fs *c = trans->c; | 2125 | struct bch_fs *c = trans->c; |
| 1817 | struct printbuf buf = PRINTBUF; | 2126 | struct printbuf buf = PRINTBUF; |
| @@ -1821,6 +2130,32 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, · 3 unmodified lines | |||
| 1821 | if (inode_points_to_dirent(target, d)) | 2130 | if (inode_points_to_dirent(target, d)) |
| 1822 | return 0; | 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 | if (bch2_inode_should_have_bp(target) && | 2159 | if (bch2_inode_should_have_bp(target) && |
| 1825 | !fsck_err(trans, inode_wrong_backpointer, | 2160 | !fsck_err(trans, inode_wrong_backpointer, |
| 1826 | "dirent points to inode that does not point back:\n %s", | 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 | buf.buf))) | 2165 | buf.buf))) |
| 1831 | goto err; | 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 | struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter, | 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 | ret = bkey_err(bp_dirent); | 2170 | ret = bkey_err(bp_dirent); |
| 1843 | if (ret && !bch2_err_matches(ret, ENOENT)) | 2171 | if (ret && !bch2_err_matches(ret, ENOENT)) |
| 1844 | goto err; | 2172 | goto err; |
| @@ -1851,14 +2179,14 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, · 6 unmodified lines | |||
| 1851 | "inode %llu:%u has wrong backpointer:\n" | 2179 | "inode %llu:%u has wrong backpointer:\n" |
| 1852 | "got %llu:%llu\n" | 2180 | "got %llu:%llu\n" |
| 1853 | "should be %llu:%llu", | 2181 | "should be %llu:%llu", |
| 1854 | target->bi_inum, target_snapshot, | 2182 | target->bi_inum, target->bi_snapshot, |
| 1855 | target->bi_dir, | 2183 | target->bi_dir, |
| 1856 | target->bi_dir_offset, | 2184 | target->bi_dir_offset, |
| 1857 | d.k->p.inode, | 2185 | d.k->p.inode, |
| 1858 | d.k->p.offset)) { | 2186 | d.k->p.offset)) { |
| 1859 | target->bi_dir = d.k->p.inode; | 2187 | target->bi_dir = d.k->p.inode; |
| 1860 | target->bi_dir_offset = d.k->p.offset; | 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 | goto out; | 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 | trans, inode_dir_multiple_links, | 2201 | trans, inode_dir_multiple_links, |
| 1874 | "%s %llu:%u with multiple links\n%s", | 2202 | "%s %llu:%u with multiple links\n%s", |
| 1875 | S_ISDIR(target->bi_mode) ? "directory" : "subvolume", | 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 | ret = __remove_dirent(trans, d.k->p); | 2205 | ret = __remove_dirent(trans, d.k->p); |
| 1878 | goto out; | 2206 | goto out; |
| 1879 | } | 2207 | } |
| @@ -1886,10 +2214,10 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, · 6 unmodified lines | |||
| 1886 | if (fsck_err_on(backpointer_exists && !target->bi_nlink, | 2214 | if (fsck_err_on(backpointer_exists && !target->bi_nlink, |
| 1887 | trans, inode_multiple_links_but_nlink_0, | 2215 | trans, inode_multiple_links_but_nlink_0, |
| 1888 | "inode %llu:%u type %s has multiple links but i_nlink 0\n%s", | 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 | target->bi_nlink++; | 2218 | target->bi_nlink++; |
| 1891 | target->bi_flags &= ~BCH_INODE_unlinked; | 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 | if (ret) | 2221 | if (ret) |
| 1894 | goto err; | 2222 | goto err; |
| 1895 | } | 2223 | } |
| @@ -1906,15 +2234,14 @@ noinline_for_stack · 10 unmodified lines | |||
| 1906 | static int check_dirent_target(struct btree_trans *trans, | 2234 | static int check_dirent_target(struct btree_trans *trans, |
| 1907 | struct btree_iter *iter, | 2235 | struct btree_iter *iter, |
| 1908 | struct bkey_s_c_dirent d, | 2236 | struct bkey_s_c_dirent d, |
| 1909 | struct bch_inode_unpacked *target, | 2237 | struct bch_inode_unpacked *target) |
| 1910 | u32 target_snapshot) | ||
| 1911 | { | 2238 | { |
| 1912 | struct bch_fs *c = trans->c; | 2239 | struct bch_fs *c = trans->c; |
| 1913 | struct bkey_i_dirent *n; | 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.