KVM/arm64 updates for 5.15 - Page ownership tracking between host EL1 and EL2 - Rely on userspace page tables to create large stage-2 mappings - Fix incompatibility between pKVM and kmemleak - Fix the PMU reset state, and improve the performance of the virtual PMU - Move over to the generic KVM entry code - Address PSCI reset issues w.r.t. save/restore - Preliminary rework for the upcoming pKVM fixed feature - A bunch of MM cleanups - a vGIC fix for timer spurious interrupts - Various cleanups
Unified · Split
| @@ -45,14 +45,24 @@ how the user addresses are used by the kernel: · 44 unmodified lines | |||
| 45 | 45 | ||
| 46 | 1. User addresses not accessed by the kernel but used for address space | 46 | 1. User addresses not accessed by the kernel but used for address space |
| 47 | management (e.g. ``mprotect()``, ``madvise()``). The use of valid | 47 | management (e.g. ``mprotect()``, ``madvise()``). The use of valid |
| 48 | tagged pointers in this context is allowed with the exception of | 48 | tagged pointers in this context is allowed with these exceptions: |
| 49 | ``brk()``, ``mmap()`` and the ``new_address`` argument to | 49 | |
| 50 | ``mremap()`` as these have the potential to alias with existing | 50 | - ``brk()``, ``mmap()`` and the ``new_address`` argument to |
| 51 | user addresses. | 51 | ``mremap()`` as these have the potential to alias with existing |
| 52 | 52 | user addresses. | |
| 53 | NOTE: This behaviour changed in v5.6 and so some earlier kernels may | 53 | |
| 54 | incorrectly accept valid tagged pointers for the ``brk()``, | 54 | NOTE: This behaviour changed in v5.6 and so some earlier kernels may |
| 55 | ``mmap()`` and ``mremap()`` system calls. | 55 | incorrectly accept valid tagged pointers for the ``brk()``, |
| 56 | ``mmap()`` and ``mremap()`` system calls. | ||
| 57 | |||
| 58 | - The ``range.start``, ``start`` and ``dst`` arguments to the | ||
| 59 | ``UFFDIO_*`` ``ioctl()``s used on a file descriptor obtained from | ||
| 60 | ``userfaultfd()``, as fault addresses subsequently obtained by reading | ||
| 61 | the file descriptor will be untagged, which may otherwise confuse | ||
| 62 | tag-unaware programs. | ||
| 63 | |||
| 64 | NOTE: This behaviour changed in v5.14 and so some earlier kernels may | ||
| 65 | incorrectly accept valid tagged pointers for this system call. | ||
| 56 | 66 | ||
| 57 | 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI | 67 | 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI |
| 58 | relaxation is disabled by default and the application thread needs to | 68 | relaxation is disabled by default and the application thread needs to |
| @@ -1,56 +0,0 @@ | |||
| 1 | IMX8 glue layer controller, NXP imx8 families support Synopsys MAC 5.10a IP. | ||
| 2 | |||
| 3 | This file documents platform glue layer for IMX. | ||
| 4 | Please see stmmac.txt for the other unchanged properties. | ||
| 5 | |||
| 6 | The device node has following properties. | ||
| 7 | |||
| 8 | Required properties: | ||
| 9 | - compatible: Should be "nxp,imx8mp-dwmac-eqos" to select glue layer | ||
| 10 | and "snps,dwmac-5.10a" to select IP version. | ||
| 11 | - clocks: Must contain a phandle for each entry in clock-names. | ||
| 12 | - clock-names: Should be "stmmaceth" for the host clock. | ||
| 13 | Should be "pclk" for the MAC apb clock. | ||
| 14 | Should be "ptp_ref" for the MAC timer clock. | ||
| 15 | Should be "tx" for the MAC RGMII TX clock: | ||
| 16 | Should be "mem" for EQOS MEM clock. | ||
| 17 | - "mem" clock is required for imx8dxl platform. | ||
| 18 | - "mem" clock is not required for imx8mp platform. | ||
| 19 | - interrupt-names: Should contain a list of interrupt names corresponding to | ||
| 20 | the interrupts in the interrupts property, if available. | ||
| 21 | Should be "macirq" for the main MAC IRQ | ||
| 22 | Should be "eth_wake_irq" for the IT which wake up system | ||
| 23 | - intf_mode: Should be phandle/offset pair. The phandle to the syscon node which | ||
| 24 | encompases the GPR register, and the offset of the GPR register. | ||
| 25 | - required for imx8mp platform. | ||
| 26 | - is optional for imx8dxl platform. | ||
| 27 | |||
| 28 | Optional properties: | ||
| 29 | - intf_mode: is optional for imx8dxl platform. | ||
| 30 | - snps,rmii_refclk_ext: to select RMII reference clock from external. | ||
| 31 | |||
| 32 | Example: | ||
| 33 | eqos: ethernet@30bf0000 { | ||
| 34 | compatible = "nxp,imx8mp-dwmac-eqos", "snps,dwmac-5.10a"; | ||
| 35 | reg = <0x30bf0000 0x10000>; | ||
| 36 | interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, | ||
| 37 | <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; | ||
| 38 | interrupt-names = "eth_wake_irq", "macirq"; | ||
| 39 | clocks = <&clk IMX8MP_CLK_ENET_QOS_ROOT>, | ||
| 40 | <&clk IMX8MP_CLK_QOS_ENET_ROOT>, | ||
| 41 | <&clk IMX8MP_CLK_ENET_QOS_TIMER>, | ||
| 42 | <&clk IMX8MP_CLK_ENET_QOS>; | ||
| 43 | clock-names = "stmmaceth", "pclk", "ptp_ref", "tx"; | ||
| 44 | assigned-clocks = <&clk IMX8MP_CLK_ENET_AXI>, | ||
| 45 | <&clk IMX8MP_CLK_ENET_QOS_TIMER>, | ||
| 46 | <&clk IMX8MP_CLK_ENET_QOS>; | ||
| 47 | assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>, | ||
| 48 | <&clk IMX8MP_SYS_PLL2_100M>, | ||
| 49 | <&clk IMX8MP_SYS_PLL2_125M>; | ||
| 50 | assigned-clock-rates = <0>, <100000000>, <125000000>; | ||
| 51 | nvmem-cells = <ð_mac0>; | ||
| 52 | nvmem-cell-names = "mac-address"; | ||
| 53 | nvmem_macaddr_swap; | ||
| 54 | intf_mode = <&gpr 0x4>; | ||
| 55 | status = "disabled"; | ||
| 56 | }; | ||
| @@ -0,0 +1,93 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/net/nxp,dwmac-imx.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: NXP i.MX8 DWMAC glue layer Device Tree Bindings | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Joakim Zhang <qiangqing.zhang@nxp.com> | ||
| 11 | |||
| 12 | # We need a select here so we don't match all nodes with 'snps,dwmac' | ||
| 13 | select: | ||
| 14 | properties: | ||
| 15 | compatible: | ||
| 16 | contains: | ||
| 17 | enum: | ||
| 18 | - nxp,imx8mp-dwmac-eqos | ||
| 19 | - nxp,imx8dxl-dwmac-eqos | ||
| 20 | required: | ||
| 21 | - compatible | ||
| 22 | |||
| 23 | allOf: | ||
| 24 | - $ref: "snps,dwmac.yaml#" | ||
| 25 | |||
| 26 | properties: | ||
| 27 | compatible: | ||
| 28 | oneOf: | ||
| 29 | - items: | ||
| 30 | - enum: | ||
| 31 | - nxp,imx8mp-dwmac-eqos | ||
| 32 | - nxp,imx8dxl-dwmac-eqos | ||
| 33 | - const: snps,dwmac-5.10a | ||
| 34 | |||
| 35 | clocks: | ||
| 36 | minItems: 3 | ||
| 37 | maxItems: 5 | ||
| 38 | items: | ||
| 39 | - description: MAC host clock | ||
| 40 | - description: MAC apb clock | ||
| 41 | - description: MAC timer clock | ||
| 42 | - description: MAC RGMII TX clock | ||
| 43 | - description: EQOS MEM clock | ||
| 44 | |||
| 45 | clock-names: | ||
| 46 | minItems: 3 | ||
| 47 | maxItems: 5 | ||
| 48 | contains: | ||
| 49 | enum: | ||
| 50 | - stmmaceth | ||
| 51 | - pclk | ||
| 52 | - ptp_ref | ||
| 53 | - tx | ||
| 54 | - mem | ||
| 55 | |||
| 56 | intf_mode: | ||
| 57 | $ref: /schemas/types.yaml#/definitions/phandle-array | ||
| 58 | description: | ||
| 59 | Should be phandle/offset pair. The phandle to the syscon node which | ||
| 60 | encompases the GPR register, and the offset of the GPR register. | ||
| 61 | |||
| 62 | snps,rmii_refclk_ext: | ||
| 63 | $ref: /schemas/types.yaml#/definitions/flag | ||
| 64 | description: | ||
| 65 | To select RMII reference clock from external. | ||
| 66 | |||
| 67 | required: | ||
| 68 | - compatible | ||
| 69 | - clocks | ||
| 70 | - clock-names | ||
| 71 | |||
| 72 | unevaluatedProperties: false | ||
| 73 | |||
| 74 | examples: | ||
| 75 | - | | ||
| 76 | #include <dt-bindings/interrupt-controller/arm-gic.h> | ||
| 77 | #include <dt-bindings/interrupt-controller/irq.h> | ||
| 78 | #include <dt-bindings/clock/imx8mp-clock.h> | ||
| 79 | |||
| 80 | eqos: ethernet@30bf0000 { | ||
| 81 | compatible = "nxp,imx8mp-dwmac-eqos","snps,dwmac-5.10a"; | ||
| 82 | reg = <0x30bf0000 0x10000>; | ||
| 83 | interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, | ||
| 84 | <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; | ||
| 85 | interrupt-names = "macirq", "eth_wake_irq"; | ||
| 86 | clocks = <&clk IMX8MP_CLK_ENET_QOS_ROOT>, | ||
| 87 | <&clk IMX8MP_CLK_QOS_ENET_ROOT>, | ||
| 88 | <&clk IMX8MP_CLK_ENET_QOS_TIMER>, | ||
| 89 | <&clk IMX8MP_CLK_ENET_QOS>; | ||
| 90 | clock-names = "stmmaceth", "pclk", "ptp_ref", "tx"; | ||
| 91 | phy-mode = "rgmii"; | ||
| 92 | status = "disabled"; | ||
| 93 | }; | ||
| @@ -28,6 +28,7 @@ select: · 27 unmodified lines | |||
| 28 | - snps,dwmac-4.00 | 28 | - snps,dwmac-4.00 |
| 29 | - snps,dwmac-4.10a | 29 | - snps,dwmac-4.10a |
| 30 | - snps,dwmac-4.20a | 30 | - snps,dwmac-4.20a |
| 31 | - snps,dwmac-5.10a | ||
| 31 | - snps,dwxgmac | 32 | - snps,dwxgmac |
| 32 | - snps,dwxgmac-2.10 | 33 | - snps,dwxgmac-2.10 |
| 33 | 34 | ||
| @@ -82,6 +83,7 @@ properties: · 48 unmodified lines | |||
| 82 | - snps,dwmac-4.00 | 83 | - snps,dwmac-4.00 |
| 83 | - snps,dwmac-4.10a | 84 | - snps,dwmac-4.10a |
| 84 | - snps,dwmac-4.20a | 85 | - snps,dwmac-4.20a |
| 86 | - snps,dwmac-5.10a | ||
| 85 | - snps,dwxgmac | 87 | - snps,dwxgmac |
| 86 | - snps,dwxgmac-2.10 | 88 | - snps,dwxgmac-2.10 |
| 87 | 89 | ||
| @@ -375,6 +377,7 @@ allOf: · 287 unmodified lines | |||
| 375 | - snps,dwmac-4.00 | 377 | - snps,dwmac-4.00 |
| 376 | - snps,dwmac-4.10a | 378 | - snps,dwmac-4.10a |
| 377 | - snps,dwmac-4.20a | 379 | - snps,dwmac-4.20a |
| 380 | - snps,dwmac-5.10a | ||
| 378 | - snps,dwxgmac | 381 | - snps,dwxgmac |
| 379 | - snps,dwxgmac-2.10 | 382 | - snps,dwxgmac-2.10 |
| 380 | - st,spear600-gmac | 383 | - st,spear600-gmac |
| @@ -57,12 +57,14 @@ properties: · 56 unmodified lines | |||
| 57 | maxItems: 1 | 57 | maxItems: 1 |
| 58 | 58 | ||
| 59 | power-domains: | 59 | power-domains: |
| 60 | deprecated: true | ||
| 60 | description: | 61 | description: |
| 61 | Power domain to use for enable control. This binding is only | 62 | Power domain to use for enable control. This binding is only |
| 62 | available if the compatible is chosen to regulator-fixed-domain. | 63 | available if the compatible is chosen to regulator-fixed-domain. |
| 63 | maxItems: 1 | 64 | maxItems: 1 |
| 64 | 65 | ||
| 65 | required-opps: | 66 | required-opps: |
| 67 | deprecated: true | ||
| 66 | description: | 68 | description: |
| 67 | Performance state to use for enable control. This binding is only | 69 | Performance state to use for enable control. This binding is only |
| 68 | available if the compatible is chosen to regulator-fixed-domain. The | 70 | available if the compatible is chosen to regulator-fixed-domain. The |
| @@ -114,7 +114,7 @@ properties: · 113 unmodified lines | |||
| 114 | 114 | ||
| 115 | ports: | 115 | ports: |
| 116 | $ref: /schemas/graph.yaml#/properties/ports | 116 | $ref: /schemas/graph.yaml#/properties/ports |
| 117 | properties: | 117 | patternProperties: |
| 118 | port(@[0-9a-f]+)?: | 118 | port(@[0-9a-f]+)?: |
| 119 | $ref: audio-graph-port.yaml# | 119 | $ref: audio-graph-port.yaml# |
| 120 | unevaluatedProperties: false | 120 | unevaluatedProperties: false |
| @@ -243,8 +243,8 @@ Configuration Flags and Socket Options · 242 unmodified lines | |||
| 243 | These are the various configuration flags that can be used to control | 243 | These are the various configuration flags that can be used to control |
| 244 | and monitor the behavior of AF_XDP sockets. | 244 | and monitor the behavior of AF_XDP sockets. |
| 245 | 245 | ||
| 246 | XDP_COPY and XDP_ZERO_COPY bind flags | 246 | XDP_COPY and XDP_ZEROCOPY bind flags |
| 247 | ------------------------------------- | 247 | ------------------------------------ |
| 248 | 248 | ||
| 249 | When you bind to a socket, the kernel will first try to use zero-copy | 249 | When you bind to a socket, the kernel will first try to use zero-copy |
| 250 | copy. If zero-copy is not supported, it will fall back on using copy | 250 | copy. If zero-copy is not supported, it will fall back on using copy |
| @@ -252,7 +252,7 @@ mode, i.e. copying all packets out to user space. But if you would · 1 unmodified line | |||
| 252 | like to force a certain mode, you can use the following flags. If you | 252 | like to force a certain mode, you can use the following flags. If you |
| 253 | pass the XDP_COPY flag to the bind call, the kernel will force the | 253 | pass the XDP_COPY flag to the bind call, the kernel will force the |
| 254 | socket into copy mode. If it cannot use copy mode, the bind call will | 254 | socket into copy mode. If it cannot use copy mode, the bind call will |
| 255 | fail with an error. Conversely, the XDP_ZERO_COPY flag will force the | 255 | fail with an error. Conversely, the XDP_ZEROCOPY flag will force the |
| 256 | socket into zero-copy mode or fail. | 256 | socket into zero-copy mode or fail. |
| 257 | 257 | ||
| 258 | XDP_SHARED_UMEM bind flag | 258 | XDP_SHARED_UMEM bind flag |
| @@ -826,7 +826,7 @@ tcp_fastopen_blackhole_timeout_sec - INTEGER · 825 unmodified lines | |||
| 826 | initial value when the blackhole issue goes away. | 826 | initial value when the blackhole issue goes away. |
| 827 | 0 to disable the blackhole detection. | 827 | 0 to disable the blackhole detection. |
| 828 | 828 | ||
| 829 | By default, it is set to 1hr. | 829 | By default, it is set to 0 (feature is disabled). |
| 830 | 830 | ||
| 831 | tcp_fastopen_key - list of comma separated 32-digit hexadecimal INTEGERs | 831 | tcp_fastopen_key - list of comma separated 32-digit hexadecimal INTEGERs |
| 832 | The list consists of a primary key and an optional backup key. The | 832 | The list consists of a primary key and an optional backup key. The |
| @@ -191,7 +191,7 @@ Documentation written by Tom Zanussi · 190 unmodified lines | |||
| 191 | with the event, in nanoseconds. May be | 191 | with the event, in nanoseconds. May be |
| 192 | modified by .usecs to have timestamps | 192 | modified by .usecs to have timestamps |
| 193 | interpreted as microseconds. | 193 | interpreted as microseconds. |
| 194 | cpu int the cpu on which the event occurred. | 194 | common_cpu int the cpu on which the event occurred. |
| 195 | ====================== ==== ======================================= | 195 | ====================== ==== ======================================= |
| 196 | 196 | ||
| 197 | Extended error information | 197 | Extended error information |
| @@ -445,7 +445,7 @@ F: drivers/platform/x86/wmi.c · 444 unmodified lines | |||
| 445 | F: include/uapi/linux/wmi.h | 445 | F: include/uapi/linux/wmi.h |
| 446 | 446 | ||
| 447 | ACRN HYPERVISOR SERVICE MODULE | 447 | ACRN HYPERVISOR SERVICE MODULE |
| 448 | M: Shuo Liu <shuo.a.liu@intel.com> | 448 | M: Fei Li <fei1.li@intel.com> |
| 449 | L: acrn-dev@lists.projectacrn.org (subscribers-only) | 449 | L: acrn-dev@lists.projectacrn.org (subscribers-only) |
| 450 | S: Supported | 450 | S: Supported |
| 451 | W: https://projectacrn.org | 451 | W: https://projectacrn.org |
| @@ -7858,9 +7858,9 @@ S: Maintained · 7406 unmodified lines | |||
| 7858 | F: drivers/input/touchscreen/goodix.c | 7858 | F: drivers/input/touchscreen/goodix.c |
| 7859 | 7859 | ||
| 7860 | GOOGLE ETHERNET DRIVERS | 7860 | GOOGLE ETHERNET DRIVERS |
| 7861 | M: Catherine Sullivan <csully@google.com> | 7861 | M: Jeroen de Borst <jeroendb@google.com> |
| 7862 | R: Sagi Shahar <sagis@google.com> | 7862 | R: Catherine Sullivan <csully@google.com> |
| 7863 | R: Jon Olson <jonolson@google.com> | 7863 | R: David Awogbemila <awogbemila@google.com> |
| 7864 | L: netdev@vger.kernel.org | 7864 | L: netdev@vger.kernel.org |
| 7865 | S: Supported | 7865 | S: Supported |
| 7866 | F: Documentation/networking/device_drivers/ethernet/google/gve.rst | 7866 | F: Documentation/networking/device_drivers/ethernet/google/gve.rst |
| @@ -11327,6 +11327,12 @@ W: https://linuxtv.org · 3460 unmodified lines | |||
| 11327 | T: git git://linuxtv.org/media_tree.git | 11327 | T: git git://linuxtv.org/media_tree.git |
| 11328 | F: drivers/media/radio/radio-maxiradio* | 11328 | F: drivers/media/radio/radio-maxiradio* |
| 11329 | 11329 | ||
| 11330 | MCAB MICROCHIP CAN BUS ANALYZER TOOL DRIVER | ||
| 11331 | R: Yasushi SHOJI <yashi@spacecubics.com> | ||
| 11332 | L: linux-can@vger.kernel.org | ||
| 11333 | S: Maintained | ||
| 11334 | F: drivers/net/can/usb/mcba_usb.c | ||
| 11335 | |||
| 11330 | MCAN MMIO DEVICE DRIVER | 11336 | MCAN MMIO DEVICE DRIVER |
| 11331 | M: Chandrasekar Ramakrishnan <rcsekar@samsung.com> | 11337 | M: Chandrasekar Ramakrishnan <rcsekar@samsung.com> |
| 11332 | L: linux-can@vger.kernel.org | 11338 | L: linux-can@vger.kernel.org |
| @@ -11758,6 +11764,7 @@ F: drivers/char/hw_random/mtk-rng.c · 425 unmodified lines | |||
| 11758 | MEDIATEK SWITCH DRIVER | 11764 | MEDIATEK SWITCH DRIVER |
| 11759 | M: Sean Wang <sean.wang@mediatek.com> | 11765 | M: Sean Wang <sean.wang@mediatek.com> |
| 11760 | M: Landen Chao <Landen.Chao@mediatek.com> | 11766 | M: Landen Chao <Landen.Chao@mediatek.com> |
| 11767 | M: DENG Qingfang <dqfext@gmail.com> | ||
| 11761 | L: netdev@vger.kernel.org | 11768 | L: netdev@vger.kernel.org |
| 11762 | S: Maintained | 11769 | S: Maintained |
| 11763 | F: drivers/net/dsa/mt7530.* | 11770 | F: drivers/net/dsa/mt7530.* |
| @@ -15467,6 +15474,8 @@ M: Pan, Xinhui <Xinhui.Pan@amd.com> · 3703 unmodified lines | |||
| 15467 | L: amd-gfx@lists.freedesktop.org | 15474 | L: amd-gfx@lists.freedesktop.org |
| 15468 | S: Supported | 15475 | S: Supported |
| 15469 | T: git https://gitlab.freedesktop.org/agd5f/linux.git | 15476 | T: git https://gitlab.freedesktop.org/agd5f/linux.git |
| 15477 | B: https://gitlab.freedesktop.org/drm/amd/-/issues | ||
| 15478 | C: irc://irc.oftc.net/radeon | ||
| 15470 | F: drivers/gpu/drm/amd/ | 15479 | F: drivers/gpu/drm/amd/ |
| 15471 | F: drivers/gpu/drm/radeon/ | 15480 | F: drivers/gpu/drm/radeon/ |
| 15472 | F: include/uapi/drm/amdgpu_drm.h | 15481 | F: include/uapi/drm/amdgpu_drm.h |
| @@ -19122,7 +19131,7 @@ M: Mauro Carvalho Chehab <mchehab@kernel.org> · 3649 unmodified lines | |||
| 19122 | L: linux-usb@vger.kernel.org | 19131 | L: linux-usb@vger.kernel.org |
| 19123 | S: Maintained | 19132 | S: Maintained |
| 19124 | F: Documentation/devicetree/bindings/phy/hisilicon,hi3670-usb3.yaml | 19133 | F: Documentation/devicetree/bindings/phy/hisilicon,hi3670-usb3.yaml |
| 19125 | F: drivers/phy/hisilicon/phy-kirin970-usb3.c | 19134 | F: drivers/phy/hisilicon/phy-hi3670-usb3.c |
| 19126 | 19135 | ||
| 19127 | USB ISP116X DRIVER | 19136 | USB ISP116X DRIVER |
| 19128 | M: Olav Kongas <ok@artecdesign.ee> | 19137 | M: Olav Kongas <ok@artecdesign.ee> |
| @@ -19800,6 +19809,14 @@ L: netdev@vger.kernel.org · 671 unmodified lines | |||
| 19800 | S: Supported | 19809 | S: Supported |
| 19801 | F: drivers/ptp/ptp_vmw.c | 19810 | F: drivers/ptp/ptp_vmw.c |
| 19802 | 19811 | ||
| 19812 | VMWARE VMCI DRIVER | ||
| 19813 | M: Jorgen Hansen <jhansen@vmware.com> | ||
| 19814 | M: Vishnu Dasa <vdasa@vmware.com> | ||
| 19815 | L: linux-kernel@vger.kernel.org | ||
| 19816 | L: pv-drivers@vmware.com (private) | ||
| 19817 | S: Maintained | ||
| 19818 | F: drivers/misc/vmw_vmci/ | ||
| 19819 | |||
| 19803 | VMWARE VMMOUSE SUBDRIVER | 19820 | VMWARE VMMOUSE SUBDRIVER |
| 19804 | M: "VMware Graphics" <linux-graphics-maintainer@vmware.com> | 19821 | M: "VMware Graphics" <linux-graphics-maintainer@vmware.com> |
| 19805 | M: "VMware, Inc." <pv-drivers@vmware.com> | 19822 | M: "VMware, Inc." <pv-drivers@vmware.com> |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 14 | 3 | PATCHLEVEL = 14 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc2 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Opossums on Parade | 6 | NAME = Opossums on Parade |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -14,7 +14,6 @@ config ALPHA · 13 unmodified lines | |||
| 14 | select PCI_SYSCALL if PCI | 14 | select PCI_SYSCALL if PCI |
| 15 | select HAVE_AOUT | 15 | select HAVE_AOUT |
| 16 | select HAVE_ASM_MODVERSIONS | 16 | select HAVE_ASM_MODVERSIONS |
| 17 | select HAVE_IDE | ||
| 18 | select HAVE_PCSPKR_PLATFORM | 17 | select HAVE_PCSPKR_PLATFORM |
| 19 | select HAVE_PERF_EVENTS | 18 | select HAVE_PERF_EVENTS |
| 20 | select NEED_DMA_MAP_STATE | 19 | select NEED_DMA_MAP_STATE |
| @@ -532,7 +531,7 @@ config SMP · 511 unmodified lines | |||
| 532 | will run faster if you say N here. | 531 | will run faster if you say N here. |
| 533 | 532 | ||
| 534 | See also the SMP-HOWTO available at | 533 | See also the SMP-HOWTO available at |
| 535 | <http://www.tldp.org/docs.html#howto>. | 534 | <https://www.tldp.org/docs.html#howto>. |
| 536 | 535 | ||
| 537 | If you don't know what to do here, say N. | 536 | If you don't know what to do here, say N. |
| 538 | 537 | ||
| @@ -23,7 +23,7 @@ · 22 unmodified lines | |||
| 23 | #include "ksize.h" | 23 | #include "ksize.h" |
| 24 | 24 | ||
| 25 | extern unsigned long switch_to_osf_pal(unsigned long nr, | 25 | extern unsigned long switch_to_osf_pal(unsigned long nr, |
| 26 | struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa, | 26 | struct pcb_struct *pcb_va, struct pcb_struct *pcb_pa, |
| 27 | unsigned long *vptb); | 27 | unsigned long *vptb); |
| 28 | 28 | ||
| 29 | extern void move_stack(unsigned long new_stack); | 29 | extern void move_stack(unsigned long new_stack); |
| @@ -200,7 +200,7 @@ extern char _end; · 199 unmodified lines | |||
| 200 | START_ADDR KSEG address of the entry point of kernel code. | 200 | START_ADDR KSEG address of the entry point of kernel code. |
| 201 | 201 | ||
| 202 | ZERO_PGE KSEG address of page full of zeroes, but | 202 | ZERO_PGE KSEG address of page full of zeroes, but |
| 203 | upon entry to kerne cvan be expected | 203 | upon entry to kernel, it can be expected |
| 204 | to hold the parameter list and possible | 204 | to hold the parameter list and possible |
| 205 | INTRD information. | 205 | INTRD information. |
| 206 | 206 | ||
| @@ -30,7 +30,7 @@ extern long srm_printk(const char *, ...) · 29 unmodified lines | |||
| 30 | __attribute__ ((format (printf, 1, 2))); | 30 | __attribute__ ((format (printf, 1, 2))); |
| 31 | 31 | ||
| 32 | /* | 32 | /* |
| 33 | * gzip delarations | 33 | * gzip declarations |
| 34 | */ | 34 | */ |
| 35 | #define OF(args) args | 35 | #define OF(args) args |
| 36 | #define STATIC static | 36 | #define STATIC static |
| @@ -70,3 +70,4 @@ CONFIG_DEBUG_INFO=y · 69 unmodified lines | |||
| 70 | CONFIG_ALPHA_LEGACY_START_ADDRESS=y | 70 | CONFIG_ALPHA_LEGACY_START_ADDRESS=y |
| 71 | CONFIG_MATHEMU=y | 71 | CONFIG_MATHEMU=y |
| 72 | CONFIG_CRYPTO_HMAC=y | 72 | CONFIG_CRYPTO_HMAC=y |
| 73 | CONFIG_DEVTMPFS=y | ||
| @@ -4,15 +4,4 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include <uapi/asm/compiler.h> | 5 | #include <uapi/asm/compiler.h> |
| 6 | 6 | ||
| 7 | /* Some idiots over in <linux/compiler.h> thought inline should imply | ||
| 8 | always_inline. This breaks stuff. We'll include this file whenever | ||
| 9 | we run into such problems. */ | ||
| 10 | |||
| 11 | #include <linux/compiler.h> | ||
| 12 | #undef inline | ||
| 13 | #undef __inline__ | ||
| 14 | #undef __inline | ||
| 15 | #undef __always_inline | ||
| 16 | #define __always_inline inline __attribute__((always_inline)) | ||
| 17 | |||
| 18 | #endif /* __ALPHA_COMPILER_H */ | 7 | #endif /* __ALPHA_COMPILER_H */ |
| @@ -9,4 +9,10 @@ static inline int syscall_get_arch(struct task_struct *task) · 8 unmodified lines | |||
| 9 | return AUDIT_ARCH_ALPHA; | 9 | return AUDIT_ARCH_ALPHA; |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | static inline long syscall_get_return_value(struct task_struct *task, | ||
| 13 | struct pt_regs *regs) | ||
| 14 | { | ||
| 15 | return regs->r0; | ||
| 16 | } | ||
| 17 | |||
| 12 | #endif /* _ASM_ALPHA_SYSCALL_H */ | 18 | #endif /* _ASM_ALPHA_SYSCALL_H */ |
| @@ -834,7 +834,7 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer, · 833 unmodified lines | |||
| 834 | return -EFAULT; | 834 | return -EFAULT; |
| 835 | state = ¤t_thread_info()->ieee_state; | 835 | state = ¤t_thread_info()->ieee_state; |
| 836 | 836 | ||
| 837 | /* Update softare trap enable bits. */ | 837 | /* Update software trap enable bits. */ |
| 838 | *state = (*state & ~IEEE_SW_MASK) | (swcr & IEEE_SW_MASK); | 838 | *state = (*state & ~IEEE_SW_MASK) | (swcr & IEEE_SW_MASK); |
| 839 | 839 | ||
| 840 | /* Update the real fpcr. */ | 840 | /* Update the real fpcr. */ |
| @@ -854,7 +854,7 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer, · 13 unmodified lines | |||
| 854 | state = ¤t_thread_info()->ieee_state; | 854 | state = ¤t_thread_info()->ieee_state; |
| 855 | exc &= IEEE_STATUS_MASK; | 855 | exc &= IEEE_STATUS_MASK; |
| 856 | 856 | ||
| 857 | /* Update softare trap enable bits. */ | 857 | /* Update software trap enable bits. */ |
| 858 | swcr = (*state & IEEE_SW_MASK) | exc; | 858 | swcr = (*state & IEEE_SW_MASK) | exc; |
| 859 | *state |= exc; | 859 | *state |= exc; |
| 860 | 860 | ||
| @@ -574,7 +574,7 @@ static void alpha_pmu_start(struct perf_event *event, int flags) · 573 unmodified lines | |||
| 574 | * Check that CPU performance counters are supported. | 574 | * Check that CPU performance counters are supported. |
| 575 | * - currently support EV67 and later CPUs. | 575 | * - currently support EV67 and later CPUs. |
| 576 | * - actually some later revisions of the EV6 have the same PMC model as the | 576 | * - actually some later revisions of the EV6 have the same PMC model as the |
| 577 | * EV67 but we don't do suffiently deep CPU detection to detect them. | 577 | * EV67 but we don't do sufficiently deep CPU detection to detect them. |
| 578 | * Bad luck to the very few people who might have one, I guess. | 578 | * Bad luck to the very few people who might have one, I guess. |
| 579 | */ | 579 | */ |
| 580 | static int supported_cpu(void) | 580 | static int supported_cpu(void) |
| @@ -256,7 +256,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, · 255 unmodified lines | |||
| 256 | childstack->r26 = (unsigned long) ret_from_kernel_thread; | 256 | childstack->r26 = (unsigned long) ret_from_kernel_thread; |
| 257 | childstack->r9 = usp; /* function */ | 257 | childstack->r9 = usp; /* function */ |
| 258 | childstack->r10 = kthread_arg; | 258 | childstack->r10 = kthread_arg; |
| 259 | childregs->hae = alpha_mv.hae_cache, | 259 | childregs->hae = alpha_mv.hae_cache; |
| 260 | childti->pcb.usp = 0; | 260 | childti->pcb.usp = 0; |
| 261 | return 0; | 261 | return 0; |
| 262 | } | 262 | } |
| @@ -319,18 +319,19 @@ setup_memory(void *kernel_end) · 318 unmodified lines | |||
| 319 | i, cluster->usage, cluster->start_pfn, | 319 | i, cluster->usage, cluster->start_pfn, |
| 320 | cluster->start_pfn + cluster->numpages); | 320 | cluster->start_pfn + cluster->numpages); |
| 321 | 321 | ||
| 322 | /* Bit 0 is console/PALcode reserved. Bit 1 is | ||
| 323 | non-volatile memory -- we might want to mark | ||
| 324 | this for later. */ | ||
| 325 | if (cluster->usage & 3) | ||
| 326 | continue; | ||
| 327 | |||
| 328 | end = cluster->start_pfn + cluster->numpages; | 322 | end = cluster->start_pfn + cluster->numpages; |
| 329 | if (end > max_low_pfn) | 323 | if (end > max_low_pfn) |
| 330 | max_low_pfn = end; | 324 | max_low_pfn = end; |
| 331 | 325 | ||
| 332 | memblock_add(PFN_PHYS(cluster->start_pfn), | 326 | memblock_add(PFN_PHYS(cluster->start_pfn), |
| 333 | cluster->numpages << PAGE_SHIFT); | 327 | cluster->numpages << PAGE_SHIFT); |
| 328 | |||
| 329 | /* Bit 0 is console/PALcode reserved. Bit 1 is | ||
| 330 | non-volatile memory -- we might want to mark | ||
| 331 | this for later. */ | ||
| 332 | if (cluster->usage & 3) | ||
| 333 | memblock_reserve(PFN_PHYS(cluster->start_pfn), | ||
| 334 | cluster->numpages << PAGE_SHIFT); | ||
| 334 | } | 335 | } |
| 335 | 336 | ||
| 336 | /* | 337 | /* |
| @@ -582,7 +582,7 @@ void · 581 unmodified lines | |||
| 582 | smp_send_stop(void) | 582 | smp_send_stop(void) |
| 583 | { | 583 | { |
| 584 | cpumask_t to_whom; | 584 | cpumask_t to_whom; |
| 585 | cpumask_copy(&to_whom, cpu_possible_mask); | 585 | cpumask_copy(&to_whom, cpu_online_mask); |
| 586 | cpumask_clear_cpu(smp_processor_id(), &to_whom); | 586 | cpumask_clear_cpu(smp_processor_id(), &to_whom); |
| 587 | #ifdef DEBUG_IPI_MSG | 587 | #ifdef DEBUG_IPI_MSG |
| 588 | if (hard_smp_processor_id() != boot_cpu_id) | 588 | if (hard_smp_processor_id() != boot_cpu_id) |
| @@ -212,7 +212,7 @@ nautilus_init_pci(void) · 211 unmodified lines | |||
| 212 | 212 | ||
| 213 | /* Use default IO. */ | 213 | /* Use default IO. */ |
| 214 | pci_add_resource(&bridge->windows, &ioport_resource); | 214 | pci_add_resource(&bridge->windows, &ioport_resource); |
| 215 | /* Irongate PCI memory aperture, calculate requred size before | 215 | /* Irongate PCI memory aperture, calculate required size before |
| 216 | setting it up. */ | 216 | setting it up. */ |
| 217 | pci_add_resource(&bridge->windows, &irongate_mem); | 217 | pci_add_resource(&bridge->windows, &irongate_mem); |
| 218 | 218 | ||
| @@ -730,7 +730,7 @@ do_entUnaUser(void __user * va, unsigned long opcode, · 729 unmodified lines | |||
| 730 | long error; | 730 | long error; |
| 731 | 731 | ||
| 732 | /* Check the UAC bits to decide what the user wants us to do | 732 | /* Check the UAC bits to decide what the user wants us to do |
| 733 | with the unaliged access. */ | 733 | with the unaligned access. */ |
| 734 | 734 | ||
| 735 | if (!(current_thread_info()->status & TS_UAC_NOPRINT)) { | 735 | if (!(current_thread_info()->status & TS_UAC_NOPRINT)) { |
| 736 | if (__ratelimit(&ratelimit)) { | 736 | if (__ratelimit(&ratelimit)) { |
| @@ -65,7 +65,7 @@ static long (*save_emul) (unsigned long pc); · 64 unmodified lines | |||
| 65 | long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long); | 65 | long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long); |
| 66 | long do_alpha_fp_emul(unsigned long); | 66 | long do_alpha_fp_emul(unsigned long); |
| 67 | 67 | ||
| 68 | int init_module(void) | 68 | static int alpha_fp_emul_init_module(void) |
| 69 | { | 69 | { |
| 70 | save_emul_imprecise = alpha_fp_emul_imprecise; | 70 | save_emul_imprecise = alpha_fp_emul_imprecise; |
| 71 | save_emul = alpha_fp_emul; | 71 | save_emul = alpha_fp_emul; |
| @@ -73,12 +73,14 @@ int init_module(void) · 1 unmodified line | |||
| 73 | alpha_fp_emul = do_alpha_fp_emul; | 73 | alpha_fp_emul = do_alpha_fp_emul; |
| 74 | return 0; | 74 | return 0; |
| 75 | } | 75 | } |
| 76 | module_init(alpha_fp_emul_init_module); | ||
| 76 | 77 | ||
| 77 | void cleanup_module(void) | 78 | static void alpha_fp_emul_cleanup_module(void) |
| 78 | { | 79 | { |
| 79 | alpha_fp_emul_imprecise = save_emul_imprecise; | 80 | alpha_fp_emul_imprecise = save_emul_imprecise; |
| 80 | alpha_fp_emul = save_emul; | 81 | alpha_fp_emul = save_emul; |
| 81 | } | 82 | } |
| 83 | module_exit(alpha_fp_emul_cleanup_module); | ||
| 82 | 84 | ||
| 83 | #undef alpha_fp_emul_imprecise | 85 | #undef alpha_fp_emul_imprecise |
| 84 | #define alpha_fp_emul_imprecise do_alpha_fp_emul_imprecise | 86 | #define alpha_fp_emul_imprecise do_alpha_fp_emul_imprecise |
| @@ -401,3 +403,5 @@ alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask) · 316 unmodified lines | |||
| 401 | egress: | 403 | egress: |
| 402 | return si_code; | 404 | return si_code; |
| 403 | } | 405 | } |
| 406 | |||
| 407 | EXPORT_SYMBOL(__udiv_qrnnd); | ||
| @@ -95,7 +95,6 @@ config ARM · 94 unmodified lines | |||
| 95 | select HAVE_FUNCTION_TRACER if !XIP_KERNEL | 95 | select HAVE_FUNCTION_TRACER if !XIP_KERNEL |
| 96 | select HAVE_GCC_PLUGINS | 96 | select HAVE_GCC_PLUGINS |
| 97 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) | 97 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) |
| 98 | select HAVE_IDE if PCI || ISA || PCMCIA | ||
| 99 | select HAVE_IRQ_TIME_ACCOUNTING | 98 | select HAVE_IRQ_TIME_ACCOUNTING |
| 100 | select HAVE_KERNEL_GZIP | 99 | select HAVE_KERNEL_GZIP |
| 101 | select HAVE_KERNEL_LZ4 | 100 | select HAVE_KERNEL_LZ4 |
| @@ -361,7 +360,6 @@ config ARCH_FOOTBRIDGE · 259 unmodified lines | |||
| 361 | bool "FootBridge" | 360 | bool "FootBridge" |
| 362 | select CPU_SA110 | 361 | select CPU_SA110 |
| 363 | select FOOTBRIDGE | 362 | select FOOTBRIDGE |
| 364 | select HAVE_IDE | ||
| 365 | select NEED_MACH_IO_H if !MMU | 363 | select NEED_MACH_IO_H if !MMU |
| 366 | select NEED_MACH_MEMORY_H | 364 | select NEED_MACH_MEMORY_H |
| 367 | help | 365 | help |
| @@ -430,7 +428,6 @@ config ARCH_PXA · 62 unmodified lines | |||
| 430 | select GENERIC_IRQ_MULTI_HANDLER | 428 | select GENERIC_IRQ_MULTI_HANDLER |
| 431 | select GPIO_PXA | 429 | select GPIO_PXA |
| 432 | select GPIOLIB | 430 | select GPIOLIB |
| 433 | select HAVE_IDE | ||
| 434 | select IRQ_DOMAIN | 431 | select IRQ_DOMAIN |
| 435 | select PLAT_PXA | 432 | select PLAT_PXA |
| 436 | select SPARSE_IRQ | 433 | select SPARSE_IRQ |
| @@ -446,7 +443,6 @@ config ARCH_RPC · 9 unmodified lines | |||
| 446 | select ARM_HAS_SG_CHAIN | 443 | select ARM_HAS_SG_CHAIN |
| 447 | select CPU_SA110 | 444 | select CPU_SA110 |
| 448 | select FIQ | 445 | select FIQ |
| 449 | select HAVE_IDE | ||
| 450 | select HAVE_PATA_PLATFORM | 446 | select HAVE_PATA_PLATFORM |
| 451 | select ISA_DMA_API | 447 | select ISA_DMA_API |
| 452 | select LEGACY_TIMER_TICK | 448 | select LEGACY_TIMER_TICK |
| @@ -469,7 +465,6 @@ config ARCH_SA1100 · 16 unmodified lines | |||
| 469 | select CPU_SA1100 | 465 | select CPU_SA1100 |
| 470 | select GENERIC_IRQ_MULTI_HANDLER | 466 | select GENERIC_IRQ_MULTI_HANDLER |
| 471 | select GPIOLIB | 467 | select GPIOLIB |
| 472 | select HAVE_IDE | ||
| 473 | select IRQ_DOMAIN | 468 | select IRQ_DOMAIN |
| 474 | select ISA | 469 | select ISA |
| 475 | select NEED_MACH_MEMORY_H | 470 | select NEED_MACH_MEMORY_H |
| @@ -505,7 +500,6 @@ config ARCH_OMAP1 · 29 unmodified lines | |||
| 505 | select GENERIC_IRQ_CHIP | 500 | select GENERIC_IRQ_CHIP |
| 506 | select GENERIC_IRQ_MULTI_HANDLER | 501 | select GENERIC_IRQ_MULTI_HANDLER |
| 507 | select GPIOLIB | 502 | select GPIOLIB |
| 508 | select HAVE_IDE | ||
| 509 | select HAVE_LEGACY_CLK | 503 | select HAVE_LEGACY_CLK |
| 510 | select IRQ_DOMAIN | 504 | select IRQ_DOMAIN |
| 511 | select NEED_MACH_IO_H if PCCARD | 505 | select NEED_MACH_IO_H if PCCARD |
| @@ -9,7 +9,6 @@ menuconfig ARCH_DAVINCI · 8 unmodified lines | |||
| 9 | select PM_GENERIC_DOMAINS_OF if PM && OF | 9 | select PM_GENERIC_DOMAINS_OF if PM && OF |
| 10 | select REGMAP_MMIO | 10 | select REGMAP_MMIO |
| 11 | select RESET_CONTROLLER | 11 | select RESET_CONTROLLER |
| 12 | select HAVE_IDE | ||
| 13 | select PINCTRL_SINGLE | 12 | select PINCTRL_SINGLE |
| 14 | 13 | ||
| 15 | if ARCH_DAVINCI | 14 | if ARCH_DAVINCI |
| @@ -49,6 +49,7 @@ static int __init parse_tag_acorn(const struct tag *tag) · 48 unmodified lines | |||
| 49 | fallthrough; /* ??? */ | 49 | fallthrough; /* ??? */ |
| 50 | case 256: | 50 | case 256: |
| 51 | vram_size += PAGE_SIZE * 256; | 51 | vram_size += PAGE_SIZE * 256; |
| 52 | break; | ||
| 52 | default: | 53 | default: |
| 53 | break; | 54 | break; |
| 54 | } | 55 | } |
| @@ -1602,6 +1602,9 @@ exit: · 1601 unmodified lines | |||
| 1602 | rn = arm_bpf_get_reg32(src_lo, tmp2[1], ctx); | 1602 | rn = arm_bpf_get_reg32(src_lo, tmp2[1], ctx); |
| 1603 | emit_ldx_r(dst, rn, off, ctx, BPF_SIZE(code)); | 1603 | emit_ldx_r(dst, rn, off, ctx, BPF_SIZE(code)); |
| 1604 | break; | 1604 | break; |
| 1605 | /* speculation barrier */ | ||
| 1606 | case BPF_ST | BPF_NOSPEC: | ||
| 1607 | break; | ||
| 1605 | /* ST: *(size *)(dst + off) = imm */ | 1608 | /* ST: *(size *)(dst + off) = imm */ |
| 1606 | case BPF_ST | BPF_MEM | BPF_W: | 1609 | case BPF_ST | BPF_MEM | BPF_W: |
| 1607 | case BPF_ST | BPF_MEM | BPF_H: | 1610 | case BPF_ST | BPF_MEM | BPF_H: |
| @@ -579,7 +579,7 @@ · 578 unmodified lines | |||
| 579 | }; | 579 | }; |
| 580 | 580 | ||
| 581 | flexcan1: can@308c0000 { | 581 | flexcan1: can@308c0000 { |
| 582 | compatible = "fsl,imx8mp-flexcan", "fsl,imx6q-flexcan"; | 582 | compatible = "fsl,imx8mp-flexcan"; |
| 583 | reg = <0x308c0000 0x10000>; | 583 | reg = <0x308c0000 0x10000>; |
| 584 | interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; | 584 | interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; |
| 585 | clocks = <&clk IMX8MP_CLK_IPG_ROOT>, | 585 | clocks = <&clk IMX8MP_CLK_IPG_ROOT>, |
| @@ -594,7 +594,7 @@ · 8 unmodified lines | |||
| 594 | }; | 594 | }; |
| 595 | 595 | ||
| 596 | flexcan2: can@308d0000 { | 596 | flexcan2: can@308d0000 { |
| 597 | compatible = "fsl,imx8mp-flexcan", "fsl,imx6q-flexcan"; | 597 | compatible = "fsl,imx8mp-flexcan"; |
| 598 | reg = <0x308d0000 0x10000>; | 598 | reg = <0x308d0000 0x10000>; |
| 599 | interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; | 599 | interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; |
| 600 | clocks = <&clk IMX8MP_CLK_IPG_ROOT>, | 600 | clocks = <&clk IMX8MP_CLK_IPG_ROOT>, |
| @@ -821,9 +821,9 @@ · 220 unmodified lines | |||
| 821 | eqos: ethernet@30bf0000 { | 821 | eqos: ethernet@30bf0000 { |
| 822 | compatible = "nxp,imx8mp-dwmac-eqos", "snps,dwmac-5.10a"; | 822 | compatible = "nxp,imx8mp-dwmac-eqos", "snps,dwmac-5.10a"; |
| 823 | reg = <0x30bf0000 0x10000>; | 823 | reg = <0x30bf0000 0x10000>; |
| 824 | interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, | 824 | interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, |
| 825 | <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; | 825 | <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; |
| 826 | interrupt-names = "eth_wake_irq", "macirq"; | 826 | interrupt-names = "macirq", "eth_wake_irq"; |
| 827 | clocks = <&clk IMX8MP_CLK_ENET_QOS_ROOT>, | 827 | clocks = <&clk IMX8MP_CLK_ENET_QOS_ROOT>, |
| 828 | <&clk IMX8MP_CLK_QOS_ENET_ROOT>, | 828 | <&clk IMX8MP_CLK_QOS_ENET_ROOT>, |
| 829 | <&clk IMX8MP_CLK_ENET_QOS_TIMER>, | 829 | <&clk IMX8MP_CLK_ENET_QOS_TIMER>, |
| @@ -1063,7 +1063,7 @@ · 1062 unmodified lines | |||
| 1063 | status = "okay"; | 1063 | status = "okay"; |
| 1064 | extcon = <&usb2_id>; | 1064 | extcon = <&usb2_id>; |
| 1065 | 1065 | ||
| 1066 | usb@7600000 { | 1066 | dwc3@7600000 { |
| 1067 | extcon = <&usb2_id>; | 1067 | extcon = <&usb2_id>; |
| 1068 | dr_mode = "otg"; | 1068 | dr_mode = "otg"; |
| 1069 | maximum-speed = "high-speed"; | 1069 | maximum-speed = "high-speed"; |
| @@ -1074,7 +1074,7 @@ · 4 unmodified lines | |||
| 1074 | status = "okay"; | 1074 | status = "okay"; |
| 1075 | extcon = <&usb3_id>; | 1075 | extcon = <&usb3_id>; |
| 1076 | 1076 | ||
| 1077 | usb@6a00000 { | 1077 | dwc3@6a00000 { |
| 1078 | extcon = <&usb3_id>; | 1078 | extcon = <&usb3_id>; |
| 1079 | dr_mode = "otg"; | 1079 | dr_mode = "otg"; |
| 1080 | }; | 1080 | }; |
| @@ -443,7 +443,7 @@ · 442 unmodified lines | |||
| 443 | resets = <&gcc GCC_USB0_BCR>; | 443 | resets = <&gcc GCC_USB0_BCR>; |
| 444 | status = "disabled"; | 444 | status = "disabled"; |
| 445 | 445 | ||
| 446 | dwc_0: usb@8a00000 { | 446 | dwc_0: dwc3@8a00000 { |
| 447 | compatible = "snps,dwc3"; | 447 | compatible = "snps,dwc3"; |
| 448 | reg = <0x8a00000 0xcd00>; | 448 | reg = <0x8a00000 0xcd00>; |
| 449 | interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; | 449 | interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -484,7 +484,7 @@ · 34 unmodified lines | |||
| 484 | resets = <&gcc GCC_USB1_BCR>; | 484 | resets = <&gcc GCC_USB1_BCR>; |
| 485 | status = "disabled"; | 485 | status = "disabled"; |
| 486 | 486 | ||
| 487 | dwc_1: usb@8c00000 { | 487 | dwc_1: dwc3@8c00000 { |
| 488 | compatible = "snps,dwc3"; | 488 | compatible = "snps,dwc3"; |
| 489 | reg = <0x8c00000 0xcd00>; | 489 | reg = <0x8c00000 0xcd00>; |
| 490 | interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; | 490 | interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -2566,7 +2566,7 @@ · 2565 unmodified lines | |||
| 2566 | power-domains = <&gcc USB30_GDSC>; | 2566 | power-domains = <&gcc USB30_GDSC>; |
| 2567 | status = "disabled"; | 2567 | status = "disabled"; |
| 2568 | 2568 | ||
| 2569 | usb@6a00000 { | 2569 | dwc3@6a00000 { |
| 2570 | compatible = "snps,dwc3"; | 2570 | compatible = "snps,dwc3"; |
| 2571 | reg = <0x06a00000 0xcc00>; | 2571 | reg = <0x06a00000 0xcc00>; |
| 2572 | interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>; | 2572 | interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -2873,7 +2873,7 @@ · 300 unmodified lines | |||
| 2873 | qcom,select-utmi-as-pipe-clk; | 2873 | qcom,select-utmi-as-pipe-clk; |
| 2874 | status = "disabled"; | 2874 | status = "disabled"; |
| 2875 | 2875 | ||
| 2876 | usb@7600000 { | 2876 | dwc3@7600000 { |
| 2877 | compatible = "snps,dwc3"; | 2877 | compatible = "snps,dwc3"; |
| 2878 | reg = <0x07600000 0xcc00>; | 2878 | reg = <0x07600000 0xcc00>; |
| 2879 | interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>; | 2879 | interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -1964,7 +1964,7 @@ · 1963 unmodified lines | |||
| 1964 | 1964 | ||
| 1965 | resets = <&gcc GCC_USB_30_BCR>; | 1965 | resets = <&gcc GCC_USB_30_BCR>; |
| 1966 | 1966 | ||
| 1967 | usb3_dwc3: usb@a800000 { | 1967 | usb3_dwc3: dwc3@a800000 { |
| 1968 | compatible = "snps,dwc3"; | 1968 | compatible = "snps,dwc3"; |
| 1969 | reg = <0x0a800000 0xcd00>; | 1969 | reg = <0x0a800000 0xcd00>; |
| 1970 | interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; | 1970 | interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -337,7 +337,7 @@ · 336 unmodified lines | |||
| 337 | &usb3 { | 337 | &usb3 { |
| 338 | status = "okay"; | 338 | status = "okay"; |
| 339 | 339 | ||
| 340 | usb@7580000 { | 340 | dwc3@7580000 { |
| 341 | dr_mode = "host"; | 341 | dr_mode = "host"; |
| 342 | }; | 342 | }; |
| 343 | }; | 343 | }; |
| @@ -544,7 +544,7 @@ · 543 unmodified lines | |||
| 544 | assigned-clock-rates = <19200000>, <200000000>; | 544 | assigned-clock-rates = <19200000>, <200000000>; |
| 545 | status = "disabled"; | 545 | status = "disabled"; |
| 546 | 546 | ||
| 547 | usb@7580000 { | 547 | dwc3@7580000 { |
| 548 | compatible = "snps,dwc3"; | 548 | compatible = "snps,dwc3"; |
| 549 | reg = <0x07580000 0xcd00>; | 549 | reg = <0x07580000 0xcd00>; |
| 550 | interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; | 550 | interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -573,7 +573,7 @@ · 22 unmodified lines | |||
| 573 | assigned-clock-rates = <19200000>, <133333333>; | 573 | assigned-clock-rates = <19200000>, <133333333>; |
| 574 | status = "disabled"; | 574 | status = "disabled"; |
| 575 | 575 | ||
| 576 | usb@78c0000 { | 576 | dwc3@78c0000 { |
| 577 | compatible = "snps,dwc3"; | 577 | compatible = "snps,dwc3"; |
| 578 | reg = <0x078c0000 0xcc00>; | 578 | reg = <0x078c0000 0xcc00>; |
| 579 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; | 579 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -2756,7 +2756,7 @@ · 2755 unmodified lines | |||
| 2756 | <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3 0>; | 2756 | <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3 0>; |
| 2757 | interconnect-names = "usb-ddr", "apps-usb"; | 2757 | interconnect-names = "usb-ddr", "apps-usb"; |
| 2758 | 2758 | ||
| 2759 | usb_1_dwc3: usb@a600000 { | 2759 | usb_1_dwc3: dwc3@a600000 { |
| 2760 | compatible = "snps,dwc3"; | 2760 | compatible = "snps,dwc3"; |
| 2761 | reg = <0 0x0a600000 0 0xe000>; | 2761 | reg = <0 0x0a600000 0 0xe000>; |
| 2762 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; | 2762 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -3781,7 +3781,7 @@ · 3780 unmodified lines | |||
| 3781 | <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>; | 3781 | <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>; |
| 3782 | interconnect-names = "usb-ddr", "apps-usb"; | 3782 | interconnect-names = "usb-ddr", "apps-usb"; |
| 3783 | 3783 | ||
| 3784 | usb_1_dwc3: usb@a600000 { | 3784 | usb_1_dwc3: dwc3@a600000 { |
| 3785 | compatible = "snps,dwc3"; | 3785 | compatible = "snps,dwc3"; |
| 3786 | reg = <0 0x0a600000 0 0xcd00>; | 3786 | reg = <0 0x0a600000 0 0xcd00>; |
| 3787 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; | 3787 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -3829,7 +3829,7 @@ · 41 unmodified lines | |||
| 3829 | <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_1 0>; | 3829 | <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_1 0>; |
| 3830 | interconnect-names = "usb-ddr", "apps-usb"; | 3830 | interconnect-names = "usb-ddr", "apps-usb"; |
| 3831 | 3831 | ||
| 3832 | usb_2_dwc3: usb@a800000 { | 3832 | usb_2_dwc3: dwc3@a800000 { |
| 3833 | compatible = "snps,dwc3"; | 3833 | compatible = "snps,dwc3"; |
| 3834 | reg = <0 0x0a800000 0 0xcd00>; | 3834 | reg = <0 0x0a800000 0 0xcd00>; |
| 3835 | interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; | 3835 | interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -2344,7 +2344,7 @@ · 2343 unmodified lines | |||
| 2344 | 2344 | ||
| 2345 | resets = <&gcc GCC_USB30_PRIM_BCR>; | 2345 | resets = <&gcc GCC_USB30_PRIM_BCR>; |
| 2346 | 2346 | ||
| 2347 | usb_1_dwc3: usb@a600000 { | 2347 | usb_1_dwc3: dwc3@a600000 { |
| 2348 | compatible = "snps,dwc3"; | 2348 | compatible = "snps,dwc3"; |
| 2349 | reg = <0 0x0a600000 0 0xcd00>; | 2349 | reg = <0 0x0a600000 0 0xcd00>; |
| 2350 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; | 2350 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -602,14 +602,14 @@ static inline bool id_aa64pfr0_32bit_el1(u64 pfr0) · 601 unmodified lines | |||
| 602 | { | 602 | { |
| 603 | u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_SHIFT); | 603 | u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_SHIFT); |
| 604 | 604 | ||
| 605 | return val == ID_AA64PFR0_EL1_32BIT_64BIT; | 605 | return val == ID_AA64PFR0_ELx_32BIT_64BIT; |
| 606 | } | 606 | } |
| 607 | 607 | ||
| 608 | static inline bool id_aa64pfr0_32bit_el0(u64 pfr0) | 608 | static inline bool id_aa64pfr0_32bit_el0(u64 pfr0) |
| 609 | { | 609 | { |
| 610 | u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL0_SHIFT); | 610 | u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL0_SHIFT); |
| 611 | 611 | ||
| 612 | return val == ID_AA64PFR0_EL0_32BIT_64BIT; | 612 | return val == ID_AA64PFR0_ELx_32BIT_64BIT; |
| 613 | } | 613 | } |
| 614 | 614 | ||
| 615 | static inline bool id_aa64pfr0_sve(u64 pfr0) | 615 | static inline bool id_aa64pfr0_sve(u64 pfr0) |
| @@ -657,7 +657,8 @@ static inline bool system_supports_4kb_granule(void) · 41 unmodified lines | |||
| 657 | val = cpuid_feature_extract_unsigned_field(mmfr0, | 657 | val = cpuid_feature_extract_unsigned_field(mmfr0, |
| 658 | ID_AA64MMFR0_TGRAN4_SHIFT); | 658 | ID_AA64MMFR0_TGRAN4_SHIFT); |
| 659 | 659 | ||
| 660 | return val == ID_AA64MMFR0_TGRAN4_SUPPORTED; | 660 | return (val >= ID_AA64MMFR0_TGRAN4_SUPPORTED_MIN) && |
| 661 | (val <= ID_AA64MMFR0_TGRAN4_SUPPORTED_MAX); | ||
| 661 | } | 662 | } |
| 662 | 663 | ||
| 663 | static inline bool system_supports_64kb_granule(void) | 664 | static inline bool system_supports_64kb_granule(void) |
| @@ -669,7 +670,8 @@ static inline bool system_supports_64kb_granule(void) · 5 unmodified lines | |||
| 669 | val = cpuid_feature_extract_unsigned_field(mmfr0, | 670 | val = cpuid_feature_extract_unsigned_field(mmfr0, |
| 670 | ID_AA64MMFR0_TGRAN64_SHIFT); | 671 | ID_AA64MMFR0_TGRAN64_SHIFT); |
| 671 | 672 | ||
| 672 | return val == ID_AA64MMFR0_TGRAN64_SUPPORTED; | 673 | return (val >= ID_AA64MMFR0_TGRAN64_SUPPORTED_MIN) && |
| 674 | (val <= ID_AA64MMFR0_TGRAN64_SUPPORTED_MAX); | ||
| 673 | } | 675 | } |
| 674 | 676 | ||
| 675 | static inline bool system_supports_16kb_granule(void) | 677 | static inline bool system_supports_16kb_granule(void) |
| @@ -681,7 +683,8 @@ static inline bool system_supports_16kb_granule(void) · 5 unmodified lines | |||
| 681 | val = cpuid_feature_extract_unsigned_field(mmfr0, | 683 | val = cpuid_feature_extract_unsigned_field(mmfr0, |
| 682 | ID_AA64MMFR0_TGRAN16_SHIFT); | 684 | ID_AA64MMFR0_TGRAN16_SHIFT); |
| 683 | 685 | ||
| 684 | return val == ID_AA64MMFR0_TGRAN16_SUPPORTED; | 686 | return (val >= ID_AA64MMFR0_TGRAN16_SUPPORTED_MIN) && |
| 687 | (val <= ID_AA64MMFR0_TGRAN16_SUPPORTED_MAX); | ||
| 685 | } | 688 | } |
| 686 | 689 | ||
| 687 | static inline bool system_supports_mixed_endian_el0(void) | 690 | static inline bool system_supports_mixed_endian_el0(void) |
| @@ -781,13 +784,13 @@ extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt); · 93 unmodified lines | |||
| 781 | static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange) | 784 | static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange) |
| 782 | { | 785 | { |
| 783 | switch (parange) { | 786 | switch (parange) { |
| 784 | case 0: return 32; | 787 | case ID_AA64MMFR0_PARANGE_32: return 32; |
| 785 | case 1: return 36; | 788 | case ID_AA64MMFR0_PARANGE_36: return 36; |
| 786 | case 2: return 40; | 789 | case ID_AA64MMFR0_PARANGE_40: return 40; |
| 787 | case 3: return 42; | 790 | case ID_AA64MMFR0_PARANGE_42: return 42; |
| 788 | case 4: return 44; | 791 | case ID_AA64MMFR0_PARANGE_44: return 44; |
| 789 | case 5: return 48; | 792 | case ID_AA64MMFR0_PARANGE_48: return 48; |
| 790 | case 6: return 52; | 793 | case ID_AA64MMFR0_PARANGE_52: return 52; |
| 791 | /* | 794 | /* |
| 792 | * A future PE could use a value unknown to the kernel. | 795 | * A future PE could use a value unknown to the kernel. |
| 793 | * However, by the "D10.1.4 Principles of the ID scheme | 796 | * However, by the "D10.1.4 Principles of the ID scheme |
| @@ -12,8 +12,13 @@ · 11 unmodified lines | |||
| 12 | #include <asm/types.h> | 12 | #include <asm/types.h> |
| 13 | 13 | ||
| 14 | /* Hyp Configuration Register (HCR) bits */ | 14 | /* Hyp Configuration Register (HCR) bits */ |
| 15 | |||
| 16 | #define HCR_TID5 (UL(1) << 58) | ||
| 17 | #define HCR_DCT (UL(1) << 57) | ||
| 15 | #define HCR_ATA_SHIFT 56 | 18 | #define HCR_ATA_SHIFT 56 |
| 16 | #define HCR_ATA (UL(1) << HCR_ATA_SHIFT) | 19 | #define HCR_ATA (UL(1) << HCR_ATA_SHIFT) |
| 20 | #define HCR_AMVOFFEN (UL(1) << 51) | ||
| 21 | #define HCR_FIEN (UL(1) << 47) | ||
| 17 | #define HCR_FWB (UL(1) << 46) | 22 | #define HCR_FWB (UL(1) << 46) |
| 18 | #define HCR_API (UL(1) << 41) | 23 | #define HCR_API (UL(1) << 41) |
| 19 | #define HCR_APK (UL(1) << 40) | 24 | #define HCR_APK (UL(1) << 40) |
| @@ -32,9 +37,9 @@ · 12 unmodified lines | |||
| 32 | #define HCR_TVM (UL(1) << 26) | 37 | #define HCR_TVM (UL(1) << 26) |
| 33 | #define HCR_TTLB (UL(1) << 25) | 38 | #define HCR_TTLB (UL(1) << 25) |
| 34 | #define HCR_TPU (UL(1) << 24) | 39 | #define HCR_TPU (UL(1) << 24) |
| 35 | #define HCR_TPC (UL(1) << 23) | 40 | #define HCR_TPC (UL(1) << 23) /* HCR_TPCP if FEAT_DPB */ |
| 36 | #define HCR_TSW (UL(1) << 22) | 41 | #define HCR_TSW (UL(1) << 22) |
| 37 | #define HCR_TAC (UL(1) << 21) | 42 | #define HCR_TACR (UL(1) << 21) |
| 38 | #define HCR_TIDCP (UL(1) << 20) | 43 | #define HCR_TIDCP (UL(1) << 20) |
| 39 | #define HCR_TSC (UL(1) << 19) | 44 | #define HCR_TSC (UL(1) << 19) |
| 40 | #define HCR_TID3 (UL(1) << 18) | 45 | #define HCR_TID3 (UL(1) << 18) |
| @@ -56,12 +61,13 @@ · 15 unmodified lines | |||
| 56 | #define HCR_PTW (UL(1) << 2) | 61 | #define HCR_PTW (UL(1) << 2) |
| 57 | #define HCR_SWIO (UL(1) << 1) | 62 | #define HCR_SWIO (UL(1) << 1) |
| 58 | #define HCR_VM (UL(1) << 0) | 63 | #define HCR_VM (UL(1) << 0) |
| 64 | #define HCR_RES0 ((UL(1) << 48) | (UL(1) << 39)) | ||
| 59 | 65 | ||
| 60 | /* | 66 | /* |
| 61 | * The bits we set in HCR: | 67 | * The bits we set in HCR: |
| 62 | * TLOR: Trap LORegion register accesses | 68 | * TLOR: Trap LORegion register accesses |
| 63 | * RW: 64bit by default, can be overridden for 32bit VMs | 69 | * RW: 64bit by default, can be overridden for 32bit VMs |
| 64 | * TAC: Trap ACTLR | 70 | * TACR: Trap ACTLR |
| 65 | * TSC: Trap SMC | 71 | * TSC: Trap SMC |
| 66 | * TSW: Trap cache operations by set/way | 72 | * TSW: Trap cache operations by set/way |
| 67 | * TWE: Trap WFE | 73 | * TWE: Trap WFE |
| @@ -76,7 +82,7 @@ · 8 unmodified lines | |||
| 76 | * PTW: Take a stage2 fault if a stage1 walk steps in device memory | 82 | * PTW: Take a stage2 fault if a stage1 walk steps in device memory |
| 77 | */ | 83 | */ |
| 78 | #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ | 84 | #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ |
| 79 | HCR_BSU_IS | HCR_FB | HCR_TAC | \ | 85 | HCR_BSU_IS | HCR_FB | HCR_TACR | \ |
| 80 | HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \ | 86 | HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \ |
| 81 | HCR_FMO | HCR_IMO | HCR_PTW ) | 87 | HCR_FMO | HCR_IMO | HCR_PTW ) |
| 82 | #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF) | 88 | #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF) |
| @@ -275,24 +281,40 @@ · 192 unmodified lines | |||
| 275 | #define CPTR_EL2_TTA (1 << 20) | 281 | #define CPTR_EL2_TTA (1 << 20) |
| 276 | #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) | 282 | #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) |
| 277 | #define CPTR_EL2_TZ (1 << 8) | 283 | #define CPTR_EL2_TZ (1 << 8) |
| 278 | #define CPTR_EL2_RES1 0x000032ff /* known RES1 bits in CPTR_EL2 */ | 284 | #define CPTR_NVHE_EL2_RES1 0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */ |
| 279 | #define CPTR_EL2_DEFAULT CPTR_EL2_RES1 | 285 | #define CPTR_EL2_DEFAULT CPTR_NVHE_EL2_RES1 |
| 286 | #define CPTR_NVHE_EL2_RES0 (GENMASK(63, 32) | \ | ||
| 287 | GENMASK(29, 21) | \ | ||
| 288 | GENMASK(19, 14) | \ | ||
| 289 | BIT(11)) | ||
| 280 | 290 | ||
| 281 | /* Hyp Debug Configuration Register bits */ | 291 | /* Hyp Debug Configuration Register bits */ |
| 282 | #define MDCR_EL2_E2TB_MASK (UL(0x3)) | 292 | #define MDCR_EL2_E2TB_MASK (UL(0x3)) |
| 283 | #define MDCR_EL2_E2TB_SHIFT (UL(24)) | 293 | #define MDCR_EL2_E2TB_SHIFT (UL(24)) |
| 284 | #define MDCR_EL2_TTRF (1 << 19) | 294 | #define MDCR_EL2_HPMFZS (UL(1) << 36) |
| 285 | #define MDCR_EL2_TPMS (1 << 14) | 295 | #define MDCR_EL2_HPMFZO (UL(1) << 29) |
| 296 | #define MDCR_EL2_MTPME (UL(1) << 28) | ||
| 297 | #define MDCR_EL2_TDCC (UL(1) << 27) | ||
| 298 | #define MDCR_EL2_HCCD (UL(1) << 23) | ||
| 299 | #define MDCR_EL2_TTRF (UL(1) << 19) | ||
| 300 | #define MDCR_EL2_HPMD (UL(1) << 17) | ||
| 301 | #define MDCR_EL2_TPMS (UL(1) << 14) | ||
| 286 | #define MDCR_EL2_E2PB_MASK (UL(0x3)) | 302 | #define MDCR_EL2_E2PB_MASK (UL(0x3)) |
| 287 | #define MDCR_EL2_E2PB_SHIFT (UL(12)) | 303 | #define MDCR_EL2_E2PB_SHIFT (UL(12)) |
| 288 | #define MDCR_EL2_TDRA (1 << 11) | 304 | #define MDCR_EL2_TDRA (UL(1) << 11) |
| 289 | #define MDCR_EL2_TDOSA (1 << 10) | 305 | #define MDCR_EL2_TDOSA (UL(1) << 10) |
| 290 | #define MDCR_EL2_TDA (1 << 9) | 306 | #define MDCR_EL2_TDA (UL(1) << 9) |
| 291 | #define MDCR_EL2_TDE (1 << 8) | 307 | #define MDCR_EL2_TDE (UL(1) << 8) |
| 292 | #define MDCR_EL2_HPME (1 << 7) | 308 | #define MDCR_EL2_HPME (UL(1) << 7) |
| 293 | #define MDCR_EL2_TPM (1 << 6) | 309 | #define MDCR_EL2_TPM (UL(1) << 6) |
| 294 | #define MDCR_EL2_TPMCR (1 << 5) | 310 | #define MDCR_EL2_TPMCR (UL(1) << 5) |
| 295 | #define MDCR_EL2_HPMN_MASK (0x1F) | 311 | #define MDCR_EL2_HPMN_MASK (UL(0x1F)) |
| 312 | #define MDCR_EL2_RES0 (GENMASK(63, 37) | \ | ||
| 313 | GENMASK(35, 30) | \ | ||
| 314 | GENMASK(25, 24) | \ | ||
| 315 | GENMASK(22, 20) | \ | ||
| 316 | BIT(18) | \ | ||
| 317 | GENMASK(16, 15)) | ||
| 296 | 318 | ||
| 297 | /* For compatibility with fault code shared with 32-bit */ | 319 | /* For compatibility with fault code shared with 32-bit */ |
| 298 | #define FSC_FAULT ESR_ELx_FSC_FAULT | 320 | #define FSC_FAULT ESR_ELx_FSC_FAULT |
| @@ -59,12 +59,11 @@ · 58 unmodified lines | |||
| 59 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs 13 | 59 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs 13 |
| 60 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs 14 | 60 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs 14 |
| 61 | #define __KVM_HOST_SMCCC_FUNC___pkvm_init 15 | 61 | #define __KVM_HOST_SMCCC_FUNC___pkvm_init 15 |
| 62 | #define __KVM_HOST_SMCCC_FUNC___pkvm_create_mappings 16 | 62 | #define __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp 16 |
| 63 | #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping 17 | 63 | #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping 17 |
| 64 | #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector 18 | 64 | #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector 18 |
| 65 | #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize 19 | 65 | #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize 19 |
| 66 | #define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp 20 | 66 | #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 20 |
| 67 | #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 21 | ||
| 68 | 67 | ||
| 69 | #ifndef __ASSEMBLY__ | 68 | #ifndef __ASSEMBLY__ |
| 70 | 69 | ||
| @@ -210,7 +209,7 @@ extern u64 __vgic_v3_read_vmcr(void); · 139 unmodified lines | |||
| 210 | extern void __vgic_v3_write_vmcr(u32 vmcr); | 209 | extern void __vgic_v3_write_vmcr(u32 vmcr); |
| 211 | extern void __vgic_v3_init_lrs(void); | 210 | extern void __vgic_v3_init_lrs(void); |
| 212 | 211 | ||
| 213 | extern u32 __kvm_get_mdcr_el2(void); | 212 | extern u64 __kvm_get_mdcr_el2(void); |
| 214 | 213 | ||
| 215 | #define __KVM_EXTABLE(from, to) \ | 214 | #define __KVM_EXTABLE(from, to) \ |
| 216 | " .pushsection __kvm_ex_table, \"a\"\n" \ | 215 | " .pushsection __kvm_ex_table, \"a\"\n" \ |
| @@ -66,7 +66,7 @@ DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use); · 65 unmodified lines | |||
| 66 | extern unsigned int kvm_sve_max_vl; | 66 | extern unsigned int kvm_sve_max_vl; |
| 67 | int kvm_arm_init_sve(void); | 67 | int kvm_arm_init_sve(void); |
| 68 | 68 | ||
| 69 | int __attribute_const__ kvm_target_cpu(void); | 69 | u32 __attribute_const__ kvm_target_cpu(void); |
| 70 | int kvm_reset_vcpu(struct kvm_vcpu *vcpu); | 70 | int kvm_reset_vcpu(struct kvm_vcpu *vcpu); |
| 71 | void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu); | 71 | void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu); |
| 72 | 72 | ||
| @@ -185,7 +185,6 @@ enum vcpu_sysreg { · 112 unmodified lines | |||
| 185 | PMCNTENSET_EL0, /* Count Enable Set Register */ | 185 | PMCNTENSET_EL0, /* Count Enable Set Register */ |
| 186 | PMINTENSET_EL1, /* Interrupt Enable Set Register */ | 186 | PMINTENSET_EL1, /* Interrupt Enable Set Register */ |
| 187 | PMOVSSET_EL0, /* Overflow Flag Status Set Register */ | 187 | PMOVSSET_EL0, /* Overflow Flag Status Set Register */ |
| 188 | PMSWINC_EL0, /* Software Increment Register */ | ||
| 189 | PMUSERENR_EL0, /* User Enable Register */ | 188 | PMUSERENR_EL0, /* User Enable Register */ |
| 190 | 189 | ||
| 191 | /* Pointer Authentication Registers in a strict increasing order. */ | 190 | /* Pointer Authentication Registers in a strict increasing order. */ |
| @@ -287,9 +286,13 @@ struct kvm_vcpu_arch { · 95 unmodified lines | |||
| 287 | /* Stage 2 paging state used by the hardware on next switch */ | 286 | /* Stage 2 paging state used by the hardware on next switch */ |
| 288 | struct kvm_s2_mmu *hw_mmu; | 287 | struct kvm_s2_mmu *hw_mmu; |
| 289 | 288 | ||
| 290 | /* HYP configuration */ | 289 | /* Values of trap registers for the guest. */ |
| 291 | u64 hcr_el2; | 290 | u64 hcr_el2; |
| 292 | u32 mdcr_el2; | 291 | u64 mdcr_el2; |
| 292 | u64 cptr_el2; | ||
| 293 | |||
| 294 | /* Values of trap registers for the host before guest entry. */ | ||
| 295 | u64 mdcr_el2_host; | ||
| 293 | 296 | ||
| 294 | /* Exception Information */ | 297 | /* Exception Information */ |
| 295 | struct kvm_vcpu_fault_info fault; | 298 | struct kvm_vcpu_fault_info fault; |
| @@ -576,6 +579,7 @@ struct kvm_vcpu_stat { · 280 unmodified lines | |||
| 576 | u64 wfi_exit_stat; | 579 | u64 wfi_exit_stat; |
| 577 | u64 mmio_exit_user; | 580 | u64 mmio_exit_user; |
| 578 | u64 mmio_exit_kernel; | 581 | u64 mmio_exit_kernel; |
| 582 | u64 signal_exits; | ||
| 579 | u64 exits; | 583 | u64 exits; |
| 580 | }; | 584 | }; |
| 581 | 585 | ||
| @@ -771,6 +775,11 @@ void kvm_arch_free_vm(struct kvm *kvm); · 189 unmodified lines | |||
| 771 | 775 | ||
| 772 | int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type); | 776 | int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type); |
| 773 | 777 | ||
| 778 | static inline bool kvm_vm_is_protected(struct kvm *kvm) | ||
| 779 | { | ||
| 780 | return false; | ||
| 781 | } | ||
| 782 | |||
| 774 | int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature); | 783 | int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature); |
| 775 | bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); | 784 | bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); |
| 776 | 785 | ||
| @@ -95,7 +95,7 @@ void __sve_restore_state(void *sve_pffr, u32 *fpsr); · 94 unmodified lines | |||
| 95 | 95 | ||
| 96 | #ifndef __KVM_NVHE_HYPERVISOR__ | 96 | #ifndef __KVM_NVHE_HYPERVISOR__ |
| 97 | void activate_traps_vhe_load(struct kvm_vcpu *vcpu); | 97 | void activate_traps_vhe_load(struct kvm_vcpu *vcpu); |
| 98 | void deactivate_traps_vhe_put(void); | 98 | void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu); |
| 99 | #endif | 99 | #endif |
| 100 | 100 | ||
| 101 | u64 __guest_enter(struct kvm_vcpu *vcpu); | 101 | u64 __guest_enter(struct kvm_vcpu *vcpu); |
| @@ -252,6 +252,11 @@ static inline int kvm_write_guest_lock(struct kvm *kvm, gpa_t gpa, · 251 unmodified lines | |||
| 252 | 252 | ||
| 253 | #define kvm_phys_to_vttbr(addr) phys_to_ttbr(addr) | 253 | #define kvm_phys_to_vttbr(addr) phys_to_ttbr(addr) |
| 254 | 254 | ||
| 255 | /* | ||
| 256 | * When this is (directly or indirectly) used on the TLB invalidation | ||
| 257 | * path, we rely on a previously issued DSB so that page table updates | ||
| 258 | * and VMID reads are correctly ordered. | ||
| 259 | */ | ||
| 255 | static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu) | 260 | static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu) |
| 256 | { | 261 | { |
| 257 | struct kvm_vmid *vmid = &mmu->vmid; | 262 | struct kvm_vmid *vmid = &mmu->vmid; |
| @@ -259,7 +264,7 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu) · 1 unmodified line | |||
| 259 | u64 cnp = system_supports_cnp() ? VTTBR_CNP_BIT : 0; | 264 | u64 cnp = system_supports_cnp() ? VTTBR_CNP_BIT : 0; |
| 260 | 265 | ||
| 261 | baddr = mmu->pgd_phys; | 266 | baddr = mmu->pgd_phys; |
| 262 | vmid_field = (u64)vmid->vmid << VTTBR_VMID_SHIFT; | 267 | vmid_field = (u64)READ_ONCE(vmid->vmid) << VTTBR_VMID_SHIFT; |
| 263 | return kvm_phys_to_vttbr(baddr) | vmid_field | cnp; | 268 | return kvm_phys_to_vttbr(baddr) | vmid_field | cnp; |
| 264 | } | 269 | } |
| 265 | 270 | ||
| @@ -267,9 +272,10 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu) · 1 unmodified line | |||
| 267 | * Must be called from hyp code running at EL2 with an updated VTTBR | 272 | * Must be called from hyp code running at EL2 with an updated VTTBR |
| 268 | * and interrupts disabled. | 273 | * and interrupts disabled. |
| 269 | */ | 274 | */ |
| 270 | static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long vtcr) | 275 | static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, |
| 276 | struct kvm_arch *arch) | ||
| 271 | { | 277 | { |
| 272 | write_sysreg(vtcr, vtcr_el2); | 278 | write_sysreg(arch->vtcr, vtcr_el2); |
| 273 | write_sysreg(kvm_get_vttbr(mmu), vttbr_el2); | 279 | write_sysreg(kvm_get_vttbr(mmu), vttbr_el2); |
| 274 | 280 | ||
| 275 | /* | 281 | /* |
| @@ -280,11 +286,6 @@ static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long · 4 unmodified lines | |||
| 280 | asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT)); | 286 | asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT)); |
| 281 | } | 287 | } |
| 282 | 288 | ||
| 283 | static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu) | ||
| 284 | { | ||
| 285 | __load_stage2(mmu, kern_hyp_va(mmu->arch)->vtcr); | ||
| 286 | } | ||
| 287 | |||
| 288 | static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu) | 289 | static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu) |
| 289 | { | 290 | { |
| 290 | return container_of(mmu->arch, struct kvm, arch); | 291 | return container_of(mmu->arch, struct kvm, arch); |
| @@ -25,6 +25,46 @@ static inline u64 kvm_get_parange(u64 mmfr0) · 24 unmodified lines | |||
| 25 | 25 | ||
| 26 | typedef u64 kvm_pte_t; | 26 | typedef u64 kvm_pte_t; |
| 27 | 27 | ||
| 28 | #define KVM_PTE_VALID BIT(0) | ||
| 29 | |||
| 30 | #define KVM_PTE_ADDR_MASK GENMASK(47, PAGE_SHIFT) | ||
| 31 | #define KVM_PTE_ADDR_51_48 GENMASK(15, 12) | ||
| 32 | |||
| 33 | static inline bool kvm_pte_valid(kvm_pte_t pte) | ||
| 34 | { | ||
| 35 | return pte & KVM_PTE_VALID; | ||
| 36 | } | ||
| 37 | |||
| 38 | static inline u64 kvm_pte_to_phys(kvm_pte_t pte) | ||
| 39 | { | ||
| 40 | u64 pa = pte & KVM_PTE_ADDR_MASK; | ||
| 41 | |||
| 42 | if (PAGE_SHIFT == 16) | ||
| 43 | pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48; | ||
| 44 | |||
| 45 | return pa; | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline u64 kvm_granule_shift(u32 level) | ||
| 49 | { | ||
| 50 | /* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */ | ||
| 51 | return ARM64_HW_PGTABLE_LEVEL_SHIFT(level); | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline u64 kvm_granule_size(u32 level) | ||
| 55 | { | ||
| 56 | return BIT(kvm_granule_shift(level)); | ||
| 57 | } | ||
| 58 | |||
| 59 | static inline bool kvm_level_supports_block_mapping(u32 level) | ||
| 60 | { | ||
| 61 | /* | ||
| 62 | * Reject invalid block mappings and don't bother with 4TB mappings for | ||
| 63 | * 52-bit PAs. | ||
| 64 | */ | ||
| 65 | return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1)); | ||
| 66 | } | ||
| 67 | |||
| 28 | /** | 68 | /** |
| 29 | * struct kvm_pgtable_mm_ops - Memory management callbacks. | 69 | * struct kvm_pgtable_mm_ops - Memory management callbacks. |
| 30 | * @zalloc_page: Allocate a single zeroed memory page. | 70 | * @zalloc_page: Allocate a single zeroed memory page. |
| @@ -75,31 +115,16 @@ enum kvm_pgtable_stage2_flags { · 44 unmodified lines | |||
| 75 | KVM_PGTABLE_S2_IDMAP = BIT(1), | 115 | KVM_PGTABLE_S2_IDMAP = BIT(1), |
| 76 | }; | 116 | }; |
| 77 | 117 | ||
| 78 | /** | ||
| 79 | * struct kvm_pgtable - KVM page-table. | ||
| 80 | * @ia_bits: Maximum input address size, in bits. | ||
| 81 | * @start_level: Level at which the page-table walk starts. | ||
| 82 | * @pgd: Pointer to the first top-level entry of the page-table. | ||
| 83 | * @mm_ops: Memory management callbacks. | ||
| 84 | * @mmu: Stage-2 KVM MMU struct. Unused for stage-1 page-tables. | ||
| 85 | */ | ||
| 86 | struct kvm_pgtable { | ||
| 87 | u32 ia_bits; | ||
| 88 | u32 start_level; | ||
| 89 | kvm_pte_t *pgd; | ||
| 90 | struct kvm_pgtable_mm_ops *mm_ops; | ||
| 91 | |||
| 92 | /* Stage-2 only */ | ||
| 93 | struct kvm_s2_mmu *mmu; | ||
| 94 | enum kvm_pgtable_stage2_flags flags; | ||
| 95 | }; | ||
| 96 | |||
| 97 | /** | 118 | /** |
| 98 | * enum kvm_pgtable_prot - Page-table permissions and attributes. | 119 | * enum kvm_pgtable_prot - Page-table permissions and attributes. |
| 99 | * @KVM_PGTABLE_PROT_X: Execute permission. | 120 | * @KVM_PGTABLE_PROT_X: Execute permission. |
| 100 | * @KVM_PGTABLE_PROT_W: Write permission. | 121 | * @KVM_PGTABLE_PROT_W: Write permission. |
| 101 | * @KVM_PGTABLE_PROT_R: Read permission. | 122 | * @KVM_PGTABLE_PROT_R: Read permission. |
| 102 | * @KVM_PGTABLE_PROT_DEVICE: Device attributes. | 123 | * @KVM_PGTABLE_PROT_DEVICE: Device attributes. |
| 124 | * @KVM_PGTABLE_PROT_SW0: Software bit 0. | ||
| 125 | * @KVM_PGTABLE_PROT_SW1: Software bit 1. | ||
| 126 | * @KVM_PGTABLE_PROT_SW2: Software bit 2. | ||
| 127 | * @KVM_PGTABLE_PROT_SW3: Software bit 3. | ||
| 103 | */ | 128 | */ |
| 104 | enum kvm_pgtable_prot { | 129 | enum kvm_pgtable_prot { |
| 105 | KVM_PGTABLE_PROT_X = BIT(0), | 130 | KVM_PGTABLE_PROT_X = BIT(0), |
| @@ -107,21 +132,48 @@ enum kvm_pgtable_prot { · 1 unmodified line | |||
| 107 | KVM_PGTABLE_PROT_R = BIT(2), | 132 | KVM_PGTABLE_PROT_R = BIT(2), |
| 108 | 133 | ||
| 109 | KVM_PGTABLE_PROT_DEVICE = BIT(3), | 134 | KVM_PGTABLE_PROT_DEVICE = BIT(3), |
| 135 | |||
| 136 | KVM_PGTABLE_PROT_SW0 = BIT(55), | ||
| 137 | KVM_PGTABLE_PROT_SW1 = BIT(56), | ||
| 138 | KVM_PGTABLE_PROT_SW2 = BIT(57), | ||
| 139 | KVM_PGTABLE_PROT_SW3 = BIT(58), | ||
| 110 | }; | 140 | }; |
| 111 | 141 | ||
| 112 | #define PAGE_HYP (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W) | 142 | #define KVM_PGTABLE_PROT_RW (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W) |
| 143 | #define KVM_PGTABLE_PROT_RWX (KVM_PGTABLE_PROT_RW | KVM_PGTABLE_PROT_X) | ||
| 144 | |||
| 145 | #define PKVM_HOST_MEM_PROT KVM_PGTABLE_PROT_RWX | ||
| 146 | #define PKVM_HOST_MMIO_PROT KVM_PGTABLE_PROT_RW | ||
| 147 | |||
| 148 | #define PAGE_HYP KVM_PGTABLE_PROT_RW | ||
| 113 | #define PAGE_HYP_EXEC (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X) | 149 | #define PAGE_HYP_EXEC (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X) |
| 114 | #define PAGE_HYP_RO (KVM_PGTABLE_PROT_R) | 150 | #define PAGE_HYP_RO (KVM_PGTABLE_PROT_R) |
| 115 | #define PAGE_HYP_DEVICE (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE) | 151 | #define PAGE_HYP_DEVICE (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE) |
| 116 | 152 | ||
| 153 | typedef bool (*kvm_pgtable_force_pte_cb_t)(u64 addr, u64 end, | ||
| 154 | enum kvm_pgtable_prot prot); | ||
| 155 | |||
| 117 | /** | 156 | /** |
| 118 | * struct kvm_mem_range - Range of Intermediate Physical Addresses | 157 | * struct kvm_pgtable - KVM page-table. |
| 119 | * @start: Start of the range. | 158 | * @ia_bits: Maximum input address size, in bits. |
| 120 | * @end: End of the range. | 159 | * @start_level: Level at which the page-table walk starts. |
| 160 | * @pgd: Pointer to the first top-level entry of the page-table. | ||
| 161 | * @mm_ops: Memory management callbacks. | ||
| 162 | * @mmu: Stage-2 KVM MMU struct. Unused for stage-1 page-tables. | ||
| 163 | * @flags: Stage-2 page-table flags. | ||
| 164 | * @force_pte_cb: Function that returns true if page level mappings must | ||
| 165 | * be used instead of block mappings. | ||
| 121 | */ | 166 | */ |
| 122 | struct kvm_mem_range { | 167 | struct kvm_pgtable { |
| 123 | u64 start; | 168 | u32 ia_bits; |
| 124 | u64 end; | 169 | u32 start_level; |
| 170 | kvm_pte_t *pgd; | ||
| 171 | struct kvm_pgtable_mm_ops *mm_ops; | ||
| 172 | |||
| 173 | /* Stage-2 only */ | ||
| 174 | struct kvm_s2_mmu *mmu; | ||
| 175 | enum kvm_pgtable_stage2_flags flags; | ||
| 176 | kvm_pgtable_force_pte_cb_t force_pte_cb; | ||
| 125 | }; | 177 | }; |
| 126 | 178 | ||
| 127 | /** | 179 | /** |
| @@ -216,21 +268,24 @@ int kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys, · 88 unmodified lines | |||
| 216 | u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift); | 268 | u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift); |
| 217 | 269 | ||
| 218 | /** | 270 | /** |
| 219 | * kvm_pgtable_stage2_init_flags() - Initialise a guest stage-2 page-table. | 271 | * __kvm_pgtable_stage2_init() - Initialise a guest stage-2 page-table. |
| 220 | * @pgt: Uninitialised page-table structure to initialise. | 272 | * @pgt: Uninitialised page-table structure to initialise. |
| 221 | * @arch: Arch-specific KVM structure representing the guest virtual | 273 | * @arch: Arch-specific KVM structure representing the guest virtual |
| 222 | * machine. | 274 | * machine. |
| 223 | * @mm_ops: Memory management callbacks. | 275 | * @mm_ops: Memory management callbacks. |
| 224 | * @flags: Stage-2 configuration flags. | 276 | * @flags: Stage-2 configuration flags. |
| 277 | * @force_pte_cb: Function that returns true if page level mappings must | ||
| 278 | * be used instead of block mappings. | ||
| 225 | * | 279 | * |
| 226 | * Return: 0 on success, negative error code on failure. | 280 | * Return: 0 on success, negative error code on failure. |
| 227 | */ | 281 | */ |
| 228 | int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch, | 282 | int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch, |
| 229 | struct kvm_pgtable_mm_ops *mm_ops, | 283 | struct kvm_pgtable_mm_ops *mm_ops, |
| 230 | enum kvm_pgtable_stage2_flags flags); | 284 | enum kvm_pgtable_stage2_flags flags, |
| 285 | kvm_pgtable_force_pte_cb_t force_pte_cb); | ||
| 231 | 286 | ||
| 232 | #define kvm_pgtable_stage2_init(pgt, arch, mm_ops) \ | 287 | #define kvm_pgtable_stage2_init(pgt, arch, mm_ops) \ |
| 233 | kvm_pgtable_stage2_init_flags(pgt, arch, mm_ops, 0) | 288 | __kvm_pgtable_stage2_init(pgt, arch, mm_ops, 0, NULL) |
| 234 | 289 | ||
| 235 | /** | 290 | /** |
| 236 | * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table. | 291 | * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table. |
| @@ -374,7 +429,8 @@ kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr); · 137 unmodified lines | |||
| 374 | * If there is a valid, leaf page-table entry used to translate @addr, then | 429 | * If there is a valid, leaf page-table entry used to translate @addr, then |
| 375 | * relax the permissions in that entry according to the read, write and | 430 | * relax the permissions in that entry according to the read, write and |
| 376 | * execute permissions specified by @prot. No permissions are removed, and | 431 | * execute permissions specified by @prot. No permissions are removed, and |
| 377 | * TLB invalidation is performed after updating the entry. | 432 | * TLB invalidation is performed after updating the entry. Software bits cannot |
| 433 | * be set or cleared using kvm_pgtable_stage2_relax_perms(). | ||
| 378 | * | 434 | * |
| 379 | * Return: 0 on success, negative error code on failure. | 435 | * Return: 0 on success, negative error code on failure. |
| 380 | */ | 436 | */ |
| @@ -433,22 +489,42 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, · 52 unmodified lines | |||
| 433 | struct kvm_pgtable_walker *walker); | 489 | struct kvm_pgtable_walker *walker); |
| 434 | 490 | ||
| 435 | /** | 491 | /** |
| 436 | * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical | 492 | * kvm_pgtable_get_leaf() - Walk a page-table and retrieve the leaf entry |
| 437 | * Addresses with compatible permission | 493 | * with its level. |
| 438 | * attributes. | 494 | * @pgt: Page-table structure initialised by kvm_pgtable_*_init() |
| 439 | * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*(). | 495 | * or a similar initialiser. |
| 440 | * @addr: Address that must be covered by the range. | 496 | * @addr: Input address for the start of the walk. |
| 441 | * @prot: Protection attributes that the range must be compatible with. | 497 | * @ptep: Pointer to storage for the retrieved PTE. |
| 442 | * @range: Range structure used to limit the search space at call time and | 498 | * @level: Pointer to storage for the level of the retrieved PTE. |
| 443 | * that will hold the result. | 499 | * |
| 500 | * The offset of @addr within a page is ignored. | ||
| 444 | * | 501 | * |
| 445 | * The offset of @addr within a page is ignored. An IPA is compatible with @prot | 502 | * The walker will walk the page-table entries corresponding to the input |
| 446 | * iff its corresponding stage-2 page-table entry has default ownership and, if | 503 | * address specified, retrieving the leaf corresponding to this address. |
| 447 | * valid, is mapped with protection attributes identical to @prot. | 504 | * Invalid entries are treated as leaf entries. |
| 448 | * | 505 | * |
| 449 | * Return: 0 on success, negative error code on failure. | 506 | * Return: 0 on success, negative error code on failure. |
| 450 | */ | 507 | */ |
| 451 | int kvm_pgtable_stage2_find_range(struct kvm_pgtable *pgt, u64 addr, | 508 | int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, |
| 452 | enum kvm_pgtable_prot prot, | 509 | kvm_pte_t *ptep, u32 *level); |
| 453 | struct kvm_mem_range *range); | 510 | |
| 511 | /** | ||
| 512 | * kvm_pgtable_stage2_pte_prot() - Retrieve the protection attributes of a | ||
| 513 | * stage-2 Page-Table Entry. | ||
| 514 | * @pte: Page-table entry | ||
| 515 | * | ||
| 516 | * Return: protection attributes of the page-table entry in the enum | ||
| 517 | * kvm_pgtable_prot format. | ||
| 518 | */ | ||
| 519 | enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte); | ||
| 520 | |||
| 521 | /** | ||
| 522 | * kvm_pgtable_hyp_pte_prot() - Retrieve the protection attributes of a stage-1 | ||
| 523 | * Page-Table Entry. | ||
| 524 | * @pte: Page-table entry | ||
| 525 | * | ||
| 526 | * Return: protection attributes of the page-table entry in the enum | ||
| 527 | * kvm_pgtable_prot format. | ||
| 528 | */ | ||
| 529 | enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte); | ||
| 454 | #endif /* __ARM64_KVM_PGTABLE_H__ */ | 530 | #endif /* __ARM64_KVM_PGTABLE_H__ */ |
| @@ -784,14 +784,13 @@ · 783 unmodified lines | |||
| 784 | #define ID_AA64PFR0_AMU 0x1 | 784 | #define ID_AA64PFR0_AMU 0x1 |
| 785 | #define ID_AA64PFR0_SVE 0x1 | 785 | #define ID_AA64PFR0_SVE 0x1 |
| 786 | #define ID_AA64PFR0_RAS_V1 0x1 | 786 | #define ID_AA64PFR0_RAS_V1 0x1 |
| 787 | #define ID_AA64PFR0_RAS_V1P1 0x2 | ||
| 787 | #define ID_AA64PFR0_FP_NI 0xf | 788 | #define ID_AA64PFR0_FP_NI 0xf |
| 788 | #define ID_AA64PFR0_FP_SUPPORTED 0x0 | 789 | #define ID_AA64PFR0_FP_SUPPORTED 0x0 |
| 789 | #define ID_AA64PFR0_ASIMD_NI 0xf | 790 | #define ID_AA64PFR0_ASIMD_NI 0xf |
| 790 | #define ID_AA64PFR0_ASIMD_SUPPORTED 0x0 | 791 | #define ID_AA64PFR0_ASIMD_SUPPORTED 0x0 |
| 791 | #define ID_AA64PFR0_EL1_64BIT_ONLY 0x1 | 792 | #define ID_AA64PFR0_ELx_64BIT_ONLY 0x1 |
| 792 | #define ID_AA64PFR0_EL1_32BIT_64BIT 0x2 | 793 | #define ID_AA64PFR0_ELx_32BIT_64BIT 0x2 |
| 793 | #define ID_AA64PFR0_EL0_64BIT_ONLY 0x1 | ||
| 794 | #define ID_AA64PFR0_EL0_32BIT_64BIT 0x2 | ||
| 795 | 794 | ||
| 796 | /* id_aa64pfr1 */ | 795 | /* id_aa64pfr1 */ |
| 797 | #define ID_AA64PFR1_MPAMFRAC_SHIFT 16 | 796 | #define ID_AA64PFR1_MPAMFRAC_SHIFT 16 |
| @@ -847,15 +846,29 @@ · 49 unmodified lines | |||
| 847 | #define ID_AA64MMFR0_ASID_SHIFT 4 | 846 | #define ID_AA64MMFR0_ASID_SHIFT 4 |
| 848 | #define ID_AA64MMFR0_PARANGE_SHIFT 0 | 847 | #define ID_AA64MMFR0_PARANGE_SHIFT 0 |
| 849 | 848 | ||
| 850 | #define ID_AA64MMFR0_TGRAN4_NI 0xf | 849 | #define ID_AA64MMFR0_ASID_8 0x0 |
| 851 | #define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0 | 850 | #define ID_AA64MMFR0_ASID_16 0x2 |
| 852 | #define ID_AA64MMFR0_TGRAN64_NI 0xf | 851 | |
| 853 | #define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0 | 852 | #define ID_AA64MMFR0_TGRAN4_NI 0xf |
| 854 | #define ID_AA64MMFR0_TGRAN16_NI 0x0 | 853 | #define ID_AA64MMFR0_TGRAN4_SUPPORTED_MIN 0x0 |
| 855 | #define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1 | 854 | #define ID_AA64MMFR0_TGRAN4_SUPPORTED_MAX 0x7 |
| 855 | #define ID_AA64MMFR0_TGRAN64_NI 0xf | ||
| 856 | #define ID_AA64MMFR0_TGRAN64_SUPPORTED_MIN 0x0 | ||
| 857 | #define ID_AA64MMFR0_TGRAN64_SUPPORTED_MAX 0x7 | ||
| 858 | #define ID_AA64MMFR0_TGRAN16_NI 0x0 | ||
| 859 | #define ID_AA64MMFR0_TGRAN16_SUPPORTED_MIN 0x1 | ||
| 860 | #define ID_AA64MMFR0_TGRAN16_SUPPORTED_MAX 0xf | ||
| 861 | |||
| 862 | #define ID_AA64MMFR0_PARANGE_32 0x0 | ||
| 863 | #define ID_AA64MMFR0_PARANGE_36 0x1 | ||
| 864 | #define ID_AA64MMFR0_PARANGE_40 0x2 | ||
| 865 | #define ID_AA64MMFR0_PARANGE_42 0x3 | ||
| 866 | #define ID_AA64MMFR0_PARANGE_44 0x4 | ||
| 856 | #define ID_AA64MMFR0_PARANGE_48 0x5 | 867 | #define ID_AA64MMFR0_PARANGE_48 0x5 |
| 857 | #define ID_AA64MMFR0_PARANGE_52 0x6 | 868 | #define ID_AA64MMFR0_PARANGE_52 0x6 |
| 858 | 869 | ||
| 870 | #define ARM64_MIN_PARANGE_BITS 32 | ||
| 871 | |||
| 859 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_DEFAULT 0x0 | 872 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_DEFAULT 0x0 |
| 860 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE 0x1 | 873 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE 0x1 |
| 861 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_MIN 0x2 | 874 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_MIN 0x2 |
| @@ -900,6 +913,7 @@ · 38 unmodified lines | |||
| 900 | #define ID_AA64MMFR2_CNP_SHIFT 0 | 913 | #define ID_AA64MMFR2_CNP_SHIFT 0 |
| 901 | 914 | ||
| 902 | /* id_aa64dfr0 */ | 915 | /* id_aa64dfr0 */ |
| 916 | #define ID_AA64DFR0_MTPMU_SHIFT 48 | ||
| 903 | #define ID_AA64DFR0_TRBE_SHIFT 44 | 917 | #define ID_AA64DFR0_TRBE_SHIFT 44 |
| 904 | #define ID_AA64DFR0_TRACE_FILT_SHIFT 40 | 918 | #define ID_AA64DFR0_TRACE_FILT_SHIFT 40 |
| 905 | #define ID_AA64DFR0_DOUBLELOCK_SHIFT 36 | 919 | #define ID_AA64DFR0_DOUBLELOCK_SHIFT 36 |
| @@ -1028,16 +1042,19 @@ · 122 unmodified lines | |||
| 1028 | 1042 | ||
| 1029 | #if defined(CONFIG_ARM64_4K_PAGES) | 1043 | #if defined(CONFIG_ARM64_4K_PAGES) |
| 1030 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN4_SHIFT | 1044 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN4_SHIFT |
| 1031 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN4_SUPPORTED | 1045 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN4_SUPPORTED_MIN |
| 1032 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0x7 | 1046 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX ID_AA64MMFR0_TGRAN4_SUPPORTED_MAX |
| 1047 | #define ID_AA64MMFR0_TGRAN_2_SHIFT ID_AA64MMFR0_TGRAN4_2_SHIFT | ||
| 1033 | #elif defined(CONFIG_ARM64_16K_PAGES) | 1048 | #elif defined(CONFIG_ARM64_16K_PAGES) |
| 1034 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN16_SHIFT | 1049 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN16_SHIFT |
| 1035 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN16_SUPPORTED | 1050 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN16_SUPPORTED_MIN |
| 1036 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0xF | 1051 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX ID_AA64MMFR0_TGRAN16_SUPPORTED_MAX |
| 1052 | #define ID_AA64MMFR0_TGRAN_2_SHIFT ID_AA64MMFR0_TGRAN16_2_SHIFT | ||
| 1037 | #elif defined(CONFIG_ARM64_64K_PAGES) | 1053 | #elif defined(CONFIG_ARM64_64K_PAGES) |
| 1038 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN64_SHIFT | 1054 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN64_SHIFT |
| 1039 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN64_SUPPORTED | 1055 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN64_SUPPORTED_MIN |
| 1040 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0x7 | 1056 | #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX ID_AA64MMFR0_TGRAN64_SUPPORTED_MAX |
| 1057 | #define ID_AA64MMFR0_TGRAN_2_SHIFT ID_AA64MMFR0_TGRAN64_2_SHIFT | ||
| 1041 | #endif | 1058 | #endif |
| 1042 | 1059 | ||
| 1043 | #define MVFR2_FPMISC_SHIFT 4 | 1060 | #define MVFR2_FPMISC_SHIFT 4 |
| @@ -1153,6 +1170,11 @@ · 109 unmodified lines | |||
| 1153 | #define ICH_VTR_A3V_SHIFT 21 | 1170 | #define ICH_VTR_A3V_SHIFT 21 |
| 1154 | #define ICH_VTR_A3V_MASK (1 << ICH_VTR_A3V_SHIFT) | 1171 | #define ICH_VTR_A3V_MASK (1 << ICH_VTR_A3V_SHIFT) |
| 1155 | 1172 | ||
| 1173 | #define ARM64_FEATURE_FIELD_BITS 4 | ||
| 1174 | |||
| 1175 | /* Create a mask for the feature bits of the specified feature. */ | ||
| 1176 | #define ARM64_FEATURE_MASK(x) (GENMASK_ULL(x##_SHIFT + ARM64_FEATURE_FIELD_BITS - 1, x##_SHIFT)) | ||
| 1177 | |||
| 1156 | #ifdef __ASSEMBLY__ | 1178 | #ifdef __ASSEMBLY__ |
| 1157 | 1179 | ||
| 1158 | .irp num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 | 1180 | .irp num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 |
| @@ -239,8 +239,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { · 238 unmodified lines | |||
| 239 | S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI), | 239 | S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI), |
| 240 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL3_SHIFT, 4, 0), | 240 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL3_SHIFT, 4, 0), |
| 241 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL2_SHIFT, 4, 0), | 241 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL2_SHIFT, 4, 0), |
| 242 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_SHIFT, 4, ID_AA64PFR0_EL1_64BIT_ONLY), | 242 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_SHIFT, 4, ID_AA64PFR0_ELx_64BIT_ONLY), |
| 243 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_EL0_64BIT_ONLY), | 243 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_ELx_64BIT_ONLY), |
| 244 | ARM64_FTR_END, | 244 | ARM64_FTR_END, |
| 245 | }; | 245 | }; |
| 246 | 246 | ||
| @@ -1956,7 +1956,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { · 1709 unmodified lines | |||
| 1956 | .sys_reg = SYS_ID_AA64PFR0_EL1, | 1956 | .sys_reg = SYS_ID_AA64PFR0_EL1, |
| 1957 | .sign = FTR_UNSIGNED, | 1957 | .sign = FTR_UNSIGNED, |
| 1958 | .field_pos = ID_AA64PFR0_EL0_SHIFT, | 1958 | .field_pos = ID_AA64PFR0_EL0_SHIFT, |
| 1959 | .min_field_value = ID_AA64PFR0_EL0_32BIT_64BIT, | 1959 | .min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT, |
| 1960 | }, | 1960 | }, |
| 1961 | #ifdef CONFIG_KVM | 1961 | #ifdef CONFIG_KVM |
| 1962 | { | 1962 | { |
| @@ -1967,7 +1967,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { · 4 unmodified lines | |||
| 1967 | .sys_reg = SYS_ID_AA64PFR0_EL1, | 1967 | .sys_reg = SYS_ID_AA64PFR0_EL1, |
| 1968 | .sign = FTR_UNSIGNED, | 1968 | .sign = FTR_UNSIGNED, |
| 1969 | .field_pos = ID_AA64PFR0_EL1_SHIFT, | 1969 | .field_pos = ID_AA64PFR0_EL1_SHIFT, |
| 1970 | .min_field_value = ID_AA64PFR0_EL1_32BIT_64BIT, | 1970 | .min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT, |
| 1971 | }, | 1971 | }, |
| 1972 | { | 1972 | { |
| 1973 | .desc = "Protected KVM", | 1973 | .desc = "Protected KVM", |
| @@ -32,20 +32,23 @@ SYM_FUNC_END(__arm_smccc_sve_check) · 31 unmodified lines | |||
| 32 | EXPORT_SYMBOL(__arm_smccc_sve_check) | 32 | EXPORT_SYMBOL(__arm_smccc_sve_check) |
| 33 | 33 | ||
| 34 | .macro SMCCC instr | 34 | .macro SMCCC instr |
| 35 | stp x29, x30, [sp, #-16]! | ||
| 36 | mov x29, sp | ||
| 35 | alternative_if ARM64_SVE | 37 | alternative_if ARM64_SVE |
| 36 | bl __arm_smccc_sve_check | 38 | bl __arm_smccc_sve_check |
| 37 | alternative_else_nop_endif | 39 | alternative_else_nop_endif |
| 38 | \instr #0 | 40 | \instr #0 |
| 39 | ldr x4, [sp] | 41 | ldr x4, [sp, #16] |
| 40 | stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] | 42 | stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] |
| 41 | stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] | 43 | stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] |
| 42 | ldr x4, [sp, #8] | 44 | ldr x4, [sp, #24] |
| 43 | cbz x4, 1f /* no quirk structure */ | 45 | cbz x4, 1f /* no quirk structure */ |
| 44 | ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] | 46 | ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] |
| 45 | cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 | 47 | cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 |
| 46 | b.ne 1f | 48 | b.ne 1f |
| 47 | str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] | 49 | str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] |
| 48 | 1: ret | 50 | 1: ldp x29, x30, [sp], #16 |
| 51 | ret | ||
| 49 | .endm | 52 | .endm |
| 50 | 53 | ||
| 51 | /* | 54 | /* |
| @@ -181,6 +181,8 @@ SECTIONS · 180 unmodified lines | |||
| 181 | /* everything from this point to __init_begin will be marked RO NX */ | 181 | /* everything from this point to __init_begin will be marked RO NX */ |
| 182 | RO_DATA(PAGE_SIZE) | 182 | RO_DATA(PAGE_SIZE) |
| 183 | 183 | ||
| 184 | HYPERVISOR_DATA_SECTIONS | ||
| 185 | |||
| 184 | idmap_pg_dir = .; | 186 | idmap_pg_dir = .; |
| 185 | . += IDMAP_DIR_SIZE; | 187 | . += IDMAP_DIR_SIZE; |
| 186 | idmap_pg_end = .; | 188 | idmap_pg_end = .; |
| @@ -260,8 +262,6 @@ SECTIONS · 73 unmodified lines | |||
| 260 | _sdata = .; | 262 | _sdata = .; |
| 261 | RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) | 263 | RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) |
| 262 | 264 | ||
| 263 | HYPERVISOR_DATA_SECTIONS | ||
| 264 | |||
| 265 | /* | 265 | /* |
| 266 | * Data written with the MMU off but read with the MMU on requires | 266 | * Data written with the MMU off but read with the MMU on requires |
| 267 | * cache lines to be invalidated, discarding up to a Cache Writeback | 267 | * cache lines to be invalidated, discarding up to a Cache Writeback |
| @@ -26,6 +26,7 @@ menuconfig KVM · 25 unmodified lines | |||
| 26 | select HAVE_KVM_ARCH_TLB_FLUSH_ALL | 26 | select HAVE_KVM_ARCH_TLB_FLUSH_ALL |
| 27 | select KVM_MMIO | 27 | select KVM_MMIO |
| 28 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT | 28 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT |
| 29 | select KVM_XFER_TO_GUEST_WORK | ||
| 29 | select SRCU | 30 | select SRCU |
| 30 | select KVM_VFIO | 31 | select KVM_VFIO |
| 31 | select HAVE_KVM_EVENTFD | 32 | select HAVE_KVM_EVENTFD |
| @@ -46,6 +47,15 @@ if KVM · 14 unmodified lines | |||
| 46 | 47 | ||
| 47 | source "virt/kvm/Kconfig" | 48 | source "virt/kvm/Kconfig" |
| 48 | 49 | ||
| 50 | config NVHE_EL2_DEBUG | ||
| 51 | bool "Debug mode for non-VHE EL2 object" | ||
| 52 | help | ||
| 53 | Say Y here to enable the debug mode for the non-VHE KVM EL2 object. | ||
| 54 | Failure reports will BUG() in the hypervisor. This is intended for | ||
| 55 | local EL2 hypervisor development. | ||
| 56 | |||
| 57 | If unsure, say N. | ||
| 58 | |||
| 49 | endif # KVM | 59 | endif # KVM |
| 50 | 60 | ||
| 51 | endif # VIRTUALIZATION | 61 | endif # VIRTUALIZATION |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #include <linux/bug.h> | 7 | #include <linux/bug.h> |
| 8 | #include <linux/cpu_pm.h> | 8 | #include <linux/cpu_pm.h> |
| 9 | #include <linux/entry-kvm.h> | ||
| 9 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
| 10 | #include <linux/err.h> | 11 | #include <linux/err.h> |
| 11 | #include <linux/kvm_host.h> | 12 | #include <linux/kvm_host.h> |
| @@ -15,6 +16,7 @@ · 3 unmodified lines | |||
| 15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
| 16 | #include <linux/mman.h> | 17 | #include <linux/mman.h> |
| 17 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
| 19 | #include <linux/kmemleak.h> | ||
| 18 | #include <linux/kvm.h> | 20 | #include <linux/kvm.h> |
| 19 | #include <linux/kvm_irqfd.h> | 21 | #include <linux/kvm_irqfd.h> |
| 20 | #include <linux/irqbypass.h> | 22 | #include <linux/irqbypass.h> |
| @@ -42,10 +44,6 @@ · 21 unmodified lines | |||
| 42 | #include <kvm/arm_pmu.h> | 44 | #include <kvm/arm_pmu.h> |
| 43 | #include <kvm/arm_psci.h> | 45 | #include <kvm/arm_psci.h> |
| 44 | 46 | ||
| 45 | #ifdef REQUIRES_VIRT | ||
| 46 | __asm__(".arch_extension virt"); | ||
| 47 | #endif | ||
| 48 | |||
| 49 | static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT; | 47 | static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT; |
| 50 | DEFINE_STATIC_KEY_FALSE(kvm_protected_mode_initialized); | 48 | DEFINE_STATIC_KEY_FALSE(kvm_protected_mode_initialized); |
| 51 | 49 | ||
| @@ -94,10 +92,14 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, · 42 unmodified lines | |||
| 94 | kvm->arch.return_nisv_io_abort_to_user = true; | 92 | kvm->arch.return_nisv_io_abort_to_user = true; |
| 95 | break; | 93 | break; |
| 96 | case KVM_CAP_ARM_MTE: | 94 | case KVM_CAP_ARM_MTE: |
| 97 | if (!system_supports_mte() || kvm->created_vcpus) | 95 | mutex_lock(&kvm->lock); |
| 98 | return -EINVAL; | 96 | if (!system_supports_mte() || kvm->created_vcpus) { |
| 99 | r = 0; | 97 | r = -EINVAL; |
| 100 | kvm->arch.mte_enabled = true; | 98 | } else { |
| 99 | r = 0; | ||
| 100 | kvm->arch.mte_enabled = true; | ||
| 101 | } | ||
| 102 | mutex_unlock(&kvm->lock); | ||
| 101 | break; | 103 | break; |
| 102 | default: | 104 | default: |
| 103 | r = -EINVAL; | 105 | r = -EINVAL; |
| @@ -571,7 +573,7 @@ static void update_vmid(struct kvm_vmid *vmid) · 467 unmodified lines | |||
| 571 | kvm_call_hyp(__kvm_flush_vm_context); | 573 | kvm_call_hyp(__kvm_flush_vm_context); |
| 572 | } | 574 | } |
| 573 | 575 | ||
| 574 | vmid->vmid = kvm_next_vmid; | 576 | WRITE_ONCE(vmid->vmid, kvm_next_vmid); |
| 575 | kvm_next_vmid++; | 577 | kvm_next_vmid++; |
| 576 | kvm_next_vmid &= (1 << kvm_get_vmid_bits()) - 1; | 578 | kvm_next_vmid &= (1 << kvm_get_vmid_bits()) - 1; |
| 577 | 579 | ||
| @@ -714,6 +716,45 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu) · 136 unmodified lines | |||
| 714 | static_branch_unlikely(&arm64_mismatched_32bit_el0); | 716 | static_branch_unlikely(&arm64_mismatched_32bit_el0); |
| 715 | } | 717 | } |
| 716 | 718 | ||
| 719 | /** | ||
| 720 | * kvm_vcpu_exit_request - returns true if the VCPU should *not* enter the guest | ||
| 721 | * @vcpu: The VCPU pointer | ||
| 722 | * @ret: Pointer to write optional return code | ||
| 723 | * | ||
| 724 | * Returns: true if the VCPU needs to return to a preemptible + interruptible | ||
| 725 | * and skip guest entry. | ||
| 726 | * | ||
| 727 | * This function disambiguates between two different types of exits: exits to a | ||
| 728 | * preemptible + interruptible kernel context and exits to userspace. For an | ||
| 729 | * exit to userspace, this function will write the return code to ret and return | ||
| 730 | * true. For an exit to preemptible + interruptible kernel context (i.e. check | ||
| 731 | * for pending work and re-enter), return true without writing to ret. | ||
| 732 | */ | ||
| 733 | static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret) | ||
| 734 | { | ||
| 735 | struct kvm_run *run = vcpu->run; | ||
| 736 | |||
| 737 | /* | ||
| 738 | * If we're using a userspace irqchip, then check if we need | ||
| 739 | * to tell a userspace irqchip about timer or PMU level | ||
| 740 | * changes and if so, exit to userspace (the actual level | ||
| 741 | * state gets updated in kvm_timer_update_run and | ||
| 742 | * kvm_pmu_update_run below). | ||
| 743 | */ | ||
| 744 | if (static_branch_unlikely(&userspace_irqchip_in_use)) { | ||
| 745 | if (kvm_timer_should_notify_user(vcpu) || | ||
| 746 | kvm_pmu_should_notify_user(vcpu)) { | ||
| 747 | *ret = -EINTR; | ||
| 748 | run->exit_reason = KVM_EXIT_INTR; | ||
| 749 | return true; | ||
| 750 | } | ||
| 751 | } | ||
| 752 | |||
| 753 | return kvm_request_pending(vcpu) || | ||
| 754 | need_new_vmid_gen(&vcpu->arch.hw_mmu->vmid) || | ||
| 755 | xfer_to_guest_mode_work_pending(); | ||
| 756 | } | ||
| 757 | |||
| 717 | /** | 758 | /** |
| 718 | * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code | 759 | * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code |
| 719 | * @vcpu: The VCPU pointer | 760 | * @vcpu: The VCPU pointer |
| @@ -757,7 +798,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) · 37 unmodified lines | |||
| 757 | /* | 798 | /* |
| 758 | * Check conditions before entering the guest | 799 | * Check conditions before entering the guest |
| 759 | */ | 800 | */ |
| 760 | cond_resched(); | 801 | ret = xfer_to_guest_mode_handle_work(vcpu); |
| 802 | if (!ret) | ||
| 803 | ret = 1; | ||
| 761 | 804 | ||
| 762 | update_vmid(&vcpu->arch.hw_mmu->vmid); | 805 | update_vmid(&vcpu->arch.hw_mmu->vmid); |
| 763 | 806 | ||
| @@ -776,30 +819,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) · 12 unmodified lines | |||
| 776 | 819 | ||
| 777 | kvm_vgic_flush_hwstate(vcpu); | 820 | kvm_vgic_flush_hwstate(vcpu); |
| 778 | 821 | ||
| 779 | /* | ||
| 780 | * Exit if we have a signal pending so that we can deliver the | ||
| 781 | * signal to user space. | ||
| 782 | */ | ||
| 783 | if (signal_pending(current)) { | ||
| 784 | ret = -EINTR; | ||
| 785 | run->exit_reason = KVM_EXIT_INTR; | ||
| 786 | } | ||
| 787 | |||
| 788 | /* | ||
| 789 | * If we're using a userspace irqchip, then check if we need | ||
| 790 | * to tell a userspace irqchip about timer or PMU level | ||
| 791 | * changes and if so, exit to userspace (the actual level | ||
| 792 | * state gets updated in kvm_timer_update_run and | ||
| 793 | * kvm_pmu_update_run below). | ||
| 794 | */ | ||
| 795 | if (static_branch_unlikely(&userspace_irqchip_in_use)) { | ||
| 796 | if (kvm_timer_should_notify_user(vcpu) || | ||
| 797 | kvm_pmu_should_notify_user(vcpu)) { | ||
| 798 | ret = -EINTR; | ||
| 799 | run->exit_reason = KVM_EXIT_INTR; | ||
| 800 | } | ||
| 801 | } | ||
| 802 | |||
| 803 | /* | 822 | /* |
| 804 | * Ensure we set mode to IN_GUEST_MODE after we disable | 823 | * Ensure we set mode to IN_GUEST_MODE after we disable |
| 805 | * interrupts and before the final VCPU requests check. | 824 | * interrupts and before the final VCPU requests check. |
| @@ -808,8 +827,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) · 2 unmodified lines | |||
| 808 | */ | 827 | */ |
| 809 | smp_store_mb(vcpu->mode, IN_GUEST_MODE); | 828 | smp_store_mb(vcpu->mode, IN_GUEST_MODE); |
| 810 | 829 | ||
| 811 | if (ret <= 0 || need_new_vmid_gen(&vcpu->arch.hw_mmu->vmid) || | 830 | if (ret <= 0 || kvm_vcpu_exit_request(vcpu, &ret)) { |
| 812 | kvm_request_pending(vcpu)) { | ||
| 813 | vcpu->mode = OUTSIDE_GUEST_MODE; | 831 | vcpu->mode = OUTSIDE_GUEST_MODE; |
| 814 | isb(); /* Ensure work in x_flush_hwstate is committed */ | 832 | isb(); /* Ensure work in x_flush_hwstate is committed */ |
| 815 | kvm_pmu_sync_hwstate(vcpu); | 833 | kvm_pmu_sync_hwstate(vcpu); |
| @@ -1035,7 +1053,7 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, · 219 unmodified lines | |||
| 1035 | const struct kvm_vcpu_init *init) | 1053 | const struct kvm_vcpu_init *init) |
| 1036 | { | 1054 | { |
| 1037 | unsigned int i, ret; | 1055 | unsigned int i, ret; |
| 1038 | int phys_target = kvm_target_cpu(); | 1056 | u32 phys_target = kvm_target_cpu(); |
| 1039 | 1057 | ||
| 1040 | if (init->target != phys_target) | 1058 | if (init->target != phys_target) |
| 1041 | return -EINVAL; | 1059 | return -EINVAL; |
| @@ -1104,6 +1122,7 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, · 62 unmodified lines | |||
| 1104 | } | 1122 | } |
| 1105 | 1123 | ||
| 1106 | vcpu_reset_hcr(vcpu); | 1124 | vcpu_reset_hcr(vcpu); |
| 1125 | vcpu->arch.cptr_el2 = CPTR_EL2_DEFAULT; | ||
| 1107 | 1126 | ||
| 1108 | /* | 1127 | /* |
| 1109 | * Handle the "start in power-off" case. | 1128 | * Handle the "start in power-off" case. |
| @@ -1215,6 +1234,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 105 unmodified lines | |||
| 1215 | if (copy_from_user(®, argp, sizeof(reg))) | 1234 | if (copy_from_user(®, argp, sizeof(reg))) |
| 1216 | break; | 1235 | break; |
| 1217 | 1236 | ||
| 1237 | /* | ||
| 1238 | * We could owe a reset due to PSCI. Handle the pending reset | ||
| 1239 | * here to ensure userspace register accesses are ordered after | ||
| 1240 | * the reset. | ||
| 1241 | */ | ||
| 1242 | if (kvm_check_request(KVM_REQ_VCPU_RESET, vcpu)) | ||
| 1243 | kvm_reset_vcpu(vcpu); | ||
| 1244 | |||
| 1218 | if (ioctl == KVM_SET_ONE_REG) | 1245 | if (ioctl == KVM_SET_ONE_REG) |
| 1219 | r = kvm_arm_set_reg(vcpu, ®); | 1246 | r = kvm_arm_set_reg(vcpu, ®); |
| 1220 | else | 1247 | else |
| @@ -1696,11 +1723,6 @@ static bool init_psci_relay(void) · 475 unmodified lines | |||
| 1696 | return true; | 1723 | return true; |
| 1697 | } | 1724 | } |
| 1698 | 1725 | ||
| 1699 | static int init_common_resources(void) | ||
| 1700 | { | ||
| 1701 | return kvm_set_ipa_limit(); | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | static int init_subsystems(void) | 1726 | static int init_subsystems(void) |
| 1705 | { | 1727 | { |
| 1706 | int err = 0; | 1728 | int err = 0; |
| @@ -1954,56 +1976,17 @@ static void _kvm_host_prot_finalize(void *discard) · 247 unmodified lines | |||
| 1954 | WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize)); | 1976 | WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize)); |
| 1955 | } | 1977 | } |
| 1956 | 1978 | ||
| 1957 | static inline int pkvm_mark_hyp(phys_addr_t start, phys_addr_t end) | ||
| 1958 | { | ||
| 1959 | return kvm_call_hyp_nvhe(__pkvm_mark_hyp, start, end); | ||
| 1960 | } | ||
| 1961 | |||
| 1962 | #define pkvm_mark_hyp_section(__section) \ | ||
| 1963 | pkvm_mark_hyp(__pa_symbol(__section##_start), \ | ||
| 1964 | __pa_symbol(__section##_end)) | ||
| 1965 | |||
| 1966 | static int finalize_hyp_mode(void) | 1979 | static int finalize_hyp_mode(void) |
| 1967 | { | 1980 | { |
| 1968 | int cpu, ret; | ||
| 1969 | |||
| 1970 | if (!is_protected_kvm_enabled()) | 1981 | if (!is_protected_kvm_enabled()) |
| 1971 | return 0; | 1982 | return 0; |
| 1972 | 1983 | ||
| 1973 | ret = pkvm_mark_hyp_section(__hyp_idmap_text); | 1984 | /* |
| 1974 | if (ret) | 1985 | * Exclude HYP BSS from kmemleak so that it doesn't get peeked |
| 1975 | return ret; | 1986 | * at, which would end badly once the section is inaccessible. |
| 1976 | 1987 | * None of other sections should ever be introspected. | |
| 1977 | ret = pkvm_mark_hyp_section(__hyp_text); | 1988 | */ |
| 1978 | if (ret) | 1989 | kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); |
| 1979 | return ret; | ||
| 1980 | |||
| 1981 | ret = pkvm_mark_hyp_section(__hyp_rodata); | ||
| 1982 | if (ret) | ||
| 1983 | return ret; | ||
| 1984 | |||
| 1985 | ret = pkvm_mark_hyp_section(__hyp_bss); | ||
| 1986 | if (ret) | ||
| 1987 | return ret; | ||
| 1988 | |||
| 1989 | ret = pkvm_mark_hyp(hyp_mem_base, hyp_mem_base + hyp_mem_size); | ||
| 1990 | if (ret) | ||
| 1991 | return ret; | ||
| 1992 | |||
| 1993 | for_each_possible_cpu(cpu) { | ||
| 1994 | phys_addr_t start = virt_to_phys((void *)kvm_arm_hyp_percpu_base[cpu]); | ||
| 1995 | phys_addr_t end = start + (PAGE_SIZE << nvhe_percpu_order()); | ||
| 1996 | |||
| 1997 | ret = pkvm_mark_hyp(start, end); | ||
| 1998 | if (ret) | ||
| 1999 | return ret; | ||
| 2000 | |||
| 2001 | start = virt_to_phys((void *)per_cpu(kvm_arm_hyp_stack_page, cpu)); | ||
| 2002 | end = start + PAGE_SIZE; | ||
| 2003 | ret = pkvm_mark_hyp(start, end); | ||
| 2004 | if (ret) | ||
| 2005 | return ret; | ||
| 2006 | } | ||
| 2007 | 1990 | ||
| 2008 | /* | 1991 | /* |
| 2009 | * Flip the static key upfront as that may no longer be possible | 1992 | * Flip the static key upfront as that may no longer be possible |
| @@ -2015,11 +1998,6 @@ static int finalize_hyp_mode(void) · 5 unmodified lines | |||
| 2015 | return 0; | 1998 | return 0; |
| 2016 | } | 1999 | } |
| 2017 | 2000 | ||
| 2018 | static void check_kvm_target_cpu(void *ret) | ||
| 2019 | { | ||
| 2020 | *(int *)ret = kvm_target_cpu(); | ||
| 2021 | } | ||
| 2022 | |||
| 2023 | struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr) | 2001 | struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr) |
| 2024 | { | 2002 | { |
| 2025 | struct kvm_vcpu *vcpu; | 2003 | struct kvm_vcpu *vcpu; |
| @@ -2079,7 +2057,6 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons) · 53 unmodified lines | |||
| 2079 | int kvm_arch_init(void *opaque) | 2057 | int kvm_arch_init(void *opaque) |
| 2080 | { | 2058 | { |
| 2081 | int err; | 2059 | int err; |
| 2082 | int ret, cpu; | ||
| 2083 | bool in_hyp_mode; | 2060 | bool in_hyp_mode; |
| 2084 | 2061 | ||
| 2085 | if (!is_hyp_mode_available()) { | 2062 | if (!is_hyp_mode_available()) { |
| @@ -2094,15 +2071,7 @@ int kvm_arch_init(void *opaque) · 8 unmodified lines | |||
| 2094 | kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \ | 2071 | kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \ |
| 2095 | "Only trusted guests should be used on this system.\n"); | 2072 | "Only trusted guests should be used on this system.\n"); |
| 2096 | 2073 | ||
| 2097 | for_each_online_cpu(cpu) { | 2074 | err = kvm_set_ipa_limit(); |
| 2098 | smp_call_function_single(cpu, check_kvm_target_cpu, &ret, 1); | ||
| 2099 | if (ret < 0) { | ||
| 2100 | kvm_err("Error, CPU %d not supported!\n", cpu); | ||
| 2101 | return -ENODEV; | ||
| 2102 | } | ||
| 2103 | } | ||
| 2104 | |||
| 2105 | err = init_common_resources(); | ||
| 2106 | if (err) | 2075 | if (err) |
| 2107 | return err; | 2076 | return err; |
| 2108 | 2077 | ||
| @@ -21,7 +21,7 @@ · 20 unmodified lines | |||
| 21 | DBG_MDSCR_KDE | \ | 21 | DBG_MDSCR_KDE | \ |
| 22 | DBG_MDSCR_MDE) | 22 | DBG_MDSCR_MDE) |
| 23 | 23 | ||
| 24 | static DEFINE_PER_CPU(u32, mdcr_el2); | 24 | static DEFINE_PER_CPU(u64, mdcr_el2); |
| 25 | 25 | ||
| 26 | /** | 26 | /** |
| 27 | * save/restore_guest_debug_regs | 27 | * save/restore_guest_debug_regs |
| @@ -48,6 +48,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { · 47 unmodified lines | |||
| 48 | STATS_DESC_COUNTER(VCPU, wfi_exit_stat), | 48 | STATS_DESC_COUNTER(VCPU, wfi_exit_stat), |
| 49 | STATS_DESC_COUNTER(VCPU, mmio_exit_user), | 49 | STATS_DESC_COUNTER(VCPU, mmio_exit_user), |
| 50 | STATS_DESC_COUNTER(VCPU, mmio_exit_kernel), | 50 | STATS_DESC_COUNTER(VCPU, mmio_exit_kernel), |
| 51 | STATS_DESC_COUNTER(VCPU, signal_exits), | ||
| 51 | STATS_DESC_COUNTER(VCPU, exits) | 52 | STATS_DESC_COUNTER(VCPU, exits) |
| 52 | }; | 53 | }; |
| 53 | 54 | ||
| @@ -838,7 +839,7 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu, · 784 unmodified lines | |||
| 838 | return 0; | 839 | return 0; |
| 839 | } | 840 | } |
| 840 | 841 | ||
| 841 | int __attribute_const__ kvm_target_cpu(void) | 842 | u32 __attribute_const__ kvm_target_cpu(void) |
| 842 | { | 843 | { |
| 843 | unsigned long implementor = read_cpuid_implementor(); | 844 | unsigned long implementor = read_cpuid_implementor(); |
| 844 | unsigned long part_number = read_cpuid_part_number(); | 845 | unsigned long part_number = read_cpuid_part_number(); |
| @@ -870,7 +871,7 @@ int __attribute_const__ kvm_target_cpu(void) · 25 unmodified lines | |||
| 870 | 871 | ||
| 871 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) | 872 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) |
| 872 | { | 873 | { |
| 873 | int target = kvm_target_cpu(); | 874 | u32 target = kvm_target_cpu(); |
| 874 | 875 | ||
| 875 | if (target < 0) | 876 | if (target < 0) |
| 876 | return -ENODEV; | 877 | return -ENODEV; |
| @@ -113,34 +113,20 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu) · 112 unmodified lines | |||
| 113 | * guest and host are using the same debug facilities it will be up to | 113 | * guest and host are using the same debug facilities it will be up to |
| 114 | * userspace to re-inject the correct exception for guest delivery. | 114 | * userspace to re-inject the correct exception for guest delivery. |
| 115 | * | 115 | * |
| 116 | * @return: 0 (while setting vcpu->run->exit_reason), -1 for error | 116 | * @return: 0 (while setting vcpu->run->exit_reason) |
| 117 | */ | 117 | */ |
| 118 | static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu) | 118 | static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu) |
| 119 | { | 119 | { |
| 120 | struct kvm_run *run = vcpu->run; | 120 | struct kvm_run *run = vcpu->run; |
| 121 | u32 esr = kvm_vcpu_get_esr(vcpu); | 121 | u32 esr = kvm_vcpu_get_esr(vcpu); |
| 122 | int ret = 0; | ||
| 123 | 122 | ||
| 124 | run->exit_reason = KVM_EXIT_DEBUG; | 123 | run->exit_reason = KVM_EXIT_DEBUG; |
| 125 | run->debug.arch.hsr = esr; | 124 | run->debug.arch.hsr = esr; |
| 126 | 125 | ||
| 127 | switch (ESR_ELx_EC(esr)) { | 126 | if (ESR_ELx_EC(esr) == ESR_ELx_EC_WATCHPT_LOW) |
| 128 | case ESR_ELx_EC_WATCHPT_LOW: | ||
| 129 | run->debug.arch.far = vcpu->arch.fault.far_el2; | 127 | run->debug.arch.far = vcpu->arch.fault.far_el2; |
| 130 | fallthrough; | ||
| 131 | case ESR_ELx_EC_SOFTSTP_LOW: | ||
| 132 | case ESR_ELx_EC_BREAKPT_LOW: | ||
| 133 | case ESR_ELx_EC_BKPT32: | ||
| 134 | case ESR_ELx_EC_BRK64: | ||
| 135 | break; | ||
| 136 | default: | ||
| 137 | kvm_err("%s: un-handled case esr: %#08x\n", | ||
| 138 | __func__, (unsigned int) esr); | ||
| 139 | ret = -1; | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | 128 | ||
| 143 | return ret; | 129 | return 0; |
| 144 | } | 130 | } |
| 145 | 131 | ||
| 146 | static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu) | 132 | static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu) |
| @@ -292,11 +278,12 @@ void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index) · 145 unmodified lines | |||
| 292 | kvm_handle_guest_serror(vcpu, kvm_vcpu_get_esr(vcpu)); | 278 | kvm_handle_guest_serror(vcpu, kvm_vcpu_get_esr(vcpu)); |
| 293 | } | 279 | } |
| 294 | 280 | ||
| 295 | void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr, | 281 | void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, |
| 282 | u64 elr_virt, u64 elr_phys, | ||
| 296 | u64 par, uintptr_t vcpu, | 283 | u64 par, uintptr_t vcpu, |
| 297 | u64 far, u64 hpfar) { | 284 | u64 far, u64 hpfar) { |
| 298 | u64 elr_in_kimg = __phys_to_kimg(__hyp_pa(elr)); | 285 | u64 elr_in_kimg = __phys_to_kimg(elr_phys); |
| 299 | u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr; | 286 | u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr_virt; |
| 300 | u64 mode = spsr & PSR_MODE_MASK; | 287 | u64 mode = spsr & PSR_MODE_MASK; |
| 301 | 288 | ||
| 302 | /* | 289 | /* |
| @@ -309,20 +296,24 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr, · 6 unmodified lines | |||
| 309 | kvm_err("Invalid host exception to nVHE hyp!\n"); | 296 | kvm_err("Invalid host exception to nVHE hyp!\n"); |
| 310 | } else if (ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 && | 297 | } else if (ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 && |
| 311 | (esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == BUG_BRK_IMM) { | 298 | (esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == BUG_BRK_IMM) { |
| 312 | struct bug_entry *bug = find_bug(elr_in_kimg); | ||
| 313 | const char *file = NULL; | 299 | const char *file = NULL; |
| 314 | unsigned int line = 0; | 300 | unsigned int line = 0; |
| 315 | 301 | ||
| 316 | /* All hyp bugs, including warnings, are treated as fatal. */ | 302 | /* All hyp bugs, including warnings, are treated as fatal. */ |
| 317 | if (bug) | 303 | if (!is_protected_kvm_enabled() || |
| 318 | bug_get_file_line(bug, &file, &line); | 304 | IS_ENABLED(CONFIG_NVHE_EL2_DEBUG)) { |
| 305 | struct bug_entry *bug = find_bug(elr_in_kimg); | ||
| 306 | |||
| 307 | if (bug) | ||
| 308 | bug_get_file_line(bug, &file, &line); | ||
| 309 | } | ||
| 319 | 310 | ||
| 320 | if (file) | 311 | if (file) |
| 321 | kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line); | 312 | kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line); |
| 322 | else | 313 | else |
| 323 | kvm_err("nVHE hyp BUG at: %016llx!\n", elr + hyp_offset); | 314 | kvm_err("nVHE hyp BUG at: %016llx!\n", elr_virt + hyp_offset); |
| 324 | } else { | 315 | } else { |
| 325 | kvm_err("nVHE hyp panic at: %016llx!\n", elr + hyp_offset); | 316 | kvm_err("nVHE hyp panic at: %016llx!\n", elr_virt + hyp_offset); |
| 326 | } | 317 | } |
| 327 | 318 | ||
| 328 | /* | 319 | /* |
| @@ -334,5 +325,5 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr, · 5 unmodified lines | |||
| 334 | kvm_err("Hyp Offset: 0x%llx\n", hyp_offset); | 325 | kvm_err("Hyp Offset: 0x%llx\n", hyp_offset); |
| 335 | 326 | ||
| 336 | panic("HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%016lx\n", | 327 | panic("HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%016lx\n", |
| 337 | spsr, elr, esr, far, hpfar, par, vcpu); | 328 | spsr, elr_virt, esr, far, hpfar, par, vcpu); |
| 338 | } | 329 | } |
| @@ -92,11 +92,15 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) · 91 unmodified lines | |||
| 92 | write_sysreg(0, pmselr_el0); | 92 | write_sysreg(0, pmselr_el0); |
| 93 | write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); | 93 | write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); |
| 94 | } | 94 | } |
| 95 | |||
| 96 | vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); | ||
| 95 | write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); | 97 | write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); |
| 96 | } | 98 | } |
| 97 | 99 | ||
| 98 | static inline void __deactivate_traps_common(void) | 100 | static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) |
| 99 | { | 101 | { |
| 102 | write_sysreg(vcpu->arch.mdcr_el2_host, mdcr_el2); | ||
| 103 | |||
| 100 | write_sysreg(0, hstr_el2); | 104 | write_sysreg(0, hstr_el2); |
| 101 | if (kvm_arm_support_pmu_v3()) | 105 | if (kvm_arm_support_pmu_v3()) |
| 102 | write_sysreg(0, pmuserenr_el0); | 106 | write_sysreg(0, pmuserenr_el0); |
| @@ -12,6 +12,32 @@ · 11 unmodified lines | |||
| 12 | #include <asm/virt.h> | 12 | #include <asm/virt.h> |
| 13 | #include <nvhe/spinlock.h> | 13 | #include <nvhe/spinlock.h> |
| 14 | 14 | ||
| 15 | /* | ||
| 16 | * SW bits 0-1 are reserved to track the memory ownership state of each page: | ||
| 17 | * 00: The page is owned exclusively by the page-table owner. | ||
| 18 | * 01: The page is owned by the page-table owner, but is shared | ||
| 19 | * with another entity. | ||
| 20 | * 10: The page is shared with, but not owned by the page-table owner. | ||
| 21 | * 11: Reserved for future use (lending). | ||
| 22 | */ | ||
| 23 | enum pkvm_page_state { | ||
| 24 | PKVM_PAGE_OWNED = 0ULL, | ||
| 25 | PKVM_PAGE_SHARED_OWNED = KVM_PGTABLE_PROT_SW0, | ||
| 26 | PKVM_PAGE_SHARED_BORROWED = KVM_PGTABLE_PROT_SW1, | ||
| 27 | }; | ||
| 28 | |||
| 29 | #define PKVM_PAGE_STATE_PROT_MASK (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1) | ||
| 30 | static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot, | ||
| 31 | enum pkvm_page_state state) | ||
| 32 | { | ||
| 33 | return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state; | ||
| 34 | } | ||
| 35 | |||
| 36 | static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot) | ||
| 37 | { | ||
| 38 | return prot & PKVM_PAGE_STATE_PROT_MASK; | ||
| 39 | } | ||
| 40 | |||
| 15 | struct host_kvm { | 41 | struct host_kvm { |
| 16 | struct kvm_arch arch; | 42 | struct kvm_arch arch; |
| 17 | struct kvm_pgtable pgt; | 43 | struct kvm_pgtable pgt; |
| @@ -20,16 +46,21 @@ struct host_kvm { · 2 unmodified lines | |||
| 20 | }; | 46 | }; |
| 21 | extern struct host_kvm host_kvm; | 47 | extern struct host_kvm host_kvm; |
| 22 | 48 | ||
| 49 | extern const u8 pkvm_hyp_id; | ||
| 50 | |||
| 23 | int __pkvm_prot_finalize(void); | 51 | int __pkvm_prot_finalize(void); |
| 24 | int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end); | 52 | int __pkvm_host_share_hyp(u64 pfn); |
| 25 | 53 | ||
| 54 | bool addr_is_memory(phys_addr_t phys); | ||
| 55 | int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot); | ||
| 56 | int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id); | ||
| 26 | int kvm_host_prepare_stage2(void *pgt_pool_base); | 57 | int kvm_host_prepare_stage2(void *pgt_pool_base); |
| 27 | void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt); | 58 | void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt); |
| 28 | 59 | ||
| 29 | static __always_inline void __load_host_stage2(void) | 60 | static __always_inline void __load_host_stage2(void) |
| 30 | { | 61 | { |
| 31 | if (static_branch_likely(&kvm_protected_mode_initialized)) | 62 | if (static_branch_likely(&kvm_protected_mode_initialized)) |
| 32 | __load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr); | 63 | __load_stage2(&host_kvm.arch.mmu, &host_kvm.arch); |
| 33 | else | 64 | else |
| 34 | write_sysreg(0, vttbr_el2); | 65 | write_sysreg(0, vttbr_el2); |
| 35 | } | 66 | } |
| @@ -23,8 +23,7 @@ int hyp_map_vectors(void); · 22 unmodified lines | |||
| 23 | int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back); | 23 | int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back); |
| 24 | int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot); | 24 | int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot); |
| 25 | int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot); | 25 | int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot); |
| 26 | int __pkvm_create_mappings(unsigned long start, unsigned long size, | 26 | int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot); |
| 27 | unsigned long phys, enum kvm_pgtable_prot prot); | ||
| 28 | unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size, | 27 | unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size, |
| 29 | enum kvm_pgtable_prot prot); | 28 | enum kvm_pgtable_prot prot); |
| 30 | 29 | ||
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | #include <asm/alternative.h> | 16 | #include <asm/alternative.h> |
| 17 | #include <asm/lse.h> | 17 | #include <asm/lse.h> |
| 18 | #include <asm/rwonce.h> | ||
| 18 | 19 | ||
| 19 | typedef union hyp_spinlock { | 20 | typedef union hyp_spinlock { |
| 20 | u32 __val; | 21 | u32 __val; |
| @@ -89,4 +90,28 @@ static inline void hyp_spin_unlock(hyp_spinlock_t *lock) · 68 unmodified lines | |||
| 89 | : "memory"); | 90 | : "memory"); |
| 90 | } | 91 | } |
| 91 | 92 | ||
| 93 | static inline bool hyp_spin_is_locked(hyp_spinlock_t *lock) | ||
| 94 | { | ||
| 95 | hyp_spinlock_t lockval = READ_ONCE(*lock); | ||
| 96 | |||
| 97 | return lockval.owner != lockval.next; | ||
| 98 | } | ||
| 99 | |||
| 100 | #ifdef CONFIG_NVHE_EL2_DEBUG | ||
| 101 | static inline void hyp_assert_lock_held(hyp_spinlock_t *lock) | ||
| 102 | { | ||
| 103 | /* | ||
| 104 | * The __pkvm_init() path accesses protected data-structures without | ||
| 105 | * holding locks as the other CPUs are guaranteed to not enter EL2 | ||
| 106 | * concurrently at this point in time. The point by which EL2 is | ||
| 107 | * initialized on all CPUs is reflected in the pkvm static key, so | ||
| 108 | * wait until it is set before checking the lock state. | ||
| 109 | */ | ||
| 110 | if (static_branch_likely(&kvm_protected_mode_initialized)) | ||
| 111 | BUG_ON(!hyp_spin_is_locked(lock)); | ||
| 112 | } | ||
| 113 | #else | ||
| 114 | static inline void hyp_assert_lock_held(hyp_spinlock_t *lock) { } | ||
| 115 | #endif | ||
| 116 | |||
| 92 | #endif /* __ARM64_KVM_NVHE_SPINLOCK_H__ */ | 117 | #endif /* __ARM64_KVM_NVHE_SPINLOCK_H__ */ |
| @@ -109,7 +109,7 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu) · 108 unmodified lines | |||
| 109 | __debug_switch_to_host_common(vcpu); | 109 | __debug_switch_to_host_common(vcpu); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | u32 __kvm_get_mdcr_el2(void) | 112 | u64 __kvm_get_mdcr_el2(void) |
| 113 | { | 113 | { |
| 114 | return read_sysreg(mdcr_el2); | 114 | return read_sysreg(mdcr_el2); |
| 115 | } | 115 | } |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | #include <linux/linkage.h> | 7 | #include <linux/linkage.h> |
| 8 | 8 | ||
| 9 | #include <asm/assembler.h> | 9 | #include <asm/assembler.h> |
| 10 | #include <asm/kvm_arm.h> | ||
| 10 | #include <asm/kvm_asm.h> | 11 | #include <asm/kvm_asm.h> |
| 11 | #include <asm/kvm_mmu.h> | 12 | #include <asm/kvm_mmu.h> |
| 12 | 13 | ||
| @@ -85,12 +86,24 @@ SYM_FUNC_START(__hyp_do_panic) · 72 unmodified lines | |||
| 85 | 86 | ||
| 86 | mov x29, x0 | 87 | mov x29, x0 |
| 87 | 88 | ||
| 89 | #ifdef CONFIG_NVHE_EL2_DEBUG | ||
| 90 | /* Ensure host stage-2 is disabled */ | ||
| 91 | mrs x0, hcr_el2 | ||
| 92 | bic x0, x0, #HCR_VM | ||
| 93 | msr hcr_el2, x0 | ||
| 94 | isb | ||
| 95 | tlbi vmalls12e1 | ||
| 96 | dsb nsh | ||
| 97 | #endif | ||
| 98 | |||
| 88 | /* Load the panic arguments into x0-7 */ | 99 | /* Load the panic arguments into x0-7 */ |
| 89 | mrs x0, esr_el2 | 100 | mrs x0, esr_el2 |
| 90 | get_vcpu_ptr x4, x5 | 101 | mov x4, x3 |
| 91 | mrs x5, far_el2 | 102 | mov x3, x2 |
| 92 | mrs x6, hpfar_el2 | 103 | hyp_pa x3, x6 |
| 93 | mov x7, xzr // Unused argument | 104 | get_vcpu_ptr x5, x6 |
| 105 | mrs x6, far_el2 | ||
| 106 | mrs x7, hpfar_el2 | ||
| 94 | 107 | ||
| 95 | /* Enter the host, conditionally restoring the host context. */ | 108 | /* Enter the host, conditionally restoring the host context. */ |
| 96 | cbz x29, __host_enter_without_restoring | 109 | cbz x29, __host_enter_without_restoring |
| @@ -140,14 +140,11 @@ static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt) · 139 unmodified lines | |||
| 140 | cpu_reg(host_ctxt, 1) = pkvm_cpu_set_vector(slot); | 140 | cpu_reg(host_ctxt, 1) = pkvm_cpu_set_vector(slot); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static void handle___pkvm_create_mappings(struct kvm_cpu_context *host_ctxt) | 143 | static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt) |
| 144 | { | 144 | { |
| 145 | DECLARE_REG(unsigned long, start, host_ctxt, 1); | 145 | DECLARE_REG(u64, pfn, host_ctxt, 1); |
| 146 | DECLARE_REG(unsigned long, size, host_ctxt, 2); | ||
| 147 | DECLARE_REG(unsigned long, phys, host_ctxt, 3); | ||
| 148 | DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4); | ||
| 149 | 146 | ||
| 150 | cpu_reg(host_ctxt, 1) = __pkvm_create_mappings(start, size, phys, prot); | 147 | cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(pfn); |
| 151 | } | 148 | } |
| 152 | 149 | ||
| 153 | static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt) | 150 | static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt) |
| @@ -163,14 +160,6 @@ static void handle___pkvm_prot_finalize(struct kvm_cpu_context *host_ctxt) · 9 unmodified lines | |||
| 163 | { | 160 | { |
| 164 | cpu_reg(host_ctxt, 1) = __pkvm_prot_finalize(); | 161 | cpu_reg(host_ctxt, 1) = __pkvm_prot_finalize(); |
| 165 | } | 162 | } |
| 166 | |||
| 167 | static void handle___pkvm_mark_hyp(struct kvm_cpu_context *host_ctxt) | ||
| 168 | { | ||
| 169 | DECLARE_REG(phys_addr_t, start, host_ctxt, 1); | ||
| 170 | DECLARE_REG(phys_addr_t, end, host_ctxt, 2); | ||
| 171 | |||
| 172 | cpu_reg(host_ctxt, 1) = __pkvm_mark_hyp(start, end); | ||
| 173 | } | ||
| 174 | typedef void (*hcall_t)(struct kvm_cpu_context *); | 163 | typedef void (*hcall_t)(struct kvm_cpu_context *); |
| 175 | 164 | ||
| 176 | #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x | 165 | #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x |
| @@ -193,10 +182,9 @@ static const hcall_t host_hcall[] = { · 16 unmodified lines | |||
| 193 | HANDLE_FUNC(__vgic_v3_restore_aprs), | 182 | HANDLE_FUNC(__vgic_v3_restore_aprs), |
| 194 | HANDLE_FUNC(__pkvm_init), | 183 | HANDLE_FUNC(__pkvm_init), |
| 195 | HANDLE_FUNC(__pkvm_cpu_set_vector), | 184 | HANDLE_FUNC(__pkvm_cpu_set_vector), |
| 196 | HANDLE_FUNC(__pkvm_create_mappings), | 185 | HANDLE_FUNC(__pkvm_host_share_hyp), |
| 197 | HANDLE_FUNC(__pkvm_create_private_mapping), | 186 | HANDLE_FUNC(__pkvm_create_private_mapping), |
| 198 | HANDLE_FUNC(__pkvm_prot_finalize), | 187 | HANDLE_FUNC(__pkvm_prot_finalize), |
| 199 | HANDLE_FUNC(__pkvm_mark_hyp), | ||
| 200 | }; | 188 | }; |
| 201 | 189 | ||
| 202 | static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) | 190 | static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) |
| @@ -31,7 +31,7 @@ static struct hyp_pool host_s2_pool; · 30 unmodified lines | |||
| 31 | u64 id_aa64mmfr0_el1_sys_val; | 31 | u64 id_aa64mmfr0_el1_sys_val; |
| 32 | u64 id_aa64mmfr1_el1_sys_val; | 32 | u64 id_aa64mmfr1_el1_sys_val; |
| 33 | 33 | ||
| 34 | static const u8 pkvm_hyp_id = 1; | 34 | const u8 pkvm_hyp_id = 1; |
| 35 | 35 | ||
| 36 | static void *host_s2_zalloc_pages_exact(size_t size) | 36 | static void *host_s2_zalloc_pages_exact(size_t size) |
| 37 | { | 37 | { |
| @@ -89,6 +89,8 @@ static void prepare_host_vtcr(void) · 51 unmodified lines | |||
| 89 | id_aa64mmfr1_el1_sys_val, phys_shift); | 89 | id_aa64mmfr1_el1_sys_val, phys_shift); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot); | ||
| 93 | |||
| 92 | int kvm_host_prepare_stage2(void *pgt_pool_base) | 94 | int kvm_host_prepare_stage2(void *pgt_pool_base) |
| 93 | { | 95 | { |
| 94 | struct kvm_s2_mmu *mmu = &host_kvm.arch.mmu; | 96 | struct kvm_s2_mmu *mmu = &host_kvm.arch.mmu; |
| @@ -101,16 +103,17 @@ int kvm_host_prepare_stage2(void *pgt_pool_base) · 6 unmodified lines | |||
| 101 | if (ret) | 103 | if (ret) |
| 102 | return ret; | 104 | return ret; |
| 103 | 105 | ||
| 104 | ret = kvm_pgtable_stage2_init_flags(&host_kvm.pgt, &host_kvm.arch, | 106 | ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, &host_kvm.arch, |
| 105 | &host_kvm.mm_ops, KVM_HOST_S2_FLAGS); | 107 | &host_kvm.mm_ops, KVM_HOST_S2_FLAGS, |
| 108 | host_stage2_force_pte_cb); | ||
| 106 | if (ret) | 109 | if (ret) |
| 107 | return ret; | 110 | return ret; |
| 108 | 111 | ||
| 109 | mmu->pgd_phys = __hyp_pa(host_kvm.pgt.pgd); | 112 | mmu->pgd_phys = __hyp_pa(host_kvm.pgt.pgd); |
| 110 | mmu->arch = &host_kvm.arch; | 113 | mmu->arch = &host_kvm.arch; |
| 111 | mmu->pgt = &host_kvm.pgt; | 114 | mmu->pgt = &host_kvm.pgt; |
| 112 | mmu->vmid.vmid_gen = 0; | 115 | WRITE_ONCE(mmu->vmid.vmid_gen, 0); |
| 113 | mmu->vmid.vmid = 0; | 116 | WRITE_ONCE(mmu->vmid.vmid, 0); |
| 114 | 117 | ||
| 115 | return 0; | 118 | return 0; |
| 116 | } | 119 | } |
| @@ -126,7 +129,7 @@ int __pkvm_prot_finalize(void) · 9 unmodified lines | |||
| 126 | kvm_flush_dcache_to_poc(params, sizeof(*params)); | 129 | kvm_flush_dcache_to_poc(params, sizeof(*params)); |
| 127 | 130 | ||
| 128 | write_sysreg(params->hcr_el2, hcr_el2); | 131 | write_sysreg(params->hcr_el2, hcr_el2); |
| 129 | __load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr); | 132 | __load_stage2(&host_kvm.arch.mmu, &host_kvm.arch); |
| 130 | 133 | ||
| 131 | /* | 134 | /* |
| 132 | * Make sure to have an ISB before the TLB maintenance below but only | 135 | * Make sure to have an ISB before the TLB maintenance below but only |
| @@ -159,6 +162,11 @@ static int host_stage2_unmap_dev_all(void) · 26 unmodified lines | |||
| 159 | return kvm_pgtable_stage2_unmap(pgt, addr, BIT(pgt->ia_bits) - addr); | 162 | return kvm_pgtable_stage2_unmap(pgt, addr, BIT(pgt->ia_bits) - addr); |
| 160 | } | 163 | } |
| 161 | 164 | ||
| 165 | struct kvm_mem_range { | ||
| 166 | u64 start; | ||
| 167 | u64 end; | ||
| 168 | }; | ||
| 169 | |||
| 162 | static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range) | 170 | static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range) |
| 163 | { | 171 | { |
| 164 | int cur, left = 0, right = hyp_memblock_nr; | 172 | int cur, left = 0, right = hyp_memblock_nr; |
| @@ -189,16 +197,26 @@ static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range) · 24 unmodified lines | |||
| 189 | return false; | 197 | return false; |
| 190 | } | 198 | } |
| 191 | 199 | ||
| 200 | bool addr_is_memory(phys_addr_t phys) | ||
| 201 | { | ||
| 202 | struct kvm_mem_range range; | ||
| 203 | |||
| 204 | return find_mem_range(phys, &range); | ||
| 205 | } | ||
| 206 | |||
| 207 | static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range) | ||
| 208 | { | ||
| 209 | return range->start <= addr && addr < range->end; | ||
| 210 | } | ||
| 211 | |||
| 192 | static bool range_is_memory(u64 start, u64 end) | 212 | static bool range_is_memory(u64 start, u64 end) |
| 193 | { | 213 | { |
| 194 | struct kvm_mem_range r1, r2; | 214 | struct kvm_mem_range r; |
| 195 | 215 | ||
| 196 | if (!find_mem_range(start, &r1) || !find_mem_range(end, &r2)) | 216 | if (!find_mem_range(start, &r)) |
| 197 | return false; | ||
| 198 | if (r1.start != r2.start) | ||
| 199 | return false; | 217 | return false; |
| 200 | 218 | ||
| 201 | return true; | 219 | return is_in_mem_range(end - 1, &r); |
| 202 | } | 220 | } |
| 203 | 221 | ||
| 204 | static inline int __host_stage2_idmap(u64 start, u64 end, | 222 | static inline int __host_stage2_idmap(u64 start, u64 end, |
| @@ -208,60 +226,208 @@ static inline int __host_stage2_idmap(u64 start, u64 end, · 3 unmodified lines | |||
| 208 | prot, &host_s2_pool); | 226 | prot, &host_s2_pool); |
| 209 | } | 227 | } |
| 210 | 228 | ||
| 229 | /* | ||
| 230 | * The pool has been provided with enough pages to cover all of memory with | ||
| 231 | * page granularity, but it is difficult to know how much of the MMIO range | ||
| 232 | * we will need to cover upfront, so we may need to 'recycle' the pages if we | ||
| 233 | * run out. | ||
| 234 | */ | ||
| 235 | #define host_stage2_try(fn, ...) \ | ||
| 236 | ({ \ | ||
| 237 | int __ret; \ | ||
| 238 | hyp_assert_lock_held(&host_kvm.lock); \ | ||
| 239 | __ret = fn(__VA_ARGS__); \ | ||
| 240 | if (__ret == -ENOMEM) { \ | ||
| 241 | __ret = host_stage2_unmap_dev_all(); \ | ||
| 242 | if (!__ret) \ | ||
| 243 | __ret = fn(__VA_ARGS__); \ | ||
| 244 | } \ | ||
| 245 | __ret; \ | ||
| 246 | }) | ||
| 247 | |||
| 248 | static inline bool range_included(struct kvm_mem_range *child, | ||
| 249 | struct kvm_mem_range *parent) | ||
| 250 | { | ||
| 251 | return parent->start <= child->start && child->end <= parent->end; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range) | ||
| 255 | { | ||
| 256 | struct kvm_mem_range cur; | ||
| 257 | kvm_pte_t pte; | ||
| 258 | u32 level; | ||
| 259 | int ret; | ||
| 260 | |||
| 261 | hyp_assert_lock_held(&host_kvm.lock); | ||
| 262 | ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, &level); | ||
| 263 | if (ret) | ||
| 264 | return ret; | ||
| 265 | |||
| 266 | if (kvm_pte_valid(pte)) | ||
| 267 | return -EAGAIN; | ||
| 268 | |||
| 269 | if (pte) | ||
| 270 | return -EPERM; | ||
| 271 | |||
| 272 | do { | ||
| 273 | u64 granule = kvm_granule_size(level); | ||
| 274 | cur.start = ALIGN_DOWN(addr, granule); | ||
| 275 | cur.end = cur.start + granule; | ||
| 276 | level++; | ||
| 277 | } while ((level < KVM_PGTABLE_MAX_LEVELS) && | ||
| 278 | !(kvm_level_supports_block_mapping(level) && | ||
| 279 | range_included(&cur, range))); | ||
| 280 | |||
| 281 | *range = cur; | ||
| 282 | |||
| 283 | return 0; | ||
| 284 | } | ||
| 285 | |||
| 286 | int host_stage2_idmap_locked(phys_addr_t addr, u64 size, | ||
| 287 | enum kvm_pgtable_prot prot) | ||
| 288 | { | ||
| 289 | hyp_assert_lock_held(&host_kvm.lock); | ||
| 290 | |||
| 291 | return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot); | ||
| 292 | } | ||
| 293 | |||
| 294 | int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) | ||
| 295 | { | ||
| 296 | hyp_assert_lock_held(&host_kvm.lock); | ||
| 297 | |||
| 298 | return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt, | ||
| 299 | addr, size, &host_s2_pool, owner_id); | ||
| 300 | } | ||
| 301 | |||
| 302 | static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot) | ||
| 303 | { | ||
| 304 | /* | ||
| 305 | * Block mappings must be used with care in the host stage-2 as a | ||
| 306 | * kvm_pgtable_stage2_map() operation targeting a page in the range of | ||
| 307 | * an existing block will delete the block under the assumption that | ||
| 308 | * mappings in the rest of the block range can always be rebuilt lazily. | ||
| 309 | * That assumption is correct for the host stage-2 with RWX mappings | ||
| 310 | * targeting memory or RW mappings targeting MMIO ranges (see | ||
| 311 | * host_stage2_idmap() below which implements some of the host memory | ||
| 312 | * abort logic). However, this is not safe for any other mappings where | ||
| 313 | * the host stage-2 page-table is in fact the only place where this | ||
| 314 | * state is stored. In all those cases, it is safer to use page-level | ||
| 315 | * mappings, hence avoiding to lose the state because of side-effects in | ||
| 316 | * kvm_pgtable_stage2_map(). | ||
| 317 | */ | ||
| 318 | if (range_is_memory(addr, end)) | ||
| 319 | return prot != PKVM_HOST_MEM_PROT; | ||
| 320 | else | ||
| 321 | return prot != PKVM_HOST_MMIO_PROT; | ||
| 322 | } | ||
| 323 | |||
| 211 | static int host_stage2_idmap(u64 addr) | 324 | static int host_stage2_idmap(u64 addr) |
| 212 | { | 325 | { |
| 213 | enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W; | ||
| 214 | struct kvm_mem_range range; | 326 | struct kvm_mem_range range; |
| 215 | bool is_memory = find_mem_range(addr, &range); | 327 | bool is_memory = find_mem_range(addr, &range); |
| 328 | enum kvm_pgtable_prot prot; | ||
| 216 | int ret; | 329 | int ret; |
| 217 | 330 | ||
| 218 | if (is_memory) | 331 | prot = is_memory ? PKVM_HOST_MEM_PROT : PKVM_HOST_MMIO_PROT; |
| 219 | prot |= KVM_PGTABLE_PROT_X; | ||
| 220 | 332 | ||
| 221 | hyp_spin_lock(&host_kvm.lock); | 333 | hyp_spin_lock(&host_kvm.lock); |
| 222 | ret = kvm_pgtable_stage2_find_range(&host_kvm.pgt, addr, prot, &range); | 334 | ret = host_stage2_adjust_range(addr, &range); |
| 223 | if (ret) | 335 | if (ret) |
| 224 | goto unlock; | 336 | goto unlock; |
| 225 | 337 | ||
| 226 | ret = __host_stage2_idmap(range.start, range.end, prot); | 338 | ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot); |
| 227 | if (ret != -ENOMEM) | 339 | unlock: |
| 340 | hyp_spin_unlock(&host_kvm.lock); | ||
| 341 | |||
| 342 | return ret; | ||
| 343 | } | ||
| 344 | |||
| 345 | static inline bool check_prot(enum kvm_pgtable_prot prot, | ||
| 346 | enum kvm_pgtable_prot required, | ||
| 347 | enum kvm_pgtable_prot denied) | ||
| 348 | { | ||
| 349 | return (prot & (required | denied)) == required; | ||
| 350 | } | ||
| 351 | |||
| 352 | int __pkvm_host_share_hyp(u64 pfn) | ||
| 353 | { | ||
| 354 | phys_addr_t addr = hyp_pfn_to_phys(pfn); | ||
| 355 | enum kvm_pgtable_prot prot, cur; | ||
| 356 | void *virt = __hyp_va(addr); | ||
| 357 | enum pkvm_page_state state; | ||
| 358 | kvm_pte_t pte; | ||
| 359 | int ret; | ||
| 360 | |||
| 361 | if (!addr_is_memory(addr)) | ||
| 362 | return -EINVAL; | ||
| 363 | |||
| 364 | hyp_spin_lock(&host_kvm.lock); | ||
| 365 | hyp_spin_lock(&pkvm_pgd_lock); | ||
| 366 | |||
| 367 | ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, NULL); | ||
| 368 | if (ret) | ||
| 228 | goto unlock; | 369 | goto unlock; |
| 370 | if (!pte) | ||
| 371 | goto map_shared; | ||
| 229 | 372 | ||
| 230 | /* | 373 | /* |
| 231 | * The pool has been provided with enough pages to cover all of memory | 374 | * Check attributes in the host stage-2 PTE. We need the page to be: |
| 232 | * with page granularity, but it is difficult to know how much of the | 375 | * - mapped RWX as we're sharing memory; |
| 233 | * MMIO range we will need to cover upfront, so we may need to 'recycle' | 376 | * - not borrowed, as that implies absence of ownership. |
| 234 | * the pages if we run out. | 377 | * Otherwise, we can't let it got through |
| 235 | */ | 378 | */ |
| 236 | ret = host_stage2_unmap_dev_all(); | 379 | cur = kvm_pgtable_stage2_pte_prot(pte); |
| 237 | if (ret) | 380 | prot = pkvm_mkstate(0, PKVM_PAGE_SHARED_BORROWED); |
| 381 | if (!check_prot(cur, PKVM_HOST_MEM_PROT, prot)) { | ||
| 382 | ret = -EPERM; | ||
| 238 | goto unlock; | 383 | goto unlock; |
| 384 | } | ||
| 239 | 385 | ||
| 240 | ret = __host_stage2_idmap(range.start, range.end, prot); | 386 | state = pkvm_getstate(cur); |
| 387 | if (state == PKVM_PAGE_OWNED) | ||
| 388 | goto map_shared; | ||
| 241 | 389 | ||
| 242 | unlock: | 390 | /* |
| 243 | hyp_spin_unlock(&host_kvm.lock); | 391 | * Tolerate double-sharing the same page, but this requires |
| 392 | * cross-checking the hypervisor stage-1. | ||
| 393 | */ | ||
| 394 | if (state != PKVM_PAGE_SHARED_OWNED) { | ||
| 395 | ret = -EPERM; | ||
| 396 | goto unlock; | ||
| 397 | } | ||
| 244 | 398 | ||
| 245 | return ret; | 399 | ret = kvm_pgtable_get_leaf(&pkvm_pgtable, (u64)virt, &pte, NULL); |
| 246 | } | 400 | if (ret) |
| 401 | goto unlock; | ||
| 247 | 402 | ||
| 248 | int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end) | 403 | /* |
| 249 | { | 404 | * If the page has been shared with the hypervisor, it must be |
| 250 | int ret; | 405 | * already mapped as SHARED_BORROWED in its stage-1. |
| 406 | */ | ||
| 407 | cur = kvm_pgtable_hyp_pte_prot(pte); | ||
| 408 | prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED); | ||
| 409 | if (!check_prot(cur, prot, ~prot)) | ||
| 410 | ret = -EPERM; | ||
| 411 | goto unlock; | ||
| 251 | 412 | ||
| 413 | map_shared: | ||
| 252 | /* | 414 | /* |
| 253 | * host_stage2_unmap_dev_all() currently relies on MMIO mappings being | 415 | * If the page is not yet shared, adjust mappings in both page-tables |
| 254 | * non-persistent, so don't allow changing page ownership in MMIO range. | 416 | * while both locks are held. |
| 255 | */ | 417 | */ |
| 256 | if (!range_is_memory(start, end)) | 418 | prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED); |
| 257 | return -EINVAL; | 419 | ret = pkvm_create_mappings_locked(virt, virt + PAGE_SIZE, prot); |
| 420 | BUG_ON(ret); | ||
| 258 | 421 | ||
| 259 | hyp_spin_lock(&host_kvm.lock); | 422 | prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED); |
| 260 | ret = kvm_pgtable_stage2_set_owner(&host_kvm.pgt, start, end - start, | 423 | ret = host_stage2_idmap_locked(addr, PAGE_SIZE, prot); |
| 261 | &host_s2_pool, pkvm_hyp_id); | 424 | BUG_ON(ret); |
| 425 | |||
| 426 | unlock: | ||
| 427 | hyp_spin_unlock(&pkvm_pgd_lock); | ||
| 262 | hyp_spin_unlock(&host_kvm.lock); | 428 | hyp_spin_unlock(&host_kvm.lock); |
| 263 | 429 | ||
| 264 | return ret != -EAGAIN ? ret : 0; | 430 | return ret; |
| 265 | } | 431 | } |
| 266 | 432 | ||
| 267 | void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) | 433 | void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) |
| @@ -23,8 +23,8 @@ u64 __io_map_base; · 22 unmodified lines | |||
| 23 | struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS]; | 23 | struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS]; |
| 24 | unsigned int hyp_memblock_nr; | 24 | unsigned int hyp_memblock_nr; |
| 25 | 25 | ||
| 26 | int __pkvm_create_mappings(unsigned long start, unsigned long size, | 26 | static int __pkvm_create_mappings(unsigned long start, unsigned long size, |
| 27 | unsigned long phys, enum kvm_pgtable_prot prot) | 27 | unsigned long phys, enum kvm_pgtable_prot prot) |
| 28 | { | 28 | { |
| 29 | int err; | 29 | int err; |
| 30 | 30 | ||
| @@ -67,13 +67,15 @@ out: · 36 unmodified lines | |||
| 67 | return addr; | 67 | return addr; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot) | 70 | int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot) |
| 71 | { | 71 | { |
| 72 | unsigned long start = (unsigned long)from; | 72 | unsigned long start = (unsigned long)from; |
| 73 | unsigned long end = (unsigned long)to; | 73 | unsigned long end = (unsigned long)to; |
| 74 | unsigned long virt_addr; | 74 | unsigned long virt_addr; |
| 75 | phys_addr_t phys; | 75 | phys_addr_t phys; |
| 76 | 76 | ||
| 77 | hyp_assert_lock_held(&pkvm_pgd_lock); | ||
| 78 | |||
| 77 | start = start & PAGE_MASK; | 79 | start = start & PAGE_MASK; |
| 78 | end = PAGE_ALIGN(end); | 80 | end = PAGE_ALIGN(end); |
| 79 | 81 | ||
| @@ -81,7 +83,8 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot) · 1 unmodified line | |||
| 81 | int err; | 83 | int err; |
| 82 | 84 | ||
| 83 | phys = hyp_virt_to_phys((void *)virt_addr); | 85 | phys = hyp_virt_to_phys((void *)virt_addr); |
| 84 | err = __pkvm_create_mappings(virt_addr, PAGE_SIZE, phys, prot); | 86 | err = kvm_pgtable_hyp_map(&pkvm_pgtable, virt_addr, PAGE_SIZE, |
| 87 | phys, prot); | ||
| 85 | if (err) | 88 | if (err) |
| 86 | return err; | 89 | return err; |
| 87 | } | 90 | } |
| @@ -89,6 +92,17 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot) · 1 unmodified line | |||
| 89 | return 0; | 92 | return 0; |
| 90 | } | 93 | } |
| 91 | 94 | ||
| 95 | int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot) | ||
| 96 | { | ||
| 97 | int ret; | ||
| 98 | |||
| 99 | hyp_spin_lock(&pkvm_pgd_lock); | ||
| 100 | ret = pkvm_create_mappings_locked(from, to, prot); | ||
| 101 | hyp_spin_unlock(&pkvm_pgd_lock); | ||
| 102 | |||
| 103 | return ret; | ||
| 104 | } | ||
| 105 | |||
| 92 | int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back) | 106 | int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back) |
| 93 | { | 107 | { |
| 94 | unsigned long start, end; | 108 | unsigned long start, end; |
| @@ -58,6 +58,7 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · 57 unmodified lines | |||
| 58 | { | 58 | { |
| 59 | void *start, *end, *virt = hyp_phys_to_virt(phys); | 59 | void *start, *end, *virt = hyp_phys_to_virt(phys); |
| 60 | unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT; | 60 | unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT; |
| 61 | enum kvm_pgtable_prot prot; | ||
| 61 | int ret, i; | 62 | int ret, i; |
| 62 | 63 | ||
| 63 | /* Recreate the hyp page-table using the early page allocator */ | 64 | /* Recreate the hyp page-table using the early page allocator */ |
| @@ -83,10 +84,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · 19 unmodified lines | |||
| 83 | if (ret) | 84 | if (ret) |
| 84 | return ret; | 85 | return ret; |
| 85 | 86 | ||
| 86 | ret = pkvm_create_mappings(__start_rodata, __end_rodata, PAGE_HYP_RO); | ||
| 87 | if (ret) | ||
| 88 | return ret; | ||
| 89 | |||
| 90 | ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO); | 87 | ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO); |
| 91 | if (ret) | 88 | if (ret) |
| 92 | return ret; | 89 | return ret; |
| @@ -95,10 +92,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · 2 unmodified lines | |||
| 95 | if (ret) | 92 | if (ret) |
| 96 | return ret; | 93 | return ret; |
| 97 | 94 | ||
| 98 | ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, PAGE_HYP_RO); | ||
| 99 | if (ret) | ||
| 100 | return ret; | ||
| 101 | |||
| 102 | ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP); | 95 | ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP); |
| 103 | if (ret) | 96 | if (ret) |
| 104 | return ret; | 97 | return ret; |
| @@ -117,6 +110,24 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · 12 unmodified lines | |||
| 117 | return ret; | 110 | return ret; |
| 118 | } | 111 | } |
| 119 | 112 | ||
| 113 | /* | ||
| 114 | * Map the host's .bss and .rodata sections RO in the hypervisor, but | ||
| 115 | * transfer the ownership from the host to the hypervisor itself to | ||
| 116 | * make sure it can't be donated or shared with another entity. | ||
| 117 | * | ||
| 118 | * The ownership transition requires matching changes in the host | ||
| 119 | * stage-2. This will be done later (see finalize_host_mappings()) once | ||
| 120 | * the hyp_vmemmap is addressable. | ||
| 121 | */ | ||
| 122 | prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED); | ||
| 123 | ret = pkvm_create_mappings(__start_rodata, __end_rodata, prot); | ||
| 124 | if (ret) | ||
| 125 | return ret; | ||
| 126 | |||
| 127 | ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, prot); | ||
| 128 | if (ret) | ||
| 129 | return ret; | ||
| 130 | |||
| 120 | return 0; | 131 | return 0; |
| 121 | } | 132 | } |
| 122 | 133 | ||
| @@ -148,6 +159,57 @@ static void hpool_put_page(void *addr) · 25 unmodified lines | |||
| 148 | hyp_put_page(&hpool, addr); | 159 | hyp_put_page(&hpool, addr); |
| 149 | } | 160 | } |
| 150 | 161 | ||
| 162 | static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level, | ||
| 163 | kvm_pte_t *ptep, | ||
| 164 | enum kvm_pgtable_walk_flags flag, | ||
| 165 | void * const arg) | ||
| 166 | { | ||
| 167 | enum kvm_pgtable_prot prot; | ||
| 168 | enum pkvm_page_state state; | ||
| 169 | kvm_pte_t pte = *ptep; | ||
| 170 | phys_addr_t phys; | ||
| 171 | |||
| 172 | if (!kvm_pte_valid(pte)) | ||
| 173 | return 0; | ||
| 174 | |||
| 175 | if (level != (KVM_PGTABLE_MAX_LEVELS - 1)) | ||
| 176 | return -EINVAL; | ||
| 177 | |||
| 178 | phys = kvm_pte_to_phys(pte); | ||
| 179 | if (!addr_is_memory(phys)) | ||
| 180 | return 0; | ||
| 181 | |||
| 182 | /* | ||
| 183 | * Adjust the host stage-2 mappings to match the ownership attributes | ||
| 184 | * configured in the hypervisor stage-1. | ||
| 185 | */ | ||
| 186 | state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte)); | ||
| 187 | switch (state) { | ||
| 188 | case PKVM_PAGE_OWNED: | ||
| 189 | return host_stage2_set_owner_locked(phys, PAGE_SIZE, pkvm_hyp_id); | ||
| 190 | case PKVM_PAGE_SHARED_OWNED: | ||
| 191 | prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED); | ||
| 192 | break; | ||
| 193 | case PKVM_PAGE_SHARED_BORROWED: | ||
| 194 | prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED); | ||
| 195 | break; | ||
| 196 | default: | ||
| 197 | return -EINVAL; | ||
| 198 | } | ||
| 199 | |||
| 200 | return host_stage2_idmap_locked(phys, PAGE_SIZE, prot); | ||
| 201 | } | ||
| 202 | |||
| 203 | static int finalize_host_mappings(void) | ||
| 204 | { | ||
| 205 | struct kvm_pgtable_walker walker = { | ||
| 206 | .cb = finalize_host_mappings_walker, | ||
| 207 | .flags = KVM_PGTABLE_WALK_LEAF, | ||
| 208 | }; | ||
| 209 | |||
| 210 | return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker); | ||
| 211 | } | ||
| 212 | |||
| 151 | void __noreturn __pkvm_init_finalise(void) | 213 | void __noreturn __pkvm_init_finalise(void) |
| 152 | { | 214 | { |
| 153 | struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data); | 215 | struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data); |
| @@ -167,6 +229,10 @@ void __noreturn __pkvm_init_finalise(void) · 13 unmodified lines | |||
| 167 | if (ret) | 229 | if (ret) |
| 168 | goto out; | 230 | goto out; |
| 169 | 231 | ||
| 232 | ret = finalize_host_mappings(); | ||
| 233 | if (ret) | ||
| 234 | goto out; | ||
| 235 | |||
| 170 | pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) { | 236 | pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) { |
| 171 | .zalloc_page = hyp_zalloc_hyp_page, | 237 | .zalloc_page = hyp_zalloc_hyp_page, |
| 172 | .phys_to_virt = hyp_phys_to_virt, | 238 | .phys_to_virt = hyp_phys_to_virt, |
| @@ -41,7 +41,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 40 unmodified lines | |||
| 41 | ___activate_traps(vcpu); | 41 | ___activate_traps(vcpu); |
| 42 | __activate_traps_common(vcpu); | 42 | __activate_traps_common(vcpu); |
| 43 | 43 | ||
| 44 | val = CPTR_EL2_DEFAULT; | 44 | val = vcpu->arch.cptr_el2; |
| 45 | val |= CPTR_EL2_TTA | CPTR_EL2_TAM; | 45 | val |= CPTR_EL2_TTA | CPTR_EL2_TAM; |
| 46 | if (!update_fp_enabled(vcpu)) { | 46 | if (!update_fp_enabled(vcpu)) { |
| 47 | val |= CPTR_EL2_TFP | CPTR_EL2_TZ; | 47 | val |= CPTR_EL2_TFP | CPTR_EL2_TZ; |
| @@ -69,12 +69,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 21 unmodified lines | |||
| 69 | static void __deactivate_traps(struct kvm_vcpu *vcpu) | 69 | static void __deactivate_traps(struct kvm_vcpu *vcpu) |
| 70 | { | 70 | { |
| 71 | extern char __kvm_hyp_host_vector[]; | 71 | extern char __kvm_hyp_host_vector[]; |
| 72 | u64 mdcr_el2, cptr; | 72 | u64 cptr; |
| 73 | 73 | ||
| 74 | ___deactivate_traps(vcpu); | 74 | ___deactivate_traps(vcpu); |
| 75 | 75 | ||
| 76 | mdcr_el2 = read_sysreg(mdcr_el2); | ||
| 77 | |||
| 78 | if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { | 76 | if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { |
| 79 | u64 val; | 77 | u64 val; |
| 80 | 78 | ||
| @@ -92,13 +90,8 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) · 11 unmodified lines | |||
| 92 | isb(); | 90 | isb(); |
| 93 | } | 91 | } |
| 94 | 92 | ||
| 95 | __deactivate_traps_common(); | 93 | __deactivate_traps_common(vcpu); |
| 96 | |||
| 97 | mdcr_el2 &= MDCR_EL2_HPMN_MASK; | ||
| 98 | mdcr_el2 |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT; | ||
| 99 | mdcr_el2 |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT; | ||
| 100 | 94 | ||
| 101 | write_sysreg(mdcr_el2, mdcr_el2); | ||
| 102 | write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2); | 95 | write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2); |
| 103 | 96 | ||
| 104 | cptr = CPTR_EL2_DEFAULT; | 97 | cptr = CPTR_EL2_DEFAULT; |
| @@ -170,6 +163,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) · 65 unmodified lines | |||
| 170 | { | 163 | { |
| 171 | struct kvm_cpu_context *host_ctxt; | 164 | struct kvm_cpu_context *host_ctxt; |
| 172 | struct kvm_cpu_context *guest_ctxt; | 165 | struct kvm_cpu_context *guest_ctxt; |
| 166 | struct kvm_s2_mmu *mmu; | ||
| 173 | bool pmu_switch_needed; | 167 | bool pmu_switch_needed; |
| 174 | u64 exit_code; | 168 | u64 exit_code; |
| 175 | 169 | ||
| @@ -213,7 +207,8 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) · 37 unmodified lines | |||
| 213 | __sysreg32_restore_state(vcpu); | 207 | __sysreg32_restore_state(vcpu); |
| 214 | __sysreg_restore_state_nvhe(guest_ctxt); | 208 | __sysreg_restore_state_nvhe(guest_ctxt); |
| 215 | 209 | ||
| 216 | __load_guest_stage2(kern_hyp_va(vcpu->arch.hw_mmu)); | 210 | mmu = kern_hyp_va(vcpu->arch.hw_mmu); |
| 211 | __load_stage2(mmu, kern_hyp_va(mmu->arch)); | ||
| 217 | __activate_traps(vcpu); | 212 | __activate_traps(vcpu); |
| 218 | 213 | ||
| 219 | __hyp_vgic_restore_state(vcpu); | 214 | __hyp_vgic_restore_state(vcpu); |
| @@ -34,12 +34,12 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu, · 33 unmodified lines | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | /* | 36 | /* |
| 37 | * __load_guest_stage2() includes an ISB only when the AT | 37 | * __load_stage2() includes an ISB only when the AT |
| 38 | * workaround is applied. Take care of the opposite condition, | 38 | * workaround is applied. Take care of the opposite condition, |
| 39 | * ensuring that we always have an ISB, but not two ISBs back | 39 | * ensuring that we always have an ISB, but not two ISBs back |
| 40 | * to back. | 40 | * to back. |
| 41 | */ | 41 | */ |
| 42 | __load_guest_stage2(mmu); | 42 | __load_stage2(mmu, kern_hyp_va(mmu->arch)); |
| 43 | asm(ALTERNATIVE("isb", "nop", ARM64_WORKAROUND_SPECULATIVE_AT)); | 43 | asm(ALTERNATIVE("isb", "nop", ARM64_WORKAROUND_SPECULATIVE_AT)); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| @@ -11,16 +11,12 @@ · 10 unmodified lines | |||
| 11 | #include <asm/kvm_pgtable.h> | 11 | #include <asm/kvm_pgtable.h> |
| 12 | #include <asm/stage2_pgtable.h> | 12 | #include <asm/stage2_pgtable.h> |
| 13 | 13 | ||
| 14 | #define KVM_PTE_VALID BIT(0) | ||
| 15 | 14 | ||
| 16 | #define KVM_PTE_TYPE BIT(1) | 15 | #define KVM_PTE_TYPE BIT(1) |
| 17 | #define KVM_PTE_TYPE_BLOCK 0 | 16 | #define KVM_PTE_TYPE_BLOCK 0 |
| 18 | #define KVM_PTE_TYPE_PAGE 1 | 17 | #define KVM_PTE_TYPE_PAGE 1 |
| 19 | #define KVM_PTE_TYPE_TABLE 1 | 18 | #define KVM_PTE_TYPE_TABLE 1 |
| 20 | 19 | ||
| 21 | #define KVM_PTE_ADDR_MASK GENMASK(47, PAGE_SHIFT) | ||
| 22 | #define KVM_PTE_ADDR_51_48 GENMASK(15, 12) | ||
| 23 | |||
| 24 | #define KVM_PTE_LEAF_ATTR_LO GENMASK(11, 2) | 20 | #define KVM_PTE_LEAF_ATTR_LO GENMASK(11, 2) |
| 25 | 21 | ||
| 26 | #define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX GENMASK(4, 2) | 22 | #define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX GENMASK(4, 2) |
| @@ -40,6 +36,8 @@ · 13 unmodified lines | |||
| 40 | 36 | ||
| 41 | #define KVM_PTE_LEAF_ATTR_HI GENMASK(63, 51) | 37 | #define KVM_PTE_LEAF_ATTR_HI GENMASK(63, 51) |
| 42 | 38 | ||
| 39 | #define KVM_PTE_LEAF_ATTR_HI_SW GENMASK(58, 55) | ||
| 40 | |||
| 43 | #define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54) | 41 | #define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54) |
| 44 | 42 | ||
| 45 | #define KVM_PTE_LEAF_ATTR_HI_S2_XN BIT(54) | 43 | #define KVM_PTE_LEAF_ATTR_HI_S2_XN BIT(54) |
| @@ -48,9 +46,7 @@ · 2 unmodified lines | |||
| 48 | KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \ | 46 | KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \ |
| 49 | KVM_PTE_LEAF_ATTR_HI_S2_XN) | 47 | KVM_PTE_LEAF_ATTR_HI_S2_XN) |
| 50 | 48 | ||
| 51 | #define KVM_PTE_LEAF_ATTR_S2_IGNORED GENMASK(58, 55) | 49 | #define KVM_INVALID_PTE_OWNER_MASK GENMASK(9, 2) |
| 52 | |||
| 53 | #define KVM_INVALID_PTE_OWNER_MASK GENMASK(63, 56) | ||
| 54 | #define KVM_MAX_OWNER_ID 1 | 50 | #define KVM_MAX_OWNER_ID 1 |
| 55 | 51 | ||
| 56 | struct kvm_pgtable_walk_data { | 52 | struct kvm_pgtable_walk_data { |
| @@ -61,17 +57,6 @@ struct kvm_pgtable_walk_data { · 4 unmodified lines | |||
| 61 | u64 end; | 57 | u64 end; |
| 62 | }; | 58 | }; |
| 63 | 59 | ||
| 64 | static u64 kvm_granule_shift(u32 level) | ||
| 65 | { | ||
| 66 | /* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */ | ||
| 67 | return ARM64_HW_PGTABLE_LEVEL_SHIFT(level); | ||
| 68 | } | ||
| 69 | |||
| 70 | static u64 kvm_granule_size(u32 level) | ||
| 71 | { | ||
| 72 | return BIT(kvm_granule_shift(level)); | ||
| 73 | } | ||
| 74 | |||
| 75 | #define KVM_PHYS_INVALID (-1ULL) | 60 | #define KVM_PHYS_INVALID (-1ULL) |
| 76 | 61 | ||
| 77 | static bool kvm_phys_is_valid(u64 phys) | 62 | static bool kvm_phys_is_valid(u64 phys) |
| @@ -79,15 +64,6 @@ static bool kvm_phys_is_valid(u64 phys) · 1 unmodified line | |||
| 79 | return phys < BIT(id_aa64mmfr0_parange_to_phys_shift(ID_AA64MMFR0_PARANGE_MAX)); | 64 | return phys < BIT(id_aa64mmfr0_parange_to_phys_shift(ID_AA64MMFR0_PARANGE_MAX)); |
| 80 | } | 65 | } |
| 81 | 66 | ||
| 82 | static bool kvm_level_supports_block_mapping(u32 level) | ||
| 83 | { | ||
| 84 | /* | ||
| 85 | * Reject invalid block mappings and don't bother with 4TB mappings for | ||
| 86 | * 52-bit PAs. | ||
| 87 | */ | ||
| 88 | return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1)); | ||
| 89 | } | ||
| 90 | |||
| 91 | static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level) | 67 | static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level) |
| 92 | { | 68 | { |
| 93 | u64 granule = kvm_granule_size(level); | 69 | u64 granule = kvm_granule_size(level); |
| @@ -135,11 +111,6 @@ static u32 kvm_pgd_pages(u32 ia_bits, u32 start_level) · 41 unmodified lines | |||
| 135 | return __kvm_pgd_page_idx(&pgt, -1ULL) + 1; | 111 | return __kvm_pgd_page_idx(&pgt, -1ULL) + 1; |
| 136 | } | 112 | } |
| 137 | 113 | ||
| 138 | static bool kvm_pte_valid(kvm_pte_t pte) | ||
| 139 | { | ||
| 140 | return pte & KVM_PTE_VALID; | ||
| 141 | } | ||
| 142 | |||
| 143 | static bool kvm_pte_table(kvm_pte_t pte, u32 level) | 114 | static bool kvm_pte_table(kvm_pte_t pte, u32 level) |
| 144 | { | 115 | { |
| 145 | if (level == KVM_PGTABLE_MAX_LEVELS - 1) | 116 | if (level == KVM_PGTABLE_MAX_LEVELS - 1) |
| @@ -151,16 +122,6 @@ static bool kvm_pte_table(kvm_pte_t pte, u32 level) · 5 unmodified lines | |||
| 151 | return FIELD_GET(KVM_PTE_TYPE, pte) == KVM_PTE_TYPE_TABLE; | 122 | return FIELD_GET(KVM_PTE_TYPE, pte) == KVM_PTE_TYPE_TABLE; |
| 152 | } | 123 | } |
| 153 | 124 | ||
| 154 | static u64 kvm_pte_to_phys(kvm_pte_t pte) | ||
| 155 | { | ||
| 156 | u64 pa = pte & KVM_PTE_ADDR_MASK; | ||
| 157 | |||
| 158 | if (PAGE_SHIFT == 16) | ||
| 159 | pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48; | ||
| 160 | |||
| 161 | return pa; | ||
| 162 | } | ||
| 163 | |||
| 164 | static kvm_pte_t kvm_phys_to_pte(u64 pa) | 125 | static kvm_pte_t kvm_phys_to_pte(u64 pa) |
| 165 | { | 126 | { |
| 166 | kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK; | 127 | kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK; |
| @@ -326,6 +287,45 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, · 159 unmodified lines | |||
| 326 | return _kvm_pgtable_walk(&walk_data); | 287 | return _kvm_pgtable_walk(&walk_data); |
| 327 | } | 288 | } |
| 328 | 289 | ||
| 290 | struct leaf_walk_data { | ||
| 291 | kvm_pte_t pte; | ||
| 292 | u32 level; | ||
| 293 | }; | ||
| 294 | |||
| 295 | static int leaf_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, | ||
| 296 | enum kvm_pgtable_walk_flags flag, void * const arg) | ||
| 297 | { | ||
| 298 | struct leaf_walk_data *data = arg; | ||
| 299 | |||
| 300 | data->pte = *ptep; | ||
| 301 | data->level = level; | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, | ||
| 307 | kvm_pte_t *ptep, u32 *level) | ||
| 308 | { | ||
| 309 | struct leaf_walk_data data; | ||
| 310 | struct kvm_pgtable_walker walker = { | ||
| 311 | .cb = leaf_walker, | ||
| 312 | .flags = KVM_PGTABLE_WALK_LEAF, | ||
| 313 | .arg = &data, | ||
| 314 | }; | ||
| 315 | int ret; | ||
| 316 | |||
| 317 | ret = kvm_pgtable_walk(pgt, ALIGN_DOWN(addr, PAGE_SIZE), | ||
| 318 | PAGE_SIZE, &walker); | ||
| 319 | if (!ret) { | ||
| 320 | if (ptep) | ||
| 321 | *ptep = data.pte; | ||
| 322 | if (level) | ||
| 323 | *level = data.level; | ||
| 324 | } | ||
| 325 | |||
| 326 | return ret; | ||
| 327 | } | ||
| 328 | |||
| 329 | struct hyp_map_data { | 329 | struct hyp_map_data { |
| 330 | u64 phys; | 330 | u64 phys; |
| 331 | kvm_pte_t attr; | 331 | kvm_pte_t attr; |
| @@ -357,11 +357,47 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep) · 25 unmodified lines | |||
| 357 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_AP, ap); | 357 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_AP, ap); |
| 358 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_SH, sh); | 358 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_SH, sh); |
| 359 | attr |= KVM_PTE_LEAF_ATTR_LO_S1_AF; | 359 | attr |= KVM_PTE_LEAF_ATTR_LO_S1_AF; |
| 360 | attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW; | ||
| 360 | *ptep = attr; | 361 | *ptep = attr; |
| 361 | 362 | ||
| 362 | return 0; | 363 | return 0; |
| 363 | } | 364 | } |
| 364 | 365 | ||
| 366 | enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte) | ||
| 367 | { | ||
| 368 | enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW; | ||
| 369 | u32 ap; | ||
| 370 | |||
| 371 | if (!kvm_pte_valid(pte)) | ||
| 372 | return prot; | ||
| 373 | |||
| 374 | if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN)) | ||
| 375 | prot |= KVM_PGTABLE_PROT_X; | ||
| 376 | |||
| 377 | ap = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_AP, pte); | ||
| 378 | if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RO) | ||
| 379 | prot |= KVM_PGTABLE_PROT_R; | ||
| 380 | else if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RW) | ||
| 381 | prot |= KVM_PGTABLE_PROT_RW; | ||
| 382 | |||
| 383 | return prot; | ||
| 384 | } | ||
| 385 | |||
| 386 | static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new) | ||
| 387 | { | ||
| 388 | /* | ||
| 389 | * Tolerate KVM recreating the exact same mapping, or changing software | ||
| 390 | * bits if the existing mapping was valid. | ||
| 391 | */ | ||
| 392 | if (old == new) | ||
| 393 | return false; | ||
| 394 | |||
| 395 | if (!kvm_pte_valid(old)) | ||
| 396 | return true; | ||
| 397 | |||
| 398 | return !WARN_ON((old ^ new) & ~KVM_PTE_LEAF_ATTR_HI_SW); | ||
| 399 | } | ||
| 400 | |||
| 365 | static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level, | 401 | static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level, |
| 366 | kvm_pte_t *ptep, struct hyp_map_data *data) | 402 | kvm_pte_t *ptep, struct hyp_map_data *data) |
| 367 | { | 403 | { |
| @@ -371,9 +407,8 @@ static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level, · 3 unmodified lines | |||
| 371 | if (!kvm_block_mapping_supported(addr, end, phys, level)) | 407 | if (!kvm_block_mapping_supported(addr, end, phys, level)) |
| 372 | return false; | 408 | return false; |
| 373 | 409 | ||
| 374 | /* Tolerate KVM recreating the exact same mapping */ | ||
| 375 | new = kvm_init_valid_leaf_pte(phys, data->attr, level); | 410 | new = kvm_init_valid_leaf_pte(phys, data->attr, level); |
| 376 | if (old != new && !WARN_ON(kvm_pte_valid(old))) | 411 | if (hyp_pte_needs_update(old, new)) |
| 377 | smp_store_release(ptep, new); | 412 | smp_store_release(ptep, new); |
| 378 | 413 | ||
| 379 | data->phys += granule; | 414 | data->phys += granule; |
| @@ -438,6 +473,8 @@ int kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits, · 58 unmodified lines | |||
| 438 | pgt->start_level = KVM_PGTABLE_MAX_LEVELS - levels; | 473 | pgt->start_level = KVM_PGTABLE_MAX_LEVELS - levels; |
| 439 | pgt->mm_ops = mm_ops; | 474 | pgt->mm_ops = mm_ops; |
| 440 | pgt->mmu = NULL; | 475 | pgt->mmu = NULL; |
| 476 | pgt->force_pte_cb = NULL; | ||
| 477 | |||
| 441 | return 0; | 478 | return 0; |
| 442 | } | 479 | } |
| 443 | 480 | ||
| @@ -475,6 +512,9 @@ struct stage2_map_data { · 31 unmodified lines | |||
| 475 | void *memcache; | 512 | void *memcache; |
| 476 | 513 | ||
| 477 | struct kvm_pgtable_mm_ops *mm_ops; | 514 | struct kvm_pgtable_mm_ops *mm_ops; |
| 515 | |||
| 516 | /* Force mappings to page granularity */ | ||
| 517 | bool force_pte; | ||
| 478 | }; | 518 | }; |
| 479 | 519 | ||
| 480 | u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift) | 520 | u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift) |
| @@ -539,11 +579,29 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p · 58 unmodified lines | |||
| 539 | 579 | ||
| 540 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S2_SH, sh); | 580 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S2_SH, sh); |
| 541 | attr |= KVM_PTE_LEAF_ATTR_LO_S2_AF; | 581 | attr |= KVM_PTE_LEAF_ATTR_LO_S2_AF; |
| 582 | attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW; | ||
| 542 | *ptep = attr; | 583 | *ptep = attr; |
| 543 | 584 | ||
| 544 | return 0; | 585 | return 0; |
| 545 | } | 586 | } |
| 546 | 587 | ||
| 588 | enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte) | ||
| 589 | { | ||
| 590 | enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW; | ||
| 591 | |||
| 592 | if (!kvm_pte_valid(pte)) | ||
| 593 | return prot; | ||
| 594 | |||
| 595 | if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R) | ||
| 596 | prot |= KVM_PGTABLE_PROT_R; | ||
| 597 | if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W) | ||
| 598 | prot |= KVM_PGTABLE_PROT_W; | ||
| 599 | if (!(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN)) | ||
| 600 | prot |= KVM_PGTABLE_PROT_X; | ||
| 601 | |||
| 602 | return prot; | ||
| 603 | } | ||
| 604 | |||
| 547 | static bool stage2_pte_needs_update(kvm_pte_t old, kvm_pte_t new) | 605 | static bool stage2_pte_needs_update(kvm_pte_t old, kvm_pte_t new) |
| 548 | { | 606 | { |
| 549 | if (!kvm_pte_valid(old) || !kvm_pte_valid(new)) | 607 | if (!kvm_pte_valid(old) || !kvm_pte_valid(new)) |
| @@ -588,6 +646,15 @@ static bool stage2_pte_executable(kvm_pte_t pte) · 38 unmodified lines | |||
| 588 | return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN); | 646 | return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN); |
| 589 | } | 647 | } |
| 590 | 648 | ||
| 649 | static bool stage2_leaf_mapping_allowed(u64 addr, u64 end, u32 level, | ||
| 650 | struct stage2_map_data *data) | ||
| 651 | { | ||
| 652 | if (data->force_pte && (level < (KVM_PGTABLE_MAX_LEVELS - 1))) | ||
| 653 | return false; | ||
| 654 | |||
| 655 | return kvm_block_mapping_supported(addr, end, data->phys, level); | ||
| 656 | } | ||
| 657 | |||
| 591 | static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, | 658 | static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, |
| 592 | kvm_pte_t *ptep, | 659 | kvm_pte_t *ptep, |
| 593 | struct stage2_map_data *data) | 660 | struct stage2_map_data *data) |
| @@ -597,7 +664,7 @@ static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, · 3 unmodified lines | |||
| 597 | struct kvm_pgtable *pgt = data->mmu->pgt; | 664 | struct kvm_pgtable *pgt = data->mmu->pgt; |
| 598 | struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; | 665 | struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; |
| 599 | 666 | ||
| 600 | if (!kvm_block_mapping_supported(addr, end, phys, level)) | 667 | if (!stage2_leaf_mapping_allowed(addr, end, level, data)) |
| 601 | return -E2BIG; | 668 | return -E2BIG; |
| 602 | 669 | ||
| 603 | if (kvm_phys_is_valid(phys)) | 670 | if (kvm_phys_is_valid(phys)) |
| @@ -641,7 +708,7 @@ static int stage2_map_walk_table_pre(u64 addr, u64 end, u32 level, · 37 unmodified lines | |||
| 641 | if (data->anchor) | 708 | if (data->anchor) |
| 642 | return 0; | 709 | return 0; |
| 643 | 710 | ||
| 644 | if (!kvm_block_mapping_supported(addr, end, data->phys, level)) | 711 | if (!stage2_leaf_mapping_allowed(addr, end, level, data)) |
| 645 | return 0; | 712 | return 0; |
| 646 | 713 | ||
| 647 | data->childp = kvm_pte_follow(*ptep, data->mm_ops); | 714 | data->childp = kvm_pte_follow(*ptep, data->mm_ops); |
| @@ -771,6 +838,7 @@ int kvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, · 123 unmodified lines | |||
| 771 | .mmu = pgt->mmu, | 838 | .mmu = pgt->mmu, |
| 772 | .memcache = mc, | 839 | .memcache = mc, |
| 773 | .mm_ops = pgt->mm_ops, | 840 | .mm_ops = pgt->mm_ops, |
| 841 | .force_pte = pgt->force_pte_cb && pgt->force_pte_cb(addr, addr + size, prot), | ||
| 774 | }; | 842 | }; |
| 775 | struct kvm_pgtable_walker walker = { | 843 | struct kvm_pgtable_walker walker = { |
| 776 | .cb = stage2_map_walker, | 844 | .cb = stage2_map_walker, |
| @@ -802,6 +870,7 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size, · 25 unmodified lines | |||
| 802 | .memcache = mc, | 870 | .memcache = mc, |
| 803 | .mm_ops = pgt->mm_ops, | 871 | .mm_ops = pgt->mm_ops, |
| 804 | .owner_id = owner_id, | 872 | .owner_id = owner_id, |
| 873 | .force_pte = true, | ||
| 805 | }; | 874 | }; |
| 806 | struct kvm_pgtable_walker walker = { | 875 | struct kvm_pgtable_walker walker = { |
| 807 | .cb = stage2_map_walker, | 876 | .cb = stage2_map_walker, |
| @@ -995,6 +1064,9 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, · 187 unmodified lines | |||
| 995 | u32 level; | 1064 | u32 level; |
| 996 | kvm_pte_t set = 0, clr = 0; | 1065 | kvm_pte_t set = 0, clr = 0; |
| 997 | 1066 | ||
| 1067 | if (prot & KVM_PTE_LEAF_ATTR_HI_SW) | ||
| 1068 | return -EINVAL; | ||
| 1069 | |||
| 998 | if (prot & KVM_PGTABLE_PROT_R) | 1070 | if (prot & KVM_PGTABLE_PROT_R) |
| 999 | set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R; | 1071 | set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R; |
| 1000 | 1072 | ||
| @@ -1043,9 +1115,11 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size) · 42 unmodified lines | |||
| 1043 | return kvm_pgtable_walk(pgt, addr, size, &walker); | 1115 | return kvm_pgtable_walk(pgt, addr, size, &walker); |
| 1044 | } | 1116 | } |
| 1045 | 1117 | ||
| 1046 | int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch, | 1118 | |
| 1047 | struct kvm_pgtable_mm_ops *mm_ops, | 1119 | int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch, |
| 1048 | enum kvm_pgtable_stage2_flags flags) | 1120 | struct kvm_pgtable_mm_ops *mm_ops, |
| 1121 | enum kvm_pgtable_stage2_flags flags, | ||
| 1122 | kvm_pgtable_force_pte_cb_t force_pte_cb) | ||
| 1049 | { | 1123 | { |
| 1050 | size_t pgd_sz; | 1124 | size_t pgd_sz; |
| 1051 | u64 vtcr = arch->vtcr; | 1125 | u64 vtcr = arch->vtcr; |
| @@ -1063,6 +1137,7 @@ int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch · 11 unmodified lines | |||
| 1063 | pgt->mm_ops = mm_ops; | 1137 | pgt->mm_ops = mm_ops; |
| 1064 | pgt->mmu = &arch->mmu; | 1138 | pgt->mmu = &arch->mmu; |
| 1065 | pgt->flags = flags; | 1139 | pgt->flags = flags; |
| 1140 | pgt->force_pte_cb = force_pte_cb; | ||
| 1066 | 1141 | ||
| 1067 | /* Ensure zeroed PGD pages are visible to the hardware walker */ | 1142 | /* Ensure zeroed PGD pages are visible to the hardware walker */ |
| 1068 | dsb(ishst); | 1143 | dsb(ishst); |
| @@ -1102,77 +1177,3 @@ void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) · 33 unmodified lines | |||
| 1102 | pgt->mm_ops->free_pages_exact(pgt->pgd, pgd_sz); | 1177 | pgt->mm_ops->free_pages_exact(pgt->pgd, pgd_sz); |
| 1103 | pgt->pgd = NULL; | 1178 | pgt->pgd = NULL; |
| 1104 | } | 1179 | } |
| 1105 | |||
| 1106 | #define KVM_PTE_LEAF_S2_COMPAT_MASK (KVM_PTE_LEAF_ATTR_S2_PERMS | \ | ||
| 1107 | KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR | \ | ||
| 1108 | KVM_PTE_LEAF_ATTR_S2_IGNORED) | ||
| 1109 | |||
| 1110 | static int stage2_check_permission_walker(u64 addr, u64 end, u32 level, | ||
| 1111 | kvm_pte_t *ptep, | ||
| 1112 | enum kvm_pgtable_walk_flags flag, | ||
| 1113 | void * const arg) | ||
| 1114 | { | ||
| 1115 | kvm_pte_t old_attr, pte = *ptep, *new_attr = arg; | ||
| 1116 | |||
| 1117 | /* | ||
| 1118 | * Compatible mappings are either invalid and owned by the page-table | ||
| 1119 | * owner (whose id is 0), or valid with matching permission attributes. | ||
| 1120 | */ | ||
| 1121 | if (kvm_pte_valid(pte)) { | ||
| 1122 | old_attr = pte & KVM_PTE_LEAF_S2_COMPAT_MASK; | ||
| 1123 | if (old_attr != *new_attr) | ||
| 1124 | return -EEXIST; | ||
| 1125 | } else if (pte) { | ||
| 1126 | return -EEXIST; | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | return 0; | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | int kvm_pgtable_stage2_find_range(struct kvm_pgtable *pgt, u64 addr, | ||
| 1133 | enum kvm_pgtable_prot prot, | ||
| 1134 | struct kvm_mem_range *range) | ||
| 1135 | { | ||
| 1136 | kvm_pte_t attr; | ||
| 1137 | struct kvm_pgtable_walker check_perm_walker = { | ||
| 1138 | .cb = stage2_check_permission_walker, | ||
| 1139 | .flags = KVM_PGTABLE_WALK_LEAF, | ||
| 1140 | .arg = &attr, | ||
| 1141 | }; | ||
| 1142 | u64 granule, start, end; | ||
| 1143 | u32 level; | ||
| 1144 | int ret; | ||
| 1145 | |||
| 1146 | ret = stage2_set_prot_attr(pgt, prot, &attr); | ||
| 1147 | if (ret) | ||
| 1148 | return ret; | ||
| 1149 | attr &= KVM_PTE_LEAF_S2_COMPAT_MASK; | ||
| 1150 | |||
| 1151 | for (level = pgt->start_level; level < KVM_PGTABLE_MAX_LEVELS; level++) { | ||
| 1152 | granule = kvm_granule_size(level); | ||
| 1153 | start = ALIGN_DOWN(addr, granule); | ||
| 1154 | end = start + granule; | ||
| 1155 | |||
| 1156 | if (!kvm_level_supports_block_mapping(level)) | ||
| 1157 | continue; | ||
| 1158 | |||
| 1159 | if (start < range->start || range->end < end) | ||
| 1160 | continue; | ||
| 1161 | |||
| 1162 | /* | ||
| 1163 | * Check the presence of existing mappings with incompatible | ||
| 1164 | * permissions within the current block range, and try one level | ||
| 1165 | * deeper if one is found. | ||
| 1166 | */ | ||
| 1167 | ret = kvm_pgtable_walk(pgt, start, granule, &check_perm_walker); | ||
| 1168 | if (ret != -EEXIST) | ||
| 1169 | break; | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | if (!ret) { | ||
| 1173 | range->start = start; | ||
| 1174 | range->end = end; | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | return ret; | ||
| 1178 | } | ||
| @@ -20,7 +20,7 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu) · 19 unmodified lines | |||
| 20 | __debug_switch_to_host_common(vcpu); | 20 | __debug_switch_to_host_common(vcpu); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | u32 __kvm_get_mdcr_el2(void) | 23 | u64 __kvm_get_mdcr_el2(void) |
| 24 | { | 24 | { |
| 25 | return read_sysreg(mdcr_el2); | 25 | return read_sysreg(mdcr_el2); |
| 26 | } | 26 | } |
| @@ -91,17 +91,9 @@ void activate_traps_vhe_load(struct kvm_vcpu *vcpu) · 90 unmodified lines | |||
| 91 | __activate_traps_common(vcpu); | 91 | __activate_traps_common(vcpu); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | void deactivate_traps_vhe_put(void) | 94 | void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu) |
| 95 | { | 95 | { |
| 96 | u64 mdcr_el2 = read_sysreg(mdcr_el2); | 96 | __deactivate_traps_common(vcpu); |
| 97 | |||
| 98 | mdcr_el2 &= MDCR_EL2_HPMN_MASK | | ||
| 99 | MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT | | ||
| 100 | MDCR_EL2_TPMS; | ||
| 101 | |||
| 102 | write_sysreg(mdcr_el2, mdcr_el2); | ||
| 103 | |||
| 104 | __deactivate_traps_common(); | ||
| 105 | } | 97 | } |
| 106 | 98 | ||
| 107 | /* Switch to the guest for VHE systems running in EL2 */ | 99 | /* Switch to the guest for VHE systems running in EL2 */ |
| @@ -124,11 +116,11 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) · 16 unmodified lines | |||
| 124 | * | 116 | * |
| 125 | * We have already configured the guest's stage 1 translation in | 117 | * We have already configured the guest's stage 1 translation in |
| 126 | * kvm_vcpu_load_sysregs_vhe above. We must now call | 118 | * kvm_vcpu_load_sysregs_vhe above. We must now call |
| 127 | * __load_guest_stage2 before __activate_traps, because | 119 | * __load_stage2 before __activate_traps, because |
| 128 | * __load_guest_stage2 configures stage 2 translation, and | 120 | * __load_stage2 configures stage 2 translation, and |
| 129 | * __activate_traps clear HCR_EL2.TGE (among other things). | 121 | * __activate_traps clear HCR_EL2.TGE (among other things). |
| 130 | */ | 122 | */ |
| 131 | __load_guest_stage2(vcpu->arch.hw_mmu); | 123 | __load_stage2(vcpu->arch.hw_mmu, vcpu->arch.hw_mmu->arch); |
| 132 | __activate_traps(vcpu); | 124 | __activate_traps(vcpu); |
| 133 | 125 | ||
| 134 | __kvm_adjust_pc(vcpu); | 126 | __kvm_adjust_pc(vcpu); |
| @@ -101,7 +101,7 @@ void kvm_vcpu_put_sysregs_vhe(struct kvm_vcpu *vcpu) · 100 unmodified lines | |||
| 101 | struct kvm_cpu_context *host_ctxt; | 101 | struct kvm_cpu_context *host_ctxt; |
| 102 | 102 | ||
| 103 | host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt; | 103 | host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt; |
| 104 | deactivate_traps_vhe_put(); | 104 | deactivate_traps_vhe_put(vcpu); |
| 105 | 105 | ||
| 106 | __sysreg_save_el1_state(guest_ctxt); | 106 | __sysreg_save_el1_state(guest_ctxt); |
| 107 | __sysreg_save_user_state(guest_ctxt); | 107 | __sysreg_save_user_state(guest_ctxt); |
| @@ -50,10 +50,10 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu, · 49 unmodified lines | |||
| 50 | * | 50 | * |
| 51 | * ARM erratum 1165522 requires some special handling (again), | 51 | * ARM erratum 1165522 requires some special handling (again), |
| 52 | * as we need to make sure both stages of translation are in | 52 | * as we need to make sure both stages of translation are in |
| 53 | * place before clearing TGE. __load_guest_stage2() already | 53 | * place before clearing TGE. __load_stage2() already |
| 54 | * has an ISB in order to deal with this. | 54 | * has an ISB in order to deal with this. |
| 55 | */ | 55 | */ |
| 56 | __load_guest_stage2(mmu); | 56 | __load_stage2(mmu, mmu->arch); |
| 57 | val = read_sysreg(hcr_el2); | 57 | val = read_sysreg(hcr_el2); |
| 58 | val &= ~HCR_TGE; | 58 | val &= ~HCR_TGE; |
| 59 | write_sysreg(val, hcr_el2); | 59 | write_sysreg(val, hcr_el2); |
| @@ -260,10 +260,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size, · 259 unmodified lines | |||
| 260 | { | 260 | { |
| 261 | int err; | 261 | int err; |
| 262 | 262 | ||
| 263 | if (!kvm_host_owns_hyp_mappings()) { | 263 | if (WARN_ON(!kvm_host_owns_hyp_mappings())) |
| 264 | return kvm_call_hyp_nvhe(__pkvm_create_mappings, | 264 | return -EINVAL; |
| 265 | start, size, phys, prot); | ||
| 266 | } | ||
| 267 | 265 | ||
| 268 | mutex_lock(&kvm_hyp_pgd_mutex); | 266 | mutex_lock(&kvm_hyp_pgd_mutex); |
| 269 | err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot); | 267 | err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot); |
| @@ -283,6 +281,21 @@ static phys_addr_t kvm_kaddr_to_phys(void *kaddr) · 13 unmodified lines | |||
| 283 | } | 281 | } |
| 284 | } | 282 | } |
| 285 | 283 | ||
| 284 | static int pkvm_share_hyp(phys_addr_t start, phys_addr_t end) | ||
| 285 | { | ||
| 286 | phys_addr_t addr; | ||
| 287 | int ret; | ||
| 288 | |||
| 289 | for (addr = ALIGN_DOWN(start, PAGE_SIZE); addr < end; addr += PAGE_SIZE) { | ||
| 290 | ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp, | ||
| 291 | __phys_to_pfn(addr)); | ||
| 292 | if (ret) | ||
| 293 | return ret; | ||
| 294 | } | ||
| 295 | |||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 286 | /** | 299 | /** |
| 287 | * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode | 300 | * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode |
| 288 | * @from: The virtual kernel start address of the range | 301 | * @from: The virtual kernel start address of the range |
| @@ -303,6 +316,13 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot) · 14 unmodified lines | |||
| 303 | if (is_kernel_in_hyp_mode()) | 316 | if (is_kernel_in_hyp_mode()) |
| 304 | return 0; | 317 | return 0; |
| 305 | 318 | ||
| 319 | if (!kvm_host_owns_hyp_mappings()) { | ||
| 320 | if (WARN_ON(prot != PAGE_HYP)) | ||
| 321 | return -EPERM; | ||
| 322 | return pkvm_share_hyp(kvm_kaddr_to_phys(from), | ||
| 323 | kvm_kaddr_to_phys(to)); | ||
| 324 | } | ||
| 325 | |||
| 306 | start = start & PAGE_MASK; | 326 | start = start & PAGE_MASK; |
| 307 | end = PAGE_ALIGN(end); | 327 | end = PAGE_ALIGN(end); |
| 308 | 328 | ||
| @@ -434,6 +454,32 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size, · 125 unmodified lines | |||
| 434 | return 0; | 454 | return 0; |
| 435 | } | 455 | } |
| 436 | 456 | ||
| 457 | static struct kvm_pgtable_mm_ops kvm_user_mm_ops = { | ||
| 458 | /* We shouldn't need any other callback to walk the PT */ | ||
| 459 | .phys_to_virt = kvm_host_va, | ||
| 460 | }; | ||
| 461 | |||
| 462 | static int get_user_mapping_size(struct kvm *kvm, u64 addr) | ||
| 463 | { | ||
| 464 | struct kvm_pgtable pgt = { | ||
| 465 | .pgd = (kvm_pte_t *)kvm->mm->pgd, | ||
| 466 | .ia_bits = VA_BITS, | ||
| 467 | .start_level = (KVM_PGTABLE_MAX_LEVELS - | ||
| 468 | CONFIG_PGTABLE_LEVELS), | ||
| 469 | .mm_ops = &kvm_user_mm_ops, | ||
| 470 | }; | ||
| 471 | kvm_pte_t pte = 0; /* Keep GCC quiet... */ | ||
| 472 | u32 level = ~0; | ||
| 473 | int ret; | ||
| 474 | |||
| 475 | ret = kvm_pgtable_get_leaf(&pgt, addr, &pte, &level); | ||
| 476 | VM_BUG_ON(ret); | ||
| 477 | VM_BUG_ON(level >= KVM_PGTABLE_MAX_LEVELS); | ||
| 478 | VM_BUG_ON(!(pte & PTE_VALID)); | ||
| 479 | |||
| 480 | return BIT(ARM64_HW_PGTABLE_LEVEL_SHIFT(level)); | ||
| 481 | } | ||
| 482 | |||
| 437 | static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = { | 483 | static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = { |
| 438 | .zalloc_page = stage2_memcache_zalloc_page, | 484 | .zalloc_page = stage2_memcache_zalloc_page, |
| 439 | .zalloc_pages_exact = kvm_host_zalloc_pages_exact, | 485 | .zalloc_pages_exact = kvm_host_zalloc_pages_exact, |
| @@ -486,7 +532,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu) · 46 unmodified lines | |||
| 486 | mmu->arch = &kvm->arch; | 532 | mmu->arch = &kvm->arch; |
| 487 | mmu->pgt = pgt; | 533 | mmu->pgt = pgt; |
| 488 | mmu->pgd_phys = __pa(pgt->pgd); | 534 | mmu->pgd_phys = __pa(pgt->pgd); |
| 489 | mmu->vmid.vmid_gen = 0; | 535 | WRITE_ONCE(mmu->vmid.vmid_gen, 0); |
| 490 | return 0; | 536 | return 0; |
| 491 | 537 | ||
| 492 | out_destroy_pgtable: | 538 | out_destroy_pgtable: |
| @@ -781,7 +827,7 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot, · 288 unmodified lines | |||
| 781 | * Returns the size of the mapping. | 827 | * Returns the size of the mapping. |
| 782 | */ | 828 | */ |
| 783 | static unsigned long | 829 | static unsigned long |
| 784 | transparent_hugepage_adjust(struct kvm_memory_slot *memslot, | 830 | transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot, |
| 785 | unsigned long hva, kvm_pfn_t *pfnp, | 831 | unsigned long hva, kvm_pfn_t *pfnp, |
| 786 | phys_addr_t *ipap) | 832 | phys_addr_t *ipap) |
| 787 | { | 833 | { |
| @@ -792,8 +838,8 @@ transparent_hugepage_adjust(struct kvm_memory_slot *memslot, · 4 unmodified lines | |||
| 792 | * sure that the HVA and IPA are sufficiently aligned and that the | 838 | * sure that the HVA and IPA are sufficiently aligned and that the |
| 793 | * block map is contained within the memslot. | 839 | * block map is contained within the memslot. |
| 794 | */ | 840 | */ |
| 795 | if (kvm_is_transparent_hugepage(pfn) && | 841 | if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE) && |
| 796 | fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE)) { | 842 | get_user_mapping_size(kvm, hva) >= PMD_SIZE) { |
| 797 | /* | 843 | /* |
| 798 | * The address we faulted on is backed by a transparent huge | 844 | * The address we faulted on is backed by a transparent huge |
| 799 | * page. However, because we map the compound huge page and | 845 | * page. However, because we map the compound huge page and |
| @@ -815,7 +861,7 @@ transparent_hugepage_adjust(struct kvm_memory_slot *memslot, · 15 unmodified lines | |||
| 815 | *ipap &= PMD_MASK; | 861 | *ipap &= PMD_MASK; |
| 816 | kvm_release_pfn_clean(pfn); | 862 | kvm_release_pfn_clean(pfn); |
| 817 | pfn &= ~(PTRS_PER_PMD - 1); | 863 | pfn &= ~(PTRS_PER_PMD - 1); |
| 818 | kvm_get_pfn(pfn); | 864 | get_page(pfn_to_page(pfn)); |
| 819 | *pfnp = pfn; | 865 | *pfnp = pfn; |
| 820 | 866 | ||
| 821 | return PMD_SIZE; | 867 | return PMD_SIZE; |
| @@ -1051,9 +1097,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, · 229 unmodified lines | |||
| 1051 | * If we are not forced to use page mapping, check if we are | 1097 | * If we are not forced to use page mapping, check if we are |
| 1052 | * backed by a THP and thus use block mapping if possible. | 1098 | * backed by a THP and thus use block mapping if possible. |
| 1053 | */ | 1099 | */ |
| 1054 | if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) | 1100 | if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) { |
| 1055 | vma_pagesize = transparent_hugepage_adjust(memslot, hva, | 1101 | if (fault_status == FSC_PERM && fault_granule > PAGE_SIZE) |
| 1056 | &pfn, &fault_ipa); | 1102 | vma_pagesize = fault_granule; |
| 1103 | else | ||
| 1104 | vma_pagesize = transparent_hugepage_adjust(kvm, memslot, | ||
| 1105 | hva, &pfn, | ||
| 1106 | &fault_ipa); | ||
| 1107 | } | ||
| 1057 | 1108 | ||
| 1058 | if (fault_status != FSC_PERM && !device && kvm_has_mte(kvm)) { | 1109 | if (fault_status != FSC_PERM && !device && kvm_has_mte(kvm)) { |
| 1059 | /* Check the VMM hasn't introduced a new VM_SHARED VMA */ | 1110 | /* Check the VMM hasn't introduced a new VM_SHARED VMA */ |
| @@ -50,7 +50,7 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = { · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | int kvm_perf_init(void) | 51 | int kvm_perf_init(void) |
| 52 | { | 52 | { |
| 53 | if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled()) | 53 | if (kvm_pmu_probe_pmuver() != ID_AA64DFR0_PMUVER_IMP_DEF && !is_protected_kvm_enabled()) |
| 54 | static_branch_enable(&kvm_arm_pmu_available); | 54 | static_branch_enable(&kvm_arm_pmu_available); |
| 55 | 55 | ||
| 56 | return perf_register_guest_info_callbacks(&kvm_guest_cbs); | 56 | return perf_register_guest_info_callbacks(&kvm_guest_cbs); |
| @@ -373,7 +373,6 @@ static u64 kvm_pmu_overflow_status(struct kvm_vcpu *vcpu) · 372 unmodified lines | |||
| 373 | reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0); | 373 | reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0); |
| 374 | reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0); | 374 | reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0); |
| 375 | reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1); | 375 | reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1); |
| 376 | reg &= kvm_pmu_valid_counter_mask(vcpu); | ||
| 377 | } | 376 | } |
| 378 | 377 | ||
| 379 | return reg; | 378 | return reg; |
| @@ -564,20 +563,21 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val) · 184 unmodified lines | |||
| 564 | */ | 563 | */ |
| 565 | void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) | 564 | void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) |
| 566 | { | 565 | { |
| 567 | unsigned long mask = kvm_pmu_valid_counter_mask(vcpu); | ||
| 568 | int i; | 566 | int i; |
| 569 | 567 | ||
| 570 | if (val & ARMV8_PMU_PMCR_E) { | 568 | if (val & ARMV8_PMU_PMCR_E) { |
| 571 | kvm_pmu_enable_counter_mask(vcpu, | 569 | kvm_pmu_enable_counter_mask(vcpu, |
| 572 | __vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask); | 570 | __vcpu_sys_reg(vcpu, PMCNTENSET_EL0)); |
| 573 | } else { | 571 | } else { |
| 574 | kvm_pmu_disable_counter_mask(vcpu, mask); | 572 | kvm_pmu_disable_counter_mask(vcpu, |
| 573 | __vcpu_sys_reg(vcpu, PMCNTENSET_EL0)); | ||
| 575 | } | 574 | } |
| 576 | 575 | ||
| 577 | if (val & ARMV8_PMU_PMCR_C) | 576 | if (val & ARMV8_PMU_PMCR_C) |
| 578 | kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0); | 577 | kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0); |
| 579 | 578 | ||
| 580 | if (val & ARMV8_PMU_PMCR_P) { | 579 | if (val & ARMV8_PMU_PMCR_P) { |
| 580 | unsigned long mask = kvm_pmu_valid_counter_mask(vcpu); | ||
| 581 | mask &= ~BIT(ARMV8_PMU_CYCLE_IDX); | 581 | mask &= ~BIT(ARMV8_PMU_CYCLE_IDX); |
| 582 | for_each_set_bit(i, &mask, 32) | 582 | for_each_set_bit(i, &mask, 32) |
| 583 | kvm_pmu_set_counter_value(vcpu, i, 0); | 583 | kvm_pmu_set_counter_value(vcpu, i, 0); |
| @@ -745,7 +745,7 @@ int kvm_pmu_probe_pmuver(void) · 161 unmodified lines | |||
| 745 | struct perf_event_attr attr = { }; | 745 | struct perf_event_attr attr = { }; |
| 746 | struct perf_event *event; | 746 | struct perf_event *event; |
| 747 | struct arm_pmu *pmu; | 747 | struct arm_pmu *pmu; |
| 748 | int pmuver = 0xf; | 748 | int pmuver = ID_AA64DFR0_PMUVER_IMP_DEF; |
| 749 | 749 | ||
| 750 | /* | 750 | /* |
| 751 | * Create a dummy event that only counts user cycles. As we'll never | 751 | * Create a dummy event that only counts user cycles. As we'll never |
| @@ -770,7 +770,7 @@ int kvm_pmu_probe_pmuver(void) · 18 unmodified lines | |||
| 770 | if (IS_ERR(event)) { | 770 | if (IS_ERR(event)) { |
| 771 | pr_err_once("kvm: pmu event creation failed %ld\n", | 771 | pr_err_once("kvm: pmu event creation failed %ld\n", |
| 772 | PTR_ERR(event)); | 772 | PTR_ERR(event)); |
| 773 | return 0xf; | 773 | return ID_AA64DFR0_PMUVER_IMP_DEF; |
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | if (event->pmu) { | 776 | if (event->pmu) { |
| @@ -923,7 +923,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) · 146 unmodified lines | |||
| 923 | if (!vcpu->kvm->arch.pmuver) | 923 | if (!vcpu->kvm->arch.pmuver) |
| 924 | vcpu->kvm->arch.pmuver = kvm_pmu_probe_pmuver(); | 924 | vcpu->kvm->arch.pmuver = kvm_pmu_probe_pmuver(); |
| 925 | 925 | ||
| 926 | if (vcpu->kvm->arch.pmuver == 0xf) | 926 | if (vcpu->kvm->arch.pmuver == ID_AA64DFR0_PMUVER_IMP_DEF) |
| 927 | return -ENODEV; | 927 | return -ENODEV; |
| 928 | 928 | ||
| 929 | switch (attr->attr) { | 929 | switch (attr->attr) { |
| @@ -59,6 +59,12 @@ static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu) · 58 unmodified lines | |||
| 59 | kvm_vcpu_kick(vcpu); | 59 | kvm_vcpu_kick(vcpu); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | static inline bool kvm_psci_valid_affinity(struct kvm_vcpu *vcpu, | ||
| 63 | unsigned long affinity) | ||
| 64 | { | ||
| 65 | return !(affinity & ~MPIDR_HWID_BITMASK); | ||
| 66 | } | ||
| 67 | |||
| 62 | static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) | 68 | static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) |
| 63 | { | 69 | { |
| 64 | struct vcpu_reset_state *reset_state; | 70 | struct vcpu_reset_state *reset_state; |
| @@ -66,9 +72,9 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) · 1 unmodified line | |||
| 66 | struct kvm_vcpu *vcpu = NULL; | 72 | struct kvm_vcpu *vcpu = NULL; |
| 67 | unsigned long cpu_id; | 73 | unsigned long cpu_id; |
| 68 | 74 | ||
| 69 | cpu_id = smccc_get_arg1(source_vcpu) & MPIDR_HWID_BITMASK; | 75 | cpu_id = smccc_get_arg1(source_vcpu); |
| 70 | if (vcpu_mode_is_32bit(source_vcpu)) | 76 | if (!kvm_psci_valid_affinity(source_vcpu, cpu_id)) |
| 71 | cpu_id &= ~((u32) 0); | 77 | return PSCI_RET_INVALID_PARAMS; |
| 72 | 78 | ||
| 73 | vcpu = kvm_mpidr_to_vcpu(kvm, cpu_id); | 79 | vcpu = kvm_mpidr_to_vcpu(kvm, cpu_id); |
| 74 | 80 | ||
| @@ -126,6 +132,9 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu) · 51 unmodified lines | |||
| 126 | target_affinity = smccc_get_arg1(vcpu); | 132 | target_affinity = smccc_get_arg1(vcpu); |
| 127 | lowest_affinity_level = smccc_get_arg2(vcpu); | 133 | lowest_affinity_level = smccc_get_arg2(vcpu); |
| 128 | 134 | ||
| 135 | if (!kvm_psci_valid_affinity(vcpu, target_affinity)) | ||
| 136 | return PSCI_RET_INVALID_PARAMS; | ||
| 137 | |||
| 129 | /* Determine target affinity mask */ | 138 | /* Determine target affinity mask */ |
| 130 | target_affinity_mask = psci_affinity_mask(lowest_affinity_level); | 139 | target_affinity_mask = psci_affinity_mask(lowest_affinity_level); |
| 131 | if (!target_affinity_mask) | 140 | if (!target_affinity_mask) |
| @@ -210,10 +210,16 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu) · 209 unmodified lines | |||
| 210 | */ | 210 | */ |
| 211 | int kvm_reset_vcpu(struct kvm_vcpu *vcpu) | 211 | int kvm_reset_vcpu(struct kvm_vcpu *vcpu) |
| 212 | { | 212 | { |
| 213 | struct vcpu_reset_state reset_state; | ||
| 213 | int ret; | 214 | int ret; |
| 214 | bool loaded; | 215 | bool loaded; |
| 215 | u32 pstate; | 216 | u32 pstate; |
| 216 | 217 | ||
| 218 | mutex_lock(&vcpu->kvm->lock); | ||
| 219 | reset_state = vcpu->arch.reset_state; | ||
| 220 | WRITE_ONCE(vcpu->arch.reset_state.reset, false); | ||
| 221 | mutex_unlock(&vcpu->kvm->lock); | ||
| 222 | |||
| 217 | /* Reset PMU outside of the non-preemptible section */ | 223 | /* Reset PMU outside of the non-preemptible section */ |
| 218 | kvm_pmu_vcpu_reset(vcpu); | 224 | kvm_pmu_vcpu_reset(vcpu); |
| 219 | 225 | ||
| @@ -276,8 +282,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) · 56 unmodified lines | |||
| 276 | * Additional reset state handling that PSCI may have imposed on us. | 282 | * Additional reset state handling that PSCI may have imposed on us. |
| 277 | * Must be done after all the sys_reg reset. | 283 | * Must be done after all the sys_reg reset. |
| 278 | */ | 284 | */ |
| 279 | if (vcpu->arch.reset_state.reset) { | 285 | if (reset_state.reset) { |
| 280 | unsigned long target_pc = vcpu->arch.reset_state.pc; | 286 | unsigned long target_pc = reset_state.pc; |
| 281 | 287 | ||
| 282 | /* Gracefully handle Thumb2 entry point */ | 288 | /* Gracefully handle Thumb2 entry point */ |
| 283 | if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) { | 289 | if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) { |
| @@ -286,13 +292,11 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) · 2 unmodified lines | |||
| 286 | } | 292 | } |
| 287 | 293 | ||
| 288 | /* Propagate caller endianness */ | 294 | /* Propagate caller endianness */ |
| 289 | if (vcpu->arch.reset_state.be) | 295 | if (reset_state.be) |
| 290 | kvm_vcpu_set_be(vcpu); | 296 | kvm_vcpu_set_be(vcpu); |
| 291 | 297 | ||
| 292 | *vcpu_pc(vcpu) = target_pc; | 298 | *vcpu_pc(vcpu) = target_pc; |
| 293 | vcpu_set_reg(vcpu, 0, vcpu->arch.reset_state.r0); | 299 | vcpu_set_reg(vcpu, 0, reset_state.r0); |
| 294 | |||
| 295 | vcpu->arch.reset_state.reset = false; | ||
| 296 | } | 300 | } |
| 297 | 301 | ||
| 298 | /* Reset timer */ | 302 | /* Reset timer */ |
| @@ -311,31 +315,26 @@ u32 get_kvm_ipa_limit(void) · 12 unmodified lines | |||
| 311 | 315 | ||
| 312 | int kvm_set_ipa_limit(void) | 316 | int kvm_set_ipa_limit(void) |
| 313 | { | 317 | { |
| 314 | unsigned int parange, tgran_2; | 318 | unsigned int parange; |
| 315 | u64 mmfr0; | 319 | u64 mmfr0; |
| 316 | 320 | ||
| 317 | mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); | 321 | mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); |
| 318 | parange = cpuid_feature_extract_unsigned_field(mmfr0, | 322 | parange = cpuid_feature_extract_unsigned_field(mmfr0, |
| 319 | ID_AA64MMFR0_PARANGE_SHIFT); | 323 | ID_AA64MMFR0_PARANGE_SHIFT); |
| 324 | /* | ||
| 325 | * IPA size beyond 48 bits could not be supported | ||
| 326 | * on either 4K or 16K page size. Hence let's cap | ||
| 327 | * it to 48 bits, in case it's reported as larger | ||
| 328 | * on the system. | ||
| 329 | */ | ||
| 330 | if (PAGE_SIZE != SZ_64K) | ||
| 331 | parange = min(parange, (unsigned int)ID_AA64MMFR0_PARANGE_48); | ||
| 320 | 332 | ||
| 321 | /* | 333 | /* |
| 322 | * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at | 334 | * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at |
| 323 | * Stage-2. If not, things will stop very quickly. | 335 | * Stage-2. If not, things will stop very quickly. |
| 324 | */ | 336 | */ |
| 325 | switch (PAGE_SIZE) { | 337 | switch (cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_TGRAN_2_SHIFT)) { |
| 326 | default: | ||
| 327 | case SZ_4K: | ||
| 328 | tgran_2 = ID_AA64MMFR0_TGRAN4_2_SHIFT; | ||
| 329 | break; | ||
| 330 | case SZ_16K: | ||
| 331 | tgran_2 = ID_AA64MMFR0_TGRAN16_2_SHIFT; | ||
| 332 | break; | ||
| 333 | case SZ_64K: | ||
| 334 | tgran_2 = ID_AA64MMFR0_TGRAN64_2_SHIFT; | ||
| 335 | break; | ||
| 336 | } | ||
| 337 | |||
| 338 | switch (cpuid_feature_extract_unsigned_field(mmfr0, tgran_2)) { | ||
| 339 | case ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE: | 338 | case ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE: |
| 340 | kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n"); | 339 | kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n"); |
| 341 | return -EINVAL; | 340 | return -EINVAL; |
| @@ -369,7 +368,7 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type) · 27 unmodified lines | |||
| 369 | phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type); | 368 | phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type); |
| 370 | if (phys_shift) { | 369 | if (phys_shift) { |
| 371 | if (phys_shift > kvm_ipa_limit || | 370 | if (phys_shift > kvm_ipa_limit || |
| 372 | phys_shift < 32) | 371 | phys_shift < ARM64_MIN_PARANGE_BITS) |
| 373 | return -EINVAL; | 372 | return -EINVAL; |
| 374 | } else { | 373 | } else { |
| 375 | phys_shift = KVM_PHYS_SHIFT; | 374 | phys_shift = KVM_PHYS_SHIFT; |
| @@ -44,10 +44,6 @@ · 43 unmodified lines | |||
| 44 | * 64bit interface. | 44 | * 64bit interface. |
| 45 | */ | 45 | */ |
| 46 | 46 | ||
| 47 | #define reg_to_encoding(x) \ | ||
| 48 | sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ | ||
| 49 | (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) | ||
| 50 | |||
| 51 | static bool read_from_write_only(struct kvm_vcpu *vcpu, | 47 | static bool read_from_write_only(struct kvm_vcpu *vcpu, |
| 52 | struct sys_reg_params *params, | 48 | struct sys_reg_params *params, |
| 53 | const struct sys_reg_desc *r) | 49 | const struct sys_reg_desc *r) |
| @@ -318,14 +314,14 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu, · 264 unmodified lines | |||
| 318 | /* | 314 | /* |
| 319 | * We want to avoid world-switching all the DBG registers all the | 315 | * We want to avoid world-switching all the DBG registers all the |
| 320 | * time: | 316 | * time: |
| 321 | * | 317 | * |
| 322 | * - If we've touched any debug register, it is likely that we're | 318 | * - If we've touched any debug register, it is likely that we're |
| 323 | * going to touch more of them. It then makes sense to disable the | 319 | * going to touch more of them. It then makes sense to disable the |
| 324 | * traps and start doing the save/restore dance | 320 | * traps and start doing the save/restore dance |
| 325 | * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is | 321 | * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is |
| 326 | * then mandatory to save/restore the registers, as the guest | 322 | * then mandatory to save/restore the registers, as the guest |
| 327 | * depends on them. | 323 | * depends on them. |
| 328 | * | 324 | * |
| 329 | * For this, we use a DIRTY bit, indicating the guest has modified the | 325 | * For this, we use a DIRTY bit, indicating the guest has modified the |
| 330 | * debug registers, used as follow: | 326 | * debug registers, used as follow: |
| 331 | * | 327 | * |
| @@ -603,6 +599,41 @@ static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu, · 271 unmodified lines | |||
| 603 | return REG_HIDDEN; | 599 | return REG_HIDDEN; |
| 604 | } | 600 | } |
| 605 | 601 | ||
| 602 | static void reset_pmu_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | ||
| 603 | { | ||
| 604 | u64 n, mask = BIT(ARMV8_PMU_CYCLE_IDX); | ||
| 605 | |||
| 606 | /* No PMU available, any PMU reg may UNDEF... */ | ||
| 607 | if (!kvm_arm_support_pmu_v3()) | ||
| 608 | return; | ||
| 609 | |||
| 610 | n = read_sysreg(pmcr_el0) >> ARMV8_PMU_PMCR_N_SHIFT; | ||
| 611 | n &= ARMV8_PMU_PMCR_N_MASK; | ||
| 612 | if (n) | ||
| 613 | mask |= GENMASK(n - 1, 0); | ||
| 614 | |||
| 615 | reset_unknown(vcpu, r); | ||
| 616 | __vcpu_sys_reg(vcpu, r->reg) &= mask; | ||
| 617 | } | ||
| 618 | |||
| 619 | static void reset_pmevcntr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | ||
| 620 | { | ||
| 621 | reset_unknown(vcpu, r); | ||
| 622 | __vcpu_sys_reg(vcpu, r->reg) &= GENMASK(31, 0); | ||
| 623 | } | ||
| 624 | |||
| 625 | static void reset_pmevtyper(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | ||
| 626 | { | ||
| 627 | reset_unknown(vcpu, r); | ||
| 628 | __vcpu_sys_reg(vcpu, r->reg) &= ARMV8_PMU_EVTYPE_MASK; | ||
| 629 | } | ||
| 630 | |||
| 631 | static void reset_pmselr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | ||
| 632 | { | ||
| 633 | reset_unknown(vcpu, r); | ||
| 634 | __vcpu_sys_reg(vcpu, r->reg) &= ARMV8_PMU_COUNTER_MASK; | ||
| 635 | } | ||
| 636 | |||
| 606 | static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | 637 | static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) |
| 607 | { | 638 | { |
| 608 | u64 pmcr, val; | 639 | u64 pmcr, val; |
| @@ -845,7 +876,7 @@ static bool access_pmcnten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 236 unmodified lines | |||
| 845 | kvm_pmu_disable_counter_mask(vcpu, val); | 876 | kvm_pmu_disable_counter_mask(vcpu, val); |
| 846 | } | 877 | } |
| 847 | } else { | 878 | } else { |
| 848 | p->regval = __vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask; | 879 | p->regval = __vcpu_sys_reg(vcpu, PMCNTENSET_EL0); |
| 849 | } | 880 | } |
| 850 | 881 | ||
| 851 | return true; | 882 | return true; |
| @@ -869,7 +900,7 @@ static bool access_pminten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 17 unmodified lines | |||
| 869 | /* accessing PMINTENCLR_EL1 */ | 900 | /* accessing PMINTENCLR_EL1 */ |
| 870 | __vcpu_sys_reg(vcpu, PMINTENSET_EL1) &= ~val; | 901 | __vcpu_sys_reg(vcpu, PMINTENSET_EL1) &= ~val; |
| 871 | } else { | 902 | } else { |
| 872 | p->regval = __vcpu_sys_reg(vcpu, PMINTENSET_EL1) & mask; | 903 | p->regval = __vcpu_sys_reg(vcpu, PMINTENSET_EL1); |
| 873 | } | 904 | } |
| 874 | 905 | ||
| 875 | return true; | 906 | return true; |
| @@ -891,7 +922,7 @@ static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 15 unmodified lines | |||
| 891 | /* accessing PMOVSCLR_EL0 */ | 922 | /* accessing PMOVSCLR_EL0 */ |
| 892 | __vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= ~(p->regval & mask); | 923 | __vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= ~(p->regval & mask); |
| 893 | } else { | 924 | } else { |
| 894 | p->regval = __vcpu_sys_reg(vcpu, PMOVSSET_EL0) & mask; | 925 | p->regval = __vcpu_sys_reg(vcpu, PMOVSSET_EL0); |
| 895 | } | 926 | } |
| 896 | 927 | ||
| 897 | return true; | 928 | return true; |
| @@ -944,16 +975,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 46 unmodified lines | |||
| 944 | trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } | 975 | trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } |
| 945 | 976 | ||
| 946 | #define PMU_SYS_REG(r) \ | 977 | #define PMU_SYS_REG(r) \ |
| 947 | SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility | 978 | SYS_DESC(r), .reset = reset_pmu_reg, .visibility = pmu_visibility |
| 948 | 979 | ||
| 949 | /* Macro to expand the PMEVCNTRn_EL0 register */ | 980 | /* Macro to expand the PMEVCNTRn_EL0 register */ |
| 950 | #define PMU_PMEVCNTR_EL0(n) \ | 981 | #define PMU_PMEVCNTR_EL0(n) \ |
| 951 | { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ | 982 | { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ |
| 983 | .reset = reset_pmevcntr, \ | ||
| 952 | .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), } | 984 | .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), } |
| 953 | 985 | ||
| 954 | /* Macro to expand the PMEVTYPERn_EL0 register */ | 986 | /* Macro to expand the PMEVTYPERn_EL0 register */ |
| 955 | #define PMU_PMEVTYPER_EL0(n) \ | 987 | #define PMU_PMEVTYPER_EL0(n) \ |
| 956 | { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \ | 988 | { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \ |
| 989 | .reset = reset_pmevtyper, \ | ||
| 957 | .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), } | 990 | .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), } |
| 958 | 991 | ||
| 959 | static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | 992 | static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| @@ -1026,8 +1059,6 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu, · 66 unmodified lines | |||
| 1026 | return true; | 1059 | return true; |
| 1027 | } | 1060 | } |
| 1028 | 1061 | ||
| 1029 | #define FEATURE(x) (GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT)) | ||
| 1030 | |||
| 1031 | /* Read a sanitised cpufeature ID register by sys_reg_desc */ | 1062 | /* Read a sanitised cpufeature ID register by sys_reg_desc */ |
| 1032 | static u64 read_id_reg(const struct kvm_vcpu *vcpu, | 1063 | static u64 read_id_reg(const struct kvm_vcpu *vcpu, |
| 1033 | struct sys_reg_desc const *r, bool raz) | 1064 | struct sys_reg_desc const *r, bool raz) |
| @@ -1038,40 +1069,40 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, · 4 unmodified lines | |||
| 1038 | switch (id) { | 1069 | switch (id) { |
| 1039 | case SYS_ID_AA64PFR0_EL1: | 1070 | case SYS_ID_AA64PFR0_EL1: |
| 1040 | if (!vcpu_has_sve(vcpu)) | 1071 | if (!vcpu_has_sve(vcpu)) |
| 1041 | val &= ~FEATURE(ID_AA64PFR0_SVE); | 1072 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE); |
| 1042 | val &= ~FEATURE(ID_AA64PFR0_AMU); | 1073 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU); |
| 1043 | val &= ~FEATURE(ID_AA64PFR0_CSV2); | 1074 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2); |
| 1044 | val |= FIELD_PREP(FEATURE(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2); | 1075 | val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2); |
| 1045 | val &= ~FEATURE(ID_AA64PFR0_CSV3); | 1076 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3); |
| 1046 | val |= FIELD_PREP(FEATURE(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3); | 1077 | val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3); |
| 1047 | break; | 1078 | break; |
| 1048 | case SYS_ID_AA64PFR1_EL1: | 1079 | case SYS_ID_AA64PFR1_EL1: |
| 1049 | val &= ~FEATURE(ID_AA64PFR1_MTE); | 1080 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE); |
| 1050 | if (kvm_has_mte(vcpu->kvm)) { | 1081 | if (kvm_has_mte(vcpu->kvm)) { |
| 1051 | u64 pfr, mte; | 1082 | u64 pfr, mte; |
| 1052 | 1083 | ||
| 1053 | pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1); | 1084 | pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1); |
| 1054 | mte = cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR1_MTE_SHIFT); | 1085 | mte = cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR1_MTE_SHIFT); |
| 1055 | val |= FIELD_PREP(FEATURE(ID_AA64PFR1_MTE), mte); | 1086 | val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR1_MTE), mte); |
| 1056 | } | 1087 | } |
| 1057 | break; | 1088 | break; |
| 1058 | case SYS_ID_AA64ISAR1_EL1: | 1089 | case SYS_ID_AA64ISAR1_EL1: |
| 1059 | if (!vcpu_has_ptrauth(vcpu)) | 1090 | if (!vcpu_has_ptrauth(vcpu)) |
| 1060 | val &= ~(FEATURE(ID_AA64ISAR1_APA) | | 1091 | val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) | |
| 1061 | FEATURE(ID_AA64ISAR1_API) | | 1092 | ARM64_FEATURE_MASK(ID_AA64ISAR1_API) | |
| 1062 | FEATURE(ID_AA64ISAR1_GPA) | | 1093 | ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) | |
| 1063 | FEATURE(ID_AA64ISAR1_GPI)); | 1094 | ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI)); |
| 1064 | break; | 1095 | break; |
| 1065 | case SYS_ID_AA64DFR0_EL1: | 1096 | case SYS_ID_AA64DFR0_EL1: |
| 1066 | /* Limit debug to ARMv8.0 */ | 1097 | /* Limit debug to ARMv8.0 */ |
| 1067 | val &= ~FEATURE(ID_AA64DFR0_DEBUGVER); | 1098 | val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER); |
| 1068 | val |= FIELD_PREP(FEATURE(ID_AA64DFR0_DEBUGVER), 6); | 1099 | val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), 6); |
| 1069 | /* Limit guests to PMUv3 for ARMv8.4 */ | 1100 | /* Limit guests to PMUv3 for ARMv8.4 */ |
| 1070 | val = cpuid_feature_cap_perfmon_field(val, | 1101 | val = cpuid_feature_cap_perfmon_field(val, |
| 1071 | ID_AA64DFR0_PMUVER_SHIFT, | 1102 | ID_AA64DFR0_PMUVER_SHIFT, |
| 1072 | kvm_vcpu_has_pmu(vcpu) ? ID_AA64DFR0_PMUVER_8_4 : 0); | 1103 | kvm_vcpu_has_pmu(vcpu) ? ID_AA64DFR0_PMUVER_8_4 : 0); |
| 1073 | /* Hide SPE from guests */ | 1104 | /* Hide SPE from guests */ |
| 1074 | val &= ~FEATURE(ID_AA64DFR0_PMSVER); | 1105 | val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER); |
| 1075 | break; | 1106 | break; |
| 1076 | case SYS_ID_DFR0_EL1: | 1107 | case SYS_ID_DFR0_EL1: |
| 1077 | /* Limit guests to PMUv3 for ARMv8.4 */ | 1108 | /* Limit guests to PMUv3 for ARMv8.4 */ |
| @@ -1249,6 +1280,20 @@ static int set_raz_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, · 171 unmodified lines | |||
| 1249 | return __set_id_reg(vcpu, rd, uaddr, true); | 1280 | return __set_id_reg(vcpu, rd, uaddr, true); |
| 1250 | } | 1281 | } |
| 1251 | 1282 | ||
| 1283 | static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, | ||
| 1284 | const struct kvm_one_reg *reg, void __user *uaddr) | ||
| 1285 | { | ||
| 1286 | int err; | ||
| 1287 | u64 val; | ||
| 1288 | |||
| 1289 | /* Perform the access even if we are going to ignore the value */ | ||
| 1290 | err = reg_from_user(&val, uaddr, sys_reg_to_index(rd)); | ||
| 1291 | if (err) | ||
| 1292 | return err; | ||
| 1293 | |||
| 1294 | return 0; | ||
| 1295 | } | ||
| 1296 | |||
| 1252 | static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | 1297 | static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| 1253 | const struct sys_reg_desc *r) | 1298 | const struct sys_reg_desc *r) |
| 1254 | { | 1299 | { |
| @@ -1592,16 +1637,21 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 337 unmodified lines | |||
| 1592 | .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, | 1637 | .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, |
| 1593 | { PMU_SYS_REG(SYS_PMOVSCLR_EL0), | 1638 | { PMU_SYS_REG(SYS_PMOVSCLR_EL0), |
| 1594 | .access = access_pmovs, .reg = PMOVSSET_EL0 }, | 1639 | .access = access_pmovs, .reg = PMOVSSET_EL0 }, |
| 1640 | /* | ||
| 1641 | * PM_SWINC_EL0 is exposed to userspace as RAZ/WI, as it was | ||
| 1642 | * previously (and pointlessly) advertised in the past... | ||
| 1643 | */ | ||
| 1595 | { PMU_SYS_REG(SYS_PMSWINC_EL0), | 1644 | { PMU_SYS_REG(SYS_PMSWINC_EL0), |
| 1596 | .access = access_pmswinc, .reg = PMSWINC_EL0 }, | 1645 | .get_user = get_raz_id_reg, .set_user = set_wi_reg, |
| 1646 | .access = access_pmswinc, .reset = NULL }, | ||
| 1597 | { PMU_SYS_REG(SYS_PMSELR_EL0), | 1647 | { PMU_SYS_REG(SYS_PMSELR_EL0), |
| 1598 | .access = access_pmselr, .reg = PMSELR_EL0 }, | 1648 | .access = access_pmselr, .reset = reset_pmselr, .reg = PMSELR_EL0 }, |
| 1599 | { PMU_SYS_REG(SYS_PMCEID0_EL0), | 1649 | { PMU_SYS_REG(SYS_PMCEID0_EL0), |
| 1600 | .access = access_pmceid, .reset = NULL }, | 1650 | .access = access_pmceid, .reset = NULL }, |
| 1601 | { PMU_SYS_REG(SYS_PMCEID1_EL0), | 1651 | { PMU_SYS_REG(SYS_PMCEID1_EL0), |
| 1602 | .access = access_pmceid, .reset = NULL }, | 1652 | .access = access_pmceid, .reset = NULL }, |
| 1603 | { PMU_SYS_REG(SYS_PMCCNTR_EL0), | 1653 | { PMU_SYS_REG(SYS_PMCCNTR_EL0), |
| 1604 | .access = access_pmu_evcntr, .reg = PMCCNTR_EL0 }, | 1654 | .access = access_pmu_evcntr, .reset = reset_unknown, .reg = PMCCNTR_EL0 }, |
| 1605 | { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), | 1655 | { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), |
| 1606 | .access = access_pmu_evtyper, .reset = NULL }, | 1656 | .access = access_pmu_evtyper, .reset = NULL }, |
| 1607 | { PMU_SYS_REG(SYS_PMXEVCNTR_EL0), | 1657 | { PMU_SYS_REG(SYS_PMXEVCNTR_EL0), |
| @@ -2106,23 +2156,6 @@ static int check_sysreg_table(const struct sys_reg_desc *table, unsigned int n, · 498 unmodified lines | |||
| 2106 | return 0; | 2156 | return 0; |
| 2107 | } | 2157 | } |
| 2108 | 2158 | ||
| 2109 | static int match_sys_reg(const void *key, const void *elt) | ||
| 2110 | { | ||
| 2111 | const unsigned long pval = (unsigned long)key; | ||
| 2112 | const struct sys_reg_desc *r = elt; | ||
| 2113 | |||
| 2114 | return pval - reg_to_encoding(r); | ||
| 2115 | } | ||
| 2116 | |||
| 2117 | static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params, | ||
| 2118 | const struct sys_reg_desc table[], | ||
| 2119 | unsigned int num) | ||
| 2120 | { | ||
| 2121 | unsigned long pval = reg_to_encoding(params); | ||
| 2122 | |||
| 2123 | return bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg); | ||
| 2124 | } | ||
| 2125 | |||
| 2126 | int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu) | 2159 | int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu) |
| 2127 | { | 2160 | { |
| 2128 | kvm_inject_undefined(vcpu); | 2161 | kvm_inject_undefined(vcpu); |
| @@ -2365,13 +2398,8 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu) · 236 unmodified lines | |||
| 2365 | 2398 | ||
| 2366 | trace_kvm_handle_sys_reg(esr); | 2399 | trace_kvm_handle_sys_reg(esr); |
| 2367 | 2400 | ||
| 2368 | params.Op0 = (esr >> 20) & 3; | 2401 | params = esr_sys64_to_params(esr); |
| 2369 | params.Op1 = (esr >> 14) & 0x7; | ||
| 2370 | params.CRn = (esr >> 10) & 0xf; | ||
| 2371 | params.CRm = (esr >> 1) & 0xf; | ||
| 2372 | params.Op2 = (esr >> 17) & 0x7; | ||
| 2373 | params.regval = vcpu_get_reg(vcpu, Rt); | 2402 | params.regval = vcpu_get_reg(vcpu, Rt); |
| 2374 | params.is_write = !(esr & 1); | ||
| 2375 | 2403 | ||
| 2376 | ret = emulate_sys_reg(vcpu, ¶ms); | 2404 | ret = emulate_sys_reg(vcpu, ¶ms); |
| 2377 | 2405 | ||
| @@ -11,6 +11,12 @@ · 10 unmodified lines | |||
| 11 | #ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__ | 11 | #ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__ |
| 12 | #define __ARM64_KVM_SYS_REGS_LOCAL_H__ | 12 | #define __ARM64_KVM_SYS_REGS_LOCAL_H__ |
| 13 | 13 | ||
| 14 | #include <linux/bsearch.h> | ||
| 15 | |||
| 16 | #define reg_to_encoding(x) \ | ||
| 17 | sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ | ||
| 18 | (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) | ||
| 19 | |||
| 14 | struct sys_reg_params { | 20 | struct sys_reg_params { |
| 15 | u8 Op0; | 21 | u8 Op0; |
| 16 | u8 Op1; | 22 | u8 Op1; |
| @@ -21,6 +27,14 @@ struct sys_reg_params { · 4 unmodified lines | |||
| 21 | bool is_write; | 27 | bool is_write; |
| 22 | }; | 28 | }; |
| 23 | 29 | ||
| 30 | #define esr_sys64_to_params(esr) \ | ||
| 31 | ((struct sys_reg_params){ .Op0 = ((esr) >> 20) & 3, \ | ||
| 32 | .Op1 = ((esr) >> 14) & 0x7, \ | ||
| 33 | .CRn = ((esr) >> 10) & 0xf, \ | ||
| 34 | .CRm = ((esr) >> 1) & 0xf, \ | ||
| 35 | .Op2 = ((esr) >> 17) & 0x7, \ | ||
| 36 | .is_write = !((esr) & 1) }) | ||
| 37 | |||
| 24 | struct sys_reg_desc { | 38 | struct sys_reg_desc { |
| 25 | /* Sysreg string for debug */ | 39 | /* Sysreg string for debug */ |
| 26 | const char *name; | 40 | const char *name; |
| @@ -152,6 +166,23 @@ static inline int cmp_sys_reg(const struct sys_reg_desc *i1, · 125 unmodified lines | |||
| 152 | return i1->Op2 - i2->Op2; | 166 | return i1->Op2 - i2->Op2; |
| 153 | } | 167 | } |
| 154 | 168 | ||
| 169 | static inline int match_sys_reg(const void *key, const void *elt) | ||
| 170 | { | ||
| 171 | const unsigned long pval = (unsigned long)key; | ||
| 172 | const struct sys_reg_desc *r = elt; | ||
| 173 | |||
| 174 | return pval - reg_to_encoding(r); | ||
| 175 | } | ||
| 176 | |||
| 177 | static inline const struct sys_reg_desc * | ||
| 178 | find_reg(const struct sys_reg_params *params, const struct sys_reg_desc table[], | ||
| 179 | unsigned int num) | ||
| 180 | { | ||
| 181 | unsigned long pval = reg_to_encoding(params); | ||
| 182 | |||
| 183 | return __inline_bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg); | ||
| 184 | } | ||
| 185 | |||
| 155 | const struct sys_reg_desc *find_reg_by_id(u64 id, | 186 | const struct sys_reg_desc *find_reg_by_id(u64 id, |
| 156 | struct sys_reg_params *params, | 187 | struct sys_reg_params *params, |
| 157 | const struct sys_reg_desc table[], | 188 | const struct sys_reg_desc table[], |
| @@ -78,13 +78,17 @@ TRACE_EVENT(kvm_arm_clear_debug, · 77 unmodified lines | |||
| 78 | TP_printk("flags: 0x%08x", __entry->guest_debug) | 78 | TP_printk("flags: 0x%08x", __entry->guest_debug) |
| 79 | ); | 79 | ); |
| 80 | 80 | ||
| 81 | /* | ||
| 82 | * The dreg32 name is a leftover from a distant past. This will really | ||
| 83 | * output a 64bit value... | ||
| 84 | */ | ||
| 81 | TRACE_EVENT(kvm_arm_set_dreg32, | 85 | TRACE_EVENT(kvm_arm_set_dreg32, |
| 82 | TP_PROTO(const char *name, __u32 value), | 86 | TP_PROTO(const char *name, __u64 value), |
| 83 | TP_ARGS(name, value), | 87 | TP_ARGS(name, value), |
| 84 | 88 | ||
| 85 | TP_STRUCT__entry( | 89 | TP_STRUCT__entry( |
| 86 | __field(const char *, name) | 90 | __field(const char *, name) |
| 87 | __field(__u32, value) | 91 | __field(__u64, value) |
| 88 | ), | 92 | ), |
| 89 | 93 | ||
| 90 | TP_fast_assign( | 94 | TP_fast_assign( |
| @@ -92,7 +96,7 @@ TRACE_EVENT(kvm_arm_set_dreg32, · 1 unmodified line | |||
| 92 | __entry->value = value; | 96 | __entry->value = value; |
| 93 | ), | 97 | ), |
| 94 | 98 | ||
| 95 | TP_printk("%s: 0x%08x", __entry->name, __entry->value) | 99 | TP_printk("%s: 0x%llx", __entry->name, __entry->value) |
| 96 | ); | 100 | ); |
| 97 | 101 | ||
| 98 | TRACE_DEFINE_SIZEOF(__u64); | 102 | TRACE_DEFINE_SIZEOF(__u64); |
| @@ -282,7 +282,7 @@ static unsigned long vgic_mmio_read_vcpuif(struct kvm_vcpu *vcpu, · 281 unmodified lines | |||
| 282 | case GIC_CPU_PRIMASK: | 282 | case GIC_CPU_PRIMASK: |
| 283 | /* | 283 | /* |
| 284 | * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the | 284 | * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the |
| 285 | * the PMR field as GICH_VMCR.VMPriMask rather than | 285 | * PMR field as GICH_VMCR.VMPriMask rather than |
| 286 | * GICC_PMR.Priority, so we expose the upper five bits of | 286 | * GICC_PMR.Priority, so we expose the upper five bits of |
| 287 | * priority mask to userspace using the lower bits in the | 287 | * priority mask to userspace using the lower bits in the |
| 288 | * unsigned long. | 288 | * unsigned long. |
| @@ -329,7 +329,7 @@ static void vgic_mmio_write_vcpuif(struct kvm_vcpu *vcpu, · 40 unmodified lines | |||
| 329 | case GIC_CPU_PRIMASK: | 329 | case GIC_CPU_PRIMASK: |
| 330 | /* | 330 | /* |
| 331 | * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the | 331 | * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the |
| 332 | * the PMR field as GICH_VMCR.VMPriMask rather than | 332 | * PMR field as GICH_VMCR.VMPriMask rather than |
| 333 | * GICC_PMR.Priority, so we expose the upper five bits of | 333 | * GICC_PMR.Priority, so we expose the upper five bits of |
| 334 | * priority mask to userspace using the lower bits in the | 334 | * priority mask to userspace using the lower bits in the |
| 335 | * unsigned long. | 335 | * unsigned long. |
| @@ -60,6 +60,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) · 59 unmodified lines | |||
| 60 | u32 val = cpuif->vgic_lr[lr]; | 60 | u32 val = cpuif->vgic_lr[lr]; |
| 61 | u32 cpuid, intid = val & GICH_LR_VIRTUALID; | 61 | u32 cpuid, intid = val & GICH_LR_VIRTUALID; |
| 62 | struct vgic_irq *irq; | 62 | struct vgic_irq *irq; |
| 63 | bool deactivated; | ||
| 63 | 64 | ||
| 64 | /* Extract the source vCPU id from the LR */ | 65 | /* Extract the source vCPU id from the LR */ |
| 65 | cpuid = val & GICH_LR_PHYSID_CPUID; | 66 | cpuid = val & GICH_LR_PHYSID_CPUID; |
| @@ -75,7 +76,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) · 9 unmodified lines | |||
| 75 | 76 | ||
| 76 | raw_spin_lock(&irq->irq_lock); | 77 | raw_spin_lock(&irq->irq_lock); |
| 77 | 78 | ||
| 78 | /* Always preserve the active bit */ | 79 | /* Always preserve the active bit, note deactivation */ |
| 80 | deactivated = irq->active && !(val & GICH_LR_ACTIVE_BIT); | ||
| 79 | irq->active = !!(val & GICH_LR_ACTIVE_BIT); | 81 | irq->active = !!(val & GICH_LR_ACTIVE_BIT); |
| 80 | 82 | ||
| 81 | if (irq->active && vgic_irq_is_sgi(intid)) | 83 | if (irq->active && vgic_irq_is_sgi(intid)) |
| @@ -96,36 +98,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) · 14 unmodified lines | |||
| 96 | if (irq->config == VGIC_CONFIG_LEVEL && !(val & GICH_LR_STATE)) | 98 | if (irq->config == VGIC_CONFIG_LEVEL && !(val & GICH_LR_STATE)) |
| 97 | irq->pending_latch = false; | 99 | irq->pending_latch = false; |
| 98 | 100 | ||
| 99 | /* | 101 | /* Handle resampling for mapped interrupts if required */ |
| 100 | * Level-triggered mapped IRQs are special because we only | 102 | vgic_irq_handle_resampling(irq, deactivated, val & GICH_LR_PENDING_BIT); |
| 101 | * observe rising edges as input to the VGIC. | ||
| 102 | * | ||
| 103 | * If the guest never acked the interrupt we have to sample | ||
| 104 | * the physical line and set the line level, because the | ||
| 105 | * device state could have changed or we simply need to | ||
| 106 | * process the still pending interrupt later. | ||
| 107 | * | ||
| 108 | * If this causes us to lower the level, we have to also clear | ||
| 109 | * the physical active state, since we will otherwise never be | ||
| 110 | * told when the interrupt becomes asserted again. | ||
| 111 | * | ||
| 112 | * Another case is when the interrupt requires a helping hand | ||
| 113 | * on deactivation (no HW deactivation, for example). | ||
| 114 | */ | ||
| 115 | if (vgic_irq_is_mapped_level(irq)) { | ||
| 116 | bool resample = false; | ||
| 117 | |||
| 118 | if (val & GICH_LR_PENDING_BIT) { | ||
| 119 | irq->line_level = vgic_get_phys_line_level(irq); | ||
| 120 | resample = !irq->line_level; | ||
| 121 | } else if (vgic_irq_needs_resampling(irq) && | ||
| 122 | !(irq->active || irq->pending_latch)) { | ||
| 123 | resample = true; | ||
| 124 | } | ||
| 125 | |||
| 126 | if (resample) | ||
| 127 | vgic_irq_set_phys_active(irq, false); | ||
| 128 | } | ||
| 129 | 103 | ||
| 130 | raw_spin_unlock(&irq->irq_lock); | 104 | raw_spin_unlock(&irq->irq_lock); |
| 131 | vgic_put_irq(vcpu->kvm, irq); | 105 | vgic_put_irq(vcpu->kvm, irq); |
| @@ -46,6 +46,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) · 45 unmodified lines | |||
| 46 | u32 intid, cpuid; | 46 | u32 intid, cpuid; |
| 47 | struct vgic_irq *irq; | 47 | struct vgic_irq *irq; |
| 48 | bool is_v2_sgi = false; | 48 | bool is_v2_sgi = false; |
| 49 | bool deactivated; | ||
| 49 | 50 | ||
| 50 | cpuid = val & GICH_LR_PHYSID_CPUID; | 51 | cpuid = val & GICH_LR_PHYSID_CPUID; |
| 51 | cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; | 52 | cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT; |
| @@ -68,7 +69,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) · 16 unmodified lines | |||
| 68 | 69 | ||
| 69 | raw_spin_lock(&irq->irq_lock); | 70 | raw_spin_lock(&irq->irq_lock); |
| 70 | 71 | ||
| 71 | /* Always preserve the active bit */ | 72 | /* Always preserve the active bit, note deactivation */ |
| 73 | deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT); | ||
| 72 | irq->active = !!(val & ICH_LR_ACTIVE_BIT); | 74 | irq->active = !!(val & ICH_LR_ACTIVE_BIT); |
| 73 | 75 | ||
| 74 | if (irq->active && is_v2_sgi) | 76 | if (irq->active && is_v2_sgi) |
| @@ -89,36 +91,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) · 14 unmodified lines | |||
| 89 | if (irq->config == VGIC_CONFIG_LEVEL && !(val & ICH_LR_STATE)) | 91 | if (irq->config == VGIC_CONFIG_LEVEL && !(val & ICH_LR_STATE)) |
| 90 | irq->pending_latch = false; | 92 | irq->pending_latch = false; |
| 91 | 93 | ||
| 92 | /* | 94 | /* Handle resampling for mapped interrupts if required */ |
| 93 | * Level-triggered mapped IRQs are special because we only | 95 | vgic_irq_handle_resampling(irq, deactivated, val & ICH_LR_PENDING_BIT); |
| 94 | * observe rising edges as input to the VGIC. | ||
| 95 | * | ||
| 96 | * If the guest never acked the interrupt we have to sample | ||
| 97 | * the physical line and set the line level, because the | ||
| 98 | * device state could have changed or we simply need to | ||
| 99 | * process the still pending interrupt later. | ||
| 100 | * | ||
| 101 | * If this causes us to lower the level, we have to also clear | ||
| 102 | * the physical active state, since we will otherwise never be | ||
| 103 | * told when the interrupt becomes asserted again. | ||
| 104 | * | ||
| 105 | * Another case is when the interrupt requires a helping hand | ||
| 106 | * on deactivation (no HW deactivation, for example). | ||
| 107 | */ | ||
| 108 | if (vgic_irq_is_mapped_level(irq)) { | ||
| 109 | bool resample = false; | ||
| 110 | |||
| 111 | if (val & ICH_LR_PENDING_BIT) { | ||
| 112 | irq->line_level = vgic_get_phys_line_level(irq); | ||
| 113 | resample = !irq->line_level; | ||
| 114 | } else if (vgic_irq_needs_resampling(irq) && | ||
| 115 | !(irq->active || irq->pending_latch)) { | ||
| 116 | resample = true; | ||
| 117 | } | ||
| 118 | |||
| 119 | if (resample) | ||
| 120 | vgic_irq_set_phys_active(irq, false); | ||
| 121 | } | ||
| 122 | 96 | ||
| 123 | raw_spin_unlock(&irq->irq_lock); | 97 | raw_spin_unlock(&irq->irq_lock); |
| 124 | vgic_put_irq(vcpu->kvm, irq); | 98 | vgic_put_irq(vcpu->kvm, irq); |
| @@ -106,7 +106,6 @@ struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, · 105 unmodified lines | |||
| 106 | if (intid >= VGIC_MIN_LPI) | 106 | if (intid >= VGIC_MIN_LPI) |
| 107 | return vgic_get_lpi(kvm, intid); | 107 | return vgic_get_lpi(kvm, intid); |
| 108 | 108 | ||
| 109 | WARN(1, "Looking up struct vgic_irq for reserved INTID"); | ||
| 110 | return NULL; | 109 | return NULL; |
| 111 | } | 110 | } |
| 112 | 111 | ||
| @@ -1022,3 +1021,41 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid) · 909 unmodified lines | |||
| 1022 | 1021 | ||
| 1023 | return map_is_active; | 1022 | return map_is_active; |
| 1024 | } | 1023 | } |
| 1024 | |||
| 1025 | /* | ||
| 1026 | * Level-triggered mapped IRQs are special because we only observe rising | ||
| 1027 | * edges as input to the VGIC. | ||
| 1028 | * | ||
| 1029 | * If the guest never acked the interrupt we have to sample the physical | ||
| 1030 | * line and set the line level, because the device state could have changed | ||
| 1031 | * or we simply need to process the still pending interrupt later. | ||
| 1032 | * | ||
| 1033 | * We could also have entered the guest with the interrupt active+pending. | ||
| 1034 | * On the next exit, we need to re-evaluate the pending state, as it could | ||
| 1035 | * otherwise result in a spurious interrupt by injecting a now potentially | ||
| 1036 | * stale pending state. | ||
| 1037 | * | ||
| 1038 | * If this causes us to lower the level, we have to also clear the physical | ||
| 1039 | * active state, since we will otherwise never be told when the interrupt | ||
| 1040 | * becomes asserted again. | ||
| 1041 | * | ||
| 1042 | * Another case is when the interrupt requires a helping hand on | ||
| 1043 | * deactivation (no HW deactivation, for example). | ||
| 1044 | */ | ||
| 1045 | void vgic_irq_handle_resampling(struct vgic_irq *irq, | ||
| 1046 | bool lr_deactivated, bool lr_pending) | ||
| 1047 | { | ||
| 1048 | if (vgic_irq_is_mapped_level(irq)) { | ||
| 1049 | bool resample = false; | ||
| 1050 | |||
| 1051 | if (unlikely(vgic_irq_needs_resampling(irq))) { | ||
| 1052 | resample = !(irq->active || irq->pending_latch); | ||
| 1053 | } else if (lr_pending || (lr_deactivated && irq->line_level)) { | ||
| 1054 | irq->line_level = vgic_get_phys_line_level(irq); | ||
| 1055 | resample = !irq->line_level; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | if (resample) | ||
| 1059 | vgic_irq_set_phys_active(irq, false); | ||
| 1060 | } | ||
| 1061 | } | ||
| @@ -169,6 +169,8 @@ void vgic_irq_set_phys_active(struct vgic_irq *irq, bool active); · 168 unmodified lines | |||
| 169 | bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq, | 169 | bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq, |
| 170 | unsigned long flags); | 170 | unsigned long flags); |
| 171 | void vgic_kick_vcpus(struct kvm *kvm); | 171 | void vgic_kick_vcpus(struct kvm *kvm); |
| 172 | void vgic_irq_handle_resampling(struct vgic_irq *irq, | ||
| 173 | bool lr_deactivated, bool lr_pending); | ||
| 172 | 174 | ||
| 173 | int vgic_check_ioaddr(struct kvm *kvm, phys_addr_t *ioaddr, | 175 | int vgic_check_ioaddr(struct kvm *kvm, phys_addr_t *ioaddr, |
| 174 | phys_addr_t addr, phys_addr_t alignment); | 176 | phys_addr_t addr, phys_addr_t alignment); |
| @@ -1339,7 +1339,6 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot) · 1338 unmodified lines | |||
| 1339 | return dt_virt; | 1339 | return dt_virt; |
| 1340 | } | 1340 | } |
| 1341 | 1341 | ||
| 1342 | #if CONFIG_PGTABLE_LEVELS > 3 | ||
| 1343 | int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot) | 1342 | int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot) |
| 1344 | { | 1343 | { |
| 1345 | pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); | 1344 | pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); |
| @@ -1354,16 +1353,6 @@ int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot) · 8 unmodified lines | |||
| 1354 | return 1; | 1353 | return 1; |
| 1355 | } | 1354 | } |
| 1356 | 1355 | ||
| 1357 | int pud_clear_huge(pud_t *pudp) | ||
| 1358 | { | ||
| 1359 | if (!pud_sect(READ_ONCE(*pudp))) | ||
| 1360 | return 0; | ||
| 1361 | pud_clear(pudp); | ||
| 1362 | return 1; | ||
| 1363 | } | ||
| 1364 | #endif | ||
| 1365 | |||
| 1366 | #if CONFIG_PGTABLE_LEVELS > 2 | ||
| 1367 | int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) | 1356 | int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) |
| 1368 | { | 1357 | { |
| 1369 | pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot)); | 1358 | pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot)); |
| @@ -1378,6 +1367,14 @@ int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) · 8 unmodified lines | |||
| 1378 | return 1; | 1367 | return 1; |
| 1379 | } | 1368 | } |
| 1380 | 1369 | ||
| 1370 | int pud_clear_huge(pud_t *pudp) | ||
| 1371 | { | ||
| 1372 | if (!pud_sect(READ_ONCE(*pudp))) | ||
| 1373 | return 0; | ||
| 1374 | pud_clear(pudp); | ||
| 1375 | return 1; | ||
| 1376 | } | ||
| 1377 | |||
| 1381 | int pmd_clear_huge(pmd_t *pmdp) | 1378 | int pmd_clear_huge(pmd_t *pmdp) |
| 1382 | { | 1379 | { |
| 1383 | if (!pmd_sect(READ_ONCE(*pmdp))) | 1380 | if (!pmd_sect(READ_ONCE(*pmdp))) |
| @@ -1385,7 +1382,6 @@ int pmd_clear_huge(pmd_t *pmdp) · 1 unmodified line | |||
| 1385 | pmd_clear(pmdp); | 1382 | pmd_clear(pmdp); |
| 1386 | return 1; | 1383 | return 1; |
| 1387 | } | 1384 | } |
| 1388 | #endif | ||
| 1389 | 1385 | ||
| 1390 | int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr) | 1386 | int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr) |
| 1391 | { | 1387 | { |
| @@ -823,6 +823,19 @@ emit_cond_jmp: · 822 unmodified lines | |||
| 823 | return ret; | 823 | return ret; |
| 824 | break; | 824 | break; |
| 825 | 825 | ||
| 826 | /* speculation barrier */ | ||
| 827 | case BPF_ST | BPF_NOSPEC: | ||
| 828 | /* | ||
| 829 | * Nothing required here. | ||
| 830 | * | ||
| 831 | * In case of arm64, we rely on the firmware mitigation of | ||
| 832 | * Speculative Store Bypass as controlled via the ssbd kernel | ||
| 833 | * parameter. Whenever the mitigation is enabled, it works | ||
| 834 | * for all of the kernel code with no need to provide any | ||
| 835 | * additional instructions. | ||
| 836 | */ | ||
| 837 | break; | ||
| 838 | |||
| 826 | /* ST: *(size *)(dst + off) = imm */ | 839 | /* ST: *(size *)(dst + off) = imm */ |
| 827 | case BPF_ST | BPF_MEM | BPF_W: | 840 | case BPF_ST | BPF_MEM | BPF_W: |
| 828 | case BPF_ST | BPF_MEM | BPF_H: | 841 | case BPF_ST | BPF_MEM | BPF_H: |
| @@ -44,7 +44,6 @@ config H8300_H8MAX · 43 unmodified lines | |||
| 44 | bool "H8MAX" | 44 | bool "H8MAX" |
| 45 | select H83069 | 45 | select H83069 |
| 46 | select RAMKERNEL | 46 | select RAMKERNEL |
| 47 | select HAVE_IDE | ||
| 48 | help | 47 | help |
| 49 | H8MAX Evaluation Board Support | 48 | H8MAX Evaluation Board Support |
| 50 | More Information. (Japanese Only) | 49 | More Information. (Japanese Only) |
| @@ -25,7 +25,6 @@ config IA64 · 24 unmodified lines | |||
| 25 | select HAVE_ASM_MODVERSIONS | 25 | select HAVE_ASM_MODVERSIONS |
| 26 | select HAVE_UNSTABLE_SCHED_CLOCK | 26 | select HAVE_UNSTABLE_SCHED_CLOCK |
| 27 | select HAVE_EXIT_THREAD | 27 | select HAVE_EXIT_THREAD |
| 28 | select HAVE_IDE | ||
| 29 | select HAVE_KPROBES | 28 | select HAVE_KPROBES |
| 30 | select HAVE_KRETPROBES | 29 | select HAVE_KRETPROBES |
| 31 | select HAVE_FTRACE_MCOUNT_RECORD | 30 | select HAVE_FTRACE_MCOUNT_RECORD |
| @@ -23,7 +23,6 @@ config M68K · 22 unmodified lines | |||
| 23 | select HAVE_DEBUG_BUGVERBOSE | 23 | select HAVE_DEBUG_BUGVERBOSE |
| 24 | select HAVE_EFFICIENT_UNALIGNED_ACCESS if !CPU_HAS_NO_UNALIGNED | 24 | select HAVE_EFFICIENT_UNALIGNED_ACCESS if !CPU_HAS_NO_UNALIGNED |
| 25 | select HAVE_FUTEX_CMPXCHG if MMU && FUTEX | 25 | select HAVE_FUTEX_CMPXCHG if MMU && FUTEX |
| 26 | select HAVE_IDE | ||
| 27 | select HAVE_MOD_ARCH_SPECIFIC | 26 | select HAVE_MOD_ARCH_SPECIFIC |
| 28 | select HAVE_UID16 | 27 | select HAVE_UID16 |
| 29 | select MMU_GATHER_NO_RANGE if MMU | 28 | select MMU_GATHER_NO_RANGE if MMU |
| @@ -33,6 +33,7 @@ config MAC · 32 unmodified lines | |||
| 33 | depends on MMU | 33 | depends on MMU |
| 34 | select MMU_MOTOROLA if MMU | 34 | select MMU_MOTOROLA if MMU |
| 35 | select HAVE_ARCH_NVRAM_OPS | 35 | select HAVE_ARCH_NVRAM_OPS |
| 36 | select HAVE_PATA_PLATFORM | ||
| 36 | select LEGACY_TIMER_TICK | 37 | select LEGACY_TIMER_TICK |
| 37 | help | 38 | help |
| 38 | This option enables support for the Apple Macintosh series of | 39 | This option enables support for the Apple Macintosh series of |
| @@ -26,7 +26,7 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); · 25 unmodified lines | |||
| 26 | DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); | 26 | DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); |
| 27 | 27 | ||
| 28 | static struct clk_lookup m525x_clk_lookup[] = { | 28 | static struct clk_lookup m525x_clk_lookup[] = { |
| 29 | CLKDEV_INIT(NULL, "pll.0", &pll), | 29 | CLKDEV_INIT(NULL, "pll.0", &clk_pll), |
| 30 | CLKDEV_INIT(NULL, "sys.0", &clk_sys), | 30 | CLKDEV_INIT(NULL, "sys.0", &clk_sys), |
| 31 | CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), | 31 | CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), |
| 32 | CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), | 32 | CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), |
| @@ -71,7 +71,6 @@ config MIPS · 70 unmodified lines | |||
| 71 | select HAVE_FUNCTION_TRACER | 71 | select HAVE_FUNCTION_TRACER |
| 72 | select HAVE_GCC_PLUGINS | 72 | select HAVE_GCC_PLUGINS |
| 73 | select HAVE_GENERIC_VDSO | 73 | select HAVE_GENERIC_VDSO |
| 74 | select HAVE_IDE | ||
| 75 | select HAVE_IOREMAP_PROT | 74 | select HAVE_IOREMAP_PROT |
| 76 | select HAVE_IRQ_EXIT_ON_IRQ_STACK | 75 | select HAVE_IRQ_EXIT_ON_IRQ_STACK |
| 77 | select HAVE_IRQ_TIME_ACCOUNTING | 76 | select HAVE_IRQ_TIME_ACCOUNTING |
| @@ -1355,6 +1355,9 @@ jeq_common: · 1354 unmodified lines | |||
| 1355 | } | 1355 | } |
| 1356 | break; | 1356 | break; |
| 1357 | 1357 | ||
| 1358 | case BPF_ST | BPF_NOSPEC: /* speculation barrier */ | ||
| 1359 | break; | ||
| 1360 | |||
| 1358 | case BPF_ST | BPF_B | BPF_MEM: | 1361 | case BPF_ST | BPF_B | BPF_MEM: |
| 1359 | case BPF_ST | BPF_H | BPF_MEM: | 1362 | case BPF_ST | BPF_H | BPF_MEM: |
| 1360 | case BPF_ST | BPF_W | BPF_MEM: | 1363 | case BPF_ST | BPF_W | BPF_MEM: |
| @@ -59,7 +59,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, · 58 unmodified lines | |||
| 59 | 59 | ||
| 60 | vma = find_vma(mm, addr); | 60 | vma = find_vma(mm, addr); |
| 61 | if (TASK_SIZE - len >= addr && | 61 | if (TASK_SIZE - len >= addr && |
| 62 | (!vma || addr + len <= vma->vm_start)) | 62 | (!vma || addr + len <= vm_start_gap(vma))) |
| 63 | return addr; | 63 | return addr; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| @@ -3,7 +3,6 @@ config PARISC · 2 unmodified lines | |||
| 3 | def_bool y | 3 | def_bool y |
| 4 | select ARCH_32BIT_OFF_T if !64BIT | 4 | select ARCH_32BIT_OFF_T if !64BIT |
| 5 | select ARCH_MIGHT_HAVE_PC_PARPORT | 5 | select ARCH_MIGHT_HAVE_PC_PARPORT |
| 6 | select HAVE_IDE | ||
| 7 | select HAVE_FUNCTION_TRACER | 6 | select HAVE_FUNCTION_TRACER |
| 8 | select HAVE_FUNCTION_GRAPH_TRACER | 7 | select HAVE_FUNCTION_GRAPH_TRACER |
| 9 | select HAVE_SYSCALL_TRACEPOINTS | 8 | select HAVE_SYSCALL_TRACEPOINTS |
| @@ -220,7 +220,6 @@ config PPC · 219 unmodified lines | |||
| 220 | select HAVE_HARDLOCKUP_DETECTOR_ARCH if PPC_BOOK3S_64 && SMP | 220 | select HAVE_HARDLOCKUP_DETECTOR_ARCH if PPC_BOOK3S_64 && SMP |
| 221 | select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH | 221 | select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH |
| 222 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx) | 222 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx) |
| 223 | select HAVE_IDE | ||
| 224 | select HAVE_IOREMAP_PROT | 223 | select HAVE_IOREMAP_PROT |
| 225 | select HAVE_IRQ_EXIT_ON_IRQ_STACK | 224 | select HAVE_IRQ_EXIT_ON_IRQ_STACK |
| 226 | select HAVE_IRQ_TIME_ACCOUNTING | 225 | select HAVE_IRQ_TIME_ACCOUNTING |
| @@ -27,6 +27,13 @@ KASAN_SANITIZE := n · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ | 28 | ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ |
| 29 | -Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both | 29 | -Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both |
| 30 | |||
| 31 | # Go prior to 1.16.x assumes r30 is not clobbered by any VDSO code. That used to be true | ||
| 32 | # by accident when the VDSO was hand-written asm code, but may not be now that the VDSO is | ||
| 33 | # compiler generated. To avoid breaking Go tell GCC not to use r30. Impact on code | ||
| 34 | # generation is minimal, it will just use r29 instead. | ||
| 35 | ccflags-y += $(call cc-option, -ffixed-r30) | ||
| 36 | |||
| 30 | asflags-y := -D__VDSO64__ -s | 37 | asflags-y := -D__VDSO64__ -s |
| 31 | 38 | ||
| 32 | targets += vdso64.lds | 39 | targets += vdso64.lds |
| @@ -2697,8 +2697,10 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu) · 2696 unmodified lines | |||
| 2697 | HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP | HFSCR_PREFIX; | 2697 | HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP | HFSCR_PREFIX; |
| 2698 | if (cpu_has_feature(CPU_FTR_HVMODE)) { | 2698 | if (cpu_has_feature(CPU_FTR_HVMODE)) { |
| 2699 | vcpu->arch.hfscr &= mfspr(SPRN_HFSCR); | 2699 | vcpu->arch.hfscr &= mfspr(SPRN_HFSCR); |
| 2700 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
| 2700 | if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) | 2701 | if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) |
| 2701 | vcpu->arch.hfscr |= HFSCR_TM; | 2702 | vcpu->arch.hfscr |= HFSCR_TM; |
| 2703 | #endif | ||
| 2702 | } | 2704 | } |
| 2703 | if (cpu_has_feature(CPU_FTR_TM_COMP)) | 2705 | if (cpu_has_feature(CPU_FTR_TM_COMP)) |
| 2704 | vcpu->arch.hfscr |= HFSCR_TM; | 2706 | vcpu->arch.hfscr |= HFSCR_TM; |
| @@ -302,6 +302,9 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) · 301 unmodified lines | |||
| 302 | if (vcpu->kvm->arch.l1_ptcr == 0) | 302 | if (vcpu->kvm->arch.l1_ptcr == 0) |
| 303 | return H_NOT_AVAILABLE; | 303 | return H_NOT_AVAILABLE; |
| 304 | 304 | ||
| 305 | if (MSR_TM_TRANSACTIONAL(vcpu->arch.shregs.msr)) | ||
| 306 | return H_BAD_MODE; | ||
| 307 | |||
| 305 | /* copy parameters in */ | 308 | /* copy parameters in */ |
| 306 | hv_ptr = kvmppc_get_gpr(vcpu, 4); | 309 | hv_ptr = kvmppc_get_gpr(vcpu, 4); |
| 307 | regs_ptr = kvmppc_get_gpr(vcpu, 5); | 310 | regs_ptr = kvmppc_get_gpr(vcpu, 5); |
| @@ -322,6 +325,23 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) · 14 unmodified lines | |||
| 322 | if (l2_hv.vcpu_token >= NR_CPUS) | 325 | if (l2_hv.vcpu_token >= NR_CPUS) |
| 323 | return H_PARAMETER; | 326 | return H_PARAMETER; |
| 324 | 327 | ||
| 328 | /* | ||
| 329 | * L1 must have set up a suspended state to enter the L2 in a | ||
| 330 | * transactional state, and only in that case. These have to be | ||
| 331 | * filtered out here to prevent causing a TM Bad Thing in the | ||
| 332 | * host HRFID. We could synthesize a TM Bad Thing back to the L1 | ||
| 333 | * here but there doesn't seem like much point. | ||
| 334 | */ | ||
| 335 | if (MSR_TM_SUSPENDED(vcpu->arch.shregs.msr)) { | ||
| 336 | if (!MSR_TM_ACTIVE(l2_regs.msr)) | ||
| 337 | return H_BAD_MODE; | ||
| 338 | } else { | ||
| 339 | if (l2_regs.msr & MSR_TS_MASK) | ||
| 340 | return H_BAD_MODE; | ||
| 341 | if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_TS_MASK)) | ||
| 342 | return H_BAD_MODE; | ||
| 343 | } | ||
| 344 | |||
| 325 | /* translate lpid */ | 345 | /* translate lpid */ |
| 326 | l2 = kvmhv_get_nested(vcpu->kvm, l2_hv.lpid, true); | 346 | l2 = kvmhv_get_nested(vcpu->kvm, l2_hv.lpid, true); |
| 327 | if (!l2) | 347 | if (!l2) |
| @@ -317,6 +317,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc · 316 unmodified lines | |||
| 317 | */ | 317 | */ |
| 318 | mtspr(SPRN_HDEC, hdec); | 318 | mtspr(SPRN_HDEC, hdec); |
| 319 | 319 | ||
| 320 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
| 321 | tm_return_to_guest: | ||
| 322 | #endif | ||
| 320 | mtspr(SPRN_DAR, vcpu->arch.shregs.dar); | 323 | mtspr(SPRN_DAR, vcpu->arch.shregs.dar); |
| 321 | mtspr(SPRN_DSISR, vcpu->arch.shregs.dsisr); | 324 | mtspr(SPRN_DSISR, vcpu->arch.shregs.dsisr); |
| 322 | mtspr(SPRN_SRR0, vcpu->arch.shregs.srr0); | 325 | mtspr(SPRN_SRR0, vcpu->arch.shregs.srr0); |
| @@ -415,11 +418,23 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc · 92 unmodified lines | |||
| 415 | * is in real suspend mode and is trying to transition to | 418 | * is in real suspend mode and is trying to transition to |
| 416 | * transactional mode. | 419 | * transactional mode. |
| 417 | */ | 420 | */ |
| 418 | if (local_paca->kvm_hstate.fake_suspend && | 421 | if (!local_paca->kvm_hstate.fake_suspend && |
| 419 | (vcpu->arch.shregs.msr & MSR_TS_S)) { | 422 | (vcpu->arch.shregs.msr & MSR_TS_S)) { |
| 420 | if (kvmhv_p9_tm_emulation_early(vcpu)) { | 423 | if (kvmhv_p9_tm_emulation_early(vcpu)) { |
| 421 | /* Prevent it being handled again. */ | 424 | /* |
| 422 | trap = 0; | 425 | * Go straight back into the guest with the |
| 426 | * new NIP/MSR as set by TM emulation. | ||
| 427 | */ | ||
| 428 | mtspr(SPRN_HSRR0, vcpu->arch.regs.nip); | ||
| 429 | mtspr(SPRN_HSRR1, vcpu->arch.shregs.msr); | ||
| 430 | |||
| 431 | /* | ||
| 432 | * tm_return_to_guest re-loads SRR0/1, DAR, | ||
| 433 | * DSISR after RI is cleared, in case they had | ||
| 434 | * been clobbered by a MCE. | ||
| 435 | */ | ||
| 436 | __mtmsrd(0, 1); /* clear RI */ | ||
| 437 | goto tm_return_to_guest; | ||
| 423 | } | 438 | } |
| 424 | } | 439 | } |
| 425 | #endif | 440 | #endif |
| @@ -499,6 +514,10 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc · 73 unmodified lines | |||
| 499 | * If we are in real mode, only switch MMU on after the MMU is | 514 | * If we are in real mode, only switch MMU on after the MMU is |
| 500 | * switched to host, to avoid the P9_RADIX_PREFETCH_BUG. | 515 | * switched to host, to avoid the P9_RADIX_PREFETCH_BUG. |
| 501 | */ | 516 | */ |
| 517 | if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && | ||
| 518 | vcpu->arch.shregs.msr & MSR_TS_MASK) | ||
| 519 | msr |= MSR_TS_S; | ||
| 520 | |||
| 502 | __mtmsrd(msr, 0); | 521 | __mtmsrd(msr, 0); |
| 503 | 522 | ||
| 504 | end_timing(vcpu); | 523 | end_timing(vcpu); |
| @@ -242,6 +242,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) · 241 unmodified lines | |||
| 242 | * value so we can restore it on the way out. | 242 | * value so we can restore it on the way out. |
| 243 | */ | 243 | */ |
| 244 | orig_rets = args.rets; | 244 | orig_rets = args.rets; |
| 245 | if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) { | ||
| 246 | /* | ||
| 247 | * Don't overflow our args array: ensure there is room for | ||
| 248 | * at least rets[0] (even if the call specifies 0 nret). | ||
| 249 | * | ||
| 250 | * Each handler must then check for the correct nargs and nret | ||
| 251 | * values, but they may always return failure in rets[0]. | ||
| 252 | */ | ||
| 253 | rc = -EINVAL; | ||
| 254 | goto fail; | ||
| 255 | } | ||
| 245 | args.rets = &args.args[be32_to_cpu(args.nargs)]; | 256 | args.rets = &args.args[be32_to_cpu(args.nargs)]; |
| 246 | 257 | ||
| 247 | mutex_lock(&vcpu->kvm->arch.rtas_token_lock); | 258 | mutex_lock(&vcpu->kvm->arch.rtas_token_lock); |
| @@ -269,9 +280,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) · 21 unmodified lines | |||
| 269 | fail: | 280 | fail: |
| 270 | /* | 281 | /* |
| 271 | * We only get here if the guest has called RTAS with a bogus | 282 | * We only get here if the guest has called RTAS with a bogus |
| 272 | * args pointer. That means we can't get to the args, and so we | 283 | * args pointer or nargs/nret values that would overflow the |
| 273 | * can't fail the RTAS call. So fail right out to userspace, | 284 | * array. That means we can't get to the args, and so we can't |
| 274 | * which should kill the guest. | 285 | * fail the RTAS call. So fail right out to userspace, which |
| 286 | * should kill the guest. | ||
| 287 | * | ||
| 288 | * SLOF should actually pass the hcall return value from the | ||
| 289 | * rtas handler call in r3, so enter_rtas could be modified to | ||
| 290 | * return a failure indication in r3 and we could return such | ||
| 291 | * errors to the guest rather than failing to host userspace. | ||
| 292 | * However old guests that don't test for failure could then | ||
| 293 | * continue silently after errors, so for now we won't do this. | ||
| 275 | */ | 294 | */ |
| 276 | return rc; | 295 | return rc; |
| 277 | } | 296 | } |
| @@ -2048,9 +2048,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 2047 unmodified lines | |||
| 2048 | { | 2048 | { |
| 2049 | struct kvm_enable_cap cap; | 2049 | struct kvm_enable_cap cap; |
| 2050 | r = -EFAULT; | 2050 | r = -EFAULT; |
| 2051 | vcpu_load(vcpu); | ||
| 2052 | if (copy_from_user(&cap, argp, sizeof(cap))) | 2051 | if (copy_from_user(&cap, argp, sizeof(cap))) |
| 2053 | goto out; | 2052 | goto out; |
| 2053 | vcpu_load(vcpu); | ||
| 2054 | r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); | 2054 | r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); |
| 2055 | vcpu_put(vcpu); | 2055 | vcpu_put(vcpu); |
| 2056 | break; | 2056 | break; |
| @@ -2074,9 +2074,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 17 unmodified lines | |||
| 2074 | case KVM_DIRTY_TLB: { | 2074 | case KVM_DIRTY_TLB: { |
| 2075 | struct kvm_dirty_tlb dirty; | 2075 | struct kvm_dirty_tlb dirty; |
| 2076 | r = -EFAULT; | 2076 | r = -EFAULT; |
| 2077 | vcpu_load(vcpu); | ||
| 2078 | if (copy_from_user(&dirty, argp, sizeof(dirty))) | 2077 | if (copy_from_user(&dirty, argp, sizeof(dirty))) |
| 2079 | goto out; | 2078 | goto out; |
| 2079 | vcpu_load(vcpu); | ||
| 2080 | r = kvm_vcpu_ioctl_dirty_tlb(vcpu, &dirty); | 2080 | r = kvm_vcpu_ioctl_dirty_tlb(vcpu, &dirty); |
| 2081 | vcpu_put(vcpu); | 2081 | vcpu_put(vcpu); |
| 2082 | break; | 2082 | break; |
| @@ -240,3 +240,13 @@ void __init setup_kuap(bool disabled) · 239 unmodified lines | |||
| 240 | mtspr(SPRN_MD_AP, MD_APG_KUAP); | 240 | mtspr(SPRN_MD_AP, MD_APG_KUAP); |
| 241 | } | 241 | } |
| 242 | #endif | 242 | #endif |
| 243 | |||
| 244 | int pud_clear_huge(pud_t *pud) | ||
| 245 | { | ||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | |||
| 249 | int pmd_clear_huge(pmd_t *pmd) | ||
| 250 | { | ||
| 251 | return 0; | ||
| 252 | } | ||
| @@ -737,6 +737,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * · 736 unmodified lines | |||
| 737 | } | 737 | } |
| 738 | break; | 738 | break; |
| 739 | 739 | ||
| 740 | /* | ||
| 741 | * BPF_ST NOSPEC (speculation barrier) | ||
| 742 | */ | ||
| 743 | case BPF_ST | BPF_NOSPEC: | ||
| 744 | break; | ||
| 745 | |||
| 740 | /* | 746 | /* |
| 741 | * BPF_ST(X) | 747 | * BPF_ST(X) |
| 742 | */ | 748 | */ |
| @@ -627,6 +627,12 @@ emit_clear: · 626 unmodified lines | |||
| 627 | } | 627 | } |
| 628 | break; | 628 | break; |
| 629 | 629 | ||
| 630 | /* | ||
| 631 | * BPF_ST NOSPEC (speculation barrier) | ||
| 632 | */ | ||
| 633 | case BPF_ST | BPF_NOSPEC: | ||
| 634 | break; | ||
| 635 | |||
| 630 | /* | 636 | /* |
| 631 | * BPF_ST(X) | 637 | * BPF_ST(X) |
| 632 | */ | 638 | */ |
| @@ -42,6 +42,7 @@ static int pasemi_system_reset_exception(struct pt_regs *regs) · 41 unmodified lines | |||
| 42 | switch (regs->msr & SRR1_WAKEMASK) { | 42 | switch (regs->msr & SRR1_WAKEMASK) { |
| 43 | case SRR1_WAKEDEC: | 43 | case SRR1_WAKEDEC: |
| 44 | set_dec(1); | 44 | set_dec(1); |
| 45 | break; | ||
| 45 | case SRR1_WAKEEE: | 46 | case SRR1_WAKEEE: |
| 46 | /* | 47 | /* |
| 47 | * Handle these when interrupts get re-enabled and we take | 48 | * Handle these when interrupts get re-enabled and we take |
| @@ -77,7 +77,7 @@ · 76 unmodified lines | |||
| 77 | #include "../../../../drivers/pci/pci.h" | 77 | #include "../../../../drivers/pci/pci.h" |
| 78 | 78 | ||
| 79 | DEFINE_STATIC_KEY_FALSE(shared_processor); | 79 | DEFINE_STATIC_KEY_FALSE(shared_processor); |
| 80 | EXPORT_SYMBOL_GPL(shared_processor); | 80 | EXPORT_SYMBOL(shared_processor); |
| 81 | 81 | ||
| 82 | int CMO_PrPSP = -1; | 82 | int CMO_PrPSP = -1; |
| 83 | int CMO_SecPSP = -1; | 83 | int CMO_SecPSP = -1; |
| @@ -27,10 +27,10 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE) | 28 | #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE) |
| 29 | 29 | ||
| 30 | /* Load initrd at enough distance from DRAM start */ | 30 | /* Load initrd anywhere in system RAM */ |
| 31 | static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) | 31 | static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) |
| 32 | { | 32 | { |
| 33 | return image_addr + SZ_256M; | 33 | return ULONG_MAX; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | #define alloc_screen_info(x...) (&screen_info) | 36 | #define alloc_screen_info(x...) (&screen_info) |
| @@ -132,8 +132,12 @@ unsigned long get_wchan(struct task_struct *task) · 131 unmodified lines | |||
| 132 | { | 132 | { |
| 133 | unsigned long pc = 0; | 133 | unsigned long pc = 0; |
| 134 | 134 | ||
| 135 | if (likely(task && task != current && !task_is_running(task))) | 135 | if (likely(task && task != current && !task_is_running(task))) { |
| 136 | if (!try_get_task_stack(task)) | ||
| 137 | return 0; | ||
| 136 | walk_stackframe(task, NULL, save_wchan, &pc); | 138 | walk_stackframe(task, NULL, save_wchan, &pc); |
| 139 | put_task_stack(task); | ||
| 140 | } | ||
| 137 | return pc; | 141 | return pc; |
| 138 | } | 142 | } |
| 139 | 143 | ||
| @@ -30,23 +30,23 @@ ENTRY(__asm_copy_from_user) · 29 unmodified lines | |||
| 30 | * t0 - end of uncopied dst | 30 | * t0 - end of uncopied dst |
| 31 | */ | 31 | */ |
| 32 | add t0, a0, a2 | 32 | add t0, a0, a2 |
| 33 | bgtu a0, t0, 5f | ||
| 34 | 33 | ||
| 35 | /* | 34 | /* |
| 36 | * Use byte copy only if too small. | 35 | * Use byte copy only if too small. |
| 36 | * SZREG holds 4 for RV32 and 8 for RV64 | ||
| 37 | */ | 37 | */ |
| 38 | li a3, 8*SZREG /* size must be larger than size in word_copy */ | 38 | li a3, 9*SZREG /* size must be larger than size in word_copy */ |
| 39 | bltu a2, a3, .Lbyte_copy_tail | 39 | bltu a2, a3, .Lbyte_copy_tail |
| 40 | 40 | ||
| 41 | /* | 41 | /* |
| 42 | * Copy first bytes until dst is align to word boundary. | 42 | * Copy first bytes until dst is aligned to word boundary. |
| 43 | * a0 - start of dst | 43 | * a0 - start of dst |
| 44 | * t1 - start of aligned dst | 44 | * t1 - start of aligned dst |
| 45 | */ | 45 | */ |
| 46 | addi t1, a0, SZREG-1 | 46 | addi t1, a0, SZREG-1 |
| 47 | andi t1, t1, ~(SZREG-1) | 47 | andi t1, t1, ~(SZREG-1) |
| 48 | /* dst is already aligned, skip */ | 48 | /* dst is already aligned, skip */ |
| 49 | beq a0, t1, .Lskip_first_bytes | 49 | beq a0, t1, .Lskip_align_dst |
| 50 | 1: | 50 | 1: |
| 51 | /* a5 - one byte for copying data */ | 51 | /* a5 - one byte for copying data */ |
| 52 | fixup lb a5, 0(a1), 10f | 52 | fixup lb a5, 0(a1), 10f |
| @@ -55,7 +55,7 @@ ENTRY(__asm_copy_from_user) · 2 unmodified lines | |||
| 55 | addi a0, a0, 1 /* dst */ | 55 | addi a0, a0, 1 /* dst */ |
| 56 | bltu a0, t1, 1b /* t1 - start of aligned dst */ | 56 | bltu a0, t1, 1b /* t1 - start of aligned dst */ |
| 57 | 57 | ||
| 58 | .Lskip_first_bytes: | 58 | .Lskip_align_dst: |
| 59 | /* | 59 | /* |
| 60 | * Now dst is aligned. | 60 | * Now dst is aligned. |
| 61 | * Use shift-copy if src is misaligned. | 61 | * Use shift-copy if src is misaligned. |
| @@ -72,10 +72,9 @@ ENTRY(__asm_copy_from_user) · 10 unmodified lines | |||
| 72 | * | 72 | * |
| 73 | * a0 - start of aligned dst | 73 | * a0 - start of aligned dst |
| 74 | * a1 - start of aligned src | 74 | * a1 - start of aligned src |
| 75 | * a3 - a1 & mask:(SZREG-1) | ||
| 76 | * t0 - end of aligned dst | 75 | * t0 - end of aligned dst |
| 77 | */ | 76 | */ |
| 78 | addi t0, t0, -(8*SZREG-1) /* not to over run */ | 77 | addi t0, t0, -(8*SZREG) /* not to over run */ |
| 79 | 2: | 78 | 2: |
| 80 | fixup REG_L a4, 0(a1), 10f | 79 | fixup REG_L a4, 0(a1), 10f |
| 81 | fixup REG_L a5, SZREG(a1), 10f | 80 | fixup REG_L a5, SZREG(a1), 10f |
| @@ -97,7 +96,7 @@ ENTRY(__asm_copy_from_user) · 15 unmodified lines | |||
| 97 | addi a1, a1, 8*SZREG | 96 | addi a1, a1, 8*SZREG |
| 98 | bltu a0, t0, 2b | 97 | bltu a0, t0, 2b |
| 99 | 98 | ||
| 100 | addi t0, t0, 8*SZREG-1 /* revert to original value */ | 99 | addi t0, t0, 8*SZREG /* revert to original value */ |
| 101 | j .Lbyte_copy_tail | 100 | j .Lbyte_copy_tail |
| 102 | 101 | ||
| 103 | .Lshift_copy: | 102 | .Lshift_copy: |
| @@ -107,7 +106,7 @@ ENTRY(__asm_copy_from_user) · 3 unmodified lines | |||
| 107 | * For misaligned copy we still perform aligned word copy, but | 106 | * For misaligned copy we still perform aligned word copy, but |
| 108 | * we need to use the value fetched from the previous iteration and | 107 | * we need to use the value fetched from the previous iteration and |
| 109 | * do some shifts. | 108 | * do some shifts. |
| 110 | * This is safe because reading less than a word size. | 109 | * This is safe because reading is less than a word size. |
| 111 | * | 110 | * |
| 112 | * a0 - start of aligned dst | 111 | * a0 - start of aligned dst |
| 113 | * a1 - start of src | 112 | * a1 - start of src |
| @@ -117,7 +116,7 @@ ENTRY(__asm_copy_from_user) · 3 unmodified lines | |||
| 117 | */ | 116 | */ |
| 118 | /* calculating aligned word boundary for dst */ | 117 | /* calculating aligned word boundary for dst */ |
| 119 | andi t1, t0, ~(SZREG-1) | 118 | andi t1, t0, ~(SZREG-1) |
| 120 | /* Converting unaligned src to aligned arc */ | 119 | /* Converting unaligned src to aligned src */ |
| 121 | andi a1, a1, ~(SZREG-1) | 120 | andi a1, a1, ~(SZREG-1) |
| 122 | 121 | ||
| 123 | /* | 122 | /* |
| @@ -125,11 +124,11 @@ ENTRY(__asm_copy_from_user) · 1 unmodified line | |||
| 125 | * t3 - prev shift | 124 | * t3 - prev shift |
| 126 | * t4 - current shift | 125 | * t4 - current shift |
| 127 | */ | 126 | */ |
| 128 | slli t3, a3, LGREG | 127 | slli t3, a3, 3 /* converting bytes in a3 to bits */ |
| 129 | li a5, SZREG*8 | 128 | li a5, SZREG*8 |
| 130 | sub t4, a5, t3 | 129 | sub t4, a5, t3 |
| 131 | 130 | ||
| 132 | /* Load the first word to combine with seceond word */ | 131 | /* Load the first word to combine with second word */ |
| 133 | fixup REG_L a5, 0(a1), 10f | 132 | fixup REG_L a5, 0(a1), 10f |
| 134 | 133 | ||
| 135 | 3: | 134 | 3: |
| @@ -161,7 +160,7 @@ ENTRY(__asm_copy_from_user) · 25 unmodified lines | |||
| 161 | * a1 - start of remaining src | 160 | * a1 - start of remaining src |
| 162 | * t0 - end of remaining dst | 161 | * t0 - end of remaining dst |
| 163 | */ | 162 | */ |
| 164 | bgeu a0, t0, 5f | 163 | bgeu a0, t0, .Lout_copy_user /* check if end of copy */ |
| 165 | 4: | 164 | 4: |
| 166 | fixup lb a5, 0(a1), 10f | 165 | fixup lb a5, 0(a1), 10f |
| 167 | addi a1, a1, 1 /* src */ | 166 | addi a1, a1, 1 /* src */ |
| @@ -169,7 +168,7 @@ ENTRY(__asm_copy_from_user) · 1 unmodified line | |||
| 169 | addi a0, a0, 1 /* dst */ | 168 | addi a0, a0, 1 /* dst */ |
| 170 | bltu a0, t0, 4b /* t0 - end of dst */ | 169 | bltu a0, t0, 4b /* t0 - end of dst */ |
| 171 | 170 | ||
| 172 | 5: | 171 | .Lout_copy_user: |
| 173 | /* Disable access to user memory */ | 172 | /* Disable access to user memory */ |
| 174 | csrc CSR_STATUS, t6 | 173 | csrc CSR_STATUS, t6 |
| 175 | li a0, 0 | 174 | li a0, 0 |
| @@ -127,10 +127,17 @@ void __init mem_init(void) · 126 unmodified lines | |||
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | /* | 129 | /* |
| 130 | * The default maximal physical memory size is -PAGE_OFFSET, | 130 | * The default maximal physical memory size is -PAGE_OFFSET for 32-bit kernel, |
| 131 | * limit the memory size via mem. | 131 | * whereas for 64-bit kernel, the end of the virtual address space is occupied |
| 132 | * by the modules/BPF/kernel mappings which reduces the available size of the | ||
| 133 | * linear mapping. | ||
| 134 | * Limit the memory size via mem. | ||
| 132 | */ | 135 | */ |
| 136 | #ifdef CONFIG_64BIT | ||
| 137 | static phys_addr_t memory_limit = -PAGE_OFFSET - SZ_4G; | ||
| 138 | #else | ||
| 133 | static phys_addr_t memory_limit = -PAGE_OFFSET; | 139 | static phys_addr_t memory_limit = -PAGE_OFFSET; |
| 140 | #endif | ||
| 134 | 141 | ||
| 135 | static int __init early_mem(char *p) | 142 | static int __init early_mem(char *p) |
| 136 | { | 143 | { |
| @@ -152,7 +159,7 @@ static void __init setup_bootmem(void) · 15 unmodified lines | |||
| 152 | { | 159 | { |
| 153 | phys_addr_t vmlinux_end = __pa_symbol(&_end); | 160 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 154 | phys_addr_t vmlinux_start = __pa_symbol(&_start); | 161 | phys_addr_t vmlinux_start = __pa_symbol(&_start); |
| 155 | phys_addr_t max_mapped_addr = __pa(~(ulong)0); | 162 | phys_addr_t __maybe_unused max_mapped_addr; |
| 156 | phys_addr_t dram_end; | 163 | phys_addr_t dram_end; |
| 157 | 164 | ||
| 158 | #ifdef CONFIG_XIP_KERNEL | 165 | #ifdef CONFIG_XIP_KERNEL |
| @@ -175,14 +182,21 @@ static void __init setup_bootmem(void) · 16 unmodified lines | |||
| 175 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); | 182 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); |
| 176 | 183 | ||
| 177 | dram_end = memblock_end_of_DRAM(); | 184 | dram_end = memblock_end_of_DRAM(); |
| 185 | |||
| 186 | #ifndef CONFIG_64BIT | ||
| 178 | /* | 187 | /* |
| 179 | * memblock allocator is not aware of the fact that last 4K bytes of | 188 | * memblock allocator is not aware of the fact that last 4K bytes of |
| 180 | * the addressable memory can not be mapped because of IS_ERR_VALUE | 189 | * the addressable memory can not be mapped because of IS_ERR_VALUE |
| 181 | * macro. Make sure that last 4k bytes are not usable by memblock | 190 | * macro. Make sure that last 4k bytes are not usable by memblock |
| 182 | * if end of dram is equal to maximum addressable memory. | 191 | * if end of dram is equal to maximum addressable memory. For 64-bit |
| 192 | * kernel, this problem can't happen here as the end of the virtual | ||
| 193 | * address space is occupied by the kernel mapping then this check must | ||
| 194 | * be done in create_kernel_page_table. | ||
| 183 | */ | 195 | */ |
| 196 | max_mapped_addr = __pa(~(ulong)0); | ||
| 184 | if (max_mapped_addr == (dram_end - 1)) | 197 | if (max_mapped_addr == (dram_end - 1)) |
| 185 | memblock_set_current_limit(max_mapped_addr - 4096); | 198 | memblock_set_current_limit(max_mapped_addr - 4096); |
| 199 | #endif | ||
| 186 | 200 | ||
| 187 | min_low_pfn = PFN_UP(memblock_start_of_DRAM()); | 201 | min_low_pfn = PFN_UP(memblock_start_of_DRAM()); |
| 188 | max_low_pfn = max_pfn = PFN_DOWN(dram_end); | 202 | max_low_pfn = max_pfn = PFN_DOWN(dram_end); |
| @@ -570,6 +584,14 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) · 381 unmodified lines | |||
| 570 | BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0); | 584 | BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0); |
| 571 | BUG_ON((kernel_map.phys_addr % map_size) != 0); | 585 | BUG_ON((kernel_map.phys_addr % map_size) != 0); |
| 572 | 586 | ||
| 587 | #ifdef CONFIG_64BIT | ||
| 588 | /* | ||
| 589 | * The last 4K bytes of the addressable memory can not be mapped because | ||
| 590 | * of IS_ERR_VALUE macro. | ||
| 591 | */ | ||
| 592 | BUG_ON((kernel_map.virt_addr + kernel_map.size) > ADDRESS_SPACE_END - SZ_4K); | ||
| 593 | #endif | ||
| 594 | |||
| 573 | pt_ops.alloc_pte = alloc_pte_early; | 595 | pt_ops.alloc_pte = alloc_pte_early; |
| 574 | pt_ops.get_pte_virt = get_pte_virt_early; | 596 | pt_ops.get_pte_virt = get_pte_virt_early; |
| 575 | #ifndef __PAGETABLE_PMD_FOLDED | 597 | #ifndef __PAGETABLE_PMD_FOLDED |
| @@ -709,6 +731,8 @@ static void __init setup_vm_final(void) · 133 unmodified lines | |||
| 709 | if (start <= __pa(PAGE_OFFSET) && | 731 | if (start <= __pa(PAGE_OFFSET) && |
| 710 | __pa(PAGE_OFFSET) < end) | 732 | __pa(PAGE_OFFSET) < end) |
| 711 | start = __pa(PAGE_OFFSET); | 733 | start = __pa(PAGE_OFFSET); |
| 734 | if (end >= __pa(PAGE_OFFSET) + memory_limit) | ||
| 735 | end = __pa(PAGE_OFFSET) + memory_limit; | ||
| 712 | 736 | ||
| 713 | map_size = best_map_size(start, end - start); | 737 | map_size = best_map_size(start, end - start); |
| 714 | for (pa = start; pa < end; pa += map_size) { | 738 | for (pa = start; pa < end; pa += map_size) { |
| @@ -1251,6 +1251,10 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, · 1250 unmodified lines | |||
| 1251 | return -1; | 1251 | return -1; |
| 1252 | break; | 1252 | break; |
| 1253 | 1253 | ||
| 1254 | /* speculation barrier */ | ||
| 1255 | case BPF_ST | BPF_NOSPEC: | ||
| 1256 | break; | ||
| 1257 | |||
| 1254 | case BPF_ST | BPF_MEM | BPF_B: | 1258 | case BPF_ST | BPF_MEM | BPF_B: |
| 1255 | case BPF_ST | BPF_MEM | BPF_H: | 1259 | case BPF_ST | BPF_MEM | BPF_H: |
| 1256 | case BPF_ST | BPF_MEM | BPF_W: | 1260 | case BPF_ST | BPF_MEM | BPF_W: |
| @@ -939,6 +939,10 @@ out_be: · 938 unmodified lines | |||
| 939 | emit_ld(rd, 0, RV_REG_T1, ctx); | 939 | emit_ld(rd, 0, RV_REG_T1, ctx); |
| 940 | break; | 940 | break; |
| 941 | 941 | ||
| 942 | /* speculation barrier */ | ||
| 943 | case BPF_ST | BPF_NOSPEC: | ||
| 944 | break; | ||
| 945 | |||
| 942 | /* ST: *(size *)(dst + off) = imm */ | 946 | /* ST: *(size *)(dst + off) = imm */ |
| 943 | case BPF_ST | BPF_MEM | BPF_B: | 947 | case BPF_ST | BPF_MEM | BPF_B: |
| 944 | emit_imm(RV_REG_T1, imm, ctx); | 948 | emit_imm(RV_REG_T1, imm, ctx); |
| @@ -9,16 +9,6 @@ · 8 unmodified lines | |||
| 9 | #include <asm/errno.h> | 9 | #include <asm/errno.h> |
| 10 | #include <asm/sigp.h> | 10 | #include <asm/sigp.h> |
| 11 | 11 | ||
| 12 | #ifdef CC_USING_EXPOLINE | ||
| 13 | .pushsection .dma.text.__s390_indirect_jump_r14,"axG" | ||
| 14 | __dma__s390_indirect_jump_r14: | ||
| 15 | larl %r1,0f | ||
| 16 | ex 0,0(%r1) | ||
| 17 | j . | ||
| 18 | 0: br %r14 | ||
| 19 | .popsection | ||
| 20 | #endif | ||
| 21 | |||
| 22 | .section .dma.text,"ax" | 12 | .section .dma.text,"ax" |
| 23 | /* | 13 | /* |
| 24 | * Simplified version of expoline thunk. The normal thunks can not be used here, | 14 | * Simplified version of expoline thunk. The normal thunks can not be used here, |
| @@ -27,11 +17,10 @@ __dma__s390_indirect_jump_r14: · 2 unmodified lines | |||
| 27 | * affects a few functions that are not performance-relevant. | 17 | * affects a few functions that are not performance-relevant. |
| 28 | */ | 18 | */ |
| 29 | .macro BR_EX_DMA_r14 | 19 | .macro BR_EX_DMA_r14 |
| 30 | #ifdef CC_USING_EXPOLINE | 20 | larl %r1,0f |
| 31 | jg __dma__s390_indirect_jump_r14 | 21 | ex 0,0(%r1) |
| 32 | #else | 22 | j . |
| 33 | br %r14 | 23 | 0: br %r14 |
| 34 | #endif | ||
| 35 | .endm | 24 | .endm |
| 36 | 25 | ||
| 37 | /* | 26 | /* |
| @@ -5,7 +5,12 @@ CONFIG_WATCH_QUEUE=y · 4 unmodified lines | |||
| 5 | CONFIG_AUDIT=y | 5 | CONFIG_AUDIT=y |
| 6 | CONFIG_NO_HZ_IDLE=y | 6 | CONFIG_NO_HZ_IDLE=y |
| 7 | CONFIG_HIGH_RES_TIMERS=y | 7 | CONFIG_HIGH_RES_TIMERS=y |
| 8 | CONFIG_BPF_SYSCALL=y | ||
| 9 | CONFIG_BPF_JIT=y | ||
| 10 | CONFIG_BPF_JIT_ALWAYS_ON=y | ||
| 11 | CONFIG_BPF_LSM=y | ||
| 8 | CONFIG_PREEMPT=y | 12 | CONFIG_PREEMPT=y |
| 13 | CONFIG_SCHED_CORE=y | ||
| 9 | CONFIG_BSD_PROCESS_ACCT=y | 14 | CONFIG_BSD_PROCESS_ACCT=y |
| 10 | CONFIG_BSD_PROCESS_ACCT_V3=y | 15 | CONFIG_BSD_PROCESS_ACCT_V3=y |
| 11 | CONFIG_TASKSTATS=y | 16 | CONFIG_TASKSTATS=y |
| @@ -28,14 +33,13 @@ CONFIG_CGROUP_DEVICE=y · 16 unmodified lines | |||
| 28 | CONFIG_CGROUP_CPUACCT=y | 33 | CONFIG_CGROUP_CPUACCT=y |
| 29 | CONFIG_CGROUP_PERF=y | 34 | CONFIG_CGROUP_PERF=y |
| 30 | CONFIG_CGROUP_BPF=y | 35 | CONFIG_CGROUP_BPF=y |
| 36 | CONFIG_CGROUP_MISC=y | ||
| 31 | CONFIG_NAMESPACES=y | 37 | CONFIG_NAMESPACES=y |
| 32 | CONFIG_USER_NS=y | 38 | CONFIG_USER_NS=y |
| 33 | CONFIG_CHECKPOINT_RESTORE=y | 39 | CONFIG_CHECKPOINT_RESTORE=y |
| 34 | CONFIG_SCHED_AUTOGROUP=y | 40 | CONFIG_SCHED_AUTOGROUP=y |
| 35 | CONFIG_EXPERT=y | 41 | CONFIG_EXPERT=y |
| 36 | # CONFIG_SYSFS_SYSCALL is not set | 42 | # CONFIG_SYSFS_SYSCALL is not set |
| 37 | CONFIG_BPF_LSM=y | ||
| 38 | CONFIG_BPF_SYSCALL=y | ||
| 39 | CONFIG_USERFAULTFD=y | 43 | CONFIG_USERFAULTFD=y |
| 40 | # CONFIG_COMPAT_BRK is not set | 44 | # CONFIG_COMPAT_BRK is not set |
| 41 | CONFIG_PROFILING=y | 45 | CONFIG_PROFILING=y |
| @@ -76,6 +80,7 @@ CONFIG_BLK_DEV_THROTTLING=y · 34 unmodified lines | |||
| 76 | CONFIG_BLK_WBT=y | 80 | CONFIG_BLK_WBT=y |
| 77 | CONFIG_BLK_CGROUP_IOLATENCY=y | 81 | CONFIG_BLK_CGROUP_IOLATENCY=y |
| 78 | CONFIG_BLK_CGROUP_IOCOST=y | 82 | CONFIG_BLK_CGROUP_IOCOST=y |
| 83 | CONFIG_BLK_CGROUP_IOPRIO=y | ||
| 79 | CONFIG_BLK_INLINE_ENCRYPTION=y | 84 | CONFIG_BLK_INLINE_ENCRYPTION=y |
| 80 | CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y | 85 | CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y |
| 81 | CONFIG_PARTITION_ADVANCED=y | 86 | CONFIG_PARTITION_ADVANCED=y |
| @@ -95,6 +100,7 @@ CONFIG_CLEANCACHE=y · 13 unmodified lines | |||
| 95 | CONFIG_FRONTSWAP=y | 100 | CONFIG_FRONTSWAP=y |
| 96 | CONFIG_CMA_DEBUG=y | 101 | CONFIG_CMA_DEBUG=y |
| 97 | CONFIG_CMA_DEBUGFS=y | 102 | CONFIG_CMA_DEBUGFS=y |
| 103 | CONFIG_CMA_SYSFS=y | ||
| 98 | CONFIG_CMA_AREAS=7 | 104 | CONFIG_CMA_AREAS=7 |
| 99 | CONFIG_MEM_SOFT_DIRTY=y | 105 | CONFIG_MEM_SOFT_DIRTY=y |
| 100 | CONFIG_ZSWAP=y | 106 | CONFIG_ZSWAP=y |
| @@ -158,6 +164,7 @@ CONFIG_IPV6_RPL_LWTUNNEL=y · 57 unmodified lines | |||
| 158 | CONFIG_MPTCP=y | 164 | CONFIG_MPTCP=y |
| 159 | CONFIG_NETFILTER=y | 165 | CONFIG_NETFILTER=y |
| 160 | CONFIG_BRIDGE_NETFILTER=m | 166 | CONFIG_BRIDGE_NETFILTER=m |
| 167 | CONFIG_NETFILTER_NETLINK_HOOK=m | ||
| 161 | CONFIG_NF_CONNTRACK=m | 168 | CONFIG_NF_CONNTRACK=m |
| 162 | CONFIG_NF_CONNTRACK_SECMARK=y | 169 | CONFIG_NF_CONNTRACK_SECMARK=y |
| 163 | CONFIG_NF_CONNTRACK_EVENTS=y | 170 | CONFIG_NF_CONNTRACK_EVENTS=y |
| @@ -280,6 +287,7 @@ CONFIG_IP_VS_FTP=m · 116 unmodified lines | |||
| 280 | CONFIG_IP_VS_PE_SIP=m | 287 | CONFIG_IP_VS_PE_SIP=m |
| 281 | CONFIG_NFT_FIB_IPV4=m | 288 | CONFIG_NFT_FIB_IPV4=m |
| 282 | CONFIG_NF_TABLES_ARP=y | 289 | CONFIG_NF_TABLES_ARP=y |
| 290 | CONFIG_NF_LOG_IPV4=m | ||
| 283 | CONFIG_IP_NF_IPTABLES=m | 291 | CONFIG_IP_NF_IPTABLES=m |
| 284 | CONFIG_IP_NF_MATCH_AH=m | 292 | CONFIG_IP_NF_MATCH_AH=m |
| 285 | CONFIG_IP_NF_MATCH_ECN=m | 293 | CONFIG_IP_NF_MATCH_ECN=m |
| @@ -384,12 +392,11 @@ CONFIG_VSOCKETS=m · 98 unmodified lines | |||
| 384 | CONFIG_VIRTIO_VSOCKETS=m | 392 | CONFIG_VIRTIO_VSOCKETS=m |
| 385 | CONFIG_NETLINK_DIAG=m | 393 | CONFIG_NETLINK_DIAG=m |
| 386 | CONFIG_CGROUP_NET_PRIO=y | 394 | CONFIG_CGROUP_NET_PRIO=y |
| 387 | CONFIG_BPF_JIT=y | ||
| 388 | CONFIG_NET_PKTGEN=m | 395 | CONFIG_NET_PKTGEN=m |
| 389 | CONFIG_PCI=y | 396 | CONFIG_PCI=y |
| 390 | CONFIG_PCI_IOV=y | ||
| 391 | # CONFIG_PCIEASPM is not set | 397 | # CONFIG_PCIEASPM is not set |
| 392 | CONFIG_PCI_DEBUG=y | 398 | CONFIG_PCI_DEBUG=y |
| 399 | CONFIG_PCI_IOV=y | ||
| 393 | CONFIG_HOTPLUG_PCI=y | 400 | CONFIG_HOTPLUG_PCI=y |
| 394 | CONFIG_HOTPLUG_PCI_S390=y | 401 | CONFIG_HOTPLUG_PCI_S390=y |
| 395 | CONFIG_DEVTMPFS=y | 402 | CONFIG_DEVTMPFS=y |
| @@ -436,7 +443,7 @@ CONFIG_MD_MULTIPATH=m · 40 unmodified lines | |||
| 436 | CONFIG_MD_FAULTY=m | 443 | CONFIG_MD_FAULTY=m |
| 437 | CONFIG_MD_CLUSTER=m | 444 | CONFIG_MD_CLUSTER=m |
| 438 | CONFIG_BCACHE=m | 445 | CONFIG_BCACHE=m |
| 439 | CONFIG_BLK_DEV_DM=m | 446 | CONFIG_BLK_DEV_DM=y |
| 440 | CONFIG_DM_UNSTRIPED=m | 447 | CONFIG_DM_UNSTRIPED=m |
| 441 | CONFIG_DM_CRYPT=m | 448 | CONFIG_DM_CRYPT=m |
| 442 | CONFIG_DM_SNAPSHOT=m | 449 | CONFIG_DM_SNAPSHOT=m |
| @@ -453,6 +460,7 @@ CONFIG_DM_MULTIPATH_ST=m · 10 unmodified lines | |||
| 453 | CONFIG_DM_MULTIPATH_HST=m | 460 | CONFIG_DM_MULTIPATH_HST=m |
| 454 | CONFIG_DM_MULTIPATH_IOA=m | 461 | CONFIG_DM_MULTIPATH_IOA=m |
| 455 | CONFIG_DM_DELAY=m | 462 | CONFIG_DM_DELAY=m |
| 463 | CONFIG_DM_INIT=y | ||
| 456 | CONFIG_DM_UEVENT=y | 464 | CONFIG_DM_UEVENT=y |
| 457 | CONFIG_DM_FLAKEY=m | 465 | CONFIG_DM_FLAKEY=m |
| 458 | CONFIG_DM_VERITY=m | 466 | CONFIG_DM_VERITY=m |
| @@ -495,6 +503,7 @@ CONFIG_NLMON=m · 36 unmodified lines | |||
| 495 | # CONFIG_NET_VENDOR_GOOGLE is not set | 503 | # CONFIG_NET_VENDOR_GOOGLE is not set |
| 496 | # CONFIG_NET_VENDOR_HUAWEI is not set | 504 | # CONFIG_NET_VENDOR_HUAWEI is not set |
| 497 | # CONFIG_NET_VENDOR_INTEL is not set | 505 | # CONFIG_NET_VENDOR_INTEL is not set |
| 506 | # CONFIG_NET_VENDOR_MICROSOFT is not set | ||
| 498 | # CONFIG_NET_VENDOR_MARVELL is not set | 507 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 499 | CONFIG_MLX4_EN=m | 508 | CONFIG_MLX4_EN=m |
| 500 | CONFIG_MLX5_CORE=m | 509 | CONFIG_MLX5_CORE=m |
| @@ -551,7 +560,6 @@ CONFIG_INPUT_EVDEV=y · 50 unmodified lines | |||
| 551 | CONFIG_LEGACY_PTY_COUNT=0 | 560 | CONFIG_LEGACY_PTY_COUNT=0 |
| 552 | CONFIG_VIRTIO_CONSOLE=m | 561 | CONFIG_VIRTIO_CONSOLE=m |
| 553 | CONFIG_HW_RANDOM_VIRTIO=m | 562 | CONFIG_HW_RANDOM_VIRTIO=m |
| 554 | CONFIG_RAW_DRIVER=m | ||
| 555 | CONFIG_HANGCHECK_TIMER=m | 563 | CONFIG_HANGCHECK_TIMER=m |
| 556 | CONFIG_TN3270_FS=y | 564 | CONFIG_TN3270_FS=y |
| 557 | CONFIG_PPS=m | 565 | CONFIG_PPS=m |
| @@ -574,7 +582,6 @@ CONFIG_SYNC_FILE=y · 16 unmodified lines | |||
| 574 | CONFIG_VFIO=m | 582 | CONFIG_VFIO=m |
| 575 | CONFIG_VFIO_PCI=m | 583 | CONFIG_VFIO_PCI=m |
| 576 | CONFIG_VFIO_MDEV=m | 584 | CONFIG_VFIO_MDEV=m |
| 577 | CONFIG_VFIO_MDEV_DEVICE=m | ||
| 578 | CONFIG_VIRTIO_PCI=m | 585 | CONFIG_VIRTIO_PCI=m |
| 579 | CONFIG_VIRTIO_BALLOON=m | 586 | CONFIG_VIRTIO_BALLOON=m |
| 580 | CONFIG_VIRTIO_INPUT=y | 587 | CONFIG_VIRTIO_INPUT=y |
| @@ -619,6 +626,7 @@ CONFIG_FUSE_FS=y · 38 unmodified lines | |||
| 619 | CONFIG_CUSE=m | 626 | CONFIG_CUSE=m |
| 620 | CONFIG_VIRTIO_FS=m | 627 | CONFIG_VIRTIO_FS=m |
| 621 | CONFIG_OVERLAY_FS=m | 628 | CONFIG_OVERLAY_FS=m |
| 629 | CONFIG_NETFS_STATS=y | ||
| 622 | CONFIG_FSCACHE=m | 630 | CONFIG_FSCACHE=m |
| 623 | CONFIG_CACHEFILES=m | 631 | CONFIG_CACHEFILES=m |
| 624 | CONFIG_ISO9660_FS=y | 632 | CONFIG_ISO9660_FS=y |
| @@ -654,7 +662,6 @@ CONFIG_NFSD_V3_ACL=y · 29 unmodified lines | |||
| 654 | CONFIG_NFSD_V4=y | 662 | CONFIG_NFSD_V4=y |
| 655 | CONFIG_NFSD_V4_SECURITY_LABEL=y | 663 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 656 | CONFIG_CIFS=m | 664 | CONFIG_CIFS=m |
| 657 | CONFIG_CIFS_STATS2=y | ||
| 658 | CONFIG_CIFS_WEAK_PW_HASH=y | 665 | CONFIG_CIFS_WEAK_PW_HASH=y |
| 659 | CONFIG_CIFS_UPCALL=y | 666 | CONFIG_CIFS_UPCALL=y |
| 660 | CONFIG_CIFS_XATTR=y | 667 | CONFIG_CIFS_XATTR=y |
| @@ -682,6 +689,7 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y · 21 unmodified lines | |||
| 682 | CONFIG_SECURITY_SELINUX_DISABLE=y | 689 | CONFIG_SECURITY_SELINUX_DISABLE=y |
| 683 | CONFIG_SECURITY_LOCKDOWN_LSM=y | 690 | CONFIG_SECURITY_LOCKDOWN_LSM=y |
| 684 | CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y | 691 | CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y |
| 692 | CONFIG_SECURITY_LANDLOCK=y | ||
| 685 | CONFIG_INTEGRITY_SIGNATURE=y | 693 | CONFIG_INTEGRITY_SIGNATURE=y |
| 686 | CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y | 694 | CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y |
| 687 | CONFIG_IMA=y | 695 | CONFIG_IMA=y |
| @@ -696,6 +704,7 @@ CONFIG_CRYPTO_CRYPTD=m · 8 unmodified lines | |||
| 696 | CONFIG_CRYPTO_TEST=m | 704 | CONFIG_CRYPTO_TEST=m |
| 697 | CONFIG_CRYPTO_DH=m | 705 | CONFIG_CRYPTO_DH=m |
| 698 | CONFIG_CRYPTO_ECDH=m | 706 | CONFIG_CRYPTO_ECDH=m |
| 707 | CONFIG_CRYPTO_ECDSA=m | ||
| 699 | CONFIG_CRYPTO_ECRDSA=m | 708 | CONFIG_CRYPTO_ECRDSA=m |
| 700 | CONFIG_CRYPTO_SM2=m | 709 | CONFIG_CRYPTO_SM2=m |
| 701 | CONFIG_CRYPTO_CURVE25519=m | 710 | CONFIG_CRYPTO_CURVE25519=m |
| @@ -843,7 +852,6 @@ CONFIG_FAULT_INJECTION_DEBUG_FS=y · 141 unmodified lines | |||
| 843 | CONFIG_FAIL_FUNCTION=y | 852 | CONFIG_FAIL_FUNCTION=y |
| 844 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y | 853 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y |
| 845 | CONFIG_LKDTM=m | 854 | CONFIG_LKDTM=m |
| 846 | CONFIG_TEST_LIST_SORT=y | ||
| 847 | CONFIG_TEST_MIN_HEAP=y | 855 | CONFIG_TEST_MIN_HEAP=y |
| 848 | CONFIG_TEST_SORT=y | 856 | CONFIG_TEST_SORT=y |
| 849 | CONFIG_KPROBES_SANITY_TEST=y | 857 | CONFIG_KPROBES_SANITY_TEST=y |
| @@ -853,3 +861,4 @@ CONFIG_PERCPU_TEST=m · 3 unmodified lines | |||
| 853 | CONFIG_ATOMIC64_SELFTEST=y | 861 | CONFIG_ATOMIC64_SELFTEST=y |
| 854 | CONFIG_TEST_BITOPS=m | 862 | CONFIG_TEST_BITOPS=m |
| 855 | CONFIG_TEST_BPF=m | 863 | CONFIG_TEST_BPF=m |
| 864 | CONFIG_TEST_LIVEPATCH=m | ||
| @@ -4,6 +4,11 @@ CONFIG_WATCH_QUEUE=y · 3 unmodified lines | |||
| 4 | CONFIG_AUDIT=y | 4 | CONFIG_AUDIT=y |
| 5 | CONFIG_NO_HZ_IDLE=y | 5 | CONFIG_NO_HZ_IDLE=y |
| 6 | CONFIG_HIGH_RES_TIMERS=y | 6 | CONFIG_HIGH_RES_TIMERS=y |
| 7 | CONFIG_BPF_SYSCALL=y | ||
| 8 | CONFIG_BPF_JIT=y | ||
| 9 | CONFIG_BPF_JIT_ALWAYS_ON=y | ||
| 10 | CONFIG_BPF_LSM=y | ||
| 11 | CONFIG_SCHED_CORE=y | ||
| 7 | CONFIG_BSD_PROCESS_ACCT=y | 12 | CONFIG_BSD_PROCESS_ACCT=y |
| 8 | CONFIG_BSD_PROCESS_ACCT_V3=y | 13 | CONFIG_BSD_PROCESS_ACCT_V3=y |
| 9 | CONFIG_TASKSTATS=y | 14 | CONFIG_TASKSTATS=y |
| @@ -26,14 +31,13 @@ CONFIG_CGROUP_DEVICE=y · 16 unmodified lines | |||
| 26 | CONFIG_CGROUP_CPUACCT=y | 31 | CONFIG_CGROUP_CPUACCT=y |
| 27 | CONFIG_CGROUP_PERF=y | 32 | CONFIG_CGROUP_PERF=y |
| 28 | CONFIG_CGROUP_BPF=y | 33 | CONFIG_CGROUP_BPF=y |
| 34 | CONFIG_CGROUP_MISC=y | ||
| 29 | CONFIG_NAMESPACES=y | 35 | CONFIG_NAMESPACES=y |
| 30 | CONFIG_USER_NS=y | 36 | CONFIG_USER_NS=y |
| 31 | CONFIG_CHECKPOINT_RESTORE=y | 37 | CONFIG_CHECKPOINT_RESTORE=y |
| 32 | CONFIG_SCHED_AUTOGROUP=y | 38 | CONFIG_SCHED_AUTOGROUP=y |
| 33 | CONFIG_EXPERT=y | 39 | CONFIG_EXPERT=y |
| 34 | # CONFIG_SYSFS_SYSCALL is not set | 40 | # CONFIG_SYSFS_SYSCALL is not set |
| 35 | CONFIG_BPF_LSM=y | ||
| 36 | CONFIG_BPF_SYSCALL=y | ||
| 37 | CONFIG_USERFAULTFD=y | 41 | CONFIG_USERFAULTFD=y |
| 38 | # CONFIG_COMPAT_BRK is not set | 42 | # CONFIG_COMPAT_BRK is not set |
| 39 | CONFIG_PROFILING=y | 43 | CONFIG_PROFILING=y |
| @@ -70,6 +74,7 @@ CONFIG_BLK_DEV_THROTTLING=y · 30 unmodified lines | |||
| 70 | CONFIG_BLK_WBT=y | 74 | CONFIG_BLK_WBT=y |
| 71 | CONFIG_BLK_CGROUP_IOLATENCY=y | 75 | CONFIG_BLK_CGROUP_IOLATENCY=y |
| 72 | CONFIG_BLK_CGROUP_IOCOST=y | 76 | CONFIG_BLK_CGROUP_IOCOST=y |
| 77 | CONFIG_BLK_CGROUP_IOPRIO=y | ||
| 73 | CONFIG_BLK_INLINE_ENCRYPTION=y | 78 | CONFIG_BLK_INLINE_ENCRYPTION=y |
| 74 | CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y | 79 | CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y |
| 75 | CONFIG_PARTITION_ADVANCED=y | 80 | CONFIG_PARTITION_ADVANCED=y |
| @@ -87,6 +92,7 @@ CONFIG_KSM=y · 11 unmodified lines | |||
| 87 | CONFIG_TRANSPARENT_HUGEPAGE=y | 92 | CONFIG_TRANSPARENT_HUGEPAGE=y |
| 88 | CONFIG_CLEANCACHE=y | 93 | CONFIG_CLEANCACHE=y |
| 89 | CONFIG_FRONTSWAP=y | 94 | CONFIG_FRONTSWAP=y |
| 95 | CONFIG_CMA_SYSFS=y | ||
| 90 | CONFIG_CMA_AREAS=7 | 96 | CONFIG_CMA_AREAS=7 |
| 91 | CONFIG_MEM_SOFT_DIRTY=y | 97 | CONFIG_MEM_SOFT_DIRTY=y |
| 92 | CONFIG_ZSWAP=y | 98 | CONFIG_ZSWAP=y |
| @@ -149,6 +155,7 @@ CONFIG_IPV6_RPL_LWTUNNEL=y · 56 unmodified lines | |||
| 149 | CONFIG_MPTCP=y | 155 | CONFIG_MPTCP=y |
| 150 | CONFIG_NETFILTER=y | 156 | CONFIG_NETFILTER=y |
| 151 | CONFIG_BRIDGE_NETFILTER=m | 157 | CONFIG_BRIDGE_NETFILTER=m |
| 158 | CONFIG_NETFILTER_NETLINK_HOOK=m | ||
| 152 | CONFIG_NF_CONNTRACK=m | 159 | CONFIG_NF_CONNTRACK=m |
| 153 | CONFIG_NF_CONNTRACK_SECMARK=y | 160 | CONFIG_NF_CONNTRACK_SECMARK=y |
| 154 | CONFIG_NF_CONNTRACK_EVENTS=y | 161 | CONFIG_NF_CONNTRACK_EVENTS=y |
| @@ -271,6 +278,7 @@ CONFIG_IP_VS_FTP=m · 116 unmodified lines | |||
| 271 | CONFIG_IP_VS_PE_SIP=m | 278 | CONFIG_IP_VS_PE_SIP=m |
| 272 | CONFIG_NFT_FIB_IPV4=m | 279 | CONFIG_NFT_FIB_IPV4=m |
| 273 | CONFIG_NF_TABLES_ARP=y | 280 | CONFIG_NF_TABLES_ARP=y |
| 281 | CONFIG_NF_LOG_IPV4=m | ||
| 274 | CONFIG_IP_NF_IPTABLES=m | 282 | CONFIG_IP_NF_IPTABLES=m |
| 275 | CONFIG_IP_NF_MATCH_AH=m | 283 | CONFIG_IP_NF_MATCH_AH=m |
| 276 | CONFIG_IP_NF_MATCH_ECN=m | 284 | CONFIG_IP_NF_MATCH_ECN=m |
| @@ -374,11 +382,10 @@ CONFIG_VSOCKETS=m · 97 unmodified lines | |||
| 374 | CONFIG_VIRTIO_VSOCKETS=m | 382 | CONFIG_VIRTIO_VSOCKETS=m |
| 375 | CONFIG_NETLINK_DIAG=m | 383 | CONFIG_NETLINK_DIAG=m |
| 376 | CONFIG_CGROUP_NET_PRIO=y | 384 | CONFIG_CGROUP_NET_PRIO=y |
| 377 | CONFIG_BPF_JIT=y | ||
| 378 | CONFIG_NET_PKTGEN=m | 385 | CONFIG_NET_PKTGEN=m |
| 379 | CONFIG_PCI=y | 386 | CONFIG_PCI=y |
| 380 | CONFIG_PCI_IOV=y | ||
| 381 | # CONFIG_PCIEASPM is not set | 387 | # CONFIG_PCIEASPM is not set |
| 388 | CONFIG_PCI_IOV=y | ||
| 382 | CONFIG_HOTPLUG_PCI=y | 389 | CONFIG_HOTPLUG_PCI=y |
| 383 | CONFIG_HOTPLUG_PCI_S390=y | 390 | CONFIG_HOTPLUG_PCI_S390=y |
| 384 | CONFIG_UEVENT_HELPER=y | 391 | CONFIG_UEVENT_HELPER=y |
| @@ -427,7 +434,7 @@ CONFIG_MD_MULTIPATH=m · 42 unmodified lines | |||
| 427 | CONFIG_MD_FAULTY=m | 434 | CONFIG_MD_FAULTY=m |
| 428 | CONFIG_MD_CLUSTER=m | 435 | CONFIG_MD_CLUSTER=m |
| 429 | CONFIG_BCACHE=m | 436 | CONFIG_BCACHE=m |
| 430 | CONFIG_BLK_DEV_DM=m | 437 | CONFIG_BLK_DEV_DM=y |
| 431 | CONFIG_DM_UNSTRIPED=m | 438 | CONFIG_DM_UNSTRIPED=m |
| 432 | CONFIG_DM_CRYPT=m | 439 | CONFIG_DM_CRYPT=m |
| 433 | CONFIG_DM_SNAPSHOT=m | 440 | CONFIG_DM_SNAPSHOT=m |
| @@ -444,6 +451,7 @@ CONFIG_DM_MULTIPATH_ST=m · 10 unmodified lines | |||
| 444 | CONFIG_DM_MULTIPATH_HST=m | 451 | CONFIG_DM_MULTIPATH_HST=m |
| 445 | CONFIG_DM_MULTIPATH_IOA=m | 452 | CONFIG_DM_MULTIPATH_IOA=m |
| 446 | CONFIG_DM_DELAY=m | 453 | CONFIG_DM_DELAY=m |
| 454 | CONFIG_DM_INIT=y | ||
| 447 | CONFIG_DM_UEVENT=y | 455 | CONFIG_DM_UEVENT=y |
| 448 | CONFIG_DM_FLAKEY=m | 456 | CONFIG_DM_FLAKEY=m |
| 449 | CONFIG_DM_VERITY=m | 457 | CONFIG_DM_VERITY=m |
| @@ -487,6 +495,7 @@ CONFIG_NLMON=m · 37 unmodified lines | |||
| 487 | # CONFIG_NET_VENDOR_GOOGLE is not set | 495 | # CONFIG_NET_VENDOR_GOOGLE is not set |
| 488 | # CONFIG_NET_VENDOR_HUAWEI is not set | 496 | # CONFIG_NET_VENDOR_HUAWEI is not set |
| 489 | # CONFIG_NET_VENDOR_INTEL is not set | 497 | # CONFIG_NET_VENDOR_INTEL is not set |
| 498 | # CONFIG_NET_VENDOR_MICROSOFT is not set | ||
| 490 | # CONFIG_NET_VENDOR_MARVELL is not set | 499 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 491 | CONFIG_MLX4_EN=m | 500 | CONFIG_MLX4_EN=m |
| 492 | CONFIG_MLX5_CORE=m | 501 | CONFIG_MLX5_CORE=m |
| @@ -543,7 +552,6 @@ CONFIG_INPUT_EVDEV=y · 50 unmodified lines | |||
| 543 | CONFIG_LEGACY_PTY_COUNT=0 | 552 | CONFIG_LEGACY_PTY_COUNT=0 |
| 544 | CONFIG_VIRTIO_CONSOLE=m | 553 | CONFIG_VIRTIO_CONSOLE=m |
| 545 | CONFIG_HW_RANDOM_VIRTIO=m | 554 | CONFIG_HW_RANDOM_VIRTIO=m |
| 546 | CONFIG_RAW_DRIVER=m | ||
| 547 | CONFIG_HANGCHECK_TIMER=m | 555 | CONFIG_HANGCHECK_TIMER=m |
| 548 | CONFIG_TN3270_FS=y | 556 | CONFIG_TN3270_FS=y |
| 549 | # CONFIG_PTP_1588_CLOCK is not set | 557 | # CONFIG_PTP_1588_CLOCK is not set |
| @@ -566,7 +574,6 @@ CONFIG_SYNC_FILE=y · 16 unmodified lines | |||
| 566 | CONFIG_VFIO=m | 574 | CONFIG_VFIO=m |
| 567 | CONFIG_VFIO_PCI=m | 575 | CONFIG_VFIO_PCI=m |
| 568 | CONFIG_VFIO_MDEV=m | 576 | CONFIG_VFIO_MDEV=m |
| 569 | CONFIG_VFIO_MDEV_DEVICE=m | ||
| 570 | CONFIG_VIRTIO_PCI=m | 577 | CONFIG_VIRTIO_PCI=m |
| 571 | CONFIG_VIRTIO_BALLOON=m | 578 | CONFIG_VIRTIO_BALLOON=m |
| 572 | CONFIG_VIRTIO_INPUT=y | 579 | CONFIG_VIRTIO_INPUT=y |
| @@ -607,6 +614,7 @@ CONFIG_FUSE_FS=y · 34 unmodified lines | |||
| 607 | CONFIG_CUSE=m | 614 | CONFIG_CUSE=m |
| 608 | CONFIG_VIRTIO_FS=m | 615 | CONFIG_VIRTIO_FS=m |
| 609 | CONFIG_OVERLAY_FS=m | 616 | CONFIG_OVERLAY_FS=m |
| 617 | CONFIG_NETFS_STATS=y | ||
| 610 | CONFIG_FSCACHE=m | 618 | CONFIG_FSCACHE=m |
| 611 | CONFIG_CACHEFILES=m | 619 | CONFIG_CACHEFILES=m |
| 612 | CONFIG_ISO9660_FS=y | 620 | CONFIG_ISO9660_FS=y |
| @@ -642,7 +650,6 @@ CONFIG_NFSD_V3_ACL=y · 29 unmodified lines | |||
| 642 | CONFIG_NFSD_V4=y | 650 | CONFIG_NFSD_V4=y |
| 643 | CONFIG_NFSD_V4_SECURITY_LABEL=y | 651 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 644 | CONFIG_CIFS=m | 652 | CONFIG_CIFS=m |
| 645 | CONFIG_CIFS_STATS2=y | ||
| 646 | CONFIG_CIFS_WEAK_PW_HASH=y | 653 | CONFIG_CIFS_WEAK_PW_HASH=y |
| 647 | CONFIG_CIFS_UPCALL=y | 654 | CONFIG_CIFS_UPCALL=y |
| 648 | CONFIG_CIFS_XATTR=y | 655 | CONFIG_CIFS_XATTR=y |
| @@ -669,6 +676,7 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y · 20 unmodified lines | |||
| 669 | CONFIG_SECURITY_SELINUX_DISABLE=y | 676 | CONFIG_SECURITY_SELINUX_DISABLE=y |
| 670 | CONFIG_SECURITY_LOCKDOWN_LSM=y | 677 | CONFIG_SECURITY_LOCKDOWN_LSM=y |
| 671 | CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y | 678 | CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y |
| 679 | CONFIG_SECURITY_LANDLOCK=y | ||
| 672 | CONFIG_INTEGRITY_SIGNATURE=y | 680 | CONFIG_INTEGRITY_SIGNATURE=y |
| 673 | CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y | 681 | CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y |
| 674 | CONFIG_IMA=y | 682 | CONFIG_IMA=y |
| @@ -684,6 +692,7 @@ CONFIG_CRYPTO_CRYPTD=m · 9 unmodified lines | |||
| 684 | CONFIG_CRYPTO_TEST=m | 692 | CONFIG_CRYPTO_TEST=m |
| 685 | CONFIG_CRYPTO_DH=m | 693 | CONFIG_CRYPTO_DH=m |
| 686 | CONFIG_CRYPTO_ECDH=m | 694 | CONFIG_CRYPTO_ECDH=m |
| 695 | CONFIG_CRYPTO_ECDSA=m | ||
| 687 | CONFIG_CRYPTO_ECRDSA=m | 696 | CONFIG_CRYPTO_ECRDSA=m |
| 688 | CONFIG_CRYPTO_SM2=m | 697 | CONFIG_CRYPTO_SM2=m |
| 689 | CONFIG_CRYPTO_CURVE25519=m | 698 | CONFIG_CRYPTO_CURVE25519=m |
| @@ -754,6 +763,7 @@ CONFIG_CRC8=m · 64 unmodified lines | |||
| 754 | CONFIG_DMA_CMA=y | 763 | CONFIG_DMA_CMA=y |
| 755 | CONFIG_CMA_SIZE_MBYTES=0 | 764 | CONFIG_CMA_SIZE_MBYTES=0 |
| 756 | CONFIG_PRINTK_TIME=y | 765 | CONFIG_PRINTK_TIME=y |
| 766 | CONFIG_DYNAMIC_DEBUG=y | ||
| 757 | CONFIG_DEBUG_INFO=y | 767 | CONFIG_DEBUG_INFO=y |
| 758 | CONFIG_DEBUG_INFO_DWARF4=y | 768 | CONFIG_DEBUG_INFO_DWARF4=y |
| 759 | CONFIG_GDB_SCRIPTS=y | 769 | CONFIG_GDB_SCRIPTS=y |
| @@ -781,3 +791,4 @@ CONFIG_LKDTM=m · 21 unmodified lines | |||
| 781 | CONFIG_PERCPU_TEST=m | 791 | CONFIG_PERCPU_TEST=m |
| 782 | CONFIG_ATOMIC64_SELFTEST=y | 792 | CONFIG_ATOMIC64_SELFTEST=y |
| 783 | CONFIG_TEST_BPF=m | 793 | CONFIG_TEST_BPF=m |
| 794 | CONFIG_TEST_LIVEPATCH=m | ||
| @@ -29,9 +29,9 @@ CONFIG_PARTITION_ADVANCED=y · 28 unmodified lines | |||
| 29 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 29 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| 30 | # CONFIG_COMPACTION is not set | 30 | # CONFIG_COMPACTION is not set |
| 31 | # CONFIG_MIGRATION is not set | 31 | # CONFIG_MIGRATION is not set |
| 32 | # CONFIG_BOUNCE is not set | ||
| 33 | CONFIG_NET=y | 32 | CONFIG_NET=y |
| 34 | # CONFIG_IUCV is not set | 33 | # CONFIG_IUCV is not set |
| 34 | # CONFIG_PCPU_DEV_REFCNT is not set | ||
| 35 | # CONFIG_ETHTOOL_NETLINK is not set | 35 | # CONFIG_ETHTOOL_NETLINK is not set |
| 36 | CONFIG_DEVTMPFS=y | 36 | CONFIG_DEVTMPFS=y |
| 37 | CONFIG_BLK_DEV_RAM=y | 37 | CONFIG_BLK_DEV_RAM=y |
| @@ -51,7 +51,6 @@ CONFIG_ZFCP=y · 13 unmodified lines | |||
| 51 | # CONFIG_SERIO is not set | 51 | # CONFIG_SERIO is not set |
| 52 | # CONFIG_HVC_IUCV is not set | 52 | # CONFIG_HVC_IUCV is not set |
| 53 | # CONFIG_HW_RANDOM_S390 is not set | 53 | # CONFIG_HW_RANDOM_S390 is not set |
| 54 | CONFIG_RAW_DRIVER=y | ||
| 55 | # CONFIG_HMC_DRV is not set | 54 | # CONFIG_HMC_DRV is not set |
| 56 | # CONFIG_S390_TAPE is not set | 55 | # CONFIG_S390_TAPE is not set |
| 57 | # CONFIG_VMCP is not set | 56 | # CONFIG_VMCP is not set |
| @@ -19,6 +19,7 @@ void ftrace_caller(void); · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | extern char ftrace_graph_caller_end; | 20 | extern char ftrace_graph_caller_end; |
| 21 | extern unsigned long ftrace_plt; | 21 | extern unsigned long ftrace_plt; |
| 22 | extern void *ftrace_func; | ||
| 22 | 23 | ||
| 23 | struct dyn_arch_ftrace { }; | 24 | struct dyn_arch_ftrace { }; |
| 24 | 25 | ||
| @@ -40,6 +40,7 @@ · 39 unmodified lines | |||
| 40 | * trampoline (ftrace_plt), which clobbers also r1. | 40 | * trampoline (ftrace_plt), which clobbers also r1. |
| 41 | */ | 41 | */ |
| 42 | 42 | ||
| 43 | void *ftrace_func __read_mostly = ftrace_stub; | ||
| 43 | unsigned long ftrace_plt; | 44 | unsigned long ftrace_plt; |
| 44 | 45 | ||
| 45 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, | 46 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, |
| @@ -85,6 +86,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) · 39 unmodified lines | |||
| 85 | 86 | ||
| 86 | int ftrace_update_ftrace_func(ftrace_func_t func) | 87 | int ftrace_update_ftrace_func(ftrace_func_t func) |
| 87 | { | 88 | { |
| 89 | ftrace_func = func; | ||
| 88 | return 0; | 90 | return 0; |
| 89 | } | 91 | } |
| 90 | 92 | ||
| @@ -59,13 +59,13 @@ ENTRY(ftrace_caller) · 58 unmodified lines | |||
| 59 | #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES | 59 | #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES |
| 60 | aghik %r2,%r0,-MCOUNT_INSN_SIZE | 60 | aghik %r2,%r0,-MCOUNT_INSN_SIZE |
| 61 | lgrl %r4,function_trace_op | 61 | lgrl %r4,function_trace_op |
| 62 | lgrl %r1,ftrace_trace_function | 62 | lgrl %r1,ftrace_func |
| 63 | #else | 63 | #else |
| 64 | lgr %r2,%r0 | 64 | lgr %r2,%r0 |
| 65 | aghi %r2,-MCOUNT_INSN_SIZE | 65 | aghi %r2,-MCOUNT_INSN_SIZE |
| 66 | larl %r4,function_trace_op | 66 | larl %r4,function_trace_op |
| 67 | lg %r4,0(%r4) | 67 | lg %r4,0(%r4) |
| 68 | larl %r1,ftrace_trace_function | 68 | larl %r1,ftrace_func |
| 69 | lg %r1,0(%r1) | 69 | lg %r1,0(%r1) |
| 70 | #endif | 70 | #endif |
| 71 | lgr %r3,%r14 | 71 | lgr %r3,%r14 |
| @@ -745,7 +745,7 @@ static int __init cpumf_pmu_init(void) · 744 unmodified lines | |||
| 745 | if (!cf_dbg) { | 745 | if (!cf_dbg) { |
| 746 | pr_err("Registration of s390dbf(cpum_cf) failed\n"); | 746 | pr_err("Registration of s390dbf(cpum_cf) failed\n"); |
| 747 | return -ENOMEM; | 747 | return -ENOMEM; |
| 748 | }; | 748 | } |
| 749 | debug_register_view(cf_dbg, &debug_sprintf_view); | 749 | debug_register_view(cf_dbg, &debug_sprintf_view); |
| 750 | 750 | ||
| 751 | cpumf_pmu.attr_groups = cpumf_cf_event_group(); | 751 | cpumf_pmu.attr_groups = cpumf_cf_event_group(); |
| @@ -29,6 +29,7 @@ $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32) · 28 unmodified lines | |||
| 29 | $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32) | 29 | $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32) |
| 30 | 30 | ||
| 31 | obj-y += vdso32_wrapper.o | 31 | obj-y += vdso32_wrapper.o |
| 32 | targets += vdso32.lds | ||
| 32 | CPPFLAGS_vdso32.lds += -P -C -U$(ARCH) | 33 | CPPFLAGS_vdso32.lds += -P -C -U$(ARCH) |
| 33 | 34 | ||
| 34 | # Disable gcov profiling, ubsan and kasan for VDSO code | 35 | # Disable gcov profiling, ubsan and kasan for VDSO code |
| @@ -112,7 +112,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1) · 111 unmodified lines | |||
| 112 | { | 112 | { |
| 113 | u32 r1 = reg2hex[b1]; | 113 | u32 r1 = reg2hex[b1]; |
| 114 | 114 | ||
| 115 | if (!jit->seen_reg[r1] && r1 >= 6 && r1 <= 15) | 115 | if (r1 >= 6 && r1 <= 15 && !jit->seen_reg[r1]) |
| 116 | jit->seen_reg[r1] = 1; | 116 | jit->seen_reg[r1] = 1; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| @@ -1153,6 +1153,11 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, · 1034 unmodified lines | |||
| 1153 | break; | 1153 | break; |
| 1154 | } | 1154 | } |
| 1155 | break; | 1155 | break; |
| 1156 | /* | ||
| 1157 | * BPF_NOSPEC (speculation barrier) | ||
| 1158 | */ | ||
| 1159 | case BPF_ST | BPF_NOSPEC: | ||
| 1160 | break; | ||
| 1156 | /* | 1161 | /* |
| 1157 | * BPF_ST(X) | 1162 | * BPF_ST(X) |
| 1158 | */ | 1163 | */ |
| @@ -39,7 +39,6 @@ config SUPERH · 38 unmodified lines | |||
| 39 | select HAVE_FUTEX_CMPXCHG if FUTEX | 39 | select HAVE_FUTEX_CMPXCHG if FUTEX |
| 40 | select HAVE_FTRACE_MCOUNT_RECORD | 40 | select HAVE_FTRACE_MCOUNT_RECORD |
| 41 | select HAVE_HW_BREAKPOINT | 41 | select HAVE_HW_BREAKPOINT |
| 42 | select HAVE_IDE if HAS_IOPORT_MAP | ||
| 43 | select HAVE_IOREMAP_PROT if MMU && !X2TLB | 42 | select HAVE_IOREMAP_PROT if MMU && !X2TLB |
| 44 | select HAVE_KERNEL_BZIP2 | 43 | select HAVE_KERNEL_BZIP2 |
| 45 | select HAVE_KERNEL_GZIP | 44 | select HAVE_KERNEL_GZIP |
| @@ -19,7 +19,6 @@ config SPARC · 18 unmodified lines | |||
| 19 | select OF | 19 | select OF |
| 20 | select OF_PROMTREE | 20 | select OF_PROMTREE |
| 21 | select HAVE_ASM_MODVERSIONS | 21 | select HAVE_ASM_MODVERSIONS |
| 22 | select HAVE_IDE | ||
| 23 | select HAVE_ARCH_KGDB if !SMP || SPARC64 | 22 | select HAVE_ARCH_KGDB if !SMP || SPARC64 |
| 24 | select HAVE_ARCH_TRACEHOOK | 23 | select HAVE_ARCH_TRACEHOOK |
| 25 | select HAVE_ARCH_SECCOMP if SPARC64 | 24 | select HAVE_ARCH_SECCOMP if SPARC64 |
| @@ -1287,6 +1287,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) · 1286 unmodified lines | |||
| 1287 | return 1; | 1287 | return 1; |
| 1288 | break; | 1288 | break; |
| 1289 | } | 1289 | } |
| 1290 | /* speculation barrier */ | ||
| 1291 | case BPF_ST | BPF_NOSPEC: | ||
| 1292 | break; | ||
| 1290 | /* ST: *(size *)(dst + off) = imm */ | 1293 | /* ST: *(size *)(dst + off) = imm */ |
| 1291 | case BPF_ST | BPF_MEM | BPF_W: | 1294 | case BPF_ST | BPF_MEM | BPF_W: |
| 1292 | case BPF_ST | BPF_MEM | BPF_H: | 1295 | case BPF_ST | BPF_MEM | BPF_H: |
| @@ -202,7 +202,6 @@ config X86 · 201 unmodified lines | |||
| 202 | select HAVE_FUNCTION_TRACER | 202 | select HAVE_FUNCTION_TRACER |
| 203 | select HAVE_GCC_PLUGINS | 203 | select HAVE_GCC_PLUGINS |
| 204 | select HAVE_HW_BREAKPOINT | 204 | select HAVE_HW_BREAKPOINT |
| 205 | select HAVE_IDE | ||
| 206 | select HAVE_IOREMAP_PROT | 205 | select HAVE_IOREMAP_PROT |
| 207 | select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 | 206 | select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 |
| 208 | select HAVE_IRQ_TIME_ACCOUNTING | 207 | select HAVE_IRQ_TIME_ACCOUNTING |
| @@ -237,7 +237,7 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus) · 236 unmodified lines | |||
| 237 | for_each_present_cpu(i) { | 237 | for_each_present_cpu(i) { |
| 238 | if (i == 0) | 238 | if (i == 0) |
| 239 | continue; | 239 | continue; |
| 240 | ret = hv_call_add_logical_proc(numa_cpu_node(i), i, i); | 240 | ret = hv_call_add_logical_proc(numa_cpu_node(i), i, cpu_physical_id(i)); |
| 241 | BUG_ON(ret); | 241 | BUG_ON(ret); |
| 242 | } | 242 | } |
| 243 | 243 | ||
| @@ -79,9 +79,10 @@ __jump_label_patch(struct jump_entry *entry, enum jump_label_type type) · 78 unmodified lines | |||
| 79 | return (struct jump_label_patch){.code = code, .size = size}; | 79 | return (struct jump_label_patch){.code = code, .size = size}; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static inline void __jump_label_transform(struct jump_entry *entry, | 82 | static __always_inline void |
| 83 | enum jump_label_type type, | 83 | __jump_label_transform(struct jump_entry *entry, |
| 84 | int init) | 84 | enum jump_label_type type, |
| 85 | int init) | ||
| 85 | { | 86 | { |
| 86 | const struct jump_label_patch jlp = __jump_label_patch(entry, type); | 87 | const struct jump_label_patch jlp = __jump_label_patch(entry, type); |
| 87 | 88 | ||
| @@ -682,7 +682,6 @@ int p4d_clear_huge(p4d_t *p4d) · 681 unmodified lines | |||
| 682 | } | 682 | } |
| 683 | #endif | 683 | #endif |
| 684 | 684 | ||
| 685 | #if CONFIG_PGTABLE_LEVELS > 3 | ||
| 686 | /** | 685 | /** |
| 687 | * pud_set_huge - setup kernel PUD mapping | 686 | * pud_set_huge - setup kernel PUD mapping |
| 688 | * | 687 | * |
| @@ -721,23 +720,6 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) · 32 unmodified lines | |||
| 721 | return 1; | 720 | return 1; |
| 722 | } | 721 | } |
| 723 | 722 | ||
| 724 | /** | ||
| 725 | * pud_clear_huge - clear kernel PUD mapping when it is set | ||
| 726 | * | ||
| 727 | * Returns 1 on success and 0 on failure (no PUD map is found). | ||
| 728 | */ | ||
| 729 | int pud_clear_huge(pud_t *pud) | ||
| 730 | { | ||
| 731 | if (pud_large(*pud)) { | ||
| 732 | pud_clear(pud); | ||
| 733 | return 1; | ||
| 734 | } | ||
| 735 | |||
| 736 | return 0; | ||
| 737 | } | ||
| 738 | #endif | ||
| 739 | |||
| 740 | #if CONFIG_PGTABLE_LEVELS > 2 | ||
| 741 | /** | 723 | /** |
| 742 | * pmd_set_huge - setup kernel PMD mapping | 724 | * pmd_set_huge - setup kernel PMD mapping |
| 743 | * | 725 | * |
| @@ -768,6 +750,21 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) · 24 unmodified lines | |||
| 768 | return 1; | 750 | return 1; |
| 769 | } | 751 | } |
| 770 | 752 | ||
| 753 | /** | ||
| 754 | * pud_clear_huge - clear kernel PUD mapping when it is set | ||
| 755 | * | ||
| 756 | * Returns 1 on success and 0 on failure (no PUD map is found). | ||
| 757 | */ | ||
| 758 | int pud_clear_huge(pud_t *pud) | ||
| 759 | { | ||
| 760 | if (pud_large(*pud)) { | ||
| 761 | pud_clear(pud); | ||
| 762 | return 1; | ||
| 763 | } | ||
| 764 | |||
| 765 | return 0; | ||
| 766 | } | ||
| 767 | |||
| 771 | /** | 768 | /** |
| 772 | * pmd_clear_huge - clear kernel PMD mapping when it is set | 769 | * pmd_clear_huge - clear kernel PMD mapping when it is set |
| 773 | * | 770 | * |
| @@ -782,7 +779,6 @@ int pmd_clear_huge(pmd_t *pmd) · 8 unmodified lines | |||
| 782 | 779 | ||
| 783 | return 0; | 780 | return 0; |
| 784 | } | 781 | } |
| 785 | #endif | ||
| 786 | 782 | ||
| 787 | #ifdef CONFIG_X86_64 | 783 | #ifdef CONFIG_X86_64 |
| 788 | /** | 784 | /** |
| @@ -1219,6 +1219,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, · 1218 unmodified lines | |||
| 1219 | } | 1219 | } |
| 1220 | break; | 1220 | break; |
| 1221 | 1221 | ||
| 1222 | /* speculation barrier */ | ||
| 1223 | case BPF_ST | BPF_NOSPEC: | ||
| 1224 | if (boot_cpu_has(X86_FEATURE_XMM2)) | ||
| 1225 | /* Emit 'lfence' */ | ||
| 1226 | EMIT3(0x0F, 0xAE, 0xE8); | ||
| 1227 | break; | ||
| 1228 | |||
| 1222 | /* ST: *(u8*)(dst_reg + off) = imm */ | 1229 | /* ST: *(u8*)(dst_reg + off) = imm */ |
| 1223 | case BPF_ST | BPF_MEM | BPF_B: | 1230 | case BPF_ST | BPF_MEM | BPF_B: |
| 1224 | if (is_ereg(dst_reg)) | 1231 | if (is_ereg(dst_reg)) |
| @@ -1886,6 +1886,12 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, · 1885 unmodified lines | |||
| 1886 | i++; | 1886 | i++; |
| 1887 | break; | 1887 | break; |
| 1888 | } | 1888 | } |
| 1889 | /* speculation barrier */ | ||
| 1890 | case BPF_ST | BPF_NOSPEC: | ||
| 1891 | if (boot_cpu_has(X86_FEATURE_XMM2)) | ||
| 1892 | /* Emit 'lfence' */ | ||
| 1893 | EMIT3(0x0F, 0xAE, 0xE8); | ||
| 1894 | break; | ||
| 1889 | /* ST: *(u8*)(dst_reg + off) = imm */ | 1895 | /* ST: *(u8*)(dst_reg + off) = imm */ |
| 1890 | case BPF_ST | BPF_MEM | BPF_H: | 1896 | case BPF_ST | BPF_MEM | BPF_H: |
| 1891 | case BPF_ST | BPF_MEM | BPF_B: | 1897 | case BPF_ST | BPF_MEM | BPF_B: |
| @@ -327,7 +327,6 @@ config XTENSA_PLATFORM_ISS · 326 unmodified lines | |||
| 327 | 327 | ||
| 328 | config XTENSA_PLATFORM_XT2000 | 328 | config XTENSA_PLATFORM_XT2000 |
| 329 | bool "XT2000" | 329 | bool "XT2000" |
| 330 | select HAVE_IDE | ||
| 331 | help | 330 | help |
| 332 | XT2000 is the name of Tensilica's feature-rich emulation platform. | 331 | XT2000 is the name of Tensilica's feature-rich emulation platform. |
| 333 | This hardware is capable of running a full Linux distribution. | 332 | This hardware is capable of running a full Linux distribution. |
| @@ -1440,16 +1440,17 @@ static int iocg_wake_fn(struct wait_queue_entry *wq_entry, unsigned mode, · 1439 unmodified lines | |||
| 1440 | return -1; | 1440 | return -1; |
| 1441 | 1441 | ||
| 1442 | iocg_commit_bio(ctx->iocg, wait->bio, wait->abs_cost, cost); | 1442 | iocg_commit_bio(ctx->iocg, wait->bio, wait->abs_cost, cost); |
| 1443 | wait->committed = true; | ||
| 1443 | 1444 | ||
| 1444 | /* | 1445 | /* |
| 1445 | * autoremove_wake_function() removes the wait entry only when it | 1446 | * autoremove_wake_function() removes the wait entry only when it |
| 1446 | * actually changed the task state. We want the wait always | 1447 | * actually changed the task state. We want the wait always removed. |
| 1447 | * removed. Remove explicitly and use default_wake_function(). | 1448 | * Remove explicitly and use default_wake_function(). Note that the |
| 1449 | * order of operations is important as finish_wait() tests whether | ||
| 1450 | * @wq_entry is removed without grabbing the lock. | ||
| 1448 | */ | 1451 | */ |
| 1449 | list_del_init(&wq_entry->entry); | ||
| 1450 | wait->committed = true; | ||
| 1451 | |||
| 1452 | default_wake_function(wq_entry, mode, flags, key); | 1452 | default_wake_function(wq_entry, mode, flags, key); |
| 1453 | list_del_init_careful(&wq_entry->entry); | ||
| 1453 | return 0; | 1454 | return 0; |
| 1454 | } | 1455 | } |
| 1455 | 1456 | ||
| @@ -515,17 +515,6 @@ void blk_mq_sched_insert_requests(struct blk_mq_hw_ctx *hctx, · 514 unmodified lines | |||
| 515 | percpu_ref_put(&q->q_usage_counter); | 515 | percpu_ref_put(&q->q_usage_counter); |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | static void blk_mq_sched_free_tags(struct blk_mq_tag_set *set, | ||
| 519 | struct blk_mq_hw_ctx *hctx, | ||
| 520 | unsigned int hctx_idx) | ||
| 521 | { | ||
| 522 | if (hctx->sched_tags) { | ||
| 523 | blk_mq_free_rqs(set, hctx->sched_tags, hctx_idx); | ||
| 524 | blk_mq_free_rq_map(hctx->sched_tags, set->flags); | ||
| 525 | hctx->sched_tags = NULL; | ||
| 526 | } | ||
| 527 | } | ||
| 528 | |||
| 529 | static int blk_mq_sched_alloc_tags(struct request_queue *q, | 518 | static int blk_mq_sched_alloc_tags(struct request_queue *q, |
| 530 | struct blk_mq_hw_ctx *hctx, | 519 | struct blk_mq_hw_ctx *hctx, |
| 531 | unsigned int hctx_idx) | 520 | unsigned int hctx_idx) |
| @@ -539,8 +528,10 @@ static int blk_mq_sched_alloc_tags(struct request_queue *q, · 7 unmodified lines | |||
| 539 | return -ENOMEM; | 528 | return -ENOMEM; |
| 540 | 529 | ||
| 541 | ret = blk_mq_alloc_rqs(set, hctx->sched_tags, hctx_idx, q->nr_requests); | 530 | ret = blk_mq_alloc_rqs(set, hctx->sched_tags, hctx_idx, q->nr_requests); |
| 542 | if (ret) | 531 | if (ret) { |
| 543 | blk_mq_sched_free_tags(set, hctx, hctx_idx); | 532 | blk_mq_free_rq_map(hctx->sched_tags, set->flags); |
| 533 | hctx->sched_tags = NULL; | ||
| 534 | } | ||
| 544 | 535 | ||
| 545 | return ret; | 536 | return ret; |
| 546 | } | 537 | } |
| @@ -1079,10 +1079,9 @@ static void disk_release(struct device *dev) · 1078 unmodified lines | |||
| 1079 | disk_release_events(disk); | 1079 | disk_release_events(disk); |
| 1080 | kfree(disk->random); | 1080 | kfree(disk->random); |
| 1081 | xa_destroy(&disk->part_tbl); | 1081 | xa_destroy(&disk->part_tbl); |
| 1082 | bdput(disk->part0); | ||
| 1083 | if (test_bit(GD_QUEUE_REF, &disk->state) && disk->queue) | 1082 | if (test_bit(GD_QUEUE_REF, &disk->state) && disk->queue) |
| 1084 | blk_put_queue(disk->queue); | 1083 | blk_put_queue(disk->queue); |
| 1085 | kfree(disk); | 1084 | bdput(disk->part0); /* frees the disk */ |
| 1086 | } | 1085 | } |
| 1087 | struct class block_class = { | 1086 | struct class block_class = { |
| 1088 | .name = "block", | 1087 | .name = "block", |
| @@ -370,7 +370,7 @@ config ACPI_TABLE_UPGRADE · 369 unmodified lines | |||
| 370 | config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD | 370 | config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD |
| 371 | bool "Override ACPI tables from built-in initrd" | 371 | bool "Override ACPI tables from built-in initrd" |
| 372 | depends on ACPI_TABLE_UPGRADE | 372 | depends on ACPI_TABLE_UPGRADE |
| 373 | depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION="" | 373 | depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION_NONE |
| 374 | help | 374 | help |
| 375 | This option provides functionality to override arbitrary ACPI tables | 375 | This option provides functionality to override arbitrary ACPI tables |
| 376 | from built-in uncompressed initrd. | 376 | from built-in uncompressed initrd. |
| @@ -9,6 +9,42 @@ · 8 unmodified lines | |||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
| 11 | 11 | ||
| 12 | struct pch_fivr_resp { | ||
| 13 | u64 status; | ||
| 14 | u64 result; | ||
| 15 | }; | ||
| 16 | |||
| 17 | static int pch_fivr_read(acpi_handle handle, char *method, struct pch_fivr_resp *fivr_resp) | ||
| 18 | { | ||
| 19 | struct acpi_buffer resp = { sizeof(struct pch_fivr_resp), fivr_resp}; | ||
| 20 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 21 | struct acpi_buffer format = { sizeof("NN"), "NN" }; | ||
| 22 | union acpi_object *obj; | ||
| 23 | acpi_status status; | ||
| 24 | int ret = -EFAULT; | ||
| 25 | |||
| 26 | status = acpi_evaluate_object(handle, method, NULL, &buffer); | ||
| 27 | if (ACPI_FAILURE(status)) | ||
| 28 | return ret; | ||
| 29 | |||
| 30 | obj = buffer.pointer; | ||
| 31 | if (!obj || obj->type != ACPI_TYPE_PACKAGE) | ||
| 32 | goto release_buffer; | ||
| 33 | |||
| 34 | status = acpi_extract_package(obj, &format, &resp); | ||
| 35 | if (ACPI_FAILURE(status)) | ||
| 36 | goto release_buffer; | ||
| 37 | |||
| 38 | if (fivr_resp->status) | ||
| 39 | goto release_buffer; | ||
| 40 | |||
| 41 | ret = 0; | ||
| 42 | |||
| 43 | release_buffer: | ||
| 44 | kfree(buffer.pointer); | ||
| 45 | return ret; | ||
| 46 | } | ||
| 47 | |||
| 12 | /* | 48 | /* |
| 13 | * Presentation of attributes which are defined for INT1045 | 49 | * Presentation of attributes which are defined for INT1045 |
| 14 | * They are: | 50 | * They are: |
| @@ -23,15 +59,14 @@ static ssize_t name##_show(struct device *dev,\ · 8 unmodified lines | |||
| 23 | char *buf)\ | 59 | char *buf)\ |
| 24 | {\ | 60 | {\ |
| 25 | struct acpi_device *acpi_dev = dev_get_drvdata(dev);\ | 61 | struct acpi_device *acpi_dev = dev_get_drvdata(dev);\ |
| 26 | unsigned long long val;\ | 62 | struct pch_fivr_resp fivr_resp;\ |
| 27 | acpi_status status;\ | 63 | int status;\ |
| 28 | \ | 64 | \ |
| 29 | status = acpi_evaluate_integer(acpi_dev->handle, #method,\ | 65 | status = pch_fivr_read(acpi_dev->handle, #method, &fivr_resp);\ |
| 30 | NULL, &val);\ | 66 | if (status)\ |
| 31 | if (ACPI_SUCCESS(status))\ | 67 | return status;\ |
| 32 | return sprintf(buf, "%d\n", (int)val);\ | 68 | \ |
| 33 | else\ | 69 | return sprintf(buf, "%llu\n", fivr_resp.result);\ |
| 34 | return -EINVAL;\ | ||
| 35 | } | 70 | } |
| 36 | 71 | ||
| 37 | #define PCH_FIVR_STORE(name, method) \ | 72 | #define PCH_FIVR_STORE(name, method) \ |
| @@ -423,13 +423,6 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, · 422 unmodified lines | |||
| 423 | } | 423 | } |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | static bool irq_is_legacy(struct acpi_resource_irq *irq) | ||
| 427 | { | ||
| 428 | return irq->triggering == ACPI_EDGE_SENSITIVE && | ||
| 429 | irq->polarity == ACPI_ACTIVE_HIGH && | ||
| 430 | irq->shareable == ACPI_EXCLUSIVE; | ||
| 431 | } | ||
| 432 | |||
| 433 | /** | 426 | /** |
| 434 | * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. | 427 | * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. |
| 435 | * @ares: Input ACPI resource object. | 428 | * @ares: Input ACPI resource object. |
| @@ -468,7 +461,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, · 32 unmodified lines | |||
| 468 | } | 461 | } |
| 469 | acpi_dev_get_irqresource(res, irq->interrupts[index], | 462 | acpi_dev_get_irqresource(res, irq->interrupts[index], |
| 470 | irq->triggering, irq->polarity, | 463 | irq->triggering, irq->polarity, |
| 471 | irq->shareable, irq_is_legacy(irq)); | 464 | irq->shareable, true); |
| 472 | break; | 465 | break; |
| 473 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | 466 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
| 474 | ext_irq = &ares->data.extended_irq; | 467 | ext_irq = &ares->data.extended_irq; |
| @@ -860,11 +860,9 @@ EXPORT_SYMBOL(acpi_dev_present); · 859 unmodified lines | |||
| 860 | * Return the next match of ACPI device if another matching device was present | 860 | * Return the next match of ACPI device if another matching device was present |
| 861 | * at the moment of invocation, or NULL otherwise. | 861 | * at the moment of invocation, or NULL otherwise. |
| 862 | * | 862 | * |
| 863 | * FIXME: The function does not tolerate the sudden disappearance of @adev, e.g. | ||
| 864 | * in the case of a hotplug event. That said, the caller should ensure that | ||
| 865 | * this will never happen. | ||
| 866 | * | ||
| 867 | * The caller is responsible for invoking acpi_dev_put() on the returned device. | 863 | * The caller is responsible for invoking acpi_dev_put() on the returned device. |
| 864 | * On the other hand the function invokes acpi_dev_put() on the given @adev | ||
| 865 | * assuming that its reference counter had been increased beforehand. | ||
| 868 | * | 866 | * |
| 869 | * See additional information in acpi_dev_present() as well. | 867 | * See additional information in acpi_dev_present() as well. |
| 870 | */ | 868 | */ |
| @@ -880,6 +878,7 @@ acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const cha · 9 unmodified lines | |||
| 880 | match.hrv = hrv; | 878 | match.hrv = hrv; |
| 881 | 879 | ||
| 882 | dev = bus_find_device(&acpi_bus_type, start, &match, acpi_dev_match_cb); | 880 | dev = bus_find_device(&acpi_bus_type, start, &match, acpi_dev_match_cb); |
| 881 | acpi_dev_put(adev); | ||
| 883 | return dev ? to_acpi_device(dev) : NULL; | 882 | return dev ? to_acpi_device(dev) : NULL; |
| 884 | } | 883 | } |
| 885 | EXPORT_SYMBOL(acpi_dev_get_next_match_dev); | 884 | EXPORT_SYMBOL(acpi_dev_get_next_match_dev); |
| @@ -378,19 +378,25 @@ static int lps0_device_attach(struct acpi_device *adev, · 377 unmodified lines | |||
| 378 | * AMDI0006: | 378 | * AMDI0006: |
| 379 | * - should use rev_id 0x0 | 379 | * - should use rev_id 0x0 |
| 380 | * - function mask = 0x3: Should use Microsoft method | 380 | * - function mask = 0x3: Should use Microsoft method |
| 381 | * AMDI0007: | ||
| 382 | * - Should use rev_id 0x2 | ||
| 383 | * - Should only use AMD method | ||
| 381 | */ | 384 | */ |
| 382 | const char *hid = acpi_device_hid(adev); | 385 | const char *hid = acpi_device_hid(adev); |
| 383 | rev_id = 0; | 386 | rev_id = strcmp(hid, "AMDI0007") ? 0 : 2; |
| 384 | lps0_dsm_func_mask = validate_dsm(adev->handle, | 387 | lps0_dsm_func_mask = validate_dsm(adev->handle, |
| 385 | ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid); | 388 | ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid); |
| 386 | lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle, | 389 | lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle, |
| 387 | ACPI_LPS0_DSM_UUID_MICROSOFT, rev_id, | 390 | ACPI_LPS0_DSM_UUID_MICROSOFT, 0, |
| 388 | &lps0_dsm_guid_microsoft); | 391 | &lps0_dsm_guid_microsoft); |
| 389 | if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") || | 392 | if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") || |
| 390 | !strcmp(hid, "AMDI0005"))) { | 393 | !strcmp(hid, "AMDI0005"))) { |
| 391 | lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1; | 394 | lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1; |
| 392 | acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n", | 395 | acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n", |
| 393 | ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask); | 396 | ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask); |
| 397 | } else if (lps0_dsm_func_mask_microsoft > 0 && !strcmp(hid, "AMDI0007")) { | ||
| 398 | lps0_dsm_func_mask_microsoft = -EINVAL; | ||
| 399 | acpi_handle_debug(adev->handle, "_DSM Using AMD method\n"); | ||
| 394 | } | 400 | } |
| 395 | } else { | 401 | } else { |
| 396 | rev_id = 1; | 402 | rev_id = 1; |
| @@ -637,6 +637,20 @@ unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf, · 636 unmodified lines | |||
| 637 | } | 637 | } |
| 638 | EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); | 638 | EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); |
| 639 | 639 | ||
| 640 | static void ata_pio_xfer(struct ata_queued_cmd *qc, struct page *page, | ||
| 641 | unsigned int offset, size_t xfer_size) | ||
| 642 | { | ||
| 643 | bool do_write = (qc->tf.flags & ATA_TFLAG_WRITE); | ||
| 644 | unsigned char *buf; | ||
| 645 | |||
| 646 | buf = kmap_atomic(page); | ||
| 647 | qc->ap->ops->sff_data_xfer(qc, buf + offset, xfer_size, do_write); | ||
| 648 | kunmap_atomic(buf); | ||
| 649 | |||
| 650 | if (!do_write && !PageSlab(page)) | ||
| 651 | flush_dcache_page(page); | ||
| 652 | } | ||
| 653 | |||
| 640 | /** | 654 | /** |
| 641 | * ata_pio_sector - Transfer a sector of data. | 655 | * ata_pio_sector - Transfer a sector of data. |
| 642 | * @qc: Command on going | 656 | * @qc: Command on going |
| @@ -648,11 +662,9 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); · 5 unmodified lines | |||
| 648 | */ | 662 | */ |
| 649 | static void ata_pio_sector(struct ata_queued_cmd *qc) | 663 | static void ata_pio_sector(struct ata_queued_cmd *qc) |
| 650 | { | 664 | { |
| 651 | int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); | ||
| 652 | struct ata_port *ap = qc->ap; | 665 | struct ata_port *ap = qc->ap; |
| 653 | struct page *page; | 666 | struct page *page; |
| 654 | unsigned int offset; | 667 | unsigned int offset; |
| 655 | unsigned char *buf; | ||
| 656 | 668 | ||
| 657 | if (!qc->cursg) { | 669 | if (!qc->cursg) { |
| 658 | qc->curbytes = qc->nbytes; | 670 | qc->curbytes = qc->nbytes; |
| @@ -670,13 +682,20 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) · 11 unmodified lines | |||
| 670 | 682 | ||
| 671 | DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); | 683 | DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); |
| 672 | 684 | ||
| 673 | /* do the actual data transfer */ | 685 | /* |
| 674 | buf = kmap_atomic(page); | 686 | * Split the transfer when it splits a page boundary. Note that the |
| 675 | ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write); | 687 | * split still has to be dword aligned like all ATA data transfers. |
| 676 | kunmap_atomic(buf); | 688 | */ |
| 689 | WARN_ON_ONCE(offset % 4); | ||
| 690 | if (offset + qc->sect_size > PAGE_SIZE) { | ||
| 691 | unsigned int split_len = PAGE_SIZE - offset; | ||
| 677 | 692 | ||
| 678 | if (!do_write && !PageSlab(page)) | 693 | ata_pio_xfer(qc, page, offset, split_len); |
| 679 | flush_dcache_page(page); | 694 | ata_pio_xfer(qc, nth_page(page, 1), 0, |
| 695 | qc->sect_size - split_len); | ||
| 696 | } else { | ||
| 697 | ata_pio_xfer(qc, page, offset, qc->sect_size); | ||
| 698 | } | ||
| 680 | 699 | ||
| 681 | qc->curbytes += qc->sect_size; | 700 | qc->curbytes += qc->sect_size; |
| 682 | qc->cursg_ofs += qc->sect_size; | 701 | qc->cursg_ofs += qc->sect_size; |
| @@ -231,6 +231,8 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device); · 230 unmodified lines | |||
| 231 | int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, | 231 | int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, |
| 232 | struct module *owner, const char *modname) | 232 | struct module *owner, const char *modname) |
| 233 | { | 233 | { |
| 234 | int ret; | ||
| 235 | |||
| 234 | if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) | 236 | if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) |
| 235 | return -EINVAL; | 237 | return -EINVAL; |
| 236 | 238 | ||
| @@ -246,7 +248,11 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, · 9 unmodified lines | |||
| 246 | auxdrv->driver.bus = &auxiliary_bus_type; | 248 | auxdrv->driver.bus = &auxiliary_bus_type; |
| 247 | auxdrv->driver.mod_name = modname; | 249 | auxdrv->driver.mod_name = modname; |
| 248 | 250 | ||
| 249 | return driver_register(&auxdrv->driver); | 251 | ret = driver_register(&auxdrv->driver); |
| 252 | if (ret) | ||
| 253 | kfree(auxdrv->driver.name); | ||
| 254 | |||
| 255 | return ret; | ||
| 250 | } | 256 | } |
| 251 | EXPORT_SYMBOL_GPL(__auxiliary_driver_register); | 257 | EXPORT_SYMBOL_GPL(__auxiliary_driver_register); |
| 252 | 258 | ||
| @@ -574,8 +574,10 @@ static void devlink_remove_symlinks(struct device *dev, · 573 unmodified lines | |||
| 574 | return; | 574 | return; |
| 575 | } | 575 | } |
| 576 | 576 | ||
| 577 | snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); | 577 | if (device_is_registered(con)) { |
| 578 | sysfs_remove_link(&con->kobj, buf); | 578 | snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); |
| 579 | sysfs_remove_link(&con->kobj, buf); | ||
| 580 | } | ||
| 579 | snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); | 581 | snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); |
| 580 | sysfs_remove_link(&sup->kobj, buf); | 582 | sysfs_remove_link(&sup->kobj, buf); |
| 581 | kfree(buf); | 583 | kfree(buf); |
| @@ -88,6 +88,47 @@ · 87 unmodified lines | |||
| 88 | 88 | ||
| 89 | static DEFINE_IDR(loop_index_idr); | 89 | static DEFINE_IDR(loop_index_idr); |
| 90 | static DEFINE_MUTEX(loop_ctl_mutex); | 90 | static DEFINE_MUTEX(loop_ctl_mutex); |
| 91 | static DEFINE_MUTEX(loop_validate_mutex); | ||
| 92 | |||
| 93 | /** | ||
| 94 | * loop_global_lock_killable() - take locks for safe loop_validate_file() test | ||
| 95 | * | ||
| 96 | * @lo: struct loop_device | ||
| 97 | * @global: true if @lo is about to bind another "struct loop_device", false otherwise | ||
| 98 | * | ||
| 99 | * Returns 0 on success, -EINTR otherwise. | ||
| 100 | * | ||
| 101 | * Since loop_validate_file() traverses on other "struct loop_device" if | ||
| 102 | * is_loop_device() is true, we need a global lock for serializing concurrent | ||
| 103 | * loop_configure()/loop_change_fd()/__loop_clr_fd() calls. | ||
| 104 | */ | ||
| 105 | static int loop_global_lock_killable(struct loop_device *lo, bool global) | ||
| 106 | { | ||
| 107 | int err; | ||
| 108 | |||
| 109 | if (global) { | ||
| 110 | err = mutex_lock_killable(&loop_validate_mutex); | ||
| 111 | if (err) | ||
| 112 | return err; | ||
| 113 | } | ||
| 114 | err = mutex_lock_killable(&lo->lo_mutex); | ||
| 115 | if (err && global) | ||
| 116 | mutex_unlock(&loop_validate_mutex); | ||
| 117 | return err; | ||
| 118 | } | ||
| 119 | |||
| 120 | /** | ||
| 121 | * loop_global_unlock() - release locks taken by loop_global_lock_killable() | ||
| 122 | * | ||
| 123 | * @lo: struct loop_device | ||
| 124 | * @global: true if @lo was about to bind another "struct loop_device", false otherwise | ||
| 125 | */ | ||
| 126 | static void loop_global_unlock(struct loop_device *lo, bool global) | ||
| 127 | { | ||
| 128 | mutex_unlock(&lo->lo_mutex); | ||
| 129 | if (global) | ||
| 130 | mutex_unlock(&loop_validate_mutex); | ||
| 131 | } | ||
| 91 | 132 | ||
| 92 | static int max_part; | 133 | static int max_part; |
| 93 | static int part_shift; | 134 | static int part_shift; |
| @@ -672,13 +713,15 @@ static int loop_validate_file(struct file *file, struct block_device *bdev) · 578 unmodified lines | |||
| 672 | while (is_loop_device(f)) { | 713 | while (is_loop_device(f)) { |
| 673 | struct loop_device *l; | 714 | struct loop_device *l; |
| 674 | 715 | ||
| 716 | lockdep_assert_held(&loop_validate_mutex); | ||
| 675 | if (f->f_mapping->host->i_rdev == bdev->bd_dev) | 717 | if (f->f_mapping->host->i_rdev == bdev->bd_dev) |
| 676 | return -EBADF; | 718 | return -EBADF; |
| 677 | 719 | ||
| 678 | l = I_BDEV(f->f_mapping->host)->bd_disk->private_data; | 720 | l = I_BDEV(f->f_mapping->host)->bd_disk->private_data; |
| 679 | if (l->lo_state != Lo_bound) { | 721 | if (l->lo_state != Lo_bound) |
| 680 | return -EINVAL; | 722 | return -EINVAL; |
| 681 | } | 723 | /* Order wrt setting lo->lo_backing_file in loop_configure(). */ |
| 724 | rmb(); | ||
| 682 | f = l->lo_backing_file; | 725 | f = l->lo_backing_file; |
| 683 | } | 726 | } |
| 684 | if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) | 727 | if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) |
| @@ -697,13 +740,18 @@ static int loop_validate_file(struct file *file, struct block_device *bdev) · 12 unmodified lines | |||
| 697 | static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, | 740 | static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, |
| 698 | unsigned int arg) | 741 | unsigned int arg) |
| 699 | { | 742 | { |
| 700 | struct file *file = NULL, *old_file; | 743 | struct file *file = fget(arg); |
| 701 | int error; | 744 | struct file *old_file; |
| 702 | bool partscan; | 745 | int error; |
| 746 | bool partscan; | ||
| 747 | bool is_loop; | ||
| 703 | 748 | ||
| 704 | error = mutex_lock_killable(&lo->lo_mutex); | 749 | if (!file) |
| 750 | return -EBADF; | ||
| 751 | is_loop = is_loop_device(file); | ||
| 752 | error = loop_global_lock_killable(lo, is_loop); | ||
| 705 | if (error) | 753 | if (error) |
| 706 | return error; | 754 | goto out_putf; |
| 707 | error = -ENXIO; | 755 | error = -ENXIO; |
| 708 | if (lo->lo_state != Lo_bound) | 756 | if (lo->lo_state != Lo_bound) |
| 709 | goto out_err; | 757 | goto out_err; |
| @@ -713,11 +761,6 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, · 3 unmodified lines | |||
| 713 | if (!(lo->lo_flags & LO_FLAGS_READ_ONLY)) | 761 | if (!(lo->lo_flags & LO_FLAGS_READ_ONLY)) |
| 714 | goto out_err; | 762 | goto out_err; |
| 715 | 763 | ||
| 716 | error = -EBADF; | ||
| 717 | file = fget(arg); | ||
| 718 | if (!file) | ||
| 719 | goto out_err; | ||
| 720 | |||
| 721 | error = loop_validate_file(file, bdev); | 764 | error = loop_validate_file(file, bdev); |
| 722 | if (error) | 765 | if (error) |
| 723 | goto out_err; | 766 | goto out_err; |
| @@ -740,7 +783,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, · 16 unmodified lines | |||
| 740 | loop_update_dio(lo); | 783 | loop_update_dio(lo); |
| 741 | blk_mq_unfreeze_queue(lo->lo_queue); | 784 | blk_mq_unfreeze_queue(lo->lo_queue); |
| 742 | partscan = lo->lo_flags & LO_FLAGS_PARTSCAN; | 785 | partscan = lo->lo_flags & LO_FLAGS_PARTSCAN; |
| 743 | mutex_unlock(&lo->lo_mutex); | 786 | loop_global_unlock(lo, is_loop); |
| 787 | |||
| 788 | /* | ||
| 789 | * Flush loop_validate_file() before fput(), for l->lo_backing_file | ||
| 790 | * might be pointing at old_file which might be the last reference. | ||
| 791 | */ | ||
| 792 | if (!is_loop) { | ||
| 793 | mutex_lock(&loop_validate_mutex); | ||
| 794 | mutex_unlock(&loop_validate_mutex); | ||
| 795 | } | ||
| 744 | /* | 796 | /* |
| 745 | * We must drop file reference outside of lo_mutex as dropping | 797 | * We must drop file reference outside of lo_mutex as dropping |
| 746 | * the file ref can take open_mutex which creates circular locking | 798 | * the file ref can take open_mutex which creates circular locking |
| @@ -752,9 +804,9 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, · 5 unmodified lines | |||
| 752 | return 0; | 804 | return 0; |
| 753 | 805 | ||
| 754 | out_err: | 806 | out_err: |
| 755 | mutex_unlock(&lo->lo_mutex); | 807 | loop_global_unlock(lo, is_loop); |
| 756 | if (file) | 808 | out_putf: |
| 757 | fput(file); | 809 | fput(file); |
| 758 | return error; | 810 | return error; |
| 759 | } | 811 | } |
| 760 | 812 | ||
| @@ -1136,22 +1188,22 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, · 375 unmodified lines | |||
| 1136 | struct block_device *bdev, | 1188 | struct block_device *bdev, |
| 1137 | const struct loop_config *config) | 1189 | const struct loop_config *config) |
| 1138 | { | 1190 | { |
| 1139 | struct file *file; | 1191 | struct file *file = fget(config->fd); |
| 1140 | struct inode *inode; | 1192 | struct inode *inode; |
| 1141 | struct address_space *mapping; | 1193 | struct address_space *mapping; |
| 1142 | int error; | 1194 | int error; |
| 1143 | loff_t size; | 1195 | loff_t size; |
| 1144 | bool partscan; | 1196 | bool partscan; |
| 1145 | unsigned short bsize; | 1197 | unsigned short bsize; |
| 1198 | bool is_loop; | ||
| 1199 | |||
| 1200 | if (!file) | ||
| 1201 | return -EBADF; | ||
| 1202 | is_loop = is_loop_device(file); | ||
| 1146 | 1203 | ||
| 1147 | /* This is safe, since we have a reference from open(). */ | 1204 | /* This is safe, since we have a reference from open(). */ |
| 1148 | __module_get(THIS_MODULE); | 1205 | __module_get(THIS_MODULE); |
| 1149 | 1206 | ||
| 1150 | error = -EBADF; | ||
| 1151 | file = fget(config->fd); | ||
| 1152 | if (!file) | ||
| 1153 | goto out; | ||
| 1154 | |||
| 1155 | /* | 1207 | /* |
| 1156 | * If we don't hold exclusive handle for the device, upgrade to it | 1208 | * If we don't hold exclusive handle for the device, upgrade to it |
| 1157 | * here to avoid changing device under exclusive owner. | 1209 | * here to avoid changing device under exclusive owner. |
| @@ -1162,7 +1214,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, · 4 unmodified lines | |||
| 1162 | goto out_putf; | 1214 | goto out_putf; |
| 1163 | } | 1215 | } |
| 1164 | 1216 | ||
| 1165 | error = mutex_lock_killable(&lo->lo_mutex); | 1217 | error = loop_global_lock_killable(lo, is_loop); |
| 1166 | if (error) | 1218 | if (error) |
| 1167 | goto out_bdev; | 1219 | goto out_bdev; |
| 1168 | 1220 | ||
| @@ -1242,6 +1294,9 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, · 73 unmodified lines | |||
| 1242 | size = get_loop_size(lo, file); | 1294 | size = get_loop_size(lo, file); |
| 1243 | loop_set_size(lo, size); | 1295 | loop_set_size(lo, size); |
| 1244 | 1296 | ||
| 1297 | /* Order wrt reading lo_state in loop_validate_file(). */ | ||
| 1298 | wmb(); | ||
| 1299 | |||
| 1245 | lo->lo_state = Lo_bound; | 1300 | lo->lo_state = Lo_bound; |
| 1246 | if (part_shift) | 1301 | if (part_shift) |
| 1247 | lo->lo_flags |= LO_FLAGS_PARTSCAN; | 1302 | lo->lo_flags |= LO_FLAGS_PARTSCAN; |
| @@ -1253,7 +1308,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, · 5 unmodified lines | |||
| 1253 | * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev). | 1308 | * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev). |
| 1254 | */ | 1309 | */ |
| 1255 | bdgrab(bdev); | 1310 | bdgrab(bdev); |
| 1256 | mutex_unlock(&lo->lo_mutex); | 1311 | loop_global_unlock(lo, is_loop); |
| 1257 | if (partscan) | 1312 | if (partscan) |
| 1258 | loop_reread_partitions(lo); | 1313 | loop_reread_partitions(lo); |
| 1259 | if (!(mode & FMODE_EXCL)) | 1314 | if (!(mode & FMODE_EXCL)) |
| @@ -1261,13 +1316,12 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, · 1 unmodified line | |||
| 1261 | return 0; | 1316 | return 0; |
| 1262 | 1317 | ||
| 1263 | out_unlock: | 1318 | out_unlock: |
| 1264 | mutex_unlock(&lo->lo_mutex); | 1319 | loop_global_unlock(lo, is_loop); |
| 1265 | out_bdev: | 1320 | out_bdev: |
| 1266 | if (!(mode & FMODE_EXCL)) | 1321 | if (!(mode & FMODE_EXCL)) |
| 1267 | bd_abort_claiming(bdev, loop_configure); | 1322 | bd_abort_claiming(bdev, loop_configure); |
| 1268 | out_putf: | 1323 | out_putf: |
| 1269 | fput(file); | 1324 | fput(file); |
| 1270 | out: | ||
| 1271 | /* This is safe: open() is still holding a reference. */ | 1325 | /* This is safe: open() is still holding a reference. */ |
| 1272 | module_put(THIS_MODULE); | 1326 | module_put(THIS_MODULE); |
| 1273 | return error; | 1327 | return error; |
| @@ -1283,6 +1337,18 @@ static int __loop_clr_fd(struct loop_device *lo, bool release) · 9 unmodified lines | |||
| 1283 | int lo_number; | 1337 | int lo_number; |
| 1284 | struct loop_worker *pos, *worker; | 1338 | struct loop_worker *pos, *worker; |
| 1285 | 1339 | ||
| 1340 | /* | ||
| 1341 | * Flush loop_configure() and loop_change_fd(). It is acceptable for | ||
| 1342 | * loop_validate_file() to succeed, for actual clear operation has not | ||
| 1343 | * started yet. | ||
| 1344 | */ | ||
| 1345 | mutex_lock(&loop_validate_mutex); | ||
| 1346 | mutex_unlock(&loop_validate_mutex); | ||
| 1347 | /* | ||
| 1348 | * loop_validate_file() now fails because l->lo_state != Lo_bound | ||
| 1349 | * became visible. | ||
| 1350 | */ | ||
| 1351 | |||
| 1286 | mutex_lock(&lo->lo_mutex); | 1352 | mutex_lock(&lo->lo_mutex); |
| 1287 | if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) { | 1353 | if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) { |
| 1288 | err = -ENXIO; | 1354 | err = -ENXIO; |
| @@ -4100,8 +4100,6 @@ again: · 4099 unmodified lines | |||
| 4100 | 4100 | ||
| 4101 | static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) | 4101 | static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) |
| 4102 | { | 4102 | { |
| 4103 | bool need_wait; | ||
| 4104 | |||
| 4105 | dout("%s rbd_dev %p\n", __func__, rbd_dev); | 4103 | dout("%s rbd_dev %p\n", __func__, rbd_dev); |
| 4106 | lockdep_assert_held_write(&rbd_dev->lock_rwsem); | 4104 | lockdep_assert_held_write(&rbd_dev->lock_rwsem); |
| 4107 | 4105 | ||
| @@ -4113,11 +4111,11 @@ static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) · 5 unmodified lines | |||
| 4113 | */ | 4111 | */ |
| 4114 | rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; | 4112 | rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; |
| 4115 | rbd_assert(!completion_done(&rbd_dev->releasing_wait)); | 4113 | rbd_assert(!completion_done(&rbd_dev->releasing_wait)); |
| 4116 | need_wait = !list_empty(&rbd_dev->running_list); | 4114 | if (list_empty(&rbd_dev->running_list)) |
| 4117 | downgrade_write(&rbd_dev->lock_rwsem); | 4115 | return true; |
| 4118 | if (need_wait) | 4116 | |
| 4119 | wait_for_completion(&rbd_dev->releasing_wait); | 4117 | up_write(&rbd_dev->lock_rwsem); |
| 4120 | up_read(&rbd_dev->lock_rwsem); | 4118 | wait_for_completion(&rbd_dev->releasing_wait); |
| 4121 | 4119 | ||
| 4122 | down_write(&rbd_dev->lock_rwsem); | 4120 | down_write(&rbd_dev->lock_rwsem); |
| 4123 | if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) | 4121 | if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) |
| @@ -4203,15 +4201,11 @@ static void rbd_handle_acquired_lock(struct rbd_device *rbd_dev, u8 struct_v, · 79 unmodified lines | |||
| 4203 | if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { | 4201 | if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { |
| 4204 | down_write(&rbd_dev->lock_rwsem); | 4202 | down_write(&rbd_dev->lock_rwsem); |
| 4205 | if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { | 4203 | if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { |
| 4206 | /* | 4204 | dout("%s rbd_dev %p cid %llu-%llu == owner_cid\n", |
| 4207 | * we already know that the remote client is | 4205 | __func__, rbd_dev, cid.gid, cid.handle); |
| 4208 | * the owner | 4206 | } else { |
| 4209 | */ | 4207 | rbd_set_owner_cid(rbd_dev, &cid); |
| 4210 | up_write(&rbd_dev->lock_rwsem); | ||
| 4211 | return; | ||
| 4212 | } | 4208 | } |
| 4213 | |||
| 4214 | rbd_set_owner_cid(rbd_dev, &cid); | ||
| 4215 | downgrade_write(&rbd_dev->lock_rwsem); | 4209 | downgrade_write(&rbd_dev->lock_rwsem); |
| 4216 | } else { | 4210 | } else { |
| 4217 | down_read(&rbd_dev->lock_rwsem); | 4211 | down_read(&rbd_dev->lock_rwsem); |
| @@ -4236,14 +4230,12 @@ static void rbd_handle_released_lock(struct rbd_device *rbd_dev, u8 struct_v, · 18 unmodified lines | |||
| 4236 | if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { | 4230 | if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { |
| 4237 | down_write(&rbd_dev->lock_rwsem); | 4231 | down_write(&rbd_dev->lock_rwsem); |
| 4238 | if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { | 4232 | if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { |
| 4239 | dout("%s rbd_dev %p unexpected owner, cid %llu-%llu != owner_cid %llu-%llu\n", | 4233 | dout("%s rbd_dev %p cid %llu-%llu != owner_cid %llu-%llu\n", |
| 4240 | __func__, rbd_dev, cid.gid, cid.handle, | 4234 | __func__, rbd_dev, cid.gid, cid.handle, |
| 4241 | rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); | 4235 | rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); |
| 4242 | up_write(&rbd_dev->lock_rwsem); | 4236 | } else { |
| 4243 | return; | 4237 | rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); |
| 4244 | } | 4238 | } |
| 4245 | |||
| 4246 | rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); | ||
| 4247 | downgrade_write(&rbd_dev->lock_rwsem); | 4239 | downgrade_write(&rbd_dev->lock_rwsem); |
| 4248 | } else { | 4240 | } else { |
| 4249 | down_read(&rbd_dev->lock_rwsem); | 4241 | down_read(&rbd_dev->lock_rwsem); |
| @@ -4951,6 +4943,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev) · 701 unmodified lines | |||
| 4951 | disk->minors = RBD_MINORS_PER_MAJOR; | 4943 | disk->minors = RBD_MINORS_PER_MAJOR; |
| 4952 | } | 4944 | } |
| 4953 | disk->fops = &rbd_bd_ops; | 4945 | disk->fops = &rbd_bd_ops; |
| 4946 | disk->private_data = rbd_dev; | ||
| 4954 | 4947 | ||
| 4955 | blk_queue_flag_set(QUEUE_FLAG_NONROT, q); | 4948 | blk_queue_flag_set(QUEUE_FLAG_NONROT, q); |
| 4956 | /* QUEUE_FLAG_ADD_RANDOM is off by default for blk-mq */ | 4949 | /* QUEUE_FLAG_ADD_RANDOM is off by default for blk-mq */ |
| @@ -773,11 +773,18 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, · 772 unmodified lines | |||
| 773 | cmd_pkt = mhi_to_virtual(mhi_ring, ptr); | 773 | cmd_pkt = mhi_to_virtual(mhi_ring, ptr); |
| 774 | 774 | ||
| 775 | chan = MHI_TRE_GET_CMD_CHID(cmd_pkt); | 775 | chan = MHI_TRE_GET_CMD_CHID(cmd_pkt); |
| 776 | mhi_chan = &mhi_cntrl->mhi_chan[chan]; | 776 | |
| 777 | write_lock_bh(&mhi_chan->lock); | 777 | if (chan < mhi_cntrl->max_chan && |
| 778 | mhi_chan->ccs = MHI_TRE_GET_EV_CODE(tre); | 778 | mhi_cntrl->mhi_chan[chan].configured) { |
| 779 | complete(&mhi_chan->completion); | 779 | mhi_chan = &mhi_cntrl->mhi_chan[chan]; |
| 780 | write_unlock_bh(&mhi_chan->lock); | 780 | write_lock_bh(&mhi_chan->lock); |
| 781 | mhi_chan->ccs = MHI_TRE_GET_EV_CODE(tre); | ||
| 782 | complete(&mhi_chan->completion); | ||
| 783 | write_unlock_bh(&mhi_chan->lock); | ||
| 784 | } else { | ||
| 785 | dev_err(&mhi_cntrl->mhi_dev->dev, | ||
| 786 | "Completion packet for invalid channel ID: %d\n", chan); | ||
| 787 | } | ||
| 781 | 788 | ||
| 782 | mhi_del_ring_element(mhi_cntrl, mhi_ring); | 789 | mhi_del_ring_element(mhi_cntrl, mhi_ring); |
| 783 | } | 790 | } |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | |||
| 32 | * @edl: emergency download mode firmware path (if any) | 32 | * @edl: emergency download mode firmware path (if any) |
| 33 | * @bar_num: PCI base address register to use for MHI MMIO register space | 33 | * @bar_num: PCI base address register to use for MHI MMIO register space |
| 34 | * @dma_data_width: DMA transfer word size (32 or 64 bits) | 34 | * @dma_data_width: DMA transfer word size (32 or 64 bits) |
| 35 | * @sideband_wake: Devices using dedicated sideband GPIO for wakeup instead | ||
| 36 | * of inband wake support (such as sdx24) | ||
| 35 | */ | 37 | */ |
| 36 | struct mhi_pci_dev_info { | 38 | struct mhi_pci_dev_info { |
| 37 | const struct mhi_controller_config *config; | 39 | const struct mhi_controller_config *config; |
| @@ -40,6 +42,7 @@ struct mhi_pci_dev_info { · 2 unmodified lines | |||
| 40 | const char *edl; | 42 | const char *edl; |
| 41 | unsigned int bar_num; | 43 | unsigned int bar_num; |
| 42 | unsigned int dma_data_width; | 44 | unsigned int dma_data_width; |
| 45 | bool sideband_wake; | ||
| 43 | }; | 46 | }; |
| 44 | 47 | ||
| 45 | #define MHI_CHANNEL_CONFIG_UL(ch_num, ch_name, el_count, ev_ring) \ | 48 | #define MHI_CHANNEL_CONFIG_UL(ch_num, ch_name, el_count, ev_ring) \ |
| @@ -72,6 +75,22 @@ struct mhi_pci_dev_info { · 26 unmodified lines | |||
| 72 | .doorbell_mode_switch = false, \ | 75 | .doorbell_mode_switch = false, \ |
| 73 | } | 76 | } |
| 74 | 77 | ||
| 78 | #define MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(ch_num, ch_name, el_count, ev_ring) \ | ||
| 79 | { \ | ||
| 80 | .num = ch_num, \ | ||
| 81 | .name = ch_name, \ | ||
| 82 | .num_elements = el_count, \ | ||
| 83 | .event_ring = ev_ring, \ | ||
| 84 | .dir = DMA_FROM_DEVICE, \ | ||
| 85 | .ee_mask = BIT(MHI_EE_AMSS), \ | ||
| 86 | .pollcfg = 0, \ | ||
| 87 | .doorbell = MHI_DB_BRST_DISABLE, \ | ||
| 88 | .lpm_notify = false, \ | ||
| 89 | .offload_channel = false, \ | ||
| 90 | .doorbell_mode_switch = false, \ | ||
| 91 | .auto_queue = true, \ | ||
| 92 | } | ||
| 93 | |||
| 75 | #define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \ | 94 | #define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \ |
| 76 | { \ | 95 | { \ |
| 77 | .num_elements = el_count, \ | 96 | .num_elements = el_count, \ |
| @@ -210,7 +229,7 @@ static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = { · 132 unmodified lines | |||
| 210 | MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0), | 229 | MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0), |
| 211 | MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0), | 230 | MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0), |
| 212 | MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0), | 231 | MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0), |
| 213 | MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0), | 232 | MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0), |
| 214 | MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), | 233 | MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), |
| 215 | MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), | 234 | MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), |
| 216 | MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2), | 235 | MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2), |
| @@ -242,7 +261,8 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx65_info = { · 25 unmodified lines | |||
| 242 | .edl = "qcom/sdx65m/edl.mbn", | 261 | .edl = "qcom/sdx65m/edl.mbn", |
| 243 | .config = &modem_qcom_v1_mhiv_config, | 262 | .config = &modem_qcom_v1_mhiv_config, |
| 244 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, | 263 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, |
| 245 | .dma_data_width = 32 | 264 | .dma_data_width = 32, |
| 265 | .sideband_wake = false, | ||
| 246 | }; | 266 | }; |
| 247 | 267 | ||
| 248 | static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = { | 268 | static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = { |
| @@ -251,7 +271,8 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = { · 2 unmodified lines | |||
| 251 | .edl = "qcom/sdx55m/edl.mbn", | 271 | .edl = "qcom/sdx55m/edl.mbn", |
| 252 | .config = &modem_qcom_v1_mhiv_config, | 272 | .config = &modem_qcom_v1_mhiv_config, |
| 253 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, | 273 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, |
| 254 | .dma_data_width = 32 | 274 | .dma_data_width = 32, |
| 275 | .sideband_wake = false, | ||
| 255 | }; | 276 | }; |
| 256 | 277 | ||
| 257 | static const struct mhi_pci_dev_info mhi_qcom_sdx24_info = { | 278 | static const struct mhi_pci_dev_info mhi_qcom_sdx24_info = { |
| @@ -259,7 +280,8 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx24_info = { · 1 unmodified line | |||
| 259 | .edl = "qcom/prog_firehose_sdx24.mbn", | 280 | .edl = "qcom/prog_firehose_sdx24.mbn", |
| 260 | .config = &modem_qcom_v1_mhiv_config, | 281 | .config = &modem_qcom_v1_mhiv_config, |
| 261 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, | 282 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, |
| 262 | .dma_data_width = 32 | 283 | .dma_data_width = 32, |
| 284 | .sideband_wake = true, | ||
| 263 | }; | 285 | }; |
| 264 | 286 | ||
| 265 | static const struct mhi_channel_config mhi_quectel_em1xx_channels[] = { | 287 | static const struct mhi_channel_config mhi_quectel_em1xx_channels[] = { |
| @@ -301,7 +323,8 @@ static const struct mhi_pci_dev_info mhi_quectel_em1xx_info = { · 35 unmodified lines | |||
| 301 | .edl = "qcom/prog_firehose_sdx24.mbn", | 323 | .edl = "qcom/prog_firehose_sdx24.mbn", |
| 302 | .config = &modem_quectel_em1xx_config, | 324 | .config = &modem_quectel_em1xx_config, |
| 303 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, | 325 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, |
| 304 | .dma_data_width = 32 | 326 | .dma_data_width = 32, |
| 327 | .sideband_wake = true, | ||
| 305 | }; | 328 | }; |
| 306 | 329 | ||
| 307 | static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = { | 330 | static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = { |
| @@ -339,7 +362,8 @@ static const struct mhi_pci_dev_info mhi_foxconn_sdx55_info = { · 31 unmodified lines | |||
| 339 | .edl = "qcom/sdx55m/edl.mbn", | 362 | .edl = "qcom/sdx55m/edl.mbn", |
| 340 | .config = &modem_foxconn_sdx55_config, | 363 | .config = &modem_foxconn_sdx55_config, |
| 341 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, | 364 | .bar_num = MHI_PCI_DEFAULT_BAR_NUM, |
| 342 | .dma_data_width = 32 | 365 | .dma_data_width = 32, |
| 366 | .sideband_wake = false, | ||
| 343 | }; | 367 | }; |
| 344 | 368 | ||
| 345 | static const struct pci_device_id mhi_pci_id_table[] = { | 369 | static const struct pci_device_id mhi_pci_id_table[] = { |
| @@ -640,9 +664,12 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 294 unmodified lines | |||
| 640 | mhi_cntrl->status_cb = mhi_pci_status_cb; | 664 | mhi_cntrl->status_cb = mhi_pci_status_cb; |
| 641 | mhi_cntrl->runtime_get = mhi_pci_runtime_get; | 665 | mhi_cntrl->runtime_get = mhi_pci_runtime_get; |
| 642 | mhi_cntrl->runtime_put = mhi_pci_runtime_put; | 666 | mhi_cntrl->runtime_put = mhi_pci_runtime_put; |
| 643 | mhi_cntrl->wake_get = mhi_pci_wake_get_nop; | 667 | |
| 644 | mhi_cntrl->wake_put = mhi_pci_wake_put_nop; | 668 | if (info->sideband_wake) { |
| 645 | mhi_cntrl->wake_toggle = mhi_pci_wake_toggle_nop; | 669 | mhi_cntrl->wake_get = mhi_pci_wake_get_nop; |
| 670 | mhi_cntrl->wake_put = mhi_pci_wake_put_nop; | ||
| 671 | mhi_cntrl->wake_toggle = mhi_pci_wake_toggle_nop; | ||
| 672 | } | ||
| 646 | 673 | ||
| 647 | err = mhi_pci_claim(mhi_cntrl, info->bar_num, DMA_BIT_MASK(info->dma_data_width)); | 674 | err = mhi_pci_claim(mhi_cntrl, info->bar_num, DMA_BIT_MASK(info->dma_data_width)); |
| 648 | if (err) | 675 | if (err) |
| @@ -34,7 +34,6 @@ static long __init parse_acpi_path(const struct efi_dev_path *node, · 33 unmodified lines | |||
| 34 | break; | 34 | break; |
| 35 | if (!adev->pnp.unique_id && node->acpi.uid == 0) | 35 | if (!adev->pnp.unique_id && node->acpi.uid == 0) |
| 36 | break; | 36 | break; |
| 37 | acpi_dev_put(adev); | ||
| 38 | } | 37 | } |
| 39 | if (!adev) | 38 | if (!adev) |
| 40 | return -ENODEV; | 39 | return -ENODEV; |
| @@ -896,6 +896,7 @@ static int __init efi_memreserve_map_root(void) · 895 unmodified lines | |||
| 896 | static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) | 896 | static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) |
| 897 | { | 897 | { |
| 898 | struct resource *res, *parent; | 898 | struct resource *res, *parent; |
| 899 | int ret; | ||
| 899 | 900 | ||
| 900 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); | 901 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); |
| 901 | if (!res) | 902 | if (!res) |
| @@ -908,7 +909,17 @@ static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) · 6 unmodified lines | |||
| 908 | 909 | ||
| 909 | /* we expect a conflict with a 'System RAM' region */ | 910 | /* we expect a conflict with a 'System RAM' region */ |
| 910 | parent = request_resource_conflict(&iomem_resource, res); | 911 | parent = request_resource_conflict(&iomem_resource, res); |
| 911 | return parent ? request_resource(parent, res) : 0; | 912 | ret = parent ? request_resource(parent, res) : 0; |
| 913 | |||
| 914 | /* | ||
| 915 | * Given that efi_mem_reserve_iomem() can be called at any | ||
| 916 | * time, only call memblock_reserve() if the architecture | ||
| 917 | * keeps the infrastructure around. | ||
| 918 | */ | ||
| 919 | if (IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK) && !ret) | ||
| 920 | memblock_reserve(addr, size); | ||
| 921 | |||
| 922 | return ret; | ||
| 912 | } | 923 | } |
| 913 | 924 | ||
| 914 | int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) | 925 | int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) |
| @@ -630,8 +630,8 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, · 629 unmodified lines | |||
| 630 | * @image: EFI loaded image protocol | 630 | * @image: EFI loaded image protocol |
| 631 | * @load_addr: pointer to loaded initrd | 631 | * @load_addr: pointer to loaded initrd |
| 632 | * @load_size: size of loaded initrd | 632 | * @load_size: size of loaded initrd |
| 633 | * @soft_limit: preferred size of allocated memory for loading the initrd | 633 | * @soft_limit: preferred address for loading the initrd |
| 634 | * @hard_limit: minimum size of allocated memory | 634 | * @hard_limit: upper limit address for loading the initrd |
| 635 | * | 635 | * |
| 636 | * Return: status code | 636 | * Return: status code |
| 637 | */ | 637 | */ |
| @@ -180,7 +180,10 @@ void __init efi_mokvar_table_init(void) · 179 unmodified lines | |||
| 180 | pr_err("EFI MOKvar config table is not valid\n"); | 180 | pr_err("EFI MOKvar config table is not valid\n"); |
| 181 | return; | 181 | return; |
| 182 | } | 182 | } |
| 183 | efi_mem_reserve(efi.mokvar_table, map_size_needed); | 183 | |
| 184 | if (md.type == EFI_BOOT_SERVICES_DATA) | ||
| 185 | efi_mem_reserve(efi.mokvar_table, map_size_needed); | ||
| 186 | |||
| 184 | efi_mokvar_table_size = map_size_needed; | 187 | efi_mokvar_table_size = map_size_needed; |
| 185 | } | 188 | } |
| 186 | 189 | ||
| @@ -62,9 +62,11 @@ int __init efi_tpm_eventlog_init(void) · 61 unmodified lines | |||
| 62 | tbl_size = sizeof(*log_tbl) + log_tbl->size; | 62 | tbl_size = sizeof(*log_tbl) + log_tbl->size; |
| 63 | memblock_reserve(efi.tpm_log, tbl_size); | 63 | memblock_reserve(efi.tpm_log, tbl_size); |
| 64 | 64 | ||
| 65 | if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || | 65 | if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) { |
| 66 | log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { | 66 | pr_info("TPM Final Events table not present\n"); |
| 67 | pr_warn(FW_BUG "TPM Final Events table missing or invalid\n"); | 67 | goto out; |
| 68 | } else if (log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { | ||
| 69 | pr_warn(FW_BUG "TPM Final Events table invalid\n"); | ||
| 68 | goto out; | 70 | goto out; |
| 69 | } | 71 | } |
| 70 | 72 | ||
| @@ -619,6 +619,13 @@ struct amdgpu_video_codec_info { · 618 unmodified lines | |||
| 619 | u32 max_level; | 619 | u32 max_level; |
| 620 | }; | 620 | }; |
| 621 | 621 | ||
| 622 | #define codec_info_build(type, width, height, level) \ | ||
| 623 | .codec_type = type,\ | ||
| 624 | .max_width = width,\ | ||
| 625 | .max_height = height,\ | ||
| 626 | .max_pixels_per_frame = height * width,\ | ||
| 627 | .max_level = level, | ||
| 628 | |||
| 622 | struct amdgpu_video_codecs { | 629 | struct amdgpu_video_codecs { |
| 623 | const u32 codec_count; | 630 | const u32 codec_count; |
| 624 | const struct amdgpu_video_codec_info *codec_array; | 631 | const struct amdgpu_video_codec_info *codec_array; |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/power_supply.h> | 27 | #include <linux/power_supply.h> |
| 28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
| 29 | #include <linux/suspend.h> | ||
| 29 | #include <acpi/video.h> | 30 | #include <acpi/video.h> |
| 30 | #include <acpi/actbl.h> | 31 | #include <acpi/actbl.h> |
| 31 | 32 | ||
| @@ -1042,7 +1043,7 @@ bool amdgpu_acpi_is_s0ix_supported(struct amdgpu_device *adev) · 1010 unmodified lines | |||
| 1042 | #if defined(CONFIG_AMD_PMC) || defined(CONFIG_AMD_PMC_MODULE) | 1043 | #if defined(CONFIG_AMD_PMC) || defined(CONFIG_AMD_PMC_MODULE) |
| 1043 | if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) { | 1044 | if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) { |
| 1044 | if (adev->flags & AMD_IS_APU) | 1045 | if (adev->flags & AMD_IS_APU) |
| 1045 | return true; | 1046 | return pm_suspend_target_state == PM_SUSPEND_TO_IDLE; |
| 1046 | } | 1047 | } |
| 1047 | #endif | 1048 | #endif |
| 1048 | return false; | 1049 | return false; |
| @@ -3504,13 +3504,13 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 3503 unmodified lines | |||
| 3504 | r = amdgpu_device_get_job_timeout_settings(adev); | 3504 | r = amdgpu_device_get_job_timeout_settings(adev); |
| 3505 | if (r) { | 3505 | if (r) { |
| 3506 | dev_err(adev->dev, "invalid lockup_timeout parameter syntax\n"); | 3506 | dev_err(adev->dev, "invalid lockup_timeout parameter syntax\n"); |
| 3507 | goto failed_unmap; | 3507 | return r; |
| 3508 | } | 3508 | } |
| 3509 | 3509 | ||
| 3510 | /* early init functions */ | 3510 | /* early init functions */ |
| 3511 | r = amdgpu_device_ip_early_init(adev); | 3511 | r = amdgpu_device_ip_early_init(adev); |
| 3512 | if (r) | 3512 | if (r) |
| 3513 | goto failed_unmap; | 3513 | return r; |
| 3514 | 3514 | ||
| 3515 | /* doorbell bar mapping and doorbell index init*/ | 3515 | /* doorbell bar mapping and doorbell index init*/ |
| 3516 | amdgpu_device_doorbell_init(adev); | 3516 | amdgpu_device_doorbell_init(adev); |
| @@ -3736,10 +3736,6 @@ release_ras_con: · 219 unmodified lines | |||
| 3736 | failed: | 3736 | failed: |
| 3737 | amdgpu_vf_error_trans_all(adev); | 3737 | amdgpu_vf_error_trans_all(adev); |
| 3738 | 3738 | ||
| 3739 | failed_unmap: | ||
| 3740 | iounmap(adev->rmmio); | ||
| 3741 | adev->rmmio = NULL; | ||
| 3742 | |||
| 3743 | return r; | 3739 | return r; |
| 3744 | } | 3740 | } |
| 3745 | 3741 | ||
| @@ -1190,6 +1190,10 @@ static const struct pci_device_id pciidlist[] = { · 1189 unmodified lines | |||
| 1190 | /* Van Gogh */ | 1190 | /* Van Gogh */ |
| 1191 | {0x1002, 0x163F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VANGOGH|AMD_IS_APU}, | 1191 | {0x1002, 0x163F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VANGOGH|AMD_IS_APU}, |
| 1192 | 1192 | ||
| 1193 | /* Yellow Carp */ | ||
| 1194 | {0x1002, 0x164D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_YELLOW_CARP|AMD_IS_APU}, | ||
| 1195 | {0x1002, 0x1681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_YELLOW_CARP|AMD_IS_APU}, | ||
| 1196 | |||
| 1193 | /* Navy_Flounder */ | 1197 | /* Navy_Flounder */ |
| 1194 | {0x1002, 0x73C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVY_FLOUNDER}, | 1198 | {0x1002, 0x73C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVY_FLOUNDER}, |
| 1195 | {0x1002, 0x73C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVY_FLOUNDER}, | 1199 | {0x1002, 0x73C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVY_FLOUNDER}, |
| @@ -255,6 +255,15 @@ static int amdgpu_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_str · 254 unmodified lines | |||
| 255 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) | 255 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) |
| 256 | return -EPERM; | 256 | return -EPERM; |
| 257 | 257 | ||
| 258 | /* Workaround for Thunk bug creating PROT_NONE,MAP_PRIVATE mappings | ||
| 259 | * for debugger access to invisible VRAM. Should have used MAP_SHARED | ||
| 260 | * instead. Clearing VM_MAYWRITE prevents the mapping from ever | ||
| 261 | * becoming writable and makes is_cow_mapping(vm_flags) false. | ||
| 262 | */ | ||
| 263 | if (is_cow_mapping(vma->vm_flags) && | ||
| 264 | !(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) | ||
| 265 | vma->vm_flags &= ~VM_MAYWRITE; | ||
| 266 | |||
| 258 | return drm_gem_ttm_mmap(obj, vma); | 267 | return drm_gem_ttm_mmap(obj, vma); |
| 259 | } | 268 | } |
| 260 | 269 | ||
| @@ -3300,6 +3300,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_3[] = · 3299 unmodified lines | |||
| 3300 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000), | 3300 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000), |
| 3301 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000), | 3301 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000), |
| 3302 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), | 3302 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), |
| 3303 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSX_DEBUG_1, 0x00010000, 0x00010020), | ||
| 3303 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), | 3304 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), |
| 3304 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffbfffff, 0x00a00000) | 3305 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffbfffff, 0x00a00000) |
| 3305 | }; | 3306 | }; |
| @@ -3379,6 +3380,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_3_vangogh[] = · 73 unmodified lines | |||
| 3379 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0xffffffbf, 0x00000020), | 3380 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0xffffffbf, 0x00000020), |
| 3380 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1_Vangogh, 0xffffffff, 0x00070103), | 3381 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1_Vangogh, 0xffffffff, 0x00070103), |
| 3381 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQG_CONFIG, 0x000017ff, 0x00001000), | 3382 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQG_CONFIG, 0x000017ff, 0x00001000), |
| 3383 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSX_DEBUG_1, 0x00010000, 0x00010020), | ||
| 3382 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), | 3384 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), |
| 3383 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00400000), | 3385 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00400000), |
| 3384 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000000ff), | 3386 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000000ff), |
| @@ -3445,6 +3447,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_3_4[] = · 60 unmodified lines | |||
| 3445 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000), | 3447 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000), |
| 3446 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000), | 3448 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000), |
| 3447 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), | 3449 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), |
| 3450 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSX_DEBUG_1, 0x00010000, 0x00010020), | ||
| 3448 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0x01030000, 0x01030000), | 3451 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0x01030000, 0x01030000), |
| 3449 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0x03a00000, 0x00a00000), | 3452 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0x03a00000, 0x00a00000), |
| 3450 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmLDS_CONFIG, 0x00000020, 0x00000020) | 3453 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmLDS_CONFIG, 0x00000020, 0x00000020) |
| @@ -64,32 +64,13 @@ · 63 unmodified lines | |||
| 64 | #include "smuio_v11_0.h" | 64 | #include "smuio_v11_0.h" |
| 65 | #include "smuio_v11_0_6.h" | 65 | #include "smuio_v11_0_6.h" |
| 66 | 66 | ||
| 67 | #define codec_info_build(type, width, height, level) \ | ||
| 68 | .codec_type = type,\ | ||
| 69 | .max_width = width,\ | ||
| 70 | .max_height = height,\ | ||
| 71 | .max_pixels_per_frame = height * width,\ | ||
| 72 | .max_level = level, | ||
| 73 | |||
| 74 | static const struct amd_ip_funcs nv_common_ip_funcs; | 67 | static const struct amd_ip_funcs nv_common_ip_funcs; |
| 75 | 68 | ||
| 76 | /* Navi */ | 69 | /* Navi */ |
| 77 | static const struct amdgpu_video_codec_info nv_video_codecs_encode_array[] = | 70 | static const struct amdgpu_video_codec_info nv_video_codecs_encode_array[] = |
| 78 | { | 71 | { |
| 79 | { | 72 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, |
| 80 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | 73 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, |
| 81 | .max_width = 4096, | ||
| 82 | .max_height = 2304, | ||
| 83 | .max_pixels_per_frame = 4096 * 2304, | ||
| 84 | .max_level = 0, | ||
| 85 | }, | ||
| 86 | { | ||
| 87 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 88 | .max_width = 4096, | ||
| 89 | .max_height = 2304, | ||
| 90 | .max_pixels_per_frame = 4096 * 2304, | ||
| 91 | .max_level = 0, | ||
| 92 | }, | ||
| 93 | }; | 74 | }; |
| 94 | 75 | ||
| 95 | static const struct amdgpu_video_codecs nv_video_codecs_encode = | 76 | static const struct amdgpu_video_codecs nv_video_codecs_encode = |
| @@ -101,55 +82,13 @@ static const struct amdgpu_video_codecs nv_video_codecs_encode = · 5 unmodified lines | |||
| 101 | /* Navi1x */ | 82 | /* Navi1x */ |
| 102 | static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] = | 83 | static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] = |
| 103 | { | 84 | { |
| 104 | { | 85 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, |
| 105 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | 86 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, |
| 106 | .max_width = 4096, | 87 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, |
| 107 | .max_height = 4096, | 88 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, |
| 108 | .max_pixels_per_frame = 4096 * 4096, | 89 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, |
| 109 | .max_level = 3, | 90 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, |
| 110 | }, | 91 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, |
| 111 | { | ||
| 112 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, | ||
| 113 | .max_width = 4096, | ||
| 114 | .max_height = 4096, | ||
| 115 | .max_pixels_per_frame = 4096 * 4096, | ||
| 116 | .max_level = 5, | ||
| 117 | }, | ||
| 118 | { | ||
| 119 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | ||
| 120 | .max_width = 4096, | ||
| 121 | .max_height = 4096, | ||
| 122 | .max_pixels_per_frame = 4096 * 4096, | ||
| 123 | .max_level = 52, | ||
| 124 | }, | ||
| 125 | { | ||
| 126 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, | ||
| 127 | .max_width = 4096, | ||
| 128 | .max_height = 4096, | ||
| 129 | .max_pixels_per_frame = 4096 * 4096, | ||
| 130 | .max_level = 4, | ||
| 131 | }, | ||
| 132 | { | ||
| 133 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 134 | .max_width = 8192, | ||
| 135 | .max_height = 4352, | ||
| 136 | .max_pixels_per_frame = 8192 * 4352, | ||
| 137 | .max_level = 186, | ||
| 138 | }, | ||
| 139 | { | ||
| 140 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, | ||
| 141 | .max_width = 4096, | ||
| 142 | .max_height = 4096, | ||
| 143 | .max_pixels_per_frame = 4096 * 4096, | ||
| 144 | .max_level = 0, | ||
| 145 | }, | ||
| 146 | { | ||
| 147 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, | ||
| 148 | .max_width = 8192, | ||
| 149 | .max_height = 4352, | ||
| 150 | .max_pixels_per_frame = 8192 * 4352, | ||
| 151 | .max_level = 0, | ||
| 152 | }, | ||
| 153 | }; | 92 | }; |
| 154 | 93 | ||
| 155 | static const struct amdgpu_video_codecs nv_video_codecs_decode = | 94 | static const struct amdgpu_video_codecs nv_video_codecs_decode = |
| @@ -161,62 +100,14 @@ static const struct amdgpu_video_codecs nv_video_codecs_decode = · 5 unmodified lines | |||
| 161 | /* Sienna Cichlid */ | 100 | /* Sienna Cichlid */ |
| 162 | static const struct amdgpu_video_codec_info sc_video_codecs_decode_array[] = | 101 | static const struct amdgpu_video_codec_info sc_video_codecs_decode_array[] = |
| 163 | { | 102 | { |
| 164 | { | 103 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, |
| 165 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | 104 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, |
| 166 | .max_width = 4096, | 105 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, |
| 167 | .max_height = 4096, | 106 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, |
| 168 | .max_pixels_per_frame = 4096 * 4096, | 107 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, |
| 169 | .max_level = 3, | 108 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, |
| 170 | }, | 109 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, |
| 171 | { | 110 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, |
| 172 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, | ||
| 173 | .max_width = 4096, | ||
| 174 | .max_height = 4096, | ||
| 175 | .max_pixels_per_frame = 4096 * 4096, | ||
| 176 | .max_level = 5, | ||
| 177 | }, | ||
| 178 | { | ||
| 179 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | ||
| 180 | .max_width = 4096, | ||
| 181 | .max_height = 4096, | ||
| 182 | .max_pixels_per_frame = 4096 * 4096, | ||
| 183 | .max_level = 52, | ||
| 184 | }, | ||
| 185 | { | ||
| 186 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, | ||
| 187 | .max_width = 4096, | ||
| 188 | .max_height = 4096, | ||
| 189 | .max_pixels_per_frame = 4096 * 4096, | ||
| 190 | .max_level = 4, | ||
| 191 | }, | ||
| 192 | { | ||
| 193 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 194 | .max_width = 8192, | ||
| 195 | .max_height = 4352, | ||
| 196 | .max_pixels_per_frame = 8192 * 4352, | ||
| 197 | .max_level = 186, | ||
| 198 | }, | ||
| 199 | { | ||
| 200 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, | ||
| 201 | .max_width = 4096, | ||
| 202 | .max_height = 4096, | ||
| 203 | .max_pixels_per_frame = 4096 * 4096, | ||
| 204 | .max_level = 0, | ||
| 205 | }, | ||
| 206 | { | ||
| 207 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, | ||
| 208 | .max_width = 8192, | ||
| 209 | .max_height = 4352, | ||
| 210 | .max_pixels_per_frame = 8192 * 4352, | ||
| 211 | .max_level = 0, | ||
| 212 | }, | ||
| 213 | { | ||
| 214 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, | ||
| 215 | .max_width = 8192, | ||
| 216 | .max_height = 4352, | ||
| 217 | .max_pixels_per_frame = 8192 * 4352, | ||
| 218 | .max_level = 0, | ||
| 219 | }, | ||
| 220 | }; | 111 | }; |
| 221 | 112 | ||
| 222 | static const struct amdgpu_video_codecs sc_video_codecs_decode = | 113 | static const struct amdgpu_video_codecs sc_video_codecs_decode = |
| @@ -228,80 +119,20 @@ static const struct amdgpu_video_codecs sc_video_codecs_decode = · 5 unmodified lines | |||
| 228 | /* SRIOV Sienna Cichlid, not const since data is controlled by host */ | 119 | /* SRIOV Sienna Cichlid, not const since data is controlled by host */ |
| 229 | static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = | 120 | static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = |
| 230 | { | 121 | { |
| 231 | { | 122 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, |
| 232 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | 123 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, |
| 233 | .max_width = 4096, | ||
| 234 | .max_height = 2304, | ||
| 235 | .max_pixels_per_frame = 4096 * 2304, | ||
| 236 | .max_level = 0, | ||
| 237 | }, | ||
| 238 | { | ||
| 239 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 240 | .max_width = 4096, | ||
| 241 | .max_height = 2304, | ||
| 242 | .max_pixels_per_frame = 4096 * 2304, | ||
| 243 | .max_level = 0, | ||
| 244 | }, | ||
| 245 | }; | 124 | }; |
| 246 | 125 | ||
| 247 | static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array[] = | 126 | static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array[] = |
| 248 | { | 127 | { |
| 249 | { | 128 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, |
| 250 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | 129 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, |
| 251 | .max_width = 4096, | 130 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, |
| 252 | .max_height = 4096, | 131 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, |
| 253 | .max_pixels_per_frame = 4096 * 4096, | 132 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, |
| 254 | .max_level = 3, | 133 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, |
| 255 | }, | 134 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, |
| 256 | { | 135 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, |
| 257 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, | ||
| 258 | .max_width = 4096, | ||
| 259 | .max_height = 4096, | ||
| 260 | .max_pixels_per_frame = 4096 * 4096, | ||
| 261 | .max_level = 5, | ||
| 262 | }, | ||
| 263 | { | ||
| 264 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | ||
| 265 | .max_width = 4096, | ||
| 266 | .max_height = 4096, | ||
| 267 | .max_pixels_per_frame = 4096 * 4096, | ||
| 268 | .max_level = 52, | ||
| 269 | }, | ||
| 270 | { | ||
| 271 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, | ||
| 272 | .max_width = 4096, | ||
| 273 | .max_height = 4096, | ||
| 274 | .max_pixels_per_frame = 4096 * 4096, | ||
| 275 | .max_level = 4, | ||
| 276 | }, | ||
| 277 | { | ||
| 278 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 279 | .max_width = 8192, | ||
| 280 | .max_height = 4352, | ||
| 281 | .max_pixels_per_frame = 8192 * 4352, | ||
| 282 | .max_level = 186, | ||
| 283 | }, | ||
| 284 | { | ||
| 285 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, | ||
| 286 | .max_width = 4096, | ||
| 287 | .max_height = 4096, | ||
| 288 | .max_pixels_per_frame = 4096 * 4096, | ||
| 289 | .max_level = 0, | ||
| 290 | }, | ||
| 291 | { | ||
| 292 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, | ||
| 293 | .max_width = 8192, | ||
| 294 | .max_height = 4352, | ||
| 295 | .max_pixels_per_frame = 8192 * 4352, | ||
| 296 | .max_level = 0, | ||
| 297 | }, | ||
| 298 | { | ||
| 299 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, | ||
| 300 | .max_width = 8192, | ||
| 301 | .max_height = 4352, | ||
| 302 | .max_pixels_per_frame = 8192 * 4352, | ||
| 303 | .max_level = 0, | ||
| 304 | }, | ||
| 305 | }; | 136 | }; |
| 306 | 137 | ||
| 307 | static struct amdgpu_video_codecs sriov_sc_video_codecs_encode = | 138 | static struct amdgpu_video_codecs sriov_sc_video_codecs_encode = |
| @@ -333,6 +164,19 @@ static const struct amdgpu_video_codecs bg_video_codecs_encode = { · 25 unmodified lines | |||
| 333 | .codec_array = NULL, | 164 | .codec_array = NULL, |
| 334 | }; | 165 | }; |
| 335 | 166 | ||
| 167 | /* Yellow Carp*/ | ||
| 168 | static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = { | ||
| 169 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, | ||
| 170 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, | ||
| 171 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, | ||
| 172 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | ||
| 173 | }; | ||
| 174 | |||
| 175 | static const struct amdgpu_video_codecs yc_video_codecs_decode = { | ||
| 176 | .codec_count = ARRAY_SIZE(yc_video_codecs_decode_array), | ||
| 177 | .codec_array = yc_video_codecs_decode_array, | ||
| 178 | }; | ||
| 179 | |||
| 336 | static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, | 180 | static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, |
| 337 | const struct amdgpu_video_codecs **codecs) | 181 | const struct amdgpu_video_codecs **codecs) |
| 338 | { | 182 | { |
| @@ -353,12 +197,17 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, · 14 unmodified lines | |||
| 353 | case CHIP_NAVY_FLOUNDER: | 197 | case CHIP_NAVY_FLOUNDER: |
| 354 | case CHIP_DIMGREY_CAVEFISH: | 198 | case CHIP_DIMGREY_CAVEFISH: |
| 355 | case CHIP_VANGOGH: | 199 | case CHIP_VANGOGH: |
| 356 | case CHIP_YELLOW_CARP: | ||
| 357 | if (encode) | 200 | if (encode) |
| 358 | *codecs = &nv_video_codecs_encode; | 201 | *codecs = &nv_video_codecs_encode; |
| 359 | else | 202 | else |
| 360 | *codecs = &sc_video_codecs_decode; | 203 | *codecs = &sc_video_codecs_decode; |
| 361 | return 0; | 204 | return 0; |
| 205 | case CHIP_YELLOW_CARP: | ||
| 206 | if (encode) | ||
| 207 | *codecs = &nv_video_codecs_encode; | ||
| 208 | else | ||
| 209 | *codecs = &yc_video_codecs_decode; | ||
| 210 | return 0; | ||
| 362 | case CHIP_BEIGE_GOBY: | 211 | case CHIP_BEIGE_GOBY: |
| 363 | if (encode) | 212 | if (encode) |
| 364 | *codecs = &bg_video_codecs_encode; | 213 | *codecs = &bg_video_codecs_encode; |
| @@ -1387,7 +1236,10 @@ static int nv_common_early_init(void *handle) · 1022 unmodified lines | |||
| 1387 | AMD_PG_SUPPORT_VCN | | 1236 | AMD_PG_SUPPORT_VCN | |
| 1388 | AMD_PG_SUPPORT_VCN_DPG | | 1237 | AMD_PG_SUPPORT_VCN_DPG | |
| 1389 | AMD_PG_SUPPORT_JPEG; | 1238 | AMD_PG_SUPPORT_JPEG; |
| 1390 | adev->external_rev_id = adev->rev_id + 0x01; | 1239 | if (adev->pdev->device == 0x1681) |
| 1240 | adev->external_rev_id = adev->rev_id + 0x19; | ||
| 1241 | else | ||
| 1242 | adev->external_rev_id = adev->rev_id + 0x01; | ||
| 1391 | break; | 1243 | break; |
| 1392 | default: | 1244 | default: |
| 1393 | /* FIXME: not supported yet */ | 1245 | /* FIXME: not supported yet */ |
| @@ -67,7 +67,7 @@ static int psp_v12_0_init_microcode(struct psp_context *psp) · 66 unmodified lines | |||
| 67 | 67 | ||
| 68 | err = psp_init_asd_microcode(psp, chip_name); | 68 | err = psp_init_asd_microcode(psp, chip_name); |
| 69 | if (err) | 69 | if (err) |
| 70 | goto out; | 70 | return err; |
| 71 | 71 | ||
| 72 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); | 72 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); |
| 73 | err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); | 73 | err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); |
| @@ -80,7 +80,7 @@ static int psp_v12_0_init_microcode(struct psp_context *psp) · 6 unmodified lines | |||
| 80 | } else { | 80 | } else { |
| 81 | err = amdgpu_ucode_validate(adev->psp.ta_fw); | 81 | err = amdgpu_ucode_validate(adev->psp.ta_fw); |
| 82 | if (err) | 82 | if (err) |
| 83 | goto out2; | 83 | goto out; |
| 84 | 84 | ||
| 85 | ta_hdr = (const struct ta_firmware_header_v1_0 *) | 85 | ta_hdr = (const struct ta_firmware_header_v1_0 *) |
| 86 | adev->psp.ta_fw->data; | 86 | adev->psp.ta_fw->data; |
| @@ -105,10 +105,9 @@ static int psp_v12_0_init_microcode(struct psp_context *psp) · 18 unmodified lines | |||
| 105 | 105 | ||
| 106 | return 0; | 106 | return 0; |
| 107 | 107 | ||
| 108 | out2: | 108 | out: |
| 109 | release_firmware(adev->psp.ta_fw); | 109 | release_firmware(adev->psp.ta_fw); |
| 110 | adev->psp.ta_fw = NULL; | 110 | adev->psp.ta_fw = NULL; |
| 111 | out: | ||
| 112 | if (err) { | 111 | if (err) { |
| 113 | dev_err(adev->dev, | 112 | dev_err(adev->dev, |
| 114 | "psp v12.0: Failed to load firmware \"%s\"\n", | 113 | "psp v12.0: Failed to load firmware \"%s\"\n", |
| @@ -88,20 +88,8 @@ · 87 unmodified lines | |||
| 88 | /* Vega, Raven, Arcturus */ | 88 | /* Vega, Raven, Arcturus */ |
| 89 | static const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] = | 89 | static const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] = |
| 90 | { | 90 | { |
| 91 | { | 91 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, |
| 92 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | 92 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, |
| 93 | .max_width = 4096, | ||
| 94 | .max_height = 2304, | ||
| 95 | .max_pixels_per_frame = 4096 * 2304, | ||
| 96 | .max_level = 0, | ||
| 97 | }, | ||
| 98 | { | ||
| 99 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 100 | .max_width = 4096, | ||
| 101 | .max_height = 2304, | ||
| 102 | .max_pixels_per_frame = 4096 * 2304, | ||
| 103 | .max_level = 0, | ||
| 104 | }, | ||
| 105 | }; | 93 | }; |
| 106 | 94 | ||
| 107 | static const struct amdgpu_video_codecs vega_video_codecs_encode = | 95 | static const struct amdgpu_video_codecs vega_video_codecs_encode = |
| @@ -113,48 +101,12 @@ static const struct amdgpu_video_codecs vega_video_codecs_encode = · 5 unmodified lines | |||
| 113 | /* Vega */ | 101 | /* Vega */ |
| 114 | static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] = | 102 | static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] = |
| 115 | { | 103 | { |
| 116 | { | 104 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, |
| 117 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | 105 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, |
| 118 | .max_width = 4096, | 106 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, |
| 119 | .max_height = 4096, | 107 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, |
| 120 | .max_pixels_per_frame = 4096 * 4096, | 108 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, |
| 121 | .max_level = 3, | 109 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, |
| 122 | }, | ||
| 123 | { | ||
| 124 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, | ||
| 125 | .max_width = 4096, | ||
| 126 | .max_height = 4096, | ||
| 127 | .max_pixels_per_frame = 4096 * 4096, | ||
| 128 | .max_level = 5, | ||
| 129 | }, | ||
| 130 | { | ||
| 131 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | ||
| 132 | .max_width = 4096, | ||
| 133 | .max_height = 4096, | ||
| 134 | .max_pixels_per_frame = 4096 * 4096, | ||
| 135 | .max_level = 52, | ||
| 136 | }, | ||
| 137 | { | ||
| 138 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, | ||
| 139 | .max_width = 4096, | ||
| 140 | .max_height = 4096, | ||
| 141 | .max_pixels_per_frame = 4096 * 4096, | ||
| 142 | .max_level = 4, | ||
| 143 | }, | ||
| 144 | { | ||
| 145 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 146 | .max_width = 4096, | ||
| 147 | .max_height = 4096, | ||
| 148 | .max_pixels_per_frame = 4096 * 4096, | ||
| 149 | .max_level = 186, | ||
| 150 | }, | ||
| 151 | { | ||
| 152 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, | ||
| 153 | .max_width = 4096, | ||
| 154 | .max_height = 4096, | ||
| 155 | .max_pixels_per_frame = 4096 * 4096, | ||
| 156 | .max_level = 0, | ||
| 157 | }, | ||
| 158 | }; | 110 | }; |
| 159 | 111 | ||
| 160 | static const struct amdgpu_video_codecs vega_video_codecs_decode = | 112 | static const struct amdgpu_video_codecs vega_video_codecs_decode = |
| @@ -166,55 +118,13 @@ static const struct amdgpu_video_codecs vega_video_codecs_decode = · 5 unmodified lines | |||
| 166 | /* Raven */ | 118 | /* Raven */ |
| 167 | static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] = | 119 | static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] = |
| 168 | { | 120 | { |
| 169 | { | 121 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, |
| 170 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | 122 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, |
| 171 | .max_width = 4096, | 123 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, |
| 172 | .max_height = 4096, | 124 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, |
| 173 | .max_pixels_per_frame = 4096 * 4096, | 125 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, |
| 174 | .max_level = 3, | 126 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, |
| 175 | }, | 127 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)}, |
| 176 | { | ||
| 177 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, | ||
| 178 | .max_width = 4096, | ||
| 179 | .max_height = 4096, | ||
| 180 | .max_pixels_per_frame = 4096 * 4096, | ||
| 181 | .max_level = 5, | ||
| 182 | }, | ||
| 183 | { | ||
| 184 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | ||
| 185 | .max_width = 4096, | ||
| 186 | .max_height = 4096, | ||
| 187 | .max_pixels_per_frame = 4096 * 4096, | ||
| 188 | .max_level = 52, | ||
| 189 | }, | ||
| 190 | { | ||
| 191 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, | ||
| 192 | .max_width = 4096, | ||
| 193 | .max_height = 4096, | ||
| 194 | .max_pixels_per_frame = 4096 * 4096, | ||
| 195 | .max_level = 4, | ||
| 196 | }, | ||
| 197 | { | ||
| 198 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 199 | .max_width = 4096, | ||
| 200 | .max_height = 4096, | ||
| 201 | .max_pixels_per_frame = 4096 * 4096, | ||
| 202 | .max_level = 186, | ||
| 203 | }, | ||
| 204 | { | ||
| 205 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, | ||
| 206 | .max_width = 4096, | ||
| 207 | .max_height = 4096, | ||
| 208 | .max_pixels_per_frame = 4096 * 4096, | ||
| 209 | .max_level = 0, | ||
| 210 | }, | ||
| 211 | { | ||
| 212 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, | ||
| 213 | .max_width = 4096, | ||
| 214 | .max_height = 4096, | ||
| 215 | .max_pixels_per_frame = 4096 * 4096, | ||
| 216 | .max_level = 0, | ||
| 217 | }, | ||
| 218 | }; | 128 | }; |
| 219 | 129 | ||
| 220 | static const struct amdgpu_video_codecs rv_video_codecs_decode = | 130 | static const struct amdgpu_video_codecs rv_video_codecs_decode = |
| @@ -226,55 +136,13 @@ static const struct amdgpu_video_codecs rv_video_codecs_decode = · 5 unmodified lines | |||
| 226 | /* Renoir, Arcturus */ | 136 | /* Renoir, Arcturus */ |
| 227 | static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] = | 137 | static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] = |
| 228 | { | 138 | { |
| 229 | { | 139 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, |
| 230 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | 140 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, |
| 231 | .max_width = 4096, | 141 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, |
| 232 | .max_height = 4096, | 142 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, |
| 233 | .max_pixels_per_frame = 4096 * 4096, | 143 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, |
| 234 | .max_level = 3, | 144 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, |
| 235 | }, | 145 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, |
| 236 | { | ||
| 237 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, | ||
| 238 | .max_width = 4096, | ||
| 239 | .max_height = 4096, | ||
| 240 | .max_pixels_per_frame = 4096 * 4096, | ||
| 241 | .max_level = 5, | ||
| 242 | }, | ||
| 243 | { | ||
| 244 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | ||
| 245 | .max_width = 4096, | ||
| 246 | .max_height = 4096, | ||
| 247 | .max_pixels_per_frame = 4096 * 4096, | ||
| 248 | .max_level = 52, | ||
| 249 | }, | ||
| 250 | { | ||
| 251 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, | ||
| 252 | .max_width = 4096, | ||
| 253 | .max_height = 4096, | ||
| 254 | .max_pixels_per_frame = 4096 * 4096, | ||
| 255 | .max_level = 4, | ||
| 256 | }, | ||
| 257 | { | ||
| 258 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, | ||
| 259 | .max_width = 8192, | ||
| 260 | .max_height = 4352, | ||
| 261 | .max_pixels_per_frame = 4096 * 4096, | ||
| 262 | .max_level = 186, | ||
| 263 | }, | ||
| 264 | { | ||
| 265 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, | ||
| 266 | .max_width = 4096, | ||
| 267 | .max_height = 4096, | ||
| 268 | .max_pixels_per_frame = 4096 * 4096, | ||
| 269 | .max_level = 0, | ||
| 270 | }, | ||
| 271 | { | ||
| 272 | .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, | ||
| 273 | .max_width = 8192, | ||
| 274 | .max_height = 4352, | ||
| 275 | .max_pixels_per_frame = 4096 * 4096, | ||
| 276 | .max_level = 0, | ||
| 277 | }, | ||
| 278 | }; | 146 | }; |
| 279 | 147 | ||
| 280 | static const struct amdgpu_video_codecs rn_video_codecs_decode = | 148 | static const struct amdgpu_video_codecs rn_video_codecs_decode = |
| @@ -2429,9 +2429,9 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) · 2428 unmodified lines | |||
| 2429 | max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll; | 2429 | max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll; |
| 2430 | min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll; | 2430 | min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll; |
| 2431 | 2431 | ||
| 2432 | if (caps->ext_caps->bits.oled == 1 || | 2432 | if (caps->ext_caps->bits.oled == 1 /*|| |
| 2433 | caps->ext_caps->bits.sdr_aux_backlight_control == 1 || | 2433 | caps->ext_caps->bits.sdr_aux_backlight_control == 1 || |
| 2434 | caps->ext_caps->bits.hdr_aux_backlight_control == 1) | 2434 | caps->ext_caps->bits.hdr_aux_backlight_control == 1*/) |
| 2435 | caps->aux_support = true; | 2435 | caps->aux_support = true; |
| 2436 | 2436 | ||
| 2437 | if (amdgpu_backlight == 0) | 2437 | if (amdgpu_backlight == 0) |
| @@ -197,7 +197,7 @@ void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr, struct · 196 unmodified lines | |||
| 197 | 197 | ||
| 198 | REG_UPDATE(DENTIST_DISPCLK_CNTL, | 198 | REG_UPDATE(DENTIST_DISPCLK_CNTL, |
| 199 | DENTIST_DISPCLK_WDIVIDER, dispclk_wdivider); | 199 | DENTIST_DISPCLK_WDIVIDER, dispclk_wdivider); |
| 200 | // REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 5, 100); | 200 | REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 1000); |
| 201 | REG_UPDATE(DENTIST_DISPCLK_CNTL, | 201 | REG_UPDATE(DENTIST_DISPCLK_CNTL, |
| 202 | DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider); | 202 | DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider); |
| 203 | REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, 1, 5, 100); | 203 | REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, 1, 5, 100); |
| @@ -190,6 +190,10 @@ void dcn3_init_clocks(struct clk_mgr *clk_mgr_base) · 189 unmodified lines | |||
| 190 | &clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz, | 190 | &clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz, |
| 191 | &num_levels); | 191 | &num_levels); |
| 192 | 192 | ||
| 193 | /* SOCCLK */ | ||
| 194 | dcn3_init_single_clock(clk_mgr, PPCLK_SOCCLK, | ||
| 195 | &clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz, | ||
| 196 | &num_levels); | ||
| 193 | // DPREFCLK ??? | 197 | // DPREFCLK ??? |
| 194 | 198 | ||
| 195 | /* DISPCLK */ | 199 | /* DISPCLK */ |
| @@ -48,6 +48,21 @@ · 47 unmodified lines | |||
| 48 | 48 | ||
| 49 | #include "dc_dmub_srv.h" | 49 | #include "dc_dmub_srv.h" |
| 50 | 50 | ||
| 51 | #include "yellow_carp_offset.h" | ||
| 52 | |||
| 53 | #define regCLK1_CLK_PLL_REQ 0x0237 | ||
| 54 | #define regCLK1_CLK_PLL_REQ_BASE_IDX 0 | ||
| 55 | |||
| 56 | #define CLK1_CLK_PLL_REQ__FbMult_int__SHIFT 0x0 | ||
| 57 | #define CLK1_CLK_PLL_REQ__PllSpineDiv__SHIFT 0xc | ||
| 58 | #define CLK1_CLK_PLL_REQ__FbMult_frac__SHIFT 0x10 | ||
| 59 | #define CLK1_CLK_PLL_REQ__FbMult_int_MASK 0x000001FFL | ||
| 60 | #define CLK1_CLK_PLL_REQ__PllSpineDiv_MASK 0x0000F000L | ||
| 61 | #define CLK1_CLK_PLL_REQ__FbMult_frac_MASK 0xFFFF0000L | ||
| 62 | |||
| 63 | #define REG(reg_name) \ | ||
| 64 | (CLK_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name) | ||
| 65 | |||
| 51 | #define TO_CLK_MGR_DCN31(clk_mgr)\ | 66 | #define TO_CLK_MGR_DCN31(clk_mgr)\ |
| 52 | container_of(clk_mgr, struct clk_mgr_dcn31, base) | 67 | container_of(clk_mgr, struct clk_mgr_dcn31, base) |
| 53 | 68 | ||
| @@ -124,10 +139,10 @@ static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, · 70 unmodified lines | |||
| 124 | * also if safe to lower is false, we just go in the higher state | 139 | * also if safe to lower is false, we just go in the higher state |
| 125 | */ | 140 | */ |
| 126 | if (safe_to_lower) { | 141 | if (safe_to_lower) { |
| 127 | if (new_clocks->z9_support == DCN_Z9_SUPPORT_ALLOW && | 142 | if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_ALLOW && |
| 128 | new_clocks->z9_support != clk_mgr_base->clks.z9_support) { | 143 | new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) { |
| 129 | dcn31_smu_set_Z9_support(clk_mgr, true); | 144 | dcn31_smu_set_Z9_support(clk_mgr, true); |
| 130 | clk_mgr_base->clks.z9_support = new_clocks->z9_support; | 145 | clk_mgr_base->clks.zstate_support = new_clocks->zstate_support; |
| 131 | } | 146 | } |
| 132 | 147 | ||
| 133 | if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) { | 148 | if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) { |
| @@ -148,10 +163,10 @@ static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, · 14 unmodified lines | |||
| 148 | } | 163 | } |
| 149 | } | 164 | } |
| 150 | } else { | 165 | } else { |
| 151 | if (new_clocks->z9_support == DCN_Z9_SUPPORT_DISALLOW && | 166 | if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_DISALLOW && |
| 152 | new_clocks->z9_support != clk_mgr_base->clks.z9_support) { | 167 | new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) { |
| 153 | dcn31_smu_set_Z9_support(clk_mgr, false); | 168 | dcn31_smu_set_Z9_support(clk_mgr, false); |
| 154 | clk_mgr_base->clks.z9_support = new_clocks->z9_support; | 169 | clk_mgr_base->clks.zstate_support = new_clocks->zstate_support; |
| 155 | } | 170 | } |
| 156 | 171 | ||
| 157 | if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) { | 172 | if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) { |
| @@ -229,7 +244,32 @@ static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, · 71 unmodified lines | |||
| 229 | 244 | ||
| 230 | static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr) | 245 | static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr) |
| 231 | { | 246 | { |
| 232 | return 0; | 247 | /* get FbMult value */ |
| 248 | struct fixed31_32 pll_req; | ||
| 249 | unsigned int fbmult_frac_val = 0; | ||
| 250 | unsigned int fbmult_int_val = 0; | ||
| 251 | |||
| 252 | /* | ||
| 253 | * Register value of fbmult is in 8.16 format, we are converting to 31.32 | ||
| 254 | * to leverage the fix point operations available in driver | ||
| 255 | */ | ||
| 256 | |||
| 257 | REG_GET(CLK1_CLK_PLL_REQ, FbMult_frac, &fbmult_frac_val); /* 16 bit fractional part*/ | ||
| 258 | REG_GET(CLK1_CLK_PLL_REQ, FbMult_int, &fbmult_int_val); /* 8 bit integer part */ | ||
| 259 | |||
| 260 | pll_req = dc_fixpt_from_int(fbmult_int_val); | ||
| 261 | |||
| 262 | /* | ||
| 263 | * since fractional part is only 16 bit in register definition but is 32 bit | ||
| 264 | * in our fix point definiton, need to shift left by 16 to obtain correct value | ||
| 265 | */ | ||
| 266 | pll_req.value |= fbmult_frac_val << 16; | ||
| 267 | |||
| 268 | /* multiply by REFCLK period */ | ||
| 269 | pll_req = dc_fixpt_mul_int(pll_req, clk_mgr->dfs_ref_freq_khz); | ||
| 270 | |||
| 271 | /* integer part is now VCO frequency in kHz */ | ||
| 272 | return dc_fixpt_floor(pll_req); | ||
| 233 | } | 273 | } |
| 234 | 274 | ||
| 235 | static void dcn31_enable_pme_wa(struct clk_mgr *clk_mgr_base) | 275 | static void dcn31_enable_pme_wa(struct clk_mgr *clk_mgr_base) |
| @@ -246,7 +286,7 @@ static void dcn31_init_clocks(struct clk_mgr *clk_mgr) · 10 unmodified lines | |||
| 246 | clk_mgr->clks.p_state_change_support = true; | 286 | clk_mgr->clks.p_state_change_support = true; |
| 247 | clk_mgr->clks.prev_p_state_change_support = true; | 287 | clk_mgr->clks.prev_p_state_change_support = true; |
| 248 | clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; | 288 | clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; |
| 249 | clk_mgr->clks.z9_support = DCN_Z9_SUPPORT_UNKNOWN; | 289 | clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN; |
| 250 | } | 290 | } |
| 251 | 291 | ||
| 252 | static bool dcn31_are_clock_states_equal(struct dc_clocks *a, | 292 | static bool dcn31_are_clock_states_equal(struct dc_clocks *a, |
| @@ -260,7 +300,7 @@ static bool dcn31_are_clock_states_equal(struct dc_clocks *a, · 7 unmodified lines | |||
| 260 | return false; | 300 | return false; |
| 261 | else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz) | 301 | else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz) |
| 262 | return false; | 302 | return false; |
| 263 | else if (a->z9_support != b->z9_support) | 303 | else if (a->zstate_support != b->zstate_support) |
| 264 | return false; | 304 | return false; |
| 265 | else if (a->dtbclk_en != b->dtbclk_en) | 305 | else if (a->dtbclk_en != b->dtbclk_en) |
| 266 | return false; | 306 | return false; |
| @@ -592,6 +632,7 @@ void dcn31_clk_mgr_construct( · 325 unmodified lines | |||
| 592 | clk_mgr->base.dprefclk_ss_percentage = 0; | 632 | clk_mgr->base.dprefclk_ss_percentage = 0; |
| 593 | clk_mgr->base.dprefclk_ss_divider = 1000; | 633 | clk_mgr->base.dprefclk_ss_divider = 1000; |
| 594 | clk_mgr->base.ss_on_dprefclk = false; | 634 | clk_mgr->base.ss_on_dprefclk = false; |
| 635 | clk_mgr->base.dfs_ref_freq_khz = 48000; | ||
| 595 | 636 | ||
| 596 | clk_mgr->smu_wm_set.wm_set = (struct dcn31_watermarks *)dm_helpers_allocate_gpu_mem( | 637 | clk_mgr->smu_wm_set.wm_set = (struct dcn31_watermarks *)dm_helpers_allocate_gpu_mem( |
| 597 | clk_mgr->base.base.ctx, | 638 | clk_mgr->base.base.ctx, |
| @@ -27,60 +27,6 @@ · 26 unmodified lines | |||
| 27 | #define __DCN31_CLK_MGR_H__ | 27 | #define __DCN31_CLK_MGR_H__ |
| 28 | #include "clk_mgr_internal.h" | 28 | #include "clk_mgr_internal.h" |
| 29 | 29 | ||
| 30 | //CLK1_CLK_PLL_REQ | ||
| 31 | #ifndef CLK11_CLK1_CLK_PLL_REQ__FbMult_int__SHIFT | ||
| 32 | #define CLK11_CLK1_CLK_PLL_REQ__FbMult_int__SHIFT 0x0 | ||
| 33 | #define CLK11_CLK1_CLK_PLL_REQ__PllSpineDiv__SHIFT 0xc | ||
| 34 | #define CLK11_CLK1_CLK_PLL_REQ__FbMult_frac__SHIFT 0x10 | ||
| 35 | #define CLK11_CLK1_CLK_PLL_REQ__FbMult_int_MASK 0x000001FFL | ||
| 36 | #define CLK11_CLK1_CLK_PLL_REQ__PllSpineDiv_MASK 0x0000F000L | ||
| 37 | #define CLK11_CLK1_CLK_PLL_REQ__FbMult_frac_MASK 0xFFFF0000L | ||
| 38 | //CLK1_CLK0_DFS_CNTL | ||
| 39 | #define CLK11_CLK1_CLK0_DFS_CNTL__CLK0_DIVIDER__SHIFT 0x0 | ||
| 40 | #define CLK11_CLK1_CLK0_DFS_CNTL__CLK0_DIVIDER_MASK 0x0000007FL | ||
| 41 | /*DPREF clock related*/ | ||
| 42 | #define CLK0_CLK3_DFS_CNTL__CLK3_DIVIDER__SHIFT 0x0 | ||
| 43 | #define CLK0_CLK3_DFS_CNTL__CLK3_DIVIDER_MASK 0x0000007FL | ||
| 44 | #define CLK1_CLK3_DFS_CNTL__CLK3_DIVIDER__SHIFT 0x0 | ||
| 45 | #define CLK1_CLK3_DFS_CNTL__CLK3_DIVIDER_MASK 0x0000007FL | ||
| 46 | #define CLK2_CLK3_DFS_CNTL__CLK3_DIVIDER__SHIFT 0x0 | ||
| 47 | #define CLK2_CLK3_DFS_CNTL__CLK3_DIVIDER_MASK 0x0000007FL | ||
| 48 | #define CLK3_CLK3_DFS_CNTL__CLK3_DIVIDER__SHIFT 0x0 | ||
| 49 | #define CLK3_CLK3_DFS_CNTL__CLK3_DIVIDER_MASK 0x0000007FL | ||
| 50 | |||
| 51 | //CLK3_0_CLK3_CLK_PLL_REQ | ||
| 52 | #define CLK3_0_CLK3_CLK_PLL_REQ__FbMult_int__SHIFT 0x0 | ||
| 53 | #define CLK3_0_CLK3_CLK_PLL_REQ__PllSpineDiv__SHIFT 0xc | ||
| 54 | #define CLK3_0_CLK3_CLK_PLL_REQ__FbMult_frac__SHIFT 0x10 | ||
| 55 | #define CLK3_0_CLK3_CLK_PLL_REQ__FbMult_int_MASK 0x000001FFL | ||
| 56 | #define CLK3_0_CLK3_CLK_PLL_REQ__PllSpineDiv_MASK 0x0000F000L | ||
| 57 | #define CLK3_0_CLK3_CLK_PLL_REQ__FbMult_frac_MASK 0xFFFF0000L | ||
| 58 | |||
| 59 | #define mmCLK0_CLK3_DFS_CNTL 0x16C60 | ||
| 60 | #define mmCLK00_CLK0_CLK3_DFS_CNTL 0x16C60 | ||
| 61 | #define mmCLK01_CLK0_CLK3_DFS_CNTL 0x16E60 | ||
| 62 | #define mmCLK02_CLK0_CLK3_DFS_CNTL 0x17060 | ||
| 63 | #define mmCLK03_CLK0_CLK3_DFS_CNTL 0x17260 | ||
| 64 | |||
| 65 | #define mmCLK0_CLK_PLL_REQ 0x16C10 | ||
| 66 | #define mmCLK00_CLK0_CLK_PLL_REQ 0x16C10 | ||
| 67 | #define mmCLK01_CLK0_CLK_PLL_REQ 0x16E10 | ||
| 68 | #define mmCLK02_CLK0_CLK_PLL_REQ 0x17010 | ||
| 69 | #define mmCLK03_CLK0_CLK_PLL_REQ 0x17210 | ||
| 70 | |||
| 71 | #define mmCLK1_CLK_PLL_REQ 0x1B00D | ||
| 72 | #define mmCLK10_CLK1_CLK_PLL_REQ 0x1B00D | ||
| 73 | #define mmCLK11_CLK1_CLK_PLL_REQ 0x1B20D | ||
| 74 | #define mmCLK12_CLK1_CLK_PLL_REQ 0x1B40D | ||
| 75 | #define mmCLK13_CLK1_CLK_PLL_REQ 0x1B60D | ||
| 76 | |||
| 77 | #define mmCLK2_CLK_PLL_REQ 0x17E0D | ||
| 78 | |||
| 79 | /*AMCLK*/ | ||
| 80 | #define mmCLK11_CLK1_CLK0_DFS_CNTL 0x1B23F | ||
| 81 | #define mmCLK11_CLK1_CLK_PLL_REQ 0x1B20D | ||
| 82 | #endif | ||
| 83 | |||
| 84 | struct dcn31_watermarks; | 30 | struct dcn31_watermarks; |
| 85 | 31 | ||
| 86 | struct dcn31_smu_watermark_set { | 32 | struct dcn31_smu_watermark_set { |
| @@ -1820,8 +1820,7 @@ bool perform_link_training_with_retries( · 1819 unmodified lines | |||
| 1820 | */ | 1820 | */ |
| 1821 | panel_mode = DP_PANEL_MODE_DEFAULT; | 1821 | panel_mode = DP_PANEL_MODE_DEFAULT; |
| 1822 | } | 1822 | } |
| 1823 | } else | 1823 | } |
| 1824 | panel_mode = DP_PANEL_MODE_DEFAULT; | ||
| 1825 | } | 1824 | } |
| 1826 | #endif | 1825 | #endif |
| 1827 | 1826 | ||
| @@ -4650,7 +4649,10 @@ enum dp_panel_mode dp_get_panel_mode(struct dc_link *link) · 2822 unmodified lines | |||
| 4650 | } | 4649 | } |
| 4651 | } | 4650 | } |
| 4652 | 4651 | ||
| 4653 | if (link->dpcd_caps.panel_mode_edp) { | 4652 | if (link->dpcd_caps.panel_mode_edp && |
| 4653 | (link->connector_signal == SIGNAL_TYPE_EDP || | ||
| 4654 | (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT && | ||
| 4655 | link->is_internal_display))) { | ||
| 4654 | return DP_PANEL_MODE_EDP; | 4656 | return DP_PANEL_MODE_EDP; |
| 4655 | } | 4657 | } |
| 4656 | 4658 | ||
| @@ -4914,9 +4916,7 @@ bool dc_link_set_default_brightness_aux(struct dc_link *link) · 257 unmodified lines | |||
| 4914 | { | 4916 | { |
| 4915 | uint32_t default_backlight; | 4917 | uint32_t default_backlight; |
| 4916 | 4918 | ||
| 4917 | if (link && | 4919 | if (link && link->dpcd_sink_ext_caps.bits.oled == 1) { |
| 4918 | (link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || | ||
| 4919 | link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { | ||
| 4920 | if (!dc_link_read_default_bl_aux(link, &default_backlight)) | 4920 | if (!dc_link_read_default_bl_aux(link, &default_backlight)) |
| 4921 | default_backlight = 150000; | 4921 | default_backlight = 150000; |
| 4922 | // if < 5 nits or > 5000, it might be wrong readback | 4922 | // if < 5 nits or > 5000, it might be wrong readback |
| @@ -1062,7 +1062,7 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) · 1061 unmodified lines | |||
| 1062 | * so use only 30 bpp on DCE_VERSION_11_0. Testing with DCE 11.2 and 8.3 | 1062 | * so use only 30 bpp on DCE_VERSION_11_0. Testing with DCE 11.2 and 8.3 |
| 1063 | * did not show such problems, so this seems to be the exception. | 1063 | * did not show such problems, so this seems to be the exception. |
| 1064 | */ | 1064 | */ |
| 1065 | if (plane_state->ctx->dce_version != DCE_VERSION_11_0) | 1065 | if (plane_state->ctx->dce_version > DCE_VERSION_11_0) |
| 1066 | pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP; | 1066 | pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP; |
| 1067 | else | 1067 | else |
| 1068 | pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; | 1068 | pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; |
| @@ -354,10 +354,10 @@ enum dcn_pwr_state { · 353 unmodified lines | |||
| 354 | }; | 354 | }; |
| 355 | 355 | ||
| 356 | #if defined(CONFIG_DRM_AMD_DC_DCN) | 356 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 357 | enum dcn_z9_support_state { | 357 | enum dcn_zstate_support_state { |
| 358 | DCN_Z9_SUPPORT_UNKNOWN, | 358 | DCN_ZSTATE_SUPPORT_UNKNOWN, |
| 359 | DCN_Z9_SUPPORT_ALLOW, | 359 | DCN_ZSTATE_SUPPORT_ALLOW, |
| 360 | DCN_Z9_SUPPORT_DISALLOW, | 360 | DCN_ZSTATE_SUPPORT_DISALLOW, |
| 361 | }; | 361 | }; |
| 362 | #endif | 362 | #endif |
| 363 | /* | 363 | /* |
| @@ -378,7 +378,7 @@ struct dc_clocks { · 14 unmodified lines | |||
| 378 | int dramclk_khz; | 378 | int dramclk_khz; |
| 379 | bool p_state_change_support; | 379 | bool p_state_change_support; |
| 380 | #if defined(CONFIG_DRM_AMD_DC_DCN) | 380 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 381 | enum dcn_z9_support_state z9_support; | 381 | enum dcn_zstate_support_state zstate_support; |
| 382 | bool dtbclk_en; | 382 | bool dtbclk_en; |
| 383 | #endif | 383 | #endif |
| 384 | enum dcn_pwr_state pwr_state; | 384 | enum dcn_pwr_state pwr_state; |
| @@ -636,6 +636,7 @@ struct dce_hwseq_registers { · 635 unmodified lines | |||
| 636 | uint32_t ODM_MEM_PWR_CTRL3; | 636 | uint32_t ODM_MEM_PWR_CTRL3; |
| 637 | uint32_t DMU_MEM_PWR_CNTL; | 637 | uint32_t DMU_MEM_PWR_CNTL; |
| 638 | uint32_t MMHUBBUB_MEM_PWR_CNTL; | 638 | uint32_t MMHUBBUB_MEM_PWR_CNTL; |
| 639 | uint32_t DCHUBBUB_ARB_HOSTVM_CNTL; | ||
| 639 | }; | 640 | }; |
| 640 | /* set field name */ | 641 | /* set field name */ |
| 641 | #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ | 642 | #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ |
| @@ -1110,7 +1111,8 @@ struct dce_hwseq_registers { · 468 unmodified lines | |||
| 1110 | type DOMAIN_POWER_FORCEON;\ | 1111 | type DOMAIN_POWER_FORCEON;\ |
| 1111 | type DOMAIN_POWER_GATE;\ | 1112 | type DOMAIN_POWER_GATE;\ |
| 1112 | type DOMAIN_PGFSM_PWR_STATUS;\ | 1113 | type DOMAIN_PGFSM_PWR_STATUS;\ |
| 1113 | type HPO_HDMISTREAMCLK_G_GATE_DIS; | 1114 | type HPO_HDMISTREAMCLK_G_GATE_DIS;\ |
| 1115 | type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE; | ||
| 1114 | 1116 | ||
| 1115 | struct dce_hwseq_shift { | 1117 | struct dce_hwseq_shift { |
| 1116 | HWSEQ_REG_FIELD_LIST(uint8_t) | 1118 | HWSEQ_REG_FIELD_LIST(uint8_t) |
| @@ -217,6 +217,8 @@ static void dpp1_dscl_set_lb( · 216 unmodified lines | |||
| 217 | const struct line_buffer_params *lb_params, | 217 | const struct line_buffer_params *lb_params, |
| 218 | enum lb_memory_config mem_size_config) | 218 | enum lb_memory_config mem_size_config) |
| 219 | { | 219 | { |
| 220 | uint32_t max_partitions = 63; /* Currently hardcoded on all ASICs before DCN 3.2 */ | ||
| 221 | |||
| 220 | /* LB */ | 222 | /* LB */ |
| 221 | if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { | 223 | if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { |
| 222 | /* DSCL caps: pixel data processed in fixed format */ | 224 | /* DSCL caps: pixel data processed in fixed format */ |
| @@ -239,9 +241,12 @@ static void dpp1_dscl_set_lb( · 16 unmodified lines | |||
| 239 | LB_DATA_FORMAT__ALPHA_EN, lb_params->alpha_en); /* Alpha enable */ | 241 | LB_DATA_FORMAT__ALPHA_EN, lb_params->alpha_en); /* Alpha enable */ |
| 240 | } | 242 | } |
| 241 | 243 | ||
| 244 | if (dpp->base.caps->max_lb_partitions == 31) | ||
| 245 | max_partitions = 31; | ||
| 246 | |||
| 242 | REG_SET_2(LB_MEMORY_CTRL, 0, | 247 | REG_SET_2(LB_MEMORY_CTRL, 0, |
| 243 | MEMORY_CONFIG, mem_size_config, | 248 | MEMORY_CONFIG, mem_size_config, |
| 244 | LB_MAX_PARTITIONS, 63); | 249 | LB_MAX_PARTITIONS, max_partitions); |
| 245 | } | 250 | } |
| 246 | 251 | ||
| 247 | static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) | 252 | static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) |
| @@ -2093,8 +2093,10 @@ int dcn20_populate_dml_pipes_from_context( · 2092 unmodified lines | |||
| 2093 | - timing->v_border_bottom; | 2093 | - timing->v_border_bottom; |
| 2094 | pipes[pipe_cnt].pipe.dest.htotal = timing->h_total; | 2094 | pipes[pipe_cnt].pipe.dest.htotal = timing->h_total; |
| 2095 | pipes[pipe_cnt].pipe.dest.vtotal = v_total; | 2095 | pipes[pipe_cnt].pipe.dest.vtotal = v_total; |
| 2096 | pipes[pipe_cnt].pipe.dest.hactive = timing->h_addressable; | 2096 | pipes[pipe_cnt].pipe.dest.hactive = |
| 2097 | pipes[pipe_cnt].pipe.dest.vactive = timing->v_addressable; | 2097 | timing->h_addressable + timing->h_border_left + timing->h_border_right; |
| 2098 | pipes[pipe_cnt].pipe.dest.vactive = | ||
| 2099 | timing->v_addressable + timing->v_border_top + timing->v_border_bottom; | ||
| 2098 | pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE; | 2100 | pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE; |
| 2099 | pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0; | 2101 | pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0; |
| 2100 | if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING) | 2102 | if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING) |
| @@ -3079,6 +3081,37 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) · 978 unmodified lines | |||
| 3079 | return false; | 3081 | return false; |
| 3080 | } | 3082 | } |
| 3081 | 3083 | ||
| 3084 | static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struct dc_state *context) | ||
| 3085 | { | ||
| 3086 | int plane_count; | ||
| 3087 | int i; | ||
| 3088 | |||
| 3089 | plane_count = 0; | ||
| 3090 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
| 3091 | if (context->res_ctx.pipe_ctx[i].plane_state) | ||
| 3092 | plane_count++; | ||
| 3093 | } | ||
| 3094 | |||
| 3095 | /* | ||
| 3096 | * Zstate is allowed in following scenarios: | ||
| 3097 | * 1. Single eDP with PSR enabled | ||
| 3098 | * 2. 0 planes (No memory requests) | ||
| 3099 | * 3. Single eDP without PSR but > 5ms stutter period | ||
| 3100 | */ | ||
| 3101 | if (plane_count == 0) | ||
| 3102 | return DCN_ZSTATE_SUPPORT_ALLOW; | ||
| 3103 | else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { | ||
| 3104 | struct dc_link *link = context->streams[0]->sink->link; | ||
| 3105 | |||
| 3106 | if ((link->link_index == 0 && link->psr_settings.psr_feature_enabled) | ||
| 3107 | || context->bw_ctx.dml.vba.StutterPeriod > 5000.0) | ||
| 3108 | return DCN_ZSTATE_SUPPORT_ALLOW; | ||
| 3109 | else | ||
| 3110 | return DCN_ZSTATE_SUPPORT_DISALLOW; | ||
| 3111 | } else | ||
| 3112 | return DCN_ZSTATE_SUPPORT_DISALLOW; | ||
| 3113 | } | ||
| 3114 | |||
| 3082 | void dcn20_calculate_dlg_params( | 3115 | void dcn20_calculate_dlg_params( |
| 3083 | struct dc *dc, struct dc_state *context, | 3116 | struct dc *dc, struct dc_state *context, |
| 3084 | display_e2e_pipe_params_st *pipes, | 3117 | display_e2e_pipe_params_st *pipes, |
| @@ -3086,7 +3119,6 @@ void dcn20_calculate_dlg_params( · 1 unmodified line | |||
| 3086 | int vlevel) | 3119 | int vlevel) |
| 3087 | { | 3120 | { |
| 3088 | int i, pipe_idx; | 3121 | int i, pipe_idx; |
| 3089 | int plane_count; | ||
| 3090 | 3122 | ||
| 3091 | /* Writeback MCIF_WB arbitration parameters */ | 3123 | /* Writeback MCIF_WB arbitration parameters */ |
| 3092 | dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt); | 3124 | dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt); |
| @@ -3102,17 +3134,7 @@ void dcn20_calculate_dlg_params( · 9 unmodified lines | |||
| 3102 | != dm_dram_clock_change_unsupported; | 3134 | != dm_dram_clock_change_unsupported; |
| 3103 | context->bw_ctx.bw.dcn.clk.dppclk_khz = 0; | 3135 | context->bw_ctx.bw.dcn.clk.dppclk_khz = 0; |
| 3104 | 3136 | ||
| 3105 | context->bw_ctx.bw.dcn.clk.z9_support = (context->bw_ctx.dml.vba.StutterPeriod > 5000.0) ? | 3137 | context->bw_ctx.bw.dcn.clk.zstate_support = decide_zstate_support(dc, context); |
| 3106 | DCN_Z9_SUPPORT_ALLOW : DCN_Z9_SUPPORT_DISALLOW; | ||
| 3107 | |||
| 3108 | plane_count = 0; | ||
| 3109 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
| 3110 | if (context->res_ctx.pipe_ctx[i].plane_state) | ||
| 3111 | plane_count++; | ||
| 3112 | } | ||
| 3113 | |||
| 3114 | if (plane_count == 0) | ||
| 3115 | context->bw_ctx.bw.dcn.clk.z9_support = DCN_Z9_SUPPORT_ALLOW; | ||
| 3116 | 3138 | ||
| 3117 | context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context); | 3139 | context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context); |
| 3118 | 3140 | ||
| @@ -109,6 +109,7 @@ struct _vcs_dpi_ip_params_st dcn2_1_ip = { · 108 unmodified lines | |||
| 109 | .max_page_table_levels = 4, | 109 | .max_page_table_levels = 4, |
| 110 | .pte_chunk_size_kbytes = 2, | 110 | .pte_chunk_size_kbytes = 2, |
| 111 | .meta_chunk_size_kbytes = 2, | 111 | .meta_chunk_size_kbytes = 2, |
| 112 | .min_meta_chunk_size_bytes = 256, | ||
| 112 | .writeback_chunk_size_kbytes = 2, | 113 | .writeback_chunk_size_kbytes = 2, |
| 113 | .line_buffer_size_bits = 789504, | 114 | .line_buffer_size_bits = 789504, |
| 114 | .is_line_buffer_bpp_fixed = 0, | 115 | .is_line_buffer_bpp_fixed = 0, |
| @@ -383,13 +383,6 @@ bool dpp3_get_optimal_number_of_taps( · 382 unmodified lines | |||
| 383 | int min_taps_y, min_taps_c; | 383 | int min_taps_y, min_taps_c; |
| 384 | enum lb_memory_config lb_config; | 384 | enum lb_memory_config lb_config; |
| 385 | 385 | ||
| 386 | /* Some ASICs does not support FP16 scaling, so we reject modes require this*/ | ||
| 387 | if (scl_data->viewport.width != scl_data->h_active && | ||
| 388 | scl_data->viewport.height != scl_data->v_active && | ||
| 389 | dpp->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT && | ||
| 390 | scl_data->format == PIXEL_FORMAT_FP16) | ||
| 391 | return false; | ||
| 392 | |||
| 393 | if (scl_data->viewport.width > scl_data->h_active && | 386 | if (scl_data->viewport.width > scl_data->h_active && |
| 394 | dpp->ctx->dc->debug.max_downscale_src_width != 0 && | 387 | dpp->ctx->dc->debug.max_downscale_src_width != 0 && |
| 395 | scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) | 388 | scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) |
| @@ -1440,15 +1433,6 @@ bool dpp3_construct( · 1044 unmodified lines | |||
| 1440 | dpp->tf_shift = tf_shift; | 1433 | dpp->tf_shift = tf_shift; |
| 1441 | dpp->tf_mask = tf_mask; | 1434 | dpp->tf_mask = tf_mask; |
| 1442 | 1435 | ||
| 1443 | dpp->lb_pixel_depth_supported = | ||
| 1444 | LB_PIXEL_DEPTH_18BPP | | ||
| 1445 | LB_PIXEL_DEPTH_24BPP | | ||
| 1446 | LB_PIXEL_DEPTH_30BPP | | ||
| 1447 | LB_PIXEL_DEPTH_36BPP; | ||
| 1448 | |||
| 1449 | dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY; | ||
| 1450 | dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/ | ||
| 1451 | |||
| 1452 | return true; | 1436 | return true; |
| 1453 | } | 1437 | } |
| 1454 | 1438 | ||
| @@ -154,6 +154,7 @@ · 153 unmodified lines | |||
| 154 | SRI(COLOR_KEYER_BLUE, CNVC_CFG, id), \ | 154 | SRI(COLOR_KEYER_BLUE, CNVC_CFG, id), \ |
| 155 | SRI(CURSOR_CONTROL, CURSOR0_, id),\ | 155 | SRI(CURSOR_CONTROL, CURSOR0_, id),\ |
| 156 | SRI(OBUF_MEM_PWR_CTRL, DSCL, id),\ | 156 | SRI(OBUF_MEM_PWR_CTRL, DSCL, id),\ |
| 157 | SRI(DSCL_MEM_PWR_STATUS, DSCL, id), \ | ||
| 157 | SRI(DSCL_MEM_PWR_CTRL, DSCL, id) | 158 | SRI(DSCL_MEM_PWR_CTRL, DSCL, id) |
| 158 | 159 | ||
| 159 | #define DPP_REG_LIST_DCN30(id)\ | 160 | #define DPP_REG_LIST_DCN30(id)\ |
| @@ -163,8 +164,6 @@ · 3 unmodified lines | |||
| 163 | SRI(CM_SHAPER_LUT_DATA, CM, id),\ | 164 | SRI(CM_SHAPER_LUT_DATA, CM, id),\ |
| 164 | SRI(CM_MEM_PWR_CTRL2, CM, id), \ | 165 | SRI(CM_MEM_PWR_CTRL2, CM, id), \ |
| 165 | SRI(CM_MEM_PWR_STATUS2, CM, id), \ | 166 | SRI(CM_MEM_PWR_STATUS2, CM, id), \ |
| 166 | SRI(DSCL_MEM_PWR_STATUS, DSCL, id), \ | ||
| 167 | SRI(DSCL_MEM_PWR_CTRL, DSCL, id), \ | ||
| 168 | SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B, CM, id),\ | 167 | SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B, CM, id),\ |
| 169 | SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G, CM, id),\ | 168 | SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G, CM, id),\ |
| 170 | SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R, CM, id),\ | 169 | SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R, CM, id),\ |
| @@ -1398,11 +1398,18 @@ void dcn302_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 1397 unmodified lines | |||
| 1398 | dcn3_02_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; | 1398 | dcn3_02_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; |
| 1399 | dcn3_02_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; | 1399 | dcn3_02_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; |
| 1400 | dcn3_02_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz; | 1400 | dcn3_02_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz; |
| 1401 | dcn3_02_soc.clock_limits[i].dtbclk_mhz = dcn3_02_soc.clock_limits[0].dtbclk_mhz; | 1401 | /* Populate from bw_params for DTBCLK, SOCCLK */ |
| 1402 | if (!bw_params->clk_table.entries[i].dtbclk_mhz && i > 0) | ||
| 1403 | dcn3_02_soc.clock_limits[i].dtbclk_mhz = dcn3_02_soc.clock_limits[i-1].dtbclk_mhz; | ||
| 1404 | else | ||
| 1405 | dcn3_02_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz; | ||
| 1406 | if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0) | ||
| 1407 | dcn3_02_soc.clock_limits[i].socclk_mhz = dcn3_02_soc.clock_limits[i-1].socclk_mhz; | ||
| 1408 | else | ||
| 1409 | dcn3_02_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz; | ||
| 1402 | /* These clocks cannot come from bw_params, always fill from dcn3_02_soc[1] */ | 1410 | /* These clocks cannot come from bw_params, always fill from dcn3_02_soc[1] */ |
| 1403 | /* FCLK, PHYCLK_D18, SOCCLK, DSCCLK */ | 1411 | /* FCLK, PHYCLK_D18, DSCCLK */ |
| 1404 | dcn3_02_soc.clock_limits[i].phyclk_d18_mhz = dcn3_02_soc.clock_limits[0].phyclk_d18_mhz; | 1412 | dcn3_02_soc.clock_limits[i].phyclk_d18_mhz = dcn3_02_soc.clock_limits[0].phyclk_d18_mhz; |
| 1405 | dcn3_02_soc.clock_limits[i].socclk_mhz = dcn3_02_soc.clock_limits[0].socclk_mhz; | ||
| 1406 | dcn3_02_soc.clock_limits[i].dscclk_mhz = dcn3_02_soc.clock_limits[0].dscclk_mhz; | 1413 | dcn3_02_soc.clock_limits[i].dscclk_mhz = dcn3_02_soc.clock_limits[0].dscclk_mhz; |
| 1407 | } | 1414 | } |
| 1408 | /* re-init DML with updated bb */ | 1415 | /* re-init DML with updated bb */ |
| @@ -1326,11 +1326,18 @@ void dcn303_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 1325 unmodified lines | |||
| 1326 | dcn3_03_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; | 1326 | dcn3_03_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; |
| 1327 | dcn3_03_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; | 1327 | dcn3_03_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; |
| 1328 | dcn3_03_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz; | 1328 | dcn3_03_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz; |
| 1329 | dcn3_03_soc.clock_limits[i].dtbclk_mhz = dcn3_03_soc.clock_limits[0].dtbclk_mhz; | 1329 | /* Populate from bw_params for DTBCLK, SOCCLK */ |
| 1330 | if (!bw_params->clk_table.entries[i].dtbclk_mhz && i > 0) | ||
| 1331 | dcn3_03_soc.clock_limits[i].dtbclk_mhz = dcn3_03_soc.clock_limits[i-1].dtbclk_mhz; | ||
| 1332 | else | ||
| 1333 | dcn3_03_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz; | ||
| 1334 | if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0) | ||
| 1335 | dcn3_03_soc.clock_limits[i].socclk_mhz = dcn3_03_soc.clock_limits[i-1].socclk_mhz; | ||
| 1336 | else | ||
| 1337 | dcn3_03_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz; | ||
| 1330 | /* These clocks cannot come from bw_params, always fill from dcn3_03_soc[1] */ | 1338 | /* These clocks cannot come from bw_params, always fill from dcn3_03_soc[1] */ |
| 1331 | /* FCLK, PHYCLK_D18, SOCCLK, DSCCLK */ | 1339 | /* FCLK, PHYCLK_D18, DSCCLK */ |
| 1332 | dcn3_03_soc.clock_limits[i].phyclk_d18_mhz = dcn3_03_soc.clock_limits[0].phyclk_d18_mhz; | 1340 | dcn3_03_soc.clock_limits[i].phyclk_d18_mhz = dcn3_03_soc.clock_limits[0].phyclk_d18_mhz; |
| 1333 | dcn3_03_soc.clock_limits[i].socclk_mhz = dcn3_03_soc.clock_limits[0].socclk_mhz; | ||
| 1334 | dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz; | 1341 | dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz; |
| 1335 | } | 1342 | } |
| 1336 | /* re-init DML with updated bb */ | 1343 | /* re-init DML with updated bb */ |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | |||
| 47 | #include "dce/dmub_outbox.h" | 47 | #include "dce/dmub_outbox.h" |
| 48 | #include "dc_link_dp.h" | 48 | #include "dc_link_dp.h" |
| 49 | #include "inc/link_dpcd.h" | 49 | #include "inc/link_dpcd.h" |
| 50 | #include "dcn10/dcn10_hw_sequencer.h" | ||
| 50 | 51 | ||
| 51 | #define DC_LOGGER_INIT(logger) | 52 | #define DC_LOGGER_INIT(logger) |
| 52 | 53 | ||
| @@ -594,3 +595,20 @@ bool dcn31_is_abm_supported(struct dc *dc, · 541 unmodified lines | |||
| 594 | } | 595 | } |
| 595 | return false; | 596 | return false; |
| 596 | } | 597 | } |
| 598 | |||
| 599 | static void apply_riommu_invalidation_wa(struct dc *dc) | ||
| 600 | { | ||
| 601 | struct dce_hwseq *hws = dc->hwseq; | ||
| 602 | |||
| 603 | if (!hws->wa.early_riommu_invalidation) | ||
| 604 | return; | ||
| 605 | |||
| 606 | REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL, DISABLE_HOSTVM_FORCE_ALLOW_PSTATE, 0); | ||
| 607 | } | ||
| 608 | |||
| 609 | void dcn31_init_pipes(struct dc *dc, struct dc_state *context) | ||
| 610 | { | ||
| 611 | dcn10_init_pipes(dc, context); | ||
| 612 | apply_riommu_invalidation_wa(dc); | ||
| 613 | |||
| 614 | } | ||
| @@ -52,5 +52,6 @@ void dcn31_reset_hw_ctx_wrap( · 51 unmodified lines | |||
| 52 | struct dc_state *context); | 52 | struct dc_state *context); |
| 53 | bool dcn31_is_abm_supported(struct dc *dc, | 53 | bool dcn31_is_abm_supported(struct dc *dc, |
| 54 | struct dc_state *context, struct dc_stream_state *stream); | 54 | struct dc_state *context, struct dc_stream_state *stream); |
| 55 | void dcn31_init_pipes(struct dc *dc, struct dc_state *context); | ||
| 55 | 56 | ||
| 56 | #endif /* __DC_HWSS_DCN31_H__ */ | 57 | #endif /* __DC_HWSS_DCN31_H__ */ |
| @@ -93,7 +93,6 @@ static const struct hw_sequencer_funcs dcn31_funcs = { · 92 unmodified lines | |||
| 93 | .set_flip_control_gsl = dcn20_set_flip_control_gsl, | 93 | .set_flip_control_gsl = dcn20_set_flip_control_gsl, |
| 94 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, | 94 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, |
| 95 | .calc_vupdate_position = dcn10_calc_vupdate_position, | 95 | .calc_vupdate_position = dcn10_calc_vupdate_position, |
| 96 | .apply_idle_power_optimizations = dcn30_apply_idle_power_optimizations, | ||
| 97 | .set_backlight_level = dcn21_set_backlight_level, | 96 | .set_backlight_level = dcn21_set_backlight_level, |
| 98 | .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, | 97 | .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, |
| 99 | .set_pipe = dcn21_set_pipe, | 98 | .set_pipe = dcn21_set_pipe, |
| @@ -104,7 +103,7 @@ static const struct hw_sequencer_funcs dcn31_funcs = { · 4 unmodified lines | |||
| 104 | }; | 103 | }; |
| 105 | 104 | ||
| 106 | static const struct hwseq_private_funcs dcn31_private_funcs = { | 105 | static const struct hwseq_private_funcs dcn31_private_funcs = { |
| 107 | .init_pipes = dcn10_init_pipes, | 106 | .init_pipes = dcn31_init_pipes, |
| 108 | .update_plane_addr = dcn20_update_plane_addr, | 107 | .update_plane_addr = dcn20_update_plane_addr, |
| 109 | .plane_atomic_disconnect = dcn10_plane_atomic_disconnect, | 108 | .plane_atomic_disconnect = dcn10_plane_atomic_disconnect, |
| 110 | .update_mpcc = dcn20_update_mpcc, | 109 | .update_mpcc = dcn20_update_mpcc, |
| @@ -220,6 +220,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = { · 219 unmodified lines | |||
| 220 | .sr_exit_z8_time_us = 402.0, | 220 | .sr_exit_z8_time_us = 402.0, |
| 221 | .sr_enter_plus_exit_z8_time_us = 520.0, | 221 | .sr_enter_plus_exit_z8_time_us = 520.0, |
| 222 | .writeback_latency_us = 12.0, | 222 | .writeback_latency_us = 12.0, |
| 223 | .dram_channel_width_bytes = 4, | ||
| 223 | .round_trip_ping_latency_dcfclk_cycles = 106, | 224 | .round_trip_ping_latency_dcfclk_cycles = 106, |
| 224 | .urgent_latency_pixel_data_only_us = 4.0, | 225 | .urgent_latency_pixel_data_only_us = 4.0, |
| 225 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, | 226 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, |
| @@ -741,6 +742,7 @@ static const struct dccg_mask dccg_mask = { · 515 unmodified lines | |||
| 741 | 742 | ||
| 742 | #define HWSEQ_DCN31_REG_LIST()\ | 743 | #define HWSEQ_DCN31_REG_LIST()\ |
| 743 | SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ | 744 | SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ |
| 745 | SR(DCHUBBUB_ARB_HOSTVM_CNTL), \ | ||
| 744 | SR(DIO_MEM_PWR_CTRL), \ | 746 | SR(DIO_MEM_PWR_CTRL), \ |
| 745 | SR(ODM_MEM_PWR_CTRL3), \ | 747 | SR(ODM_MEM_PWR_CTRL3), \ |
| 746 | SR(DMU_MEM_PWR_CNTL), \ | 748 | SR(DMU_MEM_PWR_CNTL), \ |
| @@ -801,6 +803,7 @@ static const struct dce_hwseq_registers hwseq_reg = { · 54 unmodified lines | |||
| 801 | #define HWSEQ_DCN31_MASK_SH_LIST(mask_sh)\ | 803 | #define HWSEQ_DCN31_MASK_SH_LIST(mask_sh)\ |
| 802 | HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ | 804 | HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ |
| 803 | HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ | 805 | HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ |
| 806 | HWS_SF(, DCHUBBUB_ARB_HOSTVM_CNTL, DISABLE_HOSTVM_FORCE_ALLOW_PSTATE, mask_sh), \ | ||
| 804 | HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ | 807 | HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ |
| 805 | HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ | 808 | HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ |
| 806 | HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ | 809 | HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ |
| @@ -1299,6 +1302,7 @@ static struct dce_hwseq *dcn31_hwseq_create( · 492 unmodified lines | |||
| 1299 | hws->regs = &hwseq_reg; | 1302 | hws->regs = &hwseq_reg; |
| 1300 | hws->shifts = &hwseq_shift; | 1303 | hws->shifts = &hwseq_shift; |
| 1301 | hws->masks = &hwseq_mask; | 1304 | hws->masks = &hwseq_mask; |
| 1305 | hws->wa.early_riommu_invalidation = true; | ||
| 1302 | } | 1306 | } |
| 1303 | return hws; | 1307 | return hws; |
| 1304 | } | 1308 | } |
| @@ -841,6 +841,9 @@ static bool CalculatePrefetchSchedule( · 840 unmodified lines | |||
| 841 | else | 841 | else |
| 842 | *DestinationLinesForPrefetch = dst_y_prefetch_equ; | 842 | *DestinationLinesForPrefetch = dst_y_prefetch_equ; |
| 843 | 843 | ||
| 844 | // Limit to prevent overflow in DST_Y_PREFETCH register | ||
| 845 | *DestinationLinesForPrefetch = dml_min(*DestinationLinesForPrefetch, 63.75); | ||
| 846 | |||
| 844 | dml_print("DML: VStartup: %d\n", VStartup); | 847 | dml_print("DML: VStartup: %d\n", VStartup); |
| 845 | dml_print("DML: TCalc: %f\n", TCalc); | 848 | dml_print("DML: TCalc: %f\n", TCalc); |
| 846 | dml_print("DML: TWait: %f\n", TWait); | 849 | dml_print("DML: TWait: %f\n", TWait); |
| @@ -4889,7 +4892,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 4042 unmodified lines | |||
| 4889 | } | 4892 | } |
| 4890 | } while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true) | 4893 | } while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true) |
| 4891 | && (mode_lib->vba.NextMaxVStartup != mode_lib->vba.MaxMaxVStartup[0][0] | 4894 | && (mode_lib->vba.NextMaxVStartup != mode_lib->vba.MaxMaxVStartup[0][0] |
| 4892 | || mode_lib->vba.NextPrefetchMode < mode_lib->vba.MaxPrefetchMode)); | 4895 | || mode_lib->vba.NextPrefetchMode <= mode_lib->vba.MaxPrefetchMode)); |
| 4893 | 4896 | ||
| 4894 | if (locals->PrefetchSupported[i][j] == true && locals->VRatioInPrefetchSupported[i][j] == true) { | 4897 | if (locals->PrefetchSupported[i][j] == true && locals->VRatioInPrefetchSupported[i][j] == true) { |
| 4895 | mode_lib->vba.BandwidthAvailableForImmediateFlip = locals->ReturnBWPerState[i][0]; | 4898 | mode_lib->vba.BandwidthAvailableForImmediateFlip = locals->ReturnBWPerState[i][0]; |
| @@ -289,6 +289,9 @@ struct dpp_caps { · 288 unmodified lines | |||
| 289 | /* DSCL processing pixel data in fixed or float format */ | 289 | /* DSCL processing pixel data in fixed or float format */ |
| 290 | enum dscl_data_processing_format dscl_data_proc_format; | 290 | enum dscl_data_processing_format dscl_data_proc_format; |
| 291 | 291 | ||
| 292 | /* max LB partitions */ | ||
| 293 | unsigned int max_lb_partitions; | ||
| 294 | |||
| 292 | /* Calculates the number of partitions in the line buffer. | 295 | /* Calculates the number of partitions in the line buffer. |
| 293 | * The implementation of this function is overloaded for | 296 | * The implementation of this function is overloaded for |
| 294 | * different versions of DSCL LB. | 297 | * different versions of DSCL LB. |
| @@ -41,6 +41,7 @@ struct dce_hwseq_wa { · 40 unmodified lines | |||
| 41 | bool DEGVIDCN10_254; | 41 | bool DEGVIDCN10_254; |
| 42 | bool DEGVIDCN21; | 42 | bool DEGVIDCN21; |
| 43 | bool disallow_self_refresh_during_multi_plane_transition; | 43 | bool disallow_self_refresh_during_multi_plane_transition; |
| 44 | bool early_riommu_invalidation; | ||
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | struct hwseq_wa_state { | 47 | struct hwseq_wa_state { |
| @@ -101,7 +101,8 @@ · 100 unmodified lines | |||
| 101 | #define PPSMC_MSG_SetSystemVirtualSTBtoDramAddrLow 0x41 | 101 | #define PPSMC_MSG_SetSystemVirtualSTBtoDramAddrLow 0x41 |
| 102 | 102 | ||
| 103 | #define PPSMC_MSG_GfxDriverResetRecovery 0x42 | 103 | #define PPSMC_MSG_GfxDriverResetRecovery 0x42 |
| 104 | #define PPSMC_Message_Count 0x43 | 104 | #define PPSMC_MSG_BoardPowerCalibration 0x43 |
| 105 | #define PPSMC_Message_Count 0x44 | ||
| 105 | 106 | ||
| 106 | //PPSMC Reset Types | 107 | //PPSMC Reset Types |
| 107 | #define PPSMC_RESET_TYPE_WARM_RESET 0x00 | 108 | #define PPSMC_RESET_TYPE_WARM_RESET 0x00 |
| @@ -225,7 +225,8 @@ · 224 unmodified lines | |||
| 225 | __SMU_DUMMY_MAP(DisableDeterminism), \ | 225 | __SMU_DUMMY_MAP(DisableDeterminism), \ |
| 226 | __SMU_DUMMY_MAP(SetUclkDpmMode), \ | 226 | __SMU_DUMMY_MAP(SetUclkDpmMode), \ |
| 227 | __SMU_DUMMY_MAP(LightSBR), \ | 227 | __SMU_DUMMY_MAP(LightSBR), \ |
| 228 | __SMU_DUMMY_MAP(GfxDriverResetRecovery), | 228 | __SMU_DUMMY_MAP(GfxDriverResetRecovery), \ |
| 229 | __SMU_DUMMY_MAP(BoardPowerCalibration), | ||
| 229 | 230 | ||
| 230 | #undef __SMU_DUMMY_MAP | 231 | #undef __SMU_DUMMY_MAP |
| 231 | #define __SMU_DUMMY_MAP(type) SMU_MSG_##type | 232 | #define __SMU_DUMMY_MAP(type) SMU_MSG_##type |
| @@ -34,7 +34,7 @@ · 33 unmodified lines | |||
| 34 | #define SMU11_DRIVER_IF_VERSION_Navy_Flounder 0xE | 34 | #define SMU11_DRIVER_IF_VERSION_Navy_Flounder 0xE |
| 35 | #define SMU11_DRIVER_IF_VERSION_VANGOGH 0x03 | 35 | #define SMU11_DRIVER_IF_VERSION_VANGOGH 0x03 |
| 36 | #define SMU11_DRIVER_IF_VERSION_Dimgrey_Cavefish 0xF | 36 | #define SMU11_DRIVER_IF_VERSION_Dimgrey_Cavefish 0xF |
| 37 | #define SMU11_DRIVER_IF_VERSION_Beige_Goby 0x9 | 37 | #define SMU11_DRIVER_IF_VERSION_Beige_Goby 0xD |
| 38 | 38 | ||
| 39 | /* MP Apertures */ | 39 | /* MP Apertures */ |
| 40 | #define MP0_Public 0x03800000 | 40 | #define MP0_Public 0x03800000 |
| @@ -134,6 +134,7 @@ static const struct cmn2asic_msg_mapping aldebaran_message_map[SMU_MSG_MAX_COUNT · 133 unmodified lines | |||
| 134 | MSG_MAP(DisableDeterminism, PPSMC_MSG_DisableDeterminism, 0), | 134 | MSG_MAP(DisableDeterminism, PPSMC_MSG_DisableDeterminism, 0), |
| 135 | MSG_MAP(SetUclkDpmMode, PPSMC_MSG_SetUclkDpmMode, 0), | 135 | MSG_MAP(SetUclkDpmMode, PPSMC_MSG_SetUclkDpmMode, 0), |
| 136 | MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), | 136 | MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), |
| 137 | MSG_MAP(BoardPowerCalibration, PPSMC_MSG_BoardPowerCalibration, 0), | ||
| 137 | }; | 138 | }; |
| 138 | 139 | ||
| 139 | static const struct cmn2asic_mapping aldebaran_clk_map[SMU_CLK_COUNT] = { | 140 | static const struct cmn2asic_mapping aldebaran_clk_map[SMU_CLK_COUNT] = { |
| @@ -440,6 +441,39 @@ static int aldebaran_setup_pptable(struct smu_context *smu) · 300 unmodified lines | |||
| 440 | return ret; | 441 | return ret; |
| 441 | } | 442 | } |
| 442 | 443 | ||
| 444 | static bool aldebaran_is_primary(struct smu_context *smu) | ||
| 445 | { | ||
| 446 | struct amdgpu_device *adev = smu->adev; | ||
| 447 | |||
| 448 | if (adev->smuio.funcs && adev->smuio.funcs->get_die_id) | ||
| 449 | return adev->smuio.funcs->get_die_id(adev) == 0; | ||
| 450 | |||
| 451 | return true; | ||
| 452 | } | ||
| 453 | |||
| 454 | static int aldebaran_run_board_btc(struct smu_context *smu) | ||
| 455 | { | ||
| 456 | u32 smu_version; | ||
| 457 | int ret; | ||
| 458 | |||
| 459 | if (!aldebaran_is_primary(smu)) | ||
| 460 | return 0; | ||
| 461 | |||
| 462 | ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); | ||
| 463 | if (ret) { | ||
| 464 | dev_err(smu->adev->dev, "Failed to get smu version!\n"); | ||
| 465 | return ret; | ||
| 466 | } | ||
| 467 | if (smu_version <= 0x00441d00) | ||
| 468 | return 0; | ||
| 469 | |||
| 470 | ret = smu_cmn_send_smc_msg(smu, SMU_MSG_BoardPowerCalibration, NULL); | ||
| 471 | if (ret) | ||
| 472 | dev_err(smu->adev->dev, "Board power calibration failed!\n"); | ||
| 473 | |||
| 474 | return ret; | ||
| 475 | } | ||
| 476 | |||
| 443 | static int aldebaran_run_btc(struct smu_context *smu) | 477 | static int aldebaran_run_btc(struct smu_context *smu) |
| 444 | { | 478 | { |
| 445 | int ret; | 479 | int ret; |
| @@ -447,6 +481,8 @@ static int aldebaran_run_btc(struct smu_context *smu) · 1 unmodified line | |||
| 447 | ret = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL); | 481 | ret = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL); |
| 448 | if (ret) | 482 | if (ret) |
| 449 | dev_err(smu->adev->dev, "RunDcBtc failed!\n"); | 483 | dev_err(smu->adev->dev, "RunDcBtc failed!\n"); |
| 484 | else | ||
| 485 | ret = aldebaran_run_board_btc(smu); | ||
| 450 | 486 | ||
| 451 | return ret; | 487 | return ret; |
| 452 | } | 488 | } |
| @@ -524,16 +560,6 @@ static int aldebaran_freqs_in_same_level(int32_t frequency1, · 71 unmodified lines | |||
| 524 | return (abs(frequency1 - frequency2) <= EPSILON); | 560 | return (abs(frequency1 - frequency2) <= EPSILON); |
| 525 | } | 561 | } |
| 526 | 562 | ||
| 527 | static bool aldebaran_is_primary(struct smu_context *smu) | ||
| 528 | { | ||
| 529 | struct amdgpu_device *adev = smu->adev; | ||
| 530 | |||
| 531 | if (adev->smuio.funcs && adev->smuio.funcs->get_die_id) | ||
| 532 | return adev->smuio.funcs->get_die_id(adev) == 0; | ||
| 533 | |||
| 534 | return true; | ||
| 535 | } | ||
| 536 | |||
| 537 | static int aldebaran_get_smu_metrics_data(struct smu_context *smu, | 563 | static int aldebaran_get_smu_metrics_data(struct smu_context *smu, |
| 538 | MetricsMember_t member, | 564 | MetricsMember_t member, |
| 539 | uint32_t *value) | 565 | uint32_t *value) |
| @@ -834,6 +834,9 @@ long drm_ioctl(struct file *filp, · 833 unmodified lines | |||
| 834 | if (drm_dev_is_unplugged(dev)) | 834 | if (drm_dev_is_unplugged(dev)) |
| 835 | return -ENODEV; | 835 | return -ENODEV; |
| 836 | 836 | ||
| 837 | if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE) | ||
| 838 | return -ENOTTY; | ||
| 839 | |||
| 837 | is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; | 840 | is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; |
| 838 | 841 | ||
| 839 | if (is_driver_ioctl) { | 842 | if (is_driver_ioctl) { |
| @@ -2166,7 +2166,8 @@ static void · 2165 unmodified lines | |||
| 2166 | init_vbt_missing_defaults(struct drm_i915_private *i915) | 2166 | init_vbt_missing_defaults(struct drm_i915_private *i915) |
| 2167 | { | 2167 | { |
| 2168 | enum port port; | 2168 | enum port port; |
| 2169 | int ports = PORT_A | PORT_B | PORT_C | PORT_D | PORT_E | PORT_F; | 2169 | int ports = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | |
| 2170 | BIT(PORT_D) | BIT(PORT_E) | BIT(PORT_F); | ||
| 2170 | 2171 | ||
| 2171 | if (!HAS_DDI(i915) && !IS_CHERRYVIEW(i915)) | 2172 | if (!HAS_DDI(i915) && !IS_CHERRYVIEW(i915)) |
| 2172 | return; | 2173 | return; |
| @@ -11361,13 +11361,19 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) · 11360 unmodified lines | |||
| 11361 | intel_ddi_init(dev_priv, PORT_B); | 11361 | intel_ddi_init(dev_priv, PORT_B); |
| 11362 | intel_ddi_init(dev_priv, PORT_C); | 11362 | intel_ddi_init(dev_priv, PORT_C); |
| 11363 | vlv_dsi_init(dev_priv); | 11363 | vlv_dsi_init(dev_priv); |
| 11364 | } else if (DISPLAY_VER(dev_priv) >= 9) { | 11364 | } else if (DISPLAY_VER(dev_priv) == 10) { |
| 11365 | intel_ddi_init(dev_priv, PORT_A); | 11365 | intel_ddi_init(dev_priv, PORT_A); |
| 11366 | intel_ddi_init(dev_priv, PORT_B); | 11366 | intel_ddi_init(dev_priv, PORT_B); |
| 11367 | intel_ddi_init(dev_priv, PORT_C); | 11367 | intel_ddi_init(dev_priv, PORT_C); |
| 11368 | intel_ddi_init(dev_priv, PORT_D); | 11368 | intel_ddi_init(dev_priv, PORT_D); |
| 11369 | intel_ddi_init(dev_priv, PORT_E); | 11369 | intel_ddi_init(dev_priv, PORT_E); |
| 11370 | intel_ddi_init(dev_priv, PORT_F); | 11370 | intel_ddi_init(dev_priv, PORT_F); |
| 11371 | } else if (DISPLAY_VER(dev_priv) >= 9) { | ||
| 11372 | intel_ddi_init(dev_priv, PORT_A); | ||
| 11373 | intel_ddi_init(dev_priv, PORT_B); | ||
| 11374 | intel_ddi_init(dev_priv, PORT_C); | ||
| 11375 | intel_ddi_init(dev_priv, PORT_D); | ||
| 11376 | intel_ddi_init(dev_priv, PORT_E); | ||
| 11371 | } else if (HAS_DDI(dev_priv)) { | 11377 | } else if (HAS_DDI(dev_priv)) { |
| 11372 | u32 found; | 11378 | u32 found; |
| 11373 | 11379 | ||
| @@ -25,10 +25,8 @@ · 24 unmodified lines | |||
| 25 | #include "i915_gem_clflush.h" | 25 | #include "i915_gem_clflush.h" |
| 26 | #include "i915_gem_context.h" | 26 | #include "i915_gem_context.h" |
| 27 | #include "i915_gem_ioctls.h" | 27 | #include "i915_gem_ioctls.h" |
| 28 | #include "i915_sw_fence_work.h" | ||
| 29 | #include "i915_trace.h" | 28 | #include "i915_trace.h" |
| 30 | #include "i915_user_extensions.h" | 29 | #include "i915_user_extensions.h" |
| 31 | #include "i915_memcpy.h" | ||
| 32 | 30 | ||
| 33 | struct eb_vma { | 31 | struct eb_vma { |
| 34 | struct i915_vma *vma; | 32 | struct i915_vma *vma; |
| @@ -1456,6 +1454,10 @@ static u32 *reloc_gpu(struct i915_execbuffer *eb, · 1421 unmodified lines | |||
| 1456 | int err; | 1454 | int err; |
| 1457 | struct intel_engine_cs *engine = eb->engine; | 1455 | struct intel_engine_cs *engine = eb->engine; |
| 1458 | 1456 | ||
| 1457 | /* If we need to copy for the cmdparser, we will stall anyway */ | ||
| 1458 | if (eb_use_cmdparser(eb)) | ||
| 1459 | return ERR_PTR(-EWOULDBLOCK); | ||
| 1460 | |||
| 1459 | if (!reloc_can_use_engine(engine)) { | 1461 | if (!reloc_can_use_engine(engine)) { |
| 1460 | engine = engine->gt->engine_class[COPY_ENGINE_CLASS][0]; | 1462 | engine = engine->gt->engine_class[COPY_ENGINE_CLASS][0]; |
| 1461 | if (!engine) | 1463 | if (!engine) |
| @@ -2372,217 +2374,6 @@ shadow_batch_pin(struct i915_execbuffer *eb, · 910 unmodified lines | |||
| 2372 | return vma; | 2374 | return vma; |
| 2373 | } | 2375 | } |
| 2374 | 2376 | ||
| 2375 | struct eb_parse_work { | ||
| 2376 | struct dma_fence_work base; | ||
| 2377 | struct intel_engine_cs *engine; | ||
| 2378 | struct i915_vma *batch; | ||
| 2379 | struct i915_vma *shadow; | ||
| 2380 | struct i915_vma *trampoline; | ||
| 2381 | unsigned long batch_offset; | ||
| 2382 | unsigned long batch_length; | ||
| 2383 | unsigned long *jump_whitelist; | ||
| 2384 | const void *batch_map; | ||
| 2385 | void *shadow_map; | ||
| 2386 | }; | ||
| 2387 | |||
| 2388 | static int __eb_parse(struct dma_fence_work *work) | ||
| 2389 | { | ||
| 2390 | struct eb_parse_work *pw = container_of(work, typeof(*pw), base); | ||
| 2391 | int ret; | ||
| 2392 | bool cookie; | ||
| 2393 | |||
| 2394 | cookie = dma_fence_begin_signalling(); | ||
| 2395 | ret = intel_engine_cmd_parser(pw->engine, | ||
| 2396 | pw->batch, | ||
| 2397 | pw->batch_offset, | ||
| 2398 | pw->batch_length, | ||
| 2399 | pw->shadow, | ||
| 2400 | pw->jump_whitelist, | ||
| 2401 | pw->shadow_map, | ||
| 2402 | pw->batch_map); | ||
| 2403 | dma_fence_end_signalling(cookie); | ||
| 2404 | |||
| 2405 | return ret; | ||
| 2406 | } | ||
| 2407 | |||
| 2408 | static void __eb_parse_release(struct dma_fence_work *work) | ||
| 2409 | { | ||
| 2410 | struct eb_parse_work *pw = container_of(work, typeof(*pw), base); | ||
| 2411 | |||
| 2412 | if (!IS_ERR_OR_NULL(pw->jump_whitelist)) | ||
| 2413 | kfree(pw->jump_whitelist); | ||
| 2414 | |||
| 2415 | if (pw->batch_map) | ||
| 2416 | i915_gem_object_unpin_map(pw->batch->obj); | ||
| 2417 | else | ||
| 2418 | i915_gem_object_unpin_pages(pw->batch->obj); | ||
| 2419 | |||
| 2420 | i915_gem_object_unpin_map(pw->shadow->obj); | ||
| 2421 | |||
| 2422 | if (pw->trampoline) | ||
| 2423 | i915_active_release(&pw->trampoline->active); | ||
| 2424 | i915_active_release(&pw->shadow->active); | ||
| 2425 | i915_active_release(&pw->batch->active); | ||
| 2426 | } | ||
| 2427 | |||
| 2428 | static const struct dma_fence_work_ops eb_parse_ops = { | ||
| 2429 | .name = "eb_parse", | ||
| 2430 | .work = __eb_parse, | ||
| 2431 | .release = __eb_parse_release, | ||
| 2432 | }; | ||
| 2433 | |||
| 2434 | static inline int | ||
| 2435 | __parser_mark_active(struct i915_vma *vma, | ||
| 2436 | struct intel_timeline *tl, | ||
| 2437 | struct dma_fence *fence) | ||
| 2438 | { | ||
| 2439 | struct intel_gt_buffer_pool_node *node = vma->private; | ||
| 2440 | |||
| 2441 | return i915_active_ref(&node->active, tl->fence_context, fence); | ||
| 2442 | } | ||
| 2443 | |||
| 2444 | static int | ||
| 2445 | parser_mark_active(struct eb_parse_work *pw, struct intel_timeline *tl) | ||
| 2446 | { | ||
| 2447 | int err; | ||
| 2448 | |||
| 2449 | mutex_lock(&tl->mutex); | ||
| 2450 | |||
| 2451 | err = __parser_mark_active(pw->shadow, tl, &pw->base.dma); | ||
| 2452 | if (err) | ||
| 2453 | goto unlock; | ||
| 2454 | |||
| 2455 | if (pw->trampoline) { | ||
| 2456 | err = __parser_mark_active(pw->trampoline, tl, &pw->base.dma); | ||
| 2457 | if (err) | ||
| 2458 | goto unlock; | ||
| 2459 | } | ||
| 2460 | |||
| 2461 | unlock: | ||
| 2462 | mutex_unlock(&tl->mutex); | ||
| 2463 | return err; | ||
| 2464 | } | ||
| 2465 | |||
| 2466 | static int eb_parse_pipeline(struct i915_execbuffer *eb, | ||
| 2467 | struct i915_vma *shadow, | ||
| 2468 | struct i915_vma *trampoline) | ||
| 2469 | { | ||
| 2470 | struct eb_parse_work *pw; | ||
| 2471 | struct drm_i915_gem_object *batch = eb->batch->vma->obj; | ||
| 2472 | bool needs_clflush; | ||
| 2473 | int err; | ||
| 2474 | |||
| 2475 | GEM_BUG_ON(overflows_type(eb->batch_start_offset, pw->batch_offset)); | ||
| 2476 | GEM_BUG_ON(overflows_type(eb->batch_len, pw->batch_length)); | ||
| 2477 | |||
| 2478 | pw = kzalloc(sizeof(*pw), GFP_KERNEL); | ||
| 2479 | if (!pw) | ||
| 2480 | return -ENOMEM; | ||
| 2481 | |||
| 2482 | err = i915_active_acquire(&eb->batch->vma->active); | ||
| 2483 | if (err) | ||
| 2484 | goto err_free; | ||
| 2485 | |||
| 2486 | err = i915_active_acquire(&shadow->active); | ||
| 2487 | if (err) | ||
| 2488 | goto err_batch; | ||
| 2489 | |||
| 2490 | if (trampoline) { | ||
| 2491 | err = i915_active_acquire(&trampoline->active); | ||
| 2492 | if (err) | ||
| 2493 | goto err_shadow; | ||
| 2494 | } | ||
| 2495 | |||
| 2496 | pw->shadow_map = i915_gem_object_pin_map(shadow->obj, I915_MAP_WB); | ||
| 2497 | if (IS_ERR(pw->shadow_map)) { | ||
| 2498 | err = PTR_ERR(pw->shadow_map); | ||
| 2499 | goto err_trampoline; | ||
| 2500 | } | ||
| 2501 | |||
| 2502 | needs_clflush = | ||
| 2503 | !(batch->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ); | ||
| 2504 | |||
| 2505 | pw->batch_map = ERR_PTR(-ENODEV); | ||
| 2506 | if (needs_clflush && i915_has_memcpy_from_wc()) | ||
| 2507 | pw->batch_map = i915_gem_object_pin_map(batch, I915_MAP_WC); | ||
| 2508 | |||
| 2509 | if (IS_ERR(pw->batch_map)) { | ||
| 2510 | err = i915_gem_object_pin_pages(batch); | ||
| 2511 | if (err) | ||
| 2512 | goto err_unmap_shadow; | ||
| 2513 | pw->batch_map = NULL; | ||
| 2514 | } | ||
| 2515 | |||
| 2516 | pw->jump_whitelist = | ||
| 2517 | intel_engine_cmd_parser_alloc_jump_whitelist(eb->batch_len, | ||
| 2518 | trampoline); | ||
| 2519 | if (IS_ERR(pw->jump_whitelist)) { | ||
| 2520 | err = PTR_ERR(pw->jump_whitelist); | ||
| 2521 | goto err_unmap_batch; | ||
| 2522 | } | ||
| 2523 | |||
| 2524 | dma_fence_work_init(&pw->base, &eb_parse_ops); | ||
| 2525 | |||
| 2526 | pw->engine = eb->engine; | ||
| 2527 | pw->batch = eb->batch->vma; | ||
| 2528 | pw->batch_offset = eb->batch_start_offset; | ||
| 2529 | pw->batch_length = eb->batch_len; | ||
| 2530 | pw->shadow = shadow; | ||
| 2531 | pw->trampoline = trampoline; | ||
| 2532 | |||
| 2533 | /* Mark active refs early for this worker, in case we get interrupted */ | ||
| 2534 | err = parser_mark_active(pw, eb->context->timeline); | ||
| 2535 | if (err) | ||
| 2536 | goto err_commit; | ||
| 2537 | |||
| 2538 | err = dma_resv_reserve_shared(pw->batch->resv, 1); | ||
| 2539 | if (err) | ||
| 2540 | goto err_commit; | ||
| 2541 | |||
| 2542 | err = dma_resv_reserve_shared(shadow->resv, 1); | ||
| 2543 | if (err) | ||
| 2544 | goto err_commit; | ||
| 2545 | |||
| 2546 | /* Wait for all writes (and relocs) into the batch to complete */ | ||
| 2547 | err = i915_sw_fence_await_reservation(&pw->base.chain, | ||
| 2548 | pw->batch->resv, NULL, false, | ||
| 2549 | 0, I915_FENCE_GFP); | ||
| 2550 | if (err < 0) | ||
| 2551 | goto err_commit; | ||
| 2552 | |||
| 2553 | /* Keep the batch alive and unwritten as we parse */ | ||
| 2554 | dma_resv_add_shared_fence(pw->batch->resv, &pw->base.dma); | ||
| 2555 | |||
| 2556 | /* Force execution to wait for completion of the parser */ | ||
| 2557 | dma_resv_add_excl_fence(shadow->resv, &pw->base.dma); | ||
| 2558 | |||
| 2559 | dma_fence_work_commit_imm(&pw->base); | ||
| 2560 | return 0; | ||
| 2561 | |||
| 2562 | err_commit: | ||
| 2563 | i915_sw_fence_set_error_once(&pw->base.chain, err); | ||
| 2564 | dma_fence_work_commit_imm(&pw->base); | ||
| 2565 | return err; | ||
| 2566 | |||
| 2567 | err_unmap_batch: | ||
| 2568 | if (pw->batch_map) | ||
| 2569 | i915_gem_object_unpin_map(batch); | ||
| 2570 | else | ||
| 2571 | i915_gem_object_unpin_pages(batch); | ||
| 2572 | err_unmap_shadow: | ||
| 2573 | i915_gem_object_unpin_map(shadow->obj); | ||
| 2574 | err_trampoline: | ||
| 2575 | if (trampoline) | ||
| 2576 | i915_active_release(&trampoline->active); | ||
| 2577 | err_shadow: | ||
| 2578 | i915_active_release(&shadow->active); | ||
| 2579 | err_batch: | ||
| 2580 | i915_active_release(&eb->batch->vma->active); | ||
| 2581 | err_free: | ||
| 2582 | kfree(pw); | ||
| 2583 | return err; | ||
| 2584 | } | ||
| 2585 | |||
| 2586 | static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i915_vma *vma) | 2377 | static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i915_vma *vma) |
| 2587 | { | 2378 | { |
| 2588 | /* | 2379 | /* |
| @@ -2672,7 +2463,15 @@ static int eb_parse(struct i915_execbuffer *eb) · 83 unmodified lines | |||
| 2672 | goto err_trampoline; | 2463 | goto err_trampoline; |
| 2673 | } | 2464 | } |
| 2674 | 2465 | ||
| 2675 | err = eb_parse_pipeline(eb, shadow, trampoline); | 2466 | err = dma_resv_reserve_shared(shadow->resv, 1); |
| 2467 | if (err) | ||
| 2468 | goto err_trampoline; | ||
| 2469 | |||
| 2470 | err = intel_engine_cmd_parser(eb->engine, | ||
| 2471 | eb->batch->vma, | ||
| 2472 | eb->batch_start_offset, | ||
| 2473 | eb->batch_len, | ||
| 2474 | shadow, trampoline); | ||
| 2676 | if (err) | 2475 | if (err) |
| 2677 | goto err_unpin_batch; | 2476 | goto err_unpin_batch; |
| 2678 | 2477 | ||
| @@ -125,6 +125,10 @@ static int igt_gpu_reloc(void *arg) · 124 unmodified lines | |||
| 125 | intel_gt_pm_get(&eb.i915->gt); | 125 | intel_gt_pm_get(&eb.i915->gt); |
| 126 | 126 | ||
| 127 | for_each_uabi_engine(eb.engine, eb.i915) { | 127 | for_each_uabi_engine(eb.engine, eb.i915) { |
| 128 | if (intel_engine_requires_cmd_parser(eb.engine) || | ||
| 129 | intel_engine_using_cmd_parser(eb.engine)) | ||
| 130 | continue; | ||
| 131 | |||
| 128 | reloc_cache_init(&eb.reloc_cache, eb.i915); | 132 | reloc_cache_init(&eb.reloc_cache, eb.i915); |
| 129 | memset(map, POISON_INUSE, 4096); | 133 | memset(map, POISON_INUSE, 4096); |
| 130 | 134 | ||
| @@ -1977,6 +1977,21 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, · 1976 unmodified lines | |||
| 1977 | if (drm_WARN_ON(&i915->drm, !engine)) | 1977 | if (drm_WARN_ON(&i915->drm, !engine)) |
| 1978 | return -EINVAL; | 1978 | return -EINVAL; |
| 1979 | 1979 | ||
| 1980 | /* | ||
| 1981 | * Due to d3_entered is used to indicate skipping PPGTT invalidation on | ||
| 1982 | * vGPU reset, it's set on D0->D3 on PCI config write, and cleared after | ||
| 1983 | * vGPU reset if in resuming. | ||
| 1984 | * In S0ix exit, the device power state also transite from D3 to D0 as | ||
| 1985 | * S3 resume, but no vGPU reset (triggered by QEMU devic model). After | ||
| 1986 | * S0ix exit, all engines continue to work. However the d3_entered | ||
| 1987 | * remains set which will break next vGPU reset logic (miss the expected | ||
| 1988 | * PPGTT invalidation). | ||
| 1989 | * Engines can only work in D0. Thus the 1st elsp write gives GVT a | ||
| 1990 | * chance to clear d3_entered. | ||
| 1991 | */ | ||
| 1992 | if (vgpu->d3_entered) | ||
| 1993 | vgpu->d3_entered = false; | ||
| 1994 | |||
| 1980 | execlist = &vgpu->submission.execlist[engine->id]; | 1995 | execlist = &vgpu->submission.execlist[engine->id]; |
| 1981 | 1996 | ||
| 1982 | execlist->elsp_dwords.data[3 - execlist->elsp_dwords.index] = data; | 1997 | execlist->elsp_dwords.data[3 - execlist->elsp_dwords.index] = data; |
| @@ -1145,19 +1145,41 @@ find_reg(const struct intel_engine_cs *engine, u32 addr) · 1144 unmodified lines | |||
| 1145 | static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, | 1145 | static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, |
| 1146 | struct drm_i915_gem_object *src_obj, | 1146 | struct drm_i915_gem_object *src_obj, |
| 1147 | unsigned long offset, unsigned long length, | 1147 | unsigned long offset, unsigned long length, |
| 1148 | void *dst, const void *src) | 1148 | bool *needs_clflush_after) |
| 1149 | { | 1149 | { |
| 1150 | bool needs_clflush = | 1150 | unsigned int src_needs_clflush; |
| 1151 | !(src_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ); | 1151 | unsigned int dst_needs_clflush; |
| 1152 | 1152 | void *dst, *src; | |
| 1153 | if (src) { | 1153 | int ret; |
| 1154 | GEM_BUG_ON(!needs_clflush); | 1154 | |
| 1155 | i915_unaligned_memcpy_from_wc(dst, src + offset, length); | 1155 | ret = i915_gem_object_prepare_write(dst_obj, &dst_needs_clflush); |
| 1156 | } else { | 1156 | if (ret) |
| 1157 | struct scatterlist *sg; | 1157 | return ERR_PTR(ret); |
| 1158 | |||
| 1159 | dst = i915_gem_object_pin_map(dst_obj, I915_MAP_WB); | ||
| 1160 | i915_gem_object_finish_access(dst_obj); | ||
| 1161 | if (IS_ERR(dst)) | ||
| 1162 | return dst; | ||
| 1163 | |||
| 1164 | ret = i915_gem_object_prepare_read(src_obj, &src_needs_clflush); | ||
| 1165 | if (ret) { | ||
| 1166 | i915_gem_object_unpin_map(dst_obj); | ||
| 1167 | return ERR_PTR(ret); | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | src = ERR_PTR(-ENODEV); | ||
| 1171 | if (src_needs_clflush && i915_has_memcpy_from_wc()) { | ||
| 1172 | src = i915_gem_object_pin_map(src_obj, I915_MAP_WC); | ||
| 1173 | if (!IS_ERR(src)) { | ||
| 1174 | i915_unaligned_memcpy_from_wc(dst, | ||
| 1175 | src + offset, | ||
| 1176 | length); | ||
| 1177 | i915_gem_object_unpin_map(src_obj); | ||
| 1178 | } | ||
| 1179 | } | ||
| 1180 | if (IS_ERR(src)) { | ||
| 1181 | unsigned long x, n, remain; | ||
| 1158 | void *ptr; | 1182 | void *ptr; |
| 1159 | unsigned int x, sg_ofs; | ||
| 1160 | unsigned long remain; | ||
| 1161 | 1183 | ||
| 1162 | /* | 1184 | /* |
| 1163 | * We can avoid clflushing partial cachelines before the write | 1185 | * We can avoid clflushing partial cachelines before the write |
| @@ -1168,40 +1190,34 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 4 unmodified lines | |||
| 1168 | * validate up to the end of the batch. | 1190 | * validate up to the end of the batch. |
| 1169 | */ | 1191 | */ |
| 1170 | remain = length; | 1192 | remain = length; |
| 1171 | if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) | 1193 | if (dst_needs_clflush & CLFLUSH_BEFORE) |
| 1172 | remain = round_up(remain, | 1194 | remain = round_up(remain, |
| 1173 | boot_cpu_data.x86_clflush_size); | 1195 | boot_cpu_data.x86_clflush_size); |
| 1174 | 1196 | ||
| 1175 | ptr = dst; | 1197 | ptr = dst; |
| 1176 | x = offset_in_page(offset); | 1198 | x = offset_in_page(offset); |
| 1177 | sg = i915_gem_object_get_sg(src_obj, offset >> PAGE_SHIFT, &sg_ofs, false); | 1199 | for (n = offset >> PAGE_SHIFT; remain; n++) { |
| 1178 | 1200 | int len = min(remain, PAGE_SIZE - x); | |
| 1179 | while (remain) { | 1201 | |
| 1180 | unsigned long sg_max = sg->length >> PAGE_SHIFT; | 1202 | src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); |
| 1181 | 1203 | if (src_needs_clflush) | |
| 1182 | for (; remain && sg_ofs < sg_max; sg_ofs++) { | 1204 | drm_clflush_virt_range(src + x, len); |
| 1183 | unsigned long len = min(remain, PAGE_SIZE - x); | 1205 | memcpy(ptr, src + x, len); |
| 1184 | void *map; | 1206 | kunmap_atomic(src); |
| 1185 | 1207 | ||
| 1186 | map = kmap_atomic(nth_page(sg_page(sg), sg_ofs)); | 1208 | ptr += len; |
| 1187 | if (needs_clflush) | 1209 | remain -= len; |
| 1188 | drm_clflush_virt_range(map + x, len); | 1210 | x = 0; |
| 1189 | memcpy(ptr, map + x, len); | ||
| 1190 | kunmap_atomic(map); | ||
| 1191 | |||
| 1192 | ptr += len; | ||
| 1193 | remain -= len; | ||
| 1194 | x = 0; | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | sg_ofs = 0; | ||
| 1198 | sg = sg_next(sg); | ||
| 1199 | } | 1211 | } |
| 1200 | } | 1212 | } |
| 1201 | 1213 | ||
| 1214 | i915_gem_object_finish_access(src_obj); | ||
| 1215 | |||
| 1202 | memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32)); | 1216 | memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32)); |
| 1203 | 1217 | ||
| 1204 | /* dst_obj is returned with vmap pinned */ | 1218 | /* dst_obj is returned with vmap pinned */ |
| 1219 | *needs_clflush_after = dst_needs_clflush & CLFLUSH_AFTER; | ||
| 1220 | |||
| 1205 | return dst; | 1221 | return dst; |
| 1206 | } | 1222 | } |
| 1207 | 1223 | ||
| @@ -1360,6 +1376,9 @@ static int check_bbstart(u32 *cmd, u32 offset, u32 length, · 152 unmodified lines | |||
| 1360 | if (target_cmd_index == offset) | 1376 | if (target_cmd_index == offset) |
| 1361 | return 0; | 1377 | return 0; |
| 1362 | 1378 | ||
| 1379 | if (IS_ERR(jump_whitelist)) | ||
| 1380 | return PTR_ERR(jump_whitelist); | ||
| 1381 | |||
| 1363 | if (!test_bit(target_cmd_index, jump_whitelist)) { | 1382 | if (!test_bit(target_cmd_index, jump_whitelist)) { |
| 1364 | DRM_DEBUG("CMD: BB_START to 0x%llx not a previously executed cmd\n", | 1383 | DRM_DEBUG("CMD: BB_START to 0x%llx not a previously executed cmd\n", |
| 1365 | jump_target); | 1384 | jump_target); |
| @@ -1369,28 +1388,10 @@ static int check_bbstart(u32 *cmd, u32 offset, u32 length, · 3 unmodified lines | |||
| 1369 | return 0; | 1388 | return 0; |
| 1370 | } | 1389 | } |
| 1371 | 1390 | ||
| 1372 | /** | 1391 | static unsigned long *alloc_whitelist(u32 batch_length) |
| 1373 | * intel_engine_cmd_parser_alloc_jump_whitelist() - preallocate jump whitelist for intel_engine_cmd_parser() | ||
| 1374 | * @batch_length: length of the commands in batch_obj | ||
| 1375 | * @trampoline: Whether jump trampolines are used. | ||
| 1376 | * | ||
| 1377 | * Preallocates a jump whitelist for parsing the cmd buffer in intel_engine_cmd_parser(). | ||
| 1378 | * This has to be preallocated, because the command parser runs in signaling context, | ||
| 1379 | * and may not allocate any memory. | ||
| 1380 | * | ||
| 1381 | * Return: NULL or pointer to a jump whitelist, or ERR_PTR() on failure. Use | ||
| 1382 | * IS_ERR() to check for errors. Must bre freed() with kfree(). | ||
| 1383 | * | ||
| 1384 | * NULL is a valid value, meaning no allocation was required. | ||
| 1385 | */ | ||
| 1386 | unsigned long *intel_engine_cmd_parser_alloc_jump_whitelist(u32 batch_length, | ||
| 1387 | bool trampoline) | ||
| 1388 | { | 1392 | { |
| 1389 | unsigned long *jmp; | 1393 | unsigned long *jmp; |
| 1390 | 1394 | ||
| 1391 | if (trampoline) | ||
| 1392 | return NULL; | ||
| 1393 | |||
| 1394 | /* | 1395 | /* |
| 1395 | * We expect batch_length to be less than 256KiB for known users, | 1396 | * We expect batch_length to be less than 256KiB for known users, |
| 1396 | * i.e. we need at most an 8KiB bitmap allocation which should be | 1397 | * i.e. we need at most an 8KiB bitmap allocation which should be |
| @@ -1415,9 +1416,7 @@ unsigned long *intel_engine_cmd_parser_alloc_jump_whitelist(u32 batch_length, · 18 unmodified lines | |||
| 1415 | * @batch_offset: byte offset in the batch at which execution starts | 1416 | * @batch_offset: byte offset in the batch at which execution starts |
| 1416 | * @batch_length: length of the commands in batch_obj | 1417 | * @batch_length: length of the commands in batch_obj |
| 1417 | * @shadow: validated copy of the batch buffer in question | 1418 | * @shadow: validated copy of the batch buffer in question |
| 1418 | * @jump_whitelist: buffer preallocated with intel_engine_cmd_parser_alloc_jump_whitelist() | 1419 | * @trampoline: true if we need to trampoline into privileged execution |
| 1419 | * @shadow_map: mapping to @shadow vma | ||
| 1420 | * @batch_map: mapping to @batch vma | ||
| 1421 | * | 1420 | * |
| 1422 | * Parses the specified batch buffer looking for privilege violations as | 1421 | * Parses the specified batch buffer looking for privilege violations as |
| 1423 | * described in the overview. | 1422 | * described in the overview. |
| @@ -1425,21 +1424,21 @@ unsigned long *intel_engine_cmd_parser_alloc_jump_whitelist(u32 batch_length, · 1 unmodified line | |||
| 1425 | * Return: non-zero if the parser finds violations or otherwise fails; -EACCES | 1424 | * Return: non-zero if the parser finds violations or otherwise fails; -EACCES |
| 1426 | * if the batch appears legal but should use hardware parsing | 1425 | * if the batch appears legal but should use hardware parsing |
| 1427 | */ | 1426 | */ |
| 1427 | |||
| 1428 | int intel_engine_cmd_parser(struct intel_engine_cs *engine, | 1428 | int intel_engine_cmd_parser(struct intel_engine_cs *engine, |
| 1429 | struct i915_vma *batch, | 1429 | struct i915_vma *batch, |
| 1430 | unsigned long batch_offset, | 1430 | unsigned long batch_offset, |
| 1431 | unsigned long batch_length, | 1431 | unsigned long batch_length, |
| 1432 | struct i915_vma *shadow, | 1432 | struct i915_vma *shadow, |
| 1433 | unsigned long *jump_whitelist, | 1433 | bool trampoline) |
| 1434 | void *shadow_map, | ||
| 1435 | const void *batch_map) | ||
| 1436 | { | 1434 | { |
| 1437 | u32 *cmd, *batch_end, offset = 0; | 1435 | u32 *cmd, *batch_end, offset = 0; |
| 1438 | struct drm_i915_cmd_descriptor default_desc = noop_desc; | 1436 | struct drm_i915_cmd_descriptor default_desc = noop_desc; |
| 1439 | const struct drm_i915_cmd_descriptor *desc = &default_desc; | 1437 | const struct drm_i915_cmd_descriptor *desc = &default_desc; |
| 1438 | bool needs_clflush_after = false; | ||
| 1439 | unsigned long *jump_whitelist; | ||
| 1440 | u64 batch_addr, shadow_addr; | 1440 | u64 batch_addr, shadow_addr; |
| 1441 | int ret = 0; | 1441 | int ret = 0; |
| 1442 | bool trampoline = !jump_whitelist; | ||
| 1443 | 1442 | ||
| 1444 | GEM_BUG_ON(!IS_ALIGNED(batch_offset, sizeof(*cmd))); | 1443 | GEM_BUG_ON(!IS_ALIGNED(batch_offset, sizeof(*cmd))); |
| 1445 | GEM_BUG_ON(!IS_ALIGNED(batch_length, sizeof(*cmd))); | 1444 | GEM_BUG_ON(!IS_ALIGNED(batch_length, sizeof(*cmd))); |
| @@ -1447,8 +1446,18 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, · 1 unmodified line | |||
| 1447 | batch->size)); | 1446 | batch->size)); |
| 1448 | GEM_BUG_ON(!batch_length); | 1447 | GEM_BUG_ON(!batch_length); |
| 1449 | 1448 | ||
| 1450 | cmd = copy_batch(shadow->obj, batch->obj, batch_offset, batch_length, | 1449 | cmd = copy_batch(shadow->obj, batch->obj, |
| 1451 | shadow_map, batch_map); | 1450 | batch_offset, batch_length, |
| 1451 | &needs_clflush_after); | ||
| 1452 | if (IS_ERR(cmd)) { | ||
| 1453 | DRM_DEBUG("CMD: Failed to copy batch\n"); | ||
| 1454 | return PTR_ERR(cmd); | ||
| 1455 | } | ||
| 1456 | |||
| 1457 | jump_whitelist = NULL; | ||
| 1458 | if (!trampoline) | ||
| 1459 | /* Defer failure until attempted use */ | ||
| 1460 | jump_whitelist = alloc_whitelist(batch_length); | ||
| 1452 | 1461 | ||
| 1453 | shadow_addr = gen8_canonical_addr(shadow->node.start); | 1462 | shadow_addr = gen8_canonical_addr(shadow->node.start); |
| 1454 | batch_addr = gen8_canonical_addr(batch->node.start + batch_offset); | 1463 | batch_addr = gen8_canonical_addr(batch->node.start + batch_offset); |
| @@ -1549,6 +1558,9 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, · 94 unmodified lines | |||
| 1549 | 1558 | ||
| 1550 | i915_gem_object_flush_map(shadow->obj); | 1559 | i915_gem_object_flush_map(shadow->obj); |
| 1551 | 1560 | ||
| 1561 | if (!IS_ERR_OR_NULL(jump_whitelist)) | ||
| 1562 | kfree(jump_whitelist); | ||
| 1563 | i915_gem_object_unpin_map(shadow->obj); | ||
| 1552 | return ret; | 1564 | return ret; |
| 1553 | } | 1565 | } |
| 1554 | 1566 | ||
| @@ -1906,17 +1906,12 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type); · 1905 unmodified lines | |||
| 1906 | int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv); | 1906 | int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv); |
| 1907 | int intel_engine_init_cmd_parser(struct intel_engine_cs *engine); | 1907 | int intel_engine_init_cmd_parser(struct intel_engine_cs *engine); |
| 1908 | void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine); | 1908 | void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine); |
| 1909 | unsigned long *intel_engine_cmd_parser_alloc_jump_whitelist(u32 batch_length, | ||
| 1910 | bool trampoline); | ||
| 1911 | |||
| 1912 | int intel_engine_cmd_parser(struct intel_engine_cs *engine, | 1909 | int intel_engine_cmd_parser(struct intel_engine_cs *engine, |
| 1913 | struct i915_vma *batch, | 1910 | struct i915_vma *batch, |
| 1914 | unsigned long batch_offset, | 1911 | unsigned long batch_offset, |
| 1915 | unsigned long batch_length, | 1912 | unsigned long batch_length, |
| 1916 | struct i915_vma *shadow, | 1913 | struct i915_vma *shadow, |
| 1917 | unsigned long *jump_whitelist, | 1914 | bool trampoline); |
| 1918 | void *shadow_map, | ||
| 1919 | const void *batch_map); | ||
| 1920 | #define I915_CMD_PARSER_TRAMPOLINE_SIZE 8 | 1915 | #define I915_CMD_PARSER_TRAMPOLINE_SIZE 8 |
| 1921 | 1916 | ||
| 1922 | /* intel_device_info.c */ | 1917 | /* intel_device_info.c */ |
| @@ -1426,10 +1426,8 @@ i915_request_await_execution(struct i915_request *rq, · 1425 unmodified lines | |||
| 1426 | 1426 | ||
| 1427 | do { | 1427 | do { |
| 1428 | fence = *child++; | 1428 | fence = *child++; |
| 1429 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { | 1429 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) |
| 1430 | i915_sw_fence_set_error_once(&rq->submit, fence->error); | ||
| 1431 | continue; | 1430 | continue; |
| 1432 | } | ||
| 1433 | 1431 | ||
| 1434 | if (fence->context == rq->fence.context) | 1432 | if (fence->context == rq->fence.context) |
| 1435 | continue; | 1433 | continue; |
| @@ -1527,10 +1525,8 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence) · 91 unmodified lines | |||
| 1527 | 1525 | ||
| 1528 | do { | 1526 | do { |
| 1529 | fence = *child++; | 1527 | fence = *child++; |
| 1530 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { | 1528 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) |
| 1531 | i915_sw_fence_set_error_once(&rq->submit, fence->error); | ||
| 1532 | continue; | 1529 | continue; |
| 1533 | } | ||
| 1534 | 1530 | ||
| 1535 | /* | 1531 | /* |
| 1536 | * Requests on the same timeline are explicitly ordered, along | 1532 | * Requests on the same timeline are explicitly ordered, along |
| @@ -325,7 +325,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) · 324 unmodified lines | |||
| 325 | info->pipe_mask &= ~BIT(PIPE_C); | 325 | info->pipe_mask &= ~BIT(PIPE_C); |
| 326 | info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C); | 326 | info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C); |
| 327 | } | 327 | } |
| 328 | } else if (HAS_DISPLAY(dev_priv) && GRAPHICS_VER(dev_priv) >= 9) { | 328 | } else if (HAS_DISPLAY(dev_priv) && DISPLAY_VER(dev_priv) >= 9) { |
| 329 | u32 dfsm = intel_de_read(dev_priv, SKL_DFSM); | 329 | u32 dfsm = intel_de_read(dev_priv, SKL_DFSM); |
| 330 | 330 | ||
| 331 | if (dfsm & SKL_DFSM_PIPE_A_DISABLE) { | 331 | if (dfsm & SKL_DFSM_PIPE_A_DISABLE) { |
| @@ -340,7 +340,8 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) · 8 unmodified lines | |||
| 340 | info->pipe_mask &= ~BIT(PIPE_C); | 340 | info->pipe_mask &= ~BIT(PIPE_C); |
| 341 | info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C); | 341 | info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C); |
| 342 | } | 342 | } |
| 343 | if (GRAPHICS_VER(dev_priv) >= 12 && | 343 | |
| 344 | if (DISPLAY_VER(dev_priv) >= 12 && | ||
| 344 | (dfsm & TGL_DFSM_PIPE_D_DISABLE)) { | 345 | (dfsm & TGL_DFSM_PIPE_D_DISABLE)) { |
| 345 | info->pipe_mask &= ~BIT(PIPE_D); | 346 | info->pipe_mask &= ~BIT(PIPE_D); |
| 346 | info->cpu_transcoder_mask &= ~BIT(TRANSCODER_D); | 347 | info->cpu_transcoder_mask &= ~BIT(TRANSCODER_D); |
| @@ -352,10 +353,10 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) · 5 unmodified lines | |||
| 352 | if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE) | 353 | if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE) |
| 353 | info->display.has_fbc = 0; | 354 | info->display.has_fbc = 0; |
| 354 | 355 | ||
| 355 | if (GRAPHICS_VER(dev_priv) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE)) | 356 | if (DISPLAY_VER(dev_priv) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE)) |
| 356 | info->display.has_dmc = 0; | 357 | info->display.has_dmc = 0; |
| 357 | 358 | ||
| 358 | if (GRAPHICS_VER(dev_priv) >= 10 && | 359 | if (DISPLAY_VER(dev_priv) >= 10 && |
| 359 | (dfsm & CNL_DFSM_DISPLAY_DSC_DISABLE)) | 360 | (dfsm & CNL_DFSM_DISPLAY_DSC_DISABLE)) |
| 360 | info->display.has_dsc = 0; | 361 | info->display.has_dsc = 0; |
| 361 | } | 362 | } |
| @@ -296,7 +296,7 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = { · 295 unmodified lines | |||
| 296 | static const struct dpu_mdp_cfg sm8250_mdp[] = { | 296 | static const struct dpu_mdp_cfg sm8250_mdp[] = { |
| 297 | { | 297 | { |
| 298 | .name = "top_0", .id = MDP_TOP, | 298 | .name = "top_0", .id = MDP_TOP, |
| 299 | .base = 0x0, .len = 0x45C, | 299 | .base = 0x0, .len = 0x494, |
| 300 | .features = 0, | 300 | .features = 0, |
| 301 | .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ | 301 | .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ |
| 302 | .clk_ctrls[DPU_CLK_CTRL_VIG0] = { | 302 | .clk_ctrls[DPU_CLK_CTRL_VIG0] = { |
| @@ -771,6 +771,7 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog) · 770 unmodified lines | |||
| 771 | dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, | 771 | dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, |
| 772 | dp_catalog->width_blanking); | 772 | dp_catalog->width_blanking); |
| 773 | dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active); | 773 | dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active); |
| 774 | dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0); | ||
| 774 | return 0; | 775 | return 0; |
| 775 | } | 776 | } |
| 776 | 777 | ||
| @@ -1526,7 +1526,7 @@ static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) · 1525 unmodified lines | |||
| 1526 | * running. Add the global reset just before disabling the | 1526 | * running. Add the global reset just before disabling the |
| 1527 | * link clocks and core clocks. | 1527 | * link clocks and core clocks. |
| 1528 | */ | 1528 | */ |
| 1529 | ret = dp_ctrl_off(&ctrl->dp_ctrl); | 1529 | ret = dp_ctrl_off_link_stream(&ctrl->dp_ctrl); |
| 1530 | if (ret) { | 1530 | if (ret) { |
| 1531 | DRM_ERROR("failed to disable DP controller\n"); | 1531 | DRM_ERROR("failed to disable DP controller\n"); |
| 1532 | return ret; | 1532 | return ret; |
| @@ -219,6 +219,7 @@ static int dp_display_bind(struct device *dev, struct device *master, · 218 unmodified lines | |||
| 219 | goto end; | 219 | goto end; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | dp->aux->drm_dev = drm; | ||
| 222 | rc = dp_aux_register(dp->aux); | 223 | rc = dp_aux_register(dp->aux); |
| 223 | if (rc) { | 224 | if (rc) { |
| 224 | DRM_ERROR("DRM DP AUX register failed\n"); | 225 | DRM_ERROR("DRM DP AUX register failed\n"); |
| @@ -1311,6 +1312,10 @@ static int dp_pm_resume(struct device *dev) · 1086 unmodified lines | |||
| 1311 | else | 1312 | else |
| 1312 | dp->dp_display.is_connected = false; | 1313 | dp->dp_display.is_connected = false; |
| 1313 | 1314 | ||
| 1315 | dp_display_handle_plugged_change(g_dp_display, | ||
| 1316 | dp->dp_display.is_connected); | ||
| 1317 | |||
| 1318 | |||
| 1314 | mutex_unlock(&dp->event_mutex); | 1319 | mutex_unlock(&dp->event_mutex); |
| 1315 | 1320 | ||
| 1316 | return 0; | 1321 | return 0; |
| @@ -142,6 +142,9 @@ static const struct iommu_flush_ops null_tlb_ops = { · 141 unmodified lines | |||
| 142 | .tlb_add_page = msm_iommu_tlb_add_page, | 142 | .tlb_add_page = msm_iommu_tlb_add_page, |
| 143 | }; | 143 | }; |
| 144 | 144 | ||
| 145 | static int msm_fault_handler(struct iommu_domain *domain, struct device *dev, | ||
| 146 | unsigned long iova, int flags, void *arg); | ||
| 147 | |||
| 145 | struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent) | 148 | struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent) |
| 146 | { | 149 | { |
| 147 | struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(parent->dev); | 150 | struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(parent->dev); |
| @@ -157,6 +160,13 @@ struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent) · 9 unmodified lines | |||
| 157 | if (!ttbr1_cfg) | 160 | if (!ttbr1_cfg) |
| 158 | return ERR_PTR(-ENODEV); | 161 | return ERR_PTR(-ENODEV); |
| 159 | 162 | ||
| 163 | /* | ||
| 164 | * Defer setting the fault handler until we have a valid adreno_smmu | ||
| 165 | * to avoid accidentially installing a GPU specific fault handler for | ||
| 166 | * the display's iommu | ||
| 167 | */ | ||
| 168 | iommu_set_fault_handler(iommu->domain, msm_fault_handler, iommu); | ||
| 169 | |||
| 160 | pagetable = kzalloc(sizeof(*pagetable), GFP_KERNEL); | 170 | pagetable = kzalloc(sizeof(*pagetable), GFP_KERNEL); |
| 161 | if (!pagetable) | 171 | if (!pagetable) |
| 162 | return ERR_PTR(-ENOMEM); | 172 | return ERR_PTR(-ENOMEM); |
| @@ -300,7 +310,6 @@ struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain) · 137 unmodified lines | |||
| 300 | 310 | ||
| 301 | iommu->domain = domain; | 311 | iommu->domain = domain; |
| 302 | msm_mmu_init(&iommu->base, dev, &funcs, MSM_MMU_IOMMU); | 312 | msm_mmu_init(&iommu->base, dev, &funcs, MSM_MMU_IOMMU); |
| 303 | iommu_set_fault_handler(domain, msm_fault_handler, iommu); | ||
| 304 | 313 | ||
| 305 | atomic_set(&iommu->pagetables, 0); | 314 | atomic_set(&iommu->pagetables, 0); |
| 306 | 315 | ||
| @@ -149,6 +149,8 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) · 148 unmodified lines | |||
| 149 | */ | 149 | */ |
| 150 | if (bo->base.dev) | 150 | if (bo->base.dev) |
| 151 | drm_gem_object_release(&bo->base); | 151 | drm_gem_object_release(&bo->base); |
| 152 | else | ||
| 153 | dma_resv_fini(&bo->base._resv); | ||
| 152 | 154 | ||
| 153 | kfree(nvbo); | 155 | kfree(nvbo); |
| 154 | } | 156 | } |
| @@ -330,6 +332,10 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, · 175 unmodified lines | |||
| 330 | if (IS_ERR(nvbo)) | 332 | if (IS_ERR(nvbo)) |
| 331 | return PTR_ERR(nvbo); | 333 | return PTR_ERR(nvbo); |
| 332 | 334 | ||
| 335 | nvbo->bo.base.size = size; | ||
| 336 | dma_resv_init(&nvbo->bo.base._resv); | ||
| 337 | drm_vma_node_reset(&nvbo->bo.base.vma_node); | ||
| 338 | |||
| 333 | ret = nouveau_bo_init(nvbo, size, align, domain, sg, robj); | 339 | ret = nouveau_bo_init(nvbo, size, align, domain, sg, robj); |
| 334 | if (ret) | 340 | if (ret) |
| 335 | return ret; | 341 | return ret; |
| @@ -447,7 +447,6 @@ static int rpi_touchscreen_remove(struct i2c_client *i2c) · 446 unmodified lines | |||
| 447 | drm_panel_remove(&ts->base); | 447 | drm_panel_remove(&ts->base); |
| 448 | 448 | ||
| 449 | mipi_dsi_device_unregister(ts->dsi); | 449 | mipi_dsi_device_unregister(ts->dsi); |
| 450 | kfree(ts->dsi); | ||
| 451 | 450 | ||
| 452 | return 0; | 451 | return 0; |
| 453 | } | 452 | } |
| @@ -4166,7 +4166,7 @@ static const struct drm_display_mode yes_optoelectronics_ytc700tlag_05_201c_mode · 4165 unmodified lines | |||
| 4166 | static const struct panel_desc yes_optoelectronics_ytc700tlag_05_201c = { | 4166 | static const struct panel_desc yes_optoelectronics_ytc700tlag_05_201c = { |
| 4167 | .modes = &yes_optoelectronics_ytc700tlag_05_201c_mode, | 4167 | .modes = &yes_optoelectronics_ytc700tlag_05_201c_mode, |
| 4168 | .num_modes = 1, | 4168 | .num_modes = 1, |
| 4169 | .bpc = 6, | 4169 | .bpc = 8, |
| 4170 | .size = { | 4170 | .size = { |
| 4171 | .width = 154, | 4171 | .width = 154, |
| 4172 | .height = 90, | 4172 | .height = 90, |
| @@ -102,6 +102,9 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, · 101 unmodified lines | |||
| 102 | return; | 102 | return; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | if (!mem) | ||
| 106 | return; | ||
| 107 | |||
| 105 | man = ttm_manager_type(bdev, mem->mem_type); | 108 | man = ttm_manager_type(bdev, mem->mem_type); |
| 106 | list_move_tail(&bo->lru, &man->lru[bo->priority]); | 109 | list_move_tail(&bo->lru, &man->lru[bo->priority]); |
| 107 | 110 | ||
| @@ -63,6 +63,9 @@ int ttm_mem_io_reserve(struct ttm_device *bdev, · 62 unmodified lines | |||
| 63 | void ttm_mem_io_free(struct ttm_device *bdev, | 63 | void ttm_mem_io_free(struct ttm_device *bdev, |
| 64 | struct ttm_resource *mem) | 64 | struct ttm_resource *mem) |
| 65 | { | 65 | { |
| 66 | if (!mem) | ||
| 67 | return; | ||
| 68 | |||
| 66 | if (!mem->bus.offset && !mem->bus.addr) | 69 | if (!mem->bus.offset && !mem->bus.addr) |
| 67 | return; | 70 | return; |
| 68 | 71 | ||
| @@ -44,6 +44,8 @@ static unsigned ttm_glob_use_count; · 43 unmodified lines | |||
| 44 | struct ttm_global ttm_glob; | 44 | struct ttm_global ttm_glob; |
| 45 | EXPORT_SYMBOL(ttm_glob); | 45 | EXPORT_SYMBOL(ttm_glob); |
| 46 | 46 | ||
| 47 | struct dentry *ttm_debugfs_root; | ||
| 48 | |||
| 47 | static void ttm_global_release(void) | 49 | static void ttm_global_release(void) |
| 48 | { | 50 | { |
| 49 | struct ttm_global *glob = &ttm_glob; | 51 | struct ttm_global *glob = &ttm_glob; |
| @@ -53,6 +55,7 @@ static void ttm_global_release(void) · 3 unmodified lines | |||
| 53 | goto out; | 55 | goto out; |
| 54 | 56 | ||
| 55 | ttm_pool_mgr_fini(); | 57 | ttm_pool_mgr_fini(); |
| 58 | debugfs_remove(ttm_debugfs_root); | ||
| 56 | 59 | ||
| 57 | __free_page(glob->dummy_read_page); | 60 | __free_page(glob->dummy_read_page); |
| 58 | memset(glob, 0, sizeof(*glob)); | 61 | memset(glob, 0, sizeof(*glob)); |
| @@ -73,6 +76,13 @@ static int ttm_global_init(void) · 14 unmodified lines | |||
| 73 | 76 | ||
| 74 | si_meminfo(&si); | 77 | si_meminfo(&si); |
| 75 | 78 | ||
| 79 | ttm_debugfs_root = debugfs_create_dir("ttm", NULL); | ||
| 80 | if (IS_ERR(ttm_debugfs_root)) { | ||
| 81 | ret = PTR_ERR(ttm_debugfs_root); | ||
| 82 | ttm_debugfs_root = NULL; | ||
| 83 | goto out; | ||
| 84 | } | ||
| 85 | |||
| 76 | /* Limit the number of pages in the pool to about 50% of the total | 86 | /* Limit the number of pages in the pool to about 50% of the total |
| 77 | * system memory. | 87 | * system memory. |
| 78 | */ | 88 | */ |
| @@ -100,6 +110,10 @@ static int ttm_global_init(void) · 21 unmodified lines | |||
| 100 | debugfs_create_atomic_t("buffer_objects", 0444, ttm_debugfs_root, | 110 | debugfs_create_atomic_t("buffer_objects", 0444, ttm_debugfs_root, |
| 101 | &glob->bo_count); | 111 | &glob->bo_count); |
| 102 | out: | 112 | out: |
| 113 | if (ret && ttm_debugfs_root) | ||
| 114 | debugfs_remove(ttm_debugfs_root); | ||
| 115 | if (ret) | ||
| 116 | --ttm_glob_use_count; | ||
| 103 | mutex_unlock(&ttm_global_mutex); | 117 | mutex_unlock(&ttm_global_mutex); |
| 104 | return ret; | 118 | return ret; |
| 105 | } | 119 | } |
| @@ -72,22 +72,6 @@ pgprot_t ttm_prot_from_caching(enum ttm_caching caching, pgprot_t tmp) · 71 unmodified lines | |||
| 72 | return tmp; | 72 | return tmp; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | struct dentry *ttm_debugfs_root; | ||
| 76 | |||
| 77 | static int __init ttm_init(void) | ||
| 78 | { | ||
| 79 | ttm_debugfs_root = debugfs_create_dir("ttm", NULL); | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | static void __exit ttm_exit(void) | ||
| 84 | { | ||
| 85 | debugfs_remove(ttm_debugfs_root); | ||
| 86 | } | ||
| 87 | |||
| 88 | module_init(ttm_init); | ||
| 89 | module_exit(ttm_exit); | ||
| 90 | |||
| 91 | MODULE_AUTHOR("Thomas Hellstrom, Jerome Glisse"); | 75 | MODULE_AUTHOR("Thomas Hellstrom, Jerome Glisse"); |
| 92 | MODULE_DESCRIPTION("TTM memory manager subsystem (for DRM device)"); | 76 | MODULE_DESCRIPTION("TTM memory manager subsystem (for DRM device)"); |
| 93 | MODULE_LICENSE("GPL and additional rights"); | 77 | MODULE_LICENSE("GPL and additional rights"); |
| @@ -1857,38 +1857,46 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) · 1856 unmodified lines | |||
| 1857 | vc4_hdmi_cec_update_clk_div(vc4_hdmi); | 1857 | vc4_hdmi_cec_update_clk_div(vc4_hdmi); |
| 1858 | 1858 | ||
| 1859 | if (vc4_hdmi->variant->external_irq_controller) { | 1859 | if (vc4_hdmi->variant->external_irq_controller) { |
| 1860 | ret = devm_request_threaded_irq(&pdev->dev, | 1860 | ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-rx"), |
| 1861 | platform_get_irq_byname(pdev, "cec-rx"), | 1861 | vc4_cec_irq_handler_rx_bare, |
| 1862 | vc4_cec_irq_handler_rx_bare, | 1862 | vc4_cec_irq_handler_rx_thread, 0, |
| 1863 | vc4_cec_irq_handler_rx_thread, 0, | 1863 | "vc4 hdmi cec rx", vc4_hdmi); |
| 1864 | "vc4 hdmi cec rx", vc4_hdmi); | ||
| 1865 | if (ret) | 1864 | if (ret) |
| 1866 | goto err_delete_cec_adap; | 1865 | goto err_delete_cec_adap; |
| 1867 | 1866 | ||
| 1868 | ret = devm_request_threaded_irq(&pdev->dev, | 1867 | ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-tx"), |
| 1869 | platform_get_irq_byname(pdev, "cec-tx"), | 1868 | vc4_cec_irq_handler_tx_bare, |
| 1870 | vc4_cec_irq_handler_tx_bare, | 1869 | vc4_cec_irq_handler_tx_thread, 0, |
| 1871 | vc4_cec_irq_handler_tx_thread, 0, | 1870 | "vc4 hdmi cec tx", vc4_hdmi); |
| 1872 | "vc4 hdmi cec tx", vc4_hdmi); | ||
| 1873 | if (ret) | 1871 | if (ret) |
| 1874 | goto err_delete_cec_adap; | 1872 | goto err_remove_cec_rx_handler; |
| 1875 | } else { | 1873 | } else { |
| 1876 | HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff); | 1874 | HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff); |
| 1877 | 1875 | ||
| 1878 | ret = devm_request_threaded_irq(&pdev->dev, platform_get_irq(pdev, 0), | 1876 | ret = request_threaded_irq(platform_get_irq(pdev, 0), |
| 1879 | vc4_cec_irq_handler, | 1877 | vc4_cec_irq_handler, |
| 1880 | vc4_cec_irq_handler_thread, 0, | 1878 | vc4_cec_irq_handler_thread, 0, |
| 1881 | "vc4 hdmi cec", vc4_hdmi); | 1879 | "vc4 hdmi cec", vc4_hdmi); |
| 1882 | if (ret) | 1880 | if (ret) |
| 1883 | goto err_delete_cec_adap; | 1881 | goto err_delete_cec_adap; |
| 1884 | } | 1882 | } |
| 1885 | 1883 | ||
| 1886 | ret = cec_register_adapter(vc4_hdmi->cec_adap, &pdev->dev); | 1884 | ret = cec_register_adapter(vc4_hdmi->cec_adap, &pdev->dev); |
| 1887 | if (ret < 0) | 1885 | if (ret < 0) |
| 1888 | goto err_delete_cec_adap; | 1886 | goto err_remove_handlers; |
| 1889 | 1887 | ||
| 1890 | return 0; | 1888 | return 0; |
| 1891 | 1889 | ||
| 1890 | err_remove_handlers: | ||
| 1891 | if (vc4_hdmi->variant->external_irq_controller) | ||
| 1892 | free_irq(platform_get_irq_byname(pdev, "cec-tx"), vc4_hdmi); | ||
| 1893 | else | ||
| 1894 | free_irq(platform_get_irq(pdev, 0), vc4_hdmi); | ||
| 1895 | |||
| 1896 | err_remove_cec_rx_handler: | ||
| 1897 | if (vc4_hdmi->variant->external_irq_controller) | ||
| 1898 | free_irq(platform_get_irq_byname(pdev, "cec-rx"), vc4_hdmi); | ||
| 1899 | |||
| 1892 | err_delete_cec_adap: | 1900 | err_delete_cec_adap: |
| 1893 | cec_delete_adapter(vc4_hdmi->cec_adap); | 1901 | cec_delete_adapter(vc4_hdmi->cec_adap); |
| 1894 | 1902 | ||
| @@ -1897,6 +1905,15 @@ err_delete_cec_adap: · 2 unmodified lines | |||
| 1897 | 1905 | ||
| 1898 | static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) | 1906 | static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) |
| 1899 | { | 1907 | { |
| 1908 | struct platform_device *pdev = vc4_hdmi->pdev; | ||
| 1909 | |||
| 1910 | if (vc4_hdmi->variant->external_irq_controller) { | ||
| 1911 | free_irq(platform_get_irq_byname(pdev, "cec-rx"), vc4_hdmi); | ||
| 1912 | free_irq(platform_get_irq_byname(pdev, "cec-tx"), vc4_hdmi); | ||
| 1913 | } else { | ||
| 1914 | free_irq(platform_get_irq(pdev, 0), vc4_hdmi); | ||
| 1915 | } | ||
| 1916 | |||
| 1900 | cec_unregister_adapter(vc4_hdmi->cec_adap); | 1917 | cec_unregister_adapter(vc4_hdmi->cec_adap); |
| 1901 | } | 1918 | } |
| 1902 | #else | 1919 | #else |
| @@ -576,7 +576,7 @@ config HID_LOGITECH_HIDPP · 575 unmodified lines | |||
| 576 | depends on HID_LOGITECH | 576 | depends on HID_LOGITECH |
| 577 | select POWER_SUPPLY | 577 | select POWER_SUPPLY |
| 578 | help | 578 | help |
| 579 | Support for Logitech devices relyingon the HID++ Logitech specification | 579 | Support for Logitech devices relying on the HID++ Logitech specification |
| 580 | 580 | ||
| 581 | Say Y if you want support for Logitech devices relying on the HID++ | 581 | Say Y if you want support for Logitech devices relying on the HID++ |
| 582 | specification. Such devices are the various Logitech Touchpads (T650, | 582 | specification. Such devices are the various Logitech Touchpads (T650, |
| @@ -58,7 +58,7 @@ static void amd_stop_sensor_v2(struct amd_mp2_dev *privdata, u16 sensor_idx) · 57 unmodified lines | |||
| 58 | cmd_base.cmd_v2.sensor_id = sensor_idx; | 58 | cmd_base.cmd_v2.sensor_id = sensor_idx; |
| 59 | cmd_base.cmd_v2.length = 16; | 59 | cmd_base.cmd_v2.length = 16; |
| 60 | 60 | ||
| 61 | writeq(0x0, privdata->mmio + AMD_C2P_MSG2); | 61 | writeq(0x0, privdata->mmio + AMD_C2P_MSG1); |
| 62 | writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); | 62 | writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| @@ -501,6 +501,8 @@ static const struct hid_device_id apple_devices[] = { · 500 unmodified lines | |||
| 501 | APPLE_RDESC_JIS }, | 501 | APPLE_RDESC_JIS }, |
| 502 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), | 502 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), |
| 503 | .driver_data = APPLE_HAS_FN }, | 503 | .driver_data = APPLE_HAS_FN }, |
| 504 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), | ||
| 505 | .driver_data = APPLE_HAS_FN }, | ||
| 504 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), | 506 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), |
| 505 | .driver_data = APPLE_HAS_FN }, | 507 | .driver_data = APPLE_HAS_FN }, |
| 506 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), | 508 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), |
| @@ -485,9 +485,6 @@ static void asus_kbd_backlight_set(struct led_classdev *led_cdev, · 484 unmodified lines | |||
| 485 | { | 485 | { |
| 486 | struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, | 486 | struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, |
| 487 | cdev); | 487 | cdev); |
| 488 | if (led->brightness == brightness) | ||
| 489 | return; | ||
| 490 | |||
| 491 | led->brightness = brightness; | 488 | led->brightness = brightness; |
| 492 | schedule_work(&led->work); | 489 | schedule_work(&led->work); |
| 493 | } | 490 | } |
| @@ -742,7 +742,7 @@ static int ft260_is_interface_enabled(struct hid_device *hdev) · 741 unmodified lines | |||
| 742 | int ret; | 742 | int ret; |
| 743 | 743 | ||
| 744 | ret = ft260_get_system_config(hdev, &cfg); | 744 | ret = ft260_get_system_config(hdev, &cfg); |
| 745 | if (ret) | 745 | if (ret < 0) |
| 746 | return ret; | 746 | return ret; |
| 747 | 747 | ||
| 748 | ft260_dbg("interface: 0x%02x\n", interface); | 748 | ft260_dbg("interface: 0x%02x\n", interface); |
| @@ -754,23 +754,16 @@ static int ft260_is_interface_enabled(struct hid_device *hdev) · 5 unmodified lines | |||
| 754 | switch (cfg.chip_mode) { | 754 | switch (cfg.chip_mode) { |
| 755 | case FT260_MODE_ALL: | 755 | case FT260_MODE_ALL: |
| 756 | case FT260_MODE_BOTH: | 756 | case FT260_MODE_BOTH: |
| 757 | if (interface == 1) { | 757 | if (interface == 1) |
| 758 | hid_info(hdev, "uart interface is not supported\n"); | 758 | hid_info(hdev, "uart interface is not supported\n"); |
| 759 | return 0; | 759 | else |
| 760 | } | 760 | ret = 1; |
| 761 | ret = 1; | ||
| 762 | break; | 761 | break; |
| 763 | case FT260_MODE_UART: | 762 | case FT260_MODE_UART: |
| 764 | if (interface == 0) { | 763 | hid_info(hdev, "uart interface is not supported\n"); |
| 765 | hid_info(hdev, "uart is unsupported on interface 0\n"); | ||
| 766 | ret = 0; | ||
| 767 | } | ||
| 768 | break; | 764 | break; |
| 769 | case FT260_MODE_I2C: | 765 | case FT260_MODE_I2C: |
| 770 | if (interface == 1) { | 766 | ret = 1; |
| 771 | hid_info(hdev, "i2c is unsupported on interface 1\n"); | ||
| 772 | ret = 0; | ||
| 773 | } | ||
| 774 | break; | 767 | break; |
| 775 | } | 768 | } |
| 776 | return ret; | 769 | return ret; |
| @@ -785,7 +778,7 @@ static int ft260_byte_show(struct hid_device *hdev, int id, u8 *cfg, int len, · 8 unmodified lines | |||
| 785 | if (ret < 0) | 778 | if (ret < 0) |
| 786 | return ret; | 779 | return ret; |
| 787 | 780 | ||
| 788 | return scnprintf(buf, PAGE_SIZE, "%hi\n", *field); | 781 | return scnprintf(buf, PAGE_SIZE, "%d\n", *field); |
| 789 | } | 782 | } |
| 790 | 783 | ||
| 791 | static int ft260_word_show(struct hid_device *hdev, int id, u8 *cfg, int len, | 784 | static int ft260_word_show(struct hid_device *hdev, int id, u8 *cfg, int len, |
| @@ -797,7 +790,7 @@ static int ft260_word_show(struct hid_device *hdev, int id, u8 *cfg, int len, · 5 unmodified lines | |||
| 797 | if (ret < 0) | 790 | if (ret < 0) |
| 798 | return ret; | 791 | return ret; |
| 799 | 792 | ||
| 800 | return scnprintf(buf, PAGE_SIZE, "%hi\n", le16_to_cpu(*field)); | 793 | return scnprintf(buf, PAGE_SIZE, "%d\n", le16_to_cpu(*field)); |
| 801 | } | 794 | } |
| 802 | 795 | ||
| 803 | #define FT260_ATTR_SHOW(name, reptype, id, type, func) \ | 796 | #define FT260_ATTR_SHOW(name, reptype, id, type, func) \ |
| @@ -1004,11 +997,9 @@ err_hid_stop: · 200 unmodified lines | |||
| 1004 | 997 | ||
| 1005 | static void ft260_remove(struct hid_device *hdev) | 998 | static void ft260_remove(struct hid_device *hdev) |
| 1006 | { | 999 | { |
| 1007 | int ret; | ||
| 1008 | struct ft260_device *dev = hid_get_drvdata(hdev); | 1000 | struct ft260_device *dev = hid_get_drvdata(hdev); |
| 1009 | 1001 | ||
| 1010 | ret = ft260_is_interface_enabled(hdev); | 1002 | if (!dev) |
| 1011 | if (ret <= 0) | ||
| 1012 | return; | 1003 | return; |
| 1013 | 1004 | ||
| 1014 | sysfs_remove_group(&hdev->dev.kobj, &ft260_attr_group); | 1005 | sysfs_remove_group(&hdev->dev.kobj, &ft260_attr_group); |
| @@ -784,6 +784,17 @@ static void hid_ishtp_cl_reset_handler(struct work_struct *work) · 783 unmodified lines | |||
| 784 | } | 784 | } |
| 785 | } | 785 | } |
| 786 | 786 | ||
| 787 | static void hid_ishtp_cl_resume_handler(struct work_struct *work) | ||
| 788 | { | ||
| 789 | struct ishtp_cl_data *client_data = container_of(work, struct ishtp_cl_data, resume_work); | ||
| 790 | struct ishtp_cl *hid_ishtp_cl = client_data->hid_ishtp_cl; | ||
| 791 | |||
| 792 | if (ishtp_wait_resume(ishtp_get_ishtp_device(hid_ishtp_cl))) { | ||
| 793 | client_data->suspended = false; | ||
| 794 | wake_up_interruptible(&client_data->ishtp_resume_wait); | ||
| 795 | } | ||
| 796 | } | ||
| 797 | |||
| 787 | ishtp_print_log ishtp_hid_print_trace; | 798 | ishtp_print_log ishtp_hid_print_trace; |
| 788 | 799 | ||
| 789 | /** | 800 | /** |
| @@ -822,6 +833,8 @@ static int hid_ishtp_cl_probe(struct ishtp_cl_device *cl_device) · 32 unmodified lines | |||
| 822 | init_waitqueue_head(&client_data->ishtp_resume_wait); | 833 | init_waitqueue_head(&client_data->ishtp_resume_wait); |
| 823 | 834 | ||
| 824 | INIT_WORK(&client_data->work, hid_ishtp_cl_reset_handler); | 835 | INIT_WORK(&client_data->work, hid_ishtp_cl_reset_handler); |
| 836 | INIT_WORK(&client_data->resume_work, hid_ishtp_cl_resume_handler); | ||
| 837 | |||
| 825 | 838 | ||
| 826 | ishtp_hid_print_trace = ishtp_trace_callback(cl_device); | 839 | ishtp_hid_print_trace = ishtp_trace_callback(cl_device); |
| 827 | 840 | ||
| @@ -921,7 +934,7 @@ static int hid_ishtp_cl_resume(struct device *device) · 93 unmodified lines | |||
| 921 | 934 | ||
| 922 | hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__, | 935 | hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__, |
| 923 | hid_ishtp_cl); | 936 | hid_ishtp_cl); |
| 924 | client_data->suspended = false; | 937 | schedule_work(&client_data->resume_work); |
| 925 | return 0; | 938 | return 0; |
| 926 | } | 939 | } |
| 927 | 940 | ||
| @@ -135,6 +135,7 @@ struct ishtp_cl_data { · 134 unmodified lines | |||
| 135 | int multi_packet_cnt; | 135 | int multi_packet_cnt; |
| 136 | 136 | ||
| 137 | struct work_struct work; | 137 | struct work_struct work; |
| 138 | struct work_struct resume_work; | ||
| 138 | struct ishtp_cl_device *cl_device; | 139 | struct ishtp_cl_device *cl_device; |
| 139 | }; | 140 | }; |
| 140 | 141 | ||
| @@ -314,13 +314,6 @@ static int ishtp_cl_device_resume(struct device *dev) · 313 unmodified lines | |||
| 314 | if (!device) | 314 | if (!device) |
| 315 | return 0; | 315 | return 0; |
| 316 | 316 | ||
| 317 | /* | ||
| 318 | * When ISH needs hard reset, it is done asynchrnously, hence bus | ||
| 319 | * resume will be called before full ISH resume | ||
| 320 | */ | ||
| 321 | if (device->ishtp_dev->resume_flag) | ||
| 322 | return 0; | ||
| 323 | |||
| 324 | driver = to_ishtp_cl_driver(dev->driver); | 317 | driver = to_ishtp_cl_driver(dev->driver); |
| 325 | if (driver && driver->driver.pm) { | 318 | if (driver && driver->driver.pm) { |
| 326 | if (driver->driver.pm->resume) | 319 | if (driver->driver.pm->resume) |
| @@ -849,6 +842,28 @@ struct device *ishtp_device(struct ishtp_cl_device *device) · 522 unmodified lines | |||
| 849 | } | 842 | } |
| 850 | EXPORT_SYMBOL(ishtp_device); | 843 | EXPORT_SYMBOL(ishtp_device); |
| 851 | 844 | ||
| 845 | /** | ||
| 846 | * ishtp_wait_resume() - Wait for IPC resume | ||
| 847 | * | ||
| 848 | * Wait for IPC resume | ||
| 849 | * | ||
| 850 | * Return: resume complete or not | ||
| 851 | */ | ||
| 852 | bool ishtp_wait_resume(struct ishtp_device *dev) | ||
| 853 | { | ||
| 854 | /* 50ms to get resume response */ | ||
| 855 | #define WAIT_FOR_RESUME_ACK_MS 50 | ||
| 856 | |||
| 857 | /* Waiting to get resume response */ | ||
| 858 | if (dev->resume_flag) | ||
| 859 | wait_event_interruptible_timeout(dev->resume_wait, | ||
| 860 | !dev->resume_flag, | ||
| 861 | msecs_to_jiffies(WAIT_FOR_RESUME_ACK_MS)); | ||
| 862 | |||
| 863 | return (!dev->resume_flag); | ||
| 864 | } | ||
| 865 | EXPORT_SYMBOL_GPL(ishtp_wait_resume); | ||
| 866 | |||
| 852 | /** | 867 | /** |
| 853 | * ishtp_get_pci_device() - Return PCI device dev pointer | 868 | * ishtp_get_pci_device() - Return PCI device dev pointer |
| 854 | * This interface is used to return PCI device pointer | 869 | * This interface is used to return PCI device pointer |
| @@ -38,7 +38,7 @@ config USB_HIDDEV · 37 unmodified lines | |||
| 38 | help | 38 | help |
| 39 | Say Y here if you want to support HID devices (from the USB | 39 | Say Y here if you want to support HID devices (from the USB |
| 40 | specification standpoint) that aren't strictly user interface | 40 | specification standpoint) that aren't strictly user interface |
| 41 | devices, like monitor controls and Uninterruptable Power Supplies. | 41 | devices, like monitor controls and Uninterruptible Power Supplies. |
| 42 | 42 | ||
| 43 | This module supports these devices separately using a separate | 43 | This module supports these devices separately using a separate |
| 44 | event interface on /dev/usb/hiddevX (char 180:96 to 180:111). | 44 | event interface on /dev/usb/hiddevX (char 180:96 to 180:111). |
| @@ -2548,6 +2548,9 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, · 2547 unmodified lines | |||
| 2548 | int slot; | 2548 | int slot; |
| 2549 | 2549 | ||
| 2550 | slot = input_mt_get_slot_by_key(input, hid_data->id); | 2550 | slot = input_mt_get_slot_by_key(input, hid_data->id); |
| 2551 | if (slot < 0) | ||
| 2552 | return; | ||
| 2553 | |||
| 2551 | input_mt_slot(input, slot); | 2554 | input_mt_slot(input, slot); |
| 2552 | input_mt_report_slot_state(input, MT_TOOL_FINGER, prox); | 2555 | input_mt_report_slot_state(input, MT_TOOL_FINGER, prox); |
| 2553 | } | 2556 | } |
| @@ -3831,7 +3834,7 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, · 1277 unmodified lines | |||
| 3831 | wacom_wac->shared->touch->product == 0xF6) { | 3834 | wacom_wac->shared->touch->product == 0xF6) { |
| 3832 | input_dev->evbit[0] |= BIT_MASK(EV_SW); | 3835 | input_dev->evbit[0] |= BIT_MASK(EV_SW); |
| 3833 | __set_bit(SW_MUTE_DEVICE, input_dev->swbit); | 3836 | __set_bit(SW_MUTE_DEVICE, input_dev->swbit); |
| 3834 | wacom_wac->shared->has_mute_touch_switch = true; | 3837 | wacom_wac->has_mute_touch_switch = true; |
| 3835 | } | 3838 | } |
| 3836 | fallthrough; | 3839 | fallthrough; |
| 3837 | 3840 | ||
| @@ -605,6 +605,17 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) · 604 unmodified lines | |||
| 605 | */ | 605 | */ |
| 606 | mutex_lock(&vmbus_connection.channel_mutex); | 606 | mutex_lock(&vmbus_connection.channel_mutex); |
| 607 | 607 | ||
| 608 | list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { | ||
| 609 | if (guid_equal(&channel->offermsg.offer.if_type, | ||
| 610 | &newchannel->offermsg.offer.if_type) && | ||
| 611 | guid_equal(&channel->offermsg.offer.if_instance, | ||
| 612 | &newchannel->offermsg.offer.if_instance)) { | ||
| 613 | fnew = false; | ||
| 614 | newchannel->primary_channel = channel; | ||
| 615 | break; | ||
| 616 | } | ||
| 617 | } | ||
| 618 | |||
| 608 | init_vp_index(newchannel); | 619 | init_vp_index(newchannel); |
| 609 | 620 | ||
| 610 | /* Remember the channels that should be cleaned up upon suspend. */ | 621 | /* Remember the channels that should be cleaned up upon suspend. */ |
| @@ -617,16 +628,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) · 6 unmodified lines | |||
| 617 | */ | 628 | */ |
| 618 | atomic_dec(&vmbus_connection.offer_in_progress); | 629 | atomic_dec(&vmbus_connection.offer_in_progress); |
| 619 | 630 | ||
| 620 | list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { | ||
| 621 | if (guid_equal(&channel->offermsg.offer.if_type, | ||
| 622 | &newchannel->offermsg.offer.if_type) && | ||
| 623 | guid_equal(&channel->offermsg.offer.if_instance, | ||
| 624 | &newchannel->offermsg.offer.if_instance)) { | ||
| 625 | fnew = false; | ||
| 626 | break; | ||
| 627 | } | ||
| 628 | } | ||
| 629 | |||
| 630 | if (fnew) { | 631 | if (fnew) { |
| 631 | list_add_tail(&newchannel->listentry, | 632 | list_add_tail(&newchannel->listentry, |
| 632 | &vmbus_connection.chn_list); | 633 | &vmbus_connection.chn_list); |
| @@ -647,7 +648,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) · 14 unmodified lines | |||
| 647 | /* | 648 | /* |
| 648 | * Process the sub-channel. | 649 | * Process the sub-channel. |
| 649 | */ | 650 | */ |
| 650 | newchannel->primary_channel = channel; | ||
| 651 | list_add_tail(&newchannel->sc_list, &channel->sc_list); | 651 | list_add_tail(&newchannel->sc_list, &channel->sc_list); |
| 652 | } | 652 | } |
| 653 | 653 | ||
| @@ -683,6 +683,30 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) · 29 unmodified lines | |||
| 683 | queue_work(wq, &newchannel->add_channel_work); | 683 | queue_work(wq, &newchannel->add_channel_work); |
| 684 | } | 684 | } |
| 685 | 685 | ||
| 686 | /* | ||
| 687 | * Check if CPUs used by other channels of the same device. | ||
| 688 | * It should only be called by init_vp_index(). | ||
| 689 | */ | ||
| 690 | static bool hv_cpuself_used(u32 cpu, struct vmbus_channel *chn) | ||
| 691 | { | ||
| 692 | struct vmbus_channel *primary = chn->primary_channel; | ||
| 693 | struct vmbus_channel *sc; | ||
| 694 | |||
| 695 | lockdep_assert_held(&vmbus_connection.channel_mutex); | ||
| 696 | |||
| 697 | if (!primary) | ||
| 698 | return false; | ||
| 699 | |||
| 700 | if (primary->target_cpu == cpu) | ||
| 701 | return true; | ||
| 702 | |||
| 703 | list_for_each_entry(sc, &primary->sc_list, sc_list) | ||
| 704 | if (sc != chn && sc->target_cpu == cpu) | ||
| 705 | return true; | ||
| 706 | |||
| 707 | return false; | ||
| 708 | } | ||
| 709 | |||
| 686 | /* | 710 | /* |
| 687 | * We use this state to statically distribute the channel interrupt load. | 711 | * We use this state to statically distribute the channel interrupt load. |
| 688 | */ | 712 | */ |
| @@ -702,6 +726,7 @@ static int next_numa_node_id; · 13 unmodified lines | |||
| 702 | static void init_vp_index(struct vmbus_channel *channel) | 726 | static void init_vp_index(struct vmbus_channel *channel) |
| 703 | { | 727 | { |
| 704 | bool perf_chn = hv_is_perf_channel(channel); | 728 | bool perf_chn = hv_is_perf_channel(channel); |
| 729 | u32 i, ncpu = num_online_cpus(); | ||
| 705 | cpumask_var_t available_mask; | 730 | cpumask_var_t available_mask; |
| 706 | struct cpumask *alloced_mask; | 731 | struct cpumask *alloced_mask; |
| 707 | u32 target_cpu; | 732 | u32 target_cpu; |
| @@ -724,31 +749,38 @@ static void init_vp_index(struct vmbus_channel *channel) · 16 unmodified lines | |||
| 724 | return; | 749 | return; |
| 725 | } | 750 | } |
| 726 | 751 | ||
| 727 | while (true) { | 752 | for (i = 1; i <= ncpu + 1; i++) { |
| 728 | numa_node = next_numa_node_id++; | 753 | while (true) { |
| 729 | if (numa_node == nr_node_ids) { | 754 | numa_node = next_numa_node_id++; |
| 730 | next_numa_node_id = 0; | 755 | if (numa_node == nr_node_ids) { |
| 731 | continue; | 756 | next_numa_node_id = 0; |
| 757 | continue; | ||
| 758 | } | ||
| 759 | if (cpumask_empty(cpumask_of_node(numa_node))) | ||
| 760 | continue; | ||
| 761 | break; | ||
| 762 | } | ||
| 763 | alloced_mask = &hv_context.hv_numa_map[numa_node]; | ||
| 764 | |||
| 765 | if (cpumask_weight(alloced_mask) == | ||
| 766 | cpumask_weight(cpumask_of_node(numa_node))) { | ||
| 767 | /* | ||
| 768 | * We have cycled through all the CPUs in the node; | ||
| 769 | * reset the alloced map. | ||
| 770 | */ | ||
| 771 | cpumask_clear(alloced_mask); | ||
| 732 | } | 772 | } |
| 733 | if (cpumask_empty(cpumask_of_node(numa_node))) | ||
| 734 | continue; | ||
| 735 | break; | ||
| 736 | } | ||
| 737 | alloced_mask = &hv_context.hv_numa_map[numa_node]; | ||
| 738 | 773 | ||
| 739 | if (cpumask_weight(alloced_mask) == | 774 | cpumask_xor(available_mask, alloced_mask, |
| 740 | cpumask_weight(cpumask_of_node(numa_node))) { | 775 | cpumask_of_node(numa_node)); |
| 741 | /* | ||
| 742 | * We have cycled through all the CPUs in the node; | ||
| 743 | * reset the alloced map. | ||
| 744 | */ | ||
| 745 | cpumask_clear(alloced_mask); | ||
| 746 | } | ||
| 747 | 776 | ||
| 748 | cpumask_xor(available_mask, alloced_mask, cpumask_of_node(numa_node)); | 777 | target_cpu = cpumask_first(available_mask); |
| 778 | cpumask_set_cpu(target_cpu, alloced_mask); | ||
| 749 | 779 | ||
| 750 | target_cpu = cpumask_first(available_mask); | 780 | if (channel->offermsg.offer.sub_channel_index >= ncpu || |
| 751 | cpumask_set_cpu(target_cpu, alloced_mask); | 781 | i > ncpu || !hv_cpuself_used(target_cpu, channel)) |
| 782 | break; | ||
| 783 | } | ||
| 752 | 784 | ||
| 753 | channel->target_cpu = target_cpu; | 785 | channel->target_cpu = target_cpu; |
| 754 | 786 | ||
| @@ -635,8 +635,8 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) · 634 unmodified lines | |||
| 635 | 635 | ||
| 636 | status = readb(i2c->base + MPC_I2C_SR); | 636 | status = readb(i2c->base + MPC_I2C_SR); |
| 637 | if (status & CSR_MIF) { | 637 | if (status & CSR_MIF) { |
| 638 | /* Read again to allow register to stabilise */ | 638 | /* Wait up to 100us for transfer to properly complete */ |
| 639 | status = readb(i2c->base + MPC_I2C_SR); | 639 | readb_poll_timeout(i2c->base + MPC_I2C_SR, status, !(status & CSR_MCF), 0, 100); |
| 640 | writeb(0, i2c->base + MPC_I2C_SR); | 640 | writeb(0, i2c->base + MPC_I2C_SR); |
| 641 | mpc_i2c_do_intr(i2c, status); | 641 | mpc_i2c_do_intr(i2c, status); |
| 642 | return IRQ_HANDLED; | 642 | return IRQ_HANDLED; |
| @@ -120,6 +120,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev, u8 wqe_mode) · 119 unmodified lines | |||
| 120 | if (!chip_ctx) | 120 | if (!chip_ctx) |
| 121 | return -ENOMEM; | 121 | return -ENOMEM; |
| 122 | chip_ctx->chip_num = bp->chip_num; | 122 | chip_ctx->chip_num = bp->chip_num; |
| 123 | chip_ctx->hw_stats_size = bp->hw_ring_stats_size; | ||
| 123 | 124 | ||
| 124 | rdev->chip_ctx = chip_ctx; | 125 | rdev->chip_ctx = chip_ctx; |
| 125 | /* rest members to follow eventually */ | 126 | /* rest members to follow eventually */ |
| @@ -550,6 +551,7 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev, · 424 unmodified lines | |||
| 550 | dma_addr_t dma_map, | 551 | dma_addr_t dma_map, |
| 551 | u32 *fw_stats_ctx_id) | 552 | u32 *fw_stats_ctx_id) |
| 552 | { | 553 | { |
| 554 | struct bnxt_qplib_chip_ctx *chip_ctx = rdev->chip_ctx; | ||
| 553 | struct hwrm_stat_ctx_alloc_output resp = {0}; | 555 | struct hwrm_stat_ctx_alloc_output resp = {0}; |
| 554 | struct hwrm_stat_ctx_alloc_input req = {0}; | 556 | struct hwrm_stat_ctx_alloc_input req = {0}; |
| 555 | struct bnxt_en_dev *en_dev = rdev->en_dev; | 557 | struct bnxt_en_dev *en_dev = rdev->en_dev; |
| @@ -566,7 +568,7 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev, · 10 unmodified lines | |||
| 566 | bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_ALLOC, -1, -1); | 568 | bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_ALLOC, -1, -1); |
| 567 | req.update_period_ms = cpu_to_le32(1000); | 569 | req.update_period_ms = cpu_to_le32(1000); |
| 568 | req.stats_dma_addr = cpu_to_le64(dma_map); | 570 | req.stats_dma_addr = cpu_to_le64(dma_map); |
| 569 | req.stats_dma_length = cpu_to_le16(sizeof(struct ctx_hw_stats_ext)); | 571 | req.stats_dma_length = cpu_to_le16(chip_ctx->hw_stats_size); |
| 570 | req.stat_ctx_flags = STAT_CTX_ALLOC_REQ_STAT_CTX_FLAGS_ROCE; | 572 | req.stat_ctx_flags = STAT_CTX_ALLOC_REQ_STAT_CTX_FLAGS_ROCE; |
| 571 | bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, | 573 | bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, |
| 572 | sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); | 574 | sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); |
| @@ -56,6 +56,7 @@ · 55 unmodified lines | |||
| 56 | static void bnxt_qplib_free_stats_ctx(struct pci_dev *pdev, | 56 | static void bnxt_qplib_free_stats_ctx(struct pci_dev *pdev, |
| 57 | struct bnxt_qplib_stats *stats); | 57 | struct bnxt_qplib_stats *stats); |
| 58 | static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev, | 58 | static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev, |
| 59 | struct bnxt_qplib_chip_ctx *cctx, | ||
| 59 | struct bnxt_qplib_stats *stats); | 60 | struct bnxt_qplib_stats *stats); |
| 60 | 61 | ||
| 61 | /* PBL */ | 62 | /* PBL */ |
| @@ -559,7 +560,7 @@ int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res, · 497 unmodified lines | |||
| 559 | goto fail; | 560 | goto fail; |
| 560 | stats_alloc: | 561 | stats_alloc: |
| 561 | /* Stats */ | 562 | /* Stats */ |
| 562 | rc = bnxt_qplib_alloc_stats_ctx(res->pdev, &ctx->stats); | 563 | rc = bnxt_qplib_alloc_stats_ctx(res->pdev, res->cctx, &ctx->stats); |
| 563 | if (rc) | 564 | if (rc) |
| 564 | goto fail; | 565 | goto fail; |
| 565 | 566 | ||
| @@ -889,15 +890,12 @@ static void bnxt_qplib_free_stats_ctx(struct pci_dev *pdev, · 323 unmodified lines | |||
| 889 | } | 890 | } |
| 890 | 891 | ||
| 891 | static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev, | 892 | static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev, |
| 893 | struct bnxt_qplib_chip_ctx *cctx, | ||
| 892 | struct bnxt_qplib_stats *stats) | 894 | struct bnxt_qplib_stats *stats) |
| 893 | { | 895 | { |
| 894 | memset(stats, 0, sizeof(*stats)); | 896 | memset(stats, 0, sizeof(*stats)); |
| 895 | stats->fw_id = -1; | 897 | stats->fw_id = -1; |
| 896 | /* 128 byte aligned context memory is required only for 57500. | 898 | stats->size = cctx->hw_stats_size; |
| 897 | * However making this unconditional, it does not harm previous | ||
| 898 | * generation. | ||
| 899 | */ | ||
| 900 | stats->size = ALIGN(sizeof(struct ctx_hw_stats), 128); | ||
| 901 | stats->dma = dma_alloc_coherent(&pdev->dev, stats->size, | 899 | stats->dma = dma_alloc_coherent(&pdev->dev, stats->size, |
| 902 | &stats->dma_map, GFP_KERNEL); | 900 | &stats->dma_map, GFP_KERNEL); |
| 903 | if (!stats->dma) { | 901 | if (!stats->dma) { |
| @@ -54,6 +54,7 @@ struct bnxt_qplib_chip_ctx { · 53 unmodified lines | |||
| 54 | u16 chip_num; | 54 | u16 chip_num; |
| 55 | u8 chip_rev; | 55 | u8 chip_rev; |
| 56 | u8 chip_metal; | 56 | u8 chip_metal; |
| 57 | u16 hw_stats_size; | ||
| 57 | struct bnxt_qplib_drv_modes modes; | 58 | struct bnxt_qplib_drv_modes modes; |
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| @@ -2845,7 +2845,7 @@ static u64 irdma_sc_decode_fpm_commit(struct irdma_sc_dev *dev, __le64 *buf, · 2844 unmodified lines | |||
| 2845 | * parses fpm commit info and copy base value | 2845 | * parses fpm commit info and copy base value |
| 2846 | * of hmc objects in hmc_info | 2846 | * of hmc objects in hmc_info |
| 2847 | */ | 2847 | */ |
| 2848 | static enum irdma_status_code | 2848 | static void |
| 2849 | irdma_sc_parse_fpm_commit_buf(struct irdma_sc_dev *dev, __le64 *buf, | 2849 | irdma_sc_parse_fpm_commit_buf(struct irdma_sc_dev *dev, __le64 *buf, |
| 2850 | struct irdma_hmc_obj_info *info, u32 *sd) | 2850 | struct irdma_hmc_obj_info *info, u32 *sd) |
| 2851 | { | 2851 | { |
| @@ -2915,7 +2915,6 @@ irdma_sc_parse_fpm_commit_buf(struct irdma_sc_dev *dev, __le64 *buf, · 63 unmodified lines | |||
| 2915 | else | 2915 | else |
| 2916 | *sd = (u32)(size >> 21); | 2916 | *sd = (u32)(size >> 21); |
| 2917 | 2917 | ||
| 2918 | return 0; | ||
| 2919 | } | 2918 | } |
| 2920 | 2919 | ||
| 2921 | /** | 2920 | /** |
| @@ -4187,11 +4186,9 @@ enum irdma_status_code irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq, · 1265 unmodified lines | |||
| 4187 | * @dev: sc device struct | 4186 | * @dev: sc device struct |
| 4188 | * @count: allocate count | 4187 | * @count: allocate count |
| 4189 | */ | 4188 | */ |
| 4190 | enum irdma_status_code irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, u32 count) | 4189 | void irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, u32 count) |
| 4191 | { | 4190 | { |
| 4192 | writel(count, dev->hw_regs[IRDMA_AEQALLOC]); | 4191 | writel(count, dev->hw_regs[IRDMA_AEQALLOC]); |
| 4193 | |||
| 4194 | return 0; | ||
| 4195 | } | 4192 | } |
| 4196 | 4193 | ||
| 4197 | /** | 4194 | /** |
| @@ -4434,9 +4431,9 @@ static enum irdma_status_code irdma_sc_cfg_iw_fpm(struct irdma_sc_dev *dev, · 236 unmodified lines | |||
| 4434 | ret_code = irdma_sc_commit_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id, | 4431 | ret_code = irdma_sc_commit_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id, |
| 4435 | &commit_fpm_mem, true, wait_type); | 4432 | &commit_fpm_mem, true, wait_type); |
| 4436 | if (!ret_code) | 4433 | if (!ret_code) |
| 4437 | ret_code = irdma_sc_parse_fpm_commit_buf(dev, dev->fpm_commit_buf, | 4434 | irdma_sc_parse_fpm_commit_buf(dev, dev->fpm_commit_buf, |
| 4438 | hmc_info->hmc_obj, | 4435 | hmc_info->hmc_obj, |
| 4439 | &hmc_info->sd_table.sd_cnt); | 4436 | &hmc_info->sd_table.sd_cnt); |
| 4440 | print_hex_dump_debug("HMC: COMMIT FPM BUFFER", DUMP_PREFIX_OFFSET, 16, | 4437 | print_hex_dump_debug("HMC: COMMIT FPM BUFFER", DUMP_PREFIX_OFFSET, 16, |
| 4441 | 8, commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE, | 4438 | 8, commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE, |
| 4442 | false); | 4439 | false); |
| @@ -1920,7 +1920,7 @@ enum irdma_status_code irdma_ctrl_init_hw(struct irdma_pci_f *rf) · 1919 unmodified lines | |||
| 1920 | * irdma_set_hw_rsrc - set hw memory resources. | 1920 | * irdma_set_hw_rsrc - set hw memory resources. |
| 1921 | * @rf: RDMA PCI function | 1921 | * @rf: RDMA PCI function |
| 1922 | */ | 1922 | */ |
| 1923 | static u32 irdma_set_hw_rsrc(struct irdma_pci_f *rf) | 1923 | static void irdma_set_hw_rsrc(struct irdma_pci_f *rf) |
| 1924 | { | 1924 | { |
| 1925 | rf->allocated_qps = (void *)(rf->mem_rsrc + | 1925 | rf->allocated_qps = (void *)(rf->mem_rsrc + |
| 1926 | (sizeof(struct irdma_arp_entry) * rf->arp_table_size)); | 1926 | (sizeof(struct irdma_arp_entry) * rf->arp_table_size)); |
| @@ -1937,8 +1937,6 @@ static u32 irdma_set_hw_rsrc(struct irdma_pci_f *rf) · 10 unmodified lines | |||
| 1937 | spin_lock_init(&rf->arp_lock); | 1937 | spin_lock_init(&rf->arp_lock); |
| 1938 | spin_lock_init(&rf->qptable_lock); | 1938 | spin_lock_init(&rf->qptable_lock); |
| 1939 | spin_lock_init(&rf->qh_list_lock); | 1939 | spin_lock_init(&rf->qh_list_lock); |
| 1940 | |||
| 1941 | return 0; | ||
| 1942 | } | 1940 | } |
| 1943 | 1941 | ||
| 1944 | /** | 1942 | /** |
| @@ -2000,9 +1998,7 @@ u32 irdma_initialize_hw_rsrc(struct irdma_pci_f *rf) · 55 unmodified lines | |||
| 2000 | 1998 | ||
| 2001 | rf->arp_table = (struct irdma_arp_entry *)rf->mem_rsrc; | 1999 | rf->arp_table = (struct irdma_arp_entry *)rf->mem_rsrc; |
| 2002 | 2000 | ||
| 2003 | ret = irdma_set_hw_rsrc(rf); | 2001 | irdma_set_hw_rsrc(rf); |
| 2004 | if (ret) | ||
| 2005 | goto set_hw_rsrc_fail; | ||
| 2006 | 2002 | ||
| 2007 | set_bit(0, rf->allocated_mrs); | 2003 | set_bit(0, rf->allocated_mrs); |
| 2008 | set_bit(0, rf->allocated_qps); | 2004 | set_bit(0, rf->allocated_qps); |
| @@ -2025,9 +2021,6 @@ u32 irdma_initialize_hw_rsrc(struct irdma_pci_f *rf) · 16 unmodified lines | |||
| 2025 | 2021 | ||
| 2026 | return 0; | 2022 | return 0; |
| 2027 | 2023 | ||
| 2028 | set_hw_rsrc_fail: | ||
| 2029 | kfree(rf->mem_rsrc); | ||
| 2030 | rf->mem_rsrc = NULL; | ||
| 2031 | mem_rsrc_kzalloc_fail: | 2024 | mem_rsrc_kzalloc_fail: |
| 2032 | kfree(rf->allocated_ws_nodes); | 2025 | kfree(rf->allocated_ws_nodes); |
| 2033 | rf->allocated_ws_nodes = NULL; | 2026 | rf->allocated_ws_nodes = NULL; |
| @@ -215,10 +215,10 @@ static void irdma_remove(struct auxiliary_device *aux_dev) · 214 unmodified lines | |||
| 215 | pr_debug("INIT: Gen2 PF[%d] device remove success\n", PCI_FUNC(pf->pdev->devfn)); | 215 | pr_debug("INIT: Gen2 PF[%d] device remove success\n", PCI_FUNC(pf->pdev->devfn)); |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | static void irdma_fill_device_info(struct irdma_device *iwdev, struct ice_pf *pf) | 218 | static void irdma_fill_device_info(struct irdma_device *iwdev, struct ice_pf *pf, |
| 219 | struct ice_vsi *vsi) | ||
| 219 | { | 220 | { |
| 220 | struct irdma_pci_f *rf = iwdev->rf; | 221 | struct irdma_pci_f *rf = iwdev->rf; |
| 221 | struct ice_vsi *vsi = ice_get_main_vsi(pf); | ||
| 222 | 222 | ||
| 223 | rf->cdev = pf; | 223 | rf->cdev = pf; |
| 224 | rf->gen_ops.register_qset = irdma_lan_register_qset; | 224 | rf->gen_ops.register_qset = irdma_lan_register_qset; |
| @@ -253,12 +253,15 @@ static int irdma_probe(struct auxiliary_device *aux_dev, const struct auxiliary_ · 28 unmodified lines | |||
| 253 | struct iidc_auxiliary_dev, | 253 | struct iidc_auxiliary_dev, |
| 254 | adev); | 254 | adev); |
| 255 | struct ice_pf *pf = iidc_adev->pf; | 255 | struct ice_pf *pf = iidc_adev->pf; |
| 256 | struct ice_vsi *vsi = ice_get_main_vsi(pf); | ||
| 256 | struct iidc_qos_params qos_info = {}; | 257 | struct iidc_qos_params qos_info = {}; |
| 257 | struct irdma_device *iwdev; | 258 | struct irdma_device *iwdev; |
| 258 | struct irdma_pci_f *rf; | 259 | struct irdma_pci_f *rf; |
| 259 | struct irdma_l2params l2params = {}; | 260 | struct irdma_l2params l2params = {}; |
| 260 | int err; | 261 | int err; |
| 261 | 262 | ||
| 263 | if (!vsi) | ||
| 264 | return -EIO; | ||
| 262 | iwdev = ib_alloc_device(irdma_device, ibdev); | 265 | iwdev = ib_alloc_device(irdma_device, ibdev); |
| 263 | if (!iwdev) | 266 | if (!iwdev) |
| 264 | return -ENOMEM; | 267 | return -ENOMEM; |
| @@ -268,7 +271,7 @@ static int irdma_probe(struct auxiliary_device *aux_dev, const struct auxiliary_ · 3 unmodified lines | |||
| 268 | return -ENOMEM; | 271 | return -ENOMEM; |
| 269 | } | 272 | } |
| 270 | 273 | ||
| 271 | irdma_fill_device_info(iwdev, pf); | 274 | irdma_fill_device_info(iwdev, pf, vsi); |
| 272 | rf = iwdev->rf; | 275 | rf = iwdev->rf; |
| 273 | 276 | ||
| 274 | if (irdma_ctrl_init_hw(rf)) { | 277 | if (irdma_ctrl_init_hw(rf)) { |
| @@ -1222,8 +1222,7 @@ enum irdma_status_code irdma_sc_aeq_init(struct irdma_sc_aeq *aeq, · 1221 unmodified lines | |||
| 1222 | struct irdma_aeq_init_info *info); | 1222 | struct irdma_aeq_init_info *info); |
| 1223 | enum irdma_status_code irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq, | 1223 | enum irdma_status_code irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq, |
| 1224 | struct irdma_aeqe_info *info); | 1224 | struct irdma_aeqe_info *info); |
| 1225 | enum irdma_status_code irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, | 1225 | void irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, u32 count); |
| 1226 | u32 count); | ||
| 1227 | 1226 | ||
| 1228 | void irdma_sc_pd_init(struct irdma_sc_dev *dev, struct irdma_sc_pd *pd, u32 pd_id, | 1227 | void irdma_sc_pd_init(struct irdma_sc_dev *dev, struct irdma_sc_pd *pd, u32 pd_id, |
| 1229 | int abi_ver); | 1228 | int abi_ver); |
| @@ -931,7 +931,7 @@ enum irdma_status_code irdma_uk_mw_bind(struct irdma_qp_uk *qp, · 930 unmodified lines | |||
| 931 | enum irdma_status_code irdma_uk_post_receive(struct irdma_qp_uk *qp, | 931 | enum irdma_status_code irdma_uk_post_receive(struct irdma_qp_uk *qp, |
| 932 | struct irdma_post_rq_info *info) | 932 | struct irdma_post_rq_info *info) |
| 933 | { | 933 | { |
| 934 | u32 total_size = 0, wqe_idx, i, byte_off; | 934 | u32 wqe_idx, i, byte_off; |
| 935 | u32 addl_frag_cnt; | 935 | u32 addl_frag_cnt; |
| 936 | __le64 *wqe; | 936 | __le64 *wqe; |
| 937 | u64 hdr; | 937 | u64 hdr; |
| @@ -939,9 +939,6 @@ enum irdma_status_code irdma_uk_post_receive(struct irdma_qp_uk *qp, · 1 unmodified line | |||
| 939 | if (qp->max_rq_frag_cnt < info->num_sges) | 939 | if (qp->max_rq_frag_cnt < info->num_sges) |
| 940 | return IRDMA_ERR_INVALID_FRAG_COUNT; | 940 | return IRDMA_ERR_INVALID_FRAG_COUNT; |
| 941 | 941 | ||
| 942 | for (i = 0; i < info->num_sges; i++) | ||
| 943 | total_size += info->sg_list[i].len; | ||
| 944 | |||
| 945 | wqe = irdma_qp_get_next_recv_wqe(qp, &wqe_idx); | 942 | wqe = irdma_qp_get_next_recv_wqe(qp, &wqe_idx); |
| 946 | if (!wqe) | 943 | if (!wqe) |
| 947 | return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; | 944 | return IRDMA_ERR_QP_TOOMANY_WRS_POSTED; |
| @@ -557,7 +557,7 @@ static int irdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) · 556 unmodified lines | |||
| 557 | * @iwqp: qp ptr | 557 | * @iwqp: qp ptr |
| 558 | * @init_info: initialize info to return | 558 | * @init_info: initialize info to return |
| 559 | */ | 559 | */ |
| 560 | static int irdma_setup_virt_qp(struct irdma_device *iwdev, | 560 | static void irdma_setup_virt_qp(struct irdma_device *iwdev, |
| 561 | struct irdma_qp *iwqp, | 561 | struct irdma_qp *iwqp, |
| 562 | struct irdma_qp_init_info *init_info) | 562 | struct irdma_qp_init_info *init_info) |
| 563 | { | 563 | { |
| @@ -574,8 +574,6 @@ static int irdma_setup_virt_qp(struct irdma_device *iwdev, · 10 unmodified lines | |||
| 574 | init_info->sq_pa = qpmr->sq_pbl.addr; | 574 | init_info->sq_pa = qpmr->sq_pbl.addr; |
| 575 | init_info->rq_pa = qpmr->rq_pbl.addr; | 575 | init_info->rq_pa = qpmr->rq_pbl.addr; |
| 576 | } | 576 | } |
| 577 | |||
| 578 | return 0; | ||
| 579 | } | 577 | } |
| 580 | 578 | ||
| 581 | /** | 579 | /** |
| @@ -914,7 +912,7 @@ static struct ib_qp *irdma_create_qp(struct ib_pd *ibpd, · 332 unmodified lines | |||
| 914 | } | 912 | } |
| 915 | } | 913 | } |
| 916 | init_info.qp_uk_init_info.abi_ver = iwpd->sc_pd.abi_ver; | 914 | init_info.qp_uk_init_info.abi_ver = iwpd->sc_pd.abi_ver; |
| 917 | err_code = irdma_setup_virt_qp(iwdev, iwqp, &init_info); | 915 | irdma_setup_virt_qp(iwdev, iwqp, &init_info); |
| 918 | } else { | 916 | } else { |
| 919 | init_info.qp_uk_init_info.abi_ver = IRDMA_ABI_VER; | 917 | init_info.qp_uk_init_info.abi_ver = IRDMA_ABI_VER; |
| 920 | err_code = irdma_setup_kmode_qp(iwdev, iwqp, &init_info, init_attr); | 918 | err_code = irdma_setup_kmode_qp(iwdev, iwqp, &init_info, init_attr); |
| @@ -113,13 +113,14 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova, · 112 unmodified lines | |||
| 113 | int num_buf; | 113 | int num_buf; |
| 114 | void *vaddr; | 114 | void *vaddr; |
| 115 | int err; | 115 | int err; |
| 116 | int i; | ||
| 116 | 117 | ||
| 117 | umem = ib_umem_get(pd->ibpd.device, start, length, access); | 118 | umem = ib_umem_get(pd->ibpd.device, start, length, access); |
| 118 | if (IS_ERR(umem)) { | 119 | if (IS_ERR(umem)) { |
| 119 | pr_warn("err %d from rxe_umem_get\n", | 120 | pr_warn("%s: Unable to pin memory region err = %d\n", |
| 120 | (int)PTR_ERR(umem)); | 121 | __func__, (int)PTR_ERR(umem)); |
| 121 | err = PTR_ERR(umem); | 122 | err = PTR_ERR(umem); |
| 122 | goto err1; | 123 | goto err_out; |
| 123 | } | 124 | } |
| 124 | 125 | ||
| 125 | mr->umem = umem; | 126 | mr->umem = umem; |
| @@ -129,9 +130,9 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova, · 3 unmodified lines | |||
| 129 | 130 | ||
| 130 | err = rxe_mr_alloc(mr, num_buf); | 131 | err = rxe_mr_alloc(mr, num_buf); |
| 131 | if (err) { | 132 | if (err) { |
| 132 | pr_warn("err %d from rxe_mr_alloc\n", err); | 133 | pr_warn("%s: Unable to allocate memory for map\n", |
| 133 | ib_umem_release(umem); | 134 | __func__); |
| 134 | goto err1; | 135 | goto err_release_umem; |
| 135 | } | 136 | } |
| 136 | 137 | ||
| 137 | mr->page_shift = PAGE_SHIFT; | 138 | mr->page_shift = PAGE_SHIFT; |
| @@ -151,10 +152,10 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova, · 13 unmodified lines | |||
| 151 | 152 | ||
| 152 | vaddr = page_address(sg_page_iter_page(&sg_iter)); | 153 | vaddr = page_address(sg_page_iter_page(&sg_iter)); |
| 153 | if (!vaddr) { | 154 | if (!vaddr) { |
| 154 | pr_warn("null vaddr\n"); | 155 | pr_warn("%s: Unable to get virtual address\n", |
| 155 | ib_umem_release(umem); | 156 | __func__); |
| 156 | err = -ENOMEM; | 157 | err = -ENOMEM; |
| 157 | goto err1; | 158 | goto err_cleanup_map; |
| 158 | } | 159 | } |
| 159 | 160 | ||
| 160 | buf->addr = (uintptr_t)vaddr; | 161 | buf->addr = (uintptr_t)vaddr; |
| @@ -177,7 +178,13 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova, · 16 unmodified lines | |||
| 177 | 178 | ||
| 178 | return 0; | 179 | return 0; |
| 179 | 180 | ||
| 180 | err1: | 181 | err_cleanup_map: |
| 182 | for (i = 0; i < mr->num_map; i++) | ||
| 183 | kfree(mr->map[i]); | ||
| 184 | kfree(mr->map); | ||
| 185 | err_release_umem: | ||
| 186 | ib_umem_release(umem); | ||
| 187 | err_out: | ||
| 181 | return err; | 188 | return err; |
| 182 | } | 189 | } |
| 183 | 190 | ||
| @@ -173,10 +173,8 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg, · 172 unmodified lines | |||
| 173 | int ret; | 173 | int ret; |
| 174 | 174 | ||
| 175 | for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { | 175 | for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { |
| 176 | if (!adev->status.enabled) { | 176 | if (!adev->status.enabled) |
| 177 | acpi_dev_put(adev); | ||
| 178 | continue; | 177 | continue; |
| 179 | } | ||
| 180 | 178 | ||
| 181 | if (bridge->n_sensors >= CIO2_NUM_PORTS) { | 179 | if (bridge->n_sensors >= CIO2_NUM_PORTS) { |
| 182 | acpi_dev_put(adev); | 180 | acpi_dev_put(adev); |
| @@ -185,7 +183,6 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg, · 2 unmodified lines | |||
| 185 | } | 183 | } |
| 186 | 184 | ||
| 187 | sensor = &bridge->sensors[bridge->n_sensors]; | 185 | sensor = &bridge->sensors[bridge->n_sensors]; |
| 188 | sensor->adev = adev; | ||
| 189 | strscpy(sensor->name, cfg->hid, sizeof(sensor->name)); | 186 | strscpy(sensor->name, cfg->hid, sizeof(sensor->name)); |
| 190 | 187 | ||
| 191 | ret = cio2_bridge_read_acpi_buffer(adev, "SSDB", | 188 | ret = cio2_bridge_read_acpi_buffer(adev, "SSDB", |
| @@ -215,6 +212,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg, · 23 unmodified lines | |||
| 215 | goto err_free_swnodes; | 212 | goto err_free_swnodes; |
| 216 | } | 213 | } |
| 217 | 214 | ||
| 215 | sensor->adev = acpi_dev_get(adev); | ||
| 218 | adev->fwnode.secondary = fwnode; | 216 | adev->fwnode.secondary = fwnode; |
| 219 | 217 | ||
| 220 | dev_info(&cio2->dev, "Found supported sensor %s\n", | 218 | dev_info(&cio2->dev, "Found supported sensor %s\n", |
| @@ -385,7 +385,7 @@ static int ngene_command_config_free_buf(struct ngene *dev, u8 *config) · 384 unmodified lines | |||
| 385 | 385 | ||
| 386 | com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER; | 386 | com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER; |
| 387 | com.cmd.hdr.Length = 6; | 387 | com.cmd.hdr.Length = 6; |
| 388 | memcpy(&com.cmd.ConfigureBuffers.config, config, 6); | 388 | memcpy(&com.cmd.ConfigureFreeBuffers.config, config, 6); |
| 389 | com.in_len = 6; | 389 | com.in_len = 6; |
| 390 | com.out_len = 0; | 390 | com.out_len = 0; |
| 391 | 391 | ||
| @@ -407,12 +407,14 @@ enum _BUFFER_CONFIGS { · 406 unmodified lines | |||
| 407 | 407 | ||
| 408 | struct FW_CONFIGURE_FREE_BUFFERS { | 408 | struct FW_CONFIGURE_FREE_BUFFERS { |
| 409 | struct FW_HEADER hdr; | 409 | struct FW_HEADER hdr; |
| 410 | u8 UVI1_BufferLength; | 410 | struct { |
| 411 | u8 UVI2_BufferLength; | 411 | u8 UVI1_BufferLength; |
| 412 | u8 TVO_BufferLength; | 412 | u8 UVI2_BufferLength; |
| 413 | u8 AUD1_BufferLength; | 413 | u8 TVO_BufferLength; |
| 414 | u8 AUD2_BufferLength; | 414 | u8 AUD1_BufferLength; |
| 415 | u8 TVA_BufferLength; | 415 | u8 AUD2_BufferLength; |
| 416 | u8 TVA_BufferLength; | ||
| 417 | } __packed config; | ||
| 416 | } __attribute__ ((__packed__)); | 418 | } __attribute__ ((__packed__)); |
| 417 | 419 | ||
| 418 | struct FW_CONFIGURE_UART { | 420 | struct FW_CONFIGURE_UART { |
| @@ -714,23 +714,20 @@ static int at24_probe(struct i2c_client *client) · 713 unmodified lines | |||
| 714 | } | 714 | } |
| 715 | 715 | ||
| 716 | /* | 716 | /* |
| 717 | * If the 'label' property is not present for the AT24 EEPROM, | 717 | * We initialize nvmem_config.id to NVMEM_DEVID_AUTO even if the |
| 718 | * then nvmem_config.id is initialised to NVMEM_DEVID_AUTO, | 718 | * label property is set as some platform can have multiple eeproms |
| 719 | * and this will append the 'devid' to the name of the NVMEM | 719 | * with same label and we can not register each of those with same |
| 720 | * device. This is purely legacy and the AT24 driver has always | 720 | * label. Failing to register those eeproms trigger cascade failure |
| 721 | * defaulted to this. However, if the 'label' property is | 721 | * on such platform. |
| 722 | * present then this means that the name is specified by the | ||
| 723 | * firmware and this name should be used verbatim and so it is | ||
| 724 | * not necessary to append the 'devid'. | ||
| 725 | */ | 722 | */ |
| 723 | nvmem_config.id = NVMEM_DEVID_AUTO; | ||
| 724 | |||
| 726 | if (device_property_present(dev, "label")) { | 725 | if (device_property_present(dev, "label")) { |
| 727 | nvmem_config.id = NVMEM_DEVID_NONE; | ||
| 728 | err = device_property_read_string(dev, "label", | 726 | err = device_property_read_string(dev, "label", |
| 729 | &nvmem_config.name); | 727 | &nvmem_config.name); |
| 730 | if (err) | 728 | if (err) |
| 731 | return err; | 729 | return err; |
| 732 | } else { | 730 | } else { |
| 733 | nvmem_config.id = NVMEM_DEVID_AUTO; | ||
| 734 | nvmem_config.name = dev_name(dev); | 731 | nvmem_config.name = dev_name(dev); |
| 735 | } | 732 | } |
| 736 | 733 | ||
| @@ -28,6 +28,7 @@ · 27 unmodified lines | |||
| 28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
| 29 | #include <linux/hdreg.h> | 29 | #include <linux/hdreg.h> |
| 30 | #include <linux/kdev_t.h> | 30 | #include <linux/kdev_t.h> |
| 31 | #include <linux/kref.h> | ||
| 31 | #include <linux/blkdev.h> | 32 | #include <linux/blkdev.h> |
| 32 | #include <linux/cdev.h> | 33 | #include <linux/cdev.h> |
| 33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| @@ -111,7 +112,7 @@ struct mmc_blk_data { · 77 unmodified lines | |||
| 111 | #define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ | 112 | #define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ |
| 112 | #define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */ | 113 | #define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */ |
| 113 | 114 | ||
| 114 | unsigned int usage; | 115 | struct kref kref; |
| 115 | unsigned int read_only; | 116 | unsigned int read_only; |
| 116 | unsigned int part_type; | 117 | unsigned int part_type; |
| 117 | unsigned int reset_done; | 118 | unsigned int reset_done; |
| @@ -181,10 +182,8 @@ static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) · 63 unmodified lines | |||
| 181 | 182 | ||
| 182 | mutex_lock(&open_lock); | 183 | mutex_lock(&open_lock); |
| 183 | md = disk->private_data; | 184 | md = disk->private_data; |
| 184 | if (md && md->usage == 0) | 185 | if (md && !kref_get_unless_zero(&md->kref)) |
| 185 | md = NULL; | 186 | md = NULL; |
| 186 | if (md) | ||
| 187 | md->usage++; | ||
| 188 | mutex_unlock(&open_lock); | 187 | mutex_unlock(&open_lock); |
| 189 | 188 | ||
| 190 | return md; | 189 | return md; |
| @@ -196,18 +195,25 @@ static inline int mmc_get_devidx(struct gendisk *disk) · 5 unmodified lines | |||
| 196 | return devidx; | 195 | return devidx; |
| 197 | } | 196 | } |
| 198 | 197 | ||
| 199 | static void mmc_blk_put(struct mmc_blk_data *md) | 198 | static void mmc_blk_kref_release(struct kref *ref) |
| 200 | { | 199 | { |
| 201 | mutex_lock(&open_lock); | 200 | struct mmc_blk_data *md = container_of(ref, struct mmc_blk_data, kref); |
| 202 | md->usage--; | 201 | int devidx; |
| 203 | if (md->usage == 0) { | ||
| 204 | int devidx = mmc_get_devidx(md->disk); | ||
| 205 | 202 | ||
| 206 | ida_simple_remove(&mmc_blk_ida, devidx); | 203 | devidx = mmc_get_devidx(md->disk); |
| 207 | put_disk(md->disk); | 204 | ida_simple_remove(&mmc_blk_ida, devidx); |
| 208 | kfree(md); | 205 | |
| 209 | } | 206 | mutex_lock(&open_lock); |
| 207 | md->disk->private_data = NULL; | ||
| 210 | mutex_unlock(&open_lock); | 208 | mutex_unlock(&open_lock); |
| 209 | |||
| 210 | put_disk(md->disk); | ||
| 211 | kfree(md); | ||
| 212 | } | ||
| 213 | |||
| 214 | static void mmc_blk_put(struct mmc_blk_data *md) | ||
| 215 | { | ||
| 216 | kref_put(&md->kref, mmc_blk_kref_release); | ||
| 211 | } | 217 | } |
| 212 | 218 | ||
| 213 | static ssize_t power_ro_lock_show(struct device *dev, | 219 | static ssize_t power_ro_lock_show(struct device *dev, |
| @@ -2327,7 +2333,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, · 2113 unmodified lines | |||
| 2327 | 2333 | ||
| 2328 | INIT_LIST_HEAD(&md->part); | 2334 | INIT_LIST_HEAD(&md->part); |
| 2329 | INIT_LIST_HEAD(&md->rpmbs); | 2335 | INIT_LIST_HEAD(&md->rpmbs); |
| 2330 | md->usage = 1; | 2336 | kref_init(&md->kref); |
| 2337 | |||
| 2331 | md->queue.blkdata = md; | 2338 | md->queue.blkdata = md; |
| 2332 | 2339 | ||
| 2333 | md->disk->major = MMC_BLOCK_MAJOR; | 2340 | md->disk->major = MMC_BLOCK_MAJOR; |
| @@ -75,7 +75,8 @@ static void mmc_host_classdev_release(struct device *dev) · 74 unmodified lines | |||
| 75 | { | 75 | { |
| 76 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | 76 | struct mmc_host *host = cls_dev_to_mmc_host(dev); |
| 77 | wakeup_source_unregister(host->ws); | 77 | wakeup_source_unregister(host->ws); |
| 78 | ida_simple_remove(&mmc_host_ida, host->index); | 78 | if (of_alias_get_id(host->parent->of_node, "mmc") < 0) |
| 79 | ida_simple_remove(&mmc_host_ida, host->index); | ||
| 79 | kfree(host); | 80 | kfree(host); |
| 80 | } | 81 | } |
| 81 | 82 | ||
| @@ -502,7 +503,7 @@ static int mmc_first_nonreserved_index(void) · 420 unmodified lines | |||
| 502 | */ | 503 | */ |
| 503 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | 504 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) |
| 504 | { | 505 | { |
| 505 | int err; | 506 | int index; |
| 506 | struct mmc_host *host; | 507 | struct mmc_host *host; |
| 507 | int alias_id, min_idx, max_idx; | 508 | int alias_id, min_idx, max_idx; |
| 508 | 509 | ||
| @@ -515,20 +516,19 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) · 6 unmodified lines | |||
| 515 | 516 | ||
| 516 | alias_id = of_alias_get_id(dev->of_node, "mmc"); | 517 | alias_id = of_alias_get_id(dev->of_node, "mmc"); |
| 517 | if (alias_id >= 0) { | 518 | if (alias_id >= 0) { |
| 518 | min_idx = alias_id; | 519 | index = alias_id; |
| 519 | max_idx = alias_id + 1; | ||
| 520 | } else { | 520 | } else { |
| 521 | min_idx = mmc_first_nonreserved_index(); | 521 | min_idx = mmc_first_nonreserved_index(); |
| 522 | max_idx = 0; | 522 | max_idx = 0; |
| 523 | } | ||
| 524 | 523 | ||
| 525 | err = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL); | 524 | index = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL); |
| 526 | if (err < 0) { | 525 | if (index < 0) { |
| 527 | kfree(host); | 526 | kfree(host); |
| 528 | return NULL; | 527 | return NULL; |
| 528 | } | ||
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | host->index = err; | 531 | host->index = index; |
| 532 | 532 | ||
| 533 | dev_set_name(&host->class_dev, "mmc%d", host->index); | 533 | dev_set_name(&host->class_dev, "mmc%d", host->index); |
| 534 | host->ws = wakeup_source_register(NULL, dev_name(&host->class_dev)); | 534 | host->ws = wakeup_source_register(NULL, dev_name(&host->class_dev)); |
| @@ -3450,7 +3450,9 @@ static int bond_master_netdev_event(unsigned long event, · 3449 unmodified lines | |||
| 3450 | return bond_event_changename(event_bond); | 3450 | return bond_event_changename(event_bond); |
| 3451 | case NETDEV_UNREGISTER: | 3451 | case NETDEV_UNREGISTER: |
| 3452 | bond_remove_proc_entry(event_bond); | 3452 | bond_remove_proc_entry(event_bond); |
| 3453 | #ifdef CONFIG_XFRM_OFFLOAD | ||
| 3453 | xfrm_dev_state_flush(dev_net(bond_dev), bond_dev, true); | 3454 | xfrm_dev_state_flush(dev_net(bond_dev), bond_dev, true); |
| 3455 | #endif /* CONFIG_XFRM_OFFLOAD */ | ||
| 3454 | break; | 3456 | break; |
| 3455 | case NETDEV_REGISTER: | 3457 | case NETDEV_REGISTER: |
| 3456 | bond_create_proc_entry(event_bond); | 3458 | bond_create_proc_entry(event_bond); |
| @@ -218,7 +218,7 @@ static int hi3110_spi_trans(struct spi_device *spi, int len) · 217 unmodified lines | |||
| 218 | return ret; | 218 | return ret; |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | static u8 hi3110_cmd(struct spi_device *spi, u8 command) | 221 | static int hi3110_cmd(struct spi_device *spi, u8 command) |
| 222 | { | 222 | { |
| 223 | struct hi3110_priv *priv = spi_get_drvdata(spi); | 223 | struct hi3110_priv *priv = spi_get_drvdata(spi); |
| 224 | 224 | ||
| @@ -2300,6 +2300,7 @@ static irqreturn_t mcp251xfd_irq(int irq, void *dev_id) · 2299 unmodified lines | |||
| 2300 | err, priv->regs_status.intf); | 2300 | err, priv->regs_status.intf); |
| 2301 | mcp251xfd_dump(priv); | 2301 | mcp251xfd_dump(priv); |
| 2302 | mcp251xfd_chip_interrupts_disable(priv); | 2302 | mcp251xfd_chip_interrupts_disable(priv); |
| 2303 | mcp251xfd_timestamp_stop(priv); | ||
| 2303 | 2304 | ||
| 2304 | return handled; | 2305 | return handled; |
| 2305 | } | 2306 | } |
| @@ -255,6 +255,8 @@ struct ems_usb { · 254 unmodified lines | |||
| 255 | unsigned int free_slots; /* remember number of available slots */ | 255 | unsigned int free_slots; /* remember number of available slots */ |
| 256 | 256 | ||
| 257 | struct ems_cpc_msg active_params; /* active controller parameters */ | 257 | struct ems_cpc_msg active_params; /* active controller parameters */ |
| 258 | void *rxbuf[MAX_RX_URBS]; | ||
| 259 | dma_addr_t rxbuf_dma[MAX_RX_URBS]; | ||
| 258 | }; | 260 | }; |
| 259 | 261 | ||
| 260 | static void ems_usb_read_interrupt_callback(struct urb *urb) | 262 | static void ems_usb_read_interrupt_callback(struct urb *urb) |
| @@ -587,6 +589,7 @@ static int ems_usb_start(struct ems_usb *dev) · 326 unmodified lines | |||
| 587 | for (i = 0; i < MAX_RX_URBS; i++) { | 589 | for (i = 0; i < MAX_RX_URBS; i++) { |
| 588 | struct urb *urb = NULL; | 590 | struct urb *urb = NULL; |
| 589 | u8 *buf = NULL; | 591 | u8 *buf = NULL; |
| 592 | dma_addr_t buf_dma; | ||
| 590 | 593 | ||
| 591 | /* create a URB, and a buffer for it */ | 594 | /* create a URB, and a buffer for it */ |
| 592 | urb = usb_alloc_urb(0, GFP_KERNEL); | 595 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| @@ -596,7 +599,7 @@ static int ems_usb_start(struct ems_usb *dev) · 3 unmodified lines | |||
| 596 | } | 599 | } |
| 597 | 600 | ||
| 598 | buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, | 601 | buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, |
| 599 | &urb->transfer_dma); | 602 | &buf_dma); |
| 600 | if (!buf) { | 603 | if (!buf) { |
| 601 | netdev_err(netdev, "No memory left for USB buffer\n"); | 604 | netdev_err(netdev, "No memory left for USB buffer\n"); |
| 602 | usb_free_urb(urb); | 605 | usb_free_urb(urb); |
| @@ -604,6 +607,8 @@ static int ems_usb_start(struct ems_usb *dev) · 1 unmodified line | |||
| 604 | break; | 607 | break; |
| 605 | } | 608 | } |
| 606 | 609 | ||
| 610 | urb->transfer_dma = buf_dma; | ||
| 611 | |||
| 607 | usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), | 612 | usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), |
| 608 | buf, RX_BUFFER_SIZE, | 613 | buf, RX_BUFFER_SIZE, |
| 609 | ems_usb_read_bulk_callback, dev); | 614 | ems_usb_read_bulk_callback, dev); |
| @@ -619,6 +624,9 @@ static int ems_usb_start(struct ems_usb *dev) · 9 unmodified lines | |||
| 619 | break; | 624 | break; |
| 620 | } | 625 | } |
| 621 | 626 | ||
| 627 | dev->rxbuf[i] = buf; | ||
| 628 | dev->rxbuf_dma[i] = buf_dma; | ||
| 629 | |||
| 622 | /* Drop reference, USB core will take care of freeing it */ | 630 | /* Drop reference, USB core will take care of freeing it */ |
| 623 | usb_free_urb(urb); | 631 | usb_free_urb(urb); |
| 624 | } | 632 | } |
| @@ -684,6 +692,10 @@ static void unlink_all_urbs(struct ems_usb *dev) · 59 unmodified lines | |||
| 684 | 692 | ||
| 685 | usb_kill_anchored_urbs(&dev->rx_submitted); | 693 | usb_kill_anchored_urbs(&dev->rx_submitted); |
| 686 | 694 | ||
| 695 | for (i = 0; i < MAX_RX_URBS; ++i) | ||
| 696 | usb_free_coherent(dev->udev, RX_BUFFER_SIZE, | ||
| 697 | dev->rxbuf[i], dev->rxbuf_dma[i]); | ||
| 698 | |||
| 687 | usb_kill_anchored_urbs(&dev->tx_submitted); | 699 | usb_kill_anchored_urbs(&dev->tx_submitted); |
| 688 | atomic_set(&dev->active_tx_urbs, 0); | 700 | atomic_set(&dev->active_tx_urbs, 0); |
| 689 | 701 | ||
| @@ -195,6 +195,8 @@ struct esd_usb2 { · 194 unmodified lines | |||
| 195 | int net_count; | 195 | int net_count; |
| 196 | u32 version; | 196 | u32 version; |
| 197 | int rxinitdone; | 197 | int rxinitdone; |
| 198 | void *rxbuf[MAX_RX_URBS]; | ||
| 199 | dma_addr_t rxbuf_dma[MAX_RX_URBS]; | ||
| 198 | }; | 200 | }; |
| 199 | 201 | ||
| 200 | struct esd_usb2_net_priv { | 202 | struct esd_usb2_net_priv { |
| @@ -545,6 +547,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) · 344 unmodified lines | |||
| 545 | for (i = 0; i < MAX_RX_URBS; i++) { | 547 | for (i = 0; i < MAX_RX_URBS; i++) { |
| 546 | struct urb *urb = NULL; | 548 | struct urb *urb = NULL; |
| 547 | u8 *buf = NULL; | 549 | u8 *buf = NULL; |
| 550 | dma_addr_t buf_dma; | ||
| 548 | 551 | ||
| 549 | /* create a URB, and a buffer for it */ | 552 | /* create a URB, and a buffer for it */ |
| 550 | urb = usb_alloc_urb(0, GFP_KERNEL); | 553 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| @@ -554,7 +557,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) · 3 unmodified lines | |||
| 554 | } | 557 | } |
| 555 | 558 | ||
| 556 | buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, | 559 | buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, |
| 557 | &urb->transfer_dma); | 560 | &buf_dma); |
| 558 | if (!buf) { | 561 | if (!buf) { |
| 559 | dev_warn(dev->udev->dev.parent, | 562 | dev_warn(dev->udev->dev.parent, |
| 560 | "No memory left for USB buffer\n"); | 563 | "No memory left for USB buffer\n"); |
| @@ -562,6 +565,8 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) · 1 unmodified line | |||
| 562 | goto freeurb; | 565 | goto freeurb; |
| 563 | } | 566 | } |
| 564 | 567 | ||
| 568 | urb->transfer_dma = buf_dma; | ||
| 569 | |||
| 565 | usb_fill_bulk_urb(urb, dev->udev, | 570 | usb_fill_bulk_urb(urb, dev->udev, |
| 566 | usb_rcvbulkpipe(dev->udev, 1), | 571 | usb_rcvbulkpipe(dev->udev, 1), |
| 567 | buf, RX_BUFFER_SIZE, | 572 | buf, RX_BUFFER_SIZE, |
| @@ -574,8 +579,12 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) · 6 unmodified lines | |||
| 574 | usb_unanchor_urb(urb); | 579 | usb_unanchor_urb(urb); |
| 575 | usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, | 580 | usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, |
| 576 | urb->transfer_dma); | 581 | urb->transfer_dma); |
| 582 | goto freeurb; | ||
| 577 | } | 583 | } |
| 578 | 584 | ||
| 585 | dev->rxbuf[i] = buf; | ||
| 586 | dev->rxbuf_dma[i] = buf_dma; | ||
| 587 | |||
| 579 | freeurb: | 588 | freeurb: |
| 580 | /* Drop reference, USB core will take care of freeing it */ | 589 | /* Drop reference, USB core will take care of freeing it */ |
| 581 | usb_free_urb(urb); | 590 | usb_free_urb(urb); |
| @@ -663,6 +672,11 @@ static void unlink_all_urbs(struct esd_usb2 *dev) · 81 unmodified lines | |||
| 663 | int i, j; | 672 | int i, j; |
| 664 | 673 | ||
| 665 | usb_kill_anchored_urbs(&dev->rx_submitted); | 674 | usb_kill_anchored_urbs(&dev->rx_submitted); |
| 675 | |||
| 676 | for (i = 0; i < MAX_RX_URBS; ++i) | ||
| 677 | usb_free_coherent(dev->udev, RX_BUFFER_SIZE, | ||
| 678 | dev->rxbuf[i], dev->rxbuf_dma[i]); | ||
| 679 | |||
| 666 | for (i = 0; i < dev->net_count; i++) { | 680 | for (i = 0; i < dev->net_count; i++) { |
| 667 | priv = dev->nets[i]; | 681 | priv = dev->nets[i]; |
| 668 | if (priv) { | 682 | if (priv) { |
| @@ -653,6 +653,8 @@ static int mcba_usb_start(struct mcba_priv *priv) · 652 unmodified lines | |||
| 653 | break; | 653 | break; |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | urb->transfer_dma = buf_dma; | ||
| 657 | |||
| 656 | usb_fill_bulk_urb(urb, priv->udev, | 658 | usb_fill_bulk_urb(urb, priv->udev, |
| 657 | usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN), | 659 | usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN), |
| 658 | buf, MCBA_USB_RX_BUFF_SIZE, | 660 | buf, MCBA_USB_RX_BUFF_SIZE, |
| @@ -117,7 +117,8 @@ · 116 unmodified lines | |||
| 117 | #define PCAN_USB_BERR_MASK (PCAN_USB_ERR_RXERR | PCAN_USB_ERR_TXERR) | 117 | #define PCAN_USB_BERR_MASK (PCAN_USB_ERR_RXERR | PCAN_USB_ERR_TXERR) |
| 118 | 118 | ||
| 119 | /* identify bus event packets with rx/tx error counters */ | 119 | /* identify bus event packets with rx/tx error counters */ |
| 120 | #define PCAN_USB_ERR_CNT 0x80 | 120 | #define PCAN_USB_ERR_CNT_DEC 0x00 /* counters are decreasing */ |
| 121 | #define PCAN_USB_ERR_CNT_INC 0x80 /* counters are increasing */ | ||
| 121 | 122 | ||
| 122 | /* private to PCAN-USB adapter */ | 123 | /* private to PCAN-USB adapter */ |
| 123 | struct pcan_usb { | 124 | struct pcan_usb { |
| @@ -608,11 +609,12 @@ static int pcan_usb_handle_bus_evt(struct pcan_usb_msg_context *mc, u8 ir) · 484 unmodified lines | |||
| 608 | 609 | ||
| 609 | /* acccording to the content of the packet */ | 610 | /* acccording to the content of the packet */ |
| 610 | switch (ir) { | 611 | switch (ir) { |
| 611 | case PCAN_USB_ERR_CNT: | 612 | case PCAN_USB_ERR_CNT_DEC: |
| 613 | case PCAN_USB_ERR_CNT_INC: | ||
| 612 | 614 | ||
| 613 | /* save rx/tx error counters from in the device context */ | 615 | /* save rx/tx error counters from in the device context */ |
| 614 | pdev->bec.rxerr = mc->ptr[0]; | 616 | pdev->bec.rxerr = mc->ptr[1]; |
| 615 | pdev->bec.txerr = mc->ptr[1]; | 617 | pdev->bec.txerr = mc->ptr[2]; |
| 616 | break; | 618 | break; |
| 617 | 619 | ||
| 618 | default: | 620 | default: |
| @@ -137,7 +137,8 @@ struct usb_8dev_priv { · 136 unmodified lines | |||
| 137 | u8 *cmd_msg_buffer; | 137 | u8 *cmd_msg_buffer; |
| 138 | 138 | ||
| 139 | struct mutex usb_8dev_cmd_lock; | 139 | struct mutex usb_8dev_cmd_lock; |
| 140 | 140 | void *rxbuf[MAX_RX_URBS]; | |
| 141 | dma_addr_t rxbuf_dma[MAX_RX_URBS]; | ||
| 141 | }; | 142 | }; |
| 142 | 143 | ||
| 143 | /* tx frame */ | 144 | /* tx frame */ |
| @@ -733,6 +734,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) · 589 unmodified lines | |||
| 733 | for (i = 0; i < MAX_RX_URBS; i++) { | 734 | for (i = 0; i < MAX_RX_URBS; i++) { |
| 734 | struct urb *urb = NULL; | 735 | struct urb *urb = NULL; |
| 735 | u8 *buf; | 736 | u8 *buf; |
| 737 | dma_addr_t buf_dma; | ||
| 736 | 738 | ||
| 737 | /* create a URB, and a buffer for it */ | 739 | /* create a URB, and a buffer for it */ |
| 738 | urb = usb_alloc_urb(0, GFP_KERNEL); | 740 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| @@ -742,7 +744,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) · 3 unmodified lines | |||
| 742 | } | 744 | } |
| 743 | 745 | ||
| 744 | buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL, | 746 | buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL, |
| 745 | &urb->transfer_dma); | 747 | &buf_dma); |
| 746 | if (!buf) { | 748 | if (!buf) { |
| 747 | netdev_err(netdev, "No memory left for USB buffer\n"); | 749 | netdev_err(netdev, "No memory left for USB buffer\n"); |
| 748 | usb_free_urb(urb); | 750 | usb_free_urb(urb); |
| @@ -750,6 +752,8 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) · 1 unmodified line | |||
| 750 | break; | 752 | break; |
| 751 | } | 753 | } |
| 752 | 754 | ||
| 755 | urb->transfer_dma = buf_dma; | ||
| 756 | |||
| 753 | usb_fill_bulk_urb(urb, priv->udev, | 757 | usb_fill_bulk_urb(urb, priv->udev, |
| 754 | usb_rcvbulkpipe(priv->udev, | 758 | usb_rcvbulkpipe(priv->udev, |
| 755 | USB_8DEV_ENDP_DATA_RX), | 759 | USB_8DEV_ENDP_DATA_RX), |
| @@ -767,6 +771,9 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) · 11 unmodified lines | |||
| 767 | break; | 771 | break; |
| 768 | } | 772 | } |
| 769 | 773 | ||
| 774 | priv->rxbuf[i] = buf; | ||
| 775 | priv->rxbuf_dma[i] = buf_dma; | ||
| 776 | |||
| 770 | /* Drop reference, USB core will take care of freeing it */ | 777 | /* Drop reference, USB core will take care of freeing it */ |
| 771 | usb_free_urb(urb); | 778 | usb_free_urb(urb); |
| 772 | } | 779 | } |
| @@ -836,6 +843,10 @@ static void unlink_all_urbs(struct usb_8dev_priv *priv) · 63 unmodified lines | |||
| 836 | 843 | ||
| 837 | usb_kill_anchored_urbs(&priv->rx_submitted); | 844 | usb_kill_anchored_urbs(&priv->rx_submitted); |
| 838 | 845 | ||
| 846 | for (i = 0; i < MAX_RX_URBS; ++i) | ||
| 847 | usb_free_coherent(priv->udev, RX_BUFFER_SIZE, | ||
| 848 | priv->rxbuf[i], priv->rxbuf_dma[i]); | ||
| 849 | |||
| 839 | usb_kill_anchored_urbs(&priv->tx_submitted); | 850 | usb_kill_anchored_urbs(&priv->tx_submitted); |
| 840 | atomic_set(&priv->active_tx_urbs, 0); | 851 | atomic_set(&priv->active_tx_urbs, 0); |
| 841 | 852 | ||
| @@ -366,6 +366,8 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid, · 365 unmodified lines | |||
| 366 | int i; | 366 | int i; |
| 367 | 367 | ||
| 368 | reg[1] |= vid & CVID_MASK; | 368 | reg[1] |= vid & CVID_MASK; |
| 369 | if (vid > 1) | ||
| 370 | reg[1] |= ATA2_IVL; | ||
| 369 | reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER; | 371 | reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER; |
| 370 | reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP; | 372 | reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP; |
| 371 | /* STATIC_ENT indicate that entry is static wouldn't | 373 | /* STATIC_ENT indicate that entry is static wouldn't |
| @@ -79,6 +79,7 @@ enum mt753x_bpdu_port_fw { · 78 unmodified lines | |||
| 79 | #define STATIC_EMP 0 | 79 | #define STATIC_EMP 0 |
| 80 | #define STATIC_ENT 3 | 80 | #define STATIC_ENT 3 |
| 81 | #define MT7530_ATA2 0x78 | 81 | #define MT7530_ATA2 0x78 |
| 82 | #define ATA2_IVL BIT(15) | ||
| 82 | 83 | ||
| 83 | /* Register for address table write data */ | 84 | /* Register for address table write data */ |
| 84 | #define MT7530_ATWD 0x7c | 85 | #define MT7530_ATWD 0x7c |
| @@ -12,7 +12,7 @@ config NET_DSA_MV88E6XXX · 11 unmodified lines | |||
| 12 | config NET_DSA_MV88E6XXX_PTP | 12 | config NET_DSA_MV88E6XXX_PTP |
| 13 | bool "PTP support for Marvell 88E6xxx" | 13 | bool "PTP support for Marvell 88E6xxx" |
| 14 | default n | 14 | default n |
| 15 | depends on PTP_1588_CLOCK | 15 | depends on NET_DSA_MV88E6XXX && PTP_1588_CLOCK |
| 16 | help | 16 | help |
| 17 | Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch | 17 | Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch |
| 18 | chips that support it. | 18 | chips that support it. |
| @@ -2155,7 +2155,7 @@ static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip, · 2154 unmodified lines | |||
| 2155 | int i, err; | 2155 | int i, err; |
| 2156 | 2156 | ||
| 2157 | if (!vid) | 2157 | if (!vid) |
| 2158 | return -EOPNOTSUPP; | 2158 | return 0; |
| 2159 | 2159 | ||
| 2160 | err = mv88e6xxx_vtu_get(chip, vid, &vlan); | 2160 | err = mv88e6xxx_vtu_get(chip, vid, &vlan); |
| 2161 | if (err) | 2161 | if (err) |
| @@ -397,6 +397,12 @@ static int sja1105_init_static_vlan(struct sja1105_private *priv) · 396 unmodified lines | |||
| 397 | if (dsa_is_cpu_port(ds, port)) | 397 | if (dsa_is_cpu_port(ds, port)) |
| 398 | v->pvid = true; | 398 | v->pvid = true; |
| 399 | list_add(&v->list, &priv->dsa_8021q_vlans); | 399 | list_add(&v->list, &priv->dsa_8021q_vlans); |
| 400 | |||
| 401 | v = kmemdup(v, sizeof(*v), GFP_KERNEL); | ||
| 402 | if (!v) | ||
| 403 | return -ENOMEM; | ||
| 404 | |||
| 405 | list_add(&v->list, &priv->bridge_vlans); | ||
| 400 | } | 406 | } |
| 401 | 407 | ||
| 402 | ((struct sja1105_vlan_lookup_entry *)table->entries)[0] = pvid; | 408 | ((struct sja1105_vlan_lookup_entry *)table->entries)[0] = pvid; |
| @@ -1671,11 +1671,16 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp, · 1670 unmodified lines | |||
| 1671 | 1671 | ||
| 1672 | if ((tpa_info->flags2 & RX_CMP_FLAGS2_META_FORMAT_VLAN) && | 1672 | if ((tpa_info->flags2 & RX_CMP_FLAGS2_META_FORMAT_VLAN) && |
| 1673 | (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) { | 1673 | (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) { |
| 1674 | u16 vlan_proto = tpa_info->metadata >> | 1674 | __be16 vlan_proto = htons(tpa_info->metadata >> |
| 1675 | RX_CMP_FLAGS2_METADATA_TPID_SFT; | 1675 | RX_CMP_FLAGS2_METADATA_TPID_SFT); |
| 1676 | u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_TCI_MASK; | 1676 | u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_TCI_MASK; |
| 1677 | 1677 | ||
| 1678 | __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag); | 1678 | if (eth_type_vlan(vlan_proto)) { |
| 1679 | __vlan_hwaccel_put_tag(skb, vlan_proto, vtag); | ||
| 1680 | } else { | ||
| 1681 | dev_kfree_skb(skb); | ||
| 1682 | return NULL; | ||
| 1683 | } | ||
| 1679 | } | 1684 | } |
| 1680 | 1685 | ||
| 1681 | skb_checksum_none_assert(skb); | 1686 | skb_checksum_none_assert(skb); |
| @@ -1897,9 +1902,15 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, · 215 unmodified lines | |||
| 1897 | (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) { | 1902 | (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) { |
| 1898 | u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data); | 1903 | u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data); |
| 1899 | u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_TCI_MASK; | 1904 | u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_TCI_MASK; |
| 1900 | u16 vlan_proto = meta_data >> RX_CMP_FLAGS2_METADATA_TPID_SFT; | 1905 | __be16 vlan_proto = htons(meta_data >> |
| 1906 | RX_CMP_FLAGS2_METADATA_TPID_SFT); | ||
| 1901 | 1907 | ||
| 1902 | __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag); | 1908 | if (eth_type_vlan(vlan_proto)) { |
| 1909 | __vlan_hwaccel_put_tag(skb, vlan_proto, vtag); | ||
| 1910 | } else { | ||
| 1911 | dev_kfree_skb(skb); | ||
| 1912 | goto next_rx; | ||
| 1913 | } | ||
| 1903 | } | 1914 | } |
| 1904 | 1915 | ||
| 1905 | skb_checksum_none_assert(skb); | 1916 | skb_checksum_none_assert(skb); |
| @@ -7563,8 +7574,12 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) · 5657 unmodified lines | |||
| 7563 | bp->flags &= ~BNXT_FLAG_WOL_CAP; | 7574 | bp->flags &= ~BNXT_FLAG_WOL_CAP; |
| 7564 | if (flags & FUNC_QCAPS_RESP_FLAGS_WOL_MAGICPKT_SUPPORTED) | 7575 | if (flags & FUNC_QCAPS_RESP_FLAGS_WOL_MAGICPKT_SUPPORTED) |
| 7565 | bp->flags |= BNXT_FLAG_WOL_CAP; | 7576 | bp->flags |= BNXT_FLAG_WOL_CAP; |
| 7566 | if (flags & FUNC_QCAPS_RESP_FLAGS_PTP_SUPPORTED) | 7577 | if (flags & FUNC_QCAPS_RESP_FLAGS_PTP_SUPPORTED) { |
| 7567 | __bnxt_hwrm_ptp_qcfg(bp); | 7578 | __bnxt_hwrm_ptp_qcfg(bp); |
| 7579 | } else { | ||
| 7580 | kfree(bp->ptp_cfg); | ||
| 7581 | bp->ptp_cfg = NULL; | ||
| 7582 | } | ||
| 7568 | } else { | 7583 | } else { |
| 7569 | #ifdef CONFIG_BNXT_SRIOV | 7584 | #ifdef CONFIG_BNXT_SRIOV |
| 7570 | struct bnxt_vf_info *vf = &bp->vf; | 7585 | struct bnxt_vf_info *vf = &bp->vf; |
| @@ -10123,7 +10138,6 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) · 2552 unmodified lines | |||
| 10123 | } | 10138 | } |
| 10124 | } | 10139 | } |
| 10125 | 10140 | ||
| 10126 | bnxt_ptp_start(bp); | ||
| 10127 | rc = bnxt_init_nic(bp, irq_re_init); | 10141 | rc = bnxt_init_nic(bp, irq_re_init); |
| 10128 | if (rc) { | 10142 | if (rc) { |
| 10129 | netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc); | 10143 | netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc); |
| @@ -10197,6 +10211,12 @@ int bnxt_half_open_nic(struct bnxt *bp) · 67 unmodified lines | |||
| 10197 | { | 10211 | { |
| 10198 | int rc = 0; | 10212 | int rc = 0; |
| 10199 | 10213 | ||
| 10214 | if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) { | ||
| 10215 | netdev_err(bp->dev, "A previous firmware reset has not completed, aborting half open\n"); | ||
| 10216 | rc = -ENODEV; | ||
| 10217 | goto half_open_err; | ||
| 10218 | } | ||
| 10219 | |||
| 10200 | rc = bnxt_alloc_mem(bp, false); | 10220 | rc = bnxt_alloc_mem(bp, false); |
| 10201 | if (rc) { | 10221 | if (rc) { |
| 10202 | netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); | 10222 | netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); |
| @@ -10256,9 +10276,16 @@ static int bnxt_open(struct net_device *dev) · 53 unmodified lines | |||
| 10256 | rc = bnxt_hwrm_if_change(bp, true); | 10276 | rc = bnxt_hwrm_if_change(bp, true); |
| 10257 | if (rc) | 10277 | if (rc) |
| 10258 | return rc; | 10278 | return rc; |
| 10279 | |||
| 10280 | if (bnxt_ptp_init(bp)) { | ||
| 10281 | netdev_warn(dev, "PTP initialization failed.\n"); | ||
| 10282 | kfree(bp->ptp_cfg); | ||
| 10283 | bp->ptp_cfg = NULL; | ||
| 10284 | } | ||
| 10259 | rc = __bnxt_open_nic(bp, true, true); | 10285 | rc = __bnxt_open_nic(bp, true, true); |
| 10260 | if (rc) { | 10286 | if (rc) { |
| 10261 | bnxt_hwrm_if_change(bp, false); | 10287 | bnxt_hwrm_if_change(bp, false); |
| 10288 | bnxt_ptp_clear(bp); | ||
| 10262 | } else { | 10289 | } else { |
| 10263 | if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) { | 10290 | if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) { |
| 10264 | if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { | 10291 | if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { |
| @@ -10349,6 +10376,7 @@ static int bnxt_close(struct net_device *dev) · 84 unmodified lines | |||
| 10349 | { | 10376 | { |
| 10350 | struct bnxt *bp = netdev_priv(dev); | 10377 | struct bnxt *bp = netdev_priv(dev); |
| 10351 | 10378 | ||
| 10379 | bnxt_ptp_clear(bp); | ||
| 10352 | bnxt_hwmon_close(bp); | 10380 | bnxt_hwmon_close(bp); |
| 10353 | bnxt_close_nic(bp, true, true); | 10381 | bnxt_close_nic(bp, true, true); |
| 10354 | bnxt_hwrm_shutdown_link(bp); | 10382 | bnxt_hwrm_shutdown_link(bp); |
| @@ -11335,6 +11363,7 @@ static void bnxt_fw_reset_close(struct bnxt *bp) · 980 unmodified lines | |||
| 11335 | bnxt_clear_int_mode(bp); | 11363 | bnxt_clear_int_mode(bp); |
| 11336 | pci_disable_device(bp->pdev); | 11364 | pci_disable_device(bp->pdev); |
| 11337 | } | 11365 | } |
| 11366 | bnxt_ptp_clear(bp); | ||
| 11338 | __bnxt_close_nic(bp, true, false); | 11367 | __bnxt_close_nic(bp, true, false); |
| 11339 | bnxt_vf_reps_free(bp); | 11368 | bnxt_vf_reps_free(bp); |
| 11340 | bnxt_clear_int_mode(bp); | 11369 | bnxt_clear_int_mode(bp); |
| @@ -11959,10 +11988,21 @@ static bool bnxt_fw_reset_timeout(struct bnxt *bp) · 618 unmodified lines | |||
| 11959 | (bp->fw_reset_max_dsecs * HZ / 10)); | 11988 | (bp->fw_reset_max_dsecs * HZ / 10)); |
| 11960 | } | 11989 | } |
| 11961 | 11990 | ||
| 11991 | static void bnxt_fw_reset_abort(struct bnxt *bp, int rc) | ||
| 11992 | { | ||
| 11993 | clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | ||
| 11994 | if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF) { | ||
| 11995 | bnxt_ulp_start(bp, rc); | ||
| 11996 | bnxt_dl_health_status_update(bp, false); | ||
| 11997 | } | ||
| 11998 | bp->fw_reset_state = 0; | ||
| 11999 | dev_close(bp->dev); | ||
| 12000 | } | ||
| 12001 | |||
| 11962 | static void bnxt_fw_reset_task(struct work_struct *work) | 12002 | static void bnxt_fw_reset_task(struct work_struct *work) |
| 11963 | { | 12003 | { |
| 11964 | struct bnxt *bp = container_of(work, struct bnxt, fw_reset_task.work); | 12004 | struct bnxt *bp = container_of(work, struct bnxt, fw_reset_task.work); |
| 11965 | int rc; | 12005 | int rc = 0; |
| 11966 | 12006 | ||
| 11967 | if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { | 12007 | if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { |
| 11968 | netdev_err(bp->dev, "bnxt_fw_reset_task() called when not in fw reset mode!\n"); | 12008 | netdev_err(bp->dev, "bnxt_fw_reset_task() called when not in fw reset mode!\n"); |
| @@ -11992,6 +12032,11 @@ static void bnxt_fw_reset_task(struct work_struct *work) · 23 unmodified lines | |||
| 11992 | } | 12032 | } |
| 11993 | bp->fw_reset_timestamp = jiffies; | 12033 | bp->fw_reset_timestamp = jiffies; |
| 11994 | rtnl_lock(); | 12034 | rtnl_lock(); |
| 12035 | if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) { | ||
| 12036 | bnxt_fw_reset_abort(bp, rc); | ||
| 12037 | rtnl_unlock(); | ||
| 12038 | return; | ||
| 12039 | } | ||
| 11995 | bnxt_fw_reset_close(bp); | 12040 | bnxt_fw_reset_close(bp); |
| 11996 | if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { | 12041 | if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { |
| 11997 | bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN; | 12042 | bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN; |
| @@ -12039,6 +12084,7 @@ static void bnxt_fw_reset_task(struct work_struct *work) · 41 unmodified lines | |||
| 12039 | if (val == 0xffff) { | 12084 | if (val == 0xffff) { |
| 12040 | if (bnxt_fw_reset_timeout(bp)) { | 12085 | if (bnxt_fw_reset_timeout(bp)) { |
| 12041 | netdev_err(bp->dev, "Firmware reset aborted, PCI config space invalid\n"); | 12086 | netdev_err(bp->dev, "Firmware reset aborted, PCI config space invalid\n"); |
| 12087 | rc = -ETIMEDOUT; | ||
| 12042 | goto fw_reset_abort; | 12088 | goto fw_reset_abort; |
| 12043 | } | 12089 | } |
| 12044 | bnxt_queue_fw_reset_work(bp, HZ / 1000); | 12090 | bnxt_queue_fw_reset_work(bp, HZ / 1000); |
| @@ -12048,6 +12094,7 @@ static void bnxt_fw_reset_task(struct work_struct *work) · 3 unmodified lines | |||
| 12048 | clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state); | 12094 | clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state); |
| 12049 | if (pci_enable_device(bp->pdev)) { | 12095 | if (pci_enable_device(bp->pdev)) { |
| 12050 | netdev_err(bp->dev, "Cannot re-enable PCI device\n"); | 12096 | netdev_err(bp->dev, "Cannot re-enable PCI device\n"); |
| 12097 | rc = -ENODEV; | ||
| 12051 | goto fw_reset_abort; | 12098 | goto fw_reset_abort; |
| 12052 | } | 12099 | } |
| 12053 | pci_set_master(bp->pdev); | 12100 | pci_set_master(bp->pdev); |
| @@ -12074,18 +12121,18 @@ static void bnxt_fw_reset_task(struct work_struct *work) · 20 unmodified lines | |||
| 12074 | } | 12121 | } |
| 12075 | rc = bnxt_open(bp->dev); | 12122 | rc = bnxt_open(bp->dev); |
| 12076 | if (rc) { | 12123 | if (rc) { |
| 12077 | netdev_err(bp->dev, "bnxt_open_nic() failed\n"); | 12124 | netdev_err(bp->dev, "bnxt_open() failed during FW reset\n"); |
| 12078 | clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 12125 | bnxt_fw_reset_abort(bp, rc); |
| 12079 | dev_close(bp->dev); | 12126 | rtnl_unlock(); |
| 12127 | return; | ||
| 12080 | } | 12128 | } |
| 12081 | 12129 | ||
| 12082 | bp->fw_reset_state = 0; | 12130 | bp->fw_reset_state = 0; |
| 12083 | /* Make sure fw_reset_state is 0 before clearing the flag */ | 12131 | /* Make sure fw_reset_state is 0 before clearing the flag */ |
| 12084 | smp_mb__before_atomic(); | 12132 | smp_mb__before_atomic(); |
| 12085 | clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 12133 | clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 12086 | bnxt_ulp_start(bp, rc); | 12134 | bnxt_ulp_start(bp, 0); |
| 12087 | if (!rc) | 12135 | bnxt_reenable_sriov(bp); |
| 12088 | bnxt_reenable_sriov(bp); | ||
| 12089 | bnxt_vf_reps_alloc(bp); | 12136 | bnxt_vf_reps_alloc(bp); |
| 12090 | bnxt_vf_reps_open(bp); | 12137 | bnxt_vf_reps_open(bp); |
| 12091 | bnxt_dl_health_recovery_done(bp); | 12138 | bnxt_dl_health_recovery_done(bp); |
| @@ -12103,12 +12150,8 @@ fw_reset_abort_status: · 11 unmodified lines | |||
| 12103 | netdev_err(bp->dev, "fw_health_status 0x%x\n", sts); | 12150 | netdev_err(bp->dev, "fw_health_status 0x%x\n", sts); |
| 12104 | } | 12151 | } |
| 12105 | fw_reset_abort: | 12152 | fw_reset_abort: |
| 12106 | clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | ||
| 12107 | if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF) | ||
| 12108 | bnxt_dl_health_status_update(bp, false); | ||
| 12109 | bp->fw_reset_state = 0; | ||
| 12110 | rtnl_lock(); | 12153 | rtnl_lock(); |
| 12111 | dev_close(bp->dev); | 12154 | bnxt_fw_reset_abort(bp, rc); |
| 12112 | rtnl_unlock(); | 12155 | rtnl_unlock(); |
| 12113 | } | 12156 | } |
| 12114 | 12157 | ||
| @@ -12662,7 +12705,6 @@ static void bnxt_remove_one(struct pci_dev *pdev) · 547 unmodified lines | |||
| 12662 | if (BNXT_PF(bp)) | 12705 | if (BNXT_PF(bp)) |
| 12663 | devlink_port_type_clear(&bp->dl_port); | 12706 | devlink_port_type_clear(&bp->dl_port); |
| 12664 | 12707 | ||
| 12665 | bnxt_ptp_clear(bp); | ||
| 12666 | pci_disable_pcie_error_reporting(pdev); | 12708 | pci_disable_pcie_error_reporting(pdev); |
| 12667 | unregister_netdev(dev); | 12709 | unregister_netdev(dev); |
| 12668 | clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 12710 | clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| @@ -13246,11 +13288,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 577 unmodified lines | |||
| 13246 | rc); | 13288 | rc); |
| 13247 | } | 13289 | } |
| 13248 | 13290 | ||
| 13249 | if (bnxt_ptp_init(bp)) { | ||
| 13250 | netdev_warn(dev, "PTP initialization failed.\n"); | ||
| 13251 | kfree(bp->ptp_cfg); | ||
| 13252 | bp->ptp_cfg = NULL; | ||
| 13253 | } | ||
| 13254 | bnxt_inv_fw_health_reg(bp); | 13291 | bnxt_inv_fw_health_reg(bp); |
| 13255 | bnxt_dl_register(bp); | 13292 | bnxt_dl_register(bp); |
| 13256 | 13293 | ||
| @@ -13436,7 +13473,8 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev, · 179 unmodified lines | |||
| 13436 | if (netif_running(netdev)) | 13473 | if (netif_running(netdev)) |
| 13437 | bnxt_close(netdev); | 13474 | bnxt_close(netdev); |
| 13438 | 13475 | ||
| 13439 | pci_disable_device(pdev); | 13476 | if (pci_is_enabled(pdev)) |
| 13477 | pci_disable_device(pdev); | ||
| 13440 | bnxt_free_ctx_mem(bp); | 13478 | bnxt_free_ctx_mem(bp); |
| 13441 | kfree(bp->ctx); | 13479 | kfree(bp->ctx); |
| 13442 | bp->ctx = NULL; | 13480 | bp->ctx = NULL; |
| @@ -433,6 +433,7 @@ static int bnxt_hwrm_queue_dscp2pri_cfg(struct bnxt *bp, struct dcb_app *app, · 432 unmodified lines | |||
| 433 | static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc) | 433 | static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc) |
| 434 | { | 434 | { |
| 435 | int total_ets_bw = 0; | 435 | int total_ets_bw = 0; |
| 436 | bool zero = false; | ||
| 436 | u8 max_tc = 0; | 437 | u8 max_tc = 0; |
| 437 | int i; | 438 | int i; |
| 438 | 439 | ||
| @@ -453,13 +454,20 @@ static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc) · 14 unmodified lines | |||
| 453 | break; | 454 | break; |
| 454 | case IEEE_8021QAZ_TSA_ETS: | 455 | case IEEE_8021QAZ_TSA_ETS: |
| 455 | total_ets_bw += ets->tc_tx_bw[i]; | 456 | total_ets_bw += ets->tc_tx_bw[i]; |
| 457 | zero = zero || !ets->tc_tx_bw[i]; | ||
| 456 | break; | 458 | break; |
| 457 | default: | 459 | default: |
| 458 | return -ENOTSUPP; | 460 | return -ENOTSUPP; |
| 459 | } | 461 | } |
| 460 | } | 462 | } |
| 461 | if (total_ets_bw > 100) | 463 | if (total_ets_bw > 100) { |
| 464 | netdev_warn(bp->dev, "rejecting ETS config exceeding available bandwidth\n"); | ||
| 462 | return -EINVAL; | 465 | return -EINVAL; |
| 466 | } | ||
| 467 | if (zero && total_ets_bw == 100) { | ||
| 468 | netdev_warn(bp->dev, "rejecting ETS config starving a TC\n"); | ||
| 469 | return -EINVAL; | ||
| 470 | } | ||
| 463 | 471 | ||
| 464 | if (max_tc >= bp->max_tc) | 472 | if (max_tc >= bp->max_tc) |
| 465 | *tc = bp->max_tc; | 473 | *tc = bp->max_tc; |
| @@ -353,6 +353,12 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) · 352 unmodified lines | |||
| 353 | 353 | ||
| 354 | bnxt_ptp_get_current_time(bp); | 354 | bnxt_ptp_get_current_time(bp); |
| 355 | ptp->next_period = now + HZ; | 355 | ptp->next_period = now + HZ; |
| 356 | if (time_after_eq(now, ptp->next_overflow_check)) { | ||
| 357 | spin_lock_bh(&ptp->ptp_lock); | ||
| 358 | timecounter_read(&ptp->tc); | ||
| 359 | spin_unlock_bh(&ptp->ptp_lock); | ||
| 360 | ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; | ||
| 361 | } | ||
| 356 | return HZ; | 362 | return HZ; |
| 357 | } | 363 | } |
| 358 | 364 | ||
| @@ -385,22 +391,6 @@ int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts) · 26 unmodified lines | |||
| 385 | return 0; | 391 | return 0; |
| 386 | } | 392 | } |
| 387 | 393 | ||
| 388 | void bnxt_ptp_start(struct bnxt *bp) | ||
| 389 | { | ||
| 390 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | ||
| 391 | |||
| 392 | if (!ptp) | ||
| 393 | return; | ||
| 394 | |||
| 395 | if (bp->flags & BNXT_FLAG_CHIP_P5) { | ||
| 396 | spin_lock_bh(&ptp->ptp_lock); | ||
| 397 | ptp->current_time = bnxt_refclk_read(bp, NULL); | ||
| 398 | WRITE_ONCE(ptp->old_time, ptp->current_time); | ||
| 399 | spin_unlock_bh(&ptp->ptp_lock); | ||
| 400 | ptp_schedule_worker(ptp->ptp_clock, 0); | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | static const struct ptp_clock_info bnxt_ptp_caps = { | 394 | static const struct ptp_clock_info bnxt_ptp_caps = { |
| 405 | .owner = THIS_MODULE, | 395 | .owner = THIS_MODULE, |
| 406 | .name = "bnxt clock", | 396 | .name = "bnxt clock", |
| @@ -439,6 +429,7 @@ int bnxt_ptp_init(struct bnxt *bp) · 32 unmodified lines | |||
| 439 | ptp->cc.shift = 0; | 429 | ptp->cc.shift = 0; |
| 440 | ptp->cc.mult = 1; | 430 | ptp->cc.mult = 1; |
| 441 | 431 | ||
| 432 | ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD; | ||
| 442 | timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real())); | 433 | timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real())); |
| 443 | 434 | ||
| 444 | ptp->ptp_info = bnxt_ptp_caps; | 435 | ptp->ptp_info = bnxt_ptp_caps; |
| @@ -450,7 +441,13 @@ int bnxt_ptp_init(struct bnxt *bp) · 5 unmodified lines | |||
| 450 | bnxt_unmap_ptp_regs(bp); | 441 | bnxt_unmap_ptp_regs(bp); |
| 451 | return err; | 442 | return err; |
| 452 | } | 443 | } |
| 453 | 444 | if (bp->flags & BNXT_FLAG_CHIP_P5) { | |
| 445 | spin_lock_bh(&ptp->ptp_lock); | ||
| 446 | ptp->current_time = bnxt_refclk_read(bp, NULL); | ||
| 447 | WRITE_ONCE(ptp->old_time, ptp->current_time); | ||
| 448 | spin_unlock_bh(&ptp->ptp_lock); | ||
| 449 | ptp_schedule_worker(ptp->ptp_clock, 0); | ||
| 450 | } | ||
| 454 | return 0; | 451 | return 0; |
| 455 | } | 452 | } |
| 456 | 453 | ||
| @@ -32,6 +32,10 @@ struct bnxt_ptp_cfg { · 31 unmodified lines | |||
| 32 | u64 current_time; | 32 | u64 current_time; |
| 33 | u64 old_time; | 33 | u64 old_time; |
| 34 | unsigned long next_period; | 34 | unsigned long next_period; |
| 35 | unsigned long next_overflow_check; | ||
| 36 | /* 48-bit PHC overflows in 78 hours. Check overflow every 19 hours. */ | ||
| 37 | #define BNXT_PHC_OVERFLOW_PERIOD (19 * 3600 * HZ) | ||
| 38 | |||
| 35 | u16 tx_seqid; | 39 | u16 tx_seqid; |
| 36 | struct bnxt *bp; | 40 | struct bnxt *bp; |
| 37 | atomic_t tx_avail; | 41 | atomic_t tx_avail; |
| @@ -75,7 +79,6 @@ int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr); · 37 unmodified lines | |||
| 75 | int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr); | 79 | int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr); |
| 76 | int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb); | 80 | int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb); |
| 77 | int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts); | 81 | int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts); |
| 78 | void bnxt_ptp_start(struct bnxt *bp); | ||
| 79 | int bnxt_ptp_init(struct bnxt *bp); | 82 | int bnxt_ptp_init(struct bnxt *bp); |
| 80 | void bnxt_ptp_clear(struct bnxt *bp); | 83 | void bnxt_ptp_clear(struct bnxt *bp); |
| 81 | #endif | 84 | #endif |
| @@ -479,16 +479,17 @@ struct bnxt_en_dev *bnxt_ulp_probe(struct net_device *dev) · 478 unmodified lines | |||
| 479 | if (!edev) | 479 | if (!edev) |
| 480 | return ERR_PTR(-ENOMEM); | 480 | return ERR_PTR(-ENOMEM); |
| 481 | edev->en_ops = &bnxt_en_ops_tbl; | 481 | edev->en_ops = &bnxt_en_ops_tbl; |
| 482 | if (bp->flags & BNXT_FLAG_ROCEV1_CAP) | ||
| 483 | edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; | ||
| 484 | if (bp->flags & BNXT_FLAG_ROCEV2_CAP) | ||
| 485 | edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; | ||
| 486 | edev->net = dev; | 482 | edev->net = dev; |
| 487 | edev->pdev = bp->pdev; | 483 | edev->pdev = bp->pdev; |
| 488 | edev->l2_db_size = bp->db_size; | 484 | edev->l2_db_size = bp->db_size; |
| 489 | edev->l2_db_size_nc = bp->db_size; | 485 | edev->l2_db_size_nc = bp->db_size; |
| 490 | bp->edev = edev; | 486 | bp->edev = edev; |
| 491 | } | 487 | } |
| 488 | edev->flags &= ~BNXT_EN_FLAG_ROCE_CAP; | ||
| 489 | if (bp->flags & BNXT_FLAG_ROCEV1_CAP) | ||
| 490 | edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; | ||
| 491 | if (bp->flags & BNXT_FLAG_ROCEV2_CAP) | ||
| 492 | edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; | ||
| 492 | return bp->edev; | 493 | return bp->edev; |
| 493 | } | 494 | } |
| 494 | EXPORT_SYMBOL(bnxt_ulp_probe); | 495 | EXPORT_SYMBOL(bnxt_ulp_probe); |
| @@ -420,7 +420,7 @@ static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct) · 419 unmodified lines | |||
| 420 | * bits 32:47 indicate the PVF num. | 420 | * bits 32:47 indicate the PVF num. |
| 421 | */ | 421 | */ |
| 422 | for (q_no = 0; q_no < ern; q_no++) { | 422 | for (q_no = 0; q_no < ern; q_no++) { |
| 423 | reg_val = oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; | 423 | reg_val = (u64)oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; |
| 424 | 424 | ||
| 425 | /* for VF assigned queues. */ | 425 | /* for VF assigned queues. */ |
| 426 | if (q_no < oct->sriov_info.pf_srn) { | 426 | if (q_no < oct->sriov_info.pf_srn) { |
| @@ -357,7 +357,7 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) · 356 unmodified lines | |||
| 357 | int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; | 357 | int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; |
| 358 | void __iomem *ioaddr; | 358 | void __iomem *ioaddr; |
| 359 | 359 | ||
| 360 | i = pci_enable_device(pdev); | 360 | i = pcim_enable_device(pdev); |
| 361 | if (i) return i; | 361 | if (i) return i; |
| 362 | 362 | ||
| 363 | pci_set_master(pdev); | 363 | pci_set_master(pdev); |
| @@ -379,7 +379,7 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) · 15 unmodified lines | |||
| 379 | 379 | ||
| 380 | ioaddr = pci_iomap(pdev, TULIP_BAR, netdev_res_size); | 380 | ioaddr = pci_iomap(pdev, TULIP_BAR, netdev_res_size); |
| 381 | if (!ioaddr) | 381 | if (!ioaddr) |
| 382 | goto err_out_free_res; | 382 | goto err_out_netdev; |
| 383 | 383 | ||
| 384 | for (i = 0; i < 3; i++) | 384 | for (i = 0; i < 3; i++) |
| 385 | ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(eeprom_read(ioaddr, i)); | 385 | ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(eeprom_read(ioaddr, i)); |
| @@ -458,8 +458,6 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) · 72 unmodified lines | |||
| 458 | 458 | ||
| 459 | err_out_cleardev: | 459 | err_out_cleardev: |
| 460 | pci_iounmap(pdev, ioaddr); | 460 | pci_iounmap(pdev, ioaddr); |
| 461 | err_out_free_res: | ||
| 462 | pci_release_regions(pdev); | ||
| 463 | err_out_netdev: | 461 | err_out_netdev: |
| 464 | free_netdev (dev); | 462 | free_netdev (dev); |
| 465 | return -ENODEV; | 463 | return -ENODEV; |
| @@ -1526,7 +1524,6 @@ static void w840_remove1(struct pci_dev *pdev) · 1060 unmodified lines | |||
| 1526 | if (dev) { | 1524 | if (dev) { |
| 1527 | struct netdev_private *np = netdev_priv(dev); | 1525 | struct netdev_private *np = netdev_priv(dev); |
| 1528 | unregister_netdev(dev); | 1526 | unregister_netdev(dev); |
| 1529 | pci_release_regions(pdev); | ||
| 1530 | pci_iounmap(pdev, np->base_addr); | 1527 | pci_iounmap(pdev, np->base_addr); |
| 1531 | free_netdev(dev); | 1528 | free_netdev(dev); |
| 1532 | } | 1529 | } |
| @@ -2770,32 +2770,32 @@ static int dpaa2_switch_ctrl_if_setup(struct ethsw_core *ethsw) · 2769 unmodified lines | |||
| 2770 | if (err) | 2770 | if (err) |
| 2771 | return err; | 2771 | return err; |
| 2772 | 2772 | ||
| 2773 | err = dpaa2_switch_seed_bp(ethsw); | ||
| 2774 | if (err) | ||
| 2775 | goto err_free_dpbp; | ||
| 2776 | |||
| 2777 | err = dpaa2_switch_alloc_rings(ethsw); | 2773 | err = dpaa2_switch_alloc_rings(ethsw); |
| 2778 | if (err) | 2774 | if (err) |
| 2779 | goto err_drain_dpbp; | 2775 | goto err_free_dpbp; |
| 2780 | 2776 | ||
| 2781 | err = dpaa2_switch_setup_dpio(ethsw); | 2777 | err = dpaa2_switch_setup_dpio(ethsw); |
| 2782 | if (err) | 2778 | if (err) |
| 2783 | goto err_destroy_rings; | 2779 | goto err_destroy_rings; |
| 2784 | 2780 | ||
| 2781 | err = dpaa2_switch_seed_bp(ethsw); | ||
| 2782 | if (err) | ||
| 2783 | goto err_deregister_dpio; | ||
| 2784 | |||
| 2785 | err = dpsw_ctrl_if_enable(ethsw->mc_io, 0, ethsw->dpsw_handle); | 2785 | err = dpsw_ctrl_if_enable(ethsw->mc_io, 0, ethsw->dpsw_handle); |
| 2786 | if (err) { | 2786 | if (err) { |
| 2787 | dev_err(ethsw->dev, "dpsw_ctrl_if_enable err %d\n", err); | 2787 | dev_err(ethsw->dev, "dpsw_ctrl_if_enable err %d\n", err); |
| 2788 | goto err_deregister_dpio; | 2788 | goto err_drain_dpbp; |
| 2789 | } | 2789 | } |
| 2790 | 2790 | ||
| 2791 | return 0; | 2791 | return 0; |
| 2792 | 2792 | ||
| 2793 | err_drain_dpbp: | ||
| 2794 | dpaa2_switch_drain_bp(ethsw); | ||
| 2793 | err_deregister_dpio: | 2795 | err_deregister_dpio: |
| 2794 | dpaa2_switch_free_dpio(ethsw); | 2796 | dpaa2_switch_free_dpio(ethsw); |
| 2795 | err_destroy_rings: | 2797 | err_destroy_rings: |
| 2796 | dpaa2_switch_destroy_rings(ethsw); | 2798 | dpaa2_switch_destroy_rings(ethsw); |
| 2797 | err_drain_dpbp: | ||
| 2798 | dpaa2_switch_drain_bp(ethsw); | ||
| 2799 | err_free_dpbp: | 2799 | err_free_dpbp: |
| 2800 | dpaa2_switch_free_dpbp(ethsw); | 2800 | dpaa2_switch_free_dpbp(ethsw); |
| 2801 | 2801 | ||
| @@ -524,6 +524,7 @@ static void setup_memac(struct mac_device *mac_dev) · 523 unmodified lines | |||
| 524 | | SUPPORTED_Autoneg \ | 524 | | SUPPORTED_Autoneg \ |
| 525 | | SUPPORTED_Pause \ | 525 | | SUPPORTED_Pause \ |
| 526 | | SUPPORTED_Asym_Pause \ | 526 | | SUPPORTED_Asym_Pause \ |
| 527 | | SUPPORTED_FIBRE \ | ||
| 527 | | SUPPORTED_MII) | 528 | | SUPPORTED_MII) |
| 528 | 529 | ||
| 529 | static DEFINE_MUTEX(eth_lock); | 530 | static DEFINE_MUTEX(eth_lock); |
| @@ -131,7 +131,7 @@ · 130 unmodified lines | |||
| 131 | /* buf unit size is cache_line_size, which is 64, so the shift is 6 */ | 131 | /* buf unit size is cache_line_size, which is 64, so the shift is 6 */ |
| 132 | #define PPE_BUF_SIZE_SHIFT 6 | 132 | #define PPE_BUF_SIZE_SHIFT 6 |
| 133 | #define PPE_TX_BUF_HOLD BIT(31) | 133 | #define PPE_TX_BUF_HOLD BIT(31) |
| 134 | #define CACHE_LINE_MASK 0x3F | 134 | #define SOC_CACHE_LINE_MASK 0x3F |
| 135 | #else | 135 | #else |
| 136 | #define PPE_CFG_QOS_VMID_GRP_SHIFT 8 | 136 | #define PPE_CFG_QOS_VMID_GRP_SHIFT 8 |
| 137 | #define PPE_CFG_RX_CTRL_ALIGN_SHIFT 11 | 137 | #define PPE_CFG_RX_CTRL_ALIGN_SHIFT 11 |
| @@ -531,8 +531,8 @@ hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 393 unmodified lines | |||
| 531 | #if defined(CONFIG_HI13X1_GMAC) | 531 | #if defined(CONFIG_HI13X1_GMAC) |
| 532 | desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV | 532 | desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV |
| 533 | | TX_RELEASE_TO_PPE | priv->port << TX_POOL_SHIFT); | 533 | | TX_RELEASE_TO_PPE | priv->port << TX_POOL_SHIFT); |
| 534 | desc->data_offset = (__force u32)cpu_to_be32(phys & CACHE_LINE_MASK); | 534 | desc->data_offset = (__force u32)cpu_to_be32(phys & SOC_CACHE_LINE_MASK); |
| 535 | desc->send_addr = (__force u32)cpu_to_be32(phys & ~CACHE_LINE_MASK); | 535 | desc->send_addr = (__force u32)cpu_to_be32(phys & ~SOC_CACHE_LINE_MASK); |
| 536 | #else | 536 | #else |
| 537 | desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV); | 537 | desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV); |
| 538 | desc->send_addr = (__force u32)cpu_to_be32(phys); | 538 | desc->send_addr = (__force u32)cpu_to_be32(phys); |
| @@ -98,6 +98,7 @@ struct hclgevf_mbx_resp_status { · 97 unmodified lines | |||
| 98 | u32 origin_mbx_msg; | 98 | u32 origin_mbx_msg; |
| 99 | bool received_resp; | 99 | bool received_resp; |
| 100 | int resp_status; | 100 | int resp_status; |
| 101 | u16 match_id; | ||
| 101 | u8 additional_info[HCLGE_MBX_MAX_RESP_DATA_SIZE]; | 102 | u8 additional_info[HCLGE_MBX_MAX_RESP_DATA_SIZE]; |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| @@ -143,7 +144,8 @@ struct hclge_mbx_vf_to_pf_cmd { · 39 unmodified lines | |||
| 143 | u8 mbx_need_resp; | 144 | u8 mbx_need_resp; |
| 144 | u8 rsv1[1]; | 145 | u8 rsv1[1]; |
| 145 | u8 msg_len; | 146 | u8 msg_len; |
| 146 | u8 rsv2[3]; | 147 | u8 rsv2; |
| 148 | u16 match_id; | ||
| 147 | struct hclge_vf_to_pf_msg msg; | 149 | struct hclge_vf_to_pf_msg msg; |
| 148 | }; | 150 | }; |
| 149 | 151 | ||
| @@ -153,7 +155,8 @@ struct hclge_mbx_pf_to_vf_cmd { · 3 unmodified lines | |||
| 153 | u8 dest_vfid; | 155 | u8 dest_vfid; |
| 154 | u8 rsv[3]; | 156 | u8 rsv[3]; |
| 155 | u8 msg_len; | 157 | u8 msg_len; |
| 156 | u8 rsv1[3]; | 158 | u8 rsv1; |
| 159 | u16 match_id; | ||
| 157 | struct hclge_pf_to_vf_msg msg; | 160 | struct hclge_pf_to_vf_msg msg; |
| 158 | }; | 161 | }; |
| 159 | 162 | ||
| @@ -9552,13 +9552,17 @@ static int hclge_set_vport_vlan_filter(struct hclge_vport *vport, bool enable) · 9551 unmodified lines | |||
| 9552 | if (ret) | 9552 | if (ret) |
| 9553 | return ret; | 9553 | return ret; |
| 9554 | 9554 | ||
| 9555 | if (test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, ae_dev->caps)) | 9555 | if (test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, ae_dev->caps)) { |
| 9556 | ret = hclge_set_port_vlan_filter_bypass(hdev, vport->vport_id, | 9556 | ret = hclge_set_port_vlan_filter_bypass(hdev, vport->vport_id, |
| 9557 | !enable); | 9557 | !enable); |
| 9558 | else if (!vport->vport_id) | 9558 | } else if (!vport->vport_id) { |
| 9559 | if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps)) | ||
| 9560 | enable = false; | ||
| 9561 | |||
| 9559 | ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, | 9562 | ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, |
| 9560 | HCLGE_FILTER_FE_INGRESS, | 9563 | HCLGE_FILTER_FE_INGRESS, |
| 9561 | enable, 0); | 9564 | enable, 0); |
| 9565 | } | ||
| 9562 | 9566 | ||
| 9563 | return ret; | 9567 | return ret; |
| 9564 | } | 9568 | } |
| @@ -47,6 +47,7 @@ static int hclge_gen_resp_to_vf(struct hclge_vport *vport, · 46 unmodified lines | |||
| 47 | 47 | ||
| 48 | resp_pf_to_vf->dest_vfid = vf_to_pf_req->mbx_src_vfid; | 48 | resp_pf_to_vf->dest_vfid = vf_to_pf_req->mbx_src_vfid; |
| 49 | resp_pf_to_vf->msg_len = vf_to_pf_req->msg_len; | 49 | resp_pf_to_vf->msg_len = vf_to_pf_req->msg_len; |
| 50 | resp_pf_to_vf->match_id = vf_to_pf_req->match_id; | ||
| 50 | 51 | ||
| 51 | resp_pf_to_vf->msg.code = HCLGE_MBX_PF_VF_RESP; | 52 | resp_pf_to_vf->msg.code = HCLGE_MBX_PF_VF_RESP; |
| 52 | resp_pf_to_vf->msg.vf_mbx_msg_code = vf_to_pf_req->msg.code; | 53 | resp_pf_to_vf->msg.vf_mbx_msg_code = vf_to_pf_req->msg.code; |
| @@ -5,9 +5,27 @@ · 4 unmodified lines | |||
| 5 | #include "hclge_main.h" | 5 | #include "hclge_main.h" |
| 6 | #include "hnae3.h" | 6 | #include "hnae3.h" |
| 7 | 7 | ||
| 8 | static int hclge_ptp_get_cycle(struct hclge_dev *hdev) | ||
| 9 | { | ||
| 10 | struct hclge_ptp *ptp = hdev->ptp; | ||
| 11 | |||
| 12 | ptp->cycle.quo = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG) & | ||
| 13 | HCLGE_PTP_CYCLE_QUO_MASK; | ||
| 14 | ptp->cycle.numer = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG); | ||
| 15 | ptp->cycle.den = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG); | ||
| 16 | |||
| 17 | if (ptp->cycle.den == 0) { | ||
| 18 | dev_err(&hdev->pdev->dev, "invalid ptp cycle denominator!\n"); | ||
| 19 | return -EINVAL; | ||
| 20 | } | ||
| 21 | |||
| 22 | return 0; | ||
| 23 | } | ||
| 24 | |||
| 8 | static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) | 25 | static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) |
| 9 | { | 26 | { |
| 10 | struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp); | 27 | struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp); |
| 28 | struct hclge_ptp_cycle *cycle = &hdev->ptp->cycle; | ||
| 11 | u64 adj_val, adj_base, diff; | 29 | u64 adj_val, adj_base, diff; |
| 12 | unsigned long flags; | 30 | unsigned long flags; |
| 13 | bool is_neg = false; | 31 | bool is_neg = false; |
| @@ -18,7 +36,7 @@ static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) · 4 unmodified lines | |||
| 18 | is_neg = true; | 36 | is_neg = true; |
| 19 | } | 37 | } |
| 20 | 38 | ||
| 21 | adj_base = HCLGE_PTP_CYCLE_ADJ_BASE * HCLGE_PTP_CYCLE_ADJ_UNIT; | 39 | adj_base = (u64)cycle->quo * (u64)cycle->den + (u64)cycle->numer; |
| 22 | adj_val = adj_base * ppb; | 40 | adj_val = adj_base * ppb; |
| 23 | diff = div_u64(adj_val, 1000000000ULL); | 41 | diff = div_u64(adj_val, 1000000000ULL); |
| 24 | 42 | ||
| @@ -29,16 +47,16 @@ static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) · 4 unmodified lines | |||
| 29 | 47 | ||
| 30 | /* This clock cycle is defined by three part: quotient, numerator | 48 | /* This clock cycle is defined by three part: quotient, numerator |
| 31 | * and denominator. For example, 2.5ns, the quotient is 2, | 49 | * and denominator. For example, 2.5ns, the quotient is 2, |
| 32 | * denominator is fixed to HCLGE_PTP_CYCLE_ADJ_UNIT, and numerator | 50 | * denominator is fixed to ptp->cycle.den, and numerator |
| 33 | * is 0.5 * HCLGE_PTP_CYCLE_ADJ_UNIT. | 51 | * is 0.5 * ptp->cycle.den. |
| 34 | */ | 52 | */ |
| 35 | quo = div_u64_rem(adj_val, HCLGE_PTP_CYCLE_ADJ_UNIT, &numerator); | 53 | quo = div_u64_rem(adj_val, cycle->den, &numerator); |
| 36 | 54 | ||
| 37 | spin_lock_irqsave(&hdev->ptp->lock, flags); | 55 | spin_lock_irqsave(&hdev->ptp->lock, flags); |
| 38 | writel(quo, hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG); | 56 | writel(quo & HCLGE_PTP_CYCLE_QUO_MASK, |
| 57 | hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG); | ||
| 39 | writel(numerator, hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG); | 58 | writel(numerator, hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG); |
| 40 | writel(HCLGE_PTP_CYCLE_ADJ_UNIT, | 59 | writel(cycle->den, hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG); |
| 41 | hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG); | ||
| 42 | writel(HCLGE_PTP_CYCLE_ADJ_EN, | 60 | writel(HCLGE_PTP_CYCLE_ADJ_EN, |
| 43 | hdev->ptp->io_base + HCLGE_PTP_CYCLE_CFG_REG); | 61 | hdev->ptp->io_base + HCLGE_PTP_CYCLE_CFG_REG); |
| 44 | spin_unlock_irqrestore(&hdev->ptp->lock, flags); | 62 | spin_unlock_irqrestore(&hdev->ptp->lock, flags); |
| @@ -475,6 +493,10 @@ int hclge_ptp_init(struct hclge_dev *hdev) · 430 unmodified lines | |||
| 475 | ret = hclge_ptp_create_clock(hdev); | 493 | ret = hclge_ptp_create_clock(hdev); |
| 476 | if (ret) | 494 | if (ret) |
| 477 | return ret; | 495 | return ret; |
| 496 | |||
| 497 | ret = hclge_ptp_get_cycle(hdev); | ||
| 498 | if (ret) | ||
| 499 | return ret; | ||
| 478 | } | 500 | } |
| 479 | 501 | ||
| 480 | ret = hclge_ptp_int_en(hdev, true); | 502 | ret = hclge_ptp_int_en(hdev, true); |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | #define HCLGE_PTP_TIME_ADJ_REG 0x60 | 29 | #define HCLGE_PTP_TIME_ADJ_REG 0x60 |
| 30 | #define HCLGE_PTP_TIME_ADJ_EN BIT(0) | 30 | #define HCLGE_PTP_TIME_ADJ_EN BIT(0) |
| 31 | #define HCLGE_PTP_CYCLE_QUO_REG 0x64 | 31 | #define HCLGE_PTP_CYCLE_QUO_REG 0x64 |
| 32 | #define HCLGE_PTP_CYCLE_QUO_MASK GENMASK(7, 0) | ||
| 32 | #define HCLGE_PTP_CYCLE_DEN_REG 0x68 | 33 | #define HCLGE_PTP_CYCLE_DEN_REG 0x68 |
| 33 | #define HCLGE_PTP_CYCLE_NUM_REG 0x6C | 34 | #define HCLGE_PTP_CYCLE_NUM_REG 0x6C |
| 34 | #define HCLGE_PTP_CYCLE_CFG_REG 0x70 | 35 | #define HCLGE_PTP_CYCLE_CFG_REG 0x70 |
| @@ -37,9 +38,7 @@ · 2 unmodified lines | |||
| 37 | #define HCLGE_PTP_CUR_TIME_SEC_L_REG 0x78 | 38 | #define HCLGE_PTP_CUR_TIME_SEC_L_REG 0x78 |
| 38 | #define HCLGE_PTP_CUR_TIME_NSEC_REG 0x7C | 39 | #define HCLGE_PTP_CUR_TIME_NSEC_REG 0x7C |
| 39 | 40 | ||
| 40 | #define HCLGE_PTP_CYCLE_ADJ_BASE 2 | ||
| 41 | #define HCLGE_PTP_CYCLE_ADJ_MAX 500000000 | 41 | #define HCLGE_PTP_CYCLE_ADJ_MAX 500000000 |
| 42 | #define HCLGE_PTP_CYCLE_ADJ_UNIT 100000000 | ||
| 43 | #define HCLGE_PTP_SEC_H_OFFSET 32u | 42 | #define HCLGE_PTP_SEC_H_OFFSET 32u |
| 44 | #define HCLGE_PTP_SEC_L_MASK GENMASK(31, 0) | 43 | #define HCLGE_PTP_SEC_L_MASK GENMASK(31, 0) |
| 45 | 44 | ||
| @@ -47,6 +46,12 @@ · 1 unmodified line | |||
| 47 | #define HCLGE_PTP_FLAG_TX_EN 1 | 46 | #define HCLGE_PTP_FLAG_TX_EN 1 |
| 48 | #define HCLGE_PTP_FLAG_RX_EN 2 | 47 | #define HCLGE_PTP_FLAG_RX_EN 2 |
| 49 | 48 | ||
| 49 | struct hclge_ptp_cycle { | ||
| 50 | u32 quo; | ||
| 51 | u32 numer; | ||
| 52 | u32 den; | ||
| 53 | }; | ||
| 54 | |||
| 50 | struct hclge_ptp { | 55 | struct hclge_ptp { |
| 51 | struct hclge_dev *hdev; | 56 | struct hclge_dev *hdev; |
| 52 | struct ptp_clock *clock; | 57 | struct ptp_clock *clock; |
| @@ -58,6 +63,7 @@ struct hclge_ptp { · 5 unmodified lines | |||
| 58 | spinlock_t lock; /* protects ptp registers */ | 63 | spinlock_t lock; /* protects ptp registers */ |
| 59 | u32 ptp_cfg; | 64 | u32 ptp_cfg; |
| 60 | u32 last_tx_seqid; | 65 | u32 last_tx_seqid; |
| 66 | struct hclge_ptp_cycle cycle; | ||
| 61 | unsigned long tx_start; | 67 | unsigned long tx_start; |
| 62 | unsigned long tx_cnt; | 68 | unsigned long tx_cnt; |
| 63 | unsigned long tx_skipped; | 69 | unsigned long tx_skipped; |
| @@ -2641,6 +2641,16 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) · 2640 unmodified lines | |||
| 2641 | 2641 | ||
| 2642 | static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) | 2642 | static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) |
| 2643 | { | 2643 | { |
| 2644 | struct hnae3_handle *nic = &hdev->nic; | ||
| 2645 | int ret; | ||
| 2646 | |||
| 2647 | ret = hclgevf_en_hw_strip_rxvtag(nic, true); | ||
| 2648 | if (ret) { | ||
| 2649 | dev_err(&hdev->pdev->dev, | ||
| 2650 | "failed to enable rx vlan offload, ret = %d\n", ret); | ||
| 2651 | return ret; | ||
| 2652 | } | ||
| 2653 | |||
| 2644 | return hclgevf_set_vlan_filter(&hdev->nic, htons(ETH_P_8021Q), 0, | 2654 | return hclgevf_set_vlan_filter(&hdev->nic, htons(ETH_P_8021Q), 0, |
| 2645 | false); | 2655 | false); |
| 2646 | } | 2656 | } |
| @@ -13,6 +13,7 @@ static int hclgevf_resp_to_errno(u16 resp_code) · 12 unmodified lines | |||
| 13 | return resp_code ? -resp_code : 0; | 13 | return resp_code ? -resp_code : 0; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | #define HCLGEVF_MBX_MATCH_ID_START 1 | ||
| 16 | static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev *hdev) | 17 | static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev *hdev) |
| 17 | { | 18 | { |
| 18 | /* this function should be called with mbx_resp.mbx_mutex held | 19 | /* this function should be called with mbx_resp.mbx_mutex held |
| @@ -21,6 +22,10 @@ static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev *hdev) · 2 unmodified lines | |||
| 21 | hdev->mbx_resp.received_resp = false; | 22 | hdev->mbx_resp.received_resp = false; |
| 22 | hdev->mbx_resp.origin_mbx_msg = 0; | 23 | hdev->mbx_resp.origin_mbx_msg = 0; |
| 23 | hdev->mbx_resp.resp_status = 0; | 24 | hdev->mbx_resp.resp_status = 0; |
| 25 | hdev->mbx_resp.match_id++; | ||
| 26 | /* Update match_id and ensure the value of match_id is not zero */ | ||
| 27 | if (hdev->mbx_resp.match_id == 0) | ||
| 28 | hdev->mbx_resp.match_id = HCLGEVF_MBX_MATCH_ID_START; | ||
| 24 | memset(hdev->mbx_resp.additional_info, 0, HCLGE_MBX_MAX_RESP_DATA_SIZE); | 29 | memset(hdev->mbx_resp.additional_info, 0, HCLGE_MBX_MAX_RESP_DATA_SIZE); |
| 25 | } | 30 | } |
| 26 | 31 | ||
| @@ -115,6 +120,7 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, · 88 unmodified lines | |||
| 115 | if (need_resp) { | 120 | if (need_resp) { |
| 116 | mutex_lock(&hdev->mbx_resp.mbx_mutex); | 121 | mutex_lock(&hdev->mbx_resp.mbx_mutex); |
| 117 | hclgevf_reset_mbx_resp_status(hdev); | 122 | hclgevf_reset_mbx_resp_status(hdev); |
| 123 | req->match_id = hdev->mbx_resp.match_id; | ||
| 118 | status = hclgevf_cmd_send(&hdev->hw, &desc, 1); | 124 | status = hclgevf_cmd_send(&hdev->hw, &desc, 1); |
| 119 | if (status) { | 125 | if (status) { |
| 120 | dev_err(&hdev->pdev->dev, | 126 | dev_err(&hdev->pdev->dev, |
| @@ -211,6 +217,19 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) · 90 unmodified lines | |||
| 211 | resp->additional_info[i] = *temp; | 217 | resp->additional_info[i] = *temp; |
| 212 | temp++; | 218 | temp++; |
| 213 | } | 219 | } |
| 220 | |||
| 221 | /* If match_id is not zero, it means PF support | ||
| 222 | * match_id. If the match_id is right, VF get the | ||
| 223 | * right response, otherwise ignore the response. | ||
| 224 | * Driver will clear hdev->mbx_resp when send | ||
| 225 | * next message which need response. | ||
| 226 | */ | ||
| 227 | if (req->match_id) { | ||
| 228 | if (req->match_id == resp->match_id) | ||
| 229 | resp->received_resp = true; | ||
| 230 | } else { | ||
| 231 | resp->received_resp = true; | ||
| 232 | } | ||
| 214 | break; | 233 | break; |
| 215 | case HCLGE_MBX_LINK_STAT_CHANGE: | 234 | case HCLGE_MBX_LINK_STAT_CHANGE: |
| 216 | case HCLGE_MBX_ASSERTING_RESET: | 235 | case HCLGE_MBX_ASSERTING_RESET: |
| @@ -1731,7 +1731,6 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) · 1730 unmodified lines | |||
| 1731 | tx_send_failed++; | 1731 | tx_send_failed++; |
| 1732 | tx_dropped++; | 1732 | tx_dropped++; |
| 1733 | ret = NETDEV_TX_OK; | 1733 | ret = NETDEV_TX_OK; |
| 1734 | ibmvnic_tx_scrq_flush(adapter, tx_scrq); | ||
| 1735 | goto out; | 1734 | goto out; |
| 1736 | } | 1735 | } |
| 1737 | 1736 | ||
| @@ -1753,6 +1752,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) · 15 unmodified lines | |||
| 1753 | dev_kfree_skb_any(skb); | 1752 | dev_kfree_skb_any(skb); |
| 1754 | tx_send_failed++; | 1753 | tx_send_failed++; |
| 1755 | tx_dropped++; | 1754 | tx_dropped++; |
| 1755 | ibmvnic_tx_scrq_flush(adapter, tx_scrq); | ||
| 1756 | ret = NETDEV_TX_OK; | 1756 | ret = NETDEV_TX_OK; |
| 1757 | goto out; | 1757 | goto out; |
| 1758 | } | 1758 | } |
| @@ -980,7 +980,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, · 979 unmodified lines | |||
| 980 | default: | 980 | default: |
| 981 | /* if we got here and link is up something bad is afoot */ | 981 | /* if we got here and link is up something bad is afoot */ |
| 982 | netdev_info(netdev, | 982 | netdev_info(netdev, |
| 983 | "WARNING: Link is up but PHY type 0x%x is not recognized.\n", | 983 | "WARNING: Link is up but PHY type 0x%x is not recognized, or incorrect cable is in use\n", |
| 984 | hw_link_info->phy_type); | 984 | hw_link_info->phy_type); |
| 985 | } | 985 | } |
| 986 | 986 | ||
| @@ -5294,6 +5294,10 @@ flags_complete: · 4307 unmodified lines | |||
| 5294 | dev_warn(&pf->pdev->dev, | 5294 | dev_warn(&pf->pdev->dev, |
| 5295 | "Device configuration forbids SW from starting the LLDP agent.\n"); | 5295 | "Device configuration forbids SW from starting the LLDP agent.\n"); |
| 5296 | return -EINVAL; | 5296 | return -EINVAL; |
| 5297 | case I40E_AQ_RC_EAGAIN: | ||
| 5298 | dev_warn(&pf->pdev->dev, | ||
| 5299 | "Stop FW LLDP agent command is still being processed, please try again in a second.\n"); | ||
| 5300 | return -EBUSY; | ||
| 5297 | default: | 5301 | default: |
| 5298 | dev_warn(&pf->pdev->dev, | 5302 | dev_warn(&pf->pdev->dev, |
| 5299 | "Starting FW LLDP agent failed: error: %s, %s\n", | 5303 | "Starting FW LLDP agent failed: error: %s, %s\n", |
| @@ -4454,11 +4454,10 @@ int i40e_control_wait_tx_q(int seid, struct i40e_pf *pf, int pf_q, · 4453 unmodified lines | |||
| 4454 | } | 4454 | } |
| 4455 | 4455 | ||
| 4456 | /** | 4456 | /** |
| 4457 | * i40e_vsi_control_tx - Start or stop a VSI's rings | 4457 | * i40e_vsi_enable_tx - Start a VSI's rings |
| 4458 | * @vsi: the VSI being configured | 4458 | * @vsi: the VSI being configured |
| 4459 | * @enable: start or stop the rings | ||
| 4460 | **/ | 4459 | **/ |
| 4461 | static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) | 4460 | static int i40e_vsi_enable_tx(struct i40e_vsi *vsi) |
| 4462 | { | 4461 | { |
| 4463 | struct i40e_pf *pf = vsi->back; | 4462 | struct i40e_pf *pf = vsi->back; |
| 4464 | int i, pf_q, ret = 0; | 4463 | int i, pf_q, ret = 0; |
| @@ -4467,7 +4466,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) · 2 unmodified lines | |||
| 4467 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { | 4466 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { |
| 4468 | ret = i40e_control_wait_tx_q(vsi->seid, pf, | 4467 | ret = i40e_control_wait_tx_q(vsi->seid, pf, |
| 4469 | pf_q, | 4468 | pf_q, |
| 4470 | false /*is xdp*/, enable); | 4469 | false /*is xdp*/, true); |
| 4471 | if (ret) | 4470 | if (ret) |
| 4472 | break; | 4471 | break; |
| 4473 | 4472 | ||
| @@ -4476,7 +4475,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) · 2 unmodified lines | |||
| 4476 | 4475 | ||
| 4477 | ret = i40e_control_wait_tx_q(vsi->seid, pf, | 4476 | ret = i40e_control_wait_tx_q(vsi->seid, pf, |
| 4478 | pf_q + vsi->alloc_queue_pairs, | 4477 | pf_q + vsi->alloc_queue_pairs, |
| 4479 | true /*is xdp*/, enable); | 4478 | true /*is xdp*/, true); |
| 4480 | if (ret) | 4479 | if (ret) |
| 4481 | break; | 4480 | break; |
| 4482 | } | 4481 | } |
| @@ -4574,32 +4573,25 @@ int i40e_control_wait_rx_q(struct i40e_pf *pf, int pf_q, bool enable) · 91 unmodified lines | |||
| 4574 | } | 4573 | } |
| 4575 | 4574 | ||
| 4576 | /** | 4575 | /** |
| 4577 | * i40e_vsi_control_rx - Start or stop a VSI's rings | 4576 | * i40e_vsi_enable_rx - Start a VSI's rings |
| 4578 | * @vsi: the VSI being configured | 4577 | * @vsi: the VSI being configured |
| 4579 | * @enable: start or stop the rings | ||
| 4580 | **/ | 4578 | **/ |
| 4581 | static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable) | 4579 | static int i40e_vsi_enable_rx(struct i40e_vsi *vsi) |
| 4582 | { | 4580 | { |
| 4583 | struct i40e_pf *pf = vsi->back; | 4581 | struct i40e_pf *pf = vsi->back; |
| 4584 | int i, pf_q, ret = 0; | 4582 | int i, pf_q, ret = 0; |
| 4585 | 4583 | ||
| 4586 | pf_q = vsi->base_queue; | 4584 | pf_q = vsi->base_queue; |
| 4587 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { | 4585 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { |
| 4588 | ret = i40e_control_wait_rx_q(pf, pf_q, enable); | 4586 | ret = i40e_control_wait_rx_q(pf, pf_q, true); |
| 4589 | if (ret) { | 4587 | if (ret) { |
| 4590 | dev_info(&pf->pdev->dev, | 4588 | dev_info(&pf->pdev->dev, |
| 4591 | "VSI seid %d Rx ring %d %sable timeout\n", | 4589 | "VSI seid %d Rx ring %d enable timeout\n", |
| 4592 | vsi->seid, pf_q, (enable ? "en" : "dis")); | 4590 | vsi->seid, pf_q); |
| 4593 | break; | 4591 | break; |
| 4594 | } | 4592 | } |
| 4595 | } | 4593 | } |
| 4596 | 4594 | ||
| 4597 | /* Due to HW errata, on Rx disable only, the register can indicate done | ||
| 4598 | * before it really is. Needs 50ms to be sure | ||
| 4599 | */ | ||
| 4600 | if (!enable) | ||
| 4601 | mdelay(50); | ||
| 4602 | |||
| 4603 | return ret; | 4595 | return ret; |
| 4604 | } | 4596 | } |
| 4605 | 4597 | ||
| @@ -4612,29 +4604,47 @@ int i40e_vsi_start_rings(struct i40e_vsi *vsi) · 6 unmodified lines | |||
| 4612 | int ret = 0; | 4604 | int ret = 0; |
| 4613 | 4605 | ||
| 4614 | /* do rx first for enable and last for disable */ | 4606 | /* do rx first for enable and last for disable */ |
| 4615 | ret = i40e_vsi_control_rx(vsi, true); | 4607 | ret = i40e_vsi_enable_rx(vsi); |
| 4616 | if (ret) | 4608 | if (ret) |
| 4617 | return ret; | 4609 | return ret; |
| 4618 | ret = i40e_vsi_control_tx(vsi, true); | 4610 | ret = i40e_vsi_enable_tx(vsi); |
| 4619 | 4611 | ||
| 4620 | return ret; | 4612 | return ret; |
| 4621 | } | 4613 | } |
| 4622 | 4614 | ||
| 4615 | #define I40E_DISABLE_TX_GAP_MSEC 50 | ||
| 4616 | |||
| 4623 | /** | 4617 | /** |
| 4624 | * i40e_vsi_stop_rings - Stop a VSI's rings | 4618 | * i40e_vsi_stop_rings - Stop a VSI's rings |
| 4625 | * @vsi: the VSI being configured | 4619 | * @vsi: the VSI being configured |
| 4626 | **/ | 4620 | **/ |
| 4627 | void i40e_vsi_stop_rings(struct i40e_vsi *vsi) | 4621 | void i40e_vsi_stop_rings(struct i40e_vsi *vsi) |
| 4628 | { | 4622 | { |
| 4623 | struct i40e_pf *pf = vsi->back; | ||
| 4624 | int pf_q, err, q_end; | ||
| 4625 | |||
| 4629 | /* When port TX is suspended, don't wait */ | 4626 | /* When port TX is suspended, don't wait */ |
| 4630 | if (test_bit(__I40E_PORT_SUSPENDED, vsi->back->state)) | 4627 | if (test_bit(__I40E_PORT_SUSPENDED, vsi->back->state)) |
| 4631 | return i40e_vsi_stop_rings_no_wait(vsi); | 4628 | return i40e_vsi_stop_rings_no_wait(vsi); |
| 4632 | 4629 | ||
| 4633 | /* do rx first for enable and last for disable | 4630 | q_end = vsi->base_queue + vsi->num_queue_pairs; |
| 4634 | * Ignore return value, we need to shutdown whatever we can | 4631 | for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) |
| 4635 | */ | 4632 | i40e_pre_tx_queue_cfg(&pf->hw, (u32)pf_q, false); |
| 4636 | i40e_vsi_control_tx(vsi, false); | 4633 | |
| 4637 | i40e_vsi_control_rx(vsi, false); | 4634 | for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) { |
| 4635 | err = i40e_control_wait_rx_q(pf, pf_q, false); | ||
| 4636 | if (err) | ||
| 4637 | dev_info(&pf->pdev->dev, | ||
| 4638 | "VSI seid %d Rx ring %d dissable timeout\n", | ||
| 4639 | vsi->seid, pf_q); | ||
| 4640 | } | ||
| 4641 | |||
| 4642 | msleep(I40E_DISABLE_TX_GAP_MSEC); | ||
| 4643 | pf_q = vsi->base_queue; | ||
| 4644 | for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) | ||
| 4645 | wr32(&pf->hw, I40E_QTX_ENA(pf_q), 0); | ||
| 4646 | |||
| 4647 | i40e_vsi_wait_queues_disabled(vsi); | ||
| 4638 | } | 4648 | } |
| 4639 | 4649 | ||
| 4640 | /** | 4650 | /** |
| @@ -7280,6 +7290,8 @@ static int i40e_validate_mqprio_qopt(struct i40e_vsi *vsi, · 2639 unmodified lines | |||
| 7280 | } | 7290 | } |
| 7281 | if (vsi->num_queue_pairs < | 7291 | if (vsi->num_queue_pairs < |
| 7282 | (mqprio_qopt->qopt.offset[i] + mqprio_qopt->qopt.count[i])) { | 7292 | (mqprio_qopt->qopt.offset[i] + mqprio_qopt->qopt.count[i])) { |
| 7293 | dev_err(&vsi->back->pdev->dev, | ||
| 7294 | "Failed to create traffic channel, insufficient number of queues.\n"); | ||
| 7283 | return -EINVAL; | 7295 | return -EINVAL; |
| 7284 | } | 7296 | } |
| 7285 | if (sum_max_rate > i40e_get_link_speed(vsi)) { | 7297 | if (sum_max_rate > i40e_get_link_speed(vsi)) { |
| @@ -13261,6 +13273,7 @@ static const struct net_device_ops i40e_netdev_ops = { · 5975 unmodified lines | |||
| 13261 | .ndo_poll_controller = i40e_netpoll, | 13273 | .ndo_poll_controller = i40e_netpoll, |
| 13262 | #endif | 13274 | #endif |
| 13263 | .ndo_setup_tc = __i40e_setup_tc, | 13275 | .ndo_setup_tc = __i40e_setup_tc, |
| 13276 | .ndo_select_queue = i40e_lan_select_queue, | ||
| 13264 | .ndo_set_features = i40e_set_features, | 13277 | .ndo_set_features = i40e_set_features, |
| 13265 | .ndo_set_vf_mac = i40e_ndo_set_vf_mac, | 13278 | .ndo_set_vf_mac = i40e_ndo_set_vf_mac, |
| 13266 | .ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan, | 13279 | .ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan, |
| @@ -3631,6 +3631,56 @@ dma_error: · 3630 unmodified lines | |||
| 3631 | return -1; | 3631 | return -1; |
| 3632 | } | 3632 | } |
| 3633 | 3633 | ||
| 3634 | static u16 i40e_swdcb_skb_tx_hash(struct net_device *dev, | ||
| 3635 | const struct sk_buff *skb, | ||
| 3636 | u16 num_tx_queues) | ||
| 3637 | { | ||
| 3638 | u32 jhash_initval_salt = 0xd631614b; | ||
| 3639 | u32 hash; | ||
| 3640 | |||
| 3641 | if (skb->sk && skb->sk->sk_hash) | ||
| 3642 | hash = skb->sk->sk_hash; | ||
| 3643 | else | ||
| 3644 | hash = (__force u16)skb->protocol ^ skb->hash; | ||
| 3645 | |||
| 3646 | hash = jhash_1word(hash, jhash_initval_salt); | ||
| 3647 | |||
| 3648 | return (u16)(((u64)hash * num_tx_queues) >> 32); | ||
| 3649 | } | ||
| 3650 | |||
| 3651 | u16 i40e_lan_select_queue(struct net_device *netdev, | ||
| 3652 | struct sk_buff *skb, | ||
| 3653 | struct net_device __always_unused *sb_dev) | ||
| 3654 | { | ||
| 3655 | struct i40e_netdev_priv *np = netdev_priv(netdev); | ||
| 3656 | struct i40e_vsi *vsi = np->vsi; | ||
| 3657 | struct i40e_hw *hw; | ||
| 3658 | u16 qoffset; | ||
| 3659 | u16 qcount; | ||
| 3660 | u8 tclass; | ||
| 3661 | u16 hash; | ||
| 3662 | u8 prio; | ||
| 3663 | |||
| 3664 | /* is DCB enabled at all? */ | ||
| 3665 | if (vsi->tc_config.numtc == 1) | ||
| 3666 | return i40e_swdcb_skb_tx_hash(netdev, skb, | ||
| 3667 | netdev->real_num_tx_queues); | ||
| 3668 | |||
| 3669 | prio = skb->priority; | ||
| 3670 | hw = &vsi->back->hw; | ||
| 3671 | tclass = hw->local_dcbx_config.etscfg.prioritytable[prio]; | ||
| 3672 | /* sanity check */ | ||
| 3673 | if (unlikely(!(vsi->tc_config.enabled_tc & BIT(tclass)))) | ||
| 3674 | tclass = 0; | ||
| 3675 | |||
| 3676 | /* select a queue assigned for the given TC */ | ||
| 3677 | qcount = vsi->tc_config.tc_info[tclass].qcount; | ||
| 3678 | hash = i40e_swdcb_skb_tx_hash(netdev, skb, qcount); | ||
| 3679 | |||
| 3680 | qoffset = vsi->tc_config.tc_info[tclass].qoffset; | ||
| 3681 | return qoffset + hash; | ||
| 3682 | } | ||
| 3683 | |||
| 3634 | /** | 3684 | /** |
| 3635 | * i40e_xmit_xdp_ring - transmits an XDP buffer to an XDP Tx ring | 3685 | * i40e_xmit_xdp_ring - transmits an XDP buffer to an XDP Tx ring |
| 3636 | * @xdpf: data to transmit | 3686 | * @xdpf: data to transmit |
| @@ -451,6 +451,8 @@ static inline unsigned int i40e_rx_pg_order(struct i40e_ring *ring) · 450 unmodified lines | |||
| 451 | 451 | ||
| 452 | bool i40e_alloc_rx_buffers(struct i40e_ring *rxr, u16 cleaned_count); | 452 | bool i40e_alloc_rx_buffers(struct i40e_ring *rxr, u16 cleaned_count); |
| 453 | netdev_tx_t i40e_lan_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | 453 | netdev_tx_t i40e_lan_xmit_frame(struct sk_buff *skb, struct net_device *netdev); |
| 454 | u16 i40e_lan_select_queue(struct net_device *netdev, struct sk_buff *skb, | ||
| 455 | struct net_device *sb_dev); | ||
| 454 | void i40e_clean_tx_ring(struct i40e_ring *tx_ring); | 456 | void i40e_clean_tx_ring(struct i40e_ring *tx_ring); |
| 455 | void i40e_clean_rx_ring(struct i40e_ring *rx_ring); | 457 | void i40e_clean_rx_ring(struct i40e_ring *rx_ring); |
| 456 | int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring); | 458 | int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring); |
| @@ -1825,7 +1825,8 @@ static void ixgbe_dma_sync_frag(struct ixgbe_ring *rx_ring, · 1824 unmodified lines | |||
| 1825 | struct sk_buff *skb) | 1825 | struct sk_buff *skb) |
| 1826 | { | 1826 | { |
| 1827 | if (ring_uses_build_skb(rx_ring)) { | 1827 | if (ring_uses_build_skb(rx_ring)) { |
| 1828 | unsigned long offset = (unsigned long)(skb->data) & ~PAGE_MASK; | 1828 | unsigned long mask = (unsigned long)ixgbe_rx_pg_size(rx_ring) - 1; |
| 1829 | unsigned long offset = (unsigned long)(skb->data) & mask; | ||
| 1829 | 1830 | ||
| 1830 | dma_sync_single_range_for_cpu(rx_ring->dev, | 1831 | dma_sync_single_range_for_cpu(rx_ring->dev, |
| 1831 | IXGBE_CB(skb)->dma, | 1832 | IXGBE_CB(skb)->dma, |
| @@ -10,4 +10,4 @@ obj-$(CONFIG_OCTEONTX2_AF) += rvu_af.o · 9 unmodified lines | |||
| 10 | rvu_mbox-y := mbox.o rvu_trace.o | 10 | rvu_mbox-y := mbox.o rvu_trace.o |
| 11 | rvu_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \ | 11 | rvu_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \ |
| 12 | rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \ | 12 | rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \ |
| 13 | rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o | 13 | rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o |
| @@ -1504,8 +1504,8 @@ static int cgx_lmac_init(struct cgx *cgx) · 1503 unmodified lines | |||
| 1504 | 1504 | ||
| 1505 | /* Add reference */ | 1505 | /* Add reference */ |
| 1506 | cgx->lmac_idmap[lmac->lmac_id] = lmac; | 1506 | cgx->lmac_idmap[lmac->lmac_id] = lmac; |
| 1507 | cgx->mac_ops->mac_pause_frm_config(cgx, lmac->lmac_id, true); | ||
| 1508 | set_bit(lmac->lmac_id, &cgx->lmac_bmap); | 1507 | set_bit(lmac->lmac_id, &cgx->lmac_bmap); |
| 1508 | cgx->mac_ops->mac_pause_frm_config(cgx, lmac->lmac_id, true); | ||
| 1509 | } | 1509 | } |
| 1510 | 1510 | ||
| 1511 | return cgx_lmac_verify_fwi_version(cgx); | 1511 | return cgx_lmac_verify_fwi_version(cgx); |
| @@ -151,7 +151,10 @@ enum npc_kpu_lh_ltype { · 150 unmodified lines | |||
| 151 | * Software assigns pkind for each incoming port such as CGX | 151 | * Software assigns pkind for each incoming port such as CGX |
| 152 | * Ethernet interfaces, LBK interfaces, etc. | 152 | * Ethernet interfaces, LBK interfaces, etc. |
| 153 | */ | 153 | */ |
| 154 | #define NPC_UNRESERVED_PKIND_COUNT NPC_RX_VLAN_EXDSA_PKIND | ||
| 155 | |||
| 154 | enum npc_pkind_type { | 156 | enum npc_pkind_type { |
| 157 | NPC_RX_LBK_PKIND = 0ULL, | ||
| 155 | NPC_RX_VLAN_EXDSA_PKIND = 56ULL, | 158 | NPC_RX_VLAN_EXDSA_PKIND = 56ULL, |
| 156 | NPC_RX_CHLEN24B_PKIND = 57ULL, | 159 | NPC_RX_CHLEN24B_PKIND = 57ULL, |
| 157 | NPC_RX_CPT_HDR_PKIND, | 160 | NPC_RX_CPT_HDR_PKIND, |
| @@ -391,8 +391,10 @@ void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf) · 390 unmodified lines | |||
| 391 | 391 | ||
| 392 | /* Get numVFs attached to this PF and first HWVF */ | 392 | /* Get numVFs attached to this PF and first HWVF */ |
| 393 | cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf)); | 393 | cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf)); |
| 394 | *numvfs = (cfg >> 12) & 0xFF; | 394 | if (numvfs) |
| 395 | *hwvf = cfg & 0xFFF; | 395 | *numvfs = (cfg >> 12) & 0xFF; |
| 396 | if (hwvf) | ||
| 397 | *hwvf = cfg & 0xFFF; | ||
| 396 | } | 398 | } |
| 397 | 399 | ||
| 398 | static int rvu_get_hwvf(struct rvu *rvu, int pcifunc) | 400 | static int rvu_get_hwvf(struct rvu *rvu, int pcifunc) |
| @@ -1314,7 +1316,7 @@ int rvu_mbox_handler_detach_resources(struct rvu *rvu, · 915 unmodified lines | |||
| 1314 | return rvu_detach_rsrcs(rvu, detach, detach->hdr.pcifunc); | 1316 | return rvu_detach_rsrcs(rvu, detach, detach->hdr.pcifunc); |
| 1315 | } | 1317 | } |
| 1316 | 1318 | ||
| 1317 | static int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc) | 1319 | int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc) |
| 1318 | { | 1320 | { |
| 1319 | struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); | 1321 | struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); |
| 1320 | int blkaddr = BLKADDR_NIX0, vf; | 1322 | int blkaddr = BLKADDR_NIX0, vf; |
| @@ -2859,6 +2861,12 @@ static int rvu_enable_sriov(struct rvu *rvu) · 1538 unmodified lines | |||
| 2859 | if (!vfs) | 2861 | if (!vfs) |
| 2860 | return 0; | 2862 | return 0; |
| 2861 | 2863 | ||
| 2864 | /* LBK channel number 63 is used for switching packets between | ||
| 2865 | * CGX mapped VFs. Hence limit LBK pairs till 62 only. | ||
| 2866 | */ | ||
| 2867 | if (vfs > 62) | ||
| 2868 | vfs = 62; | ||
| 2869 | |||
| 2862 | /* Save VFs number for reference in VF interrupts handlers. | 2870 | /* Save VFs number for reference in VF interrupts handlers. |
| 2863 | * Since interrupts might start arriving during SRIOV enablement | 2871 | * Since interrupts might start arriving during SRIOV enablement |
| 2864 | * ordinary API cannot be used to get number of enabled VFs. | 2872 | * ordinary API cannot be used to get number of enabled VFs. |
| @@ -3001,6 +3009,8 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 136 unmodified lines | |||
| 3001 | /* Initialize debugfs */ | 3009 | /* Initialize debugfs */ |
| 3002 | rvu_dbg_init(rvu); | 3010 | rvu_dbg_init(rvu); |
| 3003 | 3011 | ||
| 3012 | mutex_init(&rvu->rswitch.switch_lock); | ||
| 3013 | |||
| 3004 | return 0; | 3014 | return 0; |
| 3005 | err_dl: | 3015 | err_dl: |
| 3006 | rvu_unregister_dl(rvu); | 3016 | rvu_unregister_dl(rvu); |
| @@ -415,6 +415,16 @@ struct npc_kpu_profile_adapter { · 414 unmodified lines | |||
| 415 | size_t kpus; | 415 | size_t kpus; |
| 416 | }; | 416 | }; |
| 417 | 417 | ||
| 418 | #define RVU_SWITCH_LBK_CHAN 63 | ||
| 419 | |||
| 420 | struct rvu_switch { | ||
| 421 | struct mutex switch_lock; /* Serialize flow installation */ | ||
| 422 | u32 used_entries; | ||
| 423 | u16 *entry2pcifunc; | ||
| 424 | u16 mode; | ||
| 425 | u16 start_entry; | ||
| 426 | }; | ||
| 427 | |||
| 418 | struct rvu { | 428 | struct rvu { |
| 419 | void __iomem *afreg_base; | 429 | void __iomem *afreg_base; |
| 420 | void __iomem *pfreg_base; | 430 | void __iomem *pfreg_base; |
| @@ -445,6 +455,7 @@ struct rvu { · 24 unmodified lines | |||
| 445 | 455 | ||
| 446 | /* CGX */ | 456 | /* CGX */ |
| 447 | #define PF_CGXMAP_BASE 1 /* PF 0 is reserved for RVU PF */ | 457 | #define PF_CGXMAP_BASE 1 /* PF 0 is reserved for RVU PF */ |
| 458 | u16 cgx_mapped_vfs; /* maximum CGX mapped VFs */ | ||
| 448 | u8 cgx_mapped_pfs; | 459 | u8 cgx_mapped_pfs; |
| 449 | u8 cgx_cnt_max; /* CGX port count max */ | 460 | u8 cgx_cnt_max; /* CGX port count max */ |
| 450 | u8 *pf2cgxlmac_map; /* pf to cgx_lmac map */ | 461 | u8 *pf2cgxlmac_map; /* pf to cgx_lmac map */ |
| @@ -477,6 +488,9 @@ struct rvu { · 26 unmodified lines | |||
| 477 | struct rvu_debugfs rvu_dbg; | 488 | struct rvu_debugfs rvu_dbg; |
| 478 | #endif | 489 | #endif |
| 479 | struct rvu_devlink *rvu_dl; | 490 | struct rvu_devlink *rvu_dl; |
| 491 | |||
| 492 | /* RVU switch implementation over NPC with DMAC rules */ | ||
| 493 | struct rvu_switch rswitch; | ||
| 480 | }; | 494 | }; |
| 481 | 495 | ||
| 482 | static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) | 496 | static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) |
| @@ -691,6 +705,7 @@ int nix_aq_context_read(struct rvu *rvu, struct nix_hw *nix_hw, · 208 unmodified lines | |||
| 691 | struct nix_cn10k_aq_enq_req *aq_req, | 705 | struct nix_cn10k_aq_enq_req *aq_req, |
| 692 | struct nix_cn10k_aq_enq_rsp *aq_rsp, | 706 | struct nix_cn10k_aq_enq_rsp *aq_rsp, |
| 693 | u16 pcifunc, u8 ctype, u32 qidx); | 707 | u16 pcifunc, u8 ctype, u32 qidx); |
| 708 | int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc); | ||
| 694 | 709 | ||
| 695 | /* NPC APIs */ | 710 | /* NPC APIs */ |
| 696 | int rvu_npc_init(struct rvu *rvu); | 711 | int rvu_npc_init(struct rvu *rvu); |
| @@ -768,4 +783,10 @@ void rvu_dbg_exit(struct rvu *rvu); · 71 unmodified lines | |||
| 768 | static inline void rvu_dbg_init(struct rvu *rvu) {} | 783 | static inline void rvu_dbg_init(struct rvu *rvu) {} |
| 769 | static inline void rvu_dbg_exit(struct rvu *rvu) {} | 784 | static inline void rvu_dbg_exit(struct rvu *rvu) {} |
| 770 | #endif | 785 | #endif |
| 786 | |||
| 787 | /* RVU Switch */ | ||
| 788 | void rvu_switch_enable(struct rvu *rvu); | ||
| 789 | void rvu_switch_disable(struct rvu *rvu); | ||
| 790 | void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc); | ||
| 791 | |||
| 771 | #endif /* RVU_H */ | 792 | #endif /* RVU_H */ |
| @@ -126,6 +126,7 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu) · 125 unmodified lines | |||
| 126 | unsigned long lmac_bmap; | 126 | unsigned long lmac_bmap; |
| 127 | int size, free_pkind; | 127 | int size, free_pkind; |
| 128 | int cgx, lmac, iter; | 128 | int cgx, lmac, iter; |
| 129 | int numvfs, hwvfs; | ||
| 129 | 130 | ||
| 130 | if (!cgx_cnt_max) | 131 | if (!cgx_cnt_max) |
| 131 | return 0; | 132 | return 0; |
| @@ -166,6 +167,8 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu) · 34 unmodified lines | |||
| 166 | pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16; | 167 | pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16; |
| 167 | rvu_map_cgx_nix_block(rvu, pf, cgx, lmac); | 168 | rvu_map_cgx_nix_block(rvu, pf, cgx, lmac); |
| 168 | rvu->cgx_mapped_pfs++; | 169 | rvu->cgx_mapped_pfs++; |
| 170 | rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvfs); | ||
| 171 | rvu->cgx_mapped_vfs += numvfs; | ||
| 169 | pf++; | 172 | pf++; |
| 170 | } | 173 | } |
| 171 | } | 174 | } |
| @@ -2113,9 +2113,6 @@ static void rvu_print_npc_mcam_info(struct seq_file *s, · 2112 unmodified lines | |||
| 2113 | int entry_acnt, entry_ecnt; | 2113 | int entry_acnt, entry_ecnt; |
| 2114 | int cntr_acnt, cntr_ecnt; | 2114 | int cntr_acnt, cntr_ecnt; |
| 2115 | 2115 | ||
| 2116 | /* Skip PF0 */ | ||
| 2117 | if (!pcifunc) | ||
| 2118 | return; | ||
| 2119 | rvu_npc_get_mcam_entry_alloc_info(rvu, pcifunc, blkaddr, | 2116 | rvu_npc_get_mcam_entry_alloc_info(rvu, pcifunc, blkaddr, |
| 2120 | &entry_acnt, &entry_ecnt); | 2117 | &entry_acnt, &entry_ecnt); |
| 2121 | rvu_npc_get_mcam_counter_alloc_info(rvu, pcifunc, blkaddr, | 2118 | rvu_npc_get_mcam_counter_alloc_info(rvu, pcifunc, blkaddr, |
| @@ -2298,7 +2295,7 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s, · 176 unmodified lines | |||
| 2298 | static void rvu_dbg_npc_mcam_show_action(struct seq_file *s, | 2295 | static void rvu_dbg_npc_mcam_show_action(struct seq_file *s, |
| 2299 | struct rvu_npc_mcam_rule *rule) | 2296 | struct rvu_npc_mcam_rule *rule) |
| 2300 | { | 2297 | { |
| 2301 | if (rule->intf == NIX_INTF_TX) { | 2298 | if (is_npc_intf_tx(rule->intf)) { |
| 2302 | switch (rule->tx_action.op) { | 2299 | switch (rule->tx_action.op) { |
| 2303 | case NIX_TX_ACTIONOP_DROP: | 2300 | case NIX_TX_ACTIONOP_DROP: |
| 2304 | seq_puts(s, "\taction: Drop\n"); | 2301 | seq_puts(s, "\taction: Drop\n"); |
| @@ -1364,6 +1364,44 @@ static void rvu_health_reporters_destroy(struct rvu *rvu) · 1363 unmodified lines | |||
| 1364 | rvu_nix_health_reporters_destroy(rvu_dl); | 1364 | rvu_nix_health_reporters_destroy(rvu_dl); |
| 1365 | } | 1365 | } |
| 1366 | 1366 | ||
| 1367 | static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode) | ||
| 1368 | { | ||
| 1369 | struct rvu_devlink *rvu_dl = devlink_priv(devlink); | ||
| 1370 | struct rvu *rvu = rvu_dl->rvu; | ||
| 1371 | struct rvu_switch *rswitch; | ||
| 1372 | |||
| 1373 | rswitch = &rvu->rswitch; | ||
| 1374 | *mode = rswitch->mode; | ||
| 1375 | |||
| 1376 | return 0; | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, | ||
| 1380 | struct netlink_ext_ack *extack) | ||
| 1381 | { | ||
| 1382 | struct rvu_devlink *rvu_dl = devlink_priv(devlink); | ||
| 1383 | struct rvu *rvu = rvu_dl->rvu; | ||
| 1384 | struct rvu_switch *rswitch; | ||
| 1385 | |||
| 1386 | rswitch = &rvu->rswitch; | ||
| 1387 | switch (mode) { | ||
| 1388 | case DEVLINK_ESWITCH_MODE_LEGACY: | ||
| 1389 | case DEVLINK_ESWITCH_MODE_SWITCHDEV: | ||
| 1390 | if (rswitch->mode == mode) | ||
| 1391 | return 0; | ||
| 1392 | rswitch->mode = mode; | ||
| 1393 | if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) | ||
| 1394 | rvu_switch_enable(rvu); | ||
| 1395 | else | ||
| 1396 | rvu_switch_disable(rvu); | ||
| 1397 | break; | ||
| 1398 | default: | ||
| 1399 | return -EINVAL; | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | return 0; | ||
| 1403 | } | ||
| 1404 | |||
| 1367 | static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, | 1405 | static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, |
| 1368 | struct netlink_ext_ack *extack) | 1406 | struct netlink_ext_ack *extack) |
| 1369 | { | 1407 | { |
| @@ -1372,6 +1410,8 @@ static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req · 2 unmodified lines | |||
| 1372 | 1410 | ||
| 1373 | static const struct devlink_ops rvu_devlink_ops = { | 1411 | static const struct devlink_ops rvu_devlink_ops = { |
| 1374 | .info_get = rvu_devlink_info_get, | 1412 | .info_get = rvu_devlink_info_get, |
| 1413 | .eswitch_mode_get = rvu_devlink_eswitch_mode_get, | ||
| 1414 | .eswitch_mode_set = rvu_devlink_eswitch_mode_set, | ||
| 1375 | }; | 1415 | }; |
| 1376 | 1416 | ||
| 1377 | int rvu_register_dl(struct rvu *rvu) | 1417 | int rvu_register_dl(struct rvu *rvu) |
| @@ -1380,14 +1420,9 @@ int rvu_register_dl(struct rvu *rvu) · 2 unmodified lines | |||
| 1380 | struct devlink *dl; | 1420 | struct devlink *dl; |
| 1381 | int err; | 1421 | int err; |
| 1382 | 1422 | ||
| 1383 | rvu_dl = kzalloc(sizeof(*rvu_dl), GFP_KERNEL); | ||
| 1384 | if (!rvu_dl) | ||
| 1385 | return -ENOMEM; | ||
| 1386 | |||
| 1387 | dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink)); | 1423 | dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink)); |
| 1388 | if (!dl) { | 1424 | if (!dl) { |
| 1389 | dev_warn(rvu->dev, "devlink_alloc failed\n"); | 1425 | dev_warn(rvu->dev, "devlink_alloc failed\n"); |
| 1390 | kfree(rvu_dl); | ||
| 1391 | return -ENOMEM; | 1426 | return -ENOMEM; |
| 1392 | } | 1427 | } |
| 1393 | 1428 | ||
| @@ -1395,10 +1430,10 @@ int rvu_register_dl(struct rvu *rvu) · 1 unmodified line | |||
| 1395 | if (err) { | 1430 | if (err) { |
| 1396 | dev_err(rvu->dev, "devlink register failed with error %d\n", err); | 1431 | dev_err(rvu->dev, "devlink register failed with error %d\n", err); |
| 1397 | devlink_free(dl); | 1432 | devlink_free(dl); |
| 1398 | kfree(rvu_dl); | ||
| 1399 | return err; | 1433 | return err; |
| 1400 | } | 1434 | } |
| 1401 | 1435 | ||
| 1436 | rvu_dl = devlink_priv(dl); | ||
| 1402 | rvu_dl->dl = dl; | 1437 | rvu_dl->dl = dl; |
| 1403 | rvu_dl->rvu = rvu; | 1438 | rvu_dl->rvu = rvu; |
| 1404 | rvu->rvu_dl = rvu_dl; | 1439 | rvu->rvu_dl = rvu_dl; |
| @@ -1417,5 +1452,4 @@ void rvu_unregister_dl(struct rvu *rvu) · 12 unmodified lines | |||
| 1417 | rvu_health_reporters_destroy(rvu); | 1452 | rvu_health_reporters_destroy(rvu); |
| 1418 | devlink_unregister(dl); | 1453 | devlink_unregister(dl); |
| 1419 | devlink_free(dl); | 1454 | devlink_free(dl); |
| 1420 | kfree(rvu_dl); | ||
| 1421 | } | 1455 | } |
| @@ -196,11 +196,22 @@ static void nix_rx_sync(struct rvu *rvu, int blkaddr) · 195 unmodified lines | |||
| 196 | { | 196 | { |
| 197 | int err; | 197 | int err; |
| 198 | 198 | ||
| 199 | /*Sync all in flight RX packets to LLC/DRAM */ | 199 | /* Sync all in flight RX packets to LLC/DRAM */ |
| 200 | rvu_write64(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0)); | 200 | rvu_write64(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0)); |
| 201 | err = rvu_poll_reg(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0), true); | 201 | err = rvu_poll_reg(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0), true); |
| 202 | if (err) | 202 | if (err) |
| 203 | dev_err(rvu->dev, "NIX RX software sync failed\n"); | 203 | dev_err(rvu->dev, "SYNC1: NIX RX software sync failed\n"); |
| 204 | |||
| 205 | /* SW_SYNC ensures all existing transactions are finished and pkts | ||
| 206 | * are written to LLC/DRAM, queues should be teared down after | ||
| 207 | * successful SW_SYNC. Due to a HW errata, in some rare scenarios | ||
| 208 | * an existing transaction might end after SW_SYNC operation. To | ||
| 209 | * ensure operation is fully done, do the SW_SYNC twice. | ||
| 210 | */ | ||
| 211 | rvu_write64(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0)); | ||
| 212 | err = rvu_poll_reg(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0), true); | ||
| 213 | if (err) | ||
| 214 | dev_err(rvu->dev, "SYNC2: NIX RX software sync failed\n"); | ||
| 204 | } | 215 | } |
| 205 | 216 | ||
| 206 | static bool is_valid_txschq(struct rvu *rvu, int blkaddr, | 217 | static bool is_valid_txschq(struct rvu *rvu, int blkaddr, |
| @@ -298,6 +309,7 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf) · 91 unmodified lines | |||
| 298 | rvu_nix_chan_lbk(rvu, lbkid, vf + 1); | 309 | rvu_nix_chan_lbk(rvu, lbkid, vf + 1); |
| 299 | pfvf->rx_chan_cnt = 1; | 310 | pfvf->rx_chan_cnt = 1; |
| 300 | pfvf->tx_chan_cnt = 1; | 311 | pfvf->tx_chan_cnt = 1; |
| 312 | rvu_npc_set_pkind(rvu, NPC_RX_LBK_PKIND, pfvf); | ||
| 301 | rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf, | 313 | rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf, |
| 302 | pfvf->rx_chan_base, | 314 | pfvf->rx_chan_base, |
| 303 | pfvf->rx_chan_cnt); | 315 | pfvf->rx_chan_cnt); |
| @@ -1952,6 +1964,35 @@ static void nix_tl1_default_cfg(struct rvu *rvu, struct nix_hw *nix_hw, · 1648 unmodified lines | |||
| 1952 | pfvf_map[schq] = TXSCH_SET_FLAG(pfvf_map[schq], NIX_TXSCHQ_CFG_DONE); | 1964 | pfvf_map[schq] = TXSCH_SET_FLAG(pfvf_map[schq], NIX_TXSCHQ_CFG_DONE); |
| 1953 | } | 1965 | } |
| 1954 | 1966 | ||
| 1967 | static void rvu_nix_tx_tl2_cfg(struct rvu *rvu, int blkaddr, | ||
| 1968 | u16 pcifunc, struct nix_txsch *txsch) | ||
| 1969 | { | ||
| 1970 | struct rvu_hwinfo *hw = rvu->hw; | ||
| 1971 | int lbk_link_start, lbk_links; | ||
| 1972 | u8 pf = rvu_get_pf(pcifunc); | ||
| 1973 | int schq; | ||
| 1974 | |||
| 1975 | if (!is_pf_cgxmapped(rvu, pf)) | ||
| 1976 | return; | ||
| 1977 | |||
| 1978 | lbk_link_start = hw->cgx_links; | ||
| 1979 | |||
| 1980 | for (schq = 0; schq < txsch->schq.max; schq++) { | ||
| 1981 | if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc) | ||
| 1982 | continue; | ||
| 1983 | /* Enable all LBK links with channel 63 by default so that | ||
| 1984 | * packets can be sent to LBK with a NPC TX MCAM rule | ||
| 1985 | */ | ||
| 1986 | lbk_links = hw->lbk_links; | ||
| 1987 | while (lbk_links--) | ||
| 1988 | rvu_write64(rvu, blkaddr, | ||
| 1989 | NIX_AF_TL3_TL2X_LINKX_CFG(schq, | ||
| 1990 | lbk_link_start + | ||
| 1991 | lbk_links), | ||
| 1992 | BIT_ULL(12) | RVU_SWITCH_LBK_CHAN); | ||
| 1993 | } | ||
| 1994 | } | ||
| 1995 | |||
| 1955 | int rvu_mbox_handler_nix_txschq_cfg(struct rvu *rvu, | 1996 | int rvu_mbox_handler_nix_txschq_cfg(struct rvu *rvu, |
| 1956 | struct nix_txschq_config *req, | 1997 | struct nix_txschq_config *req, |
| 1957 | struct msg_rsp *rsp) | 1998 | struct msg_rsp *rsp) |
| @@ -2040,6 +2081,9 @@ int rvu_mbox_handler_nix_txschq_cfg(struct rvu *rvu, · 82 unmodified lines | |||
| 2040 | rvu_write64(rvu, blkaddr, reg, regval); | 2081 | rvu_write64(rvu, blkaddr, reg, regval); |
| 2041 | } | 2082 | } |
| 2042 | 2083 | ||
| 2084 | rvu_nix_tx_tl2_cfg(rvu, blkaddr, pcifunc, | ||
| 2085 | &nix_hw->txsch[NIX_TXSCH_LVL_TL2]); | ||
| 2086 | |||
| 2043 | return 0; | 2087 | return 0; |
| 2044 | } | 2088 | } |
| 2045 | 2089 | ||
| @@ -3180,6 +3224,8 @@ int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu, · 1134 unmodified lines | |||
| 3180 | if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf) | 3224 | if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf) |
| 3181 | ether_addr_copy(pfvf->default_mac, req->mac_addr); | 3225 | ether_addr_copy(pfvf->default_mac, req->mac_addr); |
| 3182 | 3226 | ||
| 3227 | rvu_switch_update_rules(rvu, pcifunc); | ||
| 3228 | |||
| 3183 | return 0; | 3229 | return 0; |
| 3184 | } | 3230 | } |
| 3185 | 3231 | ||
| @@ -3808,7 +3854,6 @@ static void rvu_nix_block_freemem(struct rvu *rvu, int blkaddr, · 622 unmodified lines | |||
| 3808 | vlan = &nix_hw->txvlan; | 3854 | vlan = &nix_hw->txvlan; |
| 3809 | kfree(vlan->rsrc.bmap); | 3855 | kfree(vlan->rsrc.bmap); |
| 3810 | mutex_destroy(&vlan->rsrc_lock); | 3856 | mutex_destroy(&vlan->rsrc_lock); |
| 3811 | devm_kfree(rvu->dev, vlan->entry2pfvf_map); | ||
| 3812 | 3857 | ||
| 3813 | mcast = &nix_hw->mcast; | 3858 | mcast = &nix_hw->mcast; |
| 3814 | qmem_free(rvu->dev, mcast->mce_ctx); | 3859 | qmem_free(rvu->dev, mcast->mce_ctx); |
| @@ -3849,6 +3894,8 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req, · 34 unmodified lines | |||
| 3849 | pfvf = rvu_get_pfvf(rvu, pcifunc); | 3894 | pfvf = rvu_get_pfvf(rvu, pcifunc); |
| 3850 | set_bit(NIXLF_INITIALIZED, &pfvf->flags); | 3895 | set_bit(NIXLF_INITIALIZED, &pfvf->flags); |
| 3851 | 3896 | ||
| 3897 | rvu_switch_update_rules(rvu, pcifunc); | ||
| 3898 | |||
| 3852 | return rvu_cgx_start_stop_io(rvu, pcifunc, true); | 3899 | return rvu_cgx_start_stop_io(rvu, pcifunc, true); |
| 3853 | } | 3900 | } |
| 3854 | 3901 | ||
| @@ -442,7 +442,8 @@ static void npc_fixup_vf_rule(struct rvu *rvu, struct npc_mcam *mcam, · 441 unmodified lines | |||
| 442 | owner = mcam->entry2pfvf_map[index]; | 442 | owner = mcam->entry2pfvf_map[index]; |
| 443 | target_func = (entry->action >> 4) & 0xffff; | 443 | target_func = (entry->action >> 4) & 0xffff; |
| 444 | /* do nothing when target is LBK/PF or owner is not PF */ | 444 | /* do nothing when target is LBK/PF or owner is not PF */ |
| 445 | if (is_afvf(target_func) || (owner & RVU_PFVF_FUNC_MASK) || | 445 | if (is_pffunc_af(owner) || is_afvf(target_func) || |
| 446 | (owner & RVU_PFVF_FUNC_MASK) || | ||
| 446 | !(target_func & RVU_PFVF_FUNC_MASK)) | 447 | !(target_func & RVU_PFVF_FUNC_MASK)) |
| 447 | return; | 448 | return; |
| 448 | 449 | ||
| @@ -468,6 +469,8 @@ static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, · 19 unmodified lines | |||
| 468 | { | 469 | { |
| 469 | int bank = npc_get_bank(mcam, index); | 470 | int bank = npc_get_bank(mcam, index); |
| 470 | int kw = 0, actbank, actindex; | 471 | int kw = 0, actbank, actindex; |
| 472 | u8 tx_intf_mask = ~intf & 0x3; | ||
| 473 | u8 tx_intf = intf; | ||
| 471 | u64 cam0, cam1; | 474 | u64 cam0, cam1; |
| 472 | 475 | ||
| 473 | actbank = bank; /* Save bank id, to set action later on */ | 476 | actbank = bank; /* Save bank id, to set action later on */ |
| @@ -488,12 +491,21 @@ static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, · 14 unmodified lines | |||
| 488 | */ | 491 | */ |
| 489 | for (; bank < (actbank + mcam->banks_per_entry); bank++, kw = kw + 2) { | 492 | for (; bank < (actbank + mcam->banks_per_entry); bank++, kw = kw + 2) { |
| 490 | /* Interface should be set in all banks */ | 493 | /* Interface should be set in all banks */ |
| 494 | if (is_npc_intf_tx(intf)) { | ||
| 495 | /* Last bit must be set and rest don't care | ||
| 496 | * for TX interfaces | ||
| 497 | */ | ||
| 498 | tx_intf_mask = 0x1; | ||
| 499 | tx_intf = intf & tx_intf_mask; | ||
| 500 | tx_intf_mask = ~tx_intf & tx_intf_mask; | ||
| 501 | } | ||
| 502 | |||
| 491 | rvu_write64(rvu, blkaddr, | 503 | rvu_write64(rvu, blkaddr, |
| 492 | NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 1), | 504 | NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 1), |
| 493 | intf); | 505 | tx_intf); |
| 494 | rvu_write64(rvu, blkaddr, | 506 | rvu_write64(rvu, blkaddr, |
| 495 | NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 0), | 507 | NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 0), |
| 496 | ~intf & 0x3); | 508 | tx_intf_mask); |
| 497 | 509 | ||
| 498 | /* Set the match key */ | 510 | /* Set the match key */ |
| 499 | npc_get_keyword(entry, kw, &cam0, &cam1); | 511 | npc_get_keyword(entry, kw, &cam0, &cam1); |
| @@ -650,6 +662,7 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc, · 150 unmodified lines | |||
| 650 | eth_broadcast_addr((u8 *)&req.mask.dmac); | 662 | eth_broadcast_addr((u8 *)&req.mask.dmac); |
| 651 | req.features = BIT_ULL(NPC_DMAC); | 663 | req.features = BIT_ULL(NPC_DMAC); |
| 652 | req.channel = chan; | 664 | req.channel = chan; |
| 665 | req.chan_mask = 0xFFFU; | ||
| 653 | req.intf = pfvf->nix_rx_intf; | 666 | req.intf = pfvf->nix_rx_intf; |
| 654 | req.op = action.op; | 667 | req.op = action.op; |
| 655 | req.hdr.pcifunc = 0; /* AF is requester */ | 668 | req.hdr.pcifunc = 0; /* AF is requester */ |
| @@ -799,6 +812,7 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc, · 143 unmodified lines | |||
| 799 | eth_broadcast_addr((u8 *)&req.mask.dmac); | 812 | eth_broadcast_addr((u8 *)&req.mask.dmac); |
| 800 | req.features = BIT_ULL(NPC_DMAC); | 813 | req.features = BIT_ULL(NPC_DMAC); |
| 801 | req.channel = chan; | 814 | req.channel = chan; |
| 815 | req.chan_mask = 0xFFFU; | ||
| 802 | req.intf = pfvf->nix_rx_intf; | 816 | req.intf = pfvf->nix_rx_intf; |
| 803 | req.entry = index; | 817 | req.entry = index; |
| 804 | req.hdr.pcifunc = 0; /* AF is requester */ | 818 | req.hdr.pcifunc = 0; /* AF is requester */ |
| @@ -1707,7 +1721,6 @@ static void npc_parser_profile_init(struct rvu *rvu, int blkaddr) · 902 unmodified lines | |||
| 1707 | { | 1721 | { |
| 1708 | struct rvu_hwinfo *hw = rvu->hw; | 1722 | struct rvu_hwinfo *hw = rvu->hw; |
| 1709 | int num_pkinds, num_kpus, idx; | 1723 | int num_pkinds, num_kpus, idx; |
| 1710 | struct npc_pkind *pkind; | ||
| 1711 | 1724 | ||
| 1712 | /* Disable all KPUs and their entries */ | 1725 | /* Disable all KPUs and their entries */ |
| 1713 | for (idx = 0; idx < hw->npc_kpus; idx++) { | 1726 | for (idx = 0; idx < hw->npc_kpus; idx++) { |
| @@ -1725,9 +1738,8 @@ static void npc_parser_profile_init(struct rvu *rvu, int blkaddr) · 11 unmodified lines | |||
| 1725 | * Check HW max count to avoid configuring junk or | 1738 | * Check HW max count to avoid configuring junk or |
| 1726 | * writing to unsupported CSR addresses. | 1739 | * writing to unsupported CSR addresses. |
| 1727 | */ | 1740 | */ |
| 1728 | pkind = &hw->pkind; | ||
| 1729 | num_pkinds = rvu->kpu.pkinds; | 1741 | num_pkinds = rvu->kpu.pkinds; |
| 1730 | num_pkinds = min_t(int, pkind->rsrc.max, num_pkinds); | 1742 | num_pkinds = min_t(int, hw->npc_pkinds, num_pkinds); |
| 1731 | 1743 | ||
| 1732 | for (idx = 0; idx < num_pkinds; idx++) | 1744 | for (idx = 0; idx < num_pkinds; idx++) |
| 1733 | npc_config_kpuaction(rvu, blkaddr, &rvu->kpu.ikpu[idx], 0, idx, true); | 1745 | npc_config_kpuaction(rvu, blkaddr, &rvu->kpu.ikpu[idx], 0, idx, true); |
| @@ -1745,6 +1757,8 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr) · 11 unmodified lines | |||
| 1745 | int nixlf_count = rvu_get_nixlf_count(rvu); | 1757 | int nixlf_count = rvu_get_nixlf_count(rvu); |
| 1746 | struct npc_mcam *mcam = &rvu->hw->mcam; | 1758 | struct npc_mcam *mcam = &rvu->hw->mcam; |
| 1747 | int rsvd, err; | 1759 | int rsvd, err; |
| 1760 | u16 index; | ||
| 1761 | int cntr; | ||
| 1748 | u64 cfg; | 1762 | u64 cfg; |
| 1749 | 1763 | ||
| 1750 | /* Actual number of MCAM entries vary by entry size */ | 1764 | /* Actual number of MCAM entries vary by entry size */ |
| @@ -1845,6 +1859,14 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr) · 94 unmodified lines | |||
| 1845 | if (!mcam->entry2target_pffunc) | 1859 | if (!mcam->entry2target_pffunc) |
| 1846 | goto free_mem; | 1860 | goto free_mem; |
| 1847 | 1861 | ||
| 1862 | for (index = 0; index < mcam->bmap_entries; index++) { | ||
| 1863 | mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP; | ||
| 1864 | mcam->entry2cntr_map[index] = NPC_MCAM_INVALID_MAP; | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | for (cntr = 0; cntr < mcam->counters.max; cntr++) | ||
| 1868 | mcam->cntr2pfvf_map[cntr] = NPC_MCAM_INVALID_MAP; | ||
| 1869 | |||
| 1848 | mutex_init(&mcam->lock); | 1870 | mutex_init(&mcam->lock); |
| 1849 | 1871 | ||
| 1850 | return 0; | 1872 | return 0; |
| @@ -1867,7 +1889,8 @@ static void rvu_npc_hw_init(struct rvu *rvu, int blkaddr) · 16 unmodified lines | |||
| 1867 | if (npc_const1 & BIT_ULL(63)) | 1889 | if (npc_const1 & BIT_ULL(63)) |
| 1868 | npc_const2 = rvu_read64(rvu, blkaddr, NPC_AF_CONST2); | 1890 | npc_const2 = rvu_read64(rvu, blkaddr, NPC_AF_CONST2); |
| 1869 | 1891 | ||
| 1870 | pkind->rsrc.max = (npc_const1 >> 12) & 0xFFULL; | 1892 | pkind->rsrc.max = NPC_UNRESERVED_PKIND_COUNT; |
| 1893 | hw->npc_pkinds = (npc_const1 >> 12) & 0xFFULL; | ||
| 1871 | hw->npc_kpu_entries = npc_const1 & 0xFFFULL; | 1894 | hw->npc_kpu_entries = npc_const1 & 0xFFFULL; |
| 1872 | hw->npc_kpus = (npc_const >> 8) & 0x1FULL; | 1895 | hw->npc_kpus = (npc_const >> 8) & 0x1FULL; |
| 1873 | hw->npc_intfs = npc_const & 0xFULL; | 1896 | hw->npc_intfs = npc_const & 0xFULL; |
| @@ -1978,6 +2001,10 @@ int rvu_npc_init(struct rvu *rvu) · 104 unmodified lines | |||
| 1978 | err = rvu_alloc_bitmap(&pkind->rsrc); | 2001 | err = rvu_alloc_bitmap(&pkind->rsrc); |
| 1979 | if (err) | 2002 | if (err) |
| 1980 | return err; | 2003 | return err; |
| 2004 | /* Reserve PKIND#0 for LBKs. Power reset value of LBK_CH_PKIND is '0', | ||
| 2005 | * no need to configure PKIND for all LBKs separately. | ||
| 2006 | */ | ||
| 2007 | rvu_alloc_rsrc(&pkind->rsrc); | ||
| 1981 | 2008 | ||
| 1982 | /* Allocate mem for pkind to PF and channel mapping info */ | 2009 | /* Allocate mem for pkind to PF and channel mapping info */ |
| 1983 | pkind->pfchan_map = devm_kcalloc(rvu->dev, pkind->rsrc.max, | 2010 | pkind->pfchan_map = devm_kcalloc(rvu->dev, pkind->rsrc.max, |
| @@ -2562,7 +2589,7 @@ int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu, · 578 unmodified lines | |||
| 2562 | } | 2589 | } |
| 2563 | 2590 | ||
| 2564 | /* Alloc request from PFFUNC with no NIXLF attached should be denied */ | 2591 | /* Alloc request from PFFUNC with no NIXLF attached should be denied */ |
| 2565 | if (!is_nixlf_attached(rvu, pcifunc)) | 2592 | if (!is_pffunc_af(pcifunc) && !is_nixlf_attached(rvu, pcifunc)) |
| 2566 | return NPC_MCAM_ALLOC_DENIED; | 2593 | return NPC_MCAM_ALLOC_DENIED; |
| 2567 | 2594 | ||
| 2568 | return npc_mcam_alloc_entries(mcam, pcifunc, req, rsp); | 2595 | return npc_mcam_alloc_entries(mcam, pcifunc, req, rsp); |
| @@ -2582,7 +2609,7 @@ int rvu_mbox_handler_npc_mcam_free_entry(struct rvu *rvu, · 13 unmodified lines | |||
| 2582 | return NPC_MCAM_INVALID_REQ; | 2609 | return NPC_MCAM_INVALID_REQ; |
| 2583 | 2610 | ||
| 2584 | /* Free request from PFFUNC with no NIXLF attached, ignore */ | 2611 | /* Free request from PFFUNC with no NIXLF attached, ignore */ |
| 2585 | if (!is_nixlf_attached(rvu, pcifunc)) | 2612 | if (!is_pffunc_af(pcifunc) && !is_nixlf_attached(rvu, pcifunc)) |
| 2586 | return NPC_MCAM_INVALID_REQ; | 2613 | return NPC_MCAM_INVALID_REQ; |
| 2587 | 2614 | ||
| 2588 | mutex_lock(&mcam->lock); | 2615 | mutex_lock(&mcam->lock); |
| @@ -2594,7 +2621,7 @@ int rvu_mbox_handler_npc_mcam_free_entry(struct rvu *rvu, · 5 unmodified lines | |||
| 2594 | if (rc) | 2621 | if (rc) |
| 2595 | goto exit; | 2622 | goto exit; |
| 2596 | 2623 | ||
| 2597 | mcam->entry2pfvf_map[req->entry] = 0; | 2624 | mcam->entry2pfvf_map[req->entry] = NPC_MCAM_INVALID_MAP; |
| 2598 | mcam->entry2target_pffunc[req->entry] = 0x0; | 2625 | mcam->entry2target_pffunc[req->entry] = 0x0; |
| 2599 | npc_mcam_clear_bit(mcam, req->entry); | 2626 | npc_mcam_clear_bit(mcam, req->entry); |
| 2600 | npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, false); | 2627 | npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, false); |
| @@ -2679,13 +2706,14 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu, · 78 unmodified lines | |||
| 2679 | else | 2706 | else |
| 2680 | nix_intf = pfvf->nix_rx_intf; | 2707 | nix_intf = pfvf->nix_rx_intf; |
| 2681 | 2708 | ||
| 2682 | if (npc_mcam_verify_channel(rvu, pcifunc, req->intf, channel)) { | 2709 | if (!is_pffunc_af(pcifunc) && |
| 2710 | npc_mcam_verify_channel(rvu, pcifunc, req->intf, channel)) { | ||
| 2683 | rc = NPC_MCAM_INVALID_REQ; | 2711 | rc = NPC_MCAM_INVALID_REQ; |
| 2684 | goto exit; | 2712 | goto exit; |
| 2685 | } | 2713 | } |
| 2686 | 2714 | ||
| 2687 | if (npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf, | 2715 | if (!is_pffunc_af(pcifunc) && |
| 2688 | pcifunc)) { | 2716 | npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf, pcifunc)) { |
| 2689 | rc = NPC_MCAM_INVALID_REQ; | 2717 | rc = NPC_MCAM_INVALID_REQ; |
| 2690 | goto exit; | 2718 | goto exit; |
| 2691 | } | 2719 | } |
| @@ -2836,7 +2864,7 @@ int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu, · 144 unmodified lines | |||
| 2836 | return NPC_MCAM_INVALID_REQ; | 2864 | return NPC_MCAM_INVALID_REQ; |
| 2837 | 2865 | ||
| 2838 | /* If the request is from a PFFUNC with no NIXLF attached, ignore */ | 2866 | /* If the request is from a PFFUNC with no NIXLF attached, ignore */ |
| 2839 | if (!is_nixlf_attached(rvu, pcifunc)) | 2867 | if (!is_pffunc_af(pcifunc) && !is_nixlf_attached(rvu, pcifunc)) |
| 2840 | return NPC_MCAM_INVALID_REQ; | 2868 | return NPC_MCAM_INVALID_REQ; |
| 2841 | 2869 | ||
| 2842 | /* Since list of allocated counter IDs needs to be sent to requester, | 2870 | /* Since list of allocated counter IDs needs to be sent to requester, |
| @@ -3081,7 +3109,7 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu, · 238 unmodified lines | |||
| 3081 | if (rc) { | 3109 | if (rc) { |
| 3082 | /* Free allocated MCAM entry */ | 3110 | /* Free allocated MCAM entry */ |
| 3083 | mutex_lock(&mcam->lock); | 3111 | mutex_lock(&mcam->lock); |
| 3084 | mcam->entry2pfvf_map[entry] = 0; | 3112 | mcam->entry2pfvf_map[entry] = NPC_MCAM_INVALID_MAP; |
| 3085 | npc_mcam_clear_bit(mcam, entry); | 3113 | npc_mcam_clear_bit(mcam, entry); |
| 3086 | mutex_unlock(&mcam->lock); | 3114 | mutex_unlock(&mcam->lock); |
| 3087 | return rc; | 3115 | return rc; |
| @@ -910,14 +910,17 @@ static void rvu_mcam_add_counter_to_rule(struct rvu *rvu, u16 pcifunc, · 909 unmodified lines | |||
| 910 | 910 | ||
| 911 | static void npc_update_rx_entry(struct rvu *rvu, struct rvu_pfvf *pfvf, | 911 | static void npc_update_rx_entry(struct rvu *rvu, struct rvu_pfvf *pfvf, |
| 912 | struct mcam_entry *entry, | 912 | struct mcam_entry *entry, |
| 913 | struct npc_install_flow_req *req, u16 target) | 913 | struct npc_install_flow_req *req, |
| 914 | u16 target, bool pf_set_vfs_mac) | ||
| 914 | { | 915 | { |
| 916 | struct rvu_switch *rswitch = &rvu->rswitch; | ||
| 915 | struct nix_rx_action action; | 917 | struct nix_rx_action action; |
| 916 | u64 chan_mask; | ||
| 917 | 918 | ||
| 918 | chan_mask = req->chan_mask ? req->chan_mask : ~0ULL; | 919 | if (rswitch->mode == DEVLINK_ESWITCH_MODE_SWITCHDEV && pf_set_vfs_mac) |
| 919 | npc_update_entry(rvu, NPC_CHAN, entry, req->channel, 0, chan_mask, 0, | 920 | req->chan_mask = 0x0; /* Do not care channel */ |
| 920 | NIX_INTF_RX); | 921 | |
| 922 | npc_update_entry(rvu, NPC_CHAN, entry, req->channel, 0, req->chan_mask, | ||
| 923 | 0, NIX_INTF_RX); | ||
| 921 | 924 | ||
| 922 | *(u64 *)&action = 0x00; | 925 | *(u64 *)&action = 0x00; |
| 923 | action.pf_func = target; | 926 | action.pf_func = target; |
| @@ -949,9 +952,16 @@ static void npc_update_tx_entry(struct rvu *rvu, struct rvu_pfvf *pfvf, · 25 unmodified lines | |||
| 949 | struct npc_install_flow_req *req, u16 target) | 952 | struct npc_install_flow_req *req, u16 target) |
| 950 | { | 953 | { |
| 951 | struct nix_tx_action action; | 954 | struct nix_tx_action action; |
| 955 | u64 mask = ~0ULL; | ||
| 956 | |||
| 957 | /* If AF is installing then do not care about | ||
| 958 | * PF_FUNC in Send Descriptor | ||
| 959 | */ | ||
| 960 | if (is_pffunc_af(req->hdr.pcifunc)) | ||
| 961 | mask = 0; | ||
| 952 | 962 | ||
| 953 | npc_update_entry(rvu, NPC_PF_FUNC, entry, (__force u16)htons(target), | 963 | npc_update_entry(rvu, NPC_PF_FUNC, entry, (__force u16)htons(target), |
| 954 | 0, ~0ULL, 0, NIX_INTF_TX); | 964 | 0, mask, 0, NIX_INTF_TX); |
| 955 | 965 | ||
| 956 | *(u64 *)&action = 0x00; | 966 | *(u64 *)&action = 0x00; |
| 957 | action.op = req->op; | 967 | action.op = req->op; |
| @@ -1002,7 +1012,7 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target, · 44 unmodified lines | |||
| 1002 | req->intf); | 1012 | req->intf); |
| 1003 | 1013 | ||
| 1004 | if (is_npc_intf_rx(req->intf)) | 1014 | if (is_npc_intf_rx(req->intf)) |
| 1005 | npc_update_rx_entry(rvu, pfvf, entry, req, target); | 1015 | npc_update_rx_entry(rvu, pfvf, entry, req, target, pf_set_vfs_mac); |
| 1006 | else | 1016 | else |
| 1007 | npc_update_tx_entry(rvu, pfvf, entry, req, target); | 1017 | npc_update_tx_entry(rvu, pfvf, entry, req, target); |
| 1008 | 1018 | ||
| @@ -1164,7 +1174,9 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu, · 155 unmodified lines | |||
| 1164 | if (err) | 1174 | if (err) |
| 1165 | return err; | 1175 | return err; |
| 1166 | 1176 | ||
| 1167 | if (npc_mcam_verify_channel(rvu, target, req->intf, req->channel)) | 1177 | /* Skip channel validation if AF is installing */ |
| 1178 | if (!is_pffunc_af(req->hdr.pcifunc) && | ||
| 1179 | npc_mcam_verify_channel(rvu, target, req->intf, req->channel)) | ||
| 1168 | return -EINVAL; | 1180 | return -EINVAL; |
| 1169 | 1181 | ||
| 1170 | pfvf = rvu_get_pfvf(rvu, target); | 1182 | pfvf = rvu_get_pfvf(rvu, target); |
| @@ -1180,6 +1192,7 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu, · 9 unmodified lines | |||
| 1180 | eth_broadcast_addr((u8 *)&req->mask.dmac); | 1192 | eth_broadcast_addr((u8 *)&req->mask.dmac); |
| 1181 | } | 1193 | } |
| 1182 | 1194 | ||
| 1195 | /* Proceed if NIXLF is attached or not for TX rules */ | ||
| 1183 | err = nix_get_nixlf(rvu, target, &nixlf, NULL); | 1196 | err = nix_get_nixlf(rvu, target, &nixlf, NULL); |
| 1184 | if (err && is_npc_intf_rx(req->intf) && !pf_set_vfs_mac) | 1197 | if (err && is_npc_intf_rx(req->intf) && !pf_set_vfs_mac) |
| 1185 | return -EINVAL; | 1198 | return -EINVAL; |
| @@ -0,0 +1,259 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* Marvell OcteonTx2 RVU Admin Function driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2021 Marvell. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/bitfield.h> | ||
| 8 | #include "rvu.h" | ||
| 9 | |||
| 10 | static int rvu_switch_install_rx_rule(struct rvu *rvu, u16 pcifunc, | ||
| 11 | u16 chan_mask) | ||
| 12 | { | ||
| 13 | struct npc_install_flow_req req = { 0 }; | ||
| 14 | struct npc_install_flow_rsp rsp = { 0 }; | ||
| 15 | struct rvu_pfvf *pfvf; | ||
| 16 | |||
| 17 | pfvf = rvu_get_pfvf(rvu, pcifunc); | ||
| 18 | /* If the pcifunc is not initialized then nothing to do. | ||
| 19 | * This same function will be called again via rvu_switch_update_rules | ||
| 20 | * after pcifunc is initialized. | ||
| 21 | */ | ||
| 22 | if (!test_bit(NIXLF_INITIALIZED, &pfvf->flags)) | ||
| 23 | return 0; | ||
| 24 | |||
| 25 | ether_addr_copy(req.packet.dmac, pfvf->mac_addr); | ||
| 26 | eth_broadcast_addr((u8 *)&req.mask.dmac); | ||
| 27 | req.hdr.pcifunc = 0; /* AF is requester */ | ||
| 28 | req.vf = pcifunc; | ||
| 29 | req.features = BIT_ULL(NPC_DMAC); | ||
| 30 | req.channel = pfvf->rx_chan_base; | ||
| 31 | req.chan_mask = chan_mask; | ||
| 32 | req.intf = pfvf->nix_rx_intf; | ||
| 33 | req.op = NIX_RX_ACTION_DEFAULT; | ||
| 34 | req.default_rule = 1; | ||
| 35 | |||
| 36 | return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); | ||
| 37 | } | ||
| 38 | |||
| 39 | static int rvu_switch_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry) | ||
| 40 | { | ||
| 41 | struct npc_install_flow_req req = { 0 }; | ||
| 42 | struct npc_install_flow_rsp rsp = { 0 }; | ||
| 43 | struct rvu_pfvf *pfvf; | ||
| 44 | u8 lbkid; | ||
| 45 | |||
| 46 | pfvf = rvu_get_pfvf(rvu, pcifunc); | ||
| 47 | /* If the pcifunc is not initialized then nothing to do. | ||
| 48 | * This same function will be called again via rvu_switch_update_rules | ||
| 49 | * after pcifunc is initialized. | ||
| 50 | */ | ||
| 51 | if (!test_bit(NIXLF_INITIALIZED, &pfvf->flags)) | ||
| 52 | return 0; | ||
| 53 | |||
| 54 | lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1; | ||
| 55 | ether_addr_copy(req.packet.dmac, pfvf->mac_addr); | ||
| 56 | eth_broadcast_addr((u8 *)&req.mask.dmac); | ||
| 57 | req.hdr.pcifunc = 0; /* AF is requester */ | ||
| 58 | req.vf = pcifunc; | ||
| 59 | req.entry = entry; | ||
| 60 | req.features = BIT_ULL(NPC_DMAC); | ||
| 61 | req.intf = pfvf->nix_tx_intf; | ||
| 62 | req.op = NIX_TX_ACTIONOP_UCAST_CHAN; | ||
| 63 | req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN; | ||
| 64 | req.set_cntr = 1; | ||
| 65 | |||
| 66 | return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); | ||
| 67 | } | ||
| 68 | |||
| 69 | static int rvu_switch_install_rules(struct rvu *rvu) | ||
| 70 | { | ||
| 71 | struct rvu_switch *rswitch = &rvu->rswitch; | ||
| 72 | u16 start = rswitch->start_entry; | ||
| 73 | struct rvu_hwinfo *hw = rvu->hw; | ||
| 74 | u16 pcifunc, entry = 0; | ||
| 75 | int pf, vf, numvfs; | ||
| 76 | int err; | ||
| 77 | |||
| 78 | for (pf = 1; pf < hw->total_pfs; pf++) { | ||
| 79 | if (!is_pf_cgxmapped(rvu, pf)) | ||
| 80 | continue; | ||
| 81 | |||
| 82 | pcifunc = pf << 10; | ||
| 83 | /* rvu_get_nix_blkaddr sets up the corresponding NIX block | ||
| 84 | * address and NIX RX and TX interfaces for a pcifunc. | ||
| 85 | * Generally it is called during attach call of a pcifunc but it | ||
| 86 | * is called here since we are pre-installing rules before | ||
| 87 | * nixlfs are attached | ||
| 88 | */ | ||
| 89 | rvu_get_nix_blkaddr(rvu, pcifunc); | ||
| 90 | |||
| 91 | /* MCAM RX rule for a PF/VF already exists as default unicast | ||
| 92 | * rules installed by AF. Hence change the channel in those | ||
| 93 | * rules to ignore channel so that packets with the required | ||
| 94 | * DMAC received from LBK(by other PF/VFs in system) or from | ||
| 95 | * external world (from wire) are accepted. | ||
| 96 | */ | ||
| 97 | err = rvu_switch_install_rx_rule(rvu, pcifunc, 0x0); | ||
| 98 | if (err) { | ||
| 99 | dev_err(rvu->dev, "RX rule for PF%d failed(%d)\n", | ||
| 100 | pf, err); | ||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 104 | err = rvu_switch_install_tx_rule(rvu, pcifunc, start + entry); | ||
| 105 | if (err) { | ||
| 106 | dev_err(rvu->dev, "TX rule for PF%d failed(%d)\n", | ||
| 107 | pf, err); | ||
| 108 | return err; | ||
| 109 | } | ||
| 110 | |||
| 111 | rswitch->entry2pcifunc[entry++] = pcifunc; | ||
| 112 | |||
| 113 | rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL); | ||
| 114 | for (vf = 0; vf < numvfs; vf++) { | ||
| 115 | pcifunc = pf << 10 | ((vf + 1) & 0x3FF); | ||
| 116 | rvu_get_nix_blkaddr(rvu, pcifunc); | ||
| 117 | |||
| 118 | err = rvu_switch_install_rx_rule(rvu, pcifunc, 0x0); | ||
| 119 | if (err) { | ||
| 120 | dev_err(rvu->dev, | ||
| 121 | "RX rule for PF%dVF%d failed(%d)\n", | ||
| 122 | pf, vf, err); | ||
| 123 | return err; | ||
| 124 | } | ||
| 125 | |||
| 126 | err = rvu_switch_install_tx_rule(rvu, pcifunc, | ||
| 127 | start + entry); | ||
| 128 | if (err) { | ||
| 129 | dev_err(rvu->dev, | ||
| 130 | "TX rule for PF%dVF%d failed(%d)\n", | ||
| 131 | pf, vf, err); | ||
| 132 | return err; | ||
| 133 | } | ||
| 134 | |||
| 135 | rswitch->entry2pcifunc[entry++] = pcifunc; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | |||
| 142 | void rvu_switch_enable(struct rvu *rvu) | ||
| 143 | { | ||
| 144 | struct npc_mcam_alloc_entry_req alloc_req = { 0 }; | ||
| 145 | struct npc_mcam_alloc_entry_rsp alloc_rsp = { 0 }; | ||
| 146 | struct npc_delete_flow_req uninstall_req = { 0 }; | ||
| 147 | struct npc_mcam_free_entry_req free_req = { 0 }; | ||
| 148 | struct rvu_switch *rswitch = &rvu->rswitch; | ||
| 149 | struct msg_rsp rsp; | ||
| 150 | int ret; | ||
| 151 | |||
| 152 | alloc_req.contig = true; | ||
| 153 | alloc_req.count = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs; | ||
| 154 | ret = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req, | ||
| 155 | &alloc_rsp); | ||
| 156 | if (ret) { | ||
| 157 | dev_err(rvu->dev, | ||
| 158 | "Unable to allocate MCAM entries\n"); | ||
| 159 | goto exit; | ||
| 160 | } | ||
| 161 | |||
| 162 | if (alloc_rsp.count != alloc_req.count) { | ||
| 163 | dev_err(rvu->dev, | ||
| 164 | "Unable to allocate %d MCAM entries, got %d\n", | ||
| 165 | alloc_req.count, alloc_rsp.count); | ||
| 166 | goto free_entries; | ||
| 167 | } | ||
| 168 | |||
| 169 | rswitch->entry2pcifunc = kcalloc(alloc_req.count, sizeof(u16), | ||
| 170 | GFP_KERNEL); | ||
| 171 | if (!rswitch->entry2pcifunc) | ||
| 172 | goto free_entries; | ||
| 173 | |||
| 174 | rswitch->used_entries = alloc_rsp.count; | ||
| 175 | rswitch->start_entry = alloc_rsp.entry; | ||
| 176 | |||
| 177 | ret = rvu_switch_install_rules(rvu); | ||
| 178 | if (ret) | ||
| 179 | goto uninstall_rules; | ||
| 180 | |||
| 181 | return; | ||
| 182 | |||
| 183 | uninstall_rules: | ||
| 184 | uninstall_req.start = rswitch->start_entry; | ||
| 185 | uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1; | ||
| 186 | rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &rsp); | ||
| 187 | kfree(rswitch->entry2pcifunc); | ||
| 188 | free_entries: | ||
| 189 | free_req.all = 1; | ||
| 190 | rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp); | ||
| 191 | exit: | ||
| 192 | return; | ||
| 193 | } | ||
| 194 | |||
| 195 | void rvu_switch_disable(struct rvu *rvu) | ||
| 196 | { | ||
| 197 | struct npc_delete_flow_req uninstall_req = { 0 }; | ||
| 198 | struct npc_mcam_free_entry_req free_req = { 0 }; | ||
| 199 | struct rvu_switch *rswitch = &rvu->rswitch; | ||
| 200 | struct rvu_hwinfo *hw = rvu->hw; | ||
| 201 | int pf, vf, numvfs; | ||
| 202 | struct msg_rsp rsp; | ||
| 203 | u16 pcifunc; | ||
| 204 | int err; | ||
| 205 | |||
| 206 | if (!rswitch->used_entries) | ||
| 207 | return; | ||
| 208 | |||
| 209 | for (pf = 1; pf < hw->total_pfs; pf++) { | ||
| 210 | if (!is_pf_cgxmapped(rvu, pf)) | ||
| 211 | continue; | ||
| 212 | |||
| 213 | pcifunc = pf << 10; | ||
| 214 | err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF); | ||
| 215 | if (err) | ||
| 216 | dev_err(rvu->dev, | ||
| 217 | "Reverting RX rule for PF%d failed(%d)\n", | ||
| 218 | pf, err); | ||
| 219 | |||
| 220 | rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL); | ||
| 221 | for (vf = 0; vf < numvfs; vf++) { | ||
| 222 | pcifunc = pf << 10 | ((vf + 1) & 0x3FF); | ||
| 223 | err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF); | ||
| 224 | if (err) | ||
| 225 | dev_err(rvu->dev, | ||
| 226 | "Reverting RX rule for PF%dVF%d failed(%d)\n", | ||
| 227 | pf, vf, err); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | uninstall_req.start = rswitch->start_entry; | ||
| 232 | uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1; | ||
| 233 | free_req.all = 1; | ||
| 234 | rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &rsp); | ||
| 235 | rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp); | ||
| 236 | rswitch->used_entries = 0; | ||
| 237 | kfree(rswitch->entry2pcifunc); | ||
| 238 | } | ||
| 239 | |||
| 240 | void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc) | ||
| 241 | { | ||
| 242 | struct rvu_switch *rswitch = &rvu->rswitch; | ||
| 243 | u32 max = rswitch->used_entries; | ||
| 244 | u16 entry; | ||
| 245 | |||
| 246 | if (!rswitch->used_entries) | ||
| 247 | return; | ||
| 248 | |||
| 249 | for (entry = 0; entry < max; entry++) { | ||
| 250 | if (rswitch->entry2pcifunc[entry] == pcifunc) | ||
| 251 | break; | ||
| 252 | } | ||
| 253 | |||
| 254 | if (entry >= max) | ||
| 255 | return; | ||
| 256 | |||
| 257 | rvu_switch_install_tx_rule(rvu, pcifunc, rswitch->start_entry + entry); | ||
| 258 | rvu_switch_install_rx_rule(rvu, pcifunc, 0x0); | ||
| 259 | } | ||
| @@ -924,12 +924,14 @@ static int otx2_cq_init(struct otx2_nic *pfvf, u16 qidx) · 923 unmodified lines | |||
| 924 | aq->cq.drop = RQ_DROP_LVL_CQ(pfvf->hw.rq_skid, cq->cqe_cnt); | 924 | aq->cq.drop = RQ_DROP_LVL_CQ(pfvf->hw.rq_skid, cq->cqe_cnt); |
| 925 | aq->cq.drop_ena = 1; | 925 | aq->cq.drop_ena = 1; |
| 926 | 926 | ||
| 927 | /* Enable receive CQ backpressure */ | 927 | if (!is_otx2_lbkvf(pfvf->pdev)) { |
| 928 | aq->cq.bp_ena = 1; | 928 | /* Enable receive CQ backpressure */ |
| 929 | aq->cq.bpid = pfvf->bpid[0]; | 929 | aq->cq.bp_ena = 1; |
| 930 | aq->cq.bpid = pfvf->bpid[0]; | ||
| 930 | 931 | ||
| 931 | /* Set backpressure level is same as cq pass level */ | 932 | /* Set backpressure level is same as cq pass level */ |
| 932 | aq->cq.bp = RQ_PASS_LVL_CQ(pfvf->hw.rq_skid, qset->rqe_cnt); | 933 | aq->cq.bp = RQ_PASS_LVL_CQ(pfvf->hw.rq_skid, qset->rqe_cnt); |
| 934 | } | ||
| 933 | } | 935 | } |
| 934 | 936 | ||
| 935 | /* Fill AQ info */ | 937 | /* Fill AQ info */ |
| @@ -1186,7 +1188,7 @@ static int otx2_aura_init(struct otx2_nic *pfvf, int aura_id, · 250 unmodified lines | |||
| 1186 | aq->aura.fc_hyst_bits = 0; /* Store count on all updates */ | 1188 | aq->aura.fc_hyst_bits = 0; /* Store count on all updates */ |
| 1187 | 1189 | ||
| 1188 | /* Enable backpressure for RQ aura */ | 1190 | /* Enable backpressure for RQ aura */ |
| 1189 | if (aura_id < pfvf->hw.rqpool_cnt) { | 1191 | if (aura_id < pfvf->hw.rqpool_cnt && !is_otx2_lbkvf(pfvf->pdev)) { |
| 1190 | aq->aura.bp_ena = 0; | 1192 | aq->aura.bp_ena = 0; |
| 1191 | aq->aura.nix0_bpid = pfvf->bpid[0]; | 1193 | aq->aura.nix0_bpid = pfvf->bpid[0]; |
| 1192 | /* Set backpressure level for RQ's Aura */ | 1194 | /* Set backpressure level for RQ's Aura */ |
| @@ -298,15 +298,14 @@ static int otx2_set_channels(struct net_device *dev, · 297 unmodified lines | |||
| 298 | err = otx2_set_real_num_queues(dev, channel->tx_count, | 298 | err = otx2_set_real_num_queues(dev, channel->tx_count, |
| 299 | channel->rx_count); | 299 | channel->rx_count); |
| 300 | if (err) | 300 | if (err) |
| 301 | goto fail; | 301 | return err; |
| 302 | 302 | ||
| 303 | pfvf->hw.rx_queues = channel->rx_count; | 303 | pfvf->hw.rx_queues = channel->rx_count; |
| 304 | pfvf->hw.tx_queues = channel->tx_count; | 304 | pfvf->hw.tx_queues = channel->tx_count; |
| 305 | pfvf->qset.cq_cnt = pfvf->hw.tx_queues + pfvf->hw.rx_queues; | 305 | pfvf->qset.cq_cnt = pfvf->hw.tx_queues + pfvf->hw.rx_queues; |
| 306 | 306 | ||
| 307 | fail: | ||
| 308 | if (if_up) | 307 | if (if_up) |
| 309 | dev->netdev_ops->ndo_open(dev); | 308 | err = dev->netdev_ops->ndo_open(dev); |
| 310 | 309 | ||
| 311 | netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n", | 310 | netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n", |
| 312 | pfvf->hw.tx_queues, pfvf->hw.rx_queues); | 311 | pfvf->hw.tx_queues, pfvf->hw.rx_queues); |
| @@ -410,7 +409,7 @@ static int otx2_set_ringparam(struct net_device *netdev, · 97 unmodified lines | |||
| 410 | qs->rqe_cnt = rx_count; | 409 | qs->rqe_cnt = rx_count; |
| 411 | 410 | ||
| 412 | if (if_up) | 411 | if (if_up) |
| 413 | netdev->netdev_ops->ndo_open(netdev); | 412 | return netdev->netdev_ops->ndo_open(netdev); |
| 414 | 413 | ||
| 415 | return 0; | 414 | return 0; |
| 416 | } | 415 | } |
| @@ -1662,6 +1662,7 @@ int otx2_open(struct net_device *netdev) · 1661 unmodified lines | |||
| 1662 | err_tx_stop_queues: | 1662 | err_tx_stop_queues: |
| 1663 | netif_tx_stop_all_queues(netdev); | 1663 | netif_tx_stop_all_queues(netdev); |
| 1664 | netif_carrier_off(netdev); | 1664 | netif_carrier_off(netdev); |
| 1665 | pf->flags |= OTX2_FLAG_INTF_DOWN; | ||
| 1665 | err_free_cints: | 1666 | err_free_cints: |
| 1666 | otx2_free_cints(pf, qidx); | 1667 | otx2_free_cints(pf, qidx); |
| 1667 | vec = pci_irq_vector(pf->pdev, | 1668 | vec = pci_irq_vector(pf->pdev, |
| @@ -1689,6 +1690,10 @@ int otx2_stop(struct net_device *netdev) · 21 unmodified lines | |||
| 1689 | struct otx2_rss_info *rss; | 1690 | struct otx2_rss_info *rss; |
| 1690 | int qidx, vec, wrk; | 1691 | int qidx, vec, wrk; |
| 1691 | 1692 | ||
| 1693 | /* If the DOWN flag is set resources are already freed */ | ||
| 1694 | if (pf->flags & OTX2_FLAG_INTF_DOWN) | ||
| 1695 | return 0; | ||
| 1696 | |||
| 1692 | netif_carrier_off(netdev); | 1697 | netif_carrier_off(netdev); |
| 1693 | netif_tx_stop_all_queues(netdev); | 1698 | netif_tx_stop_all_queues(netdev); |
| 1694 | 1699 | ||
| @@ -3535,6 +3535,7 @@ slave_start: · 3534 unmodified lines | |||
| 3535 | 3535 | ||
| 3536 | if (!SRIOV_VALID_STATE(dev->flags)) { | 3536 | if (!SRIOV_VALID_STATE(dev->flags)) { |
| 3537 | mlx4_err(dev, "Invalid SRIOV state\n"); | 3537 | mlx4_err(dev, "Invalid SRIOV state\n"); |
| 3538 | err = -EINVAL; | ||
| 3538 | goto err_close; | 3539 | goto err_close; |
| 3539 | } | 3540 | } |
| 3540 | } | 3541 | } |
| @@ -500,10 +500,7 @@ static int next_phys_dev(struct device *dev, const void *data) · 499 unmodified lines | |||
| 500 | return 1; | 500 | return 1; |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | /* This function is called with two flows: | 503 | /* Must be called with intf_mutex held */ |
| 504 | * 1. During initialization of mlx5_core_dev and we don't need to lock it. | ||
| 505 | * 2. During LAG configure stage and caller holds &mlx5_intf_mutex. | ||
| 506 | */ | ||
| 507 | struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev) | 504 | struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev) |
| 508 | { | 505 | { |
| 509 | struct auxiliary_device *adev; | 506 | struct auxiliary_device *adev; |
| @@ -471,6 +471,15 @@ static void mlx5e_build_rx_cq_param(struct mlx5_core_dev *mdev, · 470 unmodified lines | |||
| 471 | param->cq_period_mode = params->rx_cq_moderation.cq_period_mode; | 471 | param->cq_period_mode = params->rx_cq_moderation.cq_period_mode; |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | static u8 rq_end_pad_mode(struct mlx5_core_dev *mdev, struct mlx5e_params *params) | ||
| 475 | { | ||
| 476 | bool ro = pcie_relaxed_ordering_enabled(mdev->pdev) && | ||
| 477 | MLX5_CAP_GEN(mdev, relaxed_ordering_write); | ||
| 478 | |||
| 479 | return ro && params->lro_en ? | ||
| 480 | MLX5_WQ_END_PAD_MODE_NONE : MLX5_WQ_END_PAD_MODE_ALIGN; | ||
| 481 | } | ||
| 482 | |||
| 474 | int mlx5e_build_rq_param(struct mlx5_core_dev *mdev, | 483 | int mlx5e_build_rq_param(struct mlx5_core_dev *mdev, |
| 475 | struct mlx5e_params *params, | 484 | struct mlx5e_params *params, |
| 476 | struct mlx5e_xsk_param *xsk, | 485 | struct mlx5e_xsk_param *xsk, |
| @@ -508,7 +517,7 @@ int mlx5e_build_rq_param(struct mlx5_core_dev *mdev, · 31 unmodified lines | |||
| 508 | } | 517 | } |
| 509 | 518 | ||
| 510 | MLX5_SET(wq, wq, wq_type, params->rq_wq_type); | 519 | MLX5_SET(wq, wq, wq_type, params->rq_wq_type); |
| 511 | MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN); | 520 | MLX5_SET(wq, wq, end_padding_mode, rq_end_pad_mode(mdev, params)); |
| 512 | MLX5_SET(wq, wq, log_wq_stride, | 521 | MLX5_SET(wq, wq, log_wq_stride, |
| 513 | mlx5e_get_rqwq_log_stride(params->rq_wq_type, ndsegs)); | 522 | mlx5e_get_rqwq_log_stride(params->rq_wq_type, ndsegs)); |
| 514 | MLX5_SET(wq, wq, pd, mdev->mlx5e_res.hw_objs.pdn); | 523 | MLX5_SET(wq, wq, pd, mdev->mlx5e_res.hw_objs.pdn); |
| @@ -482,8 +482,11 @@ static void mlx5e_ptp_build_params(struct mlx5e_ptp *c, · 481 unmodified lines | |||
| 482 | params->log_sq_size = orig->log_sq_size; | 482 | params->log_sq_size = orig->log_sq_size; |
| 483 | mlx5e_ptp_build_sq_param(c->mdev, params, &cparams->txq_sq_param); | 483 | mlx5e_ptp_build_sq_param(c->mdev, params, &cparams->txq_sq_param); |
| 484 | } | 484 | } |
| 485 | if (test_bit(MLX5E_PTP_STATE_RX, c->state)) | 485 | /* RQ */ |
| 486 | if (test_bit(MLX5E_PTP_STATE_RX, c->state)) { | ||
| 487 | params->vlan_strip_disable = orig->vlan_strip_disable; | ||
| 486 | mlx5e_ptp_build_rq_param(c->mdev, c->netdev, c->priv->q_counter, cparams); | 488 | mlx5e_ptp_build_rq_param(c->mdev, c->netdev, c->priv->q_counter, cparams); |
| 489 | } | ||
| 487 | } | 490 | } |
| 488 | 491 | ||
| 489 | static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params, | 492 | static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params, |
| @@ -494,7 +497,7 @@ static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params, · 4 unmodified lines | |||
| 494 | int err; | 497 | int err; |
| 495 | 498 | ||
| 496 | rq->wq_type = params->rq_wq_type; | 499 | rq->wq_type = params->rq_wq_type; |
| 497 | rq->pdev = mdev->device; | 500 | rq->pdev = c->pdev; |
| 498 | rq->netdev = priv->netdev; | 501 | rq->netdev = priv->netdev; |
| 499 | rq->priv = priv; | 502 | rq->priv = priv; |
| 500 | rq->clock = &mdev->clock; | 503 | rq->clock = &mdev->clock; |
| @@ -37,7 +37,7 @@ static void mlx5e_init_trap_rq(struct mlx5e_trap *t, struct mlx5e_params *params · 36 unmodified lines | |||
| 37 | struct mlx5e_priv *priv = t->priv; | 37 | struct mlx5e_priv *priv = t->priv; |
| 38 | 38 | ||
| 39 | rq->wq_type = params->rq_wq_type; | 39 | rq->wq_type = params->rq_wq_type; |
| 40 | rq->pdev = mdev->device; | 40 | rq->pdev = t->pdev; |
| 41 | rq->netdev = priv->netdev; | 41 | rq->netdev = priv->netdev; |
| 42 | rq->priv = priv; | 42 | rq->priv = priv; |
| 43 | rq->clock = &mdev->clock; | 43 | rq->clock = &mdev->clock; |
| @@ -3384,7 +3384,7 @@ static int mlx5e_modify_channels_scatter_fcs(struct mlx5e_channels *chs, bool en · 3383 unmodified lines | |||
| 3384 | 3384 | ||
| 3385 | static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd) | 3385 | static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd) |
| 3386 | { | 3386 | { |
| 3387 | int err = 0; | 3387 | int err; |
| 3388 | int i; | 3388 | int i; |
| 3389 | 3389 | ||
| 3390 | for (i = 0; i < chs->num; i++) { | 3390 | for (i = 0; i < chs->num; i++) { |
| @@ -3392,6 +3392,8 @@ static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd) · 1 unmodified line | |||
| 3392 | if (err) | 3392 | if (err) |
| 3393 | return err; | 3393 | return err; |
| 3394 | } | 3394 | } |
| 3395 | if (chs->ptp && test_bit(MLX5E_PTP_STATE_RX, chs->ptp->state)) | ||
| 3396 | return mlx5e_modify_rq_vsd(&chs->ptp->rq, vsd); | ||
| 3395 | 3397 | ||
| 3396 | return 0; | 3398 | return 0; |
| 3397 | } | 3399 | } |
| @@ -3829,6 +3831,24 @@ int mlx5e_set_features(struct net_device *netdev, netdev_features_t features) · 431 unmodified lines | |||
| 3829 | return 0; | 3831 | return 0; |
| 3830 | } | 3832 | } |
| 3831 | 3833 | ||
| 3834 | static netdev_features_t mlx5e_fix_uplink_rep_features(struct net_device *netdev, | ||
| 3835 | netdev_features_t features) | ||
| 3836 | { | ||
| 3837 | features &= ~NETIF_F_HW_TLS_RX; | ||
| 3838 | if (netdev->features & NETIF_F_HW_TLS_RX) | ||
| 3839 | netdev_warn(netdev, "Disabling hw_tls_rx, not supported in switchdev mode\n"); | ||
| 3840 | |||
| 3841 | features &= ~NETIF_F_HW_TLS_TX; | ||
| 3842 | if (netdev->features & NETIF_F_HW_TLS_TX) | ||
| 3843 | netdev_warn(netdev, "Disabling hw_tls_tx, not supported in switchdev mode\n"); | ||
| 3844 | |||
| 3845 | features &= ~NETIF_F_NTUPLE; | ||
| 3846 | if (netdev->features & NETIF_F_NTUPLE) | ||
| 3847 | netdev_warn(netdev, "Disabling ntuple, not supported in switchdev mode\n"); | ||
| 3848 | |||
| 3849 | return features; | ||
| 3850 | } | ||
| 3851 | |||
| 3832 | static netdev_features_t mlx5e_fix_features(struct net_device *netdev, | 3852 | static netdev_features_t mlx5e_fix_features(struct net_device *netdev, |
| 3833 | netdev_features_t features) | 3853 | netdev_features_t features) |
| 3834 | { | 3854 | { |
| @@ -3860,15 +3880,8 @@ static netdev_features_t mlx5e_fix_features(struct net_device *netdev, · 25 unmodified lines | |||
| 3860 | netdev_warn(netdev, "Disabling rxhash, not supported when CQE compress is active\n"); | 3880 | netdev_warn(netdev, "Disabling rxhash, not supported when CQE compress is active\n"); |
| 3861 | } | 3881 | } |
| 3862 | 3882 | ||
| 3863 | if (mlx5e_is_uplink_rep(priv)) { | 3883 | if (mlx5e_is_uplink_rep(priv)) |
| 3864 | features &= ~NETIF_F_HW_TLS_RX; | 3884 | features = mlx5e_fix_uplink_rep_features(netdev, features); |
| 3865 | if (netdev->features & NETIF_F_HW_TLS_RX) | ||
| 3866 | netdev_warn(netdev, "Disabling hw_tls_rx, not supported in switchdev mode\n"); | ||
| 3867 | |||
| 3868 | features &= ~NETIF_F_HW_TLS_TX; | ||
| 3869 | if (netdev->features & NETIF_F_HW_TLS_TX) | ||
| 3870 | netdev_warn(netdev, "Disabling hw_tls_tx, not supported in switchdev mode\n"); | ||
| 3871 | } | ||
| 3872 | 3885 | ||
| 3873 | mutex_unlock(&priv->state_lock); | 3886 | mutex_unlock(&priv->state_lock); |
| 3874 | 3887 | ||
| @@ -4859,6 +4872,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) · 984 unmodified lines | |||
| 4859 | if (MLX5_CAP_ETH(mdev, scatter_fcs)) | 4872 | if (MLX5_CAP_ETH(mdev, scatter_fcs)) |
| 4860 | netdev->hw_features |= NETIF_F_RXFCS; | 4873 | netdev->hw_features |= NETIF_F_RXFCS; |
| 4861 | 4874 | ||
| 4875 | if (mlx5_qos_is_supported(mdev)) | ||
| 4876 | netdev->hw_features |= NETIF_F_HW_TC; | ||
| 4877 | |||
| 4862 | netdev->features = netdev->hw_features; | 4878 | netdev->features = netdev->hw_features; |
| 4863 | 4879 | ||
| 4864 | /* Defaults */ | 4880 | /* Defaults */ |
| @@ -4879,8 +4895,6 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) · 14 unmodified lines | |||
| 4879 | netdev->hw_features |= NETIF_F_NTUPLE; | 4895 | netdev->hw_features |= NETIF_F_NTUPLE; |
| 4880 | #endif | 4896 | #endif |
| 4881 | } | 4897 | } |
| 4882 | if (mlx5_qos_is_supported(mdev)) | ||
| 4883 | netdev->features |= NETIF_F_HW_TC; | ||
| 4884 | 4898 | ||
| 4885 | netdev->features |= NETIF_F_HIGHDMA; | 4899 | netdev->features |= NETIF_F_HIGHDMA; |
| 4886 | netdev->features |= NETIF_F_HW_VLAN_STAG_FILTER; | 4900 | netdev->features |= NETIF_F_HW_VLAN_STAG_FILTER; |
| @@ -452,12 +452,32 @@ static void mlx5e_detach_mod_hdr(struct mlx5e_priv *priv, · 451 unmodified lines | |||
| 452 | static | 452 | static |
| 453 | struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex) | 453 | struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex) |
| 454 | { | 454 | { |
| 455 | struct mlx5_core_dev *mdev; | ||
| 455 | struct net_device *netdev; | 456 | struct net_device *netdev; |
| 456 | struct mlx5e_priv *priv; | 457 | struct mlx5e_priv *priv; |
| 457 | 458 | ||
| 458 | netdev = __dev_get_by_index(net, ifindex); | 459 | netdev = dev_get_by_index(net, ifindex); |
| 460 | if (!netdev) | ||
| 461 | return ERR_PTR(-ENODEV); | ||
| 462 | |||
| 459 | priv = netdev_priv(netdev); | 463 | priv = netdev_priv(netdev); |
| 460 | return priv->mdev; | 464 | mdev = priv->mdev; |
| 465 | dev_put(netdev); | ||
| 466 | |||
| 467 | /* Mirred tc action holds a refcount on the ifindex net_device (see | ||
| 468 | * net/sched/act_mirred.c:tcf_mirred_get_dev). So, it's okay to continue using mdev | ||
| 469 | * after dev_put(netdev), while we're in the context of adding a tc flow. | ||
| 470 | * | ||
| 471 | * The mdev pointer corresponds to the peer/out net_device of a hairpin. It is then | ||
| 472 | * stored in a hairpin object, which exists until all flows, that refer to it, get | ||
| 473 | * removed. | ||
| 474 | * | ||
| 475 | * On the other hand, after a hairpin object has been created, the peer net_device may | ||
| 476 | * be removed/unbound while there are still some hairpin flows that are using it. This | ||
| 477 | * case is handled by mlx5e_tc_hairpin_update_dead_peer, which is hooked to | ||
| 478 | * NETDEV_UNREGISTER event of the peer net_device. | ||
| 479 | */ | ||
| 480 | return mdev; | ||
| 461 | } | 481 | } |
| 462 | 482 | ||
| 463 | static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp) | 483 | static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp) |
| @@ -666,6 +686,10 @@ mlx5e_hairpin_create(struct mlx5e_priv *priv, struct mlx5_hairpin_params *params · 202 unmodified lines | |||
| 666 | 686 | ||
| 667 | func_mdev = priv->mdev; | 687 | func_mdev = priv->mdev; |
| 668 | peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); | 688 | peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); |
| 689 | if (IS_ERR(peer_mdev)) { | ||
| 690 | err = PTR_ERR(peer_mdev); | ||
| 691 | goto create_pair_err; | ||
| 692 | } | ||
| 669 | 693 | ||
| 670 | pair = mlx5_core_hairpin_create(func_mdev, peer_mdev, params); | 694 | pair = mlx5_core_hairpin_create(func_mdev, peer_mdev, params); |
| 671 | if (IS_ERR(pair)) { | 695 | if (IS_ERR(pair)) { |
| @@ -804,6 +828,11 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, · 132 unmodified lines | |||
| 804 | int err; | 828 | int err; |
| 805 | 829 | ||
| 806 | peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); | 830 | peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); |
| 831 | if (IS_ERR(peer_mdev)) { | ||
| 832 | NL_SET_ERR_MSG_MOD(extack, "invalid ifindex of mirred device"); | ||
| 833 | return PTR_ERR(peer_mdev); | ||
| 834 | } | ||
| 835 | |||
| 807 | if (!MLX5_CAP_GEN(priv->mdev, hairpin) || !MLX5_CAP_GEN(peer_mdev, hairpin)) { | 836 | if (!MLX5_CAP_GEN(priv->mdev, hairpin) || !MLX5_CAP_GEN(peer_mdev, hairpin)) { |
| 808 | NL_SET_ERR_MSG_MOD(extack, "hairpin is not supported"); | 837 | NL_SET_ERR_MSG_MOD(extack, "hairpin is not supported"); |
| 809 | return -EOPNOTSUPP; | 838 | return -EOPNOTSUPP; |
| @@ -636,7 +636,7 @@ struct esw_vport_tbl_namespace { · 635 unmodified lines | |||
| 636 | }; | 636 | }; |
| 637 | 637 | ||
| 638 | struct mlx5_vport_tbl_attr { | 638 | struct mlx5_vport_tbl_attr { |
| 639 | u16 chain; | 639 | u32 chain; |
| 640 | u16 prio; | 640 | u16 prio; |
| 641 | u16 vport; | 641 | u16 vport; |
| 642 | const struct esw_vport_tbl_namespace *vport_ns; | 642 | const struct esw_vport_tbl_namespace *vport_ns; |
| @@ -382,10 +382,11 @@ esw_setup_vport_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *f · 381 unmodified lines | |||
| 382 | { | 382 | { |
| 383 | dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_VPORT; | 383 | dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_VPORT; |
| 384 | dest[dest_idx].vport.num = esw_attr->dests[attr_idx].rep->vport; | 384 | dest[dest_idx].vport.num = esw_attr->dests[attr_idx].rep->vport; |
| 385 | dest[dest_idx].vport.vhca_id = | 385 | if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) { |
| 386 | MLX5_CAP_GEN(esw_attr->dests[attr_idx].mdev, vhca_id); | 386 | dest[dest_idx].vport.vhca_id = |
| 387 | if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) | 387 | MLX5_CAP_GEN(esw_attr->dests[attr_idx].mdev, vhca_id); |
| 388 | dest[dest_idx].vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID; | 388 | dest[dest_idx].vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID; |
| 389 | } | ||
| 389 | if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) { | 390 | if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) { |
| 390 | if (pkt_reformat) { | 391 | if (pkt_reformat) { |
| 391 | flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; | 392 | flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; |
| @@ -2367,6 +2368,9 @@ static int mlx5_esw_offloads_devcom_event(int event, · 1975 unmodified lines | |||
| 2367 | 2368 | ||
| 2368 | switch (event) { | 2369 | switch (event) { |
| 2369 | case ESW_OFFLOADS_DEVCOM_PAIR: | 2370 | case ESW_OFFLOADS_DEVCOM_PAIR: |
| 2371 | if (mlx5_get_next_phys_dev(esw->dev) != peer_esw->dev) | ||
| 2372 | break; | ||
| 2373 | |||
| 2370 | if (mlx5_eswitch_vport_match_metadata_enabled(esw) != | 2374 | if (mlx5_eswitch_vport_match_metadata_enabled(esw) != |
| 2371 | mlx5_eswitch_vport_match_metadata_enabled(peer_esw)) | 2375 | mlx5_eswitch_vport_match_metadata_enabled(peer_esw)) |
| 2372 | break; | 2376 | break; |
| @@ -1024,17 +1024,19 @@ static int connect_fwd_rules(struct mlx5_core_dev *dev, · 1023 unmodified lines | |||
| 1024 | static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table *ft, | 1024 | static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table *ft, |
| 1025 | struct fs_prio *prio) | 1025 | struct fs_prio *prio) |
| 1026 | { | 1026 | { |
| 1027 | struct mlx5_flow_table *next_ft; | 1027 | struct mlx5_flow_table *next_ft, *first_ft; |
| 1028 | int err = 0; | 1028 | int err = 0; |
| 1029 | 1029 | ||
| 1030 | /* Connect_prev_fts and update_root_ft_create are mutually exclusive */ | 1030 | /* Connect_prev_fts and update_root_ft_create are mutually exclusive */ |
| 1031 | 1031 | ||
| 1032 | if (list_empty(&prio->node.children)) { | 1032 | first_ft = list_first_entry_or_null(&prio->node.children, |
| 1033 | struct mlx5_flow_table, node.list); | ||
| 1034 | if (!first_ft || first_ft->level > ft->level) { | ||
| 1033 | err = connect_prev_fts(dev, ft, prio); | 1035 | err = connect_prev_fts(dev, ft, prio); |
| 1034 | if (err) | 1036 | if (err) |
| 1035 | return err; | 1037 | return err; |
| 1036 | 1038 | ||
| 1037 | next_ft = find_next_chained_ft(prio); | 1039 | next_ft = first_ft ? first_ft : find_next_chained_ft(prio); |
| 1038 | err = connect_fwd_rules(dev, ft, next_ft); | 1040 | err = connect_fwd_rules(dev, ft, next_ft); |
| 1039 | if (err) | 1041 | if (err) |
| 1040 | return err; | 1042 | return err; |
| @@ -2120,7 +2122,7 @@ static int disconnect_flow_table(struct mlx5_flow_table *ft) · 1079 unmodified lines | |||
| 2120 | node.list) == ft)) | 2122 | node.list) == ft)) |
| 2121 | return 0; | 2123 | return 0; |
| 2122 | 2124 | ||
| 2123 | next_ft = find_next_chained_ft(prio); | 2125 | next_ft = find_next_ft(ft); |
| 2124 | err = connect_fwd_rules(dev, next_ft, ft); | 2126 | err = connect_fwd_rules(dev, next_ft, ft); |
| 2125 | if (err) | 2127 | if (err) |
| 2126 | return err; | 2128 | return err; |
| @@ -626,8 +626,16 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work) · 625 unmodified lines | |||
| 626 | } | 626 | } |
| 627 | fw_reporter_ctx.err_synd = health->synd; | 627 | fw_reporter_ctx.err_synd = health->synd; |
| 628 | fw_reporter_ctx.miss_counter = health->miss_counter; | 628 | fw_reporter_ctx.miss_counter = health->miss_counter; |
| 629 | devlink_health_report(health->fw_fatal_reporter, | 629 | if (devlink_health_report(health->fw_fatal_reporter, |
| 630 | "FW fatal error reported", &fw_reporter_ctx); | 630 | "FW fatal error reported", &fw_reporter_ctx) == -ECANCELED) { |
| 631 | /* If recovery wasn't performed, due to grace period, | ||
| 632 | * unload the driver. This ensures that the driver | ||
| 633 | * closes all its resources and it is not subjected to | ||
| 634 | * requests from the kernel. | ||
| 635 | */ | ||
| 636 | mlx5_core_err(dev, "Driver is in error state. Unloading\n"); | ||
| 637 | mlx5_unload_one(dev); | ||
| 638 | } | ||
| 631 | } | 639 | } |
| 632 | 640 | ||
| 633 | static const struct devlink_health_reporter_ops mlx5_fw_fatal_reporter_ops = { | 641 | static const struct devlink_health_reporter_ops mlx5_fw_fatal_reporter_ops = { |
| @@ -3,6 +3,7 @@ config SPARX5_SWITCH · 2 unmodified lines | |||
| 3 | depends on NET_SWITCHDEV | 3 | depends on NET_SWITCHDEV |
| 4 | depends on HAS_IOMEM | 4 | depends on HAS_IOMEM |
| 5 | depends on OF | 5 | depends on OF |
| 6 | depends on ARCH_SPARX5 || COMPILE_TEST | ||
| 6 | select PHYLINK | 7 | select PHYLINK |
| 7 | select PHY_SPARX5_SERDES | 8 | select PHY_SPARX5_SERDES |
| 8 | select RESET_CONTROLLER | 9 | select RESET_CONTROLLER |
| @@ -29,7 +29,7 @@ static const u8 ionic_qtype_versions[IONIC_QTYPE_MAX] = { · 28 unmodified lines | |||
| 29 | */ | 29 | */ |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode); | 32 | static void ionic_lif_rx_mode(struct ionic_lif *lif); |
| 33 | static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr); | 33 | static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr); |
| 34 | static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr); | 34 | static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr); |
| 35 | static void ionic_link_status_check(struct ionic_lif *lif); | 35 | static void ionic_link_status_check(struct ionic_lif *lif); |
| @@ -53,7 +53,19 @@ static void ionic_dim_work(struct work_struct *work) · 17 unmodified lines | |||
| 53 | cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); | 53 | cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); |
| 54 | qcq = container_of(dim, struct ionic_qcq, dim); | 54 | qcq = container_of(dim, struct ionic_qcq, dim); |
| 55 | new_coal = ionic_coal_usec_to_hw(qcq->q.lif->ionic, cur_moder.usec); | 55 | new_coal = ionic_coal_usec_to_hw(qcq->q.lif->ionic, cur_moder.usec); |
| 56 | qcq->intr.dim_coal_hw = new_coal ? new_coal : 1; | 56 | new_coal = new_coal ? new_coal : 1; |
| 57 | |||
| 58 | if (qcq->intr.dim_coal_hw != new_coal) { | ||
| 59 | unsigned int qi = qcq->cq.bound_q->index; | ||
| 60 | struct ionic_lif *lif = qcq->q.lif; | ||
| 61 | |||
| 62 | qcq->intr.dim_coal_hw = new_coal; | ||
| 63 | |||
| 64 | ionic_intr_coal_init(lif->ionic->idev.intr_ctrl, | ||
| 65 | lif->rxqcqs[qi]->intr.index, | ||
| 66 | qcq->intr.dim_coal_hw); | ||
| 67 | } | ||
| 68 | |||
| 57 | dim->state = DIM_START_MEASURE; | 69 | dim->state = DIM_START_MEASURE; |
| 58 | } | 70 | } |
| 59 | 71 | ||
| @@ -77,7 +89,7 @@ static void ionic_lif_deferred_work(struct work_struct *work) · 17 unmodified lines | |||
| 77 | 89 | ||
| 78 | switch (w->type) { | 90 | switch (w->type) { |
| 79 | case IONIC_DW_TYPE_RX_MODE: | 91 | case IONIC_DW_TYPE_RX_MODE: |
| 80 | ionic_lif_rx_mode(lif, w->rx_mode); | 92 | ionic_lif_rx_mode(lif); |
| 81 | break; | 93 | break; |
| 82 | case IONIC_DW_TYPE_RX_ADDR_ADD: | 94 | case IONIC_DW_TYPE_RX_ADDR_ADD: |
| 83 | ionic_lif_addr_add(lif, w->addr); | 95 | ionic_lif_addr_add(lif, w->addr); |
| @@ -1301,10 +1313,8 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr) · 1217 unmodified lines | |||
| 1301 | return 0; | 1313 | return 0; |
| 1302 | } | 1314 | } |
| 1303 | 1315 | ||
| 1304 | static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add, | 1316 | static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add) |
| 1305 | bool can_sleep) | ||
| 1306 | { | 1317 | { |
| 1307 | struct ionic_deferred_work *work; | ||
| 1308 | unsigned int nmfilters; | 1318 | unsigned int nmfilters; |
| 1309 | unsigned int nufilters; | 1319 | unsigned int nufilters; |
| 1310 | 1320 | ||
| @@ -1330,97 +1340,46 @@ static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add, · 19 unmodified lines | |||
| 1330 | lif->nucast--; | 1340 | lif->nucast--; |
| 1331 | } | 1341 | } |
| 1332 | 1342 | ||
| 1333 | if (!can_sleep) { | 1343 | netdev_dbg(lif->netdev, "rx_filter %s %pM\n", |
| 1334 | work = kzalloc(sizeof(*work), GFP_ATOMIC); | 1344 | add ? "add" : "del", addr); |
| 1335 | if (!work) | 1345 | if (add) |
| 1336 | return -ENOMEM; | 1346 | return ionic_lif_addr_add(lif, addr); |
| 1337 | work->type = add ? IONIC_DW_TYPE_RX_ADDR_ADD : | 1347 | else |
| 1338 | IONIC_DW_TYPE_RX_ADDR_DEL; | 1348 | return ionic_lif_addr_del(lif, addr); |
| 1339 | memcpy(work->addr, addr, ETH_ALEN); | ||
| 1340 | netdev_dbg(lif->netdev, "deferred: rx_filter %s %pM\n", | ||
| 1341 | add ? "add" : "del", addr); | ||
| 1342 | ionic_lif_deferred_enqueue(&lif->deferred, work); | ||
| 1343 | } else { | ||
| 1344 | netdev_dbg(lif->netdev, "rx_filter %s %pM\n", | ||
| 1345 | add ? "add" : "del", addr); | ||
| 1346 | if (add) | ||
| 1347 | return ionic_lif_addr_add(lif, addr); | ||
| 1348 | else | ||
| 1349 | return ionic_lif_addr_del(lif, addr); | ||
| 1350 | } | ||
| 1351 | 1349 | ||
| 1352 | return 0; | 1350 | return 0; |
| 1353 | } | 1351 | } |
| 1354 | 1352 | ||
| 1355 | static int ionic_addr_add(struct net_device *netdev, const u8 *addr) | 1353 | static int ionic_addr_add(struct net_device *netdev, const u8 *addr) |
| 1356 | { | 1354 | { |
| 1357 | return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, CAN_SLEEP); | 1355 | return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR); |
| 1358 | } | ||
| 1359 | |||
| 1360 | static int ionic_ndo_addr_add(struct net_device *netdev, const u8 *addr) | ||
| 1361 | { | ||
| 1362 | return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, CAN_NOT_SLEEP); | ||
| 1363 | } | 1356 | } |
| 1364 | 1357 | ||
| 1365 | static int ionic_addr_del(struct net_device *netdev, const u8 *addr) | 1358 | static int ionic_addr_del(struct net_device *netdev, const u8 *addr) |
| 1366 | { | 1359 | { |
| 1367 | return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, CAN_SLEEP); | 1360 | return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR); |
| 1368 | } | 1361 | } |
| 1369 | 1362 | ||
| 1370 | static int ionic_ndo_addr_del(struct net_device *netdev, const u8 *addr) | 1363 | static void ionic_lif_rx_mode(struct ionic_lif *lif) |
| 1371 | { | 1364 | { |
| 1372 | return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, CAN_NOT_SLEEP); | 1365 | struct net_device *netdev = lif->netdev; |
| 1373 | } | 1366 | unsigned int nfilters; |
| 1374 | 1367 | unsigned int nd_flags; | |
| 1375 | static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode) | ||
| 1376 | { | ||
| 1377 | struct ionic_admin_ctx ctx = { | ||
| 1378 | .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), | ||
| 1379 | .cmd.rx_mode_set = { | ||
| 1380 | .opcode = IONIC_CMD_RX_MODE_SET, | ||
| 1381 | .lif_index = cpu_to_le16(lif->index), | ||
| 1382 | .rx_mode = cpu_to_le16(rx_mode), | ||
| 1383 | }, | ||
| 1384 | }; | ||
| 1385 | char buf[128]; | 1368 | char buf[128]; |
| 1386 | int err; | 1369 | u16 rx_mode; |
| 1387 | int i; | 1370 | int i; |
| 1388 | #define REMAIN(__x) (sizeof(buf) - (__x)) | 1371 | #define REMAIN(__x) (sizeof(buf) - (__x)) |
| 1389 | 1372 | ||
| 1390 | i = scnprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:", | 1373 | mutex_lock(&lif->config_lock); |
| 1391 | lif->rx_mode, rx_mode); | ||
| 1392 | if (rx_mode & IONIC_RX_MODE_F_UNICAST) | ||
| 1393 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_UNICAST"); | ||
| 1394 | if (rx_mode & IONIC_RX_MODE_F_MULTICAST) | ||
| 1395 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_MULTICAST"); | ||
| 1396 | if (rx_mode & IONIC_RX_MODE_F_BROADCAST) | ||
| 1397 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_BROADCAST"); | ||
| 1398 | if (rx_mode & IONIC_RX_MODE_F_PROMISC) | ||
| 1399 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_PROMISC"); | ||
| 1400 | if (rx_mode & IONIC_RX_MODE_F_ALLMULTI) | ||
| 1401 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_ALLMULTI"); | ||
| 1402 | netdev_dbg(lif->netdev, "lif%d %s\n", lif->index, buf); | ||
| 1403 | |||
| 1404 | err = ionic_adminq_post_wait(lif, &ctx); | ||
| 1405 | if (err) | ||
| 1406 | netdev_warn(lif->netdev, "set rx_mode 0x%04x failed: %d\n", | ||
| 1407 | rx_mode, err); | ||
| 1408 | else | ||
| 1409 | lif->rx_mode = rx_mode; | ||
| 1410 | } | ||
| 1411 | 1374 | ||
| 1412 | static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep) | 1375 | /* grab the flags once for local use */ |
| 1413 | { | 1376 | nd_flags = netdev->flags; |
| 1414 | struct ionic_lif *lif = netdev_priv(netdev); | ||
| 1415 | struct ionic_deferred_work *work; | ||
| 1416 | unsigned int nfilters; | ||
| 1417 | unsigned int rx_mode; | ||
| 1418 | 1377 | ||
| 1419 | rx_mode = IONIC_RX_MODE_F_UNICAST; | 1378 | rx_mode = IONIC_RX_MODE_F_UNICAST; |
| 1420 | rx_mode |= (netdev->flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0; | 1379 | rx_mode |= (nd_flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0; |
| 1421 | rx_mode |= (netdev->flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0; | 1380 | rx_mode |= (nd_flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0; |
| 1422 | rx_mode |= (netdev->flags & IFF_PROMISC) ? IONIC_RX_MODE_F_PROMISC : 0; | 1381 | rx_mode |= (nd_flags & IFF_PROMISC) ? IONIC_RX_MODE_F_PROMISC : 0; |
| 1423 | rx_mode |= (netdev->flags & IFF_ALLMULTI) ? IONIC_RX_MODE_F_ALLMULTI : 0; | 1382 | rx_mode |= (nd_flags & IFF_ALLMULTI) ? IONIC_RX_MODE_F_ALLMULTI : 0; |
| 1424 | 1383 | ||
| 1425 | /* sync unicast addresses | 1384 | /* sync unicast addresses |
| 1426 | * next check to see if we're in an overflow state | 1385 | * next check to see if we're in an overflow state |
| @@ -1429,49 +1388,83 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep) · 2 unmodified lines | |||
| 1429 | * we remove our overflow flag and check the netdev flags | 1388 | * we remove our overflow flag and check the netdev flags |
| 1430 | * to see if we can disable NIC PROMISC | 1389 | * to see if we can disable NIC PROMISC |
| 1431 | */ | 1390 | */ |
| 1432 | if (can_sleep) | 1391 | __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del); |
| 1433 | __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del); | ||
| 1434 | else | ||
| 1435 | __dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del); | ||
| 1436 | nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); | 1392 | nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); |
| 1437 | if (netdev_uc_count(netdev) + 1 > nfilters) { | 1393 | if (netdev_uc_count(netdev) + 1 > nfilters) { |
| 1438 | rx_mode |= IONIC_RX_MODE_F_PROMISC; | 1394 | rx_mode |= IONIC_RX_MODE_F_PROMISC; |
| 1439 | lif->uc_overflow = true; | 1395 | lif->uc_overflow = true; |
| 1440 | } else if (lif->uc_overflow) { | 1396 | } else if (lif->uc_overflow) { |
| 1441 | lif->uc_overflow = false; | 1397 | lif->uc_overflow = false; |
| 1442 | if (!(netdev->flags & IFF_PROMISC)) | 1398 | if (!(nd_flags & IFF_PROMISC)) |
| 1443 | rx_mode &= ~IONIC_RX_MODE_F_PROMISC; | 1399 | rx_mode &= ~IONIC_RX_MODE_F_PROMISC; |
| 1444 | } | 1400 | } |
| 1445 | 1401 | ||
| 1446 | /* same for multicast */ | 1402 | /* same for multicast */ |
| 1447 | if (can_sleep) | 1403 | __dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del); |
| 1448 | __dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del); | ||
| 1449 | else | ||
| 1450 | __dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del); | ||
| 1451 | nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters); | 1404 | nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters); |
| 1452 | if (netdev_mc_count(netdev) > nfilters) { | 1405 | if (netdev_mc_count(netdev) > nfilters) { |
| 1453 | rx_mode |= IONIC_RX_MODE_F_ALLMULTI; | 1406 | rx_mode |= IONIC_RX_MODE_F_ALLMULTI; |
| 1454 | lif->mc_overflow = true; | 1407 | lif->mc_overflow = true; |
| 1455 | } else if (lif->mc_overflow) { | 1408 | } else if (lif->mc_overflow) { |
| 1456 | lif->mc_overflow = false; | 1409 | lif->mc_overflow = false; |
| 1457 | if (!(netdev->flags & IFF_ALLMULTI)) | 1410 | if (!(nd_flags & IFF_ALLMULTI)) |
| 1458 | rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI; | 1411 | rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI; |
| 1459 | } | 1412 | } |
| 1460 | 1413 | ||
| 1414 | i = scnprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:", | ||
| 1415 | lif->rx_mode, rx_mode); | ||
| 1416 | if (rx_mode & IONIC_RX_MODE_F_UNICAST) | ||
| 1417 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_UNICAST"); | ||
| 1418 | if (rx_mode & IONIC_RX_MODE_F_MULTICAST) | ||
| 1419 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_MULTICAST"); | ||
| 1420 | if (rx_mode & IONIC_RX_MODE_F_BROADCAST) | ||
| 1421 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_BROADCAST"); | ||
| 1422 | if (rx_mode & IONIC_RX_MODE_F_PROMISC) | ||
| 1423 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_PROMISC"); | ||
| 1424 | if (rx_mode & IONIC_RX_MODE_F_ALLMULTI) | ||
| 1425 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_ALLMULTI"); | ||
| 1426 | if (rx_mode & IONIC_RX_MODE_F_RDMA_SNIFFER) | ||
| 1427 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_RDMA_SNIFFER"); | ||
| 1428 | netdev_dbg(netdev, "lif%d %s\n", lif->index, buf); | ||
| 1429 | |||
| 1461 | if (lif->rx_mode != rx_mode) { | 1430 | if (lif->rx_mode != rx_mode) { |
| 1462 | if (!can_sleep) { | 1431 | struct ionic_admin_ctx ctx = { |
| 1463 | work = kzalloc(sizeof(*work), GFP_ATOMIC); | 1432 | .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), |
| 1464 | if (!work) { | 1433 | .cmd.rx_mode_set = { |
| 1465 | netdev_err(lif->netdev, "rxmode change dropped\n"); | 1434 | .opcode = IONIC_CMD_RX_MODE_SET, |
| 1466 | return; | 1435 | .lif_index = cpu_to_le16(lif->index), |
| 1467 | } | 1436 | }, |
| 1468 | work->type = IONIC_DW_TYPE_RX_MODE; | 1437 | }; |
| 1469 | work->rx_mode = rx_mode; | 1438 | int err; |
| 1470 | netdev_dbg(lif->netdev, "deferred: rx_mode\n"); | 1439 | |
| 1471 | ionic_lif_deferred_enqueue(&lif->deferred, work); | 1440 | ctx.cmd.rx_mode_set.rx_mode = cpu_to_le16(rx_mode); |
| 1472 | } else { | 1441 | err = ionic_adminq_post_wait(lif, &ctx); |
| 1473 | ionic_lif_rx_mode(lif, rx_mode); | 1442 | if (err) |
| 1443 | netdev_warn(netdev, "set rx_mode 0x%04x failed: %d\n", | ||
| 1444 | rx_mode, err); | ||
| 1445 | else | ||
| 1446 | lif->rx_mode = rx_mode; | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | mutex_unlock(&lif->config_lock); | ||
| 1450 | } | ||
| 1451 | |||
| 1452 | static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep) | ||
| 1453 | { | ||
| 1454 | struct ionic_lif *lif = netdev_priv(netdev); | ||
| 1455 | struct ionic_deferred_work *work; | ||
| 1456 | |||
| 1457 | if (!can_sleep) { | ||
| 1458 | work = kzalloc(sizeof(*work), GFP_ATOMIC); | ||
| 1459 | if (!work) { | ||
| 1460 | netdev_err(lif->netdev, "rxmode change dropped\n"); | ||
| 1461 | return; | ||
| 1474 | } | 1462 | } |
| 1463 | work->type = IONIC_DW_TYPE_RX_MODE; | ||
| 1464 | netdev_dbg(lif->netdev, "deferred: rx_mode\n"); | ||
| 1465 | ionic_lif_deferred_enqueue(&lif->deferred, work); | ||
| 1466 | } else { | ||
| 1467 | ionic_lif_rx_mode(lif); | ||
| 1475 | } | 1468 | } |
| 1476 | } | 1469 | } |
| 1477 | 1470 | ||
| @@ -3058,6 +3051,7 @@ void ionic_lif_deinit(struct ionic_lif *lif) · 1580 unmodified lines | |||
| 3058 | ionic_lif_qcq_deinit(lif, lif->notifyqcq); | 3051 | ionic_lif_qcq_deinit(lif, lif->notifyqcq); |
| 3059 | ionic_lif_qcq_deinit(lif, lif->adminqcq); | 3052 | ionic_lif_qcq_deinit(lif, lif->adminqcq); |
| 3060 | 3053 | ||
| 3054 | mutex_destroy(&lif->config_lock); | ||
| 3061 | mutex_destroy(&lif->queue_lock); | 3055 | mutex_destroy(&lif->queue_lock); |
| 3062 | ionic_lif_reset(lif); | 3056 | ionic_lif_reset(lif); |
| 3063 | } | 3057 | } |
| @@ -3185,7 +3179,7 @@ static int ionic_station_set(struct ionic_lif *lif) · 121 unmodified lines | |||
| 3185 | */ | 3179 | */ |
| 3186 | if (!ether_addr_equal(ctx.comp.lif_getattr.mac, | 3180 | if (!ether_addr_equal(ctx.comp.lif_getattr.mac, |
| 3187 | netdev->dev_addr)) | 3181 | netdev->dev_addr)) |
| 3188 | ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP); | 3182 | ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR); |
| 3189 | } else { | 3183 | } else { |
| 3190 | /* Update the netdev mac with the device's mac */ | 3184 | /* Update the netdev mac with the device's mac */ |
| 3191 | memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len); | 3185 | memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len); |
| @@ -3202,7 +3196,7 @@ static int ionic_station_set(struct ionic_lif *lif) · 10 unmodified lines | |||
| 3202 | 3196 | ||
| 3203 | netdev_dbg(lif->netdev, "adding station MAC addr %pM\n", | 3197 | netdev_dbg(lif->netdev, "adding station MAC addr %pM\n", |
| 3204 | netdev->dev_addr); | 3198 | netdev->dev_addr); |
| 3205 | ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP); | 3199 | ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR); |
| 3206 | 3200 | ||
| 3207 | return 0; | 3201 | return 0; |
| 3208 | } | 3202 | } |
| @@ -3225,6 +3219,7 @@ int ionic_lif_init(struct ionic_lif *lif) · 16 unmodified lines | |||
| 3225 | 3219 | ||
| 3226 | lif->hw_index = le16_to_cpu(comp.hw_index); | 3220 | lif->hw_index = le16_to_cpu(comp.hw_index); |
| 3227 | mutex_init(&lif->queue_lock); | 3221 | mutex_init(&lif->queue_lock); |
| 3222 | mutex_init(&lif->config_lock); | ||
| 3228 | 3223 | ||
| 3229 | /* now that we have the hw_index we can figure out our doorbell page */ | 3224 | /* now that we have the hw_index we can figure out our doorbell page */ |
| 3230 | lif->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif); | 3225 | lif->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif); |
| @@ -108,7 +108,6 @@ struct ionic_deferred_work { · 107 unmodified lines | |||
| 108 | struct list_head list; | 108 | struct list_head list; |
| 109 | enum ionic_deferred_work_type type; | 109 | enum ionic_deferred_work_type type; |
| 110 | union { | 110 | union { |
| 111 | unsigned int rx_mode; | ||
| 112 | u8 addr[ETH_ALEN]; | 111 | u8 addr[ETH_ALEN]; |
| 113 | u8 fw_status; | 112 | u8 fw_status; |
| 114 | }; | 113 | }; |
| @@ -179,6 +178,7 @@ struct ionic_lif { · 64 unmodified lines | |||
| 179 | unsigned int index; | 178 | unsigned int index; |
| 180 | unsigned int hw_index; | 179 | unsigned int hw_index; |
| 181 | struct mutex queue_lock; /* lock for queue structures */ | 180 | struct mutex queue_lock; /* lock for queue structures */ |
| 181 | struct mutex config_lock; /* lock for config actions */ | ||
| 182 | spinlock_t adminq_lock; /* lock for AdminQ operations */ | 182 | spinlock_t adminq_lock; /* lock for AdminQ operations */ |
| 183 | struct ionic_qcq *adminqcq; | 183 | struct ionic_qcq *adminqcq; |
| 184 | struct ionic_qcq *notifyqcq; | 184 | struct ionic_qcq *notifyqcq; |
| @@ -199,7 +199,7 @@ struct ionic_lif { · 14 unmodified lines | |||
| 199 | unsigned int nrxq_descs; | 199 | unsigned int nrxq_descs; |
| 200 | u32 rx_copybreak; | 200 | u32 rx_copybreak; |
| 201 | u64 rxq_features; | 201 | u64 rxq_features; |
| 202 | unsigned int rx_mode; | 202 | u16 rx_mode; |
| 203 | u64 hw_features; | 203 | u64 hw_features; |
| 204 | bool registered; | 204 | bool registered; |
| 205 | bool mc_overflow; | 205 | bool mc_overflow; |
| @@ -302,7 +302,7 @@ int ionic_lif_identify(struct ionic *ionic, u8 lif_type, · 96 unmodified lines | |||
| 302 | int ionic_lif_size(struct ionic *ionic); | 302 | int ionic_lif_size(struct ionic *ionic); |
| 303 | 303 | ||
| 304 | #if IS_ENABLED(CONFIG_PTP_1588_CLOCK) | 304 | #if IS_ENABLED(CONFIG_PTP_1588_CLOCK) |
| 305 | int ionic_lif_hwstamp_replay(struct ionic_lif *lif); | 305 | void ionic_lif_hwstamp_replay(struct ionic_lif *lif); |
| 306 | int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr); | 306 | int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr); |
| 307 | int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr); | 307 | int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr); |
| 308 | ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 counter); | 308 | ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 counter); |
| @@ -311,10 +311,7 @@ void ionic_lif_unregister_phc(struct ionic_lif *lif); · 2 unmodified lines | |||
| 311 | void ionic_lif_alloc_phc(struct ionic_lif *lif); | 311 | void ionic_lif_alloc_phc(struct ionic_lif *lif); |
| 312 | void ionic_lif_free_phc(struct ionic_lif *lif); | 312 | void ionic_lif_free_phc(struct ionic_lif *lif); |
| 313 | #else | 313 | #else |
| 314 | static inline int ionic_lif_hwstamp_replay(struct ionic_lif *lif) | 314 | static inline void ionic_lif_hwstamp_replay(struct ionic_lif *lif) {} |
| 315 | { | ||
| 316 | return -EOPNOTSUPP; | ||
| 317 | } | ||
| 318 | 315 | ||
| 319 | static inline int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr) | 316 | static inline int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr) |
| 320 | { | 317 | { |
| @@ -188,6 +188,9 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr) · 187 unmodified lines | |||
| 188 | struct hwtstamp_config config; | 188 | struct hwtstamp_config config; |
| 189 | int err; | 189 | int err; |
| 190 | 190 | ||
| 191 | if (!lif->phc || !lif->phc->ptp) | ||
| 192 | return -EOPNOTSUPP; | ||
| 193 | |||
| 191 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) | 194 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) |
| 192 | return -EFAULT; | 195 | return -EFAULT; |
| 193 | 196 | ||
| @@ -203,15 +206,16 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr) · 9 unmodified lines | |||
| 203 | return 0; | 206 | return 0; |
| 204 | } | 207 | } |
| 205 | 208 | ||
| 206 | int ionic_lif_hwstamp_replay(struct ionic_lif *lif) | 209 | void ionic_lif_hwstamp_replay(struct ionic_lif *lif) |
| 207 | { | 210 | { |
| 208 | int err; | 211 | int err; |
| 209 | 212 | ||
| 213 | if (!lif->phc || !lif->phc->ptp) | ||
| 214 | return; | ||
| 215 | |||
| 210 | err = ionic_lif_hwstamp_set_ts_config(lif, NULL); | 216 | err = ionic_lif_hwstamp_set_ts_config(lif, NULL); |
| 211 | if (err) | 217 | if (err) |
| 212 | netdev_info(lif->netdev, "hwstamp replay failed: %d\n", err); | 218 | netdev_info(lif->netdev, "hwstamp replay failed: %d\n", err); |
| 213 | |||
| 214 | return err; | ||
| 215 | } | 219 | } |
| 216 | 220 | ||
| 217 | int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr) | 221 | int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr) |
| @@ -274,12 +274,11 @@ static void ionic_rx_clean(struct ionic_queue *q, · 273 unmodified lines | |||
| 274 | } | 274 | } |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | if (likely(netdev->features & NETIF_F_RXCSUM)) { | 277 | if (likely(netdev->features & NETIF_F_RXCSUM) && |
| 278 | if (comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_CALC) { | 278 | (comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_CALC)) { |
| 279 | skb->ip_summed = CHECKSUM_COMPLETE; | 279 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 280 | skb->csum = (__force __wsum)le16_to_cpu(comp->csum); | 280 | skb->csum = (__force __wsum)le16_to_cpu(comp->csum); |
| 281 | stats->csum_complete++; | 281 | stats->csum_complete++; |
| 282 | } | ||
| 283 | } else { | 282 | } else { |
| 284 | stats->csum_none++; | 283 | stats->csum_none++; |
| 285 | } | 284 | } |
| @@ -451,11 +450,12 @@ void ionic_rx_empty(struct ionic_queue *q) · 165 unmodified lines | |||
| 451 | q->tail_idx = 0; | 450 | q->tail_idx = 0; |
| 452 | } | 451 | } |
| 453 | 452 | ||
| 454 | static void ionic_dim_update(struct ionic_qcq *qcq) | 453 | static void ionic_dim_update(struct ionic_qcq *qcq, int napi_mode) |
| 455 | { | 454 | { |
| 456 | struct dim_sample dim_sample; | 455 | struct dim_sample dim_sample; |
| 457 | struct ionic_lif *lif; | 456 | struct ionic_lif *lif; |
| 458 | unsigned int qi; | 457 | unsigned int qi; |
| 458 | u64 pkts, bytes; | ||
| 459 | 459 | ||
| 460 | if (!qcq->intr.dim_coal_hw) | 460 | if (!qcq->intr.dim_coal_hw) |
| 461 | return; | 461 | return; |
| @@ -463,14 +463,23 @@ static void ionic_dim_update(struct ionic_qcq *qcq) · 1 unmodified line | |||
| 463 | lif = qcq->q.lif; | 463 | lif = qcq->q.lif; |
| 464 | qi = qcq->cq.bound_q->index; | 464 | qi = qcq->cq.bound_q->index; |
| 465 | 465 | ||
| 466 | ionic_intr_coal_init(lif->ionic->idev.intr_ctrl, | 466 | switch (napi_mode) { |
| 467 | lif->rxqcqs[qi]->intr.index, | 467 | case IONIC_LIF_F_TX_DIM_INTR: |
| 468 | qcq->intr.dim_coal_hw); | 468 | pkts = lif->txqstats[qi].pkts; |
| 469 | bytes = lif->txqstats[qi].bytes; | ||
| 470 | break; | ||
| 471 | case IONIC_LIF_F_RX_DIM_INTR: | ||
| 472 | pkts = lif->rxqstats[qi].pkts; | ||
| 473 | bytes = lif->rxqstats[qi].bytes; | ||
| 474 | break; | ||
| 475 | default: | ||
| 476 | pkts = lif->txqstats[qi].pkts + lif->rxqstats[qi].pkts; | ||
| 477 | bytes = lif->txqstats[qi].bytes + lif->rxqstats[qi].bytes; | ||
| 478 | break; | ||
| 479 | } | ||
| 469 | 480 | ||
| 470 | dim_update_sample(qcq->cq.bound_intr->rearm_count, | 481 | dim_update_sample(qcq->cq.bound_intr->rearm_count, |
| 471 | lif->txqstats[qi].pkts, | 482 | pkts, bytes, &dim_sample); |
| 472 | lif->txqstats[qi].bytes, | ||
| 473 | &dim_sample); | ||
| 474 | 483 | ||
| 475 | net_dim(&qcq->dim, dim_sample); | 484 | net_dim(&qcq->dim, dim_sample); |
| 476 | } | 485 | } |
| @@ -491,7 +500,7 @@ int ionic_tx_napi(struct napi_struct *napi, int budget) · 14 unmodified lines | |||
| 491 | ionic_tx_service, NULL, NULL); | 500 | ionic_tx_service, NULL, NULL); |
| 492 | 501 | ||
| 493 | if (work_done < budget && napi_complete_done(napi, work_done)) { | 502 | if (work_done < budget && napi_complete_done(napi, work_done)) { |
| 494 | ionic_dim_update(qcq); | 503 | ionic_dim_update(qcq, IONIC_LIF_F_TX_DIM_INTR); |
| 495 | flags |= IONIC_INTR_CRED_UNMASK; | 504 | flags |= IONIC_INTR_CRED_UNMASK; |
| 496 | cq->bound_intr->rearm_count++; | 505 | cq->bound_intr->rearm_count++; |
| 497 | } | 506 | } |
| @@ -530,7 +539,7 @@ int ionic_rx_napi(struct napi_struct *napi, int budget) · 32 unmodified lines | |||
| 530 | ionic_rx_fill(cq->bound_q); | 539 | ionic_rx_fill(cq->bound_q); |
| 531 | 540 | ||
| 532 | if (work_done < budget && napi_complete_done(napi, work_done)) { | 541 | if (work_done < budget && napi_complete_done(napi, work_done)) { |
| 533 | ionic_dim_update(qcq); | 542 | ionic_dim_update(qcq, IONIC_LIF_F_RX_DIM_INTR); |
| 534 | flags |= IONIC_INTR_CRED_UNMASK; | 543 | flags |= IONIC_INTR_CRED_UNMASK; |
| 535 | cq->bound_intr->rearm_count++; | 544 | cq->bound_intr->rearm_count++; |
| 536 | } | 545 | } |
| @@ -576,7 +585,7 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget) · 39 unmodified lines | |||
| 576 | ionic_rx_fill(rxcq->bound_q); | 585 | ionic_rx_fill(rxcq->bound_q); |
| 577 | 586 | ||
| 578 | if (rx_work_done < budget && napi_complete_done(napi, rx_work_done)) { | 587 | if (rx_work_done < budget && napi_complete_done(napi, rx_work_done)) { |
| 579 | ionic_dim_update(qcq); | 588 | ionic_dim_update(qcq, 0); |
| 580 | flags |= IONIC_INTR_CRED_UNMASK; | 589 | flags |= IONIC_INTR_CRED_UNMASK; |
| 581 | rxcq->bound_intr->rearm_count++; | 590 | rxcq->bound_intr->rearm_count++; |
| 582 | } | 591 | } |
| @@ -831,7 +831,7 @@ int qede_configure_vlan_filters(struct qede_dev *edev) · 830 unmodified lines | |||
| 831 | int qede_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) | 831 | int qede_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) |
| 832 | { | 832 | { |
| 833 | struct qede_dev *edev = netdev_priv(dev); | 833 | struct qede_dev *edev = netdev_priv(dev); |
| 834 | struct qede_vlan *vlan = NULL; | 834 | struct qede_vlan *vlan; |
| 835 | int rc = 0; | 835 | int rc = 0; |
| 836 | 836 | ||
| 837 | DP_VERBOSE(edev, NETIF_MSG_IFDOWN, "Removing vlan 0x%04x\n", vid); | 837 | DP_VERBOSE(edev, NETIF_MSG_IFDOWN, "Removing vlan 0x%04x\n", vid); |
| @@ -842,7 +842,7 @@ int qede_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) · 4 unmodified lines | |||
| 842 | if (vlan->vid == vid) | 842 | if (vlan->vid == vid) |
| 843 | break; | 843 | break; |
| 844 | 844 | ||
| 845 | if (!vlan || (vlan->vid != vid)) { | 845 | if (list_entry_is_head(vlan, &edev->vlan_list, list)) { |
| 846 | DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), | 846 | DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), |
| 847 | "Vlan isn't configured\n"); | 847 | "Vlan isn't configured\n"); |
| 848 | goto out; | 848 | goto out; |
| @@ -154,7 +154,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) · 153 unmodified lines | |||
| 154 | "driver lock acquired\n"); | 154 | "driver lock acquired\n"); |
| 155 | return 1; | 155 | return 1; |
| 156 | } | 156 | } |
| 157 | ssleep(1); | 157 | mdelay(1000); |
| 158 | } while (++i < 10); | 158 | } while (++i < 10); |
| 159 | 159 | ||
| 160 | netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); | 160 | netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); |
| @@ -3274,7 +3274,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) · 3113 unmodified lines | |||
| 3274 | if ((value & ISP_CONTROL_SR) == 0) | 3274 | if ((value & ISP_CONTROL_SR) == 0) |
| 3275 | break; | 3275 | break; |
| 3276 | 3276 | ||
| 3277 | ssleep(1); | 3277 | mdelay(1000); |
| 3278 | } while ((--max_wait_time)); | 3278 | } while ((--max_wait_time)); |
| 3279 | 3279 | ||
| 3280 | /* | 3280 | /* |
| @@ -3310,7 +3310,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) · 29 unmodified lines | |||
| 3310 | ispControlStatus); | 3310 | ispControlStatus); |
| 3311 | if ((value & ISP_CONTROL_FSR) == 0) | 3311 | if ((value & ISP_CONTROL_FSR) == 0) |
| 3312 | break; | 3312 | break; |
| 3313 | ssleep(1); | 3313 | mdelay(1000); |
| 3314 | } while ((--max_wait_time)); | 3314 | } while ((--max_wait_time)); |
| 3315 | } | 3315 | } |
| 3316 | if (max_wait_time == 0) | 3316 | if (max_wait_time == 0) |
| @@ -5084,7 +5084,8 @@ static int r8169_mdio_register(struct rtl8169_private *tp) · 5083 unmodified lines | |||
| 5084 | new_bus->priv = tp; | 5084 | new_bus->priv = tp; |
| 5085 | new_bus->parent = &pdev->dev; | 5085 | new_bus->parent = &pdev->dev; |
| 5086 | new_bus->irq[0] = PHY_MAC_INTERRUPT; | 5086 | new_bus->irq[0] = PHY_MAC_INTERRUPT; |
| 5087 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x", pci_dev_id(pdev)); | 5087 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x-%x", |
| 5088 | pci_domain_nr(pdev->bus), pci_dev_id(pdev)); | ||
| 5088 | 5089 | ||
| 5089 | new_bus->read = r8169_mdio_read_reg; | 5090 | new_bus->read = r8169_mdio_read_reg; |
| 5090 | new_bus->write = r8169_mdio_write_reg; | 5091 | new_bus->write = r8169_mdio_write_reg; |
| @@ -864,7 +864,7 @@ enum GECMR_BIT { · 863 unmodified lines | |||
| 864 | 864 | ||
| 865 | /* The Ethernet AVB descriptor definitions. */ | 865 | /* The Ethernet AVB descriptor definitions. */ |
| 866 | struct ravb_desc { | 866 | struct ravb_desc { |
| 867 | __le16 ds; /* Descriptor size */ | 867 | __le16 ds; /* Descriptor size */ |
| 868 | u8 cc; /* Content control MSBs (reserved) */ | 868 | u8 cc; /* Content control MSBs (reserved) */ |
| 869 | u8 die_dt; /* Descriptor interrupt enable and type */ | 869 | u8 die_dt; /* Descriptor interrupt enable and type */ |
| 870 | __le32 dptr; /* Descriptor pointer */ | 870 | __le32 dptr; /* Descriptor pointer */ |
| @@ -920,7 +920,7 @@ static int ravb_poll(struct napi_struct *napi, int budget) · 919 unmodified lines | |||
| 920 | if (ravb_rx(ndev, "a, q)) | 920 | if (ravb_rx(ndev, "a, q)) |
| 921 | goto out; | 921 | goto out; |
| 922 | 922 | ||
| 923 | /* Processing RX Descriptor Ring */ | 923 | /* Processing TX Descriptor Ring */ |
| 924 | spin_lock_irqsave(&priv->lock, flags); | 924 | spin_lock_irqsave(&priv->lock, flags); |
| 925 | /* Clear TX interrupt */ | 925 | /* Clear TX interrupt */ |
| 926 | ravb_write(ndev, ~(mask | TIS_RESERVED), TIS); | 926 | ravb_write(ndev, ~(mask | TIS_RESERVED), TIS); |
| @@ -443,7 +443,7 @@ static int sis900_probe(struct pci_dev *pci_dev, · 442 unmodified lines | |||
| 443 | #endif | 443 | #endif |
| 444 | 444 | ||
| 445 | /* setup various bits in PCI command register */ | 445 | /* setup various bits in PCI command register */ |
| 446 | ret = pci_enable_device(pci_dev); | 446 | ret = pcim_enable_device(pci_dev); |
| 447 | if(ret) return ret; | 447 | if(ret) return ret; |
| 448 | 448 | ||
| 449 | i = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32)); | 449 | i = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32)); |
| @@ -469,7 +469,7 @@ static int sis900_probe(struct pci_dev *pci_dev, · 19 unmodified lines | |||
| 469 | ioaddr = pci_iomap(pci_dev, 0, 0); | 469 | ioaddr = pci_iomap(pci_dev, 0, 0); |
| 470 | if (!ioaddr) { | 470 | if (!ioaddr) { |
| 471 | ret = -ENOMEM; | 471 | ret = -ENOMEM; |
| 472 | goto err_out_cleardev; | 472 | goto err_out; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | sis_priv = netdev_priv(net_dev); | 475 | sis_priv = netdev_priv(net_dev); |
| @@ -581,8 +581,6 @@ err_unmap_tx: · 105 unmodified lines | |||
| 581 | sis_priv->tx_ring_dma); | 581 | sis_priv->tx_ring_dma); |
| 582 | err_out_unmap: | 582 | err_out_unmap: |
| 583 | pci_iounmap(pci_dev, ioaddr); | 583 | pci_iounmap(pci_dev, ioaddr); |
| 584 | err_out_cleardev: | ||
| 585 | pci_release_regions(pci_dev); | ||
| 586 | err_out: | 584 | err_out: |
| 587 | free_netdev(net_dev); | 585 | free_netdev(net_dev); |
| 588 | return ret; | 586 | return ret; |
| @@ -2499,7 +2497,6 @@ static void sis900_remove(struct pci_dev *pci_dev) · 1910 unmodified lines | |||
| 2499 | sis_priv->tx_ring_dma); | 2497 | sis_priv->tx_ring_dma); |
| 2500 | pci_iounmap(pci_dev, sis_priv->ioaddr); | 2498 | pci_iounmap(pci_dev, sis_priv->ioaddr); |
| 2501 | free_netdev(net_dev); | 2499 | free_netdev(net_dev); |
| 2502 | pci_release_regions(pci_dev); | ||
| 2503 | } | 2500 | } |
| 2504 | 2501 | ||
| 2505 | static int __maybe_unused sis900_suspend(struct device *dev) | 2502 | static int __maybe_unused sis900_suspend(struct device *dev) |
| @@ -1249,6 +1249,7 @@ const struct stmmac_ops dwmac410_ops = { · 1248 unmodified lines | |||
| 1249 | .config_l3_filter = dwmac4_config_l3_filter, | 1249 | .config_l3_filter = dwmac4_config_l3_filter, |
| 1250 | .config_l4_filter = dwmac4_config_l4_filter, | 1250 | .config_l4_filter = dwmac4_config_l4_filter, |
| 1251 | .est_configure = dwmac5_est_configure, | 1251 | .est_configure = dwmac5_est_configure, |
| 1252 | .est_irq_status = dwmac5_est_irq_status, | ||
| 1252 | .fpe_configure = dwmac5_fpe_configure, | 1253 | .fpe_configure = dwmac5_fpe_configure, |
| 1253 | .fpe_send_mpacket = dwmac5_fpe_send_mpacket, | 1254 | .fpe_send_mpacket = dwmac5_fpe_send_mpacket, |
| 1254 | .fpe_irq_status = dwmac5_fpe_irq_status, | 1255 | .fpe_irq_status = dwmac5_fpe_irq_status, |
| @@ -1300,6 +1301,7 @@ const struct stmmac_ops dwmac510_ops = { · 45 unmodified lines | |||
| 1300 | .config_l3_filter = dwmac4_config_l3_filter, | 1301 | .config_l3_filter = dwmac4_config_l3_filter, |
| 1301 | .config_l4_filter = dwmac4_config_l4_filter, | 1302 | .config_l4_filter = dwmac4_config_l4_filter, |
| 1302 | .est_configure = dwmac5_est_configure, | 1303 | .est_configure = dwmac5_est_configure, |
| 1304 | .est_irq_status = dwmac5_est_irq_status, | ||
| 1303 | .fpe_configure = dwmac5_fpe_configure, | 1305 | .fpe_configure = dwmac5_fpe_configure, |
| 1304 | .fpe_send_mpacket = dwmac5_fpe_send_mpacket, | 1306 | .fpe_send_mpacket = dwmac5_fpe_send_mpacket, |
| 1305 | .fpe_irq_status = dwmac5_fpe_irq_status, | 1307 | .fpe_irq_status = dwmac5_fpe_irq_status, |
| @@ -8191,8 +8191,9 @@ static int niu_pci_vpd_fetch(struct niu *np, u32 start) · 8190 unmodified lines | |||
| 8191 | err = niu_pci_vpd_scan_props(np, here, end); | 8191 | err = niu_pci_vpd_scan_props(np, here, end); |
| 8192 | if (err < 0) | 8192 | if (err < 0) |
| 8193 | return err; | 8193 | return err; |
| 8194 | /* ret == 1 is not an error */ | ||
| 8194 | if (err == 1) | 8195 | if (err == 1) |
| 8195 | return -EINVAL; | 8196 | return 0; |
| 8196 | } | 8197 | } |
| 8197 | return 0; | 8198 | return 0; |
| 8198 | } | 8199 | } |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | |||
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/ptp_clock_kernel.h> | 15 | #include <linux/ptp_clock_kernel.h> |
| 16 | #include <linux/soc/ixp4xx/cpu.h> | 16 | #include <linux/soc/ixp4xx/cpu.h> |
| 17 | #include <linux/module.h> | ||
| 18 | #include <mach/ixp4xx-regs.h> | ||
| 17 | 19 | ||
| 18 | #include "ixp46x_ts.h" | 20 | #include "ixp46x_ts.h" |
| 19 | 21 | ||
| @@ -288,7 +288,7 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) · 287 unmodified lines | |||
| 288 | if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) { | 288 | if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) { |
| 289 | if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E || | 289 | if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E || |
| 290 | BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810 || | 290 | BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810 || |
| 291 | BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E) | 291 | BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811) |
| 292 | val |= BCM54XX_SHD_SCR3_RXCTXC_DIS; | 292 | val |= BCM54XX_SHD_SCR3_RXCTXC_DIS; |
| 293 | else | 293 | else |
| 294 | val |= BCM54XX_SHD_SCR3_TRDDAPD; | 294 | val |= BCM54XX_SHD_SCR3_TRDDAPD; |
| @@ -2495,7 +2495,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, · 2494 unmodified lines | |||
| 2495 | hso_net_init); | 2495 | hso_net_init); |
| 2496 | if (!net) { | 2496 | if (!net) { |
| 2497 | dev_err(&interface->dev, "Unable to create ethernet device\n"); | 2497 | dev_err(&interface->dev, "Unable to create ethernet device\n"); |
| 2498 | goto exit; | 2498 | goto err_hso_dev; |
| 2499 | } | 2499 | } |
| 2500 | 2500 | ||
| 2501 | hso_net = netdev_priv(net); | 2501 | hso_net = netdev_priv(net); |
| @@ -2508,13 +2508,13 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, · 6 unmodified lines | |||
| 2508 | USB_DIR_IN); | 2508 | USB_DIR_IN); |
| 2509 | if (!hso_net->in_endp) { | 2509 | if (!hso_net->in_endp) { |
| 2510 | dev_err(&interface->dev, "Can't find BULK IN endpoint\n"); | 2510 | dev_err(&interface->dev, "Can't find BULK IN endpoint\n"); |
| 2511 | goto exit; | 2511 | goto err_net; |
| 2512 | } | 2512 | } |
| 2513 | hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, | 2513 | hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, |
| 2514 | USB_DIR_OUT); | 2514 | USB_DIR_OUT); |
| 2515 | if (!hso_net->out_endp) { | 2515 | if (!hso_net->out_endp) { |
| 2516 | dev_err(&interface->dev, "Can't find BULK OUT endpoint\n"); | 2516 | dev_err(&interface->dev, "Can't find BULK OUT endpoint\n"); |
| 2517 | goto exit; | 2517 | goto err_net; |
| 2518 | } | 2518 | } |
| 2519 | SET_NETDEV_DEV(net, &interface->dev); | 2519 | SET_NETDEV_DEV(net, &interface->dev); |
| 2520 | SET_NETDEV_DEVTYPE(net, &hso_type); | 2520 | SET_NETDEV_DEVTYPE(net, &hso_type); |
| @@ -2523,18 +2523,18 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, · 2 unmodified lines | |||
| 2523 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { | 2523 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { |
| 2524 | hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL); | 2524 | hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL); |
| 2525 | if (!hso_net->mux_bulk_rx_urb_pool[i]) | 2525 | if (!hso_net->mux_bulk_rx_urb_pool[i]) |
| 2526 | goto exit; | 2526 | goto err_mux_bulk_rx; |
| 2527 | hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE, | 2527 | hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE, |
| 2528 | GFP_KERNEL); | 2528 | GFP_KERNEL); |
| 2529 | if (!hso_net->mux_bulk_rx_buf_pool[i]) | 2529 | if (!hso_net->mux_bulk_rx_buf_pool[i]) |
| 2530 | goto exit; | 2530 | goto err_mux_bulk_rx; |
| 2531 | } | 2531 | } |
| 2532 | hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL); | 2532 | hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
| 2533 | if (!hso_net->mux_bulk_tx_urb) | 2533 | if (!hso_net->mux_bulk_tx_urb) |
| 2534 | goto exit; | 2534 | goto err_mux_bulk_rx; |
| 2535 | hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL); | 2535 | hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL); |
| 2536 | if (!hso_net->mux_bulk_tx_buf) | 2536 | if (!hso_net->mux_bulk_tx_buf) |
| 2537 | goto exit; | 2537 | goto err_free_tx_urb; |
| 2538 | 2538 | ||
| 2539 | add_net_device(hso_dev); | 2539 | add_net_device(hso_dev); |
| 2540 | 2540 | ||
| @@ -2542,7 +2542,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, · 1 unmodified line | |||
| 2542 | result = register_netdev(net); | 2542 | result = register_netdev(net); |
| 2543 | if (result) { | 2543 | if (result) { |
| 2544 | dev_err(&interface->dev, "Failed to register device\n"); | 2544 | dev_err(&interface->dev, "Failed to register device\n"); |
| 2545 | goto exit; | 2545 | goto err_free_tx_buf; |
| 2546 | } | 2546 | } |
| 2547 | 2547 | ||
| 2548 | hso_log_port(hso_dev); | 2548 | hso_log_port(hso_dev); |
| @@ -2550,8 +2550,21 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, · 1 unmodified line | |||
| 2550 | hso_create_rfkill(hso_dev, interface); | 2550 | hso_create_rfkill(hso_dev, interface); |
| 2551 | 2551 | ||
| 2552 | return hso_dev; | 2552 | return hso_dev; |
| 2553 | exit: | 2553 | |
| 2554 | hso_free_net_device(hso_dev, true); | 2554 | err_free_tx_buf: |
| 2555 | remove_net_device(hso_dev); | ||
| 2556 | kfree(hso_net->mux_bulk_tx_buf); | ||
| 2557 | err_free_tx_urb: | ||
| 2558 | usb_free_urb(hso_net->mux_bulk_tx_urb); | ||
| 2559 | err_mux_bulk_rx: | ||
| 2560 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { | ||
| 2561 | usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]); | ||
| 2562 | kfree(hso_net->mux_bulk_rx_buf_pool[i]); | ||
| 2563 | } | ||
| 2564 | err_net: | ||
| 2565 | free_netdev(net); | ||
| 2566 | err_hso_dev: | ||
| 2567 | kfree(hso_dev); | ||
| 2555 | return NULL; | 2568 | return NULL; |
| 2556 | } | 2569 | } |
| 2557 | 2570 | ||
| @@ -1552,7 +1552,8 @@ static int · 1551 unmodified lines | |||
| 1552 | rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, | 1552 | rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, |
| 1553 | u32 advertising); | 1553 | u32 advertising); |
| 1554 | 1554 | ||
| 1555 | static int rtl8152_set_mac_address(struct net_device *netdev, void *p) | 1555 | static int __rtl8152_set_mac_address(struct net_device *netdev, void *p, |
| 1556 | bool in_resume) | ||
| 1556 | { | 1557 | { |
| 1557 | struct r8152 *tp = netdev_priv(netdev); | 1558 | struct r8152 *tp = netdev_priv(netdev); |
| 1558 | struct sockaddr *addr = p; | 1559 | struct sockaddr *addr = p; |
| @@ -1561,9 +1562,11 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p) · 2 unmodified lines | |||
| 1561 | if (!is_valid_ether_addr(addr->sa_data)) | 1562 | if (!is_valid_ether_addr(addr->sa_data)) |
| 1562 | goto out1; | 1563 | goto out1; |
| 1563 | 1564 | ||
| 1564 | ret = usb_autopm_get_interface(tp->intf); | 1565 | if (!in_resume) { |
| 1565 | if (ret < 0) | 1566 | ret = usb_autopm_get_interface(tp->intf); |
| 1566 | goto out1; | 1567 | if (ret < 0) |
| 1568 | goto out1; | ||
| 1569 | } | ||
| 1567 | 1570 | ||
| 1568 | mutex_lock(&tp->control); | 1571 | mutex_lock(&tp->control); |
| 1569 | 1572 | ||
| @@ -1575,11 +1578,17 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p) · 5 unmodified lines | |||
| 1575 | 1578 | ||
| 1576 | mutex_unlock(&tp->control); | 1579 | mutex_unlock(&tp->control); |
| 1577 | 1580 | ||
| 1578 | usb_autopm_put_interface(tp->intf); | 1581 | if (!in_resume) |
| 1582 | usb_autopm_put_interface(tp->intf); | ||
| 1579 | out1: | 1583 | out1: |
| 1580 | return ret; | 1584 | return ret; |
| 1581 | } | 1585 | } |
| 1582 | 1586 | ||
| 1587 | static int rtl8152_set_mac_address(struct net_device *netdev, void *p) | ||
| 1588 | { | ||
| 1589 | return __rtl8152_set_mac_address(netdev, p, false); | ||
| 1590 | } | ||
| 1591 | |||
| 1583 | /* Devices containing proper chips can support a persistent | 1592 | /* Devices containing proper chips can support a persistent |
| 1584 | * host system provided MAC address. | 1593 | * host system provided MAC address. |
| 1585 | * Examples of this are Dell TB15 and Dell WD15 docks | 1594 | * Examples of this are Dell TB15 and Dell WD15 docks |
| @@ -1698,7 +1707,7 @@ static int determine_ethernet_addr(struct r8152 *tp, struct sockaddr *sa) · 112 unmodified lines | |||
| 1698 | return ret; | 1707 | return ret; |
| 1699 | } | 1708 | } |
| 1700 | 1709 | ||
| 1701 | static int set_ethernet_addr(struct r8152 *tp) | 1710 | static int set_ethernet_addr(struct r8152 *tp, bool in_resume) |
| 1702 | { | 1711 | { |
| 1703 | struct net_device *dev = tp->netdev; | 1712 | struct net_device *dev = tp->netdev; |
| 1704 | struct sockaddr sa; | 1713 | struct sockaddr sa; |
| @@ -1711,7 +1720,7 @@ static int set_ethernet_addr(struct r8152 *tp) · 6 unmodified lines | |||
| 1711 | if (tp->version == RTL_VER_01) | 1720 | if (tp->version == RTL_VER_01) |
| 1712 | ether_addr_copy(dev->dev_addr, sa.sa_data); | 1721 | ether_addr_copy(dev->dev_addr, sa.sa_data); |
| 1713 | else | 1722 | else |
| 1714 | ret = rtl8152_set_mac_address(dev, &sa); | 1723 | ret = __rtl8152_set_mac_address(dev, &sa, in_resume); |
| 1715 | 1724 | ||
| 1716 | return ret; | 1725 | return ret; |
| 1717 | } | 1726 | } |
| @@ -6763,9 +6772,10 @@ static int rtl8152_close(struct net_device *netdev) · 5045 unmodified lines | |||
| 6763 | tp->rtl_ops.down(tp); | 6772 | tp->rtl_ops.down(tp); |
| 6764 | 6773 | ||
| 6765 | mutex_unlock(&tp->control); | 6774 | mutex_unlock(&tp->control); |
| 6775 | } | ||
| 6766 | 6776 | ||
| 6777 | if (!res) | ||
| 6767 | usb_autopm_put_interface(tp->intf); | 6778 | usb_autopm_put_interface(tp->intf); |
| 6768 | } | ||
| 6769 | 6779 | ||
| 6770 | free_all_mem(tp); | 6780 | free_all_mem(tp); |
| 6771 | 6781 | ||
| @@ -8443,7 +8453,7 @@ static int rtl8152_reset_resume(struct usb_interface *intf) · 1671 unmodified lines | |||
| 8443 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); | 8453 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); |
| 8444 | tp->rtl_ops.init(tp); | 8454 | tp->rtl_ops.init(tp); |
| 8445 | queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); | 8455 | queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); |
| 8446 | set_ethernet_addr(tp); | 8456 | set_ethernet_addr(tp, true); |
| 8447 | return rtl8152_resume(intf); | 8457 | return rtl8152_resume(intf); |
| 8448 | } | 8458 | } |
| 8449 | 8459 | ||
| @@ -9644,7 +9654,7 @@ static int rtl8152_probe(struct usb_interface *intf, · 1194 unmodified lines | |||
| 9644 | tp->rtl_fw.retry = true; | 9654 | tp->rtl_fw.retry = true; |
| 9645 | #endif | 9655 | #endif |
| 9646 | queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); | 9656 | queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); |
| 9647 | set_ethernet_addr(tp); | 9657 | set_ethernet_addr(tp, false); |
| 9648 | 9658 | ||
| 9649 | usb_set_intfdata(intf, tp); | 9659 | usb_set_intfdata(intf, tp); |
| 9650 | 9660 | ||
| @@ -136,6 +136,29 @@ static struct ieee80211_supported_band band_5ghz = { · 135 unmodified lines | |||
| 136 | /* Assigned at module init. Guaranteed locally-administered and unicast. */ | 136 | /* Assigned at module init. Guaranteed locally-administered and unicast. */ |
| 137 | static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {}; | 137 | static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {}; |
| 138 | 138 | ||
| 139 | static void virt_wifi_inform_bss(struct wiphy *wiphy) | ||
| 140 | { | ||
| 141 | u64 tsf = div_u64(ktime_get_boottime_ns(), 1000); | ||
| 142 | struct cfg80211_bss *informed_bss; | ||
| 143 | static const struct { | ||
| 144 | u8 tag; | ||
| 145 | u8 len; | ||
| 146 | u8 ssid[8]; | ||
| 147 | } __packed ssid = { | ||
| 148 | .tag = WLAN_EID_SSID, | ||
| 149 | .len = 8, | ||
| 150 | .ssid = "VirtWifi", | ||
| 151 | }; | ||
| 152 | |||
| 153 | informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, | ||
| 154 | CFG80211_BSS_FTYPE_PRESP, | ||
| 155 | fake_router_bssid, tsf, | ||
| 156 | WLAN_CAPABILITY_ESS, 0, | ||
| 157 | (void *)&ssid, sizeof(ssid), | ||
| 158 | DBM_TO_MBM(-50), GFP_KERNEL); | ||
| 159 | cfg80211_put_bss(wiphy, informed_bss); | ||
| 160 | } | ||
| 161 | |||
| 139 | /* Called with the rtnl lock held. */ | 162 | /* Called with the rtnl lock held. */ |
| 140 | static int virt_wifi_scan(struct wiphy *wiphy, | 163 | static int virt_wifi_scan(struct wiphy *wiphy, |
| 141 | struct cfg80211_scan_request *request) | 164 | struct cfg80211_scan_request *request) |
| @@ -156,28 +179,13 @@ static int virt_wifi_scan(struct wiphy *wiphy, · 14 unmodified lines | |||
| 156 | /* Acquires and releases the rdev BSS lock. */ | 179 | /* Acquires and releases the rdev BSS lock. */ |
| 157 | static void virt_wifi_scan_result(struct work_struct *work) | 180 | static void virt_wifi_scan_result(struct work_struct *work) |
| 158 | { | 181 | { |
| 159 | struct { | ||
| 160 | u8 tag; | ||
| 161 | u8 len; | ||
| 162 | u8 ssid[8]; | ||
| 163 | } __packed ssid = { | ||
| 164 | .tag = WLAN_EID_SSID, .len = 8, .ssid = "VirtWifi", | ||
| 165 | }; | ||
| 166 | struct cfg80211_bss *informed_bss; | ||
| 167 | struct virt_wifi_wiphy_priv *priv = | 182 | struct virt_wifi_wiphy_priv *priv = |
| 168 | container_of(work, struct virt_wifi_wiphy_priv, | 183 | container_of(work, struct virt_wifi_wiphy_priv, |
| 169 | scan_result.work); | 184 | scan_result.work); |
| 170 | struct wiphy *wiphy = priv_to_wiphy(priv); | 185 | struct wiphy *wiphy = priv_to_wiphy(priv); |
| 171 | struct cfg80211_scan_info scan_info = { .aborted = false }; | 186 | struct cfg80211_scan_info scan_info = { .aborted = false }; |
| 172 | u64 tsf = div_u64(ktime_get_boottime_ns(), 1000); | ||
| 173 | 187 | ||
| 174 | informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, | 188 | virt_wifi_inform_bss(wiphy); |
| 175 | CFG80211_BSS_FTYPE_PRESP, | ||
| 176 | fake_router_bssid, tsf, | ||
| 177 | WLAN_CAPABILITY_ESS, 0, | ||
| 178 | (void *)&ssid, sizeof(ssid), | ||
| 179 | DBM_TO_MBM(-50), GFP_KERNEL); | ||
| 180 | cfg80211_put_bss(wiphy, informed_bss); | ||
| 181 | 189 | ||
| 182 | /* Schedules work which acquires and releases the rtnl lock. */ | 190 | /* Schedules work which acquires and releases the rtnl lock. */ |
| 183 | cfg80211_scan_done(priv->scan_request, &scan_info); | 191 | cfg80211_scan_done(priv->scan_request, &scan_info); |
| @@ -225,10 +233,12 @@ static int virt_wifi_connect(struct wiphy *wiphy, struct net_device *netdev, · 41 unmodified lines | |||
| 225 | if (!could_schedule) | 233 | if (!could_schedule) |
| 226 | return -EBUSY; | 234 | return -EBUSY; |
| 227 | 235 | ||
| 228 | if (sme->bssid) | 236 | if (sme->bssid) { |
| 229 | ether_addr_copy(priv->connect_requested_bss, sme->bssid); | 237 | ether_addr_copy(priv->connect_requested_bss, sme->bssid); |
| 230 | else | 238 | } else { |
| 239 | virt_wifi_inform_bss(wiphy); | ||
| 231 | eth_zero_addr(priv->connect_requested_bss); | 240 | eth_zero_addr(priv->connect_requested_bss); |
| 241 | } | ||
| 232 | 242 | ||
| 233 | wiphy_debug(wiphy, "connect\n"); | 243 | wiphy_debug(wiphy, "connect\n"); |
| 234 | 244 | ||
| @@ -241,11 +251,13 @@ static void virt_wifi_connect_complete(struct work_struct *work) · 6 unmodified lines | |||
| 241 | struct virt_wifi_netdev_priv *priv = | 251 | struct virt_wifi_netdev_priv *priv = |
| 242 | container_of(work, struct virt_wifi_netdev_priv, connect.work); | 252 | container_of(work, struct virt_wifi_netdev_priv, connect.work); |
| 243 | u8 *requested_bss = priv->connect_requested_bss; | 253 | u8 *requested_bss = priv->connect_requested_bss; |
| 244 | bool has_addr = !is_zero_ether_addr(requested_bss); | ||
| 245 | bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); | 254 | bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); |
| 246 | u16 status = WLAN_STATUS_SUCCESS; | 255 | u16 status = WLAN_STATUS_SUCCESS; |
| 247 | 256 | ||
| 248 | if (!priv->is_up || (has_addr && !right_addr)) | 257 | if (is_zero_ether_addr(requested_bss)) |
| 258 | requested_bss = NULL; | ||
| 259 | |||
| 260 | if (!priv->is_up || (requested_bss && !right_addr)) | ||
| 249 | status = WLAN_STATUS_UNSPECIFIED_FAILURE; | 261 | status = WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 250 | else | 262 | else |
| 251 | priv->is_connected = true; | 263 | priv->is_connected = true; |
| @@ -984,6 +984,8 @@ static void wwan_create_default_link(struct wwan_device *wwandev, · 983 unmodified lines | |||
| 984 | goto unlock; | 984 | goto unlock; |
| 985 | } | 985 | } |
| 986 | 986 | ||
| 987 | rtnl_configure_link(dev, NULL); /* Link initialized, notify new link */ | ||
| 988 | |||
| 987 | unlock: | 989 | unlock: |
| 988 | rtnl_unlock(); | 990 | rtnl_unlock(); |
| 989 | 991 | ||
| @@ -192,8 +192,7 @@ static void nfcsim_recv_wq(struct work_struct *work) · 191 unmodified lines | |||
| 192 | 192 | ||
| 193 | if (!IS_ERR(skb)) | 193 | if (!IS_ERR(skb)) |
| 194 | dev_kfree_skb(skb); | 194 | dev_kfree_skb(skb); |
| 195 | 195 | return; | |
| 196 | skb = ERR_PTR(-ENODEV); | ||
| 197 | } | 196 | } |
| 198 | 197 | ||
| 199 | dev->cb(dev->nfc_digital_dev, dev->arg, skb); | 198 | dev->cb(dev->nfc_digital_dev, dev->arg, skb); |
| @@ -423,7 +423,7 @@ int s3fwrn5_fw_download(struct s3fwrn5_fw_info *fw_info) · 422 unmodified lines | |||
| 423 | if (IS_ERR(tfm)) { | 423 | if (IS_ERR(tfm)) { |
| 424 | ret = PTR_ERR(tfm); | 424 | ret = PTR_ERR(tfm); |
| 425 | dev_err(&fw_info->ndev->nfc_dev->dev, | 425 | dev_err(&fw_info->ndev->nfc_dev->dev, |
| 426 | "Cannot allocate shash (code=%d)\n", ret); | 426 | "Cannot allocate shash (code=%pe)\n", tfm); |
| 427 | goto out; | 427 | goto out; |
| 428 | } | 428 | } |
| 429 | 429 | ||
| @@ -900,7 +900,10 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns, · 899 unmodified lines | |||
| 900 | cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req))); | 900 | cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req))); |
| 901 | cmnd->write_zeroes.length = | 901 | cmnd->write_zeroes.length = |
| 902 | cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1); | 902 | cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1); |
| 903 | cmnd->write_zeroes.control = 0; | 903 | if (nvme_ns_has_pi(ns)) |
| 904 | cmnd->write_zeroes.control = cpu_to_le16(NVME_RW_PRINFO_PRACT); | ||
| 905 | else | ||
| 906 | cmnd->write_zeroes.control = 0; | ||
| 904 | return BLK_STS_OK; | 907 | return BLK_STS_OK; |
| 905 | } | 908 | } |
| 906 | 909 | ||
| @@ -3807,6 +3810,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid, · 2900 unmodified lines | |||
| 3807 | 3810 | ||
| 3808 | static void nvme_ns_remove(struct nvme_ns *ns) | 3811 | static void nvme_ns_remove(struct nvme_ns *ns) |
| 3809 | { | 3812 | { |
| 3813 | bool last_path = false; | ||
| 3814 | |||
| 3810 | if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags)) | 3815 | if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags)) |
| 3811 | return; | 3816 | return; |
| 3812 | 3817 | ||
| @@ -3815,8 +3820,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) · 2 unmodified lines | |||
| 3815 | 3820 | ||
| 3816 | mutex_lock(&ns->ctrl->subsys->lock); | 3821 | mutex_lock(&ns->ctrl->subsys->lock); |
| 3817 | list_del_rcu(&ns->siblings); | 3822 | list_del_rcu(&ns->siblings); |
| 3818 | if (list_empty(&ns->head->list)) | ||
| 3819 | list_del_init(&ns->head->entry); | ||
| 3820 | mutex_unlock(&ns->ctrl->subsys->lock); | 3823 | mutex_unlock(&ns->ctrl->subsys->lock); |
| 3821 | 3824 | ||
| 3822 | synchronize_rcu(); /* guarantee not available in head->list */ | 3825 | synchronize_rcu(); /* guarantee not available in head->list */ |
| @@ -3836,7 +3839,15 @@ static void nvme_ns_remove(struct nvme_ns *ns) · 13 unmodified lines | |||
| 3836 | list_del_init(&ns->list); | 3839 | list_del_init(&ns->list); |
| 3837 | up_write(&ns->ctrl->namespaces_rwsem); | 3840 | up_write(&ns->ctrl->namespaces_rwsem); |
| 3838 | 3841 | ||
| 3839 | nvme_mpath_check_last_path(ns); | 3842 | /* Synchronize with nvme_init_ns_head() */ |
| 3843 | mutex_lock(&ns->head->subsys->lock); | ||
| 3844 | if (list_empty(&ns->head->list)) { | ||
| 3845 | list_del_init(&ns->head->entry); | ||
| 3846 | last_path = true; | ||
| 3847 | } | ||
| 3848 | mutex_unlock(&ns->head->subsys->lock); | ||
| 3849 | if (last_path) | ||
| 3850 | nvme_mpath_shutdown_disk(ns->head); | ||
| 3840 | nvme_put_ns(ns); | 3851 | nvme_put_ns(ns); |
| 3841 | } | 3852 | } |
| 3842 | 3853 | ||
| @@ -760,14 +760,21 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id) · 759 unmodified lines | |||
| 760 | #endif | 760 | #endif |
| 761 | } | 761 | } |
| 762 | 762 | ||
| 763 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) | 763 | void nvme_mpath_shutdown_disk(struct nvme_ns_head *head) |
| 764 | { | 764 | { |
| 765 | if (!head->disk) | 765 | if (!head->disk) |
| 766 | return; | 766 | return; |
| 767 | kblockd_schedule_work(&head->requeue_work); | ||
| 767 | if (head->disk->flags & GENHD_FL_UP) { | 768 | if (head->disk->flags & GENHD_FL_UP) { |
| 768 | nvme_cdev_del(&head->cdev, &head->cdev_device); | 769 | nvme_cdev_del(&head->cdev, &head->cdev_device); |
| 769 | del_gendisk(head->disk); | 770 | del_gendisk(head->disk); |
| 770 | } | 771 | } |
| 772 | } | ||
| 773 | |||
| 774 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) | ||
| 775 | { | ||
| 776 | if (!head->disk) | ||
| 777 | return; | ||
| 771 | blk_set_queue_dying(head->disk->queue); | 778 | blk_set_queue_dying(head->disk->queue); |
| 772 | /* make sure all pending bios are cleaned up */ | 779 | /* make sure all pending bios are cleaned up */ |
| 773 | kblockd_schedule_work(&head->requeue_work); | 780 | kblockd_schedule_work(&head->requeue_work); |
| @@ -716,14 +716,7 @@ void nvme_mpath_uninit(struct nvme_ctrl *ctrl); · 715 unmodified lines | |||
| 716 | void nvme_mpath_stop(struct nvme_ctrl *ctrl); | 716 | void nvme_mpath_stop(struct nvme_ctrl *ctrl); |
| 717 | bool nvme_mpath_clear_current_path(struct nvme_ns *ns); | 717 | bool nvme_mpath_clear_current_path(struct nvme_ns *ns); |
| 718 | void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl); | 718 | void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl); |
| 719 | 719 | void nvme_mpath_shutdown_disk(struct nvme_ns_head *head); | |
| 720 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) | ||
| 721 | { | ||
| 722 | struct nvme_ns_head *head = ns->head; | ||
| 723 | |||
| 724 | if (head->disk && list_empty(&head->list)) | ||
| 725 | kblockd_schedule_work(&head->requeue_work); | ||
| 726 | } | ||
| 727 | 720 | ||
| 728 | static inline void nvme_trace_bio_complete(struct request *req) | 721 | static inline void nvme_trace_bio_complete(struct request *req) |
| 729 | { | 722 | { |
| @@ -772,7 +765,7 @@ static inline bool nvme_mpath_clear_current_path(struct nvme_ns *ns) · 42 unmodified lines | |||
| 772 | static inline void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) | 765 | static inline void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) |
| 773 | { | 766 | { |
| 774 | } | 767 | } |
| 775 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) | 768 | static inline void nvme_mpath_shutdown_disk(struct nvme_ns_head *head) |
| 776 | { | 769 | { |
| 777 | } | 770 | } |
| 778 | static inline void nvme_trace_bio_complete(struct request *req) | 771 | static inline void nvme_trace_bio_complete(struct request *req) |
| @@ -2631,7 +2631,9 @@ static void nvme_reset_work(struct work_struct *work) · 2630 unmodified lines | |||
| 2631 | bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); | 2631 | bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); |
| 2632 | int result; | 2632 | int result; |
| 2633 | 2633 | ||
| 2634 | if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING)) { | 2634 | if (dev->ctrl.state != NVME_CTRL_RESETTING) { |
| 2635 | dev_warn(dev->ctrl.device, "ctrl state %d is not RESETTING\n", | ||
| 2636 | dev->ctrl.state); | ||
| 2635 | result = -ENODEV; | 2637 | result = -ENODEV; |
| 2636 | goto out; | 2638 | goto out; |
| 2637 | } | 2639 | } |
| @@ -56,7 +56,7 @@ TRACE_EVENT(nvme_setup_cmd, · 55 unmodified lines | |||
| 56 | __field(u8, fctype) | 56 | __field(u8, fctype) |
| 57 | __field(u16, cid) | 57 | __field(u16, cid) |
| 58 | __field(u32, nsid) | 58 | __field(u32, nsid) |
| 59 | __field(u64, metadata) | 59 | __field(bool, metadata) |
| 60 | __array(u8, cdw10, 24) | 60 | __array(u8, cdw10, 24) |
| 61 | ), | 61 | ), |
| 62 | TP_fast_assign( | 62 | TP_fast_assign( |
| @@ -66,13 +66,13 @@ TRACE_EVENT(nvme_setup_cmd, · 3 unmodified lines | |||
| 66 | __entry->flags = cmd->common.flags; | 66 | __entry->flags = cmd->common.flags; |
| 67 | __entry->cid = cmd->common.command_id; | 67 | __entry->cid = cmd->common.command_id; |
| 68 | __entry->nsid = le32_to_cpu(cmd->common.nsid); | 68 | __entry->nsid = le32_to_cpu(cmd->common.nsid); |
| 69 | __entry->metadata = le64_to_cpu(cmd->common.metadata); | 69 | __entry->metadata = !!blk_integrity_rq(req); |
| 70 | __entry->fctype = cmd->fabrics.fctype; | 70 | __entry->fctype = cmd->fabrics.fctype; |
| 71 | __assign_disk_name(__entry->disk, req->rq_disk); | 71 | __assign_disk_name(__entry->disk, req->rq_disk); |
| 72 | memcpy(__entry->cdw10, &cmd->common.cdw10, | 72 | memcpy(__entry->cdw10, &cmd->common.cdw10, |
| 73 | sizeof(__entry->cdw10)); | 73 | sizeof(__entry->cdw10)); |
| 74 | ), | 74 | ), |
| 75 | TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%llx, cmd=(%s %s)", | 75 | TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%x, cmd=(%s %s)", |
| 76 | __entry->ctrl_id, __print_disk_name(__entry->disk), | 76 | __entry->ctrl_id, __print_disk_name(__entry->disk), |
| 77 | __entry->qid, __entry->cid, __entry->nsid, | 77 | __entry->qid, __entry->cid, __entry->nsid, |
| 78 | __entry->flags, __entry->metadata, | 78 | __entry->flags, __entry->metadata, |
| @@ -46,34 +46,79 @@ · 45 unmodified lines | |||
| 46 | #define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE | 46 | #define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE |
| 47 | #define AMD_PMC_RESULT_FAILED 0xFF | 47 | #define AMD_PMC_RESULT_FAILED 0xFF |
| 48 | 48 | ||
| 49 | /* FCH SSC Registers */ | ||
| 50 | #define FCH_S0I3_ENTRY_TIME_L_OFFSET 0x30 | ||
| 51 | #define FCH_S0I3_ENTRY_TIME_H_OFFSET 0x34 | ||
| 52 | #define FCH_S0I3_EXIT_TIME_L_OFFSET 0x38 | ||
| 53 | #define FCH_S0I3_EXIT_TIME_H_OFFSET 0x3C | ||
| 54 | #define FCH_SSC_MAPPING_SIZE 0x800 | ||
| 55 | #define FCH_BASE_PHY_ADDR_LOW 0xFED81100 | ||
| 56 | #define FCH_BASE_PHY_ADDR_HIGH 0x00000000 | ||
| 57 | |||
| 58 | /* SMU Message Definations */ | ||
| 59 | #define SMU_MSG_GETSMUVERSION 0x02 | ||
| 60 | #define SMU_MSG_LOG_GETDRAM_ADDR_HI 0x04 | ||
| 61 | #define SMU_MSG_LOG_GETDRAM_ADDR_LO 0x05 | ||
| 62 | #define SMU_MSG_LOG_START 0x06 | ||
| 63 | #define SMU_MSG_LOG_RESET 0x07 | ||
| 64 | #define SMU_MSG_LOG_DUMP_DATA 0x08 | ||
| 65 | #define SMU_MSG_GET_SUP_CONSTRAINTS 0x09 | ||
| 49 | /* List of supported CPU ids */ | 66 | /* List of supported CPU ids */ |
| 50 | #define AMD_CPU_ID_RV 0x15D0 | 67 | #define AMD_CPU_ID_RV 0x15D0 |
| 51 | #define AMD_CPU_ID_RN 0x1630 | 68 | #define AMD_CPU_ID_RN 0x1630 |
| 52 | #define AMD_CPU_ID_PCO AMD_CPU_ID_RV | 69 | #define AMD_CPU_ID_PCO AMD_CPU_ID_RV |
| 53 | #define AMD_CPU_ID_CZN AMD_CPU_ID_RN | 70 | #define AMD_CPU_ID_CZN AMD_CPU_ID_RN |
| 71 | #define AMD_CPU_ID_YC 0x14B5 | ||
| 54 | 72 | ||
| 55 | #define AMD_SMU_FW_VERSION 0x0 | ||
| 56 | #define PMC_MSG_DELAY_MIN_US 100 | 73 | #define PMC_MSG_DELAY_MIN_US 100 |
| 57 | #define RESPONSE_REGISTER_LOOP_MAX 200 | 74 | #define RESPONSE_REGISTER_LOOP_MAX 200 |
| 58 | 75 | ||
| 76 | #define SOC_SUBSYSTEM_IP_MAX 12 | ||
| 77 | #define DELAY_MIN_US 2000 | ||
| 78 | #define DELAY_MAX_US 3000 | ||
| 59 | enum amd_pmc_def { | 79 | enum amd_pmc_def { |
| 60 | MSG_TEST = 0x01, | 80 | MSG_TEST = 0x01, |
| 61 | MSG_OS_HINT_PCO, | 81 | MSG_OS_HINT_PCO, |
| 62 | MSG_OS_HINT_RN, | 82 | MSG_OS_HINT_RN, |
| 63 | }; | 83 | }; |
| 64 | 84 | ||
| 85 | struct amd_pmc_bit_map { | ||
| 86 | const char *name; | ||
| 87 | u32 bit_mask; | ||
| 88 | }; | ||
| 89 | |||
| 90 | static const struct amd_pmc_bit_map soc15_ip_blk[] = { | ||
| 91 | {"DISPLAY", BIT(0)}, | ||
| 92 | {"CPU", BIT(1)}, | ||
| 93 | {"GFX", BIT(2)}, | ||
| 94 | {"VDD", BIT(3)}, | ||
| 95 | {"ACP", BIT(4)}, | ||
| 96 | {"VCN", BIT(5)}, | ||
| 97 | {"ISP", BIT(6)}, | ||
| 98 | {"NBIO", BIT(7)}, | ||
| 99 | {"DF", BIT(8)}, | ||
| 100 | {"USB0", BIT(9)}, | ||
| 101 | {"USB1", BIT(10)}, | ||
| 102 | {"LAPIC", BIT(11)}, | ||
| 103 | {} | ||
| 104 | }; | ||
| 105 | |||
| 65 | struct amd_pmc_dev { | 106 | struct amd_pmc_dev { |
| 66 | void __iomem *regbase; | 107 | void __iomem *regbase; |
| 67 | void __iomem *smu_base; | 108 | void __iomem *smu_virt_addr; |
| 109 | void __iomem *fch_virt_addr; | ||
| 68 | u32 base_addr; | 110 | u32 base_addr; |
| 69 | u32 cpu_id; | 111 | u32 cpu_id; |
| 112 | u32 active_ips; | ||
| 70 | struct device *dev; | 113 | struct device *dev; |
| 114 | struct mutex lock; /* generic mutex lock */ | ||
| 71 | #if IS_ENABLED(CONFIG_DEBUG_FS) | 115 | #if IS_ENABLED(CONFIG_DEBUG_FS) |
| 72 | struct dentry *dbgfs_dir; | 116 | struct dentry *dbgfs_dir; |
| 73 | #endif /* CONFIG_DEBUG_FS */ | 117 | #endif /* CONFIG_DEBUG_FS */ |
| 74 | }; | 118 | }; |
| 75 | 119 | ||
| 76 | static struct amd_pmc_dev pmc; | 120 | static struct amd_pmc_dev pmc; |
| 121 | static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg, bool ret); | ||
| 77 | 122 | ||
| 78 | static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset) | 123 | static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset) |
| 79 | { | 124 | { |
| @@ -85,18 +130,77 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3 · 5 unmodified lines | |||
| 85 | iowrite32(val, dev->regbase + reg_offset); | 130 | iowrite32(val, dev->regbase + reg_offset); |
| 86 | } | 131 | } |
| 87 | 132 | ||
| 133 | struct smu_metrics { | ||
| 134 | u32 table_version; | ||
| 135 | u32 hint_count; | ||
| 136 | u32 s0i3_cyclecount; | ||
| 137 | u32 timein_s0i2; | ||
| 138 | u64 timeentering_s0i3_lastcapture; | ||
| 139 | u64 timeentering_s0i3_totaltime; | ||
| 140 | u64 timeto_resume_to_os_lastcapture; | ||
| 141 | u64 timeto_resume_to_os_totaltime; | ||
| 142 | u64 timein_s0i3_lastcapture; | ||
| 143 | u64 timein_s0i3_totaltime; | ||
| 144 | u64 timein_swdrips_lastcapture; | ||
| 145 | u64 timein_swdrips_totaltime; | ||
| 146 | u64 timecondition_notmet_lastcapture[SOC_SUBSYSTEM_IP_MAX]; | ||
| 147 | u64 timecondition_notmet_totaltime[SOC_SUBSYSTEM_IP_MAX]; | ||
| 148 | } __packed; | ||
| 149 | |||
| 88 | #ifdef CONFIG_DEBUG_FS | 150 | #ifdef CONFIG_DEBUG_FS |
| 89 | static int smu_fw_info_show(struct seq_file *s, void *unused) | 151 | static int smu_fw_info_show(struct seq_file *s, void *unused) |
| 90 | { | 152 | { |
| 91 | struct amd_pmc_dev *dev = s->private; | 153 | struct amd_pmc_dev *dev = s->private; |
| 92 | u32 value; | 154 | struct smu_metrics table; |
| 155 | int idx; | ||
| 156 | |||
| 157 | if (dev->cpu_id == AMD_CPU_ID_PCO) | ||
| 158 | return -EINVAL; | ||
| 159 | |||
| 160 | memcpy_fromio(&table, dev->smu_virt_addr, sizeof(struct smu_metrics)); | ||
| 161 | |||
| 162 | seq_puts(s, "\n=== SMU Statistics ===\n"); | ||
| 163 | seq_printf(s, "Table Version: %d\n", table.table_version); | ||
| 164 | seq_printf(s, "Hint Count: %d\n", table.hint_count); | ||
| 165 | seq_printf(s, "S0i3 Cycle Count: %d\n", table.s0i3_cyclecount); | ||
| 166 | seq_printf(s, "Time (in us) to S0i3: %lld\n", table.timeentering_s0i3_lastcapture); | ||
| 167 | seq_printf(s, "Time (in us) in S0i3: %lld\n", table.timein_s0i3_lastcapture); | ||
| 168 | |||
| 169 | seq_puts(s, "\n=== Active time (in us) ===\n"); | ||
| 170 | for (idx = 0 ; idx < SOC_SUBSYSTEM_IP_MAX ; idx++) { | ||
| 171 | if (soc15_ip_blk[idx].bit_mask & dev->active_ips) | ||
| 172 | seq_printf(s, "%-8s : %lld\n", soc15_ip_blk[idx].name, | ||
| 173 | table.timecondition_notmet_lastcapture[idx]); | ||
| 174 | } | ||
| 93 | 175 | ||
| 94 | value = ioread32(dev->smu_base + AMD_SMU_FW_VERSION); | ||
| 95 | seq_printf(s, "SMU FW Info: %x\n", value); | ||
| 96 | return 0; | 176 | return 0; |
| 97 | } | 177 | } |
| 98 | DEFINE_SHOW_ATTRIBUTE(smu_fw_info); | 178 | DEFINE_SHOW_ATTRIBUTE(smu_fw_info); |
| 99 | 179 | ||
| 180 | static int s0ix_stats_show(struct seq_file *s, void *unused) | ||
| 181 | { | ||
| 182 | struct amd_pmc_dev *dev = s->private; | ||
| 183 | u64 entry_time, exit_time, residency; | ||
| 184 | |||
| 185 | entry_time = ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_H_OFFSET); | ||
| 186 | entry_time = entry_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_L_OFFSET); | ||
| 187 | |||
| 188 | exit_time = ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_H_OFFSET); | ||
| 189 | exit_time = exit_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_L_OFFSET); | ||
| 190 | |||
| 191 | /* It's in 48MHz. We need to convert it */ | ||
| 192 | residency = exit_time - entry_time; | ||
| 193 | do_div(residency, 48); | ||
| 194 | |||
| 195 | seq_puts(s, "=== S0ix statistics ===\n"); | ||
| 196 | seq_printf(s, "S0ix Entry Time: %lld\n", entry_time); | ||
| 197 | seq_printf(s, "S0ix Exit Time: %lld\n", exit_time); | ||
| 198 | seq_printf(s, "Residency Time: %lld\n", residency); | ||
| 199 | |||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | DEFINE_SHOW_ATTRIBUTE(s0ix_stats); | ||
| 203 | |||
| 100 | static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev) | 204 | static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev) |
| 101 | { | 205 | { |
| 102 | debugfs_remove_recursive(dev->dbgfs_dir); | 206 | debugfs_remove_recursive(dev->dbgfs_dir); |
| @@ -107,6 +211,8 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev) · 4 unmodified lines | |||
| 107 | dev->dbgfs_dir = debugfs_create_dir("amd_pmc", NULL); | 211 | dev->dbgfs_dir = debugfs_create_dir("amd_pmc", NULL); |
| 108 | debugfs_create_file("smu_fw_info", 0644, dev->dbgfs_dir, dev, | 212 | debugfs_create_file("smu_fw_info", 0644, dev->dbgfs_dir, dev, |
| 109 | &smu_fw_info_fops); | 213 | &smu_fw_info_fops); |
| 214 | debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev, | ||
| 215 | &s0ix_stats_fops); | ||
| 110 | } | 216 | } |
| 111 | #else | 217 | #else |
| 112 | static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev) | 218 | static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev) |
| @@ -118,6 +224,32 @@ static inline void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev) · 5 unmodified lines | |||
| 118 | } | 224 | } |
| 119 | #endif /* CONFIG_DEBUG_FS */ | 225 | #endif /* CONFIG_DEBUG_FS */ |
| 120 | 226 | ||
| 227 | static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev) | ||
| 228 | { | ||
| 229 | u32 phys_addr_low, phys_addr_hi; | ||
| 230 | u64 smu_phys_addr; | ||
| 231 | |||
| 232 | if (dev->cpu_id == AMD_CPU_ID_PCO) | ||
| 233 | return -EINVAL; | ||
| 234 | |||
| 235 | /* Get Active devices list from SMU */ | ||
| 236 | amd_pmc_send_cmd(dev, 0, &dev->active_ips, SMU_MSG_GET_SUP_CONSTRAINTS, 1); | ||
| 237 | |||
| 238 | /* Get dram address */ | ||
| 239 | amd_pmc_send_cmd(dev, 0, &phys_addr_low, SMU_MSG_LOG_GETDRAM_ADDR_LO, 1); | ||
| 240 | amd_pmc_send_cmd(dev, 0, &phys_addr_hi, SMU_MSG_LOG_GETDRAM_ADDR_HI, 1); | ||
| 241 | smu_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low); | ||
| 242 | |||
| 243 | dev->smu_virt_addr = devm_ioremap(dev->dev, smu_phys_addr, sizeof(struct smu_metrics)); | ||
| 244 | if (!dev->smu_virt_addr) | ||
| 245 | return -ENOMEM; | ||
| 246 | |||
| 247 | /* Start the logging */ | ||
| 248 | amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, 0); | ||
| 249 | |||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 121 | static void amd_pmc_dump_registers(struct amd_pmc_dev *dev) | 253 | static void amd_pmc_dump_registers(struct amd_pmc_dev *dev) |
| 122 | { | 254 | { |
| 123 | u32 value; | 255 | u32 value; |
| @@ -132,19 +264,19 @@ static void amd_pmc_dump_registers(struct amd_pmc_dev *dev) · 8 unmodified lines | |||
| 132 | dev_dbg(dev->dev, "AMD_PMC_REGISTER_MESSAGE:%x\n", value); | 264 | dev_dbg(dev->dev, "AMD_PMC_REGISTER_MESSAGE:%x\n", value); |
| 133 | } | 265 | } |
| 134 | 266 | ||
| 135 | static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set) | 267 | static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg, bool ret) |
| 136 | { | 268 | { |
| 137 | int rc; | 269 | int rc; |
| 138 | u8 msg; | ||
| 139 | u32 val; | 270 | u32 val; |
| 140 | 271 | ||
| 272 | mutex_lock(&dev->lock); | ||
| 141 | /* Wait until we get a valid response */ | 273 | /* Wait until we get a valid response */ |
| 142 | rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE, | 274 | rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE, |
| 143 | val, val > 0, PMC_MSG_DELAY_MIN_US, | 275 | val, val != 0, PMC_MSG_DELAY_MIN_US, |
| 144 | PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); | 276 | PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); |
| 145 | if (rc) { | 277 | if (rc) { |
| 146 | dev_err(dev->dev, "failed to talk to SMU\n"); | 278 | dev_err(dev->dev, "failed to talk to SMU\n"); |
| 147 | return rc; | 279 | goto out_unlock; |
| 148 | } | 280 | } |
| 149 | 281 | ||
| 150 | /* Write zero to response register */ | 282 | /* Write zero to response register */ |
| @@ -154,34 +286,91 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set) · 3 unmodified lines | |||
| 154 | amd_pmc_reg_write(dev, AMD_PMC_REGISTER_ARGUMENT, set); | 286 | amd_pmc_reg_write(dev, AMD_PMC_REGISTER_ARGUMENT, set); |
| 155 | 287 | ||
| 156 | /* Write message ID to message ID register */ | 288 | /* Write message ID to message ID register */ |
| 157 | msg = (dev->cpu_id == AMD_CPU_ID_RN) ? MSG_OS_HINT_RN : MSG_OS_HINT_PCO; | ||
| 158 | amd_pmc_reg_write(dev, AMD_PMC_REGISTER_MESSAGE, msg); | 289 | amd_pmc_reg_write(dev, AMD_PMC_REGISTER_MESSAGE, msg); |
| 159 | return 0; | 290 | |
| 291 | /* Wait until we get a valid response */ | ||
| 292 | rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE, | ||
| 293 | val, val != 0, PMC_MSG_DELAY_MIN_US, | ||
| 294 | PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); | ||
| 295 | if (rc) { | ||
| 296 | dev_err(dev->dev, "SMU response timed out\n"); | ||
| 297 | goto out_unlock; | ||
| 298 | } | ||
| 299 | |||
| 300 | switch (val) { | ||
| 301 | case AMD_PMC_RESULT_OK: | ||
| 302 | if (ret) { | ||
| 303 | /* PMFW may take longer time to return back the data */ | ||
| 304 | usleep_range(DELAY_MIN_US, 10 * DELAY_MAX_US); | ||
| 305 | *data = amd_pmc_reg_read(dev, AMD_PMC_REGISTER_ARGUMENT); | ||
| 306 | } | ||
| 307 | break; | ||
| 308 | case AMD_PMC_RESULT_CMD_REJECT_BUSY: | ||
| 309 | dev_err(dev->dev, "SMU not ready. err: 0x%x\n", val); | ||
| 310 | rc = -EBUSY; | ||
| 311 | goto out_unlock; | ||
| 312 | case AMD_PMC_RESULT_CMD_UNKNOWN: | ||
| 313 | dev_err(dev->dev, "SMU cmd unknown. err: 0x%x\n", val); | ||
| 314 | rc = -EINVAL; | ||
| 315 | goto out_unlock; | ||
| 316 | case AMD_PMC_RESULT_CMD_REJECT_PREREQ: | ||
| 317 | case AMD_PMC_RESULT_FAILED: | ||
| 318 | default: | ||
| 319 | dev_err(dev->dev, "SMU cmd failed. err: 0x%x\n", val); | ||
| 320 | rc = -EIO; | ||
| 321 | goto out_unlock; | ||
| 322 | } | ||
| 323 | |||
| 324 | out_unlock: | ||
| 325 | mutex_unlock(&dev->lock); | ||
| 326 | amd_pmc_dump_registers(dev); | ||
| 327 | return rc; | ||
| 328 | } | ||
| 329 | |||
| 330 | static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev) | ||
| 331 | { | ||
| 332 | switch (dev->cpu_id) { | ||
| 333 | case AMD_CPU_ID_PCO: | ||
| 334 | return MSG_OS_HINT_PCO; | ||
| 335 | case AMD_CPU_ID_RN: | ||
| 336 | case AMD_CPU_ID_YC: | ||
| 337 | return MSG_OS_HINT_RN; | ||
| 338 | } | ||
| 339 | return -EINVAL; | ||
| 160 | } | 340 | } |
| 161 | 341 | ||
| 162 | static int __maybe_unused amd_pmc_suspend(struct device *dev) | 342 | static int __maybe_unused amd_pmc_suspend(struct device *dev) |
| 163 | { | 343 | { |
| 164 | struct amd_pmc_dev *pdev = dev_get_drvdata(dev); | 344 | struct amd_pmc_dev *pdev = dev_get_drvdata(dev); |
| 165 | int rc; | 345 | int rc; |
| 346 | u8 msg; | ||
| 347 | |||
| 348 | /* Reset and Start SMU logging - to monitor the s0i3 stats */ | ||
| 349 | amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_RESET, 0); | ||
| 350 | amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_START, 0); | ||
| 166 | 351 | ||
| 167 | rc = amd_pmc_send_cmd(pdev, 1); | 352 | msg = amd_pmc_get_os_hint(pdev); |
| 353 | rc = amd_pmc_send_cmd(pdev, 1, NULL, msg, 0); | ||
| 168 | if (rc) | 354 | if (rc) |
| 169 | dev_err(pdev->dev, "suspend failed\n"); | 355 | dev_err(pdev->dev, "suspend failed\n"); |
| 170 | 356 | ||
| 171 | amd_pmc_dump_registers(pdev); | 357 | return rc; |
| 172 | return 0; | ||
| 173 | } | 358 | } |
| 174 | 359 | ||
| 175 | static int __maybe_unused amd_pmc_resume(struct device *dev) | 360 | static int __maybe_unused amd_pmc_resume(struct device *dev) |
| 176 | { | 361 | { |
| 177 | struct amd_pmc_dev *pdev = dev_get_drvdata(dev); | 362 | struct amd_pmc_dev *pdev = dev_get_drvdata(dev); |
| 178 | int rc; | 363 | int rc; |
| 364 | u8 msg; | ||
| 365 | |||
| 366 | /* Let SMU know that we are looking for stats */ | ||
| 367 | amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0); | ||
| 179 | 368 | ||
| 180 | rc = amd_pmc_send_cmd(pdev, 0); | 369 | msg = amd_pmc_get_os_hint(pdev); |
| 370 | rc = amd_pmc_send_cmd(pdev, 0, NULL, msg, 0); | ||
| 181 | if (rc) | 371 | if (rc) |
| 182 | dev_err(pdev->dev, "resume failed\n"); | 372 | dev_err(pdev->dev, "resume failed\n"); |
| 183 | 373 | ||
| 184 | amd_pmc_dump_registers(pdev); | ||
| 185 | return 0; | 374 | return 0; |
| 186 | } | 375 | } |
| 187 | 376 | ||
| @@ -190,6 +379,7 @@ static const struct dev_pm_ops amd_pmc_pm_ops = { · 2 unmodified lines | |||
| 190 | }; | 379 | }; |
| 191 | 380 | ||
| 192 | static const struct pci_device_id pmc_pci_ids[] = { | 381 | static const struct pci_device_id pmc_pci_ids[] = { |
| 382 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_YC) }, | ||
| 193 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_CZN) }, | 383 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_CZN) }, |
| 194 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RN) }, | 384 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RN) }, |
| 195 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) }, | 385 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) }, |
| @@ -201,9 +391,8 @@ static int amd_pmc_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 201 | { | 391 | { |
| 202 | struct amd_pmc_dev *dev = &pmc; | 392 | struct amd_pmc_dev *dev = &pmc; |
| 203 | struct pci_dev *rdev; | 393 | struct pci_dev *rdev; |
| 204 | u32 base_addr_lo; | 394 | u32 base_addr_lo, base_addr_hi; |
| 205 | u32 base_addr_hi; | 395 | u64 base_addr, fch_phys_addr; |
| 206 | u64 base_addr; | ||
| 207 | int err; | 396 | int err; |
| 208 | u32 val; | 397 | u32 val; |
| 209 | 398 | ||
| @@ -248,16 +437,25 @@ static int amd_pmc_probe(struct platform_device *pdev) · 38 unmodified lines | |||
| 248 | pci_dev_put(rdev); | 437 | pci_dev_put(rdev); |
| 249 | base_addr = ((u64)base_addr_hi << 32 | base_addr_lo); | 438 | base_addr = ((u64)base_addr_hi << 32 | base_addr_lo); |
| 250 | 439 | ||
| 251 | dev->smu_base = devm_ioremap(dev->dev, base_addr, AMD_PMC_MAPPING_SIZE); | ||
| 252 | if (!dev->smu_base) | ||
| 253 | return -ENOMEM; | ||
| 254 | |||
| 255 | dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMC_BASE_ADDR_OFFSET, | 440 | dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMC_BASE_ADDR_OFFSET, |
| 256 | AMD_PMC_MAPPING_SIZE); | 441 | AMD_PMC_MAPPING_SIZE); |
| 257 | if (!dev->regbase) | 442 | if (!dev->regbase) |
| 258 | return -ENOMEM; | 443 | return -ENOMEM; |
| 259 | 444 | ||
| 260 | amd_pmc_dump_registers(dev); | 445 | mutex_init(&dev->lock); |
| 446 | |||
| 447 | /* Use FCH registers to get the S0ix stats */ | ||
| 448 | base_addr_lo = FCH_BASE_PHY_ADDR_LOW; | ||
| 449 | base_addr_hi = FCH_BASE_PHY_ADDR_HIGH; | ||
| 450 | fch_phys_addr = ((u64)base_addr_hi << 32 | base_addr_lo); | ||
| 451 | dev->fch_virt_addr = devm_ioremap(dev->dev, fch_phys_addr, FCH_SSC_MAPPING_SIZE); | ||
| 452 | if (!dev->fch_virt_addr) | ||
| 453 | return -ENOMEM; | ||
| 454 | |||
| 455 | /* Use SMU to get the s0i3 debug stats */ | ||
| 456 | err = amd_pmc_setup_smu_logging(dev); | ||
| 457 | if (err) | ||
| 458 | dev_err(dev->dev, "SMU debugging info not supported on this platform\n"); | ||
| 261 | 459 | ||
| 262 | platform_set_drvdata(pdev, dev); | 460 | platform_set_drvdata(pdev, dev); |
| 263 | amd_pmc_dbgfs_register(dev); | 461 | amd_pmc_dbgfs_register(dev); |
| @@ -269,11 +467,14 @@ static int amd_pmc_remove(struct platform_device *pdev) · 5 unmodified lines | |||
| 269 | struct amd_pmc_dev *dev = platform_get_drvdata(pdev); | 467 | struct amd_pmc_dev *dev = platform_get_drvdata(pdev); |
| 270 | 468 | ||
| 271 | amd_pmc_dbgfs_unregister(dev); | 469 | amd_pmc_dbgfs_unregister(dev); |
| 470 | mutex_destroy(&dev->lock); | ||
| 272 | return 0; | 471 | return 0; |
| 273 | } | 472 | } |
| 274 | 473 | ||
| 275 | static const struct acpi_device_id amd_pmc_acpi_ids[] = { | 474 | static const struct acpi_device_id amd_pmc_acpi_ids[] = { |
| 276 | {"AMDI0005", 0}, | 475 | {"AMDI0005", 0}, |
| 476 | {"AMDI0006", 0}, | ||
| 477 | {"AMDI0007", 0}, | ||
| 277 | {"AMD0004", 0}, | 478 | {"AMD0004", 0}, |
| 278 | { } | 479 | { } |
| 279 | }; | 480 | }; |
| @@ -141,6 +141,7 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev) · 140 unmodified lines | |||
| 141 | 141 | ||
| 142 | static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = { | 142 | static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = { |
| 143 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"), | 143 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"), |
| 144 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE V2"), | ||
| 144 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 GAMING X V2"), | 145 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 GAMING X V2"), |
| 145 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"), | 146 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"), |
| 146 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M DS3H"), | 147 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M DS3H"), |
| @@ -25,6 +25,7 @@ static const struct acpi_device_id intel_hid_ids[] = { · 24 unmodified lines | |||
| 25 | {"INT33D5", 0}, | 25 | {"INT33D5", 0}, |
| 26 | {"INTC1051", 0}, | 26 | {"INTC1051", 0}, |
| 27 | {"INTC1054", 0}, | 27 | {"INTC1054", 0}, |
| 28 | {"INTC1070", 0}, | ||
| 28 | {"", 0}, | 29 | {"", 0}, |
| 29 | }; | 30 | }; |
| 30 | MODULE_DEVICE_TABLE(acpi, intel_hid_ids); | 31 | MODULE_DEVICE_TABLE(acpi, intel_hid_ids); |
| @@ -571,6 +571,11 @@ static ssize_t current_value_store(struct kobject *kobj, · 570 unmodified lines | |||
| 571 | else | 571 | else |
| 572 | ret = tlmi_save_bios_settings(""); | 572 | ret = tlmi_save_bios_settings(""); |
| 573 | 573 | ||
| 574 | if (!ret && !tlmi_priv.pending_changes) { | ||
| 575 | tlmi_priv.pending_changes = true; | ||
| 576 | /* let userland know it may need to check reboot pending again */ | ||
| 577 | kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE); | ||
| 578 | } | ||
| 574 | out: | 579 | out: |
| 575 | kfree(auth_str); | 580 | kfree(auth_str); |
| 576 | kfree(set_str); | 581 | kfree(set_str); |
| @@ -647,6 +652,14 @@ static struct kobj_type tlmi_pwd_setting_ktype = { · 70 unmodified lines | |||
| 647 | .sysfs_ops = &tlmi_kobj_sysfs_ops, | 652 | .sysfs_ops = &tlmi_kobj_sysfs_ops, |
| 648 | }; | 653 | }; |
| 649 | 654 | ||
| 655 | static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr, | ||
| 656 | char *buf) | ||
| 657 | { | ||
| 658 | return sprintf(buf, "%d\n", tlmi_priv.pending_changes); | ||
| 659 | } | ||
| 660 | |||
| 661 | static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot); | ||
| 662 | |||
| 650 | /* ---- Initialisation --------------------------------------------------------- */ | 663 | /* ---- Initialisation --------------------------------------------------------- */ |
| 651 | static void tlmi_release_attr(void) | 664 | static void tlmi_release_attr(void) |
| 652 | { | 665 | { |
| @@ -659,6 +672,7 @@ static void tlmi_release_attr(void) · 6 unmodified lines | |||
| 659 | kobject_put(&tlmi_priv.setting[i]->kobj); | 672 | kobject_put(&tlmi_priv.setting[i]->kobj); |
| 660 | } | 673 | } |
| 661 | } | 674 | } |
| 675 | sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); | ||
| 662 | kset_unregister(tlmi_priv.attribute_kset); | 676 | kset_unregister(tlmi_priv.attribute_kset); |
| 663 | 677 | ||
| 664 | /* Authentication structures */ | 678 | /* Authentication structures */ |
| @@ -709,8 +723,8 @@ static int tlmi_sysfs_init(void) · 44 unmodified lines | |||
| 709 | 723 | ||
| 710 | /* Build attribute */ | 724 | /* Build attribute */ |
| 711 | tlmi_priv.setting[i]->kobj.kset = tlmi_priv.attribute_kset; | 725 | tlmi_priv.setting[i]->kobj.kset = tlmi_priv.attribute_kset; |
| 712 | ret = kobject_init_and_add(&tlmi_priv.setting[i]->kobj, &tlmi_attr_setting_ktype, | 726 | ret = kobject_add(&tlmi_priv.setting[i]->kobj, NULL, |
| 713 | NULL, "%s", tlmi_priv.setting[i]->display_name); | 727 | "%s", tlmi_priv.setting[i]->display_name); |
| 714 | if (ret) | 728 | if (ret) |
| 715 | goto fail_create_attr; | 729 | goto fail_create_attr; |
| 716 | 730 | ||
| @@ -719,6 +733,10 @@ static int tlmi_sysfs_init(void) · 2 unmodified lines | |||
| 719 | goto fail_create_attr; | 733 | goto fail_create_attr; |
| 720 | } | 734 | } |
| 721 | 735 | ||
| 736 | ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); | ||
| 737 | if (ret) | ||
| 738 | goto fail_create_attr; | ||
| 739 | |||
| 722 | /* Create authentication entries */ | 740 | /* Create authentication entries */ |
| 723 | tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL, | 741 | tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL, |
| 724 | &tlmi_priv.class_dev->kobj); | 742 | &tlmi_priv.class_dev->kobj); |
| @@ -727,8 +745,7 @@ static int tlmi_sysfs_init(void) · 2 unmodified lines | |||
| 727 | goto fail_create_attr; | 745 | goto fail_create_attr; |
| 728 | } | 746 | } |
| 729 | tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset; | 747 | tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset; |
| 730 | ret = kobject_init_and_add(&tlmi_priv.pwd_admin->kobj, &tlmi_pwd_setting_ktype, | 748 | ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin"); |
| 731 | NULL, "%s", "Admin"); | ||
| 732 | if (ret) | 749 | if (ret) |
| 733 | goto fail_create_attr; | 750 | goto fail_create_attr; |
| 734 | 751 | ||
| @@ -737,8 +754,7 @@ static int tlmi_sysfs_init(void) · 2 unmodified lines | |||
| 737 | goto fail_create_attr; | 754 | goto fail_create_attr; |
| 738 | 755 | ||
| 739 | tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset; | 756 | tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset; |
| 740 | ret = kobject_init_and_add(&tlmi_priv.pwd_power->kobj, &tlmi_pwd_setting_ktype, | 757 | ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "System"); |
| 741 | NULL, "%s", "System"); | ||
| 742 | if (ret) | 758 | if (ret) |
| 743 | goto fail_create_attr; | 759 | goto fail_create_attr; |
| 744 | 760 | ||
| @@ -818,6 +834,7 @@ static int tlmi_analyze(void) · 73 unmodified lines | |||
| 818 | pr_info("Error retrieving possible values for %d : %s\n", | 834 | pr_info("Error retrieving possible values for %d : %s\n", |
| 819 | i, setting->display_name); | 835 | i, setting->display_name); |
| 820 | } | 836 | } |
| 837 | kobject_init(&setting->kobj, &tlmi_attr_setting_ktype); | ||
| 821 | tlmi_priv.setting[i] = setting; | 838 | tlmi_priv.setting[i] = setting; |
| 822 | tlmi_priv.settings_count++; | 839 | tlmi_priv.settings_count++; |
| 823 | kfree(item); | 840 | kfree(item); |
| @@ -844,10 +861,12 @@ static int tlmi_analyze(void) · 20 unmodified lines | |||
| 844 | if (pwdcfg.password_state & TLMI_PAP_PWD) | 861 | if (pwdcfg.password_state & TLMI_PAP_PWD) |
| 845 | tlmi_priv.pwd_admin->valid = true; | 862 | tlmi_priv.pwd_admin->valid = true; |
| 846 | 863 | ||
| 864 | kobject_init(&tlmi_priv.pwd_admin->kobj, &tlmi_pwd_setting_ktype); | ||
| 865 | |||
| 847 | tlmi_priv.pwd_power = kzalloc(sizeof(struct tlmi_pwd_setting), GFP_KERNEL); | 866 | tlmi_priv.pwd_power = kzalloc(sizeof(struct tlmi_pwd_setting), GFP_KERNEL); |
| 848 | if (!tlmi_priv.pwd_power) { | 867 | if (!tlmi_priv.pwd_power) { |
| 849 | ret = -ENOMEM; | 868 | ret = -ENOMEM; |
| 850 | goto fail_clear_attr; | 869 | goto fail_free_pwd_admin; |
| 851 | } | 870 | } |
| 852 | strscpy(tlmi_priv.pwd_power->kbdlang, "us", TLMI_LANG_MAXLEN); | 871 | strscpy(tlmi_priv.pwd_power->kbdlang, "us", TLMI_LANG_MAXLEN); |
| 853 | tlmi_priv.pwd_power->encoding = TLMI_ENCODING_ASCII; | 872 | tlmi_priv.pwd_power->encoding = TLMI_ENCODING_ASCII; |
| @@ -859,11 +878,19 @@ static int tlmi_analyze(void) · 5 unmodified lines | |||
| 859 | if (pwdcfg.password_state & TLMI_POP_PWD) | 878 | if (pwdcfg.password_state & TLMI_POP_PWD) |
| 860 | tlmi_priv.pwd_power->valid = true; | 879 | tlmi_priv.pwd_power->valid = true; |
| 861 | 880 | ||
| 881 | kobject_init(&tlmi_priv.pwd_power->kobj, &tlmi_pwd_setting_ktype); | ||
| 882 | |||
| 862 | return 0; | 883 | return 0; |
| 863 | 884 | ||
| 885 | fail_free_pwd_admin: | ||
| 886 | kfree(tlmi_priv.pwd_admin); | ||
| 864 | fail_clear_attr: | 887 | fail_clear_attr: |
| 865 | for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) | 888 | for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) { |
| 866 | kfree(tlmi_priv.setting[i]); | 889 | if (tlmi_priv.setting[i]) { |
| 890 | kfree(tlmi_priv.setting[i]->possible_values); | ||
| 891 | kfree(tlmi_priv.setting[i]); | ||
| 892 | } | ||
| 893 | } | ||
| 867 | return ret; | 894 | return ret; |
| 868 | } | 895 | } |
| 869 | 896 | ||
| @@ -60,6 +60,7 @@ struct think_lmi { · 59 unmodified lines | |||
| 60 | bool can_get_bios_selections; | 60 | bool can_get_bios_selections; |
| 61 | bool can_set_bios_password; | 61 | bool can_set_bios_password; |
| 62 | bool can_get_password_settings; | 62 | bool can_get_password_settings; |
| 63 | bool pending_changes; | ||
| 63 | 64 | ||
| 64 | struct tlmi_attr_setting *setting[TLMI_SETTINGS_COUNT]; | 65 | struct tlmi_attr_setting *setting[TLMI_SETTINGS_COUNT]; |
| 65 | struct device *class_dev; | 66 | struct device *class_dev; |
| @@ -78,7 +78,7 @@ static int wl_add(struct acpi_device *device) · 77 unmodified lines | |||
| 78 | 78 | ||
| 79 | err = wireless_input_setup(); | 79 | err = wireless_input_setup(); |
| 80 | if (err) | 80 | if (err) |
| 81 | pr_err("Failed to setup hp wireless hotkeys\n"); | 81 | pr_err("Failed to setup wireless hotkeys\n"); |
| 82 | 82 | ||
| 83 | return err; | 83 | return err; |
| 84 | } | 84 | } |
| @@ -294,9 +294,9 @@ static bool check_temp_flag_mismatch(struct regulator_dev *rdev, int severity, · 293 unmodified lines | |||
| 294 | struct bd957x_regulator_data *r) | 294 | struct bd957x_regulator_data *r) |
| 295 | { | 295 | { |
| 296 | if ((severity == REGULATOR_SEVERITY_ERR && | 296 | if ((severity == REGULATOR_SEVERITY_ERR && |
| 297 | r->ovd_notif != REGULATOR_EVENT_OVER_TEMP) || | 297 | r->temp_notif != REGULATOR_EVENT_OVER_TEMP) || |
| 298 | (severity == REGULATOR_SEVERITY_WARN && | 298 | (severity == REGULATOR_SEVERITY_WARN && |
| 299 | r->ovd_notif != REGULATOR_EVENT_OVER_TEMP_WARN)) { | 299 | r->temp_notif != REGULATOR_EVENT_OVER_TEMP_WARN)) { |
| 300 | dev_warn(rdev_get_dev(rdev), | 300 | dev_warn(rdev_get_dev(rdev), |
| 301 | "Can't support both thermal WARN and ERR\n"); | 301 | "Can't support both thermal WARN and ERR\n"); |
| 302 | if (severity == REGULATOR_SEVERITY_WARN) | 302 | if (severity == REGULATOR_SEVERITY_WARN) |
| @@ -366,9 +366,8 @@ static struct hi6421_regulator_info · 365 unmodified lines | |||
| 366 | 366 | ||
| 367 | static int hi6421_regulator_enable(struct regulator_dev *rdev) | 367 | static int hi6421_regulator_enable(struct regulator_dev *rdev) |
| 368 | { | 368 | { |
| 369 | struct hi6421_regulator_pdata *pdata; | 369 | struct hi6421_regulator_pdata *pdata = rdev_get_drvdata(rdev); |
| 370 | 370 | ||
| 371 | pdata = dev_get_drvdata(rdev->dev.parent); | ||
| 372 | /* hi6421 spec requires regulator enablement must be serialized: | 371 | /* hi6421 spec requires regulator enablement must be serialized: |
| 373 | * - Because when BUCK, LDO switching from off to on, it will have | 372 | * - Because when BUCK, LDO switching from off to on, it will have |
| 374 | * a huge instantaneous current; so you can not turn on two or | 373 | * a huge instantaneous current; so you can not turn on two or |
| @@ -385,9 +384,10 @@ static int hi6421_regulator_enable(struct regulator_dev *rdev) · 10 unmodified lines | |||
| 385 | 384 | ||
| 386 | static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) | 385 | static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) |
| 387 | { | 386 | { |
| 388 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | 387 | struct hi6421_regulator_info *info; |
| 389 | unsigned int reg_val; | 388 | unsigned int reg_val; |
| 390 | 389 | ||
| 390 | info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | ||
| 391 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); | 391 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); |
| 392 | if (reg_val & info->mode_mask) | 392 | if (reg_val & info->mode_mask) |
| 393 | return REGULATOR_MODE_IDLE; | 393 | return REGULATOR_MODE_IDLE; |
| @@ -397,9 +397,10 @@ static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) · 3 unmodified lines | |||
| 397 | 397 | ||
| 398 | static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) | 398 | static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) |
| 399 | { | 399 | { |
| 400 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | 400 | struct hi6421_regulator_info *info; |
| 401 | unsigned int reg_val; | 401 | unsigned int reg_val; |
| 402 | 402 | ||
| 403 | info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | ||
| 403 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); | 404 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); |
| 404 | if (reg_val & info->mode_mask) | 405 | if (reg_val & info->mode_mask) |
| 405 | return REGULATOR_MODE_STANDBY; | 406 | return REGULATOR_MODE_STANDBY; |
| @@ -410,9 +411,10 @@ static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) · 4 unmodified lines | |||
| 410 | static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, | 411 | static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, |
| 411 | unsigned int mode) | 412 | unsigned int mode) |
| 412 | { | 413 | { |
| 413 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | 414 | struct hi6421_regulator_info *info; |
| 414 | unsigned int new_mode; | 415 | unsigned int new_mode; |
| 415 | 416 | ||
| 417 | info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | ||
| 416 | switch (mode) { | 418 | switch (mode) { |
| 417 | case REGULATOR_MODE_NORMAL: | 419 | case REGULATOR_MODE_NORMAL: |
| 418 | new_mode = 0; | 420 | new_mode = 0; |
| @@ -434,9 +436,10 @@ static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, · 15 unmodified lines | |||
| 434 | static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev, | 436 | static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev, |
| 435 | unsigned int mode) | 437 | unsigned int mode) |
| 436 | { | 438 | { |
| 437 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | 439 | struct hi6421_regulator_info *info; |
| 438 | unsigned int new_mode; | 440 | unsigned int new_mode; |
| 439 | 441 | ||
| 442 | info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | ||
| 440 | switch (mode) { | 443 | switch (mode) { |
| 441 | case REGULATOR_MODE_NORMAL: | 444 | case REGULATOR_MODE_NORMAL: |
| 442 | new_mode = 0; | 445 | new_mode = 0; |
| @@ -459,7 +462,9 @@ static unsigned int · 16 unmodified lines | |||
| 459 | hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, | 462 | hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, |
| 460 | int input_uV, int output_uV, int load_uA) | 463 | int input_uV, int output_uV, int load_uA) |
| 461 | { | 464 | { |
| 462 | struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | 465 | struct hi6421_regulator_info *info; |
| 466 | |||
| 467 | info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | ||
| 463 | 468 | ||
| 464 | if (load_uA > info->eco_microamp) | 469 | if (load_uA > info->eco_microamp) |
| 465 | return REGULATOR_MODE_NORMAL; | 470 | return REGULATOR_MODE_NORMAL; |
| @@ -543,14 +548,13 @@ static int hi6421_regulator_probe(struct platform_device *pdev) · 77 unmodified lines | |||
| 543 | if (!pdata) | 548 | if (!pdata) |
| 544 | return -ENOMEM; | 549 | return -ENOMEM; |
| 545 | mutex_init(&pdata->lock); | 550 | mutex_init(&pdata->lock); |
| 546 | platform_set_drvdata(pdev, pdata); | ||
| 547 | 551 | ||
| 548 | for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { | 552 | for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { |
| 549 | /* assign per-regulator data */ | 553 | /* assign per-regulator data */ |
| 550 | info = &hi6421_regulator_info[i]; | 554 | info = &hi6421_regulator_info[i]; |
| 551 | 555 | ||
| 552 | config.dev = pdev->dev.parent; | 556 | config.dev = pdev->dev.parent; |
| 553 | config.driver_data = info; | 557 | config.driver_data = pdata; |
| 554 | config.regmap = pmic->regmap; | 558 | config.regmap = pmic->regmap; |
| 555 | 559 | ||
| 556 | rdev = devm_regulator_register(&pdev->dev, &info->desc, | 560 | rdev = devm_regulator_register(&pdev->dev, &info->desc, |
| @@ -98,10 +98,9 @@ static const unsigned int ldo34_voltages[] = { · 97 unmodified lines | |||
| 98 | 98 | ||
| 99 | static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev) | 99 | static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev) |
| 100 | { | 100 | { |
| 101 | struct hi6421_spmi_reg_priv *priv; | 101 | struct hi6421_spmi_reg_priv *priv = rdev_get_drvdata(rdev); |
| 102 | int ret; | 102 | int ret; |
| 103 | 103 | ||
| 104 | priv = dev_get_drvdata(rdev->dev.parent); | ||
| 105 | /* cannot enable more than one regulator at one time */ | 104 | /* cannot enable more than one regulator at one time */ |
| 106 | mutex_lock(&priv->enable_mutex); | 105 | mutex_lock(&priv->enable_mutex); |
| 107 | 106 | ||
| @@ -119,9 +118,10 @@ static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev) · 11 unmodified lines | |||
| 119 | 118 | ||
| 120 | static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) | 119 | static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) |
| 121 | { | 120 | { |
| 122 | struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); | 121 | struct hi6421_spmi_reg_info *sreg; |
| 123 | unsigned int reg_val; | 122 | unsigned int reg_val; |
| 124 | 123 | ||
| 124 | sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc); | ||
| 125 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); | 125 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); |
| 126 | 126 | ||
| 127 | if (reg_val & sreg->eco_mode_mask) | 127 | if (reg_val & sreg->eco_mode_mask) |
| @@ -133,9 +133,10 @@ static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) · 5 unmodified lines | |||
| 133 | static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, | 133 | static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, |
| 134 | unsigned int mode) | 134 | unsigned int mode) |
| 135 | { | 135 | { |
| 136 | struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); | 136 | struct hi6421_spmi_reg_info *sreg; |
| 137 | unsigned int val; | 137 | unsigned int val; |
| 138 | 138 | ||
| 139 | sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc); | ||
| 139 | switch (mode) { | 140 | switch (mode) { |
| 140 | case REGULATOR_MODE_NORMAL: | 141 | case REGULATOR_MODE_NORMAL: |
| 141 | val = 0; | 142 | val = 0; |
| @@ -159,7 +160,9 @@ hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev, · 17 unmodified lines | |||
| 159 | int input_uV, int output_uV, | 160 | int input_uV, int output_uV, |
| 160 | int load_uA) | 161 | int load_uA) |
| 161 | { | 162 | { |
| 162 | struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); | 163 | struct hi6421_spmi_reg_info *sreg; |
| 164 | |||
| 165 | sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc); | ||
| 163 | 166 | ||
| 164 | if (!sreg->eco_uA || ((unsigned int)load_uA > sreg->eco_uA)) | 167 | if (!sreg->eco_uA || ((unsigned int)load_uA > sreg->eco_uA)) |
| 165 | return REGULATOR_MODE_NORMAL; | 168 | return REGULATOR_MODE_NORMAL; |
| @@ -252,13 +255,12 @@ static int hi6421_spmi_regulator_probe(struct platform_device *pdev) · 86 unmodified lines | |||
| 252 | return -ENOMEM; | 255 | return -ENOMEM; |
| 253 | 256 | ||
| 254 | mutex_init(&priv->enable_mutex); | 257 | mutex_init(&priv->enable_mutex); |
| 255 | platform_set_drvdata(pdev, priv); | ||
| 256 | 258 | ||
| 257 | for (i = 0; i < ARRAY_SIZE(regulator_info); i++) { | 259 | for (i = 0; i < ARRAY_SIZE(regulator_info); i++) { |
| 258 | info = ®ulator_info[i]; | 260 | info = ®ulator_info[i]; |
| 259 | 261 | ||
| 260 | config.dev = pdev->dev.parent; | 262 | config.dev = pdev->dev.parent; |
| 261 | config.driver_data = info; | 263 | config.driver_data = priv; |
| 262 | config.regmap = pmic->regmap; | 264 | config.regmap = pmic->regmap; |
| 263 | 265 | ||
| 264 | rdev = devm_regulator_register(dev, &info->desc, &config); | 266 | rdev = devm_regulator_register(dev, &info->desc, &config); |
| @@ -179,8 +179,7 @@ static int dvfsrc_vcore_regulator_probe(struct platform_device *pdev) · 178 unmodified lines | |||
| 179 | for (i = 0; i < regulator_init_data->size; i++) { | 179 | for (i = 0; i < regulator_init_data->size; i++) { |
| 180 | config.dev = dev->parent; | 180 | config.dev = dev->parent; |
| 181 | config.driver_data = (mt_regulators + i); | 181 | config.driver_data = (mt_regulators + i); |
| 182 | rdev = devm_regulator_register(dev->parent, | 182 | rdev = devm_regulator_register(dev, &(mt_regulators + i)->desc, |
| 183 | &(mt_regulators + i)->desc, | ||
| 184 | &config); | 183 | &config); |
| 185 | if (IS_ERR(rdev)) { | 184 | if (IS_ERR(rdev)) { |
| 186 | dev_err(dev, "failed to register %s\n", | 185 | dev_err(dev, "failed to register %s\n", |
| @@ -37,7 +37,7 @@ · 36 unmodified lines | |||
| 37 | #define RTMV20_WIDTH2_MASK GENMASK(7, 0) | 37 | #define RTMV20_WIDTH2_MASK GENMASK(7, 0) |
| 38 | #define RTMV20_LBPLVL_MASK GENMASK(3, 0) | 38 | #define RTMV20_LBPLVL_MASK GENMASK(3, 0) |
| 39 | #define RTMV20_LBPEN_MASK BIT(7) | 39 | #define RTMV20_LBPEN_MASK BIT(7) |
| 40 | #define RTMV20_STROBEPOL_MASK BIT(1) | 40 | #define RTMV20_STROBEPOL_MASK BIT(0) |
| 41 | #define RTMV20_VSYNPOL_MASK BIT(1) | 41 | #define RTMV20_VSYNPOL_MASK BIT(1) |
| 42 | #define RTMV20_FSINEN_MASK BIT(7) | 42 | #define RTMV20_FSINEN_MASK BIT(7) |
| 43 | #define RTMV20_ESEN_MASK BIT(6) | 43 | #define RTMV20_ESEN_MASK BIT(6) |
| @@ -2642,6 +2642,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) · 2641 unmodified lines | |||
| 2642 | //#endif | 2642 | //#endif |
| 2643 | clear_bit(SCpnt->device->id * 8 + | 2643 | clear_bit(SCpnt->device->id * 8 + |
| 2644 | (u8)(SCpnt->device->lun & 0x7), host->busyluns); | 2644 | (u8)(SCpnt->device->lun & 0x7), host->busyluns); |
| 2645 | fallthrough; | ||
| 2645 | 2646 | ||
| 2646 | /* | 2647 | /* |
| 2647 | * We found the command, and cleared it out. Either | 2648 | * We found the command, and cleared it out. Either |
| @@ -1375,6 +1375,7 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne · 1374 unmodified lines | |||
| 1375 | case IS_COMPLETE: | 1375 | case IS_COMPLETE: |
| 1376 | break; | 1376 | break; |
| 1377 | } | 1377 | } |
| 1378 | break; | ||
| 1378 | 1379 | ||
| 1379 | default: | 1380 | default: |
| 1380 | break; | 1381 | break; |
| @@ -2983,13 +2983,13 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc) · 2982 unmodified lines | |||
| 2983 | } | 2983 | } |
| 2984 | 2984 | ||
| 2985 | /** | 2985 | /** |
| 2986 | * _base_free_irq - free irq | 2986 | * mpt3sas_base_free_irq - free irq |
| 2987 | * @ioc: per adapter object | 2987 | * @ioc: per adapter object |
| 2988 | * | 2988 | * |
| 2989 | * Freeing respective reply_queue from the list. | 2989 | * Freeing respective reply_queue from the list. |
| 2990 | */ | 2990 | */ |
| 2991 | static void | 2991 | void |
| 2992 | _base_free_irq(struct MPT3SAS_ADAPTER *ioc) | 2992 | mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc) |
| 2993 | { | 2993 | { |
| 2994 | struct adapter_reply_queue *reply_q, *next; | 2994 | struct adapter_reply_queue *reply_q, *next; |
| 2995 | 2995 | ||
| @@ -3191,12 +3191,12 @@ _base_check_and_enable_high_iops_queues(struct MPT3SAS_ADAPTER *ioc, · 195 unmodified lines | |||
| 3191 | } | 3191 | } |
| 3192 | 3192 | ||
| 3193 | /** | 3193 | /** |
| 3194 | * _base_disable_msix - disables msix | 3194 | * mpt3sas_base_disable_msix - disables msix |
| 3195 | * @ioc: per adapter object | 3195 | * @ioc: per adapter object |
| 3196 | * | 3196 | * |
| 3197 | */ | 3197 | */ |
| 3198 | static void | 3198 | void |
| 3199 | _base_disable_msix(struct MPT3SAS_ADAPTER *ioc) | 3199 | mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc) |
| 3200 | { | 3200 | { |
| 3201 | if (!ioc->msix_enable) | 3201 | if (!ioc->msix_enable) |
| 3202 | return; | 3202 | return; |
| @@ -3304,8 +3304,8 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) · 101 unmodified lines | |||
| 3304 | for (i = 0; i < ioc->reply_queue_count; i++) { | 3304 | for (i = 0; i < ioc->reply_queue_count; i++) { |
| 3305 | r = _base_request_irq(ioc, i); | 3305 | r = _base_request_irq(ioc, i); |
| 3306 | if (r) { | 3306 | if (r) { |
| 3307 | _base_free_irq(ioc); | 3307 | mpt3sas_base_free_irq(ioc); |
| 3308 | _base_disable_msix(ioc); | 3308 | mpt3sas_base_disable_msix(ioc); |
| 3309 | goto try_ioapic; | 3309 | goto try_ioapic; |
| 3310 | } | 3310 | } |
| 3311 | } | 3311 | } |
| @@ -3342,8 +3342,8 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) · 30 unmodified lines | |||
| 3342 | 3342 | ||
| 3343 | dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); | 3343 | dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); |
| 3344 | 3344 | ||
| 3345 | _base_free_irq(ioc); | 3345 | mpt3sas_base_free_irq(ioc); |
| 3346 | _base_disable_msix(ioc); | 3346 | mpt3sas_base_disable_msix(ioc); |
| 3347 | 3347 | ||
| 3348 | kfree(ioc->replyPostRegisterIndex); | 3348 | kfree(ioc->replyPostRegisterIndex); |
| 3349 | ioc->replyPostRegisterIndex = NULL; | 3349 | ioc->replyPostRegisterIndex = NULL; |
| @@ -7613,14 +7613,14 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) · 4263 unmodified lines | |||
| 7613 | } | 7613 | } |
| 7614 | 7614 | ||
| 7615 | /** | 7615 | /** |
| 7616 | * _base_make_ioc_ready - put controller in READY state | 7616 | * mpt3sas_base_make_ioc_ready - put controller in READY state |
| 7617 | * @ioc: per adapter object | 7617 | * @ioc: per adapter object |
| 7618 | * @type: FORCE_BIG_HAMMER or SOFT_RESET | 7618 | * @type: FORCE_BIG_HAMMER or SOFT_RESET |
| 7619 | * | 7619 | * |
| 7620 | * Return: 0 for success, non-zero for failure. | 7620 | * Return: 0 for success, non-zero for failure. |
| 7621 | */ | 7621 | */ |
| 7622 | static int | 7622 | int |
| 7623 | _base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type) | 7623 | mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type) |
| 7624 | { | 7624 | { |
| 7625 | u32 ioc_state; | 7625 | u32 ioc_state; |
| 7626 | int rc; | 7626 | int rc; |
| @@ -7897,7 +7897,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) · 270 unmodified lines | |||
| 7897 | if (ioc->chip_phys && ioc->chip) { | 7897 | if (ioc->chip_phys && ioc->chip) { |
| 7898 | mpt3sas_base_mask_interrupts(ioc); | 7898 | mpt3sas_base_mask_interrupts(ioc); |
| 7899 | ioc->shost_recovery = 1; | 7899 | ioc->shost_recovery = 1; |
| 7900 | _base_make_ioc_ready(ioc, SOFT_RESET); | 7900 | mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET); |
| 7901 | ioc->shost_recovery = 0; | 7901 | ioc->shost_recovery = 0; |
| 7902 | } | 7902 | } |
| 7903 | 7903 | ||
| @@ -8017,7 +8017,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) · 113 unmodified lines | |||
| 8017 | ioc->build_sg_mpi = &_base_build_sg; | 8017 | ioc->build_sg_mpi = &_base_build_sg; |
| 8018 | ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge; | 8018 | ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge; |
| 8019 | 8019 | ||
| 8020 | r = _base_make_ioc_ready(ioc, SOFT_RESET); | 8020 | r = mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET); |
| 8021 | if (r) | 8021 | if (r) |
| 8022 | goto out_free_resources; | 8022 | goto out_free_resources; |
| 8023 | 8023 | ||
| @@ -8471,7 +8471,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, · 447 unmodified lines | |||
| 8471 | _base_pre_reset_handler(ioc); | 8471 | _base_pre_reset_handler(ioc); |
| 8472 | mpt3sas_wait_for_commands_to_complete(ioc); | 8472 | mpt3sas_wait_for_commands_to_complete(ioc); |
| 8473 | mpt3sas_base_mask_interrupts(ioc); | 8473 | mpt3sas_base_mask_interrupts(ioc); |
| 8474 | r = _base_make_ioc_ready(ioc, type); | 8474 | r = mpt3sas_base_make_ioc_ready(ioc, type); |
| 8475 | if (r) | 8475 | if (r) |
| 8476 | goto out; | 8476 | goto out; |
| 8477 | _base_clear_outstanding_commands(ioc); | 8477 | _base_clear_outstanding_commands(ioc); |
| @@ -1730,6 +1730,10 @@ do { ioc_err(ioc, "In func: %s\n", __func__); \ · 1729 unmodified lines | |||
| 1730 | status, mpi_request, sz); } while (0) | 1730 | status, mpi_request, sz); } while (0) |
| 1731 | 1731 | ||
| 1732 | int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count); | 1732 | int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count); |
| 1733 | int | ||
| 1734 | mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type); | ||
| 1735 | void mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc); | ||
| 1736 | void mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc); | ||
| 1733 | 1737 | ||
| 1734 | /* scsih shared API */ | 1738 | /* scsih shared API */ |
| 1735 | struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, | 1739 | struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, |
| @@ -11295,7 +11295,12 @@ scsih_shutdown(struct pci_dev *pdev) · 11294 unmodified lines | |||
| 11295 | 11295 | ||
| 11296 | _scsih_ir_shutdown(ioc); | 11296 | _scsih_ir_shutdown(ioc); |
| 11297 | _scsih_nvme_shutdown(ioc); | 11297 | _scsih_nvme_shutdown(ioc); |
| 11298 | mpt3sas_base_detach(ioc); | 11298 | mpt3sas_base_mask_interrupts(ioc); |
| 11299 | ioc->shost_recovery = 1; | ||
| 11300 | mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET); | ||
| 11301 | ioc->shost_recovery = 0; | ||
| 11302 | mpt3sas_base_free_irq(ioc); | ||
| 11303 | mpt3sas_base_disable_msix(ioc); | ||
| 11299 | } | 11304 | } |
| 11300 | 11305 | ||
| 11301 | 11306 | ||
| @@ -439,39 +439,10 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj, · 438 unmodified lines | |||
| 439 | struct device *dev = container_of(kobj, struct device, kobj); | 439 | struct device *dev = container_of(kobj, struct device, kobj); |
| 440 | struct iscsi_iface *iface = iscsi_dev_to_iface(dev); | 440 | struct iscsi_iface *iface = iscsi_dev_to_iface(dev); |
| 441 | struct iscsi_transport *t = iface->transport; | 441 | struct iscsi_transport *t = iface->transport; |
| 442 | int param; | 442 | int param = -1; |
| 443 | int param_type; | ||
| 444 | 443 | ||
| 445 | if (attr == &dev_attr_iface_enabled.attr) | 444 | if (attr == &dev_attr_iface_enabled.attr) |
| 446 | param = ISCSI_NET_PARAM_IFACE_ENABLE; | 445 | param = ISCSI_NET_PARAM_IFACE_ENABLE; |
| 447 | else if (attr == &dev_attr_iface_vlan_id.attr) | ||
| 448 | param = ISCSI_NET_PARAM_VLAN_ID; | ||
| 449 | else if (attr == &dev_attr_iface_vlan_priority.attr) | ||
| 450 | param = ISCSI_NET_PARAM_VLAN_PRIORITY; | ||
| 451 | else if (attr == &dev_attr_iface_vlan_enabled.attr) | ||
| 452 | param = ISCSI_NET_PARAM_VLAN_ENABLED; | ||
| 453 | else if (attr == &dev_attr_iface_mtu.attr) | ||
| 454 | param = ISCSI_NET_PARAM_MTU; | ||
| 455 | else if (attr == &dev_attr_iface_port.attr) | ||
| 456 | param = ISCSI_NET_PARAM_PORT; | ||
| 457 | else if (attr == &dev_attr_iface_ipaddress_state.attr) | ||
| 458 | param = ISCSI_NET_PARAM_IPADDR_STATE; | ||
| 459 | else if (attr == &dev_attr_iface_delayed_ack_en.attr) | ||
| 460 | param = ISCSI_NET_PARAM_DELAYED_ACK_EN; | ||
| 461 | else if (attr == &dev_attr_iface_tcp_nagle_disable.attr) | ||
| 462 | param = ISCSI_NET_PARAM_TCP_NAGLE_DISABLE; | ||
| 463 | else if (attr == &dev_attr_iface_tcp_wsf_disable.attr) | ||
| 464 | param = ISCSI_NET_PARAM_TCP_WSF_DISABLE; | ||
| 465 | else if (attr == &dev_attr_iface_tcp_wsf.attr) | ||
| 466 | param = ISCSI_NET_PARAM_TCP_WSF; | ||
| 467 | else if (attr == &dev_attr_iface_tcp_timer_scale.attr) | ||
| 468 | param = ISCSI_NET_PARAM_TCP_TIMER_SCALE; | ||
| 469 | else if (attr == &dev_attr_iface_tcp_timestamp_en.attr) | ||
| 470 | param = ISCSI_NET_PARAM_TCP_TIMESTAMP_EN; | ||
| 471 | else if (attr == &dev_attr_iface_cache_id.attr) | ||
| 472 | param = ISCSI_NET_PARAM_CACHE_ID; | ||
| 473 | else if (attr == &dev_attr_iface_redirect_en.attr) | ||
| 474 | param = ISCSI_NET_PARAM_REDIRECT_EN; | ||
| 475 | else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) | 446 | else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) |
| 476 | param = ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO; | 447 | param = ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO; |
| 477 | else if (attr == &dev_attr_iface_header_digest.attr) | 448 | else if (attr == &dev_attr_iface_header_digest.attr) |
| @@ -508,6 +479,38 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj, · 30 unmodified lines | |||
| 508 | param = ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN; | 479 | param = ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN; |
| 509 | else if (attr == &dev_attr_iface_initiator_name.attr) | 480 | else if (attr == &dev_attr_iface_initiator_name.attr) |
| 510 | param = ISCSI_IFACE_PARAM_INITIATOR_NAME; | 481 | param = ISCSI_IFACE_PARAM_INITIATOR_NAME; |
| 482 | |||
| 483 | if (param != -1) | ||
| 484 | return t->attr_is_visible(ISCSI_IFACE_PARAM, param); | ||
| 485 | |||
| 486 | if (attr == &dev_attr_iface_vlan_id.attr) | ||
| 487 | param = ISCSI_NET_PARAM_VLAN_ID; | ||
| 488 | else if (attr == &dev_attr_iface_vlan_priority.attr) | ||
| 489 | param = ISCSI_NET_PARAM_VLAN_PRIORITY; | ||
| 490 | else if (attr == &dev_attr_iface_vlan_enabled.attr) | ||
| 491 | param = ISCSI_NET_PARAM_VLAN_ENABLED; | ||
| 492 | else if (attr == &dev_attr_iface_mtu.attr) | ||
| 493 | param = ISCSI_NET_PARAM_MTU; | ||
| 494 | else if (attr == &dev_attr_iface_port.attr) | ||
| 495 | param = ISCSI_NET_PARAM_PORT; | ||
| 496 | else if (attr == &dev_attr_iface_ipaddress_state.attr) | ||
| 497 | param = ISCSI_NET_PARAM_IPADDR_STATE; | ||
| 498 | else if (attr == &dev_attr_iface_delayed_ack_en.attr) | ||
| 499 | param = ISCSI_NET_PARAM_DELAYED_ACK_EN; | ||
| 500 | else if (attr == &dev_attr_iface_tcp_nagle_disable.attr) | ||
| 501 | param = ISCSI_NET_PARAM_TCP_NAGLE_DISABLE; | ||
| 502 | else if (attr == &dev_attr_iface_tcp_wsf_disable.attr) | ||
| 503 | param = ISCSI_NET_PARAM_TCP_WSF_DISABLE; | ||
| 504 | else if (attr == &dev_attr_iface_tcp_wsf.attr) | ||
| 505 | param = ISCSI_NET_PARAM_TCP_WSF; | ||
| 506 | else if (attr == &dev_attr_iface_tcp_timer_scale.attr) | ||
| 507 | param = ISCSI_NET_PARAM_TCP_TIMER_SCALE; | ||
| 508 | else if (attr == &dev_attr_iface_tcp_timestamp_en.attr) | ||
| 509 | param = ISCSI_NET_PARAM_TCP_TIMESTAMP_EN; | ||
| 510 | else if (attr == &dev_attr_iface_cache_id.attr) | ||
| 511 | param = ISCSI_NET_PARAM_CACHE_ID; | ||
| 512 | else if (attr == &dev_attr_iface_redirect_en.attr) | ||
| 513 | param = ISCSI_NET_PARAM_REDIRECT_EN; | ||
| 511 | else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) { | 514 | else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) { |
| 512 | if (attr == &dev_attr_ipv4_iface_ipaddress.attr) | 515 | if (attr == &dev_attr_ipv4_iface_ipaddress.attr) |
| 513 | param = ISCSI_NET_PARAM_IPV4_ADDR; | 516 | param = ISCSI_NET_PARAM_IPV4_ADDR; |
| @@ -598,32 +601,7 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj, · 84 unmodified lines | |||
| 598 | return 0; | 601 | return 0; |
| 599 | } | 602 | } |
| 600 | 603 | ||
| 601 | switch (param) { | 604 | return t->attr_is_visible(ISCSI_NET_PARAM, param); |
| 602 | case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO: | ||
| 603 | case ISCSI_IFACE_PARAM_HDRDGST_EN: | ||
| 604 | case ISCSI_IFACE_PARAM_DATADGST_EN: | ||
| 605 | case ISCSI_IFACE_PARAM_IMM_DATA_EN: | ||
| 606 | case ISCSI_IFACE_PARAM_INITIAL_R2T_EN: | ||
| 607 | case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN: | ||
| 608 | case ISCSI_IFACE_PARAM_PDU_INORDER_EN: | ||
| 609 | case ISCSI_IFACE_PARAM_ERL: | ||
| 610 | case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH: | ||
| 611 | case ISCSI_IFACE_PARAM_FIRST_BURST: | ||
| 612 | case ISCSI_IFACE_PARAM_MAX_R2T: | ||
| 613 | case ISCSI_IFACE_PARAM_MAX_BURST: | ||
| 614 | case ISCSI_IFACE_PARAM_CHAP_AUTH_EN: | ||
| 615 | case ISCSI_IFACE_PARAM_BIDI_CHAP_EN: | ||
| 616 | case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL: | ||
| 617 | case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN: | ||
| 618 | case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN: | ||
| 619 | case ISCSI_IFACE_PARAM_INITIATOR_NAME: | ||
| 620 | param_type = ISCSI_IFACE_PARAM; | ||
| 621 | break; | ||
| 622 | default: | ||
| 623 | param_type = ISCSI_NET_PARAM; | ||
| 624 | } | ||
| 625 | |||
| 626 | return t->attr_is_visible(param_type, param); | ||
| 627 | } | 605 | } |
| 628 | 606 | ||
| 629 | static struct attribute *iscsi_iface_attrs[] = { | 607 | static struct attribute *iscsi_iface_attrs[] = { |
| @@ -352,8 +352,6 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) · 351 unmodified lines | |||
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | mr = spi_readl(as, MR); | 354 | mr = spi_readl(as, MR); |
| 355 | if (spi->cs_gpiod) | ||
| 356 | gpiod_set_value(spi->cs_gpiod, 1); | ||
| 357 | } else { | 355 | } else { |
| 358 | u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; | 356 | u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; |
| 359 | int i; | 357 | int i; |
| @@ -369,8 +367,6 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) · 9 unmodified lines | |||
| 369 | 367 | ||
| 370 | mr = spi_readl(as, MR); | 368 | mr = spi_readl(as, MR); |
| 371 | mr = SPI_BFINS(PCS, ~(1 << chip_select), mr); | 369 | mr = SPI_BFINS(PCS, ~(1 << chip_select), mr); |
| 372 | if (spi->cs_gpiod) | ||
| 373 | gpiod_set_value(spi->cs_gpiod, 1); | ||
| 374 | spi_writel(as, MR, mr); | 370 | spi_writel(as, MR, mr); |
| 375 | } | 371 | } |
| 376 | 372 | ||
| @@ -400,8 +396,6 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) · 23 unmodified lines | |||
| 400 | 396 | ||
| 401 | if (!spi->cs_gpiod) | 397 | if (!spi->cs_gpiod) |
| 402 | spi_writel(as, CR, SPI_BIT(LASTXFER)); | 398 | spi_writel(as, CR, SPI_BIT(LASTXFER)); |
| 403 | else | ||
| 404 | gpiod_set_value(spi->cs_gpiod, 0); | ||
| 405 | } | 399 | } |
| 406 | 400 | ||
| 407 | static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock) | 401 | static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock) |
| @@ -1483,7 +1477,8 @@ static int atmel_spi_probe(struct platform_device *pdev) · 1075 unmodified lines | |||
| 1483 | master->bus_num = pdev->id; | 1477 | master->bus_num = pdev->id; |
| 1484 | master->num_chipselect = 4; | 1478 | master->num_chipselect = 4; |
| 1485 | master->setup = atmel_spi_setup; | 1479 | master->setup = atmel_spi_setup; |
| 1486 | master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); | 1480 | master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX | |
| 1481 | SPI_MASTER_GPIO_SS); | ||
| 1487 | master->transfer_one = atmel_spi_one_transfer; | 1482 | master->transfer_one = atmel_spi_one_transfer; |
| 1488 | master->set_cs = atmel_spi_set_cs; | 1483 | master->set_cs = atmel_spi_set_cs; |
| 1489 | master->cleanup = atmel_spi_cleanup; | 1484 | master->cleanup = atmel_spi_cleanup; |
| @@ -83,6 +83,7 @@ MODULE_PARM_DESC(polling_limit_us, · 82 unmodified lines | |||
| 83 | * struct bcm2835_spi - BCM2835 SPI controller | 83 | * struct bcm2835_spi - BCM2835 SPI controller |
| 84 | * @regs: base address of register map | 84 | * @regs: base address of register map |
| 85 | * @clk: core clock, divided to calculate serial clock | 85 | * @clk: core clock, divided to calculate serial clock |
| 86 | * @clk_hz: core clock cached speed | ||
| 86 | * @irq: interrupt, signals TX FIFO empty or RX FIFO ¾ full | 87 | * @irq: interrupt, signals TX FIFO empty or RX FIFO ¾ full |
| 87 | * @tfr: SPI transfer currently processed | 88 | * @tfr: SPI transfer currently processed |
| 88 | * @ctlr: SPI controller reverse lookup | 89 | * @ctlr: SPI controller reverse lookup |
| @@ -116,6 +117,7 @@ MODULE_PARM_DESC(polling_limit_us, · 27 unmodified lines | |||
| 116 | struct bcm2835_spi { | 117 | struct bcm2835_spi { |
| 117 | void __iomem *regs; | 118 | void __iomem *regs; |
| 118 | struct clk *clk; | 119 | struct clk *clk; |
| 120 | unsigned long clk_hz; | ||
| 119 | int irq; | 121 | int irq; |
| 120 | struct spi_transfer *tfr; | 122 | struct spi_transfer *tfr; |
| 121 | struct spi_controller *ctlr; | 123 | struct spi_controller *ctlr; |
| @@ -1045,19 +1047,18 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, · 923 unmodified lines | |||
| 1045 | { | 1047 | { |
| 1046 | struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); | 1048 | struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); |
| 1047 | struct bcm2835_spidev *slv = spi_get_ctldata(spi); | 1049 | struct bcm2835_spidev *slv = spi_get_ctldata(spi); |
| 1048 | unsigned long spi_hz, clk_hz, cdiv; | 1050 | unsigned long spi_hz, cdiv; |
| 1049 | unsigned long hz_per_byte, byte_limit; | 1051 | unsigned long hz_per_byte, byte_limit; |
| 1050 | u32 cs = slv->prepare_cs; | 1052 | u32 cs = slv->prepare_cs; |
| 1051 | 1053 | ||
| 1052 | /* set clock */ | 1054 | /* set clock */ |
| 1053 | spi_hz = tfr->speed_hz; | 1055 | spi_hz = tfr->speed_hz; |
| 1054 | clk_hz = clk_get_rate(bs->clk); | ||
| 1055 | 1056 | ||
| 1056 | if (spi_hz >= clk_hz / 2) { | 1057 | if (spi_hz >= bs->clk_hz / 2) { |
| 1057 | cdiv = 2; /* clk_hz/2 is the fastest we can go */ | 1058 | cdiv = 2; /* clk_hz/2 is the fastest we can go */ |
| 1058 | } else if (spi_hz) { | 1059 | } else if (spi_hz) { |
| 1059 | /* CDIV must be a multiple of two */ | 1060 | /* CDIV must be a multiple of two */ |
| 1060 | cdiv = DIV_ROUND_UP(clk_hz, spi_hz); | 1061 | cdiv = DIV_ROUND_UP(bs->clk_hz, spi_hz); |
| 1061 | cdiv += (cdiv % 2); | 1062 | cdiv += (cdiv % 2); |
| 1062 | 1063 | ||
| 1063 | if (cdiv >= 65536) | 1064 | if (cdiv >= 65536) |
| @@ -1065,7 +1066,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, · 1 unmodified line | |||
| 1065 | } else { | 1066 | } else { |
| 1066 | cdiv = 0; /* 0 is the slowest we can go */ | 1067 | cdiv = 0; /* 0 is the slowest we can go */ |
| 1067 | } | 1068 | } |
| 1068 | tfr->effective_speed_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536); | 1069 | tfr->effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); |
| 1069 | bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); | 1070 | bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); |
| 1070 | 1071 | ||
| 1071 | /* handle all the 3-wire mode */ | 1072 | /* handle all the 3-wire mode */ |
| @@ -1354,6 +1355,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) · 282 unmodified lines | |||
| 1354 | return bs->irq ? bs->irq : -ENODEV; | 1355 | return bs->irq ? bs->irq : -ENODEV; |
| 1355 | 1356 | ||
| 1356 | clk_prepare_enable(bs->clk); | 1357 | clk_prepare_enable(bs->clk); |
| 1358 | bs->clk_hz = clk_get_rate(bs->clk); | ||
| 1357 | 1359 | ||
| 1358 | err = bcm2835_dma_init(ctlr, &pdev->dev, bs); | 1360 | err = bcm2835_dma_init(ctlr, &pdev->dev, bs); |
| 1359 | if (err) | 1361 | if (err) |
| @@ -309,6 +309,9 @@ static unsigned int cqspi_calc_dummy(const struct spi_mem_op *op, bool dtr) · 308 unmodified lines | |||
| 309 | { | 309 | { |
| 310 | unsigned int dummy_clk; | 310 | unsigned int dummy_clk; |
| 311 | 311 | ||
| 312 | if (!op->dummy.nbytes) | ||
| 313 | return 0; | ||
| 314 | |||
| 312 | dummy_clk = op->dummy.nbytes * (8 / op->dummy.buswidth); | 315 | dummy_clk = op->dummy.nbytes * (8 / op->dummy.buswidth); |
| 313 | if (dtr) | 316 | if (dtr) |
| 314 | dummy_clk /= 2; | 317 | dummy_clk /= 2; |
| @@ -797,19 +800,20 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata, · 482 unmodified lines | |||
| 797 | reg = cqspi_calc_rdreg(f_pdata); | 800 | reg = cqspi_calc_rdreg(f_pdata); |
| 798 | writel(reg, reg_base + CQSPI_REG_RD_INSTR); | 801 | writel(reg, reg_base + CQSPI_REG_RD_INSTR); |
| 799 | 802 | ||
| 800 | if (f_pdata->dtr) { | 803 | /* |
| 801 | /* | 804 | * SPI NAND flashes require the address of the status register to be |
| 802 | * Some flashes like the cypress Semper flash expect a 4-byte | 805 | * passed in the Read SR command. Also, some SPI NOR flashes like the |
| 803 | * dummy address with the Read SR command in DTR mode, but this | 806 | * cypress Semper flash expect a 4-byte dummy address in the Read SR |
| 804 | * controller does not support sending address with the Read SR | 807 | * command in DTR mode. |
| 805 | * command. So, disable write completion polling on the | 808 | * |
| 806 | * controller's side. spi-nor will take care of polling the | 809 | * But this controller does not support address phase in the Read SR |
| 807 | * status register. | 810 | * command when doing auto-HW polling. So, disable write completion |
| 808 | */ | 811 | * polling on the controller's side. spinand and spi-nor will take |
| 809 | reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL); | 812 | * care of polling the status register. |
| 810 | reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; | 813 | */ |
| 811 | writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL); | 814 | reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL); |
| 812 | } | 815 | reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; |
| 816 | writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL); | ||
| 813 | 817 | ||
| 814 | reg = readl(reg_base + CQSPI_REG_SIZE); | 818 | reg = readl(reg_base + CQSPI_REG_SIZE); |
| 815 | reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; | 819 | reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; |
| @@ -517,6 +517,12 @@ static int cdns_spi_probe(struct platform_device *pdev) · 516 unmodified lines | |||
| 517 | goto clk_dis_apb; | 517 | goto clk_dis_apb; |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | pm_runtime_use_autosuspend(&pdev->dev); | ||
| 521 | pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); | ||
| 522 | pm_runtime_get_noresume(&pdev->dev); | ||
| 523 | pm_runtime_set_active(&pdev->dev); | ||
| 524 | pm_runtime_enable(&pdev->dev); | ||
| 525 | |||
| 520 | ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); | 526 | ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); |
| 521 | if (ret < 0) | 527 | if (ret < 0) |
| 522 | master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS; | 528 | master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS; |
| @@ -531,11 +537,6 @@ static int cdns_spi_probe(struct platform_device *pdev) · 8 unmodified lines | |||
| 531 | /* SPI controller initializations */ | 537 | /* SPI controller initializations */ |
| 532 | cdns_spi_init_hw(xspi); | 538 | cdns_spi_init_hw(xspi); |
| 533 | 539 | ||
| 534 | pm_runtime_set_active(&pdev->dev); | ||
| 535 | pm_runtime_enable(&pdev->dev); | ||
| 536 | pm_runtime_use_autosuspend(&pdev->dev); | ||
| 537 | pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); | ||
| 538 | |||
| 539 | irq = platform_get_irq(pdev, 0); | 540 | irq = platform_get_irq(pdev, 0); |
| 540 | if (irq <= 0) { | 541 | if (irq <= 0) { |
| 541 | ret = -ENXIO; | 542 | ret = -ENXIO; |
| @@ -566,6 +567,9 @@ static int cdns_spi_probe(struct platform_device *pdev) · 24 unmodified lines | |||
| 566 | 567 | ||
| 567 | master->bits_per_word_mask = SPI_BPW_MASK(8); | 568 | master->bits_per_word_mask = SPI_BPW_MASK(8); |
| 568 | 569 | ||
| 570 | pm_runtime_mark_last_busy(&pdev->dev); | ||
| 571 | pm_runtime_put_autosuspend(&pdev->dev); | ||
| 572 | |||
| 569 | ret = spi_register_master(master); | 573 | ret = spi_register_master(master); |
| 570 | if (ret) { | 574 | if (ret) { |
| 571 | dev_err(&pdev->dev, "spi_register_master failed\n"); | 575 | dev_err(&pdev->dev, "spi_register_master failed\n"); |
| @@ -506,7 +506,7 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, · 505 unmodified lines | |||
| 506 | { | 506 | { |
| 507 | struct spi_device *spi = msg->spi; | 507 | struct spi_device *spi = msg->spi; |
| 508 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE; | 508 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE; |
| 509 | u32 testreg; | 509 | u32 testreg, delay; |
| 510 | u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); | 510 | u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); |
| 511 | 511 | ||
| 512 | /* set Master or Slave mode */ | 512 | /* set Master or Slave mode */ |
| @@ -567,6 +567,23 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, · 54 unmodified lines | |||
| 567 | 567 | ||
| 568 | writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); | 568 | writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); |
| 569 | 569 | ||
| 570 | /* | ||
| 571 | * Wait until the changes in the configuration register CONFIGREG | ||
| 572 | * propagate into the hardware. It takes exactly one tick of the | ||
| 573 | * SCLK clock, but we will wait two SCLK clock just to be sure. The | ||
| 574 | * effect of the delay it takes for the hardware to apply changes | ||
| 575 | * is noticable if the SCLK clock run very slow. In such a case, if | ||
| 576 | * the polarity of SCLK should be inverted, the GPIO ChipSelect might | ||
| 577 | * be asserted before the SCLK polarity changes, which would disrupt | ||
| 578 | * the SPI communication as the device on the other end would consider | ||
| 579 | * the change of SCLK polarity as a clock tick already. | ||
| 580 | */ | ||
| 581 | delay = (2 * 1000000) / spi_imx->spi_bus_clk; | ||
| 582 | if (likely(delay < 10)) /* SCLK is faster than 100 kHz */ | ||
| 583 | udelay(delay); | ||
| 584 | else /* SCLK is _very_ slow */ | ||
| 585 | usleep_range(delay, delay + 10); | ||
| 586 | |||
| 570 | return 0; | 587 | return 0; |
| 571 | } | 588 | } |
| 572 | 589 | ||
| @@ -574,7 +591,7 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, · 1 unmodified line | |||
| 574 | struct spi_device *spi) | 591 | struct spi_device *spi) |
| 575 | { | 592 | { |
| 576 | u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); | 593 | u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); |
| 577 | u32 clk, delay; | 594 | u32 clk; |
| 578 | 595 | ||
| 579 | /* Clear BL field and set the right value */ | 596 | /* Clear BL field and set the right value */ |
| 580 | ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; | 597 | ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; |
| @@ -596,23 +613,6 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, · 15 unmodified lines | |||
| 596 | 613 | ||
| 597 | writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); | 614 | writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); |
| 598 | 615 | ||
| 599 | /* | ||
| 600 | * Wait until the changes in the configuration register CONFIGREG | ||
| 601 | * propagate into the hardware. It takes exactly one tick of the | ||
| 602 | * SCLK clock, but we will wait two SCLK clock just to be sure. The | ||
| 603 | * effect of the delay it takes for the hardware to apply changes | ||
| 604 | * is noticable if the SCLK clock run very slow. In such a case, if | ||
| 605 | * the polarity of SCLK should be inverted, the GPIO ChipSelect might | ||
| 606 | * be asserted before the SCLK polarity changes, which would disrupt | ||
| 607 | * the SPI communication as the device on the other end would consider | ||
| 608 | * the change of SCLK polarity as a clock tick already. | ||
| 609 | */ | ||
| 610 | delay = (2 * 1000000) / clk; | ||
| 611 | if (likely(delay < 10)) /* SCLK is faster than 100 kHz */ | ||
| 612 | udelay(delay); | ||
| 613 | else /* SCLK is _very_ slow */ | ||
| 614 | usleep_range(delay, delay + 10); | ||
| 615 | |||
| 616 | return 0; | 616 | return 0; |
| 617 | } | 617 | } |
| 618 | 618 | ||
| @@ -427,13 +427,23 @@ static int mtk_spi_fifo_transfer(struct spi_master *master, · 426 unmodified lines | |||
| 427 | mtk_spi_setup_packet(master); | 427 | mtk_spi_setup_packet(master); |
| 428 | 428 | ||
| 429 | cnt = xfer->len / 4; | 429 | cnt = xfer->len / 4; |
| 430 | iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt); | 430 | if (xfer->tx_buf) |
| 431 | iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt); | ||
| 432 | |||
| 433 | if (xfer->rx_buf) | ||
| 434 | ioread32_rep(mdata->base + SPI_RX_DATA_REG, xfer->rx_buf, cnt); | ||
| 431 | 435 | ||
| 432 | remainder = xfer->len % 4; | 436 | remainder = xfer->len % 4; |
| 433 | if (remainder > 0) { | 437 | if (remainder > 0) { |
| 434 | reg_val = 0; | 438 | reg_val = 0; |
| 435 | memcpy(®_val, xfer->tx_buf + (cnt * 4), remainder); | 439 | if (xfer->tx_buf) { |
| 436 | writel(reg_val, mdata->base + SPI_TX_DATA_REG); | 440 | memcpy(®_val, xfer->tx_buf + (cnt * 4), remainder); |
| 441 | writel(reg_val, mdata->base + SPI_TX_DATA_REG); | ||
| 442 | } | ||
| 443 | if (xfer->rx_buf) { | ||
| 444 | reg_val = readl(mdata->base + SPI_RX_DATA_REG); | ||
| 445 | memcpy(xfer->rx_buf + (cnt * 4), ®_val, remainder); | ||
| 446 | } | ||
| 437 | } | 447 | } |
| 438 | 448 | ||
| 439 | mtk_spi_enable_transfer(master); | 449 | mtk_spi_enable_transfer(master); |
| @@ -793,12 +803,6 @@ static int mtk_spi_probe(struct platform_device *pdev) · 353 unmodified lines | |||
| 793 | 803 | ||
| 794 | pm_runtime_enable(&pdev->dev); | 804 | pm_runtime_enable(&pdev->dev); |
| 795 | 805 | ||
| 796 | ret = devm_spi_register_master(&pdev->dev, master); | ||
| 797 | if (ret) { | ||
| 798 | dev_err(&pdev->dev, "failed to register master (%d)\n", ret); | ||
| 799 | goto err_disable_runtime_pm; | ||
| 800 | } | ||
| 801 | |||
| 802 | if (mdata->dev_comp->need_pad_sel) { | 806 | if (mdata->dev_comp->need_pad_sel) { |
| 803 | if (mdata->pad_num != master->num_chipselect) { | 807 | if (mdata->pad_num != master->num_chipselect) { |
| 804 | dev_err(&pdev->dev, | 808 | dev_err(&pdev->dev, |
| @@ -838,6 +842,12 @@ static int mtk_spi_probe(struct platform_device *pdev) · 33 unmodified lines | |||
| 838 | dev_notice(&pdev->dev, "SPI dma_set_mask(%d) failed, ret:%d\n", | 842 | dev_notice(&pdev->dev, "SPI dma_set_mask(%d) failed, ret:%d\n", |
| 839 | addr_bits, ret); | 843 | addr_bits, ret); |
| 840 | 844 | ||
| 845 | ret = devm_spi_register_master(&pdev->dev, master); | ||
| 846 | if (ret) { | ||
| 847 | dev_err(&pdev->dev, "failed to register master (%d)\n", ret); | ||
| 848 | goto err_disable_runtime_pm; | ||
| 849 | } | ||
| 850 | |||
| 841 | return 0; | 851 | return 0; |
| 842 | 852 | ||
| 843 | err_disable_runtime_pm: | 853 | err_disable_runtime_pm: |
| @@ -884,15 +884,18 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) · 883 unmodified lines | |||
| 884 | ier = readl_relaxed(spi->base + STM32H7_SPI_IER); | 884 | ier = readl_relaxed(spi->base + STM32H7_SPI_IER); |
| 885 | 885 | ||
| 886 | mask = ier; | 886 | mask = ier; |
| 887 | /* EOTIE is triggered on EOT, SUSP and TXC events. */ | 887 | /* |
| 888 | * EOTIE enables irq from EOT, SUSP and TXC events. We need to set | ||
| 889 | * SUSP to acknowledge it later. TXC is automatically cleared | ||
| 890 | */ | ||
| 891 | |||
| 888 | mask |= STM32H7_SPI_SR_SUSP; | 892 | mask |= STM32H7_SPI_SR_SUSP; |
| 889 | /* | 893 | /* |
| 890 | * When TXTF is set, DXPIE and TXPIE are cleared. So in case of | 894 | * DXPIE is set in Full-Duplex, one IT will be raised if TXP and RXP |
| 891 | * Full-Duplex, need to poll RXP event to know if there are remaining | 895 | * are set. So in case of Full-Duplex, need to poll TXP and RXP event. |
| 892 | * data, before disabling SPI. | ||
| 893 | */ | 896 | */ |
| 894 | if (spi->rx_buf && !spi->cur_usedma) | 897 | if ((spi->cur_comm == SPI_FULL_DUPLEX) && !spi->cur_usedma) |
| 895 | mask |= STM32H7_SPI_SR_RXP; | 898 | mask |= STM32H7_SPI_SR_TXP | STM32H7_SPI_SR_RXP; |
| 896 | 899 | ||
| 897 | if (!(sr & mask)) { | 900 | if (!(sr & mask)) { |
| 898 | dev_warn(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", | 901 | dev_warn(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", |
| @@ -1925,6 +1928,7 @@ static int stm32_spi_probe(struct platform_device *pdev) · 1026 unmodified lines | |||
| 1925 | master->can_dma = stm32_spi_can_dma; | 1928 | master->can_dma = stm32_spi_can_dma; |
| 1926 | 1929 | ||
| 1927 | pm_runtime_set_active(&pdev->dev); | 1930 | pm_runtime_set_active(&pdev->dev); |
| 1931 | pm_runtime_get_noresume(&pdev->dev); | ||
| 1928 | pm_runtime_enable(&pdev->dev); | 1932 | pm_runtime_enable(&pdev->dev); |
| 1929 | 1933 | ||
| 1930 | ret = spi_register_master(master); | 1934 | ret = spi_register_master(master); |
| @@ -1940,6 +1944,8 @@ static int stm32_spi_probe(struct platform_device *pdev) · 9 unmodified lines | |||
| 1940 | 1944 | ||
| 1941 | err_pm_disable: | 1945 | err_pm_disable: |
| 1942 | pm_runtime_disable(&pdev->dev); | 1946 | pm_runtime_disable(&pdev->dev); |
| 1947 | pm_runtime_put_noidle(&pdev->dev); | ||
| 1948 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1943 | err_dma_release: | 1949 | err_dma_release: |
| 1944 | if (spi->dma_tx) | 1950 | if (spi->dma_tx) |
| 1945 | dma_release_channel(spi->dma_tx); | 1951 | dma_release_channel(spi->dma_tx); |
| @@ -1956,9 +1962,14 @@ static int stm32_spi_remove(struct platform_device *pdev) · 10 unmodified lines | |||
| 1956 | struct spi_master *master = platform_get_drvdata(pdev); | 1962 | struct spi_master *master = platform_get_drvdata(pdev); |
| 1957 | struct stm32_spi *spi = spi_master_get_devdata(master); | 1963 | struct stm32_spi *spi = spi_master_get_devdata(master); |
| 1958 | 1964 | ||
| 1965 | pm_runtime_get_sync(&pdev->dev); | ||
| 1966 | |||
| 1959 | spi_unregister_master(master); | 1967 | spi_unregister_master(master); |
| 1960 | spi->cfg->disable(spi); | 1968 | spi->cfg->disable(spi); |
| 1961 | 1969 | ||
| 1970 | pm_runtime_disable(&pdev->dev); | ||
| 1971 | pm_runtime_put_noidle(&pdev->dev); | ||
| 1972 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1962 | if (master->dma_tx) | 1973 | if (master->dma_tx) |
| 1963 | dma_release_channel(master->dma_tx); | 1974 | dma_release_channel(master->dma_tx); |
| 1964 | if (master->dma_rx) | 1975 | if (master->dma_rx) |
| @@ -1966,7 +1977,6 @@ static int stm32_spi_remove(struct platform_device *pdev) · 1 unmodified line | |||
| 1966 | 1977 | ||
| 1967 | clk_disable_unprepare(spi->clk); | 1978 | clk_disable_unprepare(spi->clk); |
| 1968 | 1979 | ||
| 1969 | pm_runtime_disable(&pdev->dev); | ||
| 1970 | 1980 | ||
| 1971 | pinctrl_pm_select_sleep_state(&pdev->dev); | 1981 | pinctrl_pm_select_sleep_state(&pdev->dev); |
| 1972 | 1982 | ||
| @@ -25,7 +25,7 @@ · 24 unmodified lines | |||
| 25 | #include "target_core_alua.h" | 25 | #include "target_core_alua.h" |
| 26 | 26 | ||
| 27 | static sense_reason_t | 27 | static sense_reason_t |
| 28 | sbc_check_prot(struct se_device *, struct se_cmd *, unsigned char *, u32, bool); | 28 | sbc_check_prot(struct se_device *, struct se_cmd *, unsigned char, u32, bool); |
| 29 | static sense_reason_t sbc_execute_unmap(struct se_cmd *cmd); | 29 | static sense_reason_t sbc_execute_unmap(struct se_cmd *cmd); |
| 30 | 30 | ||
| 31 | static sense_reason_t | 31 | static sense_reason_t |
| @@ -279,14 +279,14 @@ static inline unsigned long long transport_lba_64_ext(unsigned char *cdb) · 247 unmodified lines | |||
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | static sense_reason_t | 281 | static sense_reason_t |
| 282 | sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *ops) | 282 | sbc_setup_write_same(struct se_cmd *cmd, unsigned char flags, struct sbc_ops *ops) |
| 283 | { | 283 | { |
| 284 | struct se_device *dev = cmd->se_dev; | 284 | struct se_device *dev = cmd->se_dev; |
| 285 | sector_t end_lba = dev->transport->get_blocks(dev) + 1; | 285 | sector_t end_lba = dev->transport->get_blocks(dev) + 1; |
| 286 | unsigned int sectors = sbc_get_write_same_sectors(cmd); | 286 | unsigned int sectors = sbc_get_write_same_sectors(cmd); |
| 287 | sense_reason_t ret; | 287 | sense_reason_t ret; |
| 288 | 288 | ||
| 289 | if ((flags[0] & 0x04) || (flags[0] & 0x02)) { | 289 | if ((flags & 0x04) || (flags & 0x02)) { |
| 290 | pr_err("WRITE_SAME PBDATA and LBDATA" | 290 | pr_err("WRITE_SAME PBDATA and LBDATA" |
| 291 | " bits not supported for Block Discard" | 291 | " bits not supported for Block Discard" |
| 292 | " Emulation\n"); | 292 | " Emulation\n"); |
| @@ -308,7 +308,7 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o · 15 unmodified lines | |||
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | /* We always have ANC_SUP == 0 so setting ANCHOR is always an error */ | 310 | /* We always have ANC_SUP == 0 so setting ANCHOR is always an error */ |
| 311 | if (flags[0] & 0x10) { | 311 | if (flags & 0x10) { |
| 312 | pr_warn("WRITE SAME with ANCHOR not supported\n"); | 312 | pr_warn("WRITE SAME with ANCHOR not supported\n"); |
| 313 | return TCM_INVALID_CDB_FIELD; | 313 | return TCM_INVALID_CDB_FIELD; |
| 314 | } | 314 | } |
| @@ -316,7 +316,7 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o · 1 unmodified line | |||
| 316 | * Special case for WRITE_SAME w/ UNMAP=1 that ends up getting | 316 | * Special case for WRITE_SAME w/ UNMAP=1 that ends up getting |
| 317 | * translated into block discard requests within backend code. | 317 | * translated into block discard requests within backend code. |
| 318 | */ | 318 | */ |
| 319 | if (flags[0] & 0x08) { | 319 | if (flags & 0x08) { |
| 320 | if (!ops->execute_unmap) | 320 | if (!ops->execute_unmap) |
| 321 | return TCM_UNSUPPORTED_SCSI_OPCODE; | 321 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
| 322 | 322 | ||
| @@ -331,7 +331,7 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o · 8 unmodified lines | |||
| 331 | if (!ops->execute_write_same) | 331 | if (!ops->execute_write_same) |
| 332 | return TCM_UNSUPPORTED_SCSI_OPCODE; | 332 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
| 333 | 333 | ||
| 334 | ret = sbc_check_prot(dev, cmd, &cmd->t_task_cdb[0], sectors, true); | 334 | ret = sbc_check_prot(dev, cmd, flags >> 5, sectors, true); |
| 335 | if (ret) | 335 | if (ret) |
| 336 | return ret; | 336 | return ret; |
| 337 | 337 | ||
| @@ -717,10 +717,9 @@ sbc_set_prot_op_checks(u8 protect, bool fabric_prot, enum target_prot_type prot_ · 379 unmodified lines | |||
| 717 | } | 717 | } |
| 718 | 718 | ||
| 719 | static sense_reason_t | 719 | static sense_reason_t |
| 720 | sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb, | 720 | sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char protect, |
| 721 | u32 sectors, bool is_write) | 721 | u32 sectors, bool is_write) |
| 722 | { | 722 | { |
| 723 | u8 protect = cdb[1] >> 5; | ||
| 724 | int sp_ops = cmd->se_sess->sup_prot_ops; | 723 | int sp_ops = cmd->se_sess->sup_prot_ops; |
| 725 | int pi_prot_type = dev->dev_attrib.pi_prot_type; | 724 | int pi_prot_type = dev->dev_attrib.pi_prot_type; |
| 726 | bool fabric_prot = false; | 725 | bool fabric_prot = false; |
| @@ -768,7 +767,7 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb, · 41 unmodified lines | |||
| 768 | fallthrough; | 767 | fallthrough; |
| 769 | default: | 768 | default: |
| 770 | pr_err("Unable to determine pi_prot_type for CDB: 0x%02x " | 769 | pr_err("Unable to determine pi_prot_type for CDB: 0x%02x " |
| 771 | "PROTECT: 0x%02x\n", cdb[0], protect); | 770 | "PROTECT: 0x%02x\n", cmd->t_task_cdb[0], protect); |
| 772 | return TCM_INVALID_CDB_FIELD; | 771 | return TCM_INVALID_CDB_FIELD; |
| 773 | } | 772 | } |
| 774 | 773 | ||
| @@ -843,7 +842,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 68 unmodified lines | |||
| 843 | if (sbc_check_dpofua(dev, cmd, cdb)) | 842 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 844 | return TCM_INVALID_CDB_FIELD; | 843 | return TCM_INVALID_CDB_FIELD; |
| 845 | 844 | ||
| 846 | ret = sbc_check_prot(dev, cmd, cdb, sectors, false); | 845 | ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false); |
| 847 | if (ret) | 846 | if (ret) |
| 848 | return ret; | 847 | return ret; |
| 849 | 848 | ||
| @@ -857,7 +856,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 7 unmodified lines | |||
| 857 | if (sbc_check_dpofua(dev, cmd, cdb)) | 856 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 858 | return TCM_INVALID_CDB_FIELD; | 857 | return TCM_INVALID_CDB_FIELD; |
| 859 | 858 | ||
| 860 | ret = sbc_check_prot(dev, cmd, cdb, sectors, false); | 859 | ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false); |
| 861 | if (ret) | 860 | if (ret) |
| 862 | return ret; | 861 | return ret; |
| 863 | 862 | ||
| @@ -871,7 +870,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 7 unmodified lines | |||
| 871 | if (sbc_check_dpofua(dev, cmd, cdb)) | 870 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 872 | return TCM_INVALID_CDB_FIELD; | 871 | return TCM_INVALID_CDB_FIELD; |
| 873 | 872 | ||
| 874 | ret = sbc_check_prot(dev, cmd, cdb, sectors, false); | 873 | ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, false); |
| 875 | if (ret) | 874 | if (ret) |
| 876 | return ret; | 875 | return ret; |
| 877 | 876 | ||
| @@ -892,7 +891,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 14 unmodified lines | |||
| 892 | if (sbc_check_dpofua(dev, cmd, cdb)) | 891 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 893 | return TCM_INVALID_CDB_FIELD; | 892 | return TCM_INVALID_CDB_FIELD; |
| 894 | 893 | ||
| 895 | ret = sbc_check_prot(dev, cmd, cdb, sectors, true); | 894 | ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true); |
| 896 | if (ret) | 895 | if (ret) |
| 897 | return ret; | 896 | return ret; |
| 898 | 897 | ||
| @@ -906,7 +905,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 7 unmodified lines | |||
| 906 | if (sbc_check_dpofua(dev, cmd, cdb)) | 905 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 907 | return TCM_INVALID_CDB_FIELD; | 906 | return TCM_INVALID_CDB_FIELD; |
| 908 | 907 | ||
| 909 | ret = sbc_check_prot(dev, cmd, cdb, sectors, true); | 908 | ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true); |
| 910 | if (ret) | 909 | if (ret) |
| 911 | return ret; | 910 | return ret; |
| 912 | 911 | ||
| @@ -921,7 +920,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 8 unmodified lines | |||
| 921 | if (sbc_check_dpofua(dev, cmd, cdb)) | 920 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 922 | return TCM_INVALID_CDB_FIELD; | 921 | return TCM_INVALID_CDB_FIELD; |
| 923 | 922 | ||
| 924 | ret = sbc_check_prot(dev, cmd, cdb, sectors, true); | 923 | ret = sbc_check_prot(dev, cmd, cdb[1] >> 5, sectors, true); |
| 925 | if (ret) | 924 | if (ret) |
| 926 | return ret; | 925 | return ret; |
| 927 | 926 | ||
| @@ -980,7 +979,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 52 unmodified lines | |||
| 980 | size = sbc_get_size(cmd, 1); | 979 | size = sbc_get_size(cmd, 1); |
| 981 | cmd->t_task_lba = get_unaligned_be64(&cdb[12]); | 980 | cmd->t_task_lba = get_unaligned_be64(&cdb[12]); |
| 982 | 981 | ||
| 983 | ret = sbc_setup_write_same(cmd, &cdb[10], ops); | 982 | ret = sbc_setup_write_same(cmd, cdb[10], ops); |
| 984 | if (ret) | 983 | if (ret) |
| 985 | return ret; | 984 | return ret; |
| 986 | break; | 985 | break; |
| @@ -1079,7 +1078,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 92 unmodified lines | |||
| 1079 | size = sbc_get_size(cmd, 1); | 1078 | size = sbc_get_size(cmd, 1); |
| 1080 | cmd->t_task_lba = get_unaligned_be64(&cdb[2]); | 1079 | cmd->t_task_lba = get_unaligned_be64(&cdb[2]); |
| 1081 | 1080 | ||
| 1082 | ret = sbc_setup_write_same(cmd, &cdb[1], ops); | 1081 | ret = sbc_setup_write_same(cmd, cdb[1], ops); |
| 1083 | if (ret) | 1082 | if (ret) |
| 1084 | return ret; | 1083 | return ret; |
| 1085 | break; | 1084 | break; |
| @@ -1097,7 +1096,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 11 unmodified lines | |||
| 1097 | * Follow sbcr26 with WRITE_SAME (10) and check for the existence | 1096 | * Follow sbcr26 with WRITE_SAME (10) and check for the existence |
| 1098 | * of byte 1 bit 3 UNMAP instead of original reserved field | 1097 | * of byte 1 bit 3 UNMAP instead of original reserved field |
| 1099 | */ | 1098 | */ |
| 1100 | ret = sbc_setup_write_same(cmd, &cdb[1], ops); | 1099 | ret = sbc_setup_write_same(cmd, cdb[1], ops); |
| 1101 | if (ret) | 1100 | if (ret) |
| 1102 | return ret; | 1101 | return ret; |
| 1103 | break; | 1102 | break; |
| @@ -886,7 +886,7 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) · 885 unmodified lines | |||
| 886 | INIT_WORK(&cmd->work, success ? target_complete_ok_work : | 886 | INIT_WORK(&cmd->work, success ? target_complete_ok_work : |
| 887 | target_complete_failure_work); | 887 | target_complete_failure_work); |
| 888 | 888 | ||
| 889 | if (wwn->cmd_compl_affinity == SE_COMPL_AFFINITY_CPUID) | 889 | if (!wwn || wwn->cmd_compl_affinity == SE_COMPL_AFFINITY_CPUID) |
| 890 | cpu = cmd->cpuid; | 890 | cpu = cmd->cpuid; |
| 891 | else | 891 | else |
| 892 | cpu = wwn->cmd_compl_affinity; | 892 | cpu = wwn->cmd_compl_affinity; |
| @@ -824,7 +824,7 @@ static struct usb_class_driver wdm_class = { · 823 unmodified lines | |||
| 824 | }; | 824 | }; |
| 825 | 825 | ||
| 826 | /* --- WWAN framework integration --- */ | 826 | /* --- WWAN framework integration --- */ |
| 827 | #ifdef CONFIG_WWAN | 827 | #ifdef CONFIG_WWAN_CORE |
| 828 | static int wdm_wwan_port_start(struct wwan_port *port) | 828 | static int wdm_wwan_port_start(struct wwan_port *port) |
| 829 | { | 829 | { |
| 830 | struct wdm_device *desc = wwan_port_get_drvdata(port); | 830 | struct wdm_device *desc = wwan_port_get_drvdata(port); |
| @@ -963,11 +963,11 @@ static void wdm_wwan_rx(struct wdm_device *desc, int length) · 132 unmodified lines | |||
| 963 | /* inbuf has been copied, it is safe to check for outstanding data */ | 963 | /* inbuf has been copied, it is safe to check for outstanding data */ |
| 964 | schedule_work(&desc->service_outs_intr); | 964 | schedule_work(&desc->service_outs_intr); |
| 965 | } | 965 | } |
| 966 | #else /* CONFIG_WWAN */ | 966 | #else /* CONFIG_WWAN_CORE */ |
| 967 | static void wdm_wwan_init(struct wdm_device *desc) {} | 967 | static void wdm_wwan_init(struct wdm_device *desc) {} |
| 968 | static void wdm_wwan_deinit(struct wdm_device *desc) {} | 968 | static void wdm_wwan_deinit(struct wdm_device *desc) {} |
| 969 | static void wdm_wwan_rx(struct wdm_device *desc, int length) {} | 969 | static void wdm_wwan_rx(struct wdm_device *desc, int length) {} |
| 970 | #endif /* CONFIG_WWAN */ | 970 | #endif /* CONFIG_WWAN_CORE */ |
| 971 | 971 | ||
| 972 | /* --- error handling --- */ | 972 | /* --- error handling --- */ |
| 973 | static void wdm_rxwork(struct work_struct *work) | 973 | static void wdm_rxwork(struct work_struct *work) |
| @@ -1133,7 +1133,7 @@ static int do_proc_control(struct usb_dev_state *ps, · 1132 unmodified lines | |||
| 1133 | "wIndex=%04x wLength=%04x\n", | 1133 | "wIndex=%04x wLength=%04x\n", |
| 1134 | ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, | 1134 | ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, |
| 1135 | ctrl->wIndex, ctrl->wLength); | 1135 | ctrl->wIndex, ctrl->wLength); |
| 1136 | if (ctrl->bRequestType & 0x80) { | 1136 | if ((ctrl->bRequestType & USB_DIR_IN) && ctrl->wLength) { |
| 1137 | pipe = usb_rcvctrlpipe(dev, 0); | 1137 | pipe = usb_rcvctrlpipe(dev, 0); |
| 1138 | snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, NULL, 0); | 1138 | snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, NULL, 0); |
| 1139 | 1139 | ||
| @@ -48,6 +48,7 @@ · 47 unmodified lines | |||
| 48 | 48 | ||
| 49 | #define USB_TP_TRANSMISSION_DELAY 40 /* ns */ | 49 | #define USB_TP_TRANSMISSION_DELAY 40 /* ns */ |
| 50 | #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ | 50 | #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ |
| 51 | #define USB_PING_RESPONSE_TIME 400 /* ns */ | ||
| 51 | 52 | ||
| 52 | /* Protect struct usb_device->state and ->children members | 53 | /* Protect struct usb_device->state and ->children members |
| 53 | * Note: Both are also protected by ->dev.sem, except that ->state can | 54 | * Note: Both are also protected by ->dev.sem, except that ->state can |
| @@ -182,8 +183,9 @@ int usb_device_supports_lpm(struct usb_device *udev) · 128 unmodified lines | |||
| 182 | } | 183 | } |
| 183 | 184 | ||
| 184 | /* | 185 | /* |
| 185 | * Set the Maximum Exit Latency (MEL) for the host to initiate a transition from | 186 | * Set the Maximum Exit Latency (MEL) for the host to wakup up the path from |
| 186 | * either U1 or U2. | 187 | * U1/U2, send a PING to the device and receive a PING_RESPONSE. |
| 188 | * See USB 3.1 section C.1.5.2 | ||
| 187 | */ | 189 | */ |
| 188 | static void usb_set_lpm_mel(struct usb_device *udev, | 190 | static void usb_set_lpm_mel(struct usb_device *udev, |
| 189 | struct usb3_lpm_parameters *udev_lpm_params, | 191 | struct usb3_lpm_parameters *udev_lpm_params, |
| @@ -193,35 +195,37 @@ static void usb_set_lpm_mel(struct usb_device *udev, · 3 unmodified lines | |||
| 193 | unsigned int hub_exit_latency) | 195 | unsigned int hub_exit_latency) |
| 194 | { | 196 | { |
| 195 | unsigned int total_mel; | 197 | unsigned int total_mel; |
| 196 | unsigned int device_mel; | ||
| 197 | unsigned int hub_mel; | ||
| 198 | 198 | ||
| 199 | /* | 199 | /* |
| 200 | * Calculate the time it takes to transition all links from the roothub | 200 | * tMEL1. time to transition path from host to device into U0. |
| 201 | * to the parent hub into U0. The parent hub must then decode the | 201 | * MEL for parent already contains the delay up to parent, so only add |
| 202 | * packet (hub header decode latency) to figure out which port it was | 202 | * the exit latency for the last link (pick the slower exit latency), |
| 203 | * bound for. | 203 | * and the hub header decode latency. See USB 3.1 section C 2.2.1 |
| 204 | * | 204 | * Store MEL in nanoseconds |
| 205 | * The Hub Header decode latency is expressed in 0.1us intervals (0x1 | ||
| 206 | * means 0.1us). Multiply that by 100 to get nanoseconds. | ||
| 207 | */ | 205 | */ |
| 208 | total_mel = hub_lpm_params->mel + | 206 | total_mel = hub_lpm_params->mel + |
| 209 | (hub->descriptor->u.ss.bHubHdrDecLat * 100); | 207 | max(udev_exit_latency, hub_exit_latency) * 1000 + |
| 208 | hub->descriptor->u.ss.bHubHdrDecLat * 100; | ||
| 210 | 209 | ||
| 211 | /* | 210 | /* |
| 212 | * How long will it take to transition the downstream hub's port into | 211 | * tMEL2. Time to submit PING packet. Sum of tTPTransmissionDelay for |
| 213 | * U0? The greater of either the hub exit latency or the device exit | 212 | * each link + wHubDelay for each hub. Add only for last link. |
| 214 | * latency. | 213 | * tMEL4, the time for PING_RESPONSE to traverse upstream is similar. |
| 215 | * | 214 | * Multiply by 2 to include it as well. |
| 216 | * The BOS U1/U2 exit latencies are expressed in 1us intervals. | ||
| 217 | * Multiply that by 1000 to get nanoseconds. | ||
| 218 | */ | 215 | */ |
| 219 | device_mel = udev_exit_latency * 1000; | 216 | total_mel += (__le16_to_cpu(hub->descriptor->u.ss.wHubDelay) + |
| 220 | hub_mel = hub_exit_latency * 1000; | 217 | USB_TP_TRANSMISSION_DELAY) * 2; |
| 221 | if (device_mel > hub_mel) | 218 | |
| 222 | total_mel += device_mel; | 219 | /* |
| 223 | else | 220 | * tMEL3, tPingResponse. Time taken by device to generate PING_RESPONSE |
| 224 | total_mel += hub_mel; | 221 | * after receiving PING. Also add 2100ns as stated in USB 3.1 C 1.5.2.4 |
| 222 | * to cover the delay if the PING_RESPONSE is queued behind a Max Packet | ||
| 223 | * Size DP. | ||
| 224 | * Note these delays should be added only once for the entire path, so | ||
| 225 | * add them to the MEL of the device connected to the roothub. | ||
| 226 | */ | ||
| 227 | if (!hub->hdev->parent) | ||
| 228 | total_mel += USB_PING_RESPONSE_TIME + 2100; | ||
| 225 | 229 | ||
| 226 | udev_lpm_params->mel = total_mel; | 230 | udev_lpm_params->mel = total_mel; |
| 227 | } | 231 | } |
| @@ -4112,6 +4116,47 @@ static int usb_set_lpm_timeout(struct usb_device *udev, · 3884 unmodified lines | |||
| 4112 | return 0; | 4116 | return 0; |
| 4113 | } | 4117 | } |
| 4114 | 4118 | ||
| 4119 | /* | ||
| 4120 | * Don't allow device intiated U1/U2 if the system exit latency + one bus | ||
| 4121 | * interval is greater than the minimum service interval of any active | ||
| 4122 | * periodic endpoint. See USB 3.2 section 9.4.9 | ||
| 4123 | */ | ||
| 4124 | static bool usb_device_may_initiate_lpm(struct usb_device *udev, | ||
| 4125 | enum usb3_link_state state) | ||
| 4126 | { | ||
| 4127 | unsigned int sel; /* us */ | ||
| 4128 | int i, j; | ||
| 4129 | |||
| 4130 | if (state == USB3_LPM_U1) | ||
| 4131 | sel = DIV_ROUND_UP(udev->u1_params.sel, 1000); | ||
| 4132 | else if (state == USB3_LPM_U2) | ||
| 4133 | sel = DIV_ROUND_UP(udev->u2_params.sel, 1000); | ||
| 4134 | else | ||
| 4135 | return false; | ||
| 4136 | |||
| 4137 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | ||
| 4138 | struct usb_interface *intf; | ||
| 4139 | struct usb_endpoint_descriptor *desc; | ||
| 4140 | unsigned int interval; | ||
| 4141 | |||
| 4142 | intf = udev->actconfig->interface[i]; | ||
| 4143 | if (!intf) | ||
| 4144 | continue; | ||
| 4145 | |||
| 4146 | for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) { | ||
| 4147 | desc = &intf->cur_altsetting->endpoint[j].desc; | ||
| 4148 | |||
| 4149 | if (usb_endpoint_xfer_int(desc) || | ||
| 4150 | usb_endpoint_xfer_isoc(desc)) { | ||
| 4151 | interval = (1 << (desc->bInterval - 1)) * 125; | ||
| 4152 | if (sel + 125 > interval) | ||
| 4153 | return false; | ||
| 4154 | } | ||
| 4155 | } | ||
| 4156 | } | ||
| 4157 | return true; | ||
| 4158 | } | ||
| 4159 | |||
| 4115 | /* | 4160 | /* |
| 4116 | * Enable the hub-initiated U1/U2 idle timeouts, and enable device-initiated | 4161 | * Enable the hub-initiated U1/U2 idle timeouts, and enable device-initiated |
| 4117 | * U1/U2 entry. | 4162 | * U1/U2 entry. |
| @@ -4184,20 +4229,23 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, · 66 unmodified lines | |||
| 4184 | * U1/U2_ENABLE | 4229 | * U1/U2_ENABLE |
| 4185 | */ | 4230 | */ |
| 4186 | if (udev->actconfig && | 4231 | if (udev->actconfig && |
| 4187 | usb_set_device_initiated_lpm(udev, state, true) == 0) { | 4232 | usb_device_may_initiate_lpm(udev, state)) { |
| 4188 | if (state == USB3_LPM_U1) | 4233 | if (usb_set_device_initiated_lpm(udev, state, true)) { |
| 4189 | udev->usb3_lpm_u1_enabled = 1; | 4234 | /* |
| 4190 | else if (state == USB3_LPM_U2) | 4235 | * Request to enable device initiated U1/U2 failed, |
| 4191 | udev->usb3_lpm_u2_enabled = 1; | 4236 | * better to turn off lpm in this case. |
| 4192 | } else { | 4237 | */ |
| 4193 | /* Don't request U1/U2 entry if the device | 4238 | usb_set_lpm_timeout(udev, state, 0); |
| 4194 | * cannot transition to U1/U2. | 4239 | hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); |
| 4195 | */ | 4240 | return; |
| 4196 | usb_set_lpm_timeout(udev, state, 0); | 4241 | } |
| 4197 | hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); | ||
| 4198 | } | 4242 | } |
| 4199 | } | ||
| 4200 | 4243 | ||
| 4244 | if (state == USB3_LPM_U1) | ||
| 4245 | udev->usb3_lpm_u1_enabled = 1; | ||
| 4246 | else if (state == USB3_LPM_U2) | ||
| 4247 | udev->usb3_lpm_u2_enabled = 1; | ||
| 4248 | } | ||
| 4201 | /* | 4249 | /* |
| 4202 | * Disable the hub-initiated U1/U2 idle timeouts, and disable device-initiated | 4250 | * Disable the hub-initiated U1/U2 idle timeouts, and disable device-initiated |
| 4203 | * U1/U2 entry. | 4251 | * U1/U2 entry. |
| @@ -501,10 +501,6 @@ static const struct usb_device_id usb_quirk_list[] = { · 500 unmodified lines | |||
| 501 | /* DJI CineSSD */ | 501 | /* DJI CineSSD */ |
| 502 | { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, | 502 | { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, |
| 503 | 503 | ||
| 504 | /* Fibocom L850-GL LTE Modem */ | ||
| 505 | { USB_DEVICE(0x2cb7, 0x0007), .driver_info = | ||
| 506 | USB_QUIRK_IGNORE_REMOTE_WAKEUP }, | ||
| 507 | |||
| 508 | /* INTEL VALUE SSD */ | 504 | /* INTEL VALUE SSD */ |
| 509 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, | 505 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 510 | 506 | ||
| @@ -383,6 +383,9 @@ enum dwc2_ep0_state { · 382 unmodified lines | |||
| 383 | * 0 - No (default) | 383 | * 0 - No (default) |
| 384 | * 1 - Partial power down | 384 | * 1 - Partial power down |
| 385 | * 2 - Hibernation | 385 | * 2 - Hibernation |
| 386 | * @no_clock_gating: Specifies whether to avoid clock gating feature. | ||
| 387 | * 0 - No (use clock gating) | ||
| 388 | * 1 - Yes (avoid it) | ||
| 386 | * @lpm: Enable LPM support. | 389 | * @lpm: Enable LPM support. |
| 387 | * 0 - No | 390 | * 0 - No |
| 388 | * 1 - Yes | 391 | * 1 - Yes |
| @@ -480,6 +483,7 @@ struct dwc2_core_params { · 91 unmodified lines | |||
| 480 | #define DWC2_POWER_DOWN_PARAM_NONE 0 | 483 | #define DWC2_POWER_DOWN_PARAM_NONE 0 |
| 481 | #define DWC2_POWER_DOWN_PARAM_PARTIAL 1 | 484 | #define DWC2_POWER_DOWN_PARAM_PARTIAL 1 |
| 482 | #define DWC2_POWER_DOWN_PARAM_HIBERNATION 2 | 485 | #define DWC2_POWER_DOWN_PARAM_HIBERNATION 2 |
| 486 | bool no_clock_gating; | ||
| 483 | 487 | ||
| 484 | bool lpm; | 488 | bool lpm; |
| 485 | bool lpm_clock_gating; | 489 | bool lpm_clock_gating; |
| @@ -556,7 +556,8 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) · 555 unmodified lines | |||
| 556 | * If neither hibernation nor partial power down are supported, | 556 | * If neither hibernation nor partial power down are supported, |
| 557 | * clock gating is used to save power. | 557 | * clock gating is used to save power. |
| 558 | */ | 558 | */ |
| 559 | dwc2_gadget_enter_clock_gating(hsotg); | 559 | if (!hsotg->params.no_clock_gating) |
| 560 | dwc2_gadget_enter_clock_gating(hsotg); | ||
| 560 | } | 561 | } |
| 561 | 562 | ||
| 562 | /* | 563 | /* |
| @@ -2749,12 +2749,14 @@ static void dwc2_hsotg_complete_in(struct dwc2_hsotg *hsotg, · 2748 unmodified lines | |||
| 2749 | return; | 2749 | return; |
| 2750 | } | 2750 | } |
| 2751 | 2751 | ||
| 2752 | /* Zlp for all endpoints, for ep0 only in DATA IN stage */ | 2752 | /* Zlp for all endpoints in non DDMA, for ep0 only in DATA IN stage */ |
| 2753 | if (hs_ep->send_zlp) { | 2753 | if (hs_ep->send_zlp) { |
| 2754 | dwc2_hsotg_program_zlp(hsotg, hs_ep); | ||
| 2755 | hs_ep->send_zlp = 0; | 2754 | hs_ep->send_zlp = 0; |
| 2756 | /* transfer will be completed on next complete interrupt */ | 2755 | if (!using_desc_dma(hsotg)) { |
| 2757 | return; | 2756 | dwc2_hsotg_program_zlp(hsotg, hs_ep); |
| 2757 | /* transfer will be completed on next complete interrupt */ | ||
| 2758 | return; | ||
| 2759 | } | ||
| 2758 | } | 2760 | } |
| 2759 | 2761 | ||
| 2760 | if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_DATA_IN) { | 2762 | if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_DATA_IN) { |
| @@ -3900,9 +3902,27 @@ static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg, · 1139 unmodified lines | |||
| 3900 | __func__); | 3902 | __func__); |
| 3901 | } | 3903 | } |
| 3902 | } else { | 3904 | } else { |
| 3905 | /* Mask GINTSTS_GOUTNAKEFF interrupt */ | ||
| 3906 | dwc2_hsotg_disable_gsint(hsotg, GINTSTS_GOUTNAKEFF); | ||
| 3907 | |||
| 3903 | if (!(dwc2_readl(hsotg, GINTSTS) & GINTSTS_GOUTNAKEFF)) | 3908 | if (!(dwc2_readl(hsotg, GINTSTS) & GINTSTS_GOUTNAKEFF)) |
| 3904 | dwc2_set_bit(hsotg, DCTL, DCTL_SGOUTNAK); | 3909 | dwc2_set_bit(hsotg, DCTL, DCTL_SGOUTNAK); |
| 3905 | 3910 | ||
| 3911 | if (!using_dma(hsotg)) { | ||
| 3912 | /* Wait for GINTSTS_RXFLVL interrupt */ | ||
| 3913 | if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, | ||
| 3914 | GINTSTS_RXFLVL, 100)) { | ||
| 3915 | dev_warn(hsotg->dev, "%s: timeout GINTSTS.RXFLVL\n", | ||
| 3916 | __func__); | ||
| 3917 | } else { | ||
| 3918 | /* | ||
| 3919 | * Pop GLOBAL OUT NAK status packet from RxFIFO | ||
| 3920 | * to assert GOUTNAKEFF interrupt | ||
| 3921 | */ | ||
| 3922 | dwc2_readl(hsotg, GRXSTSP); | ||
| 3923 | } | ||
| 3924 | } | ||
| 3925 | |||
| 3906 | /* Wait for global nak to take effect */ | 3926 | /* Wait for global nak to take effect */ |
| 3907 | if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, | 3927 | if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, |
| 3908 | GINTSTS_GOUTNAKEFF, 100)) | 3928 | GINTSTS_GOUTNAKEFF, 100)) |
| @@ -4348,6 +4368,9 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value, bool now) · 439 unmodified lines | |||
| 4348 | epctl = dwc2_readl(hs, epreg); | 4368 | epctl = dwc2_readl(hs, epreg); |
| 4349 | 4369 | ||
| 4350 | if (value) { | 4370 | if (value) { |
| 4371 | /* Unmask GOUTNAKEFF interrupt */ | ||
| 4372 | dwc2_hsotg_en_gsint(hs, GINTSTS_GOUTNAKEFF); | ||
| 4373 | |||
| 4351 | if (!(dwc2_readl(hs, GINTSTS) & GINTSTS_GOUTNAKEFF)) | 4374 | if (!(dwc2_readl(hs, GINTSTS) & GINTSTS_GOUTNAKEFF)) |
| 4352 | dwc2_set_bit(hs, DCTL, DCTL_SGOUTNAK); | 4375 | dwc2_set_bit(hs, DCTL, DCTL_SGOUTNAK); |
| 4353 | // STALL bit will be set in GOUTNAKEFF interrupt handler | 4376 | // STALL bit will be set in GOUTNAKEFF interrupt handler |
| @@ -3338,7 +3338,8 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) · 3337 unmodified lines | |||
| 3338 | * If not hibernation nor partial power down are supported, | 3338 | * If not hibernation nor partial power down are supported, |
| 3339 | * clock gating is used to save power. | 3339 | * clock gating is used to save power. |
| 3340 | */ | 3340 | */ |
| 3341 | dwc2_host_enter_clock_gating(hsotg); | 3341 | if (!hsotg->params.no_clock_gating) |
| 3342 | dwc2_host_enter_clock_gating(hsotg); | ||
| 3342 | break; | 3343 | break; |
| 3343 | } | 3344 | } |
| 3344 | 3345 | ||
| @@ -4402,7 +4403,8 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) · 1057 unmodified lines | |||
| 4402 | * If not hibernation nor partial power down are supported, | 4403 | * If not hibernation nor partial power down are supported, |
| 4403 | * clock gating is used to save power. | 4404 | * clock gating is used to save power. |
| 4404 | */ | 4405 | */ |
| 4405 | dwc2_host_enter_clock_gating(hsotg); | 4406 | if (!hsotg->params.no_clock_gating) |
| 4407 | dwc2_host_enter_clock_gating(hsotg); | ||
| 4406 | 4408 | ||
| 4407 | /* After entering suspend, hardware is not accessible */ | 4409 | /* After entering suspend, hardware is not accessible */ |
| 4408 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 4410 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
| @@ -76,6 +76,7 @@ static void dwc2_set_s3c6400_params(struct dwc2_hsotg *hsotg) · 75 unmodified lines | |||
| 76 | struct dwc2_core_params *p = &hsotg->params; | 76 | struct dwc2_core_params *p = &hsotg->params; |
| 77 | 77 | ||
| 78 | p->power_down = DWC2_POWER_DOWN_PARAM_NONE; | 78 | p->power_down = DWC2_POWER_DOWN_PARAM_NONE; |
| 79 | p->no_clock_gating = true; | ||
| 79 | p->phy_utmi_width = 8; | 80 | p->phy_utmi_width = 8; |
| 80 | } | 81 | } |
| 81 | 82 | ||
| @@ -1279,6 +1279,7 @@ struct dwc3 { · 1278 unmodified lines | |||
| 1279 | unsigned dis_metastability_quirk:1; | 1279 | unsigned dis_metastability_quirk:1; |
| 1280 | 1280 | ||
| 1281 | unsigned dis_split_quirk:1; | 1281 | unsigned dis_split_quirk:1; |
| 1282 | unsigned async_callbacks:1; | ||
| 1282 | 1283 | ||
| 1283 | u16 imod_interval; | 1284 | u16 imod_interval; |
| 1284 | }; | 1285 | }; |
| @@ -597,11 +597,13 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) · 596 unmodified lines | |||
| 597 | 597 | ||
| 598 | static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | 598 | static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) |
| 599 | { | 599 | { |
| 600 | int ret; | 600 | int ret = -EINVAL; |
| 601 | 601 | ||
| 602 | spin_unlock(&dwc->lock); | 602 | if (dwc->async_callbacks) { |
| 603 | ret = dwc->gadget_driver->setup(dwc->gadget, ctrl); | 603 | spin_unlock(&dwc->lock); |
| 604 | spin_lock(&dwc->lock); | 604 | ret = dwc->gadget_driver->setup(dwc->gadget, ctrl); |
| 605 | spin_lock(&dwc->lock); | ||
| 606 | } | ||
| 605 | return ret; | 607 | return ret; |
| 606 | } | 608 | } |
| 607 | 609 | ||
| @@ -2585,6 +2585,16 @@ static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA) · 2584 unmodified lines | |||
| 2585 | return ret; | 2585 | return ret; |
| 2586 | } | 2586 | } |
| 2587 | 2587 | ||
| 2588 | static void dwc3_gadget_async_callbacks(struct usb_gadget *g, bool enable) | ||
| 2589 | { | ||
| 2590 | struct dwc3 *dwc = gadget_to_dwc(g); | ||
| 2591 | unsigned long flags; | ||
| 2592 | |||
| 2593 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 2594 | dwc->async_callbacks = enable; | ||
| 2595 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
| 2596 | } | ||
| 2597 | |||
| 2588 | static const struct usb_gadget_ops dwc3_gadget_ops = { | 2598 | static const struct usb_gadget_ops dwc3_gadget_ops = { |
| 2589 | .get_frame = dwc3_gadget_get_frame, | 2599 | .get_frame = dwc3_gadget_get_frame, |
| 2590 | .wakeup = dwc3_gadget_wakeup, | 2600 | .wakeup = dwc3_gadget_wakeup, |
| @@ -2596,6 +2606,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { · 5 unmodified lines | |||
| 2596 | .udc_set_ssp_rate = dwc3_gadget_set_ssp_rate, | 2606 | .udc_set_ssp_rate = dwc3_gadget_set_ssp_rate, |
| 2597 | .get_config_params = dwc3_gadget_config_params, | 2607 | .get_config_params = dwc3_gadget_config_params, |
| 2598 | .vbus_draw = dwc3_gadget_vbus_draw, | 2608 | .vbus_draw = dwc3_gadget_vbus_draw, |
| 2609 | .udc_async_callbacks = dwc3_gadget_async_callbacks, | ||
| 2599 | }; | 2610 | }; |
| 2600 | 2611 | ||
| 2601 | /* -------------------------------------------------------------------------- */ | 2612 | /* -------------------------------------------------------------------------- */ |
| @@ -3231,7 +3242,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, · 629 unmodified lines | |||
| 3231 | 3242 | ||
| 3232 | static void dwc3_disconnect_gadget(struct dwc3 *dwc) | 3243 | static void dwc3_disconnect_gadget(struct dwc3 *dwc) |
| 3233 | { | 3244 | { |
| 3234 | if (dwc->gadget_driver && dwc->gadget_driver->disconnect) { | 3245 | if (dwc->async_callbacks && dwc->gadget_driver->disconnect) { |
| 3235 | spin_unlock(&dwc->lock); | 3246 | spin_unlock(&dwc->lock); |
| 3236 | dwc->gadget_driver->disconnect(dwc->gadget); | 3247 | dwc->gadget_driver->disconnect(dwc->gadget); |
| 3237 | spin_lock(&dwc->lock); | 3248 | spin_lock(&dwc->lock); |
| @@ -3240,7 +3251,7 @@ static void dwc3_disconnect_gadget(struct dwc3 *dwc) · 2 unmodified lines | |||
| 3240 | 3251 | ||
| 3241 | static void dwc3_suspend_gadget(struct dwc3 *dwc) | 3252 | static void dwc3_suspend_gadget(struct dwc3 *dwc) |
| 3242 | { | 3253 | { |
| 3243 | if (dwc->gadget_driver && dwc->gadget_driver->suspend) { | 3254 | if (dwc->async_callbacks && dwc->gadget_driver->suspend) { |
| 3244 | spin_unlock(&dwc->lock); | 3255 | spin_unlock(&dwc->lock); |
| 3245 | dwc->gadget_driver->suspend(dwc->gadget); | 3256 | dwc->gadget_driver->suspend(dwc->gadget); |
| 3246 | spin_lock(&dwc->lock); | 3257 | spin_lock(&dwc->lock); |
| @@ -3249,7 +3260,7 @@ static void dwc3_suspend_gadget(struct dwc3 *dwc) · 2 unmodified lines | |||
| 3249 | 3260 | ||
| 3250 | static void dwc3_resume_gadget(struct dwc3 *dwc) | 3261 | static void dwc3_resume_gadget(struct dwc3 *dwc) |
| 3251 | { | 3262 | { |
| 3252 | if (dwc->gadget_driver && dwc->gadget_driver->resume) { | 3263 | if (dwc->async_callbacks && dwc->gadget_driver->resume) { |
| 3253 | spin_unlock(&dwc->lock); | 3264 | spin_unlock(&dwc->lock); |
| 3254 | dwc->gadget_driver->resume(dwc->gadget); | 3265 | dwc->gadget_driver->resume(dwc->gadget); |
| 3255 | spin_lock(&dwc->lock); | 3266 | spin_lock(&dwc->lock); |
| @@ -3261,7 +3272,7 @@ static void dwc3_reset_gadget(struct dwc3 *dwc) · 5 unmodified lines | |||
| 3261 | if (!dwc->gadget_driver) | 3272 | if (!dwc->gadget_driver) |
| 3262 | return; | 3273 | return; |
| 3263 | 3274 | ||
| 3264 | if (dwc->gadget->speed != USB_SPEED_UNKNOWN) { | 3275 | if (dwc->async_callbacks && dwc->gadget->speed != USB_SPEED_UNKNOWN) { |
| 3265 | spin_unlock(&dwc->lock); | 3276 | spin_unlock(&dwc->lock); |
| 3266 | usb_gadget_udc_reset(dwc->gadget, dwc->gadget_driver); | 3277 | usb_gadget_udc_reset(dwc->gadget, dwc->gadget_driver); |
| 3267 | spin_lock(&dwc->lock); | 3278 | spin_lock(&dwc->lock); |
| @@ -3585,7 +3596,7 @@ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) · 317 unmodified lines | |||
| 3585 | * implemented. | 3596 | * implemented. |
| 3586 | */ | 3597 | */ |
| 3587 | 3598 | ||
| 3588 | if (dwc->gadget_driver && dwc->gadget_driver->resume) { | 3599 | if (dwc->async_callbacks && dwc->gadget_driver->resume) { |
| 3589 | spin_unlock(&dwc->lock); | 3600 | spin_unlock(&dwc->lock); |
| 3590 | dwc->gadget_driver->resume(dwc->gadget); | 3601 | dwc->gadget_driver->resume(dwc->gadget); |
| 3591 | spin_lock(&dwc->lock); | 3602 | spin_lock(&dwc->lock); |
| @@ -1198,7 +1198,7 @@ void gserial_free_line(unsigned char port_num) · 1197 unmodified lines | |||
| 1198 | struct gs_port *port; | 1198 | struct gs_port *port; |
| 1199 | 1199 | ||
| 1200 | mutex_lock(&ports[port_num].lock); | 1200 | mutex_lock(&ports[port_num].lock); |
| 1201 | if (WARN_ON(!ports[port_num].port)) { | 1201 | if (!ports[port_num].port) { |
| 1202 | mutex_unlock(&ports[port_num].lock); | 1202 | mutex_unlock(&ports[port_num].lock); |
| 1203 | return; | 1203 | return; |
| 1204 | } | 1204 | } |
| @@ -3853,6 +3853,7 @@ static int tegra_xudc_probe(struct platform_device *pdev) · 3852 unmodified lines | |||
| 3853 | return 0; | 3853 | return 0; |
| 3854 | 3854 | ||
| 3855 | free_eps: | 3855 | free_eps: |
| 3856 | pm_runtime_disable(&pdev->dev); | ||
| 3856 | tegra_xudc_free_eps(xudc); | 3857 | tegra_xudc_free_eps(xudc); |
| 3857 | free_event_ring: | 3858 | free_event_ring: |
| 3858 | tegra_xudc_free_event_ring(xudc); | 3859 | tegra_xudc_free_event_ring(xudc); |
| @@ -703,24 +703,28 @@ EXPORT_SYMBOL_GPL(ehci_setup); · 702 unmodified lines | |||
| 703 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) | 703 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
| 704 | { | 704 | { |
| 705 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 705 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
| 706 | u32 status, masked_status, pcd_status = 0, cmd; | 706 | u32 status, current_status, masked_status, pcd_status = 0; |
| 707 | u32 cmd; | ||
| 707 | int bh; | 708 | int bh; |
| 708 | 709 | ||
| 709 | spin_lock(&ehci->lock); | 710 | spin_lock(&ehci->lock); |
| 710 | 711 | ||
| 711 | status = ehci_readl(ehci, &ehci->regs->status); | 712 | status = 0; |
| 713 | current_status = ehci_readl(ehci, &ehci->regs->status); | ||
| 714 | restart: | ||
| 712 | 715 | ||
| 713 | /* e.g. cardbus physical eject */ | 716 | /* e.g. cardbus physical eject */ |
| 714 | if (status == ~(u32) 0) { | 717 | if (current_status == ~(u32) 0) { |
| 715 | ehci_dbg (ehci, "device removed\n"); | 718 | ehci_dbg (ehci, "device removed\n"); |
| 716 | goto dead; | 719 | goto dead; |
| 717 | } | 720 | } |
| 721 | status |= current_status; | ||
| 718 | 722 | ||
| 719 | /* | 723 | /* |
| 720 | * We don't use STS_FLR, but some controllers don't like it to | 724 | * We don't use STS_FLR, but some controllers don't like it to |
| 721 | * remain on, so mask it out along with the other status bits. | 725 | * remain on, so mask it out along with the other status bits. |
| 722 | */ | 726 | */ |
| 723 | masked_status = status & (INTR_MASK | STS_FLR); | 727 | masked_status = current_status & (INTR_MASK | STS_FLR); |
| 724 | 728 | ||
| 725 | /* Shared IRQ? */ | 729 | /* Shared IRQ? */ |
| 726 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { | 730 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { |
| @@ -730,6 +734,12 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) · 3 unmodified lines | |||
| 730 | 734 | ||
| 731 | /* clear (just) interrupts */ | 735 | /* clear (just) interrupts */ |
| 732 | ehci_writel(ehci, masked_status, &ehci->regs->status); | 736 | ehci_writel(ehci, masked_status, &ehci->regs->status); |
| 737 | |||
| 738 | /* For edge interrupts, don't race with an interrupt bit being raised */ | ||
| 739 | current_status = ehci_readl(ehci, &ehci->regs->status); | ||
| 740 | if (current_status & INTR_MASK) | ||
| 741 | goto restart; | ||
| 742 | |||
| 733 | cmd = ehci_readl(ehci, &ehci->regs->command); | 743 | cmd = ehci_readl(ehci, &ehci->regs->command); |
| 734 | bh = 0; | 744 | bh = 0; |
| 735 | 745 | ||
| @@ -153,8 +153,6 @@ struct max3421_hcd { · 152 unmodified lines | |||
| 153 | */ | 153 | */ |
| 154 | struct urb *curr_urb; | 154 | struct urb *curr_urb; |
| 155 | enum scheduling_pass sched_pass; | 155 | enum scheduling_pass sched_pass; |
| 156 | struct usb_device *loaded_dev; /* dev that's loaded into the chip */ | ||
| 157 | int loaded_epnum; /* epnum whose toggles are loaded */ | ||
| 158 | int urb_done; /* > 0 -> no errors, < 0: errno */ | 156 | int urb_done; /* > 0 -> no errors, < 0: errno */ |
| 159 | size_t curr_len; | 157 | size_t curr_len; |
| 160 | u8 hien; | 158 | u8 hien; |
| @@ -492,39 +490,17 @@ max3421_set_speed(struct usb_hcd *hcd, struct usb_device *dev) · 331 unmodified lines | |||
| 492 | * Caller must NOT hold HCD spinlock. | 490 | * Caller must NOT hold HCD spinlock. |
| 493 | */ | 491 | */ |
| 494 | static void | 492 | static void |
| 495 | max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum, | 493 | max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum) |
| 496 | int force_toggles) | ||
| 497 | { | 494 | { |
| 498 | struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); | 495 | int rcvtog, sndtog; |
| 499 | int old_epnum, same_ep, rcvtog, sndtog; | ||
| 500 | struct usb_device *old_dev; | ||
| 501 | u8 hctl; | 496 | u8 hctl; |
| 502 | 497 | ||
| 503 | old_dev = max3421_hcd->loaded_dev; | ||
| 504 | old_epnum = max3421_hcd->loaded_epnum; | ||
| 505 | |||
| 506 | same_ep = (dev == old_dev && epnum == old_epnum); | ||
| 507 | if (same_ep && !force_toggles) | ||
| 508 | return; | ||
| 509 | |||
| 510 | if (old_dev && !same_ep) { | ||
| 511 | /* save the old end-points toggles: */ | ||
| 512 | u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); | ||
| 513 | |||
| 514 | rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1; | ||
| 515 | sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; | ||
| 516 | |||
| 517 | /* no locking: HCD (i.e., we) own toggles, don't we? */ | ||
| 518 | usb_settoggle(old_dev, old_epnum, 0, rcvtog); | ||
| 519 | usb_settoggle(old_dev, old_epnum, 1, sndtog); | ||
| 520 | } | ||
| 521 | /* setup new endpoint's toggle bits: */ | 498 | /* setup new endpoint's toggle bits: */ |
| 522 | rcvtog = usb_gettoggle(dev, epnum, 0); | 499 | rcvtog = usb_gettoggle(dev, epnum, 0); |
| 523 | sndtog = usb_gettoggle(dev, epnum, 1); | 500 | sndtog = usb_gettoggle(dev, epnum, 1); |
| 524 | hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) | | 501 | hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) | |
| 525 | BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); | 502 | BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); |
| 526 | 503 | ||
| 527 | max3421_hcd->loaded_epnum = epnum; | ||
| 528 | spi_wr8(hcd, MAX3421_REG_HCTL, hctl); | 504 | spi_wr8(hcd, MAX3421_REG_HCTL, hctl); |
| 529 | 505 | ||
| 530 | /* | 506 | /* |
| @@ -532,7 +508,6 @@ max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum, · 1 unmodified line | |||
| 532 | * address-assignment so it's best to just always load the | 508 | * address-assignment so it's best to just always load the |
| 533 | * address whenever the end-point changed/was forced. | 509 | * address whenever the end-point changed/was forced. |
| 534 | */ | 510 | */ |
| 535 | max3421_hcd->loaded_dev = dev; | ||
| 536 | spi_wr8(hcd, MAX3421_REG_PERADDR, dev->devnum); | 511 | spi_wr8(hcd, MAX3421_REG_PERADDR, dev->devnum); |
| 537 | } | 512 | } |
| 538 | 513 | ||
| @@ -667,7 +642,7 @@ max3421_select_and_start_urb(struct usb_hcd *hcd) · 128 unmodified lines | |||
| 667 | struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); | 642 | struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); |
| 668 | struct urb *urb, *curr_urb = NULL; | 643 | struct urb *urb, *curr_urb = NULL; |
| 669 | struct max3421_ep *max3421_ep; | 644 | struct max3421_ep *max3421_ep; |
| 670 | int epnum, force_toggles = 0; | 645 | int epnum; |
| 671 | struct usb_host_endpoint *ep; | 646 | struct usb_host_endpoint *ep; |
| 672 | struct list_head *pos; | 647 | struct list_head *pos; |
| 673 | unsigned long flags; | 648 | unsigned long flags; |
| @@ -777,7 +752,6 @@ done: · 103 unmodified lines | |||
| 777 | usb_settoggle(urb->dev, epnum, 0, 1); | 752 | usb_settoggle(urb->dev, epnum, 0, 1); |
| 778 | usb_settoggle(urb->dev, epnum, 1, 1); | 753 | usb_settoggle(urb->dev, epnum, 1, 1); |
| 779 | max3421_ep->pkt_state = PKT_STATE_SETUP; | 754 | max3421_ep->pkt_state = PKT_STATE_SETUP; |
| 780 | force_toggles = 1; | ||
| 781 | } else | 755 | } else |
| 782 | max3421_ep->pkt_state = PKT_STATE_TRANSFER; | 756 | max3421_ep->pkt_state = PKT_STATE_TRANSFER; |
| 783 | } | 757 | } |
| @@ -785,7 +759,7 @@ done: · 1 unmodified line | |||
| 785 | spin_unlock_irqrestore(&max3421_hcd->lock, flags); | 759 | spin_unlock_irqrestore(&max3421_hcd->lock, flags); |
| 786 | 760 | ||
| 787 | max3421_ep->last_active = max3421_hcd->frame_number; | 761 | max3421_ep->last_active = max3421_hcd->frame_number; |
| 788 | max3421_set_address(hcd, urb->dev, epnum, force_toggles); | 762 | max3421_set_address(hcd, urb->dev, epnum); |
| 789 | max3421_set_speed(hcd, urb->dev); | 763 | max3421_set_speed(hcd, urb->dev); |
| 790 | max3421_next_transfer(hcd, 0); | 764 | max3421_next_transfer(hcd, 0); |
| 791 | return 1; | 765 | return 1; |
| @@ -1379,6 +1353,16 @@ max3421_urb_done(struct usb_hcd *hcd) · 587 unmodified lines | |||
| 1379 | status = 0; | 1353 | status = 0; |
| 1380 | urb = max3421_hcd->curr_urb; | 1354 | urb = max3421_hcd->curr_urb; |
| 1381 | if (urb) { | 1355 | if (urb) { |
| 1356 | /* save the old end-points toggles: */ | ||
| 1357 | u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); | ||
| 1358 | int rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1; | ||
| 1359 | int sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; | ||
| 1360 | int epnum = usb_endpoint_num(&urb->ep->desc); | ||
| 1361 | |||
| 1362 | /* no locking: HCD (i.e., we) own toggles, don't we? */ | ||
| 1363 | usb_settoggle(urb->dev, epnum, 0, rcvtog); | ||
| 1364 | usb_settoggle(urb->dev, epnum, 1, sndtog); | ||
| 1365 | |||
| 1382 | max3421_hcd->curr_urb = NULL; | 1366 | max3421_hcd->curr_urb = NULL; |
| 1383 | spin_lock_irqsave(&max3421_hcd->lock, flags); | 1367 | spin_lock_irqsave(&max3421_hcd->lock, flags); |
| 1384 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 1368 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
| @@ -1638,11 +1638,12 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) · 1637 unmodified lines | |||
| 1638 | * Inform the usbcore about resume-in-progress by returning | 1638 | * Inform the usbcore about resume-in-progress by returning |
| 1639 | * a non-zero value even if there are no status changes. | 1639 | * a non-zero value even if there are no status changes. |
| 1640 | */ | 1640 | */ |
| 1641 | spin_lock_irqsave(&xhci->lock, flags); | ||
| 1642 | |||
| 1641 | status = bus_state->resuming_ports; | 1643 | status = bus_state->resuming_ports; |
| 1642 | 1644 | ||
| 1643 | mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC; | 1645 | mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC; |
| 1644 | 1646 | ||
| 1645 | spin_lock_irqsave(&xhci->lock, flags); | ||
| 1646 | /* For each port, did anything change? If so, set that bit in buf. */ | 1647 | /* For each port, did anything change? If so, set that bit in buf. */ |
| 1647 | for (i = 0; i < max_ports; i++) { | 1648 | for (i = 0; i < max_ports; i++) { |
| 1648 | temp = readl(ports[i]->addr); | 1649 | temp = readl(ports[i]->addr); |
| @@ -207,8 +207,7 @@ static int renesas_check_rom_state(struct pci_dev *pdev) · 206 unmodified lines | |||
| 207 | return 0; | 207 | return 0; |
| 208 | 208 | ||
| 209 | case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */ | 209 | case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */ |
| 210 | dev_dbg(&pdev->dev, "Unknown ROM status ...\n"); | 210 | return 0; |
| 211 | break; | ||
| 212 | 211 | ||
| 213 | case RENESAS_ROM_STATUS_ERROR: /* Error State */ | 212 | case RENESAS_ROM_STATUS_ERROR: /* Error State */ |
| 214 | default: /* All other states are marked as "Reserved states" */ | 213 | default: /* All other states are marked as "Reserved states" */ |
| @@ -225,12 +224,13 @@ static int renesas_fw_check_running(struct pci_dev *pdev) · 10 unmodified lines | |||
| 225 | u8 fw_state; | 224 | u8 fw_state; |
| 226 | int err; | 225 | int err; |
| 227 | 226 | ||
| 228 | /* | 227 | /* Check if device has ROM and loaded, if so skip everything */ |
| 229 | * Only if device has ROM and loaded FW we can skip loading and | 228 | err = renesas_check_rom(pdev); |
| 230 | * return success. Otherwise (even unknown state), attempt to load FW. | 229 | if (err) { /* we have rom */ |
| 231 | */ | 230 | err = renesas_check_rom_state(pdev); |
| 232 | if (renesas_check_rom(pdev) && !renesas_check_rom_state(pdev)) | 231 | if (!err) |
| 233 | return 0; | 232 | return err; |
| 233 | } | ||
| 234 | 234 | ||
| 235 | /* | 235 | /* |
| 236 | * Test if the device is actually needing the firmware. As most | 236 | * Test if the device is actually needing the firmware. As most |
| @@ -636,7 +636,14 @@ static const struct pci_device_id pci_ids[] = { · 635 unmodified lines | |||
| 636 | { /* end: all zeroes */ } | 636 | { /* end: all zeroes */ } |
| 637 | }; | 637 | }; |
| 638 | MODULE_DEVICE_TABLE(pci, pci_ids); | 638 | MODULE_DEVICE_TABLE(pci, pci_ids); |
| 639 | |||
| 640 | /* | ||
| 641 | * Without CONFIG_USB_XHCI_PCI_RENESAS renesas_xhci_check_request_fw() won't | ||
| 642 | * load firmware, so don't encumber the xhci-pci driver with it. | ||
| 643 | */ | ||
| 644 | #if IS_ENABLED(CONFIG_USB_XHCI_PCI_RENESAS) | ||
| 639 | MODULE_FIRMWARE("renesas_usb_fw.mem"); | 645 | MODULE_FIRMWARE("renesas_usb_fw.mem"); |
| 646 | #endif | ||
| 640 | 647 | ||
| 641 | /* pci driver glue; this is a "new style" PCI driver module */ | 648 | /* pci driver glue; this is a "new style" PCI driver module */ |
| 642 | static struct pci_driver xhci_pci_driver = { | 649 | static struct pci_driver xhci_pci_driver = { |
| @@ -86,10 +86,10 @@ static struct usb_phy *__device_to_usb_phy(struct device *dev) · 85 unmodified lines | |||
| 86 | 86 | ||
| 87 | list_for_each_entry(usb_phy, &phy_list, head) { | 87 | list_for_each_entry(usb_phy, &phy_list, head) { |
| 88 | if (usb_phy->dev == dev) | 88 | if (usb_phy->dev == dev) |
| 89 | break; | 89 | return usb_phy; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | return usb_phy; | 92 | return NULL; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static void usb_phy_set_default_current(struct usb_phy *usb_phy) | 95 | static void usb_phy_set_default_current(struct usb_phy *usb_phy) |
| @@ -150,8 +150,14 @@ static int usb_phy_uevent(struct device *dev, struct kobj_uevent_env *env) · 54 unmodified lines | |||
| 150 | struct usb_phy *usb_phy; | 150 | struct usb_phy *usb_phy; |
| 151 | char uchger_state[50] = { 0 }; | 151 | char uchger_state[50] = { 0 }; |
| 152 | char uchger_type[50] = { 0 }; | 152 | char uchger_type[50] = { 0 }; |
| 153 | unsigned long flags; | ||
| 153 | 154 | ||
| 155 | spin_lock_irqsave(&phy_lock, flags); | ||
| 154 | usb_phy = __device_to_usb_phy(dev); | 156 | usb_phy = __device_to_usb_phy(dev); |
| 157 | spin_unlock_irqrestore(&phy_lock, flags); | ||
| 158 | |||
| 159 | if (!usb_phy) | ||
| 160 | return -ENODEV; | ||
| 155 | 161 | ||
| 156 | snprintf(uchger_state, ARRAY_SIZE(uchger_state), | 162 | snprintf(uchger_state, ARRAY_SIZE(uchger_state), |
| 157 | "USB_CHARGER_STATE=%s", usb_chger_state[usb_phy->chg_state]); | 163 | "USB_CHARGER_STATE=%s", usb_chger_state[usb_phy->chg_state]); |
| @@ -101,6 +101,8 @@ static struct dma_chan *usbhsf_dma_chan_get(struct usbhs_fifo *fifo, · 100 unmodified lines | |||
| 101 | #define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1) | 101 | #define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1) |
| 102 | #define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0) | 102 | #define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0) |
| 103 | static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map); | 103 | static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map); |
| 104 | static void usbhsf_tx_irq_ctrl(struct usbhs_pipe *pipe, int enable); | ||
| 105 | static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable); | ||
| 104 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) | 106 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) |
| 105 | { | 107 | { |
| 106 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 108 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
| @@ -123,6 +125,11 @@ struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) · 16 unmodified lines | |||
| 123 | if (chan) { | 125 | if (chan) { |
| 124 | dmaengine_terminate_all(chan); | 126 | dmaengine_terminate_all(chan); |
| 125 | usbhsf_dma_unmap(pkt); | 127 | usbhsf_dma_unmap(pkt); |
| 128 | } else { | ||
| 129 | if (usbhs_pipe_is_dir_in(pipe)) | ||
| 130 | usbhsf_rx_irq_ctrl(pipe, 0); | ||
| 131 | else | ||
| 132 | usbhsf_tx_irq_ctrl(pipe, 0); | ||
| 126 | } | 133 | } |
| 127 | 134 | ||
| 128 | usbhs_pipe_clear_without_sequence(pipe, 0, 0); | 135 | usbhs_pipe_clear_without_sequence(pipe, 0, 0); |
| @@ -155,6 +155,7 @@ static const struct usb_device_id id_table[] = { · 154 unmodified lines | |||
| 155 | { USB_DEVICE(0x10C4, 0x89A4) }, /* CESINEL FTBC Flexible Thyristor Bridge Controller */ | 155 | { USB_DEVICE(0x10C4, 0x89A4) }, /* CESINEL FTBC Flexible Thyristor Bridge Controller */ |
| 156 | { USB_DEVICE(0x10C4, 0x89FB) }, /* Qivicon ZigBee USB Radio Stick */ | 156 | { USB_DEVICE(0x10C4, 0x89FB) }, /* Qivicon ZigBee USB Radio Stick */ |
| 157 | { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ | 157 | { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ |
| 158 | { USB_DEVICE(0x10C4, 0x8A5B) }, /* CEL EM3588 ZigBee USB Stick */ | ||
| 158 | { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ | 159 | { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ |
| 159 | { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */ | 160 | { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */ |
| 160 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 161 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
| @@ -202,8 +203,8 @@ static const struct usb_device_id id_table[] = { · 41 unmodified lines | |||
| 202 | { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ | 203 | { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ |
| 203 | { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ | 204 | { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ |
| 204 | { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */ | 205 | { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */ |
| 205 | { USB_DEVICE(0x1901, 0x0197) }, /* GE CS1000 Display serial interface */ | 206 | { USB_DEVICE(0x1901, 0x0197) }, /* GE CS1000 M.2 Key E serial interface */ |
| 206 | { USB_DEVICE(0x1901, 0x0198) }, /* GE CS1000 M.2 Key E serial interface */ | 207 | { USB_DEVICE(0x1901, 0x0198) }, /* GE CS1000 Display serial interface */ |
| 207 | { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */ | 208 | { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */ |
| 208 | { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ | 209 | { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ |
| 209 | { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ | 210 | { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ |
| @@ -238,6 +238,7 @@ static void option_instat_callback(struct urb *urb); · 237 unmodified lines | |||
| 238 | #define QUECTEL_PRODUCT_UC15 0x9090 | 238 | #define QUECTEL_PRODUCT_UC15 0x9090 |
| 239 | /* These u-blox products use Qualcomm's vendor ID */ | 239 | /* These u-blox products use Qualcomm's vendor ID */ |
| 240 | #define UBLOX_PRODUCT_R410M 0x90b2 | 240 | #define UBLOX_PRODUCT_R410M 0x90b2 |
| 241 | #define UBLOX_PRODUCT_R6XX 0x90fa | ||
| 241 | /* These Yuga products use Qualcomm's vendor ID */ | 242 | /* These Yuga products use Qualcomm's vendor ID */ |
| 242 | #define YUGA_PRODUCT_CLM920_NC5 0x9625 | 243 | #define YUGA_PRODUCT_CLM920_NC5 0x9625 |
| 243 | 244 | ||
| @@ -1101,6 +1102,8 @@ static const struct usb_device_id option_ids[] = { · 857 unmodified lines | |||
| 1101 | /* u-blox products using Qualcomm vendor ID */ | 1102 | /* u-blox products using Qualcomm vendor ID */ |
| 1102 | { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), | 1103 | { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), |
| 1103 | .driver_info = RSVD(1) | RSVD(3) }, | 1104 | .driver_info = RSVD(1) | RSVD(3) }, |
| 1105 | { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R6XX), | ||
| 1106 | .driver_info = RSVD(3) }, | ||
| 1104 | /* Quectel products using Quectel vendor ID */ | 1107 | /* Quectel products using Quectel vendor ID */ |
| 1105 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21, 0xff, 0xff, 0xff), | 1108 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21, 0xff, 0xff, 0xff), |
| 1106 | .driver_info = NUMEP2 }, | 1109 | .driver_info = NUMEP2 }, |
| @@ -45,6 +45,13 @@ UNUSUAL_DEV(0x059f, 0x105f, 0x0000, 0x9999, · 44 unmodified lines | |||
| 45 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 45 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 46 | US_FL_NO_REPORT_OPCODES | US_FL_NO_SAME), | 46 | US_FL_NO_REPORT_OPCODES | US_FL_NO_SAME), |
| 47 | 47 | ||
| 48 | /* Reported-by: Julian Sikorski <belegdol@gmail.com> */ | ||
| 49 | UNUSUAL_DEV(0x059f, 0x1061, 0x0000, 0x9999, | ||
| 50 | "LaCie", | ||
| 51 | "Rugged USB3-FW", | ||
| 52 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 53 | US_FL_IGNORE_UAS), | ||
| 54 | |||
| 48 | /* | 55 | /* |
| 49 | * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI | 56 | * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI |
| 50 | * commands in UAS mode. Observed with the 1.28 firmware; are there others? | 57 | * commands in UAS mode. Observed with the 1.28 firmware; are there others? |
| @@ -685,6 +685,15 @@ static int stusb160x_probe(struct i2c_client *client) · 684 unmodified lines | |||
| 685 | if (!fwnode) | 685 | if (!fwnode) |
| 686 | return -ENODEV; | 686 | return -ENODEV; |
| 687 | 687 | ||
| 688 | /* | ||
| 689 | * This fwnode has a "compatible" property, but is never populated as a | ||
| 690 | * struct device. Instead we simply parse it to read the properties. | ||
| 691 | * This it breaks fw_devlink=on. To maintain backward compatibility | ||
| 692 | * with existing DT files, we work around this by deleting any | ||
| 693 | * fwnode_links to/from this fwnode. | ||
| 694 | */ | ||
| 695 | fw_devlink_purge_absent_suppliers(fwnode); | ||
| 696 | |||
| 688 | /* | 697 | /* |
| 689 | * When both VDD and VSYS power supplies are present, the low power | 698 | * When both VDD and VSYS power supplies are present, the low power |
| 690 | * supply VSYS is selected when VSYS voltage is above 3.1 V. | 699 | * supply VSYS is selected when VSYS voltage is above 3.1 V. |
| @@ -739,10 +748,6 @@ static int stusb160x_probe(struct i2c_client *client) · 48 unmodified lines | |||
| 739 | typec_set_pwr_opmode(chip->port, chip->pwr_opmode); | 748 | typec_set_pwr_opmode(chip->port, chip->pwr_opmode); |
| 740 | 749 | ||
| 741 | if (client->irq) { | 750 | if (client->irq) { |
| 742 | ret = stusb160x_irq_init(chip, client->irq); | ||
| 743 | if (ret) | ||
| 744 | goto port_unregister; | ||
| 745 | |||
| 746 | chip->role_sw = fwnode_usb_role_switch_get(fwnode); | 751 | chip->role_sw = fwnode_usb_role_switch_get(fwnode); |
| 747 | if (IS_ERR(chip->role_sw)) { | 752 | if (IS_ERR(chip->role_sw)) { |
| 748 | ret = PTR_ERR(chip->role_sw); | 753 | ret = PTR_ERR(chip->role_sw); |
| @@ -752,6 +757,10 @@ static int stusb160x_probe(struct i2c_client *client) · 3 unmodified lines | |||
| 752 | ret); | 757 | ret); |
| 753 | goto port_unregister; | 758 | goto port_unregister; |
| 754 | } | 759 | } |
| 760 | |||
| 761 | ret = stusb160x_irq_init(chip, client->irq); | ||
| 762 | if (ret) | ||
| 763 | goto role_sw_put; | ||
| 755 | } else { | 764 | } else { |
| 756 | /* | 765 | /* |
| 757 | * If Source or Dual power role, need to enable VDD supply | 766 | * If Source or Dual power role, need to enable VDD supply |
| @@ -775,6 +784,9 @@ static int stusb160x_probe(struct i2c_client *client) · 17 unmodified lines | |||
| 775 | 784 | ||
| 776 | return 0; | 785 | return 0; |
| 777 | 786 | ||
| 787 | role_sw_put: | ||
| 788 | if (chip->role_sw) | ||
| 789 | usb_role_switch_put(chip->role_sw); | ||
| 778 | port_unregister: | 790 | port_unregister: |
| 779 | typec_unregister_port(chip->port); | 791 | typec_unregister_port(chip->port); |
| 780 | all_reg_disable: | 792 | all_reg_disable: |
| @@ -629,6 +629,15 @@ static int tps6598x_probe(struct i2c_client *client) · 628 unmodified lines | |||
| 629 | if (!fwnode) | 629 | if (!fwnode) |
| 630 | return -ENODEV; | 630 | return -ENODEV; |
| 631 | 631 | ||
| 632 | /* | ||
| 633 | * This fwnode has a "compatible" property, but is never populated as a | ||
| 634 | * struct device. Instead we simply parse it to read the properties. | ||
| 635 | * This breaks fw_devlink=on. To maintain backward compatibility | ||
| 636 | * with existing DT files, we work around this by deleting any | ||
| 637 | * fwnode_links to/from this fwnode. | ||
| 638 | */ | ||
| 639 | fw_devlink_purge_absent_suppliers(fwnode); | ||
| 640 | |||
| 632 | tps->role_sw = fwnode_usb_role_switch_get(fwnode); | 641 | tps->role_sw = fwnode_usb_role_switch_get(fwnode); |
| 633 | if (IS_ERR(tps->role_sw)) { | 642 | if (IS_ERR(tps->role_sw)) { |
| 634 | ret = PTR_ERR(tps->role_sw); | 643 | ret = PTR_ERR(tps->role_sw); |
| @@ -168,21 +168,6 @@ config OSF4_COMPAT · 167 unmodified lines | |||
| 168 | with v4 shared libraries freely available from Compaq. If you're | 168 | with v4 shared libraries freely available from Compaq. If you're |
| 169 | going to use shared libraries from Tru64 version 5.0 or later, say N. | 169 | going to use shared libraries from Tru64 version 5.0 or later, say N. |
| 170 | 170 | ||
| 171 | config BINFMT_EM86 | ||
| 172 | tristate "Kernel support for Linux/Intel ELF binaries" | ||
| 173 | depends on ALPHA | ||
| 174 | help | ||
| 175 | Say Y here if you want to be able to execute Linux/Intel ELF | ||
| 176 | binaries just like native Alpha binaries on your Alpha machine. For | ||
| 177 | this to work, you need to have the emulator /usr/bin/em86 in place. | ||
| 178 | |||
| 179 | You can get the same functionality by saying N here and saying Y to | ||
| 180 | "Kernel support for MISC binaries". | ||
| 181 | |||
| 182 | You may answer M to compile the emulation support as a module and | ||
| 183 | later load the module when you want to use a Linux/Intel binary. The | ||
| 184 | module will be called binfmt_em86. If unsure, say Y. | ||
| 185 | |||
| 186 | config BINFMT_MISC | 171 | config BINFMT_MISC |
| 187 | tristate "Kernel support for MISC binaries" | 172 | tristate "Kernel support for MISC binaries" |
| 188 | help | 173 | help |
| @@ -39,7 +39,6 @@ obj-$(CONFIG_FS_ENCRYPTION) += crypto/ · 38 unmodified lines | |||
| 39 | obj-$(CONFIG_FS_VERITY) += verity/ | 39 | obj-$(CONFIG_FS_VERITY) += verity/ |
| 40 | obj-$(CONFIG_FILE_LOCKING) += locks.o | 40 | obj-$(CONFIG_FILE_LOCKING) += locks.o |
| 41 | obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o | 41 | obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o |
| 42 | obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o | ||
| 43 | obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o | 42 | obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o |
| 44 | obj-$(CONFIG_BINFMT_SCRIPT) += binfmt_script.o | 43 | obj-$(CONFIG_BINFMT_SCRIPT) += binfmt_script.o |
| 45 | obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o | 44 | obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o |
| @@ -29,16 +29,11 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *); · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | static int afs_deliver_yfs_cb_callback(struct afs_call *); | 30 | static int afs_deliver_yfs_cb_callback(struct afs_call *); |
| 31 | 31 | ||
| 32 | #define CM_NAME(name) \ | ||
| 33 | char afs_SRXCB##name##_name[] __tracepoint_string = \ | ||
| 34 | "CB." #name | ||
| 35 | |||
| 36 | /* | 32 | /* |
| 37 | * CB.CallBack operation type | 33 | * CB.CallBack operation type |
| 38 | */ | 34 | */ |
| 39 | static CM_NAME(CallBack); | ||
| 40 | static const struct afs_call_type afs_SRXCBCallBack = { | 35 | static const struct afs_call_type afs_SRXCBCallBack = { |
| 41 | .name = afs_SRXCBCallBack_name, | 36 | .name = "CB.CallBack", |
| 42 | .deliver = afs_deliver_cb_callback, | 37 | .deliver = afs_deliver_cb_callback, |
| 43 | .destructor = afs_cm_destructor, | 38 | .destructor = afs_cm_destructor, |
| 44 | .work = SRXAFSCB_CallBack, | 39 | .work = SRXAFSCB_CallBack, |
| @@ -47,9 +42,8 @@ static const struct afs_call_type afs_SRXCBCallBack = { · 2 unmodified lines | |||
| 47 | /* | 42 | /* |
| 48 | * CB.InitCallBackState operation type | 43 | * CB.InitCallBackState operation type |
| 49 | */ | 44 | */ |
| 50 | static CM_NAME(InitCallBackState); | ||
| 51 | static const struct afs_call_type afs_SRXCBInitCallBackState = { | 45 | static const struct afs_call_type afs_SRXCBInitCallBackState = { |
| 52 | .name = afs_SRXCBInitCallBackState_name, | 46 | .name = "CB.InitCallBackState", |
| 53 | .deliver = afs_deliver_cb_init_call_back_state, | 47 | .deliver = afs_deliver_cb_init_call_back_state, |
| 54 | .destructor = afs_cm_destructor, | 48 | .destructor = afs_cm_destructor, |
| 55 | .work = SRXAFSCB_InitCallBackState, | 49 | .work = SRXAFSCB_InitCallBackState, |
| @@ -58,9 +52,8 @@ static const struct afs_call_type afs_SRXCBInitCallBackState = { · 2 unmodified lines | |||
| 58 | /* | 52 | /* |
| 59 | * CB.InitCallBackState3 operation type | 53 | * CB.InitCallBackState3 operation type |
| 60 | */ | 54 | */ |
| 61 | static CM_NAME(InitCallBackState3); | ||
| 62 | static const struct afs_call_type afs_SRXCBInitCallBackState3 = { | 55 | static const struct afs_call_type afs_SRXCBInitCallBackState3 = { |
| 63 | .name = afs_SRXCBInitCallBackState3_name, | 56 | .name = "CB.InitCallBackState3", |
| 64 | .deliver = afs_deliver_cb_init_call_back_state3, | 57 | .deliver = afs_deliver_cb_init_call_back_state3, |
| 65 | .destructor = afs_cm_destructor, | 58 | .destructor = afs_cm_destructor, |
| 66 | .work = SRXAFSCB_InitCallBackState, | 59 | .work = SRXAFSCB_InitCallBackState, |
| @@ -69,9 +62,8 @@ static const struct afs_call_type afs_SRXCBInitCallBackState3 = { · 2 unmodified lines | |||
| 69 | /* | 62 | /* |
| 70 | * CB.Probe operation type | 63 | * CB.Probe operation type |
| 71 | */ | 64 | */ |
| 72 | static CM_NAME(Probe); | ||
| 73 | static const struct afs_call_type afs_SRXCBProbe = { | 65 | static const struct afs_call_type afs_SRXCBProbe = { |
| 74 | .name = afs_SRXCBProbe_name, | 66 | .name = "CB.Probe", |
| 75 | .deliver = afs_deliver_cb_probe, | 67 | .deliver = afs_deliver_cb_probe, |
| 76 | .destructor = afs_cm_destructor, | 68 | .destructor = afs_cm_destructor, |
| 77 | .work = SRXAFSCB_Probe, | 69 | .work = SRXAFSCB_Probe, |
| @@ -80,9 +72,8 @@ static const struct afs_call_type afs_SRXCBProbe = { · 2 unmodified lines | |||
| 80 | /* | 72 | /* |
| 81 | * CB.ProbeUuid operation type | 73 | * CB.ProbeUuid operation type |
| 82 | */ | 74 | */ |
| 83 | static CM_NAME(ProbeUuid); | ||
| 84 | static const struct afs_call_type afs_SRXCBProbeUuid = { | 75 | static const struct afs_call_type afs_SRXCBProbeUuid = { |
| 85 | .name = afs_SRXCBProbeUuid_name, | 76 | .name = "CB.ProbeUuid", |
| 86 | .deliver = afs_deliver_cb_probe_uuid, | 77 | .deliver = afs_deliver_cb_probe_uuid, |
| 87 | .destructor = afs_cm_destructor, | 78 | .destructor = afs_cm_destructor, |
| 88 | .work = SRXAFSCB_ProbeUuid, | 79 | .work = SRXAFSCB_ProbeUuid, |
| @@ -91,9 +82,8 @@ static const struct afs_call_type afs_SRXCBProbeUuid = { · 2 unmodified lines | |||
| 91 | /* | 82 | /* |
| 92 | * CB.TellMeAboutYourself operation type | 83 | * CB.TellMeAboutYourself operation type |
| 93 | */ | 84 | */ |
| 94 | static CM_NAME(TellMeAboutYourself); | ||
| 95 | static const struct afs_call_type afs_SRXCBTellMeAboutYourself = { | 85 | static const struct afs_call_type afs_SRXCBTellMeAboutYourself = { |
| 96 | .name = afs_SRXCBTellMeAboutYourself_name, | 86 | .name = "CB.TellMeAboutYourself", |
| 97 | .deliver = afs_deliver_cb_tell_me_about_yourself, | 87 | .deliver = afs_deliver_cb_tell_me_about_yourself, |
| 98 | .destructor = afs_cm_destructor, | 88 | .destructor = afs_cm_destructor, |
| 99 | .work = SRXAFSCB_TellMeAboutYourself, | 89 | .work = SRXAFSCB_TellMeAboutYourself, |
| @@ -102,9 +92,8 @@ static const struct afs_call_type afs_SRXCBTellMeAboutYourself = { · 2 unmodified lines | |||
| 102 | /* | 92 | /* |
| 103 | * YFS CB.CallBack operation type | 93 | * YFS CB.CallBack operation type |
| 104 | */ | 94 | */ |
| 105 | static CM_NAME(YFS_CallBack); | ||
| 106 | static const struct afs_call_type afs_SRXYFSCB_CallBack = { | 95 | static const struct afs_call_type afs_SRXYFSCB_CallBack = { |
| 107 | .name = afs_SRXCBYFS_CallBack_name, | 96 | .name = "YFSCB.CallBack", |
| 108 | .deliver = afs_deliver_yfs_cb_callback, | 97 | .deliver = afs_deliver_yfs_cb_callback, |
| 109 | .destructor = afs_cm_destructor, | 98 | .destructor = afs_cm_destructor, |
| 110 | .work = SRXAFSCB_CallBack, | 99 | .work = SRXAFSCB_CallBack, |
| @@ -656,7 +656,6 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry, · 655 unmodified lines | |||
| 656 | return ret; | 656 | return ret; |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | ret = -ENOENT; | ||
| 660 | if (!cookie.found) { | 659 | if (!cookie.found) { |
| 661 | _leave(" = -ENOENT [not found]"); | 660 | _leave(" = -ENOENT [not found]"); |
| 662 | return -ENOENT; | 661 | return -ENOENT; |
| @@ -2020,17 +2019,20 @@ static int afs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, · 1357 unmodified lines | |||
| 2020 | 2019 | ||
| 2021 | if (d_count(new_dentry) > 2) { | 2020 | if (d_count(new_dentry) > 2) { |
| 2022 | /* copy the target dentry's name */ | 2021 | /* copy the target dentry's name */ |
| 2023 | ret = -ENOMEM; | ||
| 2024 | op->rename.tmp = d_alloc(new_dentry->d_parent, | 2022 | op->rename.tmp = d_alloc(new_dentry->d_parent, |
| 2025 | &new_dentry->d_name); | 2023 | &new_dentry->d_name); |
| 2026 | if (!op->rename.tmp) | 2024 | if (!op->rename.tmp) { |
| 2025 | op->error = -ENOMEM; | ||
| 2027 | goto error; | 2026 | goto error; |
| 2027 | } | ||
| 2028 | 2028 | ||
| 2029 | ret = afs_sillyrename(new_dvnode, | 2029 | ret = afs_sillyrename(new_dvnode, |
| 2030 | AFS_FS_I(d_inode(new_dentry)), | 2030 | AFS_FS_I(d_inode(new_dentry)), |
| 2031 | new_dentry, op->key); | 2031 | new_dentry, op->key); |
| 2032 | if (ret) | 2032 | if (ret) { |
| 2033 | op->error = ret; | ||
| 2033 | goto error; | 2034 | goto error; |
| 2035 | } | ||
| 2034 | 2036 | ||
| 2035 | op->dentry_2 = op->rename.tmp; | 2037 | op->dentry_2 = op->rename.tmp; |
| 2036 | op->rename.rehash = NULL; | 2038 | op->rename.rehash = NULL; |
| @@ -771,14 +771,20 @@ int afs_writepages(struct address_space *mapping, · 770 unmodified lines | |||
| 771 | if (wbc->range_cyclic) { | 771 | if (wbc->range_cyclic) { |
| 772 | start = mapping->writeback_index * PAGE_SIZE; | 772 | start = mapping->writeback_index * PAGE_SIZE; |
| 773 | ret = afs_writepages_region(mapping, wbc, start, LLONG_MAX, &next); | 773 | ret = afs_writepages_region(mapping, wbc, start, LLONG_MAX, &next); |
| 774 | if (start > 0 && wbc->nr_to_write > 0 && ret == 0) | 774 | if (ret == 0) { |
| 775 | ret = afs_writepages_region(mapping, wbc, 0, start, | 775 | mapping->writeback_index = next / PAGE_SIZE; |
| 776 | &next); | 776 | if (start > 0 && wbc->nr_to_write > 0) { |
| 777 | mapping->writeback_index = next / PAGE_SIZE; | 777 | ret = afs_writepages_region(mapping, wbc, 0, |
| 778 | start, &next); | ||
| 779 | if (ret == 0) | ||
| 780 | mapping->writeback_index = | ||
| 781 | next / PAGE_SIZE; | ||
| 782 | } | ||
| 783 | } | ||
| 778 | } else if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) { | 784 | } else if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) { |
| 779 | ret = afs_writepages_region(mapping, wbc, 0, LLONG_MAX, &next); | 785 | ret = afs_writepages_region(mapping, wbc, 0, LLONG_MAX, &next); |
| 780 | if (wbc->nr_to_write > 0) | 786 | if (wbc->nr_to_write > 0 && ret == 0) |
| 781 | mapping->writeback_index = next; | 787 | mapping->writeback_index = next / PAGE_SIZE; |
| 782 | } else { | 788 | } else { |
| 783 | ret = afs_writepages_region(mapping, wbc, | 789 | ret = afs_writepages_region(mapping, wbc, |
| 784 | wbc->range_start, wbc->range_end, &next); | 790 | wbc->range_start, wbc->range_end, &next); |
| @@ -1,110 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * linux/fs/binfmt_em86.c | ||
| 4 | * | ||
| 5 | * Based on linux/fs/binfmt_script.c | ||
| 6 | * Copyright (C) 1996 Martin von Löwis | ||
| 7 | * original #!-checking implemented by tytso. | ||
| 8 | * | ||
| 9 | * em86 changes Copyright (C) 1997 Jim Paradis | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/string.h> | ||
| 14 | #include <linux/stat.h> | ||
| 15 | #include <linux/binfmts.h> | ||
| 16 | #include <linux/elf.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/fs.h> | ||
| 19 | #include <linux/file.h> | ||
| 20 | #include <linux/errno.h> | ||
| 21 | |||
| 22 | |||
| 23 | #define EM86_INTERP "/usr/bin/em86" | ||
| 24 | #define EM86_I_NAME "em86" | ||
| 25 | |||
| 26 | static int load_em86(struct linux_binprm *bprm) | ||
| 27 | { | ||
| 28 | const char *i_name, *i_arg; | ||
| 29 | char *interp; | ||
| 30 | struct file * file; | ||
| 31 | int retval; | ||
| 32 | struct elfhdr elf_ex; | ||
| 33 | |||
| 34 | /* Make sure this is a Linux/Intel ELF executable... */ | ||
| 35 | elf_ex = *((struct elfhdr *)bprm->buf); | ||
| 36 | |||
| 37 | if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0) | ||
| 38 | return -ENOEXEC; | ||
| 39 | |||
| 40 | /* First of all, some simple consistency checks */ | ||
| 41 | if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || | ||
| 42 | (!((elf_ex.e_machine == EM_386) || (elf_ex.e_machine == EM_486))) || | ||
| 43 | !bprm->file->f_op->mmap) { | ||
| 44 | return -ENOEXEC; | ||
| 45 | } | ||
| 46 | |||
| 47 | /* Need to be able to load the file after exec */ | ||
| 48 | if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE) | ||
| 49 | return -ENOENT; | ||
| 50 | |||
| 51 | /* Unlike in the script case, we don't have to do any hairy | ||
| 52 | * parsing to find our interpreter... it's hardcoded! | ||
| 53 | */ | ||
| 54 | interp = EM86_INTERP; | ||
| 55 | i_name = EM86_I_NAME; | ||
| 56 | i_arg = NULL; /* We reserve the right to add an arg later */ | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Splice in (1) the interpreter's name for argv[0] | ||
| 60 | * (2) (optional) argument to interpreter | ||
| 61 | * (3) filename of emulated file (replace argv[0]) | ||
| 62 | * | ||
| 63 | * This is done in reverse order, because of how the | ||
| 64 | * user environment and arguments are stored. | ||
| 65 | */ | ||
| 66 | remove_arg_zero(bprm); | ||
| 67 | retval = copy_string_kernel(bprm->filename, bprm); | ||
| 68 | if (retval < 0) return retval; | ||
| 69 | bprm->argc++; | ||
| 70 | if (i_arg) { | ||
| 71 | retval = copy_string_kernel(i_arg, bprm); | ||
| 72 | if (retval < 0) return retval; | ||
| 73 | bprm->argc++; | ||
| 74 | } | ||
| 75 | retval = copy_string_kernel(i_name, bprm); | ||
| 76 | if (retval < 0) return retval; | ||
| 77 | bprm->argc++; | ||
| 78 | |||
| 79 | /* | ||
| 80 | * OK, now restart the process with the interpreter's inode. | ||
| 81 | * Note that we use open_exec() as the name is now in kernel | ||
| 82 | * space, and we don't need to copy it. | ||
| 83 | */ | ||
| 84 | file = open_exec(interp); | ||
| 85 | if (IS_ERR(file)) | ||
| 86 | return PTR_ERR(file); | ||
| 87 | |||
| 88 | bprm->interpreter = file; | ||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | static struct linux_binfmt em86_format = { | ||
| 93 | .module = THIS_MODULE, | ||
| 94 | .load_binary = load_em86, | ||
| 95 | }; | ||
| 96 | |||
| 97 | static int __init init_em86_binfmt(void) | ||
| 98 | { | ||
| 99 | register_binfmt(&em86_format); | ||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | static void __exit exit_em86_binfmt(void) | ||
| 104 | { | ||
| 105 | unregister_binfmt(&em86_format); | ||
| 106 | } | ||
| 107 | |||
| 108 | core_initcall(init_em86_binfmt); | ||
| 109 | module_exit(exit_em86_binfmt); | ||
| 110 | MODULE_LICENSE("GPL"); | ||
| @@ -812,6 +812,8 @@ static void bdev_free_inode(struct inode *inode) · 811 unmodified lines | |||
| 812 | free_percpu(bdev->bd_stats); | 812 | free_percpu(bdev->bd_stats); |
| 813 | kfree(bdev->bd_meta_info); | 813 | kfree(bdev->bd_meta_info); |
| 814 | 814 | ||
| 815 | if (!bdev_is_partition(bdev)) | ||
| 816 | kfree(bdev->bd_disk); | ||
| 815 | kmem_cache_free(bdev_cachep, BDEV_I(inode)); | 817 | kmem_cache_free(bdev_cachep, BDEV_I(inode)); |
| 816 | } | 818 | } |
| 817 | 819 | ||
| @@ -1488,15 +1488,15 @@ static int btrfs_find_all_roots_safe(struct btrfs_trans_handle *trans, · 1487 unmodified lines | |||
| 1488 | int btrfs_find_all_roots(struct btrfs_trans_handle *trans, | 1488 | int btrfs_find_all_roots(struct btrfs_trans_handle *trans, |
| 1489 | struct btrfs_fs_info *fs_info, u64 bytenr, | 1489 | struct btrfs_fs_info *fs_info, u64 bytenr, |
| 1490 | u64 time_seq, struct ulist **roots, | 1490 | u64 time_seq, struct ulist **roots, |
| 1491 | bool ignore_offset) | 1491 | bool ignore_offset, bool skip_commit_root_sem) |
| 1492 | { | 1492 | { |
| 1493 | int ret; | 1493 | int ret; |
| 1494 | 1494 | ||
| 1495 | if (!trans) | 1495 | if (!trans && !skip_commit_root_sem) |
| 1496 | down_read(&fs_info->commit_root_sem); | 1496 | down_read(&fs_info->commit_root_sem); |
| 1497 | ret = btrfs_find_all_roots_safe(trans, fs_info, bytenr, | 1497 | ret = btrfs_find_all_roots_safe(trans, fs_info, bytenr, |
| 1498 | time_seq, roots, ignore_offset); | 1498 | time_seq, roots, ignore_offset); |
| 1499 | if (!trans) | 1499 | if (!trans && !skip_commit_root_sem) |
| 1500 | up_read(&fs_info->commit_root_sem); | 1500 | up_read(&fs_info->commit_root_sem); |
| 1501 | return ret; | 1501 | return ret; |
| 1502 | } | 1502 | } |
| @@ -47,7 +47,8 @@ int btrfs_find_all_leafs(struct btrfs_trans_handle *trans, · 46 unmodified lines | |||
| 47 | const u64 *extent_item_pos, bool ignore_offset); | 47 | const u64 *extent_item_pos, bool ignore_offset); |
| 48 | int btrfs_find_all_roots(struct btrfs_trans_handle *trans, | 48 | int btrfs_find_all_roots(struct btrfs_trans_handle *trans, |
| 49 | struct btrfs_fs_info *fs_info, u64 bytenr, | 49 | struct btrfs_fs_info *fs_info, u64 bytenr, |
| 50 | u64 time_seq, struct ulist **roots, bool ignore_offset); | 50 | u64 time_seq, struct ulist **roots, bool ignore_offset, |
| 51 | bool skip_commit_root_sem); | ||
| 51 | char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, | 52 | char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, |
| 52 | u32 name_len, unsigned long name_off, | 53 | u32 name_len, unsigned long name_off, |
| 53 | struct extent_buffer *eb_in, u64 parent, | 54 | struct extent_buffer *eb_in, u64 parent, |
| @@ -352,7 +352,7 @@ static void end_compressed_bio_write(struct bio *bio) · 351 unmodified lines | |||
| 352 | btrfs_record_physical_zoned(inode, cb->start, bio); | 352 | btrfs_record_physical_zoned(inode, cb->start, bio); |
| 353 | btrfs_writepage_endio_finish_ordered(BTRFS_I(inode), NULL, | 353 | btrfs_writepage_endio_finish_ordered(BTRFS_I(inode), NULL, |
| 354 | cb->start, cb->start + cb->len - 1, | 354 | cb->start, cb->start + cb->len - 1, |
| 355 | bio->bi_status == BLK_STS_OK); | 355 | !cb->errors); |
| 356 | 356 | ||
| 357 | end_compressed_writeback(inode, cb); | 357 | end_compressed_writeback(inode, cb); |
| 358 | /* note, our inode could be gone now */ | 358 | /* note, our inode could be gone now */ |
| @@ -974,7 +974,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, · 973 unmodified lines | |||
| 974 | kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref); | 974 | kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref); |
| 975 | 975 | ||
| 976 | if (qrecord_inserted) | 976 | if (qrecord_inserted) |
| 977 | btrfs_qgroup_trace_extent_post(fs_info, record); | 977 | btrfs_qgroup_trace_extent_post(trans, record); |
| 978 | 978 | ||
| 979 | return 0; | 979 | return 0; |
| 980 | } | 980 | } |
| @@ -1069,7 +1069,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, · 88 unmodified lines | |||
| 1069 | 1069 | ||
| 1070 | 1070 | ||
| 1071 | if (qrecord_inserted) | 1071 | if (qrecord_inserted) |
| 1072 | return btrfs_qgroup_trace_extent_post(fs_info, record); | 1072 | return btrfs_qgroup_trace_extent_post(trans, record); |
| 1073 | return 0; | 1073 | return 0; |
| 1074 | } | 1074 | } |
| 1075 | 1075 | ||
| @@ -209,7 +209,7 @@ void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb, · 208 unmodified lines | |||
| 209 | static void csum_tree_block(struct extent_buffer *buf, u8 *result) | 209 | static void csum_tree_block(struct extent_buffer *buf, u8 *result) |
| 210 | { | 210 | { |
| 211 | struct btrfs_fs_info *fs_info = buf->fs_info; | 211 | struct btrfs_fs_info *fs_info = buf->fs_info; |
| 212 | const int num_pages = fs_info->nodesize >> PAGE_SHIFT; | 212 | const int num_pages = num_extent_pages(buf); |
| 213 | const int first_page_part = min_t(u32, PAGE_SIZE, fs_info->nodesize); | 213 | const int first_page_part = min_t(u32, PAGE_SIZE, fs_info->nodesize); |
| 214 | SHASH_DESC_ON_STACK(shash, fs_info->csum_shash); | 214 | SHASH_DESC_ON_STACK(shash, fs_info->csum_shash); |
| 215 | char *kaddr; | 215 | char *kaddr; |
| @@ -6019,6 +6019,9 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) · 6018 unmodified lines | |||
| 6019 | mutex_lock(&fs_info->fs_devices->device_list_mutex); | 6019 | mutex_lock(&fs_info->fs_devices->device_list_mutex); |
| 6020 | devices = &fs_info->fs_devices->devices; | 6020 | devices = &fs_info->fs_devices->devices; |
| 6021 | list_for_each_entry(device, devices, dev_list) { | 6021 | list_for_each_entry(device, devices, dev_list) { |
| 6022 | if (test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)) | ||
| 6023 | continue; | ||
| 6024 | |||
| 6022 | ret = btrfs_trim_free_extents(device, &group_trimmed); | 6025 | ret = btrfs_trim_free_extents(device, &group_trimmed); |
| 6023 | if (ret) { | 6026 | if (ret) { |
| 6024 | dev_failed++; | 6027 | dev_failed++; |
| @@ -2992,7 +2992,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) · 2991 unmodified lines | |||
| 2992 | goto out; | 2992 | goto out; |
| 2993 | } | 2993 | } |
| 2994 | 2994 | ||
| 2995 | if (ordered_extent->disk) | 2995 | if (ordered_extent->bdev) |
| 2996 | btrfs_rewrite_logical_zoned(ordered_extent); | 2996 | btrfs_rewrite_logical_zoned(ordered_extent); |
| 2997 | 2997 | ||
| 2998 | btrfs_free_io_failure_record(inode, start, end); | 2998 | btrfs_free_io_failure_record(inode, start, end); |
| @@ -190,8 +190,6 @@ static int __btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset · 189 unmodified lines | |||
| 190 | entry->truncated_len = (u64)-1; | 190 | entry->truncated_len = (u64)-1; |
| 191 | entry->qgroup_rsv = ret; | 191 | entry->qgroup_rsv = ret; |
| 192 | entry->physical = (u64)-1; | 192 | entry->physical = (u64)-1; |
| 193 | entry->disk = NULL; | ||
| 194 | entry->partno = (u8)-1; | ||
| 195 | 193 | ||
| 196 | ASSERT(type == BTRFS_ORDERED_REGULAR || | 194 | ASSERT(type == BTRFS_ORDERED_REGULAR || |
| 197 | type == BTRFS_ORDERED_NOCOW || | 195 | type == BTRFS_ORDERED_NOCOW || |
| @@ -145,8 +145,7 @@ struct btrfs_ordered_extent { · 144 unmodified lines | |||
| 145 | * command in a workqueue context | 145 | * command in a workqueue context |
| 146 | */ | 146 | */ |
| 147 | u64 physical; | 147 | u64 physical; |
| 148 | struct gendisk *disk; | 148 | struct block_device *bdev; |
| 149 | u8 partno; | ||
| 150 | }; | 149 | }; |
| 151 | 150 | ||
| 152 | /* | 151 | /* |
| @@ -1704,17 +1704,39 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info, · 1703 unmodified lines | |||
| 1704 | return 0; | 1704 | return 0; |
| 1705 | } | 1705 | } |
| 1706 | 1706 | ||
| 1707 | int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info, | 1707 | int btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans, |
| 1708 | struct btrfs_qgroup_extent_record *qrecord) | 1708 | struct btrfs_qgroup_extent_record *qrecord) |
| 1709 | { | 1709 | { |
| 1710 | struct ulist *old_root; | 1710 | struct ulist *old_root; |
| 1711 | u64 bytenr = qrecord->bytenr; | 1711 | u64 bytenr = qrecord->bytenr; |
| 1712 | int ret; | 1712 | int ret; |
| 1713 | 1713 | ||
| 1714 | ret = btrfs_find_all_roots(NULL, fs_info, bytenr, 0, &old_root, false); | 1714 | /* |
| 1715 | * We are always called in a context where we are already holding a | ||
| 1716 | * transaction handle. Often we are called when adding a data delayed | ||
| 1717 | * reference from btrfs_truncate_inode_items() (truncating or unlinking), | ||
| 1718 | * in which case we will be holding a write lock on extent buffer from a | ||
| 1719 | * subvolume tree. In this case we can't allow btrfs_find_all_roots() to | ||
| 1720 | * acquire fs_info->commit_root_sem, because that is a higher level lock | ||
| 1721 | * that must be acquired before locking any extent buffers. | ||
| 1722 | * | ||
| 1723 | * So we want btrfs_find_all_roots() to not acquire the commit_root_sem | ||
| 1724 | * but we can't pass it a non-NULL transaction handle, because otherwise | ||
| 1725 | * it would not use commit roots and would lock extent buffers, causing | ||
| 1726 | * a deadlock if it ends up trying to read lock the same extent buffer | ||
| 1727 | * that was previously write locked at btrfs_truncate_inode_items(). | ||
| 1728 | * | ||
| 1729 | * So pass a NULL transaction handle to btrfs_find_all_roots() and | ||
| 1730 | * explicitly tell it to not acquire the commit_root_sem - if we are | ||
| 1731 | * holding a transaction handle we don't need its protection. | ||
| 1732 | */ | ||
| 1733 | ASSERT(trans != NULL); | ||
| 1734 | |||
| 1735 | ret = btrfs_find_all_roots(NULL, trans->fs_info, bytenr, 0, &old_root, | ||
| 1736 | false, true); | ||
| 1715 | if (ret < 0) { | 1737 | if (ret < 0) { |
| 1716 | fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT; | 1738 | trans->fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT; |
| 1717 | btrfs_warn(fs_info, | 1739 | btrfs_warn(trans->fs_info, |
| 1718 | "error accounting new delayed refs extent (err code: %d), quota inconsistent", | 1740 | "error accounting new delayed refs extent (err code: %d), quota inconsistent", |
| 1719 | ret); | 1741 | ret); |
| 1720 | return 0; | 1742 | return 0; |
| @@ -1758,7 +1780,7 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr, · 37 unmodified lines | |||
| 1758 | kfree(record); | 1780 | kfree(record); |
| 1759 | return 0; | 1781 | return 0; |
| 1760 | } | 1782 | } |
| 1761 | return btrfs_qgroup_trace_extent_post(fs_info, record); | 1783 | return btrfs_qgroup_trace_extent_post(trans, record); |
| 1762 | } | 1784 | } |
| 1763 | 1785 | ||
| 1764 | int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans, | 1786 | int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans, |
| @@ -2629,7 +2651,7 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans) · 864 unmodified lines | |||
| 2629 | /* Search commit root to find old_roots */ | 2651 | /* Search commit root to find old_roots */ |
| 2630 | ret = btrfs_find_all_roots(NULL, fs_info, | 2652 | ret = btrfs_find_all_roots(NULL, fs_info, |
| 2631 | record->bytenr, 0, | 2653 | record->bytenr, 0, |
| 2632 | &record->old_roots, false); | 2654 | &record->old_roots, false, false); |
| 2633 | if (ret < 0) | 2655 | if (ret < 0) |
| 2634 | goto cleanup; | 2656 | goto cleanup; |
| 2635 | } | 2657 | } |
| @@ -2645,7 +2667,7 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans) · 9 unmodified lines | |||
| 2645 | * current root. It's safe inside commit_transaction(). | 2667 | * current root. It's safe inside commit_transaction(). |
| 2646 | */ | 2668 | */ |
| 2647 | ret = btrfs_find_all_roots(trans, fs_info, | 2669 | ret = btrfs_find_all_roots(trans, fs_info, |
| 2648 | record->bytenr, BTRFS_SEQ_LAST, &new_roots, false); | 2670 | record->bytenr, BTRFS_SEQ_LAST, &new_roots, false, false); |
| 2649 | if (ret < 0) | 2671 | if (ret < 0) |
| 2650 | goto cleanup; | 2672 | goto cleanup; |
| 2651 | if (qgroup_to_skip) { | 2673 | if (qgroup_to_skip) { |
| @@ -3179,7 +3201,7 @@ static int qgroup_rescan_leaf(struct btrfs_trans_handle *trans, · 527 unmodified lines | |||
| 3179 | num_bytes = found.offset; | 3201 | num_bytes = found.offset; |
| 3180 | 3202 | ||
| 3181 | ret = btrfs_find_all_roots(NULL, fs_info, found.objectid, 0, | 3203 | ret = btrfs_find_all_roots(NULL, fs_info, found.objectid, 0, |
| 3182 | &roots, false); | 3204 | &roots, false, false); |
| 3183 | if (ret < 0) | 3205 | if (ret < 0) |
| 3184 | goto out; | 3206 | goto out; |
| 3185 | /* For rescan, just pass old_roots as NULL */ | 3207 | /* For rescan, just pass old_roots as NULL */ |
| @@ -298,7 +298,7 @@ int btrfs_qgroup_trace_extent_nolock( · 297 unmodified lines | |||
| 298 | * using current root, then we can move all expensive backref walk out of | 298 | * using current root, then we can move all expensive backref walk out of |
| 299 | * transaction committing, but not now as qgroup accounting will be wrong again. | 299 | * transaction committing, but not now as qgroup accounting will be wrong again. |
| 300 | */ | 300 | */ |
| 301 | int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info, | 301 | int btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans, |
| 302 | struct btrfs_qgroup_extent_record *qrecord); | 302 | struct btrfs_qgroup_extent_record *qrecord); |
| 303 | 303 | ||
| 304 | /* | 304 | /* |
| @@ -224,7 +224,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root, · 223 unmodified lines | |||
| 224 | * quota. | 224 | * quota. |
| 225 | */ | 225 | */ |
| 226 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, | 226 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 227 | false); | 227 | false, false); |
| 228 | if (ret) { | 228 | if (ret) { |
| 229 | ulist_free(old_roots); | 229 | ulist_free(old_roots); |
| 230 | test_err("couldn't find old roots: %d", ret); | 230 | test_err("couldn't find old roots: %d", ret); |
| @@ -237,7 +237,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root, · 6 unmodified lines | |||
| 237 | return ret; | 237 | return ret; |
| 238 | 238 | ||
| 239 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, | 239 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 240 | false); | 240 | false, false); |
| 241 | if (ret) { | 241 | if (ret) { |
| 242 | ulist_free(old_roots); | 242 | ulist_free(old_roots); |
| 243 | ulist_free(new_roots); | 243 | ulist_free(new_roots); |
| @@ -261,7 +261,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root, · 17 unmodified lines | |||
| 261 | new_roots = NULL; | 261 | new_roots = NULL; |
| 262 | 262 | ||
| 263 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, | 263 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 264 | false); | 264 | false, false); |
| 265 | if (ret) { | 265 | if (ret) { |
| 266 | ulist_free(old_roots); | 266 | ulist_free(old_roots); |
| 267 | test_err("couldn't find old roots: %d", ret); | 267 | test_err("couldn't find old roots: %d", ret); |
| @@ -273,7 +273,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root, · 5 unmodified lines | |||
| 273 | return -EINVAL; | 273 | return -EINVAL; |
| 274 | 274 | ||
| 275 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, | 275 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 276 | false); | 276 | false, false); |
| 277 | if (ret) { | 277 | if (ret) { |
| 278 | ulist_free(old_roots); | 278 | ulist_free(old_roots); |
| 279 | ulist_free(new_roots); | 279 | ulist_free(new_roots); |
| @@ -325,7 +325,7 @@ static int test_multiple_refs(struct btrfs_root *root, · 45 unmodified lines | |||
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, | 327 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 328 | false); | 328 | false, false); |
| 329 | if (ret) { | 329 | if (ret) { |
| 330 | ulist_free(old_roots); | 330 | ulist_free(old_roots); |
| 331 | test_err("couldn't find old roots: %d", ret); | 331 | test_err("couldn't find old roots: %d", ret); |
| @@ -338,7 +338,7 @@ static int test_multiple_refs(struct btrfs_root *root, · 6 unmodified lines | |||
| 338 | return ret; | 338 | return ret; |
| 339 | 339 | ||
| 340 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, | 340 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 341 | false); | 341 | false, false); |
| 342 | if (ret) { | 342 | if (ret) { |
| 343 | ulist_free(old_roots); | 343 | ulist_free(old_roots); |
| 344 | ulist_free(new_roots); | 344 | ulist_free(new_roots); |
| @@ -360,7 +360,7 @@ static int test_multiple_refs(struct btrfs_root *root, · 15 unmodified lines | |||
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, | 362 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 363 | false); | 363 | false, false); |
| 364 | if (ret) { | 364 | if (ret) { |
| 365 | ulist_free(old_roots); | 365 | ulist_free(old_roots); |
| 366 | test_err("couldn't find old roots: %d", ret); | 366 | test_err("couldn't find old roots: %d", ret); |
| @@ -373,7 +373,7 @@ static int test_multiple_refs(struct btrfs_root *root, · 6 unmodified lines | |||
| 373 | return ret; | 373 | return ret; |
| 374 | 374 | ||
| 375 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, | 375 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 376 | false); | 376 | false, false); |
| 377 | if (ret) { | 377 | if (ret) { |
| 378 | ulist_free(old_roots); | 378 | ulist_free(old_roots); |
| 379 | ulist_free(new_roots); | 379 | ulist_free(new_roots); |
| @@ -401,7 +401,7 @@ static int test_multiple_refs(struct btrfs_root *root, · 21 unmodified lines | |||
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, | 403 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 404 | false); | 404 | false, false); |
| 405 | if (ret) { | 405 | if (ret) { |
| 406 | ulist_free(old_roots); | 406 | ulist_free(old_roots); |
| 407 | test_err("couldn't find old roots: %d", ret); | 407 | test_err("couldn't find old roots: %d", ret); |
| @@ -414,7 +414,7 @@ static int test_multiple_refs(struct btrfs_root *root, · 6 unmodified lines | |||
| 414 | return ret; | 414 | return ret; |
| 415 | 415 | ||
| 416 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, | 416 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 417 | false); | 417 | false, false); |
| 418 | if (ret) { | 418 | if (ret) { |
| 419 | ulist_free(old_roots); | 419 | ulist_free(old_roots); |
| 420 | ulist_free(new_roots); | 420 | ulist_free(new_roots); |
| @@ -5526,16 +5526,29 @@ log_extents: · 5525 unmodified lines | |||
| 5526 | spin_lock(&inode->lock); | 5526 | spin_lock(&inode->lock); |
| 5527 | inode->logged_trans = trans->transid; | 5527 | inode->logged_trans = trans->transid; |
| 5528 | /* | 5528 | /* |
| 5529 | * Don't update last_log_commit if we logged that an inode exists | 5529 | * Don't update last_log_commit if we logged that an inode exists. |
| 5530 | * after it was loaded to memory (full_sync bit set). | 5530 | * We do this for two reasons: |
| 5531 | * This is to prevent data loss when we do a write to the inode, | 5531 | * |
| 5532 | * then the inode gets evicted after all delalloc was flushed, | 5532 | * 1) We might have had buffered writes to this inode that were |
| 5533 | * then we log it exists (due to a rename for example) and then | 5533 | * flushed and had their ordered extents completed in this |
| 5534 | * fsync it. This last fsync would do nothing (not logging the | 5534 | * transaction, but we did not previously log the inode with |
| 5535 | * extents previously written). | 5535 | * LOG_INODE_ALL. Later the inode was evicted and after that |
| 5536 | * it was loaded again and this LOG_INODE_EXISTS log operation | ||
| 5537 | * happened. We must make sure that if an explicit fsync against | ||
| 5538 | * the inode is performed later, it logs the new extents, an | ||
| 5539 | * updated inode item, etc, and syncs the log. The same logic | ||
| 5540 | * applies to direct IO writes instead of buffered writes. | ||
| 5541 | * | ||
| 5542 | * 2) When we log the inode with LOG_INODE_EXISTS, its inode item | ||
| 5543 | * is logged with an i_size of 0 or whatever value was logged | ||
| 5544 | * before. If later the i_size of the inode is increased by a | ||
| 5545 | * truncate operation, the log is synced through an fsync of | ||
| 5546 | * some other inode and then finally an explicit fsync against | ||
| 5547 | * this inode is made, we must make sure this fsync logs the | ||
| 5548 | * inode with the new i_size, the hole between old i_size and | ||
| 5549 | * the new i_size, and syncs the log. | ||
| 5536 | */ | 5550 | */ |
| 5537 | if (inode_only != LOG_INODE_EXISTS || | 5551 | if (inode_only != LOG_INODE_EXISTS) |
| 5538 | !test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags)) | ||
| 5539 | inode->last_log_commit = inode->last_sub_trans; | 5552 | inode->last_log_commit = inode->last_sub_trans; |
| 5540 | spin_unlock(&inode->lock); | 5553 | spin_unlock(&inode->lock); |
| 5541 | } | 5554 | } |
| @@ -6490,8 +6503,8 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans, · 948 unmodified lines | |||
| 6490 | * if this inode hasn't been logged and directory we're renaming it | 6503 | * if this inode hasn't been logged and directory we're renaming it |
| 6491 | * from hasn't been logged, we don't need to log it | 6504 | * from hasn't been logged, we don't need to log it |
| 6492 | */ | 6505 | */ |
| 6493 | if (inode->logged_trans < trans->transid && | 6506 | if (!inode_logged(trans, inode) && |
| 6494 | (!old_dir || old_dir->logged_trans < trans->transid)) | 6507 | (!old_dir || !inode_logged(trans, old_dir))) |
| 6495 | return; | 6508 | return; |
| 6496 | 6509 | ||
| 6497 | /* | 6510 | /* |
| @@ -1078,6 +1078,7 @@ static void __btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices, · 1077 unmodified lines | |||
| 1078 | if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) { | 1078 | if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) { |
| 1079 | list_del_init(&device->dev_alloc_list); | 1079 | list_del_init(&device->dev_alloc_list); |
| 1080 | clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state); | 1080 | clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state); |
| 1081 | fs_devices->rw_devices--; | ||
| 1081 | } | 1082 | } |
| 1082 | list_del_init(&device->dev_list); | 1083 | list_del_init(&device->dev_list); |
| 1083 | fs_devices->num_devices--; | 1084 | fs_devices->num_devices--; |
| @@ -1349,8 +1349,7 @@ void btrfs_record_physical_zoned(struct inode *inode, u64 file_offset, · 1348 unmodified lines | |||
| 1349 | return; | 1349 | return; |
| 1350 | 1350 | ||
| 1351 | ordered->physical = physical; | 1351 | ordered->physical = physical; |
| 1352 | ordered->disk = bio->bi_bdev->bd_disk; | 1352 | ordered->bdev = bio->bi_bdev; |
| 1353 | ordered->partno = bio->bi_bdev->bd_partno; | ||
| 1354 | 1353 | ||
| 1355 | btrfs_put_ordered_extent(ordered); | 1354 | btrfs_put_ordered_extent(ordered); |
| 1356 | } | 1355 | } |
| @@ -1362,18 +1361,16 @@ void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered) · 5 unmodified lines | |||
| 1362 | struct extent_map_tree *em_tree; | 1361 | struct extent_map_tree *em_tree; |
| 1363 | struct extent_map *em; | 1362 | struct extent_map *em; |
| 1364 | struct btrfs_ordered_sum *sum; | 1363 | struct btrfs_ordered_sum *sum; |
| 1365 | struct block_device *bdev; | ||
| 1366 | u64 orig_logical = ordered->disk_bytenr; | 1364 | u64 orig_logical = ordered->disk_bytenr; |
| 1367 | u64 *logical = NULL; | 1365 | u64 *logical = NULL; |
| 1368 | int nr, stripe_len; | 1366 | int nr, stripe_len; |
| 1369 | 1367 | ||
| 1370 | /* Zoned devices should not have partitions. So, we can assume it is 0 */ | 1368 | /* Zoned devices should not have partitions. So, we can assume it is 0 */ |
| 1371 | ASSERT(ordered->partno == 0); | 1369 | ASSERT(!bdev_is_partition(ordered->bdev)); |
| 1372 | bdev = bdgrab(ordered->disk->part0); | 1370 | if (WARN_ON(!ordered->bdev)) |
| 1373 | if (WARN_ON(!bdev)) | ||
| 1374 | return; | 1371 | return; |
| 1375 | 1372 | ||
| 1376 | if (WARN_ON(btrfs_rmap_block(fs_info, orig_logical, bdev, | 1373 | if (WARN_ON(btrfs_rmap_block(fs_info, orig_logical, ordered->bdev, |
| 1377 | ordered->physical, &logical, &nr, | 1374 | ordered->physical, &logical, &nr, |
| 1378 | &stripe_len))) | 1375 | &stripe_len))) |
| 1379 | goto out; | 1376 | goto out; |
| @@ -1402,7 +1399,6 @@ void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered) · 22 unmodified lines | |||
| 1402 | 1399 | ||
| 1403 | out: | 1400 | out: |
| 1404 | kfree(logical); | 1401 | kfree(logical); |
| 1405 | bdput(bdev); | ||
| 1406 | } | 1402 | } |
| 1407 | 1403 | ||
| 1408 | bool btrfs_check_meta_write_pointer(struct btrfs_fs_info *fs_info, | 1404 | bool btrfs_check_meta_write_pointer(struct btrfs_fs_info *fs_info, |
| @@ -4456,7 +4456,7 @@ bool check_session_state(struct ceph_mds_session *s) · 4455 unmodified lines | |||
| 4456 | break; | 4456 | break; |
| 4457 | case CEPH_MDS_SESSION_CLOSING: | 4457 | case CEPH_MDS_SESSION_CLOSING: |
| 4458 | /* Should never reach this when we're unmounting */ | 4458 | /* Should never reach this when we're unmounting */ |
| 4459 | WARN_ON_ONCE(true); | 4459 | WARN_ON_ONCE(s->s_ttl); |
| 4460 | fallthrough; | 4460 | fallthrough; |
| 4461 | case CEPH_MDS_SESSION_NEW: | 4461 | case CEPH_MDS_SESSION_NEW: |
| 4462 | case CEPH_MDS_SESSION_RESTARTING: | 4462 | case CEPH_MDS_SESSION_RESTARTING: |
| @@ -873,8 +873,11 @@ PsxDelete: · 872 unmodified lines | |||
| 873 | InformationLevel) - 4; | 873 | InformationLevel) - 4; |
| 874 | offset = param_offset + params; | 874 | offset = param_offset + params; |
| 875 | 875 | ||
| 876 | /* Setup pointer to Request Data (inode type) */ | 876 | /* Setup pointer to Request Data (inode type). |
| 877 | pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset); | 877 | * Note that SMB offsets are from the beginning of SMB which is 4 bytes |
| 878 | * in, after RFC1001 field | ||
| 879 | */ | ||
| 880 | pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4); | ||
| 878 | pRqD->type = cpu_to_le16(type); | 881 | pRqD->type = cpu_to_le16(type); |
| 879 | pSMB->ParameterOffset = cpu_to_le16(param_offset); | 882 | pSMB->ParameterOffset = cpu_to_le16(param_offset); |
| 880 | pSMB->DataOffset = cpu_to_le16(offset); | 883 | pSMB->DataOffset = cpu_to_le16(offset); |
| @@ -1081,7 +1084,8 @@ PsxCreat: · 200 unmodified lines | |||
| 1081 | param_offset = offsetof(struct smb_com_transaction2_spi_req, | 1084 | param_offset = offsetof(struct smb_com_transaction2_spi_req, |
| 1082 | InformationLevel) - 4; | 1085 | InformationLevel) - 4; |
| 1083 | offset = param_offset + params; | 1086 | offset = param_offset + params; |
| 1084 | pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); | 1087 | /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ |
| 1088 | pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4); | ||
| 1085 | pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); | 1089 | pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); |
| 1086 | pdata->Permissions = cpu_to_le64(mode); | 1090 | pdata->Permissions = cpu_to_le64(mode); |
| 1087 | pdata->PosixOpenFlags = cpu_to_le32(posix_flags); | 1091 | pdata->PosixOpenFlags = cpu_to_le32(posix_flags); |
| @@ -220,7 +220,7 @@ cifs_reconnect(struct TCP_Server_Info *server) · 219 unmodified lines | |||
| 220 | #ifdef CONFIG_CIFS_DFS_UPCALL | 220 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 221 | struct super_block *sb = NULL; | 221 | struct super_block *sb = NULL; |
| 222 | struct cifs_sb_info *cifs_sb = NULL; | 222 | struct cifs_sb_info *cifs_sb = NULL; |
| 223 | struct dfs_cache_tgt_list tgt_list = {0}; | 223 | struct dfs_cache_tgt_list tgt_list = DFS_CACHE_TGT_LIST_INIT(tgt_list); |
| 224 | struct dfs_cache_tgt_iterator *tgt_it = NULL; | 224 | struct dfs_cache_tgt_iterator *tgt_it = NULL; |
| 225 | #endif | 225 | #endif |
| 226 | 226 | ||
| @@ -3130,7 +3130,7 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_ · 2903 unmodified lines | |||
| 3130 | { | 3130 | { |
| 3131 | int rc; | 3131 | int rc; |
| 3132 | char *npath = NULL; | 3132 | char *npath = NULL; |
| 3133 | struct dfs_cache_tgt_list tgt_list = {0}; | 3133 | struct dfs_cache_tgt_list tgt_list = DFS_CACHE_TGT_LIST_INIT(tgt_list); |
| 3134 | struct dfs_cache_tgt_iterator *tgt_it = NULL; | 3134 | struct dfs_cache_tgt_iterator *tgt_it = NULL; |
| 3135 | struct smb3_fs_context tmp_ctx = {NULL}; | 3135 | struct smb3_fs_context tmp_ctx = {NULL}; |
| 3136 | 3136 | ||
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include "cifs_debug.h" | 19 | #include "cifs_debug.h" |
| 20 | #include "cifs_unicode.h" | 20 | #include "cifs_unicode.h" |
| 21 | #include "smb2glob.h" | 21 | #include "smb2glob.h" |
| 22 | #include "dns_resolve.h" | ||
| 22 | 23 | ||
| 23 | #include "dfs_cache.h" | 24 | #include "dfs_cache.h" |
| 24 | 25 | ||
| @@ -911,6 +912,7 @@ static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl) · 886 unmodified lines | |||
| 911 | 912 | ||
| 912 | err_free_it: | 913 | err_free_it: |
| 913 | list_for_each_entry_safe(it, nit, head, it_list) { | 914 | list_for_each_entry_safe(it, nit, head, it_list) { |
| 915 | list_del(&it->it_list); | ||
| 914 | kfree(it->it_name); | 916 | kfree(it->it_name); |
| 915 | kfree(it); | 917 | kfree(it); |
| 916 | } | 918 | } |
| @@ -1293,6 +1295,194 @@ int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, · 376 unmodified lines | |||
| 1293 | return 0; | 1295 | return 0; |
| 1294 | } | 1296 | } |
| 1295 | 1297 | ||
| 1298 | static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, const char *s2) | ||
| 1299 | { | ||
| 1300 | char unc[sizeof("\\\\") + SERVER_NAME_LENGTH] = {0}; | ||
| 1301 | const char *host; | ||
| 1302 | size_t hostlen; | ||
| 1303 | char *ip = NULL; | ||
| 1304 | struct sockaddr sa; | ||
| 1305 | bool match; | ||
| 1306 | int rc; | ||
| 1307 | |||
| 1308 | if (strcasecmp(s1, s2)) | ||
| 1309 | return false; | ||
| 1310 | |||
| 1311 | /* | ||
| 1312 | * Resolve share's hostname and check if server address matches. Otherwise just ignore it | ||
| 1313 | * as we could not have upcall to resolve hostname or failed to convert ip address. | ||
| 1314 | */ | ||
| 1315 | match = true; | ||
| 1316 | extract_unc_hostname(s1, &host, &hostlen); | ||
| 1317 | scnprintf(unc, sizeof(unc), "\\\\%.*s", (int)hostlen, host); | ||
| 1318 | |||
| 1319 | rc = dns_resolve_server_name_to_ip(unc, &ip, NULL); | ||
| 1320 | if (rc < 0) { | ||
| 1321 | cifs_dbg(FYI, "%s: could not resolve %.*s. assuming server address matches.\n", | ||
| 1322 | __func__, (int)hostlen, host); | ||
| 1323 | return true; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | if (!cifs_convert_address(&sa, ip, strlen(ip))) { | ||
| 1327 | cifs_dbg(VFS, "%s: failed to convert address \'%s\'. skip address matching.\n", | ||
| 1328 | __func__, ip); | ||
| 1329 | } else { | ||
| 1330 | mutex_lock(&server->srv_mutex); | ||
| 1331 | match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, &sa); | ||
| 1332 | mutex_unlock(&server->srv_mutex); | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | kfree(ip); | ||
| 1336 | return match; | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | /* | ||
| 1340 | * Mark dfs tcon for reconnecting when the currently connected tcon does not match any of the new | ||
| 1341 | * target shares in @refs. | ||
| 1342 | */ | ||
| 1343 | static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cache_tgt_list *tl, | ||
| 1344 | const struct dfs_info3_param *refs, int numrefs) | ||
| 1345 | { | ||
| 1346 | struct dfs_cache_tgt_iterator *it; | ||
| 1347 | int i; | ||
| 1348 | |||
| 1349 | for (it = dfs_cache_get_tgt_iterator(tl); it; it = dfs_cache_get_next_tgt(tl, it)) { | ||
| 1350 | for (i = 0; i < numrefs; i++) { | ||
| 1351 | if (target_share_equal(tcon->ses->server, dfs_cache_get_tgt_name(it), | ||
| 1352 | refs[i].node_name)) | ||
| 1353 | return; | ||
| 1354 | } | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | cifs_dbg(FYI, "%s: no cached or matched targets. mark dfs share for reconnect.\n", __func__); | ||
| 1358 | for (i = 0; i < tcon->ses->chan_count; i++) { | ||
| 1359 | spin_lock(&GlobalMid_Lock); | ||
| 1360 | if (tcon->ses->chans[i].server->tcpStatus != CifsExiting) | ||
| 1361 | tcon->ses->chans[i].server->tcpStatus = CifsNeedReconnect; | ||
| 1362 | spin_unlock(&GlobalMid_Lock); | ||
| 1363 | } | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | /* Refresh dfs referral of tcon and mark it for reconnect if needed */ | ||
| 1367 | static int refresh_tcon(struct cifs_ses **sessions, struct cifs_tcon *tcon, bool force_refresh) | ||
| 1368 | { | ||
| 1369 | const char *path = tcon->dfs_path + 1; | ||
| 1370 | struct cifs_ses *ses; | ||
| 1371 | struct cache_entry *ce; | ||
| 1372 | struct dfs_info3_param *refs = NULL; | ||
| 1373 | int numrefs = 0; | ||
| 1374 | bool needs_refresh = false; | ||
| 1375 | struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl); | ||
| 1376 | int rc = 0; | ||
| 1377 | unsigned int xid; | ||
| 1378 | |||
| 1379 | ses = find_ipc_from_server_path(sessions, path); | ||
| 1380 | if (IS_ERR(ses)) { | ||
| 1381 | cifs_dbg(FYI, "%s: could not find ipc session\n", __func__); | ||
| 1382 | return PTR_ERR(ses); | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | down_read(&htable_rw_lock); | ||
| 1386 | ce = lookup_cache_entry(path); | ||
| 1387 | needs_refresh = force_refresh || IS_ERR(ce) || cache_entry_expired(ce); | ||
| 1388 | if (!IS_ERR(ce)) { | ||
| 1389 | rc = get_targets(ce, &tl); | ||
| 1390 | if (rc) | ||
| 1391 | cifs_dbg(FYI, "%s: could not get dfs targets: %d\n", __func__, rc); | ||
| 1392 | } | ||
| 1393 | up_read(&htable_rw_lock); | ||
| 1394 | |||
| 1395 | if (!needs_refresh) { | ||
| 1396 | rc = 0; | ||
| 1397 | goto out; | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | xid = get_xid(); | ||
| 1401 | rc = get_dfs_referral(xid, ses, path, &refs, &numrefs); | ||
| 1402 | free_xid(xid); | ||
| 1403 | |||
| 1404 | /* Create or update a cache entry with the new referral */ | ||
| 1405 | if (!rc) { | ||
| 1406 | dump_refs(refs, numrefs); | ||
| 1407 | |||
| 1408 | down_write(&htable_rw_lock); | ||
| 1409 | ce = lookup_cache_entry(path); | ||
| 1410 | if (IS_ERR(ce)) | ||
| 1411 | add_cache_entry_locked(refs, numrefs); | ||
| 1412 | else if (force_refresh || cache_entry_expired(ce)) | ||
| 1413 | update_cache_entry_locked(ce, refs, numrefs); | ||
| 1414 | up_write(&htable_rw_lock); | ||
| 1415 | |||
| 1416 | mark_for_reconnect_if_needed(tcon, &tl, refs, numrefs); | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | out: | ||
| 1420 | dfs_cache_free_tgts(&tl); | ||
| 1421 | free_dfs_info_array(refs, numrefs); | ||
| 1422 | return rc; | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | /** | ||
| 1426 | * dfs_cache_remount_fs - remount a DFS share | ||
| 1427 | * | ||
| 1428 | * Reconfigure dfs mount by forcing a new DFS referral and if the currently cached targets do not | ||
| 1429 | * match any of the new targets, mark it for reconnect. | ||
| 1430 | * | ||
| 1431 | * @cifs_sb: cifs superblock. | ||
| 1432 | * | ||
| 1433 | * Return zero if remounted, otherwise non-zero. | ||
| 1434 | */ | ||
| 1435 | int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb) | ||
| 1436 | { | ||
| 1437 | struct cifs_tcon *tcon; | ||
| 1438 | struct mount_group *mg; | ||
| 1439 | struct cifs_ses *sessions[CACHE_MAX_ENTRIES + 1] = {NULL}; | ||
| 1440 | int rc; | ||
| 1441 | |||
| 1442 | if (!cifs_sb || !cifs_sb->master_tlink) | ||
| 1443 | return -EINVAL; | ||
| 1444 | |||
| 1445 | tcon = cifs_sb_master_tcon(cifs_sb); | ||
| 1446 | if (!tcon->dfs_path) { | ||
| 1447 | cifs_dbg(FYI, "%s: not a dfs tcon\n", __func__); | ||
| 1448 | return 0; | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | if (uuid_is_null(&cifs_sb->dfs_mount_id)) { | ||
| 1452 | cifs_dbg(FYI, "%s: tcon has no dfs mount group id\n", __func__); | ||
| 1453 | return -EINVAL; | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | mutex_lock(&mount_group_list_lock); | ||
| 1457 | mg = find_mount_group_locked(&cifs_sb->dfs_mount_id); | ||
| 1458 | if (IS_ERR(mg)) { | ||
| 1459 | mutex_unlock(&mount_group_list_lock); | ||
| 1460 | cifs_dbg(FYI, "%s: tcon has ipc session to refresh referral\n", __func__); | ||
| 1461 | return PTR_ERR(mg); | ||
| 1462 | } | ||
| 1463 | kref_get(&mg->refcount); | ||
| 1464 | mutex_unlock(&mount_group_list_lock); | ||
| 1465 | |||
| 1466 | spin_lock(&mg->lock); | ||
| 1467 | memcpy(&sessions, mg->sessions, mg->num_sessions * sizeof(mg->sessions[0])); | ||
| 1468 | spin_unlock(&mg->lock); | ||
| 1469 | |||
| 1470 | /* | ||
| 1471 | * After reconnecting to a different server, unique ids won't match anymore, so we disable | ||
| 1472 | * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE). | ||
| 1473 | */ | ||
| 1474 | cifs_autodisable_serverino(cifs_sb); | ||
| 1475 | /* | ||
| 1476 | * Force the use of prefix path to support failover on DFS paths that resolve to targets | ||
| 1477 | * that have different prefix paths. | ||
| 1478 | */ | ||
| 1479 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; | ||
| 1480 | rc = refresh_tcon(sessions, tcon, true); | ||
| 1481 | |||
| 1482 | kref_put(&mg->refcount, mount_group_release); | ||
| 1483 | return rc; | ||
| 1484 | } | ||
| 1485 | |||
| 1296 | /* | 1486 | /* |
| 1297 | * Refresh all active dfs mounts regardless of whether they are in cache or not. | 1487 | * Refresh all active dfs mounts regardless of whether they are in cache or not. |
| 1298 | * (cache can be cleared) | 1488 | * (cache can be cleared) |
| @@ -1303,7 +1493,6 @@ static void refresh_mounts(struct cifs_ses **sessions) · 4 unmodified lines | |||
| 1303 | struct cifs_ses *ses; | 1493 | struct cifs_ses *ses; |
| 1304 | struct cifs_tcon *tcon, *ntcon; | 1494 | struct cifs_tcon *tcon, *ntcon; |
| 1305 | struct list_head tcons; | 1495 | struct list_head tcons; |
| 1306 | unsigned int xid; | ||
| 1307 | 1496 | ||
| 1308 | INIT_LIST_HEAD(&tcons); | 1497 | INIT_LIST_HEAD(&tcons); |
| 1309 | 1498 | ||
| @@ -1321,44 +1510,8 @@ static void refresh_mounts(struct cifs_ses **sessions) · 11 unmodified lines | |||
| 1321 | spin_unlock(&cifs_tcp_ses_lock); | 1510 | spin_unlock(&cifs_tcp_ses_lock); |
| 1322 | 1511 | ||
| 1323 | list_for_each_entry_safe(tcon, ntcon, &tcons, ulist) { | 1512 | list_for_each_entry_safe(tcon, ntcon, &tcons, ulist) { |
| 1324 | const char *path = tcon->dfs_path + 1; | ||
| 1325 | struct cache_entry *ce; | ||
| 1326 | struct dfs_info3_param *refs = NULL; | ||
| 1327 | int numrefs = 0; | ||
| 1328 | bool needs_refresh = false; | ||
| 1329 | int rc = 0; | ||
| 1330 | |||
| 1331 | list_del_init(&tcon->ulist); | 1513 | list_del_init(&tcon->ulist); |
| 1332 | 1514 | refresh_tcon(sessions, tcon, false); | |
| 1333 | ses = find_ipc_from_server_path(sessions, path); | ||
| 1334 | if (IS_ERR(ses)) | ||
| 1335 | goto next_tcon; | ||
| 1336 | |||
| 1337 | down_read(&htable_rw_lock); | ||
| 1338 | ce = lookup_cache_entry(path); | ||
| 1339 | needs_refresh = IS_ERR(ce) || cache_entry_expired(ce); | ||
| 1340 | up_read(&htable_rw_lock); | ||
| 1341 | |||
| 1342 | if (!needs_refresh) | ||
| 1343 | goto next_tcon; | ||
| 1344 | |||
| 1345 | xid = get_xid(); | ||
| 1346 | rc = get_dfs_referral(xid, ses, path, &refs, &numrefs); | ||
| 1347 | free_xid(xid); | ||
| 1348 | |||
| 1349 | /* Create or update a cache entry with the new referral */ | ||
| 1350 | if (!rc) { | ||
| 1351 | down_write(&htable_rw_lock); | ||
| 1352 | ce = lookup_cache_entry(path); | ||
| 1353 | if (IS_ERR(ce)) | ||
| 1354 | add_cache_entry_locked(refs, numrefs); | ||
| 1355 | else if (cache_entry_expired(ce)) | ||
| 1356 | update_cache_entry_locked(ce, refs, numrefs); | ||
| 1357 | up_write(&htable_rw_lock); | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | next_tcon: | ||
| 1361 | free_dfs_info_array(refs, numrefs); | ||
| 1362 | cifs_put_tcon(tcon); | 1515 | cifs_put_tcon(tcon); |
| 1363 | } | 1516 | } |
| 1364 | } | 1517 | } |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | |||
| 13 | #include <linux/uuid.h> | 13 | #include <linux/uuid.h> |
| 14 | #include "cifsglob.h" | 14 | #include "cifsglob.h" |
| 15 | 15 | ||
| 16 | #define DFS_CACHE_TGT_LIST_INIT(var) { .tl_numtgts = 0, .tl_list = LIST_HEAD_INIT((var).tl_list), } | ||
| 17 | |||
| 16 | struct dfs_cache_tgt_list { | 18 | struct dfs_cache_tgt_list { |
| 17 | int tl_numtgts; | 19 | int tl_numtgts; |
| 18 | struct list_head tl_list; | 20 | struct list_head tl_list; |
| @@ -44,6 +46,7 @@ int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, · 25 unmodified lines | |||
| 44 | void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id); | 46 | void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id); |
| 45 | void dfs_cache_add_refsrv_session(const uuid_t *mount_id, struct cifs_ses *ses); | 47 | void dfs_cache_add_refsrv_session(const uuid_t *mount_id, struct cifs_ses *ses); |
| 46 | char *dfs_cache_canonical_path(const char *path, const struct nls_table *cp, int remap); | 48 | char *dfs_cache_canonical_path(const char *path, const struct nls_table *cp, int remap); |
| 49 | int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb); | ||
| 47 | 50 | ||
| 48 | static inline struct dfs_cache_tgt_iterator * | 51 | static inline struct dfs_cache_tgt_iterator * |
| 49 | dfs_cache_get_next_tgt(struct dfs_cache_tgt_list *tl, | 52 | dfs_cache_get_next_tgt(struct dfs_cache_tgt_list *tl, |
| @@ -4619,7 +4619,7 @@ read_complete: · 4618 unmodified lines | |||
| 4619 | 4619 | ||
| 4620 | static int cifs_readpage(struct file *file, struct page *page) | 4620 | static int cifs_readpage(struct file *file, struct page *page) |
| 4621 | { | 4621 | { |
| 4622 | loff_t offset = (loff_t)page->index << PAGE_SHIFT; | 4622 | loff_t offset = page_file_offset(page); |
| 4623 | int rc = -EACCES; | 4623 | int rc = -EACCES; |
| 4624 | unsigned int xid; | 4624 | unsigned int xid; |
| 4625 | 4625 | ||
| @@ -13,6 +13,9 @@ · 12 unmodified lines | |||
| 13 | #include <linux/magic.h> | 13 | #include <linux/magic.h> |
| 14 | #include <linux/security.h> | 14 | #include <linux/security.h> |
| 15 | #include <net/net_namespace.h> | 15 | #include <net/net_namespace.h> |
| 16 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
| 17 | #include "dfs_cache.h" | ||
| 18 | #endif | ||
| 16 | */ | 19 | */ |
| 17 | 20 | ||
| 18 | #include <linux/ctype.h> | 21 | #include <linux/ctype.h> |
| @@ -779,6 +782,10 @@ static int smb3_reconfigure(struct fs_context *fc) · 760 unmodified lines | |||
| 779 | smb3_cleanup_fs_context_contents(cifs_sb->ctx); | 782 | smb3_cleanup_fs_context_contents(cifs_sb->ctx); |
| 780 | rc = smb3_fs_context_dup(cifs_sb->ctx, ctx); | 783 | rc = smb3_fs_context_dup(cifs_sb->ctx, ctx); |
| 781 | smb3_update_mnt_flags(cifs_sb); | 784 | smb3_update_mnt_flags(cifs_sb); |
| 785 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
| 786 | if (!rc) | ||
| 787 | rc = dfs_cache_remount_fs(cifs_sb); | ||
| 788 | #endif | ||
| 782 | 789 | ||
| 783 | return rc; | 790 | return rc; |
| 784 | } | 791 | } |
| @@ -918,6 +925,13 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, · 133 unmodified lines | |||
| 918 | ctx->cred_uid = uid; | 925 | ctx->cred_uid = uid; |
| 919 | ctx->cruid_specified = true; | 926 | ctx->cruid_specified = true; |
| 920 | break; | 927 | break; |
| 928 | case Opt_backupuid: | ||
| 929 | uid = make_kuid(current_user_ns(), result.uint_32); | ||
| 930 | if (!uid_valid(uid)) | ||
| 931 | goto cifs_parse_mount_err; | ||
| 932 | ctx->backupuid = uid; | ||
| 933 | ctx->backupuid_specified = true; | ||
| 934 | break; | ||
| 921 | case Opt_backupgid: | 935 | case Opt_backupgid: |
| 922 | gid = make_kgid(current_user_ns(), result.uint_32); | 936 | gid = make_kgid(current_user_ns(), result.uint_32); |
| 923 | if (!gid_valid(gid)) | 937 | if (!gid_valid(gid)) |
| @@ -3618,6 +3618,7 @@ static int smb3_simple_fallocate_write_range(unsigned int xid, · 3617 unmodified lines | |||
| 3618 | { | 3618 | { |
| 3619 | struct cifs_io_parms io_parms = {0}; | 3619 | struct cifs_io_parms io_parms = {0}; |
| 3620 | int nbytes; | 3620 | int nbytes; |
| 3621 | int rc = 0; | ||
| 3621 | struct kvec iov[2]; | 3622 | struct kvec iov[2]; |
| 3622 | 3623 | ||
| 3623 | io_parms.netfid = cfile->fid.netfid; | 3624 | io_parms.netfid = cfile->fid.netfid; |
| @@ -3625,13 +3626,25 @@ static int smb3_simple_fallocate_write_range(unsigned int xid, · 1 unmodified line | |||
| 3625 | io_parms.tcon = tcon; | 3626 | io_parms.tcon = tcon; |
| 3626 | io_parms.persistent_fid = cfile->fid.persistent_fid; | 3627 | io_parms.persistent_fid = cfile->fid.persistent_fid; |
| 3627 | io_parms.volatile_fid = cfile->fid.volatile_fid; | 3628 | io_parms.volatile_fid = cfile->fid.volatile_fid; |
| 3628 | io_parms.offset = off; | ||
| 3629 | io_parms.length = len; | ||
| 3630 | 3629 | ||
| 3631 | /* iov[0] is reserved for smb header */ | 3630 | while (len) { |
| 3632 | iov[1].iov_base = buf; | 3631 | io_parms.offset = off; |
| 3633 | iov[1].iov_len = io_parms.length; | 3632 | io_parms.length = len; |
| 3634 | return SMB2_write(xid, &io_parms, &nbytes, iov, 1); | 3633 | if (io_parms.length > SMB2_MAX_BUFFER_SIZE) |
| 3634 | io_parms.length = SMB2_MAX_BUFFER_SIZE; | ||
| 3635 | /* iov[0] is reserved for smb header */ | ||
| 3636 | iov[1].iov_base = buf; | ||
| 3637 | iov[1].iov_len = io_parms.length; | ||
| 3638 | rc = SMB2_write(xid, &io_parms, &nbytes, iov, 1); | ||
| 3639 | if (rc) | ||
| 3640 | break; | ||
| 3641 | if (nbytes > len) | ||
| 3642 | return -EINVAL; | ||
| 3643 | buf += nbytes; | ||
| 3644 | off += nbytes; | ||
| 3645 | len -= nbytes; | ||
| 3646 | } | ||
| 3647 | return rc; | ||
| 3635 | } | 3648 | } |
| 3636 | 3649 | ||
| 3637 | static int smb3_simple_fallocate_range(unsigned int xid, | 3650 | static int smb3_simple_fallocate_range(unsigned int xid, |
| @@ -3655,11 +3668,6 @@ static int smb3_simple_fallocate_range(unsigned int xid, · 17 unmodified lines | |||
| 3655 | (char **)&out_data, &out_data_len); | 3668 | (char **)&out_data, &out_data_len); |
| 3656 | if (rc) | 3669 | if (rc) |
| 3657 | goto out; | 3670 | goto out; |
| 3658 | /* | ||
| 3659 | * It is already all allocated | ||
| 3660 | */ | ||
| 3661 | if (out_data_len == 0) | ||
| 3662 | goto out; | ||
| 3663 | 3671 | ||
| 3664 | buf = kzalloc(1024 * 1024, GFP_KERNEL); | 3672 | buf = kzalloc(1024 * 1024, GFP_KERNEL); |
| 3665 | if (buf == NULL) { | 3673 | if (buf == NULL) { |
| @@ -3782,6 +3790,24 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon, · 116 unmodified lines | |||
| 3782 | goto out; | 3790 | goto out; |
| 3783 | } | 3791 | } |
| 3784 | 3792 | ||
| 3793 | if (keep_size == true) { | ||
| 3794 | /* | ||
| 3795 | * We can not preallocate pages beyond the end of the file | ||
| 3796 | * in SMB2 | ||
| 3797 | */ | ||
| 3798 | if (off >= i_size_read(inode)) { | ||
| 3799 | rc = 0; | ||
| 3800 | goto out; | ||
| 3801 | } | ||
| 3802 | /* | ||
| 3803 | * For fallocates that are partially beyond the end of file, | ||
| 3804 | * clamp len so we only fallocate up to the end of file. | ||
| 3805 | */ | ||
| 3806 | if (off + len > i_size_read(inode)) { | ||
| 3807 | len = i_size_read(inode) - off; | ||
| 3808 | } | ||
| 3809 | } | ||
| 3810 | |||
| 3785 | if ((keep_size == true) || (i_size_read(inode) >= off + len)) { | 3811 | if ((keep_size == true) || (i_size_read(inode) >= off + len)) { |
| 3786 | /* | 3812 | /* |
| 3787 | * At this point, we are trying to fallocate an internal | 3813 | * At this point, we are trying to fallocate an internal |
| @@ -106,12 +106,11 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len) · 105 unmodified lines | |||
| 106 | return err; | 106 | return err; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static bool ext2_check_page(struct page *page, int quiet) | 109 | static bool ext2_check_page(struct page *page, int quiet, char *kaddr) |
| 110 | { | 110 | { |
| 111 | struct inode *dir = page->mapping->host; | 111 | struct inode *dir = page->mapping->host; |
| 112 | struct super_block *sb = dir->i_sb; | 112 | struct super_block *sb = dir->i_sb; |
| 113 | unsigned chunk_size = ext2_chunk_size(dir); | 113 | unsigned chunk_size = ext2_chunk_size(dir); |
| 114 | char *kaddr = page_address(page); | ||
| 115 | u32 max_inumber = le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count); | 114 | u32 max_inumber = le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count); |
| 116 | unsigned offs, rec_len; | 115 | unsigned offs, rec_len; |
| 117 | unsigned limit = PAGE_SIZE; | 116 | unsigned limit = PAGE_SIZE; |
| @@ -205,7 +204,8 @@ static struct page * ext2_get_page(struct inode *dir, unsigned long n, · 87 unmodified lines | |||
| 205 | if (!IS_ERR(page)) { | 204 | if (!IS_ERR(page)) { |
| 206 | *page_addr = kmap_local_page(page); | 205 | *page_addr = kmap_local_page(page); |
| 207 | if (unlikely(!PageChecked(page))) { | 206 | if (unlikely(!PageChecked(page))) { |
| 208 | if (PageError(page) || !ext2_check_page(page, quiet)) | 207 | if (PageError(page) || !ext2_check_page(page, quiet, |
| 208 | *page_addr)) | ||
| 209 | goto fail; | 209 | goto fail; |
| 210 | } | 210 | } |
| 211 | } | 211 | } |
| @@ -584,10 +584,10 @@ out_unlock: · 372 unmodified lines | |||
| 584 | * ext2_delete_entry deletes a directory entry by merging it with the | 584 | * ext2_delete_entry deletes a directory entry by merging it with the |
| 585 | * previous entry. Page is up-to-date. | 585 | * previous entry. Page is up-to-date. |
| 586 | */ | 586 | */ |
| 587 | int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) | 587 | int ext2_delete_entry (struct ext2_dir_entry_2 *dir, struct page *page, |
| 588 | char *kaddr) | ||
| 588 | { | 589 | { |
| 589 | struct inode *inode = page->mapping->host; | 590 | struct inode *inode = page->mapping->host; |
| 590 | char *kaddr = page_address(page); | ||
| 591 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); | 591 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); |
| 592 | unsigned to = ((char *)dir - kaddr) + | 592 | unsigned to = ((char *)dir - kaddr) + |
| 593 | ext2_rec_len_from_disk(dir->rec_len); | 593 | ext2_rec_len_from_disk(dir->rec_len); |
| @@ -607,7 +607,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) · 13 unmodified lines | |||
| 607 | de = ext2_next_entry(de); | 607 | de = ext2_next_entry(de); |
| 608 | } | 608 | } |
| 609 | if (pde) | 609 | if (pde) |
| 610 | from = (char*)pde - (char*)page_address(page); | 610 | from = (char *)pde - kaddr; |
| 611 | pos = page_offset(page) + from; | 611 | pos = page_offset(page) + from; |
| 612 | lock_page(page); | 612 | lock_page(page); |
| 613 | err = ext2_prepare_chunk(page, pos, to - from); | 613 | err = ext2_prepare_chunk(page, pos, to - from); |
| @@ -740,7 +740,8 @@ extern int ext2_inode_by_name(struct inode *dir, · 739 unmodified lines | |||
| 740 | extern int ext2_make_empty(struct inode *, struct inode *); | 740 | extern int ext2_make_empty(struct inode *, struct inode *); |
| 741 | extern struct ext2_dir_entry_2 *ext2_find_entry(struct inode *, const struct qstr *, | 741 | extern struct ext2_dir_entry_2 *ext2_find_entry(struct inode *, const struct qstr *, |
| 742 | struct page **, void **res_page_addr); | 742 | struct page **, void **res_page_addr); |
| 743 | extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *); | 743 | extern int ext2_delete_entry(struct ext2_dir_entry_2 *dir, struct page *page, |
| 744 | char *kaddr); | ||
| 744 | extern int ext2_empty_dir (struct inode *); | 745 | extern int ext2_empty_dir (struct inode *); |
| 745 | extern struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p, void **pa); | 746 | extern struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p, void **pa); |
| 746 | extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, void *, | 747 | extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, void *, |
| @@ -293,7 +293,7 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry) · 292 unmodified lines | |||
| 293 | goto out; | 293 | goto out; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | err = ext2_delete_entry (de, page); | 296 | err = ext2_delete_entry (de, page, page_addr); |
| 297 | ext2_put_page(page, page_addr); | 297 | ext2_put_page(page, page_addr); |
| 298 | if (err) | 298 | if (err) |
| 299 | goto out; | 299 | goto out; |
| @@ -397,7 +397,7 @@ static int ext2_rename (struct user_namespace * mnt_userns, · 97 unmodified lines | |||
| 397 | old_inode->i_ctime = current_time(old_inode); | 397 | old_inode->i_ctime = current_time(old_inode); |
| 398 | mark_inode_dirty(old_inode); | 398 | mark_inode_dirty(old_inode); |
| 399 | 399 | ||
| 400 | ext2_delete_entry(old_de, old_page); | 400 | ext2_delete_entry(old_de, old_page, old_page_addr); |
| 401 | 401 | ||
| 402 | if (dir_de) { | 402 | if (dir_de) { |
| 403 | if (old_dir != new_dir) | 403 | if (old_dir != new_dir) |
| @@ -521,6 +521,9 @@ static bool inode_prepare_wbs_switch(struct inode *inode, · 520 unmodified lines | |||
| 521 | */ | 521 | */ |
| 522 | smp_mb(); | 522 | smp_mb(); |
| 523 | 523 | ||
| 524 | if (IS_DAX(inode)) | ||
| 525 | return false; | ||
| 526 | |||
| 524 | /* while holding I_WB_SWITCH, no one else can update the association */ | 527 | /* while holding I_WB_SWITCH, no one else can update the association */ |
| 525 | spin_lock(&inode->i_lock); | 528 | spin_lock(&inode->i_lock); |
| 526 | if (!(inode->i_sb->s_flags & SB_ACTIVE) || | 529 | if (!(inode->i_sb->s_flags & SB_ACTIVE) || |
| @@ -77,7 +77,7 @@ enum hugetlb_param { · 76 unmodified lines | |||
| 77 | static const struct fs_parameter_spec hugetlb_fs_parameters[] = { | 77 | static const struct fs_parameter_spec hugetlb_fs_parameters[] = { |
| 78 | fsparam_u32 ("gid", Opt_gid), | 78 | fsparam_u32 ("gid", Opt_gid), |
| 79 | fsparam_string("min_size", Opt_min_size), | 79 | fsparam_string("min_size", Opt_min_size), |
| 80 | fsparam_u32 ("mode", Opt_mode), | 80 | fsparam_u32oct("mode", Opt_mode), |
| 81 | fsparam_string("nr_inodes", Opt_nr_inodes), | 81 | fsparam_string("nr_inodes", Opt_nr_inodes), |
| 82 | fsparam_string("pagesize", Opt_pagesize), | 82 | fsparam_string("pagesize", Opt_pagesize), |
| 83 | fsparam_string("size", Opt_size), | 83 | fsparam_string("size", Opt_size), |
| @@ -61,7 +61,6 @@ extern void __init chrdev_init(void); · 60 unmodified lines | |||
| 61 | */ | 61 | */ |
| 62 | extern const struct fs_context_operations legacy_fs_context_ops; | 62 | extern const struct fs_context_operations legacy_fs_context_ops; |
| 63 | extern int parse_monolithic_mount_data(struct fs_context *, void *); | 63 | extern int parse_monolithic_mount_data(struct fs_context *, void *); |
| 64 | extern void fc_drop_locked(struct fs_context *); | ||
| 65 | extern void vfs_clean_context(struct fs_context *fc); | 64 | extern void vfs_clean_context(struct fs_context *fc); |
| 66 | extern int finish_clean_context(struct fs_context *fc); | 65 | extern int finish_clean_context(struct fs_context *fc); |
| 67 | 66 | ||
| @@ -731,7 +731,12 @@ static void io_wqe_enqueue(struct io_wqe *wqe, struct io_wq_work *work) · 730 unmodified lines | |||
| 731 | int work_flags; | 731 | int work_flags; |
| 732 | unsigned long flags; | 732 | unsigned long flags; |
| 733 | 733 | ||
| 734 | if (test_bit(IO_WQ_BIT_EXIT, &wqe->wq->state)) { | 734 | /* |
| 735 | * If io-wq is exiting for this task, or if the request has explicitly | ||
| 736 | * been marked as one that should not get executed, cancel it here. | ||
| 737 | */ | ||
| 738 | if (test_bit(IO_WQ_BIT_EXIT, &wqe->wq->state) || | ||
| 739 | (work->flags & IO_WQ_WORK_CANCEL)) { | ||
| 735 | io_run_cancel(work, wqe); | 740 | io_run_cancel(work, wqe); |
| 736 | return; | 741 | return; |
| 737 | } | 742 | } |
| @@ -1279,8 +1279,17 @@ static void io_prep_async_link(struct io_kiocb *req) · 1278 unmodified lines | |||
| 1279 | { | 1279 | { |
| 1280 | struct io_kiocb *cur; | 1280 | struct io_kiocb *cur; |
| 1281 | 1281 | ||
| 1282 | io_for_each_link(cur, req) | 1282 | if (req->flags & REQ_F_LINK_TIMEOUT) { |
| 1283 | io_prep_async_work(cur); | 1283 | struct io_ring_ctx *ctx = req->ctx; |
| 1284 | |||
| 1285 | spin_lock_irq(&ctx->completion_lock); | ||
| 1286 | io_for_each_link(cur, req) | ||
| 1287 | io_prep_async_work(cur); | ||
| 1288 | spin_unlock_irq(&ctx->completion_lock); | ||
| 1289 | } else { | ||
| 1290 | io_for_each_link(cur, req) | ||
| 1291 | io_prep_async_work(cur); | ||
| 1292 | } | ||
| 1284 | } | 1293 | } |
| 1285 | 1294 | ||
| 1286 | static void io_queue_async_work(struct io_kiocb *req) | 1295 | static void io_queue_async_work(struct io_kiocb *req) |
| @@ -1294,6 +1303,17 @@ static void io_queue_async_work(struct io_kiocb *req) · 7 unmodified lines | |||
| 1294 | 1303 | ||
| 1295 | /* init ->work of the whole link before punting */ | 1304 | /* init ->work of the whole link before punting */ |
| 1296 | io_prep_async_link(req); | 1305 | io_prep_async_link(req); |
| 1306 | |||
| 1307 | /* | ||
| 1308 | * Not expected to happen, but if we do have a bug where this _can_ | ||
| 1309 | * happen, catch it here and ensure the request is marked as | ||
| 1310 | * canceled. That will make io-wq go through the usual work cancel | ||
| 1311 | * procedure rather than attempt to run this request (or create a new | ||
| 1312 | * worker for it). | ||
| 1313 | */ | ||
| 1314 | if (WARN_ON_ONCE(!same_thread_group(req->task, current))) | ||
| 1315 | req->work.flags |= IO_WQ_WORK_CANCEL; | ||
| 1316 | |||
| 1297 | trace_io_uring_queue_async_work(ctx, io_wq_is_hashed(&req->work), req, | 1317 | trace_io_uring_queue_async_work(ctx, io_wq_is_hashed(&req->work), req, |
| 1298 | &req->work, req->flags); | 1318 | &req->work, req->flags); |
| 1299 | io_wq_enqueue(tctx->io_wq, &req->work); | 1319 | io_wq_enqueue(tctx->io_wq, &req->work); |
| @@ -1939,9 +1959,13 @@ static void tctx_task_work(struct callback_head *cb) · 639 unmodified lines | |||
| 1939 | node = next; | 1959 | node = next; |
| 1940 | } | 1960 | } |
| 1941 | if (wq_list_empty(&tctx->task_list)) { | 1961 | if (wq_list_empty(&tctx->task_list)) { |
| 1962 | spin_lock_irq(&tctx->task_lock); | ||
| 1942 | clear_bit(0, &tctx->task_state); | 1963 | clear_bit(0, &tctx->task_state); |
| 1943 | if (wq_list_empty(&tctx->task_list)) | 1964 | if (wq_list_empty(&tctx->task_list)) { |
| 1965 | spin_unlock_irq(&tctx->task_lock); | ||
| 1944 | break; | 1966 | break; |
| 1967 | } | ||
| 1968 | spin_unlock_irq(&tctx->task_lock); | ||
| 1945 | /* another tctx_task_work() is enqueued, yield */ | 1969 | /* another tctx_task_work() is enqueued, yield */ |
| 1946 | if (test_and_set_bit(0, &tctx->task_state)) | 1970 | if (test_and_set_bit(0, &tctx->task_state)) |
| 1947 | break; | 1971 | break; |
| @@ -2036,6 +2060,12 @@ static void io_req_task_queue(struct io_kiocb *req) · 88 unmodified lines | |||
| 2036 | io_req_task_work_add(req); | 2060 | io_req_task_work_add(req); |
| 2037 | } | 2061 | } |
| 2038 | 2062 | ||
| 2063 | static void io_req_task_queue_reissue(struct io_kiocb *req) | ||
| 2064 | { | ||
| 2065 | req->io_task_work.func = io_queue_async_work; | ||
| 2066 | io_req_task_work_add(req); | ||
| 2067 | } | ||
| 2068 | |||
| 2039 | static inline void io_queue_next(struct io_kiocb *req) | 2069 | static inline void io_queue_next(struct io_kiocb *req) |
| 2040 | { | 2070 | { |
| 2041 | struct io_kiocb *nxt = io_req_find_next(req); | 2071 | struct io_kiocb *nxt = io_req_find_next(req); |
| @@ -2205,7 +2235,7 @@ static inline bool io_run_task_work(void) · 163 unmodified lines | |||
| 2205 | * Find and free completed poll iocbs | 2235 | * Find and free completed poll iocbs |
| 2206 | */ | 2236 | */ |
| 2207 | static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events, | 2237 | static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events, |
| 2208 | struct list_head *done) | 2238 | struct list_head *done, bool resubmit) |
| 2209 | { | 2239 | { |
| 2210 | struct req_batch rb; | 2240 | struct req_batch rb; |
| 2211 | struct io_kiocb *req; | 2241 | struct io_kiocb *req; |
| @@ -2220,11 +2250,11 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events, · 8 unmodified lines | |||
| 2220 | req = list_first_entry(done, struct io_kiocb, inflight_entry); | 2250 | req = list_first_entry(done, struct io_kiocb, inflight_entry); |
| 2221 | list_del(&req->inflight_entry); | 2251 | list_del(&req->inflight_entry); |
| 2222 | 2252 | ||
| 2223 | if (READ_ONCE(req->result) == -EAGAIN && | 2253 | if (READ_ONCE(req->result) == -EAGAIN && resubmit && |
| 2224 | !(req->flags & REQ_F_DONT_REISSUE)) { | 2254 | !(req->flags & REQ_F_DONT_REISSUE)) { |
| 2225 | req->iopoll_completed = 0; | 2255 | req->iopoll_completed = 0; |
| 2226 | req_ref_get(req); | 2256 | req_ref_get(req); |
| 2227 | io_queue_async_work(req); | 2257 | io_req_task_queue_reissue(req); |
| 2228 | continue; | 2258 | continue; |
| 2229 | } | 2259 | } |
| 2230 | 2260 | ||
| @@ -2244,7 +2274,7 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events, · 13 unmodified lines | |||
| 2244 | } | 2274 | } |
| 2245 | 2275 | ||
| 2246 | static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events, | 2276 | static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events, |
| 2247 | long min) | 2277 | long min, bool resubmit) |
| 2248 | { | 2278 | { |
| 2249 | struct io_kiocb *req, *tmp; | 2279 | struct io_kiocb *req, *tmp; |
| 2250 | LIST_HEAD(done); | 2280 | LIST_HEAD(done); |
| @@ -2287,7 +2317,7 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events, · 36 unmodified lines | |||
| 2287 | } | 2317 | } |
| 2288 | 2318 | ||
| 2289 | if (!list_empty(&done)) | 2319 | if (!list_empty(&done)) |
| 2290 | io_iopoll_complete(ctx, nr_events, &done); | 2320 | io_iopoll_complete(ctx, nr_events, &done, resubmit); |
| 2291 | 2321 | ||
| 2292 | return ret; | 2322 | return ret; |
| 2293 | } | 2323 | } |
| @@ -2305,7 +2335,7 @@ static void io_iopoll_try_reap_events(struct io_ring_ctx *ctx) · 11 unmodified lines | |||
| 2305 | while (!list_empty(&ctx->iopoll_list)) { | 2335 | while (!list_empty(&ctx->iopoll_list)) { |
| 2306 | unsigned int nr_events = 0; | 2336 | unsigned int nr_events = 0; |
| 2307 | 2337 | ||
| 2308 | io_do_iopoll(ctx, &nr_events, 0); | 2338 | io_do_iopoll(ctx, &nr_events, 0, false); |
| 2309 | 2339 | ||
| 2310 | /* let it sleep and repeat later if can't complete a request */ | 2340 | /* let it sleep and repeat later if can't complete a request */ |
| 2311 | if (nr_events == 0) | 2341 | if (nr_events == 0) |
| @@ -2367,7 +2397,7 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, long min) · 55 unmodified lines | |||
| 2367 | list_empty(&ctx->iopoll_list)) | 2397 | list_empty(&ctx->iopoll_list)) |
| 2368 | break; | 2398 | break; |
| 2369 | } | 2399 | } |
| 2370 | ret = io_do_iopoll(ctx, &nr_events, min); | 2400 | ret = io_do_iopoll(ctx, &nr_events, min, true); |
| 2371 | } while (!ret && nr_events < min && !need_resched()); | 2401 | } while (!ret && nr_events < min && !need_resched()); |
| 2372 | out: | 2402 | out: |
| 2373 | mutex_unlock(&ctx->uring_lock); | 2403 | mutex_unlock(&ctx->uring_lock); |
| @@ -2417,6 +2447,12 @@ static bool io_rw_should_reissue(struct io_kiocb *req) · 43 unmodified lines | |||
| 2417 | */ | 2447 | */ |
| 2418 | if (percpu_ref_is_dying(&ctx->refs)) | 2448 | if (percpu_ref_is_dying(&ctx->refs)) |
| 2419 | return false; | 2449 | return false; |
| 2450 | /* | ||
| 2451 | * Play it safe and assume not safe to re-import and reissue if we're | ||
| 2452 | * not in the original thread group (or in task context). | ||
| 2453 | */ | ||
| 2454 | if (!same_thread_group(req->task, current) || !in_task()) | ||
| 2455 | return false; | ||
| 2420 | return true; | 2456 | return true; |
| 2421 | } | 2457 | } |
| 2422 | #else | 2458 | #else |
| @@ -2747,7 +2783,7 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, · 324 unmodified lines | |||
| 2747 | req->flags &= ~REQ_F_REISSUE; | 2783 | req->flags &= ~REQ_F_REISSUE; |
| 2748 | if (io_resubmit_prep(req)) { | 2784 | if (io_resubmit_prep(req)) { |
| 2749 | req_ref_get(req); | 2785 | req_ref_get(req); |
| 2750 | io_queue_async_work(req); | 2786 | io_req_task_queue_reissue(req); |
| 2751 | } else { | 2787 | } else { |
| 2752 | int cflags = 0; | 2788 | int cflags = 0; |
| 2753 | 2789 | ||
| @@ -4802,6 +4838,7 @@ IO_NETOP_FN(recv); · 2048 unmodified lines | |||
| 4802 | struct io_poll_table { | 4838 | struct io_poll_table { |
| 4803 | struct poll_table_struct pt; | 4839 | struct poll_table_struct pt; |
| 4804 | struct io_kiocb *req; | 4840 | struct io_kiocb *req; |
| 4841 | int nr_entries; | ||
| 4805 | int error; | 4842 | int error; |
| 4806 | }; | 4843 | }; |
| 4807 | 4844 | ||
| @@ -4902,7 +4939,6 @@ static bool io_poll_complete(struct io_kiocb *req, __poll_t mask) · 94 unmodified lines | |||
| 4902 | if (req->poll.events & EPOLLONESHOT) | 4939 | if (req->poll.events & EPOLLONESHOT) |
| 4903 | flags = 0; | 4940 | flags = 0; |
| 4904 | if (!io_cqring_fill_event(ctx, req->user_data, error, flags)) { | 4941 | if (!io_cqring_fill_event(ctx, req->user_data, error, flags)) { |
| 4905 | io_poll_remove_waitqs(req); | ||
| 4906 | req->poll.done = true; | 4942 | req->poll.done = true; |
| 4907 | flags = 0; | 4943 | flags = 0; |
| 4908 | } | 4944 | } |
| @@ -4925,6 +4961,7 @@ static void io_poll_task_func(struct io_kiocb *req) · 16 unmodified lines | |||
| 4925 | 4961 | ||
| 4926 | done = io_poll_complete(req, req->result); | 4962 | done = io_poll_complete(req, req->result); |
| 4927 | if (done) { | 4963 | if (done) { |
| 4964 | io_poll_remove_double(req); | ||
| 4928 | hash_del(&req->hash_node); | 4965 | hash_del(&req->hash_node); |
| 4929 | } else { | 4966 | } else { |
| 4930 | req->result = 0; | 4967 | req->result = 0; |
| @@ -4995,11 +5032,11 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, · 64 unmodified lines | |||
| 4995 | struct io_kiocb *req = pt->req; | 5032 | struct io_kiocb *req = pt->req; |
| 4996 | 5033 | ||
| 4997 | /* | 5034 | /* |
| 4998 | * If poll->head is already set, it's because the file being polled | 5035 | * The file being polled uses multiple waitqueues for poll handling |
| 4999 | * uses multiple waitqueues for poll handling (eg one for read, one | 5036 | * (e.g. one for read, one for write). Setup a separate io_poll_iocb |
| 5000 | * for write). Setup a separate io_poll_iocb if this happens. | 5037 | * if this happens. |
| 5001 | */ | 5038 | */ |
| 5002 | if (unlikely(poll->head)) { | 5039 | if (unlikely(pt->nr_entries)) { |
| 5003 | struct io_poll_iocb *poll_one = poll; | 5040 | struct io_poll_iocb *poll_one = poll; |
| 5004 | 5041 | ||
| 5005 | /* already have a 2nd entry, fail a third attempt */ | 5042 | /* already have a 2nd entry, fail a third attempt */ |
| @@ -5027,7 +5064,7 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, · 21 unmodified lines | |||
| 5027 | *poll_ptr = poll; | 5064 | *poll_ptr = poll; |
| 5028 | } | 5065 | } |
| 5029 | 5066 | ||
| 5030 | pt->error = 0; | 5067 | pt->nr_entries++; |
| 5031 | poll->head = head; | 5068 | poll->head = head; |
| 5032 | 5069 | ||
| 5033 | if (poll->events & EPOLLEXCLUSIVE) | 5070 | if (poll->events & EPOLLEXCLUSIVE) |
| @@ -5104,11 +5141,16 @@ static __poll_t __io_arm_poll_handler(struct io_kiocb *req, · 70 unmodified lines | |||
| 5104 | 5141 | ||
| 5105 | ipt->pt._key = mask; | 5142 | ipt->pt._key = mask; |
| 5106 | ipt->req = req; | 5143 | ipt->req = req; |
| 5107 | ipt->error = -EINVAL; | 5144 | ipt->error = 0; |
| 5145 | ipt->nr_entries = 0; | ||
| 5108 | 5146 | ||
| 5109 | mask = vfs_poll(req->file, &ipt->pt) & poll->events; | 5147 | mask = vfs_poll(req->file, &ipt->pt) & poll->events; |
| 5148 | if (unlikely(!ipt->nr_entries) && !ipt->error) | ||
| 5149 | ipt->error = -EINVAL; | ||
| 5110 | 5150 | ||
| 5111 | spin_lock_irq(&ctx->completion_lock); | 5151 | spin_lock_irq(&ctx->completion_lock); |
| 5152 | if (ipt->error || (mask && (poll->events & EPOLLONESHOT))) | ||
| 5153 | io_poll_remove_double(req); | ||
| 5112 | if (likely(poll->head)) { | 5154 | if (likely(poll->head)) { |
| 5113 | spin_lock(&poll->head->lock); | 5155 | spin_lock(&poll->head->lock); |
| 5114 | if (unlikely(list_empty(&poll->wait.entry))) { | 5156 | if (unlikely(list_empty(&poll->wait.entry))) { |
| @@ -5179,7 +5221,6 @@ static int io_arm_poll_handler(struct io_kiocb *req) · 64 unmodified lines | |||
| 5179 | ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, | 5221 | ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, |
| 5180 | io_async_wake); | 5222 | io_async_wake); |
| 5181 | if (ret || ipt.error) { | 5223 | if (ret || ipt.error) { |
| 5182 | io_poll_remove_double(req); | ||
| 5183 | spin_unlock_irq(&ctx->completion_lock); | 5224 | spin_unlock_irq(&ctx->completion_lock); |
| 5184 | if (ret) | 5225 | if (ret) |
| 5185 | return IO_APOLL_READY; | 5226 | return IO_APOLL_READY; |
| @@ -6792,7 +6833,7 @@ static int __io_sq_thread(struct io_ring_ctx *ctx, bool cap_entries) · 1606 unmodified lines | |||
| 6792 | 6833 | ||
| 6793 | mutex_lock(&ctx->uring_lock); | 6834 | mutex_lock(&ctx->uring_lock); |
| 6794 | if (!list_empty(&ctx->iopoll_list)) | 6835 | if (!list_empty(&ctx->iopoll_list)) |
| 6795 | io_do_iopoll(ctx, &nr_events, 0); | 6836 | io_do_iopoll(ctx, &nr_events, 0, true); |
| 6796 | 6837 | ||
| 6797 | /* | 6838 | /* |
| 6798 | * Don't submit if refs are dying, good for io_uring_register(), | 6839 | * Don't submit if refs are dying, good for io_uring_register(), |
| @@ -7899,15 +7940,19 @@ static struct io_wq *io_init_wq_offload(struct io_ring_ctx *ctx, · 1100 unmodified lines | |||
| 7899 | struct io_wq_data data; | 7940 | struct io_wq_data data; |
| 7900 | unsigned int concurrency; | 7941 | unsigned int concurrency; |
| 7901 | 7942 | ||
| 7943 | mutex_lock(&ctx->uring_lock); | ||
| 7902 | hash = ctx->hash_map; | 7944 | hash = ctx->hash_map; |
| 7903 | if (!hash) { | 7945 | if (!hash) { |
| 7904 | hash = kzalloc(sizeof(*hash), GFP_KERNEL); | 7946 | hash = kzalloc(sizeof(*hash), GFP_KERNEL); |
| 7905 | if (!hash) | 7947 | if (!hash) { |
| 7948 | mutex_unlock(&ctx->uring_lock); | ||
| 7906 | return ERR_PTR(-ENOMEM); | 7949 | return ERR_PTR(-ENOMEM); |
| 7950 | } | ||
| 7907 | refcount_set(&hash->refs, 1); | 7951 | refcount_set(&hash->refs, 1); |
| 7908 | init_waitqueue_head(&hash->wait); | 7952 | init_waitqueue_head(&hash->wait); |
| 7909 | ctx->hash_map = hash; | 7953 | ctx->hash_map = hash; |
| 7910 | } | 7954 | } |
| 7955 | mutex_unlock(&ctx->uring_lock); | ||
| 7911 | 7956 | ||
| 7912 | data.hash = hash; | 7957 | data.hash = hash; |
| 7913 | data.task = task; | 7958 | data.task = task; |
| @@ -7981,9 +8026,11 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx, · 67 unmodified lines | |||
| 7981 | f = fdget(p->wq_fd); | 8026 | f = fdget(p->wq_fd); |
| 7982 | if (!f.file) | 8027 | if (!f.file) |
| 7983 | return -ENXIO; | 8028 | return -ENXIO; |
| 7984 | fdput(f); | 8029 | if (f.file->f_op != &io_uring_fops) { |
| 7985 | if (f.file->f_op != &io_uring_fops) | 8030 | fdput(f); |
| 7986 | return -EINVAL; | 8031 | return -EINVAL; |
| 8032 | } | ||
| 8033 | fdput(f); | ||
| 7987 | } | 8034 | } |
| 7988 | if (ctx->flags & IORING_SETUP_SQPOLL) { | 8035 | if (ctx->flags & IORING_SETUP_SQPOLL) { |
| 7989 | struct task_struct *tsk; | 8036 | struct task_struct *tsk; |
| @@ -1529,6 +1529,45 @@ static void ocfs2_truncate_cluster_pages(struct inode *inode, u64 byte_start, · 1528 unmodified lines | |||
| 1529 | } | 1529 | } |
| 1530 | } | 1530 | } |
| 1531 | 1531 | ||
| 1532 | /* | ||
| 1533 | * zero out partial blocks of one cluster. | ||
| 1534 | * | ||
| 1535 | * start: file offset where zero starts, will be made upper block aligned. | ||
| 1536 | * len: it will be trimmed to the end of current cluster if "start + len" | ||
| 1537 | * is bigger than it. | ||
| 1538 | */ | ||
| 1539 | static int ocfs2_zeroout_partial_cluster(struct inode *inode, | ||
| 1540 | u64 start, u64 len) | ||
| 1541 | { | ||
| 1542 | int ret; | ||
| 1543 | u64 start_block, end_block, nr_blocks; | ||
| 1544 | u64 p_block, offset; | ||
| 1545 | u32 cluster, p_cluster, nr_clusters; | ||
| 1546 | struct super_block *sb = inode->i_sb; | ||
| 1547 | u64 end = ocfs2_align_bytes_to_clusters(sb, start); | ||
| 1548 | |||
| 1549 | if (start + len < end) | ||
| 1550 | end = start + len; | ||
| 1551 | |||
| 1552 | start_block = ocfs2_blocks_for_bytes(sb, start); | ||
| 1553 | end_block = ocfs2_blocks_for_bytes(sb, end); | ||
| 1554 | nr_blocks = end_block - start_block; | ||
| 1555 | if (!nr_blocks) | ||
| 1556 | return 0; | ||
| 1557 | |||
| 1558 | cluster = ocfs2_bytes_to_clusters(sb, start); | ||
| 1559 | ret = ocfs2_get_clusters(inode, cluster, &p_cluster, | ||
| 1560 | &nr_clusters, NULL); | ||
| 1561 | if (ret) | ||
| 1562 | return ret; | ||
| 1563 | if (!p_cluster) | ||
| 1564 | return 0; | ||
| 1565 | |||
| 1566 | offset = start_block - ocfs2_clusters_to_blocks(sb, cluster); | ||
| 1567 | p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset; | ||
| 1568 | return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS); | ||
| 1569 | } | ||
| 1570 | |||
| 1532 | static int ocfs2_zero_partial_clusters(struct inode *inode, | 1571 | static int ocfs2_zero_partial_clusters(struct inode *inode, |
| 1533 | u64 start, u64 len) | 1572 | u64 start, u64 len) |
| 1534 | { | 1573 | { |
| @@ -1538,6 +1577,7 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, · 3 unmodified lines | |||
| 1538 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1577 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 1539 | unsigned int csize = osb->s_clustersize; | 1578 | unsigned int csize = osb->s_clustersize; |
| 1540 | handle_t *handle; | 1579 | handle_t *handle; |
| 1580 | loff_t isize = i_size_read(inode); | ||
| 1541 | 1581 | ||
| 1542 | /* | 1582 | /* |
| 1543 | * The "start" and "end" values are NOT necessarily part of | 1583 | * The "start" and "end" values are NOT necessarily part of |
| @@ -1558,6 +1598,26 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, · 14 unmodified lines | |||
| 1558 | if ((start & (csize - 1)) == 0 && (end & (csize - 1)) == 0) | 1598 | if ((start & (csize - 1)) == 0 && (end & (csize - 1)) == 0) |
| 1559 | goto out; | 1599 | goto out; |
| 1560 | 1600 | ||
| 1601 | /* No page cache for EOF blocks, issue zero out to disk. */ | ||
| 1602 | if (end > isize) { | ||
| 1603 | /* | ||
| 1604 | * zeroout eof blocks in last cluster starting from | ||
| 1605 | * "isize" even "start" > "isize" because it is | ||
| 1606 | * complicated to zeroout just at "start" as "start" | ||
| 1607 | * may be not aligned with block size, buffer write | ||
| 1608 | * would be required to do that, but out of eof buffer | ||
| 1609 | * write is not supported. | ||
| 1610 | */ | ||
| 1611 | ret = ocfs2_zeroout_partial_cluster(inode, isize, | ||
| 1612 | end - isize); | ||
| 1613 | if (ret) { | ||
| 1614 | mlog_errno(ret); | ||
| 1615 | goto out; | ||
| 1616 | } | ||
| 1617 | if (start >= isize) | ||
| 1618 | goto out; | ||
| 1619 | end = isize; | ||
| 1620 | } | ||
| 1561 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | 1621 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
| 1562 | if (IS_ERR(handle)) { | 1622 | if (IS_ERR(handle)) { |
| 1563 | ret = PTR_ERR(handle); | 1623 | ret = PTR_ERR(handle); |
| @@ -1855,45 +1915,6 @@ out: · 291 unmodified lines | |||
| 1855 | return ret; | 1915 | return ret; |
| 1856 | } | 1916 | } |
| 1857 | 1917 | ||
| 1858 | /* | ||
| 1859 | * zero out partial blocks of one cluster. | ||
| 1860 | * | ||
| 1861 | * start: file offset where zero starts, will be made upper block aligned. | ||
| 1862 | * len: it will be trimmed to the end of current cluster if "start + len" | ||
| 1863 | * is bigger than it. | ||
| 1864 | */ | ||
| 1865 | static int ocfs2_zeroout_partial_cluster(struct inode *inode, | ||
| 1866 | u64 start, u64 len) | ||
| 1867 | { | ||
| 1868 | int ret; | ||
| 1869 | u64 start_block, end_block, nr_blocks; | ||
| 1870 | u64 p_block, offset; | ||
| 1871 | u32 cluster, p_cluster, nr_clusters; | ||
| 1872 | struct super_block *sb = inode->i_sb; | ||
| 1873 | u64 end = ocfs2_align_bytes_to_clusters(sb, start); | ||
| 1874 | |||
| 1875 | if (start + len < end) | ||
| 1876 | end = start + len; | ||
| 1877 | |||
| 1878 | start_block = ocfs2_blocks_for_bytes(sb, start); | ||
| 1879 | end_block = ocfs2_blocks_for_bytes(sb, end); | ||
| 1880 | nr_blocks = end_block - start_block; | ||
| 1881 | if (!nr_blocks) | ||
| 1882 | return 0; | ||
| 1883 | |||
| 1884 | cluster = ocfs2_bytes_to_clusters(sb, start); | ||
| 1885 | ret = ocfs2_get_clusters(inode, cluster, &p_cluster, | ||
| 1886 | &nr_clusters, NULL); | ||
| 1887 | if (ret) | ||
| 1888 | return ret; | ||
| 1889 | if (!p_cluster) | ||
| 1890 | return 0; | ||
| 1891 | |||
| 1892 | offset = start_block - ocfs2_clusters_to_blocks(sb, cluster); | ||
| 1893 | p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset; | ||
| 1894 | return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS); | ||
| 1895 | } | ||
| 1896 | |||
| 1897 | /* | 1918 | /* |
| 1898 | * Parts of this function taken from xfs_change_file_space() | 1919 | * Parts of this function taken from xfs_change_file_space() |
| 1899 | */ | 1920 | */ |
| @@ -1935,7 +1956,6 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, · 35 unmodified lines | |||
| 1935 | goto out_inode_unlock; | 1956 | goto out_inode_unlock; |
| 1936 | } | 1957 | } |
| 1937 | 1958 | ||
| 1938 | orig_isize = i_size_read(inode); | ||
| 1939 | switch (sr->l_whence) { | 1959 | switch (sr->l_whence) { |
| 1940 | case 0: /*SEEK_SET*/ | 1960 | case 0: /*SEEK_SET*/ |
| 1941 | break; | 1961 | break; |
| @@ -1943,7 +1963,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, · 1 unmodified line | |||
| 1943 | sr->l_start += f_pos; | 1963 | sr->l_start += f_pos; |
| 1944 | break; | 1964 | break; |
| 1945 | case 2: /*SEEK_END*/ | 1965 | case 2: /*SEEK_END*/ |
| 1946 | sr->l_start += orig_isize; | 1966 | sr->l_start += i_size_read(inode); |
| 1947 | break; | 1967 | break; |
| 1948 | default: | 1968 | default: |
| 1949 | ret = -EINVAL; | 1969 | ret = -EINVAL; |
| @@ -1998,6 +2018,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, · 48 unmodified lines | |||
| 1998 | ret = -EINVAL; | 2018 | ret = -EINVAL; |
| 1999 | } | 2019 | } |
| 2000 | 2020 | ||
| 2021 | orig_isize = i_size_read(inode); | ||
| 2001 | /* zeroout eof blocks in the cluster. */ | 2022 | /* zeroout eof blocks in the cluster. */ |
| 2002 | if (!ret && change_size && orig_isize < size) { | 2023 | if (!ret && change_size && orig_isize < size) { |
| 2003 | ret = ocfs2_zeroout_partial_cluster(inode, orig_isize, | 2024 | ret = ocfs2_zeroout_partial_cluster(inode, orig_isize, |
| @@ -429,20 +429,20 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) · 428 unmodified lines | |||
| 429 | #endif | 429 | #endif |
| 430 | 430 | ||
| 431 | /* | 431 | /* |
| 432 | * Only wake up if the pipe started out empty, since | 432 | * Epoll nonsensically wants a wakeup whether the pipe |
| 433 | * otherwise there should be no readers waiting. | 433 | * was already empty or not. |
| 434 | * | 434 | * |
| 435 | * If it wasn't empty we try to merge new data into | 435 | * If it wasn't empty we try to merge new data into |
| 436 | * the last buffer. | 436 | * the last buffer. |
| 437 | * | 437 | * |
| 438 | * That naturally merges small writes, but it also | 438 | * That naturally merges small writes, but it also |
| 439 | * page-aligs the rest of the writes for large writes | 439 | * page-aligns the rest of the writes for large writes |
| 440 | * spanning multiple pages. | 440 | * spanning multiple pages. |
| 441 | */ | 441 | */ |
| 442 | head = pipe->head; | 442 | head = pipe->head; |
| 443 | was_empty = pipe_empty(head, pipe->tail); | 443 | was_empty = true; |
| 444 | chars = total_len & (PAGE_SIZE-1); | 444 | chars = total_len & (PAGE_SIZE-1); |
| 445 | if (chars && !was_empty) { | 445 | if (chars && !pipe_empty(head, pipe->tail)) { |
| 446 | unsigned int mask = pipe->ring_size - 1; | 446 | unsigned int mask = pipe->ring_size - 1; |
| 447 | struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask]; | 447 | struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask]; |
| 448 | int offset = buf->offset + buf->len; | 448 | int offset = buf->offset + buf->len; |
| @@ -387,6 +387,24 @@ void pathrelse(struct treepath *search_path) · 386 unmodified lines | |||
| 387 | search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET; | 387 | search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET; |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | static int has_valid_deh_location(struct buffer_head *bh, struct item_head *ih) | ||
| 391 | { | ||
| 392 | struct reiserfs_de_head *deh; | ||
| 393 | int i; | ||
| 394 | |||
| 395 | deh = B_I_DEH(bh, ih); | ||
| 396 | for (i = 0; i < ih_entry_count(ih); i++) { | ||
| 397 | if (deh_location(&deh[i]) > ih_item_len(ih)) { | ||
| 398 | reiserfs_warning(NULL, "reiserfs-5094", | ||
| 399 | "directory entry location seems wrong %h", | ||
| 400 | &deh[i]); | ||
| 401 | return 0; | ||
| 402 | } | ||
| 403 | } | ||
| 404 | |||
| 405 | return 1; | ||
| 406 | } | ||
| 407 | |||
| 390 | static int is_leaf(char *buf, int blocksize, struct buffer_head *bh) | 408 | static int is_leaf(char *buf, int blocksize, struct buffer_head *bh) |
| 391 | { | 409 | { |
| 392 | struct block_head *blkh; | 410 | struct block_head *blkh; |
| @@ -454,11 +472,14 @@ static int is_leaf(char *buf, int blocksize, struct buffer_head *bh) · 61 unmodified lines | |||
| 454 | "(second one): %h", ih); | 472 | "(second one): %h", ih); |
| 455 | return 0; | 473 | return 0; |
| 456 | } | 474 | } |
| 457 | if (is_direntry_le_ih(ih) && (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE))) { | 475 | if (is_direntry_le_ih(ih)) { |
| 458 | reiserfs_warning(NULL, "reiserfs-5093", | 476 | if (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE)) { |
| 459 | "item entry count seems wrong %h", | 477 | reiserfs_warning(NULL, "reiserfs-5093", |
| 460 | ih); | 478 | "item entry count seems wrong %h", |
| 461 | return 0; | 479 | ih); |
| 480 | return 0; | ||
| 481 | } | ||
| 482 | return has_valid_deh_location(bh, ih); | ||
| 462 | } | 483 | } |
| 463 | prev_location = ih_location(ih); | 484 | prev_location = ih_location(ih); |
| 464 | } | 485 | } |
| @@ -2082,6 +2082,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) · 2081 unmodified lines | |||
| 2082 | unlock_new_inode(root_inode); | 2082 | unlock_new_inode(root_inode); |
| 2083 | } | 2083 | } |
| 2084 | 2084 | ||
| 2085 | if (!S_ISDIR(root_inode->i_mode) || !inode_get_bytes(root_inode) || | ||
| 2086 | !root_inode->i_size) { | ||
| 2087 | SWARN(silent, s, "", "corrupt root inode, run fsck"); | ||
| 2088 | iput(root_inode); | ||
| 2089 | errval = -EUCLEAN; | ||
| 2090 | goto error; | ||
| 2091 | } | ||
| 2092 | |||
| 2085 | s->s_root = d_make_root(root_inode); | 2093 | s->s_root = d_make_root(root_inode); |
| 2086 | if (!s->s_root) | 2094 | if (!s->s_root) |
| 2087 | goto error; | 2095 | goto error; |
| @@ -32,6 +32,9 @@ static void seq_set_overflow(struct seq_file *m) · 31 unmodified lines | |||
| 32 | 32 | ||
| 33 | static void *seq_buf_alloc(unsigned long size) | 33 | static void *seq_buf_alloc(unsigned long size) |
| 34 | { | 34 | { |
| 35 | if (unlikely(size > MAX_RW_COUNT)) | ||
| 36 | return NULL; | ||
| 37 | |||
| 35 | return kvmalloc(size, GFP_KERNEL_ACCOUNT); | 38 | return kvmalloc(size, GFP_KERNEL_ACCOUNT); |
| 36 | } | 39 | } |
| 37 | 40 | ||
| @@ -1236,23 +1236,21 @@ static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx, · 1235 unmodified lines | |||
| 1236 | } | 1236 | } |
| 1237 | 1237 | ||
| 1238 | static __always_inline int validate_range(struct mm_struct *mm, | 1238 | static __always_inline int validate_range(struct mm_struct *mm, |
| 1239 | __u64 *start, __u64 len) | 1239 | __u64 start, __u64 len) |
| 1240 | { | 1240 | { |
| 1241 | __u64 task_size = mm->task_size; | 1241 | __u64 task_size = mm->task_size; |
| 1242 | 1242 | ||
| 1243 | *start = untagged_addr(*start); | 1243 | if (start & ~PAGE_MASK) |
| 1244 | |||
| 1245 | if (*start & ~PAGE_MASK) | ||
| 1246 | return -EINVAL; | 1244 | return -EINVAL; |
| 1247 | if (len & ~PAGE_MASK) | 1245 | if (len & ~PAGE_MASK) |
| 1248 | return -EINVAL; | 1246 | return -EINVAL; |
| 1249 | if (!len) | 1247 | if (!len) |
| 1250 | return -EINVAL; | 1248 | return -EINVAL; |
| 1251 | if (*start < mmap_min_addr) | 1249 | if (start < mmap_min_addr) |
| 1252 | return -EINVAL; | 1250 | return -EINVAL; |
| 1253 | if (*start >= task_size) | 1251 | if (start >= task_size) |
| 1254 | return -EINVAL; | 1252 | return -EINVAL; |
| 1255 | if (len > task_size - *start) | 1253 | if (len > task_size - start) |
| 1256 | return -EINVAL; | 1254 | return -EINVAL; |
| 1257 | return 0; | 1255 | return 0; |
| 1258 | } | 1256 | } |
| @@ -1316,7 +1314,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 57 unmodified lines | |||
| 1316 | vm_flags |= VM_UFFD_MINOR; | 1314 | vm_flags |= VM_UFFD_MINOR; |
| 1317 | } | 1315 | } |
| 1318 | 1316 | ||
| 1319 | ret = validate_range(mm, &uffdio_register.range.start, | 1317 | ret = validate_range(mm, uffdio_register.range.start, |
| 1320 | uffdio_register.range.len); | 1318 | uffdio_register.range.len); |
| 1321 | if (ret) | 1319 | if (ret) |
| 1322 | goto out; | 1320 | goto out; |
| @@ -1522,7 +1520,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, · 199 unmodified lines | |||
| 1522 | if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister))) | 1520 | if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister))) |
| 1523 | goto out; | 1521 | goto out; |
| 1524 | 1522 | ||
| 1525 | ret = validate_range(mm, &uffdio_unregister.start, | 1523 | ret = validate_range(mm, uffdio_unregister.start, |
| 1526 | uffdio_unregister.len); | 1524 | uffdio_unregister.len); |
| 1527 | if (ret) | 1525 | if (ret) |
| 1528 | goto out; | 1526 | goto out; |
| @@ -1671,7 +1669,7 @@ static int userfaultfd_wake(struct userfaultfd_ctx *ctx, · 142 unmodified lines | |||
| 1671 | if (copy_from_user(&uffdio_wake, buf, sizeof(uffdio_wake))) | 1669 | if (copy_from_user(&uffdio_wake, buf, sizeof(uffdio_wake))) |
| 1672 | goto out; | 1670 | goto out; |
| 1673 | 1671 | ||
| 1674 | ret = validate_range(ctx->mm, &uffdio_wake.start, uffdio_wake.len); | 1672 | ret = validate_range(ctx->mm, uffdio_wake.start, uffdio_wake.len); |
| 1675 | if (ret) | 1673 | if (ret) |
| 1676 | goto out; | 1674 | goto out; |
| 1677 | 1675 | ||
| @@ -1711,7 +1709,7 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx, · 33 unmodified lines | |||
| 1711 | sizeof(uffdio_copy)-sizeof(__s64))) | 1709 | sizeof(uffdio_copy)-sizeof(__s64))) |
| 1712 | goto out; | 1710 | goto out; |
| 1713 | 1711 | ||
| 1714 | ret = validate_range(ctx->mm, &uffdio_copy.dst, uffdio_copy.len); | 1712 | ret = validate_range(ctx->mm, uffdio_copy.dst, uffdio_copy.len); |
| 1715 | if (ret) | 1713 | if (ret) |
| 1716 | goto out; | 1714 | goto out; |
| 1717 | /* | 1715 | /* |
| @@ -1768,7 +1766,7 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx, · 50 unmodified lines | |||
| 1768 | sizeof(uffdio_zeropage)-sizeof(__s64))) | 1766 | sizeof(uffdio_zeropage)-sizeof(__s64))) |
| 1769 | goto out; | 1767 | goto out; |
| 1770 | 1768 | ||
| 1771 | ret = validate_range(ctx->mm, &uffdio_zeropage.range.start, | 1769 | ret = validate_range(ctx->mm, uffdio_zeropage.range.start, |
| 1772 | uffdio_zeropage.range.len); | 1770 | uffdio_zeropage.range.len); |
| 1773 | if (ret) | 1771 | if (ret) |
| 1774 | goto out; | 1772 | goto out; |
| @@ -1818,7 +1816,7 @@ static int userfaultfd_writeprotect(struct userfaultfd_ctx *ctx, · 43 unmodified lines | |||
| 1818 | sizeof(struct uffdio_writeprotect))) | 1816 | sizeof(struct uffdio_writeprotect))) |
| 1819 | return -EFAULT; | 1817 | return -EFAULT; |
| 1820 | 1818 | ||
| 1821 | ret = validate_range(ctx->mm, &uffdio_wp.range.start, | 1819 | ret = validate_range(ctx->mm, uffdio_wp.range.start, |
| 1822 | uffdio_wp.range.len); | 1820 | uffdio_wp.range.len); |
| 1823 | if (ret) | 1821 | if (ret) |
| 1824 | return ret; | 1822 | return ret; |
| @@ -1866,7 +1864,7 @@ static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg) · 41 unmodified lines | |||
| 1866 | sizeof(uffdio_continue) - (sizeof(__s64)))) | 1864 | sizeof(uffdio_continue) - (sizeof(__s64)))) |
| 1867 | goto out; | 1865 | goto out; |
| 1868 | 1866 | ||
| 1869 | ret = validate_range(ctx->mm, &uffdio_continue.range.start, | 1867 | ret = validate_range(ctx->mm, uffdio_continue.range.start, |
| 1870 | uffdio_continue.range.len); | 1868 | uffdio_continue.range.len); |
| 1871 | if (ret) | 1869 | if (ret) |
| 1872 | goto out; | 1870 | goto out; |
| @@ -411,7 +411,16 @@ struct xfs_log_dinode { · 410 unmodified lines | |||
| 411 | /* start of the extended dinode, writable fields */ | 411 | /* start of the extended dinode, writable fields */ |
| 412 | uint32_t di_crc; /* CRC of the inode */ | 412 | uint32_t di_crc; /* CRC of the inode */ |
| 413 | uint64_t di_changecount; /* number of attribute changes */ | 413 | uint64_t di_changecount; /* number of attribute changes */ |
| 414 | xfs_lsn_t di_lsn; /* flush sequence */ | 414 | |
| 415 | /* | ||
| 416 | * The LSN we write to this field during formatting is not a reflection | ||
| 417 | * of the current on-disk LSN. It should never be used for recovery | ||
| 418 | * sequencing, nor should it be recovered into the on-disk inode at all. | ||
| 419 | * See xlog_recover_inode_commit_pass2() and xfs_log_dinode_to_disk() | ||
| 420 | * for details. | ||
| 421 | */ | ||
| 422 | xfs_lsn_t di_lsn; | ||
| 423 | |||
| 415 | uint64_t di_flags2; /* more random flags */ | 424 | uint64_t di_flags2; /* more random flags */ |
| 416 | uint32_t di_cowextsize; /* basic cow extent size for file */ | 425 | uint32_t di_cowextsize; /* basic cow extent size for file */ |
| 417 | uint8_t di_pad2[12]; /* more padding for future expansion */ | 426 | uint8_t di_pad2[12]; /* more padding for future expansion */ |
| @@ -698,7 +698,8 @@ xlog_recover_do_inode_buffer( · 697 unmodified lines | |||
| 698 | static xfs_lsn_t | 698 | static xfs_lsn_t |
| 699 | xlog_recover_get_buf_lsn( | 699 | xlog_recover_get_buf_lsn( |
| 700 | struct xfs_mount *mp, | 700 | struct xfs_mount *mp, |
| 701 | struct xfs_buf *bp) | 701 | struct xfs_buf *bp, |
| 702 | struct xfs_buf_log_format *buf_f) | ||
| 702 | { | 703 | { |
| 703 | uint32_t magic32; | 704 | uint32_t magic32; |
| 704 | uint16_t magic16; | 705 | uint16_t magic16; |
| @@ -706,11 +707,20 @@ xlog_recover_get_buf_lsn( · 1 unmodified line | |||
| 706 | void *blk = bp->b_addr; | 707 | void *blk = bp->b_addr; |
| 707 | uuid_t *uuid; | 708 | uuid_t *uuid; |
| 708 | xfs_lsn_t lsn = -1; | 709 | xfs_lsn_t lsn = -1; |
| 710 | uint16_t blft; | ||
| 709 | 711 | ||
| 710 | /* v4 filesystems always recover immediately */ | 712 | /* v4 filesystems always recover immediately */ |
| 711 | if (!xfs_sb_version_hascrc(&mp->m_sb)) | 713 | if (!xfs_sb_version_hascrc(&mp->m_sb)) |
| 712 | goto recover_immediately; | 714 | goto recover_immediately; |
| 713 | 715 | ||
| 716 | /* | ||
| 717 | * realtime bitmap and summary file blocks do not have magic numbers or | ||
| 718 | * UUIDs, so we must recover them immediately. | ||
| 719 | */ | ||
| 720 | blft = xfs_blft_from_flags(buf_f); | ||
| 721 | if (blft == XFS_BLFT_RTBITMAP_BUF || blft == XFS_BLFT_RTSUMMARY_BUF) | ||
| 722 | goto recover_immediately; | ||
| 723 | |||
| 714 | magic32 = be32_to_cpu(*(__be32 *)blk); | 724 | magic32 = be32_to_cpu(*(__be32 *)blk); |
| 715 | switch (magic32) { | 725 | switch (magic32) { |
| 716 | case XFS_ABTB_CRC_MAGIC: | 726 | case XFS_ABTB_CRC_MAGIC: |
| @@ -796,6 +806,7 @@ xlog_recover_get_buf_lsn( · 79 unmodified lines | |||
| 796 | switch (magicda) { | 806 | switch (magicda) { |
| 797 | case XFS_DIR3_LEAF1_MAGIC: | 807 | case XFS_DIR3_LEAF1_MAGIC: |
| 798 | case XFS_DIR3_LEAFN_MAGIC: | 808 | case XFS_DIR3_LEAFN_MAGIC: |
| 809 | case XFS_ATTR3_LEAF_MAGIC: | ||
| 799 | case XFS_DA3_NODE_MAGIC: | 810 | case XFS_DA3_NODE_MAGIC: |
| 800 | lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); | 811 | lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); |
| 801 | uuid = &((struct xfs_da3_blkinfo *)blk)->uuid; | 812 | uuid = &((struct xfs_da3_blkinfo *)blk)->uuid; |
| @@ -919,7 +930,7 @@ xlog_recover_buf_commit_pass2( · 117 unmodified lines | |||
| 919 | * the verifier will be reset to match whatever recover turns that | 930 | * the verifier will be reset to match whatever recover turns that |
| 920 | * buffer into. | 931 | * buffer into. |
| 921 | */ | 932 | */ |
| 922 | lsn = xlog_recover_get_buf_lsn(mp, bp); | 933 | lsn = xlog_recover_get_buf_lsn(mp, bp, buf_f); |
| 923 | if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) { | 934 | if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) { |
| 924 | trace_xfs_log_recover_buf_skip(log, buf_f); | 935 | trace_xfs_log_recover_buf_skip(log, buf_f); |
| 925 | xlog_recover_validate_buf_type(mp, bp, buf_f, NULLCOMMITLSN); | 936 | xlog_recover_validate_buf_type(mp, bp, buf_f, NULLCOMMITLSN); |
| @@ -145,7 +145,8 @@ xfs_log_dinode_to_disk_ts( · 144 unmodified lines | |||
| 145 | STATIC void | 145 | STATIC void |
| 146 | xfs_log_dinode_to_disk( | 146 | xfs_log_dinode_to_disk( |
| 147 | struct xfs_log_dinode *from, | 147 | struct xfs_log_dinode *from, |
| 148 | struct xfs_dinode *to) | 148 | struct xfs_dinode *to, |
| 149 | xfs_lsn_t lsn) | ||
| 149 | { | 150 | { |
| 150 | to->di_magic = cpu_to_be16(from->di_magic); | 151 | to->di_magic = cpu_to_be16(from->di_magic); |
| 151 | to->di_mode = cpu_to_be16(from->di_mode); | 152 | to->di_mode = cpu_to_be16(from->di_mode); |
| @@ -182,7 +183,7 @@ xfs_log_dinode_to_disk( · 30 unmodified lines | |||
| 182 | to->di_flags2 = cpu_to_be64(from->di_flags2); | 183 | to->di_flags2 = cpu_to_be64(from->di_flags2); |
| 183 | to->di_cowextsize = cpu_to_be32(from->di_cowextsize); | 184 | to->di_cowextsize = cpu_to_be32(from->di_cowextsize); |
| 184 | to->di_ino = cpu_to_be64(from->di_ino); | 185 | to->di_ino = cpu_to_be64(from->di_ino); |
| 185 | to->di_lsn = cpu_to_be64(from->di_lsn); | 186 | to->di_lsn = cpu_to_be64(lsn); |
| 186 | memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); | 187 | memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); |
| 187 | uuid_copy(&to->di_uuid, &from->di_uuid); | 188 | uuid_copy(&to->di_uuid, &from->di_uuid); |
| 188 | to->di_flushiter = 0; | 189 | to->di_flushiter = 0; |
| @@ -261,16 +262,25 @@ xlog_recover_inode_commit_pass2( · 72 unmodified lines | |||
| 261 | } | 262 | } |
| 262 | 263 | ||
| 263 | /* | 264 | /* |
| 264 | * If the inode has an LSN in it, recover the inode only if it's less | 265 | * If the inode has an LSN in it, recover the inode only if the on-disk |
| 265 | * than the lsn of the transaction we are replaying. Note: we still | 266 | * inode's LSN is older than the lsn of the transaction we are |
| 266 | * need to replay an owner change even though the inode is more recent | 267 | * replaying. We can have multiple checkpoints with the same start LSN, |
| 267 | * than the transaction as there is no guarantee that all the btree | 268 | * so the current LSN being equal to the on-disk LSN doesn't necessarily |
| 268 | * blocks are more recent than this transaction, too. | 269 | * mean that the on-disk inode is more recent than the change being |
| 270 | * replayed. | ||
| 271 | * | ||
| 272 | * We must check the current_lsn against the on-disk inode | ||
| 273 | * here because the we can't trust the log dinode to contain a valid LSN | ||
| 274 | * (see comment below before replaying the log dinode for details). | ||
| 275 | * | ||
| 276 | * Note: we still need to replay an owner change even though the inode | ||
| 277 | * is more recent than the transaction as there is no guarantee that all | ||
| 278 | * the btree blocks are more recent than this transaction, too. | ||
| 269 | */ | 279 | */ |
| 270 | if (dip->di_version >= 3) { | 280 | if (dip->di_version >= 3) { |
| 271 | xfs_lsn_t lsn = be64_to_cpu(dip->di_lsn); | 281 | xfs_lsn_t lsn = be64_to_cpu(dip->di_lsn); |
| 272 | 282 | ||
| 273 | if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) { | 283 | if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) > 0) { |
| 274 | trace_xfs_log_recover_inode_skip(log, in_f); | 284 | trace_xfs_log_recover_inode_skip(log, in_f); |
| 275 | error = 0; | 285 | error = 0; |
| 276 | goto out_owner_change; | 286 | goto out_owner_change; |
| @@ -368,8 +378,17 @@ xlog_recover_inode_commit_pass2( · 91 unmodified lines | |||
| 368 | goto out_release; | 378 | goto out_release; |
| 369 | } | 379 | } |
| 370 | 380 | ||
| 371 | /* recover the log dinode inode into the on disk inode */ | 381 | /* |
| 372 | xfs_log_dinode_to_disk(ldip, dip); | 382 | * Recover the log dinode inode into the on disk inode. |
| 383 | * | ||
| 384 | * The LSN in the log dinode is garbage - it can be zero or reflect | ||
| 385 | * stale in-memory runtime state that isn't coherent with the changes | ||
| 386 | * logged in this transaction or the changes written to the on-disk | ||
| 387 | * inode. Hence we write the current lSN into the inode because that | ||
| 388 | * matches what xfs_iflush() would write inode the inode when flushing | ||
| 389 | * the changes in this transaction. | ||
| 390 | */ | ||
| 391 | xfs_log_dinode_to_disk(ldip, dip, current_lsn); | ||
| 373 | 392 | ||
| 374 | fields = in_f->ilf_fields; | 393 | fields = in_f->ilf_fields; |
| 375 | if (fields & XFS_ILOG_DEV) | 394 | if (fields & XFS_ILOG_DEV) |
| @@ -78,13 +78,12 @@ xlog_verify_iclog( · 77 unmodified lines | |||
| 78 | STATIC void | 78 | STATIC void |
| 79 | xlog_verify_tail_lsn( | 79 | xlog_verify_tail_lsn( |
| 80 | struct xlog *log, | 80 | struct xlog *log, |
| 81 | struct xlog_in_core *iclog, | 81 | struct xlog_in_core *iclog); |
| 82 | xfs_lsn_t tail_lsn); | ||
| 83 | #else | 82 | #else |
| 84 | #define xlog_verify_dest_ptr(a,b) | 83 | #define xlog_verify_dest_ptr(a,b) |
| 85 | #define xlog_verify_grant_tail(a) | 84 | #define xlog_verify_grant_tail(a) |
| 86 | #define xlog_verify_iclog(a,b,c) | 85 | #define xlog_verify_iclog(a,b,c) |
| 87 | #define xlog_verify_tail_lsn(a,b,c) | 86 | #define xlog_verify_tail_lsn(a,b) |
| 88 | #endif | 87 | #endif |
| 89 | 88 | ||
| 90 | STATIC int | 89 | STATIC int |
| @@ -487,51 +486,80 @@ out_error: · 396 unmodified lines | |||
| 487 | return error; | 486 | return error; |
| 488 | } | 487 | } |
| 489 | 488 | ||
| 490 | static bool | ||
| 491 | __xlog_state_release_iclog( | ||
| 492 | struct xlog *log, | ||
| 493 | struct xlog_in_core *iclog) | ||
| 494 | { | ||
| 495 | lockdep_assert_held(&log->l_icloglock); | ||
| 496 | |||
| 497 | if (iclog->ic_state == XLOG_STATE_WANT_SYNC) { | ||
| 498 | /* update tail before writing to iclog */ | ||
| 499 | xfs_lsn_t tail_lsn = xlog_assign_tail_lsn(log->l_mp); | ||
| 500 | |||
| 501 | iclog->ic_state = XLOG_STATE_SYNCING; | ||
| 502 | iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn); | ||
| 503 | xlog_verify_tail_lsn(log, iclog, tail_lsn); | ||
| 504 | /* cycle incremented when incrementing curr_block */ | ||
| 505 | trace_xlog_iclog_syncing(iclog, _RET_IP_); | ||
| 506 | return true; | ||
| 507 | } | ||
| 508 | |||
| 509 | ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); | ||
| 510 | return false; | ||
| 511 | } | ||
| 512 | |||
| 513 | /* | 489 | /* |
| 514 | * Flush iclog to disk if this is the last reference to the given iclog and the | 490 | * Flush iclog to disk if this is the last reference to the given iclog and the |
| 515 | * it is in the WANT_SYNC state. | 491 | * it is in the WANT_SYNC state. |
| 492 | * | ||
| 493 | * If the caller passes in a non-zero @old_tail_lsn and the current log tail | ||
| 494 | * does not match, there may be metadata on disk that must be persisted before | ||
| 495 | * this iclog is written. To satisfy that requirement, set the | ||
| 496 | * XLOG_ICL_NEED_FLUSH flag as a condition for writing this iclog with the new | ||
| 497 | * log tail value. | ||
| 498 | * | ||
| 499 | * If XLOG_ICL_NEED_FUA is already set on the iclog, we need to ensure that the | ||
| 500 | * log tail is updated correctly. NEED_FUA indicates that the iclog will be | ||
| 501 | * written to stable storage, and implies that a commit record is contained | ||
| 502 | * within the iclog. We need to ensure that the log tail does not move beyond | ||
| 503 | * the tail that the first commit record in the iclog ordered against, otherwise | ||
| 504 | * correct recovery of that checkpoint becomes dependent on future operations | ||
| 505 | * performed on this iclog. | ||
| 506 | * | ||
| 507 | * Hence if NEED_FUA is set and the current iclog tail lsn is empty, write the | ||
| 508 | * current tail into iclog. Once the iclog tail is set, future operations must | ||
| 509 | * not modify it, otherwise they potentially violate ordering constraints for | ||
| 510 | * the checkpoint commit that wrote the initial tail lsn value. The tail lsn in | ||
| 511 | * the iclog will get zeroed on activation of the iclog after sync, so we | ||
| 512 | * always capture the tail lsn on the iclog on the first NEED_FUA release | ||
| 513 | * regardless of the number of active reference counts on this iclog. | ||
| 516 | */ | 514 | */ |
| 515 | |||
| 517 | int | 516 | int |
| 518 | xlog_state_release_iclog( | 517 | xlog_state_release_iclog( |
| 519 | struct xlog *log, | 518 | struct xlog *log, |
| 520 | struct xlog_in_core *iclog) | 519 | struct xlog_in_core *iclog, |
| 520 | xfs_lsn_t old_tail_lsn) | ||
| 521 | { | 521 | { |
| 522 | xfs_lsn_t tail_lsn; | ||
| 522 | lockdep_assert_held(&log->l_icloglock); | 523 | lockdep_assert_held(&log->l_icloglock); |
| 523 | 524 | ||
| 524 | trace_xlog_iclog_release(iclog, _RET_IP_); | 525 | trace_xlog_iclog_release(iclog, _RET_IP_); |
| 525 | if (iclog->ic_state == XLOG_STATE_IOERROR) | 526 | if (iclog->ic_state == XLOG_STATE_IOERROR) |
| 526 | return -EIO; | 527 | return -EIO; |
| 527 | 528 | ||
| 528 | if (atomic_dec_and_test(&iclog->ic_refcnt) && | 529 | /* |
| 529 | __xlog_state_release_iclog(log, iclog)) { | 530 | * Grabbing the current log tail needs to be atomic w.r.t. the writing |
| 530 | spin_unlock(&log->l_icloglock); | 531 | * of the tail LSN into the iclog so we guarantee that the log tail does |
| 531 | xlog_sync(log, iclog); | 532 | * not move between deciding if a cache flush is required and writing |
| 532 | spin_lock(&log->l_icloglock); | 533 | * the LSN into the iclog below. |
| 534 | */ | ||
| 535 | if (old_tail_lsn || iclog->ic_state == XLOG_STATE_WANT_SYNC) { | ||
| 536 | tail_lsn = xlog_assign_tail_lsn(log->l_mp); | ||
| 537 | |||
| 538 | if (old_tail_lsn && tail_lsn != old_tail_lsn) | ||
| 539 | iclog->ic_flags |= XLOG_ICL_NEED_FLUSH; | ||
| 540 | |||
| 541 | if ((iclog->ic_flags & XLOG_ICL_NEED_FUA) && | ||
| 542 | !iclog->ic_header.h_tail_lsn) | ||
| 543 | iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn); | ||
| 533 | } | 544 | } |
| 534 | 545 | ||
| 546 | if (!atomic_dec_and_test(&iclog->ic_refcnt)) | ||
| 547 | return 0; | ||
| 548 | |||
| 549 | if (iclog->ic_state != XLOG_STATE_WANT_SYNC) { | ||
| 550 | ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); | ||
| 551 | return 0; | ||
| 552 | } | ||
| 553 | |||
| 554 | iclog->ic_state = XLOG_STATE_SYNCING; | ||
| 555 | if (!iclog->ic_header.h_tail_lsn) | ||
| 556 | iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn); | ||
| 557 | xlog_verify_tail_lsn(log, iclog); | ||
| 558 | trace_xlog_iclog_syncing(iclog, _RET_IP_); | ||
| 559 | |||
| 560 | spin_unlock(&log->l_icloglock); | ||
| 561 | xlog_sync(log, iclog); | ||
| 562 | spin_lock(&log->l_icloglock); | ||
| 535 | return 0; | 563 | return 0; |
| 536 | } | 564 | } |
| 537 | 565 | ||
| @@ -773,6 +801,21 @@ xfs_log_mount_cancel( · 235 unmodified lines | |||
| 773 | xfs_log_unmount(mp); | 801 | xfs_log_unmount(mp); |
| 774 | } | 802 | } |
| 775 | 803 | ||
| 804 | /* | ||
| 805 | * Flush out the iclog to disk ensuring that device caches are flushed and | ||
| 806 | * the iclog hits stable storage before any completion waiters are woken. | ||
| 807 | */ | ||
| 808 | static inline int | ||
| 809 | xlog_force_iclog( | ||
| 810 | struct xlog_in_core *iclog) | ||
| 811 | { | ||
| 812 | atomic_inc(&iclog->ic_refcnt); | ||
| 813 | iclog->ic_flags |= XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA; | ||
| 814 | if (iclog->ic_state == XLOG_STATE_ACTIVE) | ||
| 815 | xlog_state_switch_iclogs(iclog->ic_log, iclog, 0); | ||
| 816 | return xlog_state_release_iclog(iclog->ic_log, iclog, 0); | ||
| 817 | } | ||
| 818 | |||
| 776 | /* | 819 | /* |
| 777 | * Wait for the iclog and all prior iclogs to be written disk as required by the | 820 | * Wait for the iclog and all prior iclogs to be written disk as required by the |
| 778 | * log force state machine. Waiting on ic_force_wait ensures iclog completions | 821 | * log force state machine. Waiting on ic_force_wait ensures iclog completions |
| @@ -827,13 +870,6 @@ xlog_write_unmount_record( · 48 unmodified lines | |||
| 827 | /* account for space used by record data */ | 870 | /* account for space used by record data */ |
| 828 | ticket->t_curr_res -= sizeof(ulf); | 871 | ticket->t_curr_res -= sizeof(ulf); |
| 829 | 872 | ||
| 830 | /* | ||
| 831 | * For external log devices, we need to flush the data device cache | ||
| 832 | * first to ensure all metadata writeback is on stable storage before we | ||
| 833 | * stamp the tail LSN into the unmount record. | ||
| 834 | */ | ||
| 835 | if (log->l_targ != log->l_mp->m_ddev_targp) | ||
| 836 | blkdev_issue_flush(log->l_targ->bt_bdev); | ||
| 837 | return xlog_write(log, &vec, ticket, NULL, NULL, XLOG_UNMOUNT_TRANS); | 873 | return xlog_write(log, &vec, ticket, NULL, NULL, XLOG_UNMOUNT_TRANS); |
| 838 | } | 874 | } |
| 839 | 875 | ||
| @@ -865,18 +901,7 @@ out_err: · 25 unmodified lines | |||
| 865 | 901 | ||
| 866 | spin_lock(&log->l_icloglock); | 902 | spin_lock(&log->l_icloglock); |
| 867 | iclog = log->l_iclog; | 903 | iclog = log->l_iclog; |
| 868 | atomic_inc(&iclog->ic_refcnt); | 904 | error = xlog_force_iclog(iclog); |
| 869 | if (iclog->ic_state == XLOG_STATE_ACTIVE) | ||
| 870 | xlog_state_switch_iclogs(log, iclog, 0); | ||
| 871 | else | ||
| 872 | ASSERT(iclog->ic_state == XLOG_STATE_WANT_SYNC || | ||
| 873 | iclog->ic_state == XLOG_STATE_IOERROR); | ||
| 874 | /* | ||
| 875 | * Ensure the journal is fully flushed and on stable storage once the | ||
| 876 | * iclog containing the unmount record is written. | ||
| 877 | */ | ||
| 878 | iclog->ic_flags |= (XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA); | ||
| 879 | error = xlog_state_release_iclog(log, iclog); | ||
| 880 | xlog_wait_on_iclog(iclog); | 905 | xlog_wait_on_iclog(iclog); |
| 881 | 906 | ||
| 882 | if (tic) { | 907 | if (tic) { |
| @@ -1796,10 +1821,20 @@ xlog_write_iclog( · 913 unmodified lines | |||
| 1796 | * metadata writeback and causing priority inversions. | 1821 | * metadata writeback and causing priority inversions. |
| 1797 | */ | 1822 | */ |
| 1798 | iclog->ic_bio.bi_opf = REQ_OP_WRITE | REQ_META | REQ_SYNC | REQ_IDLE; | 1823 | iclog->ic_bio.bi_opf = REQ_OP_WRITE | REQ_META | REQ_SYNC | REQ_IDLE; |
| 1799 | if (iclog->ic_flags & XLOG_ICL_NEED_FLUSH) | 1824 | if (iclog->ic_flags & XLOG_ICL_NEED_FLUSH) { |
| 1800 | iclog->ic_bio.bi_opf |= REQ_PREFLUSH; | 1825 | iclog->ic_bio.bi_opf |= REQ_PREFLUSH; |
| 1826 | /* | ||
| 1827 | * For external log devices, we also need to flush the data | ||
| 1828 | * device cache first to ensure all metadata writeback covered | ||
| 1829 | * by the LSN in this iclog is on stable storage. This is slow, | ||
| 1830 | * but it *must* complete before we issue the external log IO. | ||
| 1831 | */ | ||
| 1832 | if (log->l_targ != log->l_mp->m_ddev_targp) | ||
| 1833 | blkdev_issue_flush(log->l_mp->m_ddev_targp->bt_bdev); | ||
| 1834 | } | ||
| 1801 | if (iclog->ic_flags & XLOG_ICL_NEED_FUA) | 1835 | if (iclog->ic_flags & XLOG_ICL_NEED_FUA) |
| 1802 | iclog->ic_bio.bi_opf |= REQ_FUA; | 1836 | iclog->ic_bio.bi_opf |= REQ_FUA; |
| 1837 | |||
| 1803 | iclog->ic_flags &= ~(XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA); | 1838 | iclog->ic_flags &= ~(XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA); |
| 1804 | 1839 | ||
| 1805 | if (xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count)) { | 1840 | if (xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count)) { |
| @@ -2310,7 +2345,7 @@ xlog_write_copy_finish( · 504 unmodified lines | |||
| 2310 | return 0; | 2345 | return 0; |
| 2311 | 2346 | ||
| 2312 | release_iclog: | 2347 | release_iclog: |
| 2313 | error = xlog_state_release_iclog(log, iclog); | 2348 | error = xlog_state_release_iclog(log, iclog, 0); |
| 2314 | spin_unlock(&log->l_icloglock); | 2349 | spin_unlock(&log->l_icloglock); |
| 2315 | return error; | 2350 | return error; |
| 2316 | } | 2351 | } |
| @@ -2529,7 +2564,7 @@ next_lv: · 212 unmodified lines | |||
| 2529 | ASSERT(optype & XLOG_COMMIT_TRANS); | 2564 | ASSERT(optype & XLOG_COMMIT_TRANS); |
| 2530 | *commit_iclog = iclog; | 2565 | *commit_iclog = iclog; |
| 2531 | } else { | 2566 | } else { |
| 2532 | error = xlog_state_release_iclog(log, iclog); | 2567 | error = xlog_state_release_iclog(log, iclog, 0); |
| 2533 | } | 2568 | } |
| 2534 | spin_unlock(&log->l_icloglock); | 2569 | spin_unlock(&log->l_icloglock); |
| 2535 | 2570 | ||
| @@ -2567,6 +2602,7 @@ xlog_state_activate_iclog( · 31 unmodified lines | |||
| 2567 | memset(iclog->ic_header.h_cycle_data, 0, | 2602 | memset(iclog->ic_header.h_cycle_data, 0, |
| 2568 | sizeof(iclog->ic_header.h_cycle_data)); | 2603 | sizeof(iclog->ic_header.h_cycle_data)); |
| 2569 | iclog->ic_header.h_lsn = 0; | 2604 | iclog->ic_header.h_lsn = 0; |
| 2605 | iclog->ic_header.h_tail_lsn = 0; | ||
| 2570 | } | 2606 | } |
| 2571 | 2607 | ||
| 2572 | /* | 2608 | /* |
| @@ -2967,7 +3003,7 @@ restart: · 394 unmodified lines | |||
| 2967 | * reference to the iclog. | 3003 | * reference to the iclog. |
| 2968 | */ | 3004 | */ |
| 2969 | if (!atomic_add_unless(&iclog->ic_refcnt, -1, 1)) | 3005 | if (!atomic_add_unless(&iclog->ic_refcnt, -1, 1)) |
| 2970 | error = xlog_state_release_iclog(log, iclog); | 3006 | error = xlog_state_release_iclog(log, iclog, 0); |
| 2971 | spin_unlock(&log->l_icloglock); | 3007 | spin_unlock(&log->l_icloglock); |
| 2972 | if (error) | 3008 | if (error) |
| 2973 | return error; | 3009 | return error; |
| @@ -3131,6 +3167,35 @@ xlog_state_switch_iclogs( · 157 unmodified lines | |||
| 3131 | log->l_iclog = iclog->ic_next; | 3167 | log->l_iclog = iclog->ic_next; |
| 3132 | } | 3168 | } |
| 3133 | 3169 | ||
| 3170 | /* | ||
| 3171 | * Force the iclog to disk and check if the iclog has been completed before | ||
| 3172 | * xlog_force_iclog() returns. This can happen on synchronous (e.g. | ||
| 3173 | * pmem) or fast async storage because we drop the icloglock to issue the IO. | ||
| 3174 | * If completion has already occurred, tell the caller so that it can avoid an | ||
| 3175 | * unnecessary wait on the iclog. | ||
| 3176 | */ | ||
| 3177 | static int | ||
| 3178 | xlog_force_and_check_iclog( | ||
| 3179 | struct xlog_in_core *iclog, | ||
| 3180 | bool *completed) | ||
| 3181 | { | ||
| 3182 | xfs_lsn_t lsn = be64_to_cpu(iclog->ic_header.h_lsn); | ||
| 3183 | int error; | ||
| 3184 | |||
| 3185 | *completed = false; | ||
| 3186 | error = xlog_force_iclog(iclog); | ||
| 3187 | if (error) | ||
| 3188 | return error; | ||
| 3189 | |||
| 3190 | /* | ||
| 3191 | * If the iclog has already been completed and reused the header LSN | ||
| 3192 | * will have been rewritten by completion | ||
| 3193 | */ | ||
| 3194 | if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) | ||
| 3195 | *completed = true; | ||
| 3196 | return 0; | ||
| 3197 | } | ||
| 3198 | |||
| 3134 | /* | 3199 | /* |
| 3135 | * Write out all data in the in-core log as of this exact moment in time. | 3200 | * Write out all data in the in-core log as of this exact moment in time. |
| 3136 | * | 3201 | * |
| @@ -3165,7 +3230,6 @@ xfs_log_force( · 28 unmodified lines | |||
| 3165 | { | 3230 | { |
| 3166 | struct xlog *log = mp->m_log; | 3231 | struct xlog *log = mp->m_log; |
| 3167 | struct xlog_in_core *iclog; | 3232 | struct xlog_in_core *iclog; |
| 3168 | xfs_lsn_t lsn; | ||
| 3169 | 3233 | ||
| 3170 | XFS_STATS_INC(mp, xs_log_force); | 3234 | XFS_STATS_INC(mp, xs_log_force); |
| 3171 | trace_xfs_log_force(mp, 0, _RET_IP_); | 3235 | trace_xfs_log_force(mp, 0, _RET_IP_); |
| @@ -3193,39 +3257,33 @@ xfs_log_force( · 21 unmodified lines | |||
| 3193 | iclog = iclog->ic_prev; | 3257 | iclog = iclog->ic_prev; |
| 3194 | } else if (iclog->ic_state == XLOG_STATE_ACTIVE) { | 3258 | } else if (iclog->ic_state == XLOG_STATE_ACTIVE) { |
| 3195 | if (atomic_read(&iclog->ic_refcnt) == 0) { | 3259 | if (atomic_read(&iclog->ic_refcnt) == 0) { |
| 3196 | /* | 3260 | /* We have exclusive access to this iclog. */ |
| 3197 | * We are the only one with access to this iclog. | 3261 | bool completed; |
| 3198 | * | 3262 | |
| 3199 | * Flush it out now. There should be a roundoff of zero | 3263 | if (xlog_force_and_check_iclog(iclog, &completed)) |
| 3200 | * to show that someone has already taken care of the | ||
| 3201 | * roundoff from the previous sync. | ||
| 3202 | */ | ||
| 3203 | atomic_inc(&iclog->ic_refcnt); | ||
| 3204 | lsn = be64_to_cpu(iclog->ic_header.h_lsn); | ||
| 3205 | xlog_state_switch_iclogs(log, iclog, 0); | ||
| 3206 | if (xlog_state_release_iclog(log, iclog)) | ||
| 3207 | goto out_error; | 3264 | goto out_error; |
| 3208 | 3265 | ||
| 3209 | if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) | 3266 | if (completed) |
| 3210 | goto out_unlock; | 3267 | goto out_unlock; |
| 3211 | } else { | 3268 | } else { |
| 3212 | /* | 3269 | /* |
| 3213 | * Someone else is writing to this iclog. | 3270 | * Someone else is still writing to this iclog, so we |
| 3214 | * | 3271 | * need to ensure that when they release the iclog it |
| 3215 | * Use its call to flush out the data. However, the | 3272 | * gets synced immediately as we may be waiting on it. |
| 3216 | * other thread may not force out this LR, so we mark | ||
| 3217 | * it WANT_SYNC. | ||
| 3218 | */ | 3273 | */ |
| 3219 | xlog_state_switch_iclogs(log, iclog, 0); | 3274 | xlog_state_switch_iclogs(log, iclog, 0); |
| 3220 | } | 3275 | } |
| 3221 | } else { | ||
| 3222 | /* | ||
| 3223 | * If the head iclog is not active nor dirty, we just attach | ||
| 3224 | * ourselves to the head and go to sleep if necessary. | ||
| 3225 | */ | ||
| 3226 | ; | ||
| 3227 | } | 3276 | } |
| 3228 | 3277 | ||
| 3278 | /* | ||
| 3279 | * The iclog we are about to wait on may contain the checkpoint pushed | ||
| 3280 | * by the above xlog_cil_force() call, but it may not have been pushed | ||
| 3281 | * to disk yet. Like the ACTIVE case above, we need to make sure caches | ||
| 3282 | * are flushed when this iclog is written. | ||
| 3283 | */ | ||
| 3284 | if (iclog->ic_state == XLOG_STATE_WANT_SYNC) | ||
| 3285 | iclog->ic_flags |= XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA; | ||
| 3286 | |||
| 3229 | if (flags & XFS_LOG_SYNC) | 3287 | if (flags & XFS_LOG_SYNC) |
| 3230 | return xlog_wait_on_iclog(iclog); | 3288 | return xlog_wait_on_iclog(iclog); |
| 3231 | out_unlock: | 3289 | out_unlock: |
| @@ -3245,6 +3303,7 @@ xlog_force_lsn( · 13 unmodified lines | |||
| 3245 | bool already_slept) | 3303 | bool already_slept) |
| 3246 | { | 3304 | { |
| 3247 | struct xlog_in_core *iclog; | 3305 | struct xlog_in_core *iclog; |
| 3306 | bool completed; | ||
| 3248 | 3307 | ||
| 3249 | spin_lock(&log->l_icloglock); | 3308 | spin_lock(&log->l_icloglock); |
| 3250 | iclog = log->l_iclog; | 3309 | iclog = log->l_iclog; |
| @@ -3258,7 +3317,8 @@ xlog_force_lsn( · 7 unmodified lines | |||
| 3258 | goto out_unlock; | 3317 | goto out_unlock; |
| 3259 | } | 3318 | } |
| 3260 | 3319 | ||
| 3261 | if (iclog->ic_state == XLOG_STATE_ACTIVE) { | 3320 | switch (iclog->ic_state) { |
| 3321 | case XLOG_STATE_ACTIVE: | ||
| 3262 | /* | 3322 | /* |
| 3263 | * We sleep here if we haven't already slept (e.g. this is the | 3323 | * We sleep here if we haven't already slept (e.g. this is the |
| 3264 | * first time we've looked at the correct iclog buf) and the | 3324 | * first time we've looked at the correct iclog buf) and the |
| @@ -3281,12 +3341,31 @@ xlog_force_lsn( · 16 unmodified lines | |||
| 3281 | &log->l_icloglock); | 3341 | &log->l_icloglock); |
| 3282 | return -EAGAIN; | 3342 | return -EAGAIN; |
| 3283 | } | 3343 | } |
| 3284 | atomic_inc(&iclog->ic_refcnt); | 3344 | if (xlog_force_and_check_iclog(iclog, &completed)) |
| 3285 | xlog_state_switch_iclogs(log, iclog, 0); | ||
| 3286 | if (xlog_state_release_iclog(log, iclog)) | ||
| 3287 | goto out_error; | 3345 | goto out_error; |
| 3288 | if (log_flushed) | 3346 | if (log_flushed) |
| 3289 | *log_flushed = 1; | 3347 | *log_flushed = 1; |
| 3348 | if (completed) | ||
| 3349 | goto out_unlock; | ||
| 3350 | break; | ||
| 3351 | case XLOG_STATE_WANT_SYNC: | ||
| 3352 | /* | ||
| 3353 | * This iclog may contain the checkpoint pushed by the | ||
| 3354 | * xlog_cil_force_seq() call, but there are other writers still | ||
| 3355 | * accessing it so it hasn't been pushed to disk yet. Like the | ||
| 3356 | * ACTIVE case above, we need to make sure caches are flushed | ||
| 3357 | * when this iclog is written. | ||
| 3358 | */ | ||
| 3359 | iclog->ic_flags |= XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA; | ||
| 3360 | break; | ||
| 3361 | default: | ||
| 3362 | /* | ||
| 3363 | * The entire checkpoint was written by the CIL force and is on | ||
| 3364 | * its way to disk already. It will be stable when it | ||
| 3365 | * completes, so we don't need to manipulate caches here at all. | ||
| 3366 | * We just need to wait for completion if necessary. | ||
| 3367 | */ | ||
| 3368 | break; | ||
| 3290 | } | 3369 | } |
| 3291 | 3370 | ||
| 3292 | if (flags & XFS_LOG_SYNC) | 3371 | if (flags & XFS_LOG_SYNC) |
| @@ -3559,10 +3638,10 @@ xlog_verify_grant_tail( · 266 unmodified lines | |||
| 3559 | STATIC void | 3638 | STATIC void |
| 3560 | xlog_verify_tail_lsn( | 3639 | xlog_verify_tail_lsn( |
| 3561 | struct xlog *log, | 3640 | struct xlog *log, |
| 3562 | struct xlog_in_core *iclog, | 3641 | struct xlog_in_core *iclog) |
| 3563 | xfs_lsn_t tail_lsn) | ||
| 3564 | { | 3642 | { |
| 3565 | int blocks; | 3643 | xfs_lsn_t tail_lsn = be64_to_cpu(iclog->ic_header.h_tail_lsn); |
| 3644 | int blocks; | ||
| 3566 | 3645 | ||
| 3567 | if (CYCLE_LSN(tail_lsn) == log->l_prev_cycle) { | 3646 | if (CYCLE_LSN(tail_lsn) == log->l_prev_cycle) { |
| 3568 | blocks = | 3647 | blocks = |
| @@ -654,8 +654,9 @@ xlog_cil_push_work( · 653 unmodified lines | |||
| 654 | struct xfs_trans_header thdr; | 654 | struct xfs_trans_header thdr; |
| 655 | struct xfs_log_iovec lhdr; | 655 | struct xfs_log_iovec lhdr; |
| 656 | struct xfs_log_vec lvhdr = { NULL }; | 656 | struct xfs_log_vec lvhdr = { NULL }; |
| 657 | xfs_lsn_t preflush_tail_lsn; | ||
| 657 | xfs_lsn_t commit_lsn; | 658 | xfs_lsn_t commit_lsn; |
| 658 | xfs_lsn_t push_seq; | 659 | xfs_csn_t push_seq; |
| 659 | struct bio bio; | 660 | struct bio bio; |
| 660 | DECLARE_COMPLETION_ONSTACK(bdev_flush); | 661 | DECLARE_COMPLETION_ONSTACK(bdev_flush); |
| 661 | 662 | ||
| @@ -730,7 +731,15 @@ xlog_cil_push_work( · 68 unmodified lines | |||
| 730 | * because we hold the flush lock exclusively. Hence we can now issue | 731 | * because we hold the flush lock exclusively. Hence we can now issue |
| 731 | * a cache flush to ensure all the completed metadata in the journal we | 732 | * a cache flush to ensure all the completed metadata in the journal we |
| 732 | * are about to overwrite is on stable storage. | 733 | * are about to overwrite is on stable storage. |
| 734 | * | ||
| 735 | * Because we are issuing this cache flush before we've written the | ||
| 736 | * tail lsn to the iclog, we can have metadata IO completions move the | ||
| 737 | * tail forwards between the completion of this flush and the iclog | ||
| 738 | * being written. In this case, we need to re-issue the cache flush | ||
| 739 | * before the iclog write. To detect whether the log tail moves, sample | ||
| 740 | * the tail LSN *before* we issue the flush. | ||
| 733 | */ | 741 | */ |
| 742 | preflush_tail_lsn = atomic64_read(&log->l_tail_lsn); | ||
| 734 | xfs_flush_bdev_async(&bio, log->l_mp->m_ddev_targp->bt_bdev, | 743 | xfs_flush_bdev_async(&bio, log->l_mp->m_ddev_targp->bt_bdev, |
| 735 | &bdev_flush); | 744 | &bdev_flush); |
| 736 | 745 | ||
| @@ -941,7 +950,7 @@ restart: · 204 unmodified lines | |||
| 941 | * storage. | 950 | * storage. |
| 942 | */ | 951 | */ |
| 943 | commit_iclog->ic_flags |= XLOG_ICL_NEED_FUA; | 952 | commit_iclog->ic_flags |= XLOG_ICL_NEED_FUA; |
| 944 | xlog_state_release_iclog(log, commit_iclog); | 953 | xlog_state_release_iclog(log, commit_iclog, preflush_tail_lsn); |
| 945 | spin_unlock(&log->l_icloglock); | 954 | spin_unlock(&log->l_icloglock); |
| 946 | return; | 955 | return; |
| 947 | 956 | ||
| @@ -59,6 +59,16 @@ enum xlog_iclog_state { · 58 unmodified lines | |||
| 59 | { XLOG_STATE_DIRTY, "XLOG_STATE_DIRTY" }, \ | 59 | { XLOG_STATE_DIRTY, "XLOG_STATE_DIRTY" }, \ |
| 60 | { XLOG_STATE_IOERROR, "XLOG_STATE_IOERROR" } | 60 | { XLOG_STATE_IOERROR, "XLOG_STATE_IOERROR" } |
| 61 | 61 | ||
| 62 | /* | ||
| 63 | * In core log flags | ||
| 64 | */ | ||
| 65 | #define XLOG_ICL_NEED_FLUSH (1 << 0) /* iclog needs REQ_PREFLUSH */ | ||
| 66 | #define XLOG_ICL_NEED_FUA (1 << 1) /* iclog needs REQ_FUA */ | ||
| 67 | |||
| 68 | #define XLOG_ICL_STRINGS \ | ||
| 69 | { XLOG_ICL_NEED_FLUSH, "XLOG_ICL_NEED_FLUSH" }, \ | ||
| 70 | { XLOG_ICL_NEED_FUA, "XLOG_ICL_NEED_FUA" } | ||
| 71 | |||
| 62 | 72 | ||
| 63 | /* | 73 | /* |
| 64 | * Log ticket flags | 74 | * Log ticket flags |
| @@ -143,9 +153,6 @@ enum xlog_iclog_state { · 78 unmodified lines | |||
| 143 | 153 | ||
| 144 | #define XLOG_COVER_OPS 5 | 154 | #define XLOG_COVER_OPS 5 |
| 145 | 155 | ||
| 146 | #define XLOG_ICL_NEED_FLUSH (1 << 0) /* iclog needs REQ_PREFLUSH */ | ||
| 147 | #define XLOG_ICL_NEED_FUA (1 << 1) /* iclog needs REQ_FUA */ | ||
| 148 | |||
| 149 | /* Ticket reservation region accounting */ | 156 | /* Ticket reservation region accounting */ |
| 150 | #define XLOG_TIC_LEN_MAX 15 | 157 | #define XLOG_TIC_LEN_MAX 15 |
| 151 | 158 | ||
| @@ -497,7 +504,8 @@ int xlog_commit_record(struct xlog *log, struct xlog_ticket *ticket, · 345 unmodified lines | |||
| 497 | void xfs_log_ticket_ungrant(struct xlog *log, struct xlog_ticket *ticket); | 504 | void xfs_log_ticket_ungrant(struct xlog *log, struct xlog_ticket *ticket); |
| 498 | void xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket); | 505 | void xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket); |
| 499 | 506 | ||
| 500 | int xlog_state_release_iclog(struct xlog *log, struct xlog_in_core *iclog); | 507 | int xlog_state_release_iclog(struct xlog *log, struct xlog_in_core *iclog, |
| 508 | xfs_lsn_t log_tail_lsn); | ||
| 501 | 509 | ||
| 502 | /* | 510 | /* |
| 503 | * When we crack an atomic LSN, we sample it first so that the value will not | 511 | * When we crack an atomic LSN, we sample it first so that the value will not |
| @@ -3944,6 +3944,7 @@ DECLARE_EVENT_CLASS(xlog_iclog_class, · 3943 unmodified lines | |||
| 3944 | __field(uint32_t, state) | 3944 | __field(uint32_t, state) |
| 3945 | __field(int32_t, refcount) | 3945 | __field(int32_t, refcount) |
| 3946 | __field(uint32_t, offset) | 3946 | __field(uint32_t, offset) |
| 3947 | __field(uint32_t, flags) | ||
| 3947 | __field(unsigned long long, lsn) | 3948 | __field(unsigned long long, lsn) |
| 3948 | __field(unsigned long, caller_ip) | 3949 | __field(unsigned long, caller_ip) |
| 3949 | ), | 3950 | ), |
| @@ -3952,15 +3953,17 @@ DECLARE_EVENT_CLASS(xlog_iclog_class, · 2 unmodified lines | |||
| 3952 | __entry->state = iclog->ic_state; | 3953 | __entry->state = iclog->ic_state; |
| 3953 | __entry->refcount = atomic_read(&iclog->ic_refcnt); | 3954 | __entry->refcount = atomic_read(&iclog->ic_refcnt); |
| 3954 | __entry->offset = iclog->ic_offset; | 3955 | __entry->offset = iclog->ic_offset; |
| 3956 | __entry->flags = iclog->ic_flags; | ||
| 3955 | __entry->lsn = be64_to_cpu(iclog->ic_header.h_lsn); | 3957 | __entry->lsn = be64_to_cpu(iclog->ic_header.h_lsn); |
| 3956 | __entry->caller_ip = caller_ip; | 3958 | __entry->caller_ip = caller_ip; |
| 3957 | ), | 3959 | ), |
| 3958 | TP_printk("dev %d:%d state %s refcnt %d offset %u lsn 0x%llx caller %pS", | 3960 | TP_printk("dev %d:%d state %s refcnt %d offset %u lsn 0x%llx flags %s caller %pS", |
| 3959 | MAJOR(__entry->dev), MINOR(__entry->dev), | 3961 | MAJOR(__entry->dev), MINOR(__entry->dev), |
| 3960 | __print_symbolic(__entry->state, XLOG_STATE_STRINGS), | 3962 | __print_symbolic(__entry->state, XLOG_STATE_STRINGS), |
| 3961 | __entry->refcount, | 3963 | __entry->refcount, |
| 3962 | __entry->offset, | 3964 | __entry->offset, |
| 3963 | __entry->lsn, | 3965 | __entry->lsn, |
| 3966 | __print_flags(__entry->flags, "|", XLOG_ICL_STRINGS), | ||
| 3964 | (char *)__entry->caller_ip) | 3967 | (char *)__entry->caller_ip) |
| 3965 | 3968 | ||
| 3966 | ); | 3969 | ); |
| @@ -707,11 +707,6 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv); · 706 unmodified lines | |||
| 707 | * @hrv: Hardware Revision of the device, pass -1 to not check _HRV | 707 | * @hrv: Hardware Revision of the device, pass -1 to not check _HRV |
| 708 | * | 708 | * |
| 709 | * The caller is responsible for invoking acpi_dev_put() on the returned device. | 709 | * The caller is responsible for invoking acpi_dev_put() on the returned device. |
| 710 | * | ||
| 711 | * FIXME: Due to above requirement there is a window that may invalidate @adev | ||
| 712 | * and next iteration will use a dangling pointer, e.g. in the case of a | ||
| 713 | * hotplug event. That said, the caller should ensure that this will never | ||
| 714 | * happen. | ||
| 715 | */ | 710 | */ |
| 716 | #define for_each_acpi_dev_match(adev, hid, uid, hrv) \ | 711 | #define for_each_acpi_dev_match(adev, hid, uid, hrv) \ |
| 717 | for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv); \ | 712 | for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv); \ |
| @@ -725,7 +720,8 @@ static inline struct acpi_device *acpi_dev_get(struct acpi_device *adev) · 7 unmodified lines | |||
| 725 | 720 | ||
| 726 | static inline void acpi_dev_put(struct acpi_device *adev) | 721 | static inline void acpi_dev_put(struct acpi_device *adev) |
| 727 | { | 722 | { |
| 728 | put_device(&adev->dev); | 723 | if (adev) |
| 724 | put_device(&adev->dev); | ||
| 729 | } | 725 | } |
| 730 | 726 | ||
| 731 | struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle); | 727 | struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle); |
| @@ -68,6 +68,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, · 67 unmodified lines | |||
| 68 | unsigned long arg); | 68 | unsigned long arg); |
| 69 | 69 | ||
| 70 | #define DRM_IOCTL_NR(n) _IOC_NR(n) | 70 | #define DRM_IOCTL_NR(n) _IOC_NR(n) |
| 71 | #define DRM_IOCTL_TYPE(n) _IOC_TYPE(n) | ||
| 71 | #define DRM_MAJOR 226 | 72 | #define DRM_MAJOR 226 |
| 72 | 73 | ||
| 73 | /** | 74 | /** |
| @@ -57,7 +57,7 @@ struct blk_keyslot_manager; · 56 unmodified lines | |||
| 57 | * Maximum number of blkcg policies allowed to be registered concurrently. | 57 | * Maximum number of blkcg policies allowed to be registered concurrently. |
| 58 | * Defined here to simplify include dependency. | 58 | * Defined here to simplify include dependency. |
| 59 | */ | 59 | */ |
| 60 | #define BLKCG_MAX_POLS 5 | 60 | #define BLKCG_MAX_POLS 6 |
| 61 | 61 | ||
| 62 | typedef void (rq_end_io_fn)(struct request *, blk_status_t); | 62 | typedef void (rq_end_io_fn)(struct request *, blk_status_t); |
| 63 | 63 | ||
| @@ -134,4 +134,5 @@ BPF_LINK_TYPE(BPF_LINK_TYPE_CGROUP, cgroup) · 133 unmodified lines | |||
| 134 | BPF_LINK_TYPE(BPF_LINK_TYPE_ITER, iter) | 134 | BPF_LINK_TYPE(BPF_LINK_TYPE_ITER, iter) |
| 135 | #ifdef CONFIG_NET | 135 | #ifdef CONFIG_NET |
| 136 | BPF_LINK_TYPE(BPF_LINK_TYPE_NETNS, netns) | 136 | BPF_LINK_TYPE(BPF_LINK_TYPE_NETNS, netns) |
| 137 | BPF_LINK_TYPE(BPF_LINK_TYPE_XDP, xdp) | ||
| 137 | #endif | 138 | #endif |
| @@ -340,8 +340,8 @@ struct bpf_insn_aux_data { · 339 unmodified lines | |||
| 340 | }; | 340 | }; |
| 341 | u64 map_key_state; /* constant (32 bit) key tracking for maps */ | 341 | u64 map_key_state; /* constant (32 bit) key tracking for maps */ |
| 342 | int ctx_field_size; /* the ctx field size for load insn, maybe 0 */ | 342 | int ctx_field_size; /* the ctx field size for load insn, maybe 0 */ |
| 343 | int sanitize_stack_off; /* stack slot to be cleared */ | ||
| 344 | u32 seen; /* this insn was processed by the verifier at env->pass_cnt */ | 343 | u32 seen; /* this insn was processed by the verifier at env->pass_cnt */ |
| 344 | bool sanitize_stack_spill; /* subject to Spectre v4 sanitation */ | ||
| 345 | bool zext_dst; /* this insn zero extends dst reg */ | 345 | bool zext_dst; /* this insn zero extends dst reg */ |
| 346 | u8 alu_state; /* used in combination with alu_limit */ | 346 | u8 alu_state; /* used in combination with alu_limit */ |
| 347 | 347 | ||
| @@ -414,6 +414,7 @@ struct bpf_verifier_env { · 66 unmodified lines | |||
| 414 | u32 used_map_cnt; /* number of used maps */ | 414 | u32 used_map_cnt; /* number of used maps */ |
| 415 | u32 used_btf_cnt; /* number of used BTF objects */ | 415 | u32 used_btf_cnt; /* number of used BTF objects */ |
| 416 | u32 id_gen; /* used to generate unique reg IDs */ | 416 | u32 id_gen; /* used to generate unique reg IDs */ |
| 417 | bool explore_alu_limits; | ||
| 417 | bool allow_ptr_leaks; | 418 | bool allow_ptr_leaks; |
| 418 | bool allow_uninit_stack; | 419 | bool allow_uninit_stack; |
| 419 | bool allow_ptr_to_map_access; | 420 | bool allow_ptr_to_map_access; |
| @@ -2,7 +2,11 @@ · 1 unmodified line | |||
| 2 | #ifndef __LINUX_ENTRYKVM_H | 2 | #ifndef __LINUX_ENTRYKVM_H |
| 3 | #define __LINUX_ENTRYKVM_H | 3 | #define __LINUX_ENTRYKVM_H |
| 4 | 4 | ||
| 5 | #include <linux/entry-common.h> | 5 | #include <linux/static_call_types.h> |
| 6 | #include <linux/tracehook.h> | ||
| 7 | #include <linux/syscalls.h> | ||
| 8 | #include <linux/seccomp.h> | ||
| 9 | #include <linux/sched.h> | ||
| 6 | #include <linux/tick.h> | 10 | #include <linux/tick.h> |
| 7 | 11 | ||
| 8 | /* Transfer to guest mode work */ | 12 | /* Transfer to guest mode work */ |
| @@ -73,6 +73,11 @@ struct ctl_table_header; · 72 unmodified lines | |||
| 73 | /* unused opcode to mark call to interpreter with arguments */ | 73 | /* unused opcode to mark call to interpreter with arguments */ |
| 74 | #define BPF_CALL_ARGS 0xe0 | 74 | #define BPF_CALL_ARGS 0xe0 |
| 75 | 75 | ||
| 76 | /* unused opcode to mark speculation barrier for mitigating | ||
| 77 | * Speculative Store Bypass | ||
| 78 | */ | ||
| 79 | #define BPF_NOSPEC 0xc0 | ||
| 80 | |||
| 76 | /* As per nm, we expose JITed images as text (code) section for | 81 | /* As per nm, we expose JITed images as text (code) section for |
| 77 | * kallsyms. That way, tools like perf can find it to match | 82 | * kallsyms. That way, tools like perf can find it to match |
| 78 | * addresses. | 83 | * addresses. |
| @@ -390,6 +395,16 @@ static inline bool insn_is_zext(const struct bpf_insn *insn) · 311 unmodified lines | |||
| 390 | .off = 0, \ | 395 | .off = 0, \ |
| 391 | .imm = 0 }) | 396 | .imm = 0 }) |
| 392 | 397 | ||
| 398 | /* Speculation barrier */ | ||
| 399 | |||
| 400 | #define BPF_ST_NOSPEC() \ | ||
| 401 | ((struct bpf_insn) { \ | ||
| 402 | .code = BPF_ST | BPF_NOSPEC, \ | ||
| 403 | .dst_reg = 0, \ | ||
| 404 | .src_reg = 0, \ | ||
| 405 | .off = 0, \ | ||
| 406 | .imm = 0 }) | ||
| 407 | |||
| 393 | /* Internal classic blocks for direct assignment */ | 408 | /* Internal classic blocks for direct assignment */ |
| 394 | 409 | ||
| 395 | #define __BPF_STMT(CODE, K) \ | 410 | #define __BPF_STMT(CODE, K) \ |
| @@ -141,6 +141,7 @@ extern int vfs_get_tree(struct fs_context *fc); · 140 unmodified lines | |||
| 141 | extern void put_fs_context(struct fs_context *fc); | 141 | extern void put_fs_context(struct fs_context *fc); |
| 142 | extern int vfs_parse_fs_param_source(struct fs_context *fc, | 142 | extern int vfs_parse_fs_param_source(struct fs_context *fc, |
| 143 | struct fs_parameter *param); | 143 | struct fs_parameter *param); |
| 144 | extern void fc_drop_locked(struct fs_context *fc); | ||
| 144 | 145 | ||
| 145 | /* | 146 | /* |
| 146 | * sget() wrappers to be called from the ->get_tree() op. | 147 | * sget() wrappers to be called from the ->get_tree() op. |
| @@ -318,14 +318,16 @@ static inline void memcpy_to_page(struct page *page, size_t offset, · 317 unmodified lines | |||
| 318 | 318 | ||
| 319 | VM_BUG_ON(offset + len > PAGE_SIZE); | 319 | VM_BUG_ON(offset + len > PAGE_SIZE); |
| 320 | memcpy(to + offset, from, len); | 320 | memcpy(to + offset, from, len); |
| 321 | flush_dcache_page(page); | ||
| 321 | kunmap_local(to); | 322 | kunmap_local(to); |
| 322 | } | 323 | } |
| 323 | 324 | ||
| 324 | static inline void memzero_page(struct page *page, size_t offset, size_t len) | 325 | static inline void memzero_page(struct page *page, size_t offset, size_t len) |
| 325 | { | 326 | { |
| 326 | char *addr = kmap_atomic(page); | 327 | char *addr = kmap_local_page(page); |
| 327 | memset(addr + offset, 0, len); | 328 | memset(addr + offset, 0, len); |
| 328 | kunmap_atomic(addr); | 329 | flush_dcache_page(page); |
| 330 | kunmap_local(addr); | ||
| 329 | } | 331 | } |
| 330 | 332 | ||
| 331 | #endif /* _LINUX_HIGHMEM_H */ | 333 | #endif /* _LINUX_HIGHMEM_H */ |
| @@ -81,6 +81,8 @@ int ishtp_register_event_cb(struct ishtp_cl_device *device, · 80 unmodified lines | |||
| 81 | 81 | ||
| 82 | /* Get the device * from ishtp device instance */ | 82 | /* Get the device * from ishtp device instance */ |
| 83 | struct device *ishtp_device(struct ishtp_cl_device *cl_device); | 83 | struct device *ishtp_device(struct ishtp_cl_device *cl_device); |
| 84 | /* wait for IPC resume */ | ||
| 85 | bool ishtp_wait_resume(struct ishtp_device *dev); | ||
| 84 | /* Trace interface for clients */ | 86 | /* Trace interface for clients */ |
| 85 | ishtp_print_log ishtp_trace_callback(struct ishtp_cl_device *cl_device); | 87 | ishtp_print_log ishtp_trace_callback(struct ishtp_cl_device *cl_device); |
| 86 | /* Get device pointer of PCI device for DMA acces */ | 88 | /* Get device pointer of PCI device for DMA acces */ |
| @@ -872,7 +872,6 @@ void kvm_release_pfn_clean(kvm_pfn_t pfn); · 871 unmodified lines | |||
| 872 | void kvm_release_pfn_dirty(kvm_pfn_t pfn); | 872 | void kvm_release_pfn_dirty(kvm_pfn_t pfn); |
| 873 | void kvm_set_pfn_dirty(kvm_pfn_t pfn); | 873 | void kvm_set_pfn_dirty(kvm_pfn_t pfn); |
| 874 | void kvm_set_pfn_accessed(kvm_pfn_t pfn); | 874 | void kvm_set_pfn_accessed(kvm_pfn_t pfn); |
| 875 | void kvm_get_pfn(kvm_pfn_t pfn); | ||
| 876 | 875 | ||
| 877 | void kvm_release_pfn(kvm_pfn_t pfn, bool dirty, struct gfn_to_pfn_cache *cache); | 876 | void kvm_release_pfn(kvm_pfn_t pfn, bool dirty, struct gfn_to_pfn_cache *cache); |
| 878 | int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, | 877 | int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, |
| @@ -209,7 +209,7 @@ static inline void __next_physmem_range(u64 *idx, struct memblock_type *type, · 208 unmodified lines | |||
| 209 | */ | 209 | */ |
| 210 | #define for_each_mem_range(i, p_start, p_end) \ | 210 | #define for_each_mem_range(i, p_start, p_end) \ |
| 211 | __for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, \ | 211 | __for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, \ |
| 212 | MEMBLOCK_NONE, p_start, p_end, NULL) | 212 | MEMBLOCK_HOTPLUG, p_start, p_end, NULL) |
| 213 | 213 | ||
| 214 | /** | 214 | /** |
| 215 | * for_each_mem_range_rev - reverse iterate through memblock areas from | 215 | * for_each_mem_range_rev - reverse iterate through memblock areas from |
| @@ -220,7 +220,7 @@ static inline void __next_physmem_range(u64 *idx, struct memblock_type *type, · 4 unmodified lines | |||
| 220 | */ | 220 | */ |
| 221 | #define for_each_mem_range_rev(i, p_start, p_end) \ | 221 | #define for_each_mem_range_rev(i, p_start, p_end) \ |
| 222 | __for_each_mem_range_rev(i, &memblock.memory, NULL, NUMA_NO_NODE, \ | 222 | __for_each_mem_range_rev(i, &memblock.memory, NULL, NUMA_NO_NODE, \ |
| 223 | MEMBLOCK_NONE, p_start, p_end, NULL) | 223 | MEMBLOCK_HOTPLUG, p_start, p_end, NULL) |
| 224 | 224 | ||
| 225 | /** | 225 | /** |
| 226 | * for_each_reserved_mem_range - iterate over all reserved memblock areas | 226 | * for_each_reserved_mem_range - iterate over all reserved memblock areas |
| @@ -200,13 +200,13 @@ enum rt5033_reg { · 199 unmodified lines | |||
| 200 | #define RT5033_REGULATOR_BUCK_VOLTAGE_MIN 1000000U | 200 | #define RT5033_REGULATOR_BUCK_VOLTAGE_MIN 1000000U |
| 201 | #define RT5033_REGULATOR_BUCK_VOLTAGE_MAX 3000000U | 201 | #define RT5033_REGULATOR_BUCK_VOLTAGE_MAX 3000000U |
| 202 | #define RT5033_REGULATOR_BUCK_VOLTAGE_STEP 100000U | 202 | #define RT5033_REGULATOR_BUCK_VOLTAGE_STEP 100000U |
| 203 | #define RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM 32 | 203 | #define RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM 21 |
| 204 | 204 | ||
| 205 | /* RT5033 regulator LDO output voltage uV */ | 205 | /* RT5033 regulator LDO output voltage uV */ |
| 206 | #define RT5033_REGULATOR_LDO_VOLTAGE_MIN 1200000U | 206 | #define RT5033_REGULATOR_LDO_VOLTAGE_MIN 1200000U |
| 207 | #define RT5033_REGULATOR_LDO_VOLTAGE_MAX 3000000U | 207 | #define RT5033_REGULATOR_LDO_VOLTAGE_MAX 3000000U |
| 208 | #define RT5033_REGULATOR_LDO_VOLTAGE_STEP 100000U | 208 | #define RT5033_REGULATOR_LDO_VOLTAGE_STEP 100000U |
| 209 | #define RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM 32 | 209 | #define RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM 19 |
| 210 | 210 | ||
| 211 | /* RT5033 regulator SAFE LDO output voltage uV */ | 211 | /* RT5033 regulator SAFE LDO output voltage uV */ |
| 212 | #define RT5033_REGULATOR_SAFE_LDO_VOLTAGE 4900000U | 212 | #define RT5033_REGULATOR_SAFE_LDO_VOLTAGE 4900000U |
| @@ -632,43 +632,6 @@ static inline int PageTransCompound(struct page *page) · 631 unmodified lines | |||
| 632 | return PageCompound(page); | 632 | return PageCompound(page); |
| 633 | } | 633 | } |
| 634 | 634 | ||
| 635 | /* | ||
| 636 | * PageTransCompoundMap is the same as PageTransCompound, but it also | ||
| 637 | * guarantees the primary MMU has the entire compound page mapped | ||
| 638 | * through pmd_trans_huge, which in turn guarantees the secondary MMUs | ||
| 639 | * can also map the entire compound page. This allows the secondary | ||
| 640 | * MMUs to call get_user_pages() only once for each compound page and | ||
| 641 | * to immediately map the entire compound page with a single secondary | ||
| 642 | * MMU fault. If there will be a pmd split later, the secondary MMUs | ||
| 643 | * will get an update through the MMU notifier invalidation through | ||
| 644 | * split_huge_pmd(). | ||
| 645 | * | ||
| 646 | * Unlike PageTransCompound, this is safe to be called only while | ||
| 647 | * split_huge_pmd() cannot run from under us, like if protected by the | ||
| 648 | * MMU notifier, otherwise it may result in page->_mapcount check false | ||
| 649 | * positives. | ||
| 650 | * | ||
| 651 | * We have to treat page cache THP differently since every subpage of it | ||
| 652 | * would get _mapcount inc'ed once it is PMD mapped. But, it may be PTE | ||
| 653 | * mapped in the current process so comparing subpage's _mapcount to | ||
| 654 | * compound_mapcount to filter out PTE mapped case. | ||
| 655 | */ | ||
| 656 | static inline int PageTransCompoundMap(struct page *page) | ||
| 657 | { | ||
| 658 | struct page *head; | ||
| 659 | |||
| 660 | if (!PageTransCompound(page)) | ||
| 661 | return 0; | ||
| 662 | |||
| 663 | if (PageAnon(page)) | ||
| 664 | return atomic_read(&page->_mapcount) < 0; | ||
| 665 | |||
| 666 | head = compound_head(page); | ||
| 667 | /* File THP is PMD mapped and not PTE mapped */ | ||
| 668 | return atomic_read(&page->_mapcount) == | ||
| 669 | atomic_read(compound_mapcount_ptr(head)); | ||
| 670 | } | ||
| 671 | |||
| 672 | /* | 635 | /* |
| 673 | * PageTransTail returns true for both transparent huge pages | 636 | * PageTransTail returns true for both transparent huge pages |
| 674 | * and hugetlbfs pages, so it should only be called when it's known | 637 | * and hugetlbfs pages, so it should only be called when it's known |
| @@ -1397,34 +1397,10 @@ static inline int p4d_clear_huge(p4d_t *p4d) · 1396 unmodified lines | |||
| 1397 | } | 1397 | } |
| 1398 | #endif /* !__PAGETABLE_P4D_FOLDED */ | 1398 | #endif /* !__PAGETABLE_P4D_FOLDED */ |
| 1399 | 1399 | ||
| 1400 | #ifndef __PAGETABLE_PUD_FOLDED | ||
| 1401 | int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot); | 1400 | int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot); |
| 1402 | int pud_clear_huge(pud_t *pud); | ||
| 1403 | #else | ||
| 1404 | static inline int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) | ||
| 1405 | { | ||
| 1406 | return 0; | ||
| 1407 | } | ||
| 1408 | static inline int pud_clear_huge(pud_t *pud) | ||
| 1409 | { | ||
| 1410 | return 0; | ||
| 1411 | } | ||
| 1412 | #endif /* !__PAGETABLE_PUD_FOLDED */ | ||
| 1413 | |||
| 1414 | #ifndef __PAGETABLE_PMD_FOLDED | ||
| 1415 | int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot); | 1401 | int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot); |
| 1402 | int pud_clear_huge(pud_t *pud); | ||
| 1416 | int pmd_clear_huge(pmd_t *pmd); | 1403 | int pmd_clear_huge(pmd_t *pmd); |
| 1417 | #else | ||
| 1418 | static inline int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) | ||
| 1419 | { | ||
| 1420 | return 0; | ||
| 1421 | } | ||
| 1422 | static inline int pmd_clear_huge(pmd_t *pmd) | ||
| 1423 | { | ||
| 1424 | return 0; | ||
| 1425 | } | ||
| 1426 | #endif /* !__PAGETABLE_PMD_FOLDED */ | ||
| 1427 | |||
| 1428 | int p4d_free_pud_page(p4d_t *p4d, unsigned long addr); | 1404 | int p4d_free_pud_page(p4d_t *p4d, unsigned long addr); |
| 1429 | int pud_free_pmd_page(pud_t *pud, unsigned long addr); | 1405 | int pud_free_pmd_page(pud_t *pud, unsigned long addr); |
| 1430 | int pmd_free_pte_page(pmd_t *pmd, unsigned long addr); | 1406 | int pmd_free_pte_page(pmd_t *pmd, unsigned long addr); |
| @@ -285,11 +285,45 @@ static inline struct sk_psock *sk_psock(const struct sock *sk) · 284 unmodified lines | |||
| 285 | return rcu_dereference_sk_user_data(sk); | 285 | return rcu_dereference_sk_user_data(sk); |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static inline void sk_psock_set_state(struct sk_psock *psock, | ||
| 289 | enum sk_psock_state_bits bit) | ||
| 290 | { | ||
| 291 | set_bit(bit, &psock->state); | ||
| 292 | } | ||
| 293 | |||
| 294 | static inline void sk_psock_clear_state(struct sk_psock *psock, | ||
| 295 | enum sk_psock_state_bits bit) | ||
| 296 | { | ||
| 297 | clear_bit(bit, &psock->state); | ||
| 298 | } | ||
| 299 | |||
| 300 | static inline bool sk_psock_test_state(const struct sk_psock *psock, | ||
| 301 | enum sk_psock_state_bits bit) | ||
| 302 | { | ||
| 303 | return test_bit(bit, &psock->state); | ||
| 304 | } | ||
| 305 | |||
| 306 | static inline void sock_drop(struct sock *sk, struct sk_buff *skb) | ||
| 307 | { | ||
| 308 | sk_drops_add(sk, skb); | ||
| 309 | kfree_skb(skb); | ||
| 310 | } | ||
| 311 | |||
| 312 | static inline void drop_sk_msg(struct sk_psock *psock, struct sk_msg *msg) | ||
| 313 | { | ||
| 314 | if (msg->skb) | ||
| 315 | sock_drop(psock->sk, msg->skb); | ||
| 316 | kfree(msg); | ||
| 317 | } | ||
| 318 | |||
| 288 | static inline void sk_psock_queue_msg(struct sk_psock *psock, | 319 | static inline void sk_psock_queue_msg(struct sk_psock *psock, |
| 289 | struct sk_msg *msg) | 320 | struct sk_msg *msg) |
| 290 | { | 321 | { |
| 291 | spin_lock_bh(&psock->ingress_lock); | 322 | spin_lock_bh(&psock->ingress_lock); |
| 292 | list_add_tail(&msg->list, &psock->ingress_msg); | 323 | if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) |
| 324 | list_add_tail(&msg->list, &psock->ingress_msg); | ||
| 325 | else | ||
| 326 | drop_sk_msg(psock, msg); | ||
| 293 | spin_unlock_bh(&psock->ingress_lock); | 327 | spin_unlock_bh(&psock->ingress_lock); |
| 294 | } | 328 | } |
| 295 | 329 | ||
| @@ -406,24 +440,6 @@ static inline void sk_psock_restore_proto(struct sock *sk, · 110 unmodified lines | |||
| 406 | psock->psock_update_sk_prot(sk, psock, true); | 440 | psock->psock_update_sk_prot(sk, psock, true); |
| 407 | } | 441 | } |
| 408 | 442 | ||
| 409 | static inline void sk_psock_set_state(struct sk_psock *psock, | ||
| 410 | enum sk_psock_state_bits bit) | ||
| 411 | { | ||
| 412 | set_bit(bit, &psock->state); | ||
| 413 | } | ||
| 414 | |||
| 415 | static inline void sk_psock_clear_state(struct sk_psock *psock, | ||
| 416 | enum sk_psock_state_bits bit) | ||
| 417 | { | ||
| 418 | clear_bit(bit, &psock->state); | ||
| 419 | } | ||
| 420 | |||
| 421 | static inline bool sk_psock_test_state(const struct sk_psock *psock, | ||
| 422 | enum sk_psock_state_bits bit) | ||
| 423 | { | ||
| 424 | return test_bit(bit, &psock->state); | ||
| 425 | } | ||
| 426 | |||
| 427 | static inline struct sk_psock *sk_psock_get(struct sock *sk) | 443 | static inline struct sk_psock *sk_psock_get(struct sock *sk) |
| 428 | { | 444 | { |
| 429 | struct sk_psock *psock; | 445 | struct sk_psock *psock; |
| @@ -15,9 +15,11 @@ · 14 unmodified lines | |||
| 15 | #include <linux/if_ether.h> | 15 | #include <linux/if_ether.h> |
| 16 | 16 | ||
| 17 | /* Lengths of frame formats */ | 17 | /* Lengths of frame formats */ |
| 18 | #define LLC_PDU_LEN_I 4 /* header and 2 control bytes */ | 18 | #define LLC_PDU_LEN_I 4 /* header and 2 control bytes */ |
| 19 | #define LLC_PDU_LEN_S 4 | 19 | #define LLC_PDU_LEN_S 4 |
| 20 | #define LLC_PDU_LEN_U 3 /* header and 1 control byte */ | 20 | #define LLC_PDU_LEN_U 3 /* header and 1 control byte */ |
| 21 | /* header and 1 control byte and XID info */ | ||
| 22 | #define LLC_PDU_LEN_U_XID (LLC_PDU_LEN_U + sizeof(struct llc_xid_info)) | ||
| 21 | /* Known SAP addresses */ | 23 | /* Known SAP addresses */ |
| 22 | #define LLC_GLOBAL_SAP 0xFF | 24 | #define LLC_GLOBAL_SAP 0xFF |
| 23 | #define LLC_NULL_SAP 0x00 /* not network-layer visible */ | 25 | #define LLC_NULL_SAP 0x00 /* not network-layer visible */ |
| @@ -50,9 +52,10 @@ · 26 unmodified lines | |||
| 50 | #define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */ | 52 | #define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */ |
| 51 | #define LLC_PDU_TYPE_MASK 0x03 | 53 | #define LLC_PDU_TYPE_MASK 0x03 |
| 52 | 54 | ||
| 53 | #define LLC_PDU_TYPE_I 0 /* first bit */ | 55 | #define LLC_PDU_TYPE_I 0 /* first bit */ |
| 54 | #define LLC_PDU_TYPE_S 1 /* first two bits */ | 56 | #define LLC_PDU_TYPE_S 1 /* first two bits */ |
| 55 | #define LLC_PDU_TYPE_U 3 /* first two bits */ | 57 | #define LLC_PDU_TYPE_U 3 /* first two bits */ |
| 58 | #define LLC_PDU_TYPE_U_XID 4 /* private type for detecting XID commands */ | ||
| 56 | 59 | ||
| 57 | #define LLC_PDU_TYPE_IS_I(pdu) \ | 60 | #define LLC_PDU_TYPE_IS_I(pdu) \ |
| 58 | ((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0) | 61 | ((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0) |
| @@ -230,9 +233,18 @@ static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb) · 171 unmodified lines | |||
| 230 | static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type, | 233 | static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type, |
| 231 | u8 ssap, u8 dsap, u8 cr) | 234 | u8 ssap, u8 dsap, u8 cr) |
| 232 | { | 235 | { |
| 233 | const int hlen = type == LLC_PDU_TYPE_U ? 3 : 4; | 236 | int hlen = 4; /* default value for I and S types */ |
| 234 | struct llc_pdu_un *pdu; | 237 | struct llc_pdu_un *pdu; |
| 235 | 238 | ||
| 239 | switch (type) { | ||
| 240 | case LLC_PDU_TYPE_U: | ||
| 241 | hlen = 3; | ||
| 242 | break; | ||
| 243 | case LLC_PDU_TYPE_U_XID: | ||
| 244 | hlen = 6; | ||
| 245 | break; | ||
| 246 | } | ||
| 247 | |||
| 236 | skb_push(skb, hlen); | 248 | skb_push(skb, hlen); |
| 237 | skb_reset_network_header(skb); | 249 | skb_reset_network_header(skb); |
| 238 | pdu = llc_pdu_un_hdr(skb); | 250 | pdu = llc_pdu_un_hdr(skb); |
| @@ -374,7 +386,10 @@ static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, · 135 unmodified lines | |||
| 374 | xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */ | 386 | xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */ |
| 375 | xid_info->type = svcs_supported; | 387 | xid_info->type = svcs_supported; |
| 376 | xid_info->rw = rx_window << 1; /* size of receive window */ | 388 | xid_info->rw = rx_window << 1; /* size of receive window */ |
| 377 | skb_put(skb, sizeof(struct llc_xid_info)); | 389 | |
| 390 | /* no need to push/put since llc_pdu_header_init() has already | ||
| 391 | * pushed 3 + 3 bytes | ||
| 392 | */ | ||
| 378 | } | 393 | } |
| 379 | 394 | ||
| 380 | /** | 395 | /** |
| @@ -984,6 +984,7 @@ struct sctp_transport { · 983 unmodified lines | |||
| 984 | } cacc; | 984 | } cacc; |
| 985 | 985 | ||
| 986 | struct { | 986 | struct { |
| 987 | __u32 last_rtx_chunks; | ||
| 987 | __u16 pmtu; | 988 | __u16 pmtu; |
| 988 | __u16 probe_size; | 989 | __u16 probe_size; |
| 989 | __u16 probe_high; | 990 | __u16 probe_high; |
| @@ -1024,8 +1025,8 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu); · 34 unmodified lines | |||
| 1024 | void sctp_transport_immediate_rtx(struct sctp_transport *); | 1025 | void sctp_transport_immediate_rtx(struct sctp_transport *); |
| 1025 | void sctp_transport_dst_release(struct sctp_transport *t); | 1026 | void sctp_transport_dst_release(struct sctp_transport *t); |
| 1026 | void sctp_transport_dst_confirm(struct sctp_transport *t); | 1027 | void sctp_transport_dst_confirm(struct sctp_transport *t); |
| 1027 | void sctp_transport_pl_send(struct sctp_transport *t); | 1028 | bool sctp_transport_pl_send(struct sctp_transport *t); |
| 1028 | void sctp_transport_pl_recv(struct sctp_transport *t); | 1029 | bool sctp_transport_pl_recv(struct sctp_transport *t); |
| 1029 | 1030 | ||
| 1030 | 1031 | ||
| 1031 | /* This is the structure we use to queue packets as they come into | 1032 | /* This is the structure we use to queue packets as they come into |
| @@ -1709,7 +1709,6 @@ struct tcp_fastopen_context { · 1708 unmodified lines | |||
| 1709 | struct rcu_head rcu; | 1709 | struct rcu_head rcu; |
| 1710 | }; | 1710 | }; |
| 1711 | 1711 | ||
| 1712 | extern unsigned int sysctl_tcp_fastopen_blackhole_timeout; | ||
| 1713 | void tcp_fastopen_active_disable(struct sock *sk); | 1712 | void tcp_fastopen_active_disable(struct sock *sk); |
| 1714 | bool tcp_fastopen_active_should_disable(struct sock *sk); | 1713 | bool tcp_fastopen_active_should_disable(struct sock *sk); |
| 1715 | void tcp_fastopen_active_disable_ofo_check(struct sock *sk); | 1714 | void tcp_fastopen_active_disable_ofo_check(struct sock *sk); |
| @@ -712,6 +712,12 @@ struct snd_soc_dai_link { · 711 unmodified lines | |||
| 712 | /* Do not create a PCM for this DAI link (Backend link) */ | 712 | /* Do not create a PCM for this DAI link (Backend link) */ |
| 713 | unsigned int ignore:1; | 713 | unsigned int ignore:1; |
| 714 | 714 | ||
| 715 | /* This flag will reorder stop sequence. By enabling this flag | ||
| 716 | * DMA controller stop sequence will be invoked first followed by | ||
| 717 | * CPU DAI driver stop sequence | ||
| 718 | */ | ||
| 719 | unsigned int stop_dma_first:1; | ||
| 720 | |||
| 715 | #ifdef CONFIG_SND_SOC_TOPOLOGY | 721 | #ifdef CONFIG_SND_SOC_TOPOLOGY |
| 716 | struct snd_soc_dobj dobj; /* For topology */ | 722 | struct snd_soc_dobj dobj; /* For topology */ |
| 717 | #endif | 723 | #endif |
| @@ -174,6 +174,34 @@ enum afs_vl_operation { · 173 unmodified lines | |||
| 174 | afs_VL_GetCapabilities = 65537, /* AFS Get VL server capabilities */ | 174 | afs_VL_GetCapabilities = 65537, /* AFS Get VL server capabilities */ |
| 175 | }; | 175 | }; |
| 176 | 176 | ||
| 177 | enum afs_cm_operation { | ||
| 178 | afs_CB_CallBack = 204, /* AFS break callback promises */ | ||
| 179 | afs_CB_InitCallBackState = 205, /* AFS initialise callback state */ | ||
| 180 | afs_CB_Probe = 206, /* AFS probe client */ | ||
| 181 | afs_CB_GetLock = 207, /* AFS get contents of CM lock table */ | ||
| 182 | afs_CB_GetCE = 208, /* AFS get cache file description */ | ||
| 183 | afs_CB_GetXStatsVersion = 209, /* AFS get version of extended statistics */ | ||
| 184 | afs_CB_GetXStats = 210, /* AFS get contents of extended statistics data */ | ||
| 185 | afs_CB_InitCallBackState3 = 213, /* AFS initialise callback state, version 3 */ | ||
| 186 | afs_CB_ProbeUuid = 214, /* AFS check the client hasn't rebooted */ | ||
| 187 | }; | ||
| 188 | |||
| 189 | enum yfs_cm_operation { | ||
| 190 | yfs_CB_Probe = 206, /* YFS probe client */ | ||
| 191 | yfs_CB_GetLock = 207, /* YFS get contents of CM lock table */ | ||
| 192 | yfs_CB_XStatsVersion = 209, /* YFS get version of extended statistics */ | ||
| 193 | yfs_CB_GetXStats = 210, /* YFS get contents of extended statistics data */ | ||
| 194 | yfs_CB_InitCallBackState3 = 213, /* YFS initialise callback state, version 3 */ | ||
| 195 | yfs_CB_ProbeUuid = 214, /* YFS check the client hasn't rebooted */ | ||
| 196 | yfs_CB_GetServerPrefs = 215, | ||
| 197 | yfs_CB_GetCellServDV = 216, | ||
| 198 | yfs_CB_GetLocalCell = 217, | ||
| 199 | yfs_CB_GetCacheConfig = 218, | ||
| 200 | yfs_CB_GetCellByNum = 65537, | ||
| 201 | yfs_CB_TellMeAboutYourself = 65538, /* get client capabilities */ | ||
| 202 | yfs_CB_CallBack = 64204, | ||
| 203 | }; | ||
| 204 | |||
| 177 | enum afs_edit_dir_op { | 205 | enum afs_edit_dir_op { |
| 178 | afs_edit_dir_create, | 206 | afs_edit_dir_create, |
| 179 | afs_edit_dir_create_error, | 207 | afs_edit_dir_create_error, |
| @@ -436,6 +464,32 @@ enum afs_cb_break_reason { · 256 unmodified lines | |||
| 436 | EM(afs_YFSVL_GetCellName, "YFSVL.GetCellName") \ | 464 | EM(afs_YFSVL_GetCellName, "YFSVL.GetCellName") \ |
| 437 | E_(afs_VL_GetCapabilities, "VL.GetCapabilities") | 465 | E_(afs_VL_GetCapabilities, "VL.GetCapabilities") |
| 438 | 466 | ||
| 467 | #define afs_cm_operations \ | ||
| 468 | EM(afs_CB_CallBack, "CB.CallBack") \ | ||
| 469 | EM(afs_CB_InitCallBackState, "CB.InitCallBackState") \ | ||
| 470 | EM(afs_CB_Probe, "CB.Probe") \ | ||
| 471 | EM(afs_CB_GetLock, "CB.GetLock") \ | ||
| 472 | EM(afs_CB_GetCE, "CB.GetCE") \ | ||
| 473 | EM(afs_CB_GetXStatsVersion, "CB.GetXStatsVersion") \ | ||
| 474 | EM(afs_CB_GetXStats, "CB.GetXStats") \ | ||
| 475 | EM(afs_CB_InitCallBackState3, "CB.InitCallBackState3") \ | ||
| 476 | E_(afs_CB_ProbeUuid, "CB.ProbeUuid") | ||
| 477 | |||
| 478 | #define yfs_cm_operations \ | ||
| 479 | EM(yfs_CB_Probe, "YFSCB.Probe") \ | ||
| 480 | EM(yfs_CB_GetLock, "YFSCB.GetLock") \ | ||
| 481 | EM(yfs_CB_XStatsVersion, "YFSCB.XStatsVersion") \ | ||
| 482 | EM(yfs_CB_GetXStats, "YFSCB.GetXStats") \ | ||
| 483 | EM(yfs_CB_InitCallBackState3, "YFSCB.InitCallBackState3") \ | ||
| 484 | EM(yfs_CB_ProbeUuid, "YFSCB.ProbeUuid") \ | ||
| 485 | EM(yfs_CB_GetServerPrefs, "YFSCB.GetServerPrefs") \ | ||
| 486 | EM(yfs_CB_GetCellServDV, "YFSCB.GetCellServDV") \ | ||
| 487 | EM(yfs_CB_GetLocalCell, "YFSCB.GetLocalCell") \ | ||
| 488 | EM(yfs_CB_GetCacheConfig, "YFSCB.GetCacheConfig") \ | ||
| 489 | EM(yfs_CB_GetCellByNum, "YFSCB.GetCellByNum") \ | ||
| 490 | EM(yfs_CB_TellMeAboutYourself, "YFSCB.TellMeAboutYourself") \ | ||
| 491 | E_(yfs_CB_CallBack, "YFSCB.CallBack") | ||
| 492 | |||
| 439 | #define afs_edit_dir_ops \ | 493 | #define afs_edit_dir_ops \ |
| 440 | EM(afs_edit_dir_create, "create") \ | 494 | EM(afs_edit_dir_create, "create") \ |
| 441 | EM(afs_edit_dir_create_error, "c_fail") \ | 495 | EM(afs_edit_dir_create_error, "c_fail") \ |
| @@ -569,6 +623,8 @@ afs_server_traces; · 127 unmodified lines | |||
| 569 | afs_cell_traces; | 623 | afs_cell_traces; |
| 570 | afs_fs_operations; | 624 | afs_fs_operations; |
| 571 | afs_vl_operations; | 625 | afs_vl_operations; |
| 626 | afs_cm_operations; | ||
| 627 | yfs_cm_operations; | ||
| 572 | afs_edit_dir_ops; | 628 | afs_edit_dir_ops; |
| 573 | afs_edit_dir_reasons; | 629 | afs_edit_dir_reasons; |
| 574 | afs_eproto_causes; | 630 | afs_eproto_causes; |
| @@ -649,20 +705,21 @@ TRACE_EVENT(afs_cb_call, · 74 unmodified lines | |||
| 649 | 705 | ||
| 650 | TP_STRUCT__entry( | 706 | TP_STRUCT__entry( |
| 651 | __field(unsigned int, call ) | 707 | __field(unsigned int, call ) |
| 652 | __field(const char *, name ) | ||
| 653 | __field(u32, op ) | 708 | __field(u32, op ) |
| 709 | __field(u16, service_id ) | ||
| 654 | ), | 710 | ), |
| 655 | 711 | ||
| 656 | TP_fast_assign( | 712 | TP_fast_assign( |
| 657 | __entry->call = call->debug_id; | 713 | __entry->call = call->debug_id; |
| 658 | __entry->name = call->type->name; | ||
| 659 | __entry->op = call->operation_ID; | 714 | __entry->op = call->operation_ID; |
| 715 | __entry->service_id = call->service_id; | ||
| 660 | ), | 716 | ), |
| 661 | 717 | ||
| 662 | TP_printk("c=%08x %s o=%u", | 718 | TP_printk("c=%08x %s", |
| 663 | __entry->call, | 719 | __entry->call, |
| 664 | __entry->name, | 720 | __entry->service_id == 2501 ? |
| 665 | __entry->op) | 721 | __print_symbolic(__entry->op, yfs_cm_operations) : |
| 722 | __print_symbolic(__entry->op, afs_cm_operations)) | ||
| 666 | ); | 723 | ); |
| 667 | 724 | ||
| 668 | TRACE_EVENT(afs_call, | 725 | TRACE_EVENT(afs_call, |
| @@ -136,7 +136,7 @@ DECLARE_EVENT_CLASS(net_dev_template, · 135 unmodified lines | |||
| 136 | __assign_str(name, skb->dev->name); | 136 | __assign_str(name, skb->dev->name); |
| 137 | ), | 137 | ), |
| 138 | 138 | ||
| 139 | TP_printk("dev=%s skbaddr=%p len=%u", | 139 | TP_printk("dev=%s skbaddr=%px len=%u", |
| 140 | __get_str(name), __entry->skbaddr, __entry->len) | 140 | __get_str(name), __entry->skbaddr, __entry->len) |
| 141 | ) | 141 | ) |
| 142 | 142 | ||
| @@ -41,11 +41,37 @@ TRACE_EVENT(qdisc_dequeue, · 40 unmodified lines | |||
| 41 | __entry->txq_state = txq->state; | 41 | __entry->txq_state = txq->state; |
| 42 | ), | 42 | ), |
| 43 | 43 | ||
| 44 | TP_printk("dequeue ifindex=%d qdisc handle=0x%X parent=0x%X txq_state=0x%lX packets=%d skbaddr=%p", | 44 | TP_printk("dequeue ifindex=%d qdisc handle=0x%X parent=0x%X txq_state=0x%lX packets=%d skbaddr=%px", |
| 45 | __entry->ifindex, __entry->handle, __entry->parent, | 45 | __entry->ifindex, __entry->handle, __entry->parent, |
| 46 | __entry->txq_state, __entry->packets, __entry->skbaddr ) | 46 | __entry->txq_state, __entry->packets, __entry->skbaddr ) |
| 47 | ); | 47 | ); |
| 48 | 48 | ||
| 49 | TRACE_EVENT(qdisc_enqueue, | ||
| 50 | |||
| 51 | TP_PROTO(struct Qdisc *qdisc, const struct netdev_queue *txq, struct sk_buff *skb), | ||
| 52 | |||
| 53 | TP_ARGS(qdisc, txq, skb), | ||
| 54 | |||
| 55 | TP_STRUCT__entry( | ||
| 56 | __field(struct Qdisc *, qdisc) | ||
| 57 | __field(void *, skbaddr) | ||
| 58 | __field(int, ifindex) | ||
| 59 | __field(u32, handle) | ||
| 60 | __field(u32, parent) | ||
| 61 | ), | ||
| 62 | |||
| 63 | TP_fast_assign( | ||
| 64 | __entry->qdisc = qdisc; | ||
| 65 | __entry->skbaddr = skb; | ||
| 66 | __entry->ifindex = txq->dev ? txq->dev->ifindex : 0; | ||
| 67 | __entry->handle = qdisc->handle; | ||
| 68 | __entry->parent = qdisc->parent; | ||
| 69 | ), | ||
| 70 | |||
| 71 | TP_printk("enqueue ifindex=%d qdisc handle=0x%X parent=0x%X skbaddr=%px", | ||
| 72 | __entry->ifindex, __entry->handle, __entry->parent, __entry->skbaddr) | ||
| 73 | ); | ||
| 74 | |||
| 49 | TRACE_EVENT(qdisc_reset, | 75 | TRACE_EVENT(qdisc_reset, |
| 50 | 76 | ||
| 51 | TP_PROTO(struct Qdisc *q), | 77 | TP_PROTO(struct Qdisc *q), |
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | 1 | /* SPDX-License-Identifier: LGPL-2.1 WITH Linux-syscall-note */ |
| 2 | /* Copyright(c) 2019 Intel Corporation. All rights rsvd. */ | 2 | /* Copyright(c) 2019 Intel Corporation. All rights rsvd. */ |
| 3 | #ifndef _USR_IDXD_H_ | 3 | #ifndef _USR_IDXD_H_ |
| 4 | #define _USR_IDXD_H_ | 4 | #define _USR_IDXD_H_ |
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */ | 1 | /* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2006 - 2021 Intel Corporation. All rights reserved. | 3 | * Copyright (c) 2006 - 2021 Intel Corporation. All rights reserved. |
| 4 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 4 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | |||
| 32 | #include <linux/perf_event.h> | 32 | #include <linux/perf_event.h> |
| 33 | #include <linux/extable.h> | 33 | #include <linux/extable.h> |
| 34 | #include <linux/log2.h> | 34 | #include <linux/log2.h> |
| 35 | |||
| 36 | #include <asm/barrier.h> | ||
| 35 | #include <asm/unaligned.h> | 37 | #include <asm/unaligned.h> |
| 36 | 38 | ||
| 37 | /* Registers */ | 39 | /* Registers */ |
| @@ -1377,6 +1379,7 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) · 1339 unmodified lines | |||
| 1377 | /* Non-UAPI available opcodes. */ | 1379 | /* Non-UAPI available opcodes. */ |
| 1378 | [BPF_JMP | BPF_CALL_ARGS] = &&JMP_CALL_ARGS, | 1380 | [BPF_JMP | BPF_CALL_ARGS] = &&JMP_CALL_ARGS, |
| 1379 | [BPF_JMP | BPF_TAIL_CALL] = &&JMP_TAIL_CALL, | 1381 | [BPF_JMP | BPF_TAIL_CALL] = &&JMP_TAIL_CALL, |
| 1382 | [BPF_ST | BPF_NOSPEC] = &&ST_NOSPEC, | ||
| 1380 | [BPF_LDX | BPF_PROBE_MEM | BPF_B] = &&LDX_PROBE_MEM_B, | 1383 | [BPF_LDX | BPF_PROBE_MEM | BPF_B] = &&LDX_PROBE_MEM_B, |
| 1381 | [BPF_LDX | BPF_PROBE_MEM | BPF_H] = &&LDX_PROBE_MEM_H, | 1384 | [BPF_LDX | BPF_PROBE_MEM | BPF_H] = &&LDX_PROBE_MEM_H, |
| 1382 | [BPF_LDX | BPF_PROBE_MEM | BPF_W] = &&LDX_PROBE_MEM_W, | 1385 | [BPF_LDX | BPF_PROBE_MEM | BPF_W] = &&LDX_PROBE_MEM_W, |
| @@ -1621,7 +1624,21 @@ out: · 238 unmodified lines | |||
| 1621 | COND_JMP(s, JSGE, >=) | 1624 | COND_JMP(s, JSGE, >=) |
| 1622 | COND_JMP(s, JSLE, <=) | 1625 | COND_JMP(s, JSLE, <=) |
| 1623 | #undef COND_JMP | 1626 | #undef COND_JMP |
| 1624 | /* STX and ST and LDX*/ | 1627 | /* ST, STX and LDX*/ |
| 1628 | ST_NOSPEC: | ||
| 1629 | /* Speculation barrier for mitigating Speculative Store Bypass. | ||
| 1630 | * In case of arm64, we rely on the firmware mitigation as | ||
| 1631 | * controlled via the ssbd kernel parameter. Whenever the | ||
| 1632 | * mitigation is enabled, it works for all of the kernel code | ||
| 1633 | * with no need to provide any additional instructions here. | ||
| 1634 | * In case of x86, we use 'lfence' insn for mitigation. We | ||
| 1635 | * reuse preexisting logic from Spectre v1 mitigation that | ||
| 1636 | * happens to produce the required code on x86 for v4 as well. | ||
| 1637 | */ | ||
| 1638 | #ifdef CONFIG_X86 | ||
| 1639 | barrier_nospec(); | ||
| 1640 | #endif | ||
| 1641 | CONT; | ||
| 1625 | #define LDST(SIZEOP, SIZE) \ | 1642 | #define LDST(SIZEOP, SIZE) \ |
| 1626 | STX_MEM_##SIZEOP: \ | 1643 | STX_MEM_##SIZEOP: \ |
| 1627 | *(SIZE *)(unsigned long) (DST + insn->off) = SRC; \ | 1644 | *(SIZE *)(unsigned long) (DST + insn->off) = SRC; \ |
| @@ -206,15 +206,17 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs, · 205 unmodified lines | |||
| 206 | verbose(cbs->private_data, "BUG_%02x\n", insn->code); | 206 | verbose(cbs->private_data, "BUG_%02x\n", insn->code); |
| 207 | } | 207 | } |
| 208 | } else if (class == BPF_ST) { | 208 | } else if (class == BPF_ST) { |
| 209 | if (BPF_MODE(insn->code) != BPF_MEM) { | 209 | if (BPF_MODE(insn->code) == BPF_MEM) { |
| 210 | verbose(cbs->private_data, "(%02x) *(%s *)(r%d %+d) = %d\n", | ||
| 211 | insn->code, | ||
| 212 | bpf_ldst_string[BPF_SIZE(insn->code) >> 3], | ||
| 213 | insn->dst_reg, | ||
| 214 | insn->off, insn->imm); | ||
| 215 | } else if (BPF_MODE(insn->code) == 0xc0 /* BPF_NOSPEC, no UAPI */) { | ||
| 216 | verbose(cbs->private_data, "(%02x) nospec\n", insn->code); | ||
| 217 | } else { | ||
| 210 | verbose(cbs->private_data, "BUG_st_%02x\n", insn->code); | 218 | verbose(cbs->private_data, "BUG_st_%02x\n", insn->code); |
| 211 | return; | ||
| 212 | } | 219 | } |
| 213 | verbose(cbs->private_data, "(%02x) *(%s *)(r%d %+d) = %d\n", | ||
| 214 | insn->code, | ||
| 215 | bpf_ldst_string[BPF_SIZE(insn->code) >> 3], | ||
| 216 | insn->dst_reg, | ||
| 217 | insn->off, insn->imm); | ||
| 218 | } else if (class == BPF_LDX) { | 220 | } else if (class == BPF_LDX) { |
| 219 | if (BPF_MODE(insn->code) != BPF_MEM) { | 221 | if (BPF_MODE(insn->code) != BPF_MEM) { |
| 220 | verbose(cbs->private_data, "BUG_ldx_%02x\n", insn->code); | 222 | verbose(cbs->private_data, "BUG_ldx_%02x\n", insn->code); |
| @@ -2610,6 +2610,19 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, · 2609 unmodified lines | |||
| 2610 | cur = env->cur_state->frame[env->cur_state->curframe]; | 2610 | cur = env->cur_state->frame[env->cur_state->curframe]; |
| 2611 | if (value_regno >= 0) | 2611 | if (value_regno >= 0) |
| 2612 | reg = &cur->regs[value_regno]; | 2612 | reg = &cur->regs[value_regno]; |
| 2613 | if (!env->bypass_spec_v4) { | ||
| 2614 | bool sanitize = reg && is_spillable_regtype(reg->type); | ||
| 2615 | |||
| 2616 | for (i = 0; i < size; i++) { | ||
| 2617 | if (state->stack[spi].slot_type[i] == STACK_INVALID) { | ||
| 2618 | sanitize = true; | ||
| 2619 | break; | ||
| 2620 | } | ||
| 2621 | } | ||
| 2622 | |||
| 2623 | if (sanitize) | ||
| 2624 | env->insn_aux_data[insn_idx].sanitize_stack_spill = true; | ||
| 2625 | } | ||
| 2613 | 2626 | ||
| 2614 | if (reg && size == BPF_REG_SIZE && register_is_bounded(reg) && | 2627 | if (reg && size == BPF_REG_SIZE && register_is_bounded(reg) && |
| 2615 | !register_is_null(reg) && env->bpf_capable) { | 2628 | !register_is_null(reg) && env->bpf_capable) { |
| @@ -2632,47 +2645,10 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, · 16 unmodified lines | |||
| 2632 | verbose(env, "invalid size of register spill\n"); | 2645 | verbose(env, "invalid size of register spill\n"); |
| 2633 | return -EACCES; | 2646 | return -EACCES; |
| 2634 | } | 2647 | } |
| 2635 | |||
| 2636 | if (state != cur && reg->type == PTR_TO_STACK) { | 2648 | if (state != cur && reg->type == PTR_TO_STACK) { |
| 2637 | verbose(env, "cannot spill pointers to stack into stack frame of the caller\n"); | 2649 | verbose(env, "cannot spill pointers to stack into stack frame of the caller\n"); |
| 2638 | return -EINVAL; | 2650 | return -EINVAL; |
| 2639 | } | 2651 | } |
| 2640 | |||
| 2641 | if (!env->bypass_spec_v4) { | ||
| 2642 | bool sanitize = false; | ||
| 2643 | |||
| 2644 | if (state->stack[spi].slot_type[0] == STACK_SPILL && | ||
| 2645 | register_is_const(&state->stack[spi].spilled_ptr)) | ||
| 2646 | sanitize = true; | ||
| 2647 | for (i = 0; i < BPF_REG_SIZE; i++) | ||
| 2648 | if (state->stack[spi].slot_type[i] == STACK_MISC) { | ||
| 2649 | sanitize = true; | ||
| 2650 | break; | ||
| 2651 | } | ||
| 2652 | if (sanitize) { | ||
| 2653 | int *poff = &env->insn_aux_data[insn_idx].sanitize_stack_off; | ||
| 2654 | int soff = (-spi - 1) * BPF_REG_SIZE; | ||
| 2655 | |||
| 2656 | /* detected reuse of integer stack slot with a pointer | ||
| 2657 | * which means either llvm is reusing stack slot or | ||
| 2658 | * an attacker is trying to exploit CVE-2018-3639 | ||
| 2659 | * (speculative store bypass) | ||
| 2660 | * Have to sanitize that slot with preemptive | ||
| 2661 | * store of zero. | ||
| 2662 | */ | ||
| 2663 | if (*poff && *poff != soff) { | ||
| 2664 | /* disallow programs where single insn stores | ||
| 2665 | * into two different stack slots, since verifier | ||
| 2666 | * cannot sanitize them | ||
| 2667 | */ | ||
| 2668 | verbose(env, | ||
| 2669 | "insn %d cannot access two stack slots fp%d and fp%d", | ||
| 2670 | insn_idx, *poff, soff); | ||
| 2671 | return -EINVAL; | ||
| 2672 | } | ||
| 2673 | *poff = soff; | ||
| 2674 | } | ||
| 2675 | } | ||
| 2676 | save_register_state(state, spi, reg); | 2652 | save_register_state(state, spi, reg); |
| 2677 | } else { | 2653 | } else { |
| 2678 | u8 type = STACK_MISC; | 2654 | u8 type = STACK_MISC; |
| @@ -3677,6 +3653,8 @@ continue_func: · 998 unmodified lines | |||
| 3677 | if (tail_call_reachable) | 3653 | if (tail_call_reachable) |
| 3678 | for (j = 0; j < frame; j++) | 3654 | for (j = 0; j < frame; j++) |
| 3679 | subprog[ret_prog[j]].tail_call_reachable = true; | 3655 | subprog[ret_prog[j]].tail_call_reachable = true; |
| 3656 | if (subprog[0].tail_call_reachable) | ||
| 3657 | env->prog->aux->tail_call_reachable = true; | ||
| 3680 | 3658 | ||
| 3681 | /* end of for() loop means the last insn of the 'subprog' | 3659 | /* end of for() loop means the last insn of the 'subprog' |
| 3682 | * was reached. Doesn't matter whether it was JA or EXIT | 3660 | * was reached. Doesn't matter whether it was JA or EXIT |
| @@ -6559,6 +6537,12 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, · 2876 unmodified lines | |||
| 6559 | alu_state |= off_is_imm ? BPF_ALU_IMMEDIATE : 0; | 6537 | alu_state |= off_is_imm ? BPF_ALU_IMMEDIATE : 0; |
| 6560 | alu_state |= ptr_is_dst_reg ? | 6538 | alu_state |= ptr_is_dst_reg ? |
| 6561 | BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST; | 6539 | BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST; |
| 6540 | |||
| 6541 | /* Limit pruning on unknown scalars to enable deep search for | ||
| 6542 | * potential masking differences from other program paths. | ||
| 6543 | */ | ||
| 6544 | if (!off_is_imm) | ||
| 6545 | env->explore_alu_limits = true; | ||
| 6562 | } | 6546 | } |
| 6563 | 6547 | ||
| 6564 | err = update_alu_sanitation_state(aux, alu_state, alu_limit); | 6548 | err = update_alu_sanitation_state(aux, alu_state, alu_limit); |
| @@ -9934,8 +9918,8 @@ next: · 3369 unmodified lines | |||
| 9934 | } | 9918 | } |
| 9935 | 9919 | ||
| 9936 | /* Returns true if (rold safe implies rcur safe) */ | 9920 | /* Returns true if (rold safe implies rcur safe) */ |
| 9937 | static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, | 9921 | static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, |
| 9938 | struct bpf_id_pair *idmap) | 9922 | struct bpf_reg_state *rcur, struct bpf_id_pair *idmap) |
| 9939 | { | 9923 | { |
| 9940 | bool equal; | 9924 | bool equal; |
| 9941 | 9925 | ||
| @@ -9961,6 +9945,8 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, · 19 unmodified lines | |||
| 9961 | return false; | 9945 | return false; |
| 9962 | switch (rold->type) { | 9946 | switch (rold->type) { |
| 9963 | case SCALAR_VALUE: | 9947 | case SCALAR_VALUE: |
| 9948 | if (env->explore_alu_limits) | ||
| 9949 | return false; | ||
| 9964 | if (rcur->type == SCALAR_VALUE) { | 9950 | if (rcur->type == SCALAR_VALUE) { |
| 9965 | if (!rold->precise && !rcur->precise) | 9951 | if (!rold->precise && !rcur->precise) |
| 9966 | return true; | 9952 | return true; |
| @@ -10051,9 +10037,8 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, · 84 unmodified lines | |||
| 10051 | return false; | 10037 | return false; |
| 10052 | } | 10038 | } |
| 10053 | 10039 | ||
| 10054 | static bool stacksafe(struct bpf_func_state *old, | 10040 | static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old, |
| 10055 | struct bpf_func_state *cur, | 10041 | struct bpf_func_state *cur, struct bpf_id_pair *idmap) |
| 10056 | struct bpf_id_pair *idmap) | ||
| 10057 | { | 10042 | { |
| 10058 | int i, spi; | 10043 | int i, spi; |
| 10059 | 10044 | ||
| @@ -10098,9 +10083,8 @@ static bool stacksafe(struct bpf_func_state *old, · 38 unmodified lines | |||
| 10098 | continue; | 10083 | continue; |
| 10099 | if (old->stack[spi].slot_type[0] != STACK_SPILL) | 10084 | if (old->stack[spi].slot_type[0] != STACK_SPILL) |
| 10100 | continue; | 10085 | continue; |
| 10101 | if (!regsafe(&old->stack[spi].spilled_ptr, | 10086 | if (!regsafe(env, &old->stack[spi].spilled_ptr, |
| 10102 | &cur->stack[spi].spilled_ptr, | 10087 | &cur->stack[spi].spilled_ptr, idmap)) |
| 10103 | idmap)) | ||
| 10104 | /* when explored and current stack slot are both storing | 10088 | /* when explored and current stack slot are both storing |
| 10105 | * spilled registers, check that stored pointers types | 10089 | * spilled registers, check that stored pointers types |
| 10106 | * are the same as well. | 10090 | * are the same as well. |
| @@ -10157,10 +10141,11 @@ static bool func_states_equal(struct bpf_verifier_env *env, struct bpf_func_stat · 50 unmodified lines | |||
| 10157 | 10141 | ||
| 10158 | memset(env->idmap_scratch, 0, sizeof(env->idmap_scratch)); | 10142 | memset(env->idmap_scratch, 0, sizeof(env->idmap_scratch)); |
| 10159 | for (i = 0; i < MAX_BPF_REG; i++) | 10143 | for (i = 0; i < MAX_BPF_REG; i++) |
| 10160 | if (!regsafe(&old->regs[i], &cur->regs[i], env->idmap_scratch)) | 10144 | if (!regsafe(env, &old->regs[i], &cur->regs[i], |
| 10145 | env->idmap_scratch)) | ||
| 10161 | return false; | 10146 | return false; |
| 10162 | 10147 | ||
| 10163 | if (!stacksafe(old, cur, env->idmap_scratch)) | 10148 | if (!stacksafe(env, old, cur, env->idmap_scratch)) |
| 10164 | return false; | 10149 | return false; |
| 10165 | 10150 | ||
| 10166 | if (!refsafe(old, cur)) | 10151 | if (!refsafe(old, cur)) |
| @@ -11904,35 +11889,33 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) · 1737 unmodified lines | |||
| 11904 | 11889 | ||
| 11905 | for (i = 0; i < insn_cnt; i++, insn++) { | 11890 | for (i = 0; i < insn_cnt; i++, insn++) { |
| 11906 | bpf_convert_ctx_access_t convert_ctx_access; | 11891 | bpf_convert_ctx_access_t convert_ctx_access; |
| 11892 | bool ctx_access; | ||
| 11907 | 11893 | ||
| 11908 | if (insn->code == (BPF_LDX | BPF_MEM | BPF_B) || | 11894 | if (insn->code == (BPF_LDX | BPF_MEM | BPF_B) || |
| 11909 | insn->code == (BPF_LDX | BPF_MEM | BPF_H) || | 11895 | insn->code == (BPF_LDX | BPF_MEM | BPF_H) || |
| 11910 | insn->code == (BPF_LDX | BPF_MEM | BPF_W) || | 11896 | insn->code == (BPF_LDX | BPF_MEM | BPF_W) || |
| 11911 | insn->code == (BPF_LDX | BPF_MEM | BPF_DW)) | 11897 | insn->code == (BPF_LDX | BPF_MEM | BPF_DW)) { |
| 11912 | type = BPF_READ; | 11898 | type = BPF_READ; |
| 11913 | else if (insn->code == (BPF_STX | BPF_MEM | BPF_B) || | 11899 | ctx_access = true; |
| 11914 | insn->code == (BPF_STX | BPF_MEM | BPF_H) || | 11900 | } else if (insn->code == (BPF_STX | BPF_MEM | BPF_B) || |
| 11915 | insn->code == (BPF_STX | BPF_MEM | BPF_W) || | 11901 | insn->code == (BPF_STX | BPF_MEM | BPF_H) || |
| 11916 | insn->code == (BPF_STX | BPF_MEM | BPF_DW)) | 11902 | insn->code == (BPF_STX | BPF_MEM | BPF_W) || |
| 11903 | insn->code == (BPF_STX | BPF_MEM | BPF_DW) || | ||
| 11904 | insn->code == (BPF_ST | BPF_MEM | BPF_B) || | ||
| 11905 | insn->code == (BPF_ST | BPF_MEM | BPF_H) || | ||
| 11906 | insn->code == (BPF_ST | BPF_MEM | BPF_W) || | ||
| 11907 | insn->code == (BPF_ST | BPF_MEM | BPF_DW)) { | ||
| 11917 | type = BPF_WRITE; | 11908 | type = BPF_WRITE; |
| 11918 | else | 11909 | ctx_access = BPF_CLASS(insn->code) == BPF_STX; |
| 11910 | } else { | ||
| 11919 | continue; | 11911 | continue; |
| 11912 | } | ||
| 11920 | 11913 | ||
| 11921 | if (type == BPF_WRITE && | 11914 | if (type == BPF_WRITE && |
| 11922 | env->insn_aux_data[i + delta].sanitize_stack_off) { | 11915 | env->insn_aux_data[i + delta].sanitize_stack_spill) { |
| 11923 | struct bpf_insn patch[] = { | 11916 | struct bpf_insn patch[] = { |
| 11924 | /* Sanitize suspicious stack slot with zero. | ||
| 11925 | * There are no memory dependencies for this store, | ||
| 11926 | * since it's only using frame pointer and immediate | ||
| 11927 | * constant of zero | ||
| 11928 | */ | ||
| 11929 | BPF_ST_MEM(BPF_DW, BPF_REG_FP, | ||
| 11930 | env->insn_aux_data[i + delta].sanitize_stack_off, | ||
| 11931 | 0), | ||
| 11932 | /* the original STX instruction will immediately | ||
| 11933 | * overwrite the same stack slot with appropriate value | ||
| 11934 | */ | ||
| 11935 | *insn, | 11917 | *insn, |
| 11918 | BPF_ST_NOSPEC(), | ||
| 11936 | }; | 11919 | }; |
| 11937 | 11920 | ||
| 11938 | cnt = ARRAY_SIZE(patch); | 11921 | cnt = ARRAY_SIZE(patch); |
| @@ -11946,6 +11929,9 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) · 7 unmodified lines | |||
| 11946 | continue; | 11929 | continue; |
| 11947 | } | 11930 | } |
| 11948 | 11931 | ||
| 11932 | if (!ctx_access) | ||
| 11933 | continue; | ||
| 11934 | |||
| 11949 | switch (env->insn_aux_data[i + delta].ptr_type) { | 11935 | switch (env->insn_aux_data[i + delta].ptr_type) { |
| 11950 | case PTR_TO_CTX: | 11936 | case PTR_TO_CTX: |
| 11951 | if (!ops->convert_ctx_access) | 11937 | if (!ops->convert_ctx_access) |
| @@ -12750,37 +12736,6 @@ static void free_states(struct bpf_verifier_env *env) · 798 unmodified lines | |||
| 12750 | } | 12736 | } |
| 12751 | } | 12737 | } |
| 12752 | 12738 | ||
| 12753 | /* The verifier is using insn_aux_data[] to store temporary data during | ||
| 12754 | * verification and to store information for passes that run after the | ||
| 12755 | * verification like dead code sanitization. do_check_common() for subprogram N | ||
| 12756 | * may analyze many other subprograms. sanitize_insn_aux_data() clears all | ||
| 12757 | * temporary data after do_check_common() finds that subprogram N cannot be | ||
| 12758 | * verified independently. pass_cnt counts the number of times | ||
| 12759 | * do_check_common() was run and insn->aux->seen tells the pass number | ||
| 12760 | * insn_aux_data was touched. These variables are compared to clear temporary | ||
| 12761 | * data from failed pass. For testing and experiments do_check_common() can be | ||
| 12762 | * run multiple times even when prior attempt to verify is unsuccessful. | ||
| 12763 | * | ||
| 12764 | * Note that special handling is needed on !env->bypass_spec_v1 if this is | ||
| 12765 | * ever called outside of error path with subsequent program rejection. | ||
| 12766 | */ | ||
| 12767 | static void sanitize_insn_aux_data(struct bpf_verifier_env *env) | ||
| 12768 | { | ||
| 12769 | struct bpf_insn *insn = env->prog->insnsi; | ||
| 12770 | struct bpf_insn_aux_data *aux; | ||
| 12771 | int i, class; | ||
| 12772 | |||
| 12773 | for (i = 0; i < env->prog->len; i++) { | ||
| 12774 | class = BPF_CLASS(insn[i].code); | ||
| 12775 | if (class != BPF_LDX && class != BPF_STX) | ||
| 12776 | continue; | ||
| 12777 | aux = &env->insn_aux_data[i]; | ||
| 12778 | if (aux->seen != env->pass_cnt) | ||
| 12779 | continue; | ||
| 12780 | memset(aux, 0, offsetof(typeof(*aux), orig_idx)); | ||
| 12781 | } | ||
| 12782 | } | ||
| 12783 | |||
| 12784 | static int do_check_common(struct bpf_verifier_env *env, int subprog) | 12739 | static int do_check_common(struct bpf_verifier_env *env, int subprog) |
| 12785 | { | 12740 | { |
| 12786 | bool pop_log = !(env->log.level & BPF_LOG_LEVEL2); | 12741 | bool pop_log = !(env->log.level & BPF_LOG_LEVEL2); |
| @@ -12857,9 +12812,6 @@ out: · 70 unmodified lines | |||
| 12857 | if (!ret && pop_log) | 12812 | if (!ret && pop_log) |
| 12858 | bpf_vlog_reset(&env->log, 0); | 12813 | bpf_vlog_reset(&env->log, 0); |
| 12859 | free_states(env); | 12814 | free_states(env); |
| 12860 | if (ret) | ||
| 12861 | /* clean aux data in case subprog was rejected */ | ||
| 12862 | sanitize_insn_aux_data(env); | ||
| 12863 | return ret; | 12815 | return ret; |
| 12864 | } | 12816 | } |
| 12865 | 12817 | ||
| @@ -1221,9 +1221,7 @@ int cgroup1_get_tree(struct fs_context *fc) · 1220 unmodified lines | |||
| 1221 | ret = cgroup_do_get_tree(fc); | 1221 | ret = cgroup_do_get_tree(fc); |
| 1222 | 1222 | ||
| 1223 | if (!ret && percpu_ref_is_dying(&ctx->root->cgrp.self.refcnt)) { | 1223 | if (!ret && percpu_ref_is_dying(&ctx->root->cgrp.self.refcnt)) { |
| 1224 | struct super_block *sb = fc->root->d_sb; | 1224 | fc_drop_locked(fc); |
| 1225 | dput(fc->root); | ||
| 1226 | deactivate_locked_super(sb); | ||
| 1227 | ret = 1; | 1225 | ret = 1; |
| 1228 | } | 1226 | } |
| 1229 | 1227 | ||
| @@ -5,6 +5,13 @@ · 4 unmodified lines | |||
| 5 | */ | 5 | */ |
| 6 | #include <linux/dma-map-ops.h> | 6 | #include <linux/dma-map-ops.h> |
| 7 | 7 | ||
| 8 | static struct page *dma_common_vaddr_to_page(void *cpu_addr) | ||
| 9 | { | ||
| 10 | if (is_vmalloc_addr(cpu_addr)) | ||
| 11 | return vmalloc_to_page(cpu_addr); | ||
| 12 | return virt_to_page(cpu_addr); | ||
| 13 | } | ||
| 14 | |||
| 8 | /* | 15 | /* |
| 9 | * Create scatter-list for the already allocated DMA buffer. | 16 | * Create scatter-list for the already allocated DMA buffer. |
| 10 | */ | 17 | */ |
| @@ -12,7 +19,7 @@ int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, · 1 unmodified line | |||
| 12 | void *cpu_addr, dma_addr_t dma_addr, size_t size, | 19 | void *cpu_addr, dma_addr_t dma_addr, size_t size, |
| 13 | unsigned long attrs) | 20 | unsigned long attrs) |
| 14 | { | 21 | { |
| 15 | struct page *page = virt_to_page(cpu_addr); | 22 | struct page *page = dma_common_vaddr_to_page(cpu_addr); |
| 16 | int ret; | 23 | int ret; |
| 17 | 24 | ||
| 18 | ret = sg_alloc_table(sgt, 1, GFP_KERNEL); | 25 | ret = sg_alloc_table(sgt, 1, GFP_KERNEL); |
| @@ -32,6 +39,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, · 13 unmodified lines | |||
| 32 | unsigned long user_count = vma_pages(vma); | 39 | unsigned long user_count = vma_pages(vma); |
| 33 | unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; | 40 | unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; |
| 34 | unsigned long off = vma->vm_pgoff; | 41 | unsigned long off = vma->vm_pgoff; |
| 42 | struct page *page = dma_common_vaddr_to_page(cpu_addr); | ||
| 35 | int ret = -ENXIO; | 43 | int ret = -ENXIO; |
| 36 | 44 | ||
| 37 | vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs); | 45 | vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs); |
| @@ -43,7 +51,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, · 5 unmodified lines | |||
| 43 | return -ENXIO; | 51 | return -ENXIO; |
| 44 | 52 | ||
| 45 | return remap_pfn_range(vma, vma->vm_start, | 53 | return remap_pfn_range(vma, vma->vm_start, |
| 46 | page_to_pfn(virt_to_page(cpu_addr)) + vma->vm_pgoff, | 54 | page_to_pfn(page) + vma->vm_pgoff, |
| 47 | user_count << PAGE_SHIFT, vma->vm_page_prot); | 55 | user_count << PAGE_SHIFT, vma->vm_page_prot); |
| 48 | #else | 56 | #else |
| 49 | return -ENXIO; | 57 | return -ENXIO; |
| @@ -47,7 +47,7 @@ void __init idle_thread_set_boot_cpu(void) · 46 unmodified lines | |||
| 47 | * | 47 | * |
| 48 | * Creates the thread if it does not exist. | 48 | * Creates the thread if it does not exist. |
| 49 | */ | 49 | */ |
| 50 | static inline void idle_init(unsigned int cpu) | 50 | static __always_inline void idle_init(unsigned int cpu) |
| 51 | { | 51 | { |
| 52 | struct task_struct *tsk = per_cpu(idle_threads, cpu); | 52 | struct task_struct *tsk = per_cpu(idle_threads, cpu); |
| 53 | 53 | ||
| @@ -991,6 +991,11 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer) · 990 unmodified lines | |||
| 991 | if (!p) | 991 | if (!p) |
| 992 | goto out; | 992 | goto out; |
| 993 | 993 | ||
| 994 | /* Protect timer list r/w in arm_timer() */ | ||
| 995 | sighand = lock_task_sighand(p, &flags); | ||
| 996 | if (unlikely(sighand == NULL)) | ||
| 997 | goto out; | ||
| 998 | |||
| 994 | /* | 999 | /* |
| 995 | * Fetch the current sample and update the timer's expiry time. | 1000 | * Fetch the current sample and update the timer's expiry time. |
| 996 | */ | 1001 | */ |
| @@ -1001,11 +1006,6 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer) · 4 unmodified lines | |||
| 1001 | 1006 | ||
| 1002 | bump_cpu_timer(timer, now); | 1007 | bump_cpu_timer(timer, now); |
| 1003 | 1008 | ||
| 1004 | /* Protect timer list r/w in arm_timer() */ | ||
| 1005 | sighand = lock_task_sighand(p, &flags); | ||
| 1006 | if (unlikely(sighand == NULL)) | ||
| 1007 | goto out; | ||
| 1008 | |||
| 1009 | /* | 1009 | /* |
| 1010 | * Now re-arm for the new expiry time. | 1010 | * Now re-arm for the new expiry time. |
| 1011 | */ | 1011 | */ |
| @@ -207,6 +207,7 @@ struct timer_base { · 206 unmodified lines | |||
| 207 | unsigned int cpu; | 207 | unsigned int cpu; |
| 208 | bool next_expiry_recalc; | 208 | bool next_expiry_recalc; |
| 209 | bool is_idle; | 209 | bool is_idle; |
| 210 | bool timers_pending; | ||
| 210 | DECLARE_BITMAP(pending_map, WHEEL_SIZE); | 211 | DECLARE_BITMAP(pending_map, WHEEL_SIZE); |
| 211 | struct hlist_head vectors[WHEEL_SIZE]; | 212 | struct hlist_head vectors[WHEEL_SIZE]; |
| 212 | } ____cacheline_aligned; | 213 | } ____cacheline_aligned; |
| @@ -595,6 +596,7 @@ static void enqueue_timer(struct timer_base *base, struct timer_list *timer, · 382 unmodified lines | |||
| 595 | * can reevaluate the wheel: | 596 | * can reevaluate the wheel: |
| 596 | */ | 597 | */ |
| 597 | base->next_expiry = bucket_expiry; | 598 | base->next_expiry = bucket_expiry; |
| 599 | base->timers_pending = true; | ||
| 598 | base->next_expiry_recalc = false; | 600 | base->next_expiry_recalc = false; |
| 599 | trigger_dyntick_cpu(base, timer); | 601 | trigger_dyntick_cpu(base, timer); |
| 600 | } | 602 | } |
| @@ -1582,6 +1584,7 @@ static unsigned long __next_timer_interrupt(struct timer_base *base) · 981 unmodified lines | |||
| 1582 | } | 1584 | } |
| 1583 | 1585 | ||
| 1584 | base->next_expiry_recalc = false; | 1586 | base->next_expiry_recalc = false; |
| 1587 | base->timers_pending = !(next == base->clk + NEXT_TIMER_MAX_DELTA); | ||
| 1585 | 1588 | ||
| 1586 | return next; | 1589 | return next; |
| 1587 | } | 1590 | } |
| @@ -1633,7 +1636,6 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) · 45 unmodified lines | |||
| 1633 | struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); | 1636 | struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); |
| 1634 | u64 expires = KTIME_MAX; | 1637 | u64 expires = KTIME_MAX; |
| 1635 | unsigned long nextevt; | 1638 | unsigned long nextevt; |
| 1636 | bool is_max_delta; | ||
| 1637 | 1639 | ||
| 1638 | /* | 1640 | /* |
| 1639 | * Pretend that there is no timer pending if the cpu is offline. | 1641 | * Pretend that there is no timer pending if the cpu is offline. |
| @@ -1646,7 +1648,6 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) · 6 unmodified lines | |||
| 1646 | if (base->next_expiry_recalc) | 1648 | if (base->next_expiry_recalc) |
| 1647 | base->next_expiry = __next_timer_interrupt(base); | 1649 | base->next_expiry = __next_timer_interrupt(base); |
| 1648 | nextevt = base->next_expiry; | 1650 | nextevt = base->next_expiry; |
| 1649 | is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA); | ||
| 1650 | 1651 | ||
| 1651 | /* | 1652 | /* |
| 1652 | * We have a fresh next event. Check whether we can forward the | 1653 | * We have a fresh next event. Check whether we can forward the |
| @@ -1664,7 +1665,7 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) · 11 unmodified lines | |||
| 1664 | expires = basem; | 1665 | expires = basem; |
| 1665 | base->is_idle = false; | 1666 | base->is_idle = false; |
| 1666 | } else { | 1667 | } else { |
| 1667 | if (!is_max_delta) | 1668 | if (base->timers_pending) |
| 1668 | expires = basem + (u64)(nextevt - basej) * TICK_NSEC; | 1669 | expires = basem + (u64)(nextevt - basej) * TICK_NSEC; |
| 1669 | /* | 1670 | /* |
| 1670 | * If we expect to sleep more than a tick, mark the base idle. | 1671 | * If we expect to sleep more than a tick, mark the base idle. |
| @@ -1947,6 +1948,7 @@ int timers_prepare_cpu(unsigned int cpu) · 276 unmodified lines | |||
| 1947 | base = per_cpu_ptr(&timer_bases[b], cpu); | 1948 | base = per_cpu_ptr(&timer_bases[b], cpu); |
| 1948 | base->clk = jiffies; | 1949 | base->clk = jiffies; |
| 1949 | base->next_expiry = base->clk + NEXT_TIMER_MAX_DELTA; | 1950 | base->next_expiry = base->clk + NEXT_TIMER_MAX_DELTA; |
| 1951 | base->timers_pending = false; | ||
| 1950 | base->is_idle = false; | 1952 | base->is_idle = false; |
| 1951 | } | 1953 | } |
| 1952 | return 0; | 1954 | return 0; |
| @@ -5985,7 +5985,8 @@ ftrace_graph_release(struct inode *inode, struct file *file) · 5984 unmodified lines | |||
| 5985 | * infrastructure to do the synchronization, thus we must do it | 5985 | * infrastructure to do the synchronization, thus we must do it |
| 5986 | * ourselves. | 5986 | * ourselves. |
| 5987 | */ | 5987 | */ |
| 5988 | synchronize_rcu_tasks_rude(); | 5988 | if (old_hash != EMPTY_HASH) |
| 5989 | synchronize_rcu_tasks_rude(); | ||
| 5989 | 5990 | ||
| 5990 | free_ftrace_hash(old_hash); | 5991 | free_ftrace_hash(old_hash); |
| 5991 | } | 5992 | } |
| @@ -7544,7 +7545,7 @@ int ftrace_is_dead(void) · 1552 unmodified lines | |||
| 7544 | */ | 7545 | */ |
| 7545 | int register_ftrace_function(struct ftrace_ops *ops) | 7546 | int register_ftrace_function(struct ftrace_ops *ops) |
| 7546 | { | 7547 | { |
| 7547 | int ret = -1; | 7548 | int ret; |
| 7548 | 7549 | ||
| 7549 | ftrace_ops_init(ops); | 7550 | ftrace_ops_init(ops); |
| 7550 | 7551 | ||
| @@ -3880,10 +3880,30 @@ static bool rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer) · 3879 unmodified lines | |||
| 3880 | if (unlikely(!head)) | 3880 | if (unlikely(!head)) |
| 3881 | return true; | 3881 | return true; |
| 3882 | 3882 | ||
| 3883 | return reader->read == rb_page_commit(reader) && | 3883 | /* Reader should exhaust content in reader page */ |
| 3884 | (commit == reader || | 3884 | if (reader->read != rb_page_commit(reader)) |
| 3885 | (commit == head && | 3885 | return false; |
| 3886 | head->read == rb_page_commit(commit))); | 3886 | |
| 3887 | /* | ||
| 3888 | * If writers are committing on the reader page, knowing all | ||
| 3889 | * committed content has been read, the ring buffer is empty. | ||
| 3890 | */ | ||
| 3891 | if (commit == reader) | ||
| 3892 | return true; | ||
| 3893 | |||
| 3894 | /* | ||
| 3895 | * If writers are committing on a page other than reader page | ||
| 3896 | * and head page, there should always be content to read. | ||
| 3897 | */ | ||
| 3898 | if (commit != head) | ||
| 3899 | return false; | ||
| 3900 | |||
| 3901 | /* | ||
| 3902 | * Writers are committing on the head page, we just need | ||
| 3903 | * to care about there're committed data, and the reader will | ||
| 3904 | * swap reader page with head page when it is to read data. | ||
| 3905 | */ | ||
| 3906 | return rb_page_commit(commit) == 0; | ||
| 3887 | } | 3907 | } |
| 3888 | 3908 | ||
| 3889 | /** | 3909 | /** |
| @@ -5609,6 +5609,10 @@ static const char readme_msg[] = · 5608 unmodified lines | |||
| 5609 | "\t [:name=histname1]\n" | 5609 | "\t [:name=histname1]\n" |
| 5610 | "\t [:<handler>.<action>]\n" | 5610 | "\t [:<handler>.<action>]\n" |
| 5611 | "\t [if <filter>]\n\n" | 5611 | "\t [if <filter>]\n\n" |
| 5612 | "\t Note, special fields can be used as well:\n" | ||
| 5613 | "\t common_timestamp - to record current timestamp\n" | ||
| 5614 | "\t common_cpu - to record the CPU the event happened on\n" | ||
| 5615 | "\n" | ||
| 5612 | "\t When a matching event is hit, an entry is added to a hash\n" | 5616 | "\t When a matching event is hit, an entry is added to a hash\n" |
| 5613 | "\t table using the key(s) and value(s) named, and the value of a\n" | 5617 | "\t table using the key(s) and value(s) named, and the value of a\n" |
| 5614 | "\t sum called 'hitcount' is incremented. Keys and values\n" | 5618 | "\t sum called 'hitcount' is incremented. Keys and values\n" |
| @@ -1111,7 +1111,7 @@ static const char *hist_field_name(struct hist_field *field, · 1110 unmodified lines | |||
| 1111 | field->flags & HIST_FIELD_FL_ALIAS) | 1111 | field->flags & HIST_FIELD_FL_ALIAS) |
| 1112 | field_name = hist_field_name(field->operands[0], ++level); | 1112 | field_name = hist_field_name(field->operands[0], ++level); |
| 1113 | else if (field->flags & HIST_FIELD_FL_CPU) | 1113 | else if (field->flags & HIST_FIELD_FL_CPU) |
| 1114 | field_name = "cpu"; | 1114 | field_name = "common_cpu"; |
| 1115 | else if (field->flags & HIST_FIELD_FL_EXPR || | 1115 | else if (field->flags & HIST_FIELD_FL_EXPR || |
| 1116 | field->flags & HIST_FIELD_FL_VAR_REF) { | 1116 | field->flags & HIST_FIELD_FL_VAR_REF) { |
| 1117 | if (field->system) { | 1117 | if (field->system) { |
| @@ -1991,14 +1991,24 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, · 873 unmodified lines | |||
| 1991 | hist_data->enable_timestamps = true; | 1991 | hist_data->enable_timestamps = true; |
| 1992 | if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS) | 1992 | if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS) |
| 1993 | hist_data->attrs->ts_in_usecs = true; | 1993 | hist_data->attrs->ts_in_usecs = true; |
| 1994 | } else if (strcmp(field_name, "cpu") == 0) | 1994 | } else if (strcmp(field_name, "common_cpu") == 0) |
| 1995 | *flags |= HIST_FIELD_FL_CPU; | 1995 | *flags |= HIST_FIELD_FL_CPU; |
| 1996 | else { | 1996 | else { |
| 1997 | field = trace_find_event_field(file->event_call, field_name); | 1997 | field = trace_find_event_field(file->event_call, field_name); |
| 1998 | if (!field || !field->size) { | 1998 | if (!field || !field->size) { |
| 1999 | hist_err(tr, HIST_ERR_FIELD_NOT_FOUND, errpos(field_name)); | 1999 | /* |
| 2000 | field = ERR_PTR(-EINVAL); | 2000 | * For backward compatibility, if field_name |
| 2001 | goto out; | 2001 | * was "cpu", then we treat this the same as |
| 2002 | * common_cpu. | ||
| 2003 | */ | ||
| 2004 | if (strcmp(field_name, "cpu") == 0) { | ||
| 2005 | *flags |= HIST_FIELD_FL_CPU; | ||
| 2006 | } else { | ||
| 2007 | hist_err(tr, HIST_ERR_FIELD_NOT_FOUND, | ||
| 2008 | errpos(field_name)); | ||
| 2009 | field = ERR_PTR(-EINVAL); | ||
| 2010 | goto out; | ||
| 2011 | } | ||
| 2002 | } | 2012 | } |
| 2003 | } | 2013 | } |
| 2004 | out: | 2014 | out: |
| @@ -5085,7 +5095,7 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) · 3080 unmodified lines | |||
| 5085 | seq_printf(m, "%s=", hist_field->var.name); | 5095 | seq_printf(m, "%s=", hist_field->var.name); |
| 5086 | 5096 | ||
| 5087 | if (hist_field->flags & HIST_FIELD_FL_CPU) | 5097 | if (hist_field->flags & HIST_FIELD_FL_CPU) |
| 5088 | seq_puts(m, "cpu"); | 5098 | seq_puts(m, "common_cpu"); |
| 5089 | else if (field_name) { | 5099 | else if (field_name) { |
| 5090 | if (hist_field->flags & HIST_FIELD_FL_VAR_REF || | 5100 | if (hist_field->flags & HIST_FIELD_FL_VAR_REF || |
| 5091 | hist_field->flags & HIST_FIELD_FL_ALIAS) | 5101 | hist_field->flags & HIST_FIELD_FL_ALIAS) |
| @@ -893,15 +893,13 @@ static struct synth_event *alloc_synth_event(const char *name, int n_fields, · 892 unmodified lines | |||
| 893 | dyn_event_init(&event->devent, &synth_event_ops); | 893 | dyn_event_init(&event->devent, &synth_event_ops); |
| 894 | 894 | ||
| 895 | for (i = 0, j = 0; i < n_fields; i++) { | 895 | for (i = 0, j = 0; i < n_fields; i++) { |
| 896 | fields[i]->field_pos = i; | ||
| 896 | event->fields[i] = fields[i]; | 897 | event->fields[i] = fields[i]; |
| 897 | 898 | ||
| 898 | if (fields[i]->is_dynamic) { | 899 | if (fields[i]->is_dynamic) |
| 899 | event->dynamic_fields[j] = fields[i]; | ||
| 900 | event->dynamic_fields[j]->field_pos = i; | ||
| 901 | event->dynamic_fields[j++] = fields[i]; | 900 | event->dynamic_fields[j++] = fields[i]; |
| 902 | event->n_dynamic_fields++; | ||
| 903 | } | ||
| 904 | } | 901 | } |
| 902 | event->n_dynamic_fields = j; | ||
| 905 | event->n_fields = n_fields; | 903 | event->n_fields = n_fields; |
| 906 | out: | 904 | out: |
| 907 | return event; | 905 | return event; |
| @@ -14,10 +14,10 @@ struct synth_field { · 13 unmodified lines | |||
| 14 | char *name; | 14 | char *name; |
| 15 | size_t size; | 15 | size_t size; |
| 16 | unsigned int offset; | 16 | unsigned int offset; |
| 17 | unsigned int field_pos; | ||
| 17 | bool is_signed; | 18 | bool is_signed; |
| 18 | bool is_string; | 19 | bool is_string; |
| 19 | bool is_dynamic; | 20 | bool is_dynamic; |
| 20 | bool field_pos; | ||
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | struct synth_event { | 23 | struct synth_event { |
| @@ -299,8 +299,8 @@ static int tracepoint_add_func(struct tracepoint *tp, · 298 unmodified lines | |||
| 299 | * a pointer to it. This array is referenced by __DO_TRACE from | 299 | * a pointer to it. This array is referenced by __DO_TRACE from |
| 300 | * include/linux/tracepoint.h using rcu_dereference_sched(). | 300 | * include/linux/tracepoint.h using rcu_dereference_sched(). |
| 301 | */ | 301 | */ |
| 302 | rcu_assign_pointer(tp->funcs, tp_funcs); | ||
| 303 | tracepoint_update_call(tp, tp_funcs, false); | 302 | tracepoint_update_call(tp, tp_funcs, false); |
| 303 | rcu_assign_pointer(tp->funcs, tp_funcs); | ||
| 304 | static_key_enable(&tp->key); | 304 | static_key_enable(&tp->key); |
| 305 | 305 | ||
| 306 | release_probes(old); | 306 | release_probes(old); |
| @@ -3676,15 +3676,21 @@ static void pwq_unbound_release_workfn(struct work_struct *work) · 3675 unmodified lines | |||
| 3676 | unbound_release_work); | 3676 | unbound_release_work); |
| 3677 | struct workqueue_struct *wq = pwq->wq; | 3677 | struct workqueue_struct *wq = pwq->wq; |
| 3678 | struct worker_pool *pool = pwq->pool; | 3678 | struct worker_pool *pool = pwq->pool; |
| 3679 | bool is_last; | 3679 | bool is_last = false; |
| 3680 | 3680 | ||
| 3681 | if (WARN_ON_ONCE(!(wq->flags & WQ_UNBOUND))) | 3681 | /* |
| 3682 | return; | 3682 | * when @pwq is not linked, it doesn't hold any reference to the |
| 3683 | * @wq, and @wq is invalid to access. | ||
| 3684 | */ | ||
| 3685 | if (!list_empty(&pwq->pwqs_node)) { | ||
| 3686 | if (WARN_ON_ONCE(!(wq->flags & WQ_UNBOUND))) | ||
| 3687 | return; | ||
| 3683 | 3688 | ||
| 3684 | mutex_lock(&wq->mutex); | 3689 | mutex_lock(&wq->mutex); |
| 3685 | list_del_rcu(&pwq->pwqs_node); | 3690 | list_del_rcu(&pwq->pwqs_node); |
| 3686 | is_last = list_empty(&wq->pwqs); | 3691 | is_last = list_empty(&wq->pwqs); |
| 3687 | mutex_unlock(&wq->mutex); | 3692 | mutex_unlock(&wq->mutex); |
| 3693 | } | ||
| 3688 | 3694 | ||
| 3689 | mutex_lock(&wq_pool_mutex); | 3695 | mutex_lock(&wq_pool_mutex); |
| 3690 | put_unbound_pool(pool); | 3696 | put_unbound_pool(pool); |
| @@ -683,9 +683,6 @@ config PARMAN · 682 unmodified lines | |||
| 683 | config OBJAGG | 683 | config OBJAGG |
| 684 | tristate "objagg" if COMPILE_TEST | 684 | tristate "objagg" if COMPILE_TEST |
| 685 | 685 | ||
| 686 | config STRING_SELFTEST | ||
| 687 | tristate "Test string functions" | ||
| 688 | |||
| 689 | endmenu | 686 | endmenu |
| 690 | 687 | ||
| 691 | config GENERIC_IOREMAP | 688 | config GENERIC_IOREMAP |
| @@ -2180,6 +2180,9 @@ config ASYNC_RAID6_TEST · 2179 unmodified lines | |||
| 2180 | config TEST_HEXDUMP | 2180 | config TEST_HEXDUMP |
| 2181 | tristate "Test functions located in the hexdump module at runtime" | 2181 | tristate "Test functions located in the hexdump module at runtime" |
| 2182 | 2182 | ||
| 2183 | config STRING_SELFTEST | ||
| 2184 | tristate "Test string functions at runtime" | ||
| 2185 | |||
| 2183 | config TEST_STRING_HELPERS | 2186 | config TEST_STRING_HELPERS |
| 2184 | tristate "Test functions located in the string_helpers module at runtime" | 2187 | tristate "Test functions located in the string_helpers module at runtime" |
| 2185 | 2188 | ||
| @@ -398,12 +398,12 @@ static void cgwb_release_workfn(struct work_struct *work) · 397 unmodified lines | |||
| 398 | blkcg_unpin_online(blkcg); | 398 | blkcg_unpin_online(blkcg); |
| 399 | 399 | ||
| 400 | fprop_local_destroy_percpu(&wb->memcg_completions); | 400 | fprop_local_destroy_percpu(&wb->memcg_completions); |
| 401 | percpu_ref_exit(&wb->refcnt); | ||
| 402 | 401 | ||
| 403 | spin_lock_irq(&cgwb_lock); | 402 | spin_lock_irq(&cgwb_lock); |
| 404 | list_del(&wb->offline_node); | 403 | list_del(&wb->offline_node); |
| 405 | spin_unlock_irq(&cgwb_lock); | 404 | spin_unlock_irq(&cgwb_lock); |
| 406 | 405 | ||
| 406 | percpu_ref_exit(&wb->refcnt); | ||
| 407 | wb_exit(wb); | 407 | wb_exit(wb); |
| 408 | WARN_ON_ONCE(!list_empty(&wb->b_attached)); | 408 | WARN_ON_ONCE(!list_empty(&wb->b_attached)); |
| 409 | kfree_rcu(wb, rcu); | 409 | kfree_rcu(wb, rcu); |
| @@ -733,6 +733,22 @@ void kfence_shutdown_cache(struct kmem_cache *s) · 732 unmodified lines | |||
| 733 | 733 | ||
| 734 | void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) | 734 | void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) |
| 735 | { | 735 | { |
| 736 | /* | ||
| 737 | * Perform size check before switching kfence_allocation_gate, so that | ||
| 738 | * we don't disable KFENCE without making an allocation. | ||
| 739 | */ | ||
| 740 | if (size > PAGE_SIZE) | ||
| 741 | return NULL; | ||
| 742 | |||
| 743 | /* | ||
| 744 | * Skip allocations from non-default zones, including DMA. We cannot | ||
| 745 | * guarantee that pages in the KFENCE pool will have the requested | ||
| 746 | * properties (e.g. reside in DMAable memory). | ||
| 747 | */ | ||
| 748 | if ((flags & GFP_ZONEMASK) || | ||
| 749 | (s->flags & (SLAB_CACHE_DMA | SLAB_CACHE_DMA32))) | ||
| 750 | return NULL; | ||
| 751 | |||
| 736 | /* | 752 | /* |
| 737 | * allocation_gate only needs to become non-zero, so it doesn't make | 753 | * allocation_gate only needs to become non-zero, so it doesn't make |
| 738 | * sense to continue writing to it and pay the associated contention | 754 | * sense to continue writing to it and pay the associated contention |
| @@ -757,9 +773,6 @@ void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) · 18 unmodified lines | |||
| 757 | if (!READ_ONCE(kfence_enabled)) | 773 | if (!READ_ONCE(kfence_enabled)) |
| 758 | return NULL; | 774 | return NULL; |
| 759 | 775 | ||
| 760 | if (size > PAGE_SIZE) | ||
| 761 | return NULL; | ||
| 762 | |||
| 763 | return kfence_guarded_alloc(s, size, flags); | 776 | return kfence_guarded_alloc(s, size, flags); |
| 764 | } | 777 | } |
| 765 | 778 | ||
| @@ -852,7 +852,7 @@ static void kfence_test_exit(void) · 851 unmodified lines | |||
| 852 | tracepoint_synchronize_unregister(); | 852 | tracepoint_synchronize_unregister(); |
| 853 | } | 853 | } |
| 854 | 854 | ||
| 855 | late_initcall(kfence_test_init); | 855 | late_initcall_sync(kfence_test_init); |
| 856 | module_exit(kfence_test_exit); | 856 | module_exit(kfence_test_exit); |
| 857 | 857 | ||
| 858 | MODULE_LICENSE("GPL v2"); | 858 | MODULE_LICENSE("GPL v2"); |
| @@ -947,7 +947,8 @@ static bool should_skip_region(struct memblock_type *type, · 946 unmodified lines | |||
| 947 | return true; | 947 | return true; |
| 948 | 948 | ||
| 949 | /* skip hotpluggable memory regions if needed */ | 949 | /* skip hotpluggable memory regions if needed */ |
| 950 | if (movable_node_is_enabled() && memblock_is_hotpluggable(m)) | 950 | if (movable_node_is_enabled() && memblock_is_hotpluggable(m) && |
| 951 | !(flags & MEMBLOCK_HOTPLUG)) | ||
| 951 | return true; | 952 | return true; |
| 952 | 953 | ||
| 953 | /* if we want mirror memory skip non-mirror memory regions */ | 954 | /* if we want mirror memory skip non-mirror memory regions */ |
| @@ -3574,7 +3574,8 @@ static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap) · 3573 unmodified lines | |||
| 3574 | unsigned long val; | 3574 | unsigned long val; |
| 3575 | 3575 | ||
| 3576 | if (mem_cgroup_is_root(memcg)) { | 3576 | if (mem_cgroup_is_root(memcg)) { |
| 3577 | cgroup_rstat_flush(memcg->css.cgroup); | 3577 | /* mem_cgroup_threshold() calls here from irqsafe context */ |
| 3578 | cgroup_rstat_flush_irqsafe(memcg->css.cgroup); | ||
| 3578 | val = memcg_page_state(memcg, NR_FILE_PAGES) + | 3579 | val = memcg_page_state(memcg, NR_FILE_PAGES) + |
| 3579 | memcg_page_state(memcg, NR_ANON_MAPPED); | 3580 | memcg_page_state(memcg, NR_ANON_MAPPED); |
| 3580 | if (swap) | 3581 | if (swap) |
| @@ -4026,8 +4026,17 @@ vm_fault_t finish_fault(struct vm_fault *vmf) · 4025 unmodified lines | |||
| 4026 | return ret; | 4026 | return ret; |
| 4027 | } | 4027 | } |
| 4028 | 4028 | ||
| 4029 | if (unlikely(pte_alloc(vma->vm_mm, vmf->pmd))) | 4029 | if (vmf->prealloc_pte) { |
| 4030 | vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); | ||
| 4031 | if (likely(pmd_none(*vmf->pmd))) { | ||
| 4032 | mm_inc_nr_ptes(vma->vm_mm); | ||
| 4033 | pmd_populate(vma->vm_mm, vmf->pmd, vmf->prealloc_pte); | ||
| 4034 | vmf->prealloc_pte = NULL; | ||
| 4035 | } | ||
| 4036 | spin_unlock(vmf->ptl); | ||
| 4037 | } else if (unlikely(pte_alloc(vma->vm_mm, vmf->pmd))) { | ||
| 4030 | return VM_FAULT_OOM; | 4038 | return VM_FAULT_OOM; |
| 4039 | } | ||
| 4031 | } | 4040 | } |
| 4032 | 4041 | ||
| 4033 | /* See comment in handle_pte_fault() */ | 4042 | /* See comment in handle_pte_fault() */ |
| @@ -2068,7 +2068,7 @@ int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma, · 2067 unmodified lines | |||
| 2068 | LIST_HEAD(migratepages); | 2068 | LIST_HEAD(migratepages); |
| 2069 | new_page_t *new; | 2069 | new_page_t *new; |
| 2070 | bool compound; | 2070 | bool compound; |
| 2071 | unsigned int nr_pages = thp_nr_pages(page); | 2071 | int nr_pages = thp_nr_pages(page); |
| 2072 | 2072 | ||
| 2073 | /* | 2073 | /* |
| 2074 | * PTE mapped THP or HugeTLB page can't reach here so the page could | 2074 | * PTE mapped THP or HugeTLB page can't reach here so the page could |
| @@ -156,14 +156,14 @@ static inline void put_memcg_path_buf(void) · 155 unmodified lines | |||
| 156 | #define TRACE_MMAP_LOCK_EVENT(type, mm, ...) \ | 156 | #define TRACE_MMAP_LOCK_EVENT(type, mm, ...) \ |
| 157 | do { \ | 157 | do { \ |
| 158 | const char *memcg_path; \ | 158 | const char *memcg_path; \ |
| 159 | preempt_disable(); \ | 159 | local_lock(&memcg_paths.lock); \ |
| 160 | memcg_path = get_mm_memcg_path(mm); \ | 160 | memcg_path = get_mm_memcg_path(mm); \ |
| 161 | trace_mmap_lock_##type(mm, \ | 161 | trace_mmap_lock_##type(mm, \ |
| 162 | memcg_path != NULL ? memcg_path : "", \ | 162 | memcg_path != NULL ? memcg_path : "", \ |
| 163 | ##__VA_ARGS__); \ | 163 | ##__VA_ARGS__); \ |
| 164 | if (likely(memcg_path != NULL)) \ | 164 | if (likely(memcg_path != NULL)) \ |
| 165 | put_memcg_path_buf(); \ | 165 | put_memcg_path_buf(); \ |
| 166 | preempt_enable(); \ | 166 | local_unlock(&memcg_paths.lock); \ |
| 167 | } while (0) | 167 | } while (0) |
| 168 | 168 | ||
| 169 | #else /* !CONFIG_MEMCG */ | 169 | #else /* !CONFIG_MEMCG */ |
| @@ -840,21 +840,24 @@ void init_mem_debugging_and_hardening(void) · 839 unmodified lines | |||
| 840 | } | 840 | } |
| 841 | #endif | 841 | #endif |
| 842 | 842 | ||
| 843 | if (_init_on_alloc_enabled_early) { | 843 | if ((_init_on_alloc_enabled_early || _init_on_free_enabled_early) && |
| 844 | if (page_poisoning_requested) | 844 | page_poisoning_requested) { |
| 845 | pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, " | 845 | pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, " |
| 846 | "will take precedence over init_on_alloc\n"); | 846 | "will take precedence over init_on_alloc and init_on_free\n"); |
| 847 | else | 847 | _init_on_alloc_enabled_early = false; |
| 848 | static_branch_enable(&init_on_alloc); | 848 | _init_on_free_enabled_early = false; |
| 849 | } | ||
| 850 | if (_init_on_free_enabled_early) { | ||
| 851 | if (page_poisoning_requested) | ||
| 852 | pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, " | ||
| 853 | "will take precedence over init_on_free\n"); | ||
| 854 | else | ||
| 855 | static_branch_enable(&init_on_free); | ||
| 856 | } | 849 | } |
| 857 | 850 | ||
| 851 | if (_init_on_alloc_enabled_early) | ||
| 852 | static_branch_enable(&init_on_alloc); | ||
| 853 | else | ||
| 854 | static_branch_disable(&init_on_alloc); | ||
| 855 | |||
| 856 | if (_init_on_free_enabled_early) | ||
| 857 | static_branch_enable(&init_on_free); | ||
| 858 | else | ||
| 859 | static_branch_disable(&init_on_free); | ||
| 860 | |||
| 858 | #ifdef CONFIG_DEBUG_PAGEALLOC | 861 | #ifdef CONFIG_DEBUG_PAGEALLOC |
| 859 | if (!debug_pagealloc_enabled()) | 862 | if (!debug_pagealloc_enabled()) |
| 860 | return; | 863 | return; |
| @@ -152,6 +152,7 @@ static void secretmem_freepage(struct page *page) · 151 unmodified lines | |||
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | const struct address_space_operations secretmem_aops = { | 154 | const struct address_space_operations secretmem_aops = { |
| 155 | .set_page_dirty = __set_page_dirty_no_writeback, | ||
| 155 | .freepage = secretmem_freepage, | 156 | .freepage = secretmem_freepage, |
| 156 | .migratepage = secretmem_migratepage, | 157 | .migratepage = secretmem_migratepage, |
| 157 | .isolate_page = secretmem_isolate_page, | 158 | .isolate_page = secretmem_isolate_page, |
| @@ -346,7 +346,7 @@ static inline void memcg_slab_free_hook(struct kmem_cache *s_orig, · 345 unmodified lines | |||
| 346 | continue; | 346 | continue; |
| 347 | 347 | ||
| 348 | page = virt_to_head_page(p[i]); | 348 | page = virt_to_head_page(p[i]); |
| 349 | objcgs = page_objcgs(page); | 349 | objcgs = page_objcgs_check(page); |
| 350 | if (!objcgs) | 350 | if (!objcgs) |
| 351 | continue; | 351 | continue; |
| 352 | 352 | ||
| @@ -3236,6 +3236,16 @@ struct detached_freelist { · 3235 unmodified lines | |||
| 3236 | struct kmem_cache *s; | 3236 | struct kmem_cache *s; |
| 3237 | }; | 3237 | }; |
| 3238 | 3238 | ||
| 3239 | static inline void free_nonslab_page(struct page *page) | ||
| 3240 | { | ||
| 3241 | unsigned int order = compound_order(page); | ||
| 3242 | |||
| 3243 | VM_BUG_ON_PAGE(!PageCompound(page), page); | ||
| 3244 | kfree_hook(page_address(page)); | ||
| 3245 | mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B, -(PAGE_SIZE << order)); | ||
| 3246 | __free_pages(page, order); | ||
| 3247 | } | ||
| 3248 | |||
| 3239 | /* | 3249 | /* |
| 3240 | * This function progressively scans the array with free objects (with | 3250 | * This function progressively scans the array with free objects (with |
| 3241 | * a limited look ahead) and extract objects belonging to the same | 3251 | * a limited look ahead) and extract objects belonging to the same |
| @@ -3272,9 +3282,7 @@ int build_detached_freelist(struct kmem_cache *s, size_t size, · 30 unmodified lines | |||
| 3272 | if (!s) { | 3282 | if (!s) { |
| 3273 | /* Handle kalloc'ed objects */ | 3283 | /* Handle kalloc'ed objects */ |
| 3274 | if (unlikely(!PageSlab(page))) { | 3284 | if (unlikely(!PageSlab(page))) { |
| 3275 | BUG_ON(!PageCompound(page)); | 3285 | free_nonslab_page(page); |
| 3276 | kfree_hook(object); | ||
| 3277 | __free_pages(page, compound_order(page)); | ||
| 3278 | p[size] = NULL; /* mark object processed */ | 3286 | p[size] = NULL; /* mark object processed */ |
| 3279 | return size; | 3287 | return size; |
| 3280 | } | 3288 | } |
| @@ -4250,13 +4258,7 @@ void kfree(const void *x) · 969 unmodified lines | |||
| 4250 | 4258 | ||
| 4251 | page = virt_to_head_page(x); | 4259 | page = virt_to_head_page(x); |
| 4252 | if (unlikely(!PageSlab(page))) { | 4260 | if (unlikely(!PageSlab(page))) { |
| 4253 | unsigned int order = compound_order(page); | 4261 | free_nonslab_page(page); |
| 4254 | |||
| 4255 | BUG_ON(!PageCompound(page)); | ||
| 4256 | kfree_hook(object); | ||
| 4257 | mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B, | ||
| 4258 | -(PAGE_SIZE << order)); | ||
| 4259 | __free_pages(page, order); | ||
| 4260 | return; | 4262 | return; |
| 4261 | } | 4263 | } |
| 4262 | slab_free(page->slab_cache, page, object, NULL, 1, _RET_IP_); | 4264 | slab_free(page->slab_cache, page, object, NULL, 1, _RET_IP_); |
| @@ -701,6 +701,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, · 700 unmodified lines | |||
| 701 | void *data; | 701 | void *data; |
| 702 | int ret; | 702 | int ret; |
| 703 | 703 | ||
| 704 | if (prog->expected_attach_type == BPF_XDP_DEVMAP || | ||
| 705 | prog->expected_attach_type == BPF_XDP_CPUMAP) | ||
| 706 | return -EINVAL; | ||
| 704 | if (kattr->test.ctx_in || kattr->test.ctx_out) | 707 | if (kattr->test.ctx_in || kattr->test.ctx_out) |
| 705 | return -EINVAL; | 708 | return -EINVAL; |
| 706 | 709 | ||
| @@ -780,7 +780,7 @@ int br_fdb_replay(const struct net_device *br_dev, const struct net_device *dev, · 779 unmodified lines | |||
| 780 | struct net_device *dst_dev; | 780 | struct net_device *dst_dev; |
| 781 | 781 | ||
| 782 | dst_dev = dst ? dst->dev : br->dev; | 782 | dst_dev = dst ? dst->dev : br->dev; |
| 783 | if (dst_dev != br_dev && dst_dev != dev) | 783 | if (dst_dev && dst_dev != dev) |
| 784 | continue; | 784 | continue; |
| 785 | 785 | ||
| 786 | err = br_fdb_replay_one(nb, fdb, dst_dev, action, ctx); | 786 | err = br_fdb_replay_one(nb, fdb, dst_dev, action, ctx); |
| @@ -539,7 +539,8 @@ static int caif_seqpkt_sendmsg(struct socket *sock, struct msghdr *msg, · 538 unmodified lines | |||
| 539 | goto err; | 539 | goto err; |
| 540 | 540 | ||
| 541 | ret = -EINVAL; | 541 | ret = -EINVAL; |
| 542 | if (unlikely(msg->msg_iter.iov->iov_base == NULL)) | 542 | if (unlikely(msg->msg_iter.nr_segs == 0) || |
| 543 | unlikely(msg->msg_iter.iov->iov_base == NULL)) | ||
| 543 | goto err; | 544 | goto err; |
| 544 | noblock = msg->msg_flags & MSG_DONTWAIT; | 545 | noblock = msg->msg_flags & MSG_DONTWAIT; |
| 545 | 546 | ||
| @@ -1075,11 +1075,16 @@ static bool j1939_session_deactivate_locked(struct j1939_session *session) · 1074 unmodified lines | |||
| 1075 | 1075 | ||
| 1076 | static bool j1939_session_deactivate(struct j1939_session *session) | 1076 | static bool j1939_session_deactivate(struct j1939_session *session) |
| 1077 | { | 1077 | { |
| 1078 | struct j1939_priv *priv = session->priv; | ||
| 1078 | bool active; | 1079 | bool active; |
| 1079 | 1080 | ||
| 1080 | j1939_session_list_lock(session->priv); | 1081 | j1939_session_list_lock(priv); |
| 1082 | /* This function should be called with a session ref-count of at | ||
| 1083 | * least 2. | ||
| 1084 | */ | ||
| 1085 | WARN_ON_ONCE(kref_read(&session->kref) < 2); | ||
| 1081 | active = j1939_session_deactivate_locked(session); | 1086 | active = j1939_session_deactivate_locked(session); |
| 1082 | j1939_session_list_unlock(session->priv); | 1087 | j1939_session_list_unlock(priv); |
| 1083 | 1088 | ||
| 1084 | return active; | 1089 | return active; |
| 1085 | } | 1090 | } |
| @@ -1869,7 +1874,7 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session, · 783 unmodified lines | |||
| 1869 | if (!session->transmission) | 1874 | if (!session->transmission) |
| 1870 | j1939_tp_schedule_txtimer(session, 0); | 1875 | j1939_tp_schedule_txtimer(session, 0); |
| 1871 | } else { | 1876 | } else { |
| 1872 | j1939_tp_set_rxtimeout(session, 250); | 1877 | j1939_tp_set_rxtimeout(session, 750); |
| 1873 | } | 1878 | } |
| 1874 | session->last_cmd = 0xff; | 1879 | session->last_cmd = 0xff; |
| 1875 | consume_skb(se_skb); | 1880 | consume_skb(se_skb); |
| @@ -546,10 +546,18 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 545 unmodified lines | |||
| 546 | return -EFAULT; | 546 | return -EFAULT; |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | rtnl_lock(); | ||
| 549 | lock_sock(sk); | 550 | lock_sock(sk); |
| 550 | 551 | ||
| 551 | if (ro->bound && ro->ifindex) | 552 | if (ro->bound && ro->ifindex) { |
| 552 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); | 553 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); |
| 554 | if (!dev) { | ||
| 555 | if (count > 1) | ||
| 556 | kfree(filter); | ||
| 557 | err = -ENODEV; | ||
| 558 | goto out_fil; | ||
| 559 | } | ||
| 560 | } | ||
| 553 | 561 | ||
| 554 | if (ro->bound) { | 562 | if (ro->bound) { |
| 555 | /* (try to) register the new filters */ | 563 | /* (try to) register the new filters */ |
| @@ -588,6 +596,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 32 unmodified lines | |||
| 588 | dev_put(dev); | 596 | dev_put(dev); |
| 589 | 597 | ||
| 590 | release_sock(sk); | 598 | release_sock(sk); |
| 599 | rtnl_unlock(); | ||
| 591 | 600 | ||
| 592 | break; | 601 | break; |
| 593 | 602 | ||
| @@ -600,10 +609,16 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 6 unmodified lines | |||
| 600 | 609 | ||
| 601 | err_mask &= CAN_ERR_MASK; | 610 | err_mask &= CAN_ERR_MASK; |
| 602 | 611 | ||
| 612 | rtnl_lock(); | ||
| 603 | lock_sock(sk); | 613 | lock_sock(sk); |
| 604 | 614 | ||
| 605 | if (ro->bound && ro->ifindex) | 615 | if (ro->bound && ro->ifindex) { |
| 606 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); | 616 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); |
| 617 | if (!dev) { | ||
| 618 | err = -ENODEV; | ||
| 619 | goto out_err; | ||
| 620 | } | ||
| 621 | } | ||
| 607 | 622 | ||
| 608 | /* remove current error mask */ | 623 | /* remove current error mask */ |
| 609 | if (ro->bound) { | 624 | if (ro->bound) { |
| @@ -627,6 +642,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 17 unmodified lines | |||
| 627 | dev_put(dev); | 642 | dev_put(dev); |
| 628 | 643 | ||
| 629 | release_sock(sk); | 644 | release_sock(sk); |
| 645 | rtnl_unlock(); | ||
| 630 | 646 | ||
| 631 | break; | 647 | break; |
| 632 | 648 | ||
| @@ -131,6 +131,7 @@ · 130 unmodified lines | |||
| 131 | #include <trace/events/napi.h> | 131 | #include <trace/events/napi.h> |
| 132 | #include <trace/events/net.h> | 132 | #include <trace/events/net.h> |
| 133 | #include <trace/events/skb.h> | 133 | #include <trace/events/skb.h> |
| 134 | #include <trace/events/qdisc.h> | ||
| 134 | #include <linux/inetdevice.h> | 135 | #include <linux/inetdevice.h> |
| 135 | #include <linux/cpu_rmap.h> | 136 | #include <linux/cpu_rmap.h> |
| 136 | #include <linux/static_key.h> | 137 | #include <linux/static_key.h> |
| @@ -3844,6 +3845,18 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) · 3707 unmodified lines | |||
| 3844 | } | 3845 | } |
| 3845 | } | 3846 | } |
| 3846 | 3847 | ||
| 3848 | static int dev_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *q, | ||
| 3849 | struct sk_buff **to_free, | ||
| 3850 | struct netdev_queue *txq) | ||
| 3851 | { | ||
| 3852 | int rc; | ||
| 3853 | |||
| 3854 | rc = q->enqueue(skb, q, to_free) & NET_XMIT_MASK; | ||
| 3855 | if (rc == NET_XMIT_SUCCESS) | ||
| 3856 | trace_qdisc_enqueue(q, txq, skb); | ||
| 3857 | return rc; | ||
| 3858 | } | ||
| 3859 | |||
| 3847 | static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | 3860 | static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, |
| 3848 | struct net_device *dev, | 3861 | struct net_device *dev, |
| 3849 | struct netdev_queue *txq) | 3862 | struct netdev_queue *txq) |
| @@ -3862,8 +3875,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, · 12 unmodified lines | |||
| 3862 | * of q->seqlock to protect from racing with requeuing. | 3875 | * of q->seqlock to protect from racing with requeuing. |
| 3863 | */ | 3876 | */ |
| 3864 | if (unlikely(!nolock_qdisc_is_empty(q))) { | 3877 | if (unlikely(!nolock_qdisc_is_empty(q))) { |
| 3865 | rc = q->enqueue(skb, q, &to_free) & | 3878 | rc = dev_qdisc_enqueue(skb, q, &to_free, txq); |
| 3866 | NET_XMIT_MASK; | ||
| 3867 | __qdisc_run(q); | 3879 | __qdisc_run(q); |
| 3868 | qdisc_run_end(q); | 3880 | qdisc_run_end(q); |
| 3869 | 3881 | ||
| @@ -3879,7 +3891,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, · 9 unmodified lines | |||
| 3879 | return NET_XMIT_SUCCESS; | 3891 | return NET_XMIT_SUCCESS; |
| 3880 | } | 3892 | } |
| 3881 | 3893 | ||
| 3882 | rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK; | 3894 | rc = dev_qdisc_enqueue(skb, q, &to_free, txq); |
| 3883 | qdisc_run(q); | 3895 | qdisc_run(q); |
| 3884 | 3896 | ||
| 3885 | no_lock_out: | 3897 | no_lock_out: |
| @@ -3923,7 +3935,7 @@ no_lock_out: · 37 unmodified lines | |||
| 3923 | qdisc_run_end(q); | 3935 | qdisc_run_end(q); |
| 3924 | rc = NET_XMIT_SUCCESS; | 3936 | rc = NET_XMIT_SUCCESS; |
| 3925 | } else { | 3937 | } else { |
| 3926 | rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK; | 3938 | rc = dev_qdisc_enqueue(skb, q, &to_free, txq); |
| 3927 | if (qdisc_run_begin(q)) { | 3939 | if (qdisc_run_begin(q)) { |
| 3928 | if (unlikely(contended)) { | 3940 | if (unlikely(contended)) { |
| 3929 | spin_unlock(&q->busylock); | 3941 | spin_unlock(&q->busylock); |
| @@ -9700,14 +9712,17 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) · 5770 unmodified lines | |||
| 9700 | struct net_device *dev; | 9712 | struct net_device *dev; |
| 9701 | int err, fd; | 9713 | int err, fd; |
| 9702 | 9714 | ||
| 9715 | rtnl_lock(); | ||
| 9703 | dev = dev_get_by_index(net, attr->link_create.target_ifindex); | 9716 | dev = dev_get_by_index(net, attr->link_create.target_ifindex); |
| 9704 | if (!dev) | 9717 | if (!dev) { |
| 9718 | rtnl_unlock(); | ||
| 9705 | return -EINVAL; | 9719 | return -EINVAL; |
| 9720 | } | ||
| 9706 | 9721 | ||
| 9707 | link = kzalloc(sizeof(*link), GFP_USER); | 9722 | link = kzalloc(sizeof(*link), GFP_USER); |
| 9708 | if (!link) { | 9723 | if (!link) { |
| 9709 | err = -ENOMEM; | 9724 | err = -ENOMEM; |
| 9710 | goto out_put_dev; | 9725 | goto unlock; |
| 9711 | } | 9726 | } |
| 9712 | 9727 | ||
| 9713 | bpf_link_init(&link->link, BPF_LINK_TYPE_XDP, &bpf_xdp_link_lops, prog); | 9728 | bpf_link_init(&link->link, BPF_LINK_TYPE_XDP, &bpf_xdp_link_lops, prog); |
| @@ -9717,14 +9732,14 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) · 3 unmodified lines | |||
| 9717 | err = bpf_link_prime(&link->link, &link_primer); | 9732 | err = bpf_link_prime(&link->link, &link_primer); |
| 9718 | if (err) { | 9733 | if (err) { |
| 9719 | kfree(link); | 9734 | kfree(link); |
| 9720 | goto out_put_dev; | 9735 | goto unlock; |
| 9721 | } | 9736 | } |
| 9722 | 9737 | ||
| 9723 | rtnl_lock(); | ||
| 9724 | err = dev_xdp_attach_link(dev, NULL, link); | 9738 | err = dev_xdp_attach_link(dev, NULL, link); |
| 9725 | rtnl_unlock(); | 9739 | rtnl_unlock(); |
| 9726 | 9740 | ||
| 9727 | if (err) { | 9741 | if (err) { |
| 9742 | link->dev = NULL; | ||
| 9728 | bpf_link_cleanup(&link_primer); | 9743 | bpf_link_cleanup(&link_primer); |
| 9729 | goto out_put_dev; | 9744 | goto out_put_dev; |
| 9730 | } | 9745 | } |
| @@ -9734,6 +9749,9 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) · 3 unmodified lines | |||
| 9734 | dev_put(dev); | 9749 | dev_put(dev); |
| 9735 | return fd; | 9750 | return fd; |
| 9736 | 9751 | ||
| 9752 | unlock: | ||
| 9753 | rtnl_unlock(); | ||
| 9754 | |||
| 9737 | out_put_dev: | 9755 | out_put_dev: |
| 9738 | dev_put(dev); | 9756 | dev_put(dev); |
| 9739 | return err; | 9757 | return err; |
| @@ -9328,18 +9328,10 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, · 9327 unmodified lines | |||
| 9328 | 9328 | ||
| 9329 | switch (attrs->flavour) { | 9329 | switch (attrs->flavour) { |
| 9330 | case DEVLINK_PORT_FLAVOUR_PHYSICAL: | 9330 | case DEVLINK_PORT_FLAVOUR_PHYSICAL: |
| 9331 | case DEVLINK_PORT_FLAVOUR_VIRTUAL: | ||
| 9332 | n = snprintf(name, len, "p%u", attrs->phys.port_number); | 9331 | n = snprintf(name, len, "p%u", attrs->phys.port_number); |
| 9333 | if (n < len && attrs->split) | 9332 | if (n < len && attrs->split) |
| 9334 | n += snprintf(name + n, len - n, "s%u", | 9333 | n += snprintf(name + n, len - n, "s%u", |
| 9335 | attrs->phys.split_subport_number); | 9334 | attrs->phys.split_subport_number); |
| 9336 | if (!attrs->split) | ||
| 9337 | n = snprintf(name, len, "p%u", attrs->phys.port_number); | ||
| 9338 | else | ||
| 9339 | n = snprintf(name, len, "p%us%u", | ||
| 9340 | attrs->phys.port_number, | ||
| 9341 | attrs->phys.split_subport_number); | ||
| 9342 | |||
| 9343 | break; | 9335 | break; |
| 9344 | case DEVLINK_PORT_FLAVOUR_CPU: | 9336 | case DEVLINK_PORT_FLAVOUR_CPU: |
| 9345 | case DEVLINK_PORT_FLAVOUR_DSA: | 9337 | case DEVLINK_PORT_FLAVOUR_DSA: |
| @@ -9381,6 +9373,8 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, · 35 unmodified lines | |||
| 9381 | n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf, | 9373 | n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf, |
| 9382 | attrs->pci_sf.sf); | 9374 | attrs->pci_sf.sf); |
| 9383 | break; | 9375 | break; |
| 9376 | case DEVLINK_PORT_FLAVOUR_VIRTUAL: | ||
| 9377 | return -EOPNOTSUPP; | ||
| 9384 | } | 9378 | } |
| 9385 | 9379 | ||
| 9386 | if (n >= len) | 9380 | if (n >= len) |
| @@ -1504,7 +1504,7 @@ __be32 flow_get_u32_dst(const struct flow_keys *flow) · 1503 unmodified lines | |||
| 1504 | } | 1504 | } |
| 1505 | EXPORT_SYMBOL(flow_get_u32_dst); | 1505 | EXPORT_SYMBOL(flow_get_u32_dst); |
| 1506 | 1506 | ||
| 1507 | /* Sort the source and destination IP (and the ports if the IP are the same), | 1507 | /* Sort the source and destination IP and the ports, |
| 1508 | * to have consistent hash within the two directions | 1508 | * to have consistent hash within the two directions |
| 1509 | */ | 1509 | */ |
| 1510 | static inline void __flow_hash_consistentify(struct flow_keys *keys) | 1510 | static inline void __flow_hash_consistentify(struct flow_keys *keys) |
| @@ -1515,11 +1515,11 @@ static inline void __flow_hash_consistentify(struct flow_keys *keys) · 4 unmodified lines | |||
| 1515 | case FLOW_DISSECTOR_KEY_IPV4_ADDRS: | 1515 | case FLOW_DISSECTOR_KEY_IPV4_ADDRS: |
| 1516 | addr_diff = (__force u32)keys->addrs.v4addrs.dst - | 1516 | addr_diff = (__force u32)keys->addrs.v4addrs.dst - |
| 1517 | (__force u32)keys->addrs.v4addrs.src; | 1517 | (__force u32)keys->addrs.v4addrs.src; |
| 1518 | if ((addr_diff < 0) || | 1518 | if (addr_diff < 0) |
| 1519 | (addr_diff == 0 && | ||
| 1520 | ((__force u16)keys->ports.dst < | ||
| 1521 | (__force u16)keys->ports.src))) { | ||
| 1522 | swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst); | 1519 | swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst); |
| 1520 | |||
| 1521 | if ((__force u16)keys->ports.dst < | ||
| 1522 | (__force u16)keys->ports.src) { | ||
| 1523 | swap(keys->ports.src, keys->ports.dst); | 1523 | swap(keys->ports.src, keys->ports.dst); |
| 1524 | } | 1524 | } |
| 1525 | break; | 1525 | break; |
| @@ -1527,13 +1527,13 @@ static inline void __flow_hash_consistentify(struct flow_keys *keys) · 1 unmodified line | |||
| 1527 | addr_diff = memcmp(&keys->addrs.v6addrs.dst, | 1527 | addr_diff = memcmp(&keys->addrs.v6addrs.dst, |
| 1528 | &keys->addrs.v6addrs.src, | 1528 | &keys->addrs.v6addrs.src, |
| 1529 | sizeof(keys->addrs.v6addrs.dst)); | 1529 | sizeof(keys->addrs.v6addrs.dst)); |
| 1530 | if ((addr_diff < 0) || | 1530 | if (addr_diff < 0) { |
| 1531 | (addr_diff == 0 && | ||
| 1532 | ((__force u16)keys->ports.dst < | ||
| 1533 | (__force u16)keys->ports.src))) { | ||
| 1534 | for (i = 0; i < 4; i++) | 1531 | for (i = 0; i < 4; i++) |
| 1535 | swap(keys->addrs.v6addrs.src.s6_addr32[i], | 1532 | swap(keys->addrs.v6addrs.src.s6_addr32[i], |
| 1536 | keys->addrs.v6addrs.dst.s6_addr32[i]); | 1533 | keys->addrs.v6addrs.dst.s6_addr32[i]); |
| 1534 | } | ||
| 1535 | if ((__force u16)keys->ports.dst < | ||
| 1536 | (__force u16)keys->ports.src) { | ||
| 1537 | swap(keys->ports.src, keys->ports.dst); | 1537 | swap(keys->ports.src, keys->ports.dst); |
| 1538 | } | 1538 | } |
| 1539 | break; | 1539 | break; |
| @@ -663,7 +663,7 @@ static void skb_release_data(struct sk_buff *skb) · 662 unmodified lines | |||
| 663 | if (skb->cloned && | 663 | if (skb->cloned && |
| 664 | atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1, | 664 | atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1, |
| 665 | &shinfo->dataref)) | 665 | &shinfo->dataref)) |
| 666 | return; | 666 | goto exit; |
| 667 | 667 | ||
| 668 | skb_zcopy_clear(skb, true); | 668 | skb_zcopy_clear(skb, true); |
| 669 | 669 | ||
| @@ -674,6 +674,17 @@ static void skb_release_data(struct sk_buff *skb) · 4 unmodified lines | |||
| 674 | kfree_skb_list(shinfo->frag_list); | 674 | kfree_skb_list(shinfo->frag_list); |
| 675 | 675 | ||
| 676 | skb_free_head(skb); | 676 | skb_free_head(skb); |
| 677 | exit: | ||
| 678 | /* When we clone an SKB we copy the reycling bit. The pp_recycle | ||
| 679 | * bit is only set on the head though, so in order to avoid races | ||
| 680 | * while trying to recycle fragments on __skb_frag_unref() we need | ||
| 681 | * to make one SKB responsible for triggering the recycle path. | ||
| 682 | * So disable the recycling bit if an SKB is cloned and we have | ||
| 683 | * additional references to to the fragmented part of the SKB. | ||
| 684 | * Eventually the last SKB will have the recycling bit set and it's | ||
| 685 | * dataref set to 0, which will trigger the recycling | ||
| 686 | */ | ||
| 687 | skb->pp_recycle = 0; | ||
| 677 | } | 688 | } |
| 678 | 689 | ||
| 679 | /* | 690 | /* |
| @@ -3011,8 +3022,11 @@ skb_zerocopy_headlen(const struct sk_buff *from) · 2331 unmodified lines | |||
| 3011 | 3022 | ||
| 3012 | if (!from->head_frag || | 3023 | if (!from->head_frag || |
| 3013 | skb_headlen(from) < L1_CACHE_BYTES || | 3024 | skb_headlen(from) < L1_CACHE_BYTES || |
| 3014 | skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) | 3025 | skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) { |
| 3015 | hlen = skb_headlen(from); | 3026 | hlen = skb_headlen(from); |
| 3027 | if (!hlen) | ||
| 3028 | hlen = from->len; | ||
| 3029 | } | ||
| 3016 | 3030 | ||
| 3017 | if (skb_has_frag_list(from)) | 3031 | if (skb_has_frag_list(from)) |
| 3018 | hlen = from->len; | 3032 | hlen = from->len; |
| @@ -508,10 +508,8 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, · 507 unmodified lines | |||
| 508 | if (skb_linearize(skb)) | 508 | if (skb_linearize(skb)) |
| 509 | return -EAGAIN; | 509 | return -EAGAIN; |
| 510 | num_sge = skb_to_sgvec(skb, msg->sg.data, 0, skb->len); | 510 | num_sge = skb_to_sgvec(skb, msg->sg.data, 0, skb->len); |
| 511 | if (unlikely(num_sge < 0)) { | 511 | if (unlikely(num_sge < 0)) |
| 512 | kfree(msg); | ||
| 513 | return num_sge; | 512 | return num_sge; |
| 514 | } | ||
| 515 | 513 | ||
| 516 | copied = skb->len; | 514 | copied = skb->len; |
| 517 | msg->sg.start = 0; | 515 | msg->sg.start = 0; |
| @@ -530,6 +528,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb) · 12 unmodified lines | |||
| 530 | { | 528 | { |
| 531 | struct sock *sk = psock->sk; | 529 | struct sock *sk = psock->sk; |
| 532 | struct sk_msg *msg; | 530 | struct sk_msg *msg; |
| 531 | int err; | ||
| 533 | 532 | ||
| 534 | /* If we are receiving on the same sock skb->sk is already assigned, | 533 | /* If we are receiving on the same sock skb->sk is already assigned, |
| 535 | * skip memory accounting and owner transition seeing it already set | 534 | * skip memory accounting and owner transition seeing it already set |
| @@ -548,7 +547,10 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb) · 12 unmodified lines | |||
| 548 | * into user buffers. | 547 | * into user buffers. |
| 549 | */ | 548 | */ |
| 550 | skb_set_owner_r(skb, sk); | 549 | skb_set_owner_r(skb, sk); |
| 551 | return sk_psock_skb_ingress_enqueue(skb, psock, sk, msg); | 550 | err = sk_psock_skb_ingress_enqueue(skb, psock, sk, msg); |
| 551 | if (err < 0) | ||
| 552 | kfree(msg); | ||
| 553 | return err; | ||
| 552 | } | 554 | } |
| 553 | 555 | ||
| 554 | /* Puts an skb on the ingress queue of the socket already assigned to the | 556 | /* Puts an skb on the ingress queue of the socket already assigned to the |
| @@ -559,12 +561,16 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb · 4 unmodified lines | |||
| 559 | { | 561 | { |
| 560 | struct sk_msg *msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_ATOMIC); | 562 | struct sk_msg *msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_ATOMIC); |
| 561 | struct sock *sk = psock->sk; | 563 | struct sock *sk = psock->sk; |
| 564 | int err; | ||
| 562 | 565 | ||
| 563 | if (unlikely(!msg)) | 566 | if (unlikely(!msg)) |
| 564 | return -EAGAIN; | 567 | return -EAGAIN; |
| 565 | sk_msg_init(msg); | 568 | sk_msg_init(msg); |
| 566 | skb_set_owner_r(skb, sk); | 569 | skb_set_owner_r(skb, sk); |
| 567 | return sk_psock_skb_ingress_enqueue(skb, psock, sk, msg); | 570 | err = sk_psock_skb_ingress_enqueue(skb, psock, sk, msg); |
| 571 | if (err < 0) | ||
| 572 | kfree(msg); | ||
| 573 | return err; | ||
| 568 | } | 574 | } |
| 569 | 575 | ||
| 570 | static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb, | 576 | static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb, |
| @@ -578,29 +584,42 @@ static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb, · 7 unmodified lines | |||
| 578 | return sk_psock_skb_ingress(psock, skb); | 584 | return sk_psock_skb_ingress(psock, skb); |
| 579 | } | 585 | } |
| 580 | 586 | ||
| 581 | static void sock_drop(struct sock *sk, struct sk_buff *skb) | 587 | static void sk_psock_skb_state(struct sk_psock *psock, |
| 588 | struct sk_psock_work_state *state, | ||
| 589 | struct sk_buff *skb, | ||
| 590 | int len, int off) | ||
| 582 | { | 591 | { |
| 583 | sk_drops_add(sk, skb); | 592 | spin_lock_bh(&psock->ingress_lock); |
| 584 | kfree_skb(skb); | 593 | if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) { |
| 594 | state->skb = skb; | ||
| 595 | state->len = len; | ||
| 596 | state->off = off; | ||
| 597 | } else { | ||
| 598 | sock_drop(psock->sk, skb); | ||
| 599 | } | ||
| 600 | spin_unlock_bh(&psock->ingress_lock); | ||
| 585 | } | 601 | } |
| 586 | 602 | ||
| 587 | static void sk_psock_backlog(struct work_struct *work) | 603 | static void sk_psock_backlog(struct work_struct *work) |
| 588 | { | 604 | { |
| 589 | struct sk_psock *psock = container_of(work, struct sk_psock, work); | 605 | struct sk_psock *psock = container_of(work, struct sk_psock, work); |
| 590 | struct sk_psock_work_state *state = &psock->work_state; | 606 | struct sk_psock_work_state *state = &psock->work_state; |
| 591 | struct sk_buff *skb; | 607 | struct sk_buff *skb = NULL; |
| 592 | bool ingress; | 608 | bool ingress; |
| 593 | u32 len, off; | 609 | u32 len, off; |
| 594 | int ret; | 610 | int ret; |
| 595 | 611 | ||
| 596 | mutex_lock(&psock->work_mutex); | 612 | mutex_lock(&psock->work_mutex); |
| 597 | if (state->skb) { | 613 | if (unlikely(state->skb)) { |
| 614 | spin_lock_bh(&psock->ingress_lock); | ||
| 598 | skb = state->skb; | 615 | skb = state->skb; |
| 599 | len = state->len; | 616 | len = state->len; |
| 600 | off = state->off; | 617 | off = state->off; |
| 601 | state->skb = NULL; | 618 | state->skb = NULL; |
| 602 | goto start; | 619 | spin_unlock_bh(&psock->ingress_lock); |
| 603 | } | 620 | } |
| 621 | if (skb) | ||
| 622 | goto start; | ||
| 604 | 623 | ||
| 605 | while ((skb = skb_dequeue(&psock->ingress_skb))) { | 624 | while ((skb = skb_dequeue(&psock->ingress_skb))) { |
| 606 | len = skb->len; | 625 | len = skb->len; |
| @@ -615,9 +634,8 @@ start: · 8 unmodified lines | |||
| 615 | len, ingress); | 634 | len, ingress); |
| 616 | if (ret <= 0) { | 635 | if (ret <= 0) { |
| 617 | if (ret == -EAGAIN) { | 636 | if (ret == -EAGAIN) { |
| 618 | state->skb = skb; | 637 | sk_psock_skb_state(psock, state, skb, |
| 619 | state->len = len; | 638 | len, off); |
| 620 | state->off = off; | ||
| 621 | goto end; | 639 | goto end; |
| 622 | } | 640 | } |
| 623 | /* Hard errors break pipe and stop xmit. */ | 641 | /* Hard errors break pipe and stop xmit. */ |
| @@ -716,6 +734,11 @@ static void __sk_psock_zap_ingress(struct sk_psock *psock) · 92 unmodified lines | |||
| 716 | skb_bpf_redirect_clear(skb); | 734 | skb_bpf_redirect_clear(skb); |
| 717 | sock_drop(psock->sk, skb); | 735 | sock_drop(psock->sk, skb); |
| 718 | } | 736 | } |
| 737 | kfree_skb(psock->work_state.skb); | ||
| 738 | /* We null the skb here to ensure that calls to sk_psock_backlog | ||
| 739 | * do not pick up the free'd skb. | ||
| 740 | */ | ||
| 741 | psock->work_state.skb = NULL; | ||
| 719 | __sk_psock_purge_ingress_msg(psock); | 742 | __sk_psock_purge_ingress_msg(psock); |
| 720 | } | 743 | } |
| 721 | 744 | ||
| @@ -767,8 +790,6 @@ static void sk_psock_destroy(struct work_struct *work) · 45 unmodified lines | |||
| 767 | 790 | ||
| 768 | void sk_psock_drop(struct sock *sk, struct sk_psock *psock) | 791 | void sk_psock_drop(struct sock *sk, struct sk_psock *psock) |
| 769 | { | 792 | { |
| 770 | sk_psock_stop(psock, false); | ||
| 771 | |||
| 772 | write_lock_bh(&sk->sk_callback_lock); | 793 | write_lock_bh(&sk->sk_callback_lock); |
| 773 | sk_psock_restore_proto(sk, psock); | 794 | sk_psock_restore_proto(sk, psock); |
| 774 | rcu_assign_sk_user_data(sk, NULL); | 795 | rcu_assign_sk_user_data(sk, NULL); |
| @@ -778,6 +799,8 @@ void sk_psock_drop(struct sock *sk, struct sk_psock *psock) · 3 unmodified lines | |||
| 778 | sk_psock_stop_verdict(sk, psock); | 799 | sk_psock_stop_verdict(sk, psock); |
| 779 | write_unlock_bh(&sk->sk_callback_lock); | 800 | write_unlock_bh(&sk->sk_callback_lock); |
| 780 | 801 | ||
| 802 | sk_psock_stop(psock, false); | ||
| 803 | |||
| 781 | INIT_RCU_WORK(&psock->rwork, sk_psock_destroy); | 804 | INIT_RCU_WORK(&psock->rwork, sk_psock_destroy); |
| 782 | queue_rcu_work(system_wq, &psock->rwork); | 805 | queue_rcu_work(system_wq, &psock->rwork); |
| 783 | } | 806 | } |
| @@ -816,7 +816,7 @@ static int dn_auto_bind(struct socket *sock) · 815 unmodified lines | |||
| 816 | static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) | 816 | static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) |
| 817 | { | 817 | { |
| 818 | struct dn_scp *scp = DN_SK(sk); | 818 | struct dn_scp *scp = DN_SK(sk); |
| 819 | DEFINE_WAIT(wait); | 819 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
| 820 | int err; | 820 | int err; |
| 821 | 821 | ||
| 822 | if (scp->state != DN_CR) | 822 | if (scp->state != DN_CR) |
| @@ -826,11 +826,11 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) · 3 unmodified lines | |||
| 826 | scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk)); | 826 | scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk)); |
| 827 | dn_send_conn_conf(sk, allocation); | 827 | dn_send_conn_conf(sk, allocation); |
| 828 | 828 | ||
| 829 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 829 | add_wait_queue(sk_sleep(sk), &wait); |
| 830 | for(;;) { | 830 | for(;;) { |
| 831 | release_sock(sk); | 831 | release_sock(sk); |
| 832 | if (scp->state == DN_CC) | 832 | if (scp->state == DN_CC) |
| 833 | *timeo = schedule_timeout(*timeo); | 833 | *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo); |
| 834 | lock_sock(sk); | 834 | lock_sock(sk); |
| 835 | err = 0; | 835 | err = 0; |
| 836 | if (scp->state == DN_RUN) | 836 | if (scp->state == DN_RUN) |
| @@ -844,9 +844,8 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) · 7 unmodified lines | |||
| 844 | err = -EAGAIN; | 844 | err = -EAGAIN; |
| 845 | if (!*timeo) | 845 | if (!*timeo) |
| 846 | break; | 846 | break; |
| 847 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 848 | } | 847 | } |
| 849 | finish_wait(sk_sleep(sk), &wait); | 848 | remove_wait_queue(sk_sleep(sk), &wait); |
| 850 | if (err == 0) { | 849 | if (err == 0) { |
| 851 | sk->sk_socket->state = SS_CONNECTED; | 850 | sk->sk_socket->state = SS_CONNECTED; |
| 852 | } else if (scp->state != DN_CC) { | 851 | } else if (scp->state != DN_CC) { |
| @@ -858,7 +857,7 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) · 5 unmodified lines | |||
| 858 | static int dn_wait_run(struct sock *sk, long *timeo) | 857 | static int dn_wait_run(struct sock *sk, long *timeo) |
| 859 | { | 858 | { |
| 860 | struct dn_scp *scp = DN_SK(sk); | 859 | struct dn_scp *scp = DN_SK(sk); |
| 861 | DEFINE_WAIT(wait); | 860 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
| 862 | int err = 0; | 861 | int err = 0; |
| 863 | 862 | ||
| 864 | if (scp->state == DN_RUN) | 863 | if (scp->state == DN_RUN) |
| @@ -867,11 +866,11 @@ static int dn_wait_run(struct sock *sk, long *timeo) · 2 unmodified lines | |||
| 867 | if (!*timeo) | 866 | if (!*timeo) |
| 868 | return -EALREADY; | 867 | return -EALREADY; |
| 869 | 868 | ||
| 870 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 869 | add_wait_queue(sk_sleep(sk), &wait); |
| 871 | for(;;) { | 870 | for(;;) { |
| 872 | release_sock(sk); | 871 | release_sock(sk); |
| 873 | if (scp->state == DN_CI || scp->state == DN_CC) | 872 | if (scp->state == DN_CI || scp->state == DN_CC) |
| 874 | *timeo = schedule_timeout(*timeo); | 873 | *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo); |
| 875 | lock_sock(sk); | 874 | lock_sock(sk); |
| 876 | err = 0; | 875 | err = 0; |
| 877 | if (scp->state == DN_RUN) | 876 | if (scp->state == DN_RUN) |
| @@ -885,9 +884,8 @@ static int dn_wait_run(struct sock *sk, long *timeo) · 7 unmodified lines | |||
| 885 | err = -ETIMEDOUT; | 884 | err = -ETIMEDOUT; |
| 886 | if (!*timeo) | 885 | if (!*timeo) |
| 887 | break; | 886 | break; |
| 888 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 889 | } | 887 | } |
| 890 | finish_wait(sk_sleep(sk), &wait); | 888 | remove_wait_queue(sk_sleep(sk), &wait); |
| 891 | out: | 889 | out: |
| 892 | if (err == 0) { | 890 | if (err == 0) { |
| 893 | sk->sk_socket->state = SS_CONNECTED; | 891 | sk->sk_socket->state = SS_CONNECTED; |
| @@ -1032,16 +1030,16 @@ static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt) · 138 unmodified lines | |||
| 1032 | 1030 | ||
| 1033 | static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) | 1031 | static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) |
| 1034 | { | 1032 | { |
| 1035 | DEFINE_WAIT(wait); | 1033 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
| 1036 | struct sk_buff *skb = NULL; | 1034 | struct sk_buff *skb = NULL; |
| 1037 | int err = 0; | 1035 | int err = 0; |
| 1038 | 1036 | ||
| 1039 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 1037 | add_wait_queue(sk_sleep(sk), &wait); |
| 1040 | for(;;) { | 1038 | for(;;) { |
| 1041 | release_sock(sk); | 1039 | release_sock(sk); |
| 1042 | skb = skb_dequeue(&sk->sk_receive_queue); | 1040 | skb = skb_dequeue(&sk->sk_receive_queue); |
| 1043 | if (skb == NULL) { | 1041 | if (skb == NULL) { |
| 1044 | *timeo = schedule_timeout(*timeo); | 1042 | *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo); |
| 1045 | skb = skb_dequeue(&sk->sk_receive_queue); | 1043 | skb = skb_dequeue(&sk->sk_receive_queue); |
| 1046 | } | 1044 | } |
| 1047 | lock_sock(sk); | 1045 | lock_sock(sk); |
| @@ -1056,9 +1054,8 @@ static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) · 8 unmodified lines | |||
| 1056 | err = -EAGAIN; | 1054 | err = -EAGAIN; |
| 1057 | if (!*timeo) | 1055 | if (!*timeo) |
| 1058 | break; | 1056 | break; |
| 1059 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 1060 | } | 1057 | } |
| 1061 | finish_wait(sk_sleep(sk), &wait); | 1058 | remove_wait_queue(sk_sleep(sk), &wait); |
| 1062 | 1059 | ||
| 1063 | return skb == NULL ? ERR_PTR(err) : skb; | 1060 | return skb == NULL ? ERR_PTR(err) : skb; |
| 1064 | } | 1061 | } |
| @@ -1808,6 +1808,7 @@ void dsa_slave_setup_tagger(struct net_device *slave) · 1807 unmodified lines | |||
| 1808 | struct dsa_slave_priv *p = netdev_priv(slave); | 1808 | struct dsa_slave_priv *p = netdev_priv(slave); |
| 1809 | const struct dsa_port *cpu_dp = dp->cpu_dp; | 1809 | const struct dsa_port *cpu_dp = dp->cpu_dp; |
| 1810 | struct net_device *master = cpu_dp->master; | 1810 | struct net_device *master = cpu_dp->master; |
| 1811 | const struct dsa_switch *ds = dp->ds; | ||
| 1811 | 1812 | ||
| 1812 | slave->needed_headroom = cpu_dp->tag_ops->needed_headroom; | 1813 | slave->needed_headroom = cpu_dp->tag_ops->needed_headroom; |
| 1813 | slave->needed_tailroom = cpu_dp->tag_ops->needed_tailroom; | 1814 | slave->needed_tailroom = cpu_dp->tag_ops->needed_tailroom; |
| @@ -1819,6 +1820,14 @@ void dsa_slave_setup_tagger(struct net_device *slave) · 5 unmodified lines | |||
| 1819 | slave->needed_tailroom += master->needed_tailroom; | 1820 | slave->needed_tailroom += master->needed_tailroom; |
| 1820 | 1821 | ||
| 1821 | p->xmit = cpu_dp->tag_ops->xmit; | 1822 | p->xmit = cpu_dp->tag_ops->xmit; |
| 1823 | |||
| 1824 | slave->features = master->vlan_features | NETIF_F_HW_TC; | ||
| 1825 | if (ds->ops->port_vlan_add && ds->ops->port_vlan_del) | ||
| 1826 | slave->features |= NETIF_F_HW_VLAN_CTAG_FILTER; | ||
| 1827 | slave->hw_features |= NETIF_F_HW_TC; | ||
| 1828 | slave->features |= NETIF_F_LLTX; | ||
| 1829 | if (slave->needed_tailroom) | ||
| 1830 | slave->features &= ~(NETIF_F_SG | NETIF_F_FRAGLIST); | ||
| 1822 | } | 1831 | } |
| 1823 | 1832 | ||
| 1824 | static struct lock_class_key dsa_slave_netdev_xmit_lock_key; | 1833 | static struct lock_class_key dsa_slave_netdev_xmit_lock_key; |
| @@ -1881,11 +1890,6 @@ int dsa_slave_create(struct dsa_port *port) · 56 unmodified lines | |||
| 1881 | if (slave_dev == NULL) | 1890 | if (slave_dev == NULL) |
| 1882 | return -ENOMEM; | 1891 | return -ENOMEM; |
| 1883 | 1892 | ||
| 1884 | slave_dev->features = master->vlan_features | NETIF_F_HW_TC; | ||
| 1885 | if (ds->ops->port_vlan_add && ds->ops->port_vlan_del) | ||
| 1886 | slave_dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; | ||
| 1887 | slave_dev->hw_features |= NETIF_F_HW_TC; | ||
| 1888 | slave_dev->features |= NETIF_F_LLTX; | ||
| 1889 | slave_dev->ethtool_ops = &dsa_slave_ethtool_ops; | 1893 | slave_dev->ethtool_ops = &dsa_slave_ethtool_ops; |
| 1890 | if (!is_zero_ether_addr(port->mac)) | 1894 | if (!is_zero_ether_addr(port->mac)) |
| 1891 | ether_addr_copy(slave_dev->dev_addr, port->mac); | 1895 | ether_addr_copy(slave_dev->dev_addr, port->mac); |
| @@ -53,6 +53,9 @@ static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev) · 52 unmodified lines | |||
| 53 | u8 *tag; | 53 | u8 *tag; |
| 54 | u8 *addr; | 54 | u8 *addr; |
| 55 | 55 | ||
| 56 | if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) | ||
| 57 | return NULL; | ||
| 58 | |||
| 56 | /* Tag encoding */ | 59 | /* Tag encoding */ |
| 57 | tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); | 60 | tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); |
| 58 | addr = skb_mac_header(skb); | 61 | addr = skb_mac_header(skb); |
| @@ -114,6 +117,9 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, · 55 unmodified lines | |||
| 114 | u8 *addr; | 117 | u8 *addr; |
| 115 | u16 val; | 118 | u16 val; |
| 116 | 119 | ||
| 120 | if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) | ||
| 121 | return NULL; | ||
| 122 | |||
| 117 | /* Tag encoding */ | 123 | /* Tag encoding */ |
| 118 | tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN); | 124 | tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN); |
| 119 | addr = skb_mac_header(skb); | 125 | addr = skb_mac_header(skb); |
| @@ -164,6 +170,9 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb, · 44 unmodified lines | |||
| 164 | u8 *addr; | 170 | u8 *addr; |
| 165 | u8 *tag; | 171 | u8 *tag; |
| 166 | 172 | ||
| 173 | if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) | ||
| 174 | return NULL; | ||
| 175 | |||
| 167 | /* Tag encoding */ | 176 | /* Tag encoding */ |
| 168 | tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); | 177 | tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); |
| 169 | addr = skb_mac_header(skb); | 178 | addr = skb_mac_header(skb); |
| @@ -390,7 +390,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, · 389 unmodified lines | |||
| 390 | tunnel->i_seqno = ntohl(tpi->seq) + 1; | 390 | tunnel->i_seqno = ntohl(tpi->seq) + 1; |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | skb_reset_network_header(skb); | 393 | skb_set_network_header(skb, (tunnel->dev->type == ARPHRD_ETHER) ? ETH_HLEN : 0); |
| 394 | 394 | ||
| 395 | err = IP_ECN_decapsulate(iph, skb); | 395 | err = IP_ECN_decapsulate(iph, skb); |
| 396 | if (unlikely(err)) { | 396 | if (unlikely(err)) { |
| @@ -503,7 +503,7 @@ static int __init tcp_bpf_v4_build_proto(void) · 502 unmodified lines | |||
| 503 | tcp_bpf_rebuild_protos(tcp_bpf_prots[TCP_BPF_IPV4], &tcp_prot); | 503 | tcp_bpf_rebuild_protos(tcp_bpf_prots[TCP_BPF_IPV4], &tcp_prot); |
| 504 | return 0; | 504 | return 0; |
| 505 | } | 505 | } |
| 506 | core_initcall(tcp_bpf_v4_build_proto); | 506 | late_initcall(tcp_bpf_v4_build_proto); |
| 507 | 507 | ||
| 508 | static int tcp_bpf_assert_proto_ops(struct proto *ops) | 508 | static int tcp_bpf_assert_proto_ops(struct proto *ops) |
| 509 | { | 509 | { |
| @@ -507,8 +507,18 @@ void tcp_fastopen_active_disable(struct sock *sk) · 506 unmodified lines | |||
| 507 | { | 507 | { |
| 508 | struct net *net = sock_net(sk); | 508 | struct net *net = sock_net(sk); |
| 509 | 509 | ||
| 510 | if (!sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout) | ||
| 511 | return; | ||
| 512 | |||
| 513 | /* Paired with READ_ONCE() in tcp_fastopen_active_should_disable() */ | ||
| 514 | WRITE_ONCE(net->ipv4.tfo_active_disable_stamp, jiffies); | ||
| 515 | |||
| 516 | /* Paired with smp_rmb() in tcp_fastopen_active_should_disable(). | ||
| 517 | * We want net->ipv4.tfo_active_disable_stamp to be updated first. | ||
| 518 | */ | ||
| 519 | smp_mb__before_atomic(); | ||
| 510 | atomic_inc(&net->ipv4.tfo_active_disable_times); | 520 | atomic_inc(&net->ipv4.tfo_active_disable_times); |
| 511 | net->ipv4.tfo_active_disable_stamp = jiffies; | 521 | |
| 512 | NET_INC_STATS(net, LINUX_MIB_TCPFASTOPENBLACKHOLE); | 522 | NET_INC_STATS(net, LINUX_MIB_TCPFASTOPENBLACKHOLE); |
| 513 | } | 523 | } |
| 514 | 524 | ||
| @@ -519,17 +529,27 @@ void tcp_fastopen_active_disable(struct sock *sk) · 4 unmodified lines | |||
| 519 | bool tcp_fastopen_active_should_disable(struct sock *sk) | 529 | bool tcp_fastopen_active_should_disable(struct sock *sk) |
| 520 | { | 530 | { |
| 521 | unsigned int tfo_bh_timeout = sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout; | 531 | unsigned int tfo_bh_timeout = sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout; |
| 522 | int tfo_da_times = atomic_read(&sock_net(sk)->ipv4.tfo_active_disable_times); | ||
| 523 | unsigned long timeout; | 532 | unsigned long timeout; |
| 533 | int tfo_da_times; | ||
| 524 | int multiplier; | 534 | int multiplier; |
| 525 | 535 | ||
| 536 | if (!tfo_bh_timeout) | ||
| 537 | return false; | ||
| 538 | |||
| 539 | tfo_da_times = atomic_read(&sock_net(sk)->ipv4.tfo_active_disable_times); | ||
| 526 | if (!tfo_da_times) | 540 | if (!tfo_da_times) |
| 527 | return false; | 541 | return false; |
| 528 | 542 | ||
| 543 | /* Paired with smp_mb__before_atomic() in tcp_fastopen_active_disable() */ | ||
| 544 | smp_rmb(); | ||
| 545 | |||
| 529 | /* Limit timeout to max: 2^6 * initial timeout */ | 546 | /* Limit timeout to max: 2^6 * initial timeout */ |
| 530 | multiplier = 1 << min(tfo_da_times - 1, 6); | 547 | multiplier = 1 << min(tfo_da_times - 1, 6); |
| 531 | timeout = multiplier * tfo_bh_timeout * HZ; | 548 | |
| 532 | if (time_before(jiffies, sock_net(sk)->ipv4.tfo_active_disable_stamp + timeout)) | 549 | /* Paired with the WRITE_ONCE() in tcp_fastopen_active_disable(). */ |
| 550 | timeout = READ_ONCE(sock_net(sk)->ipv4.tfo_active_disable_stamp) + | ||
| 551 | multiplier * tfo_bh_timeout * HZ; | ||
| 552 | if (time_before(jiffies, timeout)) | ||
| 533 | return true; | 553 | return true; |
| 534 | 554 | ||
| 535 | /* Mark check bit so we can check for successful active TFO | 555 | /* Mark check bit so we can check for successful active TFO |
| @@ -2965,7 +2965,7 @@ static int __net_init tcp_sk_init(struct net *net) · 2964 unmodified lines | |||
| 2965 | net->ipv4.sysctl_tcp_comp_sack_nr = 44; | 2965 | net->ipv4.sysctl_tcp_comp_sack_nr = 44; |
| 2966 | net->ipv4.sysctl_tcp_fastopen = TFO_CLIENT_ENABLE; | 2966 | net->ipv4.sysctl_tcp_fastopen = TFO_CLIENT_ENABLE; |
| 2967 | spin_lock_init(&net->ipv4.tcp_fastopen_ctx_lock); | 2967 | spin_lock_init(&net->ipv4.tcp_fastopen_ctx_lock); |
| 2968 | net->ipv4.sysctl_tcp_fastopen_blackhole_timeout = 60 * 60; | 2968 | net->ipv4.sysctl_tcp_fastopen_blackhole_timeout = 0; |
| 2969 | atomic_set(&net->ipv4.tfo_active_disable_times, 0); | 2969 | atomic_set(&net->ipv4.tfo_active_disable_times, 0); |
| 2970 | 2970 | ||
| 2971 | /* Reno is always built in */ | 2971 | /* Reno is always built in */ |
| @@ -645,10 +645,12 @@ static struct sock *__udp4_lib_err_encap(struct net *net, · 644 unmodified lines | |||
| 645 | const struct iphdr *iph, | 645 | const struct iphdr *iph, |
| 646 | struct udphdr *uh, | 646 | struct udphdr *uh, |
| 647 | struct udp_table *udptable, | 647 | struct udp_table *udptable, |
| 648 | struct sock *sk, | ||
| 648 | struct sk_buff *skb, u32 info) | 649 | struct sk_buff *skb, u32 info) |
| 649 | { | 650 | { |
| 651 | int (*lookup)(struct sock *sk, struct sk_buff *skb); | ||
| 650 | int network_offset, transport_offset; | 652 | int network_offset, transport_offset; |
| 651 | struct sock *sk; | 653 | struct udp_sock *up; |
| 652 | 654 | ||
| 653 | network_offset = skb_network_offset(skb); | 655 | network_offset = skb_network_offset(skb); |
| 654 | transport_offset = skb_transport_offset(skb); | 656 | transport_offset = skb_transport_offset(skb); |
| @@ -659,18 +661,28 @@ static struct sock *__udp4_lib_err_encap(struct net *net, · 4 unmodified lines | |||
| 659 | /* Transport header needs to point to the UDP header */ | 661 | /* Transport header needs to point to the UDP header */ |
| 660 | skb_set_transport_header(skb, iph->ihl << 2); | 662 | skb_set_transport_header(skb, iph->ihl << 2); |
| 661 | 663 | ||
| 664 | if (sk) { | ||
| 665 | up = udp_sk(sk); | ||
| 666 | |||
| 667 | lookup = READ_ONCE(up->encap_err_lookup); | ||
| 668 | if (lookup && lookup(sk, skb)) | ||
| 669 | sk = NULL; | ||
| 670 | |||
| 671 | goto out; | ||
| 672 | } | ||
| 673 | |||
| 662 | sk = __udp4_lib_lookup(net, iph->daddr, uh->source, | 674 | sk = __udp4_lib_lookup(net, iph->daddr, uh->source, |
| 663 | iph->saddr, uh->dest, skb->dev->ifindex, 0, | 675 | iph->saddr, uh->dest, skb->dev->ifindex, 0, |
| 664 | udptable, NULL); | 676 | udptable, NULL); |
| 665 | if (sk) { | 677 | if (sk) { |
| 666 | int (*lookup)(struct sock *sk, struct sk_buff *skb); | 678 | up = udp_sk(sk); |
| 667 | struct udp_sock *up = udp_sk(sk); | ||
| 668 | 679 | ||
| 669 | lookup = READ_ONCE(up->encap_err_lookup); | 680 | lookup = READ_ONCE(up->encap_err_lookup); |
| 670 | if (!lookup || lookup(sk, skb)) | 681 | if (!lookup || lookup(sk, skb)) |
| 671 | sk = NULL; | 682 | sk = NULL; |
| 672 | } | 683 | } |
| 673 | 684 | ||
| 685 | out: | ||
| 674 | if (!sk) | 686 | if (!sk) |
| 675 | sk = ERR_PTR(__udp4_lib_err_encap_no_sk(skb, info)); | 687 | sk = ERR_PTR(__udp4_lib_err_encap_no_sk(skb, info)); |
| 676 | 688 | ||
| @@ -707,15 +719,16 @@ int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) · 30 unmodified lines | |||
| 707 | sk = __udp4_lib_lookup(net, iph->daddr, uh->dest, | 719 | sk = __udp4_lib_lookup(net, iph->daddr, uh->dest, |
| 708 | iph->saddr, uh->source, skb->dev->ifindex, | 720 | iph->saddr, uh->source, skb->dev->ifindex, |
| 709 | inet_sdif(skb), udptable, NULL); | 721 | inet_sdif(skb), udptable, NULL); |
| 722 | |||
| 710 | if (!sk || udp_sk(sk)->encap_type) { | 723 | if (!sk || udp_sk(sk)->encap_type) { |
| 711 | /* No socket for error: try tunnels before discarding */ | 724 | /* No socket for error: try tunnels before discarding */ |
| 712 | sk = ERR_PTR(-ENOENT); | ||
| 713 | if (static_branch_unlikely(&udp_encap_needed_key)) { | 725 | if (static_branch_unlikely(&udp_encap_needed_key)) { |
| 714 | sk = __udp4_lib_err_encap(net, iph, uh, udptable, skb, | 726 | sk = __udp4_lib_err_encap(net, iph, uh, udptable, sk, skb, |
| 715 | info); | 727 | info); |
| 716 | if (!sk) | 728 | if (!sk) |
| 717 | return 0; | 729 | return 0; |
| 718 | } | 730 | } else |
| 731 | sk = ERR_PTR(-ENOENT); | ||
| 719 | 732 | ||
| 720 | if (IS_ERR(sk)) { | 733 | if (IS_ERR(sk)) { |
| 721 | __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); | 734 | __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); |
| @@ -134,7 +134,7 @@ static int __init udp_bpf_v4_build_proto(void) · 133 unmodified lines | |||
| 134 | udp_bpf_rebuild_protos(&udp_bpf_prots[UDP_BPF_IPV4], &udp_prot); | 134 | udp_bpf_rebuild_protos(&udp_bpf_prots[UDP_BPF_IPV4], &udp_prot); |
| 135 | return 0; | 135 | return 0; |
| 136 | } | 136 | } |
| 137 | core_initcall(udp_bpf_v4_build_proto); | 137 | late_initcall(udp_bpf_v4_build_proto); |
| 138 | 138 | ||
| 139 | int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) | 139 | int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) |
| 140 | { | 140 | { |
| @@ -74,7 +74,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * · 73 unmodified lines | |||
| 74 | 74 | ||
| 75 | if (likely(nskb)) { | 75 | if (likely(nskb)) { |
| 76 | if (skb->sk) | 76 | if (skb->sk) |
| 77 | skb_set_owner_w(skb, skb->sk); | 77 | skb_set_owner_w(nskb, skb->sk); |
| 78 | consume_skb(skb); | 78 | consume_skb(skb); |
| 79 | } else { | 79 | } else { |
| 80 | kfree_skb(skb); | 80 | kfree_skb(skb); |
| @@ -549,9 +549,10 @@ int ip6_forward(struct sk_buff *skb) · 468 unmodified lines | |||
| 549 | if (net->ipv6.devconf_all->proxy_ndp && | 549 | if (net->ipv6.devconf_all->proxy_ndp && |
| 550 | pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) { | 550 | pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) { |
| 551 | int proxied = ip6_forward_proxy_check(skb); | 551 | int proxied = ip6_forward_proxy_check(skb); |
| 552 | if (proxied > 0) | 552 | if (proxied > 0) { |
| 553 | hdr->hop_limit--; | ||
| 553 | return ip6_input(skb); | 554 | return ip6_input(skb); |
| 554 | else if (proxied < 0) { | 555 | } else if (proxied < 0) { |
| 555 | __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS); | 556 | __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS); |
| 556 | goto drop; | 557 | goto drop; |
| 557 | } | 558 | } |
| @@ -3769,7 +3769,7 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg, · 3768 unmodified lines | |||
| 3769 | err = PTR_ERR(rt->fib6_metrics); | 3769 | err = PTR_ERR(rt->fib6_metrics); |
| 3770 | /* Do not leave garbage there. */ | 3770 | /* Do not leave garbage there. */ |
| 3771 | rt->fib6_metrics = (struct dst_metrics *)&dst_default_metrics; | 3771 | rt->fib6_metrics = (struct dst_metrics *)&dst_default_metrics; |
| 3772 | goto out; | 3772 | goto out_free; |
| 3773 | } | 3773 | } |
| 3774 | 3774 | ||
| 3775 | if (cfg->fc_flags & RTF_ADDRCONF) | 3775 | if (cfg->fc_flags & RTF_ADDRCONF) |
| @@ -502,12 +502,14 @@ static struct sock *__udp6_lib_err_encap(struct net *net, · 501 unmodified lines | |||
| 502 | const struct ipv6hdr *hdr, int offset, | 502 | const struct ipv6hdr *hdr, int offset, |
| 503 | struct udphdr *uh, | 503 | struct udphdr *uh, |
| 504 | struct udp_table *udptable, | 504 | struct udp_table *udptable, |
| 505 | struct sock *sk, | ||
| 505 | struct sk_buff *skb, | 506 | struct sk_buff *skb, |
| 506 | struct inet6_skb_parm *opt, | 507 | struct inet6_skb_parm *opt, |
| 507 | u8 type, u8 code, __be32 info) | 508 | u8 type, u8 code, __be32 info) |
| 508 | { | 509 | { |
| 510 | int (*lookup)(struct sock *sk, struct sk_buff *skb); | ||
| 509 | int network_offset, transport_offset; | 511 | int network_offset, transport_offset; |
| 510 | struct sock *sk; | 512 | struct udp_sock *up; |
| 511 | 513 | ||
| 512 | network_offset = skb_network_offset(skb); | 514 | network_offset = skb_network_offset(skb); |
| 513 | transport_offset = skb_transport_offset(skb); | 515 | transport_offset = skb_transport_offset(skb); |
| @@ -518,18 +520,28 @@ static struct sock *__udp6_lib_err_encap(struct net *net, · 4 unmodified lines | |||
| 518 | /* Transport header needs to point to the UDP header */ | 520 | /* Transport header needs to point to the UDP header */ |
| 519 | skb_set_transport_header(skb, offset); | 521 | skb_set_transport_header(skb, offset); |
| 520 | 522 | ||
| 523 | if (sk) { | ||
| 524 | up = udp_sk(sk); | ||
| 525 | |||
| 526 | lookup = READ_ONCE(up->encap_err_lookup); | ||
| 527 | if (lookup && lookup(sk, skb)) | ||
| 528 | sk = NULL; | ||
| 529 | |||
| 530 | goto out; | ||
| 531 | } | ||
| 532 | |||
| 521 | sk = __udp6_lib_lookup(net, &hdr->daddr, uh->source, | 533 | sk = __udp6_lib_lookup(net, &hdr->daddr, uh->source, |
| 522 | &hdr->saddr, uh->dest, | 534 | &hdr->saddr, uh->dest, |
| 523 | inet6_iif(skb), 0, udptable, skb); | 535 | inet6_iif(skb), 0, udptable, skb); |
| 524 | if (sk) { | 536 | if (sk) { |
| 525 | int (*lookup)(struct sock *sk, struct sk_buff *skb); | 537 | up = udp_sk(sk); |
| 526 | struct udp_sock *up = udp_sk(sk); | ||
| 527 | 538 | ||
| 528 | lookup = READ_ONCE(up->encap_err_lookup); | 539 | lookup = READ_ONCE(up->encap_err_lookup); |
| 529 | if (!lookup || lookup(sk, skb)) | 540 | if (!lookup || lookup(sk, skb)) |
| 530 | sk = NULL; | 541 | sk = NULL; |
| 531 | } | 542 | } |
| 532 | 543 | ||
| 544 | out: | ||
| 533 | if (!sk) { | 545 | if (!sk) { |
| 534 | sk = ERR_PTR(__udp6_lib_err_encap_no_sk(skb, opt, type, code, | 546 | sk = ERR_PTR(__udp6_lib_err_encap_no_sk(skb, opt, type, code, |
| 535 | offset, info)); | 547 | offset, info)); |
| @@ -558,16 +570,17 @@ int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, · 22 unmodified lines | |||
| 558 | 570 | ||
| 559 | sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, | 571 | sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, |
| 560 | inet6_iif(skb), inet6_sdif(skb), udptable, NULL); | 572 | inet6_iif(skb), inet6_sdif(skb), udptable, NULL); |
| 573 | |||
| 561 | if (!sk || udp_sk(sk)->encap_type) { | 574 | if (!sk || udp_sk(sk)->encap_type) { |
| 562 | /* No socket for error: try tunnels before discarding */ | 575 | /* No socket for error: try tunnels before discarding */ |
| 563 | sk = ERR_PTR(-ENOENT); | ||
| 564 | if (static_branch_unlikely(&udpv6_encap_needed_key)) { | 576 | if (static_branch_unlikely(&udpv6_encap_needed_key)) { |
| 565 | sk = __udp6_lib_err_encap(net, hdr, offset, uh, | 577 | sk = __udp6_lib_err_encap(net, hdr, offset, uh, |
| 566 | udptable, skb, | 578 | udptable, sk, skb, |
| 567 | opt, type, code, info); | 579 | opt, type, code, info); |
| 568 | if (!sk) | 580 | if (!sk) |
| 569 | return 0; | 581 | return 0; |
| 570 | } | 582 | } else |
| 583 | sk = ERR_PTR(-ENOENT); | ||
| 571 | 584 | ||
| 572 | if (IS_ERR(sk)) { | 585 | if (IS_ERR(sk)) { |
| 573 | __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), | 586 | __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), |
| @@ -98,8 +98,16 @@ static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr) · 97 unmodified lines | |||
| 98 | { | 98 | { |
| 99 | u8 rc = LLC_PDU_LEN_U; | 99 | u8 rc = LLC_PDU_LEN_U; |
| 100 | 100 | ||
| 101 | if (addr->sllc_test || addr->sllc_xid) | 101 | if (addr->sllc_test) |
| 102 | rc = LLC_PDU_LEN_U; | 102 | rc = LLC_PDU_LEN_U; |
| 103 | else if (addr->sllc_xid) | ||
| 104 | /* We need to expand header to sizeof(struct llc_xid_info) | ||
| 105 | * since llc_pdu_init_as_xid_cmd() sets 4,5,6 bytes of LLC header | ||
| 106 | * as XID PDU. In llc_ui_sendmsg() we reserved header size and then | ||
| 107 | * filled all other space with user data. If we won't reserve this | ||
| 108 | * bytes, llc_pdu_init_as_xid_cmd() will overwrite user data | ||
| 109 | */ | ||
| 110 | rc = LLC_PDU_LEN_U_XID; | ||
| 103 | else if (sk->sk_type == SOCK_STREAM) | 111 | else if (sk->sk_type == SOCK_STREAM) |
2 more lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 233 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 297 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.