diff options
831 files changed, 7949 insertions, 3667 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index 640f65e79ef1..8e69345c37cc 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl | |||
| @@ -244,3 +244,11 @@ Description: read only | |||
| 244 | Returns 1 if the psl timebase register is synchronized | 244 | Returns 1 if the psl timebase register is synchronized |
| 245 | with the core timebase register, 0 otherwise. | 245 | with the core timebase register, 0 otherwise. |
| 246 | Users: https://github.com/ibm-capi/libcxl | 246 | Users: https://github.com/ibm-capi/libcxl |
| 247 | |||
| 248 | What: /sys/class/cxl/<card>/tunneled_ops_supported | ||
| 249 | Date: May 2018 | ||
| 250 | Contact: linuxppc-dev@lists.ozlabs.org | ||
| 251 | Description: read only | ||
| 252 | Returns 1 if tunneled operations are supported in capi mode, | ||
| 253 | 0 otherwise. | ||
| 254 | Users: https://github.com/ibm-capi/libcxl | ||
diff --git a/Documentation/acpi/cppc_sysfs.txt b/Documentation/acpi/cppc_sysfs.txt new file mode 100644 index 000000000000..f20fb445135d --- /dev/null +++ b/Documentation/acpi/cppc_sysfs.txt | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | |||
| 2 | Collaborative Processor Performance Control (CPPC) | ||
| 3 | |||
| 4 | CPPC defined in the ACPI spec describes a mechanism for the OS to manage the | ||
| 5 | performance of a logical processor on a contigious and abstract performance | ||
| 6 | scale. CPPC exposes a set of registers to describe abstract performance scale, | ||
| 7 | to request performance levels and to measure per-cpu delivered performance. | ||
| 8 | |||
| 9 | For more details on CPPC please refer to the ACPI specification at: | ||
| 10 | |||
| 11 | http://uefi.org/specifications | ||
| 12 | |||
| 13 | Some of the CPPC registers are exposed via sysfs under: | ||
| 14 | |||
| 15 | /sys/devices/system/cpu/cpuX/acpi_cppc/ | ||
| 16 | |||
| 17 | for each cpu X | ||
| 18 | |||
| 19 | -------------------------------------------------------------------------------- | ||
| 20 | |||
| 21 | $ ls -lR /sys/devices/system/cpu/cpu0/acpi_cppc/ | ||
| 22 | /sys/devices/system/cpu/cpu0/acpi_cppc/: | ||
| 23 | total 0 | ||
| 24 | -r--r--r-- 1 root root 65536 Mar 5 19:38 feedback_ctrs | ||
| 25 | -r--r--r-- 1 root root 65536 Mar 5 19:38 highest_perf | ||
| 26 | -r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_freq | ||
| 27 | -r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_nonlinear_perf | ||
| 28 | -r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_perf | ||
| 29 | -r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_freq | ||
| 30 | -r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_perf | ||
| 31 | -r--r--r-- 1 root root 65536 Mar 5 19:38 reference_perf | ||
| 32 | -r--r--r-- 1 root root 65536 Mar 5 19:38 wraparound_time | ||
| 33 | |||
| 34 | -------------------------------------------------------------------------------- | ||
| 35 | |||
| 36 | * highest_perf : Highest performance of this processor (abstract scale). | ||
| 37 | * nominal_perf : Highest sustained performance of this processor (abstract scale). | ||
| 38 | * lowest_nonlinear_perf : Lowest performance of this processor with nonlinear | ||
| 39 | power savings (abstract scale). | ||
| 40 | * lowest_perf : Lowest performance of this processor (abstract scale). | ||
| 41 | |||
| 42 | * lowest_freq : CPU frequency corresponding to lowest_perf (in MHz). | ||
| 43 | * nominal_freq : CPU frequency corresponding to nominal_perf (in MHz). | ||
| 44 | The above frequencies should only be used to report processor performance in | ||
| 45 | freqency instead of abstract scale. These values should not be used for any | ||
| 46 | functional decisions. | ||
| 47 | |||
| 48 | * feedback_ctrs : Includes both Reference and delivered performance counter. | ||
| 49 | Reference counter ticks up proportional to processor's reference performance. | ||
| 50 | Delivered counter ticks up proportional to processor's delivered performance. | ||
| 51 | * wraparound_time: Minimum time for the feedback counters to wraparound (seconds). | ||
| 52 | * reference_perf : Performance level at which reference performance counter | ||
| 53 | accumulates (abstract scale). | ||
| 54 | |||
| 55 | -------------------------------------------------------------------------------- | ||
| 56 | |||
| 57 | Computing Average Delivered Performance | ||
| 58 | |||
| 59 | Below describes the steps to compute the average performance delivered by taking | ||
| 60 | two different snapshots of feedback counters at time T1 and T2. | ||
| 61 | |||
| 62 | T1: Read feedback_ctrs as fbc_t1 | ||
| 63 | Wait or run some workload | ||
| 64 | T2: Read feedback_ctrs as fbc_t2 | ||
| 65 | |||
| 66 | delivered_counter_delta = fbc_t2[del] - fbc_t1[del] | ||
| 67 | reference_counter_delta = fbc_t2[ref] - fbc_t1[ref] | ||
| 68 | |||
| 69 | delivered_perf = (refernce_perf x delivered_counter_delta) / reference_counter_delta | ||
diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst index d2b6fda3d67b..ab2fe0eda1d7 100644 --- a/Documentation/admin-guide/pm/intel_pstate.rst +++ b/Documentation/admin-guide/pm/intel_pstate.rst | |||
| @@ -145,7 +145,7 @@ feature enabled.] | |||
| 145 | 145 | ||
| 146 | In this mode ``intel_pstate`` registers utilization update callbacks with the | 146 | In this mode ``intel_pstate`` registers utilization update callbacks with the |
| 147 | CPU scheduler in order to run a P-state selection algorithm, either | 147 | CPU scheduler in order to run a P-state selection algorithm, either |
| 148 | ``powersave`` or ``performance``, depending on the ``scaling_cur_freq`` policy | 148 | ``powersave`` or ``performance``, depending on the ``scaling_governor`` policy |
| 149 | setting in ``sysfs``. The current CPU frequency information to be made | 149 | setting in ``sysfs``. The current CPU frequency information to be made |
| 150 | available from the ``scaling_cur_freq`` policy attribute in ``sysfs`` is | 150 | available from the ``scaling_cur_freq`` policy attribute in ``sysfs`` is |
| 151 | periodically updated by those utilization update callbacks too. | 151 | periodically updated by those utilization update callbacks too. |
diff --git a/Documentation/admin-guide/pm/sleep-states.rst b/Documentation/admin-guide/pm/sleep-states.rst index 1e5c0f00cb2f..dbf5acd49f35 100644 --- a/Documentation/admin-guide/pm/sleep-states.rst +++ b/Documentation/admin-guide/pm/sleep-states.rst | |||
| @@ -15,7 +15,7 @@ Sleep States That Can Be Supported | |||
| 15 | ================================== | 15 | ================================== |
| 16 | 16 | ||
| 17 | Depending on its configuration and the capabilities of the platform it runs on, | 17 | Depending on its configuration and the capabilities of the platform it runs on, |
| 18 | the Linux kernel can support up to four system sleep states, includig | 18 | the Linux kernel can support up to four system sleep states, including |
| 19 | hibernation and up to three variants of system suspend. The sleep states that | 19 | hibernation and up to three variants of system suspend. The sleep states that |
| 20 | can be supported by the kernel are listed below. | 20 | can be supported by the kernel are listed below. |
| 21 | 21 | ||
diff --git a/Documentation/bpf/bpf_devel_QA.txt b/Documentation/bpf/bpf_devel_QA.txt index 1a0b704e1a38..da57601153a0 100644 --- a/Documentation/bpf/bpf_devel_QA.txt +++ b/Documentation/bpf/bpf_devel_QA.txt | |||
| @@ -557,6 +557,14 @@ A: Although LLVM IR generation and optimization try to stay architecture | |||
| 557 | pulls in some header files containing file scope host assembly codes. | 557 | pulls in some header files containing file scope host assembly codes. |
| 558 | - You can add "-fno-jump-tables" to work around the switch table issue. | 558 | - You can add "-fno-jump-tables" to work around the switch table issue. |
| 559 | 559 | ||
| 560 | Otherwise, you can use bpf target. | 560 | Otherwise, you can use bpf target. Additionally, you _must_ use bpf target |
| 561 | when: | ||
| 562 | |||
| 563 | - Your program uses data structures with pointer or long / unsigned long | ||
| 564 | types that interface with BPF helpers or context data structures. Access | ||
| 565 | into these structures is verified by the BPF verifier and may result | ||
| 566 | in verification failures if the native architecture is not aligned with | ||
| 567 | the BPF architecture, e.g. 64-bit. An example of this is | ||
| 568 | BPF_PROG_TYPE_SK_MSG require '-target bpf' | ||
| 561 | 569 | ||
| 562 | Happy BPF hacking! | 570 | Happy BPF hacking! |
diff --git a/Documentation/device-mapper/thin-provisioning.txt b/Documentation/device-mapper/thin-provisioning.txt index 4bcd4b7f79f9..3d01948ea061 100644 --- a/Documentation/device-mapper/thin-provisioning.txt +++ b/Documentation/device-mapper/thin-provisioning.txt | |||
| @@ -264,7 +264,10 @@ i) Constructor | |||
| 264 | data device, but just remove the mapping. | 264 | data device, but just remove the mapping. |
| 265 | 265 | ||
| 266 | read_only: Don't allow any changes to be made to the pool | 266 | read_only: Don't allow any changes to be made to the pool |
| 267 | metadata. | 267 | metadata. This mode is only available after the |
| 268 | thin-pool has been created and first used in full | ||
| 269 | read/write mode. It cannot be specified on initial | ||
| 270 | thin-pool creation. | ||
| 268 | 271 | ||
| 269 | error_if_no_space: Error IOs, instead of queueing, if no space. | 272 | error_if_no_space: Error IOs, instead of queueing, if no space. |
| 270 | 273 | ||
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index f4006d3c9fdf..c760ecb81381 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt | |||
| @@ -30,7 +30,6 @@ compatible: | |||
| 30 | Optional properties: | 30 | Optional properties: |
| 31 | - dma-coherent : Present if dma operations are coherent | 31 | - dma-coherent : Present if dma operations are coherent |
| 32 | - clocks : a list of phandle + clock specifier pairs | 32 | - clocks : a list of phandle + clock specifier pairs |
| 33 | - resets : a list of phandle + reset specifier pairs | ||
| 34 | - target-supply : regulator for SATA target power | 33 | - target-supply : regulator for SATA target power |
| 35 | - phys : reference to the SATA PHY node | 34 | - phys : reference to the SATA PHY node |
| 36 | - phy-names : must be "sata-phy" | 35 | - phy-names : must be "sata-phy" |
diff --git a/Documentation/devicetree/bindings/display/panel/panel-common.txt b/Documentation/devicetree/bindings/display/panel/panel-common.txt index 557fa765adcb..5d2519af4bb5 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-common.txt +++ b/Documentation/devicetree/bindings/display/panel/panel-common.txt | |||
| @@ -38,7 +38,7 @@ Display Timings | |||
| 38 | require specific display timings. The panel-timing subnode expresses those | 38 | require specific display timings. The panel-timing subnode expresses those |
| 39 | timings as specified in the timing subnode section of the display timing | 39 | timings as specified in the timing subnode section of the display timing |
| 40 | bindings defined in | 40 | bindings defined in |
| 41 | Documentation/devicetree/bindings/display/display-timing.txt. | 41 | Documentation/devicetree/bindings/display/panel/display-timing.txt. |
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | Connectivity | 44 | Connectivity |
diff --git a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt index aadfb236d53a..61315eaa7660 100644 --- a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt +++ b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt | |||
| @@ -26,6 +26,7 @@ Required Properties: | |||
| 26 | - "renesas,dmac-r8a7794" (R-Car E2) | 26 | - "renesas,dmac-r8a7794" (R-Car E2) |
| 27 | - "renesas,dmac-r8a7795" (R-Car H3) | 27 | - "renesas,dmac-r8a7795" (R-Car H3) |
| 28 | - "renesas,dmac-r8a7796" (R-Car M3-W) | 28 | - "renesas,dmac-r8a7796" (R-Car M3-W) |
| 29 | - "renesas,dmac-r8a77965" (R-Car M3-N) | ||
| 29 | - "renesas,dmac-r8a77970" (R-Car V3M) | 30 | - "renesas,dmac-r8a77970" (R-Car V3M) |
| 30 | - "renesas,dmac-r8a77980" (R-Car V3H) | 31 | - "renesas,dmac-r8a77980" (R-Car V3H) |
| 31 | 32 | ||
diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt index 23e3abc3fdef..c88919480d37 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt | |||
| @@ -4,6 +4,13 @@ Required properties: | |||
| 4 | - compatible: | 4 | - compatible: |
| 5 | atmel,maxtouch | 5 | atmel,maxtouch |
| 6 | 6 | ||
| 7 | The following compatibles have been used in various products but are | ||
| 8 | deprecated: | ||
| 9 | atmel,qt602240_ts | ||
| 10 | atmel,atmel_mxt_ts | ||
| 11 | atmel,atmel_mxt_tp | ||
| 12 | atmel,mXT224 | ||
| 13 | |||
| 7 | - reg: The I2C address of the device | 14 | - reg: The I2C address of the device |
| 8 | 15 | ||
| 9 | - interrupts: The sink for the touchpad's IRQ output | 16 | - interrupts: The sink for the touchpad's IRQ output |
diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt index 93c3a6ae32f9..ac71daa46195 100644 --- a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt +++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt | |||
| @@ -5,7 +5,9 @@ Required properties: | |||
| 5 | - compatible: Must contain one or more of the following: | 5 | - compatible: Must contain one or more of the following: |
| 6 | - "renesas,rcar-gen3-canfd" for R-Car Gen3 compatible controller. | 6 | - "renesas,rcar-gen3-canfd" for R-Car Gen3 compatible controller. |
| 7 | - "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller. | 7 | - "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller. |
| 8 | - "renesas,r8a7796-canfd" for R8A7796 (R-Car M3) compatible controller. | 8 | - "renesas,r8a7796-canfd" for R8A7796 (R-Car M3-W) compatible controller. |
| 9 | - "renesas,r8a77970-canfd" for R8A77970 (R-Car V3M) compatible controller. | ||
| 10 | - "renesas,r8a77980-canfd" for R8A77980 (R-Car V3H) compatible controller. | ||
| 9 | 11 | ||
| 10 | When compatible with the generic version, nodes must list the | 12 | When compatible with the generic version, nodes must list the |
| 11 | SoC-specific version corresponding to the platform first, followed by the | 13 | SoC-specific version corresponding to the platform first, followed by the |
diff --git a/Documentation/devicetree/bindings/net/marvell-pp2.txt b/Documentation/devicetree/bindings/net/marvell-pp2.txt index 1814fa13f6ab..fc019df0d863 100644 --- a/Documentation/devicetree/bindings/net/marvell-pp2.txt +++ b/Documentation/devicetree/bindings/net/marvell-pp2.txt | |||
| @@ -21,9 +21,10 @@ Required properties: | |||
| 21 | - main controller clock (for both armada-375-pp2 and armada-7k-pp2) | 21 | - main controller clock (for both armada-375-pp2 and armada-7k-pp2) |
| 22 | - GOP clock (for both armada-375-pp2 and armada-7k-pp2) | 22 | - GOP clock (for both armada-375-pp2 and armada-7k-pp2) |
| 23 | - MG clock (only for armada-7k-pp2) | 23 | - MG clock (only for armada-7k-pp2) |
| 24 | - MG Core clock (only for armada-7k-pp2) | ||
| 24 | - AXI clock (only for armada-7k-pp2) | 25 | - AXI clock (only for armada-7k-pp2) |
| 25 | - clock-names: names of used clocks, must be "pp_clk", "gop_clk", "mg_clk" | 26 | - clock-names: names of used clocks, must be "pp_clk", "gop_clk", "mg_clk", |
| 26 | and "axi_clk" (the 2 latter only for armada-7k-pp2). | 27 | "mg_core_clk" and "axi_clk" (the 3 latter only for armada-7k-pp2). |
| 27 | 28 | ||
| 28 | The ethernet ports are represented by subnodes. At least one port is | 29 | The ethernet ports are represented by subnodes. At least one port is |
| 29 | required. | 30 | required. |
| @@ -80,8 +81,8 @@ cpm_ethernet: ethernet@0 { | |||
| 80 | compatible = "marvell,armada-7k-pp22"; | 81 | compatible = "marvell,armada-7k-pp22"; |
| 81 | reg = <0x0 0x100000>, <0x129000 0xb000>; | 82 | reg = <0x0 0x100000>, <0x129000 0xb000>; |
| 82 | clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, | 83 | clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, |
| 83 | <&cpm_syscon0 1 5>, <&cpm_syscon0 1 18>; | 84 | <&cpm_syscon0 1 5>, <&cpm_syscon0 1 6>, <&cpm_syscon0 1 18>; |
| 84 | clock-names = "pp_clk", "gop_clk", "gp_clk", "axi_clk"; | 85 | clock-names = "pp_clk", "gop_clk", "mg_clk", "mg_core_clk", "axi_clk"; |
| 85 | 86 | ||
| 86 | eth0: eth0 { | 87 | eth0: eth0 { |
| 87 | interrupts = <ICU_GRP_NSR 39 IRQ_TYPE_LEVEL_HIGH>, | 88 | interrupts = <ICU_GRP_NSR 39 IRQ_TYPE_LEVEL_HIGH>, |
diff --git a/Documentation/devicetree/bindings/net/renesas,ravb.txt b/Documentation/devicetree/bindings/net/renesas,ravb.txt index c306f55d335b..890526dbfc26 100644 --- a/Documentation/devicetree/bindings/net/renesas,ravb.txt +++ b/Documentation/devicetree/bindings/net/renesas,ravb.txt | |||
| @@ -18,6 +18,7 @@ Required properties: | |||
| 18 | 18 | ||
| 19 | - "renesas,etheravb-r8a7795" for the R8A7795 SoC. | 19 | - "renesas,etheravb-r8a7795" for the R8A7795 SoC. |
| 20 | - "renesas,etheravb-r8a7796" for the R8A7796 SoC. | 20 | - "renesas,etheravb-r8a7796" for the R8A7796 SoC. |
| 21 | - "renesas,etheravb-r8a77965" for the R8A77965 SoC. | ||
| 21 | - "renesas,etheravb-r8a77970" for the R8A77970 SoC. | 22 | - "renesas,etheravb-r8a77970" for the R8A77970 SoC. |
| 22 | - "renesas,etheravb-r8a77980" for the R8A77980 SoC. | 23 | - "renesas,etheravb-r8a77980" for the R8A77980 SoC. |
| 23 | - "renesas,etheravb-r8a77995" for the R8A77995 SoC. | 24 | - "renesas,etheravb-r8a77995" for the R8A77995 SoC. |
diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt index ed5eb547afc8..64bc5c2a76da 100644 --- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt | |||
| @@ -56,9 +56,9 @@ pins it needs, and how they should be configured, with regard to muxer | |||
| 56 | configuration, drive strength and pullups. If one of these options is | 56 | configuration, drive strength and pullups. If one of these options is |
| 57 | not set, its actual value will be unspecified. | 57 | not set, its actual value will be unspecified. |
| 58 | 58 | ||
| 59 | This driver supports the generic pin multiplexing and configuration | 59 | Allwinner A1X Pin Controller supports the generic pin multiplexing and |
| 60 | bindings. For details on each properties, you can refer to | 60 | configuration bindings. For details on each properties, you can refer to |
| 61 | ./pinctrl-bindings.txt. | 61 | ./pinctrl-bindings.txt. |
| 62 | 62 | ||
| 63 | Required sub-node properties: | 63 | Required sub-node properties: |
| 64 | - pins | 64 | - pins |
diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index a006ea4d065f..106808b55b6d 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | |||
| @@ -43,6 +43,8 @@ Required properties: | |||
| 43 | - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. | 43 | - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. |
| 44 | - "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART. | 44 | - "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART. |
| 45 | - "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART. | 45 | - "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART. |
| 46 | - "renesas,scif-r8a77965" for R8A77965 (R-Car M3-N) SCIF compatible UART. | ||
| 47 | - "renesas,hscif-r8a77965" for R8A77965 (R-Car M3-N) HSCIF compatible UART. | ||
| 46 | - "renesas,scif-r8a77970" for R8A77970 (R-Car V3M) SCIF compatible UART. | 48 | - "renesas,scif-r8a77970" for R8A77970 (R-Car V3M) SCIF compatible UART. |
| 47 | - "renesas,hscif-r8a77970" for R8A77970 (R-Car V3M) HSCIF compatible UART. | 49 | - "renesas,hscif-r8a77970" for R8A77970 (R-Car V3M) HSCIF compatible UART. |
| 48 | - "renesas,scif-r8a77980" for R8A77980 (R-Car V3H) SCIF compatible UART. | 50 | - "renesas,scif-r8a77980" for R8A77980 (R-Car V3H) SCIF compatible UART. |
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index b5f978a4cac6..a38d8bfae19c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
| @@ -182,6 +182,7 @@ karo Ka-Ro electronics GmbH | |||
| 182 | keithkoep Keith & Koep GmbH | 182 | keithkoep Keith & Koep GmbH |
| 183 | keymile Keymile GmbH | 183 | keymile Keymile GmbH |
| 184 | khadas Khadas | 184 | khadas Khadas |
| 185 | kiebackpeter Kieback & Peter GmbH | ||
| 185 | kinetic Kinetic Technologies | 186 | kinetic Kinetic Technologies |
| 186 | kingnovel Kingnovel Technology Co., Ltd. | 187 | kingnovel Kingnovel Technology Co., Ltd. |
| 187 | kosagi Sutajio Ko-Usagi PTE Ltd. | 188 | kosagi Sutajio Ko-Usagi PTE Ltd. |
diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt index a4feb6dde8cd..725fb8d255c1 100644 --- a/Documentation/devicetree/overlay-notes.txt +++ b/Documentation/devicetree/overlay-notes.txt | |||
| @@ -98,6 +98,14 @@ Finally, if you need to remove all overlays in one-go, just call | |||
| 98 | of_overlay_remove_all() which will remove every single one in the correct | 98 | of_overlay_remove_all() which will remove every single one in the correct |
| 99 | order. | 99 | order. |
| 100 | 100 | ||
| 101 | In addition, there is the option to register notifiers that get called on | ||
| 102 | overlay operations. See of_overlay_notifier_register/unregister and | ||
| 103 | enum of_overlay_notify_action for details. | ||
| 104 | |||
| 105 | Note that a notifier callback is not supposed to store pointers to a device | ||
| 106 | tree node or its content beyond OF_OVERLAY_POST_REMOVE corresponding to the | ||
| 107 | respective node it received. | ||
| 108 | |||
| 101 | Overlay DTS Format | 109 | Overlay DTS Format |
| 102 | ------------------ | 110 | ------------------ |
| 103 | 111 | ||
diff --git a/Documentation/doc-guide/parse-headers.rst b/Documentation/doc-guide/parse-headers.rst index 96a0423d5dba..82a3e43b6864 100644 --- a/Documentation/doc-guide/parse-headers.rst +++ b/Documentation/doc-guide/parse-headers.rst | |||
| @@ -177,14 +177,14 @@ BUGS | |||
| 177 | **** | 177 | **** |
| 178 | 178 | ||
| 179 | 179 | ||
| 180 | Report bugs to Mauro Carvalho Chehab <mchehab@s-opensource.com> | 180 | Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org> |
| 181 | 181 | ||
| 182 | 182 | ||
| 183 | COPYRIGHT | 183 | COPYRIGHT |
| 184 | ********* | 184 | ********* |
| 185 | 185 | ||
| 186 | 186 | ||
| 187 | Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@s-opensource.com>. | 187 | Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. |
| 188 | 188 | ||
| 189 | License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. | 189 | License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. |
| 190 | 190 | ||
diff --git a/Documentation/media/uapi/rc/keytable.c.rst b/Documentation/media/uapi/rc/keytable.c.rst index e6ce1e3f5a78..217237f93b37 100644 --- a/Documentation/media/uapi/rc/keytable.c.rst +++ b/Documentation/media/uapi/rc/keytable.c.rst | |||
| @@ -7,7 +7,7 @@ file: uapi/v4l/keytable.c | |||
| 7 | 7 | ||
| 8 | /* keytable.c - This program allows checking/replacing keys at IR | 8 | /* keytable.c - This program allows checking/replacing keys at IR |
| 9 | 9 | ||
| 10 | Copyright (C) 2006-2009 Mauro Carvalho Chehab <mchehab@infradead.org> | 10 | Copyright (C) 2006-2009 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 11 | 11 | ||
| 12 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
| 13 | it under the terms of the GNU General Public License as published by | 13 | it under the terms of the GNU General Public License as published by |
diff --git a/Documentation/media/uapi/v4l/v4l2grab.c.rst b/Documentation/media/uapi/v4l/v4l2grab.c.rst index 5aabd0b7b089..f0d0ab6abd41 100644 --- a/Documentation/media/uapi/v4l/v4l2grab.c.rst +++ b/Documentation/media/uapi/v4l/v4l2grab.c.rst | |||
| @@ -6,7 +6,7 @@ file: media/v4l/v4l2grab.c | |||
| 6 | .. code-block:: c | 6 | .. code-block:: c |
| 7 | 7 | ||
| 8 | /* V4L2 video picture grabber | 8 | /* V4L2 video picture grabber |
| 9 | Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> | 9 | Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 10 | 10 | ||
| 11 | This program is free software; you can redistribute it and/or modify | 11 | This program is free software; you can redistribute it and/or modify |
| 12 | it under the terms of the GNU General Public License as published by | 12 | it under the terms of the GNU General Public License as published by |
diff --git a/Documentation/sphinx/parse-headers.pl b/Documentation/sphinx/parse-headers.pl index a958d8b5e99d..d410f47567e9 100755 --- a/Documentation/sphinx/parse-headers.pl +++ b/Documentation/sphinx/parse-headers.pl | |||
| @@ -387,11 +387,11 @@ tree for more details. | |||
| 387 | 387 | ||
| 388 | =head1 BUGS | 388 | =head1 BUGS |
| 389 | 389 | ||
| 390 | Report bugs to Mauro Carvalho Chehab <mchehab@s-opensource.com> | 390 | Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org> |
| 391 | 391 | ||
| 392 | =head1 COPYRIGHT | 392 | =head1 COPYRIGHT |
| 393 | 393 | ||
| 394 | Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@s-opensource.com>. | 394 | Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. |
| 395 | 395 | ||
| 396 | License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. | 396 | License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. |
| 397 | 397 | ||
diff --git a/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt b/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt index 698660b7f21f..c77c0f060864 100644 --- a/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt +++ b/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt | |||
| @@ -6,7 +6,7 @@ communicating in English you can also ask the Chinese maintainer for | |||
| 6 | help. Contact the Chinese maintainer if this translation is outdated | 6 | help. Contact the Chinese maintainer if this translation is outdated |
| 7 | or if there is a problem with the translation. | 7 | or if there is a problem with the translation. |
| 8 | 8 | ||
| 9 | Maintainer: Mauro Carvalho Chehab <mchehab@infradead.org> | 9 | Maintainer: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 10 | Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> | 10 | Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> |
| 11 | --------------------------------------------------------------------- | 11 | --------------------------------------------------------------------- |
| 12 | Documentation/video4linux/v4l2-framework.txt 的中文翻译 | 12 | Documentation/video4linux/v4l2-framework.txt 的中文翻译 |
| @@ -14,7 +14,7 @@ Documentation/video4linux/v4l2-framework.txt 的中文翻译 | |||
| 14 | 如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | 14 | 如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 |
| 15 | 交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | 15 | 交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 |
| 16 | 译存在问题,请联系中文版维护者。 | 16 | 译存在问题,请联系中文版维护者。 |
| 17 | 英文版维护者: Mauro Carvalho Chehab <mchehab@infradead.org> | 17 | 英文版维护者: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 18 | 中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | 18 | 中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com> |
| 19 | 中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | 19 | 中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> |
| 20 | 中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | 20 | 中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> |
diff --git a/Documentation/virtual/kvm/cpuid.txt b/Documentation/virtual/kvm/cpuid.txt index d4f33eb805dd..ab022dcd0911 100644 --- a/Documentation/virtual/kvm/cpuid.txt +++ b/Documentation/virtual/kvm/cpuid.txt | |||
| @@ -72,8 +72,8 @@ KVM_FEATURE_CLOCKSOURCE_STABLE_BIT || 24 || host will warn if no guest-side | |||
| 72 | 72 | ||
| 73 | flag || value || meaning | 73 | flag || value || meaning |
| 74 | ================================================================================== | 74 | ================================================================================== |
| 75 | KVM_HINTS_DEDICATED || 0 || guest checks this feature bit to | 75 | KVM_HINTS_REALTIME || 0 || guest checks this feature bit to |
| 76 | || || determine if there is vCPU pinning | 76 | || || determine that vCPUs are never |
| 77 | || || and there is no vCPU over-commitment, | 77 | || || preempted for an unlimited time, |
| 78 | || || allowing optimizations | 78 | || || allowing optimizations |
| 79 | ---------------------------------------------------------------------------------- | 79 | ---------------------------------------------------------------------------------- |
diff --git a/MAINTAINERS b/MAINTAINERS index 79bb02ff812f..078fd80f664f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -137,9 +137,9 @@ Maintainers List (try to look for most precise areas first) | |||
| 137 | ----------------------------------- | 137 | ----------------------------------- |
| 138 | 138 | ||
| 139 | 3C59X NETWORK DRIVER | 139 | 3C59X NETWORK DRIVER |
| 140 | M: Steffen Klassert <klassert@mathematik.tu-chemnitz.de> | 140 | M: Steffen Klassert <klassert@kernel.org> |
| 141 | L: netdev@vger.kernel.org | 141 | L: netdev@vger.kernel.org |
| 142 | S: Maintained | 142 | S: Odd Fixes |
| 143 | F: Documentation/networking/vortex.txt | 143 | F: Documentation/networking/vortex.txt |
| 144 | F: drivers/net/ethernet/3com/3c59x.c | 144 | F: drivers/net/ethernet/3com/3c59x.c |
| 145 | 145 | ||
| @@ -2554,7 +2554,6 @@ F: Documentation/devicetree/bindings/sound/axentia,* | |||
| 2554 | F: sound/soc/atmel/tse850-pcm5142.c | 2554 | F: sound/soc/atmel/tse850-pcm5142.c |
| 2555 | 2555 | ||
| 2556 | AZ6007 DVB DRIVER | 2556 | AZ6007 DVB DRIVER |
| 2557 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 2558 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 2557 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 2559 | L: linux-media@vger.kernel.org | 2558 | L: linux-media@vger.kernel.org |
| 2560 | W: https://linuxtv.org | 2559 | W: https://linuxtv.org |
| @@ -3083,7 +3082,6 @@ F: include/linux/btrfs* | |||
| 3083 | F: include/uapi/linux/btrfs* | 3082 | F: include/uapi/linux/btrfs* |
| 3084 | 3083 | ||
| 3085 | BTTV VIDEO4LINUX DRIVER | 3084 | BTTV VIDEO4LINUX DRIVER |
| 3086 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 3087 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 3085 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 3088 | L: linux-media@vger.kernel.org | 3086 | L: linux-media@vger.kernel.org |
| 3089 | W: https://linuxtv.org | 3087 | W: https://linuxtv.org |
| @@ -3693,7 +3691,6 @@ F: drivers/cpufreq/arm_big_little_dt.c | |||
| 3693 | 3691 | ||
| 3694 | CPU POWER MONITORING SUBSYSTEM | 3692 | CPU POWER MONITORING SUBSYSTEM |
| 3695 | M: Thomas Renninger <trenn@suse.com> | 3693 | M: Thomas Renninger <trenn@suse.com> |
| 3696 | M: Shuah Khan <shuahkh@osg.samsung.com> | ||
| 3697 | M: Shuah Khan <shuah@kernel.org> | 3694 | M: Shuah Khan <shuah@kernel.org> |
| 3698 | L: linux-pm@vger.kernel.org | 3695 | L: linux-pm@vger.kernel.org |
| 3699 | S: Maintained | 3696 | S: Maintained |
| @@ -3812,7 +3809,6 @@ S: Maintained | |||
| 3812 | F: drivers/media/dvb-frontends/cx24120* | 3809 | F: drivers/media/dvb-frontends/cx24120* |
| 3813 | 3810 | ||
| 3814 | CX88 VIDEO4LINUX DRIVER | 3811 | CX88 VIDEO4LINUX DRIVER |
| 3815 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 3816 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 3812 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 3817 | L: linux-media@vger.kernel.org | 3813 | L: linux-media@vger.kernel.org |
| 3818 | W: https://linuxtv.org | 3814 | W: https://linuxtv.org |
| @@ -4313,7 +4309,7 @@ F: Documentation/driver-api/dma-buf.rst | |||
| 4313 | T: git git://anongit.freedesktop.org/drm/drm-misc | 4309 | T: git git://anongit.freedesktop.org/drm/drm-misc |
| 4314 | 4310 | ||
| 4315 | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM | 4311 | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM |
| 4316 | M: Vinod Koul <vinod.koul@intel.com> | 4312 | M: Vinod Koul <vkoul@kernel.org> |
| 4317 | L: dmaengine@vger.kernel.org | 4313 | L: dmaengine@vger.kernel.org |
| 4318 | Q: https://patchwork.kernel.org/project/linux-dmaengine/list/ | 4314 | Q: https://patchwork.kernel.org/project/linux-dmaengine/list/ |
| 4319 | S: Maintained | 4315 | S: Maintained |
| @@ -5053,7 +5049,6 @@ F: drivers/edac/thunderx_edac* | |||
| 5053 | 5049 | ||
| 5054 | EDAC-CORE | 5050 | EDAC-CORE |
| 5055 | M: Borislav Petkov <bp@alien8.de> | 5051 | M: Borislav Petkov <bp@alien8.de> |
| 5056 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 5057 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 5052 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5058 | L: linux-edac@vger.kernel.org | 5053 | L: linux-edac@vger.kernel.org |
| 5059 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next | 5054 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next |
| @@ -5082,7 +5077,6 @@ S: Maintained | |||
| 5082 | F: drivers/edac/fsl_ddr_edac.* | 5077 | F: drivers/edac/fsl_ddr_edac.* |
| 5083 | 5078 | ||
| 5084 | EDAC-GHES | 5079 | EDAC-GHES |
| 5085 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 5086 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 5080 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5087 | L: linux-edac@vger.kernel.org | 5081 | L: linux-edac@vger.kernel.org |
| 5088 | S: Maintained | 5082 | S: Maintained |
| @@ -5099,21 +5093,18 @@ S: Maintained | |||
| 5099 | F: drivers/edac/i5000_edac.c | 5093 | F: drivers/edac/i5000_edac.c |
| 5100 | 5094 | ||
| 5101 | EDAC-I5400 | 5095 | EDAC-I5400 |
| 5102 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 5103 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 5096 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5104 | L: linux-edac@vger.kernel.org | 5097 | L: linux-edac@vger.kernel.org |
| 5105 | S: Maintained | 5098 | S: Maintained |
| 5106 | F: drivers/edac/i5400_edac.c | 5099 | F: drivers/edac/i5400_edac.c |
| 5107 | 5100 | ||
| 5108 | EDAC-I7300 | 5101 | EDAC-I7300 |
| 5109 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 5110 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 5102 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5111 | L: linux-edac@vger.kernel.org | 5103 | L: linux-edac@vger.kernel.org |
| 5112 | S: Maintained | 5104 | S: Maintained |
| 5113 | F: drivers/edac/i7300_edac.c | 5105 | F: drivers/edac/i7300_edac.c |
| 5114 | 5106 | ||
| 5115 | EDAC-I7CORE | 5107 | EDAC-I7CORE |
| 5116 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 5117 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 5108 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5118 | L: linux-edac@vger.kernel.org | 5109 | L: linux-edac@vger.kernel.org |
| 5119 | S: Maintained | 5110 | S: Maintained |
| @@ -5163,7 +5154,6 @@ S: Maintained | |||
| 5163 | F: drivers/edac/r82600_edac.c | 5154 | F: drivers/edac/r82600_edac.c |
| 5164 | 5155 | ||
| 5165 | EDAC-SBRIDGE | 5156 | EDAC-SBRIDGE |
| 5166 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 5167 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 5157 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5168 | L: linux-edac@vger.kernel.org | 5158 | L: linux-edac@vger.kernel.org |
| 5169 | S: Maintained | 5159 | S: Maintained |
| @@ -5222,7 +5212,6 @@ S: Maintained | |||
| 5222 | F: drivers/net/ethernet/ibm/ehea/ | 5212 | F: drivers/net/ethernet/ibm/ehea/ |
| 5223 | 5213 | ||
| 5224 | EM28XX VIDEO4LINUX DRIVER | 5214 | EM28XX VIDEO4LINUX DRIVER |
| 5225 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 5226 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 5215 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5227 | L: linux-media@vger.kernel.org | 5216 | L: linux-media@vger.kernel.org |
| 5228 | W: https://linuxtv.org | 5217 | W: https://linuxtv.org |
| @@ -7677,9 +7666,11 @@ L: linux-kbuild@vger.kernel.org | |||
| 7677 | S: Maintained | 7666 | S: Maintained |
| 7678 | F: Documentation/kbuild/ | 7667 | F: Documentation/kbuild/ |
| 7679 | F: Makefile | 7668 | F: Makefile |
| 7680 | F: scripts/Makefile.* | 7669 | F: scripts/Kbuild* |
| 7670 | F: scripts/Makefile* | ||
| 7681 | F: scripts/basic/ | 7671 | F: scripts/basic/ |
| 7682 | F: scripts/mk* | 7672 | F: scripts/mk* |
| 7673 | F: scripts/mod/ | ||
| 7683 | F: scripts/package/ | 7674 | F: scripts/package/ |
| 7684 | 7675 | ||
| 7685 | KERNEL JANITORS | 7676 | KERNEL JANITORS |
| @@ -7704,10 +7695,10 @@ F: include/linux/sunrpc/ | |||
| 7704 | F: include/uapi/linux/sunrpc/ | 7695 | F: include/uapi/linux/sunrpc/ |
| 7705 | 7696 | ||
| 7706 | KERNEL SELFTEST FRAMEWORK | 7697 | KERNEL SELFTEST FRAMEWORK |
| 7707 | M: Shuah Khan <shuahkh@osg.samsung.com> | ||
| 7708 | M: Shuah Khan <shuah@kernel.org> | 7698 | M: Shuah Khan <shuah@kernel.org> |
| 7709 | L: linux-kselftest@vger.kernel.org | 7699 | L: linux-kselftest@vger.kernel.org |
| 7710 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git | 7700 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git |
| 7701 | Q: https://patchwork.kernel.org/project/linux-kselftest/list/ | ||
| 7711 | S: Maintained | 7702 | S: Maintained |
| 7712 | F: tools/testing/selftests/ | 7703 | F: tools/testing/selftests/ |
| 7713 | F: Documentation/dev-tools/kselftest* | 7704 | F: Documentation/dev-tools/kselftest* |
| @@ -8871,7 +8862,6 @@ F: Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt | |||
| 8871 | F: drivers/staging/media/tegra-vde/ | 8862 | F: drivers/staging/media/tegra-vde/ |
| 8872 | 8863 | ||
| 8873 | MEDIA INPUT INFRASTRUCTURE (V4L/DVB) | 8864 | MEDIA INPUT INFRASTRUCTURE (V4L/DVB) |
| 8874 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 8875 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 8865 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8876 | P: LinuxTV.org Project | 8866 | P: LinuxTV.org Project |
| 8877 | L: linux-media@vger.kernel.org | 8867 | L: linux-media@vger.kernel.org |
| @@ -9725,6 +9715,7 @@ W: https://fedorahosted.org/dropwatch/ | |||
| 9725 | F: net/core/drop_monitor.c | 9715 | F: net/core/drop_monitor.c |
| 9726 | 9716 | ||
| 9727 | NETWORKING DRIVERS | 9717 | NETWORKING DRIVERS |
| 9718 | M: "David S. Miller" <davem@davemloft.net> | ||
| 9728 | L: netdev@vger.kernel.org | 9719 | L: netdev@vger.kernel.org |
| 9729 | W: http://www.linuxfoundation.org/en/Net | 9720 | W: http://www.linuxfoundation.org/en/Net |
| 9730 | Q: http://patchwork.ozlabs.org/project/netdev/list/ | 9721 | Q: http://patchwork.ozlabs.org/project/netdev/list/ |
| @@ -9881,7 +9872,7 @@ F: include/linux/platform_data/nxp-nci.h | |||
| 9881 | F: Documentation/devicetree/bindings/net/nfc/ | 9872 | F: Documentation/devicetree/bindings/net/nfc/ |
| 9882 | 9873 | ||
| 9883 | NFS, SUNRPC, AND LOCKD CLIENTS | 9874 | NFS, SUNRPC, AND LOCKD CLIENTS |
| 9884 | M: Trond Myklebust <trond.myklebust@primarydata.com> | 9875 | M: Trond Myklebust <trond.myklebust@hammerspace.com> |
| 9885 | M: Anna Schumaker <anna.schumaker@netapp.com> | 9876 | M: Anna Schumaker <anna.schumaker@netapp.com> |
| 9886 | L: linux-nfs@vger.kernel.org | 9877 | L: linux-nfs@vger.kernel.org |
| 9887 | W: http://client.linux-nfs.org | 9878 | W: http://client.linux-nfs.org |
| @@ -12230,7 +12221,7 @@ F: Documentation/s390/vfio-ccw.txt | |||
| 12230 | F: include/uapi/linux/vfio_ccw.h | 12221 | F: include/uapi/linux/vfio_ccw.h |
| 12231 | 12222 | ||
| 12232 | S390 ZCRYPT DRIVER | 12223 | S390 ZCRYPT DRIVER |
| 12233 | M: Harald Freudenberger <freude@de.ibm.com> | 12224 | M: Harald Freudenberger <freude@linux.ibm.com> |
| 12234 | L: linux-s390@vger.kernel.org | 12225 | L: linux-s390@vger.kernel.org |
| 12235 | W: http://www.ibm.com/developerworks/linux/linux390/ | 12226 | W: http://www.ibm.com/developerworks/linux/linux390/ |
| 12236 | S: Supported | 12227 | S: Supported |
| @@ -12259,7 +12250,6 @@ S: Odd Fixes | |||
| 12259 | F: drivers/media/i2c/saa6588* | 12250 | F: drivers/media/i2c/saa6588* |
| 12260 | 12251 | ||
| 12261 | SAA7134 VIDEO4LINUX DRIVER | 12252 | SAA7134 VIDEO4LINUX DRIVER |
| 12262 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 12263 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 12253 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 12264 | L: linux-media@vger.kernel.org | 12254 | L: linux-media@vger.kernel.org |
| 12265 | W: https://linuxtv.org | 12255 | W: https://linuxtv.org |
| @@ -12498,6 +12488,7 @@ F: drivers/scsi/st_*.h | |||
| 12498 | SCTP PROTOCOL | 12488 | SCTP PROTOCOL |
| 12499 | M: Vlad Yasevich <vyasevich@gmail.com> | 12489 | M: Vlad Yasevich <vyasevich@gmail.com> |
| 12500 | M: Neil Horman <nhorman@tuxdriver.com> | 12490 | M: Neil Horman <nhorman@tuxdriver.com> |
| 12491 | M: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> | ||
| 12501 | L: linux-sctp@vger.kernel.org | 12492 | L: linux-sctp@vger.kernel.org |
| 12502 | W: http://lksctp.sourceforge.net | 12493 | W: http://lksctp.sourceforge.net |
| 12503 | S: Maintained | 12494 | S: Maintained |
| @@ -12763,7 +12754,6 @@ S: Maintained | |||
| 12763 | F: drivers/media/radio/si4713/radio-usb-si4713.c | 12754 | F: drivers/media/radio/si4713/radio-usb-si4713.c |
| 12764 | 12755 | ||
| 12765 | SIANO DVB DRIVER | 12756 | SIANO DVB DRIVER |
| 12766 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 12767 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 12757 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 12768 | L: linux-media@vger.kernel.org | 12758 | L: linux-media@vger.kernel.org |
| 12769 | W: https://linuxtv.org | 12759 | W: https://linuxtv.org |
| @@ -13275,6 +13265,12 @@ M: Jan-Benedict Glaw <jbglaw@lug-owl.de> | |||
| 13275 | S: Maintained | 13265 | S: Maintained |
| 13276 | F: arch/alpha/kernel/srm_env.c | 13266 | F: arch/alpha/kernel/srm_env.c |
| 13277 | 13267 | ||
| 13268 | ST STM32 I2C/SMBUS DRIVER | ||
| 13269 | M: Pierre-Yves MORDRET <pierre-yves.mordret@st.com> | ||
| 13270 | L: linux-i2c@vger.kernel.org | ||
| 13271 | S: Maintained | ||
| 13272 | F: drivers/i2c/busses/i2c-stm32* | ||
| 13273 | |||
| 13278 | STABLE BRANCH | 13274 | STABLE BRANCH |
| 13279 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 13275 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 13280 | L: stable@vger.kernel.org | 13276 | L: stable@vger.kernel.org |
| @@ -13754,7 +13750,6 @@ S: Maintained | |||
| 13754 | F: drivers/media/i2c/tda9840* | 13750 | F: drivers/media/i2c/tda9840* |
| 13755 | 13751 | ||
| 13756 | TEA5761 TUNER DRIVER | 13752 | TEA5761 TUNER DRIVER |
| 13757 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 13758 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 13753 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 13759 | L: linux-media@vger.kernel.org | 13754 | L: linux-media@vger.kernel.org |
| 13760 | W: https://linuxtv.org | 13755 | W: https://linuxtv.org |
| @@ -13763,7 +13758,6 @@ S: Odd fixes | |||
| 13763 | F: drivers/media/tuners/tea5761.* | 13758 | F: drivers/media/tuners/tea5761.* |
| 13764 | 13759 | ||
| 13765 | TEA5767 TUNER DRIVER | 13760 | TEA5767 TUNER DRIVER |
| 13766 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 13767 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 13761 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 13768 | L: linux-media@vger.kernel.org | 13762 | L: linux-media@vger.kernel.org |
| 13769 | W: https://linuxtv.org | 13763 | W: https://linuxtv.org |
| @@ -13853,7 +13847,6 @@ S: Supported | |||
| 13853 | F: drivers/iommu/tegra* | 13847 | F: drivers/iommu/tegra* |
| 13854 | 13848 | ||
| 13855 | TEGRA KBC DRIVER | 13849 | TEGRA KBC DRIVER |
| 13856 | M: Rakesh Iyer <riyer@nvidia.com> | ||
| 13857 | M: Laxman Dewangan <ldewangan@nvidia.com> | 13850 | M: Laxman Dewangan <ldewangan@nvidia.com> |
| 13858 | S: Supported | 13851 | S: Supported |
| 13859 | F: drivers/input/keyboard/tegra-kbc.c | 13852 | F: drivers/input/keyboard/tegra-kbc.c |
| @@ -14180,7 +14173,6 @@ F: Documentation/networking/tlan.txt | |||
| 14180 | F: drivers/net/ethernet/ti/tlan.* | 14173 | F: drivers/net/ethernet/ti/tlan.* |
| 14181 | 14174 | ||
| 14182 | TM6000 VIDEO4LINUX DRIVER | 14175 | TM6000 VIDEO4LINUX DRIVER |
| 14183 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 14184 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 14176 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 14185 | L: linux-media@vger.kernel.org | 14177 | L: linux-media@vger.kernel.org |
| 14186 | W: https://linuxtv.org | 14178 | W: https://linuxtv.org |
| @@ -14663,7 +14655,6 @@ F: drivers/usb/common/usb-otg-fsm.c | |||
| 14663 | 14655 | ||
| 14664 | USB OVER IP DRIVER | 14656 | USB OVER IP DRIVER |
| 14665 | M: Valentina Manea <valentina.manea.m@gmail.com> | 14657 | M: Valentina Manea <valentina.manea.m@gmail.com> |
| 14666 | M: Shuah Khan <shuahkh@osg.samsung.com> | ||
| 14667 | M: Shuah Khan <shuah@kernel.org> | 14658 | M: Shuah Khan <shuah@kernel.org> |
| 14668 | L: linux-usb@vger.kernel.org | 14659 | L: linux-usb@vger.kernel.org |
| 14669 | S: Maintained | 14660 | S: Maintained |
| @@ -15407,7 +15398,6 @@ S: Maintained | |||
| 15407 | F: arch/x86/entry/vdso/ | 15398 | F: arch/x86/entry/vdso/ |
| 15408 | 15399 | ||
| 15409 | XC2028/3028 TUNER DRIVER | 15400 | XC2028/3028 TUNER DRIVER |
| 15410 | M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | ||
| 15411 | M: Mauro Carvalho Chehab <mchehab@kernel.org> | 15401 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 15412 | L: linux-media@vger.kernel.org | 15402 | L: linux-media@vger.kernel.org |
| 15413 | W: https://linuxtv.org | 15403 | W: https://linuxtv.org |
| @@ -2,8 +2,8 @@ | |||
| 2 | VERSION = 4 | 2 | VERSION = 4 |
| 3 | PATCHLEVEL = 17 | 3 | PATCHLEVEL = 17 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc3 | 5 | EXTRAVERSION = -rc6 |
| 6 | NAME = Fearless Coyote | 6 | NAME = Merciless Moray |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| 9 | # To see a list of typical targets execute "make help" | 9 | # To see a list of typical targets execute "make help" |
diff --git a/arch/Kconfig b/arch/Kconfig index 8e0d665c8d53..75dd23acf133 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -464,6 +464,10 @@ config GCC_PLUGIN_LATENT_ENTROPY | |||
| 464 | config GCC_PLUGIN_STRUCTLEAK | 464 | config GCC_PLUGIN_STRUCTLEAK |
| 465 | bool "Force initialization of variables containing userspace addresses" | 465 | bool "Force initialization of variables containing userspace addresses" |
| 466 | depends on GCC_PLUGINS | 466 | depends on GCC_PLUGINS |
| 467 | # Currently STRUCTLEAK inserts initialization out of live scope of | ||
| 468 | # variables from KASAN point of view. This leads to KASAN false | ||
| 469 | # positive reports. Prohibit this combination for now. | ||
| 470 | depends on !KASAN_EXTRA | ||
| 467 | help | 471 | help |
| 468 | This plugin zero-initializes any structures containing a | 472 | This plugin zero-initializes any structures containing a |
| 469 | __user attribute. This can prevent some classes of information | 473 | __user attribute. This can prevent some classes of information |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 45a6b9b7af2a..6a4e7341ecd3 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
| @@ -117,11 +117,9 @@ ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj) | |||
| 117 | asflags-y := -DZIMAGE | 117 | asflags-y := -DZIMAGE |
| 118 | 118 | ||
| 119 | # Supply kernel BSS size to the decompressor via a linker symbol. | 119 | # Supply kernel BSS size to the decompressor via a linker symbol. |
| 120 | KBSS_SZ = $(shell $(CROSS_COMPILE)nm $(obj)/../../../../vmlinux | \ | 120 | KBSS_SZ = $(shell echo $$(($$($(CROSS_COMPILE)nm $(obj)/../../../../vmlinux | \ |
| 121 | perl -e 'while (<>) { \ | 121 | sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \ |
| 122 | $$bss_start=hex($$1) if /^([[:xdigit:]]+) B __bss_start$$/; \ | 122 | -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) ) |
| 123 | $$bss_end=hex($$1) if /^([[:xdigit:]]+) B __bss_stop$$/; \ | ||
| 124 | }; printf "%d\n", $$bss_end - $$bss_start;') | ||
| 125 | LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ) | 123 | LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ) |
| 126 | # Supply ZRELADDR to the decompressor via a linker symbol. | 124 | # Supply ZRELADDR to the decompressor via a linker symbol. |
| 127 | ifneq ($(CONFIG_AUTO_ZRELADDR),y) | 125 | ifneq ($(CONFIG_AUTO_ZRELADDR),y) |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 45c8823c3750..517e0e18f0b8 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
| @@ -29,19 +29,19 @@ | |||
| 29 | #if defined(CONFIG_DEBUG_ICEDCC) | 29 | #if defined(CONFIG_DEBUG_ICEDCC) |
| 30 | 30 | ||
| 31 | #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) | 31 | #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) |
| 32 | .macro loadsp, rb, tmp | 32 | .macro loadsp, rb, tmp1, tmp2 |
| 33 | .endm | 33 | .endm |
| 34 | .macro writeb, ch, rb | 34 | .macro writeb, ch, rb |
| 35 | mcr p14, 0, \ch, c0, c5, 0 | 35 | mcr p14, 0, \ch, c0, c5, 0 |
| 36 | .endm | 36 | .endm |
| 37 | #elif defined(CONFIG_CPU_XSCALE) | 37 | #elif defined(CONFIG_CPU_XSCALE) |
| 38 | .macro loadsp, rb, tmp | 38 | .macro loadsp, rb, tmp1, tmp2 |
| 39 | .endm | 39 | .endm |
| 40 | .macro writeb, ch, rb | 40 | .macro writeb, ch, rb |
| 41 | mcr p14, 0, \ch, c8, c0, 0 | 41 | mcr p14, 0, \ch, c8, c0, 0 |
| 42 | .endm | 42 | .endm |
| 43 | #else | 43 | #else |
| 44 | .macro loadsp, rb, tmp | 44 | .macro loadsp, rb, tmp1, tmp2 |
| 45 | .endm | 45 | .endm |
| 46 | .macro writeb, ch, rb | 46 | .macro writeb, ch, rb |
| 47 | mcr p14, 0, \ch, c1, c0, 0 | 47 | mcr p14, 0, \ch, c1, c0, 0 |
| @@ -57,7 +57,7 @@ | |||
| 57 | .endm | 57 | .endm |
| 58 | 58 | ||
| 59 | #if defined(CONFIG_ARCH_SA1100) | 59 | #if defined(CONFIG_ARCH_SA1100) |
| 60 | .macro loadsp, rb, tmp | 60 | .macro loadsp, rb, tmp1, tmp2 |
| 61 | mov \rb, #0x80000000 @ physical base address | 61 | mov \rb, #0x80000000 @ physical base address |
| 62 | #ifdef CONFIG_DEBUG_LL_SER3 | 62 | #ifdef CONFIG_DEBUG_LL_SER3 |
| 63 | add \rb, \rb, #0x00050000 @ Ser3 | 63 | add \rb, \rb, #0x00050000 @ Ser3 |
| @@ -66,8 +66,8 @@ | |||
| 66 | #endif | 66 | #endif |
| 67 | .endm | 67 | .endm |
| 68 | #else | 68 | #else |
| 69 | .macro loadsp, rb, tmp | 69 | .macro loadsp, rb, tmp1, tmp2 |
| 70 | addruart \rb, \tmp | 70 | addruart \rb, \tmp1, \tmp2 |
| 71 | .endm | 71 | .endm |
| 72 | #endif | 72 | #endif |
| 73 | #endif | 73 | #endif |
| @@ -561,8 +561,6 @@ not_relocated: mov r0, #0 | |||
| 561 | bl decompress_kernel | 561 | bl decompress_kernel |
| 562 | bl cache_clean_flush | 562 | bl cache_clean_flush |
| 563 | bl cache_off | 563 | bl cache_off |
| 564 | mov r1, r7 @ restore architecture number | ||
| 565 | mov r2, r8 @ restore atags pointer | ||
| 566 | 564 | ||
| 567 | #ifdef CONFIG_ARM_VIRT_EXT | 565 | #ifdef CONFIG_ARM_VIRT_EXT |
| 568 | mrs r0, spsr @ Get saved CPU boot mode | 566 | mrs r0, spsr @ Get saved CPU boot mode |
| @@ -1297,7 +1295,7 @@ phex: adr r3, phexbuf | |||
| 1297 | b 1b | 1295 | b 1b |
| 1298 | 1296 | ||
| 1299 | @ puts corrupts {r0, r1, r2, r3} | 1297 | @ puts corrupts {r0, r1, r2, r3} |
| 1300 | puts: loadsp r3, r1 | 1298 | puts: loadsp r3, r2, r1 |
| 1301 | 1: ldrb r2, [r0], #1 | 1299 | 1: ldrb r2, [r0], #1 |
| 1302 | teq r2, #0 | 1300 | teq r2, #0 |
| 1303 | moveq pc, lr | 1301 | moveq pc, lr |
| @@ -1314,8 +1312,8 @@ puts: loadsp r3, r1 | |||
| 1314 | @ putc corrupts {r0, r1, r2, r3} | 1312 | @ putc corrupts {r0, r1, r2, r3} |
| 1315 | putc: | 1313 | putc: |
| 1316 | mov r2, r0 | 1314 | mov r2, r0 |
| 1315 | loadsp r3, r1, r0 | ||
| 1317 | mov r0, #0 | 1316 | mov r0, #0 |
| 1318 | loadsp r3, r1 | ||
| 1319 | b 2b | 1317 | b 2b |
| 1320 | 1318 | ||
| 1321 | @ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr} | 1319 | @ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr} |
| @@ -1365,6 +1363,8 @@ __hyp_reentry_vectors: | |||
| 1365 | 1363 | ||
| 1366 | __enter_kernel: | 1364 | __enter_kernel: |
| 1367 | mov r0, #0 @ must be 0 | 1365 | mov r0, #0 @ must be 0 |
| 1366 | mov r1, r7 @ restore architecture number | ||
| 1367 | mov r2, r8 @ restore atags pointer | ||
| 1368 | ARM( mov pc, r4 ) @ call kernel | 1368 | ARM( mov pc, r4 ) @ call kernel |
| 1369 | M_CLASS( add r4, r4, #1 ) @ enter in Thumb mode for M class | 1369 | M_CLASS( add r4, r4, #1 ) @ enter in Thumb mode for M class |
| 1370 | THUMB( bx r4 ) @ entry point is always ARM for A/R classes | 1370 | THUMB( bx r4 ) @ entry point is always ARM for A/R classes |
diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index 699fdf94d139..9fe4f5a6379e 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi | |||
| @@ -69,7 +69,7 @@ | |||
| 69 | timer@20200 { | 69 | timer@20200 { |
| 70 | compatible = "arm,cortex-a9-global-timer"; | 70 | compatible = "arm,cortex-a9-global-timer"; |
| 71 | reg = <0x20200 0x100>; | 71 | reg = <0x20200 0x100>; |
| 72 | interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>; | 72 | interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>; |
| 73 | clocks = <&periph_clk>; | 73 | clocks = <&periph_clk>; |
| 74 | }; | 74 | }; |
| 75 | 75 | ||
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts index a1f4d6d5a569..0edf769ea95c 100644 --- a/arch/arm/boot/dts/da850-lcdk.dts +++ b/arch/arm/boot/dts/da850-lcdk.dts | |||
| @@ -21,8 +21,8 @@ | |||
| 21 | stdout-path = "serial2:115200n8"; | 21 | stdout-path = "serial2:115200n8"; |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | memory { | 24 | memory@c0000000 { |
| 25 | device_type = "memory"; | 25 | /* 128 MB DDR2 SDRAM @ 0xc0000000 */ |
| 26 | reg = <0xc0000000 0x08000000>; | 26 | reg = <0xc0000000 0x08000000>; |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi index c66cf7895363..12010002dbdb 100644 --- a/arch/arm/boot/dts/da850.dtsi +++ b/arch/arm/boot/dts/da850.dtsi | |||
| @@ -7,10 +7,19 @@ | |||
| 7 | * Free Software Foundation; either version 2 of the License, or (at your | 7 | * Free Software Foundation; either version 2 of the License, or (at your |
| 8 | * option) any later version. | 8 | * option) any later version. |
| 9 | */ | 9 | */ |
| 10 | #include "skeleton.dtsi" | ||
| 11 | #include <dt-bindings/interrupt-controller/irq.h> | 10 | #include <dt-bindings/interrupt-controller/irq.h> |
| 12 | 11 | ||
| 13 | / { | 12 | / { |
| 13 | #address-cells = <1>; | ||
| 14 | #size-cells = <1>; | ||
| 15 | chosen { }; | ||
| 16 | aliases { }; | ||
| 17 | |||
| 18 | memory@c0000000 { | ||
| 19 | device_type = "memory"; | ||
| 20 | reg = <0xc0000000 0x0>; | ||
| 21 | }; | ||
| 22 | |||
| 14 | arm { | 23 | arm { |
| 15 | #address-cells = <1>; | 24 | #address-cells = <1>; |
| 16 | #size-cells = <1>; | 25 | #size-cells = <1>; |
| @@ -46,8 +55,6 @@ | |||
| 46 | pmx_core: pinmux@14120 { | 55 | pmx_core: pinmux@14120 { |
| 47 | compatible = "pinctrl-single"; | 56 | compatible = "pinctrl-single"; |
| 48 | reg = <0x14120 0x50>; | 57 | reg = <0x14120 0x50>; |
| 49 | #address-cells = <1>; | ||
| 50 | #size-cells = <0>; | ||
| 51 | #pinctrl-cells = <2>; | 58 | #pinctrl-cells = <2>; |
| 52 | pinctrl-single,bit-per-mux; | 59 | pinctrl-single,bit-per-mux; |
| 53 | pinctrl-single,register-width = <32>; | 60 | pinctrl-single,register-width = <32>; |
diff --git a/arch/arm/boot/dts/dm8148-evm.dts b/arch/arm/boot/dts/dm8148-evm.dts index d6657b3bae84..85d7b5148b0a 100644 --- a/arch/arm/boot/dts/dm8148-evm.dts +++ b/arch/arm/boot/dts/dm8148-evm.dts | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | / { | 11 | / { |
| 12 | model = "DM8148 EVM"; | 12 | model = "DM8148 EVM"; |
| 13 | compatible = "ti,dm8148-evm", "ti,dm8148"; | 13 | compatible = "ti,dm8148-evm", "ti,dm8148", "ti,dm814"; |
| 14 | 14 | ||
| 15 | memory@80000000 { | 15 | memory@80000000 { |
| 16 | device_type = "memory"; | 16 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/dm8148-t410.dts b/arch/arm/boot/dts/dm8148-t410.dts index 63883b3479f9..6418f9cdbe83 100644 --- a/arch/arm/boot/dts/dm8148-t410.dts +++ b/arch/arm/boot/dts/dm8148-t410.dts | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | / { | 10 | / { |
| 11 | model = "HP t410 Smart Zero Client"; | 11 | model = "HP t410 Smart Zero Client"; |
| 12 | compatible = "hp,t410", "ti,dm8148"; | 12 | compatible = "hp,t410", "ti,dm8148", "ti,dm814"; |
| 13 | 13 | ||
| 14 | memory@80000000 { | 14 | memory@80000000 { |
| 15 | device_type = "memory"; | 15 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts index c72a2132aa82..1d030d567307 100644 --- a/arch/arm/boot/dts/dm8168-evm.dts +++ b/arch/arm/boot/dts/dm8168-evm.dts | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | / { | 11 | / { |
| 12 | model = "DM8168 EVM"; | 12 | model = "DM8168 EVM"; |
| 13 | compatible = "ti,dm8168-evm", "ti,dm8168"; | 13 | compatible = "ti,dm8168-evm", "ti,dm8168", "ti,dm816"; |
| 14 | 14 | ||
| 15 | memory@80000000 { | 15 | memory@80000000 { |
| 16 | device_type = "memory"; | 16 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/dra62x-j5eco-evm.dts b/arch/arm/boot/dts/dra62x-j5eco-evm.dts index fee0547f7302..31b824ad5d29 100644 --- a/arch/arm/boot/dts/dra62x-j5eco-evm.dts +++ b/arch/arm/boot/dts/dra62x-j5eco-evm.dts | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | / { | 11 | / { |
| 12 | model = "DRA62x J5 Eco EVM"; | 12 | model = "DRA62x J5 Eco EVM"; |
| 13 | compatible = "ti,dra62x-j5eco-evm", "ti,dra62x", "ti,dm8148"; | 13 | compatible = "ti,dra62x-j5eco-evm", "ti,dra62x", "ti,dm8148", "ti,dm814"; |
| 14 | 14 | ||
| 15 | memory@80000000 { | 15 | memory@80000000 { |
| 16 | device_type = "memory"; | 16 | device_type = "memory"; |
diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi index bf343195697e..54111ed218b1 100644 --- a/arch/arm/boot/dts/imx35.dtsi +++ b/arch/arm/boot/dts/imx35.dtsi | |||
| @@ -303,7 +303,7 @@ | |||
| 303 | }; | 303 | }; |
| 304 | 304 | ||
| 305 | can1: can@53fe4000 { | 305 | can1: can@53fe4000 { |
| 306 | compatible = "fsl,imx35-flexcan"; | 306 | compatible = "fsl,imx35-flexcan", "fsl,imx25-flexcan"; |
| 307 | reg = <0x53fe4000 0x1000>; | 307 | reg = <0x53fe4000 0x1000>; |
| 308 | clocks = <&clks 33>, <&clks 33>; | 308 | clocks = <&clks 33>, <&clks 33>; |
| 309 | clock-names = "ipg", "per"; | 309 | clock-names = "ipg", "per"; |
| @@ -312,7 +312,7 @@ | |||
| 312 | }; | 312 | }; |
| 313 | 313 | ||
| 314 | can2: can@53fe8000 { | 314 | can2: can@53fe8000 { |
| 315 | compatible = "fsl,imx35-flexcan"; | 315 | compatible = "fsl,imx35-flexcan", "fsl,imx25-flexcan"; |
| 316 | reg = <0x53fe8000 0x1000>; | 316 | reg = <0x53fe8000 0x1000>; |
| 317 | clocks = <&clks 34>, <&clks 34>; | 317 | clocks = <&clks 34>, <&clks 34>; |
| 318 | clock-names = "ipg", "per"; | 318 | clock-names = "ipg", "per"; |
diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts b/arch/arm/boot/dts/imx51-zii-rdu1.dts index 0c99ac04ad08..6464f2560e06 100644 --- a/arch/arm/boot/dts/imx51-zii-rdu1.dts +++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts | |||
| @@ -523,7 +523,7 @@ | |||
| 523 | }; | 523 | }; |
| 524 | 524 | ||
| 525 | touchscreen@20 { | 525 | touchscreen@20 { |
| 526 | compatible = "syna,rmi4_i2c"; | 526 | compatible = "syna,rmi4-i2c"; |
| 527 | reg = <0x20>; | 527 | reg = <0x20>; |
| 528 | pinctrl-names = "default"; | 528 | pinctrl-names = "default"; |
| 529 | pinctrl-0 = <&pinctrl_ts>; | 529 | pinctrl-0 = <&pinctrl_ts>; |
| @@ -541,8 +541,8 @@ | |||
| 541 | 541 | ||
| 542 | rmi4-f11@11 { | 542 | rmi4-f11@11 { |
| 543 | reg = <0x11>; | 543 | reg = <0x11>; |
| 544 | touch-inverted-y; | 544 | touchscreen-inverted-y; |
| 545 | touch-swapped-x-y; | 545 | touchscreen-swapped-x-y; |
| 546 | syna,sensor-type = <1>; | 546 | syna,sensor-type = <1>; |
| 547 | }; | 547 | }; |
| 548 | }; | 548 | }; |
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 7d647d043f52..3d65c0192f69 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi | |||
| @@ -551,7 +551,7 @@ | |||
| 551 | }; | 551 | }; |
| 552 | 552 | ||
| 553 | can1: can@53fc8000 { | 553 | can1: can@53fc8000 { |
| 554 | compatible = "fsl,imx53-flexcan"; | 554 | compatible = "fsl,imx53-flexcan", "fsl,imx25-flexcan"; |
| 555 | reg = <0x53fc8000 0x4000>; | 555 | reg = <0x53fc8000 0x4000>; |
| 556 | interrupts = <82>; | 556 | interrupts = <82>; |
| 557 | clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, | 557 | clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, |
| @@ -561,7 +561,7 @@ | |||
| 561 | }; | 561 | }; |
| 562 | 562 | ||
| 563 | can2: can@53fcc000 { | 563 | can2: can@53fcc000 { |
| 564 | compatible = "fsl,imx53-flexcan"; | 564 | compatible = "fsl,imx53-flexcan", "fsl,imx25-flexcan"; |
| 565 | reg = <0x53fcc000 0x4000>; | 565 | reg = <0x53fcc000 0x4000>; |
| 566 | interrupts = <83>; | 566 | interrupts = <83>; |
| 567 | clocks = <&clks IMX5_CLK_CAN2_IPG_GATE>, | 567 | clocks = <&clks IMX5_CLK_CAN2_IPG_GATE>, |
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 4d42335c0dee..ce85b3ca1a55 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi | |||
| @@ -868,6 +868,7 @@ | |||
| 868 | 868 | ||
| 869 | crypto: caam@30900000 { | 869 | crypto: caam@30900000 { |
| 870 | compatible = "fsl,sec-v4.0"; | 870 | compatible = "fsl,sec-v4.0"; |
| 871 | fsl,sec-era = <8>; | ||
| 871 | #address-cells = <1>; | 872 | #address-cells = <1>; |
| 872 | #size-cells = <1>; | 873 | #size-cells = <1>; |
| 873 | reg = <0x30900000 0x40000>; | 874 | reg = <0x30900000 0x40000>; |
diff --git a/arch/arm/boot/dts/logicpd-som-lv.dtsi b/arch/arm/boot/dts/logicpd-som-lv.dtsi index b47cac23a04b..6fa7bba3e801 100644 --- a/arch/arm/boot/dts/logicpd-som-lv.dtsi +++ b/arch/arm/boot/dts/logicpd-som-lv.dtsi | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | gpio = <&gpio1 3 0>; /* gpio_3 */ | 26 | gpio = <&gpio1 3 0>; /* gpio_3 */ |
| 27 | startup-delay-us = <70000>; | 27 | startup-delay-us = <70000>; |
| 28 | enable-active-high; | 28 | enable-active-high; |
| 29 | vin-supply = <&vmmc2>; | 29 | vin-supply = <&vaux3>; |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | /* HS USB Host PHY on PORT 1 */ | 32 | /* HS USB Host PHY on PORT 1 */ |
| @@ -82,6 +82,7 @@ | |||
| 82 | twl_audio: audio { | 82 | twl_audio: audio { |
| 83 | compatible = "ti,twl4030-audio"; | 83 | compatible = "ti,twl4030-audio"; |
| 84 | codec { | 84 | codec { |
| 85 | ti,hs_extmute_gpio = <&gpio2 25 GPIO_ACTIVE_HIGH>; | ||
| 85 | }; | 86 | }; |
| 86 | }; | 87 | }; |
| 87 | }; | 88 | }; |
| @@ -199,6 +200,7 @@ | |||
| 199 | pinctrl-single,pins = < | 200 | pinctrl-single,pins = < |
| 200 | OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */ | 201 | OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */ |
| 201 | OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */ | 202 | OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */ |
| 203 | OMAP3_CORE1_IOPAD(0x20ba, PIN_OUTPUT | MUX_MODE4) /* gpmc_ncs6.gpio_57 */ | ||
| 202 | >; | 204 | >; |
| 203 | }; | 205 | }; |
| 204 | }; | 206 | }; |
| @@ -213,7 +215,7 @@ | |||
| 213 | }; | 215 | }; |
| 214 | wl127x_gpio: pinmux_wl127x_gpio_pin { | 216 | wl127x_gpio: pinmux_wl127x_gpio_pin { |
| 215 | pinctrl-single,pins = < | 217 | pinctrl-single,pins = < |
| 216 | OMAP3_WKUP_IOPAD(0x2a0c, PIN_INPUT | MUX_MODE4) /* sys_boot0.gpio_2 */ | 218 | OMAP3_WKUP_IOPAD(0x2a0a, PIN_INPUT | MUX_MODE4) /* sys_boot0.gpio_2 */ |
| 217 | OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4) /* sys_boot1.gpio_3 */ | 219 | OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4) /* sys_boot1.gpio_3 */ |
| 218 | >; | 220 | >; |
| 219 | }; | 221 | }; |
| @@ -260,6 +262,11 @@ | |||
| 260 | #include "twl4030.dtsi" | 262 | #include "twl4030.dtsi" |
| 261 | #include "twl4030_omap3.dtsi" | 263 | #include "twl4030_omap3.dtsi" |
| 262 | 264 | ||
| 265 | &vaux3 { | ||
| 266 | regulator-min-microvolt = <2800000>; | ||
| 267 | regulator-max-microvolt = <2800000>; | ||
| 268 | }; | ||
| 269 | |||
| 263 | &twl { | 270 | &twl { |
| 264 | twl_power: power { | 271 | twl_power: power { |
| 265 | compatible = "ti,twl4030-power-idle-osc-off", "ti,twl4030-power-idle"; | 272 | compatible = "ti,twl4030-power-idle-osc-off", "ti,twl4030-power-idle"; |
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 063fdb65dc60..f07f9018c3e7 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts | |||
| @@ -379,7 +379,7 @@ | |||
| 379 | port@0 { | 379 | port@0 { |
| 380 | reg = <0>; | 380 | reg = <0>; |
| 381 | adv7511_in: endpoint { | 381 | adv7511_in: endpoint { |
| 382 | remote-endpoint = <&du_out_lvds0>; | 382 | remote-endpoint = <&lvds0_out>; |
| 383 | }; | 383 | }; |
| 384 | }; | 384 | }; |
| 385 | 385 | ||
| @@ -467,10 +467,8 @@ | |||
| 467 | status = "okay"; | 467 | status = "okay"; |
| 468 | 468 | ||
| 469 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 722>, | 469 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 722>, |
| 470 | <&cpg CPG_MOD 726>, <&cpg CPG_MOD 725>, | ||
| 471 | <&x13_clk>, <&x2_clk>; | 470 | <&x13_clk>, <&x2_clk>; |
| 472 | clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1", | 471 | clock-names = "du.0", "du.1", "du.2", "dclkin.0", "dclkin.1"; |
| 473 | "dclkin.0", "dclkin.1"; | ||
| 474 | 472 | ||
| 475 | ports { | 473 | ports { |
| 476 | port@0 { | 474 | port@0 { |
| @@ -478,12 +476,26 @@ | |||
| 478 | remote-endpoint = <&adv7123_in>; | 476 | remote-endpoint = <&adv7123_in>; |
| 479 | }; | 477 | }; |
| 480 | }; | 478 | }; |
| 479 | }; | ||
| 480 | }; | ||
| 481 | |||
| 482 | &lvds0 { | ||
| 483 | status = "okay"; | ||
| 484 | |||
| 485 | ports { | ||
| 481 | port@1 { | 486 | port@1 { |
| 482 | endpoint { | 487 | endpoint { |
| 483 | remote-endpoint = <&adv7511_in>; | 488 | remote-endpoint = <&adv7511_in>; |
| 484 | }; | 489 | }; |
| 485 | }; | 490 | }; |
| 486 | port@2 { | 491 | }; |
| 492 | }; | ||
| 493 | |||
| 494 | &lvds1 { | ||
| 495 | status = "okay"; | ||
| 496 | |||
| 497 | ports { | ||
| 498 | port@1 { | ||
| 487 | lvds_connector: endpoint { | 499 | lvds_connector: endpoint { |
| 488 | }; | 500 | }; |
| 489 | }; | 501 | }; |
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index e4367cecad18..05a0fc23ac88 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi | |||
| @@ -1627,18 +1627,13 @@ | |||
| 1627 | 1627 | ||
| 1628 | du: display@feb00000 { | 1628 | du: display@feb00000 { |
| 1629 | compatible = "renesas,du-r8a7790"; | 1629 | compatible = "renesas,du-r8a7790"; |
| 1630 | reg = <0 0xfeb00000 0 0x70000>, | 1630 | reg = <0 0xfeb00000 0 0x70000>; |
| 1631 | <0 0xfeb90000 0 0x1c>, | ||
| 1632 | <0 0xfeb94000 0 0x1c>; | ||
| 1633 | reg-names = "du", "lvds.0", "lvds.1"; | ||
| 1634 | interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, | 1631 | interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, |
| 1635 | <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, | 1632 | <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, |
| 1636 | <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>; | 1633 | <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>; |
| 1637 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, | 1634 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, |
| 1638 | <&cpg CPG_MOD 722>, <&cpg CPG_MOD 726>, | 1635 | <&cpg CPG_MOD 722>; |
| 1639 | <&cpg CPG_MOD 725>; | 1636 | clock-names = "du.0", "du.1", "du.2"; |
| 1640 | clock-names = "du.0", "du.1", "du.2", "lvds.0", | ||
| 1641 | "lvds.1"; | ||
| 1642 | status = "disabled"; | 1637 | status = "disabled"; |
| 1643 | 1638 | ||
| 1644 | ports { | 1639 | ports { |
| @@ -1653,11 +1648,65 @@ | |||
| 1653 | port@1 { | 1648 | port@1 { |
| 1654 | reg = <1>; | 1649 | reg = <1>; |
| 1655 | du_out_lvds0: endpoint { | 1650 | du_out_lvds0: endpoint { |
| 1651 | remote-endpoint = <&lvds0_in>; | ||
| 1656 | }; | 1652 | }; |
| 1657 | }; | 1653 | }; |
| 1658 | port@2 { | 1654 | port@2 { |
| 1659 | reg = <2>; | 1655 | reg = <2>; |
| 1660 | du_out_lvds1: endpoint { | 1656 | du_out_lvds1: endpoint { |
| 1657 | remote-endpoint = <&lvds1_in>; | ||
| 1658 | }; | ||
| 1659 | }; | ||
| 1660 | }; | ||
| 1661 | }; | ||
| 1662 | |||
| 1663 | lvds0: lvds@feb90000 { | ||
| 1664 | compatible = "renesas,r8a7790-lvds"; | ||
| 1665 | reg = <0 0xfeb90000 0 0x1c>; | ||
| 1666 | clocks = <&cpg CPG_MOD 726>; | ||
| 1667 | power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; | ||
| 1668 | resets = <&cpg 726>; | ||
| 1669 | status = "disabled"; | ||
| 1670 | |||
| 1671 | ports { | ||
| 1672 | #address-cells = <1>; | ||
| 1673 | #size-cells = <0>; | ||
| 1674 | |||
| 1675 | port@0 { | ||
| 1676 | reg = <0>; | ||
| 1677 | lvds0_in: endpoint { | ||
| 1678 | remote-endpoint = <&du_out_lvds0>; | ||
| 1679 | }; | ||
| 1680 | }; | ||
| 1681 | port@1 { | ||
| 1682 | reg = <1>; | ||
| 1683 | lvds0_out: endpoint { | ||
| 1684 | }; | ||
| 1685 | }; | ||
| 1686 | }; | ||
| 1687 | }; | ||
| 1688 | |||
| 1689 | lvds1: lvds@feb94000 { | ||
| 1690 | compatible = "renesas,r8a7790-lvds"; | ||
| 1691 | reg = <0 0xfeb94000 0 0x1c>; | ||
| 1692 | clocks = <&cpg CPG_MOD 725>; | ||
| 1693 | power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; | ||
| 1694 | resets = <&cpg 725>; | ||
| 1695 | status = "disabled"; | ||
| 1696 | |||
| 1697 | ports { | ||
| 1698 | #address-cells = <1>; | ||
| 1699 | #size-cells = <0>; | ||
| 1700 | |||
| 1701 | port@0 { | ||
| 1702 | reg = <0>; | ||
| 1703 | lvds1_in: endpoint { | ||
| 1704 | remote-endpoint = <&du_out_lvds1>; | ||
| 1705 | }; | ||
| 1706 | }; | ||
| 1707 | port@1 { | ||
| 1708 | reg = <1>; | ||
| 1709 | lvds1_out: endpoint { | ||
| 1661 | }; | 1710 | }; |
| 1662 | }; | 1711 | }; |
| 1663 | }; | 1712 | }; |
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index f40321a1c917..9d7213a0b8b8 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts | |||
| @@ -468,10 +468,9 @@ | |||
| 468 | pinctrl-names = "default"; | 468 | pinctrl-names = "default"; |
| 469 | status = "okay"; | 469 | status = "okay"; |
| 470 | 470 | ||
| 471 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 726>, | 471 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, |
| 472 | <&x13_clk>, <&x2_clk>; | 472 | <&x13_clk>, <&x2_clk>; |
| 473 | clock-names = "du.0", "du.1", "lvds.0", | 473 | clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1"; |
| 474 | "dclkin.0", "dclkin.1"; | ||
| 475 | 474 | ||
| 476 | ports { | 475 | ports { |
| 477 | port@0 { | 476 | port@0 { |
| @@ -479,6 +478,13 @@ | |||
| 479 | remote-endpoint = <&adv7511_in>; | 478 | remote-endpoint = <&adv7511_in>; |
| 480 | }; | 479 | }; |
| 481 | }; | 480 | }; |
| 481 | }; | ||
| 482 | }; | ||
| 483 | |||
| 484 | &lvds0 { | ||
| 485 | status = "okay"; | ||
| 486 | |||
| 487 | ports { | ||
| 482 | port@1 { | 488 | port@1 { |
| 483 | lvds_connector: endpoint { | 489 | lvds_connector: endpoint { |
| 484 | }; | 490 | }; |
diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index c14e6fe9e4f6..ae9ed9ff53ef 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts | |||
| @@ -441,10 +441,9 @@ | |||
| 441 | pinctrl-names = "default"; | 441 | pinctrl-names = "default"; |
| 442 | status = "okay"; | 442 | status = "okay"; |
| 443 | 443 | ||
| 444 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 726>, | 444 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, |
| 445 | <&x3_clk>, <&x16_clk>; | 445 | <&x3_clk>, <&x16_clk>; |
| 446 | clock-names = "du.0", "du.1", "lvds.0", | 446 | clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1"; |
| 447 | "dclkin.0", "dclkin.1"; | ||
| 448 | 447 | ||
| 449 | ports { | 448 | ports { |
| 450 | port@0 { | 449 | port@0 { |
| @@ -455,6 +454,17 @@ | |||
| 455 | }; | 454 | }; |
| 456 | }; | 455 | }; |
| 457 | 456 | ||
| 457 | &lvds0 { | ||
| 458 | status = "okay"; | ||
| 459 | |||
| 460 | ports { | ||
| 461 | port@1 { | ||
| 462 | lvds_connector: endpoint { | ||
| 463 | }; | ||
| 464 | }; | ||
| 465 | }; | ||
| 466 | }; | ||
| 467 | |||
| 458 | &rcar_sound { | 468 | &rcar_sound { |
| 459 | pinctrl-0 = <&ssi_pins &audio_clk_pins>; | 469 | pinctrl-0 = <&ssi_pins &audio_clk_pins>; |
| 460 | pinctrl-names = "default"; | 470 | pinctrl-names = "default"; |
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index f11dab71b03a..506b20885413 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi | |||
| @@ -1633,15 +1633,12 @@ | |||
| 1633 | 1633 | ||
| 1634 | du: display@feb00000 { | 1634 | du: display@feb00000 { |
| 1635 | compatible = "renesas,du-r8a7791"; | 1635 | compatible = "renesas,du-r8a7791"; |
| 1636 | reg = <0 0xfeb00000 0 0x40000>, | 1636 | reg = <0 0xfeb00000 0 0x40000>; |
| 1637 | <0 0xfeb90000 0 0x1c>; | ||
| 1638 | reg-names = "du", "lvds.0"; | ||
| 1639 | interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, | 1637 | interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, |
| 1640 | <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; | 1638 | <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; |
| 1641 | clocks = <&cpg CPG_MOD 724>, | 1639 | clocks = <&cpg CPG_MOD 724>, |
| 1642 | <&cpg CPG_MOD 723>, | 1640 | <&cpg CPG_MOD 723>; |
| 1643 | <&cpg CPG_MOD 726>; | 1641 | clock-names = "du.0", "du.1"; |
| 1644 | clock-names = "du.0", "du.1", "lvds.0"; | ||
| 1645 | status = "disabled"; | 1642 | status = "disabled"; |
| 1646 | 1643 | ||
| 1647 | ports { | 1644 | ports { |
| @@ -1656,6 +1653,33 @@ | |||
| 1656 | port@1 { | 1653 | port@1 { |
| 1657 | reg = <1>; | 1654 | reg = <1>; |
| 1658 | du_out_lvds0: endpoint { | 1655 | du_out_lvds0: endpoint { |
| 1656 | remote-endpoint = <&lvds0_in>; | ||
| 1657 | }; | ||
| 1658 | }; | ||
| 1659 | }; | ||
| 1660 | }; | ||
| 1661 | |||
| 1662 | lvds0: lvds@feb90000 { | ||
| 1663 | compatible = "renesas,r8a7791-lvds"; | ||
| 1664 | reg = <0 0xfeb90000 0 0x1c>; | ||
| 1665 | clocks = <&cpg CPG_MOD 726>; | ||
| 1666 | power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; | ||
| 1667 | resets = <&cpg 726>; | ||
| 1668 | status = "disabled"; | ||
| 1669 | |||
| 1670 | ports { | ||
| 1671 | #address-cells = <1>; | ||
| 1672 | #size-cells = <0>; | ||
| 1673 | |||
| 1674 | port@0 { | ||
| 1675 | reg = <0>; | ||
| 1676 | lvds0_in: endpoint { | ||
| 1677 | remote-endpoint = <&du_out_lvds0>; | ||
| 1678 | }; | ||
| 1679 | }; | ||
| 1680 | port@1 { | ||
| 1681 | reg = <1>; | ||
| 1682 | lvds0_out: endpoint { | ||
| 1659 | }; | 1683 | }; |
| 1660 | }; | 1684 | }; |
| 1661 | }; | 1685 | }; |
diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 9ed6961f2d9a..96e117d8b2cc 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts | |||
| @@ -447,10 +447,9 @@ | |||
| 447 | pinctrl-names = "default"; | 447 | pinctrl-names = "default"; |
| 448 | status = "okay"; | 448 | status = "okay"; |
| 449 | 449 | ||
| 450 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, <&cpg CPG_MOD 726>, | 450 | clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, |
| 451 | <&x13_clk>, <&x2_clk>; | 451 | <&x13_clk>, <&x2_clk>; |
| 452 | clock-names = "du.0", "du.1", "lvds.0", | 452 | clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1"; |
| 453 | "dclkin.0", "dclkin.1"; | ||
| 454 | 453 | ||
| 455 | ports { | 454 | ports { |
| 456 | port@0 { | 455 | port@0 { |
| @@ -458,6 +457,11 @@ | |||
| 458 | remote-endpoint = <&adv7511_in>; | 457 | remote-endpoint = <&adv7511_in>; |
| 459 | }; | 458 | }; |
| 460 | }; | 459 | }; |
| 460 | }; | ||
| 461 | }; | ||
| 462 | |||
| 463 | &lvds0 { | ||
| 464 | ports { | ||
| 461 | port@1 { | 465 | port@1 { |
| 462 | lvds_connector: endpoint { | 466 | lvds_connector: endpoint { |
| 463 | }; | 467 | }; |
diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index f9c5a557107d..4f526030dc7c 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi | |||
| @@ -1292,15 +1292,12 @@ | |||
| 1292 | 1292 | ||
| 1293 | du: display@feb00000 { | 1293 | du: display@feb00000 { |
| 1294 | compatible = "renesas,du-r8a7793"; | 1294 | compatible = "renesas,du-r8a7793"; |
| 1295 | reg = <0 0xfeb00000 0 0x40000>, | 1295 | reg = <0 0xfeb00000 0 0x40000>; |
| 1296 | <0 0xfeb90000 0 0x1c>; | ||
| 1297 | reg-names = "du", "lvds.0"; | ||
| 1298 | interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, | 1296 | interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, |
| 1299 | <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; | 1297 | <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; |
| 1300 | clocks = <&cpg CPG_MOD 724>, | 1298 | clocks = <&cpg CPG_MOD 724>, |
| 1301 | <&cpg CPG_MOD 723>, | 1299 | <&cpg CPG_MOD 723>; |
| 1302 | <&cpg CPG_MOD 726>; | 1300 | clock-names = "du.0", "du.1"; |
| 1303 | clock-names = "du.0", "du.1", "lvds.0"; | ||
| 1304 | status = "disabled"; | 1301 | status = "disabled"; |
| 1305 | 1302 | ||
| 1306 | ports { | 1303 | ports { |
| @@ -1315,6 +1312,34 @@ | |||
| 1315 | port@1 { | 1312 | port@1 { |
| 1316 | reg = <1>; | 1313 | reg = <1>; |
| 1317 | du_out_lvds0: endpoint { | 1314 | du_out_lvds0: endpoint { |
| 1315 | remote-endpoint = <&lvds0_in>; | ||
| 1316 | }; | ||
| 1317 | }; | ||
| 1318 | }; | ||
| 1319 | }; | ||
| 1320 | |||
| 1321 | lvds0: lvds@feb90000 { | ||
| 1322 | compatible = "renesas,r8a7793-lvds"; | ||
| 1323 | reg = <0 0xfeb90000 0 0x1c>; | ||
| 1324 | clocks = <&cpg CPG_MOD 726>; | ||
| 1325 | power-domains = <&sysc R8A7793_PD_ALWAYS_ON>; | ||
| 1326 | resets = <&cpg 726>; | ||
| 1327 | |||
| 1328 | status = "disabled"; | ||
| 1329 | |||
| 1330 | ports { | ||
| 1331 | #address-cells = <1>; | ||
| 1332 | #size-cells = <0>; | ||
| 1333 | |||
| 1334 | port@0 { | ||
| 1335 | reg = <0>; | ||
| 1336 | lvds0_in: endpoint { | ||
| 1337 | remote-endpoint = <&du_out_lvds0>; | ||
| 1338 | }; | ||
| 1339 | }; | ||
| 1340 | port@1 { | ||
| 1341 | reg = <1>; | ||
| 1342 | lvds0_out: endpoint { | ||
| 1318 | }; | 1343 | }; |
| 1319 | }; | 1344 | }; |
| 1320 | }; | 1345 | }; |
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 0a7136462a1a..983dd5c14794 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi | |||
| @@ -741,7 +741,7 @@ | |||
| 741 | phy_type = "ulpi"; | 741 | phy_type = "ulpi"; |
| 742 | clocks = <&tegra_car TEGRA20_CLK_USB2>, | 742 | clocks = <&tegra_car TEGRA20_CLK_USB2>, |
| 743 | <&tegra_car TEGRA20_CLK_PLL_U>, | 743 | <&tegra_car TEGRA20_CLK_PLL_U>, |
| 744 | <&tegra_car TEGRA20_CLK_PLL_P_OUT4>; | 744 | <&tegra_car TEGRA20_CLK_CDEV2>; |
| 745 | clock-names = "reg", "pll_u", "ulpi-link"; | 745 | clock-names = "reg", "pll_u", "ulpi-link"; |
| 746 | resets = <&tegra_car 58>, <&tegra_car 22>; | 746 | resets = <&tegra_car 58>, <&tegra_car 22>; |
| 747 | reset-names = "usb", "utmi-pads"; | 747 | reset-names = "usb", "utmi-pads"; |
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index bc8d4bbd82e2..9342904cccca 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
| @@ -536,4 +536,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) | |||
| 536 | #endif | 536 | #endif |
| 537 | .endm | 537 | .endm |
| 538 | 538 | ||
| 539 | #ifdef CONFIG_KPROBES | ||
| 540 | #define _ASM_NOKPROBE(entry) \ | ||
| 541 | .pushsection "_kprobe_blacklist", "aw" ; \ | ||
| 542 | .balign 4 ; \ | ||
| 543 | .long entry; \ | ||
| 544 | .popsection | ||
| 545 | #else | ||
| 546 | #define _ASM_NOKPROBE(entry) | ||
| 547 | #endif | ||
| 548 | |||
| 539 | #endif /* __ASM_ASSEMBLER_H__ */ | 549 | #endif /* __ASM_ASSEMBLER_H__ */ |
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 707a1f06dc5d..f675162663f0 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
| @@ -309,6 +309,22 @@ static inline unsigned int kvm_get_vmid_bits(void) | |||
| 309 | return 8; | 309 | return 8; |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | /* | ||
| 313 | * We are not in the kvm->srcu critical section most of the time, so we take | ||
| 314 | * the SRCU read lock here. Since we copy the data from the user page, we | ||
| 315 | * can immediately drop the lock again. | ||
| 316 | */ | ||
| 317 | static inline int kvm_read_guest_lock(struct kvm *kvm, | ||
| 318 | gpa_t gpa, void *data, unsigned long len) | ||
| 319 | { | ||
| 320 | int srcu_idx = srcu_read_lock(&kvm->srcu); | ||
| 321 | int ret = kvm_read_guest(kvm, gpa, data, len); | ||
| 322 | |||
| 323 | srcu_read_unlock(&kvm->srcu, srcu_idx); | ||
| 324 | |||
| 325 | return ret; | ||
| 326 | } | ||
| 327 | |||
| 312 | static inline void *kvm_get_hyp_vector(void) | 328 | static inline void *kvm_get_hyp_vector(void) |
| 313 | { | 329 | { |
| 314 | return kvm_ksym_ref(__kvm_hyp_vector); | 330 | return kvm_ksym_ref(__kvm_hyp_vector); |
diff --git a/arch/arm/include/uapi/asm/siginfo.h b/arch/arm/include/uapi/asm/siginfo.h deleted file mode 100644 index d0513880be21..000000000000 --- a/arch/arm/include/uapi/asm/siginfo.h +++ /dev/null | |||
| @@ -1,13 +0,0 @@ | |||
| 1 | #ifndef __ASM_SIGINFO_H | ||
| 2 | #define __ASM_SIGINFO_H | ||
| 3 | |||
| 4 | #include <asm-generic/siginfo.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * SIGFPE si_codes | ||
| 8 | */ | ||
| 9 | #ifdef __KERNEL__ | ||
| 10 | #define FPE_FIXME 0 /* Broken dup of SI_USER */ | ||
| 11 | #endif /* __KERNEL__ */ | ||
| 12 | |||
| 13 | #endif | ||
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 6b38d7a634c1..dd2eb5f76b9f 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c | |||
| @@ -83,7 +83,7 @@ void machine_crash_nonpanic_core(void *unused) | |||
| 83 | { | 83 | { |
| 84 | struct pt_regs regs; | 84 | struct pt_regs regs; |
| 85 | 85 | ||
| 86 | crash_setup_regs(®s, NULL); | 86 | crash_setup_regs(®s, get_irq_regs()); |
| 87 | printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n", | 87 | printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n", |
| 88 | smp_processor_id()); | 88 | smp_processor_id()); |
| 89 | crash_save_cpu(®s, smp_processor_id()); | 89 | crash_save_cpu(®s, smp_processor_id()); |
| @@ -95,6 +95,27 @@ void machine_crash_nonpanic_core(void *unused) | |||
| 95 | cpu_relax(); | 95 | cpu_relax(); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | void crash_smp_send_stop(void) | ||
| 99 | { | ||
| 100 | static int cpus_stopped; | ||
| 101 | unsigned long msecs; | ||
| 102 | |||
| 103 | if (cpus_stopped) | ||
| 104 | return; | ||
| 105 | |||
| 106 | atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | ||
| 107 | smp_call_function(machine_crash_nonpanic_core, NULL, false); | ||
| 108 | msecs = 1000; /* Wait at most a second for the other cpus to stop */ | ||
| 109 | while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { | ||
| 110 | mdelay(1); | ||
| 111 | msecs--; | ||
| 112 | } | ||
| 113 | if (atomic_read(&waiting_for_crash_ipi) > 0) | ||
| 114 | pr_warn("Non-crashing CPUs did not react to IPI\n"); | ||
| 115 | |||
| 116 | cpus_stopped = 1; | ||
| 117 | } | ||
| 118 | |||
| 98 | static void machine_kexec_mask_interrupts(void) | 119 | static void machine_kexec_mask_interrupts(void) |
| 99 | { | 120 | { |
| 100 | unsigned int i; | 121 | unsigned int i; |
| @@ -120,19 +141,8 @@ static void machine_kexec_mask_interrupts(void) | |||
| 120 | 141 | ||
| 121 | void machine_crash_shutdown(struct pt_regs *regs) | 142 | void machine_crash_shutdown(struct pt_regs *regs) |
| 122 | { | 143 | { |
| 123 | unsigned long msecs; | ||
| 124 | |||
| 125 | local_irq_disable(); | 144 | local_irq_disable(); |
| 126 | 145 | crash_smp_send_stop(); | |
| 127 | atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | ||
| 128 | smp_call_function(machine_crash_nonpanic_core, NULL, false); | ||
| 129 | msecs = 1000; /* Wait at most a second for the other cpus to stop */ | ||
| 130 | while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { | ||
| 131 | mdelay(1); | ||
| 132 | msecs--; | ||
| 133 | } | ||
| 134 | if (atomic_read(&waiting_for_crash_ipi) > 0) | ||
| 135 | pr_warn("Non-crashing CPUs did not react to IPI\n"); | ||
| 136 | 146 | ||
| 137 | crash_save_cpu(regs, smp_processor_id()); | 147 | crash_save_cpu(regs, smp_processor_id()); |
| 138 | machine_kexec_mask_interrupts(); | 148 | machine_kexec_mask_interrupts(); |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 5e3633c24e63..2fe87109ae46 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
| 20 | #include <linux/hardirq.h> | 20 | #include <linux/hardirq.h> |
| 21 | #include <linux/kdebug.h> | 21 | #include <linux/kdebug.h> |
| 22 | #include <linux/kprobes.h> | ||
| 22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 23 | #include <linux/kexec.h> | 24 | #include <linux/kexec.h> |
| 24 | #include <linux/bug.h> | 25 | #include <linux/bug.h> |
| @@ -417,7 +418,8 @@ void unregister_undef_hook(struct undef_hook *hook) | |||
| 417 | raw_spin_unlock_irqrestore(&undef_lock, flags); | 418 | raw_spin_unlock_irqrestore(&undef_lock, flags); |
| 418 | } | 419 | } |
| 419 | 420 | ||
| 420 | static int call_undef_hook(struct pt_regs *regs, unsigned int instr) | 421 | static nokprobe_inline |
| 422 | int call_undef_hook(struct pt_regs *regs, unsigned int instr) | ||
| 421 | { | 423 | { |
| 422 | struct undef_hook *hook; | 424 | struct undef_hook *hook; |
| 423 | unsigned long flags; | 425 | unsigned long flags; |
| @@ -490,6 +492,7 @@ die_sig: | |||
| 490 | 492 | ||
| 491 | arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); | 493 | arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); |
| 492 | } | 494 | } |
| 495 | NOKPROBE_SYMBOL(do_undefinstr) | ||
| 493 | 496 | ||
| 494 | /* | 497 | /* |
| 495 | * Handle FIQ similarly to NMI on x86 systems. | 498 | * Handle FIQ similarly to NMI on x86 systems. |
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index df73914e81c8..746e7801dcdf 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S | |||
| @@ -38,6 +38,7 @@ ENTRY(__get_user_1) | |||
| 38 | mov r0, #0 | 38 | mov r0, #0 |
| 39 | ret lr | 39 | ret lr |
| 40 | ENDPROC(__get_user_1) | 40 | ENDPROC(__get_user_1) |
| 41 | _ASM_NOKPROBE(__get_user_1) | ||
| 41 | 42 | ||
| 42 | ENTRY(__get_user_2) | 43 | ENTRY(__get_user_2) |
| 43 | check_uaccess r0, 2, r1, r2, __get_user_bad | 44 | check_uaccess r0, 2, r1, r2, __get_user_bad |
| @@ -58,6 +59,7 @@ rb .req r0 | |||
| 58 | mov r0, #0 | 59 | mov r0, #0 |
| 59 | ret lr | 60 | ret lr |
| 60 | ENDPROC(__get_user_2) | 61 | ENDPROC(__get_user_2) |
| 62 | _ASM_NOKPROBE(__get_user_2) | ||
| 61 | 63 | ||
| 62 | ENTRY(__get_user_4) | 64 | ENTRY(__get_user_4) |
| 63 | check_uaccess r0, 4, r1, r2, __get_user_bad | 65 | check_uaccess r0, 4, r1, r2, __get_user_bad |
| @@ -65,6 +67,7 @@ ENTRY(__get_user_4) | |||
| 65 | mov r0, #0 | 67 | mov r0, #0 |
| 66 | ret lr | 68 | ret lr |
| 67 | ENDPROC(__get_user_4) | 69 | ENDPROC(__get_user_4) |
| 70 | _ASM_NOKPROBE(__get_user_4) | ||
| 68 | 71 | ||
| 69 | ENTRY(__get_user_8) | 72 | ENTRY(__get_user_8) |
| 70 | check_uaccess r0, 8, r1, r2, __get_user_bad8 | 73 | check_uaccess r0, 8, r1, r2, __get_user_bad8 |
| @@ -78,6 +81,7 @@ ENTRY(__get_user_8) | |||
| 78 | mov r0, #0 | 81 | mov r0, #0 |
| 79 | ret lr | 82 | ret lr |
| 80 | ENDPROC(__get_user_8) | 83 | ENDPROC(__get_user_8) |
| 84 | _ASM_NOKPROBE(__get_user_8) | ||
| 81 | 85 | ||
| 82 | #ifdef __ARMEB__ | 86 | #ifdef __ARMEB__ |
| 83 | ENTRY(__get_user_32t_8) | 87 | ENTRY(__get_user_32t_8) |
| @@ -91,6 +95,7 @@ ENTRY(__get_user_32t_8) | |||
| 91 | mov r0, #0 | 95 | mov r0, #0 |
| 92 | ret lr | 96 | ret lr |
| 93 | ENDPROC(__get_user_32t_8) | 97 | ENDPROC(__get_user_32t_8) |
| 98 | _ASM_NOKPROBE(__get_user_32t_8) | ||
| 94 | 99 | ||
| 95 | ENTRY(__get_user_64t_1) | 100 | ENTRY(__get_user_64t_1) |
| 96 | check_uaccess r0, 1, r1, r2, __get_user_bad8 | 101 | check_uaccess r0, 1, r1, r2, __get_user_bad8 |
| @@ -98,6 +103,7 @@ ENTRY(__get_user_64t_1) | |||
| 98 | mov r0, #0 | 103 | mov r0, #0 |
| 99 | ret lr | 104 | ret lr |
| 100 | ENDPROC(__get_user_64t_1) | 105 | ENDPROC(__get_user_64t_1) |
| 106 | _ASM_NOKPROBE(__get_user_64t_1) | ||
| 101 | 107 | ||
| 102 | ENTRY(__get_user_64t_2) | 108 | ENTRY(__get_user_64t_2) |
| 103 | check_uaccess r0, 2, r1, r2, __get_user_bad8 | 109 | check_uaccess r0, 2, r1, r2, __get_user_bad8 |
| @@ -114,6 +120,7 @@ rb .req r0 | |||
| 114 | mov r0, #0 | 120 | mov r0, #0 |
| 115 | ret lr | 121 | ret lr |
| 116 | ENDPROC(__get_user_64t_2) | 122 | ENDPROC(__get_user_64t_2) |
| 123 | _ASM_NOKPROBE(__get_user_64t_2) | ||
| 117 | 124 | ||
| 118 | ENTRY(__get_user_64t_4) | 125 | ENTRY(__get_user_64t_4) |
| 119 | check_uaccess r0, 4, r1, r2, __get_user_bad8 | 126 | check_uaccess r0, 4, r1, r2, __get_user_bad8 |
| @@ -121,6 +128,7 @@ ENTRY(__get_user_64t_4) | |||
| 121 | mov r0, #0 | 128 | mov r0, #0 |
| 122 | ret lr | 129 | ret lr |
| 123 | ENDPROC(__get_user_64t_4) | 130 | ENDPROC(__get_user_64t_4) |
| 131 | _ASM_NOKPROBE(__get_user_64t_4) | ||
| 124 | #endif | 132 | #endif |
| 125 | 133 | ||
| 126 | __get_user_bad8: | 134 | __get_user_bad8: |
| @@ -131,6 +139,8 @@ __get_user_bad: | |||
| 131 | ret lr | 139 | ret lr |
| 132 | ENDPROC(__get_user_bad) | 140 | ENDPROC(__get_user_bad) |
| 133 | ENDPROC(__get_user_bad8) | 141 | ENDPROC(__get_user_bad8) |
| 142 | _ASM_NOKPROBE(__get_user_bad) | ||
| 143 | _ASM_NOKPROBE(__get_user_bad8) | ||
| 134 | 144 | ||
| 135 | .pushsection __ex_table, "a" | 145 | .pushsection __ex_table, "a" |
| 136 | .long 1b, __get_user_bad | 146 | .long 1b, __get_user_bad |
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 004f9c8de032..d1e8ce7b4bd2 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c | |||
| @@ -205,12 +205,17 @@ static const short da830_evm_mmc_sd_pins[] = { | |||
| 205 | -1 | 205 | -1 |
| 206 | }; | 206 | }; |
| 207 | 207 | ||
| 208 | #define DA830_MMCSD_WP_PIN GPIO_TO_PIN(2, 1) | ||
| 209 | #define DA830_MMCSD_CD_PIN GPIO_TO_PIN(2, 2) | ||
| 210 | |||
| 208 | static struct gpiod_lookup_table mmc_gpios_table = { | 211 | static struct gpiod_lookup_table mmc_gpios_table = { |
| 209 | .dev_id = "da830-mmc.0", | 212 | .dev_id = "da830-mmc.0", |
| 210 | .table = { | 213 | .table = { |
| 211 | /* gpio chip 1 contains gpio range 32-63 */ | 214 | /* gpio chip 1 contains gpio range 32-63 */ |
| 212 | GPIO_LOOKUP("davinci_gpio.1", 2, "cd", GPIO_ACTIVE_LOW), | 215 | GPIO_LOOKUP("davinci_gpio.0", DA830_MMCSD_CD_PIN, "cd", |
| 213 | GPIO_LOOKUP("davinci_gpio.1", 1, "wp", GPIO_ACTIVE_LOW), | 216 | GPIO_ACTIVE_LOW), |
| 217 | GPIO_LOOKUP("davinci_gpio.0", DA830_MMCSD_WP_PIN, "wp", | ||
| 218 | GPIO_ACTIVE_LOW), | ||
| 214 | }, | 219 | }, |
| 215 | }; | 220 | }; |
| 216 | 221 | ||
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 3063478bcc36..158ed9a1483f 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c | |||
| @@ -763,12 +763,17 @@ static const short da850_evm_mcasp_pins[] __initconst = { | |||
| 763 | -1 | 763 | -1 |
| 764 | }; | 764 | }; |
| 765 | 765 | ||
| 766 | #define DA850_MMCSD_CD_PIN GPIO_TO_PIN(4, 0) | ||
| 767 | #define DA850_MMCSD_WP_PIN GPIO_TO_PIN(4, 1) | ||
| 768 | |||
| 766 | static struct gpiod_lookup_table mmc_gpios_table = { | 769 | static struct gpiod_lookup_table mmc_gpios_table = { |
| 767 | .dev_id = "da830-mmc.0", | 770 | .dev_id = "da830-mmc.0", |
| 768 | .table = { | 771 | .table = { |
| 769 | /* gpio chip 2 contains gpio range 64-95 */ | 772 | /* gpio chip 2 contains gpio range 64-95 */ |
| 770 | GPIO_LOOKUP("davinci_gpio.2", 0, "cd", GPIO_ACTIVE_LOW), | 773 | GPIO_LOOKUP("davinci_gpio.0", DA850_MMCSD_CD_PIN, "cd", |
| 771 | GPIO_LOOKUP("davinci_gpio.2", 1, "wp", GPIO_ACTIVE_LOW), | 774 | GPIO_ACTIVE_LOW), |
| 775 | GPIO_LOOKUP("davinci_gpio.0", DA850_MMCSD_WP_PIN, "wp", | ||
| 776 | GPIO_ACTIVE_LOW), | ||
| 772 | }, | 777 | }, |
| 773 | }; | 778 | }; |
| 774 | 779 | ||
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index cb30637d9eaf..23ab9e8bc04c 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
| 20 | #include <linux/gpio/machine.h> | 20 | #include <linux/gpio/machine.h> |
| 21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
| 22 | #include <linux/dm9000.h> | ||
| 22 | #include <linux/videodev2.h> | 23 | #include <linux/videodev2.h> |
| 23 | #include <media/i2c/tvp514x.h> | 24 | #include <media/i2c/tvp514x.h> |
| 24 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
| @@ -109,12 +110,15 @@ static struct platform_device davinci_nand_device = { | |||
| 109 | }, | 110 | }, |
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 113 | #define DM355_I2C_SDA_PIN GPIO_TO_PIN(0, 15) | ||
| 114 | #define DM355_I2C_SCL_PIN GPIO_TO_PIN(0, 14) | ||
| 115 | |||
| 112 | static struct gpiod_lookup_table i2c_recovery_gpiod_table = { | 116 | static struct gpiod_lookup_table i2c_recovery_gpiod_table = { |
| 113 | .dev_id = "i2c_davinci", | 117 | .dev_id = "i2c_davinci.1", |
| 114 | .table = { | 118 | .table = { |
| 115 | GPIO_LOOKUP("davinci_gpio", 15, "sda", | 119 | GPIO_LOOKUP("davinci_gpio.0", DM355_I2C_SDA_PIN, "sda", |
| 116 | GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), | 120 | GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), |
| 117 | GPIO_LOOKUP("davinci_gpio", 14, "scl", | 121 | GPIO_LOOKUP("davinci_gpio.0", DM355_I2C_SCL_PIN, "scl", |
| 118 | GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), | 122 | GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), |
| 119 | }, | 123 | }, |
| 120 | }; | 124 | }; |
| @@ -179,11 +183,16 @@ static struct resource dm355evm_dm9000_rsrc[] = { | |||
| 179 | }, | 183 | }, |
| 180 | }; | 184 | }; |
| 181 | 185 | ||
| 186 | static struct dm9000_plat_data dm335evm_dm9000_platdata; | ||
| 187 | |||
| 182 | static struct platform_device dm355evm_dm9000 = { | 188 | static struct platform_device dm355evm_dm9000 = { |
| 183 | .name = "dm9000", | 189 | .name = "dm9000", |
| 184 | .id = -1, | 190 | .id = -1, |
| 185 | .resource = dm355evm_dm9000_rsrc, | 191 | .resource = dm355evm_dm9000_rsrc, |
| 186 | .num_resources = ARRAY_SIZE(dm355evm_dm9000_rsrc), | 192 | .num_resources = ARRAY_SIZE(dm355evm_dm9000_rsrc), |
| 193 | .dev = { | ||
| 194 | .platform_data = &dm335evm_dm9000_platdata, | ||
| 195 | }, | ||
| 187 | }; | 196 | }; |
| 188 | 197 | ||
| 189 | static struct tvp514x_platform_data tvp5146_pdata = { | 198 | static struct tvp514x_platform_data tvp5146_pdata = { |
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 95b55aae1366..509e64ab1994 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
| 18 | #include <linux/platform_data/pcf857x.h> | 18 | #include <linux/platform_data/pcf857x.h> |
| 19 | #include <linux/platform_data/at24.h> | 19 | #include <linux/platform_data/at24.h> |
| 20 | #include <linux/platform_data/gpio-davinci.h> | ||
| 20 | #include <linux/mtd/mtd.h> | 21 | #include <linux/mtd/mtd.h> |
| 21 | #include <linux/mtd/rawnand.h> | 22 | #include <linux/mtd/rawnand.h> |
| 22 | #include <linux/mtd/partitions.h> | 23 | #include <linux/mtd/partitions.h> |
| @@ -596,12 +597,15 @@ static struct i2c_board_info __initdata i2c_info[] = { | |||
| 596 | }, | 597 | }, |
| 597 | }; | 598 | }; |
| 598 | 599 | ||
| 600 | #define DM644X_I2C_SDA_PIN GPIO_TO_PIN(2, 12) | ||
| 601 | #define DM644X_I2C_SCL_PIN GPIO_TO_PIN(2, 11) | ||
| 602 | |||
| 599 | static struct gpiod_lookup_table i2c_recovery_gpiod_table = { | 603 | static struct gpiod_lookup_table i2c_recovery_gpiod_table = { |
| 600 | .dev_id = "i2c_davinci", | 604 | .dev_id = "i2c_davinci.1", |
| 601 | .table = { | 605 | .table = { |
| 602 | GPIO_LOOKUP("davinci_gpio", 44, "sda", | 606 | GPIO_LOOKUP("davinci_gpio.0", DM644X_I2C_SDA_PIN, "sda", |
| 603 | GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), | 607 | GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), |
| 604 | GPIO_LOOKUP("davinci_gpio", 43, "scl", | 608 | GPIO_LOOKUP("davinci_gpio.0", DM644X_I2C_SCL_PIN, "scl", |
| 605 | GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), | 609 | GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), |
| 606 | }, | 610 | }, |
| 607 | }; | 611 | }; |
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 2d37f5b0e1f5..a3c0d1e87647 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c | |||
| @@ -532,11 +532,12 @@ static struct vpif_display_config dm646x_vpif_display_config = { | |||
| 532 | .set_clock = set_vpif_clock, | 532 | .set_clock = set_vpif_clock, |
| 533 | .subdevinfo = dm646x_vpif_subdev, | 533 | .subdevinfo = dm646x_vpif_subdev, |
| 534 | .subdev_count = ARRAY_SIZE(dm646x_vpif_subdev), | 534 | .subdev_count = ARRAY_SIZE(dm646x_vpif_subdev), |
| 535 | .i2c_adapter_id = 1, | ||
| 535 | .chan_config[0] = { | 536 | .chan_config[0] = { |
| 536 | .outputs = dm6467_ch0_outputs, | 537 | .outputs = dm6467_ch0_outputs, |
| 537 | .output_count = ARRAY_SIZE(dm6467_ch0_outputs), | 538 | .output_count = ARRAY_SIZE(dm6467_ch0_outputs), |
| 538 | }, | 539 | }, |
| 539 | .card_name = "DM646x EVM", | 540 | .card_name = "DM646x EVM Video Display", |
| 540 | }; | 541 | }; |
| 541 | 542 | ||
| 542 | /** | 543 | /** |
| @@ -674,6 +675,7 @@ static struct vpif_capture_config dm646x_vpif_capture_cfg = { | |||
| 674 | .setup_input_channel_mode = setup_vpif_input_channel_mode, | 675 | .setup_input_channel_mode = setup_vpif_input_channel_mode, |
| 675 | .subdev_info = vpif_capture_sdev_info, | 676 | .subdev_info = vpif_capture_sdev_info, |
| 676 | .subdev_count = ARRAY_SIZE(vpif_capture_sdev_info), | 677 | .subdev_count = ARRAY_SIZE(vpif_capture_sdev_info), |
| 678 | .i2c_adapter_id = 1, | ||
| 677 | .chan_config[0] = { | 679 | .chan_config[0] = { |
| 678 | .inputs = dm6467_ch0_inputs, | 680 | .inputs = dm6467_ch0_inputs, |
| 679 | .input_count = ARRAY_SIZE(dm6467_ch0_inputs), | 681 | .input_count = ARRAY_SIZE(dm6467_ch0_inputs), |
| @@ -694,6 +696,7 @@ static struct vpif_capture_config dm646x_vpif_capture_cfg = { | |||
| 694 | .fid_pol = 0, | 696 | .fid_pol = 0, |
| 695 | }, | 697 | }, |
| 696 | }, | 698 | }, |
| 699 | .card_name = "DM646x EVM Video Capture", | ||
| 697 | }; | 700 | }; |
| 698 | 701 | ||
| 699 | static void __init evm_init_video(void) | 702 | static void __init evm_init_video(void) |
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 0d32042b728f..be8b892a6ea7 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c | |||
| @@ -123,12 +123,16 @@ static const short hawk_mmcsd0_pins[] = { | |||
| 123 | -1 | 123 | -1 |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) | ||
| 127 | #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) | ||
| 128 | |||
| 126 | static struct gpiod_lookup_table mmc_gpios_table = { | 129 | static struct gpiod_lookup_table mmc_gpios_table = { |
| 127 | .dev_id = "da830-mmc.0", | 130 | .dev_id = "da830-mmc.0", |
| 128 | .table = { | 131 | .table = { |
| 129 | /* CD: gpio3_12: gpio60: chip 1 contains gpio range 32-63*/ | 132 | GPIO_LOOKUP("davinci_gpio.0", DA850_HAWK_MMCSD_CD_PIN, "cd", |
| 130 | GPIO_LOOKUP("davinci_gpio.0", 28, "cd", GPIO_ACTIVE_LOW), | 133 | GPIO_ACTIVE_LOW), |
| 131 | GPIO_LOOKUP("davinci_gpio.0", 29, "wp", GPIO_ACTIVE_LOW), | 134 | GPIO_LOOKUP("davinci_gpio.0", DA850_HAWK_MMCSD_WP_PIN, "wp", |
| 135 | GPIO_ACTIVE_LOW), | ||
| 132 | }, | 136 | }, |
| 133 | }; | 137 | }; |
| 134 | 138 | ||
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 109ab1fa0d2c..c32ca27ab343 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c | |||
| @@ -488,7 +488,8 @@ static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = { | |||
| 488 | [IRQ_DM646X_MCASP0TXINT] = 7, | 488 | [IRQ_DM646X_MCASP0TXINT] = 7, |
| 489 | [IRQ_DM646X_MCASP0RXINT] = 7, | 489 | [IRQ_DM646X_MCASP0RXINT] = 7, |
| 490 | [IRQ_DM646X_RESERVED_3] = 7, | 490 | [IRQ_DM646X_RESERVED_3] = 7, |
| 491 | [IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */ | 491 | [IRQ_DM646X_MCASP1TXINT] = 7, |
| 492 | [IRQ_TINT0_TINT12] = 7, /* clockevent */ | ||
| 492 | [IRQ_TINT0_TINT34] = 7, /* clocksource */ | 493 | [IRQ_TINT0_TINT34] = 7, /* clocksource */ |
| 493 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ | 494 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ |
| 494 | [IRQ_TINT1_TINT34] = 7, /* system tick */ | 495 | [IRQ_TINT1_TINT34] = 7, /* system tick */ |
diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c index fe57e2692629..abca83d22ff3 100644 --- a/arch/arm/mach-keystone/pm_domain.c +++ b/arch/arm/mach-keystone/pm_domain.c | |||
| @@ -29,6 +29,7 @@ static struct dev_pm_domain keystone_pm_domain = { | |||
| 29 | 29 | ||
| 30 | static struct pm_clk_notifier_block platform_domain_notifier = { | 30 | static struct pm_clk_notifier_block platform_domain_notifier = { |
| 31 | .pm_domain = &keystone_pm_domain, | 31 | .pm_domain = &keystone_pm_domain, |
| 32 | .con_ids = { NULL }, | ||
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | static const struct of_device_id of_keystone_table[] = { | 35 | static const struct of_device_id of_keystone_table[] = { |
diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c index 793a24a53c52..d7ca9e2b40d2 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq.c +++ b/arch/arm/mach-omap1/ams-delta-fiq.c | |||
| @@ -58,22 +58,24 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id) | |||
| 58 | irq_num = gpio_to_irq(gpio); | 58 | irq_num = gpio_to_irq(gpio); |
| 59 | fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio]; | 59 | fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio]; |
| 60 | 60 | ||
| 61 | while (irq_counter[gpio] < fiq_count) { | 61 | if (irq_counter[gpio] < fiq_count && |
| 62 | if (gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) { | 62 | gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) { |
| 63 | struct irq_data *d = irq_get_irq_data(irq_num); | 63 | struct irq_data *d = irq_get_irq_data(irq_num); |
| 64 | 64 | ||
| 65 | /* | 65 | /* |
| 66 | * It looks like handle_edge_irq() that | 66 | * handle_simple_irq() that OMAP GPIO edge |
| 67 | * OMAP GPIO edge interrupts default to, | 67 | * interrupts default to since commit 80ac93c27441 |
| 68 | * expects interrupt already unmasked. | 68 | * requires interrupt already acked and unmasked. |
| 69 | */ | 69 | */ |
| 70 | if (irq_chip && irq_chip->irq_unmask) | 70 | if (irq_chip) { |
| 71 | if (irq_chip->irq_ack) | ||
| 72 | irq_chip->irq_ack(d); | ||
| 73 | if (irq_chip->irq_unmask) | ||
| 71 | irq_chip->irq_unmask(d); | 74 | irq_chip->irq_unmask(d); |
| 72 | } | 75 | } |
| 73 | generic_handle_irq(irq_num); | ||
| 74 | |||
| 75 | irq_counter[gpio]++; | ||
| 76 | } | 76 | } |
| 77 | for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++) | ||
| 78 | generic_handle_irq(irq_num); | ||
| 77 | } | 79 | } |
| 78 | return IRQ_HANDLED; | 80 | return IRQ_HANDLED; |
| 79 | } | 81 | } |
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 76eb6ec5f157..1e6a967cd2d5 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
| @@ -188,7 +188,7 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) | |||
| 188 | ((prev & OMAP_POWERSTATE_MASK) << 0)); | 188 | ((prev & OMAP_POWERSTATE_MASK) << 0)); |
| 189 | trace_power_domain_target_rcuidle(pwrdm->name, | 189 | trace_power_domain_target_rcuidle(pwrdm->name, |
| 190 | trace_state, | 190 | trace_state, |
| 191 | smp_processor_id()); | 191 | raw_smp_processor_id()); |
| 192 | } | 192 | } |
| 193 | break; | 193 | break; |
| 194 | default: | 194 | default: |
| @@ -518,7 +518,7 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) | |||
| 518 | if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) { | 518 | if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) { |
| 519 | /* Trace the pwrdm desired target state */ | 519 | /* Trace the pwrdm desired target state */ |
| 520 | trace_power_domain_target_rcuidle(pwrdm->name, pwrst, | 520 | trace_power_domain_target_rcuidle(pwrdm->name, pwrst, |
| 521 | smp_processor_id()); | 521 | raw_smp_processor_id()); |
| 522 | /* Program the pwrdm desired target state */ | 522 | /* Program the pwrdm desired target state */ |
| 523 | ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst); | 523 | ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst); |
| 524 | } | 524 | } |
diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c index bcdecc25461b..b2aa9b32bff2 100644 --- a/arch/arm/probes/kprobes/opt-arm.c +++ b/arch/arm/probes/kprobes/opt-arm.c | |||
| @@ -165,13 +165,14 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) | |||
| 165 | { | 165 | { |
| 166 | unsigned long flags; | 166 | unsigned long flags; |
| 167 | struct kprobe *p = &op->kp; | 167 | struct kprobe *p = &op->kp; |
| 168 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 168 | struct kprobe_ctlblk *kcb; |
| 169 | 169 | ||
| 170 | /* Save skipped registers */ | 170 | /* Save skipped registers */ |
| 171 | regs->ARM_pc = (unsigned long)op->kp.addr; | 171 | regs->ARM_pc = (unsigned long)op->kp.addr; |
| 172 | regs->ARM_ORIG_r0 = ~0UL; | 172 | regs->ARM_ORIG_r0 = ~0UL; |
| 173 | 173 | ||
| 174 | local_irq_save(flags); | 174 | local_irq_save(flags); |
| 175 | kcb = get_kprobe_ctlblk(); | ||
| 175 | 176 | ||
| 176 | if (kprobe_running()) { | 177 | if (kprobe_running()) { |
| 177 | kprobes_inc_nmissed_count(&op->kp); | 178 | kprobes_inc_nmissed_count(&op->kp); |
| @@ -191,6 +192,7 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) | |||
| 191 | 192 | ||
| 192 | local_irq_restore(flags); | 193 | local_irq_restore(flags); |
| 193 | } | 194 | } |
| 195 | NOKPROBE_SYMBOL(optimized_callback) | ||
| 194 | 196 | ||
| 195 | int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig) | 197 | int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig) |
| 196 | { | 198 | { |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 4c375e11ae95..af4ee2cef2f9 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
| @@ -257,7 +257,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ | |||
| 257 | 257 | ||
| 258 | if (exceptions == VFP_EXCEPTION_ERROR) { | 258 | if (exceptions == VFP_EXCEPTION_ERROR) { |
| 259 | vfp_panic("unhandled bounce", inst); | 259 | vfp_panic("unhandled bounce", inst); |
| 260 | vfp_raise_sigfpe(FPE_FIXME, regs); | 260 | vfp_raise_sigfpe(FPE_FLTINV, regs); |
| 261 | return; | 261 | return; |
| 262 | } | 262 | } |
| 263 | 263 | ||
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index c0231d077fa6..1ad8677f6a0a 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi | |||
| @@ -1317,7 +1317,7 @@ | |||
| 1317 | reg = <0x14d60000 0x100>; | 1317 | reg = <0x14d60000 0x100>; |
| 1318 | dmas = <&pdma0 31 &pdma0 30>; | 1318 | dmas = <&pdma0 31 &pdma0 30>; |
| 1319 | dma-names = "tx", "rx"; | 1319 | dma-names = "tx", "rx"; |
| 1320 | interrupts = <GIC_SPI 435 IRQ_TYPE_NONE>; | 1320 | interrupts = <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>; |
| 1321 | clocks = <&cmu_peric CLK_PCLK_I2S1>, | 1321 | clocks = <&cmu_peric CLK_PCLK_I2S1>, |
| 1322 | <&cmu_peric CLK_PCLK_I2S1>, | 1322 | <&cmu_peric CLK_PCLK_I2S1>, |
| 1323 | <&cmu_peric CLK_SCLK_I2S1>; | 1323 | <&cmu_peric CLK_SCLK_I2S1>; |
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi index 48cad7919efa..ed2f1237ea1e 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi | |||
| @@ -38,9 +38,10 @@ | |||
| 38 | compatible = "marvell,armada-7k-pp22"; | 38 | compatible = "marvell,armada-7k-pp22"; |
| 39 | reg = <0x0 0x100000>, <0x129000 0xb000>; | 39 | reg = <0x0 0x100000>, <0x129000 0xb000>; |
| 40 | clocks = <&CP110_LABEL(clk) 1 3>, <&CP110_LABEL(clk) 1 9>, | 40 | clocks = <&CP110_LABEL(clk) 1 3>, <&CP110_LABEL(clk) 1 9>, |
| 41 | <&CP110_LABEL(clk) 1 5>, <&CP110_LABEL(clk) 1 18>; | 41 | <&CP110_LABEL(clk) 1 5>, <&CP110_LABEL(clk) 1 6>, |
| 42 | <&CP110_LABEL(clk) 1 18>; | ||
| 42 | clock-names = "pp_clk", "gop_clk", | 43 | clock-names = "pp_clk", "gop_clk", |
| 43 | "mg_clk", "axi_clk"; | 44 | "mg_clk", "mg_core_clk", "axi_clk"; |
| 44 | marvell,system-controller = <&CP110_LABEL(syscon0)>; | 45 | marvell,system-controller = <&CP110_LABEL(syscon0)>; |
| 45 | status = "disabled"; | 46 | status = "disabled"; |
| 46 | dma-coherent; | 47 | dma-coherent; |
| @@ -141,6 +142,8 @@ | |||
| 141 | #size-cells = <0>; | 142 | #size-cells = <0>; |
| 142 | compatible = "marvell,xmdio"; | 143 | compatible = "marvell,xmdio"; |
| 143 | reg = <0x12a600 0x10>; | 144 | reg = <0x12a600 0x10>; |
| 145 | clocks = <&CP110_LABEL(clk) 1 5>, | ||
| 146 | <&CP110_LABEL(clk) 1 6>, <&CP110_LABEL(clk) 1 18>; | ||
| 144 | status = "disabled"; | 147 | status = "disabled"; |
| 145 | }; | 148 | }; |
| 146 | 149 | ||
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi index a8baad7b80df..13f57fff1477 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi | |||
| @@ -46,7 +46,7 @@ | |||
| 46 | compatible = "ethernet-phy-ieee802.3-c22"; | 46 | compatible = "ethernet-phy-ieee802.3-c22"; |
| 47 | reg = <0x0>; | 47 | reg = <0x0>; |
| 48 | interrupt-parent = <&gpio>; | 48 | interrupt-parent = <&gpio>; |
| 49 | interrupts = <TEGRA_MAIN_GPIO(M, 5) IRQ_TYPE_LEVEL_HIGH>; | 49 | interrupts = <TEGRA_MAIN_GPIO(M, 5) IRQ_TYPE_LEVEL_LOW>; |
| 50 | }; | 50 | }; |
| 51 | }; | 51 | }; |
| 52 | }; | 52 | }; |
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi index e62bda1cf2d9..c32dd3419c87 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi | |||
| @@ -414,7 +414,7 @@ | |||
| 414 | mmc-ddr-1_8v; | 414 | mmc-ddr-1_8v; |
| 415 | mmc-hs200-1_8v; | 415 | mmc-hs200-1_8v; |
| 416 | mmc-pwrseq = <&emmc_pwrseq>; | 416 | mmc-pwrseq = <&emmc_pwrseq>; |
| 417 | cdns,phy-input-delay-legacy = <4>; | 417 | cdns,phy-input-delay-legacy = <9>; |
| 418 | cdns,phy-input-delay-mmc-highspeed = <2>; | 418 | cdns,phy-input-delay-mmc-highspeed = <2>; |
| 419 | cdns,phy-input-delay-mmc-ddr = <3>; | 419 | cdns,phy-input-delay-mmc-ddr = <3>; |
| 420 | cdns,phy-dll-delay-sdclk = <21>; | 420 | cdns,phy-dll-delay-sdclk = <21>; |
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts index 2c1a92fafbfb..440c2e6a638b 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts | |||
| @@ -67,3 +67,11 @@ | |||
| 67 | reg = <0>; | 67 | reg = <0>; |
| 68 | }; | 68 | }; |
| 69 | }; | 69 | }; |
| 70 | |||
| 71 | &pinctrl_ether_rgmii { | ||
| 72 | tx { | ||
| 73 | pins = "RGMII_TXCLK", "RGMII_TXD0", "RGMII_TXD1", | ||
| 74 | "RGMII_TXD2", "RGMII_TXD3", "RGMII_TXCTL"; | ||
| 75 | drive-strength = <9>; | ||
| 76 | }; | ||
| 77 | }; | ||
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi index 9efe20d07589..3a5ed789c056 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi | |||
| @@ -519,7 +519,7 @@ | |||
| 519 | mmc-ddr-1_8v; | 519 | mmc-ddr-1_8v; |
| 520 | mmc-hs200-1_8v; | 520 | mmc-hs200-1_8v; |
| 521 | mmc-pwrseq = <&emmc_pwrseq>; | 521 | mmc-pwrseq = <&emmc_pwrseq>; |
| 522 | cdns,phy-input-delay-legacy = <4>; | 522 | cdns,phy-input-delay-legacy = <9>; |
| 523 | cdns,phy-input-delay-mmc-highspeed = <2>; | 523 | cdns,phy-input-delay-mmc-highspeed = <2>; |
| 524 | cdns,phy-input-delay-mmc-ddr = <3>; | 524 | cdns,phy-input-delay-mmc-ddr = <3>; |
| 525 | cdns,phy-dll-delay-sdclk = <21>; | 525 | cdns,phy-dll-delay-sdclk = <21>; |
diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi index 7c8f710d9bfa..e85d6ddea3c2 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi | |||
| @@ -334,7 +334,7 @@ | |||
| 334 | mmc-ddr-1_8v; | 334 | mmc-ddr-1_8v; |
| 335 | mmc-hs200-1_8v; | 335 | mmc-hs200-1_8v; |
| 336 | mmc-pwrseq = <&emmc_pwrseq>; | 336 | mmc-pwrseq = <&emmc_pwrseq>; |
| 337 | cdns,phy-input-delay-legacy = <4>; | 337 | cdns,phy-input-delay-legacy = <9>; |
| 338 | cdns,phy-input-delay-mmc-highspeed = <2>; | 338 | cdns,phy-input-delay-mmc-highspeed = <2>; |
| 339 | cdns,phy-input-delay-mmc-ddr = <3>; | 339 | cdns,phy-input-delay-mmc-ddr = <3>; |
| 340 | cdns,phy-dll-delay-sdclk = <21>; | 340 | cdns,phy-dll-delay-sdclk = <21>; |
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 30014a9f8f2b..ea690b3562af 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h | |||
| @@ -75,6 +75,7 @@ | |||
| 75 | #define ARM_CPU_IMP_CAVIUM 0x43 | 75 | #define ARM_CPU_IMP_CAVIUM 0x43 |
| 76 | #define ARM_CPU_IMP_BRCM 0x42 | 76 | #define ARM_CPU_IMP_BRCM 0x42 |
| 77 | #define ARM_CPU_IMP_QCOM 0x51 | 77 | #define ARM_CPU_IMP_QCOM 0x51 |
| 78 | #define ARM_CPU_IMP_NVIDIA 0x4E | ||
| 78 | 79 | ||
| 79 | #define ARM_CPU_PART_AEM_V8 0xD0F | 80 | #define ARM_CPU_PART_AEM_V8 0xD0F |
| 80 | #define ARM_CPU_PART_FOUNDATION 0xD00 | 81 | #define ARM_CPU_PART_FOUNDATION 0xD00 |
| @@ -99,6 +100,9 @@ | |||
| 99 | #define QCOM_CPU_PART_FALKOR 0xC00 | 100 | #define QCOM_CPU_PART_FALKOR 0xC00 |
| 100 | #define QCOM_CPU_PART_KRYO 0x200 | 101 | #define QCOM_CPU_PART_KRYO 0x200 |
| 101 | 102 | ||
| 103 | #define NVIDIA_CPU_PART_DENVER 0x003 | ||
| 104 | #define NVIDIA_CPU_PART_CARMEL 0x004 | ||
| 105 | |||
| 102 | #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) | 106 | #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) |
| 103 | #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) | 107 | #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) |
| 104 | #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) | 108 | #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) |
| @@ -114,6 +118,8 @@ | |||
| 114 | #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) | 118 | #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) |
| 115 | #define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR) | 119 | #define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR) |
| 116 | #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO) | 120 | #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO) |
| 121 | #define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER) | ||
| 122 | #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) | ||
| 117 | 123 | ||
| 118 | #ifndef __ASSEMBLY__ | 124 | #ifndef __ASSEMBLY__ |
| 119 | 125 | ||
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 23b33e8ea03a..1dab3a984608 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h | |||
| @@ -333,7 +333,7 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu) | |||
| 333 | } else { | 333 | } else { |
| 334 | u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1); | 334 | u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1); |
| 335 | sctlr |= (1 << 25); | 335 | sctlr |= (1 << 25); |
| 336 | vcpu_write_sys_reg(vcpu, SCTLR_EL1, sctlr); | 336 | vcpu_write_sys_reg(vcpu, sctlr, SCTLR_EL1); |
| 337 | } | 337 | } |
| 338 | } | 338 | } |
| 339 | 339 | ||
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 082110993647..6128992c2ded 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h | |||
| @@ -360,6 +360,22 @@ static inline unsigned int kvm_get_vmid_bits(void) | |||
| 360 | return (cpuid_feature_extract_unsigned_field(reg, ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8; | 360 | return (cpuid_feature_extract_unsigned_field(reg, ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8; |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | /* | ||
| 364 | * We are not in the kvm->srcu critical section most of the time, so we take | ||
| 365 | * the SRCU read lock here. Since we copy the data from the user page, we | ||
| 366 | * can immediately drop the lock again. | ||
| 367 | */ | ||
| 368 | static inline int kvm_read_guest_lock(struct kvm *kvm, | ||
| 369 | gpa_t gpa, void *data, unsigned long len) | ||
| 370 | { | ||
| 371 | int srcu_idx = srcu_read_lock(&kvm->srcu); | ||
| 372 | int ret = kvm_read_guest(kvm, gpa, data, len); | ||
| 373 | |||
| 374 | srcu_read_unlock(&kvm->srcu, srcu_idx); | ||
| 375 | |||
| 376 | return ret; | ||
| 377 | } | ||
| 378 | |||
| 363 | #ifdef CONFIG_KVM_INDIRECT_VECTORS | 379 | #ifdef CONFIG_KVM_INDIRECT_VECTORS |
| 364 | /* | 380 | /* |
| 365 | * EL2 vectors can be mapped and rerouted in a number of ways, | 381 | * EL2 vectors can be mapped and rerouted in a number of ways, |
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index a900befadfe8..e4a1182deff7 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c | |||
| @@ -316,6 +316,7 @@ static const struct midr_range arm64_bp_harden_smccc_cpus[] = { | |||
| 316 | MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), | 316 | MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), |
| 317 | MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1), | 317 | MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1), |
| 318 | MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), | 318 | MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), |
| 319 | MIDR_ALL_VERSIONS(MIDR_NVIDIA_DENVER), | ||
| 319 | {}, | 320 | {}, |
| 320 | }; | 321 | }; |
| 321 | 322 | ||
diff --git a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c index 86801b6055d6..39be799d0417 100644 --- a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c +++ b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c | |||
| @@ -18,11 +18,20 @@ | |||
| 18 | #include <linux/compiler.h> | 18 | #include <linux/compiler.h> |
| 19 | #include <linux/irqchip/arm-gic.h> | 19 | #include <linux/irqchip/arm-gic.h> |
| 20 | #include <linux/kvm_host.h> | 20 | #include <linux/kvm_host.h> |
| 21 | #include <linux/swab.h> | ||
| 21 | 22 | ||
| 22 | #include <asm/kvm_emulate.h> | 23 | #include <asm/kvm_emulate.h> |
| 23 | #include <asm/kvm_hyp.h> | 24 | #include <asm/kvm_hyp.h> |
| 24 | #include <asm/kvm_mmu.h> | 25 | #include <asm/kvm_mmu.h> |
| 25 | 26 | ||
| 27 | static bool __hyp_text __is_be(struct kvm_vcpu *vcpu) | ||
| 28 | { | ||
| 29 | if (vcpu_mode_is_32bit(vcpu)) | ||
| 30 | return !!(read_sysreg_el2(spsr) & COMPAT_PSR_E_BIT); | ||
| 31 | |||
| 32 | return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE); | ||
| 33 | } | ||
| 34 | |||
| 26 | /* | 35 | /* |
| 27 | * __vgic_v2_perform_cpuif_access -- perform a GICV access on behalf of the | 36 | * __vgic_v2_perform_cpuif_access -- perform a GICV access on behalf of the |
| 28 | * guest. | 37 | * guest. |
| @@ -64,14 +73,19 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) | |||
| 64 | addr += fault_ipa - vgic->vgic_cpu_base; | 73 | addr += fault_ipa - vgic->vgic_cpu_base; |
| 65 | 74 | ||
| 66 | if (kvm_vcpu_dabt_iswrite(vcpu)) { | 75 | if (kvm_vcpu_dabt_iswrite(vcpu)) { |
| 67 | u32 data = vcpu_data_guest_to_host(vcpu, | 76 | u32 data = vcpu_get_reg(vcpu, rd); |
| 68 | vcpu_get_reg(vcpu, rd), | 77 | if (__is_be(vcpu)) { |
| 69 | sizeof(u32)); | 78 | /* guest pre-swabbed data, undo this for writel() */ |
| 79 | data = swab32(data); | ||
| 80 | } | ||
| 70 | writel_relaxed(data, addr); | 81 | writel_relaxed(data, addr); |
| 71 | } else { | 82 | } else { |
| 72 | u32 data = readl_relaxed(addr); | 83 | u32 data = readl_relaxed(addr); |
| 73 | vcpu_set_reg(vcpu, rd, vcpu_data_host_to_guest(vcpu, data, | 84 | if (__is_be(vcpu)) { |
| 74 | sizeof(u32))); | 85 | /* guest expects swabbed data */ |
| 86 | data = swab32(data); | ||
| 87 | } | ||
| 88 | vcpu_set_reg(vcpu, rd, data); | ||
| 75 | } | 89 | } |
| 76 | 90 | ||
| 77 | return 1; | 91 | return 1; |
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 9f3c47acf8ff..1b18b4722420 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
| @@ -646,8 +646,10 @@ static int keep_initrd __initdata; | |||
| 646 | 646 | ||
| 647 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 647 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
| 648 | { | 648 | { |
| 649 | if (!keep_initrd) | 649 | if (!keep_initrd) { |
| 650 | free_reserved_area((void *)start, (void *)end, 0, "initrd"); | 650 | free_reserved_area((void *)start, (void *)end, 0, "initrd"); |
| 651 | memblock_free(__virt_to_phys(start), end - start); | ||
| 652 | } | ||
| 651 | } | 653 | } |
| 652 | 654 | ||
| 653 | static int __init keepinitrd_setup(char *__unused) | 655 | static int __init keepinitrd_setup(char *__unused) |
diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h index 9e8621d94ee9..e17262ad125e 100644 --- a/arch/hexagon/include/asm/io.h +++ b/arch/hexagon/include/asm/io.h | |||
| @@ -216,6 +216,12 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, | |||
| 216 | memcpy((void *) dst, src, count); | 216 | memcpy((void *) dst, src, count); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | static inline void memset_io(volatile void __iomem *addr, int value, | ||
| 220 | size_t size) | ||
| 221 | { | ||
| 222 | memset((void __force *)addr, value, size); | ||
| 223 | } | ||
| 224 | |||
| 219 | #define PCI_IO_ADDR (volatile void __iomem *) | 225 | #define PCI_IO_ADDR (volatile void __iomem *) |
| 220 | 226 | ||
| 221 | /* | 227 | /* |
diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c index 617506d1a559..7cd0a2259269 100644 --- a/arch/hexagon/lib/checksum.c +++ b/arch/hexagon/lib/checksum.c | |||
| @@ -199,3 +199,4 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) | |||
| 199 | memcpy(dst, src, len); | 199 | memcpy(dst, src, len); |
| 200 | return csum_partial(dst, len, sum); | 200 | return csum_partial(dst, len, sum); |
| 201 | } | 201 | } |
| 202 | EXPORT_SYMBOL(csum_partial_copy_nocheck); | ||
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index e2364ff59180..34ac503e28ad 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile | |||
| @@ -123,6 +123,9 @@ INSTALL_TARGETS = zinstall install | |||
| 123 | 123 | ||
| 124 | PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS) | 124 | PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS) |
| 125 | 125 | ||
| 126 | # Default kernel to build | ||
| 127 | all: bzImage | ||
| 128 | |||
| 126 | zImage: vmlinuz | 129 | zImage: vmlinuz |
| 127 | Image: vmlinux | 130 | Image: vmlinux |
| 128 | 131 | ||
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 3b8507f71050..e0e1c9775c32 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c | |||
| @@ -268,7 +268,7 @@ static struct parisc_device *find_device_by_addr(unsigned long hpa) | |||
| 268 | * Walks up the device tree looking for a device of the specified type. | 268 | * Walks up the device tree looking for a device of the specified type. |
| 269 | * If it finds it, it returns it. If not, it returns NULL. | 269 | * If it finds it, it returns it. If not, it returns NULL. |
| 270 | */ | 270 | */ |
| 271 | const struct parisc_device * __init | 271 | const struct parisc_device * |
| 272 | find_pa_parent_type(const struct parisc_device *padev, int type) | 272 | find_pa_parent_type(const struct parisc_device *padev, int type) |
| 273 | { | 273 | { |
| 274 | const struct device *dev = &padev->dev; | 274 | const struct device *dev = &padev->dev; |
| @@ -448,7 +448,8 @@ static int match_by_id(struct device * dev, void * data) | |||
| 448 | * Checks all the children of @parent for a matching @id. If none | 448 | * Checks all the children of @parent for a matching @id. If none |
| 449 | * found, it allocates a new device and returns it. | 449 | * found, it allocates a new device and returns it. |
| 450 | */ | 450 | */ |
| 451 | static struct parisc_device * alloc_tree_node(struct device *parent, char id) | 451 | static struct parisc_device * __init alloc_tree_node( |
| 452 | struct device *parent, char id) | ||
| 452 | { | 453 | { |
| 453 | struct match_id_data d = { | 454 | struct match_id_data d = { |
| 454 | .id = id, | 455 | .id = id, |
| @@ -825,8 +826,8 @@ static void walk_lower_bus(struct parisc_device *dev) | |||
| 825 | * devices which are not physically connected (such as extra serial & | 826 | * devices which are not physically connected (such as extra serial & |
| 826 | * keyboard ports). This problem is not yet solved. | 827 | * keyboard ports). This problem is not yet solved. |
| 827 | */ | 828 | */ |
| 828 | static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, | 829 | static void __init walk_native_bus(unsigned long io_io_low, |
| 829 | struct device *parent) | 830 | unsigned long io_io_high, struct device *parent) |
| 830 | { | 831 | { |
| 831 | int i, devices_found = 0; | 832 | int i, devices_found = 0; |
| 832 | unsigned long hpa = io_io_low; | 833 | unsigned long hpa = io_io_low; |
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 13ee3569959a..ae684ac6efb6 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c | |||
| @@ -174,7 +174,7 @@ void pcibios_set_master(struct pci_dev *dev) | |||
| 174 | * pcibios_init_bridge() initializes cache line and default latency | 174 | * pcibios_init_bridge() initializes cache line and default latency |
| 175 | * for pci controllers and pci-pci bridges | 175 | * for pci controllers and pci-pci bridges |
| 176 | */ | 176 | */ |
| 177 | void __init pcibios_init_bridge(struct pci_dev *dev) | 177 | void __ref pcibios_init_bridge(struct pci_dev *dev) |
| 178 | { | 178 | { |
| 179 | unsigned short bridge_ctl, bridge_ctl_new; | 179 | unsigned short bridge_ctl, bridge_ctl_new; |
| 180 | 180 | ||
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 4065b5e48c9d..5e26dbede5fc 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c | |||
| @@ -423,8 +423,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | #ifdef CONFIG_PROC_FS | 425 | #ifdef CONFIG_PROC_FS |
| 426 | int __init | 426 | int setup_profiling_timer(unsigned int multiplier) |
| 427 | setup_profiling_timer(unsigned int multiplier) | ||
| 428 | { | 427 | { |
| 429 | return -EINVAL; | 428 | return -EINVAL; |
| 430 | } | 429 | } |
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index c3830400ca28..a1e772f909cb 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c | |||
| @@ -205,7 +205,7 @@ static int __init rtc_init(void) | |||
| 205 | device_initcall(rtc_init); | 205 | device_initcall(rtc_init); |
| 206 | #endif | 206 | #endif |
| 207 | 207 | ||
| 208 | void read_persistent_clock(struct timespec *ts) | 208 | void read_persistent_clock64(struct timespec64 *ts) |
| 209 | { | 209 | { |
| 210 | static struct pdc_tod tod_data; | 210 | static struct pdc_tod tod_data; |
| 211 | if (pdc_tod_read(&tod_data) == 0) { | 211 | if (pdc_tod_read(&tod_data) == 0) { |
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 68e671a11987..71d31274d782 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
| @@ -837,6 +837,17 @@ void __init initialize_ivt(const void *iva) | |||
| 837 | if (pdc_instr(&instr) == PDC_OK) | 837 | if (pdc_instr(&instr) == PDC_OK) |
| 838 | ivap[0] = instr; | 838 | ivap[0] = instr; |
| 839 | 839 | ||
| 840 | /* | ||
| 841 | * Rules for the checksum of the HPMC handler: | ||
| 842 | * 1. The IVA does not point to PDC/PDH space (ie: the OS has installed | ||
| 843 | * its own IVA). | ||
| 844 | * 2. The word at IVA + 32 is nonzero. | ||
| 845 | * 3. If Length (IVA + 60) is not zero, then Length (IVA + 60) and | ||
| 846 | * Address (IVA + 56) are word-aligned. | ||
| 847 | * 4. The checksum of the 8 words starting at IVA + 32 plus the sum of | ||
| 848 | * the Length/4 words starting at Address is zero. | ||
| 849 | */ | ||
| 850 | |||
| 840 | /* Compute Checksum for HPMC handler */ | 851 | /* Compute Checksum for HPMC handler */ |
| 841 | length = os_hpmc_size; | 852 | length = os_hpmc_size; |
| 842 | ivap[7] = length; | 853 | ivap[7] = length; |
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index cab32ee824d2..2607d2d33405 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c | |||
| @@ -516,7 +516,7 @@ static void __init map_pages(unsigned long start_vaddr, | |||
| 516 | } | 516 | } |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | void free_initmem(void) | 519 | void __ref free_initmem(void) |
| 520 | { | 520 | { |
| 521 | unsigned long init_begin = (unsigned long)__init_begin; | 521 | unsigned long init_begin = (unsigned long)__init_begin; |
| 522 | unsigned long init_end = (unsigned long)__init_end; | 522 | unsigned long init_end = (unsigned long)__init_end; |
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index 9abddde372ab..b2dabd06659d 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h | |||
| @@ -69,17 +69,30 @@ struct dyn_arch_ftrace { | |||
| 69 | #endif | 69 | #endif |
| 70 | 70 | ||
| 71 | #if defined(CONFIG_FTRACE_SYSCALLS) && !defined(__ASSEMBLY__) | 71 | #if defined(CONFIG_FTRACE_SYSCALLS) && !defined(__ASSEMBLY__) |
| 72 | #ifdef PPC64_ELF_ABI_v1 | 72 | /* |
| 73 | * Some syscall entry functions on powerpc start with "ppc_" (fork and clone, | ||
| 74 | * for instance) or ppc32_/ppc64_. We should also match the sys_ variant with | ||
| 75 | * those. | ||
| 76 | */ | ||
| 73 | #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME | 77 | #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME |
| 78 | #ifdef PPC64_ELF_ABI_v1 | ||
| 79 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) | ||
| 80 | { | ||
| 81 | /* We need to skip past the initial dot, and the __se_sys alias */ | ||
| 82 | return !strcmp(sym + 1, name) || | ||
| 83 | (!strncmp(sym, ".__se_sys", 9) && !strcmp(sym + 6, name)) || | ||
| 84 | (!strncmp(sym, ".ppc_", 5) && !strcmp(sym + 5, name + 4)) || | ||
| 85 | (!strncmp(sym, ".ppc32_", 7) && !strcmp(sym + 7, name + 4)) || | ||
| 86 | (!strncmp(sym, ".ppc64_", 7) && !strcmp(sym + 7, name + 4)); | ||
| 87 | } | ||
| 88 | #else | ||
| 74 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) | 89 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) |
| 75 | { | 90 | { |
| 76 | /* | 91 | return !strcmp(sym, name) || |
| 77 | * Compare the symbol name with the system call name. Skip the .sys or .SyS | 92 | (!strncmp(sym, "__se_sys", 8) && !strcmp(sym + 5, name)) || |
| 78 | * prefix from the symbol name and the sys prefix from the system call name and | 93 | (!strncmp(sym, "ppc_", 4) && !strcmp(sym + 4, name + 4)) || |
| 79 | * just match the rest. This is only needed on ppc64 since symbol names on | 94 | (!strncmp(sym, "ppc32_", 6) && !strcmp(sym + 6, name + 4)) || |
| 80 | * 32bit do not start with a period so the generic function will work. | 95 | (!strncmp(sym, "ppc64_", 6) && !strcmp(sym + 6, name + 4)); |
| 81 | */ | ||
| 82 | return !strcmp(sym + 4, name + 3); | ||
| 83 | } | 96 | } |
| 84 | #endif | 97 | #endif |
| 85 | #endif /* CONFIG_FTRACE_SYSCALLS && !__ASSEMBLY__ */ | 98 | #endif /* CONFIG_FTRACE_SYSCALLS && !__ASSEMBLY__ */ |
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 4185f1c96125..3f109a3e3edb 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h | |||
| @@ -165,7 +165,6 @@ struct paca_struct { | |||
| 165 | u64 saved_msr; /* MSR saved here by enter_rtas */ | 165 | u64 saved_msr; /* MSR saved here by enter_rtas */ |
| 166 | u16 trap_save; /* Used when bad stack is encountered */ | 166 | u16 trap_save; /* Used when bad stack is encountered */ |
| 167 | u8 irq_soft_mask; /* mask for irq soft masking */ | 167 | u8 irq_soft_mask; /* mask for irq soft masking */ |
| 168 | u8 soft_enabled; /* irq soft-enable flag */ | ||
| 169 | u8 irq_happened; /* irq happened while soft-disabled */ | 168 | u8 irq_happened; /* irq happened while soft-disabled */ |
| 170 | u8 io_sync; /* writel() needs spin_unlock sync */ | 169 | u8 io_sync; /* writel() needs spin_unlock sync */ |
| 171 | u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ | 170 | u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ |
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 9f421641a35c..16b077801a5f 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
| @@ -91,6 +91,7 @@ extern int start_topology_update(void); | |||
| 91 | extern int stop_topology_update(void); | 91 | extern int stop_topology_update(void); |
| 92 | extern int prrn_is_enabled(void); | 92 | extern int prrn_is_enabled(void); |
| 93 | extern int find_and_online_cpu_nid(int cpu); | 93 | extern int find_and_online_cpu_nid(int cpu); |
| 94 | extern int timed_topology_update(int nsecs); | ||
| 94 | #else | 95 | #else |
| 95 | static inline int start_topology_update(void) | 96 | static inline int start_topology_update(void) |
| 96 | { | 97 | { |
| @@ -108,16 +109,12 @@ static inline int find_and_online_cpu_nid(int cpu) | |||
| 108 | { | 109 | { |
| 109 | return 0; | 110 | return 0; |
| 110 | } | 111 | } |
| 112 | static inline int timed_topology_update(int nsecs) | ||
| 113 | { | ||
| 114 | return 0; | ||
| 115 | } | ||
| 111 | #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ | 116 | #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ |
| 112 | 117 | ||
| 113 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_NEED_MULTIPLE_NODES) | ||
| 114 | #if defined(CONFIG_PPC_SPLPAR) | ||
| 115 | extern int timed_topology_update(int nsecs); | ||
| 116 | #else | ||
| 117 | #define timed_topology_update(nsecs) | ||
| 118 | #endif /* CONFIG_PPC_SPLPAR */ | ||
| 119 | #endif /* CONFIG_HOTPLUG_CPU || CONFIG_NEED_MULTIPLE_NODES */ | ||
| 120 | |||
| 121 | #include <asm-generic/topology.h> | 118 | #include <asm-generic/topology.h> |
| 122 | 119 | ||
| 123 | #ifdef CONFIG_SMP | 120 | #ifdef CONFIG_SMP |
diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c index 1bceb95f422d..5584247f5029 100644 --- a/arch/powerpc/platforms/powernv/opal-nvram.c +++ b/arch/powerpc/platforms/powernv/opal-nvram.c | |||
| @@ -44,6 +44,10 @@ static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index) | |||
| 44 | return count; | 44 | return count; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | /* | ||
| 48 | * This can be called in the panic path with interrupts off, so use | ||
| 49 | * mdelay in that case. | ||
| 50 | */ | ||
| 47 | static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) | 51 | static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) |
| 48 | { | 52 | { |
| 49 | s64 rc = OPAL_BUSY; | 53 | s64 rc = OPAL_BUSY; |
| @@ -58,10 +62,16 @@ static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) | |||
| 58 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | 62 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { |
| 59 | rc = opal_write_nvram(__pa(buf), count, off); | 63 | rc = opal_write_nvram(__pa(buf), count, off); |
| 60 | if (rc == OPAL_BUSY_EVENT) { | 64 | if (rc == OPAL_BUSY_EVENT) { |
| 61 | msleep(OPAL_BUSY_DELAY_MS); | 65 | if (in_interrupt() || irqs_disabled()) |
| 66 | mdelay(OPAL_BUSY_DELAY_MS); | ||
| 67 | else | ||
| 68 | msleep(OPAL_BUSY_DELAY_MS); | ||
| 62 | opal_poll_events(NULL); | 69 | opal_poll_events(NULL); |
| 63 | } else if (rc == OPAL_BUSY) { | 70 | } else if (rc == OPAL_BUSY) { |
| 64 | msleep(OPAL_BUSY_DELAY_MS); | 71 | if (in_interrupt() || irqs_disabled()) |
| 72 | mdelay(OPAL_BUSY_DELAY_MS); | ||
| 73 | else | ||
| 74 | msleep(OPAL_BUSY_DELAY_MS); | ||
| 65 | } | 75 | } |
| 66 | } | 76 | } |
| 67 | 77 | ||
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index 6176fe9795ca..941d8cc6c9f5 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig | |||
| @@ -261,9 +261,9 @@ CONFIG_IP_VS_NQ=m | |||
| 261 | CONFIG_IP_VS_FTP=m | 261 | CONFIG_IP_VS_FTP=m |
| 262 | CONFIG_IP_VS_PE_SIP=m | 262 | CONFIG_IP_VS_PE_SIP=m |
| 263 | CONFIG_NF_CONNTRACK_IPV4=m | 263 | CONFIG_NF_CONNTRACK_IPV4=m |
| 264 | CONFIG_NF_TABLES_IPV4=m | 264 | CONFIG_NF_TABLES_IPV4=y |
| 265 | CONFIG_NFT_CHAIN_ROUTE_IPV4=m | 265 | CONFIG_NFT_CHAIN_ROUTE_IPV4=m |
| 266 | CONFIG_NF_TABLES_ARP=m | 266 | CONFIG_NF_TABLES_ARP=y |
| 267 | CONFIG_NFT_CHAIN_NAT_IPV4=m | 267 | CONFIG_NFT_CHAIN_NAT_IPV4=m |
| 268 | CONFIG_IP_NF_IPTABLES=m | 268 | CONFIG_IP_NF_IPTABLES=m |
| 269 | CONFIG_IP_NF_MATCH_AH=m | 269 | CONFIG_IP_NF_MATCH_AH=m |
| @@ -284,7 +284,7 @@ CONFIG_IP_NF_ARPTABLES=m | |||
| 284 | CONFIG_IP_NF_ARPFILTER=m | 284 | CONFIG_IP_NF_ARPFILTER=m |
| 285 | CONFIG_IP_NF_ARP_MANGLE=m | 285 | CONFIG_IP_NF_ARP_MANGLE=m |
| 286 | CONFIG_NF_CONNTRACK_IPV6=m | 286 | CONFIG_NF_CONNTRACK_IPV6=m |
| 287 | CONFIG_NF_TABLES_IPV6=m | 287 | CONFIG_NF_TABLES_IPV6=y |
| 288 | CONFIG_NFT_CHAIN_ROUTE_IPV6=m | 288 | CONFIG_NFT_CHAIN_ROUTE_IPV6=m |
| 289 | CONFIG_NFT_CHAIN_NAT_IPV6=m | 289 | CONFIG_NFT_CHAIN_NAT_IPV6=m |
| 290 | CONFIG_IP6_NF_IPTABLES=m | 290 | CONFIG_IP6_NF_IPTABLES=m |
| @@ -305,7 +305,7 @@ CONFIG_IP6_NF_RAW=m | |||
| 305 | CONFIG_IP6_NF_SECURITY=m | 305 | CONFIG_IP6_NF_SECURITY=m |
| 306 | CONFIG_IP6_NF_NAT=m | 306 | CONFIG_IP6_NF_NAT=m |
| 307 | CONFIG_IP6_NF_TARGET_MASQUERADE=m | 307 | CONFIG_IP6_NF_TARGET_MASQUERADE=m |
| 308 | CONFIG_NF_TABLES_BRIDGE=m | 308 | CONFIG_NF_TABLES_BRIDGE=y |
| 309 | CONFIG_RDS=m | 309 | CONFIG_RDS=m |
| 310 | CONFIG_RDS_RDMA=m | 310 | CONFIG_RDS_RDMA=m |
| 311 | CONFIG_RDS_TCP=m | 311 | CONFIG_RDS_TCP=m |
| @@ -604,7 +604,6 @@ CONFIG_DETECT_HUNG_TASK=y | |||
| 604 | CONFIG_WQ_WATCHDOG=y | 604 | CONFIG_WQ_WATCHDOG=y |
| 605 | CONFIG_PANIC_ON_OOPS=y | 605 | CONFIG_PANIC_ON_OOPS=y |
| 606 | CONFIG_DEBUG_TIMEKEEPING=y | 606 | CONFIG_DEBUG_TIMEKEEPING=y |
| 607 | CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y | ||
| 608 | CONFIG_PROVE_LOCKING=y | 607 | CONFIG_PROVE_LOCKING=y |
| 609 | CONFIG_LOCK_STAT=y | 608 | CONFIG_LOCK_STAT=y |
| 610 | CONFIG_DEBUG_LOCKDEP=y | 609 | CONFIG_DEBUG_LOCKDEP=y |
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig index c105bcc6d7a6..eb6f75f24208 100644 --- a/arch/s390/configs/performance_defconfig +++ b/arch/s390/configs/performance_defconfig | |||
| @@ -259,9 +259,9 @@ CONFIG_IP_VS_NQ=m | |||
| 259 | CONFIG_IP_VS_FTP=m | 259 | CONFIG_IP_VS_FTP=m |
| 260 | CONFIG_IP_VS_PE_SIP=m | 260 | CONFIG_IP_VS_PE_SIP=m |
| 261 | CONFIG_NF_CONNTRACK_IPV4=m | 261 | CONFIG_NF_CONNTRACK_IPV4=m |
| 262 | CONFIG_NF_TABLES_IPV4=m | 262 | CONFIG_NF_TABLES_IPV4=y |
| 263 | CONFIG_NFT_CHAIN_ROUTE_IPV4=m | 263 | CONFIG_NFT_CHAIN_ROUTE_IPV4=m |
| 264 | CONFIG_NF_TABLES_ARP=m | 264 | CONFIG_NF_TABLES_ARP=y |
| 265 | CONFIG_NFT_CHAIN_NAT_IPV4=m | 265 | CONFIG_NFT_CHAIN_NAT_IPV4=m |
| 266 | CONFIG_IP_NF_IPTABLES=m | 266 | CONFIG_IP_NF_IPTABLES=m |
| 267 | CONFIG_IP_NF_MATCH_AH=m | 267 | CONFIG_IP_NF_MATCH_AH=m |
| @@ -282,7 +282,7 @@ CONFIG_IP_NF_ARPTABLES=m | |||
| 282 | CONFIG_IP_NF_ARPFILTER=m | 282 | CONFIG_IP_NF_ARPFILTER=m |
| 283 | CONFIG_IP_NF_ARP_MANGLE=m | 283 | CONFIG_IP_NF_ARP_MANGLE=m |
| 284 | CONFIG_NF_CONNTRACK_IPV6=m | 284 | CONFIG_NF_CONNTRACK_IPV6=m |
| 285 | CONFIG_NF_TABLES_IPV6=m | 285 | CONFIG_NF_TABLES_IPV6=y |
| 286 | CONFIG_NFT_CHAIN_ROUTE_IPV6=m | 286 | CONFIG_NFT_CHAIN_ROUTE_IPV6=m |
| 287 | CONFIG_NFT_CHAIN_NAT_IPV6=m | 287 | CONFIG_NFT_CHAIN_NAT_IPV6=m |
| 288 | CONFIG_IP6_NF_IPTABLES=m | 288 | CONFIG_IP6_NF_IPTABLES=m |
| @@ -303,7 +303,7 @@ CONFIG_IP6_NF_RAW=m | |||
| 303 | CONFIG_IP6_NF_SECURITY=m | 303 | CONFIG_IP6_NF_SECURITY=m |
| 304 | CONFIG_IP6_NF_NAT=m | 304 | CONFIG_IP6_NF_NAT=m |
| 305 | CONFIG_IP6_NF_TARGET_MASQUERADE=m | 305 | CONFIG_IP6_NF_TARGET_MASQUERADE=m |
| 306 | CONFIG_NF_TABLES_BRIDGE=m | 306 | CONFIG_NF_TABLES_BRIDGE=y |
| 307 | CONFIG_RDS=m | 307 | CONFIG_RDS=m |
| 308 | CONFIG_RDS_RDMA=m | 308 | CONFIG_RDS_RDMA=m |
| 309 | CONFIG_RDS_TCP=m | 309 | CONFIG_RDS_TCP=m |
diff --git a/arch/s390/crypto/crc32be-vx.S b/arch/s390/crypto/crc32be-vx.S index e8077f0971f8..2bf01ba44107 100644 --- a/arch/s390/crypto/crc32be-vx.S +++ b/arch/s390/crypto/crc32be-vx.S | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
| 16 | #include <asm/nospec-insn.h> | ||
| 16 | #include <asm/vx-insn.h> | 17 | #include <asm/vx-insn.h> |
| 17 | 18 | ||
| 18 | /* Vector register range containing CRC-32 constants */ | 19 | /* Vector register range containing CRC-32 constants */ |
| @@ -67,6 +68,8 @@ | |||
| 67 | 68 | ||
| 68 | .previous | 69 | .previous |
| 69 | 70 | ||
| 71 | GEN_BR_THUNK %r14 | ||
| 72 | |||
| 70 | .text | 73 | .text |
| 71 | /* | 74 | /* |
| 72 | * The CRC-32 function(s) use these calling conventions: | 75 | * The CRC-32 function(s) use these calling conventions: |
| @@ -203,6 +206,6 @@ ENTRY(crc32_be_vgfm_16) | |||
| 203 | 206 | ||
| 204 | .Ldone: | 207 | .Ldone: |
| 205 | VLGVF %r2,%v2,3 | 208 | VLGVF %r2,%v2,3 |
| 206 | br %r14 | 209 | BR_EX %r14 |
| 207 | 210 | ||
| 208 | .previous | 211 | .previous |
diff --git a/arch/s390/crypto/crc32le-vx.S b/arch/s390/crypto/crc32le-vx.S index d8c67a58c0c5..7d6f568bd3ad 100644 --- a/arch/s390/crypto/crc32le-vx.S +++ b/arch/s390/crypto/crc32le-vx.S | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
| 17 | #include <asm/nospec-insn.h> | ||
| 17 | #include <asm/vx-insn.h> | 18 | #include <asm/vx-insn.h> |
| 18 | 19 | ||
| 19 | /* Vector register range containing CRC-32 constants */ | 20 | /* Vector register range containing CRC-32 constants */ |
| @@ -76,6 +77,7 @@ | |||
| 76 | 77 | ||
| 77 | .previous | 78 | .previous |
| 78 | 79 | ||
| 80 | GEN_BR_THUNK %r14 | ||
| 79 | 81 | ||
| 80 | .text | 82 | .text |
| 81 | 83 | ||
| @@ -264,6 +266,6 @@ crc32_le_vgfm_generic: | |||
| 264 | 266 | ||
| 265 | .Ldone: | 267 | .Ldone: |
| 266 | VLGVF %r2,%v2,2 | 268 | VLGVF %r2,%v2,2 |
| 267 | br %r14 | 269 | BR_EX %r14 |
| 268 | 270 | ||
| 269 | .previous | 271 | .previous |
diff --git a/arch/s390/include/asm/nospec-insn.h b/arch/s390/include/asm/nospec-insn.h new file mode 100644 index 000000000000..a01f81186e86 --- /dev/null +++ b/arch/s390/include/asm/nospec-insn.h | |||
| @@ -0,0 +1,196 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef _ASM_S390_NOSPEC_ASM_H | ||
| 3 | #define _ASM_S390_NOSPEC_ASM_H | ||
| 4 | |||
| 5 | #include <asm/alternative-asm.h> | ||
| 6 | #include <asm/asm-offsets.h> | ||
| 7 | #include <asm/dwarf.h> | ||
| 8 | |||
| 9 | #ifdef __ASSEMBLY__ | ||
| 10 | |||
| 11 | #ifdef CONFIG_EXPOLINE | ||
| 12 | |||
| 13 | _LC_BR_R1 = __LC_BR_R1 | ||
| 14 | |||
| 15 | /* | ||
| 16 | * The expoline macros are used to create thunks in the same format | ||
| 17 | * as gcc generates them. The 'comdat' section flag makes sure that | ||
| 18 | * the various thunks are merged into a single copy. | ||
| 19 | */ | ||
| 20 | .macro __THUNK_PROLOG_NAME name | ||
| 21 | .pushsection .text.\name,"axG",@progbits,\name,comdat | ||
| 22 | .globl \name | ||
| 23 | .hidden \name | ||
| 24 | .type \name,@function | ||
| 25 | \name: | ||
| 26 | CFI_STARTPROC | ||
| 27 | .endm | ||
| 28 | |||
| 29 | .macro __THUNK_EPILOG | ||
| 30 | CFI_ENDPROC | ||
| 31 | .popsection | ||
| 32 | .endm | ||
| 33 | |||
| 34 | .macro __THUNK_PROLOG_BR r1,r2 | ||
| 35 | __THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1 | ||
| 36 | .endm | ||
| 37 | |||
| 38 | .macro __THUNK_PROLOG_BC d0,r1,r2 | ||
| 39 | __THUNK_PROLOG_NAME __s390x_indirect_branch_\d0\()_\r2\()use_\r1 | ||
| 40 | .endm | ||
| 41 | |||
| 42 | .macro __THUNK_BR r1,r2 | ||
| 43 | jg __s390x_indirect_jump_r\r2\()use_r\r1 | ||
| 44 | .endm | ||
| 45 | |||
| 46 | .macro __THUNK_BC d0,r1,r2 | ||
| 47 | jg __s390x_indirect_branch_\d0\()_\r2\()use_\r1 | ||
| 48 | .endm | ||
| 49 | |||
| 50 | .macro __THUNK_BRASL r1,r2,r3 | ||
| 51 | brasl \r1,__s390x_indirect_jump_r\r3\()use_r\r2 | ||
| 52 | .endm | ||
| 53 | |||
| 54 | .macro __DECODE_RR expand,reg,ruse | ||
| 55 | .set __decode_fail,1 | ||
| 56 | .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
| 57 | .ifc \reg,%r\r1 | ||
| 58 | .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
| 59 | .ifc \ruse,%r\r2 | ||
| 60 | \expand \r1,\r2 | ||
| 61 | .set __decode_fail,0 | ||
| 62 | .endif | ||
| 63 | .endr | ||
| 64 | .endif | ||
| 65 | .endr | ||
| 66 | .if __decode_fail == 1 | ||
| 67 | .error "__DECODE_RR failed" | ||
| 68 | .endif | ||
| 69 | .endm | ||
| 70 | |||
| 71 | .macro __DECODE_RRR expand,rsave,rtarget,ruse | ||
| 72 | .set __decode_fail,1 | ||
| 73 | .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
| 74 | .ifc \rsave,%r\r1 | ||
| 75 | .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
| 76 | .ifc \rtarget,%r\r2 | ||
| 77 | .irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
| 78 | .ifc \ruse,%r\r3 | ||
| 79 | \expand \r1,\r2,\r3 | ||
| 80 | .set __decode_fail,0 | ||
| 81 | .endif | ||
| 82 | .endr | ||
| 83 | .endif | ||
| 84 | .endr | ||
| 85 | .endif | ||
| 86 | .endr | ||
| 87 | .if __decode_fail == 1 | ||
| 88 | .error "__DECODE_RRR failed" | ||
| 89 | .endif | ||
| 90 | .endm | ||
| 91 | |||
| 92 | .macro __DECODE_DRR expand,disp,reg,ruse | ||
| 93 | .set __decode_fail,1 | ||
| 94 | .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
| 95 | .ifc \reg,%r\r1 | ||
| 96 | .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
| 97 | .ifc \ruse,%r\r2 | ||
| 98 | \expand \disp,\r1,\r2 | ||
| 99 | .set __decode_fail,0 | ||
| 100 | .endif | ||
| 101 | .endr | ||
| 102 | .endif | ||
| 103 | .endr | ||
| 104 | .if __decode_fail == 1 | ||
| 105 | .error "__DECODE_DRR failed" | ||
| 106 | .endif | ||
| 107 | .endm | ||
| 108 | |||
| 109 | .macro __THUNK_EX_BR reg,ruse | ||
| 110 | # Be very careful when adding instructions to this macro! | ||
| 111 | # The ALTERNATIVE replacement code has a .+10 which targets | ||
| 112 | # the "br \reg" after the code has been patched. | ||
| 113 | #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES | ||
| 114 | exrl 0,555f | ||
| 115 | j . | ||
| 116 | #else | ||
| 117 | .ifc \reg,%r1 | ||
| 118 | ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35 | ||
| 119 | j . | ||
| 120 | .else | ||
| 121 | larl \ruse,555f | ||
| 122 | ex 0,0(\ruse) | ||
| 123 | j . | ||
| 124 | .endif | ||
| 125 | #endif | ||
| 126 | 555: br \reg | ||
| 127 | .endm | ||
| 128 | |||
| 129 | .macro __THUNK_EX_BC disp,reg,ruse | ||
| 130 | #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES | ||
| 131 | exrl 0,556f | ||
| 132 | j . | ||
| 133 | #else | ||
| 134 | larl \ruse,556f | ||
| 135 | ex 0,0(\ruse) | ||
| 136 | j . | ||
| 137 | #endif | ||
| 138 | 556: b \disp(\reg) | ||
| 139 | .endm | ||
| 140 | |||
| 141 | .macro GEN_BR_THUNK reg,ruse=%r1 | ||
| 142 | __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse | ||
| 143 | __THUNK_EX_BR \reg,\ruse | ||
| 144 | __THUNK_EPILOG | ||
| 145 | .endm | ||
| 146 | |||
| 147 | .macro GEN_B_THUNK disp,reg,ruse=%r1 | ||
| 148 | __DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse | ||
| 149 | __THUNK_EX_BC \disp,\reg,\ruse | ||
| 150 | __THUNK_EPILOG | ||
| 151 | .endm | ||
| 152 | |||
| 153 | .macro BR_EX reg,ruse=%r1 | ||
| 154 | 557: __DECODE_RR __THUNK_BR,\reg,\ruse | ||
| 155 | .pushsection .s390_indirect_branches,"a",@progbits | ||
| 156 | .long 557b-. | ||
| 157 | .popsection | ||
| 158 | .endm | ||
| 159 | |||
| 160 | .macro B_EX disp,reg,ruse=%r1 | ||
| 161 | 558: __DECODE_DRR __THUNK_BC,\disp,\reg,\ruse | ||
| 162 | .pushsection .s390_indirect_branches,"a",@progbits | ||
| 163 | .long 558b-. | ||
| 164 | .popsection | ||
| 165 | .endm | ||
| 166 | |||
| 167 | .macro BASR_EX rsave,rtarget,ruse=%r1 | ||
| 168 | 559: __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse | ||
| 169 | .pushsection .s390_indirect_branches,"a",@progbits | ||
| 170 | .long 559b-. | ||
| 171 | .popsection | ||
| 172 | .endm | ||
| 173 | |||
| 174 | #else | ||
| 175 | .macro GEN_BR_THUNK reg,ruse=%r1 | ||
| 176 | .endm | ||
| 177 | |||
| 178 | .macro GEN_B_THUNK disp,reg,ruse=%r1 | ||
| 179 | .endm | ||
| 180 | |||
| 181 | .macro BR_EX reg,ruse=%r1 | ||
| 182 | br \reg | ||
| 183 | .endm | ||
| 184 | |||
| 185 | .macro B_EX disp,reg,ruse=%r1 | ||
| 186 | b \disp(\reg) | ||
| 187 | .endm | ||
| 188 | |||
| 189 | .macro BASR_EX rsave,rtarget,ruse=%r1 | ||
| 190 | basr \rsave,\rtarget | ||
| 191 | .endm | ||
| 192 | #endif | ||
| 193 | |||
| 194 | #endif /* __ASSEMBLY__ */ | ||
| 195 | |||
| 196 | #endif /* _ASM_S390_NOSPEC_ASM_H */ | ||
diff --git a/arch/s390/include/asm/purgatory.h b/arch/s390/include/asm/purgatory.h index e297bcfc476f..6090670df51f 100644 --- a/arch/s390/include/asm/purgatory.h +++ b/arch/s390/include/asm/purgatory.h | |||
| @@ -13,5 +13,11 @@ | |||
| 13 | 13 | ||
| 14 | int verify_sha256_digest(void); | 14 | int verify_sha256_digest(void); |
| 15 | 15 | ||
| 16 | extern u64 kernel_entry; | ||
| 17 | extern u64 kernel_type; | ||
| 18 | |||
| 19 | extern u64 crash_start; | ||
| 20 | extern u64 crash_size; | ||
| 21 | |||
| 16 | #endif /* __ASSEMBLY__ */ | 22 | #endif /* __ASSEMBLY__ */ |
| 17 | #endif /* _S390_PURGATORY_H_ */ | 23 | #endif /* _S390_PURGATORY_H_ */ |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 84ea6225efb4..f92dd8ed3884 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
| @@ -65,6 +65,7 @@ obj-y += nospec-branch.o | |||
| 65 | 65 | ||
| 66 | extra-y += head.o head64.o vmlinux.lds | 66 | extra-y += head.o head64.o vmlinux.lds |
| 67 | 67 | ||
| 68 | obj-$(CONFIG_SYSFS) += nospec-sysfs.o | ||
| 68 | CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) | 69 | CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) |
| 69 | 70 | ||
| 70 | obj-$(CONFIG_MODULES) += module.o | 71 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index eb2a5c0443cd..11aea745a2a6 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
| @@ -181,6 +181,7 @@ int main(void) | |||
| 181 | OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags); | 181 | OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags); |
| 182 | OFFSET(__LC_PREEMPT_COUNT, lowcore, preempt_count); | 182 | OFFSET(__LC_PREEMPT_COUNT, lowcore, preempt_count); |
| 183 | OFFSET(__LC_GMAP, lowcore, gmap); | 183 | OFFSET(__LC_GMAP, lowcore, gmap); |
| 184 | OFFSET(__LC_BR_R1, lowcore, br_r1_trampoline); | ||
| 184 | /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ | 185 | /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ |
| 185 | OFFSET(__LC_DUMP_REIPL, lowcore, ipib); | 186 | OFFSET(__LC_DUMP_REIPL, lowcore, ipib); |
| 186 | /* hardware defined lowcore locations 0x1000 - 0x18ff */ | 187 | /* hardware defined lowcore locations 0x1000 - 0x18ff */ |
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index f6c56009e822..b65874b0b412 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S | |||
| @@ -9,18 +9,22 @@ | |||
| 9 | 9 | ||
| 10 | #include <linux/linkage.h> | 10 | #include <linux/linkage.h> |
| 11 | #include <asm/asm-offsets.h> | 11 | #include <asm/asm-offsets.h> |
| 12 | #include <asm/nospec-insn.h> | ||
| 12 | #include <asm/ptrace.h> | 13 | #include <asm/ptrace.h> |
| 13 | #include <asm/sigp.h> | 14 | #include <asm/sigp.h> |
| 14 | 15 | ||
| 16 | GEN_BR_THUNK %r9 | ||
| 17 | GEN_BR_THUNK %r14 | ||
| 18 | |||
| 15 | ENTRY(s390_base_mcck_handler) | 19 | ENTRY(s390_base_mcck_handler) |
| 16 | basr %r13,0 | 20 | basr %r13,0 |
| 17 | 0: lg %r15,__LC_PANIC_STACK # load panic stack | 21 | 0: lg %r15,__LC_PANIC_STACK # load panic stack |
| 18 | aghi %r15,-STACK_FRAME_OVERHEAD | 22 | aghi %r15,-STACK_FRAME_OVERHEAD |
| 19 | larl %r1,s390_base_mcck_handler_fn | 23 | larl %r1,s390_base_mcck_handler_fn |
| 20 | lg %r1,0(%r1) | 24 | lg %r9,0(%r1) |
| 21 | ltgr %r1,%r1 | 25 | ltgr %r9,%r9 |
| 22 | jz 1f | 26 | jz 1f |
| 23 | basr %r14,%r1 | 27 | BASR_EX %r14,%r9 |
| 24 | 1: la %r1,4095 | 28 | 1: la %r1,4095 |
| 25 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) | 29 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) |
| 26 | lpswe __LC_MCK_OLD_PSW | 30 | lpswe __LC_MCK_OLD_PSW |
| @@ -37,10 +41,10 @@ ENTRY(s390_base_ext_handler) | |||
| 37 | basr %r13,0 | 41 | basr %r13,0 |
| 38 | 0: aghi %r15,-STACK_FRAME_OVERHEAD | 42 | 0: aghi %r15,-STACK_FRAME_OVERHEAD |
| 39 | larl %r1,s390_base_ext_handler_fn | 43 | larl %r1,s390_base_ext_handler_fn |
| 40 | lg %r1,0(%r1) | 44 | lg %r9,0(%r1) |
| 41 | ltgr %r1,%r1 | 45 | ltgr %r9,%r9 |
| 42 | jz 1f | 46 | jz 1f |
| 43 | basr %r14,%r1 | 47 | BASR_EX %r14,%r9 |
| 44 | 1: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC | 48 | 1: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC |
| 45 | ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit | 49 | ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit |
| 46 | lpswe __LC_EXT_OLD_PSW | 50 | lpswe __LC_EXT_OLD_PSW |
| @@ -57,10 +61,10 @@ ENTRY(s390_base_pgm_handler) | |||
| 57 | basr %r13,0 | 61 | basr %r13,0 |
| 58 | 0: aghi %r15,-STACK_FRAME_OVERHEAD | 62 | 0: aghi %r15,-STACK_FRAME_OVERHEAD |
| 59 | larl %r1,s390_base_pgm_handler_fn | 63 | larl %r1,s390_base_pgm_handler_fn |
| 60 | lg %r1,0(%r1) | 64 | lg %r9,0(%r1) |
| 61 | ltgr %r1,%r1 | 65 | ltgr %r9,%r9 |
| 62 | jz 1f | 66 | jz 1f |
| 63 | basr %r14,%r1 | 67 | BASR_EX %r14,%r9 |
| 64 | lmg %r0,%r15,__LC_SAVE_AREA_SYNC | 68 | lmg %r0,%r15,__LC_SAVE_AREA_SYNC |
| 65 | lpswe __LC_PGM_OLD_PSW | 69 | lpswe __LC_PGM_OLD_PSW |
| 66 | 1: lpswe disabled_wait_psw-0b(%r13) | 70 | 1: lpswe disabled_wait_psw-0b(%r13) |
| @@ -117,7 +121,7 @@ ENTRY(diag308_reset) | |||
| 117 | larl %r4,.Lcontinue_psw # Restore PSW flags | 121 | larl %r4,.Lcontinue_psw # Restore PSW flags |
| 118 | lpswe 0(%r4) | 122 | lpswe 0(%r4) |
| 119 | .Lcontinue: | 123 | .Lcontinue: |
| 120 | br %r14 | 124 | BR_EX %r14 |
| 121 | .align 16 | 125 | .align 16 |
| 122 | .Lrestart_psw: | 126 | .Lrestart_psw: |
| 123 | .long 0x00080000,0x80000000 + .Lrestart_part2 | 127 | .long 0x00080000,0x80000000 + .Lrestart_part2 |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 3f22f139a041..f03402efab4b 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <asm/setup.h> | 28 | #include <asm/setup.h> |
| 29 | #include <asm/nmi.h> | 29 | #include <asm/nmi.h> |
| 30 | #include <asm/export.h> | 30 | #include <asm/export.h> |
| 31 | #include <asm/nospec-insn.h> | ||
| 31 | 32 | ||
| 32 | __PT_R0 = __PT_GPRS | 33 | __PT_R0 = __PT_GPRS |
| 33 | __PT_R1 = __PT_GPRS + 8 | 34 | __PT_R1 = __PT_GPRS + 8 |
| @@ -183,67 +184,9 @@ _LPP_OFFSET = __LC_LPP | |||
| 183 | "jnz .+8; .long 0xb2e8d000", 82 | 184 | "jnz .+8; .long 0xb2e8d000", 82 |
| 184 | .endm | 185 | .endm |
| 185 | 186 | ||
| 186 | #ifdef CONFIG_EXPOLINE | 187 | GEN_BR_THUNK %r9 |
| 187 | 188 | GEN_BR_THUNK %r14 | |
| 188 | .macro GEN_BR_THUNK name,reg,tmp | 189 | GEN_BR_THUNK %r14,%r11 |
| 189 | .section .text.\name,"axG",@progbits,\name,comdat | ||
| 190 | .globl \name | ||
| 191 | .hidden \name | ||
| 192 | .type \name,@function | ||
| 193 | \name: | ||
| 194 | CFI_STARTPROC | ||
| 195 | #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES | ||
| 196 | exrl 0,0f | ||
| 197 | #else | ||
| 198 | larl \tmp,0f | ||
| 199 | ex 0,0(\tmp) | ||
| 200 | #endif | ||
| 201 | j . | ||
| 202 | 0: br \reg | ||
| 203 | CFI_ENDPROC | ||
| 204 | .endm | ||
| 205 | |||
| 206 | GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1 | ||
| 207 | GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1 | ||
| 208 | GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11 | ||
| 209 | |||
| 210 | .macro BASR_R14_R9 | ||
| 211 | 0: brasl %r14,__s390x_indirect_jump_r1use_r9 | ||
| 212 | .pushsection .s390_indirect_branches,"a",@progbits | ||
| 213 | .long 0b-. | ||
| 214 | .popsection | ||
| 215 | .endm | ||
| 216 | |||
| 217 | .macro BR_R1USE_R14 | ||
| 218 | 0: jg __s390x_indirect_jump_r1use_r14 | ||
| 219 | .pushsection .s390_indirect_branches,"a",@progbits | ||
| 220 | .long 0b-. | ||
| 221 | .popsection | ||
| 222 | .endm | ||
| 223 | |||
| 224 | .macro BR_R11USE_R14 | ||
| 225 | 0: jg __s390x_indirect_jump_r11use_r14 | ||
| 226 | .pushsection .s390_indirect_branches,"a",@progbits | ||
| 227 | .long 0b-. | ||
| 228 | .popsection | ||
| 229 | .endm | ||
| 230 | |||
| 231 | #else /* CONFIG_EXPOLINE */ | ||
| 232 | |||
| 233 | .macro BASR_R14_R9 | ||
| 234 | basr %r14,%r9 | ||
| 235 | .endm | ||
| 236 | |||
| 237 | .macro BR_R1USE_R14 | ||
| 238 | br %r14 | ||
| 239 | .endm | ||
| 240 | |||
| 241 | .macro BR_R11USE_R14 | ||
| 242 | br %r14 | ||
| 243 | .endm | ||
| 244 | |||
| 245 | #endif /* CONFIG_EXPOLINE */ | ||
| 246 | |||
| 247 | 190 | ||
| 248 | .section .kprobes.text, "ax" | 191 | .section .kprobes.text, "ax" |
| 249 | .Ldummy: | 192 | .Ldummy: |
| @@ -260,7 +203,7 @@ _LPP_OFFSET = __LC_LPP | |||
| 260 | ENTRY(__bpon) | 203 | ENTRY(__bpon) |
| 261 | .globl __bpon | 204 | .globl __bpon |
| 262 | BPON | 205 | BPON |
| 263 | BR_R1USE_R14 | 206 | BR_EX %r14 |
| 264 | 207 | ||
| 265 | /* | 208 | /* |
| 266 | * Scheduler resume function, called by switch_to | 209 | * Scheduler resume function, called by switch_to |
| @@ -284,7 +227,7 @@ ENTRY(__switch_to) | |||
| 284 | mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next | 227 | mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next |
| 285 | lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task | 228 | lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task |
| 286 | ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 | 229 | ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 |
| 287 | BR_R1USE_R14 | 230 | BR_EX %r14 |
| 288 | 231 | ||
| 289 | .L__critical_start: | 232 | .L__critical_start: |
| 290 | 233 | ||
| @@ -351,7 +294,7 @@ sie_exit: | |||
| 351 | xgr %r5,%r5 | 294 | xgr %r5,%r5 |
| 352 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers | 295 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers |
| 353 | lg %r2,__SF_SIE_REASON(%r15) # return exit reason code | 296 | lg %r2,__SF_SIE_REASON(%r15) # return exit reason code |
| 354 | BR_R1USE_R14 | 297 | BR_EX %r14 |
| 355 | .Lsie_fault: | 298 | .Lsie_fault: |
| 356 | lghi %r14,-EFAULT | 299 | lghi %r14,-EFAULT |
| 357 | stg %r14,__SF_SIE_REASON(%r15) # set exit reason code | 300 | stg %r14,__SF_SIE_REASON(%r15) # set exit reason code |
| @@ -410,7 +353,7 @@ ENTRY(system_call) | |||
| 410 | lgf %r9,0(%r8,%r10) # get system call add. | 353 | lgf %r9,0(%r8,%r10) # get system call add. |
| 411 | TSTMSK __TI_flags(%r12),_TIF_TRACE | 354 | TSTMSK __TI_flags(%r12),_TIF_TRACE |
| 412 | jnz .Lsysc_tracesys | 355 | jnz .Lsysc_tracesys |
| 413 | BASR_R14_R9 # call sys_xxxx | 356 | BASR_EX %r14,%r9 # call sys_xxxx |
| 414 | stg %r2,__PT_R2(%r11) # store return value | 357 | stg %r2,__PT_R2(%r11) # store return value |
| 415 | 358 | ||
| 416 | .Lsysc_return: | 359 | .Lsysc_return: |
| @@ -595,7 +538,7 @@ ENTRY(system_call) | |||
| 595 | lmg %r3,%r7,__PT_R3(%r11) | 538 | lmg %r3,%r7,__PT_R3(%r11) |
| 596 | stg %r7,STACK_FRAME_OVERHEAD(%r15) | 539 | stg %r7,STACK_FRAME_OVERHEAD(%r15) |
| 597 | lg %r2,__PT_ORIG_GPR2(%r11) | 540 | lg %r2,__PT_ORIG_GPR2(%r11) |
| 598 | BASR_R14_R9 # call sys_xxx | 541 | BASR_EX %r14,%r9 # call sys_xxx |
| 599 | stg %r2,__PT_R2(%r11) # store return value | 542 | stg %r2,__PT_R2(%r11) # store return value |
| 600 | .Lsysc_tracenogo: | 543 | .Lsysc_tracenogo: |
| 601 | TSTMSK __TI_flags(%r12),_TIF_TRACE | 544 | TSTMSK __TI_flags(%r12),_TIF_TRACE |
| @@ -619,7 +562,7 @@ ENTRY(ret_from_fork) | |||
| 619 | lmg %r9,%r10,__PT_R9(%r11) # load gprs | 562 | lmg %r9,%r10,__PT_R9(%r11) # load gprs |
| 620 | ENTRY(kernel_thread_starter) | 563 | ENTRY(kernel_thread_starter) |
| 621 | la %r2,0(%r10) | 564 | la %r2,0(%r10) |
| 622 | BASR_R14_R9 | 565 | BASR_EX %r14,%r9 |
| 623 | j .Lsysc_tracenogo | 566 | j .Lsysc_tracenogo |
| 624 | 567 | ||
| 625 | /* | 568 | /* |
| @@ -701,7 +644,7 @@ ENTRY(pgm_check_handler) | |||
| 701 | je .Lpgm_return | 644 | je .Lpgm_return |
| 702 | lgf %r9,0(%r10,%r1) # load address of handler routine | 645 | lgf %r9,0(%r10,%r1) # load address of handler routine |
| 703 | lgr %r2,%r11 # pass pointer to pt_regs | 646 | lgr %r2,%r11 # pass pointer to pt_regs |
| 704 | BASR_R14_R9 # branch to interrupt-handler | 647 | BASR_EX %r14,%r9 # branch to interrupt-handler |
| 705 | .Lpgm_return: | 648 | .Lpgm_return: |
| 706 | LOCKDEP_SYS_EXIT | 649 | LOCKDEP_SYS_EXIT |
| 707 | tm __PT_PSW+1(%r11),0x01 # returning to user ? | 650 | tm __PT_PSW+1(%r11),0x01 # returning to user ? |
| @@ -1019,7 +962,7 @@ ENTRY(psw_idle) | |||
| 1019 | stpt __TIMER_IDLE_ENTER(%r2) | 962 | stpt __TIMER_IDLE_ENTER(%r2) |
| 1020 | .Lpsw_idle_lpsw: | 963 | .Lpsw_idle_lpsw: |
| 1021 | lpswe __SF_EMPTY(%r15) | 964 | lpswe __SF_EMPTY(%r15) |
| 1022 | BR_R1USE_R14 | 965 | BR_EX %r14 |
| 1023 | .Lpsw_idle_end: | 966 | .Lpsw_idle_end: |
| 1024 | 967 | ||
| 1025 | /* | 968 | /* |
| @@ -1061,7 +1004,7 @@ ENTRY(save_fpu_regs) | |||
| 1061 | .Lsave_fpu_regs_done: | 1004 | .Lsave_fpu_regs_done: |
| 1062 | oi __LC_CPU_FLAGS+7,_CIF_FPU | 1005 | oi __LC_CPU_FLAGS+7,_CIF_FPU |
| 1063 | .Lsave_fpu_regs_exit: | 1006 | .Lsave_fpu_regs_exit: |
| 1064 | BR_R1USE_R14 | 1007 | BR_EX %r14 |
| 1065 | .Lsave_fpu_regs_end: | 1008 | .Lsave_fpu_regs_end: |
| 1066 | EXPORT_SYMBOL(save_fpu_regs) | 1009 | EXPORT_SYMBOL(save_fpu_regs) |
| 1067 | 1010 | ||
| @@ -1107,7 +1050,7 @@ load_fpu_regs: | |||
| 1107 | .Lload_fpu_regs_done: | 1050 | .Lload_fpu_regs_done: |
| 1108 | ni __LC_CPU_FLAGS+7,255-_CIF_FPU | 1051 | ni __LC_CPU_FLAGS+7,255-_CIF_FPU |
| 1109 | .Lload_fpu_regs_exit: | 1052 | .Lload_fpu_regs_exit: |
| 1110 | BR_R1USE_R14 | 1053 | BR_EX %r14 |
| 1111 | .Lload_fpu_regs_end: | 1054 | .Lload_fpu_regs_end: |
| 1112 | 1055 | ||
| 1113 | .L__critical_end: | 1056 | .L__critical_end: |
| @@ -1322,7 +1265,7 @@ cleanup_critical: | |||
| 1322 | jl 0f | 1265 | jl 0f |
| 1323 | clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end | 1266 | clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end |
| 1324 | jl .Lcleanup_load_fpu_regs | 1267 | jl .Lcleanup_load_fpu_regs |
| 1325 | 0: BR_R11USE_R14 | 1268 | 0: BR_EX %r14 |
| 1326 | 1269 | ||
| 1327 | .align 8 | 1270 | .align 8 |
| 1328 | .Lcleanup_table: | 1271 | .Lcleanup_table: |
| @@ -1358,7 +1301,7 @@ cleanup_critical: | |||
| 1358 | ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE | 1301 | ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE |
| 1359 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | 1302 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce |
| 1360 | larl %r9,sie_exit # skip forward to sie_exit | 1303 | larl %r9,sie_exit # skip forward to sie_exit |
| 1361 | BR_R11USE_R14 | 1304 | BR_EX %r14 |
| 1362 | #endif | 1305 | #endif |
| 1363 | 1306 | ||
| 1364 | .Lcleanup_system_call: | 1307 | .Lcleanup_system_call: |
| @@ -1412,7 +1355,7 @@ cleanup_critical: | |||
| 1412 | stg %r15,56(%r11) # r15 stack pointer | 1355 | stg %r15,56(%r11) # r15 stack pointer |
| 1413 | # set new psw address and exit | 1356 | # set new psw address and exit |
| 1414 | larl %r9,.Lsysc_do_svc | 1357 | larl %r9,.Lsysc_do_svc |
| 1415 | BR_R11USE_R14 | 1358 | BR_EX %r14,%r11 |
| 1416 | .Lcleanup_system_call_insn: | 1359 | .Lcleanup_system_call_insn: |
| 1417 | .quad system_call | 1360 | .quad system_call |
| 1418 | .quad .Lsysc_stmg | 1361 | .quad .Lsysc_stmg |
| @@ -1424,7 +1367,7 @@ cleanup_critical: | |||
| 1424 | 1367 | ||
| 1425 | .Lcleanup_sysc_tif: | 1368 | .Lcleanup_sysc_tif: |
| 1426 | larl %r9,.Lsysc_tif | 1369 | larl %r9,.Lsysc_tif |
| 1427 | BR_R11USE_R14 | 1370 | BR_EX %r14,%r11 |
| 1428 | 1371 | ||
| 1429 | .Lcleanup_sysc_restore: | 1372 | .Lcleanup_sysc_restore: |
| 1430 | # check if stpt has been executed | 1373 | # check if stpt has been executed |
| @@ -1441,14 +1384,14 @@ cleanup_critical: | |||
| 1441 | mvc 0(64,%r11),__PT_R8(%r9) | 1384 | mvc 0(64,%r11),__PT_R8(%r9) |
| 1442 | lmg %r0,%r7,__PT_R0(%r9) | 1385 | lmg %r0,%r7,__PT_R0(%r9) |
| 1443 | 1: lmg %r8,%r9,__LC_RETURN_PSW | 1386 | 1: lmg %r8,%r9,__LC_RETURN_PSW |
| 1444 | BR_R11USE_R14 | 1387 | BR_EX %r14,%r11 |
| 1445 | .Lcleanup_sysc_restore_insn: | 1388 | .Lcleanup_sysc_restore_insn: |
| 1446 | .quad .Lsysc_exit_timer | 1389 | .quad .Lsysc_exit_timer |
| 1447 | .quad .Lsysc_done - 4 | 1390 | .quad .Lsysc_done - 4 |
| 1448 | 1391 | ||
| 1449 | .Lcleanup_io_tif: | 1392 | .Lcleanup_io_tif: |
| 1450 | larl %r9,.Lio_tif | 1393 | larl %r9,.Lio_tif |
| 1451 | BR_R11USE_R14 | 1394 | BR_EX %r14,%r11 |
| 1452 | 1395 | ||
| 1453 | .Lcleanup_io_restore: | 1396 | .Lcleanup_io_restore: |
| 1454 | # check if stpt has been executed | 1397 | # check if stpt has been executed |
| @@ -1462,7 +1405,7 @@ cleanup_critical: | |||
| 1462 | mvc 0(64,%r11),__PT_R8(%r9) | 1405 | mvc 0(64,%r11),__PT_R8(%r9) |
| 1463 | lmg %r0,%r7,__PT_R0(%r9) | 1406 | lmg %r0,%r7,__PT_R0(%r9) |
| 1464 | 1: lmg %r8,%r9,__LC_RETURN_PSW | 1407 | 1: lmg %r8,%r9,__LC_RETURN_PSW |
| 1465 | BR_R11USE_R14 | 1408 | BR_EX %r14,%r11 |
| 1466 | .Lcleanup_io_restore_insn: | 1409 | .Lcleanup_io_restore_insn: |
| 1467 | .quad .Lio_exit_timer | 1410 | .quad .Lio_exit_timer |
| 1468 | .quad .Lio_done - 4 | 1411 | .quad .Lio_done - 4 |
| @@ -1515,17 +1458,17 @@ cleanup_critical: | |||
| 1515 | # prepare return psw | 1458 | # prepare return psw |
| 1516 | nihh %r8,0xfcfd # clear irq & wait state bits | 1459 | nihh %r8,0xfcfd # clear irq & wait state bits |
| 1517 | lg %r9,48(%r11) # return from psw_idle | 1460 | lg %r9,48(%r11) # return from psw_idle |
| 1518 | BR_R11USE_R14 | 1461 | BR_EX %r14,%r11 |
| 1519 | .Lcleanup_idle_insn: | 1462 | .Lcleanup_idle_insn: |
| 1520 | .quad .Lpsw_idle_lpsw | 1463 | .quad .Lpsw_idle_lpsw |
| 1521 | 1464 | ||
| 1522 | .Lcleanup_save_fpu_regs: | 1465 | .Lcleanup_save_fpu_regs: |
| 1523 | larl %r9,save_fpu_regs | 1466 | larl %r9,save_fpu_regs |
| 1524 | BR_R11USE_R14 | 1467 | BR_EX %r14,%r11 |
| 1525 | 1468 | ||
| 1526 | .Lcleanup_load_fpu_regs: | 1469 | .Lcleanup_load_fpu_regs: |
| 1527 | larl %r9,load_fpu_regs | 1470 | larl %r9,load_fpu_regs |
| 1528 | BR_R11USE_R14 | 1471 | BR_EX %r14,%r11 |
| 1529 | 1472 | ||
| 1530 | /* | 1473 | /* |
| 1531 | * Integer constants | 1474 | * Integer constants |
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 94f2099bceb0..3d17c41074ca 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c | |||
| @@ -176,10 +176,9 @@ void do_softirq_own_stack(void) | |||
| 176 | new -= STACK_FRAME_OVERHEAD; | 176 | new -= STACK_FRAME_OVERHEAD; |
| 177 | ((struct stack_frame *) new)->back_chain = old; | 177 | ((struct stack_frame *) new)->back_chain = old; |
| 178 | asm volatile(" la 15,0(%0)\n" | 178 | asm volatile(" la 15,0(%0)\n" |
| 179 | " basr 14,%2\n" | 179 | " brasl 14,__do_softirq\n" |
| 180 | " la 15,0(%1)\n" | 180 | " la 15,0(%1)\n" |
| 181 | : : "a" (new), "a" (old), | 181 | : : "a" (new), "a" (old) |
| 182 | "a" (__do_softirq) | ||
| 183 | : "0", "1", "2", "3", "4", "5", "14", | 182 | : "0", "1", "2", "3", "4", "5", "14", |
| 184 | "cc", "memory" ); | 183 | "cc", "memory" ); |
| 185 | } else { | 184 | } else { |
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 82df7d80fab2..27110f3294ed 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S | |||
| @@ -9,13 +9,17 @@ | |||
| 9 | #include <linux/linkage.h> | 9 | #include <linux/linkage.h> |
| 10 | #include <asm/asm-offsets.h> | 10 | #include <asm/asm-offsets.h> |
| 11 | #include <asm/ftrace.h> | 11 | #include <asm/ftrace.h> |
| 12 | #include <asm/nospec-insn.h> | ||
| 12 | #include <asm/ptrace.h> | 13 | #include <asm/ptrace.h> |
| 13 | #include <asm/export.h> | 14 | #include <asm/export.h> |
| 14 | 15 | ||
| 16 | GEN_BR_THUNK %r1 | ||
| 17 | GEN_BR_THUNK %r14 | ||
| 18 | |||
| 15 | .section .kprobes.text, "ax" | 19 | .section .kprobes.text, "ax" |
| 16 | 20 | ||
| 17 | ENTRY(ftrace_stub) | 21 | ENTRY(ftrace_stub) |
| 18 | br %r14 | 22 | BR_EX %r14 |
| 19 | 23 | ||
| 20 | #define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE) | 24 | #define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE) |
| 21 | #define STACK_PTREGS (STACK_FRAME_OVERHEAD) | 25 | #define STACK_PTREGS (STACK_FRAME_OVERHEAD) |
| @@ -23,7 +27,7 @@ ENTRY(ftrace_stub) | |||
| 23 | #define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW) | 27 | #define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW) |
| 24 | 28 | ||
| 25 | ENTRY(_mcount) | 29 | ENTRY(_mcount) |
| 26 | br %r14 | 30 | BR_EX %r14 |
| 27 | 31 | ||
| 28 | EXPORT_SYMBOL(_mcount) | 32 | EXPORT_SYMBOL(_mcount) |
| 29 | 33 | ||
| @@ -53,7 +57,7 @@ ENTRY(ftrace_caller) | |||
| 53 | #endif | 57 | #endif |
| 54 | lgr %r3,%r14 | 58 | lgr %r3,%r14 |
| 55 | la %r5,STACK_PTREGS(%r15) | 59 | la %r5,STACK_PTREGS(%r15) |
| 56 | basr %r14,%r1 | 60 | BASR_EX %r14,%r1 |
| 57 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 61 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 58 | # The j instruction gets runtime patched to a nop instruction. | 62 | # The j instruction gets runtime patched to a nop instruction. |
| 59 | # See ftrace_enable_ftrace_graph_caller. | 63 | # See ftrace_enable_ftrace_graph_caller. |
| @@ -68,7 +72,7 @@ ftrace_graph_caller_end: | |||
| 68 | #endif | 72 | #endif |
| 69 | lg %r1,(STACK_PTREGS_PSW+8)(%r15) | 73 | lg %r1,(STACK_PTREGS_PSW+8)(%r15) |
| 70 | lmg %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15) | 74 | lmg %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15) |
| 71 | br %r1 | 75 | BR_EX %r1 |
| 72 | 76 | ||
| 73 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 77 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 74 | 78 | ||
| @@ -81,6 +85,6 @@ ENTRY(return_to_handler) | |||
| 81 | aghi %r15,STACK_FRAME_OVERHEAD | 85 | aghi %r15,STACK_FRAME_OVERHEAD |
| 82 | lgr %r14,%r2 | 86 | lgr %r14,%r2 |
| 83 | lmg %r2,%r5,32(%r15) | 87 | lmg %r2,%r5,32(%r15) |
| 84 | br %r14 | 88 | BR_EX %r14 |
| 85 | 89 | ||
| 86 | #endif | 90 | #endif |
diff --git a/arch/s390/kernel/nospec-branch.c b/arch/s390/kernel/nospec-branch.c index 46d49a11663f..8ad6a7128b3a 100644 --- a/arch/s390/kernel/nospec-branch.c +++ b/arch/s390/kernel/nospec-branch.c | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
| 3 | #include <linux/device.h> | 3 | #include <linux/device.h> |
| 4 | #include <linux/cpu.h> | ||
| 5 | #include <asm/nospec-branch.h> | 4 | #include <asm/nospec-branch.h> |
| 6 | 5 | ||
| 7 | static int __init nobp_setup_early(char *str) | 6 | static int __init nobp_setup_early(char *str) |
| @@ -44,24 +43,6 @@ static int __init nospec_report(void) | |||
| 44 | } | 43 | } |
| 45 | arch_initcall(nospec_report); | 44 | arch_initcall(nospec_report); |
| 46 | 45 | ||
| 47 | #ifdef CONFIG_SYSFS | ||
| 48 | ssize_t cpu_show_spectre_v1(struct device *dev, | ||
| 49 | struct device_attribute *attr, char *buf) | ||
| 50 | { | ||
| 51 | return sprintf(buf, "Mitigation: __user pointer sanitization\n"); | ||
| 52 | } | ||
| 53 | |||
| 54 | ssize_t cpu_show_spectre_v2(struct device *dev, | ||
| 55 | struct device_attribute *attr, char *buf) | ||
| 56 | { | ||
| 57 | if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) | ||
| 58 | return sprintf(buf, "Mitigation: execute trampolines\n"); | ||
| 59 | if (__test_facility(82, S390_lowcore.alt_stfle_fac_list)) | ||
| 60 | return sprintf(buf, "Mitigation: limited branch prediction.\n"); | ||
| 61 | return sprintf(buf, "Vulnerable\n"); | ||
| 62 | } | ||
| 63 | #endif | ||
| 64 | |||
| 65 | #ifdef CONFIG_EXPOLINE | 46 | #ifdef CONFIG_EXPOLINE |
| 66 | 47 | ||
| 67 | int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF); | 48 | int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF); |
| @@ -112,7 +93,6 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end) | |||
| 112 | s32 *epo; | 93 | s32 *epo; |
| 113 | 94 | ||
| 114 | /* Second part of the instruction replace is always a nop */ | 95 | /* Second part of the instruction replace is always a nop */ |
| 115 | memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4); | ||
| 116 | for (epo = start; epo < end; epo++) { | 96 | for (epo = start; epo < end; epo++) { |
| 117 | instr = (u8 *) epo + *epo; | 97 | instr = (u8 *) epo + *epo; |
| 118 | if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04) | 98 | if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04) |
| @@ -133,18 +113,34 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end) | |||
| 133 | br = thunk + (*(int *)(thunk + 2)) * 2; | 113 | br = thunk + (*(int *)(thunk + 2)) * 2; |
| 134 | else | 114 | else |
| 135 | continue; | 115 | continue; |
| 136 | if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0) | 116 | /* Check for unconditional branch 0x07f? or 0x47f???? */ |
| 117 | if ((br[0] & 0xbf) != 0x07 || (br[1] & 0xf0) != 0xf0) | ||
| 137 | continue; | 118 | continue; |
| 119 | |||
| 120 | memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x07, 0x00 }, 4); | ||
| 138 | switch (type) { | 121 | switch (type) { |
| 139 | case BRCL_EXPOLINE: | 122 | case BRCL_EXPOLINE: |
| 140 | /* brcl to thunk, replace with br + nop */ | ||
| 141 | insnbuf[0] = br[0]; | 123 | insnbuf[0] = br[0]; |
| 142 | insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); | 124 | insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); |
| 125 | if (br[0] == 0x47) { | ||
| 126 | /* brcl to b, replace with bc + nopr */ | ||
| 127 | insnbuf[2] = br[2]; | ||
| 128 | insnbuf[3] = br[3]; | ||
| 129 | } else { | ||
| 130 | /* brcl to br, replace with bcr + nop */ | ||
| 131 | } | ||
| 143 | break; | 132 | break; |
| 144 | case BRASL_EXPOLINE: | 133 | case BRASL_EXPOLINE: |
| 145 | /* brasl to thunk, replace with basr + nop */ | ||
| 146 | insnbuf[0] = 0x0d; | ||
| 147 | insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); | 134 | insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); |
| 135 | if (br[0] == 0x47) { | ||
| 136 | /* brasl to b, replace with bas + nopr */ | ||
| 137 | insnbuf[0] = 0x4d; | ||
| 138 | insnbuf[2] = br[2]; | ||
| 139 | insnbuf[3] = br[3]; | ||
| 140 | } else { | ||
| 141 | /* brasl to br, replace with basr + nop */ | ||
| 142 | insnbuf[0] = 0x0d; | ||
| 143 | } | ||
| 148 | break; | 144 | break; |
| 149 | } | 145 | } |
| 150 | 146 | ||
diff --git a/arch/s390/kernel/nospec-sysfs.c b/arch/s390/kernel/nospec-sysfs.c new file mode 100644 index 000000000000..8affad5f18cb --- /dev/null +++ b/arch/s390/kernel/nospec-sysfs.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | #include <linux/device.h> | ||
| 3 | #include <linux/cpu.h> | ||
| 4 | #include <asm/facility.h> | ||
| 5 | #include <asm/nospec-branch.h> | ||
| 6 | |||
| 7 | ssize_t cpu_show_spectre_v1(struct device *dev, | ||
| 8 | struct device_attribute *attr, char *buf) | ||
| 9 | { | ||
| 10 | return sprintf(buf, "Mitigation: __user pointer sanitization\n"); | ||
| 11 | } | ||
| 12 | |||
| 13 | ssize_t cpu_show_spectre_v2(struct device *dev, | ||
| 14 | struct device_attribute *attr, char *buf) | ||
| 15 | { | ||
| 16 | if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) | ||
| 17 | return sprintf(buf, "Mitigation: execute trampolines\n"); | ||
| 18 | if (__test_facility(82, S390_lowcore.alt_stfle_fac_list)) | ||
| 19 | return sprintf(buf, "Mitigation: limited branch prediction\n"); | ||
| 20 | return sprintf(buf, "Vulnerable\n"); | ||
| 21 | } | ||
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 1c9ddd7aa5ec..0292d68e7dde 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c | |||
| @@ -753,6 +753,10 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
| 753 | */ | 753 | */ |
| 754 | rate = 0; | 754 | rate = 0; |
| 755 | if (attr->freq) { | 755 | if (attr->freq) { |
| 756 | if (!attr->sample_freq) { | ||
| 757 | err = -EINVAL; | ||
| 758 | goto out; | ||
| 759 | } | ||
| 756 | rate = freq_to_sample_rate(&si, attr->sample_freq); | 760 | rate = freq_to_sample_rate(&si, attr->sample_freq); |
| 757 | rate = hw_limit_rate(&si, rate); | 761 | rate = hw_limit_rate(&si, rate); |
| 758 | attr->freq = 0; | 762 | attr->freq = 0; |
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index 73cc3750f0d3..7f14adf512c6 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S | |||
| @@ -7,8 +7,11 @@ | |||
| 7 | 7 | ||
| 8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
| 9 | #include <asm/asm-offsets.h> | 9 | #include <asm/asm-offsets.h> |
| 10 | #include <asm/nospec-insn.h> | ||
| 10 | #include <asm/sigp.h> | 11 | #include <asm/sigp.h> |
| 11 | 12 | ||
| 13 | GEN_BR_THUNK %r9 | ||
| 14 | |||
| 12 | # | 15 | # |
| 13 | # Issue "store status" for the current CPU to its prefix page | 16 | # Issue "store status" for the current CPU to its prefix page |
| 14 | # and call passed function afterwards | 17 | # and call passed function afterwards |
| @@ -67,9 +70,9 @@ ENTRY(store_status) | |||
| 67 | st %r4,0(%r1) | 70 | st %r4,0(%r1) |
| 68 | st %r5,4(%r1) | 71 | st %r5,4(%r1) |
| 69 | stg %r2,8(%r1) | 72 | stg %r2,8(%r1) |
| 70 | lgr %r1,%r2 | 73 | lgr %r9,%r2 |
| 71 | lgr %r2,%r3 | 74 | lgr %r2,%r3 |
| 72 | br %r1 | 75 | BR_EX %r9 |
| 73 | 76 | ||
| 74 | .section .bss | 77 | .section .bss |
| 75 | .align 8 | 78 | .align 8 |
diff --git a/arch/s390/kernel/swsusp.S b/arch/s390/kernel/swsusp.S index e99187149f17..a049a7b9d6e8 100644 --- a/arch/s390/kernel/swsusp.S +++ b/arch/s390/kernel/swsusp.S | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <asm/ptrace.h> | 13 | #include <asm/ptrace.h> |
| 14 | #include <asm/thread_info.h> | 14 | #include <asm/thread_info.h> |
| 15 | #include <asm/asm-offsets.h> | 15 | #include <asm/asm-offsets.h> |
| 16 | #include <asm/nospec-insn.h> | ||
| 16 | #include <asm/sigp.h> | 17 | #include <asm/sigp.h> |
| 17 | 18 | ||
| 18 | /* | 19 | /* |
| @@ -24,6 +25,8 @@ | |||
| 24 | * (see below) in the resume process. | 25 | * (see below) in the resume process. |
| 25 | * This function runs with disabled interrupts. | 26 | * This function runs with disabled interrupts. |
| 26 | */ | 27 | */ |
| 28 | GEN_BR_THUNK %r14 | ||
| 29 | |||
| 27 | .section .text | 30 | .section .text |
| 28 | ENTRY(swsusp_arch_suspend) | 31 | ENTRY(swsusp_arch_suspend) |
| 29 | stmg %r6,%r15,__SF_GPRS(%r15) | 32 | stmg %r6,%r15,__SF_GPRS(%r15) |
| @@ -103,7 +106,7 @@ ENTRY(swsusp_arch_suspend) | |||
| 103 | spx 0x318(%r1) | 106 | spx 0x318(%r1) |
| 104 | lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) | 107 | lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) |
| 105 | lghi %r2,0 | 108 | lghi %r2,0 |
| 106 | br %r14 | 109 | BR_EX %r14 |
| 107 | 110 | ||
| 108 | /* | 111 | /* |
| 109 | * Restore saved memory image to correct place and restore register context. | 112 | * Restore saved memory image to correct place and restore register context. |
| @@ -197,11 +200,10 @@ pgm_check_entry: | |||
| 197 | larl %r15,init_thread_union | 200 | larl %r15,init_thread_union |
| 198 | ahi %r15,1<<(PAGE_SHIFT+THREAD_SIZE_ORDER) | 201 | ahi %r15,1<<(PAGE_SHIFT+THREAD_SIZE_ORDER) |
| 199 | larl %r2,.Lpanic_string | 202 | larl %r2,.Lpanic_string |
| 200 | larl %r3,sclp_early_printk | ||
| 201 | lghi %r1,0 | 203 | lghi %r1,0 |
| 202 | sam31 | 204 | sam31 |
| 203 | sigp %r1,%r0,SIGP_SET_ARCHITECTURE | 205 | sigp %r1,%r0,SIGP_SET_ARCHITECTURE |
| 204 | basr %r14,%r3 | 206 | brasl %r14,sclp_early_printk |
| 205 | larl %r3,.Ldisabled_wait_31 | 207 | larl %r3,.Ldisabled_wait_31 |
| 206 | lpsw 0(%r3) | 208 | lpsw 0(%r3) |
| 207 | 4: | 209 | 4: |
| @@ -267,7 +269,7 @@ restore_registers: | |||
| 267 | /* Return 0 */ | 269 | /* Return 0 */ |
| 268 | lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) | 270 | lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) |
| 269 | lghi %r2,0 | 271 | lghi %r2,0 |
| 270 | br %r14 | 272 | BR_EX %r14 |
| 271 | 273 | ||
| 272 | .section .data..nosave,"aw",@progbits | 274 | .section .data..nosave,"aw",@progbits |
| 273 | .align 8 | 275 | .align 8 |
diff --git a/arch/s390/lib/mem.S b/arch/s390/lib/mem.S index 495c9c4bacc7..2311f15be9cf 100644 --- a/arch/s390/lib/mem.S +++ b/arch/s390/lib/mem.S | |||
| @@ -7,6 +7,9 @@ | |||
| 7 | 7 | ||
| 8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
| 9 | #include <asm/export.h> | 9 | #include <asm/export.h> |
| 10 | #include <asm/nospec-insn.h> | ||
| 11 | |||
| 12 | GEN_BR_THUNK %r14 | ||
| 10 | 13 | ||
| 11 | /* | 14 | /* |
| 12 | * void *memmove(void *dest, const void *src, size_t n) | 15 | * void *memmove(void *dest, const void *src, size_t n) |
| @@ -33,14 +36,14 @@ ENTRY(memmove) | |||
| 33 | .Lmemmove_forward_remainder: | 36 | .Lmemmove_forward_remainder: |
| 34 | larl %r5,.Lmemmove_mvc | 37 | larl %r5,.Lmemmove_mvc |
| 35 | ex %r4,0(%r5) | 38 | ex %r4,0(%r5) |
| 36 | br %r14 | 39 | BR_EX %r14 |
| 37 | .Lmemmove_reverse: | 40 | .Lmemmove_reverse: |
| 38 | ic %r0,0(%r4,%r3) | 41 | ic %r0,0(%r4,%r3) |
| 39 | stc %r0,0(%r4,%r1) | 42 | stc %r0,0(%r4,%r1) |
| 40 | brctg %r4,.Lmemmove_reverse | 43 | brctg %r4,.Lmemmove_reverse |
| 41 | ic %r0,0(%r4,%r3) | 44 | ic %r0,0(%r4,%r3) |
| 42 | stc %r0,0(%r4,%r1) | 45 | stc %r0,0(%r4,%r1) |
| 43 | br %r14 | 46 | BR_EX %r14 |
| 44 | .Lmemmove_mvc: | 47 | .Lmemmove_mvc: |
| 45 | mvc 0(1,%r1),0(%r3) | 48 | mvc 0(1,%r1),0(%r3) |
| 46 | EXPORT_SYMBOL(memmove) | 49 | EXPORT_SYMBOL(memmove) |
| @@ -77,7 +80,7 @@ ENTRY(memset) | |||
| 77 | .Lmemset_clear_remainder: | 80 | .Lmemset_clear_remainder: |
| 78 | larl %r3,.Lmemset_xc | 81 | larl %r3,.Lmemset_xc |
| 79 | ex %r4,0(%r3) | 82 | ex %r4,0(%r3) |
| 80 | br %r14 | 83 | BR_EX %r14 |
| 81 | .Lmemset_fill: | 84 | .Lmemset_fill: |
| 82 | cghi %r4,1 | 85 | cghi %r4,1 |
| 83 | lgr %r1,%r2 | 86 | lgr %r1,%r2 |
| @@ -95,10 +98,10 @@ ENTRY(memset) | |||
| 95 | stc %r3,0(%r1) | 98 | stc %r3,0(%r1) |
| 96 | larl %r5,.Lmemset_mvc | 99 | larl %r5,.Lmemset_mvc |
| 97 | ex %r4,0(%r5) | 100 | ex %r4,0(%r5) |
| 98 | br %r14 | 101 | BR_EX %r14 |
| 99 | .Lmemset_fill_exit: | 102 | .Lmemset_fill_exit: |
| 100 | stc %r3,0(%r1) | 103 | stc %r3,0(%r1) |
| 101 | br %r14 | 104 | BR_EX %r14 |
| 102 | .Lmemset_xc: | 105 | .Lmemset_xc: |
| 103 | xc 0(1,%r1),0(%r1) | 106 | xc 0(1,%r1),0(%r1) |
| 104 | .Lmemset_mvc: | 107 | .Lmemset_mvc: |
| @@ -121,7 +124,7 @@ ENTRY(memcpy) | |||
| 121 | .Lmemcpy_remainder: | 124 | .Lmemcpy_remainder: |
| 122 | larl %r5,.Lmemcpy_mvc | 125 | larl %r5,.Lmemcpy_mvc |
| 123 | ex %r4,0(%r5) | 126 | ex %r4,0(%r5) |
| 124 | br %r14 | 127 | BR_EX %r14 |
| 125 | .Lmemcpy_loop: | 128 | .Lmemcpy_loop: |
| 126 | mvc 0(256,%r1),0(%r3) | 129 | mvc 0(256,%r1),0(%r3) |
| 127 | la %r1,256(%r1) | 130 | la %r1,256(%r1) |
| @@ -159,10 +162,10 @@ ENTRY(__memset\bits) | |||
| 159 | \insn %r3,0(%r1) | 162 | \insn %r3,0(%r1) |
| 160 | larl %r5,.L__memset_mvc\bits | 163 | larl %r5,.L__memset_mvc\bits |
| 161 | ex %r4,0(%r5) | 164 | ex %r4,0(%r5) |
| 162 | br %r14 | 165 | BR_EX %r14 |
| 163 | .L__memset_exit\bits: | 166 | .L__memset_exit\bits: |
| 164 | \insn %r3,0(%r2) | 167 | \insn %r3,0(%r2) |
| 165 | br %r14 | 168 | BR_EX %r14 |
| 166 | .L__memset_mvc\bits: | 169 | .L__memset_mvc\bits: |
| 167 | mvc \bytes(1,%r1),0(%r1) | 170 | mvc \bytes(1,%r1),0(%r1) |
| 168 | .endm | 171 | .endm |
diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S index 25bb4643c4f4..9f794869c1b0 100644 --- a/arch/s390/net/bpf_jit.S +++ b/arch/s390/net/bpf_jit.S | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
| 12 | #include <asm/nospec-insn.h> | ||
| 12 | #include "bpf_jit.h" | 13 | #include "bpf_jit.h" |
| 13 | 14 | ||
| 14 | /* | 15 | /* |
| @@ -54,7 +55,7 @@ ENTRY(sk_load_##NAME##_pos); \ | |||
| 54 | clg %r3,STK_OFF_HLEN(%r15); /* Offset + SIZE > hlen? */ \ | 55 | clg %r3,STK_OFF_HLEN(%r15); /* Offset + SIZE > hlen? */ \ |
| 55 | jh sk_load_##NAME##_slow; \ | 56 | jh sk_load_##NAME##_slow; \ |
| 56 | LOAD %r14,-SIZE(%r3,%r12); /* Get data from skb */ \ | 57 | LOAD %r14,-SIZE(%r3,%r12); /* Get data from skb */ \ |
| 57 | b OFF_OK(%r6); /* Return */ \ | 58 | B_EX OFF_OK,%r6; /* Return */ \ |
| 58 | \ | 59 | \ |
| 59 | sk_load_##NAME##_slow:; \ | 60 | sk_load_##NAME##_slow:; \ |
| 60 | lgr %r2,%r7; /* Arg1 = skb pointer */ \ | 61 | lgr %r2,%r7; /* Arg1 = skb pointer */ \ |
| @@ -64,11 +65,14 @@ sk_load_##NAME##_slow:; \ | |||
| 64 | brasl %r14,skb_copy_bits; /* Get data from skb */ \ | 65 | brasl %r14,skb_copy_bits; /* Get data from skb */ \ |
| 65 | LOAD %r14,STK_OFF_TMP(%r15); /* Load from temp bufffer */ \ | 66 | LOAD %r14,STK_OFF_TMP(%r15); /* Load from temp bufffer */ \ |
| 66 | ltgr %r2,%r2; /* Set cc to (%r2 != 0) */ \ | 67 | ltgr %r2,%r2; /* Set cc to (%r2 != 0) */ \ |
| 67 | br %r6; /* Return */ | 68 | BR_EX %r6; /* Return */ |
| 68 | 69 | ||
| 69 | sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */ | 70 | sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */ |
| 70 | sk_load_common(half, 2, llgh) /* r14 = *(u16 *) (skb->data+offset) */ | 71 | sk_load_common(half, 2, llgh) /* r14 = *(u16 *) (skb->data+offset) */ |
| 71 | 72 | ||
| 73 | GEN_BR_THUNK %r6 | ||
| 74 | GEN_B_THUNK OFF_OK,%r6 | ||
| 75 | |||
| 72 | /* | 76 | /* |
| 73 | * Load 1 byte from SKB (optimized version) | 77 | * Load 1 byte from SKB (optimized version) |
| 74 | */ | 78 | */ |
| @@ -80,7 +84,7 @@ ENTRY(sk_load_byte_pos) | |||
| 80 | clg %r3,STK_OFF_HLEN(%r15) # Offset >= hlen? | 84 | clg %r3,STK_OFF_HLEN(%r15) # Offset >= hlen? |
| 81 | jnl sk_load_byte_slow | 85 | jnl sk_load_byte_slow |
| 82 | llgc %r14,0(%r3,%r12) # Get byte from skb | 86 | llgc %r14,0(%r3,%r12) # Get byte from skb |
| 83 | b OFF_OK(%r6) # Return OK | 87 | B_EX OFF_OK,%r6 # Return OK |
| 84 | 88 | ||
| 85 | sk_load_byte_slow: | 89 | sk_load_byte_slow: |
| 86 | lgr %r2,%r7 # Arg1 = skb pointer | 90 | lgr %r2,%r7 # Arg1 = skb pointer |
| @@ -90,7 +94,7 @@ sk_load_byte_slow: | |||
| 90 | brasl %r14,skb_copy_bits # Get data from skb | 94 | brasl %r14,skb_copy_bits # Get data from skb |
| 91 | llgc %r14,STK_OFF_TMP(%r15) # Load result from temp buffer | 95 | llgc %r14,STK_OFF_TMP(%r15) # Load result from temp buffer |
| 92 | ltgr %r2,%r2 # Set cc to (%r2 != 0) | 96 | ltgr %r2,%r2 # Set cc to (%r2 != 0) |
| 93 | br %r6 # Return cc | 97 | BR_EX %r6 # Return cc |
| 94 | 98 | ||
| 95 | #define sk_negative_common(NAME, SIZE, LOAD) \ | 99 | #define sk_negative_common(NAME, SIZE, LOAD) \ |
| 96 | sk_load_##NAME##_slow_neg:; \ | 100 | sk_load_##NAME##_slow_neg:; \ |
| @@ -104,7 +108,7 @@ sk_load_##NAME##_slow_neg:; \ | |||
| 104 | jz bpf_error; \ | 108 | jz bpf_error; \ |
| 105 | LOAD %r14,0(%r2); /* Get data from pointer */ \ | 109 | LOAD %r14,0(%r2); /* Get data from pointer */ \ |
| 106 | xr %r3,%r3; /* Set cc to zero */ \ | 110 | xr %r3,%r3; /* Set cc to zero */ \ |
| 107 | br %r6; /* Return cc */ | 111 | BR_EX %r6; /* Return cc */ |
| 108 | 112 | ||
| 109 | sk_negative_common(word, 4, llgf) | 113 | sk_negative_common(word, 4, llgf) |
| 110 | sk_negative_common(half, 2, llgh) | 114 | sk_negative_common(half, 2, llgh) |
| @@ -113,4 +117,4 @@ sk_negative_common(byte, 1, llgc) | |||
| 113 | bpf_error: | 117 | bpf_error: |
| 114 | # force a return 0 from jit handler | 118 | # force a return 0 from jit handler |
| 115 | ltgr %r15,%r15 # Set condition code | 119 | ltgr %r15,%r15 # Set condition code |
| 116 | br %r6 | 120 | BR_EX %r6 |
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 78a19c93b380..dd2bcf0e7d00 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include <linux/bpf.h> | 25 | #include <linux/bpf.h> |
| 26 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
| 27 | #include <asm/dis.h> | 27 | #include <asm/dis.h> |
| 28 | #include <asm/facility.h> | ||
| 29 | #include <asm/nospec-branch.h> | ||
| 28 | #include <asm/set_memory.h> | 30 | #include <asm/set_memory.h> |
| 29 | #include "bpf_jit.h" | 31 | #include "bpf_jit.h" |
| 30 | 32 | ||
| @@ -41,6 +43,8 @@ struct bpf_jit { | |||
| 41 | int base_ip; /* Base address for literal pool */ | 43 | int base_ip; /* Base address for literal pool */ |
| 42 | int ret0_ip; /* Address of return 0 */ | 44 | int ret0_ip; /* Address of return 0 */ |
| 43 | int exit_ip; /* Address of exit */ | 45 | int exit_ip; /* Address of exit */ |
| 46 | int r1_thunk_ip; /* Address of expoline thunk for 'br %r1' */ | ||
| 47 | int r14_thunk_ip; /* Address of expoline thunk for 'br %r14' */ | ||
| 44 | int tail_call_start; /* Tail call start offset */ | 48 | int tail_call_start; /* Tail call start offset */ |
| 45 | int labels[1]; /* Labels for local jumps */ | 49 | int labels[1]; /* Labels for local jumps */ |
| 46 | }; | 50 | }; |
| @@ -250,6 +254,19 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1) | |||
| 250 | REG_SET_SEEN(b2); \ | 254 | REG_SET_SEEN(b2); \ |
| 251 | }) | 255 | }) |
| 252 | 256 | ||
| 257 | #define EMIT6_PCREL_RILB(op, b, target) \ | ||
| 258 | ({ \ | ||
| 259 | int rel = (target - jit->prg) / 2; \ | ||
| 260 | _EMIT6(op | reg_high(b) << 16 | rel >> 16, rel & 0xffff); \ | ||
| 261 | REG_SET_SEEN(b); \ | ||
| 262 | }) | ||
| 263 | |||
| 264 | #define EMIT6_PCREL_RIL(op, target) \ | ||
| 265 | ({ \ | ||
| 266 | int rel = (target - jit->prg) / 2; \ | ||
| 267 | _EMIT6(op | rel >> 16, rel & 0xffff); \ | ||
| 268 | }) | ||
| 269 | |||
| 253 | #define _EMIT6_IMM(op, imm) \ | 270 | #define _EMIT6_IMM(op, imm) \ |
| 254 | ({ \ | 271 | ({ \ |
| 255 | unsigned int __imm = (imm); \ | 272 | unsigned int __imm = (imm); \ |
| @@ -469,8 +486,45 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth) | |||
| 469 | EMIT4(0xb9040000, REG_2, BPF_REG_0); | 486 | EMIT4(0xb9040000, REG_2, BPF_REG_0); |
| 470 | /* Restore registers */ | 487 | /* Restore registers */ |
| 471 | save_restore_regs(jit, REGS_RESTORE, stack_depth); | 488 | save_restore_regs(jit, REGS_RESTORE, stack_depth); |
| 489 | if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) { | ||
| 490 | jit->r14_thunk_ip = jit->prg; | ||
| 491 | /* Generate __s390_indirect_jump_r14 thunk */ | ||
| 492 | if (test_facility(35)) { | ||
| 493 | /* exrl %r0,.+10 */ | ||
| 494 | EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10); | ||
| 495 | } else { | ||
| 496 | /* larl %r1,.+14 */ | ||
| 497 | EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14); | ||
| 498 | /* ex 0,0(%r1) */ | ||
| 499 | EMIT4_DISP(0x44000000, REG_0, REG_1, 0); | ||
| 500 | } | ||
| 501 | /* j . */ | ||
| 502 | EMIT4_PCREL(0xa7f40000, 0); | ||
| 503 | } | ||
| 472 | /* br %r14 */ | 504 | /* br %r14 */ |
| 473 | _EMIT2(0x07fe); | 505 | _EMIT2(0x07fe); |
| 506 | |||
| 507 | if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable && | ||
| 508 | (jit->seen & SEEN_FUNC)) { | ||
| 509 | jit->r1_thunk_ip = jit->prg; | ||
| 510 | /* Generate __s390_indirect_jump_r1 thunk */ | ||
| 511 | if (test_facility(35)) { | ||
| 512 | /* exrl %r0,.+10 */ | ||
| 513 | EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10); | ||
| 514 | /* j . */ | ||
| 515 | EMIT4_PCREL(0xa7f40000, 0); | ||
| 516 | /* br %r1 */ | ||
| 517 | _EMIT2(0x07f1); | ||
| 518 | } else { | ||
| 519 | /* larl %r1,.+14 */ | ||
| 520 | EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14); | ||
| 521 | /* ex 0,S390_lowcore.br_r1_tampoline */ | ||
| 522 | EMIT4_DISP(0x44000000, REG_0, REG_0, | ||
| 523 | offsetof(struct lowcore, br_r1_trampoline)); | ||
| 524 | /* j . */ | ||
| 525 | EMIT4_PCREL(0xa7f40000, 0); | ||
| 526 | } | ||
| 527 | } | ||
| 474 | } | 528 | } |
| 475 | 529 | ||
| 476 | /* | 530 | /* |
| @@ -966,8 +1020,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i | |||
| 966 | /* lg %w1,<d(imm)>(%l) */ | 1020 | /* lg %w1,<d(imm)>(%l) */ |
| 967 | EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L, | 1021 | EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L, |
| 968 | EMIT_CONST_U64(func)); | 1022 | EMIT_CONST_U64(func)); |
| 969 | /* basr %r14,%w1 */ | 1023 | if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) { |
| 970 | EMIT2(0x0d00, REG_14, REG_W1); | 1024 | /* brasl %r14,__s390_indirect_jump_r1 */ |
| 1025 | EMIT6_PCREL_RILB(0xc0050000, REG_14, jit->r1_thunk_ip); | ||
| 1026 | } else { | ||
| 1027 | /* basr %r14,%w1 */ | ||
| 1028 | EMIT2(0x0d00, REG_14, REG_W1); | ||
| 1029 | } | ||
| 971 | /* lgr %b0,%r2: load return value into %b0 */ | 1030 | /* lgr %b0,%r2: load return value into %b0 */ |
| 972 | EMIT4(0xb9040000, BPF_REG_0, REG_2); | 1031 | EMIT4(0xb9040000, BPF_REG_0, REG_2); |
| 973 | if ((jit->seen & SEEN_SKB) && | 1032 | if ((jit->seen & SEEN_SKB) && |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 97fe29316476..1851eaeee131 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
| @@ -9,6 +9,7 @@ config SUPERH | |||
| 9 | select HAVE_IDE if HAS_IOPORT_MAP | 9 | select HAVE_IDE if HAS_IOPORT_MAP |
| 10 | select HAVE_MEMBLOCK | 10 | select HAVE_MEMBLOCK |
| 11 | select HAVE_MEMBLOCK_NODE_MAP | 11 | select HAVE_MEMBLOCK_NODE_MAP |
| 12 | select NO_BOOTMEM | ||
| 12 | select ARCH_DISCARD_MEMBLOCK | 13 | select ARCH_DISCARD_MEMBLOCK |
| 13 | select HAVE_OPROFILE | 14 | select HAVE_OPROFILE |
| 14 | select HAVE_GENERIC_DMA_COHERENT | 15 | select HAVE_GENERIC_DMA_COHERENT |
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 4205f6d42b69..a5bd03642678 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c | |||
| @@ -43,7 +43,11 @@ void __ref cpu_probe(void) | |||
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | #if defined(CONFIG_CPU_J2) | 45 | #if defined(CONFIG_CPU_J2) |
| 46 | #if defined(CONFIG_SMP) | ||
| 46 | unsigned cpu = hard_smp_processor_id(); | 47 | unsigned cpu = hard_smp_processor_id(); |
| 48 | #else | ||
| 49 | unsigned cpu = 0; | ||
| 50 | #endif | ||
| 47 | if (cpu == 0) of_scan_flat_dt(scan_cache, NULL); | 51 | if (cpu == 0) of_scan_flat_dt(scan_cache, NULL); |
| 48 | if (j2_ccr_base) __raw_writel(0x80000303, j2_ccr_base + 4*cpu); | 52 | if (j2_ccr_base) __raw_writel(0x80000303, j2_ccr_base + 4*cpu); |
| 49 | if (cpu != 0) return; | 53 | if (cpu != 0) return; |
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index d34e998b809f..c286cf5da6e7 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <linux/ioport.h> | 11 | #include <linux/ioport.h> |
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/initrd.h> | 13 | #include <linux/initrd.h> |
| 14 | #include <linux/bootmem.h> | ||
| 15 | #include <linux/console.h> | 14 | #include <linux/console.h> |
| 16 | #include <linux/root_dev.h> | 15 | #include <linux/root_dev.h> |
| 17 | #include <linux/utsname.h> | 16 | #include <linux/utsname.h> |
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index 8ce98691d822..f1b44697ad68 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c | |||
| @@ -59,7 +59,9 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, | |||
| 59 | 59 | ||
| 60 | split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order); | 60 | split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order); |
| 61 | 61 | ||
| 62 | *dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset); | 62 | *dma_handle = virt_to_phys(ret); |
| 63 | if (!WARN_ON(!dev)) | ||
| 64 | *dma_handle -= PFN_PHYS(dev->dma_pfn_offset); | ||
| 63 | 65 | ||
| 64 | return ret_nocache; | 66 | return ret_nocache; |
| 65 | } | 67 | } |
| @@ -69,9 +71,12 @@ void dma_generic_free_coherent(struct device *dev, size_t size, | |||
| 69 | unsigned long attrs) | 71 | unsigned long attrs) |
| 70 | { | 72 | { |
| 71 | int order = get_order(size); | 73 | int order = get_order(size); |
| 72 | unsigned long pfn = (dma_handle >> PAGE_SHIFT) + dev->dma_pfn_offset; | 74 | unsigned long pfn = dma_handle >> PAGE_SHIFT; |
| 73 | int k; | 75 | int k; |
| 74 | 76 | ||
| 77 | if (!WARN_ON(!dev)) | ||
| 78 | pfn += dev->dma_pfn_offset; | ||
| 79 | |||
| 75 | for (k = 0; k < (1 << order); k++) | 80 | for (k = 0; k < (1 << order); k++) |
| 76 | __free_pages(pfn_to_page(pfn + k), 0); | 81 | __free_pages(pfn_to_page(pfn + k), 0); |
| 77 | 82 | ||
| @@ -143,7 +148,7 @@ int __init platform_resource_setup_memory(struct platform_device *pdev, | |||
| 143 | if (!memsize) | 148 | if (!memsize) |
| 144 | return 0; | 149 | return 0; |
| 145 | 150 | ||
| 146 | buf = dma_alloc_coherent(NULL, memsize, &dma_handle, GFP_KERNEL); | 151 | buf = dma_alloc_coherent(&pdev->dev, memsize, &dma_handle, GFP_KERNEL); |
| 147 | if (!buf) { | 152 | if (!buf) { |
| 148 | pr_warning("%s: unable to allocate memory\n", name); | 153 | pr_warning("%s: unable to allocate memory\n", name); |
| 149 | return -ENOMEM; | 154 | return -ENOMEM; |
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index ce0bbaa7e404..4034035fbede 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c | |||
| @@ -211,59 +211,15 @@ void __init allocate_pgdat(unsigned int nid) | |||
| 211 | 211 | ||
| 212 | NODE_DATA(nid) = __va(phys); | 212 | NODE_DATA(nid) = __va(phys); |
| 213 | memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); | 213 | memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); |
| 214 | |||
| 215 | NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; | ||
| 216 | #endif | 214 | #endif |
| 217 | 215 | ||
| 218 | NODE_DATA(nid)->node_start_pfn = start_pfn; | 216 | NODE_DATA(nid)->node_start_pfn = start_pfn; |
| 219 | NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; | 217 | NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; |
| 220 | } | 218 | } |
| 221 | 219 | ||
| 222 | static void __init bootmem_init_one_node(unsigned int nid) | ||
| 223 | { | ||
| 224 | unsigned long total_pages, paddr; | ||
| 225 | unsigned long end_pfn; | ||
| 226 | struct pglist_data *p; | ||
| 227 | |||
| 228 | p = NODE_DATA(nid); | ||
| 229 | |||
| 230 | /* Nothing to do.. */ | ||
| 231 | if (!p->node_spanned_pages) | ||
| 232 | return; | ||
| 233 | |||
| 234 | end_pfn = pgdat_end_pfn(p); | ||
| 235 | |||
| 236 | total_pages = bootmem_bootmap_pages(p->node_spanned_pages); | ||
| 237 | |||
| 238 | paddr = memblock_alloc(total_pages << PAGE_SHIFT, PAGE_SIZE); | ||
| 239 | if (!paddr) | ||
| 240 | panic("Can't allocate bootmap for nid[%d]\n", nid); | ||
| 241 | |||
| 242 | init_bootmem_node(p, paddr >> PAGE_SHIFT, p->node_start_pfn, end_pfn); | ||
| 243 | |||
| 244 | free_bootmem_with_active_regions(nid, end_pfn); | ||
| 245 | |||
| 246 | /* | ||
| 247 | * XXX Handle initial reservations for the system memory node | ||
| 248 | * only for the moment, we'll refactor this later for handling | ||
| 249 | * reservations in other nodes. | ||
| 250 | */ | ||
| 251 | if (nid == 0) { | ||
| 252 | struct memblock_region *reg; | ||
| 253 | |||
| 254 | /* Reserve the sections we're already using. */ | ||
| 255 | for_each_memblock(reserved, reg) { | ||
| 256 | reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 260 | sparse_memory_present_with_active_regions(nid); | ||
| 261 | } | ||
| 262 | |||
| 263 | static void __init do_init_bootmem(void) | 220 | static void __init do_init_bootmem(void) |
| 264 | { | 221 | { |
| 265 | struct memblock_region *reg; | 222 | struct memblock_region *reg; |
| 266 | int i; | ||
| 267 | 223 | ||
| 268 | /* Add active regions with valid PFNs. */ | 224 | /* Add active regions with valid PFNs. */ |
| 269 | for_each_memblock(memory, reg) { | 225 | for_each_memblock(memory, reg) { |
| @@ -279,9 +235,12 @@ static void __init do_init_bootmem(void) | |||
| 279 | 235 | ||
| 280 | plat_mem_setup(); | 236 | plat_mem_setup(); |
| 281 | 237 | ||
| 282 | for_each_online_node(i) | 238 | for_each_memblock(memory, reg) { |
| 283 | bootmem_init_one_node(i); | 239 | int nid = memblock_get_region_node(reg); |
| 284 | 240 | ||
| 241 | memory_present(nid, memblock_region_memory_base_pfn(reg), | ||
| 242 | memblock_region_memory_end_pfn(reg)); | ||
| 243 | } | ||
| 285 | sparse_init(); | 244 | sparse_init(); |
| 286 | } | 245 | } |
| 287 | 246 | ||
| @@ -322,7 +281,6 @@ void __init paging_init(void) | |||
| 322 | { | 281 | { |
| 323 | unsigned long max_zone_pfns[MAX_NR_ZONES]; | 282 | unsigned long max_zone_pfns[MAX_NR_ZONES]; |
| 324 | unsigned long vaddr, end; | 283 | unsigned long vaddr, end; |
| 325 | int nid; | ||
| 326 | 284 | ||
| 327 | sh_mv.mv_mem_init(); | 285 | sh_mv.mv_mem_init(); |
| 328 | 286 | ||
| @@ -377,21 +335,7 @@ void __init paging_init(void) | |||
| 377 | kmap_coherent_init(); | 335 | kmap_coherent_init(); |
| 378 | 336 | ||
| 379 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); | 337 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); |
| 380 | 338 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; | |
| 381 | for_each_online_node(nid) { | ||
| 382 | pg_data_t *pgdat = NODE_DATA(nid); | ||
| 383 | unsigned long low, start_pfn; | ||
| 384 | |||
| 385 | start_pfn = pgdat->bdata->node_min_pfn; | ||
| 386 | low = pgdat->bdata->node_low_pfn; | ||
| 387 | |||
| 388 | if (max_zone_pfns[ZONE_NORMAL] < low) | ||
| 389 | max_zone_pfns[ZONE_NORMAL] = low; | ||
| 390 | |||
| 391 | printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n", | ||
| 392 | nid, start_pfn, low); | ||
| 393 | } | ||
| 394 | |||
| 395 | free_area_init_nodes(max_zone_pfns); | 339 | free_area_init_nodes(max_zone_pfns); |
| 396 | } | 340 | } |
| 397 | 341 | ||
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c index 05713d190247..830e8b3684e4 100644 --- a/arch/sh/mm/numa.c +++ b/arch/sh/mm/numa.c | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | * for more details. | 8 | * for more details. |
| 9 | */ | 9 | */ |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/bootmem.h> | ||
| 12 | #include <linux/memblock.h> | 11 | #include <linux/memblock.h> |
| 13 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
| 14 | #include <linux/numa.h> | 13 | #include <linux/numa.h> |
| @@ -26,9 +25,7 @@ EXPORT_SYMBOL_GPL(node_data); | |||
| 26 | */ | 25 | */ |
| 27 | void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) | 26 | void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) |
| 28 | { | 27 | { |
| 29 | unsigned long bootmap_pages; | ||
| 30 | unsigned long start_pfn, end_pfn; | 28 | unsigned long start_pfn, end_pfn; |
| 31 | unsigned long bootmem_paddr; | ||
| 32 | 29 | ||
| 33 | /* Don't allow bogus node assignment */ | 30 | /* Don't allow bogus node assignment */ |
| 34 | BUG_ON(nid >= MAX_NUMNODES || nid <= 0); | 31 | BUG_ON(nid >= MAX_NUMNODES || nid <= 0); |
| @@ -48,25 +45,9 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) | |||
| 48 | SMP_CACHE_BYTES, end)); | 45 | SMP_CACHE_BYTES, end)); |
| 49 | memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); | 46 | memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); |
| 50 | 47 | ||
| 51 | NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; | ||
| 52 | NODE_DATA(nid)->node_start_pfn = start_pfn; | 48 | NODE_DATA(nid)->node_start_pfn = start_pfn; |
| 53 | NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; | 49 | NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; |
| 54 | 50 | ||
| 55 | /* Node-local bootmap */ | ||
| 56 | bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); | ||
| 57 | bootmem_paddr = memblock_alloc_base(bootmap_pages << PAGE_SHIFT, | ||
| 58 | PAGE_SIZE, end); | ||
| 59 | init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, | ||
| 60 | start_pfn, end_pfn); | ||
| 61 | |||
| 62 | free_bootmem_with_active_regions(nid, end_pfn); | ||
| 63 | |||
| 64 | /* Reserve the pgdat and bootmap space with the bootmem allocator */ | ||
| 65 | reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT, | ||
| 66 | sizeof(struct pglist_data), BOOTMEM_DEFAULT); | ||
| 67 | reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr, | ||
| 68 | bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); | ||
| 69 | |||
| 70 | /* It's up */ | 51 | /* It's up */ |
| 71 | node_set_online(nid); | 52 | node_set_online(nid); |
| 72 | 53 | ||
diff --git a/arch/sparc/include/uapi/asm/oradax.h b/arch/sparc/include/uapi/asm/oradax.h index 722951908b0a..4f6676fe4bcc 100644 --- a/arch/sparc/include/uapi/asm/oradax.h +++ b/arch/sparc/include/uapi/asm/oradax.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * This program is free software: you can redistribute it and/or modify | 4 | * This program is free software: you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation, either version 3 of the License, or | 6 | * the Free Software Foundation, either version 2 of the License, or |
| 7 | * (at your option) any later version. | 7 | * (at your option) any later version. |
| 8 | * | 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, | 9 | * This program is distributed in the hope that it will be useful, |
diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 1a0fa10cb6b7..32bae68e34c1 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c | |||
| @@ -403,7 +403,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
| 403 | if (err) { | 403 | if (err) { |
| 404 | printk(KERN_ERR "VIO: Could not register device %s, err=%d\n", | 404 | printk(KERN_ERR "VIO: Could not register device %s, err=%d\n", |
| 405 | dev_name(&vdev->dev), err); | 405 | dev_name(&vdev->dev), err); |
| 406 | kfree(vdev); | 406 | put_device(&vdev->dev); |
| 407 | return NULL; | 407 | return NULL; |
| 408 | } | 408 | } |
| 409 | if (vdev->dp) | 409 | if (vdev->dp) |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 47d3efff6805..09f36c0d9d4f 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
| @@ -163,7 +163,8 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) | |||
| 163 | if (status != EFI_SUCCESS) | 163 | if (status != EFI_SUCCESS) |
| 164 | goto free_struct; | 164 | goto free_struct; |
| 165 | 165 | ||
| 166 | memcpy(rom->romdata, pci->romimage, pci->romsize); | 166 | memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, |
| 167 | pci->romsize); | ||
| 167 | return status; | 168 | return status; |
| 168 | 169 | ||
| 169 | free_struct: | 170 | free_struct: |
| @@ -269,7 +270,8 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) | |||
| 269 | if (status != EFI_SUCCESS) | 270 | if (status != EFI_SUCCESS) |
| 270 | goto free_struct; | 271 | goto free_struct; |
| 271 | 272 | ||
| 272 | memcpy(rom->romdata, pci->romimage, pci->romsize); | 273 | memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, |
| 274 | pci->romsize); | ||
| 273 | return status; | 275 | return status; |
| 274 | 276 | ||
| 275 | free_struct: | 277 | free_struct: |
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index fca012baba19..8169e8b7a4dc 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
| @@ -306,6 +306,25 @@ ENTRY(startup_64) | |||
| 306 | leaq boot_stack_end(%rbx), %rsp | 306 | leaq boot_stack_end(%rbx), %rsp |
| 307 | 307 | ||
| 308 | /* | 308 | /* |
| 309 | * paging_prepare() and cleanup_trampoline() below can have GOT | ||
| 310 | * references. Adjust the table with address we are running at. | ||
| 311 | * | ||
| 312 | * Zero RAX for adjust_got: the GOT was not adjusted before; | ||
| 313 | * there's no adjustment to undo. | ||
| 314 | */ | ||
| 315 | xorq %rax, %rax | ||
| 316 | |||
| 317 | /* | ||
| 318 | * Calculate the address the binary is loaded at and use it as | ||
| 319 | * a GOT adjustment. | ||
| 320 | */ | ||
| 321 | call 1f | ||
| 322 | 1: popq %rdi | ||
| 323 | subq $1b, %rdi | ||
| 324 | |||
| 325 | call adjust_got | ||
| 326 | |||
| 327 | /* | ||
| 309 | * At this point we are in long mode with 4-level paging enabled, | 328 | * At this point we are in long mode with 4-level paging enabled, |
| 310 | * but we might want to enable 5-level paging or vice versa. | 329 | * but we might want to enable 5-level paging or vice versa. |
| 311 | * | 330 | * |
| @@ -370,10 +389,14 @@ trampoline_return: | |||
| 370 | /* | 389 | /* |
| 371 | * cleanup_trampoline() would restore trampoline memory. | 390 | * cleanup_trampoline() would restore trampoline memory. |
| 372 | * | 391 | * |
| 392 | * RDI is address of the page table to use instead of page table | ||
| 393 | * in trampoline memory (if required). | ||
| 394 | * | ||
| 373 | * RSI holds real mode data and needs to be preserved across | 395 | * RSI holds real mode data and needs to be preserved across |
| 374 | * this function call. | 396 | * this function call. |
| 375 | */ | 397 | */ |
| 376 | pushq %rsi | 398 | pushq %rsi |
| 399 | leaq top_pgtable(%rbx), %rdi | ||
| 377 | call cleanup_trampoline | 400 | call cleanup_trampoline |
| 378 | popq %rsi | 401 | popq %rsi |
| 379 | 402 | ||
| @@ -381,6 +404,21 @@ trampoline_return: | |||
| 381 | pushq $0 | 404 | pushq $0 |
| 382 | popfq | 405 | popfq |
| 383 | 406 | ||
| 407 | /* | ||
| 408 | * Previously we've adjusted the GOT with address the binary was | ||
| 409 | * loaded at. Now we need to re-adjust for relocation address. | ||
| 410 | * | ||
| 411 | * Calculate the address the binary is loaded at, so that we can | ||
| 412 | * undo the previous GOT adjustment. | ||
| 413 | */ | ||
| 414 | call 1f | ||
| 415 | 1: popq %rax | ||
| 416 | subq $1b, %rax | ||
| 417 | |||
| 418 | /* The new adjustment is the relocation address */ | ||
| 419 | movq %rbx, %rdi | ||
| 420 | call adjust_got | ||
| 421 | |||
| 384 | /* | 422 | /* |
| 385 | * Copy the compressed kernel to the end of our buffer | 423 | * Copy the compressed kernel to the end of our buffer |
| 386 | * where decompression in place becomes safe. | 424 | * where decompression in place becomes safe. |
| @@ -482,19 +520,6 @@ relocated: | |||
| 482 | rep stosq | 520 | rep stosq |
| 483 | 521 | ||
| 484 | /* | 522 | /* |
| 485 | * Adjust our own GOT | ||
| 486 | */ | ||
| 487 | leaq _got(%rip), %rdx | ||
| 488 | leaq _egot(%rip), %rcx | ||
| 489 | 1: | ||
| 490 | cmpq %rcx, %rdx | ||
| 491 | jae 2f | ||
| 492 | addq %rbx, (%rdx) | ||
| 493 | addq $8, %rdx | ||
| 494 | jmp 1b | ||
| 495 | 2: | ||
| 496 | |||
| 497 | /* | ||
| 498 | * Do the extraction, and jump to the new kernel.. | 523 | * Do the extraction, and jump to the new kernel.. |
| 499 | */ | 524 | */ |
| 500 | pushq %rsi /* Save the real mode argument */ | 525 | pushq %rsi /* Save the real mode argument */ |
| @@ -512,6 +537,27 @@ relocated: | |||
| 512 | */ | 537 | */ |
| 513 | jmp *%rax | 538 | jmp *%rax |
| 514 | 539 | ||
| 540 | /* | ||
| 541 | * Adjust the global offset table | ||
| 542 | * | ||
| 543 | * RAX is the previous adjustment of the table to undo (use 0 if it's the | ||
| 544 | * first time we touch GOT). | ||
| 545 | * RDI is the new adjustment to apply. | ||
| 546 | */ | ||
| 547 | adjust_got: | ||
| 548 | /* Walk through the GOT adding the address to the entries */ | ||
| 549 | leaq _got(%rip), %rdx | ||
| 550 | leaq _egot(%rip), %rcx | ||
| 551 | 1: | ||
| 552 | cmpq %rcx, %rdx | ||
| 553 | jae 2f | ||
| 554 | subq %rax, (%rdx) /* Undo previous adjustment */ | ||
| 555 | addq %rdi, (%rdx) /* Apply the new adjustment */ | ||
| 556 | addq $8, %rdx | ||
| 557 | jmp 1b | ||
| 558 | 2: | ||
| 559 | ret | ||
| 560 | |||
| 515 | .code32 | 561 | .code32 |
| 516 | /* | 562 | /* |
| 517 | * This is the 32-bit trampoline that will be copied over to low memory. | 563 | * This is the 32-bit trampoline that will be copied over to low memory. |
| @@ -649,3 +695,10 @@ boot_stack_end: | |||
| 649 | .balign 4096 | 695 | .balign 4096 |
| 650 | pgtable: | 696 | pgtable: |
| 651 | .fill BOOT_PGT_SIZE, 1, 0 | 697 | .fill BOOT_PGT_SIZE, 1, 0 |
| 698 | |||
| 699 | /* | ||
| 700 | * The page table is going to be used instead of page table in the trampoline | ||
| 701 | * memory. | ||
| 702 | */ | ||
| 703 | top_pgtable: | ||
| 704 | .fill PAGE_SIZE, 1, 0 | ||
diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index 32af1cbcd903..a362fa0b849c 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c | |||
| @@ -23,14 +23,6 @@ struct paging_config { | |||
| 23 | static char trampoline_save[TRAMPOLINE_32BIT_SIZE]; | 23 | static char trampoline_save[TRAMPOLINE_32BIT_SIZE]; |
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | * The page table is going to be used instead of page table in the trampoline | ||
| 27 | * memory. | ||
| 28 | * | ||
| 29 | * It must not be in BSS as BSS is cleared after cleanup_trampoline(). | ||
| 30 | */ | ||
| 31 | static char top_pgtable[PAGE_SIZE] __aligned(PAGE_SIZE) __section(.data); | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Trampoline address will be printed by extract_kernel() for debugging | 26 | * Trampoline address will be printed by extract_kernel() for debugging |
| 35 | * purposes. | 27 | * purposes. |
| 36 | * | 28 | * |
| @@ -134,7 +126,7 @@ out: | |||
| 134 | return paging_config; | 126 | return paging_config; |
| 135 | } | 127 | } |
| 136 | 128 | ||
| 137 | void cleanup_trampoline(void) | 129 | void cleanup_trampoline(void *pgtable) |
| 138 | { | 130 | { |
| 139 | void *trampoline_pgtable; | 131 | void *trampoline_pgtable; |
| 140 | 132 | ||
| @@ -145,8 +137,8 @@ void cleanup_trampoline(void) | |||
| 145 | * if it's there. | 137 | * if it's there. |
| 146 | */ | 138 | */ |
| 147 | if ((void *)__native_read_cr3() == trampoline_pgtable) { | 139 | if ((void *)__native_read_cr3() == trampoline_pgtable) { |
| 148 | memcpy(top_pgtable, trampoline_pgtable, PAGE_SIZE); | 140 | memcpy(pgtable, trampoline_pgtable, PAGE_SIZE); |
| 149 | native_write_cr3((unsigned long)top_pgtable); | 141 | native_write_cr3((unsigned long)pgtable); |
| 150 | } | 142 | } |
| 151 | 143 | ||
| 152 | /* Restore trampoline memory */ | 144 | /* Restore trampoline memory */ |
diff --git a/arch/x86/entry/vdso/vdso32/vdso-fakesections.c b/arch/x86/entry/vdso/vdso32/vdso-fakesections.c deleted file mode 100644 index 541468e25265..000000000000 --- a/arch/x86/entry/vdso/vdso32/vdso-fakesections.c +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | #include "../vdso-fakesections.c" | ||
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index a6006e7bb729..45b2b1c93d04 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/cpu.h> | 27 | #include <linux/cpu.h> |
| 28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
| 29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
| 30 | #include <linux/nospec.h> | ||
| 30 | 31 | ||
| 31 | #include <asm/apic.h> | 32 | #include <asm/apic.h> |
| 32 | #include <asm/stacktrace.h> | 33 | #include <asm/stacktrace.h> |
| @@ -304,17 +305,20 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event) | |||
| 304 | 305 | ||
| 305 | config = attr->config; | 306 | config = attr->config; |
| 306 | 307 | ||
| 307 | cache_type = (config >> 0) & 0xff; | 308 | cache_type = (config >> 0) & 0xff; |
| 308 | if (cache_type >= PERF_COUNT_HW_CACHE_MAX) | 309 | if (cache_type >= PERF_COUNT_HW_CACHE_MAX) |
| 309 | return -EINVAL; | 310 | return -EINVAL; |
| 311 | cache_type = array_index_nospec(cache_type, PERF_COUNT_HW_CACHE_MAX); | ||
| 310 | 312 | ||
| 311 | cache_op = (config >> 8) & 0xff; | 313 | cache_op = (config >> 8) & 0xff; |
| 312 | if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) | 314 | if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) |
| 313 | return -EINVAL; | 315 | return -EINVAL; |
| 316 | cache_op = array_index_nospec(cache_op, PERF_COUNT_HW_CACHE_OP_MAX); | ||
| 314 | 317 | ||
| 315 | cache_result = (config >> 16) & 0xff; | 318 | cache_result = (config >> 16) & 0xff; |
| 316 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) | 319 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) |
| 317 | return -EINVAL; | 320 | return -EINVAL; |
| 321 | cache_result = array_index_nospec(cache_result, PERF_COUNT_HW_CACHE_RESULT_MAX); | ||
| 318 | 322 | ||
| 319 | val = hw_cache_event_ids[cache_type][cache_op][cache_result]; | 323 | val = hw_cache_event_ids[cache_type][cache_op][cache_result]; |
| 320 | 324 | ||
| @@ -421,6 +425,8 @@ int x86_setup_perfctr(struct perf_event *event) | |||
| 421 | if (attr->config >= x86_pmu.max_events) | 425 | if (attr->config >= x86_pmu.max_events) |
| 422 | return -EINVAL; | 426 | return -EINVAL; |
| 423 | 427 | ||
| 428 | attr->config = array_index_nospec((unsigned long)attr->config, x86_pmu.max_events); | ||
| 429 | |||
| 424 | /* | 430 | /* |
| 425 | * The generic map: | 431 | * The generic map: |
| 426 | */ | 432 | */ |
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 9aca448bb8e6..9f8084f18d58 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c | |||
| @@ -92,6 +92,7 @@ | |||
| 92 | #include <linux/module.h> | 92 | #include <linux/module.h> |
| 93 | #include <linux/slab.h> | 93 | #include <linux/slab.h> |
| 94 | #include <linux/perf_event.h> | 94 | #include <linux/perf_event.h> |
| 95 | #include <linux/nospec.h> | ||
| 95 | #include <asm/cpu_device_id.h> | 96 | #include <asm/cpu_device_id.h> |
| 96 | #include <asm/intel-family.h> | 97 | #include <asm/intel-family.h> |
| 97 | #include "../perf_event.h" | 98 | #include "../perf_event.h" |
| @@ -302,6 +303,7 @@ static int cstate_pmu_event_init(struct perf_event *event) | |||
| 302 | } else if (event->pmu == &cstate_pkg_pmu) { | 303 | } else if (event->pmu == &cstate_pkg_pmu) { |
| 303 | if (cfg >= PERF_CSTATE_PKG_EVENT_MAX) | 304 | if (cfg >= PERF_CSTATE_PKG_EVENT_MAX) |
| 304 | return -EINVAL; | 305 | return -EINVAL; |
| 306 | cfg = array_index_nospec((unsigned long)cfg, PERF_CSTATE_PKG_EVENT_MAX); | ||
| 305 | if (!pkg_msr[cfg].attr) | 307 | if (!pkg_msr[cfg].attr) |
| 306 | return -EINVAL; | 308 | return -EINVAL; |
| 307 | event->hw.event_base = pkg_msr[cfg].msr; | 309 | event->hw.event_base = pkg_msr[cfg].msr; |
diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index e7edf19e64c2..b4771a6ddbc1 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/perf_event.h> | 2 | #include <linux/perf_event.h> |
| 3 | #include <linux/nospec.h> | ||
| 3 | #include <asm/intel-family.h> | 4 | #include <asm/intel-family.h> |
| 4 | 5 | ||
| 5 | enum perf_msr_id { | 6 | enum perf_msr_id { |
| @@ -158,9 +159,6 @@ static int msr_event_init(struct perf_event *event) | |||
| 158 | if (event->attr.type != event->pmu->type) | 159 | if (event->attr.type != event->pmu->type) |
| 159 | return -ENOENT; | 160 | return -ENOENT; |
| 160 | 161 | ||
| 161 | if (cfg >= PERF_MSR_EVENT_MAX) | ||
| 162 | return -EINVAL; | ||
| 163 | |||
| 164 | /* unsupported modes and filters */ | 162 | /* unsupported modes and filters */ |
| 165 | if (event->attr.exclude_user || | 163 | if (event->attr.exclude_user || |
| 166 | event->attr.exclude_kernel || | 164 | event->attr.exclude_kernel || |
| @@ -171,6 +169,11 @@ static int msr_event_init(struct perf_event *event) | |||
| 171 | event->attr.sample_period) /* no sampling */ | 169 | event->attr.sample_period) /* no sampling */ |
| 172 | return -EINVAL; | 170 | return -EINVAL; |
| 173 | 171 | ||
| 172 | if (cfg >= PERF_MSR_EVENT_MAX) | ||
| 173 | return -EINVAL; | ||
| 174 | |||
| 175 | cfg = array_index_nospec((unsigned long)cfg, PERF_MSR_EVENT_MAX); | ||
| 176 | |||
| 174 | if (!msr[cfg].attr) | 177 | if (!msr[cfg].attr) |
| 175 | return -EINVAL; | 178 | return -EINVAL; |
| 176 | 179 | ||
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index b27da9602a6d..aced6c9290d6 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
| @@ -140,6 +140,20 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); | |||
| 140 | 140 | ||
| 141 | #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) | 141 | #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) |
| 142 | 142 | ||
| 143 | #if defined(__clang__) && !defined(CC_HAVE_ASM_GOTO) | ||
| 144 | |||
| 145 | /* | ||
| 146 | * Workaround for the sake of BPF compilation which utilizes kernel | ||
| 147 | * headers, but clang does not support ASM GOTO and fails the build. | ||
| 148 | */ | ||
| 149 | #ifndef __BPF_TRACING__ | ||
| 150 | #warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments" | ||
| 151 | #endif | ||
| 152 | |||
| 153 | #define static_cpu_has(bit) boot_cpu_has(bit) | ||
| 154 | |||
| 155 | #else | ||
| 156 | |||
| 143 | /* | 157 | /* |
| 144 | * Static testing of CPU features. Used the same as boot_cpu_has(). | 158 | * Static testing of CPU features. Used the same as boot_cpu_has(). |
| 145 | * These will statically patch the target code for additional | 159 | * These will statically patch the target code for additional |
| @@ -195,6 +209,7 @@ t_no: | |||
| 195 | boot_cpu_has(bit) : \ | 209 | boot_cpu_has(bit) : \ |
| 196 | _static_cpu_has(bit) \ | 210 | _static_cpu_has(bit) \ |
| 197 | ) | 211 | ) |
| 212 | #endif | ||
| 198 | 213 | ||
| 199 | #define cpu_has_bug(c, bit) cpu_has(c, (bit)) | 214 | #define cpu_has_bug(c, bit) cpu_has(c, (bit)) |
| 200 | #define set_cpu_bug(c, bit) set_cpu_cap(c, (bit)) | 215 | #define set_cpu_bug(c, bit) set_cpu_cap(c, (bit)) |
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h index b3e32b010ab1..c2c01f84df75 100644 --- a/arch/x86/include/asm/insn.h +++ b/arch/x86/include/asm/insn.h | |||
| @@ -208,4 +208,22 @@ static inline int insn_offset_immediate(struct insn *insn) | |||
| 208 | return insn_offset_displacement(insn) + insn->displacement.nbytes; | 208 | return insn_offset_displacement(insn) + insn->displacement.nbytes; |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | #define POP_SS_OPCODE 0x1f | ||
| 212 | #define MOV_SREG_OPCODE 0x8e | ||
| 213 | |||
| 214 | /* | ||
| 215 | * Intel SDM Vol.3A 6.8.3 states; | ||
| 216 | * "Any single-step trap that would be delivered following the MOV to SS | ||
| 217 | * instruction or POP to SS instruction (because EFLAGS.TF is 1) is | ||
| 218 | * suppressed." | ||
| 219 | * This function returns true if @insn is MOV SS or POP SS. On these | ||
| 220 | * instructions, single stepping is suppressed. | ||
| 221 | */ | ||
| 222 | static inline int insn_masking_exception(struct insn *insn) | ||
| 223 | { | ||
| 224 | return insn->opcode.bytes[0] == POP_SS_OPCODE || | ||
| 225 | (insn->opcode.bytes[0] == MOV_SREG_OPCODE && | ||
| 226 | X86_MODRM_REG(insn->modrm.bytes[0]) == 2); | ||
| 227 | } | ||
| 228 | |||
| 211 | #endif /* _ASM_X86_INSN_H */ | 229 | #endif /* _ASM_X86_INSN_H */ |
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 57e3785d0d26..cf9911b5a53c 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h | |||
| @@ -193,7 +193,7 @@ static inline int init_new_context(struct task_struct *tsk, | |||
| 193 | 193 | ||
| 194 | #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS | 194 | #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS |
| 195 | if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { | 195 | if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { |
| 196 | /* pkey 0 is the default and always allocated */ | 196 | /* pkey 0 is the default and allocated implicitly */ |
| 197 | mm->context.pkey_allocation_map = 0x1; | 197 | mm->context.pkey_allocation_map = 0x1; |
| 198 | /* -1 means unallocated or invalid */ | 198 | /* -1 means unallocated or invalid */ |
| 199 | mm->context.execute_only_pkey = -1; | 199 | mm->context.execute_only_pkey = -1; |
diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h index a0ba1ffda0df..851c04b7a092 100644 --- a/arch/x86/include/asm/pkeys.h +++ b/arch/x86/include/asm/pkeys.h | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | #ifndef _ASM_X86_PKEYS_H | 2 | #ifndef _ASM_X86_PKEYS_H |
| 3 | #define _ASM_X86_PKEYS_H | 3 | #define _ASM_X86_PKEYS_H |
| 4 | 4 | ||
| 5 | #define ARCH_DEFAULT_PKEY 0 | ||
| 6 | |||
| 5 | #define arch_max_pkey() (boot_cpu_has(X86_FEATURE_OSPKE) ? 16 : 1) | 7 | #define arch_max_pkey() (boot_cpu_has(X86_FEATURE_OSPKE) ? 16 : 1) |
| 6 | 8 | ||
| 7 | extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, | 9 | extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, |
| @@ -15,7 +17,7 @@ extern int __execute_only_pkey(struct mm_struct *mm); | |||
| 15 | static inline int execute_only_pkey(struct mm_struct *mm) | 17 | static inline int execute_only_pkey(struct mm_struct *mm) |
| 16 | { | 18 | { |
| 17 | if (!boot_cpu_has(X86_FEATURE_OSPKE)) | 19 | if (!boot_cpu_has(X86_FEATURE_OSPKE)) |
| 18 | return 0; | 20 | return ARCH_DEFAULT_PKEY; |
| 19 | 21 | ||
| 20 | return __execute_only_pkey(mm); | 22 | return __execute_only_pkey(mm); |
| 21 | } | 23 | } |
| @@ -49,13 +51,21 @@ bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) | |||
| 49 | { | 51 | { |
| 50 | /* | 52 | /* |
| 51 | * "Allocated" pkeys are those that have been returned | 53 | * "Allocated" pkeys are those that have been returned |
| 52 | * from pkey_alloc(). pkey 0 is special, and never | 54 | * from pkey_alloc() or pkey 0 which is allocated |
| 53 | * returned from pkey_alloc(). | 55 | * implicitly when the mm is created. |
| 54 | */ | 56 | */ |
| 55 | if (pkey <= 0) | 57 | if (pkey < 0) |
| 56 | return false; | 58 | return false; |
| 57 | if (pkey >= arch_max_pkey()) | 59 | if (pkey >= arch_max_pkey()) |
| 58 | return false; | 60 | return false; |
| 61 | /* | ||
| 62 | * The exec-only pkey is set in the allocation map, but | ||
| 63 | * is not available to any of the user interfaces like | ||
| 64 | * mprotect_pkey(). | ||
| 65 | */ | ||
| 66 | if (pkey == mm->context.execute_only_pkey) | ||
| 67 | return false; | ||
| 68 | |||
| 59 | return mm_pkey_allocation_map(mm) & (1U << pkey); | 69 | return mm_pkey_allocation_map(mm) & (1U << pkey); |
| 60 | } | 70 | } |
| 61 | 71 | ||
diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 4c851ebb3ceb..0ede697c3961 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #define KVM_FEATURE_PV_TLB_FLUSH 9 | 29 | #define KVM_FEATURE_PV_TLB_FLUSH 9 |
| 30 | #define KVM_FEATURE_ASYNC_PF_VMEXIT 10 | 30 | #define KVM_FEATURE_ASYNC_PF_VMEXIT 10 |
| 31 | 31 | ||
| 32 | #define KVM_HINTS_DEDICATED 0 | 32 | #define KVM_HINTS_REALTIME 0 |
| 33 | 33 | ||
| 34 | /* The last 8 bits are used to indicate how to interpret the flags field | 34 | /* The last 8 bits are used to indicate how to interpret the flags field |
| 35 | * in pvclock structure. If no bits are set, all flags are ignored. | 35 | * in pvclock structure. If no bits are set, all flags are ignored. |
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index c88e0b127810..b481b95bd8f6 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c | |||
| @@ -14,8 +14,11 @@ | |||
| 14 | #include <asm/amd_nb.h> | 14 | #include <asm/amd_nb.h> |
| 15 | 15 | ||
| 16 | #define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450 | 16 | #define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450 |
| 17 | #define PCI_DEVICE_ID_AMD_17H_M10H_ROOT 0x15d0 | ||
| 17 | #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 | 18 | #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 |
| 18 | #define PCI_DEVICE_ID_AMD_17H_DF_F4 0x1464 | 19 | #define PCI_DEVICE_ID_AMD_17H_DF_F4 0x1464 |
| 20 | #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb | ||
| 21 | #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec | ||
| 19 | 22 | ||
| 20 | /* Protect the PCI config register pairs used for SMN and DF indirect access. */ | 23 | /* Protect the PCI config register pairs used for SMN and DF indirect access. */ |
| 21 | static DEFINE_MUTEX(smn_mutex); | 24 | static DEFINE_MUTEX(smn_mutex); |
| @@ -24,6 +27,7 @@ static u32 *flush_words; | |||
| 24 | 27 | ||
| 25 | static const struct pci_device_id amd_root_ids[] = { | 28 | static const struct pci_device_id amd_root_ids[] = { |
| 26 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) }, | 29 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) }, |
| 30 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT) }, | ||
| 27 | {} | 31 | {} |
| 28 | }; | 32 | }; |
| 29 | 33 | ||
| @@ -39,6 +43,7 @@ const struct pci_device_id amd_nb_misc_ids[] = { | |||
| 39 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, | 43 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, |
| 40 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, | 44 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, |
| 41 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, | 45 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, |
| 46 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) }, | ||
| 42 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, | 47 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, |
| 43 | {} | 48 | {} |
| 44 | }; | 49 | }; |
| @@ -51,6 +56,7 @@ static const struct pci_device_id amd_nb_link_ids[] = { | |||
| 51 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, | 56 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, |
| 52 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) }, | 57 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) }, |
| 53 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) }, | 58 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) }, |
| 59 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) }, | ||
| 54 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, | 60 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, |
| 55 | {} | 61 | {} |
| 56 | }; | 62 | }; |
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 8b04234e010b..7685444a106b 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
| @@ -116,6 +116,7 @@ static void init_x2apic_ldr(void) | |||
| 116 | goto update; | 116 | goto update; |
| 117 | } | 117 | } |
| 118 | cmsk = cluster_hotplug_mask; | 118 | cmsk = cluster_hotplug_mask; |
| 119 | cmsk->clusterid = cluster; | ||
| 119 | cluster_hotplug_mask = NULL; | 120 | cluster_hotplug_mask = NULL; |
| 120 | update: | 121 | update: |
| 121 | this_cpu_write(cluster_masks, cmsk); | 122 | this_cpu_write(cluster_masks, cmsk); |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 8a5b185735e1..ce243f7d2d4e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -848,6 +848,11 @@ void get_cpu_cap(struct cpuinfo_x86 *c) | |||
| 848 | c->x86_power = edx; | 848 | c->x86_power = edx; |
| 849 | } | 849 | } |
| 850 | 850 | ||
| 851 | if (c->extended_cpuid_level >= 0x80000008) { | ||
| 852 | cpuid(0x80000008, &eax, &ebx, &ecx, &edx); | ||
| 853 | c->x86_capability[CPUID_8000_0008_EBX] = ebx; | ||
| 854 | } | ||
| 855 | |||
| 851 | if (c->extended_cpuid_level >= 0x8000000a) | 856 | if (c->extended_cpuid_level >= 0x8000000a) |
| 852 | c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a); | 857 | c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a); |
| 853 | 858 | ||
| @@ -871,7 +876,6 @@ static void get_cpu_address_sizes(struct cpuinfo_x86 *c) | |||
| 871 | 876 | ||
| 872 | c->x86_virt_bits = (eax >> 8) & 0xff; | 877 | c->x86_virt_bits = (eax >> 8) & 0xff; |
| 873 | c->x86_phys_bits = eax & 0xff; | 878 | c->x86_phys_bits = eax & 0xff; |
| 874 | c->x86_capability[CPUID_8000_0008_EBX] = ebx; | ||
| 875 | } | 879 | } |
| 876 | #ifdef CONFIG_X86_32 | 880 | #ifdef CONFIG_X86_32 |
| 877 | else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36)) | 881 | else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36)) |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index f7666eef4a87..c8e038800591 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
| @@ -94,6 +94,11 @@ static struct smca_bank_name smca_names[] = { | |||
| 94 | [SMCA_SMU] = { "smu", "System Management Unit" }, | 94 | [SMCA_SMU] = { "smu", "System Management Unit" }, |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | static u32 smca_bank_addrs[MAX_NR_BANKS][NR_BLOCKS] __ro_after_init = | ||
| 98 | { | ||
| 99 | [0 ... MAX_NR_BANKS - 1] = { [0 ... NR_BLOCKS - 1] = -1 } | ||
| 100 | }; | ||
| 101 | |||
| 97 | const char *smca_get_name(enum smca_bank_types t) | 102 | const char *smca_get_name(enum smca_bank_types t) |
| 98 | { | 103 | { |
| 99 | if (t >= N_SMCA_BANK_TYPES) | 104 | if (t >= N_SMCA_BANK_TYPES) |
| @@ -443,20 +448,26 @@ static u32 smca_get_block_address(unsigned int cpu, unsigned int bank, | |||
| 443 | if (!block) | 448 | if (!block) |
| 444 | return MSR_AMD64_SMCA_MCx_MISC(bank); | 449 | return MSR_AMD64_SMCA_MCx_MISC(bank); |
| 445 | 450 | ||
| 451 | /* Check our cache first: */ | ||
| 452 | if (smca_bank_addrs[bank][block] != -1) | ||
| 453 | return smca_bank_addrs[bank][block]; | ||
| 454 | |||
| 446 | /* | 455 | /* |
| 447 | * For SMCA enabled processors, BLKPTR field of the first MISC register | 456 | * For SMCA enabled processors, BLKPTR field of the first MISC register |
| 448 | * (MCx_MISC0) indicates presence of additional MISC regs set (MISC1-4). | 457 | * (MCx_MISC0) indicates presence of additional MISC regs set (MISC1-4). |
| 449 | */ | 458 | */ |
| 450 | if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_CONFIG(bank), &low, &high)) | 459 | if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_CONFIG(bank), &low, &high)) |
| 451 | return addr; | 460 | goto out; |
| 452 | 461 | ||
| 453 | if (!(low & MCI_CONFIG_MCAX)) | 462 | if (!(low & MCI_CONFIG_MCAX)) |
| 454 | return addr; | 463 | goto out; |
| 455 | 464 | ||
| 456 | if (!rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_MISC(bank), &low, &high) && | 465 | if (!rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_MISC(bank), &low, &high) && |
| 457 | (low & MASK_BLKPTR_LO)) | 466 | (low & MASK_BLKPTR_LO)) |
| 458 | return MSR_AMD64_SMCA_MCx_MISCy(bank, block - 1); | 467 | addr = MSR_AMD64_SMCA_MCx_MISCy(bank, block - 1); |
| 459 | 468 | ||
| 469 | out: | ||
| 470 | smca_bank_addrs[bank][block] = addr; | ||
| 460 | return addr; | 471 | return addr; |
| 461 | } | 472 | } |
| 462 | 473 | ||
| @@ -468,18 +479,6 @@ static u32 get_block_address(unsigned int cpu, u32 current_addr, u32 low, u32 hi | |||
| 468 | if ((bank >= mca_cfg.banks) || (block >= NR_BLOCKS)) | 479 | if ((bank >= mca_cfg.banks) || (block >= NR_BLOCKS)) |
| 469 | return addr; | 480 | return addr; |
| 470 | 481 | ||
| 471 | /* Get address from already initialized block. */ | ||
| 472 | if (per_cpu(threshold_banks, cpu)) { | ||
| 473 | struct threshold_bank *bankp = per_cpu(threshold_banks, cpu)[bank]; | ||
| 474 | |||
| 475 | if (bankp && bankp->blocks) { | ||
| 476 | struct threshold_block *blockp = &bankp->blocks[block]; | ||
| 477 | |||
| 478 | if (blockp) | ||
| 479 | return blockp->address; | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | if (mce_flags.smca) | 482 | if (mce_flags.smca) |
| 484 | return smca_get_block_address(cpu, bank, block); | 483 | return smca_get_block_address(cpu, bank, block); |
| 485 | 484 | ||
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 0c408f8c4ed4..2d29e47c056e 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
| @@ -104,6 +104,12 @@ static bool __head check_la57_support(unsigned long physaddr) | |||
| 104 | } | 104 | } |
| 105 | #endif | 105 | #endif |
| 106 | 106 | ||
| 107 | /* Code in __startup_64() can be relocated during execution, but the compiler | ||
| 108 | * doesn't have to generate PC-relative relocations when accessing globals from | ||
| 109 | * that function. Clang actually does not generate them, which leads to | ||
| 110 | * boot-time crashes. To work around this problem, every global pointer must | ||
| 111 | * be adjusted using fixup_pointer(). | ||
| 112 | */ | ||
| 107 | unsigned long __head __startup_64(unsigned long physaddr, | 113 | unsigned long __head __startup_64(unsigned long physaddr, |
| 108 | struct boot_params *bp) | 114 | struct boot_params *bp) |
| 109 | { | 115 | { |
| @@ -113,6 +119,7 @@ unsigned long __head __startup_64(unsigned long physaddr, | |||
| 113 | p4dval_t *p4d; | 119 | p4dval_t *p4d; |
| 114 | pudval_t *pud; | 120 | pudval_t *pud; |
| 115 | pmdval_t *pmd, pmd_entry; | 121 | pmdval_t *pmd, pmd_entry; |
| 122 | pteval_t *mask_ptr; | ||
| 116 | bool la57; | 123 | bool la57; |
| 117 | int i; | 124 | int i; |
| 118 | unsigned int *next_pgt_ptr; | 125 | unsigned int *next_pgt_ptr; |
| @@ -196,7 +203,8 @@ unsigned long __head __startup_64(unsigned long physaddr, | |||
| 196 | 203 | ||
| 197 | pmd_entry = __PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL; | 204 | pmd_entry = __PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL; |
| 198 | /* Filter out unsupported __PAGE_KERNEL_* bits: */ | 205 | /* Filter out unsupported __PAGE_KERNEL_* bits: */ |
| 199 | pmd_entry &= __supported_pte_mask; | 206 | mask_ptr = fixup_pointer(&__supported_pte_mask, physaddr); |
| 207 | pmd_entry &= *mask_ptr; | ||
| 200 | pmd_entry += sme_get_me_mask(); | 208 | pmd_entry += sme_get_me_mask(); |
| 201 | pmd_entry += physaddr; | 209 | pmd_entry += physaddr; |
| 202 | 210 | ||
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 0715f827607c..6f4d42377fe5 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
| @@ -370,6 +370,10 @@ int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn) | |||
| 370 | if (insn->opcode.bytes[0] == BREAKPOINT_INSTRUCTION) | 370 | if (insn->opcode.bytes[0] == BREAKPOINT_INSTRUCTION) |
| 371 | return 0; | 371 | return 0; |
| 372 | 372 | ||
| 373 | /* We should not singlestep on the exception masking instructions */ | ||
| 374 | if (insn_masking_exception(insn)) | ||
| 375 | return 0; | ||
| 376 | |||
| 373 | #ifdef CONFIG_X86_64 | 377 | #ifdef CONFIG_X86_64 |
| 374 | /* Only x86_64 has RIP relative instructions */ | 378 | /* Only x86_64 has RIP relative instructions */ |
| 375 | if (insn_rip_relative(insn)) { | 379 | if (insn_rip_relative(insn)) { |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 7867417cfaff..5b2300b818af 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
| @@ -457,7 +457,7 @@ static void __init sev_map_percpu_data(void) | |||
| 457 | static void __init kvm_smp_prepare_cpus(unsigned int max_cpus) | 457 | static void __init kvm_smp_prepare_cpus(unsigned int max_cpus) |
| 458 | { | 458 | { |
| 459 | native_smp_prepare_cpus(max_cpus); | 459 | native_smp_prepare_cpus(max_cpus); |
| 460 | if (kvm_para_has_hint(KVM_HINTS_DEDICATED)) | 460 | if (kvm_para_has_hint(KVM_HINTS_REALTIME)) |
| 461 | static_branch_disable(&virt_spin_lock_key); | 461 | static_branch_disable(&virt_spin_lock_key); |
| 462 | } | 462 | } |
| 463 | 463 | ||
| @@ -553,7 +553,7 @@ static void __init kvm_guest_init(void) | |||
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && | 555 | if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && |
| 556 | !kvm_para_has_hint(KVM_HINTS_DEDICATED) && | 556 | !kvm_para_has_hint(KVM_HINTS_REALTIME) && |
| 557 | kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) | 557 | kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) |
| 558 | pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others; | 558 | pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others; |
| 559 | 559 | ||
| @@ -649,7 +649,7 @@ static __init int kvm_setup_pv_tlb_flush(void) | |||
| 649 | int cpu; | 649 | int cpu; |
| 650 | 650 | ||
| 651 | if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && | 651 | if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && |
| 652 | !kvm_para_has_hint(KVM_HINTS_DEDICATED) && | 652 | !kvm_para_has_hint(KVM_HINTS_REALTIME) && |
| 653 | kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { | 653 | kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { |
| 654 | for_each_possible_cpu(cpu) { | 654 | for_each_possible_cpu(cpu) { |
| 655 | zalloc_cpumask_var_node(per_cpu_ptr(&__pv_tlb_mask, cpu), | 655 | zalloc_cpumask_var_node(per_cpu_ptr(&__pv_tlb_mask, cpu), |
| @@ -745,7 +745,7 @@ void __init kvm_spinlock_init(void) | |||
| 745 | if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT)) | 745 | if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT)) |
| 746 | return; | 746 | return; |
| 747 | 747 | ||
| 748 | if (kvm_para_has_hint(KVM_HINTS_DEDICATED)) | 748 | if (kvm_para_has_hint(KVM_HINTS_REALTIME)) |
| 749 | return; | 749 | return; |
| 750 | 750 | ||
| 751 | __pv_init_lock_hash(); | 751 | __pv_init_lock_hash(); |
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 60cdec6628b0..d1ab07ec8c9a 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c | |||
| @@ -57,12 +57,17 @@ static void load_segments(void) | |||
| 57 | static void machine_kexec_free_page_tables(struct kimage *image) | 57 | static void machine_kexec_free_page_tables(struct kimage *image) |
| 58 | { | 58 | { |
| 59 | free_page((unsigned long)image->arch.pgd); | 59 | free_page((unsigned long)image->arch.pgd); |
| 60 | image->arch.pgd = NULL; | ||
| 60 | #ifdef CONFIG_X86_PAE | 61 | #ifdef CONFIG_X86_PAE |
| 61 | free_page((unsigned long)image->arch.pmd0); | 62 | free_page((unsigned long)image->arch.pmd0); |
| 63 | image->arch.pmd0 = NULL; | ||
| 62 | free_page((unsigned long)image->arch.pmd1); | 64 | free_page((unsigned long)image->arch.pmd1); |
| 65 | image->arch.pmd1 = NULL; | ||
| 63 | #endif | 66 | #endif |
| 64 | free_page((unsigned long)image->arch.pte0); | 67 | free_page((unsigned long)image->arch.pte0); |
| 68 | image->arch.pte0 = NULL; | ||
| 65 | free_page((unsigned long)image->arch.pte1); | 69 | free_page((unsigned long)image->arch.pte1); |
| 70 | image->arch.pte1 = NULL; | ||
| 66 | } | 71 | } |
| 67 | 72 | ||
| 68 | static int machine_kexec_alloc_page_tables(struct kimage *image) | 73 | static int machine_kexec_alloc_page_tables(struct kimage *image) |
| @@ -79,7 +84,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image) | |||
| 79 | !image->arch.pmd0 || !image->arch.pmd1 || | 84 | !image->arch.pmd0 || !image->arch.pmd1 || |
| 80 | #endif | 85 | #endif |
| 81 | !image->arch.pte0 || !image->arch.pte1) { | 86 | !image->arch.pte0 || !image->arch.pte1) { |
| 82 | machine_kexec_free_page_tables(image); | ||
| 83 | return -ENOMEM; | 87 | return -ENOMEM; |
| 84 | } | 88 | } |
| 85 | return 0; | 89 | return 0; |
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index a5e55d832d0a..6010449ca6d2 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c | |||
| @@ -39,9 +39,13 @@ const struct kexec_file_ops * const kexec_file_loaders[] = { | |||
| 39 | static void free_transition_pgtable(struct kimage *image) | 39 | static void free_transition_pgtable(struct kimage *image) |
| 40 | { | 40 | { |
| 41 | free_page((unsigned long)image->arch.p4d); | 41 | free_page((unsigned long)image->arch.p4d); |
| 42 | image->arch.p4d = NULL; | ||
| 42 | free_page((unsigned long)image->arch.pud); | 43 | free_page((unsigned long)image->arch.pud); |
| 44 | image->arch.pud = NULL; | ||
| 43 | free_page((unsigned long)image->arch.pmd); | 45 | free_page((unsigned long)image->arch.pmd); |
| 46 | image->arch.pmd = NULL; | ||
| 44 | free_page((unsigned long)image->arch.pte); | 47 | free_page((unsigned long)image->arch.pte); |
| 48 | image->arch.pte = NULL; | ||
| 45 | } | 49 | } |
| 46 | 50 | ||
| 47 | static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) | 51 | static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) |
| @@ -91,7 +95,6 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) | |||
| 91 | set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC)); | 95 | set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC)); |
| 92 | return 0; | 96 | return 0; |
| 93 | err: | 97 | err: |
| 94 | free_transition_pgtable(image); | ||
| 95 | return result; | 98 | return result; |
| 96 | } | 99 | } |
| 97 | 100 | ||
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 4b100fe0f508..12bb445fb98d 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
| @@ -542,6 +542,7 @@ void set_personality_64bit(void) | |||
| 542 | clear_thread_flag(TIF_X32); | 542 | clear_thread_flag(TIF_X32); |
| 543 | /* Pretend that this comes from a 64bit execve */ | 543 | /* Pretend that this comes from a 64bit execve */ |
| 544 | task_pt_regs(current)->orig_ax = __NR_execve; | 544 | task_pt_regs(current)->orig_ax = __NR_execve; |
| 545 | current_thread_info()->status &= ~TS_COMPAT; | ||
| 545 | 546 | ||
| 546 | /* Ensure the corresponding mm is not marked. */ | 547 | /* Ensure the corresponding mm is not marked. */ |
| 547 | if (current->mm) | 548 | if (current->mm) |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 91e6da48cbb6..74392d9d51e0 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
| @@ -1067,6 +1067,7 @@ static struct clocksource clocksource_tsc_early = { | |||
| 1067 | .resume = tsc_resume, | 1067 | .resume = tsc_resume, |
| 1068 | .mark_unstable = tsc_cs_mark_unstable, | 1068 | .mark_unstable = tsc_cs_mark_unstable, |
| 1069 | .tick_stable = tsc_cs_tick_stable, | 1069 | .tick_stable = tsc_cs_tick_stable, |
| 1070 | .list = LIST_HEAD_INIT(clocksource_tsc_early.list), | ||
| 1070 | }; | 1071 | }; |
| 1071 | 1072 | ||
| 1072 | /* | 1073 | /* |
| @@ -1086,6 +1087,7 @@ static struct clocksource clocksource_tsc = { | |||
| 1086 | .resume = tsc_resume, | 1087 | .resume = tsc_resume, |
| 1087 | .mark_unstable = tsc_cs_mark_unstable, | 1088 | .mark_unstable = tsc_cs_mark_unstable, |
| 1088 | .tick_stable = tsc_cs_tick_stable, | 1089 | .tick_stable = tsc_cs_tick_stable, |
| 1090 | .list = LIST_HEAD_INIT(clocksource_tsc.list), | ||
| 1089 | }; | 1091 | }; |
| 1090 | 1092 | ||
| 1091 | void mark_tsc_unstable(char *reason) | 1093 | void mark_tsc_unstable(char *reason) |
| @@ -1098,13 +1100,9 @@ void mark_tsc_unstable(char *reason) | |||
| 1098 | clear_sched_clock_stable(); | 1100 | clear_sched_clock_stable(); |
| 1099 | disable_sched_clock_irqtime(); | 1101 | disable_sched_clock_irqtime(); |
| 1100 | pr_info("Marking TSC unstable due to %s\n", reason); | 1102 | pr_info("Marking TSC unstable due to %s\n", reason); |
| 1101 | /* Change only the rating, when not registered */ | 1103 | |
| 1102 | if (clocksource_tsc.mult) { | 1104 | clocksource_mark_unstable(&clocksource_tsc_early); |
| 1103 | clocksource_mark_unstable(&clocksource_tsc); | 1105 | clocksource_mark_unstable(&clocksource_tsc); |
| 1104 | } else { | ||
| 1105 | clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE; | ||
| 1106 | clocksource_tsc.rating = 0; | ||
| 1107 | } | ||
| 1108 | } | 1106 | } |
| 1109 | 1107 | ||
| 1110 | EXPORT_SYMBOL_GPL(mark_tsc_unstable); | 1108 | EXPORT_SYMBOL_GPL(mark_tsc_unstable); |
| @@ -1244,7 +1242,7 @@ static void tsc_refine_calibration_work(struct work_struct *work) | |||
| 1244 | 1242 | ||
| 1245 | /* Don't bother refining TSC on unstable systems */ | 1243 | /* Don't bother refining TSC on unstable systems */ |
| 1246 | if (tsc_unstable) | 1244 | if (tsc_unstable) |
| 1247 | return; | 1245 | goto unreg; |
| 1248 | 1246 | ||
| 1249 | /* | 1247 | /* |
| 1250 | * Since the work is started early in boot, we may be | 1248 | * Since the work is started early in boot, we may be |
| @@ -1297,11 +1295,12 @@ static void tsc_refine_calibration_work(struct work_struct *work) | |||
| 1297 | 1295 | ||
| 1298 | out: | 1296 | out: |
| 1299 | if (tsc_unstable) | 1297 | if (tsc_unstable) |
| 1300 | return; | 1298 | goto unreg; |
| 1301 | 1299 | ||
| 1302 | if (boot_cpu_has(X86_FEATURE_ART)) | 1300 | if (boot_cpu_has(X86_FEATURE_ART)) |
| 1303 | art_related_clocksource = &clocksource_tsc; | 1301 | art_related_clocksource = &clocksource_tsc; |
| 1304 | clocksource_register_khz(&clocksource_tsc, tsc_khz); | 1302 | clocksource_register_khz(&clocksource_tsc, tsc_khz); |
| 1303 | unreg: | ||
| 1305 | clocksource_unregister(&clocksource_tsc_early); | 1304 | clocksource_unregister(&clocksource_tsc_early); |
| 1306 | } | 1305 | } |
| 1307 | 1306 | ||
| @@ -1311,8 +1310,8 @@ static int __init init_tsc_clocksource(void) | |||
| 1311 | if (!boot_cpu_has(X86_FEATURE_TSC) || tsc_disabled > 0 || !tsc_khz) | 1310 | if (!boot_cpu_has(X86_FEATURE_TSC) || tsc_disabled > 0 || !tsc_khz) |
| 1312 | return 0; | 1311 | return 0; |
| 1313 | 1312 | ||
| 1314 | if (check_tsc_unstable()) | 1313 | if (tsc_unstable) |
| 1315 | return 0; | 1314 | goto unreg; |
| 1316 | 1315 | ||
| 1317 | if (tsc_clocksource_reliable) | 1316 | if (tsc_clocksource_reliable) |
| 1318 | clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; | 1317 | clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; |
| @@ -1328,6 +1327,7 @@ static int __init init_tsc_clocksource(void) | |||
| 1328 | if (boot_cpu_has(X86_FEATURE_ART)) | 1327 | if (boot_cpu_has(X86_FEATURE_ART)) |
| 1329 | art_related_clocksource = &clocksource_tsc; | 1328 | art_related_clocksource = &clocksource_tsc; |
| 1330 | clocksource_register_khz(&clocksource_tsc, tsc_khz); | 1329 | clocksource_register_khz(&clocksource_tsc, tsc_khz); |
| 1330 | unreg: | ||
| 1331 | clocksource_unregister(&clocksource_tsc_early); | 1331 | clocksource_unregister(&clocksource_tsc_early); |
| 1332 | return 0; | 1332 | return 0; |
| 1333 | } | 1333 | } |
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 85c7ef23d99f..c84bb5396958 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
| @@ -299,6 +299,10 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool | |||
| 299 | if (is_prefix_bad(insn)) | 299 | if (is_prefix_bad(insn)) |
| 300 | return -ENOTSUPP; | 300 | return -ENOTSUPP; |
| 301 | 301 | ||
| 302 | /* We should not singlestep on the exception masking instructions */ | ||
| 303 | if (insn_masking_exception(insn)) | ||
| 304 | return -ENOTSUPP; | ||
| 305 | |||
| 302 | if (x86_64) | 306 | if (x86_64) |
| 303 | good_insns = good_insns_64; | 307 | good_insns = good_insns_64; |
| 304 | else | 308 | else |
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 98618e397342..5708e951a5c6 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c | |||
| @@ -1265,7 +1265,7 @@ static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu) | |||
| 1265 | struct kvm_run *run = vcpu->run; | 1265 | struct kvm_run *run = vcpu->run; |
| 1266 | 1266 | ||
| 1267 | kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result); | 1267 | kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result); |
| 1268 | return 1; | 1268 | return kvm_skip_emulated_instruction(vcpu); |
| 1269 | } | 1269 | } |
| 1270 | 1270 | ||
| 1271 | static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param) | 1271 | static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param) |
| @@ -1296,8 +1296,10 @@ static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param) | |||
| 1296 | if (param & ~KVM_HYPERV_CONN_ID_MASK) | 1296 | if (param & ~KVM_HYPERV_CONN_ID_MASK) |
| 1297 | return HV_STATUS_INVALID_HYPERCALL_INPUT; | 1297 | return HV_STATUS_INVALID_HYPERCALL_INPUT; |
| 1298 | 1298 | ||
| 1299 | /* conn_to_evt is protected by vcpu->kvm->srcu */ | 1299 | /* the eventfd is protected by vcpu->kvm->srcu, but conn_to_evt isn't */ |
| 1300 | rcu_read_lock(); | ||
| 1300 | eventfd = idr_find(&vcpu->kvm->arch.hyperv.conn_to_evt, param); | 1301 | eventfd = idr_find(&vcpu->kvm->arch.hyperv.conn_to_evt, param); |
| 1302 | rcu_read_unlock(); | ||
| 1301 | if (!eventfd) | 1303 | if (!eventfd) |
| 1302 | return HV_STATUS_INVALID_PORT_ID; | 1304 | return HV_STATUS_INVALID_PORT_ID; |
| 1303 | 1305 | ||
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 70dcb5548022..b74c9c1405b9 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
| @@ -1463,23 +1463,6 @@ static void start_sw_tscdeadline(struct kvm_lapic *apic) | |||
| 1463 | local_irq_restore(flags); | 1463 | local_irq_restore(flags); |
| 1464 | } | 1464 | } |
| 1465 | 1465 | ||
| 1466 | static void start_sw_period(struct kvm_lapic *apic) | ||
| 1467 | { | ||
| 1468 | if (!apic->lapic_timer.period) | ||
| 1469 | return; | ||
| 1470 | |||
| 1471 | if (apic_lvtt_oneshot(apic) && | ||
| 1472 | ktime_after(ktime_get(), | ||
| 1473 | apic->lapic_timer.target_expiration)) { | ||
| 1474 | apic_timer_expired(apic); | ||
| 1475 | return; | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | hrtimer_start(&apic->lapic_timer.timer, | ||
| 1479 | apic->lapic_timer.target_expiration, | ||
| 1480 | HRTIMER_MODE_ABS_PINNED); | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | static void update_target_expiration(struct kvm_lapic *apic, uint32_t old_divisor) | 1466 | static void update_target_expiration(struct kvm_lapic *apic, uint32_t old_divisor) |
| 1484 | { | 1467 | { |
| 1485 | ktime_t now, remaining; | 1468 | ktime_t now, remaining; |
| @@ -1546,6 +1529,26 @@ static void advance_periodic_target_expiration(struct kvm_lapic *apic) | |||
| 1546 | apic->lapic_timer.period); | 1529 | apic->lapic_timer.period); |
| 1547 | } | 1530 | } |
| 1548 | 1531 | ||
| 1532 | static void start_sw_period(struct kvm_lapic *apic) | ||
| 1533 | { | ||
| 1534 | if (!apic->lapic_timer.period) | ||
| 1535 | return; | ||
| 1536 | |||
| 1537 | if (ktime_after(ktime_get(), | ||
| 1538 | apic->lapic_timer.target_expiration)) { | ||
| 1539 | apic_timer_expired(apic); | ||
| 1540 | |||
| 1541 | if (apic_lvtt_oneshot(apic)) | ||
| 1542 | return; | ||
| 1543 | |||
| 1544 | advance_periodic_target_expiration(apic); | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | hrtimer_start(&apic->lapic_timer.timer, | ||
| 1548 | apic->lapic_timer.target_expiration, | ||
| 1549 | HRTIMER_MODE_ABS_PINNED); | ||
| 1550 | } | ||
| 1551 | |||
| 1549 | bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu) | 1552 | bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu) |
| 1550 | { | 1553 | { |
| 1551 | if (!lapic_in_kernel(vcpu)) | 1554 | if (!lapic_in_kernel(vcpu)) |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c7668806163f..3f1696570b41 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -1494,6 +1494,12 @@ static inline bool cpu_has_vmx_vmfunc(void) | |||
| 1494 | SECONDARY_EXEC_ENABLE_VMFUNC; | 1494 | SECONDARY_EXEC_ENABLE_VMFUNC; |
| 1495 | } | 1495 | } |
| 1496 | 1496 | ||
| 1497 | static bool vmx_umip_emulated(void) | ||
| 1498 | { | ||
| 1499 | return vmcs_config.cpu_based_2nd_exec_ctrl & | ||
| 1500 | SECONDARY_EXEC_DESC; | ||
| 1501 | } | ||
| 1502 | |||
| 1497 | static inline bool report_flexpriority(void) | 1503 | static inline bool report_flexpriority(void) |
| 1498 | { | 1504 | { |
| 1499 | return flexpriority_enabled; | 1505 | return flexpriority_enabled; |
| @@ -4761,14 +4767,16 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
| 4761 | else | 4767 | else |
| 4762 | hw_cr4 |= KVM_PMODE_VM_CR4_ALWAYS_ON; | 4768 | hw_cr4 |= KVM_PMODE_VM_CR4_ALWAYS_ON; |
| 4763 | 4769 | ||
| 4764 | if ((cr4 & X86_CR4_UMIP) && !boot_cpu_has(X86_FEATURE_UMIP)) { | 4770 | if (!boot_cpu_has(X86_FEATURE_UMIP) && vmx_umip_emulated()) { |
| 4765 | vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL, | 4771 | if (cr4 & X86_CR4_UMIP) { |
| 4766 | SECONDARY_EXEC_DESC); | 4772 | vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL, |
| 4767 | hw_cr4 &= ~X86_CR4_UMIP; | ||
| 4768 | } else if (!is_guest_mode(vcpu) || | ||
| 4769 | !nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC)) | ||
| 4770 | vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL, | ||
| 4771 | SECONDARY_EXEC_DESC); | 4773 | SECONDARY_EXEC_DESC); |
| 4774 | hw_cr4 &= ~X86_CR4_UMIP; | ||
| 4775 | } else if (!is_guest_mode(vcpu) || | ||
| 4776 | !nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC)) | ||
| 4777 | vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL, | ||
| 4778 | SECONDARY_EXEC_DESC); | ||
| 4779 | } | ||
| 4772 | 4780 | ||
| 4773 | if (cr4 & X86_CR4_VMXE) { | 4781 | if (cr4 & X86_CR4_VMXE) { |
| 4774 | /* | 4782 | /* |
| @@ -9497,12 +9505,6 @@ static bool vmx_xsaves_supported(void) | |||
| 9497 | SECONDARY_EXEC_XSAVES; | 9505 | SECONDARY_EXEC_XSAVES; |
| 9498 | } | 9506 | } |
| 9499 | 9507 | ||
| 9500 | static bool vmx_umip_emulated(void) | ||
| 9501 | { | ||
| 9502 | return vmcs_config.cpu_based_2nd_exec_ctrl & | ||
| 9503 | SECONDARY_EXEC_DESC; | ||
| 9504 | } | ||
| 9505 | |||
| 9506 | static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) | 9508 | static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) |
| 9507 | { | 9509 | { |
| 9508 | u32 exit_intr_info; | 9510 | u32 exit_intr_info; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 51ecd381793b..59371de5d722 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -114,7 +114,7 @@ module_param(ignore_msrs, bool, S_IRUGO | S_IWUSR); | |||
| 114 | static bool __read_mostly report_ignored_msrs = true; | 114 | static bool __read_mostly report_ignored_msrs = true; |
| 115 | module_param(report_ignored_msrs, bool, S_IRUGO | S_IWUSR); | 115 | module_param(report_ignored_msrs, bool, S_IRUGO | S_IWUSR); |
| 116 | 116 | ||
| 117 | unsigned int min_timer_period_us = 500; | 117 | unsigned int min_timer_period_us = 200; |
| 118 | module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR); | 118 | module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR); |
| 119 | 119 | ||
| 120 | static bool __read_mostly kvmclock_periodic_sync = true; | 120 | static bool __read_mostly kvmclock_periodic_sync = true; |
| @@ -843,7 +843,10 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4); | |||
| 843 | int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | 843 | int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) |
| 844 | { | 844 | { |
| 845 | #ifdef CONFIG_X86_64 | 845 | #ifdef CONFIG_X86_64 |
| 846 | cr3 &= ~CR3_PCID_INVD; | 846 | bool pcid_enabled = kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE); |
| 847 | |||
| 848 | if (pcid_enabled) | ||
| 849 | cr3 &= ~CR3_PCID_INVD; | ||
| 847 | #endif | 850 | #endif |
| 848 | 851 | ||
| 849 | if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) { | 852 | if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) { |
| @@ -6671,12 +6674,13 @@ void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu) | |||
| 6671 | int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | 6674 | int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) |
| 6672 | { | 6675 | { |
| 6673 | unsigned long nr, a0, a1, a2, a3, ret; | 6676 | unsigned long nr, a0, a1, a2, a3, ret; |
| 6674 | int op_64_bit, r; | 6677 | int op_64_bit; |
| 6675 | |||
| 6676 | r = kvm_skip_emulated_instruction(vcpu); | ||
| 6677 | 6678 | ||
| 6678 | if (kvm_hv_hypercall_enabled(vcpu->kvm)) | 6679 | if (kvm_hv_hypercall_enabled(vcpu->kvm)) { |
| 6679 | return kvm_hv_hypercall(vcpu); | 6680 | if (!kvm_hv_hypercall(vcpu)) |
| 6681 | return 0; | ||
| 6682 | goto out; | ||
| 6683 | } | ||
| 6680 | 6684 | ||
| 6681 | nr = kvm_register_read(vcpu, VCPU_REGS_RAX); | 6685 | nr = kvm_register_read(vcpu, VCPU_REGS_RAX); |
| 6682 | a0 = kvm_register_read(vcpu, VCPU_REGS_RBX); | 6686 | a0 = kvm_register_read(vcpu, VCPU_REGS_RBX); |
| @@ -6697,7 +6701,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | |||
| 6697 | 6701 | ||
| 6698 | if (kvm_x86_ops->get_cpl(vcpu) != 0) { | 6702 | if (kvm_x86_ops->get_cpl(vcpu) != 0) { |
| 6699 | ret = -KVM_EPERM; | 6703 | ret = -KVM_EPERM; |
| 6700 | goto out; | 6704 | goto out_error; |
| 6701 | } | 6705 | } |
| 6702 | 6706 | ||
| 6703 | switch (nr) { | 6707 | switch (nr) { |
| @@ -6717,12 +6721,14 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | |||
| 6717 | ret = -KVM_ENOSYS; | 6721 | ret = -KVM_ENOSYS; |
| 6718 | break; | 6722 | break; |
| 6719 | } | 6723 | } |
| 6720 | out: | 6724 | out_error: |
| 6721 | if (!op_64_bit) | 6725 | if (!op_64_bit) |
| 6722 | ret = (u32)ret; | 6726 | ret = (u32)ret; |
| 6723 | kvm_register_write(vcpu, VCPU_REGS_RAX, ret); | 6727 | kvm_register_write(vcpu, VCPU_REGS_RAX, ret); |
| 6728 | |||
| 6729 | out: | ||
| 6724 | ++vcpu->stat.hypercalls; | 6730 | ++vcpu->stat.hypercalls; |
| 6725 | return r; | 6731 | return kvm_skip_emulated_instruction(vcpu); |
| 6726 | } | 6732 | } |
| 6727 | EXPORT_SYMBOL_GPL(kvm_emulate_hypercall); | 6733 | EXPORT_SYMBOL_GPL(kvm_emulate_hypercall); |
| 6728 | 6734 | ||
diff --git a/arch/x86/mm/pkeys.c b/arch/x86/mm/pkeys.c index d7bc0eea20a5..6e98e0a7c923 100644 --- a/arch/x86/mm/pkeys.c +++ b/arch/x86/mm/pkeys.c | |||
| @@ -94,26 +94,27 @@ int __arch_override_mprotect_pkey(struct vm_area_struct *vma, int prot, int pkey | |||
| 94 | */ | 94 | */ |
| 95 | if (pkey != -1) | 95 | if (pkey != -1) |
| 96 | return pkey; | 96 | return pkey; |
| 97 | /* | 97 | |
| 98 | * Look for a protection-key-drive execute-only mapping | ||
| 99 | * which is now being given permissions that are not | ||
| 100 | * execute-only. Move it back to the default pkey. | ||
| 101 | */ | ||
| 102 | if (vma_is_pkey_exec_only(vma) && | ||
| 103 | (prot & (PROT_READ|PROT_WRITE))) { | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | /* | 98 | /* |
| 107 | * The mapping is execute-only. Go try to get the | 99 | * The mapping is execute-only. Go try to get the |
| 108 | * execute-only protection key. If we fail to do that, | 100 | * execute-only protection key. If we fail to do that, |
| 109 | * fall through as if we do not have execute-only | 101 | * fall through as if we do not have execute-only |
| 110 | * support. | 102 | * support in this mm. |
| 111 | */ | 103 | */ |
| 112 | if (prot == PROT_EXEC) { | 104 | if (prot == PROT_EXEC) { |
| 113 | pkey = execute_only_pkey(vma->vm_mm); | 105 | pkey = execute_only_pkey(vma->vm_mm); |
| 114 | if (pkey > 0) | 106 | if (pkey > 0) |
| 115 | return pkey; | 107 | return pkey; |
| 108 | } else if (vma_is_pkey_exec_only(vma)) { | ||
| 109 | /* | ||
| 110 | * Protections are *not* PROT_EXEC, but the mapping | ||
| 111 | * is using the exec-only pkey. This mapping was | ||
| 112 | * PROT_EXEC and will no longer be. Move back to | ||
| 113 | * the default pkey. | ||
| 114 | */ | ||
| 115 | return ARCH_DEFAULT_PKEY; | ||
| 116 | } | 116 | } |
| 117 | |||
| 117 | /* | 118 | /* |
| 118 | * This is a vanilla, non-pkey mprotect (or we failed to | 119 | * This is a vanilla, non-pkey mprotect (or we failed to |
| 119 | * setup execute-only), inherit the pkey from the VMA we | 120 | * setup execute-only), inherit the pkey from the VMA we |
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index b725154182cc..263c8453815e 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c | |||
| @@ -1027,7 +1027,17 @@ emit_cond_jmp: /* convert BPF opcode to x86 */ | |||
| 1027 | break; | 1027 | break; |
| 1028 | 1028 | ||
| 1029 | case BPF_JMP | BPF_JA: | 1029 | case BPF_JMP | BPF_JA: |
| 1030 | jmp_offset = addrs[i + insn->off] - addrs[i]; | 1030 | if (insn->off == -1) |
| 1031 | /* -1 jmp instructions will always jump | ||
| 1032 | * backwards two bytes. Explicitly handling | ||
| 1033 | * this case avoids wasting too many passes | ||
| 1034 | * when there are long sequences of replaced | ||
| 1035 | * dead code. | ||
| 1036 | */ | ||
| 1037 | jmp_offset = -2; | ||
| 1038 | else | ||
| 1039 | jmp_offset = addrs[i + insn->off] - addrs[i]; | ||
| 1040 | |||
| 1031 | if (!jmp_offset) | 1041 | if (!jmp_offset) |
| 1032 | /* optimize out nop jumps */ | 1042 | /* optimize out nop jumps */ |
| 1033 | break; | 1043 | break; |
| @@ -1226,6 +1236,7 @@ skip_init_addrs: | |||
| 1226 | for (pass = 0; pass < 20 || image; pass++) { | 1236 | for (pass = 0; pass < 20 || image; pass++) { |
| 1227 | proglen = do_jit(prog, addrs, image, oldproglen, &ctx); | 1237 | proglen = do_jit(prog, addrs, image, oldproglen, &ctx); |
| 1228 | if (proglen <= 0) { | 1238 | if (proglen <= 0) { |
| 1239 | out_image: | ||
| 1229 | image = NULL; | 1240 | image = NULL; |
| 1230 | if (header) | 1241 | if (header) |
| 1231 | bpf_jit_binary_free(header); | 1242 | bpf_jit_binary_free(header); |
| @@ -1236,8 +1247,7 @@ skip_init_addrs: | |||
| 1236 | if (proglen != oldproglen) { | 1247 | if (proglen != oldproglen) { |
| 1237 | pr_err("bpf_jit: proglen=%d != oldproglen=%d\n", | 1248 | pr_err("bpf_jit: proglen=%d != oldproglen=%d\n", |
| 1238 | proglen, oldproglen); | 1249 | proglen, oldproglen); |
| 1239 | prog = orig_prog; | 1250 | goto out_image; |
| 1240 | goto out_addrs; | ||
| 1241 | } | 1251 | } |
| 1242 | break; | 1252 | break; |
| 1243 | } | 1253 | } |
| @@ -1273,7 +1283,7 @@ skip_init_addrs: | |||
| 1273 | prog = orig_prog; | 1283 | prog = orig_prog; |
| 1274 | } | 1284 | } |
| 1275 | 1285 | ||
| 1276 | if (!prog->is_func || extra_pass) { | 1286 | if (!image || !prog->is_func || extra_pass) { |
| 1277 | out_addrs: | 1287 | out_addrs: |
| 1278 | kfree(addrs); | 1288 | kfree(addrs); |
| 1279 | kfree(jit_data); | 1289 | kfree(jit_data); |
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c index 826898701045..19c1ff542387 100644 --- a/arch/x86/xen/enlighten_hvm.c +++ b/arch/x86/xen/enlighten_hvm.c | |||
| @@ -65,6 +65,19 @@ static void __init xen_hvm_init_mem_mapping(void) | |||
| 65 | { | 65 | { |
| 66 | early_memunmap(HYPERVISOR_shared_info, PAGE_SIZE); | 66 | early_memunmap(HYPERVISOR_shared_info, PAGE_SIZE); |
| 67 | HYPERVISOR_shared_info = __va(PFN_PHYS(shared_info_pfn)); | 67 | HYPERVISOR_shared_info = __va(PFN_PHYS(shared_info_pfn)); |
| 68 | |||
| 69 | /* | ||
| 70 | * The virtual address of the shared_info page has changed, so | ||
| 71 | * the vcpu_info pointer for VCPU 0 is now stale. | ||
| 72 | * | ||
| 73 | * The prepare_boot_cpu callback will re-initialize it via | ||
| 74 | * xen_vcpu_setup, but we can't rely on that to be called for | ||
| 75 | * old Xen versions (xen_have_vector_callback == 0). | ||
| 76 | * | ||
| 77 | * It is, in any case, bad to have a stale vcpu_info pointer | ||
| 78 | * so reset it now. | ||
| 79 | */ | ||
| 80 | xen_vcpu_info_reset(0); | ||
| 68 | } | 81 | } |
| 69 | 82 | ||
| 70 | static void __init init_hvm_pv_info(void) | 83 | static void __init init_hvm_pv_info(void) |
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index c36d23aa6c35..357969a3697c 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c | |||
| @@ -421,45 +421,33 @@ static void xen_load_gdt(const struct desc_ptr *dtr) | |||
| 421 | { | 421 | { |
| 422 | unsigned long va = dtr->address; | 422 | unsigned long va = dtr->address; |
| 423 | unsigned int size = dtr->size + 1; | 423 | unsigned int size = dtr->size + 1; |
| 424 | unsigned pages = DIV_ROUND_UP(size, PAGE_SIZE); | 424 | unsigned long pfn, mfn; |
| 425 | unsigned long frames[pages]; | 425 | int level; |
| 426 | int f; | 426 | pte_t *ptep; |
| 427 | 427 | void *virt; | |
| 428 | /* | ||
| 429 | * A GDT can be up to 64k in size, which corresponds to 8192 | ||
| 430 | * 8-byte entries, or 16 4k pages.. | ||
| 431 | */ | ||
| 432 | 428 | ||
| 433 | BUG_ON(size > 65536); | 429 | /* @size should be at most GDT_SIZE which is smaller than PAGE_SIZE. */ |
| 430 | BUG_ON(size > PAGE_SIZE); | ||
| 434 | BUG_ON(va & ~PAGE_MASK); | 431 | BUG_ON(va & ~PAGE_MASK); |
| 435 | 432 | ||
| 436 | for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { | 433 | /* |
| 437 | int level; | 434 | * The GDT is per-cpu and is in the percpu data area. |
| 438 | pte_t *ptep; | 435 | * That can be virtually mapped, so we need to do a |
| 439 | unsigned long pfn, mfn; | 436 | * page-walk to get the underlying MFN for the |
| 440 | void *virt; | 437 | * hypercall. The page can also be in the kernel's |
| 441 | 438 | * linear range, so we need to RO that mapping too. | |
| 442 | /* | 439 | */ |
| 443 | * The GDT is per-cpu and is in the percpu data area. | 440 | ptep = lookup_address(va, &level); |
| 444 | * That can be virtually mapped, so we need to do a | 441 | BUG_ON(ptep == NULL); |
| 445 | * page-walk to get the underlying MFN for the | ||
| 446 | * hypercall. The page can also be in the kernel's | ||
| 447 | * linear range, so we need to RO that mapping too. | ||
| 448 | */ | ||
| 449 | ptep = lookup_address(va, &level); | ||
| 450 | BUG_ON(ptep == NULL); | ||
| 451 | |||
| 452 | pfn = pte_pfn(*ptep); | ||
| 453 | mfn = pfn_to_mfn(pfn); | ||
| 454 | virt = __va(PFN_PHYS(pfn)); | ||
| 455 | 442 | ||
| 456 | frames[f] = mfn; | 443 | pfn = pte_pfn(*ptep); |
| 444 | mfn = pfn_to_mfn(pfn); | ||
| 445 | virt = __va(PFN_PHYS(pfn)); | ||
| 457 | 446 | ||
| 458 | make_lowmem_page_readonly((void *)va); | 447 | make_lowmem_page_readonly((void *)va); |
| 459 | make_lowmem_page_readonly(virt); | 448 | make_lowmem_page_readonly(virt); |
| 460 | } | ||
| 461 | 449 | ||
| 462 | if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct))) | 450 | if (HYPERVISOR_set_gdt(&mfn, size / sizeof(struct desc_struct))) |
| 463 | BUG(); | 451 | BUG(); |
| 464 | } | 452 | } |
| 465 | 453 | ||
| @@ -470,34 +458,22 @@ static void __init xen_load_gdt_boot(const struct desc_ptr *dtr) | |||
| 470 | { | 458 | { |
| 471 | unsigned long va = dtr->address; | 459 | unsigned long va = dtr->address; |
| 472 | unsigned int size = dtr->size + 1; | 460 | unsigned int size = dtr->size + 1; |
| 473 | unsigned pages = DIV_ROUND_UP(size, PAGE_SIZE); | 461 | unsigned long pfn, mfn; |
| 474 | unsigned long frames[pages]; | 462 | pte_t pte; |
| 475 | int f; | ||
| 476 | |||
| 477 | /* | ||
| 478 | * A GDT can be up to 64k in size, which corresponds to 8192 | ||
| 479 | * 8-byte entries, or 16 4k pages.. | ||
| 480 | */ | ||
| 481 | 463 | ||
| 482 | BUG_ON(size > 65536); | 464 | /* @size should be at most GDT_SIZE which is smaller than PAGE_SIZE. */ |
| 465 | BUG_ON(size > PAGE_SIZE); | ||
| 483 | BUG_ON(va & ~PAGE_MASK); | 466 | BUG_ON(va & ~PAGE_MASK); |
| 484 | 467 | ||
| 485 | for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { | 468 | pfn = virt_to_pfn(va); |
| 486 | pte_t pte; | 469 | mfn = pfn_to_mfn(pfn); |
| 487 | unsigned long pfn, mfn; | ||
| 488 | 470 | ||
| 489 | pfn = virt_to_pfn(va); | 471 | pte = pfn_pte(pfn, PAGE_KERNEL_RO); |
| 490 | mfn = pfn_to_mfn(pfn); | ||
| 491 | 472 | ||
| 492 | pte = pfn_pte(pfn, PAGE_KERNEL_RO); | 473 | if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0)) |
| 493 | 474 | BUG(); | |
| 494 | if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0)) | ||
| 495 | BUG(); | ||
| 496 | |||
| 497 | frames[f] = mfn; | ||
| 498 | } | ||
| 499 | 475 | ||
| 500 | if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct))) | 476 | if (HYPERVISOR_set_gdt(&mfn, size / sizeof(struct desc_struct))) |
| 501 | BUG(); | 477 | BUG(); |
| 502 | } | 478 | } |
| 503 | 479 | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index d33e7dbe3129..2d76106788a3 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
| @@ -42,13 +42,11 @@ xmaddr_t arbitrary_virt_to_machine(void *vaddr) | |||
| 42 | } | 42 | } |
| 43 | EXPORT_SYMBOL_GPL(arbitrary_virt_to_machine); | 43 | EXPORT_SYMBOL_GPL(arbitrary_virt_to_machine); |
| 44 | 44 | ||
| 45 | static void xen_flush_tlb_all(void) | 45 | static noinline void xen_flush_tlb_all(void) |
| 46 | { | 46 | { |
| 47 | struct mmuext_op *op; | 47 | struct mmuext_op *op; |
| 48 | struct multicall_space mcs; | 48 | struct multicall_space mcs; |
| 49 | 49 | ||
| 50 | trace_xen_mmu_flush_tlb_all(0); | ||
| 51 | |||
| 52 | preempt_disable(); | 50 | preempt_disable(); |
| 53 | 51 | ||
| 54 | mcs = xen_mc_entry(sizeof(*op)); | 52 | mcs = xen_mc_entry(sizeof(*op)); |
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 486c0a34d00b..2c30cabfda90 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c | |||
| @@ -1310,13 +1310,11 @@ unsigned long xen_read_cr2_direct(void) | |||
| 1310 | return this_cpu_read(xen_vcpu_info.arch.cr2); | 1310 | return this_cpu_read(xen_vcpu_info.arch.cr2); |
| 1311 | } | 1311 | } |
| 1312 | 1312 | ||
| 1313 | static void xen_flush_tlb(void) | 1313 | static noinline void xen_flush_tlb(void) |
| 1314 | { | 1314 | { |
| 1315 | struct mmuext_op *op; | 1315 | struct mmuext_op *op; |
| 1316 | struct multicall_space mcs; | 1316 | struct multicall_space mcs; |
| 1317 | 1317 | ||
| 1318 | trace_xen_mmu_flush_tlb(0); | ||
| 1319 | |||
| 1320 | preempt_disable(); | 1318 | preempt_disable(); |
| 1321 | 1319 | ||
| 1322 | mcs = xen_mc_entry(sizeof(*op)); | 1320 | mcs = xen_mc_entry(sizeof(*op)); |
diff --git a/block/blk-mq.c b/block/blk-mq.c index c3621453ad87..9ce9cac16c3f 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -95,18 +95,15 @@ static void blk_mq_check_inflight(struct blk_mq_hw_ctx *hctx, | |||
| 95 | { | 95 | { |
| 96 | struct mq_inflight *mi = priv; | 96 | struct mq_inflight *mi = priv; |
| 97 | 97 | ||
| 98 | if (blk_mq_rq_state(rq) == MQ_RQ_IN_FLIGHT) { | 98 | /* |
| 99 | /* | 99 | * index[0] counts the specific partition that was asked for. index[1] |
| 100 | * index[0] counts the specific partition that was asked | 100 | * counts the ones that are active on the whole device, so increment |
| 101 | * for. index[1] counts the ones that are active on the | 101 | * that if mi->part is indeed a partition, and not a whole device. |
| 102 | * whole device, so increment that if mi->part is indeed | 102 | */ |
| 103 | * a partition, and not a whole device. | 103 | if (rq->part == mi->part) |
| 104 | */ | 104 | mi->inflight[0]++; |
| 105 | if (rq->part == mi->part) | 105 | if (mi->part->partno) |
| 106 | mi->inflight[0]++; | 106 | mi->inflight[1]++; |
| 107 | if (mi->part->partno) | ||
| 108 | mi->inflight[1]++; | ||
| 109 | } | ||
| 110 | } | 107 | } |
| 111 | 108 | ||
| 112 | void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, | 109 | void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, |
| @@ -118,6 +115,25 @@ void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, | |||
| 118 | blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight, &mi); | 115 | blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight, &mi); |
| 119 | } | 116 | } |
| 120 | 117 | ||
| 118 | static void blk_mq_check_inflight_rw(struct blk_mq_hw_ctx *hctx, | ||
| 119 | struct request *rq, void *priv, | ||
| 120 | bool reserved) | ||
| 121 | { | ||
| 122 | struct mq_inflight *mi = priv; | ||
| 123 | |||
| 124 | if (rq->part == mi->part) | ||
| 125 | mi->inflight[rq_data_dir(rq)]++; | ||
| 126 | } | ||
| 127 | |||
| 128 | void blk_mq_in_flight_rw(struct request_queue *q, struct hd_struct *part, | ||
| 129 | unsigned int inflight[2]) | ||
| 130 | { | ||
| 131 | struct mq_inflight mi = { .part = part, .inflight = inflight, }; | ||
| 132 | |||
| 133 | inflight[0] = inflight[1] = 0; | ||
| 134 | blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight_rw, &mi); | ||
| 135 | } | ||
| 136 | |||
| 121 | void blk_freeze_queue_start(struct request_queue *q) | 137 | void blk_freeze_queue_start(struct request_queue *q) |
| 122 | { | 138 | { |
| 123 | int freeze_depth; | 139 | int freeze_depth; |
diff --git a/block/blk-mq.h b/block/blk-mq.h index 89b5cd3a6c70..e1bb420dc5d6 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h | |||
| @@ -188,7 +188,9 @@ static inline bool blk_mq_hw_queue_mapped(struct blk_mq_hw_ctx *hctx) | |||
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, | 190 | void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, |
| 191 | unsigned int inflight[2]); | 191 | unsigned int inflight[2]); |
| 192 | void blk_mq_in_flight_rw(struct request_queue *q, struct hd_struct *part, | ||
| 193 | unsigned int inflight[2]); | ||
| 192 | 194 | ||
| 193 | static inline void blk_mq_put_dispatch_budget(struct blk_mq_hw_ctx *hctx) | 195 | static inline void blk_mq_put_dispatch_budget(struct blk_mq_hw_ctx *hctx) |
| 194 | { | 196 | { |
diff --git a/block/genhd.c b/block/genhd.c index dc7e089373b9..c4513fe1adda 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -82,6 +82,18 @@ void part_in_flight(struct request_queue *q, struct hd_struct *part, | |||
| 82 | } | 82 | } |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, | ||
| 86 | unsigned int inflight[2]) | ||
| 87 | { | ||
| 88 | if (q->mq_ops) { | ||
| 89 | blk_mq_in_flight_rw(q, part, inflight); | ||
| 90 | return; | ||
| 91 | } | ||
| 92 | |||
| 93 | inflight[0] = atomic_read(&part->in_flight[0]); | ||
| 94 | inflight[1] = atomic_read(&part->in_flight[1]); | ||
| 95 | } | ||
| 96 | |||
| 85 | struct hd_struct *__disk_get_part(struct gendisk *disk, int partno) | 97 | struct hd_struct *__disk_get_part(struct gendisk *disk, int partno) |
| 86 | { | 98 | { |
| 87 | struct disk_part_tbl *ptbl = rcu_dereference(disk->part_tbl); | 99 | struct disk_part_tbl *ptbl = rcu_dereference(disk->part_tbl); |
diff --git a/block/partition-generic.c b/block/partition-generic.c index 08dabcd8b6ae..db57cced9b98 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c | |||
| @@ -145,13 +145,15 @@ ssize_t part_stat_show(struct device *dev, | |||
| 145 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); | 145 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | ssize_t part_inflight_show(struct device *dev, | 148 | ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr, |
| 149 | struct device_attribute *attr, char *buf) | 149 | char *buf) |
| 150 | { | 150 | { |
| 151 | struct hd_struct *p = dev_to_part(dev); | 151 | struct hd_struct *p = dev_to_part(dev); |
| 152 | struct request_queue *q = part_to_disk(p)->queue; | ||
| 153 | unsigned int inflight[2]; | ||
| 152 | 154 | ||
| 153 | return sprintf(buf, "%8u %8u\n", atomic_read(&p->in_flight[0]), | 155 | part_in_flight_rw(q, p, inflight); |
| 154 | atomic_read(&p->in_flight[1])); | 156 | return sprintf(buf, "%8u %8u\n", inflight[0], inflight[1]); |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 157 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 159 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 9e4463dda622..b823a86c166d 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
| @@ -87,6 +87,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); | |||
| 87 | 87 | ||
| 88 | 88 | ||
| 89 | static int ac_sleep_before_get_state_ms; | 89 | static int ac_sleep_before_get_state_ms; |
| 90 | static int ac_check_pmic = 1; | ||
| 90 | 91 | ||
| 91 | static struct acpi_driver acpi_ac_driver = { | 92 | static struct acpi_driver acpi_ac_driver = { |
| 92 | .name = "ac", | 93 | .name = "ac", |
| @@ -310,13 +311,19 @@ static int acpi_ac_battery_notify(struct notifier_block *nb, | |||
| 310 | return NOTIFY_OK; | 311 | return NOTIFY_OK; |
| 311 | } | 312 | } |
| 312 | 313 | ||
| 313 | static int thinkpad_e530_quirk(const struct dmi_system_id *d) | 314 | static int __init thinkpad_e530_quirk(const struct dmi_system_id *d) |
| 314 | { | 315 | { |
| 315 | ac_sleep_before_get_state_ms = 1000; | 316 | ac_sleep_before_get_state_ms = 1000; |
| 316 | return 0; | 317 | return 0; |
| 317 | } | 318 | } |
| 318 | 319 | ||
| 319 | static const struct dmi_system_id ac_dmi_table[] = { | 320 | static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d) |
| 321 | { | ||
| 322 | ac_check_pmic = 0; | ||
| 323 | return 0; | ||
| 324 | } | ||
| 325 | |||
| 326 | static const struct dmi_system_id ac_dmi_table[] __initconst = { | ||
| 320 | { | 327 | { |
| 321 | /* Thinkpad e530 */ | 328 | /* Thinkpad e530 */ |
| 322 | .callback = thinkpad_e530_quirk, | 329 | .callback = thinkpad_e530_quirk, |
| @@ -325,6 +332,22 @@ static const struct dmi_system_id ac_dmi_table[] = { | |||
| 325 | DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"), | 332 | DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"), |
| 326 | }, | 333 | }, |
| 327 | }, | 334 | }, |
| 335 | { | ||
| 336 | /* ECS EF20EA */ | ||
| 337 | .callback = ac_do_not_check_pmic_quirk, | ||
| 338 | .matches = { | ||
| 339 | DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), | ||
| 340 | }, | ||
| 341 | }, | ||
| 342 | { | ||
| 343 | /* Lenovo Ideapad Miix 320 */ | ||
| 344 | .callback = ac_do_not_check_pmic_quirk, | ||
| 345 | .matches = { | ||
| 346 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 347 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"), | ||
| 348 | DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), | ||
| 349 | }, | ||
| 350 | }, | ||
| 328 | {}, | 351 | {}, |
| 329 | }; | 352 | }; |
| 330 | 353 | ||
| @@ -384,7 +407,6 @@ end: | |||
| 384 | kfree(ac); | 407 | kfree(ac); |
| 385 | } | 408 | } |
| 386 | 409 | ||
| 387 | dmi_check_system(ac_dmi_table); | ||
| 388 | return result; | 410 | return result; |
| 389 | } | 411 | } |
| 390 | 412 | ||
| @@ -442,13 +464,17 @@ static int __init acpi_ac_init(void) | |||
| 442 | if (acpi_disabled) | 464 | if (acpi_disabled) |
| 443 | return -ENODEV; | 465 | return -ENODEV; |
| 444 | 466 | ||
| 445 | for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++) | 467 | dmi_check_system(ac_dmi_table); |
| 446 | if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1", | 468 | |
| 447 | acpi_ac_blacklist[i].hrv)) { | 469 | if (ac_check_pmic) { |
| 448 | pr_info(PREFIX "AC: found native %s PMIC, not loading\n", | 470 | for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++) |
| 449 | acpi_ac_blacklist[i].hid); | 471 | if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1", |
| 450 | return -ENODEV; | 472 | acpi_ac_blacklist[i].hrv)) { |
| 451 | } | 473 | pr_info(PREFIX "AC: found native %s PMIC, not loading\n", |
| 474 | acpi_ac_blacklist[i].hid); | ||
| 475 | return -ENODEV; | ||
| 476 | } | ||
| 477 | } | ||
| 452 | 478 | ||
| 453 | #ifdef CONFIG_ACPI_PROCFS_POWER | 479 | #ifdef CONFIG_ACPI_PROCFS_POWER |
| 454 | acpi_ac_dir = acpi_lock_ac_dir(); | 480 | acpi_ac_dir = acpi_lock_ac_dir(); |
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 4bde16fb97d8..95600309ce42 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c | |||
| @@ -12,35 +12,51 @@ | |||
| 12 | #define pr_fmt(fmt) "ACPI: watchdog: " fmt | 12 | #define pr_fmt(fmt) "ACPI: watchdog: " fmt |
| 13 | 13 | ||
| 14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
| 15 | #include <linux/dmi.h> | ||
| 16 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
| 17 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 18 | 17 | ||
| 19 | #include "internal.h" | 18 | #include "internal.h" |
| 20 | 19 | ||
| 21 | static const struct dmi_system_id acpi_watchdog_skip[] = { | 20 | #ifdef CONFIG_RTC_MC146818_LIB |
| 22 | { | 21 | #include <linux/mc146818rtc.h> |
| 23 | /* | 22 | |
| 24 | * On Lenovo Z50-70 there are two issues with the WDAT | 23 | /* |
| 25 | * table. First some of the instructions use RTC SRAM | 24 | * There are several systems where the WDAT table is accessing RTC SRAM to |
| 26 | * to store persistent information. This does not work well | 25 | * store persistent information. This does not work well with the Linux RTC |
| 27 | * with Linux RTC driver. Second, more important thing is | 26 | * driver so on those systems we skip WDAT driver and prefer iTCO_wdt |
| 28 | * that the instructions do not actually reset the system. | 27 | * instead. |
| 29 | * | 28 | * |
| 30 | * On this particular system iTCO_wdt seems to work just | 29 | * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. |
| 31 | * fine so we prefer that over WDAT for now. | 30 | */ |
| 32 | * | 31 | static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) |
| 33 | * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. | 32 | { |
| 34 | */ | 33 | const struct acpi_wdat_entry *entries; |
| 35 | .ident = "Lenovo Z50-70", | 34 | int i; |
| 36 | .matches = { | 35 | |
| 37 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 36 | entries = (struct acpi_wdat_entry *)(wdat + 1); |
| 38 | DMI_MATCH(DMI_PRODUCT_NAME, "20354"), | 37 | for (i = 0; i < wdat->entries; i++) { |
| 39 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"), | 38 | const struct acpi_generic_address *gas; |
| 40 | }, | 39 | |
| 41 | }, | 40 | gas = &entries[i].register_region; |
| 42 | {} | 41 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
| 43 | }; | 42 | switch (gas->address) { |
| 43 | case RTC_PORT(0): | ||
| 44 | case RTC_PORT(1): | ||
| 45 | case RTC_PORT(2): | ||
| 46 | case RTC_PORT(3): | ||
| 47 | return true; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | return false; | ||
| 53 | } | ||
| 54 | #else | ||
| 55 | static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) | ||
| 56 | { | ||
| 57 | return false; | ||
| 58 | } | ||
| 59 | #endif | ||
| 44 | 60 | ||
| 45 | static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) | 61 | static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) |
| 46 | { | 62 | { |
| @@ -50,9 +66,6 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) | |||
| 50 | if (acpi_disabled) | 66 | if (acpi_disabled) |
| 51 | return NULL; | 67 | return NULL; |
| 52 | 68 | ||
| 53 | if (dmi_check_system(acpi_watchdog_skip)) | ||
| 54 | return NULL; | ||
| 55 | |||
| 56 | status = acpi_get_table(ACPI_SIG_WDAT, 0, | 69 | status = acpi_get_table(ACPI_SIG_WDAT, 0, |
| 57 | (struct acpi_table_header **)&wdat); | 70 | (struct acpi_table_header **)&wdat); |
| 58 | if (ACPI_FAILURE(status)) { | 71 | if (ACPI_FAILURE(status)) { |
| @@ -60,6 +73,11 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) | |||
| 60 | return NULL; | 73 | return NULL; |
| 61 | } | 74 | } |
| 62 | 75 | ||
| 76 | if (acpi_watchdog_uses_rtc(wdat)) { | ||
| 77 | pr_info("Skipping WDAT on this system because it uses RTC SRAM\n"); | ||
| 78 | return NULL; | ||
| 79 | } | ||
| 80 | |||
| 63 | return wdat; | 81 | return wdat; |
| 64 | } | 82 | } |
| 65 | 83 | ||
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index a2a85122fafe..5a9c2febc0fb 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h | |||
| @@ -143,6 +143,8 @@ acpi_status | |||
| 143 | fl_split_input_pathname(char *input_path, | 143 | fl_split_input_pathname(char *input_path, |
| 144 | char **out_directory_path, char **out_filename); | 144 | char **out_directory_path, char **out_filename); |
| 145 | 145 | ||
| 146 | char *fl_get_file_basename(char *file_pathname); | ||
| 147 | |||
| 146 | char *ad_generate_filename(char *prefix, char *table_id); | 148 | char *ad_generate_filename(char *prefix, char *table_id); |
| 147 | 149 | ||
| 148 | void | 150 | void |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 0bc550072a21..1e6204518496 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
| @@ -82,7 +82,7 @@ ACPI_GLOBAL(u8, acpi_gbl_global_lock_pending); | |||
| 82 | * interrupt level | 82 | * interrupt level |
| 83 | */ | 83 | */ |
| 84 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */ | 84 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */ |
| 85 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ | 85 | ACPI_GLOBAL(acpi_raw_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ |
| 86 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock); | 86 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock); |
| 87 | 87 | ||
| 88 | /* Mutex for _OSI support */ | 88 | /* Mutex for _OSI support */ |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 514aaf948ea9..3825df923480 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
| @@ -56,6 +56,10 @@ acpi_status acpi_ns_initialize_objects(void); | |||
| 56 | 56 | ||
| 57 | acpi_status acpi_ns_initialize_devices(u32 flags); | 57 | acpi_status acpi_ns_initialize_devices(u32 flags); |
| 58 | 58 | ||
| 59 | acpi_status | ||
| 60 | acpi_ns_init_one_package(acpi_handle obj_handle, | ||
| 61 | u32 level, void *context, void **return_value); | ||
| 62 | |||
| 59 | /* | 63 | /* |
| 60 | * nsload - Namespace loading | 64 | * nsload - Namespace loading |
| 61 | */ | 65 | */ |
diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c index 170802c62179..dc94de91033e 100644 --- a/drivers/acpi/acpica/dbnames.c +++ b/drivers/acpi/acpica/dbnames.c | |||
| @@ -189,9 +189,15 @@ void acpi_db_dump_namespace(char *start_arg, char *depth_arg) | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | 191 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); |
| 192 | acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n", | 192 | |
| 193 | ((struct acpi_namespace_node *)subtree_entry)->name. | 193 | if (((struct acpi_namespace_node *)subtree_entry)->parent) { |
| 194 | ascii, subtree_entry); | 194 | acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n", |
| 195 | ((struct acpi_namespace_node *)subtree_entry)-> | ||
| 196 | name.ascii, subtree_entry); | ||
| 197 | } else { | ||
| 198 | acpi_os_printf("ACPI Namespace (from %s):\n", | ||
| 199 | ACPI_NAMESPACE_ROOT); | ||
| 200 | } | ||
| 195 | 201 | ||
| 196 | /* Display the subtree */ | 202 | /* Display the subtree */ |
| 197 | 203 | ||
diff --git a/drivers/acpi/acpica/dbtest.c b/drivers/acpi/acpica/dbtest.c index 3892680a5258..8a5462439a97 100644 --- a/drivers/acpi/acpica/dbtest.c +++ b/drivers/acpi/acpica/dbtest.c | |||
| @@ -30,6 +30,8 @@ acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length); | |||
| 30 | static acpi_status | 30 | static acpi_status |
| 31 | acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length); | 31 | acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length); |
| 32 | 32 | ||
| 33 | static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node); | ||
| 34 | |||
| 33 | static acpi_status | 35 | static acpi_status |
| 34 | acpi_db_read_from_object(struct acpi_namespace_node *node, | 36 | acpi_db_read_from_object(struct acpi_namespace_node *node, |
| 35 | acpi_object_type expected_type, | 37 | acpi_object_type expected_type, |
| @@ -273,6 +275,11 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
| 273 | bit_length = byte_length * 8; | 275 | bit_length = byte_length * 8; |
| 274 | break; | 276 | break; |
| 275 | 277 | ||
| 278 | case ACPI_TYPE_PACKAGE: | ||
| 279 | |||
| 280 | local_type = ACPI_TYPE_PACKAGE; | ||
| 281 | break; | ||
| 282 | |||
| 276 | case ACPI_TYPE_FIELD_UNIT: | 283 | case ACPI_TYPE_FIELD_UNIT: |
| 277 | case ACPI_TYPE_BUFFER_FIELD: | 284 | case ACPI_TYPE_BUFFER_FIELD: |
| 278 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 285 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
| @@ -305,6 +312,7 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
| 305 | 312 | ||
| 306 | acpi_os_printf("%14s: %4.4s", | 313 | acpi_os_printf("%14s: %4.4s", |
| 307 | acpi_ut_get_type_name(node->type), node->name.ascii); | 314 | acpi_ut_get_type_name(node->type), node->name.ascii); |
| 315 | |||
| 308 | if (!obj_desc) { | 316 | if (!obj_desc) { |
| 309 | acpi_os_printf(" Ignoring, no attached object\n"); | 317 | acpi_os_printf(" Ignoring, no attached object\n"); |
| 310 | return (AE_OK); | 318 | return (AE_OK); |
| @@ -322,14 +330,13 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
| 322 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 330 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
| 323 | case ACPI_ADR_SPACE_SYSTEM_IO: | 331 | case ACPI_ADR_SPACE_SYSTEM_IO: |
| 324 | case ACPI_ADR_SPACE_PCI_CONFIG: | 332 | case ACPI_ADR_SPACE_PCI_CONFIG: |
| 325 | case ACPI_ADR_SPACE_EC: | ||
| 326 | 333 | ||
| 327 | break; | 334 | break; |
| 328 | 335 | ||
| 329 | default: | 336 | default: |
| 330 | 337 | ||
| 331 | acpi_os_printf | 338 | acpi_os_printf |
| 332 | (" %s space is not supported [%4.4s]\n", | 339 | (" %s space is not supported in this command [%4.4s]\n", |
| 333 | acpi_ut_get_region_name(region_obj->region. | 340 | acpi_ut_get_region_name(region_obj->region. |
| 334 | space_id), | 341 | space_id), |
| 335 | region_obj->region.node->name.ascii); | 342 | region_obj->region.node->name.ascii); |
| @@ -359,6 +366,11 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
| 359 | status = acpi_db_test_buffer_type(node, bit_length); | 366 | status = acpi_db_test_buffer_type(node, bit_length); |
| 360 | break; | 367 | break; |
| 361 | 368 | ||
| 369 | case ACPI_TYPE_PACKAGE: | ||
| 370 | |||
| 371 | status = acpi_db_test_package_type(node); | ||
| 372 | break; | ||
| 373 | |||
| 362 | default: | 374 | default: |
| 363 | 375 | ||
| 364 | acpi_os_printf(" Ignoring, type not implemented (%2.2X)", | 376 | acpi_os_printf(" Ignoring, type not implemented (%2.2X)", |
| @@ -366,6 +378,13 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
| 366 | break; | 378 | break; |
| 367 | } | 379 | } |
| 368 | 380 | ||
| 381 | /* Exit on error, but don't abort the namespace walk */ | ||
| 382 | |||
| 383 | if (ACPI_FAILURE(status)) { | ||
| 384 | status = AE_OK; | ||
| 385 | goto exit; | ||
| 386 | } | ||
| 387 | |||
| 369 | switch (node->type) { | 388 | switch (node->type) { |
| 370 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 389 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
| 371 | 390 | ||
| @@ -373,12 +392,14 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
| 373 | acpi_os_printf(" (%s)", | 392 | acpi_os_printf(" (%s)", |
| 374 | acpi_ut_get_region_name(region_obj->region. | 393 | acpi_ut_get_region_name(region_obj->region. |
| 375 | space_id)); | 394 | space_id)); |
| 395 | |||
| 376 | break; | 396 | break; |
| 377 | 397 | ||
| 378 | default: | 398 | default: |
| 379 | break; | 399 | break; |
| 380 | } | 400 | } |
| 381 | 401 | ||
| 402 | exit: | ||
| 382 | acpi_os_printf("\n"); | 403 | acpi_os_printf("\n"); |
| 383 | return (status); | 404 | return (status); |
| 384 | } | 405 | } |
| @@ -431,7 +452,6 @@ acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length) | |||
| 431 | if (temp1->integer.value == value_to_write) { | 452 | if (temp1->integer.value == value_to_write) { |
| 432 | value_to_write = 0; | 453 | value_to_write = 0; |
| 433 | } | 454 | } |
| 434 | |||
| 435 | /* Write a new value */ | 455 | /* Write a new value */ |
| 436 | 456 | ||
| 437 | write_value.type = ACPI_TYPE_INTEGER; | 457 | write_value.type = ACPI_TYPE_INTEGER; |
| @@ -708,6 +728,35 @@ exit: | |||
| 708 | 728 | ||
| 709 | /******************************************************************************* | 729 | /******************************************************************************* |
| 710 | * | 730 | * |
| 731 | * FUNCTION: acpi_db_test_package_type | ||
| 732 | * | ||
| 733 | * PARAMETERS: node - Parent NS node for the object | ||
| 734 | * | ||
| 735 | * RETURN: Status | ||
| 736 | * | ||
| 737 | * DESCRIPTION: Test read for a Package object. | ||
| 738 | * | ||
| 739 | ******************************************************************************/ | ||
| 740 | |||
| 741 | static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node) | ||
| 742 | { | ||
| 743 | union acpi_object *temp1 = NULL; | ||
| 744 | acpi_status status; | ||
| 745 | |||
| 746 | /* Read the original value */ | ||
| 747 | |||
| 748 | status = acpi_db_read_from_object(node, ACPI_TYPE_PACKAGE, &temp1); | ||
| 749 | if (ACPI_FAILURE(status)) { | ||
| 750 | return (status); | ||
| 751 | } | ||
| 752 | |||
| 753 | acpi_os_printf(" %8.8X Elements", temp1->package.count); | ||
| 754 | acpi_os_free(temp1); | ||
| 755 | return (status); | ||
| 756 | } | ||
| 757 | |||
| 758 | /******************************************************************************* | ||
| 759 | * | ||
| 711 | * FUNCTION: acpi_db_read_from_object | 760 | * FUNCTION: acpi_db_read_from_object |
| 712 | * | 761 | * |
| 713 | * PARAMETERS: node - Parent NS node for the object | 762 | * PARAMETERS: node - Parent NS node for the object |
| @@ -746,8 +795,8 @@ acpi_db_read_from_object(struct acpi_namespace_node *node, | |||
| 746 | acpi_gbl_method_executing = TRUE; | 795 | acpi_gbl_method_executing = TRUE; |
| 747 | status = acpi_evaluate_object(read_handle, NULL, | 796 | status = acpi_evaluate_object(read_handle, NULL, |
| 748 | ¶m_objects, &return_obj); | 797 | ¶m_objects, &return_obj); |
| 749 | acpi_gbl_method_executing = FALSE; | ||
| 750 | 798 | ||
| 799 | acpi_gbl_method_executing = FALSE; | ||
| 751 | if (ACPI_FAILURE(status)) { | 800 | if (ACPI_FAILURE(status)) { |
| 752 | acpi_os_printf("Could not read from object, %s", | 801 | acpi_os_printf("Could not read from object, %s", |
| 753 | acpi_format_exception(status)); | 802 | acpi_format_exception(status)); |
| @@ -760,6 +809,7 @@ acpi_db_read_from_object(struct acpi_namespace_node *node, | |||
| 760 | case ACPI_TYPE_INTEGER: | 809 | case ACPI_TYPE_INTEGER: |
| 761 | case ACPI_TYPE_BUFFER: | 810 | case ACPI_TYPE_BUFFER: |
| 762 | case ACPI_TYPE_STRING: | 811 | case ACPI_TYPE_STRING: |
| 812 | case ACPI_TYPE_PACKAGE: | ||
| 763 | /* | 813 | /* |
| 764 | * Did we receive the type we wanted? Most important for the | 814 | * Did we receive the type we wanted? Most important for the |
| 765 | * Integer/Buffer case (when a field is larger than an Integer, | 815 | * Integer/Buffer case (when a field is larger than an Integer, |
| @@ -771,6 +821,7 @@ acpi_db_read_from_object(struct acpi_namespace_node *node, | |||
| 771 | acpi_ut_get_type_name(expected_type), | 821 | acpi_ut_get_type_name(expected_type), |
| 772 | acpi_ut_get_type_name(ret_value->type)); | 822 | acpi_ut_get_type_name(ret_value->type)); |
| 773 | 823 | ||
| 824 | acpi_os_free(return_obj.pointer); | ||
| 774 | return (AE_TYPE); | 825 | return (AE_TYPE); |
| 775 | } | 826 | } |
| 776 | 827 | ||
diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index d1422f984f6e..7592176a8fa2 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c | |||
| @@ -115,7 +115,7 @@ acpi_ds_scope_stack_push(struct acpi_namespace_node *node, | |||
| 115 | acpi_ut_get_type_name(old_scope_info-> | 115 | acpi_ut_get_type_name(old_scope_info-> |
| 116 | common.value))); | 116 | common.value))); |
| 117 | } else { | 117 | } else { |
| 118 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[\\___] (%s)", "ROOT")); | 118 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, ACPI_NAMESPACE_ROOT)); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, | 121 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, |
| @@ -166,14 +166,14 @@ acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state) | |||
| 166 | 166 | ||
| 167 | new_scope_info = walk_state->scope_info; | 167 | new_scope_info = walk_state->scope_info; |
| 168 | if (new_scope_info) { | 168 | if (new_scope_info) { |
| 169 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, | 169 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[%4.4s] (%s)\n", |
| 170 | "[%4.4s] (%s)\n", | ||
| 171 | acpi_ut_get_node_name(new_scope_info-> | 170 | acpi_ut_get_node_name(new_scope_info-> |
| 172 | scope.node), | 171 | scope.node), |
| 173 | acpi_ut_get_type_name(new_scope_info-> | 172 | acpi_ut_get_type_name(new_scope_info-> |
| 174 | common.value))); | 173 | common.value))); |
| 175 | } else { | 174 | } else { |
| 176 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[\\___] (ROOT)\n")); | 175 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "%s\n", |
| 176 | ACPI_NAMESPACE_ROOT)); | ||
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | acpi_ut_delete_generic_state(scope_info); | 179 | acpi_ut_delete_generic_state(scope_info); |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 99d92cb32803..f85c6f3271f6 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
| @@ -174,6 +174,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
| 174 | return_ACPI_STATUS(status); | 174 | return_ACPI_STATUS(status); |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | /* Complete the initialization/resolution of package objects */ | ||
| 178 | |||
| 179 | status = acpi_ns_walk_namespace(ACPI_TYPE_PACKAGE, ACPI_ROOT_OBJECT, | ||
| 180 | ACPI_UINT32_MAX, 0, | ||
| 181 | acpi_ns_init_one_package, NULL, NULL, | ||
| 182 | NULL); | ||
| 183 | |||
| 177 | /* Parameter Data (optional) */ | 184 | /* Parameter Data (optional) */ |
| 178 | 185 | ||
| 179 | if (parameter_node) { | 186 | if (parameter_node) { |
| @@ -430,6 +437,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
| 430 | return_ACPI_STATUS(status); | 437 | return_ACPI_STATUS(status); |
| 431 | } | 438 | } |
| 432 | 439 | ||
| 440 | /* Complete the initialization/resolution of package objects */ | ||
| 441 | |||
| 442 | status = acpi_ns_walk_namespace(ACPI_TYPE_PACKAGE, ACPI_ROOT_OBJECT, | ||
| 443 | ACPI_UINT32_MAX, 0, | ||
| 444 | acpi_ns_init_one_package, NULL, NULL, | ||
| 445 | NULL); | ||
| 446 | |||
| 433 | /* Store the ddb_handle into the Target operand */ | 447 | /* Store the ddb_handle into the Target operand */ |
| 434 | 448 | ||
| 435 | status = acpi_ex_store(ddb_handle, target, walk_state); | 449 | status = acpi_ex_store(ddb_handle, target, walk_state); |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 27a86ad55b58..3de794bcf8fa 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
| @@ -390,14 +390,14 @@ acpi_status acpi_hw_clear_acpi_status(void) | |||
| 390 | ACPI_BITMASK_ALL_FIXED_STATUS, | 390 | ACPI_BITMASK_ALL_FIXED_STATUS, |
| 391 | ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); | 391 | ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); |
| 392 | 392 | ||
| 393 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 393 | lock_flags = acpi_os_acquire_raw_lock(acpi_gbl_hardware_lock); |
| 394 | 394 | ||
| 395 | /* Clear the fixed events in PM1 A/B */ | 395 | /* Clear the fixed events in PM1 A/B */ |
| 396 | 396 | ||
| 397 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, | 397 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, |
| 398 | ACPI_BITMASK_ALL_FIXED_STATUS); | 398 | ACPI_BITMASK_ALL_FIXED_STATUS); |
| 399 | 399 | ||
| 400 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | 400 | acpi_os_release_raw_lock(acpi_gbl_hardware_lock, lock_flags); |
| 401 | 401 | ||
| 402 | if (ACPI_FAILURE(status)) { | 402 | if (ACPI_FAILURE(status)) { |
| 403 | goto exit; | 403 | goto exit; |
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 5d1396870bd0..6e39a771a56e 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
| @@ -227,7 +227,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) | |||
| 227 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 227 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 230 | lock_flags = acpi_os_acquire_raw_lock(acpi_gbl_hardware_lock); |
| 231 | 231 | ||
| 232 | /* | 232 | /* |
| 233 | * At this point, we know that the parent register is one of the | 233 | * At this point, we know that the parent register is one of the |
| @@ -288,7 +288,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) | |||
| 288 | 288 | ||
| 289 | unlock_and_exit: | 289 | unlock_and_exit: |
| 290 | 290 | ||
| 291 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | 291 | acpi_os_release_raw_lock(acpi_gbl_hardware_lock, lock_flags); |
| 292 | return_ACPI_STATUS(status); | 292 | return_ACPI_STATUS(status); |
| 293 | } | 293 | } |
| 294 | 294 | ||
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 77f2b5f4948a..d77257d1c827 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c | |||
| @@ -242,6 +242,58 @@ error_exit: | |||
| 242 | 242 | ||
| 243 | /******************************************************************************* | 243 | /******************************************************************************* |
| 244 | * | 244 | * |
| 245 | * FUNCTION: acpi_ns_init_one_package | ||
| 246 | * | ||
| 247 | * PARAMETERS: obj_handle - Node | ||
| 248 | * level - Current nesting level | ||
| 249 | * context - Not used | ||
| 250 | * return_value - Not used | ||
| 251 | * | ||
| 252 | * RETURN: Status | ||
| 253 | * | ||
| 254 | * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every package | ||
| 255 | * within the namespace. Used during dynamic load of an SSDT. | ||
| 256 | * | ||
| 257 | ******************************************************************************/ | ||
| 258 | |||
| 259 | acpi_status | ||
| 260 | acpi_ns_init_one_package(acpi_handle obj_handle, | ||
| 261 | u32 level, void *context, void **return_value) | ||
| 262 | { | ||
| 263 | acpi_status status; | ||
| 264 | union acpi_operand_object *obj_desc; | ||
| 265 | struct acpi_namespace_node *node = | ||
| 266 | (struct acpi_namespace_node *)obj_handle; | ||
| 267 | |||
| 268 | obj_desc = acpi_ns_get_attached_object(node); | ||
| 269 | if (!obj_desc) { | ||
| 270 | return (AE_OK); | ||
| 271 | } | ||
| 272 | |||
| 273 | /* Exit if package is already initialized */ | ||
| 274 | |||
| 275 | if (obj_desc->package.flags & AOPOBJ_DATA_VALID) { | ||
| 276 | return (AE_OK); | ||
| 277 | } | ||
| 278 | |||
| 279 | status = acpi_ds_get_package_arguments(obj_desc); | ||
| 280 | if (ACPI_FAILURE(status)) { | ||
| 281 | return (AE_OK); | ||
| 282 | } | ||
| 283 | |||
| 284 | status = | ||
| 285 | acpi_ut_walk_package_tree(obj_desc, NULL, | ||
| 286 | acpi_ds_init_package_element, NULL); | ||
| 287 | if (ACPI_FAILURE(status)) { | ||
| 288 | return (AE_OK); | ||
| 289 | } | ||
| 290 | |||
| 291 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; | ||
| 292 | return (AE_OK); | ||
| 293 | } | ||
| 294 | |||
| 295 | /******************************************************************************* | ||
| 296 | * | ||
| 245 | * FUNCTION: acpi_ns_init_one_object | 297 | * FUNCTION: acpi_ns_init_one_object |
| 246 | * | 298 | * |
| 247 | * PARAMETERS: obj_handle - Node | 299 | * PARAMETERS: obj_handle - Node |
| @@ -360,27 +412,11 @@ acpi_ns_init_one_object(acpi_handle obj_handle, | |||
| 360 | 412 | ||
| 361 | case ACPI_TYPE_PACKAGE: | 413 | case ACPI_TYPE_PACKAGE: |
| 362 | 414 | ||
| 363 | info->package_init++; | 415 | /* Complete the initialization/resolution of the package object */ |
| 364 | status = acpi_ds_get_package_arguments(obj_desc); | ||
| 365 | if (ACPI_FAILURE(status)) { | ||
| 366 | break; | ||
| 367 | } | ||
| 368 | |||
| 369 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE, | ||
| 370 | "%s: Completing resolution of Package elements\n", | ||
| 371 | ACPI_GET_FUNCTION_NAME)); | ||
| 372 | 416 | ||
| 373 | /* | 417 | info->package_init++; |
| 374 | * Resolve all named references in package objects (and all | 418 | status = |
| 375 | * sub-packages). This action has been deferred until the entire | 419 | acpi_ns_init_one_package(obj_handle, level, NULL, NULL); |
| 376 | * namespace has been loaded, in order to support external and | ||
| 377 | * forward references from individual package elements (05/2017). | ||
| 378 | */ | ||
| 379 | status = acpi_ut_walk_package_tree(obj_desc, NULL, | ||
| 380 | acpi_ds_init_package_element, | ||
| 381 | NULL); | ||
| 382 | |||
| 383 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; | ||
| 384 | break; | 420 | break; |
| 385 | 421 | ||
| 386 | default: | 422 | default: |
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index b12a0b1cd9ce..6601e71b45e3 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c | |||
| @@ -539,7 +539,7 @@ static void acpi_rs_out_title(const char *title) | |||
| 539 | 539 | ||
| 540 | static void acpi_rs_dump_byte_list(u16 length, u8 * data) | 540 | static void acpi_rs_dump_byte_list(u16 length, u8 * data) |
| 541 | { | 541 | { |
| 542 | u8 i; | 542 | u16 i; |
| 543 | 543 | ||
| 544 | for (i = 0; i < length; i++) { | 544 | for (i = 0; i < length; i++) { |
| 545 | acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]); | 545 | acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]); |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index c5085b7ae8c9..5f8e7b561c90 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
| @@ -88,7 +88,7 @@ acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, | |||
| 88 | * DESCRIPTION: This function is called to verify and install an ACPI table. | 88 | * DESCRIPTION: This function is called to verify and install an ACPI table. |
| 89 | * When this function is called by "Load" or "LoadTable" opcodes, | 89 | * When this function is called by "Load" or "LoadTable" opcodes, |
| 90 | * or by acpi_load_table() API, the "Reload" parameter is set. | 90 | * or by acpi_load_table() API, the "Reload" parameter is set. |
| 91 | * After sucessfully returning from this function, table is | 91 | * After successfully returning from this function, table is |
| 92 | * "INSTALLED" but not "VALIDATED". | 92 | * "INSTALLED" but not "VALIDATED". |
| 93 | * | 93 | * |
| 94 | ******************************************************************************/ | 94 | ******************************************************************************/ |
diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c index 148aeb84e561..fffa6f5ae59e 100644 --- a/drivers/acpi/acpica/utbuffer.c +++ b/drivers/acpi/acpica/utbuffer.c | |||
| @@ -53,7 +53,7 @@ void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset) | |||
| 53 | 53 | ||
| 54 | /* Print current offset */ | 54 | /* Print current offset */ |
| 55 | 55 | ||
| 56 | acpi_os_printf("%6.4X: ", (base_offset + i)); | 56 | acpi_os_printf("%8.4X: ", (base_offset + i)); |
| 57 | 57 | ||
| 58 | /* Print 16 hex chars */ | 58 | /* Print 16 hex chars */ |
| 59 | 59 | ||
| @@ -219,7 +219,7 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file, | |||
| 219 | 219 | ||
| 220 | /* Print current offset */ | 220 | /* Print current offset */ |
| 221 | 221 | ||
| 222 | fprintf(file, "%6.4X: ", (base_offset + i)); | 222 | fprintf(file, "%8.4X: ", (base_offset + i)); |
| 223 | 223 | ||
| 224 | /* Print 16 hex chars */ | 224 | /* Print 16 hex chars */ |
| 225 | 225 | ||
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index d2d93e388f40..2e465e6a0ab6 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
| @@ -52,7 +52,7 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
| 52 | return_ACPI_STATUS (status); | 52 | return_ACPI_STATUS (status); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | status = acpi_os_create_lock (&acpi_gbl_hardware_lock); | 55 | status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock); |
| 56 | if (ACPI_FAILURE (status)) { | 56 | if (ACPI_FAILURE (status)) { |
| 57 | return_ACPI_STATUS (status); | 57 | return_ACPI_STATUS (status); |
| 58 | } | 58 | } |
| @@ -109,7 +109,7 @@ void acpi_ut_mutex_terminate(void) | |||
| 109 | /* Delete the spinlocks */ | 109 | /* Delete the spinlocks */ |
| 110 | 110 | ||
| 111 | acpi_os_delete_lock(acpi_gbl_gpe_lock); | 111 | acpi_os_delete_lock(acpi_gbl_gpe_lock); |
| 112 | acpi_os_delete_lock(acpi_gbl_hardware_lock); | 112 | acpi_os_delete_raw_lock(acpi_gbl_hardware_lock); |
| 113 | acpi_os_delete_lock(acpi_gbl_reference_count_lock); | 113 | acpi_os_delete_lock(acpi_gbl_reference_count_lock); |
| 114 | 114 | ||
| 115 | /* Delete the reader/writer lock */ | 115 | /* Delete the reader/writer lock */ |
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index 5b78fe08d7d7..ae6d8cc18cec 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | *****************************************************************************/ | 8 | *****************************************************************************/ |
| 9 | 9 | ||
| 10 | #include <acpi/acpi.h> | 10 | #include <acpi/acpi.h> |
| 11 | #include <linux/kmemleak.h> | ||
| 11 | #include "accommon.h" | 12 | #include "accommon.h" |
| 12 | #include "acnamesp.h" | 13 | #include "acnamesp.h" |
| 13 | 14 | ||
| @@ -70,6 +71,7 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char | |||
| 70 | if (!object) { | 71 | if (!object) { |
| 71 | return_PTR(NULL); | 72 | return_PTR(NULL); |
| 72 | } | 73 | } |
| 74 | kmemleak_not_leak(object); | ||
| 73 | 75 | ||
| 74 | switch (type) { | 76 | switch (type) { |
| 75 | case ACPI_TYPE_REGION: | 77 | case ACPI_TYPE_REGION: |
diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index 35ffd8d51c65..a98c334c3bb7 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c | |||
| @@ -470,6 +470,7 @@ int vsnprintf(char *string, acpi_size size, const char *format, va_list args) | |||
| 470 | case 'X': | 470 | case 'X': |
| 471 | 471 | ||
| 472 | type |= ACPI_FORMAT_UPPER; | 472 | type |= ACPI_FORMAT_UPPER; |
| 473 | /* FALLTHROUGH */ | ||
| 473 | 474 | ||
| 474 | case 'x': | 475 | case 'x': |
| 475 | 476 | ||
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index bd57a77bbcb2..5bef0b059406 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c | |||
| @@ -141,7 +141,7 @@ void acpi_ut_repair_name(char *name) | |||
| 141 | * Special case for the root node. This can happen if we get an | 141 | * Special case for the root node. This can happen if we get an |
| 142 | * error during the execution of module-level code. | 142 | * error during the execution of module-level code. |
| 143 | */ | 143 | */ |
| 144 | if (ACPI_COMPARE_NAME(name, "\\___")) { | 144 | if (ACPI_COMPARE_NAME(name, ACPI_ROOT_PATHNAME)) { |
| 145 | return; | 145 | return; |
| 146 | } | 146 | } |
| 147 | 147 | ||
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 735c74a4cbdb..d9ce4b162e2c 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | #include <linux/cpufreq.h> | 40 | #include <linux/cpufreq.h> |
| 41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
| 42 | #include <linux/iopoll.h> | ||
| 42 | #include <linux/ktime.h> | 43 | #include <linux/ktime.h> |
| 43 | #include <linux/rwsem.h> | 44 | #include <linux/rwsem.h> |
| 44 | #include <linux/wait.h> | 45 | #include <linux/wait.h> |
| @@ -49,7 +50,7 @@ struct cppc_pcc_data { | |||
| 49 | struct mbox_chan *pcc_channel; | 50 | struct mbox_chan *pcc_channel; |
| 50 | void __iomem *pcc_comm_addr; | 51 | void __iomem *pcc_comm_addr; |
| 51 | bool pcc_channel_acquired; | 52 | bool pcc_channel_acquired; |
| 52 | ktime_t deadline; | 53 | unsigned int deadline_us; |
| 53 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; | 54 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; |
| 54 | 55 | ||
| 55 | bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ | 56 | bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ |
| @@ -156,6 +157,9 @@ show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, highest_perf); | |||
| 156 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf); | 157 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf); |
| 157 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf); | 158 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf); |
| 158 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf); | 159 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf); |
| 160 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_freq); | ||
| 161 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_freq); | ||
| 162 | |||
| 159 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf); | 163 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf); |
| 160 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); | 164 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); |
| 161 | 165 | ||
| @@ -183,6 +187,8 @@ static struct attribute *cppc_attrs[] = { | |||
| 183 | &lowest_perf.attr, | 187 | &lowest_perf.attr, |
| 184 | &lowest_nonlinear_perf.attr, | 188 | &lowest_nonlinear_perf.attr, |
| 185 | &nominal_perf.attr, | 189 | &nominal_perf.attr, |
| 190 | &nominal_freq.attr, | ||
| 191 | &lowest_freq.attr, | ||
| 186 | NULL | 192 | NULL |
| 187 | }; | 193 | }; |
| 188 | 194 | ||
| @@ -193,42 +199,31 @@ static struct kobj_type cppc_ktype = { | |||
| 193 | 199 | ||
| 194 | static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) | 200 | static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) |
| 195 | { | 201 | { |
| 196 | int ret = -EIO, status = 0; | 202 | int ret, status; |
| 197 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | 203 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; |
| 198 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = | 204 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = |
| 199 | pcc_ss_data->pcc_comm_addr; | 205 | pcc_ss_data->pcc_comm_addr; |
| 200 | ktime_t next_deadline = ktime_add(ktime_get(), | ||
| 201 | pcc_ss_data->deadline); | ||
| 202 | 206 | ||
| 203 | if (!pcc_ss_data->platform_owns_pcc) | 207 | if (!pcc_ss_data->platform_owns_pcc) |
| 204 | return 0; | 208 | return 0; |
| 205 | 209 | ||
| 206 | /* Retry in case the remote processor was too slow to catch up. */ | 210 | /* |
| 207 | while (!ktime_after(ktime_get(), next_deadline)) { | 211 | * Poll PCC status register every 3us(delay_us) for maximum of |
| 208 | /* | 212 | * deadline_us(timeout_us) until PCC command complete bit is set(cond) |
| 209 | * Per spec, prior to boot the PCC space wil be initialized by | 213 | */ |
| 210 | * platform and should have set the command completion bit when | 214 | ret = readw_relaxed_poll_timeout(&generic_comm_base->status, status, |
| 211 | * PCC can be used by OSPM | 215 | status & PCC_CMD_COMPLETE_MASK, 3, |
| 212 | */ | 216 | pcc_ss_data->deadline_us); |
| 213 | status = readw_relaxed(&generic_comm_base->status); | ||
| 214 | if (status & PCC_CMD_COMPLETE_MASK) { | ||
| 215 | ret = 0; | ||
| 216 | if (chk_err_bit && (status & PCC_ERROR_MASK)) | ||
| 217 | ret = -EIO; | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | /* | ||
| 221 | * Reducing the bus traffic in case this loop takes longer than | ||
| 222 | * a few retries. | ||
| 223 | */ | ||
| 224 | udelay(3); | ||
| 225 | } | ||
| 226 | 217 | ||
| 227 | if (likely(!ret)) | 218 | if (likely(!ret)) { |
| 228 | pcc_ss_data->platform_owns_pcc = false; | 219 | pcc_ss_data->platform_owns_pcc = false; |
| 229 | else | 220 | if (chk_err_bit && (status & PCC_ERROR_MASK)) |
| 230 | pr_err("PCC check channel failed for ss: %d. Status=%x\n", | 221 | ret = -EIO; |
| 231 | pcc_ss_id, status); | 222 | } |
| 223 | |||
| 224 | if (unlikely(ret)) | ||
| 225 | pr_err("PCC check channel failed for ss: %d. ret=%d\n", | ||
| 226 | pcc_ss_id, ret); | ||
| 232 | 227 | ||
| 233 | return ret; | 228 | return ret; |
| 234 | } | 229 | } |
| @@ -580,7 +575,7 @@ static int register_pcc_channel(int pcc_ss_idx) | |||
| 580 | * So add an arbitrary amount of wait on top of Nominal. | 575 | * So add an arbitrary amount of wait on top of Nominal. |
| 581 | */ | 576 | */ |
| 582 | usecs_lat = NUM_RETRIES * cppc_ss->latency; | 577 | usecs_lat = NUM_RETRIES * cppc_ss->latency; |
| 583 | pcc_data[pcc_ss_idx]->deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); | 578 | pcc_data[pcc_ss_idx]->deadline_us = usecs_lat; |
| 584 | pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; | 579 | pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; |
| 585 | pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; | 580 | pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; |
| 586 | pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; | 581 | pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; |
| @@ -613,7 +608,6 @@ bool __weak cpc_ffh_supported(void) | |||
| 613 | return false; | 608 | return false; |
| 614 | } | 609 | } |
| 615 | 610 | ||
| 616 | |||
| 617 | /** | 611 | /** |
| 618 | * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace | 612 | * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace |
| 619 | * | 613 | * |
| @@ -641,6 +635,34 @@ int pcc_data_alloc(int pcc_ss_id) | |||
| 641 | 635 | ||
| 642 | return 0; | 636 | return 0; |
| 643 | } | 637 | } |
| 638 | |||
| 639 | /* Check if CPPC revision + num_ent combination is supported */ | ||
| 640 | static bool is_cppc_supported(int revision, int num_ent) | ||
| 641 | { | ||
| 642 | int expected_num_ent; | ||
| 643 | |||
| 644 | switch (revision) { | ||
| 645 | case CPPC_V2_REV: | ||
| 646 | expected_num_ent = CPPC_V2_NUM_ENT; | ||
| 647 | break; | ||
| 648 | case CPPC_V3_REV: | ||
| 649 | expected_num_ent = CPPC_V3_NUM_ENT; | ||
| 650 | break; | ||
| 651 | default: | ||
| 652 | pr_debug("Firmware exports unsupported CPPC revision: %d\n", | ||
| 653 | revision); | ||
| 654 | return false; | ||
| 655 | } | ||
| 656 | |||
| 657 | if (expected_num_ent != num_ent) { | ||
| 658 | pr_debug("Firmware exports %d entries. Expected: %d for CPPC rev:%d\n", | ||
| 659 | num_ent, expected_num_ent, revision); | ||
| 660 | return false; | ||
| 661 | } | ||
| 662 | |||
| 663 | return true; | ||
| 664 | } | ||
| 665 | |||
| 644 | /* | 666 | /* |
| 645 | * An example CPC table looks like the following. | 667 | * An example CPC table looks like the following. |
| 646 | * | 668 | * |
| @@ -731,14 +753,6 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
| 731 | cpc_obj->type); | 753 | cpc_obj->type); |
| 732 | goto out_free; | 754 | goto out_free; |
| 733 | } | 755 | } |
| 734 | |||
| 735 | /* Only support CPPCv2. Bail otherwise. */ | ||
| 736 | if (num_ent != CPPC_NUM_ENT) { | ||
| 737 | pr_debug("Firmware exports %d entries. Expected: %d\n", | ||
| 738 | num_ent, CPPC_NUM_ENT); | ||
| 739 | goto out_free; | ||
| 740 | } | ||
| 741 | |||
| 742 | cpc_ptr->num_entries = num_ent; | 756 | cpc_ptr->num_entries = num_ent; |
| 743 | 757 | ||
| 744 | /* Second entry should be revision. */ | 758 | /* Second entry should be revision. */ |
| @@ -750,12 +764,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
| 750 | cpc_obj->type); | 764 | cpc_obj->type); |
| 751 | goto out_free; | 765 | goto out_free; |
| 752 | } | 766 | } |
| 767 | cpc_ptr->version = cpc_rev; | ||
| 753 | 768 | ||
| 754 | if (cpc_rev != CPPC_REV) { | 769 | if (!is_cppc_supported(cpc_rev, num_ent)) |
| 755 | pr_debug("Firmware exports revision:%d. Expected:%d\n", | ||
| 756 | cpc_rev, CPPC_REV); | ||
| 757 | goto out_free; | 770 | goto out_free; |
| 758 | } | ||
| 759 | 771 | ||
| 760 | /* Iterate through remaining entries in _CPC */ | 772 | /* Iterate through remaining entries in _CPC */ |
| 761 | for (i = 2; i < num_ent; i++) { | 773 | for (i = 2; i < num_ent; i++) { |
| @@ -808,6 +820,18 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
| 808 | } | 820 | } |
| 809 | } | 821 | } |
| 810 | per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id; | 822 | per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id; |
| 823 | |||
| 824 | /* | ||
| 825 | * Initialize the remaining cpc_regs as unsupported. | ||
| 826 | * Example: In case FW exposes CPPC v2, the below loop will initialize | ||
| 827 | * LOWEST_FREQ and NOMINAL_FREQ regs as unsupported | ||
| 828 | */ | ||
| 829 | for (i = num_ent - 2; i < MAX_CPC_REG_ENT; i++) { | ||
| 830 | cpc_ptr->cpc_regs[i].type = ACPI_TYPE_INTEGER; | ||
| 831 | cpc_ptr->cpc_regs[i].cpc_entry.int_value = 0; | ||
| 832 | } | ||
| 833 | |||
| 834 | |||
| 811 | /* Store CPU Logical ID */ | 835 | /* Store CPU Logical ID */ |
| 812 | cpc_ptr->cpu_id = pr->id; | 836 | cpc_ptr->cpu_id = pr->id; |
| 813 | 837 | ||
| @@ -1037,26 +1061,34 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
| 1037 | { | 1061 | { |
| 1038 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); | 1062 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); |
| 1039 | struct cpc_register_resource *highest_reg, *lowest_reg, | 1063 | struct cpc_register_resource *highest_reg, *lowest_reg, |
| 1040 | *lowest_non_linear_reg, *nominal_reg; | 1064 | *lowest_non_linear_reg, *nominal_reg, |
| 1041 | u64 high, low, nom, min_nonlinear; | 1065 | *low_freq_reg = NULL, *nom_freq_reg = NULL; |
| 1066 | u64 high, low, nom, min_nonlinear, low_f = 0, nom_f = 0; | ||
| 1042 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); | 1067 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); |
| 1043 | struct cppc_pcc_data *pcc_ss_data; | 1068 | struct cppc_pcc_data *pcc_ss_data = NULL; |
| 1044 | int ret = 0, regs_in_pcc = 0; | 1069 | int ret = 0, regs_in_pcc = 0; |
| 1045 | 1070 | ||
| 1046 | if (!cpc_desc || pcc_ss_id < 0) { | 1071 | if (!cpc_desc) { |
| 1047 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | 1072 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); |
| 1048 | return -ENODEV; | 1073 | return -ENODEV; |
| 1049 | } | 1074 | } |
| 1050 | 1075 | ||
| 1051 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
| 1052 | highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; | 1076 | highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; |
| 1053 | lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; | 1077 | lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; |
| 1054 | lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF]; | 1078 | lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF]; |
| 1055 | nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; | 1079 | nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; |
| 1080 | low_freq_reg = &cpc_desc->cpc_regs[LOWEST_FREQ]; | ||
| 1081 | nom_freq_reg = &cpc_desc->cpc_regs[NOMINAL_FREQ]; | ||
| 1056 | 1082 | ||
| 1057 | /* Are any of the regs PCC ?*/ | 1083 | /* Are any of the regs PCC ?*/ |
| 1058 | if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || | 1084 | if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || |
| 1059 | CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg)) { | 1085 | CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) || |
| 1086 | CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) { | ||
| 1087 | if (pcc_ss_id < 0) { | ||
| 1088 | pr_debug("Invalid pcc_ss_id\n"); | ||
| 1089 | return -ENODEV; | ||
| 1090 | } | ||
| 1091 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
| 1060 | regs_in_pcc = 1; | 1092 | regs_in_pcc = 1; |
| 1061 | down_write(&pcc_ss_data->pcc_lock); | 1093 | down_write(&pcc_ss_data->pcc_lock); |
| 1062 | /* Ring doorbell once to update PCC subspace */ | 1094 | /* Ring doorbell once to update PCC subspace */ |
| @@ -1081,6 +1113,17 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
| 1081 | if (!high || !low || !nom || !min_nonlinear) | 1113 | if (!high || !low || !nom || !min_nonlinear) |
| 1082 | ret = -EFAULT; | 1114 | ret = -EFAULT; |
| 1083 | 1115 | ||
| 1116 | /* Read optional lowest and nominal frequencies if present */ | ||
| 1117 | if (CPC_SUPPORTED(low_freq_reg)) | ||
| 1118 | cpc_read(cpunum, low_freq_reg, &low_f); | ||
| 1119 | |||
| 1120 | if (CPC_SUPPORTED(nom_freq_reg)) | ||
| 1121 | cpc_read(cpunum, nom_freq_reg, &nom_f); | ||
| 1122 | |||
| 1123 | perf_caps->lowest_freq = low_f; | ||
| 1124 | perf_caps->nominal_freq = nom_f; | ||
| 1125 | |||
| 1126 | |||
| 1084 | out_err: | 1127 | out_err: |
| 1085 | if (regs_in_pcc) | 1128 | if (regs_in_pcc) |
| 1086 | up_write(&pcc_ss_data->pcc_lock); | 1129 | up_write(&pcc_ss_data->pcc_lock); |
| @@ -1101,16 +1144,15 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
| 1101 | struct cpc_register_resource *delivered_reg, *reference_reg, | 1144 | struct cpc_register_resource *delivered_reg, *reference_reg, |
| 1102 | *ref_perf_reg, *ctr_wrap_reg; | 1145 | *ref_perf_reg, *ctr_wrap_reg; |
| 1103 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); | 1146 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); |
| 1104 | struct cppc_pcc_data *pcc_ss_data; | 1147 | struct cppc_pcc_data *pcc_ss_data = NULL; |
| 1105 | u64 delivered, reference, ref_perf, ctr_wrap_time; | 1148 | u64 delivered, reference, ref_perf, ctr_wrap_time; |
| 1106 | int ret = 0, regs_in_pcc = 0; | 1149 | int ret = 0, regs_in_pcc = 0; |
| 1107 | 1150 | ||
| 1108 | if (!cpc_desc || pcc_ss_id < 0) { | 1151 | if (!cpc_desc) { |
| 1109 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | 1152 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); |
| 1110 | return -ENODEV; | 1153 | return -ENODEV; |
| 1111 | } | 1154 | } |
| 1112 | 1155 | ||
| 1113 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
| 1114 | delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; | 1156 | delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; |
| 1115 | reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; | 1157 | reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; |
| 1116 | ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; | 1158 | ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; |
| @@ -1126,6 +1168,11 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
| 1126 | /* Are any of the regs PCC ?*/ | 1168 | /* Are any of the regs PCC ?*/ |
| 1127 | if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || | 1169 | if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || |
| 1128 | CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { | 1170 | CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { |
| 1171 | if (pcc_ss_id < 0) { | ||
| 1172 | pr_debug("Invalid pcc_ss_id\n"); | ||
| 1173 | return -ENODEV; | ||
| 1174 | } | ||
| 1175 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
| 1129 | down_write(&pcc_ss_data->pcc_lock); | 1176 | down_write(&pcc_ss_data->pcc_lock); |
| 1130 | regs_in_pcc = 1; | 1177 | regs_in_pcc = 1; |
| 1131 | /* Ring doorbell once to update PCC subspace */ | 1178 | /* Ring doorbell once to update PCC subspace */ |
| @@ -1176,15 +1223,14 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
| 1176 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); | 1223 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); |
| 1177 | struct cpc_register_resource *desired_reg; | 1224 | struct cpc_register_resource *desired_reg; |
| 1178 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); | 1225 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); |
| 1179 | struct cppc_pcc_data *pcc_ss_data; | 1226 | struct cppc_pcc_data *pcc_ss_data = NULL; |
| 1180 | int ret = 0; | 1227 | int ret = 0; |
| 1181 | 1228 | ||
| 1182 | if (!cpc_desc || pcc_ss_id < 0) { | 1229 | if (!cpc_desc) { |
| 1183 | pr_debug("No CPC descriptor for CPU:%d\n", cpu); | 1230 | pr_debug("No CPC descriptor for CPU:%d\n", cpu); |
| 1184 | return -ENODEV; | 1231 | return -ENODEV; |
| 1185 | } | 1232 | } |
| 1186 | 1233 | ||
| 1187 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
| 1188 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; | 1234 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; |
| 1189 | 1235 | ||
| 1190 | /* | 1236 | /* |
| @@ -1195,6 +1241,11 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
| 1195 | * achieve that goal here | 1241 | * achieve that goal here |
| 1196 | */ | 1242 | */ |
| 1197 | if (CPC_IN_PCC(desired_reg)) { | 1243 | if (CPC_IN_PCC(desired_reg)) { |
| 1244 | if (pcc_ss_id < 0) { | ||
| 1245 | pr_debug("Invalid pcc_ss_id\n"); | ||
| 1246 | return -ENODEV; | ||
| 1247 | } | ||
| 1248 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
| 1198 | down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */ | 1249 | down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */ |
| 1199 | if (pcc_ss_data->platform_owns_pcc) { | 1250 | if (pcc_ss_data->platform_owns_pcc) { |
| 1200 | ret = check_pcc_chan(pcc_ss_id, false); | 1251 | ret = check_pcc_chan(pcc_ss_id, false); |
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index 71769fd687b2..6fa9c2a4cfe9 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c | |||
| @@ -8,8 +8,8 @@ void acpi_reboot(void) | |||
| 8 | { | 8 | { |
| 9 | struct acpi_generic_address *rr; | 9 | struct acpi_generic_address *rr; |
| 10 | struct pci_bus *bus0; | 10 | struct pci_bus *bus0; |
| 11 | u8 reset_value; | ||
| 12 | unsigned int devfn; | 11 | unsigned int devfn; |
| 12 | u8 reset_value; | ||
| 13 | 13 | ||
| 14 | if (acpi_disabled) | 14 | if (acpi_disabled) |
| 15 | return; | 15 | return; |
| @@ -40,7 +40,7 @@ void acpi_reboot(void) | |||
| 40 | /* Form PCI device/function pair. */ | 40 | /* Form PCI device/function pair. */ |
| 41 | devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, | 41 | devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, |
| 42 | (rr->address >> 16) & 0xffff); | 42 | (rr->address >> 16) & 0xffff); |
| 43 | printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG."); | 43 | printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG.\n"); |
| 44 | /* Write the value that resets us. */ | 44 | /* Write the value that resets us. */ |
| 45 | pci_bus_write_config_byte(bus0, devfn, | 45 | pci_bus_write_config_byte(bus0, devfn, |
| 46 | (rr->address & 0xffff), reset_value); | 46 | (rr->address & 0xffff), reset_value); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 1ff17799769d..6389c88b3500 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -698,7 +698,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
| 698 | 698 | ||
| 699 | DPRINTK("ENTER\n"); | 699 | DPRINTK("ENTER\n"); |
| 700 | 700 | ||
| 701 | ahci_stop_engine(ap); | 701 | hpriv->stop_engine(ap); |
| 702 | 702 | ||
| 703 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), | 703 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), |
| 704 | deadline, &online, NULL); | 704 | deadline, &online, NULL); |
| @@ -724,7 +724,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
| 724 | bool online; | 724 | bool online; |
| 725 | int rc; | 725 | int rc; |
| 726 | 726 | ||
| 727 | ahci_stop_engine(ap); | 727 | hpriv->stop_engine(ap); |
| 728 | 728 | ||
| 729 | /* clear D2H reception area to properly wait for D2H FIS */ | 729 | /* clear D2H reception area to properly wait for D2H FIS */ |
| 730 | ata_tf_init(link->device, &tf); | 730 | ata_tf_init(link->device, &tf); |
| @@ -788,7 +788,7 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, | |||
| 788 | 788 | ||
| 789 | DPRINTK("ENTER\n"); | 789 | DPRINTK("ENTER\n"); |
| 790 | 790 | ||
| 791 | ahci_stop_engine(ap); | 791 | hpriv->stop_engine(ap); |
| 792 | 792 | ||
| 793 | for (i = 0; i < 2; i++) { | 793 | for (i = 0; i < 2; i++) { |
| 794 | u16 val; | 794 | u16 val; |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 4356ef1d28a8..824bd399f02e 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
| @@ -350,7 +350,6 @@ struct ahci_host_priv { | |||
| 350 | u32 em_msg_type; /* EM message type */ | 350 | u32 em_msg_type; /* EM message type */ |
| 351 | bool got_runtime_pm; /* Did we do pm_runtime_get? */ | 351 | bool got_runtime_pm; /* Did we do pm_runtime_get? */ |
| 352 | struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ | 352 | struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ |
| 353 | struct reset_control *rsts; /* Optional */ | ||
| 354 | struct regulator **target_pwrs; /* Optional */ | 353 | struct regulator **target_pwrs; /* Optional */ |
| 355 | /* | 354 | /* |
| 356 | * If platform uses PHYs. There is a 1:1 relation between the port number and | 355 | * If platform uses PHYs. There is a 1:1 relation between the port number and |
| @@ -366,6 +365,13 @@ struct ahci_host_priv { | |||
| 366 | * be overridden anytime before the host is activated. | 365 | * be overridden anytime before the host is activated. |
| 367 | */ | 366 | */ |
| 368 | void (*start_engine)(struct ata_port *ap); | 367 | void (*start_engine)(struct ata_port *ap); |
| 368 | /* | ||
| 369 | * Optional ahci_stop_engine override, if not set this gets set to the | ||
| 370 | * default ahci_stop_engine during ahci_save_initial_config, this can | ||
| 371 | * be overridden anytime before the host is activated. | ||
| 372 | */ | ||
| 373 | int (*stop_engine)(struct ata_port *ap); | ||
| 374 | |||
| 369 | irqreturn_t (*irq_handler)(int irq, void *dev_instance); | 375 | irqreturn_t (*irq_handler)(int irq, void *dev_instance); |
| 370 | 376 | ||
| 371 | /* only required for per-port MSI(-X) support */ | 377 | /* only required for per-port MSI(-X) support */ |
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index de7128d81e9c..0045dacd814b 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c | |||
| @@ -62,6 +62,60 @@ static void ahci_mvebu_regret_option(struct ahci_host_priv *hpriv) | |||
| 62 | writel(0x80, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA); | 62 | writel(0x80, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | /** | ||
| 66 | * ahci_mvebu_stop_engine | ||
| 67 | * | ||
| 68 | * @ap: Target ata port | ||
| 69 | * | ||
| 70 | * Errata Ref#226 - SATA Disk HOT swap issue when connected through | ||
| 71 | * Port Multiplier in FIS-based Switching mode. | ||
| 72 | * | ||
| 73 | * To avoid the issue, according to design, the bits[11:8, 0] of | ||
| 74 | * register PxFBS are cleared when Port Command and Status (0x18) bit[0] | ||
| 75 | * changes its value from 1 to 0, i.e. falling edge of Port | ||
| 76 | * Command and Status bit[0] sends PULSE that resets PxFBS | ||
| 77 | * bits[11:8; 0]. | ||
| 78 | * | ||
| 79 | * This function is used to override function of "ahci_stop_engine" | ||
| 80 | * from libahci.c by adding the mvebu work around(WA) to save PxFBS | ||
| 81 | * value before the PxCMD ST write of 0, then restore PxFBS value. | ||
| 82 | * | ||
| 83 | * Return: 0 on success; Error code otherwise. | ||
| 84 | */ | ||
| 85 | int ahci_mvebu_stop_engine(struct ata_port *ap) | ||
| 86 | { | ||
| 87 | void __iomem *port_mmio = ahci_port_base(ap); | ||
| 88 | u32 tmp, port_fbs; | ||
| 89 | |||
| 90 | tmp = readl(port_mmio + PORT_CMD); | ||
| 91 | |||
| 92 | /* check if the HBA is idle */ | ||
| 93 | if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) | ||
| 94 | return 0; | ||
| 95 | |||
| 96 | /* save the port PxFBS register for later restore */ | ||
| 97 | port_fbs = readl(port_mmio + PORT_FBS); | ||
| 98 | |||
| 99 | /* setting HBA to idle */ | ||
| 100 | tmp &= ~PORT_CMD_START; | ||
| 101 | writel(tmp, port_mmio + PORT_CMD); | ||
| 102 | |||
| 103 | /* | ||
| 104 | * bit #15 PxCMD signal doesn't clear PxFBS, | ||
| 105 | * restore the PxFBS register right after clearing the PxCMD ST, | ||
| 106 | * no need to wait for the PxCMD bit #15. | ||
| 107 | */ | ||
| 108 | writel(port_fbs, port_mmio + PORT_FBS); | ||
| 109 | |||
| 110 | /* wait for engine to stop. This could be as long as 500 msec */ | ||
| 111 | tmp = ata_wait_register(ap, port_mmio + PORT_CMD, | ||
| 112 | PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); | ||
| 113 | if (tmp & PORT_CMD_LIST_ON) | ||
| 114 | return -EIO; | ||
| 115 | |||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 65 | #ifdef CONFIG_PM_SLEEP | 119 | #ifdef CONFIG_PM_SLEEP |
| 66 | static int ahci_mvebu_suspend(struct platform_device *pdev, pm_message_t state) | 120 | static int ahci_mvebu_suspend(struct platform_device *pdev, pm_message_t state) |
| 67 | { | 121 | { |
| @@ -112,6 +166,8 @@ static int ahci_mvebu_probe(struct platform_device *pdev) | |||
| 112 | if (rc) | 166 | if (rc) |
| 113 | return rc; | 167 | return rc; |
| 114 | 168 | ||
| 169 | hpriv->stop_engine = ahci_mvebu_stop_engine; | ||
| 170 | |||
| 115 | if (of_device_is_compatible(pdev->dev.of_node, | 171 | if (of_device_is_compatible(pdev->dev.of_node, |
| 116 | "marvell,armada-380-ahci")) { | 172 | "marvell,armada-380-ahci")) { |
| 117 | dram = mv_mbus_dram_info(); | 173 | dram = mv_mbus_dram_info(); |
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 2685f28160f7..cfdef4d44ae9 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c | |||
| @@ -96,7 +96,7 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, | |||
| 96 | 96 | ||
| 97 | DPRINTK("ENTER\n"); | 97 | DPRINTK("ENTER\n"); |
| 98 | 98 | ||
| 99 | ahci_stop_engine(ap); | 99 | hpriv->stop_engine(ap); |
| 100 | 100 | ||
| 101 | /* | 101 | /* |
| 102 | * There is a errata on ls1021a Rev1.0 and Rev2.0 which is: | 102 | * There is a errata on ls1021a Rev1.0 and Rev2.0 which is: |
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index c2b5941d9184..ad58da7c9aff 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c | |||
| @@ -165,7 +165,7 @@ static int xgene_ahci_restart_engine(struct ata_port *ap) | |||
| 165 | PORT_CMD_ISSUE, 0x0, 1, 100)) | 165 | PORT_CMD_ISSUE, 0x0, 1, 100)) |
| 166 | return -EBUSY; | 166 | return -EBUSY; |
| 167 | 167 | ||
| 168 | ahci_stop_engine(ap); | 168 | hpriv->stop_engine(ap); |
| 169 | ahci_start_fis_rx(ap); | 169 | ahci_start_fis_rx(ap); |
| 170 | 170 | ||
| 171 | /* | 171 | /* |
| @@ -421,7 +421,7 @@ static int xgene_ahci_hardreset(struct ata_link *link, unsigned int *class, | |||
| 421 | portrxfis_saved = readl(port_mmio + PORT_FIS_ADDR); | 421 | portrxfis_saved = readl(port_mmio + PORT_FIS_ADDR); |
| 422 | portrxfishi_saved = readl(port_mmio + PORT_FIS_ADDR_HI); | 422 | portrxfishi_saved = readl(port_mmio + PORT_FIS_ADDR_HI); |
| 423 | 423 | ||
| 424 | ahci_stop_engine(ap); | 424 | hpriv->stop_engine(ap); |
| 425 | 425 | ||
| 426 | rc = xgene_ahci_do_hardreset(link, deadline, &online); | 426 | rc = xgene_ahci_do_hardreset(link, deadline, &online); |
| 427 | 427 | ||
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 7adcf3caabd0..e5d90977caec 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
| @@ -560,6 +560,9 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) | |||
| 560 | if (!hpriv->start_engine) | 560 | if (!hpriv->start_engine) |
| 561 | hpriv->start_engine = ahci_start_engine; | 561 | hpriv->start_engine = ahci_start_engine; |
| 562 | 562 | ||
| 563 | if (!hpriv->stop_engine) | ||
| 564 | hpriv->stop_engine = ahci_stop_engine; | ||
| 565 | |||
| 563 | if (!hpriv->irq_handler) | 566 | if (!hpriv->irq_handler) |
| 564 | hpriv->irq_handler = ahci_single_level_irq_intr; | 567 | hpriv->irq_handler = ahci_single_level_irq_intr; |
| 565 | } | 568 | } |
| @@ -897,9 +900,10 @@ static void ahci_start_port(struct ata_port *ap) | |||
| 897 | static int ahci_deinit_port(struct ata_port *ap, const char **emsg) | 900 | static int ahci_deinit_port(struct ata_port *ap, const char **emsg) |
| 898 | { | 901 | { |
| 899 | int rc; | 902 | int rc; |
| 903 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
| 900 | 904 | ||
| 901 | /* disable DMA */ | 905 | /* disable DMA */ |
| 902 | rc = ahci_stop_engine(ap); | 906 | rc = hpriv->stop_engine(ap); |
| 903 | if (rc) { | 907 | if (rc) { |
| 904 | *emsg = "failed to stop engine"; | 908 | *emsg = "failed to stop engine"; |
| 905 | return rc; | 909 | return rc; |
| @@ -1310,7 +1314,7 @@ int ahci_kick_engine(struct ata_port *ap) | |||
| 1310 | int busy, rc; | 1314 | int busy, rc; |
| 1311 | 1315 | ||
| 1312 | /* stop engine */ | 1316 | /* stop engine */ |
| 1313 | rc = ahci_stop_engine(ap); | 1317 | rc = hpriv->stop_engine(ap); |
| 1314 | if (rc) | 1318 | if (rc) |
| 1315 | goto out_restart; | 1319 | goto out_restart; |
| 1316 | 1320 | ||
| @@ -1549,7 +1553,7 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class, | |||
| 1549 | 1553 | ||
| 1550 | DPRINTK("ENTER\n"); | 1554 | DPRINTK("ENTER\n"); |
| 1551 | 1555 | ||
| 1552 | ahci_stop_engine(ap); | 1556 | hpriv->stop_engine(ap); |
| 1553 | 1557 | ||
| 1554 | /* clear D2H reception area to properly wait for D2H FIS */ | 1558 | /* clear D2H reception area to properly wait for D2H FIS */ |
| 1555 | ata_tf_init(link->device, &tf); | 1559 | ata_tf_init(link->device, &tf); |
| @@ -2075,14 +2079,14 @@ void ahci_error_handler(struct ata_port *ap) | |||
| 2075 | 2079 | ||
| 2076 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { | 2080 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { |
| 2077 | /* restart engine */ | 2081 | /* restart engine */ |
| 2078 | ahci_stop_engine(ap); | 2082 | hpriv->stop_engine(ap); |
| 2079 | hpriv->start_engine(ap); | 2083 | hpriv->start_engine(ap); |
| 2080 | } | 2084 | } |
| 2081 | 2085 | ||
| 2082 | sata_pmp_error_handler(ap); | 2086 | sata_pmp_error_handler(ap); |
| 2083 | 2087 | ||
| 2084 | if (!ata_dev_enabled(ap->link.device)) | 2088 | if (!ata_dev_enabled(ap->link.device)) |
| 2085 | ahci_stop_engine(ap); | 2089 | hpriv->stop_engine(ap); |
| 2086 | } | 2090 | } |
| 2087 | EXPORT_SYMBOL_GPL(ahci_error_handler); | 2091 | EXPORT_SYMBOL_GPL(ahci_error_handler); |
| 2088 | 2092 | ||
| @@ -2129,7 +2133,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) | |||
| 2129 | return; | 2133 | return; |
| 2130 | 2134 | ||
| 2131 | /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */ | 2135 | /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */ |
| 2132 | rc = ahci_stop_engine(ap); | 2136 | rc = hpriv->stop_engine(ap); |
| 2133 | if (rc) | 2137 | if (rc) |
| 2134 | return; | 2138 | return; |
| 2135 | 2139 | ||
| @@ -2189,7 +2193,7 @@ static void ahci_enable_fbs(struct ata_port *ap) | |||
| 2189 | return; | 2193 | return; |
| 2190 | } | 2194 | } |
| 2191 | 2195 | ||
| 2192 | rc = ahci_stop_engine(ap); | 2196 | rc = hpriv->stop_engine(ap); |
| 2193 | if (rc) | 2197 | if (rc) |
| 2194 | return; | 2198 | return; |
| 2195 | 2199 | ||
| @@ -2222,7 +2226,7 @@ static void ahci_disable_fbs(struct ata_port *ap) | |||
| 2222 | return; | 2226 | return; |
| 2223 | } | 2227 | } |
| 2224 | 2228 | ||
| 2225 | rc = ahci_stop_engine(ap); | 2229 | rc = hpriv->stop_engine(ap); |
| 2226 | if (rc) | 2230 | if (rc) |
| 2227 | return; | 2231 | return; |
| 2228 | 2232 | ||
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 46a762442dc5..30cc8f1a31e1 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | #include <linux/phy/phy.h> | 25 | #include <linux/phy/phy.h> |
| 26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
| 27 | #include <linux/of_platform.h> | 27 | #include <linux/of_platform.h> |
| 28 | #include <linux/reset.h> | ||
| 29 | #include "ahci.h" | 28 | #include "ahci.h" |
| 30 | 29 | ||
| 31 | static void ahci_host_stop(struct ata_host *host); | 30 | static void ahci_host_stop(struct ata_host *host); |
| @@ -196,8 +195,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators); | |||
| 196 | * following order: | 195 | * following order: |
| 197 | * 1) Regulator | 196 | * 1) Regulator |
| 198 | * 2) Clocks (through ahci_platform_enable_clks) | 197 | * 2) Clocks (through ahci_platform_enable_clks) |
| 199 | * 3) Resets | 198 | * 3) Phys |
| 200 | * 4) Phys | ||
| 201 | * | 199 | * |
| 202 | * If resource enabling fails at any point the previous enabled resources | 200 | * If resource enabling fails at any point the previous enabled resources |
| 203 | * are disabled in reverse order. | 201 | * are disabled in reverse order. |
| @@ -217,19 +215,12 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv) | |||
| 217 | if (rc) | 215 | if (rc) |
| 218 | goto disable_regulator; | 216 | goto disable_regulator; |
| 219 | 217 | ||
| 220 | rc = reset_control_deassert(hpriv->rsts); | ||
| 221 | if (rc) | ||
| 222 | goto disable_clks; | ||
| 223 | |||
| 224 | rc = ahci_platform_enable_phys(hpriv); | 218 | rc = ahci_platform_enable_phys(hpriv); |
| 225 | if (rc) | 219 | if (rc) |
| 226 | goto disable_resets; | 220 | goto disable_clks; |
| 227 | 221 | ||
| 228 | return 0; | 222 | return 0; |
| 229 | 223 | ||
| 230 | disable_resets: | ||
| 231 | reset_control_assert(hpriv->rsts); | ||
| 232 | |||
| 233 | disable_clks: | 224 | disable_clks: |
| 234 | ahci_platform_disable_clks(hpriv); | 225 | ahci_platform_disable_clks(hpriv); |
| 235 | 226 | ||
| @@ -248,15 +239,12 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources); | |||
| 248 | * following order: | 239 | * following order: |
| 249 | * 1) Phys | 240 | * 1) Phys |
| 250 | * 2) Clocks (through ahci_platform_disable_clks) | 241 | * 2) Clocks (through ahci_platform_disable_clks) |
| 251 | * 3) Resets | 242 | * 3) Regulator |
| 252 | * 4) Regulator | ||
| 253 | */ | 243 | */ |
| 254 | void ahci_platform_disable_resources(struct ahci_host_priv *hpriv) | 244 | void ahci_platform_disable_resources(struct ahci_host_priv *hpriv) |
| 255 | { | 245 | { |
| 256 | ahci_platform_disable_phys(hpriv); | 246 | ahci_platform_disable_phys(hpriv); |
| 257 | 247 | ||
| 258 | reset_control_assert(hpriv->rsts); | ||
| 259 | |||
| 260 | ahci_platform_disable_clks(hpriv); | 248 | ahci_platform_disable_clks(hpriv); |
| 261 | 249 | ||
| 262 | ahci_platform_disable_regulators(hpriv); | 250 | ahci_platform_disable_regulators(hpriv); |
| @@ -405,12 +393,6 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev) | |||
| 405 | hpriv->clks[i] = clk; | 393 | hpriv->clks[i] = clk; |
| 406 | } | 394 | } |
| 407 | 395 | ||
| 408 | hpriv->rsts = devm_reset_control_array_get_optional_shared(dev); | ||
| 409 | if (IS_ERR(hpriv->rsts)) { | ||
| 410 | rc = PTR_ERR(hpriv->rsts); | ||
| 411 | goto err_out; | ||
| 412 | } | ||
| 413 | |||
| 414 | hpriv->nports = child_nodes = of_get_child_count(dev->of_node); | 396 | hpriv->nports = child_nodes = of_get_child_count(dev->of_node); |
| 415 | 397 | ||
| 416 | /* | 398 | /* |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8bc71ca61e7f..68596bd4cf06 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -4549,6 +4549,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4549 | ATA_HORKAGE_ZERO_AFTER_TRIM | | 4549 | ATA_HORKAGE_ZERO_AFTER_TRIM | |
| 4550 | ATA_HORKAGE_NOLPM, }, | 4550 | ATA_HORKAGE_NOLPM, }, |
| 4551 | 4551 | ||
| 4552 | /* This specific Samsung model/firmware-rev does not handle LPM well */ | ||
| 4553 | { "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_HORKAGE_NOLPM, }, | ||
| 4554 | |||
| 4555 | /* Sandisk devices which are known to not handle LPM well */ | ||
| 4556 | { "SanDisk SD7UB3Q*G1001", NULL, ATA_HORKAGE_NOLPM, }, | ||
| 4557 | |||
| 4552 | /* devices that don't properly handle queued TRIM commands */ | 4558 | /* devices that don't properly handle queued TRIM commands */ |
| 4553 | { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | 4559 | { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | |
| 4554 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4560 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index c016829a38fd..513b260bcff1 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -175,8 +175,8 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) | |||
| 175 | { } | 175 | { } |
| 176 | #endif /* CONFIG_PM */ | 176 | #endif /* CONFIG_PM */ |
| 177 | 177 | ||
| 178 | static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt, | 178 | static __printf(2, 0) void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, |
| 179 | va_list args) | 179 | const char *fmt, va_list args) |
| 180 | { | 180 | { |
| 181 | ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len, | 181 | ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len, |
| 182 | ATA_EH_DESC_LEN - ehi->desc_len, | 182 | ATA_EH_DESC_LEN - ehi->desc_len, |
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index aafb8cc03523..e67815b896fc 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c | |||
| @@ -410,7 +410,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, | |||
| 410 | int rc; | 410 | int rc; |
| 411 | int retry = 100; | 411 | int retry = 100; |
| 412 | 412 | ||
| 413 | ahci_stop_engine(ap); | 413 | hpriv->stop_engine(ap); |
| 414 | 414 | ||
| 415 | /* clear D2H reception area to properly wait for D2H FIS */ | 415 | /* clear D2H reception area to properly wait for D2H FIS */ |
| 416 | ata_tf_init(link->device, &tf); | 416 | ata_tf_init(link->device, &tf); |
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 4b1995e2d044..010ca101d412 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
| @@ -285,13 +285,13 @@ static const struct sil24_cerr_info { | |||
| 285 | [PORT_CERR_INCONSISTENT] = { AC_ERR_HSM, ATA_EH_RESET, | 285 | [PORT_CERR_INCONSISTENT] = { AC_ERR_HSM, ATA_EH_RESET, |
| 286 | "protocol mismatch" }, | 286 | "protocol mismatch" }, |
| 287 | [PORT_CERR_DIRECTION] = { AC_ERR_HSM, ATA_EH_RESET, | 287 | [PORT_CERR_DIRECTION] = { AC_ERR_HSM, ATA_EH_RESET, |
| 288 | "data directon mismatch" }, | 288 | "data direction mismatch" }, |
| 289 | [PORT_CERR_UNDERRUN] = { AC_ERR_HSM, ATA_EH_RESET, | 289 | [PORT_CERR_UNDERRUN] = { AC_ERR_HSM, ATA_EH_RESET, |
| 290 | "ran out of SGEs while writing" }, | 290 | "ran out of SGEs while writing" }, |
| 291 | [PORT_CERR_OVERRUN] = { AC_ERR_HSM, ATA_EH_RESET, | 291 | [PORT_CERR_OVERRUN] = { AC_ERR_HSM, ATA_EH_RESET, |
| 292 | "ran out of SGEs while reading" }, | 292 | "ran out of SGEs while reading" }, |
| 293 | [PORT_CERR_PKT_PROT] = { AC_ERR_HSM, ATA_EH_RESET, | 293 | [PORT_CERR_PKT_PROT] = { AC_ERR_HSM, ATA_EH_RESET, |
| 294 | "invalid data directon for ATAPI CDB" }, | 294 | "invalid data direction for ATAPI CDB" }, |
| 295 | [PORT_CERR_SGT_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_RESET, | 295 | [PORT_CERR_SGT_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_RESET, |
| 296 | "SGT not on qword boundary" }, | 296 | "SGT not on qword boundary" }, |
| 297 | [PORT_CERR_SGT_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET, | 297 | [PORT_CERR_SGT_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET, |
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index d97c05690faa..4e46dc9e41ad 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
| @@ -191,7 +191,7 @@ static char *res_strings[] = { | |||
| 191 | "reserved 37", | 191 | "reserved 37", |
| 192 | "reserved 38", | 192 | "reserved 38", |
| 193 | "reserved 39", | 193 | "reserved 39", |
| 194 | "reseverd 40", | 194 | "reserved 40", |
| 195 | "reserved 41", | 195 | "reserved 41", |
| 196 | "reserved 42", | 196 | "reserved 42", |
| 197 | "reserved 43", | 197 | "reserved 43", |
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 1ef67db03c8e..9c9a22958717 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <asm/io.h> | 28 | #include <asm/io.h> |
| 29 | #include <linux/atomic.h> | 29 | #include <linux/atomic.h> |
| 30 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
| 31 | #include <linux/nospec.h> | ||
| 31 | 32 | ||
| 32 | #include "uPD98401.h" | 33 | #include "uPD98401.h" |
| 33 | #include "uPD98402.h" | 34 | #include "uPD98402.h" |
| @@ -1458,6 +1459,8 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) | |||
| 1458 | return -EFAULT; | 1459 | return -EFAULT; |
| 1459 | if (pool < 0 || pool > ZATM_LAST_POOL) | 1460 | if (pool < 0 || pool > ZATM_LAST_POOL) |
| 1460 | return -EINVAL; | 1461 | return -EINVAL; |
| 1462 | pool = array_index_nospec(pool, | ||
| 1463 | ZATM_LAST_POOL + 1); | ||
| 1461 | spin_lock_irqsave(&zatm_dev->lock, flags); | 1464 | spin_lock_irqsave(&zatm_dev->lock, flags); |
| 1462 | info = zatm_dev->pool_info[pool]; | 1465 | info = zatm_dev->pool_info[pool]; |
| 1463 | if (cmd == ZATM_GETPOOLZ) { | 1466 | if (cmd == ZATM_GETPOOLZ) { |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 8e8b04cc569a..33b36fea1d73 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -2366,7 +2366,9 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) | |||
| 2366 | osd_req_op_cls_init(obj_req->osd_req, 0, CEPH_OSD_OP_CALL, "rbd", | 2366 | osd_req_op_cls_init(obj_req->osd_req, 0, CEPH_OSD_OP_CALL, "rbd", |
| 2367 | "copyup"); | 2367 | "copyup"); |
| 2368 | osd_req_op_cls_request_data_bvecs(obj_req->osd_req, 0, | 2368 | osd_req_op_cls_request_data_bvecs(obj_req->osd_req, 0, |
| 2369 | obj_req->copyup_bvecs, bytes); | 2369 | obj_req->copyup_bvecs, |
| 2370 | obj_req->copyup_bvec_count, | ||
| 2371 | bytes); | ||
| 2370 | 2372 | ||
| 2371 | switch (obj_req->img_request->op_type) { | 2373 | switch (obj_req->img_request->op_type) { |
| 2372 | case OBJ_OP_WRITE: | 2374 | case OBJ_OP_WRITE: |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c8c8b0b8d333..b937cc1e2c07 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -231,6 +231,7 @@ static const struct usb_device_id blacklist_table[] = { | |||
| 231 | { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, | 231 | { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, |
| 232 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, | 232 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, |
| 233 | { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, | 233 | { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, |
| 234 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, | ||
| 234 | { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, | 235 | { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, |
| 235 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, | 236 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, |
| 236 | { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, | 237 | { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, |
| @@ -263,7 +264,6 @@ static const struct usb_device_id blacklist_table[] = { | |||
| 263 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, | 264 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, |
| 264 | 265 | ||
| 265 | /* QCA ROME chipset */ | 266 | /* QCA ROME chipset */ |
| 266 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME }, | ||
| 267 | { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, | 267 | { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, |
| 268 | { USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME }, | 268 | { USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME }, |
| 269 | { USB_DEVICE(0x0cf3, 0xe010), .driver_info = BTUSB_QCA_ROME }, | 269 | { USB_DEVICE(0x0cf3, 0xe010), .driver_info = BTUSB_QCA_ROME }, |
| @@ -399,6 +399,13 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = { | |||
| 399 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 3060"), | 399 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 3060"), |
| 400 | }, | 400 | }, |
| 401 | }, | 401 | }, |
| 402 | { | ||
| 403 | /* Dell XPS 9360 (QCA ROME device 0cf3:e300) */ | ||
| 404 | .matches = { | ||
| 405 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 406 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"), | ||
| 407 | }, | ||
| 408 | }, | ||
| 402 | {} | 409 | {} |
| 403 | }; | 410 | }; |
| 404 | 411 | ||
| @@ -2852,6 +2859,12 @@ static int btusb_config_oob_wake(struct hci_dev *hdev) | |||
| 2852 | } | 2859 | } |
| 2853 | #endif | 2860 | #endif |
| 2854 | 2861 | ||
| 2862 | static void btusb_check_needs_reset_resume(struct usb_interface *intf) | ||
| 2863 | { | ||
| 2864 | if (dmi_check_system(btusb_needs_reset_resume_table)) | ||
| 2865 | interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME; | ||
| 2866 | } | ||
| 2867 | |||
| 2855 | static int btusb_probe(struct usb_interface *intf, | 2868 | static int btusb_probe(struct usb_interface *intf, |
| 2856 | const struct usb_device_id *id) | 2869 | const struct usb_device_id *id) |
| 2857 | { | 2870 | { |
| @@ -2974,9 +2987,6 @@ static int btusb_probe(struct usb_interface *intf, | |||
| 2974 | hdev->send = btusb_send_frame; | 2987 | hdev->send = btusb_send_frame; |
| 2975 | hdev->notify = btusb_notify; | 2988 | hdev->notify = btusb_notify; |
| 2976 | 2989 | ||
| 2977 | if (dmi_check_system(btusb_needs_reset_resume_table)) | ||
| 2978 | interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME; | ||
| 2979 | |||
| 2980 | #ifdef CONFIG_PM | 2990 | #ifdef CONFIG_PM |
| 2981 | err = btusb_config_oob_wake(hdev); | 2991 | err = btusb_config_oob_wake(hdev); |
| 2982 | if (err) | 2992 | if (err) |
| @@ -3064,6 +3074,7 @@ static int btusb_probe(struct usb_interface *intf, | |||
| 3064 | data->setup_on_usb = btusb_setup_qca; | 3074 | data->setup_on_usb = btusb_setup_qca; |
| 3065 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; | 3075 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; |
| 3066 | set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); | 3076 | set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); |
| 3077 | btusb_check_needs_reset_resume(intf); | ||
| 3067 | } | 3078 | } |
| 3068 | 3079 | ||
| 3069 | #ifdef CONFIG_BT_HCIBTUSB_RTL | 3080 | #ifdef CONFIG_BT_HCIBTUSB_RTL |
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index c381c8e396fc..79d8c84693a1 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
| @@ -195,7 +195,7 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, int ty | |||
| 195 | return 0; | 195 | return 0; |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | int uninorth_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | 198 | static int uninorth_remove_memory(struct agp_memory *mem, off_t pg_start, int type) |
| 199 | { | 199 | { |
| 200 | size_t i; | 200 | size_t i; |
| 201 | u32 *gp; | 201 | u32 *gp; |
| @@ -470,7 +470,7 @@ static int uninorth_free_gatt_table(struct agp_bridge_data *bridge) | |||
| 470 | return 0; | 470 | return 0; |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | void null_cache_flush(void) | 473 | static void null_cache_flush(void) |
| 474 | { | 474 | { |
| 475 | mb(); | 475 | mb(); |
| 476 | } | 476 | } |
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 41492e980ef4..34968a381d0f 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
| @@ -266,15 +266,13 @@ config COMMON_CLK_STM32MP157 | |||
| 266 | Support for stm32mp157 SoC family clocks | 266 | Support for stm32mp157 SoC family clocks |
| 267 | 267 | ||
| 268 | config COMMON_CLK_STM32F | 268 | config COMMON_CLK_STM32F |
| 269 | bool "Clock driver for stm32f4 and stm32f7 SoC families" | 269 | def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746) |
| 270 | depends on MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746 | ||
| 271 | help | 270 | help |
| 272 | ---help--- | 271 | ---help--- |
| 273 | Support for stm32f4 and stm32f7 SoC families clocks | 272 | Support for stm32f4 and stm32f7 SoC families clocks |
| 274 | 273 | ||
| 275 | config COMMON_CLK_STM32H7 | 274 | config COMMON_CLK_STM32H7 |
| 276 | bool "Clock driver for stm32h7 SoC family" | 275 | def_bool COMMON_CLK && MACH_STM32H743 |
| 277 | depends on MACH_STM32H743 | ||
| 278 | help | 276 | help |
| 279 | ---help--- | 277 | ---help--- |
| 280 | Support for stm32h7 SoC family clocks | 278 | Support for stm32h7 SoC family clocks |
diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c index c58019750b7e..a2f8c42e527a 100644 --- a/drivers/clk/clk-cs2000-cp.c +++ b/drivers/clk/clk-cs2000-cp.c | |||
| @@ -541,7 +541,7 @@ probe_err: | |||
| 541 | return ret; | 541 | return ret; |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | static int cs2000_resume(struct device *dev) | 544 | static int __maybe_unused cs2000_resume(struct device *dev) |
| 545 | { | 545 | { |
| 546 | struct cs2000_priv *priv = dev_get_drvdata(dev); | 546 | struct cs2000_priv *priv = dev_get_drvdata(dev); |
| 547 | 547 | ||
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index ac4a042f8658..1628b93655ed 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c | |||
| @@ -112,10 +112,18 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) | |||
| 112 | return 0; | 112 | return 0; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static int clk_mux_determine_rate(struct clk_hw *hw, | ||
| 116 | struct clk_rate_request *req) | ||
| 117 | { | ||
| 118 | struct clk_mux *mux = to_clk_mux(hw); | ||
| 119 | |||
| 120 | return clk_mux_determine_rate_flags(hw, req, mux->flags); | ||
| 121 | } | ||
| 122 | |||
| 115 | const struct clk_ops clk_mux_ops = { | 123 | const struct clk_ops clk_mux_ops = { |
| 116 | .get_parent = clk_mux_get_parent, | 124 | .get_parent = clk_mux_get_parent, |
| 117 | .set_parent = clk_mux_set_parent, | 125 | .set_parent = clk_mux_set_parent, |
| 118 | .determine_rate = __clk_mux_determine_rate, | 126 | .determine_rate = clk_mux_determine_rate, |
| 119 | }; | 127 | }; |
| 120 | EXPORT_SYMBOL_GPL(clk_mux_ops); | 128 | EXPORT_SYMBOL_GPL(clk_mux_ops); |
| 121 | 129 | ||
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index f1d5967b4b39..edd3cf451401 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c | |||
| @@ -216,7 +216,7 @@ static const char * const usart1_src[] = { | |||
| 216 | "pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse" | 216 | "pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse" |
| 217 | }; | 217 | }; |
| 218 | 218 | ||
| 219 | const char * const usart234578_src[] = { | 219 | static const char * const usart234578_src[] = { |
| 220 | "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" | 220 | "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" |
| 221 | }; | 221 | }; |
| 222 | 222 | ||
| @@ -224,10 +224,6 @@ static const char * const usart6_src[] = { | |||
| 224 | "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" | 224 | "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" |
| 225 | }; | 225 | }; |
| 226 | 226 | ||
| 227 | static const char * const dfsdm_src[] = { | ||
| 228 | "pclk2", "ck_mcu" | ||
| 229 | }; | ||
| 230 | |||
| 231 | static const char * const fdcan_src[] = { | 227 | static const char * const fdcan_src[] = { |
| 232 | "ck_hse", "pll3_q", "pll4_q" | 228 | "ck_hse", "pll3_q", "pll4_q" |
| 233 | }; | 229 | }; |
| @@ -316,10 +312,8 @@ struct stm32_clk_mgate { | |||
| 316 | struct clock_config { | 312 | struct clock_config { |
| 317 | u32 id; | 313 | u32 id; |
| 318 | const char *name; | 314 | const char *name; |
| 319 | union { | 315 | const char *parent_name; |
| 320 | const char *parent_name; | 316 | const char * const *parent_names; |
| 321 | const char * const *parent_names; | ||
| 322 | }; | ||
| 323 | int num_parents; | 317 | int num_parents; |
| 324 | unsigned long flags; | 318 | unsigned long flags; |
| 325 | void *cfg; | 319 | void *cfg; |
| @@ -469,7 +463,7 @@ static void mp1_gate_clk_disable(struct clk_hw *hw) | |||
| 469 | } | 463 | } |
| 470 | } | 464 | } |
| 471 | 465 | ||
| 472 | const struct clk_ops mp1_gate_clk_ops = { | 466 | static const struct clk_ops mp1_gate_clk_ops = { |
| 473 | .enable = mp1_gate_clk_enable, | 467 | .enable = mp1_gate_clk_enable, |
| 474 | .disable = mp1_gate_clk_disable, | 468 | .disable = mp1_gate_clk_disable, |
| 475 | .is_enabled = clk_gate_is_enabled, | 469 | .is_enabled = clk_gate_is_enabled, |
| @@ -698,7 +692,7 @@ static void mp1_mgate_clk_disable(struct clk_hw *hw) | |||
| 698 | mp1_gate_clk_disable(hw); | 692 | mp1_gate_clk_disable(hw); |
| 699 | } | 693 | } |
| 700 | 694 | ||
| 701 | const struct clk_ops mp1_mgate_clk_ops = { | 695 | static const struct clk_ops mp1_mgate_clk_ops = { |
| 702 | .enable = mp1_mgate_clk_enable, | 696 | .enable = mp1_mgate_clk_enable, |
| 703 | .disable = mp1_mgate_clk_disable, | 697 | .disable = mp1_mgate_clk_disable, |
| 704 | .is_enabled = clk_gate_is_enabled, | 698 | .is_enabled = clk_gate_is_enabled, |
| @@ -732,7 +726,7 @@ static int clk_mmux_set_parent(struct clk_hw *hw, u8 index) | |||
| 732 | return 0; | 726 | return 0; |
| 733 | } | 727 | } |
| 734 | 728 | ||
| 735 | const struct clk_ops clk_mmux_ops = { | 729 | static const struct clk_ops clk_mmux_ops = { |
| 736 | .get_parent = clk_mmux_get_parent, | 730 | .get_parent = clk_mmux_get_parent, |
| 737 | .set_parent = clk_mmux_set_parent, | 731 | .set_parent = clk_mmux_set_parent, |
| 738 | .determine_rate = __clk_mux_determine_rate, | 732 | .determine_rate = __clk_mux_determine_rate, |
| @@ -1048,10 +1042,10 @@ struct stm32_pll_cfg { | |||
| 1048 | u32 offset; | 1042 | u32 offset; |
| 1049 | }; | 1043 | }; |
| 1050 | 1044 | ||
| 1051 | struct clk_hw *_clk_register_pll(struct device *dev, | 1045 | static struct clk_hw *_clk_register_pll(struct device *dev, |
| 1052 | struct clk_hw_onecell_data *clk_data, | 1046 | struct clk_hw_onecell_data *clk_data, |
| 1053 | void __iomem *base, spinlock_t *lock, | 1047 | void __iomem *base, spinlock_t *lock, |
| 1054 | const struct clock_config *cfg) | 1048 | const struct clock_config *cfg) |
| 1055 | { | 1049 | { |
| 1056 | struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg; | 1050 | struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg; |
| 1057 | 1051 | ||
| @@ -1405,7 +1399,8 @@ enum { | |||
| 1405 | G_USBH, | 1399 | G_USBH, |
| 1406 | G_ETHSTP, | 1400 | G_ETHSTP, |
| 1407 | G_RTCAPB, | 1401 | G_RTCAPB, |
| 1408 | G_TZC, | 1402 | G_TZC1, |
| 1403 | G_TZC2, | ||
| 1409 | G_TZPC, | 1404 | G_TZPC, |
| 1410 | G_IWDG1, | 1405 | G_IWDG1, |
| 1411 | G_BSEC, | 1406 | G_BSEC, |
| @@ -1417,7 +1412,7 @@ enum { | |||
| 1417 | G_LAST | 1412 | G_LAST |
| 1418 | }; | 1413 | }; |
| 1419 | 1414 | ||
| 1420 | struct stm32_mgate mp1_mgate[G_LAST]; | 1415 | static struct stm32_mgate mp1_mgate[G_LAST]; |
| 1421 | 1416 | ||
| 1422 | #define _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\ | 1417 | #define _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\ |
| 1423 | _mgate, _ops)\ | 1418 | _mgate, _ops)\ |
| @@ -1440,7 +1435,7 @@ struct stm32_mgate mp1_mgate[G_LAST]; | |||
| 1440 | &mp1_mgate[_id], &mp1_mgate_clk_ops) | 1435 | &mp1_mgate[_id], &mp1_mgate_clk_ops) |
| 1441 | 1436 | ||
| 1442 | /* Peripheral gates */ | 1437 | /* Peripheral gates */ |
| 1443 | struct stm32_gate_cfg per_gate_cfg[G_LAST] = { | 1438 | static struct stm32_gate_cfg per_gate_cfg[G_LAST] = { |
| 1444 | /* Multi gates */ | 1439 | /* Multi gates */ |
| 1445 | K_GATE(G_MDIO, RCC_APB1ENSETR, 31, 0), | 1440 | K_GATE(G_MDIO, RCC_APB1ENSETR, 31, 0), |
| 1446 | K_MGATE(G_DAC12, RCC_APB1ENSETR, 29, 0), | 1441 | K_MGATE(G_DAC12, RCC_APB1ENSETR, 29, 0), |
| @@ -1506,7 +1501,8 @@ struct stm32_gate_cfg per_gate_cfg[G_LAST] = { | |||
| 1506 | K_GATE(G_BSEC, RCC_APB5ENSETR, 16, 0), | 1501 | K_GATE(G_BSEC, RCC_APB5ENSETR, 16, 0), |
| 1507 | K_GATE(G_IWDG1, RCC_APB5ENSETR, 15, 0), | 1502 | K_GATE(G_IWDG1, RCC_APB5ENSETR, 15, 0), |
| 1508 | K_GATE(G_TZPC, RCC_APB5ENSETR, 13, 0), | 1503 | K_GATE(G_TZPC, RCC_APB5ENSETR, 13, 0), |
| 1509 | K_GATE(G_TZC, RCC_APB5ENSETR, 12, 0), | 1504 | K_GATE(G_TZC2, RCC_APB5ENSETR, 12, 0), |
| 1505 | K_GATE(G_TZC1, RCC_APB5ENSETR, 11, 0), | ||
| 1510 | K_GATE(G_RTCAPB, RCC_APB5ENSETR, 8, 0), | 1506 | K_GATE(G_RTCAPB, RCC_APB5ENSETR, 8, 0), |
| 1511 | K_MGATE(G_USART1, RCC_APB5ENSETR, 4, 0), | 1507 | K_MGATE(G_USART1, RCC_APB5ENSETR, 4, 0), |
| 1512 | K_MGATE(G_I2C6, RCC_APB5ENSETR, 3, 0), | 1508 | K_MGATE(G_I2C6, RCC_APB5ENSETR, 3, 0), |
| @@ -1600,7 +1596,7 @@ enum { | |||
| 1600 | M_LAST | 1596 | M_LAST |
| 1601 | }; | 1597 | }; |
| 1602 | 1598 | ||
| 1603 | struct stm32_mmux ker_mux[M_LAST]; | 1599 | static struct stm32_mmux ker_mux[M_LAST]; |
| 1604 | 1600 | ||
| 1605 | #define _K_MUX(_id, _offset, _shift, _width, _mux_flags, _mmux, _ops)\ | 1601 | #define _K_MUX(_id, _offset, _shift, _width, _mux_flags, _mmux, _ops)\ |
| 1606 | [_id] = {\ | 1602 | [_id] = {\ |
| @@ -1623,7 +1619,7 @@ struct stm32_mmux ker_mux[M_LAST]; | |||
| 1623 | _K_MUX(_id, _offset, _shift, _width, _mux_flags,\ | 1619 | _K_MUX(_id, _offset, _shift, _width, _mux_flags,\ |
| 1624 | &ker_mux[_id], &clk_mmux_ops) | 1620 | &ker_mux[_id], &clk_mmux_ops) |
| 1625 | 1621 | ||
| 1626 | const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = { | 1622 | static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = { |
| 1627 | /* Kernel multi mux */ | 1623 | /* Kernel multi mux */ |
| 1628 | K_MMUX(M_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0), | 1624 | K_MMUX(M_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0), |
| 1629 | K_MMUX(M_SPI23, RCC_SPI2S23CKSELR, 0, 3, 0), | 1625 | K_MMUX(M_SPI23, RCC_SPI2S23CKSELR, 0, 3, 0), |
| @@ -1860,7 +1856,8 @@ static const struct clock_config stm32mp1_clock_cfg[] = { | |||
| 1860 | PCLK(USART1, "usart1", "pclk5", 0, G_USART1), | 1856 | PCLK(USART1, "usart1", "pclk5", 0, G_USART1), |
| 1861 | PCLK(RTCAPB, "rtcapb", "pclk5", CLK_IGNORE_UNUSED | | 1857 | PCLK(RTCAPB, "rtcapb", "pclk5", CLK_IGNORE_UNUSED | |
| 1862 | CLK_IS_CRITICAL, G_RTCAPB), | 1858 | CLK_IS_CRITICAL, G_RTCAPB), |
| 1863 | PCLK(TZC, "tzc", "pclk5", CLK_IGNORE_UNUSED, G_TZC), | 1859 | PCLK(TZC1, "tzc1", "ck_axi", CLK_IGNORE_UNUSED, G_TZC1), |
| 1860 | PCLK(TZC2, "tzc2", "ck_axi", CLK_IGNORE_UNUSED, G_TZC2), | ||
| 1864 | PCLK(TZPC, "tzpc", "pclk5", CLK_IGNORE_UNUSED, G_TZPC), | 1861 | PCLK(TZPC, "tzpc", "pclk5", CLK_IGNORE_UNUSED, G_TZPC), |
| 1865 | PCLK(IWDG1, "iwdg1", "pclk5", 0, G_IWDG1), | 1862 | PCLK(IWDG1, "iwdg1", "pclk5", 0, G_IWDG1), |
| 1866 | PCLK(BSEC, "bsec", "pclk5", CLK_IGNORE_UNUSED, G_BSEC), | 1863 | PCLK(BSEC, "bsec", "pclk5", CLK_IGNORE_UNUSED, G_BSEC), |
| @@ -1916,8 +1913,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = { | |||
| 1916 | KCLK(RNG1_K, "rng1_k", rng_src, 0, G_RNG1, M_RNG1), | 1913 | KCLK(RNG1_K, "rng1_k", rng_src, 0, G_RNG1, M_RNG1), |
| 1917 | KCLK(RNG2_K, "rng2_k", rng_src, 0, G_RNG2, M_RNG2), | 1914 | KCLK(RNG2_K, "rng2_k", rng_src, 0, G_RNG2, M_RNG2), |
| 1918 | KCLK(USBPHY_K, "usbphy_k", usbphy_src, 0, G_USBPHY, M_USBPHY), | 1915 | KCLK(USBPHY_K, "usbphy_k", usbphy_src, 0, G_USBPHY, M_USBPHY), |
| 1919 | KCLK(STGEN_K, "stgen_k", stgen_src, CLK_IGNORE_UNUSED, | 1916 | KCLK(STGEN_K, "stgen_k", stgen_src, CLK_IS_CRITICAL, G_STGEN, M_STGEN), |
| 1920 | G_STGEN, M_STGEN), | ||
| 1921 | KCLK(SPDIF_K, "spdif_k", spdif_src, 0, G_SPDIF, M_SPDIF), | 1917 | KCLK(SPDIF_K, "spdif_k", spdif_src, 0, G_SPDIF, M_SPDIF), |
| 1922 | KCLK(SPI1_K, "spi1_k", spi123_src, 0, G_SPI1, M_SPI1), | 1918 | KCLK(SPI1_K, "spi1_k", spi123_src, 0, G_SPI1, M_SPI1), |
| 1923 | KCLK(SPI2_K, "spi2_k", spi123_src, 0, G_SPI2, M_SPI23), | 1919 | KCLK(SPI2_K, "spi2_k", spi123_src, 0, G_SPI2, M_SPI23), |
| @@ -1948,8 +1944,8 @@ static const struct clock_config stm32mp1_clock_cfg[] = { | |||
| 1948 | KCLK(FDCAN_K, "fdcan_k", fdcan_src, 0, G_FDCAN, M_FDCAN), | 1944 | KCLK(FDCAN_K, "fdcan_k", fdcan_src, 0, G_FDCAN, M_FDCAN), |
| 1949 | KCLK(SAI1_K, "sai1_k", sai_src, 0, G_SAI1, M_SAI1), | 1945 | KCLK(SAI1_K, "sai1_k", sai_src, 0, G_SAI1, M_SAI1), |
| 1950 | KCLK(SAI2_K, "sai2_k", sai2_src, 0, G_SAI2, M_SAI2), | 1946 | KCLK(SAI2_K, "sai2_k", sai2_src, 0, G_SAI2, M_SAI2), |
| 1951 | KCLK(SAI3_K, "sai3_k", sai_src, 0, G_SAI2, M_SAI3), | 1947 | KCLK(SAI3_K, "sai3_k", sai_src, 0, G_SAI3, M_SAI3), |
| 1952 | KCLK(SAI4_K, "sai4_k", sai_src, 0, G_SAI2, M_SAI4), | 1948 | KCLK(SAI4_K, "sai4_k", sai_src, 0, G_SAI4, M_SAI4), |
| 1953 | KCLK(ADC12_K, "adc12_k", adc12_src, 0, G_ADC12, M_ADC12), | 1949 | KCLK(ADC12_K, "adc12_k", adc12_src, 0, G_ADC12, M_ADC12), |
| 1954 | KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI), | 1950 | KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI), |
| 1955 | KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1), | 1951 | KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1), |
| @@ -1992,10 +1988,6 @@ static const struct clock_config stm32mp1_clock_cfg[] = { | |||
| 1992 | _DIV(RCC_MCO2CFGR, 4, 4, 0, NULL)), | 1988 | _DIV(RCC_MCO2CFGR, 4, 4, 0, NULL)), |
| 1993 | 1989 | ||
| 1994 | /* Debug clocks */ | 1990 | /* Debug clocks */ |
| 1995 | FIXED_FACTOR(NO_ID, "ck_axi_div2", "ck_axi", 0, 1, 2), | ||
| 1996 | |||
| 1997 | GATE(DBG, "ck_apb_dbg", "ck_axi_div2", 0, RCC_DBGCFGR, 8, 0), | ||
| 1998 | |||
| 1999 | GATE(CK_DBG, "ck_sys_dbg", "ck_axi", 0, RCC_DBGCFGR, 8, 0), | 1991 | GATE(CK_DBG, "ck_sys_dbg", "ck_axi", 0, RCC_DBGCFGR, 8, 0), |
| 2000 | 1992 | ||
| 2001 | COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, CLK_OPS_PARENT_ENABLE, | 1993 | COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, CLK_OPS_PARENT_ENABLE, |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index ea67ac81c6f9..7af555f0e60c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
| @@ -426,9 +426,9 @@ static bool mux_is_better_rate(unsigned long rate, unsigned long now, | |||
| 426 | return now <= rate && now > best; | 426 | return now <= rate && now > best; |
| 427 | } | 427 | } |
| 428 | 428 | ||
| 429 | static int | 429 | int clk_mux_determine_rate_flags(struct clk_hw *hw, |
| 430 | clk_mux_determine_rate_flags(struct clk_hw *hw, struct clk_rate_request *req, | 430 | struct clk_rate_request *req, |
| 431 | unsigned long flags) | 431 | unsigned long flags) |
| 432 | { | 432 | { |
| 433 | struct clk_core *core = hw->core, *parent, *best_parent = NULL; | 433 | struct clk_core *core = hw->core, *parent, *best_parent = NULL; |
| 434 | int i, num_parents, ret; | 434 | int i, num_parents, ret; |
| @@ -488,6 +488,7 @@ out: | |||
| 488 | 488 | ||
| 489 | return 0; | 489 | return 0; |
| 490 | } | 490 | } |
| 491 | EXPORT_SYMBOL_GPL(clk_mux_determine_rate_flags); | ||
| 491 | 492 | ||
| 492 | struct clk *__clk_lookup(const char *name) | 493 | struct clk *__clk_lookup(const char *name) |
| 493 | { | 494 | { |
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 114ecbb94ec5..12320118f8de 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c | |||
| @@ -464,7 +464,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
| 464 | clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000); | 464 | clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000); |
| 465 | 465 | ||
| 466 | /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ | 466 | /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ |
| 467 | clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]); | 467 | clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_OSC]); |
| 468 | clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]); | 468 | clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]); |
| 469 | clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]); | 469 | clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]); |
| 470 | clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]); | 470 | clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]); |
diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c index 3645fdb62343..ab7a3556f5b2 100644 --- a/drivers/clk/meson/clk-regmap.c +++ b/drivers/clk/meson/clk-regmap.c | |||
| @@ -153,10 +153,19 @@ static int clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index) | |||
| 153 | val << mux->shift); | 153 | val << mux->shift); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | static int clk_regmap_mux_determine_rate(struct clk_hw *hw, | ||
| 157 | struct clk_rate_request *req) | ||
| 158 | { | ||
| 159 | struct clk_regmap *clk = to_clk_regmap(hw); | ||
| 160 | struct clk_regmap_mux_data *mux = clk_get_regmap_mux_data(clk); | ||
| 161 | |||
| 162 | return clk_mux_determine_rate_flags(hw, req, mux->flags); | ||
| 163 | } | ||
| 164 | |||
| 156 | const struct clk_ops clk_regmap_mux_ops = { | 165 | const struct clk_ops clk_regmap_mux_ops = { |
| 157 | .get_parent = clk_regmap_mux_get_parent, | 166 | .get_parent = clk_regmap_mux_get_parent, |
| 158 | .set_parent = clk_regmap_mux_set_parent, | 167 | .set_parent = clk_regmap_mux_set_parent, |
| 159 | .determine_rate = __clk_mux_determine_rate, | 168 | .determine_rate = clk_regmap_mux_determine_rate, |
| 160 | }; | 169 | }; |
| 161 | EXPORT_SYMBOL_GPL(clk_regmap_mux_ops); | 170 | EXPORT_SYMBOL_GPL(clk_regmap_mux_ops); |
| 162 | 171 | ||
diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h index 0be78383f257..badc4c22b4ee 100644 --- a/drivers/clk/meson/gxbb-aoclk.h +++ b/drivers/clk/meson/gxbb-aoclk.h | |||
| @@ -17,8 +17,6 @@ | |||
| 17 | #define AO_RTC_ALT_CLK_CNTL0 0x94 | 17 | #define AO_RTC_ALT_CLK_CNTL0 0x94 |
| 18 | #define AO_RTC_ALT_CLK_CNTL1 0x98 | 18 | #define AO_RTC_ALT_CLK_CNTL1 0x98 |
| 19 | 19 | ||
| 20 | extern const struct clk_ops meson_aoclk_gate_regmap_ops; | ||
| 21 | |||
| 22 | struct aoclk_cec_32k { | 20 | struct aoclk_cec_32k { |
| 23 | struct clk_hw hw; | 21 | struct clk_hw hw; |
| 24 | struct regmap *regmap; | 22 | struct regmap *regmap; |
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index cc2992493e0b..d0524ec71aad 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c | |||
| @@ -253,7 +253,7 @@ static struct clk_fixed_factor meson8b_fclk_div3_div = { | |||
| 253 | .mult = 1, | 253 | .mult = 1, |
| 254 | .div = 3, | 254 | .div = 3, |
| 255 | .hw.init = &(struct clk_init_data){ | 255 | .hw.init = &(struct clk_init_data){ |
| 256 | .name = "fclk_div_div3", | 256 | .name = "fclk_div3_div", |
| 257 | .ops = &clk_fixed_factor_ops, | 257 | .ops = &clk_fixed_factor_ops, |
| 258 | .parent_names = (const char *[]){ "fixed_pll" }, | 258 | .parent_names = (const char *[]){ "fixed_pll" }, |
| 259 | .num_parents = 1, | 259 | .num_parents = 1, |
| @@ -632,7 +632,8 @@ static struct clk_regmap meson8b_cpu_clk = { | |||
| 632 | .hw.init = &(struct clk_init_data){ | 632 | .hw.init = &(struct clk_init_data){ |
| 633 | .name = "cpu_clk", | 633 | .name = "cpu_clk", |
| 634 | .ops = &clk_regmap_mux_ro_ops, | 634 | .ops = &clk_regmap_mux_ro_ops, |
| 635 | .parent_names = (const char *[]){ "xtal", "cpu_out_sel" }, | 635 | .parent_names = (const char *[]){ "xtal", |
| 636 | "cpu_scale_out_sel" }, | ||
| 636 | .num_parents = 2, | 637 | .num_parents = 2, |
| 637 | .flags = (CLK_SET_RATE_PARENT | | 638 | .flags = (CLK_SET_RATE_PARENT | |
| 638 | CLK_SET_RATE_NO_REPARENT), | 639 | CLK_SET_RATE_NO_REPARENT), |
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index de55c7d57438..96b35b8b3606 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
| @@ -20,7 +20,7 @@ config ACPI_CPPC_CPUFREQ | |||
| 20 | 20 | ||
| 21 | config ARM_ARMADA_37XX_CPUFREQ | 21 | config ARM_ARMADA_37XX_CPUFREQ |
| 22 | tristate "Armada 37xx CPUFreq support" | 22 | tristate "Armada 37xx CPUFreq support" |
| 23 | depends on ARCH_MVEBU | 23 | depends on ARCH_MVEBU && CPUFREQ_DT |
| 24 | help | 24 | help |
| 25 | This adds the CPUFreq driver support for Marvell Armada 37xx SoCs. | 25 | This adds the CPUFreq driver support for Marvell Armada 37xx SoCs. |
| 26 | The Armada 37xx PMU supports 4 frequency and VDD levels. | 26 | The Armada 37xx PMU supports 4 frequency and VDD levels. |
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index bc5fc1630876..3464580ac3ca 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c | |||
| @@ -42,9 +42,6 @@ | |||
| 42 | */ | 42 | */ |
| 43 | static struct cppc_cpudata **all_cpu_data; | 43 | static struct cppc_cpudata **all_cpu_data; |
| 44 | 44 | ||
| 45 | /* Capture the max KHz from DMI */ | ||
| 46 | static u64 cppc_dmi_max_khz; | ||
| 47 | |||
| 48 | /* Callback function used to retrieve the max frequency from DMI */ | 45 | /* Callback function used to retrieve the max frequency from DMI */ |
| 49 | static void cppc_find_dmi_mhz(const struct dmi_header *dm, void *private) | 46 | static void cppc_find_dmi_mhz(const struct dmi_header *dm, void *private) |
| 50 | { | 47 | { |
| @@ -75,6 +72,64 @@ static u64 cppc_get_dmi_max_khz(void) | |||
| 75 | return (1000 * mhz); | 72 | return (1000 * mhz); |
| 76 | } | 73 | } |
| 77 | 74 | ||
| 75 | /* | ||
| 76 | * If CPPC lowest_freq and nominal_freq registers are exposed then we can | ||
| 77 | * use them to convert perf to freq and vice versa | ||
| 78 | * | ||
| 79 | * If the perf/freq point lies between Nominal and Lowest, we can treat | ||
| 80 | * (Low perf, Low freq) and (Nom Perf, Nom freq) as 2D co-ordinates of a line | ||
| 81 | * and extrapolate the rest | ||
| 82 | * For perf/freq > Nominal, we use the ratio perf:freq at Nominal for conversion | ||
| 83 | */ | ||
| 84 | static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu, | ||
| 85 | unsigned int perf) | ||
| 86 | { | ||
| 87 | static u64 max_khz; | ||
| 88 | struct cppc_perf_caps *caps = &cpu->perf_caps; | ||
| 89 | u64 mul, div; | ||
| 90 | |||
| 91 | if (caps->lowest_freq && caps->nominal_freq) { | ||
| 92 | if (perf >= caps->nominal_perf) { | ||
| 93 | mul = caps->nominal_freq; | ||
| 94 | div = caps->nominal_perf; | ||
| 95 | } else { | ||
| 96 | mul = caps->nominal_freq - caps->lowest_freq; | ||
| 97 | div = caps->nominal_perf - caps->lowest_perf; | ||
| 98 | } | ||
| 99 | } else { | ||
| 100 | if (!max_khz) | ||
| 101 | max_khz = cppc_get_dmi_max_khz(); | ||
| 102 | mul = max_khz; | ||
| 103 | div = cpu->perf_caps.highest_perf; | ||
| 104 | } | ||
| 105 | return (u64)perf * mul / div; | ||
| 106 | } | ||
| 107 | |||
| 108 | static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu, | ||
| 109 | unsigned int freq) | ||
| 110 | { | ||
| 111 | static u64 max_khz; | ||
| 112 | struct cppc_perf_caps *caps = &cpu->perf_caps; | ||
| 113 | u64 mul, div; | ||
| 114 | |||
| 115 | if (caps->lowest_freq && caps->nominal_freq) { | ||
| 116 | if (freq >= caps->nominal_freq) { | ||
| 117 | mul = caps->nominal_perf; | ||
| 118 | div = caps->nominal_freq; | ||
| 119 | } else { | ||
| 120 | mul = caps->lowest_perf; | ||
| 121 | div = caps->lowest_freq; | ||
| 122 | } | ||
| 123 | } else { | ||
| 124 | if (!max_khz) | ||
| 125 | max_khz = cppc_get_dmi_max_khz(); | ||
| 126 | mul = cpu->perf_caps.highest_perf; | ||
| 127 | div = max_khz; | ||
| 128 | } | ||
| 129 | |||
| 130 | return (u64)freq * mul / div; | ||
| 131 | } | ||
| 132 | |||
| 78 | static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, | 133 | static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, |
| 79 | unsigned int target_freq, | 134 | unsigned int target_freq, |
| 80 | unsigned int relation) | 135 | unsigned int relation) |
| @@ -86,7 +141,7 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, | |||
| 86 | 141 | ||
| 87 | cpu = all_cpu_data[policy->cpu]; | 142 | cpu = all_cpu_data[policy->cpu]; |
| 88 | 143 | ||
| 89 | desired_perf = (u64)target_freq * cpu->perf_caps.highest_perf / cppc_dmi_max_khz; | 144 | desired_perf = cppc_cpufreq_khz_to_perf(cpu, target_freq); |
| 90 | /* Return if it is exactly the same perf */ | 145 | /* Return if it is exactly the same perf */ |
| 91 | if (desired_perf == cpu->perf_ctrls.desired_perf) | 146 | if (desired_perf == cpu->perf_ctrls.desired_perf) |
| 92 | return ret; | 147 | return ret; |
| @@ -126,6 +181,49 @@ static void cppc_cpufreq_stop_cpu(struct cpufreq_policy *policy) | |||
| 126 | cpu->perf_caps.lowest_perf, cpu_num, ret); | 181 | cpu->perf_caps.lowest_perf, cpu_num, ret); |
| 127 | } | 182 | } |
| 128 | 183 | ||
| 184 | /* | ||
| 185 | * The PCC subspace describes the rate at which platform can accept commands | ||
| 186 | * on the shared PCC channel (including READs which do not count towards freq | ||
| 187 | * trasition requests), so ideally we need to use the PCC values as a fallback | ||
| 188 | * if we don't have a platform specific transition_delay_us | ||
| 189 | */ | ||
| 190 | #ifdef CONFIG_ARM64 | ||
| 191 | #include <asm/cputype.h> | ||
| 192 | |||
| 193 | static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu) | ||
| 194 | { | ||
| 195 | unsigned long implementor = read_cpuid_implementor(); | ||
| 196 | unsigned long part_num = read_cpuid_part_number(); | ||
| 197 | unsigned int delay_us = 0; | ||
| 198 | |||
| 199 | switch (implementor) { | ||
| 200 | case ARM_CPU_IMP_QCOM: | ||
| 201 | switch (part_num) { | ||
| 202 | case QCOM_CPU_PART_FALKOR_V1: | ||
| 203 | case QCOM_CPU_PART_FALKOR: | ||
| 204 | delay_us = 10000; | ||
| 205 | break; | ||
| 206 | default: | ||
| 207 | delay_us = cppc_get_transition_latency(cpu) / NSEC_PER_USEC; | ||
| 208 | break; | ||
| 209 | } | ||
| 210 | break; | ||
| 211 | default: | ||
| 212 | delay_us = cppc_get_transition_latency(cpu) / NSEC_PER_USEC; | ||
| 213 | break; | ||
| 214 | } | ||
| 215 | |||
| 216 | return delay_us; | ||
| 217 | } | ||
| 218 | |||
| 219 | #else | ||
| 220 | |||
| 221 | static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu) | ||
| 222 | { | ||
| 223 | return cppc_get_transition_latency(cpu) / NSEC_PER_USEC; | ||
| 224 | } | ||
| 225 | #endif | ||
| 226 | |||
| 129 | static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) | 227 | static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) |
| 130 | { | 228 | { |
| 131 | struct cppc_cpudata *cpu; | 229 | struct cppc_cpudata *cpu; |
| @@ -143,27 +241,26 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 143 | return ret; | 241 | return ret; |
| 144 | } | 242 | } |
| 145 | 243 | ||
| 146 | cppc_dmi_max_khz = cppc_get_dmi_max_khz(); | 244 | /* Convert the lowest and nominal freq from MHz to KHz */ |
| 245 | cpu->perf_caps.lowest_freq *= 1000; | ||
| 246 | cpu->perf_caps.nominal_freq *= 1000; | ||
| 147 | 247 | ||
| 148 | /* | 248 | /* |
| 149 | * Set min to lowest nonlinear perf to avoid any efficiency penalty (see | 249 | * Set min to lowest nonlinear perf to avoid any efficiency penalty (see |
| 150 | * Section 8.4.7.1.1.5 of ACPI 6.1 spec) | 250 | * Section 8.4.7.1.1.5 of ACPI 6.1 spec) |
| 151 | */ | 251 | */ |
| 152 | policy->min = cpu->perf_caps.lowest_nonlinear_perf * cppc_dmi_max_khz / | 252 | policy->min = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_nonlinear_perf); |
| 153 | cpu->perf_caps.highest_perf; | 253 | policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf); |
| 154 | policy->max = cppc_dmi_max_khz; | ||
| 155 | 254 | ||
| 156 | /* | 255 | /* |
| 157 | * Set cpuinfo.min_freq to Lowest to make the full range of performance | 256 | * Set cpuinfo.min_freq to Lowest to make the full range of performance |
| 158 | * available if userspace wants to use any perf between lowest & lowest | 257 | * available if userspace wants to use any perf between lowest & lowest |
| 159 | * nonlinear perf | 258 | * nonlinear perf |
| 160 | */ | 259 | */ |
| 161 | policy->cpuinfo.min_freq = cpu->perf_caps.lowest_perf * cppc_dmi_max_khz / | 260 | policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_perf); |
| 162 | cpu->perf_caps.highest_perf; | 261 | policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf); |
| 163 | policy->cpuinfo.max_freq = cppc_dmi_max_khz; | ||
| 164 | 262 | ||
| 165 | policy->transition_delay_us = cppc_get_transition_latency(cpu_num) / | 263 | policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num); |
| 166 | NSEC_PER_USEC; | ||
| 167 | policy->shared_type = cpu->shared_type; | 264 | policy->shared_type = cpu->shared_type; |
| 168 | 265 | ||
| 169 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { | 266 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { |
| @@ -187,7 +284,8 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 187 | cpu->cur_policy = policy; | 284 | cpu->cur_policy = policy; |
| 188 | 285 | ||
| 189 | /* Set policy->cur to max now. The governors will adjust later. */ | 286 | /* Set policy->cur to max now. The governors will adjust later. */ |
| 190 | policy->cur = cppc_dmi_max_khz; | 287 | policy->cur = cppc_cpufreq_perf_to_khz(cpu, |
| 288 | cpu->perf_caps.highest_perf); | ||
| 191 | cpu->perf_ctrls.desired_perf = cpu->perf_caps.highest_perf; | 289 | cpu->perf_ctrls.desired_perf = cpu->perf_caps.highest_perf; |
| 192 | 290 | ||
| 193 | ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls); | 291 | ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls); |
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index d29275b97e84..4a828c18099a 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c | |||
| @@ -524,6 +524,14 @@ static int bam_alloc_chan(struct dma_chan *chan) | |||
| 524 | return 0; | 524 | return 0; |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | static int bam_pm_runtime_get_sync(struct device *dev) | ||
| 528 | { | ||
| 529 | if (pm_runtime_enabled(dev)) | ||
| 530 | return pm_runtime_get_sync(dev); | ||
| 531 | |||
| 532 | return 0; | ||
| 533 | } | ||
| 534 | |||
| 527 | /** | 535 | /** |
| 528 | * bam_free_chan - Frees dma resources associated with specific channel | 536 | * bam_free_chan - Frees dma resources associated with specific channel |
| 529 | * @chan: specified channel | 537 | * @chan: specified channel |
| @@ -539,7 +547,7 @@ static void bam_free_chan(struct dma_chan *chan) | |||
| 539 | unsigned long flags; | 547 | unsigned long flags; |
| 540 | int ret; | 548 | int ret; |
| 541 | 549 | ||
| 542 | ret = pm_runtime_get_sync(bdev->dev); | 550 | ret = bam_pm_runtime_get_sync(bdev->dev); |
| 543 | if (ret < 0) | 551 | if (ret < 0) |
| 544 | return; | 552 | return; |
| 545 | 553 | ||
| @@ -720,7 +728,7 @@ static int bam_pause(struct dma_chan *chan) | |||
| 720 | unsigned long flag; | 728 | unsigned long flag; |
| 721 | int ret; | 729 | int ret; |
| 722 | 730 | ||
| 723 | ret = pm_runtime_get_sync(bdev->dev); | 731 | ret = bam_pm_runtime_get_sync(bdev->dev); |
| 724 | if (ret < 0) | 732 | if (ret < 0) |
| 725 | return ret; | 733 | return ret; |
| 726 | 734 | ||
| @@ -746,7 +754,7 @@ static int bam_resume(struct dma_chan *chan) | |||
| 746 | unsigned long flag; | 754 | unsigned long flag; |
| 747 | int ret; | 755 | int ret; |
| 748 | 756 | ||
| 749 | ret = pm_runtime_get_sync(bdev->dev); | 757 | ret = bam_pm_runtime_get_sync(bdev->dev); |
| 750 | if (ret < 0) | 758 | if (ret < 0) |
| 751 | return ret; | 759 | return ret; |
| 752 | 760 | ||
| @@ -852,7 +860,7 @@ static irqreturn_t bam_dma_irq(int irq, void *data) | |||
| 852 | if (srcs & P_IRQ) | 860 | if (srcs & P_IRQ) |
| 853 | tasklet_schedule(&bdev->task); | 861 | tasklet_schedule(&bdev->task); |
| 854 | 862 | ||
| 855 | ret = pm_runtime_get_sync(bdev->dev); | 863 | ret = bam_pm_runtime_get_sync(bdev->dev); |
| 856 | if (ret < 0) | 864 | if (ret < 0) |
| 857 | return ret; | 865 | return ret; |
| 858 | 866 | ||
| @@ -969,7 +977,7 @@ static void bam_start_dma(struct bam_chan *bchan) | |||
| 969 | if (!vd) | 977 | if (!vd) |
| 970 | return; | 978 | return; |
| 971 | 979 | ||
| 972 | ret = pm_runtime_get_sync(bdev->dev); | 980 | ret = bam_pm_runtime_get_sync(bdev->dev); |
| 973 | if (ret < 0) | 981 | if (ret < 0) |
| 974 | return; | 982 | return; |
| 975 | 983 | ||
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 14b147135a0c..2455be8cbc4f 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c | |||
| @@ -778,6 +778,7 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info, | |||
| 778 | if (scmi_mbox_chan_setup(info, &sdev->dev, prot_id)) { | 778 | if (scmi_mbox_chan_setup(info, &sdev->dev, prot_id)) { |
| 779 | dev_err(&sdev->dev, "failed to setup transport\n"); | 779 | dev_err(&sdev->dev, "failed to setup transport\n"); |
| 780 | scmi_device_destroy(sdev); | 780 | scmi_device_destroy(sdev); |
| 781 | return; | ||
| 781 | } | 782 | } |
| 782 | 783 | ||
| 783 | /* setup handle now as the transport is ready */ | 784 | /* setup handle now as the transport is ready */ |
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index b9bd827caa22..1b4d465cc5d9 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c | |||
| @@ -98,6 +98,16 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg, | |||
| 98 | (phys_seed >> 32) & mask : TEXT_OFFSET; | 98 | (phys_seed >> 32) & mask : TEXT_OFFSET; |
| 99 | 99 | ||
| 100 | /* | 100 | /* |
| 101 | * With CONFIG_RANDOMIZE_TEXT_OFFSET=y, TEXT_OFFSET may not | ||
| 102 | * be a multiple of EFI_KIMG_ALIGN, and we must ensure that | ||
| 103 | * we preserve the misalignment of 'offset' relative to | ||
| 104 | * EFI_KIMG_ALIGN so that statically allocated objects whose | ||
| 105 | * alignment exceeds PAGE_SIZE appear correctly aligned in | ||
| 106 | * memory. | ||
| 107 | */ | ||
| 108 | offset |= TEXT_OFFSET % EFI_KIMG_ALIGN; | ||
| 109 | |||
| 110 | /* | ||
| 101 | * If KASLR is enabled, and we have some randomness available, | 111 | * If KASLR is enabled, and we have some randomness available, |
| 102 | * locate the kernel at a randomized offset in physical memory. | 112 | * locate the kernel at a randomized offset in physical memory. |
| 103 | */ | 113 | */ |
diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index 77e485557498..6f693b7d5220 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c | |||
| @@ -384,7 +384,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) | |||
| 384 | if (set) | 384 | if (set) |
| 385 | reg |= bit; | 385 | reg |= bit; |
| 386 | else | 386 | else |
| 387 | reg &= bit; | 387 | reg &= ~bit; |
| 388 | iowrite32(reg, addr); | 388 | iowrite32(reg, addr); |
| 389 | 389 | ||
| 390 | spin_unlock_irqrestore(&gpio->lock, flags); | 390 | spin_unlock_irqrestore(&gpio->lock, flags); |
diff --git a/drivers/gpio/gpio-pci-idio-16.c b/drivers/gpio/gpio-pci-idio-16.c index 1948724d8c36..25d16b2af1c3 100644 --- a/drivers/gpio/gpio-pci-idio-16.c +++ b/drivers/gpio/gpio-pci-idio-16.c | |||
| @@ -116,9 +116,9 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip, | |||
| 116 | unsigned long word_mask; | 116 | unsigned long word_mask; |
| 117 | const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); | 117 | const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); |
| 118 | unsigned long port_state; | 118 | unsigned long port_state; |
| 119 | u8 __iomem ports[] = { | 119 | void __iomem *ports[] = { |
| 120 | idio16gpio->reg->out0_7, idio16gpio->reg->out8_15, | 120 | &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15, |
| 121 | idio16gpio->reg->in0_7, idio16gpio->reg->in8_15, | 121 | &idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15, |
| 122 | }; | 122 | }; |
| 123 | 123 | ||
| 124 | /* clear bits array to a clean slate */ | 124 | /* clear bits array to a clean slate */ |
| @@ -143,7 +143,7 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip, | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | /* read bits from current gpio port */ | 145 | /* read bits from current gpio port */ |
| 146 | port_state = ioread8(ports + i); | 146 | port_state = ioread8(ports[i]); |
| 147 | 147 | ||
| 148 | /* store acquired bits at respective bits array offset */ | 148 | /* store acquired bits at respective bits array offset */ |
| 149 | bits[word_index] |= port_state << word_offset; | 149 | bits[word_index] |= port_state << word_offset; |
diff --git a/drivers/gpio/gpio-pcie-idio-24.c b/drivers/gpio/gpio-pcie-idio-24.c index 835607ecf658..f953541e7890 100644 --- a/drivers/gpio/gpio-pcie-idio-24.c +++ b/drivers/gpio/gpio-pcie-idio-24.c | |||
| @@ -206,10 +206,10 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip, | |||
| 206 | unsigned long word_mask; | 206 | unsigned long word_mask; |
| 207 | const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); | 207 | const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); |
| 208 | unsigned long port_state; | 208 | unsigned long port_state; |
| 209 | u8 __iomem ports[] = { | 209 | void __iomem *ports[] = { |
| 210 | idio24gpio->reg->out0_7, idio24gpio->reg->out8_15, | 210 | &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, |
| 211 | idio24gpio->reg->out16_23, idio24gpio->reg->in0_7, | 211 | &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7, |
| 212 | idio24gpio->reg->in8_15, idio24gpio->reg->in16_23, | 212 | &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23, |
| 213 | }; | 213 | }; |
| 214 | const unsigned long out_mode_mask = BIT(1); | 214 | const unsigned long out_mode_mask = BIT(1); |
| 215 | 215 | ||
| @@ -217,7 +217,7 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip, | |||
| 217 | bitmap_zero(bits, chip->ngpio); | 217 | bitmap_zero(bits, chip->ngpio); |
| 218 | 218 | ||
| 219 | /* get bits are evaluated a gpio port register at a time */ | 219 | /* get bits are evaluated a gpio port register at a time */ |
| 220 | for (i = 0; i < ARRAY_SIZE(ports); i++) { | 220 | for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) { |
| 221 | /* gpio offset in bits array */ | 221 | /* gpio offset in bits array */ |
| 222 | bits_offset = i * gpio_reg_size; | 222 | bits_offset = i * gpio_reg_size; |
| 223 | 223 | ||
| @@ -236,7 +236,7 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip, | |||
| 236 | 236 | ||
| 237 | /* read bits from current gpio port (port 6 is TTL GPIO) */ | 237 | /* read bits from current gpio port (port 6 is TTL GPIO) */ |
| 238 | if (i < 6) | 238 | if (i < 6) |
| 239 | port_state = ioread8(ports + i); | 239 | port_state = ioread8(ports[i]); |
| 240 | else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) | 240 | else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) |
| 241 | port_state = ioread8(&idio24gpio->reg->ttl_out0_7); | 241 | port_state = ioread8(&idio24gpio->reg->ttl_out0_7); |
| 242 | else | 242 | else |
| @@ -301,9 +301,9 @@ static void idio_24_gpio_set_multiple(struct gpio_chip *chip, | |||
| 301 | const unsigned long port_mask = GENMASK(gpio_reg_size, 0); | 301 | const unsigned long port_mask = GENMASK(gpio_reg_size, 0); |
| 302 | unsigned long flags; | 302 | unsigned long flags; |
| 303 | unsigned int out_state; | 303 | unsigned int out_state; |
| 304 | u8 __iomem ports[] = { | 304 | void __iomem *ports[] = { |
| 305 | idio24gpio->reg->out0_7, idio24gpio->reg->out8_15, | 305 | &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, |
| 306 | idio24gpio->reg->out16_23 | 306 | &idio24gpio->reg->out16_23 |
| 307 | }; | 307 | }; |
| 308 | const unsigned long out_mode_mask = BIT(1); | 308 | const unsigned long out_mode_mask = BIT(1); |
| 309 | const unsigned int ttl_offset = 48; | 309 | const unsigned int ttl_offset = 48; |
| @@ -327,9 +327,9 @@ static void idio_24_gpio_set_multiple(struct gpio_chip *chip, | |||
| 327 | raw_spin_lock_irqsave(&idio24gpio->lock, flags); | 327 | raw_spin_lock_irqsave(&idio24gpio->lock, flags); |
| 328 | 328 | ||
| 329 | /* process output lines */ | 329 | /* process output lines */ |
| 330 | out_state = ioread8(ports + i) & ~gpio_mask; | 330 | out_state = ioread8(ports[i]) & ~gpio_mask; |
| 331 | out_state |= (*bits >> bits_offset) & gpio_mask; | 331 | out_state |= (*bits >> bits_offset) & gpio_mask; |
| 332 | iowrite8(out_state, ports + i); | 332 | iowrite8(out_state, ports[i]); |
| 333 | 333 | ||
| 334 | raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); | 334 | raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); |
| 335 | } | 335 | } |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 43aeb07343ec..d8ccb500872f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -497,7 +497,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) | |||
| 497 | struct gpiohandle_request handlereq; | 497 | struct gpiohandle_request handlereq; |
| 498 | struct linehandle_state *lh; | 498 | struct linehandle_state *lh; |
| 499 | struct file *file; | 499 | struct file *file; |
| 500 | int fd, i, ret; | 500 | int fd, i, count = 0, ret; |
| 501 | u32 lflags; | 501 | u32 lflags; |
| 502 | 502 | ||
| 503 | if (copy_from_user(&handlereq, ip, sizeof(handlereq))) | 503 | if (copy_from_user(&handlereq, ip, sizeof(handlereq))) |
| @@ -558,6 +558,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) | |||
| 558 | if (ret) | 558 | if (ret) |
| 559 | goto out_free_descs; | 559 | goto out_free_descs; |
| 560 | lh->descs[i] = desc; | 560 | lh->descs[i] = desc; |
| 561 | count = i; | ||
| 561 | 562 | ||
| 562 | if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW) | 563 | if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW) |
| 563 | set_bit(FLAG_ACTIVE_LOW, &desc->flags); | 564 | set_bit(FLAG_ACTIVE_LOW, &desc->flags); |
| @@ -628,7 +629,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) | |||
| 628 | out_put_unused_fd: | 629 | out_put_unused_fd: |
| 629 | put_unused_fd(fd); | 630 | put_unused_fd(fd); |
| 630 | out_free_descs: | 631 | out_free_descs: |
| 631 | for (; i >= 0; i--) | 632 | for (i = 0; i < count; i++) |
| 632 | gpiod_free(lh->descs[i]); | 633 | gpiod_free(lh->descs[i]); |
| 633 | kfree(lh->label); | 634 | kfree(lh->label); |
| 634 | out_free_lh: | 635 | out_free_lh: |
| @@ -902,7 +903,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) | |||
| 902 | desc = &gdev->descs[offset]; | 903 | desc = &gdev->descs[offset]; |
| 903 | ret = gpiod_request(desc, le->label); | 904 | ret = gpiod_request(desc, le->label); |
| 904 | if (ret) | 905 | if (ret) |
| 905 | goto out_free_desc; | 906 | goto out_free_label; |
| 906 | le->desc = desc; | 907 | le->desc = desc; |
| 907 | le->eflags = eflags; | 908 | le->eflags = eflags; |
| 908 | 909 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 09d35051fdd6..3fabf9f97022 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | |||
| @@ -419,9 +419,11 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, unsigned ring_id) | |||
| 419 | 419 | ||
| 420 | if (other) { | 420 | if (other) { |
| 421 | signed long r; | 421 | signed long r; |
| 422 | r = dma_fence_wait_timeout(other, false, MAX_SCHEDULE_TIMEOUT); | 422 | r = dma_fence_wait(other, true); |
| 423 | if (r < 0) { | 423 | if (r < 0) { |
| 424 | DRM_ERROR("Error (%ld) waiting for fence!\n", r); | 424 | if (r != -ERESTARTSYS) |
| 425 | DRM_ERROR("Error (%ld) waiting for fence!\n", r); | ||
| 426 | |||
| 425 | return r; | 427 | return r; |
| 426 | } | 428 | } |
| 427 | } | 429 | } |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index ace9ad578ca0..4304d9e408b8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | |||
| @@ -83,21 +83,22 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, | |||
| 83 | enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ? | 83 | enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ? |
| 84 | I2C_MOT_TRUE : I2C_MOT_FALSE; | 84 | I2C_MOT_TRUE : I2C_MOT_FALSE; |
| 85 | enum ddc_result res; | 85 | enum ddc_result res; |
| 86 | ssize_t read_bytes; | 86 | uint32_t read_bytes = msg->size; |
| 87 | 87 | ||
| 88 | if (WARN_ON(msg->size > 16)) | 88 | if (WARN_ON(msg->size > 16)) |
| 89 | return -E2BIG; | 89 | return -E2BIG; |
| 90 | 90 | ||
| 91 | switch (msg->request & ~DP_AUX_I2C_MOT) { | 91 | switch (msg->request & ~DP_AUX_I2C_MOT) { |
| 92 | case DP_AUX_NATIVE_READ: | 92 | case DP_AUX_NATIVE_READ: |
| 93 | read_bytes = dal_ddc_service_read_dpcd_data( | 93 | res = dal_ddc_service_read_dpcd_data( |
| 94 | TO_DM_AUX(aux)->ddc_service, | 94 | TO_DM_AUX(aux)->ddc_service, |
| 95 | false, | 95 | false, |
| 96 | I2C_MOT_UNDEF, | 96 | I2C_MOT_UNDEF, |
| 97 | msg->address, | 97 | msg->address, |
| 98 | msg->buffer, | 98 | msg->buffer, |
| 99 | msg->size); | 99 | msg->size, |
| 100 | return read_bytes; | 100 | &read_bytes); |
| 101 | break; | ||
| 101 | case DP_AUX_NATIVE_WRITE: | 102 | case DP_AUX_NATIVE_WRITE: |
| 102 | res = dal_ddc_service_write_dpcd_data( | 103 | res = dal_ddc_service_write_dpcd_data( |
| 103 | TO_DM_AUX(aux)->ddc_service, | 104 | TO_DM_AUX(aux)->ddc_service, |
| @@ -108,14 +109,15 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, | |||
| 108 | msg->size); | 109 | msg->size); |
| 109 | break; | 110 | break; |
| 110 | case DP_AUX_I2C_READ: | 111 | case DP_AUX_I2C_READ: |
| 111 | read_bytes = dal_ddc_service_read_dpcd_data( | 112 | res = dal_ddc_service_read_dpcd_data( |
| 112 | TO_DM_AUX(aux)->ddc_service, | 113 | TO_DM_AUX(aux)->ddc_service, |
| 113 | true, | 114 | true, |
| 114 | mot, | 115 | mot, |
| 115 | msg->address, | 116 | msg->address, |
| 116 | msg->buffer, | 117 | msg->buffer, |
| 117 | msg->size); | 118 | msg->size, |
| 118 | return read_bytes; | 119 | &read_bytes); |
| 120 | break; | ||
| 119 | case DP_AUX_I2C_WRITE: | 121 | case DP_AUX_I2C_WRITE: |
| 120 | res = dal_ddc_service_write_dpcd_data( | 122 | res = dal_ddc_service_write_dpcd_data( |
| 121 | TO_DM_AUX(aux)->ddc_service, | 123 | TO_DM_AUX(aux)->ddc_service, |
| @@ -137,7 +139,9 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, | |||
| 137 | r == DDC_RESULT_SUCESSFULL); | 139 | r == DDC_RESULT_SUCESSFULL); |
| 138 | #endif | 140 | #endif |
| 139 | 141 | ||
| 140 | return msg->size; | 142 | if (res != DDC_RESULT_SUCESSFULL) |
| 143 | return -EIO; | ||
| 144 | return read_bytes; | ||
| 141 | } | 145 | } |
| 142 | 146 | ||
| 143 | static enum drm_connector_status | 147 | static enum drm_connector_status |
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 985fe8c22875..10a5807a7e8b 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | |||
| @@ -70,6 +70,10 @@ static enum bp_result get_firmware_info_v3_1( | |||
| 70 | struct bios_parser *bp, | 70 | struct bios_parser *bp, |
| 71 | struct dc_firmware_info *info); | 71 | struct dc_firmware_info *info); |
| 72 | 72 | ||
| 73 | static enum bp_result get_firmware_info_v3_2( | ||
| 74 | struct bios_parser *bp, | ||
| 75 | struct dc_firmware_info *info); | ||
| 76 | |||
| 73 | static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp, | 77 | static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp, |
| 74 | struct atom_display_object_path_v2 *object); | 78 | struct atom_display_object_path_v2 *object); |
| 75 | 79 | ||
| @@ -1321,9 +1325,11 @@ static enum bp_result bios_parser_get_firmware_info( | |||
| 1321 | case 3: | 1325 | case 3: |
| 1322 | switch (revision.minor) { | 1326 | switch (revision.minor) { |
| 1323 | case 1: | 1327 | case 1: |
| 1324 | case 2: | ||
| 1325 | result = get_firmware_info_v3_1(bp, info); | 1328 | result = get_firmware_info_v3_1(bp, info); |
| 1326 | break; | 1329 | break; |
| 1330 | case 2: | ||
| 1331 | result = get_firmware_info_v3_2(bp, info); | ||
| 1332 | break; | ||
| 1327 | default: | 1333 | default: |
| 1328 | break; | 1334 | break; |
| 1329 | } | 1335 | } |
| @@ -1383,6 +1389,84 @@ static enum bp_result get_firmware_info_v3_1( | |||
| 1383 | return BP_RESULT_OK; | 1389 | return BP_RESULT_OK; |
| 1384 | } | 1390 | } |
| 1385 | 1391 | ||
| 1392 | static enum bp_result get_firmware_info_v3_2( | ||
| 1393 | struct bios_parser *bp, | ||
| 1394 | struct dc_firmware_info *info) | ||
| 1395 | { | ||
| 1396 | struct atom_firmware_info_v3_2 *firmware_info; | ||
| 1397 | struct atom_display_controller_info_v4_1 *dce_info = NULL; | ||
| 1398 | struct atom_common_table_header *header; | ||
| 1399 | struct atom_data_revision revision; | ||
| 1400 | struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL; | ||
| 1401 | struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL; | ||
| 1402 | |||
| 1403 | if (!info) | ||
| 1404 | return BP_RESULT_BADINPUT; | ||
| 1405 | |||
| 1406 | firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2, | ||
| 1407 | DATA_TABLES(firmwareinfo)); | ||
| 1408 | |||
| 1409 | dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, | ||
| 1410 | DATA_TABLES(dce_info)); | ||
| 1411 | |||
| 1412 | if (!firmware_info || !dce_info) | ||
| 1413 | return BP_RESULT_BADBIOSTABLE; | ||
| 1414 | |||
| 1415 | memset(info, 0, sizeof(*info)); | ||
| 1416 | |||
| 1417 | header = GET_IMAGE(struct atom_common_table_header, | ||
| 1418 | DATA_TABLES(smu_info)); | ||
| 1419 | get_atom_data_table_revision(header, &revision); | ||
| 1420 | |||
| 1421 | if (revision.minor == 2) { | ||
| 1422 | /* Vega12 */ | ||
| 1423 | smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2, | ||
| 1424 | DATA_TABLES(smu_info)); | ||
| 1425 | |||
| 1426 | if (!smu_info_v3_2) | ||
| 1427 | return BP_RESULT_BADBIOSTABLE; | ||
| 1428 | |||
| 1429 | info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10; | ||
| 1430 | } else if (revision.minor == 3) { | ||
| 1431 | /* Vega20 */ | ||
| 1432 | smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3, | ||
| 1433 | DATA_TABLES(smu_info)); | ||
| 1434 | |||
| 1435 | if (!smu_info_v3_3) | ||
| 1436 | return BP_RESULT_BADBIOSTABLE; | ||
| 1437 | |||
| 1438 | info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10; | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | // We need to convert from 10KHz units into KHz units. | ||
| 1442 | info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; | ||
| 1443 | |||
| 1444 | /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */ | ||
| 1445 | info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10; | ||
| 1446 | /* Hardcode frequency if BIOS gives no DCE Ref Clk */ | ||
| 1447 | if (info->pll_info.crystal_frequency == 0) { | ||
| 1448 | if (revision.minor == 2) | ||
| 1449 | info->pll_info.crystal_frequency = 27000; | ||
| 1450 | else if (revision.minor == 3) | ||
| 1451 | info->pll_info.crystal_frequency = 100000; | ||
| 1452 | } | ||
| 1453 | /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/ | ||
| 1454 | info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10; | ||
| 1455 | info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10; | ||
| 1456 | |||
| 1457 | /* Get GPU PLL VCO Clock */ | ||
| 1458 | if (bp->cmd_tbl.get_smu_clock_info != NULL) { | ||
| 1459 | if (revision.minor == 2) | ||
| 1460 | info->smu_gpu_pll_output_freq = | ||
| 1461 | bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; | ||
| 1462 | else if (revision.minor == 3) | ||
| 1463 | info->smu_gpu_pll_output_freq = | ||
| 1464 | bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10; | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | return BP_RESULT_OK; | ||
| 1468 | } | ||
| 1469 | |||
| 1386 | static enum bp_result bios_parser_get_encoder_cap_info( | 1470 | static enum bp_result bios_parser_get_encoder_cap_info( |
| 1387 | struct dc_bios *dcb, | 1471 | struct dc_bios *dcb, |
| 1388 | struct graphics_object_id object_id, | 1472 | struct graphics_object_id object_id, |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index 49c2face1e7a..ae48d603ebd6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c | |||
| @@ -629,13 +629,14 @@ bool dal_ddc_service_query_ddc_data( | |||
| 629 | return ret; | 629 | return ret; |
| 630 | } | 630 | } |
| 631 | 631 | ||
| 632 | ssize_t dal_ddc_service_read_dpcd_data( | 632 | enum ddc_result dal_ddc_service_read_dpcd_data( |
| 633 | struct ddc_service *ddc, | 633 | struct ddc_service *ddc, |
| 634 | bool i2c, | 634 | bool i2c, |
| 635 | enum i2c_mot_mode mot, | 635 | enum i2c_mot_mode mot, |
| 636 | uint32_t address, | 636 | uint32_t address, |
| 637 | uint8_t *data, | 637 | uint8_t *data, |
| 638 | uint32_t len) | 638 | uint32_t len, |
| 639 | uint32_t *read) | ||
| 639 | { | 640 | { |
| 640 | struct aux_payload read_payload = { | 641 | struct aux_payload read_payload = { |
| 641 | .i2c_over_aux = i2c, | 642 | .i2c_over_aux = i2c, |
| @@ -652,6 +653,8 @@ ssize_t dal_ddc_service_read_dpcd_data( | |||
| 652 | .mot = mot | 653 | .mot = mot |
| 653 | }; | 654 | }; |
| 654 | 655 | ||
| 656 | *read = 0; | ||
| 657 | |||
| 655 | if (len > DEFAULT_AUX_MAX_DATA_SIZE) { | 658 | if (len > DEFAULT_AUX_MAX_DATA_SIZE) { |
| 656 | BREAK_TO_DEBUGGER(); | 659 | BREAK_TO_DEBUGGER(); |
| 657 | return DDC_RESULT_FAILED_INVALID_OPERATION; | 660 | return DDC_RESULT_FAILED_INVALID_OPERATION; |
| @@ -661,7 +664,8 @@ ssize_t dal_ddc_service_read_dpcd_data( | |||
| 661 | ddc->ctx->i2caux, | 664 | ddc->ctx->i2caux, |
| 662 | ddc->ddc_pin, | 665 | ddc->ddc_pin, |
| 663 | &command)) { | 666 | &command)) { |
| 664 | return (ssize_t)command.payloads->length; | 667 | *read = command.payloads->length; |
| 668 | return DDC_RESULT_SUCESSFULL; | ||
| 665 | } | 669 | } |
| 666 | 670 | ||
| 667 | return DDC_RESULT_FAILED_OPERATION; | 671 | return DDC_RESULT_FAILED_OPERATION; |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index ade5b8ee9c3c..132eef3826e2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c | |||
| @@ -66,8 +66,8 @@ struct dc_plane_state *dc_create_plane_state(struct dc *dc) | |||
| 66 | { | 66 | { |
| 67 | struct dc *core_dc = dc; | 67 | struct dc *core_dc = dc; |
| 68 | 68 | ||
| 69 | struct dc_plane_state *plane_state = kzalloc(sizeof(*plane_state), | 69 | struct dc_plane_state *plane_state = kvzalloc(sizeof(*plane_state), |
| 70 | GFP_KERNEL); | 70 | GFP_KERNEL); |
| 71 | 71 | ||
| 72 | if (NULL == plane_state) | 72 | if (NULL == plane_state) |
| 73 | return NULL; | 73 | return NULL; |
| @@ -120,7 +120,7 @@ static void dc_plane_state_free(struct kref *kref) | |||
| 120 | { | 120 | { |
| 121 | struct dc_plane_state *plane_state = container_of(kref, struct dc_plane_state, refcount); | 121 | struct dc_plane_state *plane_state = container_of(kref, struct dc_plane_state, refcount); |
| 122 | destruct(plane_state); | 122 | destruct(plane_state); |
| 123 | kfree(plane_state); | 123 | kvfree(plane_state); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | void dc_plane_state_release(struct dc_plane_state *plane_state) | 126 | void dc_plane_state_release(struct dc_plane_state *plane_state) |
| @@ -136,7 +136,7 @@ void dc_gamma_retain(struct dc_gamma *gamma) | |||
| 136 | static void dc_gamma_free(struct kref *kref) | 136 | static void dc_gamma_free(struct kref *kref) |
| 137 | { | 137 | { |
| 138 | struct dc_gamma *gamma = container_of(kref, struct dc_gamma, refcount); | 138 | struct dc_gamma *gamma = container_of(kref, struct dc_gamma, refcount); |
| 139 | kfree(gamma); | 139 | kvfree(gamma); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | void dc_gamma_release(struct dc_gamma **gamma) | 142 | void dc_gamma_release(struct dc_gamma **gamma) |
| @@ -147,7 +147,7 @@ void dc_gamma_release(struct dc_gamma **gamma) | |||
| 147 | 147 | ||
| 148 | struct dc_gamma *dc_create_gamma(void) | 148 | struct dc_gamma *dc_create_gamma(void) |
| 149 | { | 149 | { |
| 150 | struct dc_gamma *gamma = kzalloc(sizeof(*gamma), GFP_KERNEL); | 150 | struct dc_gamma *gamma = kvzalloc(sizeof(*gamma), GFP_KERNEL); |
| 151 | 151 | ||
| 152 | if (gamma == NULL) | 152 | if (gamma == NULL) |
| 153 | goto alloc_fail; | 153 | goto alloc_fail; |
| @@ -167,7 +167,7 @@ void dc_transfer_func_retain(struct dc_transfer_func *tf) | |||
| 167 | static void dc_transfer_func_free(struct kref *kref) | 167 | static void dc_transfer_func_free(struct kref *kref) |
| 168 | { | 168 | { |
| 169 | struct dc_transfer_func *tf = container_of(kref, struct dc_transfer_func, refcount); | 169 | struct dc_transfer_func *tf = container_of(kref, struct dc_transfer_func, refcount); |
| 170 | kfree(tf); | 170 | kvfree(tf); |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | void dc_transfer_func_release(struct dc_transfer_func *tf) | 173 | void dc_transfer_func_release(struct dc_transfer_func *tf) |
| @@ -177,7 +177,7 @@ void dc_transfer_func_release(struct dc_transfer_func *tf) | |||
| 177 | 177 | ||
| 178 | struct dc_transfer_func *dc_create_transfer_func(void) | 178 | struct dc_transfer_func *dc_create_transfer_func(void) |
| 179 | { | 179 | { |
| 180 | struct dc_transfer_func *tf = kzalloc(sizeof(*tf), GFP_KERNEL); | 180 | struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL); |
| 181 | 181 | ||
| 182 | if (tf == NULL) | 182 | if (tf == NULL) |
| 183 | goto alloc_fail; | 183 | goto alloc_fail; |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h index 090b7a8dd67b..30b3a08b91be 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h | |||
| @@ -102,13 +102,14 @@ bool dal_ddc_service_query_ddc_data( | |||
| 102 | uint8_t *read_buf, | 102 | uint8_t *read_buf, |
| 103 | uint32_t read_size); | 103 | uint32_t read_size); |
| 104 | 104 | ||
| 105 | ssize_t dal_ddc_service_read_dpcd_data( | 105 | enum ddc_result dal_ddc_service_read_dpcd_data( |
| 106 | struct ddc_service *ddc, | 106 | struct ddc_service *ddc, |
| 107 | bool i2c, | 107 | bool i2c, |
| 108 | enum i2c_mot_mode mot, | 108 | enum i2c_mot_mode mot, |
| 109 | uint32_t address, | 109 | uint32_t address, |
| 110 | uint8_t *data, | 110 | uint8_t *data, |
| 111 | uint32_t len); | 111 | uint32_t len, |
| 112 | uint32_t *read); | ||
| 112 | 113 | ||
| 113 | enum ddc_result dal_ddc_service_write_dpcd_data( | 114 | enum ddc_result dal_ddc_service_write_dpcd_data( |
| 114 | struct ddc_service *ddc, | 115 | struct ddc_service *ddc, |
diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index 9831cb5eaa7c..9b0a04f99ac8 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h | |||
| @@ -113,9 +113,14 @@ | |||
| 113 | 113 | ||
| 114 | #define AI_GREENLAND_P_A0 1 | 114 | #define AI_GREENLAND_P_A0 1 |
| 115 | #define AI_GREENLAND_P_A1 2 | 115 | #define AI_GREENLAND_P_A1 2 |
| 116 | #define AI_UNKNOWN 0xFF | ||
| 116 | 117 | ||
| 117 | #define ASICREV_IS_GREENLAND_M(eChipRev) (eChipRev < AI_UNKNOWN) | 118 | #define AI_VEGA12_P_A0 20 |
| 118 | #define ASICREV_IS_GREENLAND_P(eChipRev) (eChipRev < AI_UNKNOWN) | 119 | #define ASICREV_IS_GREENLAND_M(eChipRev) (eChipRev < AI_VEGA12_P_A0) |
| 120 | #define ASICREV_IS_GREENLAND_P(eChipRev) (eChipRev < AI_VEGA12_P_A0) | ||
| 121 | |||
| 122 | #define ASICREV_IS_VEGA12_P(eChipRev) ((eChipRev >= AI_VEGA12_P_A0) && (eChipRev < AI_UNKNOWN)) | ||
| 123 | #define ASICREV_IS_VEGA12_p(eChipRev) ((eChipRev >= AI_VEGA12_P_A0) && (eChipRev < AI_UNKNOWN)) | ||
| 119 | 124 | ||
| 120 | /* DCN1_0 */ | 125 | /* DCN1_0 */ |
| 121 | #define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */ | 126 | #define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */ |
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index e7e374f56864..b3747a019deb 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c | |||
| @@ -1093,19 +1093,19 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, | |||
| 1093 | 1093 | ||
| 1094 | output_tf->type = TF_TYPE_DISTRIBUTED_POINTS; | 1094 | output_tf->type = TF_TYPE_DISTRIBUTED_POINTS; |
| 1095 | 1095 | ||
| 1096 | rgb_user = kzalloc(sizeof(*rgb_user) * (ramp->num_entries + _EXTRA_POINTS), | 1096 | rgb_user = kvzalloc(sizeof(*rgb_user) * (ramp->num_entries + _EXTRA_POINTS), |
| 1097 | GFP_KERNEL); | 1097 | GFP_KERNEL); |
| 1098 | if (!rgb_user) | 1098 | if (!rgb_user) |
| 1099 | goto rgb_user_alloc_fail; | 1099 | goto rgb_user_alloc_fail; |
| 1100 | rgb_regamma = kzalloc(sizeof(*rgb_regamma) * (MAX_HW_POINTS + _EXTRA_POINTS), | 1100 | rgb_regamma = kvzalloc(sizeof(*rgb_regamma) * (MAX_HW_POINTS + _EXTRA_POINTS), |
| 1101 | GFP_KERNEL); | 1101 | GFP_KERNEL); |
| 1102 | if (!rgb_regamma) | 1102 | if (!rgb_regamma) |
| 1103 | goto rgb_regamma_alloc_fail; | 1103 | goto rgb_regamma_alloc_fail; |
| 1104 | axix_x = kzalloc(sizeof(*axix_x) * (ramp->num_entries + 3), | 1104 | axix_x = kvzalloc(sizeof(*axix_x) * (ramp->num_entries + 3), |
| 1105 | GFP_KERNEL); | 1105 | GFP_KERNEL); |
| 1106 | if (!axix_x) | 1106 | if (!axix_x) |
| 1107 | goto axix_x_alloc_fail; | 1107 | goto axix_x_alloc_fail; |
| 1108 | coeff = kzalloc(sizeof(*coeff) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL); | 1108 | coeff = kvzalloc(sizeof(*coeff) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL); |
| 1109 | if (!coeff) | 1109 | if (!coeff) |
| 1110 | goto coeff_alloc_fail; | 1110 | goto coeff_alloc_fail; |
| 1111 | 1111 | ||
| @@ -1157,13 +1157,13 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, | |||
| 1157 | 1157 | ||
| 1158 | ret = true; | 1158 | ret = true; |
| 1159 | 1159 | ||
| 1160 | kfree(coeff); | 1160 | kvfree(coeff); |
| 1161 | coeff_alloc_fail: | 1161 | coeff_alloc_fail: |
| 1162 | kfree(axix_x); | 1162 | kvfree(axix_x); |
| 1163 | axix_x_alloc_fail: | 1163 | axix_x_alloc_fail: |
| 1164 | kfree(rgb_regamma); | 1164 | kvfree(rgb_regamma); |
| 1165 | rgb_regamma_alloc_fail: | 1165 | rgb_regamma_alloc_fail: |
| 1166 | kfree(rgb_user); | 1166 | kvfree(rgb_user); |
| 1167 | rgb_user_alloc_fail: | 1167 | rgb_user_alloc_fail: |
| 1168 | return ret; | 1168 | return ret; |
| 1169 | } | 1169 | } |
| @@ -1192,19 +1192,19 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, | |||
| 1192 | 1192 | ||
| 1193 | input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; | 1193 | input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; |
| 1194 | 1194 | ||
| 1195 | rgb_user = kzalloc(sizeof(*rgb_user) * (ramp->num_entries + _EXTRA_POINTS), | 1195 | rgb_user = kvzalloc(sizeof(*rgb_user) * (ramp->num_entries + _EXTRA_POINTS), |
| 1196 | GFP_KERNEL); | 1196 | GFP_KERNEL); |
| 1197 | if (!rgb_user) | 1197 | if (!rgb_user) |
| 1198 | goto rgb_user_alloc_fail; | 1198 | goto rgb_user_alloc_fail; |
| 1199 | curve = kzalloc(sizeof(*curve) * (MAX_HW_POINTS + _EXTRA_POINTS), | 1199 | curve = kvzalloc(sizeof(*curve) * (MAX_HW_POINTS + _EXTRA_POINTS), |
| 1200 | GFP_KERNEL); | 1200 | GFP_KERNEL); |
| 1201 | if (!curve) | 1201 | if (!curve) |
| 1202 | goto curve_alloc_fail; | 1202 | goto curve_alloc_fail; |
| 1203 | axix_x = kzalloc(sizeof(*axix_x) * (ramp->num_entries + _EXTRA_POINTS), | 1203 | axix_x = kvzalloc(sizeof(*axix_x) * (ramp->num_entries + _EXTRA_POINTS), |
| 1204 | GFP_KERNEL); | 1204 | GFP_KERNEL); |
| 1205 | if (!axix_x) | 1205 | if (!axix_x) |
| 1206 | goto axix_x_alloc_fail; | 1206 | goto axix_x_alloc_fail; |
| 1207 | coeff = kzalloc(sizeof(*coeff) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL); | 1207 | coeff = kvzalloc(sizeof(*coeff) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL); |
| 1208 | if (!coeff) | 1208 | if (!coeff) |
| 1209 | goto coeff_alloc_fail; | 1209 | goto coeff_alloc_fail; |
| 1210 | 1210 | ||
| @@ -1246,13 +1246,13 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, | |||
| 1246 | 1246 | ||
| 1247 | ret = true; | 1247 | ret = true; |
| 1248 | 1248 | ||
| 1249 | kfree(coeff); | 1249 | kvfree(coeff); |
| 1250 | coeff_alloc_fail: | 1250 | coeff_alloc_fail: |
| 1251 | kfree(axix_x); | 1251 | kvfree(axix_x); |
| 1252 | axix_x_alloc_fail: | 1252 | axix_x_alloc_fail: |
| 1253 | kfree(curve); | 1253 | kvfree(curve); |
| 1254 | curve_alloc_fail: | 1254 | curve_alloc_fail: |
| 1255 | kfree(rgb_user); | 1255 | kvfree(rgb_user); |
| 1256 | rgb_user_alloc_fail: | 1256 | rgb_user_alloc_fail: |
| 1257 | 1257 | ||
| 1258 | return ret; | 1258 | return ret; |
| @@ -1281,8 +1281,9 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, | |||
| 1281 | } | 1281 | } |
| 1282 | ret = true; | 1282 | ret = true; |
| 1283 | } else if (trans == TRANSFER_FUNCTION_PQ) { | 1283 | } else if (trans == TRANSFER_FUNCTION_PQ) { |
| 1284 | rgb_regamma = kzalloc(sizeof(*rgb_regamma) * (MAX_HW_POINTS + | 1284 | rgb_regamma = kvzalloc(sizeof(*rgb_regamma) * |
| 1285 | _EXTRA_POINTS), GFP_KERNEL); | 1285 | (MAX_HW_POINTS + _EXTRA_POINTS), |
| 1286 | GFP_KERNEL); | ||
| 1286 | if (!rgb_regamma) | 1287 | if (!rgb_regamma) |
| 1287 | goto rgb_regamma_alloc_fail; | 1288 | goto rgb_regamma_alloc_fail; |
| 1288 | points->end_exponent = 7; | 1289 | points->end_exponent = 7; |
| @@ -1302,11 +1303,12 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, | |||
| 1302 | } | 1303 | } |
| 1303 | ret = true; | 1304 | ret = true; |
| 1304 | 1305 | ||
| 1305 | kfree(rgb_regamma); | 1306 | kvfree(rgb_regamma); |
| 1306 | } else if (trans == TRANSFER_FUNCTION_SRGB || | 1307 | } else if (trans == TRANSFER_FUNCTION_SRGB || |
| 1307 | trans == TRANSFER_FUNCTION_BT709) { | 1308 | trans == TRANSFER_FUNCTION_BT709) { |
| 1308 | rgb_regamma = kzalloc(sizeof(*rgb_regamma) * (MAX_HW_POINTS + | 1309 | rgb_regamma = kvzalloc(sizeof(*rgb_regamma) * |
| 1309 | _EXTRA_POINTS), GFP_KERNEL); | 1310 | (MAX_HW_POINTS + _EXTRA_POINTS), |
| 1311 | GFP_KERNEL); | ||
| 1310 | if (!rgb_regamma) | 1312 | if (!rgb_regamma) |
| 1311 | goto rgb_regamma_alloc_fail; | 1313 | goto rgb_regamma_alloc_fail; |
| 1312 | points->end_exponent = 0; | 1314 | points->end_exponent = 0; |
| @@ -1324,7 +1326,7 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, | |||
| 1324 | } | 1326 | } |
| 1325 | ret = true; | 1327 | ret = true; |
| 1326 | 1328 | ||
| 1327 | kfree(rgb_regamma); | 1329 | kvfree(rgb_regamma); |
| 1328 | } | 1330 | } |
| 1329 | rgb_regamma_alloc_fail: | 1331 | rgb_regamma_alloc_fail: |
| 1330 | return ret; | 1332 | return ret; |
| @@ -1348,8 +1350,9 @@ bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, | |||
| 1348 | } | 1350 | } |
| 1349 | ret = true; | 1351 | ret = true; |
| 1350 | } else if (trans == TRANSFER_FUNCTION_PQ) { | 1352 | } else if (trans == TRANSFER_FUNCTION_PQ) { |
| 1351 | rgb_degamma = kzalloc(sizeof(*rgb_degamma) * (MAX_HW_POINTS + | 1353 | rgb_degamma = kvzalloc(sizeof(*rgb_degamma) * |
| 1352 | _EXTRA_POINTS), GFP_KERNEL); | 1354 | (MAX_HW_POINTS + _EXTRA_POINTS), |
| 1355 | GFP_KERNEL); | ||
| 1353 | if (!rgb_degamma) | 1356 | if (!rgb_degamma) |
| 1354 | goto rgb_degamma_alloc_fail; | 1357 | goto rgb_degamma_alloc_fail; |
| 1355 | 1358 | ||
| @@ -1364,11 +1367,12 @@ bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, | |||
| 1364 | } | 1367 | } |
| 1365 | ret = true; | 1368 | ret = true; |
| 1366 | 1369 | ||
| 1367 | kfree(rgb_degamma); | 1370 | kvfree(rgb_degamma); |
| 1368 | } else if (trans == TRANSFER_FUNCTION_SRGB || | 1371 | } else if (trans == TRANSFER_FUNCTION_SRGB || |
| 1369 | trans == TRANSFER_FUNCTION_BT709) { | 1372 | trans == TRANSFER_FUNCTION_BT709) { |
| 1370 | rgb_degamma = kzalloc(sizeof(*rgb_degamma) * (MAX_HW_POINTS + | 1373 | rgb_degamma = kvzalloc(sizeof(*rgb_degamma) * |
| 1371 | _EXTRA_POINTS), GFP_KERNEL); | 1374 | (MAX_HW_POINTS + _EXTRA_POINTS), |
| 1375 | GFP_KERNEL); | ||
| 1372 | if (!rgb_degamma) | 1376 | if (!rgb_degamma) |
| 1373 | goto rgb_degamma_alloc_fail; | 1377 | goto rgb_degamma_alloc_fail; |
| 1374 | 1378 | ||
| @@ -1382,7 +1386,7 @@ bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, | |||
| 1382 | } | 1386 | } |
| 1383 | ret = true; | 1387 | ret = true; |
| 1384 | 1388 | ||
| 1385 | kfree(rgb_degamma); | 1389 | kvfree(rgb_degamma); |
| 1386 | } | 1390 | } |
| 1387 | points->end_exponent = 0; | 1391 | points->end_exponent = 0; |
| 1388 | points->x_point_at_y1_red = 1; | 1392 | points->x_point_at_y1_red = 1; |
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h index 0f5ad54d3fd3..de177ce8ca80 100644 --- a/drivers/gpu/drm/amd/include/atomfirmware.h +++ b/drivers/gpu/drm/amd/include/atomfirmware.h | |||
| @@ -501,6 +501,32 @@ enum atom_cooling_solution_id{ | |||
| 501 | LIQUID_COOLING = 0x01 | 501 | LIQUID_COOLING = 0x01 |
| 502 | }; | 502 | }; |
| 503 | 503 | ||
| 504 | struct atom_firmware_info_v3_2 { | ||
| 505 | struct atom_common_table_header table_header; | ||
| 506 | uint32_t firmware_revision; | ||
| 507 | uint32_t bootup_sclk_in10khz; | ||
| 508 | uint32_t bootup_mclk_in10khz; | ||
| 509 | uint32_t firmware_capability; // enum atombios_firmware_capability | ||
| 510 | uint32_t main_call_parser_entry; /* direct address of main parser call in VBIOS binary. */ | ||
| 511 | uint32_t bios_scratch_reg_startaddr; // 1st bios scratch register dword address | ||
| 512 | uint16_t bootup_vddc_mv; | ||
| 513 | uint16_t bootup_vddci_mv; | ||
| 514 | uint16_t bootup_mvddc_mv; | ||
| 515 | uint16_t bootup_vddgfx_mv; | ||
| 516 | uint8_t mem_module_id; | ||
| 517 | uint8_t coolingsolution_id; /*0: Air cooling; 1: Liquid cooling ... */ | ||
| 518 | uint8_t reserved1[2]; | ||
| 519 | uint32_t mc_baseaddr_high; | ||
| 520 | uint32_t mc_baseaddr_low; | ||
| 521 | uint8_t board_i2c_feature_id; // enum of atom_board_i2c_feature_id_def | ||
| 522 | uint8_t board_i2c_feature_gpio_id; // i2c id find in gpio_lut data table gpio_id | ||
| 523 | uint8_t board_i2c_feature_slave_addr; | ||
| 524 | uint8_t reserved3; | ||
| 525 | uint16_t bootup_mvddq_mv; | ||
| 526 | uint16_t bootup_mvpp_mv; | ||
| 527 | uint32_t zfbstartaddrin16mb; | ||
| 528 | uint32_t reserved2[3]; | ||
| 529 | }; | ||
| 504 | 530 | ||
| 505 | /* | 531 | /* |
| 506 | *************************************************************************** | 532 | *************************************************************************** |
| @@ -1169,7 +1195,29 @@ struct atom_gfx_info_v2_2 | |||
| 1169 | uint32_t rlc_gpu_timer_refclk; | 1195 | uint32_t rlc_gpu_timer_refclk; |
| 1170 | }; | 1196 | }; |
| 1171 | 1197 | ||
| 1172 | 1198 | struct atom_gfx_info_v2_3 { | |
| 1199 | struct atom_common_table_header table_header; | ||
| 1200 | uint8_t gfxip_min_ver; | ||
| 1201 | uint8_t gfxip_max_ver; | ||
| 1202 | uint8_t max_shader_engines; | ||
| 1203 | uint8_t max_tile_pipes; | ||
| 1204 | uint8_t max_cu_per_sh; | ||
| 1205 | uint8_t max_sh_per_se; | ||
| 1206 | uint8_t max_backends_per_se; | ||
| 1207 | uint8_t max_texture_channel_caches; | ||
| 1208 | uint32_t regaddr_cp_dma_src_addr; | ||
| 1209 | uint32_t regaddr_cp_dma_src_addr_hi; | ||
| 1210 | uint32_t regaddr_cp_dma_dst_addr; | ||
| 1211 | uint32_t regaddr_cp_dma_dst_addr_hi; | ||
| 1212 | uint32_t regaddr_cp_dma_command; | ||
| 1213 | uint32_t regaddr_cp_status; | ||
| 1214 | uint32_t regaddr_rlc_gpu_clock_32; | ||
| 1215 | uint32_t rlc_gpu_timer_refclk; | ||
| 1216 | uint8_t active_cu_per_sh; | ||
| 1217 | uint8_t active_rb_per_se; | ||
| 1218 | uint16_t gcgoldenoffset; | ||
| 1219 | uint32_t rm21_sram_vmin_value; | ||
| 1220 | }; | ||
| 1173 | 1221 | ||
| 1174 | /* | 1222 | /* |
| 1175 | *************************************************************************** | 1223 | *************************************************************************** |
| @@ -1198,6 +1246,76 @@ struct atom_smu_info_v3_1 | |||
| 1198 | uint8_t fw_ctf_polarity; // GPIO polarity for CTF | 1246 | uint8_t fw_ctf_polarity; // GPIO polarity for CTF |
| 1199 | }; | 1247 | }; |
| 1200 | 1248 | ||
| 1249 | struct atom_smu_info_v3_2 { | ||
| 1250 | struct atom_common_table_header table_header; | ||
| 1251 | uint8_t smuip_min_ver; | ||
| 1252 | uint8_t smuip_max_ver; | ||
| 1253 | uint8_t smu_rsd1; | ||
| 1254 | uint8_t gpuclk_ss_mode; | ||
| 1255 | uint16_t sclk_ss_percentage; | ||
| 1256 | uint16_t sclk_ss_rate_10hz; | ||
| 1257 | uint16_t gpuclk_ss_percentage; // in unit of 0.001% | ||
| 1258 | uint16_t gpuclk_ss_rate_10hz; | ||
| 1259 | uint32_t core_refclk_10khz; | ||
| 1260 | uint8_t ac_dc_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for AC/DC switching, =0xff means invalid | ||
| 1261 | uint8_t ac_dc_polarity; // GPIO polarity for AC/DC switching | ||
| 1262 | uint8_t vr0hot_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for VR0 HOT event, =0xff means invalid | ||
| 1263 | uint8_t vr0hot_polarity; // GPIO polarity for VR0 HOT event | ||
| 1264 | uint8_t vr1hot_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for VR1 HOT event , =0xff means invalid | ||
| 1265 | uint8_t vr1hot_polarity; // GPIO polarity for VR1 HOT event | ||
| 1266 | uint8_t fw_ctf_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for CTF, =0xff means invalid | ||
| 1267 | uint8_t fw_ctf_polarity; // GPIO polarity for CTF | ||
| 1268 | uint8_t pcc_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for PCC, =0xff means invalid | ||
| 1269 | uint8_t pcc_gpio_polarity; // GPIO polarity for CTF | ||
| 1270 | uint16_t smugoldenoffset; | ||
| 1271 | uint32_t gpupll_vco_freq_10khz; | ||
| 1272 | uint32_t bootup_smnclk_10khz; | ||
| 1273 | uint32_t bootup_socclk_10khz; | ||
| 1274 | uint32_t bootup_mp0clk_10khz; | ||
| 1275 | uint32_t bootup_mp1clk_10khz; | ||
| 1276 | uint32_t bootup_lclk_10khz; | ||
| 1277 | uint32_t bootup_dcefclk_10khz; | ||
| 1278 | uint32_t ctf_threshold_override_value; | ||
| 1279 | uint32_t reserved[5]; | ||
| 1280 | }; | ||
| 1281 | |||
| 1282 | struct atom_smu_info_v3_3 { | ||
| 1283 | struct atom_common_table_header table_header; | ||
| 1284 | uint8_t smuip_min_ver; | ||
| 1285 | uint8_t smuip_max_ver; | ||
| 1286 | uint8_t smu_rsd1; | ||
| 1287 | uint8_t gpuclk_ss_mode; | ||
| 1288 | uint16_t sclk_ss_percentage; | ||
| 1289 | uint16_t sclk_ss_rate_10hz; | ||
| 1290 | uint16_t gpuclk_ss_percentage; // in unit of 0.001% | ||
| 1291 | uint16_t gpuclk_ss_rate_10hz; | ||
| 1292 | uint32_t core_refclk_10khz; | ||
| 1293 | uint8_t ac_dc_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for AC/DC switching, =0xff means invalid | ||
| 1294 | uint8_t ac_dc_polarity; // GPIO polarity for AC/DC switching | ||
| 1295 | uint8_t vr0hot_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for VR0 HOT event, =0xff means invalid | ||
| 1296 | uint8_t vr0hot_polarity; // GPIO polarity for VR0 HOT event | ||
| 1297 | uint8_t vr1hot_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for VR1 HOT event , =0xff means invalid | ||
| 1298 | uint8_t vr1hot_polarity; // GPIO polarity for VR1 HOT event | ||
| 1299 | uint8_t fw_ctf_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for CTF, =0xff means invalid | ||
| 1300 | uint8_t fw_ctf_polarity; // GPIO polarity for CTF | ||
| 1301 | uint8_t pcc_gpio_bit; // GPIO bit shift in SMU_GPIOPAD_A configured for PCC, =0xff means invalid | ||
| 1302 | uint8_t pcc_gpio_polarity; // GPIO polarity for CTF | ||
| 1303 | uint16_t smugoldenoffset; | ||
| 1304 | uint32_t gpupll_vco_freq_10khz; | ||
| 1305 | uint32_t bootup_smnclk_10khz; | ||
| 1306 | uint32_t bootup_socclk_10khz; | ||
| 1307 | uint32_t bootup_mp0clk_10khz; | ||
| 1308 | uint32_t bootup_mp1clk_10khz; | ||
| 1309 | uint32_t bootup_lclk_10khz; | ||
| 1310 | uint32_t bootup_dcefclk_10khz; | ||
| 1311 | uint32_t ctf_threshold_override_value; | ||
| 1312 | uint32_t syspll3_0_vco_freq_10khz; | ||
| 1313 | uint32_t syspll3_1_vco_freq_10khz; | ||
| 1314 | uint32_t bootup_fclk_10khz; | ||
| 1315 | uint32_t bootup_waflclk_10khz; | ||
| 1316 | uint32_t reserved[3]; | ||
| 1317 | }; | ||
| 1318 | |||
| 1201 | /* | 1319 | /* |
| 1202 | *************************************************************************** | 1320 | *************************************************************************** |
| 1203 | Data Table smc_dpm_info structure | 1321 | Data Table smc_dpm_info structure |
| @@ -1283,7 +1401,6 @@ struct atom_smc_dpm_info_v4_1 | |||
| 1283 | uint32_t boardreserved[10]; | 1401 | uint32_t boardreserved[10]; |
| 1284 | }; | 1402 | }; |
| 1285 | 1403 | ||
| 1286 | |||
| 1287 | /* | 1404 | /* |
| 1288 | *************************************************************************** | 1405 | *************************************************************************** |
| 1289 | Data Table asic_profiling_info structure | 1406 | Data Table asic_profiling_info structure |
| @@ -1864,6 +1981,55 @@ enum atom_smu9_syspll0_clock_id | |||
| 1864 | SMU9_SYSPLL0_DISPCLK_ID = 11, // DISPCLK | 1981 | SMU9_SYSPLL0_DISPCLK_ID = 11, // DISPCLK |
| 1865 | }; | 1982 | }; |
| 1866 | 1983 | ||
| 1984 | enum atom_smu11_syspll_id { | ||
| 1985 | SMU11_SYSPLL0_ID = 0, | ||
| 1986 | SMU11_SYSPLL1_0_ID = 1, | ||
| 1987 | SMU11_SYSPLL1_1_ID = 2, | ||
| 1988 | SMU11_SYSPLL1_2_ID = 3, | ||
| 1989 | SMU11_SYSPLL2_ID = 4, | ||
| 1990 | SMU11_SYSPLL3_0_ID = 5, | ||
| 1991 | SMU11_SYSPLL3_1_ID = 6, | ||
| 1992 | }; | ||
| 1993 | |||
| 1994 | |||
| 1995 | enum atom_smu11_syspll0_clock_id { | ||
| 1996 | SMU11_SYSPLL0_SOCCLK_ID = 0, // SOCCLK | ||
| 1997 | SMU11_SYSPLL0_MP0CLK_ID = 1, // MP0CLK | ||
| 1998 | SMU11_SYSPLL0_DCLK_ID = 2, // DCLK | ||
| 1999 | SMU11_SYSPLL0_VCLK_ID = 3, // VCLK | ||
| 2000 | SMU11_SYSPLL0_ECLK_ID = 4, // ECLK | ||
| 2001 | SMU11_SYSPLL0_DCEFCLK_ID = 5, // DCEFCLK | ||
| 2002 | }; | ||
| 2003 | |||
| 2004 | |||
| 2005 | enum atom_smu11_syspll1_0_clock_id { | ||
| 2006 | SMU11_SYSPLL1_0_UCLKA_ID = 0, // UCLK_a | ||
| 2007 | }; | ||
| 2008 | |||
| 2009 | enum atom_smu11_syspll1_1_clock_id { | ||
| 2010 | SMU11_SYSPLL1_0_UCLKB_ID = 0, // UCLK_b | ||
| 2011 | }; | ||
| 2012 | |||
| 2013 | enum atom_smu11_syspll1_2_clock_id { | ||
| 2014 | SMU11_SYSPLL1_0_FCLK_ID = 0, // FCLK | ||
| 2015 | }; | ||
| 2016 | |||
| 2017 | enum atom_smu11_syspll2_clock_id { | ||
| 2018 | SMU11_SYSPLL2_GFXCLK_ID = 0, // GFXCLK | ||
| 2019 | }; | ||
| 2020 | |||
| 2021 | enum atom_smu11_syspll3_0_clock_id { | ||
| 2022 | SMU11_SYSPLL3_0_WAFCLK_ID = 0, // WAFCLK | ||
| 2023 | SMU11_SYSPLL3_0_DISPCLK_ID = 1, // DISPCLK | ||
| 2024 | SMU11_SYSPLL3_0_DPREFCLK_ID = 2, // DPREFCLK | ||
| 2025 | }; | ||
| 2026 | |||
| 2027 | enum atom_smu11_syspll3_1_clock_id { | ||
| 2028 | SMU11_SYSPLL3_1_MP1CLK_ID = 0, // MP1CLK | ||
| 2029 | SMU11_SYSPLL3_1_SMNCLK_ID = 1, // SMNCLK | ||
| 2030 | SMU11_SYSPLL3_1_LCLK_ID = 2, // LCLK | ||
| 2031 | }; | ||
| 2032 | |||
| 1867 | struct atom_get_smu_clock_info_output_parameters_v3_1 | 2033 | struct atom_get_smu_clock_info_output_parameters_v3_1 |
| 1868 | { | 2034 | { |
| 1869 | union { | 2035 | union { |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 26fbeafc3c96..18b5b2ff47fe 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | |||
| @@ -79,12 +79,13 @@ | |||
| 79 | #define PCIE_BUS_CLK 10000 | 79 | #define PCIE_BUS_CLK 10000 |
| 80 | #define TCLK (PCIE_BUS_CLK / 10) | 80 | #define TCLK (PCIE_BUS_CLK / 10) |
| 81 | 81 | ||
| 82 | static const struct profile_mode_setting smu7_profiling[5] = | 82 | static const struct profile_mode_setting smu7_profiling[6] = |
| 83 | {{1, 0, 100, 30, 1, 0, 100, 10}, | 83 | {{1, 0, 100, 30, 1, 0, 100, 10}, |
| 84 | {1, 10, 0, 30, 0, 0, 0, 0}, | 84 | {1, 10, 0, 30, 0, 0, 0, 0}, |
| 85 | {0, 0, 0, 0, 1, 10, 16, 31}, | 85 | {0, 0, 0, 0, 1, 10, 16, 31}, |
| 86 | {1, 0, 11, 50, 1, 0, 100, 10}, | 86 | {1, 0, 11, 50, 1, 0, 100, 10}, |
| 87 | {1, 0, 5, 30, 0, 0, 0, 0}, | 87 | {1, 0, 5, 30, 0, 0, 0, 0}, |
| 88 | {0, 0, 0, 0, 0, 0, 0, 0}, | ||
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| 90 | /** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */ | 91 | /** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */ |
| @@ -4864,6 +4865,17 @@ static int smu7_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) | |||
| 4864 | len = sizeof(smu7_profiling) / sizeof(struct profile_mode_setting); | 4865 | len = sizeof(smu7_profiling) / sizeof(struct profile_mode_setting); |
| 4865 | 4866 | ||
| 4866 | for (i = 0; i < len; i++) { | 4867 | for (i = 0; i < len; i++) { |
| 4868 | if (i == hwmgr->power_profile_mode) { | ||
| 4869 | size += sprintf(buf + size, "%3d %14s %s: %8d %16d %16d %16d %16d %16d\n", | ||
| 4870 | i, profile_name[i], "*", | ||
| 4871 | data->current_profile_setting.sclk_up_hyst, | ||
| 4872 | data->current_profile_setting.sclk_down_hyst, | ||
| 4873 | data->current_profile_setting.sclk_activity, | ||
| 4874 | data->current_profile_setting.mclk_up_hyst, | ||
| 4875 | data->current_profile_setting.mclk_down_hyst, | ||
| 4876 | data->current_profile_setting.mclk_activity); | ||
| 4877 | continue; | ||
| 4878 | } | ||
| 4867 | if (smu7_profiling[i].bupdate_sclk) | 4879 | if (smu7_profiling[i].bupdate_sclk) |
| 4868 | size += sprintf(buf + size, "%3d %16s: %8d %16d %16d ", | 4880 | size += sprintf(buf + size, "%3d %16s: %8d %16d %16d ", |
| 4869 | i, profile_name[i], smu7_profiling[i].sclk_up_hyst, | 4881 | i, profile_name[i], smu7_profiling[i].sclk_up_hyst, |
| @@ -4883,24 +4895,6 @@ static int smu7_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) | |||
| 4883 | "-", "-", "-"); | 4895 | "-", "-", "-"); |
| 4884 | } | 4896 | } |
| 4885 | 4897 | ||
| 4886 | size += sprintf(buf + size, "%3d %16s: %8d %16d %16d %16d %16d %16d\n", | ||
| 4887 | i, profile_name[i], | ||
| 4888 | data->custom_profile_setting.sclk_up_hyst, | ||
| 4889 | data->custom_profile_setting.sclk_down_hyst, | ||
| 4890 | data->custom_profile_setting.sclk_activity, | ||
| 4891 | data->custom_profile_setting.mclk_up_hyst, | ||
| 4892 | data->custom_profile_setting.mclk_down_hyst, | ||
| 4893 | data->custom_profile_setting.mclk_activity); | ||
| 4894 | |||
| 4895 | size += sprintf(buf + size, "%3s %16s: %8d %16d %16d %16d %16d %16d\n", | ||
| 4896 | "*", "CURRENT", | ||
| 4897 | data->current_profile_setting.sclk_up_hyst, | ||
| 4898 | data->current_profile_setting.sclk_down_hyst, | ||
| 4899 | data->current_profile_setting.sclk_activity, | ||
| 4900 | data->current_profile_setting.mclk_up_hyst, | ||
| 4901 | data->current_profile_setting.mclk_down_hyst, | ||
| 4902 | data->current_profile_setting.mclk_activity); | ||
| 4903 | |||
| 4904 | return size; | 4898 | return size; |
| 4905 | } | 4899 | } |
| 4906 | 4900 | ||
| @@ -4939,16 +4933,16 @@ static int smu7_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint | |||
| 4939 | if (size < 8) | 4933 | if (size < 8) |
| 4940 | return -EINVAL; | 4934 | return -EINVAL; |
| 4941 | 4935 | ||
| 4942 | data->custom_profile_setting.bupdate_sclk = input[0]; | 4936 | tmp.bupdate_sclk = input[0]; |
| 4943 | data->custom_profile_setting.sclk_up_hyst = input[1]; | 4937 | tmp.sclk_up_hyst = input[1]; |
| 4944 | data->custom_profile_setting.sclk_down_hyst = input[2]; | 4938 | tmp.sclk_down_hyst = input[2]; |
| 4945 | data->custom_profile_setting.sclk_activity = input[3]; | 4939 | tmp.sclk_activity = input[3]; |
| 4946 | data->custom_profile_setting.bupdate_mclk = input[4]; | 4940 | tmp.bupdate_mclk = input[4]; |
| 4947 | data->custom_profile_setting.mclk_up_hyst = input[5]; | 4941 | tmp.mclk_up_hyst = input[5]; |
| 4948 | data->custom_profile_setting.mclk_down_hyst = input[6]; | 4942 | tmp.mclk_down_hyst = input[6]; |
| 4949 | data->custom_profile_setting.mclk_activity = input[7]; | 4943 | tmp.mclk_activity = input[7]; |
| 4950 | if (!smum_update_dpm_settings(hwmgr, &data->custom_profile_setting)) { | 4944 | if (!smum_update_dpm_settings(hwmgr, &tmp)) { |
| 4951 | memcpy(&data->current_profile_setting, &data->custom_profile_setting, sizeof(struct profile_mode_setting)); | 4945 | memcpy(&data->current_profile_setting, &tmp, sizeof(struct profile_mode_setting)); |
| 4952 | hwmgr->power_profile_mode = mode; | 4946 | hwmgr->power_profile_mode = mode; |
| 4953 | } | 4947 | } |
| 4954 | break; | 4948 | break; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h index f40179c9ca97..b8d0bb378595 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h | |||
| @@ -325,7 +325,6 @@ struct smu7_hwmgr { | |||
| 325 | uint16_t mem_latency_high; | 325 | uint16_t mem_latency_high; |
| 326 | uint16_t mem_latency_low; | 326 | uint16_t mem_latency_low; |
| 327 | uint32_t vr_config; | 327 | uint32_t vr_config; |
| 328 | struct profile_mode_setting custom_profile_setting; | ||
| 329 | struct profile_mode_setting current_profile_setting; | 328 | struct profile_mode_setting current_profile_setting; |
| 330 | }; | 329 | }; |
| 331 | 330 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c index 03bc7453f3b1..d9e92e306535 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c | |||
| @@ -852,12 +852,10 @@ int smu7_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n) | |||
| 852 | { | 852 | { |
| 853 | struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); | 853 | struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); |
| 854 | 854 | ||
| 855 | n = (n & 0xff) << 8; | ||
| 856 | |||
| 857 | if (data->power_containment_features & | 855 | if (data->power_containment_features & |
| 858 | POWERCONTAINMENT_FEATURE_PkgPwrLimit) | 856 | POWERCONTAINMENT_FEATURE_PkgPwrLimit) |
| 859 | return smum_send_msg_to_smc_with_parameter(hwmgr, | 857 | return smum_send_msg_to_smc_with_parameter(hwmgr, |
| 860 | PPSMC_MSG_PkgPwrSetLimit, n); | 858 | PPSMC_MSG_PkgPwrSetLimit, n<<8); |
| 861 | return 0; | 859 | return 0; |
| 862 | } | 860 | } |
| 863 | 861 | ||
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 3aa65bdecb0e..684ac626ac53 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig | |||
| @@ -74,6 +74,7 @@ config DRM_SIL_SII8620 | |||
| 74 | tristate "Silicon Image SII8620 HDMI/MHL bridge" | 74 | tristate "Silicon Image SII8620 HDMI/MHL bridge" |
| 75 | depends on OF && RC_CORE | 75 | depends on OF && RC_CORE |
| 76 | select DRM_KMS_HELPER | 76 | select DRM_KMS_HELPER |
| 77 | imply EXTCON | ||
| 77 | help | 78 | help |
| 78 | Silicon Image SII8620 HDMI/MHL bridge chip driver. | 79 | Silicon Image SII8620 HDMI/MHL bridge chip driver. |
| 79 | 80 | ||
diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c index 498d5948d1a8..9837c8d69e69 100644 --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c | |||
| @@ -56,7 +56,9 @@ static int dumb_vga_get_modes(struct drm_connector *connector) | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | drm_mode_connector_update_edid_property(connector, edid); | 58 | drm_mode_connector_update_edid_property(connector, edid); |
| 59 | return drm_add_edid_modes(connector, edid); | 59 | ret = drm_add_edid_modes(connector, edid); |
| 60 | kfree(edid); | ||
| 61 | return ret; | ||
| 60 | 62 | ||
| 61 | fallback: | 63 | fallback: |
| 62 | /* | 64 | /* |
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 7d25c42f22db..c825c76edc1d 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
| @@ -155,6 +155,8 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) | |||
| 155 | state->connectors[i].state); | 155 | state->connectors[i].state); |
| 156 | state->connectors[i].ptr = NULL; | 156 | state->connectors[i].ptr = NULL; |
| 157 | state->connectors[i].state = NULL; | 157 | state->connectors[i].state = NULL; |
| 158 | state->connectors[i].old_state = NULL; | ||
| 159 | state->connectors[i].new_state = NULL; | ||
| 158 | drm_connector_put(connector); | 160 | drm_connector_put(connector); |
| 159 | } | 161 | } |
| 160 | 162 | ||
| @@ -169,6 +171,8 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) | |||
| 169 | 171 | ||
| 170 | state->crtcs[i].ptr = NULL; | 172 | state->crtcs[i].ptr = NULL; |
| 171 | state->crtcs[i].state = NULL; | 173 | state->crtcs[i].state = NULL; |
| 174 | state->crtcs[i].old_state = NULL; | ||
| 175 | state->crtcs[i].new_state = NULL; | ||
| 172 | } | 176 | } |
| 173 | 177 | ||
| 174 | for (i = 0; i < config->num_total_plane; i++) { | 178 | for (i = 0; i < config->num_total_plane; i++) { |
| @@ -181,6 +185,8 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) | |||
| 181 | state->planes[i].state); | 185 | state->planes[i].state); |
| 182 | state->planes[i].ptr = NULL; | 186 | state->planes[i].ptr = NULL; |
| 183 | state->planes[i].state = NULL; | 187 | state->planes[i].state = NULL; |
| 188 | state->planes[i].old_state = NULL; | ||
| 189 | state->planes[i].new_state = NULL; | ||
| 184 | } | 190 | } |
| 185 | 191 | ||
| 186 | for (i = 0; i < state->num_private_objs; i++) { | 192 | for (i = 0; i < state->num_private_objs; i++) { |
| @@ -190,6 +196,8 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) | |||
| 190 | state->private_objs[i].state); | 196 | state->private_objs[i].state); |
| 191 | state->private_objs[i].ptr = NULL; | 197 | state->private_objs[i].ptr = NULL; |
| 192 | state->private_objs[i].state = NULL; | 198 | state->private_objs[i].state = NULL; |
| 199 | state->private_objs[i].old_state = NULL; | ||
| 200 | state->private_objs[i].new_state = NULL; | ||
| 193 | } | 201 | } |
| 194 | state->num_private_objs = 0; | 202 | state->num_private_objs = 0; |
| 195 | 203 | ||
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index a1b9338736e3..c2c21d839727 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
| @@ -716,7 +716,7 @@ static void remove_compat_control_link(struct drm_device *dev) | |||
| 716 | if (!minor) | 716 | if (!minor) |
| 717 | return; | 717 | return; |
| 718 | 718 | ||
| 719 | name = kasprintf(GFP_KERNEL, "controlD%d", minor->index); | 719 | name = kasprintf(GFP_KERNEL, "controlD%d", minor->index + 64); |
| 720 | if (!name) | 720 | if (!name) |
| 721 | return; | 721 | return; |
| 722 | 722 | ||
diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c index 39ac15ce4702..9e2ae02f31e0 100644 --- a/drivers/gpu/drm/drm_dumb_buffers.c +++ b/drivers/gpu/drm/drm_dumb_buffers.c | |||
| @@ -65,12 +65,13 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, | |||
| 65 | return -EINVAL; | 65 | return -EINVAL; |
| 66 | 66 | ||
| 67 | /* overflow checks for 32bit size calculations */ | 67 | /* overflow checks for 32bit size calculations */ |
| 68 | /* NOTE: DIV_ROUND_UP() can overflow */ | 68 | if (args->bpp > U32_MAX - 8) |
| 69 | return -EINVAL; | ||
| 69 | cpp = DIV_ROUND_UP(args->bpp, 8); | 70 | cpp = DIV_ROUND_UP(args->bpp, 8); |
| 70 | if (!cpp || cpp > 0xffffffffU / args->width) | 71 | if (cpp > U32_MAX / args->width) |
| 71 | return -EINVAL; | 72 | return -EINVAL; |
| 72 | stride = cpp * args->width; | 73 | stride = cpp * args->width; |
| 73 | if (args->height > 0xffffffffU / stride) | 74 | if (args->height > U32_MAX / stride) |
| 74 | return -EINVAL; | 75 | return -EINVAL; |
| 75 | 76 | ||
| 76 | /* test for wrap-around */ | 77 | /* test for wrap-around */ |
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index e394799979a6..6d9b9453707c 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c | |||
| @@ -212,6 +212,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) | |||
| 212 | return -ENOMEM; | 212 | return -ENOMEM; |
| 213 | 213 | ||
| 214 | filp->private_data = priv; | 214 | filp->private_data = priv; |
| 215 | filp->f_mode |= FMODE_UNSIGNED_OFFSET; | ||
| 215 | priv->filp = filp; | 216 | priv->filp = filp; |
| 216 | priv->pid = get_pid(task_pid(current)); | 217 | priv->pid = get_pid(task_pid(current)); |
| 217 | priv->minor = minor; | 218 | priv->minor = minor; |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index abd84cbcf1c2..09c4bc0b1859 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -954,8 +954,6 @@ static int hdmi_create_connector(struct drm_encoder *encoder) | |||
| 954 | drm_mode_connector_attach_encoder(connector, encoder); | 954 | drm_mode_connector_attach_encoder(connector, encoder); |
| 955 | 955 | ||
| 956 | if (hdata->bridge) { | 956 | if (hdata->bridge) { |
| 957 | encoder->bridge = hdata->bridge; | ||
| 958 | hdata->bridge->encoder = encoder; | ||
| 959 | ret = drm_bridge_attach(encoder, hdata->bridge, NULL); | 957 | ret = drm_bridge_attach(encoder, hdata->bridge, NULL); |
| 960 | if (ret) | 958 | if (ret) |
| 961 | DRM_ERROR("Failed to attach bridge\n"); | 959 | DRM_ERROR("Failed to attach bridge\n"); |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 257299ec95c4..272c79f5f5bf 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
| @@ -473,7 +473,7 @@ static void vp_video_buffer(struct mixer_context *ctx, | |||
| 473 | chroma_addr[1] = chroma_addr[0] + 0x40; | 473 | chroma_addr[1] = chroma_addr[0] + 0x40; |
| 474 | } else { | 474 | } else { |
| 475 | luma_addr[1] = luma_addr[0] + fb->pitches[0]; | 475 | luma_addr[1] = luma_addr[0] + fb->pitches[0]; |
| 476 | chroma_addr[1] = chroma_addr[0] + fb->pitches[0]; | 476 | chroma_addr[1] = chroma_addr[0] + fb->pitches[1]; |
| 477 | } | 477 | } |
| 478 | } else { | 478 | } else { |
| 479 | luma_addr[1] = 0; | 479 | luma_addr[1] = 0; |
| @@ -482,6 +482,7 @@ static void vp_video_buffer(struct mixer_context *ctx, | |||
| 482 | 482 | ||
| 483 | spin_lock_irqsave(&ctx->reg_slock, flags); | 483 | spin_lock_irqsave(&ctx->reg_slock, flags); |
| 484 | 484 | ||
| 485 | vp_reg_write(ctx, VP_SHADOW_UPDATE, 1); | ||
| 485 | /* interlace or progressive scan mode */ | 486 | /* interlace or progressive scan mode */ |
| 486 | val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0); | 487 | val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0); |
| 487 | vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP); | 488 | vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP); |
| @@ -495,21 +496,23 @@ static void vp_video_buffer(struct mixer_context *ctx, | |||
| 495 | vp_reg_write(ctx, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) | | 496 | vp_reg_write(ctx, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) | |
| 496 | VP_IMG_VSIZE(fb->height)); | 497 | VP_IMG_VSIZE(fb->height)); |
| 497 | /* chroma plane for NV12/NV21 is half the height of the luma plane */ | 498 | /* chroma plane for NV12/NV21 is half the height of the luma plane */ |
| 498 | vp_reg_write(ctx, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) | | 499 | vp_reg_write(ctx, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[1]) | |
| 499 | VP_IMG_VSIZE(fb->height / 2)); | 500 | VP_IMG_VSIZE(fb->height / 2)); |
| 500 | 501 | ||
| 501 | vp_reg_write(ctx, VP_SRC_WIDTH, state->src.w); | 502 | vp_reg_write(ctx, VP_SRC_WIDTH, state->src.w); |
| 502 | vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h); | ||
| 503 | vp_reg_write(ctx, VP_SRC_H_POSITION, | 503 | vp_reg_write(ctx, VP_SRC_H_POSITION, |
| 504 | VP_SRC_H_POSITION_VAL(state->src.x)); | 504 | VP_SRC_H_POSITION_VAL(state->src.x)); |
| 505 | vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y); | ||
| 506 | |||
| 507 | vp_reg_write(ctx, VP_DST_WIDTH, state->crtc.w); | 505 | vp_reg_write(ctx, VP_DST_WIDTH, state->crtc.w); |
| 508 | vp_reg_write(ctx, VP_DST_H_POSITION, state->crtc.x); | 506 | vp_reg_write(ctx, VP_DST_H_POSITION, state->crtc.x); |
| 507 | |||
| 509 | if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { | 508 | if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { |
| 509 | vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h / 2); | ||
| 510 | vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y / 2); | ||
| 510 | vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h / 2); | 511 | vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h / 2); |
| 511 | vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y / 2); | 512 | vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y / 2); |
| 512 | } else { | 513 | } else { |
| 514 | vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h); | ||
| 515 | vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y); | ||
| 513 | vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h); | 516 | vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h); |
| 514 | vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y); | 517 | vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y); |
| 515 | } | 518 | } |
| @@ -699,6 +702,15 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) | |||
| 699 | 702 | ||
| 700 | /* interlace scan need to check shadow register */ | 703 | /* interlace scan need to check shadow register */ |
| 701 | if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { | 704 | if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { |
| 705 | if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags) && | ||
| 706 | vp_reg_read(ctx, VP_SHADOW_UPDATE)) | ||
| 707 | goto out; | ||
| 708 | |||
| 709 | base = mixer_reg_read(ctx, MXR_CFG); | ||
| 710 | shadow = mixer_reg_read(ctx, MXR_CFG_S); | ||
| 711 | if (base != shadow) | ||
| 712 | goto out; | ||
| 713 | |||
| 702 | base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0)); | 714 | base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0)); |
| 703 | shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0)); | 715 | shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0)); |
| 704 | if (base != shadow) | 716 | if (base != shadow) |
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h index c311f571bdf9..189cfa2470a8 100644 --- a/drivers/gpu/drm/exynos/regs-mixer.h +++ b/drivers/gpu/drm/exynos/regs-mixer.h | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #define MXR_MO 0x0304 | 47 | #define MXR_MO 0x0304 |
| 48 | #define MXR_RESOLUTION 0x0310 | 48 | #define MXR_RESOLUTION 0x0310 |
| 49 | 49 | ||
| 50 | #define MXR_CFG_S 0x2004 | ||
| 50 | #define MXR_GRAPHIC0_BASE_S 0x2024 | 51 | #define MXR_GRAPHIC0_BASE_S 0x2024 |
| 51 | #define MXR_GRAPHIC1_BASE_S 0x2044 | 52 | #define MXR_GRAPHIC1_BASE_S 0x2044 |
| 52 | 53 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index d596a8302ca3..854bd51b9478 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
| @@ -778,6 +778,9 @@ i915_gem_userptr_ioctl(struct drm_device *dev, | |||
| 778 | I915_USERPTR_UNSYNCHRONIZED)) | 778 | I915_USERPTR_UNSYNCHRONIZED)) |
| 779 | return -EINVAL; | 779 | return -EINVAL; |
| 780 | 780 | ||
| 781 | if (!args->user_size) | ||
| 782 | return -EINVAL; | ||
| 783 | |||
| 781 | if (offset_in_page(args->user_ptr | args->user_size)) | 784 | if (offset_in_page(args->user_ptr | args->user_size)) |
| 782 | return -EINVAL; | 785 | return -EINVAL; |
| 783 | 786 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e6a8c0ee7df1..8a69a9275e28 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -7326,6 +7326,9 @@ enum { | |||
| 7326 | #define SLICE_ECO_CHICKEN0 _MMIO(0x7308) | 7326 | #define SLICE_ECO_CHICKEN0 _MMIO(0x7308) |
| 7327 | #define PIXEL_MASK_CAMMING_DISABLE (1 << 14) | 7327 | #define PIXEL_MASK_CAMMING_DISABLE (1 << 14) |
| 7328 | 7328 | ||
| 7329 | #define GEN9_WM_CHICKEN3 _MMIO(0x5588) | ||
| 7330 | #define GEN9_FACTOR_IN_CLR_VAL_HIZ (1 << 9) | ||
| 7331 | |||
| 7329 | /* WaCatErrorRejectionIssue */ | 7332 | /* WaCatErrorRejectionIssue */ |
| 7330 | #define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG _MMIO(0x9030) | 7333 | #define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG _MMIO(0x9030) |
| 7331 | #define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11) | 7334 | #define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11) |
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index 32d24c69da3c..704ddb4d3ca7 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c | |||
| @@ -2302,9 +2302,44 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
| 2302 | return 0; | 2302 | return 0; |
| 2303 | } | 2303 | } |
| 2304 | 2304 | ||
| 2305 | static int skl_dpll0_vco(struct intel_atomic_state *intel_state) | ||
| 2306 | { | ||
| 2307 | struct drm_i915_private *dev_priv = to_i915(intel_state->base.dev); | ||
| 2308 | struct intel_crtc *crtc; | ||
| 2309 | struct intel_crtc_state *crtc_state; | ||
| 2310 | int vco, i; | ||
| 2311 | |||
| 2312 | vco = intel_state->cdclk.logical.vco; | ||
| 2313 | if (!vco) | ||
| 2314 | vco = dev_priv->skl_preferred_vco_freq; | ||
| 2315 | |||
| 2316 | for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) { | ||
| 2317 | if (!crtc_state->base.enable) | ||
| 2318 | continue; | ||
| 2319 | |||
| 2320 | if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) | ||
| 2321 | continue; | ||
| 2322 | |||
| 2323 | /* | ||
| 2324 | * DPLL0 VCO may need to be adjusted to get the correct | ||
| 2325 | * clock for eDP. This will affect cdclk as well. | ||
| 2326 | */ | ||
| 2327 | switch (crtc_state->port_clock / 2) { | ||
| 2328 | case 108000: | ||
| 2329 | case 216000: | ||
| 2330 | vco = 8640000; | ||
| 2331 | break; | ||
| 2332 | default: | ||
| 2333 | vco = 8100000; | ||
| 2334 | break; | ||
| 2335 | } | ||
| 2336 | } | ||
| 2337 | |||
| 2338 | return vco; | ||
| 2339 | } | ||
| 2340 | |||
| 2305 | static int skl_modeset_calc_cdclk(struct drm_atomic_state *state) | 2341 | static int skl_modeset_calc_cdclk(struct drm_atomic_state *state) |
| 2306 | { | 2342 | { |
| 2307 | struct drm_i915_private *dev_priv = to_i915(state->dev); | ||
| 2308 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); | 2343 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
| 2309 | int min_cdclk, cdclk, vco; | 2344 | int min_cdclk, cdclk, vco; |
| 2310 | 2345 | ||
| @@ -2312,9 +2347,7 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
| 2312 | if (min_cdclk < 0) | 2347 | if (min_cdclk < 0) |
| 2313 | return min_cdclk; | 2348 | return min_cdclk; |
| 2314 | 2349 | ||
| 2315 | vco = intel_state->cdclk.logical.vco; | 2350 | vco = skl_dpll0_vco(intel_state); |
| 2316 | if (!vco) | ||
| 2317 | vco = dev_priv->skl_preferred_vco_freq; | ||
| 2318 | 2351 | ||
| 2319 | /* | 2352 | /* |
| 2320 | * FIXME should also account for plane ratio | 2353 | * FIXME should also account for plane ratio |
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 41e6c75a7f3c..f9550ea46c26 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" | 37 | #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" |
| 38 | MODULE_FIRMWARE(I915_CSR_GLK); | ||
| 38 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) | 39 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) |
| 39 | 40 | ||
| 40 | #define I915_CSR_CNL "i915/cnl_dmc_ver1_07.bin" | 41 | #define I915_CSR_CNL "i915/cnl_dmc_ver1_07.bin" |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3b48fd2561fe..56004ffbd8bb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -15178,6 +15178,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
| 15178 | memset(&crtc->base.mode, 0, sizeof(crtc->base.mode)); | 15178 | memset(&crtc->base.mode, 0, sizeof(crtc->base.mode)); |
| 15179 | if (crtc_state->base.active) { | 15179 | if (crtc_state->base.active) { |
| 15180 | intel_mode_from_pipe_config(&crtc->base.mode, crtc_state); | 15180 | intel_mode_from_pipe_config(&crtc->base.mode, crtc_state); |
| 15181 | crtc->base.mode.hdisplay = crtc_state->pipe_src_w; | ||
| 15182 | crtc->base.mode.vdisplay = crtc_state->pipe_src_h; | ||
| 15181 | intel_mode_from_pipe_config(&crtc_state->base.adjusted_mode, crtc_state); | 15183 | intel_mode_from_pipe_config(&crtc_state->base.adjusted_mode, crtc_state); |
| 15182 | WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode)); | 15184 | WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode)); |
| 15183 | 15185 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9a4a51e79fa1..b7b4cfdeb974 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1881,26 +1881,6 @@ found: | |||
| 1881 | reduce_m_n); | 1881 | reduce_m_n); |
| 1882 | } | 1882 | } |
| 1883 | 1883 | ||
| 1884 | /* | ||
| 1885 | * DPLL0 VCO may need to be adjusted to get the correct | ||
| 1886 | * clock for eDP. This will affect cdclk as well. | ||
| 1887 | */ | ||
| 1888 | if (intel_dp_is_edp(intel_dp) && IS_GEN9_BC(dev_priv)) { | ||
| 1889 | int vco; | ||
| 1890 | |||
| 1891 | switch (pipe_config->port_clock / 2) { | ||
| 1892 | case 108000: | ||
| 1893 | case 216000: | ||
| 1894 | vco = 8640000; | ||
| 1895 | break; | ||
| 1896 | default: | ||
| 1897 | vco = 8100000; | ||
| 1898 | break; | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | to_intel_atomic_state(pipe_config->base.state)->cdclk.logical.vco = vco; | ||
| 1902 | } | ||
| 1903 | |||
| 1904 | if (!HAS_DDI(dev_priv)) | 1884 | if (!HAS_DDI(dev_priv)) |
| 1905 | intel_dp_set_clock(encoder, pipe_config); | 1885 | intel_dp_set_clock(encoder, pipe_config); |
| 1906 | 1886 | ||
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 4ba139c27fba..f7c25828d3bb 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c | |||
| @@ -1149,6 +1149,10 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) | |||
| 1149 | WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, | 1149 | WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, |
| 1150 | GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); | 1150 | GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); |
| 1151 | 1151 | ||
| 1152 | /* WaClearHIZ_WM_CHICKEN3:bxt,glk */ | ||
| 1153 | if (IS_GEN9_LP(dev_priv)) | ||
| 1154 | WA_SET_BIT_MASKED(GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ); | ||
| 1155 | |||
| 1152 | /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */ | 1156 | /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */ |
| 1153 | ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG); | 1157 | ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG); |
| 1154 | if (ret) | 1158 | if (ret) |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e3a5f673ff67..8704f7f8d072 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
| @@ -884,6 +884,7 @@ static void execlists_submission_tasklet(unsigned long data) | |||
| 884 | 884 | ||
| 885 | head = execlists->csb_head; | 885 | head = execlists->csb_head; |
| 886 | tail = READ_ONCE(buf[write_idx]); | 886 | tail = READ_ONCE(buf[write_idx]); |
| 887 | rmb(); /* Hopefully paired with a wmb() in HW */ | ||
| 887 | } | 888 | } |
| 888 | GEM_TRACE("%s cs-irq head=%d [%d%s], tail=%d [%d%s]\n", | 889 | GEM_TRACE("%s cs-irq head=%d [%d%s], tail=%d [%d%s]\n", |
| 889 | engine->name, | 890 | engine->name, |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index d35d2d50f595..8691c86f579c 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -326,7 +326,8 @@ static void intel_enable_lvds(struct intel_encoder *encoder, | |||
| 326 | 326 | ||
| 327 | I915_WRITE(PP_CONTROL(0), I915_READ(PP_CONTROL(0)) | PANEL_POWER_ON); | 327 | I915_WRITE(PP_CONTROL(0), I915_READ(PP_CONTROL(0)) | PANEL_POWER_ON); |
| 328 | POSTING_READ(lvds_encoder->reg); | 328 | POSTING_READ(lvds_encoder->reg); |
| 329 | if (intel_wait_for_register(dev_priv, PP_STATUS(0), PP_ON, PP_ON, 1000)) | 329 | |
| 330 | if (intel_wait_for_register(dev_priv, PP_STATUS(0), PP_ON, PP_ON, 5000)) | ||
| 330 | DRM_ERROR("timed out waiting for panel to power on\n"); | 331 | DRM_ERROR("timed out waiting for panel to power on\n"); |
| 331 | 332 | ||
| 332 | intel_panel_enable_backlight(pipe_config, conn_state); | 333 | intel_panel_enable_backlight(pipe_config, conn_state); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 6f402c4f2bdd..ab61c038f42c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -214,7 +214,6 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, | |||
| 214 | INIT_LIST_HEAD(&nvbo->entry); | 214 | INIT_LIST_HEAD(&nvbo->entry); |
| 215 | INIT_LIST_HEAD(&nvbo->vma_list); | 215 | INIT_LIST_HEAD(&nvbo->vma_list); |
| 216 | nvbo->bo.bdev = &drm->ttm.bdev; | 216 | nvbo->bo.bdev = &drm->ttm.bdev; |
| 217 | nvbo->cli = cli; | ||
| 218 | 217 | ||
| 219 | /* This is confusing, and doesn't actually mean we want an uncached | 218 | /* This is confusing, and doesn't actually mean we want an uncached |
| 220 | * mapping, but is what NOUVEAU_GEM_DOMAIN_COHERENT gets translated | 219 | * mapping, but is what NOUVEAU_GEM_DOMAIN_COHERENT gets translated |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index be8e00b49cde..73c48440d4d7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h | |||
| @@ -26,8 +26,6 @@ struct nouveau_bo { | |||
| 26 | 26 | ||
| 27 | struct list_head vma_list; | 27 | struct list_head vma_list; |
| 28 | 28 | ||
| 29 | struct nouveau_cli *cli; | ||
| 30 | |||
| 31 | unsigned contig:1; | 29 | unsigned contig:1; |
| 32 | unsigned page:5; | 30 | unsigned page:5; |
| 33 | unsigned kind:8; | 31 | unsigned kind:8; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index dff51a0ee028..8c093ca4222e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c | |||
| @@ -63,7 +63,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, | |||
| 63 | struct ttm_mem_reg *reg) | 63 | struct ttm_mem_reg *reg) |
| 64 | { | 64 | { |
| 65 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 65 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
| 66 | struct nouveau_drm *drm = nvbo->cli->drm; | 66 | struct nouveau_drm *drm = nouveau_bdev(bo->bdev); |
| 67 | struct nouveau_mem *mem; | 67 | struct nouveau_mem *mem; |
| 68 | int ret; | 68 | int ret; |
| 69 | 69 | ||
| @@ -103,7 +103,7 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man, | |||
| 103 | struct ttm_mem_reg *reg) | 103 | struct ttm_mem_reg *reg) |
| 104 | { | 104 | { |
| 105 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 105 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
| 106 | struct nouveau_drm *drm = nvbo->cli->drm; | 106 | struct nouveau_drm *drm = nouveau_bdev(bo->bdev); |
| 107 | struct nouveau_mem *mem; | 107 | struct nouveau_mem *mem; |
| 108 | int ret; | 108 | int ret; |
| 109 | 109 | ||
| @@ -131,7 +131,7 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, | |||
| 131 | struct ttm_mem_reg *reg) | 131 | struct ttm_mem_reg *reg) |
| 132 | { | 132 | { |
| 133 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 133 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
| 134 | struct nouveau_drm *drm = nvbo->cli->drm; | 134 | struct nouveau_drm *drm = nouveau_bdev(bo->bdev); |
| 135 | struct nouveau_mem *mem; | 135 | struct nouveau_mem *mem; |
| 136 | int ret; | 136 | int ret; |
| 137 | 137 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 8bd739cfd00d..2b3ccd850750 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
| @@ -3264,10 +3264,11 @@ nv50_mstm_destroy_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
| 3264 | 3264 | ||
| 3265 | drm_connector_unregister(&mstc->connector); | 3265 | drm_connector_unregister(&mstc->connector); |
| 3266 | 3266 | ||
| 3267 | drm_modeset_lock_all(drm->dev); | ||
| 3268 | drm_fb_helper_remove_one_connector(&drm->fbcon->helper, &mstc->connector); | 3267 | drm_fb_helper_remove_one_connector(&drm->fbcon->helper, &mstc->connector); |
| 3268 | |||
| 3269 | drm_modeset_lock(&drm->dev->mode_config.connection_mutex, NULL); | ||
| 3269 | mstc->port = NULL; | 3270 | mstc->port = NULL; |
| 3270 | drm_modeset_unlock_all(drm->dev); | 3271 | drm_modeset_unlock(&drm->dev->mode_config.connection_mutex); |
| 3271 | 3272 | ||
| 3272 | drm_connector_unreference(&mstc->connector); | 3273 | drm_connector_unreference(&mstc->connector); |
| 3273 | } | 3274 | } |
| @@ -3277,9 +3278,7 @@ nv50_mstm_register_connector(struct drm_connector *connector) | |||
| 3277 | { | 3278 | { |
| 3278 | struct nouveau_drm *drm = nouveau_drm(connector->dev); | 3279 | struct nouveau_drm *drm = nouveau_drm(connector->dev); |
| 3279 | 3280 | ||
| 3280 | drm_modeset_lock_all(drm->dev); | ||
| 3281 | drm_fb_helper_add_one_connector(&drm->fbcon->helper, connector); | 3281 | drm_fb_helper_add_one_connector(&drm->fbcon->helper, connector); |
| 3282 | drm_modeset_unlock_all(drm->dev); | ||
| 3283 | 3282 | ||
| 3284 | drm_connector_register(connector); | 3283 | drm_connector_register(connector); |
| 3285 | } | 3284 | } |
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 5e2e65e88847..7f3ac6b13b56 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c | |||
| @@ -828,6 +828,12 @@ static void dispc_ovl_set_scale_coef(struct dispc_device *dispc, | |||
| 828 | h_coef = dispc_ovl_get_scale_coef(fir_hinc, true); | 828 | h_coef = dispc_ovl_get_scale_coef(fir_hinc, true); |
| 829 | v_coef = dispc_ovl_get_scale_coef(fir_vinc, five_taps); | 829 | v_coef = dispc_ovl_get_scale_coef(fir_vinc, five_taps); |
| 830 | 830 | ||
| 831 | if (!h_coef || !v_coef) { | ||
| 832 | dev_err(&dispc->pdev->dev, "%s: failed to find scale coefs\n", | ||
| 833 | __func__); | ||
| 834 | return; | ||
| 835 | } | ||
| 836 | |||
| 831 | for (i = 0; i < 8; i++) { | 837 | for (i = 0; i < 8; i++) { |
| 832 | u32 h, hv; | 838 | u32 h, hv; |
| 833 | 839 | ||
| @@ -2342,7 +2348,7 @@ static int dispc_ovl_calc_scaling_24xx(struct dispc_device *dispc, | |||
| 2342 | } | 2348 | } |
| 2343 | 2349 | ||
| 2344 | if (in_width > maxsinglelinewidth) { | 2350 | if (in_width > maxsinglelinewidth) { |
| 2345 | DSSERR("Cannot scale max input width exceeded"); | 2351 | DSSERR("Cannot scale max input width exceeded\n"); |
| 2346 | return -EINVAL; | 2352 | return -EINVAL; |
| 2347 | } | 2353 | } |
| 2348 | return 0; | 2354 | return 0; |
| @@ -2424,13 +2430,13 @@ again: | |||
| 2424 | } | 2430 | } |
| 2425 | 2431 | ||
| 2426 | if (in_width > (maxsinglelinewidth * 2)) { | 2432 | if (in_width > (maxsinglelinewidth * 2)) { |
| 2427 | DSSERR("Cannot setup scaling"); | 2433 | DSSERR("Cannot setup scaling\n"); |
| 2428 | DSSERR("width exceeds maximum width possible"); | 2434 | DSSERR("width exceeds maximum width possible\n"); |
| 2429 | return -EINVAL; | 2435 | return -EINVAL; |
| 2430 | } | 2436 | } |
| 2431 | 2437 | ||
| 2432 | if (in_width > maxsinglelinewidth && *five_taps) { | 2438 | if (in_width > maxsinglelinewidth && *five_taps) { |
| 2433 | DSSERR("cannot setup scaling with five taps"); | 2439 | DSSERR("cannot setup scaling with five taps\n"); |
| 2434 | return -EINVAL; | 2440 | return -EINVAL; |
| 2435 | } | 2441 | } |
| 2436 | return 0; | 2442 | return 0; |
| @@ -2472,7 +2478,7 @@ static int dispc_ovl_calc_scaling_44xx(struct dispc_device *dispc, | |||
| 2472 | in_width > maxsinglelinewidth && ++*decim_x); | 2478 | in_width > maxsinglelinewidth && ++*decim_x); |
| 2473 | 2479 | ||
| 2474 | if (in_width > maxsinglelinewidth) { | 2480 | if (in_width > maxsinglelinewidth) { |
| 2475 | DSSERR("Cannot scale width exceeds max line width"); | 2481 | DSSERR("Cannot scale width exceeds max line width\n"); |
| 2476 | return -EINVAL; | 2482 | return -EINVAL; |
| 2477 | } | 2483 | } |
| 2478 | 2484 | ||
| @@ -2490,7 +2496,7 @@ static int dispc_ovl_calc_scaling_44xx(struct dispc_device *dispc, | |||
| 2490 | * bandwidth. Despite what theory says this appears to | 2496 | * bandwidth. Despite what theory says this appears to |
| 2491 | * be true also for 16-bit color formats. | 2497 | * be true also for 16-bit color formats. |
| 2492 | */ | 2498 | */ |
| 2493 | DSSERR("Not enough bandwidth, too much downscaling (x-decimation factor %d > 4)", *decim_x); | 2499 | DSSERR("Not enough bandwidth, too much downscaling (x-decimation factor %d > 4)\n", *decim_x); |
| 2494 | 2500 | ||
| 2495 | return -EINVAL; | 2501 | return -EINVAL; |
| 2496 | } | 2502 | } |
| @@ -4633,7 +4639,7 @@ static int dispc_errata_i734_wa_init(struct dispc_device *dispc) | |||
| 4633 | i734_buf.size, &i734_buf.paddr, | 4639 | i734_buf.size, &i734_buf.paddr, |
| 4634 | GFP_KERNEL); | 4640 | GFP_KERNEL); |
| 4635 | if (!i734_buf.vaddr) { | 4641 | if (!i734_buf.vaddr) { |
| 4636 | dev_err(&dispc->pdev->dev, "%s: dma_alloc_writecombine failed", | 4642 | dev_err(&dispc->pdev->dev, "%s: dma_alloc_writecombine failed\n", |
| 4637 | __func__); | 4643 | __func__); |
| 4638 | return -ENOMEM; | 4644 | return -ENOMEM; |
| 4639 | } | 4645 | } |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 97c88861d67a..5879f45f6fc9 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c | |||
| @@ -679,7 +679,7 @@ static int hdmi_audio_config(struct device *dev, | |||
| 679 | struct omap_dss_audio *dss_audio) | 679 | struct omap_dss_audio *dss_audio) |
| 680 | { | 680 | { |
| 681 | struct omap_hdmi *hd = dev_get_drvdata(dev); | 681 | struct omap_hdmi *hd = dev_get_drvdata(dev); |
| 682 | int ret; | 682 | int ret = 0; |
| 683 | 683 | ||
| 684 | mutex_lock(&hd->lock); | 684 | mutex_lock(&hd->lock); |
| 685 | 685 | ||
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c index 35ed2add6189..813ba42f2753 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | |||
| @@ -922,8 +922,13 @@ int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core) | |||
| 922 | { | 922 | { |
| 923 | const struct hdmi4_features *features; | 923 | const struct hdmi4_features *features; |
| 924 | struct resource *res; | 924 | struct resource *res; |
| 925 | const struct soc_device_attribute *soc; | ||
| 925 | 926 | ||
| 926 | features = soc_device_match(hdmi4_soc_devices)->data; | 927 | soc = soc_device_match(hdmi4_soc_devices); |
| 928 | if (!soc) | ||
| 929 | return -ENODEV; | ||
| 930 | |||
| 931 | features = soc->data; | ||
| 927 | core->cts_swmode = features->cts_swmode; | 932 | core->cts_swmode = features->cts_swmode; |
| 928 | core->audio_use_mclk = features->audio_use_mclk; | 933 | core->audio_use_mclk = features->audio_use_mclk; |
| 929 | 934 | ||
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index d28da9ac3e90..ae1a001d1b83 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c | |||
| @@ -671,7 +671,7 @@ static int hdmi_audio_config(struct device *dev, | |||
| 671 | struct omap_dss_audio *dss_audio) | 671 | struct omap_dss_audio *dss_audio) |
| 672 | { | 672 | { |
| 673 | struct omap_hdmi *hd = dev_get_drvdata(dev); | 673 | struct omap_hdmi *hd = dev_get_drvdata(dev); |
| 674 | int ret; | 674 | int ret = 0; |
| 675 | 675 | ||
| 676 | mutex_lock(&hd->lock); | 676 | mutex_lock(&hd->lock); |
| 677 | 677 | ||
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index a0d7b1d905e8..5cde26ac937b 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c | |||
| @@ -121,6 +121,9 @@ static int omap_connector_get_modes(struct drm_connector *connector) | |||
| 121 | if (dssdrv->read_edid) { | 121 | if (dssdrv->read_edid) { |
| 122 | void *edid = kzalloc(MAX_EDID, GFP_KERNEL); | 122 | void *edid = kzalloc(MAX_EDID, GFP_KERNEL); |
| 123 | 123 | ||
| 124 | if (!edid) | ||
| 125 | return 0; | ||
| 126 | |||
| 124 | if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) && | 127 | if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) && |
| 125 | drm_edid_is_valid(edid)) { | 128 | drm_edid_is_valid(edid)) { |
| 126 | drm_mode_connector_update_edid_property( | 129 | drm_mode_connector_update_edid_property( |
| @@ -139,6 +142,9 @@ static int omap_connector_get_modes(struct drm_connector *connector) | |||
| 139 | struct drm_display_mode *mode = drm_mode_create(dev); | 142 | struct drm_display_mode *mode = drm_mode_create(dev); |
| 140 | struct videomode vm = {0}; | 143 | struct videomode vm = {0}; |
| 141 | 144 | ||
| 145 | if (!mode) | ||
| 146 | return 0; | ||
| 147 | |||
| 142 | dssdrv->get_timings(dssdev, &vm); | 148 | dssdrv->get_timings(dssdev, &vm); |
| 143 | 149 | ||
| 144 | drm_display_mode_from_videomode(&vm, mode); | 150 | drm_display_mode_from_videomode(&vm, mode); |
| @@ -200,6 +206,10 @@ static int omap_connector_mode_valid(struct drm_connector *connector, | |||
| 200 | if (!r) { | 206 | if (!r) { |
| 201 | /* check if vrefresh is still valid */ | 207 | /* check if vrefresh is still valid */ |
| 202 | new_mode = drm_mode_duplicate(dev, mode); | 208 | new_mode = drm_mode_duplicate(dev, mode); |
| 209 | |||
| 210 | if (!new_mode) | ||
| 211 | return MODE_BAD; | ||
| 212 | |||
| 203 | new_mode->clock = vm.pixelclock / 1000; | 213 | new_mode->clock = vm.pixelclock / 1000; |
| 204 | new_mode->vrefresh = 0; | 214 | new_mode->vrefresh = 0; |
| 205 | if (mode->vrefresh == drm_mode_vrefresh(new_mode)) | 215 | if (mode->vrefresh == drm_mode_vrefresh(new_mode)) |
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index f9fa1c90b35c..401c02e9e6b2 100644 --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | |||
| @@ -401,12 +401,16 @@ int tiler_unpin(struct tiler_block *block) | |||
| 401 | struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, u16 w, | 401 | struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, u16 w, |
| 402 | u16 h, u16 align) | 402 | u16 h, u16 align) |
| 403 | { | 403 | { |
| 404 | struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL); | 404 | struct tiler_block *block; |
| 405 | u32 min_align = 128; | 405 | u32 min_align = 128; |
| 406 | int ret; | 406 | int ret; |
| 407 | unsigned long flags; | 407 | unsigned long flags; |
| 408 | u32 slot_bytes; | 408 | u32 slot_bytes; |
| 409 | 409 | ||
| 410 | block = kzalloc(sizeof(*block), GFP_KERNEL); | ||
| 411 | if (!block) | ||
| 412 | return ERR_PTR(-ENOMEM); | ||
| 413 | |||
| 410 | BUG_ON(!validfmt(fmt)); | 414 | BUG_ON(!validfmt(fmt)); |
| 411 | 415 | ||
| 412 | /* convert width/height to slots */ | 416 | /* convert width/height to slots */ |
diff --git a/drivers/gpu/drm/omapdrm/tcm-sita.c b/drivers/gpu/drm/omapdrm/tcm-sita.c index d7f7bc9f061a..817be3c41863 100644 --- a/drivers/gpu/drm/omapdrm/tcm-sita.c +++ b/drivers/gpu/drm/omapdrm/tcm-sita.c | |||
| @@ -90,7 +90,7 @@ static int l2r_t2b(u16 w, u16 h, u16 a, s16 offset, | |||
| 90 | { | 90 | { |
| 91 | int i; | 91 | int i; |
| 92 | unsigned long index; | 92 | unsigned long index; |
| 93 | bool area_free; | 93 | bool area_free = false; |
| 94 | unsigned long slots_per_band = PAGE_SIZE / slot_bytes; | 94 | unsigned long slots_per_band = PAGE_SIZE / slot_bytes; |
| 95 | unsigned long bit_offset = (offset > 0) ? offset / slot_bytes : 0; | 95 | unsigned long bit_offset = (offset > 0) ? offset / slot_bytes : 0; |
| 96 | unsigned long curr_bit = bit_offset; | 96 | unsigned long curr_bit = bit_offset; |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index f0481b7b60c5..06c94e3a5f15 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
| @@ -910,7 +910,8 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, | |||
| 910 | while (npages >= HPAGE_PMD_NR) { | 910 | while (npages >= HPAGE_PMD_NR) { |
| 911 | gfp_t huge_flags = gfp_flags; | 911 | gfp_t huge_flags = gfp_flags; |
| 912 | 912 | ||
| 913 | huge_flags |= GFP_TRANSHUGE; | 913 | huge_flags |= GFP_TRANSHUGE_LIGHT | __GFP_NORETRY | |
| 914 | __GFP_KSWAPD_RECLAIM; | ||
| 914 | huge_flags &= ~__GFP_MOVABLE; | 915 | huge_flags &= ~__GFP_MOVABLE; |
| 915 | huge_flags &= ~__GFP_COMP; | 916 | huge_flags &= ~__GFP_COMP; |
| 916 | p = alloc_pages(huge_flags, HPAGE_PMD_ORDER); | 917 | p = alloc_pages(huge_flags, HPAGE_PMD_ORDER); |
| @@ -1027,11 +1028,15 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) | |||
| 1027 | GFP_USER | GFP_DMA32, "uc dma", 0); | 1028 | GFP_USER | GFP_DMA32, "uc dma", 0); |
| 1028 | 1029 | ||
| 1029 | ttm_page_pool_init_locked(&_manager->wc_pool_huge, | 1030 | ttm_page_pool_init_locked(&_manager->wc_pool_huge, |
| 1030 | GFP_TRANSHUGE & ~(__GFP_MOVABLE | __GFP_COMP), | 1031 | (GFP_TRANSHUGE_LIGHT | __GFP_NORETRY | |
| 1032 | __GFP_KSWAPD_RECLAIM) & | ||
| 1033 | ~(__GFP_MOVABLE | __GFP_COMP), | ||
| 1031 | "wc huge", order); | 1034 | "wc huge", order); |
| 1032 | 1035 | ||
| 1033 | ttm_page_pool_init_locked(&_manager->uc_pool_huge, | 1036 | ttm_page_pool_init_locked(&_manager->uc_pool_huge, |
| 1034 | GFP_TRANSHUGE & ~(__GFP_MOVABLE | __GFP_COMP) | 1037 | (GFP_TRANSHUGE_LIGHT | __GFP_NORETRY | |
| 1038 | __GFP_KSWAPD_RECLAIM) & | ||
| 1039 | ~(__GFP_MOVABLE | __GFP_COMP) | ||
| 1035 | , "uc huge", order); | 1040 | , "uc huge", order); |
| 1036 | 1041 | ||
| 1037 | _manager->options.max_size = max_pages; | 1042 | _manager->options.max_size = max_pages; |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 8a25d1974385..f63d99c302e4 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | |||
| @@ -910,7 +910,8 @@ static gfp_t ttm_dma_pool_gfp_flags(struct ttm_dma_tt *ttm_dma, bool huge) | |||
| 910 | gfp_flags |= __GFP_ZERO; | 910 | gfp_flags |= __GFP_ZERO; |
| 911 | 911 | ||
| 912 | if (huge) { | 912 | if (huge) { |
| 913 | gfp_flags |= GFP_TRANSHUGE; | 913 | gfp_flags |= GFP_TRANSHUGE_LIGHT | __GFP_NORETRY | |
| 914 | __GFP_KSWAPD_RECLAIM; | ||
| 914 | gfp_flags &= ~__GFP_MOVABLE; | 915 | gfp_flags &= ~__GFP_MOVABLE; |
| 915 | gfp_flags &= ~__GFP_COMP; | 916 | gfp_flags &= ~__GFP_COMP; |
| 916 | } | 917 | } |
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index bf4667481935..c61dff594195 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c | |||
| @@ -760,6 +760,7 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) | |||
| 760 | struct vc4_async_flip_state { | 760 | struct vc4_async_flip_state { |
| 761 | struct drm_crtc *crtc; | 761 | struct drm_crtc *crtc; |
| 762 | struct drm_framebuffer *fb; | 762 | struct drm_framebuffer *fb; |
| 763 | struct drm_framebuffer *old_fb; | ||
| 763 | struct drm_pending_vblank_event *event; | 764 | struct drm_pending_vblank_event *event; |
| 764 | 765 | ||
| 765 | struct vc4_seqno_cb cb; | 766 | struct vc4_seqno_cb cb; |
| @@ -789,6 +790,23 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) | |||
| 789 | 790 | ||
| 790 | drm_crtc_vblank_put(crtc); | 791 | drm_crtc_vblank_put(crtc); |
| 791 | drm_framebuffer_put(flip_state->fb); | 792 | drm_framebuffer_put(flip_state->fb); |
| 793 | |||
| 794 | /* Decrement the BO usecnt in order to keep the inc/dec calls balanced | ||
| 795 | * when the planes are updated through the async update path. | ||
| 796 | * FIXME: we should move to generic async-page-flip when it's | ||
| 797 | * available, so that we can get rid of this hand-made cleanup_fb() | ||
| 798 | * logic. | ||
| 799 | */ | ||
| 800 | if (flip_state->old_fb) { | ||
| 801 | struct drm_gem_cma_object *cma_bo; | ||
| 802 | struct vc4_bo *bo; | ||
| 803 | |||
| 804 | cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0); | ||
| 805 | bo = to_vc4_bo(&cma_bo->base); | ||
| 806 | vc4_bo_dec_usecnt(bo); | ||
| 807 | drm_framebuffer_put(flip_state->old_fb); | ||
| 808 | } | ||
| 809 | |||
| 792 | kfree(flip_state); | 810 | kfree(flip_state); |
| 793 | 811 | ||
| 794 | up(&vc4->async_modeset); | 812 | up(&vc4->async_modeset); |
| @@ -813,9 +831,22 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, | |||
| 813 | struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); | 831 | struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); |
| 814 | struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); | 832 | struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); |
| 815 | 833 | ||
| 834 | /* Increment the BO usecnt here, so that we never end up with an | ||
| 835 | * unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the | ||
| 836 | * plane is later updated through the non-async path. | ||
| 837 | * FIXME: we should move to generic async-page-flip when it's | ||
| 838 | * available, so that we can get rid of this hand-made prepare_fb() | ||
| 839 | * logic. | ||
| 840 | */ | ||
| 841 | ret = vc4_bo_inc_usecnt(bo); | ||
| 842 | if (ret) | ||
| 843 | return ret; | ||
| 844 | |||
| 816 | flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); | 845 | flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); |
| 817 | if (!flip_state) | 846 | if (!flip_state) { |
| 847 | vc4_bo_dec_usecnt(bo); | ||
| 818 | return -ENOMEM; | 848 | return -ENOMEM; |
| 849 | } | ||
| 819 | 850 | ||
| 820 | drm_framebuffer_get(fb); | 851 | drm_framebuffer_get(fb); |
| 821 | flip_state->fb = fb; | 852 | flip_state->fb = fb; |
| @@ -826,10 +857,23 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, | |||
| 826 | ret = down_interruptible(&vc4->async_modeset); | 857 | ret = down_interruptible(&vc4->async_modeset); |
| 827 | if (ret) { | 858 | if (ret) { |
| 828 | drm_framebuffer_put(fb); | 859 | drm_framebuffer_put(fb); |
| 860 | vc4_bo_dec_usecnt(bo); | ||
| 829 | kfree(flip_state); | 861 | kfree(flip_state); |
| 830 | return ret; | 862 | return ret; |
| 831 | } | 863 | } |
| 832 | 864 | ||
| 865 | /* Save the current FB before it's replaced by the new one in | ||
| 866 | * drm_atomic_set_fb_for_plane(). We'll need the old FB in | ||
| 867 | * vc4_async_page_flip_complete() to decrement the BO usecnt and keep | ||
| 868 | * it consistent. | ||
| 869 | * FIXME: we should move to generic async-page-flip when it's | ||
| 870 | * available, so that we can get rid of this hand-made cleanup_fb() | ||
| 871 | * logic. | ||
| 872 | */ | ||
| 873 | flip_state->old_fb = plane->state->fb; | ||
| 874 | if (flip_state->old_fb) | ||
| 875 | drm_framebuffer_get(flip_state->old_fb); | ||
| 876 | |||
| 833 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | 877 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); |
| 834 | 878 | ||
| 835 | /* Immediately update the plane's legacy fb pointer, so that later | 879 | /* Immediately update the plane's legacy fb pointer, so that later |
diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index 72c9dbd81d7f..f185812970da 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c | |||
| @@ -96,7 +96,6 @@ struct vc4_dpi { | |||
| 96 | struct platform_device *pdev; | 96 | struct platform_device *pdev; |
| 97 | 97 | ||
| 98 | struct drm_encoder *encoder; | 98 | struct drm_encoder *encoder; |
| 99 | struct drm_connector *connector; | ||
| 100 | 99 | ||
| 101 | void __iomem *regs; | 100 | void __iomem *regs; |
| 102 | 101 | ||
| @@ -164,14 +163,31 @@ static void vc4_dpi_encoder_disable(struct drm_encoder *encoder) | |||
| 164 | 163 | ||
| 165 | static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) | 164 | static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) |
| 166 | { | 165 | { |
| 166 | struct drm_device *dev = encoder->dev; | ||
| 167 | struct drm_display_mode *mode = &encoder->crtc->mode; | 167 | struct drm_display_mode *mode = &encoder->crtc->mode; |
| 168 | struct vc4_dpi_encoder *vc4_encoder = to_vc4_dpi_encoder(encoder); | 168 | struct vc4_dpi_encoder *vc4_encoder = to_vc4_dpi_encoder(encoder); |
| 169 | struct vc4_dpi *dpi = vc4_encoder->dpi; | 169 | struct vc4_dpi *dpi = vc4_encoder->dpi; |
| 170 | struct drm_connector_list_iter conn_iter; | ||
| 171 | struct drm_connector *connector = NULL, *connector_scan; | ||
| 170 | u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE; | 172 | u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE; |
| 171 | int ret; | 173 | int ret; |
| 172 | 174 | ||
| 173 | if (dpi->connector->display_info.num_bus_formats) { | 175 | /* Look up the connector attached to DPI so we can get the |
| 174 | u32 bus_format = dpi->connector->display_info.bus_formats[0]; | 176 | * bus_format. Ideally the bridge would tell us the |
| 177 | * bus_format we want, but it doesn't yet, so assume that it's | ||
| 178 | * uniform throughout the bridge chain. | ||
| 179 | */ | ||
| 180 | drm_connector_list_iter_begin(dev, &conn_iter); | ||
| 181 | drm_for_each_connector_iter(connector_scan, &conn_iter) { | ||
| 182 | if (connector_scan->encoder == encoder) { | ||
| 183 | connector = connector_scan; | ||
| 184 | break; | ||
| 185 | } | ||
| 186 | } | ||
| 187 | drm_connector_list_iter_end(&conn_iter); | ||
| 188 | |||
| 189 | if (connector && connector->display_info.num_bus_formats) { | ||
| 190 | u32 bus_format = connector->display_info.bus_formats[0]; | ||
| 175 | 191 | ||
| 176 | switch (bus_format) { | 192 | switch (bus_format) { |
| 177 | case MEDIA_BUS_FMT_RGB888_1X24: | 193 | case MEDIA_BUS_FMT_RGB888_1X24: |
| @@ -199,6 +215,9 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) | |||
| 199 | DRM_ERROR("Unknown media bus format %d\n", bus_format); | 215 | DRM_ERROR("Unknown media bus format %d\n", bus_format); |
| 200 | break; | 216 | break; |
| 201 | } | 217 | } |
| 218 | } else { | ||
| 219 | /* Default to 24bit if no connector found. */ | ||
| 220 | dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT); | ||
| 202 | } | 221 | } |
| 203 | 222 | ||
| 204 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | 223 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 94b99c90425a..7c95ed5c5cac 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c | |||
| @@ -130,6 +130,7 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) | |||
| 130 | struct vc4_file *vc4file = file->driver_priv; | 130 | struct vc4_file *vc4file = file->driver_priv; |
| 131 | 131 | ||
| 132 | vc4_perfmon_close_file(vc4file); | 132 | vc4_perfmon_close_file(vc4file); |
| 133 | kfree(vc4file); | ||
| 133 | } | 134 | } |
| 134 | 135 | ||
| 135 | static const struct vm_operations_struct vc4_vm_ops = { | 136 | static const struct vm_operations_struct vc4_vm_ops = { |
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index ce39390be389..13dcaad06798 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c | |||
| @@ -503,7 +503,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, | |||
| 503 | * the scl fields here. | 503 | * the scl fields here. |
| 504 | */ | 504 | */ |
| 505 | if (num_planes == 1) { | 505 | if (num_planes == 1) { |
| 506 | scl0 = vc4_get_scl_field(state, 1); | 506 | scl0 = vc4_get_scl_field(state, 0); |
| 507 | scl1 = scl0; | 507 | scl1 = scl0; |
| 508 | } else { | 508 | } else { |
| 509 | scl0 = vc4_get_scl_field(state, 1); | 509 | scl0 = vc4_get_scl_field(state, 1); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 2582ffd36bb5..ba0cdb743c3e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
| @@ -441,11 +441,11 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set) | |||
| 441 | struct drm_crtc *crtc = set->crtc; | 441 | struct drm_crtc *crtc = set->crtc; |
| 442 | struct drm_framebuffer *fb; | 442 | struct drm_framebuffer *fb; |
| 443 | struct drm_crtc *tmp; | 443 | struct drm_crtc *tmp; |
| 444 | struct drm_modeset_acquire_ctx *ctx; | ||
| 445 | struct drm_device *dev = set->crtc->dev; | 444 | struct drm_device *dev = set->crtc->dev; |
| 445 | struct drm_modeset_acquire_ctx ctx; | ||
| 446 | int ret; | 446 | int ret; |
| 447 | 447 | ||
| 448 | ctx = dev->mode_config.acquire_ctx; | 448 | drm_modeset_acquire_init(&ctx, 0); |
| 449 | 449 | ||
| 450 | restart: | 450 | restart: |
| 451 | /* | 451 | /* |
| @@ -458,7 +458,7 @@ restart: | |||
| 458 | 458 | ||
| 459 | fb = set->fb; | 459 | fb = set->fb; |
| 460 | 460 | ||
| 461 | ret = crtc->funcs->set_config(set, ctx); | 461 | ret = crtc->funcs->set_config(set, &ctx); |
| 462 | if (ret == 0) { | 462 | if (ret == 0) { |
| 463 | crtc->primary->crtc = crtc; | 463 | crtc->primary->crtc = crtc; |
| 464 | crtc->primary->fb = fb; | 464 | crtc->primary->fb = fb; |
| @@ -473,20 +473,13 @@ restart: | |||
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | if (ret == -EDEADLK) { | 475 | if (ret == -EDEADLK) { |
| 476 | dev->mode_config.acquire_ctx = NULL; | 476 | drm_modeset_backoff(&ctx); |
| 477 | |||
| 478 | retry_locking: | ||
| 479 | drm_modeset_backoff(ctx); | ||
| 480 | |||
| 481 | ret = drm_modeset_lock_all_ctx(dev, ctx); | ||
| 482 | if (ret) | ||
| 483 | goto retry_locking; | ||
| 484 | |||
| 485 | dev->mode_config.acquire_ctx = ctx; | ||
| 486 | |||
| 487 | goto restart; | 477 | goto restart; |
| 488 | } | 478 | } |
| 489 | 479 | ||
| 480 | drm_modeset_drop_locks(&ctx); | ||
| 481 | drm_modeset_acquire_fini(&ctx); | ||
| 482 | |||
| 490 | return ret; | 483 | return ret; |
| 491 | } | 484 | } |
| 492 | 485 | ||
| @@ -624,7 +617,6 @@ static int vmw_fb_set_par(struct fb_info *info) | |||
| 624 | } | 617 | } |
| 625 | 618 | ||
| 626 | mutex_lock(&par->bo_mutex); | 619 | mutex_lock(&par->bo_mutex); |
| 627 | drm_modeset_lock_all(vmw_priv->dev); | ||
| 628 | ret = vmw_fb_kms_framebuffer(info); | 620 | ret = vmw_fb_kms_framebuffer(info); |
| 629 | if (ret) | 621 | if (ret) |
| 630 | goto out_unlock; | 622 | goto out_unlock; |
| @@ -657,7 +649,6 @@ out_unlock: | |||
| 657 | drm_mode_destroy(vmw_priv->dev, old_mode); | 649 | drm_mode_destroy(vmw_priv->dev, old_mode); |
| 658 | par->set_mode = mode; | 650 | par->set_mode = mode; |
| 659 | 651 | ||
| 660 | drm_modeset_unlock_all(vmw_priv->dev); | ||
| 661 | mutex_unlock(&par->bo_mutex); | 652 | mutex_unlock(&par->bo_mutex); |
| 662 | 653 | ||
| 663 | return ret; | 654 | return ret; |
| @@ -713,18 +704,14 @@ int vmw_fb_init(struct vmw_private *vmw_priv) | |||
| 713 | par->max_width = fb_width; | 704 | par->max_width = fb_width; |
| 714 | par->max_height = fb_height; | 705 | par->max_height = fb_height; |
| 715 | 706 | ||
| 716 | drm_modeset_lock_all(vmw_priv->dev); | ||
| 717 | ret = vmw_kms_fbdev_init_data(vmw_priv, 0, par->max_width, | 707 | ret = vmw_kms_fbdev_init_data(vmw_priv, 0, par->max_width, |
| 718 | par->max_height, &par->con, | 708 | par->max_height, &par->con, |
| 719 | &par->crtc, &init_mode); | 709 | &par->crtc, &init_mode); |
| 720 | if (ret) { | 710 | if (ret) |
| 721 | drm_modeset_unlock_all(vmw_priv->dev); | ||
| 722 | goto err_kms; | 711 | goto err_kms; |
| 723 | } | ||
| 724 | 712 | ||
| 725 | info->var.xres = init_mode->hdisplay; | 713 | info->var.xres = init_mode->hdisplay; |
| 726 | info->var.yres = init_mode->vdisplay; | 714 | info->var.yres = init_mode->vdisplay; |
| 727 | drm_modeset_unlock_all(vmw_priv->dev); | ||
| 728 | 715 | ||
| 729 | /* | 716 | /* |
| 730 | * Create buffers and alloc memory | 717 | * Create buffers and alloc memory |
| @@ -832,7 +819,9 @@ int vmw_fb_close(struct vmw_private *vmw_priv) | |||
| 832 | cancel_delayed_work_sync(&par->local_work); | 819 | cancel_delayed_work_sync(&par->local_work); |
| 833 | unregister_framebuffer(info); | 820 | unregister_framebuffer(info); |
| 834 | 821 | ||
| 822 | mutex_lock(&par->bo_mutex); | ||
| 835 | (void) vmw_fb_kms_detach(par, true, true); | 823 | (void) vmw_fb_kms_detach(par, true, true); |
| 824 | mutex_unlock(&par->bo_mutex); | ||
| 836 | 825 | ||
| 837 | vfree(par->vmalloc); | 826 | vfree(par->vmalloc); |
| 838 | framebuffer_release(info); | 827 | framebuffer_release(info); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index f11601b6fd74..96fd7a03d2f8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -2595,6 +2595,7 @@ void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, | |||
| 2595 | vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, | 2595 | vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, |
| 2596 | out_fence, NULL); | 2596 | out_fence, NULL); |
| 2597 | 2597 | ||
| 2598 | vmw_dmabuf_unreference(&ctx->buf); | ||
| 2598 | vmw_resource_unreserve(res, false, NULL, 0); | 2599 | vmw_resource_unreserve(res, false, NULL, 0); |
| 2599 | mutex_unlock(&res->dev_priv->cmdbuf_mutex); | 2600 | mutex_unlock(&res->dev_priv->cmdbuf_mutex); |
| 2600 | } | 2601 | } |
| @@ -2680,7 +2681,9 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, | |||
| 2680 | struct vmw_display_unit *du; | 2681 | struct vmw_display_unit *du; |
| 2681 | struct drm_display_mode *mode; | 2682 | struct drm_display_mode *mode; |
| 2682 | int i = 0; | 2683 | int i = 0; |
| 2684 | int ret = 0; | ||
| 2683 | 2685 | ||
| 2686 | mutex_lock(&dev_priv->dev->mode_config.mutex); | ||
| 2684 | list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list, | 2687 | list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list, |
| 2685 | head) { | 2688 | head) { |
| 2686 | if (i == unit) | 2689 | if (i == unit) |
| @@ -2691,7 +2694,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, | |||
| 2691 | 2694 | ||
| 2692 | if (i != unit) { | 2695 | if (i != unit) { |
| 2693 | DRM_ERROR("Could not find initial display unit.\n"); | 2696 | DRM_ERROR("Could not find initial display unit.\n"); |
| 2694 | return -EINVAL; | 2697 | ret = -EINVAL; |
| 2698 | goto out_unlock; | ||
| 2695 | } | 2699 | } |
| 2696 | 2700 | ||
| 2697 | if (list_empty(&con->modes)) | 2701 | if (list_empty(&con->modes)) |
| @@ -2699,7 +2703,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, | |||
| 2699 | 2703 | ||
| 2700 | if (list_empty(&con->modes)) { | 2704 | if (list_empty(&con->modes)) { |
| 2701 | DRM_ERROR("Could not find initial display mode.\n"); | 2705 | DRM_ERROR("Could not find initial display mode.\n"); |
| 2702 | return -EINVAL; | 2706 | ret = -EINVAL; |
| 2707 | goto out_unlock; | ||
| 2703 | } | 2708 | } |
| 2704 | 2709 | ||
| 2705 | du = vmw_connector_to_du(con); | 2710 | du = vmw_connector_to_du(con); |
| @@ -2720,7 +2725,10 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, | |||
| 2720 | head); | 2725 | head); |
| 2721 | } | 2726 | } |
| 2722 | 2727 | ||
| 2723 | return 0; | 2728 | out_unlock: |
| 2729 | mutex_unlock(&dev_priv->dev->mode_config.mutex); | ||
| 2730 | |||
| 2731 | return ret; | ||
| 2724 | } | 2732 | } |
| 2725 | 2733 | ||
| 2726 | /** | 2734 | /** |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 648f8127f65a..3d667e903beb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |||
| @@ -482,6 +482,8 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, | |||
| 482 | return ret; | 482 | return ret; |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | vps->dmabuf_size = size; | ||
| 486 | |||
| 485 | /* | 487 | /* |
| 486 | * TTM already thinks the buffer is pinned, but make sure the | 488 | * TTM already thinks the buffer is pinned, but make sure the |
| 487 | * pin_count is upped. | 489 | * pin_count is upped. |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 60252fd796f6..0000434a1fbd 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -462,10 +462,11 @@ config HID_LENOVO | |||
| 462 | select NEW_LEDS | 462 | select NEW_LEDS |
| 463 | select LEDS_CLASS | 463 | select LEDS_CLASS |
| 464 | ---help--- | 464 | ---help--- |
| 465 | Support for Lenovo devices that are not fully compliant with HID standard. | 465 | Support for IBM/Lenovo devices that are not fully compliant with HID standard. |
| 466 | 466 | ||
| 467 | Say Y if you want support for the non-compliant features of the Lenovo | 467 | Say Y if you want support for horizontal scrolling of the IBM/Lenovo |
| 468 | Thinkpad standalone keyboards, e.g: | 468 | Scrollpoint mice or the non-compliant features of the Lenovo Thinkpad |
| 469 | standalone keyboards, e.g: | ||
| 469 | - ThinkPad USB Keyboard with TrackPoint (supports extra LEDs and trackpoint | 470 | - ThinkPad USB Keyboard with TrackPoint (supports extra LEDs and trackpoint |
| 470 | configuration) | 471 | configuration) |
| 471 | - ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys) | 472 | - ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys) |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 0b5cc910f62e..46f5ecd11bf7 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -552,6 +552,13 @@ | |||
| 552 | #define USB_VENDOR_ID_HUION 0x256c | 552 | #define USB_VENDOR_ID_HUION 0x256c |
| 553 | #define USB_DEVICE_ID_HUION_TABLET 0x006e | 553 | #define USB_DEVICE_ID_HUION_TABLET 0x006e |
| 554 | 554 | ||
| 555 | #define USB_VENDOR_ID_IBM 0x04b3 | ||
| 556 | #define USB_DEVICE_ID_IBM_SCROLLPOINT_III 0x3100 | ||
| 557 | #define USB_DEVICE_ID_IBM_SCROLLPOINT_PRO 0x3103 | ||
| 558 | #define USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL 0x3105 | ||
| 559 | #define USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL 0x3108 | ||
| 560 | #define USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO 0x3109 | ||
| 561 | |||
| 555 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 | 562 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 |
| 556 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 | 563 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 |
| 557 | #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 | 564 | #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 |
| @@ -684,6 +691,7 @@ | |||
| 684 | #define USB_DEVICE_ID_LENOVO_TPKBD 0x6009 | 691 | #define USB_DEVICE_ID_LENOVO_TPKBD 0x6009 |
| 685 | #define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047 | 692 | #define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047 |
| 686 | #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 | 693 | #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 |
| 694 | #define USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL 0x6049 | ||
| 687 | #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 | 695 | #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 |
| 688 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 | 696 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 |
| 689 | #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 | 697 | #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 |
| @@ -964,6 +972,7 @@ | |||
| 964 | #define USB_DEVICE_ID_SIS817_TOUCH 0x0817 | 972 | #define USB_DEVICE_ID_SIS817_TOUCH 0x0817 |
| 965 | #define USB_DEVICE_ID_SIS_TS 0x1013 | 973 | #define USB_DEVICE_ID_SIS_TS 0x1013 |
| 966 | #define USB_DEVICE_ID_SIS1030_TOUCH 0x1030 | 974 | #define USB_DEVICE_ID_SIS1030_TOUCH 0x1030 |
| 975 | #define USB_DEVICE_ID_SIS10FB_TOUCH 0x10fb | ||
| 967 | 976 | ||
| 968 | #define USB_VENDOR_ID_SKYCABLE 0x1223 | 977 | #define USB_VENDOR_ID_SKYCABLE 0x1223 |
| 969 | #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 | 978 | #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 |
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 1ac4ff4d57a6..643b6eb54442 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c | |||
| @@ -6,6 +6,17 @@ | |||
| 6 | * | 6 | * |
| 7 | * Copyright (c) 2012 Bernhard Seibold | 7 | * Copyright (c) 2012 Bernhard Seibold |
| 8 | * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk> | 8 | * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk> |
| 9 | * | ||
| 10 | * Linux IBM/Lenovo Scrollpoint mouse driver: | ||
| 11 | * - IBM Scrollpoint III | ||
| 12 | * - IBM Scrollpoint Pro | ||
| 13 | * - IBM Scrollpoint Optical | ||
| 14 | * - IBM Scrollpoint Optical 800dpi | ||
| 15 | * - IBM Scrollpoint Optical 800dpi Pro | ||
| 16 | * - Lenovo Scrollpoint Optical | ||
| 17 | * | ||
| 18 | * Copyright (c) 2012 Peter De Wachter <pdewacht@gmail.com> | ||
| 19 | * Copyright (c) 2018 Peter Ganzhorn <peter.ganzhorn@gmail.com> | ||
| 9 | */ | 20 | */ |
| 10 | 21 | ||
| 11 | /* | 22 | /* |
| @@ -160,6 +171,17 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, | |||
| 160 | return 0; | 171 | return 0; |
| 161 | } | 172 | } |
| 162 | 173 | ||
| 174 | static int lenovo_input_mapping_scrollpoint(struct hid_device *hdev, | ||
| 175 | struct hid_input *hi, struct hid_field *field, | ||
| 176 | struct hid_usage *usage, unsigned long **bit, int *max) | ||
| 177 | { | ||
| 178 | if (usage->hid == HID_GD_Z) { | ||
| 179 | hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); | ||
| 180 | return 1; | ||
| 181 | } | ||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | |||
| 163 | static int lenovo_input_mapping(struct hid_device *hdev, | 185 | static int lenovo_input_mapping(struct hid_device *hdev, |
| 164 | struct hid_input *hi, struct hid_field *field, | 186 | struct hid_input *hi, struct hid_field *field, |
| 165 | struct hid_usage *usage, unsigned long **bit, int *max) | 187 | struct hid_usage *usage, unsigned long **bit, int *max) |
| @@ -172,6 +194,14 @@ static int lenovo_input_mapping(struct hid_device *hdev, | |||
| 172 | case USB_DEVICE_ID_LENOVO_CBTKBD: | 194 | case USB_DEVICE_ID_LENOVO_CBTKBD: |
| 173 | return lenovo_input_mapping_cptkbd(hdev, hi, field, | 195 | return lenovo_input_mapping_cptkbd(hdev, hi, field, |
| 174 | usage, bit, max); | 196 | usage, bit, max); |
| 197 | case USB_DEVICE_ID_IBM_SCROLLPOINT_III: | ||
| 198 | case USB_DEVICE_ID_IBM_SCROLLPOINT_PRO: | ||
| 199 | case USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL: | ||
| 200 | case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL: | ||
| 201 | case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO: | ||
| 202 | case USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL: | ||
| 203 | return lenovo_input_mapping_scrollpoint(hdev, hi, field, | ||
| 204 | usage, bit, max); | ||
| 175 | default: | 205 | default: |
| 176 | return 0; | 206 | return 0; |
| 177 | } | 207 | } |
| @@ -883,6 +913,12 @@ static const struct hid_device_id lenovo_devices[] = { | |||
| 883 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) }, | 913 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) }, |
| 884 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) }, | 914 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) }, |
| 885 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) }, | 915 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) }, |
| 916 | { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_III) }, | ||
| 917 | { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_PRO) }, | ||
| 918 | { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL) }, | ||
| 919 | { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL) }, | ||
| 920 | { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) }, | ||
| 921 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL) }, | ||
| 886 | { } | 922 | { } |
| 887 | }; | 923 | }; |
| 888 | 924 | ||
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 963328674e93..cc33622253aa 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -174,6 +174,8 @@ static const struct i2c_hid_quirks { | |||
| 174 | I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, | 174 | I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, |
| 175 | { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118, | 175 | { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118, |
| 176 | I2C_HID_QUIRK_RESEND_REPORT_DESCR }, | 176 | I2C_HID_QUIRK_RESEND_REPORT_DESCR }, |
| 177 | { USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS10FB_TOUCH, | ||
| 178 | I2C_HID_QUIRK_RESEND_REPORT_DESCR }, | ||
| 177 | { 0, 0 } | 179 | { 0, 0 } |
| 178 | }; | 180 | }; |
| 179 | 181 | ||
diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c index 157b44aacdff..acc2536c8094 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c | |||
| @@ -77,21 +77,21 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf, | |||
| 77 | struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; | 77 | struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; |
| 78 | int curr_hid_dev = client_data->cur_hid_dev; | 78 | int curr_hid_dev = client_data->cur_hid_dev; |
| 79 | 79 | ||
| 80 | if (data_len < sizeof(struct hostif_msg_hdr)) { | ||
| 81 | dev_err(&client_data->cl_device->dev, | ||
| 82 | "[hid-ish]: error, received %u which is less than data header %u\n", | ||
| 83 | (unsigned int)data_len, | ||
| 84 | (unsigned int)sizeof(struct hostif_msg_hdr)); | ||
| 85 | ++client_data->bad_recv_cnt; | ||
| 86 | ish_hw_reset(hid_ishtp_cl->dev); | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | |||
| 90 | payload = recv_buf + sizeof(struct hostif_msg_hdr); | 80 | payload = recv_buf + sizeof(struct hostif_msg_hdr); |
| 91 | total_len = data_len; | 81 | total_len = data_len; |
| 92 | cur_pos = 0; | 82 | cur_pos = 0; |
| 93 | 83 | ||
| 94 | do { | 84 | do { |
| 85 | if (cur_pos + sizeof(struct hostif_msg) > total_len) { | ||
| 86 | dev_err(&client_data->cl_device->dev, | ||
| 87 | "[hid-ish]: error, received %u which is less than data header %u\n", | ||
| 88 | (unsigned int)data_len, | ||
| 89 | (unsigned int)sizeof(struct hostif_msg_hdr)); | ||
| 90 | ++client_data->bad_recv_cnt; | ||
| 91 | ish_hw_reset(hid_ishtp_cl->dev); | ||
| 92 | break; | ||
| 93 | } | ||
| 94 | |||
| 95 | recv_msg = (struct hostif_msg *)(recv_buf + cur_pos); | 95 | recv_msg = (struct hostif_msg *)(recv_buf + cur_pos); |
| 96 | payload_len = recv_msg->hdr.size; | 96 | payload_len = recv_msg->hdr.size; |
| 97 | 97 | ||
| @@ -412,9 +412,7 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id, | |||
| 412 | { | 412 | { |
| 413 | struct ishtp_hid_data *hid_data = hid->driver_data; | 413 | struct ishtp_hid_data *hid_data = hid->driver_data; |
| 414 | struct ishtp_cl_data *client_data = hid_data->client_data; | 414 | struct ishtp_cl_data *client_data = hid_data->client_data; |
| 415 | static unsigned char buf[10]; | 415 | struct hostif_msg_to_sensor msg = {}; |
| 416 | unsigned int len; | ||
| 417 | struct hostif_msg_to_sensor *msg = (struct hostif_msg_to_sensor *)buf; | ||
| 418 | int rv; | 416 | int rv; |
| 419 | int i; | 417 | int i; |
| 420 | 418 | ||
| @@ -426,14 +424,11 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id, | |||
| 426 | return; | 424 | return; |
| 427 | } | 425 | } |
| 428 | 426 | ||
| 429 | len = sizeof(struct hostif_msg_to_sensor); | 427 | msg.hdr.command = (report_type == HID_FEATURE_REPORT) ? |
| 430 | |||
| 431 | memset(msg, 0, sizeof(struct hostif_msg_to_sensor)); | ||
| 432 | msg->hdr.command = (report_type == HID_FEATURE_REPORT) ? | ||
| 433 | HOSTIF_GET_FEATURE_REPORT : HOSTIF_GET_INPUT_REPORT; | 428 | HOSTIF_GET_FEATURE_REPORT : HOSTIF_GET_INPUT_REPORT; |
| 434 | for (i = 0; i < client_data->num_hid_devices; ++i) { | 429 | for (i = 0; i < client_data->num_hid_devices; ++i) { |
| 435 | if (hid == client_data->hid_sensor_hubs[i]) { | 430 | if (hid == client_data->hid_sensor_hubs[i]) { |
| 436 | msg->hdr.device_id = | 431 | msg.hdr.device_id = |
| 437 | client_data->hid_devices[i].dev_id; | 432 | client_data->hid_devices[i].dev_id; |
| 438 | break; | 433 | break; |
| 439 | } | 434 | } |
| @@ -442,8 +437,9 @@ void hid_ishtp_get_report(struct hid_device *hid, int report_id, | |||
| 442 | if (i == client_data->num_hid_devices) | 437 | if (i == client_data->num_hid_devices) |
| 443 | return; | 438 | return; |
| 444 | 439 | ||
| 445 | msg->report_id = report_id; | 440 | msg.report_id = report_id; |
| 446 | rv = ishtp_cl_send(client_data->hid_ishtp_cl, buf, len); | 441 | rv = ishtp_cl_send(client_data->hid_ishtp_cl, (uint8_t *)&msg, |
| 442 | sizeof(msg)); | ||
| 447 | if (rv) | 443 | if (rv) |
| 448 | hid_ishtp_trace(client_data, "%s hid %p send failed\n", | 444 | hid_ishtp_trace(client_data, "%s hid %p send failed\n", |
| 449 | __func__, hid); | 445 | __func__, hid); |
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index f272cdd9bd55..2623a567ffba 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c | |||
| @@ -418,7 +418,7 @@ static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev, | |||
| 418 | list_del(&device->device_link); | 418 | list_del(&device->device_link); |
| 419 | spin_unlock_irqrestore(&dev->device_list_lock, flags); | 419 | spin_unlock_irqrestore(&dev->device_list_lock, flags); |
| 420 | dev_err(dev->devc, "Failed to register ISHTP client device\n"); | 420 | dev_err(dev->devc, "Failed to register ISHTP client device\n"); |
| 421 | kfree(device); | 421 | put_device(&device->dev); |
| 422 | return NULL; | 422 | return NULL; |
| 423 | } | 423 | } |
| 424 | 424 | ||
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index b54ef1ffcbec..ee7a37eb159a 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
| @@ -1213,8 +1213,10 @@ static int __wacom_devm_sysfs_create_group(struct wacom *wacom, | |||
| 1213 | devres->root = root; | 1213 | devres->root = root; |
| 1214 | 1214 | ||
| 1215 | error = sysfs_create_group(devres->root, group); | 1215 | error = sysfs_create_group(devres->root, group); |
| 1216 | if (error) | 1216 | if (error) { |
| 1217 | devres_free(devres); | ||
| 1217 | return error; | 1218 | return error; |
| 1219 | } | ||
| 1218 | 1220 | ||
| 1219 | devres_add(&wacom->hdev->dev, devres); | 1221 | devres_add(&wacom->hdev->dev, devres); |
| 1220 | 1222 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index f249a4428458..6ec307c93ece 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -272,7 +272,7 @@ config SENSORS_K8TEMP | |||
| 272 | 272 | ||
| 273 | config SENSORS_K10TEMP | 273 | config SENSORS_K10TEMP |
| 274 | tristate "AMD Family 10h+ temperature sensor" | 274 | tristate "AMD Family 10h+ temperature sensor" |
| 275 | depends on X86 && PCI | 275 | depends on X86 && PCI && AMD_NB |
| 276 | help | 276 | help |
| 277 | If you say yes here you get support for the temperature | 277 | If you say yes here you get support for the temperature |
| 278 | sensor(s) inside your CPU. Supported are later revisions of | 278 | sensor(s) inside your CPU. Supported are later revisions of |
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index d2cc55e21374..3b73dee6fdc6 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
| 26 | #include <asm/amd_nb.h> | ||
| 26 | #include <asm/processor.h> | 27 | #include <asm/processor.h> |
| 27 | 28 | ||
| 28 | MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor"); | 29 | MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor"); |
| @@ -40,8 +41,8 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); | |||
| 40 | #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 | 41 | #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 |
| 41 | #endif | 42 | #endif |
| 42 | 43 | ||
| 43 | #ifndef PCI_DEVICE_ID_AMD_17H_RR_NB | 44 | #ifndef PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 |
| 44 | #define PCI_DEVICE_ID_AMD_17H_RR_NB 0x15d0 | 45 | #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb |
| 45 | #endif | 46 | #endif |
| 46 | 47 | ||
| 47 | /* CPUID function 0x80000001, ebx */ | 48 | /* CPUID function 0x80000001, ebx */ |
| @@ -63,10 +64,12 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); | |||
| 63 | #define NB_CAP_HTC 0x00000400 | 64 | #define NB_CAP_HTC 0x00000400 |
| 64 | 65 | ||
| 65 | /* | 66 | /* |
| 66 | * For F15h M60h, functionality of REG_REPORTED_TEMPERATURE | 67 | * For F15h M60h and M70h, REG_HARDWARE_THERMAL_CONTROL |
| 67 | * has been moved to D0F0xBC_xD820_0CA4 [Reported Temperature | 68 | * and REG_REPORTED_TEMPERATURE have been moved to |
| 68 | * Control] | 69 | * D0F0xBC_xD820_0C64 [Hardware Temperature Control] |
| 70 | * D0F0xBC_xD820_0CA4 [Reported Temperature Control] | ||
| 69 | */ | 71 | */ |
| 72 | #define F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET 0xd8200c64 | ||
| 70 | #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4 | 73 | #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4 |
| 71 | 74 | ||
| 72 | /* F17h M01h Access througn SMN */ | 75 | /* F17h M01h Access througn SMN */ |
| @@ -74,6 +77,7 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); | |||
| 74 | 77 | ||
| 75 | struct k10temp_data { | 78 | struct k10temp_data { |
| 76 | struct pci_dev *pdev; | 79 | struct pci_dev *pdev; |
| 80 | void (*read_htcreg)(struct pci_dev *pdev, u32 *regval); | ||
| 77 | void (*read_tempreg)(struct pci_dev *pdev, u32 *regval); | 81 | void (*read_tempreg)(struct pci_dev *pdev, u32 *regval); |
| 78 | int temp_offset; | 82 | int temp_offset; |
| 79 | u32 temp_adjust_mask; | 83 | u32 temp_adjust_mask; |
| @@ -98,6 +102,11 @@ static const struct tctl_offset tctl_offset_table[] = { | |||
| 98 | { 0x17, "AMD Ryzen Threadripper 1910", 10000 }, | 102 | { 0x17, "AMD Ryzen Threadripper 1910", 10000 }, |
| 99 | }; | 103 | }; |
| 100 | 104 | ||
| 105 | static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval) | ||
| 106 | { | ||
| 107 | pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval); | ||
| 108 | } | ||
| 109 | |||
| 101 | static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval) | 110 | static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval) |
| 102 | { | 111 | { |
| 103 | pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval); | 112 | pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval); |
| @@ -114,6 +123,12 @@ static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn, | |||
| 114 | mutex_unlock(&nb_smu_ind_mutex); | 123 | mutex_unlock(&nb_smu_ind_mutex); |
| 115 | } | 124 | } |
| 116 | 125 | ||
| 126 | static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval) | ||
| 127 | { | ||
| 128 | amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, | ||
| 129 | F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET, regval); | ||
| 130 | } | ||
| 131 | |||
| 117 | static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval) | 132 | static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval) |
| 118 | { | 133 | { |
| 119 | amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, | 134 | amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, |
| @@ -122,8 +137,8 @@ static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval) | |||
| 122 | 137 | ||
| 123 | static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval) | 138 | static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval) |
| 124 | { | 139 | { |
| 125 | amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0x60, | 140 | amd_smn_read(amd_pci_dev_to_node_id(pdev), |
| 126 | F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval); | 141 | F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval); |
| 127 | } | 142 | } |
| 128 | 143 | ||
| 129 | static ssize_t temp1_input_show(struct device *dev, | 144 | static ssize_t temp1_input_show(struct device *dev, |
| @@ -160,8 +175,7 @@ static ssize_t show_temp_crit(struct device *dev, | |||
| 160 | u32 regval; | 175 | u32 regval; |
| 161 | int value; | 176 | int value; |
| 162 | 177 | ||
| 163 | pci_read_config_dword(data->pdev, | 178 | data->read_htcreg(data->pdev, ®val); |
| 164 | REG_HARDWARE_THERMAL_CONTROL, ®val); | ||
| 165 | value = ((regval >> 16) & 0x7f) * 500 + 52000; | 179 | value = ((regval >> 16) & 0x7f) * 500 + 52000; |
| 166 | if (show_hyst) | 180 | if (show_hyst) |
| 167 | value -= ((regval >> 24) & 0xf) * 500; | 181 | value -= ((regval >> 24) & 0xf) * 500; |
| @@ -181,13 +195,18 @@ static umode_t k10temp_is_visible(struct kobject *kobj, | |||
| 181 | struct pci_dev *pdev = data->pdev; | 195 | struct pci_dev *pdev = data->pdev; |
| 182 | 196 | ||
| 183 | if (index >= 2) { | 197 | if (index >= 2) { |
| 184 | u32 reg_caps, reg_htc; | 198 | u32 reg; |
| 199 | |||
| 200 | if (!data->read_htcreg) | ||
| 201 | return 0; | ||
| 185 | 202 | ||
| 186 | pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES, | 203 | pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES, |
| 187 | ®_caps); | 204 | ®); |
| 188 | pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, | 205 | if (!(reg & NB_CAP_HTC)) |
| 189 | ®_htc); | 206 | return 0; |
| 190 | if (!(reg_caps & NB_CAP_HTC) || !(reg_htc & HTC_ENABLE)) | 207 | |
| 208 | data->read_htcreg(data->pdev, ®); | ||
| 209 | if (!(reg & HTC_ENABLE)) | ||
| 191 | return 0; | 210 | return 0; |
| 192 | } | 211 | } |
| 193 | return attr->mode; | 212 | return attr->mode; |
| @@ -268,11 +287,13 @@ static int k10temp_probe(struct pci_dev *pdev, | |||
| 268 | 287 | ||
| 269 | if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 || | 288 | if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 || |
| 270 | boot_cpu_data.x86_model == 0x70)) { | 289 | boot_cpu_data.x86_model == 0x70)) { |
| 290 | data->read_htcreg = read_htcreg_nb_f15; | ||
| 271 | data->read_tempreg = read_tempreg_nb_f15; | 291 | data->read_tempreg = read_tempreg_nb_f15; |
| 272 | } else if (boot_cpu_data.x86 == 0x17) { | 292 | } else if (boot_cpu_data.x86 == 0x17) { |
| 273 | data->temp_adjust_mask = 0x80000; | 293 | data->temp_adjust_mask = 0x80000; |
| 274 | data->read_tempreg = read_tempreg_nb_f17; | 294 | data->read_tempreg = read_tempreg_nb_f17; |
| 275 | } else { | 295 | } else { |
| 296 | data->read_htcreg = read_htcreg_pci; | ||
| 276 | data->read_tempreg = read_tempreg_pci; | 297 | data->read_tempreg = read_tempreg_pci; |
| 277 | } | 298 | } |
| 278 | 299 | ||
| @@ -302,7 +323,7 @@ static const struct pci_device_id k10temp_id_table[] = { | |||
| 302 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, | 323 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, |
| 303 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, | 324 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, |
| 304 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, | 325 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, |
| 305 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_RR_NB) }, | 326 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) }, |
| 306 | {} | 327 | {} |
| 307 | }; | 328 | }; |
| 308 | MODULE_DEVICE_TABLE(pci, k10temp_id_table); | 329 | MODULE_DEVICE_TABLE(pci, k10temp_id_table); |
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index fd36c39ddf4e..0cdba29ae0a9 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c | |||
| @@ -209,7 +209,10 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) | |||
| 209 | i2c_dw_disable_int(dev); | 209 | i2c_dw_disable_int(dev); |
| 210 | 210 | ||
| 211 | /* Enable the adapter */ | 211 | /* Enable the adapter */ |
| 212 | __i2c_dw_enable_and_wait(dev, true); | 212 | __i2c_dw_enable(dev, true); |
| 213 | |||
| 214 | /* Dummy read to avoid the register getting stuck on Bay Trail */ | ||
| 215 | dw_readl(dev, DW_IC_ENABLE_STATUS); | ||
| 213 | 216 | ||
| 214 | /* Clear and enable interrupts */ | 217 | /* Clear and enable interrupts */ |
| 215 | dw_readl(dev, DW_IC_CLR_INTR); | 218 | dw_readl(dev, DW_IC_CLR_INTR); |
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index 2aa0e83174c5..dae8ac618a52 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c | |||
| @@ -564,10 +564,10 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap, | |||
| 564 | * TODO: We could potentially loop and retry in the case | 564 | * TODO: We could potentially loop and retry in the case |
| 565 | * of MSP_TWI_XFER_TIMEOUT. | 565 | * of MSP_TWI_XFER_TIMEOUT. |
| 566 | */ | 566 | */ |
| 567 | return -1; | 567 | return -EIO; |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | return 0; | 570 | return num; |
| 571 | } | 571 | } |
| 572 | 572 | ||
| 573 | static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter) | 573 | static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter) |
diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c index e4be86b3de9a..7235c7302bb7 100644 --- a/drivers/i2c/busses/i2c-viperboard.c +++ b/drivers/i2c/busses/i2c-viperboard.c | |||
| @@ -337,7 +337,7 @@ static int vprbrd_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs, | |||
| 337 | } | 337 | } |
| 338 | mutex_unlock(&vb->lock); | 338 | mutex_unlock(&vb->lock); |
| 339 | } | 339 | } |
| 340 | return 0; | 340 | return num; |
| 341 | error: | 341 | error: |
| 342 | mutex_unlock(&vb->lock); | 342 | mutex_unlock(&vb->lock); |
| 343 | return error; | 343 | return error; |
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index a9126b3cda61..7c3b4740b94b 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c | |||
| @@ -445,10 +445,17 @@ static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, | |||
| 445 | msgs[1].buf = buffer; | 445 | msgs[1].buf = buffer; |
| 446 | 446 | ||
| 447 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | 447 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); |
| 448 | if (ret < 0) | 448 | if (ret < 0) { |
| 449 | dev_err(&client->adapter->dev, "i2c read failed\n"); | 449 | /* Getting a NACK is unfortunately normal with some DSTDs */ |
| 450 | else | 450 | if (ret == -EREMOTEIO) |
| 451 | dev_dbg(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n", | ||
| 452 | data_len, client->addr, cmd, ret); | ||
| 453 | else | ||
| 454 | dev_err(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n", | ||
| 455 | data_len, client->addr, cmd, ret); | ||
| 456 | } else { | ||
| 451 | memcpy(data, buffer, data_len); | 457 | memcpy(data, buffer, data_len); |
| 458 | } | ||
| 452 | 459 | ||
| 453 | kfree(buffer); | 460 | kfree(buffer); |
| 454 | return ret; | 461 | return ret; |
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index ee270e065ba9..2a972ed6851b 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig | |||
| @@ -61,9 +61,12 @@ config INFINIBAND_ON_DEMAND_PAGING | |||
| 61 | pages on demand instead. | 61 | pages on demand instead. |
| 62 | 62 | ||
| 63 | config INFINIBAND_ADDR_TRANS | 63 | config INFINIBAND_ADDR_TRANS |
| 64 | bool | 64 | bool "RDMA/CM" |
| 65 | depends on INFINIBAND | 65 | depends on INFINIBAND |
| 66 | default y | 66 | default y |
| 67 | ---help--- | ||
| 68 | Support for RDMA communication manager (CM). | ||
| 69 | This allows for a generic connection abstraction over RDMA. | ||
| 67 | 70 | ||
| 68 | config INFINIBAND_ADDR_TRANS_CONFIGFS | 71 | config INFINIBAND_ADDR_TRANS_CONFIGFS |
| 69 | bool | 72 | bool |
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index e337b08de2ff..fb2d347f760f 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c | |||
| @@ -291,14 +291,18 @@ static int find_gid(struct ib_gid_table *table, const union ib_gid *gid, | |||
| 291 | * so lookup free slot only if requested. | 291 | * so lookup free slot only if requested. |
| 292 | */ | 292 | */ |
| 293 | if (pempty && empty < 0) { | 293 | if (pempty && empty < 0) { |
| 294 | if (data->props & GID_TABLE_ENTRY_INVALID) { | 294 | if (data->props & GID_TABLE_ENTRY_INVALID && |
| 295 | /* Found an invalid (free) entry; allocate it */ | 295 | (default_gid == |
| 296 | if (data->props & GID_TABLE_ENTRY_DEFAULT) { | 296 | !!(data->props & GID_TABLE_ENTRY_DEFAULT))) { |
| 297 | if (default_gid) | 297 | /* |
| 298 | empty = curr_index; | 298 | * Found an invalid (free) entry; allocate it. |
| 299 | } else { | 299 | * If default GID is requested, then our |
| 300 | empty = curr_index; | 300 | * found slot must be one of the DEFAULT |
| 301 | } | 301 | * reserved slots or we fail. |
| 302 | * This ensures that only DEFAULT reserved | ||
| 303 | * slots are used for default property GIDs. | ||
| 304 | */ | ||
| 305 | empty = curr_index; | ||
| 302 | } | 306 | } |
| 303 | } | 307 | } |
| 304 | 308 | ||
| @@ -420,8 +424,10 @@ int ib_cache_gid_add(struct ib_device *ib_dev, u8 port, | |||
| 420 | return ret; | 424 | return ret; |
| 421 | } | 425 | } |
| 422 | 426 | ||
| 423 | int ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | 427 | static int |
| 424 | union ib_gid *gid, struct ib_gid_attr *attr) | 428 | _ib_cache_gid_del(struct ib_device *ib_dev, u8 port, |
| 429 | union ib_gid *gid, struct ib_gid_attr *attr, | ||
| 430 | unsigned long mask, bool default_gid) | ||
| 425 | { | 431 | { |
| 426 | struct ib_gid_table *table; | 432 | struct ib_gid_table *table; |
| 427 | int ret = 0; | 433 | int ret = 0; |
| @@ -431,11 +437,7 @@ int ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | |||
| 431 | 437 | ||
| 432 | mutex_lock(&table->lock); | 438 | mutex_lock(&table->lock); |
| 433 | 439 | ||
| 434 | ix = find_gid(table, gid, attr, false, | 440 | ix = find_gid(table, gid, attr, default_gid, mask, NULL); |
| 435 | GID_ATTR_FIND_MASK_GID | | ||
| 436 | GID_ATTR_FIND_MASK_GID_TYPE | | ||
| 437 | GID_ATTR_FIND_MASK_NETDEV, | ||
| 438 | NULL); | ||
| 439 | if (ix < 0) { | 441 | if (ix < 0) { |
| 440 | ret = -EINVAL; | 442 | ret = -EINVAL; |
| 441 | goto out_unlock; | 443 | goto out_unlock; |
| @@ -452,6 +454,17 @@ out_unlock: | |||
| 452 | return ret; | 454 | return ret; |
| 453 | } | 455 | } |
| 454 | 456 | ||
| 457 | int ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | ||
| 458 | union ib_gid *gid, struct ib_gid_attr *attr) | ||
| 459 | { | ||
| 460 | unsigned long mask = GID_ATTR_FIND_MASK_GID | | ||
| 461 | GID_ATTR_FIND_MASK_GID_TYPE | | ||
| 462 | GID_ATTR_FIND_MASK_DEFAULT | | ||
| 463 | GID_ATTR_FIND_MASK_NETDEV; | ||
| 464 | |||
| 465 | return _ib_cache_gid_del(ib_dev, port, gid, attr, mask, false); | ||
| 466 | } | ||
| 467 | |||
| 455 | int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port, | 468 | int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port, |
| 456 | struct net_device *ndev) | 469 | struct net_device *ndev) |
| 457 | { | 470 | { |
| @@ -728,7 +741,7 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, | |||
| 728 | unsigned long gid_type_mask, | 741 | unsigned long gid_type_mask, |
| 729 | enum ib_cache_gid_default_mode mode) | 742 | enum ib_cache_gid_default_mode mode) |
| 730 | { | 743 | { |
| 731 | union ib_gid gid; | 744 | union ib_gid gid = { }; |
| 732 | struct ib_gid_attr gid_attr; | 745 | struct ib_gid_attr gid_attr; |
| 733 | struct ib_gid_table *table; | 746 | struct ib_gid_table *table; |
| 734 | unsigned int gid_type; | 747 | unsigned int gid_type; |
| @@ -736,7 +749,9 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, | |||
| 736 | 749 | ||
| 737 | table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid; | 750 | table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid; |
| 738 | 751 | ||
| 739 | make_default_gid(ndev, &gid); | 752 | mask = GID_ATTR_FIND_MASK_GID_TYPE | |
| 753 | GID_ATTR_FIND_MASK_DEFAULT | | ||
| 754 | GID_ATTR_FIND_MASK_NETDEV; | ||
| 740 | memset(&gid_attr, 0, sizeof(gid_attr)); | 755 | memset(&gid_attr, 0, sizeof(gid_attr)); |
| 741 | gid_attr.ndev = ndev; | 756 | gid_attr.ndev = ndev; |
| 742 | 757 | ||
| @@ -747,12 +762,12 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, | |||
| 747 | gid_attr.gid_type = gid_type; | 762 | gid_attr.gid_type = gid_type; |
| 748 | 763 | ||
| 749 | if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) { | 764 | if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) { |
| 750 | mask = GID_ATTR_FIND_MASK_GID_TYPE | | 765 | make_default_gid(ndev, &gid); |
| 751 | GID_ATTR_FIND_MASK_DEFAULT; | ||
| 752 | __ib_cache_gid_add(ib_dev, port, &gid, | 766 | __ib_cache_gid_add(ib_dev, port, &gid, |
| 753 | &gid_attr, mask, true); | 767 | &gid_attr, mask, true); |
| 754 | } else if (mode == IB_CACHE_GID_DEFAULT_MODE_DELETE) { | 768 | } else if (mode == IB_CACHE_GID_DEFAULT_MODE_DELETE) { |
| 755 | ib_cache_gid_del(ib_dev, port, &gid, &gid_attr); | 769 | _ib_cache_gid_del(ib_dev, port, &gid, |
| 770 | &gid_attr, mask, true); | ||
| 756 | } | 771 | } |
| 757 | } | 772 | } |
| 758 | } | 773 | } |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 51a641002e10..a693fcd4c513 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -382,6 +382,8 @@ struct cma_hdr { | |||
| 382 | #define CMA_VERSION 0x00 | 382 | #define CMA_VERSION 0x00 |
| 383 | 383 | ||
| 384 | struct cma_req_info { | 384 | struct cma_req_info { |
| 385 | struct sockaddr_storage listen_addr_storage; | ||
| 386 | struct sockaddr_storage src_addr_storage; | ||
| 385 | struct ib_device *device; | 387 | struct ib_device *device; |
| 386 | int port; | 388 | int port; |
| 387 | union ib_gid local_gid; | 389 | union ib_gid local_gid; |
| @@ -866,7 +868,6 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv, | |||
| 866 | { | 868 | { |
| 867 | struct ib_qp_attr qp_attr; | 869 | struct ib_qp_attr qp_attr; |
| 868 | int qp_attr_mask, ret; | 870 | int qp_attr_mask, ret; |
| 869 | union ib_gid sgid; | ||
| 870 | 871 | ||
| 871 | mutex_lock(&id_priv->qp_mutex); | 872 | mutex_lock(&id_priv->qp_mutex); |
| 872 | if (!id_priv->id.qp) { | 873 | if (!id_priv->id.qp) { |
| @@ -889,12 +890,6 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv, | |||
| 889 | if (ret) | 890 | if (ret) |
| 890 | goto out; | 891 | goto out; |
| 891 | 892 | ||
| 892 | ret = ib_query_gid(id_priv->id.device, id_priv->id.port_num, | ||
| 893 | rdma_ah_read_grh(&qp_attr.ah_attr)->sgid_index, | ||
| 894 | &sgid, NULL); | ||
| 895 | if (ret) | ||
| 896 | goto out; | ||
| 897 | |||
| 898 | BUG_ON(id_priv->cma_dev->device != id_priv->id.device); | 893 | BUG_ON(id_priv->cma_dev->device != id_priv->id.device); |
| 899 | 894 | ||
| 900 | if (conn_param) | 895 | if (conn_param) |
| @@ -1340,11 +1335,11 @@ static bool validate_net_dev(struct net_device *net_dev, | |||
| 1340 | } | 1335 | } |
| 1341 | 1336 | ||
| 1342 | static struct net_device *cma_get_net_dev(struct ib_cm_event *ib_event, | 1337 | static struct net_device *cma_get_net_dev(struct ib_cm_event *ib_event, |
| 1343 | const struct cma_req_info *req) | 1338 | struct cma_req_info *req) |
| 1344 | { | 1339 | { |
| 1345 | struct sockaddr_storage listen_addr_storage, src_addr_storage; | 1340 | struct sockaddr *listen_addr = |
| 1346 | struct sockaddr *listen_addr = (struct sockaddr *)&listen_addr_storage, | 1341 | (struct sockaddr *)&req->listen_addr_storage; |
| 1347 | *src_addr = (struct sockaddr *)&src_addr_storage; | 1342 | struct sockaddr *src_addr = (struct sockaddr *)&req->src_addr_storage; |
| 1348 | struct net_device *net_dev; | 1343 | struct net_device *net_dev; |
| 1349 | const union ib_gid *gid = req->has_gid ? &req->local_gid : NULL; | 1344 | const union ib_gid *gid = req->has_gid ? &req->local_gid : NULL; |
| 1350 | int err; | 1345 | int err; |
| @@ -1359,11 +1354,6 @@ static struct net_device *cma_get_net_dev(struct ib_cm_event *ib_event, | |||
| 1359 | if (!net_dev) | 1354 | if (!net_dev) |
| 1360 | return ERR_PTR(-ENODEV); | 1355 | return ERR_PTR(-ENODEV); |
| 1361 | 1356 | ||
| 1362 | if (!validate_net_dev(net_dev, listen_addr, src_addr)) { | ||
| 1363 | dev_put(net_dev); | ||
| 1364 | return ERR_PTR(-EHOSTUNREACH); | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | return net_dev; | 1357 | return net_dev; |
| 1368 | } | 1358 | } |
| 1369 | 1359 | ||
| @@ -1490,15 +1480,51 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id, | |||
| 1490 | } | 1480 | } |
| 1491 | } | 1481 | } |
| 1492 | 1482 | ||
| 1483 | /* | ||
| 1484 | * Net namespace might be getting deleted while route lookup, | ||
| 1485 | * cm_id lookup is in progress. Therefore, perform netdevice | ||
| 1486 | * validation, cm_id lookup under rcu lock. | ||
| 1487 | * RCU lock along with netdevice state check, synchronizes with | ||
| 1488 | * netdevice migrating to different net namespace and also avoids | ||
| 1489 | * case where net namespace doesn't get deleted while lookup is in | ||
| 1490 | * progress. | ||
| 1491 | * If the device state is not IFF_UP, its properties such as ifindex | ||
| 1492 | * and nd_net cannot be trusted to remain valid without rcu lock. | ||
| 1493 | * net/core/dev.c change_net_namespace() ensures to synchronize with | ||
| 1494 | * ongoing operations on net device after device is closed using | ||
| 1495 | * synchronize_net(). | ||
| 1496 | */ | ||
| 1497 | rcu_read_lock(); | ||
| 1498 | if (*net_dev) { | ||
| 1499 | /* | ||
| 1500 | * If netdevice is down, it is likely that it is administratively | ||
| 1501 | * down or it might be migrating to different namespace. | ||
| 1502 | * In that case avoid further processing, as the net namespace | ||
| 1503 | * or ifindex may change. | ||
| 1504 | */ | ||
| 1505 | if (((*net_dev)->flags & IFF_UP) == 0) { | ||
| 1506 | id_priv = ERR_PTR(-EHOSTUNREACH); | ||
| 1507 | goto err; | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | if (!validate_net_dev(*net_dev, | ||
| 1511 | (struct sockaddr *)&req.listen_addr_storage, | ||
| 1512 | (struct sockaddr *)&req.src_addr_storage)) { | ||
| 1513 | id_priv = ERR_PTR(-EHOSTUNREACH); | ||
| 1514 | goto err; | ||
| 1515 | } | ||
| 1516 | } | ||
| 1517 | |||
| 1493 | bind_list = cma_ps_find(*net_dev ? dev_net(*net_dev) : &init_net, | 1518 | bind_list = cma_ps_find(*net_dev ? dev_net(*net_dev) : &init_net, |
| 1494 | rdma_ps_from_service_id(req.service_id), | 1519 | rdma_ps_from_service_id(req.service_id), |
| 1495 | cma_port_from_service_id(req.service_id)); | 1520 | cma_port_from_service_id(req.service_id)); |
| 1496 | id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev); | 1521 | id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev); |
| 1522 | err: | ||
| 1523 | rcu_read_unlock(); | ||
| 1497 | if (IS_ERR(id_priv) && *net_dev) { | 1524 | if (IS_ERR(id_priv) && *net_dev) { |
| 1498 | dev_put(*net_dev); | 1525 | dev_put(*net_dev); |
| 1499 | *net_dev = NULL; | 1526 | *net_dev = NULL; |
| 1500 | } | 1527 | } |
| 1501 | |||
| 1502 | return id_priv; | 1528 | return id_priv; |
| 1503 | } | 1529 | } |
| 1504 | 1530 | ||
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index 9821ae900f6d..da12da1c36f6 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c | |||
| @@ -114,7 +114,7 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, | |||
| 114 | struct sockaddr_storage *mapped_sockaddr, | 114 | struct sockaddr_storage *mapped_sockaddr, |
| 115 | u8 nl_client) | 115 | u8 nl_client) |
| 116 | { | 116 | { |
| 117 | struct hlist_head *hash_bucket_head; | 117 | struct hlist_head *hash_bucket_head = NULL; |
| 118 | struct iwpm_mapping_info *map_info; | 118 | struct iwpm_mapping_info *map_info; |
| 119 | unsigned long flags; | 119 | unsigned long flags; |
| 120 | int ret = -EINVAL; | 120 | int ret = -EINVAL; |
| @@ -142,6 +142,9 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, | |||
| 142 | } | 142 | } |
| 143 | } | 143 | } |
| 144 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); | 144 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); |
| 145 | |||
| 146 | if (!hash_bucket_head) | ||
| 147 | kfree(map_info); | ||
| 145 | return ret; | 148 | return ret; |
| 146 | } | 149 | } |
| 147 | 150 | ||
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index c50596f7f98a..b28452a55a08 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
| @@ -59,7 +59,7 @@ module_param_named(recv_queue_size, mad_recvq_size, int, 0444); | |||
| 59 | MODULE_PARM_DESC(recv_queue_size, "Size of receive queue in number of work requests"); | 59 | MODULE_PARM_DESC(recv_queue_size, "Size of receive queue in number of work requests"); |
| 60 | 60 | ||
| 61 | static struct list_head ib_mad_port_list; | 61 | static struct list_head ib_mad_port_list; |
| 62 | static u32 ib_mad_client_id = 0; | 62 | static atomic_t ib_mad_client_id = ATOMIC_INIT(0); |
| 63 | 63 | ||
| 64 | /* Port list lock */ | 64 | /* Port list lock */ |
| 65 | static DEFINE_SPINLOCK(ib_mad_port_list_lock); | 65 | static DEFINE_SPINLOCK(ib_mad_port_list_lock); |
| @@ -377,7 +377,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | spin_lock_irqsave(&port_priv->reg_lock, flags); | 379 | spin_lock_irqsave(&port_priv->reg_lock, flags); |
| 380 | mad_agent_priv->agent.hi_tid = ++ib_mad_client_id; | 380 | mad_agent_priv->agent.hi_tid = atomic_inc_return(&ib_mad_client_id); |
| 381 | 381 | ||
| 382 | /* | 382 | /* |
| 383 | * Make sure MAD registration (if supplied) | 383 | * Make sure MAD registration (if supplied) |
diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c index cc2966380c0c..c0e4fd55e2cc 100644 --- a/drivers/infiniband/core/roce_gid_mgmt.c +++ b/drivers/infiniband/core/roce_gid_mgmt.c | |||
| @@ -255,6 +255,7 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev, | |||
| 255 | struct net_device *rdma_ndev) | 255 | struct net_device *rdma_ndev) |
| 256 | { | 256 | { |
| 257 | struct net_device *real_dev = rdma_vlan_dev_real_dev(event_ndev); | 257 | struct net_device *real_dev = rdma_vlan_dev_real_dev(event_ndev); |
| 258 | unsigned long gid_type_mask; | ||
| 258 | 259 | ||
| 259 | if (!rdma_ndev) | 260 | if (!rdma_ndev) |
| 260 | return; | 261 | return; |
| @@ -264,21 +265,22 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev, | |||
| 264 | 265 | ||
| 265 | rcu_read_lock(); | 266 | rcu_read_lock(); |
| 266 | 267 | ||
| 267 | if (rdma_is_upper_dev_rcu(rdma_ndev, event_ndev) && | 268 | if (((rdma_ndev != event_ndev && |
| 268 | is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) == | 269 | !rdma_is_upper_dev_rcu(rdma_ndev, event_ndev)) || |
| 269 | BONDING_SLAVE_STATE_INACTIVE) { | 270 | is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) |
| 270 | unsigned long gid_type_mask; | 271 | == |
| 271 | 272 | BONDING_SLAVE_STATE_INACTIVE)) { | |
| 272 | rcu_read_unlock(); | 273 | rcu_read_unlock(); |
| 274 | return; | ||
| 275 | } | ||
| 273 | 276 | ||
| 274 | gid_type_mask = roce_gid_type_mask_support(ib_dev, port); | 277 | rcu_read_unlock(); |
| 275 | 278 | ||
| 276 | ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev, | 279 | gid_type_mask = roce_gid_type_mask_support(ib_dev, port); |
| 277 | gid_type_mask, | 280 | |
| 278 | IB_CACHE_GID_DEFAULT_MODE_DELETE); | 281 | ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev, |
| 279 | } else { | 282 | gid_type_mask, |
| 280 | rcu_read_unlock(); | 283 | IB_CACHE_GID_DEFAULT_MODE_DELETE); |
| 281 | } | ||
| 282 | } | 284 | } |
| 283 | 285 | ||
| 284 | static void enum_netdev_ipv4_ips(struct ib_device *ib_dev, | 286 | static void enum_netdev_ipv4_ips(struct ib_device *ib_dev, |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 74329483af6d..eab43b17e9cf 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -159,6 +159,23 @@ static void ucma_put_ctx(struct ucma_context *ctx) | |||
| 159 | complete(&ctx->comp); | 159 | complete(&ctx->comp); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | /* | ||
| 163 | * Same as ucm_get_ctx but requires that ->cm_id->device is valid, eg that the | ||
| 164 | * CM_ID is bound. | ||
| 165 | */ | ||
| 166 | static struct ucma_context *ucma_get_ctx_dev(struct ucma_file *file, int id) | ||
| 167 | { | ||
| 168 | struct ucma_context *ctx = ucma_get_ctx(file, id); | ||
| 169 | |||
| 170 | if (IS_ERR(ctx)) | ||
| 171 | return ctx; | ||
| 172 | if (!ctx->cm_id->device) { | ||
| 173 | ucma_put_ctx(ctx); | ||
| 174 | return ERR_PTR(-EINVAL); | ||
| 175 | } | ||
| 176 | return ctx; | ||
| 177 | } | ||
| 178 | |||
| 162 | static void ucma_close_event_id(struct work_struct *work) | 179 | static void ucma_close_event_id(struct work_struct *work) |
| 163 | { | 180 | { |
| 164 | struct ucma_event *uevent_close = container_of(work, struct ucma_event, close_work); | 181 | struct ucma_event *uevent_close = container_of(work, struct ucma_event, close_work); |
| @@ -683,7 +700,7 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, | |||
| 683 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 700 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 684 | return -EFAULT; | 701 | return -EFAULT; |
| 685 | 702 | ||
| 686 | if (!rdma_addr_size_in6(&cmd.src_addr) || | 703 | if ((cmd.src_addr.sin6_family && !rdma_addr_size_in6(&cmd.src_addr)) || |
| 687 | !rdma_addr_size_in6(&cmd.dst_addr)) | 704 | !rdma_addr_size_in6(&cmd.dst_addr)) |
| 688 | return -EINVAL; | 705 | return -EINVAL; |
| 689 | 706 | ||
| @@ -734,7 +751,7 @@ static ssize_t ucma_resolve_route(struct ucma_file *file, | |||
| 734 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 751 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 735 | return -EFAULT; | 752 | return -EFAULT; |
| 736 | 753 | ||
| 737 | ctx = ucma_get_ctx(file, cmd.id); | 754 | ctx = ucma_get_ctx_dev(file, cmd.id); |
| 738 | if (IS_ERR(ctx)) | 755 | if (IS_ERR(ctx)) |
| 739 | return PTR_ERR(ctx); | 756 | return PTR_ERR(ctx); |
| 740 | 757 | ||
| @@ -1050,7 +1067,7 @@ static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf, | |||
| 1050 | if (!cmd.conn_param.valid) | 1067 | if (!cmd.conn_param.valid) |
| 1051 | return -EINVAL; | 1068 | return -EINVAL; |
| 1052 | 1069 | ||
| 1053 | ctx = ucma_get_ctx(file, cmd.id); | 1070 | ctx = ucma_get_ctx_dev(file, cmd.id); |
| 1054 | if (IS_ERR(ctx)) | 1071 | if (IS_ERR(ctx)) |
| 1055 | return PTR_ERR(ctx); | 1072 | return PTR_ERR(ctx); |
| 1056 | 1073 | ||
| @@ -1092,7 +1109,7 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, | |||
| 1092 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 1109 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1093 | return -EFAULT; | 1110 | return -EFAULT; |
| 1094 | 1111 | ||
| 1095 | ctx = ucma_get_ctx(file, cmd.id); | 1112 | ctx = ucma_get_ctx_dev(file, cmd.id); |
| 1096 | if (IS_ERR(ctx)) | 1113 | if (IS_ERR(ctx)) |
| 1097 | return PTR_ERR(ctx); | 1114 | return PTR_ERR(ctx); |
| 1098 | 1115 | ||
| @@ -1120,7 +1137,7 @@ static ssize_t ucma_reject(struct ucma_file *file, const char __user *inbuf, | |||
| 1120 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 1137 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1121 | return -EFAULT; | 1138 | return -EFAULT; |
| 1122 | 1139 | ||
| 1123 | ctx = ucma_get_ctx(file, cmd.id); | 1140 | ctx = ucma_get_ctx_dev(file, cmd.id); |
| 1124 | if (IS_ERR(ctx)) | 1141 | if (IS_ERR(ctx)) |
| 1125 | return PTR_ERR(ctx); | 1142 | return PTR_ERR(ctx); |
| 1126 | 1143 | ||
| @@ -1139,7 +1156,7 @@ static ssize_t ucma_disconnect(struct ucma_file *file, const char __user *inbuf, | |||
| 1139 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 1156 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1140 | return -EFAULT; | 1157 | return -EFAULT; |
| 1141 | 1158 | ||
| 1142 | ctx = ucma_get_ctx(file, cmd.id); | 1159 | ctx = ucma_get_ctx_dev(file, cmd.id); |
| 1143 | if (IS_ERR(ctx)) | 1160 | if (IS_ERR(ctx)) |
| 1144 | return PTR_ERR(ctx); | 1161 | return PTR_ERR(ctx); |
| 1145 | 1162 | ||
| @@ -1167,15 +1184,10 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, | |||
| 1167 | if (cmd.qp_state > IB_QPS_ERR) | 1184 | if (cmd.qp_state > IB_QPS_ERR) |
| 1168 | return -EINVAL; | 1185 | return -EINVAL; |
| 1169 | 1186 | ||
| 1170 | ctx = ucma_get_ctx(file, cmd.id); | 1187 | ctx = ucma_get_ctx_dev(file, cmd.id); |
| 1171 | if (IS_ERR(ctx)) | 1188 | if (IS_ERR(ctx)) |
| 1172 | return PTR_ERR(ctx); | 1189 | return PTR_ERR(ctx); |
| 1173 | 1190 | ||
| 1174 | if (!ctx->cm_id->device) { | ||
| 1175 | ret = -EINVAL; | ||
| 1176 | goto out; | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | resp.qp_attr_mask = 0; | 1191 | resp.qp_attr_mask = 0; |
| 1180 | memset(&qp_attr, 0, sizeof qp_attr); | 1192 | memset(&qp_attr, 0, sizeof qp_attr); |
| 1181 | qp_attr.qp_state = cmd.qp_state; | 1193 | qp_attr.qp_state = cmd.qp_state; |
| @@ -1316,13 +1328,13 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, | |||
| 1316 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 1328 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1317 | return -EFAULT; | 1329 | return -EFAULT; |
| 1318 | 1330 | ||
| 1331 | if (unlikely(cmd.optlen > KMALLOC_MAX_SIZE)) | ||
| 1332 | return -EINVAL; | ||
| 1333 | |||
| 1319 | ctx = ucma_get_ctx(file, cmd.id); | 1334 | ctx = ucma_get_ctx(file, cmd.id); |
| 1320 | if (IS_ERR(ctx)) | 1335 | if (IS_ERR(ctx)) |
| 1321 | return PTR_ERR(ctx); | 1336 | return PTR_ERR(ctx); |
| 1322 | 1337 | ||
| 1323 | if (unlikely(cmd.optlen > KMALLOC_MAX_SIZE)) | ||
| 1324 | return -EINVAL; | ||
| 1325 | |||
| 1326 | optval = memdup_user(u64_to_user_ptr(cmd.optval), | 1338 | optval = memdup_user(u64_to_user_ptr(cmd.optval), |
| 1327 | cmd.optlen); | 1339 | cmd.optlen); |
| 1328 | if (IS_ERR(optval)) { | 1340 | if (IS_ERR(optval)) { |
| @@ -1384,7 +1396,7 @@ static ssize_t ucma_process_join(struct ucma_file *file, | |||
| 1384 | else | 1396 | else |
| 1385 | return -EINVAL; | 1397 | return -EINVAL; |
| 1386 | 1398 | ||
| 1387 | ctx = ucma_get_ctx(file, cmd->id); | 1399 | ctx = ucma_get_ctx_dev(file, cmd->id); |
| 1388 | if (IS_ERR(ctx)) | 1400 | if (IS_ERR(ctx)) |
| 1389 | return PTR_ERR(ctx); | 1401 | return PTR_ERR(ctx); |
| 1390 | 1402 | ||
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 13cb5e4deb86..21a887c9523b 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -691,6 +691,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, | |||
| 691 | 691 | ||
| 692 | mr->device = pd->device; | 692 | mr->device = pd->device; |
| 693 | mr->pd = pd; | 693 | mr->pd = pd; |
| 694 | mr->dm = NULL; | ||
| 694 | mr->uobject = uobj; | 695 | mr->uobject = uobj; |
| 695 | atomic_inc(&pd->usecnt); | 696 | atomic_inc(&pd->usecnt); |
| 696 | mr->res.type = RDMA_RESTRACK_MR; | 697 | mr->res.type = RDMA_RESTRACK_MR; |
| @@ -765,6 +766,11 @@ ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file, | |||
| 765 | 766 | ||
| 766 | mr = uobj->object; | 767 | mr = uobj->object; |
| 767 | 768 | ||
| 769 | if (mr->dm) { | ||
| 770 | ret = -EINVAL; | ||
| 771 | goto put_uobjs; | ||
| 772 | } | ||
| 773 | |||
| 768 | if (cmd.flags & IB_MR_REREG_ACCESS) { | 774 | if (cmd.flags & IB_MR_REREG_ACCESS) { |
| 769 | ret = ib_check_mr_access(cmd.access_flags); | 775 | ret = ib_check_mr_access(cmd.access_flags); |
| 770 | if (ret) | 776 | if (ret) |
diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c index 8c93970dc8f1..8d32c4ae368c 100644 --- a/drivers/infiniband/core/uverbs_ioctl.c +++ b/drivers/infiniband/core/uverbs_ioctl.c | |||
| @@ -234,6 +234,15 @@ static int uverbs_validate_kernel_mandatory(const struct uverbs_method_spec *met | |||
| 234 | return -EINVAL; | 234 | return -EINVAL; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | for (; i < method_spec->num_buckets; i++) { | ||
| 238 | struct uverbs_attr_spec_hash *attr_spec_bucket = | ||
| 239 | method_spec->attr_buckets[i]; | ||
| 240 | |||
| 241 | if (!bitmap_empty(attr_spec_bucket->mandatory_attrs_bitmask, | ||
| 242 | attr_spec_bucket->num_attrs)) | ||
| 243 | return -EINVAL; | ||
| 244 | } | ||
| 245 | |||
| 237 | return 0; | 246 | return 0; |
| 238 | } | 247 | } |
| 239 | 248 | ||
diff --git a/drivers/infiniband/core/uverbs_std_types_flow_action.c b/drivers/infiniband/core/uverbs_std_types_flow_action.c index cbcec3da12f6..b4f016dfa23d 100644 --- a/drivers/infiniband/core/uverbs_std_types_flow_action.c +++ b/drivers/infiniband/core/uverbs_std_types_flow_action.c | |||
| @@ -363,28 +363,28 @@ static int UVERBS_HANDLER(UVERBS_METHOD_FLOW_ACTION_ESP_MODIFY)(struct ib_device | |||
| 363 | 363 | ||
| 364 | static const struct uverbs_attr_spec uverbs_flow_action_esp_keymat[] = { | 364 | static const struct uverbs_attr_spec uverbs_flow_action_esp_keymat[] = { |
| 365 | [IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = { | 365 | [IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = { |
| 366 | .ptr = { | 366 | { .ptr = { |
| 367 | .type = UVERBS_ATTR_TYPE_PTR_IN, | 367 | .type = UVERBS_ATTR_TYPE_PTR_IN, |
| 368 | UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_keymat_aes_gcm), | 368 | UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_keymat_aes_gcm), |
| 369 | .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO, | 369 | .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO, |
| 370 | }, | 370 | } }, |
| 371 | }, | 371 | }, |
| 372 | }; | 372 | }; |
| 373 | 373 | ||
| 374 | static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = { | 374 | static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = { |
| 375 | [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = { | 375 | [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = { |
| 376 | .ptr = { | 376 | { .ptr = { |
| 377 | .type = UVERBS_ATTR_TYPE_PTR_IN, | 377 | .type = UVERBS_ATTR_TYPE_PTR_IN, |
| 378 | /* No need to specify any data */ | 378 | /* No need to specify any data */ |
| 379 | .len = 0, | 379 | .len = 0, |
| 380 | } | 380 | } } |
| 381 | }, | 381 | }, |
| 382 | [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = { | 382 | [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = { |
| 383 | .ptr = { | 383 | { .ptr = { |
| 384 | .type = UVERBS_ATTR_TYPE_PTR_IN, | 384 | .type = UVERBS_ATTR_TYPE_PTR_IN, |
| 385 | UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp, size), | 385 | UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp, size), |
| 386 | .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO, | 386 | .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO, |
| 387 | } | 387 | } } |
| 388 | }, | 388 | }, |
| 389 | }; | 389 | }; |
| 390 | 390 | ||
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 7eff3aeffe01..6ddfb1fade79 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
| @@ -1656,6 +1656,7 @@ struct ib_mr *ib_alloc_mr(struct ib_pd *pd, | |||
| 1656 | if (!IS_ERR(mr)) { | 1656 | if (!IS_ERR(mr)) { |
| 1657 | mr->device = pd->device; | 1657 | mr->device = pd->device; |
| 1658 | mr->pd = pd; | 1658 | mr->pd = pd; |
| 1659 | mr->dm = NULL; | ||
| 1659 | mr->uobject = NULL; | 1660 | mr->uobject = NULL; |
| 1660 | atomic_inc(&pd->usecnt); | 1661 | atomic_inc(&pd->usecnt); |
| 1661 | mr->need_inval = false; | 1662 | mr->need_inval = false; |
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 6f2b26126c64..2be2e1ac1b5f 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c | |||
| @@ -315,7 +315,7 @@ static void advance_oldest_read(struct t4_wq *wq) | |||
| 315 | * Deal with out-of-order and/or completions that complete | 315 | * Deal with out-of-order and/or completions that complete |
| 316 | * prior unsignalled WRs. | 316 | * prior unsignalled WRs. |
| 317 | */ | 317 | */ |
| 318 | void c4iw_flush_hw_cq(struct c4iw_cq *chp) | 318 | void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp) |
| 319 | { | 319 | { |
| 320 | struct t4_cqe *hw_cqe, *swcqe, read_cqe; | 320 | struct t4_cqe *hw_cqe, *swcqe, read_cqe; |
| 321 | struct c4iw_qp *qhp; | 321 | struct c4iw_qp *qhp; |
| @@ -339,6 +339,13 @@ void c4iw_flush_hw_cq(struct c4iw_cq *chp) | |||
| 339 | if (qhp == NULL) | 339 | if (qhp == NULL) |
| 340 | goto next_cqe; | 340 | goto next_cqe; |
| 341 | 341 | ||
| 342 | if (flush_qhp != qhp) { | ||
| 343 | spin_lock(&qhp->lock); | ||
| 344 | |||
| 345 | if (qhp->wq.flushed == 1) | ||
| 346 | goto next_cqe; | ||
| 347 | } | ||
| 348 | |||
| 342 | if (CQE_OPCODE(hw_cqe) == FW_RI_TERMINATE) | 349 | if (CQE_OPCODE(hw_cqe) == FW_RI_TERMINATE) |
| 343 | goto next_cqe; | 350 | goto next_cqe; |
| 344 | 351 | ||
| @@ -390,6 +397,8 @@ void c4iw_flush_hw_cq(struct c4iw_cq *chp) | |||
| 390 | next_cqe: | 397 | next_cqe: |
| 391 | t4_hwcq_consume(&chp->cq); | 398 | t4_hwcq_consume(&chp->cq); |
| 392 | ret = t4_next_hw_cqe(&chp->cq, &hw_cqe); | 399 | ret = t4_next_hw_cqe(&chp->cq, &hw_cqe); |
| 400 | if (qhp && flush_qhp != qhp) | ||
| 401 | spin_unlock(&qhp->lock); | ||
| 393 | } | 402 | } |
| 394 | } | 403 | } |
| 395 | 404 | ||
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index feeb8ee6f4a2..44161ca4d2a8 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
| @@ -875,6 +875,11 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) | |||
| 875 | 875 | ||
| 876 | rdev->status_page->db_off = 0; | 876 | rdev->status_page->db_off = 0; |
| 877 | 877 | ||
| 878 | init_completion(&rdev->rqt_compl); | ||
| 879 | init_completion(&rdev->pbl_compl); | ||
| 880 | kref_init(&rdev->rqt_kref); | ||
| 881 | kref_init(&rdev->pbl_kref); | ||
| 882 | |||
| 878 | return 0; | 883 | return 0; |
| 879 | err_free_status_page_and_wr_log: | 884 | err_free_status_page_and_wr_log: |
| 880 | if (c4iw_wr_log && rdev->wr_log) | 885 | if (c4iw_wr_log && rdev->wr_log) |
| @@ -893,13 +898,15 @@ destroy_resource: | |||
| 893 | 898 | ||
| 894 | static void c4iw_rdev_close(struct c4iw_rdev *rdev) | 899 | static void c4iw_rdev_close(struct c4iw_rdev *rdev) |
| 895 | { | 900 | { |
| 896 | destroy_workqueue(rdev->free_workq); | ||
| 897 | kfree(rdev->wr_log); | 901 | kfree(rdev->wr_log); |
| 898 | c4iw_release_dev_ucontext(rdev, &rdev->uctx); | 902 | c4iw_release_dev_ucontext(rdev, &rdev->uctx); |
| 899 | free_page((unsigned long)rdev->status_page); | 903 | free_page((unsigned long)rdev->status_page); |
| 900 | c4iw_pblpool_destroy(rdev); | 904 | c4iw_pblpool_destroy(rdev); |
| 901 | c4iw_rqtpool_destroy(rdev); | 905 | c4iw_rqtpool_destroy(rdev); |
| 906 | wait_for_completion(&rdev->pbl_compl); | ||
| 907 | wait_for_completion(&rdev->rqt_compl); | ||
| 902 | c4iw_ocqp_pool_destroy(rdev); | 908 | c4iw_ocqp_pool_destroy(rdev); |
| 909 | destroy_workqueue(rdev->free_workq); | ||
| 903 | c4iw_destroy_resource(&rdev->resource); | 910 | c4iw_destroy_resource(&rdev->resource); |
| 904 | } | 911 | } |
| 905 | 912 | ||
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index cc929002c05e..831027717121 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
| @@ -185,6 +185,10 @@ struct c4iw_rdev { | |||
| 185 | struct wr_log_entry *wr_log; | 185 | struct wr_log_entry *wr_log; |
| 186 | int wr_log_size; | 186 | int wr_log_size; |
| 187 | struct workqueue_struct *free_workq; | 187 | struct workqueue_struct *free_workq; |
| 188 | struct completion rqt_compl; | ||
| 189 | struct completion pbl_compl; | ||
| 190 | struct kref rqt_kref; | ||
| 191 | struct kref pbl_kref; | ||
| 188 | }; | 192 | }; |
| 189 | 193 | ||
| 190 | static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) | 194 | static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) |
| @@ -1049,7 +1053,7 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size); | |||
| 1049 | void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size); | 1053 | void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size); |
| 1050 | u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size); | 1054 | u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size); |
| 1051 | void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size); | 1055 | void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size); |
| 1052 | void c4iw_flush_hw_cq(struct c4iw_cq *chp); | 1056 | void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp); |
| 1053 | void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count); | 1057 | void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count); |
| 1054 | int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp); | 1058 | int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp); |
| 1055 | int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count); | 1059 | int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count); |
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index de77b6027d69..ae167b686608 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
| @@ -1343,12 +1343,12 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, | |||
| 1343 | qhp->wq.flushed = 1; | 1343 | qhp->wq.flushed = 1; |
| 1344 | t4_set_wq_in_error(&qhp->wq); | 1344 | t4_set_wq_in_error(&qhp->wq); |
| 1345 | 1345 | ||
| 1346 | c4iw_flush_hw_cq(rchp); | 1346 | c4iw_flush_hw_cq(rchp, qhp); |
| 1347 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); | 1347 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); |
| 1348 | rq_flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); | 1348 | rq_flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); |
| 1349 | 1349 | ||
| 1350 | if (schp != rchp) | 1350 | if (schp != rchp) |
| 1351 | c4iw_flush_hw_cq(schp); | 1351 | c4iw_flush_hw_cq(schp, qhp); |
| 1352 | sq_flushed = c4iw_flush_sq(qhp); | 1352 | sq_flushed = c4iw_flush_sq(qhp); |
| 1353 | 1353 | ||
| 1354 | spin_unlock(&qhp->lock); | 1354 | spin_unlock(&qhp->lock); |
diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c index 3cf25997ed2b..0ef25ae05e6f 100644 --- a/drivers/infiniband/hw/cxgb4/resource.c +++ b/drivers/infiniband/hw/cxgb4/resource.c | |||
| @@ -260,12 +260,22 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size) | |||
| 260 | rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT); | 260 | rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT); |
| 261 | if (rdev->stats.pbl.cur > rdev->stats.pbl.max) | 261 | if (rdev->stats.pbl.cur > rdev->stats.pbl.max) |
| 262 | rdev->stats.pbl.max = rdev->stats.pbl.cur; | 262 | rdev->stats.pbl.max = rdev->stats.pbl.cur; |
| 263 | kref_get(&rdev->pbl_kref); | ||
| 263 | } else | 264 | } else |
| 264 | rdev->stats.pbl.fail++; | 265 | rdev->stats.pbl.fail++; |
| 265 | mutex_unlock(&rdev->stats.lock); | 266 | mutex_unlock(&rdev->stats.lock); |
| 266 | return (u32)addr; | 267 | return (u32)addr; |
| 267 | } | 268 | } |
| 268 | 269 | ||
| 270 | static void destroy_pblpool(struct kref *kref) | ||
| 271 | { | ||
| 272 | struct c4iw_rdev *rdev; | ||
| 273 | |||
| 274 | rdev = container_of(kref, struct c4iw_rdev, pbl_kref); | ||
| 275 | gen_pool_destroy(rdev->pbl_pool); | ||
| 276 | complete(&rdev->pbl_compl); | ||
| 277 | } | ||
| 278 | |||
| 269 | void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) | 279 | void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) |
| 270 | { | 280 | { |
| 271 | pr_debug("addr 0x%x size %d\n", addr, size); | 281 | pr_debug("addr 0x%x size %d\n", addr, size); |
| @@ -273,6 +283,7 @@ void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) | |||
| 273 | rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT); | 283 | rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT); |
| 274 | mutex_unlock(&rdev->stats.lock); | 284 | mutex_unlock(&rdev->stats.lock); |
| 275 | gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size); | 285 | gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size); |
| 286 | kref_put(&rdev->pbl_kref, destroy_pblpool); | ||
| 276 | } | 287 | } |
| 277 | 288 | ||
| 278 | int c4iw_pblpool_create(struct c4iw_rdev *rdev) | 289 | int c4iw_pblpool_create(struct c4iw_rdev *rdev) |
| @@ -310,7 +321,7 @@ int c4iw_pblpool_create(struct c4iw_rdev *rdev) | |||
| 310 | 321 | ||
| 311 | void c4iw_pblpool_destroy(struct c4iw_rdev *rdev) | 322 | void c4iw_pblpool_destroy(struct c4iw_rdev *rdev) |
| 312 | { | 323 | { |
| 313 | gen_pool_destroy(rdev->pbl_pool); | 324 | kref_put(&rdev->pbl_kref, destroy_pblpool); |
| 314 | } | 325 | } |
| 315 | 326 | ||
| 316 | /* | 327 | /* |
| @@ -331,12 +342,22 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size) | |||
| 331 | rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT); | 342 | rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT); |
| 332 | if (rdev->stats.rqt.cur > rdev->stats.rqt.max) | 343 | if (rdev->stats.rqt.cur > rdev->stats.rqt.max) |
| 333 | rdev->stats.rqt.max = rdev->stats.rqt.cur; | 344 | rdev->stats.rqt.max = rdev->stats.rqt.cur; |
| 345 | kref_get(&rdev->rqt_kref); | ||
| 334 | } else | 346 | } else |
| 335 | rdev->stats.rqt.fail++; | 347 | rdev->stats.rqt.fail++; |
| 336 | mutex_unlock(&rdev->stats.lock); | 348 | mutex_unlock(&rdev->stats.lock); |
| 337 | return (u32)addr; | 349 | return (u32)addr; |
| 338 | } | 350 | } |
| 339 | 351 | ||
| 352 | static void destroy_rqtpool(struct kref *kref) | ||
| 353 | { | ||
| 354 | struct c4iw_rdev *rdev; | ||
| 355 | |||
| 356 | rdev = container_of(kref, struct c4iw_rdev, rqt_kref); | ||
| 357 | gen_pool_destroy(rdev->rqt_pool); | ||
| 358 | complete(&rdev->rqt_compl); | ||
| 359 | } | ||
| 360 | |||
| 340 | void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) | 361 | void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) |
| 341 | { | 362 | { |
| 342 | pr_debug("addr 0x%x size %d\n", addr, size << 6); | 363 | pr_debug("addr 0x%x size %d\n", addr, size << 6); |
| @@ -344,6 +365,7 @@ void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) | |||
| 344 | rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT); | 365 | rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT); |
| 345 | mutex_unlock(&rdev->stats.lock); | 366 | mutex_unlock(&rdev->stats.lock); |
| 346 | gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6); | 367 | gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6); |
| 368 | kref_put(&rdev->rqt_kref, destroy_rqtpool); | ||
| 347 | } | 369 | } |
| 348 | 370 | ||
| 349 | int c4iw_rqtpool_create(struct c4iw_rdev *rdev) | 371 | int c4iw_rqtpool_create(struct c4iw_rdev *rdev) |
| @@ -380,7 +402,7 @@ int c4iw_rqtpool_create(struct c4iw_rdev *rdev) | |||
| 380 | 402 | ||
| 381 | void c4iw_rqtpool_destroy(struct c4iw_rdev *rdev) | 403 | void c4iw_rqtpool_destroy(struct c4iw_rdev *rdev) |
| 382 | { | 404 | { |
| 383 | gen_pool_destroy(rdev->rqt_pool); | 405 | kref_put(&rdev->rqt_kref, destroy_rqtpool); |
| 384 | } | 406 | } |
| 385 | 407 | ||
| 386 | /* | 408 | /* |
diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c index a97055dd4fbd..b5fab55cc275 100644 --- a/drivers/infiniband/hw/hfi1/affinity.c +++ b/drivers/infiniband/hw/hfi1/affinity.c | |||
| @@ -412,7 +412,6 @@ static void hfi1_cleanup_sdma_notifier(struct hfi1_msix_entry *msix) | |||
| 412 | static int get_irq_affinity(struct hfi1_devdata *dd, | 412 | static int get_irq_affinity(struct hfi1_devdata *dd, |
| 413 | struct hfi1_msix_entry *msix) | 413 | struct hfi1_msix_entry *msix) |
| 414 | { | 414 | { |
| 415 | int ret; | ||
| 416 | cpumask_var_t diff; | 415 | cpumask_var_t diff; |
| 417 | struct hfi1_affinity_node *entry; | 416 | struct hfi1_affinity_node *entry; |
| 418 | struct cpu_mask_set *set = NULL; | 417 | struct cpu_mask_set *set = NULL; |
| @@ -424,10 +423,6 @@ static int get_irq_affinity(struct hfi1_devdata *dd, | |||
| 424 | extra[0] = '\0'; | 423 | extra[0] = '\0'; |
| 425 | cpumask_clear(&msix->mask); | 424 | cpumask_clear(&msix->mask); |
| 426 | 425 | ||
| 427 | ret = zalloc_cpumask_var(&diff, GFP_KERNEL); | ||
| 428 | if (!ret) | ||
| 429 | return -ENOMEM; | ||
| 430 | |||
| 431 | entry = node_affinity_lookup(dd->node); | 426 | entry = node_affinity_lookup(dd->node); |
| 432 | 427 | ||
| 433 | switch (msix->type) { | 428 | switch (msix->type) { |
| @@ -458,6 +453,9 @@ static int get_irq_affinity(struct hfi1_devdata *dd, | |||
| 458 | * finds its CPU here. | 453 | * finds its CPU here. |
| 459 | */ | 454 | */ |
| 460 | if (cpu == -1 && set) { | 455 | if (cpu == -1 && set) { |
| 456 | if (!zalloc_cpumask_var(&diff, GFP_KERNEL)) | ||
| 457 | return -ENOMEM; | ||
| 458 | |||
| 461 | if (cpumask_equal(&set->mask, &set->used)) { | 459 | if (cpumask_equal(&set->mask, &set->used)) { |
| 462 | /* | 460 | /* |
| 463 | * We've used up all the CPUs, bump up the generation | 461 | * We've used up all the CPUs, bump up the generation |
| @@ -469,6 +467,8 @@ static int get_irq_affinity(struct hfi1_devdata *dd, | |||
| 469 | cpumask_andnot(diff, &set->mask, &set->used); | 467 | cpumask_andnot(diff, &set->mask, &set->used); |
| 470 | cpu = cpumask_first(diff); | 468 | cpu = cpumask_first(diff); |
| 471 | cpumask_set_cpu(cpu, &set->used); | 469 | cpumask_set_cpu(cpu, &set->used); |
| 470 | |||
| 471 | free_cpumask_var(diff); | ||
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | cpumask_set_cpu(cpu, &msix->mask); | 474 | cpumask_set_cpu(cpu, &msix->mask); |
| @@ -482,7 +482,6 @@ static int get_irq_affinity(struct hfi1_devdata *dd, | |||
| 482 | hfi1_setup_sdma_notifier(msix); | 482 | hfi1_setup_sdma_notifier(msix); |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | free_cpumask_var(diff); | ||
| 486 | return 0; | 485 | return 0; |
| 487 | } | 486 | } |
| 488 | 487 | ||
diff --git a/drivers/infiniband/hw/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c index 46d1475b2154..bd837a048bf4 100644 --- a/drivers/infiniband/hw/hfi1/driver.c +++ b/drivers/infiniband/hw/hfi1/driver.c | |||
| @@ -433,31 +433,43 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt, | |||
| 433 | bool do_cnp) | 433 | bool do_cnp) |
| 434 | { | 434 | { |
| 435 | struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); | 435 | struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); |
| 436 | struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); | ||
| 436 | struct ib_other_headers *ohdr = pkt->ohdr; | 437 | struct ib_other_headers *ohdr = pkt->ohdr; |
| 437 | struct ib_grh *grh = pkt->grh; | 438 | struct ib_grh *grh = pkt->grh; |
| 438 | u32 rqpn = 0, bth1; | 439 | u32 rqpn = 0, bth1; |
| 439 | u16 pkey, rlid, dlid = ib_get_dlid(pkt->hdr); | 440 | u16 pkey; |
| 441 | u32 rlid, slid, dlid = 0; | ||
| 440 | u8 hdr_type, sc, svc_type; | 442 | u8 hdr_type, sc, svc_type; |
| 441 | bool is_mcast = false; | 443 | bool is_mcast = false; |
| 442 | 444 | ||
| 445 | /* can be called from prescan */ | ||
| 443 | if (pkt->etype == RHF_RCV_TYPE_BYPASS) { | 446 | if (pkt->etype == RHF_RCV_TYPE_BYPASS) { |
| 444 | is_mcast = hfi1_is_16B_mcast(dlid); | 447 | is_mcast = hfi1_is_16B_mcast(dlid); |
| 445 | pkey = hfi1_16B_get_pkey(pkt->hdr); | 448 | pkey = hfi1_16B_get_pkey(pkt->hdr); |
| 446 | sc = hfi1_16B_get_sc(pkt->hdr); | 449 | sc = hfi1_16B_get_sc(pkt->hdr); |
| 450 | dlid = hfi1_16B_get_dlid(pkt->hdr); | ||
| 451 | slid = hfi1_16B_get_slid(pkt->hdr); | ||
| 447 | hdr_type = HFI1_PKT_TYPE_16B; | 452 | hdr_type = HFI1_PKT_TYPE_16B; |
| 448 | } else { | 453 | } else { |
| 449 | is_mcast = (dlid > be16_to_cpu(IB_MULTICAST_LID_BASE)) && | 454 | is_mcast = (dlid > be16_to_cpu(IB_MULTICAST_LID_BASE)) && |
| 450 | (dlid != be16_to_cpu(IB_LID_PERMISSIVE)); | 455 | (dlid != be16_to_cpu(IB_LID_PERMISSIVE)); |
| 451 | pkey = ib_bth_get_pkey(ohdr); | 456 | pkey = ib_bth_get_pkey(ohdr); |
| 452 | sc = hfi1_9B_get_sc5(pkt->hdr, pkt->rhf); | 457 | sc = hfi1_9B_get_sc5(pkt->hdr, pkt->rhf); |
| 458 | dlid = ib_get_dlid(pkt->hdr); | ||
| 459 | slid = ib_get_slid(pkt->hdr); | ||
| 453 | hdr_type = HFI1_PKT_TYPE_9B; | 460 | hdr_type = HFI1_PKT_TYPE_9B; |
| 454 | } | 461 | } |
| 455 | 462 | ||
| 456 | switch (qp->ibqp.qp_type) { | 463 | switch (qp->ibqp.qp_type) { |
| 464 | case IB_QPT_UD: | ||
| 465 | dlid = ppd->lid; | ||
| 466 | rlid = slid; | ||
| 467 | rqpn = ib_get_sqpn(pkt->ohdr); | ||
| 468 | svc_type = IB_CC_SVCTYPE_UD; | ||
| 469 | break; | ||
| 457 | case IB_QPT_SMI: | 470 | case IB_QPT_SMI: |
| 458 | case IB_QPT_GSI: | 471 | case IB_QPT_GSI: |
| 459 | case IB_QPT_UD: | 472 | rlid = slid; |
| 460 | rlid = ib_get_slid(pkt->hdr); | ||
| 461 | rqpn = ib_get_sqpn(pkt->ohdr); | 473 | rqpn = ib_get_sqpn(pkt->ohdr); |
| 462 | svc_type = IB_CC_SVCTYPE_UD; | 474 | svc_type = IB_CC_SVCTYPE_UD; |
| 463 | break; | 475 | break; |
| @@ -482,7 +494,6 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt, | |||
| 482 | dlid, rlid, sc, grh); | 494 | dlid, rlid, sc, grh); |
| 483 | 495 | ||
| 484 | if (!is_mcast && (bth1 & IB_BECN_SMASK)) { | 496 | if (!is_mcast && (bth1 & IB_BECN_SMASK)) { |
| 485 | struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); | ||
| 486 | u32 lqpn = bth1 & RVT_QPN_MASK; | 497 | u32 lqpn = bth1 & RVT_QPN_MASK; |
| 487 | u8 sl = ibp->sc_to_sl[sc]; | 498 | u8 sl = ibp->sc_to_sl[sc]; |
| 488 | 499 | ||
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 32c48265405e..cac2c62bc42d 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h | |||
| @@ -1537,13 +1537,13 @@ void set_link_ipg(struct hfi1_pportdata *ppd); | |||
| 1537 | void process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn, | 1537 | void process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn, |
| 1538 | u32 rqpn, u8 svc_type); | 1538 | u32 rqpn, u8 svc_type); |
| 1539 | void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, | 1539 | void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, |
| 1540 | u32 pkey, u32 slid, u32 dlid, u8 sc5, | 1540 | u16 pkey, u32 slid, u32 dlid, u8 sc5, |
| 1541 | const struct ib_grh *old_grh); | 1541 | const struct ib_grh *old_grh); |
| 1542 | void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, | 1542 | void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, |
| 1543 | u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, | 1543 | u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, |
| 1544 | u8 sc5, const struct ib_grh *old_grh); | 1544 | u8 sc5, const struct ib_grh *old_grh); |
| 1545 | typedef void (*hfi1_handle_cnp)(struct hfi1_ibport *ibp, struct rvt_qp *qp, | 1545 | typedef void (*hfi1_handle_cnp)(struct hfi1_ibport *ibp, struct rvt_qp *qp, |
| 1546 | u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, | 1546 | u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, |
| 1547 | u8 sc5, const struct ib_grh *old_grh); | 1547 | u8 sc5, const struct ib_grh *old_grh); |
| 1548 | 1548 | ||
| 1549 | #define PKEY_CHECK_INVALID -1 | 1549 | #define PKEY_CHECK_INVALID -1 |
| @@ -2437,7 +2437,7 @@ static inline void hfi1_make_16b_hdr(struct hfi1_16b_header *hdr, | |||
| 2437 | ((slid >> OPA_16B_SLID_SHIFT) << OPA_16B_SLID_HIGH_SHIFT); | 2437 | ((slid >> OPA_16B_SLID_SHIFT) << OPA_16B_SLID_HIGH_SHIFT); |
| 2438 | lrh2 = (lrh2 & ~OPA_16B_DLID_MASK) | | 2438 | lrh2 = (lrh2 & ~OPA_16B_DLID_MASK) | |
| 2439 | ((dlid >> OPA_16B_DLID_SHIFT) << OPA_16B_DLID_HIGH_SHIFT); | 2439 | ((dlid >> OPA_16B_DLID_SHIFT) << OPA_16B_DLID_HIGH_SHIFT); |
| 2440 | lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | (pkey << OPA_16B_PKEY_SHIFT); | 2440 | lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | ((u32)pkey << OPA_16B_PKEY_SHIFT); |
| 2441 | lrh2 = (lrh2 & ~OPA_16B_L4_MASK) | l4; | 2441 | lrh2 = (lrh2 & ~OPA_16B_L4_MASK) | l4; |
| 2442 | 2442 | ||
| 2443 | hdr->lrh[0] = lrh0; | 2443 | hdr->lrh[0] = lrh0; |
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index 33eba2356742..6309edf811df 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c | |||
| @@ -88,9 +88,9 @@ | |||
| 88 | * pio buffers per ctxt, etc.) Zero means use one user context per CPU. | 88 | * pio buffers per ctxt, etc.) Zero means use one user context per CPU. |
| 89 | */ | 89 | */ |
| 90 | int num_user_contexts = -1; | 90 | int num_user_contexts = -1; |
| 91 | module_param_named(num_user_contexts, num_user_contexts, uint, S_IRUGO); | 91 | module_param_named(num_user_contexts, num_user_contexts, int, 0444); |
| 92 | MODULE_PARM_DESC( | 92 | MODULE_PARM_DESC( |
| 93 | num_user_contexts, "Set max number of user contexts to use"); | 93 | num_user_contexts, "Set max number of user contexts to use (default: -1 will use the real (non-HT) CPU count)"); |
| 94 | 94 | ||
| 95 | uint krcvqs[RXE_NUM_DATA_VL]; | 95 | uint krcvqs[RXE_NUM_DATA_VL]; |
| 96 | int krcvqsset; | 96 | int krcvqsset; |
| @@ -1209,30 +1209,49 @@ static void finalize_asic_data(struct hfi1_devdata *dd, | |||
| 1209 | kfree(ad); | 1209 | kfree(ad); |
| 1210 | } | 1210 | } |
| 1211 | 1211 | ||
| 1212 | static void __hfi1_free_devdata(struct kobject *kobj) | 1212 | /** |
| 1213 | * hfi1_clean_devdata - cleans up per-unit data structure | ||
| 1214 | * @dd: pointer to a valid devdata structure | ||
| 1215 | * | ||
| 1216 | * It cleans up all data structures set up by | ||
| 1217 | * by hfi1_alloc_devdata(). | ||
| 1218 | */ | ||
| 1219 | static void hfi1_clean_devdata(struct hfi1_devdata *dd) | ||
| 1213 | { | 1220 | { |
| 1214 | struct hfi1_devdata *dd = | ||
| 1215 | container_of(kobj, struct hfi1_devdata, kobj); | ||
| 1216 | struct hfi1_asic_data *ad; | 1221 | struct hfi1_asic_data *ad; |
| 1217 | unsigned long flags; | 1222 | unsigned long flags; |
| 1218 | 1223 | ||
| 1219 | spin_lock_irqsave(&hfi1_devs_lock, flags); | 1224 | spin_lock_irqsave(&hfi1_devs_lock, flags); |
| 1220 | idr_remove(&hfi1_unit_table, dd->unit); | 1225 | if (!list_empty(&dd->list)) { |
| 1221 | list_del(&dd->list); | 1226 | idr_remove(&hfi1_unit_table, dd->unit); |
| 1227 | list_del_init(&dd->list); | ||
| 1228 | } | ||
| 1222 | ad = release_asic_data(dd); | 1229 | ad = release_asic_data(dd); |
| 1223 | spin_unlock_irqrestore(&hfi1_devs_lock, flags); | 1230 | spin_unlock_irqrestore(&hfi1_devs_lock, flags); |
| 1224 | if (ad) | 1231 | |
| 1225 | finalize_asic_data(dd, ad); | 1232 | finalize_asic_data(dd, ad); |
| 1226 | free_platform_config(dd); | 1233 | free_platform_config(dd); |
| 1227 | rcu_barrier(); /* wait for rcu callbacks to complete */ | 1234 | rcu_barrier(); /* wait for rcu callbacks to complete */ |
| 1228 | free_percpu(dd->int_counter); | 1235 | free_percpu(dd->int_counter); |
| 1229 | free_percpu(dd->rcv_limit); | 1236 | free_percpu(dd->rcv_limit); |
| 1230 | free_percpu(dd->send_schedule); | 1237 | free_percpu(dd->send_schedule); |
| 1231 | free_percpu(dd->tx_opstats); | 1238 | free_percpu(dd->tx_opstats); |
| 1239 | dd->int_counter = NULL; | ||
| 1240 | dd->rcv_limit = NULL; | ||
| 1241 | dd->send_schedule = NULL; | ||
| 1242 | dd->tx_opstats = NULL; | ||
| 1232 | sdma_clean(dd, dd->num_sdma); | 1243 | sdma_clean(dd, dd->num_sdma); |
| 1233 | rvt_dealloc_device(&dd->verbs_dev.rdi); | 1244 | rvt_dealloc_device(&dd->verbs_dev.rdi); |
| 1234 | } | 1245 | } |
| 1235 | 1246 | ||
| 1247 | static void __hfi1_free_devdata(struct kobject *kobj) | ||
| 1248 | { | ||
| 1249 | struct hfi1_devdata *dd = | ||
| 1250 | container_of(kobj, struct hfi1_devdata, kobj); | ||
| 1251 | |||
| 1252 | hfi1_clean_devdata(dd); | ||
| 1253 | } | ||
| 1254 | |||
| 1236 | static struct kobj_type hfi1_devdata_type = { | 1255 | static struct kobj_type hfi1_devdata_type = { |
| 1237 | .release = __hfi1_free_devdata, | 1256 | .release = __hfi1_free_devdata, |
| 1238 | }; | 1257 | }; |
| @@ -1265,6 +1284,8 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra) | |||
| 1265 | return ERR_PTR(-ENOMEM); | 1284 | return ERR_PTR(-ENOMEM); |
| 1266 | dd->num_pports = nports; | 1285 | dd->num_pports = nports; |
| 1267 | dd->pport = (struct hfi1_pportdata *)(dd + 1); | 1286 | dd->pport = (struct hfi1_pportdata *)(dd + 1); |
| 1287 | dd->pcidev = pdev; | ||
| 1288 | pci_set_drvdata(pdev, dd); | ||
| 1268 | 1289 | ||
| 1269 | INIT_LIST_HEAD(&dd->list); | 1290 | INIT_LIST_HEAD(&dd->list); |
| 1270 | idr_preload(GFP_KERNEL); | 1291 | idr_preload(GFP_KERNEL); |
| @@ -1331,9 +1352,7 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra) | |||
| 1331 | return dd; | 1352 | return dd; |
| 1332 | 1353 | ||
| 1333 | bail: | 1354 | bail: |
| 1334 | if (!list_empty(&dd->list)) | 1355 | hfi1_clean_devdata(dd); |
| 1335 | list_del_init(&dd->list); | ||
| 1336 | rvt_dealloc_device(&dd->verbs_dev.rdi); | ||
| 1337 | return ERR_PTR(ret); | 1356 | return ERR_PTR(ret); |
| 1338 | } | 1357 | } |
| 1339 | 1358 | ||
diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c index 83d66e862207..c1c982908b4b 100644 --- a/drivers/infiniband/hw/hfi1/pcie.c +++ b/drivers/infiniband/hw/hfi1/pcie.c | |||
| @@ -163,9 +163,6 @@ int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev) | |||
| 163 | resource_size_t addr; | 163 | resource_size_t addr; |
| 164 | int ret = 0; | 164 | int ret = 0; |
| 165 | 165 | ||
| 166 | dd->pcidev = pdev; | ||
| 167 | pci_set_drvdata(pdev, dd); | ||
| 168 | |||
| 169 | addr = pci_resource_start(pdev, 0); | 166 | addr = pci_resource_start(pdev, 0); |
| 170 | len = pci_resource_len(pdev, 0); | 167 | len = pci_resource_len(pdev, 0); |
| 171 | 168 | ||
diff --git a/drivers/infiniband/hw/hfi1/platform.c b/drivers/infiniband/hw/hfi1/platform.c index d486355880cb..cbf7faa5038c 100644 --- a/drivers/infiniband/hw/hfi1/platform.c +++ b/drivers/infiniband/hw/hfi1/platform.c | |||
| @@ -199,6 +199,7 @@ void free_platform_config(struct hfi1_devdata *dd) | |||
| 199 | { | 199 | { |
| 200 | /* Release memory allocated for eprom or fallback file read. */ | 200 | /* Release memory allocated for eprom or fallback file read. */ |
| 201 | kfree(dd->platform_config.data); | 201 | kfree(dd->platform_config.data); |
| 202 | dd->platform_config.data = NULL; | ||
| 202 | } | 203 | } |
| 203 | 204 | ||
| 204 | void get_port_type(struct hfi1_pportdata *ppd) | 205 | void get_port_type(struct hfi1_pportdata *ppd) |
diff --git a/drivers/infiniband/hw/hfi1/qsfp.c b/drivers/infiniband/hw/hfi1/qsfp.c index 1869f639c3ae..b5966991d647 100644 --- a/drivers/infiniband/hw/hfi1/qsfp.c +++ b/drivers/infiniband/hw/hfi1/qsfp.c | |||
| @@ -204,6 +204,8 @@ static void clean_i2c_bus(struct hfi1_i2c_bus *bus) | |||
| 204 | 204 | ||
| 205 | void clean_up_i2c(struct hfi1_devdata *dd, struct hfi1_asic_data *ad) | 205 | void clean_up_i2c(struct hfi1_devdata *dd, struct hfi1_asic_data *ad) |
| 206 | { | 206 | { |
| 207 | if (!ad) | ||
| 208 | return; | ||
| 207 | clean_i2c_bus(ad->i2c_bus0); | 209 | clean_i2c_bus(ad->i2c_bus0); |
| 208 | ad->i2c_bus0 = NULL; | 210 | ad->i2c_bus0 = NULL; |
| 209 | clean_i2c_bus(ad->i2c_bus1); | 211 | clean_i2c_bus(ad->i2c_bus1); |
diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c index 3daa94bdae3a..c0071ca4147a 100644 --- a/drivers/infiniband/hw/hfi1/ruc.c +++ b/drivers/infiniband/hw/hfi1/ruc.c | |||
| @@ -733,6 +733,20 @@ static inline void hfi1_make_ruc_bth(struct rvt_qp *qp, | |||
| 733 | ohdr->bth[2] = cpu_to_be32(bth2); | 733 | ohdr->bth[2] = cpu_to_be32(bth2); |
| 734 | } | 734 | } |
| 735 | 735 | ||
| 736 | /** | ||
| 737 | * hfi1_make_ruc_header_16B - build a 16B header | ||
| 738 | * @qp: the queue pair | ||
| 739 | * @ohdr: a pointer to the destination header memory | ||
| 740 | * @bth0: bth0 passed in from the RC/UC builder | ||
| 741 | * @bth2: bth2 passed in from the RC/UC builder | ||
| 742 | * @middle: non zero implies indicates ahg "could" be used | ||
| 743 | * @ps: the current packet state | ||
| 744 | * | ||
| 745 | * This routine may disarm ahg under these situations: | ||
| 746 | * - packet needs a GRH | ||
| 747 | * - BECN needed | ||
| 748 | * - migration state not IB_MIG_MIGRATED | ||
| 749 | */ | ||
| 736 | static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, | 750 | static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, |
| 737 | struct ib_other_headers *ohdr, | 751 | struct ib_other_headers *ohdr, |
| 738 | u32 bth0, u32 bth2, int middle, | 752 | u32 bth0, u32 bth2, int middle, |
| @@ -777,6 +791,12 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, | |||
| 777 | else | 791 | else |
| 778 | middle = 0; | 792 | middle = 0; |
| 779 | 793 | ||
| 794 | if (qp->s_flags & RVT_S_ECN) { | ||
| 795 | qp->s_flags &= ~RVT_S_ECN; | ||
| 796 | /* we recently received a FECN, so return a BECN */ | ||
| 797 | becn = true; | ||
| 798 | middle = 0; | ||
| 799 | } | ||
| 780 | if (middle) | 800 | if (middle) |
| 781 | build_ahg(qp, bth2); | 801 | build_ahg(qp, bth2); |
| 782 | else | 802 | else |
| @@ -784,11 +804,6 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, | |||
| 784 | 804 | ||
| 785 | bth0 |= pkey; | 805 | bth0 |= pkey; |
| 786 | bth0 |= extra_bytes << 20; | 806 | bth0 |= extra_bytes << 20; |
| 787 | if (qp->s_flags & RVT_S_ECN) { | ||
| 788 | qp->s_flags &= ~RVT_S_ECN; | ||
| 789 | /* we recently received a FECN, so return a BECN */ | ||
| 790 | becn = true; | ||
| 791 | } | ||
| 792 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); | 807 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); |
| 793 | 808 | ||
| 794 | if (!ppd->lid) | 809 | if (!ppd->lid) |
| @@ -806,6 +821,20 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, | |||
| 806 | pkey, becn, 0, l4, priv->s_sc); | 821 | pkey, becn, 0, l4, priv->s_sc); |
| 807 | } | 822 | } |
| 808 | 823 | ||
| 824 | /** | ||
| 825 | * hfi1_make_ruc_header_9B - build a 9B header | ||
| 826 | * @qp: the queue pair | ||
| 827 | * @ohdr: a pointer to the destination header memory | ||
| 828 | * @bth0: bth0 passed in from the RC/UC builder | ||
| 829 | * @bth2: bth2 passed in from the RC/UC builder | ||
| 830 | * @middle: non zero implies indicates ahg "could" be used | ||
| 831 | * @ps: the current packet state | ||
| 832 | * | ||
| 833 | * This routine may disarm ahg under these situations: | ||
| 834 | * - packet needs a GRH | ||
| 835 | * - BECN needed | ||
| 836 | * - migration state not IB_MIG_MIGRATED | ||
| 837 | */ | ||
| 809 | static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, | 838 | static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, |
| 810 | struct ib_other_headers *ohdr, | 839 | struct ib_other_headers *ohdr, |
| 811 | u32 bth0, u32 bth2, int middle, | 840 | u32 bth0, u32 bth2, int middle, |
| @@ -839,6 +868,12 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, | |||
| 839 | else | 868 | else |
| 840 | middle = 0; | 869 | middle = 0; |
| 841 | 870 | ||
| 871 | if (qp->s_flags & RVT_S_ECN) { | ||
| 872 | qp->s_flags &= ~RVT_S_ECN; | ||
| 873 | /* we recently received a FECN, so return a BECN */ | ||
| 874 | bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT); | ||
| 875 | middle = 0; | ||
| 876 | } | ||
| 842 | if (middle) | 877 | if (middle) |
| 843 | build_ahg(qp, bth2); | 878 | build_ahg(qp, bth2); |
| 844 | else | 879 | else |
| @@ -846,11 +881,6 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, | |||
| 846 | 881 | ||
| 847 | bth0 |= pkey; | 882 | bth0 |= pkey; |
| 848 | bth0 |= extra_bytes << 20; | 883 | bth0 |= extra_bytes << 20; |
| 849 | if (qp->s_flags & RVT_S_ECN) { | ||
| 850 | qp->s_flags &= ~RVT_S_ECN; | ||
| 851 | /* we recently received a FECN, so return a BECN */ | ||
| 852 | bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT); | ||
| 853 | } | ||
| 854 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); | 884 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); |
| 855 | hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh, | 885 | hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh, |
| 856 | lrh0, | 886 | lrh0, |
diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c index bcf3b0bebac8..69c17a5ef038 100644 --- a/drivers/infiniband/hw/hfi1/ud.c +++ b/drivers/infiniband/hw/hfi1/ud.c | |||
| @@ -628,7 +628,7 @@ int hfi1_lookup_pkey_idx(struct hfi1_ibport *ibp, u16 pkey) | |||
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, | 630 | void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, |
| 631 | u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, | 631 | u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, |
| 632 | u8 sc5, const struct ib_grh *old_grh) | 632 | u8 sc5, const struct ib_grh *old_grh) |
| 633 | { | 633 | { |
| 634 | u64 pbc, pbc_flags = 0; | 634 | u64 pbc, pbc_flags = 0; |
| @@ -687,7 +687,7 @@ void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, | |||
| 687 | } | 687 | } |
| 688 | 688 | ||
| 689 | void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, | 689 | void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, |
| 690 | u32 pkey, u32 slid, u32 dlid, u8 sc5, | 690 | u16 pkey, u32 slid, u32 dlid, u8 sc5, |
| 691 | const struct ib_grh *old_grh) | 691 | const struct ib_grh *old_grh) |
| 692 | { | 692 | { |
| 693 | u64 pbc, pbc_flags = 0; | 693 | u64 pbc, pbc_flags = 0; |
diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index 0eeabfbee192..63b5b3edabcb 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c | |||
| @@ -912,7 +912,7 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, | |||
| 912 | obj_per_chunk = buf_chunk_size / obj_size; | 912 | obj_per_chunk = buf_chunk_size / obj_size; |
| 913 | num_hem = (nobj + obj_per_chunk - 1) / obj_per_chunk; | 913 | num_hem = (nobj + obj_per_chunk - 1) / obj_per_chunk; |
| 914 | bt_chunk_num = bt_chunk_size / 8; | 914 | bt_chunk_num = bt_chunk_size / 8; |
| 915 | if (table->type >= HEM_TYPE_MTT) | 915 | if (type >= HEM_TYPE_MTT) |
| 916 | num_bt_l0 = bt_chunk_num; | 916 | num_bt_l0 = bt_chunk_num; |
| 917 | 917 | ||
| 918 | table->hem = kcalloc(num_hem, sizeof(*table->hem), | 918 | table->hem = kcalloc(num_hem, sizeof(*table->hem), |
| @@ -920,7 +920,7 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, | |||
| 920 | if (!table->hem) | 920 | if (!table->hem) |
| 921 | goto err_kcalloc_hem_buf; | 921 | goto err_kcalloc_hem_buf; |
| 922 | 922 | ||
| 923 | if (check_whether_bt_num_3(table->type, hop_num)) { | 923 | if (check_whether_bt_num_3(type, hop_num)) { |
| 924 | unsigned long num_bt_l1; | 924 | unsigned long num_bt_l1; |
| 925 | 925 | ||
| 926 | num_bt_l1 = (num_hem + bt_chunk_num - 1) / | 926 | num_bt_l1 = (num_hem + bt_chunk_num - 1) / |
| @@ -939,8 +939,8 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, | |||
| 939 | goto err_kcalloc_l1_dma; | 939 | goto err_kcalloc_l1_dma; |
| 940 | } | 940 | } |
| 941 | 941 | ||
| 942 | if (check_whether_bt_num_2(table->type, hop_num) || | 942 | if (check_whether_bt_num_2(type, hop_num) || |
| 943 | check_whether_bt_num_3(table->type, hop_num)) { | 943 | check_whether_bt_num_3(type, hop_num)) { |
| 944 | table->bt_l0 = kcalloc(num_bt_l0, sizeof(*table->bt_l0), | 944 | table->bt_l0 = kcalloc(num_bt_l0, sizeof(*table->bt_l0), |
| 945 | GFP_KERNEL); | 945 | GFP_KERNEL); |
| 946 | if (!table->bt_l0) | 946 | if (!table->bt_l0) |
| @@ -1039,14 +1039,14 @@ void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev, | |||
| 1039 | void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev) | 1039 | void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev) |
| 1040 | { | 1040 | { |
| 1041 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->cq_table.table); | 1041 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->cq_table.table); |
| 1042 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.irrl_table); | ||
| 1043 | if (hr_dev->caps.trrl_entry_sz) | 1042 | if (hr_dev->caps.trrl_entry_sz) |
| 1044 | hns_roce_cleanup_hem_table(hr_dev, | 1043 | hns_roce_cleanup_hem_table(hr_dev, |
| 1045 | &hr_dev->qp_table.trrl_table); | 1044 | &hr_dev->qp_table.trrl_table); |
| 1045 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.irrl_table); | ||
| 1046 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.qp_table); | 1046 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.qp_table); |
| 1047 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table); | 1047 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table); |
| 1048 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table); | ||
| 1049 | if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE)) | 1048 | if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE)) |
| 1050 | hns_roce_cleanup_hem_table(hr_dev, | 1049 | hns_roce_cleanup_hem_table(hr_dev, |
| 1051 | &hr_dev->mr_table.mtt_cqe_table); | 1050 | &hr_dev->mr_table.mtt_cqe_table); |
| 1051 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table); | ||
| 1052 | } | 1052 | } |
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 8b84ab7800d8..25916e8522ed 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c | |||
| @@ -71,6 +71,11 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 71 | return -EINVAL; | 71 | return -EINVAL; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | if (wr->opcode == IB_WR_RDMA_READ) { | ||
| 75 | dev_err(hr_dev->dev, "Not support inline data!\n"); | ||
| 76 | return -EINVAL; | ||
| 77 | } | ||
| 78 | |||
| 74 | for (i = 0; i < wr->num_sge; i++) { | 79 | for (i = 0; i < wr->num_sge; i++) { |
| 75 | memcpy(wqe, ((void *)wr->sg_list[i].addr), | 80 | memcpy(wqe, ((void *)wr->sg_list[i].addr), |
| 76 | wr->sg_list[i].length); | 81 | wr->sg_list[i].length); |
| @@ -148,7 +153,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 148 | ibqp->qp_type != IB_QPT_GSI && | 153 | ibqp->qp_type != IB_QPT_GSI && |
| 149 | ibqp->qp_type != IB_QPT_UD)) { | 154 | ibqp->qp_type != IB_QPT_UD)) { |
| 150 | dev_err(dev, "Not supported QP(0x%x)type!\n", ibqp->qp_type); | 155 | dev_err(dev, "Not supported QP(0x%x)type!\n", ibqp->qp_type); |
| 151 | *bad_wr = NULL; | 156 | *bad_wr = wr; |
| 152 | return -EOPNOTSUPP; | 157 | return -EOPNOTSUPP; |
| 153 | } | 158 | } |
| 154 | 159 | ||
| @@ -182,7 +187,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 182 | qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = | 187 | qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = |
| 183 | wr->wr_id; | 188 | wr->wr_id; |
| 184 | 189 | ||
| 185 | owner_bit = ~(qp->sq.head >> ilog2(qp->sq.wqe_cnt)) & 0x1; | 190 | owner_bit = |
| 191 | ~(((qp->sq.head + nreq) >> ilog2(qp->sq.wqe_cnt)) & 0x1); | ||
| 186 | 192 | ||
| 187 | /* Corresponding to the QP type, wqe process separately */ | 193 | /* Corresponding to the QP type, wqe process separately */ |
| 188 | if (ibqp->qp_type == IB_QPT_GSI) { | 194 | if (ibqp->qp_type == IB_QPT_GSI) { |
| @@ -456,6 +462,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 456 | } else { | 462 | } else { |
| 457 | dev_err(dev, "Illegal qp_type(0x%x)\n", ibqp->qp_type); | 463 | dev_err(dev, "Illegal qp_type(0x%x)\n", ibqp->qp_type); |
| 458 | spin_unlock_irqrestore(&qp->sq.lock, flags); | 464 | spin_unlock_irqrestore(&qp->sq.lock, flags); |
| 465 | *bad_wr = wr; | ||
| 459 | return -EOPNOTSUPP; | 466 | return -EOPNOTSUPP; |
| 460 | } | 467 | } |
| 461 | } | 468 | } |
| @@ -2592,10 +2599,12 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp, | |||
| 2592 | roce_set_field(qpc_mask->byte_4_sqpn_tst, V2_QPC_BYTE_4_SQPN_M, | 2599 | roce_set_field(qpc_mask->byte_4_sqpn_tst, V2_QPC_BYTE_4_SQPN_M, |
| 2593 | V2_QPC_BYTE_4_SQPN_S, 0); | 2600 | V2_QPC_BYTE_4_SQPN_S, 0); |
| 2594 | 2601 | ||
| 2595 | roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | 2602 | if (attr_mask & IB_QP_DEST_QPN) { |
| 2596 | V2_QPC_BYTE_56_DQPN_S, hr_qp->qpn); | 2603 | roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, |
| 2597 | roce_set_field(qpc_mask->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | 2604 | V2_QPC_BYTE_56_DQPN_S, hr_qp->qpn); |
| 2598 | V2_QPC_BYTE_56_DQPN_S, 0); | 2605 | roce_set_field(qpc_mask->byte_56_dqpn_err, |
| 2606 | V2_QPC_BYTE_56_DQPN_M, V2_QPC_BYTE_56_DQPN_S, 0); | ||
| 2607 | } | ||
| 2599 | roce_set_field(context->byte_168_irrl_idx, | 2608 | roce_set_field(context->byte_168_irrl_idx, |
| 2600 | V2_QPC_BYTE_168_SQ_SHIFT_BAK_M, | 2609 | V2_QPC_BYTE_168_SQ_SHIFT_BAK_M, |
| 2601 | V2_QPC_BYTE_168_SQ_SHIFT_BAK_S, | 2610 | V2_QPC_BYTE_168_SQ_SHIFT_BAK_S, |
| @@ -2650,8 +2659,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, | |||
| 2650 | return -EINVAL; | 2659 | return -EINVAL; |
| 2651 | } | 2660 | } |
| 2652 | 2661 | ||
| 2653 | if ((attr_mask & IB_QP_ALT_PATH) || (attr_mask & IB_QP_ACCESS_FLAGS) || | 2662 | if (attr_mask & IB_QP_ALT_PATH) { |
| 2654 | (attr_mask & IB_QP_PKEY_INDEX) || (attr_mask & IB_QP_QKEY)) { | ||
| 2655 | dev_err(dev, "INIT2RTR attr_mask (0x%x) error\n", attr_mask); | 2663 | dev_err(dev, "INIT2RTR attr_mask (0x%x) error\n", attr_mask); |
| 2656 | return -EINVAL; | 2664 | return -EINVAL; |
| 2657 | } | 2665 | } |
| @@ -2800,10 +2808,12 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, | |||
| 2800 | V2_QPC_BYTE_140_RR_MAX_S, 0); | 2808 | V2_QPC_BYTE_140_RR_MAX_S, 0); |
| 2801 | } | 2809 | } |
| 2802 | 2810 | ||
| 2803 | roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | 2811 | if (attr_mask & IB_QP_DEST_QPN) { |
| 2804 | V2_QPC_BYTE_56_DQPN_S, attr->dest_qp_num); | 2812 | roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, |
| 2805 | roce_set_field(qpc_mask->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | 2813 | V2_QPC_BYTE_56_DQPN_S, attr->dest_qp_num); |
| 2806 | V2_QPC_BYTE_56_DQPN_S, 0); | 2814 | roce_set_field(qpc_mask->byte_56_dqpn_err, |
| 2815 | V2_QPC_BYTE_56_DQPN_M, V2_QPC_BYTE_56_DQPN_S, 0); | ||
| 2816 | } | ||
| 2807 | 2817 | ||
| 2808 | /* Configure GID index */ | 2818 | /* Configure GID index */ |
| 2809 | port_num = rdma_ah_get_port_num(&attr->ah_attr); | 2819 | port_num = rdma_ah_get_port_num(&attr->ah_attr); |
| @@ -2845,7 +2855,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, | |||
| 2845 | if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_UD) | 2855 | if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_UD) |
| 2846 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, | 2856 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, |
| 2847 | V2_QPC_BYTE_24_MTU_S, IB_MTU_4096); | 2857 | V2_QPC_BYTE_24_MTU_S, IB_MTU_4096); |
| 2848 | else | 2858 | else if (attr_mask & IB_QP_PATH_MTU) |
| 2849 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, | 2859 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, |
| 2850 | V2_QPC_BYTE_24_MTU_S, attr->path_mtu); | 2860 | V2_QPC_BYTE_24_MTU_S, attr->path_mtu); |
| 2851 | 2861 | ||
| @@ -2922,11 +2932,9 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, | |||
| 2922 | return -EINVAL; | 2932 | return -EINVAL; |
| 2923 | } | 2933 | } |
| 2924 | 2934 | ||
| 2925 | /* If exist optional param, return error */ | 2935 | /* Not support alternate path and path migration */ |
| 2926 | if ((attr_mask & IB_QP_ALT_PATH) || (attr_mask & IB_QP_ACCESS_FLAGS) || | 2936 | if ((attr_mask & IB_QP_ALT_PATH) || |
| 2927 | (attr_mask & IB_QP_QKEY) || (attr_mask & IB_QP_PATH_MIG_STATE) || | 2937 | (attr_mask & IB_QP_PATH_MIG_STATE)) { |
| 2928 | (attr_mask & IB_QP_CUR_STATE) || | ||
| 2929 | (attr_mask & IB_QP_MIN_RNR_TIMER)) { | ||
| 2930 | dev_err(dev, "RTR2RTS attr_mask (0x%x)error\n", attr_mask); | 2938 | dev_err(dev, "RTR2RTS attr_mask (0x%x)error\n", attr_mask); |
| 2931 | return -EINVAL; | 2939 | return -EINVAL; |
| 2932 | } | 2940 | } |
| @@ -3161,7 +3169,8 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp, | |||
| 3161 | (cur_state == IB_QPS_RTR && new_state == IB_QPS_ERR) || | 3169 | (cur_state == IB_QPS_RTR && new_state == IB_QPS_ERR) || |
| 3162 | (cur_state == IB_QPS_RTS && new_state == IB_QPS_ERR) || | 3170 | (cur_state == IB_QPS_RTS && new_state == IB_QPS_ERR) || |
| 3163 | (cur_state == IB_QPS_SQD && new_state == IB_QPS_ERR) || | 3171 | (cur_state == IB_QPS_SQD && new_state == IB_QPS_ERR) || |
| 3164 | (cur_state == IB_QPS_SQE && new_state == IB_QPS_ERR)) { | 3172 | (cur_state == IB_QPS_SQE && new_state == IB_QPS_ERR) || |
| 3173 | (cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR)) { | ||
| 3165 | /* Nothing */ | 3174 | /* Nothing */ |
| 3166 | ; | 3175 | ; |
| 3167 | } else { | 3176 | } else { |
| @@ -4478,7 +4487,7 @@ static int hns_roce_v2_create_eq(struct hns_roce_dev *hr_dev, | |||
| 4478 | ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, eq->eqn, 0, | 4487 | ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, eq->eqn, 0, |
| 4479 | eq_cmd, HNS_ROCE_CMD_TIMEOUT_MSECS); | 4488 | eq_cmd, HNS_ROCE_CMD_TIMEOUT_MSECS); |
| 4480 | if (ret) { | 4489 | if (ret) { |
| 4481 | dev_err(dev, "[mailbox cmd] creat eqc failed.\n"); | 4490 | dev_err(dev, "[mailbox cmd] create eqc failed.\n"); |
| 4482 | goto err_cmd_mbox; | 4491 | goto err_cmd_mbox; |
| 4483 | } | 4492 | } |
| 4484 | 4493 | ||
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index e289a924e789..d4aad34c21e2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c | |||
| @@ -620,7 +620,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, | |||
| 620 | to_hr_ucontext(ib_pd->uobject->context), | 620 | to_hr_ucontext(ib_pd->uobject->context), |
| 621 | ucmd.db_addr, &hr_qp->rdb); | 621 | ucmd.db_addr, &hr_qp->rdb); |
| 622 | if (ret) { | 622 | if (ret) { |
| 623 | dev_err(dev, "rp record doorbell map failed!\n"); | 623 | dev_err(dev, "rq record doorbell map failed!\n"); |
| 624 | goto err_mtt; | 624 | goto err_mtt; |
| 625 | } | 625 | } |
| 626 | } | 626 | } |
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 17f4f151a97f..61d8b06375bb 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
| @@ -346,7 +346,7 @@ int mlx4_ib_umem_calc_optimal_mtt_size(struct ib_umem *umem, u64 start_va, | |||
| 346 | /* Add to the first block the misalignment that it suffers from. */ | 346 | /* Add to the first block the misalignment that it suffers from. */ |
| 347 | total_len += (first_block_start & ((1ULL << block_shift) - 1ULL)); | 347 | total_len += (first_block_start & ((1ULL << block_shift) - 1ULL)); |
| 348 | last_block_end = current_block_start + current_block_len; | 348 | last_block_end = current_block_start + current_block_len; |
| 349 | last_block_aligned_end = round_up(last_block_end, 1 << block_shift); | 349 | last_block_aligned_end = round_up(last_block_end, 1ULL << block_shift); |
| 350 | total_len += (last_block_aligned_end - last_block_end); | 350 | total_len += (last_block_aligned_end - last_block_end); |
| 351 | 351 | ||
| 352 | if (total_len & ((1ULL << block_shift) - 1ULL)) | 352 | if (total_len & ((1ULL << block_shift) - 1ULL)) |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 50af8915e7ec..199648adac74 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -673,7 +673,8 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, | |||
| 673 | MLX4_IB_RX_HASH_SRC_PORT_TCP | | 673 | MLX4_IB_RX_HASH_SRC_PORT_TCP | |
| 674 | MLX4_IB_RX_HASH_DST_PORT_TCP | | 674 | MLX4_IB_RX_HASH_DST_PORT_TCP | |
| 675 | MLX4_IB_RX_HASH_SRC_PORT_UDP | | 675 | MLX4_IB_RX_HASH_SRC_PORT_UDP | |
| 676 | MLX4_IB_RX_HASH_DST_PORT_UDP)) { | 676 | MLX4_IB_RX_HASH_DST_PORT_UDP | |
| 677 | MLX4_IB_RX_HASH_INNER)) { | ||
| 677 | pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", | 678 | pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", |
| 678 | ucmd->rx_hash_fields_mask); | 679 | ucmd->rx_hash_fields_mask); |
| 679 | return (-EOPNOTSUPP); | 680 | return (-EOPNOTSUPP); |
diff --git a/drivers/infiniband/hw/mlx5/Kconfig b/drivers/infiniband/hw/mlx5/Kconfig index bce263b92821..fb4d77be019b 100644 --- a/drivers/infiniband/hw/mlx5/Kconfig +++ b/drivers/infiniband/hw/mlx5/Kconfig | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | config MLX5_INFINIBAND | 1 | config MLX5_INFINIBAND |
| 2 | tristate "Mellanox Connect-IB HCA support" | 2 | tristate "Mellanox Connect-IB HCA support" |
| 3 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE | 3 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE |
| 4 | depends on INFINIBAND_USER_ACCESS || INFINIBAND_USER_ACCESS=n | ||
| 4 | ---help--- | 5 | ---help--- |
| 5 | This driver provides low-level InfiniBand support for | 6 | This driver provides low-level InfiniBand support for |
| 6 | Mellanox Connect-IB PCI Express host channel adapters (HCAs). | 7 | Mellanox Connect-IB PCI Express host channel adapters (HCAs). |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index daa919e5a442..b4d8ff8ab807 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
| @@ -52,7 +52,6 @@ | |||
| 52 | #include <linux/mlx5/port.h> | 52 | #include <linux/mlx5/port.h> |
| 53 | #include <linux/mlx5/vport.h> | 53 | #include <linux/mlx5/vport.h> |
| 54 | #include <linux/mlx5/fs.h> | 54 | #include <linux/mlx5/fs.h> |
| 55 | #include <linux/mlx5/fs_helpers.h> | ||
| 56 | #include <linux/list.h> | 55 | #include <linux/list.h> |
| 57 | #include <rdma/ib_smi.h> | 56 | #include <rdma/ib_smi.h> |
| 58 | #include <rdma/ib_umem.h> | 57 | #include <rdma/ib_umem.h> |
| @@ -180,7 +179,7 @@ static int mlx5_netdev_event(struct notifier_block *this, | |||
| 180 | if (rep_ndev == ndev) | 179 | if (rep_ndev == ndev) |
| 181 | roce->netdev = (event == NETDEV_UNREGISTER) ? | 180 | roce->netdev = (event == NETDEV_UNREGISTER) ? |
| 182 | NULL : ndev; | 181 | NULL : ndev; |
| 183 | } else if (ndev->dev.parent == &ibdev->mdev->pdev->dev) { | 182 | } else if (ndev->dev.parent == &mdev->pdev->dev) { |
| 184 | roce->netdev = (event == NETDEV_UNREGISTER) ? | 183 | roce->netdev = (event == NETDEV_UNREGISTER) ? |
| 185 | NULL : ndev; | 184 | NULL : ndev; |
| 186 | } | 185 | } |
| @@ -4757,7 +4756,7 @@ mlx5_ib_get_vector_affinity(struct ib_device *ibdev, int comp_vector) | |||
| 4757 | { | 4756 | { |
| 4758 | struct mlx5_ib_dev *dev = to_mdev(ibdev); | 4757 | struct mlx5_ib_dev *dev = to_mdev(ibdev); |
| 4759 | 4758 | ||
| 4760 | return mlx5_get_vector_affinity(dev->mdev, comp_vector); | 4759 | return mlx5_get_vector_affinity_hint(dev->mdev, comp_vector); |
| 4761 | } | 4760 | } |
| 4762 | 4761 | ||
| 4763 | /* The mlx5_ib_multiport_mutex should be held when calling this function */ | 4762 | /* The mlx5_ib_multiport_mutex should be held when calling this function */ |
| @@ -5427,9 +5426,7 @@ static void mlx5_ib_stage_cong_debugfs_cleanup(struct mlx5_ib_dev *dev) | |||
| 5427 | static int mlx5_ib_stage_uar_init(struct mlx5_ib_dev *dev) | 5426 | static int mlx5_ib_stage_uar_init(struct mlx5_ib_dev *dev) |
| 5428 | { | 5427 | { |
| 5429 | dev->mdev->priv.uar = mlx5_get_uars_page(dev->mdev); | 5428 | dev->mdev->priv.uar = mlx5_get_uars_page(dev->mdev); |
| 5430 | if (!dev->mdev->priv.uar) | 5429 | return PTR_ERR_OR_ZERO(dev->mdev->priv.uar); |
| 5431 | return -ENOMEM; | ||
| 5432 | return 0; | ||
| 5433 | } | 5430 | } |
| 5434 | 5431 | ||
| 5435 | static void mlx5_ib_stage_uar_cleanup(struct mlx5_ib_dev *dev) | 5432 | static void mlx5_ib_stage_uar_cleanup(struct mlx5_ib_dev *dev) |
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 1520a2f20f98..90a9c461cedc 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c | |||
| @@ -866,25 +866,28 @@ static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length, | |||
| 866 | int *order) | 866 | int *order) |
| 867 | { | 867 | { |
| 868 | struct mlx5_ib_dev *dev = to_mdev(pd->device); | 868 | struct mlx5_ib_dev *dev = to_mdev(pd->device); |
| 869 | struct ib_umem *u; | ||
| 869 | int err; | 870 | int err; |
| 870 | 871 | ||
| 871 | *umem = ib_umem_get(pd->uobject->context, start, length, | 872 | *umem = NULL; |
| 872 | access_flags, 0); | 873 | |
| 873 | err = PTR_ERR_OR_ZERO(*umem); | 874 | u = ib_umem_get(pd->uobject->context, start, length, access_flags, 0); |
| 875 | err = PTR_ERR_OR_ZERO(u); | ||
| 874 | if (err) { | 876 | if (err) { |
| 875 | *umem = NULL; | 877 | mlx5_ib_dbg(dev, "umem get failed (%d)\n", err); |
| 876 | mlx5_ib_err(dev, "umem get failed (%d)\n", err); | ||
| 877 | return err; | 878 | return err; |
| 878 | } | 879 | } |
| 879 | 880 | ||
| 880 | mlx5_ib_cont_pages(*umem, start, MLX5_MKEY_PAGE_SHIFT_MASK, npages, | 881 | mlx5_ib_cont_pages(u, start, MLX5_MKEY_PAGE_SHIFT_MASK, npages, |
| 881 | page_shift, ncont, order); | 882 | page_shift, ncont, order); |
| 882 | if (!*npages) { | 883 | if (!*npages) { |
| 883 | mlx5_ib_warn(dev, "avoid zero region\n"); | 884 | mlx5_ib_warn(dev, "avoid zero region\n"); |
| 884 | ib_umem_release(*umem); | 885 | ib_umem_release(u); |
| 885 | return -EINVAL; | 886 | return -EINVAL; |
| 886 | } | 887 | } |
| 887 | 888 | ||
| 889 | *umem = u; | ||
| 890 | |||
| 888 | mlx5_ib_dbg(dev, "npages %d, ncont %d, order %d, page_shift %d\n", | 891 | mlx5_ib_dbg(dev, "npages %d, ncont %d, order %d, page_shift %d\n", |
| 889 | *npages, *ncont, *order, *page_shift); | 892 | *npages, *ncont, *order, *page_shift); |
| 890 | 893 | ||
| @@ -1458,13 +1461,12 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, | |||
| 1458 | int access_flags = flags & IB_MR_REREG_ACCESS ? | 1461 | int access_flags = flags & IB_MR_REREG_ACCESS ? |
| 1459 | new_access_flags : | 1462 | new_access_flags : |
| 1460 | mr->access_flags; | 1463 | mr->access_flags; |
| 1461 | u64 addr = (flags & IB_MR_REREG_TRANS) ? virt_addr : mr->umem->address; | ||
| 1462 | u64 len = (flags & IB_MR_REREG_TRANS) ? length : mr->umem->length; | ||
| 1463 | int page_shift = 0; | 1464 | int page_shift = 0; |
| 1464 | int upd_flags = 0; | 1465 | int upd_flags = 0; |
| 1465 | int npages = 0; | 1466 | int npages = 0; |
| 1466 | int ncont = 0; | 1467 | int ncont = 0; |
| 1467 | int order = 0; | 1468 | int order = 0; |
| 1469 | u64 addr, len; | ||
| 1468 | int err; | 1470 | int err; |
| 1469 | 1471 | ||
| 1470 | mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx, access_flags 0x%x\n", | 1472 | mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx, access_flags 0x%x\n", |
| @@ -1472,6 +1474,17 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, | |||
| 1472 | 1474 | ||
| 1473 | atomic_sub(mr->npages, &dev->mdev->priv.reg_pages); | 1475 | atomic_sub(mr->npages, &dev->mdev->priv.reg_pages); |
| 1474 | 1476 | ||
| 1477 | if (!mr->umem) | ||
| 1478 | return -EINVAL; | ||
| 1479 | |||
| 1480 | if (flags & IB_MR_REREG_TRANS) { | ||
| 1481 | addr = virt_addr; | ||
| 1482 | len = length; | ||
| 1483 | } else { | ||
| 1484 | addr = mr->umem->address; | ||
| 1485 | len = mr->umem->length; | ||
| 1486 | } | ||
| 1487 | |||
| 1475 | if (flags != IB_MR_REREG_PD) { | 1488 | if (flags != IB_MR_REREG_PD) { |
| 1476 | /* | 1489 | /* |
| 1477 | * Replace umem. This needs to be done whether or not UMR is | 1490 | * Replace umem. This needs to be done whether or not UMR is |
| @@ -1479,6 +1492,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, | |||
| 1479 | */ | 1492 | */ |
| 1480 | flags |= IB_MR_REREG_TRANS; | 1493 | flags |= IB_MR_REREG_TRANS; |
| 1481 | ib_umem_release(mr->umem); | 1494 | ib_umem_release(mr->umem); |
| 1495 | mr->umem = NULL; | ||
| 1482 | err = mr_umem_get(pd, addr, len, access_flags, &mr->umem, | 1496 | err = mr_umem_get(pd, addr, len, access_flags, &mr->umem, |
| 1483 | &npages, &page_shift, &ncont, &order); | 1497 | &npages, &page_shift, &ncont, &order); |
| 1484 | if (err) | 1498 | if (err) |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 7ed4b70f6447..87b7c1be2a11 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
| @@ -259,7 +259,11 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 259 | } else { | 259 | } else { |
| 260 | if (ucmd) { | 260 | if (ucmd) { |
| 261 | qp->rq.wqe_cnt = ucmd->rq_wqe_count; | 261 | qp->rq.wqe_cnt = ucmd->rq_wqe_count; |
| 262 | if (ucmd->rq_wqe_shift > BITS_PER_BYTE * sizeof(ucmd->rq_wqe_shift)) | ||
| 263 | return -EINVAL; | ||
| 262 | qp->rq.wqe_shift = ucmd->rq_wqe_shift; | 264 | qp->rq.wqe_shift = ucmd->rq_wqe_shift; |
| 265 | if ((1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) < qp->wq_sig) | ||
| 266 | return -EINVAL; | ||
| 263 | qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig; | 267 | qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig; |
| 264 | qp->rq.max_post = qp->rq.wqe_cnt; | 268 | qp->rq.max_post = qp->rq.wqe_cnt; |
| 265 | } else { | 269 | } else { |
| @@ -2451,18 +2455,18 @@ enum { | |||
| 2451 | 2455 | ||
| 2452 | static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate) | 2456 | static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate) |
| 2453 | { | 2457 | { |
| 2454 | if (rate == IB_RATE_PORT_CURRENT) { | 2458 | if (rate == IB_RATE_PORT_CURRENT) |
| 2455 | return 0; | 2459 | return 0; |
| 2456 | } else if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) { | 2460 | |
| 2461 | if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) | ||
| 2457 | return -EINVAL; | 2462 | return -EINVAL; |
| 2458 | } else { | ||
| 2459 | while (rate != IB_RATE_2_5_GBPS && | ||
| 2460 | !(1 << (rate + MLX5_STAT_RATE_OFFSET) & | ||
| 2461 | MLX5_CAP_GEN(dev->mdev, stat_rate_support))) | ||
| 2462 | --rate; | ||
| 2463 | } | ||
| 2464 | 2463 | ||
| 2465 | return rate + MLX5_STAT_RATE_OFFSET; | 2464 | while (rate != IB_RATE_PORT_CURRENT && |
| 2465 | !(1 << (rate + MLX5_STAT_RATE_OFFSET) & | ||
| 2466 | MLX5_CAP_GEN(dev->mdev, stat_rate_support))) | ||
| 2467 | --rate; | ||
| 2468 | |||
| 2469 | return rate ? rate + MLX5_STAT_RATE_OFFSET : rate; | ||
| 2466 | } | 2470 | } |
| 2467 | 2471 | ||
| 2468 | static int modify_raw_packet_eth_prio(struct mlx5_core_dev *dev, | 2472 | static int modify_raw_packet_eth_prio(struct mlx5_core_dev *dev, |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 0a75164cedea..007d5e8a0121 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
| @@ -461,7 +461,7 @@ static bool nes_nic_send(struct sk_buff *skb, struct net_device *netdev) | |||
| 461 | /** | 461 | /** |
| 462 | * nes_netdev_start_xmit | 462 | * nes_netdev_start_xmit |
| 463 | */ | 463 | */ |
| 464 | static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) | 464 | static netdev_tx_t nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) |
| 465 | { | 465 | { |
| 466 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 466 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
| 467 | struct nes_device *nesdev = nesvnic->nesdev; | 467 | struct nes_device *nesdev = nesvnic->nesdev; |
diff --git a/drivers/infiniband/sw/rxe/rxe_opcode.c b/drivers/infiniband/sw/rxe/rxe_opcode.c index 61927c165b59..4cf11063e0b5 100644 --- a/drivers/infiniband/sw/rxe/rxe_opcode.c +++ b/drivers/infiniband/sw/rxe/rxe_opcode.c | |||
| @@ -390,7 +390,7 @@ struct rxe_opcode_info rxe_opcode[RXE_NUM_OPCODE] = { | |||
| 390 | .name = "IB_OPCODE_RC_SEND_ONLY_INV", | 390 | .name = "IB_OPCODE_RC_SEND_ONLY_INV", |
| 391 | .mask = RXE_IETH_MASK | RXE_PAYLOAD_MASK | RXE_REQ_MASK | 391 | .mask = RXE_IETH_MASK | RXE_PAYLOAD_MASK | RXE_REQ_MASK |
| 392 | | RXE_COMP_MASK | RXE_RWR_MASK | RXE_SEND_MASK | 392 | | RXE_COMP_MASK | RXE_RWR_MASK | RXE_SEND_MASK |
| 393 | | RXE_END_MASK, | 393 | | RXE_END_MASK | RXE_START_MASK, |
| 394 | .length = RXE_BTH_BYTES + RXE_IETH_BYTES, | 394 | .length = RXE_BTH_BYTES + RXE_IETH_BYTES, |
| 395 | .offset = { | 395 | .offset = { |
| 396 | [RXE_BTH] = 0, | 396 | [RXE_BTH] = 0, |
diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c index 7bdaf71b8221..785199990457 100644 --- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c | |||
| @@ -728,7 +728,6 @@ next_wqe: | |||
| 728 | rollback_state(wqe, qp, &rollback_wqe, rollback_psn); | 728 | rollback_state(wqe, qp, &rollback_wqe, rollback_psn); |
| 729 | 729 | ||
| 730 | if (ret == -EAGAIN) { | 730 | if (ret == -EAGAIN) { |
| 731 | kfree_skb(skb); | ||
| 732 | rxe_run_task(&qp->req.task, 1); | 731 | rxe_run_task(&qp->req.task, 1); |
| 733 | goto exit; | 732 | goto exit; |
| 734 | } | 733 | } |
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index a65c9969f7fc..955ff3b6da9c 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c | |||
| @@ -742,7 +742,6 @@ static enum resp_states read_reply(struct rxe_qp *qp, | |||
| 742 | err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); | 742 | err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); |
| 743 | if (err) { | 743 | if (err) { |
| 744 | pr_err("Failed sending RDMA reply.\n"); | 744 | pr_err("Failed sending RDMA reply.\n"); |
| 745 | kfree_skb(skb); | ||
| 746 | return RESPST_ERR_RNR; | 745 | return RESPST_ERR_RNR; |
| 747 | } | 746 | } |
| 748 | 747 | ||
| @@ -954,10 +953,8 @@ static int send_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, | |||
| 954 | } | 953 | } |
| 955 | 954 | ||
| 956 | err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); | 955 | err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); |
| 957 | if (err) { | 956 | if (err) |
| 958 | pr_err_ratelimited("Failed sending ack\n"); | 957 | pr_err_ratelimited("Failed sending ack\n"); |
| 959 | kfree_skb(skb); | ||
| 960 | } | ||
| 961 | 958 | ||
| 962 | err1: | 959 | err1: |
| 963 | return err; | 960 | return err; |
| @@ -1141,7 +1138,6 @@ static enum resp_states duplicate_request(struct rxe_qp *qp, | |||
| 1141 | if (rc) { | 1138 | if (rc) { |
| 1142 | pr_err("Failed resending result. This flow is not handled - skb ignored\n"); | 1139 | pr_err("Failed resending result. This flow is not handled - skb ignored\n"); |
| 1143 | rxe_drop_ref(qp); | 1140 | rxe_drop_ref(qp); |
| 1144 | kfree_skb(skb_copy); | ||
| 1145 | rc = RESPST_CLEANUP; | 1141 | rc = RESPST_CLEANUP; |
| 1146 | goto out; | 1142 | goto out; |
| 1147 | } | 1143 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 161ba8c76285..cf291f90b58f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -1094,7 +1094,7 @@ drop_and_unlock: | |||
| 1094 | spin_unlock_irqrestore(&priv->lock, flags); | 1094 | spin_unlock_irqrestore(&priv->lock, flags); |
| 1095 | } | 1095 | } |
| 1096 | 1096 | ||
| 1097 | static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | 1097 | static netdev_tx_t ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) |
| 1098 | { | 1098 | { |
| 1099 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 1099 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
| 1100 | struct rdma_netdev *rn = netdev_priv(dev); | 1100 | struct rdma_netdev *rn = netdev_priv(dev); |
diff --git a/drivers/infiniband/ulp/srp/Kconfig b/drivers/infiniband/ulp/srp/Kconfig index c74ee9633041..99db8fe5173a 100644 --- a/drivers/infiniband/ulp/srp/Kconfig +++ b/drivers/infiniband/ulp/srp/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config INFINIBAND_SRP | 1 | config INFINIBAND_SRP |
| 2 | tristate "InfiniBand SCSI RDMA Protocol" | 2 | tristate "InfiniBand SCSI RDMA Protocol" |
| 3 | depends on SCSI | 3 | depends on SCSI && INFINIBAND_ADDR_TRANS |
| 4 | select SCSI_SRP_ATTRS | 4 | select SCSI_SRP_ATTRS |
| 5 | ---help--- | 5 | ---help--- |
| 6 | Support for the SCSI RDMA Protocol over InfiniBand. This | 6 | Support for the SCSI RDMA Protocol over InfiniBand. This |
diff --git a/drivers/infiniband/ulp/srpt/Kconfig b/drivers/infiniband/ulp/srpt/Kconfig index 31ee83d528d9..fb8b7182f05e 100644 --- a/drivers/infiniband/ulp/srpt/Kconfig +++ b/drivers/infiniband/ulp/srpt/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config INFINIBAND_SRPT | 1 | config INFINIBAND_SRPT |
| 2 | tristate "InfiniBand SCSI RDMA Protocol target support" | 2 | tristate "InfiniBand SCSI RDMA Protocol target support" |
| 3 | depends on INFINIBAND && TARGET_CORE | 3 | depends on INFINIBAND && INFINIBAND_ADDR_TRANS && TARGET_CORE |
| 4 | ---help--- | 4 | ---help--- |
| 5 | 5 | ||
| 6 | Support for the SCSI RDMA Protocol (SRP) Target driver. The | 6 | Support for the SCSI RDMA Protocol (SRP) Target driver. The |
diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 766bf2660116..5f04b2d94635 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c | |||
| @@ -88,6 +88,7 @@ static int input_leds_connect(struct input_handler *handler, | |||
| 88 | const struct input_device_id *id) | 88 | const struct input_device_id *id) |
| 89 | { | 89 | { |
| 90 | struct input_leds *leds; | 90 | struct input_leds *leds; |
| 91 | struct input_led *led; | ||
| 91 | unsigned int num_leds; | 92 | unsigned int num_leds; |
| 92 | unsigned int led_code; | 93 | unsigned int led_code; |
| 93 | int led_no; | 94 | int led_no; |
| @@ -119,14 +120,13 @@ static int input_leds_connect(struct input_handler *handler, | |||
| 119 | 120 | ||
| 120 | led_no = 0; | 121 | led_no = 0; |
| 121 | for_each_set_bit(led_code, dev->ledbit, LED_CNT) { | 122 | for_each_set_bit(led_code, dev->ledbit, LED_CNT) { |
| 122 | struct input_led *led = &leds->leds[led_no]; | 123 | if (!input_led_info[led_code].name) |
| 124 | continue; | ||
| 123 | 125 | ||
| 126 | led = &leds->leds[led_no]; | ||
| 124 | led->handle = &leds->handle; | 127 | led->handle = &leds->handle; |
| 125 | led->code = led_code; | 128 | led->code = led_code; |
| 126 | 129 | ||
| 127 | if (!input_led_info[led_code].name) | ||
| 128 | continue; | ||
| 129 | |||
| 130 | led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", | 130 | led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", |
| 131 | dev_name(&dev->dev), | 131 | dev_name(&dev->dev), |
| 132 | input_led_info[led_code].name); | 132 | input_led_info[led_code].name); |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 0a67f235ba88..38f9501acdf0 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
| @@ -583,7 +583,7 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse) | |||
| 583 | 583 | ||
| 584 | x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f)); | 584 | x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f)); |
| 585 | y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f)); | 585 | y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f)); |
| 586 | z = packet[4] & 0x7c; | 586 | z = packet[4] & 0x7f; |
| 587 | 587 | ||
| 588 | /* | 588 | /* |
| 589 | * The x and y values tend to be quite large, and when used | 589 | * The x and y values tend to be quite large, and when used |
diff --git a/drivers/input/rmi4/rmi_spi.c b/drivers/input/rmi4/rmi_spi.c index 76edbf2c1bce..082defc329a8 100644 --- a/drivers/input/rmi4/rmi_spi.c +++ b/drivers/input/rmi4/rmi_spi.c | |||
| @@ -147,8 +147,11 @@ static int rmi_spi_xfer(struct rmi_spi_xport *rmi_spi, | |||
| 147 | if (len > RMI_SPI_XFER_SIZE_LIMIT) | 147 | if (len > RMI_SPI_XFER_SIZE_LIMIT) |
| 148 | return -EINVAL; | 148 | return -EINVAL; |
| 149 | 149 | ||
| 150 | if (rmi_spi->xfer_buf_size < len) | 150 | if (rmi_spi->xfer_buf_size < len) { |
| 151 | rmi_spi_manage_pools(rmi_spi, len); | 151 | ret = rmi_spi_manage_pools(rmi_spi, len); |
| 152 | if (ret < 0) | ||
| 153 | return ret; | ||
| 154 | } | ||
| 152 | 155 | ||
| 153 | if (addr == 0) | 156 | if (addr == 0) |
| 154 | /* | 157 | /* |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 4f15496fec8b..3e613afa10b4 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -362,7 +362,7 @@ config TOUCHSCREEN_HIDEEP | |||
| 362 | 362 | ||
| 363 | If unsure, say N. | 363 | If unsure, say N. |
| 364 | 364 | ||
| 365 | To compile this driver as a moudle, choose M here : the | 365 | To compile this driver as a module, choose M here : the |
| 366 | module will be called hideep_ts. | 366 | module will be called hideep_ts. |
| 367 | 367 | ||
| 368 | config TOUCHSCREEN_ILI210X | 368 | config TOUCHSCREEN_ILI210X |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 5d9699fe1b55..09194721aed2 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
| @@ -280,7 +280,8 @@ struct mxt_data { | |||
| 280 | struct input_dev *input_dev; | 280 | struct input_dev *input_dev; |
| 281 | char phys[64]; /* device physical location */ | 281 | char phys[64]; /* device physical location */ |
| 282 | struct mxt_object *object_table; | 282 | struct mxt_object *object_table; |
| 283 | struct mxt_info info; | 283 | struct mxt_info *info; |
| 284 | void *raw_info_block; | ||
| 284 | unsigned int irq; | 285 | unsigned int irq; |
| 285 | unsigned int max_x; | 286 | unsigned int max_x; |
| 286 | unsigned int max_y; | 287 | unsigned int max_y; |
| @@ -460,12 +461,13 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry) | |||
| 460 | { | 461 | { |
| 461 | u8 appmode = data->client->addr; | 462 | u8 appmode = data->client->addr; |
| 462 | u8 bootloader; | 463 | u8 bootloader; |
| 464 | u8 family_id = data->info ? data->info->family_id : 0; | ||
| 463 | 465 | ||
| 464 | switch (appmode) { | 466 | switch (appmode) { |
| 465 | case 0x4a: | 467 | case 0x4a: |
| 466 | case 0x4b: | 468 | case 0x4b: |
| 467 | /* Chips after 1664S use different scheme */ | 469 | /* Chips after 1664S use different scheme */ |
| 468 | if (retry || data->info.family_id >= 0xa2) { | 470 | if (retry || family_id >= 0xa2) { |
| 469 | bootloader = appmode - 0x24; | 471 | bootloader = appmode - 0x24; |
| 470 | break; | 472 | break; |
| 471 | } | 473 | } |
| @@ -692,7 +694,7 @@ mxt_get_object(struct mxt_data *data, u8 type) | |||
| 692 | struct mxt_object *object; | 694 | struct mxt_object *object; |
| 693 | int i; | 695 | int i; |
| 694 | 696 | ||
| 695 | for (i = 0; i < data->info.object_num; i++) { | 697 | for (i = 0; i < data->info->object_num; i++) { |
| 696 | object = data->object_table + i; | 698 | object = data->object_table + i; |
| 697 | if (object->type == type) | 699 | if (object->type == type) |
| 698 | return object; | 700 | return object; |
| @@ -1462,12 +1464,12 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
| 1462 | data_pos += offset; | 1464 | data_pos += offset; |
| 1463 | } | 1465 | } |
| 1464 | 1466 | ||
| 1465 | if (cfg_info.family_id != data->info.family_id) { | 1467 | if (cfg_info.family_id != data->info->family_id) { |
| 1466 | dev_err(dev, "Family ID mismatch!\n"); | 1468 | dev_err(dev, "Family ID mismatch!\n"); |
| 1467 | return -EINVAL; | 1469 | return -EINVAL; |
| 1468 | } | 1470 | } |
| 1469 | 1471 | ||
| 1470 | if (cfg_info.variant_id != data->info.variant_id) { | 1472 | if (cfg_info.variant_id != data->info->variant_id) { |
| 1471 | dev_err(dev, "Variant ID mismatch!\n"); | 1473 | dev_err(dev, "Variant ID mismatch!\n"); |
| 1472 | return -EINVAL; | 1474 | return -EINVAL; |
| 1473 | } | 1475 | } |
| @@ -1512,7 +1514,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
| 1512 | 1514 | ||
| 1513 | /* Malloc memory to store configuration */ | 1515 | /* Malloc memory to store configuration */ |
| 1514 | cfg_start_ofs = MXT_OBJECT_START + | 1516 | cfg_start_ofs = MXT_OBJECT_START + |
| 1515 | data->info.object_num * sizeof(struct mxt_object) + | 1517 | data->info->object_num * sizeof(struct mxt_object) + |
| 1516 | MXT_INFO_CHECKSUM_SIZE; | 1518 | MXT_INFO_CHECKSUM_SIZE; |
| 1517 | config_mem_size = data->mem_size - cfg_start_ofs; | 1519 | config_mem_size = data->mem_size - cfg_start_ofs; |
| 1518 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); | 1520 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); |
| @@ -1563,20 +1565,6 @@ release_mem: | |||
| 1563 | return ret; | 1565 | return ret; |
| 1564 | } | 1566 | } |
| 1565 | 1567 | ||
| 1566 | static int mxt_get_info(struct mxt_data *data) | ||
| 1567 | { | ||
| 1568 | struct i2c_client *client = data->client; | ||
| 1569 | struct mxt_info *info = &data->info; | ||
| 1570 | int error; | ||
| 1571 | |||
| 1572 | /* Read 7-byte info block starting at address 0 */ | ||
| 1573 | error = __mxt_read_reg(client, 0, sizeof(*info), info); | ||
| 1574 | if (error) | ||
| 1575 | return error; | ||
| 1576 | |||
| 1577 | return 0; | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | static void mxt_free_input_device(struct mxt_data *data) | 1568 | static void mxt_free_input_device(struct mxt_data *data) |
| 1581 | { | 1569 | { |
| 1582 | if (data->input_dev) { | 1570 | if (data->input_dev) { |
| @@ -1591,9 +1579,10 @@ static void mxt_free_object_table(struct mxt_data *data) | |||
| 1591 | video_unregister_device(&data->dbg.vdev); | 1579 | video_unregister_device(&data->dbg.vdev); |
| 1592 | v4l2_device_unregister(&data->dbg.v4l2); | 1580 | v4l2_device_unregister(&data->dbg.v4l2); |
| 1593 | #endif | 1581 | #endif |
| 1594 | |||
| 1595 | kfree(data->object_table); | ||
| 1596 | data->object_table = NULL; | 1582 | data->object_table = NULL; |
| 1583 | data->info = NULL; | ||
| 1584 | kfree(data->raw_info_block); | ||
| 1585 | data->raw_info_block = NULL; | ||
| 1597 | kfree(data->msg_buf); | 1586 | kfree(data->msg_buf); |
| 1598 | data->msg_buf = NULL; | 1587 | data->msg_buf = NULL; |
| 1599 | data->T5_address = 0; | 1588 | data->T5_address = 0; |
| @@ -1609,34 +1598,18 @@ static void mxt_free_object_table(struct mxt_data *data) | |||
| 1609 | data->max_reportid = 0; | 1598 | data->max_reportid = 0; |
| 1610 | } | 1599 | } |
| 1611 | 1600 | ||
| 1612 | static int mxt_get_object_table(struct mxt_data *data) | 1601 | static int mxt_parse_object_table(struct mxt_data *data, |
| 1602 | struct mxt_object *object_table) | ||
| 1613 | { | 1603 | { |
| 1614 | struct i2c_client *client = data->client; | 1604 | struct i2c_client *client = data->client; |
| 1615 | size_t table_size; | ||
| 1616 | struct mxt_object *object_table; | ||
| 1617 | int error; | ||
| 1618 | int i; | 1605 | int i; |
| 1619 | u8 reportid; | 1606 | u8 reportid; |
| 1620 | u16 end_address; | 1607 | u16 end_address; |
| 1621 | 1608 | ||
| 1622 | table_size = data->info.object_num * sizeof(struct mxt_object); | ||
| 1623 | object_table = kzalloc(table_size, GFP_KERNEL); | ||
| 1624 | if (!object_table) { | ||
| 1625 | dev_err(&data->client->dev, "Failed to allocate memory\n"); | ||
| 1626 | return -ENOMEM; | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | error = __mxt_read_reg(client, MXT_OBJECT_START, table_size, | ||
| 1630 | object_table); | ||
| 1631 | if (error) { | ||
| 1632 | kfree(object_table); | ||
| 1633 | return error; | ||
| 1634 | } | ||
| 1635 | |||
| 1636 | /* Valid Report IDs start counting from 1 */ | 1609 | /* Valid Report IDs start counting from 1 */ |
| 1637 | reportid = 1; | 1610 | reportid = 1; |
| 1638 | data->mem_size = 0; | 1611 | data->mem_size = 0; |
| 1639 | for (i = 0; i < data->info.object_num; i++) { | 1612 | for (i = 0; i < data->info->object_num; i++) { |
| 1640 | struct mxt_object *object = object_table + i; | 1613 | struct mxt_object *object = object_table + i; |
| 1641 | u8 min_id, max_id; | 1614 | u8 min_id, max_id; |
| 1642 | 1615 | ||
| @@ -1660,8 +1633,8 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
| 1660 | 1633 | ||
| 1661 | switch (object->type) { | 1634 | switch (object->type) { |
| 1662 | case MXT_GEN_MESSAGE_T5: | 1635 | case MXT_GEN_MESSAGE_T5: |
| 1663 | if (data->info.family_id == 0x80 && | 1636 | if (data->info->family_id == 0x80 && |
| 1664 | data->info.version < 0x20) { | 1637 | data->info->version < 0x20) { |
| 1665 | /* | 1638 | /* |
| 1666 | * On mXT224 firmware versions prior to V2.0 | 1639 | * On mXT224 firmware versions prior to V2.0 |
| 1667 | * read and discard unused CRC byte otherwise | 1640 | * read and discard unused CRC byte otherwise |
| @@ -1716,24 +1689,102 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
| 1716 | /* If T44 exists, T5 position has to be directly after */ | 1689 | /* If T44 exists, T5 position has to be directly after */ |
| 1717 | if (data->T44_address && (data->T5_address != data->T44_address + 1)) { | 1690 | if (data->T44_address && (data->T5_address != data->T44_address + 1)) { |
| 1718 | dev_err(&client->dev, "Invalid T44 position\n"); | 1691 | dev_err(&client->dev, "Invalid T44 position\n"); |
| 1719 | error = -EINVAL; | 1692 | return -EINVAL; |
| 1720 | goto free_object_table; | ||
| 1721 | } | 1693 | } |
| 1722 | 1694 | ||
| 1723 | data->msg_buf = kcalloc(data->max_reportid, | 1695 | data->msg_buf = kcalloc(data->max_reportid, |
| 1724 | data->T5_msg_size, GFP_KERNEL); | 1696 | data->T5_msg_size, GFP_KERNEL); |
| 1725 | if (!data->msg_buf) { | 1697 | if (!data->msg_buf) |
| 1726 | dev_err(&client->dev, "Failed to allocate message buffer\n"); | 1698 | return -ENOMEM; |
| 1699 | |||
| 1700 | return 0; | ||
| 1701 | } | ||
| 1702 | |||
| 1703 | static int mxt_read_info_block(struct mxt_data *data) | ||
| 1704 | { | ||
| 1705 | struct i2c_client *client = data->client; | ||
| 1706 | int error; | ||
| 1707 | size_t size; | ||
| 1708 | void *id_buf, *buf; | ||
| 1709 | uint8_t num_objects; | ||
| 1710 | u32 calculated_crc; | ||
| 1711 | u8 *crc_ptr; | ||
| 1712 | |||
| 1713 | /* If info block already allocated, free it */ | ||
| 1714 | if (data->raw_info_block) | ||
| 1715 | mxt_free_object_table(data); | ||
| 1716 | |||
| 1717 | /* Read 7-byte ID information block starting at address 0 */ | ||
| 1718 | size = sizeof(struct mxt_info); | ||
| 1719 | id_buf = kzalloc(size, GFP_KERNEL); | ||
| 1720 | if (!id_buf) | ||
| 1721 | return -ENOMEM; | ||
| 1722 | |||
| 1723 | error = __mxt_read_reg(client, 0, size, id_buf); | ||
| 1724 | if (error) | ||
| 1725 | goto err_free_mem; | ||
| 1726 | |||
| 1727 | /* Resize buffer to give space for rest of info block */ | ||
| 1728 | num_objects = ((struct mxt_info *)id_buf)->object_num; | ||
| 1729 | size += (num_objects * sizeof(struct mxt_object)) | ||
| 1730 | + MXT_INFO_CHECKSUM_SIZE; | ||
| 1731 | |||
| 1732 | buf = krealloc(id_buf, size, GFP_KERNEL); | ||
| 1733 | if (!buf) { | ||
| 1727 | error = -ENOMEM; | 1734 | error = -ENOMEM; |
| 1728 | goto free_object_table; | 1735 | goto err_free_mem; |
| 1736 | } | ||
| 1737 | id_buf = buf; | ||
| 1738 | |||
| 1739 | /* Read rest of info block */ | ||
| 1740 | error = __mxt_read_reg(client, MXT_OBJECT_START, | ||
| 1741 | size - MXT_OBJECT_START, | ||
| 1742 | id_buf + MXT_OBJECT_START); | ||
| 1743 | if (error) | ||
| 1744 | goto err_free_mem; | ||
| 1745 | |||
| 1746 | /* Extract & calculate checksum */ | ||
| 1747 | crc_ptr = id_buf + size - MXT_INFO_CHECKSUM_SIZE; | ||
| 1748 | data->info_crc = crc_ptr[0] | (crc_ptr[1] << 8) | (crc_ptr[2] << 16); | ||
| 1749 | |||
| 1750 | calculated_crc = mxt_calculate_crc(id_buf, 0, | ||
| 1751 | size - MXT_INFO_CHECKSUM_SIZE); | ||
| 1752 | |||
| 1753 | /* | ||
| 1754 | * CRC mismatch can be caused by data corruption due to I2C comms | ||
| 1755 | * issue or else device is not using Object Based Protocol (eg i2c-hid) | ||
| 1756 | */ | ||
| 1757 | if ((data->info_crc == 0) || (data->info_crc != calculated_crc)) { | ||
| 1758 | dev_err(&client->dev, | ||
| 1759 | "Info Block CRC error calculated=0x%06X read=0x%06X\n", | ||
| 1760 | calculated_crc, data->info_crc); | ||
| 1761 | error = -EIO; | ||
| 1762 | goto err_free_mem; | ||
| 1763 | } | ||
| 1764 | |||
| 1765 | data->raw_info_block = id_buf; | ||
| 1766 | data->info = (struct mxt_info *)id_buf; | ||
| 1767 | |||
| 1768 | dev_info(&client->dev, | ||
| 1769 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", | ||
| 1770 | data->info->family_id, data->info->variant_id, | ||
| 1771 | data->info->version >> 4, data->info->version & 0xf, | ||
| 1772 | data->info->build, data->info->object_num); | ||
| 1773 | |||
| 1774 | /* Parse object table information */ | ||
| 1775 | error = mxt_parse_object_table(data, id_buf + MXT_OBJECT_START); | ||
| 1776 | if (error) { | ||
| 1777 | dev_err(&client->dev, "Error %d parsing object table\n", error); | ||
| 1778 | mxt_free_object_table(data); | ||
| 1779 | goto err_free_mem; | ||
| 1729 | } | 1780 | } |
| 1730 | 1781 | ||
| 1731 | data->object_table = object_table; | 1782 | data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START); |
| 1732 | 1783 | ||
| 1733 | return 0; | 1784 | return 0; |
| 1734 | 1785 | ||
| 1735 | free_object_table: | 1786 | err_free_mem: |
| 1736 | mxt_free_object_table(data); | 1787 | kfree(id_buf); |
| 1737 | return error; | 1788 | return error; |
| 1738 | } | 1789 | } |
| 1739 | 1790 | ||
| @@ -2046,7 +2097,7 @@ static int mxt_initialize(struct mxt_data *data) | |||
| 2046 | int error; | 2097 | int error; |
| 2047 | 2098 | ||
| 2048 | while (1) { | 2099 | while (1) { |
| 2049 | error = mxt_get_info(data); | 2100 | error = mxt_read_info_block(data); |
| 2050 | if (!error) | 2101 | if (!error) |
| 2051 | break; | 2102 | break; |
| 2052 | 2103 | ||
| @@ -2077,16 +2128,9 @@ static int mxt_initialize(struct mxt_data *data) | |||
| 2077 | msleep(MXT_FW_RESET_TIME); | 2128 | msleep(MXT_FW_RESET_TIME); |
| 2078 | } | 2129 | } |
| 2079 | 2130 | ||
| 2080 | /* Get object table information */ | ||
| 2081 | error = mxt_get_object_table(data); | ||
| 2082 | if (error) { | ||
| 2083 | dev_err(&client->dev, "Error %d reading object table\n", error); | ||
| 2084 | return error; | ||
| 2085 | } | ||
| 2086 | |||
| 2087 | error = mxt_acquire_irq(data); | 2131 | error = mxt_acquire_irq(data); |
| 2088 | if (error) | 2132 | if (error) |
| 2089 | goto err_free_object_table; | 2133 | return error; |
| 2090 | 2134 | ||
| 2091 | error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, | 2135 | error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, |
| 2092 | &client->dev, GFP_KERNEL, data, | 2136 | &client->dev, GFP_KERNEL, data, |
| @@ -2094,14 +2138,10 @@ static int mxt_initialize(struct mxt_data *data) | |||
| 2094 | if (error) { | 2138 | if (error) { |
| 2095 | dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", | 2139 | dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", |
| 2096 | error); | 2140 | error); |
| 2097 | goto err_free_object_table; | 2141 | return error; |
| 2098 | } | 2142 | } |
| 2099 | 2143 | ||
| 2100 | return 0; | 2144 | return 0; |
| 2101 | |||
| 2102 | err_free_object_table: | ||
| 2103 | mxt_free_object_table(data); | ||
| 2104 | return error; | ||
| 2105 | } | 2145 | } |
| 2106 | 2146 | ||
| 2107 | static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) | 2147 | static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) |
| @@ -2162,7 +2202,7 @@ recheck: | |||
| 2162 | static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x, | 2202 | static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x, |
| 2163 | unsigned int y) | 2203 | unsigned int y) |
| 2164 | { | 2204 | { |
| 2165 | struct mxt_info *info = &data->info; | 2205 | struct mxt_info *info = data->info; |
| 2166 | struct mxt_dbg *dbg = &data->dbg; | 2206 | struct mxt_dbg *dbg = &data->dbg; |
| 2167 | unsigned int ofs, page; | 2207 | unsigned int ofs, page; |
| 2168 | unsigned int col = 0; | 2208 | unsigned int col = 0; |
| @@ -2490,7 +2530,7 @@ static const struct video_device mxt_video_device = { | |||
| 2490 | 2530 | ||
| 2491 | static void mxt_debug_init(struct mxt_data *data) | 2531 | static void mxt_debug_init(struct mxt_data *data) |
| 2492 | { | 2532 | { |
| 2493 | struct mxt_info *info = &data->info; | 2533 | struct mxt_info *info = data->info; |
| 2494 | struct mxt_dbg *dbg = &data->dbg; | 2534 | struct mxt_dbg *dbg = &data->dbg; |
| 2495 | struct mxt_object *object; | 2535 | struct mxt_object *object; |
| 2496 | int error; | 2536 | int error; |
| @@ -2576,7 +2616,6 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
| 2576 | const struct firmware *cfg) | 2616 | const struct firmware *cfg) |
| 2577 | { | 2617 | { |
| 2578 | struct device *dev = &data->client->dev; | 2618 | struct device *dev = &data->client->dev; |
| 2579 | struct mxt_info *info = &data->info; | ||
| 2580 | int error; | 2619 | int error; |
| 2581 | 2620 | ||
| 2582 | error = mxt_init_t7_power_cfg(data); | 2621 | error = mxt_init_t7_power_cfg(data); |
| @@ -2601,11 +2640,6 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
| 2601 | 2640 | ||
| 2602 | mxt_debug_init(data); | 2641 | mxt_debug_init(data); |
| 2603 | 2642 | ||
| 2604 | dev_info(dev, | ||
| 2605 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", | ||
| 2606 | info->family_id, info->variant_id, info->version >> 4, | ||
| 2607 | info->version & 0xf, info->build, info->object_num); | ||
| 2608 | |||
| 2609 | return 0; | 2643 | return 0; |
| 2610 | } | 2644 | } |
| 2611 | 2645 | ||
| @@ -2614,7 +2648,7 @@ static ssize_t mxt_fw_version_show(struct device *dev, | |||
| 2614 | struct device_attribute *attr, char *buf) | 2648 | struct device_attribute *attr, char *buf) |
| 2615 | { | 2649 | { |
| 2616 | struct mxt_data *data = dev_get_drvdata(dev); | 2650 | struct mxt_data *data = dev_get_drvdata(dev); |
| 2617 | struct mxt_info *info = &data->info; | 2651 | struct mxt_info *info = data->info; |
| 2618 | return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n", | 2652 | return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n", |
| 2619 | info->version >> 4, info->version & 0xf, info->build); | 2653 | info->version >> 4, info->version & 0xf, info->build); |
| 2620 | } | 2654 | } |
| @@ -2624,7 +2658,7 @@ static ssize_t mxt_hw_version_show(struct device *dev, | |||
| 2624 | struct device_attribute *attr, char *buf) | 2658 | struct device_attribute *attr, char *buf) |
| 2625 | { | 2659 | { |
| 2626 | struct mxt_data *data = dev_get_drvdata(dev); | 2660 | struct mxt_data *data = dev_get_drvdata(dev); |
| 2627 | struct mxt_info *info = &data->info; | 2661 | struct mxt_info *info = data->info; |
| 2628 | return scnprintf(buf, PAGE_SIZE, "%u.%u\n", | 2662 | return scnprintf(buf, PAGE_SIZE, "%u.%u\n", |
| 2629 | info->family_id, info->variant_id); | 2663 | info->family_id, info->variant_id); |
| 2630 | } | 2664 | } |
| @@ -2663,7 +2697,7 @@ static ssize_t mxt_object_show(struct device *dev, | |||
| 2663 | return -ENOMEM; | 2697 | return -ENOMEM; |
| 2664 | 2698 | ||
| 2665 | error = 0; | 2699 | error = 0; |
| 2666 | for (i = 0; i < data->info.object_num; i++) { | 2700 | for (i = 0; i < data->info->object_num; i++) { |
| 2667 | object = data->object_table + i; | 2701 | object = data->object_table + i; |
| 2668 | 2702 | ||
| 2669 | if (!mxt_object_readable(object->type)) | 2703 | if (!mxt_object_readable(object->type)) |
| @@ -3035,6 +3069,15 @@ static const struct dmi_system_id mxt_dmi_table[] = { | |||
| 3035 | .driver_data = samus_platform_data, | 3069 | .driver_data = samus_platform_data, |
| 3036 | }, | 3070 | }, |
| 3037 | { | 3071 | { |
| 3072 | /* Samsung Chromebook Pro */ | ||
| 3073 | .ident = "Samsung Chromebook Pro", | ||
| 3074 | .matches = { | ||
| 3075 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | ||
| 3076 | DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"), | ||
| 3077 | }, | ||
| 3078 | .driver_data = samus_platform_data, | ||
| 3079 | }, | ||
| 3080 | { | ||
| 3038 | /* Other Google Chromebooks */ | 3081 | /* Other Google Chromebooks */ |
| 3039 | .ident = "Chromebook", | 3082 | .ident = "Chromebook", |
| 3040 | .matches = { | 3083 | .matches = { |
| @@ -3254,6 +3297,11 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); | |||
| 3254 | 3297 | ||
| 3255 | static const struct of_device_id mxt_of_match[] = { | 3298 | static const struct of_device_id mxt_of_match[] = { |
| 3256 | { .compatible = "atmel,maxtouch", }, | 3299 | { .compatible = "atmel,maxtouch", }, |
| 3300 | /* Compatibles listed below are deprecated */ | ||
| 3301 | { .compatible = "atmel,qt602240_ts", }, | ||
| 3302 | { .compatible = "atmel,atmel_mxt_ts", }, | ||
| 3303 | { .compatible = "atmel,atmel_mxt_tp", }, | ||
| 3304 | { .compatible = "atmel,mXT224", }, | ||
| 3257 | {}, | 3305 | {}, |
| 3258 | }; | 3306 | }; |
| 3259 | MODULE_DEVICE_TABLE(of, mxt_of_match); | 3307 | MODULE_DEVICE_TABLE(of, mxt_of_match); |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 2a99f0f14795..8fb8c737fffe 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
| @@ -83,7 +83,6 @@ | |||
| 83 | 83 | ||
| 84 | static DEFINE_SPINLOCK(amd_iommu_devtable_lock); | 84 | static DEFINE_SPINLOCK(amd_iommu_devtable_lock); |
| 85 | static DEFINE_SPINLOCK(pd_bitmap_lock); | 85 | static DEFINE_SPINLOCK(pd_bitmap_lock); |
| 86 | static DEFINE_SPINLOCK(iommu_table_lock); | ||
| 87 | 86 | ||
| 88 | /* List of all available dev_data structures */ | 87 | /* List of all available dev_data structures */ |
| 89 | static LLIST_HEAD(dev_data_list); | 88 | static LLIST_HEAD(dev_data_list); |
| @@ -3562,6 +3561,7 @@ EXPORT_SYMBOL(amd_iommu_device_info); | |||
| 3562 | *****************************************************************************/ | 3561 | *****************************************************************************/ |
| 3563 | 3562 | ||
| 3564 | static struct irq_chip amd_ir_chip; | 3563 | static struct irq_chip amd_ir_chip; |
| 3564 | static DEFINE_SPINLOCK(iommu_table_lock); | ||
| 3565 | 3565 | ||
| 3566 | static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) | 3566 | static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) |
| 3567 | { | 3567 | { |
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index f05f3cf90756..ddcbbdb5d658 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c | |||
| @@ -167,40 +167,16 @@ EXPORT_SYMBOL(iommu_put_dma_cookie); | |||
| 167 | * @list: Reserved region list from iommu_get_resv_regions() | 167 | * @list: Reserved region list from iommu_get_resv_regions() |
| 168 | * | 168 | * |
| 169 | * IOMMU drivers can use this to implement their .get_resv_regions callback | 169 | * IOMMU drivers can use this to implement their .get_resv_regions callback |
| 170 | * for general non-IOMMU-specific reservations. Currently, this covers host | 170 | * for general non-IOMMU-specific reservations. Currently, this covers GICv3 |
| 171 | * bridge windows for PCI devices and GICv3 ITS region reservation on ACPI | 171 | * ITS region reservation on ACPI based ARM platforms that may require HW MSI |
| 172 | * based ARM platforms that may require HW MSI reservation. | 172 | * reservation. |
| 173 | */ | 173 | */ |
| 174 | void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list) | 174 | void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list) |
| 175 | { | 175 | { |
| 176 | struct pci_host_bridge *bridge; | ||
| 177 | struct resource_entry *window; | ||
| 178 | |||
| 179 | if (!is_of_node(dev->iommu_fwspec->iommu_fwnode) && | ||
| 180 | iort_iommu_msi_get_resv_regions(dev, list) < 0) | ||
| 181 | return; | ||
| 182 | |||
| 183 | if (!dev_is_pci(dev)) | ||
| 184 | return; | ||
| 185 | |||
| 186 | bridge = pci_find_host_bridge(to_pci_dev(dev)->bus); | ||
| 187 | resource_list_for_each_entry(window, &bridge->windows) { | ||
| 188 | struct iommu_resv_region *region; | ||
| 189 | phys_addr_t start; | ||
| 190 | size_t length; | ||
| 191 | |||
| 192 | if (resource_type(window->res) != IORESOURCE_MEM) | ||
| 193 | continue; | ||
| 194 | 176 | ||
| 195 | start = window->res->start - window->offset; | 177 | if (!is_of_node(dev->iommu_fwspec->iommu_fwnode)) |
| 196 | length = window->res->end - window->res->start + 1; | 178 | iort_iommu_msi_get_resv_regions(dev, list); |
| 197 | region = iommu_alloc_resv_region(start, length, 0, | ||
| 198 | IOMMU_RESV_RESERVED); | ||
| 199 | if (!region) | ||
| 200 | return; | ||
| 201 | 179 | ||
| 202 | list_add_tail(®ion->list, list); | ||
| 203 | } | ||
| 204 | } | 180 | } |
| 205 | EXPORT_SYMBOL(iommu_dma_get_resv_regions); | 181 | EXPORT_SYMBOL(iommu_dma_get_resv_regions); |
| 206 | 182 | ||
| @@ -229,6 +205,23 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie, | |||
| 229 | return 0; | 205 | return 0; |
| 230 | } | 206 | } |
| 231 | 207 | ||
| 208 | static void iova_reserve_pci_windows(struct pci_dev *dev, | ||
| 209 | struct iova_domain *iovad) | ||
| 210 | { | ||
| 211 | struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus); | ||
| 212 | struct resource_entry *window; | ||
| 213 | unsigned long lo, hi; | ||
| 214 | |||
| 215 | resource_list_for_each_entry(window, &bridge->windows) { | ||
| 216 | if (resource_type(window->res) != IORESOURCE_MEM) | ||
| 217 | continue; | ||
| 218 | |||
| 219 | lo = iova_pfn(iovad, window->res->start - window->offset); | ||
| 220 | hi = iova_pfn(iovad, window->res->end - window->offset); | ||
| 221 | reserve_iova(iovad, lo, hi); | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 232 | static int iova_reserve_iommu_regions(struct device *dev, | 225 | static int iova_reserve_iommu_regions(struct device *dev, |
| 233 | struct iommu_domain *domain) | 226 | struct iommu_domain *domain) |
| 234 | { | 227 | { |
| @@ -238,6 +231,9 @@ static int iova_reserve_iommu_regions(struct device *dev, | |||
| 238 | LIST_HEAD(resv_regions); | 231 | LIST_HEAD(resv_regions); |
| 239 | int ret = 0; | 232 | int ret = 0; |
| 240 | 233 | ||
| 234 | if (dev_is_pci(dev)) | ||
| 235 | iova_reserve_pci_windows(to_pci_dev(dev), iovad); | ||
| 236 | |||
| 241 | iommu_get_resv_regions(dev, &resv_regions); | 237 | iommu_get_resv_regions(dev, &resv_regions); |
| 242 | list_for_each_entry(region, &resv_regions, list) { | 238 | list_for_each_entry(region, &resv_regions, list) { |
| 243 | unsigned long lo, hi; | 239 | unsigned long lo, hi; |
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index accf58388bdb..460bed4fc5b1 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c | |||
| @@ -1345,7 +1345,7 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep, | |||
| 1345 | struct qi_desc desc; | 1345 | struct qi_desc desc; |
| 1346 | 1346 | ||
| 1347 | if (mask) { | 1347 | if (mask) { |
| 1348 | BUG_ON(addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1)); | 1348 | WARN_ON_ONCE(addr & ((1ULL << (VTD_PAGE_SHIFT + mask)) - 1)); |
| 1349 | addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1; | 1349 | addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1; |
| 1350 | desc.high = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE; | 1350 | desc.high = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE; |
| 1351 | } else | 1351 | } else |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 66f69af2c219..3062a154a9fb 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
| @@ -1136,7 +1136,7 @@ static void intel_ir_reconfigure_irte(struct irq_data *irqd, bool force) | |||
| 1136 | irte->dest_id = IRTE_DEST(cfg->dest_apicid); | 1136 | irte->dest_id = IRTE_DEST(cfg->dest_apicid); |
| 1137 | 1137 | ||
| 1138 | /* Update the hardware only if the interrupt is in remapped mode. */ | 1138 | /* Update the hardware only if the interrupt is in remapped mode. */ |
| 1139 | if (!force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING) | 1139 | if (force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING) |
| 1140 | modify_irte(&ir_data->irq_2_iommu, irte); | 1140 | modify_irte(&ir_data->irq_2_iommu, irte); |
| 1141 | } | 1141 | } |
| 1142 | 1142 | ||
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 5fc8656c60f9..0468acfa131f 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c | |||
| @@ -1098,7 +1098,7 @@ static int rk_iommu_of_xlate(struct device *dev, | |||
| 1098 | data->iommu = platform_get_drvdata(iommu_dev); | 1098 | data->iommu = platform_get_drvdata(iommu_dev); |
| 1099 | dev->archdata.iommu = data; | 1099 | dev->archdata.iommu = data; |
| 1100 | 1100 | ||
| 1101 | of_dev_put(iommu_dev); | 1101 | platform_device_put(iommu_dev); |
| 1102 | 1102 | ||
| 1103 | return 0; | 1103 | return 0; |
| 1104 | } | 1104 | } |
| @@ -1175,8 +1175,15 @@ static int rk_iommu_probe(struct platform_device *pdev) | |||
| 1175 | for (i = 0; i < iommu->num_clocks; ++i) | 1175 | for (i = 0; i < iommu->num_clocks; ++i) |
| 1176 | iommu->clocks[i].id = rk_iommu_clocks[i]; | 1176 | iommu->clocks[i].id = rk_iommu_clocks[i]; |
| 1177 | 1177 | ||
| 1178 | /* | ||
| 1179 | * iommu clocks should be present for all new devices and devicetrees | ||
| 1180 | * but there are older devicetrees without clocks out in the wild. | ||
| 1181 | * So clocks as optional for the time being. | ||
| 1182 | */ | ||
| 1178 | err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks); | 1183 | err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks); |
| 1179 | if (err) | 1184 | if (err == -ENOENT) |
| 1185 | iommu->num_clocks = 0; | ||
| 1186 | else if (err) | ||
| 1180 | return err; | 1187 | return err; |
| 1181 | 1188 | ||
| 1182 | err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks); | 1189 | err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks); |
diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c index f31265937439..7f0c0be322e0 100644 --- a/drivers/irqchip/qcom-irq-combiner.c +++ b/drivers/irqchip/qcom-irq-combiner.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. | 1 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 2 | * | 2 | * |
| 3 | * This program is free software; you can redistribute it and/or modify | 3 | * This program is free software; you can redistribute it and/or modify |
| 4 | * it under the terms of the GNU General Public License version 2 and | 4 | * it under the terms of the GNU General Public License version 2 and |
| @@ -68,7 +68,7 @@ static void combiner_handle_irq(struct irq_desc *desc) | |||
| 68 | 68 | ||
| 69 | bit = readl_relaxed(combiner->regs[reg].addr); | 69 | bit = readl_relaxed(combiner->regs[reg].addr); |
| 70 | status = bit & combiner->regs[reg].enabled; | 70 | status = bit & combiner->regs[reg].enabled; |
| 71 | if (!status) | 71 | if (bit && !status) |
| 72 | pr_warn_ratelimited("Unexpected IRQ on CPU%d: (%08x %08lx %p)\n", | 72 | pr_warn_ratelimited("Unexpected IRQ on CPU%d: (%08x %08lx %p)\n", |
| 73 | smp_processor_id(), bit, | 73 | smp_processor_id(), bit, |
| 74 | combiner->regs[reg].enabled, | 74 | combiner->regs[reg].enabled, |
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 3ef7f036ceea..fc3c237daef2 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c | |||
| @@ -373,33 +373,24 @@ static const struct mbox_chan_ops pcc_chan_ops = { | |||
| 373 | }; | 373 | }; |
| 374 | 374 | ||
| 375 | /** | 375 | /** |
| 376 | * parse_pcc_subspace - Parse the PCC table and verify PCC subspace | 376 | * parse_pcc_subspaces -- Count PCC subspaces defined |
| 377 | * entries. There should be one entry per PCC client. | ||
| 378 | * @header: Pointer to the ACPI subtable header under the PCCT. | 377 | * @header: Pointer to the ACPI subtable header under the PCCT. |
| 379 | * @end: End of subtable entry. | 378 | * @end: End of subtable entry. |
| 380 | * | 379 | * |
| 381 | * Return: 0 for Success, else errno. | 380 | * Return: If we find a PCC subspace entry of a valid type, return 0. |
| 381 | * Otherwise, return -EINVAL. | ||
| 382 | * | 382 | * |
| 383 | * This gets called for each entry in the PCC table. | 383 | * This gets called for each entry in the PCC table. |
| 384 | */ | 384 | */ |
| 385 | static int parse_pcc_subspace(struct acpi_subtable_header *header, | 385 | static int parse_pcc_subspace(struct acpi_subtable_header *header, |
| 386 | const unsigned long end) | 386 | const unsigned long end) |
| 387 | { | 387 | { |
| 388 | struct acpi_pcct_hw_reduced *pcct_ss; | 388 | struct acpi_pcct_subspace *ss = (struct acpi_pcct_subspace *) header; |
| 389 | |||
| 390 | if (pcc_mbox_ctrl.num_chans <= MAX_PCC_SUBSPACES) { | ||
| 391 | pcct_ss = (struct acpi_pcct_hw_reduced *) header; | ||
| 392 | 389 | ||
| 393 | if ((pcct_ss->header.type != | 390 | if (ss->header.type < ACPI_PCCT_TYPE_RESERVED) |
| 394 | ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) | 391 | return 0; |
| 395 | && (pcct_ss->header.type != | ||
| 396 | ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) { | ||
| 397 | pr_err("Incorrect PCC Subspace type detected\n"); | ||
| 398 | return -EINVAL; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | 392 | ||
| 402 | return 0; | 393 | return -EINVAL; |
| 403 | } | 394 | } |
| 404 | 395 | ||
| 405 | /** | 396 | /** |
| @@ -449,8 +440,8 @@ static int __init acpi_pcc_probe(void) | |||
| 449 | struct acpi_table_header *pcct_tbl; | 440 | struct acpi_table_header *pcct_tbl; |
| 450 | struct acpi_subtable_header *pcct_entry; | 441 | struct acpi_subtable_header *pcct_entry; |
| 451 | struct acpi_table_pcct *acpi_pcct_tbl; | 442 | struct acpi_table_pcct *acpi_pcct_tbl; |
| 443 | struct acpi_subtable_proc proc[ACPI_PCCT_TYPE_RESERVED]; | ||
| 452 | int count, i, rc; | 444 | int count, i, rc; |
| 453 | int sum = 0; | ||
| 454 | acpi_status status = AE_OK; | 445 | acpi_status status = AE_OK; |
| 455 | 446 | ||
| 456 | /* Search for PCCT */ | 447 | /* Search for PCCT */ |
| @@ -459,43 +450,41 @@ static int __init acpi_pcc_probe(void) | |||
| 459 | if (ACPI_FAILURE(status) || !pcct_tbl) | 450 | if (ACPI_FAILURE(status) || !pcct_tbl) |
| 460 | return -ENODEV; | 451 | return -ENODEV; |
| 461 | 452 | ||
| 462 | count = acpi_table_parse_entries(ACPI_SIG_PCCT, | 453 | /* Set up the subtable handlers */ |
| 463 | sizeof(struct acpi_table_pcct), | 454 | for (i = ACPI_PCCT_TYPE_GENERIC_SUBSPACE; |
| 464 | ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE, | 455 | i < ACPI_PCCT_TYPE_RESERVED; i++) { |
| 465 | parse_pcc_subspace, MAX_PCC_SUBSPACES); | 456 | proc[i].id = i; |
| 466 | sum += (count > 0) ? count : 0; | 457 | proc[i].count = 0; |
| 467 | 458 | proc[i].handler = parse_pcc_subspace; | |
| 468 | count = acpi_table_parse_entries(ACPI_SIG_PCCT, | 459 | } |
| 469 | sizeof(struct acpi_table_pcct), | ||
| 470 | ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2, | ||
| 471 | parse_pcc_subspace, MAX_PCC_SUBSPACES); | ||
| 472 | sum += (count > 0) ? count : 0; | ||
| 473 | 460 | ||
| 474 | if (sum == 0 || sum >= MAX_PCC_SUBSPACES) { | 461 | count = acpi_table_parse_entries_array(ACPI_SIG_PCCT, |
| 475 | pr_err("Error parsing PCC subspaces from PCCT\n"); | 462 | sizeof(struct acpi_table_pcct), proc, |
| 463 | ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES); | ||
| 464 | if (count == 0 || count > MAX_PCC_SUBSPACES) { | ||
| 465 | pr_warn("Invalid PCCT: %d PCC subspaces\n", count); | ||
| 476 | return -EINVAL; | 466 | return -EINVAL; |
| 477 | } | 467 | } |
| 478 | 468 | ||
| 479 | pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * | 469 | pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * count, GFP_KERNEL); |
| 480 | sum, GFP_KERNEL); | ||
| 481 | if (!pcc_mbox_channels) { | 470 | if (!pcc_mbox_channels) { |
| 482 | pr_err("Could not allocate space for PCC mbox channels\n"); | 471 | pr_err("Could not allocate space for PCC mbox channels\n"); |
| 483 | return -ENOMEM; | 472 | return -ENOMEM; |
| 484 | } | 473 | } |
| 485 | 474 | ||
| 486 | pcc_doorbell_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL); | 475 | pcc_doorbell_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL); |
| 487 | if (!pcc_doorbell_vaddr) { | 476 | if (!pcc_doorbell_vaddr) { |
| 488 | rc = -ENOMEM; | 477 | rc = -ENOMEM; |
| 489 | goto err_free_mbox; | 478 | goto err_free_mbox; |
| 490 | } | 479 | } |
| 491 | 480 | ||
| 492 | pcc_doorbell_ack_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL); | 481 | pcc_doorbell_ack_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL); |
| 493 | if (!pcc_doorbell_ack_vaddr) { | 482 | if (!pcc_doorbell_ack_vaddr) { |
| 494 | rc = -ENOMEM; | 483 | rc = -ENOMEM; |
| 495 | goto err_free_db_vaddr; | 484 | goto err_free_db_vaddr; |
| 496 | } | 485 | } |
| 497 | 486 | ||
| 498 | pcc_doorbell_irq = kcalloc(sum, sizeof(int), GFP_KERNEL); | 487 | pcc_doorbell_irq = kcalloc(count, sizeof(int), GFP_KERNEL); |
| 499 | if (!pcc_doorbell_irq) { | 488 | if (!pcc_doorbell_irq) { |
| 500 | rc = -ENOMEM; | 489 | rc = -ENOMEM; |
| 501 | goto err_free_db_ack_vaddr; | 490 | goto err_free_db_ack_vaddr; |
| @@ -509,18 +498,24 @@ static int __init acpi_pcc_probe(void) | |||
| 509 | if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) | 498 | if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) |
| 510 | pcc_mbox_ctrl.txdone_irq = true; | 499 | pcc_mbox_ctrl.txdone_irq = true; |
| 511 | 500 | ||
| 512 | for (i = 0; i < sum; i++) { | 501 | for (i = 0; i < count; i++) { |
| 513 | struct acpi_generic_address *db_reg; | 502 | struct acpi_generic_address *db_reg; |
| 514 | struct acpi_pcct_hw_reduced *pcct_ss; | 503 | struct acpi_pcct_subspace *pcct_ss; |
| 515 | pcc_mbox_channels[i].con_priv = pcct_entry; | 504 | pcc_mbox_channels[i].con_priv = pcct_entry; |
| 516 | 505 | ||
| 517 | pcct_ss = (struct acpi_pcct_hw_reduced *) pcct_entry; | 506 | if (pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE || |
| 507 | pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) { | ||
| 508 | struct acpi_pcct_hw_reduced *pcct_hrss; | ||
| 509 | |||
| 510 | pcct_hrss = (struct acpi_pcct_hw_reduced *) pcct_entry; | ||
| 518 | 511 | ||
| 519 | if (pcc_mbox_ctrl.txdone_irq) { | 512 | if (pcc_mbox_ctrl.txdone_irq) { |
| 520 | rc = pcc_parse_subspace_irq(i, pcct_ss); | 513 | rc = pcc_parse_subspace_irq(i, pcct_hrss); |
| 521 | if (rc < 0) | 514 | if (rc < 0) |
| 522 | goto err; | 515 | goto err; |
| 516 | } | ||
| 523 | } | 517 | } |
| 518 | pcct_ss = (struct acpi_pcct_subspace *) pcct_entry; | ||
| 524 | 519 | ||
| 525 | /* If doorbell is in system memory cache the virt address */ | 520 | /* If doorbell is in system memory cache the virt address */ |
| 526 | db_reg = &pcct_ss->doorbell_register; | 521 | db_reg = &pcct_ss->doorbell_register; |
| @@ -531,7 +526,7 @@ static int __init acpi_pcc_probe(void) | |||
| 531 | ((unsigned long) pcct_entry + pcct_entry->length); | 526 | ((unsigned long) pcct_entry + pcct_entry->length); |
| 532 | } | 527 | } |
| 533 | 528 | ||
| 534 | pcc_mbox_ctrl.num_chans = sum; | 529 | pcc_mbox_ctrl.num_chans = count; |
| 535 | 530 | ||
| 536 | pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans); | 531 | pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans); |
| 537 | 532 | ||
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c index 004cc3cc6123..7fa2631b422c 100644 --- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c | |||
| @@ -290,7 +290,7 @@ do { \ | |||
| 290 | if (kthread_should_stop() || \ | 290 | if (kthread_should_stop() || \ |
| 291 | test_bit(CACHE_SET_IO_DISABLE, &ca->set->flags)) { \ | 291 | test_bit(CACHE_SET_IO_DISABLE, &ca->set->flags)) { \ |
| 292 | set_current_state(TASK_RUNNING); \ | 292 | set_current_state(TASK_RUNNING); \ |
| 293 | return 0; \ | 293 | goto out; \ |
| 294 | } \ | 294 | } \ |
| 295 | \ | 295 | \ |
| 296 | schedule(); \ | 296 | schedule(); \ |
| @@ -378,6 +378,9 @@ retry_invalidate: | |||
| 378 | bch_prio_write(ca); | 378 | bch_prio_write(ca); |
| 379 | } | 379 | } |
| 380 | } | 380 | } |
| 381 | out: | ||
| 382 | wait_for_kthread_stop(); | ||
| 383 | return 0; | ||
| 381 | } | 384 | } |
| 382 | 385 | ||
| 383 | /* Allocation */ | 386 | /* Allocation */ |
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index d338b7086013..3a0cfb237af9 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h | |||
| @@ -392,6 +392,8 @@ struct cached_dev { | |||
| 392 | #define DEFAULT_CACHED_DEV_ERROR_LIMIT 64 | 392 | #define DEFAULT_CACHED_DEV_ERROR_LIMIT 64 |
| 393 | atomic_t io_errors; | 393 | atomic_t io_errors; |
| 394 | unsigned error_limit; | 394 | unsigned error_limit; |
| 395 | |||
| 396 | char backing_dev_name[BDEVNAME_SIZE]; | ||
| 395 | }; | 397 | }; |
| 396 | 398 | ||
| 397 | enum alloc_reserve { | 399 | enum alloc_reserve { |
| @@ -464,6 +466,8 @@ struct cache { | |||
| 464 | atomic_long_t meta_sectors_written; | 466 | atomic_long_t meta_sectors_written; |
| 465 | atomic_long_t btree_sectors_written; | 467 | atomic_long_t btree_sectors_written; |
| 466 | atomic_long_t sectors_written; | 468 | atomic_long_t sectors_written; |
| 469 | |||
| 470 | char cache_dev_name[BDEVNAME_SIZE]; | ||
| 467 | }; | 471 | }; |
| 468 | 472 | ||
| 469 | struct gc_stat { | 473 | struct gc_stat { |
diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c index 028f7b386e01..d030ce3025a6 100644 --- a/drivers/md/bcache/debug.c +++ b/drivers/md/bcache/debug.c | |||
| @@ -106,7 +106,6 @@ void bch_btree_verify(struct btree *b) | |||
| 106 | 106 | ||
| 107 | void bch_data_verify(struct cached_dev *dc, struct bio *bio) | 107 | void bch_data_verify(struct cached_dev *dc, struct bio *bio) |
| 108 | { | 108 | { |
| 109 | char name[BDEVNAME_SIZE]; | ||
| 110 | struct bio *check; | 109 | struct bio *check; |
| 111 | struct bio_vec bv, cbv; | 110 | struct bio_vec bv, cbv; |
| 112 | struct bvec_iter iter, citer = { 0 }; | 111 | struct bvec_iter iter, citer = { 0 }; |
| @@ -134,7 +133,7 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio) | |||
| 134 | bv.bv_len), | 133 | bv.bv_len), |
| 135 | dc->disk.c, | 134 | dc->disk.c, |
| 136 | "verify failed at dev %s sector %llu", | 135 | "verify failed at dev %s sector %llu", |
| 137 | bdevname(dc->bdev, name), | 136 | dc->backing_dev_name, |
| 138 | (uint64_t) bio->bi_iter.bi_sector); | 137 | (uint64_t) bio->bi_iter.bi_sector); |
| 139 | 138 | ||
| 140 | kunmap_atomic(p1); | 139 | kunmap_atomic(p1); |
| @@ -251,7 +250,9 @@ void bch_debug_exit(void) | |||
| 251 | 250 | ||
| 252 | int __init bch_debug_init(struct kobject *kobj) | 251 | int __init bch_debug_init(struct kobject *kobj) |
| 253 | { | 252 | { |
| 254 | bcache_debug = debugfs_create_dir("bcache", NULL); | 253 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) |
| 254 | return 0; | ||
| 255 | 255 | ||
| 256 | bcache_debug = debugfs_create_dir("bcache", NULL); | ||
| 256 | return IS_ERR_OR_NULL(bcache_debug); | 257 | return IS_ERR_OR_NULL(bcache_debug); |
| 257 | } | 258 | } |
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c index 7fac97ae036e..2ddf8515e6a5 100644 --- a/drivers/md/bcache/io.c +++ b/drivers/md/bcache/io.c | |||
| @@ -52,7 +52,6 @@ void bch_submit_bbio(struct bio *bio, struct cache_set *c, | |||
| 52 | /* IO errors */ | 52 | /* IO errors */ |
| 53 | void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio) | 53 | void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio) |
| 54 | { | 54 | { |
| 55 | char buf[BDEVNAME_SIZE]; | ||
| 56 | unsigned errors; | 55 | unsigned errors; |
| 57 | 56 | ||
| 58 | WARN_ONCE(!dc, "NULL pointer of struct cached_dev"); | 57 | WARN_ONCE(!dc, "NULL pointer of struct cached_dev"); |
| @@ -60,7 +59,7 @@ void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio) | |||
| 60 | errors = atomic_add_return(1, &dc->io_errors); | 59 | errors = atomic_add_return(1, &dc->io_errors); |
| 61 | if (errors < dc->error_limit) | 60 | if (errors < dc->error_limit) |
| 62 | pr_err("%s: IO error on backing device, unrecoverable", | 61 | pr_err("%s: IO error on backing device, unrecoverable", |
| 63 | bio_devname(bio, buf)); | 62 | dc->backing_dev_name); |
| 64 | else | 63 | else |
| 65 | bch_cached_dev_error(dc); | 64 | bch_cached_dev_error(dc); |
| 66 | } | 65 | } |
| @@ -105,19 +104,18 @@ void bch_count_io_errors(struct cache *ca, | |||
| 105 | } | 104 | } |
| 106 | 105 | ||
| 107 | if (error) { | 106 | if (error) { |
| 108 | char buf[BDEVNAME_SIZE]; | ||
| 109 | unsigned errors = atomic_add_return(1 << IO_ERROR_SHIFT, | 107 | unsigned errors = atomic_add_return(1 << IO_ERROR_SHIFT, |
| 110 | &ca->io_errors); | 108 | &ca->io_errors); |
| 111 | errors >>= IO_ERROR_SHIFT; | 109 | errors >>= IO_ERROR_SHIFT; |
| 112 | 110 | ||
| 113 | if (errors < ca->set->error_limit) | 111 | if (errors < ca->set->error_limit) |
| 114 | pr_err("%s: IO error on %s%s", | 112 | pr_err("%s: IO error on %s%s", |
| 115 | bdevname(ca->bdev, buf), m, | 113 | ca->cache_dev_name, m, |
| 116 | is_read ? ", recovering." : "."); | 114 | is_read ? ", recovering." : "."); |
| 117 | else | 115 | else |
| 118 | bch_cache_set_error(ca->set, | 116 | bch_cache_set_error(ca->set, |
| 119 | "%s: too many IO errors %s", | 117 | "%s: too many IO errors %s", |
| 120 | bdevname(ca->bdev, buf), m); | 118 | ca->cache_dev_name, m); |
| 121 | } | 119 | } |
| 122 | } | 120 | } |
| 123 | 121 | ||
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index a65e3365eeb9..8e3e8655ed63 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
| @@ -649,11 +649,8 @@ static void backing_request_endio(struct bio *bio) | |||
| 649 | */ | 649 | */ |
| 650 | if (unlikely(s->iop.writeback && | 650 | if (unlikely(s->iop.writeback && |
| 651 | bio->bi_opf & REQ_PREFLUSH)) { | 651 | bio->bi_opf & REQ_PREFLUSH)) { |
| 652 | char buf[BDEVNAME_SIZE]; | ||
| 653 | |||
| 654 | bio_devname(bio, buf); | ||
| 655 | pr_err("Can't flush %s: returned bi_status %i", | 652 | pr_err("Can't flush %s: returned bi_status %i", |
| 656 | buf, bio->bi_status); | 653 | dc->backing_dev_name, bio->bi_status); |
| 657 | } else { | 654 | } else { |
| 658 | /* set to orig_bio->bi_status in bio_complete() */ | 655 | /* set to orig_bio->bi_status in bio_complete() */ |
| 659 | s->iop.status = bio->bi_status; | 656 | s->iop.status = bio->bi_status; |
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index d90d9e59ca00..3dea06b41d43 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
| @@ -936,7 +936,6 @@ static void cancel_writeback_rate_update_dwork(struct cached_dev *dc) | |||
| 936 | static void cached_dev_detach_finish(struct work_struct *w) | 936 | static void cached_dev_detach_finish(struct work_struct *w) |
| 937 | { | 937 | { |
| 938 | struct cached_dev *dc = container_of(w, struct cached_dev, detach); | 938 | struct cached_dev *dc = container_of(w, struct cached_dev, detach); |
| 939 | char buf[BDEVNAME_SIZE]; | ||
| 940 | struct closure cl; | 939 | struct closure cl; |
| 941 | closure_init_stack(&cl); | 940 | closure_init_stack(&cl); |
| 942 | 941 | ||
| @@ -967,7 +966,7 @@ static void cached_dev_detach_finish(struct work_struct *w) | |||
| 967 | 966 | ||
| 968 | mutex_unlock(&bch_register_lock); | 967 | mutex_unlock(&bch_register_lock); |
| 969 | 968 | ||
| 970 | pr_info("Caching disabled for %s", bdevname(dc->bdev, buf)); | 969 | pr_info("Caching disabled for %s", dc->backing_dev_name); |
| 971 | 970 | ||
| 972 | /* Drop ref we took in cached_dev_detach() */ | 971 | /* Drop ref we took in cached_dev_detach() */ |
| 973 | closure_put(&dc->disk.cl); | 972 | closure_put(&dc->disk.cl); |
| @@ -999,29 +998,28 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, | |||
| 999 | { | 998 | { |
| 1000 | uint32_t rtime = cpu_to_le32(get_seconds()); | 999 | uint32_t rtime = cpu_to_le32(get_seconds()); |
| 1001 | struct uuid_entry *u; | 1000 | struct uuid_entry *u; |
| 1002 | char buf[BDEVNAME_SIZE]; | ||
| 1003 | struct cached_dev *exist_dc, *t; | 1001 | struct cached_dev *exist_dc, *t; |
| 1004 | 1002 | ||
| 1005 | bdevname(dc->bdev, buf); | ||
| 1006 | |||
| 1007 | if ((set_uuid && memcmp(set_uuid, c->sb.set_uuid, 16)) || | 1003 | if ((set_uuid && memcmp(set_uuid, c->sb.set_uuid, 16)) || |
| 1008 | (!set_uuid && memcmp(dc->sb.set_uuid, c->sb.set_uuid, 16))) | 1004 | (!set_uuid && memcmp(dc->sb.set_uuid, c->sb.set_uuid, 16))) |
| 1009 | return -ENOENT; | 1005 | return -ENOENT; |
| 1010 | 1006 | ||
| 1011 | if (dc->disk.c) { | 1007 | if (dc->disk.c) { |
| 1012 | pr_err("Can't attach %s: already attached", buf); | 1008 | pr_err("Can't attach %s: already attached", |
| 1009 | dc->backing_dev_name); | ||
| 1013 | return -EINVAL; | 1010 | return -EINVAL; |
| 1014 | } | 1011 | } |
| 1015 | 1012 | ||
| 1016 | if (test_bit(CACHE_SET_STOPPING, &c->flags)) { | 1013 | if (test_bit(CACHE_SET_STOPPING, &c->flags)) { |
| 1017 | pr_err("Can't attach %s: shutting down", buf); | 1014 | pr_err("Can't attach %s: shutting down", |
| 1015 | dc->backing_dev_name); | ||
| 1018 | return -EINVAL; | 1016 | return -EINVAL; |
| 1019 | } | 1017 | } |
| 1020 | 1018 | ||
| 1021 | if (dc->sb.block_size < c->sb.block_size) { | 1019 | if (dc->sb.block_size < c->sb.block_size) { |
| 1022 | /* Will die */ | 1020 | /* Will die */ |
| 1023 | pr_err("Couldn't attach %s: block size less than set's block size", | 1021 | pr_err("Couldn't attach %s: block size less than set's block size", |
| 1024 | buf); | 1022 | dc->backing_dev_name); |
| 1025 | return -EINVAL; | 1023 | return -EINVAL; |
| 1026 | } | 1024 | } |
| 1027 | 1025 | ||
| @@ -1029,7 +1027,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, | |||
| 1029 | list_for_each_entry_safe(exist_dc, t, &c->cached_devs, list) { | 1027 | list_for_each_entry_safe(exist_dc, t, &c->cached_devs, list) { |
| 1030 | if (!memcmp(dc->sb.uuid, exist_dc->sb.uuid, 16)) { | 1028 | if (!memcmp(dc->sb.uuid, exist_dc->sb.uuid, 16)) { |
| 1031 | pr_err("Tried to attach %s but duplicate UUID already attached", | 1029 | pr_err("Tried to attach %s but duplicate UUID already attached", |
| 1032 | buf); | 1030 | dc->backing_dev_name); |
| 1033 | 1031 | ||
| 1034 | return -EINVAL; | 1032 | return -EINVAL; |
| 1035 | } | 1033 | } |
| @@ -1047,13 +1045,15 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, | |||
| 1047 | 1045 | ||
| 1048 | if (!u) { | 1046 | if (!u) { |
| 1049 | if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) { | 1047 | if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) { |
| 1050 | pr_err("Couldn't find uuid for %s in set", buf); | 1048 | pr_err("Couldn't find uuid for %s in set", |
| 1049 | dc->backing_dev_name); | ||
| 1051 | return -ENOENT; | 1050 | return -ENOENT; |
| 1052 | } | 1051 | } |
| 1053 | 1052 | ||
| 1054 | u = uuid_find_empty(c); | 1053 | u = uuid_find_empty(c); |
| 1055 | if (!u) { | 1054 | if (!u) { |
| 1056 | pr_err("Not caching %s, no room for UUID", buf); | 1055 | pr_err("Not caching %s, no room for UUID", |
| 1056 | dc->backing_dev_name); | ||
| 1057 | return -EINVAL; | 1057 | return -EINVAL; |
| 1058 | } | 1058 | } |
| 1059 | } | 1059 | } |
| @@ -1112,7 +1112,8 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, | |||
| 1112 | up_write(&dc->writeback_lock); | 1112 | up_write(&dc->writeback_lock); |
| 1113 | 1113 | ||
| 1114 | pr_info("Caching %s as %s on set %pU", | 1114 | pr_info("Caching %s as %s on set %pU", |
| 1115 | bdevname(dc->bdev, buf), dc->disk.disk->disk_name, | 1115 | dc->backing_dev_name, |
| 1116 | dc->disk.disk->disk_name, | ||
| 1116 | dc->disk.c->sb.set_uuid); | 1117 | dc->disk.c->sb.set_uuid); |
| 1117 | return 0; | 1118 | return 0; |
| 1118 | } | 1119 | } |
| @@ -1225,10 +1226,10 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, | |||
| 1225 | struct block_device *bdev, | 1226 | struct block_device *bdev, |
| 1226 | struct cached_dev *dc) | 1227 | struct cached_dev *dc) |
| 1227 | { | 1228 | { |
| 1228 | char name[BDEVNAME_SIZE]; | ||
| 1229 | const char *err = "cannot allocate memory"; | 1229 | const char *err = "cannot allocate memory"; |
| 1230 | struct cache_set *c; | 1230 | struct cache_set *c; |
| 1231 | 1231 | ||
| 1232 | bdevname(bdev, dc->backing_dev_name); | ||
| 1232 | memcpy(&dc->sb, sb, sizeof(struct cache_sb)); | 1233 | memcpy(&dc->sb, sb, sizeof(struct cache_sb)); |
| 1233 | dc->bdev = bdev; | 1234 | dc->bdev = bdev; |
| 1234 | dc->bdev->bd_holder = dc; | 1235 | dc->bdev->bd_holder = dc; |
| @@ -1237,6 +1238,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, | |||
| 1237 | bio_first_bvec_all(&dc->sb_bio)->bv_page = sb_page; | 1238 | bio_first_bvec_all(&dc->sb_bio)->bv_page = sb_page; |
| 1238 | get_page(sb_page); | 1239 | get_page(sb_page); |
| 1239 | 1240 | ||
| 1241 | |||
| 1240 | if (cached_dev_init(dc, sb->block_size << 9)) | 1242 | if (cached_dev_init(dc, sb->block_size << 9)) |
| 1241 | goto err; | 1243 | goto err; |
| 1242 | 1244 | ||
| @@ -1247,7 +1249,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, | |||
| 1247 | if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj)) | 1249 | if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj)) |
| 1248 | goto err; | 1250 | goto err; |
| 1249 | 1251 | ||
| 1250 | pr_info("registered backing device %s", bdevname(bdev, name)); | 1252 | pr_info("registered backing device %s", dc->backing_dev_name); |
| 1251 | 1253 | ||
| 1252 | list_add(&dc->list, &uncached_devices); | 1254 | list_add(&dc->list, &uncached_devices); |
| 1253 | list_for_each_entry(c, &bch_cache_sets, list) | 1255 | list_for_each_entry(c, &bch_cache_sets, list) |
| @@ -1259,7 +1261,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, | |||
| 1259 | 1261 | ||
| 1260 | return; | 1262 | return; |
| 1261 | err: | 1263 | err: |
| 1262 | pr_notice("error %s: %s", bdevname(bdev, name), err); | 1264 | pr_notice("error %s: %s", dc->backing_dev_name, err); |
| 1263 | bcache_device_stop(&dc->disk); | 1265 | bcache_device_stop(&dc->disk); |
| 1264 | } | 1266 | } |
| 1265 | 1267 | ||
| @@ -1367,7 +1369,7 @@ int bch_flash_dev_create(struct cache_set *c, uint64_t size) | |||
| 1367 | 1369 | ||
| 1368 | bool bch_cached_dev_error(struct cached_dev *dc) | 1370 | bool bch_cached_dev_error(struct cached_dev *dc) |
| 1369 | { | 1371 | { |
| 1370 | char name[BDEVNAME_SIZE]; | 1372 | struct cache_set *c; |
| 1371 | 1373 | ||
| 1372 | if (!dc || test_bit(BCACHE_DEV_CLOSING, &dc->disk.flags)) | 1374 | if (!dc || test_bit(BCACHE_DEV_CLOSING, &dc->disk.flags)) |
| 1373 | return false; | 1375 | return false; |
| @@ -1377,7 +1379,22 @@ bool bch_cached_dev_error(struct cached_dev *dc) | |||
| 1377 | smp_mb(); | 1379 | smp_mb(); |
| 1378 | 1380 | ||
| 1379 | pr_err("stop %s: too many IO errors on backing device %s\n", | 1381 | pr_err("stop %s: too many IO errors on backing device %s\n", |
| 1380 | dc->disk.disk->disk_name, bdevname(dc->bdev, name)); | 1382 | dc->disk.disk->disk_name, dc->backing_dev_name); |
| 1383 | |||
| 1384 | /* | ||
| 1385 | * If the cached device is still attached to a cache set, | ||
| 1386 | * even dc->io_disable is true and no more I/O requests | ||
| 1387 | * accepted, cache device internal I/O (writeback scan or | ||
| 1388 | * garbage collection) may still prevent bcache device from | ||
| 1389 | * being stopped. So here CACHE_SET_IO_DISABLE should be | ||
| 1390 | * set to c->flags too, to make the internal I/O to cache | ||
| 1391 | * device rejected and stopped immediately. | ||
| 1392 | * If c is NULL, that means the bcache device is not attached | ||
| 1393 | * to any cache set, then no CACHE_SET_IO_DISABLE bit to set. | ||
| 1394 | */ | ||
| 1395 | c = dc->disk.c; | ||
| 1396 | if (c && test_and_set_bit(CACHE_SET_IO_DISABLE, &c->flags)) | ||
| 1397 | pr_info("CACHE_SET_IO_DISABLE already set"); | ||
| 1381 | 1398 | ||
| 1382 | bcache_device_stop(&dc->disk); | 1399 | bcache_device_stop(&dc->disk); |
| 1383 | return true; | 1400 | return true; |
| @@ -1395,7 +1412,7 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...) | |||
| 1395 | return false; | 1412 | return false; |
| 1396 | 1413 | ||
| 1397 | if (test_and_set_bit(CACHE_SET_IO_DISABLE, &c->flags)) | 1414 | if (test_and_set_bit(CACHE_SET_IO_DISABLE, &c->flags)) |
| 1398 | pr_warn("CACHE_SET_IO_DISABLE already set"); | 1415 | pr_info("CACHE_SET_IO_DISABLE already set"); |
| 1399 | 1416 | ||
| 1400 | /* XXX: we can be called from atomic context | 1417 | /* XXX: we can be called from atomic context |
| 1401 | acquire_console_sem(); | 1418 | acquire_console_sem(); |
| @@ -1539,6 +1556,20 @@ static void conditional_stop_bcache_device(struct cache_set *c, | |||
| 1539 | */ | 1556 | */ |
| 1540 | pr_warn("stop_when_cache_set_failed of %s is \"auto\" and cache is dirty, stop it to avoid potential data corruption.", | 1557 | pr_warn("stop_when_cache_set_failed of %s is \"auto\" and cache is dirty, stop it to avoid potential data corruption.", |
| 1541 | d->disk->disk_name); | 1558 | d->disk->disk_name); |
| 1559 | /* | ||
| 1560 | * There might be a small time gap that cache set is | ||
| 1561 | * released but bcache device is not. Inside this time | ||
| 1562 | * gap, regular I/O requests will directly go into | ||
| 1563 | * backing device as no cache set attached to. This | ||
| 1564 | * behavior may also introduce potential inconsistence | ||
| 1565 | * data in writeback mode while cache is dirty. | ||
| 1566 | * Therefore before calling bcache_device_stop() due | ||
| 1567 | * to a broken cache device, dc->io_disable should be | ||
| 1568 | * explicitly set to true. | ||
| 1569 | */ | ||
| 1570 | dc->io_disable = true; | ||
| 1571 | /* make others know io_disable is true earlier */ | ||
| 1572 | smp_mb(); | ||
| 1542 | bcache_device_stop(d); | 1573 | bcache_device_stop(d); |
| 1543 | } else { | 1574 | } else { |
| 1544 | /* | 1575 | /* |
| @@ -2003,12 +2034,10 @@ static int cache_alloc(struct cache *ca) | |||
| 2003 | static int register_cache(struct cache_sb *sb, struct page *sb_page, | 2034 | static int register_cache(struct cache_sb *sb, struct page *sb_page, |
| 2004 | struct block_device *bdev, struct cache *ca) | 2035 | struct block_device *bdev, struct cache *ca) |
| 2005 | { | 2036 | { |
| 2006 | char name[BDEVNAME_SIZE]; | ||
| 2007 | const char *err = NULL; /* must be set for any error case */ | 2037 | const char *err = NULL; /* must be set for any error case */ |
| 2008 | int ret = 0; | 2038 | int ret = 0; |
| 2009 | 2039 | ||
| 2010 | bdevname(bdev, name); | 2040 | bdevname(bdev, ca->cache_dev_name); |
| 2011 | |||
| 2012 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); | 2041 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); |
| 2013 | ca->bdev = bdev; | 2042 | ca->bdev = bdev; |
| 2014 | ca->bdev->bd_holder = ca; | 2043 | ca->bdev->bd_holder = ca; |
| @@ -2045,14 +2074,14 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | |||
| 2045 | goto out; | 2074 | goto out; |
| 2046 | } | 2075 | } |
| 2047 | 2076 | ||
| 2048 | pr_info("registered cache device %s", name); | 2077 | pr_info("registered cache device %s", ca->cache_dev_name); |
| 2049 | 2078 | ||
| 2050 | out: | 2079 | out: |
| 2051 | kobject_put(&ca->kobj); | 2080 | kobject_put(&ca->kobj); |
| 2052 | 2081 | ||
| 2053 | err: | 2082 | err: |
| 2054 | if (err) | 2083 | if (err) |
| 2055 | pr_notice("error %s: %s", name, err); | 2084 | pr_notice("error %s: %s", ca->cache_dev_name, err); |
| 2056 | 2085 | ||
| 2057 | return ret; | 2086 | return ret; |
| 2058 | } | 2087 | } |
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 4a9547cdcdc5..ad45ebe1a74b 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c | |||
| @@ -244,8 +244,10 @@ static void dirty_endio(struct bio *bio) | |||
| 244 | struct keybuf_key *w = bio->bi_private; | 244 | struct keybuf_key *w = bio->bi_private; |
| 245 | struct dirty_io *io = w->private; | 245 | struct dirty_io *io = w->private; |
| 246 | 246 | ||
| 247 | if (bio->bi_status) | 247 | if (bio->bi_status) { |
| 248 | SET_KEY_DIRTY(&w->key, false); | 248 | SET_KEY_DIRTY(&w->key, false); |
| 249 | bch_count_backing_io_errors(io->dc, bio); | ||
| 250 | } | ||
| 249 | 251 | ||
| 250 | closure_put(&io->cl); | 252 | closure_put(&io->cl); |
| 251 | } | 253 | } |
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 12aa9ca21d8c..dc385b70e4c3 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c | |||
| @@ -1681,8 +1681,9 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign | |||
| 1681 | 1681 | ||
| 1682 | if (block_size <= KMALLOC_MAX_SIZE && | 1682 | if (block_size <= KMALLOC_MAX_SIZE && |
| 1683 | (block_size < PAGE_SIZE || !is_power_of_2(block_size))) { | 1683 | (block_size < PAGE_SIZE || !is_power_of_2(block_size))) { |
| 1684 | snprintf(slab_name, sizeof slab_name, "dm_bufio_cache-%u", c->block_size); | 1684 | unsigned align = min(1U << __ffs(block_size), (unsigned)PAGE_SIZE); |
| 1685 | c->slab_cache = kmem_cache_create(slab_name, c->block_size, ARCH_KMALLOC_MINALIGN, | 1685 | snprintf(slab_name, sizeof slab_name, "dm_bufio_cache-%u", block_size); |
| 1686 | c->slab_cache = kmem_cache_create(slab_name, block_size, align, | ||
| 1686 | SLAB_RECLAIM_ACCOUNT, NULL); | 1687 | SLAB_RECLAIM_ACCOUNT, NULL); |
| 1687 | if (!c->slab_cache) { | 1688 | if (!c->slab_cache) { |
| 1688 | r = -ENOMEM; | 1689 | r = -ENOMEM; |
diff --git a/drivers/md/dm-cache-background-tracker.c b/drivers/md/dm-cache-background-tracker.c index 1d0af0a21fc7..84814e819e4c 100644 --- a/drivers/md/dm-cache-background-tracker.c +++ b/drivers/md/dm-cache-background-tracker.c | |||
| @@ -166,7 +166,7 @@ static bool max_work_reached(struct background_tracker *b) | |||
| 166 | atomic_read(&b->pending_demotes) >= b->max_work; | 166 | atomic_read(&b->pending_demotes) >= b->max_work; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | struct bt_work *alloc_work(struct background_tracker *b) | 169 | static struct bt_work *alloc_work(struct background_tracker *b) |
| 170 | { | 170 | { |
| 171 | if (max_work_reached(b)) | 171 | if (max_work_reached(b)) |
| 172 | return NULL; | 172 | return NULL; |
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 77d9fe58dae2..514fb4aec5d1 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c | |||
| @@ -2440,7 +2440,7 @@ static void dm_integrity_free_journal_scatterlist(struct dm_integrity_c *ic, str | |||
| 2440 | unsigned i; | 2440 | unsigned i; |
| 2441 | for (i = 0; i < ic->journal_sections; i++) | 2441 | for (i = 0; i < ic->journal_sections; i++) |
| 2442 | kvfree(sl[i]); | 2442 | kvfree(sl[i]); |
| 2443 | kfree(sl); | 2443 | kvfree(sl); |
| 2444 | } | 2444 | } |
| 2445 | 2445 | ||
| 2446 | static struct scatterlist **dm_integrity_alloc_journal_scatterlist(struct dm_integrity_c *ic, struct page_list *pl) | 2446 | static struct scatterlist **dm_integrity_alloc_journal_scatterlist(struct dm_integrity_c *ic, struct page_list *pl) |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 580c49cc8079..5903e492bb34 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | 23 | ||
| 24 | #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ | 24 | #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ |
| 25 | 25 | ||
| 26 | #define MAX_NR_MIRRORS (DM_KCOPYD_MAX_REGIONS + 1) | ||
| 27 | |||
| 26 | #define DM_RAID1_HANDLE_ERRORS 0x01 | 28 | #define DM_RAID1_HANDLE_ERRORS 0x01 |
| 27 | #define DM_RAID1_KEEP_LOG 0x02 | 29 | #define DM_RAID1_KEEP_LOG 0x02 |
| 28 | #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) | 30 | #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) |
| @@ -255,7 +257,7 @@ static int mirror_flush(struct dm_target *ti) | |||
| 255 | unsigned long error_bits; | 257 | unsigned long error_bits; |
| 256 | 258 | ||
| 257 | unsigned int i; | 259 | unsigned int i; |
| 258 | struct dm_io_region io[ms->nr_mirrors]; | 260 | struct dm_io_region io[MAX_NR_MIRRORS]; |
| 259 | struct mirror *m; | 261 | struct mirror *m; |
| 260 | struct dm_io_request io_req = { | 262 | struct dm_io_request io_req = { |
| 261 | .bi_op = REQ_OP_WRITE, | 263 | .bi_op = REQ_OP_WRITE, |
| @@ -651,7 +653,7 @@ static void write_callback(unsigned long error, void *context) | |||
| 651 | static void do_write(struct mirror_set *ms, struct bio *bio) | 653 | static void do_write(struct mirror_set *ms, struct bio *bio) |
| 652 | { | 654 | { |
| 653 | unsigned int i; | 655 | unsigned int i; |
| 654 | struct dm_io_region io[ms->nr_mirrors], *dest = io; | 656 | struct dm_io_region io[MAX_NR_MIRRORS], *dest = io; |
| 655 | struct mirror *m; | 657 | struct mirror *m; |
| 656 | struct dm_io_request io_req = { | 658 | struct dm_io_request io_req = { |
| 657 | .bi_op = REQ_OP_WRITE, | 659 | .bi_op = REQ_OP_WRITE, |
| @@ -1083,7 +1085,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 1083 | argc -= args_used; | 1085 | argc -= args_used; |
| 1084 | 1086 | ||
| 1085 | if (!argc || sscanf(argv[0], "%u%c", &nr_mirrors, &dummy) != 1 || | 1087 | if (!argc || sscanf(argv[0], "%u%c", &nr_mirrors, &dummy) != 1 || |
| 1086 | nr_mirrors < 2 || nr_mirrors > DM_KCOPYD_MAX_REGIONS + 1) { | 1088 | nr_mirrors < 2 || nr_mirrors > MAX_NR_MIRRORS) { |
| 1087 | ti->error = "Invalid number of mirrors"; | 1089 | ti->error = "Invalid number of mirrors"; |
| 1088 | dm_dirty_log_destroy(dl); | 1090 | dm_dirty_log_destroy(dl); |
| 1089 | return -EINVAL; | 1091 | return -EINVAL; |
| @@ -1404,7 +1406,7 @@ static void mirror_status(struct dm_target *ti, status_type_t type, | |||
| 1404 | int num_feature_args = 0; | 1406 | int num_feature_args = 0; |
| 1405 | struct mirror_set *ms = (struct mirror_set *) ti->private; | 1407 | struct mirror_set *ms = (struct mirror_set *) ti->private; |
| 1406 | struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); | 1408 | struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); |
| 1407 | char buffer[ms->nr_mirrors + 1]; | 1409 | char buffer[MAX_NR_MIRRORS + 1]; |
| 1408 | 1410 | ||
| 1409 | switch (type) { | 1411 | switch (type) { |
| 1410 | case STATUSTYPE_INFO: | 1412 | case STATUSTYPE_INFO: |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 4ea404dbcf0b..0a7b0107ca78 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -1020,7 +1020,8 @@ int dm_set_target_max_io_len(struct dm_target *ti, sector_t len) | |||
| 1020 | EXPORT_SYMBOL_GPL(dm_set_target_max_io_len); | 1020 | EXPORT_SYMBOL_GPL(dm_set_target_max_io_len); |
| 1021 | 1021 | ||
| 1022 | static struct dm_target *dm_dax_get_live_target(struct mapped_device *md, | 1022 | static struct dm_target *dm_dax_get_live_target(struct mapped_device *md, |
| 1023 | sector_t sector, int *srcu_idx) | 1023 | sector_t sector, int *srcu_idx) |
| 1024 | __acquires(md->io_barrier) | ||
| 1024 | { | 1025 | { |
| 1025 | struct dm_table *map; | 1026 | struct dm_table *map; |
| 1026 | struct dm_target *ti; | 1027 | struct dm_target *ti; |
| @@ -1037,7 +1038,7 @@ static struct dm_target *dm_dax_get_live_target(struct mapped_device *md, | |||
| 1037 | } | 1038 | } |
| 1038 | 1039 | ||
| 1039 | static long dm_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, | 1040 | static long dm_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, |
| 1040 | long nr_pages, void **kaddr, pfn_t *pfn) | 1041 | long nr_pages, void **kaddr, pfn_t *pfn) |
| 1041 | { | 1042 | { |
| 1042 | struct mapped_device *md = dax_get_private(dax_dev); | 1043 | struct mapped_device *md = dax_get_private(dax_dev); |
| 1043 | sector_t sector = pgoff * PAGE_SECTORS; | 1044 | sector_t sector = pgoff * PAGE_SECTORS; |
| @@ -1065,7 +1066,7 @@ static long dm_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, | |||
| 1065 | } | 1066 | } |
| 1066 | 1067 | ||
| 1067 | static size_t dm_dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, | 1068 | static size_t dm_dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, |
| 1068 | void *addr, size_t bytes, struct iov_iter *i) | 1069 | void *addr, size_t bytes, struct iov_iter *i) |
| 1069 | { | 1070 | { |
| 1070 | struct mapped_device *md = dax_get_private(dax_dev); | 1071 | struct mapped_device *md = dax_get_private(dax_dev); |
| 1071 | sector_t sector = pgoff * PAGE_SECTORS; | 1072 | sector_t sector = pgoff * PAGE_SECTORS; |
diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index e216cd768409..b07114b5efb2 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | // | 20 | // |
| 21 | // VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> | 21 | // VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> |
| 22 | // | 22 | // |
| 23 | // Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 23 | // Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 24 | // SAA7111, SAA7113 and SAA7118 support | 24 | // SAA7111, SAA7113 and SAA7118 support |
| 25 | 25 | ||
| 26 | #include "saa711x_regs.h" | 26 | #include "saa711x_regs.h" |
diff --git a/drivers/media/i2c/saa711x_regs.h b/drivers/media/i2c/saa711x_regs.h index a50d480e101a..44fabe08234d 100644 --- a/drivers/media/i2c/saa711x_regs.h +++ b/drivers/media/i2c/saa711x_regs.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * SPDX-License-Identifier: GPL-2.0+ | 2 | * SPDX-License-Identifier: GPL-2.0+ |
| 3 | * saa711x - Philips SAA711x video decoder register specifications | 3 | * saa711x - Philips SAA711x video decoder register specifications |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 5 | * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #define R_00_CHIP_VERSION 0x00 | 8 | #define R_00_CHIP_VERSION 0x00 |
diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c index 1c5c61d829d6..9b4f21237810 100644 --- a/drivers/media/i2c/tda7432.c +++ b/drivers/media/i2c/tda7432.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | * Muting and tone control by Jonathan Isom <jisom@ematic.com> | 8 | * Muting and tone control by Jonathan Isom <jisom@ematic.com> |
| 9 | * | 9 | * |
| 10 | * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com> | 10 | * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com> |
| 11 | * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 11 | * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 12 | * This code is placed under the terms of the GNU General Public License | 12 | * This code is placed under the terms of the GNU General Public License |
| 13 | * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) | 13 | * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) |
| 14 | * Which was based on tda8425.c by Greg Alexander (c) 1998 | 14 | * Which was based on tda8425.c by Greg Alexander (c) 1998 |
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 2476d812f669..1734ed4ede33 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | // | 2 | // |
| 3 | // tvp5150 - Texas Instruments TVP5150A/AM1 and TVP5151 video decoder driver | 3 | // tvp5150 - Texas Instruments TVP5150A/AM1 and TVP5151 video decoder driver |
| 4 | // | 4 | // |
| 5 | // Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 5 | // Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | 6 | ||
| 7 | #include <dt-bindings/media/tvp5150.h> | 7 | #include <dt-bindings/media/tvp5150.h> |
| 8 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |
diff --git a/drivers/media/i2c/tvp5150_reg.h b/drivers/media/i2c/tvp5150_reg.h index c43b7b844021..d3a764cae1a0 100644 --- a/drivers/media/i2c/tvp5150_reg.h +++ b/drivers/media/i2c/tvp5150_reg.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers | 4 | * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 6 | * Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */ | 9 | #define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */ |
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index a26c1a3f7183..4599b7e28a8d 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com> | 5 | * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com> |
| 6 | * | 6 | * |
| 7 | * This code is partially based upon the TVP5150 driver | 7 | * This code is partially based upon the TVP5150 driver |
| 8 | * written by Mauro Carvalho Chehab (mchehab@infradead.org), | 8 | * written by Mauro Carvalho Chehab <mchehab@kernel.org>, |
| 9 | * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com> | 9 | * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com> |
| 10 | * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by | 10 | * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by |
| 11 | * Muralidharan Karicheri and Snehaprabha Narnakaje (TI). | 11 | * Muralidharan Karicheri and Snehaprabha Narnakaje (TI). |
diff --git a/drivers/media/i2c/tvp7002_reg.h b/drivers/media/i2c/tvp7002_reg.h index 3c8c8b0a6a4c..7f56ba689dfe 100644 --- a/drivers/media/i2c/tvp7002_reg.h +++ b/drivers/media/i2c/tvp7002_reg.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com> | 5 | * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com> |
| 6 | * | 6 | * |
| 7 | * This code is partially based upon the TVP5150 driver | 7 | * This code is partially based upon the TVP5150 driver |
| 8 | * written by Mauro Carvalho Chehab (mchehab@infradead.org), | 8 | * written by Mauro Carvalho Chehab <mchehab@kernel.org>, |
| 9 | * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com> | 9 | * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com> |
| 10 | * and the TVP7002 driver in the TI LSP 2.10.00.14 | 10 | * and the TVP7002 driver in the TI LSP 2.10.00.14 |
| 11 | * | 11 | * |
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c index 67ac51eff15c..6b87a721dc49 100644 --- a/drivers/media/media-devnode.c +++ b/drivers/media/media-devnode.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Copyright (C) 2010 Nokia Corporation | 4 | * Copyright (C) 2010 Nokia Corporation |
| 5 | * | 5 | * |
| 6 | * Based on drivers/media/video/v4l2_dev.c code authored by | 6 | * Based on drivers/media/video/v4l2_dev.c code authored by |
| 7 | * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) | 7 | * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) |
| 8 | * Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) | 8 | * Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) |
| 9 | * | 9 | * |
| 10 | * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 10 | * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
diff --git a/drivers/media/pci/bt8xx/bttv-audio-hook.c b/drivers/media/pci/bt8xx/bttv-audio-hook.c index 9f1f9169fb5b..346fc7f58839 100644 --- a/drivers/media/pci/bt8xx/bttv-audio-hook.c +++ b/drivers/media/pci/bt8xx/bttv-audio-hook.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Handlers for board audio hooks, splitted from bttv-cards | 2 | * Handlers for board audio hooks, splitted from bttv-cards |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org) | 4 | * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5 | * This code is placed under the terms of the GNU General Public License | 5 | * This code is placed under the terms of the GNU General Public License |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
diff --git a/drivers/media/pci/bt8xx/bttv-audio-hook.h b/drivers/media/pci/bt8xx/bttv-audio-hook.h index 159d07adeff8..be16a537a03a 100644 --- a/drivers/media/pci/bt8xx/bttv-audio-hook.h +++ b/drivers/media/pci/bt8xx/bttv-audio-hook.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Handlers for board audio hooks, splitted from bttv-cards | 2 | * Handlers for board audio hooks, splitted from bttv-cards |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org) | 4 | * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5 | * This code is placed under the terms of the GNU General Public License | 5 | * This code is placed under the terms of the GNU General Public License |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index 1902732f90e1..2616243b2c49 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c | |||
| @@ -2447,7 +2447,7 @@ struct tvcard bttv_tvcards[] = { | |||
| 2447 | }, | 2447 | }, |
| 2448 | /* ---- card 0x88---------------------------------- */ | 2448 | /* ---- card 0x88---------------------------------- */ |
| 2449 | [BTTV_BOARD_ACORP_Y878F] = { | 2449 | [BTTV_BOARD_ACORP_Y878F] = { |
| 2450 | /* Mauro Carvalho Chehab <mchehab@infradead.org> */ | 2450 | /* Mauro Carvalho Chehab <mchehab@kernel.org> */ |
| 2451 | .name = "Acorp Y878F", | 2451 | .name = "Acorp Y878F", |
| 2452 | .video_inputs = 3, | 2452 | .video_inputs = 3, |
| 2453 | /* .audio_inputs= 1, */ | 2453 | /* .audio_inputs= 1, */ |
| @@ -2688,7 +2688,7 @@ struct tvcard bttv_tvcards[] = { | |||
| 2688 | }, | 2688 | }, |
| 2689 | [BTTV_BOARD_ENLTV_FM_2] = { | 2689 | [BTTV_BOARD_ENLTV_FM_2] = { |
| 2690 | /* Encore TV Tuner Pro ENL TV-FM-2 | 2690 | /* Encore TV Tuner Pro ENL TV-FM-2 |
| 2691 | Mauro Carvalho Chehab <mchehab@infradead.org */ | 2691 | Mauro Carvalho Chehab <mchehab@kernel.org> */ |
| 2692 | .name = "Encore ENL TV-FM-2", | 2692 | .name = "Encore ENL TV-FM-2", |
| 2693 | .video_inputs = 3, | 2693 | .video_inputs = 3, |
| 2694 | /* .audio_inputs= 1, */ | 2694 | /* .audio_inputs= 1, */ |
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 707f57a9f940..de3f44b8dec6 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | (c) 2005-2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru> | 13 | (c) 2005-2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru> |
| 14 | 14 | ||
| 15 | Fixes to be fully V4L2 compliant by | 15 | Fixes to be fully V4L2 compliant by |
| 16 | (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 16 | (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 17 | 17 | ||
| 18 | Cropping and overscan support | 18 | Cropping and overscan support |
| 19 | Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> | 19 | Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> |
diff --git a/drivers/media/pci/bt8xx/bttv-i2c.c b/drivers/media/pci/bt8xx/bttv-i2c.c index eccd1e3d717a..c76823eb399d 100644 --- a/drivers/media/pci/bt8xx/bttv-i2c.c +++ b/drivers/media/pci/bt8xx/bttv-i2c.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | & Marcus Metzler (mocm@thp.uni-koeln.de) | 8 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
| 9 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> | 9 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
| 10 | 10 | ||
| 11 | (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org> | 11 | (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 12 | - Multituner support and i2c address binding | 12 | - Multituner support and i2c address binding |
| 13 | 13 | ||
| 14 | This program is free software; you can redistribute it and/or modify | 14 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index be49589a61d2..395ff9bba759 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | * Copyright (C) 2008 <srinivasa.deevi at conexant dot com> | 13 | * Copyright (C) 2008 <srinivasa.deevi at conexant dot com> |
| 14 | * Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 14 | * Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 15 | * Markus Rechberger <mrechberger@gmail.com> | 15 | * Markus Rechberger <mrechberger@gmail.com> |
| 16 | * Mauro Carvalho Chehab <mchehab@infradead.org> | 16 | * Mauro Carvalho Chehab <mchehab@kernel.org> |
| 17 | * Sascha Sommer <saschasommer@freenet.de> | 17 | * Sascha Sommer <saschasommer@freenet.de> |
| 18 | * Copyright (C) 2004, 2005 Chris Pascoe | 18 | * Copyright (C) 2004, 2005 Chris Pascoe |
| 19 | * Copyright (C) 2003, 2004 Gerd Knorr | 19 | * Copyright (C) 2003, 2004 Gerd Knorr |
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index ab09bb55cf45..8a28fda703a2 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * (c) 2007 Trent Piepho <xyzzy@speakeasy.org> | 5 | * (c) 2007 Trent Piepho <xyzzy@speakeasy.org> |
| 6 | * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org> | 6 | * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org> |
| 7 | * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | * (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8 | * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org> | 8 | * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org> |
| 9 | * Based on dummy.c by Jaroslav Kysela <perex@perex.cz> | 9 | * Based on dummy.c by Jaroslav Kysela <perex@perex.cz> |
| 10 | * | 10 | * |
| @@ -103,7 +103,7 @@ MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); | |||
| 103 | 103 | ||
| 104 | MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); | 104 | MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); |
| 105 | MODULE_AUTHOR("Ricardo Cerqueira"); | 105 | MODULE_AUTHOR("Ricardo Cerqueira"); |
| 106 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 106 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 107 | MODULE_LICENSE("GPL"); | 107 | MODULE_LICENSE("GPL"); |
| 108 | MODULE_VERSION(CX88_VERSION); | 108 | MODULE_VERSION(CX88_VERSION); |
| 109 | 109 | ||
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 0e0952e60795..7a4876cf9f08 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * (c) 2004 Jelle Foks <jelle@foks.us> | 5 | * (c) 2004 Jelle Foks <jelle@foks.us> |
| 6 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> | 6 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> |
| 7 | * | 7 | * |
| 8 | * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 8 | * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 9 | * - video_ioctl2 conversion | 9 | * - video_ioctl2 conversion |
| 10 | * | 10 | * |
| 11 | * Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/> | 11 | * Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/> |
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 8bfa5b7ed91b..60988e95b637 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | 5 | * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] |
| 6 | * | 6 | * |
| 7 | * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8 | * - Multituner support | 8 | * - Multituner support |
| 9 | * - video_ioctl2 conversion | 9 | * - video_ioctl2 conversion |
| 10 | * - PAL/M fixes | 10 | * - PAL/M fixes |
diff --git a/drivers/media/pci/cx88/cx88-i2c.c b/drivers/media/pci/cx88/cx88-i2c.c index f7692775fb5a..99f88a05a7c9 100644 --- a/drivers/media/pci/cx88/cx88-i2c.c +++ b/drivers/media/pci/cx88/cx88-i2c.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | * (c) 2002 Yurij Sysoev <yurij@naturesoft.net> | 8 | * (c) 2002 Yurij Sysoev <yurij@naturesoft.net> |
| 9 | * (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> | 9 | * (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
| 10 | * | 10 | * |
| 11 | * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org> | 11 | * (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 12 | * - Multituner support and i2c address binding | 12 | * - Multituner support and i2c address binding |
| 13 | * | 13 | * |
| 14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 9be682cdb644..7b113bad70d2 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * (c) 2003-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | 6 | * (c) 2003-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] |
| 7 | * | 7 | * |
| 8 | * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> | 8 | * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 9 | * - Multituner support | 9 | * - Multituner support |
| 10 | * - video_ioctl2 conversion | 10 | * - video_ioctl2 conversion |
| 11 | * - PAL/M fixes | 11 | * - PAL/M fixes |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 5ef635e72e10..4c52ac6d8bc5 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Copyright 1997 M. Kirkwood | 4 | * Copyright 1997 M. Kirkwood |
| 5 | * | 5 | * |
| 6 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> | 6 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 7 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8 | * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> | 8 | * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> |
| 9 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> | 9 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
| 10 | * | 10 | * |
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 9e12c6027359..840b7d60462b 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * radio-aztech.c - Aztech radio card driver | 2 | * radio-aztech.c - Aztech radio card driver |
| 3 | * | 3 | * |
| 4 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@xs4all.nl> | 4 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@xs4all.nl> |
| 5 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 5 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | * Adapted to support the Video for Linux API by | 6 | * Adapted to support the Video for Linux API by |
| 7 | * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: | 7 | * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: |
| 8 | * | 8 | * |
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 3ff4c4e1435f..f051f8694ab9 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> | 15 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
| 16 | * | 16 | * |
| 17 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> | 17 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 18 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 18 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 19 | * | 19 | * |
| 20 | * Note: this card seems to swap the left and right audio channels! | 20 | * Note: this card seems to swap the left and right audio channels! |
| 21 | * | 21 | * |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 95f06f3b35dc..e4e758739246 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | * BUGS: | 27 | * BUGS: |
| 28 | * - card unmutes if you change frequency | 28 | * - card unmutes if you change frequency |
| 29 | * | 29 | * |
| 30 | * (c) 2006, 2007 by Mauro Carvalho Chehab <mchehab@infradead.org>: | 30 | * (c) 2006, 2007 by Mauro Carvalho Chehab <mchehab@kernel.org>: |
| 31 | * - Conversion to V4L2 API | 31 | * - Conversion to V4L2 API |
| 32 | * - Uses video_ioctl2 for parsing and to add debug support | 32 | * - Uses video_ioctl2 for parsing and to add debug support |
| 33 | */ | 33 | */ |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index abeaedd8d437..5a1470eb753e 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> | 7 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
| 8 | * | 8 | * |
| 9 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> | 9 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 10 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 10 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 11 | * | 11 | * |
| 12 | * Fully tested with actual hardware and the v4l2-compliance tool. | 12 | * Fully tested with actual hardware and the v4l2-compliance tool. |
| 13 | */ | 13 | */ |
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index fc4e63d36e4c..4f9b97edd9eb 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | * No volume control - only mute/unmute - you have to use line volume | 13 | * No volume control - only mute/unmute - you have to use line volume |
| 14 | * control on SB-part of SF16-FMI/SF16-FMP/SF16-FMD | 14 | * control on SB-part of SF16-FMI/SF16-FMP/SF16-FMD |
| 15 | * | 15 | * |
| 16 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 16 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/kernel.h> /* __setup */ | 19 | #include <linux/kernel.h> /* __setup */ |
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 4f116ea294fb..1af8f29cc7d1 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | * Volume Control is done digitally | 17 | * Volume Control is done digitally |
| 18 | * | 18 | * |
| 19 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> | 19 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 20 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 20 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <linux/module.h> /* Modules */ | 23 | #include <linux/module.h> /* Modules */ |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 26a8c6002121..a4bad322ffff 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) | 12 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) |
| 13 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) | 13 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) |
| 14 | * | 14 | * |
| 15 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 15 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <stdarg.h> | 18 | #include <stdarg.h> |
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index eb72a4d13758..d0d67ad85b8f 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | * The frequency change is necessary since the card never seems to be | 25 | * The frequency change is necessary since the card never seems to be |
| 26 | * completely silent. | 26 | * completely silent. |
| 27 | * | 27 | * |
| 28 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 28 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | #include <linux/module.h> /* Modules */ | 31 | #include <linux/module.h> /* Modules */ |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 026e88eef29c..6007cd09b328 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | * 2002-07-15 - Fix Stereo typo | 27 | * 2002-07-15 - Fix Stereo typo |
| 28 | * | 28 | * |
| 29 | * 2006-07-24 - Converted to V4L2 API | 29 | * 2006-07-24 - Converted to V4L2 API |
| 30 | * by Mauro Carvalho Chehab <mchehab@infradead.org> | 30 | * by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 31 | * | 31 | * |
| 32 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> | 32 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 33 | * | 33 | * |
diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c index f6977df1a75b..d275d98d066a 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | * | 12 | * |
| 13 | * On Avermedia M135A with IR model RM-JX, the same codes exist on both | 13 | * On Avermedia M135A with IR model RM-JX, the same codes exist on both |
| 14 | * Positivo (BR) and original IR, initial version and remote control codes | 14 | * Positivo (BR) and original IR, initial version and remote control codes |
| 15 | * added by Mauro Carvalho Chehab <mchehab@infradead.org> | 15 | * added by Mauro Carvalho Chehab <mchehab@kernel.org> |
| 16 | * | 16 | * |
| 17 | * Positivo also ships Avermedia M135A with model RM-K6, extra control | 17 | * Positivo also ships Avermedia M135A with model RM-K6, extra control |
| 18 | * codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br> | 18 | * codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br> |
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c index e4e78c1f4123..057c13b765ef 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | 10 | ||
| 11 | /* Encore ENLTV-FM v5.3 | 11 | /* Encore ENLTV-FM v5.3 |
| 12 | Mauro Carvalho Chehab <mchehab@infradead.org> | 12 | Mauro Carvalho Chehab <mchehab@kernel.org> |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | static struct rc_map_table encore_enltv_fm53[] = { | 15 | static struct rc_map_table encore_enltv_fm53[] = { |
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c index c3d4437a6fda..cd0555924456 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv2.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | 10 | ||
| 11 | /* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton | 11 | /* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton |
| 12 | Mauro Carvalho Chehab <mchehab@infradead.org> */ | 12 | Mauro Carvalho Chehab <mchehab@kernel.org> */ |
| 13 | 13 | ||
| 14 | static struct rc_map_table encore_enltv2[] = { | 14 | static struct rc_map_table encore_enltv2[] = { |
| 15 | { 0x4c, KEY_POWER2 }, | 15 | { 0x4c, KEY_POWER2 }, |
diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c index f0f88df18606..a00051339842 100644 --- a/drivers/media/rc/keymaps/rc-kaiomy.c +++ b/drivers/media/rc/keymaps/rc-kaiomy.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | 10 | ||
| 11 | /* Kaiomy TVnPC U2 | 11 | /* Kaiomy TVnPC U2 |
| 12 | Mauro Carvalho Chehab <mchehab@infradead.org> | 12 | Mauro Carvalho Chehab <mchehab@kernel.org> |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | static struct rc_map_table kaiomy[] = { | 15 | static struct rc_map_table kaiomy[] = { |
diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c index 453e04377de7..db5edde3eeb1 100644 --- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c +++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | 10 | ||
| 11 | /* Kworld Plus TV Analog Lite PCI IR | 11 | /* Kworld Plus TV Analog Lite PCI IR |
| 12 | Mauro Carvalho Chehab <mchehab@infradead.org> | 12 | Mauro Carvalho Chehab <mchehab@kernel.org> |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | static struct rc_map_table kworld_plus_tv_analog[] = { | 15 | static struct rc_map_table kworld_plus_tv_analog[] = { |
diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c index 791130f108ff..e4e34f2ccf74 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-new.c +++ b/drivers/media/rc/keymaps/rc-pixelview-new.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | 10 | ||
| 11 | /* | 11 | /* |
| 12 | Mauro Carvalho Chehab <mchehab@infradead.org> | 12 | Mauro Carvalho Chehab <mchehab@kernel.org> |
| 13 | present on PV MPEG 8000GT | 13 | present on PV MPEG 8000GT |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c index 88b3e80c38ad..d78a2bdb3e36 100644 --- a/drivers/media/tuners/tea5761.c +++ b/drivers/media/tuners/tea5761.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | // For Philips TEA5761 FM Chip | 2 | // For Philips TEA5761 FM Chip |
| 3 | // I2C address is always 0x20 (0x10 at 7-bit mode). | 3 | // I2C address is always 0x20 (0x10 at 7-bit mode). |
| 4 | // | 4 | // |
| 5 | // Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org) | 5 | // Copyright (c) 2005-2007 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | 6 | ||
| 7 | #include <linux/i2c.h> | 7 | #include <linux/i2c.h> |
| 8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
| @@ -337,5 +337,5 @@ EXPORT_SYMBOL_GPL(tea5761_attach); | |||
| 337 | EXPORT_SYMBOL_GPL(tea5761_autodetection); | 337 | EXPORT_SYMBOL_GPL(tea5761_autodetection); |
| 338 | 338 | ||
| 339 | MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver"); | 339 | MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver"); |
| 340 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 340 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 341 | MODULE_LICENSE("GPL v2"); | 341 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c index 2b2c064d7dc3..016d0d5ec50b 100644 --- a/drivers/media/tuners/tea5767.c +++ b/drivers/media/tuners/tea5767.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | // For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview | 2 | // For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview |
| 3 | // I2C address is always 0xC0. | 3 | // I2C address is always 0xC0. |
| 4 | // | 4 | // |
| 5 | // Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) | 5 | // Copyright (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | // | 6 | // |
| 7 | // tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa | 7 | // tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa |
| 8 | // from their contributions on DScaler. | 8 | // from their contributions on DScaler. |
| @@ -469,5 +469,5 @@ EXPORT_SYMBOL_GPL(tea5767_attach); | |||
| 469 | EXPORT_SYMBOL_GPL(tea5767_autodetection); | 469 | EXPORT_SYMBOL_GPL(tea5767_autodetection); |
| 470 | 470 | ||
| 471 | MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver"); | 471 | MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver"); |
| 472 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 472 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 473 | MODULE_LICENSE("GPL v2"); | 473 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/media/tuners/tuner-xc2028-types.h b/drivers/media/tuners/tuner-xc2028-types.h index bb0437c36c03..50d017a4822a 100644 --- a/drivers/media/tuners/tuner-xc2028-types.h +++ b/drivers/media/tuners/tuner-xc2028-types.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * This file includes internal tipes to be used inside tuner-xc2028. | 5 | * This file includes internal tipes to be used inside tuner-xc2028. |
| 6 | * Shouldn't be included outside tuner-xc2028 | 6 | * Shouldn't be included outside tuner-xc2028 |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | 8 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | /* xc3028 firmware types */ | 11 | /* xc3028 firmware types */ |
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index fca85e08ebd7..84744e138982 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // tuner-xc2028 | 2 | // tuner-xc2028 |
| 3 | // | 3 | // |
| 4 | // Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | 4 | // Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5 | // | 5 | // |
| 6 | // Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com) | 6 | // Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com) |
| 7 | // - frontend interface | 7 | // - frontend interface |
| @@ -1518,7 +1518,7 @@ EXPORT_SYMBOL(xc2028_attach); | |||
| 1518 | 1518 | ||
| 1519 | MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver"); | 1519 | MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver"); |
| 1520 | MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>"); | 1520 | MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>"); |
| 1521 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 1521 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 1522 | MODULE_LICENSE("GPL v2"); | 1522 | MODULE_LICENSE("GPL v2"); |
| 1523 | MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE); | 1523 | MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE); |
| 1524 | MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE); | 1524 | MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE); |
diff --git a/drivers/media/tuners/tuner-xc2028.h b/drivers/media/tuners/tuner-xc2028.h index 03fd6d4233a4..7b58bc06e35c 100644 --- a/drivers/media/tuners/tuner-xc2028.h +++ b/drivers/media/tuners/tuner-xc2028.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * SPDX-License-Identifier: GPL-2.0 | 2 | * SPDX-License-Identifier: GPL-2.0 |
| 3 | * tuner-xc2028 | 3 | * tuner-xc2028 |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | 5 | * Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #ifndef __TUNER_XC2028_H__ | 8 | #ifndef __TUNER_XC2028_H__ |
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 3c2694a16ed1..d1e66b503f4d 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | // | 2 | // |
| 3 | // em28xx-camera.c - driver for Empia EM25xx/27xx/28xx USB video capture devices | 3 | // em28xx-camera.c - driver for Empia EM25xx/27xx/28xx USB video capture devices |
| 4 | // | 4 | // |
| 5 | // Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> | 5 | // Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | // Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> | 6 | // Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 7 | // | 7 | // |
| 8 | // This program is free software; you can redistribute it and/or modify | 8 | // This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 6e0e67d23876..7c3203d7044b 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | // | 5 | // |
| 6 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 6 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 7 | // Markus Rechberger <mrechberger@gmail.com> | 7 | // Markus Rechberger <mrechberger@gmail.com> |
| 8 | // Mauro Carvalho Chehab <mchehab@infradead.org> | 8 | // Mauro Carvalho Chehab <mchehab@kernel.org> |
| 9 | // Sascha Sommer <saschasommer@freenet.de> | 9 | // Sascha Sommer <saschasommer@freenet.de> |
| 10 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 10 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 11 | // | 11 | // |
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 36d341fb65dd..f28995383090 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | // | 4 | // |
| 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 6 | // Markus Rechberger <mrechberger@gmail.com> | 6 | // Markus Rechberger <mrechberger@gmail.com> |
| 7 | // Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | // Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8 | // Sascha Sommer <saschasommer@freenet.de> | 8 | // Sascha Sommer <saschasommer@freenet.de> |
| 9 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 9 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 10 | // | 10 | // |
| @@ -32,7 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | 33 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
| 34 | "Markus Rechberger <mrechberger@gmail.com>, " \ | 34 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
| 35 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ | 35 | "Mauro Carvalho Chehab <mchehab@kernel.org>, " \ |
| 36 | "Sascha Sommer <saschasommer@freenet.de>" | 36 | "Sascha Sommer <saschasommer@freenet.de>" |
| 37 | 37 | ||
| 38 | MODULE_AUTHOR(DRIVER_AUTHOR); | 38 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index a54cb8dc52c9..3f493e0b0716 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | // | 2 | // |
| 3 | // DVB device driver for em28xx | 3 | // DVB device driver for em28xx |
| 4 | // | 4 | // |
| 5 | // (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> | 5 | // (c) 2008-2011 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | // | 6 | // |
| 7 | // (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> | 7 | // (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> |
| 8 | // - Fixes for the driver to properly work with HVR-950 | 8 | // - Fixes for the driver to properly work with HVR-950 |
| @@ -63,7 +63,7 @@ | |||
| 63 | #include "tc90522.h" | 63 | #include "tc90522.h" |
| 64 | #include "qm1d1c0042.h" | 64 | #include "qm1d1c0042.h" |
| 65 | 65 | ||
| 66 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 66 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 67 | MODULE_LICENSE("GPL v2"); | 67 | MODULE_LICENSE("GPL v2"); |
| 68 | MODULE_DESCRIPTION(DRIVER_DESC " - digital TV interface"); | 68 | MODULE_DESCRIPTION(DRIVER_DESC " - digital TV interface"); |
| 69 | MODULE_VERSION(EM28XX_VERSION); | 69 | MODULE_VERSION(EM28XX_VERSION); |
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 9151bccd859a..6458682bc6e2 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | // | 4 | // |
| 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 6 | // Markus Rechberger <mrechberger@gmail.com> | 6 | // Markus Rechberger <mrechberger@gmail.com> |
| 7 | // Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | // Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8 | // Sascha Sommer <saschasommer@freenet.de> | 8 | // Sascha Sommer <saschasommer@freenet.de> |
| 9 | // Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> | 9 | // Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 10 | // | 10 | // |
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 2dc1be00b8b8..f84a1208d5d3 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | // | 4 | // |
| 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 6 | // Markus Rechberger <mrechberger@gmail.com> | 6 | // Markus Rechberger <mrechberger@gmail.com> |
| 7 | // Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | // Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8 | // Sascha Sommer <saschasommer@freenet.de> | 8 | // Sascha Sommer <saschasommer@freenet.de> |
| 9 | // | 9 | // |
| 10 | // This program is free software; you can redistribute it and/or modify | 10 | // This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index d70ee13cc52e..68571bf36d28 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | // | 5 | // |
| 6 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 6 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 7 | // Markus Rechberger <mrechberger@gmail.com> | 7 | // Markus Rechberger <mrechberger@gmail.com> |
| 8 | // Mauro Carvalho Chehab <mchehab@infradead.org> | 8 | // Mauro Carvalho Chehab <mchehab@kernel.org> |
| 9 | // Sascha Sommer <saschasommer@freenet.de> | 9 | // Sascha Sommer <saschasommer@freenet.de> |
| 10 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 10 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 11 | // | 11 | // |
| @@ -44,7 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | 45 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
| 46 | "Markus Rechberger <mrechberger@gmail.com>, " \ | 46 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
| 47 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ | 47 | "Mauro Carvalho Chehab <mchehab@kernel.org>, " \ |
| 48 | "Sascha Sommer <saschasommer@freenet.de>" | 48 | "Sascha Sommer <saschasommer@freenet.de>" |
| 49 | 49 | ||
| 50 | static unsigned int isoc_debug; | 50 | static unsigned int isoc_debug; |
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 63c7c6124707..b0378e77ddff 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> | 5 | * Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> |
| 6 | * Ludovico Cavedon <cavedon@sssup.it> | 6 | * Ludovico Cavedon <cavedon@sssup.it> |
| 7 | * Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | * Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8 | * Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 8 | * Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 9 | * | 9 | * |
| 10 | * Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> | 10 | * Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> |
diff --git a/drivers/media/usb/gspca/zc3xx-reg.h b/drivers/media/usb/gspca/zc3xx-reg.h index a1bd94e8ce52..71fda38e85e0 100644 --- a/drivers/media/usb/gspca/zc3xx-reg.h +++ b/drivers/media/usb/gspca/zc3xx-reg.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * zc030x registers | 2 | * zc030x registers |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5 | * | 5 | * |
| 6 | * The register aliases used here came from this driver: | 6 | * The register aliases used here came from this driver: |
| 7 | * http://zc0302.sourceforge.net/zc0302.php | 7 | * http://zc0302.sourceforge.net/zc0302.php |
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c index 70939e96b856..23df50aa0a4a 100644 --- a/drivers/media/usb/tm6000/tm6000-cards.c +++ b/drivers/media/usb/tm6000/tm6000-cards.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | // tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 3 | // | 3 | // |
| 4 | // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5 | 5 | ||
| 6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
diff --git a/drivers/media/usb/tm6000/tm6000-core.c b/drivers/media/usb/tm6000/tm6000-core.c index 23a1332d98e6..d3229aa45fcb 100644 --- a/drivers/media/usb/tm6000/tm6000-core.c +++ b/drivers/media/usb/tm6000/tm6000-core.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | // tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 3 | // | 3 | // |
| 4 | // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5 | // | 5 | // |
| 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
| 7 | // - DVB-T support | 7 | // - DVB-T support |
diff --git a/drivers/media/usb/tm6000/tm6000-i2c.c b/drivers/media/usb/tm6000/tm6000-i2c.c index c9a62bbff27a..659b63febf85 100644 --- a/drivers/media/usb/tm6000/tm6000-i2c.c +++ b/drivers/media/usb/tm6000/tm6000-i2c.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | // tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 3 | // | 3 | // |
| 4 | // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5 | // | 5 | // |
| 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
| 7 | // - Fix SMBus Read Byte command | 7 | // - Fix SMBus Read Byte command |
diff --git a/drivers/media/usb/tm6000/tm6000-regs.h b/drivers/media/usb/tm6000/tm6000-regs.h index 21587fcf11e3..d10424673db9 100644 --- a/drivers/media/usb/tm6000/tm6000-regs.h +++ b/drivers/media/usb/tm6000/tm6000-regs.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * SPDX-License-Identifier: GPL-2.0 | 2 | * SPDX-License-Identifier: GPL-2.0 |
| 3 | * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices | 3 | * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 5 | * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | /* | 8 | /* |
diff --git a/drivers/media/usb/tm6000/tm6000-usb-isoc.h b/drivers/media/usb/tm6000/tm6000-usb-isoc.h index 5c615b0a7a46..b275dbce3a1b 100644 --- a/drivers/media/usb/tm6000/tm6000-usb-isoc.h +++ b/drivers/media/usb/tm6000/tm6000-usb-isoc.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * SPDX-License-Identifier: GPL-2.0 | 2 | * SPDX-License-Identifier: GPL-2.0 |
| 3 | * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 3 | * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 5 | * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <linux/videodev2.h> | 8 | #include <linux/videodev2.h> |
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index b2399d4266da..aa85fe31c835 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices | 2 | // tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 3 | // | 3 | // |
| 4 | // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | // Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5 | // | 5 | // |
| 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
| 7 | // - Fixed module load/unload | 7 | // - Fixed module load/unload |
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h index e1e45770e28d..0864ed7314eb 100644 --- a/drivers/media/usb/tm6000/tm6000.h +++ b/drivers/media/usb/tm6000/tm6000.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * SPDX-License-Identifier: GPL-2.0 | 2 | * SPDX-License-Identifier: GPL-2.0 |
| 3 | * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices | 3 | * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 5 | * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> |
| 6 | * | 6 | * |
| 7 | * Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> | 7 | * Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
| 8 | * - DVB-T support | 8 | * - DVB-T support |
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 1d0b2208e8fb..c080dcc75393 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | * | 11 | * |
| 12 | * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) | 12 | * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) |
| 13 | * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) | 13 | * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) |
| 14 | * | 14 | * |
| 15 | * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com> | 15 | * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com> |
| 16 | * - Added procfs support | 16 | * - Added procfs support |
| @@ -1072,7 +1072,7 @@ static void __exit videodev_exit(void) | |||
| 1072 | subsys_initcall(videodev_init); | 1072 | subsys_initcall(videodev_init); |
| 1073 | module_exit(videodev_exit) | 1073 | module_exit(videodev_exit) |
| 1074 | 1074 | ||
| 1075 | MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>"); | 1075 | MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 1076 | MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); | 1076 | MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); |
| 1077 | MODULE_LICENSE("GPL"); | 1077 | MODULE_LICENSE("GPL"); |
| 1078 | MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR); | 1078 | MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR); |
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index f48c505550e0..de5d96dbe69e 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
| 10 | * | 10 | * |
| 11 | * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) | 11 | * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) |
| 12 | * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) | 12 | * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c index 2b3981842b4b..7491b337002c 100644 --- a/drivers/media/v4l2-core/videobuf-core.c +++ b/drivers/media/v4l2-core/videobuf-core.c | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * generic helper functions for handling video4linux capture buffers | 2 | * generic helper functions for handling video4linux capture buffers |
| 3 | * | 3 | * |
| 4 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | 4 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 5 | * | 5 | * |
| 6 | * Highly based on video-buf written originally by: | 6 | * Highly based on video-buf written originally by: |
| 7 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> | 7 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> |
| 8 | * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org> | 8 | * (c) 2006 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 9 | * (c) 2006 Ted Walther and John Sokol | 9 | * (c) 2006 Ted Walther and John Sokol |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| @@ -38,7 +38,7 @@ static int debug; | |||
| 38 | module_param(debug, int, 0644); | 38 | module_param(debug, int, 0644); |
| 39 | 39 | ||
| 40 | MODULE_DESCRIPTION("helper module to manage video4linux buffers"); | 40 | MODULE_DESCRIPTION("helper module to manage video4linux buffers"); |
| 41 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 41 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 42 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
| 43 | 43 | ||
| 44 | #define dprintk(level, fmt, arg...) \ | 44 | #define dprintk(level, fmt, arg...) \ |
diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c index e02353e340dd..f46132504d88 100644 --- a/drivers/media/v4l2-core/videobuf-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Copyright (c) 2008 Magnus Damm | 7 | * Copyright (c) 2008 Magnus Damm |
| 8 | * | 8 | * |
| 9 | * Based on videobuf-vmalloc.c, | 9 | * Based on videobuf-vmalloc.c, |
| 10 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | 10 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 11 | * | 11 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c index add2edb23eac..7770034aae28 100644 --- a/drivers/media/v4l2-core/videobuf-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c | |||
| @@ -6,11 +6,11 @@ | |||
| 6 | * into PAGE_SIZE chunks). They also assume the driver does not need | 6 | * into PAGE_SIZE chunks). They also assume the driver does not need |
| 7 | * to touch the video data. | 7 | * to touch the video data. |
| 8 | * | 8 | * |
| 9 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | 9 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 10 | * | 10 | * |
| 11 | * Highly based on video-buf written originally by: | 11 | * Highly based on video-buf written originally by: |
| 12 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> | 12 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> |
| 13 | * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org> | 13 | * (c) 2006 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 14 | * (c) 2006 Ted Walther and John Sokol | 14 | * (c) 2006 Ted Walther and John Sokol |
| 15 | * | 15 | * |
| 16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
| @@ -48,7 +48,7 @@ static int debug; | |||
| 48 | module_param(debug, int, 0644); | 48 | module_param(debug, int, 0644); |
| 49 | 49 | ||
| 50 | MODULE_DESCRIPTION("helper module to manage video4linux dma sg buffers"); | 50 | MODULE_DESCRIPTION("helper module to manage video4linux dma sg buffers"); |
| 51 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 51 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 52 | MODULE_LICENSE("GPL"); | 52 | MODULE_LICENSE("GPL"); |
| 53 | 53 | ||
| 54 | #define dprintk(level, fmt, arg...) \ | 54 | #define dprintk(level, fmt, arg...) \ |
diff --git a/drivers/media/v4l2-core/videobuf-vmalloc.c b/drivers/media/v4l2-core/videobuf-vmalloc.c index 2ff7fcc77b11..45fe781aeeec 100644 --- a/drivers/media/v4l2-core/videobuf-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf-vmalloc.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * into PAGE_SIZE chunks). They also assume the driver does not need | 6 | * into PAGE_SIZE chunks). They also assume the driver does not need |
| 7 | * to touch the video data. | 7 | * to touch the video data. |
| 8 | * | 8 | * |
| 9 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | 9 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
| @@ -41,7 +41,7 @@ static int debug; | |||
| 41 | module_param(debug, int, 0644); | 41 | module_param(debug, int, 0644); |
| 42 | 42 | ||
| 43 | MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers"); | 43 | MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers"); |
| 44 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 44 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); |
| 45 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
| 46 | 46 | ||
| 47 | #define dprintk(level, fmt, arg...) \ | 47 | #define dprintk(level, fmt, arg...) \ |
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index a4c9c8297a6d..918d4fb742d1 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h | |||
| @@ -717,6 +717,7 @@ struct cxl { | |||
| 717 | bool perst_select_user; | 717 | bool perst_select_user; |
| 718 | bool perst_same_image; | 718 | bool perst_same_image; |
| 719 | bool psl_timebase_synced; | 719 | bool psl_timebase_synced; |
| 720 | bool tunneled_ops_supported; | ||
| 720 | 721 | ||
| 721 | /* | 722 | /* |
| 722 | * number of contexts mapped on to this card. Possible values are: | 723 | * number of contexts mapped on to this card. Possible values are: |
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 83f1d08058fc..4d6736f9d463 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c | |||
| @@ -1742,6 +1742,15 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev) | |||
| 1742 | /* Required for devices using CAPP DMA mode, harmless for others */ | 1742 | /* Required for devices using CAPP DMA mode, harmless for others */ |
| 1743 | pci_set_master(dev); | 1743 | pci_set_master(dev); |
| 1744 | 1744 | ||
| 1745 | adapter->tunneled_ops_supported = false; | ||
| 1746 | |||
| 1747 | if (cxl_is_power9()) { | ||
| 1748 | if (pnv_pci_set_tunnel_bar(dev, 0x00020000E0000000ull, 1)) | ||
| 1749 | dev_info(&dev->dev, "Tunneled operations unsupported\n"); | ||
| 1750 | else | ||
| 1751 | adapter->tunneled_ops_supported = true; | ||
| 1752 | } | ||
| 1753 | |||
| 1745 | if ((rc = pnv_phb_to_cxl_mode(dev, adapter->native->sl_ops->capi_mode))) | 1754 | if ((rc = pnv_phb_to_cxl_mode(dev, adapter->native->sl_ops->capi_mode))) |
| 1746 | goto err; | 1755 | goto err; |
| 1747 | 1756 | ||
| @@ -1768,6 +1777,9 @@ static void cxl_deconfigure_adapter(struct cxl *adapter) | |||
| 1768 | { | 1777 | { |
| 1769 | struct pci_dev *pdev = to_pci_dev(adapter->dev.parent); | 1778 | struct pci_dev *pdev = to_pci_dev(adapter->dev.parent); |
| 1770 | 1779 | ||
| 1780 | if (cxl_is_power9()) | ||
| 1781 | pnv_pci_set_tunnel_bar(pdev, 0x00020000E0000000ull, 0); | ||
| 1782 | |||
| 1771 | cxl_native_release_psl_err_irq(adapter); | 1783 | cxl_native_release_psl_err_irq(adapter); |
| 1772 | cxl_unmap_adapter_regs(adapter); | 1784 | cxl_unmap_adapter_regs(adapter); |
| 1773 | 1785 | ||
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index 95285b7f636f..4b5a4c5d3c01 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c | |||
| @@ -78,6 +78,15 @@ static ssize_t psl_timebase_synced_show(struct device *device, | |||
| 78 | return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced); | 78 | return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | static ssize_t tunneled_ops_supported_show(struct device *device, | ||
| 82 | struct device_attribute *attr, | ||
| 83 | char *buf) | ||
| 84 | { | ||
| 85 | struct cxl *adapter = to_cxl_adapter(device); | ||
| 86 | |||
| 87 | return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->tunneled_ops_supported); | ||
| 88 | } | ||
| 89 | |||
| 81 | static ssize_t reset_adapter_store(struct device *device, | 90 | static ssize_t reset_adapter_store(struct device *device, |
| 82 | struct device_attribute *attr, | 91 | struct device_attribute *attr, |
| 83 | const char *buf, size_t count) | 92 | const char *buf, size_t count) |
| @@ -183,6 +192,7 @@ static struct device_attribute adapter_attrs[] = { | |||
| 183 | __ATTR_RO(base_image), | 192 | __ATTR_RO(base_image), |
| 184 | __ATTR_RO(image_loaded), | 193 | __ATTR_RO(image_loaded), |
| 185 | __ATTR_RO(psl_timebase_synced), | 194 | __ATTR_RO(psl_timebase_synced), |
| 195 | __ATTR_RO(tunneled_ops_supported), | ||
| 186 | __ATTR_RW(load_image_on_perst), | 196 | __ATTR_RW(load_image_on_perst), |
| 187 | __ATTR_RW(perst_reloads_same_image), | 197 | __ATTR_RW(perst_reloads_same_image), |
| 188 | __ATTR(reset, S_IWUSR, NULL, reset_adapter_store), | 198 | __ATTR(reset, S_IWUSR, NULL, reset_adapter_store), |
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 0c125f207aea..33053b0d1fdf 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
| @@ -518,7 +518,7 @@ static int at24_get_pdata(struct device *dev, struct at24_platform_data *pdata) | |||
| 518 | if (of_node && of_match_device(at24_of_match, dev)) | 518 | if (of_node && of_match_device(at24_of_match, dev)) |
| 519 | cdata = of_device_get_match_data(dev); | 519 | cdata = of_device_get_match_data(dev); |
| 520 | else if (id) | 520 | else if (id) |
| 521 | cdata = (void *)&id->driver_data; | 521 | cdata = (void *)id->driver_data; |
| 522 | else | 522 | else |
| 523 | cdata = acpi_device_get_match_data(dev); | 523 | cdata = acpi_device_get_match_data(dev); |
| 524 | 524 | ||
diff --git a/drivers/mtd/nand/onenand/omap2.c b/drivers/mtd/nand/onenand/omap2.c index 9c159f0dd9a6..321137158ff3 100644 --- a/drivers/mtd/nand/onenand/omap2.c +++ b/drivers/mtd/nand/onenand/omap2.c | |||
| @@ -375,56 +375,42 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area, | |||
| 375 | { | 375 | { |
| 376 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); | 376 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); |
| 377 | struct onenand_chip *this = mtd->priv; | 377 | struct onenand_chip *this = mtd->priv; |
| 378 | dma_addr_t dma_src, dma_dst; | 378 | struct device *dev = &c->pdev->dev; |
| 379 | int bram_offset; | ||
| 380 | void *buf = (void *)buffer; | 379 | void *buf = (void *)buffer; |
| 380 | dma_addr_t dma_src, dma_dst; | ||
| 381 | int bram_offset, err; | ||
| 381 | size_t xtra; | 382 | size_t xtra; |
| 382 | int ret; | ||
| 383 | 383 | ||
| 384 | bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset; | 384 | bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset; |
| 385 | if (bram_offset & 3 || (size_t)buf & 3 || count < 384) | 385 | /* |
| 386 | goto out_copy; | 386 | * If the buffer address is not DMA-able, len is not long enough to make |
| 387 | 387 | * DMA transfers profitable or panic_write() may be in an interrupt | |
| 388 | /* panic_write() may be in an interrupt context */ | 388 | * context fallback to PIO mode. |
| 389 | if (in_interrupt() || oops_in_progress) | 389 | */ |
| 390 | if (!virt_addr_valid(buf) || bram_offset & 3 || (size_t)buf & 3 || | ||
| 391 | count < 384 || in_interrupt() || oops_in_progress ) | ||
| 390 | goto out_copy; | 392 | goto out_copy; |
| 391 | 393 | ||
| 392 | if (buf >= high_memory) { | ||
| 393 | struct page *p1; | ||
| 394 | |||
| 395 | if (((size_t)buf & PAGE_MASK) != | ||
| 396 | ((size_t)(buf + count - 1) & PAGE_MASK)) | ||
| 397 | goto out_copy; | ||
| 398 | p1 = vmalloc_to_page(buf); | ||
| 399 | if (!p1) | ||
| 400 | goto out_copy; | ||
| 401 | buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK); | ||
| 402 | } | ||
| 403 | |||
| 404 | xtra = count & 3; | 394 | xtra = count & 3; |
| 405 | if (xtra) { | 395 | if (xtra) { |
| 406 | count -= xtra; | 396 | count -= xtra; |
| 407 | memcpy(buf + count, this->base + bram_offset + count, xtra); | 397 | memcpy(buf + count, this->base + bram_offset + count, xtra); |
| 408 | } | 398 | } |
| 409 | 399 | ||
| 400 | dma_dst = dma_map_single(dev, buf, count, DMA_FROM_DEVICE); | ||
| 410 | dma_src = c->phys_base + bram_offset; | 401 | dma_src = c->phys_base + bram_offset; |
| 411 | dma_dst = dma_map_single(&c->pdev->dev, buf, count, DMA_FROM_DEVICE); | ||
| 412 | if (dma_mapping_error(&c->pdev->dev, dma_dst)) { | ||
| 413 | dev_err(&c->pdev->dev, | ||
| 414 | "Couldn't DMA map a %d byte buffer\n", | ||
| 415 | count); | ||
| 416 | goto out_copy; | ||
| 417 | } | ||
| 418 | 402 | ||
| 419 | ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count); | 403 | if (dma_mapping_error(dev, dma_dst)) { |
| 420 | dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE); | 404 | dev_err(dev, "Couldn't DMA map a %d byte buffer\n", count); |
| 421 | |||
| 422 | if (ret) { | ||
| 423 | dev_err(&c->pdev->dev, "timeout waiting for DMA\n"); | ||
| 424 | goto out_copy; | 405 | goto out_copy; |
| 425 | } | 406 | } |
| 426 | 407 | ||
| 427 | return 0; | 408 | err = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count); |
| 409 | dma_unmap_single(dev, dma_dst, count, DMA_FROM_DEVICE); | ||
| 410 | if (!err) | ||
| 411 | return 0; | ||
| 412 | |||
| 413 | dev_err(dev, "timeout waiting for DMA\n"); | ||
| 428 | 414 | ||
| 429 | out_copy: | 415 | out_copy: |
| 430 | memcpy(buf, this->base + bram_offset, count); | 416 | memcpy(buf, this->base + bram_offset, count); |
| @@ -437,49 +423,34 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area, | |||
| 437 | { | 423 | { |
| 438 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); | 424 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); |
| 439 | struct onenand_chip *this = mtd->priv; | 425 | struct onenand_chip *this = mtd->priv; |
| 440 | dma_addr_t dma_src, dma_dst; | 426 | struct device *dev = &c->pdev->dev; |
| 441 | int bram_offset; | ||
| 442 | void *buf = (void *)buffer; | 427 | void *buf = (void *)buffer; |
| 443 | int ret; | 428 | dma_addr_t dma_src, dma_dst; |
| 429 | int bram_offset, err; | ||
| 444 | 430 | ||
| 445 | bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset; | 431 | bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset; |
| 446 | if (bram_offset & 3 || (size_t)buf & 3 || count < 384) | 432 | /* |
| 447 | goto out_copy; | 433 | * If the buffer address is not DMA-able, len is not long enough to make |
| 448 | 434 | * DMA transfers profitable or panic_write() may be in an interrupt | |
| 449 | /* panic_write() may be in an interrupt context */ | 435 | * context fallback to PIO mode. |
| 450 | if (in_interrupt() || oops_in_progress) | 436 | */ |
| 437 | if (!virt_addr_valid(buf) || bram_offset & 3 || (size_t)buf & 3 || | ||
| 438 | count < 384 || in_interrupt() || oops_in_progress ) | ||
| 451 | goto out_copy; | 439 | goto out_copy; |
| 452 | 440 | ||
| 453 | if (buf >= high_memory) { | 441 | dma_src = dma_map_single(dev, buf, count, DMA_TO_DEVICE); |
| 454 | struct page *p1; | ||
| 455 | |||
| 456 | if (((size_t)buf & PAGE_MASK) != | ||
| 457 | ((size_t)(buf + count - 1) & PAGE_MASK)) | ||
| 458 | goto out_copy; | ||
| 459 | p1 = vmalloc_to_page(buf); | ||
| 460 | if (!p1) | ||
| 461 | goto out_copy; | ||
| 462 | buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK); | ||
| 463 | } | ||
| 464 | |||
| 465 | dma_src = dma_map_single(&c->pdev->dev, buf, count, DMA_TO_DEVICE); | ||
| 466 | dma_dst = c->phys_base + bram_offset; | 442 | dma_dst = c->phys_base + bram_offset; |
| 467 | if (dma_mapping_error(&c->pdev->dev, dma_src)) { | 443 | if (dma_mapping_error(dev, dma_src)) { |
| 468 | dev_err(&c->pdev->dev, | 444 | dev_err(dev, "Couldn't DMA map a %d byte buffer\n", count); |
| 469 | "Couldn't DMA map a %d byte buffer\n", | ||
| 470 | count); | ||
| 471 | return -1; | ||
| 472 | } | ||
| 473 | |||
| 474 | ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count); | ||
| 475 | dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE); | ||
| 476 | |||
| 477 | if (ret) { | ||
| 478 | dev_err(&c->pdev->dev, "timeout waiting for DMA\n"); | ||
| 479 | goto out_copy; | 445 | goto out_copy; |
| 480 | } | 446 | } |
| 481 | 447 | ||
| 482 | return 0; | 448 | err = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count); |
| 449 | dma_unmap_page(dev, dma_src, count, DMA_TO_DEVICE); | ||
| 450 | if (!err) | ||
| 451 | return 0; | ||
| 452 | |||
| 453 | dev_err(dev, "timeout waiting for DMA\n"); | ||
| 483 | 454 | ||
| 484 | out_copy: | 455 | out_copy: |
| 485 | memcpy(this->base + bram_offset, buf, count); | 456 | memcpy(this->base + bram_offset, buf, count); |
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 1d779a35ac8e..ebb1d141b900 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c | |||
| @@ -1074,7 +1074,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, | |||
| 1074 | return ret; | 1074 | return ret; |
| 1075 | 1075 | ||
| 1076 | ret = marvell_nfc_wait_op(chip, | 1076 | ret = marvell_nfc_wait_op(chip, |
| 1077 | chip->data_interface.timings.sdr.tPROG_max); | 1077 | PSEC_TO_MSEC(chip->data_interface.timings.sdr.tPROG_max)); |
| 1078 | return ret; | 1078 | return ret; |
| 1079 | } | 1079 | } |
| 1080 | 1080 | ||
| @@ -1194,11 +1194,13 @@ static void marvell_nfc_hw_ecc_bch_read_chunk(struct nand_chip *chip, int chunk, | |||
| 1194 | NDCB0_CMD2(NAND_CMD_READSTART); | 1194 | NDCB0_CMD2(NAND_CMD_READSTART); |
| 1195 | 1195 | ||
| 1196 | /* | 1196 | /* |
| 1197 | * Trigger the naked read operation only on the last chunk. | 1197 | * Trigger the monolithic read on the first chunk, then naked read on |
| 1198 | * Otherwise, use monolithic read. | 1198 | * intermediate chunks and finally a last naked read on the last chunk. |
| 1199 | */ | 1199 | */ |
| 1200 | if (lt->nchunks == 1 || (chunk < lt->nchunks - 1)) | 1200 | if (chunk == 0) |
| 1201 | nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW); | 1201 | nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW); |
| 1202 | else if (chunk < lt->nchunks - 1) | ||
| 1203 | nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_NAKED_RW); | ||
| 1202 | else | 1204 | else |
| 1203 | nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_LAST_NAKED_RW); | 1205 | nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_LAST_NAKED_RW); |
| 1204 | 1206 | ||
| @@ -1408,6 +1410,7 @@ marvell_nfc_hw_ecc_bch_write_chunk(struct nand_chip *chip, int chunk, | |||
| 1408 | struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip); | 1410 | struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip); |
| 1409 | struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); | 1411 | struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); |
| 1410 | const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout; | 1412 | const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout; |
| 1413 | u32 xtype; | ||
| 1411 | int ret; | 1414 | int ret; |
| 1412 | struct marvell_nfc_op nfc_op = { | 1415 | struct marvell_nfc_op nfc_op = { |
| 1413 | .ndcb[0] = NDCB0_CMD_TYPE(TYPE_WRITE) | NDCB0_LEN_OVRD, | 1416 | .ndcb[0] = NDCB0_CMD_TYPE(TYPE_WRITE) | NDCB0_LEN_OVRD, |
| @@ -1423,7 +1426,12 @@ marvell_nfc_hw_ecc_bch_write_chunk(struct nand_chip *chip, int chunk, | |||
| 1423 | * last naked write. | 1426 | * last naked write. |
| 1424 | */ | 1427 | */ |
| 1425 | if (chunk == 0) { | 1428 | if (chunk == 0) { |
| 1426 | nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_WRITE_DISPATCH) | | 1429 | if (lt->nchunks == 1) |
| 1430 | xtype = XTYPE_MONOLITHIC_RW; | ||
| 1431 | else | ||
| 1432 | xtype = XTYPE_WRITE_DISPATCH; | ||
| 1433 | |||
| 1434 | nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(xtype) | | ||
| 1427 | NDCB0_ADDR_CYC(marvell_nand->addr_cyc) | | 1435 | NDCB0_ADDR_CYC(marvell_nand->addr_cyc) | |
| 1428 | NDCB0_CMD1(NAND_CMD_SEQIN); | 1436 | NDCB0_CMD1(NAND_CMD_SEQIN); |
| 1429 | nfc_op.ndcb[1] |= NDCB1_ADDRS_PAGE(page); | 1437 | nfc_op.ndcb[1] |= NDCB1_ADDRS_PAGE(page); |
| @@ -1494,7 +1502,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct mtd_info *mtd, | |||
| 1494 | } | 1502 | } |
| 1495 | 1503 | ||
| 1496 | ret = marvell_nfc_wait_op(chip, | 1504 | ret = marvell_nfc_wait_op(chip, |
| 1497 | chip->data_interface.timings.sdr.tPROG_max); | 1505 | PSEC_TO_MSEC(chip->data_interface.timings.sdr.tPROG_max)); |
| 1498 | 1506 | ||
| 1499 | marvell_nfc_disable_hw_ecc(chip); | 1507 | marvell_nfc_disable_hw_ecc(chip); |
| 1500 | 1508 | ||
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 72f3a89da513..f28c3a555861 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c | |||
| @@ -706,12 +706,17 @@ static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) | |||
| 706 | */ | 706 | */ |
| 707 | int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) | 707 | int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) |
| 708 | { | 708 | { |
| 709 | const struct nand_sdr_timings *timings; | ||
| 709 | u8 status = 0; | 710 | u8 status = 0; |
| 710 | int ret; | 711 | int ret; |
| 711 | 712 | ||
| 712 | if (!chip->exec_op) | 713 | if (!chip->exec_op) |
| 713 | return -ENOTSUPP; | 714 | return -ENOTSUPP; |
| 714 | 715 | ||
| 716 | /* Wait tWB before polling the STATUS reg. */ | ||
| 717 | timings = nand_get_sdr_timings(&chip->data_interface); | ||
| 718 | ndelay(PSEC_TO_NSEC(timings->tWB_max)); | ||
| 719 | |||
| 715 | ret = nand_status_op(chip, NULL); | 720 | ret = nand_status_op(chip, NULL); |
| 716 | if (ret) | 721 | if (ret) |
| 717 | return ret; | 722 | return ret; |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 1ed9529e7bd1..5eb0df2e5464 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
| @@ -450,7 +450,7 @@ static void rlb_update_client(struct rlb_client_info *client_info) | |||
| 450 | { | 450 | { |
| 451 | int i; | 451 | int i; |
| 452 | 452 | ||
| 453 | if (!client_info->slave) | 453 | if (!client_info->slave || !is_valid_ether_addr(client_info->mac_dst)) |
| 454 | return; | 454 | return; |
| 455 | 455 | ||
| 456 | for (i = 0; i < RLB_ARP_BURST_SIZE; i++) { | 456 | for (i = 0; i < RLB_ARP_BURST_SIZE; i++) { |
| @@ -943,6 +943,10 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], | |||
| 943 | skb->priority = TC_PRIO_CONTROL; | 943 | skb->priority = TC_PRIO_CONTROL; |
| 944 | skb->dev = slave->dev; | 944 | skb->dev = slave->dev; |
| 945 | 945 | ||
| 946 | netdev_dbg(slave->bond->dev, | ||
| 947 | "Send learning packet: dev %s mac %pM vlan %d\n", | ||
| 948 | slave->dev->name, mac_addr, vid); | ||
| 949 | |||
| 946 | if (vid) | 950 | if (vid) |
| 947 | __vlan_hwaccel_put_tag(skb, vlan_proto, vid); | 951 | __vlan_hwaccel_put_tag(skb, vlan_proto, vid); |
| 948 | 952 | ||
| @@ -965,14 +969,13 @@ static int alb_upper_dev_walk(struct net_device *upper, void *_data) | |||
| 965 | u8 *mac_addr = data->mac_addr; | 969 | u8 *mac_addr = data->mac_addr; |
| 966 | struct bond_vlan_tag *tags; | 970 | struct bond_vlan_tag *tags; |
| 967 | 971 | ||
| 968 | if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) { | 972 | if (is_vlan_dev(upper) && |
| 969 | if (strict_match && | 973 | bond->nest_level == vlan_get_encap_level(upper) - 1) { |
| 970 | ether_addr_equal_64bits(mac_addr, | 974 | if (upper->addr_assign_type == NET_ADDR_STOLEN) { |
| 971 | upper->dev_addr)) { | ||
| 972 | alb_send_lp_vid(slave, mac_addr, | 975 | alb_send_lp_vid(slave, mac_addr, |
| 973 | vlan_dev_vlan_proto(upper), | 976 | vlan_dev_vlan_proto(upper), |
| 974 | vlan_dev_vlan_id(upper)); | 977 | vlan_dev_vlan_id(upper)); |
| 975 | } else if (!strict_match) { | 978 | } else { |
| 976 | alb_send_lp_vid(slave, upper->dev_addr, | 979 | alb_send_lp_vid(slave, upper->dev_addr, |
| 977 | vlan_dev_vlan_proto(upper), | 980 | vlan_dev_vlan_proto(upper), |
| 978 | vlan_dev_vlan_id(upper)); | 981 | vlan_dev_vlan_id(upper)); |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 718e4914e3a0..1f1e97b26f95 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -1738,6 +1738,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, | |||
| 1738 | if (bond_mode_uses_xmit_hash(bond)) | 1738 | if (bond_mode_uses_xmit_hash(bond)) |
| 1739 | bond_update_slave_arr(bond, NULL); | 1739 | bond_update_slave_arr(bond, NULL); |
| 1740 | 1740 | ||
| 1741 | bond->nest_level = dev_get_nest_level(bond_dev); | ||
| 1742 | |||
| 1741 | netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n", | 1743 | netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n", |
| 1742 | slave_dev->name, | 1744 | slave_dev->name, |
| 1743 | bond_is_active_slave(new_slave) ? "an active" : "a backup", | 1745 | bond_is_active_slave(new_slave) ? "an active" : "a backup", |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index b1779566c5bb..3c71f1cb205f 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
| @@ -605,7 +605,7 @@ void can_bus_off(struct net_device *dev) | |||
| 605 | { | 605 | { |
| 606 | struct can_priv *priv = netdev_priv(dev); | 606 | struct can_priv *priv = netdev_priv(dev); |
| 607 | 607 | ||
| 608 | netdev_dbg(dev, "bus-off\n"); | 608 | netdev_info(dev, "bus-off\n"); |
| 609 | 609 | ||
| 610 | netif_carrier_off(dev); | 610 | netif_carrier_off(dev); |
| 611 | 611 | ||
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 634c51e6b8ae..d53a45bf2a72 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -200,6 +200,7 @@ | |||
| 200 | #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ | 200 | #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ |
| 201 | #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ | 201 | #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ |
| 202 | #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ | 202 | #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ |
| 203 | #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) /* default to BE register access */ | ||
| 203 | 204 | ||
| 204 | /* Structure of the message buffer */ | 205 | /* Structure of the message buffer */ |
| 205 | struct flexcan_mb { | 206 | struct flexcan_mb { |
| @@ -288,6 +289,12 @@ struct flexcan_priv { | |||
| 288 | 289 | ||
| 289 | static const struct flexcan_devtype_data fsl_p1010_devtype_data = { | 290 | static const struct flexcan_devtype_data fsl_p1010_devtype_data = { |
| 290 | .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | | 291 | .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
| 292 | FLEXCAN_QUIRK_BROKEN_PERR_STATE | | ||
| 293 | FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN, | ||
| 294 | }; | ||
| 295 | |||
| 296 | static const struct flexcan_devtype_data fsl_imx25_devtype_data = { | ||
| 297 | .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | | ||
| 291 | FLEXCAN_QUIRK_BROKEN_PERR_STATE, | 298 | FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
| 292 | }; | 299 | }; |
| 293 | 300 | ||
| @@ -1251,9 +1258,9 @@ static void unregister_flexcandev(struct net_device *dev) | |||
| 1251 | static const struct of_device_id flexcan_of_match[] = { | 1258 | static const struct of_device_id flexcan_of_match[] = { |
| 1252 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, | 1259 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, |
| 1253 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, | 1260 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, |
| 1254 | { .compatible = "fsl,imx53-flexcan", .data = &fsl_p1010_devtype_data, }, | 1261 | { .compatible = "fsl,imx53-flexcan", .data = &fsl_imx25_devtype_data, }, |
| 1255 | { .compatible = "fsl,imx35-flexcan", .data = &fsl_p1010_devtype_data, }, | 1262 | { .compatible = "fsl,imx35-flexcan", .data = &fsl_imx25_devtype_data, }, |
| 1256 | { .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data, }, | 1263 | { .compatible = "fsl,imx25-flexcan", .data = &fsl_imx25_devtype_data, }, |
| 1257 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, | 1264 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, |
| 1258 | { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, | 1265 | { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, |
| 1259 | { .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, }, | 1266 | { .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, }, |
| @@ -1337,18 +1344,13 @@ static int flexcan_probe(struct platform_device *pdev) | |||
| 1337 | 1344 | ||
| 1338 | priv = netdev_priv(dev); | 1345 | priv = netdev_priv(dev); |
| 1339 | 1346 | ||
| 1340 | if (of_property_read_bool(pdev->dev.of_node, "big-endian")) { | 1347 | if (of_property_read_bool(pdev->dev.of_node, "big-endian") || |
| 1348 | devtype_data->quirks & FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN) { | ||
| 1341 | priv->read = flexcan_read_be; | 1349 | priv->read = flexcan_read_be; |
| 1342 | priv->write = flexcan_write_be; | 1350 | priv->write = flexcan_write_be; |
| 1343 | } else { | 1351 | } else { |
| 1344 | if (of_device_is_compatible(pdev->dev.of_node, | 1352 | priv->read = flexcan_read_le; |
| 1345 | "fsl,p1010-flexcan")) { | 1353 | priv->write = flexcan_write_le; |
| 1346 | priv->read = flexcan_read_be; | ||
| 1347 | priv->write = flexcan_write_be; | ||
| 1348 | } else { | ||
| 1349 | priv->read = flexcan_read_le; | ||
| 1350 | priv->write = flexcan_write_le; | ||
| 1351 | } | ||
| 1352 | } | 1354 | } |
| 1353 | 1355 | ||
| 1354 | priv->can.clock.freq = clock_freq; | 1356 | priv->can.clock.freq = clock_freq; |
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c index 5590c559a8ca..53e320c92a8b 100644 --- a/drivers/net/can/spi/hi311x.c +++ b/drivers/net/can/spi/hi311x.c | |||
| @@ -91,6 +91,7 @@ | |||
| 91 | #define HI3110_STAT_BUSOFF BIT(2) | 91 | #define HI3110_STAT_BUSOFF BIT(2) |
| 92 | #define HI3110_STAT_ERRP BIT(3) | 92 | #define HI3110_STAT_ERRP BIT(3) |
| 93 | #define HI3110_STAT_ERRW BIT(4) | 93 | #define HI3110_STAT_ERRW BIT(4) |
| 94 | #define HI3110_STAT_TXMTY BIT(7) | ||
| 94 | 95 | ||
| 95 | #define HI3110_BTR0_SJW_SHIFT 6 | 96 | #define HI3110_BTR0_SJW_SHIFT 6 |
| 96 | #define HI3110_BTR0_BRP_SHIFT 0 | 97 | #define HI3110_BTR0_BRP_SHIFT 0 |
| @@ -427,8 +428,10 @@ static int hi3110_get_berr_counter(const struct net_device *net, | |||
| 427 | struct hi3110_priv *priv = netdev_priv(net); | 428 | struct hi3110_priv *priv = netdev_priv(net); |
| 428 | struct spi_device *spi = priv->spi; | 429 | struct spi_device *spi = priv->spi; |
| 429 | 430 | ||
| 431 | mutex_lock(&priv->hi3110_lock); | ||
| 430 | bec->txerr = hi3110_read(spi, HI3110_READ_TEC); | 432 | bec->txerr = hi3110_read(spi, HI3110_READ_TEC); |
| 431 | bec->rxerr = hi3110_read(spi, HI3110_READ_REC); | 433 | bec->rxerr = hi3110_read(spi, HI3110_READ_REC); |
| 434 | mutex_unlock(&priv->hi3110_lock); | ||
| 432 | 435 | ||
| 433 | return 0; | 436 | return 0; |
| 434 | } | 437 | } |
| @@ -735,10 +738,7 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) | |||
| 735 | } | 738 | } |
| 736 | } | 739 | } |
| 737 | 740 | ||
| 738 | if (intf == 0) | 741 | if (priv->tx_len && statf & HI3110_STAT_TXMTY) { |
| 739 | break; | ||
| 740 | |||
| 741 | if (intf & HI3110_INT_TXCPLT) { | ||
| 742 | net->stats.tx_packets++; | 742 | net->stats.tx_packets++; |
| 743 | net->stats.tx_bytes += priv->tx_len - 1; | 743 | net->stats.tx_bytes += priv->tx_len - 1; |
| 744 | can_led_event(net, CAN_LED_EVENT_TX); | 744 | can_led_event(net, CAN_LED_EVENT_TX); |
| @@ -748,6 +748,9 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) | |||
| 748 | } | 748 | } |
| 749 | netif_wake_queue(net); | 749 | netif_wake_queue(net); |
| 750 | } | 750 | } |
| 751 | |||
| 752 | if (intf == 0) | ||
| 753 | break; | ||
| 751 | } | 754 | } |
| 752 | mutex_unlock(&priv->hi3110_lock); | 755 | mutex_unlock(&priv->hi3110_lock); |
| 753 | return IRQ_HANDLED; | 756 | return IRQ_HANDLED; |
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 63587b8e6825..daed57d3d209 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
| @@ -1179,7 +1179,7 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, | |||
| 1179 | 1179 | ||
| 1180 | skb = alloc_can_skb(priv->netdev, &cf); | 1180 | skb = alloc_can_skb(priv->netdev, &cf); |
| 1181 | if (!skb) { | 1181 | if (!skb) { |
| 1182 | stats->tx_dropped++; | 1182 | stats->rx_dropped++; |
| 1183 | return; | 1183 | return; |
| 1184 | } | 1184 | } |
| 1185 | 1185 | ||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 3d2091099f7f..5b4374f21d76 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c | |||
| @@ -3370,6 +3370,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3370 | .num_internal_phys = 5, | 3370 | .num_internal_phys = 5, |
| 3371 | .max_vid = 4095, | 3371 | .max_vid = 4095, |
| 3372 | .port_base_addr = 0x10, | 3372 | .port_base_addr = 0x10, |
| 3373 | .phy_base_addr = 0x0, | ||
| 3373 | .global1_addr = 0x1b, | 3374 | .global1_addr = 0x1b, |
| 3374 | .global2_addr = 0x1c, | 3375 | .global2_addr = 0x1c, |
| 3375 | .age_time_coeff = 15000, | 3376 | .age_time_coeff = 15000, |
| @@ -3391,6 +3392,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3391 | .num_internal_phys = 0, | 3392 | .num_internal_phys = 0, |
| 3392 | .max_vid = 4095, | 3393 | .max_vid = 4095, |
| 3393 | .port_base_addr = 0x10, | 3394 | .port_base_addr = 0x10, |
| 3395 | .phy_base_addr = 0x0, | ||
| 3394 | .global1_addr = 0x1b, | 3396 | .global1_addr = 0x1b, |
| 3395 | .global2_addr = 0x1c, | 3397 | .global2_addr = 0x1c, |
| 3396 | .age_time_coeff = 15000, | 3398 | .age_time_coeff = 15000, |
| @@ -3410,6 +3412,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3410 | .num_internal_phys = 8, | 3412 | .num_internal_phys = 8, |
| 3411 | .max_vid = 4095, | 3413 | .max_vid = 4095, |
| 3412 | .port_base_addr = 0x10, | 3414 | .port_base_addr = 0x10, |
| 3415 | .phy_base_addr = 0x0, | ||
| 3413 | .global1_addr = 0x1b, | 3416 | .global1_addr = 0x1b, |
| 3414 | .global2_addr = 0x1c, | 3417 | .global2_addr = 0x1c, |
| 3415 | .age_time_coeff = 15000, | 3418 | .age_time_coeff = 15000, |
| @@ -3431,6 +3434,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3431 | .num_internal_phys = 5, | 3434 | .num_internal_phys = 5, |
| 3432 | .max_vid = 4095, | 3435 | .max_vid = 4095, |
| 3433 | .port_base_addr = 0x10, | 3436 | .port_base_addr = 0x10, |
| 3437 | .phy_base_addr = 0x0, | ||
| 3434 | .global1_addr = 0x1b, | 3438 | .global1_addr = 0x1b, |
| 3435 | .global2_addr = 0x1c, | 3439 | .global2_addr = 0x1c, |
| 3436 | .age_time_coeff = 15000, | 3440 | .age_time_coeff = 15000, |
| @@ -3452,6 +3456,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3452 | .num_internal_phys = 0, | 3456 | .num_internal_phys = 0, |
| 3453 | .max_vid = 4095, | 3457 | .max_vid = 4095, |
| 3454 | .port_base_addr = 0x10, | 3458 | .port_base_addr = 0x10, |
| 3459 | .phy_base_addr = 0x0, | ||
| 3455 | .global1_addr = 0x1b, | 3460 | .global1_addr = 0x1b, |
| 3456 | .global2_addr = 0x1c, | 3461 | .global2_addr = 0x1c, |
| 3457 | .age_time_coeff = 15000, | 3462 | .age_time_coeff = 15000, |
| @@ -3472,6 +3477,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3472 | .num_gpio = 11, | 3477 | .num_gpio = 11, |
| 3473 | .max_vid = 4095, | 3478 | .max_vid = 4095, |
| 3474 | .port_base_addr = 0x10, | 3479 | .port_base_addr = 0x10, |
| 3480 | .phy_base_addr = 0x10, | ||
| 3475 | .global1_addr = 0x1b, | 3481 | .global1_addr = 0x1b, |
| 3476 | .global2_addr = 0x1c, | 3482 | .global2_addr = 0x1c, |
| 3477 | .age_time_coeff = 3750, | 3483 | .age_time_coeff = 3750, |
| @@ -3493,6 +3499,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3493 | .num_internal_phys = 5, | 3499 | .num_internal_phys = 5, |
| 3494 | .max_vid = 4095, | 3500 | .max_vid = 4095, |
| 3495 | .port_base_addr = 0x10, | 3501 | .port_base_addr = 0x10, |
| 3502 | .phy_base_addr = 0x0, | ||
| 3496 | .global1_addr = 0x1b, | 3503 | .global1_addr = 0x1b, |
| 3497 | .global2_addr = 0x1c, | 3504 | .global2_addr = 0x1c, |
| 3498 | .age_time_coeff = 15000, | 3505 | .age_time_coeff = 15000, |
| @@ -3514,6 +3521,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3514 | .num_internal_phys = 0, | 3521 | .num_internal_phys = 0, |
| 3515 | .max_vid = 4095, | 3522 | .max_vid = 4095, |
| 3516 | .port_base_addr = 0x10, | 3523 | .port_base_addr = 0x10, |
| 3524 | .phy_base_addr = 0x0, | ||
| 3517 | .global1_addr = 0x1b, | 3525 | .global1_addr = 0x1b, |
| 3518 | .global2_addr = 0x1c, | 3526 | .global2_addr = 0x1c, |
| 3519 | .age_time_coeff = 15000, | 3527 | .age_time_coeff = 15000, |
| @@ -3535,6 +3543,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3535 | .num_internal_phys = 5, | 3543 | .num_internal_phys = 5, |
| 3536 | .max_vid = 4095, | 3544 | .max_vid = 4095, |
| 3537 | .port_base_addr = 0x10, | 3545 | .port_base_addr = 0x10, |
| 3546 | .phy_base_addr = 0x0, | ||
| 3538 | .global1_addr = 0x1b, | 3547 | .global1_addr = 0x1b, |
| 3539 | .global2_addr = 0x1c, | 3548 | .global2_addr = 0x1c, |
| 3540 | .age_time_coeff = 15000, | 3549 | .age_time_coeff = 15000, |
| @@ -3557,6 +3566,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3557 | .num_gpio = 15, | 3566 | .num_gpio = 15, |
| 3558 | .max_vid = 4095, | 3567 | .max_vid = 4095, |
| 3559 | .port_base_addr = 0x10, | 3568 | .port_base_addr = 0x10, |
| 3569 | .phy_base_addr = 0x0, | ||
| 3560 | .global1_addr = 0x1b, | 3570 | .global1_addr = 0x1b, |
| 3561 | .global2_addr = 0x1c, | 3571 | .global2_addr = 0x1c, |
| 3562 | .age_time_coeff = 15000, | 3572 | .age_time_coeff = 15000, |
| @@ -3578,6 +3588,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3578 | .num_internal_phys = 5, | 3588 | .num_internal_phys = 5, |
| 3579 | .max_vid = 4095, | 3589 | .max_vid = 4095, |
| 3580 | .port_base_addr = 0x10, | 3590 | .port_base_addr = 0x10, |
| 3591 | .phy_base_addr = 0x0, | ||
| 3581 | .global1_addr = 0x1b, | 3592 | .global1_addr = 0x1b, |
| 3582 | .global2_addr = 0x1c, | 3593 | .global2_addr = 0x1c, |
| 3583 | .age_time_coeff = 15000, | 3594 | .age_time_coeff = 15000, |
| @@ -3600,6 +3611,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3600 | .num_gpio = 15, | 3611 | .num_gpio = 15, |
| 3601 | .max_vid = 4095, | 3612 | .max_vid = 4095, |
| 3602 | .port_base_addr = 0x10, | 3613 | .port_base_addr = 0x10, |
| 3614 | .phy_base_addr = 0x0, | ||
| 3603 | .global1_addr = 0x1b, | 3615 | .global1_addr = 0x1b, |
| 3604 | .global2_addr = 0x1c, | 3616 | .global2_addr = 0x1c, |
| 3605 | .age_time_coeff = 15000, | 3617 | .age_time_coeff = 15000, |
| @@ -3621,6 +3633,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3621 | .num_internal_phys = 0, | 3633 | .num_internal_phys = 0, |
| 3622 | .max_vid = 4095, | 3634 | .max_vid = 4095, |
| 3623 | .port_base_addr = 0x10, | 3635 | .port_base_addr = 0x10, |
| 3636 | .phy_base_addr = 0x0, | ||
| 3624 | .global1_addr = 0x1b, | 3637 | .global1_addr = 0x1b, |
| 3625 | .global2_addr = 0x1c, | 3638 | .global2_addr = 0x1c, |
| 3626 | .age_time_coeff = 15000, | 3639 | .age_time_coeff = 15000, |
| @@ -3641,6 +3654,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3641 | .num_gpio = 16, | 3654 | .num_gpio = 16, |
| 3642 | .max_vid = 8191, | 3655 | .max_vid = 8191, |
| 3643 | .port_base_addr = 0x0, | 3656 | .port_base_addr = 0x0, |
| 3657 | .phy_base_addr = 0x0, | ||
| 3644 | .global1_addr = 0x1b, | 3658 | .global1_addr = 0x1b, |
| 3645 | .global2_addr = 0x1c, | 3659 | .global2_addr = 0x1c, |
| 3646 | .tag_protocol = DSA_TAG_PROTO_DSA, | 3660 | .tag_protocol = DSA_TAG_PROTO_DSA, |
| @@ -3663,6 +3677,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3663 | .num_gpio = 16, | 3677 | .num_gpio = 16, |
| 3664 | .max_vid = 8191, | 3678 | .max_vid = 8191, |
| 3665 | .port_base_addr = 0x0, | 3679 | .port_base_addr = 0x0, |
| 3680 | .phy_base_addr = 0x0, | ||
| 3666 | .global1_addr = 0x1b, | 3681 | .global1_addr = 0x1b, |
| 3667 | .global2_addr = 0x1c, | 3682 | .global2_addr = 0x1c, |
| 3668 | .age_time_coeff = 3750, | 3683 | .age_time_coeff = 3750, |
| @@ -3684,6 +3699,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3684 | .num_internal_phys = 11, | 3699 | .num_internal_phys = 11, |
| 3685 | .max_vid = 8191, | 3700 | .max_vid = 8191, |
| 3686 | .port_base_addr = 0x0, | 3701 | .port_base_addr = 0x0, |
| 3702 | .phy_base_addr = 0x0, | ||
| 3687 | .global1_addr = 0x1b, | 3703 | .global1_addr = 0x1b, |
| 3688 | .global2_addr = 0x1c, | 3704 | .global2_addr = 0x1c, |
| 3689 | .age_time_coeff = 3750, | 3705 | .age_time_coeff = 3750, |
| @@ -3707,6 +3723,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3707 | .num_gpio = 15, | 3723 | .num_gpio = 15, |
| 3708 | .max_vid = 4095, | 3724 | .max_vid = 4095, |
| 3709 | .port_base_addr = 0x10, | 3725 | .port_base_addr = 0x10, |
| 3726 | .phy_base_addr = 0x0, | ||
| 3710 | .global1_addr = 0x1b, | 3727 | .global1_addr = 0x1b, |
| 3711 | .global2_addr = 0x1c, | 3728 | .global2_addr = 0x1c, |
| 3712 | .age_time_coeff = 15000, | 3729 | .age_time_coeff = 15000, |
| @@ -3730,6 +3747,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3730 | .num_gpio = 16, | 3747 | .num_gpio = 16, |
| 3731 | .max_vid = 8191, | 3748 | .max_vid = 8191, |
| 3732 | .port_base_addr = 0x0, | 3749 | .port_base_addr = 0x0, |
| 3750 | .phy_base_addr = 0x0, | ||
| 3733 | .global1_addr = 0x1b, | 3751 | .global1_addr = 0x1b, |
| 3734 | .global2_addr = 0x1c, | 3752 | .global2_addr = 0x1c, |
| 3735 | .age_time_coeff = 3750, | 3753 | .age_time_coeff = 3750, |
| @@ -3753,6 +3771,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3753 | .num_gpio = 15, | 3771 | .num_gpio = 15, |
| 3754 | .max_vid = 4095, | 3772 | .max_vid = 4095, |
| 3755 | .port_base_addr = 0x10, | 3773 | .port_base_addr = 0x10, |
| 3774 | .phy_base_addr = 0x0, | ||
| 3756 | .global1_addr = 0x1b, | 3775 | .global1_addr = 0x1b, |
| 3757 | .global2_addr = 0x1c, | 3776 | .global2_addr = 0x1c, |
| 3758 | .age_time_coeff = 15000, | 3777 | .age_time_coeff = 15000, |
| @@ -3776,6 +3795,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3776 | .num_gpio = 15, | 3795 | .num_gpio = 15, |
| 3777 | .max_vid = 4095, | 3796 | .max_vid = 4095, |
| 3778 | .port_base_addr = 0x10, | 3797 | .port_base_addr = 0x10, |
| 3798 | .phy_base_addr = 0x0, | ||
| 3779 | .global1_addr = 0x1b, | 3799 | .global1_addr = 0x1b, |
| 3780 | .global2_addr = 0x1c, | 3800 | .global2_addr = 0x1c, |
| 3781 | .age_time_coeff = 15000, | 3801 | .age_time_coeff = 15000, |
| @@ -3798,6 +3818,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3798 | .num_gpio = 11, | 3818 | .num_gpio = 11, |
| 3799 | .max_vid = 4095, | 3819 | .max_vid = 4095, |
| 3800 | .port_base_addr = 0x10, | 3820 | .port_base_addr = 0x10, |
| 3821 | .phy_base_addr = 0x10, | ||
| 3801 | .global1_addr = 0x1b, | 3822 | .global1_addr = 0x1b, |
| 3802 | .global2_addr = 0x1c, | 3823 | .global2_addr = 0x1c, |
| 3803 | .age_time_coeff = 3750, | 3824 | .age_time_coeff = 3750, |
| @@ -3820,6 +3841,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3820 | .num_internal_phys = 5, | 3841 | .num_internal_phys = 5, |
| 3821 | .max_vid = 4095, | 3842 | .max_vid = 4095, |
| 3822 | .port_base_addr = 0x10, | 3843 | .port_base_addr = 0x10, |
| 3844 | .phy_base_addr = 0x0, | ||
| 3823 | .global1_addr = 0x1b, | 3845 | .global1_addr = 0x1b, |
| 3824 | .global2_addr = 0x1c, | 3846 | .global2_addr = 0x1c, |
| 3825 | .age_time_coeff = 15000, | 3847 | .age_time_coeff = 15000, |
| @@ -3841,6 +3863,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3841 | .num_internal_phys = 5, | 3863 | .num_internal_phys = 5, |
| 3842 | .max_vid = 4095, | 3864 | .max_vid = 4095, |
| 3843 | .port_base_addr = 0x10, | 3865 | .port_base_addr = 0x10, |
| 3866 | .phy_base_addr = 0x0, | ||
| 3844 | .global1_addr = 0x1b, | 3867 | .global1_addr = 0x1b, |
| 3845 | .global2_addr = 0x1c, | 3868 | .global2_addr = 0x1c, |
| 3846 | .age_time_coeff = 15000, | 3869 | .age_time_coeff = 15000, |
| @@ -3863,6 +3886,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3863 | .num_gpio = 15, | 3886 | .num_gpio = 15, |
| 3864 | .max_vid = 4095, | 3887 | .max_vid = 4095, |
| 3865 | .port_base_addr = 0x10, | 3888 | .port_base_addr = 0x10, |
| 3889 | .phy_base_addr = 0x0, | ||
| 3866 | .global1_addr = 0x1b, | 3890 | .global1_addr = 0x1b, |
| 3867 | .global2_addr = 0x1c, | 3891 | .global2_addr = 0x1c, |
| 3868 | .age_time_coeff = 15000, | 3892 | .age_time_coeff = 15000, |
| @@ -3885,6 +3909,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3885 | .num_gpio = 16, | 3909 | .num_gpio = 16, |
| 3886 | .max_vid = 8191, | 3910 | .max_vid = 8191, |
| 3887 | .port_base_addr = 0x0, | 3911 | .port_base_addr = 0x0, |
| 3912 | .phy_base_addr = 0x0, | ||
| 3888 | .global1_addr = 0x1b, | 3913 | .global1_addr = 0x1b, |
| 3889 | .global2_addr = 0x1c, | 3914 | .global2_addr = 0x1c, |
| 3890 | .age_time_coeff = 3750, | 3915 | .age_time_coeff = 3750, |
| @@ -3907,6 +3932,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
| 3907 | .num_gpio = 16, | 3932 | .num_gpio = 16, |
| 3908 | .max_vid = 8191, | 3933 | .max_vid = 8191, |
| 3909 | .port_base_addr = 0x0, | 3934 | .port_base_addr = 0x0, |
| 3935 | .phy_base_addr = 0x0, | ||
| 3910 | .global1_addr = 0x1b, | 3936 | .global1_addr = 0x1b, |
| 3911 | .global2_addr = 0x1c, | 3937 | .global2_addr = 0x1c, |
| 3912 | .age_time_coeff = 3750, | 3938 | .age_time_coeff = 3750, |
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 80490f66bc06..12b7f4649b25 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h | |||
| @@ -114,6 +114,7 @@ struct mv88e6xxx_info { | |||
| 114 | unsigned int num_gpio; | 114 | unsigned int num_gpio; |
| 115 | unsigned int max_vid; | 115 | unsigned int max_vid; |
| 116 | unsigned int port_base_addr; | 116 | unsigned int port_base_addr; |
| 117 | unsigned int phy_base_addr; | ||
| 117 | unsigned int global1_addr; | 118 | unsigned int global1_addr; |
| 118 | unsigned int global2_addr; | 119 | unsigned int global2_addr; |
| 119 | unsigned int age_time_coeff; | 120 | unsigned int age_time_coeff; |
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c index 0ce627fded48..8d22d66d84b7 100644 --- a/drivers/net/dsa/mv88e6xxx/global2.c +++ b/drivers/net/dsa/mv88e6xxx/global2.c | |||
| @@ -1118,7 +1118,7 @@ int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip, | |||
| 1118 | err = irq; | 1118 | err = irq; |
| 1119 | goto out; | 1119 | goto out; |
| 1120 | } | 1120 | } |
| 1121 | bus->irq[chip->info->port_base_addr + phy] = irq; | 1121 | bus->irq[chip->info->phy_base_addr + phy] = irq; |
| 1122 | } | 1122 | } |
| 1123 | return 0; | 1123 | return 0; |
| 1124 | out: | 1124 | out: |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 32f6d2e24d66..1a1a6380c128 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c | |||
| @@ -95,6 +95,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self) | |||
| 95 | /*rss rings */ | 95 | /*rss rings */ |
| 96 | cfg->vecs = min(cfg->aq_hw_caps->vecs, AQ_CFG_VECS_DEF); | 96 | cfg->vecs = min(cfg->aq_hw_caps->vecs, AQ_CFG_VECS_DEF); |
| 97 | cfg->vecs = min(cfg->vecs, num_online_cpus()); | 97 | cfg->vecs = min(cfg->vecs, num_online_cpus()); |
| 98 | cfg->vecs = min(cfg->vecs, self->irqvecs); | ||
| 98 | /* cfg->vecs should be power of 2 for RSS */ | 99 | /* cfg->vecs should be power of 2 for RSS */ |
| 99 | if (cfg->vecs >= 8U) | 100 | if (cfg->vecs >= 8U) |
| 100 | cfg->vecs = 8U; | 101 | cfg->vecs = 8U; |
| @@ -246,6 +247,8 @@ void aq_nic_ndev_init(struct aq_nic_s *self) | |||
| 246 | 247 | ||
| 247 | self->ndev->hw_features |= aq_hw_caps->hw_features; | 248 | self->ndev->hw_features |= aq_hw_caps->hw_features; |
| 248 | self->ndev->features = aq_hw_caps->hw_features; | 249 | self->ndev->features = aq_hw_caps->hw_features; |
| 250 | self->ndev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM | | ||
| 251 | NETIF_F_RXHASH | NETIF_F_SG | NETIF_F_LRO; | ||
| 249 | self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; | 252 | self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; |
| 250 | self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; | 253 | self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; |
| 251 | 254 | ||
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h index 219b550d1665..faa533a0ec47 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h | |||
| @@ -80,6 +80,7 @@ struct aq_nic_s { | |||
| 80 | 80 | ||
| 81 | struct pci_dev *pdev; | 81 | struct pci_dev *pdev; |
| 82 | unsigned int msix_entry_mask; | 82 | unsigned int msix_entry_mask; |
| 83 | u32 irqvecs; | ||
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| 85 | static inline struct device *aq_nic_get_dev(struct aq_nic_s *self) | 86 | static inline struct device *aq_nic_get_dev(struct aq_nic_s *self) |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index ecc6306f940f..a50e08bb4748 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | |||
| @@ -267,16 +267,16 @@ static int aq_pci_probe(struct pci_dev *pdev, | |||
| 267 | numvecs = min(numvecs, num_online_cpus()); | 267 | numvecs = min(numvecs, num_online_cpus()); |
| 268 | /*enable interrupts */ | 268 | /*enable interrupts */ |
| 269 | #if !AQ_CFG_FORCE_LEGACY_INT | 269 | #if !AQ_CFG_FORCE_LEGACY_INT |
| 270 | err = pci_alloc_irq_vectors(self->pdev, numvecs, numvecs, | 270 | numvecs = pci_alloc_irq_vectors(self->pdev, 1, numvecs, |
| 271 | PCI_IRQ_MSIX); | 271 | PCI_IRQ_MSIX | PCI_IRQ_MSI | |
| 272 | 272 | PCI_IRQ_LEGACY); | |
| 273 | if (err < 0) { | 273 | |
| 274 | err = pci_alloc_irq_vectors(self->pdev, 1, 1, | 274 | if (numvecs < 0) { |
| 275 | PCI_IRQ_MSI | PCI_IRQ_LEGACY); | 275 | err = numvecs; |
| 276 | if (err < 0) | 276 | goto err_hwinit; |
| 277 | goto err_hwinit; | ||
| 278 | } | 277 | } |
| 279 | #endif | 278 | #endif |
| 279 | self->irqvecs = numvecs; | ||
| 280 | 280 | ||
| 281 | /* net device init */ | 281 | /* net device init */ |
| 282 | aq_nic_cfg_start(self); | 282 | aq_nic_cfg_start(self); |
| @@ -298,9 +298,9 @@ err_free_aq_hw: | |||
| 298 | kfree(self->aq_hw); | 298 | kfree(self->aq_hw); |
| 299 | err_ioremap: | 299 | err_ioremap: |
| 300 | free_netdev(ndev); | 300 | free_netdev(ndev); |
| 301 | err_pci_func: | ||
| 302 | pci_release_regions(pdev); | ||
| 303 | err_ndev: | 301 | err_ndev: |
| 302 | pci_release_regions(pdev); | ||
| 303 | err_pci_func: | ||
| 304 | pci_disable_device(pdev); | 304 | pci_disable_device(pdev); |
| 305 | return err; | 305 | return err; |
| 306 | } | 306 | } |
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index f9a3c1a76d5d..f33b25fbca63 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c | |||
| @@ -2144,14 +2144,21 @@ static const struct net_device_ops bcm_sysport_netdev_ops = { | |||
| 2144 | .ndo_select_queue = bcm_sysport_select_queue, | 2144 | .ndo_select_queue = bcm_sysport_select_queue, |
| 2145 | }; | 2145 | }; |
| 2146 | 2146 | ||
| 2147 | static int bcm_sysport_map_queues(struct net_device *dev, | 2147 | static int bcm_sysport_map_queues(struct notifier_block *nb, |
| 2148 | struct dsa_notifier_register_info *info) | 2148 | struct dsa_notifier_register_info *info) |
| 2149 | { | 2149 | { |
| 2150 | struct bcm_sysport_priv *priv = netdev_priv(dev); | ||
| 2151 | struct bcm_sysport_tx_ring *ring; | 2150 | struct bcm_sysport_tx_ring *ring; |
| 2151 | struct bcm_sysport_priv *priv; | ||
| 2152 | struct net_device *slave_dev; | 2152 | struct net_device *slave_dev; |
| 2153 | unsigned int num_tx_queues; | 2153 | unsigned int num_tx_queues; |
| 2154 | unsigned int q, start, port; | 2154 | unsigned int q, start, port; |
| 2155 | struct net_device *dev; | ||
| 2156 | |||
| 2157 | priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier); | ||
| 2158 | if (priv->netdev != info->master) | ||
| 2159 | return 0; | ||
| 2160 | |||
| 2161 | dev = info->master; | ||
| 2155 | 2162 | ||
| 2156 | /* We can't be setting up queue inspection for non directly attached | 2163 | /* We can't be setting up queue inspection for non directly attached |
| 2157 | * switches | 2164 | * switches |
| @@ -2174,11 +2181,12 @@ static int bcm_sysport_map_queues(struct net_device *dev, | |||
| 2174 | if (priv->is_lite) | 2181 | if (priv->is_lite) |
| 2175 | netif_set_real_num_tx_queues(slave_dev, | 2182 | netif_set_real_num_tx_queues(slave_dev, |
| 2176 | slave_dev->num_tx_queues / 2); | 2183 | slave_dev->num_tx_queues / 2); |
| 2184 | |||
| 2177 | num_tx_queues = slave_dev->real_num_tx_queues; | 2185 | num_tx_queues = slave_dev->real_num_tx_queues; |
| 2178 | 2186 | ||
| 2179 | if (priv->per_port_num_tx_queues && | 2187 | if (priv->per_port_num_tx_queues && |
| 2180 | priv->per_port_num_tx_queues != num_tx_queues) | 2188 | priv->per_port_num_tx_queues != num_tx_queues) |
| 2181 | netdev_warn(slave_dev, "asymetric number of per-port queues\n"); | 2189 | netdev_warn(slave_dev, "asymmetric number of per-port queues\n"); |
| 2182 | 2190 | ||
| 2183 | priv->per_port_num_tx_queues = num_tx_queues; | 2191 | priv->per_port_num_tx_queues = num_tx_queues; |
| 2184 | 2192 | ||
| @@ -2201,7 +2209,7 @@ static int bcm_sysport_map_queues(struct net_device *dev, | |||
| 2201 | return 0; | 2209 | return 0; |
| 2202 | } | 2210 | } |
| 2203 | 2211 | ||
| 2204 | static int bcm_sysport_dsa_notifier(struct notifier_block *unused, | 2212 | static int bcm_sysport_dsa_notifier(struct notifier_block *nb, |
| 2205 | unsigned long event, void *ptr) | 2213 | unsigned long event, void *ptr) |
| 2206 | { | 2214 | { |
| 2207 | struct dsa_notifier_register_info *info; | 2215 | struct dsa_notifier_register_info *info; |
| @@ -2211,7 +2219,7 @@ static int bcm_sysport_dsa_notifier(struct notifier_block *unused, | |||
| 2211 | 2219 | ||
| 2212 | info = ptr; | 2220 | info = ptr; |
| 2213 | 2221 | ||
| 2214 | return notifier_from_errno(bcm_sysport_map_queues(info->master, info)); | 2222 | return notifier_from_errno(bcm_sysport_map_queues(nb, info)); |
| 2215 | } | 2223 | } |
| 2216 | 2224 | ||
| 2217 | #define REV_FMT "v%2x.%02x" | 2225 | #define REV_FMT "v%2x.%02x" |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 08bbb639be1a..9f59b1270a7c 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -8733,14 +8733,15 @@ static void tg3_free_consistent(struct tg3 *tp) | |||
| 8733 | tg3_mem_rx_release(tp); | 8733 | tg3_mem_rx_release(tp); |
| 8734 | tg3_mem_tx_release(tp); | 8734 | tg3_mem_tx_release(tp); |
| 8735 | 8735 | ||
| 8736 | /* Protect tg3_get_stats64() from reading freed tp->hw_stats. */ | 8736 | /* tp->hw_stats can be referenced safely: |
| 8737 | tg3_full_lock(tp, 0); | 8737 | * 1. under rtnl_lock |
| 8738 | * 2. or under tp->lock if TG3_FLAG_INIT_COMPLETE is set. | ||
| 8739 | */ | ||
| 8738 | if (tp->hw_stats) { | 8740 | if (tp->hw_stats) { |
| 8739 | dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), | 8741 | dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), |
| 8740 | tp->hw_stats, tp->stats_mapping); | 8742 | tp->hw_stats, tp->stats_mapping); |
| 8741 | tp->hw_stats = NULL; | 8743 | tp->hw_stats = NULL; |
| 8742 | } | 8744 | } |
| 8743 | tg3_full_unlock(tp); | ||
| 8744 | } | 8745 | } |
| 8745 | 8746 | ||
| 8746 | /* | 8747 | /* |
| @@ -14178,7 +14179,7 @@ static void tg3_get_stats64(struct net_device *dev, | |||
| 14178 | struct tg3 *tp = netdev_priv(dev); | 14179 | struct tg3 *tp = netdev_priv(dev); |
| 14179 | 14180 | ||
| 14180 | spin_lock_bh(&tp->lock); | 14181 | spin_lock_bh(&tp->lock); |
| 14181 | if (!tp->hw_stats) { | 14182 | if (!tp->hw_stats || !tg3_flag(tp, INIT_COMPLETE)) { |
| 14182 | *stats = tp->net_stats_prev; | 14183 | *stats = tp->net_stats_prev; |
| 14183 | spin_unlock_bh(&tp->lock); | 14184 | spin_unlock_bh(&tp->lock); |
| 14184 | return; | 14185 | return; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 24d2865b8806..005283c7cdfe 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
| @@ -3433,8 +3433,8 @@ static int adap_config_hma(struct adapter *adapter) | |||
| 3433 | sgl = adapter->hma.sgt->sgl; | 3433 | sgl = adapter->hma.sgt->sgl; |
| 3434 | node = dev_to_node(adapter->pdev_dev); | 3434 | node = dev_to_node(adapter->pdev_dev); |
| 3435 | for_each_sg(sgl, iter, sgt->orig_nents, i) { | 3435 | for_each_sg(sgl, iter, sgt->orig_nents, i) { |
| 3436 | newpage = alloc_pages_node(node, __GFP_NOWARN | GFP_KERNEL, | 3436 | newpage = alloc_pages_node(node, __GFP_NOWARN | GFP_KERNEL | |
| 3437 | page_order); | 3437 | __GFP_ZERO, page_order); |
| 3438 | if (!newpage) { | 3438 | if (!newpage) { |
| 3439 | dev_err(adapter->pdev_dev, | 3439 | dev_err(adapter->pdev_dev, |
| 3440 | "Not enough memory for HMA page allocation\n"); | 3440 | "Not enough memory for HMA page allocation\n"); |
| @@ -5474,6 +5474,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 5474 | } | 5474 | } |
| 5475 | spin_lock_init(&adapter->mbox_lock); | 5475 | spin_lock_init(&adapter->mbox_lock); |
| 5476 | INIT_LIST_HEAD(&adapter->mlist.list); | 5476 | INIT_LIST_HEAD(&adapter->mlist.list); |
| 5477 | adapter->mbox_log->size = T4_OS_LOG_MBOX_CMDS; | ||
| 5477 | pci_set_drvdata(pdev, adapter); | 5478 | pci_set_drvdata(pdev, adapter); |
| 5478 | 5479 | ||
| 5479 | if (func != ent->driver_data) { | 5480 | if (func != ent->driver_data) { |
| @@ -5508,8 +5509,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 5508 | goto out_free_adapter; | 5509 | goto out_free_adapter; |
| 5509 | } | 5510 | } |
| 5510 | 5511 | ||
| 5511 | adapter->mbox_log->size = T4_OS_LOG_MBOX_CMDS; | ||
| 5512 | |||
| 5513 | /* PCI device has been enabled */ | 5512 | /* PCI device has been enabled */ |
| 5514 | adapter->flags |= DEV_ENABLED; | 5513 | adapter->flags |= DEV_ENABLED; |
| 5515 | memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); | 5514 | memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); |
diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c index 4df282ed22c7..0beee2cc2ddd 100644 --- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c +++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c | |||
| @@ -61,7 +61,7 @@ static const char hw_stat_gstrings[][ETH_GSTRING_LEN] = { | |||
| 61 | static const char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = { | 61 | static const char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = { |
| 62 | "tx-single-collision", | 62 | "tx-single-collision", |
| 63 | "tx-multiple-collision", | 63 | "tx-multiple-collision", |
| 64 | "tx-late-collsion", | 64 | "tx-late-collision", |
| 65 | "tx-aborted-frames", | 65 | "tx-aborted-frames", |
| 66 | "tx-lost-frames", | 66 | "tx-lost-frames", |
| 67 | "tx-carrier-sense-errors", | 67 | "tx-carrier-sense-errors", |
diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c index 5909a4407e38..7c511f144ed6 100644 --- a/drivers/net/ethernet/intel/ice/ice_controlq.c +++ b/drivers/net/ethernet/intel/ice/ice_controlq.c | |||
| @@ -1014,10 +1014,10 @@ ice_clean_rq_elem(struct ice_hw *hw, struct ice_ctl_q_info *cq, | |||
| 1014 | desc = ICE_CTL_Q_DESC(cq->rq, ntc); | 1014 | desc = ICE_CTL_Q_DESC(cq->rq, ntc); |
| 1015 | desc_idx = ntc; | 1015 | desc_idx = ntc; |
| 1016 | 1016 | ||
| 1017 | cq->rq_last_status = (enum ice_aq_err)le16_to_cpu(desc->retval); | ||
| 1017 | flags = le16_to_cpu(desc->flags); | 1018 | flags = le16_to_cpu(desc->flags); |
| 1018 | if (flags & ICE_AQ_FLAG_ERR) { | 1019 | if (flags & ICE_AQ_FLAG_ERR) { |
| 1019 | ret_code = ICE_ERR_AQ_ERROR; | 1020 | ret_code = ICE_ERR_AQ_ERROR; |
| 1020 | cq->rq_last_status = (enum ice_aq_err)le16_to_cpu(desc->retval); | ||
| 1021 | ice_debug(hw, ICE_DBG_AQ_MSG, | 1021 | ice_debug(hw, ICE_DBG_AQ_MSG, |
| 1022 | "Control Receive Queue Event received with error 0x%x\n", | 1022 | "Control Receive Queue Event received with error 0x%x\n", |
| 1023 | cq->rq_last_status); | 1023 | cq->rq_last_status); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c index 68af127987bc..cead23e3db0c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | |||
| @@ -943,8 +943,8 @@ err2: | |||
| 943 | kfree(ipsec->ip_tbl); | 943 | kfree(ipsec->ip_tbl); |
| 944 | kfree(ipsec->rx_tbl); | 944 | kfree(ipsec->rx_tbl); |
| 945 | kfree(ipsec->tx_tbl); | 945 | kfree(ipsec->tx_tbl); |
| 946 | kfree(ipsec); | ||
| 946 | err1: | 947 | err1: |
| 947 | kfree(adapter->ipsec); | ||
| 948 | netdev_err(adapter->netdev, "Unable to allocate memory for SA tables"); | 948 | netdev_err(adapter->netdev, "Unable to allocate memory for SA tables"); |
| 949 | } | 949 | } |
| 950 | 950 | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c index 3123267dfba9..9592f3e3e42e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | |||
| @@ -3427,6 +3427,9 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) | |||
| 3427 | hw->phy.sfp_setup_needed = false; | 3427 | hw->phy.sfp_setup_needed = false; |
| 3428 | } | 3428 | } |
| 3429 | 3429 | ||
| 3430 | if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) | ||
| 3431 | return status; | ||
| 3432 | |||
| 3430 | /* Reset PHY */ | 3433 | /* Reset PHY */ |
| 3431 | if (!hw->phy.reset_disable && hw->phy.ops.reset) | 3434 | if (!hw->phy.reset_disable && hw->phy.ops.reset) |
| 3432 | hw->phy.ops.reset(hw); | 3435 | hw->phy.ops.reset(hw); |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index e3d04f226d57..850f8af95e49 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
| @@ -4137,7 +4137,7 @@ out_drop: | |||
| 4137 | return NETDEV_TX_OK; | 4137 | return NETDEV_TX_OK; |
| 4138 | } | 4138 | } |
| 4139 | 4139 | ||
| 4140 | static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | 4140 | static netdev_tx_t ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
| 4141 | { | 4141 | { |
| 4142 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 4142 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
| 4143 | struct ixgbevf_ring *tx_ring; | 4143 | struct ixgbevf_ring *tx_ring; |
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 4202f9b5b966..6f410235987c 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c | |||
| @@ -942,6 +942,7 @@ struct mvpp2 { | |||
| 942 | struct clk *pp_clk; | 942 | struct clk *pp_clk; |
| 943 | struct clk *gop_clk; | 943 | struct clk *gop_clk; |
| 944 | struct clk *mg_clk; | 944 | struct clk *mg_clk; |
| 945 | struct clk *mg_core_clk; | ||
| 945 | struct clk *axi_clk; | 946 | struct clk *axi_clk; |
| 946 | 947 | ||
| 947 | /* List of pointers to port structures */ | 948 | /* List of pointers to port structures */ |
| @@ -8768,18 +8769,27 @@ static int mvpp2_probe(struct platform_device *pdev) | |||
| 8768 | err = clk_prepare_enable(priv->mg_clk); | 8769 | err = clk_prepare_enable(priv->mg_clk); |
| 8769 | if (err < 0) | 8770 | if (err < 0) |
| 8770 | goto err_gop_clk; | 8771 | goto err_gop_clk; |
| 8772 | |||
| 8773 | priv->mg_core_clk = devm_clk_get(&pdev->dev, "mg_core_clk"); | ||
| 8774 | if (IS_ERR(priv->mg_core_clk)) { | ||
| 8775 | priv->mg_core_clk = NULL; | ||
| 8776 | } else { | ||
| 8777 | err = clk_prepare_enable(priv->mg_core_clk); | ||
| 8778 | if (err < 0) | ||
| 8779 | goto err_mg_clk; | ||
| 8780 | } | ||
| 8771 | } | 8781 | } |
| 8772 | 8782 | ||
| 8773 | priv->axi_clk = devm_clk_get(&pdev->dev, "axi_clk"); | 8783 | priv->axi_clk = devm_clk_get(&pdev->dev, "axi_clk"); |
| 8774 | if (IS_ERR(priv->axi_clk)) { | 8784 | if (IS_ERR(priv->axi_clk)) { |
| 8775 | err = PTR_ERR(priv->axi_clk); | 8785 | err = PTR_ERR(priv->axi_clk); |
| 8776 | if (err == -EPROBE_DEFER) | 8786 | if (err == -EPROBE_DEFER) |
| 8777 | goto err_gop_clk; | 8787 | goto err_mg_core_clk; |
| 8778 | priv->axi_clk = NULL; | 8788 | priv->axi_clk = NULL; |
| 8779 | } else { | 8789 | } else { |
| 8780 | err = clk_prepare_enable(priv->axi_clk); | 8790 | err = clk_prepare_enable(priv->axi_clk); |
| 8781 | if (err < 0) | 8791 | if (err < 0) |
| 8782 | goto err_gop_clk; | 8792 | goto err_mg_core_clk; |
| 8783 | } | 8793 | } |
| 8784 | 8794 | ||
| 8785 | /* Get system's tclk rate */ | 8795 | /* Get system's tclk rate */ |
| @@ -8793,7 +8803,7 @@ static int mvpp2_probe(struct platform_device *pdev) | |||
| 8793 | if (priv->hw_version == MVPP22) { | 8803 | if (priv->hw_version == MVPP22) { |
| 8794 | err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK); | 8804 | err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK); |
| 8795 | if (err) | 8805 | if (err) |
| 8796 | goto err_mg_clk; | 8806 | goto err_axi_clk; |
| 8797 | /* Sadly, the BM pools all share the same register to | 8807 | /* Sadly, the BM pools all share the same register to |
| 8798 | * store the high 32 bits of their address. So they | 8808 | * store the high 32 bits of their address. So they |
| 8799 | * must all have the same high 32 bits, which forces | 8809 | * must all have the same high 32 bits, which forces |
| @@ -8801,14 +8811,14 @@ static int mvpp2_probe(struct platform_device *pdev) | |||
| 8801 | */ | 8811 | */ |
| 8802 | err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); | 8812 | err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); |
| 8803 | if (err) | 8813 | if (err) |
| 8804 | goto err_mg_clk; | 8814 | goto err_axi_clk; |
| 8805 | } | 8815 | } |
| 8806 | 8816 | ||
| 8807 | /* Initialize network controller */ | 8817 | /* Initialize network controller */ |
| 8808 | err = mvpp2_init(pdev, priv); | 8818 | err = mvpp2_init(pdev, priv); |
| 8809 | if (err < 0) { | 8819 | if (err < 0) { |
| 8810 | dev_err(&pdev->dev, "failed to initialize controller\n"); | 8820 | dev_err(&pdev->dev, "failed to initialize controller\n"); |
| 8811 | goto err_mg_clk; | 8821 | goto err_axi_clk; |
| 8812 | } | 8822 | } |
| 8813 | 8823 | ||
| 8814 | /* Initialize ports */ | 8824 | /* Initialize ports */ |
| @@ -8821,7 +8831,7 @@ static int mvpp2_probe(struct platform_device *pdev) | |||
| 8821 | if (priv->port_count == 0) { | 8831 | if (priv->port_count == 0) { |
| 8822 | dev_err(&pdev->dev, "no ports enabled\n"); | 8832 | dev_err(&pdev->dev, "no ports enabled\n"); |
| 8823 | err = -ENODEV; | 8833 | err = -ENODEV; |
| 8824 | goto err_mg_clk; | 8834 | goto err_axi_clk; |
| 8825 | } | 8835 | } |
| 8826 | 8836 | ||
| 8827 | /* Statistics must be gathered regularly because some of them (like | 8837 | /* Statistics must be gathered regularly because some of them (like |
| @@ -8849,8 +8859,13 @@ err_port_probe: | |||
| 8849 | mvpp2_port_remove(priv->port_list[i]); | 8859 | mvpp2_port_remove(priv->port_list[i]); |
| 8850 | i++; | 8860 | i++; |
| 8851 | } | 8861 | } |
| 8852 | err_mg_clk: | 8862 | err_axi_clk: |
| 8853 | clk_disable_unprepare(priv->axi_clk); | 8863 | clk_disable_unprepare(priv->axi_clk); |
| 8864 | |||
| 8865 | err_mg_core_clk: | ||
| 8866 | if (priv->hw_version == MVPP22) | ||
| 8867 | clk_disable_unprepare(priv->mg_core_clk); | ||
| 8868 | err_mg_clk: | ||
| 8854 | if (priv->hw_version == MVPP22) | 8869 | if (priv->hw_version == MVPP22) |
| 8855 | clk_disable_unprepare(priv->mg_clk); | 8870 | clk_disable_unprepare(priv->mg_clk); |
| 8856 | err_gop_clk: | 8871 | err_gop_clk: |
| @@ -8897,6 +8912,7 @@ static int mvpp2_remove(struct platform_device *pdev) | |||
| 8897 | return 0; | 8912 | return 0; |
| 8898 | 8913 | ||
| 8899 | clk_disable_unprepare(priv->axi_clk); | 8914 | clk_disable_unprepare(priv->axi_clk); |
| 8915 | clk_disable_unprepare(priv->mg_core_clk); | ||
| 8900 | clk_disable_unprepare(priv->mg_clk); | 8916 | clk_disable_unprepare(priv->mg_clk); |
| 8901 | clk_disable_unprepare(priv->pp_clk); | 8917 | clk_disable_unprepare(priv->pp_clk); |
| 8902 | clk_disable_unprepare(priv->gop_clk); | 8918 | clk_disable_unprepare(priv->gop_clk); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index a30a2e95d13f..f11b45001cad 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
| @@ -1027,6 +1027,22 @@ static int mlx4_en_set_coalesce(struct net_device *dev, | |||
| 1027 | if (!coal->tx_max_coalesced_frames_irq) | 1027 | if (!coal->tx_max_coalesced_frames_irq) |
| 1028 | return -EINVAL; | 1028 | return -EINVAL; |
| 1029 | 1029 | ||
| 1030 | if (coal->tx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME || | ||
| 1031 | coal->rx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME || | ||
| 1032 | coal->rx_coalesce_usecs_low > MLX4_EN_MAX_COAL_TIME || | ||
| 1033 | coal->rx_coalesce_usecs_high > MLX4_EN_MAX_COAL_TIME) { | ||
| 1034 | netdev_info(dev, "%s: maximum coalesce time supported is %d usecs\n", | ||
| 1035 | __func__, MLX4_EN_MAX_COAL_TIME); | ||
| 1036 | return -ERANGE; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | if (coal->tx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS || | ||
| 1040 | coal->rx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS) { | ||
| 1041 | netdev_info(dev, "%s: maximum coalesced frames supported is %d\n", | ||
| 1042 | __func__, MLX4_EN_MAX_COAL_PKTS); | ||
| 1043 | return -ERANGE; | ||
| 1044 | } | ||
| 1045 | |||
| 1030 | priv->rx_frames = (coal->rx_max_coalesced_frames == | 1046 | priv->rx_frames = (coal->rx_max_coalesced_frames == |
| 1031 | MLX4_EN_AUTO_CONF) ? | 1047 | MLX4_EN_AUTO_CONF) ? |
| 1032 | MLX4_EN_RX_COAL_TARGET : | 1048 | MLX4_EN_RX_COAL_TARGET : |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index e0adac4a9a19..9670b33fc9b1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
| @@ -3324,12 +3324,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
| 3324 | MAX_TX_RINGS, GFP_KERNEL); | 3324 | MAX_TX_RINGS, GFP_KERNEL); |
| 3325 | if (!priv->tx_ring[t]) { | 3325 | if (!priv->tx_ring[t]) { |
| 3326 | err = -ENOMEM; | 3326 | err = -ENOMEM; |
| 3327 | goto err_free_tx; | 3327 | goto out; |
| 3328 | } | 3328 | } |
| 3329 | priv->tx_cq[t] = kzalloc(sizeof(struct mlx4_en_cq *) * | 3329 | priv->tx_cq[t] = kzalloc(sizeof(struct mlx4_en_cq *) * |
| 3330 | MAX_TX_RINGS, GFP_KERNEL); | 3330 | MAX_TX_RINGS, GFP_KERNEL); |
| 3331 | if (!priv->tx_cq[t]) { | 3331 | if (!priv->tx_cq[t]) { |
| 3332 | kfree(priv->tx_ring[t]); | ||
| 3333 | err = -ENOMEM; | 3332 | err = -ENOMEM; |
| 3334 | goto out; | 3333 | goto out; |
| 3335 | } | 3334 | } |
| @@ -3582,11 +3581,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
| 3582 | 3581 | ||
| 3583 | return 0; | 3582 | return 0; |
| 3584 | 3583 | ||
| 3585 | err_free_tx: | ||
| 3586 | while (t--) { | ||
| 3587 | kfree(priv->tx_ring[t]); | ||
| 3588 | kfree(priv->tx_cq[t]); | ||
| 3589 | } | ||
| 3590 | out: | 3584 | out: |
| 3591 | mlx4_en_destroy_netdev(dev); | 3585 | mlx4_en_destroy_netdev(dev); |
| 3592 | return err; | 3586 | return err; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index bfef69235d71..211578ffc70d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -1317,7 +1317,7 @@ static int mlx4_mf_unbond(struct mlx4_dev *dev) | |||
| 1317 | 1317 | ||
| 1318 | ret = mlx4_unbond_fs_rules(dev); | 1318 | ret = mlx4_unbond_fs_rules(dev); |
| 1319 | if (ret) | 1319 | if (ret) |
| 1320 | mlx4_warn(dev, "multifunction unbond for flow rules failedi (%d)\n", ret); | 1320 | mlx4_warn(dev, "multifunction unbond for flow rules failed (%d)\n", ret); |
| 1321 | ret1 = mlx4_unbond_mac_table(dev); | 1321 | ret1 = mlx4_unbond_mac_table(dev); |
| 1322 | if (ret1) { | 1322 | if (ret1) { |
| 1323 | mlx4_warn(dev, "multifunction unbond for MAC table failed (%d)\n", ret1); | 1323 | mlx4_warn(dev, "multifunction unbond for MAC table failed (%d)\n", ret1); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index f7c81133594f..ace6545f82e6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
| @@ -132,6 +132,9 @@ | |||
| 132 | #define MLX4_EN_TX_COAL_PKTS 16 | 132 | #define MLX4_EN_TX_COAL_PKTS 16 |
| 133 | #define MLX4_EN_TX_COAL_TIME 0x10 | 133 | #define MLX4_EN_TX_COAL_TIME 0x10 |
| 134 | 134 | ||
| 135 | #define MLX4_EN_MAX_COAL_PKTS U16_MAX | ||
| 136 | #define MLX4_EN_MAX_COAL_TIME U16_MAX | ||
| 137 | |||
| 135 | #define MLX4_EN_RX_RATE_LOW 400000 | 138 | #define MLX4_EN_RX_RATE_LOW 400000 |
| 136 | #define MLX4_EN_RX_COAL_TIME_LOW 0 | 139 | #define MLX4_EN_RX_COAL_TIME_LOW 0 |
| 137 | #define MLX4_EN_RX_RATE_HIGH 450000 | 140 | #define MLX4_EN_RX_RATE_HIGH 450000 |
| @@ -552,8 +555,8 @@ struct mlx4_en_priv { | |||
| 552 | u16 rx_usecs_low; | 555 | u16 rx_usecs_low; |
| 553 | u32 pkt_rate_high; | 556 | u32 pkt_rate_high; |
| 554 | u16 rx_usecs_high; | 557 | u16 rx_usecs_high; |
| 555 | u16 sample_interval; | 558 | u32 sample_interval; |
| 556 | u16 adaptive_rx_coal; | 559 | u32 adaptive_rx_coal; |
| 557 | u32 msg_enable; | 560 | u32 msg_enable; |
| 558 | u32 loopback_ok; | 561 | u32 loopback_ok; |
| 559 | u32 validate_loopback; | 562 | u32 validate_loopback; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index 3d46ef48d5b8..c641d5656b2d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | |||
| @@ -1007,12 +1007,14 @@ static void mlx5e_trust_update_sq_inline_mode(struct mlx5e_priv *priv) | |||
| 1007 | 1007 | ||
| 1008 | mutex_lock(&priv->state_lock); | 1008 | mutex_lock(&priv->state_lock); |
| 1009 | 1009 | ||
| 1010 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) | ||
| 1011 | goto out; | ||
| 1012 | |||
| 1013 | new_channels.params = priv->channels.params; | 1010 | new_channels.params = priv->channels.params; |
| 1014 | mlx5e_trust_update_tx_min_inline_mode(priv, &new_channels.params); | 1011 | mlx5e_trust_update_tx_min_inline_mode(priv, &new_channels.params); |
| 1015 | 1012 | ||
| 1013 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { | ||
| 1014 | priv->channels.params = new_channels.params; | ||
| 1015 | goto out; | ||
| 1016 | } | ||
| 1017 | |||
| 1016 | /* Skip if tx_min_inline is the same */ | 1018 | /* Skip if tx_min_inline is the same */ |
| 1017 | if (new_channels.params.tx_min_inline_mode == | 1019 | if (new_channels.params.tx_min_inline_mode == |
| 1018 | priv->channels.params.tx_min_inline_mode) | 1020 | priv->channels.params.tx_min_inline_mode) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index d8f68e4d1018..876c3e4c6193 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | |||
| @@ -877,13 +877,14 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = { | |||
| 877 | }; | 877 | }; |
| 878 | 878 | ||
| 879 | static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev, | 879 | static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev, |
| 880 | struct mlx5e_params *params) | 880 | struct mlx5e_params *params, u16 mtu) |
| 881 | { | 881 | { |
| 882 | u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ? | 882 | u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ? |
| 883 | MLX5_CQ_PERIOD_MODE_START_FROM_CQE : | 883 | MLX5_CQ_PERIOD_MODE_START_FROM_CQE : |
| 884 | MLX5_CQ_PERIOD_MODE_START_FROM_EQE; | 884 | MLX5_CQ_PERIOD_MODE_START_FROM_EQE; |
| 885 | 885 | ||
| 886 | params->hard_mtu = MLX5E_ETH_HARD_MTU; | 886 | params->hard_mtu = MLX5E_ETH_HARD_MTU; |
| 887 | params->sw_mtu = mtu; | ||
| 887 | params->log_sq_size = MLX5E_REP_PARAMS_LOG_SQ_SIZE; | 888 | params->log_sq_size = MLX5E_REP_PARAMS_LOG_SQ_SIZE; |
| 888 | params->rq_wq_type = MLX5_WQ_TYPE_LINKED_LIST; | 889 | params->rq_wq_type = MLX5_WQ_TYPE_LINKED_LIST; |
| 889 | params->log_rq_mtu_frames = MLX5E_REP_PARAMS_LOG_RQ_SIZE; | 890 | params->log_rq_mtu_frames = MLX5E_REP_PARAMS_LOG_RQ_SIZE; |
| @@ -931,7 +932,7 @@ static void mlx5e_init_rep(struct mlx5_core_dev *mdev, | |||
| 931 | 932 | ||
| 932 | priv->channels.params.num_channels = profile->max_nch(mdev); | 933 | priv->channels.params.num_channels = profile->max_nch(mdev); |
| 933 | 934 | ||
| 934 | mlx5e_build_rep_params(mdev, &priv->channels.params); | 935 | mlx5e_build_rep_params(mdev, &priv->channels.params, netdev->mtu); |
| 935 | mlx5e_build_rep_netdev(netdev); | 936 | mlx5e_build_rep_netdev(netdev); |
| 936 | 937 | ||
| 937 | mlx5e_timestamp_init(priv); | 938 | mlx5e_timestamp_init(priv); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c index 707976482c09..027f54ac1ca2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c | |||
| @@ -290,7 +290,7 @@ static int mlx5e_test_loopback(struct mlx5e_priv *priv) | |||
| 290 | 290 | ||
| 291 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { | 291 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 292 | netdev_err(priv->netdev, | 292 | netdev_err(priv->netdev, |
| 293 | "\tCan't perform loobpack test while device is down\n"); | 293 | "\tCan't perform loopback test while device is down\n"); |
| 294 | return -ENODEV; | 294 | return -ENODEV; |
| 295 | } | 295 | } |
| 296 | 296 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 4197001f9801..b94276db3ce9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | |||
| @@ -1261,6 +1261,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
| 1261 | f->mask); | 1261 | f->mask); |
| 1262 | addr_type = key->addr_type; | 1262 | addr_type = key->addr_type; |
| 1263 | 1263 | ||
| 1264 | /* the HW doesn't support frag first/later */ | ||
| 1265 | if (mask->flags & FLOW_DIS_FIRST_FRAG) | ||
| 1266 | return -EOPNOTSUPP; | ||
| 1267 | |||
| 1264 | if (mask->flags & FLOW_DIS_IS_FRAGMENT) { | 1268 | if (mask->flags & FLOW_DIS_IS_FRAGMENT) { |
| 1265 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, frag, 1); | 1269 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, frag, 1); |
| 1266 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, frag, | 1270 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, frag, |
| @@ -1864,7 +1868,8 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec, | |||
| 1864 | } | 1868 | } |
| 1865 | 1869 | ||
| 1866 | ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); | 1870 | ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); |
| 1867 | if (modify_ip_header && ip_proto != IPPROTO_TCP && ip_proto != IPPROTO_UDP) { | 1871 | if (modify_ip_header && ip_proto != IPPROTO_TCP && |
| 1872 | ip_proto != IPPROTO_UDP && ip_proto != IPPROTO_ICMP) { | ||
| 1868 | pr_info("can't offload re-write of ip proto %d\n", ip_proto); | 1873 | pr_info("can't offload re-write of ip proto %d\n", ip_proto); |
| 1869 | return false; | 1874 | return false; |
| 1870 | } | 1875 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index 20297108528a..5532aa3675c7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | |||
| @@ -255,7 +255,7 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb, | |||
| 255 | dma_addr = dma_map_single(sq->pdev, skb_data, headlen, | 255 | dma_addr = dma_map_single(sq->pdev, skb_data, headlen, |
| 256 | DMA_TO_DEVICE); | 256 | DMA_TO_DEVICE); |
| 257 | if (unlikely(dma_mapping_error(sq->pdev, dma_addr))) | 257 | if (unlikely(dma_mapping_error(sq->pdev, dma_addr))) |
| 258 | return -ENOMEM; | 258 | goto dma_unmap_wqe_err; |
| 259 | 259 | ||
| 260 | dseg->addr = cpu_to_be64(dma_addr); | 260 | dseg->addr = cpu_to_be64(dma_addr); |
| 261 | dseg->lkey = sq->mkey_be; | 261 | dseg->lkey = sq->mkey_be; |
| @@ -273,7 +273,7 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb, | |||
| 273 | dma_addr = skb_frag_dma_map(sq->pdev, frag, 0, fsz, | 273 | dma_addr = skb_frag_dma_map(sq->pdev, frag, 0, fsz, |
| 274 | DMA_TO_DEVICE); | 274 | DMA_TO_DEVICE); |
| 275 | if (unlikely(dma_mapping_error(sq->pdev, dma_addr))) | 275 | if (unlikely(dma_mapping_error(sq->pdev, dma_addr))) |
| 276 | return -ENOMEM; | 276 | goto dma_unmap_wqe_err; |
| 277 | 277 | ||
| 278 | dseg->addr = cpu_to_be64(dma_addr); | 278 | dseg->addr = cpu_to_be64(dma_addr); |
| 279 | dseg->lkey = sq->mkey_be; | 279 | dseg->lkey = sq->mkey_be; |
| @@ -285,6 +285,10 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb, | |||
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | return num_dma; | 287 | return num_dma; |
| 288 | |||
| 289 | dma_unmap_wqe_err: | ||
| 290 | mlx5e_dma_unmap_wqe_err(sq, num_dma); | ||
| 291 | return -ENOMEM; | ||
| 288 | } | 292 | } |
| 289 | 293 | ||
| 290 | static inline void | 294 | static inline void |
| @@ -380,17 +384,15 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, | |||
| 380 | num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen, | 384 | num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen, |
| 381 | (struct mlx5_wqe_data_seg *)cseg + ds_cnt); | 385 | (struct mlx5_wqe_data_seg *)cseg + ds_cnt); |
| 382 | if (unlikely(num_dma < 0)) | 386 | if (unlikely(num_dma < 0)) |
| 383 | goto dma_unmap_wqe_err; | 387 | goto err_drop; |
| 384 | 388 | ||
| 385 | mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt + num_dma, | 389 | mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt + num_dma, |
| 386 | num_bytes, num_dma, wi, cseg); | 390 | num_bytes, num_dma, wi, cseg); |
| 387 | 391 | ||
| 388 | return NETDEV_TX_OK; | 392 | return NETDEV_TX_OK; |
| 389 | 393 | ||
| 390 | dma_unmap_wqe_err: | 394 | err_drop: |
| 391 | sq->stats.dropped++; | 395 | sq->stats.dropped++; |
| 392 | mlx5e_dma_unmap_wqe_err(sq, wi->num_dma); | ||
| 393 | |||
| 394 | dev_kfree_skb_any(skb); | 396 | dev_kfree_skb_any(skb); |
| 395 | 397 | ||
| 396 | return NETDEV_TX_OK; | 398 | return NETDEV_TX_OK; |
| @@ -645,17 +647,15 @@ netdev_tx_t mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, | |||
| 645 | num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen, | 647 | num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen, |
| 646 | (struct mlx5_wqe_data_seg *)cseg + ds_cnt); | 648 | (struct mlx5_wqe_data_seg *)cseg + ds_cnt); |
| 647 | if (unlikely(num_dma < 0)) | 649 | if (unlikely(num_dma < 0)) |
| 648 | goto dma_unmap_wqe_err; | 650 | goto err_drop; |
| 649 | 651 | ||
| 650 | mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt + num_dma, | 652 | mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt + num_dma, |
| 651 | num_bytes, num_dma, wi, cseg); | 653 | num_bytes, num_dma, wi, cseg); |
| 652 | 654 | ||
| 653 | return NETDEV_TX_OK; | 655 | return NETDEV_TX_OK; |
| 654 | 656 | ||
| 655 | dma_unmap_wqe_err: | 657 | err_drop: |
| 656 | sq->stats.dropped++; | 658 | sq->stats.dropped++; |
| 657 | mlx5e_dma_unmap_wqe_err(sq, wi->num_dma); | ||
| 658 | |||
| 659 | dev_kfree_skb_any(skb); | 659 | dev_kfree_skb_any(skb); |
| 660 | 660 | ||
| 661 | return NETDEV_TX_OK; | 661 | return NETDEV_TX_OK; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index c1c94974e16b..1814f803bd2c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c | |||
| @@ -34,6 +34,9 @@ | |||
| 34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
| 35 | #include <linux/mlx5/driver.h> | 35 | #include <linux/mlx5/driver.h> |
| 36 | #include <linux/mlx5/cmd.h> | 36 | #include <linux/mlx5/cmd.h> |
| 37 | #ifdef CONFIG_RFS_ACCEL | ||
| 38 | #include <linux/cpu_rmap.h> | ||
| 39 | #endif | ||
| 37 | #include "mlx5_core.h" | 40 | #include "mlx5_core.h" |
| 38 | #include "fpga/core.h" | 41 | #include "fpga/core.h" |
| 39 | #include "eswitch.h" | 42 | #include "eswitch.h" |
| @@ -923,3 +926,28 @@ int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, | |||
| 923 | MLX5_SET(query_eq_in, in, eq_number, eq->eqn); | 926 | MLX5_SET(query_eq_in, in, eq_number, eq->eqn); |
| 924 | return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); | 927 | return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); |
| 925 | } | 928 | } |
| 929 | |||
| 930 | /* This function should only be called after mlx5_cmd_force_teardown_hca */ | ||
| 931 | void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev) | ||
| 932 | { | ||
| 933 | struct mlx5_eq_table *table = &dev->priv.eq_table; | ||
| 934 | struct mlx5_eq *eq; | ||
| 935 | |||
| 936 | #ifdef CONFIG_RFS_ACCEL | ||
| 937 | if (dev->rmap) { | ||
| 938 | free_irq_cpu_rmap(dev->rmap); | ||
| 939 | dev->rmap = NULL; | ||
| 940 | } | ||
| 941 | #endif | ||
| 942 | list_for_each_entry(eq, &table->comp_eqs_list, list) | ||
| 943 | free_irq(eq->irqn, eq); | ||
| 944 | |||
| 945 | free_irq(table->pages_eq.irqn, &table->pages_eq); | ||
| 946 | free_irq(table->async_eq.irqn, &table->async_eq); | ||
| 947 | free_irq(table->cmd_eq.irqn, &table->cmd_eq); | ||
| 948 | #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING | ||
| 949 | if (MLX5_CAP_GEN(dev, pg)) | ||
| 950 | free_irq(table->pfault_eq.irqn, &table->pfault_eq); | ||
| 951 | #endif | ||
| 952 | pci_free_irq_vectors(dev->pdev); | ||
| 953 | } | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 332bc56306bf..1352d13eedb3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | |||
| @@ -2175,26 +2175,35 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, | |||
| 2175 | memset(vf_stats, 0, sizeof(*vf_stats)); | 2175 | memset(vf_stats, 0, sizeof(*vf_stats)); |
| 2176 | vf_stats->rx_packets = | 2176 | vf_stats->rx_packets = |
| 2177 | MLX5_GET_CTR(out, received_eth_unicast.packets) + | 2177 | MLX5_GET_CTR(out, received_eth_unicast.packets) + |
| 2178 | MLX5_GET_CTR(out, received_ib_unicast.packets) + | ||
| 2178 | MLX5_GET_CTR(out, received_eth_multicast.packets) + | 2179 | MLX5_GET_CTR(out, received_eth_multicast.packets) + |
| 2180 | MLX5_GET_CTR(out, received_ib_multicast.packets) + | ||
| 2179 | MLX5_GET_CTR(out, received_eth_broadcast.packets); | 2181 | MLX5_GET_CTR(out, received_eth_broadcast.packets); |
| 2180 | 2182 | ||
| 2181 | vf_stats->rx_bytes = | 2183 | vf_stats->rx_bytes = |
| 2182 | MLX5_GET_CTR(out, received_eth_unicast.octets) + | 2184 | MLX5_GET_CTR(out, received_eth_unicast.octets) + |
| 2185 | MLX5_GET_CTR(out, received_ib_unicast.octets) + | ||
| 2183 | MLX5_GET_CTR(out, received_eth_multicast.octets) + | 2186 | MLX5_GET_CTR(out, received_eth_multicast.octets) + |
| 2187 | MLX5_GET_CTR(out, received_ib_multicast.octets) + | ||
| 2184 | MLX5_GET_CTR(out, received_eth_broadcast.octets); | 2188 | MLX5_GET_CTR(out, received_eth_broadcast.octets); |
| 2185 | 2189 | ||
| 2186 | vf_stats->tx_packets = | 2190 | vf_stats->tx_packets = |
| 2187 | MLX5_GET_CTR(out, transmitted_eth_unicast.packets) + | 2191 | MLX5_GET_CTR(out, transmitted_eth_unicast.packets) + |
| 2192 | MLX5_GET_CTR(out, transmitted_ib_unicast.packets) + | ||
| 2188 | MLX5_GET_CTR(out, transmitted_eth_multicast.packets) + | 2193 | MLX5_GET_CTR(out, transmitted_eth_multicast.packets) + |
| 2194 | MLX5_GET_CTR(out, transmitted_ib_multicast.packets) + | ||
| 2189 | MLX5_GET_CTR(out, transmitted_eth_broadcast.packets); | 2195 | MLX5_GET_CTR(out, transmitted_eth_broadcast.packets); |
| 2190 | 2196 | ||
| 2191 | vf_stats->tx_bytes = | 2197 | vf_stats->tx_bytes = |
| 2192 | MLX5_GET_CTR(out, transmitted_eth_unicast.octets) + | 2198 | MLX5_GET_CTR(out, transmitted_eth_unicast.octets) + |
| 2199 | MLX5_GET_CTR(out, transmitted_ib_unicast.octets) + | ||
| 2193 | MLX5_GET_CTR(out, transmitted_eth_multicast.octets) + | 2200 | MLX5_GET_CTR(out, transmitted_eth_multicast.octets) + |
| 2201 | MLX5_GET_CTR(out, transmitted_ib_multicast.octets) + | ||
| 2194 | MLX5_GET_CTR(out, transmitted_eth_broadcast.octets); | 2202 | MLX5_GET_CTR(out, transmitted_eth_broadcast.octets); |
| 2195 | 2203 | ||
| 2196 | vf_stats->multicast = | 2204 | vf_stats->multicast = |
| 2197 | MLX5_GET_CTR(out, received_eth_multicast.packets); | 2205 | MLX5_GET_CTR(out, received_eth_multicast.packets) + |
| 2206 | MLX5_GET_CTR(out, received_ib_multicast.packets); | ||
| 2198 | 2207 | ||
| 2199 | vf_stats->broadcast = | 2208 | vf_stats->broadcast = |
| 2200 | MLX5_GET_CTR(out, received_eth_broadcast.packets); | 2209 | MLX5_GET_CTR(out, received_eth_broadcast.packets); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index de51e7c39bc8..c39c1692e674 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | |||
| @@ -187,6 +187,7 @@ static void del_sw_ns(struct fs_node *node); | |||
| 187 | static void del_sw_hw_rule(struct fs_node *node); | 187 | static void del_sw_hw_rule(struct fs_node *node); |
| 188 | static bool mlx5_flow_dests_cmp(struct mlx5_flow_destination *d1, | 188 | static bool mlx5_flow_dests_cmp(struct mlx5_flow_destination *d1, |
| 189 | struct mlx5_flow_destination *d2); | 189 | struct mlx5_flow_destination *d2); |
| 190 | static void cleanup_root_ns(struct mlx5_flow_root_namespace *root_ns); | ||
| 190 | static struct mlx5_flow_rule * | 191 | static struct mlx5_flow_rule * |
| 191 | find_flow_rule(struct fs_fte *fte, | 192 | find_flow_rule(struct fs_fte *fte, |
| 192 | struct mlx5_flow_destination *dest); | 193 | struct mlx5_flow_destination *dest); |
| @@ -481,7 +482,8 @@ static void del_sw_hw_rule(struct fs_node *node) | |||
| 481 | 482 | ||
| 482 | if (rule->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER && | 483 | if (rule->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER && |
| 483 | --fte->dests_size) { | 484 | --fte->dests_size) { |
| 484 | modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION); | 485 | modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION) | |
| 486 | BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_FLOW_COUNTERS); | ||
| 485 | fte->action.action &= ~MLX5_FLOW_CONTEXT_ACTION_COUNT; | 487 | fte->action.action &= ~MLX5_FLOW_CONTEXT_ACTION_COUNT; |
| 486 | update_fte = true; | 488 | update_fte = true; |
| 487 | goto out; | 489 | goto out; |
| @@ -2351,23 +2353,27 @@ static int create_anchor_flow_table(struct mlx5_flow_steering *steering) | |||
| 2351 | 2353 | ||
| 2352 | static int init_root_ns(struct mlx5_flow_steering *steering) | 2354 | static int init_root_ns(struct mlx5_flow_steering *steering) |
| 2353 | { | 2355 | { |
| 2356 | int err; | ||
| 2357 | |||
| 2354 | steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX); | 2358 | steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX); |
| 2355 | if (!steering->root_ns) | 2359 | if (!steering->root_ns) |
| 2356 | goto cleanup; | 2360 | return -ENOMEM; |
| 2357 | 2361 | ||
| 2358 | if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node)) | 2362 | err = init_root_tree(steering, &root_fs, &steering->root_ns->ns.node); |
| 2359 | goto cleanup; | 2363 | if (err) |
| 2364 | goto out_err; | ||
| 2360 | 2365 | ||
| 2361 | set_prio_attrs(steering->root_ns); | 2366 | set_prio_attrs(steering->root_ns); |
| 2362 | 2367 | err = create_anchor_flow_table(steering); | |
| 2363 | if (create_anchor_flow_table(steering)) | 2368 | if (err) |
| 2364 | goto cleanup; | 2369 | goto out_err; |
| 2365 | 2370 | ||
| 2366 | return 0; | 2371 | return 0; |
| 2367 | 2372 | ||
| 2368 | cleanup: | 2373 | out_err: |
| 2369 | mlx5_cleanup_fs(steering->dev); | 2374 | cleanup_root_ns(steering->root_ns); |
| 2370 | return -ENOMEM; | 2375 | steering->root_ns = NULL; |
| 2376 | return err; | ||
| 2371 | } | 2377 | } |
| 2372 | 2378 | ||
| 2373 | static void clean_tree(struct fs_node *node) | 2379 | static void clean_tree(struct fs_node *node) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 63a8ea31601c..e2c465b0b3f8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
| @@ -1587,6 +1587,14 @@ static int mlx5_try_fast_unload(struct mlx5_core_dev *dev) | |||
| 1587 | 1587 | ||
| 1588 | mlx5_enter_error_state(dev, true); | 1588 | mlx5_enter_error_state(dev, true); |
| 1589 | 1589 | ||
| 1590 | /* Some platforms requiring freeing the IRQ's in the shutdown | ||
| 1591 | * flow. If they aren't freed they can't be allocated after | ||
| 1592 | * kexec. There is no need to cleanup the mlx5_core software | ||
| 1593 | * contexts. | ||
| 1594 | */ | ||
| 1595 | mlx5_irq_clear_affinity_hints(dev); | ||
| 1596 | mlx5_core_eq_free_irqs(dev); | ||
| 1597 | |||
| 1590 | return 0; | 1598 | return 0; |
| 1591 | } | 1599 | } |
| 1592 | 1600 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h index 7d001fe6e631..023882d9a22e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h | |||
| @@ -128,6 +128,8 @@ int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, | |||
| 128 | u32 *out, int outlen); | 128 | u32 *out, int outlen); |
| 129 | int mlx5_start_eqs(struct mlx5_core_dev *dev); | 129 | int mlx5_start_eqs(struct mlx5_core_dev *dev); |
| 130 | void mlx5_stop_eqs(struct mlx5_core_dev *dev); | 130 | void mlx5_stop_eqs(struct mlx5_core_dev *dev); |
| 131 | /* This function should only be called after mlx5_cmd_force_teardown_hca */ | ||
| 132 | void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev); | ||
| 131 | struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn); | 133 | struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn); |
| 132 | u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq *eq); | 134 | u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq *eq); |
| 133 | void mlx5_cq_tasklet_cb(unsigned long data); | 135 | void mlx5_cq_tasklet_cb(unsigned long data); |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 93ea56620a24..e13ac3b8dff7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c | |||
| @@ -1100,11 +1100,11 @@ err_emad_init: | |||
| 1100 | err_alloc_lag_mapping: | 1100 | err_alloc_lag_mapping: |
| 1101 | mlxsw_ports_fini(mlxsw_core); | 1101 | mlxsw_ports_fini(mlxsw_core); |
| 1102 | err_ports_init: | 1102 | err_ports_init: |
| 1103 | mlxsw_bus->fini(bus_priv); | ||
| 1104 | err_bus_init: | ||
| 1105 | if (!reload) | 1103 | if (!reload) |
| 1106 | devlink_resources_unregister(devlink, NULL); | 1104 | devlink_resources_unregister(devlink, NULL); |
| 1107 | err_register_resources: | 1105 | err_register_resources: |
| 1106 | mlxsw_bus->fini(bus_priv); | ||
| 1107 | err_bus_init: | ||
| 1108 | if (!reload) | 1108 | if (!reload) |
| 1109 | devlink_free(devlink); | 1109 | devlink_free(devlink); |
| 1110 | err_devlink_alloc: | 1110 | err_devlink_alloc: |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index c11c9a635866..4ed01182a82c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | |||
| @@ -1718,13 +1718,11 @@ __mlxsw_sp_port_mdb_del(struct mlxsw_sp_port *mlxsw_sp_port, | |||
| 1718 | struct net_device *dev = mlxsw_sp_port->dev; | 1718 | struct net_device *dev = mlxsw_sp_port->dev; |
| 1719 | int err; | 1719 | int err; |
| 1720 | 1720 | ||
| 1721 | if (bridge_port->bridge_device->multicast_enabled) { | 1721 | if (bridge_port->bridge_device->multicast_enabled && |
| 1722 | if (bridge_port->bridge_device->multicast_enabled) { | 1722 | !bridge_port->mrouter) { |
| 1723 | err = mlxsw_sp_port_smid_set(mlxsw_sp_port, mid->mid, | 1723 | err = mlxsw_sp_port_smid_set(mlxsw_sp_port, mid->mid, false); |
| 1724 | false); | 1724 | if (err) |
| 1725 | if (err) | 1725 | netdev_err(dev, "Unable to remove port from SMID\n"); |
| 1726 | netdev_err(dev, "Unable to remove port from SMID\n"); | ||
| 1727 | } | ||
| 1728 | } | 1726 | } |
| 1729 | 1727 | ||
| 1730 | err = mlxsw_sp_port_remove_from_mid(mlxsw_sp_port, mid); | 1728 | err = mlxsw_sp_port_remove_from_mid(mlxsw_sp_port, mid); |
diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index b3567a596fc1..80df9a5d4217 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c | |||
| @@ -183,17 +183,21 @@ static int | |||
| 183 | nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, | 183 | nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, |
| 184 | const struct tc_action *action, | 184 | const struct tc_action *action, |
| 185 | struct nfp_fl_pre_tunnel *pre_tun, | 185 | struct nfp_fl_pre_tunnel *pre_tun, |
| 186 | enum nfp_flower_tun_type tun_type) | 186 | enum nfp_flower_tun_type tun_type, |
| 187 | struct net_device *netdev) | ||
| 187 | { | 188 | { |
| 188 | size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun); | 189 | size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun); |
| 189 | struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action); | 190 | struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action); |
| 190 | u32 tmp_set_ip_tun_type_index = 0; | 191 | u32 tmp_set_ip_tun_type_index = 0; |
| 191 | /* Currently support one pre-tunnel so index is always 0. */ | 192 | /* Currently support one pre-tunnel so index is always 0. */ |
| 192 | int pretun_idx = 0; | 193 | int pretun_idx = 0; |
| 194 | struct net *net; | ||
| 193 | 195 | ||
| 194 | if (ip_tun->options_len) | 196 | if (ip_tun->options_len) |
| 195 | return -EOPNOTSUPP; | 197 | return -EOPNOTSUPP; |
| 196 | 198 | ||
| 199 | net = dev_net(netdev); | ||
| 200 | |||
| 197 | set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL; | 201 | set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL; |
| 198 | set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ; | 202 | set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ; |
| 199 | 203 | ||
| @@ -204,6 +208,7 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, | |||
| 204 | 208 | ||
| 205 | set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index); | 209 | set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index); |
| 206 | set_tun->tun_id = ip_tun->key.tun_id; | 210 | set_tun->tun_id = ip_tun->key.tun_id; |
| 211 | set_tun->ttl = net->ipv4.sysctl_ip_default_ttl; | ||
| 207 | 212 | ||
| 208 | /* Complete pre_tunnel action. */ | 213 | /* Complete pre_tunnel action. */ |
| 209 | pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst; | 214 | pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst; |
| @@ -511,7 +516,8 @@ nfp_flower_loop_action(const struct tc_action *a, | |||
| 511 | *a_len += sizeof(struct nfp_fl_pre_tunnel); | 516 | *a_len += sizeof(struct nfp_fl_pre_tunnel); |
| 512 | 517 | ||
| 513 | set_tun = (void *)&nfp_fl->action_data[*a_len]; | 518 | set_tun = (void *)&nfp_fl->action_data[*a_len]; |
| 514 | err = nfp_fl_set_ipv4_udp_tun(set_tun, a, pre_tun, *tun_type); | 519 | err = nfp_fl_set_ipv4_udp_tun(set_tun, a, pre_tun, *tun_type, |
| 520 | netdev); | ||
| 515 | if (err) | 521 | if (err) |
| 516 | return err; | 522 | return err; |
| 517 | *a_len += sizeof(struct nfp_fl_set_ipv4_udp_tun); | 523 | *a_len += sizeof(struct nfp_fl_set_ipv4_udp_tun); |
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index b6c0fd053a50..bee4367a2c38 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h | |||
| @@ -190,7 +190,10 @@ struct nfp_fl_set_ipv4_udp_tun { | |||
| 190 | __be16 reserved; | 190 | __be16 reserved; |
| 191 | __be64 tun_id __packed; | 191 | __be64 tun_id __packed; |
| 192 | __be32 tun_type_index; | 192 | __be32 tun_type_index; |
| 193 | __be32 extra[3]; | 193 | __be16 reserved2; |
| 194 | u8 ttl; | ||
| 195 | u8 reserved3; | ||
| 196 | __be32 extra[2]; | ||
| 194 | }; | 197 | }; |
| 195 | 198 | ||
| 196 | /* Metadata with L2 (1W/4B) | 199 | /* Metadata with L2 (1W/4B) |
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index ad02592a82b7..84e3b9f5abb1 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c | |||
| @@ -52,8 +52,6 @@ | |||
| 52 | 52 | ||
| 53 | #define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL | 53 | #define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL |
| 54 | 54 | ||
| 55 | #define NFP_FLOWER_FRAME_HEADROOM 158 | ||
| 56 | |||
| 57 | static const char *nfp_flower_extra_cap(struct nfp_app *app, struct nfp_net *nn) | 55 | static const char *nfp_flower_extra_cap(struct nfp_app *app, struct nfp_net *nn) |
| 58 | { | 56 | { |
| 59 | return "FLOWER"; | 57 | return "FLOWER"; |
| @@ -360,7 +358,7 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv) | |||
| 360 | } | 358 | } |
| 361 | 359 | ||
| 362 | SET_NETDEV_DEV(repr, &priv->nn->pdev->dev); | 360 | SET_NETDEV_DEV(repr, &priv->nn->pdev->dev); |
| 363 | nfp_net_get_mac_addr(app->pf, port); | 361 | nfp_net_get_mac_addr(app->pf, repr, port); |
| 364 | 362 | ||
| 365 | cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port); | 363 | cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port); |
| 366 | err = nfp_repr_init(app, repr, | 364 | err = nfp_repr_init(app, repr, |
| @@ -559,22 +557,6 @@ static void nfp_flower_clean(struct nfp_app *app) | |||
| 559 | app->priv = NULL; | 557 | app->priv = NULL; |
| 560 | } | 558 | } |
| 561 | 559 | ||
| 562 | static int | ||
| 563 | nfp_flower_check_mtu(struct nfp_app *app, struct net_device *netdev, | ||
| 564 | int new_mtu) | ||
| 565 | { | ||
| 566 | /* The flower fw reserves NFP_FLOWER_FRAME_HEADROOM bytes of the | ||
| 567 | * supported max MTU to allow for appending tunnel headers. To prevent | ||
| 568 | * unexpected behaviour this needs to be accounted for. | ||
| 569 | */ | ||
| 570 | if (new_mtu > netdev->max_mtu - NFP_FLOWER_FRAME_HEADROOM) { | ||
| 571 | nfp_err(app->cpp, "New MTU (%d) is not valid\n", new_mtu); | ||
| 572 | return -EINVAL; | ||
| 573 | } | ||
| 574 | |||
| 575 | return 0; | ||
| 576 | } | ||
| 577 | |||
| 578 | static bool nfp_flower_check_ack(struct nfp_flower_priv *app_priv) | 560 | static bool nfp_flower_check_ack(struct nfp_flower_priv *app_priv) |
| 579 | { | 561 | { |
| 580 | bool ret; | 562 | bool ret; |
| @@ -656,7 +638,6 @@ const struct nfp_app_type app_flower = { | |||
| 656 | .init = nfp_flower_init, | 638 | .init = nfp_flower_init, |
| 657 | .clean = nfp_flower_clean, | 639 | .clean = nfp_flower_clean, |
| 658 | 640 | ||
| 659 | .check_mtu = nfp_flower_check_mtu, | ||
| 660 | .repr_change_mtu = nfp_flower_repr_change_mtu, | 641 | .repr_change_mtu = nfp_flower_repr_change_mtu, |
| 661 | 642 | ||
| 662 | .vnic_alloc = nfp_flower_vnic_alloc, | 643 | .vnic_alloc = nfp_flower_vnic_alloc, |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c b/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c index 2a2f2fbc8850..b9618c37403f 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c | |||
| @@ -69,7 +69,7 @@ int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, | |||
| 69 | if (err) | 69 | if (err) |
| 70 | return err < 0 ? err : 0; | 70 | return err < 0 ? err : 0; |
| 71 | 71 | ||
| 72 | nfp_net_get_mac_addr(app->pf, nn->port); | 72 | nfp_net_get_mac_addr(app->pf, nn->dp.netdev, nn->port); |
| 73 | 73 | ||
| 74 | return 0; | 74 | return 0; |
| 75 | } | 75 | } |
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.h b/drivers/net/ethernet/netronome/nfp/nfp_main.h index add46e28212b..42211083b51f 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.h | |||
| @@ -171,7 +171,9 @@ void nfp_net_pci_remove(struct nfp_pf *pf); | |||
| 171 | int nfp_hwmon_register(struct nfp_pf *pf); | 171 | int nfp_hwmon_register(struct nfp_pf *pf); |
| 172 | void nfp_hwmon_unregister(struct nfp_pf *pf); | 172 | void nfp_hwmon_unregister(struct nfp_pf *pf); |
| 173 | 173 | ||
| 174 | void nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_port *port); | 174 | void |
| 175 | nfp_net_get_mac_addr(struct nfp_pf *pf, struct net_device *netdev, | ||
| 176 | struct nfp_port *port); | ||
| 175 | 177 | ||
| 176 | bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb); | 178 | bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb); |
| 177 | 179 | ||
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c index 15fa47f622aa..45cd2092e498 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c | |||
| @@ -67,23 +67,26 @@ | |||
| 67 | /** | 67 | /** |
| 68 | * nfp_net_get_mac_addr() - Get the MAC address. | 68 | * nfp_net_get_mac_addr() - Get the MAC address. |
| 69 | * @pf: NFP PF handle | 69 | * @pf: NFP PF handle |
| 70 | * @netdev: net_device to set MAC address on | ||
| 70 | * @port: NFP port structure | 71 | * @port: NFP port structure |
| 71 | * | 72 | * |
| 72 | * First try to get the MAC address from NSP ETH table. If that | 73 | * First try to get the MAC address from NSP ETH table. If that |
| 73 | * fails generate a random address. | 74 | * fails generate a random address. |
| 74 | */ | 75 | */ |
| 75 | void nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_port *port) | 76 | void |
| 77 | nfp_net_get_mac_addr(struct nfp_pf *pf, struct net_device *netdev, | ||
| 78 | struct nfp_port *port) | ||
| 76 | { | 79 | { |
| 77 | struct nfp_eth_table_port *eth_port; | 80 | struct nfp_eth_table_port *eth_port; |
| 78 | 81 | ||
| 79 | eth_port = __nfp_port_get_eth_port(port); | 82 | eth_port = __nfp_port_get_eth_port(port); |
| 80 | if (!eth_port) { | 83 | if (!eth_port) { |
| 81 | eth_hw_addr_random(port->netdev); | 84 | eth_hw_addr_random(netdev); |
| 82 | return; | 85 | return; |
| 83 | } | 86 | } |
| 84 | 87 | ||
| 85 | ether_addr_copy(port->netdev->dev_addr, eth_port->mac_addr); | 88 | ether_addr_copy(netdev->dev_addr, eth_port->mac_addr); |
| 86 | ether_addr_copy(port->netdev->perm_addr, eth_port->mac_addr); | 89 | ether_addr_copy(netdev->perm_addr, eth_port->mac_addr); |
| 87 | } | 90 | } |
| 88 | 91 | ||
| 89 | static struct nfp_eth_table_port * | 92 | static struct nfp_eth_table_port * |
| @@ -511,16 +514,18 @@ static int nfp_net_pci_map_mem(struct nfp_pf *pf) | |||
| 511 | return PTR_ERR(mem); | 514 | return PTR_ERR(mem); |
| 512 | } | 515 | } |
| 513 | 516 | ||
| 514 | min_size = NFP_MAC_STATS_SIZE * (pf->eth_tbl->max_index + 1); | 517 | if (pf->eth_tbl) { |
| 515 | pf->mac_stats_mem = nfp_rtsym_map(pf->rtbl, "_mac_stats", | 518 | min_size = NFP_MAC_STATS_SIZE * (pf->eth_tbl->max_index + 1); |
| 516 | "net.macstats", min_size, | 519 | pf->mac_stats_mem = nfp_rtsym_map(pf->rtbl, "_mac_stats", |
| 517 | &pf->mac_stats_bar); | 520 | "net.macstats", min_size, |
| 518 | if (IS_ERR(pf->mac_stats_mem)) { | 521 | &pf->mac_stats_bar); |
| 519 | if (PTR_ERR(pf->mac_stats_mem) != -ENOENT) { | 522 | if (IS_ERR(pf->mac_stats_mem)) { |
| 520 | err = PTR_ERR(pf->mac_stats_mem); | 523 | if (PTR_ERR(pf->mac_stats_mem) != -ENOENT) { |
| 521 | goto err_unmap_ctrl; | 524 | err = PTR_ERR(pf->mac_stats_mem); |
| 525 | goto err_unmap_ctrl; | ||
| 526 | } | ||
| 527 | pf->mac_stats_mem = NULL; | ||
| 522 | } | 528 | } |
| 523 | pf->mac_stats_mem = NULL; | ||
| 524 | } | 529 | } |
| 525 | 530 | ||
| 526 | pf->vf_cfg_mem = nfp_net_pf_map_rtsym(pf, "net.vfcfg", | 531 | pf->vf_cfg_mem = nfp_net_pf_map_rtsym(pf, "net.vfcfg", |
diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c index 27364b7572fc..b092894dd128 100644 --- a/drivers/net/ethernet/ni/nixge.c +++ b/drivers/net/ethernet/ni/nixge.c | |||
| @@ -1170,7 +1170,7 @@ static void *nixge_get_nvmem_address(struct device *dev) | |||
| 1170 | 1170 | ||
| 1171 | cell = nvmem_cell_get(dev, "address"); | 1171 | cell = nvmem_cell_get(dev, "address"); |
| 1172 | if (IS_ERR(cell)) | 1172 | if (IS_ERR(cell)) |
| 1173 | return cell; | 1173 | return NULL; |
| 1174 | 1174 | ||
| 1175 | mac = nvmem_cell_read(cell, &cell_size); | 1175 | mac = nvmem_cell_read(cell, &cell_size); |
| 1176 | nvmem_cell_put(cell); | 1176 | nvmem_cell_put(cell); |
| @@ -1183,7 +1183,7 @@ static int nixge_probe(struct platform_device *pdev) | |||
| 1183 | struct nixge_priv *priv; | 1183 | struct nixge_priv *priv; |
| 1184 | struct net_device *ndev; | 1184 | struct net_device *ndev; |
| 1185 | struct resource *dmares; | 1185 | struct resource *dmares; |
| 1186 | const char *mac_addr; | 1186 | const u8 *mac_addr; |
| 1187 | int err; | 1187 | int err; |
| 1188 | 1188 | ||
| 1189 | ndev = alloc_etherdev(sizeof(*priv)); | 1189 | ndev = alloc_etherdev(sizeof(*priv)); |
| @@ -1202,10 +1202,12 @@ static int nixge_probe(struct platform_device *pdev) | |||
| 1202 | ndev->max_mtu = NIXGE_JUMBO_MTU; | 1202 | ndev->max_mtu = NIXGE_JUMBO_MTU; |
| 1203 | 1203 | ||
| 1204 | mac_addr = nixge_get_nvmem_address(&pdev->dev); | 1204 | mac_addr = nixge_get_nvmem_address(&pdev->dev); |
| 1205 | if (mac_addr && is_valid_ether_addr(mac_addr)) | 1205 | if (mac_addr && is_valid_ether_addr(mac_addr)) { |
| 1206 | ether_addr_copy(ndev->dev_addr, mac_addr); | 1206 | ether_addr_copy(ndev->dev_addr, mac_addr); |
| 1207 | else | 1207 | kfree(mac_addr); |
| 1208 | } else { | ||
| 1208 | eth_hw_addr_random(ndev); | 1209 | eth_hw_addr_random(ndev); |
| 1210 | } | ||
| 1209 | 1211 | ||
| 1210 | priv = netdev_priv(ndev); | 1212 | priv = netdev_priv(ndev); |
| 1211 | priv->ndev = ndev; | 1213 | priv->ndev = ndev; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c index e874504e8b28..8667799d0069 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_l2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c | |||
| @@ -115,8 +115,7 @@ int qed_l2_alloc(struct qed_hwfn *p_hwfn) | |||
| 115 | 115 | ||
| 116 | void qed_l2_setup(struct qed_hwfn *p_hwfn) | 116 | void qed_l2_setup(struct qed_hwfn *p_hwfn) |
| 117 | { | 117 | { |
| 118 | if (p_hwfn->hw_info.personality != QED_PCI_ETH && | 118 | if (!QED_IS_L2_PERSONALITY(p_hwfn)) |
| 119 | p_hwfn->hw_info.personality != QED_PCI_ETH_ROCE) | ||
| 120 | return; | 119 | return; |
| 121 | 120 | ||
| 122 | mutex_init(&p_hwfn->p_l2_info->lock); | 121 | mutex_init(&p_hwfn->p_l2_info->lock); |
| @@ -126,8 +125,7 @@ void qed_l2_free(struct qed_hwfn *p_hwfn) | |||
| 126 | { | 125 | { |
| 127 | u32 i; | 126 | u32 i; |
| 128 | 127 | ||
| 129 | if (p_hwfn->hw_info.personality != QED_PCI_ETH && | 128 | if (!QED_IS_L2_PERSONALITY(p_hwfn)) |
| 130 | p_hwfn->hw_info.personality != QED_PCI_ETH_ROCE) | ||
| 131 | return; | 129 | return; |
| 132 | 130 | ||
| 133 | if (!p_hwfn->p_l2_info) | 131 | if (!p_hwfn->p_l2_info) |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c index 74fc626b1ec1..38502815d681 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c | |||
| @@ -2370,7 +2370,7 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb) | |||
| 2370 | u8 flags = 0; | 2370 | u8 flags = 0; |
| 2371 | 2371 | ||
| 2372 | if (unlikely(skb->ip_summed != CHECKSUM_NONE)) { | 2372 | if (unlikely(skb->ip_summed != CHECKSUM_NONE)) { |
| 2373 | DP_INFO(cdev, "Cannot transmit a checksumed packet\n"); | 2373 | DP_INFO(cdev, "Cannot transmit a checksummed packet\n"); |
| 2374 | return -EINVAL; | 2374 | return -EINVAL; |
| 2375 | } | 2375 | } |
| 2376 | 2376 | ||
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 9854aa9139af..7870ae2a6f7e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c | |||
| @@ -680,7 +680,7 @@ static int qed_nic_stop(struct qed_dev *cdev) | |||
| 680 | tasklet_disable(p_hwfn->sp_dpc); | 680 | tasklet_disable(p_hwfn->sp_dpc); |
| 681 | p_hwfn->b_sp_dpc_enabled = false; | 681 | p_hwfn->b_sp_dpc_enabled = false; |
| 682 | DP_VERBOSE(cdev, NETIF_MSG_IFDOWN, | 682 | DP_VERBOSE(cdev, NETIF_MSG_IFDOWN, |
| 683 | "Disabled sp taskelt [hwfn %d] at %p\n", | 683 | "Disabled sp tasklet [hwfn %d] at %p\n", |
| 684 | i, p_hwfn->sp_dpc); | 684 | i, p_hwfn->sp_dpc); |
| 685 | } | 685 | } |
| 686 | } | 686 | } |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.c b/drivers/net/ethernet/qlogic/qed/qed_roce.c index fb7c2d1562ae..6acfd43c1a4f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_roce.c +++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c | |||
| @@ -848,7 +848,7 @@ int qed_roce_query_qp(struct qed_hwfn *p_hwfn, | |||
| 848 | 848 | ||
| 849 | if (!(qp->resp_offloaded)) { | 849 | if (!(qp->resp_offloaded)) { |
| 850 | DP_NOTICE(p_hwfn, | 850 | DP_NOTICE(p_hwfn, |
| 851 | "The responder's qp should be offloded before requester's\n"); | 851 | "The responder's qp should be offloaded before requester's\n"); |
| 852 | return -EINVAL; | 852 | return -EINVAL; |
| 853 | } | 853 | } |
| 854 | 854 | ||
diff --git a/drivers/net/ethernet/qlogic/qede/qede_rdma.c b/drivers/net/ethernet/qlogic/qede/qede_rdma.c index 50b142fad6b8..1900bf7e67d1 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_rdma.c +++ b/drivers/net/ethernet/qlogic/qede/qede_rdma.c | |||
| @@ -238,7 +238,7 @@ qede_rdma_get_free_event_node(struct qede_dev *edev) | |||
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | if (!found) { | 240 | if (!found) { |
| 241 | event_node = kzalloc(sizeof(*event_node), GFP_KERNEL); | 241 | event_node = kzalloc(sizeof(*event_node), GFP_ATOMIC); |
| 242 | if (!event_node) { | 242 | if (!event_node) { |
| 243 | DP_NOTICE(edev, | 243 | DP_NOTICE(edev, |
| 244 | "qedr: Could not allocate memory for rdma work\n"); | 244 | "qedr: Could not allocate memory for rdma work\n"); |
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index d24b47b8e0b2..d118da5a10a2 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c | |||
| @@ -2224,7 +2224,7 @@ static void rtl8139_poll_controller(struct net_device *dev) | |||
| 2224 | struct rtl8139_private *tp = netdev_priv(dev); | 2224 | struct rtl8139_private *tp = netdev_priv(dev); |
| 2225 | const int irq = tp->pci_dev->irq; | 2225 | const int irq = tp->pci_dev->irq; |
| 2226 | 2226 | ||
| 2227 | disable_irq(irq); | 2227 | disable_irq_nosync(irq); |
| 2228 | rtl8139_interrupt(irq, dev); | 2228 | rtl8139_interrupt(irq, dev); |
| 2229 | enable_irq(irq); | 2229 | enable_irq(irq); |
| 2230 | } | 2230 | } |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 604ae78381ae..c7aac1fc99e8 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -4981,6 +4981,9 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) | |||
| 4981 | static void rtl_pll_power_up(struct rtl8169_private *tp) | 4981 | static void rtl_pll_power_up(struct rtl8169_private *tp) |
| 4982 | { | 4982 | { |
| 4983 | rtl_generic_op(tp, tp->pll_power_ops.up); | 4983 | rtl_generic_op(tp, tp->pll_power_ops.up); |
| 4984 | |||
| 4985 | /* give MAC/PHY some time to resume */ | ||
| 4986 | msleep(20); | ||
| 4984 | } | 4987 | } |
| 4985 | 4988 | ||
| 4986 | static void rtl_init_pll_power_ops(struct rtl8169_private *tp) | 4989 | static void rtl_init_pll_power_ops(struct rtl8169_private *tp) |
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 63036d9bf3e6..d90a7b1f4088 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c | |||
| @@ -4784,8 +4784,9 @@ expire: | |||
| 4784 | * will set rule->filter_id to EFX_ARFS_FILTER_ID_PENDING, meaning that | 4784 | * will set rule->filter_id to EFX_ARFS_FILTER_ID_PENDING, meaning that |
| 4785 | * the rule is not removed by efx_rps_hash_del() below. | 4785 | * the rule is not removed by efx_rps_hash_del() below. |
| 4786 | */ | 4786 | */ |
| 4787 | ret = efx_ef10_filter_remove_internal(efx, 1U << spec->priority, | 4787 | if (ret) |
| 4788 | filter_idx, true) == 0; | 4788 | ret = efx_ef10_filter_remove_internal(efx, 1U << spec->priority, |
| 4789 | filter_idx, true) == 0; | ||
| 4789 | /* While we can't safely dereference rule (we dropped the lock), we can | 4790 | /* While we can't safely dereference rule (we dropped the lock), we can |
| 4790 | * still test it for NULL. | 4791 | * still test it for NULL. |
| 4791 | */ | 4792 | */ |
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 64a94f242027..d2e254f2f72b 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
| @@ -839,6 +839,8 @@ static void efx_filter_rfs_work(struct work_struct *data) | |||
| 839 | int rc; | 839 | int rc; |
| 840 | 840 | ||
| 841 | rc = efx->type->filter_insert(efx, &req->spec, true); | 841 | rc = efx->type->filter_insert(efx, &req->spec, true); |
| 842 | if (rc >= 0) | ||
| 843 | rc %= efx->type->max_rx_ip_filters; | ||
| 842 | if (efx->rps_hash_table) { | 844 | if (efx->rps_hash_table) { |
| 843 | spin_lock_bh(&efx->rps_hash_lock); | 845 | spin_lock_bh(&efx->rps_hash_lock); |
| 844 | rule = efx_rps_hash_find(efx, &req->spec); | 846 | rule = efx_rps_hash_find(efx, &req->spec); |
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index f081de4f38d7..88c12474a0c3 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c | |||
| @@ -3443,7 +3443,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, | |||
| 3443 | 3443 | ||
| 3444 | len = (val & RCR_ENTRY_L2_LEN) >> | 3444 | len = (val & RCR_ENTRY_L2_LEN) >> |
| 3445 | RCR_ENTRY_L2_LEN_SHIFT; | 3445 | RCR_ENTRY_L2_LEN_SHIFT; |
| 3446 | len -= ETH_FCS_LEN; | 3446 | append_size = len + ETH_HLEN + ETH_FCS_LEN; |
| 3447 | 3447 | ||
| 3448 | addr = (val & RCR_ENTRY_PKT_BUF_ADDR) << | 3448 | addr = (val & RCR_ENTRY_PKT_BUF_ADDR) << |
| 3449 | RCR_ENTRY_PKT_BUF_ADDR_SHIFT; | 3449 | RCR_ENTRY_PKT_BUF_ADDR_SHIFT; |
| @@ -3453,7 +3453,6 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, | |||
| 3453 | RCR_ENTRY_PKTBUFSZ_SHIFT]; | 3453 | RCR_ENTRY_PKTBUFSZ_SHIFT]; |
| 3454 | 3454 | ||
| 3455 | off = addr & ~PAGE_MASK; | 3455 | off = addr & ~PAGE_MASK; |
| 3456 | append_size = rcr_size; | ||
| 3457 | if (num_rcr == 1) { | 3456 | if (num_rcr == 1) { |
| 3458 | int ptype; | 3457 | int ptype; |
| 3459 | 3458 | ||
| @@ -3466,7 +3465,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, | |||
| 3466 | else | 3465 | else |
| 3467 | skb_checksum_none_assert(skb); | 3466 | skb_checksum_none_assert(skb); |
| 3468 | } else if (!(val & RCR_ENTRY_MULTI)) | 3467 | } else if (!(val & RCR_ENTRY_MULTI)) |
| 3469 | append_size = len - skb->len; | 3468 | append_size = append_size - skb->len; |
| 3470 | 3469 | ||
| 3471 | niu_rx_skb_append(skb, page, off, append_size, rcr_size); | 3470 | niu_rx_skb_append(skb, page, off, append_size, rcr_size); |
| 3472 | if ((page->index + rp->rbr_block_size) - rcr_size == addr) { | 3471 | if ((page->index + rp->rbr_block_size) - rcr_size == addr) { |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 74f828412055..28d893b93d30 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -1340,6 +1340,8 @@ static inline void cpsw_add_dual_emac_def_ale_entries( | |||
| 1340 | cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, | 1340 | cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, |
| 1341 | HOST_PORT_NUM, ALE_VLAN | | 1341 | HOST_PORT_NUM, ALE_VLAN | |
| 1342 | ALE_SECURE, slave->port_vlan); | 1342 | ALE_SECURE, slave->port_vlan); |
| 1343 | cpsw_ale_control_set(cpsw->ale, slave_port, | ||
| 1344 | ALE_PORT_DROP_UNKNOWN_VLAN, 1); | ||
| 1343 | } | 1345 | } |
| 1344 | 1346 | ||
| 1345 | static void soft_reset_slave(struct cpsw_slave *slave) | 1347 | static void soft_reset_slave(struct cpsw_slave *slave) |
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index ecc84954c511..da07ccdf84bf 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
| @@ -1840,7 +1840,8 @@ static int netvsc_vf_join(struct net_device *vf_netdev, | |||
| 1840 | goto rx_handler_failed; | 1840 | goto rx_handler_failed; |
| 1841 | } | 1841 | } |
| 1842 | 1842 | ||
| 1843 | ret = netdev_upper_dev_link(vf_netdev, ndev, NULL); | 1843 | ret = netdev_master_upper_dev_link(vf_netdev, ndev, |
| 1844 | NULL, NULL, NULL); | ||
| 1844 | if (ret != 0) { | 1845 | if (ret != 0) { |
| 1845 | netdev_err(vf_netdev, | 1846 | netdev_err(vf_netdev, |
| 1846 | "can not set master device %s (err = %d)\n", | 1847 | "can not set master device %s (err = %d)\n", |
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 6b127be781d9..e7ca5b5f39ed 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c | |||
| @@ -1288,7 +1288,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, | |||
| 1288 | rndis_device->link_state ? "down" : "up"); | 1288 | rndis_device->link_state ? "down" : "up"); |
| 1289 | 1289 | ||
| 1290 | if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) | 1290 | if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) |
| 1291 | return net_device; | 1291 | goto out; |
| 1292 | 1292 | ||
| 1293 | rndis_filter_query_link_speed(rndis_device, net_device); | 1293 | rndis_filter_query_link_speed(rndis_device, net_device); |
| 1294 | 1294 | ||
diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 9fb9b565a002..4f684cbcdc57 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c | |||
| @@ -1045,7 +1045,7 @@ static int atusb_probe(struct usb_interface *interface, | |||
| 1045 | atusb->tx_dr.bRequest = ATUSB_TX; | 1045 | atusb->tx_dr.bRequest = ATUSB_TX; |
| 1046 | atusb->tx_dr.wValue = cpu_to_le16(0); | 1046 | atusb->tx_dr.wValue = cpu_to_le16(0); |
| 1047 | 1047 | ||
| 1048 | atusb->tx_urb = usb_alloc_urb(0, GFP_ATOMIC); | 1048 | atusb->tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
| 1049 | if (!atusb->tx_urb) | 1049 | if (!atusb->tx_urb) |
| 1050 | goto fail; | 1050 | goto fail; |
| 1051 | 1051 | ||
diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c index 55a22c761808..de0d7f28a181 100644 --- a/drivers/net/ieee802154/mcr20a.c +++ b/drivers/net/ieee802154/mcr20a.c | |||
| @@ -1267,7 +1267,7 @@ mcr20a_probe(struct spi_device *spi) | |||
| 1267 | ret = mcr20a_get_platform_data(spi, pdata); | 1267 | ret = mcr20a_get_platform_data(spi, pdata); |
| 1268 | if (ret < 0) { | 1268 | if (ret < 0) { |
| 1269 | dev_crit(&spi->dev, "mcr20a_get_platform_data failed.\n"); | 1269 | dev_crit(&spi->dev, "mcr20a_get_platform_data failed.\n"); |
| 1270 | return ret; | 1270 | goto free_pdata; |
| 1271 | } | 1271 | } |
| 1272 | 1272 | ||
| 1273 | /* init reset gpio */ | 1273 | /* init reset gpio */ |
| @@ -1275,7 +1275,7 @@ mcr20a_probe(struct spi_device *spi) | |||
| 1275 | ret = devm_gpio_request_one(&spi->dev, pdata->rst_gpio, | 1275 | ret = devm_gpio_request_one(&spi->dev, pdata->rst_gpio, |
| 1276 | GPIOF_OUT_INIT_HIGH, "reset"); | 1276 | GPIOF_OUT_INIT_HIGH, "reset"); |
| 1277 | if (ret) | 1277 | if (ret) |
| 1278 | return ret; | 1278 | goto free_pdata; |
| 1279 | } | 1279 | } |
| 1280 | 1280 | ||
| 1281 | /* reset mcr20a */ | 1281 | /* reset mcr20a */ |
| @@ -1291,7 +1291,8 @@ mcr20a_probe(struct spi_device *spi) | |||
| 1291 | hw = ieee802154_alloc_hw(sizeof(*lp), &mcr20a_hw_ops); | 1291 | hw = ieee802154_alloc_hw(sizeof(*lp), &mcr20a_hw_ops); |
| 1292 | if (!hw) { | 1292 | if (!hw) { |
| 1293 | dev_crit(&spi->dev, "ieee802154_alloc_hw failed\n"); | 1293 | dev_crit(&spi->dev, "ieee802154_alloc_hw failed\n"); |
| 1294 | return -ENOMEM; | 1294 | ret = -ENOMEM; |
| 1295 | goto free_pdata; | ||
| 1295 | } | 1296 | } |
| 1296 | 1297 | ||
| 1297 | /* init mcr20a local data */ | 1298 | /* init mcr20a local data */ |
| @@ -1308,8 +1309,10 @@ mcr20a_probe(struct spi_device *spi) | |||
| 1308 | /* init buf */ | 1309 | /* init buf */ |
| 1309 | lp->buf = devm_kzalloc(&spi->dev, SPI_COMMAND_BUFFER, GFP_KERNEL); | 1310 | lp->buf = devm_kzalloc(&spi->dev, SPI_COMMAND_BUFFER, GFP_KERNEL); |
| 1310 | 1311 | ||
| 1311 | if (!lp->buf) | 1312 | if (!lp->buf) { |
| 1312 | return -ENOMEM; | 1313 | ret = -ENOMEM; |
| 1314 | goto free_dev; | ||
| 1315 | } | ||
| 1313 | 1316 | ||
| 1314 | mcr20a_setup_tx_spi_messages(lp); | 1317 | mcr20a_setup_tx_spi_messages(lp); |
| 1315 | mcr20a_setup_rx_spi_messages(lp); | 1318 | mcr20a_setup_rx_spi_messages(lp); |
| @@ -1366,6 +1369,8 @@ mcr20a_probe(struct spi_device *spi) | |||
| 1366 | 1369 | ||
| 1367 | free_dev: | 1370 | free_dev: |
| 1368 | ieee802154_free_hw(lp->hw); | 1371 | ieee802154_free_hw(lp->hw); |
| 1372 | free_pdata: | ||
| 1373 | kfree(pdata); | ||
| 1369 | 1374 | ||
| 1370 | return ret; | 1375 | return ret; |
| 1371 | } | 1376 | } |
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 3bb6b66dc7bf..f9c25912eb98 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c | |||
| @@ -720,6 +720,15 @@ static struct phy_driver broadcom_drivers[] = { | |||
| 720 | .get_strings = bcm_phy_get_strings, | 720 | .get_strings = bcm_phy_get_strings, |
| 721 | .get_stats = bcm53xx_phy_get_stats, | 721 | .get_stats = bcm53xx_phy_get_stats, |
| 722 | .probe = bcm53xx_phy_probe, | 722 | .probe = bcm53xx_phy_probe, |
| 723 | }, { | ||
| 724 | .phy_id = PHY_ID_BCM89610, | ||
| 725 | .phy_id_mask = 0xfffffff0, | ||
| 726 | .name = "Broadcom BCM89610", | ||
| 727 | .features = PHY_GBIT_FEATURES, | ||
| 728 | .flags = PHY_HAS_INTERRUPT, | ||
| 729 | .config_init = bcm54xx_config_init, | ||
| 730 | .ack_interrupt = bcm_phy_ack_intr, | ||
| 731 | .config_intr = bcm_phy_config_intr, | ||
| 723 | } }; | 732 | } }; |
| 724 | 733 | ||
| 725 | module_phy_driver(broadcom_drivers); | 734 | module_phy_driver(broadcom_drivers); |
| @@ -741,6 +750,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = { | |||
| 741 | { PHY_ID_BCMAC131, 0xfffffff0 }, | 750 | { PHY_ID_BCMAC131, 0xfffffff0 }, |
| 742 | { PHY_ID_BCM5241, 0xfffffff0 }, | 751 | { PHY_ID_BCM5241, 0xfffffff0 }, |
| 743 | { PHY_ID_BCM5395, 0xfffffff0 }, | 752 | { PHY_ID_BCM5395, 0xfffffff0 }, |
| 753 | { PHY_ID_BCM89610, 0xfffffff0 }, | ||
| 744 | { } | 754 | { } |
| 745 | }; | 755 | }; |
| 746 | 756 | ||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index ac23322a32e1..9e4ba8e80a18 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -535,8 +535,17 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, | |||
| 535 | 535 | ||
| 536 | /* Grab the bits from PHYIR1, and put them in the upper half */ | 536 | /* Grab the bits from PHYIR1, and put them in the upper half */ |
| 537 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); | 537 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); |
| 538 | if (phy_reg < 0) | 538 | if (phy_reg < 0) { |
| 539 | /* if there is no device, return without an error so scanning | ||
| 540 | * the bus works properly | ||
| 541 | */ | ||
| 542 | if (phy_reg == -EIO || phy_reg == -ENODEV) { | ||
| 543 | *phy_id = 0xffffffff; | ||
| 544 | return 0; | ||
| 545 | } | ||
| 546 | |||
| 539 | return -EIO; | 547 | return -EIO; |
| 548 | } | ||
| 540 | 549 | ||
| 541 | *phy_id = (phy_reg & 0xffff) << 16; | 550 | *phy_id = (phy_reg & 0xffff) << 16; |
| 542 | 551 | ||
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index 0381da78d228..fd6c23f69c2f 100644 --- a/drivers/net/phy/sfp-bus.c +++ b/drivers/net/phy/sfp-bus.c | |||
| @@ -125,7 +125,7 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | |||
| 125 | if (id->base.br_nominal) { | 125 | if (id->base.br_nominal) { |
| 126 | if (id->base.br_nominal != 255) { | 126 | if (id->base.br_nominal != 255) { |
| 127 | br_nom = id->base.br_nominal * 100; | 127 | br_nom = id->base.br_nominal * 100; |
| 128 | br_min = br_nom + id->base.br_nominal * id->ext.br_min; | 128 | br_min = br_nom - id->base.br_nominal * id->ext.br_min; |
| 129 | br_max = br_nom + id->base.br_nominal * id->ext.br_max; | 129 | br_max = br_nom + id->base.br_nominal * id->ext.br_max; |
| 130 | } else if (id->ext.br_max) { | 130 | } else if (id->ext.br_max) { |
| 131 | br_nom = 250 * id->ext.br_max; | 131 | br_nom = 250 * id->ext.br_max; |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index c853e7410f5a..42565dd33aa6 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -1098,6 +1098,7 @@ static const struct usb_device_id products[] = { | |||
| 1098 | {QMI_FIXED_INTF(0x05c6, 0x9080, 8)}, | 1098 | {QMI_FIXED_INTF(0x05c6, 0x9080, 8)}, |
| 1099 | {QMI_FIXED_INTF(0x05c6, 0x9083, 3)}, | 1099 | {QMI_FIXED_INTF(0x05c6, 0x9083, 3)}, |
| 1100 | {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, | 1100 | {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, |
| 1101 | {QMI_FIXED_INTF(0x05c6, 0x90b2, 3)}, /* ublox R410M */ | ||
| 1101 | {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, | 1102 | {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, |
| 1102 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, | 1103 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, |
| 1103 | {QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)}, /* YUGA CLM920-NC5 */ | 1104 | {QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)}, /* YUGA CLM920-NC5 */ |
| @@ -1343,6 +1344,18 @@ static int qmi_wwan_probe(struct usb_interface *intf, | |||
| 1343 | id->driver_info = (unsigned long)&qmi_wwan_info; | 1344 | id->driver_info = (unsigned long)&qmi_wwan_info; |
| 1344 | } | 1345 | } |
| 1345 | 1346 | ||
| 1347 | /* There are devices where the same interface number can be | ||
| 1348 | * configured as different functions. We should only bind to | ||
| 1349 | * vendor specific functions when matching on interface number | ||
| 1350 | */ | ||
| 1351 | if (id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER && | ||
| 1352 | desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) { | ||
| 1353 | dev_dbg(&intf->dev, | ||
| 1354 | "Rejecting interface number match for class %02x\n", | ||
| 1355 | desc->bInterfaceClass); | ||
| 1356 | return -ENODEV; | ||
| 1357 | } | ||
| 1358 | |||
| 1346 | /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ | 1359 | /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ |
| 1347 | if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { | 1360 | if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { |
| 1348 | dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); | 1361 | dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c index 9277f4c2bfeb..94e177d7c9b5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | |||
| @@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct brcmf_fw_request *req) | |||
| 459 | kfree(req); | 459 | kfree(req); |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) | 462 | static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) |
| 463 | { | 463 | { |
| 464 | struct brcmf_fw *fwctx = ctx; | 464 | struct brcmf_fw *fwctx = ctx; |
| 465 | struct brcmf_fw_item *cur; | 465 | struct brcmf_fw_item *cur; |
| @@ -498,13 +498,10 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) | |||
| 498 | brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length); | 498 | brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length); |
| 499 | cur->nv_data.data = nvram; | 499 | cur->nv_data.data = nvram; |
| 500 | cur->nv_data.len = nvram_length; | 500 | cur->nv_data.len = nvram_length; |
| 501 | return; | 501 | return 0; |
| 502 | 502 | ||
| 503 | fail: | 503 | fail: |
| 504 | brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); | 504 | return -ENOENT; |
| 505 | fwctx->done(fwctx->dev, -ENOENT, NULL); | ||
| 506 | brcmf_fw_free_request(fwctx->req); | ||
| 507 | kfree(fwctx); | ||
| 508 | } | 505 | } |
| 509 | 506 | ||
| 510 | static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) | 507 | static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) |
| @@ -553,20 +550,27 @@ static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) | |||
| 553 | brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, | 550 | brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, |
| 554 | fw ? "" : "not "); | 551 | fw ? "" : "not "); |
| 555 | 552 | ||
| 556 | if (fw) { | 553 | if (!fw) |
| 557 | if (cur->type == BRCMF_FW_TYPE_BINARY) | ||
| 558 | cur->binary = fw; | ||
| 559 | else if (cur->type == BRCMF_FW_TYPE_NVRAM) | ||
| 560 | brcmf_fw_request_nvram_done(fw, fwctx); | ||
| 561 | else | ||
| 562 | release_firmware(fw); | ||
| 563 | } else if (cur->type == BRCMF_FW_TYPE_NVRAM) { | ||
| 564 | brcmf_fw_request_nvram_done(NULL, fwctx); | ||
| 565 | } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) { | ||
| 566 | ret = -ENOENT; | 554 | ret = -ENOENT; |
| 555 | |||
| 556 | switch (cur->type) { | ||
| 557 | case BRCMF_FW_TYPE_NVRAM: | ||
| 558 | ret = brcmf_fw_request_nvram_done(fw, fwctx); | ||
| 559 | break; | ||
| 560 | case BRCMF_FW_TYPE_BINARY: | ||
| 561 | cur->binary = fw; | ||
| 562 | break; | ||
| 563 | default: | ||
| 564 | /* something fishy here so bail out early */ | ||
| 565 | brcmf_err("unknown fw type: %d\n", cur->type); | ||
| 566 | release_firmware(fw); | ||
| 567 | ret = -EINVAL; | ||
| 567 | goto fail; | 568 | goto fail; |
| 568 | } | 569 | } |
| 569 | 570 | ||
| 571 | if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) | ||
| 572 | goto fail; | ||
| 573 | |||
| 570 | do { | 574 | do { |
| 571 | if (++fwctx->curpos == fwctx->req->n_items) { | 575 | if (++fwctx->curpos == fwctx->req->n_items) { |
| 572 | ret = 0; | 576 | ret = 0; |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 7af3a0f51b77..a17c4a79b8d4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 Intel Corporation | ||
| 11 | * | 12 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -30,7 +31,7 @@ | |||
| 30 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 31 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 32 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 33 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 33 | * Copyright(c) 2018 Intel Corporation | 34 | * Copyright(c) 2018 Intel Corporation |
| 34 | * All rights reserved. | 35 | * All rights reserved. |
| 35 | * | 36 | * |
| 36 | * Redistribution and use in source and binary forms, with or without | 37 | * Redistribution and use in source and binary forms, with or without |
| @@ -749,13 +750,9 @@ struct iwl_scan_req_umac { | |||
| 749 | } __packed; | 750 | } __packed; |
| 750 | 751 | ||
| 751 | #define IWL_SCAN_REQ_UMAC_SIZE_V8 sizeof(struct iwl_scan_req_umac) | 752 | #define IWL_SCAN_REQ_UMAC_SIZE_V8 sizeof(struct iwl_scan_req_umac) |
| 752 | #define IWL_SCAN_REQ_UMAC_SIZE_V7 (sizeof(struct iwl_scan_req_umac) - \ | 753 | #define IWL_SCAN_REQ_UMAC_SIZE_V7 48 |
| 753 | 4 * sizeof(u8)) | 754 | #define IWL_SCAN_REQ_UMAC_SIZE_V6 44 |
| 754 | #define IWL_SCAN_REQ_UMAC_SIZE_V6 (sizeof(struct iwl_scan_req_umac) - \ | 755 | #define IWL_SCAN_REQ_UMAC_SIZE_V1 36 |
| 755 | 2 * sizeof(u8) - sizeof(__le16)) | ||
| 756 | #define IWL_SCAN_REQ_UMAC_SIZE_V1 (sizeof(struct iwl_scan_req_umac) - \ | ||
| 757 | 2 * sizeof(__le32) - 2 * sizeof(u8) - \ | ||
| 758 | sizeof(__le16)) | ||
| 759 | 756 | ||
| 760 | /** | 757 | /** |
| 761 | * struct iwl_umac_scan_abort | 758 | * struct iwl_umac_scan_abort |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 8928613e033e..ca0174680af9 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | |||
| @@ -76,6 +76,7 @@ | |||
| 76 | #include "iwl-io.h" | 76 | #include "iwl-io.h" |
| 77 | #include "iwl-csr.h" | 77 | #include "iwl-csr.h" |
| 78 | #include "fw/acpi.h" | 78 | #include "fw/acpi.h" |
| 79 | #include "fw/api/nvm-reg.h" | ||
| 79 | 80 | ||
| 80 | /* NVM offsets (in words) definitions */ | 81 | /* NVM offsets (in words) definitions */ |
| 81 | enum nvm_offsets { | 82 | enum nvm_offsets { |
| @@ -146,8 +147,8 @@ static const u8 iwl_ext_nvm_channels[] = { | |||
| 146 | 149, 153, 157, 161, 165, 169, 173, 177, 181 | 147 | 149, 153, 157, 161, 165, 169, 173, 177, 181 |
| 147 | }; | 148 | }; |
| 148 | 149 | ||
| 149 | #define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels) | 150 | #define IWL_NVM_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels) |
| 150 | #define IWL_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels) | 151 | #define IWL_NVM_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels) |
| 151 | #define NUM_2GHZ_CHANNELS 14 | 152 | #define NUM_2GHZ_CHANNELS 14 |
| 152 | #define NUM_2GHZ_CHANNELS_EXT 14 | 153 | #define NUM_2GHZ_CHANNELS_EXT 14 |
| 153 | #define FIRST_2GHZ_HT_MINUS 5 | 154 | #define FIRST_2GHZ_HT_MINUS 5 |
| @@ -301,11 +302,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
| 301 | const u8 *nvm_chan; | 302 | const u8 *nvm_chan; |
| 302 | 303 | ||
| 303 | if (cfg->nvm_type != IWL_NVM_EXT) { | 304 | if (cfg->nvm_type != IWL_NVM_EXT) { |
| 304 | num_of_ch = IWL_NUM_CHANNELS; | 305 | num_of_ch = IWL_NVM_NUM_CHANNELS; |
| 305 | nvm_chan = &iwl_nvm_channels[0]; | 306 | nvm_chan = &iwl_nvm_channels[0]; |
| 306 | num_2ghz_channels = NUM_2GHZ_CHANNELS; | 307 | num_2ghz_channels = NUM_2GHZ_CHANNELS; |
| 307 | } else { | 308 | } else { |
| 308 | num_of_ch = IWL_NUM_CHANNELS_EXT; | 309 | num_of_ch = IWL_NVM_NUM_CHANNELS_EXT; |
| 309 | nvm_chan = &iwl_ext_nvm_channels[0]; | 310 | nvm_chan = &iwl_ext_nvm_channels[0]; |
| 310 | num_2ghz_channels = NUM_2GHZ_CHANNELS_EXT; | 311 | num_2ghz_channels = NUM_2GHZ_CHANNELS_EXT; |
| 311 | } | 312 | } |
| @@ -720,12 +721,12 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
| 720 | if (cfg->nvm_type != IWL_NVM_EXT) | 721 | if (cfg->nvm_type != IWL_NVM_EXT) |
| 721 | data = kzalloc(sizeof(*data) + | 722 | data = kzalloc(sizeof(*data) + |
| 722 | sizeof(struct ieee80211_channel) * | 723 | sizeof(struct ieee80211_channel) * |
| 723 | IWL_NUM_CHANNELS, | 724 | IWL_NVM_NUM_CHANNELS, |
| 724 | GFP_KERNEL); | 725 | GFP_KERNEL); |
| 725 | else | 726 | else |
| 726 | data = kzalloc(sizeof(*data) + | 727 | data = kzalloc(sizeof(*data) + |
| 727 | sizeof(struct ieee80211_channel) * | 728 | sizeof(struct ieee80211_channel) * |
| 728 | IWL_NUM_CHANNELS_EXT, | 729 | IWL_NVM_NUM_CHANNELS_EXT, |
| 729 | GFP_KERNEL); | 730 | GFP_KERNEL); |
| 730 | if (!data) | 731 | if (!data) |
| 731 | return NULL; | 732 | return NULL; |
| @@ -842,24 +843,34 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan, | |||
| 842 | return flags; | 843 | return flags; |
| 843 | } | 844 | } |
| 844 | 845 | ||
| 846 | struct regdb_ptrs { | ||
| 847 | struct ieee80211_wmm_rule *rule; | ||
| 848 | u32 token; | ||
| 849 | }; | ||
| 850 | |||
| 845 | struct ieee80211_regdomain * | 851 | struct ieee80211_regdomain * |
| 846 | iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, | 852 | iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, |
| 847 | int num_of_ch, __le32 *channels, u16 fw_mcc) | 853 | int num_of_ch, __le32 *channels, u16 fw_mcc, |
| 854 | u16 geo_info) | ||
| 848 | { | 855 | { |
| 849 | int ch_idx; | 856 | int ch_idx; |
| 850 | u16 ch_flags; | 857 | u16 ch_flags; |
| 851 | u32 reg_rule_flags, prev_reg_rule_flags = 0; | 858 | u32 reg_rule_flags, prev_reg_rule_flags = 0; |
| 852 | const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ? | 859 | const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ? |
| 853 | iwl_ext_nvm_channels : iwl_nvm_channels; | 860 | iwl_ext_nvm_channels : iwl_nvm_channels; |
| 854 | struct ieee80211_regdomain *regd; | 861 | struct ieee80211_regdomain *regd, *copy_rd; |
| 855 | int size_of_regd; | 862 | int size_of_regd, regd_to_copy, wmms_to_copy; |
| 863 | int size_of_wmms = 0; | ||
| 856 | struct ieee80211_reg_rule *rule; | 864 | struct ieee80211_reg_rule *rule; |
| 865 | struct ieee80211_wmm_rule *wmm_rule, *d_wmm, *s_wmm; | ||
| 866 | struct regdb_ptrs *regdb_ptrs; | ||
| 857 | enum nl80211_band band; | 867 | enum nl80211_band band; |
| 858 | int center_freq, prev_center_freq = 0; | 868 | int center_freq, prev_center_freq = 0; |
| 859 | int valid_rules = 0; | 869 | int valid_rules = 0, n_wmms = 0; |
| 870 | int i; | ||
| 860 | bool new_rule; | 871 | bool new_rule; |
| 861 | int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? | 872 | int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? |
| 862 | IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS; | 873 | IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS; |
| 863 | 874 | ||
| 864 | if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) | 875 | if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) |
| 865 | return ERR_PTR(-EINVAL); | 876 | return ERR_PTR(-EINVAL); |
| @@ -875,10 +886,26 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, | |||
| 875 | sizeof(struct ieee80211_regdomain) + | 886 | sizeof(struct ieee80211_regdomain) + |
| 876 | num_of_ch * sizeof(struct ieee80211_reg_rule); | 887 | num_of_ch * sizeof(struct ieee80211_reg_rule); |
| 877 | 888 | ||
| 878 | regd = kzalloc(size_of_regd, GFP_KERNEL); | 889 | if (geo_info & GEO_WMM_ETSI_5GHZ_INFO) |
| 890 | size_of_wmms = | ||
| 891 | num_of_ch * sizeof(struct ieee80211_wmm_rule); | ||
| 892 | |||
| 893 | regd = kzalloc(size_of_regd + size_of_wmms, GFP_KERNEL); | ||
| 879 | if (!regd) | 894 | if (!regd) |
| 880 | return ERR_PTR(-ENOMEM); | 895 | return ERR_PTR(-ENOMEM); |
| 881 | 896 | ||
| 897 | regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL); | ||
| 898 | if (!regdb_ptrs) { | ||
| 899 | copy_rd = ERR_PTR(-ENOMEM); | ||
| 900 | goto out; | ||
| 901 | } | ||
| 902 | |||
| 903 | /* set alpha2 from FW. */ | ||
| 904 | regd->alpha2[0] = fw_mcc >> 8; | ||
| 905 | regd->alpha2[1] = fw_mcc & 0xff; | ||
| 906 | |||
| 907 | wmm_rule = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd); | ||
| 908 | |||
| 882 | for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) { | 909 | for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) { |
| 883 | ch_flags = (u16)__le32_to_cpup(channels + ch_idx); | 910 | ch_flags = (u16)__le32_to_cpup(channels + ch_idx); |
| 884 | band = (ch_idx < NUM_2GHZ_CHANNELS) ? | 911 | band = (ch_idx < NUM_2GHZ_CHANNELS) ? |
| @@ -927,14 +954,66 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, | |||
| 927 | 954 | ||
| 928 | iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, | 955 | iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, |
| 929 | nvm_chan[ch_idx], ch_flags); | 956 | nvm_chan[ch_idx], ch_flags); |
| 957 | |||
| 958 | if (!(geo_info & GEO_WMM_ETSI_5GHZ_INFO) || | ||
| 959 | band == NL80211_BAND_2GHZ) | ||
| 960 | continue; | ||
| 961 | |||
| 962 | if (!reg_query_regdb_wmm(regd->alpha2, center_freq, | ||
| 963 | ®db_ptrs[n_wmms].token, wmm_rule)) { | ||
| 964 | /* Add only new rules */ | ||
| 965 | for (i = 0; i < n_wmms; i++) { | ||
| 966 | if (regdb_ptrs[i].token == | ||
| 967 | regdb_ptrs[n_wmms].token) { | ||
| 968 | rule->wmm_rule = regdb_ptrs[i].rule; | ||
| 969 | break; | ||
| 970 | } | ||
| 971 | } | ||
| 972 | if (i == n_wmms) { | ||
| 973 | rule->wmm_rule = wmm_rule; | ||
| 974 | regdb_ptrs[n_wmms++].rule = wmm_rule; | ||
| 975 | wmm_rule++; | ||
| 976 | } | ||
| 977 | } | ||
| 930 | } | 978 | } |
| 931 | 979 | ||
| 932 | regd->n_reg_rules = valid_rules; | 980 | regd->n_reg_rules = valid_rules; |
| 981 | regd->n_wmm_rules = n_wmms; | ||
| 933 | 982 | ||
| 934 | /* set alpha2 from FW. */ | 983 | /* |
| 935 | regd->alpha2[0] = fw_mcc >> 8; | 984 | * Narrow down regdom for unused regulatory rules to prevent hole |
| 936 | regd->alpha2[1] = fw_mcc & 0xff; | 985 | * between reg rules to wmm rules. |
| 986 | */ | ||
| 987 | regd_to_copy = sizeof(struct ieee80211_regdomain) + | ||
| 988 | valid_rules * sizeof(struct ieee80211_reg_rule); | ||
| 989 | |||
| 990 | wmms_to_copy = sizeof(struct ieee80211_wmm_rule) * n_wmms; | ||
| 991 | |||
| 992 | copy_rd = kzalloc(regd_to_copy + wmms_to_copy, GFP_KERNEL); | ||
| 993 | if (!copy_rd) { | ||
| 994 | copy_rd = ERR_PTR(-ENOMEM); | ||
| 995 | goto out; | ||
| 996 | } | ||
| 997 | |||
| 998 | memcpy(copy_rd, regd, regd_to_copy); | ||
| 999 | memcpy((u8 *)copy_rd + regd_to_copy, (u8 *)regd + size_of_regd, | ||
| 1000 | wmms_to_copy); | ||
| 1001 | |||
| 1002 | d_wmm = (struct ieee80211_wmm_rule *)((u8 *)copy_rd + regd_to_copy); | ||
| 1003 | s_wmm = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd); | ||
| 1004 | |||
| 1005 | for (i = 0; i < regd->n_reg_rules; i++) { | ||
| 1006 | if (!regd->reg_rules[i].wmm_rule) | ||
| 1007 | continue; | ||
| 1008 | |||
| 1009 | copy_rd->reg_rules[i].wmm_rule = d_wmm + | ||
| 1010 | (regd->reg_rules[i].wmm_rule - s_wmm) / | ||
| 1011 | sizeof(struct ieee80211_wmm_rule); | ||
| 1012 | } | ||
| 937 | 1013 | ||
| 938 | return regd; | 1014 | out: |
| 1015 | kfree(regdb_ptrs); | ||
| 1016 | kfree(regd); | ||
| 1017 | return copy_rd; | ||
| 939 | } | 1018 | } |
| 940 | IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info); | 1019 | IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info); |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h index 306736c7a042..3071a23b7606 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h | |||
| @@ -101,12 +101,14 @@ void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, | |||
| 101 | * | 101 | * |
| 102 | * This function parses the regulatory channel data received as a | 102 | * This function parses the regulatory channel data received as a |
| 103 | * MCC_UPDATE_CMD command. It returns a newly allocation regulatory domain, | 103 | * MCC_UPDATE_CMD command. It returns a newly allocation regulatory domain, |
| 104 | * to be fed into the regulatory core. An ERR_PTR is returned on error. | 104 | * to be fed into the regulatory core. In case the geo_info is set handle |
| 105 | * accordingly. An ERR_PTR is returned on error. | ||
| 105 | * If not given to the regulatory core, the user is responsible for freeing | 106 | * If not given to the regulatory core, the user is responsible for freeing |
| 106 | * the regdomain returned here with kfree. | 107 | * the regdomain returned here with kfree. |
| 107 | */ | 108 | */ |
| 108 | struct ieee80211_regdomain * | 109 | struct ieee80211_regdomain * |
| 109 | iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, | 110 | iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, |
| 110 | int num_of_ch, __le32 *channels, u16 fw_mcc); | 111 | int num_of_ch, __le32 *channels, u16 fw_mcc, |
| 112 | u16 geo_info); | ||
| 111 | 113 | ||
| 112 | #endif /* __iwl_nvm_parse_h__ */ | 114 | #endif /* __iwl_nvm_parse_h__ */ |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 51b30424575b..90f8c89ea59c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | |||
| @@ -311,7 +311,8 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy, | |||
| 311 | regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, | 311 | regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, |
| 312 | __le32_to_cpu(resp->n_channels), | 312 | __le32_to_cpu(resp->n_channels), |
| 313 | resp->channels, | 313 | resp->channels, |
| 314 | __le16_to_cpu(resp->mcc)); | 314 | __le16_to_cpu(resp->mcc), |
| 315 | __le16_to_cpu(resp->geo_info)); | ||
| 315 | /* Store the return source id */ | 316 | /* Store the return source id */ |
| 316 | src_id = resp->source_id; | 317 | src_id = resp->source_id; |
| 317 | kfree(resp); | 318 | kfree(resp); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 96d26cfae90b..4a017a0d71ea 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
| @@ -3236,6 +3236,7 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) | |||
| 3236 | GENL_SET_ERR_MSG(info,"MAC is no valid source addr"); | 3236 | GENL_SET_ERR_MSG(info,"MAC is no valid source addr"); |
| 3237 | NL_SET_BAD_ATTR(info->extack, | 3237 | NL_SET_BAD_ATTR(info->extack, |
| 3238 | info->attrs[HWSIM_ATTR_PERM_ADDR]); | 3238 | info->attrs[HWSIM_ATTR_PERM_ADDR]); |
| 3239 | kfree(hwname); | ||
| 3239 | return -EINVAL; | 3240 | return -EINVAL; |
| 3240 | } | 3241 | } |
| 3241 | 3242 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c index 8b6b07a936f5..b026e80940a4 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c | |||
| @@ -158,16 +158,6 @@ static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist) | |||
| 158 | 158 | ||
| 159 | static u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv) | 159 | static u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv) |
| 160 | { | 160 | { |
| 161 | struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; | ||
| 162 | |||
| 163 | /* override ant_num / ant_path */ | ||
| 164 | if (mod_params->ant_sel) { | ||
| 165 | rtlpriv->btcoexist.btc_info.ant_num = | ||
| 166 | (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1); | ||
| 167 | |||
| 168 | rtlpriv->btcoexist.btc_info.single_ant_path = | ||
| 169 | (mod_params->ant_sel == 1 ? 0 : 1); | ||
| 170 | } | ||
| 171 | return rtlpriv->btcoexist.btc_info.single_ant_path; | 161 | return rtlpriv->btcoexist.btc_info.single_ant_path; |
| 172 | } | 162 | } |
| 173 | 163 | ||
| @@ -178,7 +168,6 @@ static u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv) | |||
| 178 | 168 | ||
| 179 | static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) | 169 | static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) |
| 180 | { | 170 | { |
| 181 | struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; | ||
| 182 | u8 num; | 171 | u8 num; |
| 183 | 172 | ||
| 184 | if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2) | 173 | if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2) |
| @@ -186,10 +175,6 @@ static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) | |||
| 186 | else | 175 | else |
| 187 | num = 1; | 176 | num = 1; |
| 188 | 177 | ||
| 189 | /* override ant_num / ant_path */ | ||
| 190 | if (mod_params->ant_sel) | ||
| 191 | num = (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1) + 1; | ||
| 192 | |||
| 193 | return num; | 178 | return num; |
| 194 | } | 179 | } |
| 195 | 180 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c index e7bbbc95cdb1..b4f3f91b590e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | |||
| @@ -848,6 +848,9 @@ static bool _rtl8723be_init_mac(struct ieee80211_hw *hw) | |||
| 848 | return false; | 848 | return false; |
| 849 | } | 849 | } |
| 850 | 850 | ||
| 851 | if (rtlpriv->cfg->ops->get_btc_status()) | ||
| 852 | rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv); | ||
| 853 | |||
| 851 | bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL); | 854 | bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL); |
| 852 | rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3)); | 855 | rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3)); |
| 853 | 856 | ||
| @@ -2696,21 +2699,21 @@ void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, | |||
| 2696 | rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; | 2699 | rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; |
| 2697 | rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1); | 2700 | rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1); |
| 2698 | rtlpriv->btcoexist.btc_info.single_ant_path = | 2701 | rtlpriv->btcoexist.btc_info.single_ant_path = |
| 2699 | (value & 0x40); /*0xc3[6]*/ | 2702 | (value & 0x40 ? ANT_AUX : ANT_MAIN); /*0xc3[6]*/ |
| 2700 | } else { | 2703 | } else { |
| 2701 | rtlpriv->btcoexist.btc_info.btcoexist = 0; | 2704 | rtlpriv->btcoexist.btc_info.btcoexist = 0; |
| 2702 | rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; | 2705 | rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; |
| 2703 | rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; | 2706 | rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; |
| 2704 | rtlpriv->btcoexist.btc_info.single_ant_path = 0; | 2707 | rtlpriv->btcoexist.btc_info.single_ant_path = ANT_MAIN; |
| 2705 | } | 2708 | } |
| 2706 | 2709 | ||
| 2707 | /* override ant_num / ant_path */ | 2710 | /* override ant_num / ant_path */ |
| 2708 | if (mod_params->ant_sel) { | 2711 | if (mod_params->ant_sel) { |
| 2709 | rtlpriv->btcoexist.btc_info.ant_num = | 2712 | rtlpriv->btcoexist.btc_info.ant_num = |
| 2710 | (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1); | 2713 | (mod_params->ant_sel == 1 ? ANT_X1 : ANT_X2); |
| 2711 | 2714 | ||
| 2712 | rtlpriv->btcoexist.btc_info.single_ant_path = | 2715 | rtlpriv->btcoexist.btc_info.single_ant_path = |
| 2713 | (mod_params->ant_sel == 1 ? 0 : 1); | 2716 | (mod_params->ant_sel == 1 ? ANT_AUX : ANT_MAIN); |
| 2714 | } | 2717 | } |
| 2715 | } | 2718 | } |
| 2716 | 2719 | ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h index d27e33960e77..ce1754054a07 100644 --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h | |||
| @@ -2823,6 +2823,11 @@ enum bt_ant_num { | |||
| 2823 | ANT_X1 = 1, | 2823 | ANT_X1 = 1, |
| 2824 | }; | 2824 | }; |
| 2825 | 2825 | ||
| 2826 | enum bt_ant_path { | ||
| 2827 | ANT_MAIN = 0, | ||
| 2828 | ANT_AUX = 1, | ||
| 2829 | }; | ||
| 2830 | |||
| 2826 | enum bt_co_type { | 2831 | enum bt_co_type { |
| 2827 | BT_2WIRE = 0, | 2832 | BT_2WIRE = 0, |
| 2828 | BT_ISSC_3WIRE = 1, | 2833 | BT_ISSC_3WIRE = 1, |
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig index b979cf3bce65..88a8b5916624 100644 --- a/drivers/nvme/host/Kconfig +++ b/drivers/nvme/host/Kconfig | |||
| @@ -27,7 +27,7 @@ config NVME_FABRICS | |||
| 27 | 27 | ||
| 28 | config NVME_RDMA | 28 | config NVME_RDMA |
| 29 | tristate "NVM Express over Fabrics RDMA host driver" | 29 | tristate "NVM Express over Fabrics RDMA host driver" |
| 30 | depends on INFINIBAND && BLOCK | 30 | depends on INFINIBAND && INFINIBAND_ADDR_TRANS && BLOCK |
| 31 | select NVME_CORE | 31 | select NVME_CORE |
| 32 | select NVME_FABRICS | 32 | select NVME_FABRICS |
| 33 | select SG_POOL | 33 | select SG_POOL |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 9df4f71e58ca..99b857e5a7a9 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -99,6 +99,7 @@ static struct class *nvme_subsys_class; | |||
| 99 | 99 | ||
| 100 | static void nvme_ns_remove(struct nvme_ns *ns); | 100 | static void nvme_ns_remove(struct nvme_ns *ns); |
| 101 | static int nvme_revalidate_disk(struct gendisk *disk); | 101 | static int nvme_revalidate_disk(struct gendisk *disk); |
| 102 | static void nvme_put_subsystem(struct nvme_subsystem *subsys); | ||
| 102 | 103 | ||
| 103 | int nvme_reset_ctrl(struct nvme_ctrl *ctrl) | 104 | int nvme_reset_ctrl(struct nvme_ctrl *ctrl) |
| 104 | { | 105 | { |
| @@ -117,7 +118,8 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) | |||
| 117 | ret = nvme_reset_ctrl(ctrl); | 118 | ret = nvme_reset_ctrl(ctrl); |
| 118 | if (!ret) { | 119 | if (!ret) { |
| 119 | flush_work(&ctrl->reset_work); | 120 | flush_work(&ctrl->reset_work); |
| 120 | if (ctrl->state != NVME_CTRL_LIVE) | 121 | if (ctrl->state != NVME_CTRL_LIVE && |
| 122 | ctrl->state != NVME_CTRL_ADMIN_ONLY) | ||
| 121 | ret = -ENETRESET; | 123 | ret = -ENETRESET; |
| 122 | } | 124 | } |
| 123 | 125 | ||
| @@ -350,6 +352,7 @@ static void nvme_free_ns_head(struct kref *ref) | |||
| 350 | ida_simple_remove(&head->subsys->ns_ida, head->instance); | 352 | ida_simple_remove(&head->subsys->ns_ida, head->instance); |
| 351 | list_del_init(&head->entry); | 353 | list_del_init(&head->entry); |
| 352 | cleanup_srcu_struct(&head->srcu); | 354 | cleanup_srcu_struct(&head->srcu); |
| 355 | nvme_put_subsystem(head->subsys); | ||
| 353 | kfree(head); | 356 | kfree(head); |
| 354 | } | 357 | } |
| 355 | 358 | ||
| @@ -764,6 +767,7 @@ static int nvme_submit_user_cmd(struct request_queue *q, | |||
| 764 | ret = PTR_ERR(meta); | 767 | ret = PTR_ERR(meta); |
| 765 | goto out_unmap; | 768 | goto out_unmap; |
| 766 | } | 769 | } |
| 770 | req->cmd_flags |= REQ_INTEGRITY; | ||
| 767 | } | 771 | } |
| 768 | } | 772 | } |
| 769 | 773 | ||
| @@ -2860,6 +2864,9 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl, | |||
| 2860 | goto out_cleanup_srcu; | 2864 | goto out_cleanup_srcu; |
| 2861 | 2865 | ||
| 2862 | list_add_tail(&head->entry, &ctrl->subsys->nsheads); | 2866 | list_add_tail(&head->entry, &ctrl->subsys->nsheads); |
| 2867 | |||
| 2868 | kref_get(&ctrl->subsys->ref); | ||
| 2869 | |||
| 2863 | return head; | 2870 | return head; |
| 2864 | out_cleanup_srcu: | 2871 | out_cleanup_srcu: |
| 2865 | cleanup_srcu_struct(&head->srcu); | 2872 | cleanup_srcu_struct(&head->srcu); |
| @@ -2997,31 +3004,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) | |||
| 2997 | if (nvme_init_ns_head(ns, nsid, id)) | 3004 | if (nvme_init_ns_head(ns, nsid, id)) |
| 2998 | goto out_free_id; | 3005 | goto out_free_id; |
| 2999 | nvme_setup_streams_ns(ctrl, ns); | 3006 | nvme_setup_streams_ns(ctrl, ns); |
| 3000 | 3007 | nvme_set_disk_name(disk_name, ns, ctrl, &flags); | |
| 3001 | #ifdef CONFIG_NVME_MULTIPATH | ||
| 3002 | /* | ||
| 3003 | * If multipathing is enabled we need to always use the subsystem | ||
| 3004 | * instance number for numbering our devices to avoid conflicts | ||
| 3005 | * between subsystems that have multiple controllers and thus use | ||
| 3006 | * the multipath-aware subsystem node and those that have a single | ||
| 3007 | * controller and use the controller node directly. | ||
| 3008 | */ | ||
| 3009 | if (ns->head->disk) { | ||
| 3010 | sprintf(disk_name, "nvme%dc%dn%d", ctrl->subsys->instance, | ||
| 3011 | ctrl->cntlid, ns->head->instance); | ||
| 3012 | flags = GENHD_FL_HIDDEN; | ||
| 3013 | } else { | ||
| 3014 | sprintf(disk_name, "nvme%dn%d", ctrl->subsys->instance, | ||
| 3015 | ns->head->instance); | ||
| 3016 | } | ||
| 3017 | #else | ||
| 3018 | /* | ||
| 3019 | * But without the multipath code enabled, multiple controller per | ||
| 3020 | * subsystems are visible as devices and thus we cannot use the | ||
| 3021 | * subsystem instance. | ||
| 3022 | */ | ||
| 3023 | sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance); | ||
| 3024 | #endif | ||
| 3025 | 3008 | ||
| 3026 | if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) { | 3009 | if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) { |
| 3027 | if (nvme_nvm_register(ns, disk_name, node)) { | 3010 | if (nvme_nvm_register(ns, disk_name, node)) { |
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index 124c458806df..7ae732a77fe8 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c | |||
| @@ -668,6 +668,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, | |||
| 668 | ret = -ENOMEM; | 668 | ret = -ENOMEM; |
| 669 | goto out; | 669 | goto out; |
| 670 | } | 670 | } |
| 671 | kfree(opts->transport); | ||
| 671 | opts->transport = p; | 672 | opts->transport = p; |
| 672 | break; | 673 | break; |
| 673 | case NVMF_OPT_NQN: | 674 | case NVMF_OPT_NQN: |
| @@ -676,6 +677,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, | |||
| 676 | ret = -ENOMEM; | 677 | ret = -ENOMEM; |
| 677 | goto out; | 678 | goto out; |
| 678 | } | 679 | } |
| 680 | kfree(opts->subsysnqn); | ||
| 679 | opts->subsysnqn = p; | 681 | opts->subsysnqn = p; |
| 680 | nqnlen = strlen(opts->subsysnqn); | 682 | nqnlen = strlen(opts->subsysnqn); |
| 681 | if (nqnlen >= NVMF_NQN_SIZE) { | 683 | if (nqnlen >= NVMF_NQN_SIZE) { |
| @@ -698,6 +700,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, | |||
| 698 | ret = -ENOMEM; | 700 | ret = -ENOMEM; |
| 699 | goto out; | 701 | goto out; |
| 700 | } | 702 | } |
| 703 | kfree(opts->traddr); | ||
| 701 | opts->traddr = p; | 704 | opts->traddr = p; |
| 702 | break; | 705 | break; |
| 703 | case NVMF_OPT_TRSVCID: | 706 | case NVMF_OPT_TRSVCID: |
| @@ -706,6 +709,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, | |||
| 706 | ret = -ENOMEM; | 709 | ret = -ENOMEM; |
| 707 | goto out; | 710 | goto out; |
| 708 | } | 711 | } |
| 712 | kfree(opts->trsvcid); | ||
| 709 | opts->trsvcid = p; | 713 | opts->trsvcid = p; |
| 710 | break; | 714 | break; |
| 711 | case NVMF_OPT_QUEUE_SIZE: | 715 | case NVMF_OPT_QUEUE_SIZE: |
| @@ -792,6 +796,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, | |||
| 792 | ret = -EINVAL; | 796 | ret = -EINVAL; |
| 793 | goto out; | 797 | goto out; |
| 794 | } | 798 | } |
| 799 | nvmf_host_put(opts->host); | ||
| 795 | opts->host = nvmf_host_add(p); | 800 | opts->host = nvmf_host_add(p); |
| 796 | kfree(p); | 801 | kfree(p); |
| 797 | if (!opts->host) { | 802 | if (!opts->host) { |
| @@ -817,6 +822,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, | |||
| 817 | ret = -ENOMEM; | 822 | ret = -ENOMEM; |
| 818 | goto out; | 823 | goto out; |
| 819 | } | 824 | } |
| 825 | kfree(opts->host_traddr); | ||
| 820 | opts->host_traddr = p; | 826 | opts->host_traddr = p; |
| 821 | break; | 827 | break; |
| 822 | case NVMF_OPT_HOST_ID: | 828 | case NVMF_OPT_HOST_ID: |
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 956e0b8e9c4d..d7b664ae5923 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c | |||
| @@ -15,10 +15,32 @@ | |||
| 15 | #include "nvme.h" | 15 | #include "nvme.h" |
| 16 | 16 | ||
| 17 | static bool multipath = true; | 17 | static bool multipath = true; |
| 18 | module_param(multipath, bool, 0644); | 18 | module_param(multipath, bool, 0444); |
| 19 | MODULE_PARM_DESC(multipath, | 19 | MODULE_PARM_DESC(multipath, |
| 20 | "turn on native support for multiple controllers per subsystem"); | 20 | "turn on native support for multiple controllers per subsystem"); |
| 21 | 21 | ||
| 22 | /* | ||
| 23 | * If multipathing is enabled we need to always use the subsystem instance | ||
| 24 | * number for numbering our devices to avoid conflicts between subsystems that | ||
| 25 | * have multiple controllers and thus use the multipath-aware subsystem node | ||
| 26 | * and those that have a single controller and use the controller node | ||
| 27 | * directly. | ||
| 28 | */ | ||
| 29 | void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, | ||
| 30 | struct nvme_ctrl *ctrl, int *flags) | ||
| 31 | { | ||
| 32 | if (!multipath) { | ||
| 33 | sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance); | ||
| 34 | } else if (ns->head->disk) { | ||
| 35 | sprintf(disk_name, "nvme%dc%dn%d", ctrl->subsys->instance, | ||
| 36 | ctrl->cntlid, ns->head->instance); | ||
| 37 | *flags = GENHD_FL_HIDDEN; | ||
| 38 | } else { | ||
| 39 | sprintf(disk_name, "nvme%dn%d", ctrl->subsys->instance, | ||
| 40 | ns->head->instance); | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 22 | void nvme_failover_req(struct request *req) | 44 | void nvme_failover_req(struct request *req) |
| 23 | { | 45 | { |
| 24 | struct nvme_ns *ns = req->q->queuedata; | 46 | struct nvme_ns *ns = req->q->queuedata; |
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 061fecfd44f5..17d2f7cf3fed 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
| @@ -84,6 +84,11 @@ enum nvme_quirks { | |||
| 84 | * Supports the LighNVM command set if indicated in vs[1]. | 84 | * Supports the LighNVM command set if indicated in vs[1]. |
| 85 | */ | 85 | */ |
| 86 | NVME_QUIRK_LIGHTNVM = (1 << 6), | 86 | NVME_QUIRK_LIGHTNVM = (1 << 6), |
| 87 | |||
| 88 | /* | ||
| 89 | * Set MEDIUM priority on SQ creation | ||
| 90 | */ | ||
| 91 | NVME_QUIRK_MEDIUM_PRIO_SQ = (1 << 7), | ||
| 87 | }; | 92 | }; |
| 88 | 93 | ||
| 89 | /* | 94 | /* |
| @@ -436,6 +441,8 @@ extern const struct attribute_group nvme_ns_id_attr_group; | |||
| 436 | extern const struct block_device_operations nvme_ns_head_ops; | 441 | extern const struct block_device_operations nvme_ns_head_ops; |
| 437 | 442 | ||
| 438 | #ifdef CONFIG_NVME_MULTIPATH | 443 | #ifdef CONFIG_NVME_MULTIPATH |
| 444 | void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, | ||
| 445 | struct nvme_ctrl *ctrl, int *flags); | ||
| 439 | void nvme_failover_req(struct request *req); | 446 | void nvme_failover_req(struct request *req); |
| 440 | bool nvme_req_needs_failover(struct request *req, blk_status_t error); | 447 | bool nvme_req_needs_failover(struct request *req, blk_status_t error); |
| 441 | void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); | 448 | void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); |
| @@ -461,6 +468,16 @@ static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) | |||
| 461 | } | 468 | } |
| 462 | 469 | ||
| 463 | #else | 470 | #else |
| 471 | /* | ||
| 472 | * Without the multipath code enabled, multiple controller per subsystems are | ||
| 473 | * visible as devices and thus we cannot use the subsystem instance. | ||
| 474 | */ | ||
| 475 | static inline void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, | ||
| 476 | struct nvme_ctrl *ctrl, int *flags) | ||
| 477 | { | ||
| 478 | sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance); | ||
| 479 | } | ||
| 480 | |||
| 464 | static inline void nvme_failover_req(struct request *req) | 481 | static inline void nvme_failover_req(struct request *req) |
| 465 | { | 482 | { |
| 466 | } | 483 | } |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index fbc71fac6f1e..17a0190bd88f 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
| @@ -1093,10 +1093,19 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid, | |||
| 1093 | static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid, | 1093 | static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid, |
| 1094 | struct nvme_queue *nvmeq) | 1094 | struct nvme_queue *nvmeq) |
| 1095 | { | 1095 | { |
| 1096 | struct nvme_ctrl *ctrl = &dev->ctrl; | ||
| 1096 | struct nvme_command c; | 1097 | struct nvme_command c; |
| 1097 | int flags = NVME_QUEUE_PHYS_CONTIG; | 1098 | int flags = NVME_QUEUE_PHYS_CONTIG; |
| 1098 | 1099 | ||
| 1099 | /* | 1100 | /* |
| 1101 | * Some drives have a bug that auto-enables WRRU if MEDIUM isn't | ||
| 1102 | * set. Since URGENT priority is zeroes, it makes all queues | ||
| 1103 | * URGENT. | ||
| 1104 | */ | ||
| 1105 | if (ctrl->quirks & NVME_QUIRK_MEDIUM_PRIO_SQ) | ||
| 1106 | flags |= NVME_SQ_PRIO_MEDIUM; | ||
| 1107 | |||
| 1108 | /* | ||
| 1100 | * Note: we (ab)use the fact that the prp fields survive if no data | 1109 | * Note: we (ab)use the fact that the prp fields survive if no data |
| 1101 | * is attached to the request. | 1110 | * is attached to the request. |
| 1102 | */ | 1111 | */ |
| @@ -2701,7 +2710,8 @@ static const struct pci_device_id nvme_id_table[] = { | |||
| 2701 | .driver_data = NVME_QUIRK_STRIPE_SIZE | | 2710 | .driver_data = NVME_QUIRK_STRIPE_SIZE | |
| 2702 | NVME_QUIRK_DEALLOCATE_ZEROES, }, | 2711 | NVME_QUIRK_DEALLOCATE_ZEROES, }, |
| 2703 | { PCI_VDEVICE(INTEL, 0xf1a5), /* Intel 600P/P3100 */ | 2712 | { PCI_VDEVICE(INTEL, 0xf1a5), /* Intel 600P/P3100 */ |
| 2704 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS }, | 2713 | .driver_data = NVME_QUIRK_NO_DEEPEST_PS | |
| 2714 | NVME_QUIRK_MEDIUM_PRIO_SQ }, | ||
| 2705 | { PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */ | 2715 | { PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */ |
| 2706 | .driver_data = NVME_QUIRK_IDENTIFY_CNS, }, | 2716 | .driver_data = NVME_QUIRK_IDENTIFY_CNS, }, |
| 2707 | { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ | 2717 | { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ |
diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig index 5f4f8b16685f..3c7b61ddb0d1 100644 --- a/drivers/nvme/target/Kconfig +++ b/drivers/nvme/target/Kconfig | |||
| @@ -27,7 +27,7 @@ config NVME_TARGET_LOOP | |||
| 27 | 27 | ||
| 28 | config NVME_TARGET_RDMA | 28 | config NVME_TARGET_RDMA |
| 29 | tristate "NVMe over Fabrics RDMA target support" | 29 | tristate "NVMe over Fabrics RDMA target support" |
| 30 | depends on INFINIBAND | 30 | depends on INFINIBAND && INFINIBAND_ADDR_TRANS |
| 31 | depends on NVME_TARGET | 31 | depends on NVME_TARGET |
| 32 | select SGL_ALLOC | 32 | select SGL_ALLOC |
| 33 | help | 33 | help |
diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index 31fdfba556a8..27a8561c0cb9 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c | |||
| @@ -469,6 +469,12 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work) | |||
| 469 | nvme_stop_ctrl(&ctrl->ctrl); | 469 | nvme_stop_ctrl(&ctrl->ctrl); |
| 470 | nvme_loop_shutdown_ctrl(ctrl); | 470 | nvme_loop_shutdown_ctrl(ctrl); |
| 471 | 471 | ||
| 472 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { | ||
| 473 | /* state change failure should never happen */ | ||
| 474 | WARN_ON_ONCE(1); | ||
| 475 | return; | ||
| 476 | } | ||
| 477 | |||
| 472 | ret = nvme_loop_configure_admin_queue(ctrl); | 478 | ret = nvme_loop_configure_admin_queue(ctrl); |
| 473 | if (ret) | 479 | if (ret) |
| 474 | goto out_disable; | 480 | goto out_disable; |
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index b35fe88f1851..7baa53e5b1d7 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c | |||
| @@ -102,12 +102,28 @@ static DEFINE_IDR(ovcs_idr); | |||
| 102 | 102 | ||
| 103 | static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain); | 103 | static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain); |
| 104 | 104 | ||
| 105 | /** | ||
| 106 | * of_overlay_notifier_register() - Register notifier for overlay operations | ||
| 107 | * @nb: Notifier block to register | ||
| 108 | * | ||
| 109 | * Register for notification on overlay operations on device tree nodes. The | ||
| 110 | * reported actions definied by @of_reconfig_change. The notifier callback | ||
| 111 | * furthermore receives a pointer to the affected device tree node. | ||
| 112 | * | ||
| 113 | * Note that a notifier callback is not supposed to store pointers to a device | ||
| 114 | * tree node or its content beyond @OF_OVERLAY_POST_REMOVE corresponding to the | ||
| 115 | * respective node it received. | ||
| 116 | */ | ||
| 105 | int of_overlay_notifier_register(struct notifier_block *nb) | 117 | int of_overlay_notifier_register(struct notifier_block *nb) |
| 106 | { | 118 | { |
| 107 | return blocking_notifier_chain_register(&overlay_notify_chain, nb); | 119 | return blocking_notifier_chain_register(&overlay_notify_chain, nb); |
| 108 | } | 120 | } |
| 109 | EXPORT_SYMBOL_GPL(of_overlay_notifier_register); | 121 | EXPORT_SYMBOL_GPL(of_overlay_notifier_register); |
| 110 | 122 | ||
| 123 | /** | ||
| 124 | * of_overlay_notifier_register() - Unregister notifier for overlay operations | ||
| 125 | * @nb: Notifier block to unregister | ||
| 126 | */ | ||
| 111 | int of_overlay_notifier_unregister(struct notifier_block *nb) | 127 | int of_overlay_notifier_unregister(struct notifier_block *nb) |
| 112 | { | 128 | { |
| 113 | return blocking_notifier_chain_unregister(&overlay_notify_chain, nb); | 129 | return blocking_notifier_chain_unregister(&overlay_notify_chain, nb); |
| @@ -671,17 +687,13 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) | |||
| 671 | of_node_put(ovcs->fragments[i].overlay); | 687 | of_node_put(ovcs->fragments[i].overlay); |
| 672 | } | 688 | } |
| 673 | kfree(ovcs->fragments); | 689 | kfree(ovcs->fragments); |
| 674 | |||
| 675 | /* | 690 | /* |
| 676 | * TODO | 691 | * There should be no live pointers into ovcs->overlay_tree and |
| 677 | * | 692 | * ovcs->fdt due to the policy that overlay notifiers are not allowed |
| 678 | * would like to: kfree(ovcs->overlay_tree); | 693 | * to retain pointers into the overlay devicetree. |
| 679 | * but can not since drivers may have pointers into this data | ||
| 680 | * | ||
| 681 | * would like to: kfree(ovcs->fdt); | ||
| 682 | * but can not since drivers may have pointers into this data | ||
| 683 | */ | 694 | */ |
| 684 | 695 | kfree(ovcs->overlay_tree); | |
| 696 | kfree(ovcs->fdt); | ||
| 685 | kfree(ovcs); | 697 | kfree(ovcs); |
| 686 | } | 698 | } |
| 687 | 699 | ||
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index acba1f56af3e..297599fcbc32 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
| @@ -1195,7 +1195,7 @@ void * ccio_get_iommu(const struct parisc_device *dev) | |||
| 1195 | * to/from certain pages. To avoid this happening, we mark these pages | 1195 | * to/from certain pages. To avoid this happening, we mark these pages |
| 1196 | * as `used', and ensure that nothing will try to allocate from them. | 1196 | * as `used', and ensure that nothing will try to allocate from them. |
| 1197 | */ | 1197 | */ |
| 1198 | void ccio_cujo20_fixup(struct parisc_device *cujo, u32 iovp) | 1198 | void __init ccio_cujo20_fixup(struct parisc_device *cujo, u32 iovp) |
| 1199 | { | 1199 | { |
| 1200 | unsigned int idx; | 1200 | unsigned int idx; |
| 1201 | struct parisc_device *dev = parisc_parent(cujo); | 1201 | struct parisc_device *dev = parisc_parent(cujo); |
| @@ -1263,7 +1263,7 @@ static struct parisc_driver ccio_driver __refdata = { | |||
| 1263 | * I/O Page Directory, the resource map, and initalizing the | 1263 | * I/O Page Directory, the resource map, and initalizing the |
| 1264 | * U2/Uturn chip into virtual mode. | 1264 | * U2/Uturn chip into virtual mode. |
| 1265 | */ | 1265 | */ |
| 1266 | static void | 1266 | static void __init |
| 1267 | ccio_ioc_init(struct ioc *ioc) | 1267 | ccio_ioc_init(struct ioc *ioc) |
| 1268 | { | 1268 | { |
| 1269 | int i; | 1269 | int i; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a04197ce767d..dbfe7c4f3776 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1910,7 +1910,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
| 1910 | EXPORT_SYMBOL(pci_pme_active); | 1910 | EXPORT_SYMBOL(pci_pme_active); |
| 1911 | 1911 | ||
| 1912 | /** | 1912 | /** |
| 1913 | * pci_enable_wake - enable PCI device as wakeup event source | 1913 | * __pci_enable_wake - enable PCI device as wakeup event source |
| 1914 | * @dev: PCI device affected | 1914 | * @dev: PCI device affected |
| 1915 | * @state: PCI state from which device will issue wakeup events | 1915 | * @state: PCI state from which device will issue wakeup events |
| 1916 | * @enable: True to enable event generation; false to disable | 1916 | * @enable: True to enable event generation; false to disable |
| @@ -1928,7 +1928,7 @@ EXPORT_SYMBOL(pci_pme_active); | |||
| 1928 | * Error code depending on the platform is returned if both the platform and | 1928 | * Error code depending on the platform is returned if both the platform and |
| 1929 | * the native mechanism fail to enable the generation of wake-up events | 1929 | * the native mechanism fail to enable the generation of wake-up events |
| 1930 | */ | 1930 | */ |
| 1931 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) | 1931 | static int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) |
| 1932 | { | 1932 | { |
| 1933 | int ret = 0; | 1933 | int ret = 0; |
| 1934 | 1934 | ||
| @@ -1969,6 +1969,23 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) | |||
| 1969 | 1969 | ||
| 1970 | return ret; | 1970 | return ret; |
| 1971 | } | 1971 | } |
| 1972 | |||
| 1973 | /** | ||
| 1974 | * pci_enable_wake - change wakeup settings for a PCI device | ||
| 1975 | * @pci_dev: Target device | ||
| 1976 | * @state: PCI state from which device will issue wakeup events | ||
| 1977 | * @enable: Whether or not to enable event generation | ||
| 1978 | * | ||
| 1979 | * If @enable is set, check device_may_wakeup() for the device before calling | ||
| 1980 | * __pci_enable_wake() for it. | ||
| 1981 | */ | ||
| 1982 | int pci_enable_wake(struct pci_dev *pci_dev, pci_power_t state, bool enable) | ||
| 1983 | { | ||
| 1984 | if (enable && !device_may_wakeup(&pci_dev->dev)) | ||
| 1985 | return -EINVAL; | ||
| 1986 | |||
| 1987 | return __pci_enable_wake(pci_dev, state, enable); | ||
| 1988 | } | ||
| 1972 | EXPORT_SYMBOL(pci_enable_wake); | 1989 | EXPORT_SYMBOL(pci_enable_wake); |
| 1973 | 1990 | ||
| 1974 | /** | 1991 | /** |
| @@ -1981,9 +1998,9 @@ EXPORT_SYMBOL(pci_enable_wake); | |||
| 1981 | * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI | 1998 | * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI |
| 1982 | * ordering constraints. | 1999 | * ordering constraints. |
| 1983 | * | 2000 | * |
| 1984 | * This function only returns error code if the device is not capable of | 2001 | * This function only returns error code if the device is not allowed to wake |
| 1985 | * generating PME# from both D3_hot and D3_cold, and the platform is unable to | 2002 | * up the system from sleep or it is not capable of generating PME# from both |
| 1986 | * enable wake-up power for it. | 2003 | * D3_hot and D3_cold and the platform is unable to enable wake-up power for it. |
| 1987 | */ | 2004 | */ |
| 1988 | int pci_wake_from_d3(struct pci_dev *dev, bool enable) | 2005 | int pci_wake_from_d3(struct pci_dev *dev, bool enable) |
| 1989 | { | 2006 | { |
| @@ -2114,7 +2131,7 @@ int pci_finish_runtime_suspend(struct pci_dev *dev) | |||
| 2114 | 2131 | ||
| 2115 | dev->runtime_d3cold = target_state == PCI_D3cold; | 2132 | dev->runtime_d3cold = target_state == PCI_D3cold; |
| 2116 | 2133 | ||
| 2117 | pci_enable_wake(dev, target_state, pci_dev_run_wake(dev)); | 2134 | __pci_enable_wake(dev, target_state, pci_dev_run_wake(dev)); |
| 2118 | 2135 | ||
| 2119 | error = pci_set_power_state(dev, target_state); | 2136 | error = pci_set_power_state(dev, target_state); |
| 2120 | 2137 | ||
| @@ -2138,16 +2155,16 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
| 2138 | { | 2155 | { |
| 2139 | struct pci_bus *bus = dev->bus; | 2156 | struct pci_bus *bus = dev->bus; |
| 2140 | 2157 | ||
| 2141 | if (device_can_wakeup(&dev->dev)) | ||
| 2142 | return true; | ||
| 2143 | |||
| 2144 | if (!dev->pme_support) | 2158 | if (!dev->pme_support) |
| 2145 | return false; | 2159 | return false; |
| 2146 | 2160 | ||
| 2147 | /* PME-capable in principle, but not from the target power state */ | 2161 | /* PME-capable in principle, but not from the target power state */ |
| 2148 | if (!pci_pme_capable(dev, pci_target_state(dev, false))) | 2162 | if (!pci_pme_capable(dev, pci_target_state(dev, true))) |
| 2149 | return false; | 2163 | return false; |
| 2150 | 2164 | ||
| 2165 | if (device_can_wakeup(&dev->dev)) | ||
| 2166 | return true; | ||
| 2167 | |||
| 2151 | while (bus->parent) { | 2168 | while (bus->parent) { |
| 2152 | struct pci_dev *bridge = bus->self; | 2169 | struct pci_dev *bridge = bus->self; |
| 2153 | 2170 | ||
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index b1ae1618fefe..fee9225ca559 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c | |||
| @@ -1622,22 +1622,30 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) | |||
| 1622 | 1622 | ||
| 1623 | if (!need_valid_mask) { | 1623 | if (!need_valid_mask) { |
| 1624 | irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, | 1624 | irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, |
| 1625 | chip->ngpio, NUMA_NO_NODE); | 1625 | community->npins, NUMA_NO_NODE); |
| 1626 | if (irq_base < 0) { | 1626 | if (irq_base < 0) { |
| 1627 | dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); | 1627 | dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); |
| 1628 | return irq_base; | 1628 | return irq_base; |
| 1629 | } | 1629 | } |
| 1630 | } else { | ||
| 1631 | irq_base = 0; | ||
| 1632 | } | 1630 | } |
| 1633 | 1631 | ||
| 1634 | ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, irq_base, | 1632 | ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0, |
| 1635 | handle_bad_irq, IRQ_TYPE_NONE); | 1633 | handle_bad_irq, IRQ_TYPE_NONE); |
| 1636 | if (ret) { | 1634 | if (ret) { |
| 1637 | dev_err(pctrl->dev, "failed to add IRQ chip\n"); | 1635 | dev_err(pctrl->dev, "failed to add IRQ chip\n"); |
| 1638 | return ret; | 1636 | return ret; |
| 1639 | } | 1637 | } |
| 1640 | 1638 | ||
| 1639 | if (!need_valid_mask) { | ||
| 1640 | for (i = 0; i < community->ngpio_ranges; i++) { | ||
| 1641 | range = &community->gpio_ranges[i]; | ||
| 1642 | |||
| 1643 | irq_domain_associate_many(chip->irq.domain, irq_base, | ||
| 1644 | range->base, range->npins); | ||
| 1645 | irq_base += range->npins; | ||
| 1646 | } | ||
| 1647 | } | ||
| 1648 | |||
| 1641 | gpiochip_set_chained_irqchip(chip, &chv_gpio_irqchip, irq, | 1649 | gpiochip_set_chained_irqchip(chip, &chv_gpio_irqchip, irq, |
| 1642 | chv_gpio_irq_handler); | 1650 | chv_gpio_irq_handler); |
| 1643 | return 0; | 1651 | return 0; |
diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c index 8870a4100164..fee3435a6f15 100644 --- a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c +++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c | |||
| @@ -36,6 +36,27 @@ | |||
| 36 | .npins = ((e) - (s) + 1), \ | 36 | .npins = ((e) - (s) + 1), \ |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | #define SPTH_GPP(r, s, e, g) \ | ||
| 40 | { \ | ||
| 41 | .reg_num = (r), \ | ||
| 42 | .base = (s), \ | ||
| 43 | .size = ((e) - (s) + 1), \ | ||
| 44 | .gpio_base = (g), \ | ||
| 45 | } | ||
| 46 | |||
| 47 | #define SPTH_COMMUNITY(b, s, e, g) \ | ||
| 48 | { \ | ||
| 49 | .barno = (b), \ | ||
| 50 | .padown_offset = SPT_PAD_OWN, \ | ||
| 51 | .padcfglock_offset = SPT_PADCFGLOCK, \ | ||
| 52 | .hostown_offset = SPT_HOSTSW_OWN, \ | ||
| 53 | .ie_offset = SPT_GPI_IE, \ | ||
| 54 | .pin_base = (s), \ | ||
| 55 | .npins = ((e) - (s) + 1), \ | ||
| 56 | .gpps = (g), \ | ||
| 57 | .ngpps = ARRAY_SIZE(g), \ | ||
| 58 | } | ||
| 59 | |||
| 39 | /* Sunrisepoint-LP */ | 60 | /* Sunrisepoint-LP */ |
| 40 | static const struct pinctrl_pin_desc sptlp_pins[] = { | 61 | static const struct pinctrl_pin_desc sptlp_pins[] = { |
| 41 | /* GPP_A */ | 62 | /* GPP_A */ |
| @@ -531,10 +552,28 @@ static const struct intel_function spth_functions[] = { | |||
| 531 | FUNCTION("i2c2", spth_i2c2_groups), | 552 | FUNCTION("i2c2", spth_i2c2_groups), |
| 532 | }; | 553 | }; |
| 533 | 554 | ||
| 555 | static const struct intel_padgroup spth_community0_gpps[] = { | ||
| 556 | SPTH_GPP(0, 0, 23, 0), /* GPP_A */ | ||
| 557 | SPTH_GPP(1, 24, 47, 24), /* GPP_B */ | ||
| 558 | }; | ||
| 559 | |||
| 560 | static const struct intel_padgroup spth_community1_gpps[] = { | ||
| 561 | SPTH_GPP(0, 48, 71, 48), /* GPP_C */ | ||
| 562 | SPTH_GPP(1, 72, 95, 72), /* GPP_D */ | ||
| 563 | SPTH_GPP(2, 96, 108, 96), /* GPP_E */ | ||
| 564 | SPTH_GPP(3, 109, 132, 120), /* GPP_F */ | ||
| 565 | SPTH_GPP(4, 133, 156, 144), /* GPP_G */ | ||
| 566 | SPTH_GPP(5, 157, 180, 168), /* GPP_H */ | ||
| 567 | }; | ||
| 568 | |||
| 569 | static const struct intel_padgroup spth_community3_gpps[] = { | ||
| 570 | SPTH_GPP(0, 181, 191, 192), /* GPP_I */ | ||
| 571 | }; | ||
| 572 | |||
| 534 | static const struct intel_community spth_communities[] = { | 573 | static const struct intel_community spth_communities[] = { |
| 535 | SPT_COMMUNITY(0, 0, 47), | 574 | SPTH_COMMUNITY(0, 0, 47, spth_community0_gpps), |
| 536 | SPT_COMMUNITY(1, 48, 180), | 575 | SPTH_COMMUNITY(1, 48, 180, spth_community1_gpps), |
| 537 | SPT_COMMUNITY(2, 181, 191), | 576 | SPTH_COMMUNITY(2, 181, 191, spth_community3_gpps), |
| 538 | }; | 577 | }; |
| 539 | 578 | ||
| 540 | static const struct intel_pinctrl_soc_data spth_soc_data = { | 579 | static const struct intel_pinctrl_soc_data spth_soc_data = { |
diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.c b/drivers/pinctrl/meson/pinctrl-meson-axg.c index 4b91ff74779b..99a6ceac8e53 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-axg.c +++ b/drivers/pinctrl/meson/pinctrl-meson-axg.c | |||
| @@ -898,7 +898,7 @@ static struct meson_bank meson_axg_periphs_banks[] = { | |||
| 898 | 898 | ||
| 899 | static struct meson_bank meson_axg_aobus_banks[] = { | 899 | static struct meson_bank meson_axg_aobus_banks[] = { |
| 900 | /* name first last irq pullen pull dir out in */ | 900 | /* name first last irq pullen pull dir out in */ |
| 901 | BANK("AO", GPIOAO_0, GPIOAO_9, 0, 13, 0, 16, 0, 0, 0, 0, 0, 16, 1, 0), | 901 | BANK("AO", GPIOAO_0, GPIOAO_13, 0, 13, 0, 16, 0, 0, 0, 0, 0, 16, 1, 0), |
| 902 | }; | 902 | }; |
| 903 | 903 | ||
| 904 | static struct meson_pmx_bank meson_axg_periphs_pmx_banks[] = { | 904 | static struct meson_pmx_bank meson_axg_periphs_pmx_banks[] = { |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 39d06dd1f63a..566644bb496a 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
| @@ -154,7 +154,7 @@ config DELL_LAPTOP | |||
| 154 | depends on ACPI_VIDEO || ACPI_VIDEO = n | 154 | depends on ACPI_VIDEO || ACPI_VIDEO = n |
| 155 | depends on RFKILL || RFKILL = n | 155 | depends on RFKILL || RFKILL = n |
| 156 | depends on SERIO_I8042 | 156 | depends on SERIO_I8042 |
| 157 | select DELL_SMBIOS | 157 | depends on DELL_SMBIOS |
| 158 | select POWER_SUPPLY | 158 | select POWER_SUPPLY |
| 159 | select LEDS_CLASS | 159 | select LEDS_CLASS |
| 160 | select NEW_LEDS | 160 | select NEW_LEDS |
| @@ -168,8 +168,8 @@ config DELL_WMI | |||
| 168 | depends on DMI | 168 | depends on DMI |
| 169 | depends on INPUT | 169 | depends on INPUT |
| 170 | depends on ACPI_VIDEO || ACPI_VIDEO = n | 170 | depends on ACPI_VIDEO || ACPI_VIDEO = n |
| 171 | depends on DELL_SMBIOS | ||
| 171 | select DELL_WMI_DESCRIPTOR | 172 | select DELL_WMI_DESCRIPTOR |
| 172 | select DELL_SMBIOS | ||
| 173 | select INPUT_SPARSEKMAP | 173 | select INPUT_SPARSEKMAP |
| 174 | ---help--- | 174 | ---help--- |
| 175 | Say Y here if you want to support WMI-based hotkeys on Dell laptops. | 175 | Say Y here if you want to support WMI-based hotkeys on Dell laptops. |
diff --git a/drivers/platform/x86/asus-wireless.c b/drivers/platform/x86/asus-wireless.c index d4aeac3477f5..f086469ea740 100644 --- a/drivers/platform/x86/asus-wireless.c +++ b/drivers/platform/x86/asus-wireless.c | |||
| @@ -178,8 +178,10 @@ static int asus_wireless_remove(struct acpi_device *adev) | |||
| 178 | { | 178 | { |
| 179 | struct asus_wireless_data *data = acpi_driver_data(adev); | 179 | struct asus_wireless_data *data = acpi_driver_data(adev); |
| 180 | 180 | ||
| 181 | if (data->wq) | 181 | if (data->wq) { |
| 182 | devm_led_classdev_unregister(&adev->dev, &data->led); | ||
| 182 | destroy_workqueue(data->wq); | 183 | destroy_workqueue(data->wq); |
| 184 | } | ||
| 183 | return 0; | 185 | return 0; |
| 184 | } | 186 | } |
| 185 | 187 | ||
diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c index 8e70a627e0bb..cbbafdcaaecb 100644 --- a/drivers/remoteproc/qcom_q6v5_pil.c +++ b/drivers/remoteproc/qcom_q6v5_pil.c | |||
| @@ -1083,6 +1083,7 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc) | |||
| 1083 | dev_err(qproc->dev, "unable to resolve mba region\n"); | 1083 | dev_err(qproc->dev, "unable to resolve mba region\n"); |
| 1084 | return ret; | 1084 | return ret; |
| 1085 | } | 1085 | } |
| 1086 | of_node_put(node); | ||
| 1086 | 1087 | ||
| 1087 | qproc->mba_phys = r.start; | 1088 | qproc->mba_phys = r.start; |
| 1088 | qproc->mba_size = resource_size(&r); | 1089 | qproc->mba_size = resource_size(&r); |
| @@ -1100,6 +1101,7 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc) | |||
| 1100 | dev_err(qproc->dev, "unable to resolve mpss region\n"); | 1101 | dev_err(qproc->dev, "unable to resolve mpss region\n"); |
| 1101 | return ret; | 1102 | return ret; |
| 1102 | } | 1103 | } |
| 1104 | of_node_put(node); | ||
| 1103 | 1105 | ||
| 1104 | qproc->mpss_phys = qproc->mpss_reloc = r.start; | 1106 | qproc->mpss_phys = qproc->mpss_reloc = r.start; |
| 1105 | qproc->mpss_size = resource_size(&r); | 1107 | qproc->mpss_size = resource_size(&r); |
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 6d9c5832ce47..a9609d971f7f 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
| @@ -1163,7 +1163,7 @@ int rproc_trigger_recovery(struct rproc *rproc) | |||
| 1163 | if (ret) | 1163 | if (ret) |
| 1164 | return ret; | 1164 | return ret; |
| 1165 | 1165 | ||
| 1166 | ret = rproc_stop(rproc, false); | 1166 | ret = rproc_stop(rproc, true); |
| 1167 | if (ret) | 1167 | if (ret) |
| 1168 | goto unlock_mutex; | 1168 | goto unlock_mutex; |
| 1169 | 1169 | ||
| @@ -1316,7 +1316,7 @@ void rproc_shutdown(struct rproc *rproc) | |||
| 1316 | if (!atomic_dec_and_test(&rproc->power)) | 1316 | if (!atomic_dec_and_test(&rproc->power)) |
| 1317 | goto out; | 1317 | goto out; |
| 1318 | 1318 | ||
| 1319 | ret = rproc_stop(rproc, true); | 1319 | ret = rproc_stop(rproc, false); |
| 1320 | if (ret) { | 1320 | if (ret) { |
| 1321 | atomic_inc(&rproc->power); | 1321 | atomic_inc(&rproc->power); |
| 1322 | goto out; | 1322 | goto out; |
diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index 360e06b20c53..ac18f2f27881 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c | |||
| @@ -110,7 +110,7 @@ static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { | |||
| 110 | UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ | 110 | UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ |
| 111 | UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ | 111 | UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ |
| 112 | UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC) */ | 112 | UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC) */ |
| 113 | UNIPHIER_RESETX(12, 0x200c, 5), /* GIO (PCIe, USB3) */ | 113 | UNIPHIER_RESETX(14, 0x200c, 5), /* USB30 */ |
| 114 | UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */ | 114 | UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */ |
| 115 | UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */ | 115 | UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */ |
| 116 | UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */ | 116 | UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */ |
| @@ -127,8 +127,8 @@ static const struct uniphier_reset_data uniphier_pxs3_sys_reset_data[] = { | |||
| 127 | UNIPHIER_RESETX(6, 0x200c, 9), /* Ether0 */ | 127 | UNIPHIER_RESETX(6, 0x200c, 9), /* Ether0 */ |
| 128 | UNIPHIER_RESETX(7, 0x200c, 10), /* Ether1 */ | 128 | UNIPHIER_RESETX(7, 0x200c, 10), /* Ether1 */ |
| 129 | UNIPHIER_RESETX(8, 0x200c, 12), /* STDMAC */ | 129 | UNIPHIER_RESETX(8, 0x200c, 12), /* STDMAC */ |
| 130 | UNIPHIER_RESETX(12, 0x200c, 4), /* USB30 link (GIO0) */ | 130 | UNIPHIER_RESETX(12, 0x200c, 4), /* USB30 link */ |
| 131 | UNIPHIER_RESETX(13, 0x200c, 5), /* USB31 link (GIO1) */ | 131 | UNIPHIER_RESETX(13, 0x200c, 5), /* USB31 link */ |
| 132 | UNIPHIER_RESETX(16, 0x200c, 16), /* USB30-PHY0 */ | 132 | UNIPHIER_RESETX(16, 0x200c, 16), /* USB30-PHY0 */ |
| 133 | UNIPHIER_RESETX(17, 0x200c, 18), /* USB30-PHY1 */ | 133 | UNIPHIER_RESETX(17, 0x200c, 18), /* USB30-PHY1 */ |
| 134 | UNIPHIER_RESETX(18, 0x200c, 20), /* USB30-PHY2 */ | 134 | UNIPHIER_RESETX(18, 0x200c, 20), /* USB30-PHY2 */ |
diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c index 64b6de9763ee..1efdf9ff8679 100644 --- a/drivers/rpmsg/rpmsg_char.c +++ b/drivers/rpmsg/rpmsg_char.c | |||
| @@ -581,4 +581,6 @@ static void rpmsg_chrdev_exit(void) | |||
| 581 | unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX); | 581 | unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX); |
| 582 | } | 582 | } |
| 583 | module_exit(rpmsg_chrdev_exit); | 583 | module_exit(rpmsg_chrdev_exit); |
| 584 | |||
| 585 | MODULE_ALIAS("rpmsg:rpmsg_chrdev"); | ||
| 584 | MODULE_LICENSE("GPL v2"); | 586 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 439991d71b14..4c14ce428e92 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c | |||
| @@ -141,7 +141,7 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) | |||
| 141 | int i; | 141 | int i; |
| 142 | 142 | ||
| 143 | for (i = 0; i < nr_queues; i++) { | 143 | for (i = 0; i < nr_queues; i++) { |
| 144 | q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); | 144 | q = kmem_cache_zalloc(qdio_q_cache, GFP_KERNEL); |
| 145 | if (!q) | 145 | if (!q) |
| 146 | return -ENOMEM; | 146 | return -ENOMEM; |
| 147 | 147 | ||
| @@ -456,7 +456,6 @@ int qdio_setup_irq(struct qdio_initialize *init_data) | |||
| 456 | { | 456 | { |
| 457 | struct ciw *ciw; | 457 | struct ciw *ciw; |
| 458 | struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data; | 458 | struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data; |
| 459 | int rc; | ||
| 460 | 459 | ||
| 461 | memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib)); | 460 | memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib)); |
| 462 | memset(&irq_ptr->siga_flag, 0, sizeof(irq_ptr->siga_flag)); | 461 | memset(&irq_ptr->siga_flag, 0, sizeof(irq_ptr->siga_flag)); |
| @@ -493,16 +492,14 @@ int qdio_setup_irq(struct qdio_initialize *init_data) | |||
| 493 | ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_EQUEUE); | 492 | ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_EQUEUE); |
| 494 | if (!ciw) { | 493 | if (!ciw) { |
| 495 | DBF_ERROR("%4x NO EQ", irq_ptr->schid.sch_no); | 494 | DBF_ERROR("%4x NO EQ", irq_ptr->schid.sch_no); |
| 496 | rc = -EINVAL; | 495 | return -EINVAL; |
| 497 | goto out_err; | ||
| 498 | } | 496 | } |
| 499 | irq_ptr->equeue = *ciw; | 497 | irq_ptr->equeue = *ciw; |
| 500 | 498 | ||
| 501 | ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_AQUEUE); | 499 | ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_AQUEUE); |
| 502 | if (!ciw) { | 500 | if (!ciw) { |
| 503 | DBF_ERROR("%4x NO AQ", irq_ptr->schid.sch_no); | 501 | DBF_ERROR("%4x NO AQ", irq_ptr->schid.sch_no); |
| 504 | rc = -EINVAL; | 502 | return -EINVAL; |
| 505 | goto out_err; | ||
| 506 | } | 503 | } |
| 507 | irq_ptr->aqueue = *ciw; | 504 | irq_ptr->aqueue = *ciw; |
| 508 | 505 | ||
| @@ -512,9 +509,6 @@ int qdio_setup_irq(struct qdio_initialize *init_data) | |||
| 512 | init_data->cdev->handler = qdio_int_handler; | 509 | init_data->cdev->handler = qdio_int_handler; |
| 513 | spin_unlock_irq(get_ccwdev_lock(irq_ptr->cdev)); | 510 | spin_unlock_irq(get_ccwdev_lock(irq_ptr->cdev)); |
| 514 | return 0; | 511 | return 0; |
| 515 | out_err: | ||
| 516 | qdio_release_memory(irq_ptr); | ||
| 517 | return rc; | ||
| 518 | } | 512 | } |
| 519 | 513 | ||
| 520 | void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, | 514 | void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, |
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index 2c7550797ec2..dce92b2a895d 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c | |||
| @@ -715,6 +715,10 @@ void cp_free(struct channel_program *cp) | |||
| 715 | * and stores the result to ccwchain list. @cp must have been | 715 | * and stores the result to ccwchain list. @cp must have been |
| 716 | * initialized by a previous call with cp_init(). Otherwise, undefined | 716 | * initialized by a previous call with cp_init(). Otherwise, undefined |
| 717 | * behavior occurs. | 717 | * behavior occurs. |
| 718 | * For each chain composing the channel program: | ||
| 719 | * - On entry ch_len holds the count of CCWs to be translated. | ||
| 720 | * - On exit ch_len is adjusted to the count of successfully translated CCWs. | ||
| 721 | * This allows cp_free to find in ch_len the count of CCWs to free in a chain. | ||
| 718 | * | 722 | * |
| 719 | * The S/390 CCW Translation APIS (prefixed by 'cp_') are introduced | 723 | * The S/390 CCW Translation APIS (prefixed by 'cp_') are introduced |
| 720 | * as helpers to do ccw chain translation inside the kernel. Basically | 724 | * as helpers to do ccw chain translation inside the kernel. Basically |
| @@ -749,11 +753,18 @@ int cp_prefetch(struct channel_program *cp) | |||
| 749 | for (idx = 0; idx < len; idx++) { | 753 | for (idx = 0; idx < len; idx++) { |
| 750 | ret = ccwchain_fetch_one(chain, idx, cp); | 754 | ret = ccwchain_fetch_one(chain, idx, cp); |
| 751 | if (ret) | 755 | if (ret) |
| 752 | return ret; | 756 | goto out_err; |
| 753 | } | 757 | } |
| 754 | } | 758 | } |
| 755 | 759 | ||
| 756 | return 0; | 760 | return 0; |
| 761 | out_err: | ||
| 762 | /* Only cleanup the chain elements that were actually translated. */ | ||
| 763 | chain->ch_len = idx; | ||
| 764 | list_for_each_entry_continue(chain, &cp->ccwchain_list, next) { | ||
| 765 | chain->ch_len = 0; | ||
| 766 | } | ||
| 767 | return ret; | ||
| 757 | } | 768 | } |
| 758 | 769 | ||
| 759 | /** | 770 | /** |
diff --git a/drivers/sbus/char/oradax.c b/drivers/sbus/char/oradax.c index c44d7c7ffc92..1754f55e2fac 100644 --- a/drivers/sbus/char/oradax.c +++ b/drivers/sbus/char/oradax.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * This program is free software: you can redistribute it and/or modify | 4 | * This program is free software: you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation, either version 3 of the License, or | 6 | * the Free Software Foundation, either version 2 of the License, or |
| 7 | * (at your option) any later version. | 7 | * (at your option) any later version. |
| 8 | * | 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, | 9 | * This program is distributed in the hope that it will be useful, |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 0156c9623c35..d62ddd63f4fe 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
| @@ -724,6 +724,8 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback, | |||
| 724 | int wait; | 724 | int wait; |
| 725 | unsigned long flags = 0; | 725 | unsigned long flags = 0; |
| 726 | unsigned long mflags = 0; | 726 | unsigned long mflags = 0; |
| 727 | struct aac_hba_cmd_req *hbacmd = (struct aac_hba_cmd_req *) | ||
| 728 | fibptr->hw_fib_va; | ||
| 727 | 729 | ||
| 728 | fibptr->flags = (FIB_CONTEXT_FLAG | FIB_CONTEXT_FLAG_NATIVE_HBA); | 730 | fibptr->flags = (FIB_CONTEXT_FLAG | FIB_CONTEXT_FLAG_NATIVE_HBA); |
| 729 | if (callback) { | 731 | if (callback) { |
| @@ -734,11 +736,9 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback, | |||
| 734 | wait = 1; | 736 | wait = 1; |
| 735 | 737 | ||
| 736 | 738 | ||
| 737 | if (command == HBA_IU_TYPE_SCSI_CMD_REQ) { | 739 | hbacmd->iu_type = command; |
| 738 | struct aac_hba_cmd_req *hbacmd = | ||
| 739 | (struct aac_hba_cmd_req *)fibptr->hw_fib_va; | ||
| 740 | 740 | ||
| 741 | hbacmd->iu_type = command; | 741 | if (command == HBA_IU_TYPE_SCSI_CMD_REQ) { |
| 742 | /* bit1 of request_id must be 0 */ | 742 | /* bit1 of request_id must be 0 */ |
| 743 | hbacmd->request_id = | 743 | hbacmd->request_id = |
| 744 | cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1); | 744 | cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1); |
diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c index edb7be786c65..9e8de1462593 100644 --- a/drivers/scsi/isci/port_config.c +++ b/drivers/scsi/isci/port_config.c | |||
| @@ -291,7 +291,7 @@ sci_mpc_agent_validate_phy_configuration(struct isci_host *ihost, | |||
| 291 | * Note: We have not moved the current phy_index so we will actually | 291 | * Note: We have not moved the current phy_index so we will actually |
| 292 | * compare the startting phy with itself. | 292 | * compare the startting phy with itself. |
| 293 | * This is expected and required to add the phy to the port. */ | 293 | * This is expected and required to add the phy to the port. */ |
| 294 | while (phy_index < SCI_MAX_PHYS) { | 294 | for (; phy_index < SCI_MAX_PHYS; phy_index++) { |
| 295 | if ((phy_mask & (1 << phy_index)) == 0) | 295 | if ((phy_mask & (1 << phy_index)) == 0) |
| 296 | continue; | 296 | continue; |
| 297 | sci_phy_get_sas_address(&ihost->phys[phy_index], | 297 | sci_phy_get_sas_address(&ihost->phys[phy_index], |
| @@ -311,7 +311,6 @@ sci_mpc_agent_validate_phy_configuration(struct isci_host *ihost, | |||
| 311 | &ihost->phys[phy_index]); | 311 | &ihost->phys[phy_index]); |
| 312 | 312 | ||
| 313 | assigned_phy_mask |= (1 << phy_index); | 313 | assigned_phy_mask |= (1 << phy_index); |
| 314 | phy_index++; | ||
| 315 | } | 314 | } |
| 316 | 315 | ||
| 317 | } | 316 | } |
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 8c51d628b52e..a2ec0bc9e9fa 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c | |||
| @@ -1722,11 +1722,14 @@ static int storvsc_probe(struct hv_device *device, | |||
| 1722 | max_targets = STORVSC_MAX_TARGETS; | 1722 | max_targets = STORVSC_MAX_TARGETS; |
| 1723 | max_channels = STORVSC_MAX_CHANNELS; | 1723 | max_channels = STORVSC_MAX_CHANNELS; |
| 1724 | /* | 1724 | /* |
| 1725 | * On Windows8 and above, we support sub-channels for storage. | 1725 | * On Windows8 and above, we support sub-channels for storage |
| 1726 | * on SCSI and FC controllers. | ||
| 1726 | * The number of sub-channels offerred is based on the number of | 1727 | * The number of sub-channels offerred is based on the number of |
| 1727 | * VCPUs in the guest. | 1728 | * VCPUs in the guest. |
| 1728 | */ | 1729 | */ |
| 1729 | max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel); | 1730 | if (!dev_is_ide) |
| 1731 | max_sub_channels = | ||
| 1732 | (num_cpus - 1) / storvsc_vcpus_per_sub_channel; | ||
| 1730 | } | 1733 | } |
| 1731 | 1734 | ||
| 1732 | scsi_driver.can_queue = (max_outstanding_req_per_channel * | 1735 | scsi_driver.can_queue = (max_outstanding_req_per_channel * |
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index c374e3b5c678..777e5f1e52d1 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c | |||
| @@ -609,7 +609,7 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter, | |||
| 609 | break; | 609 | break; |
| 610 | 610 | ||
| 611 | case BTSTAT_ABORTQUEUE: | 611 | case BTSTAT_ABORTQUEUE: |
| 612 | cmd->result = (DID_ABORT << 16); | 612 | cmd->result = (DID_BUS_BUSY << 16); |
| 613 | break; | 613 | break; |
| 614 | 614 | ||
| 615 | case BTSTAT_SCSIPARITY: | 615 | case BTSTAT_SCSIPARITY: |
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 1596d35498c5..6573152ce893 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c | |||
| @@ -490,7 +490,7 @@ static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi, | |||
| 490 | 490 | ||
| 491 | static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi) | 491 | static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi) |
| 492 | { | 492 | { |
| 493 | if (!has_bspi(qspi) || (qspi->bspi_enabled)) | 493 | if (!has_bspi(qspi)) |
| 494 | return; | 494 | return; |
| 495 | 495 | ||
| 496 | qspi->bspi_enabled = 1; | 496 | qspi->bspi_enabled = 1; |
| @@ -505,7 +505,7 @@ static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi) | |||
| 505 | 505 | ||
| 506 | static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi) | 506 | static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi) |
| 507 | { | 507 | { |
| 508 | if (!has_bspi(qspi) || (!qspi->bspi_enabled)) | 508 | if (!has_bspi(qspi)) |
| 509 | return; | 509 | return; |
| 510 | 510 | ||
| 511 | qspi->bspi_enabled = 0; | 511 | qspi->bspi_enabled = 0; |
| @@ -519,16 +519,19 @@ static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi) | |||
| 519 | 519 | ||
| 520 | static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs) | 520 | static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs) |
| 521 | { | 521 | { |
| 522 | u32 data = 0; | 522 | u32 rd = 0; |
| 523 | u32 wr = 0; | ||
| 523 | 524 | ||
| 524 | if (qspi->curr_cs == cs) | ||
| 525 | return; | ||
| 526 | if (qspi->base[CHIP_SELECT]) { | 525 | if (qspi->base[CHIP_SELECT]) { |
| 527 | data = bcm_qspi_read(qspi, CHIP_SELECT, 0); | 526 | rd = bcm_qspi_read(qspi, CHIP_SELECT, 0); |
| 528 | data = (data & ~0xff) | (1 << cs); | 527 | wr = (rd & ~0xff) | (1 << cs); |
| 529 | bcm_qspi_write(qspi, CHIP_SELECT, 0, data); | 528 | if (rd == wr) |
| 529 | return; | ||
| 530 | bcm_qspi_write(qspi, CHIP_SELECT, 0, wr); | ||
| 530 | usleep_range(10, 20); | 531 | usleep_range(10, 20); |
| 531 | } | 532 | } |
| 533 | |||
| 534 | dev_dbg(&qspi->pdev->dev, "using cs:%d\n", cs); | ||
| 532 | qspi->curr_cs = cs; | 535 | qspi->curr_cs = cs; |
| 533 | } | 536 | } |
| 534 | 537 | ||
| @@ -755,8 +758,13 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi) | |||
| 755 | dev_dbg(&qspi->pdev->dev, "WR %04x\n", val); | 758 | dev_dbg(&qspi->pdev->dev, "WR %04x\n", val); |
| 756 | } | 759 | } |
| 757 | mspi_cdram = MSPI_CDRAM_CONT_BIT; | 760 | mspi_cdram = MSPI_CDRAM_CONT_BIT; |
| 758 | mspi_cdram |= (~(1 << spi->chip_select) & | 761 | |
| 759 | MSPI_CDRAM_PCS); | 762 | if (has_bspi(qspi)) |
| 763 | mspi_cdram &= ~1; | ||
| 764 | else | ||
| 765 | mspi_cdram |= (~(1 << spi->chip_select) & | ||
| 766 | MSPI_CDRAM_PCS); | ||
| 767 | |||
| 760 | mspi_cdram |= ((tp.trans->bits_per_word <= 8) ? 0 : | 768 | mspi_cdram |= ((tp.trans->bits_per_word <= 8) ? 0 : |
| 761 | MSPI_CDRAM_BITSE_BIT); | 769 | MSPI_CDRAM_BITSE_BIT); |
| 762 | 770 | ||
diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c index 1431cb98fe40..3094d818cf06 100644 --- a/drivers/spi/spi-bcm2835aux.c +++ b/drivers/spi/spi-bcm2835aux.c | |||
| @@ -184,6 +184,11 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) | |||
| 184 | struct bcm2835aux_spi *bs = spi_master_get_devdata(master); | 184 | struct bcm2835aux_spi *bs = spi_master_get_devdata(master); |
| 185 | irqreturn_t ret = IRQ_NONE; | 185 | irqreturn_t ret = IRQ_NONE; |
| 186 | 186 | ||
| 187 | /* IRQ may be shared, so return if our interrupts are disabled */ | ||
| 188 | if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) & | ||
| 189 | (BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE))) | ||
| 190 | return ret; | ||
| 191 | |||
| 187 | /* check if we have data to read */ | 192 | /* check if we have data to read */ |
| 188 | while (bs->rx_len && | 193 | while (bs->rx_len && |
| 189 | (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & | 194 | (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & |
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 5c9516ae4942..4a001634023e 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c | |||
| @@ -313,6 +313,14 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi) | |||
| 313 | 313 | ||
| 314 | while ((trans_cnt < CDNS_SPI_FIFO_DEPTH) && | 314 | while ((trans_cnt < CDNS_SPI_FIFO_DEPTH) && |
| 315 | (xspi->tx_bytes > 0)) { | 315 | (xspi->tx_bytes > 0)) { |
| 316 | |||
| 317 | /* When xspi in busy condition, bytes may send failed, | ||
| 318 | * then spi control did't work thoroughly, add one byte delay | ||
| 319 | */ | ||
| 320 | if (cdns_spi_read(xspi, CDNS_SPI_ISR) & | ||
| 321 | CDNS_SPI_IXR_TXFULL) | ||
| 322 | usleep_range(10, 20); | ||
| 323 | |||
| 316 | if (xspi->txbuf) | 324 | if (xspi->txbuf) |
| 317 | cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); | 325 | cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); |
| 318 | else | 326 | else |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 6f57592a7f95..a056ee88a960 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
| @@ -1701,7 +1701,7 @@ static struct platform_driver spi_imx_driver = { | |||
| 1701 | }; | 1701 | }; |
| 1702 | module_platform_driver(spi_imx_driver); | 1702 | module_platform_driver(spi_imx_driver); |
| 1703 | 1703 | ||
| 1704 | MODULE_DESCRIPTION("SPI Master Controller driver"); | 1704 | MODULE_DESCRIPTION("SPI Controller driver"); |
| 1705 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | 1705 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
| 1706 | MODULE_LICENSE("GPL"); | 1706 | MODULE_LICENSE("GPL"); |
| 1707 | MODULE_ALIAS("platform:" DRIVER_NAME); | 1707 | MODULE_ALIAS("platform:" DRIVER_NAME); |
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index 513ec6c6e25b..0ae7defd3492 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h | |||
| @@ -38,7 +38,7 @@ struct driver_data { | |||
| 38 | 38 | ||
| 39 | /* SSP register addresses */ | 39 | /* SSP register addresses */ |
| 40 | void __iomem *ioaddr; | 40 | void __iomem *ioaddr; |
| 41 | u32 ssdr_physical; | 41 | phys_addr_t ssdr_physical; |
| 42 | 42 | ||
| 43 | /* SSP masks*/ | 43 | /* SSP masks*/ |
| 44 | u32 dma_cr1; | 44 | u32 dma_cr1; |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index ae086aab57d5..8171eedbfc90 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
| @@ -283,6 +283,7 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, | |||
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | k = min_t(int, k, ARRAY_SIZE(sh_msiof_spi_div_table) - 1); | 285 | k = min_t(int, k, ARRAY_SIZE(sh_msiof_spi_div_table) - 1); |
| 286 | brps = min_t(int, brps, 32); | ||
| 286 | 287 | ||
| 287 | scr = sh_msiof_spi_div_table[k].brdv | SCR_BRPS(brps); | 288 | scr = sh_msiof_spi_div_table[k].brdv | SCR_BRPS(brps); |
| 288 | sh_msiof_write(p, TSCR, scr); | 289 | sh_msiof_write(p, TSCR, scr); |
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 16cab40156ca..aeab05f682d9 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c | |||
| @@ -1799,7 +1799,7 @@ static int imx_csi_probe(struct platform_device *pdev) | |||
| 1799 | priv->dev->of_node = pdata->of_node; | 1799 | priv->dev->of_node = pdata->of_node; |
| 1800 | pinctrl = devm_pinctrl_get_select_default(priv->dev); | 1800 | pinctrl = devm_pinctrl_get_select_default(priv->dev); |
| 1801 | if (IS_ERR(pinctrl)) { | 1801 | if (IS_ERR(pinctrl)) { |
| 1802 | ret = PTR_ERR(priv->vdev); | 1802 | ret = PTR_ERR(pinctrl); |
| 1803 | dev_dbg(priv->dev, | 1803 | dev_dbg(priv->dev, |
| 1804 | "devm_pinctrl_get_select_default() failed: %d\n", ret); | 1804 | "devm_pinctrl_get_select_default() failed: %d\n", ret); |
| 1805 | if (ret != -ENODEV) | 1805 | if (ret != -ENODEV) |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 07c814c42648..60429011292a 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
| @@ -427,8 +427,8 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) | |||
| 427 | { | 427 | { |
| 428 | struct se_device *dev = cmd->se_dev; | 428 | struct se_device *dev = cmd->se_dev; |
| 429 | struct scatterlist *sg = &cmd->t_data_sg[0]; | 429 | struct scatterlist *sg = &cmd->t_data_sg[0]; |
| 430 | unsigned char *buf, zero = 0x00, *p = &zero; | 430 | unsigned char *buf, *not_zero; |
| 431 | int rc, ret; | 431 | int ret; |
| 432 | 432 | ||
| 433 | buf = kmap(sg_page(sg)) + sg->offset; | 433 | buf = kmap(sg_page(sg)) + sg->offset; |
| 434 | if (!buf) | 434 | if (!buf) |
| @@ -437,10 +437,10 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) | |||
| 437 | * Fall back to block_execute_write_same() slow-path if | 437 | * Fall back to block_execute_write_same() slow-path if |
| 438 | * incoming WRITE_SAME payload does not contain zeros. | 438 | * incoming WRITE_SAME payload does not contain zeros. |
| 439 | */ | 439 | */ |
| 440 | rc = memcmp(buf, p, cmd->data_length); | 440 | not_zero = memchr_inv(buf, 0x00, cmd->data_length); |
| 441 | kunmap(sg_page(sg)); | 441 | kunmap(sg_page(sg)); |
| 442 | 442 | ||
| 443 | if (rc) | 443 | if (not_zero) |
| 444 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 444 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
| 445 | 445 | ||
| 446 | ret = blkdev_issue_zeroout(bdev, | 446 | ret = blkdev_issue_zeroout(bdev, |
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 0124a91c8d71..dd46b758852a 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c | |||
| @@ -238,6 +238,17 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, | |||
| 238 | if (IS_ERR(shm)) | 238 | if (IS_ERR(shm)) |
| 239 | return PTR_ERR(shm); | 239 | return PTR_ERR(shm); |
| 240 | 240 | ||
| 241 | /* | ||
| 242 | * Ensure offset + size does not overflow offset | ||
| 243 | * and does not overflow the size of the referred | ||
| 244 | * shared memory object. | ||
| 245 | */ | ||
| 246 | if ((ip.a + ip.b) < ip.a || | ||
| 247 | (ip.a + ip.b) > shm->size) { | ||
| 248 | tee_shm_put(shm); | ||
| 249 | return -EINVAL; | ||
| 250 | } | ||
| 251 | |||
| 241 | params[n].u.memref.shm_offs = ip.a; | 252 | params[n].u.memref.shm_offs = ip.a; |
| 242 | params[n].u.memref.size = ip.b; | 253 | params[n].u.memref.size = ip.b; |
| 243 | params[n].u.memref.shm = shm; | 254 | params[n].u.memref.shm = shm; |
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 556960a1bab3..07d3be6f0780 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c | |||
| @@ -360,9 +360,10 @@ int tee_shm_get_fd(struct tee_shm *shm) | |||
| 360 | if (!(shm->flags & TEE_SHM_DMA_BUF)) | 360 | if (!(shm->flags & TEE_SHM_DMA_BUF)) |
| 361 | return -EINVAL; | 361 | return -EINVAL; |
| 362 | 362 | ||
| 363 | get_dma_buf(shm->dmabuf); | ||
| 363 | fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC); | 364 | fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC); |
| 364 | if (fd >= 0) | 365 | if (fd < 0) |
| 365 | get_dma_buf(shm->dmabuf); | 366 | dma_buf_put(shm->dmabuf); |
| 366 | return fd; | 367 | return fd; |
| 367 | } | 368 | } |
| 368 | 369 | ||
diff --git a/drivers/thermal/int340x_thermal/int3403_thermal.c b/drivers/thermal/int340x_thermal/int3403_thermal.c index 8a7f24dd9315..0c19fcd56a0d 100644 --- a/drivers/thermal/int340x_thermal/int3403_thermal.c +++ b/drivers/thermal/int340x_thermal/int3403_thermal.c | |||
| @@ -194,6 +194,7 @@ static int int3403_cdev_add(struct int3403_priv *priv) | |||
| 194 | return -EFAULT; | 194 | return -EFAULT; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | priv->priv = obj; | ||
| 197 | obj->max_state = p->package.count - 1; | 198 | obj->max_state = p->package.count - 1; |
| 198 | obj->cdev = | 199 | obj->cdev = |
| 199 | thermal_cooling_device_register(acpi_device_bid(priv->adev), | 200 | thermal_cooling_device_register(acpi_device_bid(priv->adev), |
| @@ -201,8 +202,6 @@ static int int3403_cdev_add(struct int3403_priv *priv) | |||
| 201 | if (IS_ERR(obj->cdev)) | 202 | if (IS_ERR(obj->cdev)) |
| 202 | result = PTR_ERR(obj->cdev); | 203 | result = PTR_ERR(obj->cdev); |
| 203 | 204 | ||
| 204 | priv->priv = obj; | ||
| 205 | |||
| 206 | kfree(buf.pointer); | 205 | kfree(buf.pointer); |
| 207 | /* TODO: add ACPI notification support */ | 206 | /* TODO: add ACPI notification support */ |
| 208 | 207 | ||
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index ed805c7c5ace..ac83f721db24 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c | |||
| @@ -185,6 +185,7 @@ | |||
| 185 | * @regulator: pointer to the TMU regulator structure. | 185 | * @regulator: pointer to the TMU regulator structure. |
| 186 | * @reg_conf: pointer to structure to register with core thermal. | 186 | * @reg_conf: pointer to structure to register with core thermal. |
| 187 | * @ntrip: number of supported trip points. | 187 | * @ntrip: number of supported trip points. |
| 188 | * @enabled: current status of TMU device | ||
| 188 | * @tmu_initialize: SoC specific TMU initialization method | 189 | * @tmu_initialize: SoC specific TMU initialization method |
| 189 | * @tmu_control: SoC specific TMU control method | 190 | * @tmu_control: SoC specific TMU control method |
| 190 | * @tmu_read: SoC specific TMU temperature read method | 191 | * @tmu_read: SoC specific TMU temperature read method |
| @@ -205,6 +206,7 @@ struct exynos_tmu_data { | |||
| 205 | struct regulator *regulator; | 206 | struct regulator *regulator; |
| 206 | struct thermal_zone_device *tzd; | 207 | struct thermal_zone_device *tzd; |
| 207 | unsigned int ntrip; | 208 | unsigned int ntrip; |
| 209 | bool enabled; | ||
| 208 | 210 | ||
| 209 | int (*tmu_initialize)(struct platform_device *pdev); | 211 | int (*tmu_initialize)(struct platform_device *pdev); |
| 210 | void (*tmu_control)(struct platform_device *pdev, bool on); | 212 | void (*tmu_control)(struct platform_device *pdev, bool on); |
| @@ -398,6 +400,7 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) | |||
| 398 | mutex_lock(&data->lock); | 400 | mutex_lock(&data->lock); |
| 399 | clk_enable(data->clk); | 401 | clk_enable(data->clk); |
| 400 | data->tmu_control(pdev, on); | 402 | data->tmu_control(pdev, on); |
| 403 | data->enabled = on; | ||
| 401 | clk_disable(data->clk); | 404 | clk_disable(data->clk); |
| 402 | mutex_unlock(&data->lock); | 405 | mutex_unlock(&data->lock); |
| 403 | } | 406 | } |
| @@ -889,19 +892,24 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) | |||
| 889 | static int exynos_get_temp(void *p, int *temp) | 892 | static int exynos_get_temp(void *p, int *temp) |
| 890 | { | 893 | { |
| 891 | struct exynos_tmu_data *data = p; | 894 | struct exynos_tmu_data *data = p; |
| 895 | int value, ret = 0; | ||
| 892 | 896 | ||
| 893 | if (!data || !data->tmu_read) | 897 | if (!data || !data->tmu_read || !data->enabled) |
| 894 | return -EINVAL; | 898 | return -EINVAL; |
| 895 | 899 | ||
| 896 | mutex_lock(&data->lock); | 900 | mutex_lock(&data->lock); |
| 897 | clk_enable(data->clk); | 901 | clk_enable(data->clk); |
| 898 | 902 | ||
| 899 | *temp = code_to_temp(data, data->tmu_read(data)) * MCELSIUS; | 903 | value = data->tmu_read(data); |
| 904 | if (value < 0) | ||
| 905 | ret = value; | ||
| 906 | else | ||
| 907 | *temp = code_to_temp(data, value) * MCELSIUS; | ||
| 900 | 908 | ||
| 901 | clk_disable(data->clk); | 909 | clk_disable(data->clk); |
| 902 | mutex_unlock(&data->lock); | 910 | mutex_unlock(&data->lock); |
| 903 | 911 | ||
| 904 | return 0; | 912 | return ret; |
| 905 | } | 913 | } |
| 906 | 914 | ||
| 907 | #ifdef CONFIG_THERMAL_EMULATION | 915 | #ifdef CONFIG_THERMAL_EMULATION |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index c821b4b9647e..7b5cb28ffb35 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
| @@ -191,7 +191,9 @@ static const unsigned short full_speed_maxpacket_maxes[4] = { | |||
| 191 | static const unsigned short high_speed_maxpacket_maxes[4] = { | 191 | static const unsigned short high_speed_maxpacket_maxes[4] = { |
| 192 | [USB_ENDPOINT_XFER_CONTROL] = 64, | 192 | [USB_ENDPOINT_XFER_CONTROL] = 64, |
| 193 | [USB_ENDPOINT_XFER_ISOC] = 1024, | 193 | [USB_ENDPOINT_XFER_ISOC] = 1024, |
| 194 | [USB_ENDPOINT_XFER_BULK] = 512, | 194 | |
| 195 | /* Bulk should be 512, but some devices use 1024: we will warn below */ | ||
| 196 | [USB_ENDPOINT_XFER_BULK] = 1024, | ||
| 195 | [USB_ENDPOINT_XFER_INT] = 1024, | 197 | [USB_ENDPOINT_XFER_INT] = 1024, |
| 196 | }; | 198 | }; |
| 197 | static const unsigned short super_speed_maxpacket_maxes[4] = { | 199 | static const unsigned short super_speed_maxpacket_maxes[4] = { |
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index d83be5651f87..a666e0758a99 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h | |||
| @@ -985,6 +985,7 @@ struct dwc2_hsotg { | |||
| 985 | 985 | ||
| 986 | /* DWC OTG HW Release versions */ | 986 | /* DWC OTG HW Release versions */ |
| 987 | #define DWC2_CORE_REV_2_71a 0x4f54271a | 987 | #define DWC2_CORE_REV_2_71a 0x4f54271a |
| 988 | #define DWC2_CORE_REV_2_72a 0x4f54272a | ||
| 988 | #define DWC2_CORE_REV_2_80a 0x4f54280a | 989 | #define DWC2_CORE_REV_2_80a 0x4f54280a |
| 989 | #define DWC2_CORE_REV_2_90a 0x4f54290a | 990 | #define DWC2_CORE_REV_2_90a 0x4f54290a |
| 990 | #define DWC2_CORE_REV_2_91a 0x4f54291a | 991 | #define DWC2_CORE_REV_2_91a 0x4f54291a |
| @@ -992,6 +993,7 @@ struct dwc2_hsotg { | |||
| 992 | #define DWC2_CORE_REV_2_94a 0x4f54294a | 993 | #define DWC2_CORE_REV_2_94a 0x4f54294a |
| 993 | #define DWC2_CORE_REV_3_00a 0x4f54300a | 994 | #define DWC2_CORE_REV_3_00a 0x4f54300a |
| 994 | #define DWC2_CORE_REV_3_10a 0x4f54310a | 995 | #define DWC2_CORE_REV_3_10a 0x4f54310a |
| 996 | #define DWC2_CORE_REV_4_00a 0x4f54400a | ||
| 995 | #define DWC2_FS_IOT_REV_1_00a 0x5531100a | 997 | #define DWC2_FS_IOT_REV_1_00a 0x5531100a |
| 996 | #define DWC2_HS_IOT_REV_1_00a 0x5532100a | 998 | #define DWC2_HS_IOT_REV_1_00a 0x5532100a |
| 997 | 999 | ||
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6c32bf26e48e..83cb5577a52f 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
| @@ -3928,6 +3928,27 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, | |||
| 3928 | if (index && !hs_ep->isochronous) | 3928 | if (index && !hs_ep->isochronous) |
| 3929 | epctrl |= DXEPCTL_SETD0PID; | 3929 | epctrl |= DXEPCTL_SETD0PID; |
| 3930 | 3930 | ||
| 3931 | /* WA for Full speed ISOC IN in DDMA mode. | ||
| 3932 | * By Clear NAK status of EP, core will send ZLP | ||
| 3933 | * to IN token and assert NAK interrupt relying | ||
| 3934 | * on TxFIFO status only | ||
| 3935 | */ | ||
| 3936 | |||
| 3937 | if (hsotg->gadget.speed == USB_SPEED_FULL && | ||
| 3938 | hs_ep->isochronous && dir_in) { | ||
| 3939 | /* The WA applies only to core versions from 2.72a | ||
| 3940 | * to 4.00a (including both). Also for FS_IOT_1.00a | ||
| 3941 | * and HS_IOT_1.00a. | ||
| 3942 | */ | ||
| 3943 | u32 gsnpsid = dwc2_readl(hsotg->regs + GSNPSID); | ||
| 3944 | |||
| 3945 | if ((gsnpsid >= DWC2_CORE_REV_2_72a && | ||
| 3946 | gsnpsid <= DWC2_CORE_REV_4_00a) || | ||
| 3947 | gsnpsid == DWC2_FS_IOT_REV_1_00a || | ||
| 3948 | gsnpsid == DWC2_HS_IOT_REV_1_00a) | ||
| 3949 | epctrl |= DXEPCTL_CNAK; | ||
| 3950 | } | ||
| 3951 | |||
| 3931 | dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n", | 3952 | dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n", |
| 3932 | __func__, epctrl); | 3953 | __func__, epctrl); |
| 3933 | 3954 | ||
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 190f95964000..c51b73b3e048 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c | |||
| @@ -358,9 +358,14 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg) | |||
| 358 | 358 | ||
| 359 | static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg) | 359 | static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg) |
| 360 | { | 360 | { |
| 361 | int ret; | ||
| 362 | |||
| 361 | hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus"); | 363 | hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus"); |
| 362 | if (IS_ERR(hsotg->vbus_supply)) | 364 | if (IS_ERR(hsotg->vbus_supply)) { |
| 363 | return 0; | 365 | ret = PTR_ERR(hsotg->vbus_supply); |
| 366 | hsotg->vbus_supply = NULL; | ||
| 367 | return ret == -ENODEV ? 0 : ret; | ||
| 368 | } | ||
| 364 | 369 | ||
| 365 | return regulator_enable(hsotg->vbus_supply); | 370 | return regulator_enable(hsotg->vbus_supply); |
| 366 | } | 371 | } |
| @@ -4342,9 +4347,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd) | |||
| 4342 | 4347 | ||
| 4343 | spin_unlock_irqrestore(&hsotg->lock, flags); | 4348 | spin_unlock_irqrestore(&hsotg->lock, flags); |
| 4344 | 4349 | ||
| 4345 | dwc2_vbus_supply_init(hsotg); | 4350 | return dwc2_vbus_supply_init(hsotg); |
| 4346 | |||
| 4347 | return 0; | ||
| 4348 | } | 4351 | } |
| 4349 | 4352 | ||
| 4350 | /* | 4353 | /* |
diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index 7f21747007f1..bea2e8ec0369 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c | |||
| @@ -141,8 +141,10 @@ static int dwc2_pci_probe(struct pci_dev *pci, | |||
| 141 | goto err; | 141 | goto err; |
| 142 | 142 | ||
| 143 | glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); | 143 | glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); |
| 144 | if (!glue) | 144 | if (!glue) { |
| 145 | ret = -ENOMEM; | ||
| 145 | goto err; | 146 | goto err; |
| 147 | } | ||
| 146 | 148 | ||
| 147 | ret = platform_device_add(dwc2); | 149 | ret = platform_device_add(dwc2); |
| 148 | if (ret) { | 150 | if (ret) { |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8796a5ee9bb9..0dedf8a799f4 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
| @@ -166,7 +166,7 @@ static void dwc3_ep_inc_deq(struct dwc3_ep *dep) | |||
| 166 | dwc3_ep_inc_trb(&dep->trb_dequeue); | 166 | dwc3_ep_inc_trb(&dep->trb_dequeue); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, | 169 | static void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, |
| 170 | struct dwc3_request *req, int status) | 170 | struct dwc3_request *req, int status) |
| 171 | { | 171 | { |
| 172 | struct dwc3 *dwc = dep->dwc; | 172 | struct dwc3 *dwc = dep->dwc; |
| @@ -1424,7 +1424,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, | |||
| 1424 | dwc->lock); | 1424 | dwc->lock); |
| 1425 | 1425 | ||
| 1426 | if (!r->trb) | 1426 | if (!r->trb) |
| 1427 | goto out1; | 1427 | goto out0; |
| 1428 | 1428 | ||
| 1429 | if (r->num_pending_sgs) { | 1429 | if (r->num_pending_sgs) { |
| 1430 | struct dwc3_trb *trb; | 1430 | struct dwc3_trb *trb; |
diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index 7889bcc0509a..8b72b192c747 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c | |||
| @@ -221,7 +221,7 @@ static void pn_tx_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 221 | netif_wake_queue(dev); | 221 | netif_wake_queue(dev); |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | static int pn_net_xmit(struct sk_buff *skb, struct net_device *dev) | 224 | static netdev_tx_t pn_net_xmit(struct sk_buff *skb, struct net_device *dev) |
| 225 | { | 225 | { |
| 226 | struct phonet_port *port = netdev_priv(dev); | 226 | struct phonet_port *port = netdev_priv(dev); |
| 227 | struct f_phonet *fp; | 227 | struct f_phonet *fp; |
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 4c6c08b675b5..21307d862af6 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
| @@ -73,9 +73,10 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | |||
| 73 | if (!qh) | 73 | if (!qh) |
| 74 | goto done; | 74 | goto done; |
| 75 | qh->hw = (struct ehci_qh_hw *) | 75 | qh->hw = (struct ehci_qh_hw *) |
| 76 | dma_pool_zalloc(ehci->qh_pool, flags, &dma); | 76 | dma_pool_alloc(ehci->qh_pool, flags, &dma); |
| 77 | if (!qh->hw) | 77 | if (!qh->hw) |
| 78 | goto fail; | 78 | goto fail; |
| 79 | memset(qh->hw, 0, sizeof *qh->hw); | ||
| 79 | qh->qh_dma = dma; | 80 | qh->qh_dma = dma; |
| 80 | // INIT_LIST_HEAD (&qh->qh_list); | 81 | // INIT_LIST_HEAD (&qh->qh_list); |
| 81 | INIT_LIST_HEAD (&qh->qtd_list); | 82 | INIT_LIST_HEAD (&qh->qtd_list); |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 28e2a338b481..e56db44708bc 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -1287,7 +1287,7 @@ itd_urb_transaction( | |||
| 1287 | } else { | 1287 | } else { |
| 1288 | alloc_itd: | 1288 | alloc_itd: |
| 1289 | spin_unlock_irqrestore(&ehci->lock, flags); | 1289 | spin_unlock_irqrestore(&ehci->lock, flags); |
| 1290 | itd = dma_pool_zalloc(ehci->itd_pool, mem_flags, | 1290 | itd = dma_pool_alloc(ehci->itd_pool, mem_flags, |
| 1291 | &itd_dma); | 1291 | &itd_dma); |
| 1292 | spin_lock_irqsave(&ehci->lock, flags); | 1292 | spin_lock_irqsave(&ehci->lock, flags); |
| 1293 | if (!itd) { | 1293 | if (!itd) { |
| @@ -1297,6 +1297,7 @@ itd_urb_transaction( | |||
| 1297 | } | 1297 | } |
| 1298 | } | 1298 | } |
| 1299 | 1299 | ||
| 1300 | memset(itd, 0, sizeof(*itd)); | ||
| 1300 | itd->itd_dma = itd_dma; | 1301 | itd->itd_dma = itd_dma; |
| 1301 | itd->frame = NO_FRAME; | 1302 | itd->frame = NO_FRAME; |
| 1302 | list_add(&itd->itd_list, &sched->td_list); | 1303 | list_add(&itd->itd_list, &sched->td_list); |
| @@ -2080,7 +2081,7 @@ sitd_urb_transaction( | |||
| 2080 | } else { | 2081 | } else { |
| 2081 | alloc_sitd: | 2082 | alloc_sitd: |
| 2082 | spin_unlock_irqrestore(&ehci->lock, flags); | 2083 | spin_unlock_irqrestore(&ehci->lock, flags); |
| 2083 | sitd = dma_pool_zalloc(ehci->sitd_pool, mem_flags, | 2084 | sitd = dma_pool_alloc(ehci->sitd_pool, mem_flags, |
| 2084 | &sitd_dma); | 2085 | &sitd_dma); |
| 2085 | spin_lock_irqsave(&ehci->lock, flags); | 2086 | spin_lock_irqsave(&ehci->lock, flags); |
| 2086 | if (!sitd) { | 2087 | if (!sitd) { |
| @@ -2090,6 +2091,7 @@ sitd_urb_transaction( | |||
| 2090 | } | 2091 | } |
| 2091 | } | 2092 | } |
| 2092 | 2093 | ||
| 2094 | memset(sitd, 0, sizeof(*sitd)); | ||
| 2093 | sitd->sitd_dma = sitd_dma; | 2095 | sitd->sitd_dma = sitd_dma; |
| 2094 | sitd->frame = NO_FRAME; | 2096 | sitd->frame = NO_FRAME; |
| 2095 | list_add(&sitd->sitd_list, &iso_sched->td_list); | 2097 | list_add(&sitd->sitd_list, &iso_sched->td_list); |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 72ebbc908e19..32cd52ca8318 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
| @@ -354,7 +354,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, | |||
| 354 | 354 | ||
| 355 | slot_id = 0; | 355 | slot_id = 0; |
| 356 | for (i = 0; i < MAX_HC_SLOTS; i++) { | 356 | for (i = 0; i < MAX_HC_SLOTS; i++) { |
| 357 | if (!xhci->devs[i]) | 357 | if (!xhci->devs[i] || !xhci->devs[i]->udev) |
| 358 | continue; | 358 | continue; |
| 359 | speed = xhci->devs[i]->udev->speed; | 359 | speed = xhci->devs[i]->udev->speed; |
| 360 | if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3)) | 360 | if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3)) |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9b27798ecce5..711da3306b14 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -3621,6 +3621,7 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
| 3621 | del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); | 3621 | del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); |
| 3622 | } | 3622 | } |
| 3623 | xhci_debugfs_remove_slot(xhci, udev->slot_id); | 3623 | xhci_debugfs_remove_slot(xhci, udev->slot_id); |
| 3624 | virt_dev->udev = NULL; | ||
| 3624 | ret = xhci_disable_slot(xhci, udev->slot_id); | 3625 | ret = xhci_disable_slot(xhci, udev->slot_id); |
| 3625 | if (ret) | 3626 | if (ret) |
| 3626 | xhci_free_virt_device(xhci, udev->slot_id); | 3627 | xhci_free_virt_device(xhci, udev->slot_id); |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index e564695c6c8d..71c5835ea9cd 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -417,7 +417,6 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
| 417 | req = next_request(musb_ep); | 417 | req = next_request(musb_ep); |
| 418 | request = &req->request; | 418 | request = &req->request; |
| 419 | 419 | ||
| 420 | trace_musb_req_tx(req); | ||
| 421 | csr = musb_readw(epio, MUSB_TXCSR); | 420 | csr = musb_readw(epio, MUSB_TXCSR); |
| 422 | musb_dbg(musb, "<== %s, txcsr %04x", musb_ep->end_point.name, csr); | 421 | musb_dbg(musb, "<== %s, txcsr %04x", musb_ep->end_point.name, csr); |
| 423 | 422 | ||
| @@ -456,6 +455,8 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
| 456 | u8 is_dma = 0; | 455 | u8 is_dma = 0; |
| 457 | bool short_packet = false; | 456 | bool short_packet = false; |
| 458 | 457 | ||
| 458 | trace_musb_req_tx(req); | ||
| 459 | |||
| 459 | if (dma && (csr & MUSB_TXCSR_DMAENAB)) { | 460 | if (dma && (csr & MUSB_TXCSR_DMAENAB)) { |
| 460 | is_dma = 1; | 461 | is_dma = 1; |
| 461 | csr |= MUSB_TXCSR_P_WZC_BITS; | 462 | csr |= MUSB_TXCSR_P_WZC_BITS; |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 4fa372c845e1..15a42cee0a9c 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -990,7 +990,9 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep, | |||
| 990 | /* set tx_reinit and schedule the next qh */ | 990 | /* set tx_reinit and schedule the next qh */ |
| 991 | ep->tx_reinit = 1; | 991 | ep->tx_reinit = 1; |
| 992 | } | 992 | } |
| 993 | musb_start_urb(musb, is_in, next_qh); | 993 | |
| 994 | if (next_qh) | ||
| 995 | musb_start_urb(musb, is_in, next_qh); | ||
| 994 | } | 996 | } |
| 995 | } | 997 | } |
| 996 | 998 | ||
| @@ -2522,8 +2524,11 @@ static int musb_bus_suspend(struct usb_hcd *hcd) | |||
| 2522 | { | 2524 | { |
| 2523 | struct musb *musb = hcd_to_musb(hcd); | 2525 | struct musb *musb = hcd_to_musb(hcd); |
| 2524 | u8 devctl; | 2526 | u8 devctl; |
| 2527 | int ret; | ||
| 2525 | 2528 | ||
| 2526 | musb_port_suspend(musb, true); | 2529 | ret = musb_port_suspend(musb, true); |
| 2530 | if (ret) | ||
| 2531 | return ret; | ||
| 2527 | 2532 | ||
| 2528 | if (!is_host_active(musb)) | 2533 | if (!is_host_active(musb)) |
| 2529 | return 0; | 2534 | return 0; |
diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h index 72392bbcd0a4..2999845632ce 100644 --- a/drivers/usb/musb/musb_host.h +++ b/drivers/usb/musb/musb_host.h | |||
| @@ -67,7 +67,7 @@ extern void musb_host_rx(struct musb *, u8); | |||
| 67 | extern void musb_root_disconnect(struct musb *musb); | 67 | extern void musb_root_disconnect(struct musb *musb); |
| 68 | extern void musb_host_resume_root_hub(struct musb *musb); | 68 | extern void musb_host_resume_root_hub(struct musb *musb); |
| 69 | extern void musb_host_poke_root_hub(struct musb *musb); | 69 | extern void musb_host_poke_root_hub(struct musb *musb); |
| 70 | extern void musb_port_suspend(struct musb *musb, bool do_suspend); | 70 | extern int musb_port_suspend(struct musb *musb, bool do_suspend); |
| 71 | extern void musb_port_reset(struct musb *musb, bool do_reset); | 71 | extern void musb_port_reset(struct musb *musb, bool do_reset); |
| 72 | extern void musb_host_finish_resume(struct work_struct *work); | 72 | extern void musb_host_finish_resume(struct work_struct *work); |
| 73 | #else | 73 | #else |
| @@ -99,7 +99,10 @@ static inline void musb_root_disconnect(struct musb *musb) {} | |||
| 99 | static inline void musb_host_resume_root_hub(struct musb *musb) {} | 99 | static inline void musb_host_resume_root_hub(struct musb *musb) {} |
| 100 | static inline void musb_host_poll_rh_status(struct musb *musb) {} | 100 | static inline void musb_host_poll_rh_status(struct musb *musb) {} |
| 101 | static inline void musb_host_poke_root_hub(struct musb *musb) {} | 101 | static inline void musb_host_poke_root_hub(struct musb *musb) {} |
| 102 | static inline void musb_port_suspend(struct musb *musb, bool do_suspend) {} | 102 | static inline int musb_port_suspend(struct musb *musb, bool do_suspend) |
| 103 | { | ||
| 104 | return 0; | ||
| 105 | } | ||
| 103 | static inline void musb_port_reset(struct musb *musb, bool do_reset) {} | 106 | static inline void musb_port_reset(struct musb *musb, bool do_reset) {} |
| 104 | static inline void musb_host_finish_resume(struct work_struct *work) {} | 107 | static inline void musb_host_finish_resume(struct work_struct *work) {} |
| 105 | #endif | 108 | #endif |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 5165d2b07ade..2f8dd9826e94 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
| @@ -48,14 +48,14 @@ void musb_host_finish_resume(struct work_struct *work) | |||
| 48 | spin_unlock_irqrestore(&musb->lock, flags); | 48 | spin_unlock_irqrestore(&musb->lock, flags); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | void musb_port_suspend(struct musb *musb, bool do_suspend) | 51 | int musb_port_suspend(struct musb *musb, bool do_suspend) |
| 52 | { | 52 | { |
| 53 | struct usb_otg *otg = musb->xceiv->otg; | 53 | struct usb_otg *otg = musb->xceiv->otg; |
| 54 | u8 power; | 54 | u8 power; |
| 55 | void __iomem *mbase = musb->mregs; | 55 | void __iomem *mbase = musb->mregs; |
| 56 | 56 | ||
| 57 | if (!is_host_active(musb)) | 57 | if (!is_host_active(musb)) |
| 58 | return; | 58 | return 0; |
| 59 | 59 | ||
| 60 | /* NOTE: this doesn't necessarily put PHY into low power mode, | 60 | /* NOTE: this doesn't necessarily put PHY into low power mode, |
| 61 | * turning off its clock; that's a function of PHY integration and | 61 | * turning off its clock; that's a function of PHY integration and |
| @@ -66,16 +66,20 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) | |||
| 66 | if (do_suspend) { | 66 | if (do_suspend) { |
| 67 | int retries = 10000; | 67 | int retries = 10000; |
| 68 | 68 | ||
| 69 | power &= ~MUSB_POWER_RESUME; | 69 | if (power & MUSB_POWER_RESUME) |
| 70 | power |= MUSB_POWER_SUSPENDM; | 70 | return -EBUSY; |
| 71 | musb_writeb(mbase, MUSB_POWER, power); | ||
| 72 | 71 | ||
| 73 | /* Needed for OPT A tests */ | 72 | if (!(power & MUSB_POWER_SUSPENDM)) { |
| 74 | power = musb_readb(mbase, MUSB_POWER); | 73 | power |= MUSB_POWER_SUSPENDM; |
| 75 | while (power & MUSB_POWER_SUSPENDM) { | 74 | musb_writeb(mbase, MUSB_POWER, power); |
| 75 | |||
| 76 | /* Needed for OPT A tests */ | ||
| 76 | power = musb_readb(mbase, MUSB_POWER); | 77 | power = musb_readb(mbase, MUSB_POWER); |
| 77 | if (retries-- < 1) | 78 | while (power & MUSB_POWER_SUSPENDM) { |
| 78 | break; | 79 | power = musb_readb(mbase, MUSB_POWER); |
| 80 | if (retries-- < 1) | ||
| 81 | break; | ||
| 82 | } | ||
| 79 | } | 83 | } |
| 80 | 84 | ||
| 81 | musb_dbg(musb, "Root port suspended, power %02x", power); | 85 | musb_dbg(musb, "Root port suspended, power %02x", power); |
| @@ -111,6 +115,7 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) | |||
| 111 | schedule_delayed_work(&musb->finish_resume_work, | 115 | schedule_delayed_work(&musb->finish_resume_work, |
| 112 | msecs_to_jiffies(USB_RESUME_TIMEOUT)); | 116 | msecs_to_jiffies(USB_RESUME_TIMEOUT)); |
| 113 | } | 117 | } |
| 118 | return 0; | ||
| 114 | } | 119 | } |
| 115 | 120 | ||
| 116 | void musb_port_reset(struct musb *musb, bool do_reset) | 121 | void musb_port_reset(struct musb *musb, bool do_reset) |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index c3f252283ab9..2058852a87fa 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -233,6 +233,8 @@ static void option_instat_callback(struct urb *urb); | |||
| 233 | /* These Quectel products use Qualcomm's vendor ID */ | 233 | /* These Quectel products use Qualcomm's vendor ID */ |
| 234 | #define QUECTEL_PRODUCT_UC20 0x9003 | 234 | #define QUECTEL_PRODUCT_UC20 0x9003 |
| 235 | #define QUECTEL_PRODUCT_UC15 0x9090 | 235 | #define QUECTEL_PRODUCT_UC15 0x9090 |
| 236 | /* These u-blox products use Qualcomm's vendor ID */ | ||
| 237 | #define UBLOX_PRODUCT_R410M 0x90b2 | ||
| 236 | /* These Yuga products use Qualcomm's vendor ID */ | 238 | /* These Yuga products use Qualcomm's vendor ID */ |
| 237 | #define YUGA_PRODUCT_CLM920_NC5 0x9625 | 239 | #define YUGA_PRODUCT_CLM920_NC5 0x9625 |
| 238 | 240 | ||
| @@ -1065,6 +1067,9 @@ static const struct usb_device_id option_ids[] = { | |||
| 1065 | /* Yuga products use Qualcomm vendor ID */ | 1067 | /* Yuga products use Qualcomm vendor ID */ |
| 1066 | { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), | 1068 | { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), |
| 1067 | .driver_info = RSVD(1) | RSVD(4) }, | 1069 | .driver_info = RSVD(1) | RSVD(4) }, |
| 1070 | /* u-blox products using Qualcomm vendor ID */ | ||
| 1071 | { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), | ||
| 1072 | .driver_info = RSVD(1) | RSVD(3) }, | ||
| 1068 | /* Quectel products using Quectel vendor ID */ | 1073 | /* Quectel products using Quectel vendor ID */ |
| 1069 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), | 1074 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), |
| 1070 | .driver_info = RSVD(4) }, | 1075 | .driver_info = RSVD(4) }, |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index f5373ed2cd45..8ddbecc25d89 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
| @@ -335,47 +335,48 @@ static int palm_os_3_probe(struct usb_serial *serial, | |||
| 335 | goto exit; | 335 | goto exit; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | if (retval == sizeof(*connection_info)) { | 338 | if (retval != sizeof(*connection_info)) { |
| 339 | connection_info = (struct visor_connection_info *) | 339 | dev_err(dev, "Invalid connection information received from device\n"); |
| 340 | transfer_buffer; | 340 | retval = -ENODEV; |
| 341 | 341 | goto exit; | |
| 342 | num_ports = le16_to_cpu(connection_info->num_ports); | ||
| 343 | for (i = 0; i < num_ports; ++i) { | ||
| 344 | switch ( | ||
| 345 | connection_info->connections[i].port_function_id) { | ||
| 346 | case VISOR_FUNCTION_GENERIC: | ||
| 347 | string = "Generic"; | ||
| 348 | break; | ||
| 349 | case VISOR_FUNCTION_DEBUGGER: | ||
| 350 | string = "Debugger"; | ||
| 351 | break; | ||
| 352 | case VISOR_FUNCTION_HOTSYNC: | ||
| 353 | string = "HotSync"; | ||
| 354 | break; | ||
| 355 | case VISOR_FUNCTION_CONSOLE: | ||
| 356 | string = "Console"; | ||
| 357 | break; | ||
| 358 | case VISOR_FUNCTION_REMOTE_FILE_SYS: | ||
| 359 | string = "Remote File System"; | ||
| 360 | break; | ||
| 361 | default: | ||
| 362 | string = "unknown"; | ||
| 363 | break; | ||
| 364 | } | ||
| 365 | dev_info(dev, "%s: port %d, is for %s use\n", | ||
| 366 | serial->type->description, | ||
| 367 | connection_info->connections[i].port, string); | ||
| 368 | } | ||
| 369 | } | 342 | } |
| 370 | /* | 343 | |
| 371 | * Handle devices that report invalid stuff here. | 344 | connection_info = (struct visor_connection_info *)transfer_buffer; |
| 372 | */ | 345 | |
| 346 | num_ports = le16_to_cpu(connection_info->num_ports); | ||
| 347 | |||
| 348 | /* Handle devices that report invalid stuff here. */ | ||
| 373 | if (num_ports == 0 || num_ports > 2) { | 349 | if (num_ports == 0 || num_ports > 2) { |
| 374 | dev_warn(dev, "%s: No valid connect info available\n", | 350 | dev_warn(dev, "%s: No valid connect info available\n", |
| 375 | serial->type->description); | 351 | serial->type->description); |
| 376 | num_ports = 2; | 352 | num_ports = 2; |
| 377 | } | 353 | } |
| 378 | 354 | ||
| 355 | for (i = 0; i < num_ports; ++i) { | ||
| 356 | switch (connection_info->connections[i].port_function_id) { | ||
| 357 | case VISOR_FUNCTION_GENERIC: | ||
| 358 | string = "Generic"; | ||
| 359 | break; | ||
| 360 | case VISOR_FUNCTION_DEBUGGER: | ||
| 361 | string = "Debugger"; | ||
| 362 | break; | ||
| 363 | case VISOR_FUNCTION_HOTSYNC: | ||
| 364 | string = "HotSync"; | ||
| 365 | break; | ||
| 366 | case VISOR_FUNCTION_CONSOLE: | ||
| 367 | string = "Console"; | ||
| 368 | break; | ||
| 369 | case VISOR_FUNCTION_REMOTE_FILE_SYS: | ||
| 370 | string = "Remote File System"; | ||
| 371 | break; | ||
| 372 | default: | ||
| 373 | string = "unknown"; | ||
| 374 | break; | ||
| 375 | } | ||
| 376 | dev_info(dev, "%s: port %d, is for %s use\n", | ||
| 377 | serial->type->description, | ||
| 378 | connection_info->connections[i].port, string); | ||
| 379 | } | ||
| 379 | dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, | 380 | dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, |
| 380 | num_ports); | 381 | num_ports); |
| 381 | 382 | ||
diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index 677d12138dbd..ded49e3bf2b0 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c | |||
| @@ -3725,6 +3725,7 @@ void tcpm_unregister_port(struct tcpm_port *port) | |||
| 3725 | for (i = 0; i < ARRAY_SIZE(port->port_altmode); i++) | 3725 | for (i = 0; i < ARRAY_SIZE(port->port_altmode); i++) |
| 3726 | typec_unregister_altmode(port->port_altmode[i]); | 3726 | typec_unregister_altmode(port->port_altmode[i]); |
| 3727 | typec_unregister_port(port->typec_port); | 3727 | typec_unregister_port(port->typec_port); |
| 3728 | usb_role_switch_put(port->role_sw); | ||
| 3728 | tcpm_debugfs_exit(port); | 3729 | tcpm_debugfs_exit(port); |
| 3729 | destroy_workqueue(port->wq); | 3730 | destroy_workqueue(port->wq); |
| 3730 | } | 3731 | } |
diff --git a/drivers/usb/typec/tps6598x.c b/drivers/usb/typec/tps6598x.c index 8b8406867c02..4b4c8d271b27 100644 --- a/drivers/usb/typec/tps6598x.c +++ b/drivers/usb/typec/tps6598x.c | |||
| @@ -73,6 +73,7 @@ struct tps6598x { | |||
| 73 | struct device *dev; | 73 | struct device *dev; |
| 74 | struct regmap *regmap; | 74 | struct regmap *regmap; |
| 75 | struct mutex lock; /* device lock */ | 75 | struct mutex lock; /* device lock */ |
| 76 | u8 i2c_protocol:1; | ||
| 76 | 77 | ||
| 77 | struct typec_port *port; | 78 | struct typec_port *port; |
| 78 | struct typec_partner *partner; | 79 | struct typec_partner *partner; |
| @@ -80,19 +81,39 @@ struct tps6598x { | |||
| 80 | struct typec_capability typec_cap; | 81 | struct typec_capability typec_cap; |
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 84 | static int | ||
| 85 | tps6598x_block_read(struct tps6598x *tps, u8 reg, void *val, size_t len) | ||
| 86 | { | ||
| 87 | u8 data[len + 1]; | ||
| 88 | int ret; | ||
| 89 | |||
| 90 | if (!tps->i2c_protocol) | ||
| 91 | return regmap_raw_read(tps->regmap, reg, val, len); | ||
| 92 | |||
| 93 | ret = regmap_raw_read(tps->regmap, reg, data, sizeof(data)); | ||
| 94 | if (ret) | ||
| 95 | return ret; | ||
| 96 | |||
| 97 | if (data[0] < len) | ||
| 98 | return -EIO; | ||
| 99 | |||
| 100 | memcpy(val, &data[1], len); | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 83 | static inline int tps6598x_read16(struct tps6598x *tps, u8 reg, u16 *val) | 104 | static inline int tps6598x_read16(struct tps6598x *tps, u8 reg, u16 *val) |
| 84 | { | 105 | { |
| 85 | return regmap_raw_read(tps->regmap, reg, val, sizeof(u16)); | 106 | return tps6598x_block_read(tps, reg, val, sizeof(u16)); |
| 86 | } | 107 | } |
| 87 | 108 | ||
| 88 | static inline int tps6598x_read32(struct tps6598x *tps, u8 reg, u32 *val) | 109 | static inline int tps6598x_read32(struct tps6598x *tps, u8 reg, u32 *val) |
| 89 | { | 110 | { |
| 90 | return regmap_raw_read(tps->regmap, reg, val, sizeof(u32)); | 111 | return tps6598x_block_read(tps, reg, val, sizeof(u32)); |
| 91 | } | 112 | } |
| 92 | 113 | ||
| 93 | static inline int tps6598x_read64(struct tps6598x *tps, u8 reg, u64 *val) | 114 | static inline int tps6598x_read64(struct tps6598x *tps, u8 reg, u64 *val) |
| 94 | { | 115 | { |
| 95 | return regmap_raw_read(tps->regmap, reg, val, sizeof(u64)); | 116 | return tps6598x_block_read(tps, reg, val, sizeof(u64)); |
| 96 | } | 117 | } |
| 97 | 118 | ||
| 98 | static inline int tps6598x_write16(struct tps6598x *tps, u8 reg, u16 val) | 119 | static inline int tps6598x_write16(struct tps6598x *tps, u8 reg, u16 val) |
| @@ -121,8 +142,8 @@ static int tps6598x_read_partner_identity(struct tps6598x *tps) | |||
| 121 | struct tps6598x_rx_identity_reg id; | 142 | struct tps6598x_rx_identity_reg id; |
| 122 | int ret; | 143 | int ret; |
| 123 | 144 | ||
| 124 | ret = regmap_raw_read(tps->regmap, TPS_REG_RX_IDENTITY_SOP, | 145 | ret = tps6598x_block_read(tps, TPS_REG_RX_IDENTITY_SOP, |
| 125 | &id, sizeof(id)); | 146 | &id, sizeof(id)); |
| 126 | if (ret) | 147 | if (ret) |
| 127 | return ret; | 148 | return ret; |
| 128 | 149 | ||
| @@ -224,13 +245,13 @@ static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd, | |||
| 224 | } while (val); | 245 | } while (val); |
| 225 | 246 | ||
| 226 | if (out_len) { | 247 | if (out_len) { |
| 227 | ret = regmap_raw_read(tps->regmap, TPS_REG_DATA1, | 248 | ret = tps6598x_block_read(tps, TPS_REG_DATA1, |
| 228 | out_data, out_len); | 249 | out_data, out_len); |
| 229 | if (ret) | 250 | if (ret) |
| 230 | return ret; | 251 | return ret; |
| 231 | val = out_data[0]; | 252 | val = out_data[0]; |
| 232 | } else { | 253 | } else { |
| 233 | ret = regmap_read(tps->regmap, TPS_REG_DATA1, &val); | 254 | ret = tps6598x_block_read(tps, TPS_REG_DATA1, &val, sizeof(u8)); |
| 234 | if (ret) | 255 | if (ret) |
| 235 | return ret; | 256 | return ret; |
| 236 | } | 257 | } |
| @@ -385,6 +406,16 @@ static int tps6598x_probe(struct i2c_client *client) | |||
| 385 | if (!vid) | 406 | if (!vid) |
| 386 | return -ENODEV; | 407 | return -ENODEV; |
| 387 | 408 | ||
| 409 | /* | ||
| 410 | * Checking can the adapter handle SMBus protocol. If it can not, the | ||
| 411 | * driver needs to take care of block reads separately. | ||
| 412 | * | ||
| 413 | * FIXME: Testing with I2C_FUNC_I2C. regmap-i2c uses I2C protocol | ||
| 414 | * unconditionally if the adapter has I2C_FUNC_I2C set. | ||
| 415 | */ | ||
| 416 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
| 417 | tps->i2c_protocol = true; | ||
| 418 | |||
| 388 | ret = tps6598x_read32(tps, TPS_REG_STATUS, &status); | 419 | ret = tps6598x_read32(tps, TPS_REG_STATUS, &status); |
| 389 | if (ret < 0) | 420 | if (ret < 0) |
| 390 | return ret; | 421 | return ret; |
diff --git a/drivers/usb/usbip/stub.h b/drivers/usb/usbip/stub.h index 14a72357800a..35618ceb2791 100644 --- a/drivers/usb/usbip/stub.h +++ b/drivers/usb/usbip/stub.h | |||
| @@ -73,6 +73,7 @@ struct bus_id_priv { | |||
| 73 | struct stub_device *sdev; | 73 | struct stub_device *sdev; |
| 74 | struct usb_device *udev; | 74 | struct usb_device *udev; |
| 75 | char shutdown_busid; | 75 | char shutdown_busid; |
| 76 | spinlock_t busid_lock; | ||
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | /* stub_priv is allocated from stub_priv_cache */ | 79 | /* stub_priv is allocated from stub_priv_cache */ |
| @@ -83,6 +84,7 @@ extern struct usb_device_driver stub_driver; | |||
| 83 | 84 | ||
| 84 | /* stub_main.c */ | 85 | /* stub_main.c */ |
| 85 | struct bus_id_priv *get_busid_priv(const char *busid); | 86 | struct bus_id_priv *get_busid_priv(const char *busid); |
| 87 | void put_busid_priv(struct bus_id_priv *bid); | ||
| 86 | int del_match_busid(char *busid); | 88 | int del_match_busid(char *busid); |
| 87 | void stub_device_cleanup_urbs(struct stub_device *sdev); | 89 | void stub_device_cleanup_urbs(struct stub_device *sdev); |
| 88 | 90 | ||
diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index dd8ef36ab10e..c0d6ff1baa72 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c | |||
| @@ -300,9 +300,9 @@ static int stub_probe(struct usb_device *udev) | |||
| 300 | struct stub_device *sdev = NULL; | 300 | struct stub_device *sdev = NULL; |
| 301 | const char *udev_busid = dev_name(&udev->dev); | 301 | const char *udev_busid = dev_name(&udev->dev); |
| 302 | struct bus_id_priv *busid_priv; | 302 | struct bus_id_priv *busid_priv; |
| 303 | int rc; | 303 | int rc = 0; |
| 304 | 304 | ||
| 305 | dev_dbg(&udev->dev, "Enter\n"); | 305 | dev_dbg(&udev->dev, "Enter probe\n"); |
| 306 | 306 | ||
| 307 | /* check we should claim or not by busid_table */ | 307 | /* check we should claim or not by busid_table */ |
| 308 | busid_priv = get_busid_priv(udev_busid); | 308 | busid_priv = get_busid_priv(udev_busid); |
| @@ -317,13 +317,15 @@ static int stub_probe(struct usb_device *udev) | |||
| 317 | * other matched drivers by the driver core. | 317 | * other matched drivers by the driver core. |
| 318 | * See driver_probe_device() in driver/base/dd.c | 318 | * See driver_probe_device() in driver/base/dd.c |
| 319 | */ | 319 | */ |
| 320 | return -ENODEV; | 320 | rc = -ENODEV; |
| 321 | goto call_put_busid_priv; | ||
| 321 | } | 322 | } |
| 322 | 323 | ||
| 323 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) { | 324 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) { |
| 324 | dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n", | 325 | dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n", |
| 325 | udev_busid); | 326 | udev_busid); |
| 326 | return -ENODEV; | 327 | rc = -ENODEV; |
| 328 | goto call_put_busid_priv; | ||
| 327 | } | 329 | } |
| 328 | 330 | ||
| 329 | if (!strcmp(udev->bus->bus_name, "vhci_hcd")) { | 331 | if (!strcmp(udev->bus->bus_name, "vhci_hcd")) { |
| @@ -331,13 +333,16 @@ static int stub_probe(struct usb_device *udev) | |||
| 331 | "%s is attached on vhci_hcd... skip!\n", | 333 | "%s is attached on vhci_hcd... skip!\n", |
| 332 | udev_busid); | 334 | udev_busid); |
| 333 | 335 | ||
| 334 | return -ENODEV; | 336 | rc = -ENODEV; |
| 337 | goto call_put_busid_priv; | ||
| 335 | } | 338 | } |
| 336 | 339 | ||
| 337 | /* ok, this is my device */ | 340 | /* ok, this is my device */ |
| 338 | sdev = stub_device_alloc(udev); | 341 | sdev = stub_device_alloc(udev); |
| 339 | if (!sdev) | 342 | if (!sdev) { |
| 340 | return -ENOMEM; | 343 | rc = -ENOMEM; |
| 344 | goto call_put_busid_priv; | ||
| 345 | } | ||
| 341 | 346 | ||
| 342 | dev_info(&udev->dev, | 347 | dev_info(&udev->dev, |
| 343 | "usbip-host: register new device (bus %u dev %u)\n", | 348 | "usbip-host: register new device (bus %u dev %u)\n", |
| @@ -369,7 +374,9 @@ static int stub_probe(struct usb_device *udev) | |||
| 369 | } | 374 | } |
| 370 | busid_priv->status = STUB_BUSID_ALLOC; | 375 | busid_priv->status = STUB_BUSID_ALLOC; |
| 371 | 376 | ||
| 372 | return 0; | 377 | rc = 0; |
| 378 | goto call_put_busid_priv; | ||
| 379 | |||
| 373 | err_files: | 380 | err_files: |
| 374 | usb_hub_release_port(udev->parent, udev->portnum, | 381 | usb_hub_release_port(udev->parent, udev->portnum, |
| 375 | (struct usb_dev_state *) udev); | 382 | (struct usb_dev_state *) udev); |
| @@ -379,6 +386,9 @@ err_port: | |||
| 379 | 386 | ||
| 380 | busid_priv->sdev = NULL; | 387 | busid_priv->sdev = NULL; |
| 381 | stub_device_free(sdev); | 388 | stub_device_free(sdev); |
| 389 | |||
| 390 | call_put_busid_priv: | ||
| 391 | put_busid_priv(busid_priv); | ||
| 382 | return rc; | 392 | return rc; |
| 383 | } | 393 | } |
| 384 | 394 | ||
| @@ -404,7 +414,7 @@ static void stub_disconnect(struct usb_device *udev) | |||
| 404 | struct bus_id_priv *busid_priv; | 414 | struct bus_id_priv *busid_priv; |
| 405 | int rc; | 415 | int rc; |
| 406 | 416 | ||
| 407 | dev_dbg(&udev->dev, "Enter\n"); | 417 | dev_dbg(&udev->dev, "Enter disconnect\n"); |
| 408 | 418 | ||
| 409 | busid_priv = get_busid_priv(udev_busid); | 419 | busid_priv = get_busid_priv(udev_busid); |
| 410 | if (!busid_priv) { | 420 | if (!busid_priv) { |
| @@ -417,7 +427,7 @@ static void stub_disconnect(struct usb_device *udev) | |||
| 417 | /* get stub_device */ | 427 | /* get stub_device */ |
| 418 | if (!sdev) { | 428 | if (!sdev) { |
| 419 | dev_err(&udev->dev, "could not get device"); | 429 | dev_err(&udev->dev, "could not get device"); |
| 420 | return; | 430 | goto call_put_busid_priv; |
| 421 | } | 431 | } |
| 422 | 432 | ||
| 423 | dev_set_drvdata(&udev->dev, NULL); | 433 | dev_set_drvdata(&udev->dev, NULL); |
| @@ -432,12 +442,12 @@ static void stub_disconnect(struct usb_device *udev) | |||
| 432 | (struct usb_dev_state *) udev); | 442 | (struct usb_dev_state *) udev); |
| 433 | if (rc) { | 443 | if (rc) { |
| 434 | dev_dbg(&udev->dev, "unable to release port\n"); | 444 | dev_dbg(&udev->dev, "unable to release port\n"); |
| 435 | return; | 445 | goto call_put_busid_priv; |
| 436 | } | 446 | } |
| 437 | 447 | ||
| 438 | /* If usb reset is called from event handler */ | 448 | /* If usb reset is called from event handler */ |
| 439 | if (usbip_in_eh(current)) | 449 | if (usbip_in_eh(current)) |
| 440 | return; | 450 | goto call_put_busid_priv; |
| 441 | 451 | ||
| 442 | /* shutdown the current connection */ | 452 | /* shutdown the current connection */ |
| 443 | shutdown_busid(busid_priv); | 453 | shutdown_busid(busid_priv); |
| @@ -448,12 +458,11 @@ static void stub_disconnect(struct usb_device *udev) | |||
| 448 | busid_priv->sdev = NULL; | 458 | busid_priv->sdev = NULL; |
| 449 | stub_device_free(sdev); | 459 | stub_device_free(sdev); |
| 450 | 460 | ||
| 451 | if (busid_priv->status == STUB_BUSID_ALLOC) { | 461 | if (busid_priv->status == STUB_BUSID_ALLOC) |
| 452 | busid_priv->status = STUB_BUSID_ADDED; | 462 | busid_priv->status = STUB_BUSID_ADDED; |
| 453 | } else { | 463 | |
| 454 | busid_priv->status = STUB_BUSID_OTHER; | 464 | call_put_busid_priv: |
| 455 | del_match_busid((char *)udev_busid); | 465 | put_busid_priv(busid_priv); |
| 456 | } | ||
| 457 | } | 466 | } |
| 458 | 467 | ||
| 459 | #ifdef CONFIG_PM | 468 | #ifdef CONFIG_PM |
diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index d41d0cdeec0f..bf8a5feb0ee9 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #define DRIVER_DESC "USB/IP Host Driver" | 14 | #define DRIVER_DESC "USB/IP Host Driver" |
| 15 | 15 | ||
| 16 | struct kmem_cache *stub_priv_cache; | 16 | struct kmem_cache *stub_priv_cache; |
| 17 | |||
| 17 | /* | 18 | /* |
| 18 | * busid_tables defines matching busids that usbip can grab. A user can change | 19 | * busid_tables defines matching busids that usbip can grab. A user can change |
| 19 | * dynamically what device is locally used and what device is exported to a | 20 | * dynamically what device is locally used and what device is exported to a |
| @@ -25,6 +26,8 @@ static spinlock_t busid_table_lock; | |||
| 25 | 26 | ||
| 26 | static void init_busid_table(void) | 27 | static void init_busid_table(void) |
| 27 | { | 28 | { |
| 29 | int i; | ||
| 30 | |||
| 28 | /* | 31 | /* |
| 29 | * This also sets the bus_table[i].status to | 32 | * This also sets the bus_table[i].status to |
| 30 | * STUB_BUSID_OTHER, which is 0. | 33 | * STUB_BUSID_OTHER, which is 0. |
| @@ -32,6 +35,9 @@ static void init_busid_table(void) | |||
| 32 | memset(busid_table, 0, sizeof(busid_table)); | 35 | memset(busid_table, 0, sizeof(busid_table)); |
| 33 | 36 | ||
| 34 | spin_lock_init(&busid_table_lock); | 37 | spin_lock_init(&busid_table_lock); |
| 38 | |||
| 39 | for (i = 0; i < MAX_BUSID; i++) | ||
| 40 | spin_lock_init(&busid_table[i].busid_lock); | ||
| 35 | } | 41 | } |
| 36 | 42 | ||
| 37 | /* | 43 | /* |
| @@ -43,15 +49,20 @@ static int get_busid_idx(const char *busid) | |||
| 43 | int i; | 49 | int i; |
| 44 | int idx = -1; | 50 | int idx = -1; |
| 45 | 51 | ||
| 46 | for (i = 0; i < MAX_BUSID; i++) | 52 | for (i = 0; i < MAX_BUSID; i++) { |
| 53 | spin_lock(&busid_table[i].busid_lock); | ||
| 47 | if (busid_table[i].name[0]) | 54 | if (busid_table[i].name[0]) |
| 48 | if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { | 55 | if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { |
| 49 | idx = i; | 56 | idx = i; |
| 57 | spin_unlock(&busid_table[i].busid_lock); | ||
| 50 | break; | 58 | break; |
| 51 | } | 59 | } |
| 60 | spin_unlock(&busid_table[i].busid_lock); | ||
| 61 | } | ||
| 52 | return idx; | 62 | return idx; |
| 53 | } | 63 | } |
| 54 | 64 | ||
| 65 | /* Returns holding busid_lock. Should call put_busid_priv() to unlock */ | ||
| 55 | struct bus_id_priv *get_busid_priv(const char *busid) | 66 | struct bus_id_priv *get_busid_priv(const char *busid) |
| 56 | { | 67 | { |
| 57 | int idx; | 68 | int idx; |
| @@ -59,13 +70,22 @@ struct bus_id_priv *get_busid_priv(const char *busid) | |||
| 59 | 70 | ||
| 60 | spin_lock(&busid_table_lock); | 71 | spin_lock(&busid_table_lock); |
| 61 | idx = get_busid_idx(busid); | 72 | idx = get_busid_idx(busid); |
| 62 | if (idx >= 0) | 73 | if (idx >= 0) { |
| 63 | bid = &(busid_table[idx]); | 74 | bid = &(busid_table[idx]); |
| 75 | /* get busid_lock before returning */ | ||
| 76 | spin_lock(&bid->busid_lock); | ||
| 77 | } | ||
| 64 | spin_unlock(&busid_table_lock); | 78 | spin_unlock(&busid_table_lock); |
| 65 | 79 | ||
| 66 | return bid; | 80 | return bid; |
| 67 | } | 81 | } |
| 68 | 82 | ||
| 83 | void put_busid_priv(struct bus_id_priv *bid) | ||
| 84 | { | ||
| 85 | if (bid) | ||
| 86 | spin_unlock(&bid->busid_lock); | ||
| 87 | } | ||
| 88 | |||
| 69 | static int add_match_busid(char *busid) | 89 | static int add_match_busid(char *busid) |
| 70 | { | 90 | { |
| 71 | int i; | 91 | int i; |
| @@ -78,15 +98,19 @@ static int add_match_busid(char *busid) | |||
| 78 | goto out; | 98 | goto out; |
| 79 | } | 99 | } |
| 80 | 100 | ||
| 81 | for (i = 0; i < MAX_BUSID; i++) | 101 | for (i = 0; i < MAX_BUSID; i++) { |
| 102 | spin_lock(&busid_table[i].busid_lock); | ||
| 82 | if (!busid_table[i].name[0]) { | 103 | if (!busid_table[i].name[0]) { |
| 83 | strlcpy(busid_table[i].name, busid, BUSID_SIZE); | 104 | strlcpy(busid_table[i].name, busid, BUSID_SIZE); |
| 84 | if ((busid_table[i].status != STUB_BUSID_ALLOC) && | 105 | if ((busid_table[i].status != STUB_BUSID_ALLOC) && |
| 85 | (busid_table[i].status != STUB_BUSID_REMOV)) | 106 | (busid_table[i].status != STUB_BUSID_REMOV)) |
| 86 | busid_table[i].status = STUB_BUSID_ADDED; | 107 | busid_table[i].status = STUB_BUSID_ADDED; |
| 87 | ret = 0; | 108 | ret = 0; |
| 109 | spin_unlock(&busid_table[i].busid_lock); | ||
| 88 | break; | 110 | break; |
| 89 | } | 111 | } |
| 112 | spin_unlock(&busid_table[i].busid_lock); | ||
| 113 | } | ||
| 90 | 114 | ||
| 91 | out: | 115 | out: |
| 92 | spin_unlock(&busid_table_lock); | 116 | spin_unlock(&busid_table_lock); |
| @@ -107,6 +131,8 @@ int del_match_busid(char *busid) | |||
| 107 | /* found */ | 131 | /* found */ |
| 108 | ret = 0; | 132 | ret = 0; |
| 109 | 133 | ||
| 134 | spin_lock(&busid_table[idx].busid_lock); | ||
| 135 | |||
| 110 | if (busid_table[idx].status == STUB_BUSID_OTHER) | 136 | if (busid_table[idx].status == STUB_BUSID_OTHER) |
| 111 | memset(busid_table[idx].name, 0, BUSID_SIZE); | 137 | memset(busid_table[idx].name, 0, BUSID_SIZE); |
| 112 | 138 | ||
| @@ -114,6 +140,7 @@ int del_match_busid(char *busid) | |||
| 114 | (busid_table[idx].status != STUB_BUSID_ADDED)) | 140 | (busid_table[idx].status != STUB_BUSID_ADDED)) |
| 115 | busid_table[idx].status = STUB_BUSID_REMOV; | 141 | busid_table[idx].status = STUB_BUSID_REMOV; |
| 116 | 142 | ||
| 143 | spin_unlock(&busid_table[idx].busid_lock); | ||
| 117 | out: | 144 | out: |
| 118 | spin_unlock(&busid_table_lock); | 145 | spin_unlock(&busid_table_lock); |
| 119 | 146 | ||
| @@ -126,9 +153,12 @@ static ssize_t match_busid_show(struct device_driver *drv, char *buf) | |||
| 126 | char *out = buf; | 153 | char *out = buf; |
| 127 | 154 | ||
| 128 | spin_lock(&busid_table_lock); | 155 | spin_lock(&busid_table_lock); |
| 129 | for (i = 0; i < MAX_BUSID; i++) | 156 | for (i = 0; i < MAX_BUSID; i++) { |
| 157 | spin_lock(&busid_table[i].busid_lock); | ||
| 130 | if (busid_table[i].name[0]) | 158 | if (busid_table[i].name[0]) |
| 131 | out += sprintf(out, "%s ", busid_table[i].name); | 159 | out += sprintf(out, "%s ", busid_table[i].name); |
| 160 | spin_unlock(&busid_table[i].busid_lock); | ||
| 161 | } | ||
| 132 | spin_unlock(&busid_table_lock); | 162 | spin_unlock(&busid_table_lock); |
| 133 | out += sprintf(out, "\n"); | 163 | out += sprintf(out, "\n"); |
| 134 | 164 | ||
| @@ -169,6 +199,51 @@ static ssize_t match_busid_store(struct device_driver *dev, const char *buf, | |||
| 169 | } | 199 | } |
| 170 | static DRIVER_ATTR_RW(match_busid); | 200 | static DRIVER_ATTR_RW(match_busid); |
| 171 | 201 | ||
| 202 | static int do_rebind(char *busid, struct bus_id_priv *busid_priv) | ||
| 203 | { | ||
| 204 | int ret; | ||
| 205 | |||
| 206 | /* device_attach() callers should hold parent lock for USB */ | ||
| 207 | if (busid_priv->udev->dev.parent) | ||
| 208 | device_lock(busid_priv->udev->dev.parent); | ||
| 209 | ret = device_attach(&busid_priv->udev->dev); | ||
| 210 | if (busid_priv->udev->dev.parent) | ||
| 211 | device_unlock(busid_priv->udev->dev.parent); | ||
| 212 | if (ret < 0) { | ||
| 213 | dev_err(&busid_priv->udev->dev, "rebind failed\n"); | ||
| 214 | return ret; | ||
| 215 | } | ||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | static void stub_device_rebind(void) | ||
| 220 | { | ||
| 221 | #if IS_MODULE(CONFIG_USBIP_HOST) | ||
| 222 | struct bus_id_priv *busid_priv; | ||
| 223 | int i; | ||
| 224 | |||
| 225 | /* update status to STUB_BUSID_OTHER so probe ignores the device */ | ||
| 226 | spin_lock(&busid_table_lock); | ||
| 227 | for (i = 0; i < MAX_BUSID; i++) { | ||
| 228 | if (busid_table[i].name[0] && | ||
| 229 | busid_table[i].shutdown_busid) { | ||
| 230 | busid_priv = &(busid_table[i]); | ||
| 231 | busid_priv->status = STUB_BUSID_OTHER; | ||
| 232 | } | ||
| 233 | } | ||
| 234 | spin_unlock(&busid_table_lock); | ||
| 235 | |||
| 236 | /* now run rebind - no need to hold locks. driver files are removed */ | ||
| 237 | for (i = 0; i < MAX_BUSID; i++) { | ||
| 238 | if (busid_table[i].name[0] && | ||
| 239 | busid_table[i].shutdown_busid) { | ||
| 240 | busid_priv = &(busid_table[i]); | ||
| 241 | do_rebind(busid_table[i].name, busid_priv); | ||
| 242 | } | ||
| 243 | } | ||
| 244 | #endif | ||
| 245 | } | ||
| 246 | |||
| 172 | static ssize_t rebind_store(struct device_driver *dev, const char *buf, | 247 | static ssize_t rebind_store(struct device_driver *dev, const char *buf, |
| 173 | size_t count) | 248 | size_t count) |
| 174 | { | 249 | { |
| @@ -186,16 +261,17 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf, | |||
| 186 | if (!bid) | 261 | if (!bid) |
| 187 | return -ENODEV; | 262 | return -ENODEV; |
| 188 | 263 | ||
| 189 | /* device_attach() callers should hold parent lock for USB */ | 264 | /* mark the device for deletion so probe ignores it during rescan */ |
| 190 | if (bid->udev->dev.parent) | 265 | bid->status = STUB_BUSID_OTHER; |
| 191 | device_lock(bid->udev->dev.parent); | 266 | /* release the busid lock */ |
| 192 | ret = device_attach(&bid->udev->dev); | 267 | put_busid_priv(bid); |
| 193 | if (bid->udev->dev.parent) | 268 | |
| 194 | device_unlock(bid->udev->dev.parent); | 269 | ret = do_rebind((char *) buf, bid); |
| 195 | if (ret < 0) { | 270 | if (ret < 0) |
| 196 | dev_err(&bid->udev->dev, "rebind failed\n"); | ||
| 197 | return ret; | 271 | return ret; |
| 198 | } | 272 | |
| 273 | /* delete device from busid_table */ | ||
| 274 | del_match_busid((char *) buf); | ||
| 199 | 275 | ||
| 200 | return count; | 276 | return count; |
| 201 | } | 277 | } |
| @@ -317,6 +393,9 @@ static void __exit usbip_host_exit(void) | |||
| 317 | */ | 393 | */ |
| 318 | usb_deregister_device_driver(&stub_driver); | 394 | usb_deregister_device_driver(&stub_driver); |
| 319 | 395 | ||
| 396 | /* initiate scan to attach devices */ | ||
| 397 | stub_device_rebind(); | ||
| 398 | |||
| 320 | kmem_cache_destroy(stub_priv_cache); | 399 | kmem_cache_destroy(stub_priv_cache); |
| 321 | } | 400 | } |
| 322 | 401 | ||
diff --git a/fs/afs/addr_list.c b/fs/afs/addr_list.c index 3bedfed608a2..7587fb665ff1 100644 --- a/fs/afs/addr_list.c +++ b/fs/afs/addr_list.c | |||
| @@ -121,7 +121,7 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len, | |||
| 121 | p = text; | 121 | p = text; |
| 122 | do { | 122 | do { |
| 123 | struct sockaddr_rxrpc *srx = &alist->addrs[alist->nr_addrs]; | 123 | struct sockaddr_rxrpc *srx = &alist->addrs[alist->nr_addrs]; |
| 124 | char tdelim = delim; | 124 | const char *q, *stop; |
| 125 | 125 | ||
| 126 | if (*p == delim) { | 126 | if (*p == delim) { |
| 127 | p++; | 127 | p++; |
| @@ -130,28 +130,33 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len, | |||
| 130 | 130 | ||
| 131 | if (*p == '[') { | 131 | if (*p == '[') { |
| 132 | p++; | 132 | p++; |
| 133 | tdelim = ']'; | 133 | q = memchr(p, ']', end - p); |
| 134 | } else { | ||
| 135 | for (q = p; q < end; q++) | ||
| 136 | if (*q == '+' || *q == delim) | ||
| 137 | break; | ||
| 134 | } | 138 | } |
| 135 | 139 | ||
| 136 | if (in4_pton(p, end - p, | 140 | if (in4_pton(p, q - p, |
| 137 | (u8 *)&srx->transport.sin6.sin6_addr.s6_addr32[3], | 141 | (u8 *)&srx->transport.sin6.sin6_addr.s6_addr32[3], |
| 138 | tdelim, &p)) { | 142 | -1, &stop)) { |
| 139 | srx->transport.sin6.sin6_addr.s6_addr32[0] = 0; | 143 | srx->transport.sin6.sin6_addr.s6_addr32[0] = 0; |
| 140 | srx->transport.sin6.sin6_addr.s6_addr32[1] = 0; | 144 | srx->transport.sin6.sin6_addr.s6_addr32[1] = 0; |
| 141 | srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); | 145 | srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); |
| 142 | } else if (in6_pton(p, end - p, | 146 | } else if (in6_pton(p, q - p, |
| 143 | srx->transport.sin6.sin6_addr.s6_addr, | 147 | srx->transport.sin6.sin6_addr.s6_addr, |
| 144 | tdelim, &p)) { | 148 | -1, &stop)) { |
| 145 | /* Nothing to do */ | 149 | /* Nothing to do */ |
| 146 | } else { | 150 | } else { |
| 147 | goto bad_address; | 151 | goto bad_address; |
| 148 | } | 152 | } |
| 149 | 153 | ||
| 150 | if (tdelim == ']') { | 154 | if (stop != q) |
| 151 | if (p == end || *p != ']') | 155 | goto bad_address; |
| 152 | goto bad_address; | 156 | |
| 157 | p = q; | ||
| 158 | if (q < end && *q == ']') | ||
| 153 | p++; | 159 | p++; |
| 154 | } | ||
| 155 | 160 | ||
| 156 | if (p < end) { | 161 | if (p < end) { |
| 157 | if (*p == '+') { | 162 | if (*p == '+') { |
diff --git a/fs/afs/callback.c b/fs/afs/callback.c index abd9a84f4e88..571437dcb252 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c | |||
| @@ -23,36 +23,55 @@ | |||
| 23 | /* | 23 | /* |
| 24 | * Set up an interest-in-callbacks record for a volume on a server and | 24 | * Set up an interest-in-callbacks record for a volume on a server and |
| 25 | * register it with the server. | 25 | * register it with the server. |
| 26 | * - Called with volume->server_sem held. | 26 | * - Called with vnode->io_lock held. |
| 27 | */ | 27 | */ |
| 28 | int afs_register_server_cb_interest(struct afs_vnode *vnode, | 28 | int afs_register_server_cb_interest(struct afs_vnode *vnode, |
| 29 | struct afs_server_entry *entry) | 29 | struct afs_server_list *slist, |
| 30 | unsigned int index) | ||
| 30 | { | 31 | { |
| 31 | struct afs_cb_interest *cbi = entry->cb_interest, *vcbi, *new, *x; | 32 | struct afs_server_entry *entry = &slist->servers[index]; |
| 33 | struct afs_cb_interest *cbi, *vcbi, *new, *old; | ||
| 32 | struct afs_server *server = entry->server; | 34 | struct afs_server *server = entry->server; |
| 33 | 35 | ||
| 34 | again: | 36 | again: |
| 37 | if (vnode->cb_interest && | ||
| 38 | likely(vnode->cb_interest == entry->cb_interest)) | ||
| 39 | return 0; | ||
| 40 | |||
| 41 | read_lock(&slist->lock); | ||
| 42 | cbi = afs_get_cb_interest(entry->cb_interest); | ||
| 43 | read_unlock(&slist->lock); | ||
| 44 | |||
| 35 | vcbi = vnode->cb_interest; | 45 | vcbi = vnode->cb_interest; |
| 36 | if (vcbi) { | 46 | if (vcbi) { |
| 37 | if (vcbi == cbi) | 47 | if (vcbi == cbi) { |
| 48 | afs_put_cb_interest(afs_v2net(vnode), cbi); | ||
| 38 | return 0; | 49 | return 0; |
| 50 | } | ||
| 39 | 51 | ||
| 52 | /* Use a new interest in the server list for the same server | ||
| 53 | * rather than an old one that's still attached to a vnode. | ||
| 54 | */ | ||
| 40 | if (cbi && vcbi->server == cbi->server) { | 55 | if (cbi && vcbi->server == cbi->server) { |
| 41 | write_seqlock(&vnode->cb_lock); | 56 | write_seqlock(&vnode->cb_lock); |
| 42 | vnode->cb_interest = afs_get_cb_interest(cbi); | 57 | old = vnode->cb_interest; |
| 58 | vnode->cb_interest = cbi; | ||
| 43 | write_sequnlock(&vnode->cb_lock); | 59 | write_sequnlock(&vnode->cb_lock); |
| 44 | afs_put_cb_interest(afs_v2net(vnode), cbi); | 60 | afs_put_cb_interest(afs_v2net(vnode), old); |
| 45 | return 0; | 61 | return 0; |
| 46 | } | 62 | } |
| 47 | 63 | ||
| 64 | /* Re-use the one attached to the vnode. */ | ||
| 48 | if (!cbi && vcbi->server == server) { | 65 | if (!cbi && vcbi->server == server) { |
| 49 | afs_get_cb_interest(vcbi); | 66 | write_lock(&slist->lock); |
| 50 | x = cmpxchg(&entry->cb_interest, cbi, vcbi); | 67 | if (entry->cb_interest) { |
| 51 | if (x != cbi) { | 68 | write_unlock(&slist->lock); |
| 52 | cbi = x; | 69 | afs_put_cb_interest(afs_v2net(vnode), cbi); |
| 53 | afs_put_cb_interest(afs_v2net(vnode), vcbi); | ||
| 54 | goto again; | 70 | goto again; |
| 55 | } | 71 | } |
| 72 | |||
| 73 | entry->cb_interest = cbi; | ||
| 74 | write_unlock(&slist->lock); | ||
| 56 | return 0; | 75 | return 0; |
| 57 | } | 76 | } |
| 58 | } | 77 | } |
| @@ -72,13 +91,16 @@ again: | |||
| 72 | list_add_tail(&new->cb_link, &server->cb_interests); | 91 | list_add_tail(&new->cb_link, &server->cb_interests); |
| 73 | write_unlock(&server->cb_break_lock); | 92 | write_unlock(&server->cb_break_lock); |
| 74 | 93 | ||
| 75 | x = cmpxchg(&entry->cb_interest, cbi, new); | 94 | write_lock(&slist->lock); |
| 76 | if (x == cbi) { | 95 | if (!entry->cb_interest) { |
| 96 | entry->cb_interest = afs_get_cb_interest(new); | ||
| 77 | cbi = new; | 97 | cbi = new; |
| 98 | new = NULL; | ||
| 78 | } else { | 99 | } else { |
| 79 | cbi = x; | 100 | cbi = afs_get_cb_interest(entry->cb_interest); |
| 80 | afs_put_cb_interest(afs_v2net(vnode), new); | ||
| 81 | } | 101 | } |
| 102 | write_unlock(&slist->lock); | ||
| 103 | afs_put_cb_interest(afs_v2net(vnode), new); | ||
| 82 | } | 104 | } |
| 83 | 105 | ||
| 84 | ASSERT(cbi); | 106 | ASSERT(cbi); |
| @@ -88,11 +110,14 @@ again: | |||
| 88 | */ | 110 | */ |
| 89 | write_seqlock(&vnode->cb_lock); | 111 | write_seqlock(&vnode->cb_lock); |
| 90 | 112 | ||
| 91 | vnode->cb_interest = afs_get_cb_interest(cbi); | 113 | old = vnode->cb_interest; |
| 114 | vnode->cb_interest = cbi; | ||
| 92 | vnode->cb_s_break = cbi->server->cb_s_break; | 115 | vnode->cb_s_break = cbi->server->cb_s_break; |
| 116 | vnode->cb_v_break = vnode->volume->cb_v_break; | ||
| 93 | clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); | 117 | clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); |
| 94 | 118 | ||
| 95 | write_sequnlock(&vnode->cb_lock); | 119 | write_sequnlock(&vnode->cb_lock); |
| 120 | afs_put_cb_interest(afs_v2net(vnode), old); | ||
| 96 | return 0; | 121 | return 0; |
| 97 | } | 122 | } |
| 98 | 123 | ||
| @@ -171,13 +196,24 @@ static void afs_break_one_callback(struct afs_server *server, | |||
| 171 | if (cbi->vid != fid->vid) | 196 | if (cbi->vid != fid->vid) |
| 172 | continue; | 197 | continue; |
| 173 | 198 | ||
| 174 | data.volume = NULL; | 199 | if (fid->vnode == 0 && fid->unique == 0) { |
| 175 | data.fid = *fid; | 200 | /* The callback break applies to an entire volume. */ |
| 176 | inode = ilookup5_nowait(cbi->sb, fid->vnode, afs_iget5_test, &data); | 201 | struct afs_super_info *as = AFS_FS_S(cbi->sb); |
| 177 | if (inode) { | 202 | struct afs_volume *volume = as->volume; |
| 178 | vnode = AFS_FS_I(inode); | 203 | |
| 179 | afs_break_callback(vnode); | 204 | write_lock(&volume->cb_break_lock); |
| 180 | iput(inode); | 205 | volume->cb_v_break++; |
| 206 | write_unlock(&volume->cb_break_lock); | ||
| 207 | } else { | ||
| 208 | data.volume = NULL; | ||
| 209 | data.fid = *fid; | ||
| 210 | inode = ilookup5_nowait(cbi->sb, fid->vnode, | ||
| 211 | afs_iget5_test, &data); | ||
| 212 | if (inode) { | ||
| 213 | vnode = AFS_FS_I(inode); | ||
| 214 | afs_break_callback(vnode); | ||
| 215 | iput(inode); | ||
| 216 | } | ||
| 181 | } | 217 | } |
| 182 | } | 218 | } |
| 183 | 219 | ||
| @@ -195,6 +231,8 @@ void afs_break_callbacks(struct afs_server *server, size_t count, | |||
| 195 | ASSERT(server != NULL); | 231 | ASSERT(server != NULL); |
| 196 | ASSERTCMP(count, <=, AFSCBMAX); | 232 | ASSERTCMP(count, <=, AFSCBMAX); |
| 197 | 233 | ||
| 234 | /* TODO: Sort the callback break list by volume ID */ | ||
| 235 | |||
| 198 | for (; count > 0; callbacks++, count--) { | 236 | for (; count > 0; callbacks++, count--) { |
| 199 | _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }", | 237 | _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }", |
| 200 | callbacks->fid.vid, | 238 | callbacks->fid.vid, |
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 357de908df3a..c332c95a6940 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
| @@ -133,21 +133,10 @@ bool afs_cm_incoming_call(struct afs_call *call) | |||
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | /* | 135 | /* |
| 136 | * clean up a cache manager call | 136 | * Clean up a cache manager call. |
| 137 | */ | 137 | */ |
| 138 | static void afs_cm_destructor(struct afs_call *call) | 138 | static void afs_cm_destructor(struct afs_call *call) |
| 139 | { | 139 | { |
| 140 | _enter(""); | ||
| 141 | |||
| 142 | /* Break the callbacks here so that we do it after the final ACK is | ||
| 143 | * received. The step number here must match the final number in | ||
| 144 | * afs_deliver_cb_callback(). | ||
| 145 | */ | ||
| 146 | if (call->unmarshall == 5) { | ||
| 147 | ASSERT(call->cm_server && call->count && call->request); | ||
| 148 | afs_break_callbacks(call->cm_server, call->count, call->request); | ||
| 149 | } | ||
| 150 | |||
| 151 | kfree(call->buffer); | 140 | kfree(call->buffer); |
| 152 | call->buffer = NULL; | 141 | call->buffer = NULL; |
| 153 | } | 142 | } |
| @@ -161,14 +150,14 @@ static void SRXAFSCB_CallBack(struct work_struct *work) | |||
| 161 | 150 | ||
| 162 | _enter(""); | 151 | _enter(""); |
| 163 | 152 | ||
| 164 | /* be sure to send the reply *before* attempting to spam the AFS server | 153 | /* We need to break the callbacks before sending the reply as the |
| 165 | * with FSFetchStatus requests on the vnodes with broken callbacks lest | 154 | * server holds up change visibility till it receives our reply so as |
| 166 | * the AFS server get into a vicious cycle of trying to break further | 155 | * to maintain cache coherency. |
| 167 | * callbacks because it hadn't received completion of the CBCallBack op | 156 | */ |
| 168 | * yet */ | 157 | if (call->cm_server) |
| 169 | afs_send_empty_reply(call); | 158 | afs_break_callbacks(call->cm_server, call->count, call->request); |
| 170 | 159 | ||
| 171 | afs_break_callbacks(call->cm_server, call->count, call->request); | 160 | afs_send_empty_reply(call); |
| 172 | afs_put_call(call); | 161 | afs_put_call(call); |
| 173 | _leave(""); | 162 | _leave(""); |
| 174 | } | 163 | } |
| @@ -180,7 +169,6 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
| 180 | { | 169 | { |
| 181 | struct afs_callback_break *cb; | 170 | struct afs_callback_break *cb; |
| 182 | struct sockaddr_rxrpc srx; | 171 | struct sockaddr_rxrpc srx; |
| 183 | struct afs_server *server; | ||
| 184 | __be32 *bp; | 172 | __be32 *bp; |
| 185 | int ret, loop; | 173 | int ret, loop; |
| 186 | 174 | ||
| @@ -267,15 +255,6 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
| 267 | 255 | ||
| 268 | call->offset = 0; | 256 | call->offset = 0; |
| 269 | call->unmarshall++; | 257 | call->unmarshall++; |
| 270 | |||
| 271 | /* Record that the message was unmarshalled successfully so | ||
| 272 | * that the call destructor can know do the callback breaking | ||
| 273 | * work, even if the final ACK isn't received. | ||
| 274 | * | ||
| 275 | * If the step number changes, then afs_cm_destructor() must be | ||
| 276 | * updated also. | ||
| 277 | */ | ||
| 278 | call->unmarshall++; | ||
| 279 | case 5: | 258 | case 5: |
| 280 | break; | 259 | break; |
| 281 | } | 260 | } |
| @@ -286,10 +265,9 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
| 286 | /* we'll need the file server record as that tells us which set of | 265 | /* we'll need the file server record as that tells us which set of |
| 287 | * vnodes to operate upon */ | 266 | * vnodes to operate upon */ |
| 288 | rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); | 267 | rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); |
| 289 | server = afs_find_server(call->net, &srx); | 268 | call->cm_server = afs_find_server(call->net, &srx); |
| 290 | if (!server) | 269 | if (!call->cm_server) |
| 291 | return -ENOTCONN; | 270 | trace_afs_cm_no_server(call, &srx); |
| 292 | call->cm_server = server; | ||
| 293 | 271 | ||
| 294 | return afs_queue_call_work(call); | 272 | return afs_queue_call_work(call); |
| 295 | } | 273 | } |
| @@ -303,7 +281,8 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work) | |||
| 303 | 281 | ||
| 304 | _enter("{%p}", call->cm_server); | 282 | _enter("{%p}", call->cm_server); |
| 305 | 283 | ||
| 306 | afs_init_callback_state(call->cm_server); | 284 | if (call->cm_server) |
| 285 | afs_init_callback_state(call->cm_server); | ||
| 307 | afs_send_empty_reply(call); | 286 | afs_send_empty_reply(call); |
| 308 | afs_put_call(call); | 287 | afs_put_call(call); |
| 309 | _leave(""); | 288 | _leave(""); |
| @@ -315,7 +294,6 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work) | |||
| 315 | static int afs_deliver_cb_init_call_back_state(struct afs_call *call) | 294 | static int afs_deliver_cb_init_call_back_state(struct afs_call *call) |
| 316 | { | 295 | { |
| 317 | struct sockaddr_rxrpc srx; | 296 | struct sockaddr_rxrpc srx; |
| 318 | struct afs_server *server; | ||
| 319 | int ret; | 297 | int ret; |
| 320 | 298 | ||
| 321 | _enter(""); | 299 | _enter(""); |
| @@ -328,10 +306,9 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call) | |||
| 328 | 306 | ||
| 329 | /* we'll need the file server record as that tells us which set of | 307 | /* we'll need the file server record as that tells us which set of |
| 330 | * vnodes to operate upon */ | 308 | * vnodes to operate upon */ |
| 331 | server = afs_find_server(call->net, &srx); | 309 | call->cm_server = afs_find_server(call->net, &srx); |
| 332 | if (!server) | 310 | if (!call->cm_server) |
| 333 | return -ENOTCONN; | 311 | trace_afs_cm_no_server(call, &srx); |
| 334 | call->cm_server = server; | ||
| 335 | 312 | ||
| 336 | return afs_queue_call_work(call); | 313 | return afs_queue_call_work(call); |
| 337 | } | 314 | } |
| @@ -341,8 +318,6 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call) | |||
| 341 | */ | 318 | */ |
| 342 | static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) | 319 | static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) |
| 343 | { | 320 | { |
| 344 | struct sockaddr_rxrpc srx; | ||
| 345 | struct afs_server *server; | ||
| 346 | struct afs_uuid *r; | 321 | struct afs_uuid *r; |
| 347 | unsigned loop; | 322 | unsigned loop; |
| 348 | __be32 *b; | 323 | __be32 *b; |
| @@ -398,11 +373,11 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) | |||
| 398 | 373 | ||
| 399 | /* we'll need the file server record as that tells us which set of | 374 | /* we'll need the file server record as that tells us which set of |
| 400 | * vnodes to operate upon */ | 375 | * vnodes to operate upon */ |
| 401 | rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); | 376 | rcu_read_lock(); |
| 402 | server = afs_find_server(call->net, &srx); | 377 | call->cm_server = afs_find_server_by_uuid(call->net, call->request); |
| 403 | if (!server) | 378 | rcu_read_unlock(); |
| 404 | return -ENOTCONN; | 379 | if (!call->cm_server) |
| 405 | call->cm_server = server; | 380 | trace_afs_cm_no_server_u(call, call->request); |
| 406 | 381 | ||
| 407 | return afs_queue_call_work(call); | 382 | return afs_queue_call_work(call); |
| 408 | } | 383 | } |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 5889f70d4d27..7d623008157f 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
| @@ -180,6 +180,7 @@ static int afs_dir_open(struct inode *inode, struct file *file) | |||
| 180 | * get reclaimed during the iteration. | 180 | * get reclaimed during the iteration. |
| 181 | */ | 181 | */ |
| 182 | static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) | 182 | static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) |
| 183 | __acquires(&dvnode->validate_lock) | ||
| 183 | { | 184 | { |
| 184 | struct afs_read *req; | 185 | struct afs_read *req; |
| 185 | loff_t i_size; | 186 | loff_t i_size; |
| @@ -261,18 +262,21 @@ retry: | |||
| 261 | /* If we're going to reload, we need to lock all the pages to prevent | 262 | /* If we're going to reload, we need to lock all the pages to prevent |
| 262 | * races. | 263 | * races. |
| 263 | */ | 264 | */ |
| 264 | if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { | 265 | ret = -ERESTARTSYS; |
| 265 | ret = -ERESTARTSYS; | 266 | if (down_read_killable(&dvnode->validate_lock) < 0) |
| 266 | for (i = 0; i < req->nr_pages; i++) | 267 | goto error; |
| 267 | if (lock_page_killable(req->pages[i]) < 0) | ||
| 268 | goto error_unlock; | ||
| 269 | 268 | ||
| 270 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) | 269 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) |
| 271 | goto success; | 270 | goto success; |
| 271 | |||
| 272 | up_read(&dvnode->validate_lock); | ||
| 273 | if (down_write_killable(&dvnode->validate_lock) < 0) | ||
| 274 | goto error; | ||
| 272 | 275 | ||
| 276 | if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { | ||
| 273 | ret = afs_fetch_data(dvnode, key, req); | 277 | ret = afs_fetch_data(dvnode, key, req); |
| 274 | if (ret < 0) | 278 | if (ret < 0) |
| 275 | goto error_unlock_all; | 279 | goto error_unlock; |
| 276 | 280 | ||
| 277 | task_io_account_read(PAGE_SIZE * req->nr_pages); | 281 | task_io_account_read(PAGE_SIZE * req->nr_pages); |
| 278 | 282 | ||
| @@ -284,33 +288,26 @@ retry: | |||
| 284 | for (i = 0; i < req->nr_pages; i++) | 288 | for (i = 0; i < req->nr_pages; i++) |
| 285 | if (!afs_dir_check_page(dvnode, req->pages[i], | 289 | if (!afs_dir_check_page(dvnode, req->pages[i], |
| 286 | req->actual_len)) | 290 | req->actual_len)) |
| 287 | goto error_unlock_all; | 291 | goto error_unlock; |
| 288 | 292 | ||
| 289 | // TODO: Trim excess pages | 293 | // TODO: Trim excess pages |
| 290 | 294 | ||
| 291 | set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags); | 295 | set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags); |
| 292 | } | 296 | } |
| 293 | 297 | ||
| 298 | downgrade_write(&dvnode->validate_lock); | ||
| 294 | success: | 299 | success: |
| 295 | i = req->nr_pages; | ||
| 296 | while (i > 0) | ||
| 297 | unlock_page(req->pages[--i]); | ||
| 298 | return req; | 300 | return req; |
| 299 | 301 | ||
| 300 | error_unlock_all: | ||
| 301 | i = req->nr_pages; | ||
| 302 | error_unlock: | 302 | error_unlock: |
| 303 | while (i > 0) | 303 | up_write(&dvnode->validate_lock); |
| 304 | unlock_page(req->pages[--i]); | ||
| 305 | error: | 304 | error: |
| 306 | afs_put_read(req); | 305 | afs_put_read(req); |
| 307 | _leave(" = %d", ret); | 306 | _leave(" = %d", ret); |
| 308 | return ERR_PTR(ret); | 307 | return ERR_PTR(ret); |
| 309 | 308 | ||
| 310 | content_has_grown: | 309 | content_has_grown: |
| 311 | i = req->nr_pages; | 310 | up_write(&dvnode->validate_lock); |
| 312 | while (i > 0) | ||
| 313 | unlock_page(req->pages[--i]); | ||
| 314 | afs_put_read(req); | 311 | afs_put_read(req); |
| 315 | goto retry; | 312 | goto retry; |
| 316 | } | 313 | } |
| @@ -473,6 +470,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, | |||
| 473 | } | 470 | } |
| 474 | 471 | ||
| 475 | out: | 472 | out: |
| 473 | up_read(&dvnode->validate_lock); | ||
| 476 | afs_put_read(req); | 474 | afs_put_read(req); |
| 477 | _leave(" = %d", ret); | 475 | _leave(" = %d", ret); |
| 478 | return ret; | 476 | return ret; |
| @@ -1143,7 +1141,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 1143 | ret = -ERESTARTSYS; | 1141 | ret = -ERESTARTSYS; |
| 1144 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | 1142 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { |
| 1145 | while (afs_select_fileserver(&fc)) { | 1143 | while (afs_select_fileserver(&fc)) { |
| 1146 | fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; | 1144 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
| 1147 | afs_fs_create(&fc, dentry->d_name.name, mode, data_version, | 1145 | afs_fs_create(&fc, dentry->d_name.name, mode, data_version, |
| 1148 | &newfid, &newstatus, &newcb); | 1146 | &newfid, &newstatus, &newcb); |
| 1149 | } | 1147 | } |
| @@ -1213,7 +1211,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 1213 | ret = -ERESTARTSYS; | 1211 | ret = -ERESTARTSYS; |
| 1214 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | 1212 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { |
| 1215 | while (afs_select_fileserver(&fc)) { | 1213 | while (afs_select_fileserver(&fc)) { |
| 1216 | fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; | 1214 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
| 1217 | afs_fs_remove(&fc, dentry->d_name.name, true, | 1215 | afs_fs_remove(&fc, dentry->d_name.name, true, |
| 1218 | data_version); | 1216 | data_version); |
| 1219 | } | 1217 | } |
| @@ -1316,7 +1314,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 1316 | ret = -ERESTARTSYS; | 1314 | ret = -ERESTARTSYS; |
| 1317 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | 1315 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { |
| 1318 | while (afs_select_fileserver(&fc)) { | 1316 | while (afs_select_fileserver(&fc)) { |
| 1319 | fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; | 1317 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
| 1320 | afs_fs_remove(&fc, dentry->d_name.name, false, | 1318 | afs_fs_remove(&fc, dentry->d_name.name, false, |
| 1321 | data_version); | 1319 | data_version); |
| 1322 | } | 1320 | } |
| @@ -1373,7 +1371,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
| 1373 | ret = -ERESTARTSYS; | 1371 | ret = -ERESTARTSYS; |
| 1374 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | 1372 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { |
| 1375 | while (afs_select_fileserver(&fc)) { | 1373 | while (afs_select_fileserver(&fc)) { |
| 1376 | fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; | 1374 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
| 1377 | afs_fs_create(&fc, dentry->d_name.name, mode, data_version, | 1375 | afs_fs_create(&fc, dentry->d_name.name, mode, data_version, |
| 1378 | &newfid, &newstatus, &newcb); | 1376 | &newfid, &newstatus, &newcb); |
| 1379 | } | 1377 | } |
| @@ -1443,8 +1441,8 @@ static int afs_link(struct dentry *from, struct inode *dir, | |||
| 1443 | } | 1441 | } |
| 1444 | 1442 | ||
| 1445 | while (afs_select_fileserver(&fc)) { | 1443 | while (afs_select_fileserver(&fc)) { |
| 1446 | fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; | 1444 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
| 1447 | fc.cb_break_2 = vnode->cb_break + vnode->cb_s_break; | 1445 | fc.cb_break_2 = afs_calc_vnode_cb_break(vnode); |
| 1448 | afs_fs_link(&fc, vnode, dentry->d_name.name, data_version); | 1446 | afs_fs_link(&fc, vnode, dentry->d_name.name, data_version); |
| 1449 | } | 1447 | } |
| 1450 | 1448 | ||
| @@ -1512,7 +1510,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 1512 | ret = -ERESTARTSYS; | 1510 | ret = -ERESTARTSYS; |
| 1513 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | 1511 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { |
| 1514 | while (afs_select_fileserver(&fc)) { | 1512 | while (afs_select_fileserver(&fc)) { |
| 1515 | fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; | 1513 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
| 1516 | afs_fs_symlink(&fc, dentry->d_name.name, | 1514 | afs_fs_symlink(&fc, dentry->d_name.name, |
| 1517 | content, data_version, | 1515 | content, data_version, |
| 1518 | &newfid, &newstatus); | 1516 | &newfid, &newstatus); |
| @@ -1588,8 +1586,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 1588 | } | 1586 | } |
| 1589 | } | 1587 | } |
| 1590 | while (afs_select_fileserver(&fc)) { | 1588 | while (afs_select_fileserver(&fc)) { |
| 1591 | fc.cb_break = orig_dvnode->cb_break + orig_dvnode->cb_s_break; | 1589 | fc.cb_break = afs_calc_vnode_cb_break(orig_dvnode); |
| 1592 | fc.cb_break_2 = new_dvnode->cb_break + new_dvnode->cb_s_break; | 1590 | fc.cb_break_2 = afs_calc_vnode_cb_break(new_dvnode); |
| 1593 | afs_fs_rename(&fc, old_dentry->d_name.name, | 1591 | afs_fs_rename(&fc, old_dentry->d_name.name, |
| 1594 | new_dvnode, new_dentry->d_name.name, | 1592 | new_dvnode, new_dentry->d_name.name, |
| 1595 | orig_data_version, new_data_version); | 1593 | orig_data_version, new_data_version); |
diff --git a/fs/afs/file.c b/fs/afs/file.c index c24c08016dd9..7d4f26198573 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
| @@ -238,7 +238,7 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *de | |||
| 238 | ret = -ERESTARTSYS; | 238 | ret = -ERESTARTSYS; |
| 239 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | 239 | if (afs_begin_vnode_operation(&fc, vnode, key)) { |
| 240 | while (afs_select_fileserver(&fc)) { | 240 | while (afs_select_fileserver(&fc)) { |
| 241 | fc.cb_break = vnode->cb_break + vnode->cb_s_break; | 241 | fc.cb_break = afs_calc_vnode_cb_break(vnode); |
| 242 | afs_fs_fetch_data(&fc, desc); | 242 | afs_fs_fetch_data(&fc, desc); |
| 243 | } | 243 | } |
| 244 | 244 | ||
diff --git a/fs/afs/flock.c b/fs/afs/flock.c index 7a0e017070ec..dc62d15a964b 100644 --- a/fs/afs/flock.c +++ b/fs/afs/flock.c | |||
| @@ -86,7 +86,7 @@ static int afs_set_lock(struct afs_vnode *vnode, struct key *key, | |||
| 86 | ret = -ERESTARTSYS; | 86 | ret = -ERESTARTSYS; |
| 87 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | 87 | if (afs_begin_vnode_operation(&fc, vnode, key)) { |
| 88 | while (afs_select_fileserver(&fc)) { | 88 | while (afs_select_fileserver(&fc)) { |
| 89 | fc.cb_break = vnode->cb_break + vnode->cb_s_break; | 89 | fc.cb_break = afs_calc_vnode_cb_break(vnode); |
| 90 | afs_fs_set_lock(&fc, type); | 90 | afs_fs_set_lock(&fc, type); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| @@ -117,7 +117,7 @@ static int afs_extend_lock(struct afs_vnode *vnode, struct key *key) | |||
| 117 | ret = -ERESTARTSYS; | 117 | ret = -ERESTARTSYS; |
| 118 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | 118 | if (afs_begin_vnode_operation(&fc, vnode, key)) { |
| 119 | while (afs_select_current_fileserver(&fc)) { | 119 | while (afs_select_current_fileserver(&fc)) { |
| 120 | fc.cb_break = vnode->cb_break + vnode->cb_s_break; | 120 | fc.cb_break = afs_calc_vnode_cb_break(vnode); |
| 121 | afs_fs_extend_lock(&fc); | 121 | afs_fs_extend_lock(&fc); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| @@ -148,7 +148,7 @@ static int afs_release_lock(struct afs_vnode *vnode, struct key *key) | |||
| 148 | ret = -ERESTARTSYS; | 148 | ret = -ERESTARTSYS; |
| 149 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | 149 | if (afs_begin_vnode_operation(&fc, vnode, key)) { |
| 150 | while (afs_select_current_fileserver(&fc)) { | 150 | while (afs_select_current_fileserver(&fc)) { |
| 151 | fc.cb_break = vnode->cb_break + vnode->cb_s_break; | 151 | fc.cb_break = afs_calc_vnode_cb_break(vnode); |
| 152 | afs_fs_release_lock(&fc); | 152 | afs_fs_release_lock(&fc); |
| 153 | } | 153 | } |
| 154 | 154 | ||
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index efacdb7c1dee..b273e1d60478 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
| @@ -134,6 +134,7 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call, | |||
| 134 | struct afs_read *read_req) | 134 | struct afs_read *read_req) |
| 135 | { | 135 | { |
| 136 | const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp; | 136 | const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp; |
| 137 | bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus); | ||
| 137 | u64 data_version, size; | 138 | u64 data_version, size; |
| 138 | u32 type, abort_code; | 139 | u32 type, abort_code; |
| 139 | u8 flags = 0; | 140 | u8 flags = 0; |
| @@ -142,13 +143,32 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call, | |||
| 142 | if (vnode) | 143 | if (vnode) |
| 143 | write_seqlock(&vnode->cb_lock); | 144 | write_seqlock(&vnode->cb_lock); |
| 144 | 145 | ||
| 146 | abort_code = ntohl(xdr->abort_code); | ||
| 147 | |||
| 145 | if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) { | 148 | if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) { |
| 149 | if (xdr->if_version == htonl(0) && | ||
| 150 | abort_code != 0 && | ||
| 151 | inline_error) { | ||
| 152 | /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus | ||
| 153 | * whereby it doesn't set the interface version in the error | ||
| 154 | * case. | ||
| 155 | */ | ||
| 156 | status->abort_code = abort_code; | ||
| 157 | ret = 0; | ||
| 158 | goto out; | ||
| 159 | } | ||
| 160 | |||
| 146 | pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); | 161 | pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); |
| 147 | goto bad; | 162 | goto bad; |
| 148 | } | 163 | } |
| 149 | 164 | ||
| 165 | if (abort_code != 0 && inline_error) { | ||
| 166 | status->abort_code = abort_code; | ||
| 167 | ret = 0; | ||
| 168 | goto out; | ||
| 169 | } | ||
| 170 | |||
| 150 | type = ntohl(xdr->type); | 171 | type = ntohl(xdr->type); |
| 151 | abort_code = ntohl(xdr->abort_code); | ||
| 152 | switch (type) { | 172 | switch (type) { |
| 153 | case AFS_FTYPE_FILE: | 173 | case AFS_FTYPE_FILE: |
| 154 | case AFS_FTYPE_DIR: | 174 | case AFS_FTYPE_DIR: |
| @@ -165,13 +185,6 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call, | |||
| 165 | } | 185 | } |
| 166 | status->type = type; | 186 | status->type = type; |
| 167 | break; | 187 | break; |
| 168 | case AFS_FTYPE_INVALID: | ||
| 169 | if (abort_code != 0) { | ||
| 170 | status->abort_code = abort_code; | ||
| 171 | ret = 0; | ||
| 172 | goto out; | ||
| 173 | } | ||
| 174 | /* Fall through */ | ||
| 175 | default: | 188 | default: |
| 176 | goto bad; | 189 | goto bad; |
| 177 | } | 190 | } |
| @@ -248,7 +261,7 @@ static void xdr_decode_AFSCallBack(struct afs_call *call, | |||
| 248 | 261 | ||
| 249 | write_seqlock(&vnode->cb_lock); | 262 | write_seqlock(&vnode->cb_lock); |
| 250 | 263 | ||
| 251 | if (call->cb_break == (vnode->cb_break + cbi->server->cb_s_break)) { | 264 | if (call->cb_break == afs_cb_break_sum(vnode, cbi)) { |
| 252 | vnode->cb_version = ntohl(*bp++); | 265 | vnode->cb_version = ntohl(*bp++); |
| 253 | cb_expiry = ntohl(*bp++); | 266 | cb_expiry = ntohl(*bp++); |
| 254 | vnode->cb_type = ntohl(*bp++); | 267 | vnode->cb_type = ntohl(*bp++); |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 06194cfe9724..479b7fdda124 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
| @@ -108,7 +108,7 @@ int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool new_inode) | |||
| 108 | ret = -ERESTARTSYS; | 108 | ret = -ERESTARTSYS; |
| 109 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | 109 | if (afs_begin_vnode_operation(&fc, vnode, key)) { |
| 110 | while (afs_select_fileserver(&fc)) { | 110 | while (afs_select_fileserver(&fc)) { |
| 111 | fc.cb_break = vnode->cb_break + vnode->cb_s_break; | 111 | fc.cb_break = afs_calc_vnode_cb_break(vnode); |
| 112 | afs_fs_fetch_file_status(&fc, NULL, new_inode); | 112 | afs_fs_fetch_file_status(&fc, NULL, new_inode); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| @@ -393,15 +393,18 @@ int afs_validate(struct afs_vnode *vnode, struct key *key) | |||
| 393 | read_seqlock_excl(&vnode->cb_lock); | 393 | read_seqlock_excl(&vnode->cb_lock); |
| 394 | 394 | ||
| 395 | if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { | 395 | if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { |
| 396 | if (vnode->cb_s_break != vnode->cb_interest->server->cb_s_break) { | 396 | if (vnode->cb_s_break != vnode->cb_interest->server->cb_s_break || |
| 397 | vnode->cb_v_break != vnode->volume->cb_v_break) { | ||
| 397 | vnode->cb_s_break = vnode->cb_interest->server->cb_s_break; | 398 | vnode->cb_s_break = vnode->cb_interest->server->cb_s_break; |
| 399 | vnode->cb_v_break = vnode->volume->cb_v_break; | ||
| 400 | valid = false; | ||
| 398 | } else if (vnode->status.type == AFS_FTYPE_DIR && | 401 | } else if (vnode->status.type == AFS_FTYPE_DIR && |
| 399 | test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) && | 402 | test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) && |
| 400 | vnode->cb_expires_at - 10 > now) { | 403 | vnode->cb_expires_at - 10 > now) { |
| 401 | valid = true; | 404 | valid = true; |
| 402 | } else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) && | 405 | } else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) && |
| 403 | vnode->cb_expires_at - 10 > now) { | 406 | vnode->cb_expires_at - 10 > now) { |
| 404 | valid = true; | 407 | valid = true; |
| 405 | } | 408 | } |
| 406 | } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { | 409 | } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { |
| 407 | valid = true; | 410 | valid = true; |
| @@ -415,7 +418,7 @@ int afs_validate(struct afs_vnode *vnode, struct key *key) | |||
| 415 | if (valid) | 418 | if (valid) |
| 416 | goto valid; | 419 | goto valid; |
| 417 | 420 | ||
| 418 | mutex_lock(&vnode->validate_lock); | 421 | down_write(&vnode->validate_lock); |
| 419 | 422 | ||
| 420 | /* if the promise has expired, we need to check the server again to get | 423 | /* if the promise has expired, we need to check the server again to get |
| 421 | * a new promise - note that if the (parent) directory's metadata was | 424 | * a new promise - note that if the (parent) directory's metadata was |
| @@ -444,13 +447,13 @@ int afs_validate(struct afs_vnode *vnode, struct key *key) | |||
| 444 | * different */ | 447 | * different */ |
| 445 | if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) | 448 | if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) |
| 446 | afs_zap_data(vnode); | 449 | afs_zap_data(vnode); |
| 447 | mutex_unlock(&vnode->validate_lock); | 450 | up_write(&vnode->validate_lock); |
| 448 | valid: | 451 | valid: |
| 449 | _leave(" = 0"); | 452 | _leave(" = 0"); |
| 450 | return 0; | 453 | return 0; |
| 451 | 454 | ||
| 452 | error_unlock: | 455 | error_unlock: |
| 453 | mutex_unlock(&vnode->validate_lock); | 456 | up_write(&vnode->validate_lock); |
| 454 | _leave(" = %d", ret); | 457 | _leave(" = %d", ret); |
| 455 | return ret; | 458 | return ret; |
| 456 | } | 459 | } |
| @@ -574,7 +577,7 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 574 | ret = -ERESTARTSYS; | 577 | ret = -ERESTARTSYS; |
| 575 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | 578 | if (afs_begin_vnode_operation(&fc, vnode, key)) { |
| 576 | while (afs_select_fileserver(&fc)) { | 579 | while (afs_select_fileserver(&fc)) { |
| 577 | fc.cb_break = vnode->cb_break + vnode->cb_s_break; | 580 | fc.cb_break = afs_calc_vnode_cb_break(vnode); |
| 578 | afs_fs_setattr(&fc, attr); | 581 | afs_fs_setattr(&fc, attr); |
| 579 | } | 582 | } |
| 580 | 583 | ||
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index f8086ec95e24..e3f8a46663db 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
| @@ -396,6 +396,7 @@ struct afs_server { | |||
| 396 | #define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */ | 396 | #define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */ |
| 397 | #define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */ | 397 | #define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */ |
| 398 | #define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */ | 398 | #define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */ |
| 399 | #define AFS_SERVER_FL_MAY_HAVE_CB 8 /* May have callbacks on this fileserver */ | ||
| 399 | atomic_t usage; | 400 | atomic_t usage; |
| 400 | u32 addr_version; /* Address list version */ | 401 | u32 addr_version; /* Address list version */ |
| 401 | 402 | ||
| @@ -433,6 +434,7 @@ struct afs_server_list { | |||
| 433 | unsigned short index; /* Server currently in use */ | 434 | unsigned short index; /* Server currently in use */ |
| 434 | unsigned short vnovol_mask; /* Servers to be skipped due to VNOVOL */ | 435 | unsigned short vnovol_mask; /* Servers to be skipped due to VNOVOL */ |
| 435 | unsigned int seq; /* Set to ->servers_seq when installed */ | 436 | unsigned int seq; /* Set to ->servers_seq when installed */ |
| 437 | rwlock_t lock; | ||
| 436 | struct afs_server_entry servers[]; | 438 | struct afs_server_entry servers[]; |
| 437 | }; | 439 | }; |
| 438 | 440 | ||
| @@ -459,6 +461,9 @@ struct afs_volume { | |||
| 459 | rwlock_t servers_lock; /* Lock for ->servers */ | 461 | rwlock_t servers_lock; /* Lock for ->servers */ |
| 460 | unsigned int servers_seq; /* Incremented each time ->servers changes */ | 462 | unsigned int servers_seq; /* Incremented each time ->servers changes */ |
| 461 | 463 | ||
| 464 | unsigned cb_v_break; /* Break-everything counter. */ | ||
| 465 | rwlock_t cb_break_lock; | ||
| 466 | |||
| 462 | afs_voltype_t type; /* type of volume */ | 467 | afs_voltype_t type; /* type of volume */ |
| 463 | short error; | 468 | short error; |
| 464 | char type_force; /* force volume type (suppress R/O -> R/W) */ | 469 | char type_force; /* force volume type (suppress R/O -> R/W) */ |
| @@ -494,7 +499,7 @@ struct afs_vnode { | |||
| 494 | #endif | 499 | #endif |
| 495 | struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */ | 500 | struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */ |
| 496 | struct mutex io_lock; /* Lock for serialising I/O on this mutex */ | 501 | struct mutex io_lock; /* Lock for serialising I/O on this mutex */ |
| 497 | struct mutex validate_lock; /* lock for validating this vnode */ | 502 | struct rw_semaphore validate_lock; /* lock for validating this vnode */ |
| 498 | spinlock_t wb_lock; /* lock for wb_keys */ | 503 | spinlock_t wb_lock; /* lock for wb_keys */ |
| 499 | spinlock_t lock; /* waitqueue/flags lock */ | 504 | spinlock_t lock; /* waitqueue/flags lock */ |
| 500 | unsigned long flags; | 505 | unsigned long flags; |
| @@ -519,6 +524,7 @@ struct afs_vnode { | |||
| 519 | /* outstanding callback notification on this file */ | 524 | /* outstanding callback notification on this file */ |
| 520 | struct afs_cb_interest *cb_interest; /* Server on which this resides */ | 525 | struct afs_cb_interest *cb_interest; /* Server on which this resides */ |
| 521 | unsigned int cb_s_break; /* Mass break counter on ->server */ | 526 | unsigned int cb_s_break; /* Mass break counter on ->server */ |
| 527 | unsigned int cb_v_break; /* Mass break counter on ->volume */ | ||
| 522 | unsigned int cb_break; /* Break counter on vnode */ | 528 | unsigned int cb_break; /* Break counter on vnode */ |
| 523 | seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */ | 529 | seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */ |
| 524 | 530 | ||
| @@ -648,16 +654,29 @@ extern void afs_init_callback_state(struct afs_server *); | |||
| 648 | extern void afs_break_callback(struct afs_vnode *); | 654 | extern void afs_break_callback(struct afs_vnode *); |
| 649 | extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*); | 655 | extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*); |
| 650 | 656 | ||
| 651 | extern int afs_register_server_cb_interest(struct afs_vnode *, struct afs_server_entry *); | 657 | extern int afs_register_server_cb_interest(struct afs_vnode *, |
| 658 | struct afs_server_list *, unsigned int); | ||
| 652 | extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *); | 659 | extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *); |
| 653 | extern void afs_clear_callback_interests(struct afs_net *, struct afs_server_list *); | 660 | extern void afs_clear_callback_interests(struct afs_net *, struct afs_server_list *); |
| 654 | 661 | ||
| 655 | static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi) | 662 | static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi) |
| 656 | { | 663 | { |
| 657 | refcount_inc(&cbi->usage); | 664 | if (cbi) |
| 665 | refcount_inc(&cbi->usage); | ||
| 658 | return cbi; | 666 | return cbi; |
| 659 | } | 667 | } |
| 660 | 668 | ||
| 669 | static inline unsigned int afs_calc_vnode_cb_break(struct afs_vnode *vnode) | ||
| 670 | { | ||
| 671 | return vnode->cb_break + vnode->cb_s_break + vnode->cb_v_break; | ||
| 672 | } | ||
| 673 | |||
| 674 | static inline unsigned int afs_cb_break_sum(struct afs_vnode *vnode, | ||
| 675 | struct afs_cb_interest *cbi) | ||
| 676 | { | ||
| 677 | return vnode->cb_break + cbi->server->cb_s_break + vnode->volume->cb_v_break; | ||
| 678 | } | ||
| 679 | |||
| 661 | /* | 680 | /* |
| 662 | * cell.c | 681 | * cell.c |
| 663 | */ | 682 | */ |
diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c index ac0feac9d746..e065bc0768e6 100644 --- a/fs/afs/rotate.c +++ b/fs/afs/rotate.c | |||
| @@ -179,7 +179,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) | |||
| 179 | */ | 179 | */ |
| 180 | if (fc->flags & AFS_FS_CURSOR_VNOVOL) { | 180 | if (fc->flags & AFS_FS_CURSOR_VNOVOL) { |
| 181 | fc->ac.error = -EREMOTEIO; | 181 | fc->ac.error = -EREMOTEIO; |
| 182 | goto failed; | 182 | goto next_server; |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | write_lock(&vnode->volume->servers_lock); | 185 | write_lock(&vnode->volume->servers_lock); |
| @@ -201,7 +201,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) | |||
| 201 | */ | 201 | */ |
| 202 | if (vnode->volume->servers == fc->server_list) { | 202 | if (vnode->volume->servers == fc->server_list) { |
| 203 | fc->ac.error = -EREMOTEIO; | 203 | fc->ac.error = -EREMOTEIO; |
| 204 | goto failed; | 204 | goto next_server; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | /* Try again */ | 207 | /* Try again */ |
| @@ -350,8 +350,8 @@ use_server: | |||
| 350 | * break request before we've finished decoding the reply and | 350 | * break request before we've finished decoding the reply and |
| 351 | * installing the vnode. | 351 | * installing the vnode. |
| 352 | */ | 352 | */ |
| 353 | fc->ac.error = afs_register_server_cb_interest( | 353 | fc->ac.error = afs_register_server_cb_interest(vnode, fc->server_list, |
| 354 | vnode, &fc->server_list->servers[fc->index]); | 354 | fc->index); |
| 355 | if (fc->ac.error < 0) | 355 | if (fc->ac.error < 0) |
| 356 | goto failed; | 356 | goto failed; |
| 357 | 357 | ||
| @@ -369,8 +369,16 @@ use_server: | |||
| 369 | if (!test_bit(AFS_SERVER_FL_PROBED, &server->flags)) { | 369 | if (!test_bit(AFS_SERVER_FL_PROBED, &server->flags)) { |
| 370 | fc->ac.alist = afs_get_addrlist(alist); | 370 | fc->ac.alist = afs_get_addrlist(alist); |
| 371 | 371 | ||
| 372 | if (!afs_probe_fileserver(fc)) | 372 | if (!afs_probe_fileserver(fc)) { |
| 373 | goto failed; | 373 | switch (fc->ac.error) { |
| 374 | case -ENOMEM: | ||
| 375 | case -ERESTARTSYS: | ||
| 376 | case -EINTR: | ||
| 377 | goto failed; | ||
| 378 | default: | ||
| 379 | goto next_server; | ||
| 380 | } | ||
| 381 | } | ||
| 374 | } | 382 | } |
| 375 | 383 | ||
| 376 | if (!fc->ac.alist) | 384 | if (!fc->ac.alist) |
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 5c6263972ec9..08735948f15d 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
| @@ -41,6 +41,7 @@ int afs_open_socket(struct afs_net *net) | |||
| 41 | { | 41 | { |
| 42 | struct sockaddr_rxrpc srx; | 42 | struct sockaddr_rxrpc srx; |
| 43 | struct socket *socket; | 43 | struct socket *socket; |
| 44 | unsigned int min_level; | ||
| 44 | int ret; | 45 | int ret; |
| 45 | 46 | ||
| 46 | _enter(""); | 47 | _enter(""); |
| @@ -60,6 +61,12 @@ int afs_open_socket(struct afs_net *net) | |||
| 60 | srx.transport.sin6.sin6_family = AF_INET6; | 61 | srx.transport.sin6.sin6_family = AF_INET6; |
| 61 | srx.transport.sin6.sin6_port = htons(AFS_CM_PORT); | 62 | srx.transport.sin6.sin6_port = htons(AFS_CM_PORT); |
| 62 | 63 | ||
| 64 | min_level = RXRPC_SECURITY_ENCRYPT; | ||
| 65 | ret = kernel_setsockopt(socket, SOL_RXRPC, RXRPC_MIN_SECURITY_LEVEL, | ||
| 66 | (void *)&min_level, sizeof(min_level)); | ||
| 67 | if (ret < 0) | ||
| 68 | goto error_2; | ||
| 69 | |||
| 63 | ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx)); | 70 | ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx)); |
| 64 | if (ret == -EADDRINUSE) { | 71 | if (ret == -EADDRINUSE) { |
| 65 | srx.transport.sin6.sin6_port = 0; | 72 | srx.transport.sin6.sin6_port = 0; |
| @@ -482,8 +489,12 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
| 482 | state = READ_ONCE(call->state); | 489 | state = READ_ONCE(call->state); |
| 483 | switch (ret) { | 490 | switch (ret) { |
| 484 | case 0: | 491 | case 0: |
| 485 | if (state == AFS_CALL_CL_PROC_REPLY) | 492 | if (state == AFS_CALL_CL_PROC_REPLY) { |
| 493 | if (call->cbi) | ||
| 494 | set_bit(AFS_SERVER_FL_MAY_HAVE_CB, | ||
| 495 | &call->cbi->server->flags); | ||
| 486 | goto call_complete; | 496 | goto call_complete; |
| 497 | } | ||
| 487 | ASSERTCMP(state, >, AFS_CALL_CL_PROC_REPLY); | 498 | ASSERTCMP(state, >, AFS_CALL_CL_PROC_REPLY); |
| 488 | goto done; | 499 | goto done; |
| 489 | case -EINPROGRESS: | 500 | case -EINPROGRESS: |
| @@ -493,11 +504,6 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
| 493 | case -ECONNABORTED: | 504 | case -ECONNABORTED: |
| 494 | ASSERTCMP(state, ==, AFS_CALL_COMPLETE); | 505 | ASSERTCMP(state, ==, AFS_CALL_COMPLETE); |
| 495 | goto done; | 506 | goto done; |
| 496 | case -ENOTCONN: | ||
| 497 | abort_code = RX_CALL_DEAD; | ||
| 498 | rxrpc_kernel_abort_call(call->net->socket, call->rxcall, | ||
| 499 | abort_code, ret, "KNC"); | ||
| 500 | goto local_abort; | ||
| 501 | case -ENOTSUPP: | 507 | case -ENOTSUPP: |
| 502 | abort_code = RXGEN_OPCODE; | 508 | abort_code = RXGEN_OPCODE; |
| 503 | rxrpc_kernel_abort_call(call->net->socket, call->rxcall, | 509 | rxrpc_kernel_abort_call(call->net->socket, call->rxcall, |
diff --git a/fs/afs/security.c b/fs/afs/security.c index cea2fff313dc..1992b0ffa543 100644 --- a/fs/afs/security.c +++ b/fs/afs/security.c | |||
| @@ -147,8 +147,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, | |||
| 147 | break; | 147 | break; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | if (cb_break != (vnode->cb_break + | 150 | if (cb_break != afs_cb_break_sum(vnode, vnode->cb_interest)) { |
| 151 | vnode->cb_interest->server->cb_s_break)) { | ||
| 152 | changed = true; | 151 | changed = true; |
| 153 | break; | 152 | break; |
| 154 | } | 153 | } |
| @@ -178,7 +177,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, | |||
| 178 | } | 177 | } |
| 179 | } | 178 | } |
| 180 | 179 | ||
| 181 | if (cb_break != (vnode->cb_break + vnode->cb_interest->server->cb_s_break)) | 180 | if (cb_break != afs_cb_break_sum(vnode, vnode->cb_interest)) |
| 182 | goto someone_else_changed_it; | 181 | goto someone_else_changed_it; |
| 183 | 182 | ||
| 184 | /* We need a ref on any permits list we want to copy as we'll have to | 183 | /* We need a ref on any permits list we want to copy as we'll have to |
| @@ -257,7 +256,7 @@ found: | |||
| 257 | 256 | ||
| 258 | spin_lock(&vnode->lock); | 257 | spin_lock(&vnode->lock); |
| 259 | zap = rcu_access_pointer(vnode->permit_cache); | 258 | zap = rcu_access_pointer(vnode->permit_cache); |
| 260 | if (cb_break == (vnode->cb_break + vnode->cb_interest->server->cb_s_break) && | 259 | if (cb_break == afs_cb_break_sum(vnode, vnode->cb_interest) && |
| 261 | zap == permits) | 260 | zap == permits) |
| 262 | rcu_assign_pointer(vnode->permit_cache, replacement); | 261 | rcu_assign_pointer(vnode->permit_cache, replacement); |
| 263 | else | 262 | else |
diff --git a/fs/afs/server.c b/fs/afs/server.c index 629c74986cff..3af4625e2f8c 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
| @@ -67,12 +67,6 @@ struct afs_server *afs_find_server(struct afs_net *net, | |||
| 67 | sizeof(struct in6_addr)); | 67 | sizeof(struct in6_addr)); |
| 68 | if (diff == 0) | 68 | if (diff == 0) |
| 69 | goto found; | 69 | goto found; |
| 70 | if (diff < 0) { | ||
| 71 | // TODO: Sort the list | ||
| 72 | //if (i == alist->nr_ipv4) | ||
| 73 | // goto not_found; | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | } | 70 | } |
| 77 | } | 71 | } |
| 78 | } else { | 72 | } else { |
| @@ -87,17 +81,10 @@ struct afs_server *afs_find_server(struct afs_net *net, | |||
| 87 | (u32 __force)b->sin6_addr.s6_addr32[3]); | 81 | (u32 __force)b->sin6_addr.s6_addr32[3]); |
| 88 | if (diff == 0) | 82 | if (diff == 0) |
| 89 | goto found; | 83 | goto found; |
| 90 | if (diff < 0) { | ||
| 91 | // TODO: Sort the list | ||
| 92 | //if (i == 0) | ||
| 93 | // goto not_found; | ||
| 94 | break; | ||
| 95 | } | ||
| 96 | } | 84 | } |
| 97 | } | 85 | } |
| 98 | } | 86 | } |
| 99 | 87 | ||
| 100 | //not_found: | ||
| 101 | server = NULL; | 88 | server = NULL; |
| 102 | found: | 89 | found: |
| 103 | if (server && !atomic_inc_not_zero(&server->usage)) | 90 | if (server && !atomic_inc_not_zero(&server->usage)) |
| @@ -395,14 +382,16 @@ static void afs_destroy_server(struct afs_net *net, struct afs_server *server) | |||
| 395 | struct afs_addr_list *alist = rcu_access_pointer(server->addresses); | 382 | struct afs_addr_list *alist = rcu_access_pointer(server->addresses); |
| 396 | struct afs_addr_cursor ac = { | 383 | struct afs_addr_cursor ac = { |
| 397 | .alist = alist, | 384 | .alist = alist, |
| 398 | .addr = &alist->addrs[0], | ||
| 399 | .start = alist->index, | 385 | .start = alist->index, |
| 400 | .index = alist->index, | 386 | .index = 0, |
| 387 | .addr = &alist->addrs[alist->index], | ||
| 401 | .error = 0, | 388 | .error = 0, |
| 402 | }; | 389 | }; |
| 403 | _enter("%p", server); | 390 | _enter("%p", server); |
| 404 | 391 | ||
| 405 | afs_fs_give_up_all_callbacks(net, server, &ac, NULL); | 392 | if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags)) |
| 393 | afs_fs_give_up_all_callbacks(net, server, &ac, NULL); | ||
| 394 | |||
| 406 | call_rcu(&server->rcu, afs_server_rcu); | 395 | call_rcu(&server->rcu, afs_server_rcu); |
| 407 | afs_dec_servers_outstanding(net); | 396 | afs_dec_servers_outstanding(net); |
| 408 | } | 397 | } |
diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c index 0f8dc4c8f07c..8a5760aa5832 100644 --- a/fs/afs/server_list.c +++ b/fs/afs/server_list.c | |||
| @@ -49,6 +49,7 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, | |||
| 49 | goto error; | 49 | goto error; |
| 50 | 50 | ||
| 51 | refcount_set(&slist->usage, 1); | 51 | refcount_set(&slist->usage, 1); |
| 52 | rwlock_init(&slist->lock); | ||
| 52 | 53 | ||
| 53 | /* Make sure a records exists for each server in the list. */ | 54 | /* Make sure a records exists for each server in the list. */ |
| 54 | for (i = 0; i < vldb->nr_servers; i++) { | 55 | for (i = 0; i < vldb->nr_servers; i++) { |
| @@ -64,9 +65,11 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, | |||
| 64 | goto error_2; | 65 | goto error_2; |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | /* Insertion-sort by server pointer */ | 68 | /* Insertion-sort by UUID */ |
| 68 | for (j = 0; j < slist->nr_servers; j++) | 69 | for (j = 0; j < slist->nr_servers; j++) |
| 69 | if (slist->servers[j].server >= server) | 70 | if (memcmp(&slist->servers[j].server->uuid, |
| 71 | &server->uuid, | ||
| 72 | sizeof(server->uuid)) >= 0) | ||
| 70 | break; | 73 | break; |
| 71 | if (j < slist->nr_servers) { | 74 | if (j < slist->nr_servers) { |
| 72 | if (slist->servers[j].server == server) { | 75 | if (slist->servers[j].server == server) { |
diff --git a/fs/afs/super.c b/fs/afs/super.c index 65081ec3c36e..9e5d7966621c 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
| @@ -590,7 +590,7 @@ static void afs_i_init_once(void *_vnode) | |||
| 590 | memset(vnode, 0, sizeof(*vnode)); | 590 | memset(vnode, 0, sizeof(*vnode)); |
| 591 | inode_init_once(&vnode->vfs_inode); | 591 | inode_init_once(&vnode->vfs_inode); |
| 592 | mutex_init(&vnode->io_lock); | 592 | mutex_init(&vnode->io_lock); |
| 593 | mutex_init(&vnode->validate_lock); | 593 | init_rwsem(&vnode->validate_lock); |
| 594 | spin_lock_init(&vnode->wb_lock); | 594 | spin_lock_init(&vnode->wb_lock); |
| 595 | spin_lock_init(&vnode->lock); | 595 | spin_lock_init(&vnode->lock); |
| 596 | INIT_LIST_HEAD(&vnode->wb_keys); | 596 | INIT_LIST_HEAD(&vnode->wb_keys); |
| @@ -688,7 +688,7 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 688 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | 688 | if (afs_begin_vnode_operation(&fc, vnode, key)) { |
| 689 | fc.flags |= AFS_FS_CURSOR_NO_VSLEEP; | 689 | fc.flags |= AFS_FS_CURSOR_NO_VSLEEP; |
| 690 | while (afs_select_fileserver(&fc)) { | 690 | while (afs_select_fileserver(&fc)) { |
| 691 | fc.cb_break = vnode->cb_break + vnode->cb_s_break; | 691 | fc.cb_break = afs_calc_vnode_cb_break(vnode); |
| 692 | afs_fs_get_volume_status(&fc, &vs); | 692 | afs_fs_get_volume_status(&fc, &vs); |
| 693 | } | 693 | } |
| 694 | 694 | ||
diff --git a/fs/afs/write.c b/fs/afs/write.c index c164698dc304..8b39e6ebb40b 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
| @@ -351,7 +351,7 @@ found_key: | |||
| 351 | ret = -ERESTARTSYS; | 351 | ret = -ERESTARTSYS; |
| 352 | if (afs_begin_vnode_operation(&fc, vnode, wbk->key)) { | 352 | if (afs_begin_vnode_operation(&fc, vnode, wbk->key)) { |
| 353 | while (afs_select_fileserver(&fc)) { | 353 | while (afs_select_fileserver(&fc)) { |
| 354 | fc.cb_break = vnode->cb_break + vnode->cb_s_break; | 354 | fc.cb_break = afs_calc_vnode_cb_break(vnode); |
| 355 | afs_fs_store_data(&fc, mapping, first, last, offset, to); | 355 | afs_fs_store_data(&fc, mapping, first, last, offset, to); |
| 356 | } | 356 | } |
| 357 | 357 | ||
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 3fd44835b386..8c68961925b1 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -2436,10 +2436,8 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p, | |||
| 2436 | if (p->reada != READA_NONE) | 2436 | if (p->reada != READA_NONE) |
| 2437 | reada_for_search(fs_info, p, level, slot, key->objectid); | 2437 | reada_for_search(fs_info, p, level, slot, key->objectid); |
| 2438 | 2438 | ||
| 2439 | btrfs_release_path(p); | ||
| 2440 | |||
| 2441 | ret = -EAGAIN; | 2439 | ret = -EAGAIN; |
| 2442 | tmp = read_tree_block(fs_info, blocknr, 0, parent_level - 1, | 2440 | tmp = read_tree_block(fs_info, blocknr, gen, parent_level - 1, |
| 2443 | &first_key); | 2441 | &first_key); |
| 2444 | if (!IS_ERR(tmp)) { | 2442 | if (!IS_ERR(tmp)) { |
| 2445 | /* | 2443 | /* |
| @@ -2454,6 +2452,8 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p, | |||
| 2454 | } else { | 2452 | } else { |
| 2455 | ret = PTR_ERR(tmp); | 2453 | ret = PTR_ERR(tmp); |
| 2456 | } | 2454 | } |
| 2455 | |||
| 2456 | btrfs_release_path(p); | ||
| 2457 | return ret; | 2457 | return ret; |
| 2458 | } | 2458 | } |
| 2459 | 2459 | ||
| @@ -5414,12 +5414,24 @@ int btrfs_compare_trees(struct btrfs_root *left_root, | |||
| 5414 | down_read(&fs_info->commit_root_sem); | 5414 | down_read(&fs_info->commit_root_sem); |
| 5415 | left_level = btrfs_header_level(left_root->commit_root); | 5415 | left_level = btrfs_header_level(left_root->commit_root); |
| 5416 | left_root_level = left_level; | 5416 | left_root_level = left_level; |
| 5417 | left_path->nodes[left_level] = left_root->commit_root; | 5417 | left_path->nodes[left_level] = |
| 5418 | btrfs_clone_extent_buffer(left_root->commit_root); | ||
| 5419 | if (!left_path->nodes[left_level]) { | ||
| 5420 | up_read(&fs_info->commit_root_sem); | ||
| 5421 | ret = -ENOMEM; | ||
| 5422 | goto out; | ||
| 5423 | } | ||
| 5418 | extent_buffer_get(left_path->nodes[left_level]); | 5424 | extent_buffer_get(left_path->nodes[left_level]); |
| 5419 | 5425 | ||
| 5420 | right_level = btrfs_header_level(right_root->commit_root); | 5426 | right_level = btrfs_header_level(right_root->commit_root); |
| 5421 | right_root_level = right_level; | 5427 | right_root_level = right_level; |
| 5422 | right_path->nodes[right_level] = right_root->commit_root; | 5428 | right_path->nodes[right_level] = |
| 5429 | btrfs_clone_extent_buffer(right_root->commit_root); | ||
| 5430 | if (!right_path->nodes[right_level]) { | ||
| 5431 | up_read(&fs_info->commit_root_sem); | ||
| 5432 | ret = -ENOMEM; | ||
| 5433 | goto out; | ||
| 5434 | } | ||
| 5423 | extent_buffer_get(right_path->nodes[right_level]); | 5435 | extent_buffer_get(right_path->nodes[right_level]); |
| 5424 | up_read(&fs_info->commit_root_sem); | 5436 | up_read(&fs_info->commit_root_sem); |
| 5425 | 5437 | ||
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 2771cc56a622..0d422c9908b8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -3182,6 +3182,8 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, | |||
| 3182 | u64 *orig_start, u64 *orig_block_len, | 3182 | u64 *orig_start, u64 *orig_block_len, |
| 3183 | u64 *ram_bytes); | 3183 | u64 *ram_bytes); |
| 3184 | 3184 | ||
| 3185 | void __btrfs_del_delalloc_inode(struct btrfs_root *root, | ||
| 3186 | struct btrfs_inode *inode); | ||
| 3185 | struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry); | 3187 | struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry); |
| 3186 | int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index); | 3188 | int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index); |
| 3187 | int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | 3189 | int btrfs_unlink_inode(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 60caa68c3618..c3504b4d281b 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -3818,6 +3818,7 @@ void close_ctree(struct btrfs_fs_info *fs_info) | |||
| 3818 | set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags); | 3818 | set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags); |
| 3819 | 3819 | ||
| 3820 | btrfs_free_qgroup_config(fs_info); | 3820 | btrfs_free_qgroup_config(fs_info); |
| 3821 | ASSERT(list_empty(&fs_info->delalloc_roots)); | ||
| 3821 | 3822 | ||
| 3822 | if (percpu_counter_sum(&fs_info->delalloc_bytes)) { | 3823 | if (percpu_counter_sum(&fs_info->delalloc_bytes)) { |
| 3823 | btrfs_info(fs_info, "at unmount delalloc count %lld", | 3824 | btrfs_info(fs_info, "at unmount delalloc count %lld", |
| @@ -4125,15 +4126,15 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info) | |||
| 4125 | 4126 | ||
| 4126 | static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) | 4127 | static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) |
| 4127 | { | 4128 | { |
| 4129 | /* cleanup FS via transaction */ | ||
| 4130 | btrfs_cleanup_transaction(fs_info); | ||
| 4131 | |||
| 4128 | mutex_lock(&fs_info->cleaner_mutex); | 4132 | mutex_lock(&fs_info->cleaner_mutex); |
| 4129 | btrfs_run_delayed_iputs(fs_info); | 4133 | btrfs_run_delayed_iputs(fs_info); |
| 4130 | mutex_unlock(&fs_info->cleaner_mutex); | 4134 | mutex_unlock(&fs_info->cleaner_mutex); |
| 4131 | 4135 | ||
| 4132 | down_write(&fs_info->cleanup_work_sem); | 4136 | down_write(&fs_info->cleanup_work_sem); |
| 4133 | up_write(&fs_info->cleanup_work_sem); | 4137 | up_write(&fs_info->cleanup_work_sem); |
| 4134 | |||
| 4135 | /* cleanup FS via transaction */ | ||
| 4136 | btrfs_cleanup_transaction(fs_info); | ||
| 4137 | } | 4138 | } |
| 4138 | 4139 | ||
| 4139 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root) | 4140 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root) |
| @@ -4258,19 +4259,23 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) | |||
| 4258 | list_splice_init(&root->delalloc_inodes, &splice); | 4259 | list_splice_init(&root->delalloc_inodes, &splice); |
| 4259 | 4260 | ||
| 4260 | while (!list_empty(&splice)) { | 4261 | while (!list_empty(&splice)) { |
| 4262 | struct inode *inode = NULL; | ||
| 4261 | btrfs_inode = list_first_entry(&splice, struct btrfs_inode, | 4263 | btrfs_inode = list_first_entry(&splice, struct btrfs_inode, |
| 4262 | delalloc_inodes); | 4264 | delalloc_inodes); |
| 4263 | 4265 | __btrfs_del_delalloc_inode(root, btrfs_inode); | |
| 4264 | list_del_init(&btrfs_inode->delalloc_inodes); | ||
| 4265 | clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, | ||
| 4266 | &btrfs_inode->runtime_flags); | ||
| 4267 | spin_unlock(&root->delalloc_lock); | 4266 | spin_unlock(&root->delalloc_lock); |
| 4268 | 4267 | ||
| 4269 | btrfs_invalidate_inodes(btrfs_inode->root); | 4268 | /* |
| 4270 | 4269 | * Make sure we get a live inode and that it'll not disappear | |
| 4270 | * meanwhile. | ||
| 4271 | */ | ||
| 4272 | inode = igrab(&btrfs_inode->vfs_inode); | ||
| 4273 | if (inode) { | ||
| 4274 | invalidate_inode_pages2(inode->i_mapping); | ||
| 4275 | iput(inode); | ||
| 4276 | } | ||
| 4271 | spin_lock(&root->delalloc_lock); | 4277 | spin_lock(&root->delalloc_lock); |
| 4272 | } | 4278 | } |
| 4273 | |||
| 4274 | spin_unlock(&root->delalloc_lock); | 4279 | spin_unlock(&root->delalloc_lock); |
| 4275 | } | 4280 | } |
| 4276 | 4281 | ||
| @@ -4286,7 +4291,6 @@ static void btrfs_destroy_all_delalloc_inodes(struct btrfs_fs_info *fs_info) | |||
| 4286 | while (!list_empty(&splice)) { | 4291 | while (!list_empty(&splice)) { |
| 4287 | root = list_first_entry(&splice, struct btrfs_root, | 4292 | root = list_first_entry(&splice, struct btrfs_root, |
| 4288 | delalloc_root); | 4293 | delalloc_root); |
| 4289 | list_del_init(&root->delalloc_root); | ||
| 4290 | root = btrfs_grab_fs_root(root); | 4294 | root = btrfs_grab_fs_root(root); |
| 4291 | BUG_ON(!root); | 4295 | BUG_ON(!root); |
| 4292 | spin_unlock(&fs_info->delalloc_root_lock); | 4296 | spin_unlock(&fs_info->delalloc_root_lock); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e2f16b68fcbf..51b5e2da708c 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -3142,7 +3142,11 @@ static noinline int check_delayed_ref(struct btrfs_root *root, | |||
| 3142 | struct rb_node *node; | 3142 | struct rb_node *node; |
| 3143 | int ret = 0; | 3143 | int ret = 0; |
| 3144 | 3144 | ||
| 3145 | spin_lock(&root->fs_info->trans_lock); | ||
| 3145 | cur_trans = root->fs_info->running_transaction; | 3146 | cur_trans = root->fs_info->running_transaction; |
| 3147 | if (cur_trans) | ||
| 3148 | refcount_inc(&cur_trans->use_count); | ||
| 3149 | spin_unlock(&root->fs_info->trans_lock); | ||
| 3146 | if (!cur_trans) | 3150 | if (!cur_trans) |
| 3147 | return 0; | 3151 | return 0; |
| 3148 | 3152 | ||
| @@ -3151,6 +3155,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root, | |||
| 3151 | head = btrfs_find_delayed_ref_head(delayed_refs, bytenr); | 3155 | head = btrfs_find_delayed_ref_head(delayed_refs, bytenr); |
| 3152 | if (!head) { | 3156 | if (!head) { |
| 3153 | spin_unlock(&delayed_refs->lock); | 3157 | spin_unlock(&delayed_refs->lock); |
| 3158 | btrfs_put_transaction(cur_trans); | ||
| 3154 | return 0; | 3159 | return 0; |
| 3155 | } | 3160 | } |
| 3156 | 3161 | ||
| @@ -3167,6 +3172,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root, | |||
| 3167 | mutex_lock(&head->mutex); | 3172 | mutex_lock(&head->mutex); |
| 3168 | mutex_unlock(&head->mutex); | 3173 | mutex_unlock(&head->mutex); |
| 3169 | btrfs_put_delayed_ref_head(head); | 3174 | btrfs_put_delayed_ref_head(head); |
| 3175 | btrfs_put_transaction(cur_trans); | ||
| 3170 | return -EAGAIN; | 3176 | return -EAGAIN; |
| 3171 | } | 3177 | } |
| 3172 | spin_unlock(&delayed_refs->lock); | 3178 | spin_unlock(&delayed_refs->lock); |
| @@ -3199,6 +3205,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root, | |||
| 3199 | } | 3205 | } |
| 3200 | spin_unlock(&head->lock); | 3206 | spin_unlock(&head->lock); |
| 3201 | mutex_unlock(&head->mutex); | 3207 | mutex_unlock(&head->mutex); |
| 3208 | btrfs_put_transaction(cur_trans); | ||
| 3202 | return ret; | 3209 | return ret; |
| 3203 | } | 3210 | } |
| 3204 | 3211 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d241285a0d2a..8e604e7071f1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -1742,12 +1742,12 @@ static void btrfs_add_delalloc_inodes(struct btrfs_root *root, | |||
| 1742 | spin_unlock(&root->delalloc_lock); | 1742 | spin_unlock(&root->delalloc_lock); |
| 1743 | } | 1743 | } |
| 1744 | 1744 | ||
| 1745 | static void btrfs_del_delalloc_inode(struct btrfs_root *root, | 1745 | |
| 1746 | struct btrfs_inode *inode) | 1746 | void __btrfs_del_delalloc_inode(struct btrfs_root *root, |
| 1747 | struct btrfs_inode *inode) | ||
| 1747 | { | 1748 | { |
| 1748 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb); | 1749 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb); |
| 1749 | 1750 | ||
| 1750 | spin_lock(&root->delalloc_lock); | ||
| 1751 | if (!list_empty(&inode->delalloc_inodes)) { | 1751 | if (!list_empty(&inode->delalloc_inodes)) { |
| 1752 | list_del_init(&inode->delalloc_inodes); | 1752 | list_del_init(&inode->delalloc_inodes); |
| 1753 | clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, | 1753 | clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, |
| @@ -1760,6 +1760,13 @@ static void btrfs_del_delalloc_inode(struct btrfs_root *root, | |||
| 1760 | spin_unlock(&fs_info->delalloc_root_lock); | 1760 | spin_unlock(&fs_info->delalloc_root_lock); |
| 1761 | } | 1761 | } |
| 1762 | } | 1762 | } |
| 1763 | } | ||
| 1764 | |||
| 1765 | static void btrfs_del_delalloc_inode(struct btrfs_root *root, | ||
| 1766 | struct btrfs_inode *inode) | ||
| 1767 | { | ||
| 1768 | spin_lock(&root->delalloc_lock); | ||
| 1769 | __btrfs_del_delalloc_inode(root, inode); | ||
| 1763 | spin_unlock(&root->delalloc_lock); | 1770 | spin_unlock(&root->delalloc_lock); |
| 1764 | } | 1771 | } |
| 1765 | 1772 | ||
diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c index 53a8c95828e3..dc6140013ae8 100644 --- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c | |||
| @@ -380,6 +380,7 @@ static int prop_compression_apply(struct inode *inode, | |||
| 380 | const char *value, | 380 | const char *value, |
| 381 | size_t len) | 381 | size_t len) |
| 382 | { | 382 | { |
| 383 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | ||
| 383 | int type; | 384 | int type; |
| 384 | 385 | ||
| 385 | if (len == 0) { | 386 | if (len == 0) { |
| @@ -390,14 +391,17 @@ static int prop_compression_apply(struct inode *inode, | |||
| 390 | return 0; | 391 | return 0; |
| 391 | } | 392 | } |
| 392 | 393 | ||
| 393 | if (!strncmp("lzo", value, 3)) | 394 | if (!strncmp("lzo", value, 3)) { |
| 394 | type = BTRFS_COMPRESS_LZO; | 395 | type = BTRFS_COMPRESS_LZO; |
| 395 | else if (!strncmp("zlib", value, 4)) | 396 | btrfs_set_fs_incompat(fs_info, COMPRESS_LZO); |
| 397 | } else if (!strncmp("zlib", value, 4)) { | ||
| 396 | type = BTRFS_COMPRESS_ZLIB; | 398 | type = BTRFS_COMPRESS_ZLIB; |
| 397 | else if (!strncmp("zstd", value, len)) | 399 | } else if (!strncmp("zstd", value, len)) { |
| 398 | type = BTRFS_COMPRESS_ZSTD; | 400 | type = BTRFS_COMPRESS_ZSTD; |
| 399 | else | 401 | btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD); |
| 402 | } else { | ||
| 400 | return -EINVAL; | 403 | return -EINVAL; |
| 404 | } | ||
| 401 | 405 | ||
| 402 | BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS; | 406 | BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS; |
| 403 | BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS; | 407 | BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS; |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 00b7d3231821..b041b945a7ae 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
| @@ -1841,7 +1841,7 @@ again: | |||
| 1841 | old_bytenr = btrfs_node_blockptr(parent, slot); | 1841 | old_bytenr = btrfs_node_blockptr(parent, slot); |
| 1842 | blocksize = fs_info->nodesize; | 1842 | blocksize = fs_info->nodesize; |
| 1843 | old_ptr_gen = btrfs_node_ptr_generation(parent, slot); | 1843 | old_ptr_gen = btrfs_node_ptr_generation(parent, slot); |
| 1844 | btrfs_node_key_to_cpu(parent, &key, slot); | 1844 | btrfs_node_key_to_cpu(parent, &first_key, slot); |
| 1845 | 1845 | ||
| 1846 | if (level <= max_level) { | 1846 | if (level <= max_level) { |
| 1847 | eb = path->nodes[level]; | 1847 | eb = path->nodes[level]; |
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 221e5cdb060b..c0074d2d7d6d 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
| @@ -5236,6 +5236,10 @@ static int send_write_or_clone(struct send_ctx *sctx, | |||
| 5236 | len = btrfs_file_extent_num_bytes(path->nodes[0], ei); | 5236 | len = btrfs_file_extent_num_bytes(path->nodes[0], ei); |
| 5237 | } | 5237 | } |
| 5238 | 5238 | ||
| 5239 | if (offset >= sctx->cur_inode_size) { | ||
| 5240 | ret = 0; | ||
| 5241 | goto out; | ||
| 5242 | } | ||
| 5239 | if (offset + len > sctx->cur_inode_size) | 5243 | if (offset + len > sctx->cur_inode_size) |
| 5240 | len = sctx->cur_inode_size - offset; | 5244 | len = sctx->cur_inode_size - offset; |
| 5241 | if (len == 0) { | 5245 | if (len == 0) { |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 43758e30aa7a..8f23a94dab77 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -4320,6 +4320,110 @@ static int log_one_extent(struct btrfs_trans_handle *trans, | |||
| 4320 | return ret; | 4320 | return ret; |
| 4321 | } | 4321 | } |
| 4322 | 4322 | ||
| 4323 | /* | ||
| 4324 | * Log all prealloc extents beyond the inode's i_size to make sure we do not | ||
| 4325 | * lose them after doing a fast fsync and replaying the log. We scan the | ||
| 4326 | * subvolume's root instead of iterating the inode's extent map tree because | ||
| 4327 | * otherwise we can log incorrect extent items based on extent map conversion. | ||
| 4328 | * That can happen due to the fact that extent maps are merged when they | ||
| 4329 | * are not in the extent map tree's list of modified extents. | ||
| 4330 | */ | ||
| 4331 | static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, | ||
| 4332 | struct btrfs_inode *inode, | ||
| 4333 | struct btrfs_path *path) | ||
| 4334 | { | ||
| 4335 | struct btrfs_root *root = inode->root; | ||
| 4336 | struct btrfs_key key; | ||
| 4337 | const u64 i_size = i_size_read(&inode->vfs_inode); | ||
| 4338 | const u64 ino = btrfs_ino(inode); | ||
| 4339 | struct btrfs_path *dst_path = NULL; | ||
| 4340 | u64 last_extent = (u64)-1; | ||
| 4341 | int ins_nr = 0; | ||
| 4342 | int start_slot; | ||
| 4343 | int ret; | ||
| 4344 | |||
| 4345 | if (!(inode->flags & BTRFS_INODE_PREALLOC)) | ||
| 4346 | return 0; | ||
| 4347 | |||
| 4348 | key.objectid = ino; | ||
| 4349 | key.type = BTRFS_EXTENT_DATA_KEY; | ||
| 4350 | key.offset = i_size; | ||
| 4351 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
| 4352 | if (ret < 0) | ||
| 4353 | goto out; | ||
| 4354 | |||
| 4355 | while (true) { | ||
| 4356 | struct extent_buffer *leaf = path->nodes[0]; | ||
| 4357 | int slot = path->slots[0]; | ||
| 4358 | |||
| 4359 | if (slot >= btrfs_header_nritems(leaf)) { | ||
| 4360 | if (ins_nr > 0) { | ||
| 4361 | ret = copy_items(trans, inode, dst_path, path, | ||
| 4362 | &last_extent, start_slot, | ||
| 4363 | ins_nr, 1, 0); | ||
| 4364 | if (ret < 0) | ||
| 4365 | goto out; | ||
| 4366 | ins_nr = 0; | ||
| 4367 | } | ||
| 4368 | ret = btrfs_next_leaf(root, path); | ||
| 4369 | if (ret < 0) | ||
| 4370 | goto out; | ||
| 4371 | if (ret > 0) { | ||
| 4372 | ret = 0; | ||
| 4373 | break; | ||
| 4374 | } | ||
| 4375 | continue; | ||
| 4376 | } | ||
| 4377 | |||
| 4378 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
| 4379 | if (key.objectid > ino) | ||
| 4380 | break; | ||
| 4381 | if (WARN_ON_ONCE(key.objectid < ino) || | ||
| 4382 | key.type < BTRFS_EXTENT_DATA_KEY || | ||
| 4383 | key.offset < i_size) { | ||
| 4384 | path->slots[0]++; | ||
| 4385 | continue; | ||
| 4386 | } | ||
| 4387 | if (last_extent == (u64)-1) { | ||
| 4388 | last_extent = key.offset; | ||
| 4389 | /* | ||
| 4390 | * Avoid logging extent items logged in past fsync calls | ||
| 4391 | * and leading to duplicate keys in the log tree. | ||
| 4392 | */ | ||
| 4393 | do { | ||
| 4394 | ret = btrfs_truncate_inode_items(trans, | ||
| 4395 | root->log_root, | ||
| 4396 | &inode->vfs_inode, | ||
| 4397 | i_size, | ||
| 4398 | BTRFS_EXTENT_DATA_KEY); | ||
| 4399 | } while (ret == -EAGAIN); | ||
| 4400 | if (ret) | ||
| 4401 | goto out; | ||
| 4402 | } | ||
| 4403 | if (ins_nr == 0) | ||
| 4404 | start_slot = slot; | ||
| 4405 | ins_nr++; | ||
| 4406 | path->slots[0]++; | ||
| 4407 | if (!dst_path) { | ||
| 4408 | dst_path = btrfs_alloc_path(); | ||
| 4409 | if (!dst_path) { | ||
| 4410 | ret = -ENOMEM; | ||
| 4411 | goto out; | ||
| 4412 | } | ||
| 4413 | } | ||
| 4414 | } | ||
| 4415 | if (ins_nr > 0) { | ||
| 4416 | ret = copy_items(trans, inode, dst_path, path, &last_extent, | ||
| 4417 | start_slot, ins_nr, 1, 0); | ||
| 4418 | if (ret > 0) | ||
| 4419 | ret = 0; | ||
| 4420 | } | ||
| 4421 | out: | ||
| 4422 | btrfs_release_path(path); | ||
| 4423 | btrfs_free_path(dst_path); | ||
| 4424 | return ret; | ||
| 4425 | } | ||
| 4426 | |||
| 4323 | static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | 4427 | static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, |
| 4324 | struct btrfs_root *root, | 4428 | struct btrfs_root *root, |
| 4325 | struct btrfs_inode *inode, | 4429 | struct btrfs_inode *inode, |
| @@ -4362,6 +4466,11 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | |||
| 4362 | if (em->generation <= test_gen) | 4466 | if (em->generation <= test_gen) |
| 4363 | continue; | 4467 | continue; |
| 4364 | 4468 | ||
| 4469 | /* We log prealloc extents beyond eof later. */ | ||
| 4470 | if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) && | ||
| 4471 | em->start >= i_size_read(&inode->vfs_inode)) | ||
| 4472 | continue; | ||
| 4473 | |||
| 4365 | if (em->start < logged_start) | 4474 | if (em->start < logged_start) |
| 4366 | logged_start = em->start; | 4475 | logged_start = em->start; |
| 4367 | if ((em->start + em->len - 1) > logged_end) | 4476 | if ((em->start + em->len - 1) > logged_end) |
| @@ -4374,31 +4483,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | |||
| 4374 | num++; | 4483 | num++; |
| 4375 | } | 4484 | } |
| 4376 | 4485 | ||
| 4377 | /* | ||
| 4378 | * Add all prealloc extents beyond the inode's i_size to make sure we | ||
| 4379 | * don't lose them after doing a fast fsync and replaying the log. | ||
| 4380 | */ | ||
| 4381 | if (inode->flags & BTRFS_INODE_PREALLOC) { | ||
| 4382 | struct rb_node *node; | ||
| 4383 | |||
| 4384 | for (node = rb_last(&tree->map); node; node = rb_prev(node)) { | ||
| 4385 | em = rb_entry(node, struct extent_map, rb_node); | ||
| 4386 | if (em->start < i_size_read(&inode->vfs_inode)) | ||
| 4387 | break; | ||
| 4388 | if (!list_empty(&em->list)) | ||
| 4389 | continue; | ||
| 4390 | /* Same as above loop. */ | ||
| 4391 | if (++num > 32768) { | ||
| 4392 | list_del_init(&tree->modified_extents); | ||
| 4393 | ret = -EFBIG; | ||
| 4394 | goto process; | ||
| 4395 | } | ||
| 4396 | refcount_inc(&em->refs); | ||
| 4397 | set_bit(EXTENT_FLAG_LOGGING, &em->flags); | ||
| 4398 | list_add_tail(&em->list, &extents); | ||
| 4399 | } | ||
| 4400 | } | ||
| 4401 | |||
| 4402 | list_sort(NULL, &extents, extent_cmp); | 4486 | list_sort(NULL, &extents, extent_cmp); |
| 4403 | btrfs_get_logged_extents(inode, logged_list, logged_start, logged_end); | 4487 | btrfs_get_logged_extents(inode, logged_list, logged_start, logged_end); |
| 4404 | /* | 4488 | /* |
| @@ -4443,6 +4527,9 @@ process: | |||
| 4443 | up_write(&inode->dio_sem); | 4527 | up_write(&inode->dio_sem); |
| 4444 | 4528 | ||
| 4445 | btrfs_release_path(path); | 4529 | btrfs_release_path(path); |
| 4530 | if (!ret) | ||
| 4531 | ret = btrfs_log_prealloc_extents(trans, inode, path); | ||
| 4532 | |||
| 4446 | return ret; | 4533 | return ret; |
| 4447 | } | 4534 | } |
| 4448 | 4535 | ||
| @@ -4827,6 +4914,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
| 4827 | struct extent_map_tree *em_tree = &inode->extent_tree; | 4914 | struct extent_map_tree *em_tree = &inode->extent_tree; |
| 4828 | u64 logged_isize = 0; | 4915 | u64 logged_isize = 0; |
| 4829 | bool need_log_inode_item = true; | 4916 | bool need_log_inode_item = true; |
| 4917 | bool xattrs_logged = false; | ||
| 4830 | 4918 | ||
| 4831 | path = btrfs_alloc_path(); | 4919 | path = btrfs_alloc_path(); |
| 4832 | if (!path) | 4920 | if (!path) |
| @@ -5128,6 +5216,7 @@ next_key: | |||
| 5128 | err = btrfs_log_all_xattrs(trans, root, inode, path, dst_path); | 5216 | err = btrfs_log_all_xattrs(trans, root, inode, path, dst_path); |
| 5129 | if (err) | 5217 | if (err) |
| 5130 | goto out_unlock; | 5218 | goto out_unlock; |
| 5219 | xattrs_logged = true; | ||
| 5131 | if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) { | 5220 | if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) { |
| 5132 | btrfs_release_path(path); | 5221 | btrfs_release_path(path); |
| 5133 | btrfs_release_path(dst_path); | 5222 | btrfs_release_path(dst_path); |
| @@ -5140,6 +5229,11 @@ log_extents: | |||
| 5140 | btrfs_release_path(dst_path); | 5229 | btrfs_release_path(dst_path); |
| 5141 | if (need_log_inode_item) { | 5230 | if (need_log_inode_item) { |
| 5142 | err = log_inode_item(trans, log, dst_path, inode); | 5231 | err = log_inode_item(trans, log, dst_path, inode); |
| 5232 | if (!err && !xattrs_logged) { | ||
| 5233 | err = btrfs_log_all_xattrs(trans, root, inode, path, | ||
| 5234 | dst_path); | ||
| 5235 | btrfs_release_path(path); | ||
| 5236 | } | ||
| 5143 | if (err) | 5237 | if (err) |
| 5144 | goto out_unlock; | 5238 | goto out_unlock; |
| 5145 | } | 5239 | } |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 292266f6ab9c..be3fc701f389 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -4052,6 +4052,15 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info) | |||
| 4052 | return 0; | 4052 | return 0; |
| 4053 | } | 4053 | } |
| 4054 | 4054 | ||
| 4055 | /* | ||
| 4056 | * A ro->rw remount sequence should continue with the paused balance | ||
| 4057 | * regardless of who pauses it, system or the user as of now, so set | ||
| 4058 | * the resume flag. | ||
| 4059 | */ | ||
| 4060 | spin_lock(&fs_info->balance_lock); | ||
| 4061 | fs_info->balance_ctl->flags |= BTRFS_BALANCE_RESUME; | ||
| 4062 | spin_unlock(&fs_info->balance_lock); | ||
| 4063 | |||
| 4055 | tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance"); | 4064 | tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance"); |
| 4056 | return PTR_ERR_OR_ZERO(tsk); | 4065 | return PTR_ERR_OR_ZERO(tsk); |
| 4057 | } | 4066 | } |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index f85040d73e3d..cf0e45b10121 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
| @@ -70,69 +70,104 @@ static __le32 ceph_flags_sys2wire(u32 flags) | |||
| 70 | */ | 70 | */ |
| 71 | 71 | ||
| 72 | /* | 72 | /* |
| 73 | * Calculate the length sum of direct io vectors that can | 73 | * How many pages to get in one call to iov_iter_get_pages(). This |
| 74 | * be combined into one page vector. | 74 | * determines the size of the on-stack array used as a buffer. |
| 75 | */ | 75 | */ |
| 76 | static size_t dio_get_pagev_size(const struct iov_iter *it) | 76 | #define ITER_GET_BVECS_PAGES 64 |
| 77 | |||
| 78 | static ssize_t __iter_get_bvecs(struct iov_iter *iter, size_t maxsize, | ||
| 79 | struct bio_vec *bvecs) | ||
| 77 | { | 80 | { |
| 78 | const struct iovec *iov = it->iov; | 81 | size_t size = 0; |
| 79 | const struct iovec *iovend = iov + it->nr_segs; | 82 | int bvec_idx = 0; |
| 80 | size_t size; | 83 | |
| 81 | 84 | if (maxsize > iov_iter_count(iter)) | |
| 82 | size = iov->iov_len - it->iov_offset; | 85 | maxsize = iov_iter_count(iter); |
| 83 | /* | 86 | |
| 84 | * An iov can be page vectored when both the current tail | 87 | while (size < maxsize) { |
| 85 | * and the next base are page aligned. | 88 | struct page *pages[ITER_GET_BVECS_PAGES]; |
| 86 | */ | 89 | ssize_t bytes; |
| 87 | while (PAGE_ALIGNED((iov->iov_base + iov->iov_len)) && | 90 | size_t start; |
| 88 | (++iov < iovend && PAGE_ALIGNED((iov->iov_base)))) { | 91 | int idx = 0; |
| 89 | size += iov->iov_len; | 92 | |
| 90 | } | 93 | bytes = iov_iter_get_pages(iter, pages, maxsize - size, |
| 91 | dout("dio_get_pagevlen len = %zu\n", size); | 94 | ITER_GET_BVECS_PAGES, &start); |
| 92 | return size; | 95 | if (bytes < 0) |
| 96 | return size ?: bytes; | ||
| 97 | |||
| 98 | iov_iter_advance(iter, bytes); | ||
| 99 | size += bytes; | ||
| 100 | |||
| 101 | for ( ; bytes; idx++, bvec_idx++) { | ||
| 102 | struct bio_vec bv = { | ||
| 103 | .bv_page = pages[idx], | ||
| 104 | .bv_len = min_t(int, bytes, PAGE_SIZE - start), | ||
| 105 | .bv_offset = start, | ||
| 106 | }; | ||
| 107 | |||
| 108 | bvecs[bvec_idx] = bv; | ||
| 109 | bytes -= bv.bv_len; | ||
| 110 | start = 0; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | return size; | ||
| 93 | } | 115 | } |
| 94 | 116 | ||
| 95 | /* | 117 | /* |
| 96 | * Allocate a page vector based on (@it, @nbytes). | 118 | * iov_iter_get_pages() only considers one iov_iter segment, no matter |
| 97 | * The return value is the tuple describing a page vector, | 119 | * what maxsize or maxpages are given. For ITER_BVEC that is a single |
| 98 | * that is (@pages, @page_align, @num_pages). | 120 | * page. |
| 121 | * | ||
| 122 | * Attempt to get up to @maxsize bytes worth of pages from @iter. | ||
| 123 | * Return the number of bytes in the created bio_vec array, or an error. | ||
| 99 | */ | 124 | */ |
| 100 | static struct page ** | 125 | static ssize_t iter_get_bvecs_alloc(struct iov_iter *iter, size_t maxsize, |
| 101 | dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes, | 126 | struct bio_vec **bvecs, int *num_bvecs) |
| 102 | size_t *page_align, int *num_pages) | ||
| 103 | { | 127 | { |
| 104 | struct iov_iter tmp_it = *it; | 128 | struct bio_vec *bv; |
| 105 | size_t align; | 129 | size_t orig_count = iov_iter_count(iter); |
| 106 | struct page **pages; | 130 | ssize_t bytes; |
| 107 | int ret = 0, idx, npages; | 131 | int npages; |
| 108 | 132 | ||
| 109 | align = (unsigned long)(it->iov->iov_base + it->iov_offset) & | 133 | iov_iter_truncate(iter, maxsize); |
| 110 | (PAGE_SIZE - 1); | 134 | npages = iov_iter_npages(iter, INT_MAX); |
| 111 | npages = calc_pages_for(align, nbytes); | 135 | iov_iter_reexpand(iter, orig_count); |
| 112 | pages = kvmalloc(sizeof(*pages) * npages, GFP_KERNEL); | ||
| 113 | if (!pages) | ||
| 114 | return ERR_PTR(-ENOMEM); | ||
| 115 | 136 | ||
| 116 | for (idx = 0; idx < npages; ) { | 137 | /* |
| 117 | size_t start; | 138 | * __iter_get_bvecs() may populate only part of the array -- zero it |
| 118 | ret = iov_iter_get_pages(&tmp_it, pages + idx, nbytes, | 139 | * out. |
| 119 | npages - idx, &start); | 140 | */ |
| 120 | if (ret < 0) | 141 | bv = kvmalloc_array(npages, sizeof(*bv), GFP_KERNEL | __GFP_ZERO); |
| 121 | goto fail; | 142 | if (!bv) |
| 143 | return -ENOMEM; | ||
| 122 | 144 | ||
| 123 | iov_iter_advance(&tmp_it, ret); | 145 | bytes = __iter_get_bvecs(iter, maxsize, bv); |
| 124 | nbytes -= ret; | 146 | if (bytes < 0) { |
| 125 | idx += (ret + start + PAGE_SIZE - 1) / PAGE_SIZE; | 147 | /* |
| 148 | * No pages were pinned -- just free the array. | ||
| 149 | */ | ||
| 150 | kvfree(bv); | ||
| 151 | return bytes; | ||
| 126 | } | 152 | } |
| 127 | 153 | ||
| 128 | BUG_ON(nbytes != 0); | 154 | *bvecs = bv; |
| 129 | *num_pages = npages; | 155 | *num_bvecs = npages; |
| 130 | *page_align = align; | 156 | return bytes; |
| 131 | dout("dio_get_pages_alloc: got %d pages align %zu\n", npages, align); | 157 | } |
| 132 | return pages; | 158 | |
| 133 | fail: | 159 | static void put_bvecs(struct bio_vec *bvecs, int num_bvecs, bool should_dirty) |
| 134 | ceph_put_page_vector(pages, idx, false); | 160 | { |
| 135 | return ERR_PTR(ret); | 161 | int i; |
| 162 | |||
| 163 | for (i = 0; i < num_bvecs; i++) { | ||
| 164 | if (bvecs[i].bv_page) { | ||
| 165 | if (should_dirty) | ||
| 166 | set_page_dirty_lock(bvecs[i].bv_page); | ||
| 167 | put_page(bvecs[i].bv_page); | ||
| 168 | } | ||
| 169 | } | ||
| 170 | kvfree(bvecs); | ||
| 136 | } | 171 | } |
| 137 | 172 | ||
| 138 | /* | 173 | /* |
| @@ -746,11 +781,12 @@ static void ceph_aio_complete_req(struct ceph_osd_request *req) | |||
| 746 | struct inode *inode = req->r_inode; | 781 | struct inode *inode = req->r_inode; |
| 747 | struct ceph_aio_request *aio_req = req->r_priv; | 782 | struct ceph_aio_request *aio_req = req->r_priv; |
| 748 | struct ceph_osd_data *osd_data = osd_req_op_extent_osd_data(req, 0); | 783 | struct ceph_osd_data *osd_data = osd_req_op_extent_osd_data(req, 0); |
| 749 | int num_pages = calc_pages_for((u64)osd_data->alignment, | ||
| 750 | osd_data->length); | ||
| 751 | 784 | ||
| 752 | dout("ceph_aio_complete_req %p rc %d bytes %llu\n", | 785 | BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_BVECS); |
| 753 | inode, rc, osd_data->length); | 786 | BUG_ON(!osd_data->num_bvecs); |
| 787 | |||
| 788 | dout("ceph_aio_complete_req %p rc %d bytes %u\n", | ||
| 789 | inode, rc, osd_data->bvec_pos.iter.bi_size); | ||
| 754 | 790 | ||
| 755 | if (rc == -EOLDSNAPC) { | 791 | if (rc == -EOLDSNAPC) { |
| 756 | struct ceph_aio_work *aio_work; | 792 | struct ceph_aio_work *aio_work; |
| @@ -768,9 +804,10 @@ static void ceph_aio_complete_req(struct ceph_osd_request *req) | |||
| 768 | } else if (!aio_req->write) { | 804 | } else if (!aio_req->write) { |
| 769 | if (rc == -ENOENT) | 805 | if (rc == -ENOENT) |
| 770 | rc = 0; | 806 | rc = 0; |
| 771 | if (rc >= 0 && osd_data->length > rc) { | 807 | if (rc >= 0 && osd_data->bvec_pos.iter.bi_size > rc) { |
| 772 | int zoff = osd_data->alignment + rc; | 808 | struct iov_iter i; |
| 773 | int zlen = osd_data->length - rc; | 809 | int zlen = osd_data->bvec_pos.iter.bi_size - rc; |
| 810 | |||
| 774 | /* | 811 | /* |
| 775 | * If read is satisfied by single OSD request, | 812 | * If read is satisfied by single OSD request, |
| 776 | * it can pass EOF. Otherwise read is within | 813 | * it can pass EOF. Otherwise read is within |
| @@ -785,13 +822,16 @@ static void ceph_aio_complete_req(struct ceph_osd_request *req) | |||
| 785 | aio_req->total_len = rc + zlen; | 822 | aio_req->total_len = rc + zlen; |
| 786 | } | 823 | } |
| 787 | 824 | ||
| 788 | if (zlen > 0) | 825 | iov_iter_bvec(&i, ITER_BVEC, osd_data->bvec_pos.bvecs, |
| 789 | ceph_zero_page_vector_range(zoff, zlen, | 826 | osd_data->num_bvecs, |
| 790 | osd_data->pages); | 827 | osd_data->bvec_pos.iter.bi_size); |
| 828 | iov_iter_advance(&i, rc); | ||
| 829 | iov_iter_zero(zlen, &i); | ||
| 791 | } | 830 | } |
| 792 | } | 831 | } |
| 793 | 832 | ||
| 794 | ceph_put_page_vector(osd_data->pages, num_pages, aio_req->should_dirty); | 833 | put_bvecs(osd_data->bvec_pos.bvecs, osd_data->num_bvecs, |
| 834 | aio_req->should_dirty); | ||
| 795 | ceph_osdc_put_request(req); | 835 | ceph_osdc_put_request(req); |
| 796 | 836 | ||
| 797 | if (rc < 0) | 837 | if (rc < 0) |
| @@ -879,7 +919,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, | |||
| 879 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); | 919 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); |
| 880 | struct ceph_vino vino; | 920 | struct ceph_vino vino; |
| 881 | struct ceph_osd_request *req; | 921 | struct ceph_osd_request *req; |
| 882 | struct page **pages; | 922 | struct bio_vec *bvecs; |
| 883 | struct ceph_aio_request *aio_req = NULL; | 923 | struct ceph_aio_request *aio_req = NULL; |
| 884 | int num_pages = 0; | 924 | int num_pages = 0; |
| 885 | int flags; | 925 | int flags; |
| @@ -914,10 +954,14 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, | |||
| 914 | } | 954 | } |
| 915 | 955 | ||
| 916 | while (iov_iter_count(iter) > 0) { | 956 | while (iov_iter_count(iter) > 0) { |
| 917 | u64 size = dio_get_pagev_size(iter); | 957 | u64 size = iov_iter_count(iter); |
| 918 | size_t start = 0; | ||
| 919 | ssize_t len; | 958 | ssize_t len; |
| 920 | 959 | ||
| 960 | if (write) | ||
| 961 | size = min_t(u64, size, fsc->mount_options->wsize); | ||
| 962 | else | ||
| 963 | size = min_t(u64, size, fsc->mount_options->rsize); | ||
| 964 | |||
| 921 | vino = ceph_vino(inode); | 965 | vino = ceph_vino(inode); |
| 922 | req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, | 966 | req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, |
| 923 | vino, pos, &size, 0, | 967 | vino, pos, &size, 0, |
| @@ -933,18 +977,14 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, | |||
| 933 | break; | 977 | break; |
| 934 | } | 978 | } |
| 935 | 979 | ||
| 936 | if (write) | 980 | len = iter_get_bvecs_alloc(iter, size, &bvecs, &num_pages); |
| 937 | size = min_t(u64, size, fsc->mount_options->wsize); | 981 | if (len < 0) { |
| 938 | else | ||
| 939 | size = min_t(u64, size, fsc->mount_options->rsize); | ||
| 940 | |||
| 941 | len = size; | ||
| 942 | pages = dio_get_pages_alloc(iter, len, &start, &num_pages); | ||
| 943 | if (IS_ERR(pages)) { | ||
| 944 | ceph_osdc_put_request(req); | 982 | ceph_osdc_put_request(req); |
| 945 | ret = PTR_ERR(pages); | 983 | ret = len; |
| 946 | break; | 984 | break; |
| 947 | } | 985 | } |
| 986 | if (len != size) | ||
| 987 | osd_req_op_extent_update(req, 0, len); | ||
| 948 | 988 | ||
| 949 | /* | 989 | /* |
| 950 | * To simplify error handling, allow AIO when IO within i_size | 990 | * To simplify error handling, allow AIO when IO within i_size |
| @@ -977,8 +1017,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, | |||
| 977 | req->r_mtime = mtime; | 1017 | req->r_mtime = mtime; |
| 978 | } | 1018 | } |
| 979 | 1019 | ||
| 980 | osd_req_op_extent_osd_data_pages(req, 0, pages, len, start, | 1020 | osd_req_op_extent_osd_data_bvecs(req, 0, bvecs, num_pages, len); |
| 981 | false, false); | ||
| 982 | 1021 | ||
| 983 | if (aio_req) { | 1022 | if (aio_req) { |
| 984 | aio_req->total_len += len; | 1023 | aio_req->total_len += len; |
| @@ -991,7 +1030,6 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, | |||
| 991 | list_add_tail(&req->r_unsafe_item, &aio_req->osd_reqs); | 1030 | list_add_tail(&req->r_unsafe_item, &aio_req->osd_reqs); |
| 992 | 1031 | ||
| 993 | pos += len; | 1032 | pos += len; |
| 994 | iov_iter_advance(iter, len); | ||
| 995 | continue; | 1033 | continue; |
| 996 | } | 1034 | } |
| 997 | 1035 | ||
| @@ -1004,25 +1042,26 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, | |||
| 1004 | if (ret == -ENOENT) | 1042 | if (ret == -ENOENT) |
| 1005 | ret = 0; | 1043 | ret = 0; |
| 1006 | if (ret >= 0 && ret < len && pos + ret < size) { | 1044 | if (ret >= 0 && ret < len && pos + ret < size) { |
| 1045 | struct iov_iter i; | ||
| 1007 | int zlen = min_t(size_t, len - ret, | 1046 | int zlen = min_t(size_t, len - ret, |
| 1008 | size - pos - ret); | 1047 | size - pos - ret); |
| 1009 | ceph_zero_page_vector_range(start + ret, zlen, | 1048 | |
| 1010 | pages); | 1049 | iov_iter_bvec(&i, ITER_BVEC, bvecs, num_pages, |
| 1050 | len); | ||
| 1051 | iov_iter_advance(&i, ret); | ||
| 1052 | iov_iter_zero(zlen, &i); | ||
| 1011 | ret += zlen; | 1053 | ret += zlen; |
| 1012 | } | 1054 | } |
| 1013 | if (ret >= 0) | 1055 | if (ret >= 0) |
| 1014 | len = ret; | 1056 | len = ret; |
| 1015 | } | 1057 | } |
| 1016 | 1058 | ||
| 1017 | ceph_put_page_vector(pages, num_pages, should_dirty); | 1059 | put_bvecs(bvecs, num_pages, should_dirty); |
| 1018 | |||
| 1019 | ceph_osdc_put_request(req); | 1060 | ceph_osdc_put_request(req); |
| 1020 | if (ret < 0) | 1061 | if (ret < 0) |
| 1021 | break; | 1062 | break; |
| 1022 | 1063 | ||
| 1023 | pos += len; | 1064 | pos += len; |
| 1024 | iov_iter_advance(iter, len); | ||
| 1025 | |||
| 1026 | if (!write && pos >= size) | 1065 | if (!write && pos >= size) |
| 1027 | break; | 1066 | break; |
| 1028 | 1067 | ||
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index 741749a98614..5f132d59dfc2 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
| @@ -197,7 +197,7 @@ config CIFS_SMB311 | |||
| 197 | 197 | ||
| 198 | config CIFS_SMB_DIRECT | 198 | config CIFS_SMB_DIRECT |
| 199 | bool "SMB Direct support (Experimental)" | 199 | bool "SMB Direct support (Experimental)" |
| 200 | depends on CIFS=m && INFINIBAND || CIFS=y && INFINIBAND=y | 200 | depends on CIFS=m && INFINIBAND && INFINIBAND_ADDR_TRANS || CIFS=y && INFINIBAND=y && INFINIBAND_ADDR_TRANS=y |
| 201 | help | 201 | help |
| 202 | Enables SMB Direct experimental support for SMB 3.0, 3.02 and 3.1.1. | 202 | Enables SMB Direct experimental support for SMB 3.0, 3.02 and 3.1.1. |
| 203 | SMB Direct allows transferring SMB packets over RDMA. If unsure, | 203 | SMB Direct allows transferring SMB packets over RDMA. If unsure, |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f715609b13f3..5a5a0158cc8f 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -1047,6 +1047,18 @@ out: | |||
| 1047 | return rc; | 1047 | return rc; |
| 1048 | } | 1048 | } |
| 1049 | 1049 | ||
| 1050 | /* | ||
| 1051 | * Directory operations under CIFS/SMB2/SMB3 are synchronous, so fsync() | ||
| 1052 | * is a dummy operation. | ||
| 1053 | */ | ||
| 1054 | static int cifs_dir_fsync(struct file *file, loff_t start, loff_t end, int datasync) | ||
| 1055 | { | ||
| 1056 | cifs_dbg(FYI, "Sync directory - name: %pD datasync: 0x%x\n", | ||
| 1057 | file, datasync); | ||
| 1058 | |||
| 1059 | return 0; | ||
| 1060 | } | ||
| 1061 | |||
| 1050 | static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, | 1062 | static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, |
| 1051 | struct file *dst_file, loff_t destoff, | 1063 | struct file *dst_file, loff_t destoff, |
| 1052 | size_t len, unsigned int flags) | 1064 | size_t len, unsigned int flags) |
| @@ -1181,6 +1193,7 @@ const struct file_operations cifs_dir_ops = { | |||
| 1181 | .copy_file_range = cifs_copy_file_range, | 1193 | .copy_file_range = cifs_copy_file_range, |
| 1182 | .clone_file_range = cifs_clone_file_range, | 1194 | .clone_file_range = cifs_clone_file_range, |
| 1183 | .llseek = generic_file_llseek, | 1195 | .llseek = generic_file_llseek, |
| 1196 | .fsync = cifs_dir_fsync, | ||
| 1184 | }; | 1197 | }; |
| 1185 | 1198 | ||
| 1186 | static void | 1199 | static void |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index a5aa158d535a..7a10a5d0731f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -1977,14 +1977,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
| 1977 | goto cifs_parse_mount_err; | 1977 | goto cifs_parse_mount_err; |
| 1978 | } | 1978 | } |
| 1979 | 1979 | ||
| 1980 | #ifdef CONFIG_CIFS_SMB_DIRECT | ||
| 1981 | if (vol->rdma && vol->sign) { | ||
| 1982 | cifs_dbg(VFS, "Currently SMB direct doesn't support signing." | ||
| 1983 | " This is being fixed\n"); | ||
| 1984 | goto cifs_parse_mount_err; | ||
| 1985 | } | ||
| 1986 | #endif | ||
| 1987 | |||
| 1988 | #ifndef CONFIG_KEYS | 1980 | #ifndef CONFIG_KEYS |
| 1989 | /* Muliuser mounts require CONFIG_KEYS support */ | 1981 | /* Muliuser mounts require CONFIG_KEYS support */ |
| 1990 | if (vol->multiuser) { | 1982 | if (vol->multiuser) { |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index b76b85881dcc..9c6d95ffca97 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
| @@ -589,9 +589,15 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 589 | 589 | ||
| 590 | SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); | 590 | SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); |
| 591 | 591 | ||
| 592 | /* | ||
| 593 | * If ea_name is NULL (listxattr) and there are no EAs, return 0 as it's | ||
| 594 | * not an error. Otherwise, the specified ea_name was not found. | ||
| 595 | */ | ||
| 592 | if (!rc) | 596 | if (!rc) |
| 593 | rc = move_smb2_ea_to_cifs(ea_data, buf_size, smb2_data, | 597 | rc = move_smb2_ea_to_cifs(ea_data, buf_size, smb2_data, |
| 594 | SMB2_MAX_EA_BUF, ea_name); | 598 | SMB2_MAX_EA_BUF, ea_name); |
| 599 | else if (!ea_name && rc == -ENODATA) | ||
| 600 | rc = 0; | ||
| 595 | 601 | ||
| 596 | kfree(smb2_data); | 602 | kfree(smb2_data); |
| 597 | return rc; | 603 | return rc; |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 60db51bae0e3..0f48741a0130 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
| @@ -730,19 +730,14 @@ neg_exit: | |||
| 730 | 730 | ||
| 731 | int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) | 731 | int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) |
| 732 | { | 732 | { |
| 733 | int rc = 0; | 733 | int rc; |
| 734 | struct validate_negotiate_info_req vneg_inbuf; | 734 | struct validate_negotiate_info_req *pneg_inbuf; |
| 735 | struct validate_negotiate_info_rsp *pneg_rsp = NULL; | 735 | struct validate_negotiate_info_rsp *pneg_rsp = NULL; |
| 736 | u32 rsplen; | 736 | u32 rsplen; |
| 737 | u32 inbuflen; /* max of 4 dialects */ | 737 | u32 inbuflen; /* max of 4 dialects */ |
| 738 | 738 | ||
| 739 | cifs_dbg(FYI, "validate negotiate\n"); | 739 | cifs_dbg(FYI, "validate negotiate\n"); |
| 740 | 740 | ||
| 741 | #ifdef CONFIG_CIFS_SMB_DIRECT | ||
| 742 | if (tcon->ses->server->rdma) | ||
| 743 | return 0; | ||
| 744 | #endif | ||
| 745 | |||
| 746 | /* In SMB3.11 preauth integrity supersedes validate negotiate */ | 741 | /* In SMB3.11 preauth integrity supersedes validate negotiate */ |
| 747 | if (tcon->ses->server->dialect == SMB311_PROT_ID) | 742 | if (tcon->ses->server->dialect == SMB311_PROT_ID) |
| 748 | return 0; | 743 | return 0; |
| @@ -765,63 +760,69 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) | |||
| 765 | if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) | 760 | if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) |
| 766 | cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n"); | 761 | cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n"); |
| 767 | 762 | ||
| 768 | vneg_inbuf.Capabilities = | 763 | pneg_inbuf = kmalloc(sizeof(*pneg_inbuf), GFP_NOFS); |
| 764 | if (!pneg_inbuf) | ||
| 765 | return -ENOMEM; | ||
| 766 | |||
| 767 | pneg_inbuf->Capabilities = | ||
| 769 | cpu_to_le32(tcon->ses->server->vals->req_capabilities); | 768 | cpu_to_le32(tcon->ses->server->vals->req_capabilities); |
| 770 | memcpy(vneg_inbuf.Guid, tcon->ses->server->client_guid, | 769 | memcpy(pneg_inbuf->Guid, tcon->ses->server->client_guid, |
| 771 | SMB2_CLIENT_GUID_SIZE); | 770 | SMB2_CLIENT_GUID_SIZE); |
| 772 | 771 | ||
| 773 | if (tcon->ses->sign) | 772 | if (tcon->ses->sign) |
| 774 | vneg_inbuf.SecurityMode = | 773 | pneg_inbuf->SecurityMode = |
| 775 | cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED); | 774 | cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED); |
| 776 | else if (global_secflags & CIFSSEC_MAY_SIGN) | 775 | else if (global_secflags & CIFSSEC_MAY_SIGN) |
| 777 | vneg_inbuf.SecurityMode = | 776 | pneg_inbuf->SecurityMode = |
| 778 | cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED); | 777 | cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED); |
| 779 | else | 778 | else |
| 780 | vneg_inbuf.SecurityMode = 0; | 779 | pneg_inbuf->SecurityMode = 0; |
| 781 | 780 | ||
| 782 | 781 | ||
| 783 | if (strcmp(tcon->ses->server->vals->version_string, | 782 | if (strcmp(tcon->ses->server->vals->version_string, |
| 784 | SMB3ANY_VERSION_STRING) == 0) { | 783 | SMB3ANY_VERSION_STRING) == 0) { |
| 785 | vneg_inbuf.Dialects[0] = cpu_to_le16(SMB30_PROT_ID); | 784 | pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID); |
| 786 | vneg_inbuf.Dialects[1] = cpu_to_le16(SMB302_PROT_ID); | 785 | pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); |
| 787 | vneg_inbuf.DialectCount = cpu_to_le16(2); | 786 | pneg_inbuf->DialectCount = cpu_to_le16(2); |
| 788 | /* structure is big enough for 3 dialects, sending only 2 */ | 787 | /* structure is big enough for 3 dialects, sending only 2 */ |
| 789 | inbuflen = sizeof(struct validate_negotiate_info_req) - 2; | 788 | inbuflen = sizeof(*pneg_inbuf) - |
| 789 | sizeof(pneg_inbuf->Dialects[0]); | ||
| 790 | } else if (strcmp(tcon->ses->server->vals->version_string, | 790 | } else if (strcmp(tcon->ses->server->vals->version_string, |
| 791 | SMBDEFAULT_VERSION_STRING) == 0) { | 791 | SMBDEFAULT_VERSION_STRING) == 0) { |
| 792 | vneg_inbuf.Dialects[0] = cpu_to_le16(SMB21_PROT_ID); | 792 | pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); |
| 793 | vneg_inbuf.Dialects[1] = cpu_to_le16(SMB30_PROT_ID); | 793 | pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); |
| 794 | vneg_inbuf.Dialects[2] = cpu_to_le16(SMB302_PROT_ID); | 794 | pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); |
| 795 | vneg_inbuf.DialectCount = cpu_to_le16(3); | 795 | pneg_inbuf->DialectCount = cpu_to_le16(3); |
| 796 | /* structure is big enough for 3 dialects */ | 796 | /* structure is big enough for 3 dialects */ |
| 797 | inbuflen = sizeof(struct validate_negotiate_info_req); | 797 | inbuflen = sizeof(*pneg_inbuf); |
| 798 | } else { | 798 | } else { |
| 799 | /* otherwise specific dialect was requested */ | 799 | /* otherwise specific dialect was requested */ |
| 800 | vneg_inbuf.Dialects[0] = | 800 | pneg_inbuf->Dialects[0] = |
| 801 | cpu_to_le16(tcon->ses->server->vals->protocol_id); | 801 | cpu_to_le16(tcon->ses->server->vals->protocol_id); |
| 802 | vneg_inbuf.DialectCount = cpu_to_le16(1); | 802 | pneg_inbuf->DialectCount = cpu_to_le16(1); |
| 803 | /* structure is big enough for 3 dialects, sending only 1 */ | 803 | /* structure is big enough for 3 dialects, sending only 1 */ |
| 804 | inbuflen = sizeof(struct validate_negotiate_info_req) - 4; | 804 | inbuflen = sizeof(*pneg_inbuf) - |
| 805 | sizeof(pneg_inbuf->Dialects[0]) * 2; | ||
| 805 | } | 806 | } |
| 806 | 807 | ||
| 807 | rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, | 808 | rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, |
| 808 | FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, | 809 | FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, |
| 809 | (char *)&vneg_inbuf, sizeof(struct validate_negotiate_info_req), | 810 | (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen); |
| 810 | (char **)&pneg_rsp, &rsplen); | ||
| 811 | 811 | ||
| 812 | if (rc != 0) { | 812 | if (rc != 0) { |
| 813 | cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); | 813 | cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); |
| 814 | return -EIO; | 814 | rc = -EIO; |
| 815 | goto out_free_inbuf; | ||
| 815 | } | 816 | } |
| 816 | 817 | ||
| 817 | if (rsplen != sizeof(struct validate_negotiate_info_rsp)) { | 818 | rc = -EIO; |
| 819 | if (rsplen != sizeof(*pneg_rsp)) { | ||
| 818 | cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n", | 820 | cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n", |
| 819 | rsplen); | 821 | rsplen); |
| 820 | 822 | ||
| 821 | /* relax check since Mac returns max bufsize allowed on ioctl */ | 823 | /* relax check since Mac returns max bufsize allowed on ioctl */ |
| 822 | if ((rsplen > CIFSMaxBufSize) | 824 | if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp)) |
| 823 | || (rsplen < sizeof(struct validate_negotiate_info_rsp))) | 825 | goto out_free_rsp; |
| 824 | goto err_rsp_free; | ||
| 825 | } | 826 | } |
| 826 | 827 | ||
| 827 | /* check validate negotiate info response matches what we got earlier */ | 828 | /* check validate negotiate info response matches what we got earlier */ |
| @@ -838,15 +839,17 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) | |||
| 838 | goto vneg_out; | 839 | goto vneg_out; |
| 839 | 840 | ||
| 840 | /* validate negotiate successful */ | 841 | /* validate negotiate successful */ |
| 842 | rc = 0; | ||
| 841 | cifs_dbg(FYI, "validate negotiate info successful\n"); | 843 | cifs_dbg(FYI, "validate negotiate info successful\n"); |
| 842 | kfree(pneg_rsp); | 844 | goto out_free_rsp; |
| 843 | return 0; | ||
| 844 | 845 | ||
| 845 | vneg_out: | 846 | vneg_out: |
| 846 | cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n"); | 847 | cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n"); |
| 847 | err_rsp_free: | 848 | out_free_rsp: |
| 848 | kfree(pneg_rsp); | 849 | kfree(pneg_rsp); |
| 849 | return -EIO; | 850 | out_free_inbuf: |
| 851 | kfree(pneg_inbuf); | ||
| 852 | return rc; | ||
| 850 | } | 853 | } |
| 851 | 854 | ||
| 852 | enum securityEnum | 855 | enum securityEnum |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 47d7c151fcba..471d863958bc 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -1961,7 +1961,7 @@ void wb_workfn(struct work_struct *work) | |||
| 1961 | } | 1961 | } |
| 1962 | 1962 | ||
| 1963 | if (!list_empty(&wb->work_list)) | 1963 | if (!list_empty(&wb->work_list)) |
| 1964 | mod_delayed_work(bdi_wq, &wb->dwork, 0); | 1964 | wb_wakeup(wb); |
| 1965 | else if (wb_has_dirty_io(wb) && dirty_writeback_interval) | 1965 | else if (wb_has_dirty_io(wb) && dirty_writeback_interval) |
| 1966 | wb_wakeup_delayed(wb); | 1966 | wb_wakeup_delayed(wb); |
| 1967 | 1967 | ||
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 513c357c734b..a6c0f54c48c3 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
| @@ -588,6 +588,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 588 | return 0; | 588 | return 0; |
| 589 | 589 | ||
| 590 | out_put_hidden_dir: | 590 | out_put_hidden_dir: |
| 591 | cancel_delayed_work_sync(&sbi->sync_work); | ||
| 591 | iput(sbi->hidden_dir); | 592 | iput(sbi->hidden_dir); |
| 592 | out_put_root: | 593 | out_put_root: |
| 593 | dput(sb->s_root); | 594 | dput(sb->s_root); |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 01c6b3894406..7869622af22a 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -4250,10 +4250,11 @@ out: | |||
| 4250 | static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir, | 4250 | static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir, |
| 4251 | struct dentry *new_dentry, bool preserve) | 4251 | struct dentry *new_dentry, bool preserve) |
| 4252 | { | 4252 | { |
| 4253 | int error; | 4253 | int error, had_lock; |
| 4254 | struct inode *inode = d_inode(old_dentry); | 4254 | struct inode *inode = d_inode(old_dentry); |
| 4255 | struct buffer_head *old_bh = NULL; | 4255 | struct buffer_head *old_bh = NULL; |
| 4256 | struct inode *new_orphan_inode = NULL; | 4256 | struct inode *new_orphan_inode = NULL; |
| 4257 | struct ocfs2_lock_holder oh; | ||
| 4257 | 4258 | ||
| 4258 | if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) | 4259 | if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) |
| 4259 | return -EOPNOTSUPP; | 4260 | return -EOPNOTSUPP; |
| @@ -4295,6 +4296,14 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir, | |||
| 4295 | goto out; | 4296 | goto out; |
| 4296 | } | 4297 | } |
| 4297 | 4298 | ||
| 4299 | had_lock = ocfs2_inode_lock_tracker(new_orphan_inode, NULL, 1, | ||
| 4300 | &oh); | ||
| 4301 | if (had_lock < 0) { | ||
| 4302 | error = had_lock; | ||
| 4303 | mlog_errno(error); | ||
| 4304 | goto out; | ||
| 4305 | } | ||
| 4306 | |||
| 4298 | /* If the security isn't preserved, we need to re-initialize them. */ | 4307 | /* If the security isn't preserved, we need to re-initialize them. */ |
| 4299 | if (!preserve) { | 4308 | if (!preserve) { |
| 4300 | error = ocfs2_init_security_and_acl(dir, new_orphan_inode, | 4309 | error = ocfs2_init_security_and_acl(dir, new_orphan_inode, |
| @@ -4302,14 +4311,15 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir, | |||
| 4302 | if (error) | 4311 | if (error) |
| 4303 | mlog_errno(error); | 4312 | mlog_errno(error); |
| 4304 | } | 4313 | } |
| 4305 | out: | ||
| 4306 | if (!error) { | 4314 | if (!error) { |
| 4307 | error = ocfs2_mv_orphaned_inode_to_new(dir, new_orphan_inode, | 4315 | error = ocfs2_mv_orphaned_inode_to_new(dir, new_orphan_inode, |
| 4308 | new_dentry); | 4316 | new_dentry); |
| 4309 | if (error) | 4317 | if (error) |
| 4310 | mlog_errno(error); | 4318 | mlog_errno(error); |
| 4311 | } | 4319 | } |
| 4320 | ocfs2_inode_unlock_tracker(new_orphan_inode, 1, &oh, had_lock); | ||
| 4312 | 4321 | ||
| 4322 | out: | ||
| 4313 | if (new_orphan_inode) { | 4323 | if (new_orphan_inode) { |
| 4314 | /* | 4324 | /* |
| 4315 | * We need to open_unlock the inode no matter whether we | 4325 | * We need to open_unlock the inode no matter whether we |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 1b2ede6abcdf..1a76d751cf3c 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -261,7 +261,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, | |||
| 261 | * Inherently racy -- command line shares address space | 261 | * Inherently racy -- command line shares address space |
| 262 | * with code and data. | 262 | * with code and data. |
| 263 | */ | 263 | */ |
| 264 | rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0); | 264 | rv = access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_ANON); |
| 265 | if (rv <= 0) | 265 | if (rv <= 0) |
| 266 | goto out_free_page; | 266 | goto out_free_page; |
| 267 | 267 | ||
| @@ -279,7 +279,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, | |||
| 279 | int nr_read; | 279 | int nr_read; |
| 280 | 280 | ||
| 281 | _count = min3(count, len, PAGE_SIZE); | 281 | _count = min3(count, len, PAGE_SIZE); |
| 282 | nr_read = access_remote_vm(mm, p, page, _count, 0); | 282 | nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); |
| 283 | if (nr_read < 0) | 283 | if (nr_read < 0) |
| 284 | rv = nr_read; | 284 | rv = nr_read; |
| 285 | if (nr_read <= 0) | 285 | if (nr_read <= 0) |
| @@ -325,7 +325,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, | |||
| 325 | bool final; | 325 | bool final; |
| 326 | 326 | ||
| 327 | _count = min3(count, len, PAGE_SIZE); | 327 | _count = min3(count, len, PAGE_SIZE); |
| 328 | nr_read = access_remote_vm(mm, p, page, _count, 0); | 328 | nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); |
| 329 | if (nr_read < 0) | 329 | if (nr_read < 0) |
| 330 | rv = nr_read; | 330 | rv = nr_read; |
| 331 | if (nr_read <= 0) | 331 | if (nr_read <= 0) |
| @@ -946,7 +946,7 @@ static ssize_t environ_read(struct file *file, char __user *buf, | |||
| 946 | max_len = min_t(size_t, PAGE_SIZE, count); | 946 | max_len = min_t(size_t, PAGE_SIZE, count); |
| 947 | this_len = min(max_len, this_len); | 947 | this_len = min(max_len, this_len); |
| 948 | 948 | ||
| 949 | retval = access_remote_vm(mm, (env_start + src), page, this_len, 0); | 949 | retval = access_remote_vm(mm, (env_start + src), page, this_len, FOLL_ANON); |
| 950 | 950 | ||
| 951 | if (retval <= 0) { | 951 | if (retval <= 0) { |
| 952 | ret = retval; | 952 | ret = retval; |
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index d1e82761de81..e64ecb9f2720 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
| @@ -209,25 +209,34 @@ kclist_add_private(unsigned long pfn, unsigned long nr_pages, void *arg) | |||
| 209 | { | 209 | { |
| 210 | struct list_head *head = (struct list_head *)arg; | 210 | struct list_head *head = (struct list_head *)arg; |
| 211 | struct kcore_list *ent; | 211 | struct kcore_list *ent; |
| 212 | struct page *p; | ||
| 213 | |||
| 214 | if (!pfn_valid(pfn)) | ||
| 215 | return 1; | ||
| 216 | |||
| 217 | p = pfn_to_page(pfn); | ||
| 218 | if (!memmap_valid_within(pfn, p, page_zone(p))) | ||
| 219 | return 1; | ||
| 212 | 220 | ||
| 213 | ent = kmalloc(sizeof(*ent), GFP_KERNEL); | 221 | ent = kmalloc(sizeof(*ent), GFP_KERNEL); |
| 214 | if (!ent) | 222 | if (!ent) |
| 215 | return -ENOMEM; | 223 | return -ENOMEM; |
| 216 | ent->addr = (unsigned long)__va((pfn << PAGE_SHIFT)); | 224 | ent->addr = (unsigned long)page_to_virt(p); |
| 217 | ent->size = nr_pages << PAGE_SHIFT; | 225 | ent->size = nr_pages << PAGE_SHIFT; |
| 218 | 226 | ||
| 219 | /* Sanity check: Can happen in 32bit arch...maybe */ | 227 | if (!virt_addr_valid(ent->addr)) |
| 220 | if (ent->addr < (unsigned long) __va(0)) | ||
| 221 | goto free_out; | 228 | goto free_out; |
| 222 | 229 | ||
| 223 | /* cut not-mapped area. ....from ppc-32 code. */ | 230 | /* cut not-mapped area. ....from ppc-32 code. */ |
| 224 | if (ULONG_MAX - ent->addr < ent->size) | 231 | if (ULONG_MAX - ent->addr < ent->size) |
| 225 | ent->size = ULONG_MAX - ent->addr; | 232 | ent->size = ULONG_MAX - ent->addr; |
| 226 | 233 | ||
| 227 | /* cut when vmalloc() area is higher than direct-map area */ | 234 | /* |
| 228 | if (VMALLOC_START > (unsigned long)__va(0)) { | 235 | * We've already checked virt_addr_valid so we know this address |
| 229 | if (ent->addr > VMALLOC_START) | 236 | * is a valid pointer, therefore we can check against it to determine |
| 230 | goto free_out; | 237 | * if we need to trim |
| 238 | */ | ||
| 239 | if (VMALLOC_START > ent->addr) { | ||
| 231 | if (VMALLOC_START - ent->addr < ent->size) | 240 | if (VMALLOC_START - ent->addr < ent->size) |
| 232 | ent->size = VMALLOC_START - ent->addr; | 241 | ent->size = VMALLOC_START - ent->addr; |
| 233 | } | 242 | } |
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index ce4a34a2751d..35a124400d60 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c | |||
| @@ -511,7 +511,14 @@ xfs_attr_shortform_addname(xfs_da_args_t *args) | |||
| 511 | if (args->flags & ATTR_CREATE) | 511 | if (args->flags & ATTR_CREATE) |
| 512 | return retval; | 512 | return retval; |
| 513 | retval = xfs_attr_shortform_remove(args); | 513 | retval = xfs_attr_shortform_remove(args); |
| 514 | ASSERT(retval == 0); | 514 | if (retval) |
| 515 | return retval; | ||
| 516 | /* | ||
| 517 | * Since we have removed the old attr, clear ATTR_REPLACE so | ||
| 518 | * that the leaf format add routine won't trip over the attr | ||
| 519 | * not being around. | ||
| 520 | */ | ||
| 521 | args->flags &= ~ATTR_REPLACE; | ||
| 515 | } | 522 | } |
| 516 | 523 | ||
| 517 | if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX || | 524 | if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX || |
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 6a7c2f03ea11..040eeda8426f 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
| @@ -725,12 +725,16 @@ xfs_bmap_extents_to_btree( | |||
| 725 | *logflagsp = 0; | 725 | *logflagsp = 0; |
| 726 | if ((error = xfs_alloc_vextent(&args))) { | 726 | if ((error = xfs_alloc_vextent(&args))) { |
| 727 | xfs_iroot_realloc(ip, -1, whichfork); | 727 | xfs_iroot_realloc(ip, -1, whichfork); |
| 728 | ASSERT(ifp->if_broot == NULL); | ||
| 729 | XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); | ||
| 728 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | 730 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
| 729 | return error; | 731 | return error; |
| 730 | } | 732 | } |
| 731 | 733 | ||
| 732 | if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { | 734 | if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { |
| 733 | xfs_iroot_realloc(ip, -1, whichfork); | 735 | xfs_iroot_realloc(ip, -1, whichfork); |
| 736 | ASSERT(ifp->if_broot == NULL); | ||
| 737 | XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); | ||
| 734 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | 738 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
| 735 | return -ENOSPC; | 739 | return -ENOSPC; |
| 736 | } | 740 | } |
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index ef68b1de006a..1201107eabc6 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c | |||
| @@ -466,6 +466,8 @@ xfs_dinode_verify( | |||
| 466 | return __this_address; | 466 | return __this_address; |
| 467 | if (di_size > XFS_DFORK_DSIZE(dip, mp)) | 467 | if (di_size > XFS_DFORK_DSIZE(dip, mp)) |
| 468 | return __this_address; | 468 | return __this_address; |
| 469 | if (dip->di_nextents) | ||
| 470 | return __this_address; | ||
| 469 | /* fall through */ | 471 | /* fall through */ |
| 470 | case XFS_DINODE_FMT_EXTENTS: | 472 | case XFS_DINODE_FMT_EXTENTS: |
| 471 | case XFS_DINODE_FMT_BTREE: | 473 | case XFS_DINODE_FMT_BTREE: |
| @@ -484,12 +486,31 @@ xfs_dinode_verify( | |||
| 484 | if (XFS_DFORK_Q(dip)) { | 486 | if (XFS_DFORK_Q(dip)) { |
| 485 | switch (dip->di_aformat) { | 487 | switch (dip->di_aformat) { |
| 486 | case XFS_DINODE_FMT_LOCAL: | 488 | case XFS_DINODE_FMT_LOCAL: |
| 489 | if (dip->di_anextents) | ||
| 490 | return __this_address; | ||
| 491 | /* fall through */ | ||
| 487 | case XFS_DINODE_FMT_EXTENTS: | 492 | case XFS_DINODE_FMT_EXTENTS: |
| 488 | case XFS_DINODE_FMT_BTREE: | 493 | case XFS_DINODE_FMT_BTREE: |
| 489 | break; | 494 | break; |
| 490 | default: | 495 | default: |
| 491 | return __this_address; | 496 | return __this_address; |
| 492 | } | 497 | } |
| 498 | } else { | ||
| 499 | /* | ||
| 500 | * If there is no fork offset, this may be a freshly-made inode | ||
| 501 | * in a new disk cluster, in which case di_aformat is zeroed. | ||
| 502 | * Otherwise, such an inode must be in EXTENTS format; this goes | ||
| 503 | * for freed inodes as well. | ||
| 504 | */ | ||
| 505 | switch (dip->di_aformat) { | ||
| 506 | case 0: | ||
| 507 | case XFS_DINODE_FMT_EXTENTS: | ||
| 508 | break; | ||
| 509 | default: | ||
| 510 | return __this_address; | ||
| 511 | } | ||
| 512 | if (dip->di_anextents) | ||
| 513 | return __this_address; | ||
| 493 | } | 514 | } |
| 494 | 515 | ||
| 495 | /* only version 3 or greater inodes are extensively verified here */ | 516 | /* only version 3 or greater inodes are extensively verified here */ |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 299aee4b7b0b..e70fb8ccecea 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
| @@ -778,22 +778,26 @@ xfs_file_fallocate( | |||
| 778 | if (error) | 778 | if (error) |
| 779 | goto out_unlock; | 779 | goto out_unlock; |
| 780 | } else if (mode & FALLOC_FL_INSERT_RANGE) { | 780 | } else if (mode & FALLOC_FL_INSERT_RANGE) { |
| 781 | unsigned int blksize_mask = i_blocksize(inode) - 1; | 781 | unsigned int blksize_mask = i_blocksize(inode) - 1; |
| 782 | loff_t isize = i_size_read(inode); | ||
| 782 | 783 | ||
| 783 | new_size = i_size_read(inode) + len; | ||
| 784 | if (offset & blksize_mask || len & blksize_mask) { | 784 | if (offset & blksize_mask || len & blksize_mask) { |
| 785 | error = -EINVAL; | 785 | error = -EINVAL; |
| 786 | goto out_unlock; | 786 | goto out_unlock; |
| 787 | } | 787 | } |
| 788 | 788 | ||
| 789 | /* check the new inode size does not wrap through zero */ | 789 | /* |
| 790 | if (new_size > inode->i_sb->s_maxbytes) { | 790 | * New inode size must not exceed ->s_maxbytes, accounting for |
| 791 | * possible signed overflow. | ||
| 792 | */ | ||
| 793 | if (inode->i_sb->s_maxbytes - isize < len) { | ||
| 791 | error = -EFBIG; | 794 | error = -EFBIG; |
| 792 | goto out_unlock; | 795 | goto out_unlock; |
| 793 | } | 796 | } |
| 797 | new_size = isize + len; | ||
| 794 | 798 | ||
| 795 | /* Offset should be less than i_size */ | 799 | /* Offset should be less than i_size */ |
| 796 | if (offset >= i_size_read(inode)) { | 800 | if (offset >= isize) { |
| 797 | error = -EINVAL; | 801 | error = -EINVAL; |
| 798 | goto out_unlock; | 802 | goto out_unlock; |
| 799 | } | 803 | } |
| @@ -876,8 +880,18 @@ xfs_file_dedupe_range( | |||
| 876 | struct file *dst_file, | 880 | struct file *dst_file, |
| 877 | u64 dst_loff) | 881 | u64 dst_loff) |
| 878 | { | 882 | { |
| 883 | struct inode *srci = file_inode(src_file); | ||
| 884 | u64 max_dedupe; | ||
| 879 | int error; | 885 | int error; |
| 880 | 886 | ||
| 887 | /* | ||
| 888 | * Since we have to read all these pages in to compare them, cut | ||
| 889 | * it off at MAX_RW_COUNT/2 rounded down to the nearest block. | ||
| 890 | * That means we won't do more than MAX_RW_COUNT IO per request. | ||
| 891 | */ | ||
| 892 | max_dedupe = (MAX_RW_COUNT >> 1) & ~(i_blocksize(srci) - 1); | ||
| 893 | if (len > max_dedupe) | ||
| 894 | len = max_dedupe; | ||
| 881 | error = xfs_reflink_remap_range(src_file, loff, dst_file, dst_loff, | 895 | error = xfs_reflink_remap_range(src_file, loff, dst_file, dst_loff, |
| 882 | len, true); | 896 | len, true); |
| 883 | if (error) | 897 | if (error) |
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 7b289dd00a30..6f69a4f638f8 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h | |||
| @@ -49,11 +49,14 @@ | |||
| 49 | /* Definitions of the predefined namespace names */ | 49 | /* Definitions of the predefined namespace names */ |
| 50 | 50 | ||
| 51 | #define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */ | 51 | #define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */ |
| 52 | #define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */ | ||
| 53 | |||
| 54 | #define ACPI_PREFIX_MIXED (u32) 0x69706341 /* "Acpi" */ | 52 | #define ACPI_PREFIX_MIXED (u32) 0x69706341 /* "Acpi" */ |
| 55 | #define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */ | 53 | #define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */ |
| 56 | 54 | ||
| 55 | /* Root name stuff */ | ||
| 56 | |||
| 57 | #define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */ | ||
| 58 | #define ACPI_ROOT_PATHNAME "\\___" | ||
| 59 | #define ACPI_NAMESPACE_ROOT "Namespace Root" | ||
| 57 | #define ACPI_NS_ROOT_PATH "\\" | 60 | #define ACPI_NS_ROOT_PATH "\\" |
| 58 | 61 | ||
| 59 | #endif /* __ACNAMES_H__ */ | 62 | #endif /* __ACNAMES_H__ */ |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 540d35f06ad6..eb1f21af7556 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
| @@ -98,6 +98,27 @@ void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags); | |||
| 98 | #endif | 98 | #endif |
| 99 | 99 | ||
| 100 | /* | 100 | /* |
| 101 | * RAW spinlock primitives. If the OS does not provide them, fallback to | ||
| 102 | * spinlock primitives | ||
| 103 | */ | ||
| 104 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_raw_lock | ||
| 105 | # define acpi_os_create_raw_lock(out_handle) acpi_os_create_lock(out_handle) | ||
| 106 | #endif | ||
| 107 | |||
| 108 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_delete_raw_lock | ||
| 109 | # define acpi_os_delete_raw_lock(handle) acpi_os_delete_lock(handle) | ||
| 110 | #endif | ||
| 111 | |||
| 112 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_raw_lock | ||
| 113 | # define acpi_os_acquire_raw_lock(handle) acpi_os_acquire_lock(handle) | ||
| 114 | #endif | ||
| 115 | |||
| 116 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_release_raw_lock | ||
| 117 | # define acpi_os_release_raw_lock(handle, flags) \ | ||
| 118 | acpi_os_release_lock(handle, flags) | ||
| 119 | #endif | ||
| 120 | |||
| 121 | /* | ||
| 101 | * Semaphore primitives | 122 | * Semaphore primitives |
| 102 | */ | 123 | */ |
| 103 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_semaphore | 124 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_semaphore |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index da0215ea9f44..e8c9199bf98f 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 13 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
| 14 | 14 | ||
| 15 | #define ACPI_CA_VERSION 0x20180313 | 15 | #define ACPI_CA_VERSION 0x20180508 |
| 16 | 16 | ||
| 17 | #include <acpi/acconfig.h> | 17 | #include <acpi/acconfig.h> |
| 18 | #include <acpi/actypes.h> | 18 | #include <acpi/actypes.h> |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 1c530f95dc34..2b1bafa197c0 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
| @@ -245,6 +245,10 @@ typedef u64 acpi_physical_address; | |||
| 245 | #define acpi_spinlock void * | 245 | #define acpi_spinlock void * |
| 246 | #endif | 246 | #endif |
| 247 | 247 | ||
| 248 | #ifndef acpi_raw_spinlock | ||
| 249 | #define acpi_raw_spinlock acpi_spinlock | ||
| 250 | #endif | ||
| 251 | |||
| 248 | #ifndef acpi_semaphore | 252 | #ifndef acpi_semaphore |
| 249 | #define acpi_semaphore void * | 253 | #define acpi_semaphore void * |
| 250 | #endif | 254 | #endif |
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 2010c0516f27..8e0b8250a139 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h | |||
| @@ -20,14 +20,16 @@ | |||
| 20 | #include <acpi/pcc.h> | 20 | #include <acpi/pcc.h> |
| 21 | #include <acpi/processor.h> | 21 | #include <acpi/processor.h> |
| 22 | 22 | ||
| 23 | /* Only support CPPCv2 for now. */ | 23 | /* Support CPPCv2 and CPPCv3 */ |
| 24 | #define CPPC_NUM_ENT 21 | 24 | #define CPPC_V2_REV 2 |
| 25 | #define CPPC_REV 2 | 25 | #define CPPC_V3_REV 3 |
| 26 | #define CPPC_V2_NUM_ENT 21 | ||
| 27 | #define CPPC_V3_NUM_ENT 23 | ||
| 26 | 28 | ||
| 27 | #define PCC_CMD_COMPLETE_MASK (1 << 0) | 29 | #define PCC_CMD_COMPLETE_MASK (1 << 0) |
| 28 | #define PCC_ERROR_MASK (1 << 2) | 30 | #define PCC_ERROR_MASK (1 << 2) |
| 29 | 31 | ||
| 30 | #define MAX_CPC_REG_ENT 19 | 32 | #define MAX_CPC_REG_ENT 21 |
| 31 | 33 | ||
| 32 | /* CPPC specific PCC commands. */ | 34 | /* CPPC specific PCC commands. */ |
| 33 | #define CMD_READ 0 | 35 | #define CMD_READ 0 |
| @@ -91,6 +93,8 @@ enum cppc_regs { | |||
| 91 | AUTO_ACT_WINDOW, | 93 | AUTO_ACT_WINDOW, |
| 92 | ENERGY_PERF, | 94 | ENERGY_PERF, |
| 93 | REFERENCE_PERF, | 95 | REFERENCE_PERF, |
| 96 | LOWEST_FREQ, | ||
| 97 | NOMINAL_FREQ, | ||
| 94 | }; | 98 | }; |
| 95 | 99 | ||
| 96 | /* | 100 | /* |
| @@ -104,6 +108,8 @@ struct cppc_perf_caps { | |||
| 104 | u32 nominal_perf; | 108 | u32 nominal_perf; |
| 105 | u32 lowest_perf; | 109 | u32 lowest_perf; |
| 106 | u32 lowest_nonlinear_perf; | 110 | u32 lowest_nonlinear_perf; |
| 111 | u32 lowest_freq; | ||
| 112 | u32 nominal_freq; | ||
| 107 | }; | 113 | }; |
| 108 | 114 | ||
| 109 | struct cppc_perf_ctrls { | 115 | struct cppc_perf_ctrls { |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index a0b232703302..7451b3bca83a 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
| @@ -102,6 +102,7 @@ | |||
| 102 | 102 | ||
| 103 | #define acpi_cache_t struct kmem_cache | 103 | #define acpi_cache_t struct kmem_cache |
| 104 | #define acpi_spinlock spinlock_t * | 104 | #define acpi_spinlock spinlock_t * |
| 105 | #define acpi_raw_spinlock raw_spinlock_t * | ||
| 105 | #define acpi_cpu_flags unsigned long | 106 | #define acpi_cpu_flags unsigned long |
| 106 | 107 | ||
| 107 | /* Use native linux version of acpi_os_allocate_zeroed */ | 108 | /* Use native linux version of acpi_os_allocate_zeroed */ |
| @@ -119,6 +120,10 @@ | |||
| 119 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object | 120 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object |
| 120 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id | 121 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id |
| 121 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock | 122 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock |
| 123 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_raw_lock | ||
| 124 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_delete_raw_lock | ||
| 125 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_raw_lock | ||
| 126 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_release_raw_lock | ||
| 122 | 127 | ||
| 123 | /* | 128 | /* |
| 124 | * OSL interfaces used by debugger/disassembler | 129 | * OSL interfaces used by debugger/disassembler |
diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h index 7e81475fe034..d754a1b12721 100644 --- a/include/acpi/platform/aclinuxex.h +++ b/include/acpi/platform/aclinuxex.h | |||
| @@ -90,6 +90,36 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) | |||
| 90 | lock ? AE_OK : AE_NO_MEMORY; \ | 90 | lock ? AE_OK : AE_NO_MEMORY; \ |
| 91 | }) | 91 | }) |
| 92 | 92 | ||
| 93 | |||
| 94 | #define acpi_os_create_raw_lock(__handle) \ | ||
| 95 | ({ \ | ||
| 96 | raw_spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ | ||
| 97 | if (lock) { \ | ||
| 98 | *(__handle) = lock; \ | ||
| 99 | raw_spin_lock_init(*(__handle)); \ | ||
| 100 | } \ | ||
| 101 | lock ? AE_OK : AE_NO_MEMORY; \ | ||
| 102 | }) | ||
| 103 | |||
| 104 | static inline acpi_cpu_flags acpi_os_acquire_raw_lock(acpi_raw_spinlock lockp) | ||
| 105 | { | ||
| 106 | acpi_cpu_flags flags; | ||
| 107 | |||
| 108 | raw_spin_lock_irqsave(lockp, flags); | ||
| 109 | return flags; | ||
| 110 | } | ||
| 111 | |||
| 112 | static inline void acpi_os_release_raw_lock(acpi_raw_spinlock lockp, | ||
| 113 | acpi_cpu_flags flags) | ||
| 114 | { | ||
| 115 | raw_spin_unlock_irqrestore(lockp, flags); | ||
| 116 | } | ||
| 117 | |||
| 118 | static inline void acpi_os_delete_raw_lock(acpi_raw_spinlock handle) | ||
| 119 | { | ||
| 120 | ACPI_FREE(handle); | ||
| 121 | } | ||
| 122 | |||
| 93 | static inline u8 acpi_os_readable(void *pointer, acpi_size length) | 123 | static inline u8 acpi_os_readable(void *pointer, acpi_size length) |
| 94 | { | 124 | { |
| 95 | return TRUE; | 125 | return TRUE; |
diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h index 86e3ec662ef4..90ec780bfc68 100644 --- a/include/dt-bindings/clock/stm32mp1-clks.h +++ b/include/dt-bindings/clock/stm32mp1-clks.h | |||
| @@ -76,7 +76,7 @@ | |||
| 76 | #define I2C6 63 | 76 | #define I2C6 63 |
| 77 | #define USART1 64 | 77 | #define USART1 64 |
| 78 | #define RTCAPB 65 | 78 | #define RTCAPB 65 |
| 79 | #define TZC 66 | 79 | #define TZC1 66 |
| 80 | #define TZPC 67 | 80 | #define TZPC 67 |
| 81 | #define IWDG1 68 | 81 | #define IWDG1 68 |
| 82 | #define BSEC 69 | 82 | #define BSEC 69 |
| @@ -123,6 +123,7 @@ | |||
| 123 | #define CRC1 110 | 123 | #define CRC1 110 |
| 124 | #define USBH 111 | 124 | #define USBH 111 |
| 125 | #define ETHSTP 112 | 125 | #define ETHSTP 112 |
| 126 | #define TZC2 113 | ||
| 126 | 127 | ||
| 127 | /* Kernel clocks */ | 128 | /* Kernel clocks */ |
| 128 | #define SDMMC1_K 118 | 129 | #define SDMMC1_K 118 |
| @@ -228,7 +229,6 @@ | |||
| 228 | #define CK_MCO2 212 | 229 | #define CK_MCO2 212 |
| 229 | 230 | ||
| 230 | /* TRACE & DEBUG clocks */ | 231 | /* TRACE & DEBUG clocks */ |
| 231 | #define DBG 213 | ||
| 232 | #define CK_DBG 214 | 232 | #define CK_DBG 214 |
| 233 | #define CK_TRACE 215 | 233 | #define CK_TRACE 215 |
| 234 | 234 | ||
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 24f03941ada8..e7efe12a81bd 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h | |||
| @@ -131,6 +131,7 @@ struct vgic_irq { | |||
| 131 | u32 mpidr; /* GICv3 target VCPU */ | 131 | u32 mpidr; /* GICv3 target VCPU */ |
| 132 | }; | 132 | }; |
| 133 | u8 source; /* GICv2 SGIs only */ | 133 | u8 source; /* GICv2 SGIs only */ |
| 134 | u8 active_source; /* GICv2 SGIs only */ | ||
| 134 | u8 priority; | 135 | u8 priority; |
| 135 | enum vgic_irq_config config; /* Level or edge */ | 136 | enum vgic_irq_config config; /* Level or edge */ |
| 136 | 137 | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 15bfb15c2fa5..cb4d7b6b085c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
| @@ -578,6 +578,7 @@ int acpi_match_platform_list(const struct acpi_platform_list *plat); | |||
| 578 | 578 | ||
| 579 | extern void acpi_early_init(void); | 579 | extern void acpi_early_init(void); |
| 580 | extern void acpi_subsystem_init(void); | 580 | extern void acpi_subsystem_init(void); |
| 581 | extern void arch_post_acpi_subsys_init(void); | ||
| 581 | 582 | ||
| 582 | extern int acpi_nvs_register(__u64 start, __u64 size); | 583 | extern int acpi_nvs_register(__u64 start, __u64 size); |
| 583 | 584 | ||
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 486e65e3db26..469b20e1dd7e 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
| @@ -31,6 +31,7 @@ struct bpf_map_ops { | |||
| 31 | void (*map_release)(struct bpf_map *map, struct file *map_file); | 31 | void (*map_release)(struct bpf_map *map, struct file *map_file); |
| 32 | void (*map_free)(struct bpf_map *map); | 32 | void (*map_free)(struct bpf_map *map); |
| 33 | int (*map_get_next_key)(struct bpf_map *map, void *key, void *next_key); | 33 | int (*map_get_next_key)(struct bpf_map *map, void *key, void *next_key); |
| 34 | void (*map_release_uref)(struct bpf_map *map); | ||
| 34 | 35 | ||
| 35 | /* funcs callable from userspace and from eBPF programs */ | 36 | /* funcs callable from userspace and from eBPF programs */ |
| 36 | void *(*map_lookup_elem)(struct bpf_map *map, void *key); | 37 | void *(*map_lookup_elem)(struct bpf_map *map, void *key); |
| @@ -351,6 +352,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array, | |||
| 351 | struct bpf_prog **_prog, *__prog; \ | 352 | struct bpf_prog **_prog, *__prog; \ |
| 352 | struct bpf_prog_array *_array; \ | 353 | struct bpf_prog_array *_array; \ |
| 353 | u32 _ret = 1; \ | 354 | u32 _ret = 1; \ |
| 355 | preempt_disable(); \ | ||
| 354 | rcu_read_lock(); \ | 356 | rcu_read_lock(); \ |
| 355 | _array = rcu_dereference(array); \ | 357 | _array = rcu_dereference(array); \ |
| 356 | if (unlikely(check_non_null && !_array))\ | 358 | if (unlikely(check_non_null && !_array))\ |
| @@ -362,6 +364,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array, | |||
| 362 | } \ | 364 | } \ |
| 363 | _out: \ | 365 | _out: \ |
| 364 | rcu_read_unlock(); \ | 366 | rcu_read_unlock(); \ |
| 367 | preempt_enable_no_resched(); \ | ||
| 365 | _ret; \ | 368 | _ret; \ |
| 366 | }) | 369 | }) |
| 367 | 370 | ||
| @@ -434,7 +437,6 @@ int bpf_stackmap_copy(struct bpf_map *map, void *key, void *value); | |||
| 434 | int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file, | 437 | int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file, |
| 435 | void *key, void *value, u64 map_flags); | 438 | void *key, void *value, u64 map_flags); |
| 436 | int bpf_fd_array_map_lookup_elem(struct bpf_map *map, void *key, u32 *value); | 439 | int bpf_fd_array_map_lookup_elem(struct bpf_map *map, void *key, u32 *value); |
| 437 | void bpf_fd_array_map_clear(struct bpf_map *map); | ||
| 438 | int bpf_fd_htab_map_update_elem(struct bpf_map *map, struct file *map_file, | 440 | int bpf_fd_htab_map_update_elem(struct bpf_map *map, struct file *map_file, |
| 439 | void *key, void *value, u64 map_flags); | 441 | void *key, void *value, u64 map_flags); |
| 440 | int bpf_fd_htab_map_lookup_elem(struct bpf_map *map, void *key, u32 *value); | 442 | int bpf_fd_htab_map_lookup_elem(struct bpf_map *map, void *key, u32 *value); |
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index d3339dd48b1a..b324e01ccf2d 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #define PHY_ID_BCM54612E 0x03625e60 | 25 | #define PHY_ID_BCM54612E 0x03625e60 |
| 26 | #define PHY_ID_BCM54616S 0x03625d10 | 26 | #define PHY_ID_BCM54616S 0x03625d10 |
| 27 | #define PHY_ID_BCM57780 0x03625d90 | 27 | #define PHY_ID_BCM57780 0x03625d90 |
| 28 | #define PHY_ID_BCM89610 0x03625cd0 | ||
| 28 | 29 | ||
| 29 | #define PHY_ID_BCM7250 0xae025280 | 30 | #define PHY_ID_BCM7250 0xae025280 |
| 30 | #define PHY_ID_BCM7260 0xae025190 | 31 | #define PHY_ID_BCM7260 0xae025190 |
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 528ccc943cee..96bb32285989 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h | |||
| @@ -77,7 +77,10 @@ struct ceph_osd_data { | |||
| 77 | u32 bio_length; | 77 | u32 bio_length; |
| 78 | }; | 78 | }; |
| 79 | #endif /* CONFIG_BLOCK */ | 79 | #endif /* CONFIG_BLOCK */ |
| 80 | struct ceph_bvec_iter bvec_pos; | 80 | struct { |
| 81 | struct ceph_bvec_iter bvec_pos; | ||
| 82 | u32 num_bvecs; | ||
| 83 | }; | ||
| 81 | }; | 84 | }; |
| 82 | }; | 85 | }; |
| 83 | 86 | ||
| @@ -412,6 +415,10 @@ void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *osd_req, | |||
| 412 | struct ceph_bio_iter *bio_pos, | 415 | struct ceph_bio_iter *bio_pos, |
| 413 | u32 bio_length); | 416 | u32 bio_length); |
| 414 | #endif /* CONFIG_BLOCK */ | 417 | #endif /* CONFIG_BLOCK */ |
| 418 | void osd_req_op_extent_osd_data_bvecs(struct ceph_osd_request *osd_req, | ||
| 419 | unsigned int which, | ||
| 420 | struct bio_vec *bvecs, u32 num_bvecs, | ||
| 421 | u32 bytes); | ||
| 415 | void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req, | 422 | void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req, |
| 416 | unsigned int which, | 423 | unsigned int which, |
| 417 | struct ceph_bvec_iter *bvec_pos); | 424 | struct ceph_bvec_iter *bvec_pos); |
| @@ -426,7 +433,8 @@ extern void osd_req_op_cls_request_data_pages(struct ceph_osd_request *, | |||
| 426 | bool own_pages); | 433 | bool own_pages); |
| 427 | void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req, | 434 | void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req, |
| 428 | unsigned int which, | 435 | unsigned int which, |
| 429 | struct bio_vec *bvecs, u32 bytes); | 436 | struct bio_vec *bvecs, u32 num_bvecs, |
| 437 | u32 bytes); | ||
| 430 | extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, | 438 | extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, |
| 431 | unsigned int which, | 439 | unsigned int which, |
| 432 | struct page **pages, u64 length, | 440 | struct page **pages, u64 length, |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 210a890008f9..1d25e149c1c5 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
| @@ -765,6 +765,9 @@ int __clk_mux_determine_rate(struct clk_hw *hw, | |||
| 765 | int __clk_determine_rate(struct clk_hw *core, struct clk_rate_request *req); | 765 | int __clk_determine_rate(struct clk_hw *core, struct clk_rate_request *req); |
| 766 | int __clk_mux_determine_rate_closest(struct clk_hw *hw, | 766 | int __clk_mux_determine_rate_closest(struct clk_hw *hw, |
| 767 | struct clk_rate_request *req); | 767 | struct clk_rate_request *req); |
| 768 | int clk_mux_determine_rate_flags(struct clk_hw *hw, | ||
| 769 | struct clk_rate_request *req, | ||
| 770 | unsigned long flags); | ||
| 768 | void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent); | 771 | void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent); |
| 769 | void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate, | 772 | void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate, |
| 770 | unsigned long max_rate); | 773 | unsigned long max_rate); |
diff --git a/include/linux/efi.h b/include/linux/efi.h index f1b7d68ac460..3016d8c456bc 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
| @@ -395,8 +395,8 @@ typedef struct { | |||
| 395 | u32 attributes; | 395 | u32 attributes; |
| 396 | u32 get_bar_attributes; | 396 | u32 get_bar_attributes; |
| 397 | u32 set_bar_attributes; | 397 | u32 set_bar_attributes; |
| 398 | uint64_t romsize; | 398 | u64 romsize; |
| 399 | void *romimage; | 399 | u32 romimage; |
| 400 | } efi_pci_io_protocol_32; | 400 | } efi_pci_io_protocol_32; |
| 401 | 401 | ||
| 402 | typedef struct { | 402 | typedef struct { |
| @@ -415,8 +415,8 @@ typedef struct { | |||
| 415 | u64 attributes; | 415 | u64 attributes; |
| 416 | u64 get_bar_attributes; | 416 | u64 get_bar_attributes; |
| 417 | u64 set_bar_attributes; | 417 | u64 set_bar_attributes; |
| 418 | uint64_t romsize; | 418 | u64 romsize; |
| 419 | void *romimage; | 419 | u64 romimage; |
| 420 | } efi_pci_io_protocol_64; | 420 | } efi_pci_io_protocol_64; |
| 421 | 421 | ||
| 422 | typedef struct { | 422 | typedef struct { |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index c826b0b5232a..6cb8a5789668 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
| @@ -368,7 +368,9 @@ static inline void free_part_stats(struct hd_struct *part) | |||
| 368 | part_stat_add(cpu, gendiskp, field, -subnd) | 368 | part_stat_add(cpu, gendiskp, field, -subnd) |
| 369 | 369 | ||
| 370 | void part_in_flight(struct request_queue *q, struct hd_struct *part, | 370 | void part_in_flight(struct request_queue *q, struct hd_struct *part, |
| 371 | unsigned int inflight[2]); | 371 | unsigned int inflight[2]); |
| 372 | void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, | ||
| 373 | unsigned int inflight[2]); | ||
| 372 | void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, | 374 | void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, |
| 373 | int rw); | 375 | int rw); |
| 374 | void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, | 376 | void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, |
diff --git a/include/linux/kthread.h b/include/linux/kthread.h index c1961761311d..2803264c512f 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h | |||
| @@ -62,6 +62,7 @@ void *kthread_probe_data(struct task_struct *k); | |||
| 62 | int kthread_park(struct task_struct *k); | 62 | int kthread_park(struct task_struct *k); |
| 63 | void kthread_unpark(struct task_struct *k); | 63 | void kthread_unpark(struct task_struct *k); |
| 64 | void kthread_parkme(void); | 64 | void kthread_parkme(void); |
| 65 | void kthread_park_complete(struct task_struct *k); | ||
| 65 | 66 | ||
| 66 | int kthreadd(void *unused); | 67 | int kthreadd(void *unused); |
| 67 | extern struct task_struct *kthreadd_task; | 68 | extern struct task_struct *kthreadd_task; |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 6930c63126c7..6d6e79c59e68 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
| @@ -1045,13 +1045,7 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq) | |||
| 1045 | 1045 | ||
| 1046 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | 1046 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING |
| 1047 | 1047 | ||
| 1048 | #ifdef CONFIG_S390 | 1048 | #define KVM_MAX_IRQ_ROUTES 4096 /* might need extension/rework in the future */ |
| 1049 | #define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that... | ||
| 1050 | #elif defined(CONFIG_ARM64) | ||
| 1051 | #define KVM_MAX_IRQ_ROUTES 4096 | ||
| 1052 | #else | ||
| 1053 | #define KVM_MAX_IRQ_ROUTES 1024 | ||
| 1054 | #endif | ||
| 1055 | 1049 | ||
| 1056 | bool kvm_arch_can_set_irq_routing(struct kvm *kvm); | 1050 | bool kvm_arch_can_set_irq_routing(struct kvm *kvm); |
| 1057 | int kvm_set_irq_routing(struct kvm *kvm, | 1051 | int kvm_set_irq_routing(struct kvm *kvm, |
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 767d193c269a..2a156c5dfadd 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h | |||
| @@ -1284,25 +1284,19 @@ enum { | |||
| 1284 | }; | 1284 | }; |
| 1285 | 1285 | ||
| 1286 | static inline const struct cpumask * | 1286 | static inline const struct cpumask * |
| 1287 | mlx5_get_vector_affinity(struct mlx5_core_dev *dev, int vector) | 1287 | mlx5_get_vector_affinity_hint(struct mlx5_core_dev *dev, int vector) |
| 1288 | { | 1288 | { |
| 1289 | const struct cpumask *mask; | ||
| 1290 | struct irq_desc *desc; | 1289 | struct irq_desc *desc; |
| 1291 | unsigned int irq; | 1290 | unsigned int irq; |
| 1292 | int eqn; | 1291 | int eqn; |
| 1293 | int err; | 1292 | int err; |
| 1294 | 1293 | ||
| 1295 | err = mlx5_vector2eqn(dev, MLX5_EQ_VEC_COMP_BASE + vector, &eqn, &irq); | 1294 | err = mlx5_vector2eqn(dev, vector, &eqn, &irq); |
| 1296 | if (err) | 1295 | if (err) |
| 1297 | return NULL; | 1296 | return NULL; |
| 1298 | 1297 | ||
| 1299 | desc = irq_to_desc(irq); | 1298 | desc = irq_to_desc(irq); |
| 1300 | #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK | 1299 | return desc->affinity_hint; |
| 1301 | mask = irq_data_get_effective_affinity_mask(&desc->irq_data); | ||
| 1302 | #else | ||
| 1303 | mask = desc->irq_common_data.affinity; | ||
| 1304 | #endif | ||
| 1305 | return mask; | ||
| 1306 | } | 1300 | } |
| 1307 | 1301 | ||
| 1308 | #endif /* MLX5_DRIVER_H */ | 1302 | #endif /* MLX5_DRIVER_H */ |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 1ac1f06a4be6..c6fa9a255dbf 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -2466,6 +2466,13 @@ static inline vm_fault_t vmf_insert_pfn(struct vm_area_struct *vma, | |||
| 2466 | return VM_FAULT_NOPAGE; | 2466 | return VM_FAULT_NOPAGE; |
| 2467 | } | 2467 | } |
| 2468 | 2468 | ||
| 2469 | static inline vm_fault_t vmf_error(int err) | ||
| 2470 | { | ||
| 2471 | if (err == -ENOMEM) | ||
| 2472 | return VM_FAULT_OOM; | ||
| 2473 | return VM_FAULT_SIGBUS; | ||
| 2474 | } | ||
| 2475 | |||
| 2469 | struct page *follow_page_mask(struct vm_area_struct *vma, | 2476 | struct page *follow_page_mask(struct vm_area_struct *vma, |
| 2470 | unsigned long address, unsigned int foll_flags, | 2477 | unsigned long address, unsigned int foll_flags, |
| 2471 | unsigned int *page_mask); | 2478 | unsigned int *page_mask); |
| @@ -2493,6 +2500,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma, | |||
| 2493 | #define FOLL_MLOCK 0x1000 /* lock present pages */ | 2500 | #define FOLL_MLOCK 0x1000 /* lock present pages */ |
| 2494 | #define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */ | 2501 | #define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */ |
| 2495 | #define FOLL_COW 0x4000 /* internal GUP flag */ | 2502 | #define FOLL_COW 0x4000 /* internal GUP flag */ |
| 2503 | #define FOLL_ANON 0x8000 /* don't do file mappings */ | ||
| 2496 | 2504 | ||
| 2497 | static inline int vm_fault_to_errno(int vm_fault, int foll_flags) | 2505 | static inline int vm_fault_to_errno(int vm_fault, int foll_flags) |
| 2498 | { | 2506 | { |
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index b5b43f94f311..01b990e4b228 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h | |||
| @@ -312,7 +312,7 @@ void map_destroy(struct mtd_info *mtd); | |||
| 312 | ({ \ | 312 | ({ \ |
| 313 | int i, ret = 1; \ | 313 | int i, ret = 1; \ |
| 314 | for (i = 0; i < map_words(map); i++) { \ | 314 | for (i = 0; i < map_words(map); i++) { \ |
| 315 | if (((val1).x[i] & (val2).x[i]) != (val2).x[i]) { \ | 315 | if (((val1).x[i] & (val2).x[i]) != (val3).x[i]) { \ |
| 316 | ret = 0; \ | 316 | ret = 0; \ |
| 317 | break; \ | 317 | break; \ |
| 318 | } \ | 318 | } \ |
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 5dad59b31244..17c919436f48 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h | |||
| @@ -867,12 +867,18 @@ struct nand_op_instr { | |||
| 867 | * tBERS (during an erase) which all of them are u64 values that cannot be | 867 | * tBERS (during an erase) which all of them are u64 values that cannot be |
| 868 | * divided by usual kernel macros and must be handled with the special | 868 | * divided by usual kernel macros and must be handled with the special |
| 869 | * DIV_ROUND_UP_ULL() macro. | 869 | * DIV_ROUND_UP_ULL() macro. |
| 870 | * | ||
| 871 | * Cast to type of dividend is needed here to guarantee that the result won't | ||
| 872 | * be an unsigned long long when the dividend is an unsigned long (or smaller), | ||
| 873 | * which is what the compiler does when it sees ternary operator with 2 | ||
| 874 | * different return types (picks the largest type to make sure there's no | ||
| 875 | * loss). | ||
| 870 | */ | 876 | */ |
| 871 | #define __DIVIDE(dividend, divisor) ({ \ | 877 | #define __DIVIDE(dividend, divisor) ({ \ |
| 872 | sizeof(dividend) == sizeof(u32) ? \ | 878 | (__typeof__(dividend))(sizeof(dividend) <= sizeof(unsigned long) ? \ |
| 873 | DIV_ROUND_UP(dividend, divisor) : \ | 879 | DIV_ROUND_UP(dividend, divisor) : \ |
| 874 | DIV_ROUND_UP_ULL(dividend, divisor); \ | 880 | DIV_ROUND_UP_ULL(dividend, divisor)); \ |
| 875 | }) | 881 | }) |
| 876 | #define PSEC_TO_NSEC(x) __DIVIDE(x, 1000) | 882 | #define PSEC_TO_NSEC(x) __DIVIDE(x, 1000) |
| 877 | #define PSEC_TO_MSEC(x) __DIVIDE(x, 1000000000) | 883 | #define PSEC_TO_MSEC(x) __DIVIDE(x, 1000000000) |
| 878 | 884 | ||
diff --git a/include/linux/oom.h b/include/linux/oom.h index 5bad038ac012..6adac113e96d 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h | |||
| @@ -95,6 +95,8 @@ static inline int check_stable_address_space(struct mm_struct *mm) | |||
| 95 | return 0; | 95 | return 0; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | void __oom_reap_task_mm(struct mm_struct *mm); | ||
| 99 | |||
| 98 | extern unsigned long oom_badness(struct task_struct *p, | 100 | extern unsigned long oom_badness(struct task_struct *p, |
| 99 | struct mem_cgroup *memcg, const nodemask_t *nodemask, | 101 | struct mem_cgroup *memcg, const nodemask_t *nodemask, |
| 100 | unsigned long totalpages); | 102 | unsigned long totalpages); |
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h index b1f37a89e368..79b99d653e03 100644 --- a/include/linux/percpu-rwsem.h +++ b/include/linux/percpu-rwsem.h | |||
| @@ -133,7 +133,7 @@ static inline void percpu_rwsem_release(struct percpu_rw_semaphore *sem, | |||
| 133 | lock_release(&sem->rw_sem.dep_map, 1, ip); | 133 | lock_release(&sem->rw_sem.dep_map, 1, ip); |
| 134 | #ifdef CONFIG_RWSEM_SPIN_ON_OWNER | 134 | #ifdef CONFIG_RWSEM_SPIN_ON_OWNER |
| 135 | if (!read) | 135 | if (!read) |
| 136 | sem->rw_sem.owner = NULL; | 136 | sem->rw_sem.owner = RWSEM_OWNER_UNKNOWN; |
| 137 | #endif | 137 | #endif |
| 138 | } | 138 | } |
| 139 | 139 | ||
| @@ -141,6 +141,10 @@ static inline void percpu_rwsem_acquire(struct percpu_rw_semaphore *sem, | |||
| 141 | bool read, unsigned long ip) | 141 | bool read, unsigned long ip) |
| 142 | { | 142 | { |
| 143 | lock_acquire(&sem->rw_sem.dep_map, 0, 1, read, 1, NULL, ip); | 143 | lock_acquire(&sem->rw_sem.dep_map, 0, 1, read, 1, NULL, ip); |
| 144 | #ifdef CONFIG_RWSEM_SPIN_ON_OWNER | ||
| 145 | if (!read) | ||
| 146 | sem->rw_sem.owner = current; | ||
| 147 | #endif | ||
| 144 | } | 148 | } |
| 145 | 149 | ||
| 146 | #endif | 150 | #endif |
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h index 6bfd2b581f75..af8a61be2d8d 100644 --- a/include/linux/rbtree_augmented.h +++ b/include/linux/rbtree_augmented.h | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | #include <linux/compiler.h> | 27 | #include <linux/compiler.h> |
| 28 | #include <linux/rbtree.h> | 28 | #include <linux/rbtree.h> |
| 29 | #include <linux/rcupdate.h> | ||
| 29 | 30 | ||
| 30 | /* | 31 | /* |
| 31 | * Please note - only struct rb_augment_callbacks and the prototypes for | 32 | * Please note - only struct rb_augment_callbacks and the prototypes for |
diff --git a/include/linux/rbtree_latch.h b/include/linux/rbtree_latch.h index ece43e882b56..7d012faa509a 100644 --- a/include/linux/rbtree_latch.h +++ b/include/linux/rbtree_latch.h | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | #include <linux/rbtree.h> | 36 | #include <linux/rbtree.h> |
| 37 | #include <linux/seqlock.h> | 37 | #include <linux/seqlock.h> |
| 38 | #include <linux/rcupdate.h> | ||
| 38 | 39 | ||
| 39 | struct latch_tree_node { | 40 | struct latch_tree_node { |
| 40 | struct rb_node node[2]; | 41 | struct rb_node node[2]; |
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index d09a9c7af109..dfdaede9139e 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h | |||
| @@ -569,7 +569,7 @@ static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev) | |||
| 569 | void rproc_add_subdev(struct rproc *rproc, | 569 | void rproc_add_subdev(struct rproc *rproc, |
| 570 | struct rproc_subdev *subdev, | 570 | struct rproc_subdev *subdev, |
| 571 | int (*probe)(struct rproc_subdev *subdev), | 571 | int (*probe)(struct rproc_subdev *subdev), |
| 572 | void (*remove)(struct rproc_subdev *subdev, bool graceful)); | 572 | void (*remove)(struct rproc_subdev *subdev, bool crashed)); |
| 573 | 573 | ||
| 574 | void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev); | 574 | void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev); |
| 575 | 575 | ||
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index 56707d5ff6ad..ab93b6eae696 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h | |||
| @@ -44,6 +44,12 @@ struct rw_semaphore { | |||
| 44 | #endif | 44 | #endif |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | /* | ||
| 48 | * Setting bit 0 of the owner field with other non-zero bits will indicate | ||
| 49 | * that the rwsem is writer-owned with an unknown owner. | ||
| 50 | */ | ||
| 51 | #define RWSEM_OWNER_UNKNOWN ((struct task_struct *)-1L) | ||
| 52 | |||
| 47 | extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); | 53 | extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); |
| 48 | extern struct rw_semaphore *rwsem_down_read_failed_killable(struct rw_semaphore *sem); | 54 | extern struct rw_semaphore *rwsem_down_read_failed_killable(struct rw_semaphore *sem); |
| 49 | extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); | 55 | extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); |
diff --git a/include/linux/sched.h b/include/linux/sched.h index b3d697f3b573..c2413703f45d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -112,17 +112,36 @@ struct task_group; | |||
| 112 | 112 | ||
| 113 | #ifdef CONFIG_DEBUG_ATOMIC_SLEEP | 113 | #ifdef CONFIG_DEBUG_ATOMIC_SLEEP |
| 114 | 114 | ||
| 115 | /* | ||
| 116 | * Special states are those that do not use the normal wait-loop pattern. See | ||
| 117 | * the comment with set_special_state(). | ||
| 118 | */ | ||
| 119 | #define is_special_task_state(state) \ | ||
| 120 | ((state) & (__TASK_STOPPED | __TASK_TRACED | TASK_DEAD)) | ||
| 121 | |||
| 115 | #define __set_current_state(state_value) \ | 122 | #define __set_current_state(state_value) \ |
| 116 | do { \ | 123 | do { \ |
| 124 | WARN_ON_ONCE(is_special_task_state(state_value));\ | ||
| 117 | current->task_state_change = _THIS_IP_; \ | 125 | current->task_state_change = _THIS_IP_; \ |
| 118 | current->state = (state_value); \ | 126 | current->state = (state_value); \ |
| 119 | } while (0) | 127 | } while (0) |
| 128 | |||
| 120 | #define set_current_state(state_value) \ | 129 | #define set_current_state(state_value) \ |
| 121 | do { \ | 130 | do { \ |
| 131 | WARN_ON_ONCE(is_special_task_state(state_value));\ | ||
| 122 | current->task_state_change = _THIS_IP_; \ | 132 | current->task_state_change = _THIS_IP_; \ |
| 123 | smp_store_mb(current->state, (state_value)); \ | 133 | smp_store_mb(current->state, (state_value)); \ |
| 124 | } while (0) | 134 | } while (0) |
| 125 | 135 | ||
| 136 | #define set_special_state(state_value) \ | ||
| 137 | do { \ | ||
| 138 | unsigned long flags; /* may shadow */ \ | ||
| 139 | WARN_ON_ONCE(!is_special_task_state(state_value)); \ | ||
| 140 | raw_spin_lock_irqsave(¤t->pi_lock, flags); \ | ||
| 141 | current->task_state_change = _THIS_IP_; \ | ||
| 142 | current->state = (state_value); \ | ||
| 143 | raw_spin_unlock_irqrestore(¤t->pi_lock, flags); \ | ||
| 144 | } while (0) | ||
| 126 | #else | 145 | #else |
| 127 | /* | 146 | /* |
| 128 | * set_current_state() includes a barrier so that the write of current->state | 147 | * set_current_state() includes a barrier so that the write of current->state |
| @@ -144,8 +163,8 @@ struct task_group; | |||
| 144 | * | 163 | * |
| 145 | * The above is typically ordered against the wakeup, which does: | 164 | * The above is typically ordered against the wakeup, which does: |
| 146 | * | 165 | * |
| 147 | * need_sleep = false; | 166 | * need_sleep = false; |
| 148 | * wake_up_state(p, TASK_UNINTERRUPTIBLE); | 167 | * wake_up_state(p, TASK_UNINTERRUPTIBLE); |
| 149 | * | 168 | * |
| 150 | * Where wake_up_state() (and all other wakeup primitives) imply enough | 169 | * Where wake_up_state() (and all other wakeup primitives) imply enough |
| 151 | * barriers to order the store of the variable against wakeup. | 170 | * barriers to order the store of the variable against wakeup. |
| @@ -154,12 +173,33 @@ struct task_group; | |||
| 154 | * once it observes the TASK_UNINTERRUPTIBLE store the waking CPU can issue a | 173 | * once it observes the TASK_UNINTERRUPTIBLE store the waking CPU can issue a |
| 155 | * TASK_RUNNING store which can collide with __set_current_state(TASK_RUNNING). | 174 | * TASK_RUNNING store which can collide with __set_current_state(TASK_RUNNING). |
| 156 | * | 175 | * |
| 157 | * This is obviously fine, since they both store the exact same value. | 176 | * However, with slightly different timing the wakeup TASK_RUNNING store can |
| 177 | * also collide with the TASK_UNINTERRUPTIBLE store. Loosing that store is not | ||
| 178 | * a problem either because that will result in one extra go around the loop | ||
| 179 | * and our @cond test will save the day. | ||
| 158 | * | 180 | * |
| 159 | * Also see the comments of try_to_wake_up(). | 181 | * Also see the comments of try_to_wake_up(). |
| 160 | */ | 182 | */ |
| 161 | #define __set_current_state(state_value) do { current->state = (state_value); } while (0) | 183 | #define __set_current_state(state_value) \ |
| 162 | #define set_current_state(state_value) smp_store_mb(current->state, (state_value)) | 184 | current->state = (state_value) |
| 185 | |||
| 186 | #define set_current_state(state_value) \ | ||
| 187 | smp_store_mb(current->state, (state_value)) | ||
| 188 | |||
| 189 | /* | ||
| 190 | * set_special_state() should be used for those states when the blocking task | ||
| 191 | * can not use the regular condition based wait-loop. In that case we must | ||
| 192 | * serialize against wakeups such that any possible in-flight TASK_RUNNING stores | ||
| 193 | * will not collide with our state change. | ||
| 194 | */ | ||
| 195 | #define set_special_state(state_value) \ | ||
| 196 | do { \ | ||
| 197 | unsigned long flags; /* may shadow */ \ | ||
| 198 | raw_spin_lock_irqsave(¤t->pi_lock, flags); \ | ||
| 199 | current->state = (state_value); \ | ||
| 200 | raw_spin_unlock_irqrestore(¤t->pi_lock, flags); \ | ||
| 201 | } while (0) | ||
| 202 | |||
| 163 | #endif | 203 | #endif |
| 164 | 204 | ||
| 165 | /* Task command name length: */ | 205 | /* Task command name length: */ |
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index a7ce74c74e49..113d1ad1ced7 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h | |||
| @@ -280,7 +280,7 @@ static inline void kernel_signal_stop(void) | |||
| 280 | { | 280 | { |
| 281 | spin_lock_irq(¤t->sighand->siglock); | 281 | spin_lock_irq(¤t->sighand->siglock); |
| 282 | if (current->jobctl & JOBCTL_STOP_DEQUEUED) | 282 | if (current->jobctl & JOBCTL_STOP_DEQUEUED) |
| 283 | __set_current_state(TASK_STOPPED); | 283 | set_special_state(TASK_STOPPED); |
| 284 | spin_unlock_irq(¤t->sighand->siglock); | 284 | spin_unlock_irq(¤t->sighand->siglock); |
| 285 | 285 | ||
| 286 | schedule(); | 286 | schedule(); |
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 4b6b9283fa7b..8675e145ea8b 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h | |||
| @@ -52,7 +52,7 @@ | |||
| 52 | #define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ | 52 | #define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ |
| 53 | 53 | ||
| 54 | /* big enough to hold our biggest descriptor */ | 54 | /* big enough to hold our biggest descriptor */ |
| 55 | #define USB_COMP_EP0_BUFSIZ 1024 | 55 | #define USB_COMP_EP0_BUFSIZ 4096 |
| 56 | 56 | ||
| 57 | /* OS feature descriptor length <= 4kB */ | 57 | /* OS feature descriptor length <= 4kB */ |
| 58 | #define USB_COMP_EP0_OS_DESC_BUFSIZ 4096 | 58 | #define USB_COMP_EP0_OS_DESC_BUFSIZ 4096 |
diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h index 9318b2166439..2b0072fa5e92 100644 --- a/include/linux/wait_bit.h +++ b/include/linux/wait_bit.h | |||
| @@ -305,4 +305,21 @@ do { \ | |||
| 305 | __ret; \ | 305 | __ret; \ |
| 306 | }) | 306 | }) |
| 307 | 307 | ||
| 308 | /** | ||
| 309 | * clear_and_wake_up_bit - clear a bit and wake up anyone waiting on that bit | ||
| 310 | * | ||
| 311 | * @bit: the bit of the word being waited on | ||
| 312 | * @word: the word being waited on, a kernel virtual address | ||
| 313 | * | ||
| 314 | * You can use this helper if bitflags are manipulated atomically rather than | ||
| 315 | * non-atomically under a lock. | ||
| 316 | */ | ||
| 317 | static inline void clear_and_wake_up_bit(int bit, void *word) | ||
| 318 | { | ||
| 319 | clear_bit_unlock(bit, word); | ||
| 320 | /* See wake_up_bit() for which memory barrier you need to use. */ | ||
| 321 | smp_mb__after_atomic(); | ||
| 322 | wake_up_bit(word, bit); | ||
| 323 | } | ||
| 324 | |||
| 308 | #endif /* _LINUX_WAIT_BIT_H */ | 325 | #endif /* _LINUX_WAIT_BIT_H */ |
diff --git a/include/media/i2c/tvp7002.h b/include/media/i2c/tvp7002.h index 5ee007c1cead..cb213c136089 100644 --- a/include/media/i2c/tvp7002.h +++ b/include/media/i2c/tvp7002.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com> | 5 | * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com> |
| 6 | * | 6 | * |
| 7 | * This code is partially based upon the TVP5150 driver | 7 | * This code is partially based upon the TVP5150 driver |
| 8 | * written by Mauro Carvalho Chehab (mchehab@infradead.org), | 8 | * written by Mauro Carvalho Chehab <mchehab@kernel.org>, |
| 9 | * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com> | 9 | * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com> |
| 10 | * and the TVP7002 driver in the TI LSP 2.10.00.14 | 10 | * and the TVP7002 driver in the TI LSP 2.10.00.14 |
| 11 | * | 11 | * |
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 0bda0adc744f..60a664febba0 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * generic helper functions for handling video4linux capture buffers | 2 | * generic helper functions for handling video4linux capture buffers |
| 3 | * | 3 | * |
| 4 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | 4 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 5 | * | 5 | * |
| 6 | * Highly based on video-buf written originally by: | 6 | * Highly based on video-buf written originally by: |
| 7 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> | 7 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> |
| 8 | * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org> | 8 | * (c) 2006 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 9 | * (c) 2006 Ted Walther and John Sokol | 9 | * (c) 2006 Ted Walther and John Sokol |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index d8b27854e3bf..01bd142b979d 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h | |||
| @@ -6,11 +6,11 @@ | |||
| 6 | * into PAGE_SIZE chunks). They also assume the driver does not need | 6 | * into PAGE_SIZE chunks). They also assume the driver does not need |
| 7 | * to touch the video data. | 7 | * to touch the video data. |
| 8 | * | 8 | * |
| 9 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | 9 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 10 | * | 10 | * |
| 11 | * Highly based on video-buf written originally by: | 11 | * Highly based on video-buf written originally by: |
| 12 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> | 12 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> |
| 13 | * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org> | 13 | * (c) 2006 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 14 | * (c) 2006 Ted Walther and John Sokol | 14 | * (c) 2006 Ted Walther and John Sokol |
| 15 | * | 15 | * |
| 16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h index 486a97efdb56..36c6a4ad3504 100644 --- a/include/media/videobuf-vmalloc.h +++ b/include/media/videobuf-vmalloc.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * into PAGE_SIZE chunks). They also assume the driver does not need | 6 | * into PAGE_SIZE chunks). They also assume the driver does not need |
| 7 | * to touch the video data. | 7 | * to touch the video data. |
| 8 | * | 8 | * |
| 9 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | 9 | * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
diff --git a/include/net/bonding.h b/include/net/bonding.h index f801fc940b29..b52235158836 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h | |||
| @@ -198,6 +198,7 @@ struct bonding { | |||
| 198 | struct slave __rcu *primary_slave; | 198 | struct slave __rcu *primary_slave; |
| 199 | struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */ | 199 | struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */ |
| 200 | bool force_primary; | 200 | bool force_primary; |
| 201 | u32 nest_level; | ||
| 201 | s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ | 202 | s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ |
| 202 | int (*recv_probe)(const struct sk_buff *, struct bonding *, | 203 | int (*recv_probe)(const struct sk_buff *, struct bonding *, |
| 203 | struct slave *); | 204 | struct slave *); |
diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 9a074776f70b..d1fcf2442a42 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h | |||
| @@ -251,7 +251,7 @@ extern struct flow_dissector flow_keys_buf_dissector; | |||
| 251 | * This structure is used to hold a digest of the full flow keys. This is a | 251 | * This structure is used to hold a digest of the full flow keys. This is a |
| 252 | * larger "hash" of a flow to allow definitively matching specific flows where | 252 | * larger "hash" of a flow to allow definitively matching specific flows where |
| 253 | * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so | 253 | * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so |
| 254 | * that it can by used in CB of skb (see sch_choke for an example). | 254 | * that it can be used in CB of skb (see sch_choke for an example). |
| 255 | */ | 255 | */ |
| 256 | #define FLOW_KEYS_DIGEST_LEN 16 | 256 | #define FLOW_KEYS_DIGEST_LEN 16 |
| 257 | struct flow_keys_digest { | 257 | struct flow_keys_digest { |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d2279b2d61aa..b2f3a0c018e7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -2080,7 +2080,7 @@ struct ieee80211_txq { | |||
| 2080 | * virtual interface might not be given air time for the transmission of | 2080 | * virtual interface might not be given air time for the transmission of |
| 2081 | * the frame, as it is not synced with the AP/P2P GO yet, and thus the | 2081 | * the frame, as it is not synced with the AP/P2P GO yet, and thus the |
| 2082 | * deauthentication frame might not be transmitted. | 2082 | * deauthentication frame might not be transmitted. |
| 2083 | > | 2083 | * |
| 2084 | * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't | 2084 | * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't |
| 2085 | * support QoS NDP for AP probing - that's most likely a driver bug. | 2085 | * support QoS NDP for AP probing - that's most likely a driver bug. |
| 2086 | * | 2086 | * |
diff --git a/include/net/tls.h b/include/net/tls.h index 3da8e13a6d96..b400d0bb7448 100644 --- a/include/net/tls.h +++ b/include/net/tls.h | |||
| @@ -148,6 +148,7 @@ struct tls_context { | |||
| 148 | struct scatterlist *partially_sent_record; | 148 | struct scatterlist *partially_sent_record; |
| 149 | u16 partially_sent_offset; | 149 | u16 partially_sent_offset; |
| 150 | unsigned long flags; | 150 | unsigned long flags; |
| 151 | bool in_tcp_sendpages; | ||
| 151 | 152 | ||
| 152 | u16 pending_open_record_frags; | 153 | u16 pending_open_record_frags; |
| 153 | int (*push_pending_record)(struct sock *sk, int flags); | 154 | int (*push_pending_record)(struct sock *sk, int flags); |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index a872379b69da..45e75c36b738 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -375,6 +375,7 @@ struct xfrm_input_afinfo { | |||
| 375 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo); | 375 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo); |
| 376 | int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo); | 376 | int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo); |
| 377 | 377 | ||
| 378 | void xfrm_flush_gc(void); | ||
| 378 | void xfrm_state_delete_tunnel(struct xfrm_state *x); | 379 | void xfrm_state_delete_tunnel(struct xfrm_state *x); |
| 379 | 380 | ||
| 380 | struct xfrm_type { | 381 | struct xfrm_type { |
diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h index f0820554caa9..d0a341bc4540 100644 --- a/include/trace/events/afs.h +++ b/include/trace/events/afs.h | |||
| @@ -575,6 +575,48 @@ TRACE_EVENT(afs_protocol_error, | |||
| 575 | __entry->call, __entry->error, __entry->where) | 575 | __entry->call, __entry->error, __entry->where) |
| 576 | ); | 576 | ); |
| 577 | 577 | ||
| 578 | TRACE_EVENT(afs_cm_no_server, | ||
| 579 | TP_PROTO(struct afs_call *call, struct sockaddr_rxrpc *srx), | ||
| 580 | |||
| 581 | TP_ARGS(call, srx), | ||
| 582 | |||
| 583 | TP_STRUCT__entry( | ||
| 584 | __field(unsigned int, call ) | ||
| 585 | __field(unsigned int, op_id ) | ||
| 586 | __field_struct(struct sockaddr_rxrpc, srx ) | ||
| 587 | ), | ||
| 588 | |||
| 589 | TP_fast_assign( | ||
| 590 | __entry->call = call->debug_id; | ||
| 591 | __entry->op_id = call->operation_ID; | ||
| 592 | memcpy(&__entry->srx, srx, sizeof(__entry->srx)); | ||
| 593 | ), | ||
| 594 | |||
| 595 | TP_printk("c=%08x op=%u %pISpc", | ||
| 596 | __entry->call, __entry->op_id, &__entry->srx.transport) | ||
| 597 | ); | ||
| 598 | |||
| 599 | TRACE_EVENT(afs_cm_no_server_u, | ||
| 600 | TP_PROTO(struct afs_call *call, const uuid_t *uuid), | ||
| 601 | |||
| 602 | TP_ARGS(call, uuid), | ||
| 603 | |||
| 604 | TP_STRUCT__entry( | ||
| 605 | __field(unsigned int, call ) | ||
| 606 | __field(unsigned int, op_id ) | ||
| 607 | __field_struct(uuid_t, uuid ) | ||
| 608 | ), | ||
| 609 | |||
| 610 | TP_fast_assign( | ||
| 611 | __entry->call = call->debug_id; | ||
| 612 | __entry->op_id = call->operation_ID; | ||
| 613 | memcpy(&__entry->uuid, uuid, sizeof(__entry->uuid)); | ||
| 614 | ), | ||
| 615 | |||
| 616 | TP_printk("c=%08x op=%u %pU", | ||
| 617 | __entry->call, __entry->op_id, &__entry->uuid) | ||
| 618 | ); | ||
| 619 | |||
| 578 | #endif /* _TRACE_AFS_H */ | 620 | #endif /* _TRACE_AFS_H */ |
| 579 | 621 | ||
| 580 | /* This part must be outside protection */ | 622 | /* This part must be outside protection */ |
diff --git a/include/trace/events/initcall.h b/include/trace/events/initcall.h index 8d6cf10d27c9..eb903c3f195f 100644 --- a/include/trace/events/initcall.h +++ b/include/trace/events/initcall.h | |||
| @@ -31,7 +31,11 @@ TRACE_EVENT(initcall_start, | |||
| 31 | TP_ARGS(func), | 31 | TP_ARGS(func), |
| 32 | 32 | ||
| 33 | TP_STRUCT__entry( | 33 | TP_STRUCT__entry( |
| 34 | __field(initcall_t, func) | 34 | /* |
| 35 | * Use field_struct to avoid is_signed_type() | ||
| 36 | * comparison of a function pointer | ||
| 37 | */ | ||
| 38 | __field_struct(initcall_t, func) | ||
| 35 | ), | 39 | ), |
| 36 | 40 | ||
| 37 | TP_fast_assign( | 41 | TP_fast_assign( |
| @@ -48,8 +52,12 @@ TRACE_EVENT(initcall_finish, | |||
| 48 | TP_ARGS(func, ret), | 52 | TP_ARGS(func, ret), |
| 49 | 53 | ||
| 50 | TP_STRUCT__entry( | 54 | TP_STRUCT__entry( |
| 51 | __field(initcall_t, func) | 55 | /* |
| 52 | __field(int, ret) | 56 | * Use field_struct to avoid is_signed_type() |
| 57 | * comparison of a function pointer | ||
| 58 | */ | ||
| 59 | __field_struct(initcall_t, func) | ||
| 60 | __field(int, ret) | ||
| 53 | ), | 61 | ), |
| 54 | 62 | ||
| 55 | TP_fast_assign( | 63 | TP_fast_assign( |
diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 9e96c2fe2793..077e664ac9a2 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #define _TRACE_RXRPC_H | 15 | #define _TRACE_RXRPC_H |
| 16 | 16 | ||
| 17 | #include <linux/tracepoint.h> | 17 | #include <linux/tracepoint.h> |
| 18 | #include <linux/errqueue.h> | ||
| 18 | 19 | ||
| 19 | /* | 20 | /* |
| 20 | * Define enums for tracing information. | 21 | * Define enums for tracing information. |
| @@ -210,6 +211,20 @@ enum rxrpc_congest_change { | |||
| 210 | rxrpc_cong_saw_nack, | 211 | rxrpc_cong_saw_nack, |
| 211 | }; | 212 | }; |
| 212 | 213 | ||
| 214 | enum rxrpc_tx_fail_trace { | ||
| 215 | rxrpc_tx_fail_call_abort, | ||
| 216 | rxrpc_tx_fail_call_ack, | ||
| 217 | rxrpc_tx_fail_call_data_frag, | ||
| 218 | rxrpc_tx_fail_call_data_nofrag, | ||
| 219 | rxrpc_tx_fail_call_final_resend, | ||
| 220 | rxrpc_tx_fail_conn_abort, | ||
| 221 | rxrpc_tx_fail_conn_challenge, | ||
| 222 | rxrpc_tx_fail_conn_response, | ||
| 223 | rxrpc_tx_fail_reject, | ||
| 224 | rxrpc_tx_fail_version_keepalive, | ||
| 225 | rxrpc_tx_fail_version_reply, | ||
| 226 | }; | ||
| 227 | |||
| 213 | #endif /* end __RXRPC_DECLARE_TRACE_ENUMS_ONCE_ONLY */ | 228 | #endif /* end __RXRPC_DECLARE_TRACE_ENUMS_ONCE_ONLY */ |
| 214 | 229 | ||
| 215 | /* | 230 | /* |
| @@ -437,6 +452,19 @@ enum rxrpc_congest_change { | |||
| 437 | EM(RXRPC_CALL_LOCAL_ERROR, "LocalError") \ | 452 | EM(RXRPC_CALL_LOCAL_ERROR, "LocalError") \ |
| 438 | E_(RXRPC_CALL_NETWORK_ERROR, "NetError") | 453 | E_(RXRPC_CALL_NETWORK_ERROR, "NetError") |
| 439 | 454 | ||
| 455 | #define rxrpc_tx_fail_traces \ | ||
| 456 | EM(rxrpc_tx_fail_call_abort, "CallAbort") \ | ||
| 457 | EM(rxrpc_tx_fail_call_ack, "CallAck") \ | ||
| 458 | EM(rxrpc_tx_fail_call_data_frag, "CallDataFrag") \ | ||
| 459 | EM(rxrpc_tx_fail_call_data_nofrag, "CallDataNofrag") \ | ||
| 460 | EM(rxrpc_tx_fail_call_final_resend, "CallFinalResend") \ | ||
| 461 | EM(rxrpc_tx_fail_conn_abort, "ConnAbort") \ | ||
| 462 | EM(rxrpc_tx_fail_conn_challenge, "ConnChall") \ | ||
| 463 | EM(rxrpc_tx_fail_conn_response, "ConnResp") \ | ||
| 464 | EM(rxrpc_tx_fail_reject, "Reject") \ | ||
| 465 | EM(rxrpc_tx_fail_version_keepalive, "VerKeepalive") \ | ||
| 466 | E_(rxrpc_tx_fail_version_reply, "VerReply") | ||
| 467 | |||
| 440 | /* | 468 | /* |
| 441 | * Export enum symbols via userspace. | 469 | * Export enum symbols via userspace. |
| 442 | */ | 470 | */ |
| @@ -460,6 +488,7 @@ rxrpc_propose_ack_traces; | |||
| 460 | rxrpc_propose_ack_outcomes; | 488 | rxrpc_propose_ack_outcomes; |
| 461 | rxrpc_congest_modes; | 489 | rxrpc_congest_modes; |
| 462 | rxrpc_congest_changes; | 490 | rxrpc_congest_changes; |
| 491 | rxrpc_tx_fail_traces; | ||
| 463 | 492 | ||
| 464 | /* | 493 | /* |
| 465 | * Now redefine the EM() and E_() macros to map the enums to the strings that | 494 | * Now redefine the EM() and E_() macros to map the enums to the strings that |
| @@ -1374,6 +1403,62 @@ TRACE_EVENT(rxrpc_resend, | |||
| 1374 | __entry->anno) | 1403 | __entry->anno) |
| 1375 | ); | 1404 | ); |
| 1376 | 1405 | ||
| 1406 | TRACE_EVENT(rxrpc_rx_icmp, | ||
| 1407 | TP_PROTO(struct rxrpc_peer *peer, struct sock_extended_err *ee, | ||
| 1408 | struct sockaddr_rxrpc *srx), | ||
| 1409 | |||
| 1410 | TP_ARGS(peer, ee, srx), | ||
| 1411 | |||
| 1412 | TP_STRUCT__entry( | ||
| 1413 | __field(unsigned int, peer ) | ||
| 1414 | __field_struct(struct sock_extended_err, ee ) | ||
| 1415 | __field_struct(struct sockaddr_rxrpc, srx ) | ||
| 1416 | ), | ||
| 1417 | |||
| 1418 | TP_fast_assign( | ||
| 1419 | __entry->peer = peer->debug_id; | ||
| 1420 | memcpy(&__entry->ee, ee, sizeof(__entry->ee)); | ||
| 1421 | memcpy(&__entry->srx, srx, sizeof(__entry->srx)); | ||
| 1422 | ), | ||
| 1423 | |||
| 1424 | TP_printk("P=%08x o=%u t=%u c=%u i=%u d=%u e=%d %pISp", | ||
| 1425 | __entry->peer, | ||
| 1426 | __entry->ee.ee_origin, | ||
| 1427 | __entry->ee.ee_type, | ||
| 1428 | __entry->ee.ee_code, | ||
| 1429 | __entry->ee.ee_info, | ||
| 1430 | __entry->ee.ee_data, | ||
| 1431 | __entry->ee.ee_errno, | ||
| 1432 | &__entry->srx.transport) | ||
| 1433 | ); | ||
| 1434 | |||
| 1435 | TRACE_EVENT(rxrpc_tx_fail, | ||
| 1436 | TP_PROTO(unsigned int debug_id, rxrpc_serial_t serial, int ret, | ||
| 1437 | enum rxrpc_tx_fail_trace what), | ||
| 1438 | |||
| 1439 | TP_ARGS(debug_id, serial, ret, what), | ||
| 1440 | |||
| 1441 | TP_STRUCT__entry( | ||
| 1442 | __field(unsigned int, debug_id ) | ||
| 1443 | __field(rxrpc_serial_t, serial ) | ||
| 1444 | __field(int, ret ) | ||
| 1445 | __field(enum rxrpc_tx_fail_trace, what ) | ||
| 1446 | ), | ||
| 1447 | |||
| 1448 | TP_fast_assign( | ||
| 1449 | __entry->debug_id = debug_id; | ||
| 1450 | __entry->serial = serial; | ||
| 1451 | __entry->ret = ret; | ||
| 1452 | __entry->what = what; | ||
| 1453 | ), | ||
| 1454 | |||
| 1455 | TP_printk("c=%08x r=%x ret=%d %s", | ||
| 1456 | __entry->debug_id, | ||
| 1457 | __entry->serial, | ||
| 1458 | __entry->ret, | ||
| 1459 | __print_symbolic(__entry->what, rxrpc_tx_fail_traces)) | ||
| 1460 | ); | ||
| 1461 | |||
| 1377 | #endif /* _TRACE_RXRPC_H */ | 1462 | #endif /* _TRACE_RXRPC_H */ |
| 1378 | 1463 | ||
| 1379 | /* This part must be outside protection */ | 1464 | /* This part must be outside protection */ |
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 335d87242439..bbb08a3ef5cc 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h | |||
| @@ -224,6 +224,8 @@ TRACE_EVENT(rpc_stats_latency, | |||
| 224 | TP_ARGS(task, backlog, rtt, execute), | 224 | TP_ARGS(task, backlog, rtt, execute), |
| 225 | 225 | ||
| 226 | TP_STRUCT__entry( | 226 | TP_STRUCT__entry( |
| 227 | __field(unsigned int, task_id) | ||
| 228 | __field(unsigned int, client_id) | ||
| 227 | __field(u32, xid) | 229 | __field(u32, xid) |
| 228 | __field(int, version) | 230 | __field(int, version) |
| 229 | __string(progname, task->tk_client->cl_program->name) | 231 | __string(progname, task->tk_client->cl_program->name) |
| @@ -231,13 +233,11 @@ TRACE_EVENT(rpc_stats_latency, | |||
| 231 | __field(unsigned long, backlog) | 233 | __field(unsigned long, backlog) |
| 232 | __field(unsigned long, rtt) | 234 | __field(unsigned long, rtt) |
| 233 | __field(unsigned long, execute) | 235 | __field(unsigned long, execute) |
| 234 | __string(addr, | ||
| 235 | task->tk_xprt->address_strings[RPC_DISPLAY_ADDR]) | ||
| 236 | __string(port, | ||
| 237 | task->tk_xprt->address_strings[RPC_DISPLAY_PORT]) | ||
| 238 | ), | 236 | ), |
| 239 | 237 | ||
| 240 | TP_fast_assign( | 238 | TP_fast_assign( |
| 239 | __entry->client_id = task->tk_client->cl_clid; | ||
| 240 | __entry->task_id = task->tk_pid; | ||
| 241 | __entry->xid = be32_to_cpu(task->tk_rqstp->rq_xid); | 241 | __entry->xid = be32_to_cpu(task->tk_rqstp->rq_xid); |
| 242 | __entry->version = task->tk_client->cl_vers; | 242 | __entry->version = task->tk_client->cl_vers; |
| 243 | __assign_str(progname, task->tk_client->cl_program->name) | 243 | __assign_str(progname, task->tk_client->cl_program->name) |
| @@ -245,14 +245,10 @@ TRACE_EVENT(rpc_stats_latency, | |||
| 245 | __entry->backlog = ktime_to_us(backlog); | 245 | __entry->backlog = ktime_to_us(backlog); |
| 246 | __entry->rtt = ktime_to_us(rtt); | 246 | __entry->rtt = ktime_to_us(rtt); |
| 247 | __entry->execute = ktime_to_us(execute); | 247 | __entry->execute = ktime_to_us(execute); |
| 248 | __assign_str(addr, | ||
| 249 | task->tk_xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
| 250 | __assign_str(port, | ||
| 251 | task->tk_xprt->address_strings[RPC_DISPLAY_PORT]); | ||
| 252 | ), | 248 | ), |
| 253 | 249 | ||
| 254 | TP_printk("peer=[%s]:%s xid=0x%08x %sv%d %s backlog=%lu rtt=%lu execute=%lu", | 250 | TP_printk("task:%u@%d xid=0x%08x %sv%d %s backlog=%lu rtt=%lu execute=%lu", |
| 255 | __get_str(addr), __get_str(port), __entry->xid, | 251 | __entry->task_id, __entry->client_id, __entry->xid, |
| 256 | __get_str(progname), __entry->version, __get_str(procname), | 252 | __get_str(progname), __entry->version, __get_str(procname), |
| 257 | __entry->backlog, __entry->rtt, __entry->execute) | 253 | __entry->backlog, __entry->rtt, __entry->execute) |
| 258 | ); | 254 | ); |
diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h index 7dd8f34c37df..fdcf88bcf0ea 100644 --- a/include/trace/events/xen.h +++ b/include/trace/events/xen.h | |||
| @@ -352,22 +352,6 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd, | |||
| 352 | DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); | 352 | DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); |
| 353 | DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); | 353 | DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); |
| 354 | 354 | ||
| 355 | TRACE_EVENT(xen_mmu_flush_tlb_all, | ||
| 356 | TP_PROTO(int x), | ||
| 357 | TP_ARGS(x), | ||
| 358 | TP_STRUCT__entry(__array(char, x, 0)), | ||
| 359 | TP_fast_assign((void)x), | ||
| 360 | TP_printk("%s", "") | ||
| 361 | ); | ||
| 362 | |||
| 363 | TRACE_EVENT(xen_mmu_flush_tlb, | ||
| 364 | TP_PROTO(int x), | ||
| 365 | TP_ARGS(x), | ||
| 366 | TP_STRUCT__entry(__array(char, x, 0)), | ||
| 367 | TP_fast_assign((void)x), | ||
| 368 | TP_printk("%s", "") | ||
| 369 | ); | ||
| 370 | |||
| 371 | TRACE_EVENT(xen_mmu_flush_tlb_one_user, | 355 | TRACE_EVENT(xen_mmu_flush_tlb_one_user, |
| 372 | TP_PROTO(unsigned long addr), | 356 | TP_PROTO(unsigned long addr), |
| 373 | TP_ARGS(addr), | 357 | TP_ARGS(addr), |
diff --git a/include/uapi/linux/if_infiniband.h b/include/uapi/linux/if_infiniband.h index 050b92dcf8cf..0fc33bf30e45 100644 --- a/include/uapi/linux/if_infiniband.h +++ b/include/uapi/linux/if_infiniband.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ |
| 2 | /* | 2 | /* |
| 3 | * This software is available to you under a choice of one of two | 3 | * This software is available to you under a choice of one of two |
| 4 | * licenses. You may choose to be licensed under the terms of the GNU | 4 | * licenses. You may choose to be licensed under the terms of the GNU |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 15daf5e2638d..9c3630146cec 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
| @@ -2698,6 +2698,8 @@ enum nl80211_attrs { | |||
| 2698 | #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS | 2698 | #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS |
| 2699 | #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS | 2699 | #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS |
| 2700 | 2700 | ||
| 2701 | #define NL80211_WIPHY_NAME_MAXLEN 128 | ||
| 2702 | |||
| 2701 | #define NL80211_MAX_SUPP_RATES 32 | 2703 | #define NL80211_MAX_SUPP_RATES 32 |
| 2702 | #define NL80211_MAX_SUPP_HT_RATES 77 | 2704 | #define NL80211_MAX_SUPP_HT_RATES 77 |
| 2703 | #define NL80211_MAX_SUPP_REG_RULES 64 | 2705 | #define NL80211_MAX_SUPP_REG_RULES 64 |
diff --git a/include/uapi/linux/rds.h b/include/uapi/linux/rds.h index a66b213de3d7..20c6bd0b0007 100644 --- a/include/uapi/linux/rds.h +++ b/include/uapi/linux/rds.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2008 Oracle. All rights reserved. | 3 | * Copyright (c) 2008 Oracle. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/linux/tls.h b/include/uapi/linux/tls.h index c6633e97eca4..ff02287495ac 100644 --- a/include/uapi/linux/tls.h +++ b/include/uapi/linux/tls.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved. | 3 | * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/cxgb3-abi.h b/include/uapi/rdma/cxgb3-abi.h index 9acb4b7a6246..85aed672f43e 100644 --- a/include/uapi/rdma/cxgb3-abi.h +++ b/include/uapi/rdma/cxgb3-abi.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2006 Chelsio, Inc. All rights reserved. | 3 | * Copyright (c) 2006 Chelsio, Inc. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/cxgb4-abi.h b/include/uapi/rdma/cxgb4-abi.h index 1fefd0140c26..a159ba8dcf8f 100644 --- a/include/uapi/rdma/cxgb4-abi.h +++ b/include/uapi/rdma/cxgb4-abi.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2009-2010 Chelsio, Inc. All rights reserved. | 3 | * Copyright (c) 2009-2010 Chelsio, Inc. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/hns-abi.h b/include/uapi/rdma/hns-abi.h index 7092c8de4bd8..78613b609fa8 100644 --- a/include/uapi/rdma/hns-abi.h +++ b/include/uapi/rdma/hns-abi.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016 Hisilicon Limited. | 3 | * Copyright (c) 2016 Hisilicon Limited. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/ib_user_cm.h b/include/uapi/rdma/ib_user_cm.h index 4a8f9562f7cd..e2709bb8cb18 100644 --- a/include/uapi/rdma/ib_user_cm.h +++ b/include/uapi/rdma/ib_user_cm.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 3 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
| 4 | * Copyright (c) 2005 Intel Corporation. All rights reserved. | 4 | * Copyright (c) 2005 Intel Corporation. All rights reserved. |
diff --git a/include/uapi/rdma/ib_user_ioctl_verbs.h b/include/uapi/rdma/ib_user_ioctl_verbs.h index 04e46ea517d3..625545d862d7 100644 --- a/include/uapi/rdma/ib_user_ioctl_verbs.h +++ b/include/uapi/rdma/ib_user_ioctl_verbs.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2017-2018, Mellanox Technologies inc. All rights reserved. | 3 | * Copyright (c) 2017-2018, Mellanox Technologies inc. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/ib_user_mad.h b/include/uapi/rdma/ib_user_mad.h index ef92118dad97..90c0cf228020 100644 --- a/include/uapi/rdma/ib_user_mad.h +++ b/include/uapi/rdma/ib_user_mad.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2004 Topspin Communications. All rights reserved. | 3 | * Copyright (c) 2004 Topspin Communications. All rights reserved. |
| 4 | * Copyright (c) 2005 Voltaire, Inc. All rights reserved. | 4 | * Copyright (c) 2005 Voltaire, Inc. All rights reserved. |
diff --git a/include/uapi/rdma/ib_user_sa.h b/include/uapi/rdma/ib_user_sa.h index 0d2607f0cd20..435155d6e1c6 100644 --- a/include/uapi/rdma/ib_user_sa.h +++ b/include/uapi/rdma/ib_user_sa.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2005 Intel Corporation. All rights reserved. | 3 | * Copyright (c) 2005 Intel Corporation. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h index 9be07394fdbe..6aeb03315b0b 100644 --- a/include/uapi/rdma/ib_user_verbs.h +++ b/include/uapi/rdma/ib_user_verbs.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 3 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
| 4 | * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. | 4 | * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. |
diff --git a/include/uapi/rdma/mlx4-abi.h b/include/uapi/rdma/mlx4-abi.h index 04f64bc4045f..f74557528175 100644 --- a/include/uapi/rdma/mlx4-abi.h +++ b/include/uapi/rdma/mlx4-abi.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. | 3 | * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. |
| 4 | * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. | 4 | * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. |
diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h index cb4a02c4a1ce..fdaf00e20649 100644 --- a/include/uapi/rdma/mlx5-abi.h +++ b/include/uapi/rdma/mlx5-abi.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. | 3 | * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/mthca-abi.h b/include/uapi/rdma/mthca-abi.h index ac756cd9e807..91b12e1a6f43 100644 --- a/include/uapi/rdma/mthca-abi.h +++ b/include/uapi/rdma/mthca-abi.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 3 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
| 4 | * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. | 4 | * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. |
diff --git a/include/uapi/rdma/nes-abi.h b/include/uapi/rdma/nes-abi.h index 35bfd4015d07..f80495baa969 100644 --- a/include/uapi/rdma/nes-abi.h +++ b/include/uapi/rdma/nes-abi.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. | 3 | * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. |
| 4 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 4 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
diff --git a/include/uapi/rdma/qedr-abi.h b/include/uapi/rdma/qedr-abi.h index 8ba098900e9a..24c658b3c790 100644 --- a/include/uapi/rdma/qedr-abi.h +++ b/include/uapi/rdma/qedr-abi.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* QLogic qedr NIC Driver | 2 | /* QLogic qedr NIC Driver |
| 3 | * Copyright (c) 2015-2016 QLogic Corporation | 3 | * Copyright (c) 2015-2016 QLogic Corporation |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/rdma_user_cm.h b/include/uapi/rdma/rdma_user_cm.h index e1269024af47..0d1e78ebad05 100644 --- a/include/uapi/rdma/rdma_user_cm.h +++ b/include/uapi/rdma/rdma_user_cm.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2005-2006 Intel Corporation. All rights reserved. | 3 | * Copyright (c) 2005-2006 Intel Corporation. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/rdma_user_ioctl.h b/include/uapi/rdma/rdma_user_ioctl.h index d223f4164a0f..d92d2721b28c 100644 --- a/include/uapi/rdma/rdma_user_ioctl.h +++ b/include/uapi/rdma/rdma_user_ioctl.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016 Mellanox Technologies, LTD. All rights reserved. | 3 | * Copyright (c) 2016 Mellanox Technologies, LTD. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/include/uapi/rdma/rdma_user_rxe.h b/include/uapi/rdma/rdma_user_rxe.h index 1f8a9e7daea4..44ef6a3b7afc 100644 --- a/include/uapi/rdma/rdma_user_rxe.h +++ b/include/uapi/rdma/rdma_user_rxe.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved. | 3 | * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved. |
| 4 | * | 4 | * |
diff --git a/init/Kconfig b/init/Kconfig index f013afc74b11..18b151f0ddc1 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
| @@ -738,7 +738,7 @@ config CFS_BANDWIDTH | |||
| 738 | tasks running within the fair group scheduler. Groups with no limit | 738 | tasks running within the fair group scheduler. Groups with no limit |
| 739 | set are considered to be unconstrained and will run with no | 739 | set are considered to be unconstrained and will run with no |
| 740 | restriction. | 740 | restriction. |
| 741 | See tip/Documentation/scheduler/sched-bwc.txt for more information. | 741 | See Documentation/scheduler/sched-bwc.txt for more information. |
| 742 | 742 | ||
| 743 | config RT_GROUP_SCHED | 743 | config RT_GROUP_SCHED |
| 744 | bool "Group scheduling for SCHED_RR/FIFO" | 744 | bool "Group scheduling for SCHED_RR/FIFO" |
diff --git a/init/main.c b/init/main.c index b795aa341a3a..fd37315835b4 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -423,7 +423,7 @@ static noinline void __ref rest_init(void) | |||
| 423 | 423 | ||
| 424 | /* | 424 | /* |
| 425 | * Enable might_sleep() and smp_processor_id() checks. | 425 | * Enable might_sleep() and smp_processor_id() checks. |
| 426 | * They cannot be enabled earlier because with CONFIG_PRREMPT=y | 426 | * They cannot be enabled earlier because with CONFIG_PREEMPT=y |
| 427 | * kernel_thread() would trigger might_sleep() splats. With | 427 | * kernel_thread() would trigger might_sleep() splats. With |
| 428 | * CONFIG_PREEMPT_VOLUNTARY=y the init task might have scheduled | 428 | * CONFIG_PREEMPT_VOLUNTARY=y the init task might have scheduled |
| 429 | * already, but it's stuck on the kthreadd_done completion. | 429 | * already, but it's stuck on the kthreadd_done completion. |
| @@ -1034,6 +1034,13 @@ __setup("rodata=", set_debug_rodata); | |||
| 1034 | static void mark_readonly(void) | 1034 | static void mark_readonly(void) |
| 1035 | { | 1035 | { |
| 1036 | if (rodata_enabled) { | 1036 | if (rodata_enabled) { |
| 1037 | /* | ||
| 1038 | * load_module() results in W+X mappings, which are cleaned up | ||
| 1039 | * with call_rcu_sched(). Let's make sure that queued work is | ||
| 1040 | * flushed so that we don't hit false positives looking for | ||
| 1041 | * insecure pages which are W+X. | ||
| 1042 | */ | ||
| 1043 | rcu_barrier_sched(); | ||
| 1037 | mark_rodata_ro(); | 1044 | mark_rodata_ro(); |
| 1038 | rodata_test(); | 1045 | rodata_test(); |
| 1039 | } else | 1046 | } else |
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 14750e7c5ee4..027107f4be53 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c | |||
| @@ -476,7 +476,7 @@ static u32 prog_fd_array_sys_lookup_elem(void *ptr) | |||
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | /* decrement refcnt of all bpf_progs that are stored in this map */ | 478 | /* decrement refcnt of all bpf_progs that are stored in this map */ |
| 479 | void bpf_fd_array_map_clear(struct bpf_map *map) | 479 | static void bpf_fd_array_map_clear(struct bpf_map *map) |
| 480 | { | 480 | { |
| 481 | struct bpf_array *array = container_of(map, struct bpf_array, map); | 481 | struct bpf_array *array = container_of(map, struct bpf_array, map); |
| 482 | int i; | 482 | int i; |
| @@ -495,6 +495,7 @@ const struct bpf_map_ops prog_array_map_ops = { | |||
| 495 | .map_fd_get_ptr = prog_fd_array_get_ptr, | 495 | .map_fd_get_ptr = prog_fd_array_get_ptr, |
| 496 | .map_fd_put_ptr = prog_fd_array_put_ptr, | 496 | .map_fd_put_ptr = prog_fd_array_put_ptr, |
| 497 | .map_fd_sys_lookup_elem = prog_fd_array_sys_lookup_elem, | 497 | .map_fd_sys_lookup_elem = prog_fd_array_sys_lookup_elem, |
| 498 | .map_release_uref = bpf_fd_array_map_clear, | ||
| 498 | }; | 499 | }; |
| 499 | 500 | ||
| 500 | static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file, | 501 | static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file, |
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c index a3b21385e947..098eca568c2b 100644 --- a/kernel/bpf/sockmap.c +++ b/kernel/bpf/sockmap.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <net/tcp.h> | 43 | #include <net/tcp.h> |
| 44 | #include <linux/ptr_ring.h> | 44 | #include <linux/ptr_ring.h> |
| 45 | #include <net/inet_common.h> | 45 | #include <net/inet_common.h> |
| 46 | #include <linux/sched/signal.h> | ||
| 46 | 47 | ||
| 47 | #define SOCK_CREATE_FLAG_MASK \ | 48 | #define SOCK_CREATE_FLAG_MASK \ |
| 48 | (BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY) | 49 | (BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY) |
| @@ -325,6 +326,9 @@ retry: | |||
| 325 | if (ret > 0) { | 326 | if (ret > 0) { |
| 326 | if (apply) | 327 | if (apply) |
| 327 | apply_bytes -= ret; | 328 | apply_bytes -= ret; |
| 329 | |||
| 330 | sg->offset += ret; | ||
| 331 | sg->length -= ret; | ||
| 328 | size -= ret; | 332 | size -= ret; |
| 329 | offset += ret; | 333 | offset += ret; |
| 330 | if (uncharge) | 334 | if (uncharge) |
| @@ -332,8 +336,6 @@ retry: | |||
| 332 | goto retry; | 336 | goto retry; |
| 333 | } | 337 | } |
| 334 | 338 | ||
| 335 | sg->length = size; | ||
| 336 | sg->offset = offset; | ||
| 337 | return ret; | 339 | return ret; |
| 338 | } | 340 | } |
| 339 | 341 | ||
| @@ -391,7 +393,8 @@ static void return_mem_sg(struct sock *sk, int bytes, struct sk_msg_buff *md) | |||
| 391 | } while (i != md->sg_end); | 393 | } while (i != md->sg_end); |
| 392 | } | 394 | } |
| 393 | 395 | ||
| 394 | static void free_bytes_sg(struct sock *sk, int bytes, struct sk_msg_buff *md) | 396 | static void free_bytes_sg(struct sock *sk, int bytes, |
| 397 | struct sk_msg_buff *md, bool charge) | ||
| 395 | { | 398 | { |
| 396 | struct scatterlist *sg = md->sg_data; | 399 | struct scatterlist *sg = md->sg_data; |
| 397 | int i = md->sg_start, free; | 400 | int i = md->sg_start, free; |
| @@ -401,11 +404,13 @@ static void free_bytes_sg(struct sock *sk, int bytes, struct sk_msg_buff *md) | |||
| 401 | if (bytes < free) { | 404 | if (bytes < free) { |
| 402 | sg[i].length -= bytes; | 405 | sg[i].length -= bytes; |
| 403 | sg[i].offset += bytes; | 406 | sg[i].offset += bytes; |
| 404 | sk_mem_uncharge(sk, bytes); | 407 | if (charge) |
| 408 | sk_mem_uncharge(sk, bytes); | ||
| 405 | break; | 409 | break; |
| 406 | } | 410 | } |
| 407 | 411 | ||
| 408 | sk_mem_uncharge(sk, sg[i].length); | 412 | if (charge) |
| 413 | sk_mem_uncharge(sk, sg[i].length); | ||
| 409 | put_page(sg_page(&sg[i])); | 414 | put_page(sg_page(&sg[i])); |
| 410 | bytes -= sg[i].length; | 415 | bytes -= sg[i].length; |
| 411 | sg[i].length = 0; | 416 | sg[i].length = 0; |
| @@ -416,6 +421,7 @@ static void free_bytes_sg(struct sock *sk, int bytes, struct sk_msg_buff *md) | |||
| 416 | if (i == MAX_SKB_FRAGS) | 421 | if (i == MAX_SKB_FRAGS) |
| 417 | i = 0; | 422 | i = 0; |
| 418 | } | 423 | } |
| 424 | md->sg_start = i; | ||
| 419 | } | 425 | } |
| 420 | 426 | ||
| 421 | static int free_sg(struct sock *sk, int start, struct sk_msg_buff *md) | 427 | static int free_sg(struct sock *sk, int start, struct sk_msg_buff *md) |
| @@ -523,8 +529,6 @@ static int bpf_tcp_ingress(struct sock *sk, int apply_bytes, | |||
| 523 | i = md->sg_start; | 529 | i = md->sg_start; |
| 524 | 530 | ||
| 525 | do { | 531 | do { |
| 526 | r->sg_data[i] = md->sg_data[i]; | ||
| 527 | |||
| 528 | size = (apply && apply_bytes < md->sg_data[i].length) ? | 532 | size = (apply && apply_bytes < md->sg_data[i].length) ? |
| 529 | apply_bytes : md->sg_data[i].length; | 533 | apply_bytes : md->sg_data[i].length; |
| 530 | 534 | ||
| @@ -535,6 +539,7 @@ static int bpf_tcp_ingress(struct sock *sk, int apply_bytes, | |||
| 535 | } | 539 | } |
| 536 | 540 | ||
| 537 | sk_mem_charge(sk, size); | 541 | sk_mem_charge(sk, size); |
| 542 | r->sg_data[i] = md->sg_data[i]; | ||
| 538 | r->sg_data[i].length = size; | 543 | r->sg_data[i].length = size; |
| 539 | md->sg_data[i].length -= size; | 544 | md->sg_data[i].length -= size; |
| 540 | md->sg_data[i].offset += size; | 545 | md->sg_data[i].offset += size; |
| @@ -575,10 +580,10 @@ static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send, | |||
| 575 | struct sk_msg_buff *md, | 580 | struct sk_msg_buff *md, |
| 576 | int flags) | 581 | int flags) |
| 577 | { | 582 | { |
| 583 | bool ingress = !!(md->flags & BPF_F_INGRESS); | ||
| 578 | struct smap_psock *psock; | 584 | struct smap_psock *psock; |
| 579 | struct scatterlist *sg; | 585 | struct scatterlist *sg; |
| 580 | int i, err, free = 0; | 586 | int err = 0; |
| 581 | bool ingress = !!(md->flags & BPF_F_INGRESS); | ||
| 582 | 587 | ||
| 583 | sg = md->sg_data; | 588 | sg = md->sg_data; |
| 584 | 589 | ||
| @@ -606,16 +611,8 @@ static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send, | |||
| 606 | out_rcu: | 611 | out_rcu: |
| 607 | rcu_read_unlock(); | 612 | rcu_read_unlock(); |
| 608 | out: | 613 | out: |
| 609 | i = md->sg_start; | 614 | free_bytes_sg(NULL, send, md, false); |
| 610 | while (sg[i].length) { | 615 | return err; |
| 611 | free += sg[i].length; | ||
| 612 | put_page(sg_page(&sg[i])); | ||
| 613 | sg[i].length = 0; | ||
| 614 | i++; | ||
| 615 | if (i == MAX_SKB_FRAGS) | ||
| 616 | i = 0; | ||
| 617 | } | ||
| 618 | return free; | ||
| 619 | } | 616 | } |
| 620 | 617 | ||
| 621 | static inline void bpf_md_init(struct smap_psock *psock) | 618 | static inline void bpf_md_init(struct smap_psock *psock) |
| @@ -700,19 +697,26 @@ more_data: | |||
| 700 | err = bpf_tcp_sendmsg_do_redirect(redir, send, m, flags); | 697 | err = bpf_tcp_sendmsg_do_redirect(redir, send, m, flags); |
| 701 | lock_sock(sk); | 698 | lock_sock(sk); |
| 702 | 699 | ||
| 700 | if (unlikely(err < 0)) { | ||
| 701 | free_start_sg(sk, m); | ||
| 702 | psock->sg_size = 0; | ||
| 703 | if (!cork) | ||
| 704 | *copied -= send; | ||
| 705 | } else { | ||
| 706 | psock->sg_size -= send; | ||
| 707 | } | ||
| 708 | |||
| 703 | if (cork) { | 709 | if (cork) { |
| 704 | free_start_sg(sk, m); | 710 | free_start_sg(sk, m); |
| 711 | psock->sg_size = 0; | ||
| 705 | kfree(m); | 712 | kfree(m); |
| 706 | m = NULL; | 713 | m = NULL; |
| 714 | err = 0; | ||
| 707 | } | 715 | } |
| 708 | if (unlikely(err)) | ||
| 709 | *copied -= err; | ||
| 710 | else | ||
| 711 | psock->sg_size -= send; | ||
| 712 | break; | 716 | break; |
| 713 | case __SK_DROP: | 717 | case __SK_DROP: |
| 714 | default: | 718 | default: |
| 715 | free_bytes_sg(sk, send, m); | 719 | free_bytes_sg(sk, send, m, true); |
| 716 | apply_bytes_dec(psock, send); | 720 | apply_bytes_dec(psock, send); |
| 717 | *copied -= send; | 721 | *copied -= send; |
| 718 | psock->sg_size -= send; | 722 | psock->sg_size -= send; |
| @@ -732,6 +736,26 @@ out_err: | |||
| 732 | return err; | 736 | return err; |
| 733 | } | 737 | } |
| 734 | 738 | ||
| 739 | static int bpf_wait_data(struct sock *sk, | ||
| 740 | struct smap_psock *psk, int flags, | ||
| 741 | long timeo, int *err) | ||
| 742 | { | ||
| 743 | int rc; | ||
| 744 | |||
| 745 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | ||
| 746 | |||
| 747 | add_wait_queue(sk_sleep(sk), &wait); | ||
| 748 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); | ||
| 749 | rc = sk_wait_event(sk, &timeo, | ||
| 750 | !list_empty(&psk->ingress) || | ||
| 751 | !skb_queue_empty(&sk->sk_receive_queue), | ||
| 752 | &wait); | ||
| 753 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); | ||
| 754 | remove_wait_queue(sk_sleep(sk), &wait); | ||
| 755 | |||
| 756 | return rc; | ||
| 757 | } | ||
| 758 | |||
| 735 | static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, | 759 | static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, |
| 736 | int nonblock, int flags, int *addr_len) | 760 | int nonblock, int flags, int *addr_len) |
| 737 | { | 761 | { |
| @@ -755,6 +779,7 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, | |||
| 755 | return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len); | 779 | return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len); |
| 756 | 780 | ||
| 757 | lock_sock(sk); | 781 | lock_sock(sk); |
| 782 | bytes_ready: | ||
| 758 | while (copied != len) { | 783 | while (copied != len) { |
| 759 | struct scatterlist *sg; | 784 | struct scatterlist *sg; |
| 760 | struct sk_msg_buff *md; | 785 | struct sk_msg_buff *md; |
| @@ -809,6 +834,28 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, | |||
| 809 | } | 834 | } |
| 810 | } | 835 | } |
| 811 | 836 | ||
| 837 | if (!copied) { | ||
| 838 | long timeo; | ||
| 839 | int data; | ||
| 840 | int err = 0; | ||
| 841 | |||
| 842 | timeo = sock_rcvtimeo(sk, nonblock); | ||
| 843 | data = bpf_wait_data(sk, psock, flags, timeo, &err); | ||
| 844 | |||
| 845 | if (data) { | ||
| 846 | if (!skb_queue_empty(&sk->sk_receive_queue)) { | ||
| 847 | release_sock(sk); | ||
| 848 | smap_release_sock(psock, sk); | ||
| 849 | copied = tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len); | ||
| 850 | return copied; | ||
| 851 | } | ||
| 852 | goto bytes_ready; | ||
| 853 | } | ||
| 854 | |||
| 855 | if (err) | ||
| 856 | copied = err; | ||
| 857 | } | ||
| 858 | |||
| 812 | release_sock(sk); | 859 | release_sock(sk); |
| 813 | smap_release_sock(psock, sk); | 860 | smap_release_sock(psock, sk); |
| 814 | return copied; | 861 | return copied; |
| @@ -1831,7 +1878,7 @@ static int sock_map_update_elem(struct bpf_map *map, | |||
| 1831 | return err; | 1878 | return err; |
| 1832 | } | 1879 | } |
| 1833 | 1880 | ||
| 1834 | static void sock_map_release(struct bpf_map *map, struct file *map_file) | 1881 | static void sock_map_release(struct bpf_map *map) |
| 1835 | { | 1882 | { |
| 1836 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); | 1883 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); |
| 1837 | struct bpf_prog *orig; | 1884 | struct bpf_prog *orig; |
| @@ -1855,7 +1902,7 @@ const struct bpf_map_ops sock_map_ops = { | |||
| 1855 | .map_get_next_key = sock_map_get_next_key, | 1902 | .map_get_next_key = sock_map_get_next_key, |
| 1856 | .map_update_elem = sock_map_update_elem, | 1903 | .map_update_elem = sock_map_update_elem, |
| 1857 | .map_delete_elem = sock_map_delete_elem, | 1904 | .map_delete_elem = sock_map_delete_elem, |
| 1858 | .map_release = sock_map_release, | 1905 | .map_release_uref = sock_map_release, |
| 1859 | }; | 1906 | }; |
| 1860 | 1907 | ||
| 1861 | BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock, | 1908 | BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock, |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 4ca46df19c9a..016ef9025827 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/cred.h> | 26 | #include <linux/cred.h> |
| 27 | #include <linux/timekeeping.h> | 27 | #include <linux/timekeeping.h> |
| 28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
| 29 | #include <linux/nospec.h> | ||
| 29 | 30 | ||
| 30 | #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \ | 31 | #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \ |
| 31 | (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \ | 32 | (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \ |
| @@ -102,12 +103,14 @@ const struct bpf_map_ops bpf_map_offload_ops = { | |||
| 102 | static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) | 103 | static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) |
| 103 | { | 104 | { |
| 104 | const struct bpf_map_ops *ops; | 105 | const struct bpf_map_ops *ops; |
| 106 | u32 type = attr->map_type; | ||
| 105 | struct bpf_map *map; | 107 | struct bpf_map *map; |
| 106 | int err; | 108 | int err; |
| 107 | 109 | ||
| 108 | if (attr->map_type >= ARRAY_SIZE(bpf_map_types)) | 110 | if (type >= ARRAY_SIZE(bpf_map_types)) |
| 109 | return ERR_PTR(-EINVAL); | 111 | return ERR_PTR(-EINVAL); |
| 110 | ops = bpf_map_types[attr->map_type]; | 112 | type = array_index_nospec(type, ARRAY_SIZE(bpf_map_types)); |
| 113 | ops = bpf_map_types[type]; | ||
| 111 | if (!ops) | 114 | if (!ops) |
| 112 | return ERR_PTR(-EINVAL); | 115 | return ERR_PTR(-EINVAL); |
| 113 | 116 | ||
| @@ -122,7 +125,7 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) | |||
| 122 | if (IS_ERR(map)) | 125 | if (IS_ERR(map)) |
| 123 | return map; | 126 | return map; |
| 124 | map->ops = ops; | 127 | map->ops = ops; |
| 125 | map->map_type = attr->map_type; | 128 | map->map_type = type; |
| 126 | return map; | 129 | return map; |
| 127 | } | 130 | } |
| 128 | 131 | ||
| @@ -257,8 +260,8 @@ static void bpf_map_free_deferred(struct work_struct *work) | |||
| 257 | static void bpf_map_put_uref(struct bpf_map *map) | 260 | static void bpf_map_put_uref(struct bpf_map *map) |
| 258 | { | 261 | { |
| 259 | if (atomic_dec_and_test(&map->usercnt)) { | 262 | if (atomic_dec_and_test(&map->usercnt)) { |
| 260 | if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY) | 263 | if (map->ops->map_release_uref) |
| 261 | bpf_fd_array_map_clear(map); | 264 | map->ops->map_release_uref(map); |
| 262 | } | 265 | } |
| 263 | } | 266 | } |
| 264 | 267 | ||
| @@ -871,11 +874,17 @@ static const struct bpf_prog_ops * const bpf_prog_types[] = { | |||
| 871 | 874 | ||
| 872 | static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog) | 875 | static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog) |
| 873 | { | 876 | { |
| 874 | if (type >= ARRAY_SIZE(bpf_prog_types) || !bpf_prog_types[type]) | 877 | const struct bpf_prog_ops *ops; |
| 878 | |||
| 879 | if (type >= ARRAY_SIZE(bpf_prog_types)) | ||
| 880 | return -EINVAL; | ||
| 881 | type = array_index_nospec(type, ARRAY_SIZE(bpf_prog_types)); | ||
| 882 | ops = bpf_prog_types[type]; | ||
| 883 | if (!ops) | ||
| 875 | return -EINVAL; | 884 | return -EINVAL; |
| 876 | 885 | ||
| 877 | if (!bpf_prog_is_dev_bound(prog->aux)) | 886 | if (!bpf_prog_is_dev_bound(prog->aux)) |
| 878 | prog->aux->ops = bpf_prog_types[type]; | 887 | prog->aux->ops = ops; |
| 879 | else | 888 | else |
| 880 | prog->aux->ops = &bpf_offload_prog_ops; | 889 | prog->aux->ops = &bpf_offload_prog_ops; |
| 881 | prog->type = type; | 890 | prog->type = type; |
diff --git a/kernel/compat.c b/kernel/compat.c index 6d21894806b4..92d8c98c0f57 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
| @@ -34,6 +34,7 @@ int compat_get_timex(struct timex *txc, const struct compat_timex __user *utp) | |||
| 34 | { | 34 | { |
| 35 | struct compat_timex tx32; | 35 | struct compat_timex tx32; |
| 36 | 36 | ||
| 37 | memset(txc, 0, sizeof(struct timex)); | ||
| 37 | if (copy_from_user(&tx32, utp, sizeof(struct compat_timex))) | 38 | if (copy_from_user(&tx32, utp, sizeof(struct compat_timex))) |
| 38 | return -EFAULT; | 39 | return -EFAULT; |
| 39 | 40 | ||
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 6c6b3c48db71..1d8ca9ea9979 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 15 | #include <linux/circ_buf.h> | 15 | #include <linux/circ_buf.h> |
| 16 | #include <linux/poll.h> | 16 | #include <linux/poll.h> |
| 17 | #include <linux/nospec.h> | ||
| 17 | 18 | ||
| 18 | #include "internal.h" | 19 | #include "internal.h" |
| 19 | 20 | ||
| @@ -867,8 +868,10 @@ perf_mmap_to_page(struct ring_buffer *rb, unsigned long pgoff) | |||
| 867 | return NULL; | 868 | return NULL; |
| 868 | 869 | ||
| 869 | /* AUX space */ | 870 | /* AUX space */ |
| 870 | if (pgoff >= rb->aux_pgoff) | 871 | if (pgoff >= rb->aux_pgoff) { |
| 871 | return virt_to_page(rb->aux_pages[pgoff - rb->aux_pgoff]); | 872 | int aux_pgoff = array_index_nospec(pgoff - rb->aux_pgoff, rb->aux_nr_pages); |
| 873 | return virt_to_page(rb->aux_pages[aux_pgoff]); | ||
| 874 | } | ||
| 872 | } | 875 | } |
| 873 | 876 | ||
| 874 | return __perf_mmap_to_page(rb, pgoff); | 877 | return __perf_mmap_to_page(rb, pgoff); |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index ce6848e46e94..1725b902983f 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
| @@ -491,7 +491,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset) | |||
| 491 | if (!uprobe) | 491 | if (!uprobe) |
| 492 | return NULL; | 492 | return NULL; |
| 493 | 493 | ||
| 494 | uprobe->inode = igrab(inode); | 494 | uprobe->inode = inode; |
| 495 | uprobe->offset = offset; | 495 | uprobe->offset = offset; |
| 496 | init_rwsem(&uprobe->register_rwsem); | 496 | init_rwsem(&uprobe->register_rwsem); |
| 497 | init_rwsem(&uprobe->consumer_rwsem); | 497 | init_rwsem(&uprobe->consumer_rwsem); |
| @@ -502,7 +502,6 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset) | |||
| 502 | if (cur_uprobe) { | 502 | if (cur_uprobe) { |
| 503 | kfree(uprobe); | 503 | kfree(uprobe); |
| 504 | uprobe = cur_uprobe; | 504 | uprobe = cur_uprobe; |
| 505 | iput(inode); | ||
| 506 | } | 505 | } |
| 507 | 506 | ||
| 508 | return uprobe; | 507 | return uprobe; |
| @@ -701,7 +700,6 @@ static void delete_uprobe(struct uprobe *uprobe) | |||
| 701 | rb_erase(&uprobe->rb_node, &uprobes_tree); | 700 | rb_erase(&uprobe->rb_node, &uprobes_tree); |
| 702 | spin_unlock(&uprobes_treelock); | 701 | spin_unlock(&uprobes_treelock); |
| 703 | RB_CLEAR_NODE(&uprobe->rb_node); /* for uprobe_is_active() */ | 702 | RB_CLEAR_NODE(&uprobe->rb_node); /* for uprobe_is_active() */ |
| 704 | iput(uprobe->inode); | ||
| 705 | put_uprobe(uprobe); | 703 | put_uprobe(uprobe); |
| 706 | } | 704 | } |
| 707 | 705 | ||
| @@ -873,7 +871,8 @@ static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *u | |||
| 873 | * tuple). Creation refcount stops uprobe_unregister from freeing the | 871 | * tuple). Creation refcount stops uprobe_unregister from freeing the |
| 874 | * @uprobe even before the register operation is complete. Creation | 872 | * @uprobe even before the register operation is complete. Creation |
| 875 | * refcount is released when the last @uc for the @uprobe | 873 | * refcount is released when the last @uc for the @uprobe |
| 876 | * unregisters. | 874 | * unregisters. Caller of uprobe_register() is required to keep @inode |
| 875 | * (and the containing mount) referenced. | ||
| 877 | * | 876 | * |
| 878 | * Return errno if it cannot successully install probes | 877 | * Return errno if it cannot successully install probes |
| 879 | * else return 0 (success) | 878 | * else return 0 (success) |
diff --git a/kernel/kthread.c b/kernel/kthread.c index cd50e99202b0..2017a39ab490 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
| @@ -55,7 +55,6 @@ enum KTHREAD_BITS { | |||
| 55 | KTHREAD_IS_PER_CPU = 0, | 55 | KTHREAD_IS_PER_CPU = 0, |
| 56 | KTHREAD_SHOULD_STOP, | 56 | KTHREAD_SHOULD_STOP, |
| 57 | KTHREAD_SHOULD_PARK, | 57 | KTHREAD_SHOULD_PARK, |
| 58 | KTHREAD_IS_PARKED, | ||
| 59 | }; | 58 | }; |
| 60 | 59 | ||
| 61 | static inline void set_kthread_struct(void *kthread) | 60 | static inline void set_kthread_struct(void *kthread) |
| @@ -177,14 +176,12 @@ void *kthread_probe_data(struct task_struct *task) | |||
| 177 | 176 | ||
| 178 | static void __kthread_parkme(struct kthread *self) | 177 | static void __kthread_parkme(struct kthread *self) |
| 179 | { | 178 | { |
| 180 | __set_current_state(TASK_PARKED); | 179 | for (;;) { |
| 181 | while (test_bit(KTHREAD_SHOULD_PARK, &self->flags)) { | 180 | set_current_state(TASK_PARKED); |
| 182 | if (!test_and_set_bit(KTHREAD_IS_PARKED, &self->flags)) | 181 | if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags)) |
| 183 | complete(&self->parked); | 182 | break; |
| 184 | schedule(); | 183 | schedule(); |
| 185 | __set_current_state(TASK_PARKED); | ||
| 186 | } | 184 | } |
| 187 | clear_bit(KTHREAD_IS_PARKED, &self->flags); | ||
| 188 | __set_current_state(TASK_RUNNING); | 185 | __set_current_state(TASK_RUNNING); |
| 189 | } | 186 | } |
| 190 | 187 | ||
| @@ -194,6 +191,11 @@ void kthread_parkme(void) | |||
| 194 | } | 191 | } |
| 195 | EXPORT_SYMBOL_GPL(kthread_parkme); | 192 | EXPORT_SYMBOL_GPL(kthread_parkme); |
| 196 | 193 | ||
| 194 | void kthread_park_complete(struct task_struct *k) | ||
| 195 | { | ||
| 196 | complete(&to_kthread(k)->parked); | ||
| 197 | } | ||
| 198 | |||
| 197 | static int kthread(void *_create) | 199 | static int kthread(void *_create) |
| 198 | { | 200 | { |
| 199 | /* Copy data: it's on kthread's stack */ | 201 | /* Copy data: it's on kthread's stack */ |
| @@ -450,22 +452,15 @@ void kthread_unpark(struct task_struct *k) | |||
| 450 | { | 452 | { |
| 451 | struct kthread *kthread = to_kthread(k); | 453 | struct kthread *kthread = to_kthread(k); |
| 452 | 454 | ||
| 453 | clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags); | ||
| 454 | /* | 455 | /* |
| 455 | * We clear the IS_PARKED bit here as we don't wait | 456 | * Newly created kthread was parked when the CPU was offline. |
| 456 | * until the task has left the park code. So if we'd | 457 | * The binding was lost and we need to set it again. |
| 457 | * park before that happens we'd see the IS_PARKED bit | ||
| 458 | * which might be about to be cleared. | ||
| 459 | */ | 458 | */ |
| 460 | if (test_and_clear_bit(KTHREAD_IS_PARKED, &kthread->flags)) { | 459 | if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags)) |
| 461 | /* | 460 | __kthread_bind(k, kthread->cpu, TASK_PARKED); |
| 462 | * Newly created kthread was parked when the CPU was offline. | 461 | |
| 463 | * The binding was lost and we need to set it again. | 462 | clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags); |
| 464 | */ | 463 | wake_up_state(k, TASK_PARKED); |
| 465 | if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags)) | ||
| 466 | __kthread_bind(k, kthread->cpu, TASK_PARKED); | ||
| 467 | wake_up_state(k, TASK_PARKED); | ||
| 468 | } | ||
| 469 | } | 464 | } |
| 470 | EXPORT_SYMBOL_GPL(kthread_unpark); | 465 | EXPORT_SYMBOL_GPL(kthread_unpark); |
| 471 | 466 | ||
| @@ -488,12 +483,13 @@ int kthread_park(struct task_struct *k) | |||
| 488 | if (WARN_ON(k->flags & PF_EXITING)) | 483 | if (WARN_ON(k->flags & PF_EXITING)) |
| 489 | return -ENOSYS; | 484 | return -ENOSYS; |
| 490 | 485 | ||
| 491 | if (!test_bit(KTHREAD_IS_PARKED, &kthread->flags)) { | 486 | if (WARN_ON_ONCE(test_bit(KTHREAD_SHOULD_PARK, &kthread->flags))) |
| 492 | set_bit(KTHREAD_SHOULD_PARK, &kthread->flags); | 487 | return -EBUSY; |
| 493 | if (k != current) { | 488 | |
| 494 | wake_up_process(k); | 489 | set_bit(KTHREAD_SHOULD_PARK, &kthread->flags); |
| 495 | wait_for_completion(&kthread->parked); | 490 | if (k != current) { |
| 496 | } | 491 | wake_up_process(k); |
| 492 | wait_for_completion(&kthread->parked); | ||
| 497 | } | 493 | } |
| 498 | 494 | ||
| 499 | return 0; | 495 | return 0; |
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index e795908f3607..a90336779375 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c | |||
| @@ -352,16 +352,15 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem) | |||
| 352 | struct task_struct *owner; | 352 | struct task_struct *owner; |
| 353 | bool ret = true; | 353 | bool ret = true; |
| 354 | 354 | ||
| 355 | BUILD_BUG_ON(!rwsem_has_anonymous_owner(RWSEM_OWNER_UNKNOWN)); | ||
| 356 | |||
| 355 | if (need_resched()) | 357 | if (need_resched()) |
| 356 | return false; | 358 | return false; |
| 357 | 359 | ||
| 358 | rcu_read_lock(); | 360 | rcu_read_lock(); |
| 359 | owner = READ_ONCE(sem->owner); | 361 | owner = READ_ONCE(sem->owner); |
| 360 | if (!rwsem_owner_is_writer(owner)) { | 362 | if (!owner || !is_rwsem_owner_spinnable(owner)) { |
| 361 | /* | 363 | ret = !owner; /* !owner is spinnable */ |
| 362 | * Don't spin if the rwsem is readers owned. | ||
| 363 | */ | ||
| 364 | ret = !rwsem_owner_is_reader(owner); | ||
| 365 | goto done; | 364 | goto done; |
| 366 | } | 365 | } |
| 367 | 366 | ||
| @@ -382,11 +381,11 @@ static noinline bool rwsem_spin_on_owner(struct rw_semaphore *sem) | |||
| 382 | { | 381 | { |
| 383 | struct task_struct *owner = READ_ONCE(sem->owner); | 382 | struct task_struct *owner = READ_ONCE(sem->owner); |
| 384 | 383 | ||
| 385 | if (!rwsem_owner_is_writer(owner)) | 384 | if (!is_rwsem_owner_spinnable(owner)) |
| 386 | goto out; | 385 | return false; |
| 387 | 386 | ||
| 388 | rcu_read_lock(); | 387 | rcu_read_lock(); |
| 389 | while (sem->owner == owner) { | 388 | while (owner && (READ_ONCE(sem->owner) == owner)) { |
| 390 | /* | 389 | /* |
| 391 | * Ensure we emit the owner->on_cpu, dereference _after_ | 390 | * Ensure we emit the owner->on_cpu, dereference _after_ |
| 392 | * checking sem->owner still matches owner, if that fails, | 391 | * checking sem->owner still matches owner, if that fails, |
| @@ -408,12 +407,12 @@ static noinline bool rwsem_spin_on_owner(struct rw_semaphore *sem) | |||
| 408 | cpu_relax(); | 407 | cpu_relax(); |
| 409 | } | 408 | } |
| 410 | rcu_read_unlock(); | 409 | rcu_read_unlock(); |
| 411 | out: | 410 | |
| 412 | /* | 411 | /* |
| 413 | * If there is a new owner or the owner is not set, we continue | 412 | * If there is a new owner or the owner is not set, we continue |
| 414 | * spinning. | 413 | * spinning. |
| 415 | */ | 414 | */ |
| 416 | return !rwsem_owner_is_reader(READ_ONCE(sem->owner)); | 415 | return is_rwsem_owner_spinnable(READ_ONCE(sem->owner)); |
| 417 | } | 416 | } |
| 418 | 417 | ||
| 419 | static bool rwsem_optimistic_spin(struct rw_semaphore *sem) | 418 | static bool rwsem_optimistic_spin(struct rw_semaphore *sem) |
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 30465a2f2b6c..bc1e507be9ff 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c | |||
| @@ -221,5 +221,3 @@ void up_read_non_owner(struct rw_semaphore *sem) | |||
| 221 | EXPORT_SYMBOL(up_read_non_owner); | 221 | EXPORT_SYMBOL(up_read_non_owner); |
| 222 | 222 | ||
| 223 | #endif | 223 | #endif |
| 224 | |||
| 225 | |||
diff --git a/kernel/locking/rwsem.h b/kernel/locking/rwsem.h index a17cba8d94bb..b9d0e72aa80f 100644 --- a/kernel/locking/rwsem.h +++ b/kernel/locking/rwsem.h | |||
| @@ -1,20 +1,24 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* | 2 | /* |
| 3 | * The owner field of the rw_semaphore structure will be set to | 3 | * The owner field of the rw_semaphore structure will be set to |
| 4 | * RWSEM_READ_OWNED when a reader grabs the lock. A writer will clear | 4 | * RWSEM_READER_OWNED when a reader grabs the lock. A writer will clear |
| 5 | * the owner field when it unlocks. A reader, on the other hand, will | 5 | * the owner field when it unlocks. A reader, on the other hand, will |
| 6 | * not touch the owner field when it unlocks. | 6 | * not touch the owner field when it unlocks. |
| 7 | * | 7 | * |
| 8 | * In essence, the owner field now has the following 3 states: | 8 | * In essence, the owner field now has the following 4 states: |
| 9 | * 1) 0 | 9 | * 1) 0 |
| 10 | * - lock is free or the owner hasn't set the field yet | 10 | * - lock is free or the owner hasn't set the field yet |
| 11 | * 2) RWSEM_READER_OWNED | 11 | * 2) RWSEM_READER_OWNED |
| 12 | * - lock is currently or previously owned by readers (lock is free | 12 | * - lock is currently or previously owned by readers (lock is free |
| 13 | * or not set by owner yet) | 13 | * or not set by owner yet) |
| 14 | * 3) Other non-zero value | 14 | * 3) RWSEM_ANONYMOUSLY_OWNED bit set with some other bits set as well |
| 15 | * - a writer owns the lock | 15 | * - lock is owned by an anonymous writer, so spinning on the lock |
| 16 | * owner should be disabled. | ||
| 17 | * 4) Other non-zero value | ||
| 18 | * - a writer owns the lock and other writers can spin on the lock owner. | ||
| 16 | */ | 19 | */ |
| 17 | #define RWSEM_READER_OWNED ((struct task_struct *)1UL) | 20 | #define RWSEM_ANONYMOUSLY_OWNED (1UL << 0) |
| 21 | #define RWSEM_READER_OWNED ((struct task_struct *)RWSEM_ANONYMOUSLY_OWNED) | ||
| 18 | 22 | ||
| 19 | #ifdef CONFIG_DEBUG_RWSEMS | 23 | #ifdef CONFIG_DEBUG_RWSEMS |
| 20 | # define DEBUG_RWSEMS_WARN_ON(c) DEBUG_LOCKS_WARN_ON(c) | 24 | # define DEBUG_RWSEMS_WARN_ON(c) DEBUG_LOCKS_WARN_ON(c) |
| @@ -51,14 +55,22 @@ static inline void rwsem_set_reader_owned(struct rw_semaphore *sem) | |||
| 51 | WRITE_ONCE(sem->owner, RWSEM_READER_OWNED); | 55 | WRITE_ONCE(sem->owner, RWSEM_READER_OWNED); |
| 52 | } | 56 | } |
| 53 | 57 | ||
| 54 | static inline bool rwsem_owner_is_writer(struct task_struct *owner) | 58 | /* |
| 59 | * Return true if the a rwsem waiter can spin on the rwsem's owner | ||
| 60 | * and steal the lock, i.e. the lock is not anonymously owned. | ||
| 61 | * N.B. !owner is considered spinnable. | ||
| 62 | */ | ||
| 63 | static inline bool is_rwsem_owner_spinnable(struct task_struct *owner) | ||
| 55 | { | 64 | { |
| 56 | return owner && owner != RWSEM_READER_OWNED; | 65 | return !((unsigned long)owner & RWSEM_ANONYMOUSLY_OWNED); |
| 57 | } | 66 | } |
| 58 | 67 | ||
| 59 | static inline bool rwsem_owner_is_reader(struct task_struct *owner) | 68 | /* |
| 69 | * Return true if rwsem is owned by an anonymous writer or readers. | ||
| 70 | */ | ||
| 71 | static inline bool rwsem_has_anonymous_owner(struct task_struct *owner) | ||
| 60 | { | 72 | { |
| 61 | return owner == RWSEM_READER_OWNED; | 73 | return (unsigned long)owner & RWSEM_ANONYMOUSLY_OWNED; |
| 62 | } | 74 | } |
| 63 | #else | 75 | #else |
| 64 | static inline void rwsem_set_owner(struct rw_semaphore *sem) | 76 | static inline void rwsem_set_owner(struct rw_semaphore *sem) |
diff --git a/kernel/module.c b/kernel/module.c index ce8066b88178..c9bea7f2b43e 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -3517,6 +3517,11 @@ static noinline int do_init_module(struct module *mod) | |||
| 3517 | * walking this with preempt disabled. In all the failure paths, we | 3517 | * walking this with preempt disabled. In all the failure paths, we |
| 3518 | * call synchronize_sched(), but we don't want to slow down the success | 3518 | * call synchronize_sched(), but we don't want to slow down the success |
| 3519 | * path, so use actual RCU here. | 3519 | * path, so use actual RCU here. |
| 3520 | * Note that module_alloc() on most architectures creates W+X page | ||
| 3521 | * mappings which won't be cleaned up until do_free_init() runs. Any | ||
| 3522 | * code such as mark_rodata_ro() which depends on those mappings to | ||
| 3523 | * be cleaned up needs to sync with the queued work - ie | ||
| 3524 | * rcu_barrier_sched() | ||
| 3520 | */ | 3525 | */ |
| 3521 | call_rcu_sched(&freeinit->rcu, do_free_init); | 3526 | call_rcu_sched(&freeinit->rcu, do_free_init); |
| 3522 | mutex_unlock(&module_mutex); | 3527 | mutex_unlock(&module_mutex); |
diff --git a/kernel/sched/autogroup.c b/kernel/sched/autogroup.c index 6be6c575b6cd..2d4ff5353ded 100644 --- a/kernel/sched/autogroup.c +++ b/kernel/sched/autogroup.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | /* | 2 | /* |
| 3 | * Auto-group scheduling implementation: | 3 | * Auto-group scheduling implementation: |
| 4 | */ | 4 | */ |
| 5 | #include <linux/nospec.h> | ||
| 5 | #include "sched.h" | 6 | #include "sched.h" |
| 6 | 7 | ||
| 7 | unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1; | 8 | unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1; |
| @@ -209,7 +210,7 @@ int proc_sched_autogroup_set_nice(struct task_struct *p, int nice) | |||
| 209 | static unsigned long next = INITIAL_JIFFIES; | 210 | static unsigned long next = INITIAL_JIFFIES; |
| 210 | struct autogroup *ag; | 211 | struct autogroup *ag; |
| 211 | unsigned long shares; | 212 | unsigned long shares; |
| 212 | int err; | 213 | int err, idx; |
| 213 | 214 | ||
| 214 | if (nice < MIN_NICE || nice > MAX_NICE) | 215 | if (nice < MIN_NICE || nice > MAX_NICE) |
| 215 | return -EINVAL; | 216 | return -EINVAL; |
| @@ -227,7 +228,9 @@ int proc_sched_autogroup_set_nice(struct task_struct *p, int nice) | |||
| 227 | 228 | ||
| 228 | next = HZ / 10 + jiffies; | 229 | next = HZ / 10 + jiffies; |
| 229 | ag = autogroup_task_get(p); | 230 | ag = autogroup_task_get(p); |
| 230 | shares = scale_load(sched_prio_to_weight[nice + 20]); | 231 | |
| 232 | idx = array_index_nospec(nice + 20, 40); | ||
| 233 | shares = scale_load(sched_prio_to_weight[idx]); | ||
| 231 | 234 | ||
| 232 | down_write(&ag->lock); | 235 | down_write(&ag->lock); |
| 233 | err = sched_group_set_shares(ag->tg, shares); | 236 | err = sched_group_set_shares(ag->tg, shares); |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 5e10aaeebfcc..092f7c4de903 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -7,6 +7,9 @@ | |||
| 7 | */ | 7 | */ |
| 8 | #include "sched.h" | 8 | #include "sched.h" |
| 9 | 9 | ||
| 10 | #include <linux/kthread.h> | ||
| 11 | #include <linux/nospec.h> | ||
| 12 | |||
| 10 | #include <asm/switch_to.h> | 13 | #include <asm/switch_to.h> |
| 11 | #include <asm/tlb.h> | 14 | #include <asm/tlb.h> |
| 12 | 15 | ||
| @@ -2718,20 +2721,28 @@ static struct rq *finish_task_switch(struct task_struct *prev) | |||
| 2718 | membarrier_mm_sync_core_before_usermode(mm); | 2721 | membarrier_mm_sync_core_before_usermode(mm); |
| 2719 | mmdrop(mm); | 2722 | mmdrop(mm); |
| 2720 | } | 2723 | } |
| 2721 | if (unlikely(prev_state == TASK_DEAD)) { | 2724 | if (unlikely(prev_state & (TASK_DEAD|TASK_PARKED))) { |
| 2722 | if (prev->sched_class->task_dead) | 2725 | switch (prev_state) { |
| 2723 | prev->sched_class->task_dead(prev); | 2726 | case TASK_DEAD: |
| 2727 | if (prev->sched_class->task_dead) | ||
| 2728 | prev->sched_class->task_dead(prev); | ||
| 2724 | 2729 | ||
| 2725 | /* | 2730 | /* |
| 2726 | * Remove function-return probe instances associated with this | 2731 | * Remove function-return probe instances associated with this |
| 2727 | * task and put them back on the free list. | 2732 | * task and put them back on the free list. |
| 2728 | */ | 2733 | */ |
| 2729 | kprobe_flush_task(prev); | 2734 | kprobe_flush_task(prev); |
| 2735 | |||
| 2736 | /* Task is done with its stack. */ | ||
| 2737 | put_task_stack(prev); | ||
| 2730 | 2738 | ||
| 2731 | /* Task is done with its stack. */ | 2739 | put_task_struct(prev); |
| 2732 | put_task_stack(prev); | 2740 | break; |
| 2733 | 2741 | ||
| 2734 | put_task_struct(prev); | 2742 | case TASK_PARKED: |
| 2743 | kthread_park_complete(prev); | ||
| 2744 | break; | ||
| 2745 | } | ||
| 2735 | } | 2746 | } |
| 2736 | 2747 | ||
| 2737 | tick_nohz_task_switch(); | 2748 | tick_nohz_task_switch(); |
| @@ -3498,23 +3509,8 @@ static void __sched notrace __schedule(bool preempt) | |||
| 3498 | 3509 | ||
| 3499 | void __noreturn do_task_dead(void) | 3510 | void __noreturn do_task_dead(void) |
| 3500 | { | 3511 | { |
| 3501 | /* | ||
| 3502 | * The setting of TASK_RUNNING by try_to_wake_up() may be delayed | ||
| 3503 | * when the following two conditions become true. | ||
| 3504 | * - There is race condition of mmap_sem (It is acquired by | ||
| 3505 | * exit_mm()), and | ||
| 3506 | * - SMI occurs before setting TASK_RUNINNG. | ||
| 3507 | * (or hypervisor of virtual machine switches to other guest) | ||
| 3508 | * As a result, we may become TASK_RUNNING after becoming TASK_DEAD | ||
| 3509 | * | ||
| 3510 | * To avoid it, we have to wait for releasing tsk->pi_lock which | ||
| 3511 | * is held by try_to_wake_up() | ||
| 3512 | */ | ||
| 3513 | raw_spin_lock_irq(¤t->pi_lock); | ||
| 3514 | raw_spin_unlock_irq(¤t->pi_lock); | ||
| 3515 | |||
| 3516 | /* Causes final put_task_struct in finish_task_switch(): */ | 3512 | /* Causes final put_task_struct in finish_task_switch(): */ |
| 3517 | __set_current_state(TASK_DEAD); | 3513 | set_special_state(TASK_DEAD); |
| 3518 | 3514 | ||
| 3519 | /* Tell freezer to ignore us: */ | 3515 | /* Tell freezer to ignore us: */ |
| 3520 | current->flags |= PF_NOFREEZE; | 3516 | current->flags |= PF_NOFREEZE; |
| @@ -6928,11 +6924,15 @@ static int cpu_weight_nice_write_s64(struct cgroup_subsys_state *css, | |||
| 6928 | struct cftype *cft, s64 nice) | 6924 | struct cftype *cft, s64 nice) |
| 6929 | { | 6925 | { |
| 6930 | unsigned long weight; | 6926 | unsigned long weight; |
| 6927 | int idx; | ||
| 6931 | 6928 | ||
| 6932 | if (nice < MIN_NICE || nice > MAX_NICE) | 6929 | if (nice < MIN_NICE || nice > MAX_NICE) |
| 6933 | return -ERANGE; | 6930 | return -ERANGE; |
| 6934 | 6931 | ||
| 6935 | weight = sched_prio_to_weight[NICE_TO_PRIO(nice) - MAX_RT_PRIO]; | 6932 | idx = NICE_TO_PRIO(nice) - MAX_RT_PRIO; |
| 6933 | idx = array_index_nospec(idx, 40); | ||
| 6934 | weight = sched_prio_to_weight[idx]; | ||
| 6935 | |||
| 6936 | return sched_group_set_shares(css_tg(css), scale_load(weight)); | 6936 | return sched_group_set_shares(css_tg(css), scale_load(weight)); |
| 6937 | } | 6937 | } |
| 6938 | #endif | 6938 | #endif |
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index d2c6083304b4..e13df951aca7 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c | |||
| @@ -305,7 +305,8 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, | |||
| 305 | * Do not reduce the frequency if the CPU has not been idle | 305 | * Do not reduce the frequency if the CPU has not been idle |
| 306 | * recently, as the reduction is likely to be premature then. | 306 | * recently, as the reduction is likely to be premature then. |
| 307 | */ | 307 | */ |
| 308 | if (busy && next_f < sg_policy->next_freq) { | 308 | if (busy && next_f < sg_policy->next_freq && |
| 309 | sg_policy->next_freq != UINT_MAX) { | ||
| 309 | next_f = sg_policy->next_freq; | 310 | next_f = sg_policy->next_freq; |
| 310 | 311 | ||
| 311 | /* Reset cached freq as next_freq has changed */ | 312 | /* Reset cached freq as next_freq has changed */ |
| @@ -396,19 +397,6 @@ static void sugov_irq_work(struct irq_work *irq_work) | |||
| 396 | 397 | ||
| 397 | sg_policy = container_of(irq_work, struct sugov_policy, irq_work); | 398 | sg_policy = container_of(irq_work, struct sugov_policy, irq_work); |
| 398 | 399 | ||
| 399 | /* | ||
| 400 | * For RT tasks, the schedutil governor shoots the frequency to maximum. | ||
| 401 | * Special care must be taken to ensure that this kthread doesn't result | ||
| 402 | * in the same behavior. | ||
| 403 | * | ||
| 404 | * This is (mostly) guaranteed by the work_in_progress flag. The flag is | ||
| 405 | * updated only at the end of the sugov_work() function and before that | ||
| 406 | * the schedutil governor rejects all other frequency scaling requests. | ||
| 407 | * | ||
| 408 | * There is a very rare case though, where the RT thread yields right | ||
| 409 | * after the work_in_progress flag is cleared. The effects of that are | ||
| 410 | * neglected for now. | ||
| 411 | */ | ||
| 412 | kthread_queue_work(&sg_policy->worker, &sg_policy->work); | 400 | kthread_queue_work(&sg_policy->worker, &sg_policy->work); |
| 413 | } | 401 | } |
| 414 | 402 | ||
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index e7b3008b85bb..1356afd1eeb6 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c | |||
| @@ -1117,7 +1117,7 @@ extern bool sched_rt_bandwidth_account(struct rt_rq *rt_rq); | |||
| 1117 | * should be larger than 2^(64 - 20 - 8), which is more than 64 seconds. | 1117 | * should be larger than 2^(64 - 20 - 8), which is more than 64 seconds. |
| 1118 | * So, overflow is not an issue here. | 1118 | * So, overflow is not an issue here. |
| 1119 | */ | 1119 | */ |
| 1120 | u64 grub_reclaim(u64 delta, struct rq *rq, struct sched_dl_entity *dl_se) | 1120 | static u64 grub_reclaim(u64 delta, struct rq *rq, struct sched_dl_entity *dl_se) |
| 1121 | { | 1121 | { |
| 1122 | u64 u_inact = rq->dl.this_bw - rq->dl.running_bw; /* Utot - Uact */ | 1122 | u64 u_inact = rq->dl.this_bw - rq->dl.running_bw; /* Utot - Uact */ |
| 1123 | u64 u_act; | 1123 | u64 u_act; |
| @@ -2731,8 +2731,6 @@ bool dl_cpu_busy(unsigned int cpu) | |||
| 2731 | #endif | 2731 | #endif |
| 2732 | 2732 | ||
| 2733 | #ifdef CONFIG_SCHED_DEBUG | 2733 | #ifdef CONFIG_SCHED_DEBUG |
| 2734 | extern void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq *dl_rq); | ||
| 2735 | |||
| 2736 | void print_dl_stats(struct seq_file *m, int cpu) | 2734 | void print_dl_stats(struct seq_file *m, int cpu) |
| 2737 | { | 2735 | { |
| 2738 | print_dl_rq(m, cpu, &cpu_rq(cpu)->dl); | 2736 | print_dl_rq(m, cpu, &cpu_rq(cpu)->dl); |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 54dc31e7ab9b..79f574dba096 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
| @@ -1854,7 +1854,6 @@ static int task_numa_migrate(struct task_struct *p) | |||
| 1854 | static void numa_migrate_preferred(struct task_struct *p) | 1854 | static void numa_migrate_preferred(struct task_struct *p) |
| 1855 | { | 1855 | { |
| 1856 | unsigned long interval = HZ; | 1856 | unsigned long interval = HZ; |
| 1857 | unsigned long numa_migrate_retry; | ||
| 1858 | 1857 | ||
| 1859 | /* This task has no NUMA fault statistics yet */ | 1858 | /* This task has no NUMA fault statistics yet */ |
| 1860 | if (unlikely(p->numa_preferred_nid == -1 || !p->numa_faults)) | 1859 | if (unlikely(p->numa_preferred_nid == -1 || !p->numa_faults)) |
| @@ -1862,18 +1861,7 @@ static void numa_migrate_preferred(struct task_struct *p) | |||
| 1862 | 1861 | ||
| 1863 | /* Periodically retry migrating the task to the preferred node */ | 1862 | /* Periodically retry migrating the task to the preferred node */ |
| 1864 | interval = min(interval, msecs_to_jiffies(p->numa_scan_period) / 16); | 1863 | interval = min(interval, msecs_to_jiffies(p->numa_scan_period) / 16); |
| 1865 | numa_migrate_retry = jiffies + interval; | 1864 | p->numa_migrate_retry = jiffies + interval; |
| 1866 | |||
| 1867 | /* | ||
| 1868 | * Check that the new retry threshold is after the current one. If | ||
| 1869 | * the retry is in the future, it implies that wake_affine has | ||
| 1870 | * temporarily asked NUMA balancing to backoff from placement. | ||
| 1871 | */ | ||
| 1872 | if (numa_migrate_retry > p->numa_migrate_retry) | ||
| 1873 | return; | ||
| 1874 | |||
| 1875 | /* Safe to try placing the task on the preferred node */ | ||
| 1876 | p->numa_migrate_retry = numa_migrate_retry; | ||
| 1877 | 1865 | ||
| 1878 | /* Success if task is already running on preferred CPU */ | 1866 | /* Success if task is already running on preferred CPU */ |
| 1879 | if (task_node(p) == p->numa_preferred_nid) | 1867 | if (task_node(p) == p->numa_preferred_nid) |
| @@ -5922,48 +5910,6 @@ wake_affine_weight(struct sched_domain *sd, struct task_struct *p, | |||
| 5922 | return this_eff_load < prev_eff_load ? this_cpu : nr_cpumask_bits; | 5910 | return this_eff_load < prev_eff_load ? this_cpu : nr_cpumask_bits; |
| 5923 | } | 5911 | } |
| 5924 | 5912 | ||
| 5925 | #ifdef CONFIG_NUMA_BALANCING | ||
| 5926 | static void | ||
| 5927 | update_wa_numa_placement(struct task_struct *p, int prev_cpu, int target) | ||
| 5928 | { | ||
| 5929 | unsigned long interval; | ||
| 5930 | |||
| 5931 | if (!static_branch_likely(&sched_numa_balancing)) | ||
| 5932 | return; | ||
| 5933 | |||
| 5934 | /* If balancing has no preference then continue gathering data */ | ||
| 5935 | if (p->numa_preferred_nid == -1) | ||
| 5936 | return; | ||
| 5937 | |||
| 5938 | /* | ||
| 5939 | * If the wakeup is not affecting locality then it is neutral from | ||
| 5940 | * the perspective of NUMA balacing so continue gathering data. | ||
| 5941 | */ | ||
| 5942 | if (cpu_to_node(prev_cpu) == cpu_to_node(target)) | ||
| 5943 | return; | ||
| 5944 | |||
| 5945 | /* | ||
| 5946 | * Temporarily prevent NUMA balancing trying to place waker/wakee after | ||
| 5947 | * wakee has been moved by wake_affine. This will potentially allow | ||
| 5948 | * related tasks to converge and update their data placement. The | ||
| 5949 | * 4 * numa_scan_period is to allow the two-pass filter to migrate | ||
| 5950 | * hot data to the wakers node. | ||
| 5951 | */ | ||
| 5952 | interval = max(sysctl_numa_balancing_scan_delay, | ||
| 5953 | p->numa_scan_period << 2); | ||
| 5954 | p->numa_migrate_retry = jiffies + msecs_to_jiffies(interval); | ||
| 5955 | |||
| 5956 | interval = max(sysctl_numa_balancing_scan_delay, | ||
| 5957 | current->numa_scan_period << 2); | ||
| 5958 | current->numa_migrate_retry = jiffies + msecs_to_jiffies(interval); | ||
| 5959 | } | ||
| 5960 | #else | ||
| 5961 | static void | ||
| 5962 | update_wa_numa_placement(struct task_struct *p, int prev_cpu, int target) | ||
| 5963 | { | ||
| 5964 | } | ||
| 5965 | #endif | ||
| 5966 | |||
| 5967 | static int wake_affine(struct sched_domain *sd, struct task_struct *p, | 5913 | static int wake_affine(struct sched_domain *sd, struct task_struct *p, |
| 5968 | int this_cpu, int prev_cpu, int sync) | 5914 | int this_cpu, int prev_cpu, int sync) |
| 5969 | { | 5915 | { |
| @@ -5979,7 +5925,6 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, | |||
| 5979 | if (target == nr_cpumask_bits) | 5925 | if (target == nr_cpumask_bits) |
| 5980 | return prev_cpu; | 5926 | return prev_cpu; |
| 5981 | 5927 | ||
| 5982 | update_wa_numa_placement(p, prev_cpu, target); | ||
| 5983 | schedstat_inc(sd->ttwu_move_affine); | 5928 | schedstat_inc(sd->ttwu_move_affine); |
| 5984 | schedstat_inc(p->se.statistics.nr_wakeups_affine); | 5929 | schedstat_inc(p->se.statistics.nr_wakeups_affine); |
| 5985 | return target; | 5930 | return target; |
| @@ -9847,6 +9792,7 @@ static int idle_balance(struct rq *this_rq, struct rq_flags *rf) | |||
| 9847 | if (curr_cost > this_rq->max_idle_balance_cost) | 9792 | if (curr_cost > this_rq->max_idle_balance_cost) |
| 9848 | this_rq->max_idle_balance_cost = curr_cost; | 9793 | this_rq->max_idle_balance_cost = curr_cost; |
| 9849 | 9794 | ||
| 9795 | out: | ||
| 9850 | /* | 9796 | /* |
| 9851 | * While browsing the domains, we released the rq lock, a task could | 9797 | * While browsing the domains, we released the rq lock, a task could |
| 9852 | * have been enqueued in the meantime. Since we're not going idle, | 9798 | * have been enqueued in the meantime. Since we're not going idle, |
| @@ -9855,7 +9801,6 @@ static int idle_balance(struct rq *this_rq, struct rq_flags *rf) | |||
| 9855 | if (this_rq->cfs.h_nr_running && !pulled_task) | 9801 | if (this_rq->cfs.h_nr_running && !pulled_task) |
| 9856 | pulled_task = 1; | 9802 | pulled_task = 1; |
| 9857 | 9803 | ||
| 9858 | out: | ||
| 9859 | /* Move the next balance forward */ | 9804 | /* Move the next balance forward */ |
| 9860 | if (time_after(this_rq->next_balance, next_balance)) | 9805 | if (time_after(this_rq->next_balance, next_balance)) |
| 9861 | this_rq->next_balance = next_balance; | 9806 | this_rq->next_balance = next_balance; |
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 7aef6b4e885a..ef3c4e6f5345 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
| @@ -2701,8 +2701,6 @@ int sched_rr_handler(struct ctl_table *table, int write, | |||
| 2701 | } | 2701 | } |
| 2702 | 2702 | ||
| 2703 | #ifdef CONFIG_SCHED_DEBUG | 2703 | #ifdef CONFIG_SCHED_DEBUG |
| 2704 | extern void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq); | ||
| 2705 | |||
| 2706 | void print_rt_stats(struct seq_file *m, int cpu) | 2704 | void print_rt_stats(struct seq_file *m, int cpu) |
| 2707 | { | 2705 | { |
| 2708 | rt_rq_iter_t iter; | 2706 | rt_rq_iter_t iter; |
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 15750c222ca2..1f0a4bc6a39d 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
| @@ -2025,8 +2025,9 @@ extern bool sched_debug_enabled; | |||
| 2025 | extern void print_cfs_stats(struct seq_file *m, int cpu); | 2025 | extern void print_cfs_stats(struct seq_file *m, int cpu); |
| 2026 | extern void print_rt_stats(struct seq_file *m, int cpu); | 2026 | extern void print_rt_stats(struct seq_file *m, int cpu); |
| 2027 | extern void print_dl_stats(struct seq_file *m, int cpu); | 2027 | extern void print_dl_stats(struct seq_file *m, int cpu); |
| 2028 | extern void | 2028 | extern void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); |
| 2029 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); | 2029 | extern void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq); |
| 2030 | extern void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq *dl_rq); | ||
| 2030 | #ifdef CONFIG_NUMA_BALANCING | 2031 | #ifdef CONFIG_NUMA_BALANCING |
| 2031 | extern void | 2032 | extern void |
| 2032 | show_numa_stats(struct task_struct *p, struct seq_file *m); | 2033 | show_numa_stats(struct task_struct *p, struct seq_file *m); |
diff --git a/kernel/signal.c b/kernel/signal.c index d4ccea599692..9c33163a6165 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -1961,14 +1961,27 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) | |||
| 1961 | return; | 1961 | return; |
| 1962 | } | 1962 | } |
| 1963 | 1963 | ||
| 1964 | set_special_state(TASK_TRACED); | ||
| 1965 | |||
| 1964 | /* | 1966 | /* |
| 1965 | * We're committing to trapping. TRACED should be visible before | 1967 | * We're committing to trapping. TRACED should be visible before |
| 1966 | * TRAPPING is cleared; otherwise, the tracer might fail do_wait(). | 1968 | * TRAPPING is cleared; otherwise, the tracer might fail do_wait(). |
| 1967 | * Also, transition to TRACED and updates to ->jobctl should be | 1969 | * Also, transition to TRACED and updates to ->jobctl should be |
| 1968 | * atomic with respect to siglock and should be done after the arch | 1970 | * atomic with respect to siglock and should be done after the arch |
| 1969 | * hook as siglock is released and regrabbed across it. | 1971 | * hook as siglock is released and regrabbed across it. |
| 1972 | * | ||
| 1973 | * TRACER TRACEE | ||
| 1974 | * | ||
| 1975 | * ptrace_attach() | ||
| 1976 | * [L] wait_on_bit(JOBCTL_TRAPPING) [S] set_special_state(TRACED) | ||
| 1977 | * do_wait() | ||
| 1978 | * set_current_state() smp_wmb(); | ||
| 1979 | * ptrace_do_wait() | ||
| 1980 | * wait_task_stopped() | ||
| 1981 | * task_stopped_code() | ||
| 1982 | * [L] task_is_traced() [S] task_clear_jobctl_trapping(); | ||
| 1970 | */ | 1983 | */ |
| 1971 | set_current_state(TASK_TRACED); | 1984 | smp_wmb(); |
| 1972 | 1985 | ||
| 1973 | current->last_siginfo = info; | 1986 | current->last_siginfo = info; |
| 1974 | current->exit_code = exit_code; | 1987 | current->exit_code = exit_code; |
| @@ -2176,7 +2189,7 @@ static bool do_signal_stop(int signr) | |||
| 2176 | if (task_participate_group_stop(current)) | 2189 | if (task_participate_group_stop(current)) |
| 2177 | notify = CLD_STOPPED; | 2190 | notify = CLD_STOPPED; |
| 2178 | 2191 | ||
| 2179 | __set_current_state(TASK_STOPPED); | 2192 | set_special_state(TASK_STOPPED); |
| 2180 | spin_unlock_irq(¤t->sighand->siglock); | 2193 | spin_unlock_irq(¤t->sighand->siglock); |
| 2181 | 2194 | ||
| 2182 | /* | 2195 | /* |
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index b7591261652d..64c0291b579c 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/smpboot.h> | 21 | #include <linux/smpboot.h> |
| 22 | #include <linux/atomic.h> | 22 | #include <linux/atomic.h> |
| 23 | #include <linux/nmi.h> | 23 | #include <linux/nmi.h> |
| 24 | #include <linux/sched/wake_q.h> | ||
| 24 | 25 | ||
| 25 | /* | 26 | /* |
| 26 | * Structure to determine completion condition and record errors. May | 27 | * Structure to determine completion condition and record errors. May |
| @@ -65,27 +66,31 @@ static void cpu_stop_signal_done(struct cpu_stop_done *done) | |||
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | static void __cpu_stop_queue_work(struct cpu_stopper *stopper, | 68 | static void __cpu_stop_queue_work(struct cpu_stopper *stopper, |
| 68 | struct cpu_stop_work *work) | 69 | struct cpu_stop_work *work, |
| 70 | struct wake_q_head *wakeq) | ||
| 69 | { | 71 | { |
| 70 | list_add_tail(&work->list, &stopper->works); | 72 | list_add_tail(&work->list, &stopper->works); |
| 71 | wake_up_process(stopper->thread); | 73 | wake_q_add(wakeq, stopper->thread); |
| 72 | } | 74 | } |
| 73 | 75 | ||
| 74 | /* queue @work to @stopper. if offline, @work is completed immediately */ | 76 | /* queue @work to @stopper. if offline, @work is completed immediately */ |
| 75 | static bool cpu_stop_queue_work(unsigned int cpu, struct cpu_stop_work *work) | 77 | static bool cpu_stop_queue_work(unsigned int cpu, struct cpu_stop_work *work) |
| 76 | { | 78 | { |
| 77 | struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu); | 79 | struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu); |
| 80 | DEFINE_WAKE_Q(wakeq); | ||
| 78 | unsigned long flags; | 81 | unsigned long flags; |
| 79 | bool enabled; | 82 | bool enabled; |
| 80 | 83 | ||
| 81 | spin_lock_irqsave(&stopper->lock, flags); | 84 | spin_lock_irqsave(&stopper->lock, flags); |
| 82 | enabled = stopper->enabled; | 85 | enabled = stopper->enabled; |
| 83 | if (enabled) | 86 | if (enabled) |
| 84 | __cpu_stop_queue_work(stopper, work); | 87 | __cpu_stop_queue_work(stopper, work, &wakeq); |
| 85 | else if (work->done) | 88 | else if (work->done) |
| 86 | cpu_stop_signal_done(work->done); | 89 | cpu_stop_signal_done(work->done); |
| 87 | spin_unlock_irqrestore(&stopper->lock, flags); | 90 | spin_unlock_irqrestore(&stopper->lock, flags); |
| 88 | 91 | ||
| 92 | wake_up_q(&wakeq); | ||
| 93 | |||
| 89 | return enabled; | 94 | return enabled; |
| 90 | } | 95 | } |
| 91 | 96 | ||
| @@ -229,6 +234,7 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, | |||
| 229 | { | 234 | { |
| 230 | struct cpu_stopper *stopper1 = per_cpu_ptr(&cpu_stopper, cpu1); | 235 | struct cpu_stopper *stopper1 = per_cpu_ptr(&cpu_stopper, cpu1); |
| 231 | struct cpu_stopper *stopper2 = per_cpu_ptr(&cpu_stopper, cpu2); | 236 | struct cpu_stopper *stopper2 = per_cpu_ptr(&cpu_stopper, cpu2); |
| 237 | DEFINE_WAKE_Q(wakeq); | ||
| 232 | int err; | 238 | int err; |
| 233 | retry: | 239 | retry: |
| 234 | spin_lock_irq(&stopper1->lock); | 240 | spin_lock_irq(&stopper1->lock); |
| @@ -252,8 +258,8 @@ retry: | |||
| 252 | goto unlock; | 258 | goto unlock; |
| 253 | 259 | ||
| 254 | err = 0; | 260 | err = 0; |
| 255 | __cpu_stop_queue_work(stopper1, work1); | 261 | __cpu_stop_queue_work(stopper1, work1, &wakeq); |
| 256 | __cpu_stop_queue_work(stopper2, work2); | 262 | __cpu_stop_queue_work(stopper2, work2, &wakeq); |
| 257 | unlock: | 263 | unlock: |
| 258 | spin_unlock(&stopper2->lock); | 264 | spin_unlock(&stopper2->lock); |
| 259 | spin_unlock_irq(&stopper1->lock); | 265 | spin_unlock_irq(&stopper1->lock); |
| @@ -263,6 +269,9 @@ unlock: | |||
| 263 | cpu_relax(); | 269 | cpu_relax(); |
| 264 | goto retry; | 270 | goto retry; |
| 265 | } | 271 | } |
| 272 | |||
| 273 | wake_up_q(&wakeq); | ||
| 274 | |||
| 266 | return err; | 275 | return err; |
| 267 | } | 276 | } |
| 268 | /** | 277 | /** |
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 0e974cface0b..84f37420fcf5 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
| @@ -119,6 +119,16 @@ static DEFINE_SPINLOCK(watchdog_lock); | |||
| 119 | static int watchdog_running; | 119 | static int watchdog_running; |
| 120 | static atomic_t watchdog_reset_pending; | 120 | static atomic_t watchdog_reset_pending; |
| 121 | 121 | ||
| 122 | static void inline clocksource_watchdog_lock(unsigned long *flags) | ||
| 123 | { | ||
| 124 | spin_lock_irqsave(&watchdog_lock, *flags); | ||
| 125 | } | ||
| 126 | |||
| 127 | static void inline clocksource_watchdog_unlock(unsigned long *flags) | ||
| 128 | { | ||
| 129 | spin_unlock_irqrestore(&watchdog_lock, *flags); | ||
| 130 | } | ||
| 131 | |||
| 122 | static int clocksource_watchdog_kthread(void *data); | 132 | static int clocksource_watchdog_kthread(void *data); |
| 123 | static void __clocksource_change_rating(struct clocksource *cs, int rating); | 133 | static void __clocksource_change_rating(struct clocksource *cs, int rating); |
| 124 | 134 | ||
| @@ -142,9 +152,19 @@ static void __clocksource_unstable(struct clocksource *cs) | |||
| 142 | cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG); | 152 | cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG); |
| 143 | cs->flags |= CLOCK_SOURCE_UNSTABLE; | 153 | cs->flags |= CLOCK_SOURCE_UNSTABLE; |
| 144 | 154 | ||
| 155 | /* | ||
| 156 | * If the clocksource is registered clocksource_watchdog_kthread() will | ||
| 157 | * re-rate and re-select. | ||
| 158 | */ | ||
| 159 | if (list_empty(&cs->list)) { | ||
| 160 | cs->rating = 0; | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 145 | if (cs->mark_unstable) | 164 | if (cs->mark_unstable) |
| 146 | cs->mark_unstable(cs); | 165 | cs->mark_unstable(cs); |
| 147 | 166 | ||
| 167 | /* kick clocksource_watchdog_kthread() */ | ||
| 148 | if (finished_booting) | 168 | if (finished_booting) |
| 149 | schedule_work(&watchdog_work); | 169 | schedule_work(&watchdog_work); |
| 150 | } | 170 | } |
| @@ -153,10 +173,8 @@ static void __clocksource_unstable(struct clocksource *cs) | |||
| 153 | * clocksource_mark_unstable - mark clocksource unstable via watchdog | 173 | * clocksource_mark_unstable - mark clocksource unstable via watchdog |
| 154 | * @cs: clocksource to be marked unstable | 174 | * @cs: clocksource to be marked unstable |
| 155 | * | 175 | * |
| 156 | * This function is called instead of clocksource_change_rating from | 176 | * This function is called by the x86 TSC code to mark clocksources as unstable; |
| 157 | * cpu hotplug code to avoid a deadlock between the clocksource mutex | 177 | * it defers demotion and re-selection to a kthread. |
| 158 | * and the cpu hotplug mutex. It defers the update of the clocksource | ||
| 159 | * to the watchdog thread. | ||
| 160 | */ | 178 | */ |
| 161 | void clocksource_mark_unstable(struct clocksource *cs) | 179 | void clocksource_mark_unstable(struct clocksource *cs) |
| 162 | { | 180 | { |
| @@ -164,7 +182,7 @@ void clocksource_mark_unstable(struct clocksource *cs) | |||
| 164 | 182 | ||
| 165 | spin_lock_irqsave(&watchdog_lock, flags); | 183 | spin_lock_irqsave(&watchdog_lock, flags); |
| 166 | if (!(cs->flags & CLOCK_SOURCE_UNSTABLE)) { | 184 | if (!(cs->flags & CLOCK_SOURCE_UNSTABLE)) { |
| 167 | if (list_empty(&cs->wd_list)) | 185 | if (!list_empty(&cs->list) && list_empty(&cs->wd_list)) |
| 168 | list_add(&cs->wd_list, &watchdog_list); | 186 | list_add(&cs->wd_list, &watchdog_list); |
| 169 | __clocksource_unstable(cs); | 187 | __clocksource_unstable(cs); |
| 170 | } | 188 | } |
| @@ -319,9 +337,8 @@ static void clocksource_resume_watchdog(void) | |||
| 319 | 337 | ||
| 320 | static void clocksource_enqueue_watchdog(struct clocksource *cs) | 338 | static void clocksource_enqueue_watchdog(struct clocksource *cs) |
| 321 | { | 339 | { |
| 322 | unsigned long flags; | 340 | INIT_LIST_HEAD(&cs->wd_list); |
| 323 | 341 | ||
| 324 | spin_lock_irqsave(&watchdog_lock, flags); | ||
| 325 | if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { | 342 | if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { |
| 326 | /* cs is a clocksource to be watched. */ | 343 | /* cs is a clocksource to be watched. */ |
| 327 | list_add(&cs->wd_list, &watchdog_list); | 344 | list_add(&cs->wd_list, &watchdog_list); |
| @@ -331,7 +348,6 @@ static void clocksource_enqueue_watchdog(struct clocksource *cs) | |||
| 331 | if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) | 348 | if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) |
| 332 | cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES; | 349 | cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES; |
| 333 | } | 350 | } |
| 334 | spin_unlock_irqrestore(&watchdog_lock, flags); | ||
| 335 | } | 351 | } |
| 336 | 352 | ||
| 337 | static void clocksource_select_watchdog(bool fallback) | 353 | static void clocksource_select_watchdog(bool fallback) |
| @@ -373,9 +389,6 @@ static void clocksource_select_watchdog(bool fallback) | |||
| 373 | 389 | ||
| 374 | static void clocksource_dequeue_watchdog(struct clocksource *cs) | 390 | static void clocksource_dequeue_watchdog(struct clocksource *cs) |
| 375 | { | 391 | { |
| 376 | unsigned long flags; | ||
| 377 | |||
| 378 | spin_lock_irqsave(&watchdog_lock, flags); | ||
| 379 | if (cs != watchdog) { | 392 | if (cs != watchdog) { |
| 380 | if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { | 393 | if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { |
| 381 | /* cs is a watched clocksource. */ | 394 | /* cs is a watched clocksource. */ |
| @@ -384,21 +397,19 @@ static void clocksource_dequeue_watchdog(struct clocksource *cs) | |||
| 384 | clocksource_stop_watchdog(); | 397 | clocksource_stop_watchdog(); |
| 385 | } | 398 | } |
| 386 | } | 399 | } |
| 387 | spin_unlock_irqrestore(&watchdog_lock, flags); | ||
| 388 | } | 400 | } |
| 389 | 401 | ||
| 390 | static int __clocksource_watchdog_kthread(void) | 402 | static int __clocksource_watchdog_kthread(void) |
| 391 | { | 403 | { |
| 392 | struct clocksource *cs, *tmp; | 404 | struct clocksource *cs, *tmp; |
| 393 | unsigned long flags; | 405 | unsigned long flags; |
| 394 | LIST_HEAD(unstable); | ||
| 395 | int select = 0; | 406 | int select = 0; |
| 396 | 407 | ||
| 397 | spin_lock_irqsave(&watchdog_lock, flags); | 408 | spin_lock_irqsave(&watchdog_lock, flags); |
| 398 | list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) { | 409 | list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) { |
| 399 | if (cs->flags & CLOCK_SOURCE_UNSTABLE) { | 410 | if (cs->flags & CLOCK_SOURCE_UNSTABLE) { |
| 400 | list_del_init(&cs->wd_list); | 411 | list_del_init(&cs->wd_list); |
| 401 | list_add(&cs->wd_list, &unstable); | 412 | __clocksource_change_rating(cs, 0); |
| 402 | select = 1; | 413 | select = 1; |
| 403 | } | 414 | } |
| 404 | if (cs->flags & CLOCK_SOURCE_RESELECT) { | 415 | if (cs->flags & CLOCK_SOURCE_RESELECT) { |
| @@ -410,11 +421,6 @@ static int __clocksource_watchdog_kthread(void) | |||
| 410 | clocksource_stop_watchdog(); | 421 | clocksource_stop_watchdog(); |
| 411 | spin_unlock_irqrestore(&watchdog_lock, flags); | 422 | spin_unlock_irqrestore(&watchdog_lock, flags); |
| 412 | 423 | ||
| 413 | /* Needs to be done outside of watchdog lock */ | ||
| 414 | list_for_each_entry_safe(cs, tmp, &unstable, wd_list) { | ||
| 415 | list_del_init(&cs->wd_list); | ||
| 416 | __clocksource_change_rating(cs, 0); | ||
| 417 | } | ||
| 418 | return select; | 424 | return select; |
| 419 | } | 425 | } |
| 420 | 426 | ||
| @@ -447,6 +453,9 @@ static inline int __clocksource_watchdog_kthread(void) { return 0; } | |||
| 447 | static bool clocksource_is_watchdog(struct clocksource *cs) { return false; } | 453 | static bool clocksource_is_watchdog(struct clocksource *cs) { return false; } |
| 448 | void clocksource_mark_unstable(struct clocksource *cs) { } | 454 | void clocksource_mark_unstable(struct clocksource *cs) { } |
| 449 | 455 | ||
| 456 | static void inline clocksource_watchdog_lock(unsigned long *flags) { } | ||
| 457 | static void inline clocksource_watchdog_unlock(unsigned long *flags) { } | ||
| 458 | |||
| 450 | #endif /* CONFIG_CLOCKSOURCE_WATCHDOG */ | 459 | #endif /* CONFIG_CLOCKSOURCE_WATCHDOG */ |
| 451 | 460 | ||
| 452 | /** | 461 | /** |
| @@ -779,14 +788,19 @@ EXPORT_SYMBOL_GPL(__clocksource_update_freq_scale); | |||
| 779 | */ | 788 | */ |
| 780 | int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) | 789 | int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) |
| 781 | { | 790 | { |
| 791 | unsigned long flags; | ||
| 782 | 792 | ||
| 783 | /* Initialize mult/shift and max_idle_ns */ | 793 | /* Initialize mult/shift and max_idle_ns */ |
| 784 | __clocksource_update_freq_scale(cs, scale, freq); | 794 | __clocksource_update_freq_scale(cs, scale, freq); |
| 785 | 795 | ||
| 786 | /* Add clocksource to the clocksource list */ | 796 | /* Add clocksource to the clocksource list */ |
| 787 | mutex_lock(&clocksource_mutex); | 797 | mutex_lock(&clocksource_mutex); |
| 798 | |||
| 799 | clocksource_watchdog_lock(&flags); | ||
| 788 | clocksource_enqueue(cs); | 800 | clocksource_enqueue(cs); |
| 789 | clocksource_enqueue_watchdog(cs); | 801 | clocksource_enqueue_watchdog(cs); |
| 802 | clocksource_watchdog_unlock(&flags); | ||
| 803 | |||
| 790 | clocksource_select(); | 804 | clocksource_select(); |
| 791 | clocksource_select_watchdog(false); | 805 | clocksource_select_watchdog(false); |
| 792 | mutex_unlock(&clocksource_mutex); | 806 | mutex_unlock(&clocksource_mutex); |
| @@ -808,8 +822,13 @@ static void __clocksource_change_rating(struct clocksource *cs, int rating) | |||
| 808 | */ | 822 | */ |
| 809 | void clocksource_change_rating(struct clocksource *cs, int rating) | 823 | void clocksource_change_rating(struct clocksource *cs, int rating) |
| 810 | { | 824 | { |
| 825 | unsigned long flags; | ||
| 826 | |||
| 811 | mutex_lock(&clocksource_mutex); | 827 | mutex_lock(&clocksource_mutex); |
| 828 | clocksource_watchdog_lock(&flags); | ||
| 812 | __clocksource_change_rating(cs, rating); | 829 | __clocksource_change_rating(cs, rating); |
| 830 | clocksource_watchdog_unlock(&flags); | ||
| 831 | |||
| 813 | clocksource_select(); | 832 | clocksource_select(); |
| 814 | clocksource_select_watchdog(false); | 833 | clocksource_select_watchdog(false); |
| 815 | mutex_unlock(&clocksource_mutex); | 834 | mutex_unlock(&clocksource_mutex); |
| @@ -821,6 +840,8 @@ EXPORT_SYMBOL(clocksource_change_rating); | |||
| 821 | */ | 840 | */ |
| 822 | static int clocksource_unbind(struct clocksource *cs) | 841 | static int clocksource_unbind(struct clocksource *cs) |
| 823 | { | 842 | { |
| 843 | unsigned long flags; | ||
| 844 | |||
| 824 | if (clocksource_is_watchdog(cs)) { | 845 | if (clocksource_is_watchdog(cs)) { |
| 825 | /* Select and try to install a replacement watchdog. */ | 846 | /* Select and try to install a replacement watchdog. */ |
| 826 | clocksource_select_watchdog(true); | 847 | clocksource_select_watchdog(true); |
| @@ -834,8 +855,12 @@ static int clocksource_unbind(struct clocksource *cs) | |||
| 834 | if (curr_clocksource == cs) | 855 | if (curr_clocksource == cs) |
| 835 | return -EBUSY; | 856 | return -EBUSY; |
| 836 | } | 857 | } |
| 858 | |||
| 859 | clocksource_watchdog_lock(&flags); | ||
| 837 | clocksource_dequeue_watchdog(cs); | 860 | clocksource_dequeue_watchdog(cs); |
| 838 | list_del_init(&cs->list); | 861 | list_del_init(&cs->list); |
| 862 | clocksource_watchdog_unlock(&flags); | ||
| 863 | |||
| 839 | return 0; | 864 | return 0; |
| 840 | } | 865 | } |
| 841 | 866 | ||
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index b398c2ea69b2..aa2094d5dd27 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
| @@ -612,6 +612,14 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) | |||
| 612 | now = ktime_get(); | 612 | now = ktime_get(); |
| 613 | /* Find all expired events */ | 613 | /* Find all expired events */ |
| 614 | for_each_cpu(cpu, tick_broadcast_oneshot_mask) { | 614 | for_each_cpu(cpu, tick_broadcast_oneshot_mask) { |
| 615 | /* | ||
| 616 | * Required for !SMP because for_each_cpu() reports | ||
| 617 | * unconditionally CPU0 as set on UP kernels. | ||
| 618 | */ | ||
| 619 | if (!IS_ENABLED(CONFIG_SMP) && | ||
| 620 | cpumask_empty(tick_broadcast_oneshot_mask)) | ||
| 621 | break; | ||
| 622 | |||
| 615 | td = &per_cpu(tick_cpu_device, cpu); | 623 | td = &per_cpu(tick_cpu_device, cpu); |
| 616 | if (td->evtdev->next_event <= now) { | 624 | if (td->evtdev->next_event <= now) { |
| 617 | cpumask_set_cpu(cpu, tmpmask); | 625 | cpumask_set_cpu(cpu, tmpmask); |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 16bbf062018f..8d83bcf9ef69 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -5514,10 +5514,10 @@ static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer) | |||
| 5514 | ftrace_create_filter_files(&global_ops, d_tracer); | 5514 | ftrace_create_filter_files(&global_ops, d_tracer); |
| 5515 | 5515 | ||
| 5516 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 5516 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 5517 | trace_create_file("set_graph_function", 0444, d_tracer, | 5517 | trace_create_file("set_graph_function", 0644, d_tracer, |
| 5518 | NULL, | 5518 | NULL, |
| 5519 | &ftrace_graph_fops); | 5519 | &ftrace_graph_fops); |
| 5520 | trace_create_file("set_graph_notrace", 0444, d_tracer, | 5520 | trace_create_file("set_graph_notrace", 0644, d_tracer, |
| 5521 | NULL, | 5521 | NULL, |
| 5522 | &ftrace_graph_notrace_fops); | 5522 | &ftrace_graph_notrace_fops); |
| 5523 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 5523 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 1f951b3df60c..7d306b74230f 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
| @@ -762,6 +762,9 @@ static int regex_match_full(char *str, struct regex *r, int len) | |||
| 762 | 762 | ||
| 763 | static int regex_match_front(char *str, struct regex *r, int len) | 763 | static int regex_match_front(char *str, struct regex *r, int len) |
| 764 | { | 764 | { |
| 765 | if (len < r->len) | ||
| 766 | return 0; | ||
| 767 | |||
| 765 | if (strncmp(str, r->pattern, r->len) == 0) | 768 | if (strncmp(str, r->pattern, r->len) == 0) |
| 766 | return 1; | 769 | return 1; |
| 767 | return 0; | 770 | return 0; |
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 0d7b3ffbecc2..b9061ed59bbd 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c | |||
| @@ -2466,6 +2466,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, | |||
| 2466 | else if (strcmp(modifier, "usecs") == 0) | 2466 | else if (strcmp(modifier, "usecs") == 0) |
| 2467 | *flags |= HIST_FIELD_FL_TIMESTAMP_USECS; | 2467 | *flags |= HIST_FIELD_FL_TIMESTAMP_USECS; |
| 2468 | else { | 2468 | else { |
| 2469 | hist_err("Invalid field modifier: ", modifier); | ||
| 2469 | field = ERR_PTR(-EINVAL); | 2470 | field = ERR_PTR(-EINVAL); |
| 2470 | goto out; | 2471 | goto out; |
| 2471 | } | 2472 | } |
| @@ -2481,6 +2482,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, | |||
| 2481 | else { | 2482 | else { |
| 2482 | field = trace_find_event_field(file->event_call, field_name); | 2483 | field = trace_find_event_field(file->event_call, field_name); |
| 2483 | if (!field || !field->size) { | 2484 | if (!field || !field->size) { |
| 2485 | hist_err("Couldn't find field: ", field_name); | ||
| 2484 | field = ERR_PTR(-EINVAL); | 2486 | field = ERR_PTR(-EINVAL); |
| 2485 | goto out; | 2487 | goto out; |
| 2486 | } | 2488 | } |
| @@ -4913,6 +4915,16 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) | |||
| 4913 | seq_printf(m, "%s", field_name); | 4915 | seq_printf(m, "%s", field_name); |
| 4914 | } else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) | 4916 | } else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP) |
| 4915 | seq_puts(m, "common_timestamp"); | 4917 | seq_puts(m, "common_timestamp"); |
| 4918 | |||
| 4919 | if (hist_field->flags) { | ||
| 4920 | if (!(hist_field->flags & HIST_FIELD_FL_VAR_REF) && | ||
| 4921 | !(hist_field->flags & HIST_FIELD_FL_EXPR)) { | ||
| 4922 | const char *flags = get_hist_field_flags(hist_field); | ||
| 4923 | |||
| 4924 | if (flags) | ||
| 4925 | seq_printf(m, ".%s", flags); | ||
| 4926 | } | ||
| 4927 | } | ||
| 4916 | } | 4928 | } |
| 4917 | 4929 | ||
| 4918 | static int event_hist_trigger_print(struct seq_file *m, | 4930 | static int event_hist_trigger_print(struct seq_file *m, |
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 3c7bfc4bf5e9..4237eba4ef20 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c | |||
| @@ -472,7 +472,7 @@ static __init int stack_trace_init(void) | |||
| 472 | NULL, &stack_trace_fops); | 472 | NULL, &stack_trace_fops); |
| 473 | 473 | ||
| 474 | #ifdef CONFIG_DYNAMIC_FTRACE | 474 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 475 | trace_create_file("stack_trace_filter", 0444, d_tracer, | 475 | trace_create_file("stack_trace_filter", 0644, d_tracer, |
| 476 | &trace_ops, &stack_trace_filter_fops); | 476 | &trace_ops, &stack_trace_filter_fops); |
| 477 | #endif | 477 | #endif |
| 478 | 478 | ||
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 34fd0e0ec51d..ac892878dbe6 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
| @@ -55,6 +55,7 @@ struct trace_uprobe { | |||
| 55 | struct list_head list; | 55 | struct list_head list; |
| 56 | struct trace_uprobe_filter filter; | 56 | struct trace_uprobe_filter filter; |
| 57 | struct uprobe_consumer consumer; | 57 | struct uprobe_consumer consumer; |
| 58 | struct path path; | ||
| 58 | struct inode *inode; | 59 | struct inode *inode; |
| 59 | char *filename; | 60 | char *filename; |
| 60 | unsigned long offset; | 61 | unsigned long offset; |
| @@ -289,7 +290,7 @@ static void free_trace_uprobe(struct trace_uprobe *tu) | |||
| 289 | for (i = 0; i < tu->tp.nr_args; i++) | 290 | for (i = 0; i < tu->tp.nr_args; i++) |
| 290 | traceprobe_free_probe_arg(&tu->tp.args[i]); | 291 | traceprobe_free_probe_arg(&tu->tp.args[i]); |
| 291 | 292 | ||
| 292 | iput(tu->inode); | 293 | path_put(&tu->path); |
| 293 | kfree(tu->tp.call.class->system); | 294 | kfree(tu->tp.call.class->system); |
| 294 | kfree(tu->tp.call.name); | 295 | kfree(tu->tp.call.name); |
| 295 | kfree(tu->filename); | 296 | kfree(tu->filename); |
| @@ -363,7 +364,6 @@ end: | |||
| 363 | static int create_trace_uprobe(int argc, char **argv) | 364 | static int create_trace_uprobe(int argc, char **argv) |
| 364 | { | 365 | { |
| 365 | struct trace_uprobe *tu; | 366 | struct trace_uprobe *tu; |
| 366 | struct inode *inode; | ||
| 367 | char *arg, *event, *group, *filename; | 367 | char *arg, *event, *group, *filename; |
| 368 | char buf[MAX_EVENT_NAME_LEN]; | 368 | char buf[MAX_EVENT_NAME_LEN]; |
| 369 | struct path path; | 369 | struct path path; |
| @@ -371,7 +371,6 @@ static int create_trace_uprobe(int argc, char **argv) | |||
| 371 | bool is_delete, is_return; | 371 | bool is_delete, is_return; |
| 372 | int i, ret; | 372 | int i, ret; |
| 373 | 373 | ||
| 374 | inode = NULL; | ||
| 375 | ret = 0; | 374 | ret = 0; |
| 376 | is_delete = false; | 375 | is_delete = false; |
| 377 | is_return = false; | 376 | is_return = false; |
| @@ -437,21 +436,16 @@ static int create_trace_uprobe(int argc, char **argv) | |||
| 437 | } | 436 | } |
| 438 | /* Find the last occurrence, in case the path contains ':' too. */ | 437 | /* Find the last occurrence, in case the path contains ':' too. */ |
| 439 | arg = strrchr(argv[1], ':'); | 438 | arg = strrchr(argv[1], ':'); |
| 440 | if (!arg) { | 439 | if (!arg) |
| 441 | ret = -EINVAL; | 440 | return -EINVAL; |
| 442 | goto fail_address_parse; | ||
| 443 | } | ||
| 444 | 441 | ||
| 445 | *arg++ = '\0'; | 442 | *arg++ = '\0'; |
| 446 | filename = argv[1]; | 443 | filename = argv[1]; |
| 447 | ret = kern_path(filename, LOOKUP_FOLLOW, &path); | 444 | ret = kern_path(filename, LOOKUP_FOLLOW, &path); |
| 448 | if (ret) | 445 | if (ret) |
| 449 | goto fail_address_parse; | 446 | return ret; |
| 450 | |||
| 451 | inode = igrab(d_real_inode(path.dentry)); | ||
| 452 | path_put(&path); | ||
| 453 | 447 | ||
| 454 | if (!inode || !S_ISREG(inode->i_mode)) { | 448 | if (!d_is_reg(path.dentry)) { |
| 455 | ret = -EINVAL; | 449 | ret = -EINVAL; |
| 456 | goto fail_address_parse; | 450 | goto fail_address_parse; |
| 457 | } | 451 | } |
| @@ -490,7 +484,7 @@ static int create_trace_uprobe(int argc, char **argv) | |||
| 490 | goto fail_address_parse; | 484 | goto fail_address_parse; |
| 491 | } | 485 | } |
| 492 | tu->offset = offset; | 486 | tu->offset = offset; |
| 493 | tu->inode = inode; | 487 | tu->path = path; |
| 494 | tu->filename = kstrdup(filename, GFP_KERNEL); | 488 | tu->filename = kstrdup(filename, GFP_KERNEL); |
| 495 | 489 | ||
| 496 | if (!tu->filename) { | 490 | if (!tu->filename) { |
| @@ -558,7 +552,7 @@ error: | |||
| 558 | return ret; | 552 | return ret; |
| 559 | 553 | ||
| 560 | fail_address_parse: | 554 | fail_address_parse: |
| 561 | iput(inode); | 555 | path_put(&path); |
| 562 | 556 | ||
| 563 | pr_info("Failed to parse address or file.\n"); | 557 | pr_info("Failed to parse address or file.\n"); |
| 564 | 558 | ||
| @@ -922,6 +916,7 @@ probe_event_enable(struct trace_uprobe *tu, struct trace_event_file *file, | |||
| 922 | goto err_flags; | 916 | goto err_flags; |
| 923 | 917 | ||
| 924 | tu->consumer.filter = filter; | 918 | tu->consumer.filter = filter; |
| 919 | tu->inode = d_real_inode(tu->path.dentry); | ||
| 925 | ret = uprobe_register(tu->inode, tu->offset, &tu->consumer); | 920 | ret = uprobe_register(tu->inode, tu->offset, &tu->consumer); |
| 926 | if (ret) | 921 | if (ret) |
| 927 | goto err_buffer; | 922 | goto err_buffer; |
| @@ -967,6 +962,7 @@ probe_event_disable(struct trace_uprobe *tu, struct trace_event_file *file) | |||
| 967 | WARN_ON(!uprobe_filter_is_empty(&tu->filter)); | 962 | WARN_ON(!uprobe_filter_is_empty(&tu->filter)); |
| 968 | 963 | ||
| 969 | uprobe_unregister(tu->inode, tu->offset, &tu->consumer); | 964 | uprobe_unregister(tu->inode, tu->offset, &tu->consumer); |
| 965 | tu->inode = NULL; | ||
| 970 | tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE; | 966 | tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE; |
| 971 | 967 | ||
| 972 | uprobe_buffer_disable(); | 968 | uprobe_buffer_disable(); |
| @@ -1337,7 +1333,6 @@ struct trace_event_call * | |||
| 1337 | create_local_trace_uprobe(char *name, unsigned long offs, bool is_return) | 1333 | create_local_trace_uprobe(char *name, unsigned long offs, bool is_return) |
| 1338 | { | 1334 | { |
| 1339 | struct trace_uprobe *tu; | 1335 | struct trace_uprobe *tu; |
| 1340 | struct inode *inode; | ||
| 1341 | struct path path; | 1336 | struct path path; |
| 1342 | int ret; | 1337 | int ret; |
| 1343 | 1338 | ||
| @@ -1345,11 +1340,8 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return) | |||
| 1345 | if (ret) | 1340 | if (ret) |
| 1346 | return ERR_PTR(ret); | 1341 | return ERR_PTR(ret); |
| 1347 | 1342 | ||
| 1348 | inode = igrab(d_inode(path.dentry)); | 1343 | if (!d_is_reg(path.dentry)) { |
| 1349 | path_put(&path); | 1344 | path_put(&path); |
| 1350 | |||
| 1351 | if (!inode || !S_ISREG(inode->i_mode)) { | ||
| 1352 | iput(inode); | ||
| 1353 | return ERR_PTR(-EINVAL); | 1345 | return ERR_PTR(-EINVAL); |
| 1354 | } | 1346 | } |
| 1355 | 1347 | ||
| @@ -1364,11 +1356,12 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return) | |||
| 1364 | if (IS_ERR(tu)) { | 1356 | if (IS_ERR(tu)) { |
| 1365 | pr_info("Failed to allocate trace_uprobe.(%d)\n", | 1357 | pr_info("Failed to allocate trace_uprobe.(%d)\n", |
| 1366 | (int)PTR_ERR(tu)); | 1358 | (int)PTR_ERR(tu)); |
| 1359 | path_put(&path); | ||
| 1367 | return ERR_CAST(tu); | 1360 | return ERR_CAST(tu); |
| 1368 | } | 1361 | } |
| 1369 | 1362 | ||
| 1370 | tu->offset = offs; | 1363 | tu->offset = offs; |
| 1371 | tu->inode = inode; | 1364 | tu->path = path; |
| 1372 | tu->filename = kstrdup(name, GFP_KERNEL); | 1365 | tu->filename = kstrdup(name, GFP_KERNEL); |
| 1373 | init_trace_event_call(tu, &tu->tp.call); | 1366 | init_trace_event_call(tu, &tu->tp.call); |
| 1374 | 1367 | ||
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 671b13457387..1e37da2e0c25 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
| @@ -207,7 +207,7 @@ static int tracepoint_add_func(struct tracepoint *tp, | |||
| 207 | lockdep_is_held(&tracepoints_mutex)); | 207 | lockdep_is_held(&tracepoints_mutex)); |
| 208 | old = func_add(&tp_funcs, func, prio); | 208 | old = func_add(&tp_funcs, func, prio); |
| 209 | if (IS_ERR(old)) { | 209 | if (IS_ERR(old)) { |
| 210 | WARN_ON_ONCE(1); | 210 | WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM); |
| 211 | return PTR_ERR(old); | 211 | return PTR_ERR(old); |
| 212 | } | 212 | } |
| 213 | 213 | ||
| @@ -239,7 +239,7 @@ static int tracepoint_remove_func(struct tracepoint *tp, | |||
| 239 | lockdep_is_held(&tracepoints_mutex)); | 239 | lockdep_is_held(&tracepoints_mutex)); |
| 240 | old = func_remove(&tp_funcs, func); | 240 | old = func_remove(&tp_funcs, func); |
| 241 | if (IS_ERR(old)) { | 241 | if (IS_ERR(old)) { |
| 242 | WARN_ON_ONCE(1); | 242 | WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM); |
| 243 | return PTR_ERR(old); | 243 | return PTR_ERR(old); |
| 244 | } | 244 | } |
| 245 | 245 | ||
diff --git a/lib/errseq.c b/lib/errseq.c index df782418b333..81f9e33aa7e7 100644 --- a/lib/errseq.c +++ b/lib/errseq.c | |||
| @@ -111,27 +111,22 @@ EXPORT_SYMBOL(errseq_set); | |||
| 111 | * errseq_sample() - Grab current errseq_t value. | 111 | * errseq_sample() - Grab current errseq_t value. |
| 112 | * @eseq: Pointer to errseq_t to be sampled. | 112 | * @eseq: Pointer to errseq_t to be sampled. |
| 113 | * | 113 | * |
| 114 | * This function allows callers to sample an errseq_t value, marking it as | 114 | * This function allows callers to initialise their errseq_t variable. |
| 115 | * "seen" if required. | 115 | * If the error has been "seen", new callers will not see an old error. |
| 116 | * If there is an unseen error in @eseq, the caller of this function will | ||
| 117 | * see it the next time it checks for an error. | ||
| 116 | * | 118 | * |
| 119 | * Context: Any context. | ||
| 117 | * Return: The current errseq value. | 120 | * Return: The current errseq value. |
| 118 | */ | 121 | */ |
| 119 | errseq_t errseq_sample(errseq_t *eseq) | 122 | errseq_t errseq_sample(errseq_t *eseq) |
| 120 | { | 123 | { |
| 121 | errseq_t old = READ_ONCE(*eseq); | 124 | errseq_t old = READ_ONCE(*eseq); |
| 122 | errseq_t new = old; | ||
| 123 | 125 | ||
| 124 | /* | 126 | /* If nobody has seen this error yet, then we can be the first. */ |
| 125 | * For the common case of no errors ever having been set, we can skip | 127 | if (!(old & ERRSEQ_SEEN)) |
| 126 | * marking the SEEN bit. Once an error has been set, the value will | 128 | old = 0; |
| 127 | * never go back to zero. | 129 | return old; |
| 128 | */ | ||
| 129 | if (old != 0) { | ||
| 130 | new |= ERRSEQ_SEEN; | ||
| 131 | if (old != new) | ||
| 132 | cmpxchg(eseq, old, new); | ||
| 133 | } | ||
| 134 | return new; | ||
| 135 | } | 130 | } |
| 136 | EXPORT_SYMBOL(errseq_sample); | 131 | EXPORT_SYMBOL(errseq_sample); |
| 137 | 132 | ||
diff --git a/lib/find_bit_benchmark.c b/lib/find_bit_benchmark.c index 5985a25e6cbc..5367ffa5c18f 100644 --- a/lib/find_bit_benchmark.c +++ b/lib/find_bit_benchmark.c | |||
| @@ -132,7 +132,12 @@ static int __init find_bit_test(void) | |||
| 132 | test_find_next_bit(bitmap, BITMAP_LEN); | 132 | test_find_next_bit(bitmap, BITMAP_LEN); |
| 133 | test_find_next_zero_bit(bitmap, BITMAP_LEN); | 133 | test_find_next_zero_bit(bitmap, BITMAP_LEN); |
| 134 | test_find_last_bit(bitmap, BITMAP_LEN); | 134 | test_find_last_bit(bitmap, BITMAP_LEN); |
| 135 | test_find_first_bit(bitmap, BITMAP_LEN); | 135 | |
| 136 | /* | ||
| 137 | * test_find_first_bit() may take some time, so | ||
| 138 | * traverse only part of bitmap to avoid soft lockup. | ||
| 139 | */ | ||
| 140 | test_find_first_bit(bitmap, BITMAP_LEN / 10); | ||
| 136 | test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN); | 141 | test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN); |
| 137 | 142 | ||
| 138 | pr_err("\nStart testing find_bit() with sparse bitmap\n"); | 143 | pr_err("\nStart testing find_bit() with sparse bitmap\n"); |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index da9e10c827df..43e0cbedc3a0 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
| @@ -1612,11 +1612,9 @@ static void set_iter_tags(struct radix_tree_iter *iter, | |||
| 1612 | static void __rcu **skip_siblings(struct radix_tree_node **nodep, | 1612 | static void __rcu **skip_siblings(struct radix_tree_node **nodep, |
| 1613 | void __rcu **slot, struct radix_tree_iter *iter) | 1613 | void __rcu **slot, struct radix_tree_iter *iter) |
| 1614 | { | 1614 | { |
| 1615 | void *sib = node_to_entry(slot - 1); | ||
| 1616 | |||
| 1617 | while (iter->index < iter->next_index) { | 1615 | while (iter->index < iter->next_index) { |
| 1618 | *nodep = rcu_dereference_raw(*slot); | 1616 | *nodep = rcu_dereference_raw(*slot); |
| 1619 | if (*nodep && *nodep != sib) | 1617 | if (*nodep && !is_sibling_entry(iter->node, *nodep)) |
| 1620 | return slot; | 1618 | return slot; |
| 1621 | slot++; | 1619 | slot++; |
| 1622 | iter->index = __radix_tree_iter_add(iter, 1); | 1620 | iter->index = __radix_tree_iter_add(iter, 1); |
| @@ -1631,7 +1629,7 @@ void __rcu **__radix_tree_next_slot(void __rcu **slot, | |||
| 1631 | struct radix_tree_iter *iter, unsigned flags) | 1629 | struct radix_tree_iter *iter, unsigned flags) |
| 1632 | { | 1630 | { |
| 1633 | unsigned tag = flags & RADIX_TREE_ITER_TAG_MASK; | 1631 | unsigned tag = flags & RADIX_TREE_ITER_TAG_MASK; |
| 1634 | struct radix_tree_node *node = rcu_dereference_raw(*slot); | 1632 | struct radix_tree_node *node; |
| 1635 | 1633 | ||
| 1636 | slot = skip_siblings(&node, slot, iter); | 1634 | slot = skip_siblings(&node, slot, iter); |
| 1637 | 1635 | ||
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index fece57566d45..cc640588f145 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
| @@ -714,7 +714,7 @@ swiotlb_alloc_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
| 714 | 714 | ||
| 715 | phys_addr = swiotlb_tbl_map_single(dev, | 715 | phys_addr = swiotlb_tbl_map_single(dev, |
| 716 | __phys_to_dma(dev, io_tlb_start), | 716 | __phys_to_dma(dev, io_tlb_start), |
| 717 | 0, size, DMA_FROM_DEVICE, 0); | 717 | 0, size, DMA_FROM_DEVICE, attrs); |
| 718 | if (phys_addr == SWIOTLB_MAP_ERROR) | 718 | if (phys_addr == SWIOTLB_MAP_ERROR) |
| 719 | goto out_warn; | 719 | goto out_warn; |
| 720 | 720 | ||
| @@ -737,7 +737,7 @@ out_unmap: | |||
| 737 | swiotlb_tbl_unmap_single(dev, phys_addr, size, DMA_TO_DEVICE, | 737 | swiotlb_tbl_unmap_single(dev, phys_addr, size, DMA_TO_DEVICE, |
| 738 | DMA_ATTR_SKIP_CPU_SYNC); | 738 | DMA_ATTR_SKIP_CPU_SYNC); |
| 739 | out_warn: | 739 | out_warn: |
| 740 | if ((attrs & DMA_ATTR_NO_WARN) && printk_ratelimit()) { | 740 | if (!(attrs & DMA_ATTR_NO_WARN) && printk_ratelimit()) { |
| 741 | dev_warn(dev, | 741 | dev_warn(dev, |
| 742 | "swiotlb: coherent allocation failed, size=%zu\n", | 742 | "swiotlb: coherent allocation failed, size=%zu\n", |
| 743 | size); | 743 | size); |
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c index de16f7869fb1..6cd7d0740005 100644 --- a/lib/test_bitmap.c +++ b/lib/test_bitmap.c | |||
| @@ -331,23 +331,32 @@ static void noinline __init test_mem_optimisations(void) | |||
| 331 | unsigned int start, nbits; | 331 | unsigned int start, nbits; |
| 332 | 332 | ||
| 333 | for (start = 0; start < 1024; start += 8) { | 333 | for (start = 0; start < 1024; start += 8) { |
| 334 | memset(bmap1, 0x5a, sizeof(bmap1)); | ||
| 335 | memset(bmap2, 0x5a, sizeof(bmap2)); | ||
| 336 | for (nbits = 0; nbits < 1024 - start; nbits += 8) { | 334 | for (nbits = 0; nbits < 1024 - start; nbits += 8) { |
| 335 | memset(bmap1, 0x5a, sizeof(bmap1)); | ||
| 336 | memset(bmap2, 0x5a, sizeof(bmap2)); | ||
| 337 | |||
| 337 | bitmap_set(bmap1, start, nbits); | 338 | bitmap_set(bmap1, start, nbits); |
| 338 | __bitmap_set(bmap2, start, nbits); | 339 | __bitmap_set(bmap2, start, nbits); |
| 339 | if (!bitmap_equal(bmap1, bmap2, 1024)) | 340 | if (!bitmap_equal(bmap1, bmap2, 1024)) { |
| 340 | printk("set not equal %d %d\n", start, nbits); | 341 | printk("set not equal %d %d\n", start, nbits); |
| 341 | if (!__bitmap_equal(bmap1, bmap2, 1024)) | 342 | failed_tests++; |
| 343 | } | ||
| 344 | if (!__bitmap_equal(bmap1, bmap2, 1024)) { | ||
| 342 | printk("set not __equal %d %d\n", start, nbits); | 345 | printk("set not __equal %d %d\n", start, nbits); |
| 346 | failed_tests++; | ||
| 347 | } | ||
| 343 | 348 | ||
| 344 | bitmap_clear(bmap1, start, nbits); | 349 | bitmap_clear(bmap1, start, nbits); |
| 345 | __bitmap_clear(bmap2, start, nbits); | 350 | __bitmap_clear(bmap2, start, nbits); |
| 346 | if (!bitmap_equal(bmap1, bmap2, 1024)) | 351 | if (!bitmap_equal(bmap1, bmap2, 1024)) { |
| 347 | printk("clear not equal %d %d\n", start, nbits); | 352 | printk("clear not equal %d %d\n", start, nbits); |
| 348 | if (!__bitmap_equal(bmap1, bmap2, 1024)) | 353 | failed_tests++; |
| 354 | } | ||
| 355 | if (!__bitmap_equal(bmap1, bmap2, 1024)) { | ||
| 349 | printk("clear not __equal %d %d\n", start, | 356 | printk("clear not __equal %d %d\n", start, |
| 350 | nbits); | 357 | nbits); |
| 358 | failed_tests++; | ||
| 359 | } | ||
| 351 | } | 360 | } |
| 352 | } | 361 | } |
| 353 | } | 362 | } |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 30c0cb8cc9bc..23920c5ff728 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -1669,19 +1669,22 @@ char *pointer_string(char *buf, char *end, const void *ptr, | |||
| 1669 | return number(buf, end, (unsigned long int)ptr, spec); | 1669 | return number(buf, end, (unsigned long int)ptr, spec); |
| 1670 | } | 1670 | } |
| 1671 | 1671 | ||
| 1672 | static bool have_filled_random_ptr_key __read_mostly; | 1672 | static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key); |
| 1673 | static siphash_key_t ptr_key __read_mostly; | 1673 | static siphash_key_t ptr_key __read_mostly; |
| 1674 | 1674 | ||
| 1675 | static void fill_random_ptr_key(struct random_ready_callback *unused) | 1675 | static void enable_ptr_key_workfn(struct work_struct *work) |
| 1676 | { | 1676 | { |
| 1677 | get_random_bytes(&ptr_key, sizeof(ptr_key)); | 1677 | get_random_bytes(&ptr_key, sizeof(ptr_key)); |
| 1678 | /* | 1678 | /* Needs to run from preemptible context */ |
| 1679 | * have_filled_random_ptr_key==true is dependent on get_random_bytes(). | 1679 | static_branch_disable(¬_filled_random_ptr_key); |
| 1680 | * ptr_to_id() needs to see have_filled_random_ptr_key==true | 1680 | } |
| 1681 | * after get_random_bytes() returns. | 1681 | |
| 1682 | */ | 1682 | static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); |
| 1683 | smp_mb(); | 1683 | |
| 1684 | WRITE_ONCE(have_filled_random_ptr_key, true); | 1684 | static void fill_random_ptr_key(struct random_ready_callback *unused) |
| 1685 | { | ||
| 1686 | /* This may be in an interrupt handler. */ | ||
| 1687 | queue_work(system_unbound_wq, &enable_ptr_key_work); | ||
| 1685 | } | 1688 | } |
| 1686 | 1689 | ||
| 1687 | static struct random_ready_callback random_ready = { | 1690 | static struct random_ready_callback random_ready = { |
| @@ -1695,7 +1698,8 @@ static int __init initialize_ptr_random(void) | |||
| 1695 | if (!ret) { | 1698 | if (!ret) { |
| 1696 | return 0; | 1699 | return 0; |
| 1697 | } else if (ret == -EALREADY) { | 1700 | } else if (ret == -EALREADY) { |
| 1698 | fill_random_ptr_key(&random_ready); | 1701 | /* This is in preemptible context */ |
| 1702 | enable_ptr_key_workfn(&enable_ptr_key_work); | ||
| 1699 | return 0; | 1703 | return 0; |
| 1700 | } | 1704 | } |
| 1701 | 1705 | ||
| @@ -1709,7 +1713,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | |||
| 1709 | unsigned long hashval; | 1713 | unsigned long hashval; |
| 1710 | const int default_width = 2 * sizeof(ptr); | 1714 | const int default_width = 2 * sizeof(ptr); |
| 1711 | 1715 | ||
| 1712 | if (unlikely(!have_filled_random_ptr_key)) { | 1716 | if (static_branch_unlikely(¬_filled_random_ptr_key)) { |
| 1713 | spec.field_width = default_width; | 1717 | spec.field_width = default_width; |
| 1714 | /* string length must be less than default_width */ | 1718 | /* string length must be less than default_width */ |
| 1715 | return string(buf, end, "(ptrval)", spec); | 1719 | return string(buf, end, "(ptrval)", spec); |
diff --git a/mm/Kconfig b/mm/Kconfig index d5004d82a1d6..e14c01513bfd 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
| @@ -636,6 +636,7 @@ config DEFERRED_STRUCT_PAGE_INIT | |||
| 636 | default n | 636 | default n |
| 637 | depends on NO_BOOTMEM | 637 | depends on NO_BOOTMEM |
| 638 | depends on !FLATMEM | 638 | depends on !FLATMEM |
| 639 | depends on !NEED_PER_CPU_KM | ||
| 639 | help | 640 | help |
| 640 | Ordinarily all struct pages are initialised during early boot in a | 641 | Ordinarily all struct pages are initialised during early boot in a |
| 641 | single thread. On very large machines this can take a considerable | 642 | single thread. On very large machines this can take a considerable |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 023190c69dce..7441bd93b732 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
| @@ -115,6 +115,7 @@ static int bdi_debug_register(struct backing_dev_info *bdi, const char *name) | |||
| 115 | bdi, &bdi_debug_stats_fops); | 115 | bdi, &bdi_debug_stats_fops); |
| 116 | if (!bdi->debug_stats) { | 116 | if (!bdi->debug_stats) { |
| 117 | debugfs_remove(bdi->debug_dir); | 117 | debugfs_remove(bdi->debug_dir); |
| 118 | bdi->debug_dir = NULL; | ||
| 118 | return -ENOMEM; | 119 | return -ENOMEM; |
| 119 | } | 120 | } |
| 120 | 121 | ||
| @@ -383,7 +384,7 @@ static void wb_shutdown(struct bdi_writeback *wb) | |||
| 383 | * the barrier provided by test_and_clear_bit() above. | 384 | * the barrier provided by test_and_clear_bit() above. |
| 384 | */ | 385 | */ |
| 385 | smp_wmb(); | 386 | smp_wmb(); |
| 386 | clear_bit(WB_shutting_down, &wb->state); | 387 | clear_and_wake_up_bit(WB_shutting_down, &wb->state); |
| 387 | } | 388 | } |
| 388 | 389 | ||
| 389 | static void wb_exit(struct bdi_writeback *wb) | 390 | static void wb_exit(struct bdi_writeback *wb) |
| @@ -544,6 +544,9 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) | |||
| 544 | if (vm_flags & (VM_IO | VM_PFNMAP)) | 544 | if (vm_flags & (VM_IO | VM_PFNMAP)) |
| 545 | return -EFAULT; | 545 | return -EFAULT; |
| 546 | 546 | ||
| 547 | if (gup_flags & FOLL_ANON && !vma_is_anonymous(vma)) | ||
| 548 | return -EFAULT; | ||
| 549 | |||
| 547 | if (write) { | 550 | if (write) { |
| 548 | if (!(vm_flags & VM_WRITE)) { | 551 | if (!(vm_flags & VM_WRITE)) { |
| 549 | if (!(gup_flags & FOLL_FORCE)) | 552 | if (!(gup_flags & FOLL_FORCE)) |
diff --git a/mm/migrate.c b/mm/migrate.c index 568433023831..8c0af0f7cab1 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
| @@ -528,14 +528,12 @@ int migrate_page_move_mapping(struct address_space *mapping, | |||
| 528 | int i; | 528 | int i; |
| 529 | int index = page_index(page); | 529 | int index = page_index(page); |
| 530 | 530 | ||
| 531 | for (i = 0; i < HPAGE_PMD_NR; i++) { | 531 | for (i = 1; i < HPAGE_PMD_NR; i++) { |
| 532 | pslot = radix_tree_lookup_slot(&mapping->i_pages, | 532 | pslot = radix_tree_lookup_slot(&mapping->i_pages, |
| 533 | index + i); | 533 | index + i); |
| 534 | radix_tree_replace_slot(&mapping->i_pages, pslot, | 534 | radix_tree_replace_slot(&mapping->i_pages, pslot, |
| 535 | newpage + i); | 535 | newpage + i); |
| 536 | } | 536 | } |
| 537 | } else { | ||
| 538 | radix_tree_replace_slot(&mapping->i_pages, pslot, newpage); | ||
| 539 | } | 537 | } |
| 540 | 538 | ||
| 541 | /* | 539 | /* |
| @@ -1324,6 +1324,35 @@ static inline int mlock_future_check(struct mm_struct *mm, | |||
| 1324 | return 0; | 1324 | return 0; |
| 1325 | } | 1325 | } |
| 1326 | 1326 | ||
| 1327 | static inline u64 file_mmap_size_max(struct file *file, struct inode *inode) | ||
| 1328 | { | ||
| 1329 | if (S_ISREG(inode->i_mode)) | ||
| 1330 | return MAX_LFS_FILESIZE; | ||
| 1331 | |||
| 1332 | if (S_ISBLK(inode->i_mode)) | ||
| 1333 | return MAX_LFS_FILESIZE; | ||
| 1334 | |||
| 1335 | /* Special "we do even unsigned file positions" case */ | ||
| 1336 | if (file->f_mode & FMODE_UNSIGNED_OFFSET) | ||
| 1337 | return 0; | ||
| 1338 | |||
| 1339 | /* Yes, random drivers might want more. But I'm tired of buggy drivers */ | ||
| 1340 | return ULONG_MAX; | ||
| 1341 | } | ||
| 1342 | |||
| 1343 | static inline bool file_mmap_ok(struct file *file, struct inode *inode, | ||
| 1344 | unsigned long pgoff, unsigned long len) | ||
| 1345 | { | ||
| 1346 | u64 maxsize = file_mmap_size_max(file, inode); | ||
| 1347 | |||
| 1348 | if (maxsize && len > maxsize) | ||
| 1349 | return false; | ||
| 1350 | maxsize -= len; | ||
| 1351 | if (pgoff > maxsize >> PAGE_SHIFT) | ||
| 1352 | return false; | ||
| 1353 | return true; | ||
| 1354 | } | ||
| 1355 | |||
| 1327 | /* | 1356 | /* |
| 1328 | * The caller must hold down_write(¤t->mm->mmap_sem). | 1357 | * The caller must hold down_write(¤t->mm->mmap_sem). |
| 1329 | */ | 1358 | */ |
| @@ -1409,6 +1438,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, | |||
| 1409 | struct inode *inode = file_inode(file); | 1438 | struct inode *inode = file_inode(file); |
| 1410 | unsigned long flags_mask; | 1439 | unsigned long flags_mask; |
| 1411 | 1440 | ||
| 1441 | if (!file_mmap_ok(file, inode, pgoff, len)) | ||
| 1442 | return -EOVERFLOW; | ||
| 1443 | |||
| 1412 | flags_mask = LEGACY_MAP_MASK | file->f_op->mmap_supported_flags; | 1444 | flags_mask = LEGACY_MAP_MASK | file->f_op->mmap_supported_flags; |
| 1413 | 1445 | ||
| 1414 | switch (flags & MAP_TYPE) { | 1446 | switch (flags & MAP_TYPE) { |
| @@ -3024,6 +3056,32 @@ void exit_mmap(struct mm_struct *mm) | |||
| 3024 | /* mm's last user has gone, and its about to be pulled down */ | 3056 | /* mm's last user has gone, and its about to be pulled down */ |
| 3025 | mmu_notifier_release(mm); | 3057 | mmu_notifier_release(mm); |
| 3026 | 3058 | ||
| 3059 | if (unlikely(mm_is_oom_victim(mm))) { | ||
| 3060 | /* | ||
| 3061 | * Manually reap the mm to free as much memory as possible. | ||
| 3062 | * Then, as the oom reaper does, set MMF_OOM_SKIP to disregard | ||
| 3063 | * this mm from further consideration. Taking mm->mmap_sem for | ||
| 3064 | * write after setting MMF_OOM_SKIP will guarantee that the oom | ||
| 3065 | * reaper will not run on this mm again after mmap_sem is | ||
| 3066 | * dropped. | ||
| 3067 | * | ||
| 3068 | * Nothing can be holding mm->mmap_sem here and the above call | ||
| 3069 | * to mmu_notifier_release(mm) ensures mmu notifier callbacks in | ||
| 3070 | * __oom_reap_task_mm() will not block. | ||
| 3071 | * | ||
| 3072 | * This needs to be done before calling munlock_vma_pages_all(), | ||
| 3073 | * which clears VM_LOCKED, otherwise the oom reaper cannot | ||
| 3074 | * reliably test it. | ||
| 3075 | */ | ||
| 3076 | mutex_lock(&oom_lock); | ||
| 3077 | __oom_reap_task_mm(mm); | ||
| 3078 | mutex_unlock(&oom_lock); | ||
| 3079 | |||
| 3080 | set_bit(MMF_OOM_SKIP, &mm->flags); | ||
| 3081 | down_write(&mm->mmap_sem); | ||
| 3082 | up_write(&mm->mmap_sem); | ||
| 3083 | } | ||
| 3084 | |||
| 3027 | if (mm->locked_vm) { | 3085 | if (mm->locked_vm) { |
| 3028 | vma = mm->mmap; | 3086 | vma = mm->mmap; |
| 3029 | while (vma) { | 3087 | while (vma) { |
| @@ -3045,24 +3103,6 @@ void exit_mmap(struct mm_struct *mm) | |||
| 3045 | /* update_hiwater_rss(mm) here? but nobody should be looking */ | 3103 | /* update_hiwater_rss(mm) here? but nobody should be looking */ |
| 3046 | /* Use -1 here to ensure all VMAs in the mm are unmapped */ | 3104 | /* Use -1 here to ensure all VMAs in the mm are unmapped */ |
| 3047 | unmap_vmas(&tlb, vma, 0, -1); | 3105 | unmap_vmas(&tlb, vma, 0, -1); |
| 3048 | |||
| 3049 | if (unlikely(mm_is_oom_victim(mm))) { | ||
| 3050 | /* | ||
| 3051 | * Wait for oom_reap_task() to stop working on this | ||
| 3052 | * mm. Because MMF_OOM_SKIP is already set before | ||
| 3053 | * calling down_read(), oom_reap_task() will not run | ||
| 3054 | * on this "mm" post up_write(). | ||
| 3055 | * | ||
| 3056 | * mm_is_oom_victim() cannot be set from under us | ||
| 3057 | * either because victim->mm is already set to NULL | ||
| 3058 | * under task_lock before calling mmput and oom_mm is | ||
| 3059 | * set not NULL by the OOM killer only if victim->mm | ||
| 3060 | * is found not NULL while holding the task_lock. | ||
| 3061 | */ | ||
| 3062 | set_bit(MMF_OOM_SKIP, &mm->flags); | ||
| 3063 | down_write(&mm->mmap_sem); | ||
| 3064 | up_write(&mm->mmap_sem); | ||
| 3065 | } | ||
| 3066 | free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING); | 3106 | free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING); |
| 3067 | tlb_finish_mmu(&tlb, 0, -1); | 3107 | tlb_finish_mmu(&tlb, 0, -1); |
| 3068 | 3108 | ||
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index ff992fa8760a..8ba6cb88cf58 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
| @@ -469,7 +469,6 @@ bool process_shares_mm(struct task_struct *p, struct mm_struct *mm) | |||
| 469 | return false; | 469 | return false; |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | |||
| 473 | #ifdef CONFIG_MMU | 472 | #ifdef CONFIG_MMU |
| 474 | /* | 473 | /* |
| 475 | * OOM Reaper kernel thread which tries to reap the memory used by the OOM | 474 | * OOM Reaper kernel thread which tries to reap the memory used by the OOM |
| @@ -480,16 +479,54 @@ static DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait); | |||
| 480 | static struct task_struct *oom_reaper_list; | 479 | static struct task_struct *oom_reaper_list; |
| 481 | static DEFINE_SPINLOCK(oom_reaper_lock); | 480 | static DEFINE_SPINLOCK(oom_reaper_lock); |
| 482 | 481 | ||
| 483 | static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) | 482 | void __oom_reap_task_mm(struct mm_struct *mm) |
| 484 | { | 483 | { |
| 485 | struct mmu_gather tlb; | ||
| 486 | struct vm_area_struct *vma; | 484 | struct vm_area_struct *vma; |
| 485 | |||
| 486 | /* | ||
| 487 | * Tell all users of get_user/copy_from_user etc... that the content | ||
| 488 | * is no longer stable. No barriers really needed because unmapping | ||
| 489 | * should imply barriers already and the reader would hit a page fault | ||
| 490 | * if it stumbled over a reaped memory. | ||
| 491 | */ | ||
| 492 | set_bit(MMF_UNSTABLE, &mm->flags); | ||
| 493 | |||
| 494 | for (vma = mm->mmap ; vma; vma = vma->vm_next) { | ||
| 495 | if (!can_madv_dontneed_vma(vma)) | ||
| 496 | continue; | ||
| 497 | |||
| 498 | /* | ||
| 499 | * Only anonymous pages have a good chance to be dropped | ||
| 500 | * without additional steps which we cannot afford as we | ||
| 501 | * are OOM already. | ||
| 502 | * | ||
| 503 | * We do not even care about fs backed pages because all | ||
| 504 | * which are reclaimable have already been reclaimed and | ||
| 505 | * we do not want to block exit_mmap by keeping mm ref | ||
| 506 | * count elevated without a good reason. | ||
| 507 | */ | ||
| 508 | if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) { | ||
| 509 | const unsigned long start = vma->vm_start; | ||
| 510 | const unsigned long end = vma->vm_end; | ||
| 511 | struct mmu_gather tlb; | ||
| 512 | |||
| 513 | tlb_gather_mmu(&tlb, mm, start, end); | ||
| 514 | mmu_notifier_invalidate_range_start(mm, start, end); | ||
| 515 | unmap_page_range(&tlb, vma, start, end, NULL); | ||
| 516 | mmu_notifier_invalidate_range_end(mm, start, end); | ||
| 517 | tlb_finish_mmu(&tlb, start, end); | ||
| 518 | } | ||
| 519 | } | ||
| 520 | } | ||
| 521 | |||
| 522 | static bool oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) | ||
| 523 | { | ||
| 487 | bool ret = true; | 524 | bool ret = true; |
| 488 | 525 | ||
| 489 | /* | 526 | /* |
| 490 | * We have to make sure to not race with the victim exit path | 527 | * We have to make sure to not race with the victim exit path |
| 491 | * and cause premature new oom victim selection: | 528 | * and cause premature new oom victim selection: |
| 492 | * __oom_reap_task_mm exit_mm | 529 | * oom_reap_task_mm exit_mm |
| 493 | * mmget_not_zero | 530 | * mmget_not_zero |
| 494 | * mmput | 531 | * mmput |
| 495 | * atomic_dec_and_test | 532 | * atomic_dec_and_test |
| @@ -534,39 +571,8 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) | |||
| 534 | 571 | ||
| 535 | trace_start_task_reaping(tsk->pid); | 572 | trace_start_task_reaping(tsk->pid); |
| 536 | 573 | ||
| 537 | /* | 574 | __oom_reap_task_mm(mm); |
| 538 | * Tell all users of get_user/copy_from_user etc... that the content | ||
| 539 | * is no longer stable. No barriers really needed because unmapping | ||
| 540 | * should imply barriers already and the reader would hit a page fault | ||
| 541 | * if it stumbled over a reaped memory. | ||
| 542 | */ | ||
| 543 | set_bit(MMF_UNSTABLE, &mm->flags); | ||
| 544 | |||
| 545 | for (vma = mm->mmap ; vma; vma = vma->vm_next) { | ||
| 546 | if (!can_madv_dontneed_vma(vma)) | ||
| 547 | continue; | ||
| 548 | 575 | ||
| 549 | /* | ||
| 550 | * Only anonymous pages have a good chance to be dropped | ||
| 551 | * without additional steps which we cannot afford as we | ||
| 552 | * are OOM already. | ||
| 553 | * | ||
| 554 | * We do not even care about fs backed pages because all | ||
| 555 | * which are reclaimable have already been reclaimed and | ||
| 556 | * we do not want to block exit_mmap by keeping mm ref | ||
| 557 | * count elevated without a good reason. | ||
| 558 | */ | ||
| 559 | if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) { | ||
| 560 | const unsigned long start = vma->vm_start; | ||
| 561 | const unsigned long end = vma->vm_end; | ||
| 562 | |||
| 563 | tlb_gather_mmu(&tlb, mm, start, end); | ||
| 564 | mmu_notifier_invalidate_range_start(mm, start, end); | ||
| 565 | unmap_page_range(&tlb, vma, start, end, NULL); | ||
| 566 | mmu_notifier_invalidate_range_end(mm, start, end); | ||
| 567 | tlb_finish_mmu(&tlb, start, end); | ||
| 568 | } | ||
| 569 | } | ||
| 570 | pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", | 576 | pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", |
| 571 | task_pid_nr(tsk), tsk->comm, | 577 | task_pid_nr(tsk), tsk->comm, |
| 572 | K(get_mm_counter(mm, MM_ANONPAGES)), | 578 | K(get_mm_counter(mm, MM_ANONPAGES)), |
| @@ -587,14 +593,13 @@ static void oom_reap_task(struct task_struct *tsk) | |||
| 587 | struct mm_struct *mm = tsk->signal->oom_mm; | 593 | struct mm_struct *mm = tsk->signal->oom_mm; |
| 588 | 594 | ||
| 589 | /* Retry the down_read_trylock(mmap_sem) a few times */ | 595 | /* Retry the down_read_trylock(mmap_sem) a few times */ |
| 590 | while (attempts++ < MAX_OOM_REAP_RETRIES && !__oom_reap_task_mm(tsk, mm)) | 596 | while (attempts++ < MAX_OOM_REAP_RETRIES && !oom_reap_task_mm(tsk, mm)) |
| 591 | schedule_timeout_idle(HZ/10); | 597 | schedule_timeout_idle(HZ/10); |
| 592 | 598 | ||
| 593 | if (attempts <= MAX_OOM_REAP_RETRIES || | 599 | if (attempts <= MAX_OOM_REAP_RETRIES || |
| 594 | test_bit(MMF_OOM_SKIP, &mm->flags)) | 600 | test_bit(MMF_OOM_SKIP, &mm->flags)) |
| 595 | goto done; | 601 | goto done; |
| 596 | 602 | ||
| 597 | |||
| 598 | pr_info("oom_reaper: unable to reap pid:%d (%s)\n", | 603 | pr_info("oom_reaper: unable to reap pid:%d (%s)\n", |
| 599 | task_pid_nr(tsk), tsk->comm); | 604 | task_pid_nr(tsk), tsk->comm); |
| 600 | debug_show_all_locks(); | 605 | debug_show_all_locks(); |
diff --git a/mm/sparse.c b/mm/sparse.c index 62eef264a7bd..73dc2fcc0eab 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
| @@ -629,7 +629,7 @@ void offline_mem_sections(unsigned long start_pfn, unsigned long end_pfn) | |||
| 629 | unsigned long pfn; | 629 | unsigned long pfn; |
| 630 | 630 | ||
| 631 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { | 631 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { |
| 632 | unsigned long section_nr = pfn_to_section_nr(start_pfn); | 632 | unsigned long section_nr = pfn_to_section_nr(pfn); |
| 633 | struct mem_section *ms; | 633 | struct mem_section *ms; |
| 634 | 634 | ||
| 635 | /* | 635 | /* |
diff --git a/mm/vmstat.c b/mm/vmstat.c index 536332e988b8..a2b9518980ce 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
| @@ -1161,7 +1161,7 @@ const char * const vmstat_text[] = { | |||
| 1161 | "nr_vmscan_immediate_reclaim", | 1161 | "nr_vmscan_immediate_reclaim", |
| 1162 | "nr_dirtied", | 1162 | "nr_dirtied", |
| 1163 | "nr_written", | 1163 | "nr_written", |
| 1164 | "nr_indirectly_reclaimable", | 1164 | "", /* nr_indirectly_reclaimable */ |
| 1165 | 1165 | ||
| 1166 | /* enum writeback_stat_item counters */ | 1166 | /* enum writeback_stat_item counters */ |
| 1167 | "nr_dirty_threshold", | 1167 | "nr_dirty_threshold", |
| @@ -1740,6 +1740,10 @@ static int vmstat_show(struct seq_file *m, void *arg) | |||
| 1740 | unsigned long *l = arg; | 1740 | unsigned long *l = arg; |
| 1741 | unsigned long off = l - (unsigned long *)m->private; | 1741 | unsigned long off = l - (unsigned long *)m->private; |
| 1742 | 1742 | ||
| 1743 | /* Skip hidden vmstat items. */ | ||
| 1744 | if (*vmstat_text[off] == '\0') | ||
| 1745 | return 0; | ||
| 1746 | |||
| 1743 | seq_puts(m, vmstat_text[off]); | 1747 | seq_puts(m, vmstat_text[off]); |
| 1744 | seq_put_decimal_ull(m, " ", *l); | 1748 | seq_put_decimal_ull(m, " ", *l); |
| 1745 | seq_putc(m, '\n'); | 1749 | seq_putc(m, '\n'); |
diff --git a/mm/z3fold.c b/mm/z3fold.c index c0bca6153b95..4b366d181f35 100644 --- a/mm/z3fold.c +++ b/mm/z3fold.c | |||
| @@ -144,7 +144,8 @@ enum z3fold_page_flags { | |||
| 144 | PAGE_HEADLESS = 0, | 144 | PAGE_HEADLESS = 0, |
| 145 | MIDDLE_CHUNK_MAPPED, | 145 | MIDDLE_CHUNK_MAPPED, |
| 146 | NEEDS_COMPACTING, | 146 | NEEDS_COMPACTING, |
| 147 | PAGE_STALE | 147 | PAGE_STALE, |
| 148 | UNDER_RECLAIM | ||
| 148 | }; | 149 | }; |
| 149 | 150 | ||
| 150 | /***************** | 151 | /***************** |
| @@ -173,6 +174,7 @@ static struct z3fold_header *init_z3fold_page(struct page *page, | |||
| 173 | clear_bit(MIDDLE_CHUNK_MAPPED, &page->private); | 174 | clear_bit(MIDDLE_CHUNK_MAPPED, &page->private); |
| 174 | clear_bit(NEEDS_COMPACTING, &page->private); | 175 | clear_bit(NEEDS_COMPACTING, &page->private); |
| 175 | clear_bit(PAGE_STALE, &page->private); | 176 | clear_bit(PAGE_STALE, &page->private); |
| 177 | clear_bit(UNDER_RECLAIM, &page->private); | ||
| 176 | 178 | ||
| 177 | spin_lock_init(&zhdr->page_lock); | 179 | spin_lock_init(&zhdr->page_lock); |
| 178 | kref_init(&zhdr->refcount); | 180 | kref_init(&zhdr->refcount); |
| @@ -756,6 +758,10 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle) | |||
| 756 | atomic64_dec(&pool->pages_nr); | 758 | atomic64_dec(&pool->pages_nr); |
| 757 | return; | 759 | return; |
| 758 | } | 760 | } |
| 761 | if (test_bit(UNDER_RECLAIM, &page->private)) { | ||
| 762 | z3fold_page_unlock(zhdr); | ||
| 763 | return; | ||
| 764 | } | ||
| 759 | if (test_and_set_bit(NEEDS_COMPACTING, &page->private)) { | 765 | if (test_and_set_bit(NEEDS_COMPACTING, &page->private)) { |
| 760 | z3fold_page_unlock(zhdr); | 766 | z3fold_page_unlock(zhdr); |
| 761 | return; | 767 | return; |
| @@ -840,6 +846,8 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) | |||
| 840 | kref_get(&zhdr->refcount); | 846 | kref_get(&zhdr->refcount); |
| 841 | list_del_init(&zhdr->buddy); | 847 | list_del_init(&zhdr->buddy); |
| 842 | zhdr->cpu = -1; | 848 | zhdr->cpu = -1; |
| 849 | set_bit(UNDER_RECLAIM, &page->private); | ||
| 850 | break; | ||
| 843 | } | 851 | } |
| 844 | 852 | ||
| 845 | list_del_init(&page->lru); | 853 | list_del_init(&page->lru); |
| @@ -887,25 +895,35 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) | |||
| 887 | goto next; | 895 | goto next; |
| 888 | } | 896 | } |
| 889 | next: | 897 | next: |
| 890 | spin_lock(&pool->lock); | ||
| 891 | if (test_bit(PAGE_HEADLESS, &page->private)) { | 898 | if (test_bit(PAGE_HEADLESS, &page->private)) { |
| 892 | if (ret == 0) { | 899 | if (ret == 0) { |
| 893 | spin_unlock(&pool->lock); | ||
| 894 | free_z3fold_page(page); | 900 | free_z3fold_page(page); |
| 895 | return 0; | 901 | return 0; |
| 896 | } | 902 | } |
| 897 | } else if (kref_put(&zhdr->refcount, release_z3fold_page)) { | 903 | spin_lock(&pool->lock); |
| 898 | atomic64_dec(&pool->pages_nr); | 904 | list_add(&page->lru, &pool->lru); |
| 905 | spin_unlock(&pool->lock); | ||
| 906 | } else { | ||
| 907 | z3fold_page_lock(zhdr); | ||
| 908 | clear_bit(UNDER_RECLAIM, &page->private); | ||
| 909 | if (kref_put(&zhdr->refcount, | ||
| 910 | release_z3fold_page_locked)) { | ||
| 911 | atomic64_dec(&pool->pages_nr); | ||
| 912 | return 0; | ||
| 913 | } | ||
| 914 | /* | ||
| 915 | * if we are here, the page is still not completely | ||
| 916 | * free. Take the global pool lock then to be able | ||
| 917 | * to add it back to the lru list | ||
| 918 | */ | ||
| 919 | spin_lock(&pool->lock); | ||
| 920 | list_add(&page->lru, &pool->lru); | ||
| 899 | spin_unlock(&pool->lock); | 921 | spin_unlock(&pool->lock); |
| 900 | return 0; | 922 | z3fold_page_unlock(zhdr); |
| 901 | } | 923 | } |
| 902 | 924 | ||
| 903 | /* | 925 | /* We started off locked to we need to lock the pool back */ |
| 904 | * Add to the beginning of LRU. | 926 | spin_lock(&pool->lock); |
| 905 | * Pool lock has to be kept here to ensure the page has | ||
| 906 | * not already been released | ||
| 907 | */ | ||
| 908 | list_add(&page->lru, &pool->lru); | ||
| 909 | } | 927 | } |
| 910 | spin_unlock(&pool->lock); | 928 | spin_unlock(&pool->lock); |
| 911 | return -EAGAIN; | 929 | return -EAGAIN; |
diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c index 38aa6345bdfa..b718db2085b2 100644 --- a/net/9p/trans_common.c +++ b/net/9p/trans_common.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | 17 | ||
| 18 | /** | 18 | /** |
| 19 | * p9_release_req_pages - Release pages after the transaction. | 19 | * p9_release_pages - Release pages after the transaction. |
| 20 | */ | 20 | */ |
| 21 | void p9_release_pages(struct page **pages, int nr_pages) | 21 | void p9_release_pages(struct page **pages, int nr_pages) |
| 22 | { | 22 | { |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 0cfba919d167..848969fe7979 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
| @@ -1092,8 +1092,8 @@ static struct p9_trans_module p9_fd_trans = { | |||
| 1092 | }; | 1092 | }; |
| 1093 | 1093 | ||
| 1094 | /** | 1094 | /** |
| 1095 | * p9_poll_proc - poll worker thread | 1095 | * p9_poll_workfn - poll worker thread |
| 1096 | * @a: thread state and arguments | 1096 | * @work: work queue |
| 1097 | * | 1097 | * |
| 1098 | * polls all v9fs transports for new events and queues the appropriate | 1098 | * polls all v9fs transports for new events and queues the appropriate |
| 1099 | * work to the work queue | 1099 | * work to the work queue |
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 6d8e3031978f..3d414acb7015 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
| @@ -68,8 +68,6 @@ | |||
| 68 | * @pd: Protection Domain pointer | 68 | * @pd: Protection Domain pointer |
| 69 | * @qp: Queue Pair pointer | 69 | * @qp: Queue Pair pointer |
| 70 | * @cq: Completion Queue pointer | 70 | * @cq: Completion Queue pointer |
| 71 | * @dm_mr: DMA Memory Region pointer | ||
| 72 | * @lkey: The local access only memory region key | ||
| 73 | * @timeout: Number of uSecs to wait for connection management events | 71 | * @timeout: Number of uSecs to wait for connection management events |
| 74 | * @privport: Whether a privileged port may be used | 72 | * @privport: Whether a privileged port may be used |
| 75 | * @port: The port to use | 73 | * @port: The port to use |
| @@ -632,7 +630,7 @@ static int p9_rdma_bind_privport(struct p9_trans_rdma *rdma) | |||
| 632 | } | 630 | } |
| 633 | 631 | ||
| 634 | /** | 632 | /** |
| 635 | * trans_create_rdma - Transport method for creating atransport instance | 633 | * rdma_create_trans - Transport method for creating a transport instance |
| 636 | * @client: client instance | 634 | * @client: client instance |
| 637 | * @addr: IP address string | 635 | * @addr: IP address string |
| 638 | * @args: Mount options string | 636 | * @args: Mount options string |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 3aa5a93ad107..4d0372263e5d 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -60,7 +60,6 @@ static atomic_t vp_pinned = ATOMIC_INIT(0); | |||
| 60 | 60 | ||
| 61 | /** | 61 | /** |
| 62 | * struct virtio_chan - per-instance transport information | 62 | * struct virtio_chan - per-instance transport information |
| 63 | * @initialized: whether the channel is initialized | ||
| 64 | * @inuse: whether the channel is in use | 63 | * @inuse: whether the channel is in use |
| 65 | * @lock: protects multiple elements within this structure | 64 | * @lock: protects multiple elements within this structure |
| 66 | * @client: client instance | 65 | * @client: client instance |
| @@ -385,8 +384,8 @@ static int p9_get_mapped_pages(struct virtio_chan *chan, | |||
| 385 | * @uidata: user bffer that should be ued for zero copy read | 384 | * @uidata: user bffer that should be ued for zero copy read |
| 386 | * @uodata: user buffer that shoud be user for zero copy write | 385 | * @uodata: user buffer that shoud be user for zero copy write |
| 387 | * @inlen: read buffer size | 386 | * @inlen: read buffer size |
| 388 | * @olen: write buffer size | 387 | * @outlen: write buffer size |
| 389 | * @hdrlen: reader header size, This is the size of response protocol data | 388 | * @in_hdr_len: reader header size, This is the size of response protocol data |
| 390 | * | 389 | * |
| 391 | */ | 390 | */ |
| 392 | static int | 391 | static int |
diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index 086a4abdfa7c..0f19960390a6 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c | |||
| @@ -485,7 +485,7 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev, | |||
| 485 | 485 | ||
| 486 | static int xen_9pfs_front_resume(struct xenbus_device *dev) | 486 | static int xen_9pfs_front_resume(struct xenbus_device *dev) |
| 487 | { | 487 | { |
| 488 | dev_warn(&dev->dev, "suspsend/resume unsupported\n"); | 488 | dev_warn(&dev->dev, "suspend/resume unsupported\n"); |
| 489 | return 0; | 489 | return 0; |
| 490 | } | 490 | } |
| 491 | 491 | ||
diff --git a/net/atm/lec.c b/net/atm/lec.c index 01d5d20a6eb1..3138a869b5c0 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
| @@ -41,6 +41,9 @@ static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 }; | |||
| 41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
| 42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
| 43 | 43 | ||
| 44 | /* Hardening for Spectre-v1 */ | ||
| 45 | #include <linux/nospec.h> | ||
| 46 | |||
| 44 | #include "lec.h" | 47 | #include "lec.h" |
| 45 | #include "lec_arpc.h" | 48 | #include "lec_arpc.h" |
| 46 | #include "resources.h" | 49 | #include "resources.h" |
| @@ -687,8 +690,10 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) | |||
| 687 | bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc)); | 690 | bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc)); |
| 688 | if (bytes_left != 0) | 691 | if (bytes_left != 0) |
| 689 | pr_info("copy from user failed for %d bytes\n", bytes_left); | 692 | pr_info("copy from user failed for %d bytes\n", bytes_left); |
| 690 | if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF || | 693 | if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF) |
| 691 | !dev_lec[ioc_data.dev_num]) | 694 | return -EINVAL; |
| 695 | ioc_data.dev_num = array_index_nospec(ioc_data.dev_num, MAX_LEC_ITF); | ||
| 696 | if (!dev_lec[ioc_data.dev_num]) | ||
| 692 | return -EINVAL; | 697 | return -EINVAL; |
| 693 | vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL); | 698 | vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL); |
| 694 | if (!vpriv) | 699 | if (!vpriv) |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 82c1a6f430b3..5bb6681fa91e 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -518,8 +518,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, | |||
| 518 | return -ELOOP; | 518 | return -ELOOP; |
| 519 | } | 519 | } |
| 520 | 520 | ||
| 521 | /* Device is already being bridged */ | 521 | /* Device has master upper dev */ |
| 522 | if (br_port_exists(dev)) | 522 | if (netdev_master_upper_dev_get(dev)) |
| 523 | return -EBUSY; | 523 | return -EBUSY; |
| 524 | 524 | ||
| 525 | /* No bridging devices that dislike that (e.g. wireless) */ | 525 | /* No bridging devices that dislike that (e.g. wireless) */ |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index ea2a6c9fb7ce..d2667e5dddc3 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
| @@ -157,10 +157,12 @@ static void ceph_osd_data_bio_init(struct ceph_osd_data *osd_data, | |||
| 157 | #endif /* CONFIG_BLOCK */ | 157 | #endif /* CONFIG_BLOCK */ |
| 158 | 158 | ||
| 159 | static void ceph_osd_data_bvecs_init(struct ceph_osd_data *osd_data, | 159 | static void ceph_osd_data_bvecs_init(struct ceph_osd_data *osd_data, |
| 160 | struct ceph_bvec_iter *bvec_pos) | 160 | struct ceph_bvec_iter *bvec_pos, |
| 161 | u32 num_bvecs) | ||
| 161 | { | 162 | { |
| 162 | osd_data->type = CEPH_OSD_DATA_TYPE_BVECS; | 163 | osd_data->type = CEPH_OSD_DATA_TYPE_BVECS; |
| 163 | osd_data->bvec_pos = *bvec_pos; | 164 | osd_data->bvec_pos = *bvec_pos; |
| 165 | osd_data->num_bvecs = num_bvecs; | ||
| 164 | } | 166 | } |
| 165 | 167 | ||
| 166 | #define osd_req_op_data(oreq, whch, typ, fld) \ | 168 | #define osd_req_op_data(oreq, whch, typ, fld) \ |
| @@ -237,6 +239,22 @@ void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *osd_req, | |||
| 237 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio); | 239 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio); |
| 238 | #endif /* CONFIG_BLOCK */ | 240 | #endif /* CONFIG_BLOCK */ |
| 239 | 241 | ||
| 242 | void osd_req_op_extent_osd_data_bvecs(struct ceph_osd_request *osd_req, | ||
| 243 | unsigned int which, | ||
| 244 | struct bio_vec *bvecs, u32 num_bvecs, | ||
| 245 | u32 bytes) | ||
| 246 | { | ||
| 247 | struct ceph_osd_data *osd_data; | ||
| 248 | struct ceph_bvec_iter it = { | ||
| 249 | .bvecs = bvecs, | ||
| 250 | .iter = { .bi_size = bytes }, | ||
| 251 | }; | ||
| 252 | |||
| 253 | osd_data = osd_req_op_data(osd_req, which, extent, osd_data); | ||
| 254 | ceph_osd_data_bvecs_init(osd_data, &it, num_bvecs); | ||
| 255 | } | ||
| 256 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bvecs); | ||
| 257 | |||
| 240 | void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req, | 258 | void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req, |
| 241 | unsigned int which, | 259 | unsigned int which, |
| 242 | struct ceph_bvec_iter *bvec_pos) | 260 | struct ceph_bvec_iter *bvec_pos) |
| @@ -244,7 +262,7 @@ void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req, | |||
| 244 | struct ceph_osd_data *osd_data; | 262 | struct ceph_osd_data *osd_data; |
| 245 | 263 | ||
| 246 | osd_data = osd_req_op_data(osd_req, which, extent, osd_data); | 264 | osd_data = osd_req_op_data(osd_req, which, extent, osd_data); |
| 247 | ceph_osd_data_bvecs_init(osd_data, bvec_pos); | 265 | ceph_osd_data_bvecs_init(osd_data, bvec_pos, 0); |
| 248 | } | 266 | } |
| 249 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bvec_pos); | 267 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bvec_pos); |
| 250 | 268 | ||
| @@ -287,7 +305,8 @@ EXPORT_SYMBOL(osd_req_op_cls_request_data_pages); | |||
| 287 | 305 | ||
| 288 | void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req, | 306 | void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req, |
| 289 | unsigned int which, | 307 | unsigned int which, |
| 290 | struct bio_vec *bvecs, u32 bytes) | 308 | struct bio_vec *bvecs, u32 num_bvecs, |
| 309 | u32 bytes) | ||
| 291 | { | 310 | { |
| 292 | struct ceph_osd_data *osd_data; | 311 | struct ceph_osd_data *osd_data; |
| 293 | struct ceph_bvec_iter it = { | 312 | struct ceph_bvec_iter it = { |
| @@ -296,7 +315,7 @@ void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req, | |||
| 296 | }; | 315 | }; |
| 297 | 316 | ||
| 298 | osd_data = osd_req_op_data(osd_req, which, cls, request_data); | 317 | osd_data = osd_req_op_data(osd_req, which, cls, request_data); |
| 299 | ceph_osd_data_bvecs_init(osd_data, &it); | 318 | ceph_osd_data_bvecs_init(osd_data, &it, num_bvecs); |
| 300 | osd_req->r_ops[which].cls.indata_len += bytes; | 319 | osd_req->r_ops[which].cls.indata_len += bytes; |
| 301 | osd_req->r_ops[which].indata_len += bytes; | 320 | osd_req->r_ops[which].indata_len += bytes; |
| 302 | } | 321 | } |
diff --git a/net/compat.c b/net/compat.c index 5ae7437d3853..7242cce5631b 100644 --- a/net/compat.c +++ b/net/compat.c | |||
| @@ -377,7 +377,8 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname, | |||
| 377 | optname == SO_ATTACH_REUSEPORT_CBPF) | 377 | optname == SO_ATTACH_REUSEPORT_CBPF) |
| 378 | return do_set_attach_filter(sock, level, optname, | 378 | return do_set_attach_filter(sock, level, optname, |
| 379 | optval, optlen); | 379 | optval, optlen); |
| 380 | if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) | 380 | if (!COMPAT_USE_64BIT_TIME && |
| 381 | (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) | ||
| 381 | return do_set_sock_timeout(sock, level, optname, optval, optlen); | 382 | return do_set_sock_timeout(sock, level, optname, optval, optlen); |
| 382 | 383 | ||
| 383 | return sock_setsockopt(sock, level, optname, optval, optlen); | 384 | return sock_setsockopt(sock, level, optname, optval, optlen); |
| @@ -448,7 +449,8 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname, | |||
| 448 | static int compat_sock_getsockopt(struct socket *sock, int level, int optname, | 449 | static int compat_sock_getsockopt(struct socket *sock, int level, int optname, |
| 449 | char __user *optval, int __user *optlen) | 450 | char __user *optval, int __user *optlen) |
| 450 | { | 451 | { |
| 451 | if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) | 452 | if (!COMPAT_USE_64BIT_TIME && |
| 453 | (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) | ||
| 452 | return do_get_sock_timeout(sock, level, optname, optval, optlen); | 454 | return do_get_sock_timeout(sock, level, optname, optval, optlen); |
| 453 | return sock_getsockopt(sock, level, optname, optval, optlen); | 455 | return sock_getsockopt(sock, level, optname, optval, optlen); |
| 454 | } | 456 | } |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 03416e6dd5d7..ba02f0dfe85c 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -1032,6 +1032,11 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, | |||
| 1032 | info_size = sizeof(info); | 1032 | info_size = sizeof(info); |
| 1033 | if (copy_from_user(&info, useraddr, info_size)) | 1033 | if (copy_from_user(&info, useraddr, info_size)) |
| 1034 | return -EFAULT; | 1034 | return -EFAULT; |
| 1035 | /* Since malicious users may modify the original data, | ||
| 1036 | * we need to check whether FLOW_RSS is still requested. | ||
| 1037 | */ | ||
| 1038 | if (!(info.flow_type & FLOW_RSS)) | ||
| 1039 | return -EINVAL; | ||
| 1035 | } | 1040 | } |
| 1036 | 1041 | ||
| 1037 | if (info.cmd == ETHTOOL_GRXCLSRLALL) { | 1042 | if (info.cmd == ETHTOOL_GRXCLSRLALL) { |
diff --git a/net/core/filter.c b/net/core/filter.c index d31aff93270d..e77c30ca491d 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -3240,6 +3240,7 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb, | |||
| 3240 | skb_dst_set(skb, (struct dst_entry *) md); | 3240 | skb_dst_set(skb, (struct dst_entry *) md); |
| 3241 | 3241 | ||
| 3242 | info = &md->u.tun_info; | 3242 | info = &md->u.tun_info; |
| 3243 | memset(info, 0, sizeof(*info)); | ||
| 3243 | info->mode = IP_TUNNEL_INFO_TX; | 3244 | info->mode = IP_TUNNEL_INFO_TX; |
| 3244 | 3245 | ||
| 3245 | info->key.tun_flags = TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_NOCACHE; | 3246 | info->key.tun_flags = TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_NOCACHE; |
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 92d016e87816..385f153fe031 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
| @@ -126,6 +126,16 @@ static void ccid2_change_l_seq_window(struct sock *sk, u64 val) | |||
| 126 | DCCPF_SEQ_WMAX)); | 126 | DCCPF_SEQ_WMAX)); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | static void dccp_tasklet_schedule(struct sock *sk) | ||
| 130 | { | ||
| 131 | struct tasklet_struct *t = &dccp_sk(sk)->dccps_xmitlet; | ||
| 132 | |||
| 133 | if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { | ||
| 134 | sock_hold(sk); | ||
| 135 | __tasklet_schedule(t); | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 129 | static void ccid2_hc_tx_rto_expire(struct timer_list *t) | 139 | static void ccid2_hc_tx_rto_expire(struct timer_list *t) |
| 130 | { | 140 | { |
| 131 | struct ccid2_hc_tx_sock *hc = from_timer(hc, t, tx_rtotimer); | 141 | struct ccid2_hc_tx_sock *hc = from_timer(hc, t, tx_rtotimer); |
| @@ -166,7 +176,7 @@ static void ccid2_hc_tx_rto_expire(struct timer_list *t) | |||
| 166 | 176 | ||
| 167 | /* if we were blocked before, we may now send cwnd=1 packet */ | 177 | /* if we were blocked before, we may now send cwnd=1 packet */ |
| 168 | if (sender_was_blocked) | 178 | if (sender_was_blocked) |
| 169 | tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); | 179 | dccp_tasklet_schedule(sk); |
| 170 | /* restart backed-off timer */ | 180 | /* restart backed-off timer */ |
| 171 | sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); | 181 | sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); |
| 172 | out: | 182 | out: |
| @@ -706,7 +716,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
| 706 | done: | 716 | done: |
| 707 | /* check if incoming Acks allow pending packets to be sent */ | 717 | /* check if incoming Acks allow pending packets to be sent */ |
| 708 | if (sender_was_blocked && !ccid2_cwnd_network_limited(hc)) | 718 | if (sender_was_blocked && !ccid2_cwnd_network_limited(hc)) |
| 709 | tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); | 719 | dccp_tasklet_schedule(sk); |
| 710 | dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); | 720 | dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); |
| 711 | } | 721 | } |
| 712 | 722 | ||
diff --git a/net/dccp/timer.c b/net/dccp/timer.c index b50a8732ff43..1501a20a94ca 100644 --- a/net/dccp/timer.c +++ b/net/dccp/timer.c | |||
| @@ -232,6 +232,7 @@ static void dccp_write_xmitlet(unsigned long data) | |||
| 232 | else | 232 | else |
| 233 | dccp_write_xmit(sk); | 233 | dccp_write_xmit(sk); |
| 234 | bh_unlock_sock(sk); | 234 | bh_unlock_sock(sk); |
| 235 | sock_put(sk); | ||
| 235 | } | 236 | } |
| 236 | 237 | ||
| 237 | static void dccp_write_xmit_timer(struct timer_list *t) | 238 | static void dccp_write_xmit_timer(struct timer_list *t) |
| @@ -240,7 +241,6 @@ static void dccp_write_xmit_timer(struct timer_list *t) | |||
| 240 | struct sock *sk = &dp->dccps_inet_connection.icsk_inet.sk; | 241 | struct sock *sk = &dp->dccps_inet_connection.icsk_inet.sk; |
| 241 | 242 | ||
| 242 | dccp_write_xmitlet((unsigned long)sk); | 243 | dccp_write_xmitlet((unsigned long)sk); |
| 243 | sock_put(sk); | ||
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | void dccp_init_xmit_timers(struct sock *sk) | 246 | void dccp_init_xmit_timers(struct sock *sk) |
diff --git a/net/ieee802154/6lowpan/6lowpan_i.h b/net/ieee802154/6lowpan/6lowpan_i.h index b8d95cb71c25..44a7e16bf3b5 100644 --- a/net/ieee802154/6lowpan/6lowpan_i.h +++ b/net/ieee802154/6lowpan/6lowpan_i.h | |||
| @@ -20,8 +20,8 @@ typedef unsigned __bitwise lowpan_rx_result; | |||
| 20 | struct frag_lowpan_compare_key { | 20 | struct frag_lowpan_compare_key { |
| 21 | u16 tag; | 21 | u16 tag; |
| 22 | u16 d_size; | 22 | u16 d_size; |
| 23 | const struct ieee802154_addr src; | 23 | struct ieee802154_addr src; |
| 24 | const struct ieee802154_addr dst; | 24 | struct ieee802154_addr dst; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | /* Equivalent of ipv4 struct ipq | 27 | /* Equivalent of ipv4 struct ipq |
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c index 1790b65944b3..2cc224106b69 100644 --- a/net/ieee802154/6lowpan/reassembly.c +++ b/net/ieee802154/6lowpan/reassembly.c | |||
| @@ -75,14 +75,14 @@ fq_find(struct net *net, const struct lowpan_802154_cb *cb, | |||
| 75 | { | 75 | { |
| 76 | struct netns_ieee802154_lowpan *ieee802154_lowpan = | 76 | struct netns_ieee802154_lowpan *ieee802154_lowpan = |
| 77 | net_ieee802154_lowpan(net); | 77 | net_ieee802154_lowpan(net); |
| 78 | struct frag_lowpan_compare_key key = { | 78 | struct frag_lowpan_compare_key key = {}; |
| 79 | .tag = cb->d_tag, | ||
| 80 | .d_size = cb->d_size, | ||
| 81 | .src = *src, | ||
| 82 | .dst = *dst, | ||
| 83 | }; | ||
| 84 | struct inet_frag_queue *q; | 79 | struct inet_frag_queue *q; |
| 85 | 80 | ||
| 81 | key.tag = cb->d_tag; | ||
| 82 | key.d_size = cb->d_size; | ||
| 83 | key.src = *src; | ||
| 84 | key.dst = *dst; | ||
| 85 | |||
| 86 | q = inet_frag_find(&ieee802154_lowpan->frags, &key); | 86 | q = inet_frag_find(&ieee802154_lowpan->frags, &key); |
| 87 | if (!q) | 87 | if (!q) |
| 88 | return NULL; | 88 | return NULL; |
| @@ -372,7 +372,7 @@ int lowpan_frag_rcv(struct sk_buff *skb, u8 frag_type) | |||
| 372 | struct lowpan_frag_queue *fq; | 372 | struct lowpan_frag_queue *fq; |
| 373 | struct net *net = dev_net(skb->dev); | 373 | struct net *net = dev_net(skb->dev); |
| 374 | struct lowpan_802154_cb *cb = lowpan_802154_cb(skb); | 374 | struct lowpan_802154_cb *cb = lowpan_802154_cb(skb); |
| 375 | struct ieee802154_hdr hdr; | 375 | struct ieee802154_hdr hdr = {}; |
| 376 | int err; | 376 | int err; |
| 377 | 377 | ||
| 378 | if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) | 378 | if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 05e47d777009..56a010622f70 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -775,8 +775,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
| 775 | ipc.addr = faddr = daddr; | 775 | ipc.addr = faddr = daddr; |
| 776 | 776 | ||
| 777 | if (ipc.opt && ipc.opt->opt.srr) { | 777 | if (ipc.opt && ipc.opt->opt.srr) { |
| 778 | if (!daddr) | 778 | if (!daddr) { |
| 779 | return -EINVAL; | 779 | err = -EINVAL; |
| 780 | goto out_free; | ||
| 781 | } | ||
| 780 | faddr = ipc.opt->opt.faddr; | 782 | faddr = ipc.opt->opt.faddr; |
| 781 | } | 783 | } |
| 782 | tos = get_rttos(&ipc, inet); | 784 | tos = get_rttos(&ipc, inet); |
| @@ -842,6 +844,7 @@ back_from_confirm: | |||
| 842 | 844 | ||
| 843 | out: | 845 | out: |
| 844 | ip_rt_put(rt); | 846 | ip_rt_put(rt); |
| 847 | out_free: | ||
| 845 | if (free) | 848 | if (free) |
| 846 | kfree(ipc.opt); | 849 | kfree(ipc.opt); |
| 847 | if (!err) { | 850 | if (!err) { |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ccb25d80f679..29268efad247 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -709,7 +709,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, | |||
| 709 | fnhe->fnhe_gw = gw; | 709 | fnhe->fnhe_gw = gw; |
| 710 | fnhe->fnhe_pmtu = pmtu; | 710 | fnhe->fnhe_pmtu = pmtu; |
| 711 | fnhe->fnhe_mtu_locked = lock; | 711 | fnhe->fnhe_mtu_locked = lock; |
| 712 | fnhe->fnhe_expires = expires; | 712 | fnhe->fnhe_expires = max(1UL, expires); |
| 713 | 713 | ||
| 714 | /* Exception created; mark the cached routes for the nexthop | 714 | /* Exception created; mark the cached routes for the nexthop |
| 715 | * stale, so anyone caching it rechecks if this exception | 715 | * stale, so anyone caching it rechecks if this exception |
| @@ -1297,6 +1297,36 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) | |||
| 1297 | return mtu - lwtunnel_headroom(dst->lwtstate, mtu); | 1297 | return mtu - lwtunnel_headroom(dst->lwtstate, mtu); |
| 1298 | } | 1298 | } |
| 1299 | 1299 | ||
| 1300 | static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr) | ||
| 1301 | { | ||
| 1302 | struct fnhe_hash_bucket *hash; | ||
| 1303 | struct fib_nh_exception *fnhe, __rcu **fnhe_p; | ||
| 1304 | u32 hval = fnhe_hashfun(daddr); | ||
| 1305 | |||
| 1306 | spin_lock_bh(&fnhe_lock); | ||
| 1307 | |||
| 1308 | hash = rcu_dereference_protected(nh->nh_exceptions, | ||
| 1309 | lockdep_is_held(&fnhe_lock)); | ||
| 1310 | hash += hval; | ||
| 1311 | |||
| 1312 | fnhe_p = &hash->chain; | ||
| 1313 | fnhe = rcu_dereference_protected(*fnhe_p, lockdep_is_held(&fnhe_lock)); | ||
| 1314 | while (fnhe) { | ||
| 1315 | if (fnhe->fnhe_daddr == daddr) { | ||
| 1316 | rcu_assign_pointer(*fnhe_p, rcu_dereference_protected( | ||
| 1317 | fnhe->fnhe_next, lockdep_is_held(&fnhe_lock))); | ||
| 1318 | fnhe_flush_routes(fnhe); | ||
| 1319 | kfree_rcu(fnhe, rcu); | ||
| 1320 | break; | ||
| 1321 | } | ||
| 1322 | fnhe_p = &fnhe->fnhe_next; | ||
| 1323 | fnhe = rcu_dereference_protected(fnhe->fnhe_next, | ||
| 1324 | lockdep_is_held(&fnhe_lock)); | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | spin_unlock_bh(&fnhe_lock); | ||
| 1328 | } | ||
| 1329 | |||
| 1300 | static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr) | 1330 | static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr) |
| 1301 | { | 1331 | { |
| 1302 | struct fnhe_hash_bucket *hash = rcu_dereference(nh->nh_exceptions); | 1332 | struct fnhe_hash_bucket *hash = rcu_dereference(nh->nh_exceptions); |
| @@ -1310,8 +1340,14 @@ static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr) | |||
| 1310 | 1340 | ||
| 1311 | for (fnhe = rcu_dereference(hash[hval].chain); fnhe; | 1341 | for (fnhe = rcu_dereference(hash[hval].chain); fnhe; |
| 1312 | fnhe = rcu_dereference(fnhe->fnhe_next)) { | 1342 | fnhe = rcu_dereference(fnhe->fnhe_next)) { |
| 1313 | if (fnhe->fnhe_daddr == daddr) | 1343 | if (fnhe->fnhe_daddr == daddr) { |
| 1344 | if (fnhe->fnhe_expires && | ||
| 1345 | time_after(jiffies, fnhe->fnhe_expires)) { | ||
| 1346 | ip_del_fnhe(nh, daddr); | ||
| 1347 | break; | ||
| 1348 | } | ||
| 1314 | return fnhe; | 1349 | return fnhe; |
| 1350 | } | ||
| 1315 | } | 1351 | } |
| 1316 | return NULL; | 1352 | return NULL; |
| 1317 | } | 1353 | } |
| @@ -1339,6 +1375,7 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, | |||
| 1339 | fnhe->fnhe_gw = 0; | 1375 | fnhe->fnhe_gw = 0; |
| 1340 | fnhe->fnhe_pmtu = 0; | 1376 | fnhe->fnhe_pmtu = 0; |
| 1341 | fnhe->fnhe_expires = 0; | 1377 | fnhe->fnhe_expires = 0; |
| 1378 | fnhe->fnhe_mtu_locked = false; | ||
| 1342 | fnhe_flush_routes(fnhe); | 1379 | fnhe_flush_routes(fnhe); |
| 1343 | orig = NULL; | 1380 | orig = NULL; |
| 1344 | } | 1381 | } |
| @@ -1636,36 +1673,6 @@ static void ip_handle_martian_source(struct net_device *dev, | |||
| 1636 | #endif | 1673 | #endif |
| 1637 | } | 1674 | } |
| 1638 | 1675 | ||
| 1639 | static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr) | ||
| 1640 | { | ||
| 1641 | struct fnhe_hash_bucket *hash; | ||
| 1642 | struct fib_nh_exception *fnhe, __rcu **fnhe_p; | ||
| 1643 | u32 hval = fnhe_hashfun(daddr); | ||
| 1644 | |||
| 1645 | spin_lock_bh(&fnhe_lock); | ||
| 1646 | |||
| 1647 | hash = rcu_dereference_protected(nh->nh_exceptions, | ||
| 1648 | lockdep_is_held(&fnhe_lock)); | ||
| 1649 | hash += hval; | ||
| 1650 | |||
| 1651 | fnhe_p = &hash->chain; | ||
| 1652 | fnhe = rcu_dereference_protected(*fnhe_p, lockdep_is_held(&fnhe_lock)); | ||
| 1653 | while (fnhe) { | ||
| 1654 | if (fnhe->fnhe_daddr == daddr) { | ||
| 1655 | rcu_assign_pointer(*fnhe_p, rcu_dereference_protected( | ||
| 1656 | fnhe->fnhe_next, lockdep_is_held(&fnhe_lock))); | ||
| 1657 | fnhe_flush_routes(fnhe); | ||
| 1658 | kfree_rcu(fnhe, rcu); | ||
| 1659 | break; | ||
| 1660 | } | ||
| 1661 | fnhe_p = &fnhe->fnhe_next; | ||
| 1662 | fnhe = rcu_dereference_protected(fnhe->fnhe_next, | ||
| 1663 | lockdep_is_held(&fnhe_lock)); | ||
| 1664 | } | ||
| 1665 | |||
| 1666 | spin_unlock_bh(&fnhe_lock); | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | /* called in rcu_read_lock() section */ | 1676 | /* called in rcu_read_lock() section */ |
| 1670 | static int __mkroute_input(struct sk_buff *skb, | 1677 | static int __mkroute_input(struct sk_buff *skb, |
| 1671 | const struct fib_result *res, | 1678 | const struct fib_result *res, |
| @@ -1719,20 +1726,10 @@ static int __mkroute_input(struct sk_buff *skb, | |||
| 1719 | 1726 | ||
| 1720 | fnhe = find_exception(&FIB_RES_NH(*res), daddr); | 1727 | fnhe = find_exception(&FIB_RES_NH(*res), daddr); |
| 1721 | if (do_cache) { | 1728 | if (do_cache) { |
| 1722 | if (fnhe) { | 1729 | if (fnhe) |
| 1723 | rth = rcu_dereference(fnhe->fnhe_rth_input); | 1730 | rth = rcu_dereference(fnhe->fnhe_rth_input); |
| 1724 | if (rth && rth->dst.expires && | 1731 | else |
| 1725 | time_after(jiffies, rth->dst.expires)) { | 1732 | rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input); |
| 1726 | ip_del_fnhe(&FIB_RES_NH(*res), daddr); | ||
| 1727 | fnhe = NULL; | ||
| 1728 | } else { | ||
| 1729 | goto rt_cache; | ||
| 1730 | } | ||
| 1731 | } | ||
| 1732 | |||
| 1733 | rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input); | ||
| 1734 | |||
| 1735 | rt_cache: | ||
| 1736 | if (rt_cache_valid(rth)) { | 1733 | if (rt_cache_valid(rth)) { |
| 1737 | skb_dst_set_noref(skb, &rth->dst); | 1734 | skb_dst_set_noref(skb, &rth->dst); |
| 1738 | goto out; | 1735 | goto out; |
| @@ -2216,39 +2213,31 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
| 2216 | * the loopback interface and the IP_PKTINFO ipi_ifindex will | 2213 | * the loopback interface and the IP_PKTINFO ipi_ifindex will |
| 2217 | * be set to the loopback interface as well. | 2214 | * be set to the loopback interface as well. |
| 2218 | */ | 2215 | */ |
| 2219 | fi = NULL; | 2216 | do_cache = false; |
| 2220 | } | 2217 | } |
| 2221 | 2218 | ||
| 2222 | fnhe = NULL; | 2219 | fnhe = NULL; |
| 2223 | do_cache &= fi != NULL; | 2220 | do_cache &= fi != NULL; |
| 2224 | if (do_cache) { | 2221 | if (fi) { |
| 2225 | struct rtable __rcu **prth; | 2222 | struct rtable __rcu **prth; |
| 2226 | struct fib_nh *nh = &FIB_RES_NH(*res); | 2223 | struct fib_nh *nh = &FIB_RES_NH(*res); |
| 2227 | 2224 | ||
| 2228 | fnhe = find_exception(nh, fl4->daddr); | 2225 | fnhe = find_exception(nh, fl4->daddr); |
| 2226 | if (!do_cache) | ||
| 2227 | goto add; | ||
| 2229 | if (fnhe) { | 2228 | if (fnhe) { |
| 2230 | prth = &fnhe->fnhe_rth_output; | 2229 | prth = &fnhe->fnhe_rth_output; |
| 2231 | rth = rcu_dereference(*prth); | 2230 | } else { |
| 2232 | if (rth && rth->dst.expires && | 2231 | if (unlikely(fl4->flowi4_flags & |
| 2233 | time_after(jiffies, rth->dst.expires)) { | 2232 | FLOWI_FLAG_KNOWN_NH && |
| 2234 | ip_del_fnhe(nh, fl4->daddr); | 2233 | !(nh->nh_gw && |
| 2235 | fnhe = NULL; | 2234 | nh->nh_scope == RT_SCOPE_LINK))) { |
| 2236 | } else { | 2235 | do_cache = false; |
| 2237 | goto rt_cache; | 2236 | goto add; |
| 2238 | } | 2237 | } |
| 2238 | prth = raw_cpu_ptr(nh->nh_pcpu_rth_output); | ||
| 2239 | } | 2239 | } |
| 2240 | |||
| 2241 | if (unlikely(fl4->flowi4_flags & | ||
| 2242 | FLOWI_FLAG_KNOWN_NH && | ||
| 2243 | !(nh->nh_gw && | ||
| 2244 | nh->nh_scope == RT_SCOPE_LINK))) { | ||
| 2245 | do_cache = false; | ||
| 2246 | goto add; | ||
| 2247 | } | ||
| 2248 | prth = raw_cpu_ptr(nh->nh_pcpu_rth_output); | ||
| 2249 | rth = rcu_dereference(*prth); | 2240 | rth = rcu_dereference(*prth); |
| 2250 | |||
| 2251 | rt_cache: | ||
| 2252 | if (rt_cache_valid(rth) && dst_hold_safe(&rth->dst)) | 2241 | if (rt_cache_valid(rth) && dst_hold_safe(&rth->dst)) |
| 2253 | return rth; | 2242 | return rth; |
| 2254 | } | 2243 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9ce1c726185e..c9d00ef54dec 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -697,7 +697,7 @@ static bool tcp_should_autocork(struct sock *sk, struct sk_buff *skb, | |||
| 697 | { | 697 | { |
| 698 | return skb->len < size_goal && | 698 | return skb->len < size_goal && |
| 699 | sock_net(sk)->ipv4.sysctl_tcp_autocorking && | 699 | sock_net(sk)->ipv4.sysctl_tcp_autocorking && |
| 700 | skb != tcp_write_queue_head(sk) && | 700 | !tcp_rtx_queue_empty(sk) && |
| 701 | refcount_read(&sk->sk_wmem_alloc) > skb->truesize; | 701 | refcount_read(&sk->sk_wmem_alloc) > skb->truesize; |
| 702 | } | 702 | } |
| 703 | 703 | ||
| @@ -1204,7 +1204,8 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) | |||
| 1204 | uarg->zerocopy = 0; | 1204 | uarg->zerocopy = 0; |
| 1205 | } | 1205 | } |
| 1206 | 1206 | ||
| 1207 | if (unlikely(flags & MSG_FASTOPEN || inet_sk(sk)->defer_connect)) { | 1207 | if (unlikely(flags & MSG_FASTOPEN || inet_sk(sk)->defer_connect) && |
| 1208 | !tp->repair) { | ||
| 1208 | err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size); | 1209 | err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size); |
| 1209 | if (err == -EINPROGRESS && copied_syn > 0) | 1210 | if (err == -EINPROGRESS && copied_syn > 0) |
| 1210 | goto out; | 1211 | goto out; |
| @@ -2673,7 +2674,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2673 | case TCP_REPAIR_QUEUE: | 2674 | case TCP_REPAIR_QUEUE: |
| 2674 | if (!tp->repair) | 2675 | if (!tp->repair) |
| 2675 | err = -EPERM; | 2676 | err = -EPERM; |
| 2676 | else if (val < TCP_QUEUES_NR) | 2677 | else if ((unsigned int)val < TCP_QUEUES_NR) |
| 2677 | tp->repair_queue = val; | 2678 | tp->repair_queue = val; |
| 2678 | else | 2679 | else |
| 2679 | err = -EINVAL; | 2680 | err = -EINVAL; |
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c index 158d105e76da..58e2f479ffb4 100644 --- a/net/ipv4/tcp_bbr.c +++ b/net/ipv4/tcp_bbr.c | |||
| @@ -806,7 +806,9 @@ static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs) | |||
| 806 | } | 806 | } |
| 807 | } | 807 | } |
| 808 | } | 808 | } |
| 809 | bbr->idle_restart = 0; | 809 | /* Restart after idle ends only once we process a new S/ACK for data */ |
| 810 | if (rs->delivered > 0) | ||
| 811 | bbr->idle_restart = 0; | ||
| 810 | } | 812 | } |
| 811 | 813 | ||
| 812 | static void bbr_update_model(struct sock *sk, const struct rate_sample *rs) | 814 | static void bbr_update_model(struct sock *sk, const struct rate_sample *rs) |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 24b5c59b1c53..b61a770884fa 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -401,9 +401,9 @@ static int compute_score(struct sock *sk, struct net *net, | |||
| 401 | bool dev_match = (sk->sk_bound_dev_if == dif || | 401 | bool dev_match = (sk->sk_bound_dev_if == dif || |
| 402 | sk->sk_bound_dev_if == sdif); | 402 | sk->sk_bound_dev_if == sdif); |
| 403 | 403 | ||
| 404 | if (exact_dif && !dev_match) | 404 | if (!dev_match) |
| 405 | return -1; | 405 | return -1; |
| 406 | if (sk->sk_bound_dev_if && dev_match) | 406 | if (sk->sk_bound_dev_if) |
| 407 | score += 4; | 407 | score += 4; |
| 408 | } | 408 | } |
| 409 | 409 | ||
| @@ -952,8 +952,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
| 952 | sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); | 952 | sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); |
| 953 | 953 | ||
| 954 | if (ipc.opt && ipc.opt->opt.srr) { | 954 | if (ipc.opt && ipc.opt->opt.srr) { |
| 955 | if (!daddr) | 955 | if (!daddr) { |
| 956 | return -EINVAL; | 956 | err = -EINVAL; |
| 957 | goto out_free; | ||
| 958 | } | ||
| 957 | faddr = ipc.opt->opt.faddr; | 959 | faddr = ipc.opt->opt.faddr; |
| 958 | connected = 0; | 960 | connected = 0; |
| 959 | } | 961 | } |
| @@ -1074,6 +1076,7 @@ do_append_data: | |||
| 1074 | 1076 | ||
| 1075 | out: | 1077 | out: |
| 1076 | ip_rt_put(rt); | 1078 | ip_rt_put(rt); |
| 1079 | out_free: | ||
| 1077 | if (free) | 1080 | if (free) |
| 1078 | kfree(ipc.opt); | 1081 | kfree(ipc.opt); |
| 1079 | if (!err) | 1082 | if (!err) |
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index 6794ddf0547c..11e4e80cf7e9 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig | |||
| @@ -34,16 +34,15 @@ config IPV6_ROUTE_INFO | |||
| 34 | bool "IPv6: Route Information (RFC 4191) support" | 34 | bool "IPv6: Route Information (RFC 4191) support" |
| 35 | depends on IPV6_ROUTER_PREF | 35 | depends on IPV6_ROUTER_PREF |
| 36 | ---help--- | 36 | ---help--- |
| 37 | This is experimental support of Route Information. | 37 | Support of Route Information. |
| 38 | 38 | ||
| 39 | If unsure, say N. | 39 | If unsure, say N. |
| 40 | 40 | ||
| 41 | config IPV6_OPTIMISTIC_DAD | 41 | config IPV6_OPTIMISTIC_DAD |
| 42 | bool "IPv6: Enable RFC 4429 Optimistic DAD" | 42 | bool "IPv6: Enable RFC 4429 Optimistic DAD" |
| 43 | ---help--- | 43 | ---help--- |
| 44 | This is experimental support for optimistic Duplicate | 44 | Support for optimistic Duplicate Address Detection. It allows for |
| 45 | Address Detection. It allows for autoconfigured addresses | 45 | autoconfigured addresses to be used more quickly. |
| 46 | to be used more quickly. | ||
| 47 | 46 | ||
| 48 | If unsure, say N. | 47 | If unsure, say N. |
| 49 | 48 | ||
| @@ -280,7 +279,7 @@ config IPV6_MROUTE | |||
| 280 | depends on IPV6 | 279 | depends on IPV6 |
| 281 | select IP_MROUTE_COMMON | 280 | select IP_MROUTE_COMMON |
| 282 | ---help--- | 281 | ---help--- |
| 283 | Experimental support for IPv6 multicast forwarding. | 282 | Support for IPv6 multicast forwarding. |
| 284 | If unsure, say N. | 283 | If unsure, say N. |
| 285 | 284 | ||
| 286 | config IPV6_MROUTE_MULTIPLE_TABLES | 285 | config IPV6_MROUTE_MULTIPLE_TABLES |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index c214ffec02f0..ca957dd93a29 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
| @@ -669,7 +669,7 @@ static void vti6_link_config(struct ip6_tnl *t, bool keep_mtu) | |||
| 669 | else | 669 | else |
| 670 | mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr); | 670 | mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr); |
| 671 | 671 | ||
| 672 | dev->mtu = max_t(int, mtu, IPV6_MIN_MTU); | 672 | dev->mtu = max_t(int, mtu, IPV4_MIN_MTU); |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | /** | 675 | /** |
| @@ -881,7 +881,7 @@ static void vti6_dev_setup(struct net_device *dev) | |||
| 881 | dev->priv_destructor = vti6_dev_free; | 881 | dev->priv_destructor = vti6_dev_free; |
| 882 | 882 | ||
| 883 | dev->type = ARPHRD_TUNNEL6; | 883 | dev->type = ARPHRD_TUNNEL6; |
| 884 | dev->min_mtu = IPV6_MIN_MTU; | 884 | dev->min_mtu = IPV4_MIN_MTU; |
| 885 | dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr); | 885 | dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr); |
| 886 | dev->flags |= IFF_NOARP; | 886 | dev->flags |= IFF_NOARP; |
| 887 | dev->addr_len = sizeof(struct in6_addr); | 887 | dev->addr_len = sizeof(struct in6_addr); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index cde7d8251377..f4d61736c41a 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -1835,11 +1835,16 @@ static void ip6_multipath_l3_keys(const struct sk_buff *skb, | |||
| 1835 | const struct ipv6hdr *inner_iph; | 1835 | const struct ipv6hdr *inner_iph; |
| 1836 | const struct icmp6hdr *icmph; | 1836 | const struct icmp6hdr *icmph; |
| 1837 | struct ipv6hdr _inner_iph; | 1837 | struct ipv6hdr _inner_iph; |
| 1838 | struct icmp6hdr _icmph; | ||
| 1838 | 1839 | ||
| 1839 | if (likely(outer_iph->nexthdr != IPPROTO_ICMPV6)) | 1840 | if (likely(outer_iph->nexthdr != IPPROTO_ICMPV6)) |
| 1840 | goto out; | 1841 | goto out; |
| 1841 | 1842 | ||
| 1842 | icmph = icmp6_hdr(skb); | 1843 | icmph = skb_header_pointer(skb, skb_transport_offset(skb), |
| 1844 | sizeof(_icmph), &_icmph); | ||
| 1845 | if (!icmph) | ||
| 1846 | goto out; | ||
| 1847 | |||
| 1843 | if (icmph->icmp6_type != ICMPV6_DEST_UNREACH && | 1848 | if (icmph->icmp6_type != ICMPV6_DEST_UNREACH && |
| 1844 | icmph->icmp6_type != ICMPV6_PKT_TOOBIG && | 1849 | icmph->icmp6_type != ICMPV6_PKT_TOOBIG && |
| 1845 | icmph->icmp6_type != ICMPV6_TIME_EXCEED && | 1850 | icmph->icmp6_type != ICMPV6_TIME_EXCEED && |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 4ec76a87aeb8..ea0730028e5d 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -148,9 +148,9 @@ static int compute_score(struct sock *sk, struct net *net, | |||
| 148 | bool dev_match = (sk->sk_bound_dev_if == dif || | 148 | bool dev_match = (sk->sk_bound_dev_if == dif || |
| 149 | sk->sk_bound_dev_if == sdif); | 149 | sk->sk_bound_dev_if == sdif); |
| 150 | 150 | ||
| 151 | if (exact_dif && !dev_match) | 151 | if (!dev_match) |
| 152 | return -1; | 152 | return -1; |
| 153 | if (sk->sk_bound_dev_if && dev_match) | 153 | if (sk->sk_bound_dev_if) |
| 154 | score++; | 154 | score++; |
| 155 | } | 155 | } |
| 156 | 156 | ||
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index f85f0d7480ac..4a46df8441c9 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
| @@ -341,6 +341,9 @@ static void __net_exit xfrm6_tunnel_net_exit(struct net *net) | |||
| 341 | struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); | 341 | struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); |
| 342 | unsigned int i; | 342 | unsigned int i; |
| 343 | 343 | ||
| 344 | xfrm_state_flush(net, IPSEC_PROTO_ANY, false); | ||
| 345 | xfrm_flush_gc(); | ||
| 346 | |||
| 344 | for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) | 347 | for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) |
| 345 | WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i])); | 348 | WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i])); |
| 346 | 349 | ||
diff --git a/net/key/af_key.c b/net/key/af_key.c index 7e2e7188e7f4..e62e52e8f141 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -437,6 +437,24 @@ static int verify_address_len(const void *p) | |||
| 437 | return 0; | 437 | return 0; |
| 438 | } | 438 | } |
| 439 | 439 | ||
| 440 | static inline int sadb_key_len(const struct sadb_key *key) | ||
| 441 | { | ||
| 442 | int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8); | ||
| 443 | |||
| 444 | return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes, | ||
| 445 | sizeof(uint64_t)); | ||
| 446 | } | ||
| 447 | |||
| 448 | static int verify_key_len(const void *p) | ||
| 449 | { | ||
| 450 | const struct sadb_key *key = p; | ||
| 451 | |||
| 452 | if (sadb_key_len(key) > key->sadb_key_len) | ||
| 453 | return -EINVAL; | ||
| 454 | |||
| 455 | return 0; | ||
| 456 | } | ||
| 457 | |||
| 440 | static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx) | 458 | static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx) |
| 441 | { | 459 | { |
| 442 | return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) + | 460 | return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) + |
| @@ -533,16 +551,25 @@ static int parse_exthdrs(struct sk_buff *skb, const struct sadb_msg *hdr, void * | |||
| 533 | return -EINVAL; | 551 | return -EINVAL; |
| 534 | if (ext_hdrs[ext_type-1] != NULL) | 552 | if (ext_hdrs[ext_type-1] != NULL) |
| 535 | return -EINVAL; | 553 | return -EINVAL; |
| 536 | if (ext_type == SADB_EXT_ADDRESS_SRC || | 554 | switch (ext_type) { |
| 537 | ext_type == SADB_EXT_ADDRESS_DST || | 555 | case SADB_EXT_ADDRESS_SRC: |
| 538 | ext_type == SADB_EXT_ADDRESS_PROXY || | 556 | case SADB_EXT_ADDRESS_DST: |
| 539 | ext_type == SADB_X_EXT_NAT_T_OA) { | 557 | case SADB_EXT_ADDRESS_PROXY: |
| 558 | case SADB_X_EXT_NAT_T_OA: | ||
| 540 | if (verify_address_len(p)) | 559 | if (verify_address_len(p)) |
| 541 | return -EINVAL; | 560 | return -EINVAL; |
| 542 | } | 561 | break; |
| 543 | if (ext_type == SADB_X_EXT_SEC_CTX) { | 562 | case SADB_X_EXT_SEC_CTX: |
| 544 | if (verify_sec_ctx_len(p)) | 563 | if (verify_sec_ctx_len(p)) |
| 545 | return -EINVAL; | 564 | return -EINVAL; |
| 565 | break; | ||
| 566 | case SADB_EXT_KEY_AUTH: | ||
| 567 | case SADB_EXT_KEY_ENCRYPT: | ||
| 568 | if (verify_key_len(p)) | ||
| 569 | return -EINVAL; | ||
| 570 | break; | ||
| 571 | default: | ||
| 572 | break; | ||
| 546 | } | 573 | } |
| 547 | ext_hdrs[ext_type-1] = (void *) p; | 574 | ext_hdrs[ext_type-1] = (void *) p; |
| 548 | } | 575 | } |
| @@ -1104,14 +1131,12 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net, | |||
| 1104 | key = ext_hdrs[SADB_EXT_KEY_AUTH - 1]; | 1131 | key = ext_hdrs[SADB_EXT_KEY_AUTH - 1]; |
| 1105 | if (key != NULL && | 1132 | if (key != NULL && |
| 1106 | sa->sadb_sa_auth != SADB_X_AALG_NULL && | 1133 | sa->sadb_sa_auth != SADB_X_AALG_NULL && |
| 1107 | ((key->sadb_key_bits+7) / 8 == 0 || | 1134 | key->sadb_key_bits == 0) |
| 1108 | (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) | ||
| 1109 | return ERR_PTR(-EINVAL); | 1135 | return ERR_PTR(-EINVAL); |
| 1110 | key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; | 1136 | key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; |
| 1111 | if (key != NULL && | 1137 | if (key != NULL && |
| 1112 | sa->sadb_sa_encrypt != SADB_EALG_NULL && | 1138 | sa->sadb_sa_encrypt != SADB_EALG_NULL && |
| 1113 | ((key->sadb_key_bits+7) / 8 == 0 || | 1139 | key->sadb_key_bits == 0) |
| 1114 | (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) | ||
| 1115 | return ERR_PTR(-EINVAL); | 1140 | return ERR_PTR(-EINVAL); |
| 1116 | 1141 | ||
| 1117 | x = xfrm_state_alloc(net); | 1142 | x = xfrm_state_alloc(net); |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index cb80ebb38311..1beeea9549fa 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
| @@ -930,6 +930,9 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) | |||
| 930 | if (size > llc->dev->mtu) | 930 | if (size > llc->dev->mtu) |
| 931 | size = llc->dev->mtu; | 931 | size = llc->dev->mtu; |
| 932 | copied = size - hdrlen; | 932 | copied = size - hdrlen; |
| 933 | rc = -EINVAL; | ||
| 934 | if (copied < 0) | ||
| 935 | goto release; | ||
| 933 | release_sock(sk); | 936 | release_sock(sk); |
| 934 | skb = sock_alloc_send_skb(sk, size, noblock, &rc); | 937 | skb = sock_alloc_send_skb(sk, size, noblock, &rc); |
| 935 | lock_sock(sk); | 938 | lock_sock(sk); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 595c662a61e8..ac4295296514 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
| 9 | * Copyright 2007-2010, Intel Corporation | 9 | * Copyright 2007-2010, Intel Corporation |
| 10 | * Copyright(c) 2015-2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2015-2017 Intel Deutschland GmbH |
| 11 | * Copyright (C) 2018 Intel Corporation | ||
| 11 | * | 12 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of the GNU General Public License version 2 as | 14 | * it under the terms of the GNU General Public License version 2 as |
| @@ -970,6 +971,9 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
| 970 | 971 | ||
| 971 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 972 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
| 972 | 973 | ||
| 974 | tid_tx->timeout = | ||
| 975 | le16_to_cpu(mgmt->u.action.u.addba_resp.timeout); | ||
| 976 | |||
| 973 | if (tid_tx->timeout) { | 977 | if (tid_tx->timeout) { |
| 974 | mod_timer(&tid_tx->session_timer, | 978 | mod_timer(&tid_tx->session_timer, |
| 975 | TU_TO_EXP_TIME(tid_tx->timeout)); | 979 | TU_TO_EXP_TIME(tid_tx->timeout)); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 69449db7e283..233068756502 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #define IEEE80211_AUTH_TIMEOUT (HZ / 5) | 36 | #define IEEE80211_AUTH_TIMEOUT (HZ / 5) |
| 37 | #define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2) | 37 | #define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2) |
| 38 | #define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10) | 38 | #define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10) |
| 39 | #define IEEE80211_AUTH_TIMEOUT_SAE (HZ * 2) | ||
| 39 | #define IEEE80211_AUTH_MAX_TRIES 3 | 40 | #define IEEE80211_AUTH_MAX_TRIES 3 |
| 40 | #define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5) | 41 | #define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5) |
| 41 | #define IEEE80211_ASSOC_TIMEOUT (HZ / 5) | 42 | #define IEEE80211_ASSOC_TIMEOUT (HZ / 5) |
| @@ -1787,7 +1788,7 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
| 1787 | params[ac].acm = acm; | 1788 | params[ac].acm = acm; |
| 1788 | params[ac].uapsd = uapsd; | 1789 | params[ac].uapsd = uapsd; |
| 1789 | 1790 | ||
| 1790 | if (params->cw_min == 0 || | 1791 | if (params[ac].cw_min == 0 || |
| 1791 | params[ac].cw_min > params[ac].cw_max) { | 1792 | params[ac].cw_min > params[ac].cw_max) { |
| 1792 | sdata_info(sdata, | 1793 | sdata_info(sdata, |
| 1793 | "AP has invalid WMM params (CWmin/max=%d/%d for ACI %d), using defaults\n", | 1794 | "AP has invalid WMM params (CWmin/max=%d/%d for ACI %d), using defaults\n", |
| @@ -3814,16 +3815,19 @@ static int ieee80211_auth(struct ieee80211_sub_if_data *sdata) | |||
| 3814 | tx_flags); | 3815 | tx_flags); |
| 3815 | 3816 | ||
| 3816 | if (tx_flags == 0) { | 3817 | if (tx_flags == 0) { |
| 3817 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 3818 | if (auth_data->algorithm == WLAN_AUTH_SAE) |
| 3818 | auth_data->timeout_started = true; | 3819 | auth_data->timeout = jiffies + |
| 3819 | run_again(sdata, auth_data->timeout); | 3820 | IEEE80211_AUTH_TIMEOUT_SAE; |
| 3821 | else | ||
| 3822 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | ||
| 3820 | } else { | 3823 | } else { |
| 3821 | auth_data->timeout = | 3824 | auth_data->timeout = |
| 3822 | round_jiffies_up(jiffies + IEEE80211_AUTH_TIMEOUT_LONG); | 3825 | round_jiffies_up(jiffies + IEEE80211_AUTH_TIMEOUT_LONG); |
| 3823 | auth_data->timeout_started = true; | ||
| 3824 | run_again(sdata, auth_data->timeout); | ||
| 3825 | } | 3826 | } |
| 3826 | 3827 | ||
| 3828 | auth_data->timeout_started = true; | ||
| 3829 | run_again(sdata, auth_data->timeout); | ||
| 3830 | |||
| 3827 | return 0; | 3831 | return 0; |
| 3828 | } | 3832 | } |
| 3829 | 3833 | ||
| @@ -3894,8 +3898,15 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
| 3894 | ifmgd->status_received = false; | 3898 | ifmgd->status_received = false; |
| 3895 | if (ifmgd->auth_data && ieee80211_is_auth(fc)) { | 3899 | if (ifmgd->auth_data && ieee80211_is_auth(fc)) { |
| 3896 | if (status_acked) { | 3900 | if (status_acked) { |
| 3897 | ifmgd->auth_data->timeout = | 3901 | if (ifmgd->auth_data->algorithm == |
| 3898 | jiffies + IEEE80211_AUTH_TIMEOUT_SHORT; | 3902 | WLAN_AUTH_SAE) |
| 3903 | ifmgd->auth_data->timeout = | ||
| 3904 | jiffies + | ||
| 3905 | IEEE80211_AUTH_TIMEOUT_SAE; | ||
| 3906 | else | ||
| 3907 | ifmgd->auth_data->timeout = | ||
| 3908 | jiffies + | ||
| 3909 | IEEE80211_AUTH_TIMEOUT_SHORT; | ||
| 3899 | run_again(sdata, ifmgd->auth_data->timeout); | 3910 | run_again(sdata, ifmgd->auth_data->timeout); |
| 3900 | } else { | 3911 | } else { |
| 3901 | ifmgd->auth_data->timeout = jiffies - 1; | 3912 | ifmgd->auth_data->timeout = jiffies - 1; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 535de3161a78..05a265cd573d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
| 5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
| 6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | 6 | * Copyright 2013-2014 Intel Mobile Communications GmbH |
| 7 | * Copyright (C) 2018 Intel Corporation | ||
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
| @@ -1135,7 +1136,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
| 1135 | } | 1136 | } |
| 1136 | 1137 | ||
| 1137 | /* reset session timer */ | 1138 | /* reset session timer */ |
| 1138 | if (reset_agg_timer && tid_tx->timeout) | 1139 | if (reset_agg_timer) |
| 1139 | tid_tx->last_tx = jiffies; | 1140 | tid_tx->last_tx = jiffies; |
| 1140 | 1141 | ||
| 1141 | return queued; | 1142 | return queued; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 55342c4d5cec..2e2dd88fc79f 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -2606,13 +2606,13 @@ static int netlink_seq_show(struct seq_file *seq, void *v) | |||
| 2606 | { | 2606 | { |
| 2607 | if (v == SEQ_START_TOKEN) { | 2607 | if (v == SEQ_START_TOKEN) { |
| 2608 | seq_puts(seq, | 2608 | seq_puts(seq, |
| 2609 | "sk Eth Pid Groups " | 2609 | "sk Eth Pid Groups " |
| 2610 | "Rmem Wmem Dump Locks Drops Inode\n"); | 2610 | "Rmem Wmem Dump Locks Drops Inode\n"); |
| 2611 | } else { | 2611 | } else { |
| 2612 | struct sock *s = v; | 2612 | struct sock *s = v; |
| 2613 | struct netlink_sock *nlk = nlk_sk(s); | 2613 | struct netlink_sock *nlk = nlk_sk(s); |
| 2614 | 2614 | ||
| 2615 | seq_printf(seq, "%pK %-3d %-6u %08x %-8d %-8d %d %-8d %-8d %-8lu\n", | 2615 | seq_printf(seq, "%pK %-3d %-10u %08x %-8d %-8d %-5d %-8d %-8d %-8lu\n", |
| 2616 | s, | 2616 | s, |
| 2617 | s->sk_protocol, | 2617 | s->sk_protocol, |
| 2618 | nlk->portid, | 2618 | nlk->portid, |
diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c index d7da99a0b0b8..9696ef96b719 100644 --- a/net/nsh/nsh.c +++ b/net/nsh/nsh.c | |||
| @@ -57,6 +57,8 @@ int nsh_pop(struct sk_buff *skb) | |||
| 57 | return -ENOMEM; | 57 | return -ENOMEM; |
| 58 | nh = (struct nshhdr *)(skb->data); | 58 | nh = (struct nshhdr *)(skb->data); |
| 59 | length = nsh_hdr_len(nh); | 59 | length = nsh_hdr_len(nh); |
| 60 | if (length < NSH_BASE_HDR_LEN) | ||
| 61 | return -EINVAL; | ||
| 60 | inner_proto = tun_p_to_eth_p(nh->np); | 62 | inner_proto = tun_p_to_eth_p(nh->np); |
| 61 | if (!pskb_may_pull(skb, length)) | 63 | if (!pskb_may_pull(skb, length)) |
| 62 | return -ENOMEM; | 64 | return -ENOMEM; |
| @@ -90,6 +92,8 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, | |||
| 90 | if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN))) | 92 | if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN))) |
| 91 | goto out; | 93 | goto out; |
| 92 | nsh_len = nsh_hdr_len(nsh_hdr(skb)); | 94 | nsh_len = nsh_hdr_len(nsh_hdr(skb)); |
| 95 | if (nsh_len < NSH_BASE_HDR_LEN) | ||
| 96 | goto out; | ||
| 93 | if (unlikely(!pskb_may_pull(skb, nsh_len))) | 97 | if (unlikely(!pskb_may_pull(skb, nsh_len))) |
| 94 | goto out; | 98 | goto out; |
| 95 | 99 | ||
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 7322aa1e382e..492ab0c36f7c 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
| @@ -1712,13 +1712,10 @@ static void nlattr_set(struct nlattr *attr, u8 val, | |||
| 1712 | 1712 | ||
| 1713 | /* The nlattr stream should already have been validated */ | 1713 | /* The nlattr stream should already have been validated */ |
| 1714 | nla_for_each_nested(nla, attr, rem) { | 1714 | nla_for_each_nested(nla, attr, rem) { |
| 1715 | if (tbl[nla_type(nla)].len == OVS_ATTR_NESTED) { | 1715 | if (tbl[nla_type(nla)].len == OVS_ATTR_NESTED) |
| 1716 | if (tbl[nla_type(nla)].next) | 1716 | nlattr_set(nla, val, tbl[nla_type(nla)].next ? : tbl); |
| 1717 | tbl = tbl[nla_type(nla)].next; | 1717 | else |
| 1718 | nlattr_set(nla, val, tbl); | ||
| 1719 | } else { | ||
| 1720 | memset(nla_data(nla), val, nla_len(nla)); | 1718 | memset(nla_data(nla), val, nla_len(nla)); |
| 1721 | } | ||
| 1722 | 1719 | ||
| 1723 | if (nla_type(nla) == OVS_KEY_ATTR_CT_STATE) | 1720 | if (nla_type(nla) == OVS_KEY_ATTR_CT_STATE) |
| 1724 | *(u32 *)nla_data(nla) &= CT_SUPPORTED_MASK; | 1721 | *(u32 *)nla_data(nla) &= CT_SUPPORTED_MASK; |
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index eea1d8611b20..13b38ad0fa4a 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
| @@ -547,7 +547,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
| 547 | rdsdebug("conn %p pd %p cq %p %p\n", conn, ic->i_pd, | 547 | rdsdebug("conn %p pd %p cq %p %p\n", conn, ic->i_pd, |
| 548 | ic->i_send_cq, ic->i_recv_cq); | 548 | ic->i_send_cq, ic->i_recv_cq); |
| 549 | 549 | ||
| 550 | return ret; | 550 | goto out; |
| 551 | 551 | ||
| 552 | sends_out: | 552 | sends_out: |
| 553 | vfree(ic->i_sends); | 553 | vfree(ic->i_sends); |
| @@ -572,6 +572,7 @@ send_cq_out: | |||
| 572 | ic->i_send_cq = NULL; | 572 | ic->i_send_cq = NULL; |
| 573 | rds_ibdev_out: | 573 | rds_ibdev_out: |
| 574 | rds_ib_remove_conn(rds_ibdev, conn); | 574 | rds_ib_remove_conn(rds_ibdev, conn); |
| 575 | out: | ||
| 575 | rds_ib_dev_put(rds_ibdev); | 576 | rds_ib_dev_put(rds_ibdev); |
| 576 | 577 | ||
| 577 | return ret; | 578 | return ret; |
diff --git a/net/rds/recv.c b/net/rds/recv.c index de50e2126e40..dc67458b52f0 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
| @@ -558,6 +558,7 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg, | |||
| 558 | struct rds_cmsg_rx_trace t; | 558 | struct rds_cmsg_rx_trace t; |
| 559 | int i, j; | 559 | int i, j; |
| 560 | 560 | ||
| 561 | memset(&t, 0, sizeof(t)); | ||
| 561 | inc->i_rx_lat_trace[RDS_MSG_RX_CMSG] = local_clock(); | 562 | inc->i_rx_lat_trace[RDS_MSG_RX_CMSG] = local_clock(); |
| 562 | t.rx_traces = rs->rs_rx_traces; | 563 | t.rx_traces = rs->rs_rx_traces; |
| 563 | for (i = 0; i < rs->rs_rx_traces; i++) { | 564 | for (i = 0; i < rs->rs_rx_traces; i++) { |
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index 41bd496531d4..00192a996be0 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c | |||
| @@ -137,13 +137,18 @@ static int rfkill_gpio_probe(struct platform_device *pdev) | |||
| 137 | 137 | ||
| 138 | ret = rfkill_register(rfkill->rfkill_dev); | 138 | ret = rfkill_register(rfkill->rfkill_dev); |
| 139 | if (ret < 0) | 139 | if (ret < 0) |
| 140 | return ret; | 140 | goto err_destroy; |
| 141 | 141 | ||
| 142 | platform_set_drvdata(pdev, rfkill); | 142 | platform_set_drvdata(pdev, rfkill); |
| 143 | 143 | ||
| 144 | dev_info(&pdev->dev, "%s device registered.\n", rfkill->name); | 144 | dev_info(&pdev->dev, "%s device registered.\n", rfkill->name); |
| 145 | 145 | ||
| 146 | return 0; | 146 | return 0; |
| 147 | |||
| 148 | err_destroy: | ||
| 149 | rfkill_destroy(rfkill->rfkill_dev); | ||
| 150 | |||
| 151 | return ret; | ||
| 147 | } | 152 | } |
| 148 | 153 | ||
| 149 | static int rfkill_gpio_remove(struct platform_device *pdev) | 154 | static int rfkill_gpio_remove(struct platform_device *pdev) |
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 9a2c8e7c000e..2b463047dd7b 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
| @@ -313,7 +313,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, | |||
| 313 | memset(&cp, 0, sizeof(cp)); | 313 | memset(&cp, 0, sizeof(cp)); |
| 314 | cp.local = rx->local; | 314 | cp.local = rx->local; |
| 315 | cp.key = key; | 315 | cp.key = key; |
| 316 | cp.security_level = 0; | 316 | cp.security_level = rx->min_sec_level; |
| 317 | cp.exclusive = false; | 317 | cp.exclusive = false; |
| 318 | cp.upgrade = upgrade; | 318 | cp.upgrade = upgrade; |
| 319 | cp.service_id = srx->srx_service; | 319 | cp.service_id = srx->srx_service; |
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 90d7079e0aa9..19975d2ca9a2 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h | |||
| @@ -476,6 +476,7 @@ enum rxrpc_call_flag { | |||
| 476 | RXRPC_CALL_SEND_PING, /* A ping will need to be sent */ | 476 | RXRPC_CALL_SEND_PING, /* A ping will need to be sent */ |
| 477 | RXRPC_CALL_PINGING, /* Ping in process */ | 477 | RXRPC_CALL_PINGING, /* Ping in process */ |
| 478 | RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */ | 478 | RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */ |
| 479 | RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */ | ||
| 479 | }; | 480 | }; |
| 480 | 481 | ||
| 481 | /* | 482 | /* |
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index c717152070df..1350f1be8037 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c | |||
| @@ -40,7 +40,7 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
| 40 | } __attribute__((packed)) pkt; | 40 | } __attribute__((packed)) pkt; |
| 41 | struct rxrpc_ackinfo ack_info; | 41 | struct rxrpc_ackinfo ack_info; |
| 42 | size_t len; | 42 | size_t len; |
| 43 | int ioc; | 43 | int ret, ioc; |
| 44 | u32 serial, mtu, call_id, padding; | 44 | u32 serial, mtu, call_id, padding; |
| 45 | 45 | ||
| 46 | _enter("%d", conn->debug_id); | 46 | _enter("%d", conn->debug_id); |
| @@ -135,10 +135,13 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
| 135 | break; | 135 | break; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len); | 138 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len); |
| 139 | conn->params.peer->last_tx_at = ktime_get_real(); | 139 | conn->params.peer->last_tx_at = ktime_get_real(); |
| 140 | if (ret < 0) | ||
| 141 | trace_rxrpc_tx_fail(conn->debug_id, serial, ret, | ||
| 142 | rxrpc_tx_fail_call_final_resend); | ||
| 143 | |||
| 140 | _leave(""); | 144 | _leave(""); |
| 141 | return; | ||
| 142 | } | 145 | } |
| 143 | 146 | ||
| 144 | /* | 147 | /* |
| @@ -236,6 +239,8 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn, | |||
| 236 | 239 | ||
| 237 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len); | 240 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len); |
| 238 | if (ret < 0) { | 241 | if (ret < 0) { |
| 242 | trace_rxrpc_tx_fail(conn->debug_id, serial, ret, | ||
| 243 | rxrpc_tx_fail_conn_abort); | ||
| 239 | _debug("sendmsg failed: %d", ret); | 244 | _debug("sendmsg failed: %d", ret); |
| 240 | return -EAGAIN; | 245 | return -EAGAIN; |
| 241 | } | 246 | } |
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 0410d2277ca2..b5fd6381313d 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
| @@ -971,7 +971,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call, | |||
| 971 | if (timo) { | 971 | if (timo) { |
| 972 | unsigned long now = jiffies, expect_rx_by; | 972 | unsigned long now = jiffies, expect_rx_by; |
| 973 | 973 | ||
| 974 | expect_rx_by = jiffies + timo; | 974 | expect_rx_by = now + timo; |
| 975 | WRITE_ONCE(call->expect_rx_by, expect_rx_by); | 975 | WRITE_ONCE(call->expect_rx_by, expect_rx_by); |
| 976 | rxrpc_reduce_call_timer(call, expect_rx_by, now, | 976 | rxrpc_reduce_call_timer(call, expect_rx_by, now, |
| 977 | rxrpc_timer_set_for_normal); | 977 | rxrpc_timer_set_for_normal); |
diff --git a/net/rxrpc/local_event.c b/net/rxrpc/local_event.c index 93b5d910b4a1..8325f1b86840 100644 --- a/net/rxrpc/local_event.c +++ b/net/rxrpc/local_event.c | |||
| @@ -71,7 +71,8 @@ static void rxrpc_send_version_request(struct rxrpc_local *local, | |||
| 71 | 71 | ||
| 72 | ret = kernel_sendmsg(local->socket, &msg, iov, 2, len); | 72 | ret = kernel_sendmsg(local->socket, &msg, iov, 2, len); |
| 73 | if (ret < 0) | 73 | if (ret < 0) |
| 74 | _debug("sendmsg failed: %d", ret); | 74 | trace_rxrpc_tx_fail(local->debug_id, 0, ret, |
| 75 | rxrpc_tx_fail_version_reply); | ||
| 75 | 76 | ||
| 76 | _leave(""); | 77 | _leave(""); |
| 77 | } | 78 | } |
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c index 8b54e9531d52..b493e6b62740 100644 --- a/net/rxrpc/local_object.c +++ b/net/rxrpc/local_object.c | |||
| @@ -134,22 +134,49 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net) | |||
| 134 | } | 134 | } |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | /* we want to receive ICMP errors */ | 137 | switch (local->srx.transport.family) { |
| 138 | opt = 1; | 138 | case AF_INET: |
| 139 | ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR, | 139 | /* we want to receive ICMP errors */ |
| 140 | (char *) &opt, sizeof(opt)); | 140 | opt = 1; |
| 141 | if (ret < 0) { | 141 | ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR, |
| 142 | _debug("setsockopt failed"); | 142 | (char *) &opt, sizeof(opt)); |
| 143 | goto error; | 143 | if (ret < 0) { |
| 144 | } | 144 | _debug("setsockopt failed"); |
| 145 | goto error; | ||
| 146 | } | ||
| 145 | 147 | ||
| 146 | /* we want to set the don't fragment bit */ | 148 | /* we want to set the don't fragment bit */ |
| 147 | opt = IP_PMTUDISC_DO; | 149 | opt = IP_PMTUDISC_DO; |
| 148 | ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER, | 150 | ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER, |
| 149 | (char *) &opt, sizeof(opt)); | 151 | (char *) &opt, sizeof(opt)); |
| 150 | if (ret < 0) { | 152 | if (ret < 0) { |
| 151 | _debug("setsockopt failed"); | 153 | _debug("setsockopt failed"); |
| 152 | goto error; | 154 | goto error; |
| 155 | } | ||
| 156 | break; | ||
| 157 | |||
| 158 | case AF_INET6: | ||
| 159 | /* we want to receive ICMP errors */ | ||
| 160 | opt = 1; | ||
| 161 | ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR, | ||
| 162 | (char *) &opt, sizeof(opt)); | ||
| 163 | if (ret < 0) { | ||
| 164 | _debug("setsockopt failed"); | ||
| 165 | goto error; | ||
| 166 | } | ||
| 167 | |||
| 168 | /* we want to set the don't fragment bit */ | ||
| 169 | opt = IPV6_PMTUDISC_DO; | ||
| 170 | ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER, | ||
| 171 | (char *) &opt, sizeof(opt)); | ||
| 172 | if (ret < 0) { | ||
| 173 | _debug("setsockopt failed"); | ||
| 174 | goto error; | ||
| 175 | } | ||
| 176 | break; | ||
| 177 | |||
| 178 | default: | ||
| 179 | BUG(); | ||
| 153 | } | 180 | } |
| 154 | 181 | ||
| 155 | /* set the socket up */ | 182 | /* set the socket up */ |
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c index 7f1fc04775b3..f03de1c59ba3 100644 --- a/net/rxrpc/output.c +++ b/net/rxrpc/output.c | |||
| @@ -210,6 +210,9 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping, | |||
| 210 | if (ping) | 210 | if (ping) |
| 211 | call->ping_time = now; | 211 | call->ping_time = now; |
| 212 | conn->params.peer->last_tx_at = ktime_get_real(); | 212 | conn->params.peer->last_tx_at = ktime_get_real(); |
| 213 | if (ret < 0) | ||
| 214 | trace_rxrpc_tx_fail(call->debug_id, serial, ret, | ||
| 215 | rxrpc_tx_fail_call_ack); | ||
| 213 | 216 | ||
| 214 | if (call->state < RXRPC_CALL_COMPLETE) { | 217 | if (call->state < RXRPC_CALL_COMPLETE) { |
| 215 | if (ret < 0) { | 218 | if (ret < 0) { |
| @@ -294,6 +297,10 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call) | |||
| 294 | ret = kernel_sendmsg(conn->params.local->socket, | 297 | ret = kernel_sendmsg(conn->params.local->socket, |
| 295 | &msg, iov, 1, sizeof(pkt)); | 298 | &msg, iov, 1, sizeof(pkt)); |
| 296 | conn->params.peer->last_tx_at = ktime_get_real(); | 299 | conn->params.peer->last_tx_at = ktime_get_real(); |
| 300 | if (ret < 0) | ||
| 301 | trace_rxrpc_tx_fail(call->debug_id, serial, ret, | ||
| 302 | rxrpc_tx_fail_call_abort); | ||
| 303 | |||
| 297 | 304 | ||
| 298 | rxrpc_put_connection(conn); | 305 | rxrpc_put_connection(conn); |
| 299 | return ret; | 306 | return ret; |
| @@ -387,6 +394,9 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb, | |||
| 387 | conn->params.peer->last_tx_at = ktime_get_real(); | 394 | conn->params.peer->last_tx_at = ktime_get_real(); |
| 388 | 395 | ||
| 389 | up_read(&conn->params.local->defrag_sem); | 396 | up_read(&conn->params.local->defrag_sem); |
| 397 | if (ret < 0) | ||
| 398 | trace_rxrpc_tx_fail(call->debug_id, serial, ret, | ||
| 399 | rxrpc_tx_fail_call_data_nofrag); | ||
| 390 | if (ret == -EMSGSIZE) | 400 | if (ret == -EMSGSIZE) |
| 391 | goto send_fragmentable; | 401 | goto send_fragmentable; |
| 392 | 402 | ||
| @@ -414,6 +424,17 @@ done: | |||
| 414 | rxrpc_timer_set_for_lost_ack); | 424 | rxrpc_timer_set_for_lost_ack); |
| 415 | } | 425 | } |
| 416 | } | 426 | } |
| 427 | |||
| 428 | if (sp->hdr.seq == 1 && | ||
| 429 | !test_and_set_bit(RXRPC_CALL_BEGAN_RX_TIMER, | ||
| 430 | &call->flags)) { | ||
| 431 | unsigned long nowj = jiffies, expect_rx_by; | ||
| 432 | |||
| 433 | expect_rx_by = nowj + call->next_rx_timo; | ||
| 434 | WRITE_ONCE(call->expect_rx_by, expect_rx_by); | ||
| 435 | rxrpc_reduce_call_timer(call, expect_rx_by, nowj, | ||
| 436 | rxrpc_timer_set_for_normal); | ||
| 437 | } | ||
| 417 | } | 438 | } |
| 418 | 439 | ||
| 419 | rxrpc_set_keepalive(call); | 440 | rxrpc_set_keepalive(call); |
| @@ -465,6 +486,10 @@ send_fragmentable: | |||
| 465 | #endif | 486 | #endif |
| 466 | } | 487 | } |
| 467 | 488 | ||
| 489 | if (ret < 0) | ||
| 490 | trace_rxrpc_tx_fail(call->debug_id, serial, ret, | ||
| 491 | rxrpc_tx_fail_call_data_frag); | ||
| 492 | |||
| 468 | up_write(&conn->params.local->defrag_sem); | 493 | up_write(&conn->params.local->defrag_sem); |
| 469 | goto done; | 494 | goto done; |
| 470 | } | 495 | } |
| @@ -482,6 +507,7 @@ void rxrpc_reject_packets(struct rxrpc_local *local) | |||
| 482 | struct kvec iov[2]; | 507 | struct kvec iov[2]; |
| 483 | size_t size; | 508 | size_t size; |
| 484 | __be32 code; | 509 | __be32 code; |
| 510 | int ret; | ||
| 485 | 511 | ||
| 486 | _enter("%d", local->debug_id); | 512 | _enter("%d", local->debug_id); |
| 487 | 513 | ||
| @@ -516,7 +542,10 @@ void rxrpc_reject_packets(struct rxrpc_local *local) | |||
| 516 | whdr.flags ^= RXRPC_CLIENT_INITIATED; | 542 | whdr.flags ^= RXRPC_CLIENT_INITIATED; |
| 517 | whdr.flags &= RXRPC_CLIENT_INITIATED; | 543 | whdr.flags &= RXRPC_CLIENT_INITIATED; |
| 518 | 544 | ||
| 519 | kernel_sendmsg(local->socket, &msg, iov, 2, size); | 545 | ret = kernel_sendmsg(local->socket, &msg, iov, 2, size); |
| 546 | if (ret < 0) | ||
| 547 | trace_rxrpc_tx_fail(local->debug_id, 0, ret, | ||
| 548 | rxrpc_tx_fail_reject); | ||
| 520 | } | 549 | } |
| 521 | 550 | ||
| 522 | rxrpc_free_skb(skb, rxrpc_skb_rx_freed); | 551 | rxrpc_free_skb(skb, rxrpc_skb_rx_freed); |
| @@ -567,7 +596,8 @@ void rxrpc_send_keepalive(struct rxrpc_peer *peer) | |||
| 567 | 596 | ||
| 568 | ret = kernel_sendmsg(peer->local->socket, &msg, iov, 2, len); | 597 | ret = kernel_sendmsg(peer->local->socket, &msg, iov, 2, len); |
| 569 | if (ret < 0) | 598 | if (ret < 0) |
| 570 | _debug("sendmsg failed: %d", ret); | 599 | trace_rxrpc_tx_fail(peer->debug_id, 0, ret, |
| 600 | rxrpc_tx_fail_version_keepalive); | ||
| 571 | 601 | ||
| 572 | peer->last_tx_at = ktime_get_real(); | 602 | peer->last_tx_at = ktime_get_real(); |
| 573 | _leave(""); | 603 | _leave(""); |
diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c index 78c2f95d1f22..0ed8b651cec2 100644 --- a/net/rxrpc/peer_event.c +++ b/net/rxrpc/peer_event.c | |||
| @@ -28,39 +28,39 @@ static void rxrpc_store_error(struct rxrpc_peer *, struct sock_exterr_skb *); | |||
| 28 | * Find the peer associated with an ICMP packet. | 28 | * Find the peer associated with an ICMP packet. |
| 29 | */ | 29 | */ |
| 30 | static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, | 30 | static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, |
| 31 | const struct sk_buff *skb) | 31 | const struct sk_buff *skb, |
| 32 | struct sockaddr_rxrpc *srx) | ||
| 32 | { | 33 | { |
| 33 | struct sock_exterr_skb *serr = SKB_EXT_ERR(skb); | 34 | struct sock_exterr_skb *serr = SKB_EXT_ERR(skb); |
| 34 | struct sockaddr_rxrpc srx; | ||
| 35 | 35 | ||
| 36 | _enter(""); | 36 | _enter(""); |
| 37 | 37 | ||
| 38 | memset(&srx, 0, sizeof(srx)); | 38 | memset(srx, 0, sizeof(*srx)); |
| 39 | srx.transport_type = local->srx.transport_type; | 39 | srx->transport_type = local->srx.transport_type; |
| 40 | srx.transport_len = local->srx.transport_len; | 40 | srx->transport_len = local->srx.transport_len; |
| 41 | srx.transport.family = local->srx.transport.family; | 41 | srx->transport.family = local->srx.transport.family; |
| 42 | 42 | ||
| 43 | /* Can we see an ICMP4 packet on an ICMP6 listening socket? and vice | 43 | /* Can we see an ICMP4 packet on an ICMP6 listening socket? and vice |
| 44 | * versa? | 44 | * versa? |
| 45 | */ | 45 | */ |
| 46 | switch (srx.transport.family) { | 46 | switch (srx->transport.family) { |
| 47 | case AF_INET: | 47 | case AF_INET: |
| 48 | srx.transport.sin.sin_port = serr->port; | 48 | srx->transport.sin.sin_port = serr->port; |
| 49 | switch (serr->ee.ee_origin) { | 49 | switch (serr->ee.ee_origin) { |
| 50 | case SO_EE_ORIGIN_ICMP: | 50 | case SO_EE_ORIGIN_ICMP: |
| 51 | _net("Rx ICMP"); | 51 | _net("Rx ICMP"); |
| 52 | memcpy(&srx.transport.sin.sin_addr, | 52 | memcpy(&srx->transport.sin.sin_addr, |
| 53 | skb_network_header(skb) + serr->addr_offset, | 53 | skb_network_header(skb) + serr->addr_offset, |
| 54 | sizeof(struct in_addr)); | 54 | sizeof(struct in_addr)); |
| 55 | break; | 55 | break; |
| 56 | case SO_EE_ORIGIN_ICMP6: | 56 | case SO_EE_ORIGIN_ICMP6: |
| 57 | _net("Rx ICMP6 on v4 sock"); | 57 | _net("Rx ICMP6 on v4 sock"); |
| 58 | memcpy(&srx.transport.sin.sin_addr, | 58 | memcpy(&srx->transport.sin.sin_addr, |
| 59 | skb_network_header(skb) + serr->addr_offset + 12, | 59 | skb_network_header(skb) + serr->addr_offset + 12, |
| 60 | sizeof(struct in_addr)); | 60 | sizeof(struct in_addr)); |
| 61 | break; | 61 | break; |
| 62 | default: | 62 | default: |
| 63 | memcpy(&srx.transport.sin.sin_addr, &ip_hdr(skb)->saddr, | 63 | memcpy(&srx->transport.sin.sin_addr, &ip_hdr(skb)->saddr, |
| 64 | sizeof(struct in_addr)); | 64 | sizeof(struct in_addr)); |
| 65 | break; | 65 | break; |
| 66 | } | 66 | } |
| @@ -68,25 +68,25 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, | |||
| 68 | 68 | ||
| 69 | #ifdef CONFIG_AF_RXRPC_IPV6 | 69 | #ifdef CONFIG_AF_RXRPC_IPV6 |
| 70 | case AF_INET6: | 70 | case AF_INET6: |
| 71 | srx.transport.sin6.sin6_port = serr->port; | 71 | srx->transport.sin6.sin6_port = serr->port; |
| 72 | switch (serr->ee.ee_origin) { | 72 | switch (serr->ee.ee_origin) { |
| 73 | case SO_EE_ORIGIN_ICMP6: | 73 | case SO_EE_ORIGIN_ICMP6: |
| 74 | _net("Rx ICMP6"); | 74 | _net("Rx ICMP6"); |
| 75 | memcpy(&srx.transport.sin6.sin6_addr, | 75 | memcpy(&srx->transport.sin6.sin6_addr, |
| 76 | skb_network_header(skb) + serr->addr_offset, | 76 | skb_network_header(skb) + serr->addr_offset, |
| 77 | sizeof(struct in6_addr)); | 77 | sizeof(struct in6_addr)); |
| 78 | break; | 78 | break; |
| 79 | case SO_EE_ORIGIN_ICMP: | 79 | case SO_EE_ORIGIN_ICMP: |
| 80 | _net("Rx ICMP on v6 sock"); | 80 | _net("Rx ICMP on v6 sock"); |
| 81 | srx.transport.sin6.sin6_addr.s6_addr32[0] = 0; | 81 | srx->transport.sin6.sin6_addr.s6_addr32[0] = 0; |
| 82 | srx.transport.sin6.sin6_addr.s6_addr32[1] = 0; | 82 | srx->transport.sin6.sin6_addr.s6_addr32[1] = 0; |
| 83 | srx.transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); | 83 | srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); |
| 84 | memcpy(srx.transport.sin6.sin6_addr.s6_addr + 12, | 84 | memcpy(srx->transport.sin6.sin6_addr.s6_addr + 12, |
| 85 | skb_network_header(skb) + serr->addr_offset, | 85 | skb_network_header(skb) + serr->addr_offset, |
| 86 | sizeof(struct in_addr)); | 86 | sizeof(struct in_addr)); |
| 87 | break; | 87 | break; |
| 88 | default: | 88 | default: |
| 89 | memcpy(&srx.transport.sin6.sin6_addr, | 89 | memcpy(&srx->transport.sin6.sin6_addr, |
| 90 | &ipv6_hdr(skb)->saddr, | 90 | &ipv6_hdr(skb)->saddr, |
| 91 | sizeof(struct in6_addr)); | 91 | sizeof(struct in6_addr)); |
| 92 | break; | 92 | break; |
| @@ -98,7 +98,7 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, | |||
| 98 | BUG(); | 98 | BUG(); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | return rxrpc_lookup_peer_rcu(local, &srx); | 101 | return rxrpc_lookup_peer_rcu(local, srx); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | /* | 104 | /* |
| @@ -146,6 +146,7 @@ static void rxrpc_adjust_mtu(struct rxrpc_peer *peer, struct sock_exterr_skb *se | |||
| 146 | void rxrpc_error_report(struct sock *sk) | 146 | void rxrpc_error_report(struct sock *sk) |
| 147 | { | 147 | { |
| 148 | struct sock_exterr_skb *serr; | 148 | struct sock_exterr_skb *serr; |
| 149 | struct sockaddr_rxrpc srx; | ||
| 149 | struct rxrpc_local *local = sk->sk_user_data; | 150 | struct rxrpc_local *local = sk->sk_user_data; |
| 150 | struct rxrpc_peer *peer; | 151 | struct rxrpc_peer *peer; |
| 151 | struct sk_buff *skb; | 152 | struct sk_buff *skb; |
| @@ -166,7 +167,7 @@ void rxrpc_error_report(struct sock *sk) | |||
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | rcu_read_lock(); | 169 | rcu_read_lock(); |
| 169 | peer = rxrpc_lookup_peer_icmp_rcu(local, skb); | 170 | peer = rxrpc_lookup_peer_icmp_rcu(local, skb, &srx); |
| 170 | if (peer && !rxrpc_get_peer_maybe(peer)) | 171 | if (peer && !rxrpc_get_peer_maybe(peer)) |
| 171 | peer = NULL; | 172 | peer = NULL; |
| 172 | if (!peer) { | 173 | if (!peer) { |
| @@ -176,6 +177,8 @@ void rxrpc_error_report(struct sock *sk) | |||
| 176 | return; | 177 | return; |
| 177 | } | 178 | } |
| 178 | 179 | ||
| 180 | trace_rxrpc_rx_icmp(peer, &serr->ee, &srx); | ||
| 181 | |||
| 179 | if ((serr->ee.ee_origin == SO_EE_ORIGIN_ICMP && | 182 | if ((serr->ee.ee_origin == SO_EE_ORIGIN_ICMP && |
| 180 | serr->ee.ee_type == ICMP_DEST_UNREACH && | 183 | serr->ee.ee_type == ICMP_DEST_UNREACH && |
| 181 | serr->ee.ee_code == ICMP_FRAG_NEEDED)) { | 184 | serr->ee.ee_code == ICMP_FRAG_NEEDED)) { |
| @@ -209,9 +212,6 @@ static void rxrpc_store_error(struct rxrpc_peer *peer, | |||
| 209 | 212 | ||
| 210 | ee = &serr->ee; | 213 | ee = &serr->ee; |
| 211 | 214 | ||
| 212 | _net("Rx Error o=%d t=%d c=%d e=%d", | ||
| 213 | ee->ee_origin, ee->ee_type, ee->ee_code, ee->ee_errno); | ||
| 214 | |||
| 215 | err = ee->ee_errno; | 215 | err = ee->ee_errno; |
| 216 | 216 | ||
| 217 | switch (ee->ee_origin) { | 217 | switch (ee->ee_origin) { |
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c index 588fea0dd362..6c0ae27fff84 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c | |||
| @@ -664,7 +664,8 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn) | |||
| 664 | 664 | ||
| 665 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len); | 665 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len); |
| 666 | if (ret < 0) { | 666 | if (ret < 0) { |
| 667 | _debug("sendmsg failed: %d", ret); | 667 | trace_rxrpc_tx_fail(conn->debug_id, serial, ret, |
| 668 | rxrpc_tx_fail_conn_challenge); | ||
| 668 | return -EAGAIN; | 669 | return -EAGAIN; |
| 669 | } | 670 | } |
| 670 | 671 | ||
| @@ -719,7 +720,8 @@ static int rxkad_send_response(struct rxrpc_connection *conn, | |||
| 719 | 720 | ||
| 720 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 3, len); | 721 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 3, len); |
| 721 | if (ret < 0) { | 722 | if (ret < 0) { |
| 722 | _debug("sendmsg failed: %d", ret); | 723 | trace_rxrpc_tx_fail(conn->debug_id, serial, ret, |
| 724 | rxrpc_tx_fail_conn_response); | ||
| 723 | return -EAGAIN; | 725 | return -EAGAIN; |
| 724 | } | 726 | } |
| 725 | 727 | ||
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index 206e802ccbdc..be01f9c5d963 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c | |||
| @@ -223,6 +223,15 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, | |||
| 223 | 223 | ||
| 224 | ret = rxrpc_send_data_packet(call, skb, false); | 224 | ret = rxrpc_send_data_packet(call, skb, false); |
| 225 | if (ret < 0) { | 225 | if (ret < 0) { |
| 226 | switch (ret) { | ||
| 227 | case -ENETUNREACH: | ||
| 228 | case -EHOSTUNREACH: | ||
| 229 | case -ECONNREFUSED: | ||
| 230 | rxrpc_set_call_completion(call, | ||
| 231 | RXRPC_CALL_LOCAL_ERROR, | ||
| 232 | 0, ret); | ||
| 233 | goto out; | ||
| 234 | } | ||
| 226 | _debug("need instant resend %d", ret); | 235 | _debug("need instant resend %d", ret); |
| 227 | rxrpc_instant_resend(call, ix); | 236 | rxrpc_instant_resend(call, ix); |
| 228 | } else { | 237 | } else { |
| @@ -241,6 +250,7 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, | |||
| 241 | rxrpc_timer_set_for_send); | 250 | rxrpc_timer_set_for_send); |
| 242 | } | 251 | } |
| 243 | 252 | ||
| 253 | out: | ||
| 244 | rxrpc_free_skb(skb, rxrpc_skb_tx_freed); | 254 | rxrpc_free_skb(skb, rxrpc_skb_tx_freed); |
| 245 | _leave(""); | 255 | _leave(""); |
| 246 | } | 256 | } |
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index ddf69fc01bdf..6138d1d71900 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
| @@ -121,7 +121,8 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
| 121 | return 0; | 121 | return 0; |
| 122 | 122 | ||
| 123 | if (!flags) { | 123 | if (!flags) { |
| 124 | tcf_idr_release(*a, bind); | 124 | if (exists) |
| 125 | tcf_idr_release(*a, bind); | ||
| 125 | return -EINVAL; | 126 | return -EINVAL; |
| 126 | } | 127 | } |
| 127 | 128 | ||
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index bbcbdce732cc..ad050d7d4b46 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c | |||
| @@ -131,8 +131,11 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, | |||
| 131 | if (exists && bind) | 131 | if (exists && bind) |
| 132 | return 0; | 132 | return 0; |
| 133 | 133 | ||
| 134 | if (!lflags) | 134 | if (!lflags) { |
| 135 | if (exists) | ||
| 136 | tcf_idr_release(*a, bind); | ||
| 135 | return -EINVAL; | 137 | return -EINVAL; |
| 138 | } | ||
| 136 | 139 | ||
| 137 | if (!exists) { | 140 | if (!exists) { |
| 138 | ret = tcf_idr_create(tn, parm->index, est, a, | 141 | ret = tcf_idr_create(tn, parm->index, est, a, |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index b66754f52a9f..963e4bf0aab8 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
| @@ -152,8 +152,8 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol, | |||
| 152 | NL_SET_ERR_MSG(extack, "TC classifier not found"); | 152 | NL_SET_ERR_MSG(extack, "TC classifier not found"); |
| 153 | err = -ENOENT; | 153 | err = -ENOENT; |
| 154 | } | 154 | } |
| 155 | goto errout; | ||
| 156 | #endif | 155 | #endif |
| 156 | goto errout; | ||
| 157 | } | 157 | } |
| 158 | tp->classify = tp->ops->classify; | 158 | tp->classify = tp->ops->classify; |
| 159 | tp->protocol = protocol; | 159 | tp->protocol = protocol; |
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index a366e4c9413a..4808713c73b9 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c | |||
| @@ -128,6 +128,28 @@ static bool fq_flow_is_detached(const struct fq_flow *f) | |||
| 128 | return f->next == &detached; | 128 | return f->next == &detached; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | static bool fq_flow_is_throttled(const struct fq_flow *f) | ||
| 132 | { | ||
| 133 | return f->next == &throttled; | ||
| 134 | } | ||
| 135 | |||
| 136 | static void fq_flow_add_tail(struct fq_flow_head *head, struct fq_flow *flow) | ||
| 137 | { | ||
| 138 | if (head->first) | ||
| 139 | head->last->next = flow; | ||
| 140 | else | ||
| 141 | head->first = flow; | ||
| 142 | head->last = flow; | ||
| 143 | flow->next = NULL; | ||
| 144 | } | ||
| 145 | |||
| 146 | static void fq_flow_unset_throttled(struct fq_sched_data *q, struct fq_flow *f) | ||
| 147 | { | ||
| 148 | rb_erase(&f->rate_node, &q->delayed); | ||
| 149 | q->throttled_flows--; | ||
| 150 | fq_flow_add_tail(&q->old_flows, f); | ||
| 151 | } | ||
| 152 | |||
| 131 | static void fq_flow_set_throttled(struct fq_sched_data *q, struct fq_flow *f) | 153 | static void fq_flow_set_throttled(struct fq_sched_data *q, struct fq_flow *f) |
| 132 | { | 154 | { |
| 133 | struct rb_node **p = &q->delayed.rb_node, *parent = NULL; | 155 | struct rb_node **p = &q->delayed.rb_node, *parent = NULL; |
| @@ -155,15 +177,6 @@ static void fq_flow_set_throttled(struct fq_sched_data *q, struct fq_flow *f) | |||
| 155 | 177 | ||
| 156 | static struct kmem_cache *fq_flow_cachep __read_mostly; | 178 | static struct kmem_cache *fq_flow_cachep __read_mostly; |
| 157 | 179 | ||
| 158 | static void fq_flow_add_tail(struct fq_flow_head *head, struct fq_flow *flow) | ||
| 159 | { | ||
| 160 | if (head->first) | ||
| 161 | head->last->next = flow; | ||
| 162 | else | ||
| 163 | head->first = flow; | ||
| 164 | head->last = flow; | ||
| 165 | flow->next = NULL; | ||
| 166 | } | ||
| 167 | 180 | ||
| 168 | /* limit number of collected flows per round */ | 181 | /* limit number of collected flows per round */ |
| 169 | #define FQ_GC_MAX 8 | 182 | #define FQ_GC_MAX 8 |
| @@ -267,6 +280,8 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q) | |||
| 267 | f->socket_hash != sk->sk_hash)) { | 280 | f->socket_hash != sk->sk_hash)) { |
| 268 | f->credit = q->initial_quantum; | 281 | f->credit = q->initial_quantum; |
| 269 | f->socket_hash = sk->sk_hash; | 282 | f->socket_hash = sk->sk_hash; |
| 283 | if (fq_flow_is_throttled(f)) | ||
| 284 | fq_flow_unset_throttled(q, f); | ||
| 270 | f->time_next_packet = 0ULL; | 285 | f->time_next_packet = 0ULL; |
| 271 | } | 286 | } |
| 272 | return f; | 287 | return f; |
| @@ -438,9 +453,7 @@ static void fq_check_throttled(struct fq_sched_data *q, u64 now) | |||
| 438 | q->time_next_delayed_flow = f->time_next_packet; | 453 | q->time_next_delayed_flow = f->time_next_packet; |
| 439 | break; | 454 | break; |
| 440 | } | 455 | } |
| 441 | rb_erase(p, &q->delayed); | 456 | fq_flow_unset_throttled(q, f); |
| 442 | q->throttled_flows--; | ||
| 443 | fq_flow_add_tail(&q->old_flows, f); | ||
| 444 | } | 457 | } |
| 445 | } | 458 | } |
| 446 | 459 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 837806dd5799..a47179da24e6 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -1024,8 +1024,9 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) | |||
| 1024 | struct sctp_endpoint *ep; | 1024 | struct sctp_endpoint *ep; |
| 1025 | struct sctp_chunk *chunk; | 1025 | struct sctp_chunk *chunk; |
| 1026 | struct sctp_inq *inqueue; | 1026 | struct sctp_inq *inqueue; |
| 1027 | int state; | 1027 | int first_time = 1; /* is this the first time through the loop */ |
| 1028 | int error = 0; | 1028 | int error = 0; |
| 1029 | int state; | ||
| 1029 | 1030 | ||
| 1030 | /* The association should be held so we should be safe. */ | 1031 | /* The association should be held so we should be safe. */ |
| 1031 | ep = asoc->ep; | 1032 | ep = asoc->ep; |
| @@ -1036,6 +1037,30 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) | |||
| 1036 | state = asoc->state; | 1037 | state = asoc->state; |
| 1037 | subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); | 1038 | subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); |
| 1038 | 1039 | ||
| 1040 | /* If the first chunk in the packet is AUTH, do special | ||
| 1041 | * processing specified in Section 6.3 of SCTP-AUTH spec | ||
| 1042 | */ | ||
| 1043 | if (first_time && subtype.chunk == SCTP_CID_AUTH) { | ||
| 1044 | struct sctp_chunkhdr *next_hdr; | ||
| 1045 | |||
| 1046 | next_hdr = sctp_inq_peek(inqueue); | ||
| 1047 | if (!next_hdr) | ||
| 1048 | goto normal; | ||
| 1049 | |||
| 1050 | /* If the next chunk is COOKIE-ECHO, skip the AUTH | ||
| 1051 | * chunk while saving a pointer to it so we can do | ||
| 1052 | * Authentication later (during cookie-echo | ||
| 1053 | * processing). | ||
| 1054 | */ | ||
| 1055 | if (next_hdr->type == SCTP_CID_COOKIE_ECHO) { | ||
| 1056 | chunk->auth_chunk = skb_clone(chunk->skb, | ||
| 1057 | GFP_ATOMIC); | ||
| 1058 | chunk->auth = 1; | ||
| 1059 | continue; | ||
| 1060 | } | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | normal: | ||
| 1039 | /* SCTP-AUTH, Section 6.3: | 1064 | /* SCTP-AUTH, Section 6.3: |
| 1040 | * The receiver has a list of chunk types which it expects | 1065 | * The receiver has a list of chunk types which it expects |
| 1041 | * to be received only after an AUTH-chunk. This list has | 1066 | * to be received only after an AUTH-chunk. This list has |
| @@ -1074,6 +1099,9 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) | |||
| 1074 | /* If there is an error on chunk, discard this packet. */ | 1099 | /* If there is an error on chunk, discard this packet. */ |
| 1075 | if (error && chunk) | 1100 | if (error && chunk) |
| 1076 | chunk->pdiscard = 1; | 1101 | chunk->pdiscard = 1; |
| 1102 | |||
| 1103 | if (first_time) | ||
| 1104 | first_time = 0; | ||
| 1077 | } | 1105 | } |
| 1078 | sctp_association_put(asoc); | 1106 | sctp_association_put(asoc); |
| 1079 | } | 1107 | } |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 23ebc5318edc..eb93ffe2408b 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
| @@ -217,7 +217,7 @@ new_skb: | |||
| 217 | skb_pull(chunk->skb, sizeof(*ch)); | 217 | skb_pull(chunk->skb, sizeof(*ch)); |
| 218 | chunk->subh.v = NULL; /* Subheader is no longer valid. */ | 218 | chunk->subh.v = NULL; /* Subheader is no longer valid. */ |
| 219 | 219 | ||
| 220 | if (chunk->chunk_end + sizeof(*ch) < skb_tail_pointer(chunk->skb)) { | 220 | if (chunk->chunk_end + sizeof(*ch) <= skb_tail_pointer(chunk->skb)) { |
| 221 | /* This is not a singleton */ | 221 | /* This is not a singleton */ |
| 222 | chunk->singleton = 0; | 222 | chunk->singleton = 0; |
| 223 | } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) { | 223 | } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) { |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 2e3f7b75a8ec..42247110d842 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
| @@ -895,6 +895,9 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1, | |||
| 895 | if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2)) | 895 | if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2)) |
| 896 | return 1; | 896 | return 1; |
| 897 | 897 | ||
| 898 | if (addr1->sa.sa_family == AF_INET && addr2->sa.sa_family == AF_INET) | ||
| 899 | return addr1->v4.sin_addr.s_addr == addr2->v4.sin_addr.s_addr; | ||
| 900 | |||
| 898 | return __sctp_v6_cmp_addr(addr1, addr2); | 901 | return __sctp_v6_cmp_addr(addr1, addr2); |
| 899 | } | 902 | } |
| 900 | 903 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 5a4fb1dc8400..e62addb60434 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
| @@ -1152,7 +1152,7 @@ struct sctp_chunk *sctp_make_violation_max_retrans( | |||
| 1152 | const struct sctp_association *asoc, | 1152 | const struct sctp_association *asoc, |
| 1153 | const struct sctp_chunk *chunk) | 1153 | const struct sctp_chunk *chunk) |
| 1154 | { | 1154 | { |
| 1155 | static const char error[] = "Association exceeded its max_retans count"; | 1155 | static const char error[] = "Association exceeded its max_retrans count"; |
| 1156 | size_t payload_len = sizeof(error) + sizeof(struct sctp_errhdr); | 1156 | size_t payload_len = sizeof(error) + sizeof(struct sctp_errhdr); |
| 1157 | struct sctp_chunk *retval; | 1157 | struct sctp_chunk *retval; |
| 1158 | 1158 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index dd0594a10961..c9ae3404b1bb 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -153,10 +153,7 @@ static enum sctp_disposition sctp_sf_violation_chunk( | |||
| 153 | struct sctp_cmd_seq *commands); | 153 | struct sctp_cmd_seq *commands); |
| 154 | 154 | ||
| 155 | static enum sctp_ierror sctp_sf_authenticate( | 155 | static enum sctp_ierror sctp_sf_authenticate( |
| 156 | struct net *net, | ||
| 157 | const struct sctp_endpoint *ep, | ||
| 158 | const struct sctp_association *asoc, | 156 | const struct sctp_association *asoc, |
| 159 | const union sctp_subtype type, | ||
| 160 | struct sctp_chunk *chunk); | 157 | struct sctp_chunk *chunk); |
| 161 | 158 | ||
| 162 | static enum sctp_disposition __sctp_sf_do_9_1_abort( | 159 | static enum sctp_disposition __sctp_sf_do_9_1_abort( |
| @@ -626,6 +623,38 @@ enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net, | |||
| 626 | return SCTP_DISPOSITION_CONSUME; | 623 | return SCTP_DISPOSITION_CONSUME; |
| 627 | } | 624 | } |
| 628 | 625 | ||
| 626 | static bool sctp_auth_chunk_verify(struct net *net, struct sctp_chunk *chunk, | ||
| 627 | const struct sctp_association *asoc) | ||
| 628 | { | ||
| 629 | struct sctp_chunk auth; | ||
| 630 | |||
| 631 | if (!chunk->auth_chunk) | ||
| 632 | return true; | ||
| 633 | |||
| 634 | /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo | ||
| 635 | * is supposed to be authenticated and we have to do delayed | ||
| 636 | * authentication. We've just recreated the association using | ||
| 637 | * the information in the cookie and now it's much easier to | ||
| 638 | * do the authentication. | ||
| 639 | */ | ||
| 640 | |||
| 641 | /* Make sure that we and the peer are AUTH capable */ | ||
| 642 | if (!net->sctp.auth_enable || !asoc->peer.auth_capable) | ||
| 643 | return false; | ||
| 644 | |||
| 645 | /* set-up our fake chunk so that we can process it */ | ||
| 646 | auth.skb = chunk->auth_chunk; | ||
| 647 | auth.asoc = chunk->asoc; | ||
| 648 | auth.sctp_hdr = chunk->sctp_hdr; | ||
| 649 | auth.chunk_hdr = (struct sctp_chunkhdr *) | ||
| 650 | skb_push(chunk->auth_chunk, | ||
| 651 | sizeof(struct sctp_chunkhdr)); | ||
| 652 | skb_pull(chunk->auth_chunk, sizeof(struct sctp_chunkhdr)); | ||
| 653 | auth.transport = chunk->transport; | ||
| 654 | |||
| 655 | return sctp_sf_authenticate(asoc, &auth) == SCTP_IERROR_NO_ERROR; | ||
| 656 | } | ||
| 657 | |||
| 629 | /* | 658 | /* |
| 630 | * Respond to a normal COOKIE ECHO chunk. | 659 | * Respond to a normal COOKIE ECHO chunk. |
| 631 | * We are the side that is being asked for an association. | 660 | * We are the side that is being asked for an association. |
| @@ -763,37 +792,9 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, | |||
| 763 | if (error) | 792 | if (error) |
| 764 | goto nomem_init; | 793 | goto nomem_init; |
| 765 | 794 | ||
| 766 | /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo | 795 | if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) { |
| 767 | * is supposed to be authenticated and we have to do delayed | 796 | sctp_association_free(new_asoc); |
| 768 | * authentication. We've just recreated the association using | 797 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); |
| 769 | * the information in the cookie and now it's much easier to | ||
| 770 | * do the authentication. | ||
| 771 | */ | ||
| 772 | if (chunk->auth_chunk) { | ||
| 773 | struct sctp_chunk auth; | ||
| 774 | enum sctp_ierror ret; | ||
| 775 | |||
| 776 | /* Make sure that we and the peer are AUTH capable */ | ||
| 777 | if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { | ||
| 778 | sctp_association_free(new_asoc); | ||
| 779 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | ||
| 780 | } | ||
| 781 | |||
| 782 | /* set-up our fake chunk so that we can process it */ | ||
| 783 | auth.skb = chunk->auth_chunk; | ||
| 784 | auth.asoc = chunk->asoc; | ||
| 785 | auth.sctp_hdr = chunk->sctp_hdr; | ||
| 786 | auth.chunk_hdr = (struct sctp_chunkhdr *) | ||
| 787 | skb_push(chunk->auth_chunk, | ||
| 788 | sizeof(struct sctp_chunkhdr)); | ||
| 789 | skb_pull(chunk->auth_chunk, sizeof(struct sctp_chunkhdr)); | ||
| 790 | auth.transport = chunk->transport; | ||
| 791 | |||
| 792 | ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth); | ||
| 793 | if (ret != SCTP_IERROR_NO_ERROR) { | ||
| 794 | sctp_association_free(new_asoc); | ||
| 795 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | ||
| 796 | } | ||
| 797 | } | 798 | } |
| 798 | 799 | ||
| 799 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 800 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
| @@ -1794,13 +1795,18 @@ static enum sctp_disposition sctp_sf_do_dupcook_a( | |||
| 1794 | GFP_ATOMIC)) | 1795 | GFP_ATOMIC)) |
| 1795 | goto nomem; | 1796 | goto nomem; |
| 1796 | 1797 | ||
| 1798 | if (sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC)) | ||
| 1799 | goto nomem; | ||
| 1800 | |||
| 1801 | if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) | ||
| 1802 | return SCTP_DISPOSITION_DISCARD; | ||
| 1803 | |||
| 1797 | /* Make sure no new addresses are being added during the | 1804 | /* Make sure no new addresses are being added during the |
| 1798 | * restart. Though this is a pretty complicated attack | 1805 | * restart. Though this is a pretty complicated attack |
| 1799 | * since you'd have to get inside the cookie. | 1806 | * since you'd have to get inside the cookie. |
| 1800 | */ | 1807 | */ |
| 1801 | if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) { | 1808 | if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) |
| 1802 | return SCTP_DISPOSITION_CONSUME; | 1809 | return SCTP_DISPOSITION_CONSUME; |
| 1803 | } | ||
| 1804 | 1810 | ||
| 1805 | /* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes | 1811 | /* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes |
| 1806 | * the peer has restarted (Action A), it MUST NOT setup a new | 1812 | * the peer has restarted (Action A), it MUST NOT setup a new |
| @@ -1906,6 +1912,12 @@ static enum sctp_disposition sctp_sf_do_dupcook_b( | |||
| 1906 | GFP_ATOMIC)) | 1912 | GFP_ATOMIC)) |
| 1907 | goto nomem; | 1913 | goto nomem; |
| 1908 | 1914 | ||
| 1915 | if (sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC)) | ||
| 1916 | goto nomem; | ||
| 1917 | |||
| 1918 | if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) | ||
| 1919 | return SCTP_DISPOSITION_DISCARD; | ||
| 1920 | |||
| 1909 | /* Update the content of current association. */ | 1921 | /* Update the content of current association. */ |
| 1910 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); | 1922 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); |
| 1911 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 1923 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, |
| @@ -2003,6 +2015,9 @@ static enum sctp_disposition sctp_sf_do_dupcook_d( | |||
| 2003 | * a COOKIE ACK. | 2015 | * a COOKIE ACK. |
| 2004 | */ | 2016 | */ |
| 2005 | 2017 | ||
| 2018 | if (!sctp_auth_chunk_verify(net, chunk, asoc)) | ||
| 2019 | return SCTP_DISPOSITION_DISCARD; | ||
| 2020 | |||
| 2006 | /* Don't accidentally move back into established state. */ | 2021 | /* Don't accidentally move back into established state. */ |
| 2007 | if (asoc->state < SCTP_STATE_ESTABLISHED) { | 2022 | if (asoc->state < SCTP_STATE_ESTABLISHED) { |
| 2008 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 2023 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
| @@ -2050,7 +2065,7 @@ static enum sctp_disposition sctp_sf_do_dupcook_d( | |||
| 2050 | } | 2065 | } |
| 2051 | } | 2066 | } |
| 2052 | 2067 | ||
| 2053 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 2068 | repl = sctp_make_cookie_ack(asoc, chunk); |
| 2054 | if (!repl) | 2069 | if (!repl) |
| 2055 | goto nomem; | 2070 | goto nomem; |
| 2056 | 2071 | ||
| @@ -4165,10 +4180,7 @@ gen_shutdown: | |||
| 4165 | * The return value is the disposition of the chunk. | 4180 | * The return value is the disposition of the chunk. |
| 4166 | */ | 4181 | */ |
| 4167 | static enum sctp_ierror sctp_sf_authenticate( | 4182 | static enum sctp_ierror sctp_sf_authenticate( |
| 4168 | struct net *net, | ||
| 4169 | const struct sctp_endpoint *ep, | ||
| 4170 | const struct sctp_association *asoc, | 4183 | const struct sctp_association *asoc, |
| 4171 | const union sctp_subtype type, | ||
| 4172 | struct sctp_chunk *chunk) | 4184 | struct sctp_chunk *chunk) |
| 4173 | { | 4185 | { |
| 4174 | struct sctp_shared_key *sh_key = NULL; | 4186 | struct sctp_shared_key *sh_key = NULL; |
| @@ -4269,7 +4281,7 @@ enum sctp_disposition sctp_sf_eat_auth(struct net *net, | |||
| 4269 | commands); | 4281 | commands); |
| 4270 | 4282 | ||
| 4271 | auth_hdr = (struct sctp_authhdr *)chunk->skb->data; | 4283 | auth_hdr = (struct sctp_authhdr *)chunk->skb->data; |
| 4272 | error = sctp_sf_authenticate(net, ep, asoc, type, chunk); | 4284 | error = sctp_sf_authenticate(asoc, chunk); |
| 4273 | switch (error) { | 4285 | switch (error) { |
| 4274 | case SCTP_IERROR_AUTH_BAD_HMAC: | 4286 | case SCTP_IERROR_AUTH_BAD_HMAC: |
| 4275 | /* Generate the ERROR chunk and discard the rest | 4287 | /* Generate the ERROR chunk and discard the rest |
diff --git a/net/sctp/stream.c b/net/sctp/stream.c index f799043abec9..f1f1d1b232ba 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c | |||
| @@ -240,6 +240,8 @@ void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new) | |||
| 240 | 240 | ||
| 241 | new->out = NULL; | 241 | new->out = NULL; |
| 242 | new->in = NULL; | 242 | new->in = NULL; |
| 243 | new->outcnt = 0; | ||
| 244 | new->incnt = 0; | ||
| 243 | } | 245 | } |
| 244 | 246 | ||
| 245 | static int sctp_send_reconf(struct sctp_association *asoc, | 247 | static int sctp_send_reconf(struct sctp_association *asoc, |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 84207ad33e8e..8cb7d9858270 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
| @@ -715,7 +715,6 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | |||
| 715 | return event; | 715 | return event; |
| 716 | 716 | ||
| 717 | fail_mark: | 717 | fail_mark: |
| 718 | sctp_chunk_put(chunk); | ||
| 719 | kfree_skb(skb); | 718 | kfree_skb(skb); |
| 720 | fail: | 719 | fail: |
| 721 | return NULL; | 720 | return NULL; |
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index f5d4b69dbabc..544bab42f925 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
| @@ -292,6 +292,17 @@ static void smc_copy_sock_settings_to_smc(struct smc_sock *smc) | |||
| 292 | smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC); | 292 | smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC); |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | /* register a new rmb */ | ||
| 296 | static int smc_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc) | ||
| 297 | { | ||
| 298 | /* register memory region for new rmb */ | ||
| 299 | if (smc_wr_reg_send(link, rmb_desc->mr_rx[SMC_SINGLE_LINK])) { | ||
| 300 | rmb_desc->regerr = 1; | ||
| 301 | return -EFAULT; | ||
| 302 | } | ||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 295 | static int smc_clnt_conf_first_link(struct smc_sock *smc) | 306 | static int smc_clnt_conf_first_link(struct smc_sock *smc) |
| 296 | { | 307 | { |
| 297 | struct smc_link_group *lgr = smc->conn.lgr; | 308 | struct smc_link_group *lgr = smc->conn.lgr; |
| @@ -321,9 +332,7 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc) | |||
| 321 | 332 | ||
| 322 | smc_wr_remember_qp_attr(link); | 333 | smc_wr_remember_qp_attr(link); |
| 323 | 334 | ||
| 324 | rc = smc_wr_reg_send(link, | 335 | if (smc_reg_rmb(link, smc->conn.rmb_desc)) |
| 325 | smc->conn.rmb_desc->mr_rx[SMC_SINGLE_LINK]); | ||
| 326 | if (rc) | ||
| 327 | return SMC_CLC_DECL_INTERR; | 336 | return SMC_CLC_DECL_INTERR; |
| 328 | 337 | ||
| 329 | /* send CONFIRM LINK response over RoCE fabric */ | 338 | /* send CONFIRM LINK response over RoCE fabric */ |
| @@ -473,13 +482,8 @@ static int smc_connect_rdma(struct smc_sock *smc) | |||
| 473 | goto decline_rdma_unlock; | 482 | goto decline_rdma_unlock; |
| 474 | } | 483 | } |
| 475 | } else { | 484 | } else { |
| 476 | struct smc_buf_desc *buf_desc = smc->conn.rmb_desc; | 485 | if (!smc->conn.rmb_desc->reused) { |
| 477 | 486 | if (smc_reg_rmb(link, smc->conn.rmb_desc)) { | |
| 478 | if (!buf_desc->reused) { | ||
| 479 | /* register memory region for new rmb */ | ||
| 480 | rc = smc_wr_reg_send(link, | ||
| 481 | buf_desc->mr_rx[SMC_SINGLE_LINK]); | ||
| 482 | if (rc) { | ||
| 483 | reason_code = SMC_CLC_DECL_INTERR; | 487 | reason_code = SMC_CLC_DECL_INTERR; |
| 484 | goto decline_rdma_unlock; | 488 | goto decline_rdma_unlock; |
| 485 | } | 489 | } |
| @@ -719,9 +723,7 @@ static int smc_serv_conf_first_link(struct smc_sock *smc) | |||
| 719 | 723 | ||
| 720 | link = &lgr->lnk[SMC_SINGLE_LINK]; | 724 | link = &lgr->lnk[SMC_SINGLE_LINK]; |
| 721 | 725 | ||
| 722 | rc = smc_wr_reg_send(link, | 726 | if (smc_reg_rmb(link, smc->conn.rmb_desc)) |
| 723 | smc->conn.rmb_desc->mr_rx[SMC_SINGLE_LINK]); | ||
| 724 | if (rc) | ||
| 725 | return SMC_CLC_DECL_INTERR; | 727 | return SMC_CLC_DECL_INTERR; |
| 726 | 728 | ||
| 727 | /* send CONFIRM LINK request to client over the RoCE fabric */ | 729 | /* send CONFIRM LINK request to client over the RoCE fabric */ |
| @@ -854,13 +856,8 @@ static void smc_listen_work(struct work_struct *work) | |||
| 854 | smc_rx_init(new_smc); | 856 | smc_rx_init(new_smc); |
| 855 | 857 | ||
| 856 | if (local_contact != SMC_FIRST_CONTACT) { | 858 | if (local_contact != SMC_FIRST_CONTACT) { |
| 857 | struct smc_buf_desc *buf_desc = new_smc->conn.rmb_desc; | 859 | if (!new_smc->conn.rmb_desc->reused) { |
| 858 | 860 | if (smc_reg_rmb(link, new_smc->conn.rmb_desc)) { | |
| 859 | if (!buf_desc->reused) { | ||
| 860 | /* register memory region for new rmb */ | ||
| 861 | rc = smc_wr_reg_send(link, | ||
| 862 | buf_desc->mr_rx[SMC_SINGLE_LINK]); | ||
| 863 | if (rc) { | ||
| 864 | reason_code = SMC_CLC_DECL_INTERR; | 861 | reason_code = SMC_CLC_DECL_INTERR; |
| 865 | goto decline_rdma_unlock; | 862 | goto decline_rdma_unlock; |
| 866 | } | 863 | } |
| @@ -978,10 +975,6 @@ static void smc_tcp_listen_work(struct work_struct *work) | |||
| 978 | } | 975 | } |
| 979 | 976 | ||
| 980 | out: | 977 | out: |
| 981 | if (lsmc->clcsock) { | ||
| 982 | sock_release(lsmc->clcsock); | ||
| 983 | lsmc->clcsock = NULL; | ||
| 984 | } | ||
| 985 | release_sock(lsk); | 978 | release_sock(lsk); |
| 986 | sock_put(&lsmc->sk); /* sock_hold in smc_listen */ | 979 | sock_put(&lsmc->sk); /* sock_hold in smc_listen */ |
| 987 | } | 980 | } |
| @@ -1170,13 +1163,15 @@ static __poll_t smc_poll(struct file *file, struct socket *sock, | |||
| 1170 | /* delegate to CLC child sock */ | 1163 | /* delegate to CLC child sock */ |
| 1171 | release_sock(sk); | 1164 | release_sock(sk); |
| 1172 | mask = smc->clcsock->ops->poll(file, smc->clcsock, wait); | 1165 | mask = smc->clcsock->ops->poll(file, smc->clcsock, wait); |
| 1173 | /* if non-blocking connect finished ... */ | ||
| 1174 | lock_sock(sk); | 1166 | lock_sock(sk); |
| 1175 | if ((sk->sk_state == SMC_INIT) && (mask & EPOLLOUT)) { | 1167 | sk->sk_err = smc->clcsock->sk->sk_err; |
| 1176 | sk->sk_err = smc->clcsock->sk->sk_err; | 1168 | if (sk->sk_err) { |
| 1177 | if (sk->sk_err) { | 1169 | mask |= EPOLLERR; |
| 1178 | mask |= EPOLLERR; | 1170 | } else { |
| 1179 | } else { | 1171 | /* if non-blocking connect finished ... */ |
| 1172 | if (sk->sk_state == SMC_INIT && | ||
| 1173 | mask & EPOLLOUT && | ||
| 1174 | smc->clcsock->sk->sk_state != TCP_CLOSE) { | ||
| 1180 | rc = smc_connect_rdma(smc); | 1175 | rc = smc_connect_rdma(smc); |
| 1181 | if (rc < 0) | 1176 | if (rc < 0) |
| 1182 | mask |= EPOLLERR; | 1177 | mask |= EPOLLERR; |
| @@ -1320,8 +1315,11 @@ static ssize_t smc_sendpage(struct socket *sock, struct page *page, | |||
| 1320 | 1315 | ||
| 1321 | smc = smc_sk(sk); | 1316 | smc = smc_sk(sk); |
| 1322 | lock_sock(sk); | 1317 | lock_sock(sk); |
| 1323 | if (sk->sk_state != SMC_ACTIVE) | 1318 | if (sk->sk_state != SMC_ACTIVE) { |
| 1319 | release_sock(sk); | ||
| 1324 | goto out; | 1320 | goto out; |
| 1321 | } | ||
| 1322 | release_sock(sk); | ||
| 1325 | if (smc->use_fallback) | 1323 | if (smc->use_fallback) |
| 1326 | rc = kernel_sendpage(smc->clcsock, page, offset, | 1324 | rc = kernel_sendpage(smc->clcsock, page, offset, |
| 1327 | size, flags); | 1325 | size, flags); |
| @@ -1329,7 +1327,6 @@ static ssize_t smc_sendpage(struct socket *sock, struct page *page, | |||
| 1329 | rc = sock_no_sendpage(sock, page, offset, size, flags); | 1327 | rc = sock_no_sendpage(sock, page, offset, size, flags); |
| 1330 | 1328 | ||
| 1331 | out: | 1329 | out: |
| 1332 | release_sock(sk); | ||
| 1333 | return rc; | 1330 | return rc; |
| 1334 | } | 1331 | } |
| 1335 | 1332 | ||
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index f44f6803f7ff..d4bd01bb44e1 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c | |||
| @@ -32,6 +32,9 @@ | |||
| 32 | 32 | ||
| 33 | static u32 smc_lgr_num; /* unique link group number */ | 33 | static u32 smc_lgr_num; /* unique link group number */ |
| 34 | 34 | ||
| 35 | static void smc_buf_free(struct smc_buf_desc *buf_desc, struct smc_link *lnk, | ||
| 36 | bool is_rmb); | ||
| 37 | |||
| 35 | static void smc_lgr_schedule_free_work(struct smc_link_group *lgr) | 38 | static void smc_lgr_schedule_free_work(struct smc_link_group *lgr) |
| 36 | { | 39 | { |
| 37 | /* client link group creation always follows the server link group | 40 | /* client link group creation always follows the server link group |
| @@ -234,9 +237,22 @@ static void smc_buf_unuse(struct smc_connection *conn) | |||
| 234 | conn->sndbuf_size = 0; | 237 | conn->sndbuf_size = 0; |
| 235 | } | 238 | } |
| 236 | if (conn->rmb_desc) { | 239 | if (conn->rmb_desc) { |
| 237 | conn->rmb_desc->reused = true; | 240 | if (!conn->rmb_desc->regerr) { |
| 238 | conn->rmb_desc->used = 0; | 241 | conn->rmb_desc->reused = 1; |
| 239 | conn->rmbe_size = 0; | 242 | conn->rmb_desc->used = 0; |
| 243 | conn->rmbe_size = 0; | ||
| 244 | } else { | ||
| 245 | /* buf registration failed, reuse not possible */ | ||
| 246 | struct smc_link_group *lgr = conn->lgr; | ||
| 247 | struct smc_link *lnk; | ||
| 248 | |||
| 249 | write_lock_bh(&lgr->rmbs_lock); | ||
| 250 | list_del(&conn->rmb_desc->list); | ||
| 251 | write_unlock_bh(&lgr->rmbs_lock); | ||
| 252 | |||
| 253 | lnk = &lgr->lnk[SMC_SINGLE_LINK]; | ||
| 254 | smc_buf_free(conn->rmb_desc, lnk, true); | ||
| 255 | } | ||
| 240 | } | 256 | } |
| 241 | } | 257 | } |
| 242 | 258 | ||
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h index 07e2a393e6d9..5dfcb15d529f 100644 --- a/net/smc/smc_core.h +++ b/net/smc/smc_core.h | |||
| @@ -123,7 +123,8 @@ struct smc_buf_desc { | |||
| 123 | */ | 123 | */ |
| 124 | u32 order; /* allocation order */ | 124 | u32 order; /* allocation order */ |
| 125 | u32 used; /* currently used / unused */ | 125 | u32 used; /* currently used / unused */ |
| 126 | bool reused; /* new created / reused */ | 126 | u8 reused : 1; /* new created / reused */ |
| 127 | u8 regerr : 1; /* err during registration */ | ||
| 127 | }; | 128 | }; |
| 128 | 129 | ||
| 129 | struct smc_rtoken { /* address/key of remote RMB */ | 130 | struct smc_rtoken { /* address/key of remote RMB */ |
diff --git a/net/sunrpc/xprtrdma/fmr_ops.c b/net/sunrpc/xprtrdma/fmr_ops.c index 5cc68a824f45..f2f63959fddd 100644 --- a/net/sunrpc/xprtrdma/fmr_ops.c +++ b/net/sunrpc/xprtrdma/fmr_ops.c | |||
| @@ -72,6 +72,7 @@ fmr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr) | |||
| 72 | if (IS_ERR(mr->fmr.fm_mr)) | 72 | if (IS_ERR(mr->fmr.fm_mr)) |
| 73 | goto out_fmr_err; | 73 | goto out_fmr_err; |
| 74 | 74 | ||
| 75 | INIT_LIST_HEAD(&mr->mr_list); | ||
| 75 | return 0; | 76 | return 0; |
| 76 | 77 | ||
| 77 | out_fmr_err: | 78 | out_fmr_err: |
| @@ -102,10 +103,6 @@ fmr_op_release_mr(struct rpcrdma_mr *mr) | |||
| 102 | LIST_HEAD(unmap_list); | 103 | LIST_HEAD(unmap_list); |
| 103 | int rc; | 104 | int rc; |
| 104 | 105 | ||
| 105 | /* Ensure MW is not on any rl_registered list */ | ||
| 106 | if (!list_empty(&mr->mr_list)) | ||
| 107 | list_del(&mr->mr_list); | ||
| 108 | |||
| 109 | kfree(mr->fmr.fm_physaddrs); | 106 | kfree(mr->fmr.fm_physaddrs); |
| 110 | kfree(mr->mr_sg); | 107 | kfree(mr->mr_sg); |
| 111 | 108 | ||
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index c5743a0960be..c59c5c788db0 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c | |||
| @@ -110,6 +110,7 @@ frwr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr) | |||
| 110 | if (!mr->mr_sg) | 110 | if (!mr->mr_sg) |
| 111 | goto out_list_err; | 111 | goto out_list_err; |
| 112 | 112 | ||
| 113 | INIT_LIST_HEAD(&mr->mr_list); | ||
| 113 | sg_init_table(mr->mr_sg, depth); | 114 | sg_init_table(mr->mr_sg, depth); |
| 114 | init_completion(&frwr->fr_linv_done); | 115 | init_completion(&frwr->fr_linv_done); |
| 115 | return 0; | 116 | return 0; |
| @@ -133,10 +134,6 @@ frwr_op_release_mr(struct rpcrdma_mr *mr) | |||
| 133 | { | 134 | { |
| 134 | int rc; | 135 | int rc; |
| 135 | 136 | ||
| 136 | /* Ensure MR is not on any rl_registered list */ | ||
| 137 | if (!list_empty(&mr->mr_list)) | ||
| 138 | list_del(&mr->mr_list); | ||
| 139 | |||
| 140 | rc = ib_dereg_mr(mr->frwr.fr_mr); | 137 | rc = ib_dereg_mr(mr->frwr.fr_mr); |
| 141 | if (rc) | 138 | if (rc) |
| 142 | pr_err("rpcrdma: final ib_dereg_mr for %p returned %i\n", | 139 | pr_err("rpcrdma: final ib_dereg_mr for %p returned %i\n", |
| @@ -195,7 +192,7 @@ frwr_op_recover_mr(struct rpcrdma_mr *mr) | |||
| 195 | return; | 192 | return; |
| 196 | 193 | ||
| 197 | out_release: | 194 | out_release: |
| 198 | pr_err("rpcrdma: FRWR reset failed %d, %p release\n", rc, mr); | 195 | pr_err("rpcrdma: FRWR reset failed %d, %p released\n", rc, mr); |
| 199 | r_xprt->rx_stats.mrs_orphaned++; | 196 | r_xprt->rx_stats.mrs_orphaned++; |
| 200 | 197 | ||
| 201 | spin_lock(&r_xprt->rx_buf.rb_mrlock); | 198 | spin_lock(&r_xprt->rx_buf.rb_mrlock); |
| @@ -476,7 +473,7 @@ frwr_op_reminv(struct rpcrdma_rep *rep, struct list_head *mrs) | |||
| 476 | 473 | ||
| 477 | list_for_each_entry(mr, mrs, mr_list) | 474 | list_for_each_entry(mr, mrs, mr_list) |
| 478 | if (mr->mr_handle == rep->rr_inv_rkey) { | 475 | if (mr->mr_handle == rep->rr_inv_rkey) { |
| 479 | list_del(&mr->mr_list); | 476 | list_del_init(&mr->mr_list); |
| 480 | trace_xprtrdma_remoteinv(mr); | 477 | trace_xprtrdma_remoteinv(mr); |
| 481 | mr->frwr.fr_state = FRWR_IS_INVALID; | 478 | mr->frwr.fr_state = FRWR_IS_INVALID; |
| 482 | rpcrdma_mr_unmap_and_put(mr); | 479 | rpcrdma_mr_unmap_and_put(mr); |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index fe5eaca2d197..c345d365af88 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
| @@ -1254,6 +1254,11 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf) | |||
| 1254 | list_del(&mr->mr_all); | 1254 | list_del(&mr->mr_all); |
| 1255 | 1255 | ||
| 1256 | spin_unlock(&buf->rb_mrlock); | 1256 | spin_unlock(&buf->rb_mrlock); |
| 1257 | |||
| 1258 | /* Ensure MW is not on any rl_registered list */ | ||
| 1259 | if (!list_empty(&mr->mr_list)) | ||
| 1260 | list_del(&mr->mr_list); | ||
| 1261 | |||
| 1257 | ia->ri_ops->ro_release_mr(mr); | 1262 | ia->ri_ops->ro_release_mr(mr); |
| 1258 | count++; | 1263 | count++; |
| 1259 | spin_lock(&buf->rb_mrlock); | 1264 | spin_lock(&buf->rb_mrlock); |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 3d3b423fa9c1..cb41b12a3bf8 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
| @@ -380,7 +380,7 @@ rpcrdma_mr_pop(struct list_head *list) | |||
| 380 | struct rpcrdma_mr *mr; | 380 | struct rpcrdma_mr *mr; |
| 381 | 381 | ||
| 382 | mr = list_first_entry(list, struct rpcrdma_mr, mr_list); | 382 | mr = list_first_entry(list, struct rpcrdma_mr, mr_list); |
| 383 | list_del(&mr->mr_list); | 383 | list_del_init(&mr->mr_list); |
| 384 | return mr; | 384 | return mr; |
| 385 | } | 385 | } |
| 386 | 386 | ||
diff --git a/net/tipc/node.c b/net/tipc/node.c index 6f98b56dd48e..f29549de9245 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
| @@ -1950,6 +1950,7 @@ out: | |||
| 1950 | int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info) | 1950 | int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info) |
| 1951 | { | 1951 | { |
| 1952 | struct net *net = genl_info_net(info); | 1952 | struct net *net = genl_info_net(info); |
| 1953 | struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; | ||
| 1953 | struct tipc_nl_msg msg; | 1954 | struct tipc_nl_msg msg; |
| 1954 | char *name; | 1955 | char *name; |
| 1955 | int err; | 1956 | int err; |
| @@ -1957,9 +1958,19 @@ int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info) | |||
| 1957 | msg.portid = info->snd_portid; | 1958 | msg.portid = info->snd_portid; |
| 1958 | msg.seq = info->snd_seq; | 1959 | msg.seq = info->snd_seq; |
| 1959 | 1960 | ||
| 1960 | if (!info->attrs[TIPC_NLA_LINK_NAME]) | 1961 | if (!info->attrs[TIPC_NLA_LINK]) |
| 1961 | return -EINVAL; | 1962 | return -EINVAL; |
| 1962 | name = nla_data(info->attrs[TIPC_NLA_LINK_NAME]); | 1963 | |
| 1964 | err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX, | ||
| 1965 | info->attrs[TIPC_NLA_LINK], | ||
| 1966 | tipc_nl_link_policy, info->extack); | ||
| 1967 | if (err) | ||
| 1968 | return err; | ||
| 1969 | |||
| 1970 | if (!attrs[TIPC_NLA_LINK_NAME]) | ||
| 1971 | return -EINVAL; | ||
| 1972 | |||
| 1973 | name = nla_data(attrs[TIPC_NLA_LINK_NAME]); | ||
| 1963 | 1974 | ||
| 1964 | msg.skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 1975 | msg.skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); |
| 1965 | if (!msg.skb) | 1976 | if (!msg.skb) |
| @@ -2244,7 +2255,7 @@ int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2244 | 2255 | ||
| 2245 | rtnl_lock(); | 2256 | rtnl_lock(); |
| 2246 | for (bearer_id = prev_bearer; bearer_id < MAX_BEARERS; bearer_id++) { | 2257 | for (bearer_id = prev_bearer; bearer_id < MAX_BEARERS; bearer_id++) { |
| 2247 | err = __tipc_nl_add_monitor(net, &msg, prev_bearer); | 2258 | err = __tipc_nl_add_monitor(net, &msg, bearer_id); |
| 2248 | if (err) | 2259 | if (err) |
| 2249 | break; | 2260 | break; |
| 2250 | } | 2261 | } |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 252a52ae0893..6be21575503a 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -1516,10 +1516,10 @@ static void tipc_sk_set_orig_addr(struct msghdr *m, struct sk_buff *skb) | |||
| 1516 | 1516 | ||
| 1517 | srcaddr->sock.family = AF_TIPC; | 1517 | srcaddr->sock.family = AF_TIPC; |
| 1518 | srcaddr->sock.addrtype = TIPC_ADDR_ID; | 1518 | srcaddr->sock.addrtype = TIPC_ADDR_ID; |
| 1519 | srcaddr->sock.scope = 0; | ||
| 1519 | srcaddr->sock.addr.id.ref = msg_origport(hdr); | 1520 | srcaddr->sock.addr.id.ref = msg_origport(hdr); |
| 1520 | srcaddr->sock.addr.id.node = msg_orignode(hdr); | 1521 | srcaddr->sock.addr.id.node = msg_orignode(hdr); |
| 1521 | srcaddr->sock.addr.name.domain = 0; | 1522 | srcaddr->sock.addr.name.domain = 0; |
| 1522 | srcaddr->sock.scope = 0; | ||
| 1523 | m->msg_namelen = sizeof(struct sockaddr_tipc); | 1523 | m->msg_namelen = sizeof(struct sockaddr_tipc); |
| 1524 | 1524 | ||
| 1525 | if (!msg_in_group(hdr)) | 1525 | if (!msg_in_group(hdr)) |
| @@ -1528,6 +1528,7 @@ static void tipc_sk_set_orig_addr(struct msghdr *m, struct sk_buff *skb) | |||
| 1528 | /* Group message users may also want to know sending member's id */ | 1528 | /* Group message users may also want to know sending member's id */ |
| 1529 | srcaddr->member.family = AF_TIPC; | 1529 | srcaddr->member.family = AF_TIPC; |
| 1530 | srcaddr->member.addrtype = TIPC_ADDR_NAME; | 1530 | srcaddr->member.addrtype = TIPC_ADDR_NAME; |
| 1531 | srcaddr->member.scope = 0; | ||
| 1531 | srcaddr->member.addr.name.name.type = msg_nametype(hdr); | 1532 | srcaddr->member.addr.name.name.type = msg_nametype(hdr); |
| 1532 | srcaddr->member.addr.name.name.instance = TIPC_SKB_CB(skb)->orig_member; | 1533 | srcaddr->member.addr.name.name.instance = TIPC_SKB_CB(skb)->orig_member; |
| 1533 | srcaddr->member.addr.name.domain = 0; | 1534 | srcaddr->member.addr.name.domain = 0; |
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index 0d379970960e..20cd93be6236 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
| @@ -114,6 +114,7 @@ int tls_push_sg(struct sock *sk, | |||
| 114 | size = sg->length - offset; | 114 | size = sg->length - offset; |
| 115 | offset += sg->offset; | 115 | offset += sg->offset; |
| 116 | 116 | ||
| 117 | ctx->in_tcp_sendpages = true; | ||
| 117 | while (1) { | 118 | while (1) { |
| 118 | if (sg_is_last(sg)) | 119 | if (sg_is_last(sg)) |
| 119 | sendpage_flags = flags; | 120 | sendpage_flags = flags; |
| @@ -134,6 +135,7 @@ retry: | |||
| 134 | offset -= sg->offset; | 135 | offset -= sg->offset; |
| 135 | ctx->partially_sent_offset = offset; | 136 | ctx->partially_sent_offset = offset; |
| 136 | ctx->partially_sent_record = (void *)sg; | 137 | ctx->partially_sent_record = (void *)sg; |
| 138 | ctx->in_tcp_sendpages = false; | ||
| 137 | return ret; | 139 | return ret; |
| 138 | } | 140 | } |
| 139 | 141 | ||
| @@ -148,6 +150,8 @@ retry: | |||
| 148 | } | 150 | } |
| 149 | 151 | ||
| 150 | clear_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags); | 152 | clear_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags); |
| 153 | ctx->in_tcp_sendpages = false; | ||
| 154 | ctx->sk_write_space(sk); | ||
| 151 | 155 | ||
| 152 | return 0; | 156 | return 0; |
| 153 | } | 157 | } |
| @@ -217,6 +221,10 @@ static void tls_write_space(struct sock *sk) | |||
| 217 | { | 221 | { |
| 218 | struct tls_context *ctx = tls_get_ctx(sk); | 222 | struct tls_context *ctx = tls_get_ctx(sk); |
| 219 | 223 | ||
| 224 | /* We are already sending pages, ignore notification */ | ||
| 225 | if (ctx->in_tcp_sendpages) | ||
| 226 | return; | ||
| 227 | |||
| 220 | if (!sk->sk_write_pending && tls_is_pending_closed_record(ctx)) { | 228 | if (!sk->sk_write_pending && tls_is_pending_closed_record(ctx)) { |
| 221 | gfp_t sk_allocation = sk->sk_allocation; | 229 | gfp_t sk_allocation = sk->sk_allocation; |
| 222 | int rc; | 230 | int rc; |
| @@ -241,16 +249,13 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) | |||
| 241 | struct tls_context *ctx = tls_get_ctx(sk); | 249 | struct tls_context *ctx = tls_get_ctx(sk); |
| 242 | long timeo = sock_sndtimeo(sk, 0); | 250 | long timeo = sock_sndtimeo(sk, 0); |
| 243 | void (*sk_proto_close)(struct sock *sk, long timeout); | 251 | void (*sk_proto_close)(struct sock *sk, long timeout); |
| 252 | bool free_ctx = false; | ||
| 244 | 253 | ||
| 245 | lock_sock(sk); | 254 | lock_sock(sk); |
| 246 | sk_proto_close = ctx->sk_proto_close; | 255 | sk_proto_close = ctx->sk_proto_close; |
| 247 | 256 | ||
| 248 | if (ctx->conf == TLS_HW_RECORD) | 257 | if (ctx->conf == TLS_BASE || ctx->conf == TLS_HW_RECORD) { |
| 249 | goto skip_tx_cleanup; | 258 | free_ctx = true; |
| 250 | |||
| 251 | if (ctx->conf == TLS_BASE) { | ||
| 252 | kfree(ctx); | ||
| 253 | ctx = NULL; | ||
| 254 | goto skip_tx_cleanup; | 259 | goto skip_tx_cleanup; |
| 255 | } | 260 | } |
| 256 | 261 | ||
| @@ -287,7 +292,7 @@ skip_tx_cleanup: | |||
| 287 | /* free ctx for TLS_HW_RECORD, used by tcp_set_state | 292 | /* free ctx for TLS_HW_RECORD, used by tcp_set_state |
| 288 | * for sk->sk_prot->unhash [tls_hw_unhash] | 293 | * for sk->sk_prot->unhash [tls_hw_unhash] |
| 289 | */ | 294 | */ |
| 290 | if (ctx && ctx->conf == TLS_HW_RECORD) | 295 | if (free_ctx) |
| 291 | kfree(ctx); | 296 | kfree(ctx); |
| 292 | } | 297 | } |
| 293 | 298 | ||
diff --git a/net/wireless/core.c b/net/wireless/core.c index a6f3cac8c640..c0fd8a85e7f7 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -95,6 +95,9 @@ static int cfg80211_dev_check_name(struct cfg80211_registered_device *rdev, | |||
| 95 | 95 | ||
| 96 | ASSERT_RTNL(); | 96 | ASSERT_RTNL(); |
| 97 | 97 | ||
| 98 | if (strlen(newname) > NL80211_WIPHY_NAME_MAXLEN) | ||
| 99 | return -EINVAL; | ||
| 100 | |||
| 98 | /* prohibit calling the thing phy%d when %d is not its number */ | 101 | /* prohibit calling the thing phy%d when %d is not its number */ |
| 99 | sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); | 102 | sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); |
| 100 | if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) { | 103 | if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) { |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ff28f8feeb09..a052693c2e85 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -9214,6 +9214,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
| 9214 | 9214 | ||
| 9215 | if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) { | 9215 | if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) { |
| 9216 | if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) { | 9216 | if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) { |
| 9217 | kzfree(connkeys); | ||
| 9217 | GENL_SET_ERR_MSG(info, | 9218 | GENL_SET_ERR_MSG(info, |
| 9218 | "external auth requires connection ownership"); | 9219 | "external auth requires connection ownership"); |
| 9219 | return -EINVAL; | 9220 | return -EINVAL; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 16c7e4ef5820..ac3e12c32aa3 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -1026,6 +1026,7 @@ static int regdb_query_country(const struct fwdb_header *db, | |||
| 1026 | 1026 | ||
| 1027 | if (!tmp_rd) { | 1027 | if (!tmp_rd) { |
| 1028 | kfree(regdom); | 1028 | kfree(regdom); |
| 1029 | kfree(wmm_ptrs); | ||
| 1029 | return -ENOMEM; | 1030 | return -ENOMEM; |
| 1030 | } | 1031 | } |
| 1031 | regdom = tmp_rd; | 1032 | regdom = tmp_rd; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index f9d2f2233f09..6c177ae7a6d9 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -2175,6 +2175,12 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family) | |||
| 2175 | return afinfo; | 2175 | return afinfo; |
| 2176 | } | 2176 | } |
| 2177 | 2177 | ||
| 2178 | void xfrm_flush_gc(void) | ||
| 2179 | { | ||
| 2180 | flush_work(&xfrm_state_gc_work); | ||
| 2181 | } | ||
| 2182 | EXPORT_SYMBOL(xfrm_flush_gc); | ||
| 2183 | |||
| 2178 | /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ | 2184 | /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ |
| 2179 | void xfrm_state_delete_tunnel(struct xfrm_state *x) | 2185 | void xfrm_state_delete_tunnel(struct xfrm_state *x) |
| 2180 | { | 2186 | { |
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 4d6a6edd4bf6..092947676143 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile | |||
| @@ -255,7 +255,7 @@ $(obj)/tracex5_kern.o: $(obj)/syscall_nrs.h | |||
| 255 | $(obj)/%.o: $(src)/%.c | 255 | $(obj)/%.o: $(src)/%.c |
| 256 | $(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) -I$(obj) \ | 256 | $(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) -I$(obj) \ |
| 257 | -I$(srctree)/tools/testing/selftests/bpf/ \ | 257 | -I$(srctree)/tools/testing/selftests/bpf/ \ |
| 258 | -D__KERNEL__ -Wno-unused-value -Wno-pointer-sign \ | 258 | -D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \ |
| 259 | -D__TARGET_ARCH_$(ARCH) -Wno-compare-distinct-pointer-types \ | 259 | -D__TARGET_ARCH_$(ARCH) -Wno-compare-distinct-pointer-types \ |
| 260 | -Wno-gnu-variable-sized-type-not-at-end \ | 260 | -Wno-gnu-variable-sized-type-not-at-end \ |
| 261 | -Wno-address-of-packed-member -Wno-tautological-compare \ | 261 | -Wno-address-of-packed-member -Wno-tautological-compare \ |
diff --git a/samples/sockmap/Makefile b/samples/sockmap/Makefile index 9bf2881bd11b..fa53f4d77834 100644 --- a/samples/sockmap/Makefile +++ b/samples/sockmap/Makefile | |||
| @@ -65,11 +65,14 @@ $(src)/*.c: verify_target_bpf | |||
| 65 | # asm/sysreg.h - inline assembly used by it is incompatible with llvm. | 65 | # asm/sysreg.h - inline assembly used by it is incompatible with llvm. |
| 66 | # But, there is no easy way to fix it, so just exclude it since it is | 66 | # But, there is no easy way to fix it, so just exclude it since it is |
| 67 | # useless for BPF samples. | 67 | # useless for BPF samples. |
| 68 | # | ||
| 69 | # -target bpf option required with SK_MSG programs, this is to ensure | ||
| 70 | # reading 'void *' data types for data and data_end are __u64 reads. | ||
| 68 | $(obj)/%.o: $(src)/%.c | 71 | $(obj)/%.o: $(src)/%.c |
| 69 | $(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) -I$(obj) \ | 72 | $(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) -I$(obj) \ |
| 70 | -D__KERNEL__ -D__ASM_SYSREG_H -Wno-unused-value -Wno-pointer-sign \ | 73 | -D__KERNEL__ -D__ASM_SYSREG_H -Wno-unused-value -Wno-pointer-sign \ |
| 71 | -Wno-compare-distinct-pointer-types \ | 74 | -Wno-compare-distinct-pointer-types \ |
| 72 | -Wno-gnu-variable-sized-type-not-at-end \ | 75 | -Wno-gnu-variable-sized-type-not-at-end \ |
| 73 | -Wno-address-of-packed-member -Wno-tautological-compare \ | 76 | -Wno-address-of-packed-member -Wno-tautological-compare \ |
| 74 | -Wno-unknown-warning-option \ | 77 | -Wno-unknown-warning-option -O2 -target bpf \ |
| 75 | -O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@ | 78 | -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@ |
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index b2a95af7df18..7f5c86246138 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins | |||
| @@ -14,7 +14,7 @@ ifdef CONFIG_GCC_PLUGINS | |||
| 14 | endif | 14 | endif |
| 15 | 15 | ||
| 16 | ifdef CONFIG_GCC_PLUGIN_SANCOV | 16 | ifdef CONFIG_GCC_PLUGIN_SANCOV |
| 17 | ifeq ($(CFLAGS_KCOV),) | 17 | ifeq ($(strip $(CFLAGS_KCOV)),) |
| 18 | # It is needed because of the gcc-plugin.sh and gcc version checks. | 18 | # It is needed because of the gcc-plugin.sh and gcc version checks. |
| 19 | gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so | 19 | gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so |
| 20 | 20 | ||
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 07d07409f16f..5af34a2b0cd9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
| @@ -196,7 +196,7 @@ $(obj)/%.tab.c: $(src)/%.y FORCE | |||
| 196 | $(call if_changed,bison) | 196 | $(call if_changed,bison) |
| 197 | 197 | ||
| 198 | quiet_cmd_bison_h = YACC $@ | 198 | quiet_cmd_bison_h = YACC $@ |
| 199 | cmd_bison_h = bison -o/dev/null --defines=$@ -t -l $< | 199 | cmd_bison_h = $(YACC) -o/dev/null --defines=$@ -t -l $< |
| 200 | 200 | ||
| 201 | $(obj)/%.tab.h: $(src)/%.y FORCE | 201 | $(obj)/%.tab.h: $(src)/%.y FORCE |
| 202 | $(call if_changed,bison_h) | 202 | $(call if_changed,bison_h) |
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index c07ba4da9e36..815eaf140ab5 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c | |||
| @@ -787,10 +787,9 @@ static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node * | |||
| 787 | FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); | 787 | FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); |
| 788 | 788 | ||
| 789 | prop = get_property(node, "bus-range"); | 789 | prop = get_property(node, "bus-range"); |
| 790 | if (!prop) { | 790 | if (!prop) |
| 791 | FAIL(c, dti, node, "missing bus-range for PCI bridge"); | ||
| 792 | return; | 791 | return; |
| 793 | } | 792 | |
| 794 | if (prop->val.len != (sizeof(cell_t) * 2)) { | 793 | if (prop->val.len != (sizeof(cell_t) * 2)) { |
| 795 | FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); | 794 | FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); |
| 796 | return; | 795 | return; |
diff --git a/scripts/extract_xc3028.pl b/scripts/extract_xc3028.pl index 61d9b256c658..a1c51b7e4baf 100755 --- a/scripts/extract_xc3028.pl +++ b/scripts/extract_xc3028.pl | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #!/usr/bin/env perl | 1 | #!/usr/bin/env perl |
| 2 | 2 | ||
| 3 | # Copyright (c) Mauro Carvalho Chehab <mchehab@infradead.org> | 3 | # Copyright (c) Mauro Carvalho Chehab <mchehab@kernel.org> |
| 4 | # Released under GPLv2 | 4 | # Released under GPLv2 |
| 5 | # | 5 | # |
| 6 | # In order to use, you need to: | 6 | # In order to use, you need to: |
diff --git a/scripts/faddr2line b/scripts/faddr2line index 9e5735a4d3a5..1876a741087c 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line | |||
| @@ -170,7 +170,10 @@ __faddr2line() { | |||
| 170 | echo "$file_lines" | while read -r line | 170 | echo "$file_lines" | while read -r line |
| 171 | do | 171 | do |
| 172 | echo $line | 172 | echo $line |
| 173 | eval $(echo $line | awk -F "[ :]" '{printf("n1=%d;n2=%d;f=%s",$NF-5, $NF+5, $(NF-1))}') | 173 | n=$(echo $line | sed 's/.*:\([0-9]\+\).*/\1/g') |
| 174 | n1=$[$n-5] | ||
| 175 | n2=$[$n+5] | ||
| 176 | f=$(echo $line | sed 's/.*at \(.\+\):.*/\1/g') | ||
| 174 | awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") {printf("%d\t%s\n", NR, $0)}' $f | 177 | awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") {printf("%d\t%s\n", NR, $0)}' $f |
| 175 | done | 178 | done |
| 176 | 179 | ||
diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index ef0287e42957..03b7ce97de14 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile | |||
| @@ -14,14 +14,14 @@ genksyms-objs := genksyms.o parse.tab.o lex.lex.o | |||
| 14 | # so that 'bison: not found' will be displayed if it is missing. | 14 | # so that 'bison: not found' will be displayed if it is missing. |
| 15 | ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) | 15 | ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) |
| 16 | 16 | ||
| 17 | quiet_cmd_bison_no_warn = $(quet_cmd_bison) | 17 | quiet_cmd_bison_no_warn = $(quiet_cmd_bison) |
| 18 | cmd_bison_no_warn = $(YACC) --version >/dev/null; \ | 18 | cmd_bison_no_warn = $(YACC) --version >/dev/null; \ |
| 19 | $(cmd_bison) 2>/dev/null | 19 | $(cmd_bison) 2>/dev/null |
| 20 | 20 | ||
| 21 | $(obj)/parse.tab.c: $(src)/parse.y FORCE | 21 | $(obj)/parse.tab.c: $(src)/parse.y FORCE |
| 22 | $(call if_changed,bison_no_warn) | 22 | $(call if_changed,bison_no_warn) |
| 23 | 23 | ||
| 24 | quiet_cmd_bison_h_no_warn = $(quet_cmd_bison_h) | 24 | quiet_cmd_bison_h_no_warn = $(quiet_cmd_bison_h) |
| 25 | cmd_bison_h_no_warn = $(YACC) --version >/dev/null; \ | 25 | cmd_bison_h_no_warn = $(YACC) --version >/dev/null; \ |
| 26 | $(cmd_bison_h) 2>/dev/null | 26 | $(cmd_bison_h) 2>/dev/null |
| 27 | 27 | ||
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 944418da9fe3..0f6dcb4011a8 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c | |||
| @@ -330,14 +330,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) | |||
| 330 | goto out; | 330 | goto out; |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | /* There will be a line like so: | 333 | /* Sum all files in the same dir or subdirs. */ |
| 334 | deps_drivers/net/dummy.o := \ | ||
| 335 | drivers/net/dummy.c \ | ||
| 336 | $(wildcard include/config/net/fastroute.h) \ | ||
| 337 | include/linux/module.h \ | ||
| 338 | |||
| 339 | Sum all files in the same dir or subdirs. | ||
| 340 | */ | ||
| 341 | while ((line = get_next_line(&pos, file, flen)) != NULL) { | 334 | while ((line = get_next_line(&pos, file, flen)) != NULL) { |
| 342 | char* p = line; | 335 | char* p = line; |
| 343 | 336 | ||
diff --git a/scripts/split-man.pl b/scripts/split-man.pl index bfe16cbe42df..c3db607ee9ec 100755 --- a/scripts/split-man.pl +++ b/scripts/split-man.pl | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #!/usr/bin/perl | 1 | #!/usr/bin/perl |
| 2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | # | 3 | # |
| 4 | # Author: Mauro Carvalho Chehab <mchehab@s-opensource.com> | 4 | # Author: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> |
| 5 | # | 5 | # |
| 6 | # Produce manpages from kernel-doc. | 6 | # Produce manpages from kernel-doc. |
| 7 | # See Documentation/doc-guide/kernel-doc.rst for instructions | 7 | # See Documentation/doc-guide/kernel-doc.rst for instructions |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4cafe6a19167..be5817df0a9d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -4576,6 +4576,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, | |||
| 4576 | static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) | 4576 | static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) |
| 4577 | { | 4577 | { |
| 4578 | struct sock *sk = sock->sk; | 4578 | struct sock *sk = sock->sk; |
| 4579 | struct sk_security_struct *sksec = sk->sk_security; | ||
| 4579 | u16 family; | 4580 | u16 family; |
| 4580 | int err; | 4581 | int err; |
| 4581 | 4582 | ||
| @@ -4587,11 +4588,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 4587 | family = sk->sk_family; | 4588 | family = sk->sk_family; |
| 4588 | if (family == PF_INET || family == PF_INET6) { | 4589 | if (family == PF_INET || family == PF_INET6) { |
| 4589 | char *addrp; | 4590 | char *addrp; |
| 4590 | struct sk_security_struct *sksec = sk->sk_security; | ||
| 4591 | struct common_audit_data ad; | 4591 | struct common_audit_data ad; |
| 4592 | struct lsm_network_audit net = {0,}; | 4592 | struct lsm_network_audit net = {0,}; |
| 4593 | struct sockaddr_in *addr4 = NULL; | 4593 | struct sockaddr_in *addr4 = NULL; |
| 4594 | struct sockaddr_in6 *addr6 = NULL; | 4594 | struct sockaddr_in6 *addr6 = NULL; |
| 4595 | u16 family_sa = address->sa_family; | ||
| 4595 | unsigned short snum; | 4596 | unsigned short snum; |
| 4596 | u32 sid, node_perm; | 4597 | u32 sid, node_perm; |
| 4597 | 4598 | ||
| @@ -4601,11 +4602,20 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 4601 | * need to check address->sa_family as it is possible to have | 4602 | * need to check address->sa_family as it is possible to have |
| 4602 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. | 4603 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. |
| 4603 | */ | 4604 | */ |
| 4604 | switch (address->sa_family) { | 4605 | switch (family_sa) { |
| 4606 | case AF_UNSPEC: | ||
| 4605 | case AF_INET: | 4607 | case AF_INET: |
| 4606 | if (addrlen < sizeof(struct sockaddr_in)) | 4608 | if (addrlen < sizeof(struct sockaddr_in)) |
| 4607 | return -EINVAL; | 4609 | return -EINVAL; |
| 4608 | addr4 = (struct sockaddr_in *)address; | 4610 | addr4 = (struct sockaddr_in *)address; |
| 4611 | if (family_sa == AF_UNSPEC) { | ||
| 4612 | /* see __inet_bind(), we only want to allow | ||
| 4613 | * AF_UNSPEC if the address is INADDR_ANY | ||
| 4614 | */ | ||
| 4615 | if (addr4->sin_addr.s_addr != htonl(INADDR_ANY)) | ||
| 4616 | goto err_af; | ||
| 4617 | family_sa = AF_INET; | ||
| 4618 | } | ||
| 4609 | snum = ntohs(addr4->sin_port); | 4619 | snum = ntohs(addr4->sin_port); |
| 4610 | addrp = (char *)&addr4->sin_addr.s_addr; | 4620 | addrp = (char *)&addr4->sin_addr.s_addr; |
| 4611 | break; | 4621 | break; |
| @@ -4617,15 +4627,14 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 4617 | addrp = (char *)&addr6->sin6_addr.s6_addr; | 4627 | addrp = (char *)&addr6->sin6_addr.s6_addr; |
| 4618 | break; | 4628 | break; |
| 4619 | default: | 4629 | default: |
| 4620 | /* Note that SCTP services expect -EINVAL, whereas | 4630 | goto err_af; |
| 4621 | * others expect -EAFNOSUPPORT. | ||
| 4622 | */ | ||
| 4623 | if (sksec->sclass == SECCLASS_SCTP_SOCKET) | ||
| 4624 | return -EINVAL; | ||
| 4625 | else | ||
| 4626 | return -EAFNOSUPPORT; | ||
| 4627 | } | 4631 | } |
| 4628 | 4632 | ||
| 4633 | ad.type = LSM_AUDIT_DATA_NET; | ||
| 4634 | ad.u.net = &net; | ||
| 4635 | ad.u.net->sport = htons(snum); | ||
| 4636 | ad.u.net->family = family_sa; | ||
| 4637 | |||
| 4629 | if (snum) { | 4638 | if (snum) { |
| 4630 | int low, high; | 4639 | int low, high; |
| 4631 | 4640 | ||
| @@ -4637,10 +4646,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 4637 | snum, &sid); | 4646 | snum, &sid); |
| 4638 | if (err) | 4647 | if (err) |
| 4639 | goto out; | 4648 | goto out; |
| 4640 | ad.type = LSM_AUDIT_DATA_NET; | ||
| 4641 | ad.u.net = &net; | ||
| 4642 | ad.u.net->sport = htons(snum); | ||
| 4643 | ad.u.net->family = family; | ||
| 4644 | err = avc_has_perm(&selinux_state, | 4649 | err = avc_has_perm(&selinux_state, |
| 4645 | sksec->sid, sid, | 4650 | sksec->sid, sid, |
| 4646 | sksec->sclass, | 4651 | sksec->sclass, |
| @@ -4672,16 +4677,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 4672 | break; | 4677 | break; |
| 4673 | } | 4678 | } |
| 4674 | 4679 | ||
| 4675 | err = sel_netnode_sid(addrp, family, &sid); | 4680 | err = sel_netnode_sid(addrp, family_sa, &sid); |
| 4676 | if (err) | 4681 | if (err) |
| 4677 | goto out; | 4682 | goto out; |
| 4678 | 4683 | ||
| 4679 | ad.type = LSM_AUDIT_DATA_NET; | 4684 | if (family_sa == AF_INET) |
| 4680 | ad.u.net = &net; | ||
| 4681 | ad.u.net->sport = htons(snum); | ||
| 4682 | ad.u.net->family = family; | ||
| 4683 | |||
| 4684 | if (address->sa_family == AF_INET) | ||
| 4685 | ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; | 4685 | ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; |
| 4686 | else | 4686 | else |
| 4687 | ad.u.net->v6info.saddr = addr6->sin6_addr; | 4687 | ad.u.net->v6info.saddr = addr6->sin6_addr; |
| @@ -4694,6 +4694,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 4694 | } | 4694 | } |
| 4695 | out: | 4695 | out: |
| 4696 | return err; | 4696 | return err; |
| 4697 | err_af: | ||
| 4698 | /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */ | ||
| 4699 | if (sksec->sclass == SECCLASS_SCTP_SOCKET) | ||
| 4700 | return -EINVAL; | ||
| 4701 | return -EAFNOSUPPORT; | ||
| 4697 | } | 4702 | } |
| 4698 | 4703 | ||
| 4699 | /* This supports connect(2) and SCTP connect services such as sctp_connectx(3) | 4704 | /* This supports connect(2) and SCTP connect services such as sctp_connectx(3) |
| @@ -4771,7 +4776,7 @@ static int selinux_socket_connect_helper(struct socket *sock, | |||
| 4771 | ad.type = LSM_AUDIT_DATA_NET; | 4776 | ad.type = LSM_AUDIT_DATA_NET; |
| 4772 | ad.u.net = &net; | 4777 | ad.u.net = &net; |
| 4773 | ad.u.net->dport = htons(snum); | 4778 | ad.u.net->dport = htons(snum); |
| 4774 | ad.u.net->family = sk->sk_family; | 4779 | ad.u.net->family = address->sa_family; |
| 4775 | err = avc_has_perm(&selinux_state, | 4780 | err = avc_has_perm(&selinux_state, |
| 4776 | sksec->sid, sid, sksec->sclass, perm, &ad); | 4781 | sksec->sid, sid, sksec->sclass, perm, &ad); |
| 4777 | if (err) | 4782 | if (err) |
| @@ -5272,6 +5277,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, | |||
| 5272 | while (walk_size < addrlen) { | 5277 | while (walk_size < addrlen) { |
| 5273 | addr = addr_buf; | 5278 | addr = addr_buf; |
| 5274 | switch (addr->sa_family) { | 5279 | switch (addr->sa_family) { |
| 5280 | case AF_UNSPEC: | ||
| 5275 | case AF_INET: | 5281 | case AF_INET: |
| 5276 | len = sizeof(struct sockaddr_in); | 5282 | len = sizeof(struct sockaddr_in); |
| 5277 | break; | 5283 | break; |
| @@ -5279,7 +5285,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, | |||
| 5279 | len = sizeof(struct sockaddr_in6); | 5285 | len = sizeof(struct sockaddr_in6); |
| 5280 | break; | 5286 | break; |
| 5281 | default: | 5287 | default: |
| 5282 | return -EAFNOSUPPORT; | 5288 | return -EINVAL; |
| 5283 | } | 5289 | } |
| 5284 | 5290 | ||
| 5285 | err = -EINVAL; | 5291 | err = -EINVAL; |
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index a848836a5de0..507fd5210c1c 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c | |||
| @@ -396,8 +396,7 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file, | |||
| 396 | if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) || | 396 | if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) || |
| 397 | copy_from_user(&data->type, &data32->type, 3 * sizeof(u32))) | 397 | copy_from_user(&data->type, &data32->type, 3 * sizeof(u32))) |
| 398 | goto error; | 398 | goto error; |
| 399 | if (get_user(data->owner, &data32->owner) || | 399 | if (get_user(data->owner, &data32->owner)) |
| 400 | get_user(data->type, &data32->type)) | ||
| 401 | goto error; | 400 | goto error; |
| 402 | switch (data->type) { | 401 | switch (data->type) { |
| 403 | case SNDRV_CTL_ELEM_TYPE_BOOLEAN: | 402 | case SNDRV_CTL_ELEM_TYPE_BOOLEAN: |
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index 06d7c40af570..6491afbb5fd5 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c | |||
| @@ -423,6 +423,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, | |||
| 423 | return -ENOTTY; | 423 | return -ENOTTY; |
| 424 | if (substream->stream != dir) | 424 | if (substream->stream != dir) |
| 425 | return -EINVAL; | 425 | return -EINVAL; |
| 426 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) | ||
| 427 | return -EBADFD; | ||
| 426 | 428 | ||
| 427 | if ((ch = substream->runtime->channels) > 128) | 429 | if ((ch = substream->runtime->channels) > 128) |
| 428 | return -EINVAL; | 430 | return -EINVAL; |
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index f48a4cd24ffc..289ae6bb81d9 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c | |||
| @@ -174,12 +174,12 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, | |||
| 174 | } | 174 | } |
| 175 | return; | 175 | return; |
| 176 | } | 176 | } |
| 177 | spin_lock_irqsave(&substream->runtime->lock, flags); | ||
| 177 | if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { | 178 | if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { |
| 178 | if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) | 179 | if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) |
| 179 | return; | 180 | goto out; |
| 180 | vmidi->event.type = SNDRV_SEQ_EVENT_NONE; | 181 | vmidi->event.type = SNDRV_SEQ_EVENT_NONE; |
| 181 | } | 182 | } |
| 182 | spin_lock_irqsave(&substream->runtime->lock, flags); | ||
| 183 | while (1) { | 183 | while (1) { |
| 184 | count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf)); | 184 | count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf)); |
| 185 | if (count <= 0) | 185 | if (count <= 0) |
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 58e349fc893f..eab7f594ebe7 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c | |||
| @@ -831,9 +831,11 @@ static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol, | |||
| 831 | { | 831 | { |
| 832 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); | 832 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); |
| 833 | 833 | ||
| 834 | mutex_lock(&loopback->cable_lock); | ||
| 834 | ucontrol->value.integer.value[0] = | 835 | ucontrol->value.integer.value[0] = |
| 835 | loopback->setup[kcontrol->id.subdevice] | 836 | loopback->setup[kcontrol->id.subdevice] |
| 836 | [kcontrol->id.device].rate_shift; | 837 | [kcontrol->id.device].rate_shift; |
| 838 | mutex_unlock(&loopback->cable_lock); | ||
| 837 | return 0; | 839 | return 0; |
| 838 | } | 840 | } |
| 839 | 841 | ||
| @@ -865,9 +867,11 @@ static int loopback_notify_get(struct snd_kcontrol *kcontrol, | |||
| 865 | { | 867 | { |
| 866 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); | 868 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); |
| 867 | 869 | ||
| 870 | mutex_lock(&loopback->cable_lock); | ||
| 868 | ucontrol->value.integer.value[0] = | 871 | ucontrol->value.integer.value[0] = |
| 869 | loopback->setup[kcontrol->id.subdevice] | 872 | loopback->setup[kcontrol->id.subdevice] |
| 870 | [kcontrol->id.device].notify; | 873 | [kcontrol->id.device].notify; |
| 874 | mutex_unlock(&loopback->cable_lock); | ||
| 871 | return 0; | 875 | return 0; |
| 872 | } | 876 | } |
| 873 | 877 | ||
| @@ -879,12 +883,14 @@ static int loopback_notify_put(struct snd_kcontrol *kcontrol, | |||
| 879 | int change = 0; | 883 | int change = 0; |
| 880 | 884 | ||
| 881 | val = ucontrol->value.integer.value[0] ? 1 : 0; | 885 | val = ucontrol->value.integer.value[0] ? 1 : 0; |
| 886 | mutex_lock(&loopback->cable_lock); | ||
| 882 | if (val != loopback->setup[kcontrol->id.subdevice] | 887 | if (val != loopback->setup[kcontrol->id.subdevice] |
| 883 | [kcontrol->id.device].notify) { | 888 | [kcontrol->id.device].notify) { |
| 884 | loopback->setup[kcontrol->id.subdevice] | 889 | loopback->setup[kcontrol->id.subdevice] |
| 885 | [kcontrol->id.device].notify = val; | 890 | [kcontrol->id.device].notify = val; |
| 886 | change = 1; | 891 | change = 1; |
| 887 | } | 892 | } |
| 893 | mutex_unlock(&loopback->cable_lock); | ||
| 888 | return change; | 894 | return change; |
| 889 | } | 895 | } |
| 890 | 896 | ||
| @@ -892,15 +898,18 @@ static int loopback_active_get(struct snd_kcontrol *kcontrol, | |||
| 892 | struct snd_ctl_elem_value *ucontrol) | 898 | struct snd_ctl_elem_value *ucontrol) |
| 893 | { | 899 | { |
| 894 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); | 900 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); |
| 895 | struct loopback_cable *cable = loopback->cables | 901 | struct loopback_cable *cable; |
| 896 | [kcontrol->id.subdevice][kcontrol->id.device ^ 1]; | 902 | |
| 897 | unsigned int val = 0; | 903 | unsigned int val = 0; |
| 898 | 904 | ||
| 905 | mutex_lock(&loopback->cable_lock); | ||
| 906 | cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1]; | ||
| 899 | if (cable != NULL) { | 907 | if (cable != NULL) { |
| 900 | unsigned int running = cable->running ^ cable->pause; | 908 | unsigned int running = cable->running ^ cable->pause; |
| 901 | 909 | ||
| 902 | val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0; | 910 | val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0; |
| 903 | } | 911 | } |
| 912 | mutex_unlock(&loopback->cable_lock); | ||
| 904 | ucontrol->value.integer.value[0] = val; | 913 | ucontrol->value.integer.value[0] = val; |
| 905 | return 0; | 914 | return 0; |
| 906 | } | 915 | } |
| @@ -943,9 +952,11 @@ static int loopback_rate_get(struct snd_kcontrol *kcontrol, | |||
| 943 | { | 952 | { |
| 944 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); | 953 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); |
| 945 | 954 | ||
| 955 | mutex_lock(&loopback->cable_lock); | ||
| 946 | ucontrol->value.integer.value[0] = | 956 | ucontrol->value.integer.value[0] = |
| 947 | loopback->setup[kcontrol->id.subdevice] | 957 | loopback->setup[kcontrol->id.subdevice] |
| 948 | [kcontrol->id.device].rate; | 958 | [kcontrol->id.device].rate; |
| 959 | mutex_unlock(&loopback->cable_lock); | ||
| 949 | return 0; | 960 | return 0; |
| 950 | } | 961 | } |
| 951 | 962 | ||
| @@ -965,9 +976,11 @@ static int loopback_channels_get(struct snd_kcontrol *kcontrol, | |||
| 965 | { | 976 | { |
| 966 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); | 977 | struct loopback *loopback = snd_kcontrol_chip(kcontrol); |
| 967 | 978 | ||
| 979 | mutex_lock(&loopback->cable_lock); | ||
| 968 | ucontrol->value.integer.value[0] = | 980 | ucontrol->value.integer.value[0] = |
| 969 | loopback->setup[kcontrol->id.subdevice] | 981 | loopback->setup[kcontrol->id.subdevice] |
| 970 | [kcontrol->id.device].channels; | 982 | [kcontrol->id.device].channels; |
| 983 | mutex_unlock(&loopback->cable_lock); | ||
| 971 | return 0; | 984 | return 0; |
| 972 | } | 985 | } |
| 973 | 986 | ||
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index 4a1dc145327b..cb9acfe60f6a 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c | |||
| @@ -773,8 +773,6 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context, | |||
| 773 | u32 cycle; | 773 | u32 cycle; |
| 774 | unsigned int packets; | 774 | unsigned int packets; |
| 775 | 775 | ||
| 776 | s->max_payload_length = amdtp_stream_get_max_payload(s); | ||
| 777 | |||
| 778 | /* | 776 | /* |
| 779 | * For in-stream, first packet has come. | 777 | * For in-stream, first packet has come. |
| 780 | * For out-stream, prepared to transmit first packet | 778 | * For out-stream, prepared to transmit first packet |
| @@ -879,6 +877,9 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed) | |||
| 879 | 877 | ||
| 880 | amdtp_stream_update(s); | 878 | amdtp_stream_update(s); |
| 881 | 879 | ||
| 880 | if (s->direction == AMDTP_IN_STREAM) | ||
| 881 | s->max_payload_length = amdtp_stream_get_max_payload(s); | ||
| 882 | |||
| 882 | if (s->flags & CIP_NO_HEADER) | 883 | if (s->flags & CIP_NO_HEADER) |
| 883 | s->tag = TAG_NO_CIP_HEADER; | 884 | s->tag = TAG_NO_CIP_HEADER; |
| 884 | else | 885 | else |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b0c8c79848a9..a0c93b9c9a28 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -2210,6 +2210,8 @@ static struct snd_pci_quirk power_save_blacklist[] = { | |||
| 2210 | SND_PCI_QUIRK(0x1849, 0x0c0c, "Asrock B85M-ITX", 0), | 2210 | SND_PCI_QUIRK(0x1849, 0x0c0c, "Asrock B85M-ITX", 0), |
| 2211 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ | 2211 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ |
| 2212 | SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), | 2212 | SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), |
| 2213 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ | ||
| 2214 | SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0), | ||
| 2213 | /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ | 2215 | /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ |
| 2214 | SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0), | 2216 | SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0), |
| 2215 | {} | 2217 | {} |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8c238e51bb5a..01a6643fc7d4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -2363,6 +2363,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
| 2363 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), | 2363 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), |
| 2364 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), | 2364 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), |
| 2365 | SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), | 2365 | SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), |
| 2366 | SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950), | ||
| 2366 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 2367 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
| 2367 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | 2368 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
| 2368 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), | 2369 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), |
| @@ -3832,7 +3833,7 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, | |||
| 3832 | } | 3833 | } |
| 3833 | } | 3834 | } |
| 3834 | 3835 | ||
| 3835 | #if IS_REACHABLE(INPUT) | 3836 | #if IS_REACHABLE(CONFIG_INPUT) |
| 3836 | static void gpio2_mic_hotkey_event(struct hda_codec *codec, | 3837 | static void gpio2_mic_hotkey_event(struct hda_codec *codec, |
| 3837 | struct hda_jack_callback *event) | 3838 | struct hda_jack_callback *event) |
| 3838 | { | 3839 | { |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 344d7b069d59..bb5ab7a7dfa5 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
| @@ -967,6 +967,14 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, | |||
| 967 | } | 967 | } |
| 968 | break; | 968 | break; |
| 969 | 969 | ||
| 970 | case USB_ID(0x0d8c, 0x0103): | ||
| 971 | if (!strcmp(kctl->id.name, "PCM Playback Volume")) { | ||
| 972 | usb_audio_info(chip, | ||
| 973 | "set volume quirk for CM102-A+/102S+\n"); | ||
| 974 | cval->min = -256; | ||
| 975 | } | ||
| 976 | break; | ||
| 977 | |||
| 970 | case USB_ID(0x0471, 0x0101): | 978 | case USB_ID(0x0471, 0x0101): |
| 971 | case USB_ID(0x0471, 0x0104): | 979 | case USB_ID(0x0471, 0x0104): |
| 972 | case USB_ID(0x0471, 0x0105): | 980 | case USB_ID(0x0471, 0x0105): |
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 956be9f7c72a..5ed334575fc7 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c | |||
| @@ -576,7 +576,7 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, | |||
| 576 | 576 | ||
| 577 | if (protocol == UAC_VERSION_1) { | 577 | if (protocol == UAC_VERSION_1) { |
| 578 | attributes = csep->bmAttributes; | 578 | attributes = csep->bmAttributes; |
| 579 | } else { | 579 | } else if (protocol == UAC_VERSION_2) { |
| 580 | struct uac2_iso_endpoint_descriptor *csep2 = | 580 | struct uac2_iso_endpoint_descriptor *csep2 = |
| 581 | (struct uac2_iso_endpoint_descriptor *) csep; | 581 | (struct uac2_iso_endpoint_descriptor *) csep; |
| 582 | 582 | ||
| @@ -585,6 +585,13 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, | |||
| 585 | /* emulate the endpoint attributes of a v1 device */ | 585 | /* emulate the endpoint attributes of a v1 device */ |
| 586 | if (csep2->bmControls & UAC2_CONTROL_PITCH) | 586 | if (csep2->bmControls & UAC2_CONTROL_PITCH) |
| 587 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; | 587 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; |
| 588 | } else { /* UAC_VERSION_3 */ | ||
| 589 | struct uac3_iso_endpoint_descriptor *csep3 = | ||
| 590 | (struct uac3_iso_endpoint_descriptor *) csep; | ||
| 591 | |||
| 592 | /* emulate the endpoint attributes of a v1 device */ | ||
| 593 | if (le32_to_cpu(csep3->bmControls) & UAC2_CONTROL_PITCH) | ||
| 594 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; | ||
| 588 | } | 595 | } |
| 589 | 596 | ||
| 590 | return attributes; | 597 | return attributes; |
diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h index 2ba95d6fe852..caae4843cb70 100644 --- a/tools/arch/arm/include/uapi/asm/kvm.h +++ b/tools/arch/arm/include/uapi/asm/kvm.h | |||
| @@ -195,6 +195,12 @@ struct kvm_arch_memory_slot { | |||
| 195 | #define KVM_REG_ARM_VFP_FPINST 0x1009 | 195 | #define KVM_REG_ARM_VFP_FPINST 0x1009 |
| 196 | #define KVM_REG_ARM_VFP_FPINST2 0x100A | 196 | #define KVM_REG_ARM_VFP_FPINST2 0x100A |
| 197 | 197 | ||
| 198 | /* KVM-as-firmware specific pseudo-registers */ | ||
| 199 | #define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) | ||
| 200 | #define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \ | ||
| 201 | KVM_REG_ARM_FW | ((r) & 0xffff)) | ||
| 202 | #define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) | ||
| 203 | |||
| 198 | /* Device Control API: ARM VGIC */ | 204 | /* Device Control API: ARM VGIC */ |
| 199 | #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 | 205 | #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 |
| 200 | #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 | 206 | #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 |
diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index 9abbf3044654..04b3256f8e6d 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h | |||
| @@ -206,6 +206,12 @@ struct kvm_arch_memory_slot { | |||
| 206 | #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) | 206 | #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) |
| 207 | #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2) | 207 | #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2) |
| 208 | 208 | ||
| 209 | /* KVM-as-firmware specific pseudo-registers */ | ||
| 210 | #define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) | ||
| 211 | #define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ | ||
| 212 | KVM_REG_ARM_FW | ((r) & 0xffff)) | ||
| 213 | #define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) | ||
| 214 | |||
| 209 | /* Device Control API: ARM VGIC */ | 215 | /* Device Control API: ARM VGIC */ |
| 210 | #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 | 216 | #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 |
| 211 | #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 | 217 | #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 |
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index d554c11e01ff..578793e97431 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h | |||
| @@ -320,6 +320,7 @@ | |||
| 320 | #define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */ | 320 | #define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */ |
| 321 | #define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */ | 321 | #define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */ |
| 322 | #define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */ | 322 | #define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */ |
| 323 | #define X86_FEATURE_CLDEMOTE (16*32+25) /* CLDEMOTE instruction */ | ||
| 323 | 324 | ||
| 324 | /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */ | 325 | /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */ |
| 325 | #define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* MCA overflow recovery support */ | 326 | #define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* MCA overflow recovery support */ |
diff --git a/tools/bpf/Makefile b/tools/bpf/Makefile index 1ea545965ee3..53b60ad452f5 100644 --- a/tools/bpf/Makefile +++ b/tools/bpf/Makefile | |||
| @@ -76,6 +76,8 @@ $(OUTPUT)bpf_asm: $(OUTPUT)bpf_asm.o $(OUTPUT)bpf_exp.yacc.o $(OUTPUT)bpf_exp.le | |||
| 76 | $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $^ | 76 | $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $^ |
| 77 | 77 | ||
| 78 | $(OUTPUT)bpf_exp.lex.c: $(OUTPUT)bpf_exp.yacc.c | 78 | $(OUTPUT)bpf_exp.lex.c: $(OUTPUT)bpf_exp.yacc.c |
| 79 | $(OUTPUT)bpf_exp.yacc.o: $(OUTPUT)bpf_exp.yacc.c | ||
| 80 | $(OUTPUT)bpf_exp.lex.o: $(OUTPUT)bpf_exp.lex.c | ||
| 79 | 81 | ||
| 80 | clean: bpftool_clean | 82 | clean: bpftool_clean |
| 81 | $(call QUIET_CLEAN, bpf-progs) | 83 | $(call QUIET_CLEAN, bpf-progs) |
diff --git a/tools/bpf/bpf_dbg.c b/tools/bpf/bpf_dbg.c index 4f254bcc4423..61b9aa5d6415 100644 --- a/tools/bpf/bpf_dbg.c +++ b/tools/bpf/bpf_dbg.c | |||
| @@ -1063,7 +1063,7 @@ static int cmd_load_pcap(char *file) | |||
| 1063 | 1063 | ||
| 1064 | static int cmd_load(char *arg) | 1064 | static int cmd_load(char *arg) |
| 1065 | { | 1065 | { |
| 1066 | char *subcmd, *cont, *tmp = strdup(arg); | 1066 | char *subcmd, *cont = NULL, *tmp = strdup(arg); |
| 1067 | int ret = CMD_OK; | 1067 | int ret = CMD_OK; |
| 1068 | 1068 | ||
| 1069 | subcmd = strtok_r(tmp, " ", &cont); | 1069 | subcmd = strtok_r(tmp, " ", &cont); |
| @@ -1073,7 +1073,10 @@ static int cmd_load(char *arg) | |||
| 1073 | bpf_reset(); | 1073 | bpf_reset(); |
| 1074 | bpf_reset_breakpoints(); | 1074 | bpf_reset_breakpoints(); |
| 1075 | 1075 | ||
| 1076 | ret = cmd_load_bpf(cont); | 1076 | if (!cont) |
| 1077 | ret = CMD_ERR; | ||
| 1078 | else | ||
| 1079 | ret = cmd_load_bpf(cont); | ||
| 1077 | } else if (matches(subcmd, "pcap") == 0) { | 1080 | } else if (matches(subcmd, "pcap") == 0) { |
| 1078 | ret = cmd_load_pcap(cont); | 1081 | ret = cmd_load_pcap(cont); |
| 1079 | } else { | 1082 | } else { |
diff --git a/tools/include/linux/spinlock.h b/tools/include/linux/spinlock.h index b21b586b9854..1738c0391da4 100644 --- a/tools/include/linux/spinlock.h +++ b/tools/include/linux/spinlock.h | |||
| @@ -6,8 +6,9 @@ | |||
| 6 | #include <stdbool.h> | 6 | #include <stdbool.h> |
| 7 | 7 | ||
| 8 | #define spinlock_t pthread_mutex_t | 8 | #define spinlock_t pthread_mutex_t |
| 9 | #define DEFINE_SPINLOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; | 9 | #define DEFINE_SPINLOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER |
| 10 | #define __SPIN_LOCK_UNLOCKED(x) (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER | 10 | #define __SPIN_LOCK_UNLOCKED(x) (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER |
| 11 | #define spin_lock_init(x) pthread_mutex_init(x, NULL) | ||
| 11 | 12 | ||
| 12 | #define spin_lock_irqsave(x, f) (void)f, pthread_mutex_lock(x) | 13 | #define spin_lock_irqsave(x, f) (void)f, pthread_mutex_lock(x) |
| 13 | #define spin_unlock_irqrestore(x, f) (void)f, pthread_mutex_unlock(x) | 14 | #define spin_unlock_irqrestore(x, f) (void)f, pthread_mutex_unlock(x) |
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 1065006c9bf5..b02c41e53d56 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h | |||
| @@ -676,6 +676,13 @@ struct kvm_ioeventfd { | |||
| 676 | __u8 pad[36]; | 676 | __u8 pad[36]; |
| 677 | }; | 677 | }; |
| 678 | 678 | ||
| 679 | #define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) | ||
| 680 | #define KVM_X86_DISABLE_EXITS_HTL (1 << 1) | ||
| 681 | #define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) | ||
| 682 | #define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ | ||
| 683 | KVM_X86_DISABLE_EXITS_HTL | \ | ||
| 684 | KVM_X86_DISABLE_EXITS_PAUSE) | ||
| 685 | |||
| 679 | /* for KVM_ENABLE_CAP */ | 686 | /* for KVM_ENABLE_CAP */ |
| 680 | struct kvm_enable_cap { | 687 | struct kvm_enable_cap { |
| 681 | /* in */ | 688 | /* in */ |
diff --git a/tools/objtool/arch/x86/include/asm/insn.h b/tools/objtool/arch/x86/include/asm/insn.h index b3e32b010ab1..c2c01f84df75 100644 --- a/tools/objtool/arch/x86/include/asm/insn.h +++ b/tools/objtool/arch/x86/include/asm/insn.h | |||
| @@ -208,4 +208,22 @@ static inline int insn_offset_immediate(struct insn *insn) | |||
| 208 | return insn_offset_displacement(insn) + insn->displacement.nbytes; | 208 | return insn_offset_displacement(insn) + insn->displacement.nbytes; |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | #define POP_SS_OPCODE 0x1f | ||
| 212 | #define MOV_SREG_OPCODE 0x8e | ||
| 213 | |||
| 214 | /* | ||
| 215 | * Intel SDM Vol.3A 6.8.3 states; | ||
| 216 | * "Any single-step trap that would be delivered following the MOV to SS | ||
| 217 | * instruction or POP to SS instruction (because EFLAGS.TF is 1) is | ||
| 218 | * suppressed." | ||
| 219 | * This function returns true if @insn is MOV SS or POP SS. On these | ||
| 220 | * instructions, single stepping is suppressed. | ||
| 221 | */ | ||
| 222 | static inline int insn_masking_exception(struct insn *insn) | ||
| 223 | { | ||
| 224 | return insn->opcode.bytes[0] == POP_SS_OPCODE || | ||
| 225 | (insn->opcode.bytes[0] == MOV_SREG_OPCODE && | ||
| 226 | X86_MODRM_REG(insn->modrm.bytes[0]) == 2); | ||
| 227 | } | ||
| 228 | |||
| 211 | #endif /* _ASM_X86_INSN_H */ | 229 | #endif /* _ASM_X86_INSN_H */ |
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 5409f6f6c48d..3a31b238f885 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c | |||
| @@ -59,6 +59,31 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file, | |||
| 59 | return next; | 59 | return next; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | static struct instruction *next_insn_same_func(struct objtool_file *file, | ||
| 63 | struct instruction *insn) | ||
| 64 | { | ||
| 65 | struct instruction *next = list_next_entry(insn, list); | ||
| 66 | struct symbol *func = insn->func; | ||
| 67 | |||
| 68 | if (!func) | ||
| 69 | return NULL; | ||
| 70 | |||
| 71 | if (&next->list != &file->insn_list && next->func == func) | ||
| 72 | return next; | ||
| 73 | |||
| 74 | /* Check if we're already in the subfunction: */ | ||
| 75 | if (func == func->cfunc) | ||
| 76 | return NULL; | ||
| 77 | |||
| 78 | /* Move to the subfunction: */ | ||
| 79 | return find_insn(file, func->cfunc->sec, func->cfunc->offset); | ||
| 80 | } | ||
| 81 | |||
| 82 | #define func_for_each_insn_all(file, func, insn) \ | ||
| 83 | for (insn = find_insn(file, func->sec, func->offset); \ | ||
| 84 | insn; \ | ||
| 85 | insn = next_insn_same_func(file, insn)) | ||
| 86 | |||
| 62 | #define func_for_each_insn(file, func, insn) \ | 87 | #define func_for_each_insn(file, func, insn) \ |
| 63 | for (insn = find_insn(file, func->sec, func->offset); \ | 88 | for (insn = find_insn(file, func->sec, func->offset); \ |
| 64 | insn && &insn->list != &file->insn_list && \ | 89 | insn && &insn->list != &file->insn_list && \ |
| @@ -149,10 +174,14 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func, | |||
| 149 | if (!strcmp(func->name, global_noreturns[i])) | 174 | if (!strcmp(func->name, global_noreturns[i])) |
| 150 | return 1; | 175 | return 1; |
| 151 | 176 | ||
| 152 | if (!func->sec) | 177 | if (!func->len) |
| 153 | return 0; | 178 | return 0; |
| 154 | 179 | ||
| 155 | func_for_each_insn(file, func, insn) { | 180 | insn = find_insn(file, func->sec, func->offset); |
| 181 | if (!insn->func) | ||
| 182 | return 0; | ||
| 183 | |||
| 184 | func_for_each_insn_all(file, func, insn) { | ||
| 156 | empty = false; | 185 | empty = false; |
| 157 | 186 | ||
| 158 | if (insn->type == INSN_RETURN) | 187 | if (insn->type == INSN_RETURN) |
| @@ -167,35 +196,28 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func, | |||
| 167 | * case, the function's dead-end status depends on whether the target | 196 | * case, the function's dead-end status depends on whether the target |
| 168 | * of the sibling call returns. | 197 | * of the sibling call returns. |
| 169 | */ | 198 | */ |
| 170 | func_for_each_insn(file, func, insn) { | 199 | func_for_each_insn_all(file, func, insn) { |
| 171 | if (insn->sec != func->sec || | ||
| 172 | insn->offset >= func->offset + func->len) | ||
| 173 | break; | ||
| 174 | |||
| 175 | if (insn->type == INSN_JUMP_UNCONDITIONAL) { | 200 | if (insn->type == INSN_JUMP_UNCONDITIONAL) { |
| 176 | struct instruction *dest = insn->jump_dest; | 201 | struct instruction *dest = insn->jump_dest; |
| 177 | struct symbol *dest_func; | ||
| 178 | 202 | ||
| 179 | if (!dest) | 203 | if (!dest) |
| 180 | /* sibling call to another file */ | 204 | /* sibling call to another file */ |
| 181 | return 0; | 205 | return 0; |
| 182 | 206 | ||
| 183 | if (dest->sec != func->sec || | 207 | if (dest->func && dest->func->pfunc != insn->func->pfunc) { |
| 184 | dest->offset < func->offset || | ||
| 185 | dest->offset >= func->offset + func->len) { | ||
| 186 | /* local sibling call */ | ||
| 187 | dest_func = find_symbol_by_offset(dest->sec, | ||
| 188 | dest->offset); | ||
| 189 | if (!dest_func) | ||
| 190 | continue; | ||
| 191 | 208 | ||
| 209 | /* local sibling call */ | ||
| 192 | if (recursion == 5) { | 210 | if (recursion == 5) { |
| 193 | WARN_FUNC("infinite recursion (objtool bug!)", | 211 | /* |
| 194 | dest->sec, dest->offset); | 212 | * Infinite recursion: two functions |
| 195 | return -1; | 213 | * have sibling calls to each other. |
| 214 | * This is a very rare case. It means | ||
| 215 | * they aren't dead ends. | ||
| 216 | */ | ||
| 217 | return 0; | ||
| 196 | } | 218 | } |
| 197 | 219 | ||
| 198 | return __dead_end_function(file, dest_func, | 220 | return __dead_end_function(file, dest->func, |
| 199 | recursion + 1); | 221 | recursion + 1); |
| 200 | } | 222 | } |
| 201 | } | 223 | } |
| @@ -422,7 +444,7 @@ static void add_ignores(struct objtool_file *file) | |||
| 422 | if (!ignore_func(file, func)) | 444 | if (!ignore_func(file, func)) |
| 423 | continue; | 445 | continue; |
| 424 | 446 | ||
| 425 | func_for_each_insn(file, func, insn) | 447 | func_for_each_insn_all(file, func, insn) |
| 426 | insn->ignore = true; | 448 | insn->ignore = true; |
| 427 | } | 449 | } |
| 428 | } | 450 | } |
| @@ -782,30 +804,35 @@ out: | |||
| 782 | return ret; | 804 | return ret; |
| 783 | } | 805 | } |
| 784 | 806 | ||
| 785 | static int add_switch_table(struct objtool_file *file, struct symbol *func, | 807 | static int add_switch_table(struct objtool_file *file, struct instruction *insn, |
| 786 | struct instruction *insn, struct rela *table, | 808 | struct rela *table, struct rela *next_table) |
| 787 | struct rela *next_table) | ||
| 788 | { | 809 | { |
| 789 | struct rela *rela = table; | 810 | struct rela *rela = table; |
| 790 | struct instruction *alt_insn; | 811 | struct instruction *alt_insn; |
| 791 | struct alternative *alt; | 812 | struct alternative *alt; |
| 813 | struct symbol *pfunc = insn->func->pfunc; | ||
| 814 | unsigned int prev_offset = 0; | ||
| 792 | 815 | ||
| 793 | list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) { | 816 | list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) { |
| 794 | if (rela == next_table) | 817 | if (rela == next_table) |
| 795 | break; | 818 | break; |
| 796 | 819 | ||
| 797 | if (rela->sym->sec != insn->sec || | 820 | /* Make sure the switch table entries are consecutive: */ |
| 798 | rela->addend <= func->offset || | 821 | if (prev_offset && rela->offset != prev_offset + 8) |
| 799 | rela->addend >= func->offset + func->len) | ||
| 800 | break; | 822 | break; |
| 801 | 823 | ||
| 802 | alt_insn = find_insn(file, insn->sec, rela->addend); | 824 | /* Detect function pointers from contiguous objects: */ |
| 803 | if (!alt_insn) { | 825 | if (rela->sym->sec == pfunc->sec && |
| 804 | WARN("%s: can't find instruction at %s+0x%x", | 826 | rela->addend == pfunc->offset) |
| 805 | file->rodata->rela->name, insn->sec->name, | 827 | break; |
| 806 | rela->addend); | 828 | |
| 807 | return -1; | 829 | alt_insn = find_insn(file, rela->sym->sec, rela->addend); |
| 808 | } | 830 | if (!alt_insn) |
| 831 | break; | ||
| 832 | |||
| 833 | /* Make sure the jmp dest is in the function or subfunction: */ | ||
| 834 | if (alt_insn->func->pfunc != pfunc) | ||
| 835 | break; | ||
| 809 | 836 | ||
| 810 | alt = malloc(sizeof(*alt)); | 837 | alt = malloc(sizeof(*alt)); |
| 811 | if (!alt) { | 838 | if (!alt) { |
| @@ -815,6 +842,13 @@ static int add_switch_table(struct objtool_file *file, struct symbol *func, | |||
| 815 | 842 | ||
| 816 | alt->insn = alt_insn; | 843 | alt->insn = alt_insn; |
| 817 | list_add_tail(&alt->list, &insn->alts); | 844 | list_add_tail(&alt->list, &insn->alts); |
| 845 | prev_offset = rela->offset; | ||
| 846 | } | ||
| 847 | |||
| 848 | if (!prev_offset) { | ||
| 849 | WARN_FUNC("can't find switch jump table", | ||
| 850 | insn->sec, insn->offset); | ||
| 851 | return -1; | ||
| 818 | } | 852 | } |
| 819 | 853 | ||
| 820 | return 0; | 854 | return 0; |
| @@ -869,40 +903,21 @@ static struct rela *find_switch_table(struct objtool_file *file, | |||
| 869 | { | 903 | { |
| 870 | struct rela *text_rela, *rodata_rela; | 904 | struct rela *text_rela, *rodata_rela; |
| 871 | struct instruction *orig_insn = insn; | 905 | struct instruction *orig_insn = insn; |
| 906 | unsigned long table_offset; | ||
| 872 | 907 | ||
| 873 | text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len); | ||
| 874 | if (text_rela && text_rela->sym == file->rodata->sym) { | ||
| 875 | /* case 1 */ | ||
| 876 | rodata_rela = find_rela_by_dest(file->rodata, | ||
| 877 | text_rela->addend); | ||
| 878 | if (rodata_rela) | ||
| 879 | return rodata_rela; | ||
| 880 | |||
| 881 | /* case 2 */ | ||
| 882 | rodata_rela = find_rela_by_dest(file->rodata, | ||
| 883 | text_rela->addend + 4); | ||
| 884 | if (!rodata_rela) | ||
| 885 | return NULL; | ||
| 886 | |||
| 887 | file->ignore_unreachables = true; | ||
| 888 | return rodata_rela; | ||
| 889 | } | ||
| 890 | |||
| 891 | /* case 3 */ | ||
| 892 | /* | 908 | /* |
| 893 | * Backward search using the @first_jump_src links, these help avoid | 909 | * Backward search using the @first_jump_src links, these help avoid |
| 894 | * much of the 'in between' code. Which avoids us getting confused by | 910 | * much of the 'in between' code. Which avoids us getting confused by |
| 895 | * it. | 911 | * it. |
| 896 | */ | 912 | */ |
| 897 | for (insn = list_prev_entry(insn, list); | 913 | for (; |
| 898 | |||
| 899 | &insn->list != &file->insn_list && | 914 | &insn->list != &file->insn_list && |
| 900 | insn->sec == func->sec && | 915 | insn->sec == func->sec && |
| 901 | insn->offset >= func->offset; | 916 | insn->offset >= func->offset; |
| 902 | 917 | ||
| 903 | insn = insn->first_jump_src ?: list_prev_entry(insn, list)) { | 918 | insn = insn->first_jump_src ?: list_prev_entry(insn, list)) { |
| 904 | 919 | ||
| 905 | if (insn->type == INSN_JUMP_DYNAMIC) | 920 | if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC) |
| 906 | break; | 921 | break; |
| 907 | 922 | ||
| 908 | /* allow small jumps within the range */ | 923 | /* allow small jumps within the range */ |
| @@ -918,18 +933,29 @@ static struct rela *find_switch_table(struct objtool_file *file, | |||
| 918 | if (!text_rela || text_rela->sym != file->rodata->sym) | 933 | if (!text_rela || text_rela->sym != file->rodata->sym) |
| 919 | continue; | 934 | continue; |
| 920 | 935 | ||
| 936 | table_offset = text_rela->addend; | ||
| 937 | if (text_rela->type == R_X86_64_PC32) | ||
| 938 | table_offset += 4; | ||
| 939 | |||
| 921 | /* | 940 | /* |
| 922 | * Make sure the .rodata address isn't associated with a | 941 | * Make sure the .rodata address isn't associated with a |
| 923 | * symbol. gcc jump tables are anonymous data. | 942 | * symbol. gcc jump tables are anonymous data. |
| 924 | */ | 943 | */ |
| 925 | if (find_symbol_containing(file->rodata, text_rela->addend)) | 944 | if (find_symbol_containing(file->rodata, table_offset)) |
| 926 | continue; | 945 | continue; |
| 927 | 946 | ||
| 928 | rodata_rela = find_rela_by_dest(file->rodata, text_rela->addend); | 947 | rodata_rela = find_rela_by_dest(file->rodata, table_offset); |
| 929 | if (!rodata_rela) | 948 | if (rodata_rela) { |
| 930 | continue; | 949 | /* |
| 950 | * Use of RIP-relative switch jumps is quite rare, and | ||
| 951 | * indicates a rare GCC quirk/bug which can leave dead | ||
| 952 | * code behind. | ||
| 953 | */ | ||
| 954 | if (text_rela->type == R_X86_64_PC32) | ||
| 955 | file->ignore_unreachables = true; | ||
| 931 | 956 | ||
| 932 | return rodata_rela; | 957 | return rodata_rela; |
| 958 | } | ||
| 933 | } | 959 | } |
| 934 | 960 | ||
| 935 | return NULL; | 961 | return NULL; |
| @@ -943,7 +969,7 @@ static int add_func_switch_tables(struct objtool_file *file, | |||
| 943 | struct rela *rela, *prev_rela = NULL; | 969 | struct rela *rela, *prev_rela = NULL; |
| 944 | int ret; | 970 | int ret; |
| 945 | 971 | ||
| 946 | func_for_each_insn(file, func, insn) { | 972 | func_for_each_insn_all(file, func, insn) { |
| 947 | if (!last) | 973 | if (!last) |
| 948 | last = insn; | 974 | last = insn; |
| 949 | 975 | ||
| @@ -974,8 +1000,7 @@ static int add_func_switch_tables(struct objtool_file *file, | |||
| 974 | * the beginning of another switch table in the same function. | 1000 | * the beginning of another switch table in the same function. |
| 975 | */ | 1001 | */ |
| 976 | if (prev_jump) { | 1002 | if (prev_jump) { |
| 977 | ret = add_switch_table(file, func, prev_jump, prev_rela, | 1003 | ret = add_switch_table(file, prev_jump, prev_rela, rela); |
| 978 | rela); | ||
| 979 | if (ret) | 1004 | if (ret) |
| 980 | return ret; | 1005 | return ret; |
| 981 | } | 1006 | } |
| @@ -985,7 +1010,7 @@ static int add_func_switch_tables(struct objtool_file *file, | |||
| 985 | } | 1010 | } |
| 986 | 1011 | ||
| 987 | if (prev_jump) { | 1012 | if (prev_jump) { |
| 988 | ret = add_switch_table(file, func, prev_jump, prev_rela, NULL); | 1013 | ret = add_switch_table(file, prev_jump, prev_rela, NULL); |
| 989 | if (ret) | 1014 | if (ret) |
| 990 | return ret; | 1015 | return ret; |
| 991 | } | 1016 | } |
| @@ -1749,15 +1774,13 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
| 1749 | while (1) { | 1774 | while (1) { |
| 1750 | next_insn = next_insn_same_sec(file, insn); | 1775 | next_insn = next_insn_same_sec(file, insn); |
| 1751 | 1776 | ||
| 1752 | 1777 | if (file->c_file && func && insn->func && func != insn->func->pfunc) { | |
| 1753 | if (file->c_file && func && insn->func && func != insn->func) { | ||
| 1754 | WARN("%s() falls through to next function %s()", | 1778 | WARN("%s() falls through to next function %s()", |
| 1755 | func->name, insn->func->name); | 1779 | func->name, insn->func->name); |
| 1756 | return 1; | 1780 | return 1; |
| 1757 | } | 1781 | } |
| 1758 | 1782 | ||
| 1759 | if (insn->func) | 1783 | func = insn->func ? insn->func->pfunc : NULL; |
| 1760 | func = insn->func; | ||
| 1761 | 1784 | ||
| 1762 | if (func && insn->ignore) { | 1785 | if (func && insn->ignore) { |
| 1763 | WARN_FUNC("BUG: why am I validating an ignored function?", | 1786 | WARN_FUNC("BUG: why am I validating an ignored function?", |
| @@ -1778,7 +1801,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
| 1778 | 1801 | ||
| 1779 | i = insn; | 1802 | i = insn; |
| 1780 | save_insn = NULL; | 1803 | save_insn = NULL; |
| 1781 | func_for_each_insn_continue_reverse(file, func, i) { | 1804 | func_for_each_insn_continue_reverse(file, insn->func, i) { |
| 1782 | if (i->save) { | 1805 | if (i->save) { |
| 1783 | save_insn = i; | 1806 | save_insn = i; |
| 1784 | break; | 1807 | break; |
| @@ -1865,7 +1888,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
| 1865 | case INSN_JUMP_UNCONDITIONAL: | 1888 | case INSN_JUMP_UNCONDITIONAL: |
| 1866 | if (insn->jump_dest && | 1889 | if (insn->jump_dest && |
| 1867 | (!func || !insn->jump_dest->func || | 1890 | (!func || !insn->jump_dest->func || |
| 1868 | func == insn->jump_dest->func)) { | 1891 | insn->jump_dest->func->pfunc == func)) { |
| 1869 | ret = validate_branch(file, insn->jump_dest, | 1892 | ret = validate_branch(file, insn->jump_dest, |
| 1870 | state); | 1893 | state); |
| 1871 | if (ret) | 1894 | if (ret) |
| @@ -2060,7 +2083,7 @@ static int validate_functions(struct objtool_file *file) | |||
| 2060 | 2083 | ||
| 2061 | for_each_sec(file, sec) { | 2084 | for_each_sec(file, sec) { |
| 2062 | list_for_each_entry(func, &sec->symbol_list, list) { | 2085 | list_for_each_entry(func, &sec->symbol_list, list) { |
| 2063 | if (func->type != STT_FUNC) | 2086 | if (func->type != STT_FUNC || func->pfunc != func) |
| 2064 | continue; | 2087 | continue; |
| 2065 | 2088 | ||
| 2066 | insn = find_insn(file, sec, func->offset); | 2089 | insn = find_insn(file, sec, func->offset); |
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index c1c338661699..4e60e105583e 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c | |||
| @@ -79,6 +79,19 @@ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset) | |||
| 79 | return NULL; | 79 | return NULL; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | struct symbol *find_symbol_by_name(struct elf *elf, const char *name) | ||
| 83 | { | ||
| 84 | struct section *sec; | ||
| 85 | struct symbol *sym; | ||
| 86 | |||
| 87 | list_for_each_entry(sec, &elf->sections, list) | ||
| 88 | list_for_each_entry(sym, &sec->symbol_list, list) | ||
| 89 | if (!strcmp(sym->name, name)) | ||
| 90 | return sym; | ||
| 91 | |||
| 92 | return NULL; | ||
| 93 | } | ||
| 94 | |||
| 82 | struct symbol *find_symbol_containing(struct section *sec, unsigned long offset) | 95 | struct symbol *find_symbol_containing(struct section *sec, unsigned long offset) |
| 83 | { | 96 | { |
| 84 | struct symbol *sym; | 97 | struct symbol *sym; |
| @@ -203,10 +216,11 @@ static int read_sections(struct elf *elf) | |||
| 203 | 216 | ||
| 204 | static int read_symbols(struct elf *elf) | 217 | static int read_symbols(struct elf *elf) |
| 205 | { | 218 | { |
| 206 | struct section *symtab; | 219 | struct section *symtab, *sec; |
| 207 | struct symbol *sym; | 220 | struct symbol *sym, *pfunc; |
| 208 | struct list_head *entry, *tmp; | 221 | struct list_head *entry, *tmp; |
| 209 | int symbols_nr, i; | 222 | int symbols_nr, i; |
| 223 | char *coldstr; | ||
| 210 | 224 | ||
| 211 | symtab = find_section_by_name(elf, ".symtab"); | 225 | symtab = find_section_by_name(elf, ".symtab"); |
| 212 | if (!symtab) { | 226 | if (!symtab) { |
| @@ -281,6 +295,30 @@ static int read_symbols(struct elf *elf) | |||
| 281 | hash_add(sym->sec->symbol_hash, &sym->hash, sym->idx); | 295 | hash_add(sym->sec->symbol_hash, &sym->hash, sym->idx); |
| 282 | } | 296 | } |
| 283 | 297 | ||
| 298 | /* Create parent/child links for any cold subfunctions */ | ||
| 299 | list_for_each_entry(sec, &elf->sections, list) { | ||
| 300 | list_for_each_entry(sym, &sec->symbol_list, list) { | ||
| 301 | if (sym->type != STT_FUNC) | ||
| 302 | continue; | ||
| 303 | sym->pfunc = sym->cfunc = sym; | ||
| 304 | coldstr = strstr(sym->name, ".cold."); | ||
| 305 | if (coldstr) { | ||
| 306 | coldstr[0] = '\0'; | ||
| 307 | pfunc = find_symbol_by_name(elf, sym->name); | ||
| 308 | coldstr[0] = '.'; | ||
| 309 | |||
| 310 | if (!pfunc) { | ||
| 311 | WARN("%s(): can't find parent function", | ||
| 312 | sym->name); | ||
| 313 | goto err; | ||
| 314 | } | ||
| 315 | |||
| 316 | sym->pfunc = pfunc; | ||
| 317 | pfunc->cfunc = sym; | ||
| 318 | } | ||
| 319 | } | ||
| 320 | } | ||
| 321 | |||
| 284 | return 0; | 322 | return 0; |
| 285 | 323 | ||
| 286 | err: | 324 | err: |
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h index d86e2ff14466..de5cd2ddded9 100644 --- a/tools/objtool/elf.h +++ b/tools/objtool/elf.h | |||
| @@ -61,6 +61,7 @@ struct symbol { | |||
| 61 | unsigned char bind, type; | 61 | unsigned char bind, type; |
| 62 | unsigned long offset; | 62 | unsigned long offset; |
| 63 | unsigned int len; | 63 | unsigned int len; |
| 64 | struct symbol *pfunc, *cfunc; | ||
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | struct rela { | 67 | struct rela { |
| @@ -86,6 +87,7 @@ struct elf { | |||
| 86 | struct elf *elf_open(const char *name, int flags); | 87 | struct elf *elf_open(const char *name, int flags); |
| 87 | struct section *find_section_by_name(struct elf *elf, const char *name); | 88 | struct section *find_section_by_name(struct elf *elf, const char *name); |
| 88 | struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); | 89 | struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); |
| 90 | struct symbol *find_symbol_by_name(struct elf *elf, const char *name); | ||
| 89 | struct symbol *find_symbol_containing(struct section *sec, unsigned long offset); | 91 | struct symbol *find_symbol_containing(struct section *sec, unsigned long offset); |
| 90 | struct rela *find_rela_by_dest(struct section *sec, unsigned long offset); | 92 | struct rela *find_rela_by_dest(struct section *sec, unsigned long offset); |
| 91 | struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset, | 93 | struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset, |
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 944070e98a2c..63eb49082774 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
| @@ -175,7 +175,7 @@ static const struct option options[] = { | |||
| 175 | OPT_UINTEGER('s', "nr_secs" , &p0.nr_secs, "max number of seconds to run (default: 5 secs)"), | 175 | OPT_UINTEGER('s', "nr_secs" , &p0.nr_secs, "max number of seconds to run (default: 5 secs)"), |
| 176 | OPT_UINTEGER('u', "usleep" , &p0.sleep_usecs, "usecs to sleep per loop iteration"), | 176 | OPT_UINTEGER('u', "usleep" , &p0.sleep_usecs, "usecs to sleep per loop iteration"), |
| 177 | 177 | ||
| 178 | OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via writes (can be mixed with -W)"), | 178 | OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via reads (can be mixed with -W)"), |
| 179 | OPT_BOOLEAN('W', "data_writes" , &p0.data_writes, "access the data via writes (can be mixed with -R)"), | 179 | OPT_BOOLEAN('W', "data_writes" , &p0.data_writes, "access the data via writes (can be mixed with -R)"), |
| 180 | OPT_BOOLEAN('B', "data_backwards", &p0.data_backwards, "access the data backwards as well"), | 180 | OPT_BOOLEAN('B', "data_backwards", &p0.data_backwards, "access the data backwards as well"), |
| 181 | OPT_BOOLEAN('Z', "data_zero_memset", &p0.data_zero_memset,"access the data via glibc bzero only"), | 181 | OPT_BOOLEAN('Z', "data_zero_memset", &p0.data_zero_memset,"access the data via glibc bzero only"), |
diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index 93656f2fd53a..7e3cce3bcf3b 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv | |||
| @@ -29,7 +29,6 @@ GenuineIntel-6-4D,v13,silvermont,core | |||
| 29 | GenuineIntel-6-4C,v13,silvermont,core | 29 | GenuineIntel-6-4C,v13,silvermont,core |
| 30 | GenuineIntel-6-2A,v15,sandybridge,core | 30 | GenuineIntel-6-2A,v15,sandybridge,core |
| 31 | GenuineIntel-6-2C,v2,westmereep-dp,core | 31 | GenuineIntel-6-2C,v2,westmereep-dp,core |
| 32 | GenuineIntel-6-2C,v2,westmereep-dp,core | ||
| 33 | GenuineIntel-6-25,v2,westmereep-sp,core | 32 | GenuineIntel-6-25,v2,westmereep-sp,core |
| 34 | GenuineIntel-6-2F,v2,westmereex,core | 33 | GenuineIntel-6-2F,v2,westmereex,core |
| 35 | GenuineIntel-6-55,v1,skylakex,core | 34 | GenuineIntel-6-55,v1,skylakex,core |
diff --git a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh index 016882dbbc16..ee86473643be 100755 --- a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh +++ b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh | |||
| @@ -16,7 +16,7 @@ nm -g $libc 2>/dev/null | fgrep -q inet_pton || exit 254 | |||
| 16 | trace_libc_inet_pton_backtrace() { | 16 | trace_libc_inet_pton_backtrace() { |
| 17 | idx=0 | 17 | idx=0 |
| 18 | expected[0]="ping[][0-9 \.:]+probe_libc:inet_pton: \([[:xdigit:]]+\)" | 18 | expected[0]="ping[][0-9 \.:]+probe_libc:inet_pton: \([[:xdigit:]]+\)" |
| 19 | expected[1]=".*inet_pton[[:space:]]\($libc\)$" | 19 | expected[1]=".*inet_pton[[:space:]]\($libc|inlined\)$" |
| 20 | case "$(uname -m)" in | 20 | case "$(uname -m)" in |
| 21 | s390x) | 21 | s390x) |
| 22 | eventattr='call-graph=dwarf,max-stack=4' | 22 | eventattr='call-graph=dwarf,max-stack=4' |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 536ee148bff8..5d74a30fe00f 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -1263,6 +1263,9 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start | |||
| 1263 | max_percent = sample->percent; | 1263 | max_percent = sample->percent; |
| 1264 | } | 1264 | } |
| 1265 | 1265 | ||
| 1266 | if (al->samples_nr > nr_percent) | ||
| 1267 | nr_percent = al->samples_nr; | ||
| 1268 | |||
| 1266 | if (max_percent < min_pcnt) | 1269 | if (max_percent < min_pcnt) |
| 1267 | return -1; | 1270 | return -1; |
| 1268 | 1271 | ||
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 40020b1ca54f..bf16dc9ee507 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c | |||
| @@ -239,6 +239,7 @@ static void cs_etm__free(struct perf_session *session) | |||
| 239 | for (i = 0; i < aux->num_cpu; i++) | 239 | for (i = 0; i < aux->num_cpu; i++) |
| 240 | zfree(&aux->metadata[i]); | 240 | zfree(&aux->metadata[i]); |
| 241 | 241 | ||
| 242 | thread__zput(aux->unknown_thread); | ||
| 242 | zfree(&aux->metadata); | 243 | zfree(&aux->metadata); |
| 243 | zfree(&aux); | 244 | zfree(&aux); |
| 244 | } | 245 | } |
| @@ -612,8 +613,8 @@ cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq) | |||
| 612 | return buff->len; | 613 | return buff->len; |
| 613 | } | 614 | } |
| 614 | 615 | ||
| 615 | static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm, | 616 | static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm, |
| 616 | struct auxtrace_queue *queue) | 617 | struct auxtrace_queue *queue) |
| 617 | { | 618 | { |
| 618 | struct cs_etm_queue *etmq = queue->priv; | 619 | struct cs_etm_queue *etmq = queue->priv; |
| 619 | 620 | ||
| @@ -1357,6 +1358,23 @@ int cs_etm__process_auxtrace_info(union perf_event *event, | |||
| 1357 | etm->auxtrace.free = cs_etm__free; | 1358 | etm->auxtrace.free = cs_etm__free; |
| 1358 | session->auxtrace = &etm->auxtrace; | 1359 | session->auxtrace = &etm->auxtrace; |
| 1359 | 1360 | ||
| 1361 | etm->unknown_thread = thread__new(999999999, 999999999); | ||
| 1362 | if (!etm->unknown_thread) | ||
| 1363 | goto err_free_queues; | ||
| 1364 | |||
| 1365 | /* | ||
| 1366 | * Initialize list node so that at thread__zput() we can avoid | ||
| 1367 | * segmentation fault at list_del_init(). | ||
| 1368 | */ | ||
| 1369 | INIT_LIST_HEAD(&etm->unknown_thread->node); | ||
| 1370 | |||
| 1371 | err = thread__set_comm(etm->unknown_thread, "unknown", 0); | ||
| 1372 | if (err) | ||
| 1373 | goto err_delete_thread; | ||
| 1374 | |||
| 1375 | if (thread__init_map_groups(etm->unknown_thread, etm->machine)) | ||
| 1376 | goto err_delete_thread; | ||
| 1377 | |||
| 1360 | if (dump_trace) { | 1378 | if (dump_trace) { |
| 1361 | cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu); | 1379 | cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu); |
| 1362 | return 0; | 1380 | return 0; |
| @@ -1371,16 +1389,18 @@ int cs_etm__process_auxtrace_info(union perf_event *event, | |||
| 1371 | 1389 | ||
| 1372 | err = cs_etm__synth_events(etm, session); | 1390 | err = cs_etm__synth_events(etm, session); |
| 1373 | if (err) | 1391 | if (err) |
| 1374 | goto err_free_queues; | 1392 | goto err_delete_thread; |
| 1375 | 1393 | ||
| 1376 | err = auxtrace_queues__process_index(&etm->queues, session); | 1394 | err = auxtrace_queues__process_index(&etm->queues, session); |
| 1377 | if (err) | 1395 | if (err) |
| 1378 | goto err_free_queues; | 1396 | goto err_delete_thread; |
| 1379 | 1397 | ||
| 1380 | etm->data_queued = etm->queues.populated; | 1398 | etm->data_queued = etm->queues.populated; |
| 1381 | 1399 | ||
| 1382 | return 0; | 1400 | return 0; |
| 1383 | 1401 | ||
| 1402 | err_delete_thread: | ||
| 1403 | thread__zput(etm->unknown_thread); | ||
| 1384 | err_free_queues: | 1404 | err_free_queues: |
| 1385 | auxtrace_queues__free(&etm->queues); | 1405 | auxtrace_queues__free(&etm->queues); |
| 1386 | session->auxtrace = NULL; | 1406 | session->auxtrace = NULL; |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 2fb0272146d8..b8b8a9558d32 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -1715,7 +1715,7 @@ int parse_events(struct perf_evlist *evlist, const char *str, | |||
| 1715 | struct perf_evsel *last; | 1715 | struct perf_evsel *last; |
| 1716 | 1716 | ||
| 1717 | if (list_empty(&parse_state.list)) { | 1717 | if (list_empty(&parse_state.list)) { |
| 1718 | WARN_ONCE(true, "WARNING: event parser found nothing"); | 1718 | WARN_ONCE(true, "WARNING: event parser found nothing\n"); |
| 1719 | return -1; | 1719 | return -1; |
| 1720 | } | 1720 | } |
| 1721 | 1721 | ||
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index d14464c42714..7afeb80cc39e 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
| @@ -224,15 +224,15 @@ event_def: event_pmu | | |||
| 224 | event_bpf_file | 224 | event_bpf_file |
| 225 | 225 | ||
| 226 | event_pmu: | 226 | event_pmu: |
| 227 | PE_NAME '/' event_config '/' | 227 | PE_NAME opt_event_config |
| 228 | { | 228 | { |
| 229 | struct list_head *list, *orig_terms, *terms; | 229 | struct list_head *list, *orig_terms, *terms; |
| 230 | 230 | ||
| 231 | if (parse_events_copy_term_list($3, &orig_terms)) | 231 | if (parse_events_copy_term_list($2, &orig_terms)) |
| 232 | YYABORT; | 232 | YYABORT; |
| 233 | 233 | ||
| 234 | ALLOC_LIST(list); | 234 | ALLOC_LIST(list); |
| 235 | if (parse_events_add_pmu(_parse_state, list, $1, $3, false)) { | 235 | if (parse_events_add_pmu(_parse_state, list, $1, $2, false)) { |
| 236 | struct perf_pmu *pmu = NULL; | 236 | struct perf_pmu *pmu = NULL; |
| 237 | int ok = 0; | 237 | int ok = 0; |
| 238 | char *pattern; | 238 | char *pattern; |
| @@ -262,7 +262,7 @@ PE_NAME '/' event_config '/' | |||
| 262 | if (!ok) | 262 | if (!ok) |
| 263 | YYABORT; | 263 | YYABORT; |
| 264 | } | 264 | } |
| 265 | parse_events_terms__delete($3); | 265 | parse_events_terms__delete($2); |
| 266 | parse_events_terms__delete(orig_terms); | 266 | parse_events_terms__delete(orig_terms); |
| 267 | $$ = list; | 267 | $$ = list; |
| 268 | } | 268 | } |
diff --git a/tools/power/acpi/Makefile.config b/tools/power/acpi/Makefile.config index 2cccbba64418..f304be71c278 100644 --- a/tools/power/acpi/Makefile.config +++ b/tools/power/acpi/Makefile.config | |||
| @@ -56,6 +56,7 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} | |||
| 56 | # to compile vs uClibc, that can be done here as well. | 56 | # to compile vs uClibc, that can be done here as well. |
| 57 | CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- | 57 | CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- |
| 58 | CROSS_COMPILE ?= $(CROSS) | 58 | CROSS_COMPILE ?= $(CROSS) |
| 59 | LD = $(CC) | ||
| 59 | HOSTCC = gcc | 60 | HOSTCC = gcc |
| 60 | 61 | ||
| 61 | # check if compiler option is supported | 62 | # check if compiler option is supported |
diff --git a/tools/testing/radix-tree/Makefile b/tools/testing/radix-tree/Makefile index fa7ee369b3c9..db66f8a0d4be 100644 --- a/tools/testing/radix-tree/Makefile +++ b/tools/testing/radix-tree/Makefile | |||
| @@ -17,7 +17,7 @@ ifeq ($(BUILD), 32) | |||
| 17 | LDFLAGS += -m32 | 17 | LDFLAGS += -m32 |
| 18 | endif | 18 | endif |
| 19 | 19 | ||
| 20 | targets: mapshift $(TARGETS) | 20 | targets: generated/map-shift.h $(TARGETS) |
| 21 | 21 | ||
| 22 | main: $(OFILES) | 22 | main: $(OFILES) |
| 23 | 23 | ||
| @@ -42,9 +42,7 @@ radix-tree.c: ../../../lib/radix-tree.c | |||
| 42 | idr.c: ../../../lib/idr.c | 42 | idr.c: ../../../lib/idr.c |
| 43 | sed -e 's/^static //' -e 's/__always_inline //' -e 's/inline //' < $< > $@ | 43 | sed -e 's/^static //' -e 's/__always_inline //' -e 's/inline //' < $< > $@ |
| 44 | 44 | ||
| 45 | .PHONY: mapshift | 45 | generated/map-shift.h: |
| 46 | |||
| 47 | mapshift: | ||
| 48 | @if ! grep -qws $(SHIFT) generated/map-shift.h; then \ | 46 | @if ! grep -qws $(SHIFT) generated/map-shift.h; then \ |
| 49 | echo "#define RADIX_TREE_MAP_SHIFT $(SHIFT)" > \ | 47 | echo "#define RADIX_TREE_MAP_SHIFT $(SHIFT)" > \ |
| 50 | generated/map-shift.h; \ | 48 | generated/map-shift.h; \ |
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c index 59245b3d587c..7bf405638b0b 100644 --- a/tools/testing/radix-tree/multiorder.c +++ b/tools/testing/radix-tree/multiorder.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/radix-tree.h> | 16 | #include <linux/radix-tree.h> |
| 17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
| 19 | #include <pthread.h> | ||
| 19 | 20 | ||
| 20 | #include "test.h" | 21 | #include "test.h" |
| 21 | 22 | ||
| @@ -624,6 +625,67 @@ static void multiorder_account(void) | |||
| 624 | item_kill_tree(&tree); | 625 | item_kill_tree(&tree); |
| 625 | } | 626 | } |
| 626 | 627 | ||
| 628 | bool stop_iteration = false; | ||
| 629 | |||
| 630 | static void *creator_func(void *ptr) | ||
| 631 | { | ||
| 632 | /* 'order' is set up to ensure we have sibling entries */ | ||
| 633 | unsigned int order = RADIX_TREE_MAP_SHIFT - 1; | ||
| 634 | struct radix_tree_root *tree = ptr; | ||
| 635 | int i; | ||
| 636 | |||
| 637 | for (i = 0; i < 10000; i++) { | ||
| 638 | item_insert_order(tree, 0, order); | ||
| 639 | item_delete_rcu(tree, 0); | ||
| 640 | } | ||
| 641 | |||
| 642 | stop_iteration = true; | ||
| 643 | return NULL; | ||
| 644 | } | ||
| 645 | |||
| 646 | static void *iterator_func(void *ptr) | ||
| 647 | { | ||
| 648 | struct radix_tree_root *tree = ptr; | ||
| 649 | struct radix_tree_iter iter; | ||
| 650 | struct item *item; | ||
| 651 | void **slot; | ||
| 652 | |||
| 653 | while (!stop_iteration) { | ||
| 654 | rcu_read_lock(); | ||
| 655 | radix_tree_for_each_slot(slot, tree, &iter, 0) { | ||
| 656 | item = radix_tree_deref_slot(slot); | ||
| 657 | |||
| 658 | if (!item) | ||
| 659 | continue; | ||
| 660 | if (radix_tree_deref_retry(item)) { | ||
| 661 | slot = radix_tree_iter_retry(&iter); | ||
| 662 | continue; | ||
| 663 | } | ||
| 664 | |||
| 665 | item_sanity(item, iter.index); | ||
| 666 | } | ||
| 667 | rcu_read_unlock(); | ||
| 668 | } | ||
| 669 | return NULL; | ||
| 670 | } | ||
| 671 | |||
| 672 | static void multiorder_iteration_race(void) | ||
| 673 | { | ||
| 674 | const int num_threads = sysconf(_SC_NPROCESSORS_ONLN); | ||
| 675 | pthread_t worker_thread[num_threads]; | ||
| 676 | RADIX_TREE(tree, GFP_KERNEL); | ||
| 677 | int i; | ||
| 678 | |||
| 679 | pthread_create(&worker_thread[0], NULL, &creator_func, &tree); | ||
| 680 | for (i = 1; i < num_threads; i++) | ||
| 681 | pthread_create(&worker_thread[i], NULL, &iterator_func, &tree); | ||
| 682 | |||
| 683 | for (i = 0; i < num_threads; i++) | ||
| 684 | pthread_join(worker_thread[i], NULL); | ||
| 685 | |||
| 686 | item_kill_tree(&tree); | ||
| 687 | } | ||
| 688 | |||
| 627 | void multiorder_checks(void) | 689 | void multiorder_checks(void) |
| 628 | { | 690 | { |
| 629 | int i; | 691 | int i; |
| @@ -644,6 +706,7 @@ void multiorder_checks(void) | |||
| 644 | multiorder_join(); | 706 | multiorder_join(); |
| 645 | multiorder_split(); | 707 | multiorder_split(); |
| 646 | multiorder_account(); | 708 | multiorder_account(); |
| 709 | multiorder_iteration_race(); | ||
| 647 | 710 | ||
| 648 | radix_tree_cpu_dead(0); | 711 | radix_tree_cpu_dead(0); |
| 649 | } | 712 | } |
diff --git a/tools/testing/radix-tree/test.c b/tools/testing/radix-tree/test.c index 5978ab1f403d..def6015570b2 100644 --- a/tools/testing/radix-tree/test.c +++ b/tools/testing/radix-tree/test.c | |||
| @@ -75,6 +75,25 @@ int item_delete(struct radix_tree_root *root, unsigned long index) | |||
| 75 | return 0; | 75 | return 0; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static void item_free_rcu(struct rcu_head *head) | ||
| 79 | { | ||
| 80 | struct item *item = container_of(head, struct item, rcu_head); | ||
| 81 | |||
| 82 | free(item); | ||
| 83 | } | ||
| 84 | |||
| 85 | int item_delete_rcu(struct radix_tree_root *root, unsigned long index) | ||
| 86 | { | ||
| 87 | struct item *item = radix_tree_delete(root, index); | ||
| 88 | |||
| 89 | if (item) { | ||
| 90 | item_sanity(item, index); | ||
| 91 | call_rcu(&item->rcu_head, item_free_rcu); | ||
| 92 | return 1; | ||
| 93 | } | ||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 78 | void item_check_present(struct radix_tree_root *root, unsigned long index) | 97 | void item_check_present(struct radix_tree_root *root, unsigned long index) |
| 79 | { | 98 | { |
| 80 | struct item *item; | 99 | struct item *item; |
diff --git a/tools/testing/radix-tree/test.h b/tools/testing/radix-tree/test.h index d9c031dbeb1a..31f1d9b6f506 100644 --- a/tools/testing/radix-tree/test.h +++ b/tools/testing/radix-tree/test.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <linux/rcupdate.h> | 5 | #include <linux/rcupdate.h> |
| 6 | 6 | ||
| 7 | struct item { | 7 | struct item { |
| 8 | struct rcu_head rcu_head; | ||
| 8 | unsigned long index; | 9 | unsigned long index; |
| 9 | unsigned int order; | 10 | unsigned int order; |
| 10 | }; | 11 | }; |
| @@ -12,9 +13,11 @@ struct item { | |||
| 12 | struct item *item_create(unsigned long index, unsigned int order); | 13 | struct item *item_create(unsigned long index, unsigned int order); |
| 13 | int __item_insert(struct radix_tree_root *root, struct item *item); | 14 | int __item_insert(struct radix_tree_root *root, struct item *item); |
| 14 | int item_insert(struct radix_tree_root *root, unsigned long index); | 15 | int item_insert(struct radix_tree_root *root, unsigned long index); |
| 16 | void item_sanity(struct item *item, unsigned long index); | ||
| 15 | int item_insert_order(struct radix_tree_root *root, unsigned long index, | 17 | int item_insert_order(struct radix_tree_root *root, unsigned long index, |
| 16 | unsigned order); | 18 | unsigned order); |
| 17 | int item_delete(struct radix_tree_root *root, unsigned long index); | 19 | int item_delete(struct radix_tree_root *root, unsigned long index); |
| 20 | int item_delete_rcu(struct radix_tree_root *root, unsigned long index); | ||
| 18 | struct item *item_lookup(struct radix_tree_root *root, unsigned long index); | 21 | struct item *item_lookup(struct radix_tree_root *root, unsigned long index); |
| 19 | 22 | ||
| 20 | void item_check_present(struct radix_tree_root *root, unsigned long index); | 23 | void item_check_present(struct radix_tree_root *root, unsigned long index); |
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index faadbe233966..4123d0ab90ba 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c | |||
| @@ -1108,7 +1108,7 @@ static void test_stacktrace_build_id(void) | |||
| 1108 | 1108 | ||
| 1109 | assert(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null") | 1109 | assert(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null") |
| 1110 | == 0); | 1110 | == 0); |
| 1111 | assert(system("./urandom_read if=/dev/urandom of=/dev/zero count=4 2> /dev/null") == 0); | 1111 | assert(system("./urandom_read") == 0); |
| 1112 | /* disable stack trace collection */ | 1112 | /* disable stack trace collection */ |
| 1113 | key = 0; | 1113 | key = 0; |
| 1114 | val = 1; | 1114 | val = 1; |
| @@ -1158,7 +1158,7 @@ static void test_stacktrace_build_id(void) | |||
| 1158 | } while (bpf_map_get_next_key(stackmap_fd, &previous_key, &key) == 0); | 1158 | } while (bpf_map_get_next_key(stackmap_fd, &previous_key, &key) == 0); |
| 1159 | 1159 | ||
| 1160 | CHECK(build_id_matches < 1, "build id match", | 1160 | CHECK(build_id_matches < 1, "build id match", |
| 1161 | "Didn't find expected build ID from the map"); | 1161 | "Didn't find expected build ID from the map\n"); |
| 1162 | 1162 | ||
| 1163 | disable_pmu: | 1163 | disable_pmu: |
| 1164 | ioctl(pmu_fd, PERF_EVENT_IOC_DISABLE); | 1164 | ioctl(pmu_fd, PERF_EVENT_IOC_DISABLE); |
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 2ddcc96ae456..d9d00319b07c 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile | |||
| @@ -15,7 +15,7 @@ LIBKVM += $(LIBKVM_$(UNAME_M)) | |||
| 15 | 15 | ||
| 16 | INSTALL_HDR_PATH = $(top_srcdir)/usr | 16 | INSTALL_HDR_PATH = $(top_srcdir)/usr |
| 17 | LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/ | 17 | LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/ |
| 18 | CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) | 18 | CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -I.. |
| 19 | 19 | ||
| 20 | # After inclusion, $(OUTPUT) is defined and | 20 | # After inclusion, $(OUTPUT) is defined and |
| 21 | # $(TEST_GEN_PROGS) starts with $(OUTPUT)/ | 21 | # $(TEST_GEN_PROGS) starts with $(OUTPUT)/ |
diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testing/selftests/kvm/include/test_util.h index 7ab98e41324f..ac53730b30aa 100644 --- a/tools/testing/selftests/kvm/include/test_util.h +++ b/tools/testing/selftests/kvm/include/test_util.h | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <errno.h> | 19 | #include <errno.h> |
| 20 | #include <unistd.h> | 20 | #include <unistd.h> |
| 21 | #include <fcntl.h> | 21 | #include <fcntl.h> |
| 22 | #include "kselftest.h" | ||
| 22 | 23 | ||
| 23 | ssize_t test_write(int fd, const void *buf, size_t count); | 24 | ssize_t test_write(int fd, const void *buf, size_t count); |
| 24 | ssize_t test_read(int fd, void *buf, size_t count); | 25 | ssize_t test_read(int fd, void *buf, size_t count); |
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 2cedfda181d4..37e2a787d2fc 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c | |||
| @@ -50,8 +50,8 @@ int kvm_check_cap(long cap) | |||
| 50 | int kvm_fd; | 50 | int kvm_fd; |
| 51 | 51 | ||
| 52 | kvm_fd = open(KVM_DEV_PATH, O_RDONLY); | 52 | kvm_fd = open(KVM_DEV_PATH, O_RDONLY); |
| 53 | TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i", | 53 | if (kvm_fd < 0) |
| 54 | KVM_DEV_PATH, kvm_fd, errno); | 54 | exit(KSFT_SKIP); |
| 55 | 55 | ||
| 56 | ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, cap); | 56 | ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, cap); |
| 57 | TEST_ASSERT(ret != -1, "KVM_CHECK_EXTENSION IOCTL failed,\n" | 57 | TEST_ASSERT(ret != -1, "KVM_CHECK_EXTENSION IOCTL failed,\n" |
| @@ -91,8 +91,8 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) | |||
| 91 | 91 | ||
| 92 | vm->mode = mode; | 92 | vm->mode = mode; |
| 93 | kvm_fd = open(KVM_DEV_PATH, perm); | 93 | kvm_fd = open(KVM_DEV_PATH, perm); |
| 94 | TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i", | 94 | if (kvm_fd < 0) |
| 95 | KVM_DEV_PATH, kvm_fd, errno); | 95 | exit(KSFT_SKIP); |
| 96 | 96 | ||
| 97 | /* Create VM. */ | 97 | /* Create VM. */ |
| 98 | vm->fd = ioctl(kvm_fd, KVM_CREATE_VM, NULL); | 98 | vm->fd = ioctl(kvm_fd, KVM_CREATE_VM, NULL); |
| @@ -418,8 +418,8 @@ struct kvm_cpuid2 *kvm_get_supported_cpuid(void) | |||
| 418 | 418 | ||
| 419 | cpuid = allocate_kvm_cpuid2(); | 419 | cpuid = allocate_kvm_cpuid2(); |
| 420 | kvm_fd = open(KVM_DEV_PATH, O_RDONLY); | 420 | kvm_fd = open(KVM_DEV_PATH, O_RDONLY); |
| 421 | TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i", | 421 | if (kvm_fd < 0) |
| 422 | KVM_DEV_PATH, kvm_fd, errno); | 422 | exit(KSFT_SKIP); |
| 423 | 423 | ||
| 424 | ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_CPUID, cpuid); | 424 | ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_CPUID, cpuid); |
| 425 | TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_CPUID failed %d %d\n", | 425 | TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_CPUID failed %d %d\n", |
| @@ -675,8 +675,8 @@ static int vcpu_mmap_sz(void) | |||
| 675 | int dev_fd, ret; | 675 | int dev_fd, ret; |
| 676 | 676 | ||
| 677 | dev_fd = open(KVM_DEV_PATH, O_RDONLY); | 677 | dev_fd = open(KVM_DEV_PATH, O_RDONLY); |
| 678 | TEST_ASSERT(dev_fd >= 0, "%s open %s failed, rc: %i errno: %i", | 678 | if (dev_fd < 0) |
| 679 | __func__, KVM_DEV_PATH, dev_fd, errno); | 679 | exit(KSFT_SKIP); |
| 680 | 680 | ||
| 681 | ret = ioctl(dev_fd, KVM_GET_VCPU_MMAP_SIZE, NULL); | 681 | ret = ioctl(dev_fd, KVM_GET_VCPU_MMAP_SIZE, NULL); |
| 682 | TEST_ASSERT(ret >= sizeof(struct kvm_run), | 682 | TEST_ASSERT(ret >= sizeof(struct kvm_run), |
diff --git a/tools/testing/selftests/kvm/sync_regs_test.c b/tools/testing/selftests/kvm/sync_regs_test.c index 428e9473f5e2..eae1ece3c31b 100644 --- a/tools/testing/selftests/kvm/sync_regs_test.c +++ b/tools/testing/selftests/kvm/sync_regs_test.c | |||
| @@ -85,6 +85,9 @@ static void compare_vcpu_events(struct kvm_vcpu_events *left, | |||
| 85 | { | 85 | { |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | #define TEST_SYNC_FIELDS (KVM_SYNC_X86_REGS|KVM_SYNC_X86_SREGS|KVM_SYNC_X86_EVENTS) | ||
| 89 | #define INVALID_SYNC_FIELD 0x80000000 | ||
| 90 | |||
| 88 | int main(int argc, char *argv[]) | 91 | int main(int argc, char *argv[]) |
| 89 | { | 92 | { |
| 90 | struct kvm_vm *vm; | 93 | struct kvm_vm *vm; |
| @@ -98,9 +101,14 @@ int main(int argc, char *argv[]) | |||
| 98 | setbuf(stdout, NULL); | 101 | setbuf(stdout, NULL); |
| 99 | 102 | ||
| 100 | cap = kvm_check_cap(KVM_CAP_SYNC_REGS); | 103 | cap = kvm_check_cap(KVM_CAP_SYNC_REGS); |
| 101 | TEST_ASSERT((unsigned long)cap == KVM_SYNC_X86_VALID_FIELDS, | 104 | if ((cap & TEST_SYNC_FIELDS) != TEST_SYNC_FIELDS) { |
| 102 | "KVM_CAP_SYNC_REGS (0x%x) != KVM_SYNC_X86_VALID_FIELDS (0x%lx)\n", | 105 | fprintf(stderr, "KVM_CAP_SYNC_REGS not supported, skipping test\n"); |
| 103 | cap, KVM_SYNC_X86_VALID_FIELDS); | 106 | exit(KSFT_SKIP); |
| 107 | } | ||
| 108 | if ((cap & INVALID_SYNC_FIELD) != 0) { | ||
| 109 | fprintf(stderr, "The \"invalid\" field is not invalid, skipping test\n"); | ||
| 110 | exit(KSFT_SKIP); | ||
| 111 | } | ||
| 104 | 112 | ||
| 105 | /* Create VM */ | 113 | /* Create VM */ |
| 106 | vm = vm_create_default(VCPU_ID, guest_code); | 114 | vm = vm_create_default(VCPU_ID, guest_code); |
| @@ -108,7 +116,14 @@ int main(int argc, char *argv[]) | |||
| 108 | run = vcpu_state(vm, VCPU_ID); | 116 | run = vcpu_state(vm, VCPU_ID); |
| 109 | 117 | ||
| 110 | /* Request reading invalid register set from VCPU. */ | 118 | /* Request reading invalid register set from VCPU. */ |
| 111 | run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS << 1; | 119 | run->kvm_valid_regs = INVALID_SYNC_FIELD; |
| 120 | rv = _vcpu_run(vm, VCPU_ID); | ||
| 121 | TEST_ASSERT(rv < 0 && errno == EINVAL, | ||
| 122 | "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n", | ||
| 123 | rv); | ||
| 124 | vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0; | ||
| 125 | |||
| 126 | run->kvm_valid_regs = INVALID_SYNC_FIELD | TEST_SYNC_FIELDS; | ||
| 112 | rv = _vcpu_run(vm, VCPU_ID); | 127 | rv = _vcpu_run(vm, VCPU_ID); |
| 113 | TEST_ASSERT(rv < 0 && errno == EINVAL, | 128 | TEST_ASSERT(rv < 0 && errno == EINVAL, |
| 114 | "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n", | 129 | "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n", |
| @@ -116,7 +131,14 @@ int main(int argc, char *argv[]) | |||
| 116 | vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0; | 131 | vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0; |
| 117 | 132 | ||
| 118 | /* Request setting invalid register set into VCPU. */ | 133 | /* Request setting invalid register set into VCPU. */ |
| 119 | run->kvm_dirty_regs = KVM_SYNC_X86_VALID_FIELDS << 1; | 134 | run->kvm_dirty_regs = INVALID_SYNC_FIELD; |
| 135 | rv = _vcpu_run(vm, VCPU_ID); | ||
| 136 | TEST_ASSERT(rv < 0 && errno == EINVAL, | ||
| 137 | "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n", | ||
| 138 | rv); | ||
| 139 | vcpu_state(vm, VCPU_ID)->kvm_dirty_regs = 0; | ||
| 140 | |||
| 141 | run->kvm_dirty_regs = INVALID_SYNC_FIELD | TEST_SYNC_FIELDS; | ||
| 120 | rv = _vcpu_run(vm, VCPU_ID); | 142 | rv = _vcpu_run(vm, VCPU_ID); |
| 121 | TEST_ASSERT(rv < 0 && errno == EINVAL, | 143 | TEST_ASSERT(rv < 0 && errno == EINVAL, |
| 122 | "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n", | 144 | "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n", |
| @@ -125,7 +147,7 @@ int main(int argc, char *argv[]) | |||
| 125 | 147 | ||
| 126 | /* Request and verify all valid register sets. */ | 148 | /* Request and verify all valid register sets. */ |
| 127 | /* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */ | 149 | /* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */ |
| 128 | run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; | 150 | run->kvm_valid_regs = TEST_SYNC_FIELDS; |
| 129 | rv = _vcpu_run(vm, VCPU_ID); | 151 | rv = _vcpu_run(vm, VCPU_ID); |
| 130 | TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, | 152 | TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, |
| 131 | "Unexpected exit reason: %u (%s),\n", | 153 | "Unexpected exit reason: %u (%s),\n", |
| @@ -146,7 +168,7 @@ int main(int argc, char *argv[]) | |||
| 146 | run->s.regs.sregs.apic_base = 1 << 11; | 168 | run->s.regs.sregs.apic_base = 1 << 11; |
| 147 | /* TODO run->s.regs.events.XYZ = ABC; */ | 169 | /* TODO run->s.regs.events.XYZ = ABC; */ |
| 148 | 170 | ||
| 149 | run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; | 171 | run->kvm_valid_regs = TEST_SYNC_FIELDS; |
| 150 | run->kvm_dirty_regs = KVM_SYNC_X86_REGS | KVM_SYNC_X86_SREGS; | 172 | run->kvm_dirty_regs = KVM_SYNC_X86_REGS | KVM_SYNC_X86_SREGS; |
| 151 | rv = _vcpu_run(vm, VCPU_ID); | 173 | rv = _vcpu_run(vm, VCPU_ID); |
| 152 | TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, | 174 | TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, |
| @@ -172,7 +194,7 @@ int main(int argc, char *argv[]) | |||
| 172 | /* Clear kvm_dirty_regs bits, verify new s.regs values are | 194 | /* Clear kvm_dirty_regs bits, verify new s.regs values are |
| 173 | * overwritten with existing guest values. | 195 | * overwritten with existing guest values. |
| 174 | */ | 196 | */ |
| 175 | run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; | 197 | run->kvm_valid_regs = TEST_SYNC_FIELDS; |
| 176 | run->kvm_dirty_regs = 0; | 198 | run->kvm_dirty_regs = 0; |
| 177 | run->s.regs.regs.r11 = 0xDEADBEEF; | 199 | run->s.regs.regs.r11 = 0xDEADBEEF; |
| 178 | rv = _vcpu_run(vm, VCPU_ID); | 200 | rv = _vcpu_run(vm, VCPU_ID); |
| @@ -211,7 +233,7 @@ int main(int argc, char *argv[]) | |||
| 211 | * with kvm_sync_regs values. | 233 | * with kvm_sync_regs values. |
| 212 | */ | 234 | */ |
| 213 | run->kvm_valid_regs = 0; | 235 | run->kvm_valid_regs = 0; |
| 214 | run->kvm_dirty_regs = KVM_SYNC_X86_VALID_FIELDS; | 236 | run->kvm_dirty_regs = TEST_SYNC_FIELDS; |
| 215 | run->s.regs.regs.r11 = 0xBBBB; | 237 | run->s.regs.regs.r11 = 0xBBBB; |
| 216 | rv = _vcpu_run(vm, VCPU_ID); | 238 | rv = _vcpu_run(vm, VCPU_ID); |
| 217 | TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, | 239 | TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, |
diff --git a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c index 8f7f62093add..aaa633263b2c 100644 --- a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c +++ b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c | |||
| @@ -189,8 +189,8 @@ int main(int argc, char *argv[]) | |||
| 189 | struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); | 189 | struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); |
| 190 | 190 | ||
| 191 | if (!(entry->ecx & CPUID_VMX)) { | 191 | if (!(entry->ecx & CPUID_VMX)) { |
| 192 | printf("nested VMX not enabled, skipping test"); | 192 | fprintf(stderr, "nested VMX not enabled, skipping test\n"); |
| 193 | return 0; | 193 | exit(KSFT_SKIP); |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | vm = vm_create_default_vmx(VCPU_ID, (void *) l1_guest_code); | 196 | vm = vm_create_default_vmx(VCPU_ID, (void *) l1_guest_code); |
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index 195e9d4739a9..c1b1a4dc6a96 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk | |||
| @@ -20,10 +20,10 @@ all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) | |||
| 20 | 20 | ||
| 21 | .ONESHELL: | 21 | .ONESHELL: |
| 22 | define RUN_TESTS | 22 | define RUN_TESTS |
| 23 | @export KSFT_TAP_LEVEL=`echo 1`; | 23 | @export KSFT_TAP_LEVEL=`echo 1`; \ |
| 24 | @test_num=`echo 0`; | 24 | test_num=`echo 0`; \ |
| 25 | @echo "TAP version 13"; | 25 | echo "TAP version 13"; \ |
| 26 | @for TEST in $(1); do \ | 26 | for TEST in $(1); do \ |
| 27 | BASENAME_TEST=`basename $$TEST`; \ | 27 | BASENAME_TEST=`basename $$TEST`; \ |
| 28 | test_num=`echo $$test_num+1 | bc`; \ | 28 | test_num=`echo $$test_num+1 | bc`; \ |
| 29 | echo "selftests: $$BASENAME_TEST"; \ | 29 | echo "selftests: $$BASENAME_TEST"; \ |
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 8f1e13d2e547..3ff81a478dbe 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile | |||
| @@ -5,7 +5,8 @@ CFLAGS = -Wall -Wl,--no-as-needed -O2 -g | |||
| 5 | CFLAGS += -I../../../../usr/include/ | 5 | CFLAGS += -I../../../../usr/include/ |
| 6 | 6 | ||
| 7 | TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh | 7 | TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh |
| 8 | TEST_PROGS += fib_tests.sh fib-onlink-tests.sh in_netns.sh pmtu.sh | 8 | TEST_PROGS += fib_tests.sh fib-onlink-tests.sh pmtu.sh |
| 9 | TEST_PROGS_EXTENDED := in_netns.sh | ||
| 9 | TEST_GEN_FILES = socket | 10 | TEST_GEN_FILES = socket |
| 10 | TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy | 11 | TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy |
| 11 | TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa | 12 | TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json b/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json index 5b012f4981d4..6f289a49e5ec 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json | |||
| @@ -66,7 +66,7 @@ | |||
| 66 | "cmdUnderTest": "$TC action add action bpf object-file _b.o index 667", | 66 | "cmdUnderTest": "$TC action add action bpf object-file _b.o index 667", |
| 67 | "expExitCode": "0", | 67 | "expExitCode": "0", |
| 68 | "verifyCmd": "$TC action get action bpf index 667", | 68 | "verifyCmd": "$TC action get action bpf index 667", |
| 69 | "matchPattern": "action order [0-9]*: bpf _b.o:\\[action\\] id [0-9]* tag 3b185187f1855c4c default-action pipe.*index 667 ref", | 69 | "matchPattern": "action order [0-9]*: bpf _b.o:\\[action\\] id [0-9]* tag 3b185187f1855c4c( jited)? default-action pipe.*index 667 ref", |
| 70 | "matchCount": "1", | 70 | "matchCount": "1", |
| 71 | "teardown": [ | 71 | "teardown": [ |
| 72 | "$TC action flush action bpf", | 72 | "$TC action flush action bpf", |
| @@ -92,10 +92,15 @@ | |||
| 92 | "cmdUnderTest": "$TC action add action bpf object-file _c.o index 667", | 92 | "cmdUnderTest": "$TC action add action bpf object-file _c.o index 667", |
| 93 | "expExitCode": "255", | 93 | "expExitCode": "255", |
| 94 | "verifyCmd": "$TC action get action bpf index 667", | 94 | "verifyCmd": "$TC action get action bpf index 667", |
| 95 | "matchPattern": "action order [0-9]*: bpf _b.o:\\[action\\] id [0-9].*index 667 ref", | 95 | "matchPattern": "action order [0-9]*: bpf _c.o:\\[action\\] id [0-9].*index 667 ref", |
| 96 | "matchCount": "0", | 96 | "matchCount": "0", |
| 97 | "teardown": [ | 97 | "teardown": [ |
| 98 | "$TC action flush action bpf", | 98 | [ |
| 99 | "$TC action flush action bpf", | ||
| 100 | 0, | ||
| 101 | 1, | ||
| 102 | 255 | ||
| 103 | ], | ||
| 99 | "rm -f _c.o" | 104 | "rm -f _c.o" |
| 100 | ] | 105 | ] |
| 101 | }, | 106 | }, |
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index d744991c0f4f..39f66bc29b82 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
| @@ -11,7 +11,7 @@ CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c) | |||
| 11 | 11 | ||
| 12 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \ | 12 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \ |
| 13 | check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \ | 13 | check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \ |
| 14 | protection_keys test_vdso test_vsyscall | 14 | protection_keys test_vdso test_vsyscall mov_ss_trap |
| 15 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ | 15 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ |
| 16 | test_FCMOV test_FCOMI test_FISTTP \ | 16 | test_FCMOV test_FCOMI test_FISTTP \ |
| 17 | vdso_restorer | 17 | vdso_restorer |
diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c new file mode 100644 index 000000000000..3c3a022654f3 --- /dev/null +++ b/tools/testing/selftests/x86/mov_ss_trap.c | |||
| @@ -0,0 +1,285 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * mov_ss_trap.c: Exercise the bizarre side effects of a watchpoint on MOV SS | ||
| 4 | * | ||
| 5 | * This does MOV SS from a watchpointed address followed by various | ||
| 6 | * types of kernel entries. A MOV SS that hits a watchpoint will queue | ||
| 7 | * up a #DB trap but will not actually deliver that trap. The trap | ||
| 8 | * will be delivered after the next instruction instead. The CPU's logic | ||
| 9 | * seems to be: | ||
| 10 | * | ||
| 11 | * - Any fault: drop the pending #DB trap. | ||
| 12 | * - INT $N, INT3, INTO, SYSCALL, SYSENTER: enter the kernel and then | ||
| 13 | * deliver #DB. | ||
| 14 | * - ICEBP: enter the kernel but do not deliver the watchpoint trap | ||
| 15 | * - breakpoint: only one #DB is delivered (phew!) | ||
| 16 | * | ||
| 17 | * There are plenty of ways for a kernel to handle this incorrectly. This | ||
| 18 | * test tries to exercise all the cases. | ||
| 19 | * | ||
| 20 | * This should mostly cover CVE-2018-1087 and CVE-2018-8897. | ||
| 21 | */ | ||
| 22 | #define _GNU_SOURCE | ||
| 23 | |||
| 24 | #include <stdlib.h> | ||
| 25 | #include <sys/ptrace.h> | ||
| 26 | #include <sys/types.h> | ||
| 27 | #include <sys/wait.h> | ||
| 28 | #include <sys/user.h> | ||
| 29 | #include <sys/syscall.h> | ||
| 30 | #include <unistd.h> | ||
| 31 | #include <errno.h> | ||
| 32 | #include <stddef.h> | ||
| 33 | #include <stdio.h> | ||
| 34 | #include <err.h> | ||
| 35 | #include <string.h> | ||
| 36 | #include <setjmp.h> | ||
| 37 | #include <sys/prctl.h> | ||
| 38 | |||
| 39 | #define X86_EFLAGS_RF (1UL << 16) | ||
| 40 | |||
| 41 | #if __x86_64__ | ||
| 42 | # define REG_IP REG_RIP | ||
| 43 | #else | ||
| 44 | # define REG_IP REG_EIP | ||
| 45 | #endif | ||
| 46 | |||
| 47 | unsigned short ss; | ||
| 48 | extern unsigned char breakpoint_insn[]; | ||
| 49 | sigjmp_buf jmpbuf; | ||
| 50 | static unsigned char altstack_data[SIGSTKSZ]; | ||
| 51 | |||
| 52 | static void enable_watchpoint(void) | ||
| 53 | { | ||
| 54 | pid_t parent = getpid(); | ||
| 55 | int status; | ||
| 56 | |||
| 57 | pid_t child = fork(); | ||
| 58 | if (child < 0) | ||
| 59 | err(1, "fork"); | ||
| 60 | |||
| 61 | if (child) { | ||
| 62 | if (waitpid(child, &status, 0) != child) | ||
| 63 | err(1, "waitpid for child"); | ||
| 64 | } else { | ||
| 65 | unsigned long dr0, dr1, dr7; | ||
| 66 | |||
| 67 | dr0 = (unsigned long)&ss; | ||
| 68 | dr1 = (unsigned long)breakpoint_insn; | ||
| 69 | dr7 = ((1UL << 1) | /* G0 */ | ||
| 70 | (3UL << 16) | /* RW0 = read or write */ | ||
| 71 | (1UL << 18) | /* LEN0 = 2 bytes */ | ||
| 72 | (1UL << 3)); /* G1, RW1 = insn */ | ||
| 73 | |||
| 74 | if (ptrace(PTRACE_ATTACH, parent, NULL, NULL) != 0) | ||
| 75 | err(1, "PTRACE_ATTACH"); | ||
| 76 | |||
| 77 | if (waitpid(parent, &status, 0) != parent) | ||
| 78 | err(1, "waitpid for child"); | ||
| 79 | |||
| 80 | if (ptrace(PTRACE_POKEUSER, parent, (void *)offsetof(struct user, u_debugreg[0]), dr0) != 0) | ||
| 81 | err(1, "PTRACE_POKEUSER DR0"); | ||
| 82 | |||
| 83 | if (ptrace(PTRACE_POKEUSER, parent, (void *)offsetof(struct user, u_debugreg[1]), dr1) != 0) | ||
| 84 | err(1, "PTRACE_POKEUSER DR1"); | ||
| 85 | |||
| 86 | if (ptrace(PTRACE_POKEUSER, parent, (void *)offsetof(struct user, u_debugreg[7]), dr7) != 0) | ||
| 87 | err(1, "PTRACE_POKEUSER DR7"); | ||
| 88 | |||
| 89 | printf("\tDR0 = %lx, DR1 = %lx, DR7 = %lx\n", dr0, dr1, dr7); | ||
| 90 | |||
| 91 | if (ptrace(PTRACE_DETACH, parent, NULL, NULL) != 0) | ||
| 92 | err(1, "PTRACE_DETACH"); | ||
| 93 | |||
| 94 | exit(0); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), | ||
| 99 | int flags) | ||
| 100 | { | ||
| 101 | struct sigaction sa; | ||
| 102 | memset(&sa, 0, sizeof(sa)); | ||
| 103 | sa.sa_sigaction = handler; | ||
| 104 | sa.sa_flags = SA_SIGINFO | flags; | ||
| 105 | sigemptyset(&sa.sa_mask); | ||
| 106 | if (sigaction(sig, &sa, 0)) | ||
| 107 | err(1, "sigaction"); | ||
| 108 | } | ||
| 109 | |||
| 110 | static char const * const signames[] = { | ||
| 111 | [SIGSEGV] = "SIGSEGV", | ||
| 112 | [SIGBUS] = "SIBGUS", | ||
| 113 | [SIGTRAP] = "SIGTRAP", | ||
| 114 | [SIGILL] = "SIGILL", | ||
| 115 | }; | ||
| 116 | |||
| 117 | static void sigtrap(int sig, siginfo_t *si, void *ctx_void) | ||
| 118 | { | ||
| 119 | ucontext_t *ctx = ctx_void; | ||
| 120 | |||
| 121 | printf("\tGot SIGTRAP with RIP=%lx, EFLAGS.RF=%d\n", | ||
| 122 | (unsigned long)ctx->uc_mcontext.gregs[REG_IP], | ||
| 123 | !!(ctx->uc_mcontext.gregs[REG_EFL] & X86_EFLAGS_RF)); | ||
| 124 | } | ||
| 125 | |||
| 126 | static void handle_and_return(int sig, siginfo_t *si, void *ctx_void) | ||
| 127 | { | ||
| 128 | ucontext_t *ctx = ctx_void; | ||
| 129 | |||
| 130 | printf("\tGot %s with RIP=%lx\n", signames[sig], | ||
| 131 | (unsigned long)ctx->uc_mcontext.gregs[REG_IP]); | ||
| 132 | } | ||
| 133 | |||
| 134 | static void handle_and_longjmp(int sig, siginfo_t *si, void *ctx_void) | ||
| 135 | { | ||
| 136 | ucontext_t *ctx = ctx_void; | ||
| 137 | |||
| 138 | printf("\tGot %s with RIP=%lx\n", signames[sig], | ||
| 139 | (unsigned long)ctx->uc_mcontext.gregs[REG_IP]); | ||
| 140 | |||
| 141 | siglongjmp(jmpbuf, 1); | ||
| 142 | } | ||
| 143 | |||
| 144 | int main() | ||
| 145 | { | ||
| 146 | unsigned long nr; | ||
| 147 | |||
| 148 | asm volatile ("mov %%ss, %[ss]" : [ss] "=m" (ss)); | ||
| 149 | printf("\tSS = 0x%hx, &SS = 0x%p\n", ss, &ss); | ||
| 150 | |||
| 151 | if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0) == 0) | ||
| 152 | printf("\tPR_SET_PTRACER_ANY succeeded\n"); | ||
| 153 | |||
| 154 | printf("\tSet up a watchpoint\n"); | ||
| 155 | sethandler(SIGTRAP, sigtrap, 0); | ||
| 156 | enable_watchpoint(); | ||
| 157 | |||
| 158 | printf("[RUN]\tRead from watched memory (should get SIGTRAP)\n"); | ||
| 159 | asm volatile ("mov %[ss], %[tmp]" : [tmp] "=r" (nr) : [ss] "m" (ss)); | ||
| 160 | |||
| 161 | printf("[RUN]\tMOV SS; INT3\n"); | ||
| 162 | asm volatile ("mov %[ss], %%ss; int3" :: [ss] "m" (ss)); | ||
| 163 | |||
| 164 | printf("[RUN]\tMOV SS; INT 3\n"); | ||
| 165 | asm volatile ("mov %[ss], %%ss; .byte 0xcd, 0x3" :: [ss] "m" (ss)); | ||
| 166 | |||
| 167 | printf("[RUN]\tMOV SS; CS CS INT3\n"); | ||
| 168 | asm volatile ("mov %[ss], %%ss; .byte 0x2e, 0x2e; int3" :: [ss] "m" (ss)); | ||
| 169 | |||
| 170 | printf("[RUN]\tMOV SS; CSx14 INT3\n"); | ||
| 171 | asm volatile ("mov %[ss], %%ss; .fill 14,1,0x2e; int3" :: [ss] "m" (ss)); | ||
| 172 | |||
| 173 | printf("[RUN]\tMOV SS; INT 4\n"); | ||
| 174 | sethandler(SIGSEGV, handle_and_return, SA_RESETHAND); | ||
| 175 | asm volatile ("mov %[ss], %%ss; int $4" :: [ss] "m" (ss)); | ||
| 176 | |||
| 177 | #ifdef __i386__ | ||
| 178 | printf("[RUN]\tMOV SS; INTO\n"); | ||
| 179 | sethandler(SIGSEGV, handle_and_return, SA_RESETHAND); | ||
| 180 | nr = -1; | ||
| 181 | asm volatile ("add $1, %[tmp]; mov %[ss], %%ss; into" | ||
| 182 | : [tmp] "+r" (nr) : [ss] "m" (ss)); | ||
| 183 | #endif | ||
| 184 | |||
| 185 | if (sigsetjmp(jmpbuf, 1) == 0) { | ||
| 186 | printf("[RUN]\tMOV SS; ICEBP\n"); | ||
| 187 | |||
| 188 | /* Some emulators (e.g. QEMU TCG) don't emulate ICEBP. */ | ||
| 189 | sethandler(SIGILL, handle_and_longjmp, SA_RESETHAND); | ||
| 190 | |||
| 191 | asm volatile ("mov %[ss], %%ss; .byte 0xf1" :: [ss] "m" (ss)); | ||
| 192 | } | ||
| 193 | |||
| 194 | if (sigsetjmp(jmpbuf, 1) == 0) { | ||
| 195 | printf("[RUN]\tMOV SS; CLI\n"); | ||
| 196 | sethandler(SIGSEGV, handle_and_longjmp, SA_RESETHAND); | ||
| 197 | asm volatile ("mov %[ss], %%ss; cli" :: [ss] "m" (ss)); | ||
| 198 | } | ||
| 199 | |||
| 200 | if (sigsetjmp(jmpbuf, 1) == 0) { | ||
| 201 | printf("[RUN]\tMOV SS; #PF\n"); | ||
| 202 | sethandler(SIGSEGV, handle_and_longjmp, SA_RESETHAND); | ||
| 203 | asm volatile ("mov %[ss], %%ss; mov (-1), %[tmp]" | ||
| 204 | : [tmp] "=r" (nr) : [ss] "m" (ss)); | ||
| 205 | } | ||
| 206 | |||
| 207 | /* | ||
| 208 | * INT $1: if #DB has DPL=3 and there isn't special handling, | ||
| 209 | * then the kernel will die. | ||
| 210 | */ | ||
| 211 | if (sigsetjmp(jmpbuf, 1) == 0) { | ||
| 212 | printf("[RUN]\tMOV SS; INT 1\n"); | ||
| 213 | sethandler(SIGSEGV, handle_and_longjmp, SA_RESETHAND); | ||
| 214 | asm volatile ("mov %[ss], %%ss; int $1" :: [ss] "m" (ss)); | ||
| 215 | } | ||
| 216 | |||
| 217 | #ifdef __x86_64__ | ||
| 218 | /* | ||
| 219 | * In principle, we should test 32-bit SYSCALL as well, but | ||
| 220 | * the calling convention is so unpredictable that it's | ||
| 221 | * not obviously worth the effort. | ||
| 222 | */ | ||
| 223 | if (sigsetjmp(jmpbuf, 1) == 0) { | ||
| 224 | printf("[RUN]\tMOV SS; SYSCALL\n"); | ||
| 225 | sethandler(SIGILL, handle_and_longjmp, SA_RESETHAND); | ||
| 226 | nr = SYS_getpid; | ||
| 227 | /* | ||
| 228 | * Toggle the high bit of RSP to make it noncanonical to | ||
| 229 | * strengthen this test on non-SMAP systems. | ||
| 230 | */ | ||
| 231 | asm volatile ("btc $63, %%rsp\n\t" | ||
| 232 | "mov %[ss], %%ss; syscall\n\t" | ||
| 233 | "btc $63, %%rsp" | ||
| 234 | : "+a" (nr) : [ss] "m" (ss) | ||
| 235 | : "rcx" | ||
| 236 | #ifdef __x86_64__ | ||
| 237 | , "r11" | ||
| 238 | #endif | ||
| 239 | ); | ||
| 240 | } | ||
| 241 | #endif | ||
| 242 | |||
| 243 | printf("[RUN]\tMOV SS; breakpointed NOP\n"); | ||
| 244 | asm volatile ("mov %[ss], %%ss; breakpoint_insn: nop" :: [ss] "m" (ss)); | ||
| 245 | |||
| 246 | /* | ||
| 247 | * Invoking SYSENTER directly breaks all the rules. Just handle | ||
| 248 | * the SIGSEGV. | ||
| 249 | */ | ||
| 250 | if (sigsetjmp(jmpbuf, 1) == 0) { | ||
| 251 | printf("[RUN]\tMOV SS; SYSENTER\n"); | ||
| 252 | stack_t stack = { | ||
| 253 | .ss_sp = altstack_data, | ||
| 254 | .ss_size = SIGSTKSZ, | ||
| 255 | }; | ||
| 256 | if (sigaltstack(&stack, NULL) != 0) | ||
| 257 | err(1, "sigaltstack"); | ||
| 258 | sethandler(SIGSEGV, handle_and_longjmp, SA_RESETHAND | SA_ONSTACK); | ||
| 259 | nr = SYS_getpid; | ||
| 260 | asm volatile ("mov %[ss], %%ss; SYSENTER" : "+a" (nr) | ||
| 261 | : [ss] "m" (ss) : "flags", "rcx" | ||
| 262 | #ifdef __x86_64__ | ||
| 263 | , "r11" | ||
| 264 | #endif | ||
| 265 | ); | ||
| 266 | |||
| 267 | /* We're unreachable here. SYSENTER forgets RIP. */ | ||
| 268 | } | ||
| 269 | |||
| 270 | if (sigsetjmp(jmpbuf, 1) == 0) { | ||
| 271 | printf("[RUN]\tMOV SS; INT $0x80\n"); | ||
| 272 | sethandler(SIGSEGV, handle_and_longjmp, SA_RESETHAND); | ||
| 273 | nr = 20; /* compat getpid */ | ||
| 274 | asm volatile ("mov %[ss], %%ss; int $0x80" | ||
| 275 | : "+a" (nr) : [ss] "m" (ss) | ||
| 276 | : "flags" | ||
| 277 | #ifdef __x86_64__ | ||
| 278 | , "r8", "r9", "r10", "r11" | ||
| 279 | #endif | ||
| 280 | ); | ||
| 281 | } | ||
| 282 | |||
| 283 | printf("[OK]\tI aten't dead\n"); | ||
| 284 | return 0; | ||
| 285 | } | ||
diff --git a/tools/testing/selftests/x86/mpx-mini-test.c b/tools/testing/selftests/x86/mpx-mini-test.c index 9c0325e1ea68..50f7e9272481 100644 --- a/tools/testing/selftests/x86/mpx-mini-test.c +++ b/tools/testing/selftests/x86/mpx-mini-test.c | |||
| @@ -368,6 +368,11 @@ static int expected_bnd_index = -1; | |||
| 368 | uint64_t shadow_plb[NR_MPX_BOUNDS_REGISTERS][2]; /* shadow MPX bound registers */ | 368 | uint64_t shadow_plb[NR_MPX_BOUNDS_REGISTERS][2]; /* shadow MPX bound registers */ |
| 369 | unsigned long shadow_map[NR_MPX_BOUNDS_REGISTERS]; | 369 | unsigned long shadow_map[NR_MPX_BOUNDS_REGISTERS]; |
| 370 | 370 | ||
| 371 | /* Failed address bound checks: */ | ||
| 372 | #ifndef SEGV_BNDERR | ||
| 373 | # define SEGV_BNDERR 3 | ||
| 374 | #endif | ||
| 375 | |||
| 371 | /* | 376 | /* |
| 372 | * The kernel is supposed to provide some information about the bounds | 377 | * The kernel is supposed to provide some information about the bounds |
| 373 | * exception in the siginfo. It should match what we have in the bounds | 378 | * exception in the siginfo. It should match what we have in the bounds |
| @@ -419,8 +424,6 @@ void handler(int signum, siginfo_t *si, void *vucontext) | |||
| 419 | br_count++; | 424 | br_count++; |
| 420 | dprintf1("#BR 0x%jx (total seen: %d)\n", status, br_count); | 425 | dprintf1("#BR 0x%jx (total seen: %d)\n", status, br_count); |
| 421 | 426 | ||
| 422 | #define SEGV_BNDERR 3 /* failed address bound checks */ | ||
| 423 | |||
| 424 | dprintf2("Saw a #BR! status 0x%jx at %016lx br_reason: %jx\n", | 427 | dprintf2("Saw a #BR! status 0x%jx at %016lx br_reason: %jx\n", |
| 425 | status, ip, br_reason); | 428 | status, ip, br_reason); |
| 426 | dprintf2("si_signo: %d\n", si->si_signo); | 429 | dprintf2("si_signo: %d\n", si->si_signo); |
diff --git a/tools/testing/selftests/x86/pkey-helpers.h b/tools/testing/selftests/x86/pkey-helpers.h index b3cb7670e026..254e5436bdd9 100644 --- a/tools/testing/selftests/x86/pkey-helpers.h +++ b/tools/testing/selftests/x86/pkey-helpers.h | |||
| @@ -26,30 +26,26 @@ static inline void sigsafe_printf(const char *format, ...) | |||
| 26 | { | 26 | { |
| 27 | va_list ap; | 27 | va_list ap; |
| 28 | 28 | ||
| 29 | va_start(ap, format); | ||
| 30 | if (!dprint_in_signal) { | 29 | if (!dprint_in_signal) { |
| 30 | va_start(ap, format); | ||
| 31 | vprintf(format, ap); | 31 | vprintf(format, ap); |
| 32 | va_end(ap); | ||
| 32 | } else { | 33 | } else { |
| 33 | int ret; | 34 | int ret; |
| 34 | int len = vsnprintf(dprint_in_signal_buffer, | ||
| 35 | DPRINT_IN_SIGNAL_BUF_SIZE, | ||
| 36 | format, ap); | ||
| 37 | /* | 35 | /* |
| 38 | * len is amount that would have been printed, | 36 | * No printf() functions are signal-safe. |
| 39 | * but actual write is truncated at BUF_SIZE. | 37 | * They deadlock easily. Write the format |
| 38 | * string to get some output, even if | ||
| 39 | * incomplete. | ||
| 40 | */ | 40 | */ |
| 41 | if (len > DPRINT_IN_SIGNAL_BUF_SIZE) | 41 | ret = write(1, format, strlen(format)); |
| 42 | len = DPRINT_IN_SIGNAL_BUF_SIZE; | ||
| 43 | ret = write(1, dprint_in_signal_buffer, len); | ||
| 44 | if (ret < 0) | 42 | if (ret < 0) |
| 45 | abort(); | 43 | exit(1); |
| 46 | } | 44 | } |
| 47 | va_end(ap); | ||
| 48 | } | 45 | } |
| 49 | #define dprintf_level(level, args...) do { \ | 46 | #define dprintf_level(level, args...) do { \ |
| 50 | if (level <= DEBUG_LEVEL) \ | 47 | if (level <= DEBUG_LEVEL) \ |
| 51 | sigsafe_printf(args); \ | 48 | sigsafe_printf(args); \ |
| 52 | fflush(NULL); \ | ||
| 53 | } while (0) | 49 | } while (0) |
| 54 | #define dprintf0(args...) dprintf_level(0, args) | 50 | #define dprintf0(args...) dprintf_level(0, args) |
| 55 | #define dprintf1(args...) dprintf_level(1, args) | 51 | #define dprintf1(args...) dprintf_level(1, args) |
diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c index f15aa5a76fe3..460b4bdf4c1e 100644 --- a/tools/testing/selftests/x86/protection_keys.c +++ b/tools/testing/selftests/x86/protection_keys.c | |||
| @@ -72,10 +72,9 @@ extern void abort_hooks(void); | |||
| 72 | test_nr, iteration_nr); \ | 72 | test_nr, iteration_nr); \ |
| 73 | dprintf0("errno at assert: %d", errno); \ | 73 | dprintf0("errno at assert: %d", errno); \ |
| 74 | abort_hooks(); \ | 74 | abort_hooks(); \ |
| 75 | assert(condition); \ | 75 | exit(__LINE__); \ |
| 76 | } \ | 76 | } \ |
| 77 | } while (0) | 77 | } while (0) |
| 78 | #define raw_assert(cond) assert(cond) | ||
| 79 | 78 | ||
| 80 | void cat_into_file(char *str, char *file) | 79 | void cat_into_file(char *str, char *file) |
| 81 | { | 80 | { |
| @@ -87,12 +86,17 @@ void cat_into_file(char *str, char *file) | |||
| 87 | * these need to be raw because they are called under | 86 | * these need to be raw because they are called under |
| 88 | * pkey_assert() | 87 | * pkey_assert() |
| 89 | */ | 88 | */ |
| 90 | raw_assert(fd >= 0); | 89 | if (fd < 0) { |
| 90 | fprintf(stderr, "error opening '%s'\n", str); | ||
| 91 | perror("error: "); | ||
| 92 | exit(__LINE__); | ||
| 93 | } | ||
| 94 | |||
| 91 | ret = write(fd, str, strlen(str)); | 95 | ret = write(fd, str, strlen(str)); |
| 92 | if (ret != strlen(str)) { | 96 | if (ret != strlen(str)) { |
| 93 | perror("write to file failed"); | 97 | perror("write to file failed"); |
| 94 | fprintf(stderr, "filename: '%s' str: '%s'\n", file, str); | 98 | fprintf(stderr, "filename: '%s' str: '%s'\n", file, str); |
| 95 | raw_assert(0); | 99 | exit(__LINE__); |
| 96 | } | 100 | } |
| 97 | close(fd); | 101 | close(fd); |
| 98 | } | 102 | } |
| @@ -191,26 +195,30 @@ void lots_o_noops_around_write(int *write_to_me) | |||
| 191 | #ifdef __i386__ | 195 | #ifdef __i386__ |
| 192 | 196 | ||
| 193 | #ifndef SYS_mprotect_key | 197 | #ifndef SYS_mprotect_key |
| 194 | # define SYS_mprotect_key 380 | 198 | # define SYS_mprotect_key 380 |
| 195 | #endif | 199 | #endif |
| 200 | |||
| 196 | #ifndef SYS_pkey_alloc | 201 | #ifndef SYS_pkey_alloc |
| 197 | # define SYS_pkey_alloc 381 | 202 | # define SYS_pkey_alloc 381 |
| 198 | # define SYS_pkey_free 382 | 203 | # define SYS_pkey_free 382 |
| 199 | #endif | 204 | #endif |
| 200 | #define REG_IP_IDX REG_EIP | 205 | |
| 201 | #define si_pkey_offset 0x14 | 206 | #define REG_IP_IDX REG_EIP |
| 207 | #define si_pkey_offset 0x14 | ||
| 202 | 208 | ||
| 203 | #else | 209 | #else |
| 204 | 210 | ||
| 205 | #ifndef SYS_mprotect_key | 211 | #ifndef SYS_mprotect_key |
| 206 | # define SYS_mprotect_key 329 | 212 | # define SYS_mprotect_key 329 |
| 207 | #endif | 213 | #endif |
| 214 | |||
| 208 | #ifndef SYS_pkey_alloc | 215 | #ifndef SYS_pkey_alloc |
| 209 | # define SYS_pkey_alloc 330 | 216 | # define SYS_pkey_alloc 330 |
| 210 | # define SYS_pkey_free 331 | 217 | # define SYS_pkey_free 331 |
| 211 | #endif | 218 | #endif |
| 212 | #define REG_IP_IDX REG_RIP | 219 | |
| 213 | #define si_pkey_offset 0x20 | 220 | #define REG_IP_IDX REG_RIP |
| 221 | #define si_pkey_offset 0x20 | ||
| 214 | 222 | ||
| 215 | #endif | 223 | #endif |
| 216 | 224 | ||
| @@ -225,8 +233,14 @@ void dump_mem(void *dumpme, int len_bytes) | |||
| 225 | } | 233 | } |
| 226 | } | 234 | } |
| 227 | 235 | ||
| 228 | #define SEGV_BNDERR 3 /* failed address bound checks */ | 236 | /* Failed address bound checks: */ |
| 229 | #define SEGV_PKUERR 4 | 237 | #ifndef SEGV_BNDERR |
| 238 | # define SEGV_BNDERR 3 | ||
| 239 | #endif | ||
| 240 | |||
| 241 | #ifndef SEGV_PKUERR | ||
| 242 | # define SEGV_PKUERR 4 | ||
| 243 | #endif | ||
| 230 | 244 | ||
| 231 | static char *si_code_str(int si_code) | 245 | static char *si_code_str(int si_code) |
| 232 | { | 246 | { |
| @@ -289,13 +303,6 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext) | |||
| 289 | dump_mem(pkru_ptr - 128, 256); | 303 | dump_mem(pkru_ptr - 128, 256); |
| 290 | pkey_assert(*pkru_ptr); | 304 | pkey_assert(*pkru_ptr); |
| 291 | 305 | ||
| 292 | si_pkey_ptr = (u32 *)(((u8 *)si) + si_pkey_offset); | ||
| 293 | dprintf1("si_pkey_ptr: %p\n", si_pkey_ptr); | ||
| 294 | dump_mem(si_pkey_ptr - 8, 24); | ||
| 295 | siginfo_pkey = *si_pkey_ptr; | ||
| 296 | pkey_assert(siginfo_pkey < NR_PKEYS); | ||
| 297 | last_si_pkey = siginfo_pkey; | ||
| 298 | |||
| 299 | if ((si->si_code == SEGV_MAPERR) || | 306 | if ((si->si_code == SEGV_MAPERR) || |
| 300 | (si->si_code == SEGV_ACCERR) || | 307 | (si->si_code == SEGV_ACCERR) || |
| 301 | (si->si_code == SEGV_BNDERR)) { | 308 | (si->si_code == SEGV_BNDERR)) { |
| @@ -303,6 +310,13 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext) | |||
| 303 | exit(4); | 310 | exit(4); |
| 304 | } | 311 | } |
| 305 | 312 | ||
| 313 | si_pkey_ptr = (u32 *)(((u8 *)si) + si_pkey_offset); | ||
| 314 | dprintf1("si_pkey_ptr: %p\n", si_pkey_ptr); | ||
| 315 | dump_mem((u8 *)si_pkey_ptr - 8, 24); | ||
| 316 | siginfo_pkey = *si_pkey_ptr; | ||
| 317 | pkey_assert(siginfo_pkey < NR_PKEYS); | ||
| 318 | last_si_pkey = siginfo_pkey; | ||
| 319 | |||
| 306 | dprintf1("signal pkru from xsave: %08x\n", *pkru_ptr); | 320 | dprintf1("signal pkru from xsave: %08x\n", *pkru_ptr); |
| 307 | /* need __rdpkru() version so we do not do shadow_pkru checking */ | 321 | /* need __rdpkru() version so we do not do shadow_pkru checking */ |
| 308 | dprintf1("signal pkru from pkru: %08x\n", __rdpkru()); | 322 | dprintf1("signal pkru from pkru: %08x\n", __rdpkru()); |
| @@ -311,22 +325,6 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext) | |||
| 311 | dprintf1("WARNING: set PRKU=0 to allow faulting instruction to continue\n"); | 325 | dprintf1("WARNING: set PRKU=0 to allow faulting instruction to continue\n"); |
| 312 | pkru_faults++; | 326 | pkru_faults++; |
| 313 | dprintf1("<<<<==================================================\n"); | 327 | dprintf1("<<<<==================================================\n"); |
| 314 | return; | ||
| 315 | if (trapno == 14) { | ||
| 316 | fprintf(stderr, | ||
| 317 | "ERROR: In signal handler, page fault, trapno = %d, ip = %016lx\n", | ||
| 318 | trapno, ip); | ||
| 319 | fprintf(stderr, "si_addr %p\n", si->si_addr); | ||
| 320 | fprintf(stderr, "REG_ERR: %lx\n", | ||
| 321 | (unsigned long)uctxt->uc_mcontext.gregs[REG_ERR]); | ||
| 322 | exit(1); | ||
| 323 | } else { | ||
| 324 | fprintf(stderr, "unexpected trap %d! at 0x%lx\n", trapno, ip); | ||
| 325 | fprintf(stderr, "si_addr %p\n", si->si_addr); | ||
| 326 | fprintf(stderr, "REG_ERR: %lx\n", | ||
| 327 | (unsigned long)uctxt->uc_mcontext.gregs[REG_ERR]); | ||
| 328 | exit(2); | ||
| 329 | } | ||
| 330 | dprint_in_signal = 0; | 328 | dprint_in_signal = 0; |
| 331 | } | 329 | } |
| 332 | 330 | ||
| @@ -393,10 +391,15 @@ pid_t fork_lazy_child(void) | |||
| 393 | return forkret; | 391 | return forkret; |
| 394 | } | 392 | } |
| 395 | 393 | ||
| 396 | #define PKEY_DISABLE_ACCESS 0x1 | 394 | #ifndef PKEY_DISABLE_ACCESS |
| 397 | #define PKEY_DISABLE_WRITE 0x2 | 395 | # define PKEY_DISABLE_ACCESS 0x1 |
| 396 | #endif | ||
| 397 | |||
| 398 | #ifndef PKEY_DISABLE_WRITE | ||
| 399 | # define PKEY_DISABLE_WRITE 0x2 | ||
| 400 | #endif | ||
| 398 | 401 | ||
| 399 | u32 pkey_get(int pkey, unsigned long flags) | 402 | static u32 hw_pkey_get(int pkey, unsigned long flags) |
| 400 | { | 403 | { |
| 401 | u32 mask = (PKEY_DISABLE_ACCESS|PKEY_DISABLE_WRITE); | 404 | u32 mask = (PKEY_DISABLE_ACCESS|PKEY_DISABLE_WRITE); |
| 402 | u32 pkru = __rdpkru(); | 405 | u32 pkru = __rdpkru(); |
| @@ -418,7 +421,7 @@ u32 pkey_get(int pkey, unsigned long flags) | |||
| 418 | return masked_pkru; | 421 | return masked_pkru; |
| 419 | } | 422 | } |
| 420 | 423 | ||
| 421 | int pkey_set(int pkey, unsigned long rights, unsigned long flags) | 424 | static int hw_pkey_set(int pkey, unsigned long rights, unsigned long flags) |
| 422 | { | 425 | { |
| 423 | u32 mask = (PKEY_DISABLE_ACCESS|PKEY_DISABLE_WRITE); | 426 | u32 mask = (PKEY_DISABLE_ACCESS|PKEY_DISABLE_WRITE); |
| 424 | u32 old_pkru = __rdpkru(); | 427 | u32 old_pkru = __rdpkru(); |
| @@ -452,15 +455,15 @@ void pkey_disable_set(int pkey, int flags) | |||
| 452 | pkey, flags); | 455 | pkey, flags); |
| 453 | pkey_assert(flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)); | 456 | pkey_assert(flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)); |
| 454 | 457 | ||
| 455 | pkey_rights = pkey_get(pkey, syscall_flags); | 458 | pkey_rights = hw_pkey_get(pkey, syscall_flags); |
| 456 | 459 | ||
| 457 | dprintf1("%s(%d) pkey_get(%d): %x\n", __func__, | 460 | dprintf1("%s(%d) hw_pkey_get(%d): %x\n", __func__, |
| 458 | pkey, pkey, pkey_rights); | 461 | pkey, pkey, pkey_rights); |
| 459 | pkey_assert(pkey_rights >= 0); | 462 | pkey_assert(pkey_rights >= 0); |
| 460 | 463 | ||
| 461 | pkey_rights |= flags; | 464 | pkey_rights |= flags; |
| 462 | 465 | ||
| 463 | ret = pkey_set(pkey, pkey_rights, syscall_flags); | 466 | ret = hw_pkey_set(pkey, pkey_rights, syscall_flags); |
| 464 | assert(!ret); | 467 | assert(!ret); |
| 465 | /*pkru and flags have the same format */ | 468 | /*pkru and flags have the same format */ |
| 466 | shadow_pkru |= flags << (pkey * 2); | 469 | shadow_pkru |= flags << (pkey * 2); |
| @@ -468,8 +471,8 @@ void pkey_disable_set(int pkey, int flags) | |||
| 468 | 471 | ||
| 469 | pkey_assert(ret >= 0); | 472 | pkey_assert(ret >= 0); |
| 470 | 473 | ||
| 471 | pkey_rights = pkey_get(pkey, syscall_flags); | 474 | pkey_rights = hw_pkey_get(pkey, syscall_flags); |
| 472 | dprintf1("%s(%d) pkey_get(%d): %x\n", __func__, | 475 | dprintf1("%s(%d) hw_pkey_get(%d): %x\n", __func__, |
| 473 | pkey, pkey, pkey_rights); | 476 | pkey, pkey, pkey_rights); |
| 474 | 477 | ||
| 475 | dprintf1("%s(%d) pkru: 0x%x\n", __func__, pkey, rdpkru()); | 478 | dprintf1("%s(%d) pkru: 0x%x\n", __func__, pkey, rdpkru()); |
| @@ -483,24 +486,24 @@ void pkey_disable_clear(int pkey, int flags) | |||
| 483 | { | 486 | { |
| 484 | unsigned long syscall_flags = 0; | 487 | unsigned long syscall_flags = 0; |
| 485 | int ret; | 488 | int ret; |
| 486 | int pkey_rights = pkey_get(pkey, syscall_flags); | 489 | int pkey_rights = hw_pkey_get(pkey, syscall_flags); |
| 487 | u32 orig_pkru = rdpkru(); | 490 | u32 orig_pkru = rdpkru(); |
| 488 | 491 | ||
| 489 | pkey_assert(flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)); | 492 | pkey_assert(flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)); |
| 490 | 493 | ||
| 491 | dprintf1("%s(%d) pkey_get(%d): %x\n", __func__, | 494 | dprintf1("%s(%d) hw_pkey_get(%d): %x\n", __func__, |
| 492 | pkey, pkey, pkey_rights); | 495 | pkey, pkey, pkey_rights); |
| 493 | pkey_assert(pkey_rights >= 0); | 496 | pkey_assert(pkey_rights >= 0); |
| 494 | 497 | ||
| 495 | pkey_rights |= flags; | 498 | pkey_rights |= flags; |
| 496 | 499 | ||
| 497 | ret = pkey_set(pkey, pkey_rights, 0); | 500 | ret = hw_pkey_set(pkey, pkey_rights, 0); |
| 498 | /* pkru and flags have the same format */ | 501 | /* pkru and flags have the same format */ |
| 499 | shadow_pkru &= ~(flags << (pkey * 2)); | 502 | shadow_pkru &= ~(flags << (pkey * 2)); |
| 500 | pkey_assert(ret >= 0); | 503 | pkey_assert(ret >= 0); |
| 501 | 504 | ||
| 502 | pkey_rights = pkey_get(pkey, syscall_flags); | 505 | pkey_rights = hw_pkey_get(pkey, syscall_flags); |
| 503 | dprintf1("%s(%d) pkey_get(%d): %x\n", __func__, | 506 | dprintf1("%s(%d) hw_pkey_get(%d): %x\n", __func__, |
| 504 | pkey, pkey, pkey_rights); | 507 | pkey, pkey, pkey_rights); |
| 505 | 508 | ||
| 506 | dprintf1("%s(%d) pkru: 0x%x\n", __func__, pkey, rdpkru()); | 509 | dprintf1("%s(%d) pkru: 0x%x\n", __func__, pkey, rdpkru()); |
| @@ -674,10 +677,12 @@ int mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot, | |||
| 674 | struct pkey_malloc_record { | 677 | struct pkey_malloc_record { |
| 675 | void *ptr; | 678 | void *ptr; |
| 676 | long size; | 679 | long size; |
| 680 | int prot; | ||
| 677 | }; | 681 | }; |
| 678 | struct pkey_malloc_record *pkey_malloc_records; | 682 | struct pkey_malloc_record *pkey_malloc_records; |
| 683 | struct pkey_malloc_record *pkey_last_malloc_record; | ||
| 679 | long nr_pkey_malloc_records; | 684 | long nr_pkey_malloc_records; |
| 680 | void record_pkey_malloc(void *ptr, long size) | 685 | void record_pkey_malloc(void *ptr, long size, int prot) |
| 681 | { | 686 | { |
| 682 | long i; | 687 | long i; |
| 683 | struct pkey_malloc_record *rec = NULL; | 688 | struct pkey_malloc_record *rec = NULL; |
| @@ -709,6 +714,8 @@ void record_pkey_malloc(void *ptr, long size) | |||
| 709 | (int)(rec - pkey_malloc_records), rec, ptr, size); | 714 | (int)(rec - pkey_malloc_records), rec, ptr, size); |
| 710 | rec->ptr = ptr; | 715 | rec->ptr = ptr; |
| 711 | rec->size = size; | 716 | rec->size = size; |
| 717 | rec->prot = prot; | ||
| 718 | pkey_last_malloc_record = rec; | ||
| 712 | nr_pkey_malloc_records++; | 719 | nr_pkey_malloc_records++; |
| 713 | } | 720 | } |
| 714 | 721 | ||
| @@ -753,7 +760,7 @@ void *malloc_pkey_with_mprotect(long size, int prot, u16 pkey) | |||
| 753 | pkey_assert(ptr != (void *)-1); | 760 | pkey_assert(ptr != (void *)-1); |
| 754 | ret = mprotect_pkey((void *)ptr, PAGE_SIZE, prot, pkey); | 761 | ret = mprotect_pkey((void *)ptr, PAGE_SIZE, prot, pkey); |
| 755 | pkey_assert(!ret); | 762 | pkey_assert(!ret); |
| 756 | record_pkey_malloc(ptr, size); | 763 | record_pkey_malloc(ptr, size, prot); |
| 757 | rdpkru(); | 764 | rdpkru(); |
| 758 | 765 | ||
| 759 | dprintf1("%s() for pkey %d @ %p\n", __func__, pkey, ptr); | 766 | dprintf1("%s() for pkey %d @ %p\n", __func__, pkey, ptr); |
| @@ -774,7 +781,7 @@ void *malloc_pkey_anon_huge(long size, int prot, u16 pkey) | |||
| 774 | size = ALIGN_UP(size, HPAGE_SIZE * 2); | 781 | size = ALIGN_UP(size, HPAGE_SIZE * 2); |
| 775 | ptr = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); | 782 | ptr = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); |
| 776 | pkey_assert(ptr != (void *)-1); | 783 | pkey_assert(ptr != (void *)-1); |
| 777 | record_pkey_malloc(ptr, size); | 784 | record_pkey_malloc(ptr, size, prot); |
| 778 | mprotect_pkey(ptr, size, prot, pkey); | 785 | mprotect_pkey(ptr, size, prot, pkey); |
| 779 | 786 | ||
| 780 | dprintf1("unaligned ptr: %p\n", ptr); | 787 | dprintf1("unaligned ptr: %p\n", ptr); |
| @@ -847,7 +854,7 @@ void *malloc_pkey_hugetlb(long size, int prot, u16 pkey) | |||
| 847 | pkey_assert(ptr != (void *)-1); | 854 | pkey_assert(ptr != (void *)-1); |
| 848 | mprotect_pkey(ptr, size, prot, pkey); | 855 | mprotect_pkey(ptr, size, prot, pkey); |
| 849 | 856 | ||
| 850 | record_pkey_malloc(ptr, size); | 857 | record_pkey_malloc(ptr, size, prot); |
| 851 | 858 | ||
| 852 | dprintf1("mmap()'d hugetlbfs for pkey %d @ %p\n", pkey, ptr); | 859 | dprintf1("mmap()'d hugetlbfs for pkey %d @ %p\n", pkey, ptr); |
| 853 | return ptr; | 860 | return ptr; |
| @@ -869,7 +876,7 @@ void *malloc_pkey_mmap_dax(long size, int prot, u16 pkey) | |||
| 869 | 876 | ||
| 870 | mprotect_pkey(ptr, size, prot, pkey); | 877 | mprotect_pkey(ptr, size, prot, pkey); |
| 871 | 878 | ||
| 872 | record_pkey_malloc(ptr, size); | 879 | record_pkey_malloc(ptr, size, prot); |
| 873 | 880 | ||
| 874 | dprintf1("mmap()'d for pkey %d @ %p\n", pkey, ptr); | 881 | dprintf1("mmap()'d for pkey %d @ %p\n", pkey, ptr); |
| 875 | close(fd); | 882 | close(fd); |
| @@ -918,13 +925,21 @@ void *malloc_pkey(long size, int prot, u16 pkey) | |||
| 918 | } | 925 | } |
| 919 | 926 | ||
| 920 | int last_pkru_faults; | 927 | int last_pkru_faults; |
| 928 | #define UNKNOWN_PKEY -2 | ||
| 921 | void expected_pk_fault(int pkey) | 929 | void expected_pk_fault(int pkey) |
| 922 | { | 930 | { |
| 923 | dprintf2("%s(): last_pkru_faults: %d pkru_faults: %d\n", | 931 | dprintf2("%s(): last_pkru_faults: %d pkru_faults: %d\n", |
| 924 | __func__, last_pkru_faults, pkru_faults); | 932 | __func__, last_pkru_faults, pkru_faults); |
| 925 | dprintf2("%s(%d): last_si_pkey: %d\n", __func__, pkey, last_si_pkey); | 933 | dprintf2("%s(%d): last_si_pkey: %d\n", __func__, pkey, last_si_pkey); |
| 926 | pkey_assert(last_pkru_faults + 1 == pkru_faults); | 934 | pkey_assert(last_pkru_faults + 1 == pkru_faults); |
| 927 | pkey_assert(last_si_pkey == pkey); | 935 | |
| 936 | /* | ||
| 937 | * For exec-only memory, we do not know the pkey in | ||
| 938 | * advance, so skip this check. | ||
| 939 | */ | ||
| 940 | if (pkey != UNKNOWN_PKEY) | ||
| 941 | pkey_assert(last_si_pkey == pkey); | ||
| 942 | |||
| 928 | /* | 943 | /* |
| 929 | * The signal handler shold have cleared out PKRU to let the | 944 | * The signal handler shold have cleared out PKRU to let the |
| 930 | * test program continue. We now have to restore it. | 945 | * test program continue. We now have to restore it. |
| @@ -939,10 +954,11 @@ void expected_pk_fault(int pkey) | |||
| 939 | last_si_pkey = -1; | 954 | last_si_pkey = -1; |
| 940 | } | 955 | } |
| 941 | 956 | ||
| 942 | void do_not_expect_pk_fault(void) | 957 | #define do_not_expect_pk_fault(msg) do { \ |
| 943 | { | 958 | if (last_pkru_faults != pkru_faults) \ |
| 944 | pkey_assert(last_pkru_faults == pkru_faults); | 959 | dprintf0("unexpected PK fault: %s\n", msg); \ |
| 945 | } | 960 | pkey_assert(last_pkru_faults == pkru_faults); \ |
| 961 | } while (0) | ||
| 946 | 962 | ||
| 947 | int test_fds[10] = { -1 }; | 963 | int test_fds[10] = { -1 }; |
| 948 | int nr_test_fds; | 964 | int nr_test_fds; |
| @@ -1151,12 +1167,15 @@ void test_pkey_alloc_exhaust(int *ptr, u16 pkey) | |||
| 1151 | pkey_assert(i < NR_PKEYS*2); | 1167 | pkey_assert(i < NR_PKEYS*2); |
| 1152 | 1168 | ||
| 1153 | /* | 1169 | /* |
| 1154 | * There are 16 pkeys supported in hardware. One is taken | 1170 | * There are 16 pkeys supported in hardware. Three are |
| 1155 | * up for the default (0) and another can be taken up by | 1171 | * allocated by the time we get here: |
| 1156 | * an execute-only mapping. Ensure that we can allocate | 1172 | * 1. The default key (0) |
| 1157 | * at least 14 (16-2). | 1173 | * 2. One possibly consumed by an execute-only mapping. |
| 1174 | * 3. One allocated by the test code and passed in via | ||
| 1175 | * 'pkey' to this function. | ||
| 1176 | * Ensure that we can allocate at least another 13 (16-3). | ||
| 1158 | */ | 1177 | */ |
| 1159 | pkey_assert(i >= NR_PKEYS-2); | 1178 | pkey_assert(i >= NR_PKEYS-3); |
| 1160 | 1179 | ||
| 1161 | for (i = 0; i < nr_allocated_pkeys; i++) { | 1180 | for (i = 0; i < nr_allocated_pkeys; i++) { |
| 1162 | err = sys_pkey_free(allocated_pkeys[i]); | 1181 | err = sys_pkey_free(allocated_pkeys[i]); |
| @@ -1165,6 +1184,35 @@ void test_pkey_alloc_exhaust(int *ptr, u16 pkey) | |||
| 1165 | } | 1184 | } |
| 1166 | } | 1185 | } |
| 1167 | 1186 | ||
| 1187 | /* | ||
| 1188 | * pkey 0 is special. It is allocated by default, so you do not | ||
| 1189 | * have to call pkey_alloc() to use it first. Make sure that it | ||
| 1190 | * is usable. | ||
| 1191 | */ | ||
| 1192 | void test_mprotect_with_pkey_0(int *ptr, u16 pkey) | ||
| 1193 | { | ||
| 1194 | long size; | ||
| 1195 | int prot; | ||
| 1196 | |||
| 1197 | assert(pkey_last_malloc_record); | ||
| 1198 | size = pkey_last_malloc_record->size; | ||
| 1199 | /* | ||
| 1200 | * This is a bit of a hack. But mprotect() requires | ||
| 1201 | * huge-page-aligned sizes when operating on hugetlbfs. | ||
| 1202 | * So, make sure that we use something that's a multiple | ||
| 1203 | * of a huge page when we can. | ||
| 1204 | */ | ||
| 1205 | if (size >= HPAGE_SIZE) | ||
| 1206 | size = HPAGE_SIZE; | ||
| 1207 | prot = pkey_last_malloc_record->prot; | ||
| 1208 | |||
| 1209 | /* Use pkey 0 */ | ||
| 1210 | mprotect_pkey(ptr, size, prot, 0); | ||
| 1211 | |||
| 1212 | /* Make sure that we can set it back to the original pkey. */ | ||
| 1213 | mprotect_pkey(ptr, size, prot, pkey); | ||
| 1214 | } | ||
| 1215 | |||
| 1168 | void test_ptrace_of_child(int *ptr, u16 pkey) | 1216 | void test_ptrace_of_child(int *ptr, u16 pkey) |
| 1169 | { | 1217 | { |
| 1170 | __attribute__((__unused__)) int peek_result; | 1218 | __attribute__((__unused__)) int peek_result; |
| @@ -1228,7 +1276,7 @@ void test_ptrace_of_child(int *ptr, u16 pkey) | |||
| 1228 | pkey_assert(ret != -1); | 1276 | pkey_assert(ret != -1); |
| 1229 | /* Now access from the current task, and expect NO exception: */ | 1277 | /* Now access from the current task, and expect NO exception: */ |
| 1230 | peek_result = read_ptr(plain_ptr); | 1278 | peek_result = read_ptr(plain_ptr); |
| 1231 | do_not_expect_pk_fault(); | 1279 | do_not_expect_pk_fault("read plain pointer after ptrace"); |
| 1232 | 1280 | ||
| 1233 | ret = ptrace(PTRACE_DETACH, child_pid, ignored, 0); | 1281 | ret = ptrace(PTRACE_DETACH, child_pid, ignored, 0); |
| 1234 | pkey_assert(ret != -1); | 1282 | pkey_assert(ret != -1); |
| @@ -1241,12 +1289,9 @@ void test_ptrace_of_child(int *ptr, u16 pkey) | |||
| 1241 | free(plain_ptr_unaligned); | 1289 | free(plain_ptr_unaligned); |
| 1242 | } | 1290 | } |
| 1243 | 1291 | ||
| 1244 | void test_executing_on_unreadable_memory(int *ptr, u16 pkey) | 1292 | void *get_pointer_to_instructions(void) |
| 1245 | { | 1293 | { |
| 1246 | void *p1; | 1294 | void *p1; |
| 1247 | int scratch; | ||
| 1248 | int ptr_contents; | ||
| 1249 | int ret; | ||
| 1250 | 1295 | ||
| 1251 | p1 = ALIGN_PTR_UP(&lots_o_noops_around_write, PAGE_SIZE); | 1296 | p1 = ALIGN_PTR_UP(&lots_o_noops_around_write, PAGE_SIZE); |
| 1252 | dprintf3("&lots_o_noops: %p\n", &lots_o_noops_around_write); | 1297 | dprintf3("&lots_o_noops: %p\n", &lots_o_noops_around_write); |
| @@ -1256,7 +1301,23 @@ void test_executing_on_unreadable_memory(int *ptr, u16 pkey) | |||
| 1256 | /* Point 'p1' at the *second* page of the function: */ | 1301 | /* Point 'p1' at the *second* page of the function: */ |
| 1257 | p1 += PAGE_SIZE; | 1302 | p1 += PAGE_SIZE; |
| 1258 | 1303 | ||
| 1304 | /* | ||
| 1305 | * Try to ensure we fault this in on next touch to ensure | ||
| 1306 | * we get an instruction fault as opposed to a data one | ||
| 1307 | */ | ||
| 1259 | madvise(p1, PAGE_SIZE, MADV_DONTNEED); | 1308 | madvise(p1, PAGE_SIZE, MADV_DONTNEED); |
| 1309 | |||
| 1310 | return p1; | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | void test_executing_on_unreadable_memory(int *ptr, u16 pkey) | ||
| 1314 | { | ||
| 1315 | void *p1; | ||
| 1316 | int scratch; | ||
| 1317 | int ptr_contents; | ||
| 1318 | int ret; | ||
| 1319 | |||
| 1320 | p1 = get_pointer_to_instructions(); | ||
| 1260 | lots_o_noops_around_write(&scratch); | 1321 | lots_o_noops_around_write(&scratch); |
| 1261 | ptr_contents = read_ptr(p1); | 1322 | ptr_contents = read_ptr(p1); |
| 1262 | dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents); | 1323 | dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents); |
| @@ -1272,12 +1333,55 @@ void test_executing_on_unreadable_memory(int *ptr, u16 pkey) | |||
| 1272 | */ | 1333 | */ |
| 1273 | madvise(p1, PAGE_SIZE, MADV_DONTNEED); | 1334 | madvise(p1, PAGE_SIZE, MADV_DONTNEED); |
| 1274 | lots_o_noops_around_write(&scratch); | 1335 | lots_o_noops_around_write(&scratch); |
| 1275 | do_not_expect_pk_fault(); | 1336 | do_not_expect_pk_fault("executing on PROT_EXEC memory"); |
| 1276 | ptr_contents = read_ptr(p1); | 1337 | ptr_contents = read_ptr(p1); |
| 1277 | dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents); | 1338 | dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents); |
| 1278 | expected_pk_fault(pkey); | 1339 | expected_pk_fault(pkey); |
| 1279 | } | 1340 | } |
| 1280 | 1341 | ||
| 1342 | void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey) | ||
| 1343 | { | ||
| 1344 | void *p1; | ||
| 1345 | int scratch; | ||
| 1346 | int ptr_contents; | ||
| 1347 | int ret; | ||
| 1348 | |||
| 1349 | dprintf1("%s() start\n", __func__); | ||
| 1350 | |||
| 1351 | p1 = get_pointer_to_instructions(); | ||
| 1352 | lots_o_noops_around_write(&scratch); | ||
| 1353 | ptr_contents = read_ptr(p1); | ||
| 1354 | dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents); | ||
| 1355 | |||
| 1356 | /* Use a *normal* mprotect(), not mprotect_pkey(): */ | ||
| 1357 | ret = mprotect(p1, PAGE_SIZE, PROT_EXEC); | ||
| 1358 | pkey_assert(!ret); | ||
| 1359 | |||
| 1360 | dprintf2("pkru: %x\n", rdpkru()); | ||
| 1361 | |||
| 1362 | /* Make sure this is an *instruction* fault */ | ||
| 1363 | madvise(p1, PAGE_SIZE, MADV_DONTNEED); | ||
| 1364 | lots_o_noops_around_write(&scratch); | ||
| 1365 | do_not_expect_pk_fault("executing on PROT_EXEC memory"); | ||
| 1366 | ptr_contents = read_ptr(p1); | ||
| 1367 | dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents); | ||
| 1368 | expected_pk_fault(UNKNOWN_PKEY); | ||
| 1369 | |||
| 1370 | /* | ||
| 1371 | * Put the memory back to non-PROT_EXEC. Should clear the | ||
| 1372 | * exec-only pkey off the VMA and allow it to be readable | ||
| 1373 | * again. Go to PROT_NONE first to check for a kernel bug | ||
| 1374 | * that did not clear the pkey when doing PROT_NONE. | ||
| 1375 | */ | ||
| 1376 | ret = mprotect(p1, PAGE_SIZE, PROT_NONE); | ||
| 1377 | pkey_assert(!ret); | ||
| 1378 | |||
| 1379 | ret = mprotect(p1, PAGE_SIZE, PROT_READ|PROT_EXEC); | ||
| 1380 | pkey_assert(!ret); | ||
| 1381 | ptr_contents = read_ptr(p1); | ||
| 1382 | do_not_expect_pk_fault("plain read on recently PROT_EXEC area"); | ||
| 1383 | } | ||
| 1384 | |||
| 1281 | void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey) | 1385 | void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey) |
| 1282 | { | 1386 | { |
| 1283 | int size = PAGE_SIZE; | 1387 | int size = PAGE_SIZE; |
| @@ -1302,6 +1406,8 @@ void (*pkey_tests[])(int *ptr, u16 pkey) = { | |||
| 1302 | test_kernel_gup_of_access_disabled_region, | 1406 | test_kernel_gup_of_access_disabled_region, |
| 1303 | test_kernel_gup_write_to_write_disabled_region, | 1407 | test_kernel_gup_write_to_write_disabled_region, |
| 1304 | test_executing_on_unreadable_memory, | 1408 | test_executing_on_unreadable_memory, |
| 1409 | test_implicit_mprotect_exec_only_memory, | ||
| 1410 | test_mprotect_with_pkey_0, | ||
| 1305 | test_ptrace_of_child, | 1411 | test_ptrace_of_child, |
| 1306 | test_pkey_syscalls_on_non_allocated_pkey, | 1412 | test_pkey_syscalls_on_non_allocated_pkey, |
| 1307 | test_pkey_syscalls_bad_args, | 1413 | test_pkey_syscalls_bad_args, |
diff --git a/virt/kvm/arm/vgic/vgic-debug.c b/virt/kvm/arm/vgic/vgic-debug.c index 10b38178cff2..4ffc0b5e6105 100644 --- a/virt/kvm/arm/vgic/vgic-debug.c +++ b/virt/kvm/arm/vgic/vgic-debug.c | |||
| @@ -211,6 +211,7 @@ static int vgic_debug_show(struct seq_file *s, void *v) | |||
| 211 | struct vgic_state_iter *iter = (struct vgic_state_iter *)v; | 211 | struct vgic_state_iter *iter = (struct vgic_state_iter *)v; |
| 212 | struct vgic_irq *irq; | 212 | struct vgic_irq *irq; |
| 213 | struct kvm_vcpu *vcpu = NULL; | 213 | struct kvm_vcpu *vcpu = NULL; |
| 214 | unsigned long flags; | ||
| 214 | 215 | ||
| 215 | if (iter->dist_id == 0) { | 216 | if (iter->dist_id == 0) { |
| 216 | print_dist_state(s, &kvm->arch.vgic); | 217 | print_dist_state(s, &kvm->arch.vgic); |
| @@ -227,9 +228,9 @@ static int vgic_debug_show(struct seq_file *s, void *v) | |||
| 227 | irq = &kvm->arch.vgic.spis[iter->intid - VGIC_NR_PRIVATE_IRQS]; | 228 | irq = &kvm->arch.vgic.spis[iter->intid - VGIC_NR_PRIVATE_IRQS]; |
| 228 | } | 229 | } |
| 229 | 230 | ||
| 230 | spin_lock(&irq->irq_lock); | 231 | spin_lock_irqsave(&irq->irq_lock, flags); |
| 231 | print_irq_state(s, irq, vcpu); | 232 | print_irq_state(s, irq, vcpu); |
| 232 | spin_unlock(&irq->irq_lock); | 233 | spin_unlock_irqrestore(&irq->irq_lock, flags); |
| 233 | 234 | ||
| 234 | return 0; | 235 | return 0; |
| 235 | } | 236 | } |
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c index 68378fe17a0e..e07156c30323 100644 --- a/virt/kvm/arm/vgic/vgic-init.c +++ b/virt/kvm/arm/vgic/vgic-init.c | |||
| @@ -423,7 +423,7 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data) | |||
| 423 | * We cannot rely on the vgic maintenance interrupt to be | 423 | * We cannot rely on the vgic maintenance interrupt to be |
| 424 | * delivered synchronously. This means we can only use it to | 424 | * delivered synchronously. This means we can only use it to |
| 425 | * exit the VM, and we perform the handling of EOIed | 425 | * exit the VM, and we perform the handling of EOIed |
| 426 | * interrupts on the exit path (see vgic_process_maintenance). | 426 | * interrupts on the exit path (see vgic_fold_lr_state). |
| 427 | */ | 427 | */ |
| 428 | return IRQ_HANDLED; | 428 | return IRQ_HANDLED; |
| 429 | } | 429 | } |
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c index a8f07243aa9f..4ed79c939fb4 100644 --- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c | |||
| @@ -52,6 +52,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, | |||
| 52 | { | 52 | { |
| 53 | struct vgic_dist *dist = &kvm->arch.vgic; | 53 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 54 | struct vgic_irq *irq = vgic_get_irq(kvm, NULL, intid), *oldirq; | 54 | struct vgic_irq *irq = vgic_get_irq(kvm, NULL, intid), *oldirq; |
| 55 | unsigned long flags; | ||
| 55 | int ret; | 56 | int ret; |
| 56 | 57 | ||
| 57 | /* In this case there is no put, since we keep the reference. */ | 58 | /* In this case there is no put, since we keep the reference. */ |
| @@ -71,7 +72,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, | |||
| 71 | irq->intid = intid; | 72 | irq->intid = intid; |
| 72 | irq->target_vcpu = vcpu; | 73 | irq->target_vcpu = vcpu; |
| 73 | 74 | ||
| 74 | spin_lock(&dist->lpi_list_lock); | 75 | spin_lock_irqsave(&dist->lpi_list_lock, flags); |
| 75 | 76 | ||
| 76 | /* | 77 | /* |
| 77 | * There could be a race with another vgic_add_lpi(), so we need to | 78 | * There could be a race with another vgic_add_lpi(), so we need to |
| @@ -99,7 +100,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, | |||
| 99 | dist->lpi_list_count++; | 100 | dist->lpi_list_count++; |
| 100 | 101 | ||
| 101 | out_unlock: | 102 | out_unlock: |
| 102 | spin_unlock(&dist->lpi_list_lock); | 103 | spin_unlock_irqrestore(&dist->lpi_list_lock, flags); |
| 103 | 104 | ||
| 104 | /* | 105 | /* |
| 105 | * We "cache" the configuration table entries in our struct vgic_irq's. | 106 | * We "cache" the configuration table entries in our struct vgic_irq's. |
| @@ -280,8 +281,8 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq, | |||
| 280 | int ret; | 281 | int ret; |
| 281 | unsigned long flags; | 282 | unsigned long flags; |
| 282 | 283 | ||
| 283 | ret = kvm_read_guest(kvm, propbase + irq->intid - GIC_LPI_OFFSET, | 284 | ret = kvm_read_guest_lock(kvm, propbase + irq->intid - GIC_LPI_OFFSET, |
| 284 | &prop, 1); | 285 | &prop, 1); |
| 285 | 286 | ||
| 286 | if (ret) | 287 | if (ret) |
| 287 | return ret; | 288 | return ret; |
| @@ -315,6 +316,7 @@ static int vgic_copy_lpi_list(struct kvm_vcpu *vcpu, u32 **intid_ptr) | |||
| 315 | { | 316 | { |
| 316 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; | 317 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; |
| 317 | struct vgic_irq *irq; | 318 | struct vgic_irq *irq; |
| 319 | unsigned long flags; | ||
| 318 | u32 *intids; | 320 | u32 *intids; |
| 319 | int irq_count, i = 0; | 321 | int irq_count, i = 0; |
| 320 | 322 | ||
| @@ -330,7 +332,7 @@ static int vgic_copy_lpi_list(struct kvm_vcpu *vcpu, u32 **intid_ptr) | |||
| 330 | if (!intids) | 332 | if (!intids) |
| 331 | return -ENOMEM; | 333 | return -ENOMEM; |
| 332 | 334 | ||
| 333 | spin_lock(&dist->lpi_list_lock); | 335 | spin_lock_irqsave(&dist->lpi_list_lock, flags); |
| 334 | list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { | 336 | list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { |
| 335 | if (i == irq_count) | 337 | if (i == irq_count) |
| 336 | break; | 338 | break; |
| @@ -339,7 +341,7 @@ static int vgic_copy_lpi_list(struct kvm_vcpu *vcpu, u32 **intid_ptr) | |||
| 339 | continue; | 341 | continue; |
| 340 | intids[i++] = irq->intid; | 342 | intids[i++] = irq->intid; |
| 341 | } | 343 | } |
| 342 | spin_unlock(&dist->lpi_list_lock); | 344 | spin_unlock_irqrestore(&dist->lpi_list_lock, flags); |
| 343 | 345 | ||
| 344 | *intid_ptr = intids; | 346 | *intid_ptr = intids; |
| 345 | return i; | 347 | return i; |
| @@ -348,10 +350,11 @@ static int vgic_copy_lpi_list(struct kvm_vcpu *vcpu, u32 **intid_ptr) | |||
| 348 | static int update_affinity(struct vgic_irq *irq, struct kvm_vcpu *vcpu) | 350 | static int update_affinity(struct vgic_irq *irq, struct kvm_vcpu *vcpu) |
| 349 | { | 351 | { |
| 350 | int ret = 0; | 352 | int ret = 0; |
| 353 | unsigned long flags; | ||
| 351 | 354 | ||
| 352 | spin_lock(&irq->irq_lock); | 355 | spin_lock_irqsave(&irq->irq_lock, flags); |
| 353 | irq->target_vcpu = vcpu; | 356 | irq->target_vcpu = vcpu; |
| 354 | spin_unlock(&irq->irq_lock); | 357 | spin_unlock_irqrestore(&irq->irq_lock, flags); |
| 355 | 358 | ||
| 356 | if (irq->hw) { | 359 | if (irq->hw) { |
| 357 | struct its_vlpi_map map; | 360 | struct its_vlpi_map map; |
| @@ -441,8 +444,9 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu) | |||
| 441 | * this very same byte in the last iteration. Reuse that. | 444 | * this very same byte in the last iteration. Reuse that. |
| 442 | */ | 445 | */ |
| 443 | if (byte_offset != last_byte_offset) { | 446 | if (byte_offset != last_byte_offset) { |
| 444 | ret = kvm_read_guest(vcpu->kvm, pendbase + byte_offset, | 447 | ret = kvm_read_guest_lock(vcpu->kvm, |
| 445 | &pendmask, 1); | 448 | pendbase + byte_offset, |
| 449 | &pendmask, 1); | ||
| 446 | if (ret) { | 450 | if (ret) { |
| 447 | kfree(intids); | 451 | kfree(intids); |
| 448 | return ret; | 452 | return ret; |
| @@ -786,7 +790,7 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, u32 id, | |||
| 786 | return false; | 790 | return false; |
| 787 | 791 | ||
| 788 | /* Each 1st level entry is represented by a 64-bit value. */ | 792 | /* Each 1st level entry is represented by a 64-bit value. */ |
| 789 | if (kvm_read_guest(its->dev->kvm, | 793 | if (kvm_read_guest_lock(its->dev->kvm, |
| 790 | BASER_ADDRESS(baser) + index * sizeof(indirect_ptr), | 794 | BASER_ADDRESS(baser) + index * sizeof(indirect_ptr), |
| 791 | &indirect_ptr, sizeof(indirect_ptr))) | 795 | &indirect_ptr, sizeof(indirect_ptr))) |
| 792 | return false; | 796 | return false; |
| @@ -1367,8 +1371,8 @@ static void vgic_its_process_commands(struct kvm *kvm, struct vgic_its *its) | |||
| 1367 | cbaser = CBASER_ADDRESS(its->cbaser); | 1371 | cbaser = CBASER_ADDRESS(its->cbaser); |
| 1368 | 1372 | ||
| 1369 | while (its->cwriter != its->creadr) { | 1373 | while (its->cwriter != its->creadr) { |
| 1370 | int ret = kvm_read_guest(kvm, cbaser + its->creadr, | 1374 | int ret = kvm_read_guest_lock(kvm, cbaser + its->creadr, |
| 1371 | cmd_buf, ITS_CMD_SIZE); | 1375 | cmd_buf, ITS_CMD_SIZE); |
| 1372 | /* | 1376 | /* |
| 1373 | * If kvm_read_guest() fails, this could be due to the guest | 1377 | * If kvm_read_guest() fails, this could be due to the guest |
| 1374 | * programming a bogus value in CBASER or something else going | 1378 | * programming a bogus value in CBASER or something else going |
| @@ -1893,7 +1897,7 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, int esz, | |||
| 1893 | int next_offset; | 1897 | int next_offset; |
| 1894 | size_t byte_offset; | 1898 | size_t byte_offset; |
| 1895 | 1899 | ||
| 1896 | ret = kvm_read_guest(kvm, gpa, entry, esz); | 1900 | ret = kvm_read_guest_lock(kvm, gpa, entry, esz); |
| 1897 | if (ret) | 1901 | if (ret) |
| 1898 | return ret; | 1902 | return ret; |
| 1899 | 1903 | ||
| @@ -2263,7 +2267,7 @@ static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz) | |||
| 2263 | int ret; | 2267 | int ret; |
| 2264 | 2268 | ||
| 2265 | BUG_ON(esz > sizeof(val)); | 2269 | BUG_ON(esz > sizeof(val)); |
| 2266 | ret = kvm_read_guest(kvm, gpa, &val, esz); | 2270 | ret = kvm_read_guest_lock(kvm, gpa, &val, esz); |
| 2267 | if (ret) | 2271 | if (ret) |
| 2268 | return ret; | 2272 | return ret; |
| 2269 | val = le64_to_cpu(val); | 2273 | val = le64_to_cpu(val); |
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c index dbe99d635c80..ff9655cfeb2f 100644 --- a/virt/kvm/arm/vgic/vgic-mmio.c +++ b/virt/kvm/arm/vgic/vgic-mmio.c | |||
| @@ -289,10 +289,16 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq, | |||
| 289 | irq->vcpu->cpu != -1) /* VCPU thread is running */ | 289 | irq->vcpu->cpu != -1) /* VCPU thread is running */ |
| 290 | cond_resched_lock(&irq->irq_lock); | 290 | cond_resched_lock(&irq->irq_lock); |
| 291 | 291 | ||
| 292 | if (irq->hw) | 292 | if (irq->hw) { |
| 293 | vgic_hw_irq_change_active(vcpu, irq, active, !requester_vcpu); | 293 | vgic_hw_irq_change_active(vcpu, irq, active, !requester_vcpu); |
| 294 | else | 294 | } else { |
| 295 | u32 model = vcpu->kvm->arch.vgic.vgic_model; | ||
| 296 | |||
| 295 | irq->active = active; | 297 | irq->active = active; |
| 298 | if (model == KVM_DEV_TYPE_ARM_VGIC_V2 && | ||
| 299 | active && vgic_irq_is_sgi(irq->intid)) | ||
| 300 | irq->active_source = requester_vcpu->vcpu_id; | ||
| 301 | } | ||
| 296 | 302 | ||
| 297 | if (irq->active) | 303 | if (irq->active) |
| 298 | vgic_queue_irq_unlock(vcpu->kvm, irq, flags); | 304 | vgic_queue_irq_unlock(vcpu->kvm, irq, flags); |
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c index 45aa433f018f..a5f2e44f1c33 100644 --- a/virt/kvm/arm/vgic/vgic-v2.c +++ b/virt/kvm/arm/vgic/vgic-v2.c | |||
| @@ -37,13 +37,6 @@ void vgic_v2_init_lrs(void) | |||
| 37 | vgic_v2_write_lr(i, 0); | 37 | vgic_v2_write_lr(i, 0); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | void vgic_v2_set_npie(struct kvm_vcpu *vcpu) | ||
| 41 | { | ||
| 42 | struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2; | ||
| 43 | |||
| 44 | cpuif->vgic_hcr |= GICH_HCR_NPIE; | ||
| 45 | } | ||
| 46 | |||
| 47 | void vgic_v2_set_underflow(struct kvm_vcpu *vcpu) | 40 | void vgic_v2_set_underflow(struct kvm_vcpu *vcpu) |
| 48 | { | 41 | { |
| 49 | struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2; | 42 | struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2; |
| @@ -71,13 +64,18 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) | |||
| 71 | int lr; | 64 | int lr; |
| 72 | unsigned long flags; | 65 | unsigned long flags; |
| 73 | 66 | ||
| 74 | cpuif->vgic_hcr &= ~(GICH_HCR_UIE | GICH_HCR_NPIE); | 67 | cpuif->vgic_hcr &= ~GICH_HCR_UIE; |
| 75 | 68 | ||
| 76 | for (lr = 0; lr < vgic_cpu->used_lrs; lr++) { | 69 | for (lr = 0; lr < vgic_cpu->used_lrs; lr++) { |
| 77 | u32 val = cpuif->vgic_lr[lr]; | 70 | u32 val = cpuif->vgic_lr[lr]; |
| 78 | u32 intid = val & GICH_LR_VIRTUALID; | 71 | u32 cpuid, intid = val & GICH_LR_VIRTUALID; |
| 79 | struct vgic_irq *irq; | 72 | struct vgic_irq *irq; |
| 80 | 73 | ||
| 74 | /* Extract the source vCPU id from the LR */ | ||
| 75 | cpuid = val & GICH_LR_PHYSID_CPUID; | ||
| 76 | cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; | ||
| 77 | cpuid &= 7; | ||
| 78 | |||
| 81 | /* Notify fds when the guest EOI'ed a level-triggered SPI */ | 79 | /* Notify fds when the guest EOI'ed a level-triggered SPI */ |
| 82 | if (lr_signals_eoi_mi(val) && vgic_valid_spi(vcpu->kvm, intid)) | 80 | if (lr_signals_eoi_mi(val) && vgic_valid_spi(vcpu->kvm, intid)) |
| 83 | kvm_notify_acked_irq(vcpu->kvm, 0, | 81 | kvm_notify_acked_irq(vcpu->kvm, 0, |
| @@ -90,17 +88,16 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) | |||
| 90 | /* Always preserve the active bit */ | 88 | /* Always preserve the active bit */ |
| 91 | irq->active = !!(val & GICH_LR_ACTIVE_BIT); | 89 | irq->active = !!(val & GICH_LR_ACTIVE_BIT); |
| 92 | 90 | ||
| 91 | if (irq->active && vgic_irq_is_sgi(intid)) | ||
| 92 | irq->active_source = cpuid; | ||
| 93 | |||
| 93 | /* Edge is the only case where we preserve the pending bit */ | 94 | /* Edge is the only case where we preserve the pending bit */ |
| 94 | if (irq->config == VGIC_CONFIG_EDGE && | 95 | if (irq->config == VGIC_CONFIG_EDGE && |
| 95 | (val & GICH_LR_PENDING_BIT)) { | 96 | (val & GICH_LR_PENDING_BIT)) { |
| 96 | irq->pending_latch = true; | 97 | irq->pending_latch = true; |
| 97 | 98 | ||
| 98 | if (vgic_irq_is_sgi(intid)) { | 99 | if (vgic_irq_is_sgi(intid)) |
| 99 | u32 cpuid = val & GICH_LR_PHYSID_CPUID; | ||
| 100 | |||
| 101 | cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; | ||
| 102 | irq->source |= (1 << cpuid); | 100 | irq->source |= (1 << cpuid); |
| 103 | } | ||
| 104 | } | 101 | } |
| 105 | 102 | ||
| 106 | /* | 103 | /* |
| @@ -152,8 +149,15 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) | |||
| 152 | u32 val = irq->intid; | 149 | u32 val = irq->intid; |
| 153 | bool allow_pending = true; | 150 | bool allow_pending = true; |
| 154 | 151 | ||
| 155 | if (irq->active) | 152 | if (irq->active) { |
| 156 | val |= GICH_LR_ACTIVE_BIT; | 153 | val |= GICH_LR_ACTIVE_BIT; |
| 154 | if (vgic_irq_is_sgi(irq->intid)) | ||
| 155 | val |= irq->active_source << GICH_LR_PHYSID_CPUID_SHIFT; | ||
| 156 | if (vgic_irq_is_multi_sgi(irq)) { | ||
| 157 | allow_pending = false; | ||
| 158 | val |= GICH_LR_EOI; | ||
| 159 | } | ||
| 160 | } | ||
| 157 | 161 | ||
| 158 | if (irq->hw) { | 162 | if (irq->hw) { |
| 159 | val |= GICH_LR_HW; | 163 | val |= GICH_LR_HW; |
| @@ -190,8 +194,10 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) | |||
| 190 | BUG_ON(!src); | 194 | BUG_ON(!src); |
| 191 | val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; | 195 | val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; |
| 192 | irq->source &= ~(1 << (src - 1)); | 196 | irq->source &= ~(1 << (src - 1)); |
| 193 | if (irq->source) | 197 | if (irq->source) { |
| 194 | irq->pending_latch = true; | 198 | irq->pending_latch = true; |
| 199 | val |= GICH_LR_EOI; | ||
| 200 | } | ||
| 195 | } | 201 | } |
| 196 | } | 202 | } |
| 197 | 203 | ||
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c index 8195f52ae6f0..bdcf8e7a6161 100644 --- a/virt/kvm/arm/vgic/vgic-v3.c +++ b/virt/kvm/arm/vgic/vgic-v3.c | |||
| @@ -27,13 +27,6 @@ static bool group1_trap; | |||
| 27 | static bool common_trap; | 27 | static bool common_trap; |
| 28 | static bool gicv4_enable; | 28 | static bool gicv4_enable; |
| 29 | 29 | ||
| 30 | void vgic_v3_set_npie(struct kvm_vcpu *vcpu) | ||
| 31 | { | ||
| 32 | struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3; | ||
| 33 | |||
| 34 | cpuif->vgic_hcr |= ICH_HCR_NPIE; | ||
| 35 | } | ||
| 36 | |||
| 37 | void vgic_v3_set_underflow(struct kvm_vcpu *vcpu) | 30 | void vgic_v3_set_underflow(struct kvm_vcpu *vcpu) |
| 38 | { | 31 | { |
| 39 | struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3; | 32 | struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3; |
| @@ -55,17 +48,23 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) | |||
| 55 | int lr; | 48 | int lr; |
| 56 | unsigned long flags; | 49 | unsigned long flags; |
| 57 | 50 | ||
| 58 | cpuif->vgic_hcr &= ~(ICH_HCR_UIE | ICH_HCR_NPIE); | 51 | cpuif->vgic_hcr &= ~ICH_HCR_UIE; |
| 59 | 52 | ||
| 60 | for (lr = 0; lr < vgic_cpu->used_lrs; lr++) { | 53 | for (lr = 0; lr < vgic_cpu->used_lrs; lr++) { |
| 61 | u64 val = cpuif->vgic_lr[lr]; | 54 | u64 val = cpuif->vgic_lr[lr]; |
| 62 | u32 intid; | 55 | u32 intid, cpuid; |
| 63 | struct vgic_irq *irq; | 56 | struct vgic_irq *irq; |
| 57 | bool is_v2_sgi = false; | ||
| 64 | 58 | ||
| 65 | if (model == KVM_DEV_TYPE_ARM_VGIC_V3) | 59 | cpuid = val & GICH_LR_PHYSID_CPUID; |
| 60 | cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; | ||
| 61 | |||
| 62 | if (model == KVM_DEV_TYPE_ARM_VGIC_V3) { | ||
| 66 | intid = val & ICH_LR_VIRTUAL_ID_MASK; | 63 | intid = val & ICH_LR_VIRTUAL_ID_MASK; |
| 67 | else | 64 | } else { |
| 68 | intid = val & GICH_LR_VIRTUALID; | 65 | intid = val & GICH_LR_VIRTUALID; |
| 66 | is_v2_sgi = vgic_irq_is_sgi(intid); | ||
| 67 | } | ||
| 69 | 68 | ||
| 70 | /* Notify fds when the guest EOI'ed a level-triggered IRQ */ | 69 | /* Notify fds when the guest EOI'ed a level-triggered IRQ */ |
| 71 | if (lr_signals_eoi_mi(val) && vgic_valid_spi(vcpu->kvm, intid)) | 70 | if (lr_signals_eoi_mi(val) && vgic_valid_spi(vcpu->kvm, intid)) |
| @@ -81,18 +80,16 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) | |||
| 81 | /* Always preserve the active bit */ | 80 | /* Always preserve the active bit */ |
| 82 | irq->active = !!(val & ICH_LR_ACTIVE_BIT); | 81 | irq->active = !!(val & ICH_LR_ACTIVE_BIT); |
| 83 | 82 | ||
| 83 | if (irq->active && is_v2_sgi) | ||
| 84 | irq->active_source = cpuid; | ||
| 85 | |||
| 84 | /* Edge is the only case where we preserve the pending bit */ | 86 | /* Edge is the only case where we preserve the pending bit */ |
| 85 | if (irq->config == VGIC_CONFIG_EDGE && | 87 | if (irq->config == VGIC_CONFIG_EDGE && |
| 86 | (val & ICH_LR_PENDING_BIT)) { | 88 | (val & ICH_LR_PENDING_BIT)) { |
| 87 | irq->pending_latch = true; | 89 | irq->pending_latch = true; |
| 88 | 90 | ||
| 89 | if (vgic_irq_is_sgi(intid) && | 91 | if (is_v2_sgi) |
| 90 | model == KVM_DEV_TYPE_ARM_VGIC_V2) { | ||
| 91 | u32 cpuid = val & GICH_LR_PHYSID_CPUID; | ||
| 92 | |||
| 93 | cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; | ||
| 94 | irq->source |= (1 << cpuid); | 92 | irq->source |= (1 << cpuid); |
| 95 | } | ||
| 96 | } | 93 | } |
| 97 | 94 | ||
| 98 | /* | 95 | /* |
| @@ -133,10 +130,20 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) | |||
| 133 | { | 130 | { |
| 134 | u32 model = vcpu->kvm->arch.vgic.vgic_model; | 131 | u32 model = vcpu->kvm->arch.vgic.vgic_model; |
| 135 | u64 val = irq->intid; | 132 | u64 val = irq->intid; |
| 136 | bool allow_pending = true; | 133 | bool allow_pending = true, is_v2_sgi; |
| 137 | 134 | ||
| 138 | if (irq->active) | 135 | is_v2_sgi = (vgic_irq_is_sgi(irq->intid) && |
| 136 | model == KVM_DEV_TYPE_ARM_VGIC_V2); | ||
| 137 | |||
| 138 | if (irq->active) { | ||
| 139 | val |= ICH_LR_ACTIVE_BIT; | 139 | val |= ICH_LR_ACTIVE_BIT; |
| 140 | if (is_v2_sgi) | ||
| 141 | val |= irq->active_source << GICH_LR_PHYSID_CPUID_SHIFT; | ||
| 142 | if (vgic_irq_is_multi_sgi(irq)) { | ||
| 143 | allow_pending = false; | ||
| 144 | val |= ICH_LR_EOI; | ||
| 145 | } | ||
| 146 | } | ||
| 140 | 147 | ||
| 141 | if (irq->hw) { | 148 | if (irq->hw) { |
| 142 | val |= ICH_LR_HW; | 149 | val |= ICH_LR_HW; |
| @@ -174,8 +181,10 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) | |||
| 174 | BUG_ON(!src); | 181 | BUG_ON(!src); |
| 175 | val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; | 182 | val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; |
| 176 | irq->source &= ~(1 << (src - 1)); | 183 | irq->source &= ~(1 << (src - 1)); |
| 177 | if (irq->source) | 184 | if (irq->source) { |
| 178 | irq->pending_latch = true; | 185 | irq->pending_latch = true; |
| 186 | val |= ICH_LR_EOI; | ||
| 187 | } | ||
| 179 | } | 188 | } |
| 180 | } | 189 | } |
| 181 | 190 | ||
| @@ -335,7 +344,7 @@ retry: | |||
| 335 | bit_nr = irq->intid % BITS_PER_BYTE; | 344 | bit_nr = irq->intid % BITS_PER_BYTE; |
| 336 | ptr = pendbase + byte_offset; | 345 | ptr = pendbase + byte_offset; |
| 337 | 346 | ||
| 338 | ret = kvm_read_guest(kvm, ptr, &val, 1); | 347 | ret = kvm_read_guest_lock(kvm, ptr, &val, 1); |
| 339 | if (ret) | 348 | if (ret) |
| 340 | return ret; | 349 | return ret; |
| 341 | 350 | ||
| @@ -388,7 +397,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) | |||
| 388 | ptr = pendbase + byte_offset; | 397 | ptr = pendbase + byte_offset; |
| 389 | 398 | ||
| 390 | if (byte_offset != last_byte_offset) { | 399 | if (byte_offset != last_byte_offset) { |
| 391 | ret = kvm_read_guest(kvm, ptr, &val, 1); | 400 | ret = kvm_read_guest_lock(kvm, ptr, &val, 1); |
| 392 | if (ret) | 401 | if (ret) |
| 393 | return ret; | 402 | return ret; |
| 394 | last_byte_offset = byte_offset; | 403 | last_byte_offset = byte_offset; |
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index 702936cbe173..33c8325c8f35 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c | |||
| @@ -43,9 +43,13 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = { | |||
| 43 | * kvm->lock (mutex) | 43 | * kvm->lock (mutex) |
| 44 | * its->cmd_lock (mutex) | 44 | * its->cmd_lock (mutex) |
| 45 | * its->its_lock (mutex) | 45 | * its->its_lock (mutex) |
| 46 | * vgic_cpu->ap_list_lock | 46 | * vgic_cpu->ap_list_lock must be taken with IRQs disabled |
| 47 | * kvm->lpi_list_lock | 47 | * kvm->lpi_list_lock must be taken with IRQs disabled |
| 48 | * vgic_irq->irq_lock | 48 | * vgic_irq->irq_lock must be taken with IRQs disabled |
| 49 | * | ||
| 50 | * As the ap_list_lock might be taken from the timer interrupt handler, | ||
| 51 | * we have to disable IRQs before taking this lock and everything lower | ||
| 52 | * than it. | ||
| 49 | * | 53 | * |
| 50 | * If you need to take multiple locks, always take the upper lock first, | 54 | * If you need to take multiple locks, always take the upper lock first, |
| 51 | * then the lower ones, e.g. first take the its_lock, then the irq_lock. | 55 | * then the lower ones, e.g. first take the its_lock, then the irq_lock. |
| @@ -72,8 +76,9 @@ static struct vgic_irq *vgic_get_lpi(struct kvm *kvm, u32 intid) | |||
| 72 | { | 76 | { |
| 73 | struct vgic_dist *dist = &kvm->arch.vgic; | 77 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 74 | struct vgic_irq *irq = NULL; | 78 | struct vgic_irq *irq = NULL; |
| 79 | unsigned long flags; | ||
| 75 | 80 | ||
| 76 | spin_lock(&dist->lpi_list_lock); | 81 | spin_lock_irqsave(&dist->lpi_list_lock, flags); |
| 77 | 82 | ||
| 78 | list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { | 83 | list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { |
| 79 | if (irq->intid != intid) | 84 | if (irq->intid != intid) |
| @@ -89,7 +94,7 @@ static struct vgic_irq *vgic_get_lpi(struct kvm *kvm, u32 intid) | |||
| 89 | irq = NULL; | 94 | irq = NULL; |
| 90 | 95 | ||
| 91 | out_unlock: | 96 | out_unlock: |
| 92 | spin_unlock(&dist->lpi_list_lock); | 97 | spin_unlock_irqrestore(&dist->lpi_list_lock, flags); |
| 93 | 98 | ||
| 94 | return irq; | 99 | return irq; |
| 95 | } | 100 | } |
| @@ -134,19 +139,20 @@ static void vgic_irq_release(struct kref *ref) | |||
| 134 | void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) | 139 | void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) |
| 135 | { | 140 | { |
| 136 | struct vgic_dist *dist = &kvm->arch.vgic; | 141 | struct vgic_dist *dist = &kvm->arch.vgic; |
| 142 | unsigned long flags; | ||
| 137 | 143 | ||
| 138 | if (irq->intid < VGIC_MIN_LPI) | 144 | if (irq->intid < VGIC_MIN_LPI) |
| 139 | return; | 145 | return; |
| 140 | 146 | ||
| 141 | spin_lock(&dist->lpi_list_lock); | 147 | spin_lock_irqsave(&dist->lpi_list_lock, flags); |
| 142 | if (!kref_put(&irq->refcount, vgic_irq_release)) { | 148 | if (!kref_put(&irq->refcount, vgic_irq_release)) { |
| 143 | spin_unlock(&dist->lpi_list_lock); | 149 | spin_unlock_irqrestore(&dist->lpi_list_lock, flags); |
| 144 | return; | 150 | return; |
| 145 | }; | 151 | }; |
| 146 | 152 | ||
| 147 | list_del(&irq->lpi_list); | 153 | list_del(&irq->lpi_list); |
| 148 | dist->lpi_list_count--; | 154 | dist->lpi_list_count--; |
| 149 | spin_unlock(&dist->lpi_list_lock); | 155 | spin_unlock_irqrestore(&dist->lpi_list_lock, flags); |
| 150 | 156 | ||
| 151 | kfree(irq); | 157 | kfree(irq); |
| 152 | } | 158 | } |
| @@ -725,14 +731,6 @@ static inline void vgic_set_underflow(struct kvm_vcpu *vcpu) | |||
| 725 | vgic_v3_set_underflow(vcpu); | 731 | vgic_v3_set_underflow(vcpu); |
| 726 | } | 732 | } |
| 727 | 733 | ||
| 728 | static inline void vgic_set_npie(struct kvm_vcpu *vcpu) | ||
| 729 | { | ||
| 730 | if (kvm_vgic_global_state.type == VGIC_V2) | ||
| 731 | vgic_v2_set_npie(vcpu); | ||
| 732 | else | ||
| 733 | vgic_v3_set_npie(vcpu); | ||
| 734 | } | ||
| 735 | |||
| 736 | /* Requires the ap_list_lock to be held. */ | 734 | /* Requires the ap_list_lock to be held. */ |
| 737 | static int compute_ap_list_depth(struct kvm_vcpu *vcpu, | 735 | static int compute_ap_list_depth(struct kvm_vcpu *vcpu, |
| 738 | bool *multi_sgi) | 736 | bool *multi_sgi) |
| @@ -746,17 +744,15 @@ static int compute_ap_list_depth(struct kvm_vcpu *vcpu, | |||
| 746 | DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock)); | 744 | DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock)); |
| 747 | 745 | ||
| 748 | list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { | 746 | list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { |
| 747 | int w; | ||
| 748 | |||
| 749 | spin_lock(&irq->irq_lock); | 749 | spin_lock(&irq->irq_lock); |
| 750 | /* GICv2 SGIs can count for more than one... */ | 750 | /* GICv2 SGIs can count for more than one... */ |
| 751 | if (vgic_irq_is_sgi(irq->intid) && irq->source) { | 751 | w = vgic_irq_get_lr_count(irq); |
| 752 | int w = hweight8(irq->source); | ||
| 753 | |||
| 754 | count += w; | ||
| 755 | *multi_sgi |= (w > 1); | ||
| 756 | } else { | ||
| 757 | count++; | ||
| 758 | } | ||
| 759 | spin_unlock(&irq->irq_lock); | 752 | spin_unlock(&irq->irq_lock); |
| 753 | |||
| 754 | count += w; | ||
| 755 | *multi_sgi |= (w > 1); | ||
| 760 | } | 756 | } |
| 761 | return count; | 757 | return count; |
| 762 | } | 758 | } |
| @@ -767,7 +763,6 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu) | |||
| 767 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 763 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 768 | struct vgic_irq *irq; | 764 | struct vgic_irq *irq; |
| 769 | int count; | 765 | int count; |
| 770 | bool npie = false; | ||
| 771 | bool multi_sgi; | 766 | bool multi_sgi; |
| 772 | u8 prio = 0xff; | 767 | u8 prio = 0xff; |
| 773 | 768 | ||
| @@ -797,10 +792,8 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu) | |||
| 797 | if (likely(vgic_target_oracle(irq) == vcpu)) { | 792 | if (likely(vgic_target_oracle(irq) == vcpu)) { |
| 798 | vgic_populate_lr(vcpu, irq, count++); | 793 | vgic_populate_lr(vcpu, irq, count++); |
| 799 | 794 | ||
| 800 | if (irq->source) { | 795 | if (irq->source) |
| 801 | npie = true; | ||
| 802 | prio = irq->priority; | 796 | prio = irq->priority; |
| 803 | } | ||
| 804 | } | 797 | } |
| 805 | 798 | ||
| 806 | spin_unlock(&irq->irq_lock); | 799 | spin_unlock(&irq->irq_lock); |
| @@ -813,9 +806,6 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu) | |||
| 813 | } | 806 | } |
| 814 | } | 807 | } |
| 815 | 808 | ||
| 816 | if (npie) | ||
| 817 | vgic_set_npie(vcpu); | ||
| 818 | |||
| 819 | vcpu->arch.vgic_cpu.used_lrs = count; | 809 | vcpu->arch.vgic_cpu.used_lrs = count; |
| 820 | 810 | ||
| 821 | /* Nuke remaining LRs */ | 811 | /* Nuke remaining LRs */ |
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index 830e815748a0..32c25d42c93f 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h | |||
| @@ -110,6 +110,20 @@ static inline bool vgic_irq_is_mapped_level(struct vgic_irq *irq) | |||
| 110 | return irq->config == VGIC_CONFIG_LEVEL && irq->hw; | 110 | return irq->config == VGIC_CONFIG_LEVEL && irq->hw; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static inline int vgic_irq_get_lr_count(struct vgic_irq *irq) | ||
| 114 | { | ||
| 115 | /* Account for the active state as an interrupt */ | ||
| 116 | if (vgic_irq_is_sgi(irq->intid) && irq->source) | ||
| 117 | return hweight8(irq->source) + irq->active; | ||
| 118 | |||
| 119 | return irq_is_pending(irq) || irq->active; | ||
| 120 | } | ||
| 121 | |||
| 122 | static inline bool vgic_irq_is_multi_sgi(struct vgic_irq *irq) | ||
| 123 | { | ||
| 124 | return vgic_irq_get_lr_count(irq) > 1; | ||
| 125 | } | ||
| 126 | |||
| 113 | /* | 127 | /* |
| 114 | * This struct provides an intermediate representation of the fields contained | 128 | * This struct provides an intermediate representation of the fields contained |
| 115 | * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC | 129 | * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC |
