We need the USB fixes in here as well.
Unified · Split
| @@ -251,11 +251,11 @@ selectively from different subsystems. · 250 unmodified lines | |||
| 251 | .. code-block:: c | 251 | .. code-block:: c |
| 252 | 252 | ||
| 253 | struct kcov_remote_arg { | 253 | struct kcov_remote_arg { |
| 254 | unsigned trace_mode; | 254 | __u32 trace_mode; |
| 255 | unsigned area_size; | 255 | __u32 area_size; |
| 256 | unsigned num_handles; | 256 | __u32 num_handles; |
| 257 | uint64_t common_handle; | 257 | __aligned_u64 common_handle; |
| 258 | uint64_t handles[0]; | 258 | __aligned_u64 handles[0]; |
| 259 | }; | 259 | }; |
| 260 | 260 | ||
| 261 | #define KCOV_INIT_TRACE _IOR('c', 1, unsigned long) | 261 | #define KCOV_INIT_TRACE _IOR('c', 1, unsigned long) |
| @@ -24,19 +24,16 @@ The wrapper can be run with: · 23 unmodified lines | |||
| 24 | For more information on this wrapper (also called kunit_tool) checkout the | 24 | For more information on this wrapper (also called kunit_tool) checkout the |
| 25 | :doc:`kunit-tool` page. | 25 | :doc:`kunit-tool` page. |
| 26 | 26 | ||
| 27 | Creating a kunitconfig | 27 | Creating a .kunitconfig |
| 28 | ====================== | 28 | ======================= |
| 29 | The Python script is a thin wrapper around Kbuild. As such, it needs to be | 29 | The Python script is a thin wrapper around Kbuild. As such, it needs to be |
| 30 | configured with a ``kunitconfig`` file. This file essentially contains the | 30 | configured with a ``.kunitconfig`` file. This file essentially contains the |
| 31 | regular Kernel config, with the specific test targets as well. | 31 | regular Kernel config, with the specific test targets as well. |
| 32 | 32 | ||
| 33 | .. code-block:: bash | 33 | .. code-block:: bash |
| 34 | 34 | ||
| 35 | git clone -b master https://kunit.googlesource.com/kunitconfig $PATH_TO_KUNITCONFIG_REPO | ||
| 36 | cd $PATH_TO_LINUX_REPO | 35 | cd $PATH_TO_LINUX_REPO |
| 37 | ln -s $PATH_TO_KUNIT_CONFIG_REPO/kunitconfig kunitconfig | 36 | cp arch/um/configs/kunit_defconfig .kunitconfig |
| 38 | |||
| 39 | You may want to add kunitconfig to your local gitignore. | ||
| 40 | 37 | ||
| 41 | Verifying KUnit Works | 38 | Verifying KUnit Works |
| 42 | --------------------- | 39 | --------------------- |
| @@ -151,7 +148,7 @@ and the following to ``drivers/misc/Makefile``: · 108 unmodified lines | |||
| 151 | 148 | ||
| 152 | obj-$(CONFIG_MISC_EXAMPLE_TEST) += example-test.o | 149 | obj-$(CONFIG_MISC_EXAMPLE_TEST) += example-test.o |
| 153 | 150 | ||
| 154 | Now add it to your ``kunitconfig``: | 151 | Now add it to your ``.kunitconfig``: |
| 155 | 152 | ||
| 156 | .. code-block:: none | 153 | .. code-block:: none |
| 157 | 154 | ||
| @@ -18,8 +18,10 @@ Optional properties: · 17 unmodified lines | |||
| 18 | - dma-names: should contain "tx" and "rx". | 18 | - dma-names: should contain "tx" and "rx". |
| 19 | - atmel,fifo-size: maximum number of data the RX and TX FIFOs can store for FIFO | 19 | - atmel,fifo-size: maximum number of data the RX and TX FIFOs can store for FIFO |
| 20 | capable I2C controllers. | 20 | capable I2C controllers. |
| 21 | - i2c-sda-hold-time-ns: TWD hold time, only available for "atmel,sama5d4-i2c" | 21 | - i2c-sda-hold-time-ns: TWD hold time, only available for: |
| 22 | and "atmel,sama5d2-i2c". | 22 | "atmel,sama5d4-i2c", |
| 23 | "atmel,sama5d2-i2c", | ||
| 24 | "microchip,sam9x60-i2c". | ||
| 23 | - Child nodes conforming to i2c bus binding | 25 | - Child nodes conforming to i2c bus binding |
| 24 | 26 | ||
| 25 | Examples : | 27 | Examples : |
| @@ -111,7 +111,7 @@ patternProperties: · 110 unmodified lines | |||
| 111 | spi-rx-bus-width: | 111 | spi-rx-bus-width: |
| 112 | allOf: | 112 | allOf: |
| 113 | - $ref: /schemas/types.yaml#/definitions/uint32 | 113 | - $ref: /schemas/types.yaml#/definitions/uint32 |
| 114 | - enum: [ 1, 2, 4 ] | 114 | - enum: [ 1, 2, 4, 8 ] |
| 115 | - default: 1 | 115 | - default: 1 |
| 116 | description: | 116 | description: |
| 117 | Bus width to the SPI bus used for MISO. | 117 | Bus width to the SPI bus used for MISO. |
| @@ -123,7 +123,7 @@ patternProperties: · 5 unmodified lines | |||
| 123 | spi-tx-bus-width: | 123 | spi-tx-bus-width: |
| 124 | allOf: | 124 | allOf: |
| 125 | - $ref: /schemas/types.yaml#/definitions/uint32 | 125 | - $ref: /schemas/types.yaml#/definitions/uint32 |
| 126 | - enum: [ 1, 2, 4 ] | 126 | - enum: [ 1, 2, 4, 8 ] |
| 127 | - default: 1 | 127 | - default: 1 |
| 128 | description: | 128 | description: |
| 129 | Bus width to the SPI bus used for MOSI. | 129 | Bus width to the SPI bus used for MOSI. |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | |||
| 23 | | openrisc: | TODO | | 23 | | openrisc: | TODO | |
| 24 | | parisc: | TODO | | 24 | | parisc: | TODO | |
| 25 | | powerpc: | ok | | 25 | | powerpc: | ok | |
| 26 | | riscv: | TODO | | 26 | | riscv: | ok | |
| 27 | | s390: | ok | | 27 | | s390: | ok | |
| 28 | | sh: | ok | | 28 | | sh: | ok | |
| 29 | | sparc: | TODO | | 29 | | sparc: | TODO | |
| @@ -230,12 +230,6 @@ simultaneously on two ports. The driver checks the consistency of the schedules · 229 unmodified lines | |||
| 230 | against this restriction and errors out when appropriate. Schedule analysis is | 230 | against this restriction and errors out when appropriate. Schedule analysis is |
| 231 | needed to avoid this, which is outside the scope of the document. | 231 | needed to avoid this, which is outside the scope of the document. |
| 232 | 232 | ||
| 233 | At the moment, the time-aware scheduler can only be triggered based on a | ||
| 234 | standalone clock and not based on PTP time. This means the base-time argument | ||
| 235 | from tc-taprio is ignored and the schedule starts right away. It also means it | ||
| 236 | is more difficult to phase-align the scheduler with the other devices in the | ||
| 237 | network. | ||
| 238 | |||
| 239 | Device Tree bindings and board design | 233 | Device Tree bindings and board design |
| 240 | ===================================== | 234 | ===================================== |
| 241 | 235 | ||
| @@ -603,7 +603,7 @@ tcp_synack_retries - INTEGER · 602 unmodified lines | |||
| 603 | with the current initial RTO of 1second. With this the final timeout | 603 | with the current initial RTO of 1second. With this the final timeout |
| 604 | for a passive TCP connection will happen after 63seconds. | 604 | for a passive TCP connection will happen after 63seconds. |
| 605 | 605 | ||
| 606 | tcp_syncookies - BOOLEAN | 606 | tcp_syncookies - INTEGER |
| 607 | Only valid when the kernel was compiled with CONFIG_SYN_COOKIES | 607 | Only valid when the kernel was compiled with CONFIG_SYN_COOKIES |
| 608 | Send out syncookies when the syn backlog queue of a socket | 608 | Send out syncookies when the syn backlog queue of a socket |
| 609 | overflows. This is to prevent against the common 'SYN flood attack' | 609 | overflows. This is to prevent against the common 'SYN flood attack' |
| @@ -34,8 +34,8 @@ the names, the ``net`` tree is for fixes to existing code already in the · 33 unmodified lines | |||
| 34 | mainline tree from Linus, and ``net-next`` is where the new code goes | 34 | mainline tree from Linus, and ``net-next`` is where the new code goes |
| 35 | for the future release. You can find the trees here: | 35 | for the future release. You can find the trees here: |
| 36 | 36 | ||
| 37 | - https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git | 37 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 38 | - https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git | 38 | - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git |
| 39 | 39 | ||
| 40 | Q: How often do changes from these trees make it to the mainline Linus tree? | 40 | Q: How often do changes from these trees make it to the mainline Linus tree? |
| 41 | ---------------------------------------------------------------------------- | 41 | ---------------------------------------------------------------------------- |
| @@ -60,6 +60,7 @@ lack of a better place. · 59 unmodified lines | |||
| 60 | volatile-considered-harmful | 60 | volatile-considered-harmful |
| 61 | botching-up-ioctls | 61 | botching-up-ioctls |
| 62 | clang-format | 62 | clang-format |
| 63 | ../riscv/patch-acceptance | ||
| 63 | 64 | ||
| 64 | .. only:: subproject and html | 65 | .. only:: subproject and html |
| 65 | 66 | ||
| @@ -7,6 +7,7 @@ RISC-V architecture · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | boot-image-header | 8 | boot-image-header |
| 9 | pmu | 9 | pmu |
| 10 | patch-acceptance | ||
| 10 | 11 | ||
| 11 | .. only:: subproject and html | 12 | .. only:: subproject and html |
| 12 | 13 | ||
| @@ -0,0 +1,35 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | arch/riscv maintenance guidelines for developers | ||
| 4 | ================================================ | ||
| 5 | |||
| 6 | Overview | ||
| 7 | -------- | ||
| 8 | The RISC-V instruction set architecture is developed in the open: | ||
| 9 | in-progress drafts are available for all to review and to experiment | ||
| 10 | with implementations. New module or extension drafts can change | ||
| 11 | during the development process - sometimes in ways that are | ||
| 12 | incompatible with previous drafts. This flexibility can present a | ||
| 13 | challenge for RISC-V Linux maintenance. Linux maintainers disapprove | ||
| 14 | of churn, and the Linux development process prefers well-reviewed and | ||
| 15 | tested code over experimental code. We wish to extend these same | ||
| 16 | principles to the RISC-V-related code that will be accepted for | ||
| 17 | inclusion in the kernel. | ||
| 18 | |||
| 19 | Submit Checklist Addendum | ||
| 20 | ------------------------- | ||
| 21 | We'll only accept patches for new modules or extensions if the | ||
| 22 | specifications for those modules or extensions are listed as being | ||
| 23 | "Frozen" or "Ratified" by the RISC-V Foundation. (Developers may, of | ||
| 24 | course, maintain their own Linux kernel trees that contain code for | ||
| 25 | any draft extensions that they wish.) | ||
| 26 | |||
| 27 | Additionally, the RISC-V specification allows implementors to create | ||
| 28 | their own custom extensions. These custom extensions aren't required | ||
| 29 | to go through any review or ratification process by the RISC-V | ||
| 30 | Foundation. To avoid the maintenance complexity and potential | ||
| 31 | performance impact of adding kernel code for implementor-specific | ||
| 32 | RISC-V extensions, we'll only to accept patches for extensions that | ||
| 33 | have been officially frozen or ratified by the RISC-V Foundation. | ||
| 34 | (Implementors, may, of course, maintain their own Linux kernel trees | ||
| 35 | containing code for any custom extensions that they wish.) | ||
| @@ -771,6 +771,8 @@ F: drivers/thermal/thermal_mmio.c · 770 unmodified lines | |||
| 771 | 771 | ||
| 772 | AMAZON ETHERNET DRIVERS | 772 | AMAZON ETHERNET DRIVERS |
| 773 | M: Netanel Belgazal <netanel@amazon.com> | 773 | M: Netanel Belgazal <netanel@amazon.com> |
| 774 | M: Arthur Kiyanovski <akiyano@amazon.com> | ||
| 775 | R: Guy Tzalik <gtzalik@amazon.com> | ||
| 774 | R: Saeed Bishara <saeedb@amazon.com> | 776 | R: Saeed Bishara <saeedb@amazon.com> |
| 775 | R: Zorik Machulsky <zorik@amazon.com> | 777 | R: Zorik Machulsky <zorik@amazon.com> |
| 776 | L: netdev@vger.kernel.org | 778 | L: netdev@vger.kernel.org |
| @@ -7034,6 +7036,7 @@ L: linux-acpi@vger.kernel.org · 6257 unmodified lines | |||
| 7034 | S: Maintained | 7036 | S: Maintained |
| 7035 | F: Documentation/firmware-guide/acpi/gpio-properties.rst | 7037 | F: Documentation/firmware-guide/acpi/gpio-properties.rst |
| 7036 | F: drivers/gpio/gpiolib-acpi.c | 7038 | F: drivers/gpio/gpiolib-acpi.c |
| 7039 | F: drivers/gpio/gpiolib-acpi.h | ||
| 7037 | 7040 | ||
| 7038 | GPIO IR Transmitter | 7041 | GPIO IR Transmitter |
| 7039 | M: Sean Young <sean@mess.org> | 7042 | M: Sean Young <sean@mess.org> |
| @@ -11457,8 +11460,8 @@ M: "David S. Miller" <davem@davemloft.net> · 4417 unmodified lines | |||
| 11457 | L: netdev@vger.kernel.org | 11460 | L: netdev@vger.kernel.org |
| 11458 | W: http://www.linuxfoundation.org/en/Net | 11461 | W: http://www.linuxfoundation.org/en/Net |
| 11459 | Q: http://patchwork.ozlabs.org/project/netdev/list/ | 11462 | Q: http://patchwork.ozlabs.org/project/netdev/list/ |
| 11460 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git | 11463 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 11461 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git | 11464 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git |
| 11462 | S: Odd Fixes | 11465 | S: Odd Fixes |
| 11463 | F: Documentation/devicetree/bindings/net/ | 11466 | F: Documentation/devicetree/bindings/net/ |
| 11464 | F: drivers/net/ | 11467 | F: drivers/net/ |
| @@ -11499,8 +11502,8 @@ M: "David S. Miller" <davem@davemloft.net> · 34 unmodified lines | |||
| 11499 | L: netdev@vger.kernel.org | 11502 | L: netdev@vger.kernel.org |
| 11500 | W: http://www.linuxfoundation.org/en/Net | 11503 | W: http://www.linuxfoundation.org/en/Net |
| 11501 | Q: http://patchwork.ozlabs.org/project/netdev/list/ | 11504 | Q: http://patchwork.ozlabs.org/project/netdev/list/ |
| 11502 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git | 11505 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 11503 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git | 11506 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git |
| 11504 | B: mailto:netdev@vger.kernel.org | 11507 | B: mailto:netdev@vger.kernel.org |
| 11505 | S: Maintained | 11508 | S: Maintained |
| 11506 | F: net/ | 11509 | F: net/ |
| @@ -11545,7 +11548,7 @@ M: "David S. Miller" <davem@davemloft.net> · 38 unmodified lines | |||
| 11545 | M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | 11548 | M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> |
| 11546 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> | 11549 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> |
| 11547 | L: netdev@vger.kernel.org | 11550 | L: netdev@vger.kernel.org |
| 11548 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git | 11551 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 11549 | S: Maintained | 11552 | S: Maintained |
| 11550 | F: net/ipv4/ | 11553 | F: net/ipv4/ |
| 11551 | F: net/ipv6/ | 11554 | F: net/ipv6/ |
| @@ -13676,7 +13679,6 @@ F: drivers/net/ethernet/qualcomm/emac/ · 2124 unmodified lines | |||
| 13676 | 13679 | ||
| 13677 | QUALCOMM ETHQOS ETHERNET DRIVER | 13680 | QUALCOMM ETHQOS ETHERNET DRIVER |
| 13678 | M: Vinod Koul <vkoul@kernel.org> | 13681 | M: Vinod Koul <vkoul@kernel.org> |
| 13679 | M: Niklas Cassel <niklas.cassel@linaro.org> | ||
| 13680 | L: netdev@vger.kernel.org | 13682 | L: netdev@vger.kernel.org |
| 13681 | S: Maintained | 13683 | S: Maintained |
| 13682 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 13684 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |
| @@ -14118,6 +14120,7 @@ M: Paul Walmsley <paul.walmsley@sifive.com> · 435 unmodified lines | |||
| 14118 | M: Palmer Dabbelt <palmer@dabbelt.com> | 14120 | M: Palmer Dabbelt <palmer@dabbelt.com> |
| 14119 | M: Albert Ou <aou@eecs.berkeley.edu> | 14121 | M: Albert Ou <aou@eecs.berkeley.edu> |
| 14120 | L: linux-riscv@lists.infradead.org | 14122 | L: linux-riscv@lists.infradead.org |
| 14123 | P: Documentation/riscv/patch-acceptance.rst | ||
| 14121 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git | 14124 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git |
| 14122 | S: Supported | 14125 | S: Supported |
| 14123 | F: arch/riscv/ | 14126 | F: arch/riscv/ |
| @@ -14545,8 +14548,6 @@ F: include/linux/platform_data/spi-s3c64xx.h · 421 unmodified lines | |||
| 14545 | 14548 | ||
| 14546 | SAMSUNG SXGBE DRIVERS | 14549 | SAMSUNG SXGBE DRIVERS |
| 14547 | M: Byungho An <bh74.an@samsung.com> | 14550 | M: Byungho An <bh74.an@samsung.com> |
| 14548 | M: Girish K S <ks.giri@samsung.com> | ||
| 14549 | M: Vipul Pandya <vipul.pandya@samsung.com> | ||
| 14550 | S: Supported | 14551 | S: Supported |
| 14551 | L: netdev@vger.kernel.org | 14552 | L: netdev@vger.kernel.org |
| 14552 | F: drivers/net/ethernet/samsung/sxgbe/ | 14553 | F: drivers/net/ethernet/samsung/sxgbe/ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 5 | 3 | PATCHLEVEL = 5 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc3 | 5 | EXTRAVERSION = -rc6 |
| 6 | NAME = Kleptomaniac Octopus | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -162,7 +162,7 @@ · 161 unmodified lines | |||
| 162 | #endif | 162 | #endif |
| 163 | 163 | ||
| 164 | #ifdef CONFIG_ARC_HAS_ACCL_REGS | 164 | #ifdef CONFIG_ARC_HAS_ACCL_REGS |
| 165 | ST2 r58, r59, PT_sp + 12 | 165 | ST2 r58, r59, PT_r58 |
| 166 | #endif | 166 | #endif |
| 167 | 167 | ||
| 168 | .endm | 168 | .endm |
| @@ -172,8 +172,8 @@ · 3 unmodified lines | |||
| 172 | 172 | ||
| 173 | LD2 gp, fp, PT_r26 ; gp (r26), fp (r27) | 173 | LD2 gp, fp, PT_r26 ; gp (r26), fp (r27) |
| 174 | 174 | ||
| 175 | ld r12, [sp, PT_sp + 4] | 175 | ld r12, [sp, PT_r12] |
| 176 | ld r30, [sp, PT_sp + 8] | 176 | ld r30, [sp, PT_r30] |
| 177 | 177 | ||
| 178 | ; Restore SP (into AUX_USER_SP) only if returning to U mode | 178 | ; Restore SP (into AUX_USER_SP) only if returning to U mode |
| 179 | ; - for K mode, it will be implicitly restored as stack is unwound | 179 | ; - for K mode, it will be implicitly restored as stack is unwound |
| @@ -190,7 +190,7 @@ · 10 unmodified lines | |||
| 190 | #endif | 190 | #endif |
| 191 | 191 | ||
| 192 | #ifdef CONFIG_ARC_HAS_ACCL_REGS | 192 | #ifdef CONFIG_ARC_HAS_ACCL_REGS |
| 193 | LD2 r58, r59, PT_sp + 12 | 193 | LD2 r58, r59, PT_r58 |
| 194 | #endif | 194 | #endif |
| 195 | .endm | 195 | .endm |
| 196 | 196 | ||
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #define _ASM_ARC_HUGEPAGE_H | 8 | #define _ASM_ARC_HUGEPAGE_H |
| 9 | 9 | ||
| 10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
| 11 | #define __ARCH_USE_5LEVEL_HACK | ||
| 12 | #include <asm-generic/pgtable-nopmd.h> | 11 | #include <asm-generic/pgtable-nopmd.h> |
| 13 | 12 | ||
| 14 | static inline pte_t pmd_pte(pmd_t pmd) | 13 | static inline pte_t pmd_pte(pmd_t pmd) |
| @@ -66,7 +66,15 @@ int main(void) · 65 unmodified lines | |||
| 66 | 66 | ||
| 67 | DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); | 67 | DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); |
| 68 | DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); | 68 | DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); |
| 69 | DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25)); | 69 | |
| 70 | #ifdef CONFIG_ISA_ARCV2 | ||
| 71 | OFFSET(PT_r12, pt_regs, r12); | ||
| 72 | OFFSET(PT_r30, pt_regs, r30); | ||
| 73 | #endif | ||
| 74 | #ifdef CONFIG_ARC_HAS_ACCL_REGS | ||
| 75 | OFFSET(PT_r58, pt_regs, r58); | ||
| 76 | OFFSET(PT_r59, pt_regs, r59); | ||
| 77 | #endif | ||
| 70 | 78 | ||
| 71 | return 0; | 79 | return 0; |
| 72 | } | 80 | } |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | menuconfig ARC_PLAT_EZNPS | 7 | menuconfig ARC_PLAT_EZNPS |
| 8 | bool "\"EZchip\" ARC dev platform" | 8 | bool "\"EZchip\" ARC dev platform" |
| 9 | select CPU_BIG_ENDIAN | 9 | select CPU_BIG_ENDIAN |
| 10 | select CLKSRC_NPS | 10 | select CLKSRC_NPS if !PHYS_ADDR_T_64BIT |
| 11 | select EZNPS_GIC | 11 | select EZNPS_GIC |
| 12 | select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET | 12 | select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET |
| 13 | help | 13 | help |
| @@ -72,6 +72,7 @@ config ARM · 71 unmodified lines | |||
| 72 | select HAVE_ARM_SMCCC if CPU_V7 | 72 | select HAVE_ARM_SMCCC if CPU_V7 |
| 73 | select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32 | 73 | select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32 |
| 74 | select HAVE_CONTEXT_TRACKING | 74 | select HAVE_CONTEXT_TRACKING |
| 75 | select HAVE_COPY_THREAD_TLS | ||
| 75 | select HAVE_C_RECORDMCOUNT | 76 | select HAVE_C_RECORDMCOUNT |
| 76 | select HAVE_DEBUG_KMEMLEAK | 77 | select HAVE_DEBUG_KMEMLEAK |
| 77 | select HAVE_DMA_CONTIGUOUS if MMU | 78 | select HAVE_DMA_CONTIGUOUS if MMU |
| @@ -226,8 +226,8 @@ void release_thread(struct task_struct *dead_task) · 225 unmodified lines | |||
| 226 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 226 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
| 227 | 227 | ||
| 228 | int | 228 | int |
| 229 | copy_thread(unsigned long clone_flags, unsigned long stack_start, | 229 | copy_thread_tls(unsigned long clone_flags, unsigned long stack_start, |
| 230 | unsigned long stk_sz, struct task_struct *p) | 230 | unsigned long stk_sz, struct task_struct *p, unsigned long tls) |
| 231 | { | 231 | { |
| 232 | struct thread_info *thread = task_thread_info(p); | 232 | struct thread_info *thread = task_thread_info(p); |
| 233 | struct pt_regs *childregs = task_pt_regs(p); | 233 | struct pt_regs *childregs = task_pt_regs(p); |
| @@ -261,7 +261,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, · 27 unmodified lines | |||
| 261 | clear_ptrace_hw_breakpoint(p); | 261 | clear_ptrace_hw_breakpoint(p); |
| 262 | 262 | ||
| 263 | if (clone_flags & CLONE_SETTLS) | 263 | if (clone_flags & CLONE_SETTLS) |
| 264 | thread->tp_value[0] = childregs->ARM_r3; | 264 | thread->tp_value[0] = tls; |
| 265 | thread->tp_value[1] = get_tpuser(); | 265 | thread->tp_value[1] = get_tpuser(); |
| 266 | 266 | ||
| 267 | thread_notify(THREAD_NOTIFY_COPY, thread); | 267 | thread_notify(THREAD_NOTIFY_COPY, thread); |
| @@ -138,6 +138,7 @@ config ARM64 · 137 unmodified lines | |||
| 138 | select HAVE_CMPXCHG_DOUBLE | 138 | select HAVE_CMPXCHG_DOUBLE |
| 139 | select HAVE_CMPXCHG_LOCAL | 139 | select HAVE_CMPXCHG_LOCAL |
| 140 | select HAVE_CONTEXT_TRACKING | 140 | select HAVE_CONTEXT_TRACKING |
| 141 | select HAVE_COPY_THREAD_TLS | ||
| 141 | select HAVE_DEBUG_BUGVERBOSE | 142 | select HAVE_DEBUG_BUGVERBOSE |
| 142 | select HAVE_DEBUG_KMEMLEAK | 143 | select HAVE_DEBUG_KMEMLEAK |
| 143 | select HAVE_DMA_CONTIGUOUS | 144 | select HAVE_DMA_CONTIGUOUS |
| @@ -85,13 +85,12 @@ · 84 unmodified lines | |||
| 85 | #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE) | 85 | #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE) |
| 86 | #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) | 86 | #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) |
| 87 | #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN) | 87 | #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN) |
| 88 | #define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN) | ||
| 89 | 88 | ||
| 90 | #define __P000 PAGE_NONE | 89 | #define __P000 PAGE_NONE |
| 91 | #define __P001 PAGE_READONLY | 90 | #define __P001 PAGE_READONLY |
| 92 | #define __P010 PAGE_READONLY | 91 | #define __P010 PAGE_READONLY |
| 93 | #define __P011 PAGE_READONLY | 92 | #define __P011 PAGE_READONLY |
| 94 | #define __P100 PAGE_EXECONLY | 93 | #define __P100 PAGE_READONLY_EXEC |
| 95 | #define __P101 PAGE_READONLY_EXEC | 94 | #define __P101 PAGE_READONLY_EXEC |
| 96 | #define __P110 PAGE_READONLY_EXEC | 95 | #define __P110 PAGE_READONLY_EXEC |
| 97 | #define __P111 PAGE_READONLY_EXEC | 96 | #define __P111 PAGE_READONLY_EXEC |
| @@ -100,7 +99,7 @@ · 2 unmodified lines | |||
| 100 | #define __S001 PAGE_READONLY | 99 | #define __S001 PAGE_READONLY |
| 101 | #define __S010 PAGE_SHARED | 100 | #define __S010 PAGE_SHARED |
| 102 | #define __S011 PAGE_SHARED | 101 | #define __S011 PAGE_SHARED |
| 103 | #define __S100 PAGE_EXECONLY | 102 | #define __S100 PAGE_READONLY_EXEC |
| 104 | #define __S101 PAGE_READONLY_EXEC | 103 | #define __S101 PAGE_READONLY_EXEC |
| 105 | #define __S110 PAGE_SHARED_EXEC | 104 | #define __S110 PAGE_SHARED_EXEC |
| 106 | #define __S111 PAGE_SHARED_EXEC | 105 | #define __S111 PAGE_SHARED_EXEC |
| @@ -96,12 +96,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; · 95 unmodified lines | |||
| 96 | #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) | 96 | #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) |
| 97 | 97 | ||
| 98 | #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) | 98 | #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) |
| 99 | /* | ||
| 100 | * Execute-only user mappings do not have the PTE_USER bit set. All valid | ||
| 101 | * kernel mappings have the PTE_UXN bit set. | ||
| 102 | */ | ||
| 103 | #define pte_valid_not_user(pte) \ | 99 | #define pte_valid_not_user(pte) \ |
| 104 | ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN)) | 100 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) |
| 105 | #define pte_valid_young(pte) \ | 101 | #define pte_valid_young(pte) \ |
| 106 | ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF)) | 102 | ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF)) |
| 107 | #define pte_valid_user(pte) \ | 103 | #define pte_valid_user(pte) \ |
| @@ -117,8 +113,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; · 9 unmodified lines | |||
| 117 | 113 | ||
| 118 | /* | 114 | /* |
| 119 | * p??_access_permitted() is true for valid user mappings (subject to the | 115 | * p??_access_permitted() is true for valid user mappings (subject to the |
| 120 | * write permission check) other than user execute-only which do not have the | 116 | * write permission check). PROT_NONE mappings do not have the PTE_VALID bit |
| 121 | * PTE_USER bit set. PROT_NONE mappings do not have the PTE_VALID bit set. | 117 | * set. |
| 122 | */ | 118 | */ |
| 123 | #define pte_access_permitted(pte, write) \ | 119 | #define pte_access_permitted(pte, write) \ |
| 124 | (pte_valid_user(pte) && (!(write) || pte_write(pte))) | 120 | (pte_valid_user(pte) && (!(write) || pte_write(pte))) |
| @@ -42,7 +42,6 @@ · 41 unmodified lines | |||
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | #define __ARCH_WANT_SYS_CLONE | 44 | #define __ARCH_WANT_SYS_CLONE |
| 45 | #define __ARCH_WANT_SYS_CLONE3 | ||
| 46 | 45 | ||
| 47 | #ifndef __COMPAT_SYSCALL_NR | 46 | #ifndef __COMPAT_SYSCALL_NR |
| 48 | #include <uapi/asm/unistd.h> | 47 | #include <uapi/asm/unistd.h> |
| @@ -19,5 +19,6 @@ · 18 unmodified lines | |||
| 19 | #define __ARCH_WANT_NEW_STAT | 19 | #define __ARCH_WANT_NEW_STAT |
| 20 | #define __ARCH_WANT_SET_GET_RLIMIT | 20 | #define __ARCH_WANT_SET_GET_RLIMIT |
| 21 | #define __ARCH_WANT_TIME32_SYSCALLS | 21 | #define __ARCH_WANT_TIME32_SYSCALLS |
| 22 | #define __ARCH_WANT_SYS_CLONE3 | ||
| 22 | 23 | ||
| 23 | #include <asm-generic/unistd.h> | 24 | #include <asm-generic/unistd.h> |
| @@ -360,8 +360,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) · 359 unmodified lines | |||
| 360 | 360 | ||
| 361 | asmlinkage void ret_from_fork(void) asm("ret_from_fork"); | 361 | asmlinkage void ret_from_fork(void) asm("ret_from_fork"); |
| 362 | 362 | ||
| 363 | int copy_thread(unsigned long clone_flags, unsigned long stack_start, | 363 | int copy_thread_tls(unsigned long clone_flags, unsigned long stack_start, |
| 364 | unsigned long stk_sz, struct task_struct *p) | 364 | unsigned long stk_sz, struct task_struct *p, unsigned long tls) |
| 365 | { | 365 | { |
| 366 | struct pt_regs *childregs = task_pt_regs(p); | 366 | struct pt_regs *childregs = task_pt_regs(p); |
| 367 | 367 | ||
| @@ -394,11 +394,11 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, · 26 unmodified lines | |||
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | /* | 396 | /* |
| 397 | * If a TLS pointer was passed to clone (4th argument), use it | 397 | * If a TLS pointer was passed to clone, use it for the new |
| 398 | * for the new thread. | 398 | * thread. |
| 399 | */ | 399 | */ |
| 400 | if (clone_flags & CLONE_SETTLS) | 400 | if (clone_flags & CLONE_SETTLS) |
| 401 | p->thread.uw.tp_value = childregs->regs[3]; | 401 | p->thread.uw.tp_value = tls; |
| 402 | } else { | 402 | } else { |
| 403 | memset(childregs, 0, sizeof(struct pt_regs)); | 403 | memset(childregs, 0, sizeof(struct pt_regs)); |
| 404 | childregs->pstate = PSR_MODE_EL1h; | 404 | childregs->pstate = PSR_MODE_EL1h; |
| @@ -445,7 +445,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, · 444 unmodified lines | |||
| 445 | const struct fault_info *inf; | 445 | const struct fault_info *inf; |
| 446 | struct mm_struct *mm = current->mm; | 446 | struct mm_struct *mm = current->mm; |
| 447 | vm_fault_t fault, major = 0; | 447 | vm_fault_t fault, major = 0; |
| 448 | unsigned long vm_flags = VM_READ | VM_WRITE; | 448 | unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC; |
| 449 | unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | 449 | unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
| 450 | 450 | ||
| 451 | if (kprobe_page_fault(regs, esr)) | 451 | if (kprobe_page_fault(regs, esr)) |
| @@ -1070,7 +1070,6 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 1069 unmodified lines | |||
| 1070 | { | 1070 | { |
| 1071 | unsigned long start_pfn = start >> PAGE_SHIFT; | 1071 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 1072 | unsigned long nr_pages = size >> PAGE_SHIFT; | 1072 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 1073 | struct zone *zone; | ||
| 1074 | 1073 | ||
| 1075 | /* | 1074 | /* |
| 1076 | * FIXME: Cleanup page tables (also in arch_add_memory() in case | 1075 | * FIXME: Cleanup page tables (also in arch_add_memory() in case |
| @@ -1079,7 +1078,6 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 2 unmodified lines | |||
| 1079 | * unplug. ARCH_ENABLE_MEMORY_HOTREMOVE must not be | 1078 | * unplug. ARCH_ENABLE_MEMORY_HOTREMOVE must not be |
| 1080 | * unlocked yet. | 1079 | * unlocked yet. |
| 1081 | */ | 1080 | */ |
| 1082 | zone = page_zone(pfn_to_page(start_pfn)); | 1081 | __remove_pages(start_pfn, nr_pages, altmap); |
| 1083 | __remove_pages(zone, start_pfn, nr_pages, altmap); | ||
| 1084 | } | 1082 | } |
| 1085 | #endif | 1083 | #endif |
| @@ -91,7 +91,7 @@ static inline void atomic_##op(int i, atomic_t *v) \ · 90 unmodified lines | |||
| 91 | "1: %0 = memw_locked(%1);\n" \ | 91 | "1: %0 = memw_locked(%1);\n" \ |
| 92 | " %0 = "#op "(%0,%2);\n" \ | 92 | " %0 = "#op "(%0,%2);\n" \ |
| 93 | " memw_locked(%1,P3)=%0;\n" \ | 93 | " memw_locked(%1,P3)=%0;\n" \ |
| 94 | " if !P3 jump 1b;\n" \ | 94 | " if (!P3) jump 1b;\n" \ |
| 95 | : "=&r" (output) \ | 95 | : "=&r" (output) \ |
| 96 | : "r" (&v->counter), "r" (i) \ | 96 | : "r" (&v->counter), "r" (i) \ |
| 97 | : "memory", "p3" \ | 97 | : "memory", "p3" \ |
| @@ -107,7 +107,7 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \ · 9 unmodified lines | |||
| 107 | "1: %0 = memw_locked(%1);\n" \ | 107 | "1: %0 = memw_locked(%1);\n" \ |
| 108 | " %0 = "#op "(%0,%2);\n" \ | 108 | " %0 = "#op "(%0,%2);\n" \ |
| 109 | " memw_locked(%1,P3)=%0;\n" \ | 109 | " memw_locked(%1,P3)=%0;\n" \ |
| 110 | " if !P3 jump 1b;\n" \ | 110 | " if (!P3) jump 1b;\n" \ |
| 111 | : "=&r" (output) \ | 111 | : "=&r" (output) \ |
| 112 | : "r" (&v->counter), "r" (i) \ | 112 | : "r" (&v->counter), "r" (i) \ |
| 113 | : "memory", "p3" \ | 113 | : "memory", "p3" \ |
| @@ -124,7 +124,7 @@ static inline int atomic_fetch_##op(int i, atomic_t *v) \ · 10 unmodified lines | |||
| 124 | "1: %0 = memw_locked(%2);\n" \ | 124 | "1: %0 = memw_locked(%2);\n" \ |
| 125 | " %1 = "#op "(%0,%3);\n" \ | 125 | " %1 = "#op "(%0,%3);\n" \ |
| 126 | " memw_locked(%2,P3)=%1;\n" \ | 126 | " memw_locked(%2,P3)=%1;\n" \ |
| 127 | " if !P3 jump 1b;\n" \ | 127 | " if (!P3) jump 1b;\n" \ |
| 128 | : "=&r" (output), "=&r" (val) \ | 128 | : "=&r" (output), "=&r" (val) \ |
| 129 | : "r" (&v->counter), "r" (i) \ | 129 | : "r" (&v->counter), "r" (i) \ |
| 130 | : "memory", "p3" \ | 130 | : "memory", "p3" \ |
| @@ -173,7 +173,7 @@ static inline int atomic_fetch_add_unless(atomic_t *v, int a, int u) · 42 unmodified lines | |||
| 173 | " }" | 173 | " }" |
| 174 | " memw_locked(%2, p3) = %1;" | 174 | " memw_locked(%2, p3) = %1;" |
| 175 | " {" | 175 | " {" |
| 176 | " if !p3 jump 1b;" | 176 | " if (!p3) jump 1b;" |
| 177 | " }" | 177 | " }" |
| 178 | "2:" | 178 | "2:" |
| 179 | : "=&r" (__oldval), "=&r" (tmp) | 179 | : "=&r" (__oldval), "=&r" (tmp) |
| @@ -38,7 +38,7 @@ static inline int test_and_clear_bit(int nr, volatile void *addr) · 37 unmodified lines | |||
| 38 | "1: R12 = memw_locked(R10);\n" | 38 | "1: R12 = memw_locked(R10);\n" |
| 39 | " { P0 = tstbit(R12,R11); R12 = clrbit(R12,R11); }\n" | 39 | " { P0 = tstbit(R12,R11); R12 = clrbit(R12,R11); }\n" |
| 40 | " memw_locked(R10,P1) = R12;\n" | 40 | " memw_locked(R10,P1) = R12;\n" |
| 41 | " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" | 41 | " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" |
| 42 | : "=&r" (oldval) | 42 | : "=&r" (oldval) |
| 43 | : "r" (addr), "r" (nr) | 43 | : "r" (addr), "r" (nr) |
| 44 | : "r10", "r11", "r12", "p0", "p1", "memory" | 44 | : "r10", "r11", "r12", "p0", "p1", "memory" |
| @@ -62,7 +62,7 @@ static inline int test_and_set_bit(int nr, volatile void *addr) · 17 unmodified lines | |||
| 62 | "1: R12 = memw_locked(R10);\n" | 62 | "1: R12 = memw_locked(R10);\n" |
| 63 | " { P0 = tstbit(R12,R11); R12 = setbit(R12,R11); }\n" | 63 | " { P0 = tstbit(R12,R11); R12 = setbit(R12,R11); }\n" |
| 64 | " memw_locked(R10,P1) = R12;\n" | 64 | " memw_locked(R10,P1) = R12;\n" |
| 65 | " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" | 65 | " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" |
| 66 | : "=&r" (oldval) | 66 | : "=&r" (oldval) |
| 67 | : "r" (addr), "r" (nr) | 67 | : "r" (addr), "r" (nr) |
| 68 | : "r10", "r11", "r12", "p0", "p1", "memory" | 68 | : "r10", "r11", "r12", "p0", "p1", "memory" |
| @@ -88,7 +88,7 @@ static inline int test_and_change_bit(int nr, volatile void *addr) · 19 unmodified lines | |||
| 88 | "1: R12 = memw_locked(R10);\n" | 88 | "1: R12 = memw_locked(R10);\n" |
| 89 | " { P0 = tstbit(R12,R11); R12 = togglebit(R12,R11); }\n" | 89 | " { P0 = tstbit(R12,R11); R12 = togglebit(R12,R11); }\n" |
| 90 | " memw_locked(R10,P1) = R12;\n" | 90 | " memw_locked(R10,P1) = R12;\n" |
| 91 | " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" | 91 | " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" |
| 92 | : "=&r" (oldval) | 92 | : "=&r" (oldval) |
| 93 | : "r" (addr), "r" (nr) | 93 | : "r" (addr), "r" (nr) |
| 94 | : "r10", "r11", "r12", "p0", "p1", "memory" | 94 | : "r10", "r11", "r12", "p0", "p1", "memory" |
| @@ -223,7 +223,7 @@ static inline int ffs(int x) · 128 unmodified lines | |||
| 223 | int r; | 223 | int r; |
| 224 | 224 | ||
| 225 | asm("{ P0 = cmp.eq(%1,#0); %0 = ct0(%1);}\n" | 225 | asm("{ P0 = cmp.eq(%1,#0); %0 = ct0(%1);}\n" |
| 226 | "{ if P0 %0 = #0; if !P0 %0 = add(%0,#1);}\n" | 226 | "{ if (P0) %0 = #0; if (!P0) %0 = add(%0,#1);}\n" |
| 227 | : "=&r" (r) | 227 | : "=&r" (r) |
| 228 | : "r" (x) | 228 | : "r" (x) |
| 229 | : "p0"); | 229 | : "p0"); |
| @@ -30,7 +30,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, · 29 unmodified lines | |||
| 30 | __asm__ __volatile__ ( | 30 | __asm__ __volatile__ ( |
| 31 | "1: %0 = memw_locked(%1);\n" /* load into retval */ | 31 | "1: %0 = memw_locked(%1);\n" /* load into retval */ |
| 32 | " memw_locked(%1,P0) = %2;\n" /* store into memory */ | 32 | " memw_locked(%1,P0) = %2;\n" /* store into memory */ |
| 33 | " if !P0 jump 1b;\n" | 33 | " if (!P0) jump 1b;\n" |
| 34 | : "=&r" (retval) | 34 | : "=&r" (retval) |
| 35 | : "r" (ptr), "r" (x) | 35 | : "r" (ptr), "r" (x) |
| 36 | : "memory", "p0" | 36 | : "memory", "p0" |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | |||
| 16 | /* For example: %1 = %4 */ \ | 16 | /* For example: %1 = %4 */ \ |
| 17 | insn \ | 17 | insn \ |
| 18 | "2: memw_locked(%3,p2) = %1;\n" \ | 18 | "2: memw_locked(%3,p2) = %1;\n" \ |
| 19 | " if !p2 jump 1b;\n" \ | 19 | " if (!p2) jump 1b;\n" \ |
| 20 | " %1 = #0;\n" \ | 20 | " %1 = #0;\n" \ |
| 21 | "3:\n" \ | 21 | "3:\n" \ |
| 22 | ".section .fixup,\"ax\"\n" \ | 22 | ".section .fixup,\"ax\"\n" \ |
| @@ -84,10 +84,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, · 61 unmodified lines | |||
| 84 | "1: %1 = memw_locked(%3)\n" | 84 | "1: %1 = memw_locked(%3)\n" |
| 85 | " {\n" | 85 | " {\n" |
| 86 | " p2 = cmp.eq(%1,%4)\n" | 86 | " p2 = cmp.eq(%1,%4)\n" |
| 87 | " if !p2.new jump:NT 3f\n" | 87 | " if (!p2.new) jump:NT 3f\n" |
| 88 | " }\n" | 88 | " }\n" |
| 89 | "2: memw_locked(%3,p2) = %5\n" | 89 | "2: memw_locked(%3,p2) = %5\n" |
| 90 | " if !p2 jump 1b\n" | 90 | " if (!p2) jump 1b\n" |
| 91 | "3:\n" | 91 | "3:\n" |
| 92 | ".section .fixup,\"ax\"\n" | 92 | ".section .fixup,\"ax\"\n" |
| 93 | "4: %0 = #%6\n" | 93 | "4: %0 = #%6\n" |
| @@ -173,6 +173,7 @@ static inline void writel(u32 data, volatile void __iomem *addr) · 172 unmodified lines | |||
| 173 | 173 | ||
| 174 | void __iomem *ioremap(unsigned long phys_addr, unsigned long size); | 174 | void __iomem *ioremap(unsigned long phys_addr, unsigned long size); |
| 175 | #define ioremap_nocache ioremap | 175 | #define ioremap_nocache ioremap |
| 176 | #define ioremap_uc(X, Y) ioremap((X), (Y)) | ||
| 176 | 177 | ||
| 177 | 178 | ||
| 178 | #define __raw_writel writel | 179 | #define __raw_writel writel |
| @@ -30,9 +30,9 @@ static inline void arch_read_lock(arch_rwlock_t *lock) · 29 unmodified lines | |||
| 30 | __asm__ __volatile__( | 30 | __asm__ __volatile__( |
| 31 | "1: R6 = memw_locked(%0);\n" | 31 | "1: R6 = memw_locked(%0);\n" |
| 32 | " { P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" | 32 | " { P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" |
| 33 | " { if !P3 jump 1b; }\n" | 33 | " { if (!P3) jump 1b; }\n" |
| 34 | " memw_locked(%0,P3) = R6;\n" | 34 | " memw_locked(%0,P3) = R6;\n" |
| 35 | " { if !P3 jump 1b; }\n" | 35 | " { if (!P3) jump 1b; }\n" |
| 36 | : | 36 | : |
| 37 | : "r" (&lock->lock) | 37 | : "r" (&lock->lock) |
| 38 | : "memory", "r6", "p3" | 38 | : "memory", "r6", "p3" |
| @@ -46,7 +46,7 @@ static inline void arch_read_unlock(arch_rwlock_t *lock) · 7 unmodified lines | |||
| 46 | "1: R6 = memw_locked(%0);\n" | 46 | "1: R6 = memw_locked(%0);\n" |
| 47 | " R6 = add(R6,#-1);\n" | 47 | " R6 = add(R6,#-1);\n" |
| 48 | " memw_locked(%0,P3) = R6\n" | 48 | " memw_locked(%0,P3) = R6\n" |
| 49 | " if !P3 jump 1b;\n" | 49 | " if (!P3) jump 1b;\n" |
| 50 | : | 50 | : |
| 51 | : "r" (&lock->lock) | 51 | : "r" (&lock->lock) |
| 52 | : "memory", "r6", "p3" | 52 | : "memory", "r6", "p3" |
| @@ -61,7 +61,7 @@ static inline int arch_read_trylock(arch_rwlock_t *lock) · 8 unmodified lines | |||
| 61 | __asm__ __volatile__( | 61 | __asm__ __volatile__( |
| 62 | " R6 = memw_locked(%1);\n" | 62 | " R6 = memw_locked(%1);\n" |
| 63 | " { %0 = #0; P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" | 63 | " { %0 = #0; P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" |
| 64 | " { if !P3 jump 1f; }\n" | 64 | " { if (!P3) jump 1f; }\n" |
| 65 | " memw_locked(%1,P3) = R6;\n" | 65 | " memw_locked(%1,P3) = R6;\n" |
| 66 | " { %0 = P3 }\n" | 66 | " { %0 = P3 }\n" |
| 67 | "1:\n" | 67 | "1:\n" |
| @@ -78,9 +78,9 @@ static inline void arch_write_lock(arch_rwlock_t *lock) · 10 unmodified lines | |||
| 78 | __asm__ __volatile__( | 78 | __asm__ __volatile__( |
| 79 | "1: R6 = memw_locked(%0)\n" | 79 | "1: R6 = memw_locked(%0)\n" |
| 80 | " { P3 = cmp.eq(R6,#0); R6 = #-1;}\n" | 80 | " { P3 = cmp.eq(R6,#0); R6 = #-1;}\n" |
| 81 | " { if !P3 jump 1b; }\n" | 81 | " { if (!P3) jump 1b; }\n" |
| 82 | " memw_locked(%0,P3) = R6;\n" | 82 | " memw_locked(%0,P3) = R6;\n" |
| 83 | " { if !P3 jump 1b; }\n" | 83 | " { if (!P3) jump 1b; }\n" |
| 84 | : | 84 | : |
| 85 | : "r" (&lock->lock) | 85 | : "r" (&lock->lock) |
| 86 | : "memory", "r6", "p3" | 86 | : "memory", "r6", "p3" |
| @@ -94,7 +94,7 @@ static inline int arch_write_trylock(arch_rwlock_t *lock) · 7 unmodified lines | |||
| 94 | __asm__ __volatile__( | 94 | __asm__ __volatile__( |
| 95 | " R6 = memw_locked(%1)\n" | 95 | " R6 = memw_locked(%1)\n" |
| 96 | " { %0 = #0; P3 = cmp.eq(R6,#0); R6 = #-1;}\n" | 96 | " { %0 = #0; P3 = cmp.eq(R6,#0); R6 = #-1;}\n" |
| 97 | " { if !P3 jump 1f; }\n" | 97 | " { if (!P3) jump 1f; }\n" |
| 98 | " memw_locked(%1,P3) = R6;\n" | 98 | " memw_locked(%1,P3) = R6;\n" |
| 99 | " %0 = P3;\n" | 99 | " %0 = P3;\n" |
| 100 | "1:\n" | 100 | "1:\n" |
| @@ -117,9 +117,9 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) · 16 unmodified lines | |||
| 117 | __asm__ __volatile__( | 117 | __asm__ __volatile__( |
| 118 | "1: R6 = memw_locked(%0);\n" | 118 | "1: R6 = memw_locked(%0);\n" |
| 119 | " P3 = cmp.eq(R6,#0);\n" | 119 | " P3 = cmp.eq(R6,#0);\n" |
| 120 | " { if !P3 jump 1b; R6 = #1; }\n" | 120 | " { if (!P3) jump 1b; R6 = #1; }\n" |
| 121 | " memw_locked(%0,P3) = R6;\n" | 121 | " memw_locked(%0,P3) = R6;\n" |
| 122 | " { if !P3 jump 1b; }\n" | 122 | " { if (!P3) jump 1b; }\n" |
| 123 | : | 123 | : |
| 124 | : "r" (&lock->lock) | 124 | : "r" (&lock->lock) |
| 125 | : "memory", "r6", "p3" | 125 | : "memory", "r6", "p3" |
| @@ -139,7 +139,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) · 13 unmodified lines | |||
| 139 | __asm__ __volatile__( | 139 | __asm__ __volatile__( |
| 140 | " R6 = memw_locked(%1);\n" | 140 | " R6 = memw_locked(%1);\n" |
| 141 | " P3 = cmp.eq(R6,#0);\n" | 141 | " P3 = cmp.eq(R6,#0);\n" |
| 142 | " { if !P3 jump 1f; R6 = #1; %0 = #0; }\n" | 142 | " { if (!P3) jump 1f; R6 = #1; %0 = #0; }\n" |
| 143 | " memw_locked(%1,P3) = R6;\n" | 143 | " memw_locked(%1,P3) = R6;\n" |
| 144 | " %0 = P3;\n" | 144 | " %0 = P3;\n" |
| 145 | "1:\n" | 145 | "1:\n" |
| @@ -11,8 +11,6 @@ · 10 unmodified lines | |||
| 11 | #include <linux/thread_info.h> | 11 | #include <linux/thread_info.h> |
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | 13 | ||
| 14 | register unsigned long current_frame_pointer asm("r30"); | ||
| 15 | |||
| 16 | struct stackframe { | 14 | struct stackframe { |
| 17 | unsigned long fp; | 15 | unsigned long fp; |
| 18 | unsigned long rets; | 16 | unsigned long rets; |
| @@ -30,7 +28,7 @@ void save_stack_trace(struct stack_trace *trace) · 11 unmodified lines | |||
| 30 | 28 | ||
| 31 | low = (unsigned long)task_stack_page(current); | 29 | low = (unsigned long)task_stack_page(current); |
| 32 | high = low + THREAD_SIZE; | 30 | high = low + THREAD_SIZE; |
| 33 | fp = current_frame_pointer; | 31 | fp = (unsigned long)__builtin_frame_address(0); |
| 34 | 32 | ||
| 35 | while (fp >= low && fp <= (high - sizeof(*frame))) { | 33 | while (fp >= low && fp <= (high - sizeof(*frame))) { |
| 36 | frame = (struct stackframe *)fp; | 34 | frame = (struct stackframe *)fp; |
| @@ -369,7 +369,7 @@ ret_from_fork: · 368 unmodified lines | |||
| 369 | R26.L = #LO(do_work_pending); | 369 | R26.L = #LO(do_work_pending); |
| 370 | R0 = #VM_INT_DISABLE; | 370 | R0 = #VM_INT_DISABLE; |
| 371 | } | 371 | } |
| 372 | if P0 jump check_work_pending | 372 | if (P0) jump check_work_pending |
| 373 | { | 373 | { |
| 374 | R0 = R25; | 374 | R0 = R25; |
| 375 | callr R24 | 375 | callr R24 |
| @@ -689,9 +689,7 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 688 unmodified lines | |||
| 689 | { | 689 | { |
| 690 | unsigned long start_pfn = start >> PAGE_SHIFT; | 690 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 691 | unsigned long nr_pages = size >> PAGE_SHIFT; | 691 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 692 | struct zone *zone; | ||
| 693 | 692 | ||
| 694 | zone = page_zone(pfn_to_page(start_pfn)); | 693 | __remove_pages(start_pfn, nr_pages, altmap); |
| 695 | __remove_pages(zone, start_pfn, nr_pages, altmap); | ||
| 696 | } | 694 | } |
| 697 | #endif | 695 | #endif |
| @@ -47,7 +47,7 @@ config MIPS · 46 unmodified lines | |||
| 47 | select HAVE_ARCH_TRACEHOOK | 47 | select HAVE_ARCH_TRACEHOOK |
| 48 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES | 48 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES |
| 49 | select HAVE_ASM_MODVERSIONS | 49 | select HAVE_ASM_MODVERSIONS |
| 50 | select HAVE_EBPF_JIT if (!CPU_MICROMIPS) | 50 | select HAVE_EBPF_JIT if 64BIT && !CPU_MICROMIPS && TARGET_ISA_REV >= 2 |
| 51 | select HAVE_CONTEXT_TRACKING | 51 | select HAVE_CONTEXT_TRACKING |
| 52 | select HAVE_COPY_THREAD_TLS | 52 | select HAVE_COPY_THREAD_TLS |
| 53 | select HAVE_C_RECORDMCOUNT | 53 | select HAVE_C_RECORDMCOUNT |
| @@ -29,6 +29,9 @@ KBUILD_AFLAGS := $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ · 28 unmodified lines | |||
| 29 | -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ | 29 | -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ |
| 30 | -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS) | 30 | -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS) |
| 31 | 31 | ||
| 32 | # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. | ||
| 33 | KCOV_INSTRUMENT := n | ||
| 34 | |||
| 32 | # decompressor objects (linked with vmlinuz) | 35 | # decompressor objects (linked with vmlinuz) |
| 33 | vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o | 36 | vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o |
| 34 | 37 | ||
| @@ -15,7 +15,8 @@ · 14 unmodified lines | |||
| 15 | static inline int __pure __get_cpu_type(const int cpu_type) | 15 | static inline int __pure __get_cpu_type(const int cpu_type) |
| 16 | { | 16 | { |
| 17 | switch (cpu_type) { | 17 | switch (cpu_type) { |
| 18 | #if defined(CONFIG_SYS_HAS_CPU_LOONGSON2EF) | 18 | #if defined(CONFIG_SYS_HAS_CPU_LOONGSON2E) || \ |
| 19 | defined(CONFIG_SYS_HAS_CPU_LOONGSON2F) | ||
| 19 | case CPU_LOONGSON2EF: | 20 | case CPU_LOONGSON2EF: |
| 20 | #endif | 21 | #endif |
| 21 | 22 | ||
| @@ -49,8 +49,26 @@ struct thread_info { · 48 unmodified lines | |||
| 49 | .addr_limit = KERNEL_DS, \ | 49 | .addr_limit = KERNEL_DS, \ |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | /* How to get the thread information struct from C. */ | 52 | /* |
| 53 | * A pointer to the struct thread_info for the currently executing thread is | ||
| 54 | * held in register $28/$gp. | ||
| 55 | * | ||
| 56 | * We declare __current_thread_info as a global register variable rather than a | ||
| 57 | * local register variable within current_thread_info() because clang doesn't | ||
| 58 | * support explicit local register variables. | ||
| 59 | * | ||
| 60 | * When building the VDSO we take care not to declare the global register | ||
| 61 | * variable because this causes GCC to not preserve the value of $28/$gp in | ||
| 62 | * functions that change its value (which is common in the PIC VDSO when | ||
| 63 | * accessing the GOT). Since the VDSO shouldn't be accessing | ||
| 64 | * __current_thread_info anyway we declare it extern in order to cause a link | ||
| 65 | * failure if it's referenced. | ||
| 66 | */ | ||
| 67 | #ifdef __VDSO__ | ||
| 68 | extern struct thread_info *__current_thread_info; | ||
| 69 | #else | ||
| 53 | register struct thread_info *__current_thread_info __asm__("$28"); | 70 | register struct thread_info *__current_thread_info __asm__("$28"); |
| 71 | #endif | ||
| 54 | 72 | ||
| 55 | static inline struct thread_info *current_thread_info(void) | 73 | static inline struct thread_info *current_thread_info(void) |
| 56 | { | 74 | { |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | #define __VDSO_USE_SYSCALL ULLONG_MAX | 27 | #define __VDSO_USE_SYSCALL ULLONG_MAX |
| 28 | 28 | ||
| 29 | #ifdef CONFIG_MIPS_CLOCK_VSYSCALL | ||
| 30 | |||
| 31 | static __always_inline long gettimeofday_fallback( | 29 | static __always_inline long gettimeofday_fallback( |
| 32 | struct __kernel_old_timeval *_tv, | 30 | struct __kernel_old_timeval *_tv, |
| 33 | struct timezone *_tz) | 31 | struct timezone *_tz) |
| @@ -48,17 +46,6 @@ static __always_inline long gettimeofday_fallback( · 14 unmodified lines | |||
| 48 | return error ? -ret : ret; | 46 | return error ? -ret : ret; |
| 49 | } | 47 | } |
| 50 | 48 | ||
| 51 | #else | ||
| 52 | |||
| 53 | static __always_inline long gettimeofday_fallback( | ||
| 54 | struct __kernel_old_timeval *_tv, | ||
| 55 | struct timezone *_tz) | ||
| 56 | { | ||
| 57 | return -1; | ||
| 58 | } | ||
| 59 | |||
| 60 | #endif | ||
| 61 | |||
| 62 | static __always_inline long clock_gettime_fallback( | 49 | static __always_inline long clock_gettime_fallback( |
| 63 | clockid_t _clkid, | 50 | clockid_t _clkid, |
| 64 | struct __kernel_timespec *_ts) | 51 | struct __kernel_timespec *_ts) |
| @@ -50,6 +50,25 @@ static int __init_cache_level(unsigned int cpu) · 49 unmodified lines | |||
| 50 | return 0; | 50 | return 0; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | static void fill_cpumask_siblings(int cpu, cpumask_t *cpu_map) | ||
| 54 | { | ||
| 55 | int cpu1; | ||
| 56 | |||
| 57 | for_each_possible_cpu(cpu1) | ||
| 58 | if (cpus_are_siblings(cpu, cpu1)) | ||
| 59 | cpumask_set_cpu(cpu1, cpu_map); | ||
| 60 | } | ||
| 61 | |||
| 62 | static void fill_cpumask_cluster(int cpu, cpumask_t *cpu_map) | ||
| 63 | { | ||
| 64 | int cpu1; | ||
| 65 | int cluster = cpu_cluster(&cpu_data[cpu]); | ||
| 66 | |||
| 67 | for_each_possible_cpu(cpu1) | ||
| 68 | if (cpu_cluster(&cpu_data[cpu1]) == cluster) | ||
| 69 | cpumask_set_cpu(cpu1, cpu_map); | ||
| 70 | } | ||
| 71 | |||
| 53 | static int __populate_cache_leaves(unsigned int cpu) | 72 | static int __populate_cache_leaves(unsigned int cpu) |
| 54 | { | 73 | { |
| 55 | struct cpuinfo_mips *c = ¤t_cpu_data; | 74 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| @@ -57,14 +76,20 @@ static int __populate_cache_leaves(unsigned int cpu) · 1 unmodified line | |||
| 57 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; | 76 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; |
| 58 | 77 | ||
| 59 | if (c->icache.waysize) { | 78 | if (c->icache.waysize) { |
| 79 | /* L1 caches are per core */ | ||
| 80 | fill_cpumask_siblings(cpu, &this_leaf->shared_cpu_map); | ||
| 60 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_DATA); | 81 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_DATA); |
| 82 | fill_cpumask_siblings(cpu, &this_leaf->shared_cpu_map); | ||
| 61 | populate_cache(icache, this_leaf, 1, CACHE_TYPE_INST); | 83 | populate_cache(icache, this_leaf, 1, CACHE_TYPE_INST); |
| 62 | } else { | 84 | } else { |
| 63 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_UNIFIED); | 85 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_UNIFIED); |
| 64 | } | 86 | } |
| 65 | 87 | ||
| 66 | if (c->scache.waysize) | 88 | if (c->scache.waysize) { |
| 89 | /* L2 cache is per cluster */ | ||
| 90 | fill_cpumask_cluster(cpu, &this_leaf->shared_cpu_map); | ||
| 67 | populate_cache(scache, this_leaf, 2, CACHE_TYPE_UNIFIED); | 91 | populate_cache(scache, this_leaf, 2, CACHE_TYPE_UNIFIED); |
| 92 | } | ||
| 68 | 93 | ||
| 69 | if (c->tcache.waysize) | 94 | if (c->tcache.waysize) |
| 70 | populate_cache(tcache, this_leaf, 3, CACHE_TYPE_UNIFIED); | 95 | populate_cache(tcache, this_leaf, 3, CACHE_TYPE_UNIFIED); |
| @@ -1804,7 +1804,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 1803 unmodified lines | |||
| 1804 | unsigned int image_size; | 1804 | unsigned int image_size; |
| 1805 | u8 *image_ptr; | 1805 | u8 *image_ptr; |
| 1806 | 1806 | ||
| 1807 | if (!prog->jit_requested || MIPS_ISA_REV < 2) | 1807 | if (!prog->jit_requested) |
| 1808 | return prog; | 1808 | return prog; |
| 1809 | 1809 | ||
| 1810 | tmp = bpf_jit_blind_constants(prog); | 1810 | tmp = bpf_jit_blind_constants(prog); |
| @@ -17,12 +17,22 @@ int __vdso_clock_gettime(clockid_t clock, · 16 unmodified lines | |||
| 17 | return __cvdso_clock_gettime32(clock, ts); | 17 | return __cvdso_clock_gettime32(clock, ts); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | #ifdef CONFIG_MIPS_CLOCK_VSYSCALL | ||
| 21 | |||
| 22 | /* | ||
| 23 | * This is behind the ifdef so that we don't provide the symbol when there's no | ||
| 24 | * possibility of there being a usable clocksource, because there's nothing we | ||
| 25 | * can do without it. When libc fails the symbol lookup it should fall back on | ||
| 26 | * the standard syscall path. | ||
| 27 | */ | ||
| 20 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, | 28 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, |
| 21 | struct timezone *tz) | 29 | struct timezone *tz) |
| 22 | { | 30 | { |
| 23 | return __cvdso_gettimeofday(tv, tz); | 31 | return __cvdso_gettimeofday(tv, tz); |
| 24 | } | 32 | } |
| 25 | 33 | ||
| 34 | #endif /* CONFIG_MIPS_CLOCK_VSYSCALL */ | ||
| 35 | |||
| 26 | int __vdso_clock_getres(clockid_t clock_id, | 36 | int __vdso_clock_getres(clockid_t clock_id, |
| 27 | struct old_timespec32 *res) | 37 | struct old_timespec32 *res) |
| 28 | { | 38 | { |
| @@ -43,12 +53,22 @@ int __vdso_clock_gettime(clockid_t clock, · 14 unmodified lines | |||
| 43 | return __cvdso_clock_gettime(clock, ts); | 53 | return __cvdso_clock_gettime(clock, ts); |
| 44 | } | 54 | } |
| 45 | 55 | ||
| 56 | #ifdef CONFIG_MIPS_CLOCK_VSYSCALL | ||
| 57 | |||
| 58 | /* | ||
| 59 | * This is behind the ifdef so that we don't provide the symbol when there's no | ||
| 60 | * possibility of there being a usable clocksource, because there's nothing we | ||
| 61 | * can do without it. When libc fails the symbol lookup it should fall back on | ||
| 62 | * the standard syscall path. | ||
| 63 | */ | ||
| 46 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, | 64 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, |
| 47 | struct timezone *tz) | 65 | struct timezone *tz) |
| 48 | { | 66 | { |
| 49 | return __cvdso_gettimeofday(tv, tz); | 67 | return __cvdso_gettimeofday(tv, tz); |
| 50 | } | 68 | } |
| 51 | 69 | ||
| 70 | #endif /* CONFIG_MIPS_CLOCK_VSYSCALL */ | ||
| 71 | |||
| 52 | int __vdso_clock_getres(clockid_t clock_id, | 72 | int __vdso_clock_getres(clockid_t clock_id, |
| 53 | struct __kernel_timespec *res) | 73 | struct __kernel_timespec *res) |
| 54 | { | 74 | { |
| @@ -62,6 +62,7 @@ config PARISC · 61 unmodified lines | |||
| 62 | select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE | 62 | select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE |
| 63 | select HAVE_KPROBES_ON_FTRACE | 63 | select HAVE_KPROBES_ON_FTRACE |
| 64 | select HAVE_DYNAMIC_FTRACE_WITH_REGS | 64 | select HAVE_DYNAMIC_FTRACE_WITH_REGS |
| 65 | select HAVE_COPY_THREAD_TLS | ||
| 65 | 66 | ||
| 66 | help | 67 | help |
| 67 | The PA-RISC microprocessor is designed by Hewlett-Packard and used | 68 | The PA-RISC microprocessor is designed by Hewlett-Packard and used |
| @@ -208,8 +208,8 @@ arch_initcall(parisc_idle_init); · 207 unmodified lines | |||
| 208 | * Copy architecture-specific thread state | 208 | * Copy architecture-specific thread state |
| 209 | */ | 209 | */ |
| 210 | int | 210 | int |
| 211 | copy_thread(unsigned long clone_flags, unsigned long usp, | 211 | copy_thread_tls(unsigned long clone_flags, unsigned long usp, |
| 212 | unsigned long kthread_arg, struct task_struct *p) | 212 | unsigned long kthread_arg, struct task_struct *p, unsigned long tls) |
| 213 | { | 213 | { |
| 214 | struct pt_regs *cregs = &(p->thread.regs); | 214 | struct pt_regs *cregs = &(p->thread.regs); |
| 215 | void *stack = task_stack_page(p); | 215 | void *stack = task_stack_page(p); |
| @@ -254,9 +254,9 @@ copy_thread(unsigned long clone_flags, unsigned long usp, · 38 unmodified lines | |||
| 254 | cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; | 254 | cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; |
| 255 | cregs->kpc = (unsigned long) &child_return; | 255 | cregs->kpc = (unsigned long) &child_return; |
| 256 | 256 | ||
| 257 | /* Setup thread TLS area from the 4th parameter in clone */ | 257 | /* Setup thread TLS area */ |
| 258 | if (clone_flags & CLONE_SETTLS) | 258 | if (clone_flags & CLONE_SETTLS) |
| 259 | cregs->cr27 = cregs->gr[23]; | 259 | cregs->cr27 = tls; |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | return 0; | 262 | return 0; |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | * | 15 | * |
| 16 | * (the type definitions are in asm/spinlock_types.h) | 16 | * (the type definitions are in asm/spinlock_types.h) |
| 17 | */ | 17 | */ |
| 18 | #include <linux/jump_label.h> | ||
| 18 | #include <linux/irqflags.h> | 19 | #include <linux/irqflags.h> |
| 19 | #ifdef CONFIG_PPC64 | 20 | #ifdef CONFIG_PPC64 |
| 20 | #include <asm/paca.h> | 21 | #include <asm/paca.h> |
| @@ -151,10 +151,9 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size, · 150 unmodified lines | |||
| 151 | { | 151 | { |
| 152 | unsigned long start_pfn = start >> PAGE_SHIFT; | 152 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 153 | unsigned long nr_pages = size >> PAGE_SHIFT; | 153 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 154 | struct page *page = pfn_to_page(start_pfn) + vmem_altmap_offset(altmap); | ||
| 155 | int ret; | 154 | int ret; |
| 156 | 155 | ||
| 157 | __remove_pages(page_zone(page), start_pfn, nr_pages, altmap); | 156 | __remove_pages(start_pfn, nr_pages, altmap); |
| 158 | 157 | ||
| 159 | /* Remove htab bolted mappings for this section of memory */ | 158 | /* Remove htab bolted mappings for this section of memory */ |
| 160 | start = (unsigned long)__va(start); | 159 | start = (unsigned long)__va(start); |
| @@ -50,7 +50,7 @@ static void slice_print_mask(const char *label, const struct slice_mask *mask) { · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | #endif | 51 | #endif |
| 52 | 52 | ||
| 53 | static inline bool slice_addr_is_low(unsigned long addr) | 53 | static inline notrace bool slice_addr_is_low(unsigned long addr) |
| 54 | { | 54 | { |
| 55 | u64 tmp = (u64)addr; | 55 | u64 tmp = (u64)addr; |
| 56 | 56 | ||
| @@ -659,7 +659,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, · 602 unmodified lines | |||
| 659 | mm_ctx_user_psize(¤t->mm->context), 1); | 659 | mm_ctx_user_psize(¤t->mm->context), 1); |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr) | 662 | unsigned int notrace get_slice_psize(struct mm_struct *mm, unsigned long addr) |
| 663 | { | 663 | { |
| 664 | unsigned char *psizes; | 664 | unsigned char *psizes; |
| 665 | int index, mask_index; | 665 | int index, mask_index; |
| @@ -64,6 +64,8 @@ config RISCV · 63 unmodified lines | |||
| 64 | select SPARSEMEM_STATIC if 32BIT | 64 | select SPARSEMEM_STATIC if 32BIT |
| 65 | select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU | 65 | select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU |
| 66 | select HAVE_ARCH_MMAP_RND_BITS if MMU | 66 | select HAVE_ARCH_MMAP_RND_BITS if MMU |
| 67 | select ARCH_HAS_GCOV_PROFILE_ALL | ||
| 68 | select HAVE_COPY_THREAD_TLS | ||
| 67 | 69 | ||
| 68 | config ARCH_MMAP_RND_BITS_MIN | 70 | config ARCH_MMAP_RND_BITS_MIN |
| 69 | default 18 if 64BIT | 71 | default 18 if 64BIT |
| @@ -54,6 +54,7 @@ · 53 unmodified lines | |||
| 54 | reg = <1>; | 54 | reg = <1>; |
| 55 | riscv,isa = "rv64imafdc"; | 55 | riscv,isa = "rv64imafdc"; |
| 56 | tlb-split; | 56 | tlb-split; |
| 57 | next-level-cache = <&l2cache>; | ||
| 57 | cpu1_intc: interrupt-controller { | 58 | cpu1_intc: interrupt-controller { |
| 58 | #interrupt-cells = <1>; | 59 | #interrupt-cells = <1>; |
| 59 | compatible = "riscv,cpu-intc"; | 60 | compatible = "riscv,cpu-intc"; |
| @@ -77,6 +78,7 @@ · 17 unmodified lines | |||
| 77 | reg = <2>; | 78 | reg = <2>; |
| 78 | riscv,isa = "rv64imafdc"; | 79 | riscv,isa = "rv64imafdc"; |
| 79 | tlb-split; | 80 | tlb-split; |
| 81 | next-level-cache = <&l2cache>; | ||
| 80 | cpu2_intc: interrupt-controller { | 82 | cpu2_intc: interrupt-controller { |
| 81 | #interrupt-cells = <1>; | 83 | #interrupt-cells = <1>; |
| 82 | compatible = "riscv,cpu-intc"; | 84 | compatible = "riscv,cpu-intc"; |
| @@ -100,6 +102,7 @@ · 17 unmodified lines | |||
| 100 | reg = <3>; | 102 | reg = <3>; |
| 101 | riscv,isa = "rv64imafdc"; | 103 | riscv,isa = "rv64imafdc"; |
| 102 | tlb-split; | 104 | tlb-split; |
| 105 | next-level-cache = <&l2cache>; | ||
| 103 | cpu3_intc: interrupt-controller { | 106 | cpu3_intc: interrupt-controller { |
| 104 | #interrupt-cells = <1>; | 107 | #interrupt-cells = <1>; |
| 105 | compatible = "riscv,cpu-intc"; | 108 | compatible = "riscv,cpu-intc"; |
| @@ -123,6 +126,7 @@ · 17 unmodified lines | |||
| 123 | reg = <4>; | 126 | reg = <4>; |
| 124 | riscv,isa = "rv64imafdc"; | 127 | riscv,isa = "rv64imafdc"; |
| 125 | tlb-split; | 128 | tlb-split; |
| 129 | next-level-cache = <&l2cache>; | ||
| 126 | cpu4_intc: interrupt-controller { | 130 | cpu4_intc: interrupt-controller { |
| 127 | #interrupt-cells = <1>; | 131 | #interrupt-cells = <1>; |
| 128 | compatible = "riscv,cpu-intc"; | 132 | compatible = "riscv,cpu-intc"; |
| @@ -253,6 +257,17 @@ · 124 unmodified lines | |||
| 253 | #pwm-cells = <3>; | 257 | #pwm-cells = <3>; |
| 254 | status = "disabled"; | 258 | status = "disabled"; |
| 255 | }; | 259 | }; |
| 260 | l2cache: cache-controller@2010000 { | ||
| 261 | compatible = "sifive,fu540-c000-ccache", "cache"; | ||
| 262 | cache-block-size = <64>; | ||
| 263 | cache-level = <2>; | ||
| 264 | cache-sets = <1024>; | ||
| 265 | cache-size = <2097152>; | ||
| 266 | cache-unified; | ||
| 267 | interrupt-parent = <&plic0>; | ||
| 268 | interrupts = <1 2 3>; | ||
| 269 | reg = <0x0 0x2010000 0x0 0x1000>; | ||
| 270 | }; | ||
| 256 | 271 | ||
| 257 | }; | 272 | }; |
| 258 | }; | 273 | }; |
| @@ -116,9 +116,9 @@ · 115 unmodified lines | |||
| 116 | # define SR_PIE SR_MPIE | 116 | # define SR_PIE SR_MPIE |
| 117 | # define SR_PP SR_MPP | 117 | # define SR_PP SR_MPP |
| 118 | 118 | ||
| 119 | # define IRQ_SOFT IRQ_M_SOFT | 119 | # define RV_IRQ_SOFT IRQ_M_SOFT |
| 120 | # define IRQ_TIMER IRQ_M_TIMER | 120 | # define RV_IRQ_TIMER IRQ_M_TIMER |
| 121 | # define IRQ_EXT IRQ_M_EXT | 121 | # define RV_IRQ_EXT IRQ_M_EXT |
| 122 | #else /* CONFIG_RISCV_M_MODE */ | 122 | #else /* CONFIG_RISCV_M_MODE */ |
| 123 | # define CSR_STATUS CSR_SSTATUS | 123 | # define CSR_STATUS CSR_SSTATUS |
| 124 | # define CSR_IE CSR_SIE | 124 | # define CSR_IE CSR_SIE |
| @@ -133,15 +133,15 @@ · 8 unmodified lines | |||
| 133 | # define SR_PIE SR_SPIE | 133 | # define SR_PIE SR_SPIE |
| 134 | # define SR_PP SR_SPP | 134 | # define SR_PP SR_SPP |
| 135 | 135 | ||
| 136 | # define IRQ_SOFT IRQ_S_SOFT | 136 | # define RV_IRQ_SOFT IRQ_S_SOFT |
| 137 | # define IRQ_TIMER IRQ_S_TIMER | 137 | # define RV_IRQ_TIMER IRQ_S_TIMER |
| 138 | # define IRQ_EXT IRQ_S_EXT | 138 | # define RV_IRQ_EXT IRQ_S_EXT |
| 139 | #endif /* CONFIG_RISCV_M_MODE */ | 139 | #endif /* CONFIG_RISCV_M_MODE */ |
| 140 | 140 | ||
| 141 | /* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */ | 141 | /* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */ |
| 142 | #define IE_SIE (_AC(0x1, UL) << IRQ_SOFT) | 142 | #define IE_SIE (_AC(0x1, UL) << RV_IRQ_SOFT) |
| 143 | #define IE_TIE (_AC(0x1, UL) << IRQ_TIMER) | 143 | #define IE_TIE (_AC(0x1, UL) << RV_IRQ_TIMER) |
| 144 | #define IE_EIE (_AC(0x1, UL) << IRQ_EXT) | 144 | #define IE_EIE (_AC(0x1, UL) << RV_IRQ_EXT) |
| 145 | 145 | ||
| 146 | #ifndef __ASSEMBLY__ | 146 | #ifndef __ASSEMBLY__ |
| 147 | 147 | ||
| @@ -246,6 +246,7 @@ check_syscall_nr: · 245 unmodified lines | |||
| 246 | */ | 246 | */ |
| 247 | li t1, -1 | 247 | li t1, -1 |
| 248 | beq a7, t1, ret_from_syscall_rejected | 248 | beq a7, t1, ret_from_syscall_rejected |
| 249 | blt a7, t1, 1f | ||
| 249 | /* Call syscall */ | 250 | /* Call syscall */ |
| 250 | la s0, sys_call_table | 251 | la s0, sys_call_table |
| 251 | slli t0, a7, RISCV_LGPTR | 252 | slli t0, a7, RISCV_LGPTR |
| @@ -142,7 +142,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, · 141 unmodified lines | |||
| 142 | */ | 142 | */ |
| 143 | old = *parent; | 143 | old = *parent; |
| 144 | 144 | ||
| 145 | if (function_graph_enter(old, self_addr, frame_pointer, parent)) | 145 | if (!function_graph_enter(old, self_addr, frame_pointer, parent)) |
| 146 | *parent = return_hooker; | 146 | *parent = return_hooker; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| @@ -251,7 +251,7 @@ ENTRY(reset_regs) · 250 unmodified lines | |||
| 251 | #ifdef CONFIG_FPU | 251 | #ifdef CONFIG_FPU |
| 252 | csrr t0, CSR_MISA | 252 | csrr t0, CSR_MISA |
| 253 | andi t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D) | 253 | andi t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D) |
| 254 | bnez t0, .Lreset_regs_done | 254 | beqz t0, .Lreset_regs_done |
| 255 | 255 | ||
| 256 | li t1, SR_FS | 256 | li t1, SR_FS |
| 257 | csrs CSR_STATUS, t1 | 257 | csrs CSR_STATUS, t1 |
| @@ -23,11 +23,11 @@ asmlinkage __visible void __irq_entry do_IRQ(struct pt_regs *regs) · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | irq_enter(); | 24 | irq_enter(); |
| 25 | switch (regs->cause & ~CAUSE_IRQ_FLAG) { | 25 | switch (regs->cause & ~CAUSE_IRQ_FLAG) { |
| 26 | case IRQ_TIMER: | 26 | case RV_IRQ_TIMER: |
| 27 | riscv_timer_interrupt(); | 27 | riscv_timer_interrupt(); |
| 28 | break; | 28 | break; |
| 29 | #ifdef CONFIG_SMP | 29 | #ifdef CONFIG_SMP |
| 30 | case IRQ_SOFT: | 30 | case RV_IRQ_SOFT: |
| 31 | /* | 31 | /* |
| 32 | * We only use software interrupts to pass IPIs, so if a non-SMP | 32 | * We only use software interrupts to pass IPIs, so if a non-SMP |
| 33 | * system gets one, then we don't know what to do. | 33 | * system gets one, then we don't know what to do. |
| @@ -35,7 +35,7 @@ asmlinkage __visible void __irq_entry do_IRQ(struct pt_regs *regs) · 1 unmodified line | |||
| 35 | riscv_software_interrupt(); | 35 | riscv_software_interrupt(); |
| 36 | break; | 36 | break; |
| 37 | #endif | 37 | #endif |
| 38 | case IRQ_EXT: | 38 | case RV_IRQ_EXT: |
| 39 | handle_arch_irq(regs); | 39 | handle_arch_irq(regs); |
| 40 | break; | 40 | break; |
| 41 | default: | 41 | default: |
| @@ -99,8 +99,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) · 98 unmodified lines | |||
| 99 | return 0; | 99 | return 0; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 102 | int copy_thread_tls(unsigned long clone_flags, unsigned long usp, |
| 103 | unsigned long arg, struct task_struct *p) | 103 | unsigned long arg, struct task_struct *p, unsigned long tls) |
| 104 | { | 104 | { |
| 105 | struct pt_regs *childregs = task_pt_regs(p); | 105 | struct pt_regs *childregs = task_pt_regs(p); |
| 106 | 106 | ||
| @@ -121,7 +121,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, · 14 unmodified lines | |||
| 121 | if (usp) /* User fork */ | 121 | if (usp) /* User fork */ |
| 122 | childregs->sp = usp; | 122 | childregs->sp = usp; |
| 123 | if (clone_flags & CLONE_SETTLS) | 123 | if (clone_flags & CLONE_SETTLS) |
| 124 | childregs->tp = childregs->a5; | 124 | childregs->tp = tls; |
| 125 | childregs->a0 = 0; /* Return value of fork() */ | 125 | childregs->a0 = 0; /* Return value of fork() */ |
| 126 | p->thread.ra = (unsigned long)ret_from_fork; | 126 | p->thread.ra = (unsigned long)ret_from_fork; |
| 127 | } | 127 | } |
| @@ -9,8 +9,5 @@ · 8 unmodified lines | |||
| 9 | /* | 9 | /* |
| 10 | * Assembly functions that may be used (directly or indirectly) by modules | 10 | * Assembly functions that may be used (directly or indirectly) by modules |
| 11 | */ | 11 | */ |
| 12 | EXPORT_SYMBOL(__clear_user); | ||
| 13 | EXPORT_SYMBOL(__asm_copy_to_user); | ||
| 14 | EXPORT_SYMBOL(__asm_copy_from_user); | ||
| 15 | EXPORT_SYMBOL(memset); | 12 | EXPORT_SYMBOL(memset); |
| 16 | EXPORT_SYMBOL(memcpy); | 13 | EXPORT_SYMBOL(memcpy); |
| @@ -1,4 +1,5 @@ | |||
| 1 | #include <linux/linkage.h> | 1 | #include <linux/linkage.h> |
| 2 | #include <asm-generic/export.h> | ||
| 2 | #include <asm/asm.h> | 3 | #include <asm/asm.h> |
| 3 | #include <asm/csr.h> | 4 | #include <asm/csr.h> |
| 4 | 5 | ||
| @@ -66,6 +67,8 @@ ENTRY(__asm_copy_from_user) · 61 unmodified lines | |||
| 66 | j 3b | 67 | j 3b |
| 67 | ENDPROC(__asm_copy_to_user) | 68 | ENDPROC(__asm_copy_to_user) |
| 68 | ENDPROC(__asm_copy_from_user) | 69 | ENDPROC(__asm_copy_from_user) |
| 70 | EXPORT_SYMBOL(__asm_copy_to_user) | ||
| 71 | EXPORT_SYMBOL(__asm_copy_from_user) | ||
| 69 | 72 | ||
| 70 | 73 | ||
| 71 | ENTRY(__clear_user) | 74 | ENTRY(__clear_user) |
| @@ -108,6 +111,7 @@ ENTRY(__clear_user) · 36 unmodified lines | |||
| 108 | bltu a0, a3, 5b | 111 | bltu a0, a3, 5b |
| 109 | j 3b | 112 | j 3b |
| 110 | ENDPROC(__clear_user) | 113 | ENDPROC(__clear_user) |
| 114 | EXPORT_SYMBOL(__clear_user) | ||
| 111 | 115 | ||
| 112 | .section .fixup,"ax" | 116 | .section .fixup,"ax" |
| 113 | .balign 4 | 117 | .balign 4 |
| @@ -22,6 +22,7 @@ void flush_icache_all(void) · 21 unmodified lines | |||
| 22 | else | 22 | else |
| 23 | on_each_cpu(ipi_remote_fence_i, NULL, 1); | 23 | on_each_cpu(ipi_remote_fence_i, NULL, 1); |
| 24 | } | 24 | } |
| 25 | EXPORT_SYMBOL(flush_icache_all); | ||
| 25 | 26 | ||
| 26 | /* | 27 | /* |
| 27 | * Performs an icache flush for the given MM context. RISC-V has no direct | 28 | * Performs an icache flush for the given MM context. RISC-V has no direct |
| @@ -99,13 +99,13 @@ static void __init setup_initrd(void) · 98 unmodified lines | |||
| 99 | pr_info("initrd not found or empty"); | 99 | pr_info("initrd not found or empty"); |
| 100 | goto disable; | 100 | goto disable; |
| 101 | } | 101 | } |
| 102 | if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { | 102 | if (__pa_symbol(initrd_end) > PFN_PHYS(max_low_pfn)) { |
| 103 | pr_err("initrd extends beyond end of memory"); | 103 | pr_err("initrd extends beyond end of memory"); |
| 104 | goto disable; | 104 | goto disable; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | size = initrd_end - initrd_start; | 107 | size = initrd_end - initrd_start; |
| 108 | memblock_reserve(__pa(initrd_start), size); | 108 | memblock_reserve(__pa_symbol(initrd_start), size); |
| 109 | initrd_below_start_ok = 1; | 109 | initrd_below_start_ok = 1; |
| 110 | 110 | ||
| 111 | pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n", | 111 | pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n", |
| @@ -124,8 +124,8 @@ void __init setup_bootmem(void) · 12 unmodified lines | |||
| 124 | { | 124 | { |
| 125 | struct memblock_region *reg; | 125 | struct memblock_region *reg; |
| 126 | phys_addr_t mem_size = 0; | 126 | phys_addr_t mem_size = 0; |
| 127 | phys_addr_t vmlinux_end = __pa(&_end); | 127 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 128 | phys_addr_t vmlinux_start = __pa(&_start); | 128 | phys_addr_t vmlinux_start = __pa_symbol(&_start); |
| 129 | 129 | ||
| 130 | /* Find the memory region containing the kernel */ | 130 | /* Find the memory region containing the kernel */ |
| 131 | for_each_memblock(memory, reg) { | 131 | for_each_memblock(memory, reg) { |
| @@ -445,7 +445,7 @@ static void __init setup_vm_final(void) · 313 unmodified lines | |||
| 445 | 445 | ||
| 446 | /* Setup swapper PGD for fixmap */ | 446 | /* Setup swapper PGD for fixmap */ |
| 447 | create_pgd_mapping(swapper_pg_dir, FIXADDR_START, | 447 | create_pgd_mapping(swapper_pg_dir, FIXADDR_START, |
| 448 | __pa(fixmap_pgd_next), | 448 | __pa_symbol(fixmap_pgd_next), |
| 449 | PGDIR_SIZE, PAGE_TABLE); | 449 | PGDIR_SIZE, PAGE_TABLE); |
| 450 | 450 | ||
| 451 | /* Map all memory banks */ | 451 | /* Map all memory banks */ |
| @@ -474,7 +474,7 @@ static void __init setup_vm_final(void) · 22 unmodified lines | |||
| 474 | clear_fixmap(FIX_PMD); | 474 | clear_fixmap(FIX_PMD); |
| 475 | 475 | ||
| 476 | /* Move to swapper page table */ | 476 | /* Move to swapper page table */ |
| 477 | csr_write(CSR_SATP, PFN_DOWN(__pa(swapper_pg_dir)) | SATP_MODE); | 477 | csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE); |
| 478 | local_flush_tlb_all(); | 478 | local_flush_tlb_all(); |
| 479 | } | 479 | } |
| 480 | #else | 480 | #else |
| @@ -292,10 +292,8 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 291 unmodified lines | |||
| 292 | { | 292 | { |
| 293 | unsigned long start_pfn = start >> PAGE_SHIFT; | 293 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 294 | unsigned long nr_pages = size >> PAGE_SHIFT; | 294 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 295 | struct zone *zone; | ||
| 296 | 295 | ||
| 297 | zone = page_zone(pfn_to_page(start_pfn)); | 296 | __remove_pages(start_pfn, nr_pages, altmap); |
| 298 | __remove_pages(zone, start_pfn, nr_pages, altmap); | ||
| 299 | vmem_remove_mapping(start, size); | 297 | vmem_remove_mapping(start, size); |
| 300 | } | 298 | } |
| 301 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 299 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
| @@ -434,9 +434,7 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 433 unmodified lines | |||
| 434 | { | 434 | { |
| 435 | unsigned long start_pfn = PFN_DOWN(start); | 435 | unsigned long start_pfn = PFN_DOWN(start); |
| 436 | unsigned long nr_pages = size >> PAGE_SHIFT; | 436 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 437 | struct zone *zone; | ||
| 438 | 437 | ||
| 439 | zone = page_zone(pfn_to_page(start_pfn)); | 438 | __remove_pages(start_pfn, nr_pages, altmap); |
| 440 | __remove_pages(zone, start_pfn, nr_pages, altmap); | ||
| 441 | } | 439 | } |
| 442 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 440 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
| @@ -14,6 +14,7 @@ config UML · 13 unmodified lines | |||
| 14 | select HAVE_FUTEX_CMPXCHG if FUTEX | 14 | select HAVE_FUTEX_CMPXCHG if FUTEX |
| 15 | select HAVE_DEBUG_KMEMLEAK | 15 | select HAVE_DEBUG_KMEMLEAK |
| 16 | select HAVE_DEBUG_BUGVERBOSE | 16 | select HAVE_DEBUG_BUGVERBOSE |
| 17 | select HAVE_COPY_THREAD_TLS | ||
| 17 | select GENERIC_IRQ_SHOW | 18 | select GENERIC_IRQ_SHOW |
| 18 | select GENERIC_CPU_DEVICES | 19 | select GENERIC_CPU_DEVICES |
| 19 | select GENERIC_CLOCKEVENTS | 20 | select GENERIC_CLOCKEVENTS |
| @@ -36,7 +36,7 @@ extern long subarch_ptrace(struct task_struct *child, long request, · 35 unmodified lines | |||
| 36 | extern unsigned long getreg(struct task_struct *child, int regno); | 36 | extern unsigned long getreg(struct task_struct *child, int regno); |
| 37 | extern int putreg(struct task_struct *child, int regno, unsigned long value); | 37 | extern int putreg(struct task_struct *child, int regno, unsigned long value); |
| 38 | 38 | ||
| 39 | extern int arch_copy_tls(struct task_struct *new); | 39 | extern int arch_set_tls(struct task_struct *new, unsigned long tls); |
| 40 | extern void clear_flushed_tls(struct task_struct *task); | 40 | extern void clear_flushed_tls(struct task_struct *task); |
| 41 | extern int syscall_trace_enter(struct pt_regs *regs); | 41 | extern int syscall_trace_enter(struct pt_regs *regs); |
| 42 | extern void syscall_trace_leave(struct pt_regs *regs); | 42 | extern void syscall_trace_leave(struct pt_regs *regs); |
| @@ -153,8 +153,8 @@ void fork_handler(void) · 152 unmodified lines | |||
| 153 | userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); | 153 | userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | int copy_thread(unsigned long clone_flags, unsigned long sp, | 156 | int copy_thread_tls(unsigned long clone_flags, unsigned long sp, |
| 157 | unsigned long arg, struct task_struct * p) | 157 | unsigned long arg, struct task_struct * p, unsigned long tls) |
| 158 | { | 158 | { |
| 159 | void (*handler)(void); | 159 | void (*handler)(void); |
| 160 | int kthread = current->flags & PF_KTHREAD; | 160 | int kthread = current->flags & PF_KTHREAD; |
| @@ -188,7 +188,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, · 27 unmodified lines | |||
| 188 | * Set a new TLS for the child thread? | 188 | * Set a new TLS for the child thread? |
| 189 | */ | 189 | */ |
| 190 | if (clone_flags & CLONE_SETTLS) | 190 | if (clone_flags & CLONE_SETTLS) |
| 191 | ret = arch_copy_tls(p); | 191 | ret = arch_set_tls(p, tls); |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | return ret; | 194 | return ret; |
| @@ -865,10 +865,8 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 864 unmodified lines | |||
| 865 | { | 865 | { |
| 866 | unsigned long start_pfn = start >> PAGE_SHIFT; | 866 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 867 | unsigned long nr_pages = size >> PAGE_SHIFT; | 867 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 868 | struct zone *zone; | ||
| 869 | 868 | ||
| 870 | zone = page_zone(pfn_to_page(start_pfn)); | 869 | __remove_pages(start_pfn, nr_pages, altmap); |
| 871 | __remove_pages(zone, start_pfn, nr_pages, altmap); | ||
| 872 | } | 870 | } |
| 873 | #endif | 871 | #endif |
| 874 | 872 | ||
| @@ -1212,10 +1212,8 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size, · 1211 unmodified lines | |||
| 1212 | { | 1212 | { |
| 1213 | unsigned long start_pfn = start >> PAGE_SHIFT; | 1213 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 1214 | unsigned long nr_pages = size >> PAGE_SHIFT; | 1214 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 1215 | struct page *page = pfn_to_page(start_pfn) + vmem_altmap_offset(altmap); | ||
| 1216 | struct zone *zone = page_zone(page); | ||
| 1217 | 1215 | ||
| 1218 | __remove_pages(zone, start_pfn, nr_pages, altmap); | 1216 | __remove_pages(start_pfn, nr_pages, altmap); |
| 1219 | kernel_physical_mapping_remove(start, start + size); | 1217 | kernel_physical_mapping_remove(start, start + size); |
| 1220 | } | 1218 | } |
| 1221 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 1219 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
| @@ -215,14 +215,12 @@ static int set_tls_entry(struct task_struct* task, struct user_desc *info, · 214 unmodified lines | |||
| 215 | return 0; | 215 | return 0; |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | int arch_copy_tls(struct task_struct *new) | 218 | int arch_set_tls(struct task_struct *new, unsigned long tls) |
| 219 | { | 219 | { |
| 220 | struct user_desc info; | 220 | struct user_desc info; |
| 221 | int idx, ret = -EFAULT; | 221 | int idx, ret = -EFAULT; |
| 222 | 222 | ||
| 223 | if (copy_from_user(&info, | 223 | if (copy_from_user(&info, (void __user *) tls, sizeof(info))) |
| 224 | (void __user *) UPT_SI(&new->thread.regs.regs), | ||
| 225 | sizeof(info))) | ||
| 226 | goto out; | 224 | goto out; |
| 227 | 225 | ||
| 228 | ret = -EINVAL; | 226 | ret = -EINVAL; |
| @@ -6,14 +6,13 @@ void clear_flushed_tls(struct task_struct *task) · 5 unmodified lines | |||
| 6 | { | 6 | { |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | int arch_copy_tls(struct task_struct *t) | 9 | int arch_set_tls(struct task_struct *t, unsigned long tls) |
| 10 | { | 10 | { |
| 11 | /* | 11 | /* |
| 12 | * If CLONE_SETTLS is set, we need to save the thread id | 12 | * If CLONE_SETTLS is set, we need to save the thread id |
| 13 | * (which is argument 5, child_tid, of clone) so it can be set | 13 | * so it can be set during context switches. |
| 14 | * during context switches. | ||
| 15 | */ | 14 | */ |
| 16 | t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)]; | 15 | t->thread.arch.fs = tls; |
| 17 | 16 | ||
| 18 | return 0; | 17 | return 0; |
| 19 | } | 18 | } |
| @@ -24,6 +24,7 @@ config XTENSA · 23 unmodified lines | |||
| 24 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL | 24 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL |
| 25 | select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL | 25 | select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL |
| 26 | select HAVE_ARCH_TRACEHOOK | 26 | select HAVE_ARCH_TRACEHOOK |
| 27 | select HAVE_COPY_THREAD_TLS | ||
| 27 | select HAVE_DEBUG_KMEMLEAK | 28 | select HAVE_DEBUG_KMEMLEAK |
| 28 | select HAVE_DMA_CONTIGUOUS | 29 | select HAVE_DMA_CONTIGUOUS |
| 29 | select HAVE_EXIT_THREAD | 30 | select HAVE_EXIT_THREAD |
| @@ -202,8 +202,9 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) · 201 unmodified lines | |||
| 202 | * involved. Much simpler to just not copy those live frames across. | 202 | * involved. Much simpler to just not copy those live frames across. |
| 203 | */ | 203 | */ |
| 204 | 204 | ||
| 205 | int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, | 205 | int copy_thread_tls(unsigned long clone_flags, unsigned long usp_thread_fn, |
| 206 | unsigned long thread_fn_arg, struct task_struct *p) | 206 | unsigned long thread_fn_arg, struct task_struct *p, |
| 207 | unsigned long tls) | ||
| 207 | { | 208 | { |
| 208 | struct pt_regs *childregs = task_pt_regs(p); | 209 | struct pt_regs *childregs = task_pt_regs(p); |
| 209 | 210 | ||
| @@ -266,9 +267,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, · 56 unmodified lines | |||
| 266 | 267 | ||
| 267 | childregs->syscall = regs->syscall; | 268 | childregs->syscall = regs->syscall; |
| 268 | 269 | ||
| 269 | /* The thread pointer is passed in the '4th argument' (= a5) */ | ||
| 270 | if (clone_flags & CLONE_SETTLS) | 270 | if (clone_flags & CLONE_SETTLS) |
| 271 | childregs->threadptr = childregs->areg[5]; | 271 | childregs->threadptr = tls; |
| 272 | } else { | 272 | } else { |
| 273 | p->thread.ra = MAKE_RA_FOR_CALL( | 273 | p->thread.ra = MAKE_RA_FOR_CALL( |
| 274 | (unsigned long)ret_from_kernel_thread, 1); | 274 | (unsigned long)ret_from_kernel_thread, 1); |
| @@ -538,6 +538,55 @@ void zero_fill_bio_iter(struct bio *bio, struct bvec_iter start) · 537 unmodified lines | |||
| 538 | } | 538 | } |
| 539 | EXPORT_SYMBOL(zero_fill_bio_iter); | 539 | EXPORT_SYMBOL(zero_fill_bio_iter); |
| 540 | 540 | ||
| 541 | /** | ||
| 542 | * bio_truncate - truncate the bio to small size of @new_size | ||
| 543 | * @bio: the bio to be truncated | ||
| 544 | * @new_size: new size for truncating the bio | ||
| 545 | * | ||
| 546 | * Description: | ||
| 547 | * Truncate the bio to new size of @new_size. If bio_op(bio) is | ||
| 548 | * REQ_OP_READ, zero the truncated part. This function should only | ||
| 549 | * be used for handling corner cases, such as bio eod. | ||
| 550 | */ | ||
| 551 | void bio_truncate(struct bio *bio, unsigned new_size) | ||
| 552 | { | ||
| 553 | struct bio_vec bv; | ||
| 554 | struct bvec_iter iter; | ||
| 555 | unsigned int done = 0; | ||
| 556 | bool truncated = false; | ||
| 557 | |||
| 558 | if (new_size >= bio->bi_iter.bi_size) | ||
| 559 | return; | ||
| 560 | |||
| 561 | if (bio_op(bio) != REQ_OP_READ) | ||
| 562 | goto exit; | ||
| 563 | |||
| 564 | bio_for_each_segment(bv, bio, iter) { | ||
| 565 | if (done + bv.bv_len > new_size) { | ||
| 566 | unsigned offset; | ||
| 567 | |||
| 568 | if (!truncated) | ||
| 569 | offset = new_size - done; | ||
| 570 | else | ||
| 571 | offset = 0; | ||
| 572 | zero_user(bv.bv_page, offset, bv.bv_len - offset); | ||
| 573 | truncated = true; | ||
| 574 | } | ||
| 575 | done += bv.bv_len; | ||
| 576 | } | ||
| 577 | |||
| 578 | exit: | ||
| 579 | /* | ||
| 580 | * Don't touch bvec table here and make it really immutable, since | ||
| 581 | * fs bio user has to retrieve all pages via bio_for_each_segment_all | ||
| 582 | * in its .end_bio() callback. | ||
| 583 | * | ||
| 584 | * It is enough to truncate bio by updating .bi_size since we can make | ||
| 585 | * correct bvec with the updated .bi_size for drivers. | ||
| 586 | */ | ||
| 587 | bio->bi_iter.bi_size = new_size; | ||
| 588 | } | ||
| 589 | |||
| 541 | /** | 590 | /** |
| 542 | * bio_put - release a reference to a bio | 591 | * bio_put - release a reference to a bio |
| 543 | * @bio: bio to release reference to | 592 | * @bio: bio to release reference to |
| @@ -157,16 +157,14 @@ static inline unsigned get_max_io_size(struct request_queue *q, · 156 unmodified lines | |||
| 157 | return sectors & (lbs - 1); | 157 | return sectors & (lbs - 1); |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static unsigned get_max_segment_size(const struct request_queue *q, | 160 | static inline unsigned get_max_segment_size(const struct request_queue *q, |
| 161 | unsigned offset) | 161 | struct page *start_page, |
| 162 | unsigned long offset) | ||
| 162 | { | 163 | { |
| 163 | unsigned long mask = queue_segment_boundary(q); | 164 | unsigned long mask = queue_segment_boundary(q); |
| 164 | 165 | ||
| 165 | /* default segment boundary mask means no boundary limit */ | 166 | offset = mask & (page_to_phys(start_page) + offset); |
| 166 | if (mask == BLK_SEG_BOUNDARY_MASK) | 167 | return min_t(unsigned long, mask - offset + 1, |
| 167 | return queue_max_segment_size(q); | ||
| 168 | |||
| 169 | return min_t(unsigned long, mask - (mask & offset) + 1, | ||
| 170 | queue_max_segment_size(q)); | 168 | queue_max_segment_size(q)); |
| 171 | } | 169 | } |
| 172 | 170 | ||
| @@ -201,7 +199,8 @@ static bool bvec_split_segs(const struct request_queue *q, · 28 unmodified lines | |||
| 201 | unsigned seg_size = 0; | 199 | unsigned seg_size = 0; |
| 202 | 200 | ||
| 203 | while (len && *nsegs < max_segs) { | 201 | while (len && *nsegs < max_segs) { |
| 204 | seg_size = get_max_segment_size(q, bv->bv_offset + total_len); | 202 | seg_size = get_max_segment_size(q, bv->bv_page, |
| 203 | bv->bv_offset + total_len); | ||
| 205 | seg_size = min(seg_size, len); | 204 | seg_size = min(seg_size, len); |
| 206 | 205 | ||
| 207 | (*nsegs)++; | 206 | (*nsegs)++; |
| @@ -419,7 +418,8 @@ static unsigned blk_bvec_map_sg(struct request_queue *q, · 211 unmodified lines | |||
| 419 | 418 | ||
| 420 | while (nbytes > 0) { | 419 | while (nbytes > 0) { |
| 421 | unsigned offset = bvec->bv_offset + total; | 420 | unsigned offset = bvec->bv_offset + total; |
| 422 | unsigned len = min(get_max_segment_size(q, offset), nbytes); | 421 | unsigned len = min(get_max_segment_size(q, bvec->bv_page, |
| 422 | offset), nbytes); | ||
| 423 | struct page *page = bvec->bv_page; | 423 | struct page *page = bvec->bv_page; |
| 424 | 424 | ||
| 425 | /* | 425 | /* |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/compat.h> | 6 | #include <linux/compat.h> |
| 7 | #include <linux/elevator.h> | 7 | #include <linux/elevator.h> |
| 8 | #include <linux/hdreg.h> | 8 | #include <linux/hdreg.h> |
| 9 | #include <linux/pr.h> | ||
| 9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
| 10 | #include <linux/syscalls.h> | 11 | #include <linux/syscalls.h> |
| 11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| @@ -354,6 +355,13 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) · 342 unmodified lines | |||
| 354 | * but we call blkdev_ioctl, which gets the lock for us | 355 | * but we call blkdev_ioctl, which gets the lock for us |
| 355 | */ | 356 | */ |
| 356 | case BLKRRPART: | 357 | case BLKRRPART: |
| 358 | case BLKREPORTZONE: | ||
| 359 | case BLKRESETZONE: | ||
| 360 | case BLKOPENZONE: | ||
| 361 | case BLKCLOSEZONE: | ||
| 362 | case BLKFINISHZONE: | ||
| 363 | case BLKGETZONESZ: | ||
| 364 | case BLKGETNRZONES: | ||
| 357 | return blkdev_ioctl(bdev, mode, cmd, | 365 | return blkdev_ioctl(bdev, mode, cmd, |
| 358 | (unsigned long)compat_ptr(arg)); | 366 | (unsigned long)compat_ptr(arg)); |
| 359 | case BLKBSZSET_32: | 367 | case BLKBSZSET_32: |
| @@ -401,6 +409,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) · 41 unmodified lines | |||
| 401 | case BLKTRACETEARDOWN: /* compatible */ | 409 | case BLKTRACETEARDOWN: /* compatible */ |
| 402 | ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); | 410 | ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); |
| 403 | return ret; | 411 | return ret; |
| 412 | case IOC_PR_REGISTER: | ||
| 413 | case IOC_PR_RESERVE: | ||
| 414 | case IOC_PR_RELEASE: | ||
| 415 | case IOC_PR_PREEMPT: | ||
| 416 | case IOC_PR_PREEMPT_ABORT: | ||
| 417 | case IOC_PR_CLEAR: | ||
| 418 | return blkdev_ioctl(bdev, mode, cmd, | ||
| 419 | (unsigned long)compat_ptr(arg)); | ||
| 404 | default: | 420 | default: |
| 405 | if (disk->fops->compat_ioctl) | 421 | if (disk->fops->compat_ioctl) |
| 406 | ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg); | 422 | ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg); |
| @@ -76,8 +76,7 @@ enum brcm_ahci_version { · 75 unmodified lines | |||
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | enum brcm_ahci_quirks { | 78 | enum brcm_ahci_quirks { |
| 79 | BRCM_AHCI_QUIRK_NO_NCQ = BIT(0), | 79 | BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(0), |
| 80 | BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1), | ||
| 81 | }; | 80 | }; |
| 82 | 81 | ||
| 83 | struct brcm_ahci_priv { | 82 | struct brcm_ahci_priv { |
| @@ -213,19 +212,12 @@ static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv) · 129 unmodified lines | |||
| 213 | brcm_sata_phy_disable(priv, i); | 212 | brcm_sata_phy_disable(priv, i); |
| 214 | } | 213 | } |
| 215 | 214 | ||
| 216 | static u32 brcm_ahci_get_portmask(struct platform_device *pdev, | 215 | static u32 brcm_ahci_get_portmask(struct ahci_host_priv *hpriv, |
| 217 | struct brcm_ahci_priv *priv) | 216 | struct brcm_ahci_priv *priv) |
| 218 | { | 217 | { |
| 219 | void __iomem *ahci; | ||
| 220 | struct resource *res; | ||
| 221 | u32 impl; | 218 | u32 impl; |
| 222 | 219 | ||
| 223 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci"); | 220 | impl = readl(hpriv->mmio + HOST_PORTS_IMPL); |
| 224 | ahci = devm_ioremap_resource(&pdev->dev, res); | ||
| 225 | if (IS_ERR(ahci)) | ||
| 226 | return 0; | ||
| 227 | |||
| 228 | impl = readl(ahci + HOST_PORTS_IMPL); | ||
| 229 | 221 | ||
| 230 | if (fls(impl) > SATA_TOP_MAX_PHYS) | 222 | if (fls(impl) > SATA_TOP_MAX_PHYS) |
| 231 | dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n", | 223 | dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n", |
| @@ -233,9 +225,6 @@ static u32 brcm_ahci_get_portmask(struct platform_device *pdev, · 1 unmodified line | |||
| 233 | else if (!impl) | 225 | else if (!impl) |
| 234 | dev_info(priv->dev, "no ports found\n"); | 226 | dev_info(priv->dev, "no ports found\n"); |
| 235 | 227 | ||
| 236 | devm_iounmap(&pdev->dev, ahci); | ||
| 237 | devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); | ||
| 238 | |||
| 239 | return impl; | 228 | return impl; |
| 240 | } | 229 | } |
| 241 | 230 | ||
| @@ -285,6 +274,13 @@ static unsigned int brcm_ahci_read_id(struct ata_device *dev, · 43 unmodified lines | |||
| 285 | /* Perform the SATA PHY reset sequence */ | 274 | /* Perform the SATA PHY reset sequence */ |
| 286 | brcm_sata_phy_disable(priv, ap->port_no); | 275 | brcm_sata_phy_disable(priv, ap->port_no); |
| 287 | 276 | ||
| 277 | /* Reset the SATA clock */ | ||
| 278 | ahci_platform_disable_clks(hpriv); | ||
| 279 | msleep(10); | ||
| 280 | |||
| 281 | ahci_platform_enable_clks(hpriv); | ||
| 282 | msleep(10); | ||
| 283 | |||
| 288 | /* Bring the PHY back on */ | 284 | /* Bring the PHY back on */ |
| 289 | brcm_sata_phy_enable(priv, ap->port_no); | 285 | brcm_sata_phy_enable(priv, ap->port_no); |
| 290 | 286 | ||
| @@ -347,11 +343,10 @@ static int brcm_ahci_suspend(struct device *dev) · 56 unmodified lines | |||
| 347 | struct ata_host *host = dev_get_drvdata(dev); | 343 | struct ata_host *host = dev_get_drvdata(dev); |
| 348 | struct ahci_host_priv *hpriv = host->private_data; | 344 | struct ahci_host_priv *hpriv = host->private_data; |
| 349 | struct brcm_ahci_priv *priv = hpriv->plat_data; | 345 | struct brcm_ahci_priv *priv = hpriv->plat_data; |
| 350 | int ret; | ||
| 351 | 346 | ||
| 352 | ret = ahci_platform_suspend(dev); | ||
| 353 | brcm_sata_phys_disable(priv); | 347 | brcm_sata_phys_disable(priv); |
| 354 | return ret; | 348 | |
| 349 | return ahci_platform_suspend(dev); | ||
| 355 | } | 350 | } |
| 356 | 351 | ||
| 357 | static int brcm_ahci_resume(struct device *dev) | 352 | static int brcm_ahci_resume(struct device *dev) |
| @@ -359,11 +354,44 @@ static int brcm_ahci_resume(struct device *dev) · 1 unmodified line | |||
| 359 | struct ata_host *host = dev_get_drvdata(dev); | 354 | struct ata_host *host = dev_get_drvdata(dev); |
| 360 | struct ahci_host_priv *hpriv = host->private_data; | 355 | struct ahci_host_priv *hpriv = host->private_data; |
| 361 | struct brcm_ahci_priv *priv = hpriv->plat_data; | 356 | struct brcm_ahci_priv *priv = hpriv->plat_data; |
| 357 | int ret; | ||
| 358 | |||
| 359 | /* Make sure clocks are turned on before re-configuration */ | ||
| 360 | ret = ahci_platform_enable_clks(hpriv); | ||
| 361 | if (ret) | ||
| 362 | return ret; | ||
| 362 | 363 | ||
| 363 | brcm_sata_init(priv); | 364 | brcm_sata_init(priv); |
| 364 | brcm_sata_phys_enable(priv); | 365 | brcm_sata_phys_enable(priv); |
| 365 | brcm_sata_alpm_init(hpriv); | 366 | brcm_sata_alpm_init(hpriv); |
| 366 | return ahci_platform_resume(dev); | 367 | |
| 368 | /* Since we had to enable clocks earlier on, we cannot use | ||
| 369 | * ahci_platform_resume() as-is since a second call to | ||
| 370 | * ahci_platform_enable_resources() would bump up the resources | ||
| 371 | * (regulators, clocks, PHYs) count artificially so we copy the part | ||
| 372 | * after ahci_platform_enable_resources(). | ||
| 373 | */ | ||
| 374 | ret = ahci_platform_enable_phys(hpriv); | ||
| 375 | if (ret) | ||
| 376 | goto out_disable_phys; | ||
| 377 | |||
| 378 | ret = ahci_platform_resume_host(dev); | ||
| 379 | if (ret) | ||
| 380 | goto out_disable_platform_phys; | ||
| 381 | |||
| 382 | /* We resumed so update PM runtime state */ | ||
| 383 | pm_runtime_disable(dev); | ||
| 384 | pm_runtime_set_active(dev); | ||
| 385 | pm_runtime_enable(dev); | ||
| 386 | |||
| 387 | return 0; | ||
| 388 | |||
| 389 | out_disable_platform_phys: | ||
| 390 | ahci_platform_disable_phys(hpriv); | ||
| 391 | out_disable_phys: | ||
| 392 | brcm_sata_phys_disable(priv); | ||
| 393 | ahci_platform_disable_clks(hpriv); | ||
| 394 | return ret; | ||
| 367 | } | 395 | } |
| 368 | #endif | 396 | #endif |
| 369 | 397 | ||
| @@ -410,44 +438,71 @@ static int brcm_ahci_probe(struct platform_device *pdev) · 40 unmodified lines | |||
| 410 | if (!IS_ERR_OR_NULL(priv->rcdev)) | 438 | if (!IS_ERR_OR_NULL(priv->rcdev)) |
| 411 | reset_control_deassert(priv->rcdev); | 439 | reset_control_deassert(priv->rcdev); |
| 412 | 440 | ||
| 413 | if ((priv->version == BRCM_SATA_BCM7425) || | 441 | hpriv = ahci_platform_get_resources(pdev, 0); |
| 414 | (priv->version == BRCM_SATA_NSP)) { | 442 | if (IS_ERR(hpriv)) { |
| 415 | priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ; | 443 | ret = PTR_ERR(hpriv); |
| 444 | goto out_reset; | ||
| 445 | } | ||
| 446 | |||
| 447 | hpriv->plat_data = priv; | ||
| 448 | hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO; | ||
| 449 | |||
| 450 | switch (priv->version) { | ||
| 451 | case BRCM_SATA_BCM7425: | ||
| 452 | hpriv->flags |= AHCI_HFLAG_DELAY_ENGINE; | ||
| 453 | /* fall through */ | ||
| 454 | case BRCM_SATA_NSP: | ||
| 455 | hpriv->flags |= AHCI_HFLAG_NO_NCQ; | ||
| 416 | priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; | 456 | priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; |
| 457 | break; | ||
| 458 | default: | ||
| 459 | break; | ||
| 417 | } | 460 | } |
| 418 | 461 | ||
| 462 | ret = ahci_platform_enable_clks(hpriv); | ||
| 463 | if (ret) | ||
| 464 | goto out_reset; | ||
| 465 | |||
| 466 | /* Must be first so as to configure endianness including that | ||
| 467 | * of the standard AHCI register space. | ||
| 468 | */ | ||
| 419 | brcm_sata_init(priv); | 469 | brcm_sata_init(priv); |
| 420 | 470 | ||
| 421 | priv->port_mask = brcm_ahci_get_portmask(pdev, priv); | 471 | /* Initializes priv->port_mask which is used below */ |
| 422 | if (!priv->port_mask) | 472 | priv->port_mask = brcm_ahci_get_portmask(hpriv, priv); |
| 423 | return -ENODEV; | 473 | if (!priv->port_mask) { |
| 474 | ret = -ENODEV; | ||
| 475 | goto out_disable_clks; | ||
| 476 | } | ||
| 424 | 477 | ||
| 478 | /* Must be done before ahci_platform_enable_phys() */ | ||
| 425 | brcm_sata_phys_enable(priv); | 479 | brcm_sata_phys_enable(priv); |
| 426 | 480 | ||
| 427 | hpriv = ahci_platform_get_resources(pdev, 0); | ||
| 428 | if (IS_ERR(hpriv)) | ||
| 429 | return PTR_ERR(hpriv); | ||
| 430 | hpriv->plat_data = priv; | ||
| 431 | hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP; | ||
| 432 | |||
| 433 | brcm_sata_alpm_init(hpriv); | 481 | brcm_sata_alpm_init(hpriv); |
| 434 | 482 | ||
| 435 | ret = ahci_platform_enable_resources(hpriv); | 483 | ret = ahci_platform_enable_phys(hpriv); |
| 436 | if (ret) | 484 | if (ret) |
| 437 | return ret; | 485 | goto out_disable_phys; |
| 438 | |||
| 439 | if (priv->quirks & BRCM_AHCI_QUIRK_NO_NCQ) | ||
| 440 | hpriv->flags |= AHCI_HFLAG_NO_NCQ; | ||
| 441 | hpriv->flags |= AHCI_HFLAG_NO_WRITE_TO_RO; | ||
| 442 | 486 | ||
| 443 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info, | 487 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info, |
| 444 | &ahci_platform_sht); | 488 | &ahci_platform_sht); |
| 445 | if (ret) | 489 | if (ret) |
| 446 | return ret; | 490 | goto out_disable_platform_phys; |
| 447 | 491 | ||
| 448 | dev_info(dev, "Broadcom AHCI SATA3 registered\n"); | 492 | dev_info(dev, "Broadcom AHCI SATA3 registered\n"); |
| 449 | 493 | ||
| 450 | return 0; | 494 | return 0; |
| 495 | |||
| 496 | out_disable_platform_phys: | ||
| 497 | ahci_platform_disable_phys(hpriv); | ||
| 498 | out_disable_phys: | ||
| 499 | brcm_sata_phys_disable(priv); | ||
| 500 | out_disable_clks: | ||
| 501 | ahci_platform_disable_clks(hpriv); | ||
| 502 | out_reset: | ||
| 503 | if (!IS_ERR_OR_NULL(priv->rcdev)) | ||
| 504 | reset_control_assert(priv->rcdev); | ||
| 505 | return ret; | ||
| 451 | } | 506 | } |
| 452 | 507 | ||
| 453 | static int brcm_ahci_remove(struct platform_device *pdev) | 508 | static int brcm_ahci_remove(struct platform_device *pdev) |
| @@ -457,12 +512,12 @@ static int brcm_ahci_remove(struct platform_device *pdev) · 3 unmodified lines | |||
| 457 | struct brcm_ahci_priv *priv = hpriv->plat_data; | 512 | struct brcm_ahci_priv *priv = hpriv->plat_data; |
| 458 | int ret; | 513 | int ret; |
| 459 | 514 | ||
| 515 | brcm_sata_phys_disable(priv); | ||
| 516 | |||
| 460 | ret = ata_platform_remove_one(pdev); | 517 | ret = ata_platform_remove_one(pdev); |
| 461 | if (ret) | 518 | if (ret) |
| 462 | return ret; | 519 | return ret; |
| 463 | 520 | ||
| 464 | brcm_sata_phys_disable(priv); | ||
| 465 | |||
| 466 | return 0; | 521 | return 0; |
| 467 | } | 522 | } |
| 468 | 523 | ||
| @@ -43,7 +43,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_ops); · 42 unmodified lines | |||
| 43 | * RETURNS: | 43 | * RETURNS: |
| 44 | * 0 on success otherwise a negative error code | 44 | * 0 on success otherwise a negative error code |
| 45 | */ | 45 | */ |
| 46 | static int ahci_platform_enable_phys(struct ahci_host_priv *hpriv) | 46 | int ahci_platform_enable_phys(struct ahci_host_priv *hpriv) |
| 47 | { | 47 | { |
| 48 | int rc, i; | 48 | int rc, i; |
| 49 | 49 | ||
| @@ -74,6 +74,7 @@ disable_phys: · 24 unmodified lines | |||
| 74 | } | 74 | } |
| 75 | return rc; | 75 | return rc; |
| 76 | } | 76 | } |
| 77 | EXPORT_SYMBOL_GPL(ahci_platform_enable_phys); | ||
| 77 | 78 | ||
| 78 | /** | 79 | /** |
| 79 | * ahci_platform_disable_phys - Disable PHYs | 80 | * ahci_platform_disable_phys - Disable PHYs |
| @@ -81,7 +82,7 @@ disable_phys: · 1 unmodified line | |||
| 81 | * | 82 | * |
| 82 | * This function disables all PHYs found in hpriv->phys. | 83 | * This function disables all PHYs found in hpriv->phys. |
| 83 | */ | 84 | */ |
| 84 | static void ahci_platform_disable_phys(struct ahci_host_priv *hpriv) | 85 | void ahci_platform_disable_phys(struct ahci_host_priv *hpriv) |
| 85 | { | 86 | { |
| 86 | int i; | 87 | int i; |
| 87 | 88 | ||
| @@ -90,6 +91,7 @@ static void ahci_platform_disable_phys(struct ahci_host_priv *hpriv) · 2 unmodified lines | |||
| 90 | phy_exit(hpriv->phys[i]); | 91 | phy_exit(hpriv->phys[i]); |
| 91 | } | 92 | } |
| 92 | } | 93 | } |
| 94 | EXPORT_SYMBOL_GPL(ahci_platform_disable_phys); | ||
| 93 | 95 | ||
| 94 | /** | 96 | /** |
| 95 | * ahci_platform_enable_clks - Enable platform clocks | 97 | * ahci_platform_enable_clks - Enable platform clocks |
| @@ -5328,6 +5328,30 @@ void ata_qc_complete(struct ata_queued_cmd *qc) · 5327 unmodified lines | |||
| 5328 | } | 5328 | } |
| 5329 | } | 5329 | } |
| 5330 | 5330 | ||
| 5331 | /** | ||
| 5332 | * ata_qc_get_active - get bitmask of active qcs | ||
| 5333 | * @ap: port in question | ||
| 5334 | * | ||
| 5335 | * LOCKING: | ||
| 5336 | * spin_lock_irqsave(host lock) | ||
| 5337 | * | ||
| 5338 | * RETURNS: | ||
| 5339 | * Bitmask of active qcs | ||
| 5340 | */ | ||
| 5341 | u64 ata_qc_get_active(struct ata_port *ap) | ||
| 5342 | { | ||
| 5343 | u64 qc_active = ap->qc_active; | ||
| 5344 | |||
| 5345 | /* ATA_TAG_INTERNAL is sent to hw as tag 0 */ | ||
| 5346 | if (qc_active & (1ULL << ATA_TAG_INTERNAL)) { | ||
| 5347 | qc_active |= (1 << 0); | ||
| 5348 | qc_active &= ~(1ULL << ATA_TAG_INTERNAL); | ||
| 5349 | } | ||
| 5350 | |||
| 5351 | return qc_active; | ||
| 5352 | } | ||
| 5353 | EXPORT_SYMBOL_GPL(ata_qc_get_active); | ||
| 5354 | |||
| 5331 | /** | 5355 | /** |
| 5332 | * ata_qc_complete_multiple - Complete multiple qcs successfully | 5356 | * ata_qc_complete_multiple - Complete multiple qcs successfully |
| 5333 | * @ap: port in question | 5357 | * @ap: port in question |
| @@ -1280,7 +1280,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) · 1279 unmodified lines | |||
| 1280 | i, ioread32(hcr_base + CC), | 1280 | i, ioread32(hcr_base + CC), |
| 1281 | ioread32(hcr_base + CA)); | 1281 | ioread32(hcr_base + CA)); |
| 1282 | } | 1282 | } |
| 1283 | ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); | 1283 | ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); |
| 1284 | return; | 1284 | return; |
| 1285 | 1285 | ||
| 1286 | } else if ((ap->qc_active & (1ULL << ATA_TAG_INTERNAL))) { | 1286 | } else if ((ap->qc_active & (1ULL << ATA_TAG_INTERNAL))) { |
| @@ -2829,7 +2829,7 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp · 2828 unmodified lines | |||
| 2829 | } | 2829 | } |
| 2830 | 2830 | ||
| 2831 | if (work_done) { | 2831 | if (work_done) { |
| 2832 | ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); | 2832 | ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); |
| 2833 | 2833 | ||
| 2834 | /* Update the software queue position index in hardware */ | 2834 | /* Update the software queue position index in hardware */ |
| 2835 | writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | | 2835 | writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | |
| @@ -984,7 +984,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) · 983 unmodified lines | |||
| 984 | check_commands = 0; | 984 | check_commands = 0; |
| 985 | check_commands &= ~(1 << pos); | 985 | check_commands &= ~(1 << pos); |
| 986 | } | 986 | } |
| 987 | ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); | 987 | ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); |
| 988 | } | 988 | } |
| 989 | } | 989 | } |
| 990 | 990 | ||
| @@ -374,7 +374,7 @@ static int do_rx_dma(struct atm_vcc *vcc,struct sk_buff *skb, · 373 unmodified lines | |||
| 374 | here = (eni_vcc->descr+skip) & (eni_vcc->words-1); | 374 | here = (eni_vcc->descr+skip) & (eni_vcc->words-1); |
| 375 | dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci | 375 | dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci |
| 376 | << MID_DMA_VCI_SHIFT) | MID_DT_JK; | 376 | << MID_DMA_VCI_SHIFT) | MID_DT_JK; |
| 377 | j++; | 377 | dma[j++] = 0; |
| 378 | } | 378 | } |
| 379 | here = (eni_vcc->descr+size+skip) & (eni_vcc->words-1); | 379 | here = (eni_vcc->descr+size+skip) & (eni_vcc->words-1); |
| 380 | if (!eff) size += skip; | 380 | if (!eff) size += skip; |
| @@ -447,7 +447,7 @@ static int do_rx_dma(struct atm_vcc *vcc,struct sk_buff *skb, · 66 unmodified lines | |||
| 447 | if (size != eff) { | 447 | if (size != eff) { |
| 448 | dma[j++] = (here << MID_DMA_COUNT_SHIFT) | | 448 | dma[j++] = (here << MID_DMA_COUNT_SHIFT) | |
| 449 | (vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK; | 449 | (vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK; |
| 450 | j++; | 450 | dma[j++] = 0; |
| 451 | } | 451 | } |
| 452 | if (!j || j > 2*RX_DMA_BUF) { | 452 | if (!j || j > 2*RX_DMA_BUF) { |
| 453 | printk(KERN_CRIT DEV_LABEL "!j or j too big!!!\n"); | 453 | printk(KERN_CRIT DEV_LABEL "!j or j too big!!!\n"); |
| @@ -186,7 +186,10 @@ static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op, · 185 unmodified lines | |||
| 186 | if (zone->cond == BLK_ZONE_COND_FULL) | 186 | if (zone->cond == BLK_ZONE_COND_FULL) |
| 187 | return BLK_STS_IOERR; | 187 | return BLK_STS_IOERR; |
| 188 | 188 | ||
| 189 | zone->cond = BLK_ZONE_COND_CLOSED; | 189 | if (zone->wp == zone->start) |
| 190 | zone->cond = BLK_ZONE_COND_EMPTY; | ||
| 191 | else | ||
| 192 | zone->cond = BLK_ZONE_COND_CLOSED; | ||
| 190 | break; | 193 | break; |
| 191 | case REQ_OP_ZONE_FINISH: | 194 | case REQ_OP_ZONE_FINISH: |
| 192 | if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) | 195 | if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) |
| @@ -2707,7 +2707,7 @@ static const struct block_device_operations pktcdvd_ops = { · 2706 unmodified lines | |||
| 2707 | .release = pkt_close, | 2707 | .release = pkt_close, |
| 2708 | .ioctl = pkt_ioctl, | 2708 | .ioctl = pkt_ioctl, |
| 2709 | #ifdef CONFIG_COMPAT | 2709 | #ifdef CONFIG_COMPAT |
| 2710 | .ioctl = pkt_compat_ioctl, | 2710 | .compat_ioctl = pkt_compat_ioctl, |
| 2711 | #endif | 2711 | #endif |
| 2712 | .check_events = pkt_check_events, | 2712 | .check_events = pkt_check_events, |
| 2713 | }; | 2713 | }; |
| @@ -84,7 +84,6 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, · 83 unmodified lines | |||
| 84 | unsigned int cdev = 0; | 84 | unsigned int cdev = 0; |
| 85 | u32 mnistat, tnistat, tstatus, mcmd; | 85 | u32 mnistat, tnistat, tstatus, mcmd; |
| 86 | u16 tnicmd, mnicmd; | 86 | u16 tnicmd, mnicmd; |
| 87 | u8 mcapndx; | ||
| 88 | u32 tot_bw = 0, tot_n = 0, tot_rq = 0, y_max, rq_isoch, rq_async; | 87 | u32 tot_bw = 0, tot_n = 0, tot_rq = 0, y_max, rq_isoch, rq_async; |
| 89 | u32 step, rem, rem_isoch, rem_async; | 88 | u32 step, rem, rem_isoch, rem_async; |
| 90 | int ret = 0; | 89 | int ret = 0; |
| @@ -138,8 +137,6 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, · 47 unmodified lines | |||
| 138 | cur = list_entry(pos, struct agp_3_5_dev, list); | 137 | cur = list_entry(pos, struct agp_3_5_dev, list); |
| 139 | dev = cur->dev; | 138 | dev = cur->dev; |
| 140 | 139 | ||
| 141 | mcapndx = cur->capndx; | ||
| 142 | |||
| 143 | pci_read_config_dword(dev, cur->capndx+AGPNISTAT, &mnistat); | 140 | pci_read_config_dword(dev, cur->capndx+AGPNISTAT, &mnistat); |
| 144 | 141 | ||
| 145 | master[cdev].maxbw = (mnistat >> 16) & 0xff; | 142 | master[cdev].maxbw = (mnistat >> 16) & 0xff; |
| @@ -251,8 +248,6 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, · 105 unmodified lines | |||
| 251 | cur = master[cdev].dev; | 248 | cur = master[cdev].dev; |
| 252 | dev = cur->dev; | 249 | dev = cur->dev; |
| 253 | 250 | ||
| 254 | mcapndx = cur->capndx; | ||
| 255 | |||
| 256 | master[cdev].rq += (cdev == ndevs - 1) | 251 | master[cdev].rq += (cdev == ndevs - 1) |
| 257 | ? (rem_async + rem_isoch) : step; | 252 | ? (rem_async + rem_isoch) : step; |
| 258 | 253 | ||
| @@ -319,7 +314,7 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) · 60 unmodified lines | |||
| 319 | { | 314 | { |
| 320 | struct pci_dev *td = bridge->dev, *dev = NULL; | 315 | struct pci_dev *td = bridge->dev, *dev = NULL; |
| 321 | u8 mcapndx; | 316 | u8 mcapndx; |
| 322 | u32 isoch, arqsz; | 317 | u32 isoch; |
| 323 | u32 tstatus, mstatus, ncapid; | 318 | u32 tstatus, mstatus, ncapid; |
| 324 | u32 mmajor; | 319 | u32 mmajor; |
| 325 | u16 mpstat; | 320 | u16 mpstat; |
| @@ -334,8 +329,6 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) · 8 unmodified lines | |||
| 334 | if (isoch == 0) /* isoch xfers not available, bail out. */ | 329 | if (isoch == 0) /* isoch xfers not available, bail out. */ |
| 335 | return -ENODEV; | 330 | return -ENODEV; |
| 336 | 331 | ||
| 337 | arqsz = (tstatus >> 13) & 0x7; | ||
| 338 | |||
| 339 | /* | 332 | /* |
| 340 | * Allocate a head for our AGP 3.5 device list | 333 | * Allocate a head for our AGP 3.5 device list |
| 341 | * (multiple AGP v3 devices are allowed behind a single bridge). | 334 | * (multiple AGP v3 devices are allowed behind a single bridge). |
| @@ -130,7 +130,7 @@ ssize_t tpm_common_read(struct file *file, char __user *buf, · 129 unmodified lines | |||
| 130 | priv->response_read = true; | 130 | priv->response_read = true; |
| 131 | 131 | ||
| 132 | ret_size = min_t(ssize_t, size, priv->response_length); | 132 | ret_size = min_t(ssize_t, size, priv->response_length); |
| 133 | if (!ret_size) { | 133 | if (ret_size <= 0) { |
| 134 | priv->response_length = 0; | 134 | priv->response_length = 0; |
| 135 | goto out; | 135 | goto out; |
| 136 | } | 136 | } |
| @@ -14,7 +14,7 @@ struct file_priv { · 13 unmodified lines | |||
| 14 | struct work_struct timeout_work; | 14 | struct work_struct timeout_work; |
| 15 | struct work_struct async_work; | 15 | struct work_struct async_work; |
| 16 | wait_queue_head_t async_wait; | 16 | wait_queue_head_t async_wait; |
| 17 | size_t response_length; | 17 | ssize_t response_length; |
| 18 | bool response_read; | 18 | bool response_read; |
| 19 | bool command_enqueued; | 19 | bool command_enqueued; |
| 20 | 20 | ||
| @@ -978,13 +978,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 977 unmodified lines | |||
| 978 | 978 | ||
| 979 | if (wait_startup(chip, 0) != 0) { | 979 | if (wait_startup(chip, 0) != 0) { |
| 980 | rc = -ENODEV; | 980 | rc = -ENODEV; |
| 981 | goto err_start; | 981 | goto out_err; |
| 982 | } | 982 | } |
| 983 | 983 | ||
| 984 | /* Take control of the TPM's interrupt hardware and shut it off */ | 984 | /* Take control of the TPM's interrupt hardware and shut it off */ |
| 985 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); | 985 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); |
| 986 | if (rc < 0) | 986 | if (rc < 0) |
| 987 | goto err_start; | 987 | goto out_err; |
| 988 | 988 | ||
| 989 | intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | | 989 | intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | |
| 990 | TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; | 990 | TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; |
| @@ -993,21 +993,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 2 unmodified lines | |||
| 993 | 993 | ||
| 994 | rc = tpm_chip_start(chip); | 994 | rc = tpm_chip_start(chip); |
| 995 | if (rc) | 995 | if (rc) |
| 996 | goto err_start; | 996 | goto out_err; |
| 997 | |||
| 998 | rc = tpm2_probe(chip); | 997 | rc = tpm2_probe(chip); |
| 998 | tpm_chip_stop(chip); | ||
| 999 | if (rc) | 999 | if (rc) |
| 1000 | goto err_probe; | 1000 | goto out_err; |
| 1001 | 1001 | ||
| 1002 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); | 1002 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); |
| 1003 | if (rc < 0) | 1003 | if (rc < 0) |
| 1004 | goto err_probe; | 1004 | goto out_err; |
| 1005 | 1005 | ||
| 1006 | priv->manufacturer_id = vendor; | 1006 | priv->manufacturer_id = vendor; |
| 1007 | 1007 | ||
| 1008 | rc = tpm_tis_read8(priv, TPM_RID(0), &rid); | 1008 | rc = tpm_tis_read8(priv, TPM_RID(0), &rid); |
| 1009 | if (rc < 0) | 1009 | if (rc < 0) |
| 1010 | goto err_probe; | 1010 | goto out_err; |
| 1011 | 1011 | ||
| 1012 | dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n", | 1012 | dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n", |
| 1013 | (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2", | 1013 | (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2", |
| @@ -1016,13 +1016,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 2 unmodified lines | |||
| 1016 | probe = probe_itpm(chip); | 1016 | probe = probe_itpm(chip); |
| 1017 | if (probe < 0) { | 1017 | if (probe < 0) { |
| 1018 | rc = -ENODEV; | 1018 | rc = -ENODEV; |
| 1019 | goto err_probe; | 1019 | goto out_err; |
| 1020 | } | 1020 | } |
| 1021 | 1021 | ||
| 1022 | /* Figure out the capabilities */ | 1022 | /* Figure out the capabilities */ |
| 1023 | rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps); | 1023 | rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps); |
| 1024 | if (rc < 0) | 1024 | if (rc < 0) |
| 1025 | goto err_probe; | 1025 | goto out_err; |
| 1026 | 1026 | ||
| 1027 | dev_dbg(dev, "TPM interface capabilities (0x%x):\n", | 1027 | dev_dbg(dev, "TPM interface capabilities (0x%x):\n", |
| 1028 | intfcaps); | 1028 | intfcaps); |
| @@ -1056,10 +1056,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 27 unmodified lines | |||
| 1056 | if (tpm_get_timeouts(chip)) { | 1056 | if (tpm_get_timeouts(chip)) { |
| 1057 | dev_err(dev, "Could not get TPM timeouts and durations\n"); | 1057 | dev_err(dev, "Could not get TPM timeouts and durations\n"); |
| 1058 | rc = -ENODEV; | 1058 | rc = -ENODEV; |
| 1059 | goto err_probe; | 1059 | goto out_err; |
| 1060 | } | 1060 | } |
| 1061 | 1061 | ||
| 1062 | chip->flags |= TPM_CHIP_FLAG_IRQ; | ||
| 1063 | if (irq) { | 1062 | if (irq) { |
| 1064 | tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, | 1063 | tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, |
| 1065 | irq); | 1064 | irq); |
| @@ -1071,18 +1070,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, · 5 unmodified lines | |||
| 1071 | } | 1070 | } |
| 1072 | } | 1071 | } |
| 1073 | 1072 | ||
| 1074 | tpm_chip_stop(chip); | ||
| 1075 | |||
| 1076 | rc = tpm_chip_register(chip); | 1073 | rc = tpm_chip_register(chip); |
| 1077 | if (rc) | 1074 | if (rc) |
| 1078 | goto err_start; | 1075 | goto out_err; |
| 1079 | |||
| 1080 | return 0; | ||
| 1081 | 1076 | ||
| 1082 | err_probe: | 1077 | if (chip->ops->clk_enable != NULL) |
| 1083 | tpm_chip_stop(chip); | 1078 | chip->ops->clk_enable(chip, false); |
| 1084 | 1079 | ||
| 1085 | err_start: | 1080 | return 0; |
| 1081 | out_err: | ||
| 1086 | if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) | 1082 | if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) |
| 1087 | chip->ops->clk_enable(chip, false); | 1083 | chip->ops->clk_enable(chip, false); |
| 1088 | 1084 | ||
| @@ -56,7 +56,7 @@ static unsigned long long riscv_clocksource_rdtime(struct clocksource *cs) · 55 unmodified lines | |||
| 56 | return get_cycles64(); | 56 | return get_cycles64(); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static u64 riscv_sched_clock(void) | 59 | static u64 notrace riscv_sched_clock(void) |
| 60 | { | 60 | { |
| 61 | return get_cycles64(); | 61 | return get_cycles64(); |
| 62 | } | 62 | } |
| @@ -121,6 +121,8 @@ static const struct of_device_id blacklist[] __initconst = { · 120 unmodified lines | |||
| 121 | { .compatible = "mediatek,mt8176", }, | 121 | { .compatible = "mediatek,mt8176", }, |
| 122 | { .compatible = "mediatek,mt8183", }, | 122 | { .compatible = "mediatek,mt8183", }, |
| 123 | 123 | ||
| 124 | { .compatible = "nvidia,tegra20", }, | ||
| 125 | { .compatible = "nvidia,tegra30", }, | ||
| 124 | { .compatible = "nvidia,tegra124", }, | 126 | { .compatible = "nvidia,tegra124", }, |
| 125 | { .compatible = "nvidia,tegra210", }, | 127 | { .compatible = "nvidia,tegra210", }, |
| 126 | 128 | ||
| @@ -83,7 +83,6 @@ config ARM_EXYNOS_BUS_DEVFREQ · 82 unmodified lines | |||
| 83 | select DEVFREQ_GOV_PASSIVE | 83 | select DEVFREQ_GOV_PASSIVE |
| 84 | select DEVFREQ_EVENT_EXYNOS_PPMU | 84 | select DEVFREQ_EVENT_EXYNOS_PPMU |
| 85 | select PM_DEVFREQ_EVENT | 85 | select PM_DEVFREQ_EVENT |
| 86 | select PM_OPP | ||
| 87 | help | 86 | help |
| 88 | This adds the common DEVFREQ driver for Exynos Memory bus. Exynos | 87 | This adds the common DEVFREQ driver for Exynos Memory bus. Exynos |
| 89 | Memory bus has one more group of memory bus (e.g, MIF and INT block). | 88 | Memory bus has one more group of memory bus (e.g, MIF and INT block). |
| @@ -98,7 +97,7 @@ config ARM_TEGRA_DEVFREQ · 8 unmodified lines | |||
| 98 | ARCH_TEGRA_132_SOC || ARCH_TEGRA_124_SOC || \ | 97 | ARCH_TEGRA_132_SOC || ARCH_TEGRA_124_SOC || \ |
| 99 | ARCH_TEGRA_210_SOC || \ | 98 | ARCH_TEGRA_210_SOC || \ |
| 100 | COMPILE_TEST | 99 | COMPILE_TEST |
| 101 | select PM_OPP | 100 | depends on COMMON_CLK |
| 102 | help | 101 | help |
| 103 | This adds the DEVFREQ driver for the Tegra family of SoCs. | 102 | This adds the DEVFREQ driver for the Tegra family of SoCs. |
| 104 | It reads ACTMON counters of memory controllers and adjusts the | 103 | It reads ACTMON counters of memory controllers and adjusts the |
| @@ -109,7 +108,6 @@ config ARM_TEGRA20_DEVFREQ · 4 unmodified lines | |||
| 109 | depends on (TEGRA_MC && TEGRA20_EMC) || COMPILE_TEST | 108 | depends on (TEGRA_MC && TEGRA20_EMC) || COMPILE_TEST |
| 110 | depends on COMMON_CLK | 109 | depends on COMMON_CLK |
| 111 | select DEVFREQ_GOV_SIMPLE_ONDEMAND | 110 | select DEVFREQ_GOV_SIMPLE_ONDEMAND |
| 112 | select PM_OPP | ||
| 113 | help | 111 | help |
| 114 | This adds the DEVFREQ driver for the Tegra20 family of SoCs. | 112 | This adds the DEVFREQ driver for the Tegra20 family of SoCs. |
| 115 | It reads Memory Controller counters and adjusts the operating | 113 | It reads Memory Controller counters and adjusts the operating |
| @@ -121,7 +119,6 @@ config ARM_RK3399_DMC_DEVFREQ · 5 unmodified lines | |||
| 121 | select DEVFREQ_EVENT_ROCKCHIP_DFI | 119 | select DEVFREQ_EVENT_ROCKCHIP_DFI |
| 122 | select DEVFREQ_GOV_SIMPLE_ONDEMAND | 120 | select DEVFREQ_GOV_SIMPLE_ONDEMAND |
| 123 | select PM_DEVFREQ_EVENT | 121 | select PM_DEVFREQ_EVENT |
| 124 | select PM_OPP | ||
| 125 | help | 122 | help |
| 126 | This adds the DEVFREQ driver for the RK3399 DMC(Dynamic Memory Controller). | 123 | This adds the DEVFREQ driver for the RK3399 DMC(Dynamic Memory Controller). |
| 127 | It sets the frequency for the memory controller and reads the usage counts | 124 | It sets the frequency for the memory controller and reads the usage counts |
| @@ -999,7 +999,8 @@ static const struct jz4780_dma_soc_data jz4740_dma_soc_data = { · 998 unmodified lines | |||
| 999 | static const struct jz4780_dma_soc_data jz4725b_dma_soc_data = { | 999 | static const struct jz4780_dma_soc_data jz4725b_dma_soc_data = { |
| 1000 | .nb_channels = 6, | 1000 | .nb_channels = 6, |
| 1001 | .transfer_ord_max = 5, | 1001 | .transfer_ord_max = 5, |
| 1002 | .flags = JZ_SOC_DATA_PER_CHAN_PM | JZ_SOC_DATA_NO_DCKES_DCKEC, | 1002 | .flags = JZ_SOC_DATA_PER_CHAN_PM | JZ_SOC_DATA_NO_DCKES_DCKEC | |
| 1003 | JZ_SOC_DATA_BREAK_LINKS, | ||
| 1003 | }; | 1004 | }; |
| 1004 | 1005 | ||
| 1005 | static const struct jz4780_dma_soc_data jz4770_dma_soc_data = { | 1006 | static const struct jz4780_dma_soc_data jz4770_dma_soc_data = { |
| @@ -377,10 +377,11 @@ ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags) · 376 unmodified lines | |||
| 377 | 377 | ||
| 378 | descs->virt = dma_alloc_coherent(to_dev(ioat_chan), | 378 | descs->virt = dma_alloc_coherent(to_dev(ioat_chan), |
| 379 | SZ_2M, &descs->hw, flags); | 379 | SZ_2M, &descs->hw, flags); |
| 380 | if (!descs->virt && (i > 0)) { | 380 | if (!descs->virt) { |
| 381 | int idx; | 381 | int idx; |
| 382 | 382 | ||
| 383 | for (idx = 0; idx < i; idx++) { | 383 | for (idx = 0; idx < i; idx++) { |
| 384 | descs = &ioat_chan->descs[idx]; | ||
| 384 | dma_free_coherent(to_dev(ioat_chan), SZ_2M, | 385 | dma_free_coherent(to_dev(ioat_chan), SZ_2M, |
| 385 | descs->virt, descs->hw); | 386 | descs->virt, descs->hw); |
| 386 | descs->virt = NULL; | 387 | descs->virt = NULL; |
| @@ -229,9 +229,11 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id) · 228 unmodified lines | |||
| 229 | c = p->vchan; | 229 | c = p->vchan; |
| 230 | if (c && (tc1 & BIT(i))) { | 230 | if (c && (tc1 & BIT(i))) { |
| 231 | spin_lock_irqsave(&c->vc.lock, flags); | 231 | spin_lock_irqsave(&c->vc.lock, flags); |
| 232 | vchan_cookie_complete(&p->ds_run->vd); | 232 | if (p->ds_run != NULL) { |
| 233 | p->ds_done = p->ds_run; | 233 | vchan_cookie_complete(&p->ds_run->vd); |
| 234 | p->ds_run = NULL; | 234 | p->ds_done = p->ds_run; |
| 235 | p->ds_run = NULL; | ||
| 236 | } | ||
| 235 | spin_unlock_irqrestore(&c->vc.lock, flags); | 237 | spin_unlock_irqrestore(&c->vc.lock, flags); |
| 236 | } | 238 | } |
| 237 | if (c && (tc2 & BIT(i))) { | 239 | if (c && (tc2 & BIT(i))) { |
| @@ -271,6 +273,10 @@ static int k3_dma_start_txd(struct k3_dma_chan *c) · 33 unmodified lines | |||
| 271 | if (BIT(c->phy->idx) & k3_dma_get_chan_stat(d)) | 273 | if (BIT(c->phy->idx) & k3_dma_get_chan_stat(d)) |
| 272 | return -EAGAIN; | 274 | return -EAGAIN; |
| 273 | 275 | ||
| 276 | /* Avoid losing track of ds_run if a transaction is in flight */ | ||
| 277 | if (c->phy->ds_run) | ||
| 278 | return -EAGAIN; | ||
| 279 | |||
| 274 | if (vd) { | 280 | if (vd) { |
| 275 | struct k3_dma_desc_sw *ds = | 281 | struct k3_dma_desc_sw *ds = |
| 276 | container_of(vd, struct k3_dma_desc_sw, vd); | 282 | container_of(vd, struct k3_dma_desc_sw, vd); |
| @@ -104,9 +104,8 @@ static void vchan_complete(unsigned long arg) · 103 unmodified lines | |||
| 104 | dmaengine_desc_get_callback(&vd->tx, &cb); | 104 | dmaengine_desc_get_callback(&vd->tx, &cb); |
| 105 | 105 | ||
| 106 | list_del(&vd->node); | 106 | list_del(&vd->node); |
| 107 | vchan_vdesc_fini(vd); | ||
| 108 | |||
| 109 | dmaengine_desc_callback_invoke(&cb, &vd->tx_result); | 107 | dmaengine_desc_callback_invoke(&cb, &vd->tx_result); |
| 108 | vchan_vdesc_fini(vd); | ||
| 110 | } | 109 | } |
| 111 | } | 110 | } |
| 112 | 111 | ||
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | #include <linux/edac.h> | 10 | #include <linux/edac.h> |
| 11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 12 | #include "edac_module.h" | 12 | #include "edac_module.h" |
| 13 | #include <asm/sifive_l2_cache.h> | 13 | #include <soc/sifive/sifive_l2_cache.h> |
| 14 | 14 | ||
| 15 | #define DRVNAME "sifive_edac" | 15 | #define DRVNAME "sifive_edac" |
| 16 | 16 | ||
| @@ -215,7 +215,6 @@ static int tee_bnxt_fw_probe(struct device *dev) · 214 unmodified lines | |||
| 215 | fw_shm_pool = tee_shm_alloc(pvt_data.ctx, MAX_SHM_MEM_SZ, | 215 | fw_shm_pool = tee_shm_alloc(pvt_data.ctx, MAX_SHM_MEM_SZ, |
| 216 | TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); | 216 | TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); |
| 217 | if (IS_ERR(fw_shm_pool)) { | 217 | if (IS_ERR(fw_shm_pool)) { |
| 218 | tee_client_close_context(pvt_data.ctx); | ||
| 219 | dev_err(pvt_data.dev, "tee_shm_alloc failed\n"); | 218 | dev_err(pvt_data.dev, "tee_shm_alloc failed\n"); |
| 220 | err = PTR_ERR(fw_shm_pool); | 219 | err = PTR_ERR(fw_shm_pool); |
| 221 | goto out_sess; | 220 | goto out_sess; |
| @@ -553,8 +553,8 @@ config GPIO_TEGRA · 552 unmodified lines | |||
| 553 | 553 | ||
| 554 | config GPIO_TEGRA186 | 554 | config GPIO_TEGRA186 |
| 555 | tristate "NVIDIA Tegra186 GPIO support" | 555 | tristate "NVIDIA Tegra186 GPIO support" |
| 556 | default ARCH_TEGRA_186_SOC | 556 | default ARCH_TEGRA_186_SOC || ARCH_TEGRA_194_SOC |
| 557 | depends on ARCH_TEGRA_186_SOC || COMPILE_TEST | 557 | depends on ARCH_TEGRA_186_SOC || ARCH_TEGRA_194_SOC || COMPILE_TEST |
| 558 | depends on OF_GPIO | 558 | depends on OF_GPIO |
| 559 | select GPIOLIB_IRQCHIP | 559 | select GPIOLIB_IRQCHIP |
| 560 | select IRQ_DOMAIN_HIERARCHY | 560 | select IRQ_DOMAIN_HIERARCHY |
| @@ -1148,6 +1148,7 @@ config GPIO_MADERA · 587 unmodified lines | |||
| 1148 | config GPIO_MAX77620 | 1148 | config GPIO_MAX77620 |
| 1149 | tristate "GPIO support for PMIC MAX77620 and MAX20024" | 1149 | tristate "GPIO support for PMIC MAX77620 and MAX20024" |
| 1150 | depends on MFD_MAX77620 | 1150 | depends on MFD_MAX77620 |
| 1151 | select GPIOLIB_IRQCHIP | ||
| 1151 | help | 1152 | help |
| 1152 | GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor. | 1153 | GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor. |
| 1153 | MAX77620 PMIC has 8 pins that can be configured as GPIOs. The | 1154 | MAX77620 PMIC has 8 pins that can be configured as GPIOs. The |
| @@ -107,7 +107,7 @@ static void __iomem *bank_reg(struct aspeed_sgpio *gpio, · 106 unmodified lines | |||
| 107 | return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS; | 107 | return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS; |
| 108 | default: | 108 | default: |
| 109 | /* acturally if code runs to here, it's an error case */ | 109 | /* acturally if code runs to here, it's an error case */ |
| 110 | BUG_ON(1); | 110 | BUG(); |
| 111 | } | 111 | } |
| 112 | } | 112 | } |
| 113 | 113 | ||
| @@ -156,7 +156,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip, · 155 unmodified lines | |||
| 156 | mutex_lock(&chip->lock); | 156 | mutex_lock(&chip->lock); |
| 157 | 157 | ||
| 158 | if (test_bit(FLAG_REQUESTED, &desc->flags) && | 158 | if (test_bit(FLAG_REQUESTED, &desc->flags) && |
| 159 | !test_bit(FLAG_IS_OUT, &desc->flags)) { | 159 | !test_bit(FLAG_IS_OUT, &desc->flags)) { |
| 160 | curr = __gpio_mockup_get(chip, offset); | 160 | curr = __gpio_mockup_get(chip, offset); |
| 161 | if (curr == value) | 161 | if (curr == value) |
| 162 | goto out; | 162 | goto out; |
| @@ -165,7 +165,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip, · 2 unmodified lines | |||
| 165 | irq_type = irq_get_trigger_type(irq); | 165 | irq_type = irq_get_trigger_type(irq); |
| 166 | 166 | ||
| 167 | if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) || | 167 | if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) || |
| 168 | (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) | 168 | (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) |
| 169 | irq_sim_fire(sim, offset); | 169 | irq_sim_fire(sim, offset); |
| 170 | } | 170 | } |
| 171 | 171 | ||
| @@ -226,7 +226,7 @@ static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset) · 54 unmodified lines | |||
| 226 | int direction; | 226 | int direction; |
| 227 | 227 | ||
| 228 | mutex_lock(&chip->lock); | 228 | mutex_lock(&chip->lock); |
| 229 | direction = !chip->lines[offset].dir; | 229 | direction = chip->lines[offset].dir; |
| 230 | mutex_unlock(&chip->lock); | 230 | mutex_unlock(&chip->lock); |
| 231 | 231 | ||
| 232 | return direction; | 232 | return direction; |
| @@ -395,7 +395,7 @@ static int gpio_mockup_probe(struct platform_device *pdev) · 162 unmodified lines | |||
| 395 | struct gpio_chip *gc; | 395 | struct gpio_chip *gc; |
| 396 | struct device *dev; | 396 | struct device *dev; |
| 397 | const char *name; | 397 | const char *name; |
| 398 | int rv, base; | 398 | int rv, base, i; |
| 399 | u16 ngpio; | 399 | u16 ngpio; |
| 400 | 400 | ||
| 401 | dev = &pdev->dev; | 401 | dev = &pdev->dev; |
| @@ -447,6 +447,9 @@ static int gpio_mockup_probe(struct platform_device *pdev) · 45 unmodified lines | |||
| 447 | if (!chip->lines) | 447 | if (!chip->lines) |
| 448 | return -ENOMEM; | 448 | return -ENOMEM; |
| 449 | 449 | ||
| 450 | for (i = 0; i < gc->ngpio; i++) | ||
| 451 | chip->lines[i].dir = GPIO_LINE_DIRECTION_IN; | ||
| 452 | |||
| 450 | if (device_property_read_bool(dev, "named-gpio-lines")) { | 453 | if (device_property_read_bool(dev, "named-gpio-lines")) { |
| 451 | rv = gpio_mockup_name_lines(dev, chip); | 454 | rv = gpio_mockup_name_lines(dev, chip); |
| 452 | if (rv) | 455 | if (rv) |
| @@ -346,6 +346,7 @@ static int mpc8xxx_probe(struct platform_device *pdev) · 345 unmodified lines | |||
| 346 | return -ENOMEM; | 346 | return -ENOMEM; |
| 347 | 347 | ||
| 348 | gc = &mpc8xxx_gc->gc; | 348 | gc = &mpc8xxx_gc->gc; |
| 349 | gc->parent = &pdev->dev; | ||
| 349 | 350 | ||
| 350 | if (of_property_read_bool(np, "little-endian")) { | 351 | if (of_property_read_bool(np, "little-endian")) { |
| 351 | ret = bgpio_init(gc, &pdev->dev, 4, | 352 | ret = bgpio_init(gc, &pdev->dev, 4, |
| @@ -568,16 +568,18 @@ static void pca953x_irq_mask(struct irq_data *d) · 567 unmodified lines | |||
| 568 | { | 568 | { |
| 569 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 569 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 570 | struct pca953x_chip *chip = gpiochip_get_data(gc); | 570 | struct pca953x_chip *chip = gpiochip_get_data(gc); |
| 571 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
| 571 | 572 | ||
| 572 | chip->irq_mask[d->hwirq / BANK_SZ] &= ~BIT(d->hwirq % BANK_SZ); | 573 | clear_bit(hwirq, chip->irq_mask); |
| 573 | } | 574 | } |
| 574 | 575 | ||
| 575 | static void pca953x_irq_unmask(struct irq_data *d) | 576 | static void pca953x_irq_unmask(struct irq_data *d) |
| 576 | { | 577 | { |
| 577 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 578 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 578 | struct pca953x_chip *chip = gpiochip_get_data(gc); | 579 | struct pca953x_chip *chip = gpiochip_get_data(gc); |
| 580 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
| 579 | 581 | ||
| 580 | chip->irq_mask[d->hwirq / BANK_SZ] |= BIT(d->hwirq % BANK_SZ); | 582 | set_bit(hwirq, chip->irq_mask); |
| 581 | } | 583 | } |
| 582 | 584 | ||
| 583 | static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on) | 585 | static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on) |
| @@ -635,8 +637,7 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) · 51 unmodified lines | |||
| 635 | { | 637 | { |
| 636 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 638 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 637 | struct pca953x_chip *chip = gpiochip_get_data(gc); | 639 | struct pca953x_chip *chip = gpiochip_get_data(gc); |
| 638 | int bank_nb = d->hwirq / BANK_SZ; | 640 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
| 639 | u8 mask = BIT(d->hwirq % BANK_SZ); | ||
| 640 | 641 | ||
| 641 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 642 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
| 642 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 643 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
| @@ -644,15 +645,8 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) · 1 unmodified line | |||
| 644 | return -EINVAL; | 645 | return -EINVAL; |
| 645 | } | 646 | } |
| 646 | 647 | ||
| 647 | if (type & IRQ_TYPE_EDGE_FALLING) | 648 | assign_bit(hwirq, chip->irq_trig_fall, type & IRQ_TYPE_EDGE_FALLING); |
| 648 | chip->irq_trig_fall[bank_nb] |= mask; | 649 | assign_bit(hwirq, chip->irq_trig_raise, type & IRQ_TYPE_EDGE_RISING); |
| 649 | else | ||
| 650 | chip->irq_trig_fall[bank_nb] &= ~mask; | ||
| 651 | |||
| 652 | if (type & IRQ_TYPE_EDGE_RISING) | ||
| 653 | chip->irq_trig_raise[bank_nb] |= mask; | ||
| 654 | else | ||
| 655 | chip->irq_trig_raise[bank_nb] &= ~mask; | ||
| 656 | 650 | ||
| 657 | return 0; | 651 | return 0; |
| 658 | } | 652 | } |
| @@ -661,10 +655,10 @@ static void pca953x_irq_shutdown(struct irq_data *d) · 2 unmodified lines | |||
| 661 | { | 655 | { |
| 662 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 656 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 663 | struct pca953x_chip *chip = gpiochip_get_data(gc); | 657 | struct pca953x_chip *chip = gpiochip_get_data(gc); |
| 664 | u8 mask = BIT(d->hwirq % BANK_SZ); | 658 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
| 665 | 659 | ||
| 666 | chip->irq_trig_raise[d->hwirq / BANK_SZ] &= ~mask; | 660 | clear_bit(hwirq, chip->irq_trig_raise); |
| 667 | chip->irq_trig_fall[d->hwirq / BANK_SZ] &= ~mask; | 661 | clear_bit(hwirq, chip->irq_trig_fall); |
| 668 | } | 662 | } |
| 669 | 663 | ||
| 670 | static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending) | 664 | static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending) |
| @@ -280,7 +280,7 @@ static int iproc_gpio_probe(struct platform_device *pdev) · 279 unmodified lines | |||
| 280 | return 0; | 280 | return 0; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | static int __exit iproc_gpio_remove(struct platform_device *pdev) | 283 | static int iproc_gpio_remove(struct platform_device *pdev) |
| 284 | { | 284 | { |
| 285 | struct iproc_gpio_chip *chip; | 285 | struct iproc_gpio_chip *chip; |
| 286 | 286 | ||
| @@ -44,15 +44,14 @@ static inline unsigned long enable_cp(unsigned long *cpenable) · 43 unmodified lines | |||
| 44 | unsigned long flags; | 44 | unsigned long flags; |
| 45 | 45 | ||
| 46 | local_irq_save(flags); | 46 | local_irq_save(flags); |
| 47 | RSR_CPENABLE(*cpenable); | 47 | *cpenable = xtensa_get_sr(cpenable); |
| 48 | WSR_CPENABLE(*cpenable | BIT(XCHAL_CP_ID_XTIOP)); | 48 | xtensa_set_sr(*cpenable | BIT(XCHAL_CP_ID_XTIOP), cpenable); |
| 49 | |||
| 50 | return flags; | 49 | return flags; |
| 51 | } | 50 | } |
| 52 | 51 | ||
| 53 | static inline void disable_cp(unsigned long flags, unsigned long cpenable) | 52 | static inline void disable_cp(unsigned long flags, unsigned long cpenable) |
| 54 | { | 53 | { |
| 55 | WSR_CPENABLE(cpenable); | 54 | xtensa_set_sr(cpenable, cpenable); |
| 56 | local_irq_restore(flags); | 55 | local_irq_restore(flags); |
| 57 | } | 56 | } |
| 58 | 57 | ||
| @@ -684,6 +684,8 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) · 683 unmodified lines | |||
| 684 | unsigned int bank_num; | 684 | unsigned int bank_num; |
| 685 | 685 | ||
| 686 | for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { | 686 | for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { |
| 687 | writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + | ||
| 688 | ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); | ||
| 687 | writel_relaxed(gpio->context.datalsw[bank_num], | 689 | writel_relaxed(gpio->context.datalsw[bank_num], |
| 688 | gpio->base_addr + | 690 | gpio->base_addr + |
| 689 | ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num)); | 691 | ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num)); |
| @@ -693,9 +695,6 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) · 3 unmodified lines | |||
| 693 | writel_relaxed(gpio->context.dirm[bank_num], | 695 | writel_relaxed(gpio->context.dirm[bank_num], |
| 694 | gpio->base_addr + | 696 | gpio->base_addr + |
| 695 | ZYNQ_GPIO_DIRM_OFFSET(bank_num)); | 697 | ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
| 696 | writel_relaxed(gpio->context.int_en[bank_num], | ||
| 697 | gpio->base_addr + | ||
| 698 | ZYNQ_GPIO_INTEN_OFFSET(bank_num)); | ||
| 699 | writel_relaxed(gpio->context.int_type[bank_num], | 698 | writel_relaxed(gpio->context.int_type[bank_num], |
| 700 | gpio->base_addr + | 699 | gpio->base_addr + |
| 701 | ZYNQ_GPIO_INTTYPE_OFFSET(bank_num)); | 700 | ZYNQ_GPIO_INTTYPE_OFFSET(bank_num)); |
| @@ -705,6 +704,9 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) · 3 unmodified lines | |||
| 705 | writel_relaxed(gpio->context.int_any[bank_num], | 704 | writel_relaxed(gpio->context.int_any[bank_num], |
| 706 | gpio->base_addr + | 705 | gpio->base_addr + |
| 707 | ZYNQ_GPIO_INTANY_OFFSET(bank_num)); | 706 | ZYNQ_GPIO_INTANY_OFFSET(bank_num)); |
| 707 | writel_relaxed(~(gpio->context.int_en[bank_num]), | ||
| 708 | gpio->base_addr + | ||
| 709 | ZYNQ_GPIO_INTEN_OFFSET(bank_num)); | ||
| 708 | } | 710 | } |
| 709 | } | 711 | } |
| 710 | 712 | ||
| @@ -21,11 +21,19 @@ · 20 unmodified lines | |||
| 21 | #include "gpiolib.h" | 21 | #include "gpiolib.h" |
| 22 | #include "gpiolib-acpi.h" | 22 | #include "gpiolib-acpi.h" |
| 23 | 23 | ||
| 24 | #define QUIRK_NO_EDGE_EVENTS_ON_BOOT 0x01l | ||
| 25 | #define QUIRK_NO_WAKEUP 0x02l | ||
| 26 | |||
| 24 | static int run_edge_events_on_boot = -1; | 27 | static int run_edge_events_on_boot = -1; |
| 25 | module_param(run_edge_events_on_boot, int, 0444); | 28 | module_param(run_edge_events_on_boot, int, 0444); |
| 26 | MODULE_PARM_DESC(run_edge_events_on_boot, | 29 | MODULE_PARM_DESC(run_edge_events_on_boot, |
| 27 | "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); | 30 | "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); |
| 28 | 31 | ||
| 32 | static int honor_wakeup = -1; | ||
| 33 | module_param(honor_wakeup, int, 0444); | ||
| 34 | MODULE_PARM_DESC(honor_wakeup, | ||
| 35 | "Honor the ACPI wake-capable flag: 0=no, 1=yes, -1=auto"); | ||
| 36 | |||
| 29 | /** | 37 | /** |
| 30 | * struct acpi_gpio_event - ACPI GPIO event handler data | 38 | * struct acpi_gpio_event - ACPI GPIO event handler data |
| 31 | * | 39 | * |
| @@ -281,7 +289,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, · 249 unmodified lines | |||
| 281 | event->handle = evt_handle; | 289 | event->handle = evt_handle; |
| 282 | event->handler = handler; | 290 | event->handler = handler; |
| 283 | event->irq = irq; | 291 | event->irq = irq; |
| 284 | event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE; | 292 | event->irq_is_wake = honor_wakeup && agpio->wake_capable == ACPI_WAKE_CAPABLE; |
| 285 | event->pin = pin; | 293 | event->pin = pin; |
| 286 | event->desc = desc; | 294 | event->desc = desc; |
| 287 | 295 | ||
| @@ -1309,7 +1317,7 @@ static int acpi_gpio_handle_deferred_request_irqs(void) · 1021 unmodified lines | |||
| 1309 | /* We must use _sync so that this runs after the first deferred_probe run */ | 1317 | /* We must use _sync so that this runs after the first deferred_probe run */ |
| 1310 | late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); | 1318 | late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); |
| 1311 | 1319 | ||
| 1312 | static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = { | 1320 | static const struct dmi_system_id gpiolib_acpi_quirks[] = { |
| 1313 | { | 1321 | { |
| 1314 | /* | 1322 | /* |
| 1315 | * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for | 1323 | * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for |
| @@ -1319,7 +1327,8 @@ static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = { · 3 unmodified lines | |||
| 1319 | .matches = { | 1327 | .matches = { |
| 1320 | DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), | 1328 | DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), |
| 1321 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), | 1329 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), |
| 1322 | } | 1330 | }, |
| 1331 | .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, | ||
| 1323 | }, | 1332 | }, |
| 1324 | { | 1333 | { |
| 1325 | /* | 1334 | /* |
| @@ -1331,20 +1340,52 @@ static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = { · 5 unmodified lines | |||
| 1331 | .matches = { | 1340 | .matches = { |
| 1332 | DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), | 1341 | DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), |
| 1333 | DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), | 1342 | DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), |
| 1334 | } | 1343 | }, |
| 1344 | .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, | ||
| 1345 | }, | ||
| 1346 | { | ||
| 1347 | /* | ||
| 1348 | * Various HP X2 10 Cherry Trail models use an external | ||
| 1349 | * embedded-controller connected via I2C + an ACPI GPIO | ||
| 1350 | * event handler. The embedded controller generates various | ||
| 1351 | * spurious wakeup events when suspended. So disable wakeup | ||
| 1352 | * for its handler (it uses the only ACPI GPIO event handler). | ||
| 1353 | * This breaks wakeup when opening the lid, the user needs | ||
| 1354 | * to press the power-button to wakeup the system. The | ||
| 1355 | * alternative is suspend simply not working, which is worse. | ||
| 1356 | */ | ||
| 1357 | .matches = { | ||
| 1358 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), | ||
| 1359 | DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), | ||
| 1360 | }, | ||
| 1361 | .driver_data = (void *)QUIRK_NO_WAKEUP, | ||
| 1335 | }, | 1362 | }, |
| 1336 | {} /* Terminating entry */ | 1363 | {} /* Terminating entry */ |
| 1337 | }; | 1364 | }; |
| 1338 | 1365 | ||
| 1339 | static int acpi_gpio_setup_params(void) | 1366 | static int acpi_gpio_setup_params(void) |
| 1340 | { | 1367 | { |
| 1368 | const struct dmi_system_id *id; | ||
| 1369 | long quirks = 0; | ||
| 1370 | |||
| 1371 | id = dmi_first_match(gpiolib_acpi_quirks); | ||
| 1372 | if (id) | ||
| 1373 | quirks = (long)id->driver_data; | ||
| 1374 | |||
| 1341 | if (run_edge_events_on_boot < 0) { | 1375 | if (run_edge_events_on_boot < 0) { |
| 1342 | if (dmi_check_system(run_edge_events_on_boot_blacklist)) | 1376 | if (quirks & QUIRK_NO_EDGE_EVENTS_ON_BOOT) |
| 1343 | run_edge_events_on_boot = 0; | 1377 | run_edge_events_on_boot = 0; |
| 1344 | else | 1378 | else |
| 1345 | run_edge_events_on_boot = 1; | 1379 | run_edge_events_on_boot = 1; |
| 1346 | } | 1380 | } |
| 1347 | 1381 | ||
| 1382 | if (honor_wakeup < 0) { | ||
| 1383 | if (quirks & QUIRK_NO_WAKEUP) | ||
| 1384 | honor_wakeup = 0; | ||
| 1385 | else | ||
| 1386 | honor_wakeup = 1; | ||
| 1387 | } | ||
| 1388 | |||
| 1348 | return 0; | 1389 | return 0; |
| 1349 | } | 1390 | } |
| 1350 | 1391 | ||
| @@ -220,6 +220,14 @@ int gpiod_get_direction(struct gpio_desc *desc) · 219 unmodified lines | |||
| 220 | chip = gpiod_to_chip(desc); | 220 | chip = gpiod_to_chip(desc); |
| 221 | offset = gpio_chip_hwgpio(desc); | 221 | offset = gpio_chip_hwgpio(desc); |
| 222 | 222 | ||
| 223 | /* | ||
| 224 | * Open drain emulation using input mode may incorrectly report | ||
| 225 | * input here, fix that up. | ||
| 226 | */ | ||
| 227 | if (test_bit(FLAG_OPEN_DRAIN, &desc->flags) && | ||
| 228 | test_bit(FLAG_IS_OUT, &desc->flags)) | ||
| 229 | return 0; | ||
| 230 | |||
| 223 | if (!chip->get_direction) | 231 | if (!chip->get_direction) |
| 224 | return -ENOTSUPP; | 232 | return -ENOTSUPP; |
| 225 | 233 | ||
| @@ -4472,8 +4480,9 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, · 4246 unmodified lines | |||
| 4472 | 4480 | ||
| 4473 | if (chip->ngpio <= p->chip_hwnum) { | 4481 | if (chip->ngpio <= p->chip_hwnum) { |
| 4474 | dev_err(dev, | 4482 | dev_err(dev, |
| 4475 | "requested GPIO %d is out of range [0..%d] for chip %s\n", | 4483 | "requested GPIO %u (%u) is out of range [0..%u] for chip %s\n", |
| 4476 | idx, chip->ngpio, chip->label); | 4484 | idx, p->chip_hwnum, chip->ngpio - 1, |
| 4485 | chip->label); | ||
| 4477 | return ERR_PTR(-EINVAL); | 4486 | return ERR_PTR(-EINVAL); |
| 4478 | } | 4487 | } |
| 4479 | 4488 | ||
| @@ -613,7 +613,17 @@ static bool amdgpu_atpx_detect(void) · 612 unmodified lines | |||
| 613 | bool d3_supported = false; | 613 | bool d3_supported = false; |
| 614 | struct pci_dev *parent_pdev; | 614 | struct pci_dev *parent_pdev; |
| 615 | 615 | ||
| 616 | while ((pdev = pci_get_class(PCI_BASE_CLASS_DISPLAY << 16, pdev)) != NULL) { | 616 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { |
| 617 | vga_count++; | ||
| 618 | |||
| 619 | has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); | ||
| 620 | |||
| 621 | parent_pdev = pci_upstream_bridge(pdev); | ||
| 622 | d3_supported |= parent_pdev && parent_pdev->bridge_d3; | ||
| 623 | amdgpu_atpx_get_quirks(pdev); | ||
| 624 | } | ||
| 625 | |||
| 626 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { | ||
| 617 | vga_count++; | 627 | vga_count++; |
| 618 | 628 | ||
| 619 | has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); | 629 | has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); |
| @@ -142,7 +142,7 @@ int amdgpu_async_gfx_ring = 1; · 141 unmodified lines | |||
| 142 | int amdgpu_mcbp = 0; | 142 | int amdgpu_mcbp = 0; |
| 143 | int amdgpu_discovery = -1; | 143 | int amdgpu_discovery = -1; |
| 144 | int amdgpu_mes = 0; | 144 | int amdgpu_mes = 0; |
| 145 | int amdgpu_noretry = 1; | 145 | int amdgpu_noretry; |
| 146 | int amdgpu_force_asic_type = -1; | 146 | int amdgpu_force_asic_type = -1; |
| 147 | 147 | ||
| 148 | struct amdgpu_mgpu_info mgpu_info = { | 148 | struct amdgpu_mgpu_info mgpu_info = { |
| @@ -588,7 +588,7 @@ MODULE_PARM_DESC(mes, · 439 unmodified lines | |||
| 588 | module_param_named(mes, amdgpu_mes, int, 0444); | 588 | module_param_named(mes, amdgpu_mes, int, 0444); |
| 589 | 589 | ||
| 590 | MODULE_PARM_DESC(noretry, | 590 | MODULE_PARM_DESC(noretry, |
| 591 | "Disable retry faults (0 = retry enabled, 1 = retry disabled (default))"); | 591 | "Disable retry faults (0 = retry enabled (default), 1 = retry disabled)"); |
| 592 | module_param_named(noretry, amdgpu_noretry, int, 0644); | 592 | module_param_named(noretry, amdgpu_noretry, int, 0644); |
| 593 | 593 | ||
| 594 | /** | 594 | /** |
| @@ -1359,7 +1359,8 @@ static struct drm_driver kms_driver = { · 764 unmodified lines | |||
| 1359 | .driver_features = | 1359 | .driver_features = |
| 1360 | DRIVER_USE_AGP | DRIVER_ATOMIC | | 1360 | DRIVER_USE_AGP | DRIVER_ATOMIC | |
| 1361 | DRIVER_GEM | | 1361 | DRIVER_GEM | |
| 1362 | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ, | 1362 | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ | |
| 1363 | DRIVER_SYNCOBJ_TIMELINE, | ||
| 1363 | .load = amdgpu_driver_load_kms, | 1364 | .load = amdgpu_driver_load_kms, |
| 1364 | .open = amdgpu_driver_open_kms, | 1365 | .open = amdgpu_driver_open_kms, |
| 1365 | .postclose = amdgpu_driver_postclose_kms, | 1366 | .postclose = amdgpu_driver_postclose_kms, |
| @@ -1488,7 +1488,7 @@ out: · 1487 unmodified lines | |||
| 1488 | 1488 | ||
| 1489 | /* Start rlc autoload after psp recieved all the gfx firmware */ | 1489 | /* Start rlc autoload after psp recieved all the gfx firmware */ |
| 1490 | if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ? | 1490 | if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ? |
| 1491 | AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) { | 1491 | AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_G)) { |
| 1492 | ret = psp_rlc_autoload(psp); | 1492 | ret = psp_rlc_autoload(psp); |
| 1493 | if (ret) { | 1493 | if (ret) { |
| 1494 | DRM_ERROR("Failed to start rlc autoload\n"); | 1494 | DRM_ERROR("Failed to start rlc autoload\n"); |
| @@ -292,10 +292,10 @@ enum AMDGPU_UCODE_ID { · 291 unmodified lines | |||
| 292 | AMDGPU_UCODE_ID_CP_MEC2_JT, | 292 | AMDGPU_UCODE_ID_CP_MEC2_JT, |
| 293 | AMDGPU_UCODE_ID_CP_MES, | 293 | AMDGPU_UCODE_ID_CP_MES, |
| 294 | AMDGPU_UCODE_ID_CP_MES_DATA, | 294 | AMDGPU_UCODE_ID_CP_MES_DATA, |
| 295 | AMDGPU_UCODE_ID_RLC_G, | ||
| 296 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL, | 295 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL, |
| 297 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM, | 296 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM, |
| 298 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM, | 297 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM, |
| 298 | AMDGPU_UCODE_ID_RLC_G, | ||
| 299 | AMDGPU_UCODE_ID_STORAGE, | 299 | AMDGPU_UCODE_ID_STORAGE, |
| 300 | AMDGPU_UCODE_ID_SMC, | 300 | AMDGPU_UCODE_ID_SMC, |
| 301 | AMDGPU_UCODE_ID_UVD, | 301 | AMDGPU_UCODE_ID_UVD, |
| @@ -1052,17 +1052,10 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) · 1051 unmodified lines | |||
| 1052 | case CHIP_VEGA20: | 1052 | case CHIP_VEGA20: |
| 1053 | break; | 1053 | break; |
| 1054 | case CHIP_RAVEN: | 1054 | case CHIP_RAVEN: |
| 1055 | /* Disable GFXOFF on original raven. There are combinations | 1055 | if (!(adev->rev_id >= 0x8 || |
| 1056 | * of sbios and platforms that are not stable. | 1056 | adev->pdev->device == 0x15d8) && |
| 1057 | */ | 1057 | (adev->pm.fw_version < 0x41e2b || /* not raven1 fresh */ |
| 1058 | if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)) | 1058 | !adev->gfx.rlc.is_rlc_v2_1)) /* without rlc save restore ucodes */ |
| 1059 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; | ||
| 1060 | else if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) | ||
| 1061 | &&((adev->gfx.rlc_fw_version != 106 && | ||
| 1062 | adev->gfx.rlc_fw_version < 531) || | ||
| 1063 | (adev->gfx.rlc_fw_version == 53815) || | ||
| 1064 | (adev->gfx.rlc_feature_version < 1) || | ||
| 1065 | !adev->gfx.rlc.is_rlc_v2_1)) | ||
| 1066 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; | 1059 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; |
| 1067 | 1060 | ||
| 1068 | if (adev->pm.pp_feature & PP_GFXOFF_MASK) | 1061 | if (adev->pm.pp_feature & PP_GFXOFF_MASK) |
| @@ -3356,27 +3356,21 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing) · 3355 unmodified lines | |||
| 3356 | return color_space; | 3356 | return color_space; |
| 3357 | } | 3357 | } |
| 3358 | 3358 | ||
| 3359 | static void reduce_mode_colour_depth(struct dc_crtc_timing *timing_out) | 3359 | static bool adjust_colour_depth_from_display_info( |
| 3360 | { | 3360 | struct dc_crtc_timing *timing_out, |
| 3361 | if (timing_out->display_color_depth <= COLOR_DEPTH_888) | 3361 | const struct drm_display_info *info) |
| 3362 | return; | ||
| 3363 | |||
| 3364 | timing_out->display_color_depth--; | ||
| 3365 | } | ||
| 3366 | |||
| 3367 | static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out, | ||
| 3368 | const struct drm_display_info *info) | ||
| 3369 | { | 3362 | { |
| 3363 | enum dc_color_depth depth = timing_out->display_color_depth; | ||
| 3370 | int normalized_clk; | 3364 | int normalized_clk; |
| 3371 | if (timing_out->display_color_depth <= COLOR_DEPTH_888) | ||
| 3372 | return; | ||
| 3373 | do { | 3365 | do { |
| 3374 | normalized_clk = timing_out->pix_clk_100hz / 10; | 3366 | normalized_clk = timing_out->pix_clk_100hz / 10; |
| 3375 | /* YCbCr 4:2:0 requires additional adjustment of 1/2 */ | 3367 | /* YCbCr 4:2:0 requires additional adjustment of 1/2 */ |
| 3376 | if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420) | 3368 | if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
| 3377 | normalized_clk /= 2; | 3369 | normalized_clk /= 2; |
| 3378 | /* Adjusting pix clock following on HDMI spec based on colour depth */ | 3370 | /* Adjusting pix clock following on HDMI spec based on colour depth */ |
| 3379 | switch (timing_out->display_color_depth) { | 3371 | switch (depth) { |
| 3372 | case COLOR_DEPTH_888: | ||
| 3373 | break; | ||
| 3380 | case COLOR_DEPTH_101010: | 3374 | case COLOR_DEPTH_101010: |
| 3381 | normalized_clk = (normalized_clk * 30) / 24; | 3375 | normalized_clk = (normalized_clk * 30) / 24; |
| 3382 | break; | 3376 | break; |
| @@ -3387,14 +3381,15 @@ static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_ · 4 unmodified lines | |||
| 3387 | normalized_clk = (normalized_clk * 48) / 24; | 3381 | normalized_clk = (normalized_clk * 48) / 24; |
| 3388 | break; | 3382 | break; |
| 3389 | default: | 3383 | default: |
| 3390 | return; | 3384 | /* The above depths are the only ones valid for HDMI. */ |
| 3385 | return false; | ||
| 3391 | } | 3386 | } |
| 3392 | if (normalized_clk <= info->max_tmds_clock) | 3387 | if (normalized_clk <= info->max_tmds_clock) { |
| 3393 | return; | 3388 | timing_out->display_color_depth = depth; |
| 3394 | reduce_mode_colour_depth(timing_out); | 3389 | return true; |
| 3395 | 3390 | } | |
| 3396 | } while (timing_out->display_color_depth > COLOR_DEPTH_888); | 3391 | } while (--depth > COLOR_DEPTH_666); |
| 3397 | 3392 | return false; | |
| 3398 | } | 3393 | } |
| 3399 | 3394 | ||
| 3400 | static void fill_stream_properties_from_drm_display_mode( | 3395 | static void fill_stream_properties_from_drm_display_mode( |
| @@ -3474,8 +3469,14 @@ static void fill_stream_properties_from_drm_display_mode( · 73 unmodified lines | |||
| 3474 | 3469 | ||
| 3475 | stream->out_transfer_func->type = TF_TYPE_PREDEFINED; | 3470 | stream->out_transfer_func->type = TF_TYPE_PREDEFINED; |
| 3476 | stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; | 3471 | stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; |
| 3477 | if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) | 3472 | if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) { |
| 3478 | adjust_colour_depth_from_display_info(timing_out, info); | 3473 | if (!adjust_colour_depth_from_display_info(timing_out, info) && |
| 3474 | drm_mode_is_420_also(info, mode_in) && | ||
| 3475 | timing_out->pixel_encoding != PIXEL_ENCODING_YCBCR420) { | ||
| 3476 | timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420; | ||
| 3477 | adjust_colour_depth_from_display_info(timing_out, info); | ||
| 3478 | } | ||
| 3479 | } | ||
| 3479 | } | 3480 | } |
| 3480 | 3481 | ||
| 3481 | static void fill_audio_info(struct audio_info *audio_info, | 3482 | static void fill_audio_info(struct audio_info *audio_info, |
| @@ -866,6 +866,7 @@ static int smu_sw_init(void *handle) · 865 unmodified lines | |||
| 866 | smu->smu_baco.platform_support = false; | 866 | smu->smu_baco.platform_support = false; |
| 867 | 867 | ||
| 868 | mutex_init(&smu->sensor_lock); | 868 | mutex_init(&smu->sensor_lock); |
| 869 | mutex_init(&smu->metrics_lock); | ||
| 869 | 870 | ||
| 870 | smu->watermarks_bitmap = 0; | 871 | smu->watermarks_bitmap = 0; |
| 871 | smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; | 872 | smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; |
| @@ -862,18 +862,21 @@ static int arcturus_get_metrics_table(struct smu_context *smu, · 861 unmodified lines | |||
| 862 | struct smu_table_context *smu_table= &smu->smu_table; | 862 | struct smu_table_context *smu_table= &smu->smu_table; |
| 863 | int ret = 0; | 863 | int ret = 0; |
| 864 | 864 | ||
| 865 | mutex_lock(&smu->metrics_lock); | ||
| 865 | if (!smu_table->metrics_time || | 866 | if (!smu_table->metrics_time || |
| 866 | time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { | 867 | time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { |
| 867 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, | 868 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, |
| 868 | (void *)smu_table->metrics_table, false); | 869 | (void *)smu_table->metrics_table, false); |
| 869 | if (ret) { | 870 | if (ret) { |
| 870 | pr_info("Failed to export SMU metrics table!\n"); | 871 | pr_info("Failed to export SMU metrics table!\n"); |
| 872 | mutex_unlock(&smu->metrics_lock); | ||
| 871 | return ret; | 873 | return ret; |
| 872 | } | 874 | } |
| 873 | smu_table->metrics_time = jiffies; | 875 | smu_table->metrics_time = jiffies; |
| 874 | } | 876 | } |
| 875 | 877 | ||
| 876 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); | 878 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); |
| 879 | mutex_unlock(&smu->metrics_lock); | ||
| 877 | 880 | ||
| 878 | return ret; | 881 | return ret; |
| 879 | } | 882 | } |
| @@ -349,6 +349,7 @@ struct smu_context · 348 unmodified lines | |||
| 349 | const struct pptable_funcs *ppt_funcs; | 349 | const struct pptable_funcs *ppt_funcs; |
| 350 | struct mutex mutex; | 350 | struct mutex mutex; |
| 351 | struct mutex sensor_lock; | 351 | struct mutex sensor_lock; |
| 352 | struct mutex metrics_lock; | ||
| 352 | uint64_t pool_size; | 353 | uint64_t pool_size; |
| 353 | 354 | ||
| 354 | struct smu_table_context smu_table; | 355 | struct smu_table_context smu_table; |
| @@ -562,17 +562,20 @@ static int navi10_get_metrics_table(struct smu_context *smu, · 561 unmodified lines | |||
| 562 | struct smu_table_context *smu_table= &smu->smu_table; | 562 | struct smu_table_context *smu_table= &smu->smu_table; |
| 563 | int ret = 0; | 563 | int ret = 0; |
| 564 | 564 | ||
| 565 | mutex_lock(&smu->metrics_lock); | ||
| 565 | if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(100))) { | 566 | if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(100))) { |
| 566 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, | 567 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, |
| 567 | (void *)smu_table->metrics_table, false); | 568 | (void *)smu_table->metrics_table, false); |
| 568 | if (ret) { | 569 | if (ret) { |
| 569 | pr_info("Failed to export SMU metrics table!\n"); | 570 | pr_info("Failed to export SMU metrics table!\n"); |
| 571 | mutex_unlock(&smu->metrics_lock); | ||
| 570 | return ret; | 572 | return ret; |
| 571 | } | 573 | } |
| 572 | smu_table->metrics_time = jiffies; | 574 | smu_table->metrics_time = jiffies; |
| 573 | } | 575 | } |
| 574 | 576 | ||
| 575 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); | 577 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); |
| 578 | mutex_unlock(&smu->metrics_lock); | ||
| 576 | 579 | ||
| 577 | return ret; | 580 | return ret; |
| 578 | } | 581 | } |
| @@ -1678,17 +1678,20 @@ static int vega20_get_metrics_table(struct smu_context *smu, · 1677 unmodified lines | |||
| 1678 | struct smu_table_context *smu_table= &smu->smu_table; | 1678 | struct smu_table_context *smu_table= &smu->smu_table; |
| 1679 | int ret = 0; | 1679 | int ret = 0; |
| 1680 | 1680 | ||
| 1681 | mutex_lock(&smu->metrics_lock); | ||
| 1681 | if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { | 1682 | if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { |
| 1682 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, | 1683 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, |
| 1683 | (void *)smu_table->metrics_table, false); | 1684 | (void *)smu_table->metrics_table, false); |
| 1684 | if (ret) { | 1685 | if (ret) { |
| 1685 | pr_info("Failed to export SMU metrics table!\n"); | 1686 | pr_info("Failed to export SMU metrics table!\n"); |
| 1687 | mutex_unlock(&smu->metrics_lock); | ||
| 1686 | return ret; | 1688 | return ret; |
| 1687 | } | 1689 | } |
| 1688 | smu_table->metrics_time = jiffies; | 1690 | smu_table->metrics_time = jiffies; |
| 1689 | } | 1691 | } |
| 1690 | 1692 | ||
| 1691 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); | 1693 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); |
| 1694 | mutex_unlock(&smu->metrics_lock); | ||
| 1692 | 1695 | ||
| 1693 | return ret; | 1696 | return ret; |
| 1694 | } | 1697 | } |
| @@ -56,7 +56,7 @@ malidp_mw_connector_mode_valid(struct drm_connector *connector, · 55 unmodified lines | |||
| 56 | return MODE_OK; | 56 | return MODE_OK; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | const struct drm_connector_helper_funcs malidp_mw_connector_helper_funcs = { | 59 | static const struct drm_connector_helper_funcs malidp_mw_connector_helper_funcs = { |
| 60 | .get_modes = malidp_mw_connector_get_modes, | 60 | .get_modes = malidp_mw_connector_get_modes, |
| 61 | .mode_valid = malidp_mw_connector_mode_valid, | 61 | .mode_valid = malidp_mw_connector_mode_valid, |
| 62 | }; | 62 | }; |
| @@ -393,7 +393,7 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req, · 392 unmodified lines | |||
| 393 | memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes); | 393 | memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes); |
| 394 | idx += req->u.i2c_read.transactions[i].num_bytes; | 394 | idx += req->u.i2c_read.transactions[i].num_bytes; |
| 395 | 395 | ||
| 396 | buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 5; | 396 | buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 4; |
| 397 | buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf); | 397 | buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf); |
| 398 | idx++; | 398 | idx++; |
| 399 | } | 399 | } |
| @@ -1283,7 +1283,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, · 1282 unmodified lines | |||
| 1283 | * Changes struct fb_var_screeninfo are currently not pushed back | 1283 | * Changes struct fb_var_screeninfo are currently not pushed back |
| 1284 | * to KMS, hence fail if different settings are requested. | 1284 | * to KMS, hence fail if different settings are requested. |
| 1285 | */ | 1285 | */ |
| 1286 | if (var->bits_per_pixel != fb->format->cpp[0] * 8 || | 1286 | if (var->bits_per_pixel > fb->format->cpp[0] * 8 || |
| 1287 | var->xres > fb->width || var->yres > fb->height || | 1287 | var->xres > fb->width || var->yres > fb->height || |
| 1288 | var->xres_virtual > fb->width || var->yres_virtual > fb->height) { | 1288 | var->xres_virtual > fb->width || var->yres_virtual > fb->height) { |
| 1289 | DRM_DEBUG("fb requested width/height/bpp can't fit in current fb " | 1289 | DRM_DEBUG("fb requested width/height/bpp can't fit in current fb " |
| @@ -1308,6 +1308,11 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, · 18 unmodified lines | |||
| 1308 | drm_fb_helper_fill_pixel_fmt(var, fb->format->depth); | 1308 | drm_fb_helper_fill_pixel_fmt(var, fb->format->depth); |
| 1309 | } | 1309 | } |
| 1310 | 1310 | ||
| 1311 | /* | ||
| 1312 | * Likewise, bits_per_pixel should be rounded up to a supported value. | ||
| 1313 | */ | ||
| 1314 | var->bits_per_pixel = fb->format->cpp[0] * 8; | ||
| 1315 | |||
| 1311 | /* | 1316 | /* |
| 1312 | * drm fbdev emulation doesn't support changing the pixel format at all, | 1317 | * drm fbdev emulation doesn't support changing the pixel format at all, |
| 1313 | * so reject all pixel format changing requests. | 1318 | * so reject all pixel format changing requests. |
| @@ -856,7 +856,7 @@ static unsigned long i915_audio_component_get_power(struct device *kdev) · 855 unmodified lines | |||
| 856 | } | 856 | } |
| 857 | 857 | ||
| 858 | /* Force CDCLK to 2*BCLK as long as we need audio powered. */ | 858 | /* Force CDCLK to 2*BCLK as long as we need audio powered. */ |
| 859 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) | 859 | if (IS_GEMINILAKE(dev_priv)) |
| 860 | glk_force_audio_cdclk(dev_priv, true); | 860 | glk_force_audio_cdclk(dev_priv, true); |
| 861 | 861 | ||
| 862 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) | 862 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
| @@ -875,7 +875,7 @@ static void i915_audio_component_put_power(struct device *kdev, · 12 unmodified lines | |||
| 875 | 875 | ||
| 876 | /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */ | 876 | /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */ |
| 877 | if (--dev_priv->audio_power_refcount == 0) | 877 | if (--dev_priv->audio_power_refcount == 0) |
| 878 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) | 878 | if (IS_GEMINILAKE(dev_priv)) |
| 879 | glk_force_audio_cdclk(dev_priv, false); | 879 | glk_force_audio_cdclk(dev_priv, false); |
| 880 | 880 | ||
| 881 | intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO, cookie); | 881 | intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO, cookie); |
| @@ -4515,8 +4515,6 @@ static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_ · 4514 unmodified lines | |||
| 4515 | { | 4515 | { |
| 4516 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); | 4516 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
| 4517 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 4517 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
| 4518 | i915_reg_t reg; | ||
| 4519 | u32 trans_ddi_func_ctl2_val; | ||
| 4520 | 4518 | ||
| 4521 | if (old_crtc_state->master_transcoder == INVALID_TRANSCODER) | 4519 | if (old_crtc_state->master_transcoder == INVALID_TRANSCODER) |
| 4522 | return; | 4520 | return; |
| @@ -4524,10 +4522,7 @@ static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_ · 1 unmodified line | |||
| 4524 | DRM_DEBUG_KMS("Disabling Transcoder Port Sync on Slave Transcoder %s\n", | 4522 | DRM_DEBUG_KMS("Disabling Transcoder Port Sync on Slave Transcoder %s\n", |
| 4525 | transcoder_name(old_crtc_state->cpu_transcoder)); | 4523 | transcoder_name(old_crtc_state->cpu_transcoder)); |
| 4526 | 4524 | ||
| 4527 | reg = TRANS_DDI_FUNC_CTL2(old_crtc_state->cpu_transcoder); | 4525 | I915_WRITE(TRANS_DDI_FUNC_CTL2(old_crtc_state->cpu_transcoder), 0); |
| 4528 | trans_ddi_func_ctl2_val = ~(PORT_SYNC_MODE_ENABLE | | ||
| 4529 | PORT_SYNC_MODE_MASTER_SELECT_MASK); | ||
| 4530 | I915_WRITE(reg, trans_ddi_func_ctl2_val); | ||
| 4531 | } | 4526 | } |
| 4532 | 4527 | ||
| 4533 | static void intel_fdi_normal_train(struct intel_crtc *crtc) | 4528 | static void intel_fdi_normal_train(struct intel_crtc *crtc) |
| @@ -15112,7 +15107,7 @@ intel_prepare_plane_fb(struct drm_plane *plane, · 10578 unmodified lines | |||
| 15112 | return ret; | 15107 | return ret; |
| 15113 | 15108 | ||
| 15114 | fb_obj_bump_render_priority(obj); | 15109 | fb_obj_bump_render_priority(obj); |
| 15115 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_DIRTYFB); | 15110 | i915_gem_object_flush_frontbuffer(obj, ORIGIN_DIRTYFB); |
| 15116 | 15111 | ||
| 15117 | if (!new_plane_state->base.fence) { /* implicit fencing */ | 15112 | if (!new_plane_state->base.fence) { /* implicit fencing */ |
| 15118 | struct dma_fence *fence; | 15113 | struct dma_fence *fence; |
| @@ -229,11 +229,11 @@ static void frontbuffer_release(struct kref *ref) · 228 unmodified lines | |||
| 229 | vma->display_alignment = I915_GTT_MIN_ALIGNMENT; | 229 | vma->display_alignment = I915_GTT_MIN_ALIGNMENT; |
| 230 | spin_unlock(&obj->vma.lock); | 230 | spin_unlock(&obj->vma.lock); |
| 231 | 231 | ||
| 232 | obj->frontbuffer = NULL; | 232 | RCU_INIT_POINTER(obj->frontbuffer, NULL); |
| 233 | spin_unlock(&to_i915(obj->base.dev)->fb_tracking.lock); | 233 | spin_unlock(&to_i915(obj->base.dev)->fb_tracking.lock); |
| 234 | 234 | ||
| 235 | i915_gem_object_put(obj); | 235 | i915_gem_object_put(obj); |
| 236 | kfree(front); | 236 | kfree_rcu(front, rcu); |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | struct intel_frontbuffer * | 239 | struct intel_frontbuffer * |
| @@ -242,11 +242,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) · 2 unmodified lines | |||
| 242 | struct drm_i915_private *i915 = to_i915(obj->base.dev); | 242 | struct drm_i915_private *i915 = to_i915(obj->base.dev); |
| 243 | struct intel_frontbuffer *front; | 243 | struct intel_frontbuffer *front; |
| 244 | 244 | ||
| 245 | spin_lock(&i915->fb_tracking.lock); | 245 | front = __intel_frontbuffer_get(obj); |
| 246 | front = obj->frontbuffer; | ||
| 247 | if (front) | ||
| 248 | kref_get(&front->ref); | ||
| 249 | spin_unlock(&i915->fb_tracking.lock); | ||
| 250 | if (front) | 246 | if (front) |
| 251 | return front; | 247 | return front; |
| 252 | 248 | ||
| @@ -262,13 +258,13 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) · 9 unmodified lines | |||
| 262 | i915_active_may_sleep(frontbuffer_retire)); | 258 | i915_active_may_sleep(frontbuffer_retire)); |
| 263 | 259 | ||
| 264 | spin_lock(&i915->fb_tracking.lock); | 260 | spin_lock(&i915->fb_tracking.lock); |
| 265 | if (obj->frontbuffer) { | 261 | if (rcu_access_pointer(obj->frontbuffer)) { |
| 266 | kfree(front); | 262 | kfree(front); |
| 267 | front = obj->frontbuffer; | 263 | front = rcu_dereference_protected(obj->frontbuffer, true); |
| 268 | kref_get(&front->ref); | 264 | kref_get(&front->ref); |
| 269 | } else { | 265 | } else { |
| 270 | i915_gem_object_get(obj); | 266 | i915_gem_object_get(obj); |
| 271 | obj->frontbuffer = front; | 267 | rcu_assign_pointer(obj->frontbuffer, front); |
| 272 | } | 268 | } |
| 273 | spin_unlock(&i915->fb_tracking.lock); | 269 | spin_unlock(&i915->fb_tracking.lock); |
| 274 | 270 | ||
| @@ -27,10 +27,10 @@ · 26 unmodified lines | |||
| 27 | #include <linux/atomic.h> | 27 | #include <linux/atomic.h> |
| 28 | #include <linux/kref.h> | 28 | #include <linux/kref.h> |
| 29 | 29 | ||
| 30 | #include "gem/i915_gem_object_types.h" | ||
| 30 | #include "i915_active.h" | 31 | #include "i915_active.h" |
| 31 | 32 | ||
| 32 | struct drm_i915_private; | 33 | struct drm_i915_private; |
| 33 | struct drm_i915_gem_object; | ||
| 34 | 34 | ||
| 35 | enum fb_op_origin { | 35 | enum fb_op_origin { |
| 36 | ORIGIN_GTT, | 36 | ORIGIN_GTT, |
| @@ -45,6 +45,7 @@ struct intel_frontbuffer { · 8 unmodified lines | |||
| 45 | atomic_t bits; | 45 | atomic_t bits; |
| 46 | struct i915_active write; | 46 | struct i915_active write; |
| 47 | struct drm_i915_gem_object *obj; | 47 | struct drm_i915_gem_object *obj; |
| 48 | struct rcu_head rcu; | ||
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, | 51 | void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, |
| @@ -54,6 +55,35 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915, · 3 unmodified lines | |||
| 54 | void intel_frontbuffer_flip(struct drm_i915_private *i915, | 55 | void intel_frontbuffer_flip(struct drm_i915_private *i915, |
| 55 | unsigned frontbuffer_bits); | 56 | unsigned frontbuffer_bits); |
| 56 | 57 | ||
| 58 | void intel_frontbuffer_put(struct intel_frontbuffer *front); | ||
| 59 | |||
| 60 | static inline struct intel_frontbuffer * | ||
| 61 | __intel_frontbuffer_get(const struct drm_i915_gem_object *obj) | ||
| 62 | { | ||
| 63 | struct intel_frontbuffer *front; | ||
| 64 | |||
| 65 | if (likely(!rcu_access_pointer(obj->frontbuffer))) | ||
| 66 | return NULL; | ||
| 67 | |||
| 68 | rcu_read_lock(); | ||
| 69 | do { | ||
| 70 | front = rcu_dereference(obj->frontbuffer); | ||
| 71 | if (!front) | ||
| 72 | break; | ||
| 73 | |||
| 74 | if (unlikely(!kref_get_unless_zero(&front->ref))) | ||
| 75 | continue; | ||
| 76 | |||
| 77 | if (likely(front == rcu_access_pointer(obj->frontbuffer))) | ||
| 78 | break; | ||
| 79 | |||
| 80 | intel_frontbuffer_put(front); | ||
| 81 | } while (1); | ||
| 82 | rcu_read_unlock(); | ||
| 83 | |||
| 84 | return front; | ||
| 85 | } | ||
| 86 | |||
| 57 | struct intel_frontbuffer * | 87 | struct intel_frontbuffer * |
| 58 | intel_frontbuffer_get(struct drm_i915_gem_object *obj); | 88 | intel_frontbuffer_get(struct drm_i915_gem_object *obj); |
| 59 | 89 | ||
| @@ -119,6 +149,4 @@ void intel_frontbuffer_track(struct intel_frontbuffer *old, · 59 unmodified lines | |||
| 119 | struct intel_frontbuffer *new, | 149 | struct intel_frontbuffer *new, |
| 120 | unsigned int frontbuffer_bits); | 150 | unsigned int frontbuffer_bits); |
| 121 | 151 | ||
| 122 | void intel_frontbuffer_put(struct intel_frontbuffer *front); | ||
| 123 | |||
| 124 | #endif /* __INTEL_FRONTBUFFER_H__ */ | 152 | #endif /* __INTEL_FRONTBUFFER_H__ */ |
| @@ -279,12 +279,21 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay, · 278 unmodified lines | |||
| 279 | struct i915_vma *vma) | 279 | struct i915_vma *vma) |
| 280 | { | 280 | { |
| 281 | enum pipe pipe = overlay->crtc->pipe; | 281 | enum pipe pipe = overlay->crtc->pipe; |
| 282 | struct intel_frontbuffer *from = NULL, *to = NULL; | ||
| 282 | 283 | ||
| 283 | WARN_ON(overlay->old_vma); | 284 | WARN_ON(overlay->old_vma); |
| 284 | 285 | ||
| 285 | intel_frontbuffer_track(overlay->vma ? overlay->vma->obj->frontbuffer : NULL, | 286 | if (overlay->vma) |
| 286 | vma ? vma->obj->frontbuffer : NULL, | 287 | from = intel_frontbuffer_get(overlay->vma->obj); |
| 287 | INTEL_FRONTBUFFER_OVERLAY(pipe)); | 288 | if (vma) |
| 289 | to = intel_frontbuffer_get(vma->obj); | ||
| 290 | |||
| 291 | intel_frontbuffer_track(from, to, INTEL_FRONTBUFFER_OVERLAY(pipe)); | ||
| 292 | |||
| 293 | if (to) | ||
| 294 | intel_frontbuffer_put(to); | ||
| 295 | if (from) | ||
| 296 | intel_frontbuffer_put(from); | ||
| 288 | 297 | ||
| 289 | intel_frontbuffer_flip_prepare(overlay->i915, | 298 | intel_frontbuffer_flip_prepare(overlay->i915, |
| 290 | INTEL_FRONTBUFFER_OVERLAY(pipe)); | 299 | INTEL_FRONTBUFFER_OVERLAY(pipe)); |
| @@ -766,7 +775,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, · 475 unmodified lines | |||
| 766 | ret = PTR_ERR(vma); | 775 | ret = PTR_ERR(vma); |
| 767 | goto out_pin_section; | 776 | goto out_pin_section; |
| 768 | } | 777 | } |
| 769 | intel_frontbuffer_flush(new_bo->frontbuffer, ORIGIN_DIRTYFB); | 778 | i915_gem_object_flush_frontbuffer(new_bo, ORIGIN_DIRTYFB); |
| 770 | 779 | ||
| 771 | if (!overlay->active) { | 780 | if (!overlay->active) { |
| 772 | u32 oconfig; | 781 | u32 oconfig; |
| @@ -20,7 +20,8 @@ static void __do_clflush(struct drm_i915_gem_object *obj) · 19 unmodified lines | |||
| 20 | { | 20 | { |
| 21 | GEM_BUG_ON(!i915_gem_object_has_pages(obj)); | 21 | GEM_BUG_ON(!i915_gem_object_has_pages(obj)); |
| 22 | drm_clflush_sg(obj->mm.pages); | 22 | drm_clflush_sg(obj->mm.pages); |
| 23 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); | 23 | |
| 24 | i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); | ||
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | static int clflush_work(struct dma_fence_work *base) | 27 | static int clflush_work(struct dma_fence_work *base) |
| @@ -664,7 +664,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, · 663 unmodified lines | |||
| 664 | i915_gem_object_unlock(obj); | 664 | i915_gem_object_unlock(obj); |
| 665 | 665 | ||
| 666 | if (write_domain) | 666 | if (write_domain) |
| 667 | intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); | 667 | i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); |
| 668 | 668 | ||
| 669 | out_unpin: | 669 | out_unpin: |
| 670 | i915_gem_object_unpin_pages(obj); | 670 | i915_gem_object_unpin_pages(obj); |
| @@ -784,7 +784,7 @@ int i915_gem_object_prepare_write(struct drm_i915_gem_object *obj, · 113 unmodified lines | |||
| 784 | } | 784 | } |
| 785 | 785 | ||
| 786 | out: | 786 | out: |
| 787 | intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); | 787 | i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); |
| 788 | obj->mm.dirty = true; | 788 | obj->mm.dirty = true; |
| 789 | /* return with the pages pinned */ | 789 | /* return with the pages pinned */ |
| 790 | return 0; | 790 | return 0; |
| @@ -280,7 +280,7 @@ i915_gem_object_flush_write_domain(struct drm_i915_gem_object *obj, · 279 unmodified lines | |||
| 280 | for_each_ggtt_vma(vma, obj) | 280 | for_each_ggtt_vma(vma, obj) |
| 281 | intel_gt_flush_ggtt_writes(vma->vm->gt); | 281 | intel_gt_flush_ggtt_writes(vma->vm->gt); |
| 282 | 282 | ||
| 283 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); | 283 | i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); |
| 284 | 284 | ||
| 285 | for_each_ggtt_vma(vma, obj) { | 285 | for_each_ggtt_vma(vma, obj) { |
| 286 | if (vma->iomap) | 286 | if (vma->iomap) |
| @@ -308,6 +308,30 @@ i915_gem_object_flush_write_domain(struct drm_i915_gem_object *obj, · 21 unmodified lines | |||
| 308 | obj->write_domain = 0; | 308 | obj->write_domain = 0; |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 312 | enum fb_op_origin origin) | ||
| 313 | { | ||
| 314 | struct intel_frontbuffer *front; | ||
| 315 | |||
| 316 | front = __intel_frontbuffer_get(obj); | ||
| 317 | if (front) { | ||
| 318 | intel_frontbuffer_flush(front, origin); | ||
| 319 | intel_frontbuffer_put(front); | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 324 | enum fb_op_origin origin) | ||
| 325 | { | ||
| 326 | struct intel_frontbuffer *front; | ||
| 327 | |||
| 328 | front = __intel_frontbuffer_get(obj); | ||
| 329 | if (front) { | ||
| 330 | intel_frontbuffer_invalidate(front, origin); | ||
| 331 | intel_frontbuffer_put(front); | ||
| 332 | } | ||
| 333 | } | ||
| 334 | |||
| 311 | void i915_gem_init__objects(struct drm_i915_private *i915) | 335 | void i915_gem_init__objects(struct drm_i915_private *i915) |
| 312 | { | 336 | { |
| 313 | INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); | 337 | INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); |
| @@ -13,8 +13,8 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | #include <drm/i915_drm.h> | 14 | #include <drm/i915_drm.h> |
| 15 | 15 | ||
| 16 | #include "display/intel_frontbuffer.h" | ||
| 16 | #include "i915_gem_object_types.h" | 17 | #include "i915_gem_object_types.h" |
| 17 | |||
| 18 | #include "i915_gem_gtt.h" | 18 | #include "i915_gem_gtt.h" |
| 19 | 19 | ||
| 20 | void i915_gem_init__objects(struct drm_i915_private *i915); | 20 | void i915_gem_init__objects(struct drm_i915_private *i915); |
| @@ -463,4 +463,25 @@ int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, · 442 unmodified lines | |||
| 463 | unsigned int flags, | 463 | unsigned int flags, |
| 464 | const struct i915_sched_attr *attr); | 464 | const struct i915_sched_attr *attr); |
| 465 | 465 | ||
| 466 | void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 467 | enum fb_op_origin origin); | ||
| 468 | void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 469 | enum fb_op_origin origin); | ||
| 470 | |||
| 471 | static inline void | ||
| 472 | i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 473 | enum fb_op_origin origin) | ||
| 474 | { | ||
| 475 | if (unlikely(rcu_access_pointer(obj->frontbuffer))) | ||
| 476 | __i915_gem_object_flush_frontbuffer(obj, origin); | ||
| 477 | } | ||
| 478 | |||
| 479 | static inline void | ||
| 480 | i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 481 | enum fb_op_origin origin) | ||
| 482 | { | ||
| 483 | if (unlikely(rcu_access_pointer(obj->frontbuffer))) | ||
| 484 | __i915_gem_object_invalidate_frontbuffer(obj, origin); | ||
| 485 | } | ||
| 486 | |||
| 466 | #endif | 487 | #endif |
| @@ -150,7 +150,7 @@ struct drm_i915_gem_object { · 149 unmodified lines | |||
| 150 | */ | 150 | */ |
| 151 | u16 write_domain; | 151 | u16 write_domain; |
| 152 | 152 | ||
| 153 | struct intel_frontbuffer *frontbuffer; | 153 | struct intel_frontbuffer __rcu *frontbuffer; |
| 154 | 154 | ||
| 155 | /** Current tiling stride for the object, if it's tiled. */ | 155 | /** Current tiling stride for the object, if it's tiled. */ |
| 156 | unsigned int tiling_and_stride; | 156 | unsigned int tiling_and_stride; |
| @@ -94,8 +94,9 @@ static int __gt_park(struct intel_wakeref *wf) · 93 unmodified lines | |||
| 94 | intel_uncore_forcewake_put(&i915->uncore, FORCEWAKE_ALL); | 94 | intel_uncore_forcewake_put(&i915->uncore, FORCEWAKE_ALL); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | /* Defer dropping the display power well for 100ms, it's slow! */ | ||
| 97 | GEM_BUG_ON(!wakeref); | 98 | GEM_BUG_ON(!wakeref); |
| 98 | intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ, wakeref); | 99 | intel_display_power_put_async(i915, POWER_DOMAIN_GT_IRQ, wakeref); |
| 99 | 100 | ||
| 100 | i915_globals_park(); | 101 | i915_globals_park(); |
| 101 | 102 | ||
| @@ -4416,9 +4416,11 @@ intel_execlists_create_virtual(struct i915_gem_context *ctx, · 4415 unmodified lines | |||
| 4416 | ve->base.gt = siblings[0]->gt; | 4416 | ve->base.gt = siblings[0]->gt; |
| 4417 | ve->base.uncore = siblings[0]->uncore; | 4417 | ve->base.uncore = siblings[0]->uncore; |
| 4418 | ve->base.id = -1; | 4418 | ve->base.id = -1; |
| 4419 | |||
| 4419 | ve->base.class = OTHER_CLASS; | 4420 | ve->base.class = OTHER_CLASS; |
| 4420 | ve->base.uabi_class = I915_ENGINE_CLASS_INVALID; | 4421 | ve->base.uabi_class = I915_ENGINE_CLASS_INVALID; |
| 4421 | ve->base.instance = I915_ENGINE_CLASS_INVALID_VIRTUAL; | 4422 | ve->base.instance = I915_ENGINE_CLASS_INVALID_VIRTUAL; |
| 4423 | ve->base.uabi_instance = I915_ENGINE_CLASS_INVALID_VIRTUAL; | ||
| 4422 | 4424 | ||
| 4423 | /* | 4425 | /* |
| 4424 | * The decision on whether to submit a request using semaphores | 4426 | * The decision on whether to submit a request using semaphores |
| @@ -1413,14 +1413,6 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags) · 1412 unmodified lines | |||
| 1413 | int len; | 1413 | int len; |
| 1414 | u32 *cs; | 1414 | u32 *cs; |
| 1415 | 1415 | ||
| 1416 | flags |= MI_MM_SPACE_GTT; | ||
| 1417 | if (IS_HASWELL(i915)) | ||
| 1418 | /* These flags are for resource streamer on HSW+ */ | ||
| 1419 | flags |= HSW_MI_RS_SAVE_STATE_EN | HSW_MI_RS_RESTORE_STATE_EN; | ||
| 1420 | else | ||
| 1421 | /* We need to save the extended state for powersaving modes */ | ||
| 1422 | flags |= MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN; | ||
| 1423 | |||
| 1424 | len = 4; | 1416 | len = 4; |
| 1425 | if (IS_GEN(i915, 7)) | 1417 | if (IS_GEN(i915, 7)) |
| 1426 | len += 2 + (num_engines ? 4 * num_engines + 6 : 0); | 1418 | len += 2 + (num_engines ? 4 * num_engines + 6 : 0); |
| @@ -1589,22 +1581,21 @@ static int switch_context(struct i915_request *rq) · 162 unmodified lines | |||
| 1589 | } | 1581 | } |
| 1590 | 1582 | ||
| 1591 | if (ce->state) { | 1583 | if (ce->state) { |
| 1592 | u32 hw_flags; | 1584 | u32 flags; |
| 1593 | 1585 | ||
| 1594 | GEM_BUG_ON(rq->engine->id != RCS0); | 1586 | GEM_BUG_ON(rq->engine->id != RCS0); |
| 1595 | 1587 | ||
| 1596 | /* | 1588 | /* For resource streamer on HSW+ and power context elsewhere */ |
| 1597 | * The kernel context(s) is treated as pure scratch and is not | 1589 | BUILD_BUG_ON(HSW_MI_RS_SAVE_STATE_EN != MI_SAVE_EXT_STATE_EN); |
| 1598 | * expected to retain any state (as we sacrifice it during | 1590 | BUILD_BUG_ON(HSW_MI_RS_RESTORE_STATE_EN != MI_RESTORE_EXT_STATE_EN); |
| 1599 | * suspend and on resume it may be corrupted). This is ok, | 1591 | |
| 1600 | * as nothing actually executes using the kernel context; it | 1592 | flags = MI_SAVE_EXT_STATE_EN | MI_MM_SPACE_GTT; |
| 1601 | * is purely used for flushing user contexts. | 1593 | if (!i915_gem_context_is_kernel(rq->gem_context)) |
| 1602 | */ | 1594 | flags |= MI_RESTORE_EXT_STATE_EN; |
| 1603 | hw_flags = 0; | 1595 | else |
| 1604 | if (i915_gem_context_is_kernel(rq->gem_context)) | 1596 | flags |= MI_RESTORE_INHIBIT; |
| 1605 | hw_flags = MI_RESTORE_INHIBIT; | ||
| 1606 | 1597 | ||
| 1607 | ret = mi_set_context(rq, hw_flags); | 1598 | ret = mi_set_context(rq, flags); |
| 1608 | if (ret) | 1599 | if (ret) |
| 1609 | return ret; | 1600 | return ret; |
| 1610 | } | 1601 | } |
| @@ -1660,8 +1660,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, · 1659 unmodified lines | |||
| 1660 | (IS_BROADWELL(dev_priv) || IS_GEN(dev_priv, 9)) | 1660 | (IS_BROADWELL(dev_priv) || IS_GEN(dev_priv, 9)) |
| 1661 | 1661 | ||
| 1662 | /* WaRsDisableCoarsePowerGating:skl,cnl */ | 1662 | /* WaRsDisableCoarsePowerGating:skl,cnl */ |
| 1663 | #define NEEDS_WaRsDisableCoarsePowerGating(dev_priv) \ | 1663 | #define NEEDS_WaRsDisableCoarsePowerGating(dev_priv) \ |
| 1664 | (IS_CANNONLAKE(dev_priv) || IS_GEN(dev_priv, 9)) | 1664 | (IS_CANNONLAKE(dev_priv) || \ |
| 1665 | IS_SKL_GT3(dev_priv) || \ | ||
| 1666 | IS_SKL_GT4(dev_priv)) | ||
| 1665 | 1667 | ||
| 1666 | #define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4) | 1668 | #define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4) |
| 1667 | #define HAS_GMBUS_BURST_READ(dev_priv) (INTEL_GEN(dev_priv) >= 10 || \ | 1669 | #define HAS_GMBUS_BURST_READ(dev_priv) (INTEL_GEN(dev_priv) >= 10 || \ |
| @@ -161,7 +161,7 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, · 160 unmodified lines | |||
| 161 | * We manually control the domain here and pretend that it | 161 | * We manually control the domain here and pretend that it |
| 162 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. | 162 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. |
| 163 | */ | 163 | */ |
| 164 | intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); | 164 | i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); |
| 165 | 165 | ||
| 166 | if (copy_from_user(vaddr, user_data, args->size)) | 166 | if (copy_from_user(vaddr, user_data, args->size)) |
| 167 | return -EFAULT; | 167 | return -EFAULT; |
| @@ -169,7 +169,7 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, · 1 unmodified line | |||
| 169 | drm_clflush_virt_range(vaddr, args->size); | 169 | drm_clflush_virt_range(vaddr, args->size); |
| 170 | intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt); | 170 | intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt); |
| 171 | 171 | ||
| 172 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); | 172 | i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); |
| 173 | return 0; | 173 | return 0; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| @@ -589,7 +589,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, · 413 unmodified lines | |||
| 589 | goto out_unpin; | 589 | goto out_unpin; |
| 590 | } | 590 | } |
| 591 | 591 | ||
| 592 | intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); | 592 | i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); |
| 593 | 593 | ||
| 594 | user_data = u64_to_user_ptr(args->data_ptr); | 594 | user_data = u64_to_user_ptr(args->data_ptr); |
| 595 | offset = args->offset; | 595 | offset = args->offset; |
| @@ -631,7 +631,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, · 35 unmodified lines | |||
| 631 | user_data += page_length; | 631 | user_data += page_length; |
| 632 | offset += page_length; | 632 | offset += page_length; |
| 633 | } | 633 | } |
| 634 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); | 634 | i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); |
| 635 | 635 | ||
| 636 | i915_gem_object_unlock_fence(obj, fence); | 636 | i915_gem_object_unlock_fence(obj, fence); |
| 637 | out_unpin: | 637 | out_unpin: |
| @@ -721,7 +721,7 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj, · 83 unmodified lines | |||
| 721 | offset = 0; | 721 | offset = 0; |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); | 724 | i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); |
| 725 | i915_gem_object_unlock_fence(obj, fence); | 725 | i915_gem_object_unlock_fence(obj, fence); |
| 726 | 726 | ||
| 727 | return ret; | 727 | return ret; |
| @@ -144,61 +144,40 @@ static inline s64 ktime_since(const ktime_t kt) · 143 unmodified lines | |||
| 144 | return ktime_to_ns(ktime_sub(ktime_get(), kt)); | 144 | return ktime_to_ns(ktime_sub(ktime_get(), kt)); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | static u64 __pmu_estimate_rc6(struct i915_pmu *pmu) | ||
| 148 | { | ||
| 149 | u64 val; | ||
| 150 | |||
| 151 | /* | ||
| 152 | * We think we are runtime suspended. | ||
| 153 | * | ||
| 154 | * Report the delta from when the device was suspended to now, | ||
| 155 | * on top of the last known real value, as the approximated RC6 | ||
| 156 | * counter value. | ||
| 157 | */ | ||
| 158 | val = ktime_since(pmu->sleep_last); | ||
| 159 | val += pmu->sample[__I915_SAMPLE_RC6].cur; | ||
| 160 | |||
| 161 | pmu->sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; | ||
| 162 | |||
| 163 | return val; | ||
| 164 | } | ||
| 165 | |||
| 166 | static u64 __pmu_update_rc6(struct i915_pmu *pmu, u64 val) | ||
| 167 | { | ||
| 168 | /* | ||
| 169 | * If we are coming back from being runtime suspended we must | ||
| 170 | * be careful not to report a larger value than returned | ||
| 171 | * previously. | ||
| 172 | */ | ||
| 173 | if (val >= pmu->sample[__I915_SAMPLE_RC6_ESTIMATED].cur) { | ||
| 174 | pmu->sample[__I915_SAMPLE_RC6_ESTIMATED].cur = 0; | ||
| 175 | pmu->sample[__I915_SAMPLE_RC6].cur = val; | ||
| 176 | } else { | ||
| 177 | val = pmu->sample[__I915_SAMPLE_RC6_ESTIMATED].cur; | ||
| 178 | } | ||
| 179 | |||
| 180 | return val; | ||
| 181 | } | ||
| 182 | |||
| 183 | static u64 get_rc6(struct intel_gt *gt) | 147 | static u64 get_rc6(struct intel_gt *gt) |
| 184 | { | 148 | { |
| 185 | struct drm_i915_private *i915 = gt->i915; | 149 | struct drm_i915_private *i915 = gt->i915; |
| 186 | struct i915_pmu *pmu = &i915->pmu; | 150 | struct i915_pmu *pmu = &i915->pmu; |
| 187 | unsigned long flags; | 151 | unsigned long flags; |
| 152 | bool awake = false; | ||
| 188 | u64 val; | 153 | u64 val; |
| 189 | 154 | ||
| 190 | val = 0; | ||
| 191 | if (intel_gt_pm_get_if_awake(gt)) { | 155 | if (intel_gt_pm_get_if_awake(gt)) { |
| 192 | val = __get_rc6(gt); | 156 | val = __get_rc6(gt); |
| 193 | intel_gt_pm_put_async(gt); | 157 | intel_gt_pm_put_async(gt); |
| 158 | awake = true; | ||
| 194 | } | 159 | } |
| 195 | 160 | ||
| 196 | spin_lock_irqsave(&pmu->lock, flags); | 161 | spin_lock_irqsave(&pmu->lock, flags); |
| 197 | 162 | ||
| 198 | if (val) | 163 | if (awake) { |
| 199 | val = __pmu_update_rc6(pmu, val); | 164 | pmu->sample[__I915_SAMPLE_RC6].cur = val; |
| 165 | } else { | ||
| 166 | /* | ||
| 167 | * We think we are runtime suspended. | ||
| 168 | * | ||
| 169 | * Report the delta from when the device was suspended to now, | ||
| 170 | * on top of the last known real value, as the approximated RC6 | ||
| 171 | * counter value. | ||
| 172 | */ | ||
| 173 | val = ktime_since(pmu->sleep_last); | ||
| 174 | val += pmu->sample[__I915_SAMPLE_RC6].cur; | ||
| 175 | } | ||
| 176 | |||
| 177 | if (val < pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur) | ||
| 178 | val = pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur; | ||
| 200 | else | 179 | else |
| 201 | val = __pmu_estimate_rc6(pmu); | 180 | pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = val; |
| 202 | 181 | ||
| 203 | spin_unlock_irqrestore(&pmu->lock, flags); | 182 | spin_unlock_irqrestore(&pmu->lock, flags); |
| 204 | 183 | ||
| @@ -210,20 +189,11 @@ static void park_rc6(struct drm_i915_private *i915) · 5 unmodified lines | |||
| 210 | struct i915_pmu *pmu = &i915->pmu; | 189 | struct i915_pmu *pmu = &i915->pmu; |
| 211 | 190 | ||
| 212 | if (pmu->enable & config_enabled_mask(I915_PMU_RC6_RESIDENCY)) | 191 | if (pmu->enable & config_enabled_mask(I915_PMU_RC6_RESIDENCY)) |
| 213 | __pmu_update_rc6(pmu, __get_rc6(&i915->gt)); | 192 | pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); |
| 214 | 193 | ||
| 215 | pmu->sleep_last = ktime_get(); | 194 | pmu->sleep_last = ktime_get(); |
| 216 | } | 195 | } |
| 217 | 196 | ||
| 218 | static void unpark_rc6(struct drm_i915_private *i915) | ||
| 219 | { | ||
| 220 | struct i915_pmu *pmu = &i915->pmu; | ||
| 221 | |||
| 222 | /* Estimate how long we slept and accumulate that into rc6 counters */ | ||
| 223 | if (pmu->enable & config_enabled_mask(I915_PMU_RC6_RESIDENCY)) | ||
| 224 | __pmu_estimate_rc6(pmu); | ||
| 225 | } | ||
| 226 | |||
| 227 | #else | 197 | #else |
| 228 | 198 | ||
| 229 | static u64 get_rc6(struct intel_gt *gt) | 199 | static u64 get_rc6(struct intel_gt *gt) |
| @@ -232,7 +202,6 @@ static u64 get_rc6(struct intel_gt *gt) · 2 unmodified lines | |||
| 232 | } | 202 | } |
| 233 | 203 | ||
| 234 | static void park_rc6(struct drm_i915_private *i915) {} | 204 | static void park_rc6(struct drm_i915_private *i915) {} |
| 235 | static void unpark_rc6(struct drm_i915_private *i915) {} | ||
| 236 | 205 | ||
| 237 | #endif | 206 | #endif |
| 238 | 207 | ||
| @@ -281,8 +250,6 @@ void i915_pmu_gt_unparked(struct drm_i915_private *i915) · 42 unmodified lines | |||
| 281 | */ | 250 | */ |
| 282 | __i915_pmu_maybe_start_timer(pmu); | 251 | __i915_pmu_maybe_start_timer(pmu); |
| 283 | 252 | ||
| 284 | unpark_rc6(i915); | ||
| 285 | |||
| 286 | spin_unlock_irq(&pmu->lock); | 253 | spin_unlock_irq(&pmu->lock); |
| 287 | } | 254 | } |
| 288 | 255 | ||
| @@ -18,7 +18,7 @@ enum { · 17 unmodified lines | |||
| 18 | __I915_SAMPLE_FREQ_ACT = 0, | 18 | __I915_SAMPLE_FREQ_ACT = 0, |
| 19 | __I915_SAMPLE_FREQ_REQ, | 19 | __I915_SAMPLE_FREQ_REQ, |
| 20 | __I915_SAMPLE_RC6, | 20 | __I915_SAMPLE_RC6, |
| 21 | __I915_SAMPLE_RC6_ESTIMATED, | 21 | __I915_SAMPLE_RC6_LAST_REPORTED, |
| 22 | __I915_NUM_PMU_SAMPLERS | 22 | __I915_NUM_PMU_SAMPLERS |
| 23 | }; | 23 | }; |
| 24 | 24 | ||
| @@ -4177,7 +4177,13 @@ enum { · 4176 unmodified lines | |||
| 4177 | #define CPSSUNIT_CLKGATE_DIS REG_BIT(9) | 4177 | #define CPSSUNIT_CLKGATE_DIS REG_BIT(9) |
| 4178 | 4178 | ||
| 4179 | #define UNSLICE_UNIT_LEVEL_CLKGATE _MMIO(0x9434) | 4179 | #define UNSLICE_UNIT_LEVEL_CLKGATE _MMIO(0x9434) |
| 4180 | #define VFUNIT_CLKGATE_DIS (1 << 20) | 4180 | #define VFUNIT_CLKGATE_DIS REG_BIT(20) |
| 4181 | #define HSUNIT_CLKGATE_DIS REG_BIT(8) | ||
| 4182 | #define VSUNIT_CLKGATE_DIS REG_BIT(3) | ||
| 4183 | |||
| 4184 | #define UNSLICE_UNIT_LEVEL_CLKGATE2 _MMIO(0x94e4) | ||
| 4185 | #define VSUNIT_CLKGATE_DIS_TGL REG_BIT(19) | ||
| 4186 | #define PSDUNIT_CLKGATE_DIS REG_BIT(5) | ||
| 4181 | 4187 | ||
| 4182 | #define INF_UNIT_LEVEL_CLKGATE _MMIO(0x9560) | 4188 | #define INF_UNIT_LEVEL_CLKGATE _MMIO(0x9560) |
| 4183 | #define CGPSF_CLKGATE_DIS (1 << 3) | 4189 | #define CGPSF_CLKGATE_DIS (1 << 3) |
| @@ -1104,8 +1104,14 @@ int i915_vma_move_to_active(struct i915_vma *vma, · 1103 unmodified lines | |||
| 1104 | return err; | 1104 | return err; |
| 1105 | 1105 | ||
| 1106 | if (flags & EXEC_OBJECT_WRITE) { | 1106 | if (flags & EXEC_OBJECT_WRITE) { |
| 1107 | if (intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CS)) | 1107 | struct intel_frontbuffer *front; |
| 1108 | i915_active_add_request(&obj->frontbuffer->write, rq); | 1108 | |
| 1109 | front = __intel_frontbuffer_get(obj); | ||
| 1110 | if (unlikely(front)) { | ||
| 1111 | if (intel_frontbuffer_invalidate(front, ORIGIN_CS)) | ||
| 1112 | i915_active_add_request(&front->write, rq); | ||
| 1113 | intel_frontbuffer_put(front); | ||
| 1114 | } | ||
| 1109 | 1115 | ||
| 1110 | dma_resv_add_excl_fence(vma->resv, &rq->fence); | 1116 | dma_resv_add_excl_fence(vma->resv, &rq->fence); |
| 1111 | obj->write_domain = I915_GEM_DOMAIN_RENDER; | 1117 | obj->write_domain = I915_GEM_DOMAIN_RENDER; |
| @@ -6565,6 +6565,17 @@ static void icl_init_clock_gating(struct drm_i915_private *dev_priv) · 6564 unmodified lines | |||
| 6565 | /* WaEnable32PlaneMode:icl */ | 6565 | /* WaEnable32PlaneMode:icl */ |
| 6566 | I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, | 6566 | I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, |
| 6567 | _MASKED_BIT_ENABLE(GEN11_ENABLE_32_PLANE_MODE)); | 6567 | _MASKED_BIT_ENABLE(GEN11_ENABLE_32_PLANE_MODE)); |
| 6568 | |||
| 6569 | /* | ||
| 6570 | * Wa_1408615072:icl,ehl (vsunit) | ||
| 6571 | * Wa_1407596294:icl,ehl (hsunit) | ||
| 6572 | */ | ||
| 6573 | intel_uncore_rmw(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE, | ||
| 6574 | 0, VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS); | ||
| 6575 | |||
| 6576 | /* Wa_1407352427:icl,ehl */ | ||
| 6577 | intel_uncore_rmw(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE2, | ||
| 6578 | 0, PSDUNIT_CLKGATE_DIS); | ||
| 6568 | } | 6579 | } |
| 6569 | 6580 | ||
| 6570 | static void tgl_init_clock_gating(struct drm_i915_private *dev_priv) | 6581 | static void tgl_init_clock_gating(struct drm_i915_private *dev_priv) |
| @@ -215,11 +215,12 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc, · 214 unmodified lines | |||
| 215 | struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); | 215 | struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); |
| 216 | struct mtk_ddp_comp *comp; | 216 | struct mtk_ddp_comp *comp; |
| 217 | int i, count = 0; | 217 | int i, count = 0; |
| 218 | unsigned int local_index = plane - mtk_crtc->planes; | ||
| 218 | 219 | ||
| 219 | for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { | 220 | for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { |
| 220 | comp = mtk_crtc->ddp_comp[i]; | 221 | comp = mtk_crtc->ddp_comp[i]; |
| 221 | if (plane->index < (count + mtk_ddp_comp_layer_nr(comp))) { | 222 | if (local_index < (count + mtk_ddp_comp_layer_nr(comp))) { |
| 222 | *local_layer = plane->index - count; | 223 | *local_layer = local_index - count; |
| 223 | return comp; | 224 | return comp; |
| 224 | } | 225 | } |
| 225 | count += mtk_ddp_comp_layer_nr(comp); | 226 | count += mtk_ddp_comp_layer_nr(comp); |
| @@ -310,7 +311,9 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) · 84 unmodified lines | |||
| 310 | 311 | ||
| 311 | plane_state = to_mtk_plane_state(plane->state); | 312 | plane_state = to_mtk_plane_state(plane->state); |
| 312 | comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer); | 313 | comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer); |
| 313 | mtk_ddp_comp_layer_config(comp, local_layer, plane_state); | 314 | if (comp) |
| 315 | mtk_ddp_comp_layer_config(comp, local_layer, | ||
| 316 | plane_state); | ||
| 314 | } | 317 | } |
| 315 | 318 | ||
| 316 | return 0; | 319 | return 0; |
| @@ -386,8 +389,9 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc) · 69 unmodified lines | |||
| 386 | comp = mtk_drm_ddp_comp_for_plane(crtc, plane, | 389 | comp = mtk_drm_ddp_comp_for_plane(crtc, plane, |
| 387 | &local_layer); | 390 | &local_layer); |
| 388 | 391 | ||
| 389 | mtk_ddp_comp_layer_config(comp, local_layer, | 392 | if (comp) |
| 390 | plane_state); | 393 | mtk_ddp_comp_layer_config(comp, local_layer, |
| 394 | plane_state); | ||
| 391 | plane_state->pending.config = false; | 395 | plane_state->pending.config = false; |
| 392 | } | 396 | } |
| 393 | mtk_crtc->pending_planes = false; | 397 | mtk_crtc->pending_planes = false; |
| @@ -401,7 +405,9 @@ int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane, · 7 unmodified lines | |||
| 401 | struct mtk_ddp_comp *comp; | 405 | struct mtk_ddp_comp *comp; |
| 402 | 406 | ||
| 403 | comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer); | 407 | comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer); |
| 404 | return mtk_ddp_comp_layer_check(comp, local_layer, state); | 408 | if (comp) |
| 409 | return mtk_ddp_comp_layer_check(comp, local_layer, state); | ||
| 410 | return 0; | ||
| 405 | } | 411 | } |
| 406 | 412 | ||
| 407 | static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, | 413 | static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, |
| @@ -230,28 +230,25 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, u32 mask, u32 data) · 229 unmodified lines | |||
| 230 | static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi) | 230 | static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi) |
| 231 | { | 231 | { |
| 232 | u32 timcon0, timcon1, timcon2, timcon3; | 232 | u32 timcon0, timcon1, timcon2, timcon3; |
| 233 | u32 ui, cycle_time; | 233 | u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, 1000000); |
| 234 | struct mtk_phy_timing *timing = &dsi->phy_timing; | 234 | struct mtk_phy_timing *timing = &dsi->phy_timing; |
| 235 | 235 | ||
| 236 | ui = DIV_ROUND_UP(1000000000, dsi->data_rate); | 236 | timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1; |
| 237 | cycle_time = div_u64(8000000000ULL, dsi->data_rate); | 237 | timing->da_hs_prepare = (80 * data_rate_mhz + 4 * 1000) / 8000; |
| 238 | timing->da_hs_zero = (170 * data_rate_mhz + 10 * 1000) / 8000 + 1 - | ||
| 239 | timing->da_hs_prepare; | ||
| 240 | timing->da_hs_trail = timing->da_hs_prepare + 1; | ||
| 238 | 241 | ||
| 239 | timing->lpx = NS_TO_CYCLE(60, cycle_time); | 242 | timing->ta_go = 4 * timing->lpx - 2; |
| 240 | timing->da_hs_prepare = NS_TO_CYCLE(50 + 5 * ui, cycle_time); | 243 | timing->ta_sure = timing->lpx + 2; |
| 241 | timing->da_hs_zero = NS_TO_CYCLE(110 + 6 * ui, cycle_time); | 244 | timing->ta_get = 4 * timing->lpx; |
| 242 | timing->da_hs_trail = NS_TO_CYCLE(77 + 4 * ui, cycle_time); | 245 | timing->da_hs_exit = 2 * timing->lpx + 1; |
| 243 | 246 | ||
| 244 | timing->ta_go = 4 * timing->lpx; | 247 | timing->clk_hs_prepare = 70 * data_rate_mhz / (8 * 1000); |
| 245 | timing->ta_sure = 3 * timing->lpx / 2; | 248 | timing->clk_hs_post = timing->clk_hs_prepare + 8; |
| 246 | timing->ta_get = 5 * timing->lpx; | 249 | timing->clk_hs_trail = timing->clk_hs_prepare; |
| 247 | timing->da_hs_exit = 2 * timing->lpx; | 250 | timing->clk_hs_zero = timing->clk_hs_trail * 4; |
| 248 | 251 | timing->clk_hs_exit = 2 * timing->clk_hs_trail; | |
| 249 | timing->clk_hs_zero = NS_TO_CYCLE(336, cycle_time); | ||
| 250 | timing->clk_hs_trail = NS_TO_CYCLE(100, cycle_time) + 10; | ||
| 251 | |||
| 252 | timing->clk_hs_prepare = NS_TO_CYCLE(64, cycle_time); | ||
| 253 | timing->clk_hs_post = NS_TO_CYCLE(80 + 52 * ui, cycle_time); | ||
| 254 | timing->clk_hs_exit = 2 * timing->lpx; | ||
| 255 | 252 | ||
| 256 | timcon0 = timing->lpx | timing->da_hs_prepare << 8 | | 253 | timcon0 = timing->lpx | timing->da_hs_prepare << 8 | |
| 257 | timing->da_hs_zero << 16 | timing->da_hs_trail << 24; | 254 | timing->da_hs_zero << 16 | timing->da_hs_trail << 24; |
| @@ -482,27 +479,39 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi) · 224 unmodified lines | |||
| 482 | dsi_tmp_buf_bpp - 10); | 479 | dsi_tmp_buf_bpp - 10); |
| 483 | 480 | ||
| 484 | data_phy_cycles = timing->lpx + timing->da_hs_prepare + | 481 | data_phy_cycles = timing->lpx + timing->da_hs_prepare + |
| 485 | timing->da_hs_zero + timing->da_hs_exit + 2; | 482 | timing->da_hs_zero + timing->da_hs_exit + 3; |
| 486 | 483 | ||
| 487 | if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { | 484 | if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { |
| 488 | if (vm->hfront_porch * dsi_tmp_buf_bpp > | 485 | if ((vm->hfront_porch + vm->hback_porch) * dsi_tmp_buf_bpp > |
| 489 | data_phy_cycles * dsi->lanes + 18) { | 486 | data_phy_cycles * dsi->lanes + 18) { |
| 490 | horizontal_frontporch_byte = vm->hfront_porch * | 487 | horizontal_frontporch_byte = |
| 491 | dsi_tmp_buf_bpp - | 488 | vm->hfront_porch * dsi_tmp_buf_bpp - |
| 492 | data_phy_cycles * | 489 | (data_phy_cycles * dsi->lanes + 18) * |
| 493 | dsi->lanes - 18; | 490 | vm->hfront_porch / |
| 491 | (vm->hfront_porch + vm->hback_porch); | ||
| 492 | |||
| 493 | horizontal_backporch_byte = | ||
| 494 | horizontal_backporch_byte - | ||
| 495 | (data_phy_cycles * dsi->lanes + 18) * | ||
| 496 | vm->hback_porch / | ||
| 497 | (vm->hfront_porch + vm->hback_porch); | ||
| 494 | } else { | 498 | } else { |
| 495 | DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); | 499 | DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); |
| 496 | horizontal_frontporch_byte = vm->hfront_porch * | 500 | horizontal_frontporch_byte = vm->hfront_porch * |
| 497 | dsi_tmp_buf_bpp; | 501 | dsi_tmp_buf_bpp; |
| 498 | } | 502 | } |
| 499 | } else { | 503 | } else { |
| 500 | if (vm->hfront_porch * dsi_tmp_buf_bpp > | 504 | if ((vm->hfront_porch + vm->hback_porch) * dsi_tmp_buf_bpp > |
| 501 | data_phy_cycles * dsi->lanes + 12) { | 505 | data_phy_cycles * dsi->lanes + 12) { |
| 502 | horizontal_frontporch_byte = vm->hfront_porch * | 506 | horizontal_frontporch_byte = |
| 503 | dsi_tmp_buf_bpp - | 507 | vm->hfront_porch * dsi_tmp_buf_bpp - |
| 504 | data_phy_cycles * | 508 | (data_phy_cycles * dsi->lanes + 12) * |
| 505 | dsi->lanes - 12; | 509 | vm->hfront_porch / |
| 510 | (vm->hfront_porch + vm->hback_porch); | ||
| 511 | horizontal_backporch_byte = horizontal_backporch_byte - | ||
| 512 | (data_phy_cycles * dsi->lanes + 12) * | ||
| 513 | vm->hback_porch / | ||
| 514 | (vm->hfront_porch + vm->hback_porch); | ||
| 506 | } else { | 515 | } else { |
| 507 | DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); | 516 | DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); |
| 508 | horizontal_frontporch_byte = vm->hfront_porch * | 517 | horizontal_frontporch_byte = vm->hfront_porch * |
| @@ -685,8 +685,6 @@ static void sun4i_hdmi_unbind(struct device *dev, struct device *master, · 684 unmodified lines | |||
| 685 | struct sun4i_hdmi *hdmi = dev_get_drvdata(dev); | 685 | struct sun4i_hdmi *hdmi = dev_get_drvdata(dev); |
| 686 | 686 | ||
| 687 | cec_unregister_adapter(hdmi->cec_adap); | 687 | cec_unregister_adapter(hdmi->cec_adap); |
| 688 | drm_connector_cleanup(&hdmi->connector); | ||
| 689 | drm_encoder_cleanup(&hdmi->encoder); | ||
| 690 | i2c_del_adapter(hdmi->i2c); | 688 | i2c_del_adapter(hdmi->i2c); |
| 691 | i2c_put_adapter(hdmi->ddc_i2c); | 689 | i2c_put_adapter(hdmi->ddc_i2c); |
| 692 | clk_disable_unprepare(hdmi->mod_clk); | 690 | clk_disable_unprepare(hdmi->mod_clk); |
| @@ -489,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, · 488 unmodified lines | |||
| 489 | 489 | ||
| 490 | WARN_ON(!tcon->quirks->has_channel_0); | 490 | WARN_ON(!tcon->quirks->has_channel_0); |
| 491 | 491 | ||
| 492 | tcon->dclk_min_div = 1; | 492 | tcon->dclk_min_div = tcon->quirks->dclk_min_div; |
| 493 | tcon->dclk_max_div = 127; | 493 | tcon->dclk_max_div = 127; |
| 494 | sun4i_tcon0_mode_set_common(tcon, mode); | 494 | sun4i_tcon0_mode_set_common(tcon, mode); |
| 495 | 495 | ||
| @@ -1426,12 +1426,14 @@ static int sun8i_r40_tcon_tv_set_mux(struct sun4i_tcon *tcon, · 930 unmodified lines | |||
| 1426 | static const struct sun4i_tcon_quirks sun4i_a10_quirks = { | 1426 | static const struct sun4i_tcon_quirks sun4i_a10_quirks = { |
| 1427 | .has_channel_0 = true, | 1427 | .has_channel_0 = true, |
| 1428 | .has_channel_1 = true, | 1428 | .has_channel_1 = true, |
| 1429 | .dclk_min_div = 4, | ||
| 1429 | .set_mux = sun4i_a10_tcon_set_mux, | 1430 | .set_mux = sun4i_a10_tcon_set_mux, |
| 1430 | }; | 1431 | }; |
| 1431 | 1432 | ||
| 1432 | static const struct sun4i_tcon_quirks sun5i_a13_quirks = { | 1433 | static const struct sun4i_tcon_quirks sun5i_a13_quirks = { |
| 1433 | .has_channel_0 = true, | 1434 | .has_channel_0 = true, |
| 1434 | .has_channel_1 = true, | 1435 | .has_channel_1 = true, |
| 1436 | .dclk_min_div = 4, | ||
| 1435 | .set_mux = sun5i_a13_tcon_set_mux, | 1437 | .set_mux = sun5i_a13_tcon_set_mux, |
| 1436 | }; | 1438 | }; |
| 1437 | 1439 | ||
| @@ -1440,6 +1442,7 @@ static const struct sun4i_tcon_quirks sun6i_a31_quirks = { · 2 unmodified lines | |||
| 1440 | .has_channel_1 = true, | 1442 | .has_channel_1 = true, |
| 1441 | .has_lvds_alt = true, | 1443 | .has_lvds_alt = true, |
| 1442 | .needs_de_be_mux = true, | 1444 | .needs_de_be_mux = true, |
| 1445 | .dclk_min_div = 1, | ||
| 1443 | .set_mux = sun6i_tcon_set_mux, | 1446 | .set_mux = sun6i_tcon_set_mux, |
| 1444 | }; | 1447 | }; |
| 1445 | 1448 | ||
| @@ -1447,11 +1450,13 @@ static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { · 1 unmodified line | |||
| 1447 | .has_channel_0 = true, | 1450 | .has_channel_0 = true, |
| 1448 | .has_channel_1 = true, | 1451 | .has_channel_1 = true, |
| 1449 | .needs_de_be_mux = true, | 1452 | .needs_de_be_mux = true, |
| 1453 | .dclk_min_div = 1, | ||
| 1450 | }; | 1454 | }; |
| 1451 | 1455 | ||
| 1452 | static const struct sun4i_tcon_quirks sun7i_a20_quirks = { | 1456 | static const struct sun4i_tcon_quirks sun7i_a20_quirks = { |
| 1453 | .has_channel_0 = true, | 1457 | .has_channel_0 = true, |
| 1454 | .has_channel_1 = true, | 1458 | .has_channel_1 = true, |
| 1459 | .dclk_min_div = 4, | ||
| 1455 | /* Same display pipeline structure as A10 */ | 1460 | /* Same display pipeline structure as A10 */ |
| 1456 | .set_mux = sun4i_a10_tcon_set_mux, | 1461 | .set_mux = sun4i_a10_tcon_set_mux, |
| 1457 | }; | 1462 | }; |
| @@ -1459,11 +1464,13 @@ static const struct sun4i_tcon_quirks sun7i_a20_quirks = { · 1 unmodified line | |||
| 1459 | static const struct sun4i_tcon_quirks sun8i_a33_quirks = { | 1464 | static const struct sun4i_tcon_quirks sun8i_a33_quirks = { |
| 1460 | .has_channel_0 = true, | 1465 | .has_channel_0 = true, |
| 1461 | .has_lvds_alt = true, | 1466 | .has_lvds_alt = true, |
| 1467 | .dclk_min_div = 1, | ||
| 1462 | }; | 1468 | }; |
| 1463 | 1469 | ||
| 1464 | static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { | 1470 | static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { |
| 1465 | .supports_lvds = true, | 1471 | .supports_lvds = true, |
| 1466 | .has_channel_0 = true, | 1472 | .has_channel_0 = true, |
| 1473 | .dclk_min_div = 1, | ||
| 1467 | }; | 1474 | }; |
| 1468 | 1475 | ||
| 1469 | static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { | 1476 | static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { |
| @@ -1477,11 +1484,13 @@ static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = { · 7 unmodified lines | |||
| 1477 | 1484 | ||
| 1478 | static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { | 1485 | static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { |
| 1479 | .has_channel_0 = true, | 1486 | .has_channel_0 = true, |
| 1487 | .dclk_min_div = 1, | ||
| 1480 | }; | 1488 | }; |
| 1481 | 1489 | ||
| 1482 | static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = { | 1490 | static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = { |
| 1483 | .has_channel_0 = true, | 1491 | .has_channel_0 = true, |
| 1484 | .needs_edp_reset = true, | 1492 | .needs_edp_reset = true, |
| 1493 | .dclk_min_div = 1, | ||
| 1485 | }; | 1494 | }; |
| 1486 | 1495 | ||
| 1487 | static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = { | 1496 | static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = { |
| @@ -224,6 +224,7 @@ struct sun4i_tcon_quirks { · 223 unmodified lines | |||
| 224 | bool needs_de_be_mux; /* sun6i needs mux to select backend */ | 224 | bool needs_de_be_mux; /* sun6i needs mux to select backend */ |
| 225 | bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */ | 225 | bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */ |
| 226 | bool supports_lvds; /* Does the TCON support an LVDS output? */ | 226 | bool supports_lvds; /* Does the TCON support an LVDS output? */ |
| 227 | u8 dclk_min_div; /* minimum divider for TCON0 DCLK */ | ||
| 227 | 228 | ||
| 228 | /* callback to handle tcon muxing options */ | 229 | /* callback to handle tcon muxing options */ |
| 229 | int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *); | 230 | int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *); |
| @@ -261,7 +261,8 @@ static int asus_event(struct hid_device *hdev, struct hid_field *field, · 260 unmodified lines | |||
| 261 | struct hid_usage *usage, __s32 value) | 261 | struct hid_usage *usage, __s32 value) |
| 262 | { | 262 | { |
| 263 | if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 && | 263 | if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 && |
| 264 | (usage->hid & HID_USAGE) != 0x00 && !usage->type) { | 264 | (usage->hid & HID_USAGE) != 0x00 && |
| 265 | (usage->hid & HID_USAGE) != 0xff && !usage->type) { | ||
| 265 | hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n", | 266 | hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n", |
| 266 | usage->hid & HID_USAGE); | 267 | usage->hid & HID_USAGE); |
| 267 | } | 268 | } |
| @@ -288,6 +288,12 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign · 287 unmodified lines | |||
| 288 | offset = report->size; | 288 | offset = report->size; |
| 289 | report->size += parser->global.report_size * parser->global.report_count; | 289 | report->size += parser->global.report_size * parser->global.report_count; |
| 290 | 290 | ||
| 291 | /* Total size check: Allow for possible report index byte */ | ||
| 292 | if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) { | ||
| 293 | hid_err(parser->device, "report is too long\n"); | ||
| 294 | return -1; | ||
| 295 | } | ||
| 296 | |||
| 291 | if (!parser->local.usage_index) /* Ignore padding fields */ | 297 | if (!parser->local.usage_index) /* Ignore padding fields */ |
| 292 | return 0; | 298 | return 0; |
| 293 | 299 | ||
| @@ -631,6 +631,7 @@ · 630 unmodified lines | |||
| 631 | #define USB_VENDOR_ID_ITE 0x048d | 631 | #define USB_VENDOR_ID_ITE 0x048d |
| 632 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 | 632 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 |
| 633 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 | 633 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 |
| 634 | #define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a | ||
| 634 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 | 635 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 |
| 635 | #define USB_DEVICE_ID_ITE8595 0x8595 | 636 | #define USB_DEVICE_ID_ITE8595 0x8595 |
| 636 | 637 | ||
| @@ -730,6 +731,7 @@ · 93 unmodified lines | |||
| 730 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 | 731 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 |
| 731 | #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 | 732 | #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 |
| 732 | #define I2C_DEVICE_ID_LG_8001 0x8001 | 733 | #define I2C_DEVICE_ID_LG_8001 0x8001 |
| 734 | #define I2C_DEVICE_ID_LG_7010 0x7010 | ||
| 733 | 735 | ||
| 734 | #define USB_VENDOR_ID_LOGITECH 0x046d | 736 | #define USB_VENDOR_ID_LOGITECH 0x046d |
| 735 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e | 737 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e |
| @@ -1102,6 +1104,7 @@ · 366 unmodified lines | |||
| 1102 | #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 | 1104 | #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 |
| 1103 | #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 | 1105 | #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 |
| 1104 | #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 | 1106 | #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 |
| 1107 | #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968 | ||
| 1105 | #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 | 1108 | #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 |
| 1106 | #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7 | 1109 | #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7 |
| 1107 | 1110 | ||
| @@ -1132,9 +1132,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel · 1131 unmodified lines | |||
| 1132 | } | 1132 | } |
| 1133 | 1133 | ||
| 1134 | mapped: | 1134 | mapped: |
| 1135 | if (device->driver->input_mapped && device->driver->input_mapped(device, | 1135 | if (device->driver->input_mapped && |
| 1136 | hidinput, field, usage, &bit, &max) < 0) | 1136 | device->driver->input_mapped(device, hidinput, field, usage, |
| 1137 | goto ignore; | 1137 | &bit, &max) < 0) { |
| 1138 | /* | ||
| 1139 | * The driver indicated that no further generic handling | ||
| 1140 | * of the usage is desired. | ||
| 1141 | */ | ||
| 1142 | return; | ||
| 1143 | } | ||
| 1138 | 1144 | ||
| 1139 | set_bit(usage->type, input->evbit); | 1145 | set_bit(usage->type, input->evbit); |
| 1140 | 1146 | ||
| @@ -1215,9 +1221,11 @@ mapped: · 74 unmodified lines | |||
| 1215 | set_bit(MSC_SCAN, input->mscbit); | 1221 | set_bit(MSC_SCAN, input->mscbit); |
| 1216 | } | 1222 | } |
| 1217 | 1223 | ||
| 1218 | ignore: | ||
| 1219 | return; | 1224 | return; |
| 1220 | 1225 | ||
| 1226 | ignore: | ||
| 1227 | usage->type = 0; | ||
| 1228 | usage->code = 0; | ||
| 1221 | } | 1229 | } |
| 1222 | 1230 | ||
| 1223 | static void hidinput_handle_scroll(struct hid_usage *usage, | 1231 | static void hidinput_handle_scroll(struct hid_usage *usage, |
| @@ -40,6 +40,9 @@ static int ite_event(struct hid_device *hdev, struct hid_field *field, · 39 unmodified lines | |||
| 40 | static const struct hid_device_id ite_devices[] = { | 40 | static const struct hid_device_id ite_devices[] = { |
| 41 | { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, | 41 | { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, |
| 42 | { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, | 42 | { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, |
| 43 | /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ | ||
| 44 | { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, | ||
| 45 | USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, | ||
| 43 | { } | 46 | { } |
| 44 | }; | 47 | }; |
| 45 | MODULE_DEVICE_TABLE(hid, ite_devices); | 48 | MODULE_DEVICE_TABLE(hid, ite_devices); |
| @@ -1019,7 +1019,7 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input, · 1018 unmodified lines | |||
| 1019 | tool = MT_TOOL_DIAL; | 1019 | tool = MT_TOOL_DIAL; |
| 1020 | else if (unlikely(!confidence_state)) { | 1020 | else if (unlikely(!confidence_state)) { |
| 1021 | tool = MT_TOOL_PALM; | 1021 | tool = MT_TOOL_PALM; |
| 1022 | if (!active && | 1022 | if (!active && mt && |
| 1023 | input_mt_is_active(&mt->slots[slotnum])) { | 1023 | input_mt_is_active(&mt->slots[slotnum])) { |
| 1024 | /* | 1024 | /* |
| 1025 | * The non-confidence was reported for | 1025 | * The non-confidence was reported for |
| @@ -1985,6 +1985,9 @@ static const struct hid_device_id mt_devices[] = { · 959 unmodified lines | |||
| 1985 | { .driver_data = MT_CLS_LG, | 1985 | { .driver_data = MT_CLS_LG, |
| 1986 | HID_USB_DEVICE(USB_VENDOR_ID_LG, | 1986 | HID_USB_DEVICE(USB_VENDOR_ID_LG, |
| 1987 | USB_DEVICE_ID_LG_MELFAS_MT) }, | 1987 | USB_DEVICE_ID_LG_MELFAS_MT) }, |
| 1988 | { .driver_data = MT_CLS_LG, | ||
| 1989 | HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, | ||
| 1990 | USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) }, | ||
| 1988 | 1991 | ||
| 1989 | /* MosArt panels */ | 1992 | /* MosArt panels */ |
| 1990 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 1993 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
| @@ -174,6 +174,7 @@ static const struct hid_device_id hid_quirks[] = { · 173 unmodified lines | |||
| 174 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT }, | 174 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT }, |
| 175 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 175 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
| 176 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 176 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
| 177 | { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT }, | ||
| 177 | 178 | ||
| 178 | { 0 } | 179 | { 0 } |
| 179 | }; | 180 | }; |
| @@ -768,8 +768,12 @@ static int steam_probe(struct hid_device *hdev, · 767 unmodified lines | |||
| 768 | 768 | ||
| 769 | if (steam->quirks & STEAM_QUIRK_WIRELESS) { | 769 | if (steam->quirks & STEAM_QUIRK_WIRELESS) { |
| 770 | hid_info(hdev, "Steam wireless receiver connected"); | 770 | hid_info(hdev, "Steam wireless receiver connected"); |
| 771 | /* If using a wireless adaptor ask for connection status */ | ||
| 772 | steam->connected = false; | ||
| 771 | steam_request_conn_status(steam); | 773 | steam_request_conn_status(steam); |
| 772 | } else { | 774 | } else { |
| 775 | /* A wired connection is always present */ | ||
| 776 | steam->connected = true; | ||
| 773 | ret = steam_register(steam); | 777 | ret = steam_register(steam); |
| 774 | if (ret) { | 778 | if (ret) { |
| 775 | hid_err(hdev, | 779 | hid_err(hdev, |
| @@ -249,13 +249,14 @@ out: · 248 unmodified lines | |||
| 249 | static __poll_t hidraw_poll(struct file *file, poll_table *wait) | 249 | static __poll_t hidraw_poll(struct file *file, poll_table *wait) |
| 250 | { | 250 | { |
| 251 | struct hidraw_list *list = file->private_data; | 251 | struct hidraw_list *list = file->private_data; |
| 252 | __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* hidraw is always writable */ | ||
| 252 | 253 | ||
| 253 | poll_wait(file, &list->hidraw->wait, wait); | 254 | poll_wait(file, &list->hidraw->wait, wait); |
| 254 | if (list->head != list->tail) | 255 | if (list->head != list->tail) |
| 255 | return EPOLLIN | EPOLLRDNORM | EPOLLOUT; | 256 | mask |= EPOLLIN | EPOLLRDNORM; |
| 256 | if (!list->hidraw->exist) | 257 | if (!list->hidraw->exist) |
| 257 | return EPOLLERR | EPOLLHUP; | 258 | mask |= EPOLLERR | EPOLLHUP; |
| 258 | return 0; | 259 | return mask; |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | static int hidraw_open(struct inode *inode, struct file *file) | 262 | static int hidraw_open(struct inode *inode, struct file *file) |
| @@ -49,6 +49,8 @@ · 48 unmodified lines | |||
| 49 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) | 49 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) |
| 50 | #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) | 50 | #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) |
| 51 | #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) | 51 | #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) |
| 52 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6) | ||
| 53 | |||
| 52 | 54 | ||
| 53 | /* flags */ | 55 | /* flags */ |
| 54 | #define I2C_HID_STARTED 0 | 56 | #define I2C_HID_STARTED 0 |
| @@ -175,6 +177,8 @@ static const struct i2c_hid_quirks { · 120 unmodified lines | |||
| 175 | I2C_HID_QUIRK_BOGUS_IRQ }, | 177 | I2C_HID_QUIRK_BOGUS_IRQ }, |
| 176 | { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, | 178 | { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, |
| 177 | I2C_HID_QUIRK_RESET_ON_RESUME }, | 179 | I2C_HID_QUIRK_RESET_ON_RESUME }, |
| 180 | { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, | ||
| 181 | I2C_HID_QUIRK_BAD_INPUT_SIZE }, | ||
| 178 | { 0, 0 } | 182 | { 0, 0 } |
| 179 | }; | 183 | }; |
| 180 | 184 | ||
| @@ -496,9 +500,15 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) · 315 unmodified lines | |||
| 496 | } | 500 | } |
| 497 | 501 | ||
| 498 | if ((ret_size > size) || (ret_size < 2)) { | 502 | if ((ret_size > size) || (ret_size < 2)) { |
| 499 | dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", | 503 | if (ihid->quirks & I2C_HID_QUIRK_BAD_INPUT_SIZE) { |
| 500 | __func__, size, ret_size); | 504 | ihid->inbuf[0] = size & 0xff; |
| 501 | return; | 505 | ihid->inbuf[1] = size >> 8; |
| 506 | ret_size = size; | ||
| 507 | } else { | ||
| 508 | dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", | ||
| 509 | __func__, size, ret_size); | ||
| 510 | return; | ||
| 511 | } | ||
| 502 | } | 512 | } |
| 503 | 513 | ||
| 504 | i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf); | 514 | i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf); |
| @@ -24,7 +24,9 @@ · 23 unmodified lines | |||
| 24 | #define ICL_MOBILE_DEVICE_ID 0x34FC | 24 | #define ICL_MOBILE_DEVICE_ID 0x34FC |
| 25 | #define SPT_H_DEVICE_ID 0xA135 | 25 | #define SPT_H_DEVICE_ID 0xA135 |
| 26 | #define CML_LP_DEVICE_ID 0x02FC | 26 | #define CML_LP_DEVICE_ID 0x02FC |
| 27 | #define CMP_H_DEVICE_ID 0x06FC | ||
| 27 | #define EHL_Ax_DEVICE_ID 0x4BB3 | 28 | #define EHL_Ax_DEVICE_ID 0x4BB3 |
| 29 | #define TGL_LP_DEVICE_ID 0xA0FC | ||
| 28 | 30 | ||
| 29 | #define REVISION_ID_CHT_A0 0x6 | 31 | #define REVISION_ID_CHT_A0 0x6 |
| 30 | #define REVISION_ID_CHT_Ax_SI 0x0 | 32 | #define REVISION_ID_CHT_Ax_SI 0x0 |
| @@ -34,7 +34,9 @@ static const struct pci_device_id ish_pci_tbl[] = { · 33 unmodified lines | |||
| 34 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ICL_MOBILE_DEVICE_ID)}, | 34 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ICL_MOBILE_DEVICE_ID)}, |
| 35 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_H_DEVICE_ID)}, | 35 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_H_DEVICE_ID)}, |
| 36 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CML_LP_DEVICE_ID)}, | 36 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CML_LP_DEVICE_ID)}, |
| 37 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CMP_H_DEVICE_ID)}, | ||
| 37 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, EHL_Ax_DEVICE_ID)}, | 38 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, EHL_Ax_DEVICE_ID)}, |
| 39 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, TGL_LP_DEVICE_ID)}, | ||
| 38 | {0, } | 40 | {0, } |
| 39 | }; | 41 | }; |
| 40 | MODULE_DEVICE_TABLE(pci, ish_pci_tbl); | 42 | MODULE_DEVICE_TABLE(pci, ish_pci_tbl); |
| @@ -766,13 +766,14 @@ unlock: · 765 unmodified lines | |||
| 766 | static __poll_t uhid_char_poll(struct file *file, poll_table *wait) | 766 | static __poll_t uhid_char_poll(struct file *file, poll_table *wait) |
| 767 | { | 767 | { |
| 768 | struct uhid_device *uhid = file->private_data; | 768 | struct uhid_device *uhid = file->private_data; |
| 769 | __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* uhid is always writable */ | ||
| 769 | 770 | ||
| 770 | poll_wait(file, &uhid->waitq, wait); | 771 | poll_wait(file, &uhid->waitq, wait); |
| 771 | 772 | ||
| 772 | if (uhid->head != uhid->tail) | 773 | if (uhid->head != uhid->tail) |
| 773 | return EPOLLIN | EPOLLRDNORM; | 774 | mask |= EPOLLIN | EPOLLRDNORM; |
| 774 | 775 | ||
| 775 | return 0; | 776 | return mask; |
| 776 | } | 777 | } |
| 777 | 778 | ||
| 778 | static const struct file_operations uhid_fops = { | 779 | static const struct file_operations uhid_fops = { |
| @@ -241,12 +241,51 @@ static int hiddev_release(struct inode * inode, struct file * file) · 240 unmodified lines | |||
| 241 | return 0; | 241 | return 0; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | static int __hiddev_open(struct hiddev *hiddev, struct file *file) | ||
| 245 | { | ||
| 246 | struct hiddev_list *list; | ||
| 247 | int error; | ||
| 248 | |||
| 249 | lockdep_assert_held(&hiddev->existancelock); | ||
| 250 | |||
| 251 | list = vzalloc(sizeof(*list)); | ||
| 252 | if (!list) | ||
| 253 | return -ENOMEM; | ||
| 254 | |||
| 255 | mutex_init(&list->thread_lock); | ||
| 256 | list->hiddev = hiddev; | ||
| 257 | |||
| 258 | if (!hiddev->open++) { | ||
| 259 | error = hid_hw_power(hiddev->hid, PM_HINT_FULLON); | ||
| 260 | if (error < 0) | ||
| 261 | goto err_drop_count; | ||
| 262 | |||
| 263 | error = hid_hw_open(hiddev->hid); | ||
| 264 | if (error < 0) | ||
| 265 | goto err_normal_power; | ||
| 266 | } | ||
| 267 | |||
| 268 | spin_lock_irq(&hiddev->list_lock); | ||
| 269 | list_add_tail(&list->node, &hiddev->list); | ||
| 270 | spin_unlock_irq(&hiddev->list_lock); | ||
| 271 | |||
| 272 | file->private_data = list; | ||
| 273 | |||
| 274 | return 0; | ||
| 275 | |||
| 276 | err_normal_power: | ||
| 277 | hid_hw_power(hiddev->hid, PM_HINT_NORMAL); | ||
| 278 | err_drop_count: | ||
| 279 | hiddev->open--; | ||
| 280 | vfree(list); | ||
| 281 | return error; | ||
| 282 | } | ||
| 283 | |||
| 244 | /* | 284 | /* |
| 245 | * open file op | 285 | * open file op |
| 246 | */ | 286 | */ |
| 247 | static int hiddev_open(struct inode *inode, struct file *file) | 287 | static int hiddev_open(struct inode *inode, struct file *file) |
| 248 | { | 288 | { |
| 249 | struct hiddev_list *list; | ||
| 250 | struct usb_interface *intf; | 289 | struct usb_interface *intf; |
| 251 | struct hid_device *hid; | 290 | struct hid_device *hid; |
| 252 | struct hiddev *hiddev; | 291 | struct hiddev *hiddev; |
| @@ -255,66 +294,14 @@ static int hiddev_open(struct inode *inode, struct file *file) · 2 unmodified lines | |||
| 255 | intf = usbhid_find_interface(iminor(inode)); | 294 | intf = usbhid_find_interface(iminor(inode)); |
| 256 | if (!intf) | 295 | if (!intf) |
| 257 | return -ENODEV; | 296 | return -ENODEV; |
| 297 | |||
| 258 | hid = usb_get_intfdata(intf); | 298 | hid = usb_get_intfdata(intf); |
| 259 | hiddev = hid->hiddev; | 299 | hiddev = hid->hiddev; |
| 260 | 300 | ||
| 261 | if (!(list = vzalloc(sizeof(struct hiddev_list)))) | ||
| 262 | return -ENOMEM; | ||
| 263 | mutex_init(&list->thread_lock); | ||
| 264 | list->hiddev = hiddev; | ||
| 265 | file->private_data = list; | ||
| 266 | |||
| 267 | /* | ||
| 268 | * no need for locking because the USB major number | ||
| 269 | * is shared which usbcore guards against disconnect | ||
| 270 | */ | ||
| 271 | if (list->hiddev->exist) { | ||
| 272 | if (!list->hiddev->open++) { | ||
| 273 | res = hid_hw_open(hiddev->hid); | ||
| 274 | if (res < 0) | ||
| 275 | goto bail; | ||
| 276 | } | ||
| 277 | } else { | ||
| 278 | res = -ENODEV; | ||
| 279 | goto bail; | ||
| 280 | } | ||
| 281 | |||
| 282 | spin_lock_irq(&list->hiddev->list_lock); | ||
| 283 | list_add_tail(&list->node, &hiddev->list); | ||
| 284 | spin_unlock_irq(&list->hiddev->list_lock); | ||
| 285 | |||
| 286 | mutex_lock(&hiddev->existancelock); | 301 | mutex_lock(&hiddev->existancelock); |
| 287 | /* | 302 | res = hiddev->exist ? __hiddev_open(hiddev, file) : -ENODEV; |
| 288 | * recheck exist with existance lock held to | ||
| 289 | * avoid opening a disconnected device | ||
| 290 | */ | ||
| 291 | if (!list->hiddev->exist) { | ||
| 292 | res = -ENODEV; | ||
| 293 | goto bail_unlock; | ||
| 294 | } | ||
| 295 | if (!list->hiddev->open++) | ||
| 296 | if (list->hiddev->exist) { | ||
| 297 | struct hid_device *hid = hiddev->hid; | ||
| 298 | res = hid_hw_power(hid, PM_HINT_FULLON); | ||
| 299 | if (res < 0) | ||
| 300 | goto bail_unlock; | ||
| 301 | res = hid_hw_open(hid); | ||
| 302 | if (res < 0) | ||
| 303 | goto bail_normal_power; | ||
| 304 | } | ||
| 305 | mutex_unlock(&hiddev->existancelock); | ||
| 306 | return 0; | ||
| 307 | bail_normal_power: | ||
| 308 | hid_hw_power(hid, PM_HINT_NORMAL); | ||
| 309 | bail_unlock: | ||
| 310 | mutex_unlock(&hiddev->existancelock); | 303 | mutex_unlock(&hiddev->existancelock); |
| 311 | 304 | ||
| 312 | spin_lock_irq(&list->hiddev->list_lock); | ||
| 313 | list_del(&list->node); | ||
| 314 | spin_unlock_irq(&list->hiddev->list_lock); | ||
| 315 | bail: | ||
| 316 | file->private_data = NULL; | ||
| 317 | vfree(list); | ||
| 318 | return res; | 305 | return res; |
| 319 | } | 306 | } |
| 320 | 307 | ||
| @@ -2096,14 +2096,16 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field · 2095 unmodified lines | |||
| 2096 | (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ | 2096 | (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ |
| 2097 | hdev->product == 0x357 || hdev->product == 0x358 || /* Intuos Pro 2 */ | 2097 | hdev->product == 0x357 || hdev->product == 0x358 || /* Intuos Pro 2 */ |
| 2098 | hdev->product == 0x392 || /* Intuos Pro 2 */ | 2098 | hdev->product == 0x392 || /* Intuos Pro 2 */ |
| 2099 | hdev->product == 0x398 || hdev->product == 0x399)) { /* MobileStudio Pro */ | 2099 | hdev->product == 0x398 || hdev->product == 0x399 || /* MobileStudio Pro */ |
| 2100 | hdev->product == 0x3AA)) { /* MobileStudio Pro */ | ||
| 2100 | value = (field->logical_maximum - value); | 2101 | value = (field->logical_maximum - value); |
| 2101 | 2102 | ||
| 2102 | if (hdev->product == 0x357 || hdev->product == 0x358 || | 2103 | if (hdev->product == 0x357 || hdev->product == 0x358 || |
| 2103 | hdev->product == 0x392) | 2104 | hdev->product == 0x392) |
| 2104 | value = wacom_offset_rotation(input, usage, value, 3, 16); | 2105 | value = wacom_offset_rotation(input, usage, value, 3, 16); |
| 2105 | else if (hdev->product == 0x34d || hdev->product == 0x34e || | 2106 | else if (hdev->product == 0x34d || hdev->product == 0x34e || |
| 2106 | hdev->product == 0x398 || hdev->product == 0x399) | 2107 | hdev->product == 0x398 || hdev->product == 0x399 || |
| 2108 | hdev->product == 0x3AA) | ||
| 2107 | value = wacom_offset_rotation(input, usage, value, 1, 2); | 2109 | value = wacom_offset_rotation(input, usage, value, 1, 2); |
| 2108 | } | 2110 | } |
| 2109 | else { | 2111 | else { |
| @@ -174,7 +174,7 @@ static struct at91_twi_pdata sama5d2_config = { · 173 unmodified lines | |||
| 174 | 174 | ||
| 175 | static struct at91_twi_pdata sam9x60_config = { | 175 | static struct at91_twi_pdata sam9x60_config = { |
| 176 | .clk_max_div = 7, | 176 | .clk_max_div = 7, |
| 177 | .clk_offset = 4, | 177 | .clk_offset = 3, |
| 178 | .has_unre_flag = true, | 178 | .has_unre_flag = true, |
| 179 | .has_alt_cmd = true, | 179 | .has_alt_cmd = true, |
| 180 | .has_hold_field = true, | 180 | .has_hold_field = true, |
| @@ -58,6 +58,7 @@ struct bcm2835_i2c_dev { · 57 unmodified lines | |||
| 58 | struct i2c_adapter adapter; | 58 | struct i2c_adapter adapter; |
| 59 | struct completion completion; | 59 | struct completion completion; |
| 60 | struct i2c_msg *curr_msg; | 60 | struct i2c_msg *curr_msg; |
| 61 | struct clk *bus_clk; | ||
| 61 | int num_msgs; | 62 | int num_msgs; |
| 62 | u32 msg_err; | 63 | u32 msg_err; |
| 63 | u8 *msg_buf; | 64 | u8 *msg_buf; |
| @@ -404,7 +405,6 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) · 340 unmodified lines | |||
| 404 | struct resource *mem, *irq; | 405 | struct resource *mem, *irq; |
| 405 | int ret; | 406 | int ret; |
| 406 | struct i2c_adapter *adap; | 407 | struct i2c_adapter *adap; |
| 407 | struct clk *bus_clk; | ||
| 408 | struct clk *mclk; | 408 | struct clk *mclk; |
| 409 | u32 bus_clk_rate; | 409 | u32 bus_clk_rate; |
| 410 | 410 | ||
| @@ -427,11 +427,11 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 427 | return PTR_ERR(mclk); | 427 | return PTR_ERR(mclk); |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); | 430 | i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); |
| 431 | 431 | ||
| 432 | if (IS_ERR(bus_clk)) { | 432 | if (IS_ERR(i2c_dev->bus_clk)) { |
| 433 | dev_err(&pdev->dev, "Could not register clock\n"); | 433 | dev_err(&pdev->dev, "Could not register clock\n"); |
| 434 | return PTR_ERR(bus_clk); | 434 | return PTR_ERR(i2c_dev->bus_clk); |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", | 437 | ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", |
| @@ -442,13 +442,13 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 442 | bus_clk_rate = 100000; | 442 | bus_clk_rate = 100000; |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | ret = clk_set_rate_exclusive(bus_clk, bus_clk_rate); | 445 | ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate); |
| 446 | if (ret < 0) { | 446 | if (ret < 0) { |
| 447 | dev_err(&pdev->dev, "Could not set clock frequency\n"); | 447 | dev_err(&pdev->dev, "Could not set clock frequency\n"); |
| 448 | return ret; | 448 | return ret; |
| 449 | } | 449 | } |
| 450 | 450 | ||
| 451 | ret = clk_prepare_enable(bus_clk); | 451 | ret = clk_prepare_enable(i2c_dev->bus_clk); |
| 452 | if (ret) { | 452 | if (ret) { |
| 453 | dev_err(&pdev->dev, "Couldn't prepare clock"); | 453 | dev_err(&pdev->dev, "Couldn't prepare clock"); |
| 454 | return ret; | 454 | return ret; |
| @@ -491,10 +491,9 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) · 36 unmodified lines | |||
| 491 | static int bcm2835_i2c_remove(struct platform_device *pdev) | 491 | static int bcm2835_i2c_remove(struct platform_device *pdev) |
| 492 | { | 492 | { |
| 493 | struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); | 493 | struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); |
| 494 | struct clk *bus_clk = devm_clk_get(i2c_dev->dev, "div"); | ||
| 495 | 494 | ||
| 496 | clk_rate_exclusive_put(bus_clk); | 495 | clk_rate_exclusive_put(i2c_dev->bus_clk); |
| 497 | clk_disable_unprepare(bus_clk); | 496 | clk_disable_unprepare(i2c_dev->bus_clk); |
| 498 | 497 | ||
| 499 | free_irq(i2c_dev->irq, i2c_dev); | 498 | free_irq(i2c_dev->irq, i2c_dev); |
| 500 | i2c_del_adapter(&i2c_dev->adapter); | 499 | i2c_del_adapter(&i2c_dev->adapter); |
| @@ -186,10 +186,11 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap) · 185 unmodified lines | |||
| 186 | * If we can set SDA, we will always create a STOP to ensure additional | 186 | * If we can set SDA, we will always create a STOP to ensure additional |
| 187 | * pulses will do no harm. This is achieved by letting SDA follow SCL | 187 | * pulses will do no harm. This is achieved by letting SDA follow SCL |
| 188 | * half a cycle later. Check the 'incomplete_write_byte' fault injector | 188 | * half a cycle later. Check the 'incomplete_write_byte' fault injector |
| 189 | * for details. | 189 | * for details. Note that we must honour tsu:sto, 4us, but lets use 5us |
| 190 | * here for simplicity. | ||
| 190 | */ | 191 | */ |
| 191 | bri->set_scl(adap, scl); | 192 | bri->set_scl(adap, scl); |
| 192 | ndelay(RECOVERY_NDELAY / 2); | 193 | ndelay(RECOVERY_NDELAY); |
| 193 | if (bri->set_sda) | 194 | if (bri->set_sda) |
| 194 | bri->set_sda(adap, scl); | 195 | bri->set_sda(adap, scl); |
| 195 | ndelay(RECOVERY_NDELAY / 2); | 196 | ndelay(RECOVERY_NDELAY / 2); |
| @@ -211,7 +212,13 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap) · 15 unmodified lines | |||
| 211 | scl = !scl; | 212 | scl = !scl; |
| 212 | bri->set_scl(adap, scl); | 213 | bri->set_scl(adap, scl); |
| 213 | /* Creating STOP again, see above */ | 214 | /* Creating STOP again, see above */ |
| 214 | ndelay(RECOVERY_NDELAY / 2); | 215 | if (scl) { |
| 216 | /* Honour minimum tsu:sto */ | ||
| 217 | ndelay(RECOVERY_NDELAY); | ||
| 218 | } else { | ||
| 219 | /* Honour minimum tf and thd:dat */ | ||
| 220 | ndelay(RECOVERY_NDELAY / 2); | ||
| 221 | } | ||
| 215 | if (bri->set_sda) | 222 | if (bri->set_sda) |
| 216 | bri->set_sda(adap, scl); | 223 | bri->set_sda(adap, scl); |
| 217 | ndelay(RECOVERY_NDELAY / 2); | 224 | ndelay(RECOVERY_NDELAY / 2); |
| @@ -3305,8 +3305,10 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata) · 3304 unmodified lines | |||
| 3305 | int rc; | 3305 | int rc; |
| 3306 | 3306 | ||
| 3307 | rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr); | 3307 | rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr); |
| 3308 | if (rc) | 3308 | if (rc) { |
| 3309 | dev_err(rdev_to_dev(rdev), "Dereg MR failed: %#x\n", rc); | 3309 | dev_err(rdev_to_dev(rdev), "Dereg MR failed: %#x\n", rc); |
| 3310 | return rc; | ||
| 3311 | } | ||
| 3310 | 3312 | ||
| 3311 | if (mr->pages) { | 3313 | if (mr->pages) { |
| 3312 | rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res, | 3314 | rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res, |
| @@ -2283,13 +2283,13 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, · 2282 unmodified lines | |||
| 2283 | /* Add qp to flush list of the CQ */ | 2283 | /* Add qp to flush list of the CQ */ |
| 2284 | bnxt_qplib_add_flush_qp(qp); | 2284 | bnxt_qplib_add_flush_qp(qp); |
| 2285 | } else { | 2285 | } else { |
| 2286 | /* Before we complete, do WA 9060 */ | ||
| 2287 | if (do_wa9060(qp, cq, cq_cons, sw_sq_cons, | ||
| 2288 | cqe_sq_cons)) { | ||
| 2289 | *lib_qp = qp; | ||
| 2290 | goto out; | ||
| 2291 | } | ||
| 2286 | if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { | 2292 | if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { |
| 2287 | /* Before we complete, do WA 9060 */ | ||
| 2288 | if (do_wa9060(qp, cq, cq_cons, sw_sq_cons, | ||
| 2289 | cqe_sq_cons)) { | ||
| 2290 | *lib_qp = qp; | ||
| 2291 | goto out; | ||
| 2292 | } | ||
| 2293 | cqe->status = CQ_REQ_STATUS_OK; | 2293 | cqe->status = CQ_REQ_STATUS_OK; |
| 2294 | cqe++; | 2294 | cqe++; |
| 2295 | (*budget)--; | 2295 | (*budget)--; |
| @@ -81,7 +81,9 @@ void iowait_init(struct iowait *wait, u32 tx_limit, · 80 unmodified lines | |||
| 81 | void iowait_cancel_work(struct iowait *w) | 81 | void iowait_cancel_work(struct iowait *w) |
| 82 | { | 82 | { |
| 83 | cancel_work_sync(&iowait_get_ib_work(w)->iowork); | 83 | cancel_work_sync(&iowait_get_ib_work(w)->iowork); |
| 84 | cancel_work_sync(&iowait_get_tid_work(w)->iowork); | 84 | /* Make sure that the iowork for TID RDMA is used */ |
| 85 | if (iowait_get_tid_work(w)->iowork.func) | ||
| 86 | cancel_work_sync(&iowait_get_tid_work(w)->iowork); | ||
| 85 | } | 87 | } |
| 86 | 88 | ||
| 87 | /** | 89 | /** |
| @@ -4633,6 +4633,15 @@ void hfi1_rc_rcv_tid_rdma_ack(struct hfi1_packet *packet) · 4632 unmodified lines | |||
| 4633 | */ | 4633 | */ |
| 4634 | fpsn = full_flow_psn(flow, flow->flow_state.spsn); | 4634 | fpsn = full_flow_psn(flow, flow->flow_state.spsn); |
| 4635 | req->r_ack_psn = psn; | 4635 | req->r_ack_psn = psn; |
| 4636 | /* | ||
| 4637 | * If resync_psn points to the last flow PSN for a | ||
| 4638 | * segment and the new segment (likely from a new | ||
| 4639 | * request) starts with a new generation number, we | ||
| 4640 | * need to adjust resync_psn accordingly. | ||
| 4641 | */ | ||
| 4642 | if (flow->flow_state.generation != | ||
| 4643 | (resync_psn >> HFI1_KDETH_BTH_SEQ_SHIFT)) | ||
| 4644 | resync_psn = mask_psn(fpsn - 1); | ||
| 4636 | flow->resync_npkts += | 4645 | flow->resync_npkts += |
| 4637 | delta_psn(mask_psn(resync_psn + 1), fpsn); | 4646 | delta_psn(mask_psn(resync_psn + 1), fpsn); |
| 4638 | /* | 4647 | /* |
| @@ -169,8 +169,7 @@ static void i40iw_dealloc_ucontext(struct ib_ucontext *context) · 168 unmodified lines | |||
| 169 | static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | 169 | static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) |
| 170 | { | 170 | { |
| 171 | struct i40iw_ucontext *ucontext; | 171 | struct i40iw_ucontext *ucontext; |
| 172 | u64 db_addr_offset; | 172 | u64 db_addr_offset, push_offset, pfn; |
| 173 | u64 push_offset; | ||
| 174 | 173 | ||
| 175 | ucontext = to_ucontext(context); | 174 | ucontext = to_ucontext(context); |
| 176 | if (ucontext->iwdev->sc_dev.is_pf) { | 175 | if (ucontext->iwdev->sc_dev.is_pf) { |
| @@ -189,7 +188,6 @@ static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) · 12 unmodified lines | |||
| 189 | 188 | ||
| 190 | if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) { | 189 | if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) { |
| 191 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 190 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| 192 | vma->vm_private_data = ucontext; | ||
| 193 | } else { | 191 | } else { |
| 194 | if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2) | 192 | if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2) |
| 195 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 193 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| @@ -197,12 +195,12 @@ static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) · 1 unmodified line | |||
| 197 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); | 195 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); |
| 198 | } | 196 | } |
| 199 | 197 | ||
| 200 | if (io_remap_pfn_range(vma, vma->vm_start, | 198 | pfn = vma->vm_pgoff + |
| 201 | vma->vm_pgoff + (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> PAGE_SHIFT), | 199 | (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> |
| 202 | PAGE_SIZE, vma->vm_page_prot)) | 200 | PAGE_SHIFT); |
| 203 | return -EAGAIN; | ||
| 204 | 201 | ||
| 205 | return 0; | 202 | return rdma_user_mmap_io(context, vma, pfn, PAGE_SIZE, |
| 203 | vma->vm_page_prot, NULL); | ||
| 206 | } | 204 | } |
| 207 | 205 | ||
| 208 | /** | 206 | /** |
| @@ -224,13 +224,13 @@ static void __pass_event(struct evdev_client *client, · 223 unmodified lines | |||
| 224 | */ | 224 | */ |
| 225 | client->tail = (client->head - 2) & (client->bufsize - 1); | 225 | client->tail = (client->head - 2) & (client->bufsize - 1); |
| 226 | 226 | ||
| 227 | client->buffer[client->tail].input_event_sec = | 227 | client->buffer[client->tail] = (struct input_event) { |
| 228 | event->input_event_sec; | 228 | .input_event_sec = event->input_event_sec, |
| 229 | client->buffer[client->tail].input_event_usec = | 229 | .input_event_usec = event->input_event_usec, |
| 230 | event->input_event_usec; | 230 | .type = EV_SYN, |
| 231 | client->buffer[client->tail].type = EV_SYN; | 231 | .code = SYN_DROPPED, |
| 232 | client->buffer[client->tail].code = SYN_DROPPED; | 232 | .value = 0, |
| 233 | client->buffer[client->tail].value = 0; | 233 | }; |
| 234 | 234 | ||
| 235 | client->packet_head = client->tail; | 235 | client->packet_head = client->tail; |
| 236 | } | 236 | } |
| @@ -878,16 +878,18 @@ static int input_default_setkeycode(struct input_dev *dev, · 877 unmodified lines | |||
| 878 | } | 878 | } |
| 879 | } | 879 | } |
| 880 | 880 | ||
| 881 | __clear_bit(*old_keycode, dev->keybit); | 881 | if (*old_keycode <= KEY_MAX) { |
| 882 | __set_bit(ke->keycode, dev->keybit); | 882 | __clear_bit(*old_keycode, dev->keybit); |
| 883 | 883 | for (i = 0; i < dev->keycodemax; i++) { | |
| 884 | for (i = 0; i < dev->keycodemax; i++) { | 884 | if (input_fetch_keycode(dev, i) == *old_keycode) { |
| 885 | if (input_fetch_keycode(dev, i) == *old_keycode) { | 885 | __set_bit(*old_keycode, dev->keybit); |
| 886 | __set_bit(*old_keycode, dev->keybit); | 886 | /* Setting the bit twice is useless, so break */ |
| 887 | break; /* Setting the bit twice is useless, so break */ | 887 | break; |
| 888 | } | ||
| 888 | } | 889 | } |
| 889 | } | 890 | } |
| 890 | 891 | ||
| 892 | __set_bit(ke->keycode, dev->keybit); | ||
| 891 | return 0; | 893 | return 0; |
| 892 | } | 894 | } |
| 893 | 895 | ||
| @@ -943,9 +945,13 @@ int input_set_keycode(struct input_dev *dev, · 49 unmodified lines | |||
| 943 | * Simulate keyup event if keycode is not present | 945 | * Simulate keyup event if keycode is not present |
| 944 | * in the keymap anymore | 946 | * in the keymap anymore |
| 945 | */ | 947 | */ |
| 946 | if (test_bit(EV_KEY, dev->evbit) && | 948 | if (old_keycode > KEY_MAX) { |
| 947 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && | 949 | dev_warn(dev->dev.parent ?: &dev->dev, |
| 948 | __test_and_clear_bit(old_keycode, dev->key)) { | 950 | "%s: got too big old keycode %#x\n", |
| 951 | __func__, old_keycode); | ||
| 952 | } else if (test_bit(EV_KEY, dev->evbit) && | ||
| 953 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && | ||
| 954 | __test_and_clear_bit(old_keycode, dev->key)) { | ||
| 949 | struct input_value vals[] = { | 955 | struct input_value vals[] = { |
| 950 | { EV_KEY, old_keycode, 0 }, | 956 | { EV_KEY, old_keycode, 0 }, |
| 951 | input_value_sync | 957 | input_value_sync |
| @@ -78,7 +78,13 @@ static void imx_sc_check_for_events(struct work_struct *work) · 77 unmodified lines | |||
| 78 | return; | 78 | return; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | state = (bool)msg.state; | 81 | /* |
| 82 | * The response data from SCU firmware is 4 bytes, | ||
| 83 | * but ONLY the first byte is the key state, other | ||
| 84 | * 3 bytes could be some dirty data, so we should | ||
| 85 | * ONLY take the first byte as key state. | ||
| 86 | */ | ||
| 87 | state = (bool)(msg.state & 0xff); | ||
| 82 | 88 | ||
| 83 | if (state ^ priv->keystate) { | 89 | if (state ^ priv->keystate) { |
| 84 | priv->keystate = state; | 90 | priv->keystate = state; |
| @@ -74,12 +74,16 @@ static int uinput_dev_event(struct input_dev *dev, · 73 unmodified lines | |||
| 74 | struct uinput_device *udev = input_get_drvdata(dev); | 74 | struct uinput_device *udev = input_get_drvdata(dev); |
| 75 | struct timespec64 ts; | 75 | struct timespec64 ts; |
| 76 | 76 | ||
| 77 | udev->buff[udev->head].type = type; | ||
| 78 | udev->buff[udev->head].code = code; | ||
| 79 | udev->buff[udev->head].value = value; | ||
| 80 | ktime_get_ts64(&ts); | 77 | ktime_get_ts64(&ts); |
| 81 | udev->buff[udev->head].input_event_sec = ts.tv_sec; | 78 | |
| 82 | udev->buff[udev->head].input_event_usec = ts.tv_nsec / NSEC_PER_USEC; | 79 | udev->buff[udev->head] = (struct input_event) { |
| 80 | .input_event_sec = ts.tv_sec, | ||
| 81 | .input_event_usec = ts.tv_nsec / NSEC_PER_USEC, | ||
| 82 | .type = type, | ||
| 83 | .code = code, | ||
| 84 | .value = value, | ||
| 85 | }; | ||
| 86 | |||
| 83 | udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE; | 87 | udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE; |
| 84 | 88 | ||
| 85 | wake_up_interruptible(&udev->waitq); | 89 | wake_up_interruptible(&udev->waitq); |
| @@ -689,13 +693,14 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, · 603 unmodified lines | |||
| 689 | static __poll_t uinput_poll(struct file *file, poll_table *wait) | 693 | static __poll_t uinput_poll(struct file *file, poll_table *wait) |
| 690 | { | 694 | { |
| 691 | struct uinput_device *udev = file->private_data; | 695 | struct uinput_device *udev = file->private_data; |
| 696 | __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* uinput is always writable */ | ||
| 692 | 697 | ||
| 693 | poll_wait(file, &udev->waitq, wait); | 698 | poll_wait(file, &udev->waitq, wait); |
| 694 | 699 | ||
| 695 | if (udev->head != udev->tail) | 700 | if (udev->head != udev->tail) |
| 696 | return EPOLLIN | EPOLLRDNORM; | 701 | mask |= EPOLLIN | EPOLLRDNORM; |
| 697 | 702 | ||
| 698 | return EPOLLOUT | EPOLLWRNORM; | 703 | return mask; |
| 699 | } | 704 | } |
| 700 | 705 | ||
| 701 | static int uinput_release(struct inode *inode, struct file *file) | 706 | static int uinput_release(struct inode *inode, struct file *file) |
| @@ -1203,7 +1203,6 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) · 1202 unmodified lines | |||
| 1203 | { | 1203 | { |
| 1204 | struct device *dev = msi_desc_to_dev(desc); | 1204 | struct device *dev = msi_desc_to_dev(desc); |
| 1205 | struct iommu_domain *domain = iommu_get_domain_for_dev(dev); | 1205 | struct iommu_domain *domain = iommu_get_domain_for_dev(dev); |
| 1206 | struct iommu_dma_cookie *cookie; | ||
| 1207 | struct iommu_dma_msi_page *msi_page; | 1206 | struct iommu_dma_msi_page *msi_page; |
| 1208 | static DEFINE_MUTEX(msi_prepare_lock); /* see below */ | 1207 | static DEFINE_MUTEX(msi_prepare_lock); /* see below */ |
| 1209 | 1208 | ||
| @@ -1212,8 +1211,6 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) · 2 unmodified lines | |||
| 1212 | return 0; | 1211 | return 0; |
| 1213 | } | 1212 | } |
| 1214 | 1213 | ||
| 1215 | cookie = domain->iova_cookie; | ||
| 1216 | |||
| 1217 | /* | 1214 | /* |
| 1218 | * In fact the whole prepare operation should already be serialised by | 1215 | * In fact the whole prepare operation should already be serialised by |
| 1219 | * irq_domain_mutex further up the callchain, but that's pretty subtle | 1216 | * irq_domain_mutex further up the callchain, but that's pretty subtle |
| @@ -5624,8 +5624,10 @@ static int intel_iommu_add_device(struct device *dev) · 5623 unmodified lines | |||
| 5624 | 5624 | ||
| 5625 | group = iommu_group_get_for_dev(dev); | 5625 | group = iommu_group_get_for_dev(dev); |
| 5626 | 5626 | ||
| 5627 | if (IS_ERR(group)) | 5627 | if (IS_ERR(group)) { |
| 5628 | return PTR_ERR(group); | 5628 | ret = PTR_ERR(group); |
| 5629 | goto unlink; | ||
| 5630 | } | ||
| 5629 | 5631 | ||
| 5630 | iommu_group_put(group); | 5632 | iommu_group_put(group); |
| 5631 | 5633 | ||
| @@ -5651,7 +5653,8 @@ static int intel_iommu_add_device(struct device *dev) · 19 unmodified lines | |||
| 5651 | if (!get_private_domain_for_dev(dev)) { | 5653 | if (!get_private_domain_for_dev(dev)) { |
| 5652 | dev_warn(dev, | 5654 | dev_warn(dev, |
| 5653 | "Failed to get a private domain.\n"); | 5655 | "Failed to get a private domain.\n"); |
| 5654 | return -ENOMEM; | 5656 | ret = -ENOMEM; |
| 5657 | goto unlink; | ||
| 5655 | } | 5658 | } |
| 5656 | 5659 | ||
| 5657 | dev_info(dev, | 5660 | dev_info(dev, |
| @@ -5666,6 +5669,10 @@ static int intel_iommu_add_device(struct device *dev) · 8 unmodified lines | |||
| 5666 | } | 5669 | } |
| 5667 | 5670 | ||
| 5668 | return 0; | 5671 | return 0; |
| 5672 | |||
| 5673 | unlink: | ||
| 5674 | iommu_device_unlink(&iommu->iommu, dev); | ||
| 5675 | return ret; | ||
| 5669 | } | 5676 | } |
| 5670 | 5677 | ||
| 5671 | static void intel_iommu_remove_device(struct device *dev) | 5678 | static void intel_iommu_remove_device(struct device *dev) |
| @@ -5817,6 +5824,13 @@ static void intel_iommu_apply_resv_region(struct device *dev, · 145 unmodified lines | |||
| 5817 | WARN_ON_ONCE(!reserve_iova(&dmar_domain->iovad, start, end)); | 5824 | WARN_ON_ONCE(!reserve_iova(&dmar_domain->iovad, start, end)); |
| 5818 | } | 5825 | } |
| 5819 | 5826 | ||
| 5827 | static struct iommu_group *intel_iommu_device_group(struct device *dev) | ||
| 5828 | { | ||
| 5829 | if (dev_is_pci(dev)) | ||
| 5830 | return pci_device_group(dev); | ||
| 5831 | return generic_device_group(dev); | ||
| 5832 | } | ||
| 5833 | |||
| 5820 | #ifdef CONFIG_INTEL_IOMMU_SVM | 5834 | #ifdef CONFIG_INTEL_IOMMU_SVM |
| 5821 | struct intel_iommu *intel_svm_device_to_iommu(struct device *dev) | 5835 | struct intel_iommu *intel_svm_device_to_iommu(struct device *dev) |
| 5822 | { | 5836 | { |
| @@ -5989,7 +6003,7 @@ const struct iommu_ops intel_iommu_ops = { · 166 unmodified lines | |||
| 5989 | .get_resv_regions = intel_iommu_get_resv_regions, | 6003 | .get_resv_regions = intel_iommu_get_resv_regions, |
| 5990 | .put_resv_regions = intel_iommu_put_resv_regions, | 6004 | .put_resv_regions = intel_iommu_put_resv_regions, |
| 5991 | .apply_resv_region = intel_iommu_apply_resv_region, | 6005 | .apply_resv_region = intel_iommu_apply_resv_region, |
| 5992 | .device_group = pci_device_group, | 6006 | .device_group = intel_iommu_device_group, |
| 5993 | .dev_has_feat = intel_iommu_dev_has_feat, | 6007 | .dev_has_feat = intel_iommu_dev_has_feat, |
| 5994 | .dev_feat_enabled = intel_iommu_dev_feat_enabled, | 6008 | .dev_feat_enabled = intel_iommu_dev_feat_enabled, |
| 5995 | .dev_enable_feat = intel_iommu_dev_enable_feat, | 6009 | .dev_enable_feat = intel_iommu_dev_enable_feat, |
| @@ -751,6 +751,7 @@ err_put_group: · 750 unmodified lines | |||
| 751 | mutex_unlock(&group->mutex); | 751 | mutex_unlock(&group->mutex); |
| 752 | dev->iommu_group = NULL; | 752 | dev->iommu_group = NULL; |
| 753 | kobject_put(group->devices_kobj); | 753 | kobject_put(group->devices_kobj); |
| 754 | sysfs_remove_link(group->devices_kobj, device->name); | ||
| 754 | err_free_name: | 755 | err_free_name: |
| 755 | kfree(device->name); | 756 | kfree(device->name); |
| 756 | err_remove_link: | 757 | err_remove_link: |
| @@ -256,7 +256,7 @@ static int __init plic_init(struct device_node *node, · 255 unmodified lines | |||
| 256 | * Skip contexts other than external interrupts for our | 256 | * Skip contexts other than external interrupts for our |
| 257 | * privilege level. | 257 | * privilege level. |
| 258 | */ | 258 | */ |
| 259 | if (parent.args[0] != IRQ_EXT) | 259 | if (parent.args[0] != RV_IRQ_EXT) |
| 260 | continue; | 260 | continue; |
| 261 | 261 | ||
| 262 | hartid = plic_find_hart_id(parent.np); | 262 | hartid = plic_find_hart_id(parent.np); |
| @@ -380,7 +380,8 @@ static void cec_data_cancel(struct cec_data *data, u8 tx_status) · 379 unmodified lines | |||
| 380 | } else { | 380 | } else { |
| 381 | list_del_init(&data->list); | 381 | list_del_init(&data->list); |
| 382 | if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) | 382 | if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) |
| 383 | data->adap->transmit_queue_sz--; | 383 | if (!WARN_ON(!data->adap->transmit_queue_sz)) |
| 384 | data->adap->transmit_queue_sz--; | ||
| 384 | } | 385 | } |
| 385 | 386 | ||
| 386 | if (data->msg.tx_status & CEC_TX_STATUS_OK) { | 387 | if (data->msg.tx_status & CEC_TX_STATUS_OK) { |
| @@ -432,6 +433,14 @@ static void cec_flush(struct cec_adapter *adap) · 45 unmodified lines | |||
| 432 | * need to do anything special in that case. | 433 | * need to do anything special in that case. |
| 433 | */ | 434 | */ |
| 434 | } | 435 | } |
| 436 | /* | ||
| 437 | * If something went wrong and this counter isn't what it should | ||
| 438 | * be, then this will reset it back to 0. Warn if it is not 0, | ||
| 439 | * since it indicates a bug, either in this framework or in a | ||
| 440 | * CEC driver. | ||
| 441 | */ | ||
| 442 | if (WARN_ON(adap->transmit_queue_sz)) | ||
| 443 | adap->transmit_queue_sz = 0; | ||
| 435 | } | 444 | } |
| 436 | 445 | ||
| 437 | /* | 446 | /* |
| @@ -456,7 +465,7 @@ int cec_thread_func(void *_adap) · 18 unmodified lines | |||
| 456 | bool timeout = false; | 465 | bool timeout = false; |
| 457 | u8 attempts; | 466 | u8 attempts; |
| 458 | 467 | ||
| 459 | if (adap->transmitting) { | 468 | if (adap->transmit_in_progress) { |
| 460 | int err; | 469 | int err; |
| 461 | 470 | ||
| 462 | /* | 471 | /* |
| @@ -491,7 +500,7 @@ int cec_thread_func(void *_adap) · 28 unmodified lines | |||
| 491 | goto unlock; | 500 | goto unlock; |
| 492 | } | 501 | } |
| 493 | 502 | ||
| 494 | if (adap->transmitting && timeout) { | 503 | if (adap->transmit_in_progress && timeout) { |
| 495 | /* | 504 | /* |
| 496 | * If we timeout, then log that. Normally this does | 505 | * If we timeout, then log that. Normally this does |
| 497 | * not happen and it is an indication of a faulty CEC | 506 | * not happen and it is an indication of a faulty CEC |
| @@ -500,14 +509,18 @@ int cec_thread_func(void *_adap) · 2 unmodified lines | |||
| 500 | * so much traffic on the bus that the adapter was | 509 | * so much traffic on the bus that the adapter was |
| 501 | * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s). | 510 | * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s). |
| 502 | */ | 511 | */ |
| 503 | pr_warn("cec-%s: message %*ph timed out\n", adap->name, | 512 | if (adap->transmitting) { |
| 504 | adap->transmitting->msg.len, | 513 | pr_warn("cec-%s: message %*ph timed out\n", adap->name, |
| 505 | adap->transmitting->msg.msg); | 514 | adap->transmitting->msg.len, |
| 515 | adap->transmitting->msg.msg); | ||
| 516 | /* Just give up on this. */ | ||
| 517 | cec_data_cancel(adap->transmitting, | ||
| 518 | CEC_TX_STATUS_TIMEOUT); | ||
| 519 | } else { | ||
| 520 | pr_warn("cec-%s: transmit timed out\n", adap->name); | ||
| 521 | } | ||
| 506 | adap->transmit_in_progress = false; | 522 | adap->transmit_in_progress = false; |
| 507 | adap->tx_timeouts++; | 523 | adap->tx_timeouts++; |
| 508 | /* Just give up on this. */ | ||
| 509 | cec_data_cancel(adap->transmitting, | ||
| 510 | CEC_TX_STATUS_TIMEOUT); | ||
| 511 | goto unlock; | 524 | goto unlock; |
| 512 | } | 525 | } |
| 513 | 526 | ||
| @@ -522,7 +535,8 @@ int cec_thread_func(void *_adap) · 8 unmodified lines | |||
| 522 | data = list_first_entry(&adap->transmit_queue, | 535 | data = list_first_entry(&adap->transmit_queue, |
| 523 | struct cec_data, list); | 536 | struct cec_data, list); |
| 524 | list_del_init(&data->list); | 537 | list_del_init(&data->list); |
| 525 | adap->transmit_queue_sz--; | 538 | if (!WARN_ON(!data->adap->transmit_queue_sz)) |
| 539 | adap->transmit_queue_sz--; | ||
| 526 | 540 | ||
| 527 | /* Make this the current transmitting message */ | 541 | /* Make this the current transmitting message */ |
| 528 | adap->transmitting = data; | 542 | adap->transmitting = data; |
| @@ -1085,11 +1099,11 @@ void cec_received_msg_ts(struct cec_adapter *adap, · 556 unmodified lines | |||
| 1085 | valid_la = false; | 1099 | valid_la = false; |
| 1086 | else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) | 1100 | else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) |
| 1087 | valid_la = false; | 1101 | valid_la = false; |
| 1088 | else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST1_4)) | 1102 | else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST)) |
| 1089 | valid_la = false; | 1103 | valid_la = false; |
| 1090 | else if (cec_msg_is_broadcast(msg) && | 1104 | else if (cec_msg_is_broadcast(msg) && |
| 1091 | adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && | 1105 | adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0 && |
| 1092 | !(dir_fl & BCAST2_0)) | 1106 | !(dir_fl & BCAST1_4)) |
| 1093 | valid_la = false; | 1107 | valid_la = false; |
| 1094 | } | 1108 | } |
| 1095 | if (valid_la && min_len) { | 1109 | if (valid_la && min_len) { |
| @@ -116,6 +116,7 @@ struct pulse8 { · 115 unmodified lines | |||
| 116 | unsigned int vers; | 116 | unsigned int vers; |
| 117 | struct completion cmd_done; | 117 | struct completion cmd_done; |
| 118 | struct work_struct work; | 118 | struct work_struct work; |
| 119 | u8 work_result; | ||
| 119 | struct delayed_work ping_eeprom_work; | 120 | struct delayed_work ping_eeprom_work; |
| 120 | struct cec_msg rx_msg; | 121 | struct cec_msg rx_msg; |
| 121 | u8 data[DATA_SIZE]; | 122 | u8 data[DATA_SIZE]; |
| @@ -137,8 +138,10 @@ static void pulse8_irq_work_handler(struct work_struct *work) · 15 unmodified lines | |||
| 137 | { | 138 | { |
| 138 | struct pulse8 *pulse8 = | 139 | struct pulse8 *pulse8 = |
| 139 | container_of(work, struct pulse8, work); | 140 | container_of(work, struct pulse8, work); |
| 141 | u8 result = pulse8->work_result; | ||
| 140 | 142 | ||
| 141 | switch (pulse8->data[0] & 0x3f) { | 143 | pulse8->work_result = 0; |
| 144 | switch (result & 0x3f) { | ||
| 142 | case MSGCODE_FRAME_DATA: | 145 | case MSGCODE_FRAME_DATA: |
| 143 | cec_received_msg(pulse8->adap, &pulse8->rx_msg); | 146 | cec_received_msg(pulse8->adap, &pulse8->rx_msg); |
| 144 | break; | 147 | break; |
| @@ -172,12 +175,12 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, · 27 unmodified lines | |||
| 172 | pulse8->escape = false; | 175 | pulse8->escape = false; |
| 173 | } else if (data == MSGEND) { | 176 | } else if (data == MSGEND) { |
| 174 | struct cec_msg *msg = &pulse8->rx_msg; | 177 | struct cec_msg *msg = &pulse8->rx_msg; |
| 178 | u8 msgcode = pulse8->buf[0]; | ||
| 175 | 179 | ||
| 176 | if (debug) | 180 | if (debug) |
| 177 | dev_info(pulse8->dev, "received: %*ph\n", | 181 | dev_info(pulse8->dev, "received: %*ph\n", |
| 178 | pulse8->idx, pulse8->buf); | 182 | pulse8->idx, pulse8->buf); |
| 179 | pulse8->data[0] = pulse8->buf[0]; | 183 | switch (msgcode & 0x3f) { |
| 180 | switch (pulse8->buf[0] & 0x3f) { | ||
| 181 | case MSGCODE_FRAME_START: | 184 | case MSGCODE_FRAME_START: |
| 182 | msg->len = 1; | 185 | msg->len = 1; |
| 183 | msg->msg[0] = pulse8->buf[1]; | 186 | msg->msg[0] = pulse8->buf[1]; |
| @@ -186,14 +189,20 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, · 2 unmodified lines | |||
| 186 | if (msg->len == CEC_MAX_MSG_SIZE) | 189 | if (msg->len == CEC_MAX_MSG_SIZE) |
| 187 | break; | 190 | break; |
| 188 | msg->msg[msg->len++] = pulse8->buf[1]; | 191 | msg->msg[msg->len++] = pulse8->buf[1]; |
| 189 | if (pulse8->buf[0] & MSGCODE_FRAME_EOM) | 192 | if (msgcode & MSGCODE_FRAME_EOM) { |
| 193 | WARN_ON(pulse8->work_result); | ||
| 194 | pulse8->work_result = msgcode; | ||
| 190 | schedule_work(&pulse8->work); | 195 | schedule_work(&pulse8->work); |
| 196 | break; | ||
| 197 | } | ||
| 191 | break; | 198 | break; |
| 192 | case MSGCODE_TRANSMIT_SUCCEEDED: | 199 | case MSGCODE_TRANSMIT_SUCCEEDED: |
| 193 | case MSGCODE_TRANSMIT_FAILED_LINE: | 200 | case MSGCODE_TRANSMIT_FAILED_LINE: |
| 194 | case MSGCODE_TRANSMIT_FAILED_ACK: | 201 | case MSGCODE_TRANSMIT_FAILED_ACK: |
| 195 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: | 202 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: |
| 196 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: | 203 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: |
| 204 | WARN_ON(pulse8->work_result); | ||
| 205 | pulse8->work_result = msgcode; | ||
| 197 | schedule_work(&pulse8->work); | 206 | schedule_work(&pulse8->work); |
| 198 | break; | 207 | break; |
| 199 | case MSGCODE_HIGH_ERROR: | 208 | case MSGCODE_HIGH_ERROR: |
| @@ -148,13 +148,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state) · 147 unmodified lines | |||
| 148 | unsigned long timeout; | 148 | unsigned long timeout; |
| 149 | u32 syscfg; | 149 | u32 syscfg; |
| 150 | 150 | ||
| 151 | if (state == FL_RESETING || state == FL_PREPARING_ERASE || | 151 | if (state == FL_RESETTING || state == FL_PREPARING_ERASE || |
| 152 | state == FL_VERIFYING_ERASE) { | 152 | state == FL_VERIFYING_ERASE) { |
| 153 | int i = 21; | 153 | int i = 21; |
| 154 | unsigned int intr_flags = ONENAND_INT_MASTER; | 154 | unsigned int intr_flags = ONENAND_INT_MASTER; |
| 155 | 155 | ||
| 156 | switch (state) { | 156 | switch (state) { |
| 157 | case FL_RESETING: | 157 | case FL_RESETTING: |
| 158 | intr_flags |= ONENAND_INT_RESET; | 158 | intr_flags |= ONENAND_INT_RESET; |
| 159 | break; | 159 | break; |
| 160 | case FL_PREPARING_ERASE: | 160 | case FL_PREPARING_ERASE: |
| @@ -328,7 +328,8 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c, · 167 unmodified lines | |||
| 328 | struct dma_async_tx_descriptor *tx; | 328 | struct dma_async_tx_descriptor *tx; |
| 329 | dma_cookie_t cookie; | 329 | dma_cookie_t cookie; |
| 330 | 330 | ||
| 331 | tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0); | 331 | tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, |
| 332 | DMA_CTRL_ACK | DMA_PREP_INTERRUPT); | ||
| 332 | if (!tx) { | 333 | if (!tx) { |
| 333 | dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n"); | 334 | dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n"); |
| 334 | return -EIO; | 335 | return -EIO; |
| @@ -375,7 +376,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area, · 40 unmodified lines | |||
| 375 | * context fallback to PIO mode. | 376 | * context fallback to PIO mode. |
| 376 | */ | 377 | */ |
| 377 | if (!virt_addr_valid(buf) || bram_offset & 3 || (size_t)buf & 3 || | 378 | if (!virt_addr_valid(buf) || bram_offset & 3 || (size_t)buf & 3 || |
| 378 | count < 384 || in_interrupt() || oops_in_progress ) | 379 | count < 384 || in_interrupt() || oops_in_progress) |
| 379 | goto out_copy; | 380 | goto out_copy; |
| 380 | 381 | ||
| 381 | xtra = count & 3; | 382 | xtra = count & 3; |
| @@ -422,7 +423,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area, · 40 unmodified lines | |||
| 422 | * context fallback to PIO mode. | 423 | * context fallback to PIO mode. |
| 423 | */ | 424 | */ |
| 424 | if (!virt_addr_valid(buf) || bram_offset & 3 || (size_t)buf & 3 || | 425 | if (!virt_addr_valid(buf) || bram_offset & 3 || (size_t)buf & 3 || |
| 425 | count < 384 || in_interrupt() || oops_in_progress ) | 426 | count < 384 || in_interrupt() || oops_in_progress) |
| 426 | goto out_copy; | 427 | goto out_copy; |
| 427 | 428 | ||
| 428 | dma_src = dma_map_single(dev, buf, count, DMA_TO_DEVICE); | 429 | dma_src = dma_map_single(dev, buf, count, DMA_TO_DEVICE); |
| @@ -528,7 +529,8 @@ static int omap2_onenand_probe(struct platform_device *pdev) · 99 unmodified lines | |||
| 528 | c->gpmc_cs, c->phys_base, c->onenand.base, | 529 | c->gpmc_cs, c->phys_base, c->onenand.base, |
| 529 | c->dma_chan ? "DMA" : "PIO"); | 530 | c->dma_chan ? "DMA" : "PIO"); |
| 530 | 531 | ||
| 531 | if ((r = onenand_scan(&c->mtd, 1)) < 0) | 532 | r = onenand_scan(&c->mtd, 1); |
| 533 | if (r < 0) | ||
| 532 | goto err_release_dma; | 534 | goto err_release_dma; |
| 533 | 535 | ||
| 534 | freq = omap2_onenand_get_freq(c->onenand.version_id); | 536 | freq = omap2_onenand_get_freq(c->onenand.version_id); |
| @@ -2853,7 +2853,7 @@ static int onenand_otp_write_oob_nolock(struct mtd_info *mtd, loff_t to, · 2852 unmodified lines | |||
| 2853 | 2853 | ||
| 2854 | /* Exit OTP access mode */ | 2854 | /* Exit OTP access mode */ |
| 2855 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); | 2855 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 2856 | this->wait(mtd, FL_RESETING); | 2856 | this->wait(mtd, FL_RESETTING); |
| 2857 | 2857 | ||
| 2858 | status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); | 2858 | status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); |
| 2859 | status &= 0x60; | 2859 | status &= 0x60; |
| @@ -2924,7 +2924,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len, · 64 unmodified lines | |||
| 2924 | 2924 | ||
| 2925 | /* Exit OTP access mode */ | 2925 | /* Exit OTP access mode */ |
| 2926 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); | 2926 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 2927 | this->wait(mtd, FL_RESETING); | 2927 | this->wait(mtd, FL_RESETTING); |
| 2928 | 2928 | ||
| 2929 | return ret; | 2929 | return ret; |
| 2930 | } | 2930 | } |
| @@ -2968,7 +2968,7 @@ static int do_otp_write(struct mtd_info *mtd, loff_t to, size_t len, · 37 unmodified lines | |||
| 2968 | 2968 | ||
| 2969 | /* Exit OTP access mode */ | 2969 | /* Exit OTP access mode */ |
| 2970 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); | 2970 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 2971 | this->wait(mtd, FL_RESETING); | 2971 | this->wait(mtd, FL_RESETTING); |
| 2972 | 2972 | ||
| 2973 | return ret; | 2973 | return ret; |
| 2974 | } | 2974 | } |
| @@ -3008,7 +3008,7 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len, · 33 unmodified lines | |||
| 3008 | 3008 | ||
| 3009 | /* Exit OTP access mode */ | 3009 | /* Exit OTP access mode */ |
| 3010 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); | 3010 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 3011 | this->wait(mtd, FL_RESETING); | 3011 | this->wait(mtd, FL_RESETTING); |
| 3012 | } else { | 3012 | } else { |
| 3013 | ops.mode = MTD_OPS_PLACE_OOB; | 3013 | ops.mode = MTD_OPS_PLACE_OOB; |
| 3014 | ops.ooblen = len; | 3014 | ops.ooblen = len; |
| @@ -3413,7 +3413,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd) · 398 unmodified lines | |||
| 3413 | this->boundary[die] = bdry & FLEXONENAND_PI_MASK; | 3413 | this->boundary[die] = bdry & FLEXONENAND_PI_MASK; |
| 3414 | 3414 | ||
| 3415 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); | 3415 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 3416 | this->wait(mtd, FL_RESETING); | 3416 | this->wait(mtd, FL_RESETTING); |
| 3417 | 3417 | ||
| 3418 | printk(KERN_INFO "Die %d boundary: %d%s\n", die, | 3418 | printk(KERN_INFO "Die %d boundary: %d%s\n", die, |
| 3419 | this->boundary[die], locked ? "(Locked)" : "(Unlocked)"); | 3419 | this->boundary[die], locked ? "(Locked)" : "(Unlocked)"); |
| @@ -3635,7 +3635,7 @@ static int flexonenand_set_boundary(struct mtd_info *mtd, int die, · 215 unmodified lines | |||
| 3635 | ret = this->wait(mtd, FL_WRITING); | 3635 | ret = this->wait(mtd, FL_WRITING); |
| 3636 | out: | 3636 | out: |
| 3637 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND); | 3637 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND); |
| 3638 | this->wait(mtd, FL_RESETING); | 3638 | this->wait(mtd, FL_RESETTING); |
| 3639 | if (!ret) | 3639 | if (!ret) |
| 3640 | /* Recalculate device size on boundary change*/ | 3640 | /* Recalculate device size on boundary change*/ |
| 3641 | flexonenand_get_size(mtd); | 3641 | flexonenand_get_size(mtd); |
| @@ -3671,7 +3671,7 @@ static int onenand_chip_probe(struct mtd_info *mtd) · 29 unmodified lines | |||
| 3671 | /* Reset OneNAND to read default register values */ | 3671 | /* Reset OneNAND to read default register values */ |
| 3672 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM); | 3672 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM); |
| 3673 | /* Wait reset */ | 3673 | /* Wait reset */ |
| 3674 | this->wait(mtd, FL_RESETING); | 3674 | this->wait(mtd, FL_RESETTING); |
| 3675 | 3675 | ||
| 3676 | /* Restore system configuration 1 */ | 3676 | /* Restore system configuration 1 */ |
| 3677 | this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1); | 3677 | this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1); |
| @@ -675,12 +675,12 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, · 674 unmodified lines | |||
| 675 | normal: | 675 | normal: |
| 676 | if (count != mtd->writesize) { | 676 | if (count != mtd->writesize) { |
| 677 | /* Copy the bufferram to memory to prevent unaligned access */ | 677 | /* Copy the bufferram to memory to prevent unaligned access */ |
| 678 | memcpy(this->page_buf, p, mtd->writesize); | 678 | memcpy_fromio(this->page_buf, p, mtd->writesize); |
| 679 | p = this->page_buf + offset; | 679 | memcpy(buffer, this->page_buf + offset, count); |
| 680 | } else { | ||
| 681 | memcpy_fromio(buffer, p, count); | ||
| 680 | } | 682 | } |
| 681 | 683 | ||
| 682 | memcpy(buffer, p, count); | ||
| 683 | |||
| 684 | return 0; | 684 | return 0; |
| 685 | } | 685 | } |
| 686 | 686 | ||
| @@ -914,8 +914,8 @@ static void cadence_nand_get_caps(struct cdns_nand_ctrl *cdns_ctrl) · 913 unmodified lines | |||
| 914 | /* Prepare CDMA descriptor. */ | 914 | /* Prepare CDMA descriptor. */ |
| 915 | static void | 915 | static void |
| 916 | cadence_nand_cdma_desc_prepare(struct cdns_nand_ctrl *cdns_ctrl, | 916 | cadence_nand_cdma_desc_prepare(struct cdns_nand_ctrl *cdns_ctrl, |
| 917 | char nf_mem, u32 flash_ptr, char *mem_ptr, | 917 | char nf_mem, u32 flash_ptr, dma_addr_t mem_ptr, |
| 918 | char *ctrl_data_ptr, u16 ctype) | 918 | dma_addr_t ctrl_data_ptr, u16 ctype) |
| 919 | { | 919 | { |
| 920 | struct cadence_nand_cdma_desc *cdma_desc = cdns_ctrl->cdma_desc; | 920 | struct cadence_nand_cdma_desc *cdma_desc = cdns_ctrl->cdma_desc; |
| 921 | 921 | ||
| @@ -931,13 +931,13 @@ cadence_nand_cdma_desc_prepare(struct cdns_nand_ctrl *cdns_ctrl, · 9 unmodified lines | |||
| 931 | cdma_desc->command_flags |= CDMA_CF_DMA_MASTER; | 931 | cdma_desc->command_flags |= CDMA_CF_DMA_MASTER; |
| 932 | cdma_desc->command_flags |= CDMA_CF_INT; | 932 | cdma_desc->command_flags |= CDMA_CF_INT; |
| 933 | 933 | ||
| 934 | cdma_desc->memory_pointer = (uintptr_t)mem_ptr; | 934 | cdma_desc->memory_pointer = mem_ptr; |
| 935 | cdma_desc->status = 0; | 935 | cdma_desc->status = 0; |
| 936 | cdma_desc->sync_flag_pointer = 0; | 936 | cdma_desc->sync_flag_pointer = 0; |
| 937 | cdma_desc->sync_arguments = 0; | 937 | cdma_desc->sync_arguments = 0; |
| 938 | 938 | ||
| 939 | cdma_desc->command_type = ctype; | 939 | cdma_desc->command_type = ctype; |
| 940 | cdma_desc->ctrl_data_ptr = (uintptr_t)ctrl_data_ptr; | 940 | cdma_desc->ctrl_data_ptr = ctrl_data_ptr; |
| 941 | } | 941 | } |
| 942 | 942 | ||
| 943 | static u8 cadence_nand_check_desc_error(struct cdns_nand_ctrl *cdns_ctrl, | 943 | static u8 cadence_nand_check_desc_error(struct cdns_nand_ctrl *cdns_ctrl, |
| @@ -1280,8 +1280,7 @@ cadence_nand_cdma_transfer(struct cdns_nand_ctrl *cdns_ctrl, u8 chip_nr, · 336 unmodified lines | |||
| 1280 | } | 1280 | } |
| 1281 | 1281 | ||
| 1282 | cadence_nand_cdma_desc_prepare(cdns_ctrl, chip_nr, page, | 1282 | cadence_nand_cdma_desc_prepare(cdns_ctrl, chip_nr, page, |
| 1283 | (void *)dma_buf, (void *)dma_ctrl_dat, | 1283 | dma_buf, dma_ctrl_dat, ctype); |
| 1284 | ctype); | ||
| 1285 | 1284 | ||
| 1286 | status = cadence_nand_cdma_send_and_wait(cdns_ctrl, thread_nr); | 1285 | status = cadence_nand_cdma_send_and_wait(cdns_ctrl, thread_nr); |
| 1287 | 1286 | ||
| @@ -1360,7 +1359,7 @@ static int cadence_nand_erase(struct nand_chip *chip, u32 page) · 72 unmodified lines | |||
| 1360 | 1359 | ||
| 1361 | cadence_nand_cdma_desc_prepare(cdns_ctrl, | 1360 | cadence_nand_cdma_desc_prepare(cdns_ctrl, |
| 1362 | cdns_chip->cs[chip->cur_cs], | 1361 | cdns_chip->cs[chip->cur_cs], |
| 1363 | page, NULL, NULL, | 1362 | page, 0, 0, |
| 1364 | CDMA_CT_ERASE); | 1363 | CDMA_CT_ERASE); |
| 1365 | status = cadence_nand_cdma_send_and_wait(cdns_ctrl, thread_nr); | 1364 | status = cadence_nand_cdma_send_and_wait(cdns_ctrl, thread_nr); |
| 1366 | if (status) { | 1365 | if (status) { |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | /* Max ECC buffer length */ | 37 | /* Max ECC buffer length */ |
| 38 | #define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG) | 38 | #define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG) |
| 39 | 39 | ||
| 40 | #define FMC2_TIMEOUT_US 1000 | ||
| 40 | #define FMC2_TIMEOUT_MS 1000 | 41 | #define FMC2_TIMEOUT_MS 1000 |
| 41 | 42 | ||
| 42 | /* Timings */ | 43 | /* Timings */ |
| @@ -53,6 +54,8 @@ · 10 unmodified lines | |||
| 53 | #define FMC2_PMEM 0x88 | 54 | #define FMC2_PMEM 0x88 |
| 54 | #define FMC2_PATT 0x8c | 55 | #define FMC2_PATT 0x8c |
| 55 | #define FMC2_HECCR 0x94 | 56 | #define FMC2_HECCR 0x94 |
| 57 | #define FMC2_ISR 0x184 | ||
| 58 | #define FMC2_ICR 0x188 | ||
| 56 | #define FMC2_CSQCR 0x200 | 59 | #define FMC2_CSQCR 0x200 |
| 57 | #define FMC2_CSQCFGR1 0x204 | 60 | #define FMC2_CSQCFGR1 0x204 |
| 58 | #define FMC2_CSQCFGR2 0x208 | 61 | #define FMC2_CSQCFGR2 0x208 |
| @@ -118,6 +121,12 @@ · 59 unmodified lines | |||
| 118 | #define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24) | 121 | #define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24) |
| 119 | #define FMC2_PATT_DEFAULT 0x0a0a0a0a | 122 | #define FMC2_PATT_DEFAULT 0x0a0a0a0a |
| 120 | 123 | ||
| 124 | /* Register: FMC2_ISR */ | ||
| 125 | #define FMC2_ISR_IHLF BIT(1) | ||
| 126 | |||
| 127 | /* Register: FMC2_ICR */ | ||
| 128 | #define FMC2_ICR_CIHLF BIT(1) | ||
| 129 | |||
| 121 | /* Register: FMC2_CSQCR */ | 130 | /* Register: FMC2_CSQCR */ |
| 122 | #define FMC2_CSQCR_CSQSTART BIT(0) | 131 | #define FMC2_CSQCR_CSQSTART BIT(0) |
| 123 | 132 | ||
| @@ -1322,6 +1331,31 @@ static void stm32_fmc2_write_data(struct nand_chip *chip, const void *buf, · 1198 unmodified lines | |||
| 1322 | stm32_fmc2_set_buswidth_16(fmc2, true); | 1331 | stm32_fmc2_set_buswidth_16(fmc2, true); |
| 1323 | } | 1332 | } |
| 1324 | 1333 | ||
| 1334 | static int stm32_fmc2_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) | ||
| 1335 | { | ||
| 1336 | struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); | ||
| 1337 | const struct nand_sdr_timings *timings; | ||
| 1338 | u32 isr, sr; | ||
| 1339 | |||
| 1340 | /* Check if there is no pending requests to the NAND flash */ | ||
| 1341 | if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr, | ||
| 1342 | sr & FMC2_SR_NWRF, 1, | ||
| 1343 | FMC2_TIMEOUT_US)) | ||
| 1344 | dev_warn(fmc2->dev, "Waitrdy timeout\n"); | ||
| 1345 | |||
| 1346 | /* Wait tWB before R/B# signal is low */ | ||
| 1347 | timings = nand_get_sdr_timings(&chip->data_interface); | ||
| 1348 | ndelay(PSEC_TO_NSEC(timings->tWB_max)); | ||
| 1349 | |||
| 1350 | /* R/B# signal is low, clear high level flag */ | ||
| 1351 | writel_relaxed(FMC2_ICR_CIHLF, fmc2->io_base + FMC2_ICR); | ||
| 1352 | |||
| 1353 | /* Wait R/B# signal is high */ | ||
| 1354 | return readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_ISR, | ||
| 1355 | isr, isr & FMC2_ISR_IHLF, | ||
| 1356 | 5, 1000 * timeout_ms); | ||
| 1357 | } | ||
| 1358 | |||
| 1325 | static int stm32_fmc2_exec_op(struct nand_chip *chip, | 1359 | static int stm32_fmc2_exec_op(struct nand_chip *chip, |
| 1326 | const struct nand_operation *op, | 1360 | const struct nand_operation *op, |
| 1327 | bool check_only) | 1361 | bool check_only) |
| @@ -1366,8 +1400,8 @@ static int stm32_fmc2_exec_op(struct nand_chip *chip, · 38 unmodified lines | |||
| 1366 | break; | 1400 | break; |
| 1367 | 1401 | ||
| 1368 | case NAND_OP_WAITRDY_INSTR: | 1402 | case NAND_OP_WAITRDY_INSTR: |
| 1369 | ret = nand_soft_waitrdy(chip, | 1403 | ret = stm32_fmc2_waitrdy(chip, |
| 1370 | instr->ctx.waitrdy.timeout_ms); | 1404 | instr->ctx.waitrdy.timeout_ms); |
| 1371 | break; | 1405 | break; |
| 1372 | } | 1406 | } |
| 1373 | } | 1407 | } |
| @@ -247,7 +247,8 @@ static int sm_read_sector(struct sm_ftl *ftl, · 246 unmodified lines | |||
| 247 | 247 | ||
| 248 | /* FTL can contain -1 entries that are by default filled with bits */ | 248 | /* FTL can contain -1 entries that are by default filled with bits */ |
| 249 | if (block == -1) { | 249 | if (block == -1) { |
| 250 | memset(buffer, 0xFF, SM_SECTOR_SIZE); | 250 | if (buffer) |
| 251 | memset(buffer, 0xFF, SM_SECTOR_SIZE); | ||
| 251 | return 0; | 252 | return 0; |
| 252 | } | 253 | } |
| 253 | 254 | ||
| @@ -4596,6 +4596,7 @@ static void sst_set_default_init(struct spi_nor *nor) · 4595 unmodified lines | |||
| 4596 | static void st_micron_set_default_init(struct spi_nor *nor) | 4596 | static void st_micron_set_default_init(struct spi_nor *nor) |
| 4597 | { | 4597 | { |
| 4598 | nor->flags |= SNOR_F_HAS_LOCK; | 4598 | nor->flags |= SNOR_F_HAS_LOCK; |
| 4599 | nor->flags &= ~SNOR_F_HAS_16BIT_SR; | ||
| 4599 | nor->params.quad_enable = NULL; | 4600 | nor->params.quad_enable = NULL; |
| 4600 | nor->params.set_4byte = st_micron_set_4byte; | 4601 | nor->params.set_4byte = st_micron_set_4byte; |
| 4601 | } | 4602 | } |
| @@ -102,6 +102,7 @@ · 101 unmodified lines | |||
| 102 | #define TCAN4X5X_MODE_NORMAL BIT(7) | 102 | #define TCAN4X5X_MODE_NORMAL BIT(7) |
| 103 | 103 | ||
| 104 | #define TCAN4X5X_DISABLE_WAKE_MSK (BIT(31) | BIT(30)) | 104 | #define TCAN4X5X_DISABLE_WAKE_MSK (BIT(31) | BIT(30)) |
| 105 | #define TCAN4X5X_DISABLE_INH_MSK BIT(9) | ||
| 105 | 106 | ||
| 106 | #define TCAN4X5X_SW_RESET BIT(2) | 107 | #define TCAN4X5X_SW_RESET BIT(2) |
| 107 | 108 | ||
| @@ -166,6 +167,28 @@ static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv) · 58 unmodified lines | |||
| 166 | } | 167 | } |
| 167 | } | 168 | } |
| 168 | 169 | ||
| 170 | static int tcan4x5x_reset(struct tcan4x5x_priv *priv) | ||
| 171 | { | ||
| 172 | int ret = 0; | ||
| 173 | |||
| 174 | if (priv->reset_gpio) { | ||
| 175 | gpiod_set_value(priv->reset_gpio, 1); | ||
| 176 | |||
| 177 | /* tpulse_width minimum 30us */ | ||
| 178 | usleep_range(30, 100); | ||
| 179 | gpiod_set_value(priv->reset_gpio, 0); | ||
| 180 | } else { | ||
| 181 | ret = regmap_write(priv->regmap, TCAN4X5X_CONFIG, | ||
| 182 | TCAN4X5X_SW_RESET); | ||
| 183 | if (ret) | ||
| 184 | return ret; | ||
| 185 | } | ||
| 186 | |||
| 187 | usleep_range(700, 1000); | ||
| 188 | |||
| 189 | return ret; | ||
| 190 | } | ||
| 191 | |||
| 169 | static int regmap_spi_gather_write(void *context, const void *reg, | 192 | static int regmap_spi_gather_write(void *context, const void *reg, |
| 170 | size_t reg_len, const void *val, | 193 | size_t reg_len, const void *val, |
| 171 | size_t val_len) | 194 | size_t val_len) |
| @@ -348,14 +371,23 @@ static int tcan4x5x_disable_wake(struct m_can_classdev *cdev) · 176 unmodified lines | |||
| 348 | TCAN4X5X_DISABLE_WAKE_MSK, 0x00); | 371 | TCAN4X5X_DISABLE_WAKE_MSK, 0x00); |
| 349 | } | 372 | } |
| 350 | 373 | ||
| 374 | static int tcan4x5x_disable_state(struct m_can_classdev *cdev) | ||
| 375 | { | ||
| 376 | struct tcan4x5x_priv *tcan4x5x = cdev->device_data; | ||
| 377 | |||
| 378 | return regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, | ||
| 379 | TCAN4X5X_DISABLE_INH_MSK, 0x01); | ||
| 380 | } | ||
| 381 | |||
| 351 | static int tcan4x5x_parse_config(struct m_can_classdev *cdev) | 382 | static int tcan4x5x_parse_config(struct m_can_classdev *cdev) |
| 352 | { | 383 | { |
| 353 | struct tcan4x5x_priv *tcan4x5x = cdev->device_data; | 384 | struct tcan4x5x_priv *tcan4x5x = cdev->device_data; |
| 385 | int ret; | ||
| 354 | 386 | ||
| 355 | tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake", | 387 | tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake", |
| 356 | GPIOD_OUT_HIGH); | 388 | GPIOD_OUT_HIGH); |
| 357 | if (IS_ERR(tcan4x5x->device_wake_gpio)) { | 389 | if (IS_ERR(tcan4x5x->device_wake_gpio)) { |
| 358 | if (PTR_ERR(tcan4x5x->power) == -EPROBE_DEFER) | 390 | if (PTR_ERR(tcan4x5x->device_wake_gpio) == -EPROBE_DEFER) |
| 359 | return -EPROBE_DEFER; | 391 | return -EPROBE_DEFER; |
| 360 | 392 | ||
| 361 | tcan4x5x_disable_wake(cdev); | 393 | tcan4x5x_disable_wake(cdev); |
| @@ -366,18 +398,17 @@ static int tcan4x5x_parse_config(struct m_can_classdev *cdev) · 4 unmodified lines | |||
| 366 | if (IS_ERR(tcan4x5x->reset_gpio)) | 398 | if (IS_ERR(tcan4x5x->reset_gpio)) |
| 367 | tcan4x5x->reset_gpio = NULL; | 399 | tcan4x5x->reset_gpio = NULL; |
| 368 | 400 | ||
| 369 | usleep_range(700, 1000); | 401 | ret = tcan4x5x_reset(tcan4x5x); |
| 402 | if (ret) | ||
| 403 | return ret; | ||
| 370 | 404 | ||
| 371 | tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev, | 405 | tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev, |
| 372 | "device-state", | 406 | "device-state", |
| 373 | GPIOD_IN); | 407 | GPIOD_IN); |
| 374 | if (IS_ERR(tcan4x5x->device_state_gpio)) | 408 | if (IS_ERR(tcan4x5x->device_state_gpio)) { |
| 375 | tcan4x5x->device_state_gpio = NULL; | 409 | tcan4x5x->device_state_gpio = NULL; |
| 376 | 410 | tcan4x5x_disable_state(cdev); | |
| 377 | tcan4x5x->power = devm_regulator_get_optional(cdev->dev, | 411 | } |
| 378 | "vsup"); | ||
| 379 | if (PTR_ERR(tcan4x5x->power) == -EPROBE_DEFER) | ||
| 380 | return -EPROBE_DEFER; | ||
| 381 | 412 | ||
| 382 | return 0; | 413 | return 0; |
| 383 | } | 414 | } |
| @@ -412,6 +443,12 @@ static int tcan4x5x_can_probe(struct spi_device *spi) · 28 unmodified lines | |||
| 412 | if (!priv) | 443 | if (!priv) |
| 413 | return -ENOMEM; | 444 | return -ENOMEM; |
| 414 | 445 | ||
| 446 | priv->power = devm_regulator_get_optional(&spi->dev, "vsup"); | ||
| 447 | if (PTR_ERR(priv->power) == -EPROBE_DEFER) | ||
| 448 | return -EPROBE_DEFER; | ||
| 449 | else | ||
| 450 | priv->power = NULL; | ||
| 451 | |||
| 415 | mcan_class->device_data = priv; | 452 | mcan_class->device_data = priv; |
| 416 | 453 | ||
| 417 | m_can_class_get_clocks(mcan_class); | 454 | m_can_class_get_clocks(mcan_class); |
| @@ -451,11 +488,17 @@ static int tcan4x5x_can_probe(struct spi_device *spi) · 33 unmodified lines | |||
| 451 | priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus, | 488 | priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus, |
| 452 | &spi->dev, &tcan4x5x_regmap); | 489 | &spi->dev, &tcan4x5x_regmap); |
| 453 | 490 | ||
| 454 | ret = tcan4x5x_parse_config(mcan_class); | 491 | ret = tcan4x5x_power_enable(priv->power, 1); |
| 455 | if (ret) | 492 | if (ret) |
| 456 | goto out_clk; | 493 | goto out_clk; |
| 457 | 494 | ||
| 458 | tcan4x5x_power_enable(priv->power, 1); | 495 | ret = tcan4x5x_parse_config(mcan_class); |
| 496 | if (ret) | ||
| 497 | goto out_power; | ||
| 498 | |||
| 499 | ret = tcan4x5x_init(mcan_class); | ||
| 500 | if (ret) | ||
| 501 | goto out_power; | ||
| 459 | 502 | ||
| 460 | ret = m_can_class_register(mcan_class); | 503 | ret = m_can_class_register(mcan_class); |
| 461 | if (ret) | 504 | if (ret) |
| @@ -381,13 +381,12 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota) · 380 unmodified lines | |||
| 381 | struct net_device *dev = napi->dev; | 381 | struct net_device *dev = napi->dev; |
| 382 | struct mscan_regs __iomem *regs = priv->reg_base; | 382 | struct mscan_regs __iomem *regs = priv->reg_base; |
| 383 | struct net_device_stats *stats = &dev->stats; | 383 | struct net_device_stats *stats = &dev->stats; |
| 384 | int npackets = 0; | 384 | int work_done = 0; |
| 385 | int ret = 1; | ||
| 386 | struct sk_buff *skb; | 385 | struct sk_buff *skb; |
| 387 | struct can_frame *frame; | 386 | struct can_frame *frame; |
| 388 | u8 canrflg; | 387 | u8 canrflg; |
| 389 | 388 | ||
| 390 | while (npackets < quota) { | 389 | while (work_done < quota) { |
| 391 | canrflg = in_8(®s->canrflg); | 390 | canrflg = in_8(®s->canrflg); |
| 392 | if (!(canrflg & (MSCAN_RXF | MSCAN_ERR_IF))) | 391 | if (!(canrflg & (MSCAN_RXF | MSCAN_ERR_IF))) |
| 393 | break; | 392 | break; |
| @@ -408,18 +407,18 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota) · 14 unmodified lines | |||
| 408 | 407 | ||
| 409 | stats->rx_packets++; | 408 | stats->rx_packets++; |
| 410 | stats->rx_bytes += frame->can_dlc; | 409 | stats->rx_bytes += frame->can_dlc; |
| 411 | npackets++; | 410 | work_done++; |
| 412 | netif_receive_skb(skb); | 411 | netif_receive_skb(skb); |
| 413 | } | 412 | } |
| 414 | 413 | ||
| 415 | if (!(in_8(®s->canrflg) & (MSCAN_RXF | MSCAN_ERR_IF))) { | 414 | if (work_done < quota) { |
| 416 | napi_complete(&priv->napi); | 415 | if (likely(napi_complete_done(&priv->napi, work_done))) { |
| 417 | clear_bit(F_RX_PROGRESS, &priv->flags); | 416 | clear_bit(F_RX_PROGRESS, &priv->flags); |
| 418 | if (priv->can.state < CAN_STATE_BUS_OFF) | 417 | if (priv->can.state < CAN_STATE_BUS_OFF) |
| 419 | out_8(®s->canrier, priv->shadow_canrier); | 418 | out_8(®s->canrier, priv->shadow_canrier); |
| 420 | ret = 0; | 419 | } |
| 421 | } | 420 | } |
| 422 | return ret; | 421 | return work_done; |
| 423 | } | 422 | } |
| 424 | 423 | ||
| 425 | static irqreturn_t mscan_isr(int irq, void *dev_id) | 424 | static irqreturn_t mscan_isr(int irq, void *dev_id) |
| @@ -918,7 +918,7 @@ static int gs_usb_probe(struct usb_interface *intf, · 917 unmodified lines | |||
| 918 | GS_USB_BREQ_HOST_FORMAT, | 918 | GS_USB_BREQ_HOST_FORMAT, |
| 919 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 919 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
| 920 | 1, | 920 | 1, |
| 921 | intf->altsetting[0].desc.bInterfaceNumber, | 921 | intf->cur_altsetting->desc.bInterfaceNumber, |
| 922 | hconf, | 922 | hconf, |
| 923 | sizeof(*hconf), | 923 | sizeof(*hconf), |
| 924 | 1000); | 924 | 1000); |
| @@ -941,7 +941,7 @@ static int gs_usb_probe(struct usb_interface *intf, · 16 unmodified lines | |||
| 941 | GS_USB_BREQ_DEVICE_CONFIG, | 941 | GS_USB_BREQ_DEVICE_CONFIG, |
| 942 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 942 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
| 943 | 1, | 943 | 1, |
| 944 | intf->altsetting[0].desc.bInterfaceNumber, | 944 | intf->cur_altsetting->desc.bInterfaceNumber, |
| 945 | dconf, | 945 | dconf, |
| 946 | sizeof(*dconf), | 946 | sizeof(*dconf), |
| 947 | 1000); | 947 | 1000); |
| @@ -1590,7 +1590,7 @@ static int kvaser_usb_hydra_setup_endpoints(struct kvaser_usb *dev) · 1589 unmodified lines | |||
| 1590 | struct usb_endpoint_descriptor *ep; | 1590 | struct usb_endpoint_descriptor *ep; |
| 1591 | int i; | 1591 | int i; |
| 1592 | 1592 | ||
| 1593 | iface_desc = &dev->intf->altsetting[0]; | 1593 | iface_desc = dev->intf->cur_altsetting; |
| 1594 | 1594 | ||
| 1595 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | 1595 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
| 1596 | ep = &iface_desc->endpoint[i].desc; | 1596 | ep = &iface_desc->endpoint[i].desc; |
| @@ -1310,7 +1310,7 @@ static int kvaser_usb_leaf_setup_endpoints(struct kvaser_usb *dev) · 1309 unmodified lines | |||
| 1310 | struct usb_endpoint_descriptor *endpoint; | 1310 | struct usb_endpoint_descriptor *endpoint; |
| 1311 | int i; | 1311 | int i; |
| 1312 | 1312 | ||
| 1313 | iface_desc = &dev->intf->altsetting[0]; | 1313 | iface_desc = dev->intf->cur_altsetting; |
| 1314 | 1314 | ||
| 1315 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | 1315 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
| 1316 | endpoint = &iface_desc->endpoint[i].desc; | 1316 | endpoint = &iface_desc->endpoint[i].desc; |
| @@ -358,7 +358,7 @@ static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port, · 357 unmodified lines | |||
| 358 | return -EINVAL; | 358 | return -EINVAL; |
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | ip_frag = be32_to_cpu(fs->m_ext.data[0]); | 361 | ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1); |
| 362 | 362 | ||
| 363 | /* Locate the first rule available */ | 363 | /* Locate the first rule available */ |
| 364 | if (fs->location == RX_CLS_LOC_ANY) | 364 | if (fs->location == RX_CLS_LOC_ANY) |
| @@ -569,7 +569,7 @@ static int bcm_sf2_cfp_rule_cmp(struct bcm_sf2_priv *priv, int port, · 204 unmodified lines | |||
| 569 | 569 | ||
| 570 | if (rule->fs.flow_type != fs->flow_type || | 570 | if (rule->fs.flow_type != fs->flow_type || |
| 571 | rule->fs.ring_cookie != fs->ring_cookie || | 571 | rule->fs.ring_cookie != fs->ring_cookie || |
| 572 | rule->fs.m_ext.data[0] != fs->m_ext.data[0]) | 572 | rule->fs.h_ext.data[0] != fs->h_ext.data[0]) |
| 573 | continue; | 573 | continue; |
| 574 | 574 | ||
| 575 | switch (fs->flow_type & ~FLOW_EXT) { | 575 | switch (fs->flow_type & ~FLOW_EXT) { |
| @@ -621,7 +621,7 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port, · 45 unmodified lines | |||
| 621 | return -EINVAL; | 621 | return -EINVAL; |
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | ip_frag = be32_to_cpu(fs->m_ext.data[0]); | 624 | ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1); |
| 625 | 625 | ||
| 626 | layout = &udf_tcpip6_layout; | 626 | layout = &udf_tcpip6_layout; |
| 627 | slice_num = bcm_sf2_get_slice_number(layout, 0); | 627 | slice_num = bcm_sf2_get_slice_number(layout, 0); |
| @@ -360,6 +360,11 @@ int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port) · 359 unmodified lines | |||
| 360 | { | 360 | { |
| 361 | u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST; | 361 | u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST; |
| 362 | 362 | ||
| 363 | /* Use the default high priority for management frames sent to | ||
| 364 | * the CPU. | ||
| 365 | */ | ||
| 366 | port |= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI; | ||
| 367 | |||
| 363 | return mv88e6390_g1_monitor_write(chip, ptr, port); | 368 | return mv88e6390_g1_monitor_write(chip, ptr, port); |
| 364 | } | 369 | } |
| 365 | 370 | ||
| @@ -211,6 +211,7 @@ · 210 unmodified lines | |||
| 211 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST 0x2000 | 211 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST 0x2000 |
| 212 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST 0x2100 | 212 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST 0x2100 |
| 213 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST 0x3000 | 213 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST 0x3000 |
| 214 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI 0x00e0 | ||
| 214 | #define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK 0x00ff | 215 | #define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK 0x00ff |
| 215 | 216 | ||
| 216 | /* Offset 0x1C: Global Control 2 */ | 217 | /* Offset 0x1C: Global Control 2 */ |
| @@ -393,7 +393,7 @@ phy_interface_t mv88e6390x_port_max_speed_mode(int port) · 392 unmodified lines | |||
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, | 395 | static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, |
| 396 | phy_interface_t mode) | 396 | phy_interface_t mode, bool force) |
| 397 | { | 397 | { |
| 398 | u8 lane; | 398 | u8 lane; |
| 399 | u16 cmode; | 399 | u16 cmode; |
| @@ -427,8 +427,8 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, · 27 unmodified lines | |||
| 427 | cmode = 0; | 427 | cmode = 0; |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | /* cmode doesn't change, nothing to do for us */ | 430 | /* cmode doesn't change, nothing to do for us unless forced */ |
| 431 | if (cmode == chip->ports[port].cmode) | 431 | if (cmode == chip->ports[port].cmode && !force) |
| 432 | return 0; | 432 | return 0; |
| 433 | 433 | ||
| 434 | lane = mv88e6xxx_serdes_get_lane(chip, port); | 434 | lane = mv88e6xxx_serdes_get_lane(chip, port); |
| @@ -484,7 +484,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, · 49 unmodified lines | |||
| 484 | if (port != 9 && port != 10) | 484 | if (port != 9 && port != 10) |
| 485 | return -EOPNOTSUPP; | 485 | return -EOPNOTSUPP; |
| 486 | 486 | ||
| 487 | return mv88e6xxx_port_set_cmode(chip, port, mode); | 487 | return mv88e6xxx_port_set_cmode(chip, port, mode, false); |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, | 490 | int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, |
| @@ -504,7 +504,7 @@ int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, · 13 unmodified lines | |||
| 504 | break; | 504 | break; |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | return mv88e6xxx_port_set_cmode(chip, port, mode); | 507 | return mv88e6xxx_port_set_cmode(chip, port, mode, false); |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip, | 510 | static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip, |
| @@ -555,7 +555,7 @@ int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port, · 44 unmodified lines | |||
| 555 | if (err) | 555 | if (err) |
| 556 | return err; | 556 | return err; |
| 557 | 557 | ||
| 558 | return mv88e6xxx_port_set_cmode(chip, port, mode); | 558 | return mv88e6xxx_port_set_cmode(chip, port, mode, true); |
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) | 561 | int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) |
| @@ -1569,8 +1569,8 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled) · 1568 unmodified lines | |||
| 1569 | 1569 | ||
| 1570 | if (enabled) { | 1570 | if (enabled) { |
| 1571 | /* Enable VLAN filtering. */ | 1571 | /* Enable VLAN filtering. */ |
| 1572 | tpid = ETH_P_8021AD; | 1572 | tpid = ETH_P_8021Q; |
| 1573 | tpid2 = ETH_P_8021Q; | 1573 | tpid2 = ETH_P_8021AD; |
| 1574 | } else { | 1574 | } else { |
| 1575 | /* Disable VLAN filtering. */ | 1575 | /* Disable VLAN filtering. */ |
| 1576 | tpid = ETH_P_SJA1105; | 1576 | tpid = ETH_P_SJA1105; |
| @@ -1579,9 +1579,9 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled) · 2 unmodified lines | |||
| 1579 | 1579 | ||
| 1580 | table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; | 1580 | table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; |
| 1581 | general_params = table->entries; | 1581 | general_params = table->entries; |
| 1582 | /* EtherType used to identify outer tagged (S-tag) VLAN traffic */ | ||
| 1583 | general_params->tpid = tpid; | ||
| 1584 | /* EtherType used to identify inner tagged (C-tag) VLAN traffic */ | 1582 | /* EtherType used to identify inner tagged (C-tag) VLAN traffic */ |
| 1583 | general_params->tpid = tpid; | ||
| 1584 | /* EtherType used to identify outer tagged (S-tag) VLAN traffic */ | ||
| 1585 | general_params->tpid2 = tpid2; | 1585 | general_params->tpid2 = tpid2; |
| 1586 | /* When VLAN filtering is on, we need to at least be able to | 1586 | /* When VLAN filtering is on, we need to at least be able to |
| 1587 | * decode management traffic through the "backup plan". | 1587 | * decode management traffic through the "backup plan". |
| @@ -1855,7 +1855,7 @@ static netdev_tx_t sja1105_port_deferred_xmit(struct dsa_switch *ds, int port, · 267 unmodified lines | |||
| 1855 | if (!clone) | 1855 | if (!clone) |
| 1856 | goto out; | 1856 | goto out; |
| 1857 | 1857 | ||
| 1858 | sja1105_ptp_txtstamp_skb(ds, slot, clone); | 1858 | sja1105_ptp_txtstamp_skb(ds, port, clone); |
| 1859 | 1859 | ||
| 1860 | out: | 1860 | out: |
| 1861 | mutex_unlock(&priv->mgmt_lock); | 1861 | mutex_unlock(&priv->mgmt_lock); |
| @@ -234,7 +234,7 @@ int sja1105_ptp_commit(struct dsa_switch *ds, struct sja1105_ptp_cmd *cmd, · 233 unmodified lines | |||
| 234 | if (rw == SPI_WRITE) | 234 | if (rw == SPI_WRITE) |
| 235 | priv->info->ptp_cmd_packing(buf, cmd, PACK); | 235 | priv->info->ptp_cmd_packing(buf, cmd, PACK); |
| 236 | 236 | ||
| 237 | rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->ptp_control, buf, | 237 | rc = sja1105_xfer_buf(priv, rw, regs->ptp_control, buf, |
| 238 | SJA1105_SIZE_PTP_CMD); | 238 | SJA1105_SIZE_PTP_CMD); |
| 239 | 239 | ||
| 240 | if (rw == SPI_READ) | 240 | if (rw == SPI_READ) |
| @@ -659,7 +659,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds) · 418 unmodified lines | |||
| 659 | ptp_data->clock = NULL; | 659 | ptp_data->clock = NULL; |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot, | 662 | void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int port, |
| 663 | struct sk_buff *skb) | 663 | struct sk_buff *skb) |
| 664 | { | 664 | { |
| 665 | struct sja1105_private *priv = ds->priv; | 665 | struct sja1105_private *priv = ds->priv; |
| @@ -679,7 +679,7 @@ void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int slot, · 13 unmodified lines | |||
| 679 | goto out; | 679 | goto out; |
| 680 | } | 680 | } |
| 681 | 681 | ||
| 682 | rc = sja1105_ptpegr_ts_poll(ds, slot, &ts); | 682 | rc = sja1105_ptpegr_ts_poll(ds, port, &ts); |
| 683 | if (rc < 0) { | 683 | if (rc < 0) { |
| 684 | dev_err(ds->dev, "timed out polling for tstamp\n"); | 684 | dev_err(ds->dev, "timed out polling for tstamp\n"); |
| 685 | kfree_skb(skb); | 685 | kfree_skb(skb); |
| @@ -142,6 +142,9 @@ static size_t sja1105et_general_params_entry_packing(void *buf, void *entry_ptr, · 141 unmodified lines | |||
| 142 | return size; | 142 | return size; |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | /* TPID and TPID2 are intentionally reversed so that semantic | ||
| 146 | * compatibility with E/T is kept. | ||
| 147 | */ | ||
| 145 | static size_t | 148 | static size_t |
| 146 | sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, | 149 | sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, |
| 147 | enum packing_op op) | 150 | enum packing_op op) |
| @@ -166,9 +169,9 @@ sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, · 18 unmodified lines | |||
| 166 | sja1105_packing(buf, &entry->mirr_port, 141, 139, size, op); | 169 | sja1105_packing(buf, &entry->mirr_port, 141, 139, size, op); |
| 167 | sja1105_packing(buf, &entry->vlmarker, 138, 107, size, op); | 170 | sja1105_packing(buf, &entry->vlmarker, 138, 107, size, op); |
| 168 | sja1105_packing(buf, &entry->vlmask, 106, 75, size, op); | 171 | sja1105_packing(buf, &entry->vlmask, 106, 75, size, op); |
| 169 | sja1105_packing(buf, &entry->tpid, 74, 59, size, op); | 172 | sja1105_packing(buf, &entry->tpid2, 74, 59, size, op); |
| 170 | sja1105_packing(buf, &entry->ignore2stf, 58, 58, size, op); | 173 | sja1105_packing(buf, &entry->ignore2stf, 58, 58, size, op); |
| 171 | sja1105_packing(buf, &entry->tpid2, 57, 42, size, op); | 174 | sja1105_packing(buf, &entry->tpid, 57, 42, size, op); |
| 172 | sja1105_packing(buf, &entry->queue_ts, 41, 41, size, op); | 175 | sja1105_packing(buf, &entry->queue_ts, 41, 41, size, op); |
| 173 | sja1105_packing(buf, &entry->egrmirrvid, 40, 29, size, op); | 176 | sja1105_packing(buf, &entry->egrmirrvid, 40, 29, size, op); |
| 174 | sja1105_packing(buf, &entry->egrmirrpcp, 28, 26, size, op); | 177 | sja1105_packing(buf, &entry->egrmirrpcp, 28, 26, size, op); |
| @@ -477,11 +477,6 @@ int sja1105_setup_tc_taprio(struct dsa_switch *ds, int port, · 476 unmodified lines | |||
| 477 | if (admin->cycle_time_extension) | 477 | if (admin->cycle_time_extension) |
| 478 | return -ENOTSUPP; | 478 | return -ENOTSUPP; |
| 479 | 479 | ||
| 480 | if (!ns_to_sja1105_delta(admin->base_time)) { | ||
| 481 | dev_err(ds->dev, "A base time of zero is not hardware-allowed\n"); | ||
| 482 | return -ERANGE; | ||
| 483 | } | ||
| 484 | |||
| 485 | for (i = 0; i < admin->num_entries; i++) { | 480 | for (i = 0; i < admin->num_entries; i++) { |
| 486 | s64 delta_ns = admin->entries[i].interval; | 481 | s64 delta_ns = admin->entries[i].interval; |
| 487 | s64 delta_cycles = ns_to_sja1105_delta(delta_ns); | 482 | s64 delta_cycles = ns_to_sja1105_delta(delta_ns); |
| @@ -403,6 +403,8 @@ int aq_nic_start(struct aq_nic_s *self) · 402 unmodified lines | |||
| 403 | if (err < 0) | 403 | if (err < 0) |
| 404 | goto err_exit; | 404 | goto err_exit; |
| 405 | 405 | ||
| 406 | aq_nic_set_loopback(self); | ||
| 407 | |||
| 406 | err = self->aq_hw_ops->hw_start(self->aq_hw); | 408 | err = self->aq_hw_ops->hw_start(self->aq_hw); |
| 407 | if (err < 0) | 409 | if (err < 0) |
| 408 | goto err_exit; | 410 | goto err_exit; |
| @@ -413,8 +415,6 @@ int aq_nic_start(struct aq_nic_s *self) · 4 unmodified lines | |||
| 413 | 415 | ||
| 414 | INIT_WORK(&self->service_task, aq_nic_service_task); | 416 | INIT_WORK(&self->service_task, aq_nic_service_task); |
| 415 | 417 | ||
| 416 | aq_nic_set_loopback(self); | ||
| 417 | |||
| 418 | timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0); | 418 | timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0); |
| 419 | aq_nic_service_timer_cb(&self->service_timer); | 419 | aq_nic_service_timer_cb(&self->service_timer); |
| 420 | 420 | ||
| @@ -1525,9 +1525,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = { · 1524 unmodified lines | |||
| 1525 | .rx_extract_ts = hw_atl_b0_rx_extract_ts, | 1525 | .rx_extract_ts = hw_atl_b0_rx_extract_ts, |
| 1526 | .extract_hwts = hw_atl_b0_extract_hwts, | 1526 | .extract_hwts = hw_atl_b0_extract_hwts, |
| 1527 | .hw_set_offload = hw_atl_b0_hw_offload_set, | 1527 | .hw_set_offload = hw_atl_b0_hw_offload_set, |
| 1528 | .hw_get_hw_stats = hw_atl_utils_get_hw_stats, | ||
| 1529 | .hw_get_fw_version = hw_atl_utils_get_fw_version, | ||
| 1530 | .hw_set_offload = hw_atl_b0_hw_offload_set, | ||
| 1531 | .hw_set_loopback = hw_atl_b0_set_loopback, | 1528 | .hw_set_loopback = hw_atl_b0_set_loopback, |
| 1532 | .hw_set_fc = hw_atl_b0_set_fc, | 1529 | .hw_set_fc = hw_atl_b0_set_fc, |
| 1533 | }; | 1530 | }; |
| @@ -667,9 +667,7 @@ int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self) · 666 unmodified lines | |||
| 667 | u32 speed; | 667 | u32 speed; |
| 668 | 668 | ||
| 669 | mpi_state = hw_atl_utils_mpi_get_state(self); | 669 | mpi_state = hw_atl_utils_mpi_get_state(self); |
| 670 | speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G | | 670 | speed = mpi_state >> HW_ATL_MPI_SPEED_SHIFT; |
| 671 | FW2X_RATE_2G5 | FW2X_RATE_5G | | ||
| 672 | FW2X_RATE_10G); | ||
| 673 | 671 | ||
| 674 | if (!speed) { | 672 | if (!speed) { |
| 675 | link_status->mbps = 0U; | 673 | link_status->mbps = 0U; |
| @@ -1516,8 +1516,10 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset) · 1515 unmodified lines | |||
| 1516 | int ethaddr_bytes = ETH_ALEN; | 1516 | int ethaddr_bytes = ETH_ALEN; |
| 1517 | 1517 | ||
| 1518 | memset(ppattern + offset, 0xff, magicsync); | 1518 | memset(ppattern + offset, 0xff, magicsync); |
| 1519 | for (j = 0; j < magicsync; j++) | 1519 | for (j = 0; j < magicsync; j++) { |
| 1520 | set_bit(len++, (unsigned long *) pmask); | 1520 | pmask[len >> 3] |= BIT(len & 7); |
| 1521 | len++; | ||
| 1522 | } | ||
| 1521 | 1523 | ||
| 1522 | for (j = 0; j < B44_MAX_PATTERNS; j++) { | 1524 | for (j = 0; j < B44_MAX_PATTERNS; j++) { |
| 1523 | if ((B44_PATTERN_SIZE - len) >= ETH_ALEN) | 1525 | if ((B44_PATTERN_SIZE - len) >= ETH_ALEN) |
| @@ -1529,7 +1531,8 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset) · 5 unmodified lines | |||
| 1529 | for (k = 0; k< ethaddr_bytes; k++) { | 1531 | for (k = 0; k< ethaddr_bytes; k++) { |
| 1530 | ppattern[offset + magicsync + | 1532 | ppattern[offset + magicsync + |
| 1531 | (j * ETH_ALEN) + k] = macaddr[k]; | 1533 | (j * ETH_ALEN) + k] = macaddr[k]; |
| 1532 | set_bit(len++, (unsigned long *) pmask); | 1534 | pmask[len >> 3] |= BIT(len & 7); |
| 1535 | len++; | ||
| 1533 | } | 1536 | } |
| 1534 | } | 1537 | } |
| 1535 | return len - 1; | 1538 | return len - 1; |
| @@ -1536,8 +1536,11 @@ void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj, · 1535 unmodified lines | |||
| 1536 | ((MAX_MAC_CREDIT_E2 - GET_NUM_VFS_PER_PATH(bp) * VF_MAC_CREDIT_CNT) / \ | 1536 | ((MAX_MAC_CREDIT_E2 - GET_NUM_VFS_PER_PATH(bp) * VF_MAC_CREDIT_CNT) / \ |
| 1537 | func_num + GET_NUM_VFS_PER_PF(bp) * VF_MAC_CREDIT_CNT) | 1537 | func_num + GET_NUM_VFS_PER_PF(bp) * VF_MAC_CREDIT_CNT) |
| 1538 | 1538 | ||
| 1539 | #define BNX2X_VFS_VLAN_CREDIT(bp) \ | ||
| 1540 | (GET_NUM_VFS_PER_PATH(bp) * VF_VLAN_CREDIT_CNT) | ||
| 1541 | |||
| 1539 | #define PF_VLAN_CREDIT_E2(bp, func_num) \ | 1542 | #define PF_VLAN_CREDIT_E2(bp, func_num) \ |
| 1540 | ((MAX_MAC_CREDIT_E2 - GET_NUM_VFS_PER_PATH(bp) * VF_VLAN_CREDIT_CNT) / \ | 1543 | ((MAX_VLAN_CREDIT_E2 - 1 - BNX2X_VFS_VLAN_CREDIT(bp)) / \ |
| 1541 | func_num + GET_NUM_VFS_PER_PF(bp) * VF_VLAN_CREDIT_CNT) | 1544 | func_num + GET_NUM_VFS_PER_PF(bp) * VF_VLAN_CREDIT_CNT) |
| 1542 | 1545 | ||
| 1543 | #endif /* BNX2X_SP_VERBS */ | 1546 | #endif /* BNX2X_SP_VERBS */ |
| @@ -4088,7 +4088,7 @@ static int fu540_c000_clk_init(struct platform_device *pdev, struct clk **pclk, · 4087 unmodified lines | |||
| 4088 | mgmt->rate = 0; | 4088 | mgmt->rate = 0; |
| 4089 | mgmt->hw.init = &init; | 4089 | mgmt->hw.init = &init; |
| 4090 | 4090 | ||
| 4091 | *tx_clk = clk_register(NULL, &mgmt->hw); | 4091 | *tx_clk = devm_clk_register(&pdev->dev, &mgmt->hw); |
| 4092 | if (IS_ERR(*tx_clk)) | 4092 | if (IS_ERR(*tx_clk)) |
| 4093 | return PTR_ERR(*tx_clk); | 4093 | return PTR_ERR(*tx_clk); |
| 4094 | 4094 | ||
| @@ -4416,7 +4416,6 @@ err_out_free_netdev: · 321 unmodified lines | |||
| 4416 | 4416 | ||
| 4417 | err_disable_clocks: | 4417 | err_disable_clocks: |
| 4418 | clk_disable_unprepare(tx_clk); | 4418 | clk_disable_unprepare(tx_clk); |
| 4419 | clk_unregister(tx_clk); | ||
| 4420 | clk_disable_unprepare(hclk); | 4419 | clk_disable_unprepare(hclk); |
| 4421 | clk_disable_unprepare(pclk); | 4420 | clk_disable_unprepare(pclk); |
| 4422 | clk_disable_unprepare(rx_clk); | 4421 | clk_disable_unprepare(rx_clk); |
| @@ -4446,7 +4445,6 @@ static int macb_remove(struct platform_device *pdev) · 23 unmodified lines | |||
| 4446 | pm_runtime_dont_use_autosuspend(&pdev->dev); | 4445 | pm_runtime_dont_use_autosuspend(&pdev->dev); |
| 4447 | if (!pm_runtime_suspended(&pdev->dev)) { | 4446 | if (!pm_runtime_suspended(&pdev->dev)) { |
| 4448 | clk_disable_unprepare(bp->tx_clk); | 4447 | clk_disable_unprepare(bp->tx_clk); |
| 4449 | clk_unregister(bp->tx_clk); | ||
| 4450 | clk_disable_unprepare(bp->hclk); | 4448 | clk_disable_unprepare(bp->hclk); |
| 4451 | clk_disable_unprepare(bp->pclk); | 4449 | clk_disable_unprepare(bp->pclk); |
| 4452 | clk_disable_unprepare(bp->rx_clk); | 4450 | clk_disable_unprepare(bp->rx_clk); |
| @@ -504,6 +504,7 @@ struct link_config { · 503 unmodified lines | |||
| 504 | 504 | ||
| 505 | enum cc_pause requested_fc; /* flow control user has requested */ | 505 | enum cc_pause requested_fc; /* flow control user has requested */ |
| 506 | enum cc_pause fc; /* actual link flow control */ | 506 | enum cc_pause fc; /* actual link flow control */ |
| 507 | enum cc_pause advertised_fc; /* actual advertised flow control */ | ||
| 507 | 508 | ||
| 508 | enum cc_fec requested_fec; /* Forward Error Correction: */ | 509 | enum cc_fec requested_fec; /* Forward Error Correction: */ |
| 509 | enum cc_fec fec; /* requested and actual in use */ | 510 | enum cc_fec fec; /* requested and actual in use */ |
| @@ -807,8 +807,8 @@ static void get_pauseparam(struct net_device *dev, · 806 unmodified lines | |||
| 807 | struct port_info *p = netdev_priv(dev); | 807 | struct port_info *p = netdev_priv(dev); |
| 808 | 808 | ||
| 809 | epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; | 809 | epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; |
| 810 | epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0; | 810 | epause->rx_pause = (p->link_cfg.advertised_fc & PAUSE_RX) != 0; |
| 811 | epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0; | 811 | epause->tx_pause = (p->link_cfg.advertised_fc & PAUSE_TX) != 0; |
| 812 | } | 812 | } |
| 813 | 813 | ||
| 814 | static int set_pauseparam(struct net_device *dev, | 814 | static int set_pauseparam(struct net_device *dev, |
| @@ -4089,7 +4089,8 @@ static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause) · 4088 unmodified lines | |||
| 4089 | if (cc_pause & PAUSE_TX) | 4089 | if (cc_pause & PAUSE_TX) |
| 4090 | fw_pause |= FW_PORT_CAP32_802_3_PAUSE; | 4090 | fw_pause |= FW_PORT_CAP32_802_3_PAUSE; |
| 4091 | else | 4091 | else |
| 4092 | fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR; | 4092 | fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR | |
| 4093 | FW_PORT_CAP32_802_3_PAUSE; | ||
| 4093 | } else if (cc_pause & PAUSE_TX) { | 4094 | } else if (cc_pause & PAUSE_TX) { |
| 4094 | fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR; | 4095 | fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR; |
| 4095 | } | 4096 | } |
| @@ -8563,17 +8564,17 @@ static fw_port_cap32_t lstatus_to_fwcap(u32 lstatus) · 4467 unmodified lines | |||
| 8563 | void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) | 8564 | void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) |
| 8564 | { | 8565 | { |
| 8565 | const struct fw_port_cmd *cmd = (const void *)rpl; | 8566 | const struct fw_port_cmd *cmd = (const void *)rpl; |
| 8566 | int action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); | 8567 | fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; |
| 8567 | struct adapter *adapter = pi->adapter; | ||
| 8568 | struct link_config *lc = &pi->link_cfg; | 8568 | struct link_config *lc = &pi->link_cfg; |
| 8569 | int link_ok, linkdnrc; | 8569 | struct adapter *adapter = pi->adapter; |
| 8570 | enum fw_port_type port_type; | 8570 | unsigned int speed, fc, fec, adv_fc; |
| 8571 | enum fw_port_module_type mod_type; | 8571 | enum fw_port_module_type mod_type; |
| 8572 | unsigned int speed, fc, fec; | 8572 | int action, link_ok, linkdnrc; |
| 8573 | fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; | 8573 | enum fw_port_type port_type; |
| 8574 | 8574 | ||
| 8575 | /* Extract the various fields from the Port Information message. | 8575 | /* Extract the various fields from the Port Information message. |
| 8576 | */ | 8576 | */ |
| 8577 | action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); | ||
| 8577 | switch (action) { | 8578 | switch (action) { |
| 8578 | case FW_PORT_ACTION_GET_PORT_INFO: { | 8579 | case FW_PORT_ACTION_GET_PORT_INFO: { |
| 8579 | u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype); | 8580 | u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype); |
| @@ -8611,6 +8612,7 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) · 31 unmodified lines | |||
| 8611 | } | 8612 | } |
| 8612 | 8613 | ||
| 8613 | fec = fwcap_to_cc_fec(acaps); | 8614 | fec = fwcap_to_cc_fec(acaps); |
| 8615 | adv_fc = fwcap_to_cc_pause(acaps); | ||
| 8614 | fc = fwcap_to_cc_pause(linkattr); | 8616 | fc = fwcap_to_cc_pause(linkattr); |
| 8615 | speed = fwcap_to_speed(linkattr); | 8617 | speed = fwcap_to_speed(linkattr); |
| 8616 | 8618 | ||
| @@ -8667,7 +8669,9 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) · 50 unmodified lines | |||
| 8667 | } | 8669 | } |
| 8668 | 8670 | ||
| 8669 | if (link_ok != lc->link_ok || speed != lc->speed || | 8671 | if (link_ok != lc->link_ok || speed != lc->speed || |
| 8670 | fc != lc->fc || fec != lc->fec) { /* something changed */ | 8672 | fc != lc->fc || adv_fc != lc->advertised_fc || |
| 8673 | fec != lc->fec) { | ||
| 8674 | /* something changed */ | ||
| 8671 | if (!link_ok && lc->link_ok) { | 8675 | if (!link_ok && lc->link_ok) { |
| 8672 | lc->link_down_rc = linkdnrc; | 8676 | lc->link_down_rc = linkdnrc; |
| 8673 | dev_warn_ratelimited(adapter->pdev_dev, | 8677 | dev_warn_ratelimited(adapter->pdev_dev, |
| @@ -8677,6 +8681,7 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) · 3 unmodified lines | |||
| 8677 | } | 8681 | } |
| 8678 | lc->link_ok = link_ok; | 8682 | lc->link_ok = link_ok; |
| 8679 | lc->speed = speed; | 8683 | lc->speed = speed; |
| 8684 | lc->advertised_fc = adv_fc; | ||
| 8680 | lc->fc = fc; | 8685 | lc->fc = fc; |
| 8681 | lc->fec = fec; | 8686 | lc->fec = fec; |
| 8682 | 8687 | ||
| @@ -1690,8 +1690,8 @@ static void cxgb4vf_get_pauseparam(struct net_device *dev, · 1689 unmodified lines | |||
| 1690 | struct port_info *pi = netdev_priv(dev); | 1690 | struct port_info *pi = netdev_priv(dev); |
| 1691 | 1691 | ||
| 1692 | pauseparam->autoneg = (pi->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; | 1692 | pauseparam->autoneg = (pi->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; |
| 1693 | pauseparam->rx_pause = (pi->link_cfg.fc & PAUSE_RX) != 0; | 1693 | pauseparam->rx_pause = (pi->link_cfg.advertised_fc & PAUSE_RX) != 0; |
| 1694 | pauseparam->tx_pause = (pi->link_cfg.fc & PAUSE_TX) != 0; | 1694 | pauseparam->tx_pause = (pi->link_cfg.advertised_fc & PAUSE_TX) != 0; |
| 1695 | } | 1695 | } |
| 1696 | 1696 | ||
| 1697 | /* | 1697 | /* |
| @@ -135,6 +135,7 @@ struct link_config { · 134 unmodified lines | |||
| 135 | 135 | ||
| 136 | enum cc_pause requested_fc; /* flow control user has requested */ | 136 | enum cc_pause requested_fc; /* flow control user has requested */ |
| 137 | enum cc_pause fc; /* actual link flow control */ | 137 | enum cc_pause fc; /* actual link flow control */ |
| 138 | enum cc_pause advertised_fc; /* actual advertised flow control */ | ||
| 138 | 139 | ||
| 139 | enum cc_fec auto_fec; /* Forward Error Correction: */ | 140 | enum cc_fec auto_fec; /* Forward Error Correction: */ |
| 140 | enum cc_fec requested_fec; /* "automatic" (IEEE 802.3), */ | 141 | enum cc_fec requested_fec; /* "automatic" (IEEE 802.3), */ |
| @@ -1913,16 +1913,16 @@ static const char *t4vf_link_down_rc_str(unsigned char link_down_rc) · 1912 unmodified lines | |||
| 1913 | static void t4vf_handle_get_port_info(struct port_info *pi, | 1913 | static void t4vf_handle_get_port_info(struct port_info *pi, |
| 1914 | const struct fw_port_cmd *cmd) | 1914 | const struct fw_port_cmd *cmd) |
| 1915 | { | 1915 | { |
| 1916 | int action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); | 1916 | fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; |
| 1917 | struct adapter *adapter = pi->adapter; | ||
| 1918 | struct link_config *lc = &pi->link_cfg; | 1917 | struct link_config *lc = &pi->link_cfg; |
| 1919 | int link_ok, linkdnrc; | 1918 | struct adapter *adapter = pi->adapter; |
| 1920 | enum fw_port_type port_type; | 1919 | unsigned int speed, fc, fec, adv_fc; |
| 1921 | enum fw_port_module_type mod_type; | 1920 | enum fw_port_module_type mod_type; |
| 1922 | unsigned int speed, fc, fec; | 1921 | int action, link_ok, linkdnrc; |
| 1923 | fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; | 1922 | enum fw_port_type port_type; |
| 1924 | 1923 | ||
| 1925 | /* Extract the various fields from the Port Information message. */ | 1924 | /* Extract the various fields from the Port Information message. */ |
| 1925 | action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); | ||
| 1926 | switch (action) { | 1926 | switch (action) { |
| 1927 | case FW_PORT_ACTION_GET_PORT_INFO: { | 1927 | case FW_PORT_ACTION_GET_PORT_INFO: { |
| 1928 | u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype); | 1928 | u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype); |
| @@ -1982,6 +1982,7 @@ static void t4vf_handle_get_port_info(struct port_info *pi, · 53 unmodified lines | |||
| 1982 | } | 1982 | } |
| 1983 | 1983 | ||
| 1984 | fec = fwcap_to_cc_fec(acaps); | 1984 | fec = fwcap_to_cc_fec(acaps); |
| 1985 | adv_fc = fwcap_to_cc_pause(acaps); | ||
| 1985 | fc = fwcap_to_cc_pause(linkattr); | 1986 | fc = fwcap_to_cc_pause(linkattr); |
| 1986 | speed = fwcap_to_speed(linkattr); | 1987 | speed = fwcap_to_speed(linkattr); |
| 1987 | 1988 | ||
| @@ -2012,7 +2013,9 @@ static void t4vf_handle_get_port_info(struct port_info *pi, · 24 unmodified lines | |||
| 2012 | } | 2013 | } |
| 2013 | 2014 | ||
| 2014 | if (link_ok != lc->link_ok || speed != lc->speed || | 2015 | if (link_ok != lc->link_ok || speed != lc->speed || |
| 2015 | fc != lc->fc || fec != lc->fec) { /* something changed */ | 2016 | fc != lc->fc || adv_fc != lc->advertised_fc || |
| 2017 | fec != lc->fec) { | ||
| 2018 | /* something changed */ | ||
| 2016 | if (!link_ok && lc->link_ok) { | 2019 | if (!link_ok && lc->link_ok) { |
| 2017 | lc->link_down_rc = linkdnrc; | 2020 | lc->link_down_rc = linkdnrc; |
| 2018 | dev_warn_ratelimited(adapter->pdev_dev, | 2021 | dev_warn_ratelimited(adapter->pdev_dev, |
| @@ -2022,6 +2025,7 @@ static void t4vf_handle_get_port_info(struct port_info *pi, · 3 unmodified lines | |||
| 2022 | } | 2025 | } |
| 2023 | lc->link_ok = link_ok; | 2026 | lc->link_ok = link_ok; |
| 2024 | lc->speed = speed; | 2027 | lc->speed = speed; |
| 2028 | lc->advertised_fc = adv_fc; | ||
| 2025 | lc->fc = fc; | 2029 | lc->fc = fc; |
| 2026 | lc->fec = fec; | 2030 | lc->fec = fec; |
| 2027 | 2031 | ||
| @@ -1719,7 +1719,7 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, · 1718 unmodified lines | |||
| 1719 | int page_offset; | 1719 | int page_offset; |
| 1720 | unsigned int sz; | 1720 | unsigned int sz; |
| 1721 | int *count_ptr; | 1721 | int *count_ptr; |
| 1722 | int i; | 1722 | int i, j; |
| 1723 | 1723 | ||
| 1724 | vaddr = phys_to_virt(addr); | 1724 | vaddr = phys_to_virt(addr); |
| 1725 | WARN_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES)); | 1725 | WARN_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES)); |
| @@ -1736,14 +1736,14 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, · 10 unmodified lines | |||
| 1736 | WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr, | 1736 | WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr, |
| 1737 | SMP_CACHE_BYTES)); | 1737 | SMP_CACHE_BYTES)); |
| 1738 | 1738 | ||
| 1739 | dma_unmap_page(priv->rx_dma_dev, sg_addr, | ||
| 1740 | DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); | ||
| 1741 | |||
| 1739 | /* We may use multiple Rx pools */ | 1742 | /* We may use multiple Rx pools */ |
| 1740 | dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); | 1743 | dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); |
| 1741 | if (!dpaa_bp) | 1744 | if (!dpaa_bp) |
| 1742 | goto free_buffers; | 1745 | goto free_buffers; |
| 1743 | 1746 | ||
| 1744 | count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); | ||
| 1745 | dma_unmap_page(priv->rx_dma_dev, sg_addr, | ||
| 1746 | DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); | ||
| 1747 | if (!skb) { | 1747 | if (!skb) { |
| 1748 | sz = dpaa_bp->size + | 1748 | sz = dpaa_bp->size + |
| 1749 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | 1749 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
| @@ -1786,7 +1786,9 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, · 36 unmodified lines | |||
| 1786 | skb_add_rx_frag(skb, i - 1, head_page, frag_off, | 1786 | skb_add_rx_frag(skb, i - 1, head_page, frag_off, |
| 1787 | frag_len, dpaa_bp->size); | 1787 | frag_len, dpaa_bp->size); |
| 1788 | } | 1788 | } |
| 1789 | |||
| 1789 | /* Update the pool count for the current {cpu x bpool} */ | 1790 | /* Update the pool count for the current {cpu x bpool} */ |
| 1791 | count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); | ||
| 1790 | (*count_ptr)--; | 1792 | (*count_ptr)--; |
| 1791 | 1793 | ||
| 1792 | if (qm_sg_entry_is_final(&sgt[i])) | 1794 | if (qm_sg_entry_is_final(&sgt[i])) |
| @@ -1800,26 +1802,25 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, · 7 unmodified lines | |||
| 1800 | return skb; | 1802 | return skb; |
| 1801 | 1803 | ||
| 1802 | free_buffers: | 1804 | free_buffers: |
| 1803 | /* compensate sw bpool counter changes */ | ||
| 1804 | for (i--; i >= 0; i--) { | ||
| 1805 | dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); | ||
| 1806 | if (dpaa_bp) { | ||
| 1807 | count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); | ||
| 1808 | (*count_ptr)++; | ||
| 1809 | } | ||
| 1810 | } | ||
| 1811 | /* free all the SG entries */ | 1805 | /* free all the SG entries */ |
| 1812 | for (i = 0; i < DPAA_SGT_MAX_ENTRIES ; i++) { | 1806 | for (j = 0; j < DPAA_SGT_MAX_ENTRIES ; j++) { |
| 1813 | sg_addr = qm_sg_addr(&sgt[i]); | 1807 | sg_addr = qm_sg_addr(&sgt[j]); |
| 1814 | sg_vaddr = phys_to_virt(sg_addr); | 1808 | sg_vaddr = phys_to_virt(sg_addr); |
| 1809 | /* all pages 0..i were unmaped */ | ||
| 1810 | if (j > i) | ||
| 1811 | dma_unmap_page(priv->rx_dma_dev, qm_sg_addr(&sgt[j]), | ||
| 1812 | DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); | ||
| 1815 | free_pages((unsigned long)sg_vaddr, 0); | 1813 | free_pages((unsigned long)sg_vaddr, 0); |
| 1816 | dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); | 1814 | /* counters 0..i-1 were decremented */ |
| 1817 | if (dpaa_bp) { | 1815 | if (j >= i) { |
| 1818 | count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); | 1816 | dpaa_bp = dpaa_bpid2pool(sgt[j].bpid); |
| 1819 | (*count_ptr)--; | 1817 | if (dpaa_bp) { |
| 1818 | count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); | ||
| 1819 | (*count_ptr)--; | ||
| 1820 | } | ||
| 1820 | } | 1821 | } |
| 1821 | 1822 | ||
| 1822 | if (qm_sg_entry_is_final(&sgt[i])) | 1823 | if (qm_sg_entry_is_final(&sgt[j])) |
| 1823 | break; | 1824 | break; |
| 1824 | } | 1825 | } |
| 1825 | /* free the SGT fragment */ | 1826 | /* free the SGT fragment */ |
| @@ -2199,8 +2199,14 @@ static void fec_enet_get_regs(struct net_device *ndev, · 2198 unmodified lines | |||
| 2199 | { | 2199 | { |
| 2200 | struct fec_enet_private *fep = netdev_priv(ndev); | 2200 | struct fec_enet_private *fep = netdev_priv(ndev); |
| 2201 | u32 __iomem *theregs = (u32 __iomem *)fep->hwp; | 2201 | u32 __iomem *theregs = (u32 __iomem *)fep->hwp; |
| 2202 | struct device *dev = &fep->pdev->dev; | ||
| 2202 | u32 *buf = (u32 *)regbuf; | 2203 | u32 *buf = (u32 *)regbuf; |
| 2203 | u32 i, off; | 2204 | u32 i, off; |
| 2205 | int ret; | ||
| 2206 | |||
| 2207 | ret = pm_runtime_get_sync(dev); | ||
| 2208 | if (ret < 0) | ||
| 2209 | return; | ||
| 2204 | 2210 | ||
| 2205 | regs->version = fec_enet_register_version; | 2211 | regs->version = fec_enet_register_version; |
| 2206 | 2212 | ||
| @@ -2216,6 +2222,9 @@ static void fec_enet_get_regs(struct net_device *ndev, · 9 unmodified lines | |||
| 2216 | off >>= 2; | 2222 | off >>= 2; |
| 2217 | buf[off] = readl(&theregs[off]); | 2223 | buf[off] = readl(&theregs[off]); |
| 2218 | } | 2224 | } |
| 2225 | |||
| 2226 | pm_runtime_mark_last_busy(dev); | ||
| 2227 | pm_runtime_put_autosuspend(dev); | ||
| 2219 | } | 2228 | } |
| 2220 | 2229 | ||
| 2221 | static int fec_enet_get_ts_info(struct net_device *ndev, | 2230 | static int fec_enet_get_ts_info(struct net_device *ndev, |
| @@ -418,8 +418,6 @@ bool gve_clean_rx_done(struct gve_rx_ring *rx, int budget, · 417 unmodified lines | |||
| 418 | rx->cnt = cnt; | 418 | rx->cnt = cnt; |
| 419 | rx->fill_cnt += work_done; | 419 | rx->fill_cnt += work_done; |
| 420 | 420 | ||
| 421 | /* restock desc ring slots */ | ||
| 422 | dma_wmb(); /* Ensure descs are visible before ringing doorbell */ | ||
| 423 | gve_rx_write_doorbell(priv, rx); | 421 | gve_rx_write_doorbell(priv, rx); |
| 424 | return gve_rx_work_pending(rx); | 422 | return gve_rx_work_pending(rx); |
| 425 | } | 423 | } |
| @@ -487,10 +487,6 @@ netdev_tx_t gve_tx(struct sk_buff *skb, struct net_device *dev) · 486 unmodified lines | |||
| 487 | * may have added descriptors without ringing the doorbell. | 487 | * may have added descriptors without ringing the doorbell. |
| 488 | */ | 488 | */ |
| 489 | 489 | ||
| 490 | /* Ensure tx descs from a prior gve_tx are visible before | ||
| 491 | * ringing doorbell. | ||
| 492 | */ | ||
| 493 | dma_wmb(); | ||
| 494 | gve_tx_put_doorbell(priv, tx->q_resources, tx->req); | 490 | gve_tx_put_doorbell(priv, tx->q_resources, tx->req); |
| 495 | return NETDEV_TX_BUSY; | 491 | return NETDEV_TX_BUSY; |
| 496 | } | 492 | } |
| @@ -505,8 +501,6 @@ netdev_tx_t gve_tx(struct sk_buff *skb, struct net_device *dev) · 8 unmodified lines | |||
| 505 | if (!netif_xmit_stopped(tx->netdev_txq) && netdev_xmit_more()) | 501 | if (!netif_xmit_stopped(tx->netdev_txq) && netdev_xmit_more()) |
| 506 | return NETDEV_TX_OK; | 502 | return NETDEV_TX_OK; |
| 507 | 503 | ||
| 508 | /* Ensure tx descs are visible before ringing doorbell */ | ||
| 509 | dma_wmb(); | ||
| 510 | gve_tx_put_doorbell(priv, tx->q_resources, tx->req); | 504 | gve_tx_put_doorbell(priv, tx->q_resources, tx->req); |
| 511 | return NETDEV_TX_OK; | 505 | return NETDEV_TX_OK; |
| 512 | } | 506 | } |
| @@ -122,6 +122,22 @@ enum { · 121 unmodified lines | |||
| 122 | #endif | 122 | #endif |
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | #define MLX5E_TTC_NUM_GROUPS 3 | ||
| 126 | #define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT) | ||
| 127 | #define MLX5E_TTC_GROUP2_SIZE BIT(1) | ||
| 128 | #define MLX5E_TTC_GROUP3_SIZE BIT(0) | ||
| 129 | #define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\ | ||
| 130 | MLX5E_TTC_GROUP2_SIZE +\ | ||
| 131 | MLX5E_TTC_GROUP3_SIZE) | ||
| 132 | |||
| 133 | #define MLX5E_INNER_TTC_NUM_GROUPS 3 | ||
| 134 | #define MLX5E_INNER_TTC_GROUP1_SIZE BIT(3) | ||
| 135 | #define MLX5E_INNER_TTC_GROUP2_SIZE BIT(1) | ||
| 136 | #define MLX5E_INNER_TTC_GROUP3_SIZE BIT(0) | ||
| 137 | #define MLX5E_INNER_TTC_TABLE_SIZE (MLX5E_INNER_TTC_GROUP1_SIZE +\ | ||
| 138 | MLX5E_INNER_TTC_GROUP2_SIZE +\ | ||
| 139 | MLX5E_INNER_TTC_GROUP3_SIZE) | ||
| 140 | |||
| 125 | #ifdef CONFIG_MLX5_EN_RXNFC | 141 | #ifdef CONFIG_MLX5_EN_RXNFC |
| 126 | 142 | ||
| 127 | struct mlx5e_ethtool_table { | 143 | struct mlx5e_ethtool_table { |
| @@ -197,9 +197,10 @@ int mlx5e_health_report(struct mlx5e_priv *priv, · 196 unmodified lines | |||
| 197 | struct devlink_health_reporter *reporter, char *err_str, | 197 | struct devlink_health_reporter *reporter, char *err_str, |
| 198 | struct mlx5e_err_ctx *err_ctx) | 198 | struct mlx5e_err_ctx *err_ctx) |
| 199 | { | 199 | { |
| 200 | if (!reporter) { | 200 | netdev_err(priv->netdev, err_str); |
| 201 | netdev_err(priv->netdev, err_str); | 201 | |
| 202 | if (!reporter) | ||
| 202 | return err_ctx->recover(&err_ctx->ctx); | 203 | return err_ctx->recover(&err_ctx->ctx); |
| 203 | } | 204 | |
| 204 | return devlink_health_report(reporter, err_str, err_ctx); | 205 | return devlink_health_report(reporter, err_str, err_ctx); |
| 205 | } | 206 | } |
| @@ -904,22 +904,6 @@ del_rules: · 903 unmodified lines | |||
| 904 | return err; | 904 | return err; |
| 905 | } | 905 | } |
| 906 | 906 | ||
| 907 | #define MLX5E_TTC_NUM_GROUPS 3 | ||
| 908 | #define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT) | ||
| 909 | #define MLX5E_TTC_GROUP2_SIZE BIT(1) | ||
| 910 | #define MLX5E_TTC_GROUP3_SIZE BIT(0) | ||
| 911 | #define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\ | ||
| 912 | MLX5E_TTC_GROUP2_SIZE +\ | ||
| 913 | MLX5E_TTC_GROUP3_SIZE) | ||
| 914 | |||
| 915 | #define MLX5E_INNER_TTC_NUM_GROUPS 3 | ||
| 916 | #define MLX5E_INNER_TTC_GROUP1_SIZE BIT(3) | ||
| 917 | #define MLX5E_INNER_TTC_GROUP2_SIZE BIT(1) | ||
| 918 | #define MLX5E_INNER_TTC_GROUP3_SIZE BIT(0) | ||
| 919 | #define MLX5E_INNER_TTC_TABLE_SIZE (MLX5E_INNER_TTC_GROUP1_SIZE +\ | ||
| 920 | MLX5E_INNER_TTC_GROUP2_SIZE +\ | ||
| 921 | MLX5E_INNER_TTC_GROUP3_SIZE) | ||
| 922 | |||
| 923 | static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, | 907 | static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, |
| 924 | bool use_ipv) | 908 | bool use_ipv) |
| 925 | { | 909 | { |
| @@ -592,7 +592,7 @@ static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp, · 591 unmodified lines | |||
| 592 | for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) | 592 | for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) |
| 593 | ttc_params->indir_tirn[tt] = hp->indir_tirn[tt]; | 593 | ttc_params->indir_tirn[tt] = hp->indir_tirn[tt]; |
| 594 | 594 | ||
| 595 | ft_attr->max_fte = MLX5E_NUM_TT; | 595 | ft_attr->max_fte = MLX5E_TTC_TABLE_SIZE; |
| 596 | ft_attr->level = MLX5E_TC_TTC_FT_LEVEL; | 596 | ft_attr->level = MLX5E_TC_TTC_FT_LEVEL; |
| 597 | ft_attr->prio = MLX5E_TC_PRIO; | 597 | ft_attr->prio = MLX5E_TC_PRIO; |
| 598 | } | 598 | } |
| @@ -2999,6 +2999,25 @@ static struct ip_tunnel_info *dup_tun_info(const struct ip_tunnel_info *tun_info · 2400 unmodified lines | |||
| 2999 | return kmemdup(tun_info, tun_size, GFP_KERNEL); | 2999 | return kmemdup(tun_info, tun_size, GFP_KERNEL); |
| 3000 | } | 3000 | } |
| 3001 | 3001 | ||
| 3002 | static bool is_duplicated_encap_entry(struct mlx5e_priv *priv, | ||
| 3003 | struct mlx5e_tc_flow *flow, | ||
| 3004 | int out_index, | ||
| 3005 | struct mlx5e_encap_entry *e, | ||
| 3006 | struct netlink_ext_ack *extack) | ||
| 3007 | { | ||
| 3008 | int i; | ||
| 3009 | |||
| 3010 | for (i = 0; i < out_index; i++) { | ||
| 3011 | if (flow->encaps[i].e != e) | ||
| 3012 | continue; | ||
| 3013 | NL_SET_ERR_MSG_MOD(extack, "can't duplicate encap action"); | ||
| 3014 | netdev_err(priv->netdev, "can't duplicate encap action\n"); | ||
| 3015 | return true; | ||
| 3016 | } | ||
| 3017 | |||
| 3018 | return false; | ||
| 3019 | } | ||
| 3020 | |||
| 3002 | static int mlx5e_attach_encap(struct mlx5e_priv *priv, | 3021 | static int mlx5e_attach_encap(struct mlx5e_priv *priv, |
| 3003 | struct mlx5e_tc_flow *flow, | 3022 | struct mlx5e_tc_flow *flow, |
| 3004 | struct net_device *mirred_dev, | 3023 | struct net_device *mirred_dev, |
| @@ -3034,6 +3053,12 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, · 29 unmodified lines | |||
| 3034 | 3053 | ||
| 3035 | /* must verify if encap is valid or not */ | 3054 | /* must verify if encap is valid or not */ |
| 3036 | if (e) { | 3055 | if (e) { |
| 3056 | /* Check that entry was not already attached to this flow */ | ||
| 3057 | if (is_duplicated_encap_entry(priv, flow, out_index, e, extack)) { | ||
| 3058 | err = -EOPNOTSUPP; | ||
| 3059 | goto out_err; | ||
| 3060 | } | ||
| 3061 | |||
| 3037 | mutex_unlock(&esw->offloads.encap_tbl_lock); | 3062 | mutex_unlock(&esw->offloads.encap_tbl_lock); |
| 3038 | wait_for_completion(&e->res_ready); | 3063 | wait_for_completion(&e->res_ready); |
| 3039 | 3064 | ||
| @@ -3220,6 +3245,26 @@ bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv, · 180 unmodified lines | |||
| 3220 | same_hw_devs(priv, netdev_priv(out_dev)); | 3245 | same_hw_devs(priv, netdev_priv(out_dev)); |
| 3221 | } | 3246 | } |
| 3222 | 3247 | ||
| 3248 | static bool is_duplicated_output_device(struct net_device *dev, | ||
| 3249 | struct net_device *out_dev, | ||
| 3250 | int *ifindexes, int if_count, | ||
| 3251 | struct netlink_ext_ack *extack) | ||
| 3252 | { | ||
| 3253 | int i; | ||
| 3254 | |||
| 3255 | for (i = 0; i < if_count; i++) { | ||
| 3256 | if (ifindexes[i] == out_dev->ifindex) { | ||
| 3257 | NL_SET_ERR_MSG_MOD(extack, | ||
| 3258 | "can't duplicate output to same device"); | ||
| 3259 | netdev_err(dev, "can't duplicate output to same device: %s\n", | ||
| 3260 | out_dev->name); | ||
| 3261 | return true; | ||
| 3262 | } | ||
| 3263 | } | ||
| 3264 | |||
| 3265 | return false; | ||
| 3266 | } | ||
| 3267 | |||
| 3223 | static int parse_tc_fdb_actions(struct mlx5e_priv *priv, | 3268 | static int parse_tc_fdb_actions(struct mlx5e_priv *priv, |
| 3224 | struct flow_action *flow_action, | 3269 | struct flow_action *flow_action, |
| 3225 | struct mlx5e_tc_flow *flow, | 3270 | struct mlx5e_tc_flow *flow, |
| @@ -3231,11 +3276,12 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, · 5 unmodified lines | |||
| 3231 | struct mlx5e_tc_flow_parse_attr *parse_attr = attr->parse_attr; | 3276 | struct mlx5e_tc_flow_parse_attr *parse_attr = attr->parse_attr; |
| 3232 | struct mlx5e_rep_priv *rpriv = priv->ppriv; | 3277 | struct mlx5e_rep_priv *rpriv = priv->ppriv; |
| 3233 | const struct ip_tunnel_info *info = NULL; | 3278 | const struct ip_tunnel_info *info = NULL; |
| 3279 | int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS]; | ||
| 3234 | bool ft_flow = mlx5e_is_ft_flow(flow); | 3280 | bool ft_flow = mlx5e_is_ft_flow(flow); |
| 3235 | const struct flow_action_entry *act; | 3281 | const struct flow_action_entry *act; |
| 3282 | int err, i, if_count = 0; | ||
| 3236 | bool encap = false; | 3283 | bool encap = false; |
| 3237 | u32 action = 0; | 3284 | u32 action = 0; |
| 3238 | int err, i; | ||
| 3239 | 3285 | ||
| 3240 | if (!flow_action_has_entries(flow_action)) | 3286 | if (!flow_action_has_entries(flow_action)) |
| 3241 | return -EINVAL; | 3287 | return -EINVAL; |
| @@ -3312,6 +3358,16 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, · 70 unmodified lines | |||
| 3312 | struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH); | 3358 | struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH); |
| 3313 | struct net_device *uplink_upper; | 3359 | struct net_device *uplink_upper; |
| 3314 | 3360 | ||
| 3361 | if (is_duplicated_output_device(priv->netdev, | ||
| 3362 | out_dev, | ||
| 3363 | ifindexes, | ||
| 3364 | if_count, | ||
| 3365 | extack)) | ||
| 3366 | return -EOPNOTSUPP; | ||
| 3367 | |||
| 3368 | ifindexes[if_count] = out_dev->ifindex; | ||
| 3369 | if_count++; | ||
| 3370 | |||
| 3315 | rcu_read_lock(); | 3371 | rcu_read_lock(); |
| 3316 | uplink_upper = | 3372 | uplink_upper = |
| 3317 | netdev_master_upper_dev_get_rcu(uplink_dev); | 3373 | netdev_master_upper_dev_get_rcu(uplink_dev); |
| @@ -531,16 +531,9 @@ static void del_hw_fte(struct fs_node *node) · 530 unmodified lines | |||
| 531 | } | 531 | } |
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | static void del_sw_fte_rcu(struct rcu_head *head) | ||
| 535 | { | ||
| 536 | struct fs_fte *fte = container_of(head, struct fs_fte, rcu); | ||
| 537 | struct mlx5_flow_steering *steering = get_steering(&fte->node); | ||
| 538 | |||
| 539 | kmem_cache_free(steering->ftes_cache, fte); | ||
| 540 | } | ||
| 541 | |||
| 542 | static void del_sw_fte(struct fs_node *node) | 534 | static void del_sw_fte(struct fs_node *node) |
| 543 | { | 535 | { |
| 536 | struct mlx5_flow_steering *steering = get_steering(node); | ||
| 544 | struct mlx5_flow_group *fg; | 537 | struct mlx5_flow_group *fg; |
| 545 | struct fs_fte *fte; | 538 | struct fs_fte *fte; |
| 546 | int err; | 539 | int err; |
| @@ -553,8 +546,7 @@ static void del_sw_fte(struct fs_node *node) · 6 unmodified lines | |||
| 553 | rhash_fte); | 546 | rhash_fte); |
| 554 | WARN_ON(err); | 547 | WARN_ON(err); |
| 555 | ida_simple_remove(&fg->fte_allocator, fte->index - fg->start_index); | 548 | ida_simple_remove(&fg->fte_allocator, fte->index - fg->start_index); |
| 556 | 549 | kmem_cache_free(steering->ftes_cache, fte); | |
| 557 | call_rcu(&fte->rcu, del_sw_fte_rcu); | ||
| 558 | } | 550 | } |
| 559 | 551 | ||
| 560 | static void del_hw_flow_group(struct fs_node *node) | 552 | static void del_hw_flow_group(struct fs_node *node) |
| @@ -1633,47 +1625,22 @@ static u64 matched_fgs_get_version(struct list_head *match_head) · 1072 unmodified lines | |||
| 1633 | } | 1625 | } |
| 1634 | 1626 | ||
| 1635 | static struct fs_fte * | 1627 | static struct fs_fte * |
| 1636 | lookup_fte_for_write_locked(struct mlx5_flow_group *g, const u32 *match_value) | 1628 | lookup_fte_locked(struct mlx5_flow_group *g, |
| 1629 | const u32 *match_value, | ||
| 1630 | bool take_write) | ||
| 1637 | { | 1631 | { |
| 1638 | struct fs_fte *fte_tmp; | 1632 | struct fs_fte *fte_tmp; |
| 1639 | 1633 | ||
| 1640 | nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); | 1634 | if (take_write) |
| 1641 | 1635 | nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); | |
| 1642 | fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value, rhash_fte); | 1636 | else |
| 1643 | if (!fte_tmp || !tree_get_node(&fte_tmp->node)) { | 1637 | nested_down_read_ref_node(&g->node, FS_LOCK_PARENT); |
| 1644 | fte_tmp = NULL; | 1638 | fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value, |
| 1645 | goto out; | 1639 | rhash_fte); |
| 1646 | } | ||
| 1647 | |||
| 1648 | if (!fte_tmp->node.active) { | ||
| 1649 | tree_put_node(&fte_tmp->node, false); | ||
| 1650 | fte_tmp = NULL; | ||
| 1651 | goto out; | ||
| 1652 | } | ||
| 1653 | nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); | ||
| 1654 | |||
| 1655 | out: | ||
| 1656 | up_write_ref_node(&g->node, false); | ||
| 1657 | return fte_tmp; | ||
| 1658 | } | ||
| 1659 | |||
| 1660 | static struct fs_fte * | ||
| 1661 | lookup_fte_for_read_locked(struct mlx5_flow_group *g, const u32 *match_value) | ||
| 1662 | { | ||
| 1663 | struct fs_fte *fte_tmp; | ||
| 1664 | |||
| 1665 | if (!tree_get_node(&g->node)) | ||
| 1666 | return NULL; | ||
| 1667 | |||
| 1668 | rcu_read_lock(); | ||
| 1669 | fte_tmp = rhashtable_lookup(&g->ftes_hash, match_value, rhash_fte); | ||
| 1670 | if (!fte_tmp || !tree_get_node(&fte_tmp->node)) { | 1640 | if (!fte_tmp || !tree_get_node(&fte_tmp->node)) { |
| 1671 | rcu_read_unlock(); | ||
| 1672 | fte_tmp = NULL; | 1641 | fte_tmp = NULL; |
| 1673 | goto out; | 1642 | goto out; |
| 1674 | } | 1643 | } |
| 1675 | rcu_read_unlock(); | ||
| 1676 | |||
| 1677 | if (!fte_tmp->node.active) { | 1644 | if (!fte_tmp->node.active) { |
| 1678 | tree_put_node(&fte_tmp->node, false); | 1645 | tree_put_node(&fte_tmp->node, false); |
| 1679 | fte_tmp = NULL; | 1646 | fte_tmp = NULL; |
| @@ -1681,19 +1648,12 @@ lookup_fte_for_read_locked(struct mlx5_flow_group *g, const u32 *match_value) · 1 unmodified line | |||
| 1681 | } | 1648 | } |
| 1682 | 1649 | ||
| 1683 | nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); | 1650 | nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); |
| 1684 | |||
| 1685 | out: | 1651 | out: |
| 1686 | tree_put_node(&g->node, false); | 1652 | if (take_write) |
| 1687 | return fte_tmp; | 1653 | up_write_ref_node(&g->node, false); |
| 1688 | } | ||
| 1689 | |||
| 1690 | static struct fs_fte * | ||
| 1691 | lookup_fte_locked(struct mlx5_flow_group *g, const u32 *match_value, bool write) | ||
| 1692 | { | ||
| 1693 | if (write) | ||
| 1694 | return lookup_fte_for_write_locked(g, match_value); | ||
| 1695 | else | 1654 | else |
| 1696 | return lookup_fte_for_read_locked(g, match_value); | 1655 | up_read_ref_node(&g->node); |
| 1656 | return fte_tmp; | ||
| 1697 | } | 1657 | } |
| 1698 | 1658 | ||
| 1699 | static struct mlx5_flow_handle * | 1659 | static struct mlx5_flow_handle * |
| @@ -203,7 +203,6 @@ struct fs_fte { · 202 unmodified lines | |||
| 203 | enum fs_fte_status status; | 203 | enum fs_fte_status status; |
| 204 | struct mlx5_fc *counter; | 204 | struct mlx5_fc *counter; |
| 205 | struct rhash_head hash; | 205 | struct rhash_head hash; |
| 206 | struct rcu_head rcu; | ||
| 207 | int modify_mask; | 206 | int modify_mask; |
| 208 | }; | 207 | }; |
| 209 | 208 | ||
| @@ -1193,6 +1193,12 @@ int mlx5_load_one(struct mlx5_core_dev *dev, bool boot) · 1192 unmodified lines | |||
| 1193 | if (err) | 1193 | if (err) |
| 1194 | goto err_load; | 1194 | goto err_load; |
| 1195 | 1195 | ||
| 1196 | if (boot) { | ||
| 1197 | err = mlx5_devlink_register(priv_to_devlink(dev), dev->device); | ||
| 1198 | if (err) | ||
| 1199 | goto err_devlink_reg; | ||
| 1200 | } | ||
| 1201 | |||
| 1196 | if (mlx5_device_registered(dev)) { | 1202 | if (mlx5_device_registered(dev)) { |
| 1197 | mlx5_attach_device(dev); | 1203 | mlx5_attach_device(dev); |
| 1198 | } else { | 1204 | } else { |
| @@ -1210,6 +1216,9 @@ out: · 11 unmodified lines | |||
| 1210 | return err; | 1216 | return err; |
| 1211 | 1217 | ||
| 1212 | err_reg_dev: | 1218 | err_reg_dev: |
| 1219 | if (boot) | ||
| 1220 | mlx5_devlink_unregister(priv_to_devlink(dev)); | ||
| 1221 | err_devlink_reg: | ||
| 1213 | mlx5_unload(dev); | 1222 | mlx5_unload(dev); |
| 1214 | err_load: | 1223 | err_load: |
| 1215 | if (boot) | 1224 | if (boot) |
| @@ -1347,10 +1356,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *id) · 131 unmodified lines | |||
| 1347 | 1356 | ||
| 1348 | request_module_nowait(MLX5_IB_MOD); | 1357 | request_module_nowait(MLX5_IB_MOD); |
| 1349 | 1358 | ||
| 1350 | err = mlx5_devlink_register(devlink, &pdev->dev); | ||
| 1351 | if (err) | ||
| 1352 | goto clean_load; | ||
| 1353 | |||
| 1354 | err = mlx5_crdump_enable(dev); | 1359 | err = mlx5_crdump_enable(dev); |
| 1355 | if (err) | 1360 | if (err) |
| 1356 | dev_err(&pdev->dev, "mlx5_crdump_enable failed with error code %d\n", err); | 1361 | dev_err(&pdev->dev, "mlx5_crdump_enable failed with error code %d\n", err); |
| @@ -1358,9 +1363,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *id) · 1 unmodified line | |||
| 1358 | pci_save_state(pdev); | 1363 | pci_save_state(pdev); |
| 1359 | return 0; | 1364 | return 0; |
| 1360 | 1365 | ||
| 1361 | clean_load: | ||
| 1362 | mlx5_unload_one(dev, true); | ||
| 1363 | |||
| 1364 | err_load_one: | 1366 | err_load_one: |
| 1365 | mlx5_pci_close(dev); | 1367 | mlx5_pci_close(dev); |
| 1366 | pci_init_err: | 1368 | pci_init_err: |
| @@ -209,7 +209,7 @@ static void dr_rule_rehash_copy_ste_ctrl(struct mlx5dr_matcher *matcher, · 208 unmodified lines | |||
| 209 | /* We need to copy the refcount since this ste | 209 | /* We need to copy the refcount since this ste |
| 210 | * may have been traversed several times | 210 | * may have been traversed several times |
| 211 | */ | 211 | */ |
| 212 | refcount_set(&new_ste->refcount, refcount_read(&cur_ste->refcount)); | 212 | new_ste->refcount = cur_ste->refcount; |
| 213 | 213 | ||
| 214 | /* Link old STEs rule_mem list to the new ste */ | 214 | /* Link old STEs rule_mem list to the new ste */ |
| 215 | mlx5dr_rule_update_rule_member(cur_ste, new_ste); | 215 | mlx5dr_rule_update_rule_member(cur_ste, new_ste); |
| @@ -638,6 +638,9 @@ static int dr_rule_add_member(struct mlx5dr_rule_rx_tx *nic_rule, · 422 unmodified lines | |||
| 638 | if (!rule_mem) | 638 | if (!rule_mem) |
| 639 | return -ENOMEM; | 639 | return -ENOMEM; |
| 640 | 640 | ||
| 641 | INIT_LIST_HEAD(&rule_mem->list); | ||
| 642 | INIT_LIST_HEAD(&rule_mem->use_ste_list); | ||
| 643 | |||
| 641 | rule_mem->ste = ste; | 644 | rule_mem->ste = ste; |
| 642 | list_add_tail(&rule_mem->list, &nic_rule->rule_members_list); | 645 | list_add_tail(&rule_mem->list, &nic_rule->rule_members_list); |
| 643 | 646 | ||
| @@ -348,7 +348,7 @@ static void dr_ste_replace(struct mlx5dr_ste *dst, struct mlx5dr_ste *src) · 347 unmodified lines | |||
| 348 | if (dst->next_htbl) | 348 | if (dst->next_htbl) |
| 349 | dst->next_htbl->pointing_ste = dst; | 349 | dst->next_htbl->pointing_ste = dst; |
| 350 | 350 | ||
| 351 | refcount_set(&dst->refcount, refcount_read(&src->refcount)); | 351 | dst->refcount = src->refcount; |
| 352 | 352 | ||
| 353 | INIT_LIST_HEAD(&dst->rule_list); | 353 | INIT_LIST_HEAD(&dst->rule_list); |
| 354 | list_splice_tail_init(&src->rule_list, &dst->rule_list); | 354 | list_splice_tail_init(&src->rule_list, &dst->rule_list); |
| @@ -565,7 +565,7 @@ bool mlx5dr_ste_is_not_valid_entry(u8 *p_hw_ste) · 210 unmodified lines | |||
| 565 | 565 | ||
| 566 | bool mlx5dr_ste_not_used_ste(struct mlx5dr_ste *ste) | 566 | bool mlx5dr_ste_not_used_ste(struct mlx5dr_ste *ste) |
| 567 | { | 567 | { |
| 568 | return !refcount_read(&ste->refcount); | 568 | return !ste->refcount; |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | /* Init one ste as a pattern for ste data array */ | 571 | /* Init one ste as a pattern for ste data array */ |
| @@ -689,14 +689,14 @@ struct mlx5dr_ste_htbl *mlx5dr_ste_htbl_alloc(struct mlx5dr_icm_pool *pool, · 117 unmodified lines | |||
| 689 | htbl->ste_arr = chunk->ste_arr; | 689 | htbl->ste_arr = chunk->ste_arr; |
| 690 | htbl->hw_ste_arr = chunk->hw_ste_arr; | 690 | htbl->hw_ste_arr = chunk->hw_ste_arr; |
| 691 | htbl->miss_list = chunk->miss_list; | 691 | htbl->miss_list = chunk->miss_list; |
| 692 | refcount_set(&htbl->refcount, 0); | 692 | htbl->refcount = 0; |
| 693 | 693 | ||
| 694 | for (i = 0; i < chunk->num_of_entries; i++) { | 694 | for (i = 0; i < chunk->num_of_entries; i++) { |
| 695 | struct mlx5dr_ste *ste = &htbl->ste_arr[i]; | 695 | struct mlx5dr_ste *ste = &htbl->ste_arr[i]; |
| 696 | 696 | ||
| 697 | ste->hw_ste = htbl->hw_ste_arr + i * DR_STE_SIZE_REDUCED; | 697 | ste->hw_ste = htbl->hw_ste_arr + i * DR_STE_SIZE_REDUCED; |
| 698 | ste->htbl = htbl; | 698 | ste->htbl = htbl; |
| 699 | refcount_set(&ste->refcount, 0); | 699 | ste->refcount = 0; |
| 700 | INIT_LIST_HEAD(&ste->miss_list_node); | 700 | INIT_LIST_HEAD(&ste->miss_list_node); |
| 701 | INIT_LIST_HEAD(&htbl->miss_list[i]); | 701 | INIT_LIST_HEAD(&htbl->miss_list[i]); |
| 702 | INIT_LIST_HEAD(&ste->rule_list); | 702 | INIT_LIST_HEAD(&ste->rule_list); |
| @@ -713,7 +713,7 @@ out_free_htbl: · 10 unmodified lines | |||
| 713 | 713 | ||
| 714 | int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl) | 714 | int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl) |
| 715 | { | 715 | { |
| 716 | if (refcount_read(&htbl->refcount)) | 716 | if (htbl->refcount) |
| 717 | return -EBUSY; | 717 | return -EBUSY; |
| 718 | 718 | ||
| 719 | mlx5dr_icm_free_chunk(htbl->chunk); | 719 | mlx5dr_icm_free_chunk(htbl->chunk); |
| @@ -123,7 +123,7 @@ struct mlx5dr_matcher_rx_tx; · 122 unmodified lines | |||
| 123 | struct mlx5dr_ste { | 123 | struct mlx5dr_ste { |
| 124 | u8 *hw_ste; | 124 | u8 *hw_ste; |
| 125 | /* refcount: indicates the num of rules that using this ste */ | 125 | /* refcount: indicates the num of rules that using this ste */ |
| 126 | refcount_t refcount; | 126 | u32 refcount; |
| 127 | 127 | ||
| 128 | /* attached to the miss_list head at each htbl entry */ | 128 | /* attached to the miss_list head at each htbl entry */ |
| 129 | struct list_head miss_list_node; | 129 | struct list_head miss_list_node; |
| @@ -155,7 +155,7 @@ struct mlx5dr_ste_htbl_ctrl { · 25 unmodified lines | |||
| 155 | struct mlx5dr_ste_htbl { | 155 | struct mlx5dr_ste_htbl { |
| 156 | u8 lu_type; | 156 | u8 lu_type; |
| 157 | u16 byte_mask; | 157 | u16 byte_mask; |
| 158 | refcount_t refcount; | 158 | u32 refcount; |
| 159 | struct mlx5dr_icm_chunk *chunk; | 159 | struct mlx5dr_icm_chunk *chunk; |
| 160 | struct mlx5dr_ste *ste_arr; | 160 | struct mlx5dr_ste *ste_arr; |
| 161 | u8 *hw_ste_arr; | 161 | u8 *hw_ste_arr; |
| @@ -206,13 +206,14 @@ int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl); · 44 unmodified lines | |||
| 206 | 206 | ||
| 207 | static inline void mlx5dr_htbl_put(struct mlx5dr_ste_htbl *htbl) | 207 | static inline void mlx5dr_htbl_put(struct mlx5dr_ste_htbl *htbl) |
| 208 | { | 208 | { |
| 209 | if (refcount_dec_and_test(&htbl->refcount)) | 209 | htbl->refcount--; |
| 210 | if (!htbl->refcount) | ||
| 210 | mlx5dr_ste_htbl_free(htbl); | 211 | mlx5dr_ste_htbl_free(htbl); |
| 211 | } | 212 | } |
| 212 | 213 | ||
| 213 | static inline void mlx5dr_htbl_get(struct mlx5dr_ste_htbl *htbl) | 214 | static inline void mlx5dr_htbl_get(struct mlx5dr_ste_htbl *htbl) |
| 214 | { | 215 | { |
| 215 | refcount_inc(&htbl->refcount); | 216 | htbl->refcount++; |
| 216 | } | 217 | } |
| 217 | 218 | ||
| 218 | /* STE utils */ | 219 | /* STE utils */ |
| @@ -254,14 +255,15 @@ static inline void mlx5dr_ste_put(struct mlx5dr_ste *ste, · 35 unmodified lines | |||
| 254 | struct mlx5dr_matcher *matcher, | 255 | struct mlx5dr_matcher *matcher, |
| 255 | struct mlx5dr_matcher_rx_tx *nic_matcher) | 256 | struct mlx5dr_matcher_rx_tx *nic_matcher) |
| 256 | { | 257 | { |
| 257 | if (refcount_dec_and_test(&ste->refcount)) | 258 | ste->refcount--; |
| 259 | if (!ste->refcount) | ||
| 258 | mlx5dr_ste_free(ste, matcher, nic_matcher); | 260 | mlx5dr_ste_free(ste, matcher, nic_matcher); |
| 259 | } | 261 | } |
| 260 | 262 | ||
| 261 | /* initial as 0, increased only when ste appears in a new rule */ | 263 | /* initial as 0, increased only when ste appears in a new rule */ |
| 262 | static inline void mlx5dr_ste_get(struct mlx5dr_ste *ste) | 264 | static inline void mlx5dr_ste_get(struct mlx5dr_ste *ste) |
| 263 | { | 265 | { |
| 264 | refcount_inc(&ste->refcount); | 266 | ste->refcount++; |
| 265 | } | 267 | } |
| 266 | 268 | ||
| 267 | void mlx5dr_ste_set_hit_addr_by_next_htbl(u8 *hw_ste, | 269 | void mlx5dr_ste_set_hit_addr_by_next_htbl(u8 *hw_ste, |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | #include <linux/netlink.h> | 8 | #include <linux/netlink.h> |
| 9 | #include <linux/vmalloc.h> | ||
| 9 | #include <linux/xz.h> | 10 | #include <linux/xz.h> |
| 10 | #include "mlxfw_mfa2.h" | 11 | #include "mlxfw_mfa2.h" |
| 11 | #include "mlxfw_mfa2_file.h" | 12 | #include "mlxfw_mfa2_file.h" |
| @@ -548,7 +549,7 @@ mlxfw_mfa2_file_component_get(const struct mlxfw_mfa2_file *mfa2_file, · 536 unmodified lines | |||
| 548 | comp_size = be32_to_cpu(comp->size); | 549 | comp_size = be32_to_cpu(comp->size); |
| 549 | comp_buf_size = comp_size + mlxfw_mfa2_comp_magic_len; | 550 | comp_buf_size = comp_size + mlxfw_mfa2_comp_magic_len; |
| 550 | 551 | ||
| 551 | comp_data = kmalloc(sizeof(*comp_data) + comp_buf_size, GFP_KERNEL); | 552 | comp_data = vzalloc(sizeof(*comp_data) + comp_buf_size); |
| 552 | if (!comp_data) | 553 | if (!comp_data) |
| 553 | return ERR_PTR(-ENOMEM); | 554 | return ERR_PTR(-ENOMEM); |
| 554 | comp_data->comp.data_size = comp_size; | 555 | comp_data->comp.data_size = comp_size; |
| @@ -570,7 +571,7 @@ mlxfw_mfa2_file_component_get(const struct mlxfw_mfa2_file *mfa2_file, · 15 unmodified lines | |||
| 570 | comp_data->comp.data = comp_data->buff + mlxfw_mfa2_comp_magic_len; | 571 | comp_data->comp.data = comp_data->buff + mlxfw_mfa2_comp_magic_len; |
| 571 | return &comp_data->comp; | 572 | return &comp_data->comp; |
| 572 | err_out: | 573 | err_out: |
| 573 | kfree(comp_data); | 574 | vfree(comp_data); |
| 574 | return ERR_PTR(err); | 575 | return ERR_PTR(err); |
| 575 | } | 576 | } |
| 576 | 577 | ||
| @@ -579,7 +580,7 @@ void mlxfw_mfa2_file_component_put(struct mlxfw_mfa2_component *comp) · 2 unmodified lines | |||
| 579 | const struct mlxfw_mfa2_comp_data *comp_data; | 580 | const struct mlxfw_mfa2_comp_data *comp_data; |
| 580 | 581 | ||
| 581 | comp_data = container_of(comp, struct mlxfw_mfa2_comp_data, comp); | 582 | comp_data = container_of(comp, struct mlxfw_mfa2_comp_data, comp); |
| 582 | kfree(comp_data); | 583 | vfree(comp_data); |
| 583 | } | 584 | } |
| 584 | 585 | ||
| 585 | void mlxfw_mfa2_file_fini(struct mlxfw_mfa2_file *mfa2_file) | 586 | void mlxfw_mfa2_file_fini(struct mlxfw_mfa2_file *mfa2_file) |
| @@ -5472,6 +5472,7 @@ enum mlxsw_reg_htgt_trap_group { · 5471 unmodified lines | |||
| 5472 | MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR, | 5472 | MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR, |
| 5473 | MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0, | 5473 | MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0, |
| 5474 | MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1, | 5474 | MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1, |
| 5475 | MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP, | ||
| 5475 | 5476 | ||
| 5476 | __MLXSW_REG_HTGT_TRAP_GROUP_MAX, | 5477 | __MLXSW_REG_HTGT_TRAP_GROUP_MAX, |
| 5477 | MLXSW_REG_HTGT_TRAP_GROUP_MAX = __MLXSW_REG_HTGT_TRAP_GROUP_MAX - 1 | 5478 | MLXSW_REG_HTGT_TRAP_GROUP_MAX = __MLXSW_REG_HTGT_TRAP_GROUP_MAX - 1 |
| @@ -4542,8 +4542,8 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = { · 4541 unmodified lines | |||
| 4542 | MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false), | 4542 | MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false), |
| 4543 | MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false), | 4543 | MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false), |
| 4544 | MLXSW_SP_RXL_MARK(DECAP_ECN0, TRAP_TO_CPU, ROUTER_EXP, false), | 4544 | MLXSW_SP_RXL_MARK(DECAP_ECN0, TRAP_TO_CPU, ROUTER_EXP, false), |
| 4545 | MLXSW_SP_RXL_MARK(IPV4_VRRP, TRAP_TO_CPU, ROUTER_EXP, false), | 4545 | MLXSW_SP_RXL_MARK(IPV4_VRRP, TRAP_TO_CPU, VRRP, false), |
| 4546 | MLXSW_SP_RXL_MARK(IPV6_VRRP, TRAP_TO_CPU, ROUTER_EXP, false), | 4546 | MLXSW_SP_RXL_MARK(IPV6_VRRP, TRAP_TO_CPU, VRRP, false), |
| 4547 | /* PKT Sample trap */ | 4547 | /* PKT Sample trap */ |
| 4548 | MLXSW_RXL(mlxsw_sp_rx_listener_sample_func, PKT_SAMPLE, MIRROR_TO_CPU, | 4548 | MLXSW_RXL(mlxsw_sp_rx_listener_sample_func, PKT_SAMPLE, MIRROR_TO_CPU, |
| 4549 | false, SP_IP2ME, DISCARD), | 4549 | false, SP_IP2ME, DISCARD), |
| @@ -4626,6 +4626,10 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core) · 76 unmodified lines | |||
| 4626 | rate = 19 * 1024; | 4626 | rate = 19 * 1024; |
| 4627 | burst_size = 12; | 4627 | burst_size = 12; |
| 4628 | break; | 4628 | break; |
| 4629 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP: | ||
| 4630 | rate = 360; | ||
| 4631 | burst_size = 7; | ||
| 4632 | break; | ||
| 4629 | default: | 4633 | default: |
| 4630 | continue; | 4634 | continue; |
| 4631 | } | 4635 | } |
| @@ -4665,6 +4669,7 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core) · 33 unmodified lines | |||
| 4665 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF: | 4669 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF: |
| 4666 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM: | 4670 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM: |
| 4667 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0: | 4671 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0: |
| 4672 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP: | ||
| 4668 | priority = 5; | 4673 | priority = 5; |
| 4669 | tc = 5; | 4674 | tc = 5; |
| 4670 | break; | 4675 | break; |
| @@ -651,6 +651,13 @@ mlxsw_sp_qdisc_prio_graft(struct mlxsw_sp_port *mlxsw_sp_port, · 650 unmodified lines | |||
| 651 | mlxsw_sp_port->tclass_qdiscs[tclass_num].handle == p->child_handle) | 651 | mlxsw_sp_port->tclass_qdiscs[tclass_num].handle == p->child_handle) |
| 652 | return 0; | 652 | return 0; |
| 653 | 653 | ||
| 654 | if (!p->child_handle) { | ||
| 655 | /* This is an invisible FIFO replacing the original Qdisc. | ||
| 656 | * Ignore it--the original Qdisc's destroy will follow. | ||
| 657 | */ | ||
| 658 | return 0; | ||
| 659 | } | ||
| 660 | |||
| 654 | /* See if the grafted qdisc is already offloaded on any tclass. If so, | 661 | /* See if the grafted qdisc is already offloaded on any tclass. If so, |
| 655 | * unoffload it. | 662 | * unoffload it. |
| 656 | */ | 663 | */ |
| @@ -7079,6 +7079,9 @@ static int mlxsw_sp_router_port_check_rif_addr(struct mlxsw_sp *mlxsw_sp, · 7078 unmodified lines | |||
| 7079 | 7079 | ||
| 7080 | for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) { | 7080 | for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) { |
| 7081 | rif = mlxsw_sp->router->rifs[i]; | 7081 | rif = mlxsw_sp->router->rifs[i]; |
| 7082 | if (rif && rif->ops && | ||
| 7083 | rif->ops->type == MLXSW_SP_RIF_TYPE_IPIP_LB) | ||
| 7084 | continue; | ||
| 7082 | if (rif && rif->dev && rif->dev != dev && | 7085 | if (rif && rif->dev && rif->dev != dev && |
| 7083 | !ether_addr_equal_masked(rif->dev->dev_addr, dev_addr, | 7086 | !ether_addr_equal_masked(rif->dev->dev_addr, dev_addr, |
| 7084 | mlxsw_sp->mac_mask)) { | 7087 | mlxsw_sp->mac_mask)) { |
| @@ -2296,7 +2296,7 @@ __setup("sxgbeeth=", sxgbe_cmdline_opt); · 2295 unmodified lines | |||
| 2296 | 2296 | ||
| 2297 | 2297 | ||
| 2298 | 2298 | ||
| 2299 | MODULE_DESCRIPTION("SAMSUNG 10G/2.5G/1G Ethernet PLATFORM driver"); | 2299 | MODULE_DESCRIPTION("Samsung 10G/2.5G/1G Ethernet PLATFORM driver"); |
| 2300 | 2300 | ||
| 2301 | MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)"); | 2301 | MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)"); |
| 2302 | MODULE_PARM_DESC(eee_timer, "EEE-LPI Default LS timer value"); | 2302 | MODULE_PARM_DESC(eee_timer, "EEE-LPI Default LS timer value"); |
| @@ -112,6 +112,14 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) · 111 unmodified lines | |||
| 112 | struct device *dev = dwmac->dev; | 112 | struct device *dev = dwmac->dev; |
| 113 | const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS]; | 113 | const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS]; |
| 114 | struct meson8b_dwmac_clk_configs *clk_configs; | 114 | struct meson8b_dwmac_clk_configs *clk_configs; |
| 115 | static const struct clk_div_table div_table[] = { | ||
| 116 | { .div = 2, .val = 2, }, | ||
| 117 | { .div = 3, .val = 3, }, | ||
| 118 | { .div = 4, .val = 4, }, | ||
| 119 | { .div = 5, .val = 5, }, | ||
| 120 | { .div = 6, .val = 6, }, | ||
| 121 | { .div = 7, .val = 7, }, | ||
| 122 | }; | ||
| 115 | 123 | ||
| 116 | clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL); | 124 | clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL); |
| 117 | if (!clk_configs) | 125 | if (!clk_configs) |
| @@ -146,9 +154,9 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) · 28 unmodified lines | |||
| 146 | clk_configs->m250_div.reg = dwmac->regs + PRG_ETH0; | 154 | clk_configs->m250_div.reg = dwmac->regs + PRG_ETH0; |
| 147 | clk_configs->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT; | 155 | clk_configs->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT; |
| 148 | clk_configs->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH; | 156 | clk_configs->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH; |
| 149 | clk_configs->m250_div.flags = CLK_DIVIDER_ONE_BASED | | 157 | clk_configs->m250_div.table = div_table; |
| 150 | CLK_DIVIDER_ALLOW_ZERO | | 158 | clk_configs->m250_div.flags = CLK_DIVIDER_ALLOW_ZERO | |
| 151 | CLK_DIVIDER_ROUND_CLOSEST; | 159 | CLK_DIVIDER_ROUND_CLOSEST; |
| 152 | clk = meson8b_dwmac_register_clk(dwmac, "m250_div", &parent_name, 1, | 160 | clk = meson8b_dwmac_register_clk(dwmac, "m250_div", &parent_name, 1, |
| 153 | &clk_divider_ops, | 161 | &clk_divider_ops, |
| 154 | &clk_configs->m250_div.hw); | 162 | &clk_configs->m250_div.hw); |
| @@ -957,6 +957,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 956 unmodified lines | |||
| 957 | /* default */ | 957 | /* default */ |
| 958 | break; | 958 | break; |
| 959 | case PHY_INTERFACE_MODE_RGMII: | 959 | case PHY_INTERFACE_MODE_RGMII: |
| 960 | case PHY_INTERFACE_MODE_RGMII_ID: | ||
| 961 | case PHY_INTERFACE_MODE_RGMII_RXID: | ||
| 962 | case PHY_INTERFACE_MODE_RGMII_TXID: | ||
| 960 | reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII; | 963 | reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII; |
| 961 | break; | 964 | break; |
| 962 | case PHY_INTERFACE_MODE_RMII: | 965 | case PHY_INTERFACE_MODE_RMII: |
| @@ -44,7 +44,7 @@ static int sun7i_gmac_init(struct platform_device *pdev, void *priv) · 43 unmodified lines | |||
| 44 | * rate, which then uses the auto-reparenting feature of the | 44 | * rate, which then uses the auto-reparenting feature of the |
| 45 | * clock driver, and enabling/disabling the clock. | 45 | * clock driver, and enabling/disabling the clock. |
| 46 | */ | 46 | */ |
| 47 | if (gmac->interface == PHY_INTERFACE_MODE_RGMII) { | 47 | if (phy_interface_mode_is_rgmii(gmac->interface)) { |
| 48 | clk_set_rate(gmac->tx_clk, SUN7I_GMAC_GMII_RGMII_RATE); | 48 | clk_set_rate(gmac->tx_clk, SUN7I_GMAC_GMII_RGMII_RATE); |
| 49 | clk_prepare_enable(gmac->tx_clk); | 49 | clk_prepare_enable(gmac->tx_clk); |
| 50 | gmac->clk_enabled = 1; | 50 | gmac->clk_enabled = 1; |
| @@ -106,6 +106,7 @@ MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode"); · 105 unmodified lines | |||
| 106 | static irqreturn_t stmmac_interrupt(int irq, void *dev_id); | 106 | static irqreturn_t stmmac_interrupt(int irq, void *dev_id); |
| 107 | 107 | ||
| 108 | #ifdef CONFIG_DEBUG_FS | 108 | #ifdef CONFIG_DEBUG_FS |
| 109 | static const struct net_device_ops stmmac_netdev_ops; | ||
| 109 | static void stmmac_init_fs(struct net_device *dev); | 110 | static void stmmac_init_fs(struct net_device *dev); |
| 110 | static void stmmac_exit_fs(struct net_device *dev); | 111 | static void stmmac_exit_fs(struct net_device *dev); |
| 111 | #endif | 112 | #endif |
| @@ -4256,6 +4257,34 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) · 4144 unmodified lines | |||
| 4256 | } | 4257 | } |
| 4257 | DEFINE_SHOW_ATTRIBUTE(stmmac_dma_cap); | 4258 | DEFINE_SHOW_ATTRIBUTE(stmmac_dma_cap); |
| 4258 | 4259 | ||
| 4260 | /* Use network device events to rename debugfs file entries. | ||
| 4261 | */ | ||
| 4262 | static int stmmac_device_event(struct notifier_block *unused, | ||
| 4263 | unsigned long event, void *ptr) | ||
| 4264 | { | ||
| 4265 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||
| 4266 | struct stmmac_priv *priv = netdev_priv(dev); | ||
| 4267 | |||
| 4268 | if (dev->netdev_ops != &stmmac_netdev_ops) | ||
| 4269 | goto done; | ||
| 4270 | |||
| 4271 | switch (event) { | ||
| 4272 | case NETDEV_CHANGENAME: | ||
| 4273 | if (priv->dbgfs_dir) | ||
| 4274 | priv->dbgfs_dir = debugfs_rename(stmmac_fs_dir, | ||
| 4275 | priv->dbgfs_dir, | ||
| 4276 | stmmac_fs_dir, | ||
| 4277 | dev->name); | ||
| 4278 | break; | ||
| 4279 | } | ||
| 4280 | done: | ||
| 4281 | return NOTIFY_DONE; | ||
| 4282 | } | ||
| 4283 | |||
| 4284 | static struct notifier_block stmmac_notifier = { | ||
| 4285 | .notifier_call = stmmac_device_event, | ||
| 4286 | }; | ||
| 4287 | |||
| 4259 | static void stmmac_init_fs(struct net_device *dev) | 4288 | static void stmmac_init_fs(struct net_device *dev) |
| 4260 | { | 4289 | { |
| 4261 | struct stmmac_priv *priv = netdev_priv(dev); | 4290 | struct stmmac_priv *priv = netdev_priv(dev); |
| @@ -4270,12 +4299,15 @@ static void stmmac_init_fs(struct net_device *dev) · 8 unmodified lines | |||
| 4270 | /* Entry to report the DMA HW features */ | 4299 | /* Entry to report the DMA HW features */ |
| 4271 | debugfs_create_file("dma_cap", 0444, priv->dbgfs_dir, dev, | 4300 | debugfs_create_file("dma_cap", 0444, priv->dbgfs_dir, dev, |
| 4272 | &stmmac_dma_cap_fops); | 4301 | &stmmac_dma_cap_fops); |
| 4302 | |||
| 4303 | register_netdevice_notifier(&stmmac_notifier); | ||
| 4273 | } | 4304 | } |
| 4274 | 4305 | ||
| 4275 | static void stmmac_exit_fs(struct net_device *dev) | 4306 | static void stmmac_exit_fs(struct net_device *dev) |
| 4276 | { | 4307 | { |
| 4277 | struct stmmac_priv *priv = netdev_priv(dev); | 4308 | struct stmmac_priv *priv = netdev_priv(dev); |
| 4278 | 4309 | ||
| 4310 | unregister_netdevice_notifier(&stmmac_notifier); | ||
| 4279 | debugfs_remove_recursive(priv->dbgfs_dir); | 4311 | debugfs_remove_recursive(priv->dbgfs_dir); |
| 4280 | } | 4312 | } |
| 4281 | #endif /* CONFIG_DEBUG_FS */ | 4313 | #endif /* CONFIG_DEBUG_FS */ |
| @@ -320,7 +320,7 @@ out: · 319 unmodified lines | |||
| 320 | static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, | 320 | static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, |
| 321 | struct device_node *np, struct device *dev) | 321 | struct device_node *np, struct device *dev) |
| 322 | { | 322 | { |
| 323 | bool mdio = false; | 323 | bool mdio = !of_phy_is_fixed_link(np); |
| 324 | static const struct of_device_id need_mdio_ids[] = { | 324 | static const struct of_device_id need_mdio_ids[] = { |
| 325 | { .compatible = "snps,dwc-qos-ethernet-4.10" }, | 325 | { .compatible = "snps,dwc-qos-ethernet-4.10" }, |
| 326 | {}, | 326 | {}, |
| @@ -540,7 +540,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev, · 539 unmodified lines | |||
| 540 | mtu = dst_mtu(&rt->dst); | 540 | mtu = dst_mtu(&rt->dst); |
| 541 | } | 541 | } |
| 542 | 542 | ||
| 543 | rt->dst.ops->update_pmtu(&rt->dst, NULL, skb, mtu); | 543 | rt->dst.ops->update_pmtu(&rt->dst, NULL, skb, mtu, false); |
| 544 | 544 | ||
| 545 | if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) && | 545 | if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) && |
| 546 | mtu < ntohs(iph->tot_len)) { | 546 | mtu < ntohs(iph->tot_len)) { |
| @@ -813,7 +813,7 @@ static struct sock *gtp_encap_enable_socket(int fd, int type, · 266 unmodified lines | |||
| 813 | lock_sock(sock->sk); | 813 | lock_sock(sock->sk); |
| 814 | if (sock->sk->sk_user_data) { | 814 | if (sock->sk->sk_user_data) { |
| 815 | sk = ERR_PTR(-EBUSY); | 815 | sk = ERR_PTR(-EBUSY); |
| 816 | goto out_sock; | 816 | goto out_rel_sock; |
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | sk = sock->sk; | 819 | sk = sock->sk; |
| @@ -826,8 +826,9 @@ static struct sock *gtp_encap_enable_socket(int fd, int type, · 6 unmodified lines | |||
| 826 | 826 | ||
| 827 | setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg); | 827 | setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg); |
| 828 | 828 | ||
| 829 | out_sock: | 829 | out_rel_sock: |
| 830 | release_sock(sock->sk); | 830 | release_sock(sock->sk); |
| 831 | out_sock: | ||
| 831 | sockfd_put(sock); | 832 | sockfd_put(sock); |
| 832 | return sk; | 833 | return sk; |
| 833 | } | 834 | } |
| @@ -259,7 +259,7 @@ static void macvlan_broadcast(struct sk_buff *skb, · 258 unmodified lines | |||
| 259 | struct net_device *src, | 259 | struct net_device *src, |
| 260 | enum macvlan_mode mode) | 260 | enum macvlan_mode mode) |
| 261 | { | 261 | { |
| 262 | const struct ethhdr *eth = eth_hdr(skb); | 262 | const struct ethhdr *eth = skb_eth_hdr(skb); |
| 263 | const struct macvlan_dev *vlan; | 263 | const struct macvlan_dev *vlan; |
| 264 | struct sk_buff *nskb; | 264 | struct sk_buff *nskb; |
| 265 | unsigned int i; | 265 | unsigned int i; |
| @@ -627,6 +627,8 @@ static struct phy_driver aqr_driver[] = { · 626 unmodified lines | |||
| 627 | .config_intr = aqr_config_intr, | 627 | .config_intr = aqr_config_intr, |
| 628 | .ack_interrupt = aqr_ack_interrupt, | 628 | .ack_interrupt = aqr_ack_interrupt, |
| 629 | .read_status = aqr_read_status, | 629 | .read_status = aqr_read_status, |
| 630 | .suspend = aqr107_suspend, | ||
| 631 | .resume = aqr107_resume, | ||
| 630 | }, | 632 | }, |
| 631 | { | 633 | { |
| 632 | PHY_ID_MATCH_MODEL(PHY_ID_AQR106), | 634 | PHY_ID_MATCH_MODEL(PHY_ID_AQR106), |
| @@ -566,6 +566,9 @@ static int phylink_register_sfp(struct phylink *pl, · 565 unmodified lines | |||
| 566 | struct sfp_bus *bus; | 566 | struct sfp_bus *bus; |
| 567 | int ret; | 567 | int ret; |
| 568 | 568 | ||
| 569 | if (!fwnode) | ||
| 570 | return 0; | ||
| 571 | |||
| 569 | bus = sfp_bus_find_fwnode(fwnode); | 572 | bus = sfp_bus_find_fwnode(fwnode); |
| 570 | if (IS_ERR(bus)) { | 573 | if (IS_ERR(bus)) { |
| 571 | ret = PTR_ERR(bus); | 574 | ret = PTR_ERR(bus); |
| @@ -2724,11 +2724,6 @@ static int lan78xx_stop(struct net_device *net) · 2723 unmodified lines | |||
| 2724 | return 0; | 2724 | return 0; |
| 2725 | } | 2725 | } |
| 2726 | 2726 | ||
| 2727 | static int lan78xx_linearize(struct sk_buff *skb) | ||
| 2728 | { | ||
| 2729 | return skb_linearize(skb); | ||
| 2730 | } | ||
| 2731 | |||
| 2732 | static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev, | 2727 | static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev, |
| 2733 | struct sk_buff *skb, gfp_t flags) | 2728 | struct sk_buff *skb, gfp_t flags) |
| 2734 | { | 2729 | { |
| @@ -2740,8 +2735,10 @@ static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev, · 5 unmodified lines | |||
| 2740 | return NULL; | 2735 | return NULL; |
| 2741 | } | 2736 | } |
| 2742 | 2737 | ||
| 2743 | if (lan78xx_linearize(skb) < 0) | 2738 | if (skb_linearize(skb)) { |
| 2739 | dev_kfree_skb_any(skb); | ||
| 2744 | return NULL; | 2740 | return NULL; |
| 2741 | } | ||
| 2745 | 2742 | ||
| 2746 | tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN_MASK_) | TX_CMD_A_FCS_; | 2743 | tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN_MASK_) | TX_CMD_A_FCS_; |
| 2747 | 2744 | ||
| @@ -2541,7 +2541,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 2540 unmodified lines | |||
| 2541 | ndst = &rt->dst; | 2541 | ndst = &rt->dst; |
| 2542 | skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM); | 2542 | skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM); |
| 2543 | 2543 | ||
| 2544 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); | 2544 | tos = ip_tunnel_ecn_encap(RT_TOS(tos), old_iph, skb); |
| 2545 | ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); | 2545 | ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); |
| 2546 | err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), | 2546 | err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), |
| 2547 | vni, md, flags, udp_sum); | 2547 | vni, md, flags, udp_sum); |
| @@ -2581,7 +2581,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 33 unmodified lines | |||
| 2581 | 2581 | ||
| 2582 | skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM); | 2582 | skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM); |
| 2583 | 2583 | ||
| 2584 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); | 2584 | tos = ip_tunnel_ecn_encap(RT_TOS(tos), old_iph, skb); |
| 2585 | ttl = ttl ? : ip6_dst_hoplimit(ndst); | 2585 | ttl = ttl ? : ip6_dst_hoplimit(ndst); |
| 2586 | skb_scrub_packet(skb, xnet); | 2586 | skb_scrub_packet(skb, xnet); |
| 2587 | err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr), | 2587 | err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr), |
| @@ -708,7 +708,7 @@ static netdev_tx_t sdla_transmit(struct sk_buff *skb, · 707 unmodified lines | |||
| 708 | 708 | ||
| 709 | spin_lock_irqsave(&sdla_lock, flags); | 709 | spin_lock_irqsave(&sdla_lock, flags); |
| 710 | SDLA_WINDOW(dev, addr); | 710 | SDLA_WINDOW(dev, addr); |
| 711 | pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK)); | 711 | pbuf = (void *)(dev->mem_start + (addr & SDLA_ADDR_MASK)); |
| 712 | __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); | 712 | __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); |
| 713 | SDLA_WINDOW(dev, addr); | 713 | SDLA_WINDOW(dev, addr); |
| 714 | pbuf->opp_flag = 1; | 714 | pbuf->opp_flag = 1; |
| @@ -222,6 +222,8 @@ static blk_status_t nvme_error_status(u16 status) · 221 unmodified lines | |||
| 222 | case NVME_SC_CAP_EXCEEDED: | 222 | case NVME_SC_CAP_EXCEEDED: |
| 223 | return BLK_STS_NOSPC; | 223 | return BLK_STS_NOSPC; |
| 224 | case NVME_SC_LBA_RANGE: | 224 | case NVME_SC_LBA_RANGE: |
| 225 | case NVME_SC_CMD_INTERRUPTED: | ||
| 226 | case NVME_SC_NS_NOT_READY: | ||
| 225 | return BLK_STS_TARGET; | 227 | return BLK_STS_TARGET; |
| 226 | case NVME_SC_BAD_ATTRIBUTES: | 228 | case NVME_SC_BAD_ATTRIBUTES: |
| 227 | case NVME_SC_ONCS_NOT_SUPPORTED: | 229 | case NVME_SC_ONCS_NOT_SUPPORTED: |
| @@ -24,6 +24,16 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd) · 23 unmodified lines | |||
| 24 | return len; | 24 | return len; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | static u32 nvmet_feat_data_len(struct nvmet_req *req, u32 cdw10) | ||
| 28 | { | ||
| 29 | switch (cdw10 & 0xff) { | ||
| 30 | case NVME_FEAT_HOST_ID: | ||
| 31 | return sizeof(req->sq->ctrl->hostid); | ||
| 32 | default: | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 27 | u64 nvmet_get_log_page_offset(struct nvme_command *cmd) | 37 | u64 nvmet_get_log_page_offset(struct nvme_command *cmd) |
| 28 | { | 38 | { |
| 29 | return le64_to_cpu(cmd->get_log_page.lpo); | 39 | return le64_to_cpu(cmd->get_log_page.lpo); |
| @@ -778,7 +788,7 @@ static void nvmet_execute_get_features(struct nvmet_req *req) · 748 unmodified lines | |||
| 778 | u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10); | 788 | u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10); |
| 779 | u16 status = 0; | 789 | u16 status = 0; |
| 780 | 790 | ||
| 781 | if (!nvmet_check_data_len(req, 0)) | 791 | if (!nvmet_check_data_len(req, nvmet_feat_data_len(req, cdw10))) |
| 782 | return; | 792 | return; |
| 783 | 793 | ||
| 784 | switch (cdw10 & 0xff) { | 794 | switch (cdw10 & 0xff) { |
| @@ -115,7 +115,7 @@ struct cpcap_usb_ints_state { · 114 unmodified lines | |||
| 115 | enum cpcap_gpio_mode { | 115 | enum cpcap_gpio_mode { |
| 116 | CPCAP_DM_DP, | 116 | CPCAP_DM_DP, |
| 117 | CPCAP_MDM_RX_TX, | 117 | CPCAP_MDM_RX_TX, |
| 118 | CPCAP_UNKNOWN, | 118 | CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */ |
| 119 | CPCAP_OTG_DM_DP, | 119 | CPCAP_OTG_DM_DP, |
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| @@ -134,6 +134,8 @@ struct cpcap_phy_ddata { · 12 unmodified lines | |||
| 134 | struct iio_channel *id; | 134 | struct iio_channel *id; |
| 135 | struct regulator *vusb; | 135 | struct regulator *vusb; |
| 136 | atomic_t active; | 136 | atomic_t active; |
| 137 | unsigned int vbus_provider:1; | ||
| 138 | unsigned int docked:1; | ||
| 137 | }; | 139 | }; |
| 138 | 140 | ||
| 139 | static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata) | 141 | static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata) |
| @@ -207,6 +209,19 @@ static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata, · 67 unmodified lines | |||
| 207 | static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata); | 209 | static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata); |
| 208 | static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata); | 210 | static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata); |
| 209 | 211 | ||
| 212 | static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata, | ||
| 213 | enum musb_vbus_id_status status) | ||
| 214 | { | ||
| 215 | int error; | ||
| 216 | |||
| 217 | error = musb_mailbox(status); | ||
| 218 | if (!error) | ||
| 219 | return; | ||
| 220 | |||
| 221 | dev_dbg(ddata->dev, "%s: musb_mailbox failed: %i\n", | ||
| 222 | __func__, error); | ||
| 223 | } | ||
| 224 | |||
| 210 | static void cpcap_usb_detect(struct work_struct *work) | 225 | static void cpcap_usb_detect(struct work_struct *work) |
| 211 | { | 226 | { |
| 212 | struct cpcap_phy_ddata *ddata; | 227 | struct cpcap_phy_ddata *ddata; |
| @@ -220,16 +235,66 @@ static void cpcap_usb_detect(struct work_struct *work) · 7 unmodified lines | |||
| 220 | if (error) | 235 | if (error) |
| 221 | return; | 236 | return; |
| 222 | 237 | ||
| 223 | if (s.id_ground) { | 238 | vbus = cpcap_usb_vbus_valid(ddata); |
| 224 | dev_dbg(ddata->dev, "id ground, USB host mode\n"); | 239 | |
| 240 | /* We need to kick the VBUS as USB A-host */ | ||
| 241 | if (s.id_ground && ddata->vbus_provider) { | ||
| 242 | dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n"); | ||
| 243 | |||
| 244 | cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); | ||
| 245 | |||
| 246 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, | ||
| 247 | CPCAP_BIT_VBUSSTBY_EN | | ||
| 248 | CPCAP_BIT_VBUSEN_SPI, | ||
| 249 | CPCAP_BIT_VBUSEN_SPI); | ||
| 250 | if (error) | ||
| 251 | goto out_err; | ||
| 252 | |||
| 253 | return; | ||
| 254 | } | ||
| 255 | |||
| 256 | if (vbus && s.id_ground && ddata->docked) { | ||
| 257 | dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n"); | ||
| 258 | |||
| 259 | cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); | ||
| 260 | |||
| 261 | return; | ||
| 262 | } | ||
| 263 | |||
| 264 | /* No VBUS needed with docks */ | ||
| 265 | if (vbus && s.id_ground && !ddata->vbus_provider) { | ||
| 266 | dev_dbg(ddata->dev, "connected to a dock\n"); | ||
| 267 | |||
| 268 | ddata->docked = true; | ||
| 269 | |||
| 225 | error = cpcap_usb_set_usb_mode(ddata); | 270 | error = cpcap_usb_set_usb_mode(ddata); |
| 226 | if (error) | 271 | if (error) |
| 227 | goto out_err; | 272 | goto out_err; |
| 228 | 273 | ||
| 229 | error = musb_mailbox(MUSB_ID_GROUND); | 274 | cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); |
| 275 | |||
| 276 | /* | ||
| 277 | * Force check state again after musb has reoriented, | ||
| 278 | * otherwise devices won't enumerate after loading PHY | ||
| 279 | * driver. | ||
| 280 | */ | ||
| 281 | schedule_delayed_work(&ddata->detect_work, | ||
| 282 | msecs_to_jiffies(1000)); | ||
| 283 | |||
| 284 | return; | ||
| 285 | } | ||
| 286 | |||
| 287 | if (s.id_ground && !ddata->docked) { | ||
| 288 | dev_dbg(ddata->dev, "id ground, USB host mode\n"); | ||
| 289 | |||
| 290 | ddata->vbus_provider = true; | ||
| 291 | |||
| 292 | error = cpcap_usb_set_usb_mode(ddata); | ||
| 230 | if (error) | 293 | if (error) |
| 231 | goto out_err; | 294 | goto out_err; |
| 232 | 295 | ||
| 296 | cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); | ||
| 297 | |||
| 233 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, | 298 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, |
| 234 | CPCAP_BIT_VBUSSTBY_EN | | 299 | CPCAP_BIT_VBUSSTBY_EN | |
| 235 | CPCAP_BIT_VBUSEN_SPI, | 300 | CPCAP_BIT_VBUSEN_SPI, |
| @@ -248,43 +313,26 @@ static void cpcap_usb_detect(struct work_struct *work) · 12 unmodified lines | |||
| 248 | 313 | ||
| 249 | vbus = cpcap_usb_vbus_valid(ddata); | 314 | vbus = cpcap_usb_vbus_valid(ddata); |
| 250 | 315 | ||
| 316 | /* Otherwise assume we're connected to a USB host */ | ||
| 251 | if (vbus) { | 317 | if (vbus) { |
| 252 | /* Are we connected to a docking station with vbus? */ | ||
| 253 | if (s.id_ground) { | ||
| 254 | dev_dbg(ddata->dev, "connected to a dock\n"); | ||
| 255 | |||
| 256 | /* No VBUS needed with docks */ | ||
| 257 | error = cpcap_usb_set_usb_mode(ddata); | ||
| 258 | if (error) | ||
| 259 | goto out_err; | ||
| 260 | error = musb_mailbox(MUSB_ID_GROUND); | ||
| 261 | if (error) | ||
| 262 | goto out_err; | ||
| 263 | |||
| 264 | return; | ||
| 265 | } | ||
| 266 | |||
| 267 | /* Otherwise assume we're connected to a USB host */ | ||
| 268 | dev_dbg(ddata->dev, "connected to USB host\n"); | 318 | dev_dbg(ddata->dev, "connected to USB host\n"); |
| 269 | error = cpcap_usb_set_usb_mode(ddata); | 319 | error = cpcap_usb_set_usb_mode(ddata); |
| 270 | if (error) | 320 | if (error) |
| 271 | goto out_err; | 321 | goto out_err; |
| 272 | error = musb_mailbox(MUSB_VBUS_VALID); | 322 | cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID); |
| 273 | if (error) | ||
| 274 | goto out_err; | ||
| 275 | 323 | ||
| 276 | return; | 324 | return; |
| 277 | } | 325 | } |
| 278 | 326 | ||
| 327 | ddata->vbus_provider = false; | ||
| 328 | ddata->docked = false; | ||
| 329 | cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF); | ||
| 330 | |||
| 279 | /* Default to debug UART mode */ | 331 | /* Default to debug UART mode */ |
| 280 | error = cpcap_usb_set_uart_mode(ddata); | 332 | error = cpcap_usb_set_uart_mode(ddata); |
| 281 | if (error) | 333 | if (error) |
| 282 | goto out_err; | 334 | goto out_err; |
| 283 | 335 | ||
| 284 | error = musb_mailbox(MUSB_VBUS_OFF); | ||
| 285 | if (error) | ||
| 286 | goto out_err; | ||
| 287 | |||
| 288 | dev_dbg(ddata->dev, "set UART mode\n"); | 336 | dev_dbg(ddata->dev, "set UART mode\n"); |
| 289 | 337 | ||
| 290 | return; | 338 | return; |
| @@ -376,7 +424,8 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata) · 85 unmodified lines | |||
| 376 | { | 424 | { |
| 377 | int error; | 425 | int error; |
| 378 | 426 | ||
| 379 | error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP); | 427 | /* Disable lines to prevent glitches from waking up mdm6600 */ |
| 428 | error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED); | ||
| 380 | if (error) | 429 | if (error) |
| 381 | goto out_err; | 430 | goto out_err; |
| 382 | 431 | ||
| @@ -403,6 +452,11 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata) · 20 unmodified lines | |||
| 403 | if (error) | 452 | if (error) |
| 404 | goto out_err; | 453 | goto out_err; |
| 405 | 454 | ||
| 455 | /* Enable UART mode */ | ||
| 456 | error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP); | ||
| 457 | if (error) | ||
| 458 | goto out_err; | ||
| 459 | |||
| 406 | return 0; | 460 | return 0; |
| 407 | 461 | ||
| 408 | out_err: | 462 | out_err: |
| @@ -415,7 +469,8 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata) · 6 unmodified lines | |||
| 415 | { | 469 | { |
| 416 | int error; | 470 | int error; |
| 417 | 471 | ||
| 418 | error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP); | 472 | /* Disable lines to prevent glitches from waking up mdm6600 */ |
| 473 | error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED); | ||
| 419 | if (error) | 474 | if (error) |
| 420 | return error; | 475 | return error; |
| 421 | 476 | ||
| @@ -434,12 +489,6 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata) · 12 unmodified lines | |||
| 434 | if (error) | 489 | if (error) |
| 435 | goto out_err; | 490 | goto out_err; |
| 436 | 491 | ||
| 437 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2, | ||
| 438 | CPCAP_BIT_USBXCVREN, | ||
| 439 | CPCAP_BIT_USBXCVREN); | ||
| 440 | if (error) | ||
| 441 | goto out_err; | ||
| 442 | |||
| 443 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, | 492 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, |
| 444 | CPCAP_BIT_PU_SPI | | 493 | CPCAP_BIT_PU_SPI | |
| 445 | CPCAP_BIT_DMPD_SPI | | 494 | CPCAP_BIT_DMPD_SPI | |
| @@ -455,6 +504,11 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata) · 9 unmodified lines | |||
| 455 | if (error) | 504 | if (error) |
| 456 | goto out_err; | 505 | goto out_err; |
| 457 | 506 | ||
| 507 | /* Enable USB mode */ | ||
| 508 | error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP); | ||
| 509 | if (error) | ||
| 510 | goto out_err; | ||
| 511 | |||
| 458 | return 0; | 512 | return 0; |
| 459 | 513 | ||
| 460 | out_err: | 514 | out_err: |
| @@ -649,9 +703,7 @@ static int cpcap_usb_phy_remove(struct platform_device *pdev) · 188 unmodified lines | |||
| 649 | if (error) | 703 | if (error) |
| 650 | dev_err(ddata->dev, "could not set UART mode\n"); | 704 | dev_err(ddata->dev, "could not set UART mode\n"); |
| 651 | 705 | ||
| 652 | error = musb_mailbox(MUSB_VBUS_OFF); | 706 | cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF); |
| 653 | if (error) | ||
| 654 | dev_err(ddata->dev, "could not set mailbox\n"); | ||
| 655 | 707 | ||
| 656 | usb_remove_phy(&ddata->phy); | 708 | usb_remove_phy(&ddata->phy); |
| 657 | cancel_delayed_work_sync(&ddata->detect_work); | 709 | cancel_delayed_work_sync(&ddata->detect_work); |
| @@ -200,7 +200,7 @@ static void phy_mdm6600_status(struct work_struct *work) · 199 unmodified lines | |||
| 200 | struct phy_mdm6600 *ddata; | 200 | struct phy_mdm6600 *ddata; |
| 201 | struct device *dev; | 201 | struct device *dev; |
| 202 | DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES); | 202 | DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES); |
| 203 | int error, i, val = 0; | 203 | int error; |
| 204 | 204 | ||
| 205 | ddata = container_of(work, struct phy_mdm6600, status_work.work); | 205 | ddata = container_of(work, struct phy_mdm6600, status_work.work); |
| 206 | dev = ddata->dev; | 206 | dev = ddata->dev; |
| @@ -212,16 +212,11 @@ static void phy_mdm6600_status(struct work_struct *work) · 5 unmodified lines | |||
| 212 | if (error) | 212 | if (error) |
| 213 | return; | 213 | return; |
| 214 | 214 | ||
| 215 | for (i = 0; i < PHY_MDM6600_NR_STATUS_LINES; i++) { | 215 | ddata->status = values[0] & ((1 << PHY_MDM6600_NR_STATUS_LINES) - 1); |
| 216 | val |= test_bit(i, values) << i; | ||
| 217 | dev_dbg(ddata->dev, "XXX %s: i: %i values[i]: %i val: %i\n", | ||
| 218 | __func__, i, test_bit(i, values), val); | ||
| 219 | } | ||
| 220 | ddata->status = values[0]; | ||
| 221 | 216 | ||
| 222 | dev_info(dev, "modem status: %i %s\n", | 217 | dev_info(dev, "modem status: %i %s\n", |
| 223 | ddata->status, | 218 | ddata->status, |
| 224 | phy_mdm6600_status_name[ddata->status & 7]); | 219 | phy_mdm6600_status_name[ddata->status]); |
| 225 | complete(&ddata->ack); | 220 | complete(&ddata->ack); |
| 226 | } | 221 | } |
| 227 | 222 | ||
| @@ -66,7 +66,7 @@ · 65 unmodified lines | |||
| 66 | /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */ | 66 | /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */ |
| 67 | #define CLAMP_EN BIT(0) /* enables i/o clamp_n */ | 67 | #define CLAMP_EN BIT(0) /* enables i/o clamp_n */ |
| 68 | 68 | ||
| 69 | #define PHY_INIT_COMPLETE_TIMEOUT 1000 | 69 | #define PHY_INIT_COMPLETE_TIMEOUT 10000 |
| 70 | #define POWER_DOWN_DELAY_US_MIN 10 | 70 | #define POWER_DOWN_DELAY_US_MIN 10 |
| 71 | #define POWER_DOWN_DELAY_US_MAX 11 | 71 | #define POWER_DOWN_DELAY_US_MAX 11 |
| 72 | 72 | ||
| @@ -603,6 +603,8 @@ static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw, · 602 unmodified lines | |||
| 603 | { | 603 | { |
| 604 | const struct pre_pll_config *cfg = pre_pll_cfg_table; | 604 | const struct pre_pll_config *cfg = pre_pll_cfg_table; |
| 605 | 605 | ||
| 606 | rate = (rate / 1000) * 1000; | ||
| 607 | |||
| 606 | for (; cfg->pixclock != 0; cfg++) | 608 | for (; cfg->pixclock != 0; cfg++) |
| 607 | if (cfg->pixclock == rate && !cfg->fracdiv) | 609 | if (cfg->pixclock == rate && !cfg->fracdiv) |
| 608 | break; | 610 | break; |
| @@ -755,6 +757,8 @@ static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, · 146 unmodified lines | |||
| 755 | { | 757 | { |
| 756 | const struct pre_pll_config *cfg = pre_pll_cfg_table; | 758 | const struct pre_pll_config *cfg = pre_pll_cfg_table; |
| 757 | 759 | ||
| 760 | rate = (rate / 1000) * 1000; | ||
| 761 | |||
| 758 | for (; cfg->pixclock != 0; cfg++) | 762 | for (; cfg->pixclock != 0; cfg++) |
| 759 | if (cfg->pixclock == rate) | 763 | if (cfg->pixclock == rate) |
| 760 | break; | 764 | break; |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | config PINCTRL_LOCHNAGAR | 2 | config PINCTRL_LOCHNAGAR |
| 3 | tristate "Cirrus Logic Lochnagar pinctrl driver" | 3 | tristate "Cirrus Logic Lochnagar pinctrl driver" |
| 4 | depends on MFD_LOCHNAGAR | 4 | depends on MFD_LOCHNAGAR |
| 5 | select GPIOLIB | ||
| 5 | select PINMUX | 6 | select PINMUX |
| 6 | select PINCONF | 7 | select PINCONF |
| 7 | select GENERIC_PINCONF | 8 | select GENERIC_PINCONF |
| @@ -441,6 +441,7 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc, · 440 unmodified lines | |||
| 441 | return ret; | 441 | return ret; |
| 442 | 442 | ||
| 443 | meson_calc_reg_and_bit(bank, pin, REG_DS, ®, &bit); | 443 | meson_calc_reg_and_bit(bank, pin, REG_DS, ®, &bit); |
| 444 | bit = bit << 1; | ||
| 444 | 445 | ||
| 445 | ret = regmap_read(pc->reg_ds, reg, &val); | 446 | ret = regmap_read(pc->reg_ds, reg, &val); |
| 446 | if (ret) | 447 | if (ret) |
| @@ -18,7 +18,7 @@ if MIPS_PLATFORM_DEVICES · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | config CPU_HWMON | 19 | config CPU_HWMON |
| 20 | tristate "Loongson-3 CPU HWMon Driver" | 20 | tristate "Loongson-3 CPU HWMon Driver" |
| 21 | depends on CONFIG_MACH_LOONGSON64 | 21 | depends on MACH_LOONGSON64 |
| 22 | select HWMON | 22 | select HWMON |
| 23 | default y | 23 | default y |
| 24 | help | 24 | help |
| @@ -1295,6 +1295,9 @@ struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv) · 1294 unmodified lines | |||
| 1295 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 1295 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 1296 | int ret; | 1296 | int ret; |
| 1297 | 1297 | ||
| 1298 | if (!rapl_defaults) | ||
| 1299 | return ERR_PTR(-ENODEV); | ||
| 1300 | |||
| 1298 | rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL); | 1301 | rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL); |
| 1299 | if (!rp) | 1302 | if (!rp) |
| 1300 | return ERR_PTR(-ENOMEM); | 1303 | return ERR_PTR(-ENOMEM); |
| @@ -166,9 +166,9 @@ static struct posix_clock_operations ptp_clock_ops = { · 165 unmodified lines | |||
| 166 | .read = ptp_read, | 166 | .read = ptp_read, |
| 167 | }; | 167 | }; |
| 168 | 168 | ||
| 169 | static void delete_ptp_clock(struct posix_clock *pc) | 169 | static void ptp_clock_release(struct device *dev) |
| 170 | { | 170 | { |
| 171 | struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); | 171 | struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev); |
| 172 | 172 | ||
| 173 | mutex_destroy(&ptp->tsevq_mux); | 173 | mutex_destroy(&ptp->tsevq_mux); |
| 174 | mutex_destroy(&ptp->pincfg_mux); | 174 | mutex_destroy(&ptp->pincfg_mux); |
| @@ -213,7 +213,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, · 38 unmodified lines | |||
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | ptp->clock.ops = ptp_clock_ops; | 215 | ptp->clock.ops = ptp_clock_ops; |
| 216 | ptp->clock.release = delete_ptp_clock; | ||
| 217 | ptp->info = info; | 216 | ptp->info = info; |
| 218 | ptp->devid = MKDEV(major, index); | 217 | ptp->devid = MKDEV(major, index); |
| 219 | ptp->index = index; | 218 | ptp->index = index; |
| @@ -236,15 +235,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, · 16 unmodified lines | |||
| 236 | if (err) | 235 | if (err) |
| 237 | goto no_pin_groups; | 236 | goto no_pin_groups; |
| 238 | 237 | ||
| 239 | /* Create a new device in our class. */ | ||
| 240 | ptp->dev = device_create_with_groups(ptp_class, parent, ptp->devid, | ||
| 241 | ptp, ptp->pin_attr_groups, | ||
| 242 | "ptp%d", ptp->index); | ||
| 243 | if (IS_ERR(ptp->dev)) { | ||
| 244 | err = PTR_ERR(ptp->dev); | ||
| 245 | goto no_device; | ||
| 246 | } | ||
| 247 | |||
| 248 | /* Register a new PPS source. */ | 238 | /* Register a new PPS source. */ |
| 249 | if (info->pps) { | 239 | if (info->pps) { |
| 250 | struct pps_source_info pps; | 240 | struct pps_source_info pps; |
| @@ -260,8 +250,18 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, · 9 unmodified lines | |||
| 260 | } | 250 | } |
| 261 | } | 251 | } |
| 262 | 252 | ||
| 263 | /* Create a posix clock. */ | 253 | /* Initialize a new device of our class in our clock structure. */ |
| 264 | err = posix_clock_register(&ptp->clock, ptp->devid); | 254 | device_initialize(&ptp->dev); |
| 255 | ptp->dev.devt = ptp->devid; | ||
| 256 | ptp->dev.class = ptp_class; | ||
| 257 | ptp->dev.parent = parent; | ||
| 258 | ptp->dev.groups = ptp->pin_attr_groups; | ||
| 259 | ptp->dev.release = ptp_clock_release; | ||
| 260 | dev_set_drvdata(&ptp->dev, ptp); | ||
| 261 | dev_set_name(&ptp->dev, "ptp%d", ptp->index); | ||
| 262 | |||
| 263 | /* Create a posix clock and link it to the device. */ | ||
| 264 | err = posix_clock_register(&ptp->clock, &ptp->dev); | ||
| 265 | if (err) { | 265 | if (err) { |
| 266 | pr_err("failed to create posix clock\n"); | 266 | pr_err("failed to create posix clock\n"); |
| 267 | goto no_clock; | 267 | goto no_clock; |
| @@ -273,8 +273,6 @@ no_clock: · 5 unmodified lines | |||
| 273 | if (ptp->pps_source) | 273 | if (ptp->pps_source) |
| 274 | pps_unregister_source(ptp->pps_source); | 274 | pps_unregister_source(ptp->pps_source); |
| 275 | no_pps: | 275 | no_pps: |
| 276 | device_destroy(ptp_class, ptp->devid); | ||
| 277 | no_device: | ||
| 278 | ptp_cleanup_pin_groups(ptp); | 276 | ptp_cleanup_pin_groups(ptp); |
| 279 | no_pin_groups: | 277 | no_pin_groups: |
| 280 | if (ptp->kworker) | 278 | if (ptp->kworker) |
| @@ -304,7 +302,6 @@ int ptp_clock_unregister(struct ptp_clock *ptp) · 23 unmodified lines | |||
| 304 | if (ptp->pps_source) | 302 | if (ptp->pps_source) |
| 305 | pps_unregister_source(ptp->pps_source); | 303 | pps_unregister_source(ptp->pps_source); |
| 306 | 304 | ||
| 307 | device_destroy(ptp_class, ptp->devid); | ||
| 308 | ptp_cleanup_pin_groups(ptp); | 305 | ptp_cleanup_pin_groups(ptp); |
| 309 | 306 | ||
| 310 | posix_clock_unregister(&ptp->clock); | 307 | posix_clock_unregister(&ptp->clock); |
| @@ -28,7 +28,7 @@ struct timestamp_event_queue { · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | struct ptp_clock { | 29 | struct ptp_clock { |
| 30 | struct posix_clock clock; | 30 | struct posix_clock clock; |
| 31 | struct device *dev; | 31 | struct device dev; |
| 32 | struct ptp_clock_info *info; | 32 | struct ptp_clock_info *info; |
| 33 | dev_t devid; | 33 | dev_t devid; |
| 34 | int index; /* index into clocks.map */ | 34 | int index; /* index into clocks.map */ |
| @@ -413,10 +413,13 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) · 412 unmodified lines | |||
| 413 | int i; | 413 | int i; |
| 414 | 414 | ||
| 415 | for (i = 0; i < rate_count; i++) { | 415 | for (i = 0; i < rate_count; i++) { |
| 416 | if (ramp <= slew_rates[i]) | 416 | if (ramp > slew_rates[i]) |
| 417 | cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i); | ||
| 418 | else | ||
| 419 | break; | 417 | break; |
| 418 | |||
| 419 | if (id == AXP20X_DCDC2) | ||
| 420 | cfg = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE(i); | ||
| 421 | else | ||
| 422 | cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i); | ||
| 420 | } | 423 | } |
| 421 | 424 | ||
| 422 | if (cfg == 0xff) { | 425 | if (cfg == 0xff) { |
| @@ -605,7 +608,7 @@ static const struct regulator_desc axp22x_regulators[] = { · 182 unmodified lines | |||
| 605 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK), | 608 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK), |
| 606 | AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100, | 609 | AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100, |
| 607 | AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK, | 610 | AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK, |
| 608 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK), | 611 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO2_MASK), |
| 609 | AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100, | 612 | AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100, |
| 610 | AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK, | 613 | AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK, |
| 611 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK), | 614 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK), |
| @@ -101,7 +101,6 @@ static const struct regulator_ops bd70528_ldo_ops = { · 100 unmodified lines | |||
| 101 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 101 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 102 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 102 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 103 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 103 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
| 104 | .set_ramp_delay = bd70528_set_ramp_delay, | ||
| 105 | }; | 104 | }; |
| 106 | 105 | ||
| 107 | static const struct regulator_ops bd70528_led_ops = { | 106 | static const struct regulator_ops bd70528_led_ops = { |
| @@ -172,20 +172,7 @@ int mc146818_set_time(struct rtc_time *time) · 171 unmodified lines | |||
| 172 | save_control = CMOS_READ(RTC_CONTROL); | 172 | save_control = CMOS_READ(RTC_CONTROL); |
| 173 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); | 173 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); |
| 174 | save_freq_select = CMOS_READ(RTC_FREQ_SELECT); | 174 | save_freq_select = CMOS_READ(RTC_FREQ_SELECT); |
| 175 | 175 | CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); | |
| 176 | #ifdef CONFIG_X86 | ||
| 177 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD && | ||
| 178 | boot_cpu_data.x86 == 0x17) || | ||
| 179 | boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { | ||
| 180 | CMOS_WRITE((save_freq_select & (~RTC_DIV_RESET2)), | ||
| 181 | RTC_FREQ_SELECT); | ||
| 182 | save_freq_select &= ~RTC_DIV_RESET2; | ||
| 183 | } else | ||
| 184 | CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), | ||
| 185 | RTC_FREQ_SELECT); | ||
| 186 | #else | ||
| 187 | CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT); | ||
| 188 | #endif | ||
| 189 | 176 | ||
| 190 | #ifdef CONFIG_MACH_DECSTATION | 177 | #ifdef CONFIG_MACH_DECSTATION |
| 191 | CMOS_WRITE(real_yrs, RTC_DEC_YEAR); | 178 | CMOS_WRITE(real_yrs, RTC_DEC_YEAR); |
| @@ -47,7 +47,7 @@ static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data) · 46 unmodified lines | |||
| 47 | irqen = irqsta & ~RTC_IRQ_EN_AL; | 47 | irqen = irqsta & ~RTC_IRQ_EN_AL; |
| 48 | mutex_lock(&rtc->lock); | 48 | mutex_lock(&rtc->lock); |
| 49 | if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, | 49 | if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, |
| 50 | irqen) < 0) | 50 | irqen) == 0) |
| 51 | mtk_rtc_write_trigger(rtc); | 51 | mtk_rtc_write_trigger(rtc); |
| 52 | mutex_unlock(&rtc->lock); | 52 | mutex_unlock(&rtc->lock); |
| 53 | 53 | ||
| @@ -169,12 +169,12 @@ static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) · 115 unmodified lines | |||
| 169 | alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); | 169 | alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); |
| 170 | mutex_unlock(&rtc->lock); | 170 | mutex_unlock(&rtc->lock); |
| 171 | 171 | ||
| 172 | tm->tm_sec = data[RTC_OFFSET_SEC]; | 172 | tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK; |
| 173 | tm->tm_min = data[RTC_OFFSET_MIN]; | 173 | tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK; |
| 174 | tm->tm_hour = data[RTC_OFFSET_HOUR]; | 174 | tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK; |
| 175 | tm->tm_mday = data[RTC_OFFSET_DOM]; | 175 | tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK; |
| 176 | tm->tm_mon = data[RTC_OFFSET_MTH]; | 176 | tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK; |
| 177 | tm->tm_year = data[RTC_OFFSET_YEAR]; | 177 | tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK; |
| 178 | 178 | ||
| 179 | tm->tm_year += RTC_MIN_YEAR_OFFSET; | 179 | tm->tm_year += RTC_MIN_YEAR_OFFSET; |
| 180 | tm->tm_mon--; | 180 | tm->tm_mon--; |
| @@ -195,14 +195,25 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) · 14 unmodified lines | |||
| 195 | tm->tm_year -= RTC_MIN_YEAR_OFFSET; | 195 | tm->tm_year -= RTC_MIN_YEAR_OFFSET; |
| 196 | tm->tm_mon++; | 196 | tm->tm_mon++; |
| 197 | 197 | ||
| 198 | data[RTC_OFFSET_SEC] = tm->tm_sec; | ||
| 199 | data[RTC_OFFSET_MIN] = tm->tm_min; | ||
| 200 | data[RTC_OFFSET_HOUR] = tm->tm_hour; | ||
| 201 | data[RTC_OFFSET_DOM] = tm->tm_mday; | ||
| 202 | data[RTC_OFFSET_MTH] = tm->tm_mon; | ||
| 203 | data[RTC_OFFSET_YEAR] = tm->tm_year; | ||
| 204 | |||
| 205 | mutex_lock(&rtc->lock); | 198 | mutex_lock(&rtc->lock); |
| 199 | ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, | ||
| 200 | data, RTC_OFFSET_COUNT); | ||
| 201 | if (ret < 0) | ||
| 202 | goto exit; | ||
| 203 | |||
| 204 | data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) | | ||
| 205 | (tm->tm_sec & RTC_AL_SEC_MASK)); | ||
| 206 | data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) | | ||
| 207 | (tm->tm_min & RTC_AL_MIN_MASK)); | ||
| 208 | data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) | | ||
| 209 | (tm->tm_hour & RTC_AL_HOU_MASK)); | ||
| 210 | data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) | | ||
| 211 | (tm->tm_mday & RTC_AL_DOM_MASK)); | ||
| 212 | data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) | | ||
| 213 | (tm->tm_mon & RTC_AL_MTH_MASK)); | ||
| 214 | data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) | | ||
| 215 | (tm->tm_year & RTC_AL_YEA_MASK)); | ||
| 216 | |||
| 206 | if (alm->enabled) { | 217 | if (alm->enabled) { |
| 207 | ret = regmap_bulk_write(rtc->regmap, | 218 | ret = regmap_bulk_write(rtc->regmap, |
| 208 | rtc->addr_base + RTC_AL_SEC, | 219 | rtc->addr_base + RTC_AL_SEC, |
| @@ -379,6 +379,22 @@ static void __init sun50i_h6_rtc_clk_init(struct device_node *node) · 378 unmodified lines | |||
| 379 | CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc", | 379 | CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc", |
| 380 | sun50i_h6_rtc_clk_init); | 380 | sun50i_h6_rtc_clk_init); |
| 381 | 381 | ||
| 382 | /* | ||
| 383 | * The R40 user manual is self-conflicting on whether the prescaler is | ||
| 384 | * fixed or configurable. The clock diagram shows it as fixed, but there | ||
| 385 | * is also a configurable divider in the RTC block. | ||
| 386 | */ | ||
| 387 | static const struct sun6i_rtc_clk_data sun8i_r40_rtc_data = { | ||
| 388 | .rc_osc_rate = 16000000, | ||
| 389 | .fixed_prescaler = 512, | ||
| 390 | }; | ||
| 391 | static void __init sun8i_r40_rtc_clk_init(struct device_node *node) | ||
| 392 | { | ||
| 393 | sun6i_rtc_clk_init(node, &sun8i_r40_rtc_data); | ||
| 394 | } | ||
| 395 | CLK_OF_DECLARE_DRIVER(sun8i_r40_rtc_clk, "allwinner,sun8i-r40-rtc", | ||
| 396 | sun8i_r40_rtc_clk_init); | ||
| 397 | |||
| 382 | static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = { | 398 | static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = { |
| 383 | .rc_osc_rate = 32000, | 399 | .rc_osc_rate = 32000, |
| 384 | .has_out_clk = 1, | 400 | .has_out_clk = 1, |
| @@ -2482,50 +2482,46 @@ static int qeth_mpc_initialize(struct qeth_card *card) · 2481 unmodified lines | |||
| 2482 | rc = qeth_cm_enable(card); | 2482 | rc = qeth_cm_enable(card); |
| 2483 | if (rc) { | 2483 | if (rc) { |
| 2484 | QETH_CARD_TEXT_(card, 2, "2err%d", rc); | 2484 | QETH_CARD_TEXT_(card, 2, "2err%d", rc); |
| 2485 | goto out_qdio; | 2485 | return rc; |
| 2486 | } | 2486 | } |
| 2487 | rc = qeth_cm_setup(card); | 2487 | rc = qeth_cm_setup(card); |
| 2488 | if (rc) { | 2488 | if (rc) { |
| 2489 | QETH_CARD_TEXT_(card, 2, "3err%d", rc); | 2489 | QETH_CARD_TEXT_(card, 2, "3err%d", rc); |
| 2490 | goto out_qdio; | 2490 | return rc; |
| 2491 | } | 2491 | } |
| 2492 | rc = qeth_ulp_enable(card); | 2492 | rc = qeth_ulp_enable(card); |
| 2493 | if (rc) { | 2493 | if (rc) { |
| 2494 | QETH_CARD_TEXT_(card, 2, "4err%d", rc); | 2494 | QETH_CARD_TEXT_(card, 2, "4err%d", rc); |
| 2495 | goto out_qdio; | 2495 | return rc; |
| 2496 | } | 2496 | } |
| 2497 | rc = qeth_ulp_setup(card); | 2497 | rc = qeth_ulp_setup(card); |
| 2498 | if (rc) { | 2498 | if (rc) { |
| 2499 | QETH_CARD_TEXT_(card, 2, "5err%d", rc); | 2499 | QETH_CARD_TEXT_(card, 2, "5err%d", rc); |
| 2500 | goto out_qdio; | 2500 | return rc; |
| 2501 | } | 2501 | } |
| 2502 | rc = qeth_alloc_qdio_queues(card); | 2502 | rc = qeth_alloc_qdio_queues(card); |
| 2503 | if (rc) { | 2503 | if (rc) { |
| 2504 | QETH_CARD_TEXT_(card, 2, "5err%d", rc); | 2504 | QETH_CARD_TEXT_(card, 2, "5err%d", rc); |
| 2505 | goto out_qdio; | 2505 | return rc; |
| 2506 | } | 2506 | } |
| 2507 | rc = qeth_qdio_establish(card); | 2507 | rc = qeth_qdio_establish(card); |
| 2508 | if (rc) { | 2508 | if (rc) { |
| 2509 | QETH_CARD_TEXT_(card, 2, "6err%d", rc); | 2509 | QETH_CARD_TEXT_(card, 2, "6err%d", rc); |
| 2510 | qeth_free_qdio_queues(card); | 2510 | qeth_free_qdio_queues(card); |
| 2511 | goto out_qdio; | 2511 | return rc; |
| 2512 | } | 2512 | } |
| 2513 | rc = qeth_qdio_activate(card); | 2513 | rc = qeth_qdio_activate(card); |
| 2514 | if (rc) { | 2514 | if (rc) { |
| 2515 | QETH_CARD_TEXT_(card, 2, "7err%d", rc); | 2515 | QETH_CARD_TEXT_(card, 2, "7err%d", rc); |
| 2516 | goto out_qdio; | 2516 | return rc; |
| 2517 | } | 2517 | } |
| 2518 | rc = qeth_dm_act(card); | 2518 | rc = qeth_dm_act(card); |
| 2519 | if (rc) { | 2519 | if (rc) { |
| 2520 | QETH_CARD_TEXT_(card, 2, "8err%d", rc); | 2520 | QETH_CARD_TEXT_(card, 2, "8err%d", rc); |
| 2521 | goto out_qdio; | 2521 | return rc; |
| 2522 | } | 2522 | } |
| 2523 | 2523 | ||
| 2524 | return 0; | 2524 | return 0; |
| 2525 | out_qdio: | ||
| 2526 | qeth_qdio_clear_card(card, !IS_IQD(card)); | ||
| 2527 | qdio_free(CARD_DDEV(card)); | ||
| 2528 | return rc; | ||
| 2529 | } | 2525 | } |
| 2530 | 2526 | ||
| 2531 | void qeth_print_status_message(struct qeth_card *card) | 2527 | void qeth_print_status_message(struct qeth_card *card) |
| @@ -3429,11 +3425,6 @@ int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq) · 897 unmodified lines | |||
| 3429 | goto out; | 3425 | goto out; |
| 3430 | } | 3426 | } |
| 3431 | 3427 | ||
| 3432 | if (card->state != CARD_STATE_DOWN) { | ||
| 3433 | rc = -1; | ||
| 3434 | goto out; | ||
| 3435 | } | ||
| 3436 | |||
| 3437 | qeth_free_qdio_queues(card); | 3428 | qeth_free_qdio_queues(card); |
| 3438 | card->options.cq = cq; | 3429 | card->options.cq = cq; |
| 3439 | rc = 0; | 3430 | rc = 0; |
| @@ -5035,10 +5026,8 @@ retriable: · 1595 unmodified lines | |||
| 5035 | } | 5026 | } |
| 5036 | if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { | 5027 | if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { |
| 5037 | rc = qeth_query_setdiagass(card); | 5028 | rc = qeth_query_setdiagass(card); |
| 5038 | if (rc < 0) { | 5029 | if (rc) |
| 5039 | QETH_CARD_TEXT_(card, 2, "8err%d", rc); | 5030 | QETH_CARD_TEXT_(card, 2, "8err%d", rc); |
| 5040 | goto out; | ||
| 5041 | } | ||
| 5042 | } | 5031 | } |
| 5043 | 5032 | ||
| 5044 | if (!qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP) || | 5033 | if (!qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP) || |
| @@ -287,12 +287,12 @@ static void qeth_l2_stop_card(struct qeth_card *card) · 286 unmodified lines | |||
| 287 | card->state = CARD_STATE_HARDSETUP; | 287 | card->state = CARD_STATE_HARDSETUP; |
| 288 | } | 288 | } |
| 289 | if (card->state == CARD_STATE_HARDSETUP) { | 289 | if (card->state == CARD_STATE_HARDSETUP) { |
| 290 | qeth_qdio_clear_card(card, 0); | ||
| 291 | qeth_drain_output_queues(card); | 290 | qeth_drain_output_queues(card); |
| 292 | qeth_clear_working_pool_list(card); | 291 | qeth_clear_working_pool_list(card); |
| 293 | card->state = CARD_STATE_DOWN; | 292 | card->state = CARD_STATE_DOWN; |
| 294 | } | 293 | } |
| 295 | 294 | ||
| 295 | qeth_qdio_clear_card(card, 0); | ||
| 296 | flush_workqueue(card->event_wq); | 296 | flush_workqueue(card->event_wq); |
| 297 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | 297 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
| 298 | card->info.promisc_mode = 0; | 298 | card->info.promisc_mode = 0; |
| @@ -1952,8 +1952,7 @@ int qeth_l2_vnicc_get_timeout(struct qeth_card *card, u32 *timeout) · 1653 unmodified lines | |||
| 1952 | /* check if VNICC is currently enabled */ | 1952 | /* check if VNICC is currently enabled */ |
| 1953 | bool qeth_l2_vnicc_is_in_use(struct qeth_card *card) | 1953 | bool qeth_l2_vnicc_is_in_use(struct qeth_card *card) |
| 1954 | { | 1954 | { |
| 1955 | /* if everything is turned off, VNICC is not active */ | 1955 | if (!card->options.vnicc.sup_chars) |
| 1956 | if (!card->options.vnicc.cur_chars) | ||
| 1957 | return false; | 1956 | return false; |
| 1958 | /* default values are only OK if rx_bcast was not enabled by user | 1957 | /* default values are only OK if rx_bcast was not enabled by user |
| 1959 | * or the card is offline. | 1958 | * or the card is offline. |
| @@ -2040,8 +2039,9 @@ static void qeth_l2_vnicc_init(struct qeth_card *card) · 80 unmodified lines | |||
| 2040 | /* enforce assumed default values and recover settings, if changed */ | 2039 | /* enforce assumed default values and recover settings, if changed */ |
| 2041 | error |= qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING, | 2040 | error |= qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING, |
| 2042 | timeout); | 2041 | timeout); |
| 2043 | chars_tmp = card->options.vnicc.wanted_chars ^ QETH_VNICC_DEFAULT; | 2042 | /* Change chars, if necessary */ |
| 2044 | chars_tmp |= QETH_VNICC_BRIDGE_INVISIBLE; | 2043 | chars_tmp = card->options.vnicc.wanted_chars ^ |
| 2044 | card->options.vnicc.cur_chars; | ||
| 2045 | chars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE; | 2045 | chars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE; |
| 2046 | for_each_set_bit(i, &chars_tmp, chars_len) { | 2046 | for_each_set_bit(i, &chars_tmp, chars_len) { |
| 2047 | vnicc = BIT(i); | 2047 | vnicc = BIT(i); |
| @@ -1307,12 +1307,12 @@ static void qeth_l3_stop_card(struct qeth_card *card) · 1306 unmodified lines | |||
| 1307 | card->state = CARD_STATE_HARDSETUP; | 1307 | card->state = CARD_STATE_HARDSETUP; |
| 1308 | } | 1308 | } |
| 1309 | if (card->state == CARD_STATE_HARDSETUP) { | 1309 | if (card->state == CARD_STATE_HARDSETUP) { |
| 1310 | qeth_qdio_clear_card(card, 0); | ||
| 1311 | qeth_drain_output_queues(card); | 1310 | qeth_drain_output_queues(card); |
| 1312 | qeth_clear_working_pool_list(card); | 1311 | qeth_clear_working_pool_list(card); |
| 1313 | card->state = CARD_STATE_DOWN; | 1312 | card->state = CARD_STATE_DOWN; |
| 1314 | } | 1313 | } |
| 1315 | 1314 | ||
| 1315 | qeth_qdio_clear_card(card, 0); | ||
| 1316 | flush_workqueue(card->event_wq); | 1316 | flush_workqueue(card->event_wq); |
| 1317 | card->info.promisc_mode = 0; | 1317 | card->info.promisc_mode = 0; |
| 1318 | } | 1318 | } |
| @@ -242,21 +242,33 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, · 241 unmodified lines | |||
| 242 | struct device_attribute *attr, const char *buf, size_t count) | 242 | struct device_attribute *attr, const char *buf, size_t count) |
| 243 | { | 243 | { |
| 244 | struct qeth_card *card = dev_get_drvdata(dev); | 244 | struct qeth_card *card = dev_get_drvdata(dev); |
| 245 | int rc = 0; | ||
| 245 | char *tmp; | 246 | char *tmp; |
| 246 | int rc; | ||
| 247 | 247 | ||
| 248 | if (!IS_IQD(card)) | 248 | if (!IS_IQD(card)) |
| 249 | return -EPERM; | 249 | return -EPERM; |
| 250 | if (card->state != CARD_STATE_DOWN) | 250 | |
| 251 | return -EPERM; | 251 | mutex_lock(&card->conf_mutex); |
| 252 | if (card->options.sniffer) | 252 | if (card->state != CARD_STATE_DOWN) { |
| 253 | return -EPERM; | 253 | rc = -EPERM; |
| 254 | if (card->options.cq == QETH_CQ_NOTAVAILABLE) | 254 | goto out; |
| 255 | return -EPERM; | 255 | } |
| 256 | |||
| 257 | if (card->options.sniffer) { | ||
| 258 | rc = -EPERM; | ||
| 259 | goto out; | ||
| 260 | } | ||
| 261 | |||
| 262 | if (card->options.cq == QETH_CQ_NOTAVAILABLE) { | ||
| 263 | rc = -EPERM; | ||
| 264 | goto out; | ||
| 265 | } | ||
| 256 | 266 | ||
| 257 | tmp = strsep((char **)&buf, "\n"); | 267 | tmp = strsep((char **)&buf, "\n"); |
| 258 | if (strlen(tmp) > 8) | 268 | if (strlen(tmp) > 8) { |
| 259 | return -EINVAL; | 269 | rc = -EINVAL; |
| 270 | goto out; | ||
| 271 | } | ||
| 260 | 272 | ||
| 261 | if (card->options.hsuid[0]) | 273 | if (card->options.hsuid[0]) |
| 262 | /* delete old ip address */ | 274 | /* delete old ip address */ |
| @@ -267,11 +279,13 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, · 4 unmodified lines | |||
| 267 | card->options.hsuid[0] = '\0'; | 279 | card->options.hsuid[0] = '\0'; |
| 268 | memcpy(card->dev->perm_addr, card->options.hsuid, 9); | 280 | memcpy(card->dev->perm_addr, card->options.hsuid, 9); |
| 269 | qeth_configure_cq(card, QETH_CQ_DISABLED); | 281 | qeth_configure_cq(card, QETH_CQ_DISABLED); |
| 270 | return count; | 282 | goto out; |
| 271 | } | 283 | } |
| 272 | 284 | ||
| 273 | if (qeth_configure_cq(card, QETH_CQ_ENABLED)) | 285 | if (qeth_configure_cq(card, QETH_CQ_ENABLED)) { |
| 274 | return -EPERM; | 286 | rc = -EPERM; |
| 287 | goto out; | ||
| 288 | } | ||
| 275 | 289 | ||
| 276 | snprintf(card->options.hsuid, sizeof(card->options.hsuid), | 290 | snprintf(card->options.hsuid, sizeof(card->options.hsuid), |
| 277 | "%-8s", tmp); | 291 | "%-8s", tmp); |
| @@ -280,6 +294,8 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, · 2 unmodified lines | |||
| 280 | 294 | ||
| 281 | rc = qeth_l3_modify_hsuid(card, true); | 295 | rc = qeth_l3_modify_hsuid(card, true); |
| 282 | 296 | ||
| 297 | out: | ||
| 298 | mutex_unlock(&card->conf_mutex); | ||
| 283 | return rc ? rc : count; | 299 | return rc ? rc : count; |
| 284 | } | 300 | } |
| 285 | 301 | ||
| @@ -121,7 +121,8 @@ static inline void cxgbi_device_destroy(struct cxgbi_device *cdev) · 120 unmodified lines | |||
| 121 | "cdev 0x%p, p# %u.\n", cdev, cdev->nports); | 121 | "cdev 0x%p, p# %u.\n", cdev, cdev->nports); |
| 122 | cxgbi_hbas_remove(cdev); | 122 | cxgbi_hbas_remove(cdev); |
| 123 | cxgbi_device_portmap_cleanup(cdev); | 123 | cxgbi_device_portmap_cleanup(cdev); |
| 124 | cxgbi_ppm_release(cdev->cdev2ppm(cdev)); | 124 | if (cdev->cdev2ppm) |
| 125 | cxgbi_ppm_release(cdev->cdev2ppm(cdev)); | ||
| 125 | if (cdev->pmap.max_connect) | 126 | if (cdev->pmap.max_connect) |
| 126 | cxgbi_free_big_mem(cdev->pmap.port_csk); | 127 | cxgbi_free_big_mem(cdev->pmap.port_csk); |
| 127 | kfree(cdev); | 128 | kfree(cdev); |
| @@ -5385,7 +5385,6 @@ static const struct file_operations lpfc_debugfs_ras_log = { · 5384 unmodified lines | |||
| 5385 | .read = lpfc_debugfs_read, | 5385 | .read = lpfc_debugfs_read, |
| 5386 | .release = lpfc_debugfs_ras_log_release, | 5386 | .release = lpfc_debugfs_ras_log_release, |
| 5387 | }; | 5387 | }; |
| 5388 | #endif | ||
| 5389 | 5388 | ||
| 5390 | #undef lpfc_debugfs_op_dumpHBASlim | 5389 | #undef lpfc_debugfs_op_dumpHBASlim |
| 5391 | static const struct file_operations lpfc_debugfs_op_dumpHBASlim = { | 5390 | static const struct file_operations lpfc_debugfs_op_dumpHBASlim = { |
| @@ -5557,7 +5556,7 @@ static const struct file_operations lpfc_idiag_op_extAcc = { · 165 unmodified lines | |||
| 5557 | .write = lpfc_idiag_extacc_write, | 5556 | .write = lpfc_idiag_extacc_write, |
| 5558 | .release = lpfc_idiag_cmd_release, | 5557 | .release = lpfc_idiag_cmd_release, |
| 5559 | }; | 5558 | }; |
| 5560 | 5559 | #endif | |
| 5561 | 5560 | ||
| 5562 | /* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command | 5561 | /* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command |
| 5563 | * @phba: Pointer to HBA context object. | 5562 | * @phba: Pointer to HBA context object. |
| @@ -5883,7 +5883,7 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba) · 5882 unmodified lines | |||
| 5883 | break; | 5883 | break; |
| 5884 | default: | 5884 | default: |
| 5885 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 5885 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
| 5886 | "1804 Invalid asynchrous event code: " | 5886 | "1804 Invalid asynchronous event code: " |
| 5887 | "x%x\n", bf_get(lpfc_trailer_code, | 5887 | "x%x\n", bf_get(lpfc_trailer_code, |
| 5888 | &cq_event->cqe.mcqe_cmpl)); | 5888 | &cq_event->cqe.mcqe_cmpl)); |
| 5889 | break; | 5889 | break; |
| @@ -8555,7 +8555,7 @@ lpfc_sli4_async_mbox_unblock(struct lpfc_hba *phba) · 8554 unmodified lines | |||
| 8555 | psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; | 8555 | psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; |
| 8556 | spin_unlock_irq(&phba->hbalock); | 8556 | spin_unlock_irq(&phba->hbalock); |
| 8557 | 8557 | ||
| 8558 | /* wake up worker thread to post asynchronlous mailbox command */ | 8558 | /* wake up worker thread to post asynchronous mailbox command */ |
| 8559 | lpfc_worker_wake_up(phba); | 8559 | lpfc_worker_wake_up(phba); |
| 8560 | } | 8560 | } |
| 8561 | 8561 | ||
| @@ -8823,7 +8823,7 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, · 261 unmodified lines | |||
| 8823 | return rc; | 8823 | return rc; |
| 8824 | } | 8824 | } |
| 8825 | 8825 | ||
| 8826 | /* Now, interrupt mode asynchrous mailbox command */ | 8826 | /* Now, interrupt mode asynchronous mailbox command */ |
| 8827 | rc = lpfc_mbox_cmd_check(phba, mboxq); | 8827 | rc = lpfc_mbox_cmd_check(phba, mboxq); |
| 8828 | if (rc) { | 8828 | if (rc) { |
| 8829 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 8829 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
| @@ -13112,11 +13112,11 @@ lpfc_cq_event_setup(struct lpfc_hba *phba, void *entry, int size) · 4282 unmodified lines | |||
| 13112 | } | 13112 | } |
| 13113 | 13113 | ||
| 13114 | /** | 13114 | /** |
| 13115 | * lpfc_sli4_sp_handle_async_event - Handle an asynchroous event | 13115 | * lpfc_sli4_sp_handle_async_event - Handle an asynchronous event |
| 13116 | * @phba: Pointer to HBA context object. | 13116 | * @phba: Pointer to HBA context object. |
| 13117 | * @cqe: Pointer to mailbox completion queue entry. | 13117 | * @cqe: Pointer to mailbox completion queue entry. |
| 13118 | * | 13118 | * |
| 13119 | * This routine process a mailbox completion queue entry with asynchrous | 13119 | * This routine process a mailbox completion queue entry with asynchronous |
| 13120 | * event. | 13120 | * event. |
| 13121 | * | 13121 | * |
| 13122 | * Return: true if work posted to worker thread, otherwise false. | 13122 | * Return: true if work posted to worker thread, otherwise false. |
| @@ -13270,7 +13270,7 @@ out_no_mqe_complete: · 147 unmodified lines | |||
| 13270 | * @cqe: Pointer to mailbox completion queue entry. | 13270 | * @cqe: Pointer to mailbox completion queue entry. |
| 13271 | * | 13271 | * |
| 13272 | * This routine process a mailbox completion queue entry, it invokes the | 13272 | * This routine process a mailbox completion queue entry, it invokes the |
| 13273 | * proper mailbox complete handling or asynchrous event handling routine | 13273 | * proper mailbox complete handling or asynchronous event handling routine |
| 13274 | * according to the MCQE's async bit. | 13274 | * according to the MCQE's async bit. |
| 13275 | * | 13275 | * |
| 13276 | * Return: true if work posted to worker thread, otherwise false. | 13276 | * Return: true if work posted to worker thread, otherwise false. |
| @@ -5248,7 +5248,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) · 5247 unmodified lines | |||
| 5248 | &ct->chain_buffer_dma); | 5248 | &ct->chain_buffer_dma); |
| 5249 | if (!ct->chain_buffer) { | 5249 | if (!ct->chain_buffer) { |
| 5250 | ioc_err(ioc, "chain_lookup: pci_pool_alloc failed\n"); | 5250 | ioc_err(ioc, "chain_lookup: pci_pool_alloc failed\n"); |
| 5251 | _base_release_memory_pools(ioc); | ||
| 5252 | goto out; | 5251 | goto out; |
| 5253 | } | 5252 | } |
| 5254 | } | 5253 | } |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
| 10 | #include <linux/of_irq.h> | 10 | #include <linux/of_irq.h> |
| 11 | #include <linux/of_address.h> | 11 | #include <linux/of_address.h> |
| 12 | #include <asm/sifive_l2_cache.h> | 12 | #include <soc/sifive/sifive_l2_cache.h> |
| 13 | 13 | ||
| 14 | #define SIFIVE_L2_DIRECCFIX_LOW 0x100 | 14 | #define SIFIVE_L2_DIRECCFIX_LOW 0x100 |
| 15 | #define SIFIVE_L2_DIRECCFIX_HIGH 0x104 | 15 | #define SIFIVE_L2_DIRECCFIX_HIGH 0x104 |
| @@ -172,9 +172,11 @@ static inline u32 rx_max(struct dw_spi *dws) · 171 unmodified lines | |||
| 172 | 172 | ||
| 173 | static void dw_writer(struct dw_spi *dws) | 173 | static void dw_writer(struct dw_spi *dws) |
| 174 | { | 174 | { |
| 175 | u32 max = tx_max(dws); | 175 | u32 max; |
| 176 | u16 txw = 0; | 176 | u16 txw = 0; |
| 177 | 177 | ||
| 178 | spin_lock(&dws->buf_lock); | ||
| 179 | max = tx_max(dws); | ||
| 178 | while (max--) { | 180 | while (max--) { |
| 179 | /* Set the tx word if the transfer's original "tx" is not null */ | 181 | /* Set the tx word if the transfer's original "tx" is not null */ |
| 180 | if (dws->tx_end - dws->len) { | 182 | if (dws->tx_end - dws->len) { |
| @@ -186,13 +188,16 @@ static void dw_writer(struct dw_spi *dws) · 5 unmodified lines | |||
| 186 | dw_write_io_reg(dws, DW_SPI_DR, txw); | 188 | dw_write_io_reg(dws, DW_SPI_DR, txw); |
| 187 | dws->tx += dws->n_bytes; | 189 | dws->tx += dws->n_bytes; |
| 188 | } | 190 | } |
| 191 | spin_unlock(&dws->buf_lock); | ||
| 189 | } | 192 | } |
| 190 | 193 | ||
| 191 | static void dw_reader(struct dw_spi *dws) | 194 | static void dw_reader(struct dw_spi *dws) |
| 192 | { | 195 | { |
| 193 | u32 max = rx_max(dws); | 196 | u32 max; |
| 194 | u16 rxw; | 197 | u16 rxw; |
| 195 | 198 | ||
| 199 | spin_lock(&dws->buf_lock); | ||
| 200 | max = rx_max(dws); | ||
| 196 | while (max--) { | 201 | while (max--) { |
| 197 | rxw = dw_read_io_reg(dws, DW_SPI_DR); | 202 | rxw = dw_read_io_reg(dws, DW_SPI_DR); |
| 198 | /* Care rx only if the transfer's original "rx" is not null */ | 203 | /* Care rx only if the transfer's original "rx" is not null */ |
| @@ -204,6 +209,7 @@ static void dw_reader(struct dw_spi *dws) · 5 unmodified lines | |||
| 204 | } | 209 | } |
| 205 | dws->rx += dws->n_bytes; | 210 | dws->rx += dws->n_bytes; |
| 206 | } | 211 | } |
| 212 | spin_unlock(&dws->buf_lock); | ||
| 207 | } | 213 | } |
| 208 | 214 | ||
| 209 | static void int_error_stop(struct dw_spi *dws, const char *msg) | 215 | static void int_error_stop(struct dw_spi *dws, const char *msg) |
| @@ -276,18 +282,20 @@ static int dw_spi_transfer_one(struct spi_controller *master, · 66 unmodified lines | |||
| 276 | { | 282 | { |
| 277 | struct dw_spi *dws = spi_controller_get_devdata(master); | 283 | struct dw_spi *dws = spi_controller_get_devdata(master); |
| 278 | struct chip_data *chip = spi_get_ctldata(spi); | 284 | struct chip_data *chip = spi_get_ctldata(spi); |
| 285 | unsigned long flags; | ||
| 279 | u8 imask = 0; | 286 | u8 imask = 0; |
| 280 | u16 txlevel = 0; | 287 | u16 txlevel = 0; |
| 281 | u32 cr0; | 288 | u32 cr0; |
| 282 | int ret; | 289 | int ret; |
| 283 | 290 | ||
| 284 | dws->dma_mapped = 0; | 291 | dws->dma_mapped = 0; |
| 285 | 292 | spin_lock_irqsave(&dws->buf_lock, flags); | |
| 286 | dws->tx = (void *)transfer->tx_buf; | 293 | dws->tx = (void *)transfer->tx_buf; |
| 287 | dws->tx_end = dws->tx + transfer->len; | 294 | dws->tx_end = dws->tx + transfer->len; |
| 288 | dws->rx = transfer->rx_buf; | 295 | dws->rx = transfer->rx_buf; |
| 289 | dws->rx_end = dws->rx + transfer->len; | 296 | dws->rx_end = dws->rx + transfer->len; |
| 290 | dws->len = transfer->len; | 297 | dws->len = transfer->len; |
| 298 | spin_unlock_irqrestore(&dws->buf_lock, flags); | ||
| 291 | 299 | ||
| 292 | spi_enable_chip(dws, 0); | 300 | spi_enable_chip(dws, 0); |
| 293 | 301 | ||
| @@ -471,6 +479,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) · 177 unmodified lines | |||
| 471 | dws->type = SSI_MOTO_SPI; | 479 | dws->type = SSI_MOTO_SPI; |
| 472 | dws->dma_inited = 0; | 480 | dws->dma_inited = 0; |
| 473 | dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); | 481 | dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); |
| 482 | spin_lock_init(&dws->buf_lock); | ||
| 474 | 483 | ||
| 475 | spi_controller_set_devdata(master, dws); | 484 | spi_controller_set_devdata(master, dws); |
| 476 | 485 | ||
| @@ -119,6 +119,7 @@ struct dw_spi { · 118 unmodified lines | |||
| 119 | size_t len; | 119 | size_t len; |
| 120 | void *tx; | 120 | void *tx; |
| 121 | void *tx_end; | 121 | void *tx_end; |
| 122 | spinlock_t buf_lock; | ||
| 122 | void *rx; | 123 | void *rx; |
| 123 | void *rx_end; | 124 | void *rx_end; |
| 124 | int dma_mapped; | 125 | int dma_mapped; |
| @@ -185,6 +185,7 @@ struct fsl_dspi { · 184 unmodified lines | |||
| 185 | struct spi_transfer *cur_transfer; | 185 | struct spi_transfer *cur_transfer; |
| 186 | struct spi_message *cur_msg; | 186 | struct spi_message *cur_msg; |
| 187 | struct chip_data *cur_chip; | 187 | struct chip_data *cur_chip; |
| 188 | size_t progress; | ||
| 188 | size_t len; | 189 | size_t len; |
| 189 | const void *tx; | 190 | const void *tx; |
| 190 | void *rx; | 191 | void *rx; |
| @@ -586,21 +587,14 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi) · 395 unmodified lines | |||
| 586 | dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; | 587 | dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; |
| 587 | 588 | ||
| 588 | if (dspi->devtype_data->xspi_mode && dspi->bits_per_word > 16) { | 589 | if (dspi->devtype_data->xspi_mode && dspi->bits_per_word > 16) { |
| 589 | /* Write two TX FIFO entries first, and then the corresponding | 590 | /* Write the CMD FIFO entry first, and then the two |
| 590 | * CMD FIFO entry. | 591 | * corresponding TX FIFO entries. |
| 591 | */ | 592 | */ |
| 592 | u32 data = dspi_pop_tx(dspi); | 593 | u32 data = dspi_pop_tx(dspi); |
| 593 | 594 | ||
| 594 | if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE) { | ||
| 595 | /* LSB */ | ||
| 596 | tx_fifo_write(dspi, data & 0xFFFF); | ||
| 597 | tx_fifo_write(dspi, data >> 16); | ||
| 598 | } else { | ||
| 599 | /* MSB */ | ||
| 600 | tx_fifo_write(dspi, data >> 16); | ||
| 601 | tx_fifo_write(dspi, data & 0xFFFF); | ||
| 602 | } | ||
| 603 | cmd_fifo_write(dspi); | 595 | cmd_fifo_write(dspi); |
| 596 | tx_fifo_write(dspi, data & 0xFFFF); | ||
| 597 | tx_fifo_write(dspi, data >> 16); | ||
| 604 | } else { | 598 | } else { |
| 605 | /* Write one entry to both TX FIFO and CMD FIFO | 599 | /* Write one entry to both TX FIFO and CMD FIFO |
| 606 | * simultaneously. | 600 | * simultaneously. |
| @@ -658,7 +652,7 @@ static int dspi_rxtx(struct fsl_dspi *dspi) · 51 unmodified lines | |||
| 658 | u32 spi_tcr; | 652 | u32 spi_tcr; |
| 659 | 653 | ||
| 660 | spi_take_timestamp_post(dspi->ctlr, dspi->cur_transfer, | 654 | spi_take_timestamp_post(dspi->ctlr, dspi->cur_transfer, |
| 661 | dspi->tx - dspi->bytes_per_word, !dspi->irq); | 655 | dspi->progress, !dspi->irq); |
| 662 | 656 | ||
| 663 | /* Get transfer counter (in number of SPI transfers). It was | 657 | /* Get transfer counter (in number of SPI transfers). It was |
| 664 | * reset to 0 when transfer(s) were started. | 658 | * reset to 0 when transfer(s) were started. |
| @@ -667,6 +661,7 @@ static int dspi_rxtx(struct fsl_dspi *dspi) · 2 unmodified lines | |||
| 667 | spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr); | 661 | spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr); |
| 668 | /* Update total number of bytes that were transferred */ | 662 | /* Update total number of bytes that were transferred */ |
| 669 | msg->actual_length += spi_tcnt * dspi->bytes_per_word; | 663 | msg->actual_length += spi_tcnt * dspi->bytes_per_word; |
| 664 | dspi->progress += spi_tcnt; | ||
| 670 | 665 | ||
| 671 | trans_mode = dspi->devtype_data->trans_mode; | 666 | trans_mode = dspi->devtype_data->trans_mode; |
| 672 | if (trans_mode == DSPI_EOQ_MODE) | 667 | if (trans_mode == DSPI_EOQ_MODE) |
| @@ -679,7 +674,7 @@ static int dspi_rxtx(struct fsl_dspi *dspi) · 6 unmodified lines | |||
| 679 | return 0; | 674 | return 0; |
| 680 | 675 | ||
| 681 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, | 676 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
| 682 | dspi->tx, !dspi->irq); | 677 | dspi->progress, !dspi->irq); |
| 683 | 678 | ||
| 684 | if (trans_mode == DSPI_EOQ_MODE) | 679 | if (trans_mode == DSPI_EOQ_MODE) |
| 685 | dspi_eoq_write(dspi); | 680 | dspi_eoq_write(dspi); |
| @@ -768,6 +763,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, · 82 unmodified lines | |||
| 768 | dspi->rx = transfer->rx_buf; | 763 | dspi->rx = transfer->rx_buf; |
| 769 | dspi->rx_end = dspi->rx + transfer->len; | 764 | dspi->rx_end = dspi->rx + transfer->len; |
| 770 | dspi->len = transfer->len; | 765 | dspi->len = transfer->len; |
| 766 | dspi->progress = 0; | ||
| 771 | /* Validated transfer specific frame size (defaults applied) */ | 767 | /* Validated transfer specific frame size (defaults applied) */ |
| 772 | dspi->bits_per_word = transfer->bits_per_word; | 768 | dspi->bits_per_word = transfer->bits_per_word; |
| 773 | if (transfer->bits_per_word <= 8) | 769 | if (transfer->bits_per_word <= 8) |
| @@ -789,7 +785,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, · 15 unmodified lines | |||
| 789 | SPI_CTARE_DTCP(1)); | 785 | SPI_CTARE_DTCP(1)); |
| 790 | 786 | ||
| 791 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, | 787 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
| 792 | dspi->tx, !dspi->irq); | 788 | dspi->progress, !dspi->irq); |
| 793 | 789 | ||
| 794 | trans_mode = dspi->devtype_data->trans_mode; | 790 | trans_mode = dspi->devtype_data->trans_mode; |
| 795 | switch (trans_mode) { | 791 | switch (trans_mode) { |
| @@ -290,25 +290,32 @@ static void uniphier_spi_recv(struct uniphier_spi_priv *priv) · 289 unmodified lines | |||
| 290 | } | 290 | } |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv) | 293 | static void uniphier_spi_set_fifo_threshold(struct uniphier_spi_priv *priv, |
| 294 | unsigned int threshold) | ||
| 294 | { | 295 | { |
| 295 | unsigned int fifo_threshold, fill_bytes; | ||
| 296 | u32 val; | 296 | u32 val; |
| 297 | 297 | ||
| 298 | fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, | ||
| 299 | bytes_per_word(priv->bits_per_word)); | ||
| 300 | fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH); | ||
| 301 | |||
| 302 | fill_bytes = fifo_threshold - (priv->rx_bytes - priv->tx_bytes); | ||
| 303 | |||
| 304 | /* set fifo threshold */ | ||
| 305 | val = readl(priv->base + SSI_FC); | 298 | val = readl(priv->base + SSI_FC); |
| 306 | val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK); | 299 | val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK); |
| 307 | val |= FIELD_PREP(SSI_FC_TXFTH_MASK, fifo_threshold); | 300 | val |= FIELD_PREP(SSI_FC_TXFTH_MASK, SSI_FIFO_DEPTH - threshold); |
| 308 | val |= FIELD_PREP(SSI_FC_RXFTH_MASK, fifo_threshold); | 301 | val |= FIELD_PREP(SSI_FC_RXFTH_MASK, threshold); |
| 309 | writel(val, priv->base + SSI_FC); | 302 | writel(val, priv->base + SSI_FC); |
| 303 | } | ||
| 304 | |||
| 305 | static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv) | ||
| 306 | { | ||
| 307 | unsigned int fifo_threshold, fill_words; | ||
| 308 | unsigned int bpw = bytes_per_word(priv->bits_per_word); | ||
| 309 | |||
| 310 | fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, bpw); | ||
| 311 | fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH); | ||
| 312 | |||
| 313 | uniphier_spi_set_fifo_threshold(priv, fifo_threshold); | ||
| 314 | |||
| 315 | fill_words = fifo_threshold - | ||
| 316 | DIV_ROUND_UP(priv->rx_bytes - priv->tx_bytes, bpw); | ||
| 310 | 317 | ||
| 311 | while (fill_bytes--) | 318 | while (fill_words--) |
| 312 | uniphier_spi_send(priv); | 319 | uniphier_spi_send(priv); |
| 313 | } | 320 | } |
| 314 | 321 | ||
| @@ -1499,8 +1499,7 @@ static void spi_pump_messages(struct kthread_work *work) · 1498 unmodified lines | |||
| 1499 | * advances its @tx buffer pointer monotonically. | 1499 | * advances its @tx buffer pointer monotonically. |
| 1500 | * @ctlr: Pointer to the spi_controller structure of the driver | 1500 | * @ctlr: Pointer to the spi_controller structure of the driver |
| 1501 | * @xfer: Pointer to the transfer being timestamped | 1501 | * @xfer: Pointer to the transfer being timestamped |
| 1502 | * @tx: Pointer to the current word within the xfer->tx_buf that the driver is | 1502 | * @progress: How many words (not bytes) have been transferred so far |
| 1503 | * preparing to transmit right now. | ||
| 1504 | * @irqs_off: If true, will disable IRQs and preemption for the duration of the | 1503 | * @irqs_off: If true, will disable IRQs and preemption for the duration of the |
| 1505 | * transfer, for less jitter in time measurement. Only compatible | 1504 | * transfer, for less jitter in time measurement. Only compatible |
| 1506 | * with PIO drivers. If true, must follow up with | 1505 | * with PIO drivers. If true, must follow up with |
| @@ -1510,21 +1509,19 @@ static void spi_pump_messages(struct kthread_work *work) · 3 unmodified lines | |||
| 1510 | */ | 1509 | */ |
| 1511 | void spi_take_timestamp_pre(struct spi_controller *ctlr, | 1510 | void spi_take_timestamp_pre(struct spi_controller *ctlr, |
| 1512 | struct spi_transfer *xfer, | 1511 | struct spi_transfer *xfer, |
| 1513 | const void *tx, bool irqs_off) | 1512 | size_t progress, bool irqs_off) |
| 1514 | { | 1513 | { |
| 1515 | u8 bytes_per_word = DIV_ROUND_UP(xfer->bits_per_word, 8); | ||
| 1516 | |||
| 1517 | if (!xfer->ptp_sts) | 1514 | if (!xfer->ptp_sts) |
| 1518 | return; | 1515 | return; |
| 1519 | 1516 | ||
| 1520 | if (xfer->timestamped_pre) | 1517 | if (xfer->timestamped_pre) |
| 1521 | return; | 1518 | return; |
| 1522 | 1519 | ||
| 1523 | if (tx < (xfer->tx_buf + xfer->ptp_sts_word_pre * bytes_per_word)) | 1520 | if (progress < xfer->ptp_sts_word_pre) |
| 1524 | return; | 1521 | return; |
| 1525 | 1522 | ||
| 1526 | /* Capture the resolution of the timestamp */ | 1523 | /* Capture the resolution of the timestamp */ |
| 1527 | xfer->ptp_sts_word_pre = (tx - xfer->tx_buf) / bytes_per_word; | 1524 | xfer->ptp_sts_word_pre = progress; |
| 1528 | 1525 | ||
| 1529 | xfer->timestamped_pre = true; | 1526 | xfer->timestamped_pre = true; |
| 1530 | 1527 | ||
| @@ -1546,23 +1543,20 @@ EXPORT_SYMBOL_GPL(spi_take_timestamp_pre); · 15 unmodified lines | |||
| 1546 | * timestamped. | 1543 | * timestamped. |
| 1547 | * @ctlr: Pointer to the spi_controller structure of the driver | 1544 | * @ctlr: Pointer to the spi_controller structure of the driver |
| 1548 | * @xfer: Pointer to the transfer being timestamped | 1545 | * @xfer: Pointer to the transfer being timestamped |
| 1549 | * @tx: Pointer to the current word within the xfer->tx_buf that the driver has | 1546 | * @progress: How many words (not bytes) have been transferred so far |
| 1550 | * just transmitted. | ||
| 1551 | * @irqs_off: If true, will re-enable IRQs and preemption for the local CPU. | 1547 | * @irqs_off: If true, will re-enable IRQs and preemption for the local CPU. |
| 1552 | */ | 1548 | */ |
| 1553 | void spi_take_timestamp_post(struct spi_controller *ctlr, | 1549 | void spi_take_timestamp_post(struct spi_controller *ctlr, |
| 1554 | struct spi_transfer *xfer, | 1550 | struct spi_transfer *xfer, |
| 1555 | const void *tx, bool irqs_off) | 1551 | size_t progress, bool irqs_off) |
| 1556 | { | 1552 | { |
| 1557 | u8 bytes_per_word = DIV_ROUND_UP(xfer->bits_per_word, 8); | ||
| 1558 | |||
| 1559 | if (!xfer->ptp_sts) | 1553 | if (!xfer->ptp_sts) |
| 1560 | return; | 1554 | return; |
| 1561 | 1555 | ||
| 1562 | if (xfer->timestamped_post) | 1556 | if (xfer->timestamped_post) |
| 1563 | return; | 1557 | return; |
| 1564 | 1558 | ||
| 1565 | if (tx < (xfer->tx_buf + xfer->ptp_sts_word_post * bytes_per_word)) | 1559 | if (progress < xfer->ptp_sts_word_post) |
| 1566 | return; | 1560 | return; |
| 1567 | 1561 | ||
| 1568 | ptp_read_system_postts(xfer->ptp_sts); | 1562 | ptp_read_system_postts(xfer->ptp_sts); |
| @@ -1573,7 +1567,7 @@ void spi_take_timestamp_post(struct spi_controller *ctlr, · 4 unmodified lines | |||
| 1573 | } | 1567 | } |
| 1574 | 1568 | ||
| 1575 | /* Capture the resolution of the timestamp */ | 1569 | /* Capture the resolution of the timestamp */ |
| 1576 | xfer->ptp_sts_word_post = (tx - xfer->tx_buf) / bytes_per_word; | 1570 | xfer->ptp_sts_word_post = progress; |
| 1577 | 1571 | ||
| 1578 | xfer->timestamped_post = true; | 1572 | xfer->timestamped_post = true; |
| 1579 | } | 1573 | } |
| @@ -46,8 +46,8 @@ · 45 unmodified lines | |||
| 46 | #define PCI171X_RANGE_UNI BIT(4) | 46 | #define PCI171X_RANGE_UNI BIT(4) |
| 47 | #define PCI171X_RANGE_GAIN(x) (((x) & 0x7) << 0) | 47 | #define PCI171X_RANGE_GAIN(x) (((x) & 0x7) << 0) |
| 48 | #define PCI171X_MUX_REG 0x04 /* W: A/D multiplexor control */ | 48 | #define PCI171X_MUX_REG 0x04 /* W: A/D multiplexor control */ |
| 49 | #define PCI171X_MUX_CHANH(x) (((x) & 0xf) << 8) | 49 | #define PCI171X_MUX_CHANH(x) (((x) & 0xff) << 8) |
| 50 | #define PCI171X_MUX_CHANL(x) (((x) & 0xf) << 0) | 50 | #define PCI171X_MUX_CHANL(x) (((x) & 0xff) << 0) |
| 51 | #define PCI171X_MUX_CHAN(x) (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x)) | 51 | #define PCI171X_MUX_CHAN(x) (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x)) |
| 52 | #define PCI171X_STATUS_REG 0x06 /* R: status register */ | 52 | #define PCI171X_STATUS_REG 0x06 /* R: status register */ |
| 53 | #define PCI171X_STATUS_IRQ BIT(11) /* 1=IRQ occurred */ | 53 | #define PCI171X_STATUS_IRQ BIT(11) /* 1=IRQ occurred */ |
| @@ -449,7 +449,7 @@ struct ipu3_uapi_awb_fr_config_s { · 448 unmodified lines | |||
| 449 | __u16 reserved1; | 449 | __u16 reserved1; |
| 450 | __u32 bayer_sign; | 450 | __u32 bayer_sign; |
| 451 | __u8 bayer_nf; | 451 | __u8 bayer_nf; |
| 452 | __u8 reserved2[3]; | 452 | __u8 reserved2[7]; |
| 453 | } __attribute__((aligned(32))) __packed; | 453 | } __attribute__((aligned(32))) __packed; |
| 454 | 454 | ||
| 455 | /** | 455 | /** |
| @@ -37,6 +37,7 @@ static const struct usb_device_id rtw_usb_id_tbl[] = { · 36 unmodified lines | |||
| 37 | {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */ | 37 | {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */ |
| 38 | {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ | 38 | {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ |
| 39 | {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ | 39 | {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ |
| 40 | {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */ | ||
| 40 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ | 41 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ |
| 41 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */ | 42 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */ |
| 42 | {} /* Terminating entry */ | 43 | {} /* Terminating entry */ |
| @@ -449,8 +449,8 @@ int vnt_vt3184_init(struct vnt_private *priv) · 448 unmodified lines | |||
| 449 | 449 | ||
| 450 | memcpy(array, addr, length); | 450 | memcpy(array, addr, length); |
| 451 | 451 | ||
| 452 | ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0, | 452 | ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, |
| 453 | MESSAGE_REQUEST_BBREG, length, array); | 453 | MESSAGE_REQUEST_BBREG, length, array); |
| 454 | if (ret) | 454 | if (ret) |
| 455 | goto end; | 455 | goto end; |
| 456 | 456 | ||
| @@ -719,7 +719,7 @@ end: · 718 unmodified lines | |||
| 719 | */ | 719 | */ |
| 720 | int vnt_radio_power_on(struct vnt_private *priv) | 720 | int vnt_radio_power_on(struct vnt_private *priv) |
| 721 | { | 721 | { |
| 722 | int ret = true; | 722 | int ret = 0; |
| 723 | 723 | ||
| 724 | vnt_exit_deep_sleep(priv); | 724 | vnt_exit_deep_sleep(priv); |
| 725 | 725 | ||
| @@ -259,6 +259,7 @@ struct vnt_private { · 258 unmodified lines | |||
| 259 | u8 mac_hw; | 259 | u8 mac_hw; |
| 260 | /* netdev */ | 260 | /* netdev */ |
| 261 | struct usb_device *usb; | 261 | struct usb_device *usb; |
| 262 | struct usb_interface *intf; | ||
| 262 | 263 | ||
| 263 | u64 tsf_time; | 264 | u64 tsf_time; |
| 264 | u8 rx_rate; | 265 | u8 rx_rate; |
| @@ -949,7 +949,7 @@ static const struct ieee80211_ops vnt_mac_ops = { · 948 unmodified lines | |||
| 949 | 949 | ||
| 950 | int vnt_init(struct vnt_private *priv) | 950 | int vnt_init(struct vnt_private *priv) |
| 951 | { | 951 | { |
| 952 | if (!(vnt_init_registers(priv))) | 952 | if (vnt_init_registers(priv)) |
| 953 | return -EAGAIN; | 953 | return -EAGAIN; |
| 954 | 954 | ||
| 955 | SET_IEEE80211_PERM_ADDR(priv->hw, priv->permanent_net_addr); | 955 | SET_IEEE80211_PERM_ADDR(priv->hw, priv->permanent_net_addr); |
| @@ -992,6 +992,7 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id) · 36 unmodified lines | |||
| 992 | priv = hw->priv; | 992 | priv = hw->priv; |
| 993 | priv->hw = hw; | 993 | priv->hw = hw; |
| 994 | priv->usb = udev; | 994 | priv->usb = udev; |
| 995 | priv->intf = intf; | ||
| 995 | 996 | ||
| 996 | vnt_set_options(priv); | 997 | vnt_set_options(priv); |
| 997 | 998 | ||
| @@ -59,7 +59,9 @@ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, · 58 unmodified lines | |||
| 59 | 59 | ||
| 60 | kfree(usb_buffer); | 60 | kfree(usb_buffer); |
| 61 | 61 | ||
| 62 | if (ret >= 0 && ret < (int)length) | 62 | if (ret == (int)length) |
| 63 | ret = 0; | ||
| 64 | else | ||
| 63 | ret = -EIO; | 65 | ret = -EIO; |
| 64 | 66 | ||
| 65 | end_unlock: | 67 | end_unlock: |
| @@ -74,6 +76,23 @@ int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data) · 8 unmodified lines | |||
| 74 | reg_off, reg, sizeof(u8), &data); | 76 | reg_off, reg, sizeof(u8), &data); |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 79 | int vnt_control_out_blocks(struct vnt_private *priv, | ||
| 80 | u16 block, u8 reg, u16 length, u8 *data) | ||
| 81 | { | ||
| 82 | int ret = 0, i; | ||
| 83 | |||
| 84 | for (i = 0; i < length; i += block) { | ||
| 85 | u16 len = min_t(int, length - i, block); | ||
| 86 | |||
| 87 | ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, | ||
| 88 | i, reg, len, data + i); | ||
| 89 | if (ret) | ||
| 90 | goto end; | ||
| 91 | } | ||
| 92 | end: | ||
| 93 | return ret; | ||
| 94 | } | ||
| 95 | |||
| 77 | int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, | 96 | int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, |
| 78 | u16 index, u16 length, u8 *buffer) | 97 | u16 index, u16 length, u8 *buffer) |
| 79 | { | 98 | { |
| @@ -103,7 +122,9 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, · 23 unmodified lines | |||
| 103 | 122 | ||
| 104 | kfree(usb_buffer); | 123 | kfree(usb_buffer); |
| 105 | 124 | ||
| 106 | if (ret >= 0 && ret < (int)length) | 125 | if (ret == (int)length) |
| 126 | ret = 0; | ||
| 127 | else | ||
| 107 | ret = -EIO; | 128 | ret = -EIO; |
| 108 | 129 | ||
| 109 | end_unlock: | 130 | end_unlock: |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #include "device.h" | 19 | #include "device.h" |
| 20 | 20 | ||
| 21 | #define VNT_REG_BLOCK_SIZE 64 | ||
| 22 | |||
| 21 | int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, | 23 | int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, |
| 22 | u16 index, u16 length, u8 *buffer); | 24 | u16 index, u16 length, u8 *buffer); |
| 23 | int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, | 25 | int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, |
| @@ -26,6 +28,9 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, · 2 unmodified lines | |||
| 26 | int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 ref_off, u8 data); | 28 | int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 ref_off, u8 data); |
| 27 | int vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data); | 29 | int vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data); |
| 28 | 30 | ||
| 31 | int vnt_control_out_blocks(struct vnt_private *priv, | ||
| 32 | u16 block, u8 reg, u16 len, u8 *data); | ||
| 33 | |||
| 29 | int vnt_start_interrupt_urb(struct vnt_private *priv); | 34 | int vnt_start_interrupt_urb(struct vnt_private *priv); |
| 30 | int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb); | 35 | int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb); |
| 31 | int vnt_tx_context(struct vnt_private *priv, | 36 | int vnt_tx_context(struct vnt_private *priv, |
| @@ -99,6 +99,7 @@ void vnt_run_command(struct work_struct *work) · 98 unmodified lines | |||
| 99 | if (vnt_init(priv)) { | 99 | if (vnt_init(priv)) { |
| 100 | /* If fail all ends TODO retry */ | 100 | /* If fail all ends TODO retry */ |
| 101 | dev_err(&priv->usb->dev, "failed to start\n"); | 101 | dev_err(&priv->usb->dev, "failed to start\n"); |
| 102 | usb_set_intfdata(priv->intf, NULL); | ||
| 102 | ieee80211_free_hw(priv->hw); | 103 | ieee80211_free_hw(priv->hw); |
| 103 | return; | 104 | return; |
| 104 | } | 105 | } |
| @@ -646,7 +646,9 @@ iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio, · 645 unmodified lines | |||
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio)); | 648 | bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio)); |
| 649 | bip_set_seed(bip, bio->bi_iter.bi_sector); | 649 | /* virtual start sector must be in integrity interval units */ |
| 650 | bip_set_seed(bip, bio->bi_iter.bi_sector >> | ||
| 651 | (bi->interval_exp - SECTOR_SHIFT)); | ||
| 650 | 652 | ||
| 651 | pr_debug("IBLOCK BIP Size: %u Sector: %llu\n", bip->bip_iter.bi_size, | 653 | pr_debug("IBLOCK BIP Size: %u Sector: %llu\n", bip->bip_iter.bi_size, |
| 652 | (unsigned long long)bip->bip_iter.bi_sector); | 654 | (unsigned long long)bip->bip_iter.bi_sector); |
| @@ -110,6 +110,9 @@ static int tsens_register(struct tsens_priv *priv) · 109 unmodified lines | |||
| 110 | irq = platform_get_irq_byname(pdev, "uplow"); | 110 | irq = platform_get_irq_byname(pdev, "uplow"); |
| 111 | if (irq < 0) { | 111 | if (irq < 0) { |
| 112 | ret = irq; | 112 | ret = irq; |
| 113 | /* For old DTs with no IRQ defined */ | ||
| 114 | if (irq == -ENXIO) | ||
| 115 | ret = 0; | ||
| 113 | goto err_put_device; | 116 | goto err_put_device; |
| 114 | } | 117 | } |
| 115 | 118 | ||
| @@ -663,6 +663,12 @@ static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl, · 662 unmodified lines | |||
| 663 | return AE_OK; | 663 | return AE_OK; |
| 664 | } | 664 | } |
| 665 | 665 | ||
| 666 | static const struct acpi_device_id serdev_acpi_devices_blacklist[] = { | ||
| 667 | { "INT3511", 0 }, | ||
| 668 | { "INT3512", 0 }, | ||
| 669 | { }, | ||
| 670 | }; | ||
| 671 | |||
| 666 | static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, | 672 | static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, |
| 667 | void *data, void **return_value) | 673 | void *data, void **return_value) |
| 668 | { | 674 | { |
| @@ -675,6 +681,10 @@ static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, · 6 unmodified lines | |||
| 675 | if (acpi_device_enumerated(adev)) | 681 | if (acpi_device_enumerated(adev)) |
| 676 | return AE_OK; | 682 | return AE_OK; |
| 677 | 683 | ||
| 684 | /* Skip if black listed */ | ||
| 685 | if (!acpi_match_device_ids(adev, serdev_acpi_devices_blacklist)) | ||
| 686 | return AE_OK; | ||
| 687 | |||
| 678 | if (acpi_serdev_check_resources(ctrl, adev)) | 688 | if (acpi_serdev_check_resources(ctrl, adev)) |
| 679 | return AE_OK; | 689 | return AE_OK; |
| 680 | 690 | ||
| @@ -89,8 +89,7 @@ void tty_port_link_device(struct tty_port *port, · 88 unmodified lines | |||
| 89 | { | 89 | { |
| 90 | if (WARN_ON(index >= driver->num)) | 90 | if (WARN_ON(index >= driver->num)) |
| 91 | return; | 91 | return; |
| 92 | if (!driver->ports[index]) | 92 | driver->ports[index] = port; |
| 93 | driver->ports[index] = port; | ||
| 94 | } | 93 | } |
| 95 | EXPORT_SYMBOL_GPL(tty_port_link_device); | 94 | EXPORT_SYMBOL_GPL(tty_port_link_device); |
| 96 | 95 | ||
| @@ -1375,13 +1375,10 @@ static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev, · 1374 unmodified lines | |||
| 1375 | */ | 1375 | */ |
| 1376 | static irqreturn_t cdns3_device_irq_handler(int irq, void *data) | 1376 | static irqreturn_t cdns3_device_irq_handler(int irq, void *data) |
| 1377 | { | 1377 | { |
| 1378 | struct cdns3_device *priv_dev; | 1378 | struct cdns3_device *priv_dev = data; |
| 1379 | struct cdns3 *cdns = data; | ||
| 1380 | irqreturn_t ret = IRQ_NONE; | 1379 | irqreturn_t ret = IRQ_NONE; |
| 1381 | u32 reg; | 1380 | u32 reg; |
| 1382 | 1381 | ||
| 1383 | priv_dev = cdns->gadget_dev; | ||
| 1384 | |||
| 1385 | /* check USB device interrupt */ | 1382 | /* check USB device interrupt */ |
| 1386 | reg = readl(&priv_dev->regs->usb_ists); | 1383 | reg = readl(&priv_dev->regs->usb_ists); |
| 1387 | if (reg) { | 1384 | if (reg) { |
| @@ -1419,14 +1416,12 @@ static irqreturn_t cdns3_device_irq_handler(int irq, void *data) · 31 unmodified lines | |||
| 1419 | */ | 1416 | */ |
| 1420 | static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data) | 1417 | static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data) |
| 1421 | { | 1418 | { |
| 1422 | struct cdns3_device *priv_dev; | 1419 | struct cdns3_device *priv_dev = data; |
| 1423 | struct cdns3 *cdns = data; | ||
| 1424 | irqreturn_t ret = IRQ_NONE; | 1420 | irqreturn_t ret = IRQ_NONE; |
| 1425 | unsigned long flags; | 1421 | unsigned long flags; |
| 1426 | int bit; | 1422 | int bit; |
| 1427 | u32 reg; | 1423 | u32 reg; |
| 1428 | 1424 | ||
| 1429 | priv_dev = cdns->gadget_dev; | ||
| 1430 | spin_lock_irqsave(&priv_dev->lock, flags); | 1425 | spin_lock_irqsave(&priv_dev->lock, flags); |
| 1431 | 1426 | ||
| 1432 | reg = readl(&priv_dev->regs->usb_ists); | 1427 | reg = readl(&priv_dev->regs->usb_ists); |
| @@ -2538,7 +2533,7 @@ void cdns3_gadget_exit(struct cdns3 *cdns) · 1105 unmodified lines | |||
| 2538 | 2533 | ||
| 2539 | priv_dev = cdns->gadget_dev; | 2534 | priv_dev = cdns->gadget_dev; |
| 2540 | 2535 | ||
| 2541 | devm_free_irq(cdns->dev, cdns->dev_irq, cdns); | 2536 | devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev); |
| 2542 | 2537 | ||
| 2543 | pm_runtime_mark_last_busy(cdns->dev); | 2538 | pm_runtime_mark_last_busy(cdns->dev); |
| 2544 | pm_runtime_put_autosuspend(cdns->dev); | 2539 | pm_runtime_put_autosuspend(cdns->dev); |
| @@ -2709,7 +2704,8 @@ static int __cdns3_gadget_init(struct cdns3 *cdns) · 164 unmodified lines | |||
| 2709 | ret = devm_request_threaded_irq(cdns->dev, cdns->dev_irq, | 2704 | ret = devm_request_threaded_irq(cdns->dev, cdns->dev_irq, |
| 2710 | cdns3_device_irq_handler, | 2705 | cdns3_device_irq_handler, |
| 2711 | cdns3_device_thread_irq_handler, | 2706 | cdns3_device_thread_irq_handler, |
| 2712 | IRQF_SHARED, dev_name(cdns->dev), cdns); | 2707 | IRQF_SHARED, dev_name(cdns->dev), |
| 2708 | cdns->gadget_dev); | ||
| 2713 | 2709 | ||
| 2714 | if (ret) | 2710 | if (ret) |
| 2715 | goto err0; | 2711 | goto err0; |
| @@ -26,6 +26,7 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd); · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | struct ehci_ci_priv { | 27 | struct ehci_ci_priv { |
| 28 | struct regulator *reg_vbus; | 28 | struct regulator *reg_vbus; |
| 29 | bool enabled; | ||
| 29 | }; | 30 | }; |
| 30 | 31 | ||
| 31 | static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) | 32 | static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) |
| @@ -37,7 +38,7 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) · 5 unmodified lines | |||
| 37 | int ret = 0; | 38 | int ret = 0; |
| 38 | int port = HCS_N_PORTS(ehci->hcs_params); | 39 | int port = HCS_N_PORTS(ehci->hcs_params); |
| 39 | 40 | ||
| 40 | if (priv->reg_vbus) { | 41 | if (priv->reg_vbus && enable != priv->enabled) { |
| 41 | if (port > 1) { | 42 | if (port > 1) { |
| 42 | dev_warn(dev, | 43 | dev_warn(dev, |
| 43 | "Not support multi-port regulator control\n"); | 44 | "Not support multi-port regulator control\n"); |
| @@ -53,6 +54,7 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) · 9 unmodified lines | |||
| 53 | enable ? "enable" : "disable", ret); | 54 | enable ? "enable" : "disable", ret); |
| 54 | return ret; | 55 | return ret; |
| 55 | } | 56 | } |
| 57 | priv->enabled = enable; | ||
| 56 | } | 58 | } |
| 57 | 59 | ||
| 58 | if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) { | 60 | if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) { |
| @@ -203,9 +203,58 @@ static const unsigned short super_speed_maxpacket_maxes[4] = { · 202 unmodified lines | |||
| 203 | [USB_ENDPOINT_XFER_INT] = 1024, | 203 | [USB_ENDPOINT_XFER_INT] = 1024, |
| 204 | }; | 204 | }; |
| 205 | 205 | ||
| 206 | static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | 206 | static bool endpoint_is_duplicate(struct usb_endpoint_descriptor *e1, |
| 207 | int asnum, struct usb_host_interface *ifp, int num_ep, | 207 | struct usb_endpoint_descriptor *e2) |
| 208 | unsigned char *buffer, int size) | 208 | { |
| 209 | if (e1->bEndpointAddress == e2->bEndpointAddress) | ||
| 210 | return true; | ||
| 211 | |||
| 212 | if (usb_endpoint_xfer_control(e1) || usb_endpoint_xfer_control(e2)) { | ||
| 213 | if (usb_endpoint_num(e1) == usb_endpoint_num(e2)) | ||
| 214 | return true; | ||
| 215 | } | ||
| 216 | |||
| 217 | return false; | ||
| 218 | } | ||
| 219 | |||
| 220 | /* | ||
| 221 | * Check for duplicate endpoint addresses in other interfaces and in the | ||
| 222 | * altsetting currently being parsed. | ||
| 223 | */ | ||
| 224 | static bool config_endpoint_is_duplicate(struct usb_host_config *config, | ||
| 225 | int inum, int asnum, struct usb_endpoint_descriptor *d) | ||
| 226 | { | ||
| 227 | struct usb_endpoint_descriptor *epd; | ||
| 228 | struct usb_interface_cache *intfc; | ||
| 229 | struct usb_host_interface *alt; | ||
| 230 | int i, j, k; | ||
| 231 | |||
| 232 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { | ||
| 233 | intfc = config->intf_cache[i]; | ||
| 234 | |||
| 235 | for (j = 0; j < intfc->num_altsetting; ++j) { | ||
| 236 | alt = &intfc->altsetting[j]; | ||
| 237 | |||
| 238 | if (alt->desc.bInterfaceNumber == inum && | ||
| 239 | alt->desc.bAlternateSetting != asnum) | ||
| 240 | continue; | ||
| 241 | |||
| 242 | for (k = 0; k < alt->desc.bNumEndpoints; ++k) { | ||
| 243 | epd = &alt->endpoint[k].desc; | ||
| 244 | |||
| 245 | if (endpoint_is_duplicate(epd, d)) | ||
| 246 | return true; | ||
| 247 | } | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 251 | return false; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int usb_parse_endpoint(struct device *ddev, int cfgno, | ||
| 255 | struct usb_host_config *config, int inum, int asnum, | ||
| 256 | struct usb_host_interface *ifp, int num_ep, | ||
| 257 | unsigned char *buffer, int size) | ||
| 209 | { | 258 | { |
| 210 | unsigned char *buffer0 = buffer; | 259 | unsigned char *buffer0 = buffer; |
| 211 | struct usb_endpoint_descriptor *d; | 260 | struct usb_endpoint_descriptor *d; |
| @@ -242,13 +291,10 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, · 30 unmodified lines | |||
| 242 | goto skip_to_next_endpoint_or_interface_descriptor; | 291 | goto skip_to_next_endpoint_or_interface_descriptor; |
| 243 | 292 | ||
| 244 | /* Check for duplicate endpoint addresses */ | 293 | /* Check for duplicate endpoint addresses */ |
| 245 | for (i = 0; i < ifp->desc.bNumEndpoints; ++i) { | 294 | if (config_endpoint_is_duplicate(config, inum, asnum, d)) { |
| 246 | if (ifp->endpoint[i].desc.bEndpointAddress == | 295 | dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", |
| 247 | d->bEndpointAddress) { | 296 | cfgno, inum, asnum, d->bEndpointAddress); |
| 248 | dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", | 297 | goto skip_to_next_endpoint_or_interface_descriptor; |
| 249 | cfgno, inum, asnum, d->bEndpointAddress); | ||
| 250 | goto skip_to_next_endpoint_or_interface_descriptor; | ||
| 251 | } | ||
| 252 | } | 298 | } |
| 253 | 299 | ||
| 254 | endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; | 300 | endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; |
| @@ -346,12 +392,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, · 91 unmodified lines | |||
| 346 | endpoint->desc.wMaxPacketSize = cpu_to_le16(8); | 392 | endpoint->desc.wMaxPacketSize = cpu_to_le16(8); |
| 347 | } | 393 | } |
| 348 | 394 | ||
| 349 | /* Validate the wMaxPacketSize field */ | 395 | /* |
| 396 | * Validate the wMaxPacketSize field. | ||
| 397 | * Some devices have isochronous endpoints in altsetting 0; | ||
| 398 | * the USB-2 spec requires such endpoints to have wMaxPacketSize = 0 | ||
| 399 | * (see the end of section 5.6.3), so don't warn about them. | ||
| 400 | */ | ||
| 350 | maxp = usb_endpoint_maxp(&endpoint->desc); | 401 | maxp = usb_endpoint_maxp(&endpoint->desc); |
| 351 | if (maxp == 0) { | 402 | if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) { |
| 352 | dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has wMaxPacketSize 0, skipping\n", | 403 | dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n", |
| 353 | cfgno, inum, asnum, d->bEndpointAddress); | 404 | cfgno, inum, asnum, d->bEndpointAddress); |
| 354 | goto skip_to_next_endpoint_or_interface_descriptor; | ||
| 355 | } | 405 | } |
| 356 | 406 | ||
| 357 | /* Find the highest legal maxpacket size for this endpoint */ | 407 | /* Find the highest legal maxpacket size for this endpoint */ |
| @@ -522,8 +572,8 @@ static int usb_parse_interface(struct device *ddev, int cfgno, · 164 unmodified lines | |||
| 522 | if (((struct usb_descriptor_header *) buffer)->bDescriptorType | 572 | if (((struct usb_descriptor_header *) buffer)->bDescriptorType |
| 523 | == USB_DT_INTERFACE) | 573 | == USB_DT_INTERFACE) |
| 524 | break; | 574 | break; |
| 525 | retval = usb_parse_endpoint(ddev, cfgno, inum, asnum, alt, | 575 | retval = usb_parse_endpoint(ddev, cfgno, config, inum, asnum, |
| 526 | num_ep, buffer, size); | 576 | alt, num_ep, buffer, size); |
| 527 | if (retval < 0) | 577 | if (retval < 0) |
| 528 | return retval; | 578 | return retval; |
| 529 | ++n; | 579 | ++n; |
| @@ -2692,7 +2692,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub) · 2691 unmodified lines | |||
| 2692 | #define SET_ADDRESS_TRIES 2 | 2692 | #define SET_ADDRESS_TRIES 2 |
| 2693 | #define GET_DESCRIPTOR_TRIES 2 | 2693 | #define GET_DESCRIPTOR_TRIES 2 |
| 2694 | #define SET_CONFIG_TRIES (2 * (use_both_schemes + 1)) | 2694 | #define SET_CONFIG_TRIES (2 * (use_both_schemes + 1)) |
| 2695 | #define USE_NEW_SCHEME(i, scheme) ((i) / 2 == (int)scheme) | 2695 | #define USE_NEW_SCHEME(i, scheme) ((i) / 2 == (int)(scheme)) |
| 2696 | 2696 | ||
| 2697 | #define HUB_ROOT_RESET_TIME 60 /* times are in msec */ | 2697 | #define HUB_ROOT_RESET_TIME 60 /* times are in msec */ |
| 2698 | #define HUB_SHORT_RESET_TIME 10 | 2698 | #define HUB_SHORT_RESET_TIME 10 |
| @@ -2467,6 +2467,13 @@ static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep, · 2466 unmodified lines | |||
| 2467 | 2467 | ||
| 2468 | static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req) | 2468 | static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req) |
| 2469 | { | 2469 | { |
| 2470 | /* | ||
| 2471 | * For OUT direction, host may send less than the setup | ||
| 2472 | * length. Return true for all OUT requests. | ||
| 2473 | */ | ||
| 2474 | if (!req->direction) | ||
| 2475 | return true; | ||
| 2476 | |||
| 2470 | return req->request.actual == req->request.length; | 2477 | return req->request.actual == req->request.length; |
| 2471 | } | 2478 | } |
| 2472 | 2479 | ||
| @@ -445,6 +445,7 @@ config USB_TEGRA_XUDC · 444 unmodified lines | |||
| 445 | tristate "NVIDIA Tegra Superspeed USB 3.0 Device Controller" | 445 | tristate "NVIDIA Tegra Superspeed USB 3.0 Device Controller" |
| 446 | depends on ARCH_TEGRA || COMPILE_TEST | 446 | depends on ARCH_TEGRA || COMPILE_TEST |
| 447 | depends on PHY_TEGRA_XUSB | 447 | depends on PHY_TEGRA_XUSB |
| 448 | select USB_ROLE_SWITCH | ||
| 448 | help | 449 | help |
| 449 | Enables NVIDIA Tegra USB 3.0 device mode controller driver. | 450 | Enables NVIDIA Tegra USB 3.0 device mode controller driver. |
| 450 | 451 | ||
| @@ -415,13 +415,17 @@ static int ohci_da8xx_probe(struct platform_device *pdev) · 414 unmodified lines | |||
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | da8xx_ohci->oc_gpio = devm_gpiod_get_optional(dev, "oc", GPIOD_IN); | 417 | da8xx_ohci->oc_gpio = devm_gpiod_get_optional(dev, "oc", GPIOD_IN); |
| 418 | if (IS_ERR(da8xx_ohci->oc_gpio)) | 418 | if (IS_ERR(da8xx_ohci->oc_gpio)) { |
| 419 | error = PTR_ERR(da8xx_ohci->oc_gpio); | ||
| 419 | goto err; | 420 | goto err; |
| 421 | } | ||
| 420 | 422 | ||
| 421 | if (da8xx_ohci->oc_gpio) { | 423 | if (da8xx_ohci->oc_gpio) { |
| 422 | oc_irq = gpiod_to_irq(da8xx_ohci->oc_gpio); | 424 | oc_irq = gpiod_to_irq(da8xx_ohci->oc_gpio); |
| 423 | if (oc_irq < 0) | 425 | if (oc_irq < 0) { |
| 426 | error = oc_irq; | ||
| 424 | goto err; | 427 | goto err; |
| 428 | } | ||
| 425 | 429 | ||
| 426 | error = devm_request_threaded_irq(dev, oc_irq, NULL, | 430 | error = devm_request_threaded_irq(dev, oc_irq, NULL, |
| 427 | ohci_da8xx_oc_thread, IRQF_TRIGGER_RISING | | 431 | ohci_da8xx_oc_thread, IRQF_TRIGGER_RISING | |
| @@ -75,14 +75,17 @@ static struct musb_hdrc_platform_data jz4740_musb_platform_data = { · 74 unmodified lines | |||
| 75 | static int jz4740_musb_init(struct musb *musb) | 75 | static int jz4740_musb_init(struct musb *musb) |
| 76 | { | 76 | { |
| 77 | struct device *dev = musb->controller->parent; | 77 | struct device *dev = musb->controller->parent; |
| 78 | int err; | ||
| 78 | 79 | ||
| 79 | if (dev->of_node) | 80 | if (dev->of_node) |
| 80 | musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0); | 81 | musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0); |
| 81 | else | 82 | else |
| 82 | musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | 83 | musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); |
| 83 | if (IS_ERR(musb->xceiv)) { | 84 | if (IS_ERR(musb->xceiv)) { |
| 84 | dev_err(dev, "No transceiver configured\n"); | 85 | err = PTR_ERR(musb->xceiv); |
| 85 | return PTR_ERR(musb->xceiv); | 86 | if (err != -EPROBE_DEFER) |
| 87 | dev_err(dev, "No transceiver configured: %d", err); | ||
| 88 | return err; | ||
| 86 | } | 89 | } |
| 87 | 90 | ||
| 88 | /* Silicon does not implement ConfigData register. | 91 | /* Silicon does not implement ConfigData register. |
| @@ -1840,6 +1840,9 @@ ATTRIBUTE_GROUPS(musb); · 1839 unmodified lines | |||
| 1840 | #define MUSB_QUIRK_B_INVALID_VBUS_91 (MUSB_DEVCTL_BDEVICE | \ | 1840 | #define MUSB_QUIRK_B_INVALID_VBUS_91 (MUSB_DEVCTL_BDEVICE | \ |
| 1841 | (2 << MUSB_DEVCTL_VBUS_SHIFT) | \ | 1841 | (2 << MUSB_DEVCTL_VBUS_SHIFT) | \ |
| 1842 | MUSB_DEVCTL_SESSION) | 1842 | MUSB_DEVCTL_SESSION) |
| 1843 | #define MUSB_QUIRK_B_DISCONNECT_99 (MUSB_DEVCTL_BDEVICE | \ | ||
| 1844 | (3 << MUSB_DEVCTL_VBUS_SHIFT) | \ | ||
| 1845 | MUSB_DEVCTL_SESSION) | ||
| 1843 | #define MUSB_QUIRK_A_DISCONNECT_19 ((3 << MUSB_DEVCTL_VBUS_SHIFT) | \ | 1846 | #define MUSB_QUIRK_A_DISCONNECT_19 ((3 << MUSB_DEVCTL_VBUS_SHIFT) | \ |
| 1844 | MUSB_DEVCTL_SESSION) | 1847 | MUSB_DEVCTL_SESSION) |
| 1845 | 1848 | ||
| @@ -1862,6 +1865,11 @@ static void musb_pm_runtime_check_session(struct musb *musb) · 16 unmodified lines | |||
| 1862 | s = MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV | | 1865 | s = MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV | |
| 1863 | MUSB_DEVCTL_HR; | 1866 | MUSB_DEVCTL_HR; |
| 1864 | switch (devctl & ~s) { | 1867 | switch (devctl & ~s) { |
| 1868 | case MUSB_QUIRK_B_DISCONNECT_99: | ||
| 1869 | musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n"); | ||
| 1870 | schedule_delayed_work(&musb->irq_work, | ||
| 1871 | msecs_to_jiffies(1000)); | ||
| 1872 | break; | ||
| 1865 | case MUSB_QUIRK_B_INVALID_VBUS_91: | 1873 | case MUSB_QUIRK_B_INVALID_VBUS_91: |
| 1866 | if (musb->quirk_retries && !musb->flush_irq_work) { | 1874 | if (musb->quirk_retries && !musb->flush_irq_work) { |
| 1867 | musb_dbg(musb, | 1875 | musb_dbg(musb, |
| @@ -2310,6 +2318,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) · 442 unmodified lines | |||
| 2310 | musb_disable_interrupts(musb); | 2318 | musb_disable_interrupts(musb); |
| 2311 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | 2319 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); |
| 2312 | 2320 | ||
| 2321 | /* MUSB_POWER_SOFTCONN might be already set, JZ4740 does this. */ | ||
| 2322 | musb_writeb(musb->mregs, MUSB_POWER, 0); | ||
| 2323 | |||
| 2313 | /* Init IRQ workqueue before request_irq */ | 2324 | /* Init IRQ workqueue before request_irq */ |
| 2314 | INIT_DELAYED_WORK(&musb->irq_work, musb_irq_work); | 2325 | INIT_DELAYED_WORK(&musb->irq_work, musb_irq_work); |
| 2315 | INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); | 2326 | INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); |
| @@ -425,7 +425,7 @@ struct dma_controller *musbhs_dma_controller_create(struct musb *musb, · 424 unmodified lines | |||
| 425 | controller->controller.channel_abort = dma_channel_abort; | 425 | controller->controller.channel_abort = dma_channel_abort; |
| 426 | 426 | ||
| 427 | if (request_irq(irq, dma_controller_irq, 0, | 427 | if (request_irq(irq, dma_controller_irq, 0, |
| 428 | dev_name(musb->controller), &controller->controller)) { | 428 | dev_name(musb->controller), controller)) { |
| 429 | dev_err(dev, "request_irq %d failed!\n", irq); | 429 | dev_err(dev, "request_irq %d failed!\n", irq); |
| 430 | musb_dma_controller_destroy(&controller->controller); | 430 | musb_dma_controller_destroy(&controller->controller); |
| 431 | 431 | ||
| @@ -567,6 +567,9 @@ static void option_instat_callback(struct urb *urb); · 566 unmodified lines | |||
| 567 | /* Interface must have two endpoints */ | 567 | /* Interface must have two endpoints */ |
| 568 | #define NUMEP2 BIT(16) | 568 | #define NUMEP2 BIT(16) |
| 569 | 569 | ||
| 570 | /* Device needs ZLP */ | ||
| 571 | #define ZLP BIT(17) | ||
| 572 | |||
| 570 | 573 | ||
| 571 | static const struct usb_device_id option_ids[] = { | 574 | static const struct usb_device_id option_ids[] = { |
| 572 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 575 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
| @@ -1172,6 +1175,8 @@ static const struct usb_device_id option_ids[] = { · 599 unmodified lines | |||
| 1172 | .driver_info = NCTRL(0) | RSVD(3) }, | 1175 | .driver_info = NCTRL(0) | RSVD(3) }, |
| 1173 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1102, 0xff), /* Telit ME910 (ECM) */ | 1176 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1102, 0xff), /* Telit ME910 (ECM) */ |
| 1174 | .driver_info = NCTRL(0) }, | 1177 | .driver_info = NCTRL(0) }, |
| 1178 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110a, 0xff), /* Telit ME910G1 */ | ||
| 1179 | .driver_info = NCTRL(0) | RSVD(3) }, | ||
| 1175 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), | 1180 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), |
| 1176 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, | 1181 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1177 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), | 1182 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), |
| @@ -1196,6 +1201,8 @@ static const struct usb_device_id option_ids[] = { · 18 unmodified lines | |||
| 1196 | .driver_info = NCTRL(0) | RSVD(1) }, | 1201 | .driver_info = NCTRL(0) | RSVD(1) }, |
| 1197 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */ | 1202 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */ |
| 1198 | .driver_info = NCTRL(0) }, | 1203 | .driver_info = NCTRL(0) }, |
| 1204 | { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ | ||
| 1205 | .driver_info = NCTRL(0) | ZLP }, | ||
| 1199 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ | 1206 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
| 1200 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), | 1207 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), |
| 1201 | .driver_info = RSVD(1) }, | 1208 | .driver_info = RSVD(1) }, |
| @@ -2097,6 +2104,9 @@ static int option_attach(struct usb_serial *serial) · 895 unmodified lines | |||
| 2097 | if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber))) | 2104 | if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber))) |
| 2098 | data->use_send_setup = 1; | 2105 | data->use_send_setup = 1; |
| 2099 | 2106 | ||
| 2107 | if (device_flags & ZLP) | ||
| 2108 | data->use_zlp = 1; | ||
| 2109 | |||
| 2100 | spin_lock_init(&data->susp_lock); | 2110 | spin_lock_init(&data->susp_lock); |
| 2101 | 2111 | ||
| 2102 | usb_set_serial_data(serial, data); | 2112 | usb_set_serial_data(serial, data); |
| @@ -38,6 +38,7 @@ struct usb_wwan_intf_private { · 37 unmodified lines | |||
| 38 | spinlock_t susp_lock; | 38 | spinlock_t susp_lock; |
| 39 | unsigned int suspended:1; | 39 | unsigned int suspended:1; |
| 40 | unsigned int use_send_setup:1; | 40 | unsigned int use_send_setup:1; |
| 41 | unsigned int use_zlp:1; | ||
| 41 | int in_flight; | 42 | int in_flight; |
| 42 | unsigned int open_ports; | 43 | unsigned int open_ports; |
| 43 | void *private; | 44 | void *private; |
| @@ -461,6 +461,7 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, · 460 unmodified lines | |||
| 461 | void (*callback) (struct urb *)) | 461 | void (*callback) (struct urb *)) |
| 462 | { | 462 | { |
| 463 | struct usb_serial *serial = port->serial; | 463 | struct usb_serial *serial = port->serial; |
| 464 | struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); | ||
| 464 | struct urb *urb; | 465 | struct urb *urb; |
| 465 | 466 | ||
| 466 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | 467 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ |
| @@ -471,6 +472,9 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, · 4 unmodified lines | |||
| 471 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | 472 | usb_sndbulkpipe(serial->dev, endpoint) | dir, |
| 472 | buf, len, callback, ctx); | 473 | buf, len, callback, ctx); |
| 473 | 474 | ||
| 475 | if (intfdata->use_zlp && dir == USB_DIR_OUT) | ||
| 476 | urb->transfer_flags |= URB_ZERO_PACKET; | ||
| 477 | |||
| 474 | return urb; | 478 | return urb; |
| 475 | } | 479 | } |
| 476 | 480 | ||
| @@ -432,20 +432,30 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci) · 431 unmodified lines | |||
| 432 | 432 | ||
| 433 | if (status & TCPC_ALERT_RX_STATUS) { | 433 | if (status & TCPC_ALERT_RX_STATUS) { |
| 434 | struct pd_message msg; | 434 | struct pd_message msg; |
| 435 | unsigned int cnt; | 435 | unsigned int cnt, payload_cnt; |
| 436 | u16 header; | 436 | u16 header; |
| 437 | 437 | ||
| 438 | regmap_read(tcpci->regmap, TCPC_RX_BYTE_CNT, &cnt); | 438 | regmap_read(tcpci->regmap, TCPC_RX_BYTE_CNT, &cnt); |
| 439 | /* | ||
| 440 | * 'cnt' corresponds to READABLE_BYTE_COUNT in section 4.4.14 | ||
| 441 | * of the TCPCI spec [Rev 2.0 Ver 1.0 October 2017] and is | ||
| 442 | * defined in table 4-36 as one greater than the number of | ||
| 443 | * bytes received. And that number includes the header. So: | ||
| 444 | */ | ||
| 445 | if (cnt > 3) | ||
| 446 | payload_cnt = cnt - (1 + sizeof(msg.header)); | ||
| 447 | else | ||
| 448 | payload_cnt = 0; | ||
| 439 | 449 | ||
| 440 | tcpci_read16(tcpci, TCPC_RX_HDR, &header); | 450 | tcpci_read16(tcpci, TCPC_RX_HDR, &header); |
| 441 | msg.header = cpu_to_le16(header); | 451 | msg.header = cpu_to_le16(header); |
| 442 | 452 | ||
| 443 | if (WARN_ON(cnt > sizeof(msg.payload))) | 453 | if (WARN_ON(payload_cnt > sizeof(msg.payload))) |
| 444 | cnt = sizeof(msg.payload); | 454 | payload_cnt = sizeof(msg.payload); |
| 445 | 455 | ||
| 446 | if (cnt > 0) | 456 | if (payload_cnt > 0) |
| 447 | regmap_raw_read(tcpci->regmap, TCPC_RX_DATA, | 457 | regmap_raw_read(tcpci->regmap, TCPC_RX_DATA, |
| 448 | &msg.payload, cnt); | 458 | &msg.payload, payload_cnt); |
| 449 | 459 | ||
| 450 | /* Read complete, clear RX status alert bit */ | 460 | /* Read complete, clear RX status alert bit */ |
| 451 | tcpci_write16(tcpci, TCPC_ALERT, TCPC_ALERT_RX_STATUS); | 461 | tcpci_write16(tcpci, TCPC_ALERT, TCPC_ALERT_RX_STATUS); |
| @@ -99,15 +99,15 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num); · 98 unmodified lines | |||
| 99 | #define UCSI_ENABLE_NTFY_CMD_COMPLETE BIT(16) | 99 | #define UCSI_ENABLE_NTFY_CMD_COMPLETE BIT(16) |
| 100 | #define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE BIT(17) | 100 | #define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE BIT(17) |
| 101 | #define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE BIT(18) | 101 | #define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE BIT(18) |
| 102 | #define UCSI_ENABLE_NTFY_CAP_CHANGE BIT(19) | 102 | #define UCSI_ENABLE_NTFY_CAP_CHANGE BIT(21) |
| 103 | #define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE BIT(20) | 103 | #define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE BIT(22) |
| 104 | #define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE BIT(21) | 104 | #define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE BIT(23) |
| 105 | #define UCSI_ENABLE_NTFY_CAM_CHANGE BIT(22) | 105 | #define UCSI_ENABLE_NTFY_CAM_CHANGE BIT(24) |
| 106 | #define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE BIT(23) | 106 | #define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE BIT(25) |
| 107 | #define UCSI_ENABLE_NTFY_PARTNER_CHANGE BIT(24) | 107 | #define UCSI_ENABLE_NTFY_PARTNER_CHANGE BIT(27) |
| 108 | #define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE BIT(25) | 108 | #define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE BIT(28) |
| 109 | #define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(26) | 109 | #define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(30) |
| 110 | #define UCSI_ENABLE_NTFY_ERROR BIT(27) | 110 | #define UCSI_ENABLE_NTFY_ERROR BIT(31) |
| 111 | #define UCSI_ENABLE_NTFY_ALL 0xdbe70000 | 111 | #define UCSI_ENABLE_NTFY_ALL 0xdbe70000 |
| 112 | 112 | ||
| 113 | /* SET_UOR command bits */ | 113 | /* SET_UOR command bits */ |
| @@ -687,6 +687,7 @@ config MAX63XX_WATCHDOG · 686 unmodified lines | |||
| 687 | config MAX77620_WATCHDOG | 687 | config MAX77620_WATCHDOG |
| 688 | tristate "Maxim Max77620 Watchdog Timer" | 688 | tristate "Maxim Max77620 Watchdog Timer" |
| 689 | depends on MFD_MAX77620 || COMPILE_TEST | 689 | depends on MFD_MAX77620 || COMPILE_TEST |
| 690 | select WATCHDOG_CORE | ||
| 690 | help | 691 | help |
| 691 | This is the driver for the Max77620 watchdog timer. | 692 | This is the driver for the Max77620 watchdog timer. |
| 692 | Say 'Y' here to enable the watchdog timer support for | 693 | Say 'Y' here to enable the watchdog timer support for |
| @@ -1444,6 +1445,7 @@ config SMSC37B787_WDT · 751 unmodified lines | |||
| 1444 | config TQMX86_WDT | 1445 | config TQMX86_WDT |
| 1445 | tristate "TQ-Systems TQMX86 Watchdog Timer" | 1446 | tristate "TQ-Systems TQMX86 Watchdog Timer" |
| 1446 | depends on X86 | 1447 | depends on X86 |
| 1448 | select WATCHDOG_CORE | ||
| 1447 | help | 1449 | help |
| 1448 | This is the driver for the hardware watchdog timer in the TQMX86 IO | 1450 | This is the driver for the hardware watchdog timer in the TQMX86 IO |
| 1449 | controller found on some of their ComExpress Modules. | 1451 | controller found on some of their ComExpress Modules. |
| @@ -112,7 +112,7 @@ static int imx7ulp_wdt_restart(struct watchdog_device *wdog, · 111 unmodified lines | |||
| 112 | { | 112 | { |
| 113 | struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog); | 113 | struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog); |
| 114 | 114 | ||
| 115 | imx7ulp_wdt_enable(wdt->base, true); | 115 | imx7ulp_wdt_enable(wdog, true); |
| 116 | imx7ulp_wdt_set_timeout(&wdt->wdd, 1); | 116 | imx7ulp_wdt_set_timeout(&wdt->wdd, 1); |
| 117 | 117 | ||
| 118 | /* wait for wdog to fire */ | 118 | /* wait for wdog to fire */ |
| @@ -602,7 +602,7 @@ static int orion_wdt_probe(struct platform_device *pdev) · 601 unmodified lines | |||
| 602 | set_bit(WDOG_HW_RUNNING, &dev->wdt.status); | 602 | set_bit(WDOG_HW_RUNNING, &dev->wdt.status); |
| 603 | 603 | ||
| 604 | /* Request the IRQ only after the watchdog is disabled */ | 604 | /* Request the IRQ only after the watchdog is disabled */ |
| 605 | irq = platform_get_irq(pdev, 0); | 605 | irq = platform_get_irq_optional(pdev, 0); |
| 606 | if (irq > 0) { | 606 | if (irq > 0) { |
| 607 | /* | 607 | /* |
| 608 | * Not all supported platforms specify an interrupt for the | 608 | * Not all supported platforms specify an interrupt for the |
| @@ -617,7 +617,7 @@ static int orion_wdt_probe(struct platform_device *pdev) · 8 unmodified lines | |||
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | /* Optional 2nd interrupt for pretimeout */ | 619 | /* Optional 2nd interrupt for pretimeout */ |
| 620 | irq = platform_get_irq(pdev, 1); | 620 | irq = platform_get_irq_optional(pdev, 1); |
| 621 | if (irq > 0) { | 621 | if (irq > 0) { |
| 622 | orion_wdt_info.options |= WDIOF_PRETIMEOUT; | 622 | orion_wdt_info.options |= WDIOF_PRETIMEOUT; |
| 623 | ret = devm_request_irq(&pdev->dev, irq, orion_wdt_pre_irq, | 623 | ret = devm_request_irq(&pdev->dev, irq, orion_wdt_pre_irq, |
| @@ -188,6 +188,7 @@ static struct platform_driver rn5t618_wdt_driver = { · 187 unmodified lines | |||
| 188 | 188 | ||
| 189 | module_platform_driver(rn5t618_wdt_driver); | 189 | module_platform_driver(rn5t618_wdt_driver); |
| 190 | 190 | ||
| 191 | MODULE_ALIAS("platform:rn5t618-wdt"); | ||
| 191 | MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); | 192 | MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); |
| 192 | MODULE_DESCRIPTION("RN5T618 watchdog driver"); | 193 | MODULE_DESCRIPTION("RN5T618 watchdog driver"); |
| 193 | MODULE_LICENSE("GPL v2"); | 194 | MODULE_LICENSE("GPL v2"); |
| @@ -420,7 +420,7 @@ static int wdt_find(int addr) · 419 unmodified lines | |||
| 420 | cr_wdt_csr = NCT6102D_WDT_CSR; | 420 | cr_wdt_csr = NCT6102D_WDT_CSR; |
| 421 | break; | 421 | break; |
| 422 | case NCT6116_ID: | 422 | case NCT6116_ID: |
| 423 | ret = nct6102; | 423 | ret = nct6116; |
| 424 | cr_wdt_timeout = NCT6102D_WDT_TIMEOUT; | 424 | cr_wdt_timeout = NCT6102D_WDT_TIMEOUT; |
| 425 | cr_wdt_control = NCT6102D_WDT_CONTROL; | 425 | cr_wdt_control = NCT6102D_WDT_CONTROL; |
| 426 | cr_wdt_csr = NCT6102D_WDT_CSR; | 426 | cr_wdt_csr = NCT6102D_WDT_CSR; |
| @@ -447,7 +447,7 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start, · 446 unmodified lines | |||
| 447 | 447 | ||
| 448 | if (blkcg_css) { | 448 | if (blkcg_css) { |
| 449 | bio->bi_opf |= REQ_CGROUP_PUNT; | 449 | bio->bi_opf |= REQ_CGROUP_PUNT; |
| 450 | bio_associate_blkg_from_css(bio, blkcg_css); | 450 | kthread_associate_blkcg(blkcg_css); |
| 451 | } | 451 | } |
| 452 | refcount_set(&cb->pending_bios, 1); | 452 | refcount_set(&cb->pending_bios, 1); |
| 453 | 453 | ||
| @@ -491,6 +491,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start, · 37 unmodified lines | |||
| 491 | bio->bi_opf = REQ_OP_WRITE | write_flags; | 491 | bio->bi_opf = REQ_OP_WRITE | write_flags; |
| 492 | bio->bi_private = cb; | 492 | bio->bi_private = cb; |
| 493 | bio->bi_end_io = end_compressed_bio_write; | 493 | bio->bi_end_io = end_compressed_bio_write; |
| 494 | if (blkcg_css) | ||
| 495 | bio->bi_opf |= REQ_CGROUP_PUNT; | ||
| 494 | bio_add_page(bio, page, PAGE_SIZE, 0); | 496 | bio_add_page(bio, page, PAGE_SIZE, 0); |
| 495 | } | 497 | } |
| 496 | if (bytes_left < PAGE_SIZE) { | 498 | if (bytes_left < PAGE_SIZE) { |
| @@ -517,6 +519,9 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start, · 20 unmodified lines | |||
| 517 | bio_endio(bio); | 519 | bio_endio(bio); |
| 518 | } | 520 | } |
| 519 | 521 | ||
| 522 | if (blkcg_css) | ||
| 523 | kthread_associate_blkcg(NULL); | ||
| 524 | |||
| 520 | return 0; | 525 | return 0; |
| 521 | } | 526 | } |
| 522 | 527 | ||
| @@ -1479,10 +1479,10 @@ next_slot: · 1478 unmodified lines | |||
| 1479 | disk_num_bytes = | 1479 | disk_num_bytes = |
| 1480 | btrfs_file_extent_disk_num_bytes(leaf, fi); | 1480 | btrfs_file_extent_disk_num_bytes(leaf, fi); |
| 1481 | /* | 1481 | /* |
| 1482 | * If extent we got ends before our range starts, skip | 1482 | * If the extent we got ends before our current offset, |
| 1483 | * to next extent | 1483 | * skip to the next extent. |
| 1484 | */ | 1484 | */ |
| 1485 | if (extent_end <= start) { | 1485 | if (extent_end <= cur_offset) { |
| 1486 | path->slots[0]++; | 1486 | path->slots[0]++; |
| 1487 | goto next_slot; | 1487 | goto next_slot; |
| 1488 | } | 1488 | } |
| @@ -3031,11 +3031,9 @@ static void end_bio_bh_io_sync(struct bio *bio) · 3030 unmodified lines | |||
| 3031 | * errors, this only handles the "we need to be able to | 3031 | * errors, this only handles the "we need to be able to |
| 3032 | * do IO at the final sector" case. | 3032 | * do IO at the final sector" case. |
| 3033 | */ | 3033 | */ |
| 3034 | void guard_bio_eod(int op, struct bio *bio) | 3034 | void guard_bio_eod(struct bio *bio) |
| 3035 | { | 3035 | { |
| 3036 | sector_t maxsector; | 3036 | sector_t maxsector; |
| 3037 | struct bio_vec *bvec = bio_last_bvec_all(bio); | ||
| 3038 | unsigned truncated_bytes; | ||
| 3039 | struct hd_struct *part; | 3037 | struct hd_struct *part; |
| 3040 | 3038 | ||
| 3041 | rcu_read_lock(); | 3039 | rcu_read_lock(); |
| @@ -3061,28 +3059,7 @@ void guard_bio_eod(int op, struct bio *bio) · 19 unmodified lines | |||
| 3061 | if (likely((bio->bi_iter.bi_size >> 9) <= maxsector)) | 3059 | if (likely((bio->bi_iter.bi_size >> 9) <= maxsector)) |
| 3062 | return; | 3060 | return; |
| 3063 | 3061 | ||
| 3064 | /* Uhhuh. We've got a bio that straddles the device size! */ | 3062 | bio_truncate(bio, maxsector << 9); |
| 3065 | truncated_bytes = bio->bi_iter.bi_size - (maxsector << 9); | ||
| 3066 | |||
| 3067 | /* | ||
| 3068 | * The bio contains more than one segment which spans EOD, just return | ||
| 3069 | * and let IO layer turn it into an EIO | ||
| 3070 | */ | ||
| 3071 | if (truncated_bytes > bvec->bv_len) | ||
| 3072 | return; | ||
| 3073 | |||
| 3074 | /* Truncate the bio.. */ | ||
| 3075 | bio->bi_iter.bi_size -= truncated_bytes; | ||
| 3076 | bvec->bv_len -= truncated_bytes; | ||
| 3077 | |||
| 3078 | /* ..and clear the end of the buffer for reads */ | ||
| 3079 | if (op == REQ_OP_READ) { | ||
| 3080 | struct bio_vec bv; | ||
| 3081 | |||
| 3082 | mp_bvec_last_segment(bvec, &bv); | ||
| 3083 | zero_user(bv.bv_page, bv.bv_offset + bv.bv_len, | ||
| 3084 | truncated_bytes); | ||
| 3085 | } | ||
| 3086 | } | 3063 | } |
| 3087 | 3064 | ||
| 3088 | static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, | 3065 | static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, |
| @@ -3118,15 +3095,15 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, · 29 unmodified lines | |||
| 3118 | bio->bi_end_io = end_bio_bh_io_sync; | 3095 | bio->bi_end_io = end_bio_bh_io_sync; |
| 3119 | bio->bi_private = bh; | 3096 | bio->bi_private = bh; |
| 3120 | 3097 | ||
| 3121 | /* Take care of bh's that straddle the end of the device */ | ||
| 3122 | guard_bio_eod(op, bio); | ||
| 3123 | |||
| 3124 | if (buffer_meta(bh)) | 3098 | if (buffer_meta(bh)) |
| 3125 | op_flags |= REQ_META; | 3099 | op_flags |= REQ_META; |
| 3126 | if (buffer_prio(bh)) | 3100 | if (buffer_prio(bh)) |
| 3127 | op_flags |= REQ_PRIO; | 3101 | op_flags |= REQ_PRIO; |
| 3128 | bio_set_op_attrs(bio, op, op_flags); | 3102 | bio_set_op_attrs(bio, op, op_flags); |
| 3129 | 3103 | ||
| 3104 | /* Take care of bh's that straddle the end of the device */ | ||
| 3105 | guard_bio_eod(bio); | ||
| 3106 | |||
| 3130 | if (wbc) { | 3107 | if (wbc) { |
| 3131 | wbc_init_bio(wbc, bio); | 3108 | wbc_init_bio(wbc, bio); |
| 3132 | wbc_account_cgroup_owner(wbc, bh->b_page, bh->b_size); | 3109 | wbc_account_cgroup_owner(wbc, bh->b_page, bh->b_size); |
| @@ -352,7 +352,7 @@ static struct kobject *cdev_get(struct cdev *p) · 351 unmodified lines | |||
| 352 | 352 | ||
| 353 | if (owner && !try_module_get(owner)) | 353 | if (owner && !try_module_get(owner)) |
| 354 | return NULL; | 354 | return NULL; |
| 355 | kobj = kobject_get(&p->kobj); | 355 | kobj = kobject_get_unless_zero(&p->kobj); |
| 356 | if (!kobj) | 356 | if (!kobj) |
| 357 | module_put(owner); | 357 | module_put(owner); |
| 358 | return kobj; | 358 | return kobj; |
| @@ -1693,6 +1693,7 @@ struct cifs_fattr { · 1692 unmodified lines | |||
| 1693 | struct timespec64 cf_atime; | 1693 | struct timespec64 cf_atime; |
| 1694 | struct timespec64 cf_mtime; | 1694 | struct timespec64 cf_mtime; |
| 1695 | struct timespec64 cf_ctime; | 1695 | struct timespec64 cf_ctime; |
| 1696 | u32 cf_cifstag; | ||
| 1696 | }; | 1697 | }; |
| 1697 | 1698 | ||
| 1698 | static inline void free_dfs_info_param(struct dfs_info3_param *param) | 1699 | static inline void free_dfs_info_param(struct dfs_info3_param *param) |
| @@ -139,6 +139,28 @@ retry: · 138 unmodified lines | |||
| 139 | dput(dentry); | 139 | dput(dentry); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | static bool reparse_file_needs_reval(const struct cifs_fattr *fattr) | ||
| 143 | { | ||
| 144 | if (!(fattr->cf_cifsattrs & ATTR_REPARSE)) | ||
| 145 | return false; | ||
| 146 | /* | ||
| 147 | * The DFS tags should be only intepreted by server side as per | ||
| 148 | * MS-FSCC 2.1.2.1, but let's include them anyway. | ||
| 149 | * | ||
| 150 | * Besides, if cf_cifstag is unset (0), then we still need it to be | ||
| 151 | * revalidated to know exactly what reparse point it is. | ||
| 152 | */ | ||
| 153 | switch (fattr->cf_cifstag) { | ||
| 154 | case IO_REPARSE_TAG_DFS: | ||
| 155 | case IO_REPARSE_TAG_DFSR: | ||
| 156 | case IO_REPARSE_TAG_SYMLINK: | ||
| 157 | case IO_REPARSE_TAG_NFS: | ||
| 158 | case 0: | ||
| 159 | return true; | ||
| 160 | } | ||
| 161 | return false; | ||
| 162 | } | ||
| 163 | |||
| 142 | static void | 164 | static void |
| 143 | cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) | 165 | cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) |
| 144 | { | 166 | { |
| @@ -158,7 +180,7 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) · 13 unmodified lines | |||
| 158 | * is a symbolic link, DFS referral or a reparse point with a direct | 180 | * is a symbolic link, DFS referral or a reparse point with a direct |
| 159 | * access like junctions, deduplicated files, NFS symlinks. | 181 | * access like junctions, deduplicated files, NFS symlinks. |
| 160 | */ | 182 | */ |
| 161 | if (fattr->cf_cifsattrs & ATTR_REPARSE) | 183 | if (reparse_file_needs_reval(fattr)) |
| 162 | fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; | 184 | fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; |
| 163 | 185 | ||
| 164 | /* non-unix readdir doesn't provide nlink */ | 186 | /* non-unix readdir doesn't provide nlink */ |
| @@ -194,19 +216,37 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) · 29 unmodified lines | |||
| 194 | } | 216 | } |
| 195 | } | 217 | } |
| 196 | 218 | ||
| 219 | static void __dir_info_to_fattr(struct cifs_fattr *fattr, const void *info) | ||
| 220 | { | ||
| 221 | const FILE_DIRECTORY_INFO *fi = info; | ||
| 222 | |||
| 223 | memset(fattr, 0, sizeof(*fattr)); | ||
| 224 | fattr->cf_cifsattrs = le32_to_cpu(fi->ExtFileAttributes); | ||
| 225 | fattr->cf_eof = le64_to_cpu(fi->EndOfFile); | ||
| 226 | fattr->cf_bytes = le64_to_cpu(fi->AllocationSize); | ||
| 227 | fattr->cf_createtime = le64_to_cpu(fi->CreationTime); | ||
| 228 | fattr->cf_atime = cifs_NTtimeToUnix(fi->LastAccessTime); | ||
| 229 | fattr->cf_ctime = cifs_NTtimeToUnix(fi->ChangeTime); | ||
| 230 | fattr->cf_mtime = cifs_NTtimeToUnix(fi->LastWriteTime); | ||
| 231 | } | ||
| 232 | |||
| 197 | void | 233 | void |
| 198 | cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, | 234 | cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, |
| 199 | struct cifs_sb_info *cifs_sb) | 235 | struct cifs_sb_info *cifs_sb) |
| 200 | { | 236 | { |
| 201 | memset(fattr, 0, sizeof(*fattr)); | 237 | __dir_info_to_fattr(fattr, info); |
| 202 | fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes); | 238 | cifs_fill_common_info(fattr, cifs_sb); |
| 203 | fattr->cf_eof = le64_to_cpu(info->EndOfFile); | 239 | } |
| 204 | fattr->cf_bytes = le64_to_cpu(info->AllocationSize); | ||
| 205 | fattr->cf_createtime = le64_to_cpu(info->CreationTime); | ||
| 206 | fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); | ||
| 207 | fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); | ||
| 208 | fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); | ||
| 209 | 240 | ||
| 241 | static void cifs_fulldir_info_to_fattr(struct cifs_fattr *fattr, | ||
| 242 | SEARCH_ID_FULL_DIR_INFO *info, | ||
| 243 | struct cifs_sb_info *cifs_sb) | ||
| 244 | { | ||
| 245 | __dir_info_to_fattr(fattr, info); | ||
| 246 | |||
| 247 | /* See MS-FSCC 2.4.18 FileIdFullDirectoryInformation */ | ||
| 248 | if (fattr->cf_cifsattrs & ATTR_REPARSE) | ||
| 249 | fattr->cf_cifstag = le32_to_cpu(info->EaSize); | ||
| 210 | cifs_fill_common_info(fattr, cifs_sb); | 250 | cifs_fill_common_info(fattr, cifs_sb); |
| 211 | } | 251 | } |
| 212 | 252 | ||
| @@ -755,6 +795,11 @@ static int cifs_filldir(char *find_entry, struct file *file, · 542 unmodified lines | |||
| 755 | (FIND_FILE_STANDARD_INFO *)find_entry, | 795 | (FIND_FILE_STANDARD_INFO *)find_entry, |
| 756 | cifs_sb); | 796 | cifs_sb); |
| 757 | break; | 797 | break; |
| 798 | case SMB_FIND_FILE_ID_FULL_DIR_INFO: | ||
| 799 | cifs_fulldir_info_to_fattr(&fattr, | ||
| 800 | (SEARCH_ID_FULL_DIR_INFO *)find_entry, | ||
| 801 | cifs_sb); | ||
| 802 | break; | ||
| 758 | default: | 803 | default: |
| 759 | cifs_dir_info_to_fattr(&fattr, | 804 | cifs_dir_info_to_fattr(&fattr, |
| 760 | (FILE_DIRECTORY_INFO *)find_entry, | 805 | (FILE_DIRECTORY_INFO *)find_entry, |
| @@ -67,7 +67,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, · 66 unmodified lines | |||
| 67 | goto out; | 67 | goto out; |
| 68 | 68 | ||
| 69 | 69 | ||
| 70 | if (oparms->tcon->use_resilient) { | 70 | if (oparms->tcon->use_resilient) { |
| 71 | /* default timeout is 0, servers pick default (120 seconds) */ | 71 | /* default timeout is 0, servers pick default (120 seconds) */ |
| 72 | nr_ioctl_req.Timeout = | 72 | nr_ioctl_req.Timeout = |
| 73 | cpu_to_le32(oparms->tcon->handle_timeout); | 73 | cpu_to_le32(oparms->tcon->handle_timeout); |
| @@ -39,6 +39,8 @@ · 38 unmodified lines | |||
| 39 | #include <linux/atomic.h> | 39 | #include <linux/atomic.h> |
| 40 | #include <linux/prefetch.h> | 40 | #include <linux/prefetch.h> |
| 41 | 41 | ||
| 42 | #include "internal.h" | ||
| 43 | |||
| 42 | /* | 44 | /* |
| 43 | * How many user pages to map in one call to get_user_pages(). This determines | 45 | * How many user pages to map in one call to get_user_pages(). This determines |
| 44 | * the size of a structure in the slab cache | 46 | * the size of a structure in the slab cache |
| @@ -960,7 +960,7 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd) · 959 unmodified lines | |||
| 960 | return ksys_dup3(oldfd, newfd, 0); | 960 | return ksys_dup3(oldfd, newfd, 0); |
| 961 | } | 961 | } |
| 962 | 962 | ||
| 963 | SYSCALL_DEFINE1(dup, unsigned int, fildes) | 963 | int ksys_dup(unsigned int fildes) |
| 964 | { | 964 | { |
| 965 | int ret = -EBADF; | 965 | int ret = -EBADF; |
| 966 | struct file *file = fget_raw(fildes); | 966 | struct file *file = fget_raw(fildes); |
| @@ -975,6 +975,11 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes) · 8 unmodified lines | |||
| 975 | return ret; | 975 | return ret; |
| 976 | } | 976 | } |
| 977 | 977 | ||
| 978 | SYSCALL_DEFINE1(dup, unsigned int, fildes) | ||
| 979 | { | ||
| 980 | return ksys_dup(fildes); | ||
| 981 | } | ||
| 982 | |||
| 978 | int f_dupfd(unsigned int from, struct file *file, unsigned flags) | 983 | int f_dupfd(unsigned int from, struct file *file, unsigned flags) |
| 979 | { | 984 | { |
| 980 | int err; | 985 | int err; |
| @@ -1498,8 +1498,10 @@ static int __init init_hugetlbfs_fs(void) · 1497 unmodified lines | |||
| 1498 | /* other hstates are optional */ | 1498 | /* other hstates are optional */ |
| 1499 | i = 0; | 1499 | i = 0; |
| 1500 | for_each_hstate(h) { | 1500 | for_each_hstate(h) { |
| 1501 | if (i == default_hstate_idx) | 1501 | if (i == default_hstate_idx) { |
| 1502 | i++; | ||
| 1502 | continue; | 1503 | continue; |
| 1504 | } | ||
| 1503 | 1505 | ||
| 1504 | mnt = mount_one_hugetlbfs(h); | 1506 | mnt = mount_one_hugetlbfs(h); |
| 1505 | if (IS_ERR(mnt)) | 1507 | if (IS_ERR(mnt)) |
| @@ -38,7 +38,7 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait) · 37 unmodified lines | |||
| 38 | /* | 38 | /* |
| 39 | * buffer.c | 39 | * buffer.c |
| 40 | */ | 40 | */ |
| 41 | extern void guard_bio_eod(int rw, struct bio *bio); | 41 | extern void guard_bio_eod(struct bio *bio); |
| 42 | extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len, | 42 | extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len, |
| 43 | get_block_t *get_block, struct iomap *iomap); | 43 | get_block_t *get_block, struct iomap *iomap); |
| 44 | 44 | ||
| @@ -92,7 +92,6 @@ struct io_wqe { · 91 unmodified lines | |||
| 92 | struct io_wqe_acct acct[2]; | 92 | struct io_wqe_acct acct[2]; |
| 93 | 93 | ||
| 94 | struct hlist_nulls_head free_list; | 94 | struct hlist_nulls_head free_list; |
| 95 | struct hlist_nulls_head busy_list; | ||
| 96 | struct list_head all_list; | 95 | struct list_head all_list; |
| 97 | 96 | ||
| 98 | struct io_wq *wq; | 97 | struct io_wq *wq; |
| @@ -327,7 +326,6 @@ static void __io_worker_busy(struct io_wqe *wqe, struct io_worker *worker, · 228 unmodified lines | |||
| 327 | if (worker->flags & IO_WORKER_F_FREE) { | 326 | if (worker->flags & IO_WORKER_F_FREE) { |
| 328 | worker->flags &= ~IO_WORKER_F_FREE; | 327 | worker->flags &= ~IO_WORKER_F_FREE; |
| 329 | hlist_nulls_del_init_rcu(&worker->nulls_node); | 328 | hlist_nulls_del_init_rcu(&worker->nulls_node); |
| 330 | hlist_nulls_add_head_rcu(&worker->nulls_node, &wqe->busy_list); | ||
| 331 | } | 329 | } |
| 332 | 330 | ||
| 333 | /* | 331 | /* |
| @@ -365,7 +363,6 @@ static bool __io_worker_idle(struct io_wqe *wqe, struct io_worker *worker) · 31 unmodified lines | |||
| 365 | { | 363 | { |
| 366 | if (!(worker->flags & IO_WORKER_F_FREE)) { | 364 | if (!(worker->flags & IO_WORKER_F_FREE)) { |
| 367 | worker->flags |= IO_WORKER_F_FREE; | 365 | worker->flags |= IO_WORKER_F_FREE; |
| 368 | hlist_nulls_del_init_rcu(&worker->nulls_node); | ||
| 369 | hlist_nulls_add_head_rcu(&worker->nulls_node, &wqe->free_list); | 366 | hlist_nulls_add_head_rcu(&worker->nulls_node, &wqe->free_list); |
| 370 | } | 367 | } |
| 371 | 368 | ||
| @@ -432,6 +429,8 @@ next: · 60 unmodified lines | |||
| 432 | if (signal_pending(current)) | 429 | if (signal_pending(current)) |
| 433 | flush_signals(current); | 430 | flush_signals(current); |
| 434 | 431 | ||
| 432 | cond_resched(); | ||
| 433 | |||
| 435 | spin_lock_irq(&worker->lock); | 434 | spin_lock_irq(&worker->lock); |
| 436 | worker->cur_work = work; | 435 | worker->cur_work = work; |
| 437 | spin_unlock_irq(&worker->lock); | 436 | spin_unlock_irq(&worker->lock); |
| @@ -798,10 +797,6 @@ void io_wq_cancel_all(struct io_wq *wq) · 360 unmodified lines | |||
| 798 | 797 | ||
| 799 | set_bit(IO_WQ_BIT_CANCEL, &wq->state); | 798 | set_bit(IO_WQ_BIT_CANCEL, &wq->state); |
| 800 | 799 | ||
| 801 | /* | ||
| 802 | * Browse both lists, as there's a gap between handing work off | ||
| 803 | * to a worker and the worker putting itself on the busy_list | ||
| 804 | */ | ||
| 805 | rcu_read_lock(); | 800 | rcu_read_lock(); |
| 806 | for_each_node(node) { | 801 | for_each_node(node) { |
| 807 | struct io_wqe *wqe = wq->wqes[node]; | 802 | struct io_wqe *wqe = wq->wqes[node]; |
| @@ -1049,7 +1044,6 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) · 241 unmodified lines | |||
| 1049 | spin_lock_init(&wqe->lock); | 1044 | spin_lock_init(&wqe->lock); |
| 1050 | INIT_WQ_LIST(&wqe->work_list); | 1045 | INIT_WQ_LIST(&wqe->work_list); |
| 1051 | INIT_HLIST_NULLS_HEAD(&wqe->free_list, 0); | 1046 | INIT_HLIST_NULLS_HEAD(&wqe->free_list, 0); |
| 1052 | INIT_HLIST_NULLS_HEAD(&wqe->busy_list, 1); | ||
| 1053 | INIT_LIST_HEAD(&wqe->all_list); | 1047 | INIT_LIST_HEAD(&wqe->all_list); |
| 1054 | } | 1048 | } |
| 1055 | 1049 | ||
| @@ -330,6 +330,26 @@ struct io_timeout { · 329 unmodified lines | |||
| 330 | struct file *file; | 330 | struct file *file; |
| 331 | u64 addr; | 331 | u64 addr; |
| 332 | int flags; | 332 | int flags; |
| 333 | unsigned count; | ||
| 334 | }; | ||
| 335 | |||
| 336 | struct io_rw { | ||
| 337 | /* NOTE: kiocb has the file as the first member, so don't do it here */ | ||
| 338 | struct kiocb kiocb; | ||
| 339 | u64 addr; | ||
| 340 | u64 len; | ||
| 341 | }; | ||
| 342 | |||
| 343 | struct io_connect { | ||
| 344 | struct file *file; | ||
| 345 | struct sockaddr __user *addr; | ||
| 346 | int addr_len; | ||
| 347 | }; | ||
| 348 | |||
| 349 | struct io_sr_msg { | ||
| 350 | struct file *file; | ||
| 351 | struct user_msghdr __user *msg; | ||
| 352 | int msg_flags; | ||
| 333 | }; | 353 | }; |
| 334 | 354 | ||
| 335 | struct io_async_connect { | 355 | struct io_async_connect { |
| @@ -351,7 +371,6 @@ struct io_async_rw { · 15 unmodified lines | |||
| 351 | }; | 371 | }; |
| 352 | 372 | ||
| 353 | struct io_async_ctx { | 373 | struct io_async_ctx { |
| 354 | struct io_uring_sqe sqe; | ||
| 355 | union { | 374 | union { |
| 356 | struct io_async_rw rw; | 375 | struct io_async_rw rw; |
| 357 | struct io_async_msghdr msg; | 376 | struct io_async_msghdr msg; |
| @@ -369,15 +388,16 @@ struct io_async_ctx { · 11 unmodified lines | |||
| 369 | struct io_kiocb { | 388 | struct io_kiocb { |
| 370 | union { | 389 | union { |
| 371 | struct file *file; | 390 | struct file *file; |
| 372 | struct kiocb rw; | 391 | struct io_rw rw; |
| 373 | struct io_poll_iocb poll; | 392 | struct io_poll_iocb poll; |
| 374 | struct io_accept accept; | 393 | struct io_accept accept; |
| 375 | struct io_sync sync; | 394 | struct io_sync sync; |
| 376 | struct io_cancel cancel; | 395 | struct io_cancel cancel; |
| 377 | struct io_timeout timeout; | 396 | struct io_timeout timeout; |
| 397 | struct io_connect connect; | ||
| 398 | struct io_sr_msg sr_msg; | ||
| 378 | }; | 399 | }; |
| 379 | 400 | ||
| 380 | const struct io_uring_sqe *sqe; | ||
| 381 | struct io_async_ctx *io; | 401 | struct io_async_ctx *io; |
| 382 | struct file *ring_file; | 402 | struct file *ring_file; |
| 383 | int ring_fd; | 403 | int ring_fd; |
| @@ -411,7 +431,6 @@ struct io_kiocb { · 27 unmodified lines | |||
| 411 | #define REQ_F_INFLIGHT 16384 /* on inflight list */ | 431 | #define REQ_F_INFLIGHT 16384 /* on inflight list */ |
| 412 | #define REQ_F_COMP_LOCKED 32768 /* completion under lock */ | 432 | #define REQ_F_COMP_LOCKED 32768 /* completion under lock */ |
| 413 | #define REQ_F_HARDLINK 65536 /* doesn't sever on completion < 0 */ | 433 | #define REQ_F_HARDLINK 65536 /* doesn't sever on completion < 0 */ |
| 414 | #define REQ_F_PREPPED 131072 /* request already opcode prepared */ | ||
| 415 | u64 user_data; | 434 | u64 user_data; |
| 416 | u32 result; | 435 | u32 result; |
| 417 | u32 sequence; | 436 | u32 sequence; |
| @@ -609,33 +628,31 @@ static inline bool io_prep_async_work(struct io_kiocb *req, · 191 unmodified lines | |||
| 609 | { | 628 | { |
| 610 | bool do_hashed = false; | 629 | bool do_hashed = false; |
| 611 | 630 | ||
| 612 | if (req->sqe) { | 631 | switch (req->opcode) { |
| 613 | switch (req->opcode) { | 632 | case IORING_OP_WRITEV: |
| 614 | case IORING_OP_WRITEV: | 633 | case IORING_OP_WRITE_FIXED: |
| 615 | case IORING_OP_WRITE_FIXED: | 634 | /* only regular files should be hashed for writes */ |
| 616 | /* only regular files should be hashed for writes */ | 635 | if (req->flags & REQ_F_ISREG) |
| 617 | if (req->flags & REQ_F_ISREG) | 636 | do_hashed = true; |
| 618 | do_hashed = true; | 637 | /* fall-through */ |
| 619 | /* fall-through */ | 638 | case IORING_OP_READV: |
| 620 | case IORING_OP_READV: | 639 | case IORING_OP_READ_FIXED: |
| 621 | case IORING_OP_READ_FIXED: | 640 | case IORING_OP_SENDMSG: |
| 622 | case IORING_OP_SENDMSG: | 641 | case IORING_OP_RECVMSG: |
| 623 | case IORING_OP_RECVMSG: | 642 | case IORING_OP_ACCEPT: |
| 624 | case IORING_OP_ACCEPT: | 643 | case IORING_OP_POLL_ADD: |
| 625 | case IORING_OP_POLL_ADD: | 644 | case IORING_OP_CONNECT: |
| 626 | case IORING_OP_CONNECT: | 645 | /* |
| 627 | /* | 646 | * We know REQ_F_ISREG is not set on some of these |
| 628 | * We know REQ_F_ISREG is not set on some of these | 647 | * opcodes, but this enables us to keep the check in |
| 629 | * opcodes, but this enables us to keep the check in | 648 | * just one place. |
| 630 | * just one place. | 649 | */ |
| 631 | */ | 650 | if (!(req->flags & REQ_F_ISREG)) |
| 632 | if (!(req->flags & REQ_F_ISREG)) | 651 | req->work.flags |= IO_WQ_WORK_UNBOUND; |
| 633 | req->work.flags |= IO_WQ_WORK_UNBOUND; | 652 | break; |
| 634 | break; | ||
| 635 | } | ||
| 636 | if (io_req_needs_user(req)) | ||
| 637 | req->work.flags |= IO_WQ_WORK_NEEDS_USER; | ||
| 638 | } | 653 | } |
| 654 | if (io_req_needs_user(req)) | ||
| 655 | req->work.flags |= IO_WQ_WORK_NEEDS_USER; | ||
| 639 | 656 | ||
| 640 | *link = io_prep_linked_timeout(req); | 657 | *link = io_prep_linked_timeout(req); |
| 641 | return do_hashed; | 658 | return do_hashed; |
| @@ -1180,7 +1197,7 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events, · 538 unmodified lines | |||
| 1180 | 1197 | ||
| 1181 | ret = 0; | 1198 | ret = 0; |
| 1182 | list_for_each_entry_safe(req, tmp, &ctx->poll_list, list) { | 1199 | list_for_each_entry_safe(req, tmp, &ctx->poll_list, list) { |
| 1183 | struct kiocb *kiocb = &req->rw; | 1200 | struct kiocb *kiocb = &req->rw.kiocb; |
| 1184 | 1201 | ||
| 1185 | /* | 1202 | /* |
| 1186 | * Move completed entries to our local list. If we find a | 1203 | * Move completed entries to our local list. If we find a |
| @@ -1335,7 +1352,7 @@ static inline void req_set_fail_links(struct io_kiocb *req) · 148 unmodified lines | |||
| 1335 | 1352 | ||
| 1336 | static void io_complete_rw_common(struct kiocb *kiocb, long res) | 1353 | static void io_complete_rw_common(struct kiocb *kiocb, long res) |
| 1337 | { | 1354 | { |
| 1338 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw); | 1355 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb); |
| 1339 | 1356 | ||
| 1340 | if (kiocb->ki_flags & IOCB_WRITE) | 1357 | if (kiocb->ki_flags & IOCB_WRITE) |
| 1341 | kiocb_end_write(req); | 1358 | kiocb_end_write(req); |
| @@ -1347,7 +1364,7 @@ static void io_complete_rw_common(struct kiocb *kiocb, long res) · 5 unmodified lines | |||
| 1347 | 1364 | ||
| 1348 | static void io_complete_rw(struct kiocb *kiocb, long res, long res2) | 1365 | static void io_complete_rw(struct kiocb *kiocb, long res, long res2) |
| 1349 | { | 1366 | { |
| 1350 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw); | 1367 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb); |
| 1351 | 1368 | ||
| 1352 | io_complete_rw_common(kiocb, res); | 1369 | io_complete_rw_common(kiocb, res); |
| 1353 | io_put_req(req); | 1370 | io_put_req(req); |
| @@ -1355,7 +1372,7 @@ static void io_complete_rw(struct kiocb *kiocb, long res, long res2) · 1 unmodified line | |||
| 1355 | 1372 | ||
| 1356 | static struct io_kiocb *__io_complete_rw(struct kiocb *kiocb, long res) | 1373 | static struct io_kiocb *__io_complete_rw(struct kiocb *kiocb, long res) |
| 1357 | { | 1374 | { |
| 1358 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw); | 1375 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb); |
| 1359 | struct io_kiocb *nxt = NULL; | 1376 | struct io_kiocb *nxt = NULL; |
| 1360 | 1377 | ||
| 1361 | io_complete_rw_common(kiocb, res); | 1378 | io_complete_rw_common(kiocb, res); |
| @@ -1366,7 +1383,7 @@ static struct io_kiocb *__io_complete_rw(struct kiocb *kiocb, long res) · 4 unmodified lines | |||
| 1366 | 1383 | ||
| 1367 | static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2) | 1384 | static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2) |
| 1368 | { | 1385 | { |
| 1369 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw); | 1386 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb); |
| 1370 | 1387 | ||
| 1371 | if (kiocb->ki_flags & IOCB_WRITE) | 1388 | if (kiocb->ki_flags & IOCB_WRITE) |
| 1372 | kiocb_end_write(req); | 1389 | kiocb_end_write(req); |
| @@ -1400,7 +1417,7 @@ static void io_iopoll_req_issued(struct io_kiocb *req) · 27 unmodified lines | |||
| 1400 | 1417 | ||
| 1401 | list_req = list_first_entry(&ctx->poll_list, struct io_kiocb, | 1418 | list_req = list_first_entry(&ctx->poll_list, struct io_kiocb, |
| 1402 | list); | 1419 | list); |
| 1403 | if (list_req->rw.ki_filp != req->rw.ki_filp) | 1420 | if (list_req->file != req->file) |
| 1404 | ctx->poll_multi_file = true; | 1421 | ctx->poll_multi_file = true; |
| 1405 | } | 1422 | } |
| 1406 | 1423 | ||
| @@ -1471,11 +1488,11 @@ static bool io_file_supports_async(struct file *file) · 64 unmodified lines | |||
| 1471 | return false; | 1488 | return false; |
| 1472 | } | 1489 | } |
| 1473 | 1490 | ||
| 1474 | static int io_prep_rw(struct io_kiocb *req, bool force_nonblock) | 1491 | static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| 1492 | bool force_nonblock) | ||
| 1475 | { | 1493 | { |
| 1476 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 1477 | struct io_ring_ctx *ctx = req->ctx; | 1494 | struct io_ring_ctx *ctx = req->ctx; |
| 1478 | struct kiocb *kiocb = &req->rw; | 1495 | struct kiocb *kiocb = &req->rw.kiocb; |
| 1479 | unsigned ioprio; | 1496 | unsigned ioprio; |
| 1480 | int ret; | 1497 | int ret; |
| 1481 | 1498 | ||
| @@ -1524,6 +1541,12 @@ static int io_prep_rw(struct io_kiocb *req, bool force_nonblock) · 42 unmodified lines | |||
| 1524 | return -EINVAL; | 1541 | return -EINVAL; |
| 1525 | kiocb->ki_complete = io_complete_rw; | 1542 | kiocb->ki_complete = io_complete_rw; |
| 1526 | } | 1543 | } |
| 1544 | |||
| 1545 | req->rw.addr = READ_ONCE(sqe->addr); | ||
| 1546 | req->rw.len = READ_ONCE(sqe->len); | ||
| 1547 | /* we own ->private, reuse it for the buffer index */ | ||
| 1548 | req->rw.kiocb.private = (void *) (unsigned long) | ||
| 1549 | READ_ONCE(sqe->buf_index); | ||
| 1527 | return 0; | 1550 | return 0; |
| 1528 | } | 1551 | } |
| 1529 | 1552 | ||
| @@ -1557,11 +1580,11 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, struct io_kiocb **nxt, · 27 unmodified lines | |||
| 1557 | io_rw_done(kiocb, ret); | 1580 | io_rw_done(kiocb, ret); |
| 1558 | } | 1581 | } |
| 1559 | 1582 | ||
| 1560 | static ssize_t io_import_fixed(struct io_ring_ctx *ctx, int rw, | 1583 | static ssize_t io_import_fixed(struct io_kiocb *req, int rw, |
| 1561 | const struct io_uring_sqe *sqe, | ||
| 1562 | struct iov_iter *iter) | 1584 | struct iov_iter *iter) |
| 1563 | { | 1585 | { |
| 1564 | size_t len = READ_ONCE(sqe->len); | 1586 | struct io_ring_ctx *ctx = req->ctx; |
| 1587 | size_t len = req->rw.len; | ||
| 1565 | struct io_mapped_ubuf *imu; | 1588 | struct io_mapped_ubuf *imu; |
| 1566 | unsigned index, buf_index; | 1589 | unsigned index, buf_index; |
| 1567 | size_t offset; | 1590 | size_t offset; |
| @@ -1571,13 +1594,13 @@ static ssize_t io_import_fixed(struct io_ring_ctx *ctx, int rw, · 3 unmodified lines | |||
| 1571 | if (unlikely(!ctx->user_bufs)) | 1594 | if (unlikely(!ctx->user_bufs)) |
| 1572 | return -EFAULT; | 1595 | return -EFAULT; |
| 1573 | 1596 | ||
| 1574 | buf_index = READ_ONCE(sqe->buf_index); | 1597 | buf_index = (unsigned long) req->rw.kiocb.private; |
| 1575 | if (unlikely(buf_index >= ctx->nr_user_bufs)) | 1598 | if (unlikely(buf_index >= ctx->nr_user_bufs)) |
| 1576 | return -EFAULT; | 1599 | return -EFAULT; |
| 1577 | 1600 | ||
| 1578 | index = array_index_nospec(buf_index, ctx->nr_user_bufs); | 1601 | index = array_index_nospec(buf_index, ctx->nr_user_bufs); |
| 1579 | imu = &ctx->user_bufs[index]; | 1602 | imu = &ctx->user_bufs[index]; |
| 1580 | buf_addr = READ_ONCE(sqe->addr); | 1603 | buf_addr = req->rw.addr; |
| 1581 | 1604 | ||
| 1582 | /* overflow */ | 1605 | /* overflow */ |
| 1583 | if (buf_addr + len < buf_addr) | 1606 | if (buf_addr + len < buf_addr) |
| @@ -1634,25 +1657,20 @@ static ssize_t io_import_fixed(struct io_ring_ctx *ctx, int rw, · 50 unmodified lines | |||
| 1634 | static ssize_t io_import_iovec(int rw, struct io_kiocb *req, | 1657 | static ssize_t io_import_iovec(int rw, struct io_kiocb *req, |
| 1635 | struct iovec **iovec, struct iov_iter *iter) | 1658 | struct iovec **iovec, struct iov_iter *iter) |
| 1636 | { | 1659 | { |
| 1637 | const struct io_uring_sqe *sqe = req->sqe; | 1660 | void __user *buf = u64_to_user_ptr(req->rw.addr); |
| 1638 | void __user *buf = u64_to_user_ptr(READ_ONCE(sqe->addr)); | 1661 | size_t sqe_len = req->rw.len; |
| 1639 | size_t sqe_len = READ_ONCE(sqe->len); | ||
| 1640 | u8 opcode; | 1662 | u8 opcode; |
| 1641 | 1663 | ||
| 1642 | /* | ||
| 1643 | * We're reading ->opcode for the second time, but the first read | ||
| 1644 | * doesn't care whether it's _FIXED or not, so it doesn't matter | ||
| 1645 | * whether ->opcode changes concurrently. The first read does care | ||
| 1646 | * about whether it is a READ or a WRITE, so we don't trust this read | ||
| 1647 | * for that purpose and instead let the caller pass in the read/write | ||
| 1648 | * flag. | ||
| 1649 | */ | ||
| 1650 | opcode = req->opcode; | 1664 | opcode = req->opcode; |
| 1651 | if (opcode == IORING_OP_READ_FIXED || opcode == IORING_OP_WRITE_FIXED) { | 1665 | if (opcode == IORING_OP_READ_FIXED || opcode == IORING_OP_WRITE_FIXED) { |
| 1652 | *iovec = NULL; | 1666 | *iovec = NULL; |
| 1653 | return io_import_fixed(req->ctx, rw, sqe, iter); | 1667 | return io_import_fixed(req, rw, iter); |
| 1654 | } | 1668 | } |
| 1655 | 1669 | ||
| 1670 | /* buffer index only valid with fixed read/write */ | ||
| 1671 | if (req->rw.kiocb.private) | ||
| 1672 | return -EINVAL; | ||
| 1673 | |||
| 1656 | if (req->io) { | 1674 | if (req->io) { |
| 1657 | struct io_async_rw *iorw = &req->io->rw; | 1675 | struct io_async_rw *iorw = &req->io->rw; |
| 1658 | 1676 | ||
| @@ -1750,13 +1768,7 @@ static void io_req_map_rw(struct io_kiocb *req, ssize_t io_size, · 91 unmodified lines | |||
| 1750 | static int io_alloc_async_ctx(struct io_kiocb *req) | 1768 | static int io_alloc_async_ctx(struct io_kiocb *req) |
| 1751 | { | 1769 | { |
| 1752 | req->io = kmalloc(sizeof(*req->io), GFP_KERNEL); | 1770 | req->io = kmalloc(sizeof(*req->io), GFP_KERNEL); |
| 1753 | if (req->io) { | 1771 | return req->io == NULL; |
| 1754 | memcpy(&req->io->sqe, req->sqe, sizeof(req->io->sqe)); | ||
| 1755 | req->sqe = &req->io->sqe; | ||
| 1756 | return 0; | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | return 1; | ||
| 1760 | } | 1772 | } |
| 1761 | 1773 | ||
| 1762 | static void io_rw_async(struct io_wq_work **workptr) | 1774 | static void io_rw_async(struct io_wq_work **workptr) |
| @@ -1782,46 +1794,52 @@ static int io_setup_async_rw(struct io_kiocb *req, ssize_t io_size, · 19 unmodified lines | |||
| 1782 | return 0; | 1794 | return 0; |
| 1783 | } | 1795 | } |
| 1784 | 1796 | ||
| 1785 | static int io_read_prep(struct io_kiocb *req, struct iovec **iovec, | 1797 | static int io_read_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| 1786 | struct iov_iter *iter, bool force_nonblock) | 1798 | bool force_nonblock) |
| 1787 | { | 1799 | { |
| 1800 | struct io_async_ctx *io; | ||
| 1801 | struct iov_iter iter; | ||
| 1788 | ssize_t ret; | 1802 | ssize_t ret; |
| 1789 | 1803 | ||
| 1790 | ret = io_prep_rw(req, force_nonblock); | 1804 | ret = io_prep_rw(req, sqe, force_nonblock); |
| 1791 | if (ret) | 1805 | if (ret) |
| 1792 | return ret; | 1806 | return ret; |
| 1793 | 1807 | ||
| 1794 | if (unlikely(!(req->file->f_mode & FMODE_READ))) | 1808 | if (unlikely(!(req->file->f_mode & FMODE_READ))) |
| 1795 | return -EBADF; | 1809 | return -EBADF; |
| 1796 | 1810 | ||
| 1797 | return io_import_iovec(READ, req, iovec, iter); | 1811 | if (!req->io) |
| 1812 | return 0; | ||
| 1813 | |||
| 1814 | io = req->io; | ||
| 1815 | io->rw.iov = io->rw.fast_iov; | ||
| 1816 | req->io = NULL; | ||
| 1817 | ret = io_import_iovec(READ, req, &io->rw.iov, &iter); | ||
| 1818 | req->io = io; | ||
| 1819 | if (ret < 0) | ||
| 1820 | return ret; | ||
| 1821 | |||
| 1822 | io_req_map_rw(req, ret, io->rw.iov, io->rw.fast_iov, &iter); | ||
| 1823 | return 0; | ||
| 1798 | } | 1824 | } |
| 1799 | 1825 | ||
| 1800 | static int io_read(struct io_kiocb *req, struct io_kiocb **nxt, | 1826 | static int io_read(struct io_kiocb *req, struct io_kiocb **nxt, |
| 1801 | bool force_nonblock) | 1827 | bool force_nonblock) |
| 1802 | { | 1828 | { |
| 1803 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; | 1829 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; |
| 1804 | struct kiocb *kiocb = &req->rw; | 1830 | struct kiocb *kiocb = &req->rw.kiocb; |
| 1805 | struct iov_iter iter; | 1831 | struct iov_iter iter; |
| 1806 | struct file *file; | ||
| 1807 | size_t iov_count; | 1832 | size_t iov_count; |
| 1808 | ssize_t io_size, ret; | 1833 | ssize_t io_size, ret; |
| 1809 | 1834 | ||
| 1810 | if (!req->io) { | 1835 | ret = io_import_iovec(READ, req, &iovec, &iter); |
| 1811 | ret = io_read_prep(req, &iovec, &iter, force_nonblock); | 1836 | if (ret < 0) |
| 1812 | if (ret < 0) | 1837 | return ret; |
| 1813 | return ret; | ||
| 1814 | } else { | ||
| 1815 | ret = io_import_iovec(READ, req, &iovec, &iter); | ||
| 1816 | if (ret < 0) | ||
| 1817 | return ret; | ||
| 1818 | } | ||
| 1819 | 1838 | ||
| 1820 | /* Ensure we clear previously set non-block flag */ | 1839 | /* Ensure we clear previously set non-block flag */ |
| 1821 | if (!force_nonblock) | 1840 | if (!force_nonblock) |
| 1822 | req->rw.ki_flags &= ~IOCB_NOWAIT; | 1841 | req->rw.kiocb.ki_flags &= ~IOCB_NOWAIT; |
| 1823 | 1842 | ||
| 1824 | file = req->file; | ||
| 1825 | io_size = ret; | 1843 | io_size = ret; |
| 1826 | if (req->flags & REQ_F_LINK) | 1844 | if (req->flags & REQ_F_LINK) |
| 1827 | req->result = io_size; | 1845 | req->result = io_size; |
| @@ -1830,33 +1848,21 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt, · 2 unmodified lines | |||
| 1830 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so | 1848 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so |
| 1831 | * we know to async punt it even if it was opened O_NONBLOCK | 1849 | * we know to async punt it even if it was opened O_NONBLOCK |
| 1832 | */ | 1850 | */ |
| 1833 | if (force_nonblock && !io_file_supports_async(file)) { | 1851 | if (force_nonblock && !io_file_supports_async(req->file)) { |
| 1834 | req->flags |= REQ_F_MUST_PUNT; | 1852 | req->flags |= REQ_F_MUST_PUNT; |
| 1835 | goto copy_iov; | 1853 | goto copy_iov; |
| 1836 | } | 1854 | } |
| 1837 | 1855 | ||
| 1838 | iov_count = iov_iter_count(&iter); | 1856 | iov_count = iov_iter_count(&iter); |
| 1839 | ret = rw_verify_area(READ, file, &kiocb->ki_pos, iov_count); | 1857 | ret = rw_verify_area(READ, req->file, &kiocb->ki_pos, iov_count); |
| 1840 | if (!ret) { | 1858 | if (!ret) { |
| 1841 | ssize_t ret2; | 1859 | ssize_t ret2; |
| 1842 | 1860 | ||
| 1843 | if (file->f_op->read_iter) | 1861 | if (req->file->f_op->read_iter) |
| 1844 | ret2 = call_read_iter(file, kiocb, &iter); | 1862 | ret2 = call_read_iter(req->file, kiocb, &iter); |
| 1845 | else | 1863 | else |
| 1846 | ret2 = loop_rw_iter(READ, file, kiocb, &iter); | 1864 | ret2 = loop_rw_iter(READ, req->file, kiocb, &iter); |
| 1847 | 1865 | ||
| 1848 | /* | ||
| 1849 | * In case of a short read, punt to async. This can happen | ||
| 1850 | * if we have data partially cached. Alternatively we can | ||
| 1851 | * return the short read, in which case the application will | ||
| 1852 | * need to issue another SQE and wait for it. That SQE will | ||
| 1853 | * need async punt anyway, so it's more efficient to do it | ||
| 1854 | * here. | ||
| 1855 | */ | ||
| 1856 | if (force_nonblock && !(req->flags & REQ_F_NOWAIT) && | ||
| 1857 | (req->flags & REQ_F_ISREG) && | ||
| 1858 | ret2 > 0 && ret2 < io_size) | ||
| 1859 | ret2 = -EAGAIN; | ||
| 1860 | /* Catch -EAGAIN return for forced non-blocking submission */ | 1866 | /* Catch -EAGAIN return for forced non-blocking submission */ |
| 1861 | if (!force_nonblock || ret2 != -EAGAIN) { | 1867 | if (!force_nonblock || ret2 != -EAGAIN) { |
| 1862 | kiocb_done(kiocb, ret2, nxt, req->in_async); | 1868 | kiocb_done(kiocb, ret2, nxt, req->in_async); |
| @@ -1875,46 +1881,52 @@ out_free: · 12 unmodified lines | |||
| 1875 | return ret; | 1881 | return ret; |
| 1876 | } | 1882 | } |
| 1877 | 1883 | ||
| 1878 | static int io_write_prep(struct io_kiocb *req, struct iovec **iovec, | 1884 | static int io_write_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| 1879 | struct iov_iter *iter, bool force_nonblock) | 1885 | bool force_nonblock) |
| 1880 | { | 1886 | { |
| 1887 | struct io_async_ctx *io; | ||
| 1888 | struct iov_iter iter; | ||
| 1881 | ssize_t ret; | 1889 | ssize_t ret; |
| 1882 | 1890 | ||
| 1883 | ret = io_prep_rw(req, force_nonblock); | 1891 | ret = io_prep_rw(req, sqe, force_nonblock); |
| 1884 | if (ret) | 1892 | if (ret) |
| 1885 | return ret; | 1893 | return ret; |
| 1886 | 1894 | ||
| 1887 | if (unlikely(!(req->file->f_mode & FMODE_WRITE))) | 1895 | if (unlikely(!(req->file->f_mode & FMODE_WRITE))) |
| 1888 | return -EBADF; | 1896 | return -EBADF; |
| 1889 | 1897 | ||
| 1890 | return io_import_iovec(WRITE, req, iovec, iter); | 1898 | if (!req->io) |
| 1899 | return 0; | ||
| 1900 | |||
| 1901 | io = req->io; | ||
| 1902 | io->rw.iov = io->rw.fast_iov; | ||
| 1903 | req->io = NULL; | ||
| 1904 | ret = io_import_iovec(WRITE, req, &io->rw.iov, &iter); | ||
| 1905 | req->io = io; | ||
| 1906 | if (ret < 0) | ||
| 1907 | return ret; | ||
| 1908 | |||
| 1909 | io_req_map_rw(req, ret, io->rw.iov, io->rw.fast_iov, &iter); | ||
| 1910 | return 0; | ||
| 1891 | } | 1911 | } |
| 1892 | 1912 | ||
| 1893 | static int io_write(struct io_kiocb *req, struct io_kiocb **nxt, | 1913 | static int io_write(struct io_kiocb *req, struct io_kiocb **nxt, |
| 1894 | bool force_nonblock) | 1914 | bool force_nonblock) |
| 1895 | { | 1915 | { |
| 1896 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; | 1916 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; |
| 1897 | struct kiocb *kiocb = &req->rw; | 1917 | struct kiocb *kiocb = &req->rw.kiocb; |
| 1898 | struct iov_iter iter; | 1918 | struct iov_iter iter; |
| 1899 | struct file *file; | ||
| 1900 | size_t iov_count; | 1919 | size_t iov_count; |
| 1901 | ssize_t ret, io_size; | 1920 | ssize_t ret, io_size; |
| 1902 | 1921 | ||
| 1903 | if (!req->io) { | 1922 | ret = io_import_iovec(WRITE, req, &iovec, &iter); |
| 1904 | ret = io_write_prep(req, &iovec, &iter, force_nonblock); | 1923 | if (ret < 0) |
| 1905 | if (ret < 0) | 1924 | return ret; |
| 1906 | return ret; | ||
| 1907 | } else { | ||
| 1908 | ret = io_import_iovec(WRITE, req, &iovec, &iter); | ||
| 1909 | if (ret < 0) | ||
| 1910 | return ret; | ||
| 1911 | } | ||
| 1912 | 1925 | ||
| 1913 | /* Ensure we clear previously set non-block flag */ | 1926 | /* Ensure we clear previously set non-block flag */ |
| 1914 | if (!force_nonblock) | 1927 | if (!force_nonblock) |
| 1915 | req->rw.ki_flags &= ~IOCB_NOWAIT; | 1928 | req->rw.kiocb.ki_flags &= ~IOCB_NOWAIT; |
| 1916 | 1929 | ||
| 1917 | file = kiocb->ki_filp; | ||
| 1918 | io_size = ret; | 1930 | io_size = ret; |
| 1919 | if (req->flags & REQ_F_LINK) | 1931 | if (req->flags & REQ_F_LINK) |
| 1920 | req->result = io_size; | 1932 | req->result = io_size; |
| @@ -1934,7 +1946,7 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt, · 13 unmodified lines | |||
| 1934 | goto copy_iov; | 1946 | goto copy_iov; |
| 1935 | 1947 | ||
| 1936 | iov_count = iov_iter_count(&iter); | 1948 | iov_count = iov_iter_count(&iter); |
| 1937 | ret = rw_verify_area(WRITE, file, &kiocb->ki_pos, iov_count); | 1949 | ret = rw_verify_area(WRITE, req->file, &kiocb->ki_pos, iov_count); |
| 1938 | if (!ret) { | 1950 | if (!ret) { |
| 1939 | ssize_t ret2; | 1951 | ssize_t ret2; |
| 1940 | 1952 | ||
| @@ -1946,17 +1958,17 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt, · 5 unmodified lines | |||
| 1946 | * we return to userspace. | 1958 | * we return to userspace. |
| 1947 | */ | 1959 | */ |
| 1948 | if (req->flags & REQ_F_ISREG) { | 1960 | if (req->flags & REQ_F_ISREG) { |
| 1949 | __sb_start_write(file_inode(file)->i_sb, | 1961 | __sb_start_write(file_inode(req->file)->i_sb, |
| 1950 | SB_FREEZE_WRITE, true); | 1962 | SB_FREEZE_WRITE, true); |
| 1951 | __sb_writers_release(file_inode(file)->i_sb, | 1963 | __sb_writers_release(file_inode(req->file)->i_sb, |
| 1952 | SB_FREEZE_WRITE); | 1964 | SB_FREEZE_WRITE); |
| 1953 | } | 1965 | } |
| 1954 | kiocb->ki_flags |= IOCB_WRITE; | 1966 | kiocb->ki_flags |= IOCB_WRITE; |
| 1955 | 1967 | ||
| 1956 | if (file->f_op->write_iter) | 1968 | if (req->file->f_op->write_iter) |
| 1957 | ret2 = call_write_iter(file, kiocb, &iter); | 1969 | ret2 = call_write_iter(req->file, kiocb, &iter); |
| 1958 | else | 1970 | else |
| 1959 | ret2 = loop_rw_iter(WRITE, file, kiocb, &iter); | 1971 | ret2 = loop_rw_iter(WRITE, req->file, kiocb, &iter); |
| 1960 | if (!force_nonblock || ret2 != -EAGAIN) { | 1972 | if (!force_nonblock || ret2 != -EAGAIN) { |
| 1961 | kiocb_done(kiocb, ret2, nxt, req->in_async); | 1973 | kiocb_done(kiocb, ret2, nxt, req->in_async); |
| 1962 | } else { | 1974 | } else { |
| @@ -1989,13 +2001,10 @@ static int io_nop(struct io_kiocb *req) · 26 unmodified lines | |||
| 1989 | return 0; | 2001 | return 0; |
| 1990 | } | 2002 | } |
| 1991 | 2003 | ||
| 1992 | static int io_prep_fsync(struct io_kiocb *req) | 2004 | static int io_prep_fsync(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 1993 | { | 2005 | { |
| 1994 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 1995 | struct io_ring_ctx *ctx = req->ctx; | 2006 | struct io_ring_ctx *ctx = req->ctx; |
| 1996 | 2007 | ||
| 1997 | if (req->flags & REQ_F_PREPPED) | ||
| 1998 | return 0; | ||
| 1999 | if (!req->file) | 2008 | if (!req->file) |
| 2000 | return -EBADF; | 2009 | return -EBADF; |
| 2001 | 2010 | ||
| @@ -2010,7 +2019,6 @@ static int io_prep_fsync(struct io_kiocb *req) · 8 unmodified lines | |||
| 2010 | 2019 | ||
| 2011 | req->sync.off = READ_ONCE(sqe->off); | 2020 | req->sync.off = READ_ONCE(sqe->off); |
| 2012 | req->sync.len = READ_ONCE(sqe->len); | 2021 | req->sync.len = READ_ONCE(sqe->len); |
| 2013 | req->flags |= REQ_F_PREPPED; | ||
| 2014 | return 0; | 2022 | return 0; |
| 2015 | } | 2023 | } |
| 2016 | 2024 | ||
| @@ -2036,7 +2044,7 @@ static void io_fsync_finish(struct io_wq_work **workptr) · 19 unmodified lines | |||
| 2036 | if (io_req_cancelled(req)) | 2044 | if (io_req_cancelled(req)) |
| 2037 | return; | 2045 | return; |
| 2038 | 2046 | ||
| 2039 | ret = vfs_fsync_range(req->rw.ki_filp, req->sync.off, | 2047 | ret = vfs_fsync_range(req->file, req->sync.off, |
| 2040 | end > 0 ? end : LLONG_MAX, | 2048 | end > 0 ? end : LLONG_MAX, |
| 2041 | req->sync.flags & IORING_FSYNC_DATASYNC); | 2049 | req->sync.flags & IORING_FSYNC_DATASYNC); |
| 2042 | if (ret < 0) | 2050 | if (ret < 0) |
| @@ -2051,11 +2059,6 @@ static int io_fsync(struct io_kiocb *req, struct io_kiocb **nxt, · 8 unmodified lines | |||
| 2051 | bool force_nonblock) | 2059 | bool force_nonblock) |
| 2052 | { | 2060 | { |
| 2053 | struct io_wq_work *work, *old_work; | 2061 | struct io_wq_work *work, *old_work; |
| 2054 | int ret; | ||
| 2055 | |||
| 2056 | ret = io_prep_fsync(req); | ||
| 2057 | if (ret) | ||
| 2058 | return ret; | ||
| 2059 | 2062 | ||
| 2060 | /* fsync always requires a blocking context */ | 2063 | /* fsync always requires a blocking context */ |
| 2061 | if (force_nonblock) { | 2064 | if (force_nonblock) { |
| @@ -2071,13 +2074,10 @@ static int io_fsync(struct io_kiocb *req, struct io_kiocb **nxt, · 9 unmodified lines | |||
| 2071 | return 0; | 2074 | return 0; |
| 2072 | } | 2075 | } |
| 2073 | 2076 | ||
| 2074 | static int io_prep_sfr(struct io_kiocb *req) | 2077 | static int io_prep_sfr(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 2075 | { | 2078 | { |
| 2076 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2077 | struct io_ring_ctx *ctx = req->ctx; | 2079 | struct io_ring_ctx *ctx = req->ctx; |
| 2078 | 2080 | ||
| 2079 | if (req->flags & REQ_F_PREPPED) | ||
| 2080 | return 0; | ||
| 2081 | if (!req->file) | 2081 | if (!req->file) |
| 2082 | return -EBADF; | 2082 | return -EBADF; |
| 2083 | 2083 | ||
| @@ -2089,7 +2089,6 @@ static int io_prep_sfr(struct io_kiocb *req) · 5 unmodified lines | |||
| 2089 | req->sync.off = READ_ONCE(sqe->off); | 2089 | req->sync.off = READ_ONCE(sqe->off); |
| 2090 | req->sync.len = READ_ONCE(sqe->len); | 2090 | req->sync.len = READ_ONCE(sqe->len); |
| 2091 | req->sync.flags = READ_ONCE(sqe->sync_range_flags); | 2091 | req->sync.flags = READ_ONCE(sqe->sync_range_flags); |
| 2092 | req->flags |= REQ_F_PREPPED; | ||
| 2093 | return 0; | 2092 | return 0; |
| 2094 | } | 2093 | } |
| 2095 | 2094 | ||
| @@ -2102,7 +2101,7 @@ static void io_sync_file_range_finish(struct io_wq_work **workptr) · 6 unmodified lines | |||
| 2102 | if (io_req_cancelled(req)) | 2101 | if (io_req_cancelled(req)) |
| 2103 | return; | 2102 | return; |
| 2104 | 2103 | ||
| 2105 | ret = sync_file_range(req->rw.ki_filp, req->sync.off, req->sync.len, | 2104 | ret = sync_file_range(req->file, req->sync.off, req->sync.len, |
| 2106 | req->sync.flags); | 2105 | req->sync.flags); |
| 2107 | if (ret < 0) | 2106 | if (ret < 0) |
| 2108 | req_set_fail_links(req); | 2107 | req_set_fail_links(req); |
| @@ -2116,11 +2115,6 @@ static int io_sync_file_range(struct io_kiocb *req, struct io_kiocb **nxt, · 7 unmodified lines | |||
| 2116 | bool force_nonblock) | 2115 | bool force_nonblock) |
| 2117 | { | 2116 | { |
| 2118 | struct io_wq_work *work, *old_work; | 2117 | struct io_wq_work *work, *old_work; |
| 2119 | int ret; | ||
| 2120 | |||
| 2121 | ret = io_prep_sfr(req); | ||
| 2122 | if (ret) | ||
| 2123 | return ret; | ||
| 2124 | 2118 | ||
| 2125 | /* sync_file_range always requires a blocking context */ | 2119 | /* sync_file_range always requires a blocking context */ |
| 2126 | if (force_nonblock) { | 2120 | if (force_nonblock) { |
| @@ -2149,19 +2143,23 @@ static void io_sendrecv_async(struct io_wq_work **workptr) · 22 unmodified lines | |||
| 2149 | } | 2143 | } |
| 2150 | #endif | 2144 | #endif |
| 2151 | 2145 | ||
| 2152 | static int io_sendmsg_prep(struct io_kiocb *req, struct io_async_ctx *io) | 2146 | static int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 2153 | { | 2147 | { |
| 2154 | #if defined(CONFIG_NET) | 2148 | #if defined(CONFIG_NET) |
| 2155 | const struct io_uring_sqe *sqe = req->sqe; | 2149 | struct io_sr_msg *sr = &req->sr_msg; |
| 2156 | struct user_msghdr __user *msg; | 2150 | struct io_async_ctx *io = req->io; |
| 2157 | unsigned flags; | 2151 | |
| 2152 | sr->msg_flags = READ_ONCE(sqe->msg_flags); | ||
| 2153 | sr->msg = u64_to_user_ptr(READ_ONCE(sqe->addr)); | ||
| 2154 | |||
| 2155 | if (!io) | ||
| 2156 | return 0; | ||
| 2158 | 2157 | ||
| 2159 | flags = READ_ONCE(sqe->msg_flags); | ||
| 2160 | msg = (struct user_msghdr __user *)(unsigned long) READ_ONCE(sqe->addr); | ||
| 2161 | io->msg.iov = io->msg.fast_iov; | 2158 | io->msg.iov = io->msg.fast_iov; |
| 2162 | return sendmsg_copy_msghdr(&io->msg.msg, msg, flags, &io->msg.iov); | 2159 | return sendmsg_copy_msghdr(&io->msg.msg, sr->msg, sr->msg_flags, |
| 2160 | &io->msg.iov); | ||
| 2163 | #else | 2161 | #else |
| 2164 | return 0; | 2162 | return -EOPNOTSUPP; |
| 2165 | #endif | 2163 | #endif |
| 2166 | } | 2164 | } |
| 2167 | 2165 | ||
| @@ -2169,7 +2167,6 @@ static int io_sendmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 1 unmodified line | |||
| 2169 | bool force_nonblock) | 2167 | bool force_nonblock) |
| 2170 | { | 2168 | { |
| 2171 | #if defined(CONFIG_NET) | 2169 | #if defined(CONFIG_NET) |
| 2172 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2173 | struct io_async_msghdr *kmsg = NULL; | 2170 | struct io_async_msghdr *kmsg = NULL; |
| 2174 | struct socket *sock; | 2171 | struct socket *sock; |
| 2175 | int ret; | 2172 | int ret; |
| @@ -2183,12 +2180,6 @@ static int io_sendmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 7 unmodified lines | |||
| 2183 | struct sockaddr_storage addr; | 2180 | struct sockaddr_storage addr; |
| 2184 | unsigned flags; | 2181 | unsigned flags; |
| 2185 | 2182 | ||
| 2186 | flags = READ_ONCE(sqe->msg_flags); | ||
| 2187 | if (flags & MSG_DONTWAIT) | ||
| 2188 | req->flags |= REQ_F_NOWAIT; | ||
| 2189 | else if (force_nonblock) | ||
| 2190 | flags |= MSG_DONTWAIT; | ||
| 2191 | |||
| 2192 | if (req->io) { | 2183 | if (req->io) { |
| 2193 | kmsg = &req->io->msg; | 2184 | kmsg = &req->io->msg; |
| 2194 | kmsg->msg.msg_name = &addr; | 2185 | kmsg->msg.msg_name = &addr; |
| @@ -2197,13 +2188,24 @@ static int io_sendmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 2 unmodified lines | |||
| 2197 | kmsg->iov = kmsg->fast_iov; | 2188 | kmsg->iov = kmsg->fast_iov; |
| 2198 | kmsg->msg.msg_iter.iov = kmsg->iov; | 2189 | kmsg->msg.msg_iter.iov = kmsg->iov; |
| 2199 | } else { | 2190 | } else { |
| 2191 | struct io_sr_msg *sr = &req->sr_msg; | ||
| 2192 | |||
| 2200 | kmsg = &io.msg; | 2193 | kmsg = &io.msg; |
| 2201 | kmsg->msg.msg_name = &addr; | 2194 | kmsg->msg.msg_name = &addr; |
| 2202 | ret = io_sendmsg_prep(req, &io); | 2195 | |
| 2196 | io.msg.iov = io.msg.fast_iov; | ||
| 2197 | ret = sendmsg_copy_msghdr(&io.msg.msg, sr->msg, | ||
| 2198 | sr->msg_flags, &io.msg.iov); | ||
| 2203 | if (ret) | 2199 | if (ret) |
| 2204 | goto out; | 2200 | return ret; |
| 2205 | } | 2201 | } |
| 2206 | 2202 | ||
| 2203 | flags = req->sr_msg.msg_flags; | ||
| 2204 | if (flags & MSG_DONTWAIT) | ||
| 2205 | req->flags |= REQ_F_NOWAIT; | ||
| 2206 | else if (force_nonblock) | ||
| 2207 | flags |= MSG_DONTWAIT; | ||
| 2208 | |||
| 2207 | ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags); | 2209 | ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags); |
| 2208 | if (force_nonblock && ret == -EAGAIN) { | 2210 | if (force_nonblock && ret == -EAGAIN) { |
| 2209 | if (req->io) | 2211 | if (req->io) |
| @@ -2218,7 +2220,6 @@ static int io_sendmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 8 unmodified lines | |||
| 2218 | ret = -EINTR; | 2220 | ret = -EINTR; |
| 2219 | } | 2221 | } |
| 2220 | 2222 | ||
| 2221 | out: | ||
| 2222 | if (!io_wq_current_is_worker() && kmsg && kmsg->iov != kmsg->fast_iov) | 2223 | if (!io_wq_current_is_worker() && kmsg && kmsg->iov != kmsg->fast_iov) |
| 2223 | kfree(kmsg->iov); | 2224 | kfree(kmsg->iov); |
| 2224 | io_cqring_add_event(req, ret); | 2225 | io_cqring_add_event(req, ret); |
| @@ -2231,20 +2232,24 @@ out: · 6 unmodified lines | |||
| 2231 | #endif | 2232 | #endif |
| 2232 | } | 2233 | } |
| 2233 | 2234 | ||
| 2234 | static int io_recvmsg_prep(struct io_kiocb *req, struct io_async_ctx *io) | 2235 | static int io_recvmsg_prep(struct io_kiocb *req, |
| 2236 | const struct io_uring_sqe *sqe) | ||
| 2235 | { | 2237 | { |
| 2236 | #if defined(CONFIG_NET) | 2238 | #if defined(CONFIG_NET) |
| 2237 | const struct io_uring_sqe *sqe = req->sqe; | 2239 | struct io_sr_msg *sr = &req->sr_msg; |
| 2238 | struct user_msghdr __user *msg; | 2240 | struct io_async_ctx *io = req->io; |
| 2239 | unsigned flags; | 2241 | |
| 2242 | sr->msg_flags = READ_ONCE(sqe->msg_flags); | ||
| 2243 | sr->msg = u64_to_user_ptr(READ_ONCE(sqe->addr)); | ||
| 2244 | |||
| 2245 | if (!io) | ||
| 2246 | return 0; | ||
| 2240 | 2247 | ||
| 2241 | flags = READ_ONCE(sqe->msg_flags); | ||
| 2242 | msg = (struct user_msghdr __user *)(unsigned long) READ_ONCE(sqe->addr); | ||
| 2243 | io->msg.iov = io->msg.fast_iov; | 2248 | io->msg.iov = io->msg.fast_iov; |
| 2244 | return recvmsg_copy_msghdr(&io->msg.msg, msg, flags, &io->msg.uaddr, | 2249 | return recvmsg_copy_msghdr(&io->msg.msg, sr->msg, sr->msg_flags, |
| 2245 | &io->msg.iov); | 2250 | &io->msg.uaddr, &io->msg.iov); |
| 2246 | #else | 2251 | #else |
| 2247 | return 0; | 2252 | return -EOPNOTSUPP; |
| 2248 | #endif | 2253 | #endif |
| 2249 | } | 2254 | } |
| 2250 | 2255 | ||
| @@ -2252,7 +2257,6 @@ static int io_recvmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 1 unmodified line | |||
| 2252 | bool force_nonblock) | 2257 | bool force_nonblock) |
| 2253 | { | 2258 | { |
| 2254 | #if defined(CONFIG_NET) | 2259 | #if defined(CONFIG_NET) |
| 2255 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2256 | struct io_async_msghdr *kmsg = NULL; | 2260 | struct io_async_msghdr *kmsg = NULL; |
| 2257 | struct socket *sock; | 2261 | struct socket *sock; |
| 2258 | int ret; | 2262 | int ret; |
| @@ -2262,19 +2266,10 @@ static int io_recvmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 3 unmodified lines | |||
| 2262 | 2266 | ||
| 2263 | sock = sock_from_file(req->file, &ret); | 2267 | sock = sock_from_file(req->file, &ret); |
| 2264 | if (sock) { | 2268 | if (sock) { |
| 2265 | struct user_msghdr __user *msg; | ||
| 2266 | struct io_async_ctx io; | 2269 | struct io_async_ctx io; |
| 2267 | struct sockaddr_storage addr; | 2270 | struct sockaddr_storage addr; |
| 2268 | unsigned flags; | 2271 | unsigned flags; |
| 2269 | 2272 | ||
| 2270 | flags = READ_ONCE(sqe->msg_flags); | ||
| 2271 | if (flags & MSG_DONTWAIT) | ||
| 2272 | req->flags |= REQ_F_NOWAIT; | ||
| 2273 | else if (force_nonblock) | ||
| 2274 | flags |= MSG_DONTWAIT; | ||
| 2275 | |||
| 2276 | msg = (struct user_msghdr __user *) (unsigned long) | ||
| 2277 | READ_ONCE(sqe->addr); | ||
| 2278 | if (req->io) { | 2273 | if (req->io) { |
| 2279 | kmsg = &req->io->msg; | 2274 | kmsg = &req->io->msg; |
| 2280 | kmsg->msg.msg_name = &addr; | 2275 | kmsg->msg.msg_name = &addr; |
| @@ -2283,14 +2278,27 @@ static int io_recvmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 2 unmodified lines | |||
| 2283 | kmsg->iov = kmsg->fast_iov; | 2278 | kmsg->iov = kmsg->fast_iov; |
| 2284 | kmsg->msg.msg_iter.iov = kmsg->iov; | 2279 | kmsg->msg.msg_iter.iov = kmsg->iov; |
| 2285 | } else { | 2280 | } else { |
| 2281 | struct io_sr_msg *sr = &req->sr_msg; | ||
| 2282 | |||
| 2286 | kmsg = &io.msg; | 2283 | kmsg = &io.msg; |
| 2287 | kmsg->msg.msg_name = &addr; | 2284 | kmsg->msg.msg_name = &addr; |
| 2288 | ret = io_recvmsg_prep(req, &io); | 2285 | |
| 2286 | io.msg.iov = io.msg.fast_iov; | ||
| 2287 | ret = recvmsg_copy_msghdr(&io.msg.msg, sr->msg, | ||
| 2288 | sr->msg_flags, &io.msg.uaddr, | ||
| 2289 | &io.msg.iov); | ||
| 2289 | if (ret) | 2290 | if (ret) |
| 2290 | goto out; | 2291 | return ret; |
| 2291 | } | 2292 | } |
| 2292 | 2293 | ||
| 2293 | ret = __sys_recvmsg_sock(sock, &kmsg->msg, msg, kmsg->uaddr, flags); | 2294 | flags = req->sr_msg.msg_flags; |
| 2295 | if (flags & MSG_DONTWAIT) | ||
| 2296 | req->flags |= REQ_F_NOWAIT; | ||
| 2297 | else if (force_nonblock) | ||
| 2298 | flags |= MSG_DONTWAIT; | ||
| 2299 | |||
| 2300 | ret = __sys_recvmsg_sock(sock, &kmsg->msg, req->sr_msg.msg, | ||
| 2301 | kmsg->uaddr, flags); | ||
| 2294 | if (force_nonblock && ret == -EAGAIN) { | 2302 | if (force_nonblock && ret == -EAGAIN) { |
| 2295 | if (req->io) | 2303 | if (req->io) |
| 2296 | return -EAGAIN; | 2304 | return -EAGAIN; |
| @@ -2304,7 +2312,6 @@ static int io_recvmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 7 unmodified lines | |||
| 2304 | ret = -EINTR; | 2312 | ret = -EINTR; |
| 2305 | } | 2313 | } |
| 2306 | 2314 | ||
| 2307 | out: | ||
| 2308 | if (!io_wq_current_is_worker() && kmsg && kmsg->iov != kmsg->fast_iov) | 2315 | if (!io_wq_current_is_worker() && kmsg && kmsg->iov != kmsg->fast_iov) |
| 2309 | kfree(kmsg->iov); | 2316 | kfree(kmsg->iov); |
| 2310 | io_cqring_add_event(req, ret); | 2317 | io_cqring_add_event(req, ret); |
| @@ -2317,25 +2324,19 @@ out: · 6 unmodified lines | |||
| 2317 | #endif | 2324 | #endif |
| 2318 | } | 2325 | } |
| 2319 | 2326 | ||
| 2320 | static int io_accept_prep(struct io_kiocb *req) | 2327 | static int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 2321 | { | 2328 | { |
| 2322 | #if defined(CONFIG_NET) | 2329 | #if defined(CONFIG_NET) |
| 2323 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2324 | struct io_accept *accept = &req->accept; | 2330 | struct io_accept *accept = &req->accept; |
| 2325 | 2331 | ||
| 2326 | if (req->flags & REQ_F_PREPPED) | ||
| 2327 | return 0; | ||
| 2328 | |||
| 2329 | if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) | 2332 | if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) |
| 2330 | return -EINVAL; | 2333 | return -EINVAL; |
| 2331 | if (sqe->ioprio || sqe->len || sqe->buf_index) | 2334 | if (sqe->ioprio || sqe->len || sqe->buf_index) |
| 2332 | return -EINVAL; | 2335 | return -EINVAL; |
| 2333 | 2336 | ||
| 2334 | accept->addr = (struct sockaddr __user *) | 2337 | accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); |
| 2335 | (unsigned long) READ_ONCE(sqe->addr); | 2338 | accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2)); |
| 2336 | accept->addr_len = (int __user *) (unsigned long) READ_ONCE(sqe->addr2); | ||
| 2337 | accept->flags = READ_ONCE(sqe->accept_flags); | 2339 | accept->flags = READ_ONCE(sqe->accept_flags); |
| 2338 | req->flags |= REQ_F_PREPPED; | ||
| 2339 | return 0; | 2340 | return 0; |
| 2340 | #else | 2341 | #else |
| 2341 | return -EOPNOTSUPP; | 2342 | return -EOPNOTSUPP; |
| @@ -2383,10 +2384,6 @@ static int io_accept(struct io_kiocb *req, struct io_kiocb **nxt, · 41 unmodified lines | |||
| 2383 | #if defined(CONFIG_NET) | 2384 | #if defined(CONFIG_NET) |
| 2384 | int ret; | 2385 | int ret; |
| 2385 | 2386 | ||
| 2386 | ret = io_accept_prep(req); | ||
| 2387 | if (ret) | ||
| 2388 | return ret; | ||
| 2389 | |||
| 2390 | ret = __io_accept(req, nxt, force_nonblock); | 2387 | ret = __io_accept(req, nxt, force_nonblock); |
| 2391 | if (ret == -EAGAIN && force_nonblock) { | 2388 | if (ret == -EAGAIN && force_nonblock) { |
| 2392 | req->work.func = io_accept_finish; | 2389 | req->work.func = io_accept_finish; |
| @@ -2400,18 +2397,27 @@ static int io_accept(struct io_kiocb *req, struct io_kiocb **nxt, · 7 unmodified lines | |||
| 2400 | #endif | 2397 | #endif |
| 2401 | } | 2398 | } |
| 2402 | 2399 | ||
| 2403 | static int io_connect_prep(struct io_kiocb *req, struct io_async_ctx *io) | 2400 | static int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 2404 | { | 2401 | { |
| 2405 | #if defined(CONFIG_NET) | 2402 | #if defined(CONFIG_NET) |
| 2406 | const struct io_uring_sqe *sqe = req->sqe; | 2403 | struct io_connect *conn = &req->connect; |
| 2407 | struct sockaddr __user *addr; | 2404 | struct io_async_ctx *io = req->io; |
| 2408 | int addr_len; | ||
| 2409 | 2405 | ||
| 2410 | addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr); | 2406 | if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) |
| 2411 | addr_len = READ_ONCE(sqe->addr2); | 2407 | return -EINVAL; |
| 2412 | return move_addr_to_kernel(addr, addr_len, &io->connect.address); | 2408 | if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags) |
| 2409 | return -EINVAL; | ||
| 2410 | |||
| 2411 | conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); | ||
| 2412 | conn->addr_len = READ_ONCE(sqe->addr2); | ||
| 2413 | |||
| 2414 | if (!io) | ||
| 2415 | return 0; | ||
| 2416 | |||
| 2417 | return move_addr_to_kernel(conn->addr, conn->addr_len, | ||
| 2418 | &io->connect.address); | ||
| 2413 | #else | 2419 | #else |
| 2414 | return 0; | 2420 | return -EOPNOTSUPP; |
| 2415 | #endif | 2421 | #endif |
| 2416 | } | 2422 | } |
| 2417 | 2423 | ||
| @@ -2419,30 +2425,25 @@ static int io_connect(struct io_kiocb *req, struct io_kiocb **nxt, · 1 unmodified line | |||
| 2419 | bool force_nonblock) | 2425 | bool force_nonblock) |
| 2420 | { | 2426 | { |
| 2421 | #if defined(CONFIG_NET) | 2427 | #if defined(CONFIG_NET) |
| 2422 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2423 | struct io_async_ctx __io, *io; | 2428 | struct io_async_ctx __io, *io; |
| 2424 | unsigned file_flags; | 2429 | unsigned file_flags; |
| 2425 | int addr_len, ret; | 2430 | int ret; |
| 2426 | |||
| 2427 | if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) | ||
| 2428 | return -EINVAL; | ||
| 2429 | if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags) | ||
| 2430 | return -EINVAL; | ||
| 2431 | |||
| 2432 | addr_len = READ_ONCE(sqe->addr2); | ||
| 2433 | file_flags = force_nonblock ? O_NONBLOCK : 0; | ||
| 2434 | 2431 | ||
| 2435 | if (req->io) { | 2432 | if (req->io) { |
| 2436 | io = req->io; | 2433 | io = req->io; |
| 2437 | } else { | 2434 | } else { |
| 2438 | ret = io_connect_prep(req, &__io); | 2435 | ret = move_addr_to_kernel(req->connect.addr, |
| 2436 | req->connect.addr_len, | ||
| 2437 | &__io.connect.address); | ||
| 2439 | if (ret) | 2438 | if (ret) |
| 2440 | goto out; | 2439 | goto out; |
| 2441 | io = &__io; | 2440 | io = &__io; |
| 2442 | } | 2441 | } |
| 2443 | 2442 | ||
| 2444 | ret = __sys_connect_file(req->file, &io->connect.address, addr_len, | 2443 | file_flags = force_nonblock ? O_NONBLOCK : 0; |
| 2445 | file_flags); | 2444 | |
| 2445 | ret = __sys_connect_file(req->file, &io->connect.address, | ||
| 2446 | req->connect.addr_len, file_flags); | ||
| 2446 | if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) { | 2447 | if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) { |
| 2447 | if (req->io) | 2448 | if (req->io) |
| 2448 | return -EAGAIN; | 2449 | return -EAGAIN; |
| @@ -2513,12 +2514,9 @@ static int io_poll_cancel(struct io_ring_ctx *ctx, __u64 sqe_addr) · 64 unmodified lines | |||
| 2513 | return -ENOENT; | 2514 | return -ENOENT; |
| 2514 | } | 2515 | } |
| 2515 | 2516 | ||
| 2516 | static int io_poll_remove_prep(struct io_kiocb *req) | 2517 | static int io_poll_remove_prep(struct io_kiocb *req, |
| 2518 | const struct io_uring_sqe *sqe) | ||
| 2517 | { | 2519 | { |
| 2518 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2519 | |||
| 2520 | if (req->flags & REQ_F_PREPPED) | ||
| 2521 | return 0; | ||
| 2522 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) | 2520 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 2523 | return -EINVAL; | 2521 | return -EINVAL; |
| 2524 | if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index || | 2522 | if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index || |
| @@ -2526,7 +2524,6 @@ static int io_poll_remove_prep(struct io_kiocb *req) · 1 unmodified line | |||
| 2526 | return -EINVAL; | 2524 | return -EINVAL; |
| 2527 | 2525 | ||
| 2528 | req->poll.addr = READ_ONCE(sqe->addr); | 2526 | req->poll.addr = READ_ONCE(sqe->addr); |
| 2529 | req->flags |= REQ_F_PREPPED; | ||
| 2530 | return 0; | 2527 | return 0; |
| 2531 | } | 2528 | } |
| 2532 | 2529 | ||
| @@ -2540,10 +2537,6 @@ static int io_poll_remove(struct io_kiocb *req) · 7 unmodified lines | |||
| 2540 | u64 addr; | 2537 | u64 addr; |
| 2541 | int ret; | 2538 | int ret; |
| 2542 | 2539 | ||
| 2543 | ret = io_poll_remove_prep(req); | ||
| 2544 | if (ret) | ||
| 2545 | return ret; | ||
| 2546 | |||
| 2547 | addr = req->poll.addr; | 2540 | addr = req->poll.addr; |
| 2548 | spin_lock_irq(&ctx->completion_lock); | 2541 | spin_lock_irq(&ctx->completion_lock); |
| 2549 | ret = io_poll_cancel(ctx, addr); | 2542 | ret = io_poll_cancel(ctx, addr); |
| @@ -2681,14 +2674,11 @@ static void io_poll_req_insert(struct io_kiocb *req) · 131 unmodified lines | |||
| 2681 | hlist_add_head(&req->hash_node, list); | 2674 | hlist_add_head(&req->hash_node, list); |
| 2682 | } | 2675 | } |
| 2683 | 2676 | ||
| 2684 | static int io_poll_add_prep(struct io_kiocb *req) | 2677 | static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 2685 | { | 2678 | { |
| 2686 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2687 | struct io_poll_iocb *poll = &req->poll; | 2679 | struct io_poll_iocb *poll = &req->poll; |
| 2688 | u16 events; | 2680 | u16 events; |
| 2689 | 2681 | ||
| 2690 | if (req->flags & REQ_F_PREPPED) | ||
| 2691 | return 0; | ||
| 2692 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) | 2682 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 2693 | return -EINVAL; | 2683 | return -EINVAL; |
| 2694 | if (sqe->addr || sqe->ioprio || sqe->off || sqe->len || sqe->buf_index) | 2684 | if (sqe->addr || sqe->ioprio || sqe->off || sqe->len || sqe->buf_index) |
| @@ -2696,7 +2686,6 @@ static int io_poll_add_prep(struct io_kiocb *req) · 1 unmodified line | |||
| 2696 | if (!poll->file) | 2686 | if (!poll->file) |
| 2697 | return -EBADF; | 2687 | return -EBADF; |
| 2698 | 2688 | ||
| 2699 | req->flags |= REQ_F_PREPPED; | ||
| 2700 | events = READ_ONCE(sqe->poll_events); | 2689 | events = READ_ONCE(sqe->poll_events); |
| 2701 | poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP; | 2690 | poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP; |
| 2702 | return 0; | 2691 | return 0; |
| @@ -2709,11 +2698,6 @@ static int io_poll_add(struct io_kiocb *req, struct io_kiocb **nxt) · 6 unmodified lines | |||
| 2709 | struct io_poll_table ipt; | 2698 | struct io_poll_table ipt; |
| 2710 | bool cancel = false; | 2699 | bool cancel = false; |
| 2711 | __poll_t mask; | 2700 | __poll_t mask; |
| 2712 | int ret; | ||
| 2713 | |||
| 2714 | ret = io_poll_add_prep(req); | ||
| 2715 | if (ret) | ||
| 2716 | return ret; | ||
| 2717 | 2701 | ||
| 2718 | INIT_IO_WORK(&req->work, io_poll_complete_work); | 2702 | INIT_IO_WORK(&req->work, io_poll_complete_work); |
| 2719 | INIT_HLIST_NODE(&req->hash_node); | 2703 | INIT_HLIST_NODE(&req->hash_node); |
| @@ -2832,12 +2816,9 @@ static int io_timeout_cancel(struct io_ring_ctx *ctx, __u64 user_data) · 112 unmodified lines | |||
| 2832 | return 0; | 2816 | return 0; |
| 2833 | } | 2817 | } |
| 2834 | 2818 | ||
| 2835 | static int io_timeout_remove_prep(struct io_kiocb *req) | 2819 | static int io_timeout_remove_prep(struct io_kiocb *req, |
| 2820 | const struct io_uring_sqe *sqe) | ||
| 2836 | { | 2821 | { |
| 2837 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2838 | |||
| 2839 | if (req->flags & REQ_F_PREPPED) | ||
| 2840 | return 0; | ||
| 2841 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) | 2822 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 2842 | return -EINVAL; | 2823 | return -EINVAL; |
| 2843 | if (sqe->flags || sqe->ioprio || sqe->buf_index || sqe->len) | 2824 | if (sqe->flags || sqe->ioprio || sqe->buf_index || sqe->len) |
| @@ -2848,7 +2829,6 @@ static int io_timeout_remove_prep(struct io_kiocb *req) · 4 unmodified lines | |||
| 2848 | if (req->timeout.flags) | 2829 | if (req->timeout.flags) |
| 2849 | return -EINVAL; | 2830 | return -EINVAL; |
| 2850 | 2831 | ||
| 2851 | req->flags |= REQ_F_PREPPED; | ||
| 2852 | return 0; | 2832 | return 0; |
| 2853 | } | 2833 | } |
| 2854 | 2834 | ||
| @@ -2860,10 +2840,6 @@ static int io_timeout_remove(struct io_kiocb *req) · 5 unmodified lines | |||
| 2860 | struct io_ring_ctx *ctx = req->ctx; | 2840 | struct io_ring_ctx *ctx = req->ctx; |
| 2861 | int ret; | 2841 | int ret; |
| 2862 | 2842 | ||
| 2863 | ret = io_timeout_remove_prep(req); | ||
| 2864 | if (ret) | ||
| 2865 | return ret; | ||
| 2866 | |||
| 2867 | spin_lock_irq(&ctx->completion_lock); | 2843 | spin_lock_irq(&ctx->completion_lock); |
| 2868 | ret = io_timeout_cancel(ctx, req->timeout.addr); | 2844 | ret = io_timeout_cancel(ctx, req->timeout.addr); |
| 2869 | 2845 | ||
| @@ -2877,10 +2853,9 @@ static int io_timeout_remove(struct io_kiocb *req) · 7 unmodified lines | |||
| 2877 | return 0; | 2853 | return 0; |
| 2878 | } | 2854 | } |
| 2879 | 2855 | ||
| 2880 | static int io_timeout_prep(struct io_kiocb *req, struct io_async_ctx *io, | 2856 | static int io_timeout_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| 2881 | bool is_timeout_link) | 2857 | bool is_timeout_link) |
| 2882 | { | 2858 | { |
| 2883 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2884 | struct io_timeout_data *data; | 2859 | struct io_timeout_data *data; |
| 2885 | unsigned flags; | 2860 | unsigned flags; |
| 2886 | 2861 | ||
| @@ -2894,7 +2869,12 @@ static int io_timeout_prep(struct io_kiocb *req, struct io_async_ctx *io, · 7 unmodified lines | |||
| 2894 | if (flags & ~IORING_TIMEOUT_ABS) | 2869 | if (flags & ~IORING_TIMEOUT_ABS) |
| 2895 | return -EINVAL; | 2870 | return -EINVAL; |
| 2896 | 2871 | ||
| 2897 | data = &io->timeout; | 2872 | req->timeout.count = READ_ONCE(sqe->off); |
| 2873 | |||
| 2874 | if (!req->io && io_alloc_async_ctx(req)) | ||
| 2875 | return -ENOMEM; | ||
| 2876 | |||
| 2877 | data = &req->io->timeout; | ||
| 2898 | data->req = req; | 2878 | data->req = req; |
| 2899 | req->flags |= REQ_F_TIMEOUT; | 2879 | req->flags |= REQ_F_TIMEOUT; |
| 2900 | 2880 | ||
| @@ -2912,21 +2892,12 @@ static int io_timeout_prep(struct io_kiocb *req, struct io_async_ctx *io, · 11 unmodified lines | |||
| 2912 | 2892 | ||
| 2913 | static int io_timeout(struct io_kiocb *req) | 2893 | static int io_timeout(struct io_kiocb *req) |
| 2914 | { | 2894 | { |
| 2915 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 2916 | unsigned count; | 2895 | unsigned count; |
| 2917 | struct io_ring_ctx *ctx = req->ctx; | 2896 | struct io_ring_ctx *ctx = req->ctx; |
| 2918 | struct io_timeout_data *data; | 2897 | struct io_timeout_data *data; |
| 2919 | struct list_head *entry; | 2898 | struct list_head *entry; |
| 2920 | unsigned span = 0; | 2899 | unsigned span = 0; |
| 2921 | int ret; | ||
| 2922 | 2900 | ||
| 2923 | if (!req->io) { | ||
| 2924 | if (io_alloc_async_ctx(req)) | ||
| 2925 | return -ENOMEM; | ||
| 2926 | ret = io_timeout_prep(req, req->io, false); | ||
| 2927 | if (ret) | ||
| 2928 | return ret; | ||
| 2929 | } | ||
| 2930 | data = &req->io->timeout; | 2901 | data = &req->io->timeout; |
| 2931 | 2902 | ||
| 2932 | /* | 2903 | /* |
| @@ -2934,7 +2905,7 @@ static int io_timeout(struct io_kiocb *req) · 1 unmodified line | |||
| 2934 | * timeout event to be satisfied. If it isn't set, then this is | 2905 | * timeout event to be satisfied. If it isn't set, then this is |
| 2935 | * a pure timeout request, sequence isn't used. | 2906 | * a pure timeout request, sequence isn't used. |
| 2936 | */ | 2907 | */ |
| 2937 | count = READ_ONCE(sqe->off); | 2908 | count = req->timeout.count; |
| 2938 | if (!count) { | 2909 | if (!count) { |
| 2939 | req->flags |= REQ_F_TIMEOUT_NOSEQ; | 2910 | req->flags |= REQ_F_TIMEOUT_NOSEQ; |
| 2940 | spin_lock_irq(&ctx->completion_lock); | 2911 | spin_lock_irq(&ctx->completion_lock); |
| @@ -3052,19 +3023,15 @@ done: · 111 unmodified lines | |||
| 3052 | io_put_req_find_next(req, nxt); | 3023 | io_put_req_find_next(req, nxt); |
| 3053 | } | 3024 | } |
| 3054 | 3025 | ||
| 3055 | static int io_async_cancel_prep(struct io_kiocb *req) | 3026 | static int io_async_cancel_prep(struct io_kiocb *req, |
| 3027 | const struct io_uring_sqe *sqe) | ||
| 3056 | { | 3028 | { |
| 3057 | const struct io_uring_sqe *sqe = req->sqe; | ||
| 3058 | |||
| 3059 | if (req->flags & REQ_F_PREPPED) | ||
| 3060 | return 0; | ||
| 3061 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) | 3029 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 3062 | return -EINVAL; | 3030 | return -EINVAL; |
| 3063 | if (sqe->flags || sqe->ioprio || sqe->off || sqe->len || | 3031 | if (sqe->flags || sqe->ioprio || sqe->off || sqe->len || |
| 3064 | sqe->cancel_flags) | 3032 | sqe->cancel_flags) |
| 3065 | return -EINVAL; | 3033 | return -EINVAL; |
| 3066 | 3034 | ||
| 3067 | req->flags |= REQ_F_PREPPED; | ||
| 3068 | req->cancel.addr = READ_ONCE(sqe->addr); | 3035 | req->cancel.addr = READ_ONCE(sqe->addr); |
| 3069 | return 0; | 3036 | return 0; |
| 3070 | } | 3037 | } |
| @@ -3072,21 +3039,14 @@ static int io_async_cancel_prep(struct io_kiocb *req) · 1 unmodified line | |||
| 3072 | static int io_async_cancel(struct io_kiocb *req, struct io_kiocb **nxt) | 3039 | static int io_async_cancel(struct io_kiocb *req, struct io_kiocb **nxt) |
| 3073 | { | 3040 | { |
| 3074 | struct io_ring_ctx *ctx = req->ctx; | 3041 | struct io_ring_ctx *ctx = req->ctx; |
| 3075 | int ret; | ||
| 3076 | |||
| 3077 | ret = io_async_cancel_prep(req); | ||
| 3078 | if (ret) | ||
| 3079 | return ret; | ||
| 3080 | 3042 | ||
| 3081 | io_async_find_and_cancel(ctx, req, req->cancel.addr, nxt, 0); | 3043 | io_async_find_and_cancel(ctx, req, req->cancel.addr, nxt, 0); |
| 3082 | return 0; | 3044 | return 0; |
| 3083 | } | 3045 | } |
| 3084 | 3046 | ||
| 3085 | static int io_req_defer_prep(struct io_kiocb *req) | 3047 | static int io_req_defer_prep(struct io_kiocb *req, |
| 3048 | const struct io_uring_sqe *sqe) | ||
| 3086 | { | 3049 | { |
| 3087 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; | ||
| 3088 | struct io_async_ctx *io = req->io; | ||
| 3089 | struct iov_iter iter; | ||
| 3090 | ssize_t ret = 0; | 3050 | ssize_t ret = 0; |
| 3091 | 3051 | ||
| 3092 | switch (req->opcode) { | 3052 | switch (req->opcode) { |
| @@ -3094,61 +3054,47 @@ static int io_req_defer_prep(struct io_kiocb *req) · 1 unmodified line | |||
| 3094 | break; | 3054 | break; |
| 3095 | case IORING_OP_READV: | 3055 | case IORING_OP_READV: |
| 3096 | case IORING_OP_READ_FIXED: | 3056 | case IORING_OP_READ_FIXED: |
| 3097 | /* ensure prep does right import */ | 3057 | ret = io_read_prep(req, sqe, true); |
| 3098 | req->io = NULL; | ||
| 3099 | ret = io_read_prep(req, &iovec, &iter, true); | ||
| 3100 | req->io = io; | ||
| 3101 | if (ret < 0) | ||
| 3102 | break; | ||
| 3103 | io_req_map_rw(req, ret, iovec, inline_vecs, &iter); | ||
| 3104 | ret = 0; | ||
| 3105 | break; | 3058 | break; |
| 3106 | case IORING_OP_WRITEV: | 3059 | case IORING_OP_WRITEV: |
| 3107 | case IORING_OP_WRITE_FIXED: | 3060 | case IORING_OP_WRITE_FIXED: |
| 3108 | /* ensure prep does right import */ | 3061 | ret = io_write_prep(req, sqe, true); |
| 3109 | req->io = NULL; | ||
| 3110 | ret = io_write_prep(req, &iovec, &iter, true); | ||
| 3111 | req->io = io; | ||
| 3112 | if (ret < 0) | ||
| 3113 | break; | ||
| 3114 | io_req_map_rw(req, ret, iovec, inline_vecs, &iter); | ||
| 3115 | ret = 0; | ||
| 3116 | break; | 3062 | break; |
| 3117 | case IORING_OP_POLL_ADD: | 3063 | case IORING_OP_POLL_ADD: |
| 3118 | ret = io_poll_add_prep(req); | 3064 | ret = io_poll_add_prep(req, sqe); |
| 3119 | break; | 3065 | break; |
| 3120 | case IORING_OP_POLL_REMOVE: | 3066 | case IORING_OP_POLL_REMOVE: |
| 3121 | ret = io_poll_remove_prep(req); | 3067 | ret = io_poll_remove_prep(req, sqe); |
| 3122 | break; | 3068 | break; |
| 3123 | case IORING_OP_FSYNC: | 3069 | case IORING_OP_FSYNC: |
| 3124 | ret = io_prep_fsync(req); | 3070 | ret = io_prep_fsync(req, sqe); |
| 3125 | break; | 3071 | break; |
| 3126 | case IORING_OP_SYNC_FILE_RANGE: | 3072 | case IORING_OP_SYNC_FILE_RANGE: |
| 3127 | ret = io_prep_sfr(req); | 3073 | ret = io_prep_sfr(req, sqe); |
| 3128 | break; | 3074 | break; |
| 3129 | case IORING_OP_SENDMSG: | 3075 | case IORING_OP_SENDMSG: |
| 3130 | ret = io_sendmsg_prep(req, io); | 3076 | ret = io_sendmsg_prep(req, sqe); |
| 3131 | break; | 3077 | break; |
| 3132 | case IORING_OP_RECVMSG: | 3078 | case IORING_OP_RECVMSG: |
| 3133 | ret = io_recvmsg_prep(req, io); | 3079 | ret = io_recvmsg_prep(req, sqe); |
| 3134 | break; | 3080 | break; |
| 3135 | case IORING_OP_CONNECT: | 3081 | case IORING_OP_CONNECT: |
| 3136 | ret = io_connect_prep(req, io); | 3082 | ret = io_connect_prep(req, sqe); |
| 3137 | break; | 3083 | break; |
| 3138 | case IORING_OP_TIMEOUT: | 3084 | case IORING_OP_TIMEOUT: |
| 3139 | ret = io_timeout_prep(req, io, false); | 3085 | ret = io_timeout_prep(req, sqe, false); |
| 3140 | break; | 3086 | break; |
| 3141 | case IORING_OP_TIMEOUT_REMOVE: | 3087 | case IORING_OP_TIMEOUT_REMOVE: |
| 3142 | ret = io_timeout_remove_prep(req); | 3088 | ret = io_timeout_remove_prep(req, sqe); |
| 3143 | break; | 3089 | break; |
| 3144 | case IORING_OP_ASYNC_CANCEL: | 3090 | case IORING_OP_ASYNC_CANCEL: |
| 3145 | ret = io_async_cancel_prep(req); | 3091 | ret = io_async_cancel_prep(req, sqe); |
| 3146 | break; | 3092 | break; |
| 3147 | case IORING_OP_LINK_TIMEOUT: | 3093 | case IORING_OP_LINK_TIMEOUT: |
| 3148 | ret = io_timeout_prep(req, io, true); | 3094 | ret = io_timeout_prep(req, sqe, true); |
| 3149 | break; | 3095 | break; |
| 3150 | case IORING_OP_ACCEPT: | 3096 | case IORING_OP_ACCEPT: |
| 3151 | ret = io_accept_prep(req); | 3097 | ret = io_accept_prep(req, sqe); |
| 3152 | break; | 3098 | break; |
| 3153 | default: | 3099 | default: |
| 3154 | printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n", | 3100 | printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n", |
| @@ -3160,7 +3106,7 @@ static int io_req_defer_prep(struct io_kiocb *req) · 5 unmodified lines | |||
| 3160 | return ret; | 3106 | return ret; |
| 3161 | } | 3107 | } |
| 3162 | 3108 | ||
| 3163 | static int io_req_defer(struct io_kiocb *req) | 3109 | static int io_req_defer(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 3164 | { | 3110 | { |
| 3165 | struct io_ring_ctx *ctx = req->ctx; | 3111 | struct io_ring_ctx *ctx = req->ctx; |
| 3166 | int ret; | 3112 | int ret; |
| @@ -3169,10 +3115,10 @@ static int io_req_defer(struct io_kiocb *req) · 2 unmodified lines | |||
| 3169 | if (!req_need_defer(req) && list_empty(&ctx->defer_list)) | 3115 | if (!req_need_defer(req) && list_empty(&ctx->defer_list)) |
| 3170 | return 0; | 3116 | return 0; |
| 3171 | 3117 | ||
| 3172 | if (io_alloc_async_ctx(req)) | 3118 | if (!req->io && io_alloc_async_ctx(req)) |
| 3173 | return -EAGAIN; | 3119 | return -EAGAIN; |
| 3174 | 3120 | ||
| 3175 | ret = io_req_defer_prep(req); | 3121 | ret = io_req_defer_prep(req, sqe); |
| 3176 | if (ret < 0) | 3122 | if (ret < 0) |
| 3177 | return ret; | 3123 | return ret; |
| 3178 | 3124 | ||
| @@ -3188,9 +3134,8 @@ static int io_req_defer(struct io_kiocb *req) · 9 unmodified lines | |||
| 3188 | return -EIOCBQUEUED; | 3134 | return -EIOCBQUEUED; |
| 3189 | } | 3135 | } |
| 3190 | 3136 | ||
| 3191 | __attribute__((nonnull)) | 3137 | static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| 3192 | static int io_issue_sqe(struct io_kiocb *req, struct io_kiocb **nxt, | 3138 | struct io_kiocb **nxt, bool force_nonblock) |
| 3193 | bool force_nonblock) | ||
| 3194 | { | 3139 | { |
| 3195 | struct io_ring_ctx *ctx = req->ctx; | 3140 | struct io_ring_ctx *ctx = req->ctx; |
| 3196 | int ret; | 3141 | int ret; |
| @@ -3200,52 +3145,109 @@ static int io_issue_sqe(struct io_kiocb *req, struct io_kiocb **nxt, · 3 unmodified lines | |||
| 3200 | ret = io_nop(req); | 3145 | ret = io_nop(req); |
| 3201 | break; | 3146 | break; |
| 3202 | case IORING_OP_READV: | 3147 | case IORING_OP_READV: |
| 3203 | if (unlikely(req->sqe->buf_index)) | ||
| 3204 | return -EINVAL; | ||
| 3205 | ret = io_read(req, nxt, force_nonblock); | ||
| 3206 | break; | ||
| 3207 | case IORING_OP_WRITEV: | ||
| 3208 | if (unlikely(req->sqe->buf_index)) | ||
| 3209 | return -EINVAL; | ||
| 3210 | ret = io_write(req, nxt, force_nonblock); | ||
| 3211 | break; | ||
| 3212 | case IORING_OP_READ_FIXED: | 3148 | case IORING_OP_READ_FIXED: |
| 3149 | if (sqe) { | ||
| 3150 | ret = io_read_prep(req, sqe, force_nonblock); | ||
| 3151 | if (ret < 0) | ||
| 3152 | break; | ||
| 3153 | } | ||
| 3213 | ret = io_read(req, nxt, force_nonblock); | 3154 | ret = io_read(req, nxt, force_nonblock); |
| 3214 | break; | 3155 | break; |
| 3156 | case IORING_OP_WRITEV: | ||
| 3215 | case IORING_OP_WRITE_FIXED: | 3157 | case IORING_OP_WRITE_FIXED: |
| 3158 | if (sqe) { | ||
| 3159 | ret = io_write_prep(req, sqe, force_nonblock); | ||
| 3160 | if (ret < 0) | ||
| 3161 | break; | ||
| 3162 | } | ||
| 3216 | ret = io_write(req, nxt, force_nonblock); | 3163 | ret = io_write(req, nxt, force_nonblock); |
| 3217 | break; | 3164 | break; |
| 3218 | case IORING_OP_FSYNC: | 3165 | case IORING_OP_FSYNC: |
| 3166 | if (sqe) { | ||
| 3167 | ret = io_prep_fsync(req, sqe); | ||
| 3168 | if (ret < 0) | ||
| 3169 | break; | ||
| 3170 | } | ||
| 3219 | ret = io_fsync(req, nxt, force_nonblock); | 3171 | ret = io_fsync(req, nxt, force_nonblock); |
| 3220 | break; | 3172 | break; |
| 3221 | case IORING_OP_POLL_ADD: | 3173 | case IORING_OP_POLL_ADD: |
| 3174 | if (sqe) { | ||
| 3175 | ret = io_poll_add_prep(req, sqe); | ||
| 3176 | if (ret) | ||
| 3177 | break; | ||
| 3178 | } | ||
| 3222 | ret = io_poll_add(req, nxt); | 3179 | ret = io_poll_add(req, nxt); |
| 3223 | break; | 3180 | break; |
| 3224 | case IORING_OP_POLL_REMOVE: | 3181 | case IORING_OP_POLL_REMOVE: |
| 3182 | if (sqe) { | ||
| 3183 | ret = io_poll_remove_prep(req, sqe); | ||
| 3184 | if (ret < 0) | ||
| 3185 | break; | ||
| 3186 | } | ||
| 3225 | ret = io_poll_remove(req); | 3187 | ret = io_poll_remove(req); |
| 3226 | break; | 3188 | break; |
| 3227 | case IORING_OP_SYNC_FILE_RANGE: | 3189 | case IORING_OP_SYNC_FILE_RANGE: |
| 3190 | if (sqe) { | ||
| 3191 | ret = io_prep_sfr(req, sqe); | ||
| 3192 | if (ret < 0) | ||
| 3193 | break; | ||
| 3194 | } | ||
| 3228 | ret = io_sync_file_range(req, nxt, force_nonblock); | 3195 | ret = io_sync_file_range(req, nxt, force_nonblock); |
| 3229 | break; | 3196 | break; |
| 3230 | case IORING_OP_SENDMSG: | 3197 | case IORING_OP_SENDMSG: |
| 3198 | if (sqe) { | ||
| 3199 | ret = io_sendmsg_prep(req, sqe); | ||
| 3200 | if (ret < 0) | ||
| 3201 | break; | ||
| 3202 | } | ||
| 3231 | ret = io_sendmsg(req, nxt, force_nonblock); | 3203 | ret = io_sendmsg(req, nxt, force_nonblock); |
| 3232 | break; | 3204 | break; |
| 3233 | case IORING_OP_RECVMSG: | 3205 | case IORING_OP_RECVMSG: |
| 3206 | if (sqe) { | ||
| 3207 | ret = io_recvmsg_prep(req, sqe); | ||
| 3208 | if (ret) | ||
| 3209 | break; | ||
| 3210 | } | ||
| 3234 | ret = io_recvmsg(req, nxt, force_nonblock); | 3211 | ret = io_recvmsg(req, nxt, force_nonblock); |
| 3235 | break; | 3212 | break; |
| 3236 | case IORING_OP_TIMEOUT: | 3213 | case IORING_OP_TIMEOUT: |
| 3214 | if (sqe) { | ||
| 3215 | ret = io_timeout_prep(req, sqe, false); | ||
| 3216 | if (ret) | ||
| 3217 | break; | ||
| 3218 | } | ||
| 3237 | ret = io_timeout(req); | 3219 | ret = io_timeout(req); |
| 3238 | break; | 3220 | break; |
| 3239 | case IORING_OP_TIMEOUT_REMOVE: | 3221 | case IORING_OP_TIMEOUT_REMOVE: |
| 3222 | if (sqe) { | ||
| 3223 | ret = io_timeout_remove_prep(req, sqe); | ||
| 3224 | if (ret) | ||
| 3225 | break; | ||
| 3226 | } | ||
| 3240 | ret = io_timeout_remove(req); | 3227 | ret = io_timeout_remove(req); |
| 3241 | break; | 3228 | break; |
| 3242 | case IORING_OP_ACCEPT: | 3229 | case IORING_OP_ACCEPT: |
| 3230 | if (sqe) { | ||
| 3231 | ret = io_accept_prep(req, sqe); | ||
| 3232 | if (ret) | ||
| 3233 | break; | ||
| 3234 | } | ||
| 3243 | ret = io_accept(req, nxt, force_nonblock); | 3235 | ret = io_accept(req, nxt, force_nonblock); |
| 3244 | break; | 3236 | break; |
| 3245 | case IORING_OP_CONNECT: | 3237 | case IORING_OP_CONNECT: |
| 3238 | if (sqe) { | ||
| 3239 | ret = io_connect_prep(req, sqe); | ||
| 3240 | if (ret) | ||
| 3241 | break; | ||
| 3242 | } | ||
| 3246 | ret = io_connect(req, nxt, force_nonblock); | 3243 | ret = io_connect(req, nxt, force_nonblock); |
| 3247 | break; | 3244 | break; |
| 3248 | case IORING_OP_ASYNC_CANCEL: | 3245 | case IORING_OP_ASYNC_CANCEL: |
| 3246 | if (sqe) { | ||
| 3247 | ret = io_async_cancel_prep(req, sqe); | ||
| 3248 | if (ret) | ||
| 3249 | break; | ||
| 3250 | } | ||
| 3249 | ret = io_async_cancel(req, nxt); | 3251 | ret = io_async_cancel(req, nxt); |
| 3250 | break; | 3252 | break; |
| 3251 | default: | 3253 | default: |
| @@ -3289,7 +3291,7 @@ static void io_wq_submit_work(struct io_wq_work **workptr) · 37 unmodified lines | |||
| 3289 | req->has_user = (work->flags & IO_WQ_WORK_HAS_MM) != 0; | 3291 | req->has_user = (work->flags & IO_WQ_WORK_HAS_MM) != 0; |
| 3290 | req->in_async = true; | 3292 | req->in_async = true; |
| 3291 | do { | 3293 | do { |
| 3292 | ret = io_issue_sqe(req, &nxt, false); | 3294 | ret = io_issue_sqe(req, NULL, &nxt, false); |
| 3293 | /* | 3295 | /* |
| 3294 | * We can get EAGAIN for polled IO even though we're | 3296 | * We can get EAGAIN for polled IO even though we're |
| 3295 | * forcing a sync submission from here, since we can't | 3297 | * forcing a sync submission from here, since we can't |
| @@ -3355,14 +3357,15 @@ static inline struct file *io_file_from_index(struct io_ring_ctx *ctx, · 59 unmodified lines | |||
| 3355 | return table->files[index & IORING_FILE_TABLE_MASK]; | 3357 | return table->files[index & IORING_FILE_TABLE_MASK]; |
| 3356 | } | 3358 | } |
| 3357 | 3359 | ||
| 3358 | static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req) | 3360 | static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req, |
| 3361 | const struct io_uring_sqe *sqe) | ||
| 3359 | { | 3362 | { |
| 3360 | struct io_ring_ctx *ctx = req->ctx; | 3363 | struct io_ring_ctx *ctx = req->ctx; |
| 3361 | unsigned flags; | 3364 | unsigned flags; |
| 3362 | int fd, ret; | 3365 | int fd, ret; |
| 3363 | 3366 | ||
| 3364 | flags = READ_ONCE(req->sqe->flags); | 3367 | flags = READ_ONCE(sqe->flags); |
| 3365 | fd = READ_ONCE(req->sqe->fd); | 3368 | fd = READ_ONCE(sqe->fd); |
| 3366 | 3369 | ||
| 3367 | if (flags & IOSQE_IO_DRAIN) | 3370 | if (flags & IOSQE_IO_DRAIN) |
| 3368 | req->flags |= REQ_F_IO_DRAIN; | 3371 | req->flags |= REQ_F_IO_DRAIN; |
| @@ -3494,7 +3497,7 @@ static struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req) · 125 unmodified lines | |||
| 3494 | return nxt; | 3497 | return nxt; |
| 3495 | } | 3498 | } |
| 3496 | 3499 | ||
| 3497 | static void __io_queue_sqe(struct io_kiocb *req) | 3500 | static void __io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 3498 | { | 3501 | { |
| 3499 | struct io_kiocb *linked_timeout; | 3502 | struct io_kiocb *linked_timeout; |
| 3500 | struct io_kiocb *nxt = NULL; | 3503 | struct io_kiocb *nxt = NULL; |
| @@ -3503,7 +3506,7 @@ static void __io_queue_sqe(struct io_kiocb *req) · 2 unmodified lines | |||
| 3503 | again: | 3506 | again: |
| 3504 | linked_timeout = io_prep_linked_timeout(req); | 3507 | linked_timeout = io_prep_linked_timeout(req); |
| 3505 | 3508 | ||
| 3506 | ret = io_issue_sqe(req, &nxt, true); | 3509 | ret = io_issue_sqe(req, sqe, &nxt, true); |
| 3507 | 3510 | ||
| 3508 | /* | 3511 | /* |
| 3509 | * We async punt it if the file wasn't marked NOWAIT, or if the file | 3512 | * We async punt it if the file wasn't marked NOWAIT, or if the file |
| @@ -3550,7 +3553,7 @@ done_req: · 40 unmodified lines | |||
| 3550 | } | 3553 | } |
| 3551 | } | 3554 | } |
| 3552 | 3555 | ||
| 3553 | static void io_queue_sqe(struct io_kiocb *req) | 3556 | static void io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 3554 | { | 3557 | { |
| 3555 | int ret; | 3558 | int ret; |
| 3556 | 3559 | ||
| @@ -3560,7 +3563,7 @@ static void io_queue_sqe(struct io_kiocb *req) · 3 unmodified lines | |||
| 3560 | } | 3563 | } |
| 3561 | req->ctx->drain_next = (req->flags & REQ_F_DRAIN_LINK); | 3564 | req->ctx->drain_next = (req->flags & REQ_F_DRAIN_LINK); |
| 3562 | 3565 | ||
| 3563 | ret = io_req_defer(req); | 3566 | ret = io_req_defer(req, sqe); |
| 3564 | if (ret) { | 3567 | if (ret) { |
| 3565 | if (ret != -EIOCBQUEUED) { | 3568 | if (ret != -EIOCBQUEUED) { |
| 3566 | io_cqring_add_event(req, ret); | 3569 | io_cqring_add_event(req, ret); |
| @@ -3568,7 +3571,7 @@ static void io_queue_sqe(struct io_kiocb *req) · 1 unmodified line | |||
| 3568 | io_double_put_req(req); | 3571 | io_double_put_req(req); |
| 3569 | } | 3572 | } |
| 3570 | } else | 3573 | } else |
| 3571 | __io_queue_sqe(req); | 3574 | __io_queue_sqe(req, sqe); |
| 3572 | } | 3575 | } |
| 3573 | 3576 | ||
| 3574 | static inline void io_queue_link_head(struct io_kiocb *req) | 3577 | static inline void io_queue_link_head(struct io_kiocb *req) |
| @@ -3577,25 +3580,25 @@ static inline void io_queue_link_head(struct io_kiocb *req) · 2 unmodified lines | |||
| 3577 | io_cqring_add_event(req, -ECANCELED); | 3580 | io_cqring_add_event(req, -ECANCELED); |
| 3578 | io_double_put_req(req); | 3581 | io_double_put_req(req); |
| 3579 | } else | 3582 | } else |
| 3580 | io_queue_sqe(req); | 3583 | io_queue_sqe(req, NULL); |
| 3581 | } | 3584 | } |
| 3582 | 3585 | ||
| 3583 | #define SQE_VALID_FLAGS (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK| \ | 3586 | #define SQE_VALID_FLAGS (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK| \ |
| 3584 | IOSQE_IO_HARDLINK) | 3587 | IOSQE_IO_HARDLINK) |
| 3585 | 3588 | ||
| 3586 | static bool io_submit_sqe(struct io_kiocb *req, struct io_submit_state *state, | 3589 | static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| 3587 | struct io_kiocb **link) | 3590 | struct io_submit_state *state, struct io_kiocb **link) |
| 3588 | { | 3591 | { |
| 3589 | struct io_ring_ctx *ctx = req->ctx; | 3592 | struct io_ring_ctx *ctx = req->ctx; |
| 3590 | int ret; | 3593 | int ret; |
| 3591 | 3594 | ||
| 3592 | /* enforce forwards compatibility on users */ | 3595 | /* enforce forwards compatibility on users */ |
| 3593 | if (unlikely(req->sqe->flags & ~SQE_VALID_FLAGS)) { | 3596 | if (unlikely(sqe->flags & ~SQE_VALID_FLAGS)) { |
| 3594 | ret = -EINVAL; | 3597 | ret = -EINVAL; |
| 3595 | goto err_req; | 3598 | goto err_req; |
| 3596 | } | 3599 | } |
| 3597 | 3600 | ||
| 3598 | ret = io_req_set_file(state, req); | 3601 | ret = io_req_set_file(state, req, sqe); |
| 3599 | if (unlikely(ret)) { | 3602 | if (unlikely(ret)) { |
| 3600 | err_req: | 3603 | err_req: |
| 3601 | io_cqring_add_event(req, ret); | 3604 | io_cqring_add_event(req, ret); |
| @@ -3613,10 +3616,10 @@ err_req: · 11 unmodified lines | |||
| 3613 | if (*link) { | 3616 | if (*link) { |
| 3614 | struct io_kiocb *prev = *link; | 3617 | struct io_kiocb *prev = *link; |
| 3615 | 3618 | ||
| 3616 | if (req->sqe->flags & IOSQE_IO_DRAIN) | 3619 | if (sqe->flags & IOSQE_IO_DRAIN) |
| 3617 | (*link)->flags |= REQ_F_DRAIN_LINK | REQ_F_IO_DRAIN; | 3620 | (*link)->flags |= REQ_F_DRAIN_LINK | REQ_F_IO_DRAIN; |
| 3618 | 3621 | ||
| 3619 | if (req->sqe->flags & IOSQE_IO_HARDLINK) | 3622 | if (sqe->flags & IOSQE_IO_HARDLINK) |
| 3620 | req->flags |= REQ_F_HARDLINK; | 3623 | req->flags |= REQ_F_HARDLINK; |
| 3621 | 3624 | ||
| 3622 | if (io_alloc_async_ctx(req)) { | 3625 | if (io_alloc_async_ctx(req)) { |
| @@ -3624,7 +3627,7 @@ err_req: · 1 unmodified line | |||
| 3624 | goto err_req; | 3627 | goto err_req; |
| 3625 | } | 3628 | } |
| 3626 | 3629 | ||
| 3627 | ret = io_req_defer_prep(req); | 3630 | ret = io_req_defer_prep(req, sqe); |
| 3628 | if (ret) { | 3631 | if (ret) { |
| 3629 | /* fail even hard links since we don't submit */ | 3632 | /* fail even hard links since we don't submit */ |
| 3630 | prev->flags |= REQ_F_FAIL_LINK; | 3633 | prev->flags |= REQ_F_FAIL_LINK; |
| @@ -3632,15 +3635,18 @@ err_req: · 1 unmodified line | |||
| 3632 | } | 3635 | } |
| 3633 | trace_io_uring_link(ctx, req, prev); | 3636 | trace_io_uring_link(ctx, req, prev); |
| 3634 | list_add_tail(&req->link_list, &prev->link_list); | 3637 | list_add_tail(&req->link_list, &prev->link_list); |
| 3635 | } else if (req->sqe->flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) { | 3638 | } else if (sqe->flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) { |
| 3636 | req->flags |= REQ_F_LINK; | 3639 | req->flags |= REQ_F_LINK; |
| 3637 | if (req->sqe->flags & IOSQE_IO_HARDLINK) | 3640 | if (sqe->flags & IOSQE_IO_HARDLINK) |
| 3638 | req->flags |= REQ_F_HARDLINK; | 3641 | req->flags |= REQ_F_HARDLINK; |
| 3639 | 3642 | ||
| 3640 | INIT_LIST_HEAD(&req->link_list); | 3643 | INIT_LIST_HEAD(&req->link_list); |
| 3644 | ret = io_req_defer_prep(req, sqe); | ||
| 3645 | if (ret) | ||
| 3646 | req->flags |= REQ_F_FAIL_LINK; | ||
| 3641 | *link = req; | 3647 | *link = req; |
| 3642 | } else { | 3648 | } else { |
| 3643 | io_queue_sqe(req); | 3649 | io_queue_sqe(req, sqe); |
| 3644 | } | 3650 | } |
| 3645 | 3651 | ||
| 3646 | return true; | 3652 | return true; |
| @@ -3685,14 +3691,15 @@ static void io_commit_sqring(struct io_ring_ctx *ctx) · 38 unmodified lines | |||
| 3685 | } | 3691 | } |
| 3686 | 3692 | ||
| 3687 | /* | 3693 | /* |
| 3688 | * Fetch an sqe, if one is available. Note that req->sqe will point to memory | 3694 | * Fetch an sqe, if one is available. Note that sqe_ptr will point to memory |
| 3689 | * that is mapped by userspace. This means that care needs to be taken to | 3695 | * that is mapped by userspace. This means that care needs to be taken to |
| 3690 | * ensure that reads are stable, as we cannot rely on userspace always | 3696 | * ensure that reads are stable, as we cannot rely on userspace always |
| 3691 | * being a good citizen. If members of the sqe are validated and then later | 3697 | * being a good citizen. If members of the sqe are validated and then later |
| 3692 | * used, it's important that those reads are done through READ_ONCE() to | 3698 | * used, it's important that those reads are done through READ_ONCE() to |
| 3693 | * prevent a re-load down the line. | 3699 | * prevent a re-load down the line. |
| 3694 | */ | 3700 | */ |
| 3695 | static bool io_get_sqring(struct io_ring_ctx *ctx, struct io_kiocb *req) | 3701 | static bool io_get_sqring(struct io_ring_ctx *ctx, struct io_kiocb *req, |
| 3702 | const struct io_uring_sqe **sqe_ptr) | ||
| 3696 | { | 3703 | { |
| 3697 | struct io_rings *rings = ctx->rings; | 3704 | struct io_rings *rings = ctx->rings; |
| 3698 | u32 *sq_array = ctx->sq_array; | 3705 | u32 *sq_array = ctx->sq_array; |
| @@ -3719,9 +3726,9 @@ static bool io_get_sqring(struct io_ring_ctx *ctx, struct io_kiocb *req) · 20 unmodified lines | |||
| 3719 | * link list. | 3726 | * link list. |
| 3720 | */ | 3727 | */ |
| 3721 | req->sequence = ctx->cached_sq_head; | 3728 | req->sequence = ctx->cached_sq_head; |
| 3722 | req->sqe = &ctx->sq_sqes[head]; | 3729 | *sqe_ptr = &ctx->sq_sqes[head]; |
| 3723 | req->opcode = READ_ONCE(req->sqe->opcode); | 3730 | req->opcode = READ_ONCE((*sqe_ptr)->opcode); |
| 3724 | req->user_data = READ_ONCE(req->sqe->user_data); | 3731 | req->user_data = READ_ONCE((*sqe_ptr)->user_data); |
| 3725 | ctx->cached_sq_head++; | 3732 | ctx->cached_sq_head++; |
| 3726 | return true; | 3733 | return true; |
| 3727 | } | 3734 | } |
| @@ -3753,6 +3760,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, · 25 unmodified lines | |||
| 3753 | } | 3760 | } |
| 3754 | 3761 | ||
| 3755 | for (i = 0; i < nr; i++) { | 3762 | for (i = 0; i < nr; i++) { |
| 3763 | const struct io_uring_sqe *sqe; | ||
| 3756 | struct io_kiocb *req; | 3764 | struct io_kiocb *req; |
| 3757 | unsigned int sqe_flags; | 3765 | unsigned int sqe_flags; |
| 3758 | 3766 | ||
| @@ -3762,7 +3770,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, · 3 unmodified lines | |||
| 3762 | submitted = -EAGAIN; | 3770 | submitted = -EAGAIN; |
| 3763 | break; | 3771 | break; |
| 3764 | } | 3772 | } |
| 3765 | if (!io_get_sqring(ctx, req)) { | 3773 | if (!io_get_sqring(ctx, req, &sqe)) { |
| 3766 | __io_free_req(req); | 3774 | __io_free_req(req); |
| 3767 | break; | 3775 | break; |
| 3768 | } | 3776 | } |
| @@ -3776,7 +3784,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, · 7 unmodified lines | |||
| 3776 | } | 3784 | } |
| 3777 | 3785 | ||
| 3778 | submitted++; | 3786 | submitted++; |
| 3779 | sqe_flags = req->sqe->flags; | 3787 | sqe_flags = sqe->flags; |
| 3780 | 3788 | ||
| 3781 | req->ring_file = ring_file; | 3789 | req->ring_file = ring_file; |
| 3782 | req->ring_fd = ring_fd; | 3790 | req->ring_fd = ring_fd; |
| @@ -3784,7 +3792,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, · 1 unmodified line | |||
| 3784 | req->in_async = async; | 3792 | req->in_async = async; |
| 3785 | req->needs_fixed_file = async; | 3793 | req->needs_fixed_file = async; |
| 3786 | trace_io_uring_submit_sqe(ctx, req->user_data, true, async); | 3794 | trace_io_uring_submit_sqe(ctx, req->user_data, true, async); |
| 3787 | if (!io_submit_sqe(req, statep, &link)) | 3795 | if (!io_submit_sqe(req, sqe, statep, &link)) |
| 3788 | break; | 3796 | break; |
| 3789 | /* | 3797 | /* |
| 3790 | * If previous wasn't linked and we have a linked command, | 3798 | * If previous wasn't linked and we have a linked command, |
| @@ -4702,7 +4710,7 @@ static int io_copy_iov(struct io_ring_ctx *ctx, struct iovec *dst, · 911 unmodified lines | |||
| 4702 | if (copy_from_user(&ciov, &ciovs[index], sizeof(ciov))) | 4710 | if (copy_from_user(&ciov, &ciovs[index], sizeof(ciov))) |
| 4703 | return -EFAULT; | 4711 | return -EFAULT; |
| 4704 | 4712 | ||
| 4705 | dst->iov_base = (void __user *) (unsigned long) ciov.iov_base; | 4713 | dst->iov_base = u64_to_user_ptr((u64)ciov.iov_base); |
| 4706 | dst->iov_len = ciov.iov_len; | 4714 | dst->iov_len = ciov.iov_len; |
| 4707 | return 0; | 4715 | return 0; |
| 4708 | } | 4716 | } |
| @@ -2853,7 +2853,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, · 2852 unmodified lines | |||
| 2853 | } | 2853 | } |
| 2854 | if (inode) { | 2854 | if (inode) { |
| 2855 | /* userspace relies on this representation of dev_t */ | 2855 | /* userspace relies on this representation of dev_t */ |
| 2856 | seq_printf(f, "%d %02x:%02x:%ld ", fl_pid, | 2856 | seq_printf(f, "%d %02x:%02x:%lu ", fl_pid, |
| 2857 | MAJOR(inode->i_sb->s_dev), | 2857 | MAJOR(inode->i_sb->s_dev), |
| 2858 | MINOR(inode->i_sb->s_dev), inode->i_ino); | 2858 | MINOR(inode->i_sb->s_dev), inode->i_ino); |
| 2859 | } else { | 2859 | } else { |
| @@ -62,7 +62,7 @@ static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio) · 61 unmodified lines | |||
| 62 | { | 62 | { |
| 63 | bio->bi_end_io = mpage_end_io; | 63 | bio->bi_end_io = mpage_end_io; |
| 64 | bio_set_op_attrs(bio, op, op_flags); | 64 | bio_set_op_attrs(bio, op, op_flags); |
| 65 | guard_bio_eod(op, bio); | 65 | guard_bio_eod(bio); |
| 66 | submit_bio(bio); | 66 | submit_bio(bio); |
| 67 | return NULL; | 67 | return NULL; |
| 68 | } | 68 | } |
| @@ -1728,7 +1728,7 @@ static bool is_mnt_ns_file(struct dentry *dentry) · 1727 unmodified lines | |||
| 1728 | dentry->d_fsdata == &mntns_operations; | 1728 | dentry->d_fsdata == &mntns_operations; |
| 1729 | } | 1729 | } |
| 1730 | 1730 | ||
| 1731 | struct mnt_namespace *to_mnt_ns(struct ns_common *ns) | 1731 | static struct mnt_namespace *to_mnt_ns(struct ns_common *ns) |
| 1732 | { | 1732 | { |
| 1733 | return container_of(ns, struct mnt_namespace, ns); | 1733 | return container_of(ns, struct mnt_namespace, ns); |
| 1734 | } | 1734 | } |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | #include <linux/pseudo_fs.h> | 3 | #include <linux/pseudo_fs.h> |
| 4 | #include <linux/file.h> | 4 | #include <linux/file.h> |
| 5 | #include <linux/fs.h> | 5 | #include <linux/fs.h> |
| 6 | #include <linux/proc_fs.h> | ||
| 6 | #include <linux/proc_ns.h> | 7 | #include <linux/proc_ns.h> |
| 7 | #include <linux/magic.h> | 8 | #include <linux/magic.h> |
| 8 | #include <linux/ktime.h> | 9 | #include <linux/ktime.h> |
| @@ -11,6 +12,8 @@ · 2 unmodified lines | |||
| 11 | #include <linux/nsfs.h> | 12 | #include <linux/nsfs.h> |
| 12 | #include <linux/uaccess.h> | 13 | #include <linux/uaccess.h> |
| 13 | 14 | ||
| 15 | #include "internal.h" | ||
| 16 | |||
| 14 | static struct vfsmount *nsfs_mnt; | 17 | static struct vfsmount *nsfs_mnt; |
| 15 | 18 | ||
| 16 | static long ns_ioctl(struct file *filp, unsigned int ioctl, | 19 | static long ns_ioctl(struct file *filp, unsigned int ioctl, |
| @@ -3282,6 +3282,7 @@ static void ocfs2_dlm_init_debug(struct ocfs2_super *osb) · 3281 unmodified lines | |||
| 3282 | 3282 | ||
| 3283 | debugfs_create_u32("locking_filter", 0600, osb->osb_debug_root, | 3283 | debugfs_create_u32("locking_filter", 0600, osb->osb_debug_root, |
| 3284 | &dlm_debug->d_filter_secs); | 3284 | &dlm_debug->d_filter_secs); |
| 3285 | ocfs2_get_dlm_debug(dlm_debug); | ||
| 3285 | } | 3286 | } |
| 3286 | 3287 | ||
| 3287 | static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb) | 3288 | static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb) |
| @@ -1066,6 +1066,14 @@ int ocfs2_journal_load(struct ocfs2_journal *journal, int local, int replayed) · 1065 unmodified lines | |||
| 1066 | 1066 | ||
| 1067 | ocfs2_clear_journal_error(osb->sb, journal->j_journal, osb->slot_num); | 1067 | ocfs2_clear_journal_error(osb->sb, journal->j_journal, osb->slot_num); |
| 1068 | 1068 | ||
| 1069 | if (replayed) { | ||
| 1070 | jbd2_journal_lock_updates(journal->j_journal); | ||
| 1071 | status = jbd2_journal_flush(journal->j_journal); | ||
| 1072 | jbd2_journal_unlock_updates(journal->j_journal); | ||
| 1073 | if (status < 0) | ||
| 1074 | mlog_errno(status); | ||
| 1075 | } | ||
| 1076 | |||
| 1069 | status = ocfs2_journal_toggle_dirty(osb, 1, replayed); | 1077 | status = ocfs2_journal_toggle_dirty(osb, 1, replayed); |
| 1070 | if (status < 0) { | 1078 | if (status < 0) { |
| 1071 | mlog_errno(status); | 1079 | mlog_errno(status); |
| @@ -631,12 +631,15 @@ EXPORT_SYMBOL_GPL(posix_acl_create); · 630 unmodified lines | |||
| 631 | 631 | ||
| 632 | /** | 632 | /** |
| 633 | * posix_acl_update_mode - update mode in set_acl | 633 | * posix_acl_update_mode - update mode in set_acl |
| 634 | * @inode: target inode | ||
| 635 | * @mode_p: mode (pointer) for update | ||
| 636 | * @acl: acl pointer | ||
| 634 | * | 637 | * |
| 635 | * Update the file mode when setting an ACL: compute the new file permission | 638 | * Update the file mode when setting an ACL: compute the new file permission |
| 636 | * bits based on the ACL. In addition, if the ACL is equivalent to the new | 639 | * bits based on the ACL. In addition, if the ACL is equivalent to the new |
| 637 | * file mode, set *acl to NULL to indicate that no ACL should be set. | 640 | * file mode, set *@acl to NULL to indicate that no ACL should be set. |
| 638 | * | 641 | * |
| 639 | * As with chmod, clear the setgit bit if the caller is not in the owning group | 642 | * As with chmod, clear the setgid bit if the caller is not in the owning group |
| 640 | * or capable of CAP_FSETID (see inode_change_ok). | 643 | * or capable of CAP_FSETID (see inode_change_ok). |
| 641 | * | 644 | * |
| 642 | * Called from set_acl inode operations. | 645 | * Called from set_acl inode operations. |
| @@ -407,6 +407,17 @@ static int notrace ramoops_pstore_write(struct pstore_record *record) · 406 unmodified lines | |||
| 407 | 407 | ||
| 408 | prz = cxt->dprzs[cxt->dump_write_cnt]; | 408 | prz = cxt->dprzs[cxt->dump_write_cnt]; |
| 409 | 409 | ||
| 410 | /* | ||
| 411 | * Since this is a new crash dump, we need to reset the buffer in | ||
| 412 | * case it still has an old dump present. Without this, the new dump | ||
| 413 | * will get appended, which would seriously confuse anything trying | ||
| 414 | * to check dump file contents. Specifically, ramoops_read_kmsg_hdr() | ||
| 415 | * expects to find a dump header in the beginning of buffer data, so | ||
| 416 | * we must to reset the buffer values, in order to ensure that the | ||
| 417 | * header will be written to the beginning of the buffer. | ||
| 418 | */ | ||
| 419 | persistent_ram_zap(prz); | ||
| 420 | |||
| 410 | /* Build header and append record contents. */ | 421 | /* Build header and append record contents. */ |
| 411 | hlen = ramoops_write_kmsg_hdr(prz, record); | 422 | hlen = ramoops_write_kmsg_hdr(prz, record); |
| 412 | if (!hlen) | 423 | if (!hlen) |
| @@ -572,6 +583,7 @@ static int ramoops_init_przs(const char *name, · 159 unmodified lines | |||
| 572 | prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig, | 583 | prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig, |
| 573 | &cxt->ecc_info, | 584 | &cxt->ecc_info, |
| 574 | cxt->memtype, flags, label); | 585 | cxt->memtype, flags, label); |
| 586 | kfree(label); | ||
| 575 | if (IS_ERR(prz_ar[i])) { | 587 | if (IS_ERR(prz_ar[i])) { |
| 576 | err = PTR_ERR(prz_ar[i]); | 588 | err = PTR_ERR(prz_ar[i]); |
| 577 | dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n", | 589 | dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n", |
| @@ -617,6 +629,7 @@ static int ramoops_init_prz(const char *name, · 39 unmodified lines | |||
| 617 | label = kasprintf(GFP_KERNEL, "ramoops:%s", name); | 629 | label = kasprintf(GFP_KERNEL, "ramoops:%s", name); |
| 618 | *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info, | 630 | *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info, |
| 619 | cxt->memtype, PRZ_FLAG_ZAP_OLD, label); | 631 | cxt->memtype, PRZ_FLAG_ZAP_OLD, label); |
| 632 | kfree(label); | ||
| 620 | if (IS_ERR(*prz)) { | 633 | if (IS_ERR(*prz)) { |
| 621 | int err = PTR_ERR(*prz); | 634 | int err = PTR_ERR(*prz); |
| 622 | 635 | ||
| @@ -574,7 +574,7 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size, · 573 unmodified lines | |||
| 574 | /* Initialize general buffer state. */ | 574 | /* Initialize general buffer state. */ |
| 575 | raw_spin_lock_init(&prz->buffer_lock); | 575 | raw_spin_lock_init(&prz->buffer_lock); |
| 576 | prz->flags = flags; | 576 | prz->flags = flags; |
| 577 | prz->label = label; | 577 | prz->label = kstrdup(label, GFP_KERNEL); |
| 578 | 578 | ||
| 579 | ret = persistent_ram_buffer_map(start, size, prz, memtype); | 579 | ret = persistent_ram_buffer_map(start, size, prz, memtype); |
| 580 | if (ret) | 580 | if (ret) |
| @@ -19,6 +19,8 @@ struct ahci_host_priv; · 18 unmodified lines | |||
| 19 | struct platform_device; | 19 | struct platform_device; |
| 20 | struct scsi_host_template; | 20 | struct scsi_host_template; |
| 21 | 21 | ||
| 22 | int ahci_platform_enable_phys(struct ahci_host_priv *hpriv); | ||
| 23 | void ahci_platform_disable_phys(struct ahci_host_priv *hpriv); | ||
| 22 | int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); | 24 | int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); |
| 23 | void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); | 25 | void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); |
| 24 | int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv); | 26 | int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv); |
| @@ -470,6 +470,7 @@ extern struct bio *bio_copy_user_iov(struct request_queue *, · 469 unmodified lines | |||
| 470 | gfp_t); | 470 | gfp_t); |
| 471 | extern int bio_uncopy_user(struct bio *); | 471 | extern int bio_uncopy_user(struct bio *); |
| 472 | void zero_fill_bio_iter(struct bio *bio, struct bvec_iter iter); | 472 | void zero_fill_bio_iter(struct bio *bio, struct bvec_iter iter); |
| 473 | void bio_truncate(struct bio *bio, unsigned new_size); | ||
| 473 | 474 | ||
| 474 | static inline void zero_fill_bio(struct bio *bio) | 475 | static inline void zero_fill_bio(struct bio *bio) |
| 475 | { | 476 | { |
| @@ -153,26 +153,4 @@ static inline void bvec_advance(const struct bio_vec *bvec, · 152 unmodified lines | |||
| 153 | } | 153 | } |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | /* | ||
| 157 | * Get the last single-page segment from the multi-page bvec and store it | ||
| 158 | * in @seg | ||
| 159 | */ | ||
| 160 | static inline void mp_bvec_last_segment(const struct bio_vec *bvec, | ||
| 161 | struct bio_vec *seg) | ||
| 162 | { | ||
| 163 | unsigned total = bvec->bv_offset + bvec->bv_len; | ||
| 164 | unsigned last_page = (total - 1) / PAGE_SIZE; | ||
| 165 | |||
| 166 | seg->bv_page = bvec->bv_page + last_page; | ||
| 167 | |||
| 168 | /* the whole segment is inside the last page */ | ||
| 169 | if (bvec->bv_offset >= last_page * PAGE_SIZE) { | ||
| 170 | seg->bv_offset = bvec->bv_offset % PAGE_SIZE; | ||
| 171 | seg->bv_len = bvec->bv_len; | ||
| 172 | } else { | ||
| 173 | seg->bv_offset = 0; | ||
| 174 | seg->bv_len = total - last_page * PAGE_SIZE; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | #endif /* __LINUX_BVEC_ITER_H */ | 156 | #endif /* __LINUX_BVEC_ITER_H */ |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/can/error.h> | 18 | #include <linux/can/error.h> |
| 19 | #include <linux/can/led.h> | 19 | #include <linux/can/led.h> |
| 20 | #include <linux/can/netlink.h> | 20 | #include <linux/can/netlink.h> |
| 21 | #include <linux/can/skb.h> | ||
| 21 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
| 22 | 23 | ||
| 23 | /* | 24 | /* |
| @@ -91,6 +92,36 @@ struct can_priv { · 67 unmodified lines | |||
| 91 | #define get_can_dlc(i) (min_t(__u8, (i), CAN_MAX_DLC)) | 92 | #define get_can_dlc(i) (min_t(__u8, (i), CAN_MAX_DLC)) |
| 92 | #define get_canfd_dlc(i) (min_t(__u8, (i), CANFD_MAX_DLC)) | 93 | #define get_canfd_dlc(i) (min_t(__u8, (i), CANFD_MAX_DLC)) |
| 93 | 94 | ||
| 95 | /* Check for outgoing skbs that have not been created by the CAN subsystem */ | ||
| 96 | static inline bool can_skb_headroom_valid(struct net_device *dev, | ||
| 97 | struct sk_buff *skb) | ||
| 98 | { | ||
| 99 | /* af_packet creates a headroom of HH_DATA_MOD bytes which is fine */ | ||
| 100 | if (WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct can_skb_priv))) | ||
| 101 | return false; | ||
| 102 | |||
| 103 | /* af_packet does not apply CAN skb specific settings */ | ||
| 104 | if (skb->ip_summed == CHECKSUM_NONE) { | ||
| 105 | /* init headroom */ | ||
| 106 | can_skb_prv(skb)->ifindex = dev->ifindex; | ||
| 107 | can_skb_prv(skb)->skbcnt = 0; | ||
| 108 | |||
| 109 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 110 | |||
| 111 | /* preform proper loopback on capable devices */ | ||
| 112 | if (dev->flags & IFF_ECHO) | ||
| 113 | skb->pkt_type = PACKET_LOOPBACK; | ||
| 114 | else | ||
| 115 | skb->pkt_type = PACKET_HOST; | ||
| 116 | |||
| 117 | skb_reset_mac_header(skb); | ||
| 118 | skb_reset_network_header(skb); | ||
| 119 | skb_reset_transport_header(skb); | ||
| 120 | } | ||
| 121 | |||
| 122 | return true; | ||
| 123 | } | ||
| 124 | |||
| 94 | /* Drop a given socketbuffer if it does not contain a valid CAN frame. */ | 125 | /* Drop a given socketbuffer if it does not contain a valid CAN frame. */ |
| 95 | static inline bool can_dropped_invalid_skb(struct net_device *dev, | 126 | static inline bool can_dropped_invalid_skb(struct net_device *dev, |
| 96 | struct sk_buff *skb) | 127 | struct sk_buff *skb) |
| @@ -108,6 +139,9 @@ static inline bool can_dropped_invalid_skb(struct net_device *dev, · 11 unmodified lines | |||
| 108 | } else | 139 | } else |
| 109 | goto inval_skb; | 140 | goto inval_skb; |
| 110 | 141 | ||
| 142 | if (!can_skb_headroom_valid(dev, skb)) | ||
| 143 | goto inval_skb; | ||
| 144 | |||
| 111 | return false; | 145 | return false; |
| 112 | 146 | ||
| 113 | inval_skb: | 147 | inval_skb: |
| @@ -1364,8 +1364,11 @@ static inline int dma_get_slave_caps(struct dma_chan *chan, · 1363 unmodified lines | |||
| 1364 | static inline int dmaengine_desc_set_reuse(struct dma_async_tx_descriptor *tx) | 1364 | static inline int dmaengine_desc_set_reuse(struct dma_async_tx_descriptor *tx) |
| 1365 | { | 1365 | { |
| 1366 | struct dma_slave_caps caps; | 1366 | struct dma_slave_caps caps; |
| 1367 | int ret; | ||
| 1367 | 1368 | ||
| 1368 | dma_get_slave_caps(tx->chan, &caps); | 1369 | ret = dma_get_slave_caps(tx->chan, &caps); |
| 1370 | if (ret) | ||
| 1371 | return ret; | ||
| 1369 | 1372 | ||
| 1370 | if (caps.descriptor_reuse) { | 1373 | if (caps.descriptor_reuse) { |
| 1371 | tx->flags |= DMA_CTRL_REUSE; | 1374 | tx->flags |= DMA_CTRL_REUSE; |
| @@ -24,6 +24,14 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) · 23 unmodified lines | |||
| 24 | return (struct ethhdr *)skb_mac_header(skb); | 24 | return (struct ethhdr *)skb_mac_header(skb); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | /* Prefer this version in TX path, instead of | ||
| 28 | * skb_reset_mac_header() + eth_hdr() | ||
| 29 | */ | ||
| 30 | static inline struct ethhdr *skb_eth_hdr(const struct sk_buff *skb) | ||
| 31 | { | ||
| 32 | return (struct ethhdr *)skb->data; | ||
| 33 | } | ||
| 34 | |||
| 27 | static inline struct ethhdr *inner_eth_hdr(const struct sk_buff *skb) | 35 | static inline struct ethhdr *inner_eth_hdr(const struct sk_buff *skb) |
| 28 | { | 36 | { |
| 29 | return (struct ethhdr *)skb_inner_mac_header(skb); | 37 | return (struct ethhdr *)skb_inner_mac_header(skb); |
| @@ -79,15 +79,6 @@ · 78 unmodified lines | |||
| 79 | */ | 79 | */ |
| 80 | #define round_down(x, y) ((x) & ~__round_mask(x, y)) | 80 | #define round_down(x, y) ((x) & ~__round_mask(x, y)) |
| 81 | 81 | ||
| 82 | /** | ||
| 83 | * FIELD_SIZEOF - get the size of a struct's field | ||
| 84 | * @t: the target struct | ||
| 85 | * @f: the target struct's field | ||
| 86 | * Return: the size of @f in the struct definition without having a | ||
| 87 | * declared instance of @t. | ||
| 88 | */ | ||
| 89 | #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) | ||
| 90 | |||
| 91 | #define typeof_member(T, m) typeof(((T*)0)->m) | 82 | #define typeof_member(T, m) typeof(((T*)0)->m) |
| 92 | 83 | ||
| 93 | #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP | 84 | #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP |
| @@ -1175,6 +1175,7 @@ extern unsigned int ata_do_dev_read_id(struct ata_device *dev, · 1174 unmodified lines | |||
| 1175 | struct ata_taskfile *tf, u16 *id); | 1175 | struct ata_taskfile *tf, u16 *id); |
| 1176 | extern void ata_qc_complete(struct ata_queued_cmd *qc); | 1176 | extern void ata_qc_complete(struct ata_queued_cmd *qc); |
| 1177 | extern int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active); | 1177 | extern int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active); |
| 1178 | extern u64 ata_qc_get_active(struct ata_port *ap); | ||
| 1178 | extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd); | 1179 | extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd); |
| 1179 | extern int ata_std_bios_param(struct scsi_device *sdev, | 1180 | extern int ata_std_bios_param(struct scsi_device *sdev, |
| 1180 | struct block_device *bdev, | 1181 | struct block_device *bdev, |
| @@ -122,8 +122,8 @@ static inline bool movable_node_is_enabled(void) · 121 unmodified lines | |||
| 122 | 122 | ||
| 123 | extern void arch_remove_memory(int nid, u64 start, u64 size, | 123 | extern void arch_remove_memory(int nid, u64 start, u64 size, |
| 124 | struct vmem_altmap *altmap); | 124 | struct vmem_altmap *altmap); |
| 125 | extern void __remove_pages(struct zone *zone, unsigned long start_pfn, | 125 | extern void __remove_pages(unsigned long start_pfn, unsigned long nr_pages, |
| 126 | unsigned long nr_pages, struct vmem_altmap *altmap); | 126 | struct vmem_altmap *altmap); |
| 127 | 127 | ||
| 128 | /* reasonably generic interface to expand the physical pages */ | 128 | /* reasonably generic interface to expand the physical pages */ |
| 129 | extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, | 129 | extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, |
| @@ -342,6 +342,9 @@ extern int add_memory(int nid, u64 start, u64 size); · 212 unmodified lines | |||
| 342 | extern int add_memory_resource(int nid, struct resource *resource); | 342 | extern int add_memory_resource(int nid, struct resource *resource); |
| 343 | extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, | 343 | extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, |
| 344 | unsigned long nr_pages, struct vmem_altmap *altmap); | 344 | unsigned long nr_pages, struct vmem_altmap *altmap); |
| 345 | extern void remove_pfn_range_from_zone(struct zone *zone, | ||
| 346 | unsigned long start_pfn, | ||
| 347 | unsigned long nr_pages); | ||
| 345 | extern bool is_memblock_offlined(struct memory_block *mem); | 348 | extern bool is_memblock_offlined(struct memory_block *mem); |
| 346 | extern int sparse_add_section(int nid, unsigned long pfn, | 349 | extern int sparse_add_section(int nid, unsigned long pfn, |
| 347 | unsigned long nr_pages, struct vmem_altmap *altmap); | 350 | unsigned long nr_pages, struct vmem_altmap *altmap); |
| @@ -46,6 +46,14 @@ · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | #define RTC_AL_SEC 0x0018 | 47 | #define RTC_AL_SEC 0x0018 |
| 48 | 48 | ||
| 49 | #define RTC_AL_SEC_MASK 0x003f | ||
| 50 | #define RTC_AL_MIN_MASK 0x003f | ||
| 51 | #define RTC_AL_HOU_MASK 0x001f | ||
| 52 | #define RTC_AL_DOM_MASK 0x001f | ||
| 53 | #define RTC_AL_DOW_MASK 0x0007 | ||
| 54 | #define RTC_AL_MTH_MASK 0x000f | ||
| 55 | #define RTC_AL_YEA_MASK 0x007f | ||
| 56 | |||
| 49 | #define RTC_PDN2 0x002e | 57 | #define RTC_PDN2 0x002e |
| 50 | #define RTC_PDN2_PWRON_ALARM BIT(4) | 58 | #define RTC_PDN2_PWRON_ALARM BIT(4) |
| 51 | 59 | ||
| @@ -40,7 +40,7 @@ typedef enum { · 39 unmodified lines | |||
| 40 | FL_READING, | 40 | FL_READING, |
| 41 | FL_CACHEDPRG, | 41 | FL_CACHEDPRG, |
| 42 | /* These 4 come from onenand_state_t, which has been unified here */ | 42 | /* These 4 come from onenand_state_t, which has been unified here */ |
| 43 | FL_RESETING, | 43 | FL_RESETTING, |
| 44 | FL_OTPING, | 44 | FL_OTPING, |
| 45 | FL_PREPARING_ERASE, | 45 | FL_PREPARING_ERASE, |
| 46 | FL_VERIFYING_ERASE, | 46 | FL_VERIFYING_ERASE, |
| @@ -55,7 +55,7 @@ static inline int of_mdio_parse_addr(struct device *dev, · 54 unmodified lines | |||
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | #else /* CONFIG_OF_MDIO */ | 57 | #else /* CONFIG_OF_MDIO */ |
| 58 | static bool of_mdiobus_child_is_phy(struct device_node *child) | 58 | static inline bool of_mdiobus_child_is_phy(struct device_node *child) |
| 59 | { | 59 | { |
| 60 | return false; | 60 | return false; |
| 61 | } | 61 | } |
| @@ -69,29 +69,32 @@ struct posix_clock_operations { · 68 unmodified lines | |||
| 69 | * | 69 | * |
| 70 | * @ops: Functional interface to the clock | 70 | * @ops: Functional interface to the clock |
| 71 | * @cdev: Character device instance for this clock | 71 | * @cdev: Character device instance for this clock |
| 72 | * @kref: Reference count. | 72 | * @dev: Pointer to the clock's device. |
| 73 | * @rwsem: Protects the 'zombie' field from concurrent access. | 73 | * @rwsem: Protects the 'zombie' field from concurrent access. |
| 74 | * @zombie: If 'zombie' is true, then the hardware has disappeared. | 74 | * @zombie: If 'zombie' is true, then the hardware has disappeared. |
| 75 | * @release: A function to free the structure when the reference count reaches | ||
| 76 | * zero. May be NULL if structure is statically allocated. | ||
| 77 | * | 75 | * |
| 78 | * Drivers should embed their struct posix_clock within a private | 76 | * Drivers should embed their struct posix_clock within a private |
| 79 | * structure, obtaining a reference to it during callbacks using | 77 | * structure, obtaining a reference to it during callbacks using |
| 80 | * container_of(). | 78 | * container_of(). |
| 79 | * | ||
| 80 | * Drivers should supply an initialized but not exposed struct device | ||
| 81 | * to posix_clock_register(). It is used to manage lifetime of the | ||
| 82 | * driver's private structure. It's 'release' field should be set to | ||
| 83 | * a release function for this private structure. | ||
| 81 | */ | 84 | */ |
| 82 | struct posix_clock { | 85 | struct posix_clock { |
| 83 | struct posix_clock_operations ops; | 86 | struct posix_clock_operations ops; |
| 84 | struct cdev cdev; | 87 | struct cdev cdev; |
| 85 | struct kref kref; | 88 | struct device *dev; |
| 86 | struct rw_semaphore rwsem; | 89 | struct rw_semaphore rwsem; |
| 87 | bool zombie; | 90 | bool zombie; |
| 88 | void (*release)(struct posix_clock *clk); | ||
| 89 | }; | 91 | }; |
| 90 | 92 | ||
| 91 | /** | 93 | /** |
| 92 | * posix_clock_register() - register a new clock | 94 | * posix_clock_register() - register a new clock |
| 93 | * @clk: Pointer to the clock. Caller must provide 'ops' and 'release' | 95 | * @clk: Pointer to the clock. Caller must provide 'ops' field |
| 94 | * @devid: Allocated device id | 96 | * @dev: Pointer to the initialized device. Caller must provide |
| 97 | * 'release' field | ||
| 95 | * | 98 | * |
| 96 | * A clock driver calls this function to register itself with the | 99 | * A clock driver calls this function to register itself with the |
| 97 | * clock device subsystem. If 'clk' points to dynamically allocated | 100 | * clock device subsystem. If 'clk' points to dynamically allocated |
| @@ -100,7 +103,7 @@ struct posix_clock { · 2 unmodified lines | |||
| 100 | * | 103 | * |
| 101 | * Returns zero on success, non-zero otherwise. | 104 | * Returns zero on success, non-zero otherwise. |
| 102 | */ | 105 | */ |
| 103 | int posix_clock_register(struct posix_clock *clk, dev_t devid); | 106 | int posix_clock_register(struct posix_clock *clk, struct device *dev); |
| 104 | 107 | ||
| 105 | /** | 108 | /** |
| 106 | * posix_clock_unregister() - unregister a clock | 109 | * posix_clock_unregister() - unregister a clock |
| @@ -689,10 +689,10 @@ extern void spi_finalize_current_transfer(struct spi_controller *ctlr); · 688 unmodified lines | |||
| 689 | /* Helper calls for driver to timestamp transfer */ | 689 | /* Helper calls for driver to timestamp transfer */ |
| 690 | void spi_take_timestamp_pre(struct spi_controller *ctlr, | 690 | void spi_take_timestamp_pre(struct spi_controller *ctlr, |
| 691 | struct spi_transfer *xfer, | 691 | struct spi_transfer *xfer, |
| 692 | const void *tx, bool irqs_off); | 692 | size_t progress, bool irqs_off); |
| 693 | void spi_take_timestamp_post(struct spi_controller *ctlr, | 693 | void spi_take_timestamp_post(struct spi_controller *ctlr, |
| 694 | struct spi_transfer *xfer, | 694 | struct spi_transfer *xfer, |
| 695 | const void *tx, bool irqs_off); | 695 | size_t progress, bool irqs_off); |
| 696 | 696 | ||
| 697 | /* the spi driver core manages memory for the spi_controller classdev */ | 697 | /* the spi driver core manages memory for the spi_controller classdev */ |
| 698 | extern struct spi_controller *__spi_alloc_controller(struct device *host, | 698 | extern struct spi_controller *__spi_alloc_controller(struct device *host, |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* | 2 | /* |
| 3 | * 10G controller driver for Samsung EXYNOS SoCs | 3 | * 10G controller driver for Samsung Exynos SoCs |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | 5 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. |
| 6 | * http://www.samsung.com | 6 | * http://www.samsung.com |
| @@ -1232,6 +1232,7 @@ asmlinkage long sys_ni_syscall(void); · 1231 unmodified lines | |||
| 1232 | */ | 1232 | */ |
| 1233 | 1233 | ||
| 1234 | int ksys_umount(char __user *name, int flags); | 1234 | int ksys_umount(char __user *name, int flags); |
| 1235 | int ksys_dup(unsigned int fildes); | ||
| 1235 | int ksys_chroot(const char __user *filename); | 1236 | int ksys_chroot(const char __user *filename); |
| 1236 | ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); | 1237 | ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); |
| 1237 | int ksys_chdir(const char __user *filename); | 1238 | int ksys_chdir(const char __user *filename); |
| @@ -516,7 +516,16 @@ static inline void skb_dst_update_pmtu(struct sk_buff *skb, u32 mtu) · 515 unmodified lines | |||
| 516 | struct dst_entry *dst = skb_dst(skb); | 516 | struct dst_entry *dst = skb_dst(skb); |
| 517 | 517 | ||
| 518 | if (dst && dst->ops->update_pmtu) | 518 | if (dst && dst->ops->update_pmtu) |
| 519 | dst->ops->update_pmtu(dst, NULL, skb, mtu); | 519 | dst->ops->update_pmtu(dst, NULL, skb, mtu, true); |
| 520 | } | ||
| 521 | |||
| 522 | /* update dst pmtu but not do neighbor confirm */ | ||
| 523 | static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu) | ||
| 524 | { | ||
| 525 | struct dst_entry *dst = skb_dst(skb); | ||
| 526 | |||
| 527 | if (dst && dst->ops->update_pmtu) | ||
| 528 | dst->ops->update_pmtu(dst, NULL, skb, mtu, false); | ||
| 520 | } | 529 | } |
| 521 | 530 | ||
| 522 | static inline void skb_tunnel_check_pmtu(struct sk_buff *skb, | 531 | static inline void skb_tunnel_check_pmtu(struct sk_buff *skb, |
| @@ -526,7 +535,7 @@ static inline void skb_tunnel_check_pmtu(struct sk_buff *skb, · 3 unmodified lines | |||
| 526 | u32 encap_mtu = dst_mtu(encap_dst); | 535 | u32 encap_mtu = dst_mtu(encap_dst); |
| 527 | 536 | ||
| 528 | if (skb->len > encap_mtu - headroom) | 537 | if (skb->len > encap_mtu - headroom) |
| 529 | skb_dst_update_pmtu(skb, encap_mtu - headroom); | 538 | skb_dst_update_pmtu_no_confirm(skb, encap_mtu - headroom); |
| 530 | } | 539 | } |
| 531 | 540 | ||
| 532 | #endif /* _NET_DST_H */ | 541 | #endif /* _NET_DST_H */ |
| @@ -27,7 +27,8 @@ struct dst_ops { · 26 unmodified lines | |||
| 27 | struct dst_entry * (*negative_advice)(struct dst_entry *); | 27 | struct dst_entry * (*negative_advice)(struct dst_entry *); |
| 28 | void (*link_failure)(struct sk_buff *); | 28 | void (*link_failure)(struct sk_buff *); |
| 29 | void (*update_pmtu)(struct dst_entry *dst, struct sock *sk, | 29 | void (*update_pmtu)(struct dst_entry *dst, struct sock *sk, |
| 30 | struct sk_buff *skb, u32 mtu); | 30 | struct sk_buff *skb, u32 mtu, |
| 31 | bool confirm_neigh); | ||
| 31 | void (*redirect)(struct dst_entry *dst, struct sock *sk, | 32 | void (*redirect)(struct dst_entry *dst, struct sock *sk, |
| 32 | struct sk_buff *skb); | 33 | struct sk_buff *skb); |
| 33 | int (*local_out)(struct net *net, struct sock *sk, struct sk_buff *skb); | 34 | int (*local_out)(struct net *net, struct sock *sk, struct sk_buff *skb); |
| @@ -106,6 +106,12 @@ struct flow_offload { · 105 unmodified lines | |||
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | #define NF_FLOW_TIMEOUT (30 * HZ) | 108 | #define NF_FLOW_TIMEOUT (30 * HZ) |
| 109 | #define nf_flowtable_time_stamp (u32)jiffies | ||
| 110 | |||
| 111 | static inline __s32 nf_flow_timeout_delta(unsigned int timeout) | ||
| 112 | { | ||
| 113 | return (__s32)(timeout - nf_flowtable_time_stamp); | ||
| 114 | } | ||
| 109 | 115 | ||
| 110 | struct nf_flow_route { | 116 | struct nf_flow_route { |
| 111 | struct { | 117 | struct { |
| @@ -308,6 +308,7 @@ struct tcf_proto_ops { · 307 unmodified lines | |||
| 308 | int (*delete)(struct tcf_proto *tp, void *arg, | 308 | int (*delete)(struct tcf_proto *tp, void *arg, |
| 309 | bool *last, bool rtnl_held, | 309 | bool *last, bool rtnl_held, |
| 310 | struct netlink_ext_ack *); | 310 | struct netlink_ext_ack *); |
| 311 | bool (*delete_empty)(struct tcf_proto *tp); | ||
| 311 | void (*walk)(struct tcf_proto *tp, | 312 | void (*walk)(struct tcf_proto *tp, |
| 312 | struct tcf_walker *arg, bool rtnl_held); | 313 | struct tcf_walker *arg, bool rtnl_held); |
| 313 | int (*reoffload)(struct tcf_proto *tp, bool add, | 314 | int (*reoffload)(struct tcf_proto *tp, bool add, |
| @@ -336,6 +337,10 @@ struct tcf_proto_ops { · 22 unmodified lines | |||
| 336 | int flags; | 337 | int flags; |
| 337 | }; | 338 | }; |
| 338 | 339 | ||
| 340 | /* Classifiers setting TCF_PROTO_OPS_DOIT_UNLOCKED in tcf_proto_ops->flags | ||
| 341 | * are expected to implement tcf_proto_ops->delete_empty(), otherwise race | ||
| 342 | * conditions can occur when filters are inserted/deleted simultaneously. | ||
| 343 | */ | ||
| 339 | enum tcf_proto_ops_flags { | 344 | enum tcf_proto_ops_flags { |
| 340 | TCF_PROTO_OPS_DOIT_UNLOCKED = 1, | 345 | TCF_PROTO_OPS_DOIT_UNLOCKED = 1, |
| 341 | }; | 346 | }; |
| @@ -4,8 +4,8 @@ · 3 unmodified lines | |||
| 4 | * | 4 | * |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #ifndef _ASM_RISCV_SIFIVE_L2_CACHE_H | 7 | #ifndef __SOC_SIFIVE_L2_CACHE_H |
| 8 | #define _ASM_RISCV_SIFIVE_L2_CACHE_H | 8 | #define __SOC_SIFIVE_L2_CACHE_H |
| 9 | 9 | ||
| 10 | extern int register_sifive_l2_error_notifier(struct notifier_block *nb); | 10 | extern int register_sifive_l2_error_notifier(struct notifier_block *nb); |
| 11 | extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb); | 11 | extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb); |
| @@ -13,4 +13,4 @@ extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb); · 1 unmodified line | |||
| 13 | #define SIFIVE_L2_ERR_TYPE_CE 0 | 13 | #define SIFIVE_L2_ERR_TYPE_CE 0 |
| 14 | #define SIFIVE_L2_ERR_TYPE_UE 1 | 14 | #define SIFIVE_L2_ERR_TYPE_UE 1 |
| 15 | 15 | ||
| 16 | #endif /* _ASM_RISCV_SIFIVE_L2_CACHE_H */ | 16 | #endif /* __SOC_SIFIVE_L2_CACHE_H */ |
| @@ -18,13 +18,13 @@ DECLARE_EVENT_CLASS(preemptirq_template, · 17 unmodified lines | |||
| 18 | TP_ARGS(ip, parent_ip), | 18 | TP_ARGS(ip, parent_ip), |
| 19 | 19 | ||
| 20 | TP_STRUCT__entry( | 20 | TP_STRUCT__entry( |
| 21 | __field(u32, caller_offs) | 21 | __field(s32, caller_offs) |
| 22 | __field(u32, parent_offs) | 22 | __field(s32, parent_offs) |
| 23 | ), | 23 | ), |
| 24 | 24 | ||
| 25 | TP_fast_assign( | 25 | TP_fast_assign( |
| 26 | __entry->caller_offs = (u32)(ip - (unsigned long)_stext); | 26 | __entry->caller_offs = (s32)(ip - (unsigned long)_stext); |
| 27 | __entry->parent_offs = (u32)(parent_ip - (unsigned long)_stext); | 27 | __entry->parent_offs = (s32)(parent_ip - (unsigned long)_stext); |
| 28 | ), | 28 | ), |
| 29 | 29 | ||
| 30 | TP_printk("caller=%pS parent=%pS", | 30 | TP_printk("caller=%pS parent=%pS", |
| @@ -34,6 +34,7 @@ struct input_event { · 33 unmodified lines | |||
| 34 | __kernel_ulong_t __sec; | 34 | __kernel_ulong_t __sec; |
| 35 | #if defined(__sparc__) && defined(__arch64__) | 35 | #if defined(__sparc__) && defined(__arch64__) |
| 36 | unsigned int __usec; | 36 | unsigned int __usec; |
| 37 | unsigned int __pad; | ||
| 37 | #else | 38 | #else |
| 38 | __kernel_ulong_t __usec; | 39 | __kernel_ulong_t __usec; |
| 39 | #endif | 40 | #endif |
| @@ -9,11 +9,11 @@ · 8 unmodified lines | |||
| 9 | * and the comment before kcov_remote_start() for usage details. | 9 | * and the comment before kcov_remote_start() for usage details. |
| 10 | */ | 10 | */ |
| 11 | struct kcov_remote_arg { | 11 | struct kcov_remote_arg { |
| 12 | unsigned int trace_mode; /* KCOV_TRACE_PC or KCOV_TRACE_CMP */ | 12 | __u32 trace_mode; /* KCOV_TRACE_PC or KCOV_TRACE_CMP */ |
| 13 | unsigned int area_size; /* Length of coverage buffer in words */ | 13 | __u32 area_size; /* Length of coverage buffer in words */ |
| 14 | unsigned int num_handles; /* Size of handles array */ | 14 | __u32 num_handles; /* Size of handles array */ |
| 15 | __u64 common_handle; | 15 | __aligned_u64 common_handle; |
| 16 | __u64 handles[0]; | 16 | __aligned_u64 handles[0]; |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | #define KCOV_REMOTE_MAX_HANDLES 0x100 | 19 | #define KCOV_REMOTE_MAX_HANDLES 0x100 |
| @@ -93,7 +93,6 @@ · 92 unmodified lines | |||
| 93 | #include <linux/rodata_test.h> | 93 | #include <linux/rodata_test.h> |
| 94 | #include <linux/jump_label.h> | 94 | #include <linux/jump_label.h> |
| 95 | #include <linux/mem_encrypt.h> | 95 | #include <linux/mem_encrypt.h> |
| 96 | #include <linux/file.h> | ||
| 97 | 96 | ||
| 98 | #include <asm/io.h> | 97 | #include <asm/io.h> |
| 99 | #include <asm/bugs.h> | 98 | #include <asm/bugs.h> |
| @@ -1158,26 +1157,13 @@ static int __ref kernel_init(void *unused) · 1058 unmodified lines | |||
| 1158 | 1157 | ||
| 1159 | void console_on_rootfs(void) | 1158 | void console_on_rootfs(void) |
| 1160 | { | 1159 | { |
| 1161 | struct file *file; | 1160 | /* Open the /dev/console as stdin, this should never fail */ |
| 1162 | unsigned int i; | 1161 | if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) |
| 1163 | 1162 | pr_err("Warning: unable to open an initial console.\n"); | |
| 1164 | /* Open /dev/console in kernelspace, this should never fail */ | ||
| 1165 | file = filp_open("/dev/console", O_RDWR, 0); | ||
| 1166 | if (IS_ERR(file)) | ||
| 1167 | goto err_out; | ||
| 1168 | |||
| 1169 | /* create stdin/stdout/stderr, this should never fail */ | ||
| 1170 | for (i = 0; i < 3; i++) { | ||
| 1171 | if (f_dupfd(i, file, 0) != i) | ||
| 1172 | goto err_out; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | return; | ||
| 1176 | 1163 | ||
| 1177 | err_out: | 1164 | /* create stdout/stderr */ |
| 1178 | /* no panic -- this might not be fatal */ | 1165 | (void) ksys_dup(0); |
| 1179 | pr_err("Warning: unable to open an initial console.\n"); | 1166 | (void) ksys_dup(0); |
| 1180 | return; | ||
| 1181 | } | 1167 | } |
| 1182 | 1168 | ||
| 1183 | static noinline void __init kernel_init_freeable(void) | 1169 | static noinline void __init kernel_init_freeable(void) |
| @@ -35,8 +35,8 @@ void cgroup_bpf_offline(struct cgroup *cgrp) · 34 unmodified lines | |||
| 35 | */ | 35 | */ |
| 36 | static void cgroup_bpf_release(struct work_struct *work) | 36 | static void cgroup_bpf_release(struct work_struct *work) |
| 37 | { | 37 | { |
| 38 | struct cgroup *cgrp = container_of(work, struct cgroup, | 38 | struct cgroup *p, *cgrp = container_of(work, struct cgroup, |
| 39 | bpf.release_work); | 39 | bpf.release_work); |
| 40 | enum bpf_cgroup_storage_type stype; | 40 | enum bpf_cgroup_storage_type stype; |
| 41 | struct bpf_prog_array *old_array; | 41 | struct bpf_prog_array *old_array; |
| 42 | unsigned int type; | 42 | unsigned int type; |
| @@ -65,6 +65,9 @@ static void cgroup_bpf_release(struct work_struct *work) · 22 unmodified lines | |||
| 65 | 65 | ||
| 66 | mutex_unlock(&cgroup_mutex); | 66 | mutex_unlock(&cgroup_mutex); |
| 67 | 67 | ||
| 68 | for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p)) | ||
| 69 | cgroup_bpf_put(p); | ||
| 70 | |||
| 68 | percpu_ref_exit(&cgrp->bpf.refcnt); | 71 | percpu_ref_exit(&cgrp->bpf.refcnt); |
| 69 | cgroup_put(cgrp); | 72 | cgroup_put(cgrp); |
| 70 | } | 73 | } |
| @@ -199,6 +202,7 @@ int cgroup_bpf_inherit(struct cgroup *cgrp) · 128 unmodified lines | |||
| 199 | */ | 202 | */ |
| 200 | #define NR ARRAY_SIZE(cgrp->bpf.effective) | 203 | #define NR ARRAY_SIZE(cgrp->bpf.effective) |
| 201 | struct bpf_prog_array *arrays[NR] = {}; | 204 | struct bpf_prog_array *arrays[NR] = {}; |
| 205 | struct cgroup *p; | ||
| 202 | int ret, i; | 206 | int ret, i; |
| 203 | 207 | ||
| 204 | ret = percpu_ref_init(&cgrp->bpf.refcnt, cgroup_bpf_release_fn, 0, | 208 | ret = percpu_ref_init(&cgrp->bpf.refcnt, cgroup_bpf_release_fn, 0, |
| @@ -206,6 +210,9 @@ int cgroup_bpf_inherit(struct cgroup *cgrp) · 1 unmodified line | |||
| 206 | if (ret) | 210 | if (ret) |
| 207 | return ret; | 211 | return ret; |
| 208 | 212 | ||
| 213 | for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p)) | ||
| 214 | cgroup_bpf_get(p); | ||
| 215 | |||
| 209 | for (i = 0; i < NR; i++) | 216 | for (i = 0; i < NR; i++) |
| 210 | INIT_LIST_HEAD(&cgrp->bpf.progs[i]); | 217 | INIT_LIST_HEAD(&cgrp->bpf.progs[i]); |
| 211 | 218 | ||
| @@ -907,7 +907,8 @@ static const int caller_saved[CALLER_SAVED_REGS] = { · 906 unmodified lines | |||
| 907 | BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5 | 907 | BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5 |
| 908 | }; | 908 | }; |
| 909 | 909 | ||
| 910 | static void __mark_reg_not_init(struct bpf_reg_state *reg); | 910 | static void __mark_reg_not_init(const struct bpf_verifier_env *env, |
| 911 | struct bpf_reg_state *reg); | ||
| 911 | 912 | ||
| 912 | /* Mark the unknown part of a register (variable offset or scalar value) as | 913 | /* Mark the unknown part of a register (variable offset or scalar value) as |
| 913 | * known to have the value @imm. | 914 | * known to have the value @imm. |
| @@ -945,7 +946,7 @@ static void mark_reg_known_zero(struct bpf_verifier_env *env, · 31 unmodified lines | |||
| 945 | verbose(env, "mark_reg_known_zero(regs, %u)\n", regno); | 946 | verbose(env, "mark_reg_known_zero(regs, %u)\n", regno); |
| 946 | /* Something bad happened, let's kill all regs */ | 947 | /* Something bad happened, let's kill all regs */ |
| 947 | for (regno = 0; regno < MAX_BPF_REG; regno++) | 948 | for (regno = 0; regno < MAX_BPF_REG; regno++) |
| 948 | __mark_reg_not_init(regs + regno); | 949 | __mark_reg_not_init(env, regs + regno); |
| 949 | return; | 950 | return; |
| 950 | } | 951 | } |
| 951 | __mark_reg_known_zero(regs + regno); | 952 | __mark_reg_known_zero(regs + regno); |
| @@ -1054,7 +1055,8 @@ static void __mark_reg_unbounded(struct bpf_reg_state *reg) · 102 unmodified lines | |||
| 1054 | } | 1055 | } |
| 1055 | 1056 | ||
| 1056 | /* Mark a register as having a completely unknown (scalar) value. */ | 1057 | /* Mark a register as having a completely unknown (scalar) value. */ |
| 1057 | static void __mark_reg_unknown(struct bpf_reg_state *reg) | 1058 | static void __mark_reg_unknown(const struct bpf_verifier_env *env, |
| 1059 | struct bpf_reg_state *reg) | ||
| 1058 | { | 1060 | { |
| 1059 | /* | 1061 | /* |
| 1060 | * Clear type, id, off, and union(map_ptr, range) and | 1062 | * Clear type, id, off, and union(map_ptr, range) and |
| @@ -1064,6 +1066,8 @@ static void __mark_reg_unknown(struct bpf_reg_state *reg) · 3 unmodified lines | |||
| 1064 | reg->type = SCALAR_VALUE; | 1066 | reg->type = SCALAR_VALUE; |
| 1065 | reg->var_off = tnum_unknown; | 1067 | reg->var_off = tnum_unknown; |
| 1066 | reg->frameno = 0; | 1068 | reg->frameno = 0; |
| 1069 | reg->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ? | ||
| 1070 | true : false; | ||
| 1067 | __mark_reg_unbounded(reg); | 1071 | __mark_reg_unbounded(reg); |
| 1068 | } | 1072 | } |
| 1069 | 1073 | ||
| @@ -1074,19 +1078,16 @@ static void mark_reg_unknown(struct bpf_verifier_env *env, · 4 unmodified lines | |||
| 1074 | verbose(env, "mark_reg_unknown(regs, %u)\n", regno); | 1078 | verbose(env, "mark_reg_unknown(regs, %u)\n", regno); |
| 1075 | /* Something bad happened, let's kill all regs except FP */ | 1079 | /* Something bad happened, let's kill all regs except FP */ |
| 1076 | for (regno = 0; regno < BPF_REG_FP; regno++) | 1080 | for (regno = 0; regno < BPF_REG_FP; regno++) |
| 1077 | __mark_reg_not_init(regs + regno); | 1081 | __mark_reg_not_init(env, regs + regno); |
| 1078 | return; | 1082 | return; |
| 1079 | } | 1083 | } |
| 1080 | regs += regno; | 1084 | __mark_reg_unknown(env, regs + regno); |
| 1081 | __mark_reg_unknown(regs); | ||
| 1082 | /* constant backtracking is enabled for root without bpf2bpf calls */ | ||
| 1083 | regs->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ? | ||
| 1084 | true : false; | ||
| 1085 | } | 1085 | } |
| 1086 | 1086 | ||
| 1087 | static void __mark_reg_not_init(struct bpf_reg_state *reg) | 1087 | static void __mark_reg_not_init(const struct bpf_verifier_env *env, |
| 1088 | struct bpf_reg_state *reg) | ||
| 1088 | { | 1089 | { |
| 1089 | __mark_reg_unknown(reg); | 1090 | __mark_reg_unknown(env, reg); |
| 1090 | reg->type = NOT_INIT; | 1091 | reg->type = NOT_INIT; |
| 1091 | } | 1092 | } |
| 1092 | 1093 | ||
| @@ -1097,10 +1098,10 @@ static void mark_reg_not_init(struct bpf_verifier_env *env, · 4 unmodified lines | |||
| 1097 | verbose(env, "mark_reg_not_init(regs, %u)\n", regno); | 1098 | verbose(env, "mark_reg_not_init(regs, %u)\n", regno); |
| 1098 | /* Something bad happened, let's kill all regs except FP */ | 1099 | /* Something bad happened, let's kill all regs except FP */ |
| 1099 | for (regno = 0; regno < BPF_REG_FP; regno++) | 1100 | for (regno = 0; regno < BPF_REG_FP; regno++) |
| 1100 | __mark_reg_not_init(regs + regno); | 1101 | __mark_reg_not_init(env, regs + regno); |
| 1101 | return; | 1102 | return; |
| 1102 | } | 1103 | } |
| 1103 | __mark_reg_not_init(regs + regno); | 1104 | __mark_reg_not_init(env, regs + regno); |
| 1104 | } | 1105 | } |
| 1105 | 1106 | ||
| 1106 | #define DEF_NOT_SUBREG (0) | 1107 | #define DEF_NOT_SUBREG (0) |
| @@ -3234,7 +3235,7 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno, · 2127 unmodified lines | |||
| 3234 | } | 3235 | } |
| 3235 | if (state->stack[spi].slot_type[0] == STACK_SPILL && | 3236 | if (state->stack[spi].slot_type[0] == STACK_SPILL && |
| 3236 | state->stack[spi].spilled_ptr.type == SCALAR_VALUE) { | 3237 | state->stack[spi].spilled_ptr.type == SCALAR_VALUE) { |
| 3237 | __mark_reg_unknown(&state->stack[spi].spilled_ptr); | 3238 | __mark_reg_unknown(env, &state->stack[spi].spilled_ptr); |
| 3238 | for (j = 0; j < BPF_REG_SIZE; j++) | 3239 | for (j = 0; j < BPF_REG_SIZE; j++) |
| 3239 | state->stack[spi].slot_type[j] = STACK_MISC; | 3240 | state->stack[spi].slot_type[j] = STACK_MISC; |
| 3240 | goto mark; | 3241 | goto mark; |
| @@ -3892,7 +3893,7 @@ static void __clear_all_pkt_pointers(struct bpf_verifier_env *env, · 651 unmodified lines | |||
| 3892 | if (!reg) | 3893 | if (!reg) |
| 3893 | continue; | 3894 | continue; |
| 3894 | if (reg_is_pkt_pointer_any(reg)) | 3895 | if (reg_is_pkt_pointer_any(reg)) |
| 3895 | __mark_reg_unknown(reg); | 3896 | __mark_reg_unknown(env, reg); |
| 3896 | } | 3897 | } |
| 3897 | } | 3898 | } |
| 3898 | 3899 | ||
| @@ -3920,7 +3921,7 @@ static void release_reg_references(struct bpf_verifier_env *env, · 21 unmodified lines | |||
| 3920 | if (!reg) | 3921 | if (!reg) |
| 3921 | continue; | 3922 | continue; |
| 3922 | if (reg->ref_obj_id == ref_obj_id) | 3923 | if (reg->ref_obj_id == ref_obj_id) |
| 3923 | __mark_reg_unknown(reg); | 3924 | __mark_reg_unknown(env, reg); |
| 3924 | } | 3925 | } |
| 3925 | } | 3926 | } |
| 3926 | 3927 | ||
| @@ -4582,7 +4583,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, · 655 unmodified lines | |||
| 4582 | /* Taint dst register if offset had invalid bounds derived from | 4583 | /* Taint dst register if offset had invalid bounds derived from |
| 4583 | * e.g. dead branches. | 4584 | * e.g. dead branches. |
| 4584 | */ | 4585 | */ |
| 4585 | __mark_reg_unknown(dst_reg); | 4586 | __mark_reg_unknown(env, dst_reg); |
| 4586 | return 0; | 4587 | return 0; |
| 4587 | } | 4588 | } |
| 4588 | 4589 | ||
| @@ -4834,13 +4835,13 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, · 245 unmodified lines | |||
| 4834 | /* Taint dst register if offset had invalid bounds derived from | 4835 | /* Taint dst register if offset had invalid bounds derived from |
| 4835 | * e.g. dead branches. | 4836 | * e.g. dead branches. |
| 4836 | */ | 4837 | */ |
| 4837 | __mark_reg_unknown(dst_reg); | 4838 | __mark_reg_unknown(env, dst_reg); |
| 4838 | return 0; | 4839 | return 0; |
| 4839 | } | 4840 | } |
| 4840 | 4841 | ||
| 4841 | if (!src_known && | 4842 | if (!src_known && |
| 4842 | opcode != BPF_ADD && opcode != BPF_SUB && opcode != BPF_AND) { | 4843 | opcode != BPF_ADD && opcode != BPF_SUB && opcode != BPF_AND) { |
| 4843 | __mark_reg_unknown(dst_reg); | 4844 | __mark_reg_unknown(env, dst_reg); |
| 4844 | return 0; | 4845 | return 0; |
| 4845 | } | 4846 | } |
| 4846 | 4847 | ||
| @@ -6263,6 +6264,7 @@ static bool may_access_skb(enum bpf_prog_type type) · 1416 unmodified lines | |||
| 6263 | static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) | 6264 | static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) |
| 6264 | { | 6265 | { |
| 6265 | struct bpf_reg_state *regs = cur_regs(env); | 6266 | struct bpf_reg_state *regs = cur_regs(env); |
| 6267 | static const int ctx_reg = BPF_REG_6; | ||
| 6266 | u8 mode = BPF_MODE(insn->code); | 6268 | u8 mode = BPF_MODE(insn->code); |
| 6267 | int i, err; | 6269 | int i, err; |
| 6268 | 6270 | ||
| @@ -6296,7 +6298,7 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) · 27 unmodified lines | |||
| 6296 | } | 6298 | } |
| 6297 | 6299 | ||
| 6298 | /* check whether implicit source operand (register R6) is readable */ | 6300 | /* check whether implicit source operand (register R6) is readable */ |
| 6299 | err = check_reg_arg(env, BPF_REG_6, SRC_OP); | 6301 | err = check_reg_arg(env, ctx_reg, SRC_OP); |
| 6300 | if (err) | 6302 | if (err) |
| 6301 | return err; | 6303 | return err; |
| 6302 | 6304 | ||
| @@ -6315,7 +6317,7 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) · 12 unmodified lines | |||
| 6315 | return -EINVAL; | 6317 | return -EINVAL; |
| 6316 | } | 6318 | } |
| 6317 | 6319 | ||
| 6318 | if (regs[BPF_REG_6].type != PTR_TO_CTX) { | 6320 | if (regs[ctx_reg].type != PTR_TO_CTX) { |
| 6319 | verbose(env, | 6321 | verbose(env, |
| 6320 | "at the time of BPF_LD_ABS|IND R6 != pointer to skb\n"); | 6322 | "at the time of BPF_LD_ABS|IND R6 != pointer to skb\n"); |
| 6321 | return -EINVAL; | 6323 | return -EINVAL; |
| @@ -6328,6 +6330,10 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) · 6 unmodified lines | |||
| 6328 | return err; | 6330 | return err; |
| 6329 | } | 6331 | } |
| 6330 | 6332 | ||
| 6333 | err = check_ctx_reg(env, ®s[ctx_reg], ctx_reg); | ||
| 6334 | if (err < 0) | ||
| 6335 | return err; | ||
| 6336 | |||
| 6331 | /* reset caller saved regs to unreadable */ | 6337 | /* reset caller saved regs to unreadable */ |
| 6332 | for (i = 0; i < CALLER_SAVED_REGS; i++) { | 6338 | for (i = 0; i < CALLER_SAVED_REGS; i++) { |
| 6333 | mark_reg_not_init(env, regs, caller_saved[i]); | 6339 | mark_reg_not_init(env, regs, caller_saved[i]); |
| @@ -6982,7 +6988,7 @@ static void clean_func_state(struct bpf_verifier_env *env, · 648 unmodified lines | |||
| 6982 | /* since the register is unused, clear its state | 6988 | /* since the register is unused, clear its state |
| 6983 | * to make further comparison simpler | 6989 | * to make further comparison simpler |
| 6984 | */ | 6990 | */ |
| 6985 | __mark_reg_not_init(&st->regs[i]); | 6991 | __mark_reg_not_init(env, &st->regs[i]); |
| 6986 | } | 6992 | } |
| 6987 | 6993 | ||
| 6988 | for (i = 0; i < st->allocated_stack / BPF_REG_SIZE; i++) { | 6994 | for (i = 0; i < st->allocated_stack / BPF_REG_SIZE; i++) { |
| @@ -6990,7 +6996,7 @@ static void clean_func_state(struct bpf_verifier_env *env, · 1 unmodified line | |||
| 6990 | /* liveness must not touch this stack slot anymore */ | 6996 | /* liveness must not touch this stack slot anymore */ |
| 6991 | st->stack[i].spilled_ptr.live |= REG_LIVE_DONE; | 6997 | st->stack[i].spilled_ptr.live |= REG_LIVE_DONE; |
| 6992 | if (!(live & REG_LIVE_READ)) { | 6998 | if (!(live & REG_LIVE_READ)) { |
| 6993 | __mark_reg_not_init(&st->stack[i].spilled_ptr); | 6999 | __mark_reg_not_init(env, &st->stack[i].spilled_ptr); |
| 6994 | for (j = 0; j < BPF_REG_SIZE; j++) | 7000 | for (j = 0; j < BPF_REG_SIZE; j++) |
| 6995 | st->stack[i].slot_type[j] = STACK_INVALID; | 7001 | st->stack[i].slot_type[j] = STACK_INVALID; |
| 6996 | } | 7002 | } |
| @@ -223,7 +223,7 @@ struct cred *cred_alloc_blank(void) · 222 unmodified lines | |||
| 223 | new->magic = CRED_MAGIC; | 223 | new->magic = CRED_MAGIC; |
| 224 | #endif | 224 | #endif |
| 225 | 225 | ||
| 226 | if (security_cred_alloc_blank(new, GFP_KERNEL) < 0) | 226 | if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0) |
| 227 | goto error; | 227 | goto error; |
| 228 | 228 | ||
| 229 | return new; | 229 | return new; |
| @@ -282,7 +282,7 @@ struct cred *prepare_creds(void) · 52 unmodified lines | |||
| 282 | new->security = NULL; | 282 | new->security = NULL; |
| 283 | #endif | 283 | #endif |
| 284 | 284 | ||
| 285 | if (security_prepare_creds(new, old, GFP_KERNEL) < 0) | 285 | if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0) |
| 286 | goto error; | 286 | goto error; |
| 287 | validate_creds(new); | 287 | validate_creds(new); |
| 288 | return new; | 288 | return new; |
| @@ -715,7 +715,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) · 426 unmodified lines | |||
| 715 | #ifdef CONFIG_SECURITY | 715 | #ifdef CONFIG_SECURITY |
| 716 | new->security = NULL; | 716 | new->security = NULL; |
| 717 | #endif | 717 | #endif |
| 718 | if (security_prepare_creds(new, old, GFP_KERNEL) < 0) | 718 | if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0) |
| 719 | goto error; | 719 | goto error; |
| 720 | 720 | ||
| 721 | put_cred(old); | 721 | put_cred(old); |
| @@ -517,10 +517,6 @@ static struct task_struct *find_child_reaper(struct task_struct *father, · 516 unmodified lines | |||
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | write_unlock_irq(&tasklist_lock); | 519 | write_unlock_irq(&tasklist_lock); |
| 520 | if (unlikely(pid_ns == &init_pid_ns)) { | ||
| 521 | panic("Attempted to kill init! exitcode=0x%08x\n", | ||
| 522 | father->signal->group_exit_code ?: father->exit_code); | ||
| 523 | } | ||
| 524 | 520 | ||
| 525 | list_for_each_entry_safe(p, n, dead, ptrace_entry) { | 521 | list_for_each_entry_safe(p, n, dead, ptrace_entry) { |
| 526 | list_del_init(&p->ptrace_entry); | 522 | list_del_init(&p->ptrace_entry); |
| @@ -766,6 +762,14 @@ void __noreturn do_exit(long code) · 239 unmodified lines | |||
| 766 | acct_update_integrals(tsk); | 762 | acct_update_integrals(tsk); |
| 767 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 763 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
| 768 | if (group_dead) { | 764 | if (group_dead) { |
| 765 | /* | ||
| 766 | * If the last thread of global init has exited, panic | ||
| 767 | * immediately to get a useable coredump. | ||
| 768 | */ | ||
| 769 | if (unlikely(is_global_init(tsk))) | ||
| 770 | panic("Attempted to kill init! exitcode=0x%08x\n", | ||
| 771 | tsk->signal->group_exit_code ?: (int)code); | ||
| 772 | |||
| 769 | #ifdef CONFIG_POSIX_TIMERS | 773 | #ifdef CONFIG_POSIX_TIMERS |
| 770 | hrtimer_cancel(&tsk->signal->real_timer); | 774 | hrtimer_cancel(&tsk->signal->real_timer); |
| 771 | exit_itimers(tsk->signal); | 775 | exit_itimers(tsk->signal); |
| @@ -2578,6 +2578,16 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, · 2577 unmodified lines | |||
| 2578 | #endif | 2578 | #endif |
| 2579 | 2579 | ||
| 2580 | #ifdef __ARCH_WANT_SYS_CLONE3 | 2580 | #ifdef __ARCH_WANT_SYS_CLONE3 |
| 2581 | |||
| 2582 | /* | ||
| 2583 | * copy_thread implementations handle CLONE_SETTLS by reading the TLS value from | ||
| 2584 | * the registers containing the syscall arguments for clone. This doesn't work | ||
| 2585 | * with clone3 since the TLS value is passed in clone_args instead. | ||
| 2586 | */ | ||
| 2587 | #ifndef CONFIG_HAVE_COPY_THREAD_TLS | ||
| 2588 | #error clone3 requires copy_thread_tls support in arch | ||
| 2589 | #endif | ||
| 2590 | |||
| 2581 | noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, | 2591 | noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, |
| 2582 | struct clone_args __user *uargs, | 2592 | struct clone_args __user *uargs, |
| 2583 | size_t usize) | 2593 | size_t usize) |
| @@ -1026,6 +1026,13 @@ static long seccomp_notify_recv(struct seccomp_filter *filter, · 1025 unmodified lines | |||
| 1026 | struct seccomp_notif unotif; | 1026 | struct seccomp_notif unotif; |
| 1027 | ssize_t ret; | 1027 | ssize_t ret; |
| 1028 | 1028 | ||
| 1029 | /* Verify that we're not given garbage to keep struct extensible. */ | ||
| 1030 | ret = check_zeroed_user(buf, sizeof(unotif)); | ||
| 1031 | if (ret < 0) | ||
| 1032 | return ret; | ||
| 1033 | if (!ret) | ||
| 1034 | return -EINVAL; | ||
| 1035 | |||
| 1029 | memset(&unotif, 0, sizeof(unotif)); | 1036 | memset(&unotif, 0, sizeof(unotif)); |
| 1030 | 1037 | ||
| 1031 | ret = down_interruptible(&filter->notif->request); | 1038 | ret = down_interruptible(&filter->notif->request); |
| @@ -554,25 +554,33 @@ static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) · 553 unmodified lines | |||
| 554 | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) | 554 | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) |
| 555 | { | 555 | { |
| 556 | struct signal_struct *sig = tsk->signal; | 556 | struct signal_struct *sig = tsk->signal; |
| 557 | struct taskstats *stats; | 557 | struct taskstats *stats_new, *stats; |
| 558 | 558 | ||
| 559 | if (sig->stats || thread_group_empty(tsk)) | 559 | /* Pairs with smp_store_release() below. */ |
| 560 | goto ret; | 560 | stats = smp_load_acquire(&sig->stats); |
| 561 | if (stats || thread_group_empty(tsk)) | ||
| 562 | return stats; | ||
| 561 | 563 | ||
| 562 | /* No problem if kmem_cache_zalloc() fails */ | 564 | /* No problem if kmem_cache_zalloc() fails */ |
| 563 | stats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); | 565 | stats_new = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); |
| 564 | 566 | ||
| 565 | spin_lock_irq(&tsk->sighand->siglock); | 567 | spin_lock_irq(&tsk->sighand->siglock); |
| 566 | if (!sig->stats) { | 568 | stats = sig->stats; |
| 567 | sig->stats = stats; | 569 | if (!stats) { |
| 568 | stats = NULL; | 570 | /* |
| 571 | * Pairs with smp_store_release() above and order the | ||
| 572 | * kmem_cache_zalloc(). | ||
| 573 | */ | ||
| 574 | smp_store_release(&sig->stats, stats_new); | ||
| 575 | stats = stats_new; | ||
| 576 | stats_new = NULL; | ||
| 569 | } | 577 | } |
| 570 | spin_unlock_irq(&tsk->sighand->siglock); | 578 | spin_unlock_irq(&tsk->sighand->siglock); |
| 571 | 579 | ||
| 572 | if (stats) | 580 | if (stats_new) |
| 573 | kmem_cache_free(taskstats_cache, stats); | 581 | kmem_cache_free(taskstats_cache, stats_new); |
| 574 | ret: | 582 | |
| 575 | return sig->stats; | 583 | return stats; |
| 576 | } | 584 | } |
| 577 | 585 | ||
| 578 | /* Send pid data out on exit */ | 586 | /* Send pid data out on exit */ |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #include "posix-timers.h" | 15 | #include "posix-timers.h" |
| 16 | 16 | ||
| 17 | static void delete_clock(struct kref *kref); | ||
| 18 | |||
| 19 | /* | 17 | /* |
| 20 | * Returns NULL if the posix_clock instance attached to 'fp' is old and stale. | 18 | * Returns NULL if the posix_clock instance attached to 'fp' is old and stale. |
| 21 | */ | 19 | */ |
| @@ -125,7 +123,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp) · 103 unmodified lines | |||
| 125 | err = 0; | 123 | err = 0; |
| 126 | 124 | ||
| 127 | if (!err) { | 125 | if (!err) { |
| 128 | kref_get(&clk->kref); | 126 | get_device(clk->dev); |
| 129 | fp->private_data = clk; | 127 | fp->private_data = clk; |
| 130 | } | 128 | } |
| 131 | out: | 129 | out: |
| @@ -141,7 +139,7 @@ static int posix_clock_release(struct inode *inode, struct file *fp) · 9 unmodified lines | |||
| 141 | if (clk->ops.release) | 139 | if (clk->ops.release) |
| 142 | err = clk->ops.release(clk); | 140 | err = clk->ops.release(clk); |
| 143 | 141 | ||
| 144 | kref_put(&clk->kref, delete_clock); | 142 | put_device(clk->dev); |
| 145 | 143 | ||
| 146 | fp->private_data = NULL; | 144 | fp->private_data = NULL; |
| 147 | 145 | ||
| @@ -161,38 +159,35 @@ static const struct file_operations posix_clock_file_operations = { · 13 unmodified lines | |||
| 161 | #endif | 159 | #endif |
| 162 | }; | 160 | }; |
| 163 | 161 | ||
| 164 | int posix_clock_register(struct posix_clock *clk, dev_t devid) | 162 | int posix_clock_register(struct posix_clock *clk, struct device *dev) |
| 165 | { | 163 | { |
| 166 | int err; | 164 | int err; |
| 167 | 165 | ||
| 168 | kref_init(&clk->kref); | ||
| 169 | init_rwsem(&clk->rwsem); | 166 | init_rwsem(&clk->rwsem); |
| 170 | 167 | ||
| 171 | cdev_init(&clk->cdev, &posix_clock_file_operations); | 168 | cdev_init(&clk->cdev, &posix_clock_file_operations); |
| 169 | err = cdev_device_add(&clk->cdev, dev); | ||
| 170 | if (err) { | ||
| 171 | pr_err("%s unable to add device %d:%d\n", | ||
| 172 | dev_name(dev), MAJOR(dev->devt), MINOR(dev->devt)); | ||
| 173 | return err; | ||
| 174 | } | ||
| 172 | clk->cdev.owner = clk->ops.owner; | 175 | clk->cdev.owner = clk->ops.owner; |
| 173 | err = cdev_add(&clk->cdev, devid, 1); | 176 | clk->dev = dev; |
| 174 | 177 | ||
| 175 | return err; | 178 | return 0; |
| 176 | } | 179 | } |
| 177 | EXPORT_SYMBOL_GPL(posix_clock_register); | 180 | EXPORT_SYMBOL_GPL(posix_clock_register); |
| 178 | 181 | ||
| 179 | static void delete_clock(struct kref *kref) | ||
| 180 | { | ||
| 181 | struct posix_clock *clk = container_of(kref, struct posix_clock, kref); | ||
| 182 | |||
| 183 | if (clk->release) | ||
| 184 | clk->release(clk); | ||
| 185 | } | ||
| 186 | |||
| 187 | void posix_clock_unregister(struct posix_clock *clk) | 182 | void posix_clock_unregister(struct posix_clock *clk) |
| 188 | { | 183 | { |
| 189 | cdev_del(&clk->cdev); | 184 | cdev_device_del(&clk->cdev, clk->dev); |
| 190 | 185 | ||
| 191 | down_write(&clk->rwsem); | 186 | down_write(&clk->rwsem); |
| 192 | clk->zombie = true; | 187 | clk->zombie = true; |
| 193 | up_write(&clk->rwsem); | 188 | up_write(&clk->rwsem); |
| 194 | 189 | ||
| 195 | kref_put(&clk->kref, delete_clock); | 190 | put_device(clk->dev); |
| 196 | } | 191 | } |
| 197 | EXPORT_SYMBOL_GPL(posix_clock_unregister); | 192 | EXPORT_SYMBOL_GPL(posix_clock_unregister); |
| 198 | 193 | ||
| @@ -96,6 +96,20 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, · 95 unmodified lines | |||
| 96 | return 0; | 96 | return 0; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | /* | ||
| 100 | * Not all archs define MCOUNT_INSN_SIZE which is used to look for direct | ||
| 101 | * functions. But those archs currently don't support direct functions | ||
| 102 | * anyway, and ftrace_find_rec_direct() is just a stub for them. | ||
| 103 | * Define MCOUNT_INSN_SIZE to keep those archs compiling. | ||
| 104 | */ | ||
| 105 | #ifndef MCOUNT_INSN_SIZE | ||
| 106 | /* Make sure this only works without direct calls */ | ||
| 107 | # ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS | ||
| 108 | # error MCOUNT_INSN_SIZE not defined with direct calls enabled | ||
| 109 | # endif | ||
| 110 | # define MCOUNT_INSN_SIZE 0 | ||
| 111 | #endif | ||
| 112 | |||
| 99 | int function_graph_enter(unsigned long ret, unsigned long func, | 113 | int function_graph_enter(unsigned long ret, unsigned long func, |
| 100 | unsigned long frame_pointer, unsigned long *retp) | 114 | unsigned long frame_pointer, unsigned long *retp) |
| 101 | { | 115 | { |
| @@ -526,8 +526,7 @@ static int function_stat_show(struct seq_file *m, void *v) · 525 unmodified lines | |||
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 528 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 529 | avg = rec->time; | 529 | avg = div64_ul(rec->time, rec->counter); |
| 530 | do_div(avg, rec->counter); | ||
| 531 | if (tracing_thresh && (avg < tracing_thresh)) | 530 | if (tracing_thresh && (avg < tracing_thresh)) |
| 532 | goto out; | 531 | goto out; |
| 533 | #endif | 532 | #endif |
| @@ -553,7 +552,8 @@ static int function_stat_show(struct seq_file *m, void *v) · 19 unmodified lines | |||
| 553 | * Divide only 1000 for ns^2 -> us^2 conversion. | 552 | * Divide only 1000 for ns^2 -> us^2 conversion. |
| 554 | * trace_print_graph_duration will divide 1000 again. | 553 | * trace_print_graph_duration will divide 1000 again. |
| 555 | */ | 554 | */ |
| 556 | do_div(stddev, rec->counter * (rec->counter - 1) * 1000); | 555 | stddev = div64_ul(stddev, |
| 556 | rec->counter * (rec->counter - 1) * 1000); | ||
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | trace_seq_init(&s); | 559 | trace_seq_init(&s); |
| @@ -195,7 +195,7 @@ static int parse_entry(char *str, struct trace_event_call *call, void **pentry) · 194 unmodified lines | |||
| 195 | unsigned long irq_flags; | 195 | unsigned long irq_flags; |
| 196 | void *entry = NULL; | 196 | void *entry = NULL; |
| 197 | int entry_size; | 197 | int entry_size; |
| 198 | u64 val; | 198 | u64 val = 0; |
| 199 | int len; | 199 | int len; |
| 200 | 200 | ||
| 201 | entry = trace_alloc_entry(call, &entry_size); | 201 | entry = trace_alloc_entry(call, &entry_size); |
| @@ -630,7 +630,7 @@ static void start_wakeup_tracer(struct trace_array *tr) · 629 unmodified lines | |||
| 630 | if (ret) { | 630 | if (ret) { |
| 631 | pr_info("wakeup trace: Couldn't activate tracepoint" | 631 | pr_info("wakeup trace: Couldn't activate tracepoint" |
| 632 | " probe to kernel_sched_migrate_task\n"); | 632 | " probe to kernel_sched_migrate_task\n"); |
| 633 | return; | 633 | goto fail_deprobe_sched_switch; |
| 634 | } | 634 | } |
| 635 | 635 | ||
| 636 | wakeup_reset(tr); | 636 | wakeup_reset(tr); |
| @@ -648,6 +648,8 @@ static void start_wakeup_tracer(struct trace_array *tr) · 11 unmodified lines | |||
| 648 | printk(KERN_ERR "failed to start wakeup tracer\n"); | 648 | printk(KERN_ERR "failed to start wakeup tracer\n"); |
| 649 | 649 | ||
| 650 | return; | 650 | return; |
| 651 | fail_deprobe_sched_switch: | ||
| 652 | unregister_trace_sched_switch(probe_wakeup_sched_switch, NULL); | ||
| 651 | fail_deprobe_wake_new: | 653 | fail_deprobe_wake_new: |
| 652 | unregister_trace_sched_wakeup_new(probe_wakeup, NULL); | 654 | unregister_trace_sched_wakeup_new(probe_wakeup, NULL); |
| 653 | fail_deprobe: | 655 | fail_deprobe: |
| @@ -381,7 +381,7 @@ int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, · 380 unmodified lines | |||
| 381 | int prefix_type, int rowsize, int groupsize, | 381 | int prefix_type, int rowsize, int groupsize, |
| 382 | const void *buf, size_t len, bool ascii) | 382 | const void *buf, size_t len, bool ascii) |
| 383 | { | 383 | { |
| 384 | unsigned int save_len = s->seq.len; | 384 | unsigned int save_len = s->seq.len; |
| 385 | 385 | ||
| 386 | if (s->full) | 386 | if (s->full) |
| 387 | return 0; | 387 | return 0; |
| @@ -283,6 +283,11 @@ static void check_stack(unsigned long ip, unsigned long *stack) · 282 unmodified lines | |||
| 283 | local_irq_restore(flags); | 283 | local_irq_restore(flags); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | /* Some archs may not define MCOUNT_INSN_SIZE */ | ||
| 287 | #ifndef MCOUNT_INSN_SIZE | ||
| 288 | # define MCOUNT_INSN_SIZE 0 | ||
| 289 | #endif | ||
| 290 | |||
| 286 | static void | 291 | static void |
| 287 | stack_trace_call(unsigned long ip, unsigned long parent_ip, | 292 | stack_trace_call(unsigned long ip, unsigned long parent_ip, |
| 288 | struct ftrace_ops *op, struct pt_regs *pt_regs) | 293 | struct ftrace_ops *op, struct pt_regs *pt_regs) |
| @@ -26,6 +26,7 @@ static int __gup_benchmark_ioctl(unsigned int cmd, · 25 unmodified lines | |||
| 26 | unsigned long i, nr_pages, addr, next; | 26 | unsigned long i, nr_pages, addr, next; |
| 27 | int nr; | 27 | int nr; |
| 28 | struct page **pages; | 28 | struct page **pages; |
| 29 | int ret = 0; | ||
| 29 | 30 | ||
| 30 | if (gup->size > ULONG_MAX) | 31 | if (gup->size > ULONG_MAX) |
| 31 | return -EINVAL; | 32 | return -EINVAL; |
| @@ -63,7 +64,9 @@ static int __gup_benchmark_ioctl(unsigned int cmd, · 31 unmodified lines | |||
| 63 | NULL); | 64 | NULL); |
| 64 | break; | 65 | break; |
| 65 | default: | 66 | default: |
| 66 | return -1; | 67 | kvfree(pages); |
| 68 | ret = -EINVAL; | ||
| 69 | goto out; | ||
| 67 | } | 70 | } |
| 68 | 71 | ||
| 69 | if (nr <= 0) | 72 | if (nr <= 0) |
| @@ -85,7 +88,8 @@ static int __gup_benchmark_ioctl(unsigned int cmd, · 15 unmodified lines | |||
| 85 | gup->put_delta_usec = ktime_us_delta(end_time, start_time); | 88 | gup->put_delta_usec = ktime_us_delta(end_time, start_time); |
| 86 | 89 | ||
| 87 | kvfree(pages); | 90 | kvfree(pages); |
| 88 | return 0; | 91 | out: |
| 92 | return ret; | ||
| 89 | } | 93 | } |
| 90 | 94 | ||
| 91 | static long gup_benchmark_ioctl(struct file *filep, unsigned int cmd, | 95 | static long gup_benchmark_ioctl(struct file *filep, unsigned int cmd, |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #include <linux/swapops.h> | 27 | #include <linux/swapops.h> |
| 28 | #include <linux/jhash.h> | 28 | #include <linux/jhash.h> |
| 29 | #include <linux/numa.h> | 29 | #include <linux/numa.h> |
| 30 | #include <linux/llist.h> | ||
| 30 | 31 | ||
| 31 | #include <asm/page.h> | 32 | #include <asm/page.h> |
| 32 | #include <asm/pgtable.h> | 33 | #include <asm/pgtable.h> |
| @@ -1136,7 +1137,7 @@ static inline void ClearPageHugeTemporary(struct page *page) · 1103 unmodified lines | |||
| 1136 | page[2].mapping = NULL; | 1137 | page[2].mapping = NULL; |
| 1137 | } | 1138 | } |
| 1138 | 1139 | ||
| 1139 | void free_huge_page(struct page *page) | 1140 | static void __free_huge_page(struct page *page) |
| 1140 | { | 1141 | { |
| 1141 | /* | 1142 | /* |
| 1142 | * Can't pass hstate in here because it is called from the | 1143 | * Can't pass hstate in here because it is called from the |
| @@ -1199,6 +1200,54 @@ void free_huge_page(struct page *page) · 56 unmodified lines | |||
| 1199 | spin_unlock(&hugetlb_lock); | 1200 | spin_unlock(&hugetlb_lock); |
| 1200 | } | 1201 | } |
| 1201 | 1202 | ||
| 1203 | /* | ||
| 1204 | * As free_huge_page() can be called from a non-task context, we have | ||
| 1205 | * to defer the actual freeing in a workqueue to prevent potential | ||
| 1206 | * hugetlb_lock deadlock. | ||
| 1207 | * | ||
| 1208 | * free_hpage_workfn() locklessly retrieves the linked list of pages to | ||
| 1209 | * be freed and frees them one-by-one. As the page->mapping pointer is | ||
| 1210 | * going to be cleared in __free_huge_page() anyway, it is reused as the | ||
| 1211 | * llist_node structure of a lockless linked list of huge pages to be freed. | ||
| 1212 | */ | ||
| 1213 | static LLIST_HEAD(hpage_freelist); | ||
| 1214 | |||
| 1215 | static void free_hpage_workfn(struct work_struct *work) | ||
| 1216 | { | ||
| 1217 | struct llist_node *node; | ||
| 1218 | struct page *page; | ||
| 1219 | |||
| 1220 | node = llist_del_all(&hpage_freelist); | ||
| 1221 | |||
| 1222 | while (node) { | ||
| 1223 | page = container_of((struct address_space **)node, | ||
| 1224 | struct page, mapping); | ||
| 1225 | node = node->next; | ||
| 1226 | __free_huge_page(page); | ||
| 1227 | } | ||
| 1228 | } | ||
| 1229 | static DECLARE_WORK(free_hpage_work, free_hpage_workfn); | ||
| 1230 | |||
| 1231 | void free_huge_page(struct page *page) | ||
| 1232 | { | ||
| 1233 | /* | ||
| 1234 | * Defer freeing if in non-task context to avoid hugetlb_lock deadlock. | ||
| 1235 | */ | ||
| 1236 | if (!in_task()) { | ||
| 1237 | /* | ||
| 1238 | * Only call schedule_work() if hpage_freelist is previously | ||
| 1239 | * empty. Otherwise, schedule_work() had been called but the | ||
| 1240 | * workfn hasn't retrieved the list yet. | ||
| 1241 | */ | ||
| 1242 | if (llist_add((struct llist_node *)&page->mapping, | ||
| 1243 | &hpage_freelist)) | ||
| 1244 | schedule_work(&free_hpage_work); | ||
| 1245 | return; | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | __free_huge_page(page); | ||
| 1249 | } | ||
| 1250 | |||
| 1202 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) | 1251 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) |
| 1203 | { | 1252 | { |
| 1204 | INIT_LIST_HEAD(&page->lru); | 1253 | INIT_LIST_HEAD(&page->lru); |
| @@ -483,8 +483,9 @@ static void update_pgdat_span(struct pglist_data *pgdat) · 482 unmodified lines | |||
| 483 | pgdat->node_spanned_pages = node_end_pfn - node_start_pfn; | 483 | pgdat->node_spanned_pages = node_end_pfn - node_start_pfn; |
| 484 | } | 484 | } |
| 485 | 485 | ||
| 486 | static void __remove_zone(struct zone *zone, unsigned long start_pfn, | 486 | void __ref remove_pfn_range_from_zone(struct zone *zone, |
| 487 | unsigned long nr_pages) | 487 | unsigned long start_pfn, |
| 488 | unsigned long nr_pages) | ||
| 488 | { | 489 | { |
| 489 | struct pglist_data *pgdat = zone->zone_pgdat; | 490 | struct pglist_data *pgdat = zone->zone_pgdat; |
| 490 | unsigned long flags; | 491 | unsigned long flags; |
| @@ -499,28 +500,30 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn, · 8 unmodified lines | |||
| 499 | return; | 500 | return; |
| 500 | #endif | 501 | #endif |
| 501 | 502 | ||
| 503 | clear_zone_contiguous(zone); | ||
| 504 | |||
| 502 | pgdat_resize_lock(zone->zone_pgdat, &flags); | 505 | pgdat_resize_lock(zone->zone_pgdat, &flags); |
| 503 | shrink_zone_span(zone, start_pfn, start_pfn + nr_pages); | 506 | shrink_zone_span(zone, start_pfn, start_pfn + nr_pages); |
| 504 | update_pgdat_span(pgdat); | 507 | update_pgdat_span(pgdat); |
| 505 | pgdat_resize_unlock(zone->zone_pgdat, &flags); | 508 | pgdat_resize_unlock(zone->zone_pgdat, &flags); |
| 509 | |||
| 510 | set_zone_contiguous(zone); | ||
| 506 | } | 511 | } |
| 507 | 512 | ||
| 508 | static void __remove_section(struct zone *zone, unsigned long pfn, | 513 | static void __remove_section(unsigned long pfn, unsigned long nr_pages, |
| 509 | unsigned long nr_pages, unsigned long map_offset, | 514 | unsigned long map_offset, |
| 510 | struct vmem_altmap *altmap) | 515 | struct vmem_altmap *altmap) |
| 511 | { | 516 | { |
| 512 | struct mem_section *ms = __nr_to_section(pfn_to_section_nr(pfn)); | 517 | struct mem_section *ms = __nr_to_section(pfn_to_section_nr(pfn)); |
| 513 | 518 | ||
| 514 | if (WARN_ON_ONCE(!valid_section(ms))) | 519 | if (WARN_ON_ONCE(!valid_section(ms))) |
| 515 | return; | 520 | return; |
| 516 | 521 | ||
| 517 | __remove_zone(zone, pfn, nr_pages); | ||
| 518 | sparse_remove_section(ms, pfn, nr_pages, map_offset, altmap); | 522 | sparse_remove_section(ms, pfn, nr_pages, map_offset, altmap); |
| 519 | } | 523 | } |
| 520 | 524 | ||
| 521 | /** | 525 | /** |
| 522 | * __remove_pages() - remove sections of pages from a zone | 526 | * __remove_pages() - remove sections of pages |
| 523 | * @zone: zone from which pages need to be removed | ||
| 524 | * @pfn: starting pageframe (must be aligned to start of a section) | 527 | * @pfn: starting pageframe (must be aligned to start of a section) |
| 525 | * @nr_pages: number of pages to remove (must be multiple of section size) | 528 | * @nr_pages: number of pages to remove (must be multiple of section size) |
| 526 | * @altmap: alternative device page map or %NULL if default memmap is used | 529 | * @altmap: alternative device page map or %NULL if default memmap is used |
| @@ -530,16 +533,14 @@ static void __remove_section(struct zone *zone, unsigned long pfn, · 3 unmodified lines | |||
| 530 | * sure that pages are marked reserved and zones are adjust properly by | 533 | * sure that pages are marked reserved and zones are adjust properly by |
| 531 | * calling offline_pages(). | 534 | * calling offline_pages(). |
| 532 | */ | 535 | */ |
| 533 | void __remove_pages(struct zone *zone, unsigned long pfn, | 536 | void __remove_pages(unsigned long pfn, unsigned long nr_pages, |
| 534 | unsigned long nr_pages, struct vmem_altmap *altmap) | 537 | struct vmem_altmap *altmap) |
| 535 | { | 538 | { |
| 536 | unsigned long map_offset = 0; | 539 | unsigned long map_offset = 0; |
| 537 | unsigned long nr, start_sec, end_sec; | 540 | unsigned long nr, start_sec, end_sec; |
| 538 | 541 | ||
| 539 | map_offset = vmem_altmap_offset(altmap); | 542 | map_offset = vmem_altmap_offset(altmap); |
| 540 | 543 | ||
| 541 | clear_zone_contiguous(zone); | ||
| 542 | |||
| 543 | if (check_pfn_span(pfn, nr_pages, "remove")) | 544 | if (check_pfn_span(pfn, nr_pages, "remove")) |
| 544 | return; | 545 | return; |
| 545 | 546 | ||
| @@ -551,13 +552,11 @@ void __remove_pages(struct zone *zone, unsigned long pfn, · 5 unmodified lines | |||
| 551 | cond_resched(); | 552 | cond_resched(); |
| 552 | pfns = min(nr_pages, PAGES_PER_SECTION | 553 | pfns = min(nr_pages, PAGES_PER_SECTION |
| 553 | - (pfn & ~PAGE_SECTION_MASK)); | 554 | - (pfn & ~PAGE_SECTION_MASK)); |
| 554 | __remove_section(zone, pfn, pfns, map_offset, altmap); | 555 | __remove_section(pfn, pfns, map_offset, altmap); |
| 555 | pfn += pfns; | 556 | pfn += pfns; |
| 556 | nr_pages -= pfns; | 557 | nr_pages -= pfns; |
| 557 | map_offset = 0; | 558 | map_offset = 0; |
| 558 | } | 559 | } |
| 559 | |||
| 560 | set_zone_contiguous(zone); | ||
| 561 | } | 560 | } |
| 562 | 561 | ||
| 563 | int set_online_page_callback(online_page_callback_t callback) | 562 | int set_online_page_callback(online_page_callback_t callback) |
| @@ -869,6 +868,7 @@ failed_addition: · 305 unmodified lines | |||
| 869 | (unsigned long long) pfn << PAGE_SHIFT, | 868 | (unsigned long long) pfn << PAGE_SHIFT, |
| 870 | (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1); | 869 | (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1); |
| 871 | memory_notify(MEM_CANCEL_ONLINE, &arg); | 870 | memory_notify(MEM_CANCEL_ONLINE, &arg); |
| 871 | remove_pfn_range_from_zone(zone, pfn, nr_pages); | ||
| 872 | mem_hotplug_done(); | 872 | mem_hotplug_done(); |
| 873 | return ret; | 873 | return ret; |
| 874 | } | 874 | } |
| @@ -1628,6 +1628,7 @@ static int __ref __offline_pages(unsigned long start_pfn, · 753 unmodified lines | |||
| 1628 | writeback_set_ratelimit(); | 1628 | writeback_set_ratelimit(); |
| 1629 | 1629 | ||
| 1630 | memory_notify(MEM_OFFLINE, &arg); | 1630 | memory_notify(MEM_OFFLINE, &arg); |
| 1631 | remove_pfn_range_from_zone(zone, start_pfn, nr_pages); | ||
| 1631 | mem_hotplug_done(); | 1632 | mem_hotplug_done(); |
| 1632 | return 0; | 1633 | return 0; |
| 1633 | 1634 | ||
| @@ -120,7 +120,7 @@ void memunmap_pages(struct dev_pagemap *pgmap) · 119 unmodified lines | |||
| 120 | 120 | ||
| 121 | mem_hotplug_begin(); | 121 | mem_hotplug_begin(); |
| 122 | if (pgmap->type == MEMORY_DEVICE_PRIVATE) { | 122 | if (pgmap->type == MEMORY_DEVICE_PRIVATE) { |
| 123 | __remove_pages(page_zone(first_page), PHYS_PFN(res->start), | 123 | __remove_pages(PHYS_PFN(res->start), |
| 124 | PHYS_PFN(resource_size(res)), NULL); | 124 | PHYS_PFN(resource_size(res)), NULL); |
| 125 | } else { | 125 | } else { |
| 126 | arch_remove_memory(nid, res->start, resource_size(res), | 126 | arch_remove_memory(nid, res->start, resource_size(res), |
| @@ -1512,9 +1512,11 @@ static int do_move_pages_to_node(struct mm_struct *mm, · 1511 unmodified lines | |||
| 1512 | /* | 1512 | /* |
| 1513 | * Resolves the given address to a struct page, isolates it from the LRU and | 1513 | * Resolves the given address to a struct page, isolates it from the LRU and |
| 1514 | * puts it to the given pagelist. | 1514 | * puts it to the given pagelist. |
| 1515 | * Returns -errno if the page cannot be found/isolated or 0 when it has been | 1515 | * Returns: |
| 1516 | * queued or the page doesn't need to be migrated because it is already on | 1516 | * errno - if the page cannot be found/isolated |
| 1517 | * the target node | 1517 | * 0 - when it doesn't have to be migrated because it is already on the |
| 1518 | * target node | ||
| 1519 | * 1 - when it has been queued | ||
| 1518 | */ | 1520 | */ |
| 1519 | static int add_page_for_migration(struct mm_struct *mm, unsigned long addr, | 1521 | static int add_page_for_migration(struct mm_struct *mm, unsigned long addr, |
| 1520 | int node, struct list_head *pagelist, bool migrate_all) | 1522 | int node, struct list_head *pagelist, bool migrate_all) |
| @@ -1553,7 +1555,7 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr, · 32 unmodified lines | |||
| 1553 | if (PageHuge(page)) { | 1555 | if (PageHuge(page)) { |
| 1554 | if (PageHead(page)) { | 1556 | if (PageHead(page)) { |
| 1555 | isolate_huge_page(page, pagelist); | 1557 | isolate_huge_page(page, pagelist); |
| 1556 | err = 0; | 1558 | err = 1; |
| 1557 | } | 1559 | } |
| 1558 | } else { | 1560 | } else { |
| 1559 | struct page *head; | 1561 | struct page *head; |
| @@ -1563,7 +1565,7 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr, · 3 unmodified lines | |||
| 1563 | if (err) | 1565 | if (err) |
| 1564 | goto out_putpage; | 1566 | goto out_putpage; |
| 1565 | 1567 | ||
| 1566 | err = 0; | 1568 | err = 1; |
| 1567 | list_add_tail(&head->lru, pagelist); | 1569 | list_add_tail(&head->lru, pagelist); |
| 1568 | mod_node_page_state(page_pgdat(head), | 1570 | mod_node_page_state(page_pgdat(head), |
| 1569 | NR_ISOLATED_ANON + page_is_file_cache(head), | 1571 | NR_ISOLATED_ANON + page_is_file_cache(head), |
| @@ -1640,8 +1642,17 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, · 70 unmodified lines | |||
| 1640 | */ | 1642 | */ |
| 1641 | err = add_page_for_migration(mm, addr, current_node, | 1643 | err = add_page_for_migration(mm, addr, current_node, |
| 1642 | &pagelist, flags & MPOL_MF_MOVE_ALL); | 1644 | &pagelist, flags & MPOL_MF_MOVE_ALL); |
| 1643 | if (!err) | 1645 | |
| 1646 | if (!err) { | ||
| 1647 | /* The page is already on the target node */ | ||
| 1648 | err = store_status(status, i, current_node, 1); | ||
| 1649 | if (err) | ||
| 1650 | goto out_flush; | ||
| 1644 | continue; | 1651 | continue; |
| 1652 | } else if (err > 0) { | ||
| 1653 | /* The page is successfully queued for migration */ | ||
| 1654 | continue; | ||
| 1655 | } | ||
| 1645 | 1656 | ||
| 1646 | err = store_status(status, i, err, 1); | 1657 | err = store_status(status, i, err, 1); |
| 1647 | if (err) | 1658 | if (err) |
| @@ -90,12 +90,6 @@ static void unmap_region(struct mm_struct *mm, · 89 unmodified lines | |||
| 90 | * MAP_PRIVATE r: (no) no r: (yes) yes r: (no) yes r: (no) yes | 90 | * MAP_PRIVATE r: (no) no r: (yes) yes r: (no) yes r: (no) yes |
| 91 | * w: (no) no w: (no) no w: (copy) copy w: (no) no | 91 | * w: (no) no w: (no) no w: (copy) copy w: (no) no |
| 92 | * x: (no) no x: (no) yes x: (no) yes x: (yes) yes | 92 | * x: (no) no x: (no) yes x: (no) yes x: (yes) yes |
| 93 | * | ||
| 94 | * On arm64, PROT_EXEC has the following behaviour for both MAP_SHARED and | ||
| 95 | * MAP_PRIVATE: | ||
| 96 | * r: (no) no | ||
| 97 | * w: (no) no | ||
| 98 | * x: (yes) yes | ||
| 99 | */ | 93 | */ |
| 100 | pgprot_t protection_map[16] __ro_after_init = { | 94 | pgprot_t protection_map[16] __ro_after_init = { |
| 101 | __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, | 95 | __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, |
| @@ -890,7 +890,7 @@ static void __oom_kill_process(struct task_struct *victim, const char *message) · 889 unmodified lines | |||
| 890 | K(get_mm_counter(mm, MM_FILEPAGES)), | 890 | K(get_mm_counter(mm, MM_FILEPAGES)), |
| 891 | K(get_mm_counter(mm, MM_SHMEMPAGES)), | 891 | K(get_mm_counter(mm, MM_SHMEMPAGES)), |
| 892 | from_kuid(&init_user_ns, task_uid(victim)), | 892 | from_kuid(&init_user_ns, task_uid(victim)), |
| 893 | mm_pgtables_bytes(mm), victim->signal->oom_score_adj); | 893 | mm_pgtables_bytes(mm) >> 10, victim->signal->oom_score_adj); |
| 894 | task_unlock(victim); | 894 | task_unlock(victim); |
| 895 | 895 | ||
| 896 | /* | 896 | /* |
| @@ -2069,6 +2069,11 @@ static int zs_page_migrate(struct address_space *mapping, struct page *newpage, · 2068 unmodified lines | |||
| 2069 | zs_pool_dec_isolated(pool); | 2069 | zs_pool_dec_isolated(pool); |
| 2070 | } | 2070 | } |
| 2071 | 2071 | ||
| 2072 | if (page_zone(newpage) != page_zone(page)) { | ||
| 2073 | dec_zone_page_state(page, NR_ZSPAGES); | ||
| 2074 | inc_zone_page_state(newpage, NR_ZSPAGES); | ||
| 2075 | } | ||
| 2076 | |||
| 2072 | reset_page(page); | 2077 | reset_page(page); |
| 2073 | put_page(page); | 2078 | put_page(page); |
| 2074 | page = newpage; | 2079 | page = newpage; |
| @@ -126,6 +126,7 @@ int vlan_check_real_dev(struct net_device *real_dev, · 125 unmodified lines | |||
| 126 | void vlan_setup(struct net_device *dev); | 126 | void vlan_setup(struct net_device *dev); |
| 127 | int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack); | 127 | int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack); |
| 128 | void unregister_vlan_dev(struct net_device *dev, struct list_head *head); | 128 | void unregister_vlan_dev(struct net_device *dev, struct list_head *head); |
| 129 | void vlan_dev_uninit(struct net_device *dev); | ||
| 129 | bool vlan_dev_inherit_address(struct net_device *dev, | 130 | bool vlan_dev_inherit_address(struct net_device *dev, |
| 130 | struct net_device *real_dev); | 131 | struct net_device *real_dev); |
| 131 | 132 | ||
| @@ -586,7 +586,8 @@ static int vlan_dev_init(struct net_device *dev) · 585 unmodified lines | |||
| 586 | return 0; | 586 | return 0; |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | static void vlan_dev_uninit(struct net_device *dev) | 589 | /* Note: this function might be called multiple times for the same device. */ |
| 590 | void vlan_dev_uninit(struct net_device *dev) | ||
| 590 | { | 591 | { |
| 591 | struct vlan_priority_tci_mapping *pm; | 592 | struct vlan_priority_tci_mapping *pm; |
| 592 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 593 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); |
| @@ -108,11 +108,13 @@ static int vlan_changelink(struct net_device *dev, struct nlattr *tb[], · 107 unmodified lines | |||
| 108 | struct ifla_vlan_flags *flags; | 108 | struct ifla_vlan_flags *flags; |
| 109 | struct ifla_vlan_qos_mapping *m; | 109 | struct ifla_vlan_qos_mapping *m; |
| 110 | struct nlattr *attr; | 110 | struct nlattr *attr; |
| 111 | int rem; | 111 | int rem, err; |
| 112 | 112 | ||
| 113 | if (data[IFLA_VLAN_FLAGS]) { | 113 | if (data[IFLA_VLAN_FLAGS]) { |
| 114 | flags = nla_data(data[IFLA_VLAN_FLAGS]); | 114 | flags = nla_data(data[IFLA_VLAN_FLAGS]); |
| 115 | vlan_dev_change_flags(dev, flags->flags, flags->mask); | 115 | err = vlan_dev_change_flags(dev, flags->flags, flags->mask); |
| 116 | if (err) | ||
| 117 | return err; | ||
| 116 | } | 118 | } |
| 117 | if (data[IFLA_VLAN_INGRESS_QOS]) { | 119 | if (data[IFLA_VLAN_INGRESS_QOS]) { |
| 118 | nla_for_each_nested(attr, data[IFLA_VLAN_INGRESS_QOS], rem) { | 120 | nla_for_each_nested(attr, data[IFLA_VLAN_INGRESS_QOS], rem) { |
| @@ -123,7 +125,9 @@ static int vlan_changelink(struct net_device *dev, struct nlattr *tb[], · 4 unmodified lines | |||
| 123 | if (data[IFLA_VLAN_EGRESS_QOS]) { | 125 | if (data[IFLA_VLAN_EGRESS_QOS]) { |
| 124 | nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) { | 126 | nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) { |
| 125 | m = nla_data(attr); | 127 | m = nla_data(attr); |
| 126 | vlan_dev_set_egress_priority(dev, m->from, m->to); | 128 | err = vlan_dev_set_egress_priority(dev, m->from, m->to); |
| 129 | if (err) | ||
| 130 | return err; | ||
| 127 | } | 131 | } |
| 128 | } | 132 | } |
| 129 | return 0; | 133 | return 0; |
| @@ -179,10 +183,11 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev, · 49 unmodified lines | |||
| 179 | return -EINVAL; | 183 | return -EINVAL; |
| 180 | 184 | ||
| 181 | err = vlan_changelink(dev, tb, data, extack); | 185 | err = vlan_changelink(dev, tb, data, extack); |
| 182 | if (err < 0) | 186 | if (!err) |
| 183 | return err; | 187 | err = register_vlan_dev(dev, extack); |
| 184 | 188 | if (err) | |
| 185 | return register_vlan_dev(dev, extack); | 189 | vlan_dev_uninit(dev); |
| 190 | return err; | ||
| 186 | } | 191 | } |
| 187 | 192 | ||
| 188 | static inline size_t vlan_qos_map_size(unsigned int n) | 193 | static inline size_t vlan_qos_map_size(unsigned int n) |
| @@ -22,7 +22,8 @@ · 21 unmodified lines | |||
| 22 | #endif | 22 | #endif |
| 23 | 23 | ||
| 24 | static void fake_update_pmtu(struct dst_entry *dst, struct sock *sk, | 24 | static void fake_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 25 | struct sk_buff *skb, u32 mtu) | 25 | struct sk_buff *skb, u32 mtu, |
| 26 | bool confirm_neigh) | ||
| 26 | { | 27 | { |
| 27 | } | 28 | } |
| 28 | 29 | ||
| @@ -1867,7 +1867,7 @@ static int ebt_buf_count(struct ebt_entries_buf_state *state, unsigned int sz) · 1866 unmodified lines | |||
| 1867 | } | 1867 | } |
| 1868 | 1868 | ||
| 1869 | static int ebt_buf_add(struct ebt_entries_buf_state *state, | 1869 | static int ebt_buf_add(struct ebt_entries_buf_state *state, |
| 1870 | void *data, unsigned int sz) | 1870 | const void *data, unsigned int sz) |
| 1871 | { | 1871 | { |
| 1872 | if (state->buf_kern_start == NULL) | 1872 | if (state->buf_kern_start == NULL) |
| 1873 | goto count_only; | 1873 | goto count_only; |
| @@ -1901,7 +1901,7 @@ enum compat_mwt { · 27 unmodified lines | |||
| 1901 | EBT_COMPAT_TARGET, | 1901 | EBT_COMPAT_TARGET, |
| 1902 | }; | 1902 | }; |
| 1903 | 1903 | ||
| 1904 | static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt, | 1904 | static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt, |
| 1905 | enum compat_mwt compat_mwt, | 1905 | enum compat_mwt compat_mwt, |
| 1906 | struct ebt_entries_buf_state *state, | 1906 | struct ebt_entries_buf_state *state, |
| 1907 | const unsigned char *base) | 1907 | const unsigned char *base) |
| @@ -1979,22 +1979,23 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt, · 71 unmodified lines | |||
| 1979 | /* return size of all matches, watchers or target, including necessary | 1979 | /* return size of all matches, watchers or target, including necessary |
| 1980 | * alignment and padding. | 1980 | * alignment and padding. |
| 1981 | */ | 1981 | */ |
| 1982 | static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32, | 1982 | static int ebt_size_mwt(const struct compat_ebt_entry_mwt *match32, |
| 1983 | unsigned int size_left, enum compat_mwt type, | 1983 | unsigned int size_left, enum compat_mwt type, |
| 1984 | struct ebt_entries_buf_state *state, const void *base) | 1984 | struct ebt_entries_buf_state *state, const void *base) |
| 1985 | { | 1985 | { |
| 1986 | const char *buf = (const char *)match32; | ||
| 1986 | int growth = 0; | 1987 | int growth = 0; |
| 1987 | char *buf; | ||
| 1988 | 1988 | ||
| 1989 | if (size_left == 0) | 1989 | if (size_left == 0) |
| 1990 | return 0; | 1990 | return 0; |
| 1991 | 1991 | ||
| 1992 | buf = (char *) match32; | 1992 | do { |
| 1993 | |||
| 1994 | while (size_left >= sizeof(*match32)) { | ||
| 1995 | struct ebt_entry_match *match_kern; | 1993 | struct ebt_entry_match *match_kern; |
| 1996 | int ret; | 1994 | int ret; |
| 1997 | 1995 | ||
| 1996 | if (size_left < sizeof(*match32)) | ||
| 1997 | return -EINVAL; | ||
| 1998 | |||
| 1998 | match_kern = (struct ebt_entry_match *) state->buf_kern_start; | 1999 | match_kern = (struct ebt_entry_match *) state->buf_kern_start; |
| 1999 | if (match_kern) { | 2000 | if (match_kern) { |
| 2000 | char *tmp; | 2001 | char *tmp; |
| @@ -2031,22 +2032,18 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32, · 30 unmodified lines | |||
| 2031 | if (match_kern) | 2032 | if (match_kern) |
| 2032 | match_kern->match_size = ret; | 2033 | match_kern->match_size = ret; |
| 2033 | 2034 | ||
| 2034 | /* rule should have no remaining data after target */ | ||
| 2035 | if (type == EBT_COMPAT_TARGET && size_left) | ||
| 2036 | return -EINVAL; | ||
| 2037 | |||
| 2038 | match32 = (struct compat_ebt_entry_mwt *) buf; | 2035 | match32 = (struct compat_ebt_entry_mwt *) buf; |
| 2039 | } | 2036 | } while (size_left); |
| 2040 | 2037 | ||
| 2041 | return growth; | 2038 | return growth; |
| 2042 | } | 2039 | } |
| 2043 | 2040 | ||
| 2044 | /* called for all ebt_entry structures. */ | 2041 | /* called for all ebt_entry structures. */ |
| 2045 | static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base, | 2042 | static int size_entry_mwt(const struct ebt_entry *entry, const unsigned char *base, |
| 2046 | unsigned int *total, | 2043 | unsigned int *total, |
| 2047 | struct ebt_entries_buf_state *state) | 2044 | struct ebt_entries_buf_state *state) |
| 2048 | { | 2045 | { |
| 2049 | unsigned int i, j, startoff, new_offset = 0; | 2046 | unsigned int i, j, startoff, next_expected_off, new_offset = 0; |
| 2050 | /* stores match/watchers/targets & offset of next struct ebt_entry: */ | 2047 | /* stores match/watchers/targets & offset of next struct ebt_entry: */ |
| 2051 | unsigned int offsets[4]; | 2048 | unsigned int offsets[4]; |
| 2052 | unsigned int *offsets_update = NULL; | 2049 | unsigned int *offsets_update = NULL; |
| @@ -2132,11 +2129,13 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base, · 79 unmodified lines | |||
| 2132 | return ret; | 2129 | return ret; |
| 2133 | } | 2130 | } |
| 2134 | 2131 | ||
| 2135 | startoff = state->buf_user_offset - startoff; | 2132 | next_expected_off = state->buf_user_offset - startoff; |
| 2133 | if (next_expected_off != entry->next_offset) | ||
| 2134 | return -EINVAL; | ||
| 2136 | 2135 | ||
| 2137 | if (WARN_ON(*total < startoff)) | 2136 | if (*total < entry->next_offset) |
| 2138 | return -EINVAL; | 2137 | return -EINVAL; |
| 2139 | *total -= startoff; | 2138 | *total -= entry->next_offset; |
| 2140 | return 0; | 2139 | return 0; |
| 2141 | } | 2140 | } |
| 2142 | 2141 | ||
| @@ -110,7 +110,8 @@ static void dn_dst_ifdown(struct dst_entry *, struct net_device *dev, int how); · 109 unmodified lines | |||
| 110 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); | 110 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); |
| 111 | static void dn_dst_link_failure(struct sk_buff *); | 111 | static void dn_dst_link_failure(struct sk_buff *); |
| 112 | static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk, | 112 | static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 113 | struct sk_buff *skb , u32 mtu); | 113 | struct sk_buff *skb , u32 mtu, |
| 114 | bool confirm_neigh); | ||
| 114 | static void dn_dst_redirect(struct dst_entry *dst, struct sock *sk, | 115 | static void dn_dst_redirect(struct dst_entry *dst, struct sock *sk, |
| 115 | struct sk_buff *skb); | 116 | struct sk_buff *skb); |
| 116 | static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, | 117 | static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, |
| @@ -251,7 +252,8 @@ static int dn_dst_gc(struct dst_ops *ops) · 134 unmodified lines | |||
| 251 | * advertise to the other end). | 252 | * advertise to the other end). |
| 252 | */ | 253 | */ |
| 253 | static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk, | 254 | static void dn_dst_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 254 | struct sk_buff *skb, u32 mtu) | 255 | struct sk_buff *skb, u32 mtu, |
| 256 | bool confirm_neigh) | ||
| 255 | { | 257 | { |
| 256 | struct dn_route *rt = (struct dn_route *) dst; | 258 | struct dn_route *rt = (struct dn_route *) dst; |
| 257 | struct neighbour *n = rt->n; | 259 | struct neighbour *n = rt->n; |
| @@ -20,6 +20,8 @@ · 19 unmodified lines | |||
| 20 | #include "hsr_main.h" | 20 | #include "hsr_main.h" |
| 21 | #include "hsr_framereg.h" | 21 | #include "hsr_framereg.h" |
| 22 | 22 | ||
| 23 | static struct dentry *hsr_debugfs_root_dir; | ||
| 24 | |||
| 23 | static void print_mac_address(struct seq_file *sfp, unsigned char *mac) | 25 | static void print_mac_address(struct seq_file *sfp, unsigned char *mac) |
| 24 | { | 26 | { |
| 25 | seq_printf(sfp, "%02x:%02x:%02x:%02x:%02x:%02x:", | 27 | seq_printf(sfp, "%02x:%02x:%02x:%02x:%02x:%02x:", |
| @@ -63,8 +65,20 @@ hsr_node_table_open(struct inode *inode, struct file *filp) · 37 unmodified lines | |||
| 63 | return single_open(filp, hsr_node_table_show, inode->i_private); | 65 | return single_open(filp, hsr_node_table_show, inode->i_private); |
| 64 | } | 66 | } |
| 65 | 67 | ||
| 68 | void hsr_debugfs_rename(struct net_device *dev) | ||
| 69 | { | ||
| 70 | struct hsr_priv *priv = netdev_priv(dev); | ||
| 71 | struct dentry *d; | ||
| 72 | |||
| 73 | d = debugfs_rename(hsr_debugfs_root_dir, priv->node_tbl_root, | ||
| 74 | hsr_debugfs_root_dir, dev->name); | ||
| 75 | if (IS_ERR(d)) | ||
| 76 | netdev_warn(dev, "failed to rename\n"); | ||
| 77 | else | ||
| 78 | priv->node_tbl_root = d; | ||
| 79 | } | ||
| 80 | |||
| 66 | static const struct file_operations hsr_fops = { | 81 | static const struct file_operations hsr_fops = { |
| 67 | .owner = THIS_MODULE, | ||
| 68 | .open = hsr_node_table_open, | 82 | .open = hsr_node_table_open, |
| 69 | .read = seq_read, | 83 | .read = seq_read, |
| 70 | .llseek = seq_lseek, | 84 | .llseek = seq_lseek, |
| @@ -78,15 +92,14 @@ static const struct file_operations hsr_fops = { · 7 unmodified lines | |||
| 78 | * When debugfs is configured this routine sets up the node_table file per | 92 | * When debugfs is configured this routine sets up the node_table file per |
| 79 | * hsr device for dumping the node_table entries | 93 | * hsr device for dumping the node_table entries |
| 80 | */ | 94 | */ |
| 81 | int hsr_debugfs_init(struct hsr_priv *priv, struct net_device *hsr_dev) | 95 | void hsr_debugfs_init(struct hsr_priv *priv, struct net_device *hsr_dev) |
| 82 | { | 96 | { |
| 83 | int rc = -1; | ||
| 84 | struct dentry *de = NULL; | 97 | struct dentry *de = NULL; |
| 85 | 98 | ||
| 86 | de = debugfs_create_dir(hsr_dev->name, NULL); | 99 | de = debugfs_create_dir(hsr_dev->name, hsr_debugfs_root_dir); |
| 87 | if (!de) { | 100 | if (IS_ERR(de)) { |
| 88 | pr_err("Cannot create hsr debugfs root\n"); | 101 | pr_err("Cannot create hsr debugfs directory\n"); |
| 89 | return rc; | 102 | return; |
| 90 | } | 103 | } |
| 91 | 104 | ||
| 92 | priv->node_tbl_root = de; | 105 | priv->node_tbl_root = de; |
| @@ -94,13 +107,13 @@ int hsr_debugfs_init(struct hsr_priv *priv, struct net_device *hsr_dev) · 1 unmodified line | |||
| 94 | de = debugfs_create_file("node_table", S_IFREG | 0444, | 107 | de = debugfs_create_file("node_table", S_IFREG | 0444, |
| 95 | priv->node_tbl_root, priv, | 108 | priv->node_tbl_root, priv, |
| 96 | &hsr_fops); | 109 | &hsr_fops); |
| 97 | if (!de) { | 110 | if (IS_ERR(de)) { |
| 98 | pr_err("Cannot create hsr node_table directory\n"); | 111 | pr_err("Cannot create hsr node_table file\n"); |
| 99 | return rc; | 112 | debugfs_remove(priv->node_tbl_root); |
| 113 | priv->node_tbl_root = NULL; | ||
| 114 | return; | ||
| 100 | } | 115 | } |
| 101 | priv->node_tbl_file = de; | 116 | priv->node_tbl_file = de; |
| 102 | |||
| 103 | return 0; | ||
| 104 | } | 117 | } |
| 105 | 118 | ||
| 106 | /* hsr_debugfs_term - Tear down debugfs intrastructure | 119 | /* hsr_debugfs_term - Tear down debugfs intrastructure |
| @@ -117,3 +130,18 @@ hsr_debugfs_term(struct hsr_priv *priv) · 10 unmodified lines | |||
| 117 | debugfs_remove(priv->node_tbl_root); | 130 | debugfs_remove(priv->node_tbl_root); |
| 118 | priv->node_tbl_root = NULL; | 131 | priv->node_tbl_root = NULL; |
| 119 | } | 132 | } |
| 133 | |||
| 134 | void hsr_debugfs_create_root(void) | ||
| 135 | { | ||
| 136 | hsr_debugfs_root_dir = debugfs_create_dir("hsr", NULL); | ||
| 137 | if (IS_ERR(hsr_debugfs_root_dir)) { | ||
| 138 | pr_err("Cannot create hsr debugfs root directory\n"); | ||
| 139 | hsr_debugfs_root_dir = NULL; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | void hsr_debugfs_remove_root(void) | ||
| 144 | { | ||
| 145 | /* debugfs_remove() internally checks NULL and ERROR */ | ||
| 146 | debugfs_remove(hsr_debugfs_root_dir); | ||
| 147 | } | ||
| @@ -272,6 +272,8 @@ static void send_hsr_supervision_frame(struct hsr_port *master, · 271 unmodified lines | |||
| 272 | skb->dev->dev_addr, skb->len) <= 0) | 272 | skb->dev->dev_addr, skb->len) <= 0) |
| 273 | goto out; | 273 | goto out; |
| 274 | skb_reset_mac_header(skb); | 274 | skb_reset_mac_header(skb); |
| 275 | skb_reset_network_header(skb); | ||
| 276 | skb_reset_transport_header(skb); | ||
| 275 | 277 | ||
| 276 | if (hsr_ver > 0) { | 278 | if (hsr_ver > 0) { |
| 277 | hsr_tag = skb_put(skb, sizeof(struct hsr_tag)); | 279 | hsr_tag = skb_put(skb, sizeof(struct hsr_tag)); |
| @@ -368,7 +370,7 @@ static void hsr_dev_destroy(struct net_device *hsr_dev) · 90 unmodified lines | |||
| 368 | del_timer_sync(&hsr->prune_timer); | 370 | del_timer_sync(&hsr->prune_timer); |
| 369 | del_timer_sync(&hsr->announce_timer); | 371 | del_timer_sync(&hsr->announce_timer); |
| 370 | 372 | ||
| 371 | hsr_del_self_node(&hsr->self_node_db); | 373 | hsr_del_self_node(hsr); |
| 372 | hsr_del_nodes(&hsr->node_db); | 374 | hsr_del_nodes(&hsr->node_db); |
| 373 | } | 375 | } |
| 374 | 376 | ||
| @@ -440,11 +442,12 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], · 65 unmodified lines | |||
| 440 | INIT_LIST_HEAD(&hsr->ports); | 442 | INIT_LIST_HEAD(&hsr->ports); |
| 441 | INIT_LIST_HEAD(&hsr->node_db); | 443 | INIT_LIST_HEAD(&hsr->node_db); |
| 442 | INIT_LIST_HEAD(&hsr->self_node_db); | 444 | INIT_LIST_HEAD(&hsr->self_node_db); |
| 445 | spin_lock_init(&hsr->list_lock); | ||
| 443 | 446 | ||
| 444 | ether_addr_copy(hsr_dev->dev_addr, slave[0]->dev_addr); | 447 | ether_addr_copy(hsr_dev->dev_addr, slave[0]->dev_addr); |
| 445 | 448 | ||
| 446 | /* Make sure we recognize frames from ourselves in hsr_rcv() */ | 449 | /* Make sure we recognize frames from ourselves in hsr_rcv() */ |
| 447 | res = hsr_create_self_node(&hsr->self_node_db, hsr_dev->dev_addr, | 450 | res = hsr_create_self_node(hsr, hsr_dev->dev_addr, |
| 448 | slave[1]->dev_addr); | 451 | slave[1]->dev_addr); |
| 449 | if (res < 0) | 452 | if (res < 0) |
| 450 | return res; | 453 | return res; |
| @@ -477,31 +480,32 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], · 26 unmodified lines | |||
| 477 | 480 | ||
| 478 | res = hsr_add_port(hsr, hsr_dev, HSR_PT_MASTER); | 481 | res = hsr_add_port(hsr, hsr_dev, HSR_PT_MASTER); |
| 479 | if (res) | 482 | if (res) |
| 480 | goto err_add_port; | 483 | goto err_add_master; |
| 481 | 484 | ||
| 482 | res = register_netdevice(hsr_dev); | 485 | res = register_netdevice(hsr_dev); |
| 483 | if (res) | 486 | if (res) |
| 484 | goto fail; | 487 | goto err_unregister; |
| 485 | 488 | ||
| 486 | res = hsr_add_port(hsr, slave[0], HSR_PT_SLAVE_A); | 489 | res = hsr_add_port(hsr, slave[0], HSR_PT_SLAVE_A); |
| 487 | if (res) | 490 | if (res) |
| 488 | goto fail; | 491 | goto err_add_slaves; |
| 492 | |||
| 489 | res = hsr_add_port(hsr, slave[1], HSR_PT_SLAVE_B); | 493 | res = hsr_add_port(hsr, slave[1], HSR_PT_SLAVE_B); |
| 490 | if (res) | 494 | if (res) |
| 491 | goto fail; | 495 | goto err_add_slaves; |
| 492 | 496 | ||
| 497 | hsr_debugfs_init(hsr, hsr_dev); | ||
| 493 | mod_timer(&hsr->prune_timer, jiffies + msecs_to_jiffies(PRUNE_PERIOD)); | 498 | mod_timer(&hsr->prune_timer, jiffies + msecs_to_jiffies(PRUNE_PERIOD)); |
| 494 | res = hsr_debugfs_init(hsr, hsr_dev); | ||
| 495 | if (res) | ||
| 496 | goto fail; | ||
| 497 | 499 | ||
| 498 | return 0; | 500 | return 0; |
| 499 | 501 | ||
| 500 | fail: | 502 | err_add_slaves: |
| 503 | unregister_netdevice(hsr_dev); | ||
| 504 | err_unregister: | ||
| 501 | list_for_each_entry_safe(port, tmp, &hsr->ports, port_list) | 505 | list_for_each_entry_safe(port, tmp, &hsr->ports, port_list) |
| 502 | hsr_del_port(port); | 506 | hsr_del_port(port); |
| 503 | err_add_port: | 507 | err_add_master: |
| 504 | hsr_del_self_node(&hsr->self_node_db); | 508 | hsr_del_self_node(hsr); |
| 505 | 509 | ||
| 506 | return res; | 510 | return res; |
| 507 | } | 511 | } |
| @@ -75,10 +75,11 @@ static struct hsr_node *find_node_by_addr_A(struct list_head *node_db, · 74 unmodified lines | |||
| 75 | /* Helper for device init; the self_node_db is used in hsr_rcv() to recognize | 75 | /* Helper for device init; the self_node_db is used in hsr_rcv() to recognize |
| 76 | * frames from self that's been looped over the HSR ring. | 76 | * frames from self that's been looped over the HSR ring. |
| 77 | */ | 77 | */ |
| 78 | int hsr_create_self_node(struct list_head *self_node_db, | 78 | int hsr_create_self_node(struct hsr_priv *hsr, |
| 79 | unsigned char addr_a[ETH_ALEN], | 79 | unsigned char addr_a[ETH_ALEN], |
| 80 | unsigned char addr_b[ETH_ALEN]) | 80 | unsigned char addr_b[ETH_ALEN]) |
| 81 | { | 81 | { |
| 82 | struct list_head *self_node_db = &hsr->self_node_db; | ||
| 82 | struct hsr_node *node, *oldnode; | 83 | struct hsr_node *node, *oldnode; |
| 83 | 84 | ||
| 84 | node = kmalloc(sizeof(*node), GFP_KERNEL); | 85 | node = kmalloc(sizeof(*node), GFP_KERNEL); |
| @@ -88,33 +89,33 @@ int hsr_create_self_node(struct list_head *self_node_db, · 3 unmodified lines | |||
| 88 | ether_addr_copy(node->macaddress_A, addr_a); | 89 | ether_addr_copy(node->macaddress_A, addr_a); |
| 89 | ether_addr_copy(node->macaddress_B, addr_b); | 90 | ether_addr_copy(node->macaddress_B, addr_b); |
| 90 | 91 | ||
| 91 | rcu_read_lock(); | 92 | spin_lock_bh(&hsr->list_lock); |
| 92 | oldnode = list_first_or_null_rcu(self_node_db, | 93 | oldnode = list_first_or_null_rcu(self_node_db, |
| 93 | struct hsr_node, mac_list); | 94 | struct hsr_node, mac_list); |
| 94 | if (oldnode) { | 95 | if (oldnode) { |
| 95 | list_replace_rcu(&oldnode->mac_list, &node->mac_list); | 96 | list_replace_rcu(&oldnode->mac_list, &node->mac_list); |
| 96 | rcu_read_unlock(); | 97 | spin_unlock_bh(&hsr->list_lock); |
| 97 | synchronize_rcu(); | 98 | kfree_rcu(oldnode, rcu_head); |
| 98 | kfree(oldnode); | ||
| 99 | } else { | 99 | } else { |
| 100 | rcu_read_unlock(); | ||
| 101 | list_add_tail_rcu(&node->mac_list, self_node_db); | 100 | list_add_tail_rcu(&node->mac_list, self_node_db); |
| 101 | spin_unlock_bh(&hsr->list_lock); | ||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | return 0; | 104 | return 0; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | void hsr_del_self_node(struct list_head *self_node_db) | 107 | void hsr_del_self_node(struct hsr_priv *hsr) |
| 108 | { | 108 | { |
| 109 | struct list_head *self_node_db = &hsr->self_node_db; | ||
| 109 | struct hsr_node *node; | 110 | struct hsr_node *node; |
| 110 | 111 | ||
| 111 | rcu_read_lock(); | 112 | spin_lock_bh(&hsr->list_lock); |
| 112 | node = list_first_or_null_rcu(self_node_db, struct hsr_node, mac_list); | 113 | node = list_first_or_null_rcu(self_node_db, struct hsr_node, mac_list); |
| 113 | rcu_read_unlock(); | ||
| 114 | if (node) { | 114 | if (node) { |
| 115 | list_del_rcu(&node->mac_list); | 115 | list_del_rcu(&node->mac_list); |
| 116 | kfree(node); | 116 | kfree_rcu(node, rcu_head); |
| 117 | } | 117 | } |
| 118 | spin_unlock_bh(&hsr->list_lock); | ||
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | void hsr_del_nodes(struct list_head *node_db) | 121 | void hsr_del_nodes(struct list_head *node_db) |
| @@ -130,30 +131,43 @@ void hsr_del_nodes(struct list_head *node_db) · 9 unmodified lines | |||
| 130 | * seq_out is used to initialize filtering of outgoing duplicate frames | 131 | * seq_out is used to initialize filtering of outgoing duplicate frames |
| 131 | * originating from the newly added node. | 132 | * originating from the newly added node. |
| 132 | */ | 133 | */ |
| 133 | struct hsr_node *hsr_add_node(struct list_head *node_db, unsigned char addr[], | 134 | static struct hsr_node *hsr_add_node(struct hsr_priv *hsr, |
| 134 | u16 seq_out) | 135 | struct list_head *node_db, |
| 136 | unsigned char addr[], | ||
| 137 | u16 seq_out) | ||
| 135 | { | 138 | { |
| 136 | struct hsr_node *node; | 139 | struct hsr_node *new_node, *node; |
| 137 | unsigned long now; | 140 | unsigned long now; |
| 138 | int i; | 141 | int i; |
| 139 | 142 | ||
| 140 | node = kzalloc(sizeof(*node), GFP_ATOMIC); | 143 | new_node = kzalloc(sizeof(*new_node), GFP_ATOMIC); |
| 141 | if (!node) | 144 | if (!new_node) |
| 142 | return NULL; | 145 | return NULL; |
| 143 | 146 | ||
| 144 | ether_addr_copy(node->macaddress_A, addr); | 147 | ether_addr_copy(new_node->macaddress_A, addr); |
| 145 | 148 | ||
| 146 | /* We are only interested in time diffs here, so use current jiffies | 149 | /* We are only interested in time diffs here, so use current jiffies |
| 147 | * as initialization. (0 could trigger an spurious ring error warning). | 150 | * as initialization. (0 could trigger an spurious ring error warning). |
| 148 | */ | 151 | */ |
| 149 | now = jiffies; | 152 | now = jiffies; |
| 150 | for (i = 0; i < HSR_PT_PORTS; i++) | 153 | for (i = 0; i < HSR_PT_PORTS; i++) |
| 151 | node->time_in[i] = now; | 154 | new_node->time_in[i] = now; |
| 152 | for (i = 0; i < HSR_PT_PORTS; i++) | 155 | for (i = 0; i < HSR_PT_PORTS; i++) |
| 153 | node->seq_out[i] = seq_out; | 156 | new_node->seq_out[i] = seq_out; |
| 154 | |||
| 155 | list_add_tail_rcu(&node->mac_list, node_db); | ||
| 156 | 157 | ||
| 158 | spin_lock_bh(&hsr->list_lock); | ||
| 159 | list_for_each_entry_rcu(node, node_db, mac_list) { | ||
| 160 | if (ether_addr_equal(node->macaddress_A, addr)) | ||
| 161 | goto out; | ||
| 162 | if (ether_addr_equal(node->macaddress_B, addr)) | ||
| 163 | goto out; | ||
| 164 | } | ||
| 165 | list_add_tail_rcu(&new_node->mac_list, node_db); | ||
| 166 | spin_unlock_bh(&hsr->list_lock); | ||
| 167 | return new_node; | ||
| 168 | out: | ||
| 169 | spin_unlock_bh(&hsr->list_lock); | ||
| 170 | kfree(new_node); | ||
| 157 | return node; | 171 | return node; |
| 158 | } | 172 | } |
| 159 | 173 | ||
| @@ -163,6 +177,7 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, · 3 unmodified lines | |||
| 163 | bool is_sup) | 177 | bool is_sup) |
| 164 | { | 178 | { |
| 165 | struct list_head *node_db = &port->hsr->node_db; | 179 | struct list_head *node_db = &port->hsr->node_db; |
| 180 | struct hsr_priv *hsr = port->hsr; | ||
| 166 | struct hsr_node *node; | 181 | struct hsr_node *node; |
| 167 | struct ethhdr *ethhdr; | 182 | struct ethhdr *ethhdr; |
| 168 | u16 seq_out; | 183 | u16 seq_out; |
| @@ -196,7 +211,7 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, · 27 unmodified lines | |||
| 196 | seq_out = HSR_SEQNR_START; | 211 | seq_out = HSR_SEQNR_START; |
| 197 | } | 212 | } |
| 198 | 213 | ||
| 199 | return hsr_add_node(node_db, ethhdr->h_source, seq_out); | 214 | return hsr_add_node(hsr, node_db, ethhdr->h_source, seq_out); |
| 200 | } | 215 | } |
| 201 | 216 | ||
| 202 | /* Use the Supervision frame's info about an eventual macaddress_B for merging | 217 | /* Use the Supervision frame's info about an eventual macaddress_B for merging |
| @@ -206,10 +221,11 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, · 3 unmodified lines | |||
| 206 | void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, | 221 | void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, |
| 207 | struct hsr_port *port_rcv) | 222 | struct hsr_port *port_rcv) |
| 208 | { | 223 | { |
| 209 | struct ethhdr *ethhdr; | 224 | struct hsr_priv *hsr = port_rcv->hsr; |
| 210 | struct hsr_node *node_real; | ||
| 211 | struct hsr_sup_payload *hsr_sp; | 225 | struct hsr_sup_payload *hsr_sp; |
| 226 | struct hsr_node *node_real; | ||
| 212 | struct list_head *node_db; | 227 | struct list_head *node_db; |
| 228 | struct ethhdr *ethhdr; | ||
| 213 | int i; | 229 | int i; |
| 214 | 230 | ||
| 215 | ethhdr = (struct ethhdr *)skb_mac_header(skb); | 231 | ethhdr = (struct ethhdr *)skb_mac_header(skb); |
| @@ -231,7 +247,7 @@ void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, · 15 unmodified lines | |||
| 231 | node_real = find_node_by_addr_A(node_db, hsr_sp->macaddress_A); | 247 | node_real = find_node_by_addr_A(node_db, hsr_sp->macaddress_A); |
| 232 | if (!node_real) | 248 | if (!node_real) |
| 233 | /* No frame received from AddrA of this node yet */ | 249 | /* No frame received from AddrA of this node yet */ |
| 234 | node_real = hsr_add_node(node_db, hsr_sp->macaddress_A, | 250 | node_real = hsr_add_node(hsr, node_db, hsr_sp->macaddress_A, |
| 235 | HSR_SEQNR_START - 1); | 251 | HSR_SEQNR_START - 1); |
| 236 | if (!node_real) | 252 | if (!node_real) |
| 237 | goto done; /* No mem */ | 253 | goto done; /* No mem */ |
| @@ -252,7 +268,9 @@ void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, · 14 unmodified lines | |||
| 252 | } | 268 | } |
| 253 | node_real->addr_B_port = port_rcv->type; | 269 | node_real->addr_B_port = port_rcv->type; |
| 254 | 270 | ||
| 271 | spin_lock_bh(&hsr->list_lock); | ||
| 255 | list_del_rcu(&node_curr->mac_list); | 272 | list_del_rcu(&node_curr->mac_list); |
| 273 | spin_unlock_bh(&hsr->list_lock); | ||
| 256 | kfree_rcu(node_curr, rcu_head); | 274 | kfree_rcu(node_curr, rcu_head); |
| 257 | 275 | ||
| 258 | done: | 276 | done: |
| @@ -368,12 +386,13 @@ void hsr_prune_nodes(struct timer_list *t) · 109 unmodified lines | |||
| 368 | { | 386 | { |
| 369 | struct hsr_priv *hsr = from_timer(hsr, t, prune_timer); | 387 | struct hsr_priv *hsr = from_timer(hsr, t, prune_timer); |
| 370 | struct hsr_node *node; | 388 | struct hsr_node *node; |
| 389 | struct hsr_node *tmp; | ||
| 371 | struct hsr_port *port; | 390 | struct hsr_port *port; |
| 372 | unsigned long timestamp; | 391 | unsigned long timestamp; |
| 373 | unsigned long time_a, time_b; | 392 | unsigned long time_a, time_b; |
| 374 | 393 | ||
| 375 | rcu_read_lock(); | 394 | spin_lock_bh(&hsr->list_lock); |
| 376 | list_for_each_entry_rcu(node, &hsr->node_db, mac_list) { | 395 | list_for_each_entry_safe(node, tmp, &hsr->node_db, mac_list) { |
| 377 | /* Don't prune own node. Neither time_in[HSR_PT_SLAVE_A] | 396 | /* Don't prune own node. Neither time_in[HSR_PT_SLAVE_A] |
| 378 | * nor time_in[HSR_PT_SLAVE_B], will ever be updated for | 397 | * nor time_in[HSR_PT_SLAVE_B], will ever be updated for |
| 379 | * the master port. Thus the master node will be repeatedly | 398 | * the master port. Thus the master node will be repeatedly |
| @@ -421,7 +440,7 @@ void hsr_prune_nodes(struct timer_list *t) · 41 unmodified lines | |||
| 421 | kfree_rcu(node, rcu_head); | 440 | kfree_rcu(node, rcu_head); |
| 422 | } | 441 | } |
| 423 | } | 442 | } |
| 424 | rcu_read_unlock(); | 443 | spin_unlock_bh(&hsr->list_lock); |
| 425 | 444 | ||
| 426 | /* Restart timer */ | 445 | /* Restart timer */ |
| 427 | mod_timer(&hsr->prune_timer, | 446 | mod_timer(&hsr->prune_timer, |
| @@ -12,10 +12,8 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | struct hsr_node; | 13 | struct hsr_node; |
| 14 | 14 | ||
| 15 | void hsr_del_self_node(struct list_head *self_node_db); | 15 | void hsr_del_self_node(struct hsr_priv *hsr); |
| 16 | void hsr_del_nodes(struct list_head *node_db); | 16 | void hsr_del_nodes(struct list_head *node_db); |
| 17 | struct hsr_node *hsr_add_node(struct list_head *node_db, unsigned char addr[], | ||
| 18 | u16 seq_out); | ||
| 19 | struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, | 17 | struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, |
| 20 | bool is_sup); | 18 | bool is_sup); |
| 21 | void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, | 19 | void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, |
| @@ -33,7 +31,7 @@ int hsr_register_frame_out(struct hsr_port *port, struct hsr_node *node, · 11 unmodified lines | |||
| 33 | 31 | ||
| 34 | void hsr_prune_nodes(struct timer_list *t); | 32 | void hsr_prune_nodes(struct timer_list *t); |
| 35 | 33 | ||
| 36 | int hsr_create_self_node(struct list_head *self_node_db, | 34 | int hsr_create_self_node(struct hsr_priv *hsr, |
| 37 | unsigned char addr_a[ETH_ALEN], | 35 | unsigned char addr_a[ETH_ALEN], |
| 38 | unsigned char addr_b[ETH_ALEN]); | 36 | unsigned char addr_b[ETH_ALEN]); |
| 39 | 37 | ||
| @@ -45,6 +45,10 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event, · 44 unmodified lines | |||
| 45 | case NETDEV_CHANGE: /* Link (carrier) state changes */ | 45 | case NETDEV_CHANGE: /* Link (carrier) state changes */ |
| 46 | hsr_check_carrier_and_operstate(hsr); | 46 | hsr_check_carrier_and_operstate(hsr); |
| 47 | break; | 47 | break; |
| 48 | case NETDEV_CHANGENAME: | ||
| 49 | if (is_hsr_master(dev)) | ||
| 50 | hsr_debugfs_rename(dev); | ||
| 51 | break; | ||
| 48 | case NETDEV_CHANGEADDR: | 52 | case NETDEV_CHANGEADDR: |
| 49 | if (port->type == HSR_PT_MASTER) { | 53 | if (port->type == HSR_PT_MASTER) { |
| 50 | /* This should not happen since there's no | 54 | /* This should not happen since there's no |
| @@ -64,7 +68,7 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event, · 13 unmodified lines | |||
| 64 | 68 | ||
| 65 | /* Make sure we recognize frames from ourselves in hsr_rcv() */ | 69 | /* Make sure we recognize frames from ourselves in hsr_rcv() */ |
| 66 | port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B); | 70 | port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B); |
| 67 | res = hsr_create_self_node(&hsr->self_node_db, | 71 | res = hsr_create_self_node(hsr, |
| 68 | master->dev->dev_addr, | 72 | master->dev->dev_addr, |
| 69 | port ? | 73 | port ? |
| 70 | port->dev->dev_addr : | 74 | port->dev->dev_addr : |
| @@ -123,6 +127,7 @@ static void __exit hsr_exit(void) · 52 unmodified lines | |||
| 123 | { | 127 | { |
| 124 | unregister_netdevice_notifier(&hsr_nb); | 128 | unregister_netdevice_notifier(&hsr_nb); |
| 125 | hsr_netlink_exit(); | 129 | hsr_netlink_exit(); |
| 130 | hsr_debugfs_remove_root(); | ||
| 126 | } | 131 | } |
| 127 | 132 | ||
| 128 | module_init(hsr_init); | 133 | module_init(hsr_init); |
| @@ -160,8 +160,9 @@ struct hsr_priv { · 159 unmodified lines | |||
| 160 | int announce_count; | 160 | int announce_count; |
| 161 | u16 sequence_nr; | 161 | u16 sequence_nr; |
| 162 | u16 sup_sequence_nr; /* For HSRv1 separate seq_nr for supervision */ | 162 | u16 sup_sequence_nr; /* For HSRv1 separate seq_nr for supervision */ |
| 163 | u8 prot_version; /* Indicate if HSRv0 or HSRv1. */ | 163 | u8 prot_version; /* Indicate if HSRv0 or HSRv1. */ |
| 164 | spinlock_t seqnr_lock; /* locking for sequence_nr */ | 164 | spinlock_t seqnr_lock; /* locking for sequence_nr */ |
| 165 | spinlock_t list_lock; /* locking for node list */ | ||
| 165 | unsigned char sup_multicast_addr[ETH_ALEN]; | 166 | unsigned char sup_multicast_addr[ETH_ALEN]; |
| 166 | #ifdef CONFIG_DEBUG_FS | 167 | #ifdef CONFIG_DEBUG_FS |
| 167 | struct dentry *node_tbl_root; | 168 | struct dentry *node_tbl_root; |
| @@ -184,17 +185,24 @@ static inline u16 hsr_get_skb_sequence_nr(struct sk_buff *skb) · 16 unmodified lines | |||
| 184 | } | 185 | } |
| 185 | 186 | ||
| 186 | #if IS_ENABLED(CONFIG_DEBUG_FS) | 187 | #if IS_ENABLED(CONFIG_DEBUG_FS) |
| 187 | int hsr_debugfs_init(struct hsr_priv *priv, struct net_device *hsr_dev); | 188 | void hsr_debugfs_rename(struct net_device *dev); |
| 189 | void hsr_debugfs_init(struct hsr_priv *priv, struct net_device *hsr_dev); | ||
| 188 | void hsr_debugfs_term(struct hsr_priv *priv); | 190 | void hsr_debugfs_term(struct hsr_priv *priv); |
| 191 | void hsr_debugfs_create_root(void); | ||
| 192 | void hsr_debugfs_remove_root(void); | ||
| 189 | #else | 193 | #else |
| 190 | static inline int hsr_debugfs_init(struct hsr_priv *priv, | 194 | static inline void void hsr_debugfs_rename(struct net_device *dev) |
| 191 | struct net_device *hsr_dev) | ||
| 192 | { | 195 | { |
| 193 | return 0; | ||
| 194 | } | 196 | } |
| 195 | 197 | static inline void hsr_debugfs_init(struct hsr_priv *priv, | |
| 198 | struct net_device *hsr_dev) | ||
| 199 | {} | ||
| 196 | static inline void hsr_debugfs_term(struct hsr_priv *priv) | 200 | static inline void hsr_debugfs_term(struct hsr_priv *priv) |
| 197 | {} | 201 | {} |
| 202 | static inline void hsr_debugfs_create_root(void) | ||
| 203 | {} | ||
| 204 | static inline void hsr_debugfs_remove_root(void) | ||
| 205 | {} | ||
| 198 | #endif | 206 | #endif |
| 199 | 207 | ||
| 200 | #endif /* __HSR_PRIVATE_H */ | 208 | #endif /* __HSR_PRIVATE_H */ |
| @@ -476,6 +476,7 @@ int __init hsr_netlink_init(void) · 475 unmodified lines | |||
| 476 | if (rc) | 476 | if (rc) |
| 477 | goto fail_genl_register_family; | 477 | goto fail_genl_register_family; |
| 478 | 478 | ||
| 479 | hsr_debugfs_create_root(); | ||
| 479 | return 0; | 480 | return 0; |
| 480 | 481 | ||
| 481 | fail_genl_register_family: | 482 | fail_genl_register_family: |
| @@ -1086,7 +1086,7 @@ struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu) · 1085 unmodified lines | |||
| 1086 | if (!dst) | 1086 | if (!dst) |
| 1087 | goto out; | 1087 | goto out; |
| 1088 | } | 1088 | } |
| 1089 | dst->ops->update_pmtu(dst, sk, NULL, mtu); | 1089 | dst->ops->update_pmtu(dst, sk, NULL, mtu, true); |
| 1090 | 1090 | ||
| 1091 | dst = __sk_dst_check(sk, 0); | 1091 | dst = __sk_dst_check(sk, 0); |
| 1092 | if (!dst) | 1092 | if (!dst) |
| @@ -505,7 +505,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, · 504 unmodified lines | |||
| 505 | mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | 505 | mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
| 506 | 506 | ||
| 507 | if (skb_valid_dst(skb)) | 507 | if (skb_valid_dst(skb)) |
| 508 | skb_dst_update_pmtu(skb, mtu); | 508 | skb_dst_update_pmtu_no_confirm(skb, mtu); |
| 509 | 509 | ||
| 510 | if (skb->protocol == htons(ETH_P_IP)) { | 510 | if (skb->protocol == htons(ETH_P_IP)) { |
| 511 | if (!skb_is_gso(skb) && | 511 | if (!skb_is_gso(skb) && |
| @@ -214,7 +214,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, · 213 unmodified lines | |||
| 214 | 214 | ||
| 215 | mtu = dst_mtu(dst); | 215 | mtu = dst_mtu(dst); |
| 216 | if (skb->len > mtu) { | 216 | if (skb->len > mtu) { |
| 217 | skb_dst_update_pmtu(skb, mtu); | 217 | skb_dst_update_pmtu_no_confirm(skb, mtu); |
| 218 | if (skb->protocol == htons(ETH_P_IP)) { | 218 | if (skb->protocol == htons(ETH_P_IP)) { |
| 219 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 219 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
| 220 | htonl(mtu)); | 220 | htonl(mtu)); |
| @@ -384,10 +384,11 @@ next: ; · 383 unmodified lines | |||
| 384 | return 1; | 384 | return 1; |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | static inline int check_target(struct arpt_entry *e, const char *name) | 387 | static int check_target(struct arpt_entry *e, struct net *net, const char *name) |
| 388 | { | 388 | { |
| 389 | struct xt_entry_target *t = arpt_get_target(e); | 389 | struct xt_entry_target *t = arpt_get_target(e); |
| 390 | struct xt_tgchk_param par = { | 390 | struct xt_tgchk_param par = { |
| 391 | .net = net, | ||
| 391 | .table = name, | 392 | .table = name, |
| 392 | .entryinfo = e, | 393 | .entryinfo = e, |
| 393 | .target = t->u.kernel.target, | 394 | .target = t->u.kernel.target, |
| @@ -399,8 +400,9 @@ static inline int check_target(struct arpt_entry *e, const char *name) · 5 unmodified lines | |||
| 399 | return xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false); | 400 | return xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false); |
| 400 | } | 401 | } |
| 401 | 402 | ||
| 402 | static inline int | 403 | static int |
| 403 | find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, | 404 | find_check_entry(struct arpt_entry *e, struct net *net, const char *name, |
| 405 | unsigned int size, | ||
| 404 | struct xt_percpu_counter_alloc_state *alloc_state) | 406 | struct xt_percpu_counter_alloc_state *alloc_state) |
| 405 | { | 407 | { |
| 406 | struct xt_entry_target *t; | 408 | struct xt_entry_target *t; |
| @@ -419,7 +421,7 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, · 12 unmodified lines | |||
| 419 | } | 421 | } |
| 420 | t->u.kernel.target = target; | 422 | t->u.kernel.target = target; |
| 421 | 423 | ||
| 422 | ret = check_target(e, name); | 424 | ret = check_target(e, net, name); |
| 423 | if (ret) | 425 | if (ret) |
| 424 | goto err; | 426 | goto err; |
| 425 | return 0; | 427 | return 0; |
| @@ -512,7 +514,9 @@ static inline void cleanup_entry(struct arpt_entry *e) · 86 unmodified lines | |||
| 512 | /* Checks and translates the user-supplied table segment (held in | 514 | /* Checks and translates the user-supplied table segment (held in |
| 513 | * newinfo). | 515 | * newinfo). |
| 514 | */ | 516 | */ |
| 515 | static int translate_table(struct xt_table_info *newinfo, void *entry0, | 517 | static int translate_table(struct net *net, |
| 518 | struct xt_table_info *newinfo, | ||
| 519 | void *entry0, | ||
| 516 | const struct arpt_replace *repl) | 520 | const struct arpt_replace *repl) |
| 517 | { | 521 | { |
| 518 | struct xt_percpu_counter_alloc_state alloc_state = { 0 }; | 522 | struct xt_percpu_counter_alloc_state alloc_state = { 0 }; |
| @@ -569,7 +573,7 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0, · 50 unmodified lines | |||
| 569 | /* Finally, each sanity check must pass */ | 573 | /* Finally, each sanity check must pass */ |
| 570 | i = 0; | 574 | i = 0; |
| 571 | xt_entry_foreach(iter, entry0, newinfo->size) { | 575 | xt_entry_foreach(iter, entry0, newinfo->size) { |
| 572 | ret = find_check_entry(iter, repl->name, repl->size, | 576 | ret = find_check_entry(iter, net, repl->name, repl->size, |
| 573 | &alloc_state); | 577 | &alloc_state); |
| 574 | if (ret != 0) | 578 | if (ret != 0) |
| 575 | break; | 579 | break; |
| @@ -974,7 +978,7 @@ static int do_replace(struct net *net, const void __user *user, · 398 unmodified lines | |||
| 974 | goto free_newinfo; | 978 | goto free_newinfo; |
| 975 | } | 979 | } |
| 976 | 980 | ||
| 977 | ret = translate_table(newinfo, loc_cpu_entry, &tmp); | 981 | ret = translate_table(net, newinfo, loc_cpu_entry, &tmp); |
| 978 | if (ret != 0) | 982 | if (ret != 0) |
| 979 | goto free_newinfo; | 983 | goto free_newinfo; |
| 980 | 984 | ||
| @@ -1149,7 +1153,8 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr, · 168 unmodified lines | |||
| 1149 | } | 1153 | } |
| 1150 | } | 1154 | } |
| 1151 | 1155 | ||
| 1152 | static int translate_compat_table(struct xt_table_info **pinfo, | 1156 | static int translate_compat_table(struct net *net, |
| 1157 | struct xt_table_info **pinfo, | ||
| 1153 | void **pentry0, | 1158 | void **pentry0, |
| 1154 | const struct compat_arpt_replace *compatr) | 1159 | const struct compat_arpt_replace *compatr) |
| 1155 | { | 1160 | { |
| @@ -1217,7 +1222,7 @@ static int translate_compat_table(struct xt_table_info **pinfo, · 61 unmodified lines | |||
| 1217 | repl.num_counters = 0; | 1222 | repl.num_counters = 0; |
| 1218 | repl.counters = NULL; | 1223 | repl.counters = NULL; |
| 1219 | repl.size = newinfo->size; | 1224 | repl.size = newinfo->size; |
| 1220 | ret = translate_table(newinfo, entry1, &repl); | 1225 | ret = translate_table(net, newinfo, entry1, &repl); |
| 1221 | if (ret) | 1226 | if (ret) |
| 1222 | goto free_newinfo; | 1227 | goto free_newinfo; |
| 1223 | 1228 | ||
| @@ -1270,7 +1275,7 @@ static int compat_do_replace(struct net *net, void __user *user, · 46 unmodified lines | |||
| 1270 | goto free_newinfo; | 1275 | goto free_newinfo; |
| 1271 | } | 1276 | } |
| 1272 | 1277 | ||
| 1273 | ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp); | 1278 | ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp); |
| 1274 | if (ret != 0) | 1279 | if (ret != 0) |
| 1275 | goto free_newinfo; | 1280 | goto free_newinfo; |
| 1276 | 1281 | ||
| @@ -1546,7 +1551,7 @@ int arpt_register_table(struct net *net, · 269 unmodified lines | |||
| 1546 | loc_cpu_entry = newinfo->entries; | 1551 | loc_cpu_entry = newinfo->entries; |
| 1547 | memcpy(loc_cpu_entry, repl->entries, repl->size); | 1552 | memcpy(loc_cpu_entry, repl->entries, repl->size); |
| 1548 | 1553 | ||
| 1549 | ret = translate_table(newinfo, loc_cpu_entry, repl); | 1554 | ret = translate_table(net, newinfo, loc_cpu_entry, repl); |
| 1550 | if (ret != 0) | 1555 | if (ret != 0) |
| 1551 | goto out_free; | 1556 | goto out_free; |
| 1552 | 1557 | ||
| @@ -139,7 +139,8 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst); · 138 unmodified lines | |||
| 139 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); | 139 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); |
| 140 | static void ipv4_link_failure(struct sk_buff *skb); | 140 | static void ipv4_link_failure(struct sk_buff *skb); |
| 141 | static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 141 | static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 142 | struct sk_buff *skb, u32 mtu); | 142 | struct sk_buff *skb, u32 mtu, |
| 143 | bool confirm_neigh); | ||
| 143 | static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, | 144 | static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, |
| 144 | struct sk_buff *skb); | 145 | struct sk_buff *skb); |
| 145 | static void ipv4_dst_destroy(struct dst_entry *dst); | 146 | static void ipv4_dst_destroy(struct dst_entry *dst); |
| @@ -1043,7 +1044,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) · 897 unmodified lines | |||
| 1043 | } | 1044 | } |
| 1044 | 1045 | ||
| 1045 | static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 1046 | static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 1046 | struct sk_buff *skb, u32 mtu) | 1047 | struct sk_buff *skb, u32 mtu, |
| 1048 | bool confirm_neigh) | ||
| 1047 | { | 1049 | { |
| 1048 | struct rtable *rt = (struct rtable *) dst; | 1050 | struct rtable *rt = (struct rtable *) dst; |
| 1049 | struct flowi4 fl4; | 1051 | struct flowi4 fl4; |
| @@ -2687,7 +2689,8 @@ static unsigned int ipv4_blackhole_mtu(const struct dst_entry *dst) · 1637 unmodified lines | |||
| 2687 | } | 2689 | } |
| 2688 | 2690 | ||
| 2689 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, | 2691 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 2690 | struct sk_buff *skb, u32 mtu) | 2692 | struct sk_buff *skb, u32 mtu, |
| 2693 | bool confirm_neigh) | ||
| 2691 | { | 2694 | { |
| 2692 | } | 2695 | } |
| 2693 | 2696 | ||
| @@ -1727,8 +1727,11 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb, · 1726 unmodified lines | |||
| 1727 | } | 1727 | } |
| 1728 | 1728 | ||
| 1729 | /* Ignore very old stuff early */ | 1729 | /* Ignore very old stuff early */ |
| 1730 | if (!after(sp[used_sacks].end_seq, prior_snd_una)) | 1730 | if (!after(sp[used_sacks].end_seq, prior_snd_una)) { |
| 1731 | if (i == 0) | ||
| 1732 | first_sack_index = -1; | ||
| 1731 | continue; | 1733 | continue; |
| 1734 | } | ||
| 1732 | 1735 | ||
| 1733 | used_sacks++; | 1736 | used_sacks++; |
| 1734 | } | 1737 | } |
| @@ -72,6 +72,9 @@ static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) · 71 unmodified lines | |||
| 72 | __skb_unlink(skb, &sk->sk_write_queue); | 72 | __skb_unlink(skb, &sk->sk_write_queue); |
| 73 | tcp_rbtree_insert(&sk->tcp_rtx_queue, skb); | 73 | tcp_rbtree_insert(&sk->tcp_rtx_queue, skb); |
| 74 | 74 | ||
| 75 | if (tp->highest_sack == NULL) | ||
| 76 | tp->highest_sack = skb; | ||
| 77 | |||
| 75 | tp->packets_out += tcp_skb_pcount(skb); | 78 | tp->packets_out += tcp_skb_pcount(skb); |
| 76 | if (!prior_packets || icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) | 79 | if (!prior_packets || icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) |
| 77 | tcp_rearm_rto(sk); | 80 | tcp_rearm_rto(sk); |
| @@ -1475,7 +1475,7 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb) · 1474 unmodified lines | |||
| 1475 | * queue contains some other skb | 1475 | * queue contains some other skb |
| 1476 | */ | 1476 | */ |
| 1477 | rmem = atomic_add_return(size, &sk->sk_rmem_alloc); | 1477 | rmem = atomic_add_return(size, &sk->sk_rmem_alloc); |
| 1478 | if (rmem > (size + sk->sk_rcvbuf)) | 1478 | if (rmem > (size + (unsigned int)sk->sk_rcvbuf)) |
| 1479 | goto uncharge_drop; | 1479 | goto uncharge_drop; |
| 1480 | 1480 | ||
| 1481 | spin_lock(&list->lock); | 1481 | spin_lock(&list->lock); |
| @@ -100,12 +100,13 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, · 99 unmodified lines | |||
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk, | 102 | static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 103 | struct sk_buff *skb, u32 mtu) | 103 | struct sk_buff *skb, u32 mtu, |
| 104 | bool confirm_neigh) | ||
| 104 | { | 105 | { |
| 105 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | 106 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
| 106 | struct dst_entry *path = xdst->route; | 107 | struct dst_entry *path = xdst->route; |
| 107 | 108 | ||
| 108 | path->ops->update_pmtu(path, sk, skb, mtu); | 109 | path->ops->update_pmtu(path, sk, skb, mtu, confirm_neigh); |
| 109 | } | 110 | } |
| 110 | 111 | ||
| 111 | static void xfrm4_redirect(struct dst_entry *dst, struct sock *sk, | 112 | static void xfrm4_redirect(struct dst_entry *dst, struct sock *sk, |
| @@ -146,7 +146,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) · 145 unmodified lines | |||
| 146 | 146 | ||
| 147 | if (IS_ERR(dst)) | 147 | if (IS_ERR(dst)) |
| 148 | return NULL; | 148 | return NULL; |
| 149 | dst->ops->update_pmtu(dst, sk, NULL, mtu); | 149 | dst->ops->update_pmtu(dst, sk, NULL, mtu, true); |
| 150 | 150 | ||
| 151 | dst = inet6_csk_route_socket(sk, &fl6); | 151 | dst = inet6_csk_route_socket(sk, &fl6); |
| 152 | return IS_ERR(dst) ? NULL : dst; | 152 | return IS_ERR(dst) ? NULL : dst; |
| @@ -1040,7 +1040,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, · 1039 unmodified lines | |||
| 1040 | 1040 | ||
| 1041 | /* TooBig packet may have updated dst->dev's mtu */ | 1041 | /* TooBig packet may have updated dst->dev's mtu */ |
| 1042 | if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu) | 1042 | if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu) |
| 1043 | dst->ops->update_pmtu(dst, NULL, skb, dst->dev->mtu); | 1043 | dst->ops->update_pmtu(dst, NULL, skb, dst->dev->mtu, false); |
| 1044 | 1044 | ||
| 1045 | err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, | 1045 | err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, |
| 1046 | NEXTHDR_GRE); | 1046 | NEXTHDR_GRE); |
| @@ -640,7 +640,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, · 639 unmodified lines | |||
| 640 | if (rel_info > dst_mtu(skb_dst(skb2))) | 640 | if (rel_info > dst_mtu(skb_dst(skb2))) |
| 641 | goto out; | 641 | goto out; |
| 642 | 642 | ||
| 643 | skb_dst_update_pmtu(skb2, rel_info); | 643 | skb_dst_update_pmtu_no_confirm(skb2, rel_info); |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); | 646 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); |
| @@ -1132,7 +1132,7 @@ route_lookup: · 485 unmodified lines | |||
| 1132 | mtu = max(mtu, skb->protocol == htons(ETH_P_IPV6) ? | 1132 | mtu = max(mtu, skb->protocol == htons(ETH_P_IPV6) ? |
| 1133 | IPV6_MIN_MTU : IPV4_MIN_MTU); | 1133 | IPV6_MIN_MTU : IPV4_MIN_MTU); |
| 1134 | 1134 | ||
| 1135 | skb_dst_update_pmtu(skb, mtu); | 1135 | skb_dst_update_pmtu_no_confirm(skb, mtu); |
| 1136 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { | 1136 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { |
| 1137 | *pmtu = mtu; | 1137 | *pmtu = mtu; |
| 1138 | err = -EMSGSIZE; | 1138 | err = -EMSGSIZE; |
| @@ -479,7 +479,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) · 478 unmodified lines | |||
| 479 | 479 | ||
| 480 | mtu = dst_mtu(dst); | 480 | mtu = dst_mtu(dst); |
| 481 | if (skb->len > mtu) { | 481 | if (skb->len > mtu) { |
| 482 | skb_dst_update_pmtu(skb, mtu); | 482 | skb_dst_update_pmtu_no_confirm(skb, mtu); |
| 483 | 483 | ||
| 484 | if (skb->protocol == htons(ETH_P_IPV6)) { | 484 | if (skb->protocol == htons(ETH_P_IPV6)) { |
| 485 | if (mtu < IPV6_MIN_MTU) | 485 | if (mtu < IPV6_MIN_MTU) |
| @@ -95,7 +95,8 @@ static int ip6_pkt_prohibit(struct sk_buff *skb); · 94 unmodified lines | |||
| 95 | static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); | 95 | static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); |
| 96 | static void ip6_link_failure(struct sk_buff *skb); | 96 | static void ip6_link_failure(struct sk_buff *skb); |
| 97 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 97 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 98 | struct sk_buff *skb, u32 mtu); | 98 | struct sk_buff *skb, u32 mtu, |
| 99 | bool confirm_neigh); | ||
| 99 | static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, | 100 | static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, |
| 100 | struct sk_buff *skb); | 101 | struct sk_buff *skb); |
| 101 | static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif, | 102 | static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif, |
| @@ -264,7 +265,8 @@ static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst) · 162 unmodified lines | |||
| 264 | } | 265 | } |
| 265 | 266 | ||
| 266 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, | 267 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 267 | struct sk_buff *skb, u32 mtu) | 268 | struct sk_buff *skb, u32 mtu, |
| 269 | bool confirm_neigh) | ||
| 268 | { | 270 | { |
| 269 | } | 271 | } |
| 270 | 272 | ||
| @@ -2692,7 +2694,8 @@ static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt) · 2421 unmodified lines | |||
| 2692 | } | 2694 | } |
| 2693 | 2695 | ||
| 2694 | static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, | 2696 | static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, |
| 2695 | const struct ipv6hdr *iph, u32 mtu) | 2697 | const struct ipv6hdr *iph, u32 mtu, |
| 2698 | bool confirm_neigh) | ||
| 2696 | { | 2699 | { |
| 2697 | const struct in6_addr *daddr, *saddr; | 2700 | const struct in6_addr *daddr, *saddr; |
| 2698 | struct rt6_info *rt6 = (struct rt6_info *)dst; | 2701 | struct rt6_info *rt6 = (struct rt6_info *)dst; |
| @@ -2710,7 +2713,10 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, · 11 unmodified lines | |||
| 2710 | daddr = NULL; | 2713 | daddr = NULL; |
| 2711 | saddr = NULL; | 2714 | saddr = NULL; |
| 2712 | } | 2715 | } |
| 2713 | dst_confirm_neigh(dst, daddr); | 2716 | |
| 2717 | if (confirm_neigh) | ||
| 2718 | dst_confirm_neigh(dst, daddr); | ||
| 2719 | |||
| 2714 | mtu = max_t(u32, mtu, IPV6_MIN_MTU); | 2720 | mtu = max_t(u32, mtu, IPV6_MIN_MTU); |
| 2715 | if (mtu >= dst_mtu(dst)) | 2721 | if (mtu >= dst_mtu(dst)) |
| 2716 | return; | 2722 | return; |
| @@ -2764,9 +2770,11 @@ out_unlock: · 47 unmodified lines | |||
| 2764 | } | 2770 | } |
| 2765 | 2771 | ||
| 2766 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 2772 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 2767 | struct sk_buff *skb, u32 mtu) | 2773 | struct sk_buff *skb, u32 mtu, |
| 2774 | bool confirm_neigh) | ||
| 2768 | { | 2775 | { |
| 2769 | __ip6_rt_update_pmtu(dst, sk, skb ? ipv6_hdr(skb) : NULL, mtu); | 2776 | __ip6_rt_update_pmtu(dst, sk, skb ? ipv6_hdr(skb) : NULL, mtu, |
| 2777 | confirm_neigh); | ||
| 2770 | } | 2778 | } |
| 2771 | 2779 | ||
| 2772 | void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, | 2780 | void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, |
| @@ -2785,7 +2793,7 @@ void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, · 12 unmodified lines | |||
| 2785 | 2793 | ||
| 2786 | dst = ip6_route_output(net, NULL, &fl6); | 2794 | dst = ip6_route_output(net, NULL, &fl6); |
| 2787 | if (!dst->error) | 2795 | if (!dst->error) |
| 2788 | __ip6_rt_update_pmtu(dst, NULL, iph, ntohl(mtu)); | 2796 | __ip6_rt_update_pmtu(dst, NULL, iph, ntohl(mtu), true); |
| 2789 | dst_release(dst); | 2797 | dst_release(dst); |
| 2790 | } | 2798 | } |
| 2791 | EXPORT_SYMBOL_GPL(ip6_update_pmtu); | 2799 | EXPORT_SYMBOL_GPL(ip6_update_pmtu); |
| @@ -944,7 +944,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, · 943 unmodified lines | |||
| 944 | } | 944 | } |
| 945 | 945 | ||
| 946 | if (tunnel->parms.iph.daddr) | 946 | if (tunnel->parms.iph.daddr) |
| 947 | skb_dst_update_pmtu(skb, mtu); | 947 | skb_dst_update_pmtu_no_confirm(skb, mtu); |
| 948 | 948 | ||
| 949 | if (skb->len > mtu && !skb_is_gso(skb)) { | 949 | if (skb->len > mtu && !skb_is_gso(skb)) { |
| 950 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 950 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
| @@ -98,12 +98,13 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, · 97 unmodified lines | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static void xfrm6_update_pmtu(struct dst_entry *dst, struct sock *sk, | 100 | static void xfrm6_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 101 | struct sk_buff *skb, u32 mtu) | 101 | struct sk_buff *skb, u32 mtu, |
| 102 | bool confirm_neigh) | ||
| 102 | { | 103 | { |
| 103 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | 104 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
| 104 | struct dst_entry *path = xdst->route; | 105 | struct dst_entry *path = xdst->route; |
| 105 | 106 | ||
| 106 | path->ops->update_pmtu(path, sk, skb, mtu); | 107 | path->ops->update_pmtu(path, sk, skb, mtu, confirm_neigh); |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | static void xfrm6_redirect(struct dst_entry *dst, struct sock *sk, | 110 | static void xfrm6_redirect(struct dst_entry *dst, struct sock *sk, |
| @@ -1848,6 +1848,7 @@ static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb, · 1847 unmodified lines | |||
| 1848 | struct ip_set *set; | 1848 | struct ip_set *set; |
| 1849 | struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {}; | 1849 | struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {}; |
| 1850 | int ret = 0; | 1850 | int ret = 0; |
| 1851 | u32 lineno; | ||
| 1851 | 1852 | ||
| 1852 | if (unlikely(protocol_min_failed(attr) || | 1853 | if (unlikely(protocol_min_failed(attr) || |
| 1853 | !attr[IPSET_ATTR_SETNAME] || | 1854 | !attr[IPSET_ATTR_SETNAME] || |
| @@ -1864,7 +1865,7 @@ static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb, · 10 unmodified lines | |||
| 1864 | return -IPSET_ERR_PROTOCOL; | 1865 | return -IPSET_ERR_PROTOCOL; |
| 1865 | 1866 | ||
| 1866 | rcu_read_lock_bh(); | 1867 | rcu_read_lock_bh(); |
| 1867 | ret = set->variant->uadt(set, tb, IPSET_TEST, NULL, 0, 0); | 1868 | ret = set->variant->uadt(set, tb, IPSET_TEST, &lineno, 0, 0); |
| 1868 | rcu_read_unlock_bh(); | 1869 | rcu_read_unlock_bh(); |
| 1869 | /* Userspace can't trigger element to be re-added */ | 1870 | /* Userspace can't trigger element to be re-added */ |
| 1870 | if (ret == -EAGAIN) | 1871 | if (ret == -EAGAIN) |
| @@ -208,7 +208,7 @@ static inline void maybe_update_pmtu(int skb_af, struct sk_buff *skb, int mtu) · 207 unmodified lines | |||
| 208 | struct rtable *ort = skb_rtable(skb); | 208 | struct rtable *ort = skb_rtable(skb); |
| 209 | 209 | ||
| 210 | if (!skb->dev && sk && sk_fullsock(sk)) | 210 | if (!skb->dev && sk && sk_fullsock(sk)) |
| 211 | ort->dst.ops->update_pmtu(&ort->dst, sk, NULL, mtu); | 211 | ort->dst.ops->update_pmtu(&ort->dst, sk, NULL, mtu, true); |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af, | 214 | static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af, |
| @@ -677,6 +677,9 @@ static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], · 676 unmodified lines | |||
| 677 | unsigned int *timeouts = data; | 677 | unsigned int *timeouts = data; |
| 678 | int i; | 678 | int i; |
| 679 | 679 | ||
| 680 | if (!timeouts) | ||
| 681 | timeouts = dn->dccp_timeout; | ||
| 682 | |||
| 680 | /* set default DCCP timeouts. */ | 683 | /* set default DCCP timeouts. */ |
| 681 | for (i=0; i<CT_DCCP_MAX; i++) | 684 | for (i=0; i<CT_DCCP_MAX; i++) |
| 682 | timeouts[i] = dn->dccp_timeout[i]; | 685 | timeouts[i] = dn->dccp_timeout[i]; |
| @@ -594,6 +594,9 @@ static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], · 593 unmodified lines | |||
| 594 | struct nf_sctp_net *sn = nf_sctp_pernet(net); | 594 | struct nf_sctp_net *sn = nf_sctp_pernet(net); |
| 595 | int i; | 595 | int i; |
| 596 | 596 | ||
| 597 | if (!timeouts) | ||
| 598 | timeouts = sn->timeouts; | ||
| 599 | |||
| 597 | /* set default SCTP timeouts. */ | 600 | /* set default SCTP timeouts. */ |
| 598 | for (i=0; i<SCTP_CONNTRACK_MAX; i++) | 601 | for (i=0; i<SCTP_CONNTRACK_MAX; i++) |
| 599 | timeouts[i] = sn->timeouts[i]; | 602 | timeouts[i] = sn->timeouts[i]; |
| @@ -134,11 +134,6 @@ static void flow_offload_fixup_tcp(struct ip_ct_tcp *tcp) · 133 unmodified lines | |||
| 134 | #define NF_FLOWTABLE_TCP_PICKUP_TIMEOUT (120 * HZ) | 134 | #define NF_FLOWTABLE_TCP_PICKUP_TIMEOUT (120 * HZ) |
| 135 | #define NF_FLOWTABLE_UDP_PICKUP_TIMEOUT (30 * HZ) | 135 | #define NF_FLOWTABLE_UDP_PICKUP_TIMEOUT (30 * HZ) |
| 136 | 136 | ||
| 137 | static inline __s32 nf_flow_timeout_delta(unsigned int timeout) | ||
| 138 | { | ||
| 139 | return (__s32)(timeout - (u32)jiffies); | ||
| 140 | } | ||
| 141 | |||
| 142 | static void flow_offload_fixup_ct_timeout(struct nf_conn *ct) | 137 | static void flow_offload_fixup_ct_timeout(struct nf_conn *ct) |
| 143 | { | 138 | { |
| 144 | const struct nf_conntrack_l4proto *l4proto; | 139 | const struct nf_conntrack_l4proto *l4proto; |
| @@ -232,7 +227,7 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) · 87 unmodified lines | |||
| 232 | { | 227 | { |
| 233 | int err; | 228 | int err; |
| 234 | 229 | ||
| 235 | flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; | 230 | flow->timeout = nf_flowtable_time_stamp + NF_FLOW_TIMEOUT; |
| 236 | 231 | ||
| 237 | err = rhashtable_insert_fast(&flow_table->rhashtable, | 232 | err = rhashtable_insert_fast(&flow_table->rhashtable, |
| 238 | &flow->tuplehash[0].node, | 233 | &flow->tuplehash[0].node, |
| @@ -280,7 +280,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, · 279 unmodified lines | |||
| 280 | if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0) | 280 | if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0) |
| 281 | return NF_DROP; | 281 | return NF_DROP; |
| 282 | 282 | ||
| 283 | flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; | 283 | flow->timeout = nf_flowtable_time_stamp + NF_FLOW_TIMEOUT; |
| 284 | iph = ip_hdr(skb); | 284 | iph = ip_hdr(skb); |
| 285 | ip_decrease_ttl(iph); | 285 | ip_decrease_ttl(iph); |
| 286 | skb->tstamp = 0; | 286 | skb->tstamp = 0; |
| @@ -509,7 +509,7 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, · 222 unmodified lines | |||
| 509 | if (nf_flow_nat_ipv6(flow, skb, dir) < 0) | 509 | if (nf_flow_nat_ipv6(flow, skb, dir) < 0) |
| 510 | return NF_DROP; | 510 | return NF_DROP; |
| 511 | 511 | ||
| 512 | flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; | 512 | flow->timeout = nf_flowtable_time_stamp + NF_FLOW_TIMEOUT; |
| 513 | ip6h = ipv6_hdr(skb); | 513 | ip6h = ipv6_hdr(skb); |
| 514 | ip6h->hop_limit--; | 514 | ip6h->hop_limit--; |
| 515 | skb->tstamp = 0; | 515 | skb->tstamp = 0; |
| @@ -88,7 +88,7 @@ static int nf_flow_rule_match(struct nf_flow_match *match, · 87 unmodified lines | |||
| 88 | switch (tuple->l4proto) { | 88 | switch (tuple->l4proto) { |
| 89 | case IPPROTO_TCP: | 89 | case IPPROTO_TCP: |
| 90 | key->tcp.flags = 0; | 90 | key->tcp.flags = 0; |
| 91 | mask->tcp.flags = TCP_FLAG_RST | TCP_FLAG_FIN; | 91 | mask->tcp.flags = cpu_to_be16(be32_to_cpu(TCP_FLAG_RST | TCP_FLAG_FIN) >> 16); |
| 92 | match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_TCP); | 92 | match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_TCP); |
| 93 | break; | 93 | break; |
| 94 | case IPPROTO_UDP: | 94 | case IPPROTO_UDP: |
| @@ -166,24 +166,38 @@ static int flow_offload_eth_dst(struct net *net, · 71 unmodified lines | |||
| 166 | enum flow_offload_tuple_dir dir, | 166 | enum flow_offload_tuple_dir dir, |
| 167 | struct nf_flow_rule *flow_rule) | 167 | struct nf_flow_rule *flow_rule) |
| 168 | { | 168 | { |
| 169 | const struct flow_offload_tuple *tuple = &flow->tuplehash[dir].tuple; | ||
| 170 | struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule); | 169 | struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule); |
| 171 | struct flow_action_entry *entry1 = flow_action_entry_next(flow_rule); | 170 | struct flow_action_entry *entry1 = flow_action_entry_next(flow_rule); |
| 171 | const void *daddr = &flow->tuplehash[!dir].tuple.src_v4; | ||
| 172 | const struct dst_entry *dst_cache; | ||
| 173 | unsigned char ha[ETH_ALEN]; | ||
| 172 | struct neighbour *n; | 174 | struct neighbour *n; |
| 173 | u32 mask, val; | 175 | u32 mask, val; |
| 176 | u8 nud_state; | ||
| 174 | u16 val16; | 177 | u16 val16; |
| 175 | 178 | ||
| 176 | n = dst_neigh_lookup(tuple->dst_cache, &tuple->dst_v4); | 179 | dst_cache = flow->tuplehash[dir].tuple.dst_cache; |
| 180 | n = dst_neigh_lookup(dst_cache, daddr); | ||
| 177 | if (!n) | 181 | if (!n) |
| 178 | return -ENOENT; | 182 | return -ENOENT; |
| 179 | 183 | ||
| 184 | read_lock_bh(&n->lock); | ||
| 185 | nud_state = n->nud_state; | ||
| 186 | ether_addr_copy(ha, n->ha); | ||
| 187 | read_unlock_bh(&n->lock); | ||
| 188 | |||
| 189 | if (!(nud_state & NUD_VALID)) { | ||
| 190 | neigh_release(n); | ||
| 191 | return -ENOENT; | ||
| 192 | } | ||
| 193 | |||
| 180 | mask = ~0xffffffff; | 194 | mask = ~0xffffffff; |
| 181 | memcpy(&val, n->ha, 4); | 195 | memcpy(&val, ha, 4); |
| 182 | flow_offload_mangle(entry0, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 0, | 196 | flow_offload_mangle(entry0, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 0, |
| 183 | &val, &mask); | 197 | &val, &mask); |
| 184 | 198 | ||
| 185 | mask = ~0x0000ffff; | 199 | mask = ~0x0000ffff; |
| 186 | memcpy(&val16, n->ha + 4, 2); | 200 | memcpy(&val16, ha + 4, 2); |
| 187 | val = val16; | 201 | val = val16; |
| 188 | flow_offload_mangle(entry1, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 4, | 202 | flow_offload_mangle(entry1, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 4, |
| 189 | &val, &mask); | 203 | &val, &mask); |
| @@ -335,22 +349,26 @@ static void flow_offload_port_snat(struct net *net, · 145 unmodified lines | |||
| 335 | struct nf_flow_rule *flow_rule) | 349 | struct nf_flow_rule *flow_rule) |
| 336 | { | 350 | { |
| 337 | struct flow_action_entry *entry = flow_action_entry_next(flow_rule); | 351 | struct flow_action_entry *entry = flow_action_entry_next(flow_rule); |
| 338 | u32 mask = ~htonl(0xffff0000), port; | 352 | u32 mask, port; |
| 339 | u32 offset; | 353 | u32 offset; |
| 340 | 354 | ||
| 341 | switch (dir) { | 355 | switch (dir) { |
| 342 | case FLOW_OFFLOAD_DIR_ORIGINAL: | 356 | case FLOW_OFFLOAD_DIR_ORIGINAL: |
| 343 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port); | 357 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port); |
| 344 | offset = 0; /* offsetof(struct tcphdr, source); */ | 358 | offset = 0; /* offsetof(struct tcphdr, source); */ |
| 359 | port = htonl(port << 16); | ||
| 360 | mask = ~htonl(0xffff0000); | ||
| 345 | break; | 361 | break; |
| 346 | case FLOW_OFFLOAD_DIR_REPLY: | 362 | case FLOW_OFFLOAD_DIR_REPLY: |
| 347 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port); | 363 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port); |
| 348 | offset = 0; /* offsetof(struct tcphdr, dest); */ | 364 | offset = 0; /* offsetof(struct tcphdr, dest); */ |
| 365 | port = htonl(port); | ||
| 366 | mask = ~htonl(0xffff); | ||
| 349 | break; | 367 | break; |
| 350 | default: | 368 | default: |
| 351 | return; | 369 | return; |
| 352 | } | 370 | } |
| 353 | port = htonl(port << 16); | 371 | |
| 354 | flow_offload_mangle(entry, flow_offload_l4proto(flow), offset, | 372 | flow_offload_mangle(entry, flow_offload_l4proto(flow), offset, |
| 355 | &port, &mask); | 373 | &port, &mask); |
| 356 | } | 374 | } |
| @@ -361,22 +379,26 @@ static void flow_offload_port_dnat(struct net *net, · 4 unmodified lines | |||
| 361 | struct nf_flow_rule *flow_rule) | 379 | struct nf_flow_rule *flow_rule) |
| 362 | { | 380 | { |
| 363 | struct flow_action_entry *entry = flow_action_entry_next(flow_rule); | 381 | struct flow_action_entry *entry = flow_action_entry_next(flow_rule); |
| 364 | u32 mask = ~htonl(0xffff), port; | 382 | u32 mask, port; |
| 365 | u32 offset; | 383 | u32 offset; |
| 366 | 384 | ||
| 367 | switch (dir) { | 385 | switch (dir) { |
| 368 | case FLOW_OFFLOAD_DIR_ORIGINAL: | 386 | case FLOW_OFFLOAD_DIR_ORIGINAL: |
| 369 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port); | 387 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port); |
| 370 | offset = 0; /* offsetof(struct tcphdr, source); */ | 388 | offset = 0; /* offsetof(struct tcphdr, dest); */ |
| 389 | port = htonl(port); | ||
| 390 | mask = ~htonl(0xffff); | ||
| 371 | break; | 391 | break; |
| 372 | case FLOW_OFFLOAD_DIR_REPLY: | 392 | case FLOW_OFFLOAD_DIR_REPLY: |
| 373 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port); | 393 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port); |
| 374 | offset = 0; /* offsetof(struct tcphdr, dest); */ | 394 | offset = 0; /* offsetof(struct tcphdr, source); */ |
| 395 | port = htonl(port << 16); | ||
| 396 | mask = ~htonl(0xffff0000); | ||
| 375 | break; | 397 | break; |
| 376 | default: | 398 | default: |
| 377 | return; | 399 | return; |
| 378 | } | 400 | } |
| 379 | port = htonl(port); | 401 | |
| 380 | flow_offload_mangle(entry, flow_offload_l4proto(flow), offset, | 402 | flow_offload_mangle(entry, flow_offload_l4proto(flow), offset, |
| 381 | &port, &mask); | 403 | &port, &mask); |
| 382 | } | 404 | } |
| @@ -759,9 +781,9 @@ void nf_flow_offload_stats(struct nf_flowtable *flowtable, · 376 unmodified lines | |||
| 759 | struct flow_offload *flow) | 781 | struct flow_offload *flow) |
| 760 | { | 782 | { |
| 761 | struct flow_offload_work *offload; | 783 | struct flow_offload_work *offload; |
| 762 | s64 delta; | 784 | __s32 delta; |
| 763 | 785 | ||
| 764 | delta = flow->timeout - jiffies; | 786 | delta = nf_flow_timeout_delta(flow->timeout); |
| 765 | if ((delta >= (9 * NF_FLOW_TIMEOUT) / 10) || | 787 | if ((delta >= (9 * NF_FLOW_TIMEOUT) / 10) || |
| 766 | flow->flags & FLOW_OFFLOAD_HW_DYING) | 788 | flow->flags & FLOW_OFFLOAD_HW_DYING) |
| 767 | return; | 789 | return; |
| @@ -5984,6 +5984,7 @@ nft_flowtable_type_get(struct net *net, u8 family) · 5983 unmodified lines | |||
| 5984 | return ERR_PTR(-ENOENT); | 5984 | return ERR_PTR(-ENOENT); |
| 5985 | } | 5985 | } |
| 5986 | 5986 | ||
| 5987 | /* Only called from error and netdev event paths. */ | ||
| 5987 | static void nft_unregister_flowtable_hook(struct net *net, | 5988 | static void nft_unregister_flowtable_hook(struct net *net, |
| 5988 | struct nft_flowtable *flowtable, | 5989 | struct nft_flowtable *flowtable, |
| 5989 | struct nft_hook *hook) | 5990 | struct nft_hook *hook) |
| @@ -5999,7 +6000,7 @@ static void nft_unregister_flowtable_net_hooks(struct net *net, · 9 unmodified lines | |||
| 5999 | struct nft_hook *hook; | 6000 | struct nft_hook *hook; |
| 6000 | 6001 | ||
| 6001 | list_for_each_entry(hook, &flowtable->hook_list, list) | 6002 | list_for_each_entry(hook, &flowtable->hook_list, list) |
| 6002 | nft_unregister_flowtable_hook(net, flowtable, hook); | 6003 | nf_unregister_net_hook(net, &hook->ops); |
| 6003 | } | 6004 | } |
| 6004 | 6005 | ||
| 6005 | static int nft_register_flowtable_net_hooks(struct net *net, | 6006 | static int nft_register_flowtable_net_hooks(struct net *net, |
| @@ -6448,12 +6449,14 @@ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) · 442 unmodified lines | |||
| 6448 | { | 6449 | { |
| 6449 | struct nft_hook *hook, *next; | 6450 | struct nft_hook *hook, *next; |
| 6450 | 6451 | ||
| 6452 | flowtable->data.type->free(&flowtable->data); | ||
| 6451 | list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { | 6453 | list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { |
| 6454 | flowtable->data.type->setup(&flowtable->data, hook->ops.dev, | ||
| 6455 | FLOW_BLOCK_UNBIND); | ||
| 6452 | list_del_rcu(&hook->list); | 6456 | list_del_rcu(&hook->list); |
| 6453 | kfree(hook); | 6457 | kfree(hook); |
| 6454 | } | 6458 | } |
| 6455 | kfree(flowtable->name); | 6459 | kfree(flowtable->name); |
| 6456 | flowtable->data.type->free(&flowtable->data); | ||
| 6457 | module_put(flowtable->data.type->owner); | 6460 | module_put(flowtable->data.type->owner); |
| 6458 | kfree(flowtable); | 6461 | kfree(flowtable); |
| 6459 | } | 6462 | } |
| @@ -6497,6 +6500,7 @@ static void nft_flowtable_event(unsigned long event, struct net_device *dev, · 37 unmodified lines | |||
| 6497 | if (hook->ops.dev != dev) | 6500 | if (hook->ops.dev != dev) |
| 6498 | continue; | 6501 | continue; |
| 6499 | 6502 | ||
| 6503 | /* flow_offload_netdev_event() cleans up entries for us. */ | ||
| 6500 | nft_unregister_flowtable_hook(dev_net(dev), flowtable, hook); | 6504 | nft_unregister_flowtable_hook(dev_net(dev), flowtable, hook); |
| 6501 | list_del_rcu(&hook->list); | 6505 | list_del_rcu(&hook->list); |
| 6502 | kfree_rcu(hook, rcu); | 6506 | kfree_rcu(hook, rcu); |
| @@ -200,9 +200,6 @@ static void nft_flow_offload_activate(const struct nft_ctx *ctx, · 199 unmodified lines | |||
| 200 | static void nft_flow_offload_destroy(const struct nft_ctx *ctx, | 200 | static void nft_flow_offload_destroy(const struct nft_ctx *ctx, |
| 201 | const struct nft_expr *expr) | 201 | const struct nft_expr *expr) |
| 202 | { | 202 | { |
| 203 | struct nft_flow_offload *priv = nft_expr_priv(expr); | ||
| 204 | |||
| 205 | priv->flowtable->use--; | ||
| 206 | nf_ct_netns_put(ctx->net, ctx->family); | 203 | nf_ct_netns_put(ctx->net, ctx->family); |
| 207 | } | 204 | } |
| 208 | 205 | ||
| @@ -50,7 +50,7 @@ static void nft_tproxy_eval_v4(const struct nft_expr *expr, · 49 unmodified lines | |||
| 50 | taddr = nf_tproxy_laddr4(skb, taddr, iph->daddr); | 50 | taddr = nf_tproxy_laddr4(skb, taddr, iph->daddr); |
| 51 | 51 | ||
| 52 | if (priv->sreg_port) | 52 | if (priv->sreg_port) |
| 53 | tport = regs->data[priv->sreg_port]; | 53 | tport = nft_reg_load16(®s->data[priv->sreg_port]); |
| 54 | if (!tport) | 54 | if (!tport) |
| 55 | tport = hp->dest; | 55 | tport = hp->dest; |
| 56 | 56 | ||
| @@ -117,7 +117,7 @@ static void nft_tproxy_eval_v6(const struct nft_expr *expr, · 60 unmodified lines | |||
| 117 | taddr = *nf_tproxy_laddr6(skb, &taddr, &iph->daddr); | 117 | taddr = *nf_tproxy_laddr6(skb, &taddr, &iph->daddr); |
| 118 | 118 | ||
| 119 | if (priv->sreg_port) | 119 | if (priv->sreg_port) |
| 120 | tport = regs->data[priv->sreg_port]; | 120 | tport = nft_reg_load16(®s->data[priv->sreg_port]); |
| 121 | if (!tport) | 121 | if (!tport) |
| 122 | tport = hp->dest; | 122 | tport = hp->dest; |
| 123 | 123 | ||
| @@ -196,7 +196,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, · 195 unmodified lines | |||
| 196 | hdr->size = cpu_to_le32(len); | 196 | hdr->size = cpu_to_le32(len); |
| 197 | hdr->confirm_rx = 0; | 197 | hdr->confirm_rx = 0; |
| 198 | 198 | ||
| 199 | skb_put_padto(skb, ALIGN(len, 4)); | 199 | skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr)); |
| 200 | 200 | ||
| 201 | mutex_lock(&node->ep_lock); | 201 | mutex_lock(&node->ep_lock); |
| 202 | if (node->ep) | 202 | if (node->ep) |
| @@ -209,6 +209,7 @@ struct rxrpc_skb_priv { · 208 unmodified lines | |||
| 209 | struct rxrpc_security { | 209 | struct rxrpc_security { |
| 210 | const char *name; /* name of this service */ | 210 | const char *name; /* name of this service */ |
| 211 | u8 security_index; /* security type provided */ | 211 | u8 security_index; /* security type provided */ |
| 212 | u32 no_key_abort; /* Abort code indicating no key */ | ||
| 212 | 213 | ||
| 213 | /* Initialise a security service */ | 214 | /* Initialise a security service */ |
| 214 | int (*init)(void); | 215 | int (*init)(void); |
| @@ -977,8 +978,9 @@ static inline void rxrpc_reduce_conn_timer(struct rxrpc_connection *conn, · 762 unmodified lines | |||
| 977 | struct rxrpc_connection *rxrpc_find_service_conn_rcu(struct rxrpc_peer *, | 978 | struct rxrpc_connection *rxrpc_find_service_conn_rcu(struct rxrpc_peer *, |
| 978 | struct sk_buff *); | 979 | struct sk_buff *); |
| 979 | struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *, gfp_t); | 980 | struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *, gfp_t); |
| 980 | void rxrpc_new_incoming_connection(struct rxrpc_sock *, | 981 | void rxrpc_new_incoming_connection(struct rxrpc_sock *, struct rxrpc_connection *, |
| 981 | struct rxrpc_connection *, struct sk_buff *); | 982 | const struct rxrpc_security *, struct key *, |
| 983 | struct sk_buff *); | ||
| 982 | void rxrpc_unpublish_service_conn(struct rxrpc_connection *); | 984 | void rxrpc_unpublish_service_conn(struct rxrpc_connection *); |
| 983 | 985 | ||
| 984 | /* | 986 | /* |
| @@ -1103,7 +1105,9 @@ extern const struct rxrpc_security rxkad; · 118 unmodified lines | |||
| 1103 | int __init rxrpc_init_security(void); | 1105 | int __init rxrpc_init_security(void); |
| 1104 | void rxrpc_exit_security(void); | 1106 | void rxrpc_exit_security(void); |
| 1105 | int rxrpc_init_client_conn_security(struct rxrpc_connection *); | 1107 | int rxrpc_init_client_conn_security(struct rxrpc_connection *); |
| 1106 | int rxrpc_init_server_conn_security(struct rxrpc_connection *); | 1108 | bool rxrpc_look_up_server_security(struct rxrpc_local *, struct rxrpc_sock *, |
| 1109 | const struct rxrpc_security **, struct key **, | ||
| 1110 | struct sk_buff *); | ||
| 1107 | 1111 | ||
| 1108 | /* | 1112 | /* |
| 1109 | * sendmsg.c | 1113 | * sendmsg.c |
| @@ -239,6 +239,22 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx) · 238 unmodified lines | |||
| 239 | kfree(b); | 239 | kfree(b); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | /* | ||
| 243 | * Ping the other end to fill our RTT cache and to retrieve the rwind | ||
| 244 | * and MTU parameters. | ||
| 245 | */ | ||
| 246 | static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb) | ||
| 247 | { | ||
| 248 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | ||
| 249 | ktime_t now = skb->tstamp; | ||
| 250 | |||
| 251 | if (call->peer->rtt_usage < 3 || | ||
| 252 | ktime_before(ktime_add_ms(call->peer->rtt_last_req, 1000), now)) | ||
| 253 | rxrpc_propose_ACK(call, RXRPC_ACK_PING, sp->hdr.serial, | ||
| 254 | true, true, | ||
| 255 | rxrpc_propose_ack_ping_for_params); | ||
| 256 | } | ||
| 257 | |||
| 242 | /* | 258 | /* |
| 243 | * Allocate a new incoming call from the prealloc pool, along with a connection | 259 | * Allocate a new incoming call from the prealloc pool, along with a connection |
| 244 | * and a peer as necessary. | 260 | * and a peer as necessary. |
| @@ -247,6 +263,8 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx, · 2 unmodified lines | |||
| 247 | struct rxrpc_local *local, | 263 | struct rxrpc_local *local, |
| 248 | struct rxrpc_peer *peer, | 264 | struct rxrpc_peer *peer, |
| 249 | struct rxrpc_connection *conn, | 265 | struct rxrpc_connection *conn, |
| 266 | const struct rxrpc_security *sec, | ||
| 267 | struct key *key, | ||
| 250 | struct sk_buff *skb) | 268 | struct sk_buff *skb) |
| 251 | { | 269 | { |
| 252 | struct rxrpc_backlog *b = rx->backlog; | 270 | struct rxrpc_backlog *b = rx->backlog; |
| @@ -294,7 +312,7 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx, · 41 unmodified lines | |||
| 294 | conn->params.local = rxrpc_get_local(local); | 312 | conn->params.local = rxrpc_get_local(local); |
| 295 | conn->params.peer = peer; | 313 | conn->params.peer = peer; |
| 296 | rxrpc_see_connection(conn); | 314 | rxrpc_see_connection(conn); |
| 297 | rxrpc_new_incoming_connection(rx, conn, skb); | 315 | rxrpc_new_incoming_connection(rx, conn, sec, key, skb); |
| 298 | } else { | 316 | } else { |
| 299 | rxrpc_get_connection(conn); | 317 | rxrpc_get_connection(conn); |
| 300 | } | 318 | } |
| @@ -333,9 +351,11 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, · 32 unmodified lines | |||
| 333 | struct sk_buff *skb) | 351 | struct sk_buff *skb) |
| 334 | { | 352 | { |
| 335 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | 353 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 354 | const struct rxrpc_security *sec = NULL; | ||
| 336 | struct rxrpc_connection *conn; | 355 | struct rxrpc_connection *conn; |
| 337 | struct rxrpc_peer *peer = NULL; | 356 | struct rxrpc_peer *peer = NULL; |
| 338 | struct rxrpc_call *call; | 357 | struct rxrpc_call *call = NULL; |
| 358 | struct key *key = NULL; | ||
| 339 | 359 | ||
| 340 | _enter(""); | 360 | _enter(""); |
| 341 | 361 | ||
| @@ -346,9 +366,7 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, · 4 unmodified lines | |||
| 346 | sp->hdr.seq, RX_INVALID_OPERATION, ESHUTDOWN); | 366 | sp->hdr.seq, RX_INVALID_OPERATION, ESHUTDOWN); |
| 347 | skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; | 367 | skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; |
| 348 | skb->priority = RX_INVALID_OPERATION; | 368 | skb->priority = RX_INVALID_OPERATION; |
| 349 | _leave(" = NULL [close]"); | 369 | goto no_call; |
| 350 | call = NULL; | ||
| 351 | goto out; | ||
| 352 | } | 370 | } |
| 353 | 371 | ||
| 354 | /* The peer, connection and call may all have sprung into existence due | 372 | /* The peer, connection and call may all have sprung into existence due |
| @@ -358,29 +376,19 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, · 3 unmodified lines | |||
| 358 | */ | 376 | */ |
| 359 | conn = rxrpc_find_connection_rcu(local, skb, &peer); | 377 | conn = rxrpc_find_connection_rcu(local, skb, &peer); |
| 360 | 378 | ||
| 361 | call = rxrpc_alloc_incoming_call(rx, local, peer, conn, skb); | 379 | if (!conn && !rxrpc_look_up_server_security(local, rx, &sec, &key, skb)) |
| 380 | goto no_call; | ||
| 381 | |||
| 382 | call = rxrpc_alloc_incoming_call(rx, local, peer, conn, sec, key, skb); | ||
| 383 | key_put(key); | ||
| 362 | if (!call) { | 384 | if (!call) { |
| 363 | skb->mark = RXRPC_SKB_MARK_REJECT_BUSY; | 385 | skb->mark = RXRPC_SKB_MARK_REJECT_BUSY; |
| 364 | _leave(" = NULL [busy]"); | 386 | goto no_call; |
| 365 | call = NULL; | ||
| 366 | goto out; | ||
| 367 | } | 387 | } |
| 368 | 388 | ||
| 369 | trace_rxrpc_receive(call, rxrpc_receive_incoming, | 389 | trace_rxrpc_receive(call, rxrpc_receive_incoming, |
| 370 | sp->hdr.serial, sp->hdr.seq); | 390 | sp->hdr.serial, sp->hdr.seq); |
| 371 | 391 | ||
| 372 | /* Lock the call to prevent rxrpc_kernel_send/recv_data() and | ||
| 373 | * sendmsg()/recvmsg() inconveniently stealing the mutex once the | ||
| 374 | * notification is generated. | ||
| 375 | * | ||
| 376 | * The BUG should never happen because the kernel should be well | ||
| 377 | * behaved enough not to access the call before the first notification | ||
| 378 | * event and userspace is prevented from doing so until the state is | ||
| 379 | * appropriate. | ||
| 380 | */ | ||
| 381 | if (!mutex_trylock(&call->user_mutex)) | ||
| 382 | BUG(); | ||
| 383 | |||
| 384 | /* Make the call live. */ | 392 | /* Make the call live. */ |
| 385 | rxrpc_incoming_call(rx, call, skb); | 393 | rxrpc_incoming_call(rx, call, skb); |
| 386 | conn = call->conn; | 394 | conn = call->conn; |
| @@ -421,6 +429,9 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, · 34 unmodified lines | |||
| 421 | BUG(); | 429 | BUG(); |
| 422 | } | 430 | } |
| 423 | spin_unlock(&conn->state_lock); | 431 | spin_unlock(&conn->state_lock); |
| 432 | spin_unlock(&rx->incoming_lock); | ||
| 433 | |||
| 434 | rxrpc_send_ping(call, skb); | ||
| 424 | 435 | ||
| 425 | if (call->state == RXRPC_CALL_SERVER_ACCEPTING) | 436 | if (call->state == RXRPC_CALL_SERVER_ACCEPTING) |
| 426 | rxrpc_notify_socket(call); | 437 | rxrpc_notify_socket(call); |
| @@ -433,9 +444,12 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, · 6 unmodified lines | |||
| 433 | rxrpc_put_call(call, rxrpc_call_put); | 444 | rxrpc_put_call(call, rxrpc_call_put); |
| 434 | 445 | ||
| 435 | _leave(" = %p{%d}", call, call->debug_id); | 446 | _leave(" = %p{%d}", call, call->debug_id); |
| 436 | out: | ||
| 437 | spin_unlock(&rx->incoming_lock); | ||
| 438 | return call; | 447 | return call; |
| 448 | |||
| 449 | no_call: | ||
| 450 | spin_unlock(&rx->incoming_lock); | ||
| 451 | _leave(" = NULL [%u]", skb->mark); | ||
| 452 | return NULL; | ||
| 439 | } | 453 | } |
| 440 | 454 | ||
| 441 | /* | 455 | /* |
| @@ -376,21 +376,7 @@ static void rxrpc_secure_connection(struct rxrpc_connection *conn) · 375 unmodified lines | |||
| 376 | _enter("{%d}", conn->debug_id); | 376 | _enter("{%d}", conn->debug_id); |
| 377 | 377 | ||
| 378 | ASSERT(conn->security_ix != 0); | 378 | ASSERT(conn->security_ix != 0); |
| 379 | 379 | ASSERT(conn->server_key); | |
| 380 | if (!conn->params.key) { | ||
| 381 | _debug("set up security"); | ||
| 382 | ret = rxrpc_init_server_conn_security(conn); | ||
| 383 | switch (ret) { | ||
| 384 | case 0: | ||
| 385 | break; | ||
| 386 | case -ENOENT: | ||
| 387 | abort_code = RX_CALL_DEAD; | ||
| 388 | goto abort; | ||
| 389 | default: | ||
| 390 | abort_code = RXKADNOAUTH; | ||
| 391 | goto abort; | ||
| 392 | } | ||
| 393 | } | ||
| 394 | 380 | ||
| 395 | if (conn->security->issue_challenge(conn) < 0) { | 381 | if (conn->security->issue_challenge(conn) < 0) { |
| 396 | abort_code = RX_CALL_DEAD; | 382 | abort_code = RX_CALL_DEAD; |
| @@ -148,6 +148,8 @@ struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *rxn · 147 unmodified lines | |||
| 148 | */ | 148 | */ |
| 149 | void rxrpc_new_incoming_connection(struct rxrpc_sock *rx, | 149 | void rxrpc_new_incoming_connection(struct rxrpc_sock *rx, |
| 150 | struct rxrpc_connection *conn, | 150 | struct rxrpc_connection *conn, |
| 151 | const struct rxrpc_security *sec, | ||
| 152 | struct key *key, | ||
| 151 | struct sk_buff *skb) | 153 | struct sk_buff *skb) |
| 152 | { | 154 | { |
| 153 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | 155 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| @@ -160,6 +162,8 @@ void rxrpc_new_incoming_connection(struct rxrpc_sock *rx, · 6 unmodified lines | |||
| 160 | conn->service_id = sp->hdr.serviceId; | 162 | conn->service_id = sp->hdr.serviceId; |
| 161 | conn->security_ix = sp->hdr.securityIndex; | 163 | conn->security_ix = sp->hdr.securityIndex; |
| 162 | conn->out_clientflag = 0; | 164 | conn->out_clientflag = 0; |
| 165 | conn->security = sec; | ||
| 166 | conn->server_key = key_get(key); | ||
| 163 | if (conn->security_ix) | 167 | if (conn->security_ix) |
| 164 | conn->state = RXRPC_CONN_SERVICE_UNSECURED; | 168 | conn->state = RXRPC_CONN_SERVICE_UNSECURED; |
| 165 | else | 169 | else |
| @@ -192,22 +192,6 @@ send_extra_data: · 191 unmodified lines | |||
| 192 | goto out_no_clear_ca; | 192 | goto out_no_clear_ca; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | /* | ||
| 196 | * Ping the other end to fill our RTT cache and to retrieve the rwind | ||
| 197 | * and MTU parameters. | ||
| 198 | */ | ||
| 199 | static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb) | ||
| 200 | { | ||
| 201 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | ||
| 202 | ktime_t now = skb->tstamp; | ||
| 203 | |||
| 204 | if (call->peer->rtt_usage < 3 || | ||
| 205 | ktime_before(ktime_add_ms(call->peer->rtt_last_req, 1000), now)) | ||
| 206 | rxrpc_propose_ACK(call, RXRPC_ACK_PING, sp->hdr.serial, | ||
| 207 | true, true, | ||
| 208 | rxrpc_propose_ack_ping_for_params); | ||
| 209 | } | ||
| 210 | |||
| 211 | /* | 195 | /* |
| 212 | * Apply a hard ACK by advancing the Tx window. | 196 | * Apply a hard ACK by advancing the Tx window. |
| 213 | */ | 197 | */ |
| @@ -1396,8 +1380,6 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb) · 1182 unmodified lines | |||
| 1396 | call = rxrpc_new_incoming_call(local, rx, skb); | 1380 | call = rxrpc_new_incoming_call(local, rx, skb); |
| 1397 | if (!call) | 1381 | if (!call) |
| 1398 | goto reject_packet; | 1382 | goto reject_packet; |
| 1399 | rxrpc_send_ping(call, skb); | ||
| 1400 | mutex_unlock(&call->user_mutex); | ||
| 1401 | } | 1383 | } |
| 1402 | 1384 | ||
| 1403 | /* Process a call packet; this either discards or passes on the ref | 1385 | /* Process a call packet; this either discards or passes on the ref |
| @@ -648,9 +648,9 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn) · 647 unmodified lines | |||
| 648 | u32 serial; | 648 | u32 serial; |
| 649 | int ret; | 649 | int ret; |
| 650 | 650 | ||
| 651 | _enter("{%d,%x}", conn->debug_id, key_serial(conn->params.key)); | 651 | _enter("{%d,%x}", conn->debug_id, key_serial(conn->server_key)); |
| 652 | 652 | ||
| 653 | ret = key_validate(conn->params.key); | 653 | ret = key_validate(conn->server_key); |
| 654 | if (ret < 0) | 654 | if (ret < 0) |
| 655 | return ret; | 655 | return ret; |
| 656 | 656 | ||
| @@ -1293,6 +1293,7 @@ static void rxkad_exit(void) · 636 unmodified lines | |||
| 1293 | const struct rxrpc_security rxkad = { | 1293 | const struct rxrpc_security rxkad = { |
| 1294 | .name = "rxkad", | 1294 | .name = "rxkad", |
| 1295 | .security_index = RXRPC_SECURITY_RXKAD, | 1295 | .security_index = RXRPC_SECURITY_RXKAD, |
| 1296 | .no_key_abort = RXKADUNKNOWNKEY, | ||
| 1296 | .init = rxkad_init, | 1297 | .init = rxkad_init, |
| 1297 | .exit = rxkad_exit, | 1298 | .exit = rxkad_exit, |
| 1298 | .init_connection_security = rxkad_init_connection_security, | 1299 | .init_connection_security = rxkad_init_connection_security, |
| @@ -101,62 +101,58 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) · 100 unmodified lines | |||
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* | 103 | /* |
| 104 | * initialise the security on a server connection | 104 | * Find the security key for a server connection. |
| 105 | */ | 105 | */ |
| 106 | int rxrpc_init_server_conn_security(struct rxrpc_connection *conn) | 106 | bool rxrpc_look_up_server_security(struct rxrpc_local *local, struct rxrpc_sock *rx, |
| 107 | const struct rxrpc_security **_sec, | ||
| 108 | struct key **_key, | ||
| 109 | struct sk_buff *skb) | ||
| 107 | { | 110 | { |
| 108 | const struct rxrpc_security *sec; | 111 | const struct rxrpc_security *sec; |
| 109 | struct rxrpc_local *local = conn->params.local; | 112 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 110 | struct rxrpc_sock *rx; | 113 | key_ref_t kref = NULL; |
| 111 | struct key *key; | ||
| 112 | key_ref_t kref; | ||
| 113 | char kdesc[5 + 1 + 3 + 1]; | 114 | char kdesc[5 + 1 + 3 + 1]; |
| 114 | 115 | ||
| 115 | _enter(""); | 116 | _enter(""); |
| 116 | 117 | ||
| 117 | sprintf(kdesc, "%u:%u", conn->service_id, conn->security_ix); | 118 | sprintf(kdesc, "%u:%u", sp->hdr.serviceId, sp->hdr.securityIndex); |
| 118 | 119 | ||
| 119 | sec = rxrpc_security_lookup(conn->security_ix); | 120 | sec = rxrpc_security_lookup(sp->hdr.securityIndex); |
| 120 | if (!sec) { | 121 | if (!sec) { |
| 121 | _leave(" = -ENOKEY [lookup]"); | 122 | trace_rxrpc_abort(0, "SVS", |
| 122 | return -ENOKEY; | 123 | sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, |
| 124 | RX_INVALID_OPERATION, EKEYREJECTED); | ||
| 125 | skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; | ||
| 126 | skb->priority = RX_INVALID_OPERATION; | ||
| 127 | return false; | ||
| 123 | } | 128 | } |
| 124 | 129 | ||
| 125 | /* find the service */ | 130 | if (sp->hdr.securityIndex == RXRPC_SECURITY_NONE) |
| 126 | read_lock(&local->services_lock); | 131 | goto out; |
| 127 | rx = rcu_dereference_protected(local->service, | ||
| 128 | lockdep_is_held(&local->services_lock)); | ||
| 129 | if (rx && (rx->srx.srx_service == conn->service_id || | ||
| 130 | rx->second_service == conn->service_id)) | ||
| 131 | goto found_service; | ||
| 132 | 132 | ||
| 133 | /* the service appears to have died */ | ||
| 134 | read_unlock(&local->services_lock); | ||
| 135 | _leave(" = -ENOENT"); | ||
| 136 | return -ENOENT; | ||
| 137 | |||
| 138 | found_service: | ||
| 139 | if (!rx->securities) { | 133 | if (!rx->securities) { |
| 140 | read_unlock(&local->services_lock); | 134 | trace_rxrpc_abort(0, "SVR", |
| 141 | _leave(" = -ENOKEY"); | 135 | sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, |
| 142 | return -ENOKEY; | 136 | RX_INVALID_OPERATION, EKEYREJECTED); |
| 137 | skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; | ||
| 138 | skb->priority = RX_INVALID_OPERATION; | ||
| 139 | return false; | ||
| 143 | } | 140 | } |
| 144 | 141 | ||
| 145 | /* look through the service's keyring */ | 142 | /* look through the service's keyring */ |
| 146 | kref = keyring_search(make_key_ref(rx->securities, 1UL), | 143 | kref = keyring_search(make_key_ref(rx->securities, 1UL), |
| 147 | &key_type_rxrpc_s, kdesc, true); | 144 | &key_type_rxrpc_s, kdesc, true); |
| 148 | if (IS_ERR(kref)) { | 145 | if (IS_ERR(kref)) { |
| 149 | read_unlock(&local->services_lock); | 146 | trace_rxrpc_abort(0, "SVK", |
| 150 | _leave(" = %ld [search]", PTR_ERR(kref)); | 147 | sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, |
| 151 | return PTR_ERR(kref); | 148 | sec->no_key_abort, EKEYREJECTED); |
| 149 | skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; | ||
| 150 | skb->priority = sec->no_key_abort; | ||
| 151 | return false; | ||
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | key = key_ref_to_ptr(kref); | 154 | out: |
| 155 | read_unlock(&local->services_lock); | 155 | *_sec = sec; |
| 156 | 156 | *_key = key_ref_to_ptr(kref); | |
| 157 | conn->server_key = key; | 157 | return true; |
| 158 | conn->security = sec; | ||
| 159 | |||
| 160 | _leave(" = 0"); | ||
| 161 | return 0; | ||
| 162 | } | 158 | } |
| @@ -219,8 +219,10 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, · 218 unmodified lines | |||
| 219 | bool use_reinsert; | 219 | bool use_reinsert; |
| 220 | bool want_ingress; | 220 | bool want_ingress; |
| 221 | bool is_redirect; | 221 | bool is_redirect; |
| 222 | bool expects_nh; | ||
| 222 | int m_eaction; | 223 | int m_eaction; |
| 223 | int mac_len; | 224 | int mac_len; |
| 225 | bool at_nh; | ||
| 224 | 226 | ||
| 225 | rec_level = __this_cpu_inc_return(mirred_rec_level); | 227 | rec_level = __this_cpu_inc_return(mirred_rec_level); |
| 226 | if (unlikely(rec_level > MIRRED_RECURSION_LIMIT)) { | 228 | if (unlikely(rec_level > MIRRED_RECURSION_LIMIT)) { |
| @@ -261,19 +263,19 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, · 34 unmodified lines | |||
| 261 | goto out; | 263 | goto out; |
| 262 | } | 264 | } |
| 263 | 265 | ||
| 264 | /* If action's target direction differs than filter's direction, | ||
| 265 | * and devices expect a mac header on xmit, then mac push/pull is | ||
| 266 | * needed. | ||
| 267 | */ | ||
| 268 | want_ingress = tcf_mirred_act_wants_ingress(m_eaction); | 266 | want_ingress = tcf_mirred_act_wants_ingress(m_eaction); |
| 269 | if (skb_at_tc_ingress(skb) != want_ingress && m_mac_header_xmit) { | 267 | |
| 270 | if (!skb_at_tc_ingress(skb)) { | 268 | expects_nh = want_ingress || !m_mac_header_xmit; |
| 271 | /* caught at egress, act ingress: pull mac */ | 269 | at_nh = skb->data == skb_network_header(skb); |
| 272 | mac_len = skb_network_header(skb) - skb_mac_header(skb); | 270 | if (at_nh != expects_nh) { |
| 271 | mac_len = skb_at_tc_ingress(skb) ? skb->mac_len : | ||
| 272 | skb_network_header(skb) - skb_mac_header(skb); | ||
| 273 | if (expects_nh) { | ||
| 274 | /* target device/action expect data at nh */ | ||
| 273 | skb_pull_rcsum(skb2, mac_len); | 275 | skb_pull_rcsum(skb2, mac_len); |
| 274 | } else { | 276 | } else { |
| 275 | /* caught at ingress, act egress: push mac */ | 277 | /* target device/action expect data at mac */ |
| 276 | skb_push_rcsum(skb2, skb->mac_len); | 278 | skb_push_rcsum(skb2, mac_len); |
| 277 | } | 279 | } |
| 278 | } | 280 | } |
| 279 | 281 | ||
| @@ -308,33 +308,12 @@ static void tcf_proto_put(struct tcf_proto *tp, bool rtnl_held, · 307 unmodified lines | |||
| 308 | tcf_proto_destroy(tp, rtnl_held, true, extack); | 308 | tcf_proto_destroy(tp, rtnl_held, true, extack); |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | static int walker_check_empty(struct tcf_proto *tp, void *fh, | 311 | static bool tcf_proto_check_delete(struct tcf_proto *tp) |
| 312 | struct tcf_walker *arg) | ||
| 313 | { | 312 | { |
| 314 | if (fh) { | 313 | if (tp->ops->delete_empty) |
| 315 | arg->nonempty = true; | 314 | return tp->ops->delete_empty(tp); |
| 316 | return -1; | ||
| 317 | } | ||
| 318 | return 0; | ||
| 319 | } | ||
| 320 | |||
| 321 | static bool tcf_proto_is_empty(struct tcf_proto *tp, bool rtnl_held) | ||
| 322 | { | ||
| 323 | struct tcf_walker walker = { .fn = walker_check_empty, }; | ||
| 324 | |||
| 325 | if (tp->ops->walk) { | ||
| 326 | tp->ops->walk(tp, &walker, rtnl_held); | ||
| 327 | return !walker.nonempty; | ||
| 328 | } | ||
| 329 | return true; | ||
| 330 | } | ||
| 331 | 315 | ||
| 332 | static bool tcf_proto_check_delete(struct tcf_proto *tp, bool rtnl_held) | 316 | tp->deleting = true; |
| 333 | { | ||
| 334 | spin_lock(&tp->lock); | ||
| 335 | if (tcf_proto_is_empty(tp, rtnl_held)) | ||
| 336 | tp->deleting = true; | ||
| 337 | spin_unlock(&tp->lock); | ||
| 338 | return tp->deleting; | 317 | return tp->deleting; |
| 339 | } | 318 | } |
| 340 | 319 | ||
| @@ -1751,7 +1730,7 @@ static void tcf_chain_tp_delete_empty(struct tcf_chain *chain, · 1410 unmodified lines | |||
| 1751 | * concurrently. | 1730 | * concurrently. |
| 1752 | * Mark tp for deletion if it is empty. | 1731 | * Mark tp for deletion if it is empty. |
| 1753 | */ | 1732 | */ |
| 1754 | if (!tp_iter || !tcf_proto_check_delete(tp, rtnl_held)) { | 1733 | if (!tp_iter || !tcf_proto_check_delete(tp)) { |
| 1755 | mutex_unlock(&chain->filter_chain_lock); | 1734 | mutex_unlock(&chain->filter_chain_lock); |
| 1756 | return; | 1735 | return; |
| 1757 | } | 1736 | } |
| @@ -2773,6 +2773,17 @@ static void fl_bind_class(void *fh, u32 classid, unsigned long cl) · 2772 unmodified lines | |||
| 2773 | f->res.class = cl; | 2773 | f->res.class = cl; |
| 2774 | } | 2774 | } |
| 2775 | 2775 | ||
| 2776 | static bool fl_delete_empty(struct tcf_proto *tp) | ||
| 2777 | { | ||
| 2778 | struct cls_fl_head *head = fl_head_dereference(tp); | ||
| 2779 | |||
| 2780 | spin_lock(&tp->lock); | ||
| 2781 | tp->deleting = idr_is_empty(&head->handle_idr); | ||
| 2782 | spin_unlock(&tp->lock); | ||
| 2783 | |||
| 2784 | return tp->deleting; | ||
| 2785 | } | ||
| 2786 | |||
| 2776 | static struct tcf_proto_ops cls_fl_ops __read_mostly = { | 2787 | static struct tcf_proto_ops cls_fl_ops __read_mostly = { |
| 2777 | .kind = "flower", | 2788 | .kind = "flower", |
| 2778 | .classify = fl_classify, | 2789 | .classify = fl_classify, |
| @@ -2782,6 +2793,7 @@ static struct tcf_proto_ops cls_fl_ops __read_mostly = { · 3 unmodified lines | |||
| 2782 | .put = fl_put, | 2793 | .put = fl_put, |
| 2783 | .change = fl_change, | 2794 | .change = fl_change, |
| 2784 | .delete = fl_delete, | 2795 | .delete = fl_delete, |
| 2796 | .delete_empty = fl_delete_empty, | ||
| 2785 | .walk = fl_walk, | 2797 | .walk = fl_walk, |
| 2786 | .reoffload = fl_reoffload, | 2798 | .reoffload = fl_reoffload, |
| 2787 | .hw_add = fl_hw_add, | 2799 | .hw_add = fl_hw_add, |
| @@ -1108,33 +1108,10 @@ erridr: · 1107 unmodified lines | |||
| 1108 | return err; | 1108 | return err; |
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | static bool u32_hnode_empty(struct tc_u_hnode *ht, bool *non_root_ht) | ||
| 1112 | { | ||
| 1113 | int i; | ||
| 1114 | |||
| 1115 | if (!ht) | ||
| 1116 | return true; | ||
| 1117 | if (!ht->is_root) { | ||
| 1118 | *non_root_ht = true; | ||
| 1119 | return false; | ||
| 1120 | } | ||
| 1121 | if (*non_root_ht) | ||
| 1122 | return false; | ||
| 1123 | if (ht->refcnt < 2) | ||
| 1124 | return true; | ||
| 1125 | |||
| 1126 | for (i = 0; i <= ht->divisor; i++) { | ||
| 1127 | if (rtnl_dereference(ht->ht[i])) | ||
| 1128 | return false; | ||
| 1129 | } | ||
| 1130 | return true; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg, | 1111 | static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg, |
| 1134 | bool rtnl_held) | 1112 | bool rtnl_held) |
| 1135 | { | 1113 | { |
| 1136 | struct tc_u_common *tp_c = tp->data; | 1114 | struct tc_u_common *tp_c = tp->data; |
| 1137 | bool non_root_ht = false; | ||
| 1138 | struct tc_u_hnode *ht; | 1115 | struct tc_u_hnode *ht; |
| 1139 | struct tc_u_knode *n; | 1116 | struct tc_u_knode *n; |
| 1140 | unsigned int h; | 1117 | unsigned int h; |
| @@ -1147,8 +1124,6 @@ static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg, · 6 unmodified lines | |||
| 1147 | ht = rtnl_dereference(ht->next)) { | 1124 | ht = rtnl_dereference(ht->next)) { |
| 1148 | if (ht->prio != tp->prio) | 1125 | if (ht->prio != tp->prio) |
| 1149 | continue; | 1126 | continue; |
| 1150 | if (u32_hnode_empty(ht, &non_root_ht)) | ||
| 1151 | return; | ||
| 1152 | if (arg->count >= arg->skip) { | 1127 | if (arg->count >= arg->skip) { |
| 1153 | if (arg->fn(tp, ht, arg) < 0) { | 1128 | if (arg->fn(tp, ht, arg) < 0) { |
| 1154 | arg->stop = 1; | 1129 | arg->stop = 1; |
| @@ -1769,7 +1769,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, · 1768 unmodified lines | |||
| 1769 | q->avg_window_begin)); | 1769 | q->avg_window_begin)); |
| 1770 | u64 b = q->avg_window_bytes * (u64)NSEC_PER_SEC; | 1770 | u64 b = q->avg_window_bytes * (u64)NSEC_PER_SEC; |
| 1771 | 1771 | ||
| 1772 | do_div(b, window_interval); | 1772 | b = div64_u64(b, window_interval); |
| 1773 | q->avg_peak_bandwidth = | 1773 | q->avg_peak_bandwidth = |
| 1774 | cake_ewma(q->avg_peak_bandwidth, b, | 1774 | cake_ewma(q->avg_peak_bandwidth, b, |
| 1775 | b > q->avg_peak_bandwidth ? 2 : 8); | 1775 | b > q->avg_peak_bandwidth ? 2 : 8); |
| @@ -301,6 +301,9 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q) · 300 unmodified lines | |||
| 301 | f->socket_hash != sk->sk_hash)) { | 301 | f->socket_hash != sk->sk_hash)) { |
| 302 | f->credit = q->initial_quantum; | 302 | f->credit = q->initial_quantum; |
| 303 | f->socket_hash = sk->sk_hash; | 303 | f->socket_hash = sk->sk_hash; |
| 304 | if (q->rate_enable) | ||
| 305 | smp_store_release(&sk->sk_pacing_status, | ||
| 306 | SK_PACING_FQ); | ||
| 304 | if (fq_flow_is_throttled(f)) | 307 | if (fq_flow_is_throttled(f)) |
| 305 | fq_flow_unset_throttled(q, f); | 308 | fq_flow_unset_throttled(q, f); |
| 306 | f->time_next_packet = 0ULL; | 309 | f->time_next_packet = 0ULL; |
| @@ -322,8 +325,12 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q) · 15 unmodified lines | |||
| 322 | 325 | ||
| 323 | fq_flow_set_detached(f); | 326 | fq_flow_set_detached(f); |
| 324 | f->sk = sk; | 327 | f->sk = sk; |
| 325 | if (skb->sk == sk) | 328 | if (skb->sk == sk) { |
| 326 | f->socket_hash = sk->sk_hash; | 329 | f->socket_hash = sk->sk_hash; |
| 330 | if (q->rate_enable) | ||
| 331 | smp_store_release(&sk->sk_pacing_status, | ||
| 332 | SK_PACING_FQ); | ||
| 333 | } | ||
| 327 | f->credit = q->initial_quantum; | 334 | f->credit = q->initial_quantum; |
| 328 | 335 | ||
| 329 | rb_link_node(&f->fq_node, parent, p); | 336 | rb_link_node(&f->fq_node, parent, p); |
| @@ -428,17 +435,9 @@ static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch, · 98 unmodified lines | |||
| 428 | f->qlen++; | 435 | f->qlen++; |
| 429 | qdisc_qstats_backlog_inc(sch, skb); | 436 | qdisc_qstats_backlog_inc(sch, skb); |
| 430 | if (fq_flow_is_detached(f)) { | 437 | if (fq_flow_is_detached(f)) { |
| 431 | struct sock *sk = skb->sk; | ||
| 432 | |||
| 433 | fq_flow_add_tail(&q->new_flows, f); | 438 | fq_flow_add_tail(&q->new_flows, f); |
| 434 | if (time_after(jiffies, f->age + q->flow_refill_delay)) | 439 | if (time_after(jiffies, f->age + q->flow_refill_delay)) |
| 435 | f->credit = max_t(u32, f->credit, q->quantum); | 440 | f->credit = max_t(u32, f->credit, q->quantum); |
| 436 | if (sk && q->rate_enable) { | ||
| 437 | if (unlikely(smp_load_acquire(&sk->sk_pacing_status) != | ||
| 438 | SK_PACING_FQ)) | ||
| 439 | smp_store_release(&sk->sk_pacing_status, | ||
| 440 | SK_PACING_FQ); | ||
| 441 | } | ||
| 442 | q->inactive_flows--; | 441 | q->inactive_flows--; |
| 443 | } | 442 | } |
| 444 | 443 | ||
| @@ -787,10 +786,12 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt, · 342 unmodified lines | |||
| 787 | if (tb[TCA_FQ_QUANTUM]) { | 786 | if (tb[TCA_FQ_QUANTUM]) { |
| 788 | u32 quantum = nla_get_u32(tb[TCA_FQ_QUANTUM]); | 787 | u32 quantum = nla_get_u32(tb[TCA_FQ_QUANTUM]); |
| 789 | 788 | ||
| 790 | if (quantum > 0) | 789 | if (quantum > 0 && quantum <= (1 << 20)) { |
| 791 | q->quantum = quantum; | 790 | q->quantum = quantum; |
| 792 | else | 791 | } else { |
| 792 | NL_SET_ERR_MSG_MOD(extack, "invalid quantum"); | ||
| 793 | err = -EINVAL; | 793 | err = -EINVAL; |
| 794 | } | ||
| 794 | } | 795 | } |
| 795 | 796 | ||
| 796 | if (tb[TCA_FQ_INITIAL_QUANTUM]) | 797 | if (tb[TCA_FQ_INITIAL_QUANTUM]) |
| @@ -292,8 +292,14 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, · 291 unmodified lines | |||
| 292 | struct tc_prio_qopt_offload graft_offload; | 292 | struct tc_prio_qopt_offload graft_offload; |
| 293 | unsigned long band = arg - 1; | 293 | unsigned long band = arg - 1; |
| 294 | 294 | ||
| 295 | if (new == NULL) | 295 | if (!new) { |
| 296 | new = &noop_qdisc; | 296 | new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, |
| 297 | TC_H_MAKE(sch->handle, arg), extack); | ||
| 298 | if (!new) | ||
| 299 | new = &noop_qdisc; | ||
| 300 | else | ||
| 301 | qdisc_hash_add(new, true); | ||
| 302 | } | ||
| 297 | 303 | ||
| 298 | *old = qdisc_replace(sch, new, &q->queues[band]); | 304 | *old = qdisc_replace(sch, new, &q->queues[band]); |
| 299 | 305 | ||
| @@ -1363,8 +1363,10 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, · 1362 unmodified lines | |||
| 1363 | /* Generate an INIT ACK chunk. */ | 1363 | /* Generate an INIT ACK chunk. */ |
| 1364 | new_obj = sctp_make_init_ack(asoc, chunk, GFP_ATOMIC, | 1364 | new_obj = sctp_make_init_ack(asoc, chunk, GFP_ATOMIC, |
| 1365 | 0); | 1365 | 0); |
| 1366 | if (!new_obj) | 1366 | if (!new_obj) { |
| 1367 | goto nomem; | 1367 | error = -ENOMEM; |
| 1368 | break; | ||
| 1369 | } | ||
| 1368 | 1370 | ||
| 1369 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 1371 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
| 1370 | SCTP_CHUNK(new_obj)); | 1372 | SCTP_CHUNK(new_obj)); |
| @@ -1386,7 +1388,8 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, · 15 unmodified lines | |||
| 1386 | if (!new_obj) { | 1388 | if (!new_obj) { |
| 1387 | if (cmd->obj.chunk) | 1389 | if (cmd->obj.chunk) |
| 1388 | sctp_chunk_free(cmd->obj.chunk); | 1390 | sctp_chunk_free(cmd->obj.chunk); |
| 1389 | goto nomem; | 1391 | error = -ENOMEM; |
| 1392 | break; | ||
| 1390 | } | 1393 | } |
| 1391 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 1394 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
| 1392 | SCTP_CHUNK(new_obj)); | 1395 | SCTP_CHUNK(new_obj)); |
| @@ -1433,8 +1436,10 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, · 40 unmodified lines | |||
| 1433 | 1436 | ||
| 1434 | /* Generate a SHUTDOWN chunk. */ | 1437 | /* Generate a SHUTDOWN chunk. */ |
| 1435 | new_obj = sctp_make_shutdown(asoc, chunk); | 1438 | new_obj = sctp_make_shutdown(asoc, chunk); |
| 1436 | if (!new_obj) | 1439 | if (!new_obj) { |
| 1437 | goto nomem; | 1440 | error = -ENOMEM; |
| 1441 | break; | ||
| 1442 | } | ||
| 1438 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 1443 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
| 1439 | SCTP_CHUNK(new_obj)); | 1444 | SCTP_CHUNK(new_obj)); |
| 1440 | break; | 1445 | break; |
| @@ -1770,11 +1775,17 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, · 329 unmodified lines | |||
| 1770 | break; | 1775 | break; |
| 1771 | } | 1776 | } |
| 1772 | 1777 | ||
| 1773 | if (error) | 1778 | if (error) { |
| 1779 | cmd = sctp_next_cmd(commands); | ||
| 1780 | while (cmd) { | ||
| 1781 | if (cmd->verb == SCTP_CMD_REPLY) | ||
| 1782 | sctp_chunk_free(cmd->obj.chunk); | ||
| 1783 | cmd = sctp_next_cmd(commands); | ||
| 1784 | } | ||
| 1774 | break; | 1785 | break; |
| 1786 | } | ||
| 1775 | } | 1787 | } |
| 1776 | 1788 | ||
| 1777 | out: | ||
| 1778 | /* If this is in response to a received chunk, wait until | 1789 | /* If this is in response to a received chunk, wait until |
| 1779 | * we are done with the packet to open the queue so that we don't | 1790 | * we are done with the packet to open the queue so that we don't |
| 1780 | * send multiple packets in response to a single request. | 1791 | * send multiple packets in response to a single request. |
| @@ -1789,7 +1800,4 @@ out: · 8 unmodified lines | |||
| 1789 | sp->data_ready_signalled = 0; | 1800 | sp->data_ready_signalled = 0; |
| 1790 | 1801 | ||
| 1791 | return error; | 1802 | return error; |
| 1792 | nomem: | ||
| 1793 | error = -ENOMEM; | ||
| 1794 | goto out; | ||
| 1795 | } | 1803 | } |
| @@ -84,10 +84,8 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, · 83 unmodified lines | |||
| 84 | return 0; | 84 | return 0; |
| 85 | 85 | ||
| 86 | ret = genradix_prealloc(&stream->out, outcnt, gfp); | 86 | ret = genradix_prealloc(&stream->out, outcnt, gfp); |
| 87 | if (ret) { | 87 | if (ret) |
| 88 | genradix_free(&stream->out); | ||
| 89 | return ret; | 88 | return ret; |
| 90 | } | ||
| 91 | 89 | ||
| 92 | stream->outcnt = outcnt; | 90 | stream->outcnt = outcnt; |
| 93 | return 0; | 91 | return 0; |
| @@ -102,10 +100,8 @@ static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt, · 8 unmodified lines | |||
| 102 | return 0; | 100 | return 0; |
| 103 | 101 | ||
| 104 | ret = genradix_prealloc(&stream->in, incnt, gfp); | 102 | ret = genradix_prealloc(&stream->in, incnt, gfp); |
| 105 | if (ret) { | 103 | if (ret) |
| 106 | genradix_free(&stream->in); | ||
| 107 | return ret; | 104 | return ret; |
| 108 | } | ||
| 109 | 105 | ||
| 110 | stream->incnt = incnt; | 106 | stream->incnt = incnt; |
| 111 | return 0; | 107 | return 0; |
| @@ -123,7 +119,7 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, · 11 unmodified lines | |||
| 123 | * a new one with new outcnt to save memory if needed. | 119 | * a new one with new outcnt to save memory if needed. |
| 124 | */ | 120 | */ |
| 125 | if (outcnt == stream->outcnt) | 121 | if (outcnt == stream->outcnt) |
| 126 | goto in; | 122 | goto handle_in; |
| 127 | 123 | ||
| 128 | /* Filter out chunks queued on streams that won't exist anymore */ | 124 | /* Filter out chunks queued on streams that won't exist anymore */ |
| 129 | sched->unsched_all(stream); | 125 | sched->unsched_all(stream); |
| @@ -132,24 +128,28 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, · 2 unmodified lines | |||
| 132 | 128 | ||
| 133 | ret = sctp_stream_alloc_out(stream, outcnt, gfp); | 129 | ret = sctp_stream_alloc_out(stream, outcnt, gfp); |
| 134 | if (ret) | 130 | if (ret) |
| 135 | goto out; | 131 | goto out_err; |
| 136 | 132 | ||
| 137 | for (i = 0; i < stream->outcnt; i++) | 133 | for (i = 0; i < stream->outcnt; i++) |
| 138 | SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; | 134 | SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; |
| 139 | 135 | ||
| 140 | in: | 136 | handle_in: |
| 141 | sctp_stream_interleave_init(stream); | 137 | sctp_stream_interleave_init(stream); |
| 142 | if (!incnt) | 138 | if (!incnt) |
| 143 | goto out; | 139 | goto out; |
| 144 | 140 | ||
| 145 | ret = sctp_stream_alloc_in(stream, incnt, gfp); | 141 | ret = sctp_stream_alloc_in(stream, incnt, gfp); |
| 146 | if (ret) { | 142 | if (ret) |
| 147 | sched->free(stream); | 143 | goto in_err; |
| 148 | genradix_free(&stream->out); | 144 | |
| 149 | stream->outcnt = 0; | 145 | goto out; |
| 150 | goto out; | ||
| 151 | } | ||
| 152 | 146 | ||
| 147 | in_err: | ||
| 148 | sched->free(stream); | ||
| 149 | genradix_free(&stream->in); | ||
| 150 | out_err: | ||
| 151 | genradix_free(&stream->out); | ||
| 152 | stream->outcnt = 0; | ||
| 153 | out: | 153 | out: |
| 154 | return ret; | 154 | return ret; |
| 155 | } | 155 | } |
| @@ -263,7 +263,7 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) · 262 unmodified lines | |||
| 263 | 263 | ||
| 264 | pf->af->from_sk(&addr, sk); | 264 | pf->af->from_sk(&addr, sk); |
| 265 | pf->to_sk_daddr(&t->ipaddr, sk); | 265 | pf->to_sk_daddr(&t->ipaddr, sk); |
| 266 | dst->ops->update_pmtu(dst, sk, NULL, pmtu); | 266 | dst->ops->update_pmtu(dst, sk, NULL, pmtu, true); |
| 267 | pf->to_sk_daddr(&addr, sk); | 267 | pf->to_sk_daddr(&addr, sk); |
| 268 | 268 | ||
| 269 | dst = sctp_transport_dst_check(t); | 269 | dst = sctp_transport_dst_check(t); |
| @@ -9,7 +9,7 @@ tipc-y += addr.o bcast.o bearer.o \ · 8 unmodified lines | |||
| 9 | core.o link.o discover.o msg.o \ | 9 | core.o link.o discover.o msg.o \ |
| 10 | name_distr.o subscr.o monitor.o name_table.o net.o \ | 10 | name_distr.o subscr.o monitor.o name_table.o net.o \ |
| 11 | netlink.o netlink_compat.o node.o socket.o eth_media.o \ | 11 | netlink.o netlink_compat.o node.o socket.o eth_media.o \ |
| 12 | topsrv.o socket.o group.o trace.o | 12 | topsrv.o group.o trace.o |
| 13 | 13 | ||
| 14 | CFLAGS_trace.o += -I$(src) | 14 | CFLAGS_trace.o += -I$(src) |
| 15 | 15 | ||
| @@ -20,5 +20,3 @@ tipc-$(CONFIG_TIPC_CRYPTO) += crypto.o · 4 unmodified lines | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | obj-$(CONFIG_TIPC_DIAG) += diag.o | 22 | obj-$(CONFIG_TIPC_DIAG) += diag.o |
| 23 | |||
| 24 | tipc_diag-y := diag.o | ||
| @@ -204,8 +204,8 @@ static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, · 203 unmodified lines | |||
| 204 | return -ENOMEM; | 204 | return -ENOMEM; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | attrbuf = kmalloc_array(tipc_genl_family.maxattr + 1, | 207 | attrbuf = kcalloc(tipc_genl_family.maxattr + 1, |
| 208 | sizeof(struct nlattr *), GFP_KERNEL); | 208 | sizeof(struct nlattr *), GFP_KERNEL); |
| 209 | if (!attrbuf) { | 209 | if (!attrbuf) { |
| 210 | err = -ENOMEM; | 210 | err = -ENOMEM; |
| 211 | goto err_out; | 211 | goto err_out; |
| @@ -287,12 +287,12 @@ static void tipc_sk_respond(struct sock *sk, struct sk_buff *skb, int err) · 286 unmodified lines | |||
| 287 | * | 287 | * |
| 288 | * Caller must hold socket lock | 288 | * Caller must hold socket lock |
| 289 | */ | 289 | */ |
| 290 | static void tsk_rej_rx_queue(struct sock *sk) | 290 | static void tsk_rej_rx_queue(struct sock *sk, int error) |
| 291 | { | 291 | { |
| 292 | struct sk_buff *skb; | 292 | struct sk_buff *skb; |
| 293 | 293 | ||
| 294 | while ((skb = __skb_dequeue(&sk->sk_receive_queue))) | 294 | while ((skb = __skb_dequeue(&sk->sk_receive_queue))) |
| 295 | tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT); | 295 | tipc_sk_respond(sk, skb, error); |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | static bool tipc_sk_connected(struct sock *sk) | 298 | static bool tipc_sk_connected(struct sock *sk) |
| @@ -545,34 +545,45 @@ static void __tipc_shutdown(struct socket *sock, int error) · 246 unmodified lines | |||
| 545 | /* Remove pending SYN */ | 545 | /* Remove pending SYN */ |
| 546 | __skb_queue_purge(&sk->sk_write_queue); | 546 | __skb_queue_purge(&sk->sk_write_queue); |
| 547 | 547 | ||
| 548 | /* Reject all unreceived messages, except on an active connection | 548 | /* Remove partially received buffer if any */ |
| 549 | * (which disconnects locally & sends a 'FIN+' to peer). | 549 | skb = skb_peek(&sk->sk_receive_queue); |
| 550 | */ | 550 | if (skb && TIPC_SKB_CB(skb)->bytes_read) { |
| 551 | while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 551 | __skb_unlink(skb, &sk->sk_receive_queue); |
| 552 | if (TIPC_SKB_CB(skb)->bytes_read) { | 552 | kfree_skb(skb); |
| 553 | kfree_skb(skb); | ||
| 554 | continue; | ||
| 555 | } | ||
| 556 | if (!tipc_sk_type_connectionless(sk) && | ||
| 557 | sk->sk_state != TIPC_DISCONNECTING) { | ||
| 558 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); | ||
| 559 | tipc_node_remove_conn(net, dnode, tsk->portid); | ||
| 560 | } | ||
| 561 | tipc_sk_respond(sk, skb, error); | ||
| 562 | } | 553 | } |
| 563 | 554 | ||
| 564 | if (tipc_sk_type_connectionless(sk)) | 555 | /* Reject all unreceived messages if connectionless */ |
| 556 | if (tipc_sk_type_connectionless(sk)) { | ||
| 557 | tsk_rej_rx_queue(sk, error); | ||
| 565 | return; | 558 | return; |
| 559 | } | ||
| 566 | 560 | ||
| 567 | if (sk->sk_state != TIPC_DISCONNECTING) { | 561 | switch (sk->sk_state) { |
| 562 | case TIPC_CONNECTING: | ||
| 563 | case TIPC_ESTABLISHED: | ||
| 564 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); | ||
| 565 | tipc_node_remove_conn(net, dnode, tsk->portid); | ||
| 566 | /* Send a FIN+/- to its peer */ | ||
| 567 | skb = __skb_dequeue(&sk->sk_receive_queue); | ||
| 568 | if (skb) { | ||
| 569 | __skb_queue_purge(&sk->sk_receive_queue); | ||
| 570 | tipc_sk_respond(sk, skb, error); | ||
| 571 | break; | ||
| 572 | } | ||
| 568 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, | 573 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, |
| 569 | TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode, | 574 | TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode, |
| 570 | tsk_own_node(tsk), tsk_peer_port(tsk), | 575 | tsk_own_node(tsk), tsk_peer_port(tsk), |
| 571 | tsk->portid, error); | 576 | tsk->portid, error); |
| 572 | if (skb) | 577 | if (skb) |
| 573 | tipc_node_xmit_skb(net, skb, dnode, tsk->portid); | 578 | tipc_node_xmit_skb(net, skb, dnode, tsk->portid); |
| 574 | tipc_node_remove_conn(net, dnode, tsk->portid); | 579 | break; |
| 575 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); | 580 | case TIPC_LISTEN: |
| 581 | /* Reject all SYN messages */ | ||
| 582 | tsk_rej_rx_queue(sk, error); | ||
| 583 | break; | ||
| 584 | default: | ||
| 585 | __skb_queue_purge(&sk->sk_receive_queue); | ||
| 586 | break; | ||
| 576 | } | 587 | } |
| 577 | } | 588 | } |
| 578 | 589 | ||
| @@ -2432,8 +2443,8 @@ static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) · 1853 unmodified lines | |||
| 2432 | return sock_intr_errno(*timeo_p); | 2443 | return sock_intr_errno(*timeo_p); |
| 2433 | 2444 | ||
| 2434 | add_wait_queue(sk_sleep(sk), &wait); | 2445 | add_wait_queue(sk_sleep(sk), &wait); |
| 2435 | done = sk_wait_event(sk, timeo_p, | 2446 | done = sk_wait_event(sk, timeo_p, tipc_sk_connected(sk), |
| 2436 | sk->sk_state != TIPC_CONNECTING, &wait); | 2447 | &wait); |
| 2437 | remove_wait_queue(sk_sleep(sk), &wait); | 2448 | remove_wait_queue(sk_sleep(sk), &wait); |
| 2438 | } while (!done); | 2449 | } while (!done); |
| 2439 | return 0; | 2450 | return 0; |
| @@ -2643,7 +2654,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, · 203 unmodified lines | |||
| 2643 | * Reject any stray messages received by new socket | 2654 | * Reject any stray messages received by new socket |
| 2644 | * before the socket lock was taken (very, very unlikely) | 2655 | * before the socket lock was taken (very, very unlikely) |
| 2645 | */ | 2656 | */ |
| 2646 | tsk_rej_rx_queue(new_sk); | 2657 | tsk_rej_rx_queue(new_sk, TIPC_ERR_NO_PORT); |
| 2647 | 2658 | ||
| 2648 | /* Connect new socket to it's peer */ | 2659 | /* Connect new socket to it's peer */ |
| 2649 | tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg)); | 2660 | tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg)); |
| @@ -298,14 +298,14 @@ int main(void) · 297 unmodified lines | |||
| 298 | req = malloc(sizes.seccomp_notif); | 298 | req = malloc(sizes.seccomp_notif); |
| 299 | if (!req) | 299 | if (!req) |
| 300 | goto out_close; | 300 | goto out_close; |
| 301 | memset(req, 0, sizeof(*req)); | ||
| 302 | 301 | ||
| 303 | resp = malloc(sizes.seccomp_notif_resp); | 302 | resp = malloc(sizes.seccomp_notif_resp); |
| 304 | if (!resp) | 303 | if (!resp) |
| 305 | goto out_req; | 304 | goto out_req; |
| 306 | memset(resp, 0, sizeof(*resp)); | 305 | memset(resp, 0, sizes.seccomp_notif_resp); |
| 307 | 306 | ||
| 308 | while (1) { | 307 | while (1) { |
| 308 | memset(req, 0, sizes.seccomp_notif); | ||
| 309 | if (ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, req)) { | 309 | if (ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, req)) { |
| 310 | perror("ioctl recv"); | 310 | perror("ioctl recv"); |
| 311 | goto out_resp; | 311 | goto out_resp; |
| @@ -14,8 +14,8 @@ config HAVE_GCC_PLUGINS · 13 unmodified lines | |||
| 14 | An arch should select this symbol if it supports building with | 14 | An arch should select this symbol if it supports building with |
| 15 | GCC plugins. | 15 | GCC plugins. |
| 16 | 16 | ||
| 17 | config GCC_PLUGINS | 17 | menuconfig GCC_PLUGINS |
| 18 | bool | 18 | bool "GCC plugins" |
| 19 | depends on HAVE_GCC_PLUGINS | 19 | depends on HAVE_GCC_PLUGINS |
| 20 | depends on PLUGIN_HOSTCC != "" | 20 | depends on PLUGIN_HOSTCC != "" |
| 21 | default y | 21 | default y |
| @@ -25,8 +25,7 @@ config GCC_PLUGINS · 3 unmodified lines | |||
| 25 | 25 | ||
| 26 | See Documentation/core-api/gcc-plugins.rst for details. | 26 | See Documentation/core-api/gcc-plugins.rst for details. |
| 27 | 27 | ||
| 28 | menu "GCC plugins" | 28 | if GCC_PLUGINS |
| 29 | depends on GCC_PLUGINS | ||
| 30 | 29 | ||
| 31 | config GCC_PLUGIN_CYC_COMPLEXITY | 30 | config GCC_PLUGIN_CYC_COMPLEXITY |
| 32 | bool "Compute the cyclomatic complexity of a function" if EXPERT | 31 | bool "Compute the cyclomatic complexity of a function" if EXPERT |
| @@ -113,4 +112,4 @@ config GCC_PLUGIN_ARM_SSP_PER_TASK · 80 unmodified lines | |||
| 113 | bool | 112 | bool |
| 114 | depends on GCC_PLUGINS && ARM | 113 | depends on GCC_PLUGINS && ARM |
| 115 | 114 | ||
| 116 | endmenu | 115 | endif |
| @@ -136,7 +136,7 @@ mkdir -p debian/source/ · 135 unmodified lines | |||
| 136 | echo "1.0" > debian/source/format | 136 | echo "1.0" > debian/source/format |
| 137 | 137 | ||
| 138 | echo $debarch > debian/arch | 138 | echo $debarch > debian/arch |
| 139 | extra_build_depends=", $(if_enabled_echo CONFIG_UNWINDER_ORC libelf-dev)" | 139 | extra_build_depends=", $(if_enabled_echo CONFIG_UNWINDER_ORC libelf-dev:native)" |
| 140 | extra_build_depends="$extra_build_depends, $(if_enabled_echo CONFIG_SYSTEM_TRUSTED_KEYRING libssl-dev:native)" | 140 | extra_build_depends="$extra_build_depends, $(if_enabled_echo CONFIG_SYSTEM_TRUSTED_KEYRING libssl-dev:native)" |
| 141 | 141 | ||
| 142 | # Generate a simple changelog template | 142 | # Generate a simple changelog template |
| @@ -623,7 +623,7 @@ static __poll_t ns_revision_poll(struct file *file, poll_table *pt) · 622 unmodified lines | |||
| 623 | 623 | ||
| 624 | void __aa_bump_ns_revision(struct aa_ns *ns) | 624 | void __aa_bump_ns_revision(struct aa_ns *ns) |
| 625 | { | 625 | { |
| 626 | ns->revision++; | 626 | WRITE_ONCE(ns->revision, ns->revision + 1); |
| 627 | wake_up_interruptible(&ns->wait); | 627 | wake_up_interruptible(&ns->wait); |
| 628 | } | 628 | } |
| 629 | 629 | ||
| @@ -317,6 +317,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm, · 316 unmodified lines | |||
| 317 | 317 | ||
| 318 | if (!bprm || !profile->xattr_count) | 318 | if (!bprm || !profile->xattr_count) |
| 319 | return 0; | 319 | return 0; |
| 320 | might_sleep(); | ||
| 320 | 321 | ||
| 321 | /* transition from exec match to xattr set */ | 322 | /* transition from exec match to xattr set */ |
| 322 | state = aa_dfa_null_transition(profile->xmatch, state); | 323 | state = aa_dfa_null_transition(profile->xmatch, state); |
| @@ -361,10 +362,11 @@ out: · 38 unmodified lines | |||
| 361 | } | 362 | } |
| 362 | 363 | ||
| 363 | /** | 364 | /** |
| 364 | * __attach_match_ - find an attachment match | 365 | * find_attach - do attachment search for unconfined processes |
| 365 | * @bprm - binprm structure of transitioning task | 366 | * @bprm - binprm structure of transitioning task |
| 366 | * @name - to match against (NOT NULL) | 367 | * @ns: the current namespace (NOT NULL) |
| 367 | * @head - profile list to walk (NOT NULL) | 368 | * @head - profile list to walk (NOT NULL) |
| 369 | * @name - to match against (NOT NULL) | ||
| 368 | * @info - info message if there was an error (NOT NULL) | 370 | * @info - info message if there was an error (NOT NULL) |
| 369 | * | 371 | * |
| 370 | * Do a linear search on the profiles in the list. There is a matching | 372 | * Do a linear search on the profiles in the list. There is a matching |
| @@ -374,12 +376,11 @@ out: · 3 unmodified lines | |||
| 374 | * | 376 | * |
| 375 | * Requires: @head not be shared or have appropriate locks held | 377 | * Requires: @head not be shared or have appropriate locks held |
| 376 | * | 378 | * |
| 377 | * Returns: profile or NULL if no match found | 379 | * Returns: label or NULL if no match found |
| 378 | */ | 380 | */ |
| 379 | static struct aa_profile *__attach_match(const struct linux_binprm *bprm, | 381 | static struct aa_label *find_attach(const struct linux_binprm *bprm, |
| 380 | const char *name, | 382 | struct aa_ns *ns, struct list_head *head, |
| 381 | struct list_head *head, | 383 | const char *name, const char **info) |
| 382 | const char **info) | ||
| 383 | { | 384 | { |
| 384 | int candidate_len = 0, candidate_xattrs = 0; | 385 | int candidate_len = 0, candidate_xattrs = 0; |
| 385 | bool conflict = false; | 386 | bool conflict = false; |
| @@ -388,6 +389,8 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm, · 2 unmodified lines | |||
| 388 | AA_BUG(!name); | 389 | AA_BUG(!name); |
| 389 | AA_BUG(!head); | 390 | AA_BUG(!head); |
| 390 | 391 | ||
| 392 | rcu_read_lock(); | ||
| 393 | restart: | ||
| 391 | list_for_each_entry_rcu(profile, head, base.list) { | 394 | list_for_each_entry_rcu(profile, head, base.list) { |
| 392 | if (profile->label.flags & FLAG_NULL && | 395 | if (profile->label.flags & FLAG_NULL && |
| 393 | &profile->label == ns_unconfined(profile->ns)) | 396 | &profile->label == ns_unconfined(profile->ns)) |
| @@ -413,16 +416,32 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm, · 19 unmodified lines | |||
| 413 | perm = dfa_user_allow(profile->xmatch, state); | 416 | perm = dfa_user_allow(profile->xmatch, state); |
| 414 | /* any accepting state means a valid match. */ | 417 | /* any accepting state means a valid match. */ |
| 415 | if (perm & MAY_EXEC) { | 418 | if (perm & MAY_EXEC) { |
| 416 | int ret; | 419 | int ret = 0; |
| 417 | 420 | ||
| 418 | if (count < candidate_len) | 421 | if (count < candidate_len) |
| 419 | continue; | 422 | continue; |
| 420 | 423 | ||
| 421 | ret = aa_xattrs_match(bprm, profile, state); | 424 | if (bprm && profile->xattr_count) { |
| 422 | /* Fail matching if the xattrs don't match */ | 425 | long rev = READ_ONCE(ns->revision); |
| 423 | if (ret < 0) | 426 | |
| 424 | continue; | 427 | if (!aa_get_profile_not0(profile)) |
| 425 | 428 | goto restart; | |
| 429 | rcu_read_unlock(); | ||
| 430 | ret = aa_xattrs_match(bprm, profile, | ||
| 431 | state); | ||
| 432 | rcu_read_lock(); | ||
| 433 | aa_put_profile(profile); | ||
| 434 | if (rev != | ||
| 435 | READ_ONCE(ns->revision)) | ||
| 436 | /* policy changed */ | ||
| 437 | goto restart; | ||
| 438 | /* | ||
| 439 | * Fail matching if the xattrs don't | ||
| 440 | * match | ||
| 441 | */ | ||
| 442 | if (ret < 0) | ||
| 443 | continue; | ||
| 444 | } | ||
| 426 | /* | 445 | /* |
| 427 | * TODO: allow for more flexible best match | 446 | * TODO: allow for more flexible best match |
| 428 | * | 447 | * |
| @@ -445,43 +464,28 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm, · 16 unmodified lines | |||
| 445 | candidate_xattrs = ret; | 464 | candidate_xattrs = ret; |
| 446 | conflict = false; | 465 | conflict = false; |
| 447 | } | 466 | } |
| 448 | } else if (!strcmp(profile->base.name, name)) | 467 | } else if (!strcmp(profile->base.name, name)) { |
| 449 | /* | 468 | /* |
| 450 | * old exact non-re match, without conditionals such | 469 | * old exact non-re match, without conditionals such |
| 451 | * as xattrs. no more searching required | 470 | * as xattrs. no more searching required |
| 452 | */ | 471 | */ |
| 453 | return profile; | 472 | candidate = profile; |
| 473 | goto out; | ||
| 474 | } | ||
| 454 | } | 475 | } |
| 455 | 476 | ||
| 456 | if (conflict) { | 477 | if (!candidate || conflict) { |
| 457 | *info = "conflicting profile attachments"; | 478 | if (conflict) |
| 479 | *info = "conflicting profile attachments"; | ||
| 480 | rcu_read_unlock(); | ||
| 458 | return NULL; | 481 | return NULL; |
| 459 | } | 482 | } |
| 460 | 483 | ||
| 461 | return candidate; | 484 | out: |
| 462 | } | 485 | candidate = aa_get_newest_profile(candidate); |
| 463 | |||
| 464 | /** | ||
| 465 | * find_attach - do attachment search for unconfined processes | ||
| 466 | * @bprm - binprm structure of transitioning task | ||
| 467 | * @ns: the current namespace (NOT NULL) | ||
| 468 | * @list: list to search (NOT NULL) | ||
| 469 | * @name: the executable name to match against (NOT NULL) | ||
| 470 | * @info: info message if there was an error | ||
| 471 | * | ||
| 472 | * Returns: label or NULL if no match found | ||
| 473 | */ | ||
| 474 | static struct aa_label *find_attach(const struct linux_binprm *bprm, | ||
| 475 | struct aa_ns *ns, struct list_head *list, | ||
| 476 | const char *name, const char **info) | ||
| 477 | { | ||
| 478 | struct aa_profile *profile; | ||
| 479 | |||
| 480 | rcu_read_lock(); | ||
| 481 | profile = aa_get_profile(__attach_match(bprm, name, list, info)); | ||
| 482 | rcu_read_unlock(); | 486 | rcu_read_unlock(); |
| 483 | 487 | ||
| 484 | return profile ? &profile->label : NULL; | 488 | return &candidate->label; |
| 485 | } | 489 | } |
| 486 | 490 | ||
| 487 | static const char *next_name(int xtype, const char *name) | 491 | static const char *next_name(int xtype, const char *name) |
| @@ -618,8 +618,7 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file, · 617 unmodified lines | |||
| 618 | fctx = file_ctx(file); | 618 | fctx = file_ctx(file); |
| 619 | 619 | ||
| 620 | rcu_read_lock(); | 620 | rcu_read_lock(); |
| 621 | flabel = aa_get_newest_label(rcu_dereference(fctx->label)); | 621 | flabel = rcu_dereference(fctx->label); |
| 622 | rcu_read_unlock(); | ||
| 623 | AA_BUG(!flabel); | 622 | AA_BUG(!flabel); |
| 624 | 623 | ||
| 625 | /* revalidate access, if task is unconfined, or the cached cred | 624 | /* revalidate access, if task is unconfined, or the cached cred |
| @@ -631,9 +630,13 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file, · 5 unmodified lines | |||
| 631 | */ | 630 | */ |
| 632 | denied = request & ~fctx->allow; | 631 | denied = request & ~fctx->allow; |
| 633 | if (unconfined(label) || unconfined(flabel) || | 632 | if (unconfined(label) || unconfined(flabel) || |
| 634 | (!denied && aa_label_is_subset(flabel, label))) | 633 | (!denied && aa_label_is_subset(flabel, label))) { |
| 634 | rcu_read_unlock(); | ||
| 635 | goto done; | 635 | goto done; |
| 636 | } | ||
| 636 | 637 | ||
| 638 | flabel = aa_get_newest_label(flabel); | ||
| 639 | rcu_read_unlock(); | ||
| 637 | /* TODO: label cross check */ | 640 | /* TODO: label cross check */ |
| 638 | 641 | ||
| 639 | if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry)) | 642 | if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry)) |
| @@ -643,8 +646,9 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file, · 3 unmodified lines | |||
| 643 | else if (S_ISSOCK(file_inode(file)->i_mode)) | 646 | else if (S_ISSOCK(file_inode(file)->i_mode)) |
| 644 | error = __file_sock_perm(op, label, flabel, file, request, | 647 | error = __file_sock_perm(op, label, flabel, file, request, |
| 645 | denied); | 648 | denied); |
| 646 | done: | ||
| 647 | aa_put_label(flabel); | 649 | aa_put_label(flabel); |
| 650 | |||
| 651 | done: | ||
| 648 | return error; | 652 | return error; |
| 649 | } | 653 | } |
| 650 | 654 | ||
| @@ -442,7 +442,7 @@ int aa_bind_mount(struct aa_label *label, const struct path *path, · 441 unmodified lines | |||
| 442 | buffer = aa_get_buffer(false); | 442 | buffer = aa_get_buffer(false); |
| 443 | old_buffer = aa_get_buffer(false); | 443 | old_buffer = aa_get_buffer(false); |
| 444 | error = -ENOMEM; | 444 | error = -ENOMEM; |
| 445 | if (!buffer || old_buffer) | 445 | if (!buffer || !old_buffer) |
| 446 | goto out; | 446 | goto out; |
| 447 | 447 | ||
| 448 | error = fn_for_each_confined(label, profile, | 448 | error = fn_for_each_confined(label, profile, |
| @@ -1125,8 +1125,8 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj, · 1124 unmodified lines | |||
| 1125 | if (!name) { | 1125 | if (!name) { |
| 1126 | /* remove namespace - can only happen if fqname[0] == ':' */ | 1126 | /* remove namespace - can only happen if fqname[0] == ':' */ |
| 1127 | mutex_lock_nested(&ns->parent->lock, ns->level); | 1127 | mutex_lock_nested(&ns->parent->lock, ns->level); |
| 1128 | __aa_remove_ns(ns); | ||
| 1129 | __aa_bump_ns_revision(ns); | 1128 | __aa_bump_ns_revision(ns); |
| 1129 | __aa_remove_ns(ns); | ||
| 1130 | mutex_unlock(&ns->parent->lock); | 1130 | mutex_unlock(&ns->parent->lock); |
| 1131 | } else { | 1131 | } else { |
| 1132 | /* remove profile */ | 1132 | /* remove profile */ |
| @@ -1138,9 +1138,9 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj, · 5 unmodified lines | |||
| 1138 | goto fail_ns_lock; | 1138 | goto fail_ns_lock; |
| 1139 | } | 1139 | } |
| 1140 | name = profile->base.hname; | 1140 | name = profile->base.hname; |
| 1141 | __aa_bump_ns_revision(ns); | ||
| 1141 | __remove_profile(profile); | 1142 | __remove_profile(profile); |
| 1142 | __aa_labelset_update_subtree(ns); | 1143 | __aa_labelset_update_subtree(ns); |
| 1143 | __aa_bump_ns_revision(ns); | ||
| 1144 | mutex_unlock(&ns->lock); | 1144 | mutex_unlock(&ns->lock); |
| 1145 | } | 1145 | } |
| 1146 | 1146 | ||
| @@ -951,7 +951,8 @@ static bool tomoyo_manager(void) · 950 unmodified lines | |||
| 951 | exe = tomoyo_get_exe(); | 951 | exe = tomoyo_get_exe(); |
| 952 | if (!exe) | 952 | if (!exe) |
| 953 | return false; | 953 | return false; |
| 954 | list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list) { | 954 | list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list, |
| 955 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 955 | if (!ptr->head.is_deleted && | 956 | if (!ptr->head.is_deleted && |
| 956 | (!tomoyo_pathcmp(domainname, ptr->manager) || | 957 | (!tomoyo_pathcmp(domainname, ptr->manager) || |
| 957 | !strcmp(exe, ptr->manager->name))) { | 958 | !strcmp(exe, ptr->manager->name))) { |
| @@ -1095,7 +1096,8 @@ static int tomoyo_delete_domain(char *domainname) · 137 unmodified lines | |||
| 1095 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 1096 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
| 1096 | return -EINTR; | 1097 | return -EINTR; |
| 1097 | /* Is there an active domain? */ | 1098 | /* Is there an active domain? */ |
| 1098 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { | 1099 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, |
| 1100 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 1099 | /* Never delete tomoyo_kernel_domain */ | 1101 | /* Never delete tomoyo_kernel_domain */ |
| 1100 | if (domain == &tomoyo_kernel_domain) | 1102 | if (domain == &tomoyo_kernel_domain) |
| 1101 | continue; | 1103 | continue; |
| @@ -2778,7 +2780,8 @@ void tomoyo_check_profile(void) · 1676 unmodified lines | |||
| 2778 | 2780 | ||
| 2779 | tomoyo_policy_loaded = true; | 2781 | tomoyo_policy_loaded = true; |
| 2780 | pr_info("TOMOYO: 2.6.0\n"); | 2782 | pr_info("TOMOYO: 2.6.0\n"); |
| 2781 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { | 2783 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, |
| 2784 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 2782 | const u8 profile = domain->profile; | 2785 | const u8 profile = domain->profile; |
| 2783 | struct tomoyo_policy_namespace *ns = domain->ns; | 2786 | struct tomoyo_policy_namespace *ns = domain->ns; |
| 2784 | 2787 | ||
| @@ -41,7 +41,8 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, · 40 unmodified lines | |||
| 41 | 41 | ||
| 42 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 42 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
| 43 | return -ENOMEM; | 43 | return -ENOMEM; |
| 44 | list_for_each_entry_rcu(entry, list, list) { | 44 | list_for_each_entry_rcu(entry, list, list, |
| 45 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 45 | if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS) | 46 | if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS) |
| 46 | continue; | 47 | continue; |
| 47 | if (!check_duplicate(entry, new_entry)) | 48 | if (!check_duplicate(entry, new_entry)) |
| @@ -119,7 +120,8 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, · 71 unmodified lines | |||
| 119 | } | 120 | } |
| 120 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 121 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
| 121 | goto out; | 122 | goto out; |
| 122 | list_for_each_entry_rcu(entry, list, list) { | 123 | list_for_each_entry_rcu(entry, list, list, |
| 124 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 123 | if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS) | 125 | if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS) |
| 124 | continue; | 126 | continue; |
| 125 | if (!tomoyo_same_acl_head(entry, new_entry) || | 127 | if (!tomoyo_same_acl_head(entry, new_entry) || |
| @@ -166,7 +168,8 @@ void tomoyo_check_acl(struct tomoyo_request_info *r, · 40 unmodified lines | |||
| 166 | u16 i = 0; | 168 | u16 i = 0; |
| 167 | 169 | ||
| 168 | retry: | 170 | retry: |
| 169 | list_for_each_entry_rcu(ptr, list, list) { | 171 | list_for_each_entry_rcu(ptr, list, list, |
| 172 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 170 | if (ptr->is_deleted || ptr->type != r->param_type) | 173 | if (ptr->is_deleted || ptr->type != r->param_type) |
| 171 | continue; | 174 | continue; |
| 172 | if (!check_entry(r, ptr)) | 175 | if (!check_entry(r, ptr)) |
| @@ -298,7 +301,8 @@ static inline bool tomoyo_scan_transition · 125 unmodified lines | |||
| 298 | { | 301 | { |
| 299 | const struct tomoyo_transition_control *ptr; | 302 | const struct tomoyo_transition_control *ptr; |
| 300 | 303 | ||
| 301 | list_for_each_entry_rcu(ptr, list, head.list) { | 304 | list_for_each_entry_rcu(ptr, list, head.list, |
| 305 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 302 | if (ptr->head.is_deleted || ptr->type != type) | 306 | if (ptr->head.is_deleted || ptr->type != type) |
| 303 | continue; | 307 | continue; |
| 304 | if (ptr->domainname) { | 308 | if (ptr->domainname) { |
| @@ -735,7 +739,8 @@ retry: · 430 unmodified lines | |||
| 735 | 739 | ||
| 736 | /* Check 'aggregator' directive. */ | 740 | /* Check 'aggregator' directive. */ |
| 737 | candidate = &exename; | 741 | candidate = &exename; |
| 738 | list_for_each_entry_rcu(ptr, list, head.list) { | 742 | list_for_each_entry_rcu(ptr, list, head.list, |
| 743 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 739 | if (ptr->head.is_deleted || | 744 | if (ptr->head.is_deleted || |
| 740 | !tomoyo_path_matches_pattern(&exename, | 745 | !tomoyo_path_matches_pattern(&exename, |
| 741 | ptr->original_name)) | 746 | ptr->original_name)) |
| @@ -133,7 +133,8 @@ tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, · 132 unmodified lines | |||
| 133 | { | 133 | { |
| 134 | struct tomoyo_path_group *member; | 134 | struct tomoyo_path_group *member; |
| 135 | 135 | ||
| 136 | list_for_each_entry_rcu(member, &group->member_list, head.list) { | 136 | list_for_each_entry_rcu(member, &group->member_list, head.list, |
| 137 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 137 | if (member->head.is_deleted) | 138 | if (member->head.is_deleted) |
| 138 | continue; | 139 | continue; |
| 139 | if (!tomoyo_path_matches_pattern(pathname, member->member_name)) | 140 | if (!tomoyo_path_matches_pattern(pathname, member->member_name)) |
| @@ -161,7 +162,8 @@ bool tomoyo_number_matches_group(const unsigned long min, · 21 unmodified lines | |||
| 161 | struct tomoyo_number_group *member; | 162 | struct tomoyo_number_group *member; |
| 162 | bool matched = false; | 163 | bool matched = false; |
| 163 | 164 | ||
| 164 | list_for_each_entry_rcu(member, &group->member_list, head.list) { | 165 | list_for_each_entry_rcu(member, &group->member_list, head.list, |
| 166 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 165 | if (member->head.is_deleted) | 167 | if (member->head.is_deleted) |
| 166 | continue; | 168 | continue; |
| 167 | if (min > member->number.values[1] || | 169 | if (min > member->number.values[1] || |
| @@ -191,7 +193,8 @@ bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address, · 23 unmodified lines | |||
| 191 | bool matched = false; | 193 | bool matched = false; |
| 192 | const u8 size = is_ipv6 ? 16 : 4; | 194 | const u8 size = is_ipv6 ? 16 : 4; |
| 193 | 195 | ||
| 194 | list_for_each_entry_rcu(member, &group->member_list, head.list) { | 196 | list_for_each_entry_rcu(member, &group->member_list, head.list, |
| 197 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 195 | if (member->head.is_deleted) | 198 | if (member->head.is_deleted) |
| 196 | continue; | 199 | continue; |
| 197 | if (member->address.is_ipv6 != is_ipv6) | 200 | if (member->address.is_ipv6 != is_ipv6) |
| @@ -217,31 +217,6 @@ out: · 216 unmodified lines | |||
| 217 | return ERR_PTR(-ENOMEM); | 217 | return ERR_PTR(-ENOMEM); |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | /** | ||
| 221 | * tomoyo_get_socket_name - Get the name of a socket. | ||
| 222 | * | ||
| 223 | * @path: Pointer to "struct path". | ||
| 224 | * @buffer: Pointer to buffer to return value in. | ||
| 225 | * @buflen: Sizeof @buffer. | ||
| 226 | * | ||
| 227 | * Returns the buffer. | ||
| 228 | */ | ||
| 229 | static char *tomoyo_get_socket_name(const struct path *path, char * const buffer, | ||
| 230 | const int buflen) | ||
| 231 | { | ||
| 232 | struct inode *inode = d_backing_inode(path->dentry); | ||
| 233 | struct socket *sock = inode ? SOCKET_I(inode) : NULL; | ||
| 234 | struct sock *sk = sock ? sock->sk : NULL; | ||
| 235 | |||
| 236 | if (sk) { | ||
| 237 | snprintf(buffer, buflen, "socket:[family=%u:type=%u:protocol=%u]", | ||
| 238 | sk->sk_family, sk->sk_type, sk->sk_protocol); | ||
| 239 | } else { | ||
| 240 | snprintf(buffer, buflen, "socket:[unknown]"); | ||
| 241 | } | ||
| 242 | return buffer; | ||
| 243 | } | ||
| 244 | |||
| 245 | /** | 220 | /** |
| 246 | * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root. | 221 | * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root. |
| 247 | * | 222 | * |
| @@ -279,12 +254,7 @@ char *tomoyo_realpath_from_path(const struct path *path) · 31 unmodified lines | |||
| 279 | break; | 254 | break; |
| 280 | /* To make sure that pos is '\0' terminated. */ | 255 | /* To make sure that pos is '\0' terminated. */ |
| 281 | buf[buf_len - 1] = '\0'; | 256 | buf[buf_len - 1] = '\0'; |
| 282 | /* Get better name for socket. */ | 257 | /* For "pipe:[\$]" and "socket:[\$]". */ |
| 283 | if (sb->s_magic == SOCKFS_MAGIC) { | ||
| 284 | pos = tomoyo_get_socket_name(path, buf, buf_len - 1); | ||
| 285 | goto encode; | ||
| 286 | } | ||
| 287 | /* For "pipe:[\$]". */ | ||
| 288 | if (dentry->d_op && dentry->d_op->d_dname) { | 258 | if (dentry->d_op && dentry->d_op->d_dname) { |
| 289 | pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); | 259 | pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); |
| 290 | goto encode; | 260 | goto encode; |
| @@ -594,7 +594,8 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) · 593 unmodified lines | |||
| 594 | 594 | ||
| 595 | name.name = domainname; | 595 | name.name = domainname; |
| 596 | tomoyo_fill_path_info(&name); | 596 | tomoyo_fill_path_info(&name); |
| 597 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { | 597 | list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, |
| 598 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 598 | if (!domain->is_deleted && | 599 | if (!domain->is_deleted && |
| 599 | !tomoyo_pathcmp(&name, domain->domainname)) | 600 | !tomoyo_pathcmp(&name, domain->domainname)) |
| 600 | return domain; | 601 | return domain; |
| @@ -1028,7 +1029,8 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r) · 427 unmodified lines | |||
| 1028 | return false; | 1029 | return false; |
| 1029 | if (!domain) | 1030 | if (!domain) |
| 1030 | return true; | 1031 | return true; |
| 1031 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | 1032 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list, |
| 1033 | srcu_read_lock_held(&tomoyo_ss)) { | ||
| 1032 | u16 perm; | 1034 | u16 perm; |
| 1033 | u8 i; | 1035 | u8 i; |
| 1034 | 1036 | ||
| @@ -363,7 +363,6 @@ static const struct regmap_config hda_regmap_cfg = { · 362 unmodified lines | |||
| 363 | .reg_write = hda_reg_write, | 363 | .reg_write = hda_reg_write, |
| 364 | .use_single_read = true, | 364 | .use_single_read = true, |
| 365 | .use_single_write = true, | 365 | .use_single_write = true, |
| 366 | .disable_locking = true, | ||
| 367 | }; | 366 | }; |
| 368 | 367 | ||
| 369 | /** | 368 | /** |
| @@ -282,12 +282,13 @@ enum { · 281 unmodified lines | |||
| 282 | 282 | ||
| 283 | /* quirks for old Intel chipsets */ | 283 | /* quirks for old Intel chipsets */ |
| 284 | #define AZX_DCAPS_INTEL_ICH \ | 284 | #define AZX_DCAPS_INTEL_ICH \ |
| 285 | (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE) | 285 | (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE |\ |
| 286 | AZX_DCAPS_SYNC_WRITE) | ||
| 286 | 287 | ||
| 287 | /* quirks for Intel PCH */ | 288 | /* quirks for Intel PCH */ |
| 288 | #define AZX_DCAPS_INTEL_PCH_BASE \ | 289 | #define AZX_DCAPS_INTEL_PCH_BASE \ |
| 289 | (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ | 290 | (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ |
| 290 | AZX_DCAPS_SNOOP_TYPE(SCH)) | 291 | AZX_DCAPS_SNOOP_TYPE(SCH) | AZX_DCAPS_SYNC_WRITE) |
| 291 | 292 | ||
| 292 | /* PCH up to IVB; no runtime PM; bind with i915 gfx */ | 293 | /* PCH up to IVB; no runtime PM; bind with i915 gfx */ |
| 293 | #define AZX_DCAPS_INTEL_PCH_NOPM \ | 294 | #define AZX_DCAPS_INTEL_PCH_NOPM \ |
| @@ -302,13 +303,13 @@ enum { · 8 unmodified lines | |||
| 302 | #define AZX_DCAPS_INTEL_HASWELL \ | 303 | #define AZX_DCAPS_INTEL_HASWELL \ |
| 303 | (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\ | 304 | (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\ |
| 304 | AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\ | 305 | AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\ |
| 305 | AZX_DCAPS_SNOOP_TYPE(SCH)) | 306 | AZX_DCAPS_SNOOP_TYPE(SCH) | AZX_DCAPS_SYNC_WRITE) |
| 306 | 307 | ||
| 307 | /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */ | 308 | /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */ |
| 308 | #define AZX_DCAPS_INTEL_BROADWELL \ | 309 | #define AZX_DCAPS_INTEL_BROADWELL \ |
| 309 | (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\ | 310 | (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\ |
| 310 | AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\ | 311 | AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\ |
| 311 | AZX_DCAPS_SNOOP_TYPE(SCH)) | 312 | AZX_DCAPS_SNOOP_TYPE(SCH) | AZX_DCAPS_SYNC_WRITE) |
| 312 | 313 | ||
| 313 | #define AZX_DCAPS_INTEL_BAYTRAIL \ | 314 | #define AZX_DCAPS_INTEL_BAYTRAIL \ |
| 314 | (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT) | 315 | (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT) |
| @@ -1410,7 +1411,17 @@ static bool atpx_present(void) · 1095 unmodified lines | |||
| 1410 | acpi_handle dhandle, atpx_handle; | 1411 | acpi_handle dhandle, atpx_handle; |
| 1411 | acpi_status status; | 1412 | acpi_status status; |
| 1412 | 1413 | ||
| 1413 | while ((pdev = pci_get_class(PCI_BASE_CLASS_DISPLAY << 16, pdev)) != NULL) { | 1414 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { |
| 1415 | dhandle = ACPI_HANDLE(&pdev->dev); | ||
| 1416 | if (dhandle) { | ||
| 1417 | status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); | ||
| 1418 | if (!ACPI_FAILURE(status)) { | ||
| 1419 | pci_dev_put(pdev); | ||
| 1420 | return true; | ||
| 1421 | } | ||
| 1422 | } | ||
| 1423 | } | ||
| 1424 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { | ||
| 1414 | dhandle = ACPI_HANDLE(&pdev->dev); | 1425 | dhandle = ACPI_HANDLE(&pdev->dev); |
| 1415 | if (dhandle) { | 1426 | if (dhandle) { |
| 1416 | status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); | 1427 | status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); |
| @@ -412,6 +412,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) · 411 unmodified lines | |||
| 412 | case 0x10ec0672: | 412 | case 0x10ec0672: |
| 413 | alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ | 413 | alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ |
| 414 | break; | 414 | break; |
| 415 | case 0x10ec0222: | ||
| 415 | case 0x10ec0623: | 416 | case 0x10ec0623: |
| 416 | alc_update_coef_idx(codec, 0x19, 1<<13, 0); | 417 | alc_update_coef_idx(codec, 0x19, 1<<13, 0); |
| 417 | break; | 418 | break; |
| @@ -430,6 +431,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) · 12 unmodified lines | |||
| 430 | break; | 431 | break; |
| 431 | case 0x10ec0899: | 432 | case 0x10ec0899: |
| 432 | case 0x10ec0900: | 433 | case 0x10ec0900: |
| 434 | case 0x10ec0b00: | ||
| 433 | case 0x10ec1168: | 435 | case 0x10ec1168: |
| 434 | case 0x10ec1220: | 436 | case 0x10ec1220: |
| 435 | alc_update_coef_idx(codec, 0x7, 1<<1, 0); | 437 | alc_update_coef_idx(codec, 0x7, 1<<1, 0); |
| @@ -501,6 +503,7 @@ static void alc_shutup_pins(struct hda_codec *codec) · 65 unmodified lines | |||
| 501 | struct alc_spec *spec = codec->spec; | 503 | struct alc_spec *spec = codec->spec; |
| 502 | 504 | ||
| 503 | switch (codec->core.vendor_id) { | 505 | switch (codec->core.vendor_id) { |
| 506 | case 0x10ec0283: | ||
| 504 | case 0x10ec0286: | 507 | case 0x10ec0286: |
| 505 | case 0x10ec0288: | 508 | case 0x10ec0288: |
| 506 | case 0x10ec0298: | 509 | case 0x10ec0298: |
| @@ -2525,6 +2528,7 @@ static int patch_alc882(struct hda_codec *codec) · 2018 unmodified lines | |||
| 2525 | case 0x10ec0882: | 2528 | case 0x10ec0882: |
| 2526 | case 0x10ec0885: | 2529 | case 0x10ec0885: |
| 2527 | case 0x10ec0900: | 2530 | case 0x10ec0900: |
| 2531 | case 0x10ec0b00: | ||
| 2528 | case 0x10ec1220: | 2532 | case 0x10ec1220: |
| 2529 | break; | 2533 | break; |
| 2530 | default: | 2534 | default: |
| @@ -5904,9 +5908,12 @@ enum { · 3373 unmodified lines | |||
| 5904 | ALC256_FIXUP_ASUS_HEADSET_MIC, | 5908 | ALC256_FIXUP_ASUS_HEADSET_MIC, |
| 5905 | ALC256_FIXUP_ASUS_MIC_NO_PRESENCE, | 5909 | ALC256_FIXUP_ASUS_MIC_NO_PRESENCE, |
| 5906 | ALC299_FIXUP_PREDATOR_SPK, | 5910 | ALC299_FIXUP_PREDATOR_SPK, |
| 5907 | ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC, | ||
| 5908 | ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, | 5911 | ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, |
| 5909 | ALC294_FIXUP_ASUS_INTSPK_GPIO, | 5912 | ALC289_FIXUP_DELL_SPK2, |
| 5913 | ALC289_FIXUP_DUAL_SPK, | ||
| 5914 | ALC294_FIXUP_SPK2_TO_DAC1, | ||
| 5915 | ALC294_FIXUP_ASUS_DUAL_SPK, | ||
| 5916 | |||
| 5910 | }; | 5917 | }; |
| 5911 | 5918 | ||
| 5912 | static const struct hda_fixup alc269_fixups[] = { | 5919 | static const struct hda_fixup alc269_fixups[] = { |
| @@ -6981,33 +6988,45 @@ static const struct hda_fixup alc269_fixups[] = { · 1068 unmodified lines | |||
| 6981 | { } | 6988 | { } |
| 6982 | } | 6989 | } |
| 6983 | }, | 6990 | }, |
| 6984 | [ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC] = { | 6991 | [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = { |
| 6985 | .type = HDA_FIXUP_PINS, | 6992 | .type = HDA_FIXUP_PINS, |
| 6986 | .v.pins = (const struct hda_pintbl[]) { | 6993 | .v.pins = (const struct hda_pintbl[]) { |
| 6987 | { 0x14, 0x411111f0 }, /* disable confusing internal speaker */ | 6994 | { 0x19, 0x04a11040 }, |
| 6988 | { 0x19, 0x04a11150 }, /* use as headset mic, without its own jack detect */ | 6995 | { 0x21, 0x04211020 }, |
| 6989 | { } | 6996 | { } |
| 6990 | }, | 6997 | }, |
| 6991 | .chained = true, | 6998 | .chained = true, |
| 6992 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | 6999 | .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE |
| 6993 | }, | 7000 | }, |
| 6994 | [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = { | 7001 | [ALC289_FIXUP_DELL_SPK2] = { |
| 6995 | .type = HDA_FIXUP_PINS, | 7002 | .type = HDA_FIXUP_PINS, |
| 6996 | .v.pins = (const struct hda_pintbl[]) { | 7003 | .v.pins = (const struct hda_pintbl[]) { |
| 6997 | { 0x19, 0x04a11040 }, | 7004 | { 0x17, 0x90170130 }, /* bass spk */ |
| 6998 | { 0x21, 0x04211020 }, | ||
| 6999 | { } | 7005 | { } |
| 7000 | }, | 7006 | }, |
| 7001 | .chained = true, | 7007 | .chained = true, |
| 7002 | .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE | 7008 | .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE |
| 7003 | }, | 7009 | }, |
| 7004 | [ALC294_FIXUP_ASUS_INTSPK_GPIO] = { | 7010 | [ALC289_FIXUP_DUAL_SPK] = { |
| 7011 | .type = HDA_FIXUP_FUNC, | ||
| 7012 | .v.func = alc285_fixup_speaker2_to_dac1, | ||
| 7013 | .chained = true, | ||
| 7014 | .chain_id = ALC289_FIXUP_DELL_SPK2 | ||
| 7015 | }, | ||
| 7016 | [ALC294_FIXUP_SPK2_TO_DAC1] = { | ||
| 7017 | .type = HDA_FIXUP_FUNC, | ||
| 7018 | .v.func = alc285_fixup_speaker2_to_dac1, | ||
| 7019 | .chained = true, | ||
| 7020 | .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC | ||
| 7021 | }, | ||
| 7022 | [ALC294_FIXUP_ASUS_DUAL_SPK] = { | ||
| 7005 | .type = HDA_FIXUP_FUNC, | 7023 | .type = HDA_FIXUP_FUNC, |
| 7006 | /* The GPIO must be pulled to initialize the AMP */ | 7024 | /* The GPIO must be pulled to initialize the AMP */ |
| 7007 | .v.func = alc_fixup_gpio4, | 7025 | .v.func = alc_fixup_gpio4, |
| 7008 | .chained = true, | 7026 | .chained = true, |
| 7009 | .chain_id = ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC | 7027 | .chain_id = ALC294_FIXUP_SPK2_TO_DAC1 |
| 7010 | }, | 7028 | }, |
| 7029 | |||
| 7011 | }; | 7030 | }; |
| 7012 | 7031 | ||
| 7013 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 7032 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
| @@ -7080,6 +7099,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 66 unmodified lines | |||
| 7080 | SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), | 7099 | SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), |
| 7081 | SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), | 7100 | SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 7082 | SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), | 7101 | SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), |
| 7102 | SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK), | ||
| 7103 | SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK), | ||
| 7083 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 7104 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 7084 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 7105 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 7085 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 7106 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
| @@ -7167,7 +7188,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 81 unmodified lines | |||
| 7167 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), | 7188 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), |
| 7168 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), | 7189 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), |
| 7169 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 7190 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
| 7170 | SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_INTSPK_GPIO), | 7191 | SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), |
| 7171 | SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), | 7192 | SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), |
| 7172 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 7193 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
| 7173 | SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), | 7194 | SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), |
| @@ -7239,6 +7260,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 65 unmodified lines | |||
| 7239 | SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), | 7260 | SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), |
| 7240 | SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), | 7261 | SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), |
| 7241 | SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 7262 | SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 7263 | SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1), | ||
| 7242 | SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1), | 7264 | SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1), |
| 7243 | SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | 7265 | SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), |
| 7244 | SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | 7266 | SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), |
| @@ -9237,6 +9259,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { · 1992 unmodified lines | |||
| 9237 | HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662), | 9259 | HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662), |
| 9238 | HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882), | 9260 | HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882), |
| 9239 | HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882), | 9261 | HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882), |
| 9262 | HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882), | ||
| 9240 | HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882), | 9263 | HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882), |
| 9241 | HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882), | 9264 | HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882), |
| 9242 | {} /* terminator */ | 9265 | {} /* terminator */ |
| @@ -647,6 +647,7 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, · 646 unmodified lines | |||
| 647 | unsigned long flags; | 647 | unsigned long flags; |
| 648 | unsigned char mclk_change; | 648 | unsigned char mclk_change; |
| 649 | unsigned int i, old_rate; | 649 | unsigned int i, old_rate; |
| 650 | bool call_set_rate = false; | ||
| 650 | 651 | ||
| 651 | if (rate > ice->hw_rates->list[ice->hw_rates->count - 1]) | 652 | if (rate > ice->hw_rates->list[ice->hw_rates->count - 1]) |
| 652 | return -EINVAL; | 653 | return -EINVAL; |
| @@ -670,7 +671,7 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, · 17 unmodified lines | |||
| 670 | * setting clock rate for internal clock mode */ | 671 | * setting clock rate for internal clock mode */ |
| 671 | old_rate = ice->get_rate(ice); | 672 | old_rate = ice->get_rate(ice); |
| 672 | if (force || (old_rate != rate)) | 673 | if (force || (old_rate != rate)) |
| 673 | ice->set_rate(ice, rate); | 674 | call_set_rate = true; |
| 674 | else if (rate == ice->cur_rate) { | 675 | else if (rate == ice->cur_rate) { |
| 675 | spin_unlock_irqrestore(&ice->reg_lock, flags); | 676 | spin_unlock_irqrestore(&ice->reg_lock, flags); |
| 676 | return 0; | 677 | return 0; |
| @@ -678,12 +679,14 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, · 1 unmodified line | |||
| 678 | } | 679 | } |
| 679 | 680 | ||
| 680 | ice->cur_rate = rate; | 681 | ice->cur_rate = rate; |
| 682 | spin_unlock_irqrestore(&ice->reg_lock, flags); | ||
| 683 | |||
| 684 | if (call_set_rate) | ||
| 685 | ice->set_rate(ice, rate); | ||
| 681 | 686 | ||
| 682 | /* setting master clock */ | 687 | /* setting master clock */ |
| 683 | mclk_change = ice->set_mclk(ice, rate); | 688 | mclk_change = ice->set_mclk(ice, rate); |
| 684 | 689 | ||
| 685 | spin_unlock_irqrestore(&ice->reg_lock, flags); | ||
| 686 | |||
| 687 | if (mclk_change && ice->gpio.i2s_mclk_changed) | 690 | if (mclk_change && ice->gpio.i2s_mclk_changed) |
| 688 | ice->gpio.i2s_mclk_changed(ice); | 691 | ice->gpio.i2s_mclk_changed(ice); |
| 689 | if (ice->gpio.set_pro_rate) | 692 | if (ice->gpio.set_pro_rate) |
| @@ -505,15 +505,20 @@ static int fsl_audmix_probe(struct platform_device *pdev) · 504 unmodified lines | |||
| 505 | ARRAY_SIZE(fsl_audmix_dai)); | 505 | ARRAY_SIZE(fsl_audmix_dai)); |
| 506 | if (ret) { | 506 | if (ret) { |
| 507 | dev_err(dev, "failed to register ASoC DAI\n"); | 507 | dev_err(dev, "failed to register ASoC DAI\n"); |
| 508 | return ret; | 508 | goto err_disable_pm; |
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0); | 511 | priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0); |
| 512 | if (IS_ERR(priv->pdev)) { | 512 | if (IS_ERR(priv->pdev)) { |
| 513 | ret = PTR_ERR(priv->pdev); | 513 | ret = PTR_ERR(priv->pdev); |
| 514 | dev_err(dev, "failed to register platform %s: %d\n", mdrv, ret); | 514 | dev_err(dev, "failed to register platform %s: %d\n", mdrv, ret); |
| 515 | goto err_disable_pm; | ||
| 515 | } | 516 | } |
| 516 | 517 | ||
| 518 | return 0; | ||
| 519 | |||
| 520 | err_disable_pm: | ||
| 521 | pm_runtime_disable(dev); | ||
| 517 | return ret; | 522 | return ret; |
| 518 | } | 523 | } |
| 519 | 524 | ||
| @@ -521,6 +526,8 @@ static int fsl_audmix_remove(struct platform_device *pdev) · 1 unmodified line | |||
| 521 | { | 526 | { |
| 522 | struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev); | 527 | struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev); |
| 523 | 528 | ||
| 529 | pm_runtime_disable(&pdev->dev); | ||
| 530 | |||
| 524 | if (priv->pdev) | 531 | if (priv->pdev) |
| 525 | platform_device_unregister(priv->pdev); | 532 | platform_device_unregister(priv->pdev); |
| 526 | 533 | ||
| @@ -11,7 +11,6 @@ · 10 unmodified lines | |||
| 11 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
| 12 | #include <linux/dmi.h> | 12 | #include <linux/dmi.h> |
| 13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| 14 | #include <asm/cpu_device_id.h> | ||
| 15 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
| 16 | #include <sound/core.h> | 15 | #include <sound/core.h> |
| 17 | #include <sound/jack.h> | 16 | #include <sound/jack.h> |
| @@ -479,6 +479,12 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( · 478 unmodified lines | |||
| 479 | goto free_rtd; | 479 | goto free_rtd; |
| 480 | 480 | ||
| 481 | rtd->dev = dev; | 481 | rtd->dev = dev; |
| 482 | INIT_LIST_HEAD(&rtd->list); | ||
| 483 | INIT_LIST_HEAD(&rtd->component_list); | ||
| 484 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients); | ||
| 485 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients); | ||
| 486 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients); | ||
| 487 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); | ||
| 482 | dev_set_drvdata(dev, rtd); | 488 | dev_set_drvdata(dev, rtd); |
| 483 | INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); | 489 | INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); |
| 484 | 490 | ||
| @@ -494,12 +500,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( · 9 unmodified lines | |||
| 494 | /* | 500 | /* |
| 495 | * rtd remaining settings | 501 | * rtd remaining settings |
| 496 | */ | 502 | */ |
| 497 | INIT_LIST_HEAD(&rtd->component_list); | ||
| 498 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients); | ||
| 499 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients); | ||
| 500 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients); | ||
| 501 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); | ||
| 502 | |||
| 503 | rtd->card = card; | 503 | rtd->card = card; |
| 504 | rtd->dai_link = dai_link; | 504 | rtd->dai_link = dai_link; |
| 505 | if (!rtd->dai_link->ops) | 505 | if (!rtd->dai_link->ops) |
| @@ -1871,6 +1871,8 @@ match: · 1365 unmodified lines | |||
| 1871 | 1871 | ||
| 1872 | /* convert non BE into BE */ | 1872 | /* convert non BE into BE */ |
| 1873 | dai_link->no_pcm = 1; | 1873 | dai_link->no_pcm = 1; |
| 1874 | dai_link->dpcm_playback = 1; | ||
| 1875 | dai_link->dpcm_capture = 1; | ||
| 1874 | 1876 | ||
| 1875 | /* override any BE fixups */ | 1877 | /* override any BE fixups */ |
| 1876 | dai_link->be_hw_params_fixup = | 1878 | dai_link->be_hw_params_fixup = |
| @@ -548,12 +548,12 @@ static void remove_link(struct snd_soc_component *comp, · 547 unmodified lines | |||
| 548 | if (dobj->ops && dobj->ops->link_unload) | 548 | if (dobj->ops && dobj->ops->link_unload) |
| 549 | dobj->ops->link_unload(comp, dobj); | 549 | dobj->ops->link_unload(comp, dobj); |
| 550 | 550 | ||
| 551 | list_del(&dobj->list); | ||
| 552 | snd_soc_remove_dai_link(comp->card, link); | ||
| 553 | |||
| 551 | kfree(link->name); | 554 | kfree(link->name); |
| 552 | kfree(link->stream_name); | 555 | kfree(link->stream_name); |
| 553 | kfree(link->cpus->dai_name); | 556 | kfree(link->cpus->dai_name); |
| 554 | |||
| 555 | list_del(&dobj->list); | ||
| 556 | snd_soc_remove_dai_link(comp->card, link); | ||
| 557 | kfree(link); | 557 | kfree(link); |
| 558 | } | 558 | } |
| 559 | 559 | ||
| @@ -209,7 +209,7 @@ static int imx8_probe(struct snd_sof_dev *sdev) · 208 unmodified lines | |||
| 209 | 209 | ||
| 210 | priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains, | 210 | priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains, |
| 211 | sizeof(*priv->pd_dev), GFP_KERNEL); | 211 | sizeof(*priv->pd_dev), GFP_KERNEL); |
| 212 | if (!priv) | 212 | if (!priv->pd_dev) |
| 213 | return -ENOMEM; | 213 | return -ENOMEM; |
| 214 | 214 | ||
| 215 | priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains, | 215 | priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains, |
| @@ -304,6 +304,9 @@ static int imx8_probe(struct snd_sof_dev *sdev) · 88 unmodified lines | |||
| 304 | } | 304 | } |
| 305 | sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; | 305 | sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; |
| 306 | 306 | ||
| 307 | /* set default mailbox offset for FW ready message */ | ||
| 308 | sdev->dsp_box.offset = MBOX_OFFSET; | ||
| 309 | |||
| 307 | return 0; | 310 | return 0; |
| 308 | 311 | ||
| 309 | exit_pdev_unregister: | 312 | exit_pdev_unregister: |
| @@ -216,6 +216,8 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream, · 215 unmodified lines | |||
| 216 | link_dev = hda_link_stream_assign(bus, substream); | 216 | link_dev = hda_link_stream_assign(bus, substream); |
| 217 | if (!link_dev) | 217 | if (!link_dev) |
| 218 | return -EBUSY; | 218 | return -EBUSY; |
| 219 | |||
| 220 | snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); | ||
| 219 | } | 221 | } |
| 220 | 222 | ||
| 221 | stream_tag = hdac_stream(link_dev)->stream_tag; | 223 | stream_tag = hdac_stream(link_dev)->stream_tag; |
| @@ -228,8 +230,6 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream, · 6 unmodified lines | |||
| 228 | if (ret < 0) | 230 | if (ret < 0) |
| 229 | return ret; | 231 | return ret; |
| 230 | 232 | ||
| 231 | snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); | ||
| 232 | |||
| 233 | link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); | 233 | link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); |
| 234 | if (!link) | 234 | if (!link) |
| 235 | return -EINVAL; | 235 | return -EINVAL; |
| @@ -361,6 +361,13 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream, · 125 unmodified lines | |||
| 361 | bus = hstream->bus; | 361 | bus = hstream->bus; |
| 362 | rtd = snd_pcm_substream_chip(substream); | 362 | rtd = snd_pcm_substream_chip(substream); |
| 363 | link_dev = snd_soc_dai_get_dma_data(dai, substream); | 363 | link_dev = snd_soc_dai_get_dma_data(dai, substream); |
| 364 | |||
| 365 | if (!link_dev) { | ||
| 366 | dev_dbg(dai->dev, | ||
| 367 | "%s: link_dev is not assigned\n", __func__); | ||
| 368 | return -EINVAL; | ||
| 369 | } | ||
| 370 | |||
| 364 | hda_stream = hstream_to_sof_hda_stream(link_dev); | 371 | hda_stream = hstream_to_sof_hda_stream(link_dev); |
| 365 | 372 | ||
| 366 | /* free the link DMA channel in the FW */ | 373 | /* free the link DMA channel in the FW */ |
| @@ -826,6 +826,9 @@ void snd_sof_ipc_free(struct snd_sof_dev *sdev) · 825 unmodified lines | |||
| 826 | { | 826 | { |
| 827 | struct snd_sof_ipc *ipc = sdev->ipc; | 827 | struct snd_sof_ipc *ipc = sdev->ipc; |
| 828 | 828 | ||
| 829 | if (!ipc) | ||
| 830 | return; | ||
| 831 | |||
| 829 | /* disable sending of ipc's */ | 832 | /* disable sending of ipc's */ |
| 830 | mutex_lock(&ipc->tx_mutex); | 833 | mutex_lock(&ipc->tx_mutex); |
| 831 | ipc->disable_ipc_tx = true; | 834 | ipc->disable_ipc_tx = true; |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | |||
| 12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/of_platform.h> | 14 | #include <linux/of_platform.h> |
| 15 | #include <linux/pinctrl/consumer.h> | ||
| 16 | #include <linux/regmap.h> | 15 | #include <linux/regmap.h> |
| 17 | #include <linux/reset.h> | 16 | #include <linux/reset.h> |
| 18 | 17 | ||
| @@ -220,6 +219,7 @@ · 201 unmodified lines | |||
| 220 | * @slave_config: dma slave channel runtime config pointer | 219 | * @slave_config: dma slave channel runtime config pointer |
| 221 | * @phys_addr: SPDIFRX registers physical base address | 220 | * @phys_addr: SPDIFRX registers physical base address |
| 222 | * @lock: synchronization enabling lock | 221 | * @lock: synchronization enabling lock |
| 222 | * @irq_lock: prevent race condition with IRQ on stream state | ||
| 223 | * @cs: channel status buffer | 223 | * @cs: channel status buffer |
| 224 | * @ub: user data buffer | 224 | * @ub: user data buffer |
| 225 | * @irq: SPDIFRX interrupt line | 225 | * @irq: SPDIFRX interrupt line |
| @@ -240,6 +240,7 @@ struct stm32_spdifrx_data { · 14 unmodified lines | |||
| 240 | struct dma_slave_config slave_config; | 240 | struct dma_slave_config slave_config; |
| 241 | dma_addr_t phys_addr; | 241 | dma_addr_t phys_addr; |
| 242 | spinlock_t lock; /* Sync enabling lock */ | 242 | spinlock_t lock; /* Sync enabling lock */ |
| 243 | spinlock_t irq_lock; /* Prevent race condition on stream state */ | ||
| 243 | unsigned char cs[SPDIFRX_CS_BYTES_NB]; | 244 | unsigned char cs[SPDIFRX_CS_BYTES_NB]; |
| 244 | unsigned char ub[SPDIFRX_UB_BYTES_NB]; | 245 | unsigned char ub[SPDIFRX_UB_BYTES_NB]; |
| 245 | int irq; | 246 | int irq; |
| @@ -320,6 +321,7 @@ static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx) · 74 unmodified lines | |||
| 320 | static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) | 321 | static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) |
| 321 | { | 322 | { |
| 322 | int cr, cr_mask, imr, ret; | 323 | int cr, cr_mask, imr, ret; |
| 324 | unsigned long flags; | ||
| 323 | 325 | ||
| 324 | /* Enable IRQs */ | 326 | /* Enable IRQs */ |
| 325 | imr = SPDIFRX_IMR_IFEIE | SPDIFRX_IMR_SYNCDIE | SPDIFRX_IMR_PERRIE; | 327 | imr = SPDIFRX_IMR_IFEIE | SPDIFRX_IMR_SYNCDIE | SPDIFRX_IMR_PERRIE; |
| @@ -327,7 +329,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) · 1 unmodified line | |||
| 327 | if (ret) | 329 | if (ret) |
| 328 | return ret; | 330 | return ret; |
| 329 | 331 | ||
| 330 | spin_lock(&spdifrx->lock); | 332 | spin_lock_irqsave(&spdifrx->lock, flags); |
| 331 | 333 | ||
| 332 | spdifrx->refcount++; | 334 | spdifrx->refcount++; |
| 333 | 335 | ||
| @@ -362,7 +364,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) · 28 unmodified lines | |||
| 362 | "Failed to start synchronization\n"); | 364 | "Failed to start synchronization\n"); |
| 363 | } | 365 | } |
| 364 | 366 | ||
| 365 | spin_unlock(&spdifrx->lock); | 367 | spin_unlock_irqrestore(&spdifrx->lock, flags); |
| 366 | 368 | ||
| 367 | return ret; | 369 | return ret; |
| 368 | } | 370 | } |
| @@ -370,11 +372,12 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) · 1 unmodified line | |||
| 370 | static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx) | 372 | static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx) |
| 371 | { | 373 | { |
| 372 | int cr, cr_mask, reg; | 374 | int cr, cr_mask, reg; |
| 375 | unsigned long flags; | ||
| 373 | 376 | ||
| 374 | spin_lock(&spdifrx->lock); | 377 | spin_lock_irqsave(&spdifrx->lock, flags); |
| 375 | 378 | ||
| 376 | if (--spdifrx->refcount) { | 379 | if (--spdifrx->refcount) { |
| 377 | spin_unlock(&spdifrx->lock); | 380 | spin_unlock_irqrestore(&spdifrx->lock, flags); |
| 378 | return; | 381 | return; |
| 379 | } | 382 | } |
| 380 | 383 | ||
| @@ -393,7 +396,7 @@ static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx) · 12 unmodified lines | |||
| 393 | regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, ®); | 396 | regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, ®); |
| 394 | regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, ®); | 397 | regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, ®); |
| 395 | 398 | ||
| 396 | spin_unlock(&spdifrx->lock); | 399 | spin_unlock_irqrestore(&spdifrx->lock, flags); |
| 397 | } | 400 | } |
| 398 | 401 | ||
| 399 | static int stm32_spdifrx_dma_ctrl_register(struct device *dev, | 402 | static int stm32_spdifrx_dma_ctrl_register(struct device *dev, |
| @@ -480,8 +483,6 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx) · 80 unmodified lines | |||
| 480 | memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB); | 483 | memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB); |
| 481 | memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB); | 484 | memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB); |
| 482 | 485 | ||
| 483 | pinctrl_pm_select_default_state(&spdifrx->pdev->dev); | ||
| 484 | |||
| 485 | ret = stm32_spdifrx_dma_ctrl_start(spdifrx); | 486 | ret = stm32_spdifrx_dma_ctrl_start(spdifrx); |
| 486 | if (ret < 0) | 487 | if (ret < 0) |
| 487 | return ret; | 488 | return ret; |
| @@ -513,7 +514,6 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx) · 25 unmodified lines | |||
| 513 | 514 | ||
| 514 | end: | 515 | end: |
| 515 | clk_disable_unprepare(spdifrx->kclk); | 516 | clk_disable_unprepare(spdifrx->kclk); |
| 516 | pinctrl_pm_select_sleep_state(&spdifrx->pdev->dev); | ||
| 517 | 517 | ||
| 518 | return ret; | 518 | return ret; |
| 519 | } | 519 | } |
| @@ -665,7 +665,6 @@ static const struct regmap_config stm32_h7_spdifrx_regmap_conf = { · 145 unmodified lines | |||
| 665 | static irqreturn_t stm32_spdifrx_isr(int irq, void *devid) | 665 | static irqreturn_t stm32_spdifrx_isr(int irq, void *devid) |
| 666 | { | 666 | { |
| 667 | struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid; | 667 | struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid; |
| 668 | struct snd_pcm_substream *substream = spdifrx->substream; | ||
| 669 | struct platform_device *pdev = spdifrx->pdev; | 668 | struct platform_device *pdev = spdifrx->pdev; |
| 670 | unsigned int cr, mask, sr, imr; | 669 | unsigned int cr, mask, sr, imr; |
| 671 | unsigned int flags, sync_state; | 670 | unsigned int flags, sync_state; |
| @@ -745,14 +744,19 @@ static irqreturn_t stm32_spdifrx_isr(int irq, void *devid) · 73 unmodified lines | |||
| 745 | return IRQ_HANDLED; | 744 | return IRQ_HANDLED; |
| 746 | } | 745 | } |
| 747 | 746 | ||
| 748 | if (substream) | 747 | spin_lock(&spdifrx->irq_lock); |
| 749 | snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); | 748 | if (spdifrx->substream) |
| 749 | snd_pcm_stop(spdifrx->substream, | ||
| 750 | SNDRV_PCM_STATE_DISCONNECTED); | ||
| 751 | spin_unlock(&spdifrx->irq_lock); | ||
| 750 | 752 | ||
| 751 | return IRQ_HANDLED; | 753 | return IRQ_HANDLED; |
| 752 | } | 754 | } |
| 753 | 755 | ||
| 754 | if (err_xrun && substream) | 756 | spin_lock(&spdifrx->irq_lock); |
| 755 | snd_pcm_stop_xrun(substream); | 757 | if (err_xrun && spdifrx->substream) |
| 758 | snd_pcm_stop_xrun(spdifrx->substream); | ||
| 759 | spin_unlock(&spdifrx->irq_lock); | ||
| 756 | 760 | ||
| 757 | return IRQ_HANDLED; | 761 | return IRQ_HANDLED; |
| 758 | } | 762 | } |
| @@ -761,9 +765,12 @@ static int stm32_spdifrx_startup(struct snd_pcm_substream *substream, · 2 unmodified lines | |||
| 761 | struct snd_soc_dai *cpu_dai) | 765 | struct snd_soc_dai *cpu_dai) |
| 762 | { | 766 | { |
| 763 | struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); | 767 | struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); |
| 768 | unsigned long flags; | ||
| 764 | int ret; | 769 | int ret; |
| 765 | 770 | ||
| 771 | spin_lock_irqsave(&spdifrx->irq_lock, flags); | ||
| 766 | spdifrx->substream = substream; | 772 | spdifrx->substream = substream; |
| 773 | spin_unlock_irqrestore(&spdifrx->irq_lock, flags); | ||
| 767 | 774 | ||
| 768 | ret = clk_prepare_enable(spdifrx->kclk); | 775 | ret = clk_prepare_enable(spdifrx->kclk); |
| 769 | if (ret) | 776 | if (ret) |
| @@ -839,8 +846,12 @@ static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream, · 69 unmodified lines | |||
| 839 | struct snd_soc_dai *cpu_dai) | 846 | struct snd_soc_dai *cpu_dai) |
| 840 | { | 847 | { |
| 841 | struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); | 848 | struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); |
| 849 | unsigned long flags; | ||
| 842 | 850 | ||
| 851 | spin_lock_irqsave(&spdifrx->irq_lock, flags); | ||
| 843 | spdifrx->substream = NULL; | 852 | spdifrx->substream = NULL; |
| 853 | spin_unlock_irqrestore(&spdifrx->irq_lock, flags); | ||
| 854 | |||
| 844 | clk_disable_unprepare(spdifrx->kclk); | 855 | clk_disable_unprepare(spdifrx->kclk); |
| 845 | } | 856 | } |
| 846 | 857 | ||
| @@ -944,6 +955,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev) · 97 unmodified lines | |||
| 944 | spdifrx->pdev = pdev; | 955 | spdifrx->pdev = pdev; |
| 945 | init_completion(&spdifrx->cs_completion); | 956 | init_completion(&spdifrx->cs_completion); |
| 946 | spin_lock_init(&spdifrx->lock); | 957 | spin_lock_init(&spdifrx->lock); |
| 958 | spin_lock_init(&spdifrx->irq_lock); | ||
| 947 | 959 | ||
| 948 | platform_set_drvdata(pdev, spdifrx); | 960 | platform_set_drvdata(pdev, spdifrx); |
| 949 | 961 | ||
| @@ -145,6 +145,7 @@ struct snd_usb_substream { · 144 unmodified lines | |||
| 145 | struct snd_usb_endpoint *sync_endpoint; | 145 | struct snd_usb_endpoint *sync_endpoint; |
| 146 | unsigned long flags; | 146 | unsigned long flags; |
| 147 | bool need_setup_ep; /* (re)configure EP at prepare? */ | 147 | bool need_setup_ep; /* (re)configure EP at prepare? */ |
| 148 | bool need_setup_fmt; /* (re)configure fmt after resume? */ | ||
| 148 | unsigned int speed; /* USB_SPEED_XXX */ | 149 | unsigned int speed; /* USB_SPEED_XXX */ |
| 149 | 150 | ||
| 150 | u64 formats; /* format bitmasks (all or'ed) */ | 151 | u64 formats; /* format bitmasks (all or'ed) */ |
| @@ -506,15 +506,15 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) · 505 unmodified lines | |||
| 506 | if (WARN_ON(!iface)) | 506 | if (WARN_ON(!iface)) |
| 507 | return -EINVAL; | 507 | return -EINVAL; |
| 508 | alts = usb_altnum_to_altsetting(iface, fmt->altsetting); | 508 | alts = usb_altnum_to_altsetting(iface, fmt->altsetting); |
| 509 | altsd = get_iface_desc(alts); | 509 | if (WARN_ON(!alts)) |
| 510 | if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting)) | ||
| 511 | return -EINVAL; | 510 | return -EINVAL; |
| 511 | altsd = get_iface_desc(alts); | ||
| 512 | 512 | ||
| 513 | if (fmt == subs->cur_audiofmt) | 513 | if (fmt == subs->cur_audiofmt && !subs->need_setup_fmt) |
| 514 | return 0; | 514 | return 0; |
| 515 | 515 | ||
| 516 | /* close the old interface */ | 516 | /* close the old interface */ |
| 517 | if (subs->interface >= 0 && subs->interface != fmt->iface) { | 517 | if (subs->interface >= 0 && (subs->interface != fmt->iface || subs->need_setup_fmt)) { |
| 518 | if (!subs->stream->chip->keep_iface) { | 518 | if (!subs->stream->chip->keep_iface) { |
| 519 | err = usb_set_interface(subs->dev, subs->interface, 0); | 519 | err = usb_set_interface(subs->dev, subs->interface, 0); |
| 520 | if (err < 0) { | 520 | if (err < 0) { |
| @@ -528,6 +528,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) · 7 unmodified lines | |||
| 528 | subs->altset_idx = 0; | 528 | subs->altset_idx = 0; |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | if (subs->need_setup_fmt) | ||
| 532 | subs->need_setup_fmt = false; | ||
| 533 | |||
| 531 | /* set interface */ | 534 | /* set interface */ |
| 532 | if (iface->cur_altsetting != alts) { | 535 | if (iface->cur_altsetting != alts) { |
| 533 | err = snd_usb_select_mode_quirk(subs, fmt); | 536 | err = snd_usb_select_mode_quirk(subs, fmt); |
| @@ -1728,6 +1731,13 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea · 1194 unmodified lines | |||
| 1728 | subs->data_endpoint->retire_data_urb = retire_playback_urb; | 1731 | subs->data_endpoint->retire_data_urb = retire_playback_urb; |
| 1729 | subs->running = 0; | 1732 | subs->running = 0; |
| 1730 | return 0; | 1733 | return 0; |
| 1734 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 1735 | if (subs->stream->chip->setup_fmt_after_resume_quirk) { | ||
| 1736 | stop_endpoints(subs, true); | ||
| 1737 | subs->need_setup_fmt = true; | ||
| 1738 | return 0; | ||
| 1739 | } | ||
| 1740 | break; | ||
| 1731 | } | 1741 | } |
| 1732 | 1742 | ||
| 1733 | return -EINVAL; | 1743 | return -EINVAL; |
| @@ -1760,6 +1770,13 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream · 26 unmodified lines | |||
| 1760 | subs->data_endpoint->retire_data_urb = retire_capture_urb; | 1770 | subs->data_endpoint->retire_data_urb = retire_capture_urb; |
| 1761 | subs->running = 1; | 1771 | subs->running = 1; |
| 1762 | return 0; | 1772 | return 0; |
| 1773 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 1774 | if (subs->stream->chip->setup_fmt_after_resume_quirk) { | ||
| 1775 | stop_endpoints(subs, true); | ||
| 1776 | subs->need_setup_fmt = true; | ||
| 1777 | return 0; | ||
| 1778 | } | ||
| 1779 | break; | ||
| 1763 | } | 1780 | } |
| 1764 | 1781 | ||
| 1765 | return -EINVAL; | 1782 | return -EINVAL; |
| @@ -3466,7 +3466,8 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), · 3465 unmodified lines | |||
| 3466 | .vendor_name = "Dell", | 3466 | .vendor_name = "Dell", |
| 3467 | .product_name = "WD19 Dock", | 3467 | .product_name = "WD19 Dock", |
| 3468 | .profile_name = "Dell-WD15-Dock", | 3468 | .profile_name = "Dell-WD15-Dock", |
| 3469 | .ifnum = QUIRK_NO_INTERFACE | 3469 | .ifnum = QUIRK_ANY_INTERFACE, |
| 3470 | .type = QUIRK_SETUP_FMT_AFTER_RESUME | ||
| 3470 | } | 3471 | } |
| 3471 | }, | 3472 | }, |
| 3472 | /* MOTU Microbook II */ | 3473 | /* MOTU Microbook II */ |
| @@ -508,6 +508,16 @@ static int create_standard_mixer_quirk(struct snd_usb_audio *chip, · 507 unmodified lines | |||
| 508 | return snd_usb_create_mixer(chip, quirk->ifnum, 0); | 508 | return snd_usb_create_mixer(chip, quirk->ifnum, 0); |
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | |||
| 512 | static int setup_fmt_after_resume_quirk(struct snd_usb_audio *chip, | ||
| 513 | struct usb_interface *iface, | ||
| 514 | struct usb_driver *driver, | ||
| 515 | const struct snd_usb_audio_quirk *quirk) | ||
| 516 | { | ||
| 517 | chip->setup_fmt_after_resume_quirk = 1; | ||
| 518 | return 1; /* Continue with creating streams and mixer */ | ||
| 519 | } | ||
| 520 | |||
| 511 | /* | 521 | /* |
| 512 | * audio-interface quirks | 522 | * audio-interface quirks |
| 513 | * | 523 | * |
| @@ -546,6 +556,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, · 32 unmodified lines | |||
| 546 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, | 556 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, |
| 547 | [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk, | 557 | [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk, |
| 548 | [QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk, | 558 | [QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk, |
| 559 | [QUIRK_SETUP_FMT_AFTER_RESUME] = setup_fmt_after_resume_quirk, | ||
| 549 | }; | 560 | }; |
| 550 | 561 | ||
| 551 | if (quirk->type < QUIRK_TYPE_COUNT) { | 562 | if (quirk->type < QUIRK_TYPE_COUNT) { |
| @@ -1386,6 +1397,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) · 834 unmodified lines | |||
| 1386 | case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ | 1397 | case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ |
| 1387 | case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ | 1398 | case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ |
| 1388 | case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ | 1399 | case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ |
| 1400 | case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */ | ||
| 1389 | case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ | 1401 | case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ |
| 1390 | case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */ | 1402 | case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */ |
| 1391 | case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ | 1403 | case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ |
| @@ -33,7 +33,7 @@ struct snd_usb_audio { · 32 unmodified lines | |||
| 33 | wait_queue_head_t shutdown_wait; | 33 | wait_queue_head_t shutdown_wait; |
| 34 | unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ | 34 | unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ |
| 35 | unsigned int tx_length_quirk:1; /* Put length specifier in transfers */ | 35 | unsigned int tx_length_quirk:1; /* Put length specifier in transfers */ |
| 36 | 36 | unsigned int setup_fmt_after_resume_quirk:1; /* setup the format to interface after resume */ | |
| 37 | int num_interfaces; | 37 | int num_interfaces; |
| 38 | int num_suspended_intf; | 38 | int num_suspended_intf; |
| 39 | int sample_rate_read_error; | 39 | int sample_rate_read_error; |
| @@ -98,6 +98,7 @@ enum quirk_type { · 58 unmodified lines | |||
| 98 | QUIRK_AUDIO_EDIROL_UAXX, | 98 | QUIRK_AUDIO_EDIROL_UAXX, |
| 99 | QUIRK_AUDIO_ALIGN_TRANSFER, | 99 | QUIRK_AUDIO_ALIGN_TRANSFER, |
| 100 | QUIRK_AUDIO_STANDARD_MIXER, | 100 | QUIRK_AUDIO_STANDARD_MIXER, |
| 101 | QUIRK_SETUP_FMT_AFTER_RESUME, | ||
| 101 | 102 | ||
| 102 | QUIRK_TYPE_COUNT | 103 | QUIRK_TYPE_COUNT |
| 103 | }; | 104 | }; |
| @@ -138,6 +138,7 @@ STATIC_OBJDIR := $(OUTPUT)staticobjs/ · 137 unmodified lines | |||
| 138 | BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o | 138 | BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o |
| 139 | BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o | 139 | BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o |
| 140 | VERSION_SCRIPT := libbpf.map | 140 | VERSION_SCRIPT := libbpf.map |
| 141 | BPF_HELPER_DEFS := $(OUTPUT)bpf_helper_defs.h | ||
| 141 | 142 | ||
| 142 | LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) | 143 | LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) |
| 143 | LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) | 144 | LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) |
| @@ -159,7 +160,7 @@ all: fixdep · 15 unmodified lines | |||
| 159 | 160 | ||
| 160 | all_cmd: $(CMD_TARGETS) check | 161 | all_cmd: $(CMD_TARGETS) check |
| 161 | 162 | ||
| 162 | $(BPF_IN_SHARED): force elfdep bpfdep bpf_helper_defs.h | 163 | $(BPF_IN_SHARED): force elfdep bpfdep $(BPF_HELPER_DEFS) |
| 163 | @(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ | 164 | @(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ |
| 164 | (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \ | 165 | (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \ |
| 165 | echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true | 166 | echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true |
| @@ -177,12 +178,12 @@ $(BPF_IN_SHARED): force elfdep bpfdep bpf_helper_defs.h · 11 unmodified lines | |||
| 177 | echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true | 178 | echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true |
| 178 | $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(SHARED_OBJDIR) CFLAGS="$(CFLAGS) $(SHLIB_FLAGS)" | 179 | $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(SHARED_OBJDIR) CFLAGS="$(CFLAGS) $(SHLIB_FLAGS)" |
| 179 | 180 | ||
| 180 | $(BPF_IN_STATIC): force elfdep bpfdep bpf_helper_defs.h | 181 | $(BPF_IN_STATIC): force elfdep bpfdep $(BPF_HELPER_DEFS) |
| 181 | $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR) | 182 | $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR) |
| 182 | 183 | ||
| 183 | bpf_helper_defs.h: $(srctree)/tools/include/uapi/linux/bpf.h | 184 | $(BPF_HELPER_DEFS): $(srctree)/tools/include/uapi/linux/bpf.h |
| 184 | $(Q)$(srctree)/scripts/bpf_helpers_doc.py --header \ | 185 | $(Q)$(srctree)/scripts/bpf_helpers_doc.py --header \ |
| 185 | --file $(srctree)/tools/include/uapi/linux/bpf.h > bpf_helper_defs.h | 186 | --file $(srctree)/tools/include/uapi/linux/bpf.h > $(BPF_HELPER_DEFS) |
| 186 | 187 | ||
| 187 | $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) | 188 | $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) |
| 188 | 189 | ||
| @@ -243,7 +244,7 @@ install_lib: all_cmd · 54 unmodified lines | |||
| 243 | $(call do_install_mkdir,$(libdir_SQ)); \ | 244 | $(call do_install_mkdir,$(libdir_SQ)); \ |
| 244 | cp -fpR $(LIB_FILE) $(DESTDIR)$(libdir_SQ) | 245 | cp -fpR $(LIB_FILE) $(DESTDIR)$(libdir_SQ) |
| 245 | 246 | ||
| 246 | install_headers: bpf_helper_defs.h | 247 | install_headers: $(BPF_HELPER_DEFS) |
| 247 | $(call QUIET_INSTALL, headers) \ | 248 | $(call QUIET_INSTALL, headers) \ |
| 248 | $(call do_install,bpf.h,$(prefix)/include/bpf,644); \ | 249 | $(call do_install,bpf.h,$(prefix)/include/bpf,644); \ |
| 249 | $(call do_install,libbpf.h,$(prefix)/include/bpf,644); \ | 250 | $(call do_install,libbpf.h,$(prefix)/include/bpf,644); \ |
| @@ -251,7 +252,7 @@ install_headers: bpf_helper_defs.h · 1 unmodified line | |||
| 251 | $(call do_install,libbpf_util.h,$(prefix)/include/bpf,644); \ | 252 | $(call do_install,libbpf_util.h,$(prefix)/include/bpf,644); \ |
| 252 | $(call do_install,xsk.h,$(prefix)/include/bpf,644); \ | 253 | $(call do_install,xsk.h,$(prefix)/include/bpf,644); \ |
| 253 | $(call do_install,bpf_helpers.h,$(prefix)/include/bpf,644); \ | 254 | $(call do_install,bpf_helpers.h,$(prefix)/include/bpf,644); \ |
| 254 | $(call do_install,bpf_helper_defs.h,$(prefix)/include/bpf,644); \ | 255 | $(call do_install,$(BPF_HELPER_DEFS),$(prefix)/include/bpf,644); \ |
| 255 | $(call do_install,bpf_tracing.h,$(prefix)/include/bpf,644); \ | 256 | $(call do_install,bpf_tracing.h,$(prefix)/include/bpf,644); \ |
| 256 | $(call do_install,bpf_endian.h,$(prefix)/include/bpf,644); \ | 257 | $(call do_install,bpf_endian.h,$(prefix)/include/bpf,644); \ |
| 257 | $(call do_install,bpf_core_read.h,$(prefix)/include/bpf,644); | 258 | $(call do_install,bpf_core_read.h,$(prefix)/include/bpf,644); |
| @@ -271,7 +272,7 @@ config-clean: · 13 unmodified lines | |||
| 271 | clean: | 272 | clean: |
| 272 | $(call QUIET_CLEAN, libbpf) $(RM) -rf $(CMD_TARGETS) \ | 273 | $(call QUIET_CLEAN, libbpf) $(RM) -rf $(CMD_TARGETS) \ |
| 273 | *.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \ | 274 | *.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \ |
| 274 | *.pc LIBBPF-CFLAGS bpf_helper_defs.h \ | 275 | *.pc LIBBPF-CFLAGS $(BPF_HELPER_DEFS) \ |
| 275 | $(SHARED_OBJDIR) $(STATIC_OBJDIR) | 276 | $(SHARED_OBJDIR) $(STATIC_OBJDIR) |
| 276 | $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf | 277 | $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf |
| 277 | 278 | ||
| @@ -31,15 +31,12 @@ class KunitStatus(Enum): · 30 unmodified lines | |||
| 31 | TEST_FAILURE = auto() | 31 | TEST_FAILURE = auto() |
| 32 | 32 | ||
| 33 | def create_default_kunitconfig(): | 33 | def create_default_kunitconfig(): |
| 34 | if not os.path.exists(kunit_kernel.KUNITCONFIG_PATH): | 34 | if not os.path.exists(kunit_kernel.kunitconfig_path): |
| 35 | shutil.copyfile('arch/um/configs/kunit_defconfig', | 35 | shutil.copyfile('arch/um/configs/kunit_defconfig', |
| 36 | kunit_kernel.KUNITCONFIG_PATH) | 36 | kunit_kernel.kunitconfig_path) |
| 37 | 37 | ||
| 38 | def run_tests(linux: kunit_kernel.LinuxSourceTree, | 38 | def run_tests(linux: kunit_kernel.LinuxSourceTree, |
| 39 | request: KunitRequest) -> KunitResult: | 39 | request: KunitRequest) -> KunitResult: |
| 40 | if request.defconfig: | ||
| 41 | create_default_kunitconfig() | ||
| 42 | |||
| 43 | config_start = time.time() | 40 | config_start = time.time() |
| 44 | success = linux.build_reconfig(request.build_dir) | 41 | success = linux.build_reconfig(request.build_dir) |
| 45 | config_end = time.time() | 42 | config_end = time.time() |
| @@ -108,15 +105,22 @@ def main(argv, linux=None): · 62 unmodified lines | |||
| 108 | run_parser.add_argument('--build_dir', | 105 | run_parser.add_argument('--build_dir', |
| 109 | help='As in the make command, it specifies the build ' | 106 | help='As in the make command, it specifies the build ' |
| 110 | 'directory.', | 107 | 'directory.', |
| 111 | type=str, default=None, metavar='build_dir') | 108 | type=str, default='', metavar='build_dir') |
| 112 | 109 | ||
| 113 | run_parser.add_argument('--defconfig', | 110 | run_parser.add_argument('--defconfig', |
| 114 | help='Uses a default kunitconfig.', | 111 | help='Uses a default .kunitconfig.', |
| 115 | action='store_true') | 112 | action='store_true') |
| 116 | 113 | ||
| 117 | cli_args = parser.parse_args(argv) | 114 | cli_args = parser.parse_args(argv) |
| 118 | 115 | ||
| 119 | if cli_args.subcommand == 'run': | 116 | if cli_args.subcommand == 'run': |
| 117 | if cli_args.build_dir: | ||
| 118 | if not os.path.exists(cli_args.build_dir): | ||
| 119 | os.mkdir(cli_args.build_dir) | ||
| 120 | kunit_kernel.kunitconfig_path = os.path.join( | ||
| 121 | cli_args.build_dir, | ||
| 122 | kunit_kernel.kunitconfig_path) | ||
| 123 | |||
| 120 | if cli_args.defconfig: | 124 | if cli_args.defconfig: |
| 121 | create_default_kunitconfig() | 125 | create_default_kunitconfig() |
| 122 | 126 | ||
| @@ -14,7 +14,7 @@ import os · 13 unmodified lines | |||
| 14 | import kunit_config | 14 | import kunit_config |
| 15 | 15 | ||
| 16 | KCONFIG_PATH = '.config' | 16 | KCONFIG_PATH = '.config' |
| 17 | KUNITCONFIG_PATH = 'kunitconfig' | 17 | kunitconfig_path = '.kunitconfig' |
| 18 | 18 | ||
| 19 | class ConfigError(Exception): | 19 | class ConfigError(Exception): |
| 20 | """Represents an error trying to configure the Linux kernel.""" | 20 | """Represents an error trying to configure the Linux kernel.""" |
| @@ -82,7 +82,7 @@ class LinuxSourceTree(object): · 61 unmodified lines | |||
| 82 | 82 | ||
| 83 | def __init__(self): | 83 | def __init__(self): |
| 84 | self._kconfig = kunit_config.Kconfig() | 84 | self._kconfig = kunit_config.Kconfig() |
| 85 | self._kconfig.read_from_file(KUNITCONFIG_PATH) | 85 | self._kconfig.read_from_file(kunitconfig_path) |
| 86 | self._ops = LinuxSourceTreeOperations() | 86 | self._ops = LinuxSourceTreeOperations() |
| 87 | 87 | ||
| 88 | def clean(self): | 88 | def clean(self): |
| @@ -111,7 +111,7 @@ class LinuxSourceTree(object): · 22 unmodified lines | |||
| 111 | return True | 111 | return True |
| 112 | 112 | ||
| 113 | def build_reconfig(self, build_dir): | 113 | def build_reconfig(self, build_dir): |
| 114 | """Creates a new .config if it is not a subset of the kunitconfig.""" | 114 | """Creates a new .config if it is not a subset of the .kunitconfig.""" |
| 115 | kconfig_path = get_kconfig_path(build_dir) | 115 | kconfig_path = get_kconfig_path(build_dir) |
| 116 | if os.path.exists(kconfig_path): | 116 | if os.path.exists(kconfig_path): |
| 117 | existing_kconfig = kunit_config.Kconfig() | 117 | existing_kconfig = kunit_config.Kconfig() |
| @@ -140,10 +140,10 @@ class LinuxSourceTree(object): · 22 unmodified lines | |||
| 140 | return False | 140 | return False |
| 141 | return True | 141 | return True |
| 142 | 142 | ||
| 143 | def run_kernel(self, args=[], timeout=None, build_dir=None): | 143 | def run_kernel(self, args=[], timeout=None, build_dir=''): |
| 144 | args.extend(['mem=256M']) | 144 | args.extend(['mem=256M']) |
| 145 | process = self._ops.linux_bin(args, timeout, build_dir) | 145 | process = self._ops.linux_bin(args, timeout, build_dir) |
| 146 | with open('test.log', 'w') as f: | 146 | with open(os.path.join(build_dir, 'test.log'), 'w') as f: |
| 147 | for line in process.stdout: | 147 | for line in process.stdout: |
| 148 | f.write(line.rstrip().decode('ascii') + '\n') | 148 | f.write(line.rstrip().decode('ascii') + '\n') |
| 149 | yield line.rstrip().decode('ascii') | 149 | yield line.rstrip().decode('ascii') |
| @@ -174,6 +174,7 @@ class KUnitMainTest(unittest.TestCase): · 173 unmodified lines | |||
| 174 | kunit.main(['run'], self.linux_source_mock) | 174 | kunit.main(['run'], self.linux_source_mock) |
| 175 | assert self.linux_source_mock.build_reconfig.call_count == 1 | 175 | assert self.linux_source_mock.build_reconfig.call_count == 1 |
| 176 | assert self.linux_source_mock.run_kernel.call_count == 1 | 176 | assert self.linux_source_mock.run_kernel.call_count == 1 |
| 177 | self.linux_source_mock.run_kernel.assert_called_once_with(build_dir='', timeout=300) | ||
| 177 | self.print_mock.assert_any_call(StrContains('Testing complete.')) | 178 | self.print_mock.assert_any_call(StrContains('Testing complete.')) |
| 178 | 179 | ||
| 179 | def test_run_passes_args_fail(self): | 180 | def test_run_passes_args_fail(self): |
| @@ -199,7 +200,14 @@ class KUnitMainTest(unittest.TestCase): · 19 unmodified lines | |||
| 199 | timeout = 3453 | 200 | timeout = 3453 |
| 200 | kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock) | 201 | kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock) |
| 201 | assert self.linux_source_mock.build_reconfig.call_count == 1 | 202 | assert self.linux_source_mock.build_reconfig.call_count == 1 |
| 202 | self.linux_source_mock.run_kernel.assert_called_once_with(build_dir=None, timeout=timeout) | 203 | self.linux_source_mock.run_kernel.assert_called_once_with(build_dir='', timeout=timeout) |
| 204 | self.print_mock.assert_any_call(StrContains('Testing complete.')) | ||
| 205 | |||
| 206 | def test_run_builddir(self): | ||
| 207 | build_dir = '.kunit' | ||
| 208 | kunit.main(['run', '--build_dir', build_dir], self.linux_source_mock) | ||
| 209 | assert self.linux_source_mock.build_reconfig.call_count == 1 | ||
| 210 | self.linux_source_mock.run_kernel.assert_called_once_with(build_dir=build_dir, timeout=300) | ||
| 203 | self.print_mock.assert_any_call(StrContains('Testing complete.')) | 211 | self.print_mock.assert_any_call(StrContains('Testing complete.')) |
| 204 | 212 | ||
| 205 | if __name__ == '__main__': | 213 | if __name__ == '__main__': |
| @@ -40,3 +40,4 @@ xdping · 39 unmodified lines | |||
| 40 | test_cpp | 40 | test_cpp |
| 41 | /no_alu32 | 41 | /no_alu32 |
| 42 | /bpf_gcc | 42 | /bpf_gcc |
| 43 | bpf_helper_defs.h | ||
| @@ -120,9 +120,9 @@ force: · 119 unmodified lines | |||
| 120 | $(BPFOBJ): force | 120 | $(BPFOBJ): force |
| 121 | $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ | 121 | $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ |
| 122 | 122 | ||
| 123 | BPF_HELPERS := $(BPFDIR)/bpf_helper_defs.h $(wildcard $(BPFDIR)/bpf_*.h) | 123 | BPF_HELPERS := $(OUTPUT)/bpf_helper_defs.h $(wildcard $(BPFDIR)/bpf_*.h) |
| 124 | $(BPFDIR)/bpf_helper_defs.h: | 124 | $(OUTPUT)/bpf_helper_defs.h: |
| 125 | $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ bpf_helper_defs.h | 125 | $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ $(OUTPUT)/bpf_helper_defs.h |
| 126 | 126 | ||
| 127 | # Get Clang's default includes on this system, as opposed to those seen by | 127 | # Get Clang's default includes on this system, as opposed to those seen by |
| 128 | # '-target bpf'. This fixes "missing" files on some architectures/distros, | 128 | # '-target bpf'. This fixes "missing" files on some architectures/distros, |
| @@ -1,7 +1,7 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | ||
| 3 | CFLAGS += -I../../../../../usr/include/ | 3 | CFLAGS += -I../../../../../usr/include/ |
| 4 | LDFLAGS += -lpthread | 4 | LDLIBS += -lpthread |
| 5 | TEST_GEN_PROGS := epoll_wakeup_test | 5 | TEST_GEN_PROGS := epoll_wakeup_test |
| 6 | 6 | ||
| 7 | include ../../lib.mk | 7 | include ../../lib.mk |
| @@ -34,6 +34,12 @@ test_modprobe() · 33 unmodified lines | |||
| 34 | 34 | ||
| 35 | check_mods() | 35 | check_mods() |
| 36 | { | 36 | { |
| 37 | local uid=$(id -u) | ||
| 38 | if [ $uid -ne 0 ]; then | ||
| 39 | echo "skip all tests: must be run as root" >&2 | ||
| 40 | exit $ksft_skip | ||
| 41 | fi | ||
| 42 | |||
| 37 | trap "test_modprobe" EXIT | 43 | trap "test_modprobe" EXIT |
| 38 | if [ ! -d $DIR ]; then | 44 | if [ ! -d $DIR ]; then |
| 39 | modprobe test_firmware | 45 | modprobe test_firmware |
| @@ -7,6 +7,9 @@ · 6 unmodified lines | |||
| 7 | MAX_RETRIES=600 | 7 | MAX_RETRIES=600 |
| 8 | RETRY_INTERVAL=".1" # seconds | 8 | RETRY_INTERVAL=".1" # seconds |
| 9 | 9 | ||
| 10 | # Kselftest framework requirement - SKIP code is 4 | ||
| 11 | ksft_skip=4 | ||
| 12 | |||
| 10 | # log(msg) - write message to kernel log | 13 | # log(msg) - write message to kernel log |
| 11 | # msg - insightful words | 14 | # msg - insightful words |
| 12 | function log() { | 15 | function log() { |
| @@ -18,7 +21,16 @@ function log() { · 5 unmodified lines | |||
| 18 | function skip() { | 21 | function skip() { |
| 19 | log "SKIP: $1" | 22 | log "SKIP: $1" |
| 20 | echo "SKIP: $1" >&2 | 23 | echo "SKIP: $1" >&2 |
| 21 | exit 4 | 24 | exit $ksft_skip |
| 25 | } | ||
| 26 | |||
| 27 | # root test | ||
| 28 | function is_root() { | ||
| 29 | uid=$(id -u) | ||
| 30 | if [ $uid -ne 0 ]; then | ||
| 31 | echo "skip all tests: must be run as root" >&2 | ||
| 32 | exit $ksft_skip | ||
| 33 | fi | ||
| 22 | } | 34 | } |
| 23 | 35 | ||
| 24 | # die(msg) - game over, man | 36 | # die(msg) - game over, man |
| @@ -62,6 +74,7 @@ function set_ftrace_enabled() { · 37 unmodified lines | |||
| 62 | # for verbose livepatching output and turn on | 74 | # for verbose livepatching output and turn on |
| 63 | # the ftrace_enabled sysctl. | 75 | # the ftrace_enabled sysctl. |
| 64 | function setup_config() { | 76 | function setup_config() { |
| 77 | is_root | ||
| 65 | push_config | 78 | push_config |
| 66 | set_dynamic_debug | 79 | set_dynamic_debug |
| 67 | set_ftrace_enabled 1 | 80 | set_ftrace_enabled 1 |
| @@ -8,8 +8,7 @@ MOD_LIVEPATCH=test_klp_state · 7 unmodified lines | |||
| 8 | MOD_LIVEPATCH2=test_klp_state2 | 8 | MOD_LIVEPATCH2=test_klp_state2 |
| 9 | MOD_LIVEPATCH3=test_klp_state3 | 9 | MOD_LIVEPATCH3=test_klp_state3 |
| 10 | 10 | ||
| 11 | set_dynamic_debug | 11 | setup_config |
| 12 | |||
| 13 | 12 | ||
| 14 | # TEST: Loading and removing a module that modifies the system state | 13 | # TEST: Loading and removing a module that modifies the system state |
| 15 | 14 | ||
| @@ -1,6 +1,9 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | ||
| 4 | # Kselftest framework requirement - SKIP code is 4. | ||
| 5 | ksft_skip=4 | ||
| 6 | |||
| 4 | ALL_TESTS="loopback_test" | 7 | ALL_TESTS="loopback_test" |
| 5 | NUM_NETIFS=2 | 8 | NUM_NETIFS=2 |
| 6 | source tc_common.sh | 9 | source tc_common.sh |
| @@ -72,6 +75,11 @@ setup_prepare() · 65 unmodified lines | |||
| 72 | 75 | ||
| 73 | h1_create | 76 | h1_create |
| 74 | h2_create | 77 | h2_create |
| 78 | |||
| 79 | if ethtool -k $h1 | grep loopback | grep -q fixed; then | ||
| 80 | log_test "SKIP: dev $h1 does not support loopback feature" | ||
| 81 | exit $ksft_skip | ||
| 82 | fi | ||
| 75 | } | 83 | } |
| 76 | 84 | ||
| 77 | cleanup() | 85 | cleanup() |
| @@ -226,17 +226,19 @@ check_transfer() · 225 unmodified lines | |||
| 226 | return 0 | 226 | return 0 |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | test_tcp_forwarding() | 229 | test_tcp_forwarding_ip() |
| 230 | { | 230 | { |
| 231 | local nsa=$1 | 231 | local nsa=$1 |
| 232 | local nsb=$2 | 232 | local nsb=$2 |
| 233 | local dstip=$3 | ||
| 234 | local dstport=$4 | ||
| 233 | local lret=0 | 235 | local lret=0 |
| 234 | 236 | ||
| 235 | ip netns exec $nsb nc -w 5 -l -p 12345 < "$ns2in" > "$ns2out" & | 237 | ip netns exec $nsb nc -w 5 -l -p 12345 < "$ns2in" > "$ns2out" & |
| 236 | lpid=$! | 238 | lpid=$! |
| 237 | 239 | ||
| 238 | sleep 1 | 240 | sleep 1 |
| 239 | ip netns exec $nsa nc -w 4 10.0.2.99 12345 < "$ns1in" > "$ns1out" & | 241 | ip netns exec $nsa nc -w 4 "$dstip" "$dstport" < "$ns1in" > "$ns1out" & |
| 240 | cpid=$! | 242 | cpid=$! |
| 241 | 243 | ||
| 242 | sleep 3 | 244 | sleep 3 |
| @@ -258,6 +260,28 @@ test_tcp_forwarding() · 15 unmodified lines | |||
| 258 | return $lret | 260 | return $lret |
| 259 | } | 261 | } |
| 260 | 262 | ||
| 263 | test_tcp_forwarding() | ||
| 264 | { | ||
| 265 | test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 | ||
| 266 | |||
| 267 | return $? | ||
| 268 | } | ||
| 269 | |||
| 270 | test_tcp_forwarding_nat() | ||
| 271 | { | ||
| 272 | local lret | ||
| 273 | |||
| 274 | test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 | ||
| 275 | lret=$? | ||
| 276 | |||
| 277 | if [ $lret -eq 0 ] ; then | ||
| 278 | test_tcp_forwarding_ip "$1" "$2" 10.6.6.6 1666 | ||
| 279 | lret=$? | ||
| 280 | fi | ||
| 281 | |||
| 282 | return $lret | ||
| 283 | } | ||
| 284 | |||
| 261 | make_file "$ns1in" "ns1" | 285 | make_file "$ns1in" "ns1" |
| 262 | make_file "$ns2in" "ns2" | 286 | make_file "$ns2in" "ns2" |
| 263 | 287 | ||
| @@ -283,14 +307,19 @@ ip -net ns2 route add 192.168.10.1 via 10.0.2.1 · 19 unmodified lines | |||
| 283 | # Same, but with NAT enabled. | 307 | # Same, but with NAT enabled. |
| 284 | ip netns exec nsr1 nft -f - <<EOF | 308 | ip netns exec nsr1 nft -f - <<EOF |
| 285 | table ip nat { | 309 | table ip nat { |
| 310 | chain prerouting { | ||
| 311 | type nat hook prerouting priority 0; policy accept; | ||
| 312 | meta iif "veth0" ip daddr 10.6.6.6 tcp dport 1666 counter dnat ip to 10.0.2.99:12345 | ||
| 313 | } | ||
| 314 | |||
| 286 | chain postrouting { | 315 | chain postrouting { |
| 287 | type nat hook postrouting priority 0; policy accept; | 316 | type nat hook postrouting priority 0; policy accept; |
| 288 | meta oifname "veth1" masquerade | 317 | meta oifname "veth1" counter masquerade |
| 289 | } | 318 | } |
| 290 | } | 319 | } |
| 291 | EOF | 320 | EOF |
| 292 | 321 | ||
| 293 | test_tcp_forwarding ns1 ns2 | 322 | test_tcp_forwarding_nat ns1 ns2 |
| 294 | 323 | ||
| 295 | if [ $? -eq 0 ] ;then | 324 | if [ $? -eq 0 ] ;then |
| 296 | echo "PASS: flow offloaded for ns1/ns2 with NAT" | 325 | echo "PASS: flow offloaded for ns1/ns2 with NAT" |
| @@ -313,7 +342,7 @@ fi · 16 unmodified lines | |||
| 313 | ip netns exec ns1 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null | 342 | ip netns exec ns1 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null |
| 314 | ip netns exec ns2 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null | 343 | ip netns exec ns2 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null |
| 315 | 344 | ||
| 316 | test_tcp_forwarding ns1 ns2 | 345 | test_tcp_forwarding_nat ns1 ns2 |
| 317 | if [ $? -eq 0 ] ;then | 346 | if [ $? -eq 0 ] ;then |
| 318 | echo "PASS: flow offloaded for ns1/ns2 with NAT and pmtu discovery" | 347 | echo "PASS: flow offloaded for ns1/ns2 with NAT and pmtu discovery" |
| 319 | else | 348 | else |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <errno.h> | 15 | #include <errno.h> |
| 16 | #include <stddef.h> | 16 | #include <stddef.h> |
| 17 | 17 | ||
| 18 | static inline pid_t gettid(void) | 18 | static inline pid_t rseq_gettid(void) |
| 19 | { | 19 | { |
| 20 | return syscall(__NR_gettid); | 20 | return syscall(__NR_gettid); |
| 21 | } | 21 | } |
| @@ -373,11 +373,12 @@ void *test_percpu_spinlock_thread(void *arg) · 351 unmodified lines | |||
| 373 | rseq_percpu_unlock(&data->lock, cpu); | 373 | rseq_percpu_unlock(&data->lock, cpu); |
| 374 | #ifndef BENCHMARK | 374 | #ifndef BENCHMARK |
| 375 | if (i != 0 && !(i % (reps / 10))) | 375 | if (i != 0 && !(i % (reps / 10))) |
| 376 | printf_verbose("tid %d: count %lld\n", (int) gettid(), i); | 376 | printf_verbose("tid %d: count %lld\n", |
| 377 | (int) rseq_gettid(), i); | ||
| 377 | #endif | 378 | #endif |
| 378 | } | 379 | } |
| 379 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", | 380 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", |
| 380 | (int) gettid(), nr_abort, signals_delivered); | 381 | (int) rseq_gettid(), nr_abort, signals_delivered); |
| 381 | if (!opt_disable_rseq && thread_data->reg && | 382 | if (!opt_disable_rseq && thread_data->reg && |
| 382 | rseq_unregister_current_thread()) | 383 | rseq_unregister_current_thread()) |
| 383 | abort(); | 384 | abort(); |
| @@ -454,11 +455,12 @@ void *test_percpu_inc_thread(void *arg) · 70 unmodified lines | |||
| 454 | } while (rseq_unlikely(ret)); | 455 | } while (rseq_unlikely(ret)); |
| 455 | #ifndef BENCHMARK | 456 | #ifndef BENCHMARK |
| 456 | if (i != 0 && !(i % (reps / 10))) | 457 | if (i != 0 && !(i % (reps / 10))) |
| 457 | printf_verbose("tid %d: count %lld\n", (int) gettid(), i); | 458 | printf_verbose("tid %d: count %lld\n", |
| 459 | (int) rseq_gettid(), i); | ||
| 458 | #endif | 460 | #endif |
| 459 | } | 461 | } |
| 460 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", | 462 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", |
| 461 | (int) gettid(), nr_abort, signals_delivered); | 463 | (int) rseq_gettid(), nr_abort, signals_delivered); |
| 462 | if (!opt_disable_rseq && thread_data->reg && | 464 | if (!opt_disable_rseq && thread_data->reg && |
| 463 | rseq_unregister_current_thread()) | 465 | rseq_unregister_current_thread()) |
| 464 | abort(); | 466 | abort(); |
| @@ -605,7 +607,7 @@ void *test_percpu_list_thread(void *arg) · 140 unmodified lines | |||
| 605 | } | 607 | } |
| 606 | 608 | ||
| 607 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", | 609 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", |
| 608 | (int) gettid(), nr_abort, signals_delivered); | 610 | (int) rseq_gettid(), nr_abort, signals_delivered); |
| 609 | if (!opt_disable_rseq && rseq_unregister_current_thread()) | 611 | if (!opt_disable_rseq && rseq_unregister_current_thread()) |
| 610 | abort(); | 612 | abort(); |
| 611 | 613 | ||
| @@ -796,7 +798,7 @@ void *test_percpu_buffer_thread(void *arg) · 184 unmodified lines | |||
| 796 | } | 798 | } |
| 797 | 799 | ||
| 798 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", | 800 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", |
| 799 | (int) gettid(), nr_abort, signals_delivered); | 801 | (int) rseq_gettid(), nr_abort, signals_delivered); |
| 800 | if (!opt_disable_rseq && rseq_unregister_current_thread()) | 802 | if (!opt_disable_rseq && rseq_unregister_current_thread()) |
| 801 | abort(); | 803 | abort(); |
| 802 | 804 | ||
| @@ -1011,7 +1013,7 @@ void *test_percpu_memcpy_buffer_thread(void *arg) · 208 unmodified lines | |||
| 1011 | } | 1013 | } |
| 1012 | 1014 | ||
| 1013 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", | 1015 | printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n", |
| 1014 | (int) gettid(), nr_abort, signals_delivered); | 1016 | (int) rseq_gettid(), nr_abort, signals_delivered); |
| 1015 | if (!opt_disable_rseq && rseq_unregister_current_thread()) | 1017 | if (!opt_disable_rseq && rseq_unregister_current_thread()) |
| 1016 | abort(); | 1018 | abort(); |
| 1017 | 1019 | ||
| @@ -149,11 +149,13 @@ static inline void rseq_clear_rseq_cs(void) · 148 unmodified lines | |||
| 149 | /* | 149 | /* |
| 150 | * rseq_prepare_unload() should be invoked by each thread executing a rseq | 150 | * rseq_prepare_unload() should be invoked by each thread executing a rseq |
| 151 | * critical section at least once between their last critical section and | 151 | * critical section at least once between their last critical section and |
| 152 | * library unload of the library defining the rseq critical section | 152 | * library unload of the library defining the rseq critical section (struct |
| 153 | * (struct rseq_cs). This also applies to use of rseq in code generated by | 153 | * rseq_cs) or the code referred to by the struct rseq_cs start_ip and |
| 154 | * JIT: rseq_prepare_unload() should be invoked at least once by each | 154 | * post_commit_offset fields. This also applies to use of rseq in code |
| 155 | * thread executing a rseq critical section before reclaim of the memory | 155 | * generated by JIT: rseq_prepare_unload() should be invoked at least once by |
| 156 | * holding the struct rseq_cs. | 156 | * each thread executing a rseq critical section before reclaim of the memory |
| 157 | * holding the struct rseq_cs or reclaim of the code pointed to by struct | ||
| 158 | * rseq_cs start_ip and post_commit_offset fields. | ||
| 157 | */ | 159 | */ |
| 158 | static inline void rseq_prepare_unload(void) | 160 | static inline void rseq_prepare_unload(void) |
| 159 | { | 161 | { |
| @@ -0,0 +1 @@ | |||
| 1 | timeout=0 | ||
| @@ -3158,7 +3158,18 @@ TEST(user_notification_basic) · 3157 unmodified lines | |||
| 3158 | EXPECT_GT(poll(&pollfd, 1, -1), 0); | 3158 | EXPECT_GT(poll(&pollfd, 1, -1), 0); |
| 3159 | EXPECT_EQ(pollfd.revents, POLLIN); | 3159 | EXPECT_EQ(pollfd.revents, POLLIN); |
| 3160 | 3160 | ||
| 3161 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); | 3161 | /* Test that we can't pass garbage to the kernel. */ |
| 3162 | memset(&req, 0, sizeof(req)); | ||
| 3163 | req.pid = -1; | ||
| 3164 | errno = 0; | ||
| 3165 | ret = ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req); | ||
| 3166 | EXPECT_EQ(-1, ret); | ||
| 3167 | EXPECT_EQ(EINVAL, errno); | ||
| 3168 | |||
| 3169 | if (ret) { | ||
| 3170 | req.pid = 0; | ||
| 3171 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); | ||
| 3172 | } | ||
| 3162 | 3173 | ||
| 3163 | pollfd.fd = listener; | 3174 | pollfd.fd = listener; |
| 3164 | pollfd.events = POLLIN | POLLOUT; | 3175 | pollfd.events = POLLIN | POLLOUT; |
| @@ -3278,6 +3289,7 @@ TEST(user_notification_signal) · 113 unmodified lines | |||
| 3278 | 3289 | ||
| 3279 | close(sk_pair[1]); | 3290 | close(sk_pair[1]); |
| 3280 | 3291 | ||
| 3292 | memset(&req, 0, sizeof(req)); | ||
| 3281 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); | 3293 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); |
| 3282 | 3294 | ||
| 3283 | EXPECT_EQ(kill(pid, SIGUSR1), 0); | 3295 | EXPECT_EQ(kill(pid, SIGUSR1), 0); |
| @@ -3296,6 +3308,7 @@ TEST(user_notification_signal) · 12 unmodified lines | |||
| 3296 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); | 3308 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); |
| 3297 | EXPECT_EQ(errno, ENOENT); | 3309 | EXPECT_EQ(errno, ENOENT); |
| 3298 | 3310 | ||
| 3311 | memset(&req, 0, sizeof(req)); | ||
| 3299 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); | 3312 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); |
| 3300 | 3313 | ||
| 3301 | resp.id = req.id; | 3314 | resp.id = req.id; |
| @@ -128,7 +128,7 @@ parse() { · 127 unmodified lines | |||
| 128 | str="${ftype} ${name} ${location} ${str}" | 128 | str="${ftype} ${name} ${location} ${str}" |
| 129 | ;; | 129 | ;; |
| 130 | "nod") | 130 | "nod") |
| 131 | local dev=`LC_ALL=C ls -l "${location}"` | 131 | local dev="`LC_ALL=C ls -l "${location}"`" |
| 132 | local maj=`field 5 ${dev}` | 132 | local maj=`field 5 ${dev}` |
| 133 | local min=`field 6 ${dev}` | 133 | local min=`field 6 ${dev}` |
| 134 | maj=${maj%,} | 134 | maj=${maj%,} |