We need the USB fixes in here as well.
Unified · Split
| @@ -251,11 +251,11 @@ selectively from different subsystems. · 250 unmodified lines | ||
| 251 | 251 | .. code-block:: c |
| 252 | 252 | |
| 253 | 253 | struct kcov_remote_arg { |
| 254 | − unsigned trace_mode; | |
| 255 | − unsigned area_size; | |
| 256 | − unsigned num_handles; | |
| 257 | − uint64_t common_handle; | |
| 258 | − uint64_t handles[0]; | |
| 254 | + __u32 trace_mode; | |
| 255 | + __u32 area_size; | |
| 256 | + __u32 num_handles; | |
| 257 | + __aligned_u64 common_handle; | |
| 258 | + __aligned_u64 handles[0]; | |
| 259 | 259 | }; |
| 260 | 260 | |
| 261 | 261 | #define KCOV_INIT_TRACE _IOR('c', 1, unsigned long) |
| @@ -24,19 +24,16 @@ The wrapper can be run with: · 23 unmodified lines | ||
| 24 | 24 | For more information on this wrapper (also called kunit_tool) checkout the |
| 25 | 25 | :doc:`kunit-tool` page. |
| 26 | 26 | |
| 27 | −Creating a kunitconfig | |
| 28 | −====================== | |
| 27 | +Creating a .kunitconfig | |
| 28 | +======================= | |
| 29 | 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 | 31 | regular Kernel config, with the specific test targets as well. |
| 32 | 32 | |
| 33 | 33 | .. code-block:: bash |
| 34 | 34 | |
| 35 | − git clone -b master https://kunit.googlesource.com/kunitconfig $PATH_TO_KUNITCONFIG_REPO | |
| 36 | 35 | cd $PATH_TO_LINUX_REPO |
| 37 | − ln -s $PATH_TO_KUNIT_CONFIG_REPO/kunitconfig kunitconfig | |
| 38 | − | |
| 39 | −You may want to add kunitconfig to your local gitignore. | |
| 36 | + cp arch/um/configs/kunit_defconfig .kunitconfig | |
| 40 | 37 | |
| 41 | 38 | Verifying KUnit Works |
| 42 | 39 | --------------------- |
| @@ -151,7 +148,7 @@ and the following to ``drivers/misc/Makefile``: · 108 unmodified lines | ||
| 151 | 148 | |
| 152 | 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 | 153 | .. code-block:: none |
| 157 | 154 | |
| @@ -18,8 +18,10 @@ Optional properties: · 17 unmodified lines | ||
| 18 | 18 | - dma-names: should contain "tx" and "rx". |
| 19 | 19 | - atmel,fifo-size: maximum number of data the RX and TX FIFOs can store for FIFO |
| 20 | 20 | capable I2C controllers. |
| 21 | −- i2c-sda-hold-time-ns: TWD hold time, only available for "atmel,sama5d4-i2c" | |
| 22 | − and "atmel,sama5d2-i2c". | |
| 21 | +- i2c-sda-hold-time-ns: TWD hold time, only available for: | |
| 22 | + "atmel,sama5d4-i2c", | |
| 23 | + "atmel,sama5d2-i2c", | |
| 24 | + "microchip,sam9x60-i2c". | |
| 23 | 25 | - Child nodes conforming to i2c bus binding |
| 24 | 26 | |
| 25 | 27 | Examples : |
| @@ -111,7 +111,7 @@ patternProperties: · 110 unmodified lines | ||
| 111 | 111 | spi-rx-bus-width: |
| 112 | 112 | allOf: |
| 113 | 113 | - $ref: /schemas/types.yaml#/definitions/uint32 |
| 114 | − - enum: [ 1, 2, 4 ] | |
| 114 | + - enum: [ 1, 2, 4, 8 ] | |
| 115 | 115 | - default: 1 |
| 116 | 116 | description: |
| 117 | 117 | Bus width to the SPI bus used for MISO. |
| @@ -123,7 +123,7 @@ patternProperties: · 5 unmodified lines | ||
| 123 | 123 | spi-tx-bus-width: |
| 124 | 124 | allOf: |
| 125 | 125 | - $ref: /schemas/types.yaml#/definitions/uint32 |
| 126 | − - enum: [ 1, 2, 4 ] | |
| 126 | + - enum: [ 1, 2, 4, 8 ] | |
| 127 | 127 | - default: 1 |
| 128 | 128 | description: |
| 129 | 129 | Bus width to the SPI bus used for MOSI. |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | | openrisc: | TODO | |
| 24 | 24 | | parisc: | TODO | |
| 25 | 25 | | powerpc: | ok | |
| 26 | − | riscv: | TODO | | |
| 26 | + | riscv: | ok | | |
| 27 | 27 | | s390: | ok | |
| 28 | 28 | | sh: | ok | |
| 29 | 29 | | sparc: | TODO | |
| @@ -230,12 +230,6 @@ simultaneously on two ports. The driver checks the consistency of the schedules · 229 unmodified lines | ||
| 230 | 230 | against this restriction and errors out when appropriate. Schedule analysis is |
| 231 | 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 | 233 | Device Tree bindings and board design |
| 240 | 234 | ===================================== |
| 241 | 235 | |
| @@ -603,7 +603,7 @@ tcp_synack_retries - INTEGER · 602 unmodified lines | ||
| 603 | 603 | with the current initial RTO of 1second. With this the final timeout |
| 604 | 604 | for a passive TCP connection will happen after 63seconds. |
| 605 | 605 | |
| 606 | −tcp_syncookies - BOOLEAN | |
| 606 | +tcp_syncookies - INTEGER | |
| 607 | 607 | Only valid when the kernel was compiled with CONFIG_SYN_COOKIES |
| 608 | 608 | Send out syncookies when the syn backlog queue of a socket |
| 609 | 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 | 34 | mainline tree from Linus, and ``net-next`` is where the new code goes |
| 35 | 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 | |
| 38 | −- https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git | |
| 37 | +- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git | |
| 38 | +- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git | |
| 39 | 39 | |
| 40 | 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 | 60 | volatile-considered-harmful |
| 61 | 61 | botching-up-ioctls |
| 62 | 62 | clang-format |
| 63 | + ../riscv/patch-acceptance | |
| 63 | 64 | |
| 64 | 65 | .. only:: subproject and html |
| 65 | 66 | |
| @@ -7,6 +7,7 @@ RISC-V architecture · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | boot-image-header |
| 9 | 9 | pmu |
| 10 | + patch-acceptance | |
| 10 | 11 | |
| 11 | 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 | 772 | AMAZON ETHERNET DRIVERS |
| 773 | 773 | M: Netanel Belgazal <netanel@amazon.com> |
| 774 | +M: Arthur Kiyanovski <akiyano@amazon.com> | |
| 775 | +R: Guy Tzalik <gtzalik@amazon.com> | |
| 774 | 776 | R: Saeed Bishara <saeedb@amazon.com> |
| 775 | 777 | R: Zorik Machulsky <zorik@amazon.com> |
| 776 | 778 | L: netdev@vger.kernel.org |
| @@ -7034,6 +7036,7 @@ L: linux-acpi@vger.kernel.org · 6257 unmodified lines | ||
| 7034 | 7036 | S: Maintained |
| 7035 | 7037 | F: Documentation/firmware-guide/acpi/gpio-properties.rst |
| 7036 | 7038 | F: drivers/gpio/gpiolib-acpi.c |
| 7039 | +F: drivers/gpio/gpiolib-acpi.h | |
| 7037 | 7040 | |
| 7038 | 7041 | GPIO IR Transmitter |
| 7039 | 7042 | M: Sean Young <sean@mess.org> |
| @@ -11457,8 +11460,8 @@ M: "David S. Miller" <davem@davemloft.net> · 4417 unmodified lines | ||
| 11457 | 11460 | L: netdev@vger.kernel.org |
| 11458 | 11461 | W: http://www.linuxfoundation.org/en/Net |
| 11459 | 11462 | Q: http://patchwork.ozlabs.org/project/netdev/list/ |
| 11460 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git | |
| 11461 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git | |
| 11463 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git | |
| 11464 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git | |
| 11462 | 11465 | S: Odd Fixes |
| 11463 | 11466 | F: Documentation/devicetree/bindings/net/ |
| 11464 | 11467 | F: drivers/net/ |
| @@ -11499,8 +11502,8 @@ M: "David S. Miller" <davem@davemloft.net> · 34 unmodified lines | ||
| 11499 | 11502 | L: netdev@vger.kernel.org |
| 11500 | 11503 | W: http://www.linuxfoundation.org/en/Net |
| 11501 | 11504 | Q: http://patchwork.ozlabs.org/project/netdev/list/ |
| 11502 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git | |
| 11503 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git | |
| 11505 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git | |
| 11506 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git | |
| 11504 | 11507 | B: mailto:netdev@vger.kernel.org |
| 11505 | 11508 | S: Maintained |
| 11506 | 11509 | F: net/ |
| @@ -11545,7 +11548,7 @@ M: "David S. Miller" <davem@davemloft.net> · 38 unmodified lines | ||
| 11545 | 11548 | M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> |
| 11546 | 11549 | M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> |
| 11547 | 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 | 11552 | S: Maintained |
| 11550 | 11553 | F: net/ipv4/ |
| 11551 | 11554 | F: net/ipv6/ |
| @@ -13676,7 +13679,6 @@ F: drivers/net/ethernet/qualcomm/emac/ · 2124 unmodified lines | ||
| 13676 | 13679 | |
| 13677 | 13680 | QUALCOMM ETHQOS ETHERNET DRIVER |
| 13678 | 13681 | M: Vinod Koul <vkoul@kernel.org> |
| 13679 | −M: Niklas Cassel <niklas.cassel@linaro.org> | |
| 13680 | 13682 | L: netdev@vger.kernel.org |
| 13681 | 13683 | S: Maintained |
| 13682 | 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 | 14120 | M: Palmer Dabbelt <palmer@dabbelt.com> |
| 14119 | 14121 | M: Albert Ou <aou@eecs.berkeley.edu> |
| 14120 | 14122 | L: linux-riscv@lists.infradead.org |
| 14123 | +P: Documentation/riscv/patch-acceptance.rst | |
| 14121 | 14124 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git |
| 14122 | 14125 | S: Supported |
| 14123 | 14126 | F: arch/riscv/ |
| @@ -14545,8 +14548,6 @@ F: include/linux/platform_data/spi-s3c64xx.h · 421 unmodified lines | ||
| 14545 | 14548 | |
| 14546 | 14549 | SAMSUNG SXGBE DRIVERS |
| 14547 | 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 | 14551 | S: Supported |
| 14551 | 14552 | L: netdev@vger.kernel.org |
| 14552 | 14553 | F: drivers/net/ethernet/samsung/sxgbe/ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 5 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc3 | |
| 5 | +EXTRAVERSION = -rc6 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -162,7 +162,7 @@ · 161 unmodified lines | ||
| 162 | 162 | #endif |
| 163 | 163 | |
| 164 | 164 | #ifdef CONFIG_ARC_HAS_ACCL_REGS |
| 165 | − ST2 r58, r59, PT_sp + 12 | |
| 165 | + ST2 r58, r59, PT_r58 | |
| 166 | 166 | #endif |
| 167 | 167 | |
| 168 | 168 | .endm |
| @@ -172,8 +172,8 @@ · 3 unmodified lines | ||
| 172 | 172 | |
| 173 | 173 | LD2 gp, fp, PT_r26 ; gp (r26), fp (r27) |
| 174 | 174 | |
| 175 | − ld r12, [sp, PT_sp + 4] | |
| 176 | − ld r30, [sp, PT_sp + 8] | |
| 175 | + ld r12, [sp, PT_r12] | |
| 176 | + ld r30, [sp, PT_r30] | |
| 177 | 177 | |
| 178 | 178 | ; Restore SP (into AUX_USER_SP) only if returning to U mode |
| 179 | 179 | ; - for K mode, it will be implicitly restored as stack is unwound |
| @@ -190,7 +190,7 @@ · 10 unmodified lines | ||
| 190 | 190 | #endif |
| 191 | 191 | |
| 192 | 192 | #ifdef CONFIG_ARC_HAS_ACCL_REGS |
| 193 | − LD2 r58, r59, PT_sp + 12 | |
| 193 | + LD2 r58, r59, PT_r58 | |
| 194 | 194 | #endif |
| 195 | 195 | .endm |
| 196 | 196 | |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #define _ASM_ARC_HUGEPAGE_H |
| 9 | 9 | |
| 10 | 10 | #include <linux/types.h> |
| 11 | −#define __ARCH_USE_5LEVEL_HACK | |
| 12 | 11 | #include <asm-generic/pgtable-nopmd.h> |
| 13 | 12 | |
| 14 | 13 | static inline pte_t pmd_pte(pmd_t pmd) |
| @@ -66,7 +66,15 @@ int main(void) · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); |
| 68 | 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 | 79 | return 0; |
| 72 | 80 | } |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | menuconfig ARC_PLAT_EZNPS |
| 8 | 8 | bool "\"EZchip\" ARC dev platform" |
| 9 | 9 | select CPU_BIG_ENDIAN |
| 10 | − select CLKSRC_NPS | |
| 10 | + select CLKSRC_NPS if !PHYS_ADDR_T_64BIT | |
| 11 | 11 | select EZNPS_GIC |
| 12 | 12 | select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET |
| 13 | 13 | help |
| @@ -72,6 +72,7 @@ config ARM · 71 unmodified lines | ||
| 72 | 72 | select HAVE_ARM_SMCCC if CPU_V7 |
| 73 | 73 | select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32 |
| 74 | 74 | select HAVE_CONTEXT_TRACKING |
| 75 | + select HAVE_COPY_THREAD_TLS | |
| 75 | 76 | select HAVE_C_RECORDMCOUNT |
| 76 | 77 | select HAVE_DEBUG_KMEMLEAK |
| 77 | 78 | select HAVE_DMA_CONTIGUOUS if MMU |
| @@ -226,8 +226,8 @@ void release_thread(struct task_struct *dead_task) · 225 unmodified lines | ||
| 226 | 226 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
| 227 | 227 | |
| 228 | 228 | int |
| 229 | −copy_thread(unsigned long clone_flags, unsigned long stack_start, | |
| 230 | − unsigned long stk_sz, struct task_struct *p) | |
| 229 | +copy_thread_tls(unsigned long clone_flags, unsigned long stack_start, | |
| 230 | + unsigned long stk_sz, struct task_struct *p, unsigned long tls) | |
| 231 | 231 | { |
| 232 | 232 | struct thread_info *thread = task_thread_info(p); |
| 233 | 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 | 261 | clear_ptrace_hw_breakpoint(p); |
| 262 | 262 | |
| 263 | 263 | if (clone_flags & CLONE_SETTLS) |
| 264 | − thread->tp_value[0] = childregs->ARM_r3; | |
| 264 | + thread->tp_value[0] = tls; | |
| 265 | 265 | thread->tp_value[1] = get_tpuser(); |
| 266 | 266 | |
| 267 | 267 | thread_notify(THREAD_NOTIFY_COPY, thread); |
| @@ -138,6 +138,7 @@ config ARM64 · 137 unmodified lines | ||
| 138 | 138 | select HAVE_CMPXCHG_DOUBLE |
| 139 | 139 | select HAVE_CMPXCHG_LOCAL |
| 140 | 140 | select HAVE_CONTEXT_TRACKING |
| 141 | + select HAVE_COPY_THREAD_TLS | |
| 141 | 142 | select HAVE_DEBUG_BUGVERBOSE |
| 142 | 143 | select HAVE_DEBUG_KMEMLEAK |
| 143 | 144 | select HAVE_DMA_CONTIGUOUS |
| @@ -85,13 +85,12 @@ · 84 unmodified lines | ||
| 85 | 85 | #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE) |
| 86 | 86 | #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) |
| 87 | 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 | 89 | #define __P000 PAGE_NONE |
| 91 | 90 | #define __P001 PAGE_READONLY |
| 92 | 91 | #define __P010 PAGE_READONLY |
| 93 | 92 | #define __P011 PAGE_READONLY |
| 94 | −#define __P100 PAGE_EXECONLY | |
| 93 | +#define __P100 PAGE_READONLY_EXEC | |
| 95 | 94 | #define __P101 PAGE_READONLY_EXEC |
| 96 | 95 | #define __P110 PAGE_READONLY_EXEC |
| 97 | 96 | #define __P111 PAGE_READONLY_EXEC |
| @@ -100,7 +99,7 @@ · 2 unmodified lines | ||
| 100 | 99 | #define __S001 PAGE_READONLY |
| 101 | 100 | #define __S010 PAGE_SHARED |
| 102 | 101 | #define __S011 PAGE_SHARED |
| 103 | −#define __S100 PAGE_EXECONLY | |
| 102 | +#define __S100 PAGE_READONLY_EXEC | |
| 104 | 103 | #define __S101 PAGE_READONLY_EXEC |
| 105 | 104 | #define __S110 PAGE_SHARED_EXEC |
| 106 | 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 | 96 | #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) |
| 97 | 97 | |
| 98 | 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 | 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 | 101 | #define pte_valid_young(pte) \ |
| 106 | 102 | ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF)) |
| 107 | 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 | 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 | |
| 121 | − * PTE_USER bit set. PROT_NONE mappings do not have the PTE_VALID bit set. | |
| 116 | + * write permission check). PROT_NONE mappings do not have the PTE_VALID bit | |
| 117 | + * set. | |
| 122 | 118 | */ |
| 123 | 119 | #define pte_access_permitted(pte, write) \ |
| 124 | 120 | (pte_valid_user(pte) && (!(write) || pte_write(pte))) |
| @@ -42,7 +42,6 @@ · 41 unmodified lines | ||
| 42 | 42 | #endif |
| 43 | 43 | |
| 44 | 44 | #define __ARCH_WANT_SYS_CLONE |
| 45 | −#define __ARCH_WANT_SYS_CLONE3 | |
| 46 | 45 | |
| 47 | 46 | #ifndef __COMPAT_SYSCALL_NR |
| 48 | 47 | #include <uapi/asm/unistd.h> |
| @@ -19,5 +19,6 @@ · 18 unmodified lines | ||
| 19 | 19 | #define __ARCH_WANT_NEW_STAT |
| 20 | 20 | #define __ARCH_WANT_SET_GET_RLIMIT |
| 21 | 21 | #define __ARCH_WANT_TIME32_SYSCALLS |
| 22 | +#define __ARCH_WANT_SYS_CLONE3 | |
| 22 | 23 | |
| 23 | 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 | 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, | |
| 364 | − unsigned long stk_sz, struct task_struct *p) | |
| 363 | +int copy_thread_tls(unsigned long clone_flags, unsigned long stack_start, | |
| 364 | + unsigned long stk_sz, struct task_struct *p, unsigned long tls) | |
| 365 | 365 | { |
| 366 | 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 | |
| 398 | − * for the new thread. | |
| 397 | + * If a TLS pointer was passed to clone, use it for the new | |
| 398 | + * thread. | |
| 399 | 399 | */ |
| 400 | 400 | if (clone_flags & CLONE_SETTLS) |
| 401 | − p->thread.uw.tp_value = childregs->regs[3]; | |
| 401 | + p->thread.uw.tp_value = tls; | |
| 402 | 402 | } else { |
| 403 | 403 | memset(childregs, 0, sizeof(struct pt_regs)); |
| 404 | 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 | 445 | const struct fault_info *inf; |
| 446 | 446 | struct mm_struct *mm = current->mm; |
| 447 | 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 | 449 | unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
| 450 | 450 | |
| 451 | 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 | 1071 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 1072 | 1072 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 1073 | − struct zone *zone; | |
| 1074 | 1073 | |
| 1075 | 1074 | /* |
| 1076 | 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 | 1078 | * unplug. ARCH_ENABLE_MEMORY_HOTREMOVE must not be |
| 1080 | 1079 | * unlocked yet. |
| 1081 | 1080 | */ |
| 1082 | − zone = page_zone(pfn_to_page(start_pfn)); | |
| 1083 | − __remove_pages(zone, start_pfn, nr_pages, altmap); | |
| 1081 | + __remove_pages(start_pfn, nr_pages, altmap); | |
| 1084 | 1082 | } |
| 1085 | 1083 | #endif |
| @@ -91,7 +91,7 @@ static inline void atomic_##op(int i, atomic_t *v) \ · 90 unmodified lines | ||
| 91 | 91 | "1: %0 = memw_locked(%1);\n" \ |
| 92 | 92 | " %0 = "#op "(%0,%2);\n" \ |
| 93 | 93 | " memw_locked(%1,P3)=%0;\n" \ |
| 94 | − " if !P3 jump 1b;\n" \ | |
| 94 | + " if (!P3) jump 1b;\n" \ | |
| 95 | 95 | : "=&r" (output) \ |
| 96 | 96 | : "r" (&v->counter), "r" (i) \ |
| 97 | 97 | : "memory", "p3" \ |
| @@ -107,7 +107,7 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \ · 9 unmodified lines | ||
| 107 | 107 | "1: %0 = memw_locked(%1);\n" \ |
| 108 | 108 | " %0 = "#op "(%0,%2);\n" \ |
| 109 | 109 | " memw_locked(%1,P3)=%0;\n" \ |
| 110 | − " if !P3 jump 1b;\n" \ | |
| 110 | + " if (!P3) jump 1b;\n" \ | |
| 111 | 111 | : "=&r" (output) \ |
| 112 | 112 | : "r" (&v->counter), "r" (i) \ |
| 113 | 113 | : "memory", "p3" \ |
| @@ -124,7 +124,7 @@ static inline int atomic_fetch_##op(int i, atomic_t *v) \ · 10 unmodified lines | ||
| 124 | 124 | "1: %0 = memw_locked(%2);\n" \ |
| 125 | 125 | " %1 = "#op "(%0,%3);\n" \ |
| 126 | 126 | " memw_locked(%2,P3)=%1;\n" \ |
| 127 | − " if !P3 jump 1b;\n" \ | |
| 127 | + " if (!P3) jump 1b;\n" \ | |
| 128 | 128 | : "=&r" (output), "=&r" (val) \ |
| 129 | 129 | : "r" (&v->counter), "r" (i) \ |
| 130 | 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 | 174 | " memw_locked(%2, p3) = %1;" |
| 175 | 175 | " {" |
| 176 | − " if !p3 jump 1b;" | |
| 176 | + " if (!p3) jump 1b;" | |
| 177 | 177 | " }" |
| 178 | 178 | "2:" |
| 179 | 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 | 38 | "1: R12 = memw_locked(R10);\n" |
| 39 | 39 | " { P0 = tstbit(R12,R11); R12 = clrbit(R12,R11); }\n" |
| 40 | 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 | 42 | : "=&r" (oldval) |
| 43 | 43 | : "r" (addr), "r" (nr) |
| 44 | 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 | 62 | "1: R12 = memw_locked(R10);\n" |
| 63 | 63 | " { P0 = tstbit(R12,R11); R12 = setbit(R12,R11); }\n" |
| 64 | 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 | 66 | : "=&r" (oldval) |
| 67 | 67 | : "r" (addr), "r" (nr) |
| 68 | 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 | 88 | "1: R12 = memw_locked(R10);\n" |
| 89 | 89 | " { P0 = tstbit(R12,R11); R12 = togglebit(R12,R11); }\n" |
| 90 | 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 | 92 | : "=&r" (oldval) |
| 93 | 93 | : "r" (addr), "r" (nr) |
| 94 | 94 | : "r10", "r11", "r12", "p0", "p1", "memory" |
| @@ -223,7 +223,7 @@ static inline int ffs(int x) · 128 unmodified lines | ||
| 223 | 223 | int r; |
| 224 | 224 | |
| 225 | 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 | 227 | : "=&r" (r) |
| 228 | 228 | : "r" (x) |
| 229 | 229 | : "p0"); |
| @@ -30,7 +30,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, · 29 unmodified lines | ||
| 30 | 30 | __asm__ __volatile__ ( |
| 31 | 31 | "1: %0 = memw_locked(%1);\n" /* load into retval */ |
| 32 | 32 | " memw_locked(%1,P0) = %2;\n" /* store into memory */ |
| 33 | − " if !P0 jump 1b;\n" | |
| 33 | + " if (!P0) jump 1b;\n" | |
| 34 | 34 | : "=&r" (retval) |
| 35 | 35 | : "r" (ptr), "r" (x) |
| 36 | 36 | : "memory", "p0" |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | /* For example: %1 = %4 */ \ |
| 17 | 17 | insn \ |
| 18 | 18 | "2: memw_locked(%3,p2) = %1;\n" \ |
| 19 | − " if !p2 jump 1b;\n" \ | |
| 19 | + " if (!p2) jump 1b;\n" \ | |
| 20 | 20 | " %1 = #0;\n" \ |
| 21 | 21 | "3:\n" \ |
| 22 | 22 | ".section .fixup,\"ax\"\n" \ |
| @@ -84,10 +84,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, · 61 unmodified lines | ||
| 84 | 84 | "1: %1 = memw_locked(%3)\n" |
| 85 | 85 | " {\n" |
| 86 | 86 | " p2 = cmp.eq(%1,%4)\n" |
| 87 | − " if !p2.new jump:NT 3f\n" | |
| 87 | + " if (!p2.new) jump:NT 3f\n" | |
| 88 | 88 | " }\n" |
| 89 | 89 | "2: memw_locked(%3,p2) = %5\n" |
| 90 | − " if !p2 jump 1b\n" | |
| 90 | + " if (!p2) jump 1b\n" | |
| 91 | 91 | "3:\n" |
| 92 | 92 | ".section .fixup,\"ax\"\n" |
| 93 | 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 | 174 | void __iomem *ioremap(unsigned long phys_addr, unsigned long size); |
| 175 | 175 | #define ioremap_nocache ioremap |
| 176 | +#define ioremap_uc(X, Y) ioremap((X), (Y)) | |
| 176 | 177 | |
| 177 | 178 | |
| 178 | 179 | #define __raw_writel writel |
| @@ -30,9 +30,9 @@ static inline void arch_read_lock(arch_rwlock_t *lock) · 29 unmodified lines | ||
| 30 | 30 | __asm__ __volatile__( |
| 31 | 31 | "1: R6 = memw_locked(%0);\n" |
| 32 | 32 | " { P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" |
| 33 | − " { if !P3 jump 1b; }\n" | |
| 33 | + " { if (!P3) jump 1b; }\n" | |
| 34 | 34 | " memw_locked(%0,P3) = R6;\n" |
| 35 | − " { if !P3 jump 1b; }\n" | |
| 35 | + " { if (!P3) jump 1b; }\n" | |
| 36 | 36 | : |
| 37 | 37 | : "r" (&lock->lock) |
| 38 | 38 | : "memory", "r6", "p3" |
| @@ -46,7 +46,7 @@ static inline void arch_read_unlock(arch_rwlock_t *lock) · 7 unmodified lines | ||
| 46 | 46 | "1: R6 = memw_locked(%0);\n" |
| 47 | 47 | " R6 = add(R6,#-1);\n" |
| 48 | 48 | " memw_locked(%0,P3) = R6\n" |
| 49 | − " if !P3 jump 1b;\n" | |
| 49 | + " if (!P3) jump 1b;\n" | |
| 50 | 50 | : |
| 51 | 51 | : "r" (&lock->lock) |
| 52 | 52 | : "memory", "r6", "p3" |
| @@ -61,7 +61,7 @@ static inline int arch_read_trylock(arch_rwlock_t *lock) · 8 unmodified lines | ||
| 61 | 61 | __asm__ __volatile__( |
| 62 | 62 | " R6 = memw_locked(%1);\n" |
| 63 | 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 | 65 | " memw_locked(%1,P3) = R6;\n" |
| 66 | 66 | " { %0 = P3 }\n" |
| 67 | 67 | "1:\n" |
| @@ -78,9 +78,9 @@ static inline void arch_write_lock(arch_rwlock_t *lock) · 10 unmodified lines | ||
| 78 | 78 | __asm__ __volatile__( |
| 79 | 79 | "1: R6 = memw_locked(%0)\n" |
| 80 | 80 | " { P3 = cmp.eq(R6,#0); R6 = #-1;}\n" |
| 81 | − " { if !P3 jump 1b; }\n" | |
| 81 | + " { if (!P3) jump 1b; }\n" | |
| 82 | 82 | " memw_locked(%0,P3) = R6;\n" |
| 83 | − " { if !P3 jump 1b; }\n" | |
| 83 | + " { if (!P3) jump 1b; }\n" | |
| 84 | 84 | : |
| 85 | 85 | : "r" (&lock->lock) |
| 86 | 86 | : "memory", "r6", "p3" |
| @@ -94,7 +94,7 @@ static inline int arch_write_trylock(arch_rwlock_t *lock) · 7 unmodified lines | ||
| 94 | 94 | __asm__ __volatile__( |
| 95 | 95 | " R6 = memw_locked(%1)\n" |
| 96 | 96 | " { %0 = #0; P3 = cmp.eq(R6,#0); R6 = #-1;}\n" |
| 97 | − " { if !P3 jump 1f; }\n" | |
| 97 | + " { if (!P3) jump 1f; }\n" | |
| 98 | 98 | " memw_locked(%1,P3) = R6;\n" |
| 99 | 99 | " %0 = P3;\n" |
| 100 | 100 | "1:\n" |
| @@ -117,9 +117,9 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) · 16 unmodified lines | ||
| 117 | 117 | __asm__ __volatile__( |
| 118 | 118 | "1: R6 = memw_locked(%0);\n" |
| 119 | 119 | " P3 = cmp.eq(R6,#0);\n" |
| 120 | − " { if !P3 jump 1b; R6 = #1; }\n" | |
| 120 | + " { if (!P3) jump 1b; R6 = #1; }\n" | |
| 121 | 121 | " memw_locked(%0,P3) = R6;\n" |
| 122 | − " { if !P3 jump 1b; }\n" | |
| 122 | + " { if (!P3) jump 1b; }\n" | |
| 123 | 123 | : |
| 124 | 124 | : "r" (&lock->lock) |
| 125 | 125 | : "memory", "r6", "p3" |
| @@ -139,7 +139,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) · 13 unmodified lines | ||
| 139 | 139 | __asm__ __volatile__( |
| 140 | 140 | " R6 = memw_locked(%1);\n" |
| 141 | 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 | 143 | " memw_locked(%1,P3) = R6;\n" |
| 144 | 144 | " %0 = P3;\n" |
| 145 | 145 | "1:\n" |
| @@ -11,8 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/thread_info.h> |
| 12 | 12 | #include <linux/module.h> |
| 13 | 13 | |
| 14 | −register unsigned long current_frame_pointer asm("r30"); | |
| 15 | − | |
| 16 | 14 | struct stackframe { |
| 17 | 15 | unsigned long fp; |
| 18 | 16 | unsigned long rets; |
| @@ -30,7 +28,7 @@ void save_stack_trace(struct stack_trace *trace) · 11 unmodified lines | ||
| 30 | 28 | |
| 31 | 29 | low = (unsigned long)task_stack_page(current); |
| 32 | 30 | high = low + THREAD_SIZE; |
| 33 | − fp = current_frame_pointer; | |
| 31 | + fp = (unsigned long)__builtin_frame_address(0); | |
| 34 | 32 | |
| 35 | 33 | while (fp >= low && fp <= (high - sizeof(*frame))) { |
| 36 | 34 | frame = (struct stackframe *)fp; |
| @@ -369,7 +369,7 @@ ret_from_fork: · 368 unmodified lines | ||
| 369 | 369 | R26.L = #LO(do_work_pending); |
| 370 | 370 | R0 = #VM_INT_DISABLE; |
| 371 | 371 | } |
| 372 | − if P0 jump check_work_pending | |
| 372 | + if (P0) jump check_work_pending | |
| 373 | 373 | { |
| 374 | 374 | R0 = R25; |
| 375 | 375 | callr R24 |
| @@ -689,9 +689,7 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 688 unmodified lines | ||
| 689 | 689 | { |
| 690 | 690 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 691 | 691 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 692 | − struct zone *zone; | |
| 693 | 692 | |
| 694 | − zone = page_zone(pfn_to_page(start_pfn)); | |
| 695 | − __remove_pages(zone, start_pfn, nr_pages, altmap); | |
| 693 | + __remove_pages(start_pfn, nr_pages, altmap); | |
| 696 | 694 | } |
| 697 | 695 | #endif |
| @@ -47,7 +47,7 @@ config MIPS · 46 unmodified lines | ||
| 47 | 47 | select HAVE_ARCH_TRACEHOOK |
| 48 | 48 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES |
| 49 | 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 | 51 | select HAVE_CONTEXT_TRACKING |
| 52 | 52 | select HAVE_COPY_THREAD_TLS |
| 53 | 53 | select HAVE_C_RECORDMCOUNT |
| @@ -29,6 +29,9 @@ KBUILD_AFLAGS := $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ · 28 unmodified lines | ||
| 29 | 29 | -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ |
| 30 | 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 | 35 | # decompressor objects (linked with vmlinuz) |
| 33 | 36 | vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o |
| 34 | 37 | |
| @@ -15,7 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | static inline int __pure __get_cpu_type(const int cpu_type) |
| 16 | 16 | { |
| 17 | 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 | 20 | case CPU_LOONGSON2EF: |
| 20 | 21 | #endif |
| 21 | 22 | |
| @@ -49,8 +49,26 @@ struct thread_info { · 48 unmodified lines | ||
| 49 | 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 | 70 | register struct thread_info *__current_thread_info __asm__("$28"); |
| 71 | +#endif | |
| 54 | 72 | |
| 55 | 73 | static inline struct thread_info *current_thread_info(void) |
| 56 | 74 | { |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #define __VDSO_USE_SYSCALL ULLONG_MAX |
| 28 | 28 | |
| 29 | −#ifdef CONFIG_MIPS_CLOCK_VSYSCALL | |
| 30 | − | |
| 31 | 29 | static __always_inline long gettimeofday_fallback( |
| 32 | 30 | struct __kernel_old_timeval *_tv, |
| 33 | 31 | struct timezone *_tz) |
| @@ -48,17 +46,6 @@ static __always_inline long gettimeofday_fallback( · 14 unmodified lines | ||
| 48 | 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 | 49 | static __always_inline long clock_gettime_fallback( |
| 63 | 50 | clockid_t _clkid, |
| 64 | 51 | struct __kernel_timespec *_ts) |
| @@ -50,6 +50,25 @@ static int __init_cache_level(unsigned int cpu) · 49 unmodified lines | ||
| 50 | 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 | 72 | static int __populate_cache_leaves(unsigned int cpu) |
| 54 | 73 | { |
| 55 | 74 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| @@ -57,14 +76,20 @@ static int __populate_cache_leaves(unsigned int cpu) · 1 unmodified line | ||
| 57 | 76 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; |
| 58 | 77 | |
| 59 | 78 | if (c->icache.waysize) { |
| 79 | + /* L1 caches are per core */ | |
| 80 | + fill_cpumask_siblings(cpu, &this_leaf->shared_cpu_map); | |
| 60 | 81 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_DATA); |
| 82 | + fill_cpumask_siblings(cpu, &this_leaf->shared_cpu_map); | |
| 61 | 83 | populate_cache(icache, this_leaf, 1, CACHE_TYPE_INST); |
| 62 | 84 | } else { |
| 63 | 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 | 91 | populate_cache(scache, this_leaf, 2, CACHE_TYPE_UNIFIED); |
| 92 | + } | |
| 68 | 93 | |
| 69 | 94 | if (c->tcache.waysize) |
| 70 | 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 | 1804 | unsigned int image_size; |
| 1805 | 1805 | u8 *image_ptr; |
| 1806 | 1806 | |
| 1807 | − if (!prog->jit_requested || MIPS_ISA_REV < 2) | |
| 1807 | + if (!prog->jit_requested) | |
| 1808 | 1808 | return prog; |
| 1809 | 1809 | |
| 1810 | 1810 | tmp = bpf_jit_blind_constants(prog); |
| @@ -17,12 +17,22 @@ int __vdso_clock_gettime(clockid_t clock, · 16 unmodified lines | ||
| 17 | 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 | 28 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, |
| 21 | 29 | struct timezone *tz) |
| 22 | 30 | { |
| 23 | 31 | return __cvdso_gettimeofday(tv, tz); |
| 24 | 32 | } |
| 25 | 33 | |
| 34 | +#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */ | |
| 35 | + | |
| 26 | 36 | int __vdso_clock_getres(clockid_t clock_id, |
| 27 | 37 | struct old_timespec32 *res) |
| 28 | 38 | { |
| @@ -43,12 +53,22 @@ int __vdso_clock_gettime(clockid_t clock, · 14 unmodified lines | ||
| 43 | 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 | 64 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, |
| 47 | 65 | struct timezone *tz) |
| 48 | 66 | { |
| 49 | 67 | return __cvdso_gettimeofday(tv, tz); |
| 50 | 68 | } |
| 51 | 69 | |
| 70 | +#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */ | |
| 71 | + | |
| 52 | 72 | int __vdso_clock_getres(clockid_t clock_id, |
| 53 | 73 | struct __kernel_timespec *res) |
| 54 | 74 | { |
| @@ -62,6 +62,7 @@ config PARISC · 61 unmodified lines | ||
| 62 | 62 | select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE |
| 63 | 63 | select HAVE_KPROBES_ON_FTRACE |
| 64 | 64 | select HAVE_DYNAMIC_FTRACE_WITH_REGS |
| 65 | + select HAVE_COPY_THREAD_TLS | |
| 65 | 66 | |
| 66 | 67 | help |
| 67 | 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 | 208 | * Copy architecture-specific thread state |
| 209 | 209 | */ |
| 210 | 210 | int |
| 211 | −copy_thread(unsigned long clone_flags, unsigned long usp, | |
| 212 | − unsigned long kthread_arg, struct task_struct *p) | |
| 211 | +copy_thread_tls(unsigned long clone_flags, unsigned long usp, | |
| 212 | + unsigned long kthread_arg, struct task_struct *p, unsigned long tls) | |
| 213 | 213 | { |
| 214 | 214 | struct pt_regs *cregs = &(p->thread.regs); |
| 215 | 215 | void *stack = task_stack_page(p); |
| @@ -254,9 +254,9 @@ copy_thread(unsigned long clone_flags, unsigned long usp, · 38 unmodified lines | ||
| 254 | 254 | cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; |
| 255 | 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 | 258 | if (clone_flags & CLONE_SETTLS) |
| 259 | − cregs->cr27 = cregs->gr[23]; | |
| 259 | + cregs->cr27 = tls; | |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | return 0; |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | * |
| 16 | 16 | * (the type definitions are in asm/spinlock_types.h) |
| 17 | 17 | */ |
| 18 | +#include <linux/jump_label.h> | |
| 18 | 19 | #include <linux/irqflags.h> |
| 19 | 20 | #ifdef CONFIG_PPC64 |
| 20 | 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 | 152 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 153 | 153 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 154 | − struct page *page = pfn_to_page(start_pfn) + vmem_altmap_offset(altmap); | |
| 155 | 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 | 158 | /* Remove htab bolted mappings for this section of memory */ |
| 160 | 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 | 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 | 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 | 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 | 664 | unsigned char *psizes; |
| 665 | 665 | int index, mask_index; |
| @@ -64,6 +64,8 @@ config RISCV · 63 unmodified lines | ||
| 64 | 64 | select SPARSEMEM_STATIC if 32BIT |
| 65 | 65 | select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU |
| 66 | 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 | 70 | config ARCH_MMAP_RND_BITS_MIN |
| 69 | 71 | default 18 if 64BIT |
| @@ -54,6 +54,7 @@ · 53 unmodified lines | ||
| 54 | 54 | reg = <1>; |
| 55 | 55 | riscv,isa = "rv64imafdc"; |
| 56 | 56 | tlb-split; |
| 57 | + next-level-cache = <&l2cache>; | |
| 57 | 58 | cpu1_intc: interrupt-controller { |
| 58 | 59 | #interrupt-cells = <1>; |
| 59 | 60 | compatible = "riscv,cpu-intc"; |
| @@ -77,6 +78,7 @@ · 17 unmodified lines | ||
| 77 | 78 | reg = <2>; |
| 78 | 79 | riscv,isa = "rv64imafdc"; |
| 79 | 80 | tlb-split; |
| 81 | + next-level-cache = <&l2cache>; | |
| 80 | 82 | cpu2_intc: interrupt-controller { |
| 81 | 83 | #interrupt-cells = <1>; |
| 82 | 84 | compatible = "riscv,cpu-intc"; |
| @@ -100,6 +102,7 @@ · 17 unmodified lines | ||
| 100 | 102 | reg = <3>; |
| 101 | 103 | riscv,isa = "rv64imafdc"; |
| 102 | 104 | tlb-split; |
| 105 | + next-level-cache = <&l2cache>; | |
| 103 | 106 | cpu3_intc: interrupt-controller { |
| 104 | 107 | #interrupt-cells = <1>; |
| 105 | 108 | compatible = "riscv,cpu-intc"; |
| @@ -123,6 +126,7 @@ · 17 unmodified lines | ||
| 123 | 126 | reg = <4>; |
| 124 | 127 | riscv,isa = "rv64imafdc"; |
| 125 | 128 | tlb-split; |
| 129 | + next-level-cache = <&l2cache>; | |
| 126 | 130 | cpu4_intc: interrupt-controller { |
| 127 | 131 | #interrupt-cells = <1>; |
| 128 | 132 | compatible = "riscv,cpu-intc"; |
| @@ -253,6 +257,17 @@ · 124 unmodified lines | ||
| 253 | 257 | #pwm-cells = <3>; |
| 254 | 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 | 116 | # define SR_PIE SR_MPIE |
| 117 | 117 | # define SR_PP SR_MPP |
| 118 | 118 | |
| 119 | −# define IRQ_SOFT IRQ_M_SOFT | |
| 120 | −# define IRQ_TIMER IRQ_M_TIMER | |
| 121 | −# define IRQ_EXT IRQ_M_EXT | |
| 119 | +# define RV_IRQ_SOFT IRQ_M_SOFT | |
| 120 | +# define RV_IRQ_TIMER IRQ_M_TIMER | |
| 121 | +# define RV_IRQ_EXT IRQ_M_EXT | |
| 122 | 122 | #else /* CONFIG_RISCV_M_MODE */ |
| 123 | 123 | # define CSR_STATUS CSR_SSTATUS |
| 124 | 124 | # define CSR_IE CSR_SIE |
| @@ -133,15 +133,15 @@ · 8 unmodified lines | ||
| 133 | 133 | # define SR_PIE SR_SPIE |
| 134 | 134 | # define SR_PP SR_SPP |
| 135 | 135 | |
| 136 | −# define IRQ_SOFT IRQ_S_SOFT | |
| 137 | −# define IRQ_TIMER IRQ_S_TIMER | |
| 138 | −# define IRQ_EXT IRQ_S_EXT | |
| 136 | +# define RV_IRQ_SOFT IRQ_S_SOFT | |
| 137 | +# define RV_IRQ_TIMER IRQ_S_TIMER | |
| 138 | +# define RV_IRQ_EXT IRQ_S_EXT | |
| 139 | 139 | #endif /* CONFIG_RISCV_M_MODE */ |
| 140 | 140 | |
| 141 | 141 | /* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */ |
| 142 | −#define IE_SIE (_AC(0x1, UL) << IRQ_SOFT) | |
| 143 | −#define IE_TIE (_AC(0x1, UL) << IRQ_TIMER) | |
| 144 | −#define IE_EIE (_AC(0x1, UL) << IRQ_EXT) | |
| 142 | +#define IE_SIE (_AC(0x1, UL) << RV_IRQ_SOFT) | |
| 143 | +#define IE_TIE (_AC(0x1, UL) << RV_IRQ_TIMER) | |
| 144 | +#define IE_EIE (_AC(0x1, UL) << RV_IRQ_EXT) | |
| 145 | 145 | |
| 146 | 146 | #ifndef __ASSEMBLY__ |
| 147 | 147 | |
| @@ -246,6 +246,7 @@ check_syscall_nr: · 245 unmodified lines | ||
| 246 | 246 | */ |
| 247 | 247 | li t1, -1 |
| 248 | 248 | beq a7, t1, ret_from_syscall_rejected |
| 249 | + blt a7, t1, 1f | |
| 249 | 250 | /* Call syscall */ |
| 250 | 251 | la s0, sys_call_table |
| 251 | 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 | 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 | 146 | *parent = return_hooker; |
| 147 | 147 | } |
| 148 | 148 | |
| @@ -251,7 +251,7 @@ ENTRY(reset_regs) · 250 unmodified lines | ||
| 251 | 251 | #ifdef CONFIG_FPU |
| 252 | 252 | csrr t0, CSR_MISA |
| 253 | 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 | 256 | li t1, SR_FS |
| 257 | 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 | 24 | irq_enter(); |
| 25 | 25 | switch (regs->cause & ~CAUSE_IRQ_FLAG) { |
| 26 | − case IRQ_TIMER: | |
| 26 | + case RV_IRQ_TIMER: | |
| 27 | 27 | riscv_timer_interrupt(); |
| 28 | 28 | break; |
| 29 | 29 | #ifdef CONFIG_SMP |
| 30 | − case IRQ_SOFT: | |
| 30 | + case RV_IRQ_SOFT: | |
| 31 | 31 | /* |
| 32 | 32 | * We only use software interrupts to pass IPIs, so if a non-SMP |
| 33 | 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 | 35 | riscv_software_interrupt(); |
| 36 | 36 | break; |
| 37 | 37 | #endif |
| 38 | − case IRQ_EXT: | |
| 38 | + case RV_IRQ_EXT: | |
| 39 | 39 | handle_arch_irq(regs); |
| 40 | 40 | break; |
| 41 | 41 | default: |
| @@ -99,8 +99,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) · 98 unmodified lines | ||
| 99 | 99 | return 0; |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | −int copy_thread(unsigned long clone_flags, unsigned long usp, | |
| 103 | − unsigned long arg, struct task_struct *p) | |
| 102 | +int copy_thread_tls(unsigned long clone_flags, unsigned long usp, | |
| 103 | + unsigned long arg, struct task_struct *p, unsigned long tls) | |
| 104 | 104 | { |
| 105 | 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 | 121 | if (usp) /* User fork */ |
| 122 | 122 | childregs->sp = usp; |
| 123 | 123 | if (clone_flags & CLONE_SETTLS) |
| 124 | − childregs->tp = childregs->a5; | |
| 124 | + childregs->tp = tls; | |
| 125 | 125 | childregs->a0 = 0; /* Return value of fork() */ |
| 126 | 126 | p->thread.ra = (unsigned long)ret_from_fork; |
| 127 | 127 | } |
| @@ -9,8 +9,5 @@ · 8 unmodified lines | ||
| 9 | 9 | /* |
| 10 | 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 | 12 | EXPORT_SYMBOL(memset); |
| 16 | 13 | EXPORT_SYMBOL(memcpy); |
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | #include <linux/linkage.h> |
| 2 | +#include <asm-generic/export.h> | |
| 2 | 3 | #include <asm/asm.h> |
| 3 | 4 | #include <asm/csr.h> |
| 4 | 5 | |
| @@ -66,6 +67,8 @@ ENTRY(__asm_copy_from_user) · 61 unmodified lines | ||
| 66 | 67 | j 3b |
| 67 | 68 | ENDPROC(__asm_copy_to_user) |
| 68 | 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 | 74 | ENTRY(__clear_user) |
| @@ -108,6 +111,7 @@ ENTRY(__clear_user) · 36 unmodified lines | ||
| 108 | 111 | bltu a0, a3, 5b |
| 109 | 112 | j 3b |
| 110 | 113 | ENDPROC(__clear_user) |
| 114 | +EXPORT_SYMBOL(__clear_user) | |
| 111 | 115 | |
| 112 | 116 | .section .fixup,"ax" |
| 113 | 117 | .balign 4 |
| @@ -22,6 +22,7 @@ void flush_icache_all(void) · 21 unmodified lines | ||
| 22 | 22 | else |
| 23 | 23 | on_each_cpu(ipi_remote_fence_i, NULL, 1); |
| 24 | 24 | } |
| 25 | +EXPORT_SYMBOL(flush_icache_all); | |
| 25 | 26 | |
| 26 | 27 | /* |
| 27 | 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 | 99 | pr_info("initrd not found or empty"); |
| 100 | 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 | 103 | pr_err("initrd extends beyond end of memory"); |
| 104 | 104 | goto disable; |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | size = initrd_end - initrd_start; |
| 108 | − memblock_reserve(__pa(initrd_start), size); | |
| 108 | + memblock_reserve(__pa_symbol(initrd_start), size); | |
| 109 | 109 | initrd_below_start_ok = 1; |
| 110 | 110 | |
| 111 | 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 | 125 | struct memblock_region *reg; |
| 126 | 126 | phys_addr_t mem_size = 0; |
| 127 | − phys_addr_t vmlinux_end = __pa(&_end); | |
| 128 | − phys_addr_t vmlinux_start = __pa(&_start); | |
| 127 | + phys_addr_t vmlinux_end = __pa_symbol(&_end); | |
| 128 | + phys_addr_t vmlinux_start = __pa_symbol(&_start); | |
| 129 | 129 | |
| 130 | 130 | /* Find the memory region containing the kernel */ |
| 131 | 131 | for_each_memblock(memory, reg) { |
| @@ -445,7 +445,7 @@ static void __init setup_vm_final(void) · 313 unmodified lines | ||
| 445 | 445 | |
| 446 | 446 | /* Setup swapper PGD for fixmap */ |
| 447 | 447 | create_pgd_mapping(swapper_pg_dir, FIXADDR_START, |
| 448 | − __pa(fixmap_pgd_next), | |
| 448 | + __pa_symbol(fixmap_pgd_next), | |
| 449 | 449 | PGDIR_SIZE, PAGE_TABLE); |
| 450 | 450 | |
| 451 | 451 | /* Map all memory banks */ |
| @@ -474,7 +474,7 @@ static void __init setup_vm_final(void) · 22 unmodified lines | ||
| 474 | 474 | clear_fixmap(FIX_PMD); |
| 475 | 475 | |
| 476 | 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 | 478 | local_flush_tlb_all(); |
| 479 | 479 | } |
| 480 | 480 | #else |
| @@ -292,10 +292,8 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 291 unmodified lines | ||
| 292 | 292 | { |
| 293 | 293 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 294 | 294 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 295 | − struct zone *zone; | |
| 296 | 295 | |
| 297 | − zone = page_zone(pfn_to_page(start_pfn)); | |
| 298 | − __remove_pages(zone, start_pfn, nr_pages, altmap); | |
| 296 | + __remove_pages(start_pfn, nr_pages, altmap); | |
| 299 | 297 | vmem_remove_mapping(start, size); |
| 300 | 298 | } |
| 301 | 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 | 435 | unsigned long start_pfn = PFN_DOWN(start); |
| 436 | 436 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 437 | − struct zone *zone; | |
| 438 | 437 | |
| 439 | − zone = page_zone(pfn_to_page(start_pfn)); | |
| 440 | − __remove_pages(zone, start_pfn, nr_pages, altmap); | |
| 438 | + __remove_pages(start_pfn, nr_pages, altmap); | |
| 441 | 439 | } |
| 442 | 440 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
| @@ -14,6 +14,7 @@ config UML · 13 unmodified lines | ||
| 14 | 14 | select HAVE_FUTEX_CMPXCHG if FUTEX |
| 15 | 15 | select HAVE_DEBUG_KMEMLEAK |
| 16 | 16 | select HAVE_DEBUG_BUGVERBOSE |
| 17 | + select HAVE_COPY_THREAD_TLS | |
| 17 | 18 | select GENERIC_IRQ_SHOW |
| 18 | 19 | select GENERIC_CPU_DEVICES |
| 19 | 20 | select GENERIC_CLOCKEVENTS |
| @@ -36,7 +36,7 @@ extern long subarch_ptrace(struct task_struct *child, long request, · 35 unmodified lines | ||
| 36 | 36 | extern unsigned long getreg(struct task_struct *child, int regno); |
| 37 | 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 | 40 | extern void clear_flushed_tls(struct task_struct *task); |
| 41 | 41 | extern int syscall_trace_enter(struct pt_regs *regs); |
| 42 | 42 | extern void syscall_trace_leave(struct pt_regs *regs); |
| @@ -153,8 +153,8 @@ void fork_handler(void) · 152 unmodified lines | ||
| 153 | 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, | |
| 157 | − unsigned long arg, struct task_struct * p) | |
| 156 | +int copy_thread_tls(unsigned long clone_flags, unsigned long sp, | |
| 157 | + unsigned long arg, struct task_struct * p, unsigned long tls) | |
| 158 | 158 | { |
| 159 | 159 | void (*handler)(void); |
| 160 | 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 | 188 | * Set a new TLS for the child thread? |
| 189 | 189 | */ |
| 190 | 190 | if (clone_flags & CLONE_SETTLS) |
| 191 | − ret = arch_copy_tls(p); | |
| 191 | + ret = arch_set_tls(p, tls); | |
| 192 | 192 | } |
| 193 | 193 | |
| 194 | 194 | return ret; |
| @@ -865,10 +865,8 @@ void arch_remove_memory(int nid, u64 start, u64 size, · 864 unmodified lines | ||
| 865 | 865 | { |
| 866 | 866 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 867 | 867 | unsigned long nr_pages = size >> PAGE_SHIFT; |
| 868 | − struct zone *zone; | |
| 869 | 868 | |
| 870 | − zone = page_zone(pfn_to_page(start_pfn)); | |
| 871 | − __remove_pages(zone, start_pfn, nr_pages, altmap); | |
| 869 | + __remove_pages(start_pfn, nr_pages, altmap); | |
| 872 | 870 | } |
| 873 | 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 | 1213 | unsigned long start_pfn = start >> PAGE_SHIFT; |
| 1214 | 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 | 1217 | kernel_physical_mapping_remove(start, start + size); |
| 1220 | 1218 | } |
| 1221 | 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 | 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 | 220 | struct user_desc info; |
| 221 | 221 | int idx, ret = -EFAULT; |
| 222 | 222 | |
| 223 | − if (copy_from_user(&info, | |
| 224 | − (void __user *) UPT_SI(&new->thread.regs.regs), | |
| 225 | − sizeof(info))) | |
| 223 | + if (copy_from_user(&info, (void __user *) tls, sizeof(info))) | |
| 226 | 224 | goto out; |
| 227 | 225 | |
| 228 | 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 | 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 | |
| 14 | − * during context switches. | |
| 13 | + * so it can be set 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 | 17 | return 0; |
| 19 | 18 | } |
| @@ -24,6 +24,7 @@ config XTENSA · 23 unmodified lines | ||
| 24 | 24 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL |
| 25 | 25 | select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL |
| 26 | 26 | select HAVE_ARCH_TRACEHOOK |
| 27 | + select HAVE_COPY_THREAD_TLS | |
| 27 | 28 | select HAVE_DEBUG_KMEMLEAK |
| 28 | 29 | select HAVE_DMA_CONTIGUOUS |
| 29 | 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 | 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, | |
| 206 | − unsigned long thread_fn_arg, struct task_struct *p) | |
| 205 | +int copy_thread_tls(unsigned long clone_flags, unsigned long usp_thread_fn, | |
| 206 | + unsigned long thread_fn_arg, struct task_struct *p, | |
| 207 | + unsigned long tls) | |
| 207 | 208 | { |
| 208 | 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 | 268 | childregs->syscall = regs->syscall; |
| 268 | 269 | |
| 269 | − /* The thread pointer is passed in the '4th argument' (= a5) */ | |
| 270 | 270 | if (clone_flags & CLONE_SETTLS) |
| 271 | − childregs->threadptr = childregs->areg[5]; | |
| 271 | + childregs->threadptr = tls; | |
| 272 | 272 | } else { |
| 273 | 273 | p->thread.ra = MAKE_RA_FOR_CALL( |
| 274 | 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 | 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 | 591 | * bio_put - release a reference to a bio |
| 543 | 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 | 157 | return sectors & (lbs - 1); |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | −static unsigned get_max_segment_size(const struct request_queue *q, | |
| 161 | − unsigned offset) | |
| 160 | +static inline unsigned get_max_segment_size(const struct request_queue *q, | |
| 161 | + struct page *start_page, | |
| 162 | + unsigned long offset) | |
| 162 | 163 | { |
| 163 | 164 | unsigned long mask = queue_segment_boundary(q); |
| 164 | 165 | |
| 165 | − /* default segment boundary mask means no boundary limit */ | |
| 166 | − if (mask == BLK_SEG_BOUNDARY_MASK) | |
| 167 | − return queue_max_segment_size(q); | |
| 168 | − | |
| 169 | − return min_t(unsigned long, mask - (mask & offset) + 1, | |
| 166 | + offset = mask & (page_to_phys(start_page) + offset); | |
| 167 | + return min_t(unsigned long, mask - offset + 1, | |
| 170 | 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 | 199 | unsigned seg_size = 0; |
| 202 | 200 | |
| 203 | 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 | 204 | seg_size = min(seg_size, len); |
| 206 | 205 | |
| 207 | 206 | (*nsegs)++; |
| @@ -419,7 +418,8 @@ static unsigned blk_bvec_map_sg(struct request_queue *q, · 211 unmodified lines | ||
| 419 | 418 | |
| 420 | 419 | while (nbytes > 0) { |
| 421 | 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 | 423 | struct page *page = bvec->bv_page; |
| 424 | 424 | |
| 425 | 425 | /* |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/compat.h> |
| 7 | 7 | #include <linux/elevator.h> |
| 8 | 8 | #include <linux/hdreg.h> |
| 9 | +#include <linux/pr.h> | |
| 9 | 10 | #include <linux/slab.h> |
| 10 | 11 | #include <linux/syscalls.h> |
| 11 | 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 | 355 | * but we call blkdev_ioctl, which gets the lock for us |
| 355 | 356 | */ |
| 356 | 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 | 365 | return blkdev_ioctl(bdev, mode, cmd, |
| 358 | 366 | (unsigned long)compat_ptr(arg)); |
| 359 | 367 | case BLKBSZSET_32: |
| @@ -401,6 +409,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) · 41 unmodified lines | ||
| 401 | 409 | case BLKTRACETEARDOWN: /* compatible */ |
| 402 | 410 | ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); |
| 403 | 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 | 420 | default: |
| 405 | 421 | if (disk->fops->compat_ioctl) |
| 406 | 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 | 78 | enum brcm_ahci_quirks { |
| 79 | − BRCM_AHCI_QUIRK_NO_NCQ = BIT(0), | |
| 80 | − BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1), | |
| 79 | + BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(0), | |
| 81 | 80 | }; |
| 82 | 81 | |
| 83 | 82 | struct brcm_ahci_priv { |
| @@ -213,19 +212,12 @@ static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv) · 129 unmodified lines | ||
| 213 | 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 | 216 | struct brcm_ahci_priv *priv) |
| 218 | 217 | { |
| 219 | − void __iomem *ahci; | |
| 220 | − struct resource *res; | |
| 221 | 218 | u32 impl; |
| 222 | 219 | |
| 223 | − res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci"); | |
| 224 | − ahci = devm_ioremap_resource(&pdev->dev, res); | |
| 225 | − if (IS_ERR(ahci)) | |
| 226 | − return 0; | |
| 227 | − | |
| 228 | − impl = readl(ahci + HOST_PORTS_IMPL); | |
| 220 | + impl = readl(hpriv->mmio + HOST_PORTS_IMPL); | |
| 229 | 221 | |
| 230 | 222 | if (fls(impl) > SATA_TOP_MAX_PHYS) |
| 231 | 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 | 225 | else if (!impl) |
| 234 | 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 | 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 | 274 | /* Perform the SATA PHY reset sequence */ |
| 286 | 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 | 284 | /* Bring the PHY back on */ |
| 289 | 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 | 343 | struct ata_host *host = dev_get_drvdata(dev); |
| 348 | 344 | struct ahci_host_priv *hpriv = host->private_data; |
| 349 | 345 | struct brcm_ahci_priv *priv = hpriv->plat_data; |
| 350 | − int ret; | |
| 351 | 346 | |
| 352 | − ret = ahci_platform_suspend(dev); | |
| 353 | 347 | brcm_sata_phys_disable(priv); |
| 354 | − return ret; | |
| 348 | + | |
| 349 | + return ahci_platform_suspend(dev); | |
| 355 | 350 | } |
| 356 | 351 | |
| 357 | 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 | 354 | struct ata_host *host = dev_get_drvdata(dev); |
| 360 | 355 | struct ahci_host_priv *hpriv = host->private_data; |
| 361 | 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 | 364 | brcm_sata_init(priv); |
| 364 | 365 | brcm_sata_phys_enable(priv); |
| 365 | 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 | 396 | #endif |
| 369 | 397 | |
| @@ -410,44 +438,71 @@ static int brcm_ahci_probe(struct platform_device *pdev) · 40 unmodified lines | ||
| 410 | 438 | if (!IS_ERR_OR_NULL(priv->rcdev)) |
| 411 | 439 | reset_control_deassert(priv->rcdev); |
| 412 | 440 | |
| 413 | − if ((priv->version == BRCM_SATA_BCM7425) || | |
| 414 | − (priv->version == BRCM_SATA_NSP)) { | |
| 415 | − priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ; | |
| 441 | + hpriv = ahci_platform_get_resources(pdev, 0); | |
| 442 | + if (IS_ERR(hpriv)) { | |
| 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 | 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 | 469 | brcm_sata_init(priv); |
| 420 | 470 | |
| 421 | − priv->port_mask = brcm_ahci_get_portmask(pdev, priv); | |
| 422 | − if (!priv->port_mask) | |
| 423 | − return -ENODEV; | |
| 471 | + /* Initializes priv->port_mask which is used below */ | |
| 472 | + priv->port_mask = brcm_ahci_get_portmask(hpriv, priv); | |
| 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 | 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 | 481 | brcm_sata_alpm_init(hpriv); |
| 434 | 482 | |
| 435 | − ret = ahci_platform_enable_resources(hpriv); | |
| 483 | + ret = ahci_platform_enable_phys(hpriv); | |
| 436 | 484 | if (ret) |
| 437 | − return ret; | |
| 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; | |
| 485 | + goto out_disable_phys; | |
| 442 | 486 | |
| 443 | 487 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info, |
| 444 | 488 | &ahci_platform_sht); |
| 445 | 489 | if (ret) |
| 446 | − return ret; | |
| 490 | + goto out_disable_platform_phys; | |
| 447 | 491 | |
| 448 | 492 | dev_info(dev, "Broadcom AHCI SATA3 registered\n"); |
| 449 | 493 | |
| 450 | 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 | 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 | 512 | struct brcm_ahci_priv *priv = hpriv->plat_data; |
| 458 | 513 | int ret; |
| 459 | 514 | |
| 515 | + brcm_sata_phys_disable(priv); | |
| 516 | + | |
| 460 | 517 | ret = ata_platform_remove_one(pdev); |
| 461 | 518 | if (ret) |
| 462 | 519 | return ret; |
| 463 | 520 | |
| 464 | − brcm_sata_phys_disable(priv); | |
| 465 | − | |
| 466 | 521 | return 0; |
| 467 | 522 | } |
| 468 | 523 | |
| @@ -43,7 +43,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_ops); · 42 unmodified lines | ||
| 43 | 43 | * RETURNS: |
| 44 | 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 | 48 | int rc, i; |
| 49 | 49 | |
| @@ -74,6 +74,7 @@ disable_phys: · 24 unmodified lines | ||
| 74 | 74 | } |
| 75 | 75 | return rc; |
| 76 | 76 | } |
| 77 | +EXPORT_SYMBOL_GPL(ahci_platform_enable_phys); | |
| 77 | 78 | |
| 78 | 79 | /** |
| 79 | 80 | * ahci_platform_disable_phys - Disable PHYs |
| @@ -81,7 +82,7 @@ disable_phys: · 1 unmodified line | ||
| 81 | 82 | * |
| 82 | 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 | 87 | int i; |
| 87 | 88 | |
| @@ -90,6 +91,7 @@ static void ahci_platform_disable_phys(struct ahci_host_priv *hpriv) · 2 unmodified lines | ||
| 90 | 91 | phy_exit(hpriv->phys[i]); |
| 91 | 92 | } |
| 92 | 93 | } |
| 94 | +EXPORT_SYMBOL_GPL(ahci_platform_disable_phys); | |
| 93 | 95 | |
| 94 | 96 | /** |
| 95 | 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 | 5356 | * ata_qc_complete_multiple - Complete multiple qcs successfully |
| 5333 | 5357 | * @ap: port in question |
| @@ -1280,7 +1280,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) · 1279 unmodified lines | ||
| 1280 | 1280 | i, ioread32(hcr_base + CC), |
| 1281 | 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 | 1284 | return; |
| 1285 | 1285 | |
| 1286 | 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 | 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 | 2834 | /* Update the software queue position index in hardware */ |
| 2835 | 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 | 984 | check_commands = 0; |
| 985 | 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 | 374 | here = (eni_vcc->descr+skip) & (eni_vcc->words-1); |
| 375 | 375 | dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci |
| 376 | 376 | << MID_DMA_VCI_SHIFT) | MID_DT_JK; |
| 377 | − j++; | |
| 377 | + dma[j++] = 0; | |
| 378 | 378 | } |
| 379 | 379 | here = (eni_vcc->descr+size+skip) & (eni_vcc->words-1); |
| 380 | 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 | 447 | if (size != eff) { |
| 448 | 448 | dma[j++] = (here << MID_DMA_COUNT_SHIFT) | |
| 449 | 449 | (vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK; |
| 450 | − j++; | |
| 450 | + dma[j++] = 0; | |
| 451 | 451 | } |
| 452 | 452 | if (!j || j > 2*RX_DMA_BUF) { |
| 453 | 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 | 186 | if (zone->cond == BLK_ZONE_COND_FULL) |
| 187 | 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 | 193 | break; |
| 191 | 194 | case REQ_OP_ZONE_FINISH: |
| 192 | 195 | if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) |
| @@ -2707,7 +2707,7 @@ static const struct block_device_operations pktcdvd_ops = { · 2706 unmodified lines | ||
| 2707 | 2707 | .release = pkt_close, |
| 2708 | 2708 | .ioctl = pkt_ioctl, |
| 2709 | 2709 | #ifdef CONFIG_COMPAT |
| 2710 | − .ioctl = pkt_compat_ioctl, | |
| 2710 | + .compat_ioctl = pkt_compat_ioctl, | |
| 2711 | 2711 | #endif |
| 2712 | 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 | 84 | unsigned int cdev = 0; |
| 85 | 85 | u32 mnistat, tnistat, tstatus, mcmd; |
| 86 | 86 | u16 tnicmd, mnicmd; |
| 87 | − u8 mcapndx; | |
| 88 | 87 | u32 tot_bw = 0, tot_n = 0, tot_rq = 0, y_max, rq_isoch, rq_async; |
| 89 | 88 | u32 step, rem, rem_isoch, rem_async; |
| 90 | 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 | 137 | cur = list_entry(pos, struct agp_3_5_dev, list); |
| 139 | 138 | dev = cur->dev; |
| 140 | 139 | |
| 141 | − mcapndx = cur->capndx; | |
| 142 | − | |
| 143 | 140 | pci_read_config_dword(dev, cur->capndx+AGPNISTAT, &mnistat); |
| 144 | 141 | |
| 145 | 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 | 248 | cur = master[cdev].dev; |
| 252 | 249 | dev = cur->dev; |
| 253 | 250 | |
| 254 | − mcapndx = cur->capndx; | |
| 255 | − | |
| 256 | 251 | master[cdev].rq += (cdev == ndevs - 1) |
| 257 | 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 | 315 | struct pci_dev *td = bridge->dev, *dev = NULL; |
| 321 | 316 | u8 mcapndx; |
| 322 | − u32 isoch, arqsz; | |
| 317 | + u32 isoch; | |
| 323 | 318 | u32 tstatus, mstatus, ncapid; |
| 324 | 319 | u32 mmajor; |
| 325 | 320 | u16 mpstat; |
| @@ -334,8 +329,6 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) · 8 unmodified lines | ||
| 334 | 329 | if (isoch == 0) /* isoch xfers not available, bail out. */ |
| 335 | 330 | return -ENODEV; |
| 336 | 331 | |
| 337 | − arqsz = (tstatus >> 13) & 0x7; | |
| 338 | − | |
| 339 | 332 | /* |
| 340 | 333 | * Allocate a head for our AGP 3.5 device list |
| 341 | 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 | 130 | priv->response_read = true; |
| 131 | 131 | |
| 132 | 132 | ret_size = min_t(ssize_t, size, priv->response_length); |
| 133 | − if (!ret_size) { | |
| 133 | + if (ret_size <= 0) { | |
| 134 | 134 | priv->response_length = 0; |
| 135 | 135 | goto out; |
| 136 | 136 | } |
| @@ -14,7 +14,7 @@ struct file_priv { · 13 unmodified lines | ||
| 14 | 14 | struct work_struct timeout_work; |
| 15 | 15 | struct work_struct async_work; |
| 16 | 16 | wait_queue_head_t async_wait; |
| 17 | − size_t response_length; | |
| 17 | + ssize_t response_length; | |
| 18 | 18 | bool response_read; |
| 19 | 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 | 979 | if (wait_startup(chip, 0) != 0) { |
| 980 | 980 | rc = -ENODEV; |
| 981 | − goto err_start; | |
| 981 | + goto out_err; | |
| 982 | 982 | } |
| 983 | 983 | |
| 984 | 984 | /* Take control of the TPM's interrupt hardware and shut it off */ |
| 985 | 985 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); |
| 986 | 986 | if (rc < 0) |
| 987 | − goto err_start; | |
| 987 | + goto out_err; | |
| 988 | 988 | |
| 989 | 989 | intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | |
| 990 | 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 | 994 | rc = tpm_chip_start(chip); |
| 995 | 995 | if (rc) |
| 996 | − goto err_start; | |
| 997 | − | |
| 996 | + goto out_err; | |
| 998 | 997 | rc = tpm2_probe(chip); |
| 998 | + tpm_chip_stop(chip); | |
| 999 | 999 | if (rc) |
| 1000 | − goto err_probe; | |
| 1000 | + goto out_err; | |
| 1001 | 1001 | |
| 1002 | 1002 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); |
| 1003 | 1003 | if (rc < 0) |
| 1004 | − goto err_probe; | |
| 1004 | + goto out_err; | |
| 1005 | 1005 | |
| 1006 | 1006 | priv->manufacturer_id = vendor; |
| 1007 | 1007 | |
| 1008 | 1008 | rc = tpm_tis_read8(priv, TPM_RID(0), &rid); |
| 1009 | 1009 | if (rc < 0) |
| 1010 | − goto err_probe; | |
| 1010 | + goto out_err; | |
| 1011 | 1011 | |
| 1012 | 1012 | dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n", |
| 1013 | 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 | 1016 | probe = probe_itpm(chip); |
| 1017 | 1017 | if (probe < 0) { |
| 1018 | 1018 | rc = -ENODEV; |
| 1019 | − goto err_probe; | |
| 1019 | + goto out_err; | |
| 1020 | 1020 | } |
| 1021 | 1021 | |
| 1022 | 1022 | /* Figure out the capabilities */ |
| 1023 | 1023 | rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps); |
| 1024 | 1024 | if (rc < 0) |
| 1025 | − goto err_probe; | |
| 1025 | + goto out_err; | |
| 1026 | 1026 | |
| 1027 | 1027 | dev_dbg(dev, "TPM interface capabilities (0x%x):\n", |
| 1028 | 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 | 1056 | if (tpm_get_timeouts(chip)) { |
| 1057 | 1057 | dev_err(dev, "Could not get TPM timeouts and durations\n"); |
| 1058 | 1058 | rc = -ENODEV; |
| 1059 | − goto err_probe; | |
| 1059 | + goto out_err; | |
| 1060 | 1060 | } |
| 1061 | 1061 | |
| 1062 | − chip->flags |= TPM_CHIP_FLAG_IRQ; | |
| 1063 | 1062 | if (irq) { |
| 1064 | 1063 | tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, |
| 1065 | 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 | 1073 | rc = tpm_chip_register(chip); |
| 1077 | 1074 | if (rc) |
| 1078 | − goto err_start; | |
| 1079 | − | |
| 1080 | − return 0; | |
| 1075 | + goto out_err; | |
| 1081 | 1076 | |
| 1082 | −err_probe: | |
| 1083 | − tpm_chip_stop(chip); | |
| 1077 | + if (chip->ops->clk_enable != NULL) | |
| 1078 | + chip->ops->clk_enable(chip, false); | |
| 1084 | 1079 | |
| 1085 | −err_start: | |
| 1080 | + return 0; | |
| 1081 | +out_err: | |
| 1086 | 1082 | if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) |
| 1087 | 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 | 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 | 61 | return get_cycles64(); |
| 62 | 62 | } |
| @@ -121,6 +121,8 @@ static const struct of_device_id blacklist[] __initconst = { · 120 unmodified lines | ||
| 121 | 121 | { .compatible = "mediatek,mt8176", }, |
| 122 | 122 | { .compatible = "mediatek,mt8183", }, |
| 123 | 123 | |
| 124 | + { .compatible = "nvidia,tegra20", }, | |
| 125 | + { .compatible = "nvidia,tegra30", }, | |
| 124 | 126 | { .compatible = "nvidia,tegra124", }, |
| 125 | 127 | { .compatible = "nvidia,tegra210", }, |
| 126 | 128 | |
| @@ -83,7 +83,6 @@ config ARM_EXYNOS_BUS_DEVFREQ · 82 unmodified lines | ||
| 83 | 83 | select DEVFREQ_GOV_PASSIVE |
| 84 | 84 | select DEVFREQ_EVENT_EXYNOS_PPMU |
| 85 | 85 | select PM_DEVFREQ_EVENT |
| 86 | − select PM_OPP | |
| 87 | 86 | help |
| 88 | 87 | This adds the common DEVFREQ driver for Exynos Memory bus. Exynos |
| 89 | 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 | 97 | ARCH_TEGRA_132_SOC || ARCH_TEGRA_124_SOC || \ |
| 99 | 98 | ARCH_TEGRA_210_SOC || \ |
| 100 | 99 | COMPILE_TEST |
| 101 | − select PM_OPP | |
| 100 | + depends on COMMON_CLK | |
| 102 | 101 | help |
| 103 | 102 | This adds the DEVFREQ driver for the Tegra family of SoCs. |
| 104 | 103 | It reads ACTMON counters of memory controllers and adjusts the |
| @@ -109,7 +108,6 @@ config ARM_TEGRA20_DEVFREQ · 4 unmodified lines | ||
| 109 | 108 | depends on (TEGRA_MC && TEGRA20_EMC) || COMPILE_TEST |
| 110 | 109 | depends on COMMON_CLK |
| 111 | 110 | select DEVFREQ_GOV_SIMPLE_ONDEMAND |
| 112 | − select PM_OPP | |
| 113 | 111 | help |
| 114 | 112 | This adds the DEVFREQ driver for the Tegra20 family of SoCs. |
| 115 | 113 | It reads Memory Controller counters and adjusts the operating |
| @@ -121,7 +119,6 @@ config ARM_RK3399_DMC_DEVFREQ · 5 unmodified lines | ||
| 121 | 119 | select DEVFREQ_EVENT_ROCKCHIP_DFI |
| 122 | 120 | select DEVFREQ_GOV_SIMPLE_ONDEMAND |
| 123 | 121 | select PM_DEVFREQ_EVENT |
| 124 | − select PM_OPP | |
| 125 | 122 | help |
| 126 | 123 | This adds the DEVFREQ driver for the RK3399 DMC(Dynamic Memory Controller). |
| 127 | 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 | 999 | static const struct jz4780_dma_soc_data jz4725b_dma_soc_data = { |
| 1000 | 1000 | .nb_channels = 6, |
| 1001 | 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 | 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 | 378 | descs->virt = dma_alloc_coherent(to_dev(ioat_chan), |
| 379 | 379 | SZ_2M, &descs->hw, flags); |
| 380 | − if (!descs->virt && (i > 0)) { | |
| 380 | + if (!descs->virt) { | |
| 381 | 381 | int idx; |
| 382 | 382 | |
| 383 | 383 | for (idx = 0; idx < i; idx++) { |
| 384 | + descs = &ioat_chan->descs[idx]; | |
| 384 | 385 | dma_free_coherent(to_dev(ioat_chan), SZ_2M, |
| 385 | 386 | descs->virt, descs->hw); |
| 386 | 387 | descs->virt = NULL; |
| @@ -229,9 +229,11 @@ static irqreturn_t k3_dma_int_handler(int irq, void *dev_id) · 228 unmodified lines | ||
| 229 | 229 | c = p->vchan; |
| 230 | 230 | if (c && (tc1 & BIT(i))) { |
| 231 | 231 | spin_lock_irqsave(&c->vc.lock, flags); |
| 232 | − vchan_cookie_complete(&p->ds_run->vd); | |
| 233 | − p->ds_done = p->ds_run; | |
| 234 | − p->ds_run = NULL; | |
| 232 | + if (p->ds_run != NULL) { | |
| 233 | + vchan_cookie_complete(&p->ds_run->vd); | |
| 234 | + p->ds_done = p->ds_run; | |
| 235 | + p->ds_run = NULL; | |
| 236 | + } | |
| 235 | 237 | spin_unlock_irqrestore(&c->vc.lock, flags); |
| 236 | 238 | } |
| 237 | 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 | 273 | if (BIT(c->phy->idx) & k3_dma_get_chan_stat(d)) |
| 272 | 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 | 280 | if (vd) { |
| 275 | 281 | struct k3_dma_desc_sw *ds = |
| 276 | 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 | 104 | dmaengine_desc_get_callback(&vd->tx, &cb); |
| 105 | 105 | |
| 106 | 106 | list_del(&vd->node); |
| 107 | − vchan_vdesc_fini(vd); | |
| 108 | − | |
| 109 | 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 | 10 | #include <linux/edac.h> |
| 11 | 11 | #include <linux/platform_device.h> |
| 12 | 12 | #include "edac_module.h" |
| 13 | −#include <asm/sifive_l2_cache.h> | |
| 13 | +#include <soc/sifive/sifive_l2_cache.h> | |
| 14 | 14 | |
| 15 | 15 | #define DRVNAME "sifive_edac" |
| 16 | 16 | |
| @@ -215,7 +215,6 @@ static int tee_bnxt_fw_probe(struct device *dev) · 214 unmodified lines | ||
| 215 | 215 | fw_shm_pool = tee_shm_alloc(pvt_data.ctx, MAX_SHM_MEM_SZ, |
| 216 | 216 | TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); |
| 217 | 217 | if (IS_ERR(fw_shm_pool)) { |
| 218 | − tee_client_close_context(pvt_data.ctx); | |
| 219 | 218 | dev_err(pvt_data.dev, "tee_shm_alloc failed\n"); |
| 220 | 219 | err = PTR_ERR(fw_shm_pool); |
| 221 | 220 | goto out_sess; |
| @@ -553,8 +553,8 @@ config GPIO_TEGRA · 552 unmodified lines | ||
| 553 | 553 | |
| 554 | 554 | config GPIO_TEGRA186 |
| 555 | 555 | tristate "NVIDIA Tegra186 GPIO support" |
| 556 | − default ARCH_TEGRA_186_SOC | |
| 557 | − depends on ARCH_TEGRA_186_SOC || COMPILE_TEST | |
| 556 | + default ARCH_TEGRA_186_SOC || ARCH_TEGRA_194_SOC | |
| 557 | + depends on ARCH_TEGRA_186_SOC || ARCH_TEGRA_194_SOC || COMPILE_TEST | |
| 558 | 558 | depends on OF_GPIO |
| 559 | 559 | select GPIOLIB_IRQCHIP |
| 560 | 560 | select IRQ_DOMAIN_HIERARCHY |
| @@ -1148,6 +1148,7 @@ config GPIO_MADERA · 587 unmodified lines | ||
| 1148 | 1148 | config GPIO_MAX77620 |
| 1149 | 1149 | tristate "GPIO support for PMIC MAX77620 and MAX20024" |
| 1150 | 1150 | depends on MFD_MAX77620 |
| 1151 | + select GPIOLIB_IRQCHIP | |
| 1151 | 1152 | help |
| 1152 | 1153 | GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor. |
| 1153 | 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 | 107 | return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS; |
| 108 | 108 | default: |
| 109 | 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 | 156 | mutex_lock(&chip->lock); |
| 157 | 157 | |
| 158 | 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 | 160 | curr = __gpio_mockup_get(chip, offset); |
| 161 | 161 | if (curr == value) |
| 162 | 162 | goto out; |
| @@ -165,7 +165,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip, · 2 unmodified lines | ||
| 165 | 165 | irq_type = irq_get_trigger_type(irq); |
| 166 | 166 | |
| 167 | 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 | 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 | 226 | int direction; |
| 227 | 227 | |
| 228 | 228 | mutex_lock(&chip->lock); |
| 229 | − direction = !chip->lines[offset].dir; | |
| 229 | + direction = chip->lines[offset].dir; | |
| 230 | 230 | mutex_unlock(&chip->lock); |
| 231 | 231 | |
| 232 | 232 | return direction; |
| @@ -395,7 +395,7 @@ static int gpio_mockup_probe(struct platform_device *pdev) · 162 unmodified lines | ||
| 395 | 395 | struct gpio_chip *gc; |
| 396 | 396 | struct device *dev; |
| 397 | 397 | const char *name; |
| 398 | − int rv, base; | |
| 398 | + int rv, base, i; | |
| 399 | 399 | u16 ngpio; |
| 400 | 400 | |
| 401 | 401 | dev = &pdev->dev; |
| @@ -447,6 +447,9 @@ static int gpio_mockup_probe(struct platform_device *pdev) · 45 unmodified lines | ||
| 447 | 447 | if (!chip->lines) |
| 448 | 448 | return -ENOMEM; |
| 449 | 449 | |
| 450 | + for (i = 0; i < gc->ngpio; i++) | |
| 451 | + chip->lines[i].dir = GPIO_LINE_DIRECTION_IN; | |
| 452 | + | |
| 450 | 453 | if (device_property_read_bool(dev, "named-gpio-lines")) { |
| 451 | 454 | rv = gpio_mockup_name_lines(dev, chip); |
| 452 | 455 | if (rv) |
| @@ -346,6 +346,7 @@ static int mpc8xxx_probe(struct platform_device *pdev) · 345 unmodified lines | ||
| 346 | 346 | return -ENOMEM; |
| 347 | 347 | |
| 348 | 348 | gc = &mpc8xxx_gc->gc; |
| 349 | + gc->parent = &pdev->dev; | |
| 349 | 350 | |
| 350 | 351 | if (of_property_read_bool(np, "little-endian")) { |
| 351 | 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 | 569 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 570 | 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 | 576 | static void pca953x_irq_unmask(struct irq_data *d) |
| 576 | 577 | { |
| 577 | 578 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 578 | 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 | 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 | 638 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 637 | 639 | struct pca953x_chip *chip = gpiochip_get_data(gc); |
| 638 | − int bank_nb = d->hwirq / BANK_SZ; | |
| 639 | − u8 mask = BIT(d->hwirq % BANK_SZ); | |
| 640 | + irq_hw_number_t hwirq = irqd_to_hwirq(d); | |
| 640 | 641 | |
| 641 | 642 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
| 642 | 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 | 645 | return -EINVAL; |
| 645 | 646 | } |
| 646 | 647 | |
| 647 | − if (type & IRQ_TYPE_EDGE_FALLING) | |
| 648 | − chip->irq_trig_fall[bank_nb] |= mask; | |
| 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; | |
| 648 | + assign_bit(hwirq, chip->irq_trig_fall, type & IRQ_TYPE_EDGE_FALLING); | |
| 649 | + assign_bit(hwirq, chip->irq_trig_raise, type & IRQ_TYPE_EDGE_RISING); | |
| 656 | 650 | |
| 657 | 651 | return 0; |
| 658 | 652 | } |
| @@ -661,10 +655,10 @@ static void pca953x_irq_shutdown(struct irq_data *d) · 2 unmodified lines | ||
| 661 | 655 | { |
| 662 | 656 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
| 663 | 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; | |
| 667 | − chip->irq_trig_fall[d->hwirq / BANK_SZ] &= ~mask; | |
| 660 | + clear_bit(hwirq, chip->irq_trig_raise); | |
| 661 | + clear_bit(hwirq, chip->irq_trig_fall); | |
| 668 | 662 | } |
| 669 | 663 | |
| 670 | 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 | 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 | 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 | 44 | unsigned long flags; |
| 45 | 45 | |
| 46 | 46 | local_irq_save(flags); |
| 47 | − RSR_CPENABLE(*cpenable); | |
| 48 | − WSR_CPENABLE(*cpenable | BIT(XCHAL_CP_ID_XTIOP)); | |
| 49 | − | |
| 47 | + *cpenable = xtensa_get_sr(cpenable); | |
| 48 | + xtensa_set_sr(*cpenable | BIT(XCHAL_CP_ID_XTIOP), cpenable); | |
| 50 | 49 | return flags; |
| 51 | 50 | } |
| 52 | 51 | |
| 53 | 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 | 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 | 684 | unsigned int bank_num; |
| 685 | 685 | |
| 686 | 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 | 689 | writel_relaxed(gpio->context.datalsw[bank_num], |
| 688 | 690 | gpio->base_addr + |
| 689 | 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 | 695 | writel_relaxed(gpio->context.dirm[bank_num], |
| 694 | 696 | gpio->base_addr + |
| 695 | 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 | 698 | writel_relaxed(gpio->context.int_type[bank_num], |
| 700 | 699 | gpio->base_addr + |
| 701 | 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 | 704 | writel_relaxed(gpio->context.int_any[bank_num], |
| 706 | 705 | gpio->base_addr + |
| 707 | 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 | 21 | #include "gpiolib.h" |
| 22 | 22 | #include "gpiolib-acpi.h" |
| 23 | 23 | |
| 24 | +#define QUIRK_NO_EDGE_EVENTS_ON_BOOT 0x01l | |
| 25 | +#define QUIRK_NO_WAKEUP 0x02l | |
| 26 | + | |
| 24 | 27 | static int run_edge_events_on_boot = -1; |
| 25 | 28 | module_param(run_edge_events_on_boot, int, 0444); |
| 26 | 29 | MODULE_PARM_DESC(run_edge_events_on_boot, |
| 27 | 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 | 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 | 289 | event->handle = evt_handle; |
| 282 | 290 | event->handler = handler; |
| 283 | 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 | 293 | event->pin = pin; |
| 286 | 294 | event->desc = desc; |
| 287 | 295 | |
| @@ -1309,7 +1317,7 @@ static int acpi_gpio_handle_deferred_request_irqs(void) · 1021 unmodified lines | ||
| 1309 | 1317 | /* We must use _sync so that this runs after the first deferred_probe run */ |
| 1310 | 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 | 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 | 1327 | .matches = { |
| 1320 | 1328 | DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), |
| 1321 | 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 | 1340 | .matches = { |
| 1332 | 1341 | DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), |
| 1333 | 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 | 1363 | {} /* Terminating entry */ |
| 1337 | 1364 | }; |
| 1338 | 1365 | |
| 1339 | 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 | 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 | 1377 | run_edge_events_on_boot = 0; |
| 1344 | 1378 | else |
| 1345 | 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 | 1389 | return 0; |
| 1349 | 1390 | } |
| 1350 | 1391 | |
| @@ -220,6 +220,14 @@ int gpiod_get_direction(struct gpio_desc *desc) · 219 unmodified lines | ||
| 220 | 220 | chip = gpiod_to_chip(desc); |
| 221 | 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 | 231 | if (!chip->get_direction) |
| 224 | 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 | 4481 | if (chip->ngpio <= p->chip_hwnum) { |
| 4474 | 4482 | dev_err(dev, |
| 4475 | − "requested GPIO %d is out of range [0..%d] for chip %s\n", | |
| 4476 | − idx, chip->ngpio, chip->label); | |
| 4483 | + "requested GPIO %u (%u) is out of range [0..%u] for chip %s\n", | |
| 4484 | + idx, p->chip_hwnum, chip->ngpio - 1, | |
| 4485 | + chip->label); | |
| 4477 | 4486 | return ERR_PTR(-EINVAL); |
| 4478 | 4487 | } |
| 4479 | 4488 | |
| @@ -613,7 +613,17 @@ static bool amdgpu_atpx_detect(void) · 612 unmodified lines | ||
| 613 | 613 | bool d3_supported = false; |
| 614 | 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 | 627 | vga_count++; |
| 618 | 628 | |
| 619 | 629 | has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); |
| @@ -142,7 +142,7 @@ int amdgpu_async_gfx_ring = 1; · 141 unmodified lines | ||
| 142 | 142 | int amdgpu_mcbp = 0; |
| 143 | 143 | int amdgpu_discovery = -1; |
| 144 | 144 | int amdgpu_mes = 0; |
| 145 | −int amdgpu_noretry = 1; | |
| 145 | +int amdgpu_noretry; | |
| 146 | 146 | int amdgpu_force_asic_type = -1; |
| 147 | 147 | |
| 148 | 148 | struct amdgpu_mgpu_info mgpu_info = { |
| @@ -588,7 +588,7 @@ MODULE_PARM_DESC(mes, · 439 unmodified lines | ||
| 588 | 588 | module_param_named(mes, amdgpu_mes, int, 0444); |
| 589 | 589 | |
| 590 | 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 | 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 | 1359 | .driver_features = |
| 1360 | 1360 | DRIVER_USE_AGP | DRIVER_ATOMIC | |
| 1361 | 1361 | DRIVER_GEM | |
| 1362 | − DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ, | |
| 1362 | + DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ | | |
| 1363 | + DRIVER_SYNCOBJ_TIMELINE, | |
| 1363 | 1364 | .load = amdgpu_driver_load_kms, |
| 1364 | 1365 | .open = amdgpu_driver_open_kms, |
| 1365 | 1366 | .postclose = amdgpu_driver_postclose_kms, |
| @@ -1488,7 +1488,7 @@ out: · 1487 unmodified lines | ||
| 1488 | 1488 | |
| 1489 | 1489 | /* Start rlc autoload after psp recieved all the gfx firmware */ |
| 1490 | 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 | 1492 | ret = psp_rlc_autoload(psp); |
| 1493 | 1493 | if (ret) { |
| 1494 | 1494 | DRM_ERROR("Failed to start rlc autoload\n"); |
| @@ -292,10 +292,10 @@ enum AMDGPU_UCODE_ID { · 291 unmodified lines | ||
| 292 | 292 | AMDGPU_UCODE_ID_CP_MEC2_JT, |
| 293 | 293 | AMDGPU_UCODE_ID_CP_MES, |
| 294 | 294 | AMDGPU_UCODE_ID_CP_MES_DATA, |
| 295 | − AMDGPU_UCODE_ID_RLC_G, | |
| 296 | 295 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL, |
| 297 | 296 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM, |
| 298 | 297 | AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM, |
| 298 | + AMDGPU_UCODE_ID_RLC_G, | |
| 299 | 299 | AMDGPU_UCODE_ID_STORAGE, |
| 300 | 300 | AMDGPU_UCODE_ID_SMC, |
| 301 | 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 | 1052 | case CHIP_VEGA20: |
| 1053 | 1053 | break; |
| 1054 | 1054 | case CHIP_RAVEN: |
| 1055 | − /* Disable GFXOFF on original raven. There are combinations | |
| 1056 | − * of sbios and platforms that are not stable. | |
| 1057 | − */ | |
| 1058 | − if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)) | |
| 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)) | |
| 1055 | + if (!(adev->rev_id >= 0x8 || | |
| 1056 | + adev->pdev->device == 0x15d8) && | |
| 1057 | + (adev->pm.fw_version < 0x41e2b || /* not raven1 fresh */ | |
| 1058 | + !adev->gfx.rlc.is_rlc_v2_1)) /* without rlc save restore ucodes */ | |
| 1066 | 1059 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; |
| 1067 | 1060 | |
| 1068 | 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 | 3356 | return color_space; |
| 3357 | 3357 | } |
| 3358 | 3358 | |
| 3359 | −static void reduce_mode_colour_depth(struct dc_crtc_timing *timing_out) | |
| 3360 | −{ | |
| 3361 | − if (timing_out->display_color_depth <= COLOR_DEPTH_888) | |
| 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) | |
| 3359 | +static bool adjust_colour_depth_from_display_info( | |
| 3360 | + struct dc_crtc_timing *timing_out, | |
| 3361 | + const struct drm_display_info *info) | |
| 3369 | 3362 | { |
| 3363 | + enum dc_color_depth depth = timing_out->display_color_depth; | |
| 3370 | 3364 | int normalized_clk; |
| 3371 | − if (timing_out->display_color_depth <= COLOR_DEPTH_888) | |
| 3372 | − return; | |
| 3373 | 3365 | do { |
| 3374 | 3366 | normalized_clk = timing_out->pix_clk_100hz / 10; |
| 3375 | 3367 | /* YCbCr 4:2:0 requires additional adjustment of 1/2 */ |
| 3376 | 3368 | if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
| 3377 | 3369 | normalized_clk /= 2; |
| 3378 | 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 | 3374 | case COLOR_DEPTH_101010: |
| 3381 | 3375 | normalized_clk = (normalized_clk * 30) / 24; |
| 3382 | 3376 | break; |
| @@ -3387,14 +3381,15 @@ static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_ · 4 unmodified lines | ||
| 3387 | 3381 | normalized_clk = (normalized_clk * 48) / 24; |
| 3388 | 3382 | break; |
| 3389 | 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) | |
| 3393 | − return; | |
| 3394 | − reduce_mode_colour_depth(timing_out); | |
| 3395 | − | |
| 3396 | − } while (timing_out->display_color_depth > COLOR_DEPTH_888); | |
| 3397 | − | |
| 3387 | + if (normalized_clk <= info->max_tmds_clock) { | |
| 3388 | + timing_out->display_color_depth = depth; | |
| 3389 | + return true; | |
| 3390 | + } | |
| 3391 | + } while (--depth > COLOR_DEPTH_666); | |
| 3392 | + return false; | |
| 3398 | 3393 | } |
| 3399 | 3394 | |
| 3400 | 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 | 3470 | stream->out_transfer_func->type = TF_TYPE_PREDEFINED; |
| 3476 | 3471 | stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; |
| 3477 | − if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) | |
| 3478 | − adjust_colour_depth_from_display_info(timing_out, info); | |
| 3472 | + if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) { | |
| 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 | 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 | 866 | smu->smu_baco.platform_support = false; |
| 867 | 867 | |
| 868 | 868 | mutex_init(&smu->sensor_lock); |
| 869 | + mutex_init(&smu->metrics_lock); | |
| 869 | 870 | |
| 870 | 871 | smu->watermarks_bitmap = 0; |
| 871 | 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 | 862 | struct smu_table_context *smu_table= &smu->smu_table; |
| 863 | 863 | int ret = 0; |
| 864 | 864 | |
| 865 | + mutex_lock(&smu->metrics_lock); | |
| 865 | 866 | if (!smu_table->metrics_time || |
| 866 | 867 | time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { |
| 867 | 868 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, |
| 868 | 869 | (void *)smu_table->metrics_table, false); |
| 869 | 870 | if (ret) { |
| 870 | 871 | pr_info("Failed to export SMU metrics table!\n"); |
| 872 | + mutex_unlock(&smu->metrics_lock); | |
| 871 | 873 | return ret; |
| 872 | 874 | } |
| 873 | 875 | smu_table->metrics_time = jiffies; |
| 874 | 876 | } |
| 875 | 877 | |
| 876 | 878 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); |
| 879 | + mutex_unlock(&smu->metrics_lock); | |
| 877 | 880 | |
| 878 | 881 | return ret; |
| 879 | 882 | } |
| @@ -349,6 +349,7 @@ struct smu_context · 348 unmodified lines | ||
| 349 | 349 | const struct pptable_funcs *ppt_funcs; |
| 350 | 350 | struct mutex mutex; |
| 351 | 351 | struct mutex sensor_lock; |
| 352 | + struct mutex metrics_lock; | |
| 352 | 353 | uint64_t pool_size; |
| 353 | 354 | |
| 354 | 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 | 562 | struct smu_table_context *smu_table= &smu->smu_table; |
| 563 | 563 | int ret = 0; |
| 564 | 564 | |
| 565 | + mutex_lock(&smu->metrics_lock); | |
| 565 | 566 | if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(100))) { |
| 566 | 567 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, |
| 567 | 568 | (void *)smu_table->metrics_table, false); |
| 568 | 569 | if (ret) { |
| 569 | 570 | pr_info("Failed to export SMU metrics table!\n"); |
| 571 | + mutex_unlock(&smu->metrics_lock); | |
| 570 | 572 | return ret; |
| 571 | 573 | } |
| 572 | 574 | smu_table->metrics_time = jiffies; |
| 573 | 575 | } |
| 574 | 576 | |
| 575 | 577 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); |
| 578 | + mutex_unlock(&smu->metrics_lock); | |
| 576 | 579 | |
| 577 | 580 | return ret; |
| 578 | 581 | } |
| @@ -1678,17 +1678,20 @@ static int vega20_get_metrics_table(struct smu_context *smu, · 1677 unmodified lines | ||
| 1678 | 1678 | struct smu_table_context *smu_table= &smu->smu_table; |
| 1679 | 1679 | int ret = 0; |
| 1680 | 1680 | |
| 1681 | + mutex_lock(&smu->metrics_lock); | |
| 1681 | 1682 | if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { |
| 1682 | 1683 | ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, |
| 1683 | 1684 | (void *)smu_table->metrics_table, false); |
| 1684 | 1685 | if (ret) { |
| 1685 | 1686 | pr_info("Failed to export SMU metrics table!\n"); |
| 1687 | + mutex_unlock(&smu->metrics_lock); | |
| 1686 | 1688 | return ret; |
| 1687 | 1689 | } |
| 1688 | 1690 | smu_table->metrics_time = jiffies; |
| 1689 | 1691 | } |
| 1690 | 1692 | |
| 1691 | 1693 | memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); |
| 1694 | + mutex_unlock(&smu->metrics_lock); | |
| 1692 | 1695 | |
| 1693 | 1696 | return ret; |
| 1694 | 1697 | } |
| @@ -56,7 +56,7 @@ malidp_mw_connector_mode_valid(struct drm_connector *connector, · 55 unmodified lines | ||
| 56 | 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 | 60 | .get_modes = malidp_mw_connector_get_modes, |
| 61 | 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 | 393 | memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes); |
| 394 | 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 | 397 | buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf); |
| 398 | 398 | idx++; |
| 399 | 399 | } |
| @@ -1283,7 +1283,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, · 1282 unmodified lines | ||
| 1283 | 1283 | * Changes struct fb_var_screeninfo are currently not pushed back |
| 1284 | 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 | 1287 | var->xres > fb->width || var->yres > fb->height || |
| 1288 | 1288 | var->xres_virtual > fb->width || var->yres_virtual > fb->height) { |
| 1289 | 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 | 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 | 1317 | * drm fbdev emulation doesn't support changing the pixel format at all, |
| 1313 | 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 | 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 | 860 | glk_force_audio_cdclk(dev_priv, true); |
| 861 | 861 | |
| 862 | 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 | 876 | /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */ |
| 877 | 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 | 879 | glk_force_audio_cdclk(dev_priv, false); |
| 880 | 880 | |
| 881 | 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 | 4516 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
| 4517 | 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 | 4519 | if (old_crtc_state->master_transcoder == INVALID_TRANSCODER) |
| 4522 | 4520 | return; |
| @@ -4524,10 +4522,7 @@ static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_ · 1 unmodified line | ||
| 4524 | 4522 | DRM_DEBUG_KMS("Disabling Transcoder Port Sync on Slave Transcoder %s\n", |
| 4525 | 4523 | transcoder_name(old_crtc_state->cpu_transcoder)); |
| 4526 | 4524 | |
| 4527 | − reg = TRANS_DDI_FUNC_CTL2(old_crtc_state->cpu_transcoder); | |
| 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); | |
| 4525 | + I915_WRITE(TRANS_DDI_FUNC_CTL2(old_crtc_state->cpu_transcoder), 0); | |
| 4531 | 4526 | } |
| 4532 | 4527 | |
| 4533 | 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 | 15107 | return ret; |
| 15113 | 15108 | |
| 15114 | 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 | 15112 | if (!new_plane_state->base.fence) { /* implicit fencing */ |
| 15118 | 15113 | struct dma_fence *fence; |
| @@ -229,11 +229,11 @@ static void frontbuffer_release(struct kref *ref) · 228 unmodified lines | ||
| 229 | 229 | vma->display_alignment = I915_GTT_MIN_ALIGNMENT; |
| 230 | 230 | spin_unlock(&obj->vma.lock); |
| 231 | 231 | |
| 232 | − obj->frontbuffer = NULL; | |
| 232 | + RCU_INIT_POINTER(obj->frontbuffer, NULL); | |
| 233 | 233 | spin_unlock(&to_i915(obj->base.dev)->fb_tracking.lock); |
| 234 | 234 | |
| 235 | 235 | i915_gem_object_put(obj); |
| 236 | − kfree(front); | |
| 236 | + kfree_rcu(front, rcu); | |
| 237 | 237 | } |
| 238 | 238 | |
| 239 | 239 | struct intel_frontbuffer * |
| @@ -242,11 +242,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) · 2 unmodified lines | ||
| 242 | 242 | struct drm_i915_private *i915 = to_i915(obj->base.dev); |
| 243 | 243 | struct intel_frontbuffer *front; |
| 244 | 244 | |
| 245 | − spin_lock(&i915->fb_tracking.lock); | |
| 246 | − front = obj->frontbuffer; | |
| 247 | − if (front) | |
| 248 | − kref_get(&front->ref); | |
| 249 | − spin_unlock(&i915->fb_tracking.lock); | |
| 245 | + front = __intel_frontbuffer_get(obj); | |
| 250 | 246 | if (front) |
| 251 | 247 | return front; |
| 252 | 248 | |
| @@ -262,13 +258,13 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) · 9 unmodified lines | ||
| 262 | 258 | i915_active_may_sleep(frontbuffer_retire)); |
| 263 | 259 | |
| 264 | 260 | spin_lock(&i915->fb_tracking.lock); |
| 265 | − if (obj->frontbuffer) { | |
| 261 | + if (rcu_access_pointer(obj->frontbuffer)) { | |
| 266 | 262 | kfree(front); |
| 267 | − front = obj->frontbuffer; | |
| 263 | + front = rcu_dereference_protected(obj->frontbuffer, true); | |
| 268 | 264 | kref_get(&front->ref); |
| 269 | 265 | } else { |
| 270 | 266 | i915_gem_object_get(obj); |
| 271 | − obj->frontbuffer = front; | |
| 267 | + rcu_assign_pointer(obj->frontbuffer, front); | |
| 272 | 268 | } |
| 273 | 269 | spin_unlock(&i915->fb_tracking.lock); |
| 274 | 270 | |
| @@ -27,10 +27,10 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/atomic.h> |
| 28 | 28 | #include <linux/kref.h> |
| 29 | 29 | |
| 30 | +#include "gem/i915_gem_object_types.h" | |
| 30 | 31 | #include "i915_active.h" |
| 31 | 32 | |
| 32 | 33 | struct drm_i915_private; |
| 33 | −struct drm_i915_gem_object; | |
| 34 | 34 | |
| 35 | 35 | enum fb_op_origin { |
| 36 | 36 | ORIGIN_GTT, |
| @@ -45,6 +45,7 @@ struct intel_frontbuffer { · 8 unmodified lines | ||
| 45 | 45 | atomic_t bits; |
| 46 | 46 | struct i915_active write; |
| 47 | 47 | struct drm_i915_gem_object *obj; |
| 48 | + struct rcu_head rcu; | |
| 48 | 49 | }; |
| 49 | 50 | |
| 50 | 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 | 55 | void intel_frontbuffer_flip(struct drm_i915_private *i915, |
| 55 | 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 | 87 | struct intel_frontbuffer * |
| 58 | 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 | 149 | struct intel_frontbuffer *new, |
| 120 | 150 | unsigned int frontbuffer_bits); |
| 121 | 151 | |
| 122 | −void intel_frontbuffer_put(struct intel_frontbuffer *front); | |
| 123 | − | |
| 124 | 152 | #endif /* __INTEL_FRONTBUFFER_H__ */ |
| @@ -279,12 +279,21 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay, · 278 unmodified lines | ||
| 279 | 279 | struct i915_vma *vma) |
| 280 | 280 | { |
| 281 | 281 | enum pipe pipe = overlay->crtc->pipe; |
| 282 | + struct intel_frontbuffer *from = NULL, *to = NULL; | |
| 282 | 283 | |
| 283 | 284 | WARN_ON(overlay->old_vma); |
| 284 | 285 | |
| 285 | − intel_frontbuffer_track(overlay->vma ? overlay->vma->obj->frontbuffer : NULL, | |
| 286 | − vma ? vma->obj->frontbuffer : NULL, | |
| 287 | − INTEL_FRONTBUFFER_OVERLAY(pipe)); | |
| 286 | + if (overlay->vma) | |
| 287 | + from = intel_frontbuffer_get(overlay->vma->obj); | |
| 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 | 298 | intel_frontbuffer_flip_prepare(overlay->i915, |
| 290 | 299 | INTEL_FRONTBUFFER_OVERLAY(pipe)); |
| @@ -766,7 +775,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, · 475 unmodified lines | ||
| 766 | 775 | ret = PTR_ERR(vma); |
| 767 | 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 | 780 | if (!overlay->active) { |
| 772 | 781 | u32 oconfig; |
| @@ -20,7 +20,8 @@ static void __do_clflush(struct drm_i915_gem_object *obj) · 19 unmodified lines | ||
| 20 | 20 | { |
| 21 | 21 | GEM_BUG_ON(!i915_gem_object_has_pages(obj)); |
| 22 | 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 | 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 | 664 | i915_gem_object_unlock(obj); |
| 665 | 665 | |
| 666 | 666 | if (write_domain) |
| 667 | − intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); | |
| 667 | + i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); | |
| 668 | 668 | |
| 669 | 669 | out_unpin: |
| 670 | 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 | 786 | out: |
| 787 | − intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); | |
| 787 | + i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); | |
| 788 | 788 | obj->mm.dirty = true; |
| 789 | 789 | /* return with the pages pinned */ |
| 790 | 790 | return 0; |
| @@ -280,7 +280,7 @@ i915_gem_object_flush_write_domain(struct drm_i915_gem_object *obj, · 279 unmodified lines | ||
| 280 | 280 | for_each_ggtt_vma(vma, obj) |
| 281 | 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 | 285 | for_each_ggtt_vma(vma, obj) { |
| 286 | 286 | if (vma->iomap) |
| @@ -308,6 +308,30 @@ i915_gem_object_flush_write_domain(struct drm_i915_gem_object *obj, · 21 unmodified lines | ||
| 308 | 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 | 335 | void i915_gem_init__objects(struct drm_i915_private *i915) |
| 312 | 336 | { |
| 313 | 337 | INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); |
| @@ -13,8 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #include <drm/i915_drm.h> |
| 15 | 15 | |
| 16 | +#include "display/intel_frontbuffer.h" | |
| 16 | 17 | #include "i915_gem_object_types.h" |
| 17 | − | |
| 18 | 18 | #include "i915_gem_gtt.h" |
| 19 | 19 | |
| 20 | 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 | 463 | unsigned int flags, |
| 464 | 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 | 487 | #endif |
| @@ -150,7 +150,7 @@ struct drm_i915_gem_object { · 149 unmodified lines | ||
| 150 | 150 | */ |
| 151 | 151 | u16 write_domain; |
| 152 | 152 | |
| 153 | − struct intel_frontbuffer *frontbuffer; | |
| 153 | + struct intel_frontbuffer __rcu *frontbuffer; | |
| 154 | 154 | |
| 155 | 155 | /** Current tiling stride for the object, if it's tiled. */ |
| 156 | 156 | unsigned int tiling_and_stride; |
| @@ -94,8 +94,9 @@ static int __gt_park(struct intel_wakeref *wf) · 93 unmodified lines | ||
| 94 | 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 | 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 | 101 | i915_globals_park(); |
| 101 | 102 | |
| @@ -4416,9 +4416,11 @@ intel_execlists_create_virtual(struct i915_gem_context *ctx, · 4415 unmodified lines | ||
| 4416 | 4416 | ve->base.gt = siblings[0]->gt; |
| 4417 | 4417 | ve->base.uncore = siblings[0]->uncore; |
| 4418 | 4418 | ve->base.id = -1; |
| 4419 | + | |
| 4419 | 4420 | ve->base.class = OTHER_CLASS; |
| 4420 | 4421 | ve->base.uabi_class = I915_ENGINE_CLASS_INVALID; |
| 4421 | 4422 | ve->base.instance = I915_ENGINE_CLASS_INVALID_VIRTUAL; |
| 4423 | + ve->base.uabi_instance = I915_ENGINE_CLASS_INVALID_VIRTUAL; | |
| 4422 | 4424 | |
| 4423 | 4425 | /* |
| 4424 | 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 | 1413 | int len; |
| 1414 | 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 | 1416 | len = 4; |
| 1425 | 1417 | if (IS_GEN(i915, 7)) |
| 1426 | 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 | 1583 | if (ce->state) { |
| 1592 | − u32 hw_flags; | |
| 1584 | + u32 flags; | |
| 1593 | 1585 | |
| 1594 | 1586 | GEM_BUG_ON(rq->engine->id != RCS0); |
| 1595 | 1587 | |
| 1596 | − /* | |
| 1597 | − * The kernel context(s) is treated as pure scratch and is not | |
| 1598 | − * expected to retain any state (as we sacrifice it during | |
| 1599 | − * suspend and on resume it may be corrupted). This is ok, | |
| 1600 | − * as nothing actually executes using the kernel context; it | |
| 1601 | − * is purely used for flushing user contexts. | |
| 1602 | − */ | |
| 1603 | − hw_flags = 0; | |
| 1604 | − if (i915_gem_context_is_kernel(rq->gem_context)) | |
| 1605 | − hw_flags = MI_RESTORE_INHIBIT; | |
| 1588 | + /* For resource streamer on HSW+ and power context elsewhere */ | |
| 1589 | + BUILD_BUG_ON(HSW_MI_RS_SAVE_STATE_EN != MI_SAVE_EXT_STATE_EN); | |
| 1590 | + BUILD_BUG_ON(HSW_MI_RS_RESTORE_STATE_EN != MI_RESTORE_EXT_STATE_EN); | |
| 1591 | + | |
| 1592 | + flags = MI_SAVE_EXT_STATE_EN | MI_MM_SPACE_GTT; | |
| 1593 | + if (!i915_gem_context_is_kernel(rq->gem_context)) | |
| 1594 | + flags |= MI_RESTORE_EXT_STATE_EN; | |
| 1595 | + else | |
| 1596 | + flags |= MI_RESTORE_INHIBIT; | |
| 1606 | 1597 | |
| 1607 | − ret = mi_set_context(rq, hw_flags); | |
| 1598 | + ret = mi_set_context(rq, flags); | |
| 1608 | 1599 | if (ret) |
| 1609 | 1600 | return ret; |
| 1610 | 1601 | } |
| @@ -1660,8 +1660,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, · 1659 unmodified lines | ||
| 1660 | 1660 | (IS_BROADWELL(dev_priv) || IS_GEN(dev_priv, 9)) |
| 1661 | 1661 | |
| 1662 | 1662 | /* WaRsDisableCoarsePowerGating:skl,cnl */ |
| 1663 | −#define NEEDS_WaRsDisableCoarsePowerGating(dev_priv) \ | |
| 1664 | − (IS_CANNONLAKE(dev_priv) || IS_GEN(dev_priv, 9)) | |
| 1663 | +#define NEEDS_WaRsDisableCoarsePowerGating(dev_priv) \ | |
| 1664 | + (IS_CANNONLAKE(dev_priv) || \ | |
| 1665 | + IS_SKL_GT3(dev_priv) || \ | |
| 1666 | + IS_SKL_GT4(dev_priv)) | |
| 1665 | 1667 | |
| 1666 | 1668 | #define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4) |
| 1667 | 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 | 161 | * We manually control the domain here and pretend that it |
| 162 | 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 | 166 | if (copy_from_user(vaddr, user_data, args->size)) |
| 167 | 167 | return -EFAULT; |
| @@ -169,7 +169,7 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, · 1 unmodified line | ||
| 169 | 169 | drm_clflush_virt_range(vaddr, args->size); |
| 170 | 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 | 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 | 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 | 594 | user_data = u64_to_user_ptr(args->data_ptr); |
| 595 | 595 | offset = args->offset; |
| @@ -631,7 +631,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, · 35 unmodified lines | ||
| 631 | 631 | user_data += page_length; |
| 632 | 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 | 636 | i915_gem_object_unlock_fence(obj, fence); |
| 637 | 637 | out_unpin: |
| @@ -721,7 +721,7 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj, · 83 unmodified lines | ||
| 721 | 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 | 725 | i915_gem_object_unlock_fence(obj, fence); |
| 726 | 726 | |
| 727 | 727 | return ret; |
| @@ -144,61 +144,40 @@ static inline s64 ktime_since(const ktime_t kt) · 143 unmodified lines | ||
| 144 | 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 | 147 | static u64 get_rc6(struct intel_gt *gt) |
| 184 | 148 | { |
| 185 | 149 | struct drm_i915_private *i915 = gt->i915; |
| 186 | 150 | struct i915_pmu *pmu = &i915->pmu; |
| 187 | 151 | unsigned long flags; |
| 152 | + bool awake = false; | |
| 188 | 153 | u64 val; |
| 189 | 154 | |
| 190 | − val = 0; | |
| 191 | 155 | if (intel_gt_pm_get_if_awake(gt)) { |
| 192 | 156 | val = __get_rc6(gt); |
| 193 | 157 | intel_gt_pm_put_async(gt); |
| 158 | + awake = true; | |
| 194 | 159 | } |
| 195 | 160 | |
| 196 | 161 | spin_lock_irqsave(&pmu->lock, flags); |
| 197 | 162 | |
| 198 | − if (val) | |
| 199 | − val = __pmu_update_rc6(pmu, val); | |
| 163 | + if (awake) { | |
| 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 | 179 | else |
| 201 | − val = __pmu_estimate_rc6(pmu); | |
| 180 | + pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = val; | |
| 202 | 181 | |
| 203 | 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 | 189 | struct i915_pmu *pmu = &i915->pmu; |
| 211 | 190 | |
| 212 | 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 | 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 | 197 | #else |
| 228 | 198 | |
| 229 | 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 | 204 | static void park_rc6(struct drm_i915_private *i915) {} |
| 235 | −static void unpark_rc6(struct drm_i915_private *i915) {} | |
| 236 | 205 | |
| 237 | 206 | #endif |
| 238 | 207 | |
| @@ -281,8 +250,6 @@ void i915_pmu_gt_unparked(struct drm_i915_private *i915) · 42 unmodified lines | ||
| 281 | 250 | */ |
| 282 | 251 | __i915_pmu_maybe_start_timer(pmu); |
| 283 | 252 | |
| 284 | − unpark_rc6(i915); | |
| 285 | − | |
| 286 | 253 | spin_unlock_irq(&pmu->lock); |
| 287 | 254 | } |
| 288 | 255 | |
| @@ -18,7 +18,7 @@ enum { · 17 unmodified lines | ||
| 18 | 18 | __I915_SAMPLE_FREQ_ACT = 0, |
| 19 | 19 | __I915_SAMPLE_FREQ_REQ, |
| 20 | 20 | __I915_SAMPLE_RC6, |
| 21 | − __I915_SAMPLE_RC6_ESTIMATED, | |
| 21 | + __I915_SAMPLE_RC6_LAST_REPORTED, | |
| 22 | 22 | __I915_NUM_PMU_SAMPLERS |
| 23 | 23 | }; |
| 24 | 24 | |
| @@ -4177,7 +4177,13 @@ enum { · 4176 unmodified lines | ||
| 4177 | 4177 | #define CPSSUNIT_CLKGATE_DIS REG_BIT(9) |
| 4178 | 4178 | |
| 4179 | 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 | 4188 | #define INF_UNIT_LEVEL_CLKGATE _MMIO(0x9560) |
| 4183 | 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 | 1104 | return err; |
| 1105 | 1105 | |
| 1106 | 1106 | if (flags & EXEC_OBJECT_WRITE) { |
| 1107 | − if (intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CS)) | |
| 1108 | − i915_active_add_request(&obj->frontbuffer->write, rq); | |
| 1107 | + struct intel_frontbuffer *front; | |
| 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 | 1116 | dma_resv_add_excl_fence(vma->resv, &rq->fence); |
| 1111 | 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 | 6565 | /* WaEnable32PlaneMode:icl */ |
| 6566 | 6566 | I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, |
| 6567 | 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 | 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 | 215 | struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); |
| 216 | 216 | struct mtk_ddp_comp *comp; |
| 217 | 217 | int i, count = 0; |
| 218 | + unsigned int local_index = plane - mtk_crtc->planes; | |
| 218 | 219 | |
| 219 | 220 | for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { |
| 220 | 221 | comp = mtk_crtc->ddp_comp[i]; |
| 221 | − if (plane->index < (count + mtk_ddp_comp_layer_nr(comp))) { | |
| 222 | − *local_layer = plane->index - count; | |
| 222 | + if (local_index < (count + mtk_ddp_comp_layer_nr(comp))) { | |
| 223 | + *local_layer = local_index - count; | |
| 223 | 224 | return comp; |
| 224 | 225 | } |
| 225 | 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 | 312 | plane_state = to_mtk_plane_state(plane->state); |
| 312 | 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 | 319 | return 0; |
| @@ -386,8 +389,9 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc) · 69 unmodified lines | ||
| 386 | 389 | comp = mtk_drm_ddp_comp_for_plane(crtc, plane, |
| 387 | 390 | &local_layer); |
| 388 | 391 | |
| 389 | − mtk_ddp_comp_layer_config(comp, local_layer, | |
| 390 | − plane_state); | |
| 392 | + if (comp) | |
| 393 | + mtk_ddp_comp_layer_config(comp, local_layer, | |
| 394 | + plane_state); | |
| 391 | 395 | plane_state->pending.config = false; |
| 392 | 396 | } |
| 393 | 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 | 405 | struct mtk_ddp_comp *comp; |
| 402 | 406 | |
| 403 | 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 | 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 | 230 | static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi) |
| 231 | 231 | { |
| 232 | 232 | u32 timcon0, timcon1, timcon2, timcon3; |
| 233 | − u32 ui, cycle_time; | |
| 233 | + u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, 1000000); | |
| 234 | 234 | struct mtk_phy_timing *timing = &dsi->phy_timing; |
| 235 | 235 | |
| 236 | − ui = DIV_ROUND_UP(1000000000, dsi->data_rate); | |
| 237 | − cycle_time = div_u64(8000000000ULL, dsi->data_rate); | |
| 236 | + timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1; | |
| 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); | |
| 240 | − timing->da_hs_prepare = NS_TO_CYCLE(50 + 5 * ui, cycle_time); | |
| 241 | − timing->da_hs_zero = NS_TO_CYCLE(110 + 6 * ui, cycle_time); | |
| 242 | − timing->da_hs_trail = NS_TO_CYCLE(77 + 4 * ui, cycle_time); | |
| 242 | + timing->ta_go = 4 * timing->lpx - 2; | |
| 243 | + timing->ta_sure = timing->lpx + 2; | |
| 244 | + timing->ta_get = 4 * timing->lpx; | |
| 245 | + timing->da_hs_exit = 2 * timing->lpx + 1; | |
| 243 | 246 | |
| 244 | − timing->ta_go = 4 * timing->lpx; | |
| 245 | − timing->ta_sure = 3 * timing->lpx / 2; | |
| 246 | − timing->ta_get = 5 * timing->lpx; | |
| 247 | − timing->da_hs_exit = 2 * timing->lpx; | |
| 248 | − | |
| 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; | |
| 247 | + timing->clk_hs_prepare = 70 * data_rate_mhz / (8 * 1000); | |
| 248 | + timing->clk_hs_post = timing->clk_hs_prepare + 8; | |
| 249 | + timing->clk_hs_trail = timing->clk_hs_prepare; | |
| 250 | + timing->clk_hs_zero = timing->clk_hs_trail * 4; | |
| 251 | + timing->clk_hs_exit = 2 * timing->clk_hs_trail; | |
| 255 | 252 | |
| 256 | 253 | timcon0 = timing->lpx | timing->da_hs_prepare << 8 | |
| 257 | 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 | 479 | dsi_tmp_buf_bpp - 10); |
| 483 | 480 | |
| 484 | 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 | 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 | 486 | data_phy_cycles * dsi->lanes + 18) { |
| 490 | − horizontal_frontporch_byte = vm->hfront_porch * | |
| 491 | − dsi_tmp_buf_bpp - | |
| 492 | − data_phy_cycles * | |
| 493 | − dsi->lanes - 18; | |
| 487 | + horizontal_frontporch_byte = | |
| 488 | + vm->hfront_porch * dsi_tmp_buf_bpp - | |
| 489 | + (data_phy_cycles * 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 | 498 | } else { |
| 495 | 499 | DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); |
| 496 | 500 | horizontal_frontporch_byte = vm->hfront_porch * |
| 497 | 501 | dsi_tmp_buf_bpp; |
| 498 | 502 | } |
| 499 | 503 | } else { |
| 500 | − if (vm->hfront_porch * dsi_tmp_buf_bpp > | |
| 504 | + if ((vm->hfront_porch + vm->hback_porch) * dsi_tmp_buf_bpp > | |
| 501 | 505 | data_phy_cycles * dsi->lanes + 12) { |
| 502 | − horizontal_frontporch_byte = vm->hfront_porch * | |
| 503 | − dsi_tmp_buf_bpp - | |
| 504 | − data_phy_cycles * | |
| 505 | − dsi->lanes - 12; | |
| 506 | + horizontal_frontporch_byte = | |
| 507 | + vm->hfront_porch * dsi_tmp_buf_bpp - | |
| 508 | + (data_phy_cycles * 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 | 515 | } else { |
| 507 | 516 | DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); |
| 508 | 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 | 685 | struct sun4i_hdmi *hdmi = dev_get_drvdata(dev); |
| 686 | 686 | |
| 687 | 687 | cec_unregister_adapter(hdmi->cec_adap); |
| 688 | − drm_connector_cleanup(&hdmi->connector); | |
| 689 | − drm_encoder_cleanup(&hdmi->encoder); | |
| 690 | 688 | i2c_del_adapter(hdmi->i2c); |
| 691 | 689 | i2c_put_adapter(hdmi->ddc_i2c); |
| 692 | 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 | 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 | 493 | tcon->dclk_max_div = 127; |
| 494 | 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 | 1426 | static const struct sun4i_tcon_quirks sun4i_a10_quirks = { |
| 1427 | 1427 | .has_channel_0 = true, |
| 1428 | 1428 | .has_channel_1 = true, |
| 1429 | + .dclk_min_div = 4, | |
| 1429 | 1430 | .set_mux = sun4i_a10_tcon_set_mux, |
| 1430 | 1431 | }; |
| 1431 | 1432 | |
| 1432 | 1433 | static const struct sun4i_tcon_quirks sun5i_a13_quirks = { |
| 1433 | 1434 | .has_channel_0 = true, |
| 1434 | 1435 | .has_channel_1 = true, |
| 1436 | + .dclk_min_div = 4, | |
| 1435 | 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 | 1442 | .has_channel_1 = true, |
| 1441 | 1443 | .has_lvds_alt = true, |
| 1442 | 1444 | .needs_de_be_mux = true, |
| 1445 | + .dclk_min_div = 1, | |
| 1443 | 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 | 1450 | .has_channel_0 = true, |
| 1448 | 1451 | .has_channel_1 = true, |
| 1449 | 1452 | .needs_de_be_mux = true, |
| 1453 | + .dclk_min_div = 1, | |
| 1450 | 1454 | }; |
| 1451 | 1455 | |
| 1452 | 1456 | static const struct sun4i_tcon_quirks sun7i_a20_quirks = { |
| 1453 | 1457 | .has_channel_0 = true, |
| 1454 | 1458 | .has_channel_1 = true, |
| 1459 | + .dclk_min_div = 4, | |
| 1455 | 1460 | /* Same display pipeline structure as A10 */ |
| 1456 | 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 | 1464 | static const struct sun4i_tcon_quirks sun8i_a33_quirks = { |
| 1460 | 1465 | .has_channel_0 = true, |
| 1461 | 1466 | .has_lvds_alt = true, |
| 1467 | + .dclk_min_div = 1, | |
| 1462 | 1468 | }; |
| 1463 | 1469 | |
| 1464 | 1470 | static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { |
| 1465 | 1471 | .supports_lvds = true, |
| 1466 | 1472 | .has_channel_0 = true, |
| 1473 | + .dclk_min_div = 1, | |
| 1467 | 1474 | }; |
| 1468 | 1475 | |
| 1469 | 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 | 1485 | static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { |
| 1479 | 1486 | .has_channel_0 = true, |
| 1487 | + .dclk_min_div = 1, | |
| 1480 | 1488 | }; |
| 1481 | 1489 | |
| 1482 | 1490 | static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = { |
| 1483 | − .has_channel_0 = true, | |
| 1484 | − .needs_edp_reset = true, | |
| 1491 | + .has_channel_0 = true, | |
| 1492 | + .needs_edp_reset = true, | |
| 1493 | + .dclk_min_div = 1, | |
| 1485 | 1494 | }; |
| 1486 | 1495 | |
| 1487 | 1496 | static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = { |
| @@ -224,6 +224,7 @@ struct sun4i_tcon_quirks { · 223 unmodified lines | ||
| 224 | 224 | bool needs_de_be_mux; /* sun6i needs mux to select backend */ |
| 225 | 225 | bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */ |
| 226 | 226 | bool supports_lvds; /* Does the TCON support an LVDS output? */ |
| 227 | + u8 dclk_min_div; /* minimum divider for TCON0 DCLK */ | |
| 227 | 228 | |
| 228 | 229 | /* callback to handle tcon muxing options */ |
| 229 | 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 | 261 | struct hid_usage *usage, __s32 value) |
| 262 | 262 | { |
| 263 | 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 | 266 | hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n", |
| 266 | 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 | 288 | offset = report->size; |
| 289 | 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 | 297 | if (!parser->local.usage_index) /* Ignore padding fields */ |
| 292 | 298 | return 0; |
| 293 | 299 | |
| @@ -631,6 +631,7 @@ · 630 unmodified lines | ||
| 631 | 631 | #define USB_VENDOR_ID_ITE 0x048d |
| 632 | 632 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 |
| 633 | 633 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 |
| 634 | +#define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a | |
| 634 | 635 | #define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 |
| 635 | 636 | #define USB_DEVICE_ID_ITE8595 0x8595 |
| 636 | 637 | |
| @@ -730,6 +731,7 @@ · 93 unmodified lines | ||
| 730 | 731 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 |
| 731 | 732 | #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 |
| 732 | 733 | #define I2C_DEVICE_ID_LG_8001 0x8001 |
| 734 | +#define I2C_DEVICE_ID_LG_7010 0x7010 | |
| 733 | 735 | |
| 734 | 736 | #define USB_VENDOR_ID_LOGITECH 0x046d |
| 735 | 737 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e |
| @@ -1102,6 +1104,7 @@ · 366 unmodified lines | ||
| 1102 | 1104 | #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 |
| 1103 | 1105 | #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 |
| 1104 | 1106 | #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 |
| 1107 | +#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968 | |
| 1105 | 1108 | #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 |
| 1106 | 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 | 1134 | mapped: |
| 1135 | − if (device->driver->input_mapped && device->driver->input_mapped(device, | |
| 1136 | − hidinput, field, usage, &bit, &max) < 0) | |
| 1137 | − goto ignore; | |
| 1135 | + if (device->driver->input_mapped && | |
| 1136 | + device->driver->input_mapped(device, hidinput, field, usage, | |
| 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 | 1145 | set_bit(usage->type, input->evbit); |
| 1140 | 1146 | |
| @@ -1215,9 +1221,11 @@ mapped: · 74 unmodified lines | ||
| 1215 | 1221 | set_bit(MSC_SCAN, input->mscbit); |
| 1216 | 1222 | } |
| 1217 | 1223 | |
| 1218 | −ignore: | |
| 1219 | 1224 | return; |
| 1220 | 1225 | |
| 1226 | +ignore: | |
| 1227 | + usage->type = 0; | |
| 1228 | + usage->code = 0; | |
| 1221 | 1229 | } |
| 1222 | 1230 | |
| 1223 | 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 | 40 | static const struct hid_device_id ite_devices[] = { |
| 41 | 41 | { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, |
| 42 | 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 | 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 | 1019 | tool = MT_TOOL_DIAL; |
| 1020 | 1020 | else if (unlikely(!confidence_state)) { |
| 1021 | 1021 | tool = MT_TOOL_PALM; |
| 1022 | − if (!active && | |
| 1022 | + if (!active && mt && | |
| 1023 | 1023 | input_mt_is_active(&mt->slots[slotnum])) { |
| 1024 | 1024 | /* |
| 1025 | 1025 | * The non-confidence was reported for |
| @@ -1985,6 +1985,9 @@ static const struct hid_device_id mt_devices[] = { · 959 unmodified lines | ||
| 1985 | 1985 | { .driver_data = MT_CLS_LG, |
| 1986 | 1986 | HID_USB_DEVICE(USB_VENDOR_ID_LG, |
| 1987 | 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 | 1992 | /* MosArt panels */ |
| 1990 | 1993 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
| @@ -174,6 +174,7 @@ static const struct hid_device_id hid_quirks[] = { · 173 unmodified lines | ||
| 174 | 174 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT }, |
| 175 | 175 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
| 176 | 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 | 179 | { 0 } |
| 179 | 180 | }; |
| @@ -768,8 +768,12 @@ static int steam_probe(struct hid_device *hdev, · 767 unmodified lines | ||
| 768 | 768 | |
| 769 | 769 | if (steam->quirks & STEAM_QUIRK_WIRELESS) { |
| 770 | 770 | hid_info(hdev, "Steam wireless receiver connected"); |
| 771 | + /* If using a wireless adaptor ask for connection status */ | |
| 772 | + steam->connected = false; | |
| 771 | 773 | steam_request_conn_status(steam); |
| 772 | 774 | } else { |
| 775 | + /* A wired connection is always present */ | |
| 776 | + steam->connected = true; | |
| 773 | 777 | ret = steam_register(steam); |
| 774 | 778 | if (ret) { |
| 775 | 779 | hid_err(hdev, |
| @@ -249,13 +249,14 @@ out: · 248 unmodified lines | ||
| 249 | 249 | static __poll_t hidraw_poll(struct file *file, poll_table *wait) |
| 250 | 250 | { |
| 251 | 251 | struct hidraw_list *list = file->private_data; |
| 252 | + __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* hidraw is always writable */ | |
| 252 | 253 | |
| 253 | 254 | poll_wait(file, &list->hidraw->wait, wait); |
| 254 | 255 | if (list->head != list->tail) |
| 255 | − return EPOLLIN | EPOLLRDNORM | EPOLLOUT; | |
| 256 | + mask |= EPOLLIN | EPOLLRDNORM; | |
| 256 | 257 | if (!list->hidraw->exist) |
| 257 | − return EPOLLERR | EPOLLHUP; | |
| 258 | − return 0; | |
| 258 | + mask |= EPOLLERR | EPOLLHUP; | |
| 259 | + return mask; | |
| 259 | 260 | } |
| 260 | 261 | |
| 261 | 262 | static int hidraw_open(struct inode *inode, struct file *file) |
| @@ -49,6 +49,8 @@ · 48 unmodified lines | ||
| 49 | 49 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) |
| 50 | 50 | #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) |
| 51 | 51 | #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) |
| 52 | +#define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6) | |
| 53 | + | |
| 52 | 54 | |
| 53 | 55 | /* flags */ |
| 54 | 56 | #define I2C_HID_STARTED 0 |
| @@ -175,6 +177,8 @@ static const struct i2c_hid_quirks { · 120 unmodified lines | ||
| 175 | 177 | I2C_HID_QUIRK_BOGUS_IRQ }, |
| 176 | 178 | { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, |
| 177 | 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 | 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 | 502 | if ((ret_size > size) || (ret_size < 2)) { |
| 499 | − dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", | |
| 500 | − __func__, size, ret_size); | |
| 501 | − return; | |
| 503 | + if (ihid->quirks & I2C_HID_QUIRK_BAD_INPUT_SIZE) { | |
| 504 | + ihid->inbuf[0] = size & 0xff; | |
| 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 | 514 | i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf); |
| @@ -24,7 +24,9 @@ · 23 unmodified lines | ||
| 24 | 24 | #define ICL_MOBILE_DEVICE_ID 0x34FC |
| 25 | 25 | #define SPT_H_DEVICE_ID 0xA135 |
| 26 | 26 | #define CML_LP_DEVICE_ID 0x02FC |
| 27 | +#define CMP_H_DEVICE_ID 0x06FC | |
| 27 | 28 | #define EHL_Ax_DEVICE_ID 0x4BB3 |
| 29 | +#define TGL_LP_DEVICE_ID 0xA0FC | |
| 28 | 30 | |
| 29 | 31 | #define REVISION_ID_CHT_A0 0x6 |
| 30 | 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 | 34 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ICL_MOBILE_DEVICE_ID)}, |
| 35 | 35 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_H_DEVICE_ID)}, |
| 36 | 36 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CML_LP_DEVICE_ID)}, |
| 37 | + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CMP_H_DEVICE_ID)}, | |
| 37 | 38 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, EHL_Ax_DEVICE_ID)}, |
| 39 | + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, TGL_LP_DEVICE_ID)}, | |
| 38 | 40 | {0, } |
| 39 | 41 | }; |
| 40 | 42 | MODULE_DEVICE_TABLE(pci, ish_pci_tbl); |
| @@ -766,13 +766,14 @@ unlock: · 765 unmodified lines | ||
| 766 | 766 | static __poll_t uhid_char_poll(struct file *file, poll_table *wait) |
| 767 | 767 | { |
| 768 | 768 | struct uhid_device *uhid = file->private_data; |
| 769 | + __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* uhid is always writable */ | |
| 769 | 770 | |
| 770 | 771 | poll_wait(file, &uhid->waitq, wait); |
| 771 | 772 | |
| 772 | 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 | 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 | 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 | 285 | * open file op |
| 246 | 286 | */ |
| 247 | 287 | static int hiddev_open(struct inode *inode, struct file *file) |
| 248 | 288 | { |
| 249 | − struct hiddev_list *list; | |
| 250 | 289 | struct usb_interface *intf; |
| 251 | 290 | struct hid_device *hid; |
| 252 | 291 | struct hiddev *hiddev; |
| @@ -255,66 +294,14 @@ static int hiddev_open(struct inode *inode, struct file *file) · 2 unmodified lines | ||
| 255 | 294 | intf = usbhid_find_interface(iminor(inode)); |
| 256 | 295 | if (!intf) |
| 257 | 296 | return -ENODEV; |
| 297 | + | |
| 258 | 298 | hid = usb_get_intfdata(intf); |
| 259 | 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 | 301 | mutex_lock(&hiddev->existancelock); |
| 287 | − /* | |
| 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: | |
| 302 | + res = hiddev->exist ? __hiddev_open(hiddev, file) : -ENODEV; | |
| 310 | 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 | 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 | 2096 | (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ |
| 2097 | 2097 | hdev->product == 0x357 || hdev->product == 0x358 || /* Intuos Pro 2 */ |
| 2098 | 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 | 2101 | value = (field->logical_maximum - value); |
| 2101 | 2102 | |
| 2102 | 2103 | if (hdev->product == 0x357 || hdev->product == 0x358 || |
| 2103 | 2104 | hdev->product == 0x392) |
| 2104 | 2105 | value = wacom_offset_rotation(input, usage, value, 3, 16); |
| 2105 | 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 | 2109 | value = wacom_offset_rotation(input, usage, value, 1, 2); |
| 2108 | 2110 | } |
| 2109 | 2111 | else { |
| @@ -174,7 +174,7 @@ static struct at91_twi_pdata sama5d2_config = { · 173 unmodified lines | ||
| 174 | 174 | |
| 175 | 175 | static struct at91_twi_pdata sam9x60_config = { |
| 176 | 176 | .clk_max_div = 7, |
| 177 | − .clk_offset = 4, | |
| 177 | + .clk_offset = 3, | |
| 178 | 178 | .has_unre_flag = true, |
| 179 | 179 | .has_alt_cmd = true, |
| 180 | 180 | .has_hold_field = true, |
| @@ -58,6 +58,7 @@ struct bcm2835_i2c_dev { · 57 unmodified lines | ||
| 58 | 58 | struct i2c_adapter adapter; |
| 59 | 59 | struct completion completion; |
| 60 | 60 | struct i2c_msg *curr_msg; |
| 61 | + struct clk *bus_clk; | |
| 61 | 62 | int num_msgs; |
| 62 | 63 | u32 msg_err; |
| 63 | 64 | u8 *msg_buf; |
| @@ -404,7 +405,6 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) · 340 unmodified lines | ||
| 404 | 405 | struct resource *mem, *irq; |
| 405 | 406 | int ret; |
| 406 | 407 | struct i2c_adapter *adap; |
| 407 | − struct clk *bus_clk; | |
| 408 | 408 | struct clk *mclk; |
| 409 | 409 | u32 bus_clk_rate; |
| 410 | 410 | |
| @@ -427,11 +427,11 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) · 16 unmodified lines | ||
| 427 | 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 | 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 | 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 | 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 | 446 | if (ret < 0) { |
| 447 | 447 | dev_err(&pdev->dev, "Could not set clock frequency\n"); |
| 448 | 448 | return ret; |
| 449 | 449 | } |
| 450 | 450 | |
| 451 | − ret = clk_prepare_enable(bus_clk); | |
| 451 | + ret = clk_prepare_enable(i2c_dev->bus_clk); | |
| 452 | 452 | if (ret) { |
| 453 | 453 | dev_err(&pdev->dev, "Couldn't prepare clock"); |
| 454 | 454 | return ret; |
| @@ -491,10 +491,9 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) · 36 unmodified lines | ||
| 491 | 491 | static int bcm2835_i2c_remove(struct platform_device *pdev) |
| 492 | 492 | { |
| 493 | 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); | |
| 497 | − clk_disable_unprepare(bus_clk); | |
| 495 | + clk_rate_exclusive_put(i2c_dev->bus_clk); | |
| 496 | + clk_disable_unprepare(i2c_dev->bus_clk); | |
| 498 | 497 | |
| 499 | 498 | free_irq(i2c_dev->irq, i2c_dev); |
| 500 | 499 | i2c_del_adapter(&i2c_dev->adapter); |
| @@ -186,10 +186,11 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap) · 185 unmodified lines | ||
| 186 | 186 | * If we can set SDA, we will always create a STOP to ensure additional |
| 187 | 187 | * pulses will do no harm. This is achieved by letting SDA follow SCL |
| 188 | 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 | 192 | bri->set_scl(adap, scl); |
| 192 | − ndelay(RECOVERY_NDELAY / 2); | |
| 193 | + ndelay(RECOVERY_NDELAY); | |
| 193 | 194 | if (bri->set_sda) |
| 194 | 195 | bri->set_sda(adap, scl); |
| 195 | 196 | ndelay(RECOVERY_NDELAY / 2); |
| @@ -211,7 +212,13 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap) · 15 unmodified lines | ||
| 211 | 212 | scl = !scl; |
| 212 | 213 | bri->set_scl(adap, scl); |
| 213 | 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 | 222 | if (bri->set_sda) |
| 216 | 223 | bri->set_sda(adap, scl); |
| 217 | 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 | 3305 | int rc; |
| 3306 | 3306 | |
| 3307 | 3307 | rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr); |
| 3308 | − if (rc) | |
| 3308 | + if (rc) { | |
| 3309 | 3309 | dev_err(rdev_to_dev(rdev), "Dereg MR failed: %#x\n", rc); |
| 3310 | + return rc; | |
| 3311 | + } | |
| 3310 | 3312 | |
| 3311 | 3313 | if (mr->pages) { |
| 3312 | 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 | 2283 | /* Add qp to flush list of the CQ */ |
| 2284 | 2284 | bnxt_qplib_add_flush_qp(qp); |
| 2285 | 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 | 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 | 2293 | cqe->status = CQ_REQ_STATUS_OK; |
| 2294 | 2294 | cqe++; |
| 2295 | 2295 | (*budget)--; |
| @@ -81,7 +81,9 @@ void iowait_init(struct iowait *wait, u32 tx_limit, · 80 unmodified lines | ||
| 81 | 81 | void iowait_cancel_work(struct iowait *w) |
| 82 | 82 | { |
| 83 | 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 | 4634 | fpsn = full_flow_psn(flow, flow->flow_state.spsn); |
| 4635 | 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 | 4645 | flow->resync_npkts += |
| 4637 | 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 | 169 | static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) |
| 170 | 170 | { |
| 171 | 171 | struct i40iw_ucontext *ucontext; |
| 172 | − u64 db_addr_offset; | |
| 173 | − u64 push_offset; | |
| 172 | + u64 db_addr_offset, push_offset, pfn; | |
| 174 | 173 | |
| 175 | 174 | ucontext = to_ucontext(context); |
| 176 | 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 | 189 | if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) { |
| 191 | 190 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| 192 | − vma->vm_private_data = ucontext; | |
| 193 | 191 | } else { |
| 194 | 192 | if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2) |
| 195 | 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 | 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, | |
| 201 | − vma->vm_pgoff + (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> PAGE_SHIFT), | |
| 202 | − PAGE_SIZE, vma->vm_page_prot)) | |
| 203 | − return -EAGAIN; | |
| 198 | + pfn = vma->vm_pgoff + | |
| 199 | + (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> | |
| 200 | + PAGE_SHIFT); | |
| 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 | 225 | client->tail = (client->head - 2) & (client->bufsize - 1); |
| 226 | 226 | |
| 227 | − client->buffer[client->tail].input_event_sec = | |
| 228 | − event->input_event_sec; | |
| 229 | − client->buffer[client->tail].input_event_usec = | |
| 230 | − event->input_event_usec; | |
| 231 | − client->buffer[client->tail].type = EV_SYN; | |
| 232 | − client->buffer[client->tail].code = SYN_DROPPED; | |
| 233 | − client->buffer[client->tail].value = 0; | |
| 227 | + client->buffer[client->tail] = (struct input_event) { | |
| 228 | + .input_event_sec = event->input_event_sec, | |
| 229 | + .input_event_usec = event->input_event_usec, | |
| 230 | + .type = EV_SYN, | |
| 231 | + .code = SYN_DROPPED, | |
| 232 | + .value = 0, | |
| 233 | + }; | |
| 234 | 234 | |
| 235 | 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); | |
| 882 | − __set_bit(ke->keycode, dev->keybit); | |
| 883 | − | |
| 884 | − for (i = 0; i < dev->keycodemax; i++) { | |
| 885 | − if (input_fetch_keycode(dev, i) == *old_keycode) { | |
| 886 | − __set_bit(*old_keycode, dev->keybit); | |
| 887 | − break; /* Setting the bit twice is useless, so break */ | |
| 881 | + if (*old_keycode <= KEY_MAX) { | |
| 882 | + __clear_bit(*old_keycode, dev->keybit); | |
| 883 | + for (i = 0; i < dev->keycodemax; i++) { | |
| 884 | + if (input_fetch_keycode(dev, i) == *old_keycode) { | |
| 885 | + __set_bit(*old_keycode, dev->keybit); | |
| 886 | + /* 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 | 893 | return 0; |
| 892 | 894 | } |
| 893 | 895 | |
| @@ -943,9 +945,13 @@ int input_set_keycode(struct input_dev *dev, · 49 unmodified lines | ||
| 943 | 945 | * Simulate keyup event if keycode is not present |
| 944 | 946 | * in the keymap anymore |
| 945 | 947 | */ |
| 946 | − if (test_bit(EV_KEY, dev->evbit) && | |
| 947 | − !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && | |
| 948 | − __test_and_clear_bit(old_keycode, dev->key)) { | |
| 948 | + if (old_keycode > KEY_MAX) { | |
| 949 | + dev_warn(dev->dev.parent ?: &dev->dev, | |
| 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 | 955 | struct input_value vals[] = { |
| 950 | 956 | { EV_KEY, old_keycode, 0 }, |
| 951 | 957 | input_value_sync |
| @@ -78,7 +78,13 @@ static void imx_sc_check_for_events(struct work_struct *work) · 77 unmodified lines | ||
| 78 | 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 | 89 | if (state ^ priv->keystate) { |
| 84 | 90 | priv->keystate = state; |
| @@ -74,12 +74,16 @@ static int uinput_dev_event(struct input_dev *dev, · 73 unmodified lines | ||
| 74 | 74 | struct uinput_device *udev = input_get_drvdata(dev); |
| 75 | 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 | 77 | ktime_get_ts64(&ts); |
| 81 | − udev->buff[udev->head].input_event_sec = ts.tv_sec; | |
| 82 | − udev->buff[udev->head].input_event_usec = ts.tv_nsec / NSEC_PER_USEC; | |
| 78 | + | |
| 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 | 87 | udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE; |
| 84 | 88 | |
| 85 | 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 | 693 | static __poll_t uinput_poll(struct file *file, poll_table *wait) |
| 690 | 694 | { |
| 691 | 695 | struct uinput_device *udev = file->private_data; |
| 696 | + __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* uinput is always writable */ | |
| 692 | 697 | |
| 693 | 698 | poll_wait(file, &udev->waitq, wait); |
| 694 | 699 | |
| 695 | 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 | 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 | 1204 | struct device *dev = msi_desc_to_dev(desc); |
| 1205 | 1205 | struct iommu_domain *domain = iommu_get_domain_for_dev(dev); |
| 1206 | − struct iommu_dma_cookie *cookie; | |
| 1207 | 1206 | struct iommu_dma_msi_page *msi_page; |
| 1208 | 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 | 1211 | return 0; |
| 1213 | 1212 | } |
| 1214 | 1213 | |
| 1215 | − cookie = domain->iova_cookie; | |
| 1216 | − | |
| 1217 | 1214 | /* |
| 1218 | 1215 | * In fact the whole prepare operation should already be serialised by |
| 1219 | 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 | 5625 | group = iommu_group_get_for_dev(dev); |
| 5626 | 5626 | |
| 5627 | − if (IS_ERR(group)) | |
| 5628 | − return PTR_ERR(group); | |
| 5627 | + if (IS_ERR(group)) { | |
| 5628 | + ret = PTR_ERR(group); | |
| 5629 | + goto unlink; | |
| 5630 | + } | |
| 5629 | 5631 | |
| 5630 | 5632 | iommu_group_put(group); |
| 5631 | 5633 | |
| @@ -5651,7 +5653,8 @@ static int intel_iommu_add_device(struct device *dev) · 19 unmodified lines | ||
| 5651 | 5653 | if (!get_private_domain_for_dev(dev)) { |
| 5652 | 5654 | dev_warn(dev, |
| 5653 | 5655 | "Failed to get a private domain.\n"); |
| 5654 | − return -ENOMEM; | |
| 5656 | + ret = -ENOMEM; | |
| 5657 | + goto unlink; | |
| 5655 | 5658 | } |
| 5656 | 5659 | |
| 5657 | 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 | 5671 | return 0; |
| 5672 | + | |
| 5673 | +unlink: | |
| 5674 | + iommu_device_unlink(&iommu->iommu, dev); | |
| 5675 | + return ret; | |
| 5669 | 5676 | } |
| 5670 | 5677 | |
| 5671 | 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 | 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 | 5834 | #ifdef CONFIG_INTEL_IOMMU_SVM |
| 5821 | 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 | 6003 | .get_resv_regions = intel_iommu_get_resv_regions, |
| 5990 | 6004 | .put_resv_regions = intel_iommu_put_resv_regions, |
| 5991 | 6005 | .apply_resv_region = intel_iommu_apply_resv_region, |
| 5992 | − .device_group = pci_device_group, | |
| 6006 | + .device_group = intel_iommu_device_group, | |
| 5993 | 6007 | .dev_has_feat = intel_iommu_dev_has_feat, |
| 5994 | 6008 | .dev_feat_enabled = intel_iommu_dev_feat_enabled, |
| 5995 | 6009 | .dev_enable_feat = intel_iommu_dev_enable_feat, |
| @@ -751,6 +751,7 @@ err_put_group: · 750 unmodified lines | ||
| 751 | 751 | mutex_unlock(&group->mutex); |
| 752 | 752 | dev->iommu_group = NULL; |
| 753 | 753 | kobject_put(group->devices_kobj); |
| 754 | + sysfs_remove_link(group->devices_kobj, device->name); | |
| 754 | 755 | err_free_name: |
| 755 | 756 | kfree(device->name); |
| 756 | 757 | err_remove_link: |
| @@ -256,7 +256,7 @@ static int __init plic_init(struct device_node *node, · 255 unmodified lines | ||
| 256 | 256 | * Skip contexts other than external interrupts for our |
| 257 | 257 | * privilege level. |
| 258 | 258 | */ |
| 259 | − if (parent.args[0] != IRQ_EXT) | |
| 259 | + if (parent.args[0] != RV_IRQ_EXT) | |
| 260 | 260 | continue; |
| 261 | 261 | |
| 262 | 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 | 380 | } else { |
| 381 | 381 | list_del_init(&data->list); |
| 382 | 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 | 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 | 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 | 465 | bool timeout = false; |
| 457 | 466 | u8 attempts; |
| 458 | 467 | |
| 459 | − if (adap->transmitting) { | |
| 468 | + if (adap->transmit_in_progress) { | |
| 460 | 469 | int err; |
| 461 | 470 | |
| 462 | 471 | /* |
| @@ -491,7 +500,7 @@ int cec_thread_func(void *_adap) · 28 unmodified lines | ||
| 491 | 500 | goto unlock; |
| 492 | 501 | } |
| 493 | 502 | |
| 494 | − if (adap->transmitting && timeout) { | |
| 503 | + if (adap->transmit_in_progress && timeout) { | |
| 495 | 504 | /* |
| 496 | 505 | * If we timeout, then log that. Normally this does |
| 497 | 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 | 509 | * so much traffic on the bus that the adapter was |
| 501 | 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, | |
| 504 | − adap->transmitting->msg.len, | |
| 505 | − adap->transmitting->msg.msg); | |
| 512 | + if (adap->transmitting) { | |
| 513 | + pr_warn("cec-%s: message %*ph timed out\n", adap->name, | |
| 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 | 522 | adap->transmit_in_progress = false; |
| 507 | 523 | adap->tx_timeouts++; |
| 508 | − /* Just give up on this. */ | |
| 509 | − cec_data_cancel(adap->transmitting, | |
| 510 | − CEC_TX_STATUS_TIMEOUT); | |
| 511 | 524 | goto unlock; |
| 512 | 525 | } |
| 513 | 526 | |
| @@ -522,7 +535,8 @@ int cec_thread_func(void *_adap) · 8 unmodified lines | ||
| 522 | 535 | data = list_first_entry(&adap->transmit_queue, |
| 523 | 536 | struct cec_data, list); |
| 524 | 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 | 541 | /* Make this the current transmitting message */ |
| 528 | 542 | adap->transmitting = data; |
| @@ -1085,11 +1099,11 @@ void cec_received_msg_ts(struct cec_adapter *adap, · 556 unmodified lines | ||
| 1085 | 1099 | valid_la = false; |
| 1086 | 1100 | else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) |
| 1087 | 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 | 1103 | valid_la = false; |
| 1090 | 1104 | else if (cec_msg_is_broadcast(msg) && |
| 1091 | − adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && | |
| 1092 | − !(dir_fl & BCAST2_0)) | |
| 1105 | + adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0 && | |
| 1106 | + !(dir_fl & BCAST1_4)) | |
| 1093 | 1107 | valid_la = false; |
| 1094 | 1108 | } |
| 1095 | 1109 | if (valid_la && min_len) { |
| @@ -116,6 +116,7 @@ struct pulse8 { · 115 unmodified lines | ||
| 116 | 116 | unsigned int vers; |
| 117 | 117 | struct completion cmd_done; |
| 118 | 118 | struct work_struct work; |
| 119 | + u8 work_result; | |
| 119 | 120 | struct delayed_work ping_eeprom_work; |
| 120 | 121 | struct cec_msg rx_msg; |
| 121 | 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 | 139 | struct pulse8 *pulse8 = |
| 139 | 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 | 145 | case MSGCODE_FRAME_DATA: |
| 143 | 146 | cec_received_msg(pulse8->adap, &pulse8->rx_msg); |
| 144 | 147 | break; |
| @@ -172,12 +175,12 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, · 27 unmodified lines | ||
| 172 | 175 | pulse8->escape = false; |
| 173 | 176 | } else if (data == MSGEND) { |
| 174 | 177 | struct cec_msg *msg = &pulse8->rx_msg; |
| 178 | + u8 msgcode = pulse8->buf[0]; | |
| 175 | 179 | |
| 176 | 180 | if (debug) |
| 177 | 181 | dev_info(pulse8->dev, "received: %*ph\n", |
| 178 | 182 | pulse8->idx, pulse8->buf); |
| 179 | − pulse8->data[0] = pulse8->buf[0]; | |
| 180 | − switch (pulse8->buf[0] & 0x3f) { | |
| 183 | + switch (msgcode & 0x3f) { | |
| 181 | 184 | case MSGCODE_FRAME_START: |
| 182 | 185 | msg->len = 1; |
| 183 | 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 | 189 | if (msg->len == CEC_MAX_MSG_SIZE) |
| 187 | 190 | break; |
| 188 | 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 | 195 | schedule_work(&pulse8->work); |
| 196 | + break; | |
| 197 | + } | |
| 191 | 198 | break; |
| 192 | 199 | case MSGCODE_TRANSMIT_SUCCEEDED: |
| 193 | 200 | case MSGCODE_TRANSMIT_FAILED_LINE: |
| 194 | 201 | case MSGCODE_TRANSMIT_FAILED_ACK: |
| 195 | 202 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: |
| 196 | 203 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: |
| 204 | + WARN_ON(pulse8->work_result); | |
| 205 | + pulse8->work_result = msgcode; | |
| 197 | 206 | schedule_work(&pulse8->work); |
| 198 | 207 | break; |
| 199 | 208 | case MSGCODE_HIGH_ERROR: |
| @@ -148,13 +148,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state) · 147 unmodified lines | ||
| 148 | 148 | unsigned long timeout; |
| 149 | 149 | u32 syscfg; |
| 150 | 150 | |
| 151 | − if (state == FL_RESETING || state == FL_PREPARING_ERASE || | |
| 151 | + if (state == FL_RESETTING || state == FL_PREPARING_ERASE || | |
| 152 | 152 | state == FL_VERIFYING_ERASE) { |
| 153 | 153 | int i = 21; |
| 154 | 154 | unsigned int intr_flags = ONENAND_INT_MASTER; |
| 155 | 155 | |
| 156 | 156 | switch (state) { |
| 157 | − case FL_RESETING: | |
| 157 | + case FL_RESETTING: | |
| 158 | 158 | intr_flags |= ONENAND_INT_RESET; |
| 159 | 159 | break; |
| 160 | 160 | case FL_PREPARING_ERASE: |
| @@ -328,7 +328,8 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c, · 167 unmodified lines | ||
| 328 | 328 | struct dma_async_tx_descriptor *tx; |
| 329 | 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 | 333 | if (!tx) { |
| 333 | 334 | dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n"); |
| 334 | 335 | return -EIO; |
| @@ -375,7 +376,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area, · 40 unmodified lines | ||
| 375 | 376 | * context fallback to PIO mode. |
| 376 | 377 | */ |
| 377 | 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 | 380 | goto out_copy; |
| 380 | 381 | |
| 381 | 382 | xtra = count & 3; |
| @@ -422,7 +423,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area, · 40 unmodified lines | ||
| 422 | 423 | * context fallback to PIO mode. |
| 423 | 424 | */ |
| 424 | 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 | 427 | goto out_copy; |
| 427 | 428 | |
| 428 | 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 | 529 | c->gpmc_cs, c->phys_base, c->onenand.base, |
| 529 | 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 | 534 | goto err_release_dma; |
| 533 | 535 | |
| 534 | 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 | 2854 | /* Exit OTP access mode */ |
| 2855 | 2855 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 2856 | − this->wait(mtd, FL_RESETING); | |
| 2856 | + this->wait(mtd, FL_RESETTING); | |
| 2857 | 2857 | |
| 2858 | 2858 | status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); |
| 2859 | 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 | 2925 | /* Exit OTP access mode */ |
| 2926 | 2926 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 2927 | − this->wait(mtd, FL_RESETING); | |
| 2927 | + this->wait(mtd, FL_RESETTING); | |
| 2928 | 2928 | |
| 2929 | 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 | 2969 | /* Exit OTP access mode */ |
| 2970 | 2970 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 2971 | − this->wait(mtd, FL_RESETING); | |
| 2971 | + this->wait(mtd, FL_RESETTING); | |
| 2972 | 2972 | |
| 2973 | 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 | 3009 | /* Exit OTP access mode */ |
| 3010 | 3010 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 3011 | − this->wait(mtd, FL_RESETING); | |
| 3011 | + this->wait(mtd, FL_RESETTING); | |
| 3012 | 3012 | } else { |
| 3013 | 3013 | ops.mode = MTD_OPS_PLACE_OOB; |
| 3014 | 3014 | ops.ooblen = len; |
| @@ -3413,7 +3413,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd) · 398 unmodified lines | ||
| 3413 | 3413 | this->boundary[die] = bdry & FLEXONENAND_PI_MASK; |
| 3414 | 3414 | |
| 3415 | 3415 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
| 3416 | − this->wait(mtd, FL_RESETING); | |
| 3416 | + this->wait(mtd, FL_RESETTING); | |
| 3417 | 3417 | |
| 3418 | 3418 | printk(KERN_INFO "Die %d boundary: %d%s\n", die, |
| 3419 | 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 | 3635 | ret = this->wait(mtd, FL_WRITING); |
| 3636 | 3636 | out: |
| 3637 | 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 | 3639 | if (!ret) |
| 3640 | 3640 | /* Recalculate device size on boundary change*/ |
| 3641 | 3641 | flexonenand_get_size(mtd); |
| @@ -3671,7 +3671,7 @@ static int onenand_chip_probe(struct mtd_info *mtd) · 29 unmodified lines | ||
| 3671 | 3671 | /* Reset OneNAND to read default register values */ |
| 3672 | 3672 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM); |
| 3673 | 3673 | /* Wait reset */ |
| 3674 | − this->wait(mtd, FL_RESETING); | |
| 3674 | + this->wait(mtd, FL_RESETTING); | |
| 3675 | 3675 | |
| 3676 | 3676 | /* Restore system configuration 1 */ |
| 3677 | 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 | 675 | normal: |
| 676 | 676 | if (count != mtd->writesize) { |
| 677 | 677 | /* Copy the bufferram to memory to prevent unaligned access */ |
| 678 | − memcpy(this->page_buf, p, mtd->writesize); | |
| 679 | − p = this->page_buf + offset; | |
| 678 | + memcpy_fromio(this->page_buf, p, mtd->writesize); | |
| 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 | 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 | 914 | /* Prepare CDMA descriptor. */ |
| 915 | 915 | static void |
| 916 | 916 | cadence_nand_cdma_desc_prepare(struct cdns_nand_ctrl *cdns_ctrl, |
| 917 | − char nf_mem, u32 flash_ptr, char *mem_ptr, | |
| 918 | − char *ctrl_data_ptr, u16 ctype) | |
| 917 | + char nf_mem, u32 flash_ptr, dma_addr_t mem_ptr, | |
| 918 | + dma_addr_t ctrl_data_ptr, u16 ctype) | |
| 919 | 919 | { |
| 920 | 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 | 931 | cdma_desc->command_flags |= CDMA_CF_DMA_MASTER; |
| 932 | 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 | 935 | cdma_desc->status = 0; |
| 936 | 936 | cdma_desc->sync_flag_pointer = 0; |
| 937 | 937 | cdma_desc->sync_arguments = 0; |
| 938 | 938 | |
| 939 | 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 | 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 | 1282 | cadence_nand_cdma_desc_prepare(cdns_ctrl, chip_nr, page, |
| 1283 | − (void *)dma_buf, (void *)dma_ctrl_dat, | |
| 1284 | − ctype); | |
| 1283 | + dma_buf, dma_ctrl_dat, ctype); | |
| 1285 | 1284 | |
| 1286 | 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 | 1360 | cadence_nand_cdma_desc_prepare(cdns_ctrl, |
| 1362 | 1361 | cdns_chip->cs[chip->cur_cs], |
| 1363 | − page, NULL, NULL, | |
| 1362 | + page, 0, 0, | |
| 1364 | 1363 | CDMA_CT_ERASE); |
| 1365 | 1364 | status = cadence_nand_cdma_send_and_wait(cdns_ctrl, thread_nr); |
| 1366 | 1365 | if (status) { |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | /* Max ECC buffer length */ |
| 38 | 38 | #define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG) |
| 39 | 39 | |
| 40 | +#define FMC2_TIMEOUT_US 1000 | |
| 40 | 41 | #define FMC2_TIMEOUT_MS 1000 |
| 41 | 42 | |
| 42 | 43 | /* Timings */ |
| @@ -53,6 +54,8 @@ · 10 unmodified lines | ||
| 53 | 54 | #define FMC2_PMEM 0x88 |
| 54 | 55 | #define FMC2_PATT 0x8c |
| 55 | 56 | #define FMC2_HECCR 0x94 |
| 57 | +#define FMC2_ISR 0x184 | |
| 58 | +#define FMC2_ICR 0x188 | |
| 56 | 59 | #define FMC2_CSQCR 0x200 |
| 57 | 60 | #define FMC2_CSQCFGR1 0x204 |
| 58 | 61 | #define FMC2_CSQCFGR2 0x208 |
| @@ -118,6 +121,12 @@ · 59 unmodified lines | ||
| 118 | 121 | #define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24) |
| 119 | 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 | 130 | /* Register: FMC2_CSQCR */ |
| 122 | 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 | 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 | 1359 | static int stm32_fmc2_exec_op(struct nand_chip *chip, |
| 1326 | 1360 | const struct nand_operation *op, |
| 1327 | 1361 | bool check_only) |
| @@ -1366,8 +1400,8 @@ static int stm32_fmc2_exec_op(struct nand_chip *chip, · 38 unmodified lines | ||
| 1366 | 1400 | break; |
| 1367 | 1401 | |
| 1368 | 1402 | case NAND_OP_WAITRDY_INSTR: |
| 1369 | − ret = nand_soft_waitrdy(chip, | |
| 1370 | − instr->ctx.waitrdy.timeout_ms); | |
| 1403 | + ret = stm32_fmc2_waitrdy(chip, | |
| 1404 | + instr->ctx.waitrdy.timeout_ms); | |
| 1371 | 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 | 248 | /* FTL can contain -1 entries that are by default filled with bits */ |
| 249 | 249 | if (block == -1) { |
| 250 | − memset(buffer, 0xFF, SM_SECTOR_SIZE); | |
| 250 | + if (buffer) | |
| 251 | + memset(buffer, 0xFF, SM_SECTOR_SIZE); | |
| 251 | 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 | 4596 | static void st_micron_set_default_init(struct spi_nor *nor) |
| 4597 | 4597 | { |
| 4598 | 4598 | nor->flags |= SNOR_F_HAS_LOCK; |
| 4599 | + nor->flags &= ~SNOR_F_HAS_16BIT_SR; | |
| 4599 | 4600 | nor->params.quad_enable = NULL; |
| 4600 | 4601 | nor->params.set_4byte = st_micron_set_4byte; |
| 4601 | 4602 | } |
| @@ -102,6 +102,7 @@ · 101 unmodified lines | ||
| 102 | 102 | #define TCAN4X5X_MODE_NORMAL BIT(7) |
| 103 | 103 | |
| 104 | 104 | #define TCAN4X5X_DISABLE_WAKE_MSK (BIT(31) | BIT(30)) |
| 105 | +#define TCAN4X5X_DISABLE_INH_MSK BIT(9) | |
| 105 | 106 | |
| 106 | 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 | 192 | static int regmap_spi_gather_write(void *context, const void *reg, |
| 170 | 193 | size_t reg_len, const void *val, |
| 171 | 194 | size_t val_len) |
| @@ -348,14 +371,23 @@ static int tcan4x5x_disable_wake(struct m_can_classdev *cdev) · 176 unmodified lines | ||
| 348 | 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 | 382 | static int tcan4x5x_parse_config(struct m_can_classdev *cdev) |
| 352 | 383 | { |
| 353 | 384 | struct tcan4x5x_priv *tcan4x5x = cdev->device_data; |
| 385 | + int ret; | |
| 354 | 386 | |
| 355 | 387 | tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake", |
| 356 | 388 | GPIOD_OUT_HIGH); |
| 357 | 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 | 391 | return -EPROBE_DEFER; |
| 360 | 392 | |
| 361 | 393 | tcan4x5x_disable_wake(cdev); |
| @@ -366,18 +398,17 @@ static int tcan4x5x_parse_config(struct m_can_classdev *cdev) · 4 unmodified lines | ||
| 366 | 398 | if (IS_ERR(tcan4x5x->reset_gpio)) |
| 367 | 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 | 405 | tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev, |
| 372 | 406 | "device-state", |
| 373 | 407 | GPIOD_IN); |
| 374 | − if (IS_ERR(tcan4x5x->device_state_gpio)) | |
| 408 | + if (IS_ERR(tcan4x5x->device_state_gpio)) { | |
| 375 | 409 | tcan4x5x->device_state_gpio = NULL; |
| 376 | − | |
| 377 | − tcan4x5x->power = devm_regulator_get_optional(cdev->dev, | |
| 378 | − "vsup"); | |
| 379 | − if (PTR_ERR(tcan4x5x->power) == -EPROBE_DEFER) | |
| 380 | − return -EPROBE_DEFER; | |
| 410 | + tcan4x5x_disable_state(cdev); | |
| 411 | + } | |
| 381 | 412 | |
| 382 | 413 | return 0; |
| 383 | 414 | } |
| @@ -412,6 +443,12 @@ static int tcan4x5x_can_probe(struct spi_device *spi) · 28 unmodified lines | ||
| 412 | 443 | if (!priv) |
| 413 | 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 | 452 | mcan_class->device_data = priv; |
| 416 | 453 | |
| 417 | 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 | 488 | priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus, |
| 452 | 489 | &spi->dev, &tcan4x5x_regmap); |
| 453 | 490 | |
| 454 | − ret = tcan4x5x_parse_config(mcan_class); | |
| 491 | + ret = tcan4x5x_power_enable(priv->power, 1); | |
| 455 | 492 | if (ret) |
| 456 | 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 | 503 | ret = m_can_class_register(mcan_class); |
| 461 | 504 | if (ret) |
| @@ -381,13 +381,12 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota) · 380 unmodified lines | ||
| 381 | 381 | struct net_device *dev = napi->dev; |
| 382 | 382 | struct mscan_regs __iomem *regs = priv->reg_base; |
| 383 | 383 | struct net_device_stats *stats = &dev->stats; |
| 384 | − int npackets = 0; | |
| 385 | − int ret = 1; | |
| 384 | + int work_done = 0; | |
| 386 | 385 | struct sk_buff *skb; |
| 387 | 386 | struct can_frame *frame; |
| 388 | 387 | u8 canrflg; |
| 389 | 388 | |
| 390 | − while (npackets < quota) { | |
| 389 | + while (work_done < quota) { | |
| 391 | 390 | canrflg = in_8(®s->canrflg); |
| 392 | 391 | if (!(canrflg & (MSCAN_RXF | MSCAN_ERR_IF))) |
| 393 | 392 | break; |
| @@ -408,18 +407,18 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota) · 14 unmodified lines | ||
| 408 | 407 | |
| 409 | 408 | stats->rx_packets++; |
| 410 | 409 | stats->rx_bytes += frame->can_dlc; |
| 411 | − npackets++; | |
| 410 | + work_done++; | |
| 412 | 411 | netif_receive_skb(skb); |
| 413 | 412 | } |
| 414 | 413 | |
| 415 | − if (!(in_8(®s->canrflg) & (MSCAN_RXF | MSCAN_ERR_IF))) { | |
| 416 | − napi_complete(&priv->napi); | |
| 417 | − clear_bit(F_RX_PROGRESS, &priv->flags); | |
| 418 | − if (priv->can.state < CAN_STATE_BUS_OFF) | |
| 419 | − out_8(®s->canrier, priv->shadow_canrier); | |
| 420 | − ret = 0; | |
| 414 | + if (work_done < quota) { | |
| 415 | + if (likely(napi_complete_done(&priv->napi, work_done))) { | |
| 416 | + clear_bit(F_RX_PROGRESS, &priv->flags); | |
| 417 | + if (priv->can.state < CAN_STATE_BUS_OFF) | |
| 418 | + out_8(®s->canrier, priv->shadow_canrier); | |
| 419 | + } | |
| 421 | 420 | } |
| 422 | − return ret; | |
| 421 | + return work_done; | |
| 423 | 422 | } |
| 424 | 423 | |
| 425 | 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 | 918 | GS_USB_BREQ_HOST_FORMAT, |
| 919 | 919 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
| 920 | 920 | 1, |
| 921 | − intf->altsetting[0].desc.bInterfaceNumber, | |
| 921 | + intf->cur_altsetting->desc.bInterfaceNumber, | |
| 922 | 922 | hconf, |
| 923 | 923 | sizeof(*hconf), |
| 924 | 924 | 1000); |
| @@ -941,7 +941,7 @@ static int gs_usb_probe(struct usb_interface *intf, · 16 unmodified lines | ||
| 941 | 941 | GS_USB_BREQ_DEVICE_CONFIG, |
| 942 | 942 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
| 943 | 943 | 1, |
| 944 | − intf->altsetting[0].desc.bInterfaceNumber, | |
| 944 | + intf->cur_altsetting->desc.bInterfaceNumber, | |
| 945 | 945 | dconf, |
| 946 | 946 | sizeof(*dconf), |
| 947 | 947 | 1000); |
| @@ -1590,7 +1590,7 @@ static int kvaser_usb_hydra_setup_endpoints(struct kvaser_usb *dev) · 1589 unmodified lines | ||
| 1590 | 1590 | struct usb_endpoint_descriptor *ep; |
| 1591 | 1591 | int i; |
| 1592 | 1592 | |
| 1593 | − iface_desc = &dev->intf->altsetting[0]; | |
| 1593 | + iface_desc = dev->intf->cur_altsetting; | |
| 1594 | 1594 | |
| 1595 | 1595 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
| 1596 | 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 | 1310 | struct usb_endpoint_descriptor *endpoint; |
| 1311 | 1311 | int i; |
| 1312 | 1312 | |
| 1313 | − iface_desc = &dev->intf->altsetting[0]; | |
| 1313 | + iface_desc = dev->intf->cur_altsetting; | |
| 1314 | 1314 | |
| 1315 | 1315 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
| 1316 | 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 | 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 | 363 | /* Locate the first rule available */ |
| 364 | 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 | 570 | if (rule->fs.flow_type != fs->flow_type || |
| 571 | 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 | 573 | continue; |
| 574 | 574 | |
| 575 | 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 | 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 | 626 | layout = &udf_tcpip6_layout; |
| 627 | 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 | 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 | 368 | return mv88e6390_g1_monitor_write(chip, ptr, port); |
| 364 | 369 | } |
| 365 | 370 | |
| @@ -211,6 +211,7 @@ · 210 unmodified lines | ||
| 211 | 211 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST 0x2000 |
| 212 | 212 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST 0x2100 |
| 213 | 213 | #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST 0x3000 |
| 214 | +#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI 0x00e0 | |
| 214 | 215 | #define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK 0x00ff |
| 215 | 216 | |
| 216 | 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 | 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 | 398 | u8 lane; |
| 399 | 399 | u16 cmode; |
| @@ -427,8 +427,8 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, · 27 unmodified lines | ||
| 427 | 427 | cmode = 0; |
| 428 | 428 | } |
| 429 | 429 | |
| 430 | − /* cmode doesn't change, nothing to do for us */ | |
| 431 | − if (cmode == chip->ports[port].cmode) | |
| 430 | + /* cmode doesn't change, nothing to do for us unless forced */ | |
| 431 | + if (cmode == chip->ports[port].cmode && !force) | |
| 432 | 432 | return 0; |
| 433 | 433 | |
| 434 | 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 | 484 | if (port != 9 && port != 10) |
| 485 | 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 | 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 | 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 | 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 | 555 | if (err) |
| 556 | 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 | 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 | 1570 | if (enabled) { |
| 1571 | 1571 | /* Enable VLAN filtering. */ |
| 1572 | − tpid = ETH_P_8021AD; | |
| 1573 | − tpid2 = ETH_P_8021Q; | |
| 1572 | + tpid = ETH_P_8021Q; | |
| 1573 | + tpid2 = ETH_P_8021AD; | |
| 1574 | 1574 | } else { |
| 1575 | 1575 | /* Disable VLAN filtering. */ |
| 1576 | 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 | 1580 | table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; |
| 1581 | 1581 | general_params = table->entries; |
| 1582 | − /* EtherType used to identify outer tagged (S-tag) VLAN traffic */ | |
| 1583 | − general_params->tpid = tpid; | |
| 1584 | 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 | 1585 | general_params->tpid2 = tpid2; |
| 1586 | 1586 | /* When VLAN filtering is on, we need to at least be able to |
| 1587 | 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 | 1855 | if (!clone) |
| 1856 | 1856 | goto out; |
| 1857 | 1857 | |
| 1858 | − sja1105_ptp_txtstamp_skb(ds, slot, clone); | |
| 1858 | + sja1105_ptp_txtstamp_skb(ds, port, clone); | |
| 1859 | 1859 | |
| 1860 | 1860 | out: |
| 1861 | 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 | 234 | if (rw == SPI_WRITE) |
| 235 | 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 | 238 | SJA1105_SIZE_PTP_CMD); |
| 239 | 239 | |
| 240 | 240 | if (rw == SPI_READ) |
| @@ -659,7 +659,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds) · 418 unmodified lines | ||
| 659 | 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 | 663 | struct sk_buff *skb) |
| 664 | 664 | { |
| 665 | 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 | 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 | 683 | if (rc < 0) { |
| 684 | 684 | dev_err(ds->dev, "timed out polling for tstamp\n"); |
| 685 | 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 | 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 | 148 | static size_t |
| 146 | 149 | sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, |
| 147 | 150 | enum packing_op op) |
| @@ -166,9 +169,9 @@ sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, · 18 unmodified lines | ||
| 166 | 169 | sja1105_packing(buf, &entry->mirr_port, 141, 139, size, op); |
| 167 | 170 | sja1105_packing(buf, &entry->vlmarker, 138, 107, size, op); |
| 168 | 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 | 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 | 175 | sja1105_packing(buf, &entry->queue_ts, 41, 41, size, op); |
| 173 | 176 | sja1105_packing(buf, &entry->egrmirrvid, 40, 29, size, op); |
| 174 | 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 | 477 | if (admin->cycle_time_extension) |
| 478 | 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 | 480 | for (i = 0; i < admin->num_entries; i++) { |
| 486 | 481 | s64 delta_ns = admin->entries[i].interval; |
| 487 | 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 | 403 | if (err < 0) |
| 404 | 404 | goto err_exit; |
| 405 | 405 | |
| 406 | + aq_nic_set_loopback(self); | |
| 407 | + | |
| 406 | 408 | err = self->aq_hw_ops->hw_start(self->aq_hw); |
| 407 | 409 | if (err < 0) |
| 408 | 410 | goto err_exit; |
| @@ -413,8 +415,6 @@ int aq_nic_start(struct aq_nic_s *self) · 4 unmodified lines | ||
| 413 | 415 | |
| 414 | 416 | INIT_WORK(&self->service_task, aq_nic_service_task); |
| 415 | 417 | |
| 416 | − aq_nic_set_loopback(self); | |
| 417 | − | |
| 418 | 418 | timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0); |
| 419 | 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 | 1525 | .rx_extract_ts = hw_atl_b0_rx_extract_ts, |
| 1526 | 1526 | .extract_hwts = hw_atl_b0_extract_hwts, |
| 1527 | 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 | 1528 | .hw_set_loopback = hw_atl_b0_set_loopback, |
| 1532 | 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 | 667 | u32 speed; |
| 668 | 668 | |
| 669 | 669 | mpi_state = hw_atl_utils_mpi_get_state(self); |
| 670 | − speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G | | |
| 671 | − FW2X_RATE_2G5 | FW2X_RATE_5G | | |
| 672 | − FW2X_RATE_10G); | |
| 670 | + speed = mpi_state >> HW_ATL_MPI_SPEED_SHIFT; | |
| 673 | 671 | |
| 674 | 672 | if (!speed) { |
| 675 | 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 | 1516 | int ethaddr_bytes = ETH_ALEN; |
| 1517 | 1517 | |
| 1518 | 1518 | memset(ppattern + offset, 0xff, magicsync); |
| 1519 | − for (j = 0; j < magicsync; j++) | |
| 1520 | − set_bit(len++, (unsigned long *) pmask); | |
| 1519 | + for (j = 0; j < magicsync; j++) { | |
| 1520 | + pmask[len >> 3] |= BIT(len & 7); | |
| 1521 | + len++; | |
| 1522 | + } | |
| 1521 | 1523 | |
| 1522 | 1524 | for (j = 0; j < B44_MAX_PATTERNS; j++) { |
| 1523 | 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 | 1531 | for (k = 0; k< ethaddr_bytes; k++) { |
| 1530 | 1532 | ppattern[offset + magicsync + |
| 1531 | 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 | 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 | 1536 | ((MAX_MAC_CREDIT_E2 - GET_NUM_VFS_PER_PATH(bp) * VF_MAC_CREDIT_CNT) / \ |
| 1537 | 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 | 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 | 1544 | func_num + GET_NUM_VFS_PER_PF(bp) * VF_VLAN_CREDIT_CNT) |
| 1542 | 1545 | |
| 1543 | 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 | 4088 | mgmt->rate = 0; |
| 4089 | 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 | 4092 | if (IS_ERR(*tx_clk)) |
| 4093 | 4093 | return PTR_ERR(*tx_clk); |
| 4094 | 4094 | |
| @@ -4416,7 +4416,6 @@ err_out_free_netdev: · 321 unmodified lines | ||
| 4416 | 4416 | |
| 4417 | 4417 | err_disable_clocks: |
| 4418 | 4418 | clk_disable_unprepare(tx_clk); |
| 4419 | − clk_unregister(tx_clk); | |
| 4420 | 4419 | clk_disable_unprepare(hclk); |
| 4421 | 4420 | clk_disable_unprepare(pclk); |
| 4422 | 4421 | clk_disable_unprepare(rx_clk); |
| @@ -4446,7 +4445,6 @@ static int macb_remove(struct platform_device *pdev) · 23 unmodified lines | ||
| 4446 | 4445 | pm_runtime_dont_use_autosuspend(&pdev->dev); |
| 4447 | 4446 | if (!pm_runtime_suspended(&pdev->dev)) { |
| 4448 | 4447 | clk_disable_unprepare(bp->tx_clk); |
| 4449 | − clk_unregister(bp->tx_clk); | |
| 4450 | 4448 | clk_disable_unprepare(bp->hclk); |
| 4451 | 4449 | clk_disable_unprepare(bp->pclk); |
| 4452 | 4450 | clk_disable_unprepare(bp->rx_clk); |
| @@ -504,6 +504,7 @@ struct link_config { · 503 unmodified lines | ||
| 504 | 504 | |
| 505 | 505 | enum cc_pause requested_fc; /* flow control user has requested */ |
| 506 | 506 | enum cc_pause fc; /* actual link flow control */ |
| 507 | + enum cc_pause advertised_fc; /* actual advertised flow control */ | |
| 507 | 508 | |
| 508 | 509 | enum cc_fec requested_fec; /* Forward Error Correction: */ |
| 509 | 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 | 807 | struct port_info *p = netdev_priv(dev); |
| 808 | 808 | |
| 809 | 809 | epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; |
| 810 | − epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0; | |
| 811 | − epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0; | |
| 810 | + epause->rx_pause = (p->link_cfg.advertised_fc & PAUSE_RX) != 0; | |
| 811 | + epause->tx_pause = (p->link_cfg.advertised_fc & PAUSE_TX) != 0; | |
| 812 | 812 | } |
| 813 | 813 | |
| 814 | 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 | 4089 | if (cc_pause & PAUSE_TX) |
| 4090 | 4090 | fw_pause |= FW_PORT_CAP32_802_3_PAUSE; |
| 4091 | 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 | 4094 | } else if (cc_pause & PAUSE_TX) { |
| 4094 | 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 | 8564 | void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) |
| 8564 | 8565 | { |
| 8565 | 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 | − struct adapter *adapter = pi->adapter; | |
| 8567 | + fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; | |
| 8568 | 8568 | struct link_config *lc = &pi->link_cfg; |
| 8569 | − int link_ok, linkdnrc; | |
| 8570 | − enum fw_port_type port_type; | |
| 8569 | + struct adapter *adapter = pi->adapter; | |
| 8570 | + unsigned int speed, fc, fec, adv_fc; | |
| 8571 | 8571 | enum fw_port_module_type mod_type; |
| 8572 | − unsigned int speed, fc, fec; | |
| 8573 | − fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; | |
| 8572 | + int action, link_ok, linkdnrc; | |
| 8573 | + enum fw_port_type port_type; | |
| 8574 | 8574 | |
| 8575 | 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 | 8578 | switch (action) { |
| 8578 | 8579 | case FW_PORT_ACTION_GET_PORT_INFO: { |
| 8579 | 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 | 8614 | fec = fwcap_to_cc_fec(acaps); |
| 8615 | + adv_fc = fwcap_to_cc_pause(acaps); | |
| 8614 | 8616 | fc = fwcap_to_cc_pause(linkattr); |
| 8615 | 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 | 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 | 8675 | if (!link_ok && lc->link_ok) { |
| 8672 | 8676 | lc->link_down_rc = linkdnrc; |
| 8673 | 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 | 8682 | lc->link_ok = link_ok; |
| 8679 | 8683 | lc->speed = speed; |
| 8684 | + lc->advertised_fc = adv_fc; | |
| 8680 | 8685 | lc->fc = fc; |
| 8681 | 8686 | lc->fec = fec; |
| 8682 | 8687 | |
| @@ -1690,8 +1690,8 @@ static void cxgb4vf_get_pauseparam(struct net_device *dev, · 1689 unmodified lines | ||
| 1690 | 1690 | struct port_info *pi = netdev_priv(dev); |
| 1691 | 1691 | |
| 1692 | 1692 | pauseparam->autoneg = (pi->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; |
| 1693 | − pauseparam->rx_pause = (pi->link_cfg.fc & PAUSE_RX) != 0; | |
| 1694 | − pauseparam->tx_pause = (pi->link_cfg.fc & PAUSE_TX) != 0; | |
| 1693 | + pauseparam->rx_pause = (pi->link_cfg.advertised_fc & PAUSE_RX) != 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 | 136 | enum cc_pause requested_fc; /* flow control user has requested */ |
| 137 | 137 | enum cc_pause fc; /* actual link flow control */ |
| 138 | + enum cc_pause advertised_fc; /* actual advertised flow control */ | |
| 138 | 139 | |
| 139 | 140 | enum cc_fec auto_fec; /* Forward Error Correction: */ |
| 140 | 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 | 1913 | static void t4vf_handle_get_port_info(struct port_info *pi, |
| 1914 | 1914 | const struct fw_port_cmd *cmd) |
| 1915 | 1915 | { |
| 1916 | − int action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); | |
| 1917 | − struct adapter *adapter = pi->adapter; | |
| 1916 | + fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; | |
| 1918 | 1917 | struct link_config *lc = &pi->link_cfg; |
| 1919 | − int link_ok, linkdnrc; | |
| 1920 | − enum fw_port_type port_type; | |
| 1918 | + struct adapter *adapter = pi->adapter; | |
| 1919 | + unsigned int speed, fc, fec, adv_fc; | |
| 1921 | 1920 | enum fw_port_module_type mod_type; |
| 1922 | − unsigned int speed, fc, fec; | |
| 1923 | − fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; | |
| 1921 | + int action, link_ok, linkdnrc; | |
| 1922 | + enum fw_port_type port_type; | |
| 1924 | 1923 | |
| 1925 | 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 | 1926 | switch (action) { |
| 1927 | 1927 | case FW_PORT_ACTION_GET_PORT_INFO: { |
| 1928 | 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 | 1984 | fec = fwcap_to_cc_fec(acaps); |
| 1985 | + adv_fc = fwcap_to_cc_pause(acaps); | |
| 1985 | 1986 | fc = fwcap_to_cc_pause(linkattr); |
| 1986 | 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 | 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 | 2019 | if (!link_ok && lc->link_ok) { |
| 2017 | 2020 | lc->link_down_rc = linkdnrc; |
| 2018 | 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 | 2026 | lc->link_ok = link_ok; |
| 2024 | 2027 | lc->speed = speed; |
| 2028 | + lc->advertised_fc = adv_fc; | |
| 2025 | 2029 | lc->fc = fc; |
| 2026 | 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 | 1719 | int page_offset; |
| 1720 | 1720 | unsigned int sz; |
| 1721 | 1721 | int *count_ptr; |
| 1722 | − int i; | |
| 1722 | + int i, j; | |
| 1723 | 1723 | |
| 1724 | 1724 | vaddr = phys_to_virt(addr); |
| 1725 | 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 | 1736 | WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr, |
| 1737 | 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 | 1742 | /* We may use multiple Rx pools */ |
| 1740 | 1743 | dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); |
| 1741 | 1744 | if (!dpaa_bp) |
| 1742 | 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 | 1747 | if (!skb) { |
| 1748 | 1748 | sz = dpaa_bp->size + |
| 1749 | 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 | 1786 | skb_add_rx_frag(skb, i - 1, head_page, frag_off, |
| 1787 | 1787 | frag_len, dpaa_bp->size); |
| 1788 | 1788 | } |
| 1789 | + | |
| 1789 | 1790 | /* Update the pool count for the current {cpu x bpool} */ |
| 1791 | + count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); | |
| 1790 | 1792 | (*count_ptr)--; |
| 1791 | 1793 | |
| 1792 | 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 | 1802 | return skb; |
| 1801 | 1803 | |
| 1802 | 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 | 1805 | /* free all the SG entries */ |
| 1812 | − for (i = 0; i < DPAA_SGT_MAX_ENTRIES ; i++) { | |
| 1813 | − sg_addr = qm_sg_addr(&sgt[i]); | |
| 1806 | + for (j = 0; j < DPAA_SGT_MAX_ENTRIES ; j++) { | |
| 1807 | + sg_addr = qm_sg_addr(&sgt[j]); | |
| 1814 | 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 | 1813 | free_pages((unsigned long)sg_vaddr, 0); |
| 1816 | − dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); | |
| 1817 | − if (dpaa_bp) { | |
| 1818 | − count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); | |
| 1819 | − (*count_ptr)--; | |
| 1814 | + /* counters 0..i-1 were decremented */ | |
| 1815 | + if (j >= i) { | |
| 1816 | + dpaa_bp = dpaa_bpid2pool(sgt[j].bpid); | |
| 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 | 1824 | break; |
| 1824 | 1825 | } |
| 1825 | 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 | 2200 | struct fec_enet_private *fep = netdev_priv(ndev); |
| 2201 | 2201 | u32 __iomem *theregs = (u32 __iomem *)fep->hwp; |
| 2202 | + struct device *dev = &fep->pdev->dev; | |
| 2202 | 2203 | u32 *buf = (u32 *)regbuf; |
| 2203 | 2204 | u32 i, off; |
| 2205 | + int ret; | |
| 2206 | + | |
| 2207 | + ret = pm_runtime_get_sync(dev); | |
| 2208 | + if (ret < 0) | |
| 2209 | + return; | |
| 2204 | 2210 | |
| 2205 | 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 | 2222 | off >>= 2; |
| 2217 | 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 | 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 | 418 | rx->cnt = cnt; |
| 419 | 419 | rx->fill_cnt += work_done; |
| 420 | 420 | |
| 421 | − /* restock desc ring slots */ | |
| 422 | − dma_wmb(); /* Ensure descs are visible before ringing doorbell */ | |
| 423 | 421 | gve_rx_write_doorbell(priv, rx); |
| 424 | 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 | 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 | 490 | gve_tx_put_doorbell(priv, tx->q_resources, tx->req); |
| 495 | 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 | 501 | if (!netif_xmit_stopped(tx->netdev_txq) && netdev_xmit_more()) |
| 506 | 502 | return NETDEV_TX_OK; |
| 507 | 503 | |
| 508 | − /* Ensure tx descs are visible before ringing doorbell */ | |
| 509 | − dma_wmb(); | |
| 510 | 504 | gve_tx_put_doorbell(priv, tx->q_resources, tx->req); |
| 511 | 505 | return NETDEV_TX_OK; |
| 512 | 506 | } |
| @@ -122,6 +122,22 @@ enum { · 121 unmodified lines | ||
| 122 | 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 | 141 | #ifdef CONFIG_MLX5_EN_RXNFC |
| 126 | 142 | |
| 127 | 143 | struct mlx5e_ethtool_table { |
| @@ -197,9 +197,10 @@ int mlx5e_health_report(struct mlx5e_priv *priv, · 196 unmodified lines | ||
| 197 | 197 | struct devlink_health_reporter *reporter, char *err_str, |
| 198 | 198 | struct mlx5e_err_ctx *err_ctx) |
| 199 | 199 | { |
| 200 | − if (!reporter) { | |
| 201 | − netdev_err(priv->netdev, err_str); | |
| 200 | + netdev_err(priv->netdev, err_str); | |
| 201 | + | |
| 202 | + if (!reporter) | |
| 202 | 203 | return err_ctx->recover(&err_ctx->ctx); |
| 203 | − } | |
| 204 | + | |
| 204 | 205 | return devlink_health_report(reporter, err_str, err_ctx); |
| 205 | 206 | } |
| @@ -904,22 +904,6 @@ del_rules: · 903 unmodified lines | ||
| 904 | 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 | 907 | static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, |
| 924 | 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 | 592 | for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) |
| 593 | 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 | 596 | ft_attr->level = MLX5E_TC_TTC_FT_LEVEL; |
| 597 | 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 | 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 | 3021 | static int mlx5e_attach_encap(struct mlx5e_priv *priv, |
| 3003 | 3022 | struct mlx5e_tc_flow *flow, |
| 3004 | 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 | 3054 | /* must verify if encap is valid or not */ |
| 3036 | 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 | 3062 | mutex_unlock(&esw->offloads.encap_tbl_lock); |
| 3038 | 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 | 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 | 3268 | static int parse_tc_fdb_actions(struct mlx5e_priv *priv, |
| 3224 | 3269 | struct flow_action *flow_action, |
| 3225 | 3270 | struct mlx5e_tc_flow *flow, |
| @@ -3231,11 +3276,12 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, · 5 unmodified lines | ||
| 3231 | 3276 | struct mlx5e_tc_flow_parse_attr *parse_attr = attr->parse_attr; |
| 3232 | 3277 | struct mlx5e_rep_priv *rpriv = priv->ppriv; |
| 3233 | 3278 | const struct ip_tunnel_info *info = NULL; |
| 3279 | + int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS]; | |
| 3234 | 3280 | bool ft_flow = mlx5e_is_ft_flow(flow); |
| 3235 | 3281 | const struct flow_action_entry *act; |
| 3282 | + int err, i, if_count = 0; | |
| 3236 | 3283 | bool encap = false; |
| 3237 | 3284 | u32 action = 0; |
| 3238 | − int err, i; | |
| 3239 | 3285 | |
| 3240 | 3286 | if (!flow_action_has_entries(flow_action)) |
| 3241 | 3287 | return -EINVAL; |
| @@ -3312,6 +3358,16 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, · 70 unmodified lines | ||
| 3312 | 3358 | struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH); |
| 3313 | 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 | 3371 | rcu_read_lock(); |
| 3316 | 3372 | uplink_upper = |
| 3317 | 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 | 534 | static void del_sw_fte(struct fs_node *node) |
| 543 | 535 | { |
| 536 | + struct mlx5_flow_steering *steering = get_steering(node); | |
| 544 | 537 | struct mlx5_flow_group *fg; |
| 545 | 538 | struct fs_fte *fte; |
| 546 | 539 | int err; |
| @@ -553,8 +546,7 @@ static void del_sw_fte(struct fs_node *node) · 6 unmodified lines | ||
| 553 | 546 | rhash_fte); |
| 554 | 547 | WARN_ON(err); |
| 555 | 548 | ida_simple_remove(&fg->fte_allocator, fte->index - fg->start_index); |
| 556 | − | |
| 557 | − call_rcu(&fte->rcu, del_sw_fte_rcu); | |
| 549 | + kmem_cache_free(steering->ftes_cache, fte); | |
| 558 | 550 | } |
| 559 | 551 | |
| 560 | 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 | 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 | 1632 | struct fs_fte *fte_tmp; |
| 1639 | 1633 | |
| 1640 | − nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); | |
| 1641 | − | |
| 1642 | − fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value, rhash_fte); | |
| 1643 | − if (!fte_tmp || !tree_get_node(&fte_tmp->node)) { | |
| 1644 | − fte_tmp = NULL; | |
| 1645 | − goto out; | |
| 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); | |
| 1634 | + if (take_write) | |
| 1635 | + nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); | |
| 1636 | + else | |
| 1637 | + nested_down_read_ref_node(&g->node, FS_LOCK_PARENT); | |
| 1638 | + fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value, | |
| 1639 | + rhash_fte); | |
| 1670 | 1640 | if (!fte_tmp || !tree_get_node(&fte_tmp->node)) { |
| 1671 | − rcu_read_unlock(); | |
| 1672 | 1641 | fte_tmp = NULL; |
| 1673 | 1642 | goto out; |
| 1674 | 1643 | } |
| 1675 | − rcu_read_unlock(); | |
| 1676 | − | |
| 1677 | 1644 | if (!fte_tmp->node.active) { |
| 1678 | 1645 | tree_put_node(&fte_tmp->node, false); |
| 1679 | 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 | 1650 | nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); |
| 1684 | − | |
| 1685 | 1651 | out: |
| 1686 | − tree_put_node(&g->node, false); | |
| 1687 | − return fte_tmp; | |
| 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); | |
| 1652 | + if (take_write) | |
| 1653 | + up_write_ref_node(&g->node, false); | |
| 1695 | 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 | 1659 | static struct mlx5_flow_handle * |
| @@ -203,7 +203,6 @@ struct fs_fte { · 202 unmodified lines | ||
| 203 | 203 | enum fs_fte_status status; |
| 204 | 204 | struct mlx5_fc *counter; |
| 205 | 205 | struct rhash_head hash; |
| 206 | − struct rcu_head rcu; | |
| 207 | 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 | 1193 | if (err) |
| 1194 | 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 | 1202 | if (mlx5_device_registered(dev)) { |
| 1197 | 1203 | mlx5_attach_device(dev); |
| 1198 | 1204 | } else { |
| @@ -1210,6 +1216,9 @@ out: · 11 unmodified lines | ||
| 1210 | 1216 | return err; |
| 1211 | 1217 | |
| 1212 | 1218 | err_reg_dev: |
| 1219 | + if (boot) | |
| 1220 | + mlx5_devlink_unregister(priv_to_devlink(dev)); | |
| 1221 | +err_devlink_reg: | |
| 1213 | 1222 | mlx5_unload(dev); |
| 1214 | 1223 | err_load: |
| 1215 | 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 | 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 | 1359 | err = mlx5_crdump_enable(dev); |
| 1355 | 1360 | if (err) |
| 1356 | 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 | 1363 | pci_save_state(pdev); |
| 1359 | 1364 | return 0; |
| 1360 | 1365 | |
| 1361 | −clean_load: | |
| 1362 | − mlx5_unload_one(dev, true); | |
| 1363 | − | |
| 1364 | 1366 | err_load_one: |
| 1365 | 1367 | mlx5_pci_close(dev); |
| 1366 | 1368 | pci_init_err: |
| @@ -209,7 +209,7 @@ static void dr_rule_rehash_copy_ste_ctrl(struct mlx5dr_matcher *matcher, · 208 unmodified lines | ||
| 209 | 209 | /* We need to copy the refcount since this ste |
| 210 | 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 | 214 | /* Link old STEs rule_mem list to the new ste */ |
| 215 | 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 | 638 | if (!rule_mem) |
| 639 | 639 | return -ENOMEM; |
| 640 | 640 | |
| 641 | + INIT_LIST_HEAD(&rule_mem->list); | |
| 642 | + INIT_LIST_HEAD(&rule_mem->use_ste_list); | |
| 643 | + | |
| 641 | 644 | rule_mem->ste = ste; |
| 642 | 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 | 348 | if (dst->next_htbl) |
| 349 | 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 | 353 | INIT_LIST_HEAD(&dst->rule_list); |
| 354 | 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 | 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 | 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 | 689 | htbl->ste_arr = chunk->ste_arr; |
| 690 | 690 | htbl->hw_ste_arr = chunk->hw_ste_arr; |
| 691 | 691 | htbl->miss_list = chunk->miss_list; |
| 692 | − refcount_set(&htbl->refcount, 0); | |
| 692 | + htbl->refcount = 0; | |
| 693 | 693 | |
| 694 | 694 | for (i = 0; i < chunk->num_of_entries; i++) { |
| 695 | 695 | struct mlx5dr_ste *ste = &htbl->ste_arr[i]; |
| 696 | 696 | |
| 697 | 697 | ste->hw_ste = htbl->hw_ste_arr + i * DR_STE_SIZE_REDUCED; |
| 698 | 698 | ste->htbl = htbl; |
| 699 | − refcount_set(&ste->refcount, 0); | |
| 699 | + ste->refcount = 0; | |
| 700 | 700 | INIT_LIST_HEAD(&ste->miss_list_node); |
| 701 | 701 | INIT_LIST_HEAD(&htbl->miss_list[i]); |
| 702 | 702 | INIT_LIST_HEAD(&ste->rule_list); |
| @@ -713,7 +713,7 @@ out_free_htbl: · 10 unmodified lines | ||
| 713 | 713 | |
| 714 | 714 | int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl) |
| 715 | 715 | { |
| 716 | − if (refcount_read(&htbl->refcount)) | |
| 716 | + if (htbl->refcount) | |
| 717 | 717 | return -EBUSY; |
| 718 | 718 | |
| 719 | 719 | mlx5dr_icm_free_chunk(htbl->chunk); |
| @@ -123,7 +123,7 @@ struct mlx5dr_matcher_rx_tx; · 122 unmodified lines | ||
| 123 | 123 | struct mlx5dr_ste { |
| 124 | 124 | u8 *hw_ste; |
| 125 | 125 | /* refcount: indicates the num of rules that using this ste */ |
| 126 | − refcount_t refcount; | |
| 126 | + u32 refcount; | |
| 127 | 127 | |
| 128 | 128 | /* attached to the miss_list head at each htbl entry */ |
| 129 | 129 | struct list_head miss_list_node; |
| @@ -155,7 +155,7 @@ struct mlx5dr_ste_htbl_ctrl { · 25 unmodified lines | ||
| 155 | 155 | struct mlx5dr_ste_htbl { |
| 156 | 156 | u8 lu_type; |
| 157 | 157 | u16 byte_mask; |
| 158 | − refcount_t refcount; | |
| 158 | + u32 refcount; | |
| 159 | 159 | struct mlx5dr_icm_chunk *chunk; |
| 160 | 160 | struct mlx5dr_ste *ste_arr; |
| 161 | 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 | 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 | 211 | mlx5dr_ste_htbl_free(htbl); |
| 211 | 212 | } |
| 212 | 213 | |
| 213 | 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 | 219 | /* STE utils */ |
| @@ -254,14 +255,15 @@ static inline void mlx5dr_ste_put(struct mlx5dr_ste *ste, · 35 unmodified lines | ||
| 254 | 255 | struct mlx5dr_matcher *matcher, |
| 255 | 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 | 260 | mlx5dr_ste_free(ste, matcher, nic_matcher); |
| 259 | 261 | } |
| 260 | 262 | |
| 261 | 263 | /* initial as 0, increased only when ste appears in a new rule */ |
| 262 | 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 | 269 | void mlx5dr_ste_set_hit_addr_by_next_htbl(u8 *hw_ste, |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/kernel.h> |
| 7 | 7 | #include <linux/module.h> |
| 8 | 8 | #include <linux/netlink.h> |
| 9 | +#include <linux/vmalloc.h> | |
| 9 | 10 | #include <linux/xz.h> |
| 10 | 11 | #include "mlxfw_mfa2.h" |
| 11 | 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 | 549 | comp_size = be32_to_cpu(comp->size); |
| 549 | 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 | 553 | if (!comp_data) |
| 553 | 554 | return ERR_PTR(-ENOMEM); |
| 554 | 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 | 571 | comp_data->comp.data = comp_data->buff + mlxfw_mfa2_comp_magic_len; |
| 571 | 572 | return &comp_data->comp; |
| 572 | 573 | err_out: |
| 573 | − kfree(comp_data); | |
| 574 | + vfree(comp_data); | |
| 574 | 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 | 580 | const struct mlxfw_mfa2_comp_data *comp_data; |
| 580 | 581 | |
| 581 | 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 | 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 | 5472 | MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR, |
| 5473 | 5473 | MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0, |
| 5474 | 5474 | MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1, |
| 5475 | + MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP, | |
| 5475 | 5476 | |
| 5476 | 5477 | __MLXSW_REG_HTGT_TRAP_GROUP_MAX, |
| 5477 | 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 | 4542 | MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false), |
| 4543 | 4543 | MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false), |
| 4544 | 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), | |
| 4546 | − MLXSW_SP_RXL_MARK(IPV6_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, VRRP, false), | |
| 4547 | 4547 | /* PKT Sample trap */ |
| 4548 | 4548 | MLXSW_RXL(mlxsw_sp_rx_listener_sample_func, PKT_SAMPLE, MIRROR_TO_CPU, |
| 4549 | 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 | 4626 | rate = 19 * 1024; |
| 4627 | 4627 | burst_size = 12; |
| 4628 | 4628 | break; |
| 4629 | + case MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP: | |
| 4630 | + rate = 360; | |
| 4631 | + burst_size = 7; | |
| 4632 | + break; | |
| 4629 | 4633 | default: |
| 4630 | 4634 | continue; |
| 4631 | 4635 | } |
| @@ -4665,6 +4669,7 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core) · 33 unmodified lines | ||
| 4665 | 4669 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF: |
| 4666 | 4670 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM: |
| 4667 | 4671 | case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0: |
| 4672 | + case MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP: | |
| 4668 | 4673 | priority = 5; |
| 4669 | 4674 | tc = 5; |
| 4670 | 4675 | break; |
| @@ -651,6 +651,13 @@ mlxsw_sp_qdisc_prio_graft(struct mlxsw_sp_port *mlxsw_sp_port, · 650 unmodified lines | ||
| 651 | 651 | mlxsw_sp_port->tclass_qdiscs[tclass_num].handle == p->child_handle) |
| 652 | 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 | 661 | /* See if the grafted qdisc is already offloaded on any tclass. If so, |
| 655 | 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 | 7080 | for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) { |
| 7081 | 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 | 7085 | if (rif && rif->dev && rif->dev != dev && |
| 7083 | 7086 | !ether_addr_equal_masked(rif->dev->dev_addr, dev_addr, |
| 7084 | 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 | 2301 | MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)"); |
| 2302 | 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 | 112 | struct device *dev = dwmac->dev; |
| 113 | 113 | const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS]; |
| 114 | 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 | 124 | clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL); |
| 117 | 125 | if (!clk_configs) |
| @@ -146,9 +154,9 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) · 28 unmodified lines | ||
| 146 | 154 | clk_configs->m250_div.reg = dwmac->regs + PRG_ETH0; |
| 147 | 155 | clk_configs->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT; |
| 148 | 156 | clk_configs->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH; |
| 149 | − clk_configs->m250_div.flags = CLK_DIVIDER_ONE_BASED | | |
| 150 | − CLK_DIVIDER_ALLOW_ZERO | | |
| 151 | − CLK_DIVIDER_ROUND_CLOSEST; | |
| 157 | + clk_configs->m250_div.table = div_table; | |
| 158 | + clk_configs->m250_div.flags = CLK_DIVIDER_ALLOW_ZERO | | |
| 159 | + CLK_DIVIDER_ROUND_CLOSEST; | |
| 152 | 160 | clk = meson8b_dwmac_register_clk(dwmac, "m250_div", &parent_name, 1, |
| 153 | 161 | &clk_divider_ops, |
| 154 | 162 | &clk_configs->m250_div.hw); |
| @@ -957,6 +957,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) · 956 unmodified lines | ||
| 957 | 957 | /* default */ |
| 958 | 958 | break; |
| 959 | 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 | 963 | reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII; |
| 961 | 964 | break; |
| 962 | 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 | 44 | * rate, which then uses the auto-reparenting feature of the |
| 45 | 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 | 48 | clk_set_rate(gmac->tx_clk, SUN7I_GMAC_GMII_RGMII_RATE); |
| 49 | 49 | clk_prepare_enable(gmac->tx_clk); |
| 50 | 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 | 106 | static irqreturn_t stmmac_interrupt(int irq, void *dev_id); |
| 107 | 107 | |
| 108 | 108 | #ifdef CONFIG_DEBUG_FS |
| 109 | +static const struct net_device_ops stmmac_netdev_ops; | |
| 109 | 110 | static void stmmac_init_fs(struct net_device *dev); |
| 110 | 111 | static void stmmac_exit_fs(struct net_device *dev); |
| 111 | 112 | #endif |
| @@ -4256,6 +4257,34 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) · 4144 unmodified lines | ||
| 4256 | 4257 | } |
| 4257 | 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 | 4288 | static void stmmac_init_fs(struct net_device *dev) |
| 4260 | 4289 | { |
| 4261 | 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 | 4299 | /* Entry to report the DMA HW features */ |
| 4271 | 4300 | debugfs_create_file("dma_cap", 0444, priv->dbgfs_dir, dev, |
| 4272 | 4301 | &stmmac_dma_cap_fops); |
| 4302 | + | |
| 4303 | + register_netdevice_notifier(&stmmac_notifier); | |
| 4273 | 4304 | } |
| 4274 | 4305 | |
| 4275 | 4306 | static void stmmac_exit_fs(struct net_device *dev) |
| 4276 | 4307 | { |
| 4277 | 4308 | struct stmmac_priv *priv = netdev_priv(dev); |
| 4278 | 4309 | |
| 4310 | + unregister_netdevice_notifier(&stmmac_notifier); | |
| 4279 | 4311 | debugfs_remove_recursive(priv->dbgfs_dir); |
| 4280 | 4312 | } |
| 4281 | 4313 | #endif /* CONFIG_DEBUG_FS */ |
| @@ -320,7 +320,7 @@ out: · 319 unmodified lines | ||
| 320 | 320 | static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, |
| 321 | 321 | struct device_node *np, struct device *dev) |
| 322 | 322 | { |
| 323 | − bool mdio = false; | |
| 323 | + bool mdio = !of_phy_is_fixed_link(np); | |
| 324 | 324 | static const struct of_device_id need_mdio_ids[] = { |
| 325 | 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 | 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 | 545 | if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) && |
| 546 | 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 | 813 | lock_sock(sock->sk); |
| 814 | 814 | if (sock->sk->sk_user_data) { |
| 815 | 815 | sk = ERR_PTR(-EBUSY); |
| 816 | − goto out_sock; | |
| 816 | + goto out_rel_sock; | |
| 817 | 817 | } |
| 818 | 818 | |
| 819 | 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 | 827 | setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg); |
| 828 | 828 | |
| 829 | −out_sock: | |
| 829 | +out_rel_sock: | |
| 830 | 830 | release_sock(sock->sk); |
| 831 | +out_sock: | |
| 831 | 832 | sockfd_put(sock); |
| 832 | 833 | return sk; |
| 833 | 834 | } |
| @@ -259,7 +259,7 @@ static void macvlan_broadcast(struct sk_buff *skb, · 258 unmodified lines | ||
| 259 | 259 | struct net_device *src, |
| 260 | 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 | 263 | const struct macvlan_dev *vlan; |
| 264 | 264 | struct sk_buff *nskb; |
| 265 | 265 | unsigned int i; |
| @@ -627,6 +627,8 @@ static struct phy_driver aqr_driver[] = { · 626 unmodified lines | ||
| 627 | 627 | .config_intr = aqr_config_intr, |
| 628 | 628 | .ack_interrupt = aqr_ack_interrupt, |
| 629 | 629 | .read_status = aqr_read_status, |
| 630 | + .suspend = aqr107_suspend, | |
| 631 | + .resume = aqr107_resume, | |
| 630 | 632 | }, |
| 631 | 633 | { |
| 632 | 634 | PHY_ID_MATCH_MODEL(PHY_ID_AQR106), |
| @@ -566,6 +566,9 @@ static int phylink_register_sfp(struct phylink *pl, · 565 unmodified lines | ||
| 566 | 566 | struct sfp_bus *bus; |
| 567 | 567 | int ret; |
| 568 | 568 | |
| 569 | + if (!fwnode) | |
| 570 | + return 0; | |
| 571 | + | |
| 569 | 572 | bus = sfp_bus_find_fwnode(fwnode); |
| 570 | 573 | if (IS_ERR(bus)) { |
| 571 | 574 | ret = PTR_ERR(bus); |
| @@ -2724,11 +2724,6 @@ static int lan78xx_stop(struct net_device *net) · 2723 unmodified lines | ||
| 2724 | 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 | 2727 | static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev, |
| 2733 | 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 | 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 | 2740 | return NULL; |
| 2741 | + } | |
| 2745 | 2742 | |
| 2746 | 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 | 2541 | ndst = &rt->dst; |
| 2542 | 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 | 2545 | ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); |
| 2546 | 2546 | err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), |
| 2547 | 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 | 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 | 2585 | ttl = ttl ? : ip6_dst_hoplimit(ndst); |
| 2586 | 2586 | skb_scrub_packet(skb, xnet); |
| 2587 | 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 | 709 | spin_lock_irqsave(&sdla_lock, flags); |
| 710 | 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 | 712 | __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); |
| 713 | 713 | SDLA_WINDOW(dev, addr); |
| 714 | 714 | pbuf->opp_flag = 1; |
| @@ -222,6 +222,8 @@ static blk_status_t nvme_error_status(u16 status) · 221 unmodified lines | ||
| 222 | 222 | case NVME_SC_CAP_EXCEEDED: |
| 223 | 223 | return BLK_STS_NOSPC; |
| 224 | 224 | case NVME_SC_LBA_RANGE: |
| 225 | + case NVME_SC_CMD_INTERRUPTED: | |
| 226 | + case NVME_SC_NS_NOT_READY: | |
| 225 | 227 | return BLK_STS_TARGET; |
| 226 | 228 | case NVME_SC_BAD_ATTRIBUTES: |
| 227 | 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 | 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 | 37 | u64 nvmet_get_log_page_offset(struct nvme_command *cmd) |
| 28 | 38 | { |
| 29 | 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 | 788 | u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10); |
| 779 | 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 | 792 | return; |
| 783 | 793 | |
| 784 | 794 | switch (cdw10 & 0xff) { |
| @@ -115,7 +115,7 @@ struct cpcap_usb_ints_state { · 114 unmodified lines | ||
| 115 | 115 | enum cpcap_gpio_mode { |
| 116 | 116 | CPCAP_DM_DP, |
| 117 | 117 | CPCAP_MDM_RX_TX, |
| 118 | − CPCAP_UNKNOWN, | |
| 118 | + CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */ | |
| 119 | 119 | CPCAP_OTG_DM_DP, |
| 120 | 120 | }; |
| 121 | 121 | |
| @@ -134,6 +134,8 @@ struct cpcap_phy_ddata { · 12 unmodified lines | ||
| 134 | 134 | struct iio_channel *id; |
| 135 | 135 | struct regulator *vusb; |
| 136 | 136 | atomic_t active; |
| 137 | + unsigned int vbus_provider:1; | |
| 138 | + unsigned int docked:1; | |
| 137 | 139 | }; |
| 138 | 140 | |
| 139 | 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 | 209 | static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata); |
| 208 | 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 | 225 | static void cpcap_usb_detect(struct work_struct *work) |
| 211 | 226 | { |
| 212 | 227 | struct cpcap_phy_ddata *ddata; |
| @@ -220,16 +235,66 @@ static void cpcap_usb_detect(struct work_struct *work) · 7 unmodified lines | ||
| 220 | 235 | if (error) |
| 221 | 236 | return; |
| 222 | 237 | |
| 223 | − if (s.id_ground) { | |
| 224 | − dev_dbg(ddata->dev, "id ground, USB host mode\n"); | |
| 238 | + vbus = cpcap_usb_vbus_valid(ddata); | |
| 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 | 270 | error = cpcap_usb_set_usb_mode(ddata); |
| 226 | 271 | if (error) |
| 227 | 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 | 293 | if (error) |
| 231 | 294 | goto out_err; |
| 232 | 295 | |
| 296 | + cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); | |
| 297 | + | |
| 233 | 298 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, |
| 234 | 299 | CPCAP_BIT_VBUSSTBY_EN | |
| 235 | 300 | CPCAP_BIT_VBUSEN_SPI, |
| @@ -248,43 +313,26 @@ static void cpcap_usb_detect(struct work_struct *work) · 12 unmodified lines | ||
| 248 | 313 | |
| 249 | 314 | vbus = cpcap_usb_vbus_valid(ddata); |
| 250 | 315 | |
| 316 | + /* Otherwise assume we're connected to a USB host */ | |
| 251 | 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 | 318 | dev_dbg(ddata->dev, "connected to USB host\n"); |
| 269 | 319 | error = cpcap_usb_set_usb_mode(ddata); |
| 270 | 320 | if (error) |
| 271 | 321 | goto out_err; |
| 272 | − error = musb_mailbox(MUSB_VBUS_VALID); | |
| 273 | − if (error) | |
| 274 | − goto out_err; | |
| 322 | + cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID); | |
| 275 | 323 | |
| 276 | 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 | 331 | /* Default to debug UART mode */ |
| 280 | 332 | error = cpcap_usb_set_uart_mode(ddata); |
| 281 | 333 | if (error) |
| 282 | 334 | goto out_err; |
| 283 | 335 | |
| 284 | − error = musb_mailbox(MUSB_VBUS_OFF); | |
| 285 | − if (error) | |
| 286 | − goto out_err; | |
| 287 | − | |
| 288 | 336 | dev_dbg(ddata->dev, "set UART mode\n"); |
| 289 | 337 | |
| 290 | 338 | return; |
| @@ -376,7 +424,8 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata) · 85 unmodified lines | ||
| 376 | 424 | { |
| 377 | 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 | 429 | if (error) |
| 381 | 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 | 452 | if (error) |
| 404 | 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 | 460 | return 0; |
| 407 | 461 | |
| 408 | 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 | 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 | 474 | if (error) |
| 420 | 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 | 489 | if (error) |
| 435 | 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 | 492 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, |
| 444 | 493 | CPCAP_BIT_PU_SPI | |
| 445 | 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 | 504 | if (error) |
| 456 | 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 | 512 | return 0; |
| 459 | 513 | |
| 460 | 514 | out_err: |
| @@ -649,9 +703,7 @@ static int cpcap_usb_phy_remove(struct platform_device *pdev) · 188 unmodified lines | ||
| 649 | 703 | if (error) |
| 650 | 704 | dev_err(ddata->dev, "could not set UART mode\n"); |
| 651 | 705 | |
| 652 | − error = musb_mailbox(MUSB_VBUS_OFF); | |
| 653 | − if (error) | |
| 654 | − dev_err(ddata->dev, "could not set mailbox\n"); | |
| 706 | + cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF); | |
| 655 | 707 | |
| 656 | 708 | usb_remove_phy(&ddata->phy); |
| 657 | 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 | 200 | struct phy_mdm6600 *ddata; |
| 201 | 201 | struct device *dev; |
| 202 | 202 | DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES); |
| 203 | − int error, i, val = 0; | |
| 203 | + int error; | |
| 204 | 204 | |
| 205 | 205 | ddata = container_of(work, struct phy_mdm6600, status_work.work); |
| 206 | 206 | dev = ddata->dev; |
| @@ -212,16 +212,11 @@ static void phy_mdm6600_status(struct work_struct *work) · 5 unmodified lines | ||
| 212 | 212 | if (error) |
| 213 | 213 | return; |
| 214 | 214 | |
| 215 | − for (i = 0; i < PHY_MDM6600_NR_STATUS_LINES; i++) { | |
| 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]; | |
| 215 | + ddata->status = values[0] & ((1 << PHY_MDM6600_NR_STATUS_LINES) - 1); | |
| 221 | 216 | |
| 222 | 217 | dev_info(dev, "modem status: %i %s\n", |
| 223 | 218 | ddata->status, |
| 224 | − phy_mdm6600_status_name[ddata->status & 7]); | |
| 219 | + phy_mdm6600_status_name[ddata->status]); | |
| 225 | 220 | complete(&ddata->ack); |
| 226 | 221 | } |
| 227 | 222 | |
| @@ -66,7 +66,7 @@ · 65 unmodified lines | ||
| 66 | 66 | /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */ |
| 67 | 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 | 70 | #define POWER_DOWN_DELAY_US_MIN 10 |
| 71 | 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 | 604 | const struct pre_pll_config *cfg = pre_pll_cfg_table; |
| 605 | 605 | |
| 606 | + rate = (rate / 1000) * 1000; | |
| 607 | + | |
| 606 | 608 | for (; cfg->pixclock != 0; cfg++) |
| 607 | 609 | if (cfg->pixclock == rate && !cfg->fracdiv) |
| 608 | 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 | 758 | const struct pre_pll_config *cfg = pre_pll_cfg_table; |
| 757 | 759 | |
| 760 | + rate = (rate / 1000) * 1000; | |
| 761 | + | |
| 758 | 762 | for (; cfg->pixclock != 0; cfg++) |
| 759 | 763 | if (cfg->pixclock == rate) |
| 760 | 764 | break; |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | config PINCTRL_LOCHNAGAR |
| 3 | 3 | tristate "Cirrus Logic Lochnagar pinctrl driver" |
| 4 | 4 | depends on MFD_LOCHNAGAR |
| 5 | + select GPIOLIB | |
| 5 | 6 | select PINMUX |
| 6 | 7 | select PINCONF |
| 7 | 8 | select GENERIC_PINCONF |
| @@ -441,6 +441,7 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc, · 440 unmodified lines | ||
| 441 | 441 | return ret; |
| 442 | 442 | |
| 443 | 443 | meson_calc_reg_and_bit(bank, pin, REG_DS, ®, &bit); |
| 444 | + bit = bit << 1; | |
| 444 | 445 | |
| 445 | 446 | ret = regmap_read(pc->reg_ds, reg, &val); |
| 446 | 447 | if (ret) |
| @@ -18,7 +18,7 @@ if MIPS_PLATFORM_DEVICES · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | config CPU_HWMON |
| 20 | 20 | tristate "Loongson-3 CPU HWMon Driver" |
| 21 | − depends on CONFIG_MACH_LOONGSON64 | |
| 21 | + depends on MACH_LOONGSON64 | |
| 22 | 22 | select HWMON |
| 23 | 23 | default y |
| 24 | 24 | help |
| @@ -1295,6 +1295,9 @@ struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv) · 1294 unmodified lines | ||
| 1295 | 1295 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 1296 | 1296 | int ret; |
| 1297 | 1297 | |
| 1298 | + if (!rapl_defaults) | |
| 1299 | + return ERR_PTR(-ENODEV); | |
| 1300 | + | |
| 1298 | 1301 | rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL); |
| 1299 | 1302 | if (!rp) |
| 1300 | 1303 | return ERR_PTR(-ENOMEM); |
| @@ -166,9 +166,9 @@ static struct posix_clock_operations ptp_clock_ops = { · 165 unmodified lines | ||
| 166 | 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 | 173 | mutex_destroy(&ptp->tsevq_mux); |
| 174 | 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 | 215 | ptp->clock.ops = ptp_clock_ops; |
| 216 | − ptp->clock.release = delete_ptp_clock; | |
| 217 | 216 | ptp->info = info; |
| 218 | 217 | ptp->devid = MKDEV(major, index); |
| 219 | 218 | ptp->index = index; |
| @@ -236,15 +235,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, · 16 unmodified lines | ||
| 236 | 235 | if (err) |
| 237 | 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 | 238 | /* Register a new PPS source. */ |
| 249 | 239 | if (info->pps) { |
| 250 | 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. */ | |
| 264 | − err = posix_clock_register(&ptp->clock, ptp->devid); | |
| 253 | + /* Initialize a new device of our class in our clock structure. */ | |
| 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 | 265 | if (err) { |
| 266 | 266 | pr_err("failed to create posix clock\n"); |
| 267 | 267 | goto no_clock; |
| @@ -273,8 +273,6 @@ no_clock: · 5 unmodified lines | ||
| 273 | 273 | if (ptp->pps_source) |
| 274 | 274 | pps_unregister_source(ptp->pps_source); |
| 275 | 275 | no_pps: |
| 276 | − device_destroy(ptp_class, ptp->devid); | |
| 277 | −no_device: | |
| 278 | 276 | ptp_cleanup_pin_groups(ptp); |
| 279 | 277 | no_pin_groups: |
| 280 | 278 | if (ptp->kworker) |
| @@ -304,7 +302,6 @@ int ptp_clock_unregister(struct ptp_clock *ptp) · 23 unmodified lines | ||
| 304 | 302 | if (ptp->pps_source) |
| 305 | 303 | pps_unregister_source(ptp->pps_source); |
| 306 | 304 | |
| 307 | − device_destroy(ptp_class, ptp->devid); | |
| 308 | 305 | ptp_cleanup_pin_groups(ptp); |
| 309 | 306 | |
| 310 | 307 | posix_clock_unregister(&ptp->clock); |
| @@ -28,7 +28,7 @@ struct timestamp_event_queue { · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | struct ptp_clock { |
| 30 | 30 | struct posix_clock clock; |
| 31 | − struct device *dev; | |
| 31 | + struct device dev; | |
| 32 | 32 | struct ptp_clock_info *info; |
| 33 | 33 | dev_t devid; |
| 34 | 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 | 413 | int i; |
| 414 | 414 | |
| 415 | 415 | for (i = 0; i < rate_count; i++) { |
| 416 | − if (ramp <= slew_rates[i]) | |
| 417 | − cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i); | |
| 418 | − else | |
| 416 | + if (ramp > slew_rates[i]) | |
| 419 | 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 | 425 | if (cfg == 0xff) { |
| @@ -605,7 +608,7 @@ static const struct regulator_desc axp22x_regulators[] = { · 182 unmodified lines | ||
| 605 | 608 | AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK), |
| 606 | 609 | AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100, |
| 607 | 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 | 612 | AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100, |
| 610 | 613 | AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK, |
| 611 | 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 | 101 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 102 | 102 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 103 | 103 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
| 104 | − .set_ramp_delay = bd70528_set_ramp_delay, | |
| 105 | 104 | }; |
| 106 | 105 | |
| 107 | 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 | 172 | save_control = CMOS_READ(RTC_CONTROL); |
| 173 | 173 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); |
| 174 | 174 | save_freq_select = CMOS_READ(RTC_FREQ_SELECT); |
| 175 | − | |
| 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 | |
| 175 | + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); | |
| 189 | 176 | |
| 190 | 177 | #ifdef CONFIG_MACH_DECSTATION |
| 191 | 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 | 47 | irqen = irqsta & ~RTC_IRQ_EN_AL; |
| 48 | 48 | mutex_lock(&rtc->lock); |
| 49 | 49 | if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, |
| 50 | − irqen) < 0) | |
| 50 | + irqen) == 0) | |
| 51 | 51 | mtk_rtc_write_trigger(rtc); |
| 52 | 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 | 169 | alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); |
| 170 | 170 | mutex_unlock(&rtc->lock); |
| 171 | 171 | |
| 172 | − tm->tm_sec = data[RTC_OFFSET_SEC]; | |
| 173 | − tm->tm_min = data[RTC_OFFSET_MIN]; | |
| 174 | − tm->tm_hour = data[RTC_OFFSET_HOUR]; | |
| 175 | − tm->tm_mday = data[RTC_OFFSET_DOM]; | |
| 176 | − tm->tm_mon = data[RTC_OFFSET_MTH]; | |
| 177 | − tm->tm_year = data[RTC_OFFSET_YEAR]; | |
| 172 | + tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK; | |
| 173 | + tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK; | |
| 174 | + tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK; | |
| 175 | + tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK; | |
| 176 | + tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK; | |
| 177 | + tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK; | |
| 178 | 178 | |
| 179 | 179 | tm->tm_year += RTC_MIN_YEAR_OFFSET; |
| 180 | 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 | 195 | tm->tm_year -= RTC_MIN_YEAR_OFFSET; |
| 196 | 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 | 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 | 217 | if (alm->enabled) { |
| 207 | 218 | ret = regmap_bulk_write(rtc->regmap, |
| 208 | 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 | 379 | CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc", |
| 380 | 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 | 398 | static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = { |
| 383 | 399 | .rc_osc_rate = 32000, |
| 384 | 400 | .has_out_clk = 1, |
| @@ -2482,50 +2482,46 @@ static int qeth_mpc_initialize(struct qeth_card *card) · 2481 unmodified lines | ||
| 2482 | 2482 | rc = qeth_cm_enable(card); |
| 2483 | 2483 | if (rc) { |
| 2484 | 2484 | QETH_CARD_TEXT_(card, 2, "2err%d", rc); |
| 2485 | − goto out_qdio; | |
| 2485 | + return rc; | |
| 2486 | 2486 | } |
| 2487 | 2487 | rc = qeth_cm_setup(card); |
| 2488 | 2488 | if (rc) { |
| 2489 | 2489 | QETH_CARD_TEXT_(card, 2, "3err%d", rc); |
| 2490 | − goto out_qdio; | |
| 2490 | + return rc; | |
| 2491 | 2491 | } |
| 2492 | 2492 | rc = qeth_ulp_enable(card); |
| 2493 | 2493 | if (rc) { |
| 2494 | 2494 | QETH_CARD_TEXT_(card, 2, "4err%d", rc); |
| 2495 | − goto out_qdio; | |
| 2495 | + return rc; | |
| 2496 | 2496 | } |
| 2497 | 2497 | rc = qeth_ulp_setup(card); |
| 2498 | 2498 | if (rc) { |
| 2499 | 2499 | QETH_CARD_TEXT_(card, 2, "5err%d", rc); |
| 2500 | − goto out_qdio; | |
| 2500 | + return rc; | |
| 2501 | 2501 | } |
| 2502 | 2502 | rc = qeth_alloc_qdio_queues(card); |
| 2503 | 2503 | if (rc) { |
| 2504 | 2504 | QETH_CARD_TEXT_(card, 2, "5err%d", rc); |
| 2505 | − goto out_qdio; | |
| 2505 | + return rc; | |
| 2506 | 2506 | } |
| 2507 | 2507 | rc = qeth_qdio_establish(card); |
| 2508 | 2508 | if (rc) { |
| 2509 | 2509 | QETH_CARD_TEXT_(card, 2, "6err%d", rc); |
| 2510 | 2510 | qeth_free_qdio_queues(card); |
| 2511 | − goto out_qdio; | |
| 2511 | + return rc; | |
| 2512 | 2512 | } |
| 2513 | 2513 | rc = qeth_qdio_activate(card); |
| 2514 | 2514 | if (rc) { |
| 2515 | 2515 | QETH_CARD_TEXT_(card, 2, "7err%d", rc); |
| 2516 | − goto out_qdio; | |
| 2516 | + return rc; | |
| 2517 | 2517 | } |
| 2518 | 2518 | rc = qeth_dm_act(card); |
| 2519 | 2519 | if (rc) { |
| 2520 | 2520 | QETH_CARD_TEXT_(card, 2, "8err%d", rc); |
| 2521 | − goto out_qdio; | |
| 2521 | + return rc; | |
| 2522 | 2522 | } |
| 2523 | 2523 | |
| 2524 | 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 | 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 | 3425 | goto out; |
| 3430 | 3426 | } |
| 3431 | 3427 | |
| 3432 | − if (card->state != CARD_STATE_DOWN) { | |
| 3433 | − rc = -1; | |
| 3434 | − goto out; | |
| 3435 | − } | |
| 3436 | − | |
| 3437 | 3428 | qeth_free_qdio_queues(card); |
| 3438 | 3429 | card->options.cq = cq; |
| 3439 | 3430 | rc = 0; |
| @@ -5035,10 +5026,8 @@ retriable: · 1595 unmodified lines | ||
| 5035 | 5026 | } |
| 5036 | 5027 | if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { |
| 5037 | 5028 | rc = qeth_query_setdiagass(card); |
| 5038 | − if (rc < 0) { | |
| 5029 | + if (rc) | |
| 5039 | 5030 | QETH_CARD_TEXT_(card, 2, "8err%d", rc); |
| 5040 | − goto out; | |
| 5041 | − } | |
| 5042 | 5031 | } |
| 5043 | 5032 | |
| 5044 | 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 | 287 | card->state = CARD_STATE_HARDSETUP; |
| 288 | 288 | } |
| 289 | 289 | if (card->state == CARD_STATE_HARDSETUP) { |
| 290 | − qeth_qdio_clear_card(card, 0); | |
| 291 | 290 | qeth_drain_output_queues(card); |
| 292 | 291 | qeth_clear_working_pool_list(card); |
| 293 | 292 | card->state = CARD_STATE_DOWN; |
| 294 | 293 | } |
| 295 | 294 | |
| 295 | + qeth_qdio_clear_card(card, 0); | |
| 296 | 296 | flush_workqueue(card->event_wq); |
| 297 | 297 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
| 298 | 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 | 1952 | /* check if VNICC is currently enabled */ |
| 1953 | 1953 | bool qeth_l2_vnicc_is_in_use(struct qeth_card *card) |
| 1954 | 1954 | { |
| 1955 | − /* if everything is turned off, VNICC is not active */ | |
| 1956 | − if (!card->options.vnicc.cur_chars) | |
| 1955 | + if (!card->options.vnicc.sup_chars) | |
| 1957 | 1956 | return false; |
| 1958 | 1957 | /* default values are only OK if rx_bcast was not enabled by user |
| 1959 | 1958 | * or the card is offline. |
| @@ -2040,8 +2039,9 @@ static void qeth_l2_vnicc_init(struct qeth_card *card) · 80 unmodified lines | ||
| 2040 | 2039 | /* enforce assumed default values and recover settings, if changed */ |
| 2041 | 2040 | error |= qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING, |
| 2042 | 2041 | timeout); |
| 2043 | − chars_tmp = card->options.vnicc.wanted_chars ^ QETH_VNICC_DEFAULT; | |
| 2044 | − chars_tmp |= QETH_VNICC_BRIDGE_INVISIBLE; | |
| 2042 | + /* Change chars, if necessary */ | |
| 2043 | + chars_tmp = card->options.vnicc.wanted_chars ^ | |
| 2044 | + card->options.vnicc.cur_chars; | |
| 2045 | 2045 | chars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE; |
| 2046 | 2046 | for_each_set_bit(i, &chars_tmp, chars_len) { |
| 2047 | 2047 | vnicc = BIT(i); |
| @@ -1307,12 +1307,12 @@ static void qeth_l3_stop_card(struct qeth_card *card) · 1306 unmodified lines | ||
| 1307 | 1307 | card->state = CARD_STATE_HARDSETUP; |
| 1308 | 1308 | } |
| 1309 | 1309 | if (card->state == CARD_STATE_HARDSETUP) { |
| 1310 | − qeth_qdio_clear_card(card, 0); | |
| 1311 | 1310 | qeth_drain_output_queues(card); |
| 1312 | 1311 | qeth_clear_working_pool_list(card); |
| 1313 | 1312 | card->state = CARD_STATE_DOWN; |
| 1314 | 1313 | } |
| 1315 | 1314 | |
| 1315 | + qeth_qdio_clear_card(card, 0); | |
| 1316 | 1316 | flush_workqueue(card->event_wq); |
| 1317 | 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 | 242 | struct device_attribute *attr, const char *buf, size_t count) |
| 243 | 243 | { |
| 244 | 244 | struct qeth_card *card = dev_get_drvdata(dev); |
| 245 | + int rc = 0; | |
| 245 | 246 | char *tmp; |
| 246 | − int rc; | |
| 247 | 247 | |
| 248 | 248 | if (!IS_IQD(card)) |
| 249 | 249 | return -EPERM; |
| 250 | − if (card->state != CARD_STATE_DOWN) | |
| 251 | − return -EPERM; | |
| 252 | − if (card->options.sniffer) | |
| 253 | − return -EPERM; | |
| 254 | − if (card->options.cq == QETH_CQ_NOTAVAILABLE) | |
| 255 | − return -EPERM; | |
| 250 | + | |
| 251 | + mutex_lock(&card->conf_mutex); | |
| 252 | + if (card->state != CARD_STATE_DOWN) { | |
| 253 | + rc = -EPERM; | |
| 254 | + goto out; | |
| 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 | 267 | tmp = strsep((char **)&buf, "\n"); |
| 258 | − if (strlen(tmp) > 8) | |
| 259 | − return -EINVAL; | |
| 268 | + if (strlen(tmp) > 8) { | |
| 269 | + rc = -EINVAL; | |
| 270 | + goto out; | |
| 271 | + } | |
| 260 | 272 | |
| 261 | 273 | if (card->options.hsuid[0]) |
| 262 | 274 | /* delete old ip address */ |
| @@ -267,11 +279,13 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, · 4 unmodified lines | ||
| 267 | 279 | card->options.hsuid[0] = '\0'; |
| 268 | 280 | memcpy(card->dev->perm_addr, card->options.hsuid, 9); |
| 269 | 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)) | |
| 274 | − return -EPERM; | |
| 285 | + if (qeth_configure_cq(card, QETH_CQ_ENABLED)) { | |
| 286 | + rc = -EPERM; | |
| 287 | + goto out; | |
| 288 | + } | |
| 275 | 289 | |
| 276 | 290 | snprintf(card->options.hsuid, sizeof(card->options.hsuid), |
| 277 | 291 | "%-8s", tmp); |
| @@ -280,6 +294,8 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev, · 2 unmodified lines | ||
| 280 | 294 | |
| 281 | 295 | rc = qeth_l3_modify_hsuid(card, true); |
| 282 | 296 | |
| 297 | +out: | |
| 298 | + mutex_unlock(&card->conf_mutex); | |
| 283 | 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 | 121 | "cdev 0x%p, p# %u.\n", cdev, cdev->nports); |
| 122 | 122 | cxgbi_hbas_remove(cdev); |
| 123 | 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 | 126 | if (cdev->pmap.max_connect) |
| 126 | 127 | cxgbi_free_big_mem(cdev->pmap.port_csk); |
| 127 | 128 | kfree(cdev); |
| @@ -5385,7 +5385,6 @@ static const struct file_operations lpfc_debugfs_ras_log = { · 5384 unmodified lines | ||
| 5385 | 5385 | .read = lpfc_debugfs_read, |
| 5386 | 5386 | .release = lpfc_debugfs_ras_log_release, |
| 5387 | 5387 | }; |
| 5388 | −#endif | |
| 5389 | 5388 | |
| 5390 | 5389 | #undef lpfc_debugfs_op_dumpHBASlim |
| 5391 | 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 | 5556 | .write = lpfc_idiag_extacc_write, |
| 5558 | 5557 | .release = lpfc_idiag_cmd_release, |
| 5559 | 5558 | }; |
| 5560 | − | |
| 5559 | +#endif | |
| 5561 | 5560 | |
| 5562 | 5561 | /* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command |
| 5563 | 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 | 5883 | break; |
| 5884 | 5884 | default: |
| 5885 | 5885 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
| 5886 | − "1804 Invalid asynchrous event code: " | |
| 5886 | + "1804 Invalid asynchronous event code: " | |
| 5887 | 5887 | "x%x\n", bf_get(lpfc_trailer_code, |
| 5888 | 5888 | &cq_event->cqe.mcqe_cmpl)); |
| 5889 | 5889 | break; |
| @@ -8555,7 +8555,7 @@ lpfc_sli4_async_mbox_unblock(struct lpfc_hba *phba) · 8554 unmodified lines | ||
| 8555 | 8555 | psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; |
| 8556 | 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 | 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 | 8823 | return rc; |
| 8824 | 8824 | } |
| 8825 | 8825 | |
| 8826 | − /* Now, interrupt mode asynchrous mailbox command */ | |
| 8826 | + /* Now, interrupt mode asynchronous mailbox command */ | |
| 8827 | 8827 | rc = lpfc_mbox_cmd_check(phba, mboxq); |
| 8828 | 8828 | if (rc) { |
| 8829 | 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 | 13116 | * @phba: Pointer to HBA context object. |
| 13117 | 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 | 13120 | * event. |
| 13121 | 13121 | * |
| 13122 | 13122 | * Return: true if work posted to worker thread, otherwise false. |
| @@ -13270,7 +13270,7 @@ out_no_mqe_complete: · 147 unmodified lines | ||
| 13270 | 13270 | * @cqe: Pointer to mailbox completion queue entry. |
| 13271 | 13271 | * |
| 13272 | 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 | 13274 | * according to the MCQE's async bit. |
| 13275 | 13275 | * |
| 13276 | 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 | 5248 | &ct->chain_buffer_dma); |
| 5249 | 5249 | if (!ct->chain_buffer) { |
| 5250 | 5250 | ioc_err(ioc, "chain_lookup: pci_pool_alloc failed\n"); |
| 5251 | − _base_release_memory_pools(ioc); | |
| 5252 | 5251 | goto out; |
| 5253 | 5252 | } |
| 5254 | 5253 | } |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/interrupt.h> |
| 10 | 10 | #include <linux/of_irq.h> |
| 11 | 11 | #include <linux/of_address.h> |
| 12 | −#include <asm/sifive_l2_cache.h> | |
| 12 | +#include <soc/sifive/sifive_l2_cache.h> | |
| 13 | 13 | |
| 14 | 14 | #define SIFIVE_L2_DIRECCFIX_LOW 0x100 |
| 15 | 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 | 173 | static void dw_writer(struct dw_spi *dws) |
| 174 | 174 | { |
| 175 | − u32 max = tx_max(dws); | |
| 175 | + u32 max; | |
| 176 | 176 | u16 txw = 0; |
| 177 | 177 | |
| 178 | + spin_lock(&dws->buf_lock); | |
| 179 | + max = tx_max(dws); | |
| 178 | 180 | while (max--) { |
| 179 | 181 | /* Set the tx word if the transfer's original "tx" is not null */ |
| 180 | 182 | if (dws->tx_end - dws->len) { |
| @@ -186,13 +188,16 @@ static void dw_writer(struct dw_spi *dws) · 5 unmodified lines | ||
| 186 | 188 | dw_write_io_reg(dws, DW_SPI_DR, txw); |
| 187 | 189 | dws->tx += dws->n_bytes; |
| 188 | 190 | } |
| 191 | + spin_unlock(&dws->buf_lock); | |
| 189 | 192 | } |
| 190 | 193 | |
| 191 | 194 | static void dw_reader(struct dw_spi *dws) |
| 192 | 195 | { |
| 193 | − u32 max = rx_max(dws); | |
| 196 | + u32 max; | |
| 194 | 197 | u16 rxw; |
| 195 | 198 | |
| 199 | + spin_lock(&dws->buf_lock); | |
| 200 | + max = rx_max(dws); | |
| 196 | 201 | while (max--) { |
| 197 | 202 | rxw = dw_read_io_reg(dws, DW_SPI_DR); |
| 198 | 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 | 210 | dws->rx += dws->n_bytes; |
| 206 | 211 | } |
| 212 | + spin_unlock(&dws->buf_lock); | |
| 207 | 213 | } |
| 208 | 214 | |
| 209 | 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 | 283 | struct dw_spi *dws = spi_controller_get_devdata(master); |
| 278 | 284 | struct chip_data *chip = spi_get_ctldata(spi); |
| 285 | + unsigned long flags; | |
| 279 | 286 | u8 imask = 0; |
| 280 | 287 | u16 txlevel = 0; |
| 281 | 288 | u32 cr0; |
| 282 | 289 | int ret; |
| 283 | 290 | |
| 284 | 291 | dws->dma_mapped = 0; |
| 285 | − | |
| 292 | + spin_lock_irqsave(&dws->buf_lock, flags); | |
| 286 | 293 | dws->tx = (void *)transfer->tx_buf; |
| 287 | 294 | dws->tx_end = dws->tx + transfer->len; |
| 288 | 295 | dws->rx = transfer->rx_buf; |
| 289 | 296 | dws->rx_end = dws->rx + transfer->len; |
| 290 | 297 | dws->len = transfer->len; |
| 298 | + spin_unlock_irqrestore(&dws->buf_lock, flags); | |
| 291 | 299 | |
| 292 | 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 | 479 | dws->type = SSI_MOTO_SPI; |
| 472 | 480 | dws->dma_inited = 0; |
| 473 | 481 | dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); |
| 482 | + spin_lock_init(&dws->buf_lock); | |
| 474 | 483 | |
| 475 | 484 | spi_controller_set_devdata(master, dws); |
| 476 | 485 | |
| @@ -119,6 +119,7 @@ struct dw_spi { · 118 unmodified lines | ||
| 119 | 119 | size_t len; |
| 120 | 120 | void *tx; |
| 121 | 121 | void *tx_end; |
| 122 | + spinlock_t buf_lock; | |
| 122 | 123 | void *rx; |
| 123 | 124 | void *rx_end; |
| 124 | 125 | int dma_mapped; |
| @@ -185,6 +185,7 @@ struct fsl_dspi { · 184 unmodified lines | ||
| 185 | 185 | struct spi_transfer *cur_transfer; |
| 186 | 186 | struct spi_message *cur_msg; |
| 187 | 187 | struct chip_data *cur_chip; |
| 188 | + size_t progress; | |
| 188 | 189 | size_t len; |
| 189 | 190 | const void *tx; |
| 190 | 191 | void *rx; |
| @@ -586,21 +587,14 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi) · 395 unmodified lines | ||
| 586 | 587 | dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; |
| 587 | 588 | |
| 588 | 589 | if (dspi->devtype_data->xspi_mode && dspi->bits_per_word > 16) { |
| 589 | − /* Write two TX FIFO entries first, and then the corresponding | |
| 590 | − * CMD FIFO entry. | |
| 590 | + /* Write the CMD FIFO entry first, and then the two | |
| 591 | + * corresponding TX FIFO entries. | |
| 591 | 592 | */ |
| 592 | 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 | 595 | cmd_fifo_write(dspi); |
| 596 | + tx_fifo_write(dspi, data & 0xFFFF); | |
| 597 | + tx_fifo_write(dspi, data >> 16); | |
| 604 | 598 | } else { |
| 605 | 599 | /* Write one entry to both TX FIFO and CMD FIFO |
| 606 | 600 | * simultaneously. |
| @@ -658,7 +652,7 @@ static int dspi_rxtx(struct fsl_dspi *dspi) · 51 unmodified lines | ||
| 658 | 652 | u32 spi_tcr; |
| 659 | 653 | |
| 660 | 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 | 657 | /* Get transfer counter (in number of SPI transfers). It was |
| 664 | 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 | 661 | spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr); |
| 668 | 662 | /* Update total number of bytes that were transferred */ |
| 669 | 663 | msg->actual_length += spi_tcnt * dspi->bytes_per_word; |
| 664 | + dspi->progress += spi_tcnt; | |
| 670 | 665 | |
| 671 | 666 | trans_mode = dspi->devtype_data->trans_mode; |
| 672 | 667 | if (trans_mode == DSPI_EOQ_MODE) |
| @@ -679,7 +674,7 @@ static int dspi_rxtx(struct fsl_dspi *dspi) · 6 unmodified lines | ||
| 679 | 674 | return 0; |
| 680 | 675 | |
| 681 | 676 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
| 682 | − dspi->tx, !dspi->irq); | |
| 677 | + dspi->progress, !dspi->irq); | |
| 683 | 678 | |
| 684 | 679 | if (trans_mode == DSPI_EOQ_MODE) |
| 685 | 680 | dspi_eoq_write(dspi); |
| @@ -768,6 +763,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, · 82 unmodified lines | ||
| 768 | 763 | dspi->rx = transfer->rx_buf; |
| 769 | 764 | dspi->rx_end = dspi->rx + transfer->len; |
| 770 | 765 | dspi->len = transfer->len; |
| 766 | + dspi->progress = 0; | |
| 771 | 767 | /* Validated transfer specific frame size (defaults applied) */ |
| 772 | 768 | dspi->bits_per_word = transfer->bits_per_word; |
| 773 | 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 | 785 | SPI_CTARE_DTCP(1)); |
| 790 | 786 | |
| 791 | 787 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
| 792 | − dspi->tx, !dspi->irq); | |
| 788 | + dspi->progress, !dspi->irq); | |
| 793 | 789 | |
| 794 | 790 | trans_mode = dspi->devtype_data->trans_mode; |
| 795 | 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 | 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 | 298 | val = readl(priv->base + SSI_FC); |
| 306 | 299 | val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK); |
| 307 | − val |= FIELD_PREP(SSI_FC_TXFTH_MASK, fifo_threshold); | |
| 308 | − val |= FIELD_PREP(SSI_FC_RXFTH_MASK, fifo_threshold); | |
| 300 | + val |= FIELD_PREP(SSI_FC_TXFTH_MASK, SSI_FIFO_DEPTH - threshold); | |
| 301 | + val |= FIELD_PREP(SSI_FC_RXFTH_MASK, threshold); | |
| 309 | 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 | 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 | 1499 | * advances its @tx buffer pointer monotonically. |
| 1500 | 1500 | * @ctlr: Pointer to the spi_controller structure of the driver |
| 1501 | 1501 | * @xfer: Pointer to the transfer being timestamped |
| 1502 | − * @tx: Pointer to the current word within the xfer->tx_buf that the driver is | |
| 1503 | − * preparing to transmit right now. | |
| 1502 | + * @progress: How many words (not bytes) have been transferred so far | |
| 1504 | 1503 | * @irqs_off: If true, will disable IRQs and preemption for the duration of the |
| 1505 | 1504 | * transfer, for less jitter in time measurement. Only compatible |
| 1506 | 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 | 1510 | void spi_take_timestamp_pre(struct spi_controller *ctlr, |
| 1512 | 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 | 1514 | if (!xfer->ptp_sts) |
| 1518 | 1515 | return; |
| 1519 | 1516 | |
| 1520 | 1517 | if (xfer->timestamped_pre) |
| 1521 | 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 | 1521 | return; |
| 1525 | 1522 | |
| 1526 | 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 | 1526 | xfer->timestamped_pre = true; |
| 1530 | 1527 | |
| @@ -1546,23 +1543,20 @@ EXPORT_SYMBOL_GPL(spi_take_timestamp_pre); · 15 unmodified lines | ||
| 1546 | 1543 | * timestamped. |
| 1547 | 1544 | * @ctlr: Pointer to the spi_controller structure of the driver |
| 1548 | 1545 | * @xfer: Pointer to the transfer being timestamped |
| 1549 | − * @tx: Pointer to the current word within the xfer->tx_buf that the driver has | |
| 1550 | − * just transmitted. | |
| 1546 | + * @progress: How many words (not bytes) have been transferred so far | |
| 1551 | 1547 | * @irqs_off: If true, will re-enable IRQs and preemption for the local CPU. |
| 1552 | 1548 | */ |
| 1553 | 1549 | void spi_take_timestamp_post(struct spi_controller *ctlr, |
| 1554 | 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 | 1553 | if (!xfer->ptp_sts) |
| 1560 | 1554 | return; |
| 1561 | 1555 | |
| 1562 | 1556 | if (xfer->timestamped_post) |
| 1563 | 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 | 1560 | return; |
| 1567 | 1561 | |
| 1568 | 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 | 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 | 1572 | xfer->timestamped_post = true; |
| 1579 | 1573 | } |
| @@ -46,8 +46,8 @@ · 45 unmodified lines | ||
| 46 | 46 | #define PCI171X_RANGE_UNI BIT(4) |
| 47 | 47 | #define PCI171X_RANGE_GAIN(x) (((x) & 0x7) << 0) |
| 48 | 48 | #define PCI171X_MUX_REG 0x04 /* W: A/D multiplexor control */ |
| 49 | −#define PCI171X_MUX_CHANH(x) (((x) & 0xf) << 8) | |
| 50 | −#define PCI171X_MUX_CHANL(x) (((x) & 0xf) << 0) | |
| 49 | +#define PCI171X_MUX_CHANH(x) (((x) & 0xff) << 8) | |
| 50 | +#define PCI171X_MUX_CHANL(x) (((x) & 0xff) << 0) | |
| 51 | 51 | #define PCI171X_MUX_CHAN(x) (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x)) |
| 52 | 52 | #define PCI171X_STATUS_REG 0x06 /* R: status register */ |
| 53 | 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 | 449 | __u16 reserved1; |
| 450 | 450 | __u32 bayer_sign; |
| 451 | 451 | __u8 bayer_nf; |
| 452 | − __u8 reserved2[3]; | |
| 452 | + __u8 reserved2[7]; | |
| 453 | 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 | 37 | {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */ |
| 38 | 38 | {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ |
| 39 | 39 | {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ |
| 40 | + {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */ | |
| 40 | 41 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ |
| 41 | 42 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */ |
| 42 | 43 | {} /* Terminating entry */ |
| @@ -449,8 +449,8 @@ int vnt_vt3184_init(struct vnt_private *priv) · 448 unmodified lines | ||
| 449 | 449 | |
| 450 | 450 | memcpy(array, addr, length); |
| 451 | 451 | |
| 452 | − ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0, | |
| 453 | − MESSAGE_REQUEST_BBREG, length, array); | |
| 452 | + ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, | |
| 453 | + MESSAGE_REQUEST_BBREG, length, array); | |
| 454 | 454 | if (ret) |
| 455 | 455 | goto end; |
| 456 | 456 | |
| @@ -719,7 +719,7 @@ end: · 718 unmodified lines | ||
| 719 | 719 | */ |
| 720 | 720 | int vnt_radio_power_on(struct vnt_private *priv) |
| 721 | 721 | { |
| 722 | − int ret = true; | |
| 722 | + int ret = 0; | |
| 723 | 723 | |
| 724 | 724 | vnt_exit_deep_sleep(priv); |
| 725 | 725 | |
| @@ -259,6 +259,7 @@ struct vnt_private { · 258 unmodified lines | ||
| 259 | 259 | u8 mac_hw; |
| 260 | 260 | /* netdev */ |
| 261 | 261 | struct usb_device *usb; |
| 262 | + struct usb_interface *intf; | |
| 262 | 263 | |
| 263 | 264 | u64 tsf_time; |
| 264 | 265 | u8 rx_rate; |
| @@ -949,7 +949,7 @@ static const struct ieee80211_ops vnt_mac_ops = { · 948 unmodified lines | ||
| 949 | 949 | |
| 950 | 950 | int vnt_init(struct vnt_private *priv) |
| 951 | 951 | { |
| 952 | − if (!(vnt_init_registers(priv))) | |
| 952 | + if (vnt_init_registers(priv)) | |
| 953 | 953 | return -EAGAIN; |
| 954 | 954 | |
| 955 | 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 | 992 | priv = hw->priv; |
| 993 | 993 | priv->hw = hw; |
| 994 | 994 | priv->usb = udev; |
| 995 | + priv->intf = intf; | |
| 995 | 996 | |
| 996 | 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 | 60 | kfree(usb_buffer); |
| 61 | 61 | |
| 62 | − if (ret >= 0 && ret < (int)length) | |
| 62 | + if (ret == (int)length) | |
| 63 | + ret = 0; | |
| 64 | + else | |
| 63 | 65 | ret = -EIO; |
| 64 | 66 | |
| 65 | 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 | 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 | 96 | int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, |
| 78 | 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 | 123 | kfree(usb_buffer); |
| 105 | 124 | |
| 106 | − if (ret >= 0 && ret < (int)length) | |
| 125 | + if (ret == (int)length) | |
| 126 | + ret = 0; | |
| 127 | + else | |
| 107 | 128 | ret = -EIO; |
| 108 | 129 | |
| 109 | 130 | end_unlock: |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #include "device.h" |
| 20 | 20 | |
| 21 | +#define VNT_REG_BLOCK_SIZE 64 | |
| 22 | + | |
| 21 | 23 | int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, |
| 22 | 24 | u16 index, u16 length, u8 *buffer); |
| 23 | 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 | 28 | int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 ref_off, u8 data); |
| 27 | 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 | 34 | int vnt_start_interrupt_urb(struct vnt_private *priv); |
| 30 | 35 | int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb); |
| 31 | 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 | 99 | if (vnt_init(priv)) { |
| 100 | 100 | /* If fail all ends TODO retry */ |
| 101 | 101 | dev_err(&priv->usb->dev, "failed to start\n"); |
| 102 | + usb_set_intfdata(priv->intf, NULL); | |
| 102 | 103 | ieee80211_free_hw(priv->hw); |
| 103 | 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 | 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 | 653 | pr_debug("IBLOCK BIP Size: %u Sector: %llu\n", bip->bip_iter.bi_size, |
| 652 | 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 | 110 | irq = platform_get_irq_byname(pdev, "uplow"); |
| 111 | 111 | if (irq < 0) { |
| 112 | 112 | ret = irq; |
| 113 | + /* For old DTs with no IRQ defined */ | |
| 114 | + if (irq == -ENXIO) | |
| 115 | + ret = 0; | |
| 113 | 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 | 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 | 672 | static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, |
| 667 | 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 | 681 | if (acpi_device_enumerated(adev)) |
| 676 | 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 | 688 | if (acpi_serdev_check_resources(ctrl, adev)) |
| 679 | 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 | 90 | if (WARN_ON(index >= driver->num)) |
| 91 | 91 | return; |
| 92 | − if (!driver->ports[index]) | |
| 93 | − driver->ports[index] = port; | |
| 92 | + driver->ports[index] = port; | |
| 94 | 93 | } |
| 95 | 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 | 1376 | static irqreturn_t cdns3_device_irq_handler(int irq, void *data) |
| 1377 | 1377 | { |
| 1378 | − struct cdns3_device *priv_dev; | |
| 1379 | − struct cdns3 *cdns = data; | |
| 1378 | + struct cdns3_device *priv_dev = data; | |
| 1380 | 1379 | irqreturn_t ret = IRQ_NONE; |
| 1381 | 1380 | u32 reg; |
| 1382 | 1381 | |
| 1383 | − priv_dev = cdns->gadget_dev; | |
| 1384 | − | |
| 1385 | 1382 | /* check USB device interrupt */ |
| 1386 | 1383 | reg = readl(&priv_dev->regs->usb_ists); |
| 1387 | 1384 | if (reg) { |
| @@ -1419,14 +1416,12 @@ static irqreturn_t cdns3_device_irq_handler(int irq, void *data) · 31 unmodified lines | ||
| 1419 | 1416 | */ |
| 1420 | 1417 | static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data) |
| 1421 | 1418 | { |
| 1422 | − struct cdns3_device *priv_dev; | |
| 1423 | − struct cdns3 *cdns = data; | |
| 1419 | + struct cdns3_device *priv_dev = data; | |
| 1424 | 1420 | irqreturn_t ret = IRQ_NONE; |
| 1425 | 1421 | unsigned long flags; |
| 1426 | 1422 | int bit; |
| 1427 | 1423 | u32 reg; |
| 1428 | 1424 | |
| 1429 | − priv_dev = cdns->gadget_dev; | |
| 1430 | 1425 | spin_lock_irqsave(&priv_dev->lock, flags); |
| 1431 | 1426 | |
| 1432 | 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 | 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 | 2538 | pm_runtime_mark_last_busy(cdns->dev); |
| 2544 | 2539 | pm_runtime_put_autosuspend(cdns->dev); |
| @@ -2709,7 +2704,8 @@ static int __cdns3_gadget_init(struct cdns3 *cdns) · 164 unmodified lines | ||
| 2709 | 2704 | ret = devm_request_threaded_irq(cdns->dev, cdns->dev_irq, |
| 2710 | 2705 | cdns3_device_irq_handler, |
| 2711 | 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 | 2710 | if (ret) |
| 2715 | 2711 | goto err0; |
| @@ -26,6 +26,7 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd); · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | struct ehci_ci_priv { |
| 28 | 28 | struct regulator *reg_vbus; |
| 29 | + bool enabled; | |
| 29 | 30 | }; |
| 30 | 31 | |
| 31 | 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 | 38 | int ret = 0; |
| 38 | 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 | 42 | if (port > 1) { |
| 42 | 43 | dev_warn(dev, |
| 43 | 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 | 54 | enable ? "enable" : "disable", ret); |
| 54 | 55 | return ret; |
| 55 | 56 | } |
| 57 | + priv->enabled = enable; | |
| 56 | 58 | } |
| 57 | 59 | |
| 58 | 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 | 203 | [USB_ENDPOINT_XFER_INT] = 1024, |
| 204 | 204 | }; |
| 205 | 205 | |
| 206 | −static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |
| 207 | − int asnum, struct usb_host_interface *ifp, int num_ep, | |
| 208 | − unsigned char *buffer, int size) | |
| 206 | +static bool endpoint_is_duplicate(struct usb_endpoint_descriptor *e1, | |
| 207 | + struct usb_endpoint_descriptor *e2) | |
| 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 | 259 | unsigned char *buffer0 = buffer; |
| 211 | 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 | 291 | goto skip_to_next_endpoint_or_interface_descriptor; |
| 243 | 292 | |
| 244 | 293 | /* Check for duplicate endpoint addresses */ |
| 245 | − for (i = 0; i < ifp->desc.bNumEndpoints; ++i) { | |
| 246 | − if (ifp->endpoint[i].desc.bEndpointAddress == | |
| 247 | − d->bEndpointAddress) { | |
| 248 | − dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", | |
| 249 | − cfgno, inum, asnum, d->bEndpointAddress); | |
| 250 | − goto skip_to_next_endpoint_or_interface_descriptor; | |
| 251 | − } | |
| 294 | + if (config_endpoint_is_duplicate(config, inum, asnum, d)) { | |
| 295 | + dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", | |
| 296 | + cfgno, inum, asnum, d->bEndpointAddress); | |
| 297 | + goto skip_to_next_endpoint_or_interface_descriptor; | |
| 252 | 298 | } |
| 253 | 299 | |
| 254 | 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 | 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 | 401 | maxp = usb_endpoint_maxp(&endpoint->desc); |
| 351 | − if (maxp == 0) { | |
| 352 | − dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has wMaxPacketSize 0, skipping\n", | |
| 402 | + if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) { | |
| 403 | + dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n", | |
| 353 | 404 | cfgno, inum, asnum, d->bEndpointAddress); |
| 354 | − goto skip_to_next_endpoint_or_interface_descriptor; | |
| 355 | 405 | } |
| 356 | 406 | |
| 357 | 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 | 572 | if (((struct usb_descriptor_header *) buffer)->bDescriptorType |
| 523 | 573 | == USB_DT_INTERFACE) |
| 524 | 574 | break; |
| 525 | − retval = usb_parse_endpoint(ddev, cfgno, inum, asnum, alt, | |
| 526 | − num_ep, buffer, size); | |
| 575 | + retval = usb_parse_endpoint(ddev, cfgno, config, inum, asnum, | |
| 576 | + alt, num_ep, buffer, size); | |
| 527 | 577 | if (retval < 0) |
| 528 | 578 | return retval; |
| 529 | 579 | ++n; |
| @@ -2692,7 +2692,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub) · 2691 unmodified lines | ||
| 2692 | 2692 | #define SET_ADDRESS_TRIES 2 |
| 2693 | 2693 | #define GET_DESCRIPTOR_TRIES 2 |
| 2694 | 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 | 2697 | #define HUB_ROOT_RESET_TIME 60 /* times are in msec */ |
| 2698 | 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 | 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 | 2477 | return req->request.actual == req->request.length; |
| 2471 | 2478 | } |
| 2472 | 2479 | |
| @@ -445,6 +445,7 @@ config USB_TEGRA_XUDC · 444 unmodified lines | ||
| 445 | 445 | tristate "NVIDIA Tegra Superspeed USB 3.0 Device Controller" |
| 446 | 446 | depends on ARCH_TEGRA || COMPILE_TEST |
| 447 | 447 | depends on PHY_TEGRA_XUSB |
| 448 | + select USB_ROLE_SWITCH | |
| 448 | 449 | help |
| 449 | 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 | 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 | 420 | goto err; |
| 421 | + } | |
| 420 | 422 | |
| 421 | 423 | if (da8xx_ohci->oc_gpio) { |
| 422 | 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 | 427 | goto err; |
| 428 | + } | |
| 425 | 429 | |
| 426 | 430 | error = devm_request_threaded_irq(dev, oc_irq, NULL, |
| 427 | 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 | 75 | static int jz4740_musb_init(struct musb *musb) |
| 76 | 76 | { |
| 77 | 77 | struct device *dev = musb->controller->parent; |
| 78 | + int err; | |
| 78 | 79 | |
| 79 | 80 | if (dev->of_node) |
| 80 | 81 | musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0); |
| 81 | 82 | else |
| 82 | 83 | musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); |
| 83 | 84 | if (IS_ERR(musb->xceiv)) { |
| 84 | − dev_err(dev, "No transceiver configured\n"); | |
| 85 | − return PTR_ERR(musb->xceiv); | |
| 85 | + err = 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 | 91 | /* Silicon does not implement ConfigData register. |
| @@ -1840,6 +1840,9 @@ ATTRIBUTE_GROUPS(musb); · 1839 unmodified lines | ||
| 1840 | 1840 | #define MUSB_QUIRK_B_INVALID_VBUS_91 (MUSB_DEVCTL_BDEVICE | \ |
| 1841 | 1841 | (2 << MUSB_DEVCTL_VBUS_SHIFT) | \ |
| 1842 | 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 | 1846 | #define MUSB_QUIRK_A_DISCONNECT_19 ((3 << MUSB_DEVCTL_VBUS_SHIFT) | \ |
| 1844 | 1847 | MUSB_DEVCTL_SESSION) |
| 1845 | 1848 | |
| @@ -1862,6 +1865,11 @@ static void musb_pm_runtime_check_session(struct musb *musb) · 16 unmodified lines | ||
| 1862 | 1865 | s = MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV | |
| 1863 | 1866 | MUSB_DEVCTL_HR; |
| 1864 | 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 | 1873 | case MUSB_QUIRK_B_INVALID_VBUS_91: |
| 1866 | 1874 | if (musb->quirk_retries && !musb->flush_irq_work) { |
| 1867 | 1875 | musb_dbg(musb, |
| @@ -2310,6 +2318,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) · 442 unmodified lines | ||
| 2310 | 2318 | musb_disable_interrupts(musb); |
| 2311 | 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 | 2324 | /* Init IRQ workqueue before request_irq */ |
| 2314 | 2325 | INIT_DELAYED_WORK(&musb->irq_work, musb_irq_work); |
| 2315 | 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 | 425 | controller->controller.channel_abort = dma_channel_abort; |
| 426 | 426 | |
| 427 | 427 | if (request_irq(irq, dma_controller_irq, 0, |
| 428 | − dev_name(musb->controller), &controller->controller)) { | |
| 428 | + dev_name(musb->controller), controller)) { | |
| 429 | 429 | dev_err(dev, "request_irq %d failed!\n", irq); |
| 430 | 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 | 567 | /* Interface must have two endpoints */ |
| 568 | 568 | #define NUMEP2 BIT(16) |
| 569 | 569 | |
| 570 | +/* Device needs ZLP */ | |
| 571 | +#define ZLP BIT(17) | |
| 572 | + | |
| 570 | 573 | |
| 571 | 574 | static const struct usb_device_id option_ids[] = { |
| 572 | 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 | 1175 | .driver_info = NCTRL(0) | RSVD(3) }, |
| 1173 | 1176 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1102, 0xff), /* Telit ME910 (ECM) */ |
| 1174 | 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 | 1180 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), |
| 1176 | 1181 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1177 | 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 | 1201 | .driver_info = NCTRL(0) | RSVD(1) }, |
| 1197 | 1202 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */ |
| 1198 | 1203 | .driver_info = NCTRL(0) }, |
| 1204 | + { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ | |
| 1205 | + .driver_info = NCTRL(0) | ZLP }, | |
| 1199 | 1206 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
| 1200 | 1207 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), |
| 1201 | 1208 | .driver_info = RSVD(1) }, |
| @@ -2097,6 +2104,9 @@ static int option_attach(struct usb_serial *serial) · 895 unmodified lines | ||
| 2097 | 2104 | if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber))) |
| 2098 | 2105 | data->use_send_setup = 1; |
| 2099 | 2106 | |
| 2107 | + if (device_flags & ZLP) | |
| 2108 | + data->use_zlp = 1; | |
| 2109 | + | |
| 2100 | 2110 | spin_lock_init(&data->susp_lock); |
| 2101 | 2111 | |
| 2102 | 2112 | usb_set_serial_data(serial, data); |
| @@ -38,6 +38,7 @@ struct usb_wwan_intf_private { · 37 unmodified lines | ||
| 38 | 38 | spinlock_t susp_lock; |
| 39 | 39 | unsigned int suspended:1; |
| 40 | 40 | unsigned int use_send_setup:1; |
| 41 | + unsigned int use_zlp:1; | |
| 41 | 42 | int in_flight; |
| 42 | 43 | unsigned int open_ports; |
| 43 | 44 | void *private; |
| @@ -461,6 +461,7 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, · 460 unmodified lines | ||
| 461 | 461 | void (*callback) (struct urb *)) |
| 462 | 462 | { |
| 463 | 463 | struct usb_serial *serial = port->serial; |
| 464 | + struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); | |
| 464 | 465 | struct urb *urb; |
| 465 | 466 | |
| 466 | 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 | 472 | usb_sndbulkpipe(serial->dev, endpoint) | dir, |
| 472 | 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 | 478 | return urb; |
| 475 | 479 | } |
| 476 | 480 | |
| @@ -432,20 +432,30 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci) · 431 unmodified lines | ||
| 432 | 432 | |
| 433 | 433 | if (status & TCPC_ALERT_RX_STATUS) { |
| 434 | 434 | struct pd_message msg; |
| 435 | − unsigned int cnt; | |
| 435 | + unsigned int cnt, payload_cnt; | |
| 436 | 436 | u16 header; |
| 437 | 437 | |
| 438 | 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 | 450 | tcpci_read16(tcpci, TCPC_RX_HDR, &header); |
| 441 | 451 | msg.header = cpu_to_le16(header); |
| 442 | 452 | |
| 443 | − if (WARN_ON(cnt > sizeof(msg.payload))) | |
| 444 | − cnt = sizeof(msg.payload); | |
| 453 | + if (WARN_ON(payload_cnt > sizeof(msg.payload))) | |
| 454 | + payload_cnt = sizeof(msg.payload); | |
| 445 | 455 | |
| 446 | − if (cnt > 0) | |
| 456 | + if (payload_cnt > 0) | |
| 447 | 457 | regmap_raw_read(tcpci->regmap, TCPC_RX_DATA, |
| 448 | − &msg.payload, cnt); | |
| 458 | + &msg.payload, payload_cnt); | |
| 449 | 459 | |
| 450 | 460 | /* Read complete, clear RX status alert bit */ |
| 451 | 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 | 99 | #define UCSI_ENABLE_NTFY_CMD_COMPLETE BIT(16) |
| 100 | 100 | #define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE BIT(17) |
| 101 | 101 | #define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE BIT(18) |
| 102 | −#define UCSI_ENABLE_NTFY_CAP_CHANGE BIT(19) | |
| 103 | −#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE BIT(20) | |
| 104 | −#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE BIT(21) | |
| 105 | −#define UCSI_ENABLE_NTFY_CAM_CHANGE BIT(22) | |
| 106 | −#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE BIT(23) | |
| 107 | −#define UCSI_ENABLE_NTFY_PARTNER_CHANGE BIT(24) | |
| 108 | −#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE BIT(25) | |
| 109 | −#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(26) | |
| 110 | −#define UCSI_ENABLE_NTFY_ERROR BIT(27) | |
| 102 | +#define UCSI_ENABLE_NTFY_CAP_CHANGE BIT(21) | |
| 103 | +#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE BIT(22) | |
| 104 | +#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE BIT(23) | |
| 105 | +#define UCSI_ENABLE_NTFY_CAM_CHANGE BIT(24) | |
| 106 | +#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE BIT(25) | |
| 107 | +#define UCSI_ENABLE_NTFY_PARTNER_CHANGE BIT(27) | |
| 108 | +#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE BIT(28) | |
| 109 | +#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(30) | |
| 110 | +#define UCSI_ENABLE_NTFY_ERROR BIT(31) | |
| 111 | 111 | #define UCSI_ENABLE_NTFY_ALL 0xdbe70000 |
| 112 | 112 | |
| 113 | 113 | /* SET_UOR command bits */ |
| @@ -687,6 +687,7 @@ config MAX63XX_WATCHDOG · 686 unmodified lines | ||
| 687 | 687 | config MAX77620_WATCHDOG |
| 688 | 688 | tristate "Maxim Max77620 Watchdog Timer" |
| 689 | 689 | depends on MFD_MAX77620 || COMPILE_TEST |
| 690 | + select WATCHDOG_CORE | |
| 690 | 691 | help |
| 691 | 692 | This is the driver for the Max77620 watchdog timer. |
| 692 | 693 | Say 'Y' here to enable the watchdog timer support for |
| @@ -1444,6 +1445,7 @@ config SMSC37B787_WDT · 751 unmodified lines | ||
| 1444 | 1445 | config TQMX86_WDT |
| 1445 | 1446 | tristate "TQ-Systems TQMX86 Watchdog Timer" |
| 1446 | 1447 | depends on X86 |
| 1448 | + select WATCHDOG_CORE | |
| 1447 | 1449 | help |
| 1448 | 1450 | This is the driver for the hardware watchdog timer in the TQMX86 IO |
| 1449 | 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 | 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 | 116 | imx7ulp_wdt_set_timeout(&wdt->wdd, 1); |
| 117 | 117 | |
| 118 | 118 | /* wait for wdog to fire */ |
| @@ -602,7 +602,7 @@ static int orion_wdt_probe(struct platform_device *pdev) · 601 unmodified lines | ||
| 602 | 602 | set_bit(WDOG_HW_RUNNING, &dev->wdt.status); |
| 603 | 603 | |
| 604 | 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 | 606 | if (irq > 0) { |
| 607 | 607 | /* |
| 608 | 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 | 619 | /* Optional 2nd interrupt for pretimeout */ |
| 620 | − irq = platform_get_irq(pdev, 1); | |
| 620 | + irq = platform_get_irq_optional(pdev, 1); | |
| 621 | 621 | if (irq > 0) { |
| 622 | 622 | orion_wdt_info.options |= WDIOF_PRETIMEOUT; |
| 623 | 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 | 189 | module_platform_driver(rn5t618_wdt_driver); |
| 190 | 190 | |
| 191 | +MODULE_ALIAS("platform:rn5t618-wdt"); | |
| 191 | 192 | MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); |
| 192 | 193 | MODULE_DESCRIPTION("RN5T618 watchdog driver"); |
| 193 | 194 | MODULE_LICENSE("GPL v2"); |
| @@ -420,7 +420,7 @@ static int wdt_find(int addr) · 419 unmodified lines | ||
| 420 | 420 | cr_wdt_csr = NCT6102D_WDT_CSR; |
| 421 | 421 | break; |
| 422 | 422 | case NCT6116_ID: |
| 423 | − ret = nct6102; | |
| 423 | + ret = nct6116; | |
| 424 | 424 | cr_wdt_timeout = NCT6102D_WDT_TIMEOUT; |
| 425 | 425 | cr_wdt_control = NCT6102D_WDT_CONTROL; |
| 426 | 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 | 448 | if (blkcg_css) { |
| 449 | 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 | 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 | 491 | bio->bi_opf = REQ_OP_WRITE | write_flags; |
| 492 | 492 | bio->bi_private = cb; |
| 493 | 493 | bio->bi_end_io = end_compressed_bio_write; |
| 494 | + if (blkcg_css) | |
| 495 | + bio->bi_opf |= REQ_CGROUP_PUNT; | |
| 494 | 496 | bio_add_page(bio, page, PAGE_SIZE, 0); |
| 495 | 497 | } |
| 496 | 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 | 519 | bio_endio(bio); |
| 518 | 520 | } |
| 519 | 521 | |
| 522 | + if (blkcg_css) | |
| 523 | + kthread_associate_blkcg(NULL); | |
| 524 | + | |
| 520 | 525 | return 0; |
| 521 | 526 | } |
| 522 | 527 | |
| @@ -1479,10 +1479,10 @@ next_slot: · 1478 unmodified lines | ||
| 1479 | 1479 | disk_num_bytes = |
| 1480 | 1480 | btrfs_file_extent_disk_num_bytes(leaf, fi); |
| 1481 | 1481 | /* |
| 1482 | − * If extent we got ends before our range starts, skip | |
| 1483 | − * to next extent | |
| 1482 | + * If the extent we got ends before our current offset, | |
| 1483 | + * skip to the next extent. | |
| 1484 | 1484 | */ |
| 1485 | − if (extent_end <= start) { | |
| 1485 | + if (extent_end <= cur_offset) { | |
| 1486 | 1486 | path->slots[0]++; |
| 1487 | 1487 | goto next_slot; |
| 1488 | 1488 | } |
| @@ -3031,11 +3031,9 @@ static void end_bio_bh_io_sync(struct bio *bio) · 3030 unmodified lines | ||
| 3031 | 3031 | * errors, this only handles the "we need to be able to |
| 3032 | 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 | 3036 | sector_t maxsector; |
| 3037 | − struct bio_vec *bvec = bio_last_bvec_all(bio); | |
| 3038 | − unsigned truncated_bytes; | |
| 3039 | 3037 | struct hd_struct *part; |
| 3040 | 3038 | |
| 3041 | 3039 | rcu_read_lock(); |
| @@ -3061,28 +3059,7 @@ void guard_bio_eod(int op, struct bio *bio) · 19 unmodified lines | ||
| 3061 | 3059 | if (likely((bio->bi_iter.bi_size >> 9) <= maxsector)) |
| 3062 | 3060 | return; |
| 3063 | 3061 | |
| 3064 | − /* Uhhuh. We've got a bio that straddles the device size! */ | |
| 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 | − } | |
| 3062 | + bio_truncate(bio, maxsector << 9); | |
| 3086 | 3063 | } |
| 3087 | 3064 | |
| 3088 | 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 | 3095 | bio->bi_end_io = end_bio_bh_io_sync; |
| 3119 | 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 | 3098 | if (buffer_meta(bh)) |
| 3125 | 3099 | op_flags |= REQ_META; |
| 3126 | 3100 | if (buffer_prio(bh)) |
| 3127 | 3101 | op_flags |= REQ_PRIO; |
| 3128 | 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 | 3107 | if (wbc) { |
| 3131 | 3108 | wbc_init_bio(wbc, bio); |
| 3132 | 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 | 353 | if (owner && !try_module_get(owner)) |
| 354 | 354 | return NULL; |
| 355 | − kobj = kobject_get(&p->kobj); | |
| 355 | + kobj = kobject_get_unless_zero(&p->kobj); | |
| 356 | 356 | if (!kobj) |
| 357 | 357 | module_put(owner); |
| 358 | 358 | return kobj; |
| @@ -1693,6 +1693,7 @@ struct cifs_fattr { · 1692 unmodified lines | ||
| 1693 | 1693 | struct timespec64 cf_atime; |
| 1694 | 1694 | struct timespec64 cf_mtime; |
| 1695 | 1695 | struct timespec64 cf_ctime; |
| 1696 | + u32 cf_cifstag; | |
| 1696 | 1697 | }; |
| 1697 | 1698 | |
| 1698 | 1699 | static inline void free_dfs_info_param(struct dfs_info3_param *param) |
| @@ -139,6 +139,28 @@ retry: · 138 unmodified lines | ||
| 139 | 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 | 164 | static void |
| 143 | 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 | 180 | * is a symbolic link, DFS referral or a reparse point with a direct |
| 159 | 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 | 184 | fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; |
| 163 | 185 | |
| 164 | 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 | 233 | void |
| 198 | 234 | cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, |
| 199 | 235 | struct cifs_sb_info *cifs_sb) |
| 200 | 236 | { |
| 201 | − memset(fattr, 0, sizeof(*fattr)); | |
| 202 | − fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes); | |
| 203 | − fattr->cf_eof = le64_to_cpu(info->EndOfFile); | |
| 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); | |
| 237 | + __dir_info_to_fattr(fattr, info); | |
| 238 | + cifs_fill_common_info(fattr, cifs_sb); | |
| 239 | +} | |
| 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 | 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 | 795 | (FIND_FILE_STANDARD_INFO *)find_entry, |
| 756 | 796 | cifs_sb); |
| 757 | 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 | 803 | default: |
| 759 | 804 | cifs_dir_info_to_fattr(&fattr, |
| 760 | 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 | 67 | goto out; |
| 68 | 68 | |
| 69 | 69 | |
| 70 | − if (oparms->tcon->use_resilient) { | |
| 70 | + if (oparms->tcon->use_resilient) { | |
| 71 | 71 | /* default timeout is 0, servers pick default (120 seconds) */ |
| 72 | 72 | nr_ioctl_req.Timeout = |
| 73 | 73 | cpu_to_le32(oparms->tcon->handle_timeout); |
| @@ -39,6 +39,8 @@ · 38 unmodified lines | ||
| 39 | 39 | #include <linux/atomic.h> |
| 40 | 40 | #include <linux/prefetch.h> |
| 41 | 41 | |
| 42 | +#include "internal.h" | |
| 43 | + | |
| 42 | 44 | /* |
| 43 | 45 | * How many user pages to map in one call to get_user_pages(). This determines |
| 44 | 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 | 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 | 965 | int ret = -EBADF; |
| 966 | 966 | struct file *file = fget_raw(fildes); |
| @@ -975,6 +975,11 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes) · 8 unmodified lines | ||
| 975 | 975 | return ret; |
| 976 | 976 | } |
| 977 | 977 | |
| 978 | +SYSCALL_DEFINE1(dup, unsigned int, fildes) | |
| 979 | +{ | |
| 980 | + return ksys_dup(fildes); | |
| 981 | +} | |
| 982 | + | |
| 978 | 983 | int f_dupfd(unsigned int from, struct file *file, unsigned flags) |
| 979 | 984 | { |
| 980 | 985 | int err; |
| @@ -1498,8 +1498,10 @@ static int __init init_hugetlbfs_fs(void) · 1497 unmodified lines | ||
| 1498 | 1498 | /* other hstates are optional */ |
| 1499 | 1499 | i = 0; |
| 1500 | 1500 | for_each_hstate(h) { |
| 1501 | − if (i == default_hstate_idx) | |
| 1501 | + if (i == default_hstate_idx) { | |
| 1502 | + i++; | |
| 1502 | 1503 | continue; |
| 1504 | + } | |
| 1503 | 1505 | |
| 1504 | 1506 | mnt = mount_one_hugetlbfs(h); |
| 1505 | 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 | 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 | 42 | extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len, |
| 43 | 43 | get_block_t *get_block, struct iomap *iomap); |
| 44 | 44 | |
| @@ -92,7 +92,6 @@ struct io_wqe { · 91 unmodified lines | ||
| 92 | 92 | struct io_wqe_acct acct[2]; |
| 93 | 93 | |
| 94 | 94 | struct hlist_nulls_head free_list; |
| 95 | − struct hlist_nulls_head busy_list; | |
| 96 | 95 | struct list_head all_list; |
| 97 | 96 | |
| 98 | 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 | 326 | if (worker->flags & IO_WORKER_F_FREE) { |
| 328 | 327 | worker->flags &= ~IO_WORKER_F_FREE; |
| 329 | 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 | 364 | if (!(worker->flags & IO_WORKER_F_FREE)) { |
| 367 | 365 | worker->flags |= IO_WORKER_F_FREE; |
| 368 | − hlist_nulls_del_init_rcu(&worker->nulls_node); | |
| 369 | 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 | 429 | if (signal_pending(current)) |
| 433 | 430 | flush_signals(current); |
| 434 | 431 | |
| 432 | + cond_resched(); | |
| 433 | + | |
| 435 | 434 | spin_lock_irq(&worker->lock); |
| 436 | 435 | worker->cur_work = work; |
| 437 | 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 | 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 | 800 | rcu_read_lock(); |
| 806 | 801 | for_each_node(node) { |
| 807 | 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 | 1044 | spin_lock_init(&wqe->lock); |
| 1050 | 1045 | INIT_WQ_LIST(&wqe->work_list); |
| 1051 | 1046 | INIT_HLIST_NULLS_HEAD(&wqe->free_list, 0); |
| 1052 | − INIT_HLIST_NULLS_HEAD(&wqe->busy_list, 1); | |
| 1053 | 1047 | INIT_LIST_HEAD(&wqe->all_list); |
| 1054 | 1048 | } |
| 1055 | 1049 | |
| @@ -330,6 +330,26 @@ struct io_timeout { · 329 unmodified lines | ||
| 330 | 330 | struct file *file; |
| 331 | 331 | u64 addr; |
| 332 | 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 | 355 | struct io_async_connect { |
| @@ -351,7 +371,6 @@ struct io_async_rw { · 15 unmodified lines | ||
| 351 | 371 | }; |
| 352 | 372 | |
| 353 | 373 | struct io_async_ctx { |
| 354 | − struct io_uring_sqe sqe; | |
| 355 | 374 | union { |
| 356 | 375 | struct io_async_rw rw; |
| 357 | 376 | struct io_async_msghdr msg; |
| @@ -369,15 +388,16 @@ struct io_async_ctx { · 11 unmodified lines | ||
| 369 | 388 | struct io_kiocb { |
| 370 | 389 | union { |
| 371 | 390 | struct file *file; |
| 372 | − struct kiocb rw; | |
| 391 | + struct io_rw rw; | |
| 373 | 392 | struct io_poll_iocb poll; |
| 374 | 393 | struct io_accept accept; |
| 375 | 394 | struct io_sync sync; |
| 376 | 395 | struct io_cancel cancel; |
| 377 | 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 | 401 | struct io_async_ctx *io; |
| 382 | 402 | struct file *ring_file; |
| 383 | 403 | int ring_fd; |
| @@ -411,7 +431,6 @@ struct io_kiocb { · 27 unmodified lines | ||
| 411 | 431 | #define REQ_F_INFLIGHT 16384 /* on inflight list */ |
| 412 | 432 | #define REQ_F_COMP_LOCKED 32768 /* completion under lock */ |
| 413 | 433 | #define REQ_F_HARDLINK 65536 /* doesn't sever on completion < 0 */ |
| 414 | −#define REQ_F_PREPPED 131072 /* request already opcode prepared */ | |
| 415 | 434 | u64 user_data; |
| 416 | 435 | u32 result; |
| 417 | 436 | u32 sequence; |
| @@ -609,33 +628,31 @@ static inline bool io_prep_async_work(struct io_kiocb *req, · 191 unmodified lines | ||
| 609 | 628 | { |
| 610 | 629 | bool do_hashed = false; |
| 611 | 630 | |
| 612 | − if (req->sqe) { | |
| 613 | − switch (req->opcode) { | |
| 614 | − case IORING_OP_WRITEV: | |
| 615 | − case IORING_OP_WRITE_FIXED: | |
| 616 | − /* only regular files should be hashed for writes */ | |
| 617 | − if (req->flags & REQ_F_ISREG) | |
| 618 | − do_hashed = true; | |
| 619 | − /* fall-through */ | |
| 620 | − case IORING_OP_READV: | |
| 621 | − case IORING_OP_READ_FIXED: | |
| 622 | − case IORING_OP_SENDMSG: | |
| 623 | − case IORING_OP_RECVMSG: | |
| 624 | − case IORING_OP_ACCEPT: | |
| 625 | − case IORING_OP_POLL_ADD: | |
| 626 | − case IORING_OP_CONNECT: | |
| 627 | − /* | |
| 628 | − * We know REQ_F_ISREG is not set on some of these | |
| 629 | − * opcodes, but this enables us to keep the check in | |
| 630 | − * just one place. | |
| 631 | − */ | |
| 632 | − if (!(req->flags & REQ_F_ISREG)) | |
| 633 | − req->work.flags |= IO_WQ_WORK_UNBOUND; | |
| 634 | − break; | |
| 635 | − } | |
| 636 | − if (io_req_needs_user(req)) | |
| 637 | − req->work.flags |= IO_WQ_WORK_NEEDS_USER; | |
| 631 | + switch (req->opcode) { | |
| 632 | + case IORING_OP_WRITEV: | |
| 633 | + case IORING_OP_WRITE_FIXED: | |
| 634 | + /* only regular files should be hashed for writes */ | |
| 635 | + if (req->flags & REQ_F_ISREG) | |
| 636 | + do_hashed = true; | |
| 637 | + /* fall-through */ | |
| 638 | + case IORING_OP_READV: | |
| 639 | + case IORING_OP_READ_FIXED: | |
| 640 | + case IORING_OP_SENDMSG: | |
| 641 | + case IORING_OP_RECVMSG: | |
| 642 | + case IORING_OP_ACCEPT: | |
| 643 | + case IORING_OP_POLL_ADD: | |
| 644 | + case IORING_OP_CONNECT: | |
| 645 | + /* | |
| 646 | + * We know REQ_F_ISREG is not set on some of these | |
| 647 | + * opcodes, but this enables us to keep the check in | |
| 648 | + * just one place. | |
| 649 | + */ | |
| 650 | + if (!(req->flags & REQ_F_ISREG)) | |
| 651 | + req->work.flags |= IO_WQ_WORK_UNBOUND; | |
| 652 | + break; | |
| 638 | 653 | } |
| 654 | + if (io_req_needs_user(req)) | |
| 655 | + req->work.flags |= IO_WQ_WORK_NEEDS_USER; | |
| 639 | 656 | |
| 640 | 657 | *link = io_prep_linked_timeout(req); |
| 641 | 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 | 1198 | ret = 0; |
| 1182 | 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 | 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 | 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 | 1357 | if (kiocb->ki_flags & IOCB_WRITE) |
| 1341 | 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 | 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 | 1369 | io_complete_rw_common(kiocb, res); |
| 1353 | 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 | 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 | 1376 | struct io_kiocb *nxt = NULL; |
| 1360 | 1377 | |
| 1361 | 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 | 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 | 1388 | if (kiocb->ki_flags & IOCB_WRITE) |
| 1372 | 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 | 1418 | list_req = list_first_entry(&ctx->poll_list, struct io_kiocb, |
| 1402 | 1419 | list); |
| 1403 | − if (list_req->rw.ki_filp != req->rw.ki_filp) | |
| 1420 | + if (list_req->file != req->file) | |
| 1404 | 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 | 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 | 1494 | struct io_ring_ctx *ctx = req->ctx; |
| 1478 | − struct kiocb *kiocb = &req->rw; | |
| 1495 | + struct kiocb *kiocb = &req->rw.kiocb; | |
| 1479 | 1496 | unsigned ioprio; |
| 1480 | 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 | 1541 | return -EINVAL; |
| 1525 | 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 | 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 | 1580 | io_rw_done(kiocb, ret); |
| 1558 | 1581 | } |
| 1559 | 1582 | |
| 1560 | −static ssize_t io_import_fixed(struct io_ring_ctx *ctx, int rw, | |
| 1561 | − const struct io_uring_sqe *sqe, | |
| 1583 | +static ssize_t io_import_fixed(struct io_kiocb *req, int rw, | |
| 1562 | 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 | 1588 | struct io_mapped_ubuf *imu; |
| 1566 | 1589 | unsigned index, buf_index; |
| 1567 | 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 | 1594 | if (unlikely(!ctx->user_bufs)) |
| 1572 | 1595 | return -EFAULT; |
| 1573 | 1596 | |
| 1574 | − buf_index = READ_ONCE(sqe->buf_index); | |
| 1597 | + buf_index = (unsigned long) req->rw.kiocb.private; | |
| 1575 | 1598 | if (unlikely(buf_index >= ctx->nr_user_bufs)) |
| 1576 | 1599 | return -EFAULT; |
| 1577 | 1600 | |
| 1578 | 1601 | index = array_index_nospec(buf_index, ctx->nr_user_bufs); |
| 1579 | 1602 | imu = &ctx->user_bufs[index]; |
| 1580 | − buf_addr = READ_ONCE(sqe->addr); | |
| 1603 | + buf_addr = req->rw.addr; | |
| 1581 | 1604 | |
| 1582 | 1605 | /* overflow */ |
| 1583 | 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 | 1657 | static ssize_t io_import_iovec(int rw, struct io_kiocb *req, |
| 1635 | 1658 | struct iovec **iovec, struct iov_iter *iter) |
| 1636 | 1659 | { |
| 1637 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 1638 | − void __user *buf = u64_to_user_ptr(READ_ONCE(sqe->addr)); | |
| 1639 | − size_t sqe_len = READ_ONCE(sqe->len); | |
| 1660 | + void __user *buf = u64_to_user_ptr(req->rw.addr); | |
| 1661 | + size_t sqe_len = req->rw.len; | |
| 1640 | 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 | 1664 | opcode = req->opcode; |
| 1651 | 1665 | if (opcode == IORING_OP_READ_FIXED || opcode == IORING_OP_WRITE_FIXED) { |
| 1652 | 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 | 1674 | if (req->io) { |
| 1657 | 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 | 1768 | static int io_alloc_async_ctx(struct io_kiocb *req) |
| 1751 | 1769 | { |
| 1752 | 1770 | req->io = kmalloc(sizeof(*req->io), GFP_KERNEL); |
| 1753 | − if (req->io) { | |
| 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; | |
| 1771 | + return req->io == NULL; | |
| 1760 | 1772 | } |
| 1761 | 1773 | |
| 1762 | 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 | 1794 | return 0; |
| 1783 | 1795 | } |
| 1784 | 1796 | |
| 1785 | −static int io_read_prep(struct io_kiocb *req, struct iovec **iovec, | |
| 1786 | − struct iov_iter *iter, bool force_nonblock) | |
| 1797 | +static int io_read_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, | |
| 1798 | + bool force_nonblock) | |
| 1787 | 1799 | { |
| 1800 | + struct io_async_ctx *io; | |
| 1801 | + struct iov_iter iter; | |
| 1788 | 1802 | ssize_t ret; |
| 1789 | 1803 | |
| 1790 | − ret = io_prep_rw(req, force_nonblock); | |
| 1804 | + ret = io_prep_rw(req, sqe, force_nonblock); | |
| 1791 | 1805 | if (ret) |
| 1792 | 1806 | return ret; |
| 1793 | 1807 | |
| 1794 | 1808 | if (unlikely(!(req->file->f_mode & FMODE_READ))) |
| 1795 | 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 | 1826 | static int io_read(struct io_kiocb *req, struct io_kiocb **nxt, |
| 1801 | 1827 | bool force_nonblock) |
| 1802 | 1828 | { |
| 1803 | 1829 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; |
| 1804 | − struct kiocb *kiocb = &req->rw; | |
| 1830 | + struct kiocb *kiocb = &req->rw.kiocb; | |
| 1805 | 1831 | struct iov_iter iter; |
| 1806 | − struct file *file; | |
| 1807 | 1832 | size_t iov_count; |
| 1808 | 1833 | ssize_t io_size, ret; |
| 1809 | 1834 | |
| 1810 | − if (!req->io) { | |
| 1811 | − ret = io_read_prep(req, &iovec, &iter, force_nonblock); | |
| 1812 | − if (ret < 0) | |
| 1813 | − return ret; | |
| 1814 | − } else { | |
| 1815 | − ret = io_import_iovec(READ, req, &iovec, &iter); | |
| 1816 | − if (ret < 0) | |
| 1817 | − return ret; | |
| 1818 | − } | |
| 1835 | + ret = io_import_iovec(READ, req, &iovec, &iter); | |
| 1836 | + if (ret < 0) | |
| 1837 | + return ret; | |
| 1819 | 1838 | |
| 1820 | 1839 | /* Ensure we clear previously set non-block flag */ |
| 1821 | 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 | 1843 | io_size = ret; |
| 1826 | 1844 | if (req->flags & REQ_F_LINK) |
| 1827 | 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 | 1848 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so |
| 1831 | 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 | 1852 | req->flags |= REQ_F_MUST_PUNT; |
| 1835 | 1853 | goto copy_iov; |
| 1836 | 1854 | } |
| 1837 | 1855 | |
| 1838 | 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 | 1858 | if (!ret) { |
| 1841 | 1859 | ssize_t ret2; |
| 1842 | 1860 | |
| 1843 | − if (file->f_op->read_iter) | |
| 1844 | − ret2 = call_read_iter(file, kiocb, &iter); | |
| 1861 | + if (req->file->f_op->read_iter) | |
| 1862 | + ret2 = call_read_iter(req->file, kiocb, &iter); | |
| 1845 | 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 | 1866 | /* Catch -EAGAIN return for forced non-blocking submission */ |
| 1861 | 1867 | if (!force_nonblock || ret2 != -EAGAIN) { |
| 1862 | 1868 | kiocb_done(kiocb, ret2, nxt, req->in_async); |
| @@ -1875,46 +1881,52 @@ out_free: · 12 unmodified lines | ||
| 1875 | 1881 | return ret; |
| 1876 | 1882 | } |
| 1877 | 1883 | |
| 1878 | −static int io_write_prep(struct io_kiocb *req, struct iovec **iovec, | |
| 1879 | − struct iov_iter *iter, bool force_nonblock) | |
| 1884 | +static int io_write_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, | |
| 1885 | + bool force_nonblock) | |
| 1880 | 1886 | { |
| 1887 | + struct io_async_ctx *io; | |
| 1888 | + struct iov_iter iter; | |
| 1881 | 1889 | ssize_t ret; |
| 1882 | 1890 | |
| 1883 | − ret = io_prep_rw(req, force_nonblock); | |
| 1891 | + ret = io_prep_rw(req, sqe, force_nonblock); | |
| 1884 | 1892 | if (ret) |
| 1885 | 1893 | return ret; |
| 1886 | 1894 | |
| 1887 | 1895 | if (unlikely(!(req->file->f_mode & FMODE_WRITE))) |
| 1888 | 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 | 1913 | static int io_write(struct io_kiocb *req, struct io_kiocb **nxt, |
| 1894 | 1914 | bool force_nonblock) |
| 1895 | 1915 | { |
| 1896 | 1916 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; |
| 1897 | − struct kiocb *kiocb = &req->rw; | |
| 1917 | + struct kiocb *kiocb = &req->rw.kiocb; | |
| 1898 | 1918 | struct iov_iter iter; |
| 1899 | − struct file *file; | |
| 1900 | 1919 | size_t iov_count; |
| 1901 | 1920 | ssize_t ret, io_size; |
| 1902 | 1921 | |
| 1903 | − if (!req->io) { | |
| 1904 | − ret = io_write_prep(req, &iovec, &iter, force_nonblock); | |
| 1905 | − if (ret < 0) | |
| 1906 | − return ret; | |
| 1907 | − } else { | |
| 1908 | − ret = io_import_iovec(WRITE, req, &iovec, &iter); | |
| 1909 | − if (ret < 0) | |
| 1910 | − return ret; | |
| 1911 | − } | |
| 1922 | + ret = io_import_iovec(WRITE, req, &iovec, &iter); | |
| 1923 | + if (ret < 0) | |
| 1924 | + return ret; | |
| 1912 | 1925 | |
| 1913 | 1926 | /* Ensure we clear previously set non-block flag */ |
| 1914 | 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 | 1930 | io_size = ret; |
| 1919 | 1931 | if (req->flags & REQ_F_LINK) |
| 1920 | 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 | 1946 | goto copy_iov; |
| 1935 | 1947 | |
| 1936 | 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 | 1950 | if (!ret) { |
| 1939 | 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 | 1958 | * we return to userspace. |
| 1947 | 1959 | */ |
| 1948 | 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 | 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 | 1964 | SB_FREEZE_WRITE); |
| 1953 | 1965 | } |
| 1954 | 1966 | kiocb->ki_flags |= IOCB_WRITE; |
| 1955 | 1967 | |
| 1956 | − if (file->f_op->write_iter) | |
| 1957 | − ret2 = call_write_iter(file, kiocb, &iter); | |
| 1968 | + if (req->file->f_op->write_iter) | |
| 1969 | + ret2 = call_write_iter(req->file, kiocb, &iter); | |
| 1958 | 1970 | else |
| 1959 | − ret2 = loop_rw_iter(WRITE, file, kiocb, &iter); | |
| 1971 | + ret2 = loop_rw_iter(WRITE, req->file, kiocb, &iter); | |
| 1960 | 1972 | if (!force_nonblock || ret2 != -EAGAIN) { |
| 1961 | 1973 | kiocb_done(kiocb, ret2, nxt, req->in_async); |
| 1962 | 1974 | } else { |
| @@ -1989,13 +2001,10 @@ static int io_nop(struct io_kiocb *req) · 26 unmodified lines | ||
| 1989 | 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 | 2006 | struct io_ring_ctx *ctx = req->ctx; |
| 1996 | 2007 | |
| 1997 | − if (req->flags & REQ_F_PREPPED) | |
| 1998 | − return 0; | |
| 1999 | 2008 | if (!req->file) |
| 2000 | 2009 | return -EBADF; |
| 2001 | 2010 | |
| @@ -2010,7 +2019,6 @@ static int io_prep_fsync(struct io_kiocb *req) · 8 unmodified lines | ||
| 2010 | 2019 | |
| 2011 | 2020 | req->sync.off = READ_ONCE(sqe->off); |
| 2012 | 2021 | req->sync.len = READ_ONCE(sqe->len); |
| 2013 | − req->flags |= REQ_F_PREPPED; | |
| 2014 | 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 | 2044 | if (io_req_cancelled(req)) |
| 2037 | 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 | 2048 | end > 0 ? end : LLONG_MAX, |
| 2041 | 2049 | req->sync.flags & IORING_FSYNC_DATASYNC); |
| 2042 | 2050 | if (ret < 0) |
| @@ -2051,11 +2059,6 @@ static int io_fsync(struct io_kiocb *req, struct io_kiocb **nxt, · 8 unmodified lines | ||
| 2051 | 2059 | bool force_nonblock) |
| 2052 | 2060 | { |
| 2053 | 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 | 2063 | /* fsync always requires a blocking context */ |
| 2061 | 2064 | if (force_nonblock) { |
| @@ -2071,13 +2074,10 @@ static int io_fsync(struct io_kiocb *req, struct io_kiocb **nxt, · 9 unmodified lines | ||
| 2071 | 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 | 2079 | struct io_ring_ctx *ctx = req->ctx; |
| 2078 | 2080 | |
| 2079 | − if (req->flags & REQ_F_PREPPED) | |
| 2080 | − return 0; | |
| 2081 | 2081 | if (!req->file) |
| 2082 | 2082 | return -EBADF; |
| 2083 | 2083 | |
| @@ -2089,7 +2089,6 @@ static int io_prep_sfr(struct io_kiocb *req) · 5 unmodified lines | ||
| 2089 | 2089 | req->sync.off = READ_ONCE(sqe->off); |
| 2090 | 2090 | req->sync.len = READ_ONCE(sqe->len); |
| 2091 | 2091 | req->sync.flags = READ_ONCE(sqe->sync_range_flags); |
| 2092 | − req->flags |= REQ_F_PREPPED; | |
| 2093 | 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 | 2101 | if (io_req_cancelled(req)) |
| 2103 | 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 | 2105 | req->sync.flags); |
| 2107 | 2106 | if (ret < 0) |
| 2108 | 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 | 2115 | bool force_nonblock) |
| 2117 | 2116 | { |
| 2118 | 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 | 2119 | /* sync_file_range always requires a blocking context */ |
| 2126 | 2120 | if (force_nonblock) { |
| @@ -2149,19 +2143,23 @@ static void io_sendrecv_async(struct io_wq_work **workptr) · 22 unmodified lines | ||
| 2149 | 2143 | } |
| 2150 | 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 | 2148 | #if defined(CONFIG_NET) |
| 2155 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2156 | − struct user_msghdr __user *msg; | |
| 2157 | − unsigned flags; | |
| 2149 | + struct io_sr_msg *sr = &req->sr_msg; | |
| 2150 | + struct io_async_ctx *io = req->io; | |
| 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 | 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 | 2161 | #else |
| 2164 | − return 0; | |
| 2162 | + return -EOPNOTSUPP; | |
| 2165 | 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 | 2167 | bool force_nonblock) |
| 2170 | 2168 | { |
| 2171 | 2169 | #if defined(CONFIG_NET) |
| 2172 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2173 | 2170 | struct io_async_msghdr *kmsg = NULL; |
| 2174 | 2171 | struct socket *sock; |
| 2175 | 2172 | int ret; |
| @@ -2183,12 +2180,6 @@ static int io_sendmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 7 unmodified lines | ||
| 2183 | 2180 | struct sockaddr_storage addr; |
| 2184 | 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 | 2183 | if (req->io) { |
| 2193 | 2184 | kmsg = &req->io->msg; |
| 2194 | 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 | 2188 | kmsg->iov = kmsg->fast_iov; |
| 2198 | 2189 | kmsg->msg.msg_iter.iov = kmsg->iov; |
| 2199 | 2190 | } else { |
| 2191 | + struct io_sr_msg *sr = &req->sr_msg; | |
| 2192 | + | |
| 2200 | 2193 | kmsg = &io.msg; |
| 2201 | 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 | 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 | 2209 | ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags); |
| 2208 | 2210 | if (force_nonblock && ret == -EAGAIN) { |
| 2209 | 2211 | if (req->io) |
| @@ -2218,7 +2220,6 @@ static int io_sendmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 8 unmodified lines | ||
| 2218 | 2220 | ret = -EINTR; |
| 2219 | 2221 | } |
| 2220 | 2222 | |
| 2221 | −out: | |
| 2222 | 2223 | if (!io_wq_current_is_worker() && kmsg && kmsg->iov != kmsg->fast_iov) |
| 2223 | 2224 | kfree(kmsg->iov); |
| 2224 | 2225 | io_cqring_add_event(req, ret); |
| @@ -2231,20 +2232,24 @@ out: · 6 unmodified lines | ||
| 2231 | 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 | 2238 | #if defined(CONFIG_NET) |
| 2237 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2238 | − struct user_msghdr __user *msg; | |
| 2239 | − unsigned flags; | |
| 2239 | + struct io_sr_msg *sr = &req->sr_msg; | |
| 2240 | + struct io_async_ctx *io = req->io; | |
| 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 | 2248 | io->msg.iov = io->msg.fast_iov; |
| 2244 | − return recvmsg_copy_msghdr(&io->msg.msg, msg, flags, &io->msg.uaddr, | |
| 2245 | − &io->msg.iov); | |
| 2249 | + return recvmsg_copy_msghdr(&io->msg.msg, sr->msg, sr->msg_flags, | |
| 2250 | + &io->msg.uaddr, &io->msg.iov); | |
| 2246 | 2251 | #else |
| 2247 | − return 0; | |
| 2252 | + return -EOPNOTSUPP; | |
| 2248 | 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 | 2257 | bool force_nonblock) |
| 2253 | 2258 | { |
| 2254 | 2259 | #if defined(CONFIG_NET) |
| 2255 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2256 | 2260 | struct io_async_msghdr *kmsg = NULL; |
| 2257 | 2261 | struct socket *sock; |
| 2258 | 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 | 2267 | sock = sock_from_file(req->file, &ret); |
| 2264 | 2268 | if (sock) { |
| 2265 | − struct user_msghdr __user *msg; | |
| 2266 | 2269 | struct io_async_ctx io; |
| 2267 | 2270 | struct sockaddr_storage addr; |
| 2268 | 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 | 2273 | if (req->io) { |
| 2279 | 2274 | kmsg = &req->io->msg; |
| 2280 | 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 | 2278 | kmsg->iov = kmsg->fast_iov; |
| 2284 | 2279 | kmsg->msg.msg_iter.iov = kmsg->iov; |
| 2285 | 2280 | } else { |
| 2281 | + struct io_sr_msg *sr = &req->sr_msg; | |
| 2282 | + | |
| 2286 | 2283 | kmsg = &io.msg; |
| 2287 | 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 | 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 | 2302 | if (force_nonblock && ret == -EAGAIN) { |
| 2295 | 2303 | if (req->io) |
| 2296 | 2304 | return -EAGAIN; |
| @@ -2304,7 +2312,6 @@ static int io_recvmsg(struct io_kiocb *req, struct io_kiocb **nxt, · 7 unmodified lines | ||
| 2304 | 2312 | ret = -EINTR; |
| 2305 | 2313 | } |
| 2306 | 2314 | |
| 2307 | −out: | |
| 2308 | 2315 | if (!io_wq_current_is_worker() && kmsg && kmsg->iov != kmsg->fast_iov) |
| 2309 | 2316 | kfree(kmsg->iov); |
| 2310 | 2317 | io_cqring_add_event(req, ret); |
| @@ -2317,25 +2324,19 @@ out: · 6 unmodified lines | ||
| 2317 | 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 | 2329 | #if defined(CONFIG_NET) |
| 2323 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2324 | 2330 | struct io_accept *accept = &req->accept; |
| 2325 | 2331 | |
| 2326 | − if (req->flags & REQ_F_PREPPED) | |
| 2327 | − return 0; | |
| 2328 | − | |
| 2329 | 2332 | if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) |
| 2330 | 2333 | return -EINVAL; |
| 2331 | 2334 | if (sqe->ioprio || sqe->len || sqe->buf_index) |
| 2332 | 2335 | return -EINVAL; |
| 2333 | 2336 | |
| 2334 | − accept->addr = (struct sockaddr __user *) | |
| 2335 | − (unsigned long) READ_ONCE(sqe->addr); | |
| 2336 | − accept->addr_len = (int __user *) (unsigned long) READ_ONCE(sqe->addr2); | |
| 2337 | + accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); | |
| 2338 | + accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2)); | |
| 2337 | 2339 | accept->flags = READ_ONCE(sqe->accept_flags); |
| 2338 | − req->flags |= REQ_F_PREPPED; | |
| 2339 | 2340 | return 0; |
| 2340 | 2341 | #else |
| 2341 | 2342 | return -EOPNOTSUPP; |
| @@ -2383,10 +2384,6 @@ static int io_accept(struct io_kiocb *req, struct io_kiocb **nxt, · 41 unmodified lines | ||
| 2383 | 2384 | #if defined(CONFIG_NET) |
| 2384 | 2385 | int ret; |
| 2385 | 2386 | |
| 2386 | − ret = io_accept_prep(req); | |
| 2387 | − if (ret) | |
| 2388 | − return ret; | |
| 2389 | − | |
| 2390 | 2387 | ret = __io_accept(req, nxt, force_nonblock); |
| 2391 | 2388 | if (ret == -EAGAIN && force_nonblock) { |
| 2392 | 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 | 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 | 2402 | #if defined(CONFIG_NET) |
| 2406 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2407 | − struct sockaddr __user *addr; | |
| 2408 | − int addr_len; | |
| 2403 | + struct io_connect *conn = &req->connect; | |
| 2404 | + struct io_async_ctx *io = req->io; | |
| 2409 | 2405 | |
| 2410 | − addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr); | |
| 2411 | − addr_len = READ_ONCE(sqe->addr2); | |
| 2412 | − return move_addr_to_kernel(addr, addr_len, &io->connect.address); | |
| 2406 | + if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) | |
| 2407 | + return -EINVAL; | |
| 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 | 2419 | #else |
| 2414 | − return 0; | |
| 2420 | + return -EOPNOTSUPP; | |
| 2415 | 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 | 2425 | bool force_nonblock) |
| 2420 | 2426 | { |
| 2421 | 2427 | #if defined(CONFIG_NET) |
| 2422 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2423 | 2428 | struct io_async_ctx __io, *io; |
| 2424 | 2429 | unsigned file_flags; |
| 2425 | − int addr_len, 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; | |
| 2430 | + int ret; | |
| 2434 | 2431 | |
| 2435 | 2432 | if (req->io) { |
| 2436 | 2433 | io = req->io; |
| 2437 | 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 | 2438 | if (ret) |
| 2440 | 2439 | goto out; |
| 2441 | 2440 | io = &__io; |
| 2442 | 2441 | } |
| 2443 | 2442 | |
| 2444 | − ret = __sys_connect_file(req->file, &io->connect.address, addr_len, | |
| 2445 | − file_flags); | |
| 2443 | + file_flags = force_nonblock ? O_NONBLOCK : 0; | |
| 2444 | + | |
| 2445 | + ret = __sys_connect_file(req->file, &io->connect.address, | |
| 2446 | + req->connect.addr_len, file_flags); | |
| 2446 | 2447 | if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) { |
| 2447 | 2448 | if (req->io) |
| 2448 | 2449 | return -EAGAIN; |
| @@ -2513,12 +2514,9 @@ static int io_poll_cancel(struct io_ring_ctx *ctx, __u64 sqe_addr) · 64 unmodified lines | ||
| 2513 | 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 | 2520 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 2523 | 2521 | return -EINVAL; |
| 2524 | 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 | 2524 | return -EINVAL; |
| 2527 | 2525 | |
| 2528 | 2526 | req->poll.addr = READ_ONCE(sqe->addr); |
| 2529 | − req->flags |= REQ_F_PREPPED; | |
| 2530 | 2527 | return 0; |
| 2531 | 2528 | } |
| 2532 | 2529 | |
| @@ -2540,10 +2537,6 @@ static int io_poll_remove(struct io_kiocb *req) · 7 unmodified lines | ||
| 2540 | 2537 | u64 addr; |
| 2541 | 2538 | int ret; |
| 2542 | 2539 | |
| 2543 | − ret = io_poll_remove_prep(req); | |
| 2544 | − if (ret) | |
| 2545 | − return ret; | |
| 2546 | − | |
| 2547 | 2540 | addr = req->poll.addr; |
| 2548 | 2541 | spin_lock_irq(&ctx->completion_lock); |
| 2549 | 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 | 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 | 2679 | struct io_poll_iocb *poll = &req->poll; |
| 2688 | 2680 | u16 events; |
| 2689 | 2681 | |
| 2690 | − if (req->flags & REQ_F_PREPPED) | |
| 2691 | − return 0; | |
| 2692 | 2682 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 2693 | 2683 | return -EINVAL; |
| 2694 | 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 | 2686 | if (!poll->file) |
| 2697 | 2687 | return -EBADF; |
| 2698 | 2688 | |
| 2699 | − req->flags |= REQ_F_PREPPED; | |
| 2700 | 2689 | events = READ_ONCE(sqe->poll_events); |
| 2701 | 2690 | poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP; |
| 2702 | 2691 | return 0; |
| @@ -2709,11 +2698,6 @@ static int io_poll_add(struct io_kiocb *req, struct io_kiocb **nxt) · 6 unmodified lines | ||
| 2709 | 2698 | struct io_poll_table ipt; |
| 2710 | 2699 | bool cancel = false; |
| 2711 | 2700 | __poll_t mask; |
| 2712 | − int ret; | |
| 2713 | − | |
| 2714 | − ret = io_poll_add_prep(req); | |
| 2715 | − if (ret) | |
| 2716 | − return ret; | |
| 2717 | 2701 | |
| 2718 | 2702 | INIT_IO_WORK(&req->work, io_poll_complete_work); |
| 2719 | 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 | 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 | 2822 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 2842 | 2823 | return -EINVAL; |
| 2843 | 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 | 2829 | if (req->timeout.flags) |
| 2849 | 2830 | return -EINVAL; |
| 2850 | 2831 | |
| 2851 | − req->flags |= REQ_F_PREPPED; | |
| 2852 | 2832 | return 0; |
| 2853 | 2833 | } |
| 2854 | 2834 | |
| @@ -2860,10 +2840,6 @@ static int io_timeout_remove(struct io_kiocb *req) · 5 unmodified lines | ||
| 2860 | 2840 | struct io_ring_ctx *ctx = req->ctx; |
| 2861 | 2841 | int ret; |
| 2862 | 2842 | |
| 2863 | − ret = io_timeout_remove_prep(req); | |
| 2864 | − if (ret) | |
| 2865 | − return ret; | |
| 2866 | − | |
| 2867 | 2843 | spin_lock_irq(&ctx->completion_lock); |
| 2868 | 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 | 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 | 2857 | bool is_timeout_link) |
| 2882 | 2858 | { |
| 2883 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2884 | 2859 | struct io_timeout_data *data; |
| 2885 | 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 | 2869 | if (flags & ~IORING_TIMEOUT_ABS) |
| 2895 | 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 | 2878 | data->req = req; |
| 2899 | 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 | 2893 | static int io_timeout(struct io_kiocb *req) |
| 2914 | 2894 | { |
| 2915 | − const struct io_uring_sqe *sqe = req->sqe; | |
| 2916 | 2895 | unsigned count; |
| 2917 | 2896 | struct io_ring_ctx *ctx = req->ctx; |
| 2918 | 2897 | struct io_timeout_data *data; |
| 2919 | 2898 | struct list_head *entry; |
| 2920 | 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 | 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 | 2905 | * timeout event to be satisfied. If it isn't set, then this is |
| 2935 | 2906 | * a pure timeout request, sequence isn't used. |
| 2936 | 2907 | */ |
| 2937 | − count = READ_ONCE(sqe->off); | |
| 2908 | + count = req->timeout.count; | |
| 2938 | 2909 | if (!count) { |
| 2939 | 2910 | req->flags |= REQ_F_TIMEOUT_NOSEQ; |
| 2940 | 2911 | spin_lock_irq(&ctx->completion_lock); |
| @@ -3052,19 +3023,15 @@ done: · 111 unmodified lines | ||
| 3052 | 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 | 3029 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 3062 | 3030 | return -EINVAL; |
| 3063 | 3031 | if (sqe->flags || sqe->ioprio || sqe->off || sqe->len || |
| 3064 | 3032 | sqe->cancel_flags) |
| 3065 | 3033 | return -EINVAL; |
| 3066 | 3034 | |
| 3067 | − req->flags |= REQ_F_PREPPED; | |
| 3068 | 3035 | req->cancel.addr = READ_ONCE(sqe->addr); |
| 3069 | 3036 | return 0; |
| 3070 | 3037 | } |
| @@ -3072,21 +3039,14 @@ static int io_async_cancel_prep(struct io_kiocb *req) · 1 unmodified line | ||
| 3072 | 3039 | static int io_async_cancel(struct io_kiocb *req, struct io_kiocb **nxt) |
| 3073 | 3040 | { |
| 3074 | 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 | 3043 | io_async_find_and_cancel(ctx, req, req->cancel.addr, nxt, 0); |
| 3082 | 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 | 3050 | ssize_t ret = 0; |
| 3091 | 3051 | |
| 3092 | 3052 | switch (req->opcode) { |
| @@ -3094,61 +3054,47 @@ static int io_req_defer_prep(struct io_kiocb *req) · 1 unmodified line | ||
| 3094 | 3054 | break; |
| 3095 | 3055 | case IORING_OP_READV: |
| 3096 | 3056 | case IORING_OP_READ_FIXED: |
| 3097 | − /* ensure prep does right import */ | |
| 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; | |
| 3057 | + ret = io_read_prep(req, sqe, true); | |
| 3105 | 3058 | break; |
| 3106 | 3059 | case IORING_OP_WRITEV: |
| 3107 | 3060 | case IORING_OP_WRITE_FIXED: |
| 3108 | − /* ensure prep does right import */ | |
| 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; | |
| 3061 | + ret = io_write_prep(req, sqe, true); | |
| 3116 | 3062 | break; |
| 3117 | 3063 | case IORING_OP_POLL_ADD: |
| 3118 | − ret = io_poll_add_prep(req); | |
| 3064 | + ret = io_poll_add_prep(req, sqe); | |
| 3119 | 3065 | break; |
| 3120 | 3066 | case IORING_OP_POLL_REMOVE: |
| 3121 | − ret = io_poll_remove_prep(req); | |
| 3067 | + ret = io_poll_remove_prep(req, sqe); | |
| 3122 | 3068 | break; |
| 3123 | 3069 | case IORING_OP_FSYNC: |
| 3124 | − ret = io_prep_fsync(req); | |
| 3070 | + ret = io_prep_fsync(req, sqe); | |
| 3125 | 3071 | break; |
| 3126 | 3072 | case IORING_OP_SYNC_FILE_RANGE: |
| 3127 | − ret = io_prep_sfr(req); | |
| 3073 | + ret = io_prep_sfr(req, sqe); | |
| 3128 | 3074 | break; |
| 3129 | 3075 | case IORING_OP_SENDMSG: |
| 3130 | − ret = io_sendmsg_prep(req, io); | |
| 3076 | + ret = io_sendmsg_prep(req, sqe); | |
| 3131 | 3077 | break; |
| 3132 | 3078 | case IORING_OP_RECVMSG: |
| 3133 | − ret = io_recvmsg_prep(req, io); | |
| 3079 | + ret = io_recvmsg_prep(req, sqe); | |
| 3134 | 3080 | break; |
| 3135 | 3081 | case IORING_OP_CONNECT: |
| 3136 | − ret = io_connect_prep(req, io); | |
| 3082 | + ret = io_connect_prep(req, sqe); | |
| 3137 | 3083 | break; |
| 3138 | 3084 | case IORING_OP_TIMEOUT: |
| 3139 | − ret = io_timeout_prep(req, io, false); | |
| 3085 | + ret = io_timeout_prep(req, sqe, false); | |
| 3140 | 3086 | break; |
| 3141 | 3087 | case IORING_OP_TIMEOUT_REMOVE: |
| 3142 | − ret = io_timeout_remove_prep(req); | |
| 3088 | + ret = io_timeout_remove_prep(req, sqe); | |
| 3143 | 3089 | break; |
| 3144 | 3090 | case IORING_OP_ASYNC_CANCEL: |
| 3145 | − ret = io_async_cancel_prep(req); | |
| 3091 | + ret = io_async_cancel_prep(req, sqe); | |
| 3146 | 3092 | break; |
| 3147 | 3093 | case IORING_OP_LINK_TIMEOUT: |
| 3148 | − ret = io_timeout_prep(req, io, true); | |
| 3094 | + ret = io_timeout_prep(req, sqe, true); | |
| 3149 | 3095 | break; |
| 3150 | 3096 | case IORING_OP_ACCEPT: |
| 3151 | − ret = io_accept_prep(req); | |
| 3097 | + ret = io_accept_prep(req, sqe); | |
| 3152 | 3098 | break; |
| 3153 | 3099 | default: |
| 3154 | 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 | 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 | 3111 | struct io_ring_ctx *ctx = req->ctx; |
| 3166 | 3112 | int ret; |
| @@ -3169,10 +3115,10 @@ static int io_req_defer(struct io_kiocb *req) · 2 unmodified lines | ||
| 3169 | 3115 | if (!req_need_defer(req) && list_empty(&ctx->defer_list)) |
| 3170 | 3116 | return 0; |
| 3171 | 3117 | |
| 3172 | − if (io_alloc_async_ctx(req)) | |
| 3118 | + if (!req->io && io_alloc_async_ctx(req)) | |
| 3173 | 3119 | return -EAGAIN; |
| 3174 | 3120 | |
| 3175 | − ret = io_req_defer_prep(req); | |
| 3121 | + ret = io_req_defer_prep(req, sqe); | |
| 3176 | 3122 | if (ret < 0) |
| 3177 | 3123 | return ret; |
| 3178 | 3124 | |
| @@ -3188,9 +3134,8 @@ static int io_req_defer(struct io_kiocb *req) · 9 unmodified lines | ||
| 3188 | 3134 | return -EIOCBQUEUED; |
| 3189 | 3135 | } |
| 3190 | 3136 | |
| 3191 | −__attribute__((nonnull)) | |
| 3192 | −static int io_issue_sqe(struct io_kiocb *req, struct io_kiocb **nxt, | |
| 3193 | − bool force_nonblock) | |
| 3137 | +static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, | |
| 3138 | + struct io_kiocb **nxt, bool force_nonblock) | |
| 3194 | 3139 | { |
| 3195 | 3140 | struct io_ring_ctx *ctx = req->ctx; |
| 3196 | 3141 | int ret; |
| @@ -3200,52 +3145,109 @@ static int io_issue_sqe(struct io_kiocb *req, struct io_kiocb **nxt, · 3 unmodified lines | ||
| 3200 | 3145 | ret = io_nop(req); |
| 3201 | 3146 | break; |
| 3202 | 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 | 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 | 3154 | ret = io_read(req, nxt, force_nonblock); |
| 3214 | 3155 | break; |
| 3156 | + case IORING_OP_WRITEV: | |
| 3215 | 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 | 3163 | ret = io_write(req, nxt, force_nonblock); |
| 3217 | 3164 | break; |
| 3218 | 3165 | case IORING_OP_FSYNC: |
| 3166 | + if (sqe) { | |
| 3167 | + ret = io_prep_fsync(req, sqe); | |
| 3168 | + if (ret < 0) | |
| 3169 | + break; | |
| 3170 | + } | |
| 3219 | 3171 | ret = io_fsync(req, nxt, force_nonblock); |
| 3220 | 3172 | break; |
| 3221 | 3173 | case IORING_OP_POLL_ADD: |
| 3174 | + if (sqe) { | |
| 3175 | + ret = io_poll_add_prep(req, sqe); | |
| 3176 | + if (ret) | |
| 3177 | + break; | |
| 3178 | + } | |
| 3222 | 3179 | ret = io_poll_add(req, nxt); |
| 3223 | 3180 | break; |
| 3224 | 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 | 3187 | ret = io_poll_remove(req); |
| 3226 | 3188 | break; |
| 3227 | 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 | 3195 | ret = io_sync_file_range(req, nxt, force_nonblock); |
| 3229 | 3196 | break; |
| 3230 | 3197 | case IORING_OP_SENDMSG: |
| 3198 | + if (sqe) { | |
| 3199 | + ret = io_sendmsg_prep(req, sqe); | |
| 3200 | + if (ret < 0) | |
| 3201 | + break; | |
| 3202 | + } | |
| 3231 | 3203 | ret = io_sendmsg(req, nxt, force_nonblock); |
| 3232 | 3204 | break; |
| 3233 | 3205 | case IORING_OP_RECVMSG: |
| 3206 | + if (sqe) { | |
| 3207 | + ret = io_recvmsg_prep(req, sqe); | |
| 3208 | + if (ret) | |
| 3209 | + break; | |
| 3210 | + } | |
| 3234 | 3211 | ret = io_recvmsg(req, nxt, force_nonblock); |
| 3235 | 3212 | break; |
| 3236 | 3213 | case IORING_OP_TIMEOUT: |
| 3214 | + if (sqe) { | |
| 3215 | + ret = io_timeout_prep(req, sqe, false); | |
| 3216 | + if (ret) | |
| 3217 | + break; | |
| 3218 | + } | |
| 3237 | 3219 | ret = io_timeout(req); |
| 3238 | 3220 | break; |
| 3239 | 3221 | case IORING_OP_TIMEOUT_REMOVE: |
| 3222 | + if (sqe) { | |
| 3223 | + ret = io_timeout_remove_prep(req, sqe); | |
| 3224 | + if (ret) | |
| 3225 | + break; | |
| 3226 | + } | |
| 3240 | 3227 | ret = io_timeout_remove(req); |
| 3241 | 3228 | break; |
| 3242 | 3229 | case IORING_OP_ACCEPT: |
| 3230 | + if (sqe) { | |
| 3231 | + ret = io_accept_prep(req, sqe); | |
| 3232 | + if (ret) | |
| 3233 | + break; | |
| 3234 | + } | |
| 3243 | 3235 | ret = io_accept(req, nxt, force_nonblock); |
| 3244 | 3236 | break; |
| 3245 | 3237 | case IORING_OP_CONNECT: |
| 3238 | + if (sqe) { | |
| 3239 | + ret = io_connect_prep(req, sqe); | |
| 3240 | + if (ret) | |
| 3241 | + break; | |
| 3242 | + } | |
| 3246 | 3243 | ret = io_connect(req, nxt, force_nonblock); |
| 3247 | 3244 | break; |
| 3248 | 3245 | case IORING_OP_ASYNC_CANCEL: |
| 3246 | + if (sqe) { | |
| 3247 | + ret = io_async_cancel_prep(req, sqe); | |
| 3248 | + if (ret) | |
| 3249 | + break; | |
| 3250 | + } | |
| 3249 | 3251 | ret = io_async_cancel(req, nxt); |
| 3250 | 3252 | break; |
| 3251 | 3253 | default: |
| @@ -3289,7 +3291,7 @@ static void io_wq_submit_work(struct io_wq_work **workptr) · 37 unmodified lines | ||
| 3289 | 3291 | req->has_user = (work->flags & IO_WQ_WORK_HAS_MM) != 0; |
| 3290 | 3292 | req->in_async = true; |
| 3291 | 3293 | do { |
| 3292 | − ret = io_issue_sqe(req, &nxt, false); | |
| 3294 | + ret = io_issue_sqe(req, NULL, &nxt, false); | |
| 3293 | 3295 | /* |
| 3294 | 3296 | * We can get EAGAIN for polled IO even though we're |
| 3295 | 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 | 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 | 3363 | struct io_ring_ctx *ctx = req->ctx; |
| 3361 | 3364 | unsigned flags; |
| 3362 | 3365 | int fd, ret; |
| 3363 | 3366 | |
| 3364 | − flags = READ_ONCE(req->sqe->flags); | |
| 3365 | − fd = READ_ONCE(req->sqe->fd); | |
| 3367 | + flags = READ_ONCE(sqe->flags); | |
| 3368 | + fd = READ_ONCE(sqe->fd); | |
| 3366 | 3369 | |
| 3367 | 3370 | if (flags & IOSQE_IO_DRAIN) |
| 3368 | 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 | 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 | 3502 | struct io_kiocb *linked_timeout; |
| 3500 | 3503 | struct io_kiocb *nxt = NULL; |
| @@ -3503,7 +3506,7 @@ static void __io_queue_sqe(struct io_kiocb *req) · 2 unmodified lines | ||
| 3503 | 3506 | again: |
| 3504 | 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 | 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 | 3558 | int ret; |
| 3556 | 3559 | |
| @@ -3560,7 +3563,7 @@ static void io_queue_sqe(struct io_kiocb *req) · 3 unmodified lines | ||
| 3560 | 3563 | } |
| 3561 | 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 | 3567 | if (ret) { |
| 3565 | 3568 | if (ret != -EIOCBQUEUED) { |
| 3566 | 3569 | io_cqring_add_event(req, ret); |
| @@ -3568,7 +3571,7 @@ static void io_queue_sqe(struct io_kiocb *req) · 1 unmodified line | ||
| 3568 | 3571 | io_double_put_req(req); |
| 3569 | 3572 | } |
| 3570 | 3573 | } else |
| 3571 | − __io_queue_sqe(req); | |
| 3574 | + __io_queue_sqe(req, sqe); | |
| 3572 | 3575 | } |
| 3573 | 3576 | |
| 3574 | 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 | 3580 | io_cqring_add_event(req, -ECANCELED); |
| 3578 | 3581 | io_double_put_req(req); |
| 3579 | 3582 | } else |
| 3580 | − io_queue_sqe(req); | |
| 3583 | + io_queue_sqe(req, NULL); | |
| 3581 | 3584 | } |
| 3582 | 3585 | |
| 3583 | 3586 | #define SQE_VALID_FLAGS (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK| \ |
| 3584 | 3587 | IOSQE_IO_HARDLINK) |
| 3585 | 3588 | |
| 3586 | −static bool io_submit_sqe(struct io_kiocb *req, struct io_submit_state *state, | |
| 3587 | − struct io_kiocb **link) | |
| 3589 | +static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, | |
| 3590 | + struct io_submit_state *state, struct io_kiocb **link) | |
| 3588 | 3591 | { |
| 3589 | 3592 | struct io_ring_ctx *ctx = req->ctx; |
| 3590 | 3593 | int ret; |
| 3591 | 3594 | |
| 3592 | 3595 | /* enforce forwards compatibility on users */ |
| 3593 | − if (unlikely(req->sqe->flags & ~SQE_VALID_FLAGS)) { | |
| 3596 | + if (unlikely(sqe->flags & ~SQE_VALID_FLAGS)) { | |
| 3594 | 3597 | ret = -EINVAL; |
| 3595 | 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 | 3602 | if (unlikely(ret)) { |
| 3600 | 3603 | err_req: |
| 3601 | 3604 | io_cqring_add_event(req, ret); |
| @@ -3613,10 +3616,10 @@ err_req: · 11 unmodified lines | ||
| 3613 | 3616 | if (*link) { |
| 3614 | 3617 | struct io_kiocb *prev = *link; |
| 3615 | 3618 | |
| 3616 | − if (req->sqe->flags & IOSQE_IO_DRAIN) | |
| 3619 | + if (sqe->flags & IOSQE_IO_DRAIN) | |
| 3617 | 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 | 3623 | req->flags |= REQ_F_HARDLINK; |
| 3621 | 3624 | |
| 3622 | 3625 | if (io_alloc_async_ctx(req)) { |
| @@ -3624,7 +3627,7 @@ err_req: · 1 unmodified line | ||
| 3624 | 3627 | goto err_req; |
| 3625 | 3628 | } |
| 3626 | 3629 | |
| 3627 | − ret = io_req_defer_prep(req); | |
| 3630 | + ret = io_req_defer_prep(req, sqe); | |
| 3628 | 3631 | if (ret) { |
| 3629 | 3632 | /* fail even hard links since we don't submit */ |
| 3630 | 3633 | prev->flags |= REQ_F_FAIL_LINK; |
| @@ -3632,15 +3635,18 @@ err_req: · 1 unmodified line | ||
| 3632 | 3635 | } |
| 3633 | 3636 | trace_io_uring_link(ctx, req, prev); |
| 3634 | 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 | 3639 | req->flags |= REQ_F_LINK; |
| 3637 | − if (req->sqe->flags & IOSQE_IO_HARDLINK) | |
| 3640 | + if (sqe->flags & IOSQE_IO_HARDLINK) | |
| 3638 | 3641 | req->flags |= REQ_F_HARDLINK; |
| 3639 | 3642 | |
| 3640 | 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 | 3647 | *link = req; |
| 3642 | 3648 | } else { |
| 3643 | − io_queue_sqe(req); | |
| 3649 | + io_queue_sqe(req, sqe); | |
| 3644 | 3650 | } |
| 3645 | 3651 | |
| 3646 | 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 | 3695 | * that is mapped by userspace. This means that care needs to be taken to |
| 3690 | 3696 | * ensure that reads are stable, as we cannot rely on userspace always |
| 3691 | 3697 | * being a good citizen. If members of the sqe are validated and then later |
| 3692 | 3698 | * used, it's important that those reads are done through READ_ONCE() to |
| 3693 | 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 | 3704 | struct io_rings *rings = ctx->rings; |
| 3698 | 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 | 3726 | * link list. |
| 3720 | 3727 | */ |
| 3721 | 3728 | req->sequence = ctx->cached_sq_head; |
| 3722 | − req->sqe = &ctx->sq_sqes[head]; | |
| 3723 | − req->opcode = READ_ONCE(req->sqe->opcode); | |
| 3724 | − req->user_data = READ_ONCE(req->sqe->user_data); | |
| 3729 | + *sqe_ptr = &ctx->sq_sqes[head]; | |
| 3730 | + req->opcode = READ_ONCE((*sqe_ptr)->opcode); | |
| 3731 | + req->user_data = READ_ONCE((*sqe_ptr)->user_data); | |
| 3725 | 3732 | ctx->cached_sq_head++; |
| 3726 | 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 | 3762 | for (i = 0; i < nr; i++) { |
| 3763 | + const struct io_uring_sqe *sqe; | |
| 3756 | 3764 | struct io_kiocb *req; |
| 3757 | 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 | 3770 | submitted = -EAGAIN; |
| 3763 | 3771 | break; |
| 3764 | 3772 | } |
| 3765 | − if (!io_get_sqring(ctx, req)) { | |
| 3773 | + if (!io_get_sqring(ctx, req, &sqe)) { | |
| 3766 | 3774 | __io_free_req(req); |
| 3767 | 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 | 3786 | submitted++; |
| 3779 | − sqe_flags = req->sqe->flags; | |
| 3787 | + sqe_flags = sqe->flags; | |
| 3780 | 3788 | |
| 3781 | 3789 | req->ring_file = ring_file; |
| 3782 | 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 | 3792 | req->in_async = async; |
| 3785 | 3793 | req->needs_fixed_file = async; |
| 3786 | 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 | 3796 | break; |
| 3789 | 3797 | /* |
| 3790 | 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 | 4710 | if (copy_from_user(&ciov, &ciovs[index], sizeof(ciov))) |
| 4703 | 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 | 4714 | dst->iov_len = ciov.iov_len; |
| 4707 | 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 | 2854 | if (inode) { |
| 2855 | 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 | 2857 | MAJOR(inode->i_sb->s_dev), |
| 2858 | 2858 | MINOR(inode->i_sb->s_dev), inode->i_ino); |
| 2859 | 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 | 63 | bio->bi_end_io = mpage_end_io; |
| 64 | 64 | bio_set_op_attrs(bio, op, op_flags); |
| 65 | − guard_bio_eod(op, bio); | |
| 65 | + guard_bio_eod(bio); | |
| 66 | 66 | submit_bio(bio); |
| 67 | 67 | return NULL; |
| 68 | 68 | } |
| @@ -1728,7 +1728,7 @@ static bool is_mnt_ns_file(struct dentry *dentry) · 1727 unmodified lines | ||
| 1728 | 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 | 1733 | return container_of(ns, struct mnt_namespace, ns); |
| 1734 | 1734 | } |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/pseudo_fs.h> |
| 4 | 4 | #include <linux/file.h> |
| 5 | 5 | #include <linux/fs.h> |
| 6 | +#include <linux/proc_fs.h> | |
| 6 | 7 | #include <linux/proc_ns.h> |
| 7 | 8 | #include <linux/magic.h> |
| 8 | 9 | #include <linux/ktime.h> |
| @@ -11,6 +12,8 @@ · 2 unmodified lines | ||
| 11 | 12 | #include <linux/nsfs.h> |
| 12 | 13 | #include <linux/uaccess.h> |
| 13 | 14 | |
| 15 | +#include "internal.h" | |
| 16 | + | |
| 14 | 17 | static struct vfsmount *nsfs_mnt; |
| 15 | 18 | |
| 16 | 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 | 3283 | debugfs_create_u32("locking_filter", 0600, osb->osb_debug_root, |
| 3284 | 3284 | &dlm_debug->d_filter_secs); |
| 3285 | + ocfs2_get_dlm_debug(dlm_debug); | |
| 3285 | 3286 | } |
| 3286 | 3287 | |
| 3287 | 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 | 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 | 1077 | status = ocfs2_journal_toggle_dirty(osb, 1, replayed); |
| 1070 | 1078 | if (status < 0) { |
| 1071 | 1079 | mlog_errno(status); |
| @@ -631,12 +631,15 @@ EXPORT_SYMBOL_GPL(posix_acl_create); · 630 unmodified lines | ||
| 631 | 631 | |
| 632 | 632 | /** |
| 633 | 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 | 638 | * Update the file mode when setting an ACL: compute the new file permission |
| 636 | 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 | 643 | * or capable of CAP_FSETID (see inode_change_ok). |
| 641 | 644 | * |
| 642 | 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 | 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 | 421 | /* Build header and append record contents. */ |
| 411 | 422 | hlen = ramoops_write_kmsg_hdr(prz, record); |
| 412 | 423 | if (!hlen) |
| @@ -572,6 +583,7 @@ static int ramoops_init_przs(const char *name, · 159 unmodified lines | ||
| 572 | 583 | prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig, |
| 573 | 584 | &cxt->ecc_info, |
| 574 | 585 | cxt->memtype, flags, label); |
| 586 | + kfree(label); | |
| 575 | 587 | if (IS_ERR(prz_ar[i])) { |
| 576 | 588 | err = PTR_ERR(prz_ar[i]); |
| 577 | 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 | 629 | label = kasprintf(GFP_KERNEL, "ramoops:%s", name); |
| 618 | 630 | *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info, |
| 619 | 631 | cxt->memtype, PRZ_FLAG_ZAP_OLD, label); |
| 632 | + kfree(label); | |
| 620 | 633 | if (IS_ERR(*prz)) { |
| 621 | 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 | 574 | /* Initialize general buffer state. */ |
| 575 | 575 | raw_spin_lock_init(&prz->buffer_lock); |
| 576 | 576 | prz->flags = flags; |
| 577 | − prz->label = label; | |
| 577 | + prz->label = kstrdup(label, GFP_KERNEL); | |
| 578 | 578 | |
| 579 | 579 | ret = persistent_ram_buffer_map(start, size, prz, memtype); |
| 580 | 580 | if (ret) |
| @@ -19,6 +19,8 @@ struct ahci_host_priv; · 18 unmodified lines | ||
| 19 | 19 | struct platform_device; |
| 20 | 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 | 24 | int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); |
| 23 | 25 | void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); |
| 24 | 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 | 470 | gfp_t); |
| 471 | 471 | extern int bio_uncopy_user(struct bio *); |
| 472 | 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 | 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 | 156 | #endif /* __LINUX_BVEC_ITER_H */ |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/can/error.h> |
| 19 | 19 | #include <linux/can/led.h> |
| 20 | 20 | #include <linux/can/netlink.h> |
| 21 | +#include <linux/can/skb.h> | |
| 21 | 22 | #include <linux/netdevice.h> |
| 22 | 23 | |
| 23 | 24 | /* |
| @@ -91,6 +92,36 @@ struct can_priv { · 67 unmodified lines | ||
| 91 | 92 | #define get_can_dlc(i) (min_t(__u8, (i), CAN_MAX_DLC)) |
| 92 | 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 | 125 | /* Drop a given socketbuffer if it does not contain a valid CAN frame. */ |
| 95 | 126 | static inline bool can_dropped_invalid_skb(struct net_device *dev, |
| 96 | 127 | struct sk_buff *skb) |
| @@ -108,6 +139,9 @@ static inline bool can_dropped_invalid_skb(struct net_device *dev, · 11 unmodified lines | ||
| 108 | 139 | } else |
| 109 | 140 | goto inval_skb; |
| 110 | 141 | |
| 142 | + if (!can_skb_headroom_valid(dev, skb)) | |
| 143 | + goto inval_skb; | |
| 144 | + | |
| 111 | 145 | return false; |
| 112 | 146 | |
| 113 | 147 | inval_skb: |
| @@ -1364,8 +1364,11 @@ static inline int dma_get_slave_caps(struct dma_chan *chan, · 1363 unmodified lines | ||
| 1364 | 1364 | static inline int dmaengine_desc_set_reuse(struct dma_async_tx_descriptor *tx) |
| 1365 | 1365 | { |
| 1366 | 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 | 1373 | if (caps.descriptor_reuse) { |
| 1371 | 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 | 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 | 35 | static inline struct ethhdr *inner_eth_hdr(const struct sk_buff *skb) |
| 28 | 36 | { |
| 29 | 37 | return (struct ethhdr *)skb_inner_mac_header(skb); |
| @@ -79,15 +79,6 @@ · 78 unmodified lines | ||
| 79 | 79 | */ |
| 80 | 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 | 82 | #define typeof_member(T, m) typeof(((T*)0)->m) |
| 92 | 83 | |
| 93 | 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 | 1175 | struct ata_taskfile *tf, u16 *id); |
| 1176 | 1176 | extern void ata_qc_complete(struct ata_queued_cmd *qc); |
| 1177 | 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 | 1179 | extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd); |
| 1179 | 1180 | extern int ata_std_bios_param(struct scsi_device *sdev, |
| 1180 | 1181 | struct block_device *bdev, |
| @@ -122,8 +122,8 @@ static inline bool movable_node_is_enabled(void) · 121 unmodified lines | ||
| 122 | 122 | |
| 123 | 123 | extern void arch_remove_memory(int nid, u64 start, u64 size, |
| 124 | 124 | struct vmem_altmap *altmap); |
| 125 | −extern void __remove_pages(struct zone *zone, unsigned long start_pfn, | |
| 126 | − unsigned long nr_pages, struct vmem_altmap *altmap); | |
| 125 | +extern void __remove_pages(unsigned long start_pfn, unsigned long nr_pages, | |
| 126 | + struct vmem_altmap *altmap); | |
| 127 | 127 | |
| 128 | 128 | /* reasonably generic interface to expand the physical pages */ |
| 129 | 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 | 342 | extern int add_memory_resource(int nid, struct resource *resource); |
| 343 | 343 | extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, |
| 344 | 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 | 348 | extern bool is_memblock_offlined(struct memory_block *mem); |
| 346 | 349 | extern int sparse_add_section(int nid, unsigned long pfn, |
| 347 | 350 | unsigned long nr_pages, struct vmem_altmap *altmap); |
| @@ -46,6 +46,14 @@ · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 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 | 57 | #define RTC_PDN2 0x002e |
| 50 | 58 | #define RTC_PDN2_PWRON_ALARM BIT(4) |
| 51 | 59 | |
| @@ -40,7 +40,7 @@ typedef enum { · 39 unmodified lines | ||
| 40 | 40 | FL_READING, |
| 41 | 41 | FL_CACHEDPRG, |
| 42 | 42 | /* These 4 come from onenand_state_t, which has been unified here */ |
| 43 | − FL_RESETING, | |
| 43 | + FL_RESETTING, | |
| 44 | 44 | FL_OTPING, |
| 45 | 45 | FL_PREPARING_ERASE, |
| 46 | 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 | 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 | 60 | return false; |
| 61 | 61 | } |
| @@ -69,29 +69,32 @@ struct posix_clock_operations { · 68 unmodified lines | ||
| 69 | 69 | * |
| 70 | 70 | * @ops: Functional interface to the clock |
| 71 | 71 | * @cdev: Character device instance for this clock |
| 72 | − * @kref: Reference count. | |
| 72 | + * @dev: Pointer to the clock's device. | |
| 73 | 73 | * @rwsem: Protects the 'zombie' field from concurrent access. |
| 74 | 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 | 76 | * Drivers should embed their struct posix_clock within a private |
| 79 | 77 | * structure, obtaining a reference to it during callbacks using |
| 80 | 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 | 85 | struct posix_clock { |
| 83 | 86 | struct posix_clock_operations ops; |
| 84 | 87 | struct cdev cdev; |
| 85 | − struct kref kref; | |
| 88 | + struct device *dev; | |
| 86 | 89 | struct rw_semaphore rwsem; |
| 87 | 90 | bool zombie; |
| 88 | − void (*release)(struct posix_clock *clk); | |
| 89 | 91 | }; |
| 90 | 92 | |
| 91 | 93 | /** |
| 92 | 94 | * posix_clock_register() - register a new clock |
| 93 | − * @clk: Pointer to the clock. Caller must provide 'ops' and 'release' | |
| 94 | − * @devid: Allocated device id | |
| 95 | + * @clk: Pointer to the clock. Caller must provide 'ops' field | |
| 96 | + * @dev: Pointer to the initialized device. Caller must provide | |
| 97 | + * 'release' field | |
| 95 | 98 | * |
| 96 | 99 | * A clock driver calls this function to register itself with the |
| 97 | 100 | * clock device subsystem. If 'clk' points to dynamically allocated |
| @@ -100,7 +103,7 @@ struct posix_clock { · 2 unmodified lines | ||
| 100 | 103 | * |
| 101 | 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 | 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 | 689 | /* Helper calls for driver to timestamp transfer */ |
| 690 | 690 | void spi_take_timestamp_pre(struct spi_controller *ctlr, |
| 691 | 691 | struct spi_transfer *xfer, |
| 692 | − const void *tx, bool irqs_off); | |
| 692 | + size_t progress, bool irqs_off); | |
| 693 | 693 | void spi_take_timestamp_post(struct spi_controller *ctlr, |
| 694 | 694 | struct spi_transfer *xfer, |
| 695 | − const void *tx, bool irqs_off); | |
| 695 | + size_t progress, bool irqs_off); | |
| 696 | 696 | |
| 697 | 697 | /* the spi driver core manages memory for the spi_controller classdev */ |
| 698 | 698 | extern struct spi_controller *__spi_alloc_controller(struct device *host, |
| @@ -1,6 +1,6 @@ | ||
| 1 | 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 | 5 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. |
| 6 | 6 | * http://www.samsung.com |
| @@ -1232,6 +1232,7 @@ asmlinkage long sys_ni_syscall(void); · 1231 unmodified lines | ||
| 1232 | 1232 | */ |
| 1233 | 1233 | |
| 1234 | 1234 | int ksys_umount(char __user *name, int flags); |
| 1235 | +int ksys_dup(unsigned int fildes); | |
| 1235 | 1236 | int ksys_chroot(const char __user *filename); |
| 1236 | 1237 | ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); |
| 1237 | 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 | 516 | struct dst_entry *dst = skb_dst(skb); |
| 517 | 517 | |
| 518 | 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 | 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 | 535 | u32 encap_mtu = dst_mtu(encap_dst); |
| 527 | 536 | |
| 528 | 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 | 541 | #endif /* _NET_DST_H */ |
| @@ -27,7 +27,8 @@ struct dst_ops { · 26 unmodified lines | ||
| 27 | 27 | struct dst_entry * (*negative_advice)(struct dst_entry *); |
| 28 | 28 | void (*link_failure)(struct sk_buff *); |
| 29 | 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 | 32 | void (*redirect)(struct dst_entry *dst, struct sock *sk, |
| 32 | 33 | struct sk_buff *skb); |
| 33 | 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 | 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 | 116 | struct nf_flow_route { |
| 111 | 117 | struct { |
| @@ -308,6 +308,7 @@ struct tcf_proto_ops { · 307 unmodified lines | ||
| 308 | 308 | int (*delete)(struct tcf_proto *tp, void *arg, |
| 309 | 309 | bool *last, bool rtnl_held, |
| 310 | 310 | struct netlink_ext_ack *); |
| 311 | + bool (*delete_empty)(struct tcf_proto *tp); | |
| 311 | 312 | void (*walk)(struct tcf_proto *tp, |
| 312 | 313 | struct tcf_walker *arg, bool rtnl_held); |
| 313 | 314 | int (*reoffload)(struct tcf_proto *tp, bool add, |
| @@ -336,6 +337,10 @@ struct tcf_proto_ops { · 22 unmodified lines | ||
| 336 | 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 | 344 | enum tcf_proto_ops_flags { |
| 340 | 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 | |
| 8 | −#define _ASM_RISCV_SIFIVE_L2_CACHE_H | |
| 7 | +#ifndef __SOC_SIFIVE_L2_CACHE_H | |
| 8 | +#define __SOC_SIFIVE_L2_CACHE_H | |
| 9 | 9 | |
| 10 | 10 | extern int register_sifive_l2_error_notifier(struct notifier_block *nb); |
| 11 | 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 | 13 | #define SIFIVE_L2_ERR_TYPE_CE 0 |
| 14 | 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 | 18 | TP_ARGS(ip, parent_ip), |
| 19 | 19 | |
| 20 | 20 | TP_STRUCT__entry( |
| 21 | − __field(u32, caller_offs) | |
| 22 | − __field(u32, parent_offs) | |
| 21 | + __field(s32, caller_offs) | |
| 22 | + __field(s32, parent_offs) | |
| 23 | 23 | ), |
| 24 | 24 | |
| 25 | 25 | TP_fast_assign( |
| 26 | − __entry->caller_offs = (u32)(ip - (unsigned long)_stext); | |
| 27 | − __entry->parent_offs = (u32)(parent_ip - (unsigned long)_stext); | |
| 26 | + __entry->caller_offs = (s32)(ip - (unsigned long)_stext); | |
| 27 | + __entry->parent_offs = (s32)(parent_ip - (unsigned long)_stext); | |
| 28 | 28 | ), |
| 29 | 29 | |
| 30 | 30 | TP_printk("caller=%pS parent=%pS", |
| @@ -34,6 +34,7 @@ struct input_event { · 33 unmodified lines | ||
| 34 | 34 | __kernel_ulong_t __sec; |
| 35 | 35 | #if defined(__sparc__) && defined(__arch64__) |
| 36 | 36 | unsigned int __usec; |
| 37 | + unsigned int __pad; | |
| 37 | 38 | #else |
| 38 | 39 | __kernel_ulong_t __usec; |
| 39 | 40 | #endif |
| @@ -9,11 +9,11 @@ · 8 unmodified lines | ||
| 9 | 9 | * and the comment before kcov_remote_start() for usage details. |
| 10 | 10 | */ |
| 11 | 11 | struct kcov_remote_arg { |
| 12 | − unsigned int trace_mode; /* KCOV_TRACE_PC or KCOV_TRACE_CMP */ | |
| 13 | − unsigned int area_size; /* Length of coverage buffer in words */ | |
| 14 | − unsigned int num_handles; /* Size of handles array */ | |
| 15 | − __u64 common_handle; | |
| 16 | − __u64 handles[0]; | |
| 12 | + __u32 trace_mode; /* KCOV_TRACE_PC or KCOV_TRACE_CMP */ | |
| 13 | + __u32 area_size; /* Length of coverage buffer in words */ | |
| 14 | + __u32 num_handles; /* Size of handles array */ | |
| 15 | + __aligned_u64 common_handle; | |
| 16 | + __aligned_u64 handles[0]; | |
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | 19 | #define KCOV_REMOTE_MAX_HANDLES 0x100 |
| @@ -93,7 +93,6 @@ · 92 unmodified lines | ||
| 93 | 93 | #include <linux/rodata_test.h> |
| 94 | 94 | #include <linux/jump_label.h> |
| 95 | 95 | #include <linux/mem_encrypt.h> |
| 96 | −#include <linux/file.h> | |
| 97 | 96 | |
| 98 | 97 | #include <asm/io.h> |
| 99 | 98 | #include <asm/bugs.h> |
| @@ -1158,26 +1157,13 @@ static int __ref kernel_init(void *unused) · 1058 unmodified lines | ||
| 1158 | 1157 | |
| 1159 | 1158 | void console_on_rootfs(void) |
| 1160 | 1159 | { |
| 1161 | − struct file *file; | |
| 1162 | − unsigned int i; | |
| 1163 | − | |
| 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; | |
| 1160 | + /* Open the /dev/console as stdin, this should never fail */ | |
| 1161 | + if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) | |
| 1162 | + pr_err("Warning: unable to open an initial console.\n"); | |
| 1176 | 1163 | |
| 1177 | −err_out: | |
| 1178 | − /* no panic -- this might not be fatal */ | |
| 1179 | − pr_err("Warning: unable to open an initial console.\n"); | |
| 1180 | − return; | |
| 1164 | + /* create stdout/stderr */ | |
| 1165 | + (void) ksys_dup(0); | |
| 1166 | + (void) ksys_dup(0); | |
| 1181 | 1167 | } |
| 1182 | 1168 | |
| 1183 | 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 | 36 | static void cgroup_bpf_release(struct work_struct *work) |
| 37 | 37 | { |
| 38 | − struct cgroup *cgrp = container_of(work, struct cgroup, | |
| 39 | − bpf.release_work); | |
| 38 | + struct cgroup *p, *cgrp = container_of(work, struct cgroup, | |
| 39 | + bpf.release_work); | |
| 40 | 40 | enum bpf_cgroup_storage_type stype; |
| 41 | 41 | struct bpf_prog_array *old_array; |
| 42 | 42 | unsigned int type; |
| @@ -65,6 +65,9 @@ static void cgroup_bpf_release(struct work_struct *work) · 22 unmodified lines | ||
| 65 | 65 | |
| 66 | 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 | 71 | percpu_ref_exit(&cgrp->bpf.refcnt); |
| 69 | 72 | cgroup_put(cgrp); |
| 70 | 73 | } |
| @@ -199,6 +202,7 @@ int cgroup_bpf_inherit(struct cgroup *cgrp) · 128 unmodified lines | ||
| 199 | 202 | */ |
| 200 | 203 | #define NR ARRAY_SIZE(cgrp->bpf.effective) |
| 201 | 204 | struct bpf_prog_array *arrays[NR] = {}; |
| 205 | + struct cgroup *p; | |
| 202 | 206 | int ret, i; |
| 203 | 207 | |
| 204 | 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 | 210 | if (ret) |
| 207 | 211 | return ret; |
| 208 | 212 | |
| 213 | + for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p)) | |
| 214 | + cgroup_bpf_get(p); | |
| 215 | + | |
| 209 | 216 | for (i = 0; i < NR; i++) |
| 210 | 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 | 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 | 913 | /* Mark the unknown part of a register (variable offset or scalar value) as |
| 913 | 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 | 946 | verbose(env, "mark_reg_known_zero(regs, %u)\n", regno); |
| 946 | 947 | /* Something bad happened, let's kill all regs */ |
| 947 | 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 | 950 | return; |
| 950 | 951 | } |
| 951 | 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 | 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 | 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 | 1066 | reg->type = SCALAR_VALUE; |
| 1065 | 1067 | reg->var_off = tnum_unknown; |
| 1066 | 1068 | reg->frameno = 0; |
| 1069 | + reg->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ? | |
| 1070 | + true : false; | |
| 1067 | 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 | 1078 | verbose(env, "mark_reg_unknown(regs, %u)\n", regno); |
| 1075 | 1079 | /* Something bad happened, let's kill all regs except FP */ |
| 1076 | 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 | 1082 | return; |
| 1079 | 1083 | } |
| 1080 | − 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; | |
| 1084 | + __mark_reg_unknown(env, regs + regno); | |
| 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 | 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 | 1098 | verbose(env, "mark_reg_not_init(regs, %u)\n", regno); |
| 1098 | 1099 | /* Something bad happened, let's kill all regs except FP */ |
| 1099 | 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 | 1102 | return; |
| 1102 | 1103 | } |
| 1103 | − __mark_reg_not_init(regs + regno); | |
| 1104 | + __mark_reg_not_init(env, regs + regno); | |
| 1104 | 1105 | } |
| 1105 | 1106 | |
| 1106 | 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 | 3236 | if (state->stack[spi].slot_type[0] == STACK_SPILL && |
| 3236 | 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 | 3239 | for (j = 0; j < BPF_REG_SIZE; j++) |
| 3239 | 3240 | state->stack[spi].slot_type[j] = STACK_MISC; |
| 3240 | 3241 | goto mark; |
| @@ -3892,7 +3893,7 @@ static void __clear_all_pkt_pointers(struct bpf_verifier_env *env, · 651 unmodified lines | ||
| 3892 | 3893 | if (!reg) |
| 3893 | 3894 | continue; |
| 3894 | 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 | 3921 | if (!reg) |
| 3921 | 3922 | continue; |
| 3922 | 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 | 4583 | /* Taint dst register if offset had invalid bounds derived from |
| 4583 | 4584 | * e.g. dead branches. |
| 4584 | 4585 | */ |
| 4585 | − __mark_reg_unknown(dst_reg); | |
| 4586 | + __mark_reg_unknown(env, dst_reg); | |
| 4586 | 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 | 4835 | /* Taint dst register if offset had invalid bounds derived from |
| 4835 | 4836 | * e.g. dead branches. |
| 4836 | 4837 | */ |
| 4837 | − __mark_reg_unknown(dst_reg); | |
| 4838 | + __mark_reg_unknown(env, dst_reg); | |
| 4838 | 4839 | return 0; |
| 4839 | 4840 | } |
| 4840 | 4841 | |
| 4841 | 4842 | if (!src_known && |
| 4842 | 4843 | opcode != BPF_ADD && opcode != BPF_SUB && opcode != BPF_AND) { |
| 4843 | − __mark_reg_unknown(dst_reg); | |
| 4844 | + __mark_reg_unknown(env, dst_reg); | |
| 4844 | 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 | 6264 | static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) |
| 6264 | 6265 | { |
| 6265 | 6266 | struct bpf_reg_state *regs = cur_regs(env); |
| 6267 | + static const int ctx_reg = BPF_REG_6; | |
| 6266 | 6268 | u8 mode = BPF_MODE(insn->code); |
| 6267 | 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 | 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 | 6302 | if (err) |
| 6301 | 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 | 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 | 6321 | verbose(env, |
| 6320 | 6322 | "at the time of BPF_LD_ABS|IND R6 != pointer to skb\n"); |
| 6321 | 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 | 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 | 6337 | /* reset caller saved regs to unreadable */ |
| 6332 | 6338 | for (i = 0; i < CALLER_SAVED_REGS; i++) { |
| 6333 | 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 | 6988 | /* since the register is unused, clear its state |
| 6983 | 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 | 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 | 6996 | /* liveness must not touch this stack slot anymore */ |
| 6991 | 6997 | st->stack[i].spilled_ptr.live |= REG_LIVE_DONE; |
| 6992 | 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 | 7000 | for (j = 0; j < BPF_REG_SIZE; j++) |
| 6995 | 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 | 223 | new->magic = CRED_MAGIC; |
| 224 | 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 | 227 | goto error; |
| 228 | 228 | |
| 229 | 229 | return new; |
| @@ -282,7 +282,7 @@ struct cred *prepare_creds(void) · 52 unmodified lines | ||
| 282 | 282 | new->security = NULL; |
| 283 | 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 | 286 | goto error; |
| 287 | 287 | validate_creds(new); |
| 288 | 288 | return new; |
| @@ -715,7 +715,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) · 426 unmodified lines | ||
| 715 | 715 | #ifdef CONFIG_SECURITY |
| 716 | 716 | new->security = NULL; |
| 717 | 717 | #endif |
| 718 | − if (security_prepare_creds(new, old, GFP_KERNEL) < 0) | |
| 718 | + if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0) | |
| 719 | 719 | goto error; |
| 720 | 720 | |
| 721 | 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 | 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 | 521 | list_for_each_entry_safe(p, n, dead, ptrace_entry) { |
| 526 | 522 | list_del_init(&p->ptrace_entry); |
| @@ -766,6 +762,14 @@ void __noreturn do_exit(long code) · 239 unmodified lines | ||
| 766 | 762 | acct_update_integrals(tsk); |
| 767 | 763 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
| 768 | 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 | 773 | #ifdef CONFIG_POSIX_TIMERS |
| 770 | 774 | hrtimer_cancel(&tsk->signal->real_timer); |
| 771 | 775 | exit_itimers(tsk->signal); |
| @@ -2578,6 +2578,16 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, · 2577 unmodified lines | ||
| 2578 | 2578 | #endif |
| 2579 | 2579 | |
| 2580 | 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 | 2591 | noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, |
| 2582 | 2592 | struct clone_args __user *uargs, |
| 2583 | 2593 | size_t usize) |
| @@ -1026,6 +1026,13 @@ static long seccomp_notify_recv(struct seccomp_filter *filter, · 1025 unmodified lines | ||
| 1026 | 1026 | struct seccomp_notif unotif; |
| 1027 | 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 | 1036 | memset(&unotif, 0, sizeof(unotif)); |
| 1030 | 1037 | |
| 1031 | 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 | 554 | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) |
| 555 | 555 | { |
| 556 | 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)) | |
| 560 | − goto ret; | |
| 559 | + /* Pairs with smp_store_release() below. */ | |
| 560 | + stats = smp_load_acquire(&sig->stats); | |
| 561 | + if (stats || thread_group_empty(tsk)) | |
| 562 | + return stats; | |
| 561 | 563 | |
| 562 | 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 | 567 | spin_lock_irq(&tsk->sighand->siglock); |
| 566 | − if (!sig->stats) { | |
| 567 | − sig->stats = stats; | |
| 568 | − stats = NULL; | |
| 568 | + stats = sig->stats; | |
| 569 | + if (!stats) { | |
| 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 | 578 | spin_unlock_irq(&tsk->sighand->siglock); |
| 571 | 579 | |
| 572 | − if (stats) | |
| 573 | − kmem_cache_free(taskstats_cache, stats); | |
| 574 | −ret: | |
| 575 | − return sig->stats; | |
| 580 | + if (stats_new) | |
| 581 | + kmem_cache_free(taskstats_cache, stats_new); | |
| 582 | + | |
| 583 | + return stats; | |
| 576 | 584 | } |
| 577 | 585 | |
| 578 | 586 | /* Send pid data out on exit */ |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #include "posix-timers.h" |
| 16 | 16 | |
| 17 | −static void delete_clock(struct kref *kref); | |
| 18 | − | |
| 19 | 17 | /* |
| 20 | 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 | 123 | err = 0; |
| 126 | 124 | |
| 127 | 125 | if (!err) { |
| 128 | − kref_get(&clk->kref); | |
| 126 | + get_device(clk->dev); | |
| 129 | 127 | fp->private_data = clk; |
| 130 | 128 | } |
| 131 | 129 | out: |
| @@ -141,7 +139,7 @@ static int posix_clock_release(struct inode *inode, struct file *fp) · 9 unmodified lines | ||
| 141 | 139 | if (clk->ops.release) |
| 142 | 140 | err = clk->ops.release(clk); |
| 143 | 141 | |
| 144 | − kref_put(&clk->kref, delete_clock); | |
| 142 | + put_device(clk->dev); | |
| 145 | 143 | |
| 146 | 144 | fp->private_data = NULL; |
| 147 | 145 | |
| @@ -161,38 +159,35 @@ static const struct file_operations posix_clock_file_operations = { · 13 unmodified lines | ||
| 161 | 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 | 164 | int err; |
| 167 | 165 | |
| 168 | − kref_init(&clk->kref); | |
| 169 | 166 | init_rwsem(&clk->rwsem); |
| 170 | 167 | |
| 171 | 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 | 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 | 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 | 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 | 186 | down_write(&clk->rwsem); |
| 192 | 187 | clk->zombie = true; |
| 193 | 188 | up_write(&clk->rwsem); |
| 194 | 189 | |
| 195 | − kref_put(&clk->kref, delete_clock); | |
| 190 | + put_device(clk->dev); | |
| 196 | 191 | } |
| 197 | 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 | 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 | 113 | int function_graph_enter(unsigned long ret, unsigned long func, |
| 100 | 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 | 528 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 529 | − avg = rec->time; | |
| 530 | − do_div(avg, rec->counter); | |
| 529 | + avg = div64_ul(rec->time, rec->counter); | |
| 531 | 530 | if (tracing_thresh && (avg < tracing_thresh)) |
| 532 | 531 | goto out; |
| 533 | 532 | #endif |
| @@ -553,7 +552,8 @@ static int function_stat_show(struct seq_file *m, void *v) · 19 unmodified lines | ||
| 553 | 552 | * Divide only 1000 for ns^2 -> us^2 conversion. |
| 554 | 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 | 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 | 195 | unsigned long irq_flags; |
| 196 | 196 | void *entry = NULL; |
| 197 | 197 | int entry_size; |
| 198 | − u64 val; | |
| 198 | + u64 val = 0; | |
| 199 | 199 | int len; |
| 200 | 200 | |
| 201 | 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 | 630 | if (ret) { |
| 631 | 631 | pr_info("wakeup trace: Couldn't activate tracepoint" |
| 632 | 632 | " probe to kernel_sched_migrate_task\n"); |
| 633 | − return; | |
| 633 | + goto fail_deprobe_sched_switch; | |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | 636 | wakeup_reset(tr); |
| @@ -648,6 +648,8 @@ static void start_wakeup_tracer(struct trace_array *tr) · 11 unmodified lines | ||
| 648 | 648 | printk(KERN_ERR "failed to start wakeup tracer\n"); |
| 649 | 649 | |
| 650 | 650 | return; |
| 651 | +fail_deprobe_sched_switch: | |
| 652 | + unregister_trace_sched_switch(probe_wakeup_sched_switch, NULL); | |
| 651 | 653 | fail_deprobe_wake_new: |
| 652 | 654 | unregister_trace_sched_wakeup_new(probe_wakeup, NULL); |
| 653 | 655 | fail_deprobe: |
| @@ -381,7 +381,7 @@ int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, · 380 unmodified lines | ||
| 381 | 381 | int prefix_type, int rowsize, int groupsize, |
| 382 | 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 | 386 | if (s->full) |
| 387 | 387 | return 0; |
| @@ -283,6 +283,11 @@ static void check_stack(unsigned long ip, unsigned long *stack) · 282 unmodified lines | ||
| 283 | 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 | 291 | static void |
| 287 | 292 | stack_trace_call(unsigned long ip, unsigned long parent_ip, |
| 288 | 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 | 26 | unsigned long i, nr_pages, addr, next; |
| 27 | 27 | int nr; |
| 28 | 28 | struct page **pages; |
| 29 | + int ret = 0; | |
| 29 | 30 | |
| 30 | 31 | if (gup->size > ULONG_MAX) |
| 31 | 32 | return -EINVAL; |
| @@ -63,7 +64,9 @@ static int __gup_benchmark_ioctl(unsigned int cmd, · 31 unmodified lines | ||
| 63 | 64 | NULL); |
| 64 | 65 | break; |
| 65 | 66 | default: |
| 66 | − return -1; | |
| 67 | + kvfree(pages); | |
| 68 | + ret = -EINVAL; | |
| 69 | + goto out; | |
| 67 | 70 | } |
| 68 | 71 | |
| 69 | 72 | if (nr <= 0) |
| @@ -85,7 +88,8 @@ static int __gup_benchmark_ioctl(unsigned int cmd, · 15 unmodified lines | ||
| 85 | 88 | gup->put_delta_usec = ktime_us_delta(end_time, start_time); |
| 86 | 89 | |
| 87 | 90 | kvfree(pages); |
| 88 | − return 0; | |
| 91 | +out: | |
| 92 | + return ret; | |
| 89 | 93 | } |
| 90 | 94 | |
| 91 | 95 | static long gup_benchmark_ioctl(struct file *filep, unsigned int cmd, |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/swapops.h> |
| 28 | 28 | #include <linux/jhash.h> |
| 29 | 29 | #include <linux/numa.h> |
| 30 | +#include <linux/llist.h> | |
| 30 | 31 | |
| 31 | 32 | #include <asm/page.h> |
| 32 | 33 | #include <asm/pgtable.h> |
| @@ -1136,7 +1137,7 @@ static inline void ClearPageHugeTemporary(struct page *page) · 1103 unmodified lines | ||
| 1136 | 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 | 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 | 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 | 1251 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) |
| 1203 | 1252 | { |
| 1204 | 1253 | INIT_LIST_HEAD(&page->lru); |
| @@ -483,8 +483,9 @@ static void update_pgdat_span(struct pglist_data *pgdat) · 482 unmodified lines | ||
| 483 | 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, | |
| 487 | − unsigned long nr_pages) | |
| 486 | +void __ref remove_pfn_range_from_zone(struct zone *zone, | |
| 487 | + unsigned long start_pfn, | |
| 488 | + unsigned long nr_pages) | |
| 488 | 489 | { |
| 489 | 490 | struct pglist_data *pgdat = zone->zone_pgdat; |
| 490 | 491 | unsigned long flags; |
| @@ -499,28 +500,30 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn, · 8 unmodified lines | ||
| 499 | 500 | return; |
| 500 | 501 | #endif |
| 501 | 502 | |
| 503 | + clear_zone_contiguous(zone); | |
| 504 | + | |
| 502 | 505 | pgdat_resize_lock(zone->zone_pgdat, &flags); |
| 503 | 506 | shrink_zone_span(zone, start_pfn, start_pfn + nr_pages); |
| 504 | 507 | update_pgdat_span(pgdat); |
| 505 | 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, | |
| 509 | − unsigned long nr_pages, unsigned long map_offset, | |
| 510 | − struct vmem_altmap *altmap) | |
| 513 | +static void __remove_section(unsigned long pfn, unsigned long nr_pages, | |
| 514 | + unsigned long map_offset, | |
| 515 | + struct vmem_altmap *altmap) | |
| 511 | 516 | { |
| 512 | 517 | struct mem_section *ms = __nr_to_section(pfn_to_section_nr(pfn)); |
| 513 | 518 | |
| 514 | 519 | if (WARN_ON_ONCE(!valid_section(ms))) |
| 515 | 520 | return; |
| 516 | 521 | |
| 517 | − __remove_zone(zone, pfn, nr_pages); | |
| 518 | 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 | |
| 523 | − * @zone: zone from which pages need to be removed | |
| 526 | + * __remove_pages() - remove sections of pages | |
| 524 | 527 | * @pfn: starting pageframe (must be aligned to start of a section) |
| 525 | 528 | * @nr_pages: number of pages to remove (must be multiple of section size) |
| 526 | 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 | 533 | * sure that pages are marked reserved and zones are adjust properly by |
| 531 | 534 | * calling offline_pages(). |
| 532 | 535 | */ |
| 533 | −void __remove_pages(struct zone *zone, unsigned long pfn, | |
| 534 | − unsigned long nr_pages, struct vmem_altmap *altmap) | |
| 536 | +void __remove_pages(unsigned long pfn, unsigned long nr_pages, | |
| 537 | + struct vmem_altmap *altmap) | |
| 535 | 538 | { |
| 536 | 539 | unsigned long map_offset = 0; |
| 537 | 540 | unsigned long nr, start_sec, end_sec; |
| 538 | 541 | |
| 539 | 542 | map_offset = vmem_altmap_offset(altmap); |
| 540 | 543 | |
| 541 | − clear_zone_contiguous(zone); | |
| 542 | − | |
| 543 | 544 | if (check_pfn_span(pfn, nr_pages, "remove")) |
| 544 | 545 | return; |
| 545 | 546 | |
| @@ -551,13 +552,11 @@ void __remove_pages(struct zone *zone, unsigned long pfn, · 5 unmodified lines | ||
| 551 | 552 | cond_resched(); |
| 552 | 553 | pfns = min(nr_pages, PAGES_PER_SECTION |
| 553 | 554 | - (pfn & ~PAGE_SECTION_MASK)); |
| 554 | − __remove_section(zone, pfn, pfns, map_offset, altmap); | |
| 555 | + __remove_section(pfn, pfns, map_offset, altmap); | |
| 555 | 556 | pfn += pfns; |
| 556 | 557 | nr_pages -= pfns; |
| 557 | 558 | map_offset = 0; |
| 558 | 559 | } |
| 559 | − | |
| 560 | − set_zone_contiguous(zone); | |
| 561 | 560 | } |
| 562 | 561 | |
| 563 | 562 | int set_online_page_callback(online_page_callback_t callback) |
| @@ -869,6 +868,7 @@ failed_addition: · 305 unmodified lines | ||
| 869 | 868 | (unsigned long long) pfn << PAGE_SHIFT, |
| 870 | 869 | (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1); |
| 871 | 870 | memory_notify(MEM_CANCEL_ONLINE, &arg); |
| 871 | + remove_pfn_range_from_zone(zone, pfn, nr_pages); | |
| 872 | 872 | mem_hotplug_done(); |
| 873 | 873 | return ret; |
| 874 | 874 | } |
| @@ -1628,6 +1628,7 @@ static int __ref __offline_pages(unsigned long start_pfn, · 753 unmodified lines | ||
| 1628 | 1628 | writeback_set_ratelimit(); |
| 1629 | 1629 | |
| 1630 | 1630 | memory_notify(MEM_OFFLINE, &arg); |
| 1631 | + remove_pfn_range_from_zone(zone, start_pfn, nr_pages); | |
| 1631 | 1632 | mem_hotplug_done(); |
| 1632 | 1633 | return 0; |
| 1633 | 1634 | |
| @@ -120,7 +120,7 @@ void memunmap_pages(struct dev_pagemap *pgmap) · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | mem_hotplug_begin(); |
| 122 | 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 | 124 | PHYS_PFN(resource_size(res)), NULL); |
| 125 | 125 | } else { |
| 126 | 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 | 1513 | * Resolves the given address to a struct page, isolates it from the LRU and |
| 1514 | 1514 | * puts it to the given pagelist. |
| 1515 | − * Returns -errno if the page cannot be found/isolated or 0 when it has been | |
| 1516 | − * queued or the page doesn't need to be migrated because it is already on | |
| 1517 | − * the target node | |
| 1515 | + * Returns: | |
| 1516 | + * errno - if the page cannot be found/isolated | |
| 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 | 1521 | static int add_page_for_migration(struct mm_struct *mm, unsigned long addr, |
| 1520 | 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 | 1555 | if (PageHuge(page)) { |
| 1554 | 1556 | if (PageHead(page)) { |
| 1555 | 1557 | isolate_huge_page(page, pagelist); |
| 1556 | − err = 0; | |
| 1558 | + err = 1; | |
| 1557 | 1559 | } |
| 1558 | 1560 | } else { |
| 1559 | 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 | 1565 | if (err) |
| 1564 | 1566 | goto out_putpage; |
| 1565 | 1567 | |
| 1566 | − err = 0; | |
| 1568 | + err = 1; | |
| 1567 | 1569 | list_add_tail(&head->lru, pagelist); |
| 1568 | 1570 | mod_node_page_state(page_pgdat(head), |
| 1569 | 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 | 1643 | err = add_page_for_migration(mm, addr, current_node, |
| 1642 | 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 | 1651 | continue; |
| 1652 | + } else if (err > 0) { | |
| 1653 | + /* The page is successfully queued for migration */ | |
| 1654 | + continue; | |
| 1655 | + } | |
| 1645 | 1656 | |
| 1646 | 1657 | err = store_status(status, i, err, 1); |
| 1647 | 1658 | if (err) |
| @@ -90,12 +90,6 @@ static void unmap_region(struct mm_struct *mm, · 89 unmodified lines | ||
| 90 | 90 | * MAP_PRIVATE r: (no) no r: (yes) yes r: (no) yes r: (no) yes |
| 91 | 91 | * w: (no) no w: (no) no w: (copy) copy w: (no) no |
| 92 | 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 | 94 | pgprot_t protection_map[16] __ro_after_init = { |
| 101 | 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 | 890 | K(get_mm_counter(mm, MM_FILEPAGES)), |
| 891 | 891 | K(get_mm_counter(mm, MM_SHMEMPAGES)), |
| 892 | 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 | 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 | 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 | 2077 | reset_page(page); |
| 2073 | 2078 | put_page(page); |
| 2074 | 2079 | page = newpage; |
| @@ -126,6 +126,7 @@ int vlan_check_real_dev(struct net_device *real_dev, · 125 unmodified lines | ||
| 126 | 126 | void vlan_setup(struct net_device *dev); |
| 127 | 127 | int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack); |
| 128 | 128 | void unregister_vlan_dev(struct net_device *dev, struct list_head *head); |
| 129 | +void vlan_dev_uninit(struct net_device *dev); | |
| 129 | 130 | bool vlan_dev_inherit_address(struct net_device *dev, |
| 130 | 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 | 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 | 592 | struct vlan_priority_tci_mapping *pm; |
| 592 | 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 | 108 | struct ifla_vlan_flags *flags; |
| 109 | 109 | struct ifla_vlan_qos_mapping *m; |
| 110 | 110 | struct nlattr *attr; |
| 111 | − int rem; | |
| 111 | + int rem, err; | |
| 112 | 112 | |
| 113 | 113 | if (data[IFLA_VLAN_FLAGS]) { |
| 114 | 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 | 119 | if (data[IFLA_VLAN_INGRESS_QOS]) { |
| 118 | 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 | 125 | if (data[IFLA_VLAN_EGRESS_QOS]) { |
| 124 | 126 | nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) { |
| 125 | 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 | 133 | return 0; |
| @@ -179,10 +183,11 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev, · 49 unmodified lines | ||
| 179 | 183 | return -EINVAL; |
| 180 | 184 | |
| 181 | 185 | err = vlan_changelink(dev, tb, data, extack); |
| 182 | − if (err < 0) | |
| 183 | − return err; | |
| 184 | − | |
| 185 | − return register_vlan_dev(dev, extack); | |
| 186 | + if (!err) | |
| 187 | + err = register_vlan_dev(dev, extack); | |
| 188 | + if (err) | |
| 189 | + vlan_dev_uninit(dev); | |
| 190 | + return err; | |
| 186 | 191 | } |
| 187 | 192 | |
| 188 | 193 | static inline size_t vlan_qos_map_size(unsigned int n) |
| @@ -22,7 +22,8 @@ · 21 unmodified lines | ||
| 22 | 22 | #endif |
| 23 | 23 | |
| 24 | 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 | 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 | 1872 | if (state->buf_kern_start == NULL) |
| 1873 | 1873 | goto count_only; |
| @@ -1901,7 +1901,7 @@ enum compat_mwt { · 27 unmodified lines | ||
| 1901 | 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 | 1905 | enum compat_mwt compat_mwt, |
| 1906 | 1906 | struct ebt_entries_buf_state *state, |
| 1907 | 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 | 1979 | /* return size of all matches, watchers or target, including necessary |
| 1980 | 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 | 1983 | unsigned int size_left, enum compat_mwt type, |
| 1984 | 1984 | struct ebt_entries_buf_state *state, const void *base) |
| 1985 | 1985 | { |
| 1986 | + const char *buf = (const char *)match32; | |
| 1986 | 1987 | int growth = 0; |
| 1987 | − char *buf; | |
| 1988 | 1988 | |
| 1989 | 1989 | if (size_left == 0) |
| 1990 | 1990 | return 0; |
| 1991 | 1991 | |
| 1992 | − buf = (char *) match32; | |
| 1993 | − | |
| 1994 | − while (size_left >= sizeof(*match32)) { | |
| 1992 | + do { | |
| 1995 | 1993 | struct ebt_entry_match *match_kern; |
| 1996 | 1994 | int ret; |
| 1997 | 1995 | |
| 1996 | + if (size_left < sizeof(*match32)) | |
| 1997 | + return -EINVAL; | |
| 1998 | + | |
| 1998 | 1999 | match_kern = (struct ebt_entry_match *) state->buf_kern_start; |
| 1999 | 2000 | if (match_kern) { |
| 2000 | 2001 | char *tmp; |
| @@ -2031,22 +2032,18 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32, · 30 unmodified lines | ||
| 2031 | 2032 | if (match_kern) |
| 2032 | 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 | 2035 | match32 = (struct compat_ebt_entry_mwt *) buf; |
| 2039 | − } | |
| 2036 | + } while (size_left); | |
| 2040 | 2037 | |
| 2041 | 2038 | return growth; |
| 2042 | 2039 | } |
| 2043 | 2040 | |
| 2044 | 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 | 2043 | unsigned int *total, |
| 2047 | 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 | 2047 | /* stores match/watchers/targets & offset of next struct ebt_entry: */ |
| 2051 | 2048 | unsigned int offsets[4]; |
| 2052 | 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 | 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 | 2137 | return -EINVAL; |
| 2139 | − *total -= startoff; | |
| 2138 | + *total -= entry->next_offset; | |
| 2140 | 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 | 110 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); |
| 111 | 111 | static void dn_dst_link_failure(struct sk_buff *); |
| 112 | 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 | 115 | static void dn_dst_redirect(struct dst_entry *dst, struct sock *sk, |
| 115 | 116 | struct sk_buff *skb); |
| 116 | 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 | 252 | * advertise to the other end). |
| 252 | 253 | */ |
| 253 | 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 | 258 | struct dn_route *rt = (struct dn_route *) dst; |
| 257 | 259 | struct neighbour *n = rt->n; |
| @@ -20,6 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | #include "hsr_main.h" |
| 21 | 21 | #include "hsr_framereg.h" |
| 22 | 22 | |
| 23 | +static struct dentry *hsr_debugfs_root_dir; | |
| 24 | + | |
| 23 | 25 | static void print_mac_address(struct seq_file *sfp, unsigned char *mac) |
| 24 | 26 | { |
| 25 | 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 | 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 | 81 | static const struct file_operations hsr_fops = { |
| 67 | − .owner = THIS_MODULE, | |
| 68 | 82 | .open = hsr_node_table_open, |
| 69 | 83 | .read = seq_read, |
| 70 | 84 | .llseek = seq_lseek, |
| @@ -78,15 +92,14 @@ static const struct file_operations hsr_fops = { · 7 unmodified lines | ||
| 78 | 92 | * When debugfs is configured this routine sets up the node_table file per |
| 79 | 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 | 97 | struct dentry *de = NULL; |
| 85 | 98 | |
| 86 | − de = debugfs_create_dir(hsr_dev->name, NULL); | |
| 87 | − if (!de) { | |
| 88 | − pr_err("Cannot create hsr debugfs root\n"); | |
| 89 | − return rc; | |
| 99 | + de = debugfs_create_dir(hsr_dev->name, hsr_debugfs_root_dir); | |
| 100 | + if (IS_ERR(de)) { | |
| 101 | + pr_err("Cannot create hsr debugfs directory\n"); | |
| 102 | + return; | |
| 90 | 103 | } |
| 91 | 104 | |
| 92 | 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 | 107 | de = debugfs_create_file("node_table", S_IFREG | 0444, |
| 95 | 108 | priv->node_tbl_root, priv, |
| 96 | 109 | &hsr_fops); |
| 97 | − if (!de) { | |
| 98 | − pr_err("Cannot create hsr node_table directory\n"); | |
| 99 | − return rc; | |
| 110 | + if (IS_ERR(de)) { | |
| 111 | + pr_err("Cannot create hsr node_table file\n"); | |
| 112 | + debugfs_remove(priv->node_tbl_root); | |
| 113 | + priv->node_tbl_root = NULL; | |
| 114 | + return; | |
| 100 | 115 | } |
| 101 | 116 | priv->node_tbl_file = de; |
| 102 | − | |
| 103 | − return 0; | |
| 104 | 117 | } |
| 105 | 118 | |
| 106 | 119 | /* hsr_debugfs_term - Tear down debugfs intrastructure |
| @@ -117,3 +130,18 @@ hsr_debugfs_term(struct hsr_priv *priv) · 10 unmodified lines | ||
| 117 | 130 | debugfs_remove(priv->node_tbl_root); |
| 118 | 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 | 272 | skb->dev->dev_addr, skb->len) <= 0) |
| 273 | 273 | goto out; |
| 274 | 274 | skb_reset_mac_header(skb); |
| 275 | + skb_reset_network_header(skb); | |
| 276 | + skb_reset_transport_header(skb); | |
| 275 | 277 | |
| 276 | 278 | if (hsr_ver > 0) { |
| 277 | 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 | 370 | del_timer_sync(&hsr->prune_timer); |
| 369 | 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 | 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 | 442 | INIT_LIST_HEAD(&hsr->ports); |
| 441 | 443 | INIT_LIST_HEAD(&hsr->node_db); |
| 442 | 444 | INIT_LIST_HEAD(&hsr->self_node_db); |
| 445 | + spin_lock_init(&hsr->list_lock); | |
| 443 | 446 | |
| 444 | 447 | ether_addr_copy(hsr_dev->dev_addr, slave[0]->dev_addr); |
| 445 | 448 | |
| 446 | 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 | 451 | slave[1]->dev_addr); |
| 449 | 452 | if (res < 0) |
| 450 | 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 | 481 | res = hsr_add_port(hsr, hsr_dev, HSR_PT_MASTER); |
| 479 | 482 | if (res) |
| 480 | − goto err_add_port; | |
| 483 | + goto err_add_master; | |
| 481 | 484 | |
| 482 | 485 | res = register_netdevice(hsr_dev); |
| 483 | 486 | if (res) |
| 484 | − goto fail; | |
| 487 | + goto err_unregister; | |
| 485 | 488 | |
| 486 | 489 | res = hsr_add_port(hsr, slave[0], HSR_PT_SLAVE_A); |
| 487 | 490 | if (res) |
| 488 | − goto fail; | |
| 491 | + goto err_add_slaves; | |
| 492 | + | |
| 489 | 493 | res = hsr_add_port(hsr, slave[1], HSR_PT_SLAVE_B); |
| 490 | 494 | if (res) |
| 491 | − goto fail; | |
| 495 | + goto err_add_slaves; | |
| 492 | 496 | |
| 497 | + hsr_debugfs_init(hsr, hsr_dev); | |
| 493 | 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 | 500 | return 0; |
| 499 | 501 | |
| 500 | −fail: | |
| 502 | +err_add_slaves: | |
| 503 | + unregister_netdevice(hsr_dev); | |
| 504 | +err_unregister: | |
| 501 | 505 | list_for_each_entry_safe(port, tmp, &hsr->ports, port_list) |
| 502 | 506 | hsr_del_port(port); |
| 503 | −err_add_port: | |
| 504 | − hsr_del_self_node(&hsr->self_node_db); | |
| 507 | +err_add_master: | |
| 508 | + hsr_del_self_node(hsr); | |
| 505 | 509 | |
| 506 | 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 | 75 | /* Helper for device init; the self_node_db is used in hsr_rcv() to recognize |
| 76 | 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 | 79 | unsigned char addr_a[ETH_ALEN], |
| 80 | 80 | unsigned char addr_b[ETH_ALEN]) |
| 81 | 81 | { |
| 82 | + struct list_head *self_node_db = &hsr->self_node_db; | |
| 82 | 83 | struct hsr_node *node, *oldnode; |
| 83 | 84 | |
| 84 | 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 | 89 | ether_addr_copy(node->macaddress_A, addr_a); |
| 89 | 90 | ether_addr_copy(node->macaddress_B, addr_b); |
| 90 | 91 | |
| 91 | − rcu_read_lock(); | |
| 92 | + spin_lock_bh(&hsr->list_lock); | |
| 92 | 93 | oldnode = list_first_or_null_rcu(self_node_db, |
| 93 | 94 | struct hsr_node, mac_list); |
| 94 | 95 | if (oldnode) { |
| 95 | 96 | list_replace_rcu(&oldnode->mac_list, &node->mac_list); |
| 96 | − rcu_read_unlock(); | |
| 97 | − synchronize_rcu(); | |
| 98 | − kfree(oldnode); | |
| 97 | + spin_unlock_bh(&hsr->list_lock); | |
| 98 | + kfree_rcu(oldnode, rcu_head); | |
| 99 | 99 | } else { |
| 100 | − rcu_read_unlock(); | |
| 101 | 100 | list_add_tail_rcu(&node->mac_list, self_node_db); |
| 101 | + spin_unlock_bh(&hsr->list_lock); | |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 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 | 110 | struct hsr_node *node; |
| 110 | 111 | |
| 111 | − rcu_read_lock(); | |
| 112 | + spin_lock_bh(&hsr->list_lock); | |
| 112 | 113 | node = list_first_or_null_rcu(self_node_db, struct hsr_node, mac_list); |
| 113 | − rcu_read_unlock(); | |
| 114 | 114 | if (node) { |
| 115 | 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 | 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 | 131 | * seq_out is used to initialize filtering of outgoing duplicate frames |
| 131 | 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 | − u16 seq_out) | |
| 134 | +static struct hsr_node *hsr_add_node(struct hsr_priv *hsr, | |
| 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 | 140 | unsigned long now; |
| 138 | 141 | int i; |
| 139 | 142 | |
| 140 | − node = kzalloc(sizeof(*node), GFP_ATOMIC); | |
| 141 | − if (!node) | |
| 143 | + new_node = kzalloc(sizeof(*new_node), GFP_ATOMIC); | |
| 144 | + if (!new_node) | |
| 142 | 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 | 149 | /* We are only interested in time diffs here, so use current jiffies |
| 147 | 150 | * as initialization. (0 could trigger an spurious ring error warning). |
| 148 | 151 | */ |
| 149 | 152 | now = jiffies; |
| 150 | 153 | for (i = 0; i < HSR_PT_PORTS; i++) |
| 151 | − node->time_in[i] = now; | |
| 154 | + new_node->time_in[i] = now; | |
| 152 | 155 | for (i = 0; i < HSR_PT_PORTS; i++) |
| 153 | − node->seq_out[i] = seq_out; | |
| 154 | − | |
| 155 | − list_add_tail_rcu(&node->mac_list, node_db); | |
| 156 | + new_node->seq_out[i] = seq_out; | |
| 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 | 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 | 177 | bool is_sup) |
| 164 | 178 | { |
| 165 | 179 | struct list_head *node_db = &port->hsr->node_db; |
| 180 | + struct hsr_priv *hsr = port->hsr; | |
| 166 | 181 | struct hsr_node *node; |
| 167 | 182 | struct ethhdr *ethhdr; |
| 168 | 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 | 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 | 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 | 221 | void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, |
| 207 | 222 | struct hsr_port *port_rcv) |
| 208 | 223 | { |
| 209 | − struct ethhdr *ethhdr; | |
| 210 | − struct hsr_node *node_real; | |
| 224 | + struct hsr_priv *hsr = port_rcv->hsr; | |
| 211 | 225 | struct hsr_sup_payload *hsr_sp; |
| 226 | + struct hsr_node *node_real; | |
| 212 | 227 | struct list_head *node_db; |
| 228 | + struct ethhdr *ethhdr; | |
| 213 | 229 | int i; |
| 214 | 230 | |
| 215 | 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 | 247 | node_real = find_node_by_addr_A(node_db, hsr_sp->macaddress_A); |
| 232 | 248 | if (!node_real) |
| 233 | 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 | 251 | HSR_SEQNR_START - 1); |
| 236 | 252 | if (!node_real) |
| 237 | 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 | 269 | node_real->addr_B_port = port_rcv->type; |
| 254 | 270 | |
| 271 | + spin_lock_bh(&hsr->list_lock); | |
| 255 | 272 | list_del_rcu(&node_curr->mac_list); |
| 273 | + spin_unlock_bh(&hsr->list_lock); | |
| 256 | 274 | kfree_rcu(node_curr, rcu_head); |
| 257 | 275 | |
| 258 | 276 | done: |
| @@ -368,12 +386,13 @@ void hsr_prune_nodes(struct timer_list *t) · 109 unmodified lines | ||
| 368 | 386 | { |
| 369 | 387 | struct hsr_priv *hsr = from_timer(hsr, t, prune_timer); |
| 370 | 388 | struct hsr_node *node; |
| 389 | + struct hsr_node *tmp; | |
| 371 | 390 | struct hsr_port *port; |
| 372 | 391 | unsigned long timestamp; |
| 373 | 392 | unsigned long time_a, time_b; |
| 374 | 393 | |
| 375 | − rcu_read_lock(); | |
| 376 | − list_for_each_entry_rcu(node, &hsr->node_db, mac_list) { | |
| 394 | + spin_lock_bh(&hsr->list_lock); | |
| 395 | + list_for_each_entry_safe(node, tmp, &hsr->node_db, mac_list) { | |
| 377 | 396 | /* Don't prune own node. Neither time_in[HSR_PT_SLAVE_A] |
| 378 | 397 | * nor time_in[HSR_PT_SLAVE_B], will ever be updated for |
| 379 | 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 | 440 | kfree_rcu(node, rcu_head); |
| 422 | 441 | } |
| 423 | 442 | } |
| 424 | − rcu_read_unlock(); | |
| 443 | + spin_unlock_bh(&hsr->list_lock); | |
| 425 | 444 | |
| 426 | 445 | /* Restart timer */ |
| 427 | 446 | mod_timer(&hsr->prune_timer, |
| @@ -12,10 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 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 | 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 | 17 | struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, |
| 20 | 18 | bool is_sup); |
| 21 | 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 | 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 | 35 | unsigned char addr_a[ETH_ALEN], |
| 38 | 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 | 45 | case NETDEV_CHANGE: /* Link (carrier) state changes */ |
| 46 | 46 | hsr_check_carrier_and_operstate(hsr); |
| 47 | 47 | break; |
| 48 | + case NETDEV_CHANGENAME: | |
| 49 | + if (is_hsr_master(dev)) | |
| 50 | + hsr_debugfs_rename(dev); | |
| 51 | + break; | |
| 48 | 52 | case NETDEV_CHANGEADDR: |
| 49 | 53 | if (port->type == HSR_PT_MASTER) { |
| 50 | 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 | 69 | /* Make sure we recognize frames from ourselves in hsr_rcv() */ |
| 66 | 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 | 72 | master->dev->dev_addr, |
| 69 | 73 | port ? |
| 70 | 74 | port->dev->dev_addr : |
| @@ -123,6 +127,7 @@ static void __exit hsr_exit(void) · 52 unmodified lines | ||
| 123 | 127 | { |
| 124 | 128 | unregister_netdevice_notifier(&hsr_nb); |
| 125 | 129 | hsr_netlink_exit(); |
| 130 | + hsr_debugfs_remove_root(); | |
| 126 | 131 | } |
| 127 | 132 | |
| 128 | 133 | module_init(hsr_init); |
| @@ -160,8 +160,9 @@ struct hsr_priv { · 159 unmodified lines | ||
| 160 | 160 | int announce_count; |
| 161 | 161 | u16 sequence_nr; |
| 162 | 162 | u16 sup_sequence_nr; /* For HSRv1 separate seq_nr for supervision */ |
| 163 | − u8 prot_version; /* Indicate if HSRv0 or HSRv1. */ | |
| 164 | − spinlock_t seqnr_lock; /* locking for sequence_nr */ | |
| 163 | + u8 prot_version; /* Indicate if HSRv0 or HSRv1. */ | |
| 164 | + spinlock_t seqnr_lock; /* locking for sequence_nr */ | |
| 165 | + spinlock_t list_lock; /* locking for node list */ | |
| 165 | 166 | unsigned char sup_multicast_addr[ETH_ALEN]; |
| 166 | 167 | #ifdef CONFIG_DEBUG_FS |
| 167 | 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 | 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 | 190 | void hsr_debugfs_term(struct hsr_priv *priv); |
| 191 | +void hsr_debugfs_create_root(void); | |
| 192 | +void hsr_debugfs_remove_root(void); | |
| 189 | 193 | #else |
| 190 | −static inline int hsr_debugfs_init(struct hsr_priv *priv, | |
| 191 | − struct net_device *hsr_dev) | |
| 194 | +static inline void void hsr_debugfs_rename(struct net_device *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 | 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 | 206 | #endif |
| 199 | 207 | |
| 200 | 208 | #endif /* __HSR_PRIVATE_H */ |
| @@ -476,6 +476,7 @@ int __init hsr_netlink_init(void) · 475 unmodified lines | ||
| 476 | 476 | if (rc) |
| 477 | 477 | goto fail_genl_register_family; |
| 478 | 478 | |
| 479 | + hsr_debugfs_create_root(); | |
| 479 | 480 | return 0; |
| 480 | 481 | |
| 481 | 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 | 1086 | if (!dst) |
| 1087 | 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 | 1091 | dst = __sk_dst_check(sk, 0); |
| 1092 | 1092 | if (!dst) |
| @@ -505,7 +505,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, · 504 unmodified lines | ||
| 505 | 505 | mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
| 506 | 506 | |
| 507 | 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 | 510 | if (skb->protocol == htons(ETH_P_IP)) { |
| 511 | 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 | 215 | mtu = dst_mtu(dst); |
| 216 | 216 | if (skb->len > mtu) { |
| 217 | − skb_dst_update_pmtu(skb, mtu); | |
| 217 | + skb_dst_update_pmtu_no_confirm(skb, mtu); | |
| 218 | 218 | if (skb->protocol == htons(ETH_P_IP)) { |
| 219 | 219 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
| 220 | 220 | htonl(mtu)); |
| @@ -384,10 +384,11 @@ next: ; · 383 unmodified lines | ||
| 384 | 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 | 389 | struct xt_entry_target *t = arpt_get_target(e); |
| 390 | 390 | struct xt_tgchk_param par = { |
| 391 | + .net = net, | |
| 391 | 392 | .table = name, |
| 392 | 393 | .entryinfo = e, |
| 393 | 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 | 400 | return xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false); |
| 400 | 401 | } |
| 401 | 402 | |
| 402 | −static inline int | |
| 403 | −find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, | |
| 403 | +static int | |
| 404 | +find_check_entry(struct arpt_entry *e, struct net *net, const char *name, | |
| 405 | + unsigned int size, | |
| 404 | 406 | struct xt_percpu_counter_alloc_state *alloc_state) |
| 405 | 407 | { |
| 406 | 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 | 422 | t->u.kernel.target = target; |
| 421 | 423 | |
| 422 | − ret = check_target(e, name); | |
| 424 | + ret = check_target(e, net, name); | |
| 423 | 425 | if (ret) |
| 424 | 426 | goto err; |
| 425 | 427 | return 0; |
| @@ -512,7 +514,9 @@ static inline void cleanup_entry(struct arpt_entry *e) · 86 unmodified lines | ||
| 512 | 514 | /* Checks and translates the user-supplied table segment (held in |
| 513 | 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 | 520 | const struct arpt_replace *repl) |
| 517 | 521 | { |
| 518 | 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 | 573 | /* Finally, each sanity check must pass */ |
| 570 | 574 | i = 0; |
| 571 | 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 | 577 | &alloc_state); |
| 574 | 578 | if (ret != 0) |
| 575 | 579 | break; |
| @@ -974,7 +978,7 @@ static int do_replace(struct net *net, const void __user *user, · 398 unmodified lines | ||
| 974 | 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 | 982 | if (ret != 0) |
| 979 | 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 | 1158 | void **pentry0, |
| 1154 | 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 | 1222 | repl.num_counters = 0; |
| 1218 | 1223 | repl.counters = NULL; |
| 1219 | 1224 | repl.size = newinfo->size; |
| 1220 | − ret = translate_table(newinfo, entry1, &repl); | |
| 1225 | + ret = translate_table(net, newinfo, entry1, &repl); | |
| 1221 | 1226 | if (ret) |
| 1222 | 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 | 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 | 1279 | if (ret != 0) |
| 1275 | 1280 | goto free_newinfo; |
| 1276 | 1281 | |
| @@ -1546,7 +1551,7 @@ int arpt_register_table(struct net *net, · 269 unmodified lines | ||
| 1546 | 1551 | loc_cpu_entry = newinfo->entries; |
| 1547 | 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 | 1555 | if (ret != 0) |
| 1551 | 1556 | goto out_free; |
| 1552 | 1557 | |
| @@ -139,7 +139,8 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst); · 138 unmodified lines | ||
| 139 | 139 | static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); |
| 140 | 140 | static void ipv4_link_failure(struct sk_buff *skb); |
| 141 | 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 | 144 | static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, |
| 144 | 145 | struct sk_buff *skb); |
| 145 | 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 | 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 | 1050 | struct rtable *rt = (struct rtable *) dst; |
| 1049 | 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 | 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 | 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 | 1733 | continue; |
| 1734 | + } | |
| 1732 | 1735 | |
| 1733 | 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 | 72 | __skb_unlink(skb, &sk->sk_write_queue); |
| 73 | 73 | tcp_rbtree_insert(&sk->tcp_rtx_queue, skb); |
| 74 | 74 | |
| 75 | + if (tp->highest_sack == NULL) | |
| 76 | + tp->highest_sack = skb; | |
| 77 | + | |
| 75 | 78 | tp->packets_out += tcp_skb_pcount(skb); |
| 76 | 79 | if (!prior_packets || icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) |
| 77 | 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 | 1475 | * queue contains some other skb |
| 1476 | 1476 | */ |
| 1477 | 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 | 1479 | goto uncharge_drop; |
| 1480 | 1480 | |
| 1481 | 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 | 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 | 106 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
| 106 | 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 | 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 | 147 | if (IS_ERR(dst)) |
| 148 | 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 | 151 | dst = inet6_csk_route_socket(sk, &fl6); |
| 152 | 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 | 1041 | /* TooBig packet may have updated dst->dev's mtu */ |
| 1042 | 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 | 1045 | err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, |
| 1046 | 1046 | NEXTHDR_GRE); |
| @@ -640,7 +640,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, · 639 unmodified lines | ||
| 640 | 640 | if (rel_info > dst_mtu(skb_dst(skb2))) |
| 641 | 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 | 646 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); |
| @@ -1132,7 +1132,7 @@ route_lookup: · 485 unmodified lines | ||
| 1132 | 1132 | mtu = max(mtu, skb->protocol == htons(ETH_P_IPV6) ? |
| 1133 | 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 | 1136 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { |
| 1137 | 1137 | *pmtu = mtu; |
| 1138 | 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 | 480 | mtu = dst_mtu(dst); |
| 481 | 481 | if (skb->len > mtu) { |
| 482 | − skb_dst_update_pmtu(skb, mtu); | |
| 482 | + skb_dst_update_pmtu_no_confirm(skb, mtu); | |
| 483 | 483 | |
| 484 | 484 | if (skb->protocol == htons(ETH_P_IPV6)) { |
| 485 | 485 | if (mtu < IPV6_MIN_MTU) |
| @@ -95,7 +95,8 @@ static int ip6_pkt_prohibit(struct sk_buff *skb); · 94 unmodified lines | ||
| 95 | 95 | static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); |
| 96 | 96 | static void ip6_link_failure(struct sk_buff *skb); |
| 97 | 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 | 100 | static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, |
| 100 | 101 | struct sk_buff *skb); |
| 101 | 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 | 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 | 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 | 2700 | const struct in6_addr *daddr, *saddr; |
| 2698 | 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 | 2713 | daddr = NULL; |
| 2711 | 2714 | saddr = NULL; |
| 2712 | 2715 | } |
| 2713 | − dst_confirm_neigh(dst, daddr); | |
| 2716 | + | |
| 2717 | + if (confirm_neigh) | |
| 2718 | + dst_confirm_neigh(dst, daddr); | |
| 2719 | + | |
| 2714 | 2720 | mtu = max_t(u32, mtu, IPV6_MIN_MTU); |
| 2715 | 2721 | if (mtu >= dst_mtu(dst)) |
| 2716 | 2722 | return; |
| @@ -2764,9 +2770,11 @@ out_unlock: · 47 unmodified lines | ||
| 2764 | 2770 | } |
| 2765 | 2771 | |
| 2766 | 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 | 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 | 2794 | dst = ip6_route_output(net, NULL, &fl6); |
| 2787 | 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 | 2797 | dst_release(dst); |
| 2790 | 2798 | } |
| 2791 | 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 | 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 | 949 | if (skb->len > mtu && !skb_is_gso(skb)) { |
| 950 | 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 | 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 | 104 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
| 104 | 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 | 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 | 1848 | struct ip_set *set; |
| 1849 | 1849 | struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {}; |
| 1850 | 1850 | int ret = 0; |
| 1851 | + u32 lineno; | |
| 1851 | 1852 | |
| 1852 | 1853 | if (unlikely(protocol_min_failed(attr) || |
| 1853 | 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 | 1865 | return -IPSET_ERR_PROTOCOL; |
| 1865 | 1866 | |
| 1866 | 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 | 1869 | rcu_read_unlock_bh(); |
| 1869 | 1870 | /* Userspace can't trigger element to be re-added */ |
| 1870 | 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 | 208 | struct rtable *ort = skb_rtable(skb); |
| 209 | 209 | |
| 210 | 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 | 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 | 677 | unsigned int *timeouts = data; |
| 678 | 678 | int i; |
| 679 | 679 | |
| 680 | + if (!timeouts) | |
| 681 | + timeouts = dn->dccp_timeout; | |
| 682 | + | |
| 680 | 683 | /* set default DCCP timeouts. */ |
| 681 | 684 | for (i=0; i<CT_DCCP_MAX; i++) |
| 682 | 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 | 594 | struct nf_sctp_net *sn = nf_sctp_pernet(net); |
| 595 | 595 | int i; |
| 596 | 596 | |
| 597 | + if (!timeouts) | |
| 598 | + timeouts = sn->timeouts; | |
| 599 | + | |
| 597 | 600 | /* set default SCTP timeouts. */ |
| 598 | 601 | for (i=0; i<SCTP_CONNTRACK_MAX; i++) |
| 599 | 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 | 134 | #define NF_FLOWTABLE_TCP_PICKUP_TIMEOUT (120 * HZ) |
| 135 | 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 | 137 | static void flow_offload_fixup_ct_timeout(struct nf_conn *ct) |
| 143 | 138 | { |
| 144 | 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 | 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 | 232 | err = rhashtable_insert_fast(&flow_table->rhashtable, |
| 238 | 233 | &flow->tuplehash[0].node, |
| @@ -280,7 +280,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, · 279 unmodified lines | ||
| 280 | 280 | if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0) |
| 281 | 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 | 284 | iph = ip_hdr(skb); |
| 285 | 285 | ip_decrease_ttl(iph); |
| 286 | 286 | skb->tstamp = 0; |
| @@ -509,7 +509,7 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, · 222 unmodified lines | ||
| 509 | 509 | if (nf_flow_nat_ipv6(flow, skb, dir) < 0) |
| 510 | 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 | 513 | ip6h = ipv6_hdr(skb); |
| 514 | 514 | ip6h->hop_limit--; |
| 515 | 515 | skb->tstamp = 0; |
| @@ -88,7 +88,7 @@ static int nf_flow_rule_match(struct nf_flow_match *match, · 87 unmodified lines | ||
| 88 | 88 | switch (tuple->l4proto) { |
| 89 | 89 | case IPPROTO_TCP: |
| 90 | 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 | 92 | match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_TCP); |
| 93 | 93 | break; |
| 94 | 94 | case IPPROTO_UDP: |
| @@ -166,24 +166,38 @@ static int flow_offload_eth_dst(struct net *net, · 71 unmodified lines | ||
| 166 | 166 | enum flow_offload_tuple_dir dir, |
| 167 | 167 | struct nf_flow_rule *flow_rule) |
| 168 | 168 | { |
| 169 | − const struct flow_offload_tuple *tuple = &flow->tuplehash[dir].tuple; | |
| 170 | 169 | struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule); |
| 171 | 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 | 174 | struct neighbour *n; |
| 173 | 175 | u32 mask, val; |
| 176 | + u8 nud_state; | |
| 174 | 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 | 181 | if (!n) |
| 178 | 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 | 194 | mask = ~0xffffffff; |
| 181 | − memcpy(&val, n->ha, 4); | |
| 195 | + memcpy(&val, ha, 4); | |
| 182 | 196 | flow_offload_mangle(entry0, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 0, |
| 183 | 197 | &val, &mask); |
| 184 | 198 | |
| 185 | 199 | mask = ~0x0000ffff; |
| 186 | − memcpy(&val16, n->ha + 4, 2); | |
| 200 | + memcpy(&val16, ha + 4, 2); | |
| 187 | 201 | val = val16; |
| 188 | 202 | flow_offload_mangle(entry1, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 4, |
| 189 | 203 | &val, &mask); |
| @@ -335,22 +349,26 @@ static void flow_offload_port_snat(struct net *net, · 145 unmodified lines | ||
| 335 | 349 | struct nf_flow_rule *flow_rule) |
| 336 | 350 | { |
| 337 | 351 | struct flow_action_entry *entry = flow_action_entry_next(flow_rule); |
| 338 | − u32 mask = ~htonl(0xffff0000), port; | |
| 352 | + u32 mask, port; | |
| 339 | 353 | u32 offset; |
| 340 | 354 | |
| 341 | 355 | switch (dir) { |
| 342 | 356 | case FLOW_OFFLOAD_DIR_ORIGINAL: |
| 343 | 357 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port); |
| 344 | 358 | offset = 0; /* offsetof(struct tcphdr, source); */ |
| 359 | + port = htonl(port << 16); | |
| 360 | + mask = ~htonl(0xffff0000); | |
| 345 | 361 | break; |
| 346 | 362 | case FLOW_OFFLOAD_DIR_REPLY: |
| 347 | 363 | port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port); |
| 348 | 364 | offset = 0; /* offsetof(struct tcphdr, dest); */ |
| 365 | + port = htonl(port); | |
| 366 | + mask = ~htonl(0xffff); | |
| 349 | 367 | break; |
| 350 | 368 | default: |
| 351 | 369 | return; |
| 352 | 370 | } |
| 353 | − port = htonl(port << 16); | |
| 371 | + | |
| 354 | 372 | flow_offload_mangle(entry, flow_offload_l4proto(flow), offset, |
| 355 | 373 | &port, &mask); |
| 356 | 374 | } |
| @@ -361,22 +379,26 @@ static void flow_offload_port_dnat(struct net *net, · 4 unmodified lines | ||
| 361 | 379 | struct nf_flow_rule *flow_rule) |
| 362 | 380 | { |
| 363 | 381 | struct flow_action_entry *entry = flow_action_entry_next(flow_rule); |
| 364 | − u32 mask = ~htonl(0xffff), port; | |
| 382 | + u32 mask, port; | |
| 365 | 383 | u32 offset; |
| 366 | 384 | |
| 367 | 385 | switch (dir) { |
| 368 | 386 | case FLOW_OFFLOAD_DIR_ORIGINAL: |
| 369 | − port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port); | |
| 370 | − offset = 0; /* offsetof(struct tcphdr, source); */ | |
| 387 | + port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port); | |
| 388 | + offset = 0; /* offsetof(struct tcphdr, dest); */ | |
| 389 | + port = htonl(port); | |
| 390 | + mask = ~htonl(0xffff); | |
| 371 | 391 | break; |
| 372 | 392 | case FLOW_OFFLOAD_DIR_REPLY: |
| 373 | − port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port); | |
| 374 | − offset = 0; /* offsetof(struct tcphdr, dest); */ | |
| 393 | + port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port); | |
| 394 | + offset = 0; /* offsetof(struct tcphdr, source); */ | |
| 395 | + port = htonl(port << 16); | |
| 396 | + mask = ~htonl(0xffff0000); | |
| 375 | 397 | break; |
| 376 | 398 | default: |
| 377 | 399 | return; |
| 378 | 400 | } |
| 379 | − port = htonl(port); | |
| 401 | + | |
| 380 | 402 | flow_offload_mangle(entry, flow_offload_l4proto(flow), offset, |
| 381 | 403 | &port, &mask); |
| 382 | 404 | } |
| @@ -759,9 +781,9 @@ void nf_flow_offload_stats(struct nf_flowtable *flowtable, · 376 unmodified lines | ||
| 759 | 781 | struct flow_offload *flow) |
| 760 | 782 | { |
| 761 | 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 | 787 | if ((delta >= (9 * NF_FLOW_TIMEOUT) / 10) || |
| 766 | 788 | flow->flags & FLOW_OFFLOAD_HW_DYING) |
| 767 | 789 | return; |
| @@ -5984,6 +5984,7 @@ nft_flowtable_type_get(struct net *net, u8 family) · 5983 unmodified lines | ||
| 5984 | 5984 | return ERR_PTR(-ENOENT); |
| 5985 | 5985 | } |
| 5986 | 5986 | |
| 5987 | +/* Only called from error and netdev event paths. */ | |
| 5987 | 5988 | static void nft_unregister_flowtable_hook(struct net *net, |
| 5988 | 5989 | struct nft_flowtable *flowtable, |
| 5989 | 5990 | struct nft_hook *hook) |
| @@ -5999,7 +6000,7 @@ static void nft_unregister_flowtable_net_hooks(struct net *net, · 9 unmodified lines | ||
| 5999 | 6000 | struct nft_hook *hook; |
| 6000 | 6001 | |
| 6001 | 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 | 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 | 6450 | struct nft_hook *hook, *next; |
| 6450 | 6451 | |
| 6452 | + flowtable->data.type->free(&flowtable->data); | |
| 6451 | 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 | 6456 | list_del_rcu(&hook->list); |
| 6453 | 6457 | kfree(hook); |
| 6454 | 6458 | } |
| 6455 | 6459 | kfree(flowtable->name); |
| 6456 | − flowtable->data.type->free(&flowtable->data); | |
| 6457 | 6460 | module_put(flowtable->data.type->owner); |
| 6458 | 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 | 6500 | if (hook->ops.dev != dev) |
| 6498 | 6501 | continue; |
| 6499 | 6502 | |
| 6503 | + /* flow_offload_netdev_event() cleans up entries for us. */ | |
| 6500 | 6504 | nft_unregister_flowtable_hook(dev_net(dev), flowtable, hook); |
| 6501 | 6505 | list_del_rcu(&hook->list); |
| 6502 | 6506 | kfree_rcu(hook, rcu); |
| @@ -200,9 +200,6 @@ static void nft_flow_offload_activate(const struct nft_ctx *ctx, · 199 unmodified lines | ||
| 200 | 200 | static void nft_flow_offload_destroy(const struct nft_ctx *ctx, |
| 201 | 201 | const struct nft_expr *expr) |
| 202 | 202 | { |
| 203 | − struct nft_flow_offload *priv = nft_expr_priv(expr); | |
| 204 | − | |
| 205 | − priv->flowtable->use--; | |
| 206 | 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 | 50 | taddr = nf_tproxy_laddr4(skb, taddr, iph->daddr); |
| 51 | 51 | |
| 52 | 52 | if (priv->sreg_port) |
| 53 | − tport = regs->data[priv->sreg_port]; | |
| 53 | + tport = nft_reg_load16(®s->data[priv->sreg_port]); | |
| 54 | 54 | if (!tport) |
| 55 | 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 | 117 | taddr = *nf_tproxy_laddr6(skb, &taddr, &iph->daddr); |
| 118 | 118 | |
| 119 | 119 | if (priv->sreg_port) |
| 120 | − tport = regs->data[priv->sreg_port]; | |
| 120 | + tport = nft_reg_load16(®s->data[priv->sreg_port]); | |
| 121 | 121 | if (!tport) |
| 122 | 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 | 196 | hdr->size = cpu_to_le32(len); |
| 197 | 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 | 201 | mutex_lock(&node->ep_lock); |
| 202 | 202 | if (node->ep) |
| @@ -209,6 +209,7 @@ struct rxrpc_skb_priv { · 208 unmodified lines | ||
| 209 | 209 | struct rxrpc_security { |
| 210 | 210 | const char *name; /* name of this service */ |
| 211 | 211 | u8 security_index; /* security type provided */ |
| 212 | + u32 no_key_abort; /* Abort code indicating no key */ | |
| 212 | 213 | |
| 213 | 214 | /* Initialise a security service */ |
| 214 | 215 | int (*init)(void); |
| @@ -977,8 +978,9 @@ static inline void rxrpc_reduce_conn_timer(struct rxrpc_connection *conn, · 762 unmodified lines | ||
| 977 | 978 | struct rxrpc_connection *rxrpc_find_service_conn_rcu(struct rxrpc_peer *, |
| 978 | 979 | struct sk_buff *); |
| 979 | 980 | struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *, gfp_t); |
| 980 | −void rxrpc_new_incoming_connection(struct rxrpc_sock *, | |
| 981 | − struct rxrpc_connection *, struct sk_buff *); | |
| 981 | +void rxrpc_new_incoming_connection(struct rxrpc_sock *, struct rxrpc_connection *, | |
| 982 | + const struct rxrpc_security *, struct key *, | |
| 983 | + struct sk_buff *); | |
| 982 | 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 | 1105 | int __init rxrpc_init_security(void); |
| 1104 | 1106 | void rxrpc_exit_security(void); |
| 1105 | 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 | 1113 | * sendmsg.c |
| @@ -239,6 +239,22 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx) · 238 unmodified lines | ||
| 239 | 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 | 259 | * Allocate a new incoming call from the prealloc pool, along with a connection |
| 244 | 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 | 263 | struct rxrpc_local *local, |
| 248 | 264 | struct rxrpc_peer *peer, |
| 249 | 265 | struct rxrpc_connection *conn, |
| 266 | + const struct rxrpc_security *sec, | |
| 267 | + struct key *key, | |
| 250 | 268 | struct sk_buff *skb) |
| 251 | 269 | { |
| 252 | 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 | 312 | conn->params.local = rxrpc_get_local(local); |
| 295 | 313 | conn->params.peer = peer; |
| 296 | 314 | rxrpc_see_connection(conn); |
| 297 | − rxrpc_new_incoming_connection(rx, conn, skb); | |
| 315 | + rxrpc_new_incoming_connection(rx, conn, sec, key, skb); | |
| 298 | 316 | } else { |
| 299 | 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 | 351 | struct sk_buff *skb) |
| 334 | 352 | { |
| 335 | 353 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 354 | + const struct rxrpc_security *sec = NULL; | |
| 336 | 355 | struct rxrpc_connection *conn; |
| 337 | 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 | 360 | _enter(""); |
| 341 | 361 | |
| @@ -346,9 +366,7 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, · 4 unmodified lines | ||
| 346 | 366 | sp->hdr.seq, RX_INVALID_OPERATION, ESHUTDOWN); |
| 347 | 367 | skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; |
| 348 | 368 | skb->priority = RX_INVALID_OPERATION; |
| 349 | − _leave(" = NULL [close]"); | |
| 350 | − call = NULL; | |
| 351 | − goto out; | |
| 369 | + goto no_call; | |
| 352 | 370 | } |
| 353 | 371 | |
| 354 | 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 | 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 | 384 | if (!call) { |
| 363 | 385 | skb->mark = RXRPC_SKB_MARK_REJECT_BUSY; |
| 364 | − _leave(" = NULL [busy]"); | |
| 365 | − call = NULL; | |
| 366 | − goto out; | |
| 386 | + goto no_call; | |
| 367 | 387 | } |
| 368 | 388 | |
| 369 | 389 | trace_rxrpc_receive(call, rxrpc_receive_incoming, |
| 370 | 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 | 392 | /* Make the call live. */ |
| 385 | 393 | rxrpc_incoming_call(rx, call, skb); |
| 386 | 394 | conn = call->conn; |
| @@ -421,6 +429,9 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, · 34 unmodified lines | ||
| 421 | 429 | BUG(); |
| 422 | 430 | } |
| 423 | 431 | spin_unlock(&conn->state_lock); |
| 432 | + spin_unlock(&rx->incoming_lock); | |
| 433 | + | |
| 434 | + rxrpc_send_ping(call, skb); | |
| 424 | 435 | |
| 425 | 436 | if (call->state == RXRPC_CALL_SERVER_ACCEPTING) |
| 426 | 437 | rxrpc_notify_socket(call); |
| @@ -433,9 +444,12 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, · 6 unmodified lines | ||
| 433 | 444 | rxrpc_put_call(call, rxrpc_call_put); |
| 434 | 445 | |
| 435 | 446 | _leave(" = %p{%d}", call, call->debug_id); |
| 436 | −out: | |
| 437 | − spin_unlock(&rx->incoming_lock); | |
| 438 | 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 | 376 | _enter("{%d}", conn->debug_id); |
| 377 | 377 | |
| 378 | 378 | ASSERT(conn->security_ix != 0); |
| 379 | − | |
| 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 | − } | |
| 379 | + ASSERT(conn->server_key); | |
| 394 | 380 | |
| 395 | 381 | if (conn->security->issue_challenge(conn) < 0) { |
| 396 | 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 | 149 | void rxrpc_new_incoming_connection(struct rxrpc_sock *rx, |
| 150 | 150 | struct rxrpc_connection *conn, |
| 151 | + const struct rxrpc_security *sec, | |
| 152 | + struct key *key, | |
| 151 | 153 | struct sk_buff *skb) |
| 152 | 154 | { |
| 153 | 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 | 162 | conn->service_id = sp->hdr.serviceId; |
| 161 | 163 | conn->security_ix = sp->hdr.securityIndex; |
| 162 | 164 | conn->out_clientflag = 0; |
| 165 | + conn->security = sec; | |
| 166 | + conn->server_key = key_get(key); | |
| 163 | 167 | if (conn->security_ix) |
| 164 | 168 | conn->state = RXRPC_CONN_SERVICE_UNSECURED; |
| 165 | 169 | else |
| @@ -192,22 +192,6 @@ send_extra_data: · 191 unmodified lines | ||
| 192 | 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 | 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 | 1380 | call = rxrpc_new_incoming_call(local, rx, skb); |
| 1397 | 1381 | if (!call) |
| 1398 | 1382 | goto reject_packet; |
| 1399 | − rxrpc_send_ping(call, skb); | |
| 1400 | − mutex_unlock(&call->user_mutex); | |
| 1401 | 1383 | } |
| 1402 | 1384 | |
| 1403 | 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 | 648 | u32 serial; |
| 649 | 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 | 654 | if (ret < 0) |
| 655 | 655 | return ret; |
| 656 | 656 | |
| @@ -1293,6 +1293,7 @@ static void rxkad_exit(void) · 636 unmodified lines | ||
| 1293 | 1293 | const struct rxrpc_security rxkad = { |
| 1294 | 1294 | .name = "rxkad", |
| 1295 | 1295 | .security_index = RXRPC_SECURITY_RXKAD, |
| 1296 | + .no_key_abort = RXKADUNKNOWNKEY, | |
| 1296 | 1297 | .init = rxkad_init, |
| 1297 | 1298 | .exit = rxkad_exit, |
| 1298 | 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 | 111 | const struct rxrpc_security *sec; |
| 109 | − struct rxrpc_local *local = conn->params.local; | |
| 110 | − struct rxrpc_sock *rx; | |
| 111 | − struct key *key; | |
| 112 | − key_ref_t kref; | |
| 112 | + struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | |
| 113 | + key_ref_t kref = NULL; | |
| 113 | 114 | char kdesc[5 + 1 + 3 + 1]; |
| 114 | 115 | |
| 115 | 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 | 121 | if (!sec) { |
| 121 | − _leave(" = -ENOKEY [lookup]"); | |
| 122 | − return -ENOKEY; | |
| 122 | + trace_rxrpc_abort(0, "SVS", | |
| 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 */ | |
| 126 | − read_lock(&local->services_lock); | |
| 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; | |
| 130 | + if (sp->hdr.securityIndex == RXRPC_SECURITY_NONE) | |
| 131 | + goto out; | |
| 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 | 133 | if (!rx->securities) { |
| 140 | − read_unlock(&local->services_lock); | |
| 141 | − _leave(" = -ENOKEY"); | |
| 142 | − return -ENOKEY; | |
| 134 | + trace_rxrpc_abort(0, "SVR", | |
| 135 | + sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, | |
| 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 | 142 | /* look through the service's keyring */ |
| 146 | 143 | kref = keyring_search(make_key_ref(rx->securities, 1UL), |
| 147 | 144 | &key_type_rxrpc_s, kdesc, true); |
| 148 | 145 | if (IS_ERR(kref)) { |
| 149 | − read_unlock(&local->services_lock); | |
| 150 | − _leave(" = %ld [search]", PTR_ERR(kref)); | |
| 151 | − return PTR_ERR(kref); | |
| 146 | + trace_rxrpc_abort(0, "SVK", | |
| 147 | + sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, | |
| 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); | |
| 155 | − read_unlock(&local->services_lock); | |
| 156 | − | |
| 157 | − conn->server_key = key; | |
| 158 | − conn->security = sec; | |
| 159 | − | |
| 160 | − _leave(" = 0"); | |
| 161 | − return 0; | |
| 154 | +out: | |
| 155 | + *_sec = sec; | |
| 156 | + *_key = key_ref_to_ptr(kref); | |
| 157 | + return true; | |
| 162 | 158 | } |
| @@ -219,8 +219,10 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, · 218 unmodified lines | ||
| 219 | 219 | bool use_reinsert; |
| 220 | 220 | bool want_ingress; |
| 221 | 221 | bool is_redirect; |
| 222 | + bool expects_nh; | |
| 222 | 223 | int m_eaction; |
| 223 | 224 | int mac_len; |
| 225 | + bool at_nh; | |
| 224 | 226 | |
| 225 | 227 | rec_level = __this_cpu_inc_return(mirred_rec_level); |
| 226 | 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 | 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 | 266 | want_ingress = tcf_mirred_act_wants_ingress(m_eaction); |
| 269 | − if (skb_at_tc_ingress(skb) != want_ingress && m_mac_header_xmit) { | |
| 270 | − if (!skb_at_tc_ingress(skb)) { | |
| 271 | − /* caught at egress, act ingress: pull mac */ | |
| 272 | − mac_len = skb_network_header(skb) - skb_mac_header(skb); | |
| 267 | + | |
| 268 | + expects_nh = want_ingress || !m_mac_header_xmit; | |
| 269 | + at_nh = skb->data == skb_network_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 | 275 | skb_pull_rcsum(skb2, mac_len); |
| 274 | 276 | } else { |
| 275 | − /* caught at ingress, act egress: push mac */ | |
| 276 | − skb_push_rcsum(skb2, skb->mac_len); | |
| 277 | + /* target device/action expect data at mac */ | |
| 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 | 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, | |
| 312 | − struct tcf_walker *arg) | |
| 311 | +static bool tcf_proto_check_delete(struct tcf_proto *tp) | |
| 313 | 312 | { |
| 314 | − if (fh) { | |
| 315 | − arg->nonempty = true; | |
| 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 | −} | |
| 313 | + if (tp->ops->delete_empty) | |
| 314 | + return tp->ops->delete_empty(tp); | |
| 331 | 315 | |
| 332 | −static bool tcf_proto_check_delete(struct tcf_proto *tp, bool rtnl_held) | |
| 333 | −{ | |
| 334 | − spin_lock(&tp->lock); | |
| 335 | − if (tcf_proto_is_empty(tp, rtnl_held)) | |
| 336 | − tp->deleting = true; | |
| 337 | − spin_unlock(&tp->lock); | |
| 316 | + tp->deleting = true; | |
| 338 | 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 | 1730 | * concurrently. |
| 1752 | 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 | 1734 | mutex_unlock(&chain->filter_chain_lock); |
| 1756 | 1735 | return; |
| 1757 | 1736 | } |
| @@ -2773,6 +2773,17 @@ static void fl_bind_class(void *fh, u32 classid, unsigned long cl) · 2772 unmodified lines | ||
| 2773 | 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 | 2787 | static struct tcf_proto_ops cls_fl_ops __read_mostly = { |
| 2777 | 2788 | .kind = "flower", |
| 2778 | 2789 | .classify = fl_classify, |
| @@ -2782,6 +2793,7 @@ static struct tcf_proto_ops cls_fl_ops __read_mostly = { · 3 unmodified lines | ||
| 2782 | 2793 | .put = fl_put, |
| 2783 | 2794 | .change = fl_change, |
| 2784 | 2795 | .delete = fl_delete, |
| 2796 | + .delete_empty = fl_delete_empty, | |
| 2785 | 2797 | .walk = fl_walk, |
| 2786 | 2798 | .reoffload = fl_reoffload, |
| 2787 | 2799 | .hw_add = fl_hw_add, |
| @@ -1108,33 +1108,10 @@ erridr: · 1107 unmodified lines | ||
| 1108 | 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 | 1111 | static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg, |
| 1134 | 1112 | bool rtnl_held) |
| 1135 | 1113 | { |
| 1136 | 1114 | struct tc_u_common *tp_c = tp->data; |
| 1137 | − bool non_root_ht = false; | |
| 1138 | 1115 | struct tc_u_hnode *ht; |
| 1139 | 1116 | struct tc_u_knode *n; |
| 1140 | 1117 | unsigned int h; |
| @@ -1147,8 +1124,6 @@ static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg, · 6 unmodified lines | ||
| 1147 | 1124 | ht = rtnl_dereference(ht->next)) { |
| 1148 | 1125 | if (ht->prio != tp->prio) |
| 1149 | 1126 | continue; |
| 1150 | − if (u32_hnode_empty(ht, &non_root_ht)) | |
| 1151 | − return; | |
| 1152 | 1127 | if (arg->count >= arg->skip) { |
| 1153 | 1128 | if (arg->fn(tp, ht, arg) < 0) { |
| 1154 | 1129 | arg->stop = 1; |
| @@ -1769,7 +1769,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, · 1768 unmodified lines | ||
| 1769 | 1769 | q->avg_window_begin)); |
| 1770 | 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 | 1773 | q->avg_peak_bandwidth = |
| 1774 | 1774 | cake_ewma(q->avg_peak_bandwidth, b, |
| 1775 | 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 | 301 | f->socket_hash != sk->sk_hash)) { |
| 302 | 302 | f->credit = q->initial_quantum; |
| 303 | 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 | 307 | if (fq_flow_is_throttled(f)) |
| 305 | 308 | fq_flow_unset_throttled(q, f); |
| 306 | 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 | 326 | fq_flow_set_detached(f); |
| 324 | 327 | f->sk = sk; |
| 325 | − if (skb->sk == sk) | |
| 328 | + if (skb->sk == sk) { | |
| 326 | 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 | 334 | f->credit = q->initial_quantum; |
| 328 | 335 | |
| 329 | 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 | 435 | f->qlen++; |
| 429 | 436 | qdisc_qstats_backlog_inc(sch, skb); |
| 430 | 437 | if (fq_flow_is_detached(f)) { |
| 431 | − struct sock *sk = skb->sk; | |
| 432 | − | |
| 433 | 438 | fq_flow_add_tail(&q->new_flows, f); |
| 434 | 439 | if (time_after(jiffies, f->age + q->flow_refill_delay)) |
| 435 | 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 | 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 | 786 | if (tb[TCA_FQ_QUANTUM]) { |
| 788 | 787 | u32 quantum = nla_get_u32(tb[TCA_FQ_QUANTUM]); |
| 789 | 788 | |
| 790 | − if (quantum > 0) | |
| 789 | + if (quantum > 0 && quantum <= (1 << 20)) { | |
| 791 | 790 | q->quantum = quantum; |
| 792 | − else | |
| 791 | + } else { | |
| 792 | + NL_SET_ERR_MSG_MOD(extack, "invalid quantum"); | |
| 793 | 793 | err = -EINVAL; |
| 794 | + } | |
| 794 | 795 | } |
| 795 | 796 | |
| 796 | 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 | 292 | struct tc_prio_qopt_offload graft_offload; |
| 293 | 293 | unsigned long band = arg - 1; |
| 294 | 294 | |
| 295 | − if (new == NULL) | |
| 296 | − new = &noop_qdisc; | |
| 295 | + if (!new) { | |
| 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 | 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 | 1363 | /* Generate an INIT ACK chunk. */ |
| 1364 | 1364 | new_obj = sctp_make_init_ack(asoc, chunk, GFP_ATOMIC, |
| 1365 | 1365 | 0); |
| 1366 | − if (!new_obj) | |
| 1367 | − goto nomem; | |
| 1366 | + if (!new_obj) { | |
| 1367 | + error = -ENOMEM; | |
| 1368 | + break; | |
| 1369 | + } | |
| 1368 | 1370 | |
| 1369 | 1371 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
| 1370 | 1372 | SCTP_CHUNK(new_obj)); |
| @@ -1386,7 +1388,8 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, · 15 unmodified lines | ||
| 1386 | 1388 | if (!new_obj) { |
| 1387 | 1389 | if (cmd->obj.chunk) |
| 1388 | 1390 | sctp_chunk_free(cmd->obj.chunk); |
| 1389 | − goto nomem; | |
| 1391 | + error = -ENOMEM; | |
| 1392 | + break; | |
| 1390 | 1393 | } |
| 1391 | 1394 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
| 1392 | 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 | 1437 | /* Generate a SHUTDOWN chunk. */ |
| 1435 | 1438 | new_obj = sctp_make_shutdown(asoc, chunk); |
| 1436 | − if (!new_obj) | |
| 1437 | − goto nomem; | |
| 1439 | + if (!new_obj) { | |
| 1440 | + error = -ENOMEM; | |
| 1441 | + break; | |
| 1442 | + } | |
| 1438 | 1443 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
| 1439 | 1444 | SCTP_CHUNK(new_obj)); |
| 1440 | 1445 | break; |
| @@ -1770,11 +1775,17 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, · 329 unmodified lines | ||
| 1770 | 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 | 1785 | break; |
| 1786 | + } | |
| 1775 | 1787 | } |
| 1776 | 1788 | |
| 1777 | −out: | |
| 1778 | 1789 | /* If this is in response to a received chunk, wait until |
| 1779 | 1790 | * we are done with the packet to open the queue so that we don't |
| 1780 | 1791 | * send multiple packets in response to a single request. |
| @@ -1789,7 +1800,4 @@ out: · 8 unmodified lines | ||
| 1789 | 1800 | sp->data_ready_signalled = 0; |
| 1790 | 1801 | |
| 1791 | 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 | 84 | return 0; |
| 85 | 85 | |
| 86 | 86 | ret = genradix_prealloc(&stream->out, outcnt, gfp); |
| 87 | − if (ret) { | |
| 88 | − genradix_free(&stream->out); | |
| 87 | + if (ret) | |
| 89 | 88 | return ret; |
| 90 | − } | |
| 91 | 89 | |
| 92 | 90 | stream->outcnt = outcnt; |
| 93 | 91 | return 0; |
| @@ -102,10 +100,8 @@ static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt, · 8 unmodified lines | ||
| 102 | 100 | return 0; |
| 103 | 101 | |
| 104 | 102 | ret = genradix_prealloc(&stream->in, incnt, gfp); |
| 105 | − if (ret) { | |
| 106 | − genradix_free(&stream->in); | |
| 103 | + if (ret) | |
| 107 | 104 | return ret; |
| 108 | − } | |
| 109 | 105 | |
| 110 | 106 | stream->incnt = incnt; |
| 111 | 107 | return 0; |
| @@ -123,7 +119,7 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, · 11 unmodified lines | ||
| 123 | 119 | * a new one with new outcnt to save memory if needed. |
| 124 | 120 | */ |
| 125 | 121 | if (outcnt == stream->outcnt) |
| 126 | − goto in; | |
| 122 | + goto handle_in; | |
| 127 | 123 | |
| 128 | 124 | /* Filter out chunks queued on streams that won't exist anymore */ |
| 129 | 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 | 129 | ret = sctp_stream_alloc_out(stream, outcnt, gfp); |
| 134 | 130 | if (ret) |
| 135 | − goto out; | |
| 131 | + goto out_err; | |
| 136 | 132 | |
| 137 | 133 | for (i = 0; i < stream->outcnt; i++) |
| 138 | 134 | SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; |
| 139 | 135 | |
| 140 | −in: | |
| 136 | +handle_in: | |
| 141 | 137 | sctp_stream_interleave_init(stream); |
| 142 | 138 | if (!incnt) |
| 143 | 139 | goto out; |
| 144 | 140 | |
| 145 | 141 | ret = sctp_stream_alloc_in(stream, incnt, gfp); |
| 146 | − if (ret) { | |
| 147 | − sched->free(stream); | |
| 148 | − genradix_free(&stream->out); | |
| 149 | − stream->outcnt = 0; | |
| 150 | − goto out; | |
| 151 | − } | |
| 142 | + if (ret) | |
| 143 | + goto in_err; | |
| 144 | + | |
| 145 | + goto out; | |
| 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 | 153 | out: |
| 154 | 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 | 264 | pf->af->from_sk(&addr, sk); |
| 265 | 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 | 267 | pf->to_sk_daddr(&addr, sk); |
| 268 | 268 | |
| 269 | 269 | dst = sctp_transport_dst_check(t); |
| @@ -9,7 +9,7 @@ tipc-y += addr.o bcast.o bearer.o \ · 8 unmodified lines | ||
| 9 | 9 | core.o link.o discover.o msg.o \ |
| 10 | 10 | name_distr.o subscr.o monitor.o name_table.o net.o \ |
| 11 | 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 | 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 | 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 | 204 | return -ENOMEM; |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | − attrbuf = kmalloc_array(tipc_genl_family.maxattr + 1, | |
| 208 | − sizeof(struct nlattr *), GFP_KERNEL); | |
| 207 | + attrbuf = kcalloc(tipc_genl_family.maxattr + 1, | |
| 208 | + sizeof(struct nlattr *), GFP_KERNEL); | |
| 209 | 209 | if (!attrbuf) { |
| 210 | 210 | err = -ENOMEM; |
| 211 | 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 | 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 | 292 | struct sk_buff *skb; |
| 293 | 293 | |
| 294 | 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 | 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 | 545 | /* Remove pending SYN */ |
| 546 | 546 | __skb_queue_purge(&sk->sk_write_queue); |
| 547 | 547 | |
| 548 | − /* Reject all unreceived messages, except on an active connection | |
| 549 | − * (which disconnects locally & sends a 'FIN+' to peer). | |
| 550 | − */ | |
| 551 | − while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { | |
| 552 | − if (TIPC_SKB_CB(skb)->bytes_read) { | |
| 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); | |
| 548 | + /* Remove partially received buffer if any */ | |
| 549 | + skb = skb_peek(&sk->sk_receive_queue); | |
| 550 | + if (skb && TIPC_SKB_CB(skb)->bytes_read) { | |
| 551 | + __skb_unlink(skb, &sk->sk_receive_queue); | |
| 552 | + kfree_skb(skb); | |
| 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 | 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 | 573 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, |
| 569 | 574 | TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode, |
| 570 | 575 | tsk_own_node(tsk), tsk_peer_port(tsk), |
| 571 | 576 | tsk->portid, error); |
| 572 | 577 | if (skb) |
| 573 | 578 | tipc_node_xmit_skb(net, skb, dnode, tsk->portid); |
| 574 | − tipc_node_remove_conn(net, dnode, tsk->portid); | |
| 575 | − tipc_set_sk_state(sk, TIPC_DISCONNECTING); | |
| 579 | + break; | |
| 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 | 2443 | return sock_intr_errno(*timeo_p); |
| 2433 | 2444 | |
| 2434 | 2445 | add_wait_queue(sk_sleep(sk), &wait); |
| 2435 | − done = sk_wait_event(sk, timeo_p, | |
| 2436 | − sk->sk_state != TIPC_CONNECTING, &wait); | |
| 2446 | + done = sk_wait_event(sk, timeo_p, tipc_sk_connected(sk), | |
| 2447 | + &wait); | |
| 2437 | 2448 | remove_wait_queue(sk_sleep(sk), &wait); |
| 2438 | 2449 | } while (!done); |
| 2439 | 2450 | return 0; |
| @@ -2643,7 +2654,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, · 203 unmodified lines | ||
| 2643 | 2654 | * Reject any stray messages received by new socket |
| 2644 | 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 | 2659 | /* Connect new socket to it's peer */ |
| 2649 | 2660 | tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg)); |
| @@ -298,14 +298,14 @@ int main(void) · 297 unmodified lines | ||
| 298 | 298 | req = malloc(sizes.seccomp_notif); |
| 299 | 299 | if (!req) |
| 300 | 300 | goto out_close; |
| 301 | − memset(req, 0, sizeof(*req)); | |
| 302 | 301 | |
| 303 | 302 | resp = malloc(sizes.seccomp_notif_resp); |
| 304 | 303 | if (!resp) |
| 305 | 304 | goto out_req; |
| 306 | − memset(resp, 0, sizeof(*resp)); | |
| 305 | + memset(resp, 0, sizes.seccomp_notif_resp); | |
| 307 | 306 | |
| 308 | 307 | while (1) { |
| 308 | + memset(req, 0, sizes.seccomp_notif); | |
| 309 | 309 | if (ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, req)) { |
| 310 | 310 | perror("ioctl recv"); |
| 311 | 311 | goto out_resp; |
| @@ -14,8 +14,8 @@ config HAVE_GCC_PLUGINS · 13 unmodified lines | ||
| 14 | 14 | An arch should select this symbol if it supports building with |
| 15 | 15 | GCC plugins. |
| 16 | 16 | |
| 17 | −config GCC_PLUGINS | |
| 18 | − bool | |
| 17 | +menuconfig GCC_PLUGINS | |
| 18 | + bool "GCC plugins" | |
| 19 | 19 | depends on HAVE_GCC_PLUGINS |
| 20 | 20 | depends on PLUGIN_HOSTCC != "" |
| 21 | 21 | default y |
| @@ -25,8 +25,7 @@ config GCC_PLUGINS · 3 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | See Documentation/core-api/gcc-plugins.rst for details. |
| 27 | 27 | |
| 28 | −menu "GCC plugins" | |
| 29 | − depends on GCC_PLUGINS | |
| 28 | +if GCC_PLUGINS | |
| 30 | 29 | |
| 31 | 30 | config GCC_PLUGIN_CYC_COMPLEXITY |
| 32 | 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 | 112 | bool |
| 114 | 113 | depends on GCC_PLUGINS && ARM |
| 115 | 114 | |
| 116 | −endmenu | |
| 115 | +endif | |
| @@ -136,7 +136,7 @@ mkdir -p debian/source/ · 135 unmodified lines | ||
| 136 | 136 | echo "1.0" > debian/source/format |
| 137 | 137 | |
| 138 | 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 | 140 | extra_build_depends="$extra_build_depends, $(if_enabled_echo CONFIG_SYSTEM_TRUSTED_KEYRING libssl-dev:native)" |
| 141 | 141 | |
| 142 | 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 | 624 | void __aa_bump_ns_revision(struct aa_ns *ns) |
| 625 | 625 | { |
| 626 | − ns->revision++; | |
| 626 | + WRITE_ONCE(ns->revision, ns->revision + 1); | |
| 627 | 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 | 318 | if (!bprm || !profile->xattr_count) |
| 319 | 319 | return 0; |
| 320 | + might_sleep(); | |
| 320 | 321 | |
| 321 | 322 | /* transition from exec match to xattr set */ |
| 322 | 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 | 366 | * @bprm - binprm structure of transitioning task |
| 366 | − * @name - to match against (NOT NULL) | |
| 367 | + * @ns: the current namespace (NOT NULL) | |
| 367 | 368 | * @head - profile list to walk (NOT NULL) |
| 369 | + * @name - to match against (NOT NULL) | |
| 368 | 370 | * @info - info message if there was an error (NOT NULL) |
| 369 | 371 | * |
| 370 | 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 | 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, | |
| 380 | − const char *name, | |
| 381 | − struct list_head *head, | |
| 382 | − const char **info) | |
| 381 | +static struct aa_label *find_attach(const struct linux_binprm *bprm, | |
| 382 | + struct aa_ns *ns, struct list_head *head, | |
| 383 | + const char *name, const char **info) | |
| 383 | 384 | { |
| 384 | 385 | int candidate_len = 0, candidate_xattrs = 0; |
| 385 | 386 | bool conflict = false; |
| @@ -388,6 +389,8 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm, · 2 unmodified lines | ||
| 388 | 389 | AA_BUG(!name); |
| 389 | 390 | AA_BUG(!head); |
| 390 | 391 | |
| 392 | + rcu_read_lock(); | |
| 393 | +restart: | |
| 391 | 394 | list_for_each_entry_rcu(profile, head, base.list) { |
| 392 | 395 | if (profile->label.flags & FLAG_NULL && |
| 393 | 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 | 416 | perm = dfa_user_allow(profile->xmatch, state); |
| 414 | 417 | /* any accepting state means a valid match. */ |
| 415 | 418 | if (perm & MAY_EXEC) { |
| 416 | − int ret; | |
| 419 | + int ret = 0; | |
| 417 | 420 | |
| 418 | 421 | if (count < candidate_len) |
| 419 | 422 | continue; |
| 420 | 423 | |
| 421 | − ret = aa_xattrs_match(bprm, profile, state); | |
| 422 | − /* Fail matching if the xattrs don't match */ | |
| 423 | − if (ret < 0) | |
| 424 | − continue; | |
| 425 | − | |
| 424 | + if (bprm && profile->xattr_count) { | |
| 425 | + long rev = READ_ONCE(ns->revision); | |
| 426 | + | |
| 427 | + if (!aa_get_profile_not0(profile)) | |
| 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 | 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 | 464 | candidate_xattrs = ret; |
| 446 | 465 | conflict = false; |
| 447 | 466 | } |
| 448 | − } else if (!strcmp(profile->base.name, name)) | |
| 467 | + } else if (!strcmp(profile->base.name, name)) { | |
| 449 | 468 | /* |
| 450 | 469 | * old exact non-re match, without conditionals such |
| 451 | 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) { | |
| 457 | − *info = "conflicting profile attachments"; | |
| 477 | + if (!candidate || conflict) { | |
| 478 | + if (conflict) | |
| 479 | + *info = "conflicting profile attachments"; | |
| 480 | + rcu_read_unlock(); | |
| 458 | 481 | return NULL; |
| 459 | 482 | } |
| 460 | 483 | |
| 461 | − return candidate; | |
| 462 | −} | |
| 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)); | |
| 484 | +out: | |
| 485 | + candidate = aa_get_newest_profile(candidate); | |
| 482 | 486 | rcu_read_unlock(); |
| 483 | 487 | |
| 484 | − return profile ? &profile->label : NULL; | |
| 488 | + return &candidate->label; | |
| 485 | 489 | } |
| 486 | 490 | |
| 487 | 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 | 618 | fctx = file_ctx(file); |
| 619 | 619 | |
| 620 | 620 | rcu_read_lock(); |
| 621 | − flabel = aa_get_newest_label(rcu_dereference(fctx->label)); | |
| 622 | − rcu_read_unlock(); | |
| 621 | + flabel = rcu_dereference(fctx->label); | |
| 623 | 622 | AA_BUG(!flabel); |
| 624 | 623 | |
| 625 | 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 | 631 | denied = request & ~fctx->allow; |
| 633 | 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 | 635 | goto done; |
| 636 | + } | |
| 636 | 637 | |
| 638 | + flabel = aa_get_newest_label(flabel); | |
| 639 | + rcu_read_unlock(); | |
| 637 | 640 | /* TODO: label cross check */ |
| 638 | 641 | |
| 639 | 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 | 646 | else if (S_ISSOCK(file_inode(file)->i_mode)) |
| 644 | 647 | error = __file_sock_perm(op, label, flabel, file, request, |
| 645 | 648 | denied); |
| 646 | −done: | |
| 647 | 649 | aa_put_label(flabel); |
| 650 | + | |
| 651 | +done: | |
| 648 | 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 | 442 | buffer = aa_get_buffer(false); |
| 443 | 443 | old_buffer = aa_get_buffer(false); |
| 444 | 444 | error = -ENOMEM; |
| 445 | − if (!buffer || old_buffer) | |
| 445 | + if (!buffer || !old_buffer) | |
| 446 | 446 | goto out; |
| 447 | 447 | |
| 448 | 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 | 1125 | if (!name) { |
| 1126 | 1126 | /* remove namespace - can only happen if fqname[0] == ':' */ |
| 1127 | 1127 | mutex_lock_nested(&ns->parent->lock, ns->level); |
| 1128 | − __aa_remove_ns(ns); | |
| 1129 | 1128 | __aa_bump_ns_revision(ns); |
| 1129 | + __aa_remove_ns(ns); | |
| 1130 | 1130 | mutex_unlock(&ns->parent->lock); |
| 1131 | 1131 | } else { |
| 1132 | 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 | 1138 | goto fail_ns_lock; |
| 1139 | 1139 | } |
| 1140 | 1140 | name = profile->base.hname; |
| 1141 | + __aa_bump_ns_revision(ns); | |
| 1141 | 1142 | __remove_profile(profile); |
| 1142 | 1143 | __aa_labelset_update_subtree(ns); |
| 1143 | − __aa_bump_ns_revision(ns); | |
| 1144 | 1144 | mutex_unlock(&ns->lock); |
| 1145 | 1145 | } |
| 1146 | 1146 | |
| @@ -951,7 +951,8 @@ static bool tomoyo_manager(void) · 950 unmodified lines | ||
| 951 | 951 | exe = tomoyo_get_exe(); |
| 952 | 952 | if (!exe) |
| 953 | 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 | 956 | if (!ptr->head.is_deleted && |
| 956 | 957 | (!tomoyo_pathcmp(domainname, ptr->manager) || |
| 957 | 958 | !strcmp(exe, ptr->manager->name))) { |
| @@ -1095,7 +1096,8 @@ static int tomoyo_delete_domain(char *domainname) · 137 unmodified lines | ||
| 1095 | 1096 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
| 1096 | 1097 | return -EINTR; |
| 1097 | 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 | 1101 | /* Never delete tomoyo_kernel_domain */ |
| 1100 | 1102 | if (domain == &tomoyo_kernel_domain) |
| 1101 | 1103 | continue; |
| @@ -2778,7 +2780,8 @@ void tomoyo_check_profile(void) · 1676 unmodified lines | ||
| 2778 | 2780 | |
| 2779 | 2781 | tomoyo_policy_loaded = true; |
| 2780 | 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 | 2785 | const u8 profile = domain->profile; |
| 2783 | 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 | 42 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
| 43 | 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 | 46 | if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS) |
| 46 | 47 | continue; |
| 47 | 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 | 121 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
| 121 | 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 | 125 | if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS) |
| 124 | 126 | continue; |
| 125 | 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 | 168 | u16 i = 0; |
| 167 | 169 | |
| 168 | 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 | 173 | if (ptr->is_deleted || ptr->type != r->param_type) |
| 171 | 174 | continue; |
| 172 | 175 | if (!check_entry(r, ptr)) |
| @@ -298,7 +301,8 @@ static inline bool tomoyo_scan_transition · 125 unmodified lines | ||
| 298 | 301 | { |
| 299 | 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 | 306 | if (ptr->head.is_deleted || ptr->type != type) |
| 303 | 307 | continue; |
| 304 | 308 | if (ptr->domainname) { |
| @@ -735,7 +739,8 @@ retry: · 430 unmodified lines | ||
| 735 | 739 | |
| 736 | 740 | /* Check 'aggregator' directive. */ |
| 737 | 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 | 744 | if (ptr->head.is_deleted || |
| 740 | 745 | !tomoyo_path_matches_pattern(&exename, |
| 741 | 746 | ptr->original_name)) |
| @@ -133,7 +133,8 @@ tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, · 132 unmodified lines | ||
| 133 | 133 | { |
| 134 | 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 | 138 | if (member->head.is_deleted) |
| 138 | 139 | continue; |
| 139 | 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 | 162 | struct tomoyo_number_group *member; |
| 162 | 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 | 167 | if (member->head.is_deleted) |
| 166 | 168 | continue; |
| 167 | 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 | 193 | bool matched = false; |
| 192 | 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 | 198 | if (member->head.is_deleted) |
| 196 | 199 | continue; |
| 197 | 200 | if (member->address.is_ipv6 != is_ipv6) |
| @@ -217,31 +217,6 @@ out: · 216 unmodified lines | ||
| 217 | 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 | 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 | 254 | break; |
| 280 | 255 | /* To make sure that pos is '\0' terminated. */ |
| 281 | 256 | buf[buf_len - 1] = '\0'; |
| 282 | − /* Get better name for 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:[\$]". */ | |
| 257 | + /* For "pipe:[\$]" and "socket:[\$]". */ | |
| 288 | 258 | if (dentry->d_op && dentry->d_op->d_dname) { |
| 289 | 259 | pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); |
| 290 | 260 | goto encode; |
| @@ -594,7 +594,8 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) · 593 unmodified lines | ||
| 594 | 594 | |
| 595 | 595 | name.name = domainname; |
| 596 | 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 | 599 | if (!domain->is_deleted && |
| 599 | 600 | !tomoyo_pathcmp(&name, domain->domainname)) |
| 600 | 601 | return domain; |
| @@ -1028,7 +1029,8 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r) · 427 unmodified lines | ||
| 1028 | 1029 | return false; |
| 1029 | 1030 | if (!domain) |
| 1030 | 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 | 1034 | u16 perm; |
| 1033 | 1035 | u8 i; |
| 1034 | 1036 | |
| @@ -363,7 +363,6 @@ static const struct regmap_config hda_regmap_cfg = { · 362 unmodified lines | ||
| 363 | 363 | .reg_write = hda_reg_write, |
| 364 | 364 | .use_single_read = true, |
| 365 | 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 | 283 | /* quirks for old Intel chipsets */ |
| 284 | 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 | 288 | /* quirks for Intel PCH */ |
| 288 | 289 | #define AZX_DCAPS_INTEL_PCH_BASE \ |
| 289 | 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 | 293 | /* PCH up to IVB; no runtime PM; bind with i915 gfx */ |
| 293 | 294 | #define AZX_DCAPS_INTEL_PCH_NOPM \ |
| @@ -302,13 +303,13 @@ enum { · 8 unmodified lines | ||
| 302 | 303 | #define AZX_DCAPS_INTEL_HASWELL \ |
| 303 | 304 | (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\ |
| 304 | 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 | 308 | /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */ |
| 308 | 309 | #define AZX_DCAPS_INTEL_BROADWELL \ |
| 309 | 310 | (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\ |
| 310 | 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 | 314 | #define AZX_DCAPS_INTEL_BAYTRAIL \ |
| 314 | 315 | (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT) |
| @@ -1410,7 +1411,17 @@ static bool atpx_present(void) · 1095 unmodified lines | ||
| 1410 | 1411 | acpi_handle dhandle, atpx_handle; |
| 1411 | 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 | 1425 | dhandle = ACPI_HANDLE(&pdev->dev); |
| 1415 | 1426 | if (dhandle) { |
| 1416 | 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 | 412 | case 0x10ec0672: |
| 413 | 413 | alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ |
| 414 | 414 | break; |
| 415 | + case 0x10ec0222: | |
| 415 | 416 | case 0x10ec0623: |
| 416 | 417 | alc_update_coef_idx(codec, 0x19, 1<<13, 0); |
| 417 | 418 | break; |
| @@ -430,6 +431,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) · 12 unmodified lines | ||
| 430 | 431 | break; |
| 431 | 432 | case 0x10ec0899: |
| 432 | 433 | case 0x10ec0900: |
| 434 | + case 0x10ec0b00: | |
| 433 | 435 | case 0x10ec1168: |
| 434 | 436 | case 0x10ec1220: |
| 435 | 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 | 503 | struct alc_spec *spec = codec->spec; |
| 502 | 504 | |
| 503 | 505 | switch (codec->core.vendor_id) { |
| 506 | + case 0x10ec0283: | |
| 504 | 507 | case 0x10ec0286: |
| 505 | 508 | case 0x10ec0288: |
| 506 | 509 | case 0x10ec0298: |
| @@ -2525,6 +2528,7 @@ static int patch_alc882(struct hda_codec *codec) · 2018 unmodified lines | ||
| 2525 | 2528 | case 0x10ec0882: |
| 2526 | 2529 | case 0x10ec0885: |
| 2527 | 2530 | case 0x10ec0900: |
| 2531 | + case 0x10ec0b00: | |
| 2528 | 2532 | case 0x10ec1220: |
| 2529 | 2533 | break; |
| 2530 | 2534 | default: |
| @@ -5904,9 +5908,12 @@ enum { · 3373 unmodified lines | ||
| 5904 | 5908 | ALC256_FIXUP_ASUS_HEADSET_MIC, |
| 5905 | 5909 | ALC256_FIXUP_ASUS_MIC_NO_PRESENCE, |
| 5906 | 5910 | ALC299_FIXUP_PREDATOR_SPK, |
| 5907 | − ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC, | |
| 5908 | 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 | 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 | 6992 | .type = HDA_FIXUP_PINS, |
| 6986 | 6993 | .v.pins = (const struct hda_pintbl[]) { |
| 6987 | − { 0x14, 0x411111f0 }, /* disable confusing internal speaker */ | |
| 6988 | − { 0x19, 0x04a11150 }, /* use as headset mic, without its own jack detect */ | |
| 6994 | + { 0x19, 0x04a11040 }, | |
| 6995 | + { 0x21, 0x04211020 }, | |
| 6989 | 6996 | { } |
| 6990 | 6997 | }, |
| 6991 | 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 | 7002 | .type = HDA_FIXUP_PINS, |
| 6996 | 7003 | .v.pins = (const struct hda_pintbl[]) { |
| 6997 | − { 0x19, 0x04a11040 }, | |
| 6998 | − { 0x21, 0x04211020 }, | |
| 7004 | + { 0x17, 0x90170130 }, /* bass spk */ | |
| 6999 | 7005 | { } |
| 7000 | 7006 | }, |
| 7001 | 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 | 7023 | .type = HDA_FIXUP_FUNC, |
| 7006 | 7024 | /* The GPIO must be pulled to initialize the AMP */ |
| 7007 | 7025 | .v.func = alc_fixup_gpio4, |
| 7008 | 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 | 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 | 7099 | SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), |
| 7081 | 7100 | SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 7082 | 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 | 7104 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 7084 | 7105 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 7085 | 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 | 7188 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), |
| 7168 | 7189 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), |
| 7169 | 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 | 7192 | SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), |
| 7172 | 7193 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
| 7173 | 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 | 7260 | SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), |
| 7240 | 7261 | SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), |
| 7241 | 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 | 7264 | SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1), |
| 7243 | 7265 | SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), |
| 7244 | 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 | 9259 | HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662), |
| 9238 | 9260 | HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882), |
| 9239 | 9261 | HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882), |
| 9262 | + HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882), | |
| 9240 | 9263 | HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882), |
| 9241 | 9264 | HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882), |
| 9242 | 9265 | {} /* terminator */ |
| @@ -647,6 +647,7 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, · 646 unmodified lines | ||
| 647 | 647 | unsigned long flags; |
| 648 | 648 | unsigned char mclk_change; |
| 649 | 649 | unsigned int i, old_rate; |
| 650 | + bool call_set_rate = false; | |
| 650 | 651 | |
| 651 | 652 | if (rate > ice->hw_rates->list[ice->hw_rates->count - 1]) |
| 652 | 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 | 671 | * setting clock rate for internal clock mode */ |
| 671 | 672 | old_rate = ice->get_rate(ice); |
| 672 | 673 | if (force || (old_rate != rate)) |
| 673 | − ice->set_rate(ice, rate); | |
| 674 | + call_set_rate = true; | |
| 674 | 675 | else if (rate == ice->cur_rate) { |
| 675 | 676 | spin_unlock_irqrestore(&ice->reg_lock, flags); |
| 676 | 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 | 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 | 687 | /* setting master clock */ |
| 683 | 688 | mclk_change = ice->set_mclk(ice, rate); |
| 684 | 689 | |
| 685 | − spin_unlock_irqrestore(&ice->reg_lock, flags); | |
| 686 | − | |
| 687 | 690 | if (mclk_change && ice->gpio.i2s_mclk_changed) |
| 688 | 691 | ice->gpio.i2s_mclk_changed(ice); |
| 689 | 692 | if (ice->gpio.set_pro_rate) |
| @@ -505,15 +505,20 @@ static int fsl_audmix_probe(struct platform_device *pdev) · 504 unmodified lines | ||
| 505 | 505 | ARRAY_SIZE(fsl_audmix_dai)); |
| 506 | 506 | if (ret) { |
| 507 | 507 | dev_err(dev, "failed to register ASoC DAI\n"); |
| 508 | − return ret; | |
| 508 | + goto err_disable_pm; | |
| 509 | 509 | } |
| 510 | 510 | |
| 511 | 511 | priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0); |
| 512 | 512 | if (IS_ERR(priv->pdev)) { |
| 513 | 513 | ret = PTR_ERR(priv->pdev); |
| 514 | 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 | 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 | 527 | struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev); |
| 523 | 528 | |
| 529 | + pm_runtime_disable(&pdev->dev); | |
| 530 | + | |
| 524 | 531 | if (priv->pdev) |
| 525 | 532 | platform_device_unregister(priv->pdev); |
| 526 | 533 | |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/clk.h> |
| 12 | 12 | #include <linux/dmi.h> |
| 13 | 13 | #include <linux/slab.h> |
| 14 | −#include <asm/cpu_device_id.h> | |
| 15 | 14 | #include <linux/acpi.h> |
| 16 | 15 | #include <sound/core.h> |
| 17 | 16 | #include <sound/jack.h> |
| @@ -479,6 +479,12 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( · 478 unmodified lines | ||
| 479 | 479 | goto free_rtd; |
| 480 | 480 | |
| 481 | 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 | 488 | dev_set_drvdata(dev, rtd); |
| 483 | 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 | 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 | 503 | rtd->card = card; |
| 504 | 504 | rtd->dai_link = dai_link; |
| 505 | 505 | if (!rtd->dai_link->ops) |
| @@ -1871,6 +1871,8 @@ match: · 1365 unmodified lines | ||
| 1871 | 1871 | |
| 1872 | 1872 | /* convert non BE into BE */ |
| 1873 | 1873 | dai_link->no_pcm = 1; |
| 1874 | + dai_link->dpcm_playback = 1; | |
| 1875 | + dai_link->dpcm_capture = 1; | |
| 1874 | 1876 | |
| 1875 | 1877 | /* override any BE fixups */ |
| 1876 | 1878 | dai_link->be_hw_params_fixup = |
| @@ -548,12 +548,12 @@ static void remove_link(struct snd_soc_component *comp, · 547 unmodified lines | ||
| 548 | 548 | if (dobj->ops && dobj->ops->link_unload) |
| 549 | 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 | 554 | kfree(link->name); |
| 552 | 555 | kfree(link->stream_name); |
| 553 | 556 | kfree(link->cpus->dai_name); |
| 554 | − | |
| 555 | − list_del(&dobj->list); | |
| 556 | − snd_soc_remove_dai_link(comp->card, link); | |
| 557 | 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 | 210 | priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains, |
| 211 | 211 | sizeof(*priv->pd_dev), GFP_KERNEL); |
| 212 | − if (!priv) | |
| 212 | + if (!priv->pd_dev) | |
| 213 | 213 | return -ENOMEM; |
| 214 | 214 | |
| 215 | 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 | 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 | 310 | return 0; |
| 308 | 311 | |
| 309 | 312 | exit_pdev_unregister: |
| @@ -216,6 +216,8 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream, · 215 unmodified lines | ||
| 216 | 216 | link_dev = hda_link_stream_assign(bus, substream); |
| 217 | 217 | if (!link_dev) |
| 218 | 218 | return -EBUSY; |
| 219 | + | |
| 220 | + snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); | |
| 219 | 221 | } |
| 220 | 222 | |
| 221 | 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 | 230 | if (ret < 0) |
| 229 | 231 | return ret; |
| 230 | 232 | |
| 231 | − snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); | |
| 232 | − | |
| 233 | 233 | link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); |
| 234 | 234 | if (!link) |
| 235 | 235 | return -EINVAL; |
| @@ -361,6 +361,13 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream, · 125 unmodified lines | ||
| 361 | 361 | bus = hstream->bus; |
| 362 | 362 | rtd = snd_pcm_substream_chip(substream); |
| 363 | 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 | 371 | hda_stream = hstream_to_sof_hda_stream(link_dev); |
| 365 | 372 | |
| 366 | 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 | 827 | struct snd_sof_ipc *ipc = sdev->ipc; |
| 828 | 828 | |
| 829 | + if (!ipc) | |
| 830 | + return; | |
| 831 | + | |
| 829 | 832 | /* disable sending of ipc's */ |
| 830 | 833 | mutex_lock(&ipc->tx_mutex); |
| 831 | 834 | ipc->disable_ipc_tx = true; |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/delay.h> |
| 13 | 13 | #include <linux/module.h> |
| 14 | 14 | #include <linux/of_platform.h> |
| 15 | −#include <linux/pinctrl/consumer.h> | |
| 16 | 15 | #include <linux/regmap.h> |
| 17 | 16 | #include <linux/reset.h> |
| 18 | 17 | |
| @@ -220,6 +219,7 @@ · 201 unmodified lines | ||
| 220 | 219 | * @slave_config: dma slave channel runtime config pointer |
| 221 | 220 | * @phys_addr: SPDIFRX registers physical base address |
| 222 | 221 | * @lock: synchronization enabling lock |
| 222 | + * @irq_lock: prevent race condition with IRQ on stream state | |
| 223 | 223 | * @cs: channel status buffer |
| 224 | 224 | * @ub: user data buffer |
| 225 | 225 | * @irq: SPDIFRX interrupt line |
| @@ -240,6 +240,7 @@ struct stm32_spdifrx_data { · 14 unmodified lines | ||
| 240 | 240 | struct dma_slave_config slave_config; |
| 241 | 241 | dma_addr_t phys_addr; |
| 242 | 242 | spinlock_t lock; /* Sync enabling lock */ |
| 243 | + spinlock_t irq_lock; /* Prevent race condition on stream state */ | |
| 243 | 244 | unsigned char cs[SPDIFRX_CS_BYTES_NB]; |
| 244 | 245 | unsigned char ub[SPDIFRX_UB_BYTES_NB]; |
| 245 | 246 | int irq; |
| @@ -320,6 +321,7 @@ static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx) · 74 unmodified lines | ||
| 320 | 321 | static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) |
| 321 | 322 | { |
| 322 | 323 | int cr, cr_mask, imr, ret; |
| 324 | + unsigned long flags; | |
| 323 | 325 | |
| 324 | 326 | /* Enable IRQs */ |
| 325 | 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 | 329 | if (ret) |
| 328 | 330 | return ret; |
| 329 | 331 | |
| 330 | − spin_lock(&spdifrx->lock); | |
| 332 | + spin_lock_irqsave(&spdifrx->lock, flags); | |
| 331 | 333 | |
| 332 | 334 | spdifrx->refcount++; |
| 333 | 335 | |
| @@ -362,7 +364,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) · 28 unmodified lines | ||
| 362 | 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 | 369 | return ret; |
| 368 | 370 | } |
| @@ -370,11 +372,12 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) · 1 unmodified line | ||
| 370 | 372 | static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx) |
| 371 | 373 | { |
| 372 | 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 | 379 | if (--spdifrx->refcount) { |
| 377 | − spin_unlock(&spdifrx->lock); | |
| 380 | + spin_unlock_irqrestore(&spdifrx->lock, flags); | |
| 378 | 381 | return; |
| 379 | 382 | } |
| 380 | 383 | |
| @@ -393,7 +396,7 @@ static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx) · 12 unmodified lines | ||
| 393 | 396 | regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, ®); |
| 394 | 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 | 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 | 483 | memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB); |
| 481 | 484 | memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB); |
| 482 | 485 | |
| 483 | − pinctrl_pm_select_default_state(&spdifrx->pdev->dev); | |
| 484 | − | |
| 485 | 486 | ret = stm32_spdifrx_dma_ctrl_start(spdifrx); |
| 486 | 487 | if (ret < 0) |
| 487 | 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 | 515 | end: |
| 515 | 516 | clk_disable_unprepare(spdifrx->kclk); |
| 516 | − pinctrl_pm_select_sleep_state(&spdifrx->pdev->dev); | |
| 517 | 517 | |
| 518 | 518 | return ret; |
| 519 | 519 | } |
| @@ -665,7 +665,6 @@ static const struct regmap_config stm32_h7_spdifrx_regmap_conf = { · 145 unmodified lines | ||
| 665 | 665 | static irqreturn_t stm32_spdifrx_isr(int irq, void *devid) |
| 666 | 666 | { |
| 667 | 667 | struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid; |
| 668 | − struct snd_pcm_substream *substream = spdifrx->substream; | |
| 669 | 668 | struct platform_device *pdev = spdifrx->pdev; |
| 670 | 669 | unsigned int cr, mask, sr, imr; |
| 671 | 670 | unsigned int flags, sync_state; |
| @@ -745,14 +744,19 @@ static irqreturn_t stm32_spdifrx_isr(int irq, void *devid) · 73 unmodified lines | ||
| 745 | 744 | return IRQ_HANDLED; |
| 746 | 745 | } |
| 747 | 746 | |
| 748 | − if (substream) | |
| 749 | − snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); | |
| 747 | + spin_lock(&spdifrx->irq_lock); | |
| 748 | + if (spdifrx->substream) | |
| 749 | + snd_pcm_stop(spdifrx->substream, | |
| 750 | + SNDRV_PCM_STATE_DISCONNECTED); | |
| 751 | + spin_unlock(&spdifrx->irq_lock); | |
| 750 | 752 | |
| 751 | 753 | return IRQ_HANDLED; |
| 752 | 754 | } |
| 753 | 755 | |
| 754 | − if (err_xrun && substream) | |
| 755 | − snd_pcm_stop_xrun(substream); | |
| 756 | + spin_lock(&spdifrx->irq_lock); | |
| 757 | + if (err_xrun && spdifrx->substream) | |
| 758 | + snd_pcm_stop_xrun(spdifrx->substream); | |
| 759 | + spin_unlock(&spdifrx->irq_lock); | |
| 756 | 760 | |
| 757 | 761 | return IRQ_HANDLED; |
| 758 | 762 | } |
| @@ -761,9 +765,12 @@ static int stm32_spdifrx_startup(struct snd_pcm_substream *substream, · 2 unmodified lines | ||
| 761 | 765 | struct snd_soc_dai *cpu_dai) |
| 762 | 766 | { |
| 763 | 767 | struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); |
| 768 | + unsigned long flags; | |
| 764 | 769 | int ret; |
| 765 | 770 | |
| 771 | + spin_lock_irqsave(&spdifrx->irq_lock, flags); | |
| 766 | 772 | spdifrx->substream = substream; |
| 773 | + spin_unlock_irqrestore(&spdifrx->irq_lock, flags); | |
| 767 | 774 | |
| 768 | 775 | ret = clk_prepare_enable(spdifrx->kclk); |
| 769 | 776 | if (ret) |
| @@ -839,8 +846,12 @@ static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream, · 69 unmodified lines | ||
| 839 | 846 | struct snd_soc_dai *cpu_dai) |
| 840 | 847 | { |
| 841 | 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 | 852 | spdifrx->substream = NULL; |
| 853 | + spin_unlock_irqrestore(&spdifrx->irq_lock, flags); | |
| 854 | + | |
| 844 | 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 | 955 | spdifrx->pdev = pdev; |
| 945 | 956 | init_completion(&spdifrx->cs_completion); |
| 946 | 957 | spin_lock_init(&spdifrx->lock); |
| 958 | + spin_lock_init(&spdifrx->irq_lock); | |
| 947 | 959 | |
| 948 | 960 | platform_set_drvdata(pdev, spdifrx); |
| 949 | 961 | |
| @@ -145,6 +145,7 @@ struct snd_usb_substream { · 144 unmodified lines | ||
| 145 | 145 | struct snd_usb_endpoint *sync_endpoint; |
| 146 | 146 | unsigned long flags; |
| 147 | 147 | bool need_setup_ep; /* (re)configure EP at prepare? */ |
| 148 | + bool need_setup_fmt; /* (re)configure fmt after resume? */ | |
| 148 | 149 | unsigned int speed; /* USB_SPEED_XXX */ |
| 149 | 150 | |
| 150 | 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 | 506 | if (WARN_ON(!iface)) |
| 507 | 507 | return -EINVAL; |
| 508 | 508 | alts = usb_altnum_to_altsetting(iface, fmt->altsetting); |
| 509 | − altsd = get_iface_desc(alts); | |
| 510 | − if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting)) | |
| 509 | + if (WARN_ON(!alts)) | |
| 511 | 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 | 514 | return 0; |
| 515 | 515 | |
| 516 | 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 | 518 | if (!subs->stream->chip->keep_iface) { |
| 519 | 519 | err = usb_set_interface(subs->dev, subs->interface, 0); |
| 520 | 520 | if (err < 0) { |
| @@ -528,6 +528,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) · 7 unmodified lines | ||
| 528 | 528 | subs->altset_idx = 0; |
| 529 | 529 | } |
| 530 | 530 | |
| 531 | + if (subs->need_setup_fmt) | |
| 532 | + subs->need_setup_fmt = false; | |
| 533 | + | |
| 531 | 534 | /* set interface */ |
| 532 | 535 | if (iface->cur_altsetting != alts) { |
| 533 | 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 | 1731 | subs->data_endpoint->retire_data_urb = retire_playback_urb; |
| 1729 | 1732 | subs->running = 0; |
| 1730 | 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 | 1743 | return -EINVAL; |
| @@ -1760,6 +1770,13 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream · 26 unmodified lines | ||
| 1760 | 1770 | subs->data_endpoint->retire_data_urb = retire_capture_urb; |
| 1761 | 1771 | subs->running = 1; |
| 1762 | 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 | 1782 | return -EINVAL; |
| @@ -3466,7 +3466,8 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), · 3465 unmodified lines | ||
| 3466 | 3466 | .vendor_name = "Dell", |
| 3467 | 3467 | .product_name = "WD19 Dock", |
| 3468 | 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 | 3473 | /* MOTU Microbook II */ |
| @@ -508,6 +508,16 @@ static int create_standard_mixer_quirk(struct snd_usb_audio *chip, · 507 unmodified lines | ||
| 508 | 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 | 522 | * audio-interface quirks |
| 513 | 523 | * |
| @@ -546,6 +556,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, · 32 unmodified lines | ||
| 546 | 556 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, |
| 547 | 557 | [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk, |
| 548 | 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 | 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 | 1397 | case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ |
| 1387 | 1398 | case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ |
| 1388 | 1399 | case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ |
| 1400 | + case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */ | |
| 1389 | 1401 | case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ |
| 1390 | 1402 | case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */ |
| 1391 | 1403 | case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ |
| @@ -33,7 +33,7 @@ struct snd_usb_audio { · 32 unmodified lines | ||
| 33 | 33 | wait_queue_head_t shutdown_wait; |
| 34 | 34 | unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ |
| 35 | 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 | 37 | int num_interfaces; |
| 38 | 38 | int num_suspended_intf; |
| 39 | 39 | int sample_rate_read_error; |
| @@ -98,6 +98,7 @@ enum quirk_type { · 58 unmodified lines | ||
| 98 | 98 | QUIRK_AUDIO_EDIROL_UAXX, |
| 99 | 99 | QUIRK_AUDIO_ALIGN_TRANSFER, |
| 100 | 100 | QUIRK_AUDIO_STANDARD_MIXER, |
| 101 | + QUIRK_SETUP_FMT_AFTER_RESUME, | |
| 101 | 102 | |
| 102 | 103 | QUIRK_TYPE_COUNT |
| 103 | 104 | }; |
| @@ -138,6 +138,7 @@ STATIC_OBJDIR := $(OUTPUT)staticobjs/ · 137 unmodified lines | ||
| 138 | 138 | BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o |
| 139 | 139 | BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o |
| 140 | 140 | VERSION_SCRIPT := libbpf.map |
| 141 | +BPF_HELPER_DEFS := $(OUTPUT)bpf_helper_defs.h | |
| 141 | 142 | |
| 142 | 143 | LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) |
| 143 | 144 | LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) |
| @@ -159,7 +160,7 @@ all: fixdep · 15 unmodified lines | ||
| 159 | 160 | |
| 160 | 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 | 164 | @(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ |
| 164 | 165 | (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \ |
| 165 | 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 | 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 | 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 | 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 | 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 | 188 | $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) |
| 188 | 189 | |
| @@ -243,7 +244,7 @@ install_lib: all_cmd · 54 unmodified lines | ||
| 243 | 244 | $(call do_install_mkdir,$(libdir_SQ)); \ |
| 244 | 245 | cp -fpR $(LIB_FILE) $(DESTDIR)$(libdir_SQ) |
| 245 | 246 | |
| 246 | −install_headers: bpf_helper_defs.h | |
| 247 | +install_headers: $(BPF_HELPER_DEFS) | |
| 247 | 248 | $(call QUIET_INSTALL, headers) \ |
| 248 | 249 | $(call do_install,bpf.h,$(prefix)/include/bpf,644); \ |
| 249 | 250 | $(call do_install,libbpf.h,$(prefix)/include/bpf,644); \ |
| @@ -251,7 +252,7 @@ install_headers: bpf_helper_defs.h · 1 unmodified line | ||
| 251 | 252 | $(call do_install,libbpf_util.h,$(prefix)/include/bpf,644); \ |
| 252 | 253 | $(call do_install,xsk.h,$(prefix)/include/bpf,644); \ |
| 253 | 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 | 256 | $(call do_install,bpf_tracing.h,$(prefix)/include/bpf,644); \ |
| 256 | 257 | $(call do_install,bpf_endian.h,$(prefix)/include/bpf,644); \ |
| 257 | 258 | $(call do_install,bpf_core_read.h,$(prefix)/include/bpf,644); |
| @@ -271,7 +272,7 @@ config-clean: · 13 unmodified lines | ||
| 271 | 272 | clean: |
| 272 | 273 | $(call QUIET_CLEAN, libbpf) $(RM) -rf $(CMD_TARGETS) \ |
| 273 | 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 | 276 | $(SHARED_OBJDIR) $(STATIC_OBJDIR) |
| 276 | 277 | $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf |
| 277 | 278 | |
| @@ -31,15 +31,12 @@ class KunitStatus(Enum): · 30 unmodified lines | ||
| 31 | 31 | TEST_FAILURE = auto() |
| 32 | 32 | |
| 33 | 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 | 35 | shutil.copyfile('arch/um/configs/kunit_defconfig', |
| 36 | − kunit_kernel.KUNITCONFIG_PATH) | |
| 36 | + kunit_kernel.kunitconfig_path) | |
| 37 | 37 | |
| 38 | 38 | def run_tests(linux: kunit_kernel.LinuxSourceTree, |
| 39 | 39 | request: KunitRequest) -> KunitResult: |
| 40 | − if request.defconfig: | |
| 41 | − create_default_kunitconfig() | |
| 42 | − | |
| 43 | 40 | config_start = time.time() |
| 44 | 41 | success = linux.build_reconfig(request.build_dir) |
| 45 | 42 | config_end = time.time() |
| @@ -108,15 +105,22 @@ def main(argv, linux=None): · 62 unmodified lines | ||
| 108 | 105 | run_parser.add_argument('--build_dir', |
| 109 | 106 | help='As in the make command, it specifies the build ' |
| 110 | 107 | 'directory.', |
| 111 | − type=str, default=None, metavar='build_dir') | |
| 108 | + type=str, default='', metavar='build_dir') | |
| 112 | 109 | |
| 113 | 110 | run_parser.add_argument('--defconfig', |
| 114 | − help='Uses a default kunitconfig.', | |
| 111 | + help='Uses a default .kunitconfig.', | |
| 115 | 112 | action='store_true') |
| 116 | 113 | |
| 117 | 114 | cli_args = parser.parse_args(argv) |
| 118 | 115 | |
| 119 | 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 | 124 | if cli_args.defconfig: |
| 121 | 125 | create_default_kunitconfig() |
| 122 | 126 | |
| @@ -14,7 +14,7 @@ import os · 13 unmodified lines | ||
| 14 | 14 | import kunit_config |
| 15 | 15 | |
| 16 | 16 | KCONFIG_PATH = '.config' |
| 17 | −KUNITCONFIG_PATH = 'kunitconfig' | |
| 17 | +kunitconfig_path = '.kunitconfig' | |
| 18 | 18 | |
| 19 | 19 | class ConfigError(Exception): |
| 20 | 20 | """Represents an error trying to configure the Linux kernel.""" |
| @@ -82,7 +82,7 @@ class LinuxSourceTree(object): · 61 unmodified lines | ||
| 82 | 82 | |
| 83 | 83 | def __init__(self): |
| 84 | 84 | self._kconfig = kunit_config.Kconfig() |
| 85 | − self._kconfig.read_from_file(KUNITCONFIG_PATH) | |
| 85 | + self._kconfig.read_from_file(kunitconfig_path) | |
| 86 | 86 | self._ops = LinuxSourceTreeOperations() |
| 87 | 87 | |
| 88 | 88 | def clean(self): |
| @@ -111,7 +111,7 @@ class LinuxSourceTree(object): · 22 unmodified lines | ||
| 111 | 111 | return True |
| 112 | 112 | |
| 113 | 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 | 115 | kconfig_path = get_kconfig_path(build_dir) |
| 116 | 116 | if os.path.exists(kconfig_path): |
| 117 | 117 | existing_kconfig = kunit_config.Kconfig() |
| @@ -140,10 +140,10 @@ class LinuxSourceTree(object): · 22 unmodified lines | ||
| 140 | 140 | return False |
| 141 | 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 | 144 | args.extend(['mem=256M']) |
| 145 | 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 | 147 | for line in process.stdout: |
| 148 | 148 | f.write(line.rstrip().decode('ascii') + '\n') |
| 149 | 149 | yield line.rstrip().decode('ascii') |
| @@ -174,6 +174,7 @@ class KUnitMainTest(unittest.TestCase): · 173 unmodified lines | ||
| 174 | 174 | kunit.main(['run'], self.linux_source_mock) |
| 175 | 175 | assert self.linux_source_mock.build_reconfig.call_count == 1 |
| 176 | 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 | 178 | self.print_mock.assert_any_call(StrContains('Testing complete.')) |
| 178 | 179 | |
| 179 | 180 | def test_run_passes_args_fail(self): |
| @@ -199,7 +200,14 @@ class KUnitMainTest(unittest.TestCase): · 19 unmodified lines | ||
| 199 | 200 | timeout = 3453 |
| 200 | 201 | kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock) |
| 201 | 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 | 211 | self.print_mock.assert_any_call(StrContains('Testing complete.')) |
| 204 | 212 | |
| 205 | 213 | if __name__ == '__main__': |
| @@ -40,3 +40,4 @@ xdping · 39 unmodified lines | ||
| 40 | 40 | test_cpp |
| 41 | 41 | /no_alu32 |
| 42 | 42 | /bpf_gcc |
| 43 | +bpf_helper_defs.h | |
| @@ -120,9 +120,9 @@ force: · 119 unmodified lines | ||
| 120 | 120 | $(BPFOBJ): force |
| 121 | 121 | $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ |
| 122 | 122 | |
| 123 | −BPF_HELPERS := $(BPFDIR)/bpf_helper_defs.h $(wildcard $(BPFDIR)/bpf_*.h) | |
| 124 | −$(BPFDIR)/bpf_helper_defs.h: | |
| 125 | − $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ bpf_helper_defs.h | |
| 123 | +BPF_HELPERS := $(OUTPUT)/bpf_helper_defs.h $(wildcard $(BPFDIR)/bpf_*.h) | |
| 124 | +$(OUTPUT)/bpf_helper_defs.h: | |
| 125 | + $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ $(OUTPUT)/bpf_helper_defs.h | |
| 126 | 126 | |
| 127 | 127 | # Get Clang's default includes on this system, as opposed to those seen by |
| 128 | 128 | # '-target bpf'. This fixes "missing" files on some architectures/distros, |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | 3 | CFLAGS += -I../../../../../usr/include/ |
| 4 | −LDFLAGS += -lpthread | |
| 4 | +LDLIBS += -lpthread | |
| 5 | 5 | TEST_GEN_PROGS := epoll_wakeup_test |
| 6 | 6 | |
| 7 | 7 | include ../../lib.mk |
| @@ -34,6 +34,12 @@ test_modprobe() · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 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 | 43 | trap "test_modprobe" EXIT |
| 38 | 44 | if [ ! -d $DIR ]; then |
| 39 | 45 | modprobe test_firmware |
| @@ -7,6 +7,9 @@ · 6 unmodified lines | ||
| 7 | 7 | MAX_RETRIES=600 |
| 8 | 8 | RETRY_INTERVAL=".1" # seconds |
| 9 | 9 | |
| 10 | +# Kselftest framework requirement - SKIP code is 4 | |
| 11 | +ksft_skip=4 | |
| 12 | + | |
| 10 | 13 | # log(msg) - write message to kernel log |
| 11 | 14 | # msg - insightful words |
| 12 | 15 | function log() { |
| @@ -18,7 +21,16 @@ function log() { · 5 unmodified lines | ||
| 18 | 21 | function skip() { |
| 19 | 22 | log "SKIP: $1" |
| 20 | 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 | 36 | # die(msg) - game over, man |
| @@ -62,6 +74,7 @@ function set_ftrace_enabled() { · 37 unmodified lines | ||
| 62 | 74 | # for verbose livepatching output and turn on |
| 63 | 75 | # the ftrace_enabled sysctl. |
| 64 | 76 | function setup_config() { |
| 77 | + is_root | |
| 65 | 78 | push_config |
| 66 | 79 | set_dynamic_debug |
| 67 | 80 | set_ftrace_enabled 1 |
| @@ -8,8 +8,7 @@ MOD_LIVEPATCH=test_klp_state · 7 unmodified lines | ||
| 8 | 8 | MOD_LIVEPATCH2=test_klp_state2 |
| 9 | 9 | MOD_LIVEPATCH3=test_klp_state3 |
| 10 | 10 | |
| 11 | −set_dynamic_debug | |
| 12 | − | |
| 11 | +setup_config | |
| 13 | 12 | |
| 14 | 13 | # TEST: Loading and removing a module that modifies the system state |
| 15 | 14 | |
| @@ -1,6 +1,9 @@ | ||
| 1 | 1 | #!/bin/bash |
| 2 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | |
| 4 | +# Kselftest framework requirement - SKIP code is 4. | |
| 5 | +ksft_skip=4 | |
| 6 | + | |
| 4 | 7 | ALL_TESTS="loopback_test" |
| 5 | 8 | NUM_NETIFS=2 |
| 6 | 9 | source tc_common.sh |
| @@ -72,6 +75,11 @@ setup_prepare() · 65 unmodified lines | ||
| 72 | 75 | |
| 73 | 76 | h1_create |
| 74 | 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 | 85 | cleanup() |
| @@ -226,17 +226,19 @@ check_transfer() · 225 unmodified lines | ||
| 226 | 226 | return 0 |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | −test_tcp_forwarding() | |
| 229 | +test_tcp_forwarding_ip() | |
| 230 | 230 | { |
| 231 | 231 | local nsa=$1 |
| 232 | 232 | local nsb=$2 |
| 233 | + local dstip=$3 | |
| 234 | + local dstport=$4 | |
| 233 | 235 | local lret=0 |
| 234 | 236 | |
| 235 | 237 | ip netns exec $nsb nc -w 5 -l -p 12345 < "$ns2in" > "$ns2out" & |
| 236 | 238 | lpid=$! |
| 237 | 239 | |
| 238 | 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 | 242 | cpid=$! |
| 241 | 243 | |
| 242 | 244 | sleep 3 |
| @@ -258,6 +260,28 @@ test_tcp_forwarding() · 15 unmodified lines | ||
| 258 | 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 | 285 | make_file "$ns1in" "ns1" |
| 262 | 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 | 307 | # Same, but with NAT enabled. |
| 284 | 308 | ip netns exec nsr1 nft -f - <<EOF |
| 285 | 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 | 315 | chain postrouting { |
| 287 | 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 | 320 | EOF |
| 292 | 321 | |
| 293 | −test_tcp_forwarding ns1 ns2 | |
| 322 | +test_tcp_forwarding_nat ns1 ns2 | |
| 294 | 323 | |
| 295 | 324 | if [ $? -eq 0 ] ;then |
| 296 | 325 | echo "PASS: flow offloaded for ns1/ns2 with NAT" |
| @@ -313,7 +342,7 @@ fi · 16 unmodified lines | ||
| 313 | 342 | ip netns exec ns1 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null |
| 314 | 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 | 346 | if [ $? -eq 0 ] ;then |
| 318 | 347 | echo "PASS: flow offloaded for ns1/ns2 with NAT and pmtu discovery" |
| 319 | 348 | else |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <errno.h> |
| 16 | 16 | #include <stddef.h> |
| 17 | 17 | |
| 18 | −static inline pid_t gettid(void) | |
| 18 | +static inline pid_t rseq_gettid(void) | |
| 19 | 19 | { |
| 20 | 20 | return syscall(__NR_gettid); |
| 21 | 21 | } |
| @@ -373,11 +373,12 @@ void *test_percpu_spinlock_thread(void *arg) · 351 unmodified lines | ||
| 373 | 373 | rseq_percpu_unlock(&data->lock, cpu); |
| 374 | 374 | #ifndef BENCHMARK |
| 375 | 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 | 378 | #endif |
| 378 | 379 | } |
| 379 | 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 | 382 | if (!opt_disable_rseq && thread_data->reg && |
| 382 | 383 | rseq_unregister_current_thread()) |
| 383 | 384 | abort(); |
| @@ -454,11 +455,12 @@ void *test_percpu_inc_thread(void *arg) · 70 unmodified lines | ||
| 454 | 455 | } while (rseq_unlikely(ret)); |
| 455 | 456 | #ifndef BENCHMARK |
| 456 | 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 | 460 | #endif |
| 459 | 461 | } |
| 460 | 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 | 464 | if (!opt_disable_rseq && thread_data->reg && |
| 463 | 465 | rseq_unregister_current_thread()) |
| 464 | 466 | abort(); |
| @@ -605,7 +607,7 @@ void *test_percpu_list_thread(void *arg) · 140 unmodified lines | ||
| 605 | 607 | } |
| 606 | 608 | |
| 607 | 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 | 611 | if (!opt_disable_rseq && rseq_unregister_current_thread()) |
| 610 | 612 | abort(); |
| 611 | 613 | |
| @@ -796,7 +798,7 @@ void *test_percpu_buffer_thread(void *arg) · 184 unmodified lines | ||
| 796 | 798 | } |
| 797 | 799 | |
| 798 | 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 | 802 | if (!opt_disable_rseq && rseq_unregister_current_thread()) |
| 801 | 803 | abort(); |
| 802 | 804 | |
| @@ -1011,7 +1013,7 @@ void *test_percpu_memcpy_buffer_thread(void *arg) · 208 unmodified lines | ||
| 1011 | 1013 | } |
| 1012 | 1014 | |
| 1013 | 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 | 1017 | if (!opt_disable_rseq && rseq_unregister_current_thread()) |
| 1016 | 1018 | abort(); |
| 1017 | 1019 | |
| @@ -149,11 +149,13 @@ static inline void rseq_clear_rseq_cs(void) · 148 unmodified lines | ||
| 149 | 149 | /* |
| 150 | 150 | * rseq_prepare_unload() should be invoked by each thread executing a rseq |
| 151 | 151 | * critical section at least once between their last critical section and |
| 152 | − * library unload of the library defining the rseq critical section | |
| 153 | − * (struct rseq_cs). This also applies to use of rseq in code generated by | |
| 154 | − * JIT: rseq_prepare_unload() should be invoked at least once by each | |
| 155 | − * thread executing a rseq critical section before reclaim of the memory | |
| 156 | − * holding the struct rseq_cs. | |
| 152 | + * library unload of the library defining the rseq critical section (struct | |
| 153 | + * rseq_cs) or the code referred to by the struct rseq_cs start_ip and | |
| 154 | + * post_commit_offset fields. This also applies to use of rseq in code | |
| 155 | + * generated by JIT: rseq_prepare_unload() should be invoked at least once by | |
| 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 | 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 | 3158 | EXPECT_GT(poll(&pollfd, 1, -1), 0); |
| 3159 | 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 | 3174 | pollfd.fd = listener; |
| 3164 | 3175 | pollfd.events = POLLIN | POLLOUT; |
| @@ -3278,6 +3289,7 @@ TEST(user_notification_signal) · 113 unmodified lines | ||
| 3278 | 3289 | |
| 3279 | 3290 | close(sk_pair[1]); |
| 3280 | 3291 | |
| 3292 | + memset(&req, 0, sizeof(req)); | |
| 3281 | 3293 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); |
| 3282 | 3294 | |
| 3283 | 3295 | EXPECT_EQ(kill(pid, SIGUSR1), 0); |
| @@ -3296,6 +3308,7 @@ TEST(user_notification_signal) · 12 unmodified lines | ||
| 3296 | 3308 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); |
| 3297 | 3309 | EXPECT_EQ(errno, ENOENT); |
| 3298 | 3310 | |
| 3311 | + memset(&req, 0, sizeof(req)); | |
| 3299 | 3312 | EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); |
| 3300 | 3313 | |
| 3301 | 3314 | resp.id = req.id; |
| @@ -128,7 +128,7 @@ parse() { · 127 unmodified lines | ||
| 128 | 128 | str="${ftype} ${name} ${location} ${str}" |
| 129 | 129 | ;; |
| 130 | 130 | "nod") |
| 131 | − local dev=`LC_ALL=C ls -l "${location}"` | |
| 131 | + local dev="`LC_ALL=C ls -l "${location}"`" | |
| 132 | 132 | local maj=`field 5 ${dev}` |
| 133 | 133 | local min=`field 6 ${dev}` |
| 134 | 134 | maj=${maj%,} |