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 | 46 | 1. User addresses not accessed by the kernel but used for address space |
| 47 | 47 | management (e.g. ``mprotect()``, ``madvise()``). The use of valid |
| 48 | − tagged pointers in this context is allowed with the exception of | |
| 49 | − ``brk()``, ``mmap()`` and the ``new_address`` argument to | |
| 50 | − ``mremap()`` as these have the potential to alias with existing | |
| 51 | − user addresses. | |
| 52 | − | |
| 53 | − NOTE: This behaviour changed in v5.6 and so some earlier kernels may | |
| 54 | − incorrectly accept valid tagged pointers for the ``brk()``, | |
| 55 | − ``mmap()`` and ``mremap()`` system calls. | |
| 48 | + tagged pointers in this context is allowed with these exceptions: | |
| 49 | + | |
| 50 | + - ``brk()``, ``mmap()`` and the ``new_address`` argument to | |
| 51 | + ``mremap()`` as these have the potential to alias with existing | |
| 52 | + user addresses. | |
| 53 | + | |
| 54 | + NOTE: This behaviour changed in v5.6 and so some earlier kernels may | |
| 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 | 67 | 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI |
| 58 | 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 | 28 | - snps,dwmac-4.00 |
| 29 | 29 | - snps,dwmac-4.10a |
| 30 | 30 | - snps,dwmac-4.20a |
| 31 | + - snps,dwmac-5.10a | |
| 31 | 32 | - snps,dwxgmac |
| 32 | 33 | - snps,dwxgmac-2.10 |
| 33 | 34 | |
| @@ -82,6 +83,7 @@ properties: · 48 unmodified lines | ||
| 82 | 83 | - snps,dwmac-4.00 |
| 83 | 84 | - snps,dwmac-4.10a |
| 84 | 85 | - snps,dwmac-4.20a |
| 86 | + - snps,dwmac-5.10a | |
| 85 | 87 | - snps,dwxgmac |
| 86 | 88 | - snps,dwxgmac-2.10 |
| 87 | 89 | |
| @@ -375,6 +377,7 @@ allOf: · 287 unmodified lines | ||
| 375 | 377 | - snps,dwmac-4.00 |
| 376 | 378 | - snps,dwmac-4.10a |
| 377 | 379 | - snps,dwmac-4.20a |
| 380 | + - snps,dwmac-5.10a | |
| 378 | 381 | - snps,dwxgmac |
| 379 | 382 | - snps,dwxgmac-2.10 |
| 380 | 383 | - st,spear600-gmac |
| @@ -57,12 +57,14 @@ properties: · 56 unmodified lines | ||
| 57 | 57 | maxItems: 1 |
| 58 | 58 | |
| 59 | 59 | power-domains: |
| 60 | + deprecated: true | |
| 60 | 61 | description: |
| 61 | 62 | Power domain to use for enable control. This binding is only |
| 62 | 63 | available if the compatible is chosen to regulator-fixed-domain. |
| 63 | 64 | maxItems: 1 |
| 64 | 65 | |
| 65 | 66 | required-opps: |
| 67 | + deprecated: true | |
| 66 | 68 | description: |
| 67 | 69 | Performance state to use for enable control. This binding is only |
| 68 | 70 | available if the compatible is chosen to regulator-fixed-domain. The |
| @@ -114,7 +114,7 @@ properties: · 113 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | ports: |
| 116 | 116 | $ref: /schemas/graph.yaml#/properties/ports |
| 117 | − properties: | |
| 117 | + patternProperties: | |
| 118 | 118 | port(@[0-9a-f]+)?: |
| 119 | 119 | $ref: audio-graph-port.yaml# |
| 120 | 120 | unevaluatedProperties: false |
| @@ -243,8 +243,8 @@ Configuration Flags and Socket Options · 242 unmodified lines | ||
| 243 | 243 | These are the various configuration flags that can be used to control |
| 244 | 244 | and monitor the behavior of AF_XDP sockets. |
| 245 | 245 | |
| 246 | −XDP_COPY and XDP_ZERO_COPY bind flags | |
| 247 | −------------------------------------- | |
| 246 | +XDP_COPY and XDP_ZEROCOPY bind flags | |
| 247 | +------------------------------------ | |
| 248 | 248 | |
| 249 | 249 | When you bind to a socket, the kernel will first try to use zero-copy |
| 250 | 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 | 252 | like to force a certain mode, you can use the following flags. If you |
| 253 | 253 | pass the XDP_COPY flag to the bind call, the kernel will force the |
| 254 | 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 | 256 | socket into zero-copy mode or fail. |
| 257 | 257 | |
| 258 | 258 | XDP_SHARED_UMEM bind flag |
| @@ -826,7 +826,7 @@ tcp_fastopen_blackhole_timeout_sec - INTEGER · 825 unmodified lines | ||
| 826 | 826 | initial value when the blackhole issue goes away. |
| 827 | 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 | 831 | tcp_fastopen_key - list of comma separated 32-digit hexadecimal INTEGERs |
| 832 | 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 | 191 | with the event, in nanoseconds. May be |
| 192 | 192 | modified by .usecs to have timestamps |
| 193 | 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 | 197 | Extended error information |
| @@ -445,7 +445,7 @@ F: drivers/platform/x86/wmi.c · 444 unmodified lines | ||
| 445 | 445 | F: include/uapi/linux/wmi.h |
| 446 | 446 | |
| 447 | 447 | ACRN HYPERVISOR SERVICE MODULE |
| 448 | −M: Shuo Liu <shuo.a.liu@intel.com> | |
| 448 | +M: Fei Li <fei1.li@intel.com> | |
| 449 | 449 | L: acrn-dev@lists.projectacrn.org (subscribers-only) |
| 450 | 450 | S: Supported |
| 451 | 451 | W: https://projectacrn.org |
| @@ -7858,9 +7858,9 @@ S: Maintained · 7406 unmodified lines | ||
| 7858 | 7858 | F: drivers/input/touchscreen/goodix.c |
| 7859 | 7859 | |
| 7860 | 7860 | GOOGLE ETHERNET DRIVERS |
| 7861 | −M: Catherine Sullivan <csully@google.com> | |
| 7862 | −R: Sagi Shahar <sagis@google.com> | |
| 7863 | −R: Jon Olson <jonolson@google.com> | |
| 7861 | +M: Jeroen de Borst <jeroendb@google.com> | |
| 7862 | +R: Catherine Sullivan <csully@google.com> | |
| 7863 | +R: David Awogbemila <awogbemila@google.com> | |
| 7864 | 7864 | L: netdev@vger.kernel.org |
| 7865 | 7865 | S: Supported |
| 7866 | 7866 | F: Documentation/networking/device_drivers/ethernet/google/gve.rst |
| @@ -11327,6 +11327,12 @@ W: https://linuxtv.org · 3460 unmodified lines | ||
| 11327 | 11327 | T: git git://linuxtv.org/media_tree.git |
| 11328 | 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 | 11336 | MCAN MMIO DEVICE DRIVER |
| 11331 | 11337 | M: Chandrasekar Ramakrishnan <rcsekar@samsung.com> |
| 11332 | 11338 | L: linux-can@vger.kernel.org |
| @@ -11758,6 +11764,7 @@ F: drivers/char/hw_random/mtk-rng.c · 425 unmodified lines | ||
| 11758 | 11764 | MEDIATEK SWITCH DRIVER |
| 11759 | 11765 | M: Sean Wang <sean.wang@mediatek.com> |
| 11760 | 11766 | M: Landen Chao <Landen.Chao@mediatek.com> |
| 11767 | +M: DENG Qingfang <dqfext@gmail.com> | |
| 11761 | 11768 | L: netdev@vger.kernel.org |
| 11762 | 11769 | S: Maintained |
| 11763 | 11770 | F: drivers/net/dsa/mt7530.* |
| @@ -15467,6 +15474,8 @@ M: Pan, Xinhui <Xinhui.Pan@amd.com> · 3703 unmodified lines | ||
| 15467 | 15474 | L: amd-gfx@lists.freedesktop.org |
| 15468 | 15475 | S: Supported |
| 15469 | 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 | 15479 | F: drivers/gpu/drm/amd/ |
| 15471 | 15480 | F: drivers/gpu/drm/radeon/ |
| 15472 | 15481 | F: include/uapi/drm/amdgpu_drm.h |
| @@ -19122,7 +19131,7 @@ M: Mauro Carvalho Chehab <mchehab@kernel.org> · 3649 unmodified lines | ||
| 19122 | 19131 | L: linux-usb@vger.kernel.org |
| 19123 | 19132 | S: Maintained |
| 19124 | 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 | 19136 | USB ISP116X DRIVER |
| 19128 | 19137 | M: Olav Kongas <ok@artecdesign.ee> |
| @@ -19800,6 +19809,14 @@ L: netdev@vger.kernel.org · 671 unmodified lines | ||
| 19800 | 19809 | S: Supported |
| 19801 | 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 | 19820 | VMWARE VMMOUSE SUBDRIVER |
| 19804 | 19821 | M: "VMware Graphics" <linux-graphics-maintainer@vmware.com> |
| 19805 | 19822 | M: "VMware, Inc." <pv-drivers@vmware.com> |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 14 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc2 | |
| 5 | +EXTRAVERSION = -rc4 | |
| 6 | 6 | NAME = Opossums on Parade |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -14,7 +14,6 @@ config ALPHA · 13 unmodified lines | ||
| 14 | 14 | select PCI_SYSCALL if PCI |
| 15 | 15 | select HAVE_AOUT |
| 16 | 16 | select HAVE_ASM_MODVERSIONS |
| 17 | − select HAVE_IDE | |
| 18 | 17 | select HAVE_PCSPKR_PLATFORM |
| 19 | 18 | select HAVE_PERF_EVENTS |
| 20 | 19 | select NEED_DMA_MAP_STATE |
| @@ -532,7 +531,7 @@ config SMP · 511 unmodified lines | ||
| 532 | 531 | will run faster if you say N here. |
| 533 | 532 | |
| 534 | 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 | 536 | If you don't know what to do here, say N. |
| 538 | 537 | |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include "ksize.h" |
| 24 | 24 | |
| 25 | 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 | 27 | unsigned long *vptb); |
| 28 | 28 | |
| 29 | 29 | extern void move_stack(unsigned long new_stack); |
| @@ -200,7 +200,7 @@ extern char _end; · 199 unmodified lines | ||
| 200 | 200 | START_ADDR KSEG address of the entry point of kernel code. |
| 201 | 201 | |
| 202 | 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 | 204 | to hold the parameter list and possible |
| 205 | 205 | INTRD information. |
| 206 | 206 | |
| @@ -30,7 +30,7 @@ extern long srm_printk(const char *, ...) · 29 unmodified lines | ||
| 30 | 30 | __attribute__ ((format (printf, 1, 2))); |
| 31 | 31 | |
| 32 | 32 | /* |
| 33 | − * gzip delarations | |
| 33 | + * gzip declarations | |
| 34 | 34 | */ |
| 35 | 35 | #define OF(args) args |
| 36 | 36 | #define STATIC static |
| @@ -70,3 +70,4 @@ CONFIG_DEBUG_INFO=y · 69 unmodified lines | ||
| 70 | 70 | CONFIG_ALPHA_LEGACY_START_ADDRESS=y |
| 71 | 71 | CONFIG_MATHEMU=y |
| 72 | 72 | CONFIG_CRYPTO_HMAC=y |
| 73 | +CONFIG_DEVTMPFS=y | |
| @@ -4,15 +4,4 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 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 | 7 | #endif /* __ALPHA_COMPILER_H */ |
| @@ -9,4 +9,10 @@ static inline int syscall_get_arch(struct task_struct *task) · 8 unmodified lines | ||
| 9 | 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 | 18 | #endif /* _ASM_ALPHA_SYSCALL_H */ |
| @@ -834,7 +834,7 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer, · 833 unmodified lines | ||
| 834 | 834 | return -EFAULT; |
| 835 | 835 | state = ¤t_thread_info()->ieee_state; |
| 836 | 836 | |
| 837 | − /* Update softare trap enable bits. */ | |
| 837 | + /* Update software trap enable bits. */ | |
| 838 | 838 | *state = (*state & ~IEEE_SW_MASK) | (swcr & IEEE_SW_MASK); |
| 839 | 839 | |
| 840 | 840 | /* Update the real fpcr. */ |
| @@ -854,7 +854,7 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer, · 13 unmodified lines | ||
| 854 | 854 | state = ¤t_thread_info()->ieee_state; |
| 855 | 855 | exc &= IEEE_STATUS_MASK; |
| 856 | 856 | |
| 857 | − /* Update softare trap enable bits. */ | |
| 857 | + /* Update software trap enable bits. */ | |
| 858 | 858 | swcr = (*state & IEEE_SW_MASK) | exc; |
| 859 | 859 | *state |= exc; |
| 860 | 860 | |
| @@ -574,7 +574,7 @@ static void alpha_pmu_start(struct perf_event *event, int flags) · 573 unmodified lines | ||
| 574 | 574 | * Check that CPU performance counters are supported. |
| 575 | 575 | * - currently support EV67 and later CPUs. |
| 576 | 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 | 578 | * Bad luck to the very few people who might have one, I guess. |
| 579 | 579 | */ |
| 580 | 580 | static int supported_cpu(void) |
| @@ -256,7 +256,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, · 255 unmodified lines | ||
| 256 | 256 | childstack->r26 = (unsigned long) ret_from_kernel_thread; |
| 257 | 257 | childstack->r9 = usp; /* function */ |
| 258 | 258 | childstack->r10 = kthread_arg; |
| 259 | − childregs->hae = alpha_mv.hae_cache, | |
| 259 | + childregs->hae = alpha_mv.hae_cache; | |
| 260 | 260 | childti->pcb.usp = 0; |
| 261 | 261 | return 0; |
| 262 | 262 | } |
| @@ -319,18 +319,19 @@ setup_memory(void *kernel_end) · 318 unmodified lines | ||
| 319 | 319 | i, cluster->usage, cluster->start_pfn, |
| 320 | 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 | 322 | end = cluster->start_pfn + cluster->numpages; |
| 329 | 323 | if (end > max_low_pfn) |
| 330 | 324 | max_low_pfn = end; |
| 331 | 325 | |
| 332 | 326 | memblock_add(PFN_PHYS(cluster->start_pfn), |
| 333 | 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 | 582 | smp_send_stop(void) |
| 583 | 583 | { |
| 584 | 584 | cpumask_t to_whom; |
| 585 | − cpumask_copy(&to_whom, cpu_possible_mask); | |
| 585 | + cpumask_copy(&to_whom, cpu_online_mask); | |
| 586 | 586 | cpumask_clear_cpu(smp_processor_id(), &to_whom); |
| 587 | 587 | #ifdef DEBUG_IPI_MSG |
| 588 | 588 | if (hard_smp_processor_id() != boot_cpu_id) |
| @@ -212,7 +212,7 @@ nautilus_init_pci(void) · 211 unmodified lines | ||
| 212 | 212 | |
| 213 | 213 | /* Use default IO. */ |
| 214 | 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 | 216 | setting it up. */ |
| 217 | 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 | 730 | long error; |
| 731 | 731 | |
| 732 | 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 | 735 | if (!(current_thread_info()->status & TS_UAC_NOPRINT)) { |
| 736 | 736 | if (__ratelimit(&ratelimit)) { |
| @@ -65,7 +65,7 @@ static long (*save_emul) (unsigned long pc); · 64 unmodified lines | ||
| 65 | 65 | long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long); |
| 66 | 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 | 70 | save_emul_imprecise = alpha_fp_emul_imprecise; |
| 71 | 71 | save_emul = alpha_fp_emul; |
| @@ -73,12 +73,14 @@ int init_module(void) · 1 unmodified line | ||
| 73 | 73 | alpha_fp_emul = do_alpha_fp_emul; |
| 74 | 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 | 80 | alpha_fp_emul_imprecise = save_emul_imprecise; |
| 80 | 81 | alpha_fp_emul = save_emul; |
| 81 | 82 | } |
| 83 | +module_exit(alpha_fp_emul_cleanup_module); | |
| 82 | 84 | |
| 83 | 85 | #undef alpha_fp_emul_imprecise |
| 84 | 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 | 403 | egress: |
| 402 | 404 | return si_code; |
| 403 | 405 | } |
| 406 | + | |
| 407 | +EXPORT_SYMBOL(__udiv_qrnnd); | |
| @@ -95,7 +95,6 @@ config ARM · 94 unmodified lines | ||
| 95 | 95 | select HAVE_FUNCTION_TRACER if !XIP_KERNEL |
| 96 | 96 | select HAVE_GCC_PLUGINS |
| 97 | 97 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) |
| 98 | − select HAVE_IDE if PCI || ISA || PCMCIA | |
| 99 | 98 | select HAVE_IRQ_TIME_ACCOUNTING |
| 100 | 99 | select HAVE_KERNEL_GZIP |
| 101 | 100 | select HAVE_KERNEL_LZ4 |
| @@ -361,7 +360,6 @@ config ARCH_FOOTBRIDGE · 259 unmodified lines | ||
| 361 | 360 | bool "FootBridge" |
| 362 | 361 | select CPU_SA110 |
| 363 | 362 | select FOOTBRIDGE |
| 364 | − select HAVE_IDE | |
| 365 | 363 | select NEED_MACH_IO_H if !MMU |
| 366 | 364 | select NEED_MACH_MEMORY_H |
| 367 | 365 | help |
| @@ -430,7 +428,6 @@ config ARCH_PXA · 62 unmodified lines | ||
| 430 | 428 | select GENERIC_IRQ_MULTI_HANDLER |
| 431 | 429 | select GPIO_PXA |
| 432 | 430 | select GPIOLIB |
| 433 | − select HAVE_IDE | |
| 434 | 431 | select IRQ_DOMAIN |
| 435 | 432 | select PLAT_PXA |
| 436 | 433 | select SPARSE_IRQ |
| @@ -446,7 +443,6 @@ config ARCH_RPC · 9 unmodified lines | ||
| 446 | 443 | select ARM_HAS_SG_CHAIN |
| 447 | 444 | select CPU_SA110 |
| 448 | 445 | select FIQ |
| 449 | − select HAVE_IDE | |
| 450 | 446 | select HAVE_PATA_PLATFORM |
| 451 | 447 | select ISA_DMA_API |
| 452 | 448 | select LEGACY_TIMER_TICK |
| @@ -469,7 +465,6 @@ config ARCH_SA1100 · 16 unmodified lines | ||
| 469 | 465 | select CPU_SA1100 |
| 470 | 466 | select GENERIC_IRQ_MULTI_HANDLER |
| 471 | 467 | select GPIOLIB |
| 472 | − select HAVE_IDE | |
| 473 | 468 | select IRQ_DOMAIN |
| 474 | 469 | select ISA |
| 475 | 470 | select NEED_MACH_MEMORY_H |
| @@ -505,7 +500,6 @@ config ARCH_OMAP1 · 29 unmodified lines | ||
| 505 | 500 | select GENERIC_IRQ_CHIP |
| 506 | 501 | select GENERIC_IRQ_MULTI_HANDLER |
| 507 | 502 | select GPIOLIB |
| 508 | − select HAVE_IDE | |
| 509 | 503 | select HAVE_LEGACY_CLK |
| 510 | 504 | select IRQ_DOMAIN |
| 511 | 505 | select NEED_MACH_IO_H if PCCARD |
| @@ -9,7 +9,6 @@ menuconfig ARCH_DAVINCI · 8 unmodified lines | ||
| 9 | 9 | select PM_GENERIC_DOMAINS_OF if PM && OF |
| 10 | 10 | select REGMAP_MMIO |
| 11 | 11 | select RESET_CONTROLLER |
| 12 | − select HAVE_IDE | |
| 13 | 12 | select PINCTRL_SINGLE |
| 14 | 13 | |
| 15 | 14 | if ARCH_DAVINCI |
| @@ -49,6 +49,7 @@ static int __init parse_tag_acorn(const struct tag *tag) · 48 unmodified lines | ||
| 49 | 49 | fallthrough; /* ??? */ |
| 50 | 50 | case 256: |
| 51 | 51 | vram_size += PAGE_SIZE * 256; |
| 52 | + break; | |
| 52 | 53 | default: |
| 53 | 54 | break; |
| 54 | 55 | } |
| @@ -1602,6 +1602,9 @@ exit: · 1601 unmodified lines | ||
| 1602 | 1602 | rn = arm_bpf_get_reg32(src_lo, tmp2[1], ctx); |
| 1603 | 1603 | emit_ldx_r(dst, rn, off, ctx, BPF_SIZE(code)); |
| 1604 | 1604 | break; |
| 1605 | + /* speculation barrier */ | |
| 1606 | + case BPF_ST | BPF_NOSPEC: | |
| 1607 | + break; | |
| 1605 | 1608 | /* ST: *(size *)(dst + off) = imm */ |
| 1606 | 1609 | case BPF_ST | BPF_MEM | BPF_W: |
| 1607 | 1610 | case BPF_ST | BPF_MEM | BPF_H: |
| @@ -579,7 +579,7 @@ · 578 unmodified lines | ||
| 579 | 579 | }; |
| 580 | 580 | |
| 581 | 581 | flexcan1: can@308c0000 { |
| 582 | − compatible = "fsl,imx8mp-flexcan", "fsl,imx6q-flexcan"; | |
| 582 | + compatible = "fsl,imx8mp-flexcan"; | |
| 583 | 583 | reg = <0x308c0000 0x10000>; |
| 584 | 584 | interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; |
| 585 | 585 | clocks = <&clk IMX8MP_CLK_IPG_ROOT>, |
| @@ -594,7 +594,7 @@ · 8 unmodified lines | ||
| 594 | 594 | }; |
| 595 | 595 | |
| 596 | 596 | flexcan2: can@308d0000 { |
| 597 | − compatible = "fsl,imx8mp-flexcan", "fsl,imx6q-flexcan"; | |
| 597 | + compatible = "fsl,imx8mp-flexcan"; | |
| 598 | 598 | reg = <0x308d0000 0x10000>; |
| 599 | 599 | interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; |
| 600 | 600 | clocks = <&clk IMX8MP_CLK_IPG_ROOT>, |
| @@ -821,9 +821,9 @@ · 220 unmodified lines | ||
| 821 | 821 | eqos: ethernet@30bf0000 { |
| 822 | 822 | compatible = "nxp,imx8mp-dwmac-eqos", "snps,dwmac-5.10a"; |
| 823 | 823 | reg = <0x30bf0000 0x10000>; |
| 824 | − interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, | |
| 825 | − <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; | |
| 826 | − interrupt-names = "eth_wake_irq", "macirq"; | |
| 824 | + interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, | |
| 825 | + <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; | |
| 826 | + interrupt-names = "macirq", "eth_wake_irq"; | |
| 827 | 827 | clocks = <&clk IMX8MP_CLK_ENET_QOS_ROOT>, |
| 828 | 828 | <&clk IMX8MP_CLK_QOS_ENET_ROOT>, |
| 829 | 829 | <&clk IMX8MP_CLK_ENET_QOS_TIMER>, |
| @@ -1063,7 +1063,7 @@ · 1062 unmodified lines | ||
| 1063 | 1063 | status = "okay"; |
| 1064 | 1064 | extcon = <&usb2_id>; |
| 1065 | 1065 | |
| 1066 | − usb@7600000 { | |
| 1066 | + dwc3@7600000 { | |
| 1067 | 1067 | extcon = <&usb2_id>; |
| 1068 | 1068 | dr_mode = "otg"; |
| 1069 | 1069 | maximum-speed = "high-speed"; |
| @@ -1074,7 +1074,7 @@ · 4 unmodified lines | ||
| 1074 | 1074 | status = "okay"; |
| 1075 | 1075 | extcon = <&usb3_id>; |
| 1076 | 1076 | |
| 1077 | − usb@6a00000 { | |
| 1077 | + dwc3@6a00000 { | |
| 1078 | 1078 | extcon = <&usb3_id>; |
| 1079 | 1079 | dr_mode = "otg"; |
| 1080 | 1080 | }; |
| @@ -443,7 +443,7 @@ · 442 unmodified lines | ||
| 443 | 443 | resets = <&gcc GCC_USB0_BCR>; |
| 444 | 444 | status = "disabled"; |
| 445 | 445 | |
| 446 | − dwc_0: usb@8a00000 { | |
| 446 | + dwc_0: dwc3@8a00000 { | |
| 447 | 447 | compatible = "snps,dwc3"; |
| 448 | 448 | reg = <0x8a00000 0xcd00>; |
| 449 | 449 | interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -484,7 +484,7 @@ · 34 unmodified lines | ||
| 484 | 484 | resets = <&gcc GCC_USB1_BCR>; |
| 485 | 485 | status = "disabled"; |
| 486 | 486 | |
| 487 | − dwc_1: usb@8c00000 { | |
| 487 | + dwc_1: dwc3@8c00000 { | |
| 488 | 488 | compatible = "snps,dwc3"; |
| 489 | 489 | reg = <0x8c00000 0xcd00>; |
| 490 | 490 | interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -2566,7 +2566,7 @@ · 2565 unmodified lines | ||
| 2566 | 2566 | power-domains = <&gcc USB30_GDSC>; |
| 2567 | 2567 | status = "disabled"; |
| 2568 | 2568 | |
| 2569 | − usb@6a00000 { | |
| 2569 | + dwc3@6a00000 { | |
| 2570 | 2570 | compatible = "snps,dwc3"; |
| 2571 | 2571 | reg = <0x06a00000 0xcc00>; |
| 2572 | 2572 | interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -2873,7 +2873,7 @@ · 300 unmodified lines | ||
| 2873 | 2873 | qcom,select-utmi-as-pipe-clk; |
| 2874 | 2874 | status = "disabled"; |
| 2875 | 2875 | |
| 2876 | − usb@7600000 { | |
| 2876 | + dwc3@7600000 { | |
| 2877 | 2877 | compatible = "snps,dwc3"; |
| 2878 | 2878 | reg = <0x07600000 0xcc00>; |
| 2879 | 2879 | interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -1964,7 +1964,7 @@ · 1963 unmodified lines | ||
| 1964 | 1964 | |
| 1965 | 1965 | resets = <&gcc GCC_USB_30_BCR>; |
| 1966 | 1966 | |
| 1967 | − usb3_dwc3: usb@a800000 { | |
| 1967 | + usb3_dwc3: dwc3@a800000 { | |
| 1968 | 1968 | compatible = "snps,dwc3"; |
| 1969 | 1969 | reg = <0x0a800000 0xcd00>; |
| 1970 | 1970 | interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -337,7 +337,7 @@ · 336 unmodified lines | ||
| 337 | 337 | &usb3 { |
| 338 | 338 | status = "okay"; |
| 339 | 339 | |
| 340 | − usb@7580000 { | |
| 340 | + dwc3@7580000 { | |
| 341 | 341 | dr_mode = "host"; |
| 342 | 342 | }; |
| 343 | 343 | }; |
| @@ -544,7 +544,7 @@ · 543 unmodified lines | ||
| 544 | 544 | assigned-clock-rates = <19200000>, <200000000>; |
| 545 | 545 | status = "disabled"; |
| 546 | 546 | |
| 547 | − usb@7580000 { | |
| 547 | + dwc3@7580000 { | |
| 548 | 548 | compatible = "snps,dwc3"; |
| 549 | 549 | reg = <0x07580000 0xcd00>; |
| 550 | 550 | interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -573,7 +573,7 @@ · 22 unmodified lines | ||
| 573 | 573 | assigned-clock-rates = <19200000>, <133333333>; |
| 574 | 574 | status = "disabled"; |
| 575 | 575 | |
| 576 | − usb@78c0000 { | |
| 576 | + dwc3@78c0000 { | |
| 577 | 577 | compatible = "snps,dwc3"; |
| 578 | 578 | reg = <0x078c0000 0xcc00>; |
| 579 | 579 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -2756,7 +2756,7 @@ · 2755 unmodified lines | ||
| 2756 | 2756 | <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3 0>; |
| 2757 | 2757 | interconnect-names = "usb-ddr", "apps-usb"; |
| 2758 | 2758 | |
| 2759 | − usb_1_dwc3: usb@a600000 { | |
| 2759 | + usb_1_dwc3: dwc3@a600000 { | |
| 2760 | 2760 | compatible = "snps,dwc3"; |
| 2761 | 2761 | reg = <0 0x0a600000 0 0xe000>; |
| 2762 | 2762 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -3781,7 +3781,7 @@ · 3780 unmodified lines | ||
| 3781 | 3781 | <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>; |
| 3782 | 3782 | interconnect-names = "usb-ddr", "apps-usb"; |
| 3783 | 3783 | |
| 3784 | − usb_1_dwc3: usb@a600000 { | |
| 3784 | + usb_1_dwc3: dwc3@a600000 { | |
| 3785 | 3785 | compatible = "snps,dwc3"; |
| 3786 | 3786 | reg = <0 0x0a600000 0 0xcd00>; |
| 3787 | 3787 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -3829,7 +3829,7 @@ · 41 unmodified lines | ||
| 3829 | 3829 | <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_1 0>; |
| 3830 | 3830 | interconnect-names = "usb-ddr", "apps-usb"; |
| 3831 | 3831 | |
| 3832 | − usb_2_dwc3: usb@a800000 { | |
| 3832 | + usb_2_dwc3: dwc3@a800000 { | |
| 3833 | 3833 | compatible = "snps,dwc3"; |
| 3834 | 3834 | reg = <0 0x0a800000 0 0xcd00>; |
| 3835 | 3835 | interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -2344,7 +2344,7 @@ · 2343 unmodified lines | ||
| 2344 | 2344 | |
| 2345 | 2345 | resets = <&gcc GCC_USB30_PRIM_BCR>; |
| 2346 | 2346 | |
| 2347 | − usb_1_dwc3: usb@a600000 { | |
| 2347 | + usb_1_dwc3: dwc3@a600000 { | |
| 2348 | 2348 | compatible = "snps,dwc3"; |
| 2349 | 2349 | reg = <0 0x0a600000 0 0xcd00>; |
| 2350 | 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 | 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 | 608 | static inline bool id_aa64pfr0_32bit_el0(u64 pfr0) |
| 609 | 609 | { |
| 610 | 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 | 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 | 657 | val = cpuid_feature_extract_unsigned_field(mmfr0, |
| 658 | 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 | 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 | 670 | val = cpuid_feature_extract_unsigned_field(mmfr0, |
| 670 | 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 | 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 | 683 | val = cpuid_feature_extract_unsigned_field(mmfr0, |
| 682 | 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 | 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 | 784 | static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange) |
| 782 | 785 | { |
| 783 | 786 | switch (parange) { |
| 784 | − case 0: return 32; | |
| 785 | − case 1: return 36; | |
| 786 | − case 2: return 40; | |
| 787 | − case 3: return 42; | |
| 788 | − case 4: return 44; | |
| 789 | − case 5: return 48; | |
| 790 | − case 6: return 52; | |
| 787 | + case ID_AA64MMFR0_PARANGE_32: return 32; | |
| 788 | + case ID_AA64MMFR0_PARANGE_36: return 36; | |
| 789 | + case ID_AA64MMFR0_PARANGE_40: return 40; | |
| 790 | + case ID_AA64MMFR0_PARANGE_42: return 42; | |
| 791 | + case ID_AA64MMFR0_PARANGE_44: return 44; | |
| 792 | + case ID_AA64MMFR0_PARANGE_48: return 48; | |
| 793 | + case ID_AA64MMFR0_PARANGE_52: return 52; | |
| 791 | 794 | /* |
| 792 | 795 | * A future PE could use a value unknown to the kernel. |
| 793 | 796 | * However, by the "D10.1.4 Principles of the ID scheme |
| @@ -12,8 +12,13 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <asm/types.h> |
| 13 | 13 | |
| 14 | 14 | /* Hyp Configuration Register (HCR) bits */ |
| 15 | + | |
| 16 | +#define HCR_TID5 (UL(1) << 58) | |
| 17 | +#define HCR_DCT (UL(1) << 57) | |
| 15 | 18 | #define HCR_ATA_SHIFT 56 |
| 16 | 19 | #define HCR_ATA (UL(1) << HCR_ATA_SHIFT) |
| 20 | +#define HCR_AMVOFFEN (UL(1) << 51) | |
| 21 | +#define HCR_FIEN (UL(1) << 47) | |
| 17 | 22 | #define HCR_FWB (UL(1) << 46) |
| 18 | 23 | #define HCR_API (UL(1) << 41) |
| 19 | 24 | #define HCR_APK (UL(1) << 40) |
| @@ -32,9 +37,9 @@ · 12 unmodified lines | ||
| 32 | 37 | #define HCR_TVM (UL(1) << 26) |
| 33 | 38 | #define HCR_TTLB (UL(1) << 25) |
| 34 | 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 | 41 | #define HCR_TSW (UL(1) << 22) |
| 37 | −#define HCR_TAC (UL(1) << 21) | |
| 42 | +#define HCR_TACR (UL(1) << 21) | |
| 38 | 43 | #define HCR_TIDCP (UL(1) << 20) |
| 39 | 44 | #define HCR_TSC (UL(1) << 19) |
| 40 | 45 | #define HCR_TID3 (UL(1) << 18) |
| @@ -56,12 +61,13 @@ · 15 unmodified lines | ||
| 56 | 61 | #define HCR_PTW (UL(1) << 2) |
| 57 | 62 | #define HCR_SWIO (UL(1) << 1) |
| 58 | 63 | #define HCR_VM (UL(1) << 0) |
| 64 | +#define HCR_RES0 ((UL(1) << 48) | (UL(1) << 39)) | |
| 59 | 65 | |
| 60 | 66 | /* |
| 61 | 67 | * The bits we set in HCR: |
| 62 | 68 | * TLOR: Trap LORegion register accesses |
| 63 | 69 | * RW: 64bit by default, can be overridden for 32bit VMs |
| 64 | − * TAC: Trap ACTLR | |
| 70 | + * TACR: Trap ACTLR | |
| 65 | 71 | * TSC: Trap SMC |
| 66 | 72 | * TSW: Trap cache operations by set/way |
| 67 | 73 | * TWE: Trap WFE |
| @@ -76,7 +82,7 @@ · 8 unmodified lines | ||
| 76 | 82 | * PTW: Take a stage2 fault if a stage1 walk steps in device memory |
| 77 | 83 | */ |
| 78 | 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 | 86 | HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \ |
| 81 | 87 | HCR_FMO | HCR_IMO | HCR_PTW ) |
| 82 | 88 | #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF) |
| @@ -275,24 +281,40 @@ · 192 unmodified lines | ||
| 275 | 281 | #define CPTR_EL2_TTA (1 << 20) |
| 276 | 282 | #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) |
| 277 | 283 | #define CPTR_EL2_TZ (1 << 8) |
| 278 | −#define CPTR_EL2_RES1 0x000032ff /* known RES1 bits in CPTR_EL2 */ | |
| 279 | −#define CPTR_EL2_DEFAULT CPTR_EL2_RES1 | |
| 284 | +#define CPTR_NVHE_EL2_RES1 0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */ | |
| 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 | 291 | /* Hyp Debug Configuration Register bits */ |
| 282 | 292 | #define MDCR_EL2_E2TB_MASK (UL(0x3)) |
| 283 | 293 | #define MDCR_EL2_E2TB_SHIFT (UL(24)) |
| 284 | −#define MDCR_EL2_TTRF (1 << 19) | |
| 285 | −#define MDCR_EL2_TPMS (1 << 14) | |
| 294 | +#define MDCR_EL2_HPMFZS (UL(1) << 36) | |
| 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 | 302 | #define MDCR_EL2_E2PB_MASK (UL(0x3)) |
| 287 | 303 | #define MDCR_EL2_E2PB_SHIFT (UL(12)) |
| 288 | −#define MDCR_EL2_TDRA (1 << 11) | |
| 289 | −#define MDCR_EL2_TDOSA (1 << 10) | |
| 290 | −#define MDCR_EL2_TDA (1 << 9) | |
| 291 | −#define MDCR_EL2_TDE (1 << 8) | |
| 292 | −#define MDCR_EL2_HPME (1 << 7) | |
| 293 | −#define MDCR_EL2_TPM (1 << 6) | |
| 294 | −#define MDCR_EL2_TPMCR (1 << 5) | |
| 295 | −#define MDCR_EL2_HPMN_MASK (0x1F) | |
| 304 | +#define MDCR_EL2_TDRA (UL(1) << 11) | |
| 305 | +#define MDCR_EL2_TDOSA (UL(1) << 10) | |
| 306 | +#define MDCR_EL2_TDA (UL(1) << 9) | |
| 307 | +#define MDCR_EL2_TDE (UL(1) << 8) | |
| 308 | +#define MDCR_EL2_HPME (UL(1) << 7) | |
| 309 | +#define MDCR_EL2_TPM (UL(1) << 6) | |
| 310 | +#define MDCR_EL2_TPMCR (UL(1) << 5) | |
| 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 | 319 | /* For compatibility with fault code shared with 32-bit */ |
| 298 | 320 | #define FSC_FAULT ESR_ELx_FSC_FAULT |
| @@ -59,12 +59,11 @@ · 58 unmodified lines | ||
| 59 | 59 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs 13 |
| 60 | 60 | #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs 14 |
| 61 | 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 | 63 | #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping 17 |
| 64 | 64 | #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector 18 |
| 65 | 65 | #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize 19 |
| 66 | −#define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp 20 | |
| 67 | −#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 21 | |
| 66 | +#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 20 | |
| 68 | 67 | |
| 69 | 68 | #ifndef __ASSEMBLY__ |
| 70 | 69 | |
| @@ -210,7 +209,7 @@ extern u64 __vgic_v3_read_vmcr(void); · 139 unmodified lines | ||
| 210 | 209 | extern void __vgic_v3_write_vmcr(u32 vmcr); |
| 211 | 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 | 214 | #define __KVM_EXTABLE(from, to) \ |
| 216 | 215 | " .pushsection __kvm_ex_table, \"a\"\n" \ |
| @@ -66,7 +66,7 @@ DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use); · 65 unmodified lines | ||
| 66 | 66 | extern unsigned int kvm_sve_max_vl; |
| 67 | 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 | 70 | int kvm_reset_vcpu(struct kvm_vcpu *vcpu); |
| 71 | 71 | void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu); |
| 72 | 72 | |
| @@ -185,7 +185,6 @@ enum vcpu_sysreg { · 112 unmodified lines | ||
| 185 | 185 | PMCNTENSET_EL0, /* Count Enable Set Register */ |
| 186 | 186 | PMINTENSET_EL1, /* Interrupt Enable Set Register */ |
| 187 | 187 | PMOVSSET_EL0, /* Overflow Flag Status Set Register */ |
| 188 | − PMSWINC_EL0, /* Software Increment Register */ | |
| 189 | 188 | PMUSERENR_EL0, /* User Enable Register */ |
| 190 | 189 | |
| 191 | 190 | /* Pointer Authentication Registers in a strict increasing order. */ |
| @@ -287,9 +286,13 @@ struct kvm_vcpu_arch { · 95 unmodified lines | ||
| 287 | 286 | /* Stage 2 paging state used by the hardware on next switch */ |
| 288 | 287 | struct kvm_s2_mmu *hw_mmu; |
| 289 | 288 | |
| 290 | − /* HYP configuration */ | |
| 289 | + /* Values of trap registers for the guest. */ | |
| 291 | 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 | 297 | /* Exception Information */ |
| 295 | 298 | struct kvm_vcpu_fault_info fault; |
| @@ -576,6 +579,7 @@ struct kvm_vcpu_stat { · 280 unmodified lines | ||
| 576 | 579 | u64 wfi_exit_stat; |
| 577 | 580 | u64 mmio_exit_user; |
| 578 | 581 | u64 mmio_exit_kernel; |
| 582 | + u64 signal_exits; | |
| 579 | 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 | 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 | 783 | int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature); |
| 775 | 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 | 96 | #ifndef __KVM_NVHE_HYPERVISOR__ |
| 97 | 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 | 99 | #endif |
| 100 | 100 | |
| 101 | 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 | 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 | 260 | static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu) |
| 256 | 261 | { |
| 257 | 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 | 264 | u64 cnp = system_supports_cnp() ? VTTBR_CNP_BIT : 0; |
| 260 | 265 | |
| 261 | 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 | 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 | 272 | * Must be called from hyp code running at EL2 with an updated VTTBR |
| 268 | 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 | 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 | 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 | 289 | static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu) |
| 289 | 290 | { |
| 290 | 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 | 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 | 69 | * struct kvm_pgtable_mm_ops - Memory management callbacks. |
| 30 | 70 | * @zalloc_page: Allocate a single zeroed memory page. |
| @@ -75,31 +115,16 @@ enum kvm_pgtable_stage2_flags { · 44 unmodified lines | ||
| 75 | 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 | 119 | * enum kvm_pgtable_prot - Page-table permissions and attributes. |
| 99 | 120 | * @KVM_PGTABLE_PROT_X: Execute permission. |
| 100 | 121 | * @KVM_PGTABLE_PROT_W: Write permission. |
| 101 | 122 | * @KVM_PGTABLE_PROT_R: Read permission. |
| 102 | 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 | 129 | enum kvm_pgtable_prot { |
| 105 | 130 | KVM_PGTABLE_PROT_X = BIT(0), |
| @@ -107,21 +132,48 @@ enum kvm_pgtable_prot { · 1 unmodified line | ||
| 107 | 132 | KVM_PGTABLE_PROT_R = BIT(2), |
| 108 | 133 | |
| 109 | 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 | 149 | #define PAGE_HYP_EXEC (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X) |
| 114 | 150 | #define PAGE_HYP_RO (KVM_PGTABLE_PROT_R) |
| 115 | 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 | |
| 119 | − * @start: Start of the range. | |
| 120 | − * @end: End of the range. | |
| 157 | + * struct kvm_pgtable - KVM page-table. | |
| 158 | + * @ia_bits: Maximum input address size, in bits. | |
| 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 { | |
| 123 | − u64 start; | |
| 124 | − u64 end; | |
| 167 | +struct kvm_pgtable { | |
| 168 | + u32 ia_bits; | |
| 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 | 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 | 272 | * @pgt: Uninitialised page-table structure to initialise. |
| 221 | 273 | * @arch: Arch-specific KVM structure representing the guest virtual |
| 222 | 274 | * machine. |
| 223 | 275 | * @mm_ops: Memory management callbacks. |
| 224 | 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 | 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, | |
| 229 | − struct kvm_pgtable_mm_ops *mm_ops, | |
| 230 | − enum kvm_pgtable_stage2_flags flags); | |
| 282 | +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch, | |
| 283 | + struct kvm_pgtable_mm_ops *mm_ops, | |
| 284 | + enum kvm_pgtable_stage2_flags flags, | |
| 285 | + kvm_pgtable_force_pte_cb_t force_pte_cb); | |
| 231 | 286 | |
| 232 | 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 | 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 | 429 | * If there is a valid, leaf page-table entry used to translate @addr, then |
| 375 | 430 | * relax the permissions in that entry according to the read, write and |
| 376 | 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 | 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 | 489 | struct kvm_pgtable_walker *walker); |
| 434 | 490 | |
| 435 | 491 | /** |
| 436 | − * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical | |
| 437 | − * Addresses with compatible permission | |
| 438 | − * attributes. | |
| 439 | − * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*(). | |
| 440 | − * @addr: Address that must be covered by the range. | |
| 441 | − * @prot: Protection attributes that the range must be compatible with. | |
| 442 | − * @range: Range structure used to limit the search space at call time and | |
| 443 | − * that will hold the result. | |
| 492 | + * kvm_pgtable_get_leaf() - Walk a page-table and retrieve the leaf entry | |
| 493 | + * with its level. | |
| 494 | + * @pgt: Page-table structure initialised by kvm_pgtable_*_init() | |
| 495 | + * or a similar initialiser. | |
| 496 | + * @addr: Input address for the start of the walk. | |
| 497 | + * @ptep: Pointer to storage for the retrieved PTE. | |
| 498 | + * @level: Pointer to storage for the level of the retrieved PTE. | |
| 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 | |
| 446 | − * iff its corresponding stage-2 page-table entry has default ownership and, if | |
| 447 | − * valid, is mapped with protection attributes identical to @prot. | |
| 502 | + * The walker will walk the page-table entries corresponding to the input | |
| 503 | + * address specified, retrieving the leaf corresponding to this address. | |
| 504 | + * Invalid entries are treated as leaf entries. | |
| 448 | 505 | * |
| 449 | 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, | |
| 452 | − enum kvm_pgtable_prot prot, | |
| 453 | − struct kvm_mem_range *range); | |
| 508 | +int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, | |
| 509 | + kvm_pte_t *ptep, u32 *level); | |
| 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 | 530 | #endif /* __ARM64_KVM_PGTABLE_H__ */ |
| @@ -784,14 +784,13 @@ · 783 unmodified lines | ||
| 784 | 784 | #define ID_AA64PFR0_AMU 0x1 |
| 785 | 785 | #define ID_AA64PFR0_SVE 0x1 |
| 786 | 786 | #define ID_AA64PFR0_RAS_V1 0x1 |
| 787 | +#define ID_AA64PFR0_RAS_V1P1 0x2 | |
| 787 | 788 | #define ID_AA64PFR0_FP_NI 0xf |
| 788 | 789 | #define ID_AA64PFR0_FP_SUPPORTED 0x0 |
| 789 | 790 | #define ID_AA64PFR0_ASIMD_NI 0xf |
| 790 | 791 | #define ID_AA64PFR0_ASIMD_SUPPORTED 0x0 |
| 791 | −#define ID_AA64PFR0_EL1_64BIT_ONLY 0x1 | |
| 792 | −#define ID_AA64PFR0_EL1_32BIT_64BIT 0x2 | |
| 793 | −#define ID_AA64PFR0_EL0_64BIT_ONLY 0x1 | |
| 794 | −#define ID_AA64PFR0_EL0_32BIT_64BIT 0x2 | |
| 792 | +#define ID_AA64PFR0_ELx_64BIT_ONLY 0x1 | |
| 793 | +#define ID_AA64PFR0_ELx_32BIT_64BIT 0x2 | |
| 795 | 794 | |
| 796 | 795 | /* id_aa64pfr1 */ |
| 797 | 796 | #define ID_AA64PFR1_MPAMFRAC_SHIFT 16 |
| @@ -847,15 +846,29 @@ · 49 unmodified lines | ||
| 847 | 846 | #define ID_AA64MMFR0_ASID_SHIFT 4 |
| 848 | 847 | #define ID_AA64MMFR0_PARANGE_SHIFT 0 |
| 849 | 848 | |
| 850 | −#define ID_AA64MMFR0_TGRAN4_NI 0xf | |
| 851 | −#define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0 | |
| 852 | −#define ID_AA64MMFR0_TGRAN64_NI 0xf | |
| 853 | −#define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0 | |
| 854 | −#define ID_AA64MMFR0_TGRAN16_NI 0x0 | |
| 855 | −#define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1 | |
| 849 | +#define ID_AA64MMFR0_ASID_8 0x0 | |
| 850 | +#define ID_AA64MMFR0_ASID_16 0x2 | |
| 851 | + | |
| 852 | +#define ID_AA64MMFR0_TGRAN4_NI 0xf | |
| 853 | +#define ID_AA64MMFR0_TGRAN4_SUPPORTED_MIN 0x0 | |
| 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 | 867 | #define ID_AA64MMFR0_PARANGE_48 0x5 |
| 857 | 868 | #define ID_AA64MMFR0_PARANGE_52 0x6 |
| 858 | 869 | |
| 870 | +#define ARM64_MIN_PARANGE_BITS 32 | |
| 871 | + | |
| 859 | 872 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_DEFAULT 0x0 |
| 860 | 873 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE 0x1 |
| 861 | 874 | #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_MIN 0x2 |
| @@ -900,6 +913,7 @@ · 38 unmodified lines | ||
| 900 | 913 | #define ID_AA64MMFR2_CNP_SHIFT 0 |
| 901 | 914 | |
| 902 | 915 | /* id_aa64dfr0 */ |
| 916 | +#define ID_AA64DFR0_MTPMU_SHIFT 48 | |
| 903 | 917 | #define ID_AA64DFR0_TRBE_SHIFT 44 |
| 904 | 918 | #define ID_AA64DFR0_TRACE_FILT_SHIFT 40 |
| 905 | 919 | #define ID_AA64DFR0_DOUBLELOCK_SHIFT 36 |
| @@ -1028,16 +1042,19 @@ · 122 unmodified lines | ||
| 1028 | 1042 | |
| 1029 | 1043 | #if defined(CONFIG_ARM64_4K_PAGES) |
| 1030 | 1044 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN4_SHIFT |
| 1031 | −#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN4_SUPPORTED | |
| 1032 | −#define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0x7 | |
| 1045 | +#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN4_SUPPORTED_MIN | |
| 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 | 1048 | #elif defined(CONFIG_ARM64_16K_PAGES) |
| 1034 | 1049 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN16_SHIFT |
| 1035 | −#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN16_SUPPORTED | |
| 1036 | −#define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0xF | |
| 1050 | +#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN16_SUPPORTED_MIN | |
| 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 | 1053 | #elif defined(CONFIG_ARM64_64K_PAGES) |
| 1038 | 1054 | #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN64_SHIFT |
| 1039 | −#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN64_SUPPORTED | |
| 1040 | −#define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0x7 | |
| 1055 | +#define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN64_SUPPORTED_MIN | |
| 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 | 1058 | #endif |
| 1042 | 1059 | |
| 1043 | 1060 | #define MVFR2_FPMISC_SHIFT 4 |
| @@ -1153,6 +1170,11 @@ · 109 unmodified lines | ||
| 1153 | 1170 | #define ICH_VTR_A3V_SHIFT 21 |
| 1154 | 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 | 1178 | #ifdef __ASSEMBLY__ |
| 1157 | 1179 | |
| 1158 | 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 | 239 | S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI), |
| 240 | 240 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL3_SHIFT, 4, 0), |
| 241 | 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), | |
| 243 | − ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_EL0_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_ELx_64BIT_ONLY), | |
| 244 | 244 | ARM64_FTR_END, |
| 245 | 245 | }; |
| 246 | 246 | |
| @@ -1956,7 +1956,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { · 1709 unmodified lines | ||
| 1956 | 1956 | .sys_reg = SYS_ID_AA64PFR0_EL1, |
| 1957 | 1957 | .sign = FTR_UNSIGNED, |
| 1958 | 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 | 1961 | #ifdef CONFIG_KVM |
| 1962 | 1962 | { |
| @@ -1967,7 +1967,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { · 4 unmodified lines | ||
| 1967 | 1967 | .sys_reg = SYS_ID_AA64PFR0_EL1, |
| 1968 | 1968 | .sign = FTR_UNSIGNED, |
| 1969 | 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 | 1973 | .desc = "Protected KVM", |
| @@ -32,20 +32,23 @@ SYM_FUNC_END(__arm_smccc_sve_check) · 31 unmodified lines | ||
| 32 | 32 | EXPORT_SYMBOL(__arm_smccc_sve_check) |
| 33 | 33 | |
| 34 | 34 | .macro SMCCC instr |
| 35 | + stp x29, x30, [sp, #-16]! | |
| 36 | + mov x29, sp | |
| 35 | 37 | alternative_if ARM64_SVE |
| 36 | 38 | bl __arm_smccc_sve_check |
| 37 | 39 | alternative_else_nop_endif |
| 38 | 40 | \instr #0 |
| 39 | − ldr x4, [sp] | |
| 41 | + ldr x4, [sp, #16] | |
| 40 | 42 | stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] |
| 41 | 43 | stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] |
| 42 | − ldr x4, [sp, #8] | |
| 44 | + ldr x4, [sp, #24] | |
| 43 | 45 | cbz x4, 1f /* no quirk structure */ |
| 44 | 46 | ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] |
| 45 | 47 | cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 |
| 46 | 48 | b.ne 1f |
| 47 | 49 | str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] |
| 48 | −1: ret | |
| 50 | +1: ldp x29, x30, [sp], #16 | |
| 51 | + ret | |
| 49 | 52 | .endm |
| 50 | 53 | |
| 51 | 54 | /* |
| @@ -181,6 +181,8 @@ SECTIONS · 180 unmodified lines | ||
| 181 | 181 | /* everything from this point to __init_begin will be marked RO NX */ |
| 182 | 182 | RO_DATA(PAGE_SIZE) |
| 183 | 183 | |
| 184 | + HYPERVISOR_DATA_SECTIONS | |
| 185 | + | |
| 184 | 186 | idmap_pg_dir = .; |
| 185 | 187 | . += IDMAP_DIR_SIZE; |
| 186 | 188 | idmap_pg_end = .; |
| @@ -260,8 +262,6 @@ SECTIONS · 73 unmodified lines | ||
| 260 | 262 | _sdata = .; |
| 261 | 263 | RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) |
| 262 | 264 | |
| 263 | − HYPERVISOR_DATA_SECTIONS | |
| 264 | − | |
| 265 | 265 | /* |
| 266 | 266 | * Data written with the MMU off but read with the MMU on requires |
| 267 | 267 | * cache lines to be invalidated, discarding up to a Cache Writeback |
| @@ -26,6 +26,7 @@ menuconfig KVM · 25 unmodified lines | ||
| 26 | 26 | select HAVE_KVM_ARCH_TLB_FLUSH_ALL |
| 27 | 27 | select KVM_MMIO |
| 28 | 28 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT |
| 29 | + select KVM_XFER_TO_GUEST_WORK | |
| 29 | 30 | select SRCU |
| 30 | 31 | select KVM_VFIO |
| 31 | 32 | select HAVE_KVM_EVENTFD |
| @@ -46,6 +47,15 @@ if KVM · 14 unmodified lines | ||
| 46 | 47 | |
| 47 | 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 | 59 | endif # KVM |
| 50 | 60 | |
| 51 | 61 | endif # VIRTUALIZATION |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | #include <linux/bug.h> |
| 8 | 8 | #include <linux/cpu_pm.h> |
| 9 | +#include <linux/entry-kvm.h> | |
| 9 | 10 | #include <linux/errno.h> |
| 10 | 11 | #include <linux/err.h> |
| 11 | 12 | #include <linux/kvm_host.h> |
| @@ -15,6 +16,7 @@ · 3 unmodified lines | ||
| 15 | 16 | #include <linux/fs.h> |
| 16 | 17 | #include <linux/mman.h> |
| 17 | 18 | #include <linux/sched.h> |
| 19 | +#include <linux/kmemleak.h> | |
| 18 | 20 | #include <linux/kvm.h> |
| 19 | 21 | #include <linux/kvm_irqfd.h> |
| 20 | 22 | #include <linux/irqbypass.h> |
| @@ -42,10 +44,6 @@ · 21 unmodified lines | ||
| 42 | 44 | #include <kvm/arm_pmu.h> |
| 43 | 45 | #include <kvm/arm_psci.h> |
| 44 | 46 | |
| 45 | −#ifdef REQUIRES_VIRT | |
| 46 | −__asm__(".arch_extension virt"); | |
| 47 | −#endif | |
| 48 | − | |
| 49 | 47 | static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT; |
| 50 | 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 | 92 | kvm->arch.return_nisv_io_abort_to_user = true; |
| 95 | 93 | break; |
| 96 | 94 | case KVM_CAP_ARM_MTE: |
| 97 | − if (!system_supports_mte() || kvm->created_vcpus) | |
| 98 | − return -EINVAL; | |
| 99 | − r = 0; | |
| 100 | − kvm->arch.mte_enabled = true; | |
| 95 | + mutex_lock(&kvm->lock); | |
| 96 | + if (!system_supports_mte() || kvm->created_vcpus) { | |
| 97 | + r = -EINVAL; | |
| 98 | + } else { | |
| 99 | + r = 0; | |
| 100 | + kvm->arch.mte_enabled = true; | |
| 101 | + } | |
| 102 | + mutex_unlock(&kvm->lock); | |
| 101 | 103 | break; |
| 102 | 104 | default: |
| 103 | 105 | r = -EINVAL; |
| @@ -571,7 +573,7 @@ static void update_vmid(struct kvm_vmid *vmid) · 467 unmodified lines | ||
| 571 | 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 | 577 | kvm_next_vmid++; |
| 576 | 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 | 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 | 759 | * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code |
| 719 | 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 | 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 | 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 | 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 | 823 | * Ensure we set mode to IN_GUEST_MODE after we disable |
| 805 | 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 | 828 | smp_store_mb(vcpu->mode, IN_GUEST_MODE); |
| 810 | 829 | |
| 811 | − if (ret <= 0 || need_new_vmid_gen(&vcpu->arch.hw_mmu->vmid) || | |
| 812 | − kvm_request_pending(vcpu)) { | |
| 830 | + if (ret <= 0 || kvm_vcpu_exit_request(vcpu, &ret)) { | |
| 813 | 831 | vcpu->mode = OUTSIDE_GUEST_MODE; |
| 814 | 832 | isb(); /* Ensure work in x_flush_hwstate is committed */ |
| 815 | 833 | kvm_pmu_sync_hwstate(vcpu); |
| @@ -1035,7 +1053,7 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, · 219 unmodified lines | ||
| 1035 | 1053 | const struct kvm_vcpu_init *init) |
| 1036 | 1054 | { |
| 1037 | 1055 | unsigned int i, ret; |
| 1038 | − int phys_target = kvm_target_cpu(); | |
| 1056 | + u32 phys_target = kvm_target_cpu(); | |
| 1039 | 1057 | |
| 1040 | 1058 | if (init->target != phys_target) |
| 1041 | 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 | 1124 | vcpu_reset_hcr(vcpu); |
| 1125 | + vcpu->arch.cptr_el2 = CPTR_EL2_DEFAULT; | |
| 1107 | 1126 | |
| 1108 | 1127 | /* |
| 1109 | 1128 | * Handle the "start in power-off" case. |
| @@ -1215,6 +1234,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 105 unmodified lines | ||
| 1215 | 1234 | if (copy_from_user(®, argp, sizeof(reg))) |
| 1216 | 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 | 1245 | if (ioctl == KVM_SET_ONE_REG) |
| 1219 | 1246 | r = kvm_arm_set_reg(vcpu, ®); |
| 1220 | 1247 | else |
| @@ -1696,11 +1723,6 @@ static bool init_psci_relay(void) · 475 unmodified lines | ||
| 1696 | 1723 | return true; |
| 1697 | 1724 | } |
| 1698 | 1725 | |
| 1699 | −static int init_common_resources(void) | |
| 1700 | −{ | |
| 1701 | − return kvm_set_ipa_limit(); | |
| 1702 | −} | |
| 1703 | − | |
| 1704 | 1726 | static int init_subsystems(void) |
| 1705 | 1727 | { |
| 1706 | 1728 | int err = 0; |
| @@ -1954,56 +1976,17 @@ static void _kvm_host_prot_finalize(void *discard) · 247 unmodified lines | ||
| 1954 | 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 | 1979 | static int finalize_hyp_mode(void) |
| 1967 | 1980 | { |
| 1968 | − int cpu, ret; | |
| 1969 | − | |
| 1970 | 1981 | if (!is_protected_kvm_enabled()) |
| 1971 | 1982 | return 0; |
| 1972 | 1983 | |
| 1973 | − ret = pkvm_mark_hyp_section(__hyp_idmap_text); | |
| 1974 | − if (ret) | |
| 1975 | − return ret; | |
| 1976 | − | |
| 1977 | − ret = pkvm_mark_hyp_section(__hyp_text); | |
| 1978 | − if (ret) | |
| 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 | − } | |
| 1984 | + /* | |
| 1985 | + * Exclude HYP BSS from kmemleak so that it doesn't get peeked | |
| 1986 | + * at, which would end badly once the section is inaccessible. | |
| 1987 | + * None of other sections should ever be introspected. | |
| 1988 | + */ | |
| 1989 | + kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); | |
| 2007 | 1990 | |
| 2008 | 1991 | /* |
| 2009 | 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 | 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 | 2001 | struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr) |
| 2024 | 2002 | { |
| 2025 | 2003 | struct kvm_vcpu *vcpu; |
| @@ -2079,7 +2057,6 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons) · 53 unmodified lines | ||
| 2079 | 2057 | int kvm_arch_init(void *opaque) |
| 2080 | 2058 | { |
| 2081 | 2059 | int err; |
| 2082 | − int ret, cpu; | |
| 2083 | 2060 | bool in_hyp_mode; |
| 2084 | 2061 | |
| 2085 | 2062 | if (!is_hyp_mode_available()) { |
| @@ -2094,15 +2071,7 @@ int kvm_arch_init(void *opaque) · 8 unmodified lines | ||
| 2094 | 2071 | kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \ |
| 2095 | 2072 | "Only trusted guests should be used on this system.\n"); |
| 2096 | 2073 | |
| 2097 | − for_each_online_cpu(cpu) { | |
| 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(); | |
| 2074 | + err = kvm_set_ipa_limit(); | |
| 2106 | 2075 | if (err) |
| 2107 | 2076 | return err; |
| 2108 | 2077 | |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | DBG_MDSCR_KDE | \ |
| 22 | 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 | 27 | * save/restore_guest_debug_regs |
| @@ -48,6 +48,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { · 47 unmodified lines | ||
| 48 | 48 | STATS_DESC_COUNTER(VCPU, wfi_exit_stat), |
| 49 | 49 | STATS_DESC_COUNTER(VCPU, mmio_exit_user), |
| 50 | 50 | STATS_DESC_COUNTER(VCPU, mmio_exit_kernel), |
| 51 | + STATS_DESC_COUNTER(VCPU, signal_exits), | |
| 51 | 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 | 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 | 844 | unsigned long implementor = read_cpuid_implementor(); |
| 844 | 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 | 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 | 876 | if (target < 0) |
| 876 | 877 | return -ENODEV; |
| @@ -113,34 +113,20 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu) · 112 unmodified lines | ||
| 113 | 113 | * guest and host are using the same debug facilities it will be up to |
| 114 | 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 | 118 | static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu) |
| 119 | 119 | { |
| 120 | 120 | struct kvm_run *run = vcpu->run; |
| 121 | 121 | u32 esr = kvm_vcpu_get_esr(vcpu); |
| 122 | − int ret = 0; | |
| 123 | 122 | |
| 124 | 123 | run->exit_reason = KVM_EXIT_DEBUG; |
| 125 | 124 | run->debug.arch.hsr = esr; |
| 126 | 125 | |
| 127 | − switch (ESR_ELx_EC(esr)) { | |
| 128 | − case ESR_ELx_EC_WATCHPT_LOW: | |
| 126 | + if (ESR_ELx_EC(esr) == ESR_ELx_EC_WATCHPT_LOW) | |
| 129 | 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 | 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 | 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 | 283 | u64 par, uintptr_t vcpu, |
| 297 | 284 | u64 far, u64 hpfar) { |
| 298 | − u64 elr_in_kimg = __phys_to_kimg(__hyp_pa(elr)); | |
| 299 | − u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr; | |
| 285 | + u64 elr_in_kimg = __phys_to_kimg(elr_phys); | |
| 286 | + u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr_virt; | |
| 300 | 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 | 296 | kvm_err("Invalid host exception to nVHE hyp!\n"); |
| 310 | 297 | } else if (ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 && |
| 311 | 298 | (esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == BUG_BRK_IMM) { |
| 312 | − struct bug_entry *bug = find_bug(elr_in_kimg); | |
| 313 | 299 | const char *file = NULL; |
| 314 | 300 | unsigned int line = 0; |
| 315 | 301 | |
| 316 | 302 | /* All hyp bugs, including warnings, are treated as fatal. */ |
| 317 | − if (bug) | |
| 318 | − bug_get_file_line(bug, &file, &line); | |
| 303 | + if (!is_protected_kvm_enabled() || | |
| 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 | 311 | if (file) |
| 321 | 312 | kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line); |
| 322 | 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 | 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 | 325 | kvm_err("Hyp Offset: 0x%llx\n", hyp_offset); |
| 335 | 326 | |
| 336 | 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 | 92 | write_sysreg(0, pmselr_el0); |
| 93 | 93 | write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); |
| 94 | 94 | } |
| 95 | + | |
| 96 | + vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); | |
| 95 | 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 | 104 | write_sysreg(0, hstr_el2); |
| 101 | 105 | if (kvm_arm_support_pmu_v3()) |
| 102 | 106 | write_sysreg(0, pmuserenr_el0); |
| @@ -12,6 +12,32 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <asm/virt.h> |
| 13 | 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 | 41 | struct host_kvm { |
| 16 | 42 | struct kvm_arch arch; |
| 17 | 43 | struct kvm_pgtable pgt; |
| @@ -20,16 +46,21 @@ struct host_kvm { · 2 unmodified lines | ||
| 20 | 46 | }; |
| 21 | 47 | extern struct host_kvm host_kvm; |
| 22 | 48 | |
| 49 | +extern const u8 pkvm_hyp_id; | |
| 50 | + | |
| 23 | 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 | 57 | int kvm_host_prepare_stage2(void *pgt_pool_base); |
| 27 | 58 | void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt); |
| 28 | 59 | |
| 29 | 60 | static __always_inline void __load_host_stage2(void) |
| 30 | 61 | { |
| 31 | 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 | 64 | else |
| 34 | 65 | write_sysreg(0, vttbr_el2); |
| 35 | 66 | } |
| @@ -23,8 +23,7 @@ int hyp_map_vectors(void); · 22 unmodified lines | ||
| 23 | 23 | int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back); |
| 24 | 24 | int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot); |
| 25 | 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, | |
| 27 | − unsigned long phys, enum kvm_pgtable_prot prot); | |
| 26 | +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot); | |
| 28 | 27 | unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size, |
| 29 | 28 | enum kvm_pgtable_prot prot); |
| 30 | 29 | |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | #include <asm/alternative.h> |
| 17 | 17 | #include <asm/lse.h> |
| 18 | +#include <asm/rwonce.h> | |
| 18 | 19 | |
| 19 | 20 | typedef union hyp_spinlock { |
| 20 | 21 | u32 __val; |
| @@ -89,4 +90,28 @@ static inline void hyp_spin_unlock(hyp_spinlock_t *lock) · 68 unmodified lines | ||
| 89 | 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 | 117 | #endif /* __ARM64_KVM_NVHE_SPINLOCK_H__ */ |
| @@ -109,7 +109,7 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu) · 108 unmodified lines | ||
| 109 | 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 | 114 | return read_sysreg(mdcr_el2); |
| 115 | 115 | } |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/linkage.h> |
| 8 | 8 | |
| 9 | 9 | #include <asm/assembler.h> |
| 10 | +#include <asm/kvm_arm.h> | |
| 10 | 11 | #include <asm/kvm_asm.h> |
| 11 | 12 | #include <asm/kvm_mmu.h> |
| 12 | 13 | |
| @@ -85,12 +86,24 @@ SYM_FUNC_START(__hyp_do_panic) · 72 unmodified lines | ||
| 85 | 86 | |
| 86 | 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 | 99 | /* Load the panic arguments into x0-7 */ |
| 89 | 100 | mrs x0, esr_el2 |
| 90 | − get_vcpu_ptr x4, x5 | |
| 91 | − mrs x5, far_el2 | |
| 92 | − mrs x6, hpfar_el2 | |
| 93 | − mov x7, xzr // Unused argument | |
| 101 | + mov x4, x3 | |
| 102 | + mov x3, x2 | |
| 103 | + hyp_pa x3, x6 | |
| 104 | + get_vcpu_ptr x5, x6 | |
| 105 | + mrs x6, far_el2 | |
| 106 | + mrs x7, hpfar_el2 | |
| 94 | 107 | |
| 95 | 108 | /* Enter the host, conditionally restoring the host context. */ |
| 96 | 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 | 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); | |
| 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); | |
| 145 | + DECLARE_REG(u64, pfn, host_ctxt, 1); | |
| 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 | 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 | 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 | 163 | typedef void (*hcall_t)(struct kvm_cpu_context *); |
| 175 | 164 | |
| 176 | 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 | 182 | HANDLE_FUNC(__vgic_v3_restore_aprs), |
| 194 | 183 | HANDLE_FUNC(__pkvm_init), |
| 195 | 184 | HANDLE_FUNC(__pkvm_cpu_set_vector), |
| 196 | − HANDLE_FUNC(__pkvm_create_mappings), | |
| 185 | + HANDLE_FUNC(__pkvm_host_share_hyp), | |
| 197 | 186 | HANDLE_FUNC(__pkvm_create_private_mapping), |
| 198 | 187 | HANDLE_FUNC(__pkvm_prot_finalize), |
| 199 | − HANDLE_FUNC(__pkvm_mark_hyp), | |
| 200 | 188 | }; |
| 201 | 189 | |
| 202 | 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 | 31 | u64 id_aa64mmfr0_el1_sys_val; |
| 32 | 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 | 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 | 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 | 94 | int kvm_host_prepare_stage2(void *pgt_pool_base) |
| 93 | 95 | { |
| 94 | 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 | 103 | if (ret) |
| 102 | 104 | return ret; |
| 103 | 105 | |
| 104 | − ret = kvm_pgtable_stage2_init_flags(&host_kvm.pgt, &host_kvm.arch, | |
| 105 | − &host_kvm.mm_ops, KVM_HOST_S2_FLAGS); | |
| 106 | + ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, &host_kvm.arch, | |
| 107 | + &host_kvm.mm_ops, KVM_HOST_S2_FLAGS, | |
| 108 | + host_stage2_force_pte_cb); | |
| 106 | 109 | if (ret) |
| 107 | 110 | return ret; |
| 108 | 111 | |
| 109 | 112 | mmu->pgd_phys = __hyp_pa(host_kvm.pgt.pgd); |
| 110 | 113 | mmu->arch = &host_kvm.arch; |
| 111 | 114 | mmu->pgt = &host_kvm.pgt; |
| 112 | − mmu->vmid.vmid_gen = 0; | |
| 113 | − mmu->vmid.vmid = 0; | |
| 115 | + WRITE_ONCE(mmu->vmid.vmid_gen, 0); | |
| 116 | + WRITE_ONCE(mmu->vmid.vmid, 0); | |
| 114 | 117 | |
| 115 | 118 | return 0; |
| 116 | 119 | } |
| @@ -126,7 +129,7 @@ int __pkvm_prot_finalize(void) · 9 unmodified lines | ||
| 126 | 129 | kvm_flush_dcache_to_poc(params, sizeof(*params)); |
| 127 | 130 | |
| 128 | 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 | 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 | 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 | 170 | static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range) |
| 163 | 171 | { |
| 164 | 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 | 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 | 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)) | |
| 197 | − return false; | |
| 198 | − if (r1.start != r2.start) | |
| 216 | + if (!find_mem_range(start, &r)) | |
| 199 | 217 | return false; |
| 200 | 218 | |
| 201 | − return true; | |
| 219 | + return is_in_mem_range(end - 1, &r); | |
| 202 | 220 | } |
| 203 | 221 | |
| 204 | 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 | 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 | 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 | 326 | struct kvm_mem_range range; |
| 215 | 327 | bool is_memory = find_mem_range(addr, &range); |
| 328 | + enum kvm_pgtable_prot prot; | |
| 216 | 329 | int ret; |
| 217 | 330 | |
| 218 | − if (is_memory) | |
| 219 | − prot |= KVM_PGTABLE_PROT_X; | |
| 331 | + prot = is_memory ? PKVM_HOST_MEM_PROT : PKVM_HOST_MMIO_PROT; | |
| 220 | 332 | |
| 221 | 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 | 335 | if (ret) |
| 224 | 336 | goto unlock; |
| 225 | 337 | |
| 226 | − ret = __host_stage2_idmap(range.start, range.end, prot); | |
| 227 | − if (ret != -ENOMEM) | |
| 338 | + ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot); | |
| 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 | 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 | |
| 232 | − * with page granularity, but it is difficult to know how much of the | |
| 233 | − * MMIO range we will need to cover upfront, so we may need to 'recycle' | |
| 234 | − * the pages if we run out. | |
| 374 | + * Check attributes in the host stage-2 PTE. We need the page to be: | |
| 375 | + * - mapped RWX as we're sharing memory; | |
| 376 | + * - not borrowed, as that implies absence of ownership. | |
| 377 | + * Otherwise, we can't let it got through | |
| 235 | 378 | */ |
| 236 | − ret = host_stage2_unmap_dev_all(); | |
| 237 | − if (ret) | |
| 379 | + cur = kvm_pgtable_stage2_pte_prot(pte); | |
| 380 | + prot = pkvm_mkstate(0, PKVM_PAGE_SHARED_BORROWED); | |
| 381 | + if (!check_prot(cur, PKVM_HOST_MEM_PROT, prot)) { | |
| 382 | + ret = -EPERM; | |
| 238 | 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: | |
| 243 | − hyp_spin_unlock(&host_kvm.lock); | |
| 390 | + /* | |
| 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; | |
| 246 | −} | |
| 399 | + ret = kvm_pgtable_get_leaf(&pkvm_pgtable, (u64)virt, &pte, NULL); | |
| 400 | + if (ret) | |
| 401 | + goto unlock; | |
| 247 | 402 | |
| 248 | −int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end) | |
| 249 | −{ | |
| 250 | − int ret; | |
| 403 | + /* | |
| 404 | + * If the page has been shared with the hypervisor, it must be | |
| 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 | |
| 254 | − * non-persistent, so don't allow changing page ownership in MMIO range. | |
| 415 | + * If the page is not yet shared, adjust mappings in both page-tables | |
| 416 | + * while both locks are held. | |
| 255 | 417 | */ |
| 256 | − if (!range_is_memory(start, end)) | |
| 257 | − return -EINVAL; | |
| 418 | + prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED); | |
| 419 | + ret = pkvm_create_mappings_locked(virt, virt + PAGE_SIZE, prot); | |
| 420 | + BUG_ON(ret); | |
| 258 | 421 | |
| 259 | − hyp_spin_lock(&host_kvm.lock); | |
| 260 | − ret = kvm_pgtable_stage2_set_owner(&host_kvm.pgt, start, end - start, | |
| 261 | − &host_s2_pool, pkvm_hyp_id); | |
| 422 | + prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED); | |
| 423 | + ret = host_stage2_idmap_locked(addr, PAGE_SIZE, prot); | |
| 424 | + BUG_ON(ret); | |
| 425 | + | |
| 426 | +unlock: | |
| 427 | + hyp_spin_unlock(&pkvm_pgd_lock); | |
| 262 | 428 | hyp_spin_unlock(&host_kvm.lock); |
| 263 | 429 | |
| 264 | − return ret != -EAGAIN ? ret : 0; | |
| 430 | + return ret; | |
| 265 | 431 | } |
| 266 | 432 | |
| 267 | 433 | void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) |
| @@ -23,8 +23,8 @@ u64 __io_map_base; · 22 unmodified lines | ||
| 23 | 23 | struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS]; |
| 24 | 24 | unsigned int hyp_memblock_nr; |
| 25 | 25 | |
| 26 | −int __pkvm_create_mappings(unsigned long start, unsigned long size, | |
| 27 | − unsigned long phys, enum kvm_pgtable_prot prot) | |
| 26 | +static int __pkvm_create_mappings(unsigned long start, unsigned long size, | |
| 27 | + unsigned long phys, enum kvm_pgtable_prot prot) | |
| 28 | 28 | { |
| 29 | 29 | int err; |
| 30 | 30 | |
| @@ -67,13 +67,15 @@ out: · 36 unmodified lines | ||
| 67 | 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 | 72 | unsigned long start = (unsigned long)from; |
| 73 | 73 | unsigned long end = (unsigned long)to; |
| 74 | 74 | unsigned long virt_addr; |
| 75 | 75 | phys_addr_t phys; |
| 76 | 76 | |
| 77 | + hyp_assert_lock_held(&pkvm_pgd_lock); | |
| 78 | + | |
| 77 | 79 | start = start & PAGE_MASK; |
| 78 | 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 | 83 | int err; |
| 82 | 84 | |
| 83 | 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 | 88 | if (err) |
| 86 | 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 | 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 | 106 | int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back) |
| 93 | 107 | { |
| 94 | 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 | 59 | void *start, *end, *virt = hyp_phys_to_virt(phys); |
| 60 | 60 | unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT; |
| 61 | + enum kvm_pgtable_prot prot; | |
| 61 | 62 | int ret, i; |
| 62 | 63 | |
| 63 | 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 | 84 | if (ret) |
| 84 | 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 | 87 | ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO); |
| 91 | 88 | if (ret) |
| 92 | 89 | return ret; |
| @@ -95,10 +92,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · 2 unmodified lines | ||
| 95 | 92 | if (ret) |
| 96 | 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 | 95 | ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP); |
| 103 | 96 | if (ret) |
| 104 | 97 | return ret; |
| @@ -117,6 +110,24 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · 12 unmodified lines | ||
| 117 | 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 | 131 | return 0; |
| 121 | 132 | } |
| 122 | 133 | |
| @@ -148,6 +159,57 @@ static void hpool_put_page(void *addr) · 25 unmodified lines | ||
| 148 | 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 | 213 | void __noreturn __pkvm_init_finalise(void) |
| 152 | 214 | { |
| 153 | 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 | 229 | if (ret) |
| 168 | 230 | goto out; |
| 169 | 231 | |
| 232 | + ret = finalize_host_mappings(); | |
| 233 | + if (ret) | |
| 234 | + goto out; | |
| 235 | + | |
| 170 | 236 | pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) { |
| 171 | 237 | .zalloc_page = hyp_zalloc_hyp_page, |
| 172 | 238 | .phys_to_virt = hyp_phys_to_virt, |
| @@ -41,7 +41,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 40 unmodified lines | ||
| 41 | 41 | ___activate_traps(vcpu); |
| 42 | 42 | __activate_traps_common(vcpu); |
| 43 | 43 | |
| 44 | − val = CPTR_EL2_DEFAULT; | |
| 44 | + val = vcpu->arch.cptr_el2; | |
| 45 | 45 | val |= CPTR_EL2_TTA | CPTR_EL2_TAM; |
| 46 | 46 | if (!update_fp_enabled(vcpu)) { |
| 47 | 47 | val |= CPTR_EL2_TFP | CPTR_EL2_TZ; |
| @@ -69,12 +69,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 21 unmodified lines | ||
| 69 | 69 | static void __deactivate_traps(struct kvm_vcpu *vcpu) |
| 70 | 70 | { |
| 71 | 71 | extern char __kvm_hyp_host_vector[]; |
| 72 | − u64 mdcr_el2, cptr; | |
| 72 | + u64 cptr; | |
| 73 | 73 | |
| 74 | 74 | ___deactivate_traps(vcpu); |
| 75 | 75 | |
| 76 | − mdcr_el2 = read_sysreg(mdcr_el2); | |
| 77 | − | |
| 78 | 76 | if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { |
| 79 | 77 | u64 val; |
| 80 | 78 | |
| @@ -92,13 +90,8 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) · 11 unmodified lines | ||
| 92 | 90 | isb(); |
| 93 | 91 | } |
| 94 | 92 | |
| 95 | − __deactivate_traps_common(); | |
| 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; | |
| 93 | + __deactivate_traps_common(vcpu); | |
| 100 | 94 | |
| 101 | − write_sysreg(mdcr_el2, mdcr_el2); | |
| 102 | 95 | write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2); |
| 103 | 96 | |
| 104 | 97 | cptr = CPTR_EL2_DEFAULT; |
| @@ -170,6 +163,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) · 65 unmodified lines | ||
| 170 | 163 | { |
| 171 | 164 | struct kvm_cpu_context *host_ctxt; |
| 172 | 165 | struct kvm_cpu_context *guest_ctxt; |
| 166 | + struct kvm_s2_mmu *mmu; | |
| 173 | 167 | bool pmu_switch_needed; |
| 174 | 168 | u64 exit_code; |
| 175 | 169 | |
| @@ -213,7 +207,8 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) · 37 unmodified lines | ||
| 213 | 207 | __sysreg32_restore_state(vcpu); |
| 214 | 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 | 212 | __activate_traps(vcpu); |
| 218 | 213 | |
| 219 | 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 | 38 | * workaround is applied. Take care of the opposite condition, |
| 39 | 39 | * ensuring that we always have an ISB, but not two ISBs back |
| 40 | 40 | * to back. |
| 41 | 41 | */ |
| 42 | − __load_guest_stage2(mmu); | |
| 42 | + __load_stage2(mmu, kern_hyp_va(mmu->arch)); | |
| 43 | 43 | asm(ALTERNATIVE("isb", "nop", ARM64_WORKAROUND_SPECULATIVE_AT)); |
| 44 | 44 | } |
| 45 | 45 | |
| @@ -11,16 +11,12 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <asm/kvm_pgtable.h> |
| 12 | 12 | #include <asm/stage2_pgtable.h> |
| 13 | 13 | |
| 14 | −#define KVM_PTE_VALID BIT(0) | |
| 15 | 14 | |
| 16 | 15 | #define KVM_PTE_TYPE BIT(1) |
| 17 | 16 | #define KVM_PTE_TYPE_BLOCK 0 |
| 18 | 17 | #define KVM_PTE_TYPE_PAGE 1 |
| 19 | 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 | 20 | #define KVM_PTE_LEAF_ATTR_LO GENMASK(11, 2) |
| 25 | 21 | |
| 26 | 22 | #define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX GENMASK(4, 2) |
| @@ -40,6 +36,8 @@ · 13 unmodified lines | ||
| 40 | 36 | |
| 41 | 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 | 41 | #define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54) |
| 44 | 42 | |
| 45 | 43 | #define KVM_PTE_LEAF_ATTR_HI_S2_XN BIT(54) |
| @@ -48,9 +46,7 @@ · 2 unmodified lines | ||
| 48 | 46 | KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \ |
| 49 | 47 | KVM_PTE_LEAF_ATTR_HI_S2_XN) |
| 50 | 48 | |
| 51 | −#define KVM_PTE_LEAF_ATTR_S2_IGNORED GENMASK(58, 55) | |
| 52 | − | |
| 53 | −#define KVM_INVALID_PTE_OWNER_MASK GENMASK(63, 56) | |
| 49 | +#define KVM_INVALID_PTE_OWNER_MASK GENMASK(9, 2) | |
| 54 | 50 | #define KVM_MAX_OWNER_ID 1 |
| 55 | 51 | |
| 56 | 52 | struct kvm_pgtable_walk_data { |
| @@ -61,17 +57,6 @@ struct kvm_pgtable_walk_data { · 4 unmodified lines | ||
| 61 | 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 | 60 | #define KVM_PHYS_INVALID (-1ULL) |
| 76 | 61 | |
| 77 | 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 | 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 | 67 | static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level) |
| 92 | 68 | { |
| 93 | 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 | 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 | 114 | static bool kvm_pte_table(kvm_pte_t pte, u32 level) |
| 144 | 115 | { |
| 145 | 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 | 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 | 125 | static kvm_pte_t kvm_phys_to_pte(u64 pa) |
| 165 | 126 | { |
| 166 | 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 | 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 | 329 | struct hyp_map_data { |
| 330 | 330 | u64 phys; |
| 331 | 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 | 357 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_AP, ap); |
| 358 | 358 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_SH, sh); |
| 359 | 359 | attr |= KVM_PTE_LEAF_ATTR_LO_S1_AF; |
| 360 | + attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW; | |
| 360 | 361 | *ptep = attr; |
| 361 | 362 | |
| 362 | 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 | 401 | static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level, |
| 366 | 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 | 407 | if (!kvm_block_mapping_supported(addr, end, phys, level)) |
| 372 | 408 | return false; |
| 373 | 409 | |
| 374 | − /* Tolerate KVM recreating the exact same mapping */ | |
| 375 | 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 | 412 | smp_store_release(ptep, new); |
| 378 | 413 | |
| 379 | 414 | data->phys += granule; |
| @@ -438,6 +473,8 @@ int kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits, · 58 unmodified lines | ||
| 438 | 473 | pgt->start_level = KVM_PGTABLE_MAX_LEVELS - levels; |
| 439 | 474 | pgt->mm_ops = mm_ops; |
| 440 | 475 | pgt->mmu = NULL; |
| 476 | + pgt->force_pte_cb = NULL; | |
| 477 | + | |
| 441 | 478 | return 0; |
| 442 | 479 | } |
| 443 | 480 | |
| @@ -475,6 +512,9 @@ struct stage2_map_data { · 31 unmodified lines | ||
| 475 | 512 | void *memcache; |
| 476 | 513 | |
| 477 | 514 | struct kvm_pgtable_mm_ops *mm_ops; |
| 515 | + | |
| 516 | + /* Force mappings to page granularity */ | |
| 517 | + bool force_pte; | |
| 478 | 518 | }; |
| 479 | 519 | |
| 480 | 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 | 580 | attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S2_SH, sh); |
| 541 | 581 | attr |= KVM_PTE_LEAF_ATTR_LO_S2_AF; |
| 582 | + attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW; | |
| 542 | 583 | *ptep = attr; |
| 543 | 584 | |
| 544 | 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 | 605 | static bool stage2_pte_needs_update(kvm_pte_t old, kvm_pte_t new) |
| 548 | 606 | { |
| 549 | 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 | 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 | 658 | static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, |
| 592 | 659 | kvm_pte_t *ptep, |
| 593 | 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 | 664 | struct kvm_pgtable *pgt = data->mmu->pgt; |
| 598 | 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 | 668 | return -E2BIG; |
| 602 | 669 | |
| 603 | 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 | 708 | if (data->anchor) |
| 642 | 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 | 712 | return 0; |
| 646 | 713 | |
| 647 | 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 | 838 | .mmu = pgt->mmu, |
| 772 | 839 | .memcache = mc, |
| 773 | 840 | .mm_ops = pgt->mm_ops, |
| 841 | + .force_pte = pgt->force_pte_cb && pgt->force_pte_cb(addr, addr + size, prot), | |
| 774 | 842 | }; |
| 775 | 843 | struct kvm_pgtable_walker walker = { |
| 776 | 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 | 870 | .memcache = mc, |
| 803 | 871 | .mm_ops = pgt->mm_ops, |
| 804 | 872 | .owner_id = owner_id, |
| 873 | + .force_pte = true, | |
| 805 | 874 | }; |
| 806 | 875 | struct kvm_pgtable_walker walker = { |
| 807 | 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 | 1064 | u32 level; |
| 996 | 1065 | kvm_pte_t set = 0, clr = 0; |
| 997 | 1066 | |
| 1067 | + if (prot & KVM_PTE_LEAF_ATTR_HI_SW) | |
| 1068 | + return -EINVAL; | |
| 1069 | + | |
| 998 | 1070 | if (prot & KVM_PGTABLE_PROT_R) |
| 999 | 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 | 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, | |
| 1047 | − struct kvm_pgtable_mm_ops *mm_ops, | |
| 1048 | − enum kvm_pgtable_stage2_flags flags) | |
| 1118 | + | |
| 1119 | +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch, | |
| 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 | 1124 | size_t pgd_sz; |
| 1051 | 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 | 1137 | pgt->mm_ops = mm_ops; |
| 1064 | 1138 | pgt->mmu = &arch->mmu; |
| 1065 | 1139 | pgt->flags = flags; |
| 1140 | + pgt->force_pte_cb = force_pte_cb; | |
| 1066 | 1141 | |
| 1067 | 1142 | /* Ensure zeroed PGD pages are visible to the hardware walker */ |
| 1068 | 1143 | dsb(ishst); |
| @@ -1102,77 +1177,3 @@ void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) · 33 unmodified lines | ||
| 1102 | 1177 | pgt->mm_ops->free_pages_exact(pgt->pgd, pgd_sz); |
| 1103 | 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 | 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 | 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 | 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); | |
| 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(); | |
| 96 | + __deactivate_traps_common(vcpu); | |
| 105 | 97 | } |
| 106 | 98 | |
| 107 | 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 | 117 | * We have already configured the guest's stage 1 translation in |
| 126 | 118 | * kvm_vcpu_load_sysregs_vhe above. We must now call |
| 127 | − * __load_guest_stage2 before __activate_traps, because | |
| 128 | − * __load_guest_stage2 configures stage 2 translation, and | |
| 119 | + * __load_stage2 before __activate_traps, because | |
| 120 | + * __load_stage2 configures stage 2 translation, and | |
| 129 | 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 | 124 | __activate_traps(vcpu); |
| 133 | 125 | |
| 134 | 126 | __kvm_adjust_pc(vcpu); |
| @@ -101,7 +101,7 @@ void kvm_vcpu_put_sysregs_vhe(struct kvm_vcpu *vcpu) · 100 unmodified lines | ||
| 101 | 101 | struct kvm_cpu_context *host_ctxt; |
| 102 | 102 | |
| 103 | 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 | 106 | __sysreg_save_el1_state(guest_ctxt); |
| 107 | 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 | 51 | * ARM erratum 1165522 requires some special handling (again), |
| 52 | 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 | 54 | * has an ISB in order to deal with this. |
| 55 | 55 | */ |
| 56 | − __load_guest_stage2(mmu); | |
| 56 | + __load_stage2(mmu, mmu->arch); | |
| 57 | 57 | val = read_sysreg(hcr_el2); |
| 58 | 58 | val &= ~HCR_TGE; |
| 59 | 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 | 261 | int err; |
| 262 | 262 | |
| 263 | − if (!kvm_host_owns_hyp_mappings()) { | |
| 264 | − return kvm_call_hyp_nvhe(__pkvm_create_mappings, | |
| 265 | − start, size, phys, prot); | |
| 266 | − } | |
| 263 | + if (WARN_ON(!kvm_host_owns_hyp_mappings())) | |
| 264 | + return -EINVAL; | |
| 267 | 265 | |
| 268 | 266 | mutex_lock(&kvm_hyp_pgd_mutex); |
| 269 | 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 | 300 | * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode |
| 288 | 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 | 316 | if (is_kernel_in_hyp_mode()) |
| 304 | 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 | 326 | start = start & PAGE_MASK; |
| 307 | 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 | 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 | 483 | static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = { |
| 438 | 484 | .zalloc_page = stage2_memcache_zalloc_page, |
| 439 | 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 | 532 | mmu->arch = &kvm->arch; |
| 487 | 533 | mmu->pgt = pgt; |
| 488 | 534 | mmu->pgd_phys = __pa(pgt->pgd); |
| 489 | − mmu->vmid.vmid_gen = 0; | |
| 535 | + WRITE_ONCE(mmu->vmid.vmid_gen, 0); | |
| 490 | 536 | return 0; |
| 491 | 537 | |
| 492 | 538 | out_destroy_pgtable: |
| @@ -781,7 +827,7 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot, · 288 unmodified lines | ||
| 781 | 827 | * Returns the size of the mapping. |
| 782 | 828 | */ |
| 783 | 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 | 831 | unsigned long hva, kvm_pfn_t *pfnp, |
| 786 | 832 | phys_addr_t *ipap) |
| 787 | 833 | { |
| @@ -792,8 +838,8 @@ transparent_hugepage_adjust(struct kvm_memory_slot *memslot, · 4 unmodified lines | ||
| 792 | 838 | * sure that the HVA and IPA are sufficiently aligned and that the |
| 793 | 839 | * block map is contained within the memslot. |
| 794 | 840 | */ |
| 795 | − if (kvm_is_transparent_hugepage(pfn) && | |
| 796 | − fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE)) { | |
| 841 | + if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE) && | |
| 842 | + get_user_mapping_size(kvm, hva) >= PMD_SIZE) { | |
| 797 | 843 | /* |
| 798 | 844 | * The address we faulted on is backed by a transparent huge |
| 799 | 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 | 861 | *ipap &= PMD_MASK; |
| 816 | 862 | kvm_release_pfn_clean(pfn); |
| 817 | 863 | pfn &= ~(PTRS_PER_PMD - 1); |
| 818 | − kvm_get_pfn(pfn); | |
| 864 | + get_page(pfn_to_page(pfn)); | |
| 819 | 865 | *pfnp = pfn; |
| 820 | 866 | |
| 821 | 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 | 1097 | * If we are not forced to use page mapping, check if we are |
| 1052 | 1098 | * backed by a THP and thus use block mapping if possible. |
| 1053 | 1099 | */ |
| 1054 | − if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) | |
| 1055 | − vma_pagesize = transparent_hugepage_adjust(memslot, hva, | |
| 1056 | − &pfn, &fault_ipa); | |
| 1100 | + if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) { | |
| 1101 | + if (fault_status == FSC_PERM && fault_granule > PAGE_SIZE) | |
| 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 | 1109 | if (fault_status != FSC_PERM && !device && kvm_has_mte(kvm)) { |
| 1059 | 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 | 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 | 54 | static_branch_enable(&kvm_arm_pmu_available); |
| 55 | 55 | |
| 56 | 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 | 373 | reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0); |
| 374 | 374 | reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0); |
| 375 | 375 | reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1); |
| 376 | − reg &= kvm_pmu_valid_counter_mask(vcpu); | |
| 377 | 376 | } |
| 378 | 377 | |
| 379 | 378 | return reg; |
| @@ -564,20 +563,21 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val) · 184 unmodified lines | ||
| 564 | 563 | */ |
| 565 | 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 | 566 | int i; |
| 569 | 567 | |
| 570 | 568 | if (val & ARMV8_PMU_PMCR_E) { |
| 571 | 569 | kvm_pmu_enable_counter_mask(vcpu, |
| 572 | − __vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask); | |
| 570 | + __vcpu_sys_reg(vcpu, PMCNTENSET_EL0)); | |
| 573 | 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 | 576 | if (val & ARMV8_PMU_PMCR_C) |
| 578 | 577 | kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0); |
| 579 | 578 | |
| 580 | 579 | if (val & ARMV8_PMU_PMCR_P) { |
| 580 | + unsigned long mask = kvm_pmu_valid_counter_mask(vcpu); | |
| 581 | 581 | mask &= ~BIT(ARMV8_PMU_CYCLE_IDX); |
| 582 | 582 | for_each_set_bit(i, &mask, 32) |
| 583 | 583 | kvm_pmu_set_counter_value(vcpu, i, 0); |
| @@ -745,7 +745,7 @@ int kvm_pmu_probe_pmuver(void) · 161 unmodified lines | ||
| 745 | 745 | struct perf_event_attr attr = { }; |
| 746 | 746 | struct perf_event *event; |
| 747 | 747 | struct arm_pmu *pmu; |
| 748 | − int pmuver = 0xf; | |
| 748 | + int pmuver = ID_AA64DFR0_PMUVER_IMP_DEF; | |
| 749 | 749 | |
| 750 | 750 | /* |
| 751 | 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 | 770 | if (IS_ERR(event)) { |
| 771 | 771 | pr_err_once("kvm: pmu event creation failed %ld\n", |
| 772 | 772 | PTR_ERR(event)); |
| 773 | − return 0xf; | |
| 773 | + return ID_AA64DFR0_PMUVER_IMP_DEF; | |
| 774 | 774 | } |
| 775 | 775 | |
| 776 | 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 | 923 | if (!vcpu->kvm->arch.pmuver) |
| 924 | 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 | 927 | return -ENODEV; |
| 928 | 928 | |
| 929 | 929 | switch (attr->attr) { |
| @@ -59,6 +59,12 @@ static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu) · 58 unmodified lines | ||
| 59 | 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 | 68 | static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) |
| 63 | 69 | { |
| 64 | 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 | 72 | struct kvm_vcpu *vcpu = NULL; |
| 67 | 73 | unsigned long cpu_id; |
| 68 | 74 | |
| 69 | − cpu_id = smccc_get_arg1(source_vcpu) & MPIDR_HWID_BITMASK; | |
| 70 | − if (vcpu_mode_is_32bit(source_vcpu)) | |
| 71 | − cpu_id &= ~((u32) 0); | |
| 75 | + cpu_id = smccc_get_arg1(source_vcpu); | |
| 76 | + if (!kvm_psci_valid_affinity(source_vcpu, cpu_id)) | |
| 77 | + return PSCI_RET_INVALID_PARAMS; | |
| 72 | 78 | |
| 73 | 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 | 132 | target_affinity = smccc_get_arg1(vcpu); |
| 127 | 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 | 138 | /* Determine target affinity mask */ |
| 130 | 139 | target_affinity_mask = psci_affinity_mask(lowest_affinity_level); |
| 131 | 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 | 211 | int kvm_reset_vcpu(struct kvm_vcpu *vcpu) |
| 212 | 212 | { |
| 213 | + struct vcpu_reset_state reset_state; | |
| 213 | 214 | int ret; |
| 214 | 215 | bool loaded; |
| 215 | 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 | 223 | /* Reset PMU outside of the non-preemptible section */ |
| 218 | 224 | kvm_pmu_vcpu_reset(vcpu); |
| 219 | 225 | |
| @@ -276,8 +282,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) · 56 unmodified lines | ||
| 276 | 282 | * Additional reset state handling that PSCI may have imposed on us. |
| 277 | 283 | * Must be done after all the sys_reg reset. |
| 278 | 284 | */ |
| 279 | − if (vcpu->arch.reset_state.reset) { | |
| 280 | − unsigned long target_pc = vcpu->arch.reset_state.pc; | |
| 285 | + if (reset_state.reset) { | |
| 286 | + unsigned long target_pc = reset_state.pc; | |
| 281 | 287 | |
| 282 | 288 | /* Gracefully handle Thumb2 entry point */ |
| 283 | 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 | 294 | /* Propagate caller endianness */ |
| 289 | − if (vcpu->arch.reset_state.be) | |
| 295 | + if (reset_state.be) | |
| 290 | 296 | kvm_vcpu_set_be(vcpu); |
| 291 | 297 | |
| 292 | 298 | *vcpu_pc(vcpu) = target_pc; |
| 293 | − vcpu_set_reg(vcpu, 0, vcpu->arch.reset_state.r0); | |
| 294 | − | |
| 295 | − vcpu->arch.reset_state.reset = false; | |
| 299 | + vcpu_set_reg(vcpu, 0, reset_state.r0); | |
| 296 | 300 | } |
| 297 | 301 | |
| 298 | 302 | /* Reset timer */ |
| @@ -311,31 +315,26 @@ u32 get_kvm_ipa_limit(void) · 12 unmodified lines | ||
| 311 | 315 | |
| 312 | 316 | int kvm_set_ipa_limit(void) |
| 313 | 317 | { |
| 314 | − unsigned int parange, tgran_2; | |
| 318 | + unsigned int parange; | |
| 315 | 319 | u64 mmfr0; |
| 316 | 320 | |
| 317 | 321 | mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); |
| 318 | 322 | parange = cpuid_feature_extract_unsigned_field(mmfr0, |
| 319 | 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 | 334 | * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at |
| 323 | 335 | * Stage-2. If not, things will stop very quickly. |
| 324 | 336 | */ |
| 325 | − switch (PAGE_SIZE) { | |
| 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)) { | |
| 337 | + switch (cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_TGRAN_2_SHIFT)) { | |
| 339 | 338 | case ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE: |
| 340 | 339 | kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n"); |
| 341 | 340 | return -EINVAL; |
| @@ -369,7 +368,7 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type) · 27 unmodified lines | ||
| 369 | 368 | phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type); |
| 370 | 369 | if (phys_shift) { |
| 371 | 370 | if (phys_shift > kvm_ipa_limit || |
| 372 | − phys_shift < 32) | |
| 371 | + phys_shift < ARM64_MIN_PARANGE_BITS) | |
| 373 | 372 | return -EINVAL; |
| 374 | 373 | } else { |
| 375 | 374 | phys_shift = KVM_PHYS_SHIFT; |
| @@ -44,10 +44,6 @@ · 43 unmodified lines | ||
| 44 | 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 | 47 | static bool read_from_write_only(struct kvm_vcpu *vcpu, |
| 52 | 48 | struct sys_reg_params *params, |
| 53 | 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 | 315 | * We want to avoid world-switching all the DBG registers all the |
| 320 | 316 | * time: |
| 321 | − * | |
| 317 | + * | |
| 322 | 318 | * - If we've touched any debug register, it is likely that we're |
| 323 | 319 | * going to touch more of them. It then makes sense to disable the |
| 324 | 320 | * traps and start doing the save/restore dance |
| 325 | 321 | * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is |
| 326 | 322 | * then mandatory to save/restore the registers, as the guest |
| 327 | 323 | * depends on them. |
| 328 | − * | |
| 324 | + * | |
| 329 | 325 | * For this, we use a DIRTY bit, indicating the guest has modified the |
| 330 | 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 | 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 | 637 | static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) |
| 607 | 638 | { |
| 608 | 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 | 876 | kvm_pmu_disable_counter_mask(vcpu, val); |
| 846 | 877 | } |
| 847 | 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 | 882 | return true; |
| @@ -869,7 +900,7 @@ static bool access_pminten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 17 unmodified lines | ||
| 869 | 900 | /* accessing PMINTENCLR_EL1 */ |
| 870 | 901 | __vcpu_sys_reg(vcpu, PMINTENSET_EL1) &= ~val; |
| 871 | 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 | 906 | return true; |
| @@ -891,7 +922,7 @@ static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 15 unmodified lines | ||
| 891 | 922 | /* accessing PMOVSCLR_EL0 */ |
| 892 | 923 | __vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= ~(p->regval & mask); |
| 893 | 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 | 928 | return true; |
| @@ -944,16 +975,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 46 unmodified lines | ||
| 944 | 975 | trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } |
| 945 | 976 | |
| 946 | 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 | 980 | /* Macro to expand the PMEVCNTRn_EL0 register */ |
| 950 | 981 | #define PMU_PMEVCNTR_EL0(n) \ |
| 951 | 982 | { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ |
| 983 | + .reset = reset_pmevcntr, \ | |
| 952 | 984 | .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), } |
| 953 | 985 | |
| 954 | 986 | /* Macro to expand the PMEVTYPERn_EL0 register */ |
| 955 | 987 | #define PMU_PMEVTYPER_EL0(n) \ |
| 956 | 988 | { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \ |
| 989 | + .reset = reset_pmevtyper, \ | |
| 957 | 990 | .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), } |
| 958 | 991 | |
| 959 | 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 | 1059 | return true; |
| 1027 | 1060 | } |
| 1028 | 1061 | |
| 1029 | −#define FEATURE(x) (GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT)) | |
| 1030 | − | |
| 1031 | 1062 | /* Read a sanitised cpufeature ID register by sys_reg_desc */ |
| 1032 | 1063 | static u64 read_id_reg(const struct kvm_vcpu *vcpu, |
| 1033 | 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 | 1069 | switch (id) { |
| 1039 | 1070 | case SYS_ID_AA64PFR0_EL1: |
| 1040 | 1071 | if (!vcpu_has_sve(vcpu)) |
| 1041 | − val &= ~FEATURE(ID_AA64PFR0_SVE); | |
| 1042 | − val &= ~FEATURE(ID_AA64PFR0_AMU); | |
| 1043 | − val &= ~FEATURE(ID_AA64PFR0_CSV2); | |
| 1044 | − val |= FIELD_PREP(FEATURE(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2); | |
| 1045 | − val &= ~FEATURE(ID_AA64PFR0_CSV3); | |
| 1046 | − val |= FIELD_PREP(FEATURE(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3); | |
| 1072 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE); | |
| 1073 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU); | |
| 1074 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2); | |
| 1075 | + val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2); | |
| 1076 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3); | |
| 1077 | + val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3); | |
| 1047 | 1078 | break; |
| 1048 | 1079 | case SYS_ID_AA64PFR1_EL1: |
| 1049 | − val &= ~FEATURE(ID_AA64PFR1_MTE); | |
| 1080 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE); | |
| 1050 | 1081 | if (kvm_has_mte(vcpu->kvm)) { |
| 1051 | 1082 | u64 pfr, mte; |
| 1052 | 1083 | |
| 1053 | 1084 | pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1); |
| 1054 | 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 | 1088 | break; |
| 1058 | 1089 | case SYS_ID_AA64ISAR1_EL1: |
| 1059 | 1090 | if (!vcpu_has_ptrauth(vcpu)) |
| 1060 | − val &= ~(FEATURE(ID_AA64ISAR1_APA) | | |
| 1061 | − FEATURE(ID_AA64ISAR1_API) | | |
| 1062 | − FEATURE(ID_AA64ISAR1_GPA) | | |
| 1063 | − FEATURE(ID_AA64ISAR1_GPI)); | |
| 1091 | + val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) | | |
| 1092 | + ARM64_FEATURE_MASK(ID_AA64ISAR1_API) | | |
| 1093 | + ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) | | |
| 1094 | + ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI)); | |
| 1064 | 1095 | break; |
| 1065 | 1096 | case SYS_ID_AA64DFR0_EL1: |
| 1066 | 1097 | /* Limit debug to ARMv8.0 */ |
| 1067 | − val &= ~FEATURE(ID_AA64DFR0_DEBUGVER); | |
| 1068 | − val |= FIELD_PREP(FEATURE(ID_AA64DFR0_DEBUGVER), 6); | |
| 1098 | + val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER); | |
| 1099 | + val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), 6); | |
| 1069 | 1100 | /* Limit guests to PMUv3 for ARMv8.4 */ |
| 1070 | 1101 | val = cpuid_feature_cap_perfmon_field(val, |
| 1071 | 1102 | ID_AA64DFR0_PMUVER_SHIFT, |
| 1072 | 1103 | kvm_vcpu_has_pmu(vcpu) ? ID_AA64DFR0_PMUVER_8_4 : 0); |
| 1073 | 1104 | /* Hide SPE from guests */ |
| 1074 | − val &= ~FEATURE(ID_AA64DFR0_PMSVER); | |
| 1105 | + val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER); | |
| 1075 | 1106 | break; |
| 1076 | 1107 | case SYS_ID_DFR0_EL1: |
| 1077 | 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 | 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 | 1297 | static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| 1253 | 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 | 1637 | .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, |
| 1593 | 1638 | { PMU_SYS_REG(SYS_PMOVSCLR_EL0), |
| 1594 | 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 | 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 | 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 | 1649 | { PMU_SYS_REG(SYS_PMCEID0_EL0), |
| 1600 | 1650 | .access = access_pmceid, .reset = NULL }, |
| 1601 | 1651 | { PMU_SYS_REG(SYS_PMCEID1_EL0), |
| 1602 | 1652 | .access = access_pmceid, .reset = NULL }, |
| 1603 | 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 | 1655 | { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), |
| 1606 | 1656 | .access = access_pmu_evtyper, .reset = NULL }, |
| 1607 | 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 | 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 | 2159 | int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu) |
| 2127 | 2160 | { |
| 2128 | 2161 | kvm_inject_undefined(vcpu); |
| @@ -2365,13 +2398,8 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu) · 236 unmodified lines | ||
| 2365 | 2398 | |
| 2366 | 2399 | trace_kvm_handle_sys_reg(esr); |
| 2367 | 2400 | |
| 2368 | − params.Op0 = (esr >> 20) & 3; | |
| 2369 | − params.Op1 = (esr >> 14) & 0x7; | |
| 2370 | − params.CRn = (esr >> 10) & 0xf; | |
| 2371 | − params.CRm = (esr >> 1) & 0xf; | |
| 2372 | − params.Op2 = (esr >> 17) & 0x7; | |
| 2401 | + params = esr_sys64_to_params(esr); | |
| 2373 | 2402 | params.regval = vcpu_get_reg(vcpu, Rt); |
| 2374 | − params.is_write = !(esr & 1); | |
| 2375 | 2403 | |
| 2376 | 2404 | ret = emulate_sys_reg(vcpu, ¶ms); |
| 2377 | 2405 | |
| @@ -11,6 +11,12 @@ · 10 unmodified lines | ||
| 11 | 11 | #ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__ |
| 12 | 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 | 20 | struct sys_reg_params { |
| 15 | 21 | u8 Op0; |
| 16 | 22 | u8 Op1; |
| @@ -21,6 +27,14 @@ struct sys_reg_params { · 4 unmodified lines | ||
| 21 | 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 | 38 | struct sys_reg_desc { |
| 25 | 39 | /* Sysreg string for debug */ |
| 26 | 40 | const char *name; |
| @@ -152,6 +166,23 @@ static inline int cmp_sys_reg(const struct sys_reg_desc *i1, · 125 unmodified lines | ||
| 152 | 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 | 186 | const struct sys_reg_desc *find_reg_by_id(u64 id, |
| 156 | 187 | struct sys_reg_params *params, |
| 157 | 188 | const struct sys_reg_desc table[], |
| @@ -78,13 +78,17 @@ TRACE_EVENT(kvm_arm_clear_debug, · 77 unmodified lines | ||
| 78 | 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 | 85 | TRACE_EVENT(kvm_arm_set_dreg32, |
| 82 | − TP_PROTO(const char *name, __u32 value), | |
| 86 | + TP_PROTO(const char *name, __u64 value), | |
| 83 | 87 | TP_ARGS(name, value), |
| 84 | 88 | |
| 85 | 89 | TP_STRUCT__entry( |
| 86 | 90 | __field(const char *, name) |
| 87 | − __field(__u32, value) | |
| 91 | + __field(__u64, value) | |
| 88 | 92 | ), |
| 89 | 93 | |
| 90 | 94 | TP_fast_assign( |
| @@ -92,7 +96,7 @@ TRACE_EVENT(kvm_arm_set_dreg32, · 1 unmodified line | ||
| 92 | 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 | 102 | TRACE_DEFINE_SIZEOF(__u64); |
| @@ -282,7 +282,7 @@ static unsigned long vgic_mmio_read_vcpuif(struct kvm_vcpu *vcpu, · 281 unmodified lines | ||
| 282 | 282 | case GIC_CPU_PRIMASK: |
| 283 | 283 | /* |
| 284 | 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 | 286 | * GICC_PMR.Priority, so we expose the upper five bits of |
| 287 | 287 | * priority mask to userspace using the lower bits in the |
| 288 | 288 | * unsigned long. |
| @@ -329,7 +329,7 @@ static void vgic_mmio_write_vcpuif(struct kvm_vcpu *vcpu, · 40 unmodified lines | ||
| 329 | 329 | case GIC_CPU_PRIMASK: |
| 330 | 330 | /* |
| 331 | 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 | 333 | * GICC_PMR.Priority, so we expose the upper five bits of |
| 334 | 334 | * priority mask to userspace using the lower bits in the |
| 335 | 335 | * unsigned long. |
| @@ -60,6 +60,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) · 59 unmodified lines | ||
| 60 | 60 | u32 val = cpuif->vgic_lr[lr]; |
| 61 | 61 | u32 cpuid, intid = val & GICH_LR_VIRTUALID; |
| 62 | 62 | struct vgic_irq *irq; |
| 63 | + bool deactivated; | |
| 63 | 64 | |
| 64 | 65 | /* Extract the source vCPU id from the LR */ |
| 65 | 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 | 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 | 81 | irq->active = !!(val & GICH_LR_ACTIVE_BIT); |
| 80 | 82 | |
| 81 | 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 | 98 | if (irq->config == VGIC_CONFIG_LEVEL && !(val & GICH_LR_STATE)) |
| 97 | 99 | irq->pending_latch = false; |
| 98 | 100 | |
| 99 | − /* | |
| 100 | − * Level-triggered mapped IRQs are special because we only | |
| 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 | − } | |
| 101 | + /* Handle resampling for mapped interrupts if required */ | |
| 102 | + vgic_irq_handle_resampling(irq, deactivated, val & GICH_LR_PENDING_BIT); | |
| 129 | 103 | |
| 130 | 104 | raw_spin_unlock(&irq->irq_lock); |
| 131 | 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 | 46 | u32 intid, cpuid; |
| 47 | 47 | struct vgic_irq *irq; |
| 48 | 48 | bool is_v2_sgi = false; |
| 49 | + bool deactivated; | |
| 49 | 50 | |
| 50 | 51 | cpuid = val & GICH_LR_PHYSID_CPUID; |
| 51 | 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 | 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 | 74 | irq->active = !!(val & ICH_LR_ACTIVE_BIT); |
| 73 | 75 | |
| 74 | 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 | 91 | if (irq->config == VGIC_CONFIG_LEVEL && !(val & ICH_LR_STATE)) |
| 90 | 92 | irq->pending_latch = false; |
| 91 | 93 | |
| 92 | − /* | |
| 93 | − * Level-triggered mapped IRQs are special because we only | |
| 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 | − } | |
| 94 | + /* Handle resampling for mapped interrupts if required */ | |
| 95 | + vgic_irq_handle_resampling(irq, deactivated, val & ICH_LR_PENDING_BIT); | |
| 122 | 96 | |
| 123 | 97 | raw_spin_unlock(&irq->irq_lock); |
| 124 | 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 | 106 | if (intid >= VGIC_MIN_LPI) |
| 107 | 107 | return vgic_get_lpi(kvm, intid); |
| 108 | 108 | |
| 109 | − WARN(1, "Looking up struct vgic_irq for reserved INTID"); | |
| 110 | 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 | 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 | 169 | bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq, |
| 170 | 170 | unsigned long flags); |
| 171 | 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 | 175 | int vgic_check_ioaddr(struct kvm *kvm, phys_addr_t *ioaddr, |
| 174 | 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 | 1339 | return dt_virt; |
| 1340 | 1340 | } |
| 1341 | 1341 | |
| 1342 | −#if CONFIG_PGTABLE_LEVELS > 3 | |
| 1343 | 1342 | int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot) |
| 1344 | 1343 | { |
| 1345 | 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 | 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 | 1356 | int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot) |
| 1368 | 1357 | { |
| 1369 | 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 | 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 | 1378 | int pmd_clear_huge(pmd_t *pmdp) |
| 1382 | 1379 | { |
| 1383 | 1380 | if (!pmd_sect(READ_ONCE(*pmdp))) |
| @@ -1385,7 +1382,6 @@ int pmd_clear_huge(pmd_t *pmdp) · 1 unmodified line | ||
| 1385 | 1382 | pmd_clear(pmdp); |
| 1386 | 1383 | return 1; |
| 1387 | 1384 | } |
| 1388 | −#endif | |
| 1389 | 1385 | |
| 1390 | 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 | 823 | return ret; |
| 824 | 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 | 839 | /* ST: *(size *)(dst + off) = imm */ |
| 827 | 840 | case BPF_ST | BPF_MEM | BPF_W: |
| 828 | 841 | case BPF_ST | BPF_MEM | BPF_H: |
| @@ -44,7 +44,6 @@ config H8300_H8MAX · 43 unmodified lines | ||
| 44 | 44 | bool "H8MAX" |
| 45 | 45 | select H83069 |
| 46 | 46 | select RAMKERNEL |
| 47 | − select HAVE_IDE | |
| 48 | 47 | help |
| 49 | 48 | H8MAX Evaluation Board Support |
| 50 | 49 | More Information. (Japanese Only) |
| @@ -25,7 +25,6 @@ config IA64 · 24 unmodified lines | ||
| 25 | 25 | select HAVE_ASM_MODVERSIONS |
| 26 | 26 | select HAVE_UNSTABLE_SCHED_CLOCK |
| 27 | 27 | select HAVE_EXIT_THREAD |
| 28 | − select HAVE_IDE | |
| 29 | 28 | select HAVE_KPROBES |
| 30 | 29 | select HAVE_KRETPROBES |
| 31 | 30 | select HAVE_FTRACE_MCOUNT_RECORD |
| @@ -23,7 +23,6 @@ config M68K · 22 unmodified lines | ||
| 23 | 23 | select HAVE_DEBUG_BUGVERBOSE |
| 24 | 24 | select HAVE_EFFICIENT_UNALIGNED_ACCESS if !CPU_HAS_NO_UNALIGNED |
| 25 | 25 | select HAVE_FUTEX_CMPXCHG if MMU && FUTEX |
| 26 | − select HAVE_IDE | |
| 27 | 26 | select HAVE_MOD_ARCH_SPECIFIC |
| 28 | 27 | select HAVE_UID16 |
| 29 | 28 | select MMU_GATHER_NO_RANGE if MMU |
| @@ -33,6 +33,7 @@ config MAC · 32 unmodified lines | ||
| 33 | 33 | depends on MMU |
| 34 | 34 | select MMU_MOTOROLA if MMU |
| 35 | 35 | select HAVE_ARCH_NVRAM_OPS |
| 36 | + select HAVE_PATA_PLATFORM | |
| 36 | 37 | select LEGACY_TIMER_TICK |
| 37 | 38 | help |
| 38 | 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 | 26 | DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); |
| 27 | 27 | |
| 28 | 28 | static struct clk_lookup m525x_clk_lookup[] = { |
| 29 | − CLKDEV_INIT(NULL, "pll.0", &pll), | |
| 29 | + CLKDEV_INIT(NULL, "pll.0", &clk_pll), | |
| 30 | 30 | CLKDEV_INIT(NULL, "sys.0", &clk_sys), |
| 31 | 31 | CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), |
| 32 | 32 | CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), |
| @@ -71,7 +71,6 @@ config MIPS · 70 unmodified lines | ||
| 71 | 71 | select HAVE_FUNCTION_TRACER |
| 72 | 72 | select HAVE_GCC_PLUGINS |
| 73 | 73 | select HAVE_GENERIC_VDSO |
| 74 | − select HAVE_IDE | |
| 75 | 74 | select HAVE_IOREMAP_PROT |
| 76 | 75 | select HAVE_IRQ_EXIT_ON_IRQ_STACK |
| 77 | 76 | select HAVE_IRQ_TIME_ACCOUNTING |
| @@ -1355,6 +1355,9 @@ jeq_common: · 1354 unmodified lines | ||
| 1355 | 1355 | } |
| 1356 | 1356 | break; |
| 1357 | 1357 | |
| 1358 | + case BPF_ST | BPF_NOSPEC: /* speculation barrier */ | |
| 1359 | + break; | |
| 1360 | + | |
| 1358 | 1361 | case BPF_ST | BPF_B | BPF_MEM: |
| 1359 | 1362 | case BPF_ST | BPF_H | BPF_MEM: |
| 1360 | 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 | 60 | vma = find_vma(mm, addr); |
| 61 | 61 | if (TASK_SIZE - len >= addr && |
| 62 | − (!vma || addr + len <= vma->vm_start)) | |
| 62 | + (!vma || addr + len <= vm_start_gap(vma))) | |
| 63 | 63 | return addr; |
| 64 | 64 | } |
| 65 | 65 | |
| @@ -3,7 +3,6 @@ config PARISC · 2 unmodified lines | ||
| 3 | 3 | def_bool y |
| 4 | 4 | select ARCH_32BIT_OFF_T if !64BIT |
| 5 | 5 | select ARCH_MIGHT_HAVE_PC_PARPORT |
| 6 | − select HAVE_IDE | |
| 7 | 6 | select HAVE_FUNCTION_TRACER |
| 8 | 7 | select HAVE_FUNCTION_GRAPH_TRACER |
| 9 | 8 | select HAVE_SYSCALL_TRACEPOINTS |
| @@ -220,7 +220,6 @@ config PPC · 219 unmodified lines | ||
| 220 | 220 | select HAVE_HARDLOCKUP_DETECTOR_ARCH if PPC_BOOK3S_64 && SMP |
| 221 | 221 | select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH |
| 222 | 222 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx) |
| 223 | − select HAVE_IDE | |
| 224 | 223 | select HAVE_IOREMAP_PROT |
| 225 | 224 | select HAVE_IRQ_EXIT_ON_IRQ_STACK |
| 226 | 225 | select HAVE_IRQ_TIME_ACCOUNTING |
| @@ -27,6 +27,13 @@ KASAN_SANITIZE := n · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ |
| 29 | 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 | 37 | asflags-y := -D__VDSO64__ -s |
| 31 | 38 | |
| 32 | 39 | targets += vdso64.lds |
| @@ -2697,8 +2697,10 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu) · 2696 unmodified lines | ||
| 2697 | 2697 | HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP | HFSCR_PREFIX; |
| 2698 | 2698 | if (cpu_has_feature(CPU_FTR_HVMODE)) { |
| 2699 | 2699 | vcpu->arch.hfscr &= mfspr(SPRN_HFSCR); |
| 2700 | +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM | |
| 2700 | 2701 | if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) |
| 2701 | 2702 | vcpu->arch.hfscr |= HFSCR_TM; |
| 2703 | +#endif | |
| 2702 | 2704 | } |
| 2703 | 2705 | if (cpu_has_feature(CPU_FTR_TM_COMP)) |
| 2704 | 2706 | vcpu->arch.hfscr |= HFSCR_TM; |
| @@ -302,6 +302,9 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) · 301 unmodified lines | ||
| 302 | 302 | if (vcpu->kvm->arch.l1_ptcr == 0) |
| 303 | 303 | return H_NOT_AVAILABLE; |
| 304 | 304 | |
| 305 | + if (MSR_TM_TRANSACTIONAL(vcpu->arch.shregs.msr)) | |
| 306 | + return H_BAD_MODE; | |
| 307 | + | |
| 305 | 308 | /* copy parameters in */ |
| 306 | 309 | hv_ptr = kvmppc_get_gpr(vcpu, 4); |
| 307 | 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 | 325 | if (l2_hv.vcpu_token >= NR_CPUS) |
| 323 | 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 | 345 | /* translate lpid */ |
| 326 | 346 | l2 = kvmhv_get_nested(vcpu->kvm, l2_hv.lpid, true); |
| 327 | 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 | 318 | mtspr(SPRN_HDEC, hdec); |
| 319 | 319 | |
| 320 | +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM | |
| 321 | +tm_return_to_guest: | |
| 322 | +#endif | |
| 320 | 323 | mtspr(SPRN_DAR, vcpu->arch.shregs.dar); |
| 321 | 324 | mtspr(SPRN_DSISR, vcpu->arch.shregs.dsisr); |
| 322 | 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 | 418 | * is in real suspend mode and is trying to transition to |
| 416 | 419 | * transactional mode. |
| 417 | 420 | */ |
| 418 | − if (local_paca->kvm_hstate.fake_suspend && | |
| 421 | + if (!local_paca->kvm_hstate.fake_suspend && | |
| 419 | 422 | (vcpu->arch.shregs.msr & MSR_TS_S)) { |
| 420 | 423 | if (kvmhv_p9_tm_emulation_early(vcpu)) { |
| 421 | − /* Prevent it being handled again. */ | |
| 422 | − trap = 0; | |
| 424 | + /* | |
| 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 | 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 | 514 | * If we are in real mode, only switch MMU on after the MMU is |
| 500 | 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 | 521 | __mtmsrd(msr, 0); |
| 503 | 522 | |
| 504 | 523 | end_timing(vcpu); |
| @@ -242,6 +242,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) · 241 unmodified lines | ||
| 242 | 242 | * value so we can restore it on the way out. |
| 243 | 243 | */ |
| 244 | 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 | 256 | args.rets = &args.args[be32_to_cpu(args.nargs)]; |
| 246 | 257 | |
| 247 | 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 | 280 | fail: |
| 270 | 281 | /* |
| 271 | 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 | |
| 273 | − * can't fail the RTAS call. So fail right out to userspace, | |
| 274 | − * which should kill the guest. | |
| 283 | + * args pointer or nargs/nret values that would overflow the | |
| 284 | + * array. That means we can't get to the args, and so we can't | |
| 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 | 295 | return rc; |
| 277 | 296 | } |
| @@ -2048,9 +2048,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 2047 unmodified lines | ||
| 2048 | 2048 | { |
| 2049 | 2049 | struct kvm_enable_cap cap; |
| 2050 | 2050 | r = -EFAULT; |
| 2051 | − vcpu_load(vcpu); | |
| 2052 | 2051 | if (copy_from_user(&cap, argp, sizeof(cap))) |
| 2053 | 2052 | goto out; |
| 2053 | + vcpu_load(vcpu); | |
| 2054 | 2054 | r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); |
| 2055 | 2055 | vcpu_put(vcpu); |
| 2056 | 2056 | break; |
| @@ -2074,9 +2074,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 17 unmodified lines | ||
| 2074 | 2074 | case KVM_DIRTY_TLB: { |
| 2075 | 2075 | struct kvm_dirty_tlb dirty; |
| 2076 | 2076 | r = -EFAULT; |
| 2077 | − vcpu_load(vcpu); | |
| 2078 | 2077 | if (copy_from_user(&dirty, argp, sizeof(dirty))) |
| 2079 | 2078 | goto out; |
| 2079 | + vcpu_load(vcpu); | |
| 2080 | 2080 | r = kvm_vcpu_ioctl_dirty_tlb(vcpu, &dirty); |
| 2081 | 2081 | vcpu_put(vcpu); |
| 2082 | 2082 | break; |
| @@ -240,3 +240,13 @@ void __init setup_kuap(bool disabled) · 239 unmodified lines | ||
| 240 | 240 | mtspr(SPRN_MD_AP, MD_APG_KUAP); |
| 241 | 241 | } |
| 242 | 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 | 738 | break; |
| 739 | 739 | |
| 740 | + /* | |
| 741 | + * BPF_ST NOSPEC (speculation barrier) | |
| 742 | + */ | |
| 743 | + case BPF_ST | BPF_NOSPEC: | |
| 744 | + break; | |
| 745 | + | |
| 740 | 746 | /* |
| 741 | 747 | * BPF_ST(X) |
| 742 | 748 | */ |
| @@ -627,6 +627,12 @@ emit_clear: · 626 unmodified lines | ||
| 627 | 627 | } |
| 628 | 628 | break; |
| 629 | 629 | |
| 630 | + /* | |
| 631 | + * BPF_ST NOSPEC (speculation barrier) | |
| 632 | + */ | |
| 633 | + case BPF_ST | BPF_NOSPEC: | |
| 634 | + break; | |
| 635 | + | |
| 630 | 636 | /* |
| 631 | 637 | * BPF_ST(X) |
| 632 | 638 | */ |
| @@ -42,6 +42,7 @@ static int pasemi_system_reset_exception(struct pt_regs *regs) · 41 unmodified lines | ||
| 42 | 42 | switch (regs->msr & SRR1_WAKEMASK) { |
| 43 | 43 | case SRR1_WAKEDEC: |
| 44 | 44 | set_dec(1); |
| 45 | + break; | |
| 45 | 46 | case SRR1_WAKEEE: |
| 46 | 47 | /* |
| 47 | 48 | * Handle these when interrupts get re-enabled and we take |
| @@ -77,7 +77,7 @@ · 76 unmodified lines | ||
| 77 | 77 | #include "../../../../drivers/pci/pci.h" |
| 78 | 78 | |
| 79 | 79 | DEFINE_STATIC_KEY_FALSE(shared_processor); |
| 80 | −EXPORT_SYMBOL_GPL(shared_processor); | |
| 80 | +EXPORT_SYMBOL(shared_processor); | |
| 81 | 81 | |
| 82 | 82 | int CMO_PrPSP = -1; |
| 83 | 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 | 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 | 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 | 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 | 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 | 138 | walk_stackframe(task, NULL, save_wchan, &pc); |
| 139 | + put_task_stack(task); | |
| 140 | + } | |
| 137 | 141 | return pc; |
| 138 | 142 | } |
| 139 | 143 | |
| @@ -30,23 +30,23 @@ ENTRY(__asm_copy_from_user) · 29 unmodified lines | ||
| 30 | 30 | * t0 - end of uncopied dst |
| 31 | 31 | */ |
| 32 | 32 | add t0, a0, a2 |
| 33 | − bgtu a0, t0, 5f | |
| 34 | 33 | |
| 35 | 34 | /* |
| 36 | 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 | 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 | 43 | * a0 - start of dst |
| 44 | 44 | * t1 - start of aligned dst |
| 45 | 45 | */ |
| 46 | 46 | addi t1, a0, SZREG-1 |
| 47 | 47 | andi t1, t1, ~(SZREG-1) |
| 48 | 48 | /* dst is already aligned, skip */ |
| 49 | − beq a0, t1, .Lskip_first_bytes | |
| 49 | + beq a0, t1, .Lskip_align_dst | |
| 50 | 50 | 1: |
| 51 | 51 | /* a5 - one byte for copying data */ |
| 52 | 52 | fixup lb a5, 0(a1), 10f |
| @@ -55,7 +55,7 @@ ENTRY(__asm_copy_from_user) · 2 unmodified lines | ||
| 55 | 55 | addi a0, a0, 1 /* dst */ |
| 56 | 56 | bltu a0, t1, 1b /* t1 - start of aligned dst */ |
| 57 | 57 | |
| 58 | −.Lskip_first_bytes: | |
| 58 | +.Lskip_align_dst: | |
| 59 | 59 | /* |
| 60 | 60 | * Now dst is aligned. |
| 61 | 61 | * Use shift-copy if src is misaligned. |
| @@ -72,10 +72,9 @@ ENTRY(__asm_copy_from_user) · 10 unmodified lines | ||
| 72 | 72 | * |
| 73 | 73 | * a0 - start of aligned dst |
| 74 | 74 | * a1 - start of aligned src |
| 75 | − * a3 - a1 & mask:(SZREG-1) | |
| 76 | 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 | 78 | 2: |
| 80 | 79 | fixup REG_L a4, 0(a1), 10f |
| 81 | 80 | fixup REG_L a5, SZREG(a1), 10f |
| @@ -97,7 +96,7 @@ ENTRY(__asm_copy_from_user) · 15 unmodified lines | ||
| 97 | 96 | addi a1, a1, 8*SZREG |
| 98 | 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 | 100 | j .Lbyte_copy_tail |
| 102 | 101 | |
| 103 | 102 | .Lshift_copy: |
| @@ -107,7 +106,7 @@ ENTRY(__asm_copy_from_user) · 3 unmodified lines | ||
| 107 | 106 | * For misaligned copy we still perform aligned word copy, but |
| 108 | 107 | * we need to use the value fetched from the previous iteration and |
| 109 | 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 | 111 | * a0 - start of aligned dst |
| 113 | 112 | * a1 - start of src |
| @@ -117,7 +116,7 @@ ENTRY(__asm_copy_from_user) · 3 unmodified lines | ||
| 117 | 116 | */ |
| 118 | 117 | /* calculating aligned word boundary for dst */ |
| 119 | 118 | andi t1, t0, ~(SZREG-1) |
| 120 | − /* Converting unaligned src to aligned arc */ | |
| 119 | + /* Converting unaligned src to aligned src */ | |
| 121 | 120 | andi a1, a1, ~(SZREG-1) |
| 122 | 121 | |
| 123 | 122 | /* |
| @@ -125,11 +124,11 @@ ENTRY(__asm_copy_from_user) · 1 unmodified line | ||
| 125 | 124 | * t3 - prev shift |
| 126 | 125 | * t4 - current shift |
| 127 | 126 | */ |
| 128 | − slli t3, a3, LGREG | |
| 127 | + slli t3, a3, 3 /* converting bytes in a3 to bits */ | |
| 129 | 128 | li a5, SZREG*8 |
| 130 | 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 | 132 | fixup REG_L a5, 0(a1), 10f |
| 134 | 133 | |
| 135 | 134 | 3: |
| @@ -161,7 +160,7 @@ ENTRY(__asm_copy_from_user) · 25 unmodified lines | ||
| 161 | 160 | * a1 - start of remaining src |
| 162 | 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 | 164 | 4: |
| 166 | 165 | fixup lb a5, 0(a1), 10f |
| 167 | 166 | addi a1, a1, 1 /* src */ |
| @@ -169,7 +168,7 @@ ENTRY(__asm_copy_from_user) · 1 unmodified line | ||
| 169 | 168 | addi a0, a0, 1 /* dst */ |
| 170 | 169 | bltu a0, t0, 4b /* t0 - end of dst */ |
| 171 | 170 | |
| 172 | −5: | |
| 171 | +.Lout_copy_user: | |
| 173 | 172 | /* Disable access to user memory */ |
| 174 | 173 | csrc CSR_STATUS, t6 |
| 175 | 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, | |
| 131 | − * limit the memory size via mem. | |
| 130 | + * The default maximal physical memory size is -PAGE_OFFSET for 32-bit kernel, | |
| 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 | 139 | static phys_addr_t memory_limit = -PAGE_OFFSET; |
| 140 | +#endif | |
| 134 | 141 | |
| 135 | 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 | 160 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 154 | 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 | 163 | phys_addr_t dram_end; |
| 157 | 164 | |
| 158 | 165 | #ifdef CONFIG_XIP_KERNEL |
| @@ -175,14 +182,21 @@ static void __init setup_bootmem(void) · 16 unmodified lines | ||
| 175 | 182 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); |
| 176 | 183 | |
| 177 | 184 | dram_end = memblock_end_of_DRAM(); |
| 185 | + | |
| 186 | +#ifndef CONFIG_64BIT | |
| 178 | 187 | /* |
| 179 | 188 | * memblock allocator is not aware of the fact that last 4K bytes of |
| 180 | 189 | * the addressable memory can not be mapped because of IS_ERR_VALUE |
| 181 | 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 | 197 | if (max_mapped_addr == (dram_end - 1)) |
| 185 | 198 | memblock_set_current_limit(max_mapped_addr - 4096); |
| 199 | +#endif | |
| 186 | 200 | |
| 187 | 201 | min_low_pfn = PFN_UP(memblock_start_of_DRAM()); |
| 188 | 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 | 584 | BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0); |
| 571 | 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 | 595 | pt_ops.alloc_pte = alloc_pte_early; |
| 574 | 596 | pt_ops.get_pte_virt = get_pte_virt_early; |
| 575 | 597 | #ifndef __PAGETABLE_PMD_FOLDED |
| @@ -709,6 +731,8 @@ static void __init setup_vm_final(void) · 133 unmodified lines | ||
| 709 | 731 | if (start <= __pa(PAGE_OFFSET) && |
| 710 | 732 | __pa(PAGE_OFFSET) < end) |
| 711 | 733 | start = __pa(PAGE_OFFSET); |
| 734 | + if (end >= __pa(PAGE_OFFSET) + memory_limit) | |
| 735 | + end = __pa(PAGE_OFFSET) + memory_limit; | |
| 712 | 736 | |
| 713 | 737 | map_size = best_map_size(start, end - start); |
| 714 | 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 | 1251 | return -1; |
| 1252 | 1252 | break; |
| 1253 | 1253 | |
| 1254 | + /* speculation barrier */ | |
| 1255 | + case BPF_ST | BPF_NOSPEC: | |
| 1256 | + break; | |
| 1257 | + | |
| 1254 | 1258 | case BPF_ST | BPF_MEM | BPF_B: |
| 1255 | 1259 | case BPF_ST | BPF_MEM | BPF_H: |
| 1256 | 1260 | case BPF_ST | BPF_MEM | BPF_W: |
| @@ -939,6 +939,10 @@ out_be: · 938 unmodified lines | ||
| 939 | 939 | emit_ld(rd, 0, RV_REG_T1, ctx); |
| 940 | 940 | break; |
| 941 | 941 | |
| 942 | + /* speculation barrier */ | |
| 943 | + case BPF_ST | BPF_NOSPEC: | |
| 944 | + break; | |
| 945 | + | |
| 942 | 946 | /* ST: *(size *)(dst + off) = imm */ |
| 943 | 947 | case BPF_ST | BPF_MEM | BPF_B: |
| 944 | 948 | emit_imm(RV_REG_T1, imm, ctx); |
| @@ -9,16 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <asm/errno.h> |
| 10 | 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 | 12 | .section .dma.text,"ax" |
| 23 | 13 | /* |
| 24 | 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 | 17 | * affects a few functions that are not performance-relevant. |
| 28 | 18 | */ |
| 29 | 19 | .macro BR_EX_DMA_r14 |
| 30 | −#ifdef CC_USING_EXPOLINE | |
| 31 | − jg __dma__s390_indirect_jump_r14 | |
| 32 | −#else | |
| 33 | − br %r14 | |
| 34 | −#endif | |
| 20 | + larl %r1,0f | |
| 21 | + ex 0,0(%r1) | |
| 22 | + j . | |
| 23 | +0: br %r14 | |
| 35 | 24 | .endm |
| 36 | 25 | |
| 37 | 26 | /* |
| @@ -5,7 +5,12 @@ CONFIG_WATCH_QUEUE=y · 4 unmodified lines | ||
| 5 | 5 | CONFIG_AUDIT=y |
| 6 | 6 | CONFIG_NO_HZ_IDLE=y |
| 7 | 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 | 12 | CONFIG_PREEMPT=y |
| 13 | +CONFIG_SCHED_CORE=y | |
| 9 | 14 | CONFIG_BSD_PROCESS_ACCT=y |
| 10 | 15 | CONFIG_BSD_PROCESS_ACCT_V3=y |
| 11 | 16 | CONFIG_TASKSTATS=y |
| @@ -28,14 +33,13 @@ CONFIG_CGROUP_DEVICE=y · 16 unmodified lines | ||
| 28 | 33 | CONFIG_CGROUP_CPUACCT=y |
| 29 | 34 | CONFIG_CGROUP_PERF=y |
| 30 | 35 | CONFIG_CGROUP_BPF=y |
| 36 | +CONFIG_CGROUP_MISC=y | |
| 31 | 37 | CONFIG_NAMESPACES=y |
| 32 | 38 | CONFIG_USER_NS=y |
| 33 | 39 | CONFIG_CHECKPOINT_RESTORE=y |
| 34 | 40 | CONFIG_SCHED_AUTOGROUP=y |
| 35 | 41 | CONFIG_EXPERT=y |
| 36 | 42 | # CONFIG_SYSFS_SYSCALL is not set |
| 37 | −CONFIG_BPF_LSM=y | |
| 38 | −CONFIG_BPF_SYSCALL=y | |
| 39 | 43 | CONFIG_USERFAULTFD=y |
| 40 | 44 | # CONFIG_COMPAT_BRK is not set |
| 41 | 45 | CONFIG_PROFILING=y |
| @@ -76,6 +80,7 @@ CONFIG_BLK_DEV_THROTTLING=y · 34 unmodified lines | ||
| 76 | 80 | CONFIG_BLK_WBT=y |
| 77 | 81 | CONFIG_BLK_CGROUP_IOLATENCY=y |
| 78 | 82 | CONFIG_BLK_CGROUP_IOCOST=y |
| 83 | +CONFIG_BLK_CGROUP_IOPRIO=y | |
| 79 | 84 | CONFIG_BLK_INLINE_ENCRYPTION=y |
| 80 | 85 | CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y |
| 81 | 86 | CONFIG_PARTITION_ADVANCED=y |
| @@ -95,6 +100,7 @@ CONFIG_CLEANCACHE=y · 13 unmodified lines | ||
| 95 | 100 | CONFIG_FRONTSWAP=y |
| 96 | 101 | CONFIG_CMA_DEBUG=y |
| 97 | 102 | CONFIG_CMA_DEBUGFS=y |
| 103 | +CONFIG_CMA_SYSFS=y | |
| 98 | 104 | CONFIG_CMA_AREAS=7 |
| 99 | 105 | CONFIG_MEM_SOFT_DIRTY=y |
| 100 | 106 | CONFIG_ZSWAP=y |
| @@ -158,6 +164,7 @@ CONFIG_IPV6_RPL_LWTUNNEL=y · 57 unmodified lines | ||
| 158 | 164 | CONFIG_MPTCP=y |
| 159 | 165 | CONFIG_NETFILTER=y |
| 160 | 166 | CONFIG_BRIDGE_NETFILTER=m |
| 167 | +CONFIG_NETFILTER_NETLINK_HOOK=m | |
| 161 | 168 | CONFIG_NF_CONNTRACK=m |
| 162 | 169 | CONFIG_NF_CONNTRACK_SECMARK=y |
| 163 | 170 | CONFIG_NF_CONNTRACK_EVENTS=y |
| @@ -280,6 +287,7 @@ CONFIG_IP_VS_FTP=m · 116 unmodified lines | ||
| 280 | 287 | CONFIG_IP_VS_PE_SIP=m |
| 281 | 288 | CONFIG_NFT_FIB_IPV4=m |
| 282 | 289 | CONFIG_NF_TABLES_ARP=y |
| 290 | +CONFIG_NF_LOG_IPV4=m | |
| 283 | 291 | CONFIG_IP_NF_IPTABLES=m |
| 284 | 292 | CONFIG_IP_NF_MATCH_AH=m |
| 285 | 293 | CONFIG_IP_NF_MATCH_ECN=m |
| @@ -384,12 +392,11 @@ CONFIG_VSOCKETS=m · 98 unmodified lines | ||
| 384 | 392 | CONFIG_VIRTIO_VSOCKETS=m |
| 385 | 393 | CONFIG_NETLINK_DIAG=m |
| 386 | 394 | CONFIG_CGROUP_NET_PRIO=y |
| 387 | −CONFIG_BPF_JIT=y | |
| 388 | 395 | CONFIG_NET_PKTGEN=m |
| 389 | 396 | CONFIG_PCI=y |
| 390 | −CONFIG_PCI_IOV=y | |
| 391 | 397 | # CONFIG_PCIEASPM is not set |
| 392 | 398 | CONFIG_PCI_DEBUG=y |
| 399 | +CONFIG_PCI_IOV=y | |
| 393 | 400 | CONFIG_HOTPLUG_PCI=y |
| 394 | 401 | CONFIG_HOTPLUG_PCI_S390=y |
| 395 | 402 | CONFIG_DEVTMPFS=y |
| @@ -436,7 +443,7 @@ CONFIG_MD_MULTIPATH=m · 40 unmodified lines | ||
| 436 | 443 | CONFIG_MD_FAULTY=m |
| 437 | 444 | CONFIG_MD_CLUSTER=m |
| 438 | 445 | CONFIG_BCACHE=m |
| 439 | −CONFIG_BLK_DEV_DM=m | |
| 446 | +CONFIG_BLK_DEV_DM=y | |
| 440 | 447 | CONFIG_DM_UNSTRIPED=m |
| 441 | 448 | CONFIG_DM_CRYPT=m |
| 442 | 449 | CONFIG_DM_SNAPSHOT=m |
| @@ -453,6 +460,7 @@ CONFIG_DM_MULTIPATH_ST=m · 10 unmodified lines | ||
| 453 | 460 | CONFIG_DM_MULTIPATH_HST=m |
| 454 | 461 | CONFIG_DM_MULTIPATH_IOA=m |
| 455 | 462 | CONFIG_DM_DELAY=m |
| 463 | +CONFIG_DM_INIT=y | |
| 456 | 464 | CONFIG_DM_UEVENT=y |
| 457 | 465 | CONFIG_DM_FLAKEY=m |
| 458 | 466 | CONFIG_DM_VERITY=m |
| @@ -495,6 +503,7 @@ CONFIG_NLMON=m · 36 unmodified lines | ||
| 495 | 503 | # CONFIG_NET_VENDOR_GOOGLE is not set |
| 496 | 504 | # CONFIG_NET_VENDOR_HUAWEI is not set |
| 497 | 505 | # CONFIG_NET_VENDOR_INTEL is not set |
| 506 | +# CONFIG_NET_VENDOR_MICROSOFT is not set | |
| 498 | 507 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 499 | 508 | CONFIG_MLX4_EN=m |
| 500 | 509 | CONFIG_MLX5_CORE=m |
| @@ -551,7 +560,6 @@ CONFIG_INPUT_EVDEV=y · 50 unmodified lines | ||
| 551 | 560 | CONFIG_LEGACY_PTY_COUNT=0 |
| 552 | 561 | CONFIG_VIRTIO_CONSOLE=m |
| 553 | 562 | CONFIG_HW_RANDOM_VIRTIO=m |
| 554 | −CONFIG_RAW_DRIVER=m | |
| 555 | 563 | CONFIG_HANGCHECK_TIMER=m |
| 556 | 564 | CONFIG_TN3270_FS=y |
| 557 | 565 | CONFIG_PPS=m |
| @@ -574,7 +582,6 @@ CONFIG_SYNC_FILE=y · 16 unmodified lines | ||
| 574 | 582 | CONFIG_VFIO=m |
| 575 | 583 | CONFIG_VFIO_PCI=m |
| 576 | 584 | CONFIG_VFIO_MDEV=m |
| 577 | −CONFIG_VFIO_MDEV_DEVICE=m | |
| 578 | 585 | CONFIG_VIRTIO_PCI=m |
| 579 | 586 | CONFIG_VIRTIO_BALLOON=m |
| 580 | 587 | CONFIG_VIRTIO_INPUT=y |
| @@ -619,6 +626,7 @@ CONFIG_FUSE_FS=y · 38 unmodified lines | ||
| 619 | 626 | CONFIG_CUSE=m |
| 620 | 627 | CONFIG_VIRTIO_FS=m |
| 621 | 628 | CONFIG_OVERLAY_FS=m |
| 629 | +CONFIG_NETFS_STATS=y | |
| 622 | 630 | CONFIG_FSCACHE=m |
| 623 | 631 | CONFIG_CACHEFILES=m |
| 624 | 632 | CONFIG_ISO9660_FS=y |
| @@ -654,7 +662,6 @@ CONFIG_NFSD_V3_ACL=y · 29 unmodified lines | ||
| 654 | 662 | CONFIG_NFSD_V4=y |
| 655 | 663 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 656 | 664 | CONFIG_CIFS=m |
| 657 | −CONFIG_CIFS_STATS2=y | |
| 658 | 665 | CONFIG_CIFS_WEAK_PW_HASH=y |
| 659 | 666 | CONFIG_CIFS_UPCALL=y |
| 660 | 667 | CONFIG_CIFS_XATTR=y |
| @@ -682,6 +689,7 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y · 21 unmodified lines | ||
| 682 | 689 | CONFIG_SECURITY_SELINUX_DISABLE=y |
| 683 | 690 | CONFIG_SECURITY_LOCKDOWN_LSM=y |
| 684 | 691 | CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y |
| 692 | +CONFIG_SECURITY_LANDLOCK=y | |
| 685 | 693 | CONFIG_INTEGRITY_SIGNATURE=y |
| 686 | 694 | CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y |
| 687 | 695 | CONFIG_IMA=y |
| @@ -696,6 +704,7 @@ CONFIG_CRYPTO_CRYPTD=m · 8 unmodified lines | ||
| 696 | 704 | CONFIG_CRYPTO_TEST=m |
| 697 | 705 | CONFIG_CRYPTO_DH=m |
| 698 | 706 | CONFIG_CRYPTO_ECDH=m |
| 707 | +CONFIG_CRYPTO_ECDSA=m | |
| 699 | 708 | CONFIG_CRYPTO_ECRDSA=m |
| 700 | 709 | CONFIG_CRYPTO_SM2=m |
| 701 | 710 | CONFIG_CRYPTO_CURVE25519=m |
| @@ -843,7 +852,6 @@ CONFIG_FAULT_INJECTION_DEBUG_FS=y · 141 unmodified lines | ||
| 843 | 852 | CONFIG_FAIL_FUNCTION=y |
| 844 | 853 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y |
| 845 | 854 | CONFIG_LKDTM=m |
| 846 | −CONFIG_TEST_LIST_SORT=y | |
| 847 | 855 | CONFIG_TEST_MIN_HEAP=y |
| 848 | 856 | CONFIG_TEST_SORT=y |
| 849 | 857 | CONFIG_KPROBES_SANITY_TEST=y |
| @@ -853,3 +861,4 @@ CONFIG_PERCPU_TEST=m · 3 unmodified lines | ||
| 853 | 861 | CONFIG_ATOMIC64_SELFTEST=y |
| 854 | 862 | CONFIG_TEST_BITOPS=m |
| 855 | 863 | CONFIG_TEST_BPF=m |
| 864 | +CONFIG_TEST_LIVEPATCH=m | |
| @@ -4,6 +4,11 @@ CONFIG_WATCH_QUEUE=y · 3 unmodified lines | ||
| 4 | 4 | CONFIG_AUDIT=y |
| 5 | 5 | CONFIG_NO_HZ_IDLE=y |
| 6 | 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 | 12 | CONFIG_BSD_PROCESS_ACCT=y |
| 8 | 13 | CONFIG_BSD_PROCESS_ACCT_V3=y |
| 9 | 14 | CONFIG_TASKSTATS=y |
| @@ -26,14 +31,13 @@ CONFIG_CGROUP_DEVICE=y · 16 unmodified lines | ||
| 26 | 31 | CONFIG_CGROUP_CPUACCT=y |
| 27 | 32 | CONFIG_CGROUP_PERF=y |
| 28 | 33 | CONFIG_CGROUP_BPF=y |
| 34 | +CONFIG_CGROUP_MISC=y | |
| 29 | 35 | CONFIG_NAMESPACES=y |
| 30 | 36 | CONFIG_USER_NS=y |
| 31 | 37 | CONFIG_CHECKPOINT_RESTORE=y |
| 32 | 38 | CONFIG_SCHED_AUTOGROUP=y |
| 33 | 39 | CONFIG_EXPERT=y |
| 34 | 40 | # CONFIG_SYSFS_SYSCALL is not set |
| 35 | −CONFIG_BPF_LSM=y | |
| 36 | −CONFIG_BPF_SYSCALL=y | |
| 37 | 41 | CONFIG_USERFAULTFD=y |
| 38 | 42 | # CONFIG_COMPAT_BRK is not set |
| 39 | 43 | CONFIG_PROFILING=y |
| @@ -70,6 +74,7 @@ CONFIG_BLK_DEV_THROTTLING=y · 30 unmodified lines | ||
| 70 | 74 | CONFIG_BLK_WBT=y |
| 71 | 75 | CONFIG_BLK_CGROUP_IOLATENCY=y |
| 72 | 76 | CONFIG_BLK_CGROUP_IOCOST=y |
| 77 | +CONFIG_BLK_CGROUP_IOPRIO=y | |
| 73 | 78 | CONFIG_BLK_INLINE_ENCRYPTION=y |
| 74 | 79 | CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y |
| 75 | 80 | CONFIG_PARTITION_ADVANCED=y |
| @@ -87,6 +92,7 @@ CONFIG_KSM=y · 11 unmodified lines | ||
| 87 | 92 | CONFIG_TRANSPARENT_HUGEPAGE=y |
| 88 | 93 | CONFIG_CLEANCACHE=y |
| 89 | 94 | CONFIG_FRONTSWAP=y |
| 95 | +CONFIG_CMA_SYSFS=y | |
| 90 | 96 | CONFIG_CMA_AREAS=7 |
| 91 | 97 | CONFIG_MEM_SOFT_DIRTY=y |
| 92 | 98 | CONFIG_ZSWAP=y |
| @@ -149,6 +155,7 @@ CONFIG_IPV6_RPL_LWTUNNEL=y · 56 unmodified lines | ||
| 149 | 155 | CONFIG_MPTCP=y |
| 150 | 156 | CONFIG_NETFILTER=y |
| 151 | 157 | CONFIG_BRIDGE_NETFILTER=m |
| 158 | +CONFIG_NETFILTER_NETLINK_HOOK=m | |
| 152 | 159 | CONFIG_NF_CONNTRACK=m |
| 153 | 160 | CONFIG_NF_CONNTRACK_SECMARK=y |
| 154 | 161 | CONFIG_NF_CONNTRACK_EVENTS=y |
| @@ -271,6 +278,7 @@ CONFIG_IP_VS_FTP=m · 116 unmodified lines | ||
| 271 | 278 | CONFIG_IP_VS_PE_SIP=m |
| 272 | 279 | CONFIG_NFT_FIB_IPV4=m |
| 273 | 280 | CONFIG_NF_TABLES_ARP=y |
| 281 | +CONFIG_NF_LOG_IPV4=m | |
| 274 | 282 | CONFIG_IP_NF_IPTABLES=m |
| 275 | 283 | CONFIG_IP_NF_MATCH_AH=m |
| 276 | 284 | CONFIG_IP_NF_MATCH_ECN=m |
| @@ -374,11 +382,10 @@ CONFIG_VSOCKETS=m · 97 unmodified lines | ||
| 374 | 382 | CONFIG_VIRTIO_VSOCKETS=m |
| 375 | 383 | CONFIG_NETLINK_DIAG=m |
| 376 | 384 | CONFIG_CGROUP_NET_PRIO=y |
| 377 | −CONFIG_BPF_JIT=y | |
| 378 | 385 | CONFIG_NET_PKTGEN=m |
| 379 | 386 | CONFIG_PCI=y |
| 380 | −CONFIG_PCI_IOV=y | |
| 381 | 387 | # CONFIG_PCIEASPM is not set |
| 388 | +CONFIG_PCI_IOV=y | |
| 382 | 389 | CONFIG_HOTPLUG_PCI=y |
| 383 | 390 | CONFIG_HOTPLUG_PCI_S390=y |
| 384 | 391 | CONFIG_UEVENT_HELPER=y |
| @@ -427,7 +434,7 @@ CONFIG_MD_MULTIPATH=m · 42 unmodified lines | ||
| 427 | 434 | CONFIG_MD_FAULTY=m |
| 428 | 435 | CONFIG_MD_CLUSTER=m |
| 429 | 436 | CONFIG_BCACHE=m |
| 430 | −CONFIG_BLK_DEV_DM=m | |
| 437 | +CONFIG_BLK_DEV_DM=y | |
| 431 | 438 | CONFIG_DM_UNSTRIPED=m |
| 432 | 439 | CONFIG_DM_CRYPT=m |
| 433 | 440 | CONFIG_DM_SNAPSHOT=m |
| @@ -444,6 +451,7 @@ CONFIG_DM_MULTIPATH_ST=m · 10 unmodified lines | ||
| 444 | 451 | CONFIG_DM_MULTIPATH_HST=m |
| 445 | 452 | CONFIG_DM_MULTIPATH_IOA=m |
| 446 | 453 | CONFIG_DM_DELAY=m |
| 454 | +CONFIG_DM_INIT=y | |
| 447 | 455 | CONFIG_DM_UEVENT=y |
| 448 | 456 | CONFIG_DM_FLAKEY=m |
| 449 | 457 | CONFIG_DM_VERITY=m |
| @@ -487,6 +495,7 @@ CONFIG_NLMON=m · 37 unmodified lines | ||
| 487 | 495 | # CONFIG_NET_VENDOR_GOOGLE is not set |
| 488 | 496 | # CONFIG_NET_VENDOR_HUAWEI is not set |
| 489 | 497 | # CONFIG_NET_VENDOR_INTEL is not set |
| 498 | +# CONFIG_NET_VENDOR_MICROSOFT is not set | |
| 490 | 499 | # CONFIG_NET_VENDOR_MARVELL is not set |
| 491 | 500 | CONFIG_MLX4_EN=m |
| 492 | 501 | CONFIG_MLX5_CORE=m |
| @@ -543,7 +552,6 @@ CONFIG_INPUT_EVDEV=y · 50 unmodified lines | ||
| 543 | 552 | CONFIG_LEGACY_PTY_COUNT=0 |
| 544 | 553 | CONFIG_VIRTIO_CONSOLE=m |
| 545 | 554 | CONFIG_HW_RANDOM_VIRTIO=m |
| 546 | −CONFIG_RAW_DRIVER=m | |
| 547 | 555 | CONFIG_HANGCHECK_TIMER=m |
| 548 | 556 | CONFIG_TN3270_FS=y |
| 549 | 557 | # CONFIG_PTP_1588_CLOCK is not set |
| @@ -566,7 +574,6 @@ CONFIG_SYNC_FILE=y · 16 unmodified lines | ||
| 566 | 574 | CONFIG_VFIO=m |
| 567 | 575 | CONFIG_VFIO_PCI=m |
| 568 | 576 | CONFIG_VFIO_MDEV=m |
| 569 | −CONFIG_VFIO_MDEV_DEVICE=m | |
| 570 | 577 | CONFIG_VIRTIO_PCI=m |
| 571 | 578 | CONFIG_VIRTIO_BALLOON=m |
| 572 | 579 | CONFIG_VIRTIO_INPUT=y |
| @@ -607,6 +614,7 @@ CONFIG_FUSE_FS=y · 34 unmodified lines | ||
| 607 | 614 | CONFIG_CUSE=m |
| 608 | 615 | CONFIG_VIRTIO_FS=m |
| 609 | 616 | CONFIG_OVERLAY_FS=m |
| 617 | +CONFIG_NETFS_STATS=y | |
| 610 | 618 | CONFIG_FSCACHE=m |
| 611 | 619 | CONFIG_CACHEFILES=m |
| 612 | 620 | CONFIG_ISO9660_FS=y |
| @@ -642,7 +650,6 @@ CONFIG_NFSD_V3_ACL=y · 29 unmodified lines | ||
| 642 | 650 | CONFIG_NFSD_V4=y |
| 643 | 651 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 644 | 652 | CONFIG_CIFS=m |
| 645 | −CONFIG_CIFS_STATS2=y | |
| 646 | 653 | CONFIG_CIFS_WEAK_PW_HASH=y |
| 647 | 654 | CONFIG_CIFS_UPCALL=y |
| 648 | 655 | CONFIG_CIFS_XATTR=y |
| @@ -669,6 +676,7 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y · 20 unmodified lines | ||
| 669 | 676 | CONFIG_SECURITY_SELINUX_DISABLE=y |
| 670 | 677 | CONFIG_SECURITY_LOCKDOWN_LSM=y |
| 671 | 678 | CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y |
| 679 | +CONFIG_SECURITY_LANDLOCK=y | |
| 672 | 680 | CONFIG_INTEGRITY_SIGNATURE=y |
| 673 | 681 | CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y |
| 674 | 682 | CONFIG_IMA=y |
| @@ -684,6 +692,7 @@ CONFIG_CRYPTO_CRYPTD=m · 9 unmodified lines | ||
| 684 | 692 | CONFIG_CRYPTO_TEST=m |
| 685 | 693 | CONFIG_CRYPTO_DH=m |
| 686 | 694 | CONFIG_CRYPTO_ECDH=m |
| 695 | +CONFIG_CRYPTO_ECDSA=m | |
| 687 | 696 | CONFIG_CRYPTO_ECRDSA=m |
| 688 | 697 | CONFIG_CRYPTO_SM2=m |
| 689 | 698 | CONFIG_CRYPTO_CURVE25519=m |
| @@ -754,6 +763,7 @@ CONFIG_CRC8=m · 64 unmodified lines | ||
| 754 | 763 | CONFIG_DMA_CMA=y |
| 755 | 764 | CONFIG_CMA_SIZE_MBYTES=0 |
| 756 | 765 | CONFIG_PRINTK_TIME=y |
| 766 | +CONFIG_DYNAMIC_DEBUG=y | |
| 757 | 767 | CONFIG_DEBUG_INFO=y |
| 758 | 768 | CONFIG_DEBUG_INFO_DWARF4=y |
| 759 | 769 | CONFIG_GDB_SCRIPTS=y |
| @@ -781,3 +791,4 @@ CONFIG_LKDTM=m · 21 unmodified lines | ||
| 781 | 791 | CONFIG_PERCPU_TEST=m |
| 782 | 792 | CONFIG_ATOMIC64_SELFTEST=y |
| 783 | 793 | CONFIG_TEST_BPF=m |
| 794 | +CONFIG_TEST_LIVEPATCH=m | |
| @@ -29,9 +29,9 @@ CONFIG_PARTITION_ADVANCED=y · 28 unmodified lines | ||
| 29 | 29 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| 30 | 30 | # CONFIG_COMPACTION is not set |
| 31 | 31 | # CONFIG_MIGRATION is not set |
| 32 | −# CONFIG_BOUNCE is not set | |
| 33 | 32 | CONFIG_NET=y |
| 34 | 33 | # CONFIG_IUCV is not set |
| 34 | +# CONFIG_PCPU_DEV_REFCNT is not set | |
| 35 | 35 | # CONFIG_ETHTOOL_NETLINK is not set |
| 36 | 36 | CONFIG_DEVTMPFS=y |
| 37 | 37 | CONFIG_BLK_DEV_RAM=y |
| @@ -51,7 +51,6 @@ CONFIG_ZFCP=y · 13 unmodified lines | ||
| 51 | 51 | # CONFIG_SERIO is not set |
| 52 | 52 | # CONFIG_HVC_IUCV is not set |
| 53 | 53 | # CONFIG_HW_RANDOM_S390 is not set |
| 54 | −CONFIG_RAW_DRIVER=y | |
| 55 | 54 | # CONFIG_HMC_DRV is not set |
| 56 | 55 | # CONFIG_S390_TAPE is not set |
| 57 | 56 | # CONFIG_VMCP is not set |
| @@ -19,6 +19,7 @@ void ftrace_caller(void); · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | extern char ftrace_graph_caller_end; |
| 21 | 21 | extern unsigned long ftrace_plt; |
| 22 | +extern void *ftrace_func; | |
| 22 | 23 | |
| 23 | 24 | struct dyn_arch_ftrace { }; |
| 24 | 25 | |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | * trampoline (ftrace_plt), which clobbers also r1. |
| 41 | 41 | */ |
| 42 | 42 | |
| 43 | +void *ftrace_func __read_mostly = ftrace_stub; | |
| 43 | 44 | unsigned long ftrace_plt; |
| 44 | 45 | |
| 45 | 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 | 87 | int ftrace_update_ftrace_func(ftrace_func_t func) |
| 87 | 88 | { |
| 89 | + ftrace_func = func; | |
| 88 | 90 | return 0; |
| 89 | 91 | } |
| 90 | 92 | |
| @@ -59,13 +59,13 @@ ENTRY(ftrace_caller) · 58 unmodified lines | ||
| 59 | 59 | #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES |
| 60 | 60 | aghik %r2,%r0,-MCOUNT_INSN_SIZE |
| 61 | 61 | lgrl %r4,function_trace_op |
| 62 | − lgrl %r1,ftrace_trace_function | |
| 62 | + lgrl %r1,ftrace_func | |
| 63 | 63 | #else |
| 64 | 64 | lgr %r2,%r0 |
| 65 | 65 | aghi %r2,-MCOUNT_INSN_SIZE |
| 66 | 66 | larl %r4,function_trace_op |
| 67 | 67 | lg %r4,0(%r4) |
| 68 | − larl %r1,ftrace_trace_function | |
| 68 | + larl %r1,ftrace_func | |
| 69 | 69 | lg %r1,0(%r1) |
| 70 | 70 | #endif |
| 71 | 71 | lgr %r3,%r14 |
| @@ -745,7 +745,7 @@ static int __init cpumf_pmu_init(void) · 744 unmodified lines | ||
| 745 | 745 | if (!cf_dbg) { |
| 746 | 746 | pr_err("Registration of s390dbf(cpum_cf) failed\n"); |
| 747 | 747 | return -ENOMEM; |
| 748 | − }; | |
| 748 | + } | |
| 749 | 749 | debug_register_view(cf_dbg, &debug_sprintf_view); |
| 750 | 750 | |
| 751 | 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 | 29 | $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32) |
| 30 | 30 | |
| 31 | 31 | obj-y += vdso32_wrapper.o |
| 32 | +targets += vdso32.lds | |
| 32 | 33 | CPPFLAGS_vdso32.lds += -P -C -U$(ARCH) |
| 33 | 34 | |
| 34 | 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 | 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 | 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 | 1153 | break; |
| 1154 | 1154 | } |
| 1155 | 1155 | break; |
| 1156 | + /* | |
| 1157 | + * BPF_NOSPEC (speculation barrier) | |
| 1158 | + */ | |
| 1159 | + case BPF_ST | BPF_NOSPEC: | |
| 1160 | + break; | |
| 1156 | 1161 | /* |
| 1157 | 1162 | * BPF_ST(X) |
| 1158 | 1163 | */ |
| @@ -39,7 +39,6 @@ config SUPERH · 38 unmodified lines | ||
| 39 | 39 | select HAVE_FUTEX_CMPXCHG if FUTEX |
| 40 | 40 | select HAVE_FTRACE_MCOUNT_RECORD |
| 41 | 41 | select HAVE_HW_BREAKPOINT |
| 42 | − select HAVE_IDE if HAS_IOPORT_MAP | |
| 43 | 42 | select HAVE_IOREMAP_PROT if MMU && !X2TLB |
| 44 | 43 | select HAVE_KERNEL_BZIP2 |
| 45 | 44 | select HAVE_KERNEL_GZIP |
| @@ -19,7 +19,6 @@ config SPARC · 18 unmodified lines | ||
| 19 | 19 | select OF |
| 20 | 20 | select OF_PROMTREE |
| 21 | 21 | select HAVE_ASM_MODVERSIONS |
| 22 | − select HAVE_IDE | |
| 23 | 22 | select HAVE_ARCH_KGDB if !SMP || SPARC64 |
| 24 | 23 | select HAVE_ARCH_TRACEHOOK |
| 25 | 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 | 1287 | return 1; |
| 1288 | 1288 | break; |
| 1289 | 1289 | } |
| 1290 | + /* speculation barrier */ | |
| 1291 | + case BPF_ST | BPF_NOSPEC: | |
| 1292 | + break; | |
| 1290 | 1293 | /* ST: *(size *)(dst + off) = imm */ |
| 1291 | 1294 | case BPF_ST | BPF_MEM | BPF_W: |
| 1292 | 1295 | case BPF_ST | BPF_MEM | BPF_H: |
| @@ -202,7 +202,6 @@ config X86 · 201 unmodified lines | ||
| 202 | 202 | select HAVE_FUNCTION_TRACER |
| 203 | 203 | select HAVE_GCC_PLUGINS |
| 204 | 204 | select HAVE_HW_BREAKPOINT |
| 205 | − select HAVE_IDE | |
| 206 | 205 | select HAVE_IOREMAP_PROT |
| 207 | 206 | select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 |
| 208 | 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 | 237 | for_each_present_cpu(i) { |
| 238 | 238 | if (i == 0) |
| 239 | 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 | 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 | 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, | |
| 83 | − enum jump_label_type type, | |
| 84 | − int init) | |
| 82 | +static __always_inline void | |
| 83 | +__jump_label_transform(struct jump_entry *entry, | |
| 84 | + enum jump_label_type type, | |
| 85 | + int init) | |
| 85 | 86 | { |
| 86 | 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 | 683 | #endif |
| 684 | 684 | |
| 685 | −#if CONFIG_PGTABLE_LEVELS > 3 | |
| 686 | 685 | /** |
| 687 | 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 | 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 | 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 | 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 | 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 | 780 | return 0; |
| 784 | 781 | } |
| 785 | −#endif | |
| 786 | 782 | |
| 787 | 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 | 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 | 1229 | /* ST: *(u8*)(dst_reg + off) = imm */ |
| 1223 | 1230 | case BPF_ST | BPF_MEM | BPF_B: |
| 1224 | 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 | 1886 | i++; |
| 1887 | 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 | 1895 | /* ST: *(u8*)(dst_reg + off) = imm */ |
| 1890 | 1896 | case BPF_ST | BPF_MEM | BPF_H: |
| 1891 | 1897 | case BPF_ST | BPF_MEM | BPF_B: |
| @@ -327,7 +327,6 @@ config XTENSA_PLATFORM_ISS · 326 unmodified lines | ||
| 327 | 327 | |
| 328 | 328 | config XTENSA_PLATFORM_XT2000 |
| 329 | 329 | bool "XT2000" |
| 330 | − select HAVE_IDE | |
| 331 | 330 | help |
| 332 | 331 | XT2000 is the name of Tensilica's feature-rich emulation platform. |
| 333 | 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 | 1440 | return -1; |
| 1441 | 1441 | |
| 1442 | 1442 | iocg_commit_bio(ctx->iocg, wait->bio, wait->abs_cost, cost); |
| 1443 | + wait->committed = true; | |
| 1443 | 1444 | |
| 1444 | 1445 | /* |
| 1445 | 1446 | * autoremove_wake_function() removes the wait entry only when it |
| 1446 | − * actually changed the task state. We want the wait always | |
| 1447 | − * removed. Remove explicitly and use default_wake_function(). | |
| 1447 | + * actually changed the task state. We want the wait always removed. | |
| 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 | 1452 | default_wake_function(wq_entry, mode, flags, key); |
| 1453 | + list_del_init_careful(&wq_entry->entry); | |
| 1453 | 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 | 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 | 518 | static int blk_mq_sched_alloc_tags(struct request_queue *q, |
| 530 | 519 | struct blk_mq_hw_ctx *hctx, |
| 531 | 520 | unsigned int hctx_idx) |
| @@ -539,8 +528,10 @@ static int blk_mq_sched_alloc_tags(struct request_queue *q, · 7 unmodified lines | ||
| 539 | 528 | return -ENOMEM; |
| 540 | 529 | |
| 541 | 530 | ret = blk_mq_alloc_rqs(set, hctx->sched_tags, hctx_idx, q->nr_requests); |
| 542 | − if (ret) | |
| 543 | − blk_mq_sched_free_tags(set, hctx, hctx_idx); | |
| 531 | + if (ret) { | |
| 532 | + blk_mq_free_rq_map(hctx->sched_tags, set->flags); | |
| 533 | + hctx->sched_tags = NULL; | |
| 534 | + } | |
| 544 | 535 | |
| 545 | 536 | return ret; |
| 546 | 537 | } |
| @@ -1079,10 +1079,9 @@ static void disk_release(struct device *dev) · 1078 unmodified lines | ||
| 1079 | 1079 | disk_release_events(disk); |
| 1080 | 1080 | kfree(disk->random); |
| 1081 | 1081 | xa_destroy(&disk->part_tbl); |
| 1082 | − bdput(disk->part0); | |
| 1083 | 1082 | if (test_bit(GD_QUEUE_REF, &disk->state) && disk->queue) |
| 1084 | 1083 | blk_put_queue(disk->queue); |
| 1085 | − kfree(disk); | |
| 1084 | + bdput(disk->part0); /* frees the disk */ | |
| 1086 | 1085 | } |
| 1087 | 1086 | struct class block_class = { |
| 1088 | 1087 | .name = "block", |
| @@ -370,7 +370,7 @@ config ACPI_TABLE_UPGRADE · 369 unmodified lines | ||
| 370 | 370 | config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD |
| 371 | 371 | bool "Override ACPI tables from built-in initrd" |
| 372 | 372 | depends on ACPI_TABLE_UPGRADE |
| 373 | − depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION="" | |
| 373 | + depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION_NONE | |
| 374 | 374 | help |
| 375 | 375 | This option provides functionality to override arbitrary ACPI tables |
| 376 | 376 | from built-in uncompressed initrd. |
| @@ -9,6 +9,42 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/module.h> |
| 10 | 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 | 49 | * Presentation of attributes which are defined for INT1045 |
| 14 | 50 | * They are: |
| @@ -23,15 +59,14 @@ static ssize_t name##_show(struct device *dev,\ · 8 unmodified lines | ||
| 23 | 59 | char *buf)\ |
| 24 | 60 | {\ |
| 25 | 61 | struct acpi_device *acpi_dev = dev_get_drvdata(dev);\ |
| 26 | − unsigned long long val;\ | |
| 27 | − acpi_status status;\ | |
| 62 | + struct pch_fivr_resp fivr_resp;\ | |
| 63 | + int status;\ | |
| 28 | 64 | \ |
| 29 | − status = acpi_evaluate_integer(acpi_dev->handle, #method,\ | |
| 30 | − NULL, &val);\ | |
| 31 | − if (ACPI_SUCCESS(status))\ | |
| 32 | − return sprintf(buf, "%d\n", (int)val);\ | |
| 33 | − else\ | |
| 34 | − return -EINVAL;\ | |
| 65 | + status = pch_fivr_read(acpi_dev->handle, #method, &fivr_resp);\ | |
| 66 | + if (status)\ | |
| 67 | + return status;\ | |
| 68 | +\ | |
| 69 | + return sprintf(buf, "%llu\n", fivr_resp.result);\ | |
| 35 | 70 | } |
| 36 | 71 | |
| 37 | 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 | 427 | * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. |
| 435 | 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 | 462 | acpi_dev_get_irqresource(res, irq->interrupts[index], |
| 470 | 463 | irq->triggering, irq->polarity, |
| 471 | − irq->shareable, irq_is_legacy(irq)); | |
| 464 | + irq->shareable, true); | |
| 472 | 465 | break; |
| 473 | 466 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
| 474 | 467 | ext_irq = &ares->data.extended_irq; |
| @@ -860,11 +860,9 @@ EXPORT_SYMBOL(acpi_dev_present); · 859 unmodified lines | ||
| 860 | 860 | * Return the next match of ACPI device if another matching device was present |
| 861 | 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 | 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 | 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 | 878 | match.hrv = hrv; |
| 881 | 879 | |
| 882 | 880 | dev = bus_find_device(&acpi_bus_type, start, &match, acpi_dev_match_cb); |
| 881 | + acpi_dev_put(adev); | |
| 883 | 882 | return dev ? to_acpi_device(dev) : NULL; |
| 884 | 883 | } |
| 885 | 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 | 378 | * AMDI0006: |
| 379 | 379 | * - should use rev_id 0x0 |
| 380 | 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 | 385 | const char *hid = acpi_device_hid(adev); |
| 383 | − rev_id = 0; | |
| 386 | + rev_id = strcmp(hid, "AMDI0007") ? 0 : 2; | |
| 384 | 387 | lps0_dsm_func_mask = validate_dsm(adev->handle, |
| 385 | 388 | ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid); |
| 386 | 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 | 391 | &lps0_dsm_guid_microsoft); |
| 389 | 392 | if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") || |
| 390 | 393 | !strcmp(hid, "AMDI0005"))) { |
| 391 | 394 | lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1; |
| 392 | 395 | acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n", |
| 393 | 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 | 401 | } else { |
| 396 | 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 | 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 | 655 | * ata_pio_sector - Transfer a sector of data. |
| 642 | 656 | * @qc: Command on going |
| @@ -648,11 +662,9 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); · 5 unmodified lines | ||
| 648 | 662 | */ |
| 649 | 663 | static void ata_pio_sector(struct ata_queued_cmd *qc) |
| 650 | 664 | { |
| 651 | − int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); | |
| 652 | 665 | struct ata_port *ap = qc->ap; |
| 653 | 666 | struct page *page; |
| 654 | 667 | unsigned int offset; |
| 655 | − unsigned char *buf; | |
| 656 | 668 | |
| 657 | 669 | if (!qc->cursg) { |
| 658 | 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 | 683 | DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); |
| 672 | 684 | |
| 673 | − /* do the actual data transfer */ | |
| 674 | − buf = kmap_atomic(page); | |
| 675 | − ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write); | |
| 676 | − kunmap_atomic(buf); | |
| 685 | + /* | |
| 686 | + * Split the transfer when it splits a page boundary. Note that the | |
| 687 | + * split still has to be dword aligned like all ATA data transfers. | |
| 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)) | |
| 679 | − flush_dcache_page(page); | |
| 693 | + ata_pio_xfer(qc, page, offset, split_len); | |
| 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 | 700 | qc->curbytes += qc->sect_size; |
| 682 | 701 | qc->cursg_ofs += qc->sect_size; |
| @@ -231,6 +231,8 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device); · 230 unmodified lines | ||
| 231 | 231 | int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, |
| 232 | 232 | struct module *owner, const char *modname) |
| 233 | 233 | { |
| 234 | + int ret; | |
| 235 | + | |
| 234 | 236 | if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) |
| 235 | 237 | return -EINVAL; |
| 236 | 238 | |
| @@ -246,7 +248,11 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, · 9 unmodified lines | ||
| 246 | 248 | auxdrv->driver.bus = &auxiliary_bus_type; |
| 247 | 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 | 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 | 574 | return; |
| 575 | 575 | } |
| 576 | 576 | |
| 577 | − snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); | |
| 578 | − sysfs_remove_link(&con->kobj, buf); | |
| 577 | + if (device_is_registered(con)) { | |
| 578 | + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); | |
| 579 | + sysfs_remove_link(&con->kobj, buf); | |
| 580 | + } | |
| 579 | 581 | snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); |
| 580 | 582 | sysfs_remove_link(&sup->kobj, buf); |
| 581 | 583 | kfree(buf); |
| @@ -88,6 +88,47 @@ · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | static DEFINE_IDR(loop_index_idr); |
| 90 | 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 | 133 | static int max_part; |
| 93 | 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 | 713 | while (is_loop_device(f)) { |
| 673 | 714 | struct loop_device *l; |
| 674 | 715 | |
| 716 | + lockdep_assert_held(&loop_validate_mutex); | |
| 675 | 717 | if (f->f_mapping->host->i_rdev == bdev->bd_dev) |
| 676 | 718 | return -EBADF; |
| 677 | 719 | |
| 678 | 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 | 722 | return -EINVAL; |
| 681 | − } | |
| 723 | + /* Order wrt setting lo->lo_backing_file in loop_configure(). */ | |
| 724 | + rmb(); | |
| 682 | 725 | f = l->lo_backing_file; |
| 683 | 726 | } |
| 684 | 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 | 740 | static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, |
| 698 | 741 | unsigned int arg) |
| 699 | 742 | { |
| 700 | − struct file *file = NULL, *old_file; | |
| 701 | − int error; | |
| 702 | − bool partscan; | |
| 743 | + struct file *file = fget(arg); | |
| 744 | + struct file *old_file; | |
| 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 | 753 | if (error) |
| 706 | − return error; | |
| 754 | + goto out_putf; | |
| 707 | 755 | error = -ENXIO; |
| 708 | 756 | if (lo->lo_state != Lo_bound) |
| 709 | 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 | 761 | if (!(lo->lo_flags & LO_FLAGS_READ_ONLY)) |
| 714 | 762 | goto out_err; |
| 715 | 763 | |
| 716 | − error = -EBADF; | |
| 717 | − file = fget(arg); | |
| 718 | − if (!file) | |
| 719 | − goto out_err; | |
| 720 | − | |
| 721 | 764 | error = loop_validate_file(file, bdev); |
| 722 | 765 | if (error) |
| 723 | 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 | 783 | loop_update_dio(lo); |
| 741 | 784 | blk_mq_unfreeze_queue(lo->lo_queue); |
| 742 | 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 | 797 | * We must drop file reference outside of lo_mutex as dropping |
| 746 | 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 | 804 | return 0; |
| 753 | 805 | |
| 754 | 806 | out_err: |
| 755 | − mutex_unlock(&lo->lo_mutex); | |
| 756 | − if (file) | |
| 757 | − fput(file); | |
| 807 | + loop_global_unlock(lo, is_loop); | |
| 808 | +out_putf: | |
| 809 | + fput(file); | |
| 758 | 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 | 1188 | struct block_device *bdev, |
| 1137 | 1189 | const struct loop_config *config) |
| 1138 | 1190 | { |
| 1139 | − struct file *file; | |
| 1140 | − struct inode *inode; | |
| 1191 | + struct file *file = fget(config->fd); | |
| 1192 | + struct inode *inode; | |
| 1141 | 1193 | struct address_space *mapping; |
| 1142 | − int error; | |
| 1143 | − loff_t size; | |
| 1144 | − bool partscan; | |
| 1145 | − unsigned short bsize; | |
| 1194 | + int error; | |
| 1195 | + loff_t size; | |
| 1196 | + bool partscan; | |
| 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 | 1204 | /* This is safe, since we have a reference from open(). */ |
| 1148 | 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 | 1208 | * If we don't hold exclusive handle for the device, upgrade to it |
| 1157 | 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 | 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 | 1218 | if (error) |
| 1167 | 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 | 1294 | size = get_loop_size(lo, file); |
| 1243 | 1295 | loop_set_size(lo, size); |
| 1244 | 1296 | |
| 1297 | + /* Order wrt reading lo_state in loop_validate_file(). */ | |
| 1298 | + wmb(); | |
| 1299 | + | |
| 1245 | 1300 | lo->lo_state = Lo_bound; |
| 1246 | 1301 | if (part_shift) |
| 1247 | 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 | 1308 | * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev). |
| 1254 | 1309 | */ |
| 1255 | 1310 | bdgrab(bdev); |
| 1256 | − mutex_unlock(&lo->lo_mutex); | |
| 1311 | + loop_global_unlock(lo, is_loop); | |
| 1257 | 1312 | if (partscan) |
| 1258 | 1313 | loop_reread_partitions(lo); |
| 1259 | 1314 | if (!(mode & FMODE_EXCL)) |
| @@ -1261,13 +1316,12 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, · 1 unmodified line | ||
| 1261 | 1316 | return 0; |
| 1262 | 1317 | |
| 1263 | 1318 | out_unlock: |
| 1264 | − mutex_unlock(&lo->lo_mutex); | |
| 1319 | + loop_global_unlock(lo, is_loop); | |
| 1265 | 1320 | out_bdev: |
| 1266 | 1321 | if (!(mode & FMODE_EXCL)) |
| 1267 | 1322 | bd_abort_claiming(bdev, loop_configure); |
| 1268 | 1323 | out_putf: |
| 1269 | 1324 | fput(file); |
| 1270 | −out: | |
| 1271 | 1325 | /* This is safe: open() is still holding a reference. */ |
| 1272 | 1326 | module_put(THIS_MODULE); |
| 1273 | 1327 | return error; |
| @@ -1283,6 +1337,18 @@ static int __loop_clr_fd(struct loop_device *lo, bool release) · 9 unmodified lines | ||
| 1283 | 1337 | int lo_number; |
| 1284 | 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 | 1352 | mutex_lock(&lo->lo_mutex); |
| 1287 | 1353 | if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) { |
| 1288 | 1354 | err = -ENXIO; |
| @@ -4100,8 +4100,6 @@ again: · 4099 unmodified lines | ||
| 4100 | 4100 | |
| 4101 | 4101 | static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) |
| 4102 | 4102 | { |
| 4103 | − bool need_wait; | |
| 4104 | − | |
| 4105 | 4103 | dout("%s rbd_dev %p\n", __func__, rbd_dev); |
| 4106 | 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 | 4112 | rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; |
| 4115 | 4113 | rbd_assert(!completion_done(&rbd_dev->releasing_wait)); |
| 4116 | − need_wait = !list_empty(&rbd_dev->running_list); | |
| 4117 | − downgrade_write(&rbd_dev->lock_rwsem); | |
| 4118 | − if (need_wait) | |
| 4119 | − wait_for_completion(&rbd_dev->releasing_wait); | |
| 4120 | − up_read(&rbd_dev->lock_rwsem); | |
| 4114 | + if (list_empty(&rbd_dev->running_list)) | |
| 4115 | + return true; | |
| 4116 | + | |
| 4117 | + up_write(&rbd_dev->lock_rwsem); | |
| 4118 | + wait_for_completion(&rbd_dev->releasing_wait); | |
| 4121 | 4119 | |
| 4122 | 4120 | down_write(&rbd_dev->lock_rwsem); |
| 4123 | 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 | 4201 | if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { |
| 4204 | 4202 | down_write(&rbd_dev->lock_rwsem); |
| 4205 | 4203 | if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { |
| 4206 | − /* | |
| 4207 | − * we already know that the remote client is | |
| 4208 | − * the owner | |
| 4209 | − */ | |
| 4210 | − up_write(&rbd_dev->lock_rwsem); | |
| 4211 | − return; | |
| 4204 | + dout("%s rbd_dev %p cid %llu-%llu == owner_cid\n", | |
| 4205 | + __func__, rbd_dev, cid.gid, cid.handle); | |
| 4206 | + } else { | |
| 4207 | + rbd_set_owner_cid(rbd_dev, &cid); | |
| 4212 | 4208 | } |
| 4213 | − | |
| 4214 | − rbd_set_owner_cid(rbd_dev, &cid); | |
| 4215 | 4209 | downgrade_write(&rbd_dev->lock_rwsem); |
| 4216 | 4210 | } else { |
| 4217 | 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 | 4230 | if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { |
| 4237 | 4231 | down_write(&rbd_dev->lock_rwsem); |
| 4238 | 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 | 4234 | __func__, rbd_dev, cid.gid, cid.handle, |
| 4241 | 4235 | rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); |
| 4242 | − up_write(&rbd_dev->lock_rwsem); | |
| 4243 | − return; | |
| 4236 | + } else { | |
| 4237 | + rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); | |
| 4244 | 4238 | } |
| 4245 | − | |
| 4246 | − rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); | |
| 4247 | 4239 | downgrade_write(&rbd_dev->lock_rwsem); |
| 4248 | 4240 | } else { |
| 4249 | 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 | 4943 | disk->minors = RBD_MINORS_PER_MAJOR; |
| 4952 | 4944 | } |
| 4953 | 4945 | disk->fops = &rbd_bd_ops; |
| 4946 | + disk->private_data = rbd_dev; | |
| 4954 | 4947 | |
| 4955 | 4948 | blk_queue_flag_set(QUEUE_FLAG_NONROT, q); |
| 4956 | 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 | 773 | cmd_pkt = mhi_to_virtual(mhi_ring, ptr); |
| 774 | 774 | |
| 775 | 775 | chan = MHI_TRE_GET_CMD_CHID(cmd_pkt); |
| 776 | − mhi_chan = &mhi_cntrl->mhi_chan[chan]; | |
| 777 | − write_lock_bh(&mhi_chan->lock); | |
| 778 | − mhi_chan->ccs = MHI_TRE_GET_EV_CODE(tre); | |
| 779 | − complete(&mhi_chan->completion); | |
| 780 | − write_unlock_bh(&mhi_chan->lock); | |
| 776 | + | |
| 777 | + if (chan < mhi_cntrl->max_chan && | |
| 778 | + mhi_cntrl->mhi_chan[chan].configured) { | |
| 779 | + mhi_chan = &mhi_cntrl->mhi_chan[chan]; | |
| 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 | 789 | mhi_del_ring_element(mhi_cntrl, mhi_ring); |
| 783 | 790 | } |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | ||
| 32 | 32 | * @edl: emergency download mode firmware path (if any) |
| 33 | 33 | * @bar_num: PCI base address register to use for MHI MMIO register space |
| 34 | 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 | 38 | struct mhi_pci_dev_info { |
| 37 | 39 | const struct mhi_controller_config *config; |
| @@ -40,6 +42,7 @@ struct mhi_pci_dev_info { · 2 unmodified lines | ||
| 40 | 42 | const char *edl; |
| 41 | 43 | unsigned int bar_num; |
| 42 | 44 | unsigned int dma_data_width; |
| 45 | + bool sideband_wake; | |
| 43 | 46 | }; |
| 44 | 47 | |
| 45 | 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 | 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 | 94 | #define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \ |
| 76 | 95 | { \ |
| 77 | 96 | .num_elements = el_count, \ |
| @@ -210,7 +229,7 @@ static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = { · 132 unmodified lines | ||
| 210 | 229 | MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0), |
| 211 | 230 | MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0), |
| 212 | 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 | 233 | MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), |
| 215 | 234 | MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), |
| 216 | 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 | 261 | .edl = "qcom/sdx65m/edl.mbn", |
| 243 | 262 | .config = &modem_qcom_v1_mhiv_config, |
| 244 | 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 | 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 | 271 | .edl = "qcom/sdx55m/edl.mbn", |
| 252 | 272 | .config = &modem_qcom_v1_mhiv_config, |
| 253 | 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 | 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 | 280 | .edl = "qcom/prog_firehose_sdx24.mbn", |
| 260 | 281 | .config = &modem_qcom_v1_mhiv_config, |
| 261 | 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 | 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 | 323 | .edl = "qcom/prog_firehose_sdx24.mbn", |
| 302 | 324 | .config = &modem_quectel_em1xx_config, |
| 303 | 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 | 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 | 362 | .edl = "qcom/sdx55m/edl.mbn", |
| 340 | 363 | .config = &modem_foxconn_sdx55_config, |
| 341 | 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 | 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 | 664 | mhi_cntrl->status_cb = mhi_pci_status_cb; |
| 641 | 665 | mhi_cntrl->runtime_get = mhi_pci_runtime_get; |
| 642 | 666 | mhi_cntrl->runtime_put = mhi_pci_runtime_put; |
| 643 | − mhi_cntrl->wake_get = mhi_pci_wake_get_nop; | |
| 644 | − mhi_cntrl->wake_put = mhi_pci_wake_put_nop; | |
| 645 | − mhi_cntrl->wake_toggle = mhi_pci_wake_toggle_nop; | |
| 667 | + | |
| 668 | + if (info->sideband_wake) { | |
| 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 | 674 | err = mhi_pci_claim(mhi_cntrl, info->bar_num, DMA_BIT_MASK(info->dma_data_width)); |
| 648 | 675 | if (err) |
| @@ -34,7 +34,6 @@ static long __init parse_acpi_path(const struct efi_dev_path *node, · 33 unmodified lines | ||
| 34 | 34 | break; |
| 35 | 35 | if (!adev->pnp.unique_id && node->acpi.uid == 0) |
| 36 | 36 | break; |
| 37 | − acpi_dev_put(adev); | |
| 38 | 37 | } |
| 39 | 38 | if (!adev) |
| 40 | 39 | return -ENODEV; |
| @@ -896,6 +896,7 @@ static int __init efi_memreserve_map_root(void) · 895 unmodified lines | ||
| 896 | 896 | static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) |
| 897 | 897 | { |
| 898 | 898 | struct resource *res, *parent; |
| 899 | + int ret; | |
| 899 | 900 | |
| 900 | 901 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); |
| 901 | 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 | 910 | /* we expect a conflict with a 'System RAM' region */ |
| 910 | 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 | 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 | 630 | * @image: EFI loaded image protocol |
| 631 | 631 | * @load_addr: pointer to loaded initrd |
| 632 | 632 | * @load_size: size of loaded initrd |
| 633 | − * @soft_limit: preferred size of allocated memory for loading the initrd | |
| 634 | − * @hard_limit: minimum size of allocated memory | |
| 633 | + * @soft_limit: preferred address for loading the initrd | |
| 634 | + * @hard_limit: upper limit address for loading the initrd | |
| 635 | 635 | * |
| 636 | 636 | * Return: status code |
| 637 | 637 | */ |
| @@ -180,7 +180,10 @@ void __init efi_mokvar_table_init(void) · 179 unmodified lines | ||
| 180 | 180 | pr_err("EFI MOKvar config table is not valid\n"); |
| 181 | 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 | 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 | 62 | tbl_size = sizeof(*log_tbl) + log_tbl->size; |
| 63 | 63 | memblock_reserve(efi.tpm_log, tbl_size); |
| 64 | 64 | |
| 65 | − if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || | |
| 66 | − log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { | |
| 67 | − pr_warn(FW_BUG "TPM Final Events table missing or invalid\n"); | |
| 65 | + if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) { | |
| 66 | + pr_info("TPM Final Events table not present\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 | 70 | goto out; |
| 69 | 71 | } |
| 70 | 72 | |
| @@ -619,6 +619,13 @@ struct amdgpu_video_codec_info { · 618 unmodified lines | ||
| 619 | 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 | 629 | struct amdgpu_video_codecs { |
| 623 | 630 | const u32 codec_count; |
| 624 | 631 | const struct amdgpu_video_codec_info *codec_array; |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/slab.h> |
| 27 | 27 | #include <linux/power_supply.h> |
| 28 | 28 | #include <linux/pm_runtime.h> |
| 29 | +#include <linux/suspend.h> | |
| 29 | 30 | #include <acpi/video.h> |
| 30 | 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 | 1043 | #if defined(CONFIG_AMD_PMC) || defined(CONFIG_AMD_PMC_MODULE) |
| 1043 | 1044 | if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) { |
| 1044 | 1045 | if (adev->flags & AMD_IS_APU) |
| 1045 | − return true; | |
| 1046 | + return pm_suspend_target_state == PM_SUSPEND_TO_IDLE; | |
| 1046 | 1047 | } |
| 1047 | 1048 | #endif |
| 1048 | 1049 | return false; |
| @@ -3504,13 +3504,13 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 3503 unmodified lines | ||
| 3504 | 3504 | r = amdgpu_device_get_job_timeout_settings(adev); |
| 3505 | 3505 | if (r) { |
| 3506 | 3506 | dev_err(adev->dev, "invalid lockup_timeout parameter syntax\n"); |
| 3507 | − goto failed_unmap; | |
| 3507 | + return r; | |
| 3508 | 3508 | } |
| 3509 | 3509 | |
| 3510 | 3510 | /* early init functions */ |
| 3511 | 3511 | r = amdgpu_device_ip_early_init(adev); |
| 3512 | 3512 | if (r) |
| 3513 | − goto failed_unmap; | |
| 3513 | + return r; | |
| 3514 | 3514 | |
| 3515 | 3515 | /* doorbell bar mapping and doorbell index init*/ |
| 3516 | 3516 | amdgpu_device_doorbell_init(adev); |
| @@ -3736,10 +3736,6 @@ release_ras_con: · 219 unmodified lines | ||
| 3736 | 3736 | failed: |
| 3737 | 3737 | amdgpu_vf_error_trans_all(adev); |
| 3738 | 3738 | |
| 3739 | −failed_unmap: | |
| 3740 | − iounmap(adev->rmmio); | |
| 3741 | − adev->rmmio = NULL; | |
| 3742 | − | |
| 3743 | 3739 | return r; |
| 3744 | 3740 | } |
| 3745 | 3741 | |
| @@ -1190,6 +1190,10 @@ static const struct pci_device_id pciidlist[] = { · 1189 unmodified lines | ||
| 1190 | 1190 | /* Van Gogh */ |
| 1191 | 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 | 1197 | /* Navy_Flounder */ |
| 1194 | 1198 | {0x1002, 0x73C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVY_FLOUNDER}, |
| 1195 | 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 | 255 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) |
| 256 | 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 | 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 | 3300 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000), |
| 3301 | 3301 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000), |
| 3302 | 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 | 3304 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), |
| 3304 | 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 | 3380 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0xffffffbf, 0x00000020), |
| 3380 | 3381 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1_Vangogh, 0xffffffff, 0x00070103), |
| 3381 | 3382 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQG_CONFIG, 0x000017ff, 0x00001000), |
| 3383 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSX_DEBUG_1, 0x00010000, 0x00010020), | |
| 3382 | 3384 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), |
| 3383 | 3385 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00400000), |
| 3384 | 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 | 3447 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000), |
| 3446 | 3448 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000), |
| 3447 | 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 | 3451 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0x01030000, 0x01030000), |
| 3449 | 3452 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0x03a00000, 0x00a00000), |
| 3450 | 3453 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmLDS_CONFIG, 0x00000020, 0x00000020) |
| @@ -64,32 +64,13 @@ · 63 unmodified lines | ||
| 64 | 64 | #include "smuio_v11_0.h" |
| 65 | 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 | 67 | static const struct amd_ip_funcs nv_common_ip_funcs; |
| 75 | 68 | |
| 76 | 69 | /* Navi */ |
| 77 | 70 | static const struct amdgpu_video_codec_info nv_video_codecs_encode_array[] = |
| 78 | 71 | { |
| 79 | − { | |
| 80 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | |
| 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 | − }, | |
| 72 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, | |
| 73 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, | |
| 93 | 74 | }; |
| 94 | 75 | |
| 95 | 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 | 82 | /* Navi1x */ |
| 102 | 83 | static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] = |
| 103 | 84 | { |
| 104 | − { | |
| 105 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | |
| 106 | − .max_width = 4096, | |
| 107 | − .max_height = 4096, | |
| 108 | − .max_pixels_per_frame = 4096 * 4096, | |
| 109 | − .max_level = 3, | |
| 110 | − }, | |
| 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 | − }, | |
| 85 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, | |
| 86 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, | |
| 87 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, | |
| 88 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, | |
| 89 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, | |
| 90 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
| 91 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, | |
| 153 | 92 | }; |
| 154 | 93 | |
| 155 | 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 | 100 | /* Sienna Cichlid */ |
| 162 | 101 | static const struct amdgpu_video_codec_info sc_video_codecs_decode_array[] = |
| 163 | 102 | { |
| 164 | − { | |
| 165 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | |
| 166 | − .max_width = 4096, | |
| 167 | − .max_height = 4096, | |
| 168 | − .max_pixels_per_frame = 4096 * 4096, | |
| 169 | − .max_level = 3, | |
| 170 | − }, | |
| 171 | − { | |
| 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 | − }, | |
| 103 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, | |
| 104 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, | |
| 105 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, | |
| 106 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, | |
| 107 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, | |
| 108 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
| 109 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, | |
| 110 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, | |
| 220 | 111 | }; |
| 221 | 112 | |
| 222 | 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 | 119 | /* SRIOV Sienna Cichlid, not const since data is controlled by host */ |
| 229 | 120 | static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = |
| 230 | 121 | { |
| 231 | − { | |
| 232 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | |
| 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 | − }, | |
| 122 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, | |
| 123 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, | |
| 245 | 124 | }; |
| 246 | 125 | |
| 247 | 126 | static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array[] = |
| 248 | 127 | { |
| 249 | − { | |
| 250 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | |
| 251 | − .max_width = 4096, | |
| 252 | − .max_height = 4096, | |
| 253 | − .max_pixels_per_frame = 4096 * 4096, | |
| 254 | − .max_level = 3, | |
| 255 | − }, | |
| 256 | − { | |
| 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 | − }, | |
| 128 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, | |
| 129 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, | |
| 130 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, | |
| 131 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, | |
| 132 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, | |
| 133 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
| 134 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, | |
| 135 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, | |
| 305 | 136 | }; |
| 306 | 137 | |
| 307 | 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 | 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 | 180 | static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, |
| 337 | 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 | 197 | case CHIP_NAVY_FLOUNDER: |
| 354 | 198 | case CHIP_DIMGREY_CAVEFISH: |
| 355 | 199 | case CHIP_VANGOGH: |
| 356 | − case CHIP_YELLOW_CARP: | |
| 357 | 200 | if (encode) |
| 358 | 201 | *codecs = &nv_video_codecs_encode; |
| 359 | 202 | else |
| 360 | 203 | *codecs = &sc_video_codecs_decode; |
| 361 | 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 | 211 | case CHIP_BEIGE_GOBY: |
| 363 | 212 | if (encode) |
| 364 | 213 | *codecs = &bg_video_codecs_encode; |
| @@ -1387,7 +1236,10 @@ static int nv_common_early_init(void *handle) · 1022 unmodified lines | ||
| 1387 | 1236 | AMD_PG_SUPPORT_VCN | |
| 1388 | 1237 | AMD_PG_SUPPORT_VCN_DPG | |
| 1389 | 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 | 1243 | break; |
| 1392 | 1244 | default: |
| 1393 | 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 | 68 | err = psp_init_asd_microcode(psp, chip_name); |
| 69 | 69 | if (err) |
| 70 | − goto out; | |
| 70 | + return err; | |
| 71 | 71 | |
| 72 | 72 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); |
| 73 | 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 | 80 | } else { |
| 81 | 81 | err = amdgpu_ucode_validate(adev->psp.ta_fw); |
| 82 | 82 | if (err) |
| 83 | − goto out2; | |
| 83 | + goto out; | |
| 84 | 84 | |
| 85 | 85 | ta_hdr = (const struct ta_firmware_header_v1_0 *) |
| 86 | 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 | 106 | return 0; |
| 107 | 107 | |
| 108 | −out2: | |
| 108 | +out: | |
| 109 | 109 | release_firmware(adev->psp.ta_fw); |
| 110 | 110 | adev->psp.ta_fw = NULL; |
| 111 | −out: | |
| 112 | 111 | if (err) { |
| 113 | 112 | dev_err(adev->dev, |
| 114 | 113 | "psp v12.0: Failed to load firmware \"%s\"\n", |
| @@ -88,20 +88,8 @@ · 87 unmodified lines | ||
| 88 | 88 | /* Vega, Raven, Arcturus */ |
| 89 | 89 | static const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] = |
| 90 | 90 | { |
| 91 | − { | |
| 92 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, | |
| 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 | − }, | |
| 91 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, | |
| 92 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, | |
| 105 | 93 | }; |
| 106 | 94 | |
| 107 | 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 | 101 | /* Vega */ |
| 114 | 102 | static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] = |
| 115 | 103 | { |
| 116 | − { | |
| 117 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | |
| 118 | − .max_width = 4096, | |
| 119 | − .max_height = 4096, | |
| 120 | − .max_pixels_per_frame = 4096 * 4096, | |
| 121 | − .max_level = 3, | |
| 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 | − }, | |
| 104 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, | |
| 105 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, | |
| 106 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, | |
| 107 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, | |
| 108 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, | |
| 109 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
| 158 | 110 | }; |
| 159 | 111 | |
| 160 | 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 | 118 | /* Raven */ |
| 167 | 119 | static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] = |
| 168 | 120 | { |
| 169 | − { | |
| 170 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | |
| 171 | − .max_width = 4096, | |
| 172 | − .max_height = 4096, | |
| 173 | − .max_pixels_per_frame = 4096 * 4096, | |
| 174 | − .max_level = 3, | |
| 175 | − }, | |
| 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 | − }, | |
| 121 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, | |
| 122 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, | |
| 123 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, | |
| 124 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, | |
| 125 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, | |
| 126 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
| 127 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)}, | |
| 218 | 128 | }; |
| 219 | 129 | |
| 220 | 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 | 136 | /* Renoir, Arcturus */ |
| 227 | 137 | static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] = |
| 228 | 138 | { |
| 229 | − { | |
| 230 | − .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, | |
| 231 | − .max_width = 4096, | |
| 232 | − .max_height = 4096, | |
| 233 | − .max_pixels_per_frame = 4096 * 4096, | |
| 234 | − .max_level = 3, | |
| 235 | − }, | |
| 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 | − }, | |
| 139 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, | |
| 140 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, | |
| 141 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, | |
| 142 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, | |
| 143 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, | |
| 144 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
| 145 | + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, | |
| 278 | 146 | }; |
| 279 | 147 | |
| 280 | 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 | 2429 | max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll; |
| 2430 | 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 | 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 | 2435 | caps->aux_support = true; |
| 2436 | 2436 | |
| 2437 | 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 | 198 | REG_UPDATE(DENTIST_DISPCLK_CNTL, |
| 199 | 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 | 201 | REG_UPDATE(DENTIST_DISPCLK_CNTL, |
| 202 | 202 | DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider); |
| 203 | 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 | 190 | &clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz, |
| 191 | 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 | 197 | // DPREFCLK ??? |
| 194 | 198 | |
| 195 | 199 | /* DISPCLK */ |
| @@ -48,6 +48,21 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 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 | 66 | #define TO_CLK_MGR_DCN31(clk_mgr)\ |
| 52 | 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 | 139 | * also if safe to lower is false, we just go in the higher state |
| 125 | 140 | */ |
| 126 | 141 | if (safe_to_lower) { |
| 127 | − if (new_clocks->z9_support == DCN_Z9_SUPPORT_ALLOW && | |
| 128 | − new_clocks->z9_support != clk_mgr_base->clks.z9_support) { | |
| 142 | + if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_ALLOW && | |
| 143 | + new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) { | |
| 129 | 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 | 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 | 165 | } else { |
| 151 | − if (new_clocks->z9_support == DCN_Z9_SUPPORT_DISALLOW && | |
| 152 | − new_clocks->z9_support != clk_mgr_base->clks.z9_support) { | |
| 166 | + if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_DISALLOW && | |
| 167 | + new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) { | |
| 153 | 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 | 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 | 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 | 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 | 286 | clk_mgr->clks.p_state_change_support = true; |
| 247 | 287 | clk_mgr->clks.prev_p_state_change_support = true; |
| 248 | 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 | 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 | 300 | return false; |
| 261 | 301 | else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz) |
| 262 | 302 | return false; |
| 263 | − else if (a->z9_support != b->z9_support) | |
| 303 | + else if (a->zstate_support != b->zstate_support) | |
| 264 | 304 | return false; |
| 265 | 305 | else if (a->dtbclk_en != b->dtbclk_en) |
| 266 | 306 | return false; |
| @@ -592,6 +632,7 @@ void dcn31_clk_mgr_construct( · 325 unmodified lines | ||
| 592 | 632 | clk_mgr->base.dprefclk_ss_percentage = 0; |
| 593 | 633 | clk_mgr->base.dprefclk_ss_divider = 1000; |
| 594 | 634 | clk_mgr->base.ss_on_dprefclk = false; |
| 635 | + clk_mgr->base.dfs_ref_freq_khz = 48000; | |
| 595 | 636 | |
| 596 | 637 | clk_mgr->smu_wm_set.wm_set = (struct dcn31_watermarks *)dm_helpers_allocate_gpu_mem( |
| 597 | 638 | clk_mgr->base.base.ctx, |
| @@ -27,60 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | #define __DCN31_CLK_MGR_H__ |
| 28 | 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 | 30 | struct dcn31_watermarks; |
| 85 | 31 | |
| 86 | 32 | struct dcn31_smu_watermark_set { |
| @@ -1820,8 +1820,7 @@ bool perform_link_training_with_retries( · 1819 unmodified lines | ||
| 1820 | 1820 | */ |
| 1821 | 1821 | panel_mode = DP_PANEL_MODE_DEFAULT; |
| 1822 | 1822 | } |
| 1823 | − } else | |
| 1824 | − panel_mode = DP_PANEL_MODE_DEFAULT; | |
| 1823 | + } | |
| 1825 | 1824 | } |
| 1826 | 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 | 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 | 4917 | uint32_t default_backlight; |
| 4916 | 4918 | |
| 4917 | − if (link && | |
| 4918 | − (link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || | |
| 4919 | − link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { | |
| 4919 | + if (link && link->dpcd_sink_ext_caps.bits.oled == 1) { | |
| 4920 | 4920 | if (!dc_link_read_default_bl_aux(link, &default_backlight)) |
| 4921 | 4921 | default_backlight = 150000; |
| 4922 | 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 | 1062 | * so use only 30 bpp on DCE_VERSION_11_0. Testing with DCE 11.2 and 8.3 |
| 1063 | 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 | 1066 | pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP; |
| 1067 | 1067 | else |
| 1068 | 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 | 356 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 357 | −enum dcn_z9_support_state { | |
| 358 | − DCN_Z9_SUPPORT_UNKNOWN, | |
| 359 | − DCN_Z9_SUPPORT_ALLOW, | |
| 360 | − DCN_Z9_SUPPORT_DISALLOW, | |
| 357 | +enum dcn_zstate_support_state { | |
| 358 | + DCN_ZSTATE_SUPPORT_UNKNOWN, | |
| 359 | + DCN_ZSTATE_SUPPORT_ALLOW, | |
| 360 | + DCN_ZSTATE_SUPPORT_DISALLOW, | |
| 361 | 361 | }; |
| 362 | 362 | #endif |
| 363 | 363 | /* |
| @@ -378,7 +378,7 @@ struct dc_clocks { · 14 unmodified lines | ||
| 378 | 378 | int dramclk_khz; |
| 379 | 379 | bool p_state_change_support; |
| 380 | 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 | 382 | bool dtbclk_en; |
| 383 | 383 | #endif |
| 384 | 384 | enum dcn_pwr_state pwr_state; |
| @@ -636,6 +636,7 @@ struct dce_hwseq_registers { · 635 unmodified lines | ||
| 636 | 636 | uint32_t ODM_MEM_PWR_CTRL3; |
| 637 | 637 | uint32_t DMU_MEM_PWR_CNTL; |
| 638 | 638 | uint32_t MMHUBBUB_MEM_PWR_CNTL; |
| 639 | + uint32_t DCHUBBUB_ARB_HOSTVM_CNTL; | |
| 639 | 640 | }; |
| 640 | 641 | /* set field name */ |
| 641 | 642 | #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ |
| @@ -1110,7 +1111,8 @@ struct dce_hwseq_registers { · 468 unmodified lines | ||
| 1110 | 1111 | type DOMAIN_POWER_FORCEON;\ |
| 1111 | 1112 | type DOMAIN_POWER_GATE;\ |
| 1112 | 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 | 1117 | struct dce_hwseq_shift { |
| 1116 | 1118 | HWSEQ_REG_FIELD_LIST(uint8_t) |
| @@ -217,6 +217,8 @@ static void dpp1_dscl_set_lb( · 216 unmodified lines | ||
| 217 | 217 | const struct line_buffer_params *lb_params, |
| 218 | 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 | 222 | /* LB */ |
| 221 | 223 | if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { |
| 222 | 224 | /* DSCL caps: pixel data processed in fixed format */ |
| @@ -239,9 +241,12 @@ static void dpp1_dscl_set_lb( · 16 unmodified lines | ||
| 239 | 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 | 247 | REG_SET_2(LB_MEMORY_CTRL, 0, |
| 243 | 248 | MEMORY_CONFIG, mem_size_config, |
| 244 | − LB_MAX_PARTITIONS, 63); | |
| 249 | + LB_MAX_PARTITIONS, max_partitions); | |
| 245 | 250 | } |
| 246 | 251 | |
| 247 | 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 | 2093 | - timing->v_border_bottom; |
| 2094 | 2094 | pipes[pipe_cnt].pipe.dest.htotal = timing->h_total; |
| 2095 | 2095 | pipes[pipe_cnt].pipe.dest.vtotal = v_total; |
| 2096 | − pipes[pipe_cnt].pipe.dest.hactive = timing->h_addressable; | |
| 2097 | − pipes[pipe_cnt].pipe.dest.vactive = timing->v_addressable; | |
| 2096 | + pipes[pipe_cnt].pipe.dest.hactive = | |
| 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 | 2100 | pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE; |
| 2099 | 2101 | pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0; |
| 2100 | 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 | 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 | 3115 | void dcn20_calculate_dlg_params( |
| 3083 | 3116 | struct dc *dc, struct dc_state *context, |
| 3084 | 3117 | display_e2e_pipe_params_st *pipes, |
| @@ -3086,7 +3119,6 @@ void dcn20_calculate_dlg_params( · 1 unmodified line | ||
| 3086 | 3119 | int vlevel) |
| 3087 | 3120 | { |
| 3088 | 3121 | int i, pipe_idx; |
| 3089 | − int plane_count; | |
| 3090 | 3122 | |
| 3091 | 3123 | /* Writeback MCIF_WB arbitration parameters */ |
| 3092 | 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 | 3134 | != dm_dram_clock_change_unsupported; |
| 3103 | 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) ? | |
| 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; | |
| 3137 | + context->bw_ctx.bw.dcn.clk.zstate_support = decide_zstate_support(dc, context); | |
| 3116 | 3138 | |
| 3117 | 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 | 109 | .max_page_table_levels = 4, |
| 110 | 110 | .pte_chunk_size_kbytes = 2, |
| 111 | 111 | .meta_chunk_size_kbytes = 2, |
| 112 | + .min_meta_chunk_size_bytes = 256, | |
| 112 | 113 | .writeback_chunk_size_kbytes = 2, |
| 113 | 114 | .line_buffer_size_bits = 789504, |
| 114 | 115 | .is_line_buffer_bpp_fixed = 0, |
| @@ -383,13 +383,6 @@ bool dpp3_get_optimal_number_of_taps( · 382 unmodified lines | ||
| 383 | 383 | int min_taps_y, min_taps_c; |
| 384 | 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 | 386 | if (scl_data->viewport.width > scl_data->h_active && |
| 394 | 387 | dpp->ctx->dc->debug.max_downscale_src_width != 0 && |
| 395 | 388 | scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) |
| @@ -1440,15 +1433,6 @@ bool dpp3_construct( · 1044 unmodified lines | ||
| 1440 | 1433 | dpp->tf_shift = tf_shift; |
| 1441 | 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 | 1436 | return true; |
| 1453 | 1437 | } |
| 1454 | 1438 | |
| @@ -154,6 +154,7 @@ · 153 unmodified lines | ||
| 154 | 154 | SRI(COLOR_KEYER_BLUE, CNVC_CFG, id), \ |
| 155 | 155 | SRI(CURSOR_CONTROL, CURSOR0_, id),\ |
| 156 | 156 | SRI(OBUF_MEM_PWR_CTRL, DSCL, id),\ |
| 157 | + SRI(DSCL_MEM_PWR_STATUS, DSCL, id), \ | |
| 157 | 158 | SRI(DSCL_MEM_PWR_CTRL, DSCL, id) |
| 158 | 159 | |
| 159 | 160 | #define DPP_REG_LIST_DCN30(id)\ |
| @@ -163,8 +164,6 @@ · 3 unmodified lines | ||
| 163 | 164 | SRI(CM_SHAPER_LUT_DATA, CM, id),\ |
| 164 | 165 | SRI(CM_MEM_PWR_CTRL2, CM, id), \ |
| 165 | 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 | 167 | SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B, CM, id),\ |
| 169 | 168 | SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G, CM, id),\ |
| 170 | 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 | 1398 | dcn3_02_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; |
| 1399 | 1399 | dcn3_02_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; |
| 1400 | 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 | 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 | 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 | 1413 | dcn3_02_soc.clock_limits[i].dscclk_mhz = dcn3_02_soc.clock_limits[0].dscclk_mhz; |
| 1407 | 1414 | } |
| 1408 | 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 | 1326 | dcn3_03_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; |
| 1327 | 1327 | dcn3_03_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; |
| 1328 | 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 | 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 | 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 | 1341 | dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz; |
| 1335 | 1342 | } |
| 1336 | 1343 | /* re-init DML with updated bb */ |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | #include "dce/dmub_outbox.h" |
| 48 | 48 | #include "dc_link_dp.h" |
| 49 | 49 | #include "inc/link_dpcd.h" |
| 50 | +#include "dcn10/dcn10_hw_sequencer.h" | |
| 50 | 51 | |
| 51 | 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 | 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 | 52 | struct dc_state *context); |
| 53 | 53 | bool dcn31_is_abm_supported(struct dc *dc, |
| 54 | 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 | 57 | #endif /* __DC_HWSS_DCN31_H__ */ |
| @@ -93,7 +93,6 @@ static const struct hw_sequencer_funcs dcn31_funcs = { · 92 unmodified lines | ||
| 93 | 93 | .set_flip_control_gsl = dcn20_set_flip_control_gsl, |
| 94 | 94 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, |
| 95 | 95 | .calc_vupdate_position = dcn10_calc_vupdate_position, |
| 96 | − .apply_idle_power_optimizations = dcn30_apply_idle_power_optimizations, | |
| 97 | 96 | .set_backlight_level = dcn21_set_backlight_level, |
| 98 | 97 | .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, |
| 99 | 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 | 105 | static const struct hwseq_private_funcs dcn31_private_funcs = { |
| 107 | − .init_pipes = dcn10_init_pipes, | |
| 106 | + .init_pipes = dcn31_init_pipes, | |
| 108 | 107 | .update_plane_addr = dcn20_update_plane_addr, |
| 109 | 108 | .plane_atomic_disconnect = dcn10_plane_atomic_disconnect, |
| 110 | 109 | .update_mpcc = dcn20_update_mpcc, |
| @@ -220,6 +220,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = { · 219 unmodified lines | ||
| 220 | 220 | .sr_exit_z8_time_us = 402.0, |
| 221 | 221 | .sr_enter_plus_exit_z8_time_us = 520.0, |
| 222 | 222 | .writeback_latency_us = 12.0, |
| 223 | + .dram_channel_width_bytes = 4, | |
| 223 | 224 | .round_trip_ping_latency_dcfclk_cycles = 106, |
| 224 | 225 | .urgent_latency_pixel_data_only_us = 4.0, |
| 225 | 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 | 743 | #define HWSEQ_DCN31_REG_LIST()\ |
| 743 | 744 | SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ |
| 745 | + SR(DCHUBBUB_ARB_HOSTVM_CNTL), \ | |
| 744 | 746 | SR(DIO_MEM_PWR_CTRL), \ |
| 745 | 747 | SR(ODM_MEM_PWR_CTRL3), \ |
| 746 | 748 | SR(DMU_MEM_PWR_CNTL), \ |
| @@ -801,6 +803,7 @@ static const struct dce_hwseq_registers hwseq_reg = { · 54 unmodified lines | ||
| 801 | 803 | #define HWSEQ_DCN31_MASK_SH_LIST(mask_sh)\ |
| 802 | 804 | HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ |
| 803 | 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 | 807 | HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \ |
| 805 | 808 | HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \ |
| 806 | 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 | 1302 | hws->regs = &hwseq_reg; |
| 1300 | 1303 | hws->shifts = &hwseq_shift; |
| 1301 | 1304 | hws->masks = &hwseq_mask; |
| 1305 | + hws->wa.early_riommu_invalidation = true; | |
| 1302 | 1306 | } |
| 1303 | 1307 | return hws; |
| 1304 | 1308 | } |
| @@ -841,6 +841,9 @@ static bool CalculatePrefetchSchedule( · 840 unmodified lines | ||
| 841 | 841 | else |
| 842 | 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 | 847 | dml_print("DML: VStartup: %d\n", VStartup); |
| 845 | 848 | dml_print("DML: TCalc: %f\n", TCalc); |
| 846 | 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 | 4893 | } while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true) |
| 4891 | 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 | 4897 | if (locals->PrefetchSupported[i][j] == true && locals->VRatioInPrefetchSupported[i][j] == true) { |
| 4895 | 4898 | mode_lib->vba.BandwidthAvailableForImmediateFlip = locals->ReturnBWPerState[i][0]; |
| @@ -289,6 +289,9 @@ struct dpp_caps { · 288 unmodified lines | ||
| 289 | 289 | /* DSCL processing pixel data in fixed or float format */ |
| 290 | 290 | enum dscl_data_processing_format dscl_data_proc_format; |
| 291 | 291 | |
| 292 | + /* max LB partitions */ | |
| 293 | + unsigned int max_lb_partitions; | |
| 294 | + | |
| 292 | 295 | /* Calculates the number of partitions in the line buffer. |
| 293 | 296 | * The implementation of this function is overloaded for |
| 294 | 297 | * different versions of DSCL LB. |
| @@ -41,6 +41,7 @@ struct dce_hwseq_wa { · 40 unmodified lines | ||
| 41 | 41 | bool DEGVIDCN10_254; |
| 42 | 42 | bool DEGVIDCN21; |
| 43 | 43 | bool disallow_self_refresh_during_multi_plane_transition; |
| 44 | + bool early_riommu_invalidation; | |
| 44 | 45 | }; |
| 45 | 46 | |
| 46 | 47 | struct hwseq_wa_state { |
| @@ -101,7 +101,8 @@ · 100 unmodified lines | ||
| 101 | 101 | #define PPSMC_MSG_SetSystemVirtualSTBtoDramAddrLow 0x41 |
| 102 | 102 | |
| 103 | 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 | 107 | //PPSMC Reset Types |
| 107 | 108 | #define PPSMC_RESET_TYPE_WARM_RESET 0x00 |
| @@ -225,7 +225,8 @@ · 224 unmodified lines | ||
| 225 | 225 | __SMU_DUMMY_MAP(DisableDeterminism), \ |
| 226 | 226 | __SMU_DUMMY_MAP(SetUclkDpmMode), \ |
| 227 | 227 | __SMU_DUMMY_MAP(LightSBR), \ |
| 228 | − __SMU_DUMMY_MAP(GfxDriverResetRecovery), | |
| 228 | + __SMU_DUMMY_MAP(GfxDriverResetRecovery), \ | |
| 229 | + __SMU_DUMMY_MAP(BoardPowerCalibration), | |
| 229 | 230 | |
| 230 | 231 | #undef __SMU_DUMMY_MAP |
| 231 | 232 | #define __SMU_DUMMY_MAP(type) SMU_MSG_##type |
| @@ -34,7 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #define SMU11_DRIVER_IF_VERSION_Navy_Flounder 0xE |
| 35 | 35 | #define SMU11_DRIVER_IF_VERSION_VANGOGH 0x03 |
| 36 | 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 | 39 | /* MP Apertures */ |
| 40 | 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 | 134 | MSG_MAP(DisableDeterminism, PPSMC_MSG_DisableDeterminism, 0), |
| 135 | 135 | MSG_MAP(SetUclkDpmMode, PPSMC_MSG_SetUclkDpmMode, 0), |
| 136 | 136 | MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), |
| 137 | + MSG_MAP(BoardPowerCalibration, PPSMC_MSG_BoardPowerCalibration, 0), | |
| 137 | 138 | }; |
| 138 | 139 | |
| 139 | 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 | 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 | 477 | static int aldebaran_run_btc(struct smu_context *smu) |
| 444 | 478 | { |
| 445 | 479 | int ret; |
| @@ -447,6 +481,8 @@ static int aldebaran_run_btc(struct smu_context *smu) · 1 unmodified line | ||
| 447 | 481 | ret = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL); |
| 448 | 482 | if (ret) |
| 449 | 483 | dev_err(smu->adev->dev, "RunDcBtc failed!\n"); |
| 484 | + else | |
| 485 | + ret = aldebaran_run_board_btc(smu); | |
| 450 | 486 | |
| 451 | 487 | return ret; |
| 452 | 488 | } |
| @@ -524,16 +560,6 @@ static int aldebaran_freqs_in_same_level(int32_t frequency1, · 71 unmodified lines | ||
| 524 | 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 | 563 | static int aldebaran_get_smu_metrics_data(struct smu_context *smu, |
| 538 | 564 | MetricsMember_t member, |
| 539 | 565 | uint32_t *value) |
| @@ -834,6 +834,9 @@ long drm_ioctl(struct file *filp, · 833 unmodified lines | ||
| 834 | 834 | if (drm_dev_is_unplugged(dev)) |
| 835 | 835 | return -ENODEV; |
| 836 | 836 | |
| 837 | + if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE) | |
| 838 | + return -ENOTTY; | |
| 839 | + | |
| 837 | 840 | is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; |
| 838 | 841 | |
| 839 | 842 | if (is_driver_ioctl) { |
| @@ -2166,7 +2166,8 @@ static void · 2165 unmodified lines | ||
| 2166 | 2166 | init_vbt_missing_defaults(struct drm_i915_private *i915) |
| 2167 | 2167 | { |
| 2168 | 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 | 2172 | if (!HAS_DDI(i915) && !IS_CHERRYVIEW(i915)) |
| 2172 | 2173 | return; |
| @@ -11361,13 +11361,19 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) · 11360 unmodified lines | ||
| 11361 | 11361 | intel_ddi_init(dev_priv, PORT_B); |
| 11362 | 11362 | intel_ddi_init(dev_priv, PORT_C); |
| 11363 | 11363 | vlv_dsi_init(dev_priv); |
| 11364 | − } else if (DISPLAY_VER(dev_priv) >= 9) { | |
| 11364 | + } else if (DISPLAY_VER(dev_priv) == 10) { | |
| 11365 | 11365 | intel_ddi_init(dev_priv, PORT_A); |
| 11366 | 11366 | intel_ddi_init(dev_priv, PORT_B); |
| 11367 | 11367 | intel_ddi_init(dev_priv, PORT_C); |
| 11368 | 11368 | intel_ddi_init(dev_priv, PORT_D); |
| 11369 | 11369 | intel_ddi_init(dev_priv, PORT_E); |
| 11370 | 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 | 11377 | } else if (HAS_DDI(dev_priv)) { |
| 11372 | 11378 | u32 found; |
| 11373 | 11379 | |
| @@ -25,10 +25,8 @@ · 24 unmodified lines | ||
| 25 | 25 | #include "i915_gem_clflush.h" |
| 26 | 26 | #include "i915_gem_context.h" |
| 27 | 27 | #include "i915_gem_ioctls.h" |
| 28 | −#include "i915_sw_fence_work.h" | |
| 29 | 28 | #include "i915_trace.h" |
| 30 | 29 | #include "i915_user_extensions.h" |
| 31 | −#include "i915_memcpy.h" | |
| 32 | 30 | |
| 33 | 31 | struct eb_vma { |
| 34 | 32 | struct i915_vma *vma; |
| @@ -1456,6 +1454,10 @@ static u32 *reloc_gpu(struct i915_execbuffer *eb, · 1421 unmodified lines | ||
| 1456 | 1454 | int err; |
| 1457 | 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 | 1461 | if (!reloc_can_use_engine(engine)) { |
| 1460 | 1462 | engine = engine->gt->engine_class[COPY_ENGINE_CLASS][0]; |
| 1461 | 1463 | if (!engine) |
| @@ -2372,217 +2374,6 @@ shadow_batch_pin(struct i915_execbuffer *eb, · 910 unmodified lines | ||
| 2372 | 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 | 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 | 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 | 2475 | if (err) |
| 2677 | 2476 | goto err_unpin_batch; |
| 2678 | 2477 | |
| @@ -125,6 +125,10 @@ static int igt_gpu_reloc(void *arg) · 124 unmodified lines | ||
| 125 | 125 | intel_gt_pm_get(&eb.i915->gt); |
| 126 | 126 | |
| 127 | 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 | 132 | reloc_cache_init(&eb.reloc_cache, eb.i915); |
| 129 | 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 | 1977 | if (drm_WARN_ON(&i915->drm, !engine)) |
| 1978 | 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 | 1995 | execlist = &vgpu->submission.execlist[engine->id]; |
| 1981 | 1996 | |
| 1982 | 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 | 1145 | static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, |
| 1146 | 1146 | struct drm_i915_gem_object *src_obj, |
| 1147 | 1147 | unsigned long offset, unsigned long length, |
| 1148 | − void *dst, const void *src) | |
| 1148 | + bool *needs_clflush_after) | |
| 1149 | 1149 | { |
| 1150 | − bool needs_clflush = | |
| 1151 | − !(src_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ); | |
| 1152 | − | |
| 1153 | − if (src) { | |
| 1154 | − GEM_BUG_ON(!needs_clflush); | |
| 1155 | − i915_unaligned_memcpy_from_wc(dst, src + offset, length); | |
| 1156 | − } else { | |
| 1157 | − struct scatterlist *sg; | |
| 1150 | + unsigned int src_needs_clflush; | |
| 1151 | + unsigned int dst_needs_clflush; | |
| 1152 | + void *dst, *src; | |
| 1153 | + int ret; | |
| 1154 | + | |
| 1155 | + ret = i915_gem_object_prepare_write(dst_obj, &dst_needs_clflush); | |
| 1156 | + if (ret) | |
| 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 | 1182 | void *ptr; |
| 1159 | − unsigned int x, sg_ofs; | |
| 1160 | − unsigned long remain; | |
| 1161 | 1183 | |
| 1162 | 1184 | /* |
| 1163 | 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 | 1190 | * validate up to the end of the batch. |
| 1169 | 1191 | */ |
| 1170 | 1192 | remain = length; |
| 1171 | − if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) | |
| 1193 | + if (dst_needs_clflush & CLFLUSH_BEFORE) | |
| 1172 | 1194 | remain = round_up(remain, |
| 1173 | 1195 | boot_cpu_data.x86_clflush_size); |
| 1174 | 1196 | |
| 1175 | 1197 | ptr = dst; |
| 1176 | 1198 | x = offset_in_page(offset); |
| 1177 | − sg = i915_gem_object_get_sg(src_obj, offset >> PAGE_SHIFT, &sg_ofs, false); | |
| 1178 | − | |
| 1179 | − while (remain) { | |
| 1180 | − unsigned long sg_max = sg->length >> PAGE_SHIFT; | |
| 1181 | − | |
| 1182 | − for (; remain && sg_ofs < sg_max; sg_ofs++) { | |
| 1183 | − unsigned long len = min(remain, PAGE_SIZE - x); | |
| 1184 | − void *map; | |
| 1185 | − | |
| 1186 | − map = kmap_atomic(nth_page(sg_page(sg), sg_ofs)); | |
| 1187 | − if (needs_clflush) | |
| 1188 | − drm_clflush_virt_range(map + x, len); | |
| 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 | + for (n = offset >> PAGE_SHIFT; remain; n++) { | |
| 1200 | + int len = min(remain, PAGE_SIZE - x); | |
| 1201 | + | |
| 1202 | + src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); | |
| 1203 | + if (src_needs_clflush) | |
| 1204 | + drm_clflush_virt_range(src + x, len); | |
| 1205 | + memcpy(ptr, src + x, len); | |
| 1206 | + kunmap_atomic(src); | |
| 1207 | + | |
| 1208 | + ptr += len; | |
| 1209 | + remain -= len; | |
| 1210 | + x = 0; | |
| 1199 | 1211 | } |
| 1200 | 1212 | } |
| 1201 | 1213 | |
| 1214 | + i915_gem_object_finish_access(src_obj); | |
| 1215 | + | |
| 1202 | 1216 | memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32)); |
| 1203 | 1217 | |
| 1204 | 1218 | /* dst_obj is returned with vmap pinned */ |
| 1219 | + *needs_clflush_after = dst_needs_clflush & CLFLUSH_AFTER; | |
| 1220 | + | |
| 1205 | 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 | 1376 | if (target_cmd_index == offset) |
| 1361 | 1377 | return 0; |
| 1362 | 1378 | |
| 1379 | + if (IS_ERR(jump_whitelist)) | |
| 1380 | + return PTR_ERR(jump_whitelist); | |
| 1381 | + | |
| 1363 | 1382 | if (!test_bit(target_cmd_index, jump_whitelist)) { |
| 1364 | 1383 | DRM_DEBUG("CMD: BB_START to 0x%llx not a previously executed cmd\n", |
| 1365 | 1384 | jump_target); |
| @@ -1369,28 +1388,10 @@ static int check_bbstart(u32 *cmd, u32 offset, u32 length, · 3 unmodified lines | ||
| 1369 | 1388 | return 0; |
| 1370 | 1389 | } |
| 1371 | 1390 | |
| 1372 | −/** | |
| 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) | |
| 1391 | +static unsigned long *alloc_whitelist(u32 batch_length) | |
| 1388 | 1392 | { |
| 1389 | 1393 | unsigned long *jmp; |
| 1390 | 1394 | |
| 1391 | − if (trampoline) | |
| 1392 | − return NULL; | |
| 1393 | − | |
| 1394 | 1395 | /* |
| 1395 | 1396 | * We expect batch_length to be less than 256KiB for known users, |
| 1396 | 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 | 1416 | * @batch_offset: byte offset in the batch at which execution starts |
| 1416 | 1417 | * @batch_length: length of the commands in batch_obj |
| 1417 | 1418 | * @shadow: validated copy of the batch buffer in question |
| 1418 | − * @jump_whitelist: buffer preallocated with intel_engine_cmd_parser_alloc_jump_whitelist() | |
| 1419 | − * @shadow_map: mapping to @shadow vma | |
| 1420 | − * @batch_map: mapping to @batch vma | |
| 1419 | + * @trampoline: true if we need to trampoline into privileged execution | |
| 1421 | 1420 | * |
| 1422 | 1421 | * Parses the specified batch buffer looking for privilege violations as |
| 1423 | 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 | 1424 | * Return: non-zero if the parser finds violations or otherwise fails; -EACCES |
| 1426 | 1425 | * if the batch appears legal but should use hardware parsing |
| 1427 | 1426 | */ |
| 1427 | + | |
| 1428 | 1428 | int intel_engine_cmd_parser(struct intel_engine_cs *engine, |
| 1429 | 1429 | struct i915_vma *batch, |
| 1430 | 1430 | unsigned long batch_offset, |
| 1431 | 1431 | unsigned long batch_length, |
| 1432 | 1432 | struct i915_vma *shadow, |
| 1433 | − unsigned long *jump_whitelist, | |
| 1434 | − void *shadow_map, | |
| 1435 | − const void *batch_map) | |
| 1433 | + bool trampoline) | |
| 1436 | 1434 | { |
| 1437 | 1435 | u32 *cmd, *batch_end, offset = 0; |
| 1438 | 1436 | struct drm_i915_cmd_descriptor default_desc = noop_desc; |
| 1439 | 1437 | const struct drm_i915_cmd_descriptor *desc = &default_desc; |
| 1438 | + bool needs_clflush_after = false; | |
| 1439 | + unsigned long *jump_whitelist; | |
| 1440 | 1440 | u64 batch_addr, shadow_addr; |
| 1441 | 1441 | int ret = 0; |
| 1442 | − bool trampoline = !jump_whitelist; | |
| 1443 | 1442 | |
| 1444 | 1443 | GEM_BUG_ON(!IS_ALIGNED(batch_offset, sizeof(*cmd))); |
| 1445 | 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 | 1446 | batch->size)); |
| 1448 | 1447 | GEM_BUG_ON(!batch_length); |
| 1449 | 1448 | |
| 1450 | − cmd = copy_batch(shadow->obj, batch->obj, batch_offset, batch_length, | |
| 1451 | − shadow_map, batch_map); | |
| 1449 | + cmd = copy_batch(shadow->obj, batch->obj, | |
| 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 | 1462 | shadow_addr = gen8_canonical_addr(shadow->node.start); |
| 1454 | 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 | 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 | 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 | 1906 | int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv); |
| 1907 | 1907 | int intel_engine_init_cmd_parser(struct intel_engine_cs *engine); |
| 1908 | 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 | 1909 | int intel_engine_cmd_parser(struct intel_engine_cs *engine, |
| 1913 | 1910 | struct i915_vma *batch, |
| 1914 | 1911 | unsigned long batch_offset, |
| 1915 | 1912 | unsigned long batch_length, |
| 1916 | 1913 | struct i915_vma *shadow, |
| 1917 | − unsigned long *jump_whitelist, | |
| 1918 | − void *shadow_map, | |
| 1919 | − const void *batch_map); | |
| 1914 | + bool trampoline); | |
| 1920 | 1915 | #define I915_CMD_PARSER_TRAMPOLINE_SIZE 8 |
| 1921 | 1916 | |
| 1922 | 1917 | /* intel_device_info.c */ |
| @@ -1426,10 +1426,8 @@ i915_request_await_execution(struct i915_request *rq, · 1425 unmodified lines | ||
| 1426 | 1426 | |
| 1427 | 1427 | do { |
| 1428 | 1428 | fence = *child++; |
| 1429 | − if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { | |
| 1430 | − i915_sw_fence_set_error_once(&rq->submit, fence->error); | |
| 1429 | + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) | |
| 1431 | 1430 | continue; |
| 1432 | − } | |
| 1433 | 1431 | |
| 1434 | 1432 | if (fence->context == rq->fence.context) |
| 1435 | 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 | 1526 | do { |
| 1529 | 1527 | fence = *child++; |
| 1530 | − if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { | |
| 1531 | − i915_sw_fence_set_error_once(&rq->submit, fence->error); | |
| 1528 | + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) | |
| 1532 | 1529 | continue; |
| 1533 | − } | |
| 1534 | 1530 | |
| 1535 | 1531 | /* |
| 1536 | 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 | 325 | info->pipe_mask &= ~BIT(PIPE_C); |
| 326 | 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 | 329 | u32 dfsm = intel_de_read(dev_priv, SKL_DFSM); |
| 330 | 330 | |
| 331 | 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 | 340 | info->pipe_mask &= ~BIT(PIPE_C); |
| 341 | 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 | 345 | (dfsm & TGL_DFSM_PIPE_D_DISABLE)) { |
| 345 | 346 | info->pipe_mask &= ~BIT(PIPE_D); |
| 346 | 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 | 353 | if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE) |
| 353 | 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 | 357 | info->display.has_dmc = 0; |
| 357 | 358 | |
| 358 | − if (GRAPHICS_VER(dev_priv) >= 10 && | |
| 359 | + if (DISPLAY_VER(dev_priv) >= 10 && | |
| 359 | 360 | (dfsm & CNL_DFSM_DISPLAY_DSC_DISABLE)) |
| 360 | 361 | info->display.has_dsc = 0; |
| 361 | 362 | } |
| @@ -296,7 +296,7 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = { · 295 unmodified lines | ||
| 296 | 296 | static const struct dpu_mdp_cfg sm8250_mdp[] = { |
| 297 | 297 | { |
| 298 | 298 | .name = "top_0", .id = MDP_TOP, |
| 299 | − .base = 0x0, .len = 0x45C, | |
| 299 | + .base = 0x0, .len = 0x494, | |
| 300 | 300 | .features = 0, |
| 301 | 301 | .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ |
| 302 | 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 | 771 | dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, |
| 772 | 772 | dp_catalog->width_blanking); |
| 773 | 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 | 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 | 1526 | * running. Add the global reset just before disabling the |
| 1527 | 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 | 1530 | if (ret) { |
| 1531 | 1531 | DRM_ERROR("failed to disable DP controller\n"); |
| 1532 | 1532 | return ret; |
| @@ -219,6 +219,7 @@ static int dp_display_bind(struct device *dev, struct device *master, · 218 unmodified lines | ||
| 219 | 219 | goto end; |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | + dp->aux->drm_dev = drm; | |
| 222 | 223 | rc = dp_aux_register(dp->aux); |
| 223 | 224 | if (rc) { |
| 224 | 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 | 1312 | else |
| 1312 | 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 | 1319 | mutex_unlock(&dp->event_mutex); |
| 1315 | 1320 | |
| 1316 | 1321 | return 0; |
| @@ -142,6 +142,9 @@ static const struct iommu_flush_ops null_tlb_ops = { · 141 unmodified lines | ||
| 142 | 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 | 148 | struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent) |
| 146 | 149 | { |
| 147 | 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 | 160 | if (!ttbr1_cfg) |
| 158 | 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 | 170 | pagetable = kzalloc(sizeof(*pagetable), GFP_KERNEL); |
| 161 | 171 | if (!pagetable) |
| 162 | 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 | 311 | iommu->domain = domain; |
| 302 | 312 | msm_mmu_init(&iommu->base, dev, &funcs, MSM_MMU_IOMMU); |
| 303 | − iommu_set_fault_handler(domain, msm_fault_handler, iommu); | |
| 304 | 313 | |
| 305 | 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 | 150 | if (bo->base.dev) |
| 151 | 151 | drm_gem_object_release(&bo->base); |
| 152 | + else | |
| 153 | + dma_resv_fini(&bo->base._resv); | |
| 152 | 154 | |
| 153 | 155 | kfree(nvbo); |
| 154 | 156 | } |
| @@ -330,6 +332,10 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, · 175 unmodified lines | ||
| 330 | 332 | if (IS_ERR(nvbo)) |
| 331 | 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 | 339 | ret = nouveau_bo_init(nvbo, size, align, domain, sg, robj); |
| 334 | 340 | if (ret) |
| 335 | 341 | return ret; |
| @@ -447,7 +447,6 @@ static int rpi_touchscreen_remove(struct i2c_client *i2c) · 446 unmodified lines | ||
| 447 | 447 | drm_panel_remove(&ts->base); |
| 448 | 448 | |
| 449 | 449 | mipi_dsi_device_unregister(ts->dsi); |
| 450 | − kfree(ts->dsi); | |
| 451 | 450 | |
| 452 | 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 | 4166 | static const struct panel_desc yes_optoelectronics_ytc700tlag_05_201c = { |
| 4167 | 4167 | .modes = &yes_optoelectronics_ytc700tlag_05_201c_mode, |
| 4168 | 4168 | .num_modes = 1, |
| 4169 | − .bpc = 6, | |
| 4169 | + .bpc = 8, | |
| 4170 | 4170 | .size = { |
| 4171 | 4171 | .width = 154, |
| 4172 | 4172 | .height = 90, |
| @@ -102,6 +102,9 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, · 101 unmodified lines | ||
| 102 | 102 | return; |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | + if (!mem) | |
| 106 | + return; | |
| 107 | + | |
| 105 | 108 | man = ttm_manager_type(bdev, mem->mem_type); |
| 106 | 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 | 63 | void ttm_mem_io_free(struct ttm_device *bdev, |
| 64 | 64 | struct ttm_resource *mem) |
| 65 | 65 | { |
| 66 | + if (!mem) | |
| 67 | + return; | |
| 68 | + | |
| 66 | 69 | if (!mem->bus.offset && !mem->bus.addr) |
| 67 | 70 | return; |
| 68 | 71 | |
| @@ -44,6 +44,8 @@ static unsigned ttm_glob_use_count; · 43 unmodified lines | ||
| 44 | 44 | struct ttm_global ttm_glob; |
| 45 | 45 | EXPORT_SYMBOL(ttm_glob); |
| 46 | 46 | |
| 47 | +struct dentry *ttm_debugfs_root; | |
| 48 | + | |
| 47 | 49 | static void ttm_global_release(void) |
| 48 | 50 | { |
| 49 | 51 | struct ttm_global *glob = &ttm_glob; |
| @@ -53,6 +55,7 @@ static void ttm_global_release(void) · 3 unmodified lines | ||
| 53 | 55 | goto out; |
| 54 | 56 | |
| 55 | 57 | ttm_pool_mgr_fini(); |
| 58 | + debugfs_remove(ttm_debugfs_root); | |
| 56 | 59 | |
| 57 | 60 | __free_page(glob->dummy_read_page); |
| 58 | 61 | memset(glob, 0, sizeof(*glob)); |
| @@ -73,6 +76,13 @@ static int ttm_global_init(void) · 14 unmodified lines | ||
| 73 | 76 | |
| 74 | 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 | 86 | /* Limit the number of pages in the pool to about 50% of the total |
| 77 | 87 | * system memory. |
| 78 | 88 | */ |
| @@ -100,6 +110,10 @@ static int ttm_global_init(void) · 21 unmodified lines | ||
| 100 | 110 | debugfs_create_atomic_t("buffer_objects", 0444, ttm_debugfs_root, |
| 101 | 111 | &glob->bo_count); |
| 102 | 112 | out: |
| 113 | + if (ret && ttm_debugfs_root) | |
| 114 | + debugfs_remove(ttm_debugfs_root); | |
| 115 | + if (ret) | |
| 116 | + --ttm_glob_use_count; | |
| 103 | 117 | mutex_unlock(&ttm_global_mutex); |
| 104 | 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 | 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 | 75 | MODULE_AUTHOR("Thomas Hellstrom, Jerome Glisse"); |
| 92 | 76 | MODULE_DESCRIPTION("TTM memory manager subsystem (for DRM device)"); |
| 93 | 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 | 1857 | vc4_hdmi_cec_update_clk_div(vc4_hdmi); |
| 1858 | 1858 | |
| 1859 | 1859 | if (vc4_hdmi->variant->external_irq_controller) { |
| 1860 | − ret = devm_request_threaded_irq(&pdev->dev, | |
| 1861 | − platform_get_irq_byname(pdev, "cec-rx"), | |
| 1862 | − vc4_cec_irq_handler_rx_bare, | |
| 1863 | − vc4_cec_irq_handler_rx_thread, 0, | |
| 1864 | − "vc4 hdmi cec rx", vc4_hdmi); | |
| 1860 | + ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-rx"), | |
| 1861 | + vc4_cec_irq_handler_rx_bare, | |
| 1862 | + vc4_cec_irq_handler_rx_thread, 0, | |
| 1863 | + "vc4 hdmi cec rx", vc4_hdmi); | |
| 1865 | 1864 | if (ret) |
| 1866 | 1865 | goto err_delete_cec_adap; |
| 1867 | 1866 | |
| 1868 | − ret = devm_request_threaded_irq(&pdev->dev, | |
| 1869 | − platform_get_irq_byname(pdev, "cec-tx"), | |
| 1870 | − vc4_cec_irq_handler_tx_bare, | |
| 1871 | − vc4_cec_irq_handler_tx_thread, 0, | |
| 1872 | − "vc4 hdmi cec tx", vc4_hdmi); | |
| 1867 | + ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-tx"), | |
| 1868 | + vc4_cec_irq_handler_tx_bare, | |
| 1869 | + vc4_cec_irq_handler_tx_thread, 0, | |
| 1870 | + "vc4 hdmi cec tx", vc4_hdmi); | |
| 1873 | 1871 | if (ret) |
| 1874 | − goto err_delete_cec_adap; | |
| 1872 | + goto err_remove_cec_rx_handler; | |
| 1875 | 1873 | } else { |
| 1876 | 1874 | HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff); |
| 1877 | 1875 | |
| 1878 | − ret = devm_request_threaded_irq(&pdev->dev, platform_get_irq(pdev, 0), | |
| 1879 | − vc4_cec_irq_handler, | |
| 1880 | − vc4_cec_irq_handler_thread, 0, | |
| 1881 | − "vc4 hdmi cec", vc4_hdmi); | |
| 1876 | + ret = request_threaded_irq(platform_get_irq(pdev, 0), | |
| 1877 | + vc4_cec_irq_handler, | |
| 1878 | + vc4_cec_irq_handler_thread, 0, | |
| 1879 | + "vc4 hdmi cec", vc4_hdmi); | |
| 1882 | 1880 | if (ret) |
| 1883 | 1881 | goto err_delete_cec_adap; |
| 1884 | 1882 | } |
| 1885 | 1883 | |
| 1886 | 1884 | ret = cec_register_adapter(vc4_hdmi->cec_adap, &pdev->dev); |
| 1887 | 1885 | if (ret < 0) |
| 1888 | − goto err_delete_cec_adap; | |
| 1886 | + goto err_remove_handlers; | |
| 1889 | 1887 | |
| 1890 | 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 | 1900 | err_delete_cec_adap: |
| 1893 | 1901 | cec_delete_adapter(vc4_hdmi->cec_adap); |
| 1894 | 1902 | |
| @@ -1897,6 +1905,15 @@ err_delete_cec_adap: · 2 unmodified lines | ||
| 1897 | 1905 | |
| 1898 | 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 | 1917 | cec_unregister_adapter(vc4_hdmi->cec_adap); |
| 1901 | 1918 | } |
| 1902 | 1919 | #else |
| @@ -576,7 +576,7 @@ config HID_LOGITECH_HIDPP · 575 unmodified lines | ||
| 576 | 576 | depends on HID_LOGITECH |
| 577 | 577 | select POWER_SUPPLY |
| 578 | 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 | 581 | Say Y if you want support for Logitech devices relying on the HID++ |
| 582 | 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 | 58 | cmd_base.cmd_v2.sensor_id = sensor_idx; |
| 59 | 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 | 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 | 501 | APPLE_RDESC_JIS }, |
| 502 | 502 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), |
| 503 | 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 | 506 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), |
| 505 | 507 | .driver_data = APPLE_HAS_FN }, |
| 506 | 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 | 486 | struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, |
| 487 | 487 | cdev); |
| 488 | − if (led->brightness == brightness) | |
| 489 | − return; | |
| 490 | − | |
| 491 | 488 | led->brightness = brightness; |
| 492 | 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 | 742 | int ret; |
| 743 | 743 | |
| 744 | 744 | ret = ft260_get_system_config(hdev, &cfg); |
| 745 | − if (ret) | |
| 745 | + if (ret < 0) | |
| 746 | 746 | return ret; |
| 747 | 747 | |
| 748 | 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 | 754 | switch (cfg.chip_mode) { |
| 755 | 755 | case FT260_MODE_ALL: |
| 756 | 756 | case FT260_MODE_BOTH: |
| 757 | − if (interface == 1) { | |
| 757 | + if (interface == 1) | |
| 758 | 758 | hid_info(hdev, "uart interface is not supported\n"); |
| 759 | − return 0; | |
| 760 | − } | |
| 761 | − ret = 1; | |
| 759 | + else | |
| 760 | + ret = 1; | |
| 762 | 761 | break; |
| 763 | 762 | case FT260_MODE_UART: |
| 764 | − if (interface == 0) { | |
| 765 | − hid_info(hdev, "uart is unsupported on interface 0\n"); | |
| 766 | − ret = 0; | |
| 767 | − } | |
| 763 | + hid_info(hdev, "uart interface is not supported\n"); | |
| 768 | 764 | break; |
| 769 | 765 | case FT260_MODE_I2C: |
| 770 | − if (interface == 1) { | |
| 771 | − hid_info(hdev, "i2c is unsupported on interface 1\n"); | |
| 772 | − ret = 0; | |
| 773 | − } | |
| 766 | + ret = 1; | |
| 774 | 767 | break; |
| 775 | 768 | } |
| 776 | 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 | 778 | if (ret < 0) |
| 786 | 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 | 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 | 790 | if (ret < 0) |
| 798 | 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 | 796 | #define FT260_ATTR_SHOW(name, reptype, id, type, func) \ |
| @@ -1004,11 +997,9 @@ err_hid_stop: · 200 unmodified lines | ||
| 1004 | 997 | |
| 1005 | 998 | static void ft260_remove(struct hid_device *hdev) |
| 1006 | 999 | { |
| 1007 | − int ret; | |
| 1008 | 1000 | struct ft260_device *dev = hid_get_drvdata(hdev); |
| 1009 | 1001 | |
| 1010 | − ret = ft260_is_interface_enabled(hdev); | |
| 1011 | − if (ret <= 0) | |
| 1002 | + if (!dev) | |
| 1012 | 1003 | return; |
| 1013 | 1004 | |
| 1014 | 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 | 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 | 833 | init_waitqueue_head(&client_data->ishtp_resume_wait); |
| 823 | 834 | |
| 824 | 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 | 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 | 935 | hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__, |
| 923 | 936 | hid_ishtp_cl); |
| 924 | − client_data->suspended = false; | |
| 937 | + schedule_work(&client_data->resume_work); | |
| 925 | 938 | return 0; |
| 926 | 939 | } |
| 927 | 940 | |
| @@ -135,6 +135,7 @@ struct ishtp_cl_data { · 134 unmodified lines | ||
| 135 | 135 | int multi_packet_cnt; |
| 136 | 136 | |
| 137 | 137 | struct work_struct work; |
| 138 | + struct work_struct resume_work; | |
| 138 | 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 | 314 | if (!device) |
| 315 | 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 | 317 | driver = to_ishtp_cl_driver(dev->driver); |
| 325 | 318 | if (driver && driver->driver.pm) { |
| 326 | 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 | 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 | 868 | * ishtp_get_pci_device() - Return PCI device dev pointer |
| 854 | 869 | * This interface is used to return PCI device pointer |
| @@ -38,7 +38,7 @@ config USB_HIDDEV · 37 unmodified lines | ||
| 38 | 38 | help |
| 39 | 39 | Say Y here if you want to support HID devices (from the USB |
| 40 | 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 | 43 | This module supports these devices separately using a separate |
| 44 | 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 | 2548 | int slot; |
| 2549 | 2549 | |
| 2550 | 2550 | slot = input_mt_get_slot_by_key(input, hid_data->id); |
| 2551 | + if (slot < 0) | |
| 2552 | + return; | |
| 2553 | + | |
| 2551 | 2554 | input_mt_slot(input, slot); |
| 2552 | 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 | 3834 | wacom_wac->shared->touch->product == 0xF6) { |
| 3832 | 3835 | input_dev->evbit[0] |= BIT_MASK(EV_SW); |
| 3833 | 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 | 3839 | fallthrough; |
| 3837 | 3840 | |
| @@ -605,6 +605,17 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) · 604 unmodified lines | ||
| 605 | 605 | */ |
| 606 | 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 | 619 | init_vp_index(newchannel); |
| 609 | 620 | |
| 610 | 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 | 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 | 631 | if (fnew) { |
| 631 | 632 | list_add_tail(&newchannel->listentry, |
| 632 | 633 | &vmbus_connection.chn_list); |
| @@ -647,7 +648,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) · 14 unmodified lines | ||
| 647 | 648 | /* |
| 648 | 649 | * Process the sub-channel. |
| 649 | 650 | */ |
| 650 | − newchannel->primary_channel = channel; | |
| 651 | 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 | 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 | 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 | 726 | static void init_vp_index(struct vmbus_channel *channel) |
| 703 | 727 | { |
| 704 | 728 | bool perf_chn = hv_is_perf_channel(channel); |
| 729 | + u32 i, ncpu = num_online_cpus(); | |
| 705 | 730 | cpumask_var_t available_mask; |
| 706 | 731 | struct cpumask *alloced_mask; |
| 707 | 732 | u32 target_cpu; |
| @@ -724,31 +749,38 @@ static void init_vp_index(struct vmbus_channel *channel) · 16 unmodified lines | ||
| 724 | 749 | return; |
| 725 | 750 | } |
| 726 | 751 | |
| 727 | − while (true) { | |
| 728 | − numa_node = next_numa_node_id++; | |
| 729 | − if (numa_node == nr_node_ids) { | |
| 730 | − next_numa_node_id = 0; | |
| 731 | − continue; | |
| 752 | + for (i = 1; i <= ncpu + 1; i++) { | |
| 753 | + while (true) { | |
| 754 | + numa_node = next_numa_node_id++; | |
| 755 | + if (numa_node == nr_node_ids) { | |
| 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) == | |
| 740 | − cpumask_weight(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 | − } | |
| 774 | + cpumask_xor(available_mask, alloced_mask, | |
| 775 | + cpumask_of_node(numa_node)); | |
| 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); | |
| 751 | − cpumask_set_cpu(target_cpu, alloced_mask); | |
| 780 | + if (channel->offermsg.offer.sub_channel_index >= ncpu || | |
| 781 | + i > ncpu || !hv_cpuself_used(target_cpu, channel)) | |
| 782 | + break; | |
| 783 | + } | |
| 752 | 784 | |
| 753 | 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 | 636 | status = readb(i2c->base + MPC_I2C_SR); |
| 637 | 637 | if (status & CSR_MIF) { |
| 638 | − /* Read again to allow register to stabilise */ | |
| 639 | − status = readb(i2c->base + MPC_I2C_SR); | |
| 638 | + /* Wait up to 100us for transfer to properly complete */ | |
| 639 | + readb_poll_timeout(i2c->base + MPC_I2C_SR, status, !(status & CSR_MCF), 0, 100); | |
| 640 | 640 | writeb(0, i2c->base + MPC_I2C_SR); |
| 641 | 641 | mpc_i2c_do_intr(i2c, status); |
| 642 | 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 | 120 | if (!chip_ctx) |
| 121 | 121 | return -ENOMEM; |
| 122 | 122 | chip_ctx->chip_num = bp->chip_num; |
| 123 | + chip_ctx->hw_stats_size = bp->hw_ring_stats_size; | |
| 123 | 124 | |
| 124 | 125 | rdev->chip_ctx = chip_ctx; |
| 125 | 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 | 551 | dma_addr_t dma_map, |
| 551 | 552 | u32 *fw_stats_ctx_id) |
| 552 | 553 | { |
| 554 | + struct bnxt_qplib_chip_ctx *chip_ctx = rdev->chip_ctx; | |
| 553 | 555 | struct hwrm_stat_ctx_alloc_output resp = {0}; |
| 554 | 556 | struct hwrm_stat_ctx_alloc_input req = {0}; |
| 555 | 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 | 568 | bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_ALLOC, -1, -1); |
| 567 | 569 | req.update_period_ms = cpu_to_le32(1000); |
| 568 | 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 | 572 | req.stat_ctx_flags = STAT_CTX_ALLOC_REQ_STAT_CTX_FLAGS_ROCE; |
| 571 | 573 | bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, |
| 572 | 574 | sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); |
| @@ -56,6 +56,7 @@ · 55 unmodified lines | ||
| 56 | 56 | static void bnxt_qplib_free_stats_ctx(struct pci_dev *pdev, |
| 57 | 57 | struct bnxt_qplib_stats *stats); |
| 58 | 58 | static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev, |
| 59 | + struct bnxt_qplib_chip_ctx *cctx, | |
| 59 | 60 | struct bnxt_qplib_stats *stats); |
| 60 | 61 | |
| 61 | 62 | /* PBL */ |
| @@ -559,7 +560,7 @@ int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res, · 497 unmodified lines | ||
| 559 | 560 | goto fail; |
| 560 | 561 | stats_alloc: |
| 561 | 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 | 564 | if (rc) |
| 564 | 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 | 892 | static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev, |
| 893 | + struct bnxt_qplib_chip_ctx *cctx, | |
| 892 | 894 | struct bnxt_qplib_stats *stats) |
| 893 | 895 | { |
| 894 | 896 | memset(stats, 0, sizeof(*stats)); |
| 895 | 897 | stats->fw_id = -1; |
| 896 | − /* 128 byte aligned context memory is required only for 57500. | |
| 897 | − * However making this unconditional, it does not harm previous | |
| 898 | − * generation. | |
| 899 | − */ | |
| 900 | − stats->size = ALIGN(sizeof(struct ctx_hw_stats), 128); | |
| 898 | + stats->size = cctx->hw_stats_size; | |
| 901 | 899 | stats->dma = dma_alloc_coherent(&pdev->dev, stats->size, |
| 902 | 900 | &stats->dma_map, GFP_KERNEL); |
| 903 | 901 | if (!stats->dma) { |
| @@ -54,6 +54,7 @@ struct bnxt_qplib_chip_ctx { · 53 unmodified lines | ||
| 54 | 54 | u16 chip_num; |
| 55 | 55 | u8 chip_rev; |
| 56 | 56 | u8 chip_metal; |
| 57 | + u16 hw_stats_size; | |
| 57 | 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 | 2845 | * parses fpm commit info and copy base value |
| 2846 | 2846 | * of hmc objects in hmc_info |
| 2847 | 2847 | */ |
| 2848 | −static enum irdma_status_code | |
| 2848 | +static void | |
| 2849 | 2849 | irdma_sc_parse_fpm_commit_buf(struct irdma_sc_dev *dev, __le64 *buf, |
| 2850 | 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 | 2915 | else |
| 2916 | 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 | 4186 | * @dev: sc device struct |
| 4188 | 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 | 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 | 4431 | ret_code = irdma_sc_commit_fpm_val(dev->cqp, 0, hmc_info->hmc_fn_id, |
| 4435 | 4432 | &commit_fpm_mem, true, wait_type); |
| 4436 | 4433 | if (!ret_code) |
| 4437 | − ret_code = irdma_sc_parse_fpm_commit_buf(dev, dev->fpm_commit_buf, | |
| 4438 | − hmc_info->hmc_obj, | |
| 4439 | − &hmc_info->sd_table.sd_cnt); | |
| 4434 | + irdma_sc_parse_fpm_commit_buf(dev, dev->fpm_commit_buf, | |
| 4435 | + hmc_info->hmc_obj, | |
| 4436 | + &hmc_info->sd_table.sd_cnt); | |
| 4440 | 4437 | print_hex_dump_debug("HMC: COMMIT FPM BUFFER", DUMP_PREFIX_OFFSET, 16, |
| 4441 | 4438 | 8, commit_fpm_mem.va, IRDMA_COMMIT_FPM_BUF_SIZE, |
| 4442 | 4439 | false); |
| @@ -1920,7 +1920,7 @@ enum irdma_status_code irdma_ctrl_init_hw(struct irdma_pci_f *rf) · 1919 unmodified lines | ||
| 1920 | 1920 | * irdma_set_hw_rsrc - set hw memory resources. |
| 1921 | 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 | 1925 | rf->allocated_qps = (void *)(rf->mem_rsrc + |
| 1926 | 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 | 1937 | spin_lock_init(&rf->arp_lock); |
| 1938 | 1938 | spin_lock_init(&rf->qptable_lock); |
| 1939 | 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 | 1999 | rf->arp_table = (struct irdma_arp_entry *)rf->mem_rsrc; |
| 2002 | 2000 | |
| 2003 | − ret = irdma_set_hw_rsrc(rf); | |
| 2004 | − if (ret) | |
| 2005 | − goto set_hw_rsrc_fail; | |
| 2001 | + irdma_set_hw_rsrc(rf); | |
| 2006 | 2002 | |
| 2007 | 2003 | set_bit(0, rf->allocated_mrs); |
| 2008 | 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 | 2022 | return 0; |
| 2027 | 2023 | |
| 2028 | −set_hw_rsrc_fail: | |
| 2029 | − kfree(rf->mem_rsrc); | |
| 2030 | − rf->mem_rsrc = NULL; | |
| 2031 | 2024 | mem_rsrc_kzalloc_fail: |
| 2032 | 2025 | kfree(rf->allocated_ws_nodes); |
| 2033 | 2026 | rf->allocated_ws_nodes = NULL; |
| @@ -215,10 +215,10 @@ static void irdma_remove(struct auxiliary_device *aux_dev) · 214 unmodified lines | ||
| 215 | 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 | 221 | struct irdma_pci_f *rf = iwdev->rf; |
| 221 | − struct ice_vsi *vsi = ice_get_main_vsi(pf); | |
| 222 | 222 | |
| 223 | 223 | rf->cdev = pf; |
| 224 | 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 | 253 | struct iidc_auxiliary_dev, |
| 254 | 254 | adev); |
| 255 | 255 | struct ice_pf *pf = iidc_adev->pf; |
| 256 | + struct ice_vsi *vsi = ice_get_main_vsi(pf); | |
| 256 | 257 | struct iidc_qos_params qos_info = {}; |
| 257 | 258 | struct irdma_device *iwdev; |
| 258 | 259 | struct irdma_pci_f *rf; |
| 259 | 260 | struct irdma_l2params l2params = {}; |
| 260 | 261 | int err; |
| 261 | 262 | |
| 263 | + if (!vsi) | |
| 264 | + return -EIO; | |
| 262 | 265 | iwdev = ib_alloc_device(irdma_device, ibdev); |
| 263 | 266 | if (!iwdev) |
| 264 | 267 | return -ENOMEM; |
| @@ -268,7 +271,7 @@ static int irdma_probe(struct auxiliary_device *aux_dev, const struct auxiliary_ · 3 unmodified lines | ||
| 268 | 271 | return -ENOMEM; |
| 269 | 272 | } |
| 270 | 273 | |
| 271 | − irdma_fill_device_info(iwdev, pf); | |
| 274 | + irdma_fill_device_info(iwdev, pf, vsi); | |
| 272 | 275 | rf = iwdev->rf; |
| 273 | 276 | |
| 274 | 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 | 1222 | struct irdma_aeq_init_info *info); |
| 1223 | 1223 | enum irdma_status_code irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq, |
| 1224 | 1224 | struct irdma_aeqe_info *info); |
| 1225 | −enum irdma_status_code irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, | |
| 1226 | − u32 count); | |
| 1225 | +void irdma_sc_repost_aeq_entries(struct irdma_sc_dev *dev, u32 count); | |
| 1227 | 1226 | |
| 1228 | 1227 | void irdma_sc_pd_init(struct irdma_sc_dev *dev, struct irdma_sc_pd *pd, u32 pd_id, |
| 1229 | 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 | 931 | enum irdma_status_code irdma_uk_post_receive(struct irdma_qp_uk *qp, |
| 932 | 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 | 935 | u32 addl_frag_cnt; |
| 936 | 936 | __le64 *wqe; |
| 937 | 937 | u64 hdr; |
| @@ -939,9 +939,6 @@ enum irdma_status_code irdma_uk_post_receive(struct irdma_qp_uk *qp, · 1 unmodified line | ||
| 939 | 939 | if (qp->max_rq_frag_cnt < info->num_sges) |
| 940 | 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 | 942 | wqe = irdma_qp_get_next_recv_wqe(qp, &wqe_idx); |
| 946 | 943 | if (!wqe) |
| 947 | 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 | 557 | * @iwqp: qp ptr |
| 558 | 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 | 561 | struct irdma_qp *iwqp, |
| 562 | 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 | 574 | init_info->sq_pa = qpmr->sq_pbl.addr; |
| 575 | 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 | 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 | 916 | } else { |
| 919 | 917 | init_info.qp_uk_init_info.abi_ver = IRDMA_ABI_VER; |
| 920 | 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 | 113 | int num_buf; |
| 114 | 114 | void *vaddr; |
| 115 | 115 | int err; |
| 116 | + int i; | |
| 116 | 117 | |
| 117 | 118 | umem = ib_umem_get(pd->ibpd.device, start, length, access); |
| 118 | 119 | if (IS_ERR(umem)) { |
| 119 | − pr_warn("err %d from rxe_umem_get\n", | |
| 120 | − (int)PTR_ERR(umem)); | |
| 120 | + pr_warn("%s: Unable to pin memory region err = %d\n", | |
| 121 | + __func__, (int)PTR_ERR(umem)); | |
| 121 | 122 | err = PTR_ERR(umem); |
| 122 | − goto err1; | |
| 123 | + goto err_out; | |
| 123 | 124 | } |
| 124 | 125 | |
| 125 | 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 | 131 | err = rxe_mr_alloc(mr, num_buf); |
| 131 | 132 | if (err) { |
| 132 | − pr_warn("err %d from rxe_mr_alloc\n", err); | |
| 133 | − ib_umem_release(umem); | |
| 134 | − goto err1; | |
| 133 | + pr_warn("%s: Unable to allocate memory for map\n", | |
| 134 | + __func__); | |
| 135 | + goto err_release_umem; | |
| 135 | 136 | } |
| 136 | 137 | |
| 137 | 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 | 153 | vaddr = page_address(sg_page_iter_page(&sg_iter)); |
| 153 | 154 | if (!vaddr) { |
| 154 | − pr_warn("null vaddr\n"); | |
| 155 | − ib_umem_release(umem); | |
| 155 | + pr_warn("%s: Unable to get virtual address\n", | |
| 156 | + __func__); | |
| 156 | 157 | err = -ENOMEM; |
| 157 | − goto err1; | |
| 158 | + goto err_cleanup_map; | |
| 158 | 159 | } |
| 159 | 160 | |
| 160 | 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 | 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 | 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 | 173 | int ret; |
| 174 | 174 | |
| 175 | 175 | for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { |
| 176 | − if (!adev->status.enabled) { | |
| 177 | − acpi_dev_put(adev); | |
| 176 | + if (!adev->status.enabled) | |
| 178 | 177 | continue; |
| 179 | − } | |
| 180 | 178 | |
| 181 | 179 | if (bridge->n_sensors >= CIO2_NUM_PORTS) { |
| 182 | 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 | 185 | sensor = &bridge->sensors[bridge->n_sensors]; |
| 188 | − sensor->adev = adev; | |
| 189 | 186 | strscpy(sensor->name, cfg->hid, sizeof(sensor->name)); |
| 190 | 187 | |
| 191 | 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 | 212 | goto err_free_swnodes; |
| 216 | 213 | } |
| 217 | 214 | |
| 215 | + sensor->adev = acpi_dev_get(adev); | |
| 218 | 216 | adev->fwnode.secondary = fwnode; |
| 219 | 217 | |
| 220 | 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 | 386 | com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER; |
| 387 | 387 | com.cmd.hdr.Length = 6; |
| 388 | − memcpy(&com.cmd.ConfigureBuffers.config, config, 6); | |
| 388 | + memcpy(&com.cmd.ConfigureFreeBuffers.config, config, 6); | |
| 389 | 389 | com.in_len = 6; |
| 390 | 390 | com.out_len = 0; |
| 391 | 391 | |
| @@ -407,12 +407,14 @@ enum _BUFFER_CONFIGS { · 406 unmodified lines | ||
| 407 | 407 | |
| 408 | 408 | struct FW_CONFIGURE_FREE_BUFFERS { |
| 409 | 409 | struct FW_HEADER hdr; |
| 410 | − u8 UVI1_BufferLength; | |
| 411 | − u8 UVI2_BufferLength; | |
| 412 | − u8 TVO_BufferLength; | |
| 413 | − u8 AUD1_BufferLength; | |
| 414 | − u8 AUD2_BufferLength; | |
| 415 | − u8 TVA_BufferLength; | |
| 410 | + struct { | |
| 411 | + u8 UVI1_BufferLength; | |
| 412 | + u8 UVI2_BufferLength; | |
| 413 | + u8 TVO_BufferLength; | |
| 414 | + u8 AUD1_BufferLength; | |
| 415 | + u8 AUD2_BufferLength; | |
| 416 | + u8 TVA_BufferLength; | |
| 417 | + } __packed config; | |
| 416 | 418 | } __attribute__ ((__packed__)); |
| 417 | 419 | |
| 418 | 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, | |
| 718 | − * then nvmem_config.id is initialised to NVMEM_DEVID_AUTO, | |
| 719 | − * and this will append the 'devid' to the name of the NVMEM | |
| 720 | − * device. This is purely legacy and the AT24 driver has always | |
| 721 | − * defaulted to this. However, if the 'label' property is | |
| 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'. | |
| 717 | + * We initialize nvmem_config.id to NVMEM_DEVID_AUTO even if the | |
| 718 | + * label property is set as some platform can have multiple eeproms | |
| 719 | + * with same label and we can not register each of those with same | |
| 720 | + * label. Failing to register those eeproms trigger cascade failure | |
| 721 | + * on such platform. | |
| 725 | 722 | */ |
| 723 | + nvmem_config.id = NVMEM_DEVID_AUTO; | |
| 724 | + | |
| 726 | 725 | if (device_property_present(dev, "label")) { |
| 727 | − nvmem_config.id = NVMEM_DEVID_NONE; | |
| 728 | 726 | err = device_property_read_string(dev, "label", |
| 729 | 727 | &nvmem_config.name); |
| 730 | 728 | if (err) |
| 731 | 729 | return err; |
| 732 | 730 | } else { |
| 733 | − nvmem_config.id = NVMEM_DEVID_AUTO; | |
| 734 | 731 | nvmem_config.name = dev_name(dev); |
| 735 | 732 | } |
| 736 | 733 | |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/errno.h> |
| 29 | 29 | #include <linux/hdreg.h> |
| 30 | 30 | #include <linux/kdev_t.h> |
| 31 | +#include <linux/kref.h> | |
| 31 | 32 | #include <linux/blkdev.h> |
| 32 | 33 | #include <linux/cdev.h> |
| 33 | 34 | #include <linux/mutex.h> |
| @@ -111,7 +112,7 @@ struct mmc_blk_data { · 77 unmodified lines | ||
| 111 | 112 | #define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ |
| 112 | 113 | #define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */ |
| 113 | 114 | |
| 114 | − unsigned int usage; | |
| 115 | + struct kref kref; | |
| 115 | 116 | unsigned int read_only; |
| 116 | 117 | unsigned int part_type; |
| 117 | 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 | 183 | mutex_lock(&open_lock); |
| 183 | 184 | md = disk->private_data; |
| 184 | − if (md && md->usage == 0) | |
| 185 | + if (md && !kref_get_unless_zero(&md->kref)) | |
| 185 | 186 | md = NULL; |
| 186 | − if (md) | |
| 187 | − md->usage++; | |
| 188 | 187 | mutex_unlock(&open_lock); |
| 189 | 188 | |
| 190 | 189 | return md; |
| @@ -196,18 +195,25 @@ static inline int mmc_get_devidx(struct gendisk *disk) · 5 unmodified lines | ||
| 196 | 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); | |
| 202 | − md->usage--; | |
| 203 | − if (md->usage == 0) { | |
| 204 | − int devidx = mmc_get_devidx(md->disk); | |
| 200 | + struct mmc_blk_data *md = container_of(ref, struct mmc_blk_data, kref); | |
| 201 | + int devidx; | |
| 205 | 202 | |
| 206 | − ida_simple_remove(&mmc_blk_ida, devidx); | |
| 207 | − put_disk(md->disk); | |
| 208 | − kfree(md); | |
| 209 | − } | |
| 203 | + devidx = mmc_get_devidx(md->disk); | |
| 204 | + ida_simple_remove(&mmc_blk_ida, devidx); | |
| 205 | + | |
| 206 | + mutex_lock(&open_lock); | |
| 207 | + md->disk->private_data = NULL; | |
| 210 | 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 | 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 | 2334 | INIT_LIST_HEAD(&md->part); |
| 2329 | 2335 | INIT_LIST_HEAD(&md->rpmbs); |
| 2330 | − md->usage = 1; | |
| 2336 | + kref_init(&md->kref); | |
| 2337 | + | |
| 2331 | 2338 | md->queue.blkdata = md; |
| 2332 | 2339 | |
| 2333 | 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 | 76 | struct mmc_host *host = cls_dev_to_mmc_host(dev); |
| 77 | 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 | 80 | kfree(host); |
| 80 | 81 | } |
| 81 | 82 | |
| @@ -502,7 +503,7 @@ static int mmc_first_nonreserved_index(void) · 420 unmodified lines | ||
| 502 | 503 | */ |
| 503 | 504 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) |
| 504 | 505 | { |
| 505 | − int err; | |
| 506 | + int index; | |
| 506 | 507 | struct mmc_host *host; |
| 507 | 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 | 517 | alias_id = of_alias_get_id(dev->of_node, "mmc"); |
| 517 | 518 | if (alias_id >= 0) { |
| 518 | − min_idx = alias_id; | |
| 519 | − max_idx = alias_id + 1; | |
| 519 | + index = alias_id; | |
| 520 | 520 | } else { |
| 521 | 521 | min_idx = mmc_first_nonreserved_index(); |
| 522 | 522 | max_idx = 0; |
| 523 | − } | |
| 524 | 523 | |
| 525 | − err = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL); | |
| 526 | − if (err < 0) { | |
| 527 | − kfree(host); | |
| 528 | − return NULL; | |
| 524 | + index = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL); | |
| 525 | + if (index < 0) { | |
| 526 | + kfree(host); | |
| 527 | + return NULL; | |
| 528 | + } | |
| 529 | 529 | } |
| 530 | 530 | |
| 531 | − host->index = err; | |
| 531 | + host->index = index; | |
| 532 | 532 | |
| 533 | 533 | dev_set_name(&host->class_dev, "mmc%d", host->index); |
| 534 | 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 | 3450 | return bond_event_changename(event_bond); |
| 3451 | 3451 | case NETDEV_UNREGISTER: |
| 3452 | 3452 | bond_remove_proc_entry(event_bond); |
| 3453 | +#ifdef CONFIG_XFRM_OFFLOAD | |
| 3453 | 3454 | xfrm_dev_state_flush(dev_net(bond_dev), bond_dev, true); |
| 3455 | +#endif /* CONFIG_XFRM_OFFLOAD */ | |
| 3454 | 3456 | break; |
| 3455 | 3457 | case NETDEV_REGISTER: |
| 3456 | 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 | 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 | 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 | 2300 | err, priv->regs_status.intf); |
| 2301 | 2301 | mcp251xfd_dump(priv); |
| 2302 | 2302 | mcp251xfd_chip_interrupts_disable(priv); |
| 2303 | + mcp251xfd_timestamp_stop(priv); | |
| 2303 | 2304 | |
| 2304 | 2305 | return handled; |
| 2305 | 2306 | } |
| @@ -255,6 +255,8 @@ struct ems_usb { · 254 unmodified lines | ||
| 255 | 255 | unsigned int free_slots; /* remember number of available slots */ |
| 256 | 256 | |
| 257 | 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 | 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 | 589 | for (i = 0; i < MAX_RX_URBS; i++) { |
| 588 | 590 | struct urb *urb = NULL; |
| 589 | 591 | u8 *buf = NULL; |
| 592 | + dma_addr_t buf_dma; | |
| 590 | 593 | |
| 591 | 594 | /* create a URB, and a buffer for it */ |
| 592 | 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 | 601 | buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, |
| 599 | − &urb->transfer_dma); | |
| 602 | + &buf_dma); | |
| 600 | 603 | if (!buf) { |
| 601 | 604 | netdev_err(netdev, "No memory left for USB buffer\n"); |
| 602 | 605 | usb_free_urb(urb); |
| @@ -604,6 +607,8 @@ static int ems_usb_start(struct ems_usb *dev) · 1 unmodified line | ||
| 604 | 607 | break; |
| 605 | 608 | } |
| 606 | 609 | |
| 610 | + urb->transfer_dma = buf_dma; | |
| 611 | + | |
| 607 | 612 | usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), |
| 608 | 613 | buf, RX_BUFFER_SIZE, |
| 609 | 614 | ems_usb_read_bulk_callback, dev); |
| @@ -619,6 +624,9 @@ static int ems_usb_start(struct ems_usb *dev) · 9 unmodified lines | ||
| 619 | 624 | break; |
| 620 | 625 | } |
| 621 | 626 | |
| 627 | + dev->rxbuf[i] = buf; | |
| 628 | + dev->rxbuf_dma[i] = buf_dma; | |
| 629 | + | |
| 622 | 630 | /* Drop reference, USB core will take care of freeing it */ |
| 623 | 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 | 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 | 699 | usb_kill_anchored_urbs(&dev->tx_submitted); |
| 688 | 700 | atomic_set(&dev->active_tx_urbs, 0); |
| 689 | 701 | |
| @@ -195,6 +195,8 @@ struct esd_usb2 { · 194 unmodified lines | ||
| 195 | 195 | int net_count; |
| 196 | 196 | u32 version; |
| 197 | 197 | int rxinitdone; |
| 198 | + void *rxbuf[MAX_RX_URBS]; | |
| 199 | + dma_addr_t rxbuf_dma[MAX_RX_URBS]; | |
| 198 | 200 | }; |
| 199 | 201 | |
| 200 | 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 | 547 | for (i = 0; i < MAX_RX_URBS; i++) { |
| 546 | 548 | struct urb *urb = NULL; |
| 547 | 549 | u8 *buf = NULL; |
| 550 | + dma_addr_t buf_dma; | |
| 548 | 551 | |
| 549 | 552 | /* create a URB, and a buffer for it */ |
| 550 | 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 | 559 | buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, |
| 557 | − &urb->transfer_dma); | |
| 560 | + &buf_dma); | |
| 558 | 561 | if (!buf) { |
| 559 | 562 | dev_warn(dev->udev->dev.parent, |
| 560 | 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 | 565 | goto freeurb; |
| 563 | 566 | } |
| 564 | 567 | |
| 568 | + urb->transfer_dma = buf_dma; | |
| 569 | + | |
| 565 | 570 | usb_fill_bulk_urb(urb, dev->udev, |
| 566 | 571 | usb_rcvbulkpipe(dev->udev, 1), |
| 567 | 572 | buf, RX_BUFFER_SIZE, |
| @@ -574,8 +579,12 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) · 6 unmodified lines | ||
| 574 | 579 | usb_unanchor_urb(urb); |
| 575 | 580 | usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, |
| 576 | 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 | 588 | freeurb: |
| 580 | 589 | /* Drop reference, USB core will take care of freeing it */ |
| 581 | 590 | usb_free_urb(urb); |
| @@ -663,6 +672,11 @@ static void unlink_all_urbs(struct esd_usb2 *dev) · 81 unmodified lines | ||
| 663 | 672 | int i, j; |
| 664 | 673 | |
| 665 | 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 | 680 | for (i = 0; i < dev->net_count; i++) { |
| 667 | 681 | priv = dev->nets[i]; |
| 668 | 682 | if (priv) { |
| @@ -653,6 +653,8 @@ static int mcba_usb_start(struct mcba_priv *priv) · 652 unmodified lines | ||
| 653 | 653 | break; |
| 654 | 654 | } |
| 655 | 655 | |
| 656 | + urb->transfer_dma = buf_dma; | |
| 657 | + | |
| 656 | 658 | usb_fill_bulk_urb(urb, priv->udev, |
| 657 | 659 | usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN), |
| 658 | 660 | buf, MCBA_USB_RX_BUFF_SIZE, |
| @@ -117,7 +117,8 @@ · 116 unmodified lines | ||
| 117 | 117 | #define PCAN_USB_BERR_MASK (PCAN_USB_ERR_RXERR | PCAN_USB_ERR_TXERR) |
| 118 | 118 | |
| 119 | 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 | 123 | /* private to PCAN-USB adapter */ |
| 123 | 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 | 610 | /* acccording to the content of the packet */ |
| 610 | 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 | 615 | /* save rx/tx error counters from in the device context */ |
| 614 | − pdev->bec.rxerr = mc->ptr[0]; | |
| 615 | − pdev->bec.txerr = mc->ptr[1]; | |
| 616 | + pdev->bec.rxerr = mc->ptr[1]; | |
| 617 | + pdev->bec.txerr = mc->ptr[2]; | |
| 616 | 618 | break; |
| 617 | 619 | |
| 618 | 620 | default: |
| @@ -137,7 +137,8 @@ struct usb_8dev_priv { · 136 unmodified lines | ||
| 137 | 137 | u8 *cmd_msg_buffer; |
| 138 | 138 | |
| 139 | 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 | 144 | /* tx frame */ |
| @@ -733,6 +734,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) · 589 unmodified lines | ||
| 733 | 734 | for (i = 0; i < MAX_RX_URBS; i++) { |
| 734 | 735 | struct urb *urb = NULL; |
| 735 | 736 | u8 *buf; |
| 737 | + dma_addr_t buf_dma; | |
| 736 | 738 | |
| 737 | 739 | /* create a URB, and a buffer for it */ |
| 738 | 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 | 746 | buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL, |
| 745 | − &urb->transfer_dma); | |
| 747 | + &buf_dma); | |
| 746 | 748 | if (!buf) { |
| 747 | 749 | netdev_err(netdev, "No memory left for USB buffer\n"); |
| 748 | 750 | usb_free_urb(urb); |
| @@ -750,6 +752,8 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) · 1 unmodified line | ||
| 750 | 752 | break; |
| 751 | 753 | } |
| 752 | 754 | |
| 755 | + urb->transfer_dma = buf_dma; | |
| 756 | + | |
| 753 | 757 | usb_fill_bulk_urb(urb, priv->udev, |
| 754 | 758 | usb_rcvbulkpipe(priv->udev, |
| 755 | 759 | USB_8DEV_ENDP_DATA_RX), |
| @@ -767,6 +771,9 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) · 11 unmodified lines | ||
| 767 | 771 | break; |
| 768 | 772 | } |
| 769 | 773 | |
| 774 | + priv->rxbuf[i] = buf; | |
| 775 | + priv->rxbuf_dma[i] = buf_dma; | |
| 776 | + | |
| 770 | 777 | /* Drop reference, USB core will take care of freeing it */ |
| 771 | 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 | 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 | 850 | usb_kill_anchored_urbs(&priv->tx_submitted); |
| 840 | 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 | 366 | int i; |
| 367 | 367 | |
| 368 | 368 | reg[1] |= vid & CVID_MASK; |
| 369 | + if (vid > 1) | |
| 370 | + reg[1] |= ATA2_IVL; | |
| 369 | 371 | reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER; |
| 370 | 372 | reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP; |
| 371 | 373 | /* STATIC_ENT indicate that entry is static wouldn't |
| @@ -79,6 +79,7 @@ enum mt753x_bpdu_port_fw { · 78 unmodified lines | ||
| 79 | 79 | #define STATIC_EMP 0 |
| 80 | 80 | #define STATIC_ENT 3 |
| 81 | 81 | #define MT7530_ATA2 0x78 |
| 82 | +#define ATA2_IVL BIT(15) | |
| 82 | 83 | |
| 83 | 84 | /* Register for address table write data */ |
| 84 | 85 | #define MT7530_ATWD 0x7c |
| @@ -12,7 +12,7 @@ config NET_DSA_MV88E6XXX · 11 unmodified lines | ||
| 12 | 12 | config NET_DSA_MV88E6XXX_PTP |
| 13 | 13 | bool "PTP support for Marvell 88E6xxx" |
| 14 | 14 | default n |
| 15 | − depends on PTP_1588_CLOCK | |
| 15 | + depends on NET_DSA_MV88E6XXX && PTP_1588_CLOCK | |
| 16 | 16 | help |
| 17 | 17 | Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch |
| 18 | 18 | chips that support it. |
| @@ -2155,7 +2155,7 @@ static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip, · 2154 unmodified lines | ||
| 2155 | 2155 | int i, err; |
| 2156 | 2156 | |
| 2157 | 2157 | if (!vid) |
| 2158 | − return -EOPNOTSUPP; | |
| 2158 | + return 0; | |
| 2159 | 2159 | |
| 2160 | 2160 | err = mv88e6xxx_vtu_get(chip, vid, &vlan); |
| 2161 | 2161 | if (err) |
| @@ -397,6 +397,12 @@ static int sja1105_init_static_vlan(struct sja1105_private *priv) · 396 unmodified lines | ||
| 397 | 397 | if (dsa_is_cpu_port(ds, port)) |
| 398 | 398 | v->pvid = true; |
| 399 | 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 | 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 | 1672 | if ((tpa_info->flags2 & RX_CMP_FLAGS2_META_FORMAT_VLAN) && |
| 1673 | 1673 | (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) { |
| 1674 | − u16 vlan_proto = tpa_info->metadata >> | |
| 1675 | − RX_CMP_FLAGS2_METADATA_TPID_SFT; | |
| 1674 | + __be16 vlan_proto = htons(tpa_info->metadata >> | |
| 1675 | + RX_CMP_FLAGS2_METADATA_TPID_SFT); | |
| 1676 | 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 | 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 | 1902 | (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) { |
| 1898 | 1903 | u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data); |
| 1899 | 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 | 1916 | skb_checksum_none_assert(skb); |
| @@ -7563,8 +7574,12 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) · 5657 unmodified lines | ||
| 7563 | 7574 | bp->flags &= ~BNXT_FLAG_WOL_CAP; |
| 7564 | 7575 | if (flags & FUNC_QCAPS_RESP_FLAGS_WOL_MAGICPKT_SUPPORTED) |
| 7565 | 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 | 7578 | __bnxt_hwrm_ptp_qcfg(bp); |
| 7579 | + } else { | |
| 7580 | + kfree(bp->ptp_cfg); | |
| 7581 | + bp->ptp_cfg = NULL; | |
| 7582 | + } | |
| 7568 | 7583 | } else { |
| 7569 | 7584 | #ifdef CONFIG_BNXT_SRIOV |
| 7570 | 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 | 10141 | rc = bnxt_init_nic(bp, irq_re_init); |
| 10128 | 10142 | if (rc) { |
| 10129 | 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 | 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 | 10220 | rc = bnxt_alloc_mem(bp, false); |
| 10201 | 10221 | if (rc) { |
| 10202 | 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 | 10276 | rc = bnxt_hwrm_if_change(bp, true); |
| 10257 | 10277 | if (rc) |
| 10258 | 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 | 10285 | rc = __bnxt_open_nic(bp, true, true); |
| 10260 | 10286 | if (rc) { |
| 10261 | 10287 | bnxt_hwrm_if_change(bp, false); |
| 10288 | + bnxt_ptp_clear(bp); | |
| 10262 | 10289 | } else { |
| 10263 | 10290 | if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) { |
| 10264 | 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 | 10377 | struct bnxt *bp = netdev_priv(dev); |
| 10351 | 10378 | |
| 10379 | + bnxt_ptp_clear(bp); | |
| 10352 | 10380 | bnxt_hwmon_close(bp); |
| 10353 | 10381 | bnxt_close_nic(bp, true, true); |
| 10354 | 10382 | bnxt_hwrm_shutdown_link(bp); |
| @@ -11335,6 +11363,7 @@ static void bnxt_fw_reset_close(struct bnxt *bp) · 980 unmodified lines | ||
| 11335 | 11363 | bnxt_clear_int_mode(bp); |
| 11336 | 11364 | pci_disable_device(bp->pdev); |
| 11337 | 11365 | } |
| 11366 | + bnxt_ptp_clear(bp); | |
| 11338 | 11367 | __bnxt_close_nic(bp, true, false); |
| 11339 | 11368 | bnxt_vf_reps_free(bp); |
| 11340 | 11369 | bnxt_clear_int_mode(bp); |
| @@ -11959,10 +11988,21 @@ static bool bnxt_fw_reset_timeout(struct bnxt *bp) · 618 unmodified lines | ||
| 11959 | 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 | 12002 | static void bnxt_fw_reset_task(struct work_struct *work) |
| 11963 | 12003 | { |
| 11964 | 12004 | struct bnxt *bp = container_of(work, struct bnxt, fw_reset_task.work); |
| 11965 | − int rc; | |
| 12005 | + int rc = 0; | |
| 11966 | 12006 | |
| 11967 | 12007 | if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { |
| 11968 | 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 | 12033 | bp->fw_reset_timestamp = jiffies; |
| 11994 | 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 | 12040 | bnxt_fw_reset_close(bp); |
| 11996 | 12041 | if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { |
| 11997 | 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 | 12084 | if (val == 0xffff) { |
| 12040 | 12085 | if (bnxt_fw_reset_timeout(bp)) { |
| 12041 | 12086 | netdev_err(bp->dev, "Firmware reset aborted, PCI config space invalid\n"); |
| 12087 | + rc = -ETIMEDOUT; | |
| 12042 | 12088 | goto fw_reset_abort; |
| 12043 | 12089 | } |
| 12044 | 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 | 12094 | clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state); |
| 12049 | 12095 | if (pci_enable_device(bp->pdev)) { |
| 12050 | 12096 | netdev_err(bp->dev, "Cannot re-enable PCI device\n"); |
| 12097 | + rc = -ENODEV; | |
| 12051 | 12098 | goto fw_reset_abort; |
| 12052 | 12099 | } |
| 12053 | 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 | 12122 | rc = bnxt_open(bp->dev); |
| 12076 | 12123 | if (rc) { |
| 12077 | − netdev_err(bp->dev, "bnxt_open_nic() failed\n"); | |
| 12078 | − clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | |
| 12079 | − dev_close(bp->dev); | |
| 12124 | + netdev_err(bp->dev, "bnxt_open() failed during FW reset\n"); | |
| 12125 | + bnxt_fw_reset_abort(bp, rc); | |
| 12126 | + rtnl_unlock(); | |
| 12127 | + return; | |
| 12080 | 12128 | } |
| 12081 | 12129 | |
| 12082 | 12130 | bp->fw_reset_state = 0; |
| 12083 | 12131 | /* Make sure fw_reset_state is 0 before clearing the flag */ |
| 12084 | 12132 | smp_mb__before_atomic(); |
| 12085 | 12133 | clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 12086 | − bnxt_ulp_start(bp, rc); | |
| 12087 | − if (!rc) | |
| 12088 | − bnxt_reenable_sriov(bp); | |
| 12134 | + bnxt_ulp_start(bp, 0); | |
| 12135 | + bnxt_reenable_sriov(bp); | |
| 12089 | 12136 | bnxt_vf_reps_alloc(bp); |
| 12090 | 12137 | bnxt_vf_reps_open(bp); |
| 12091 | 12138 | bnxt_dl_health_recovery_done(bp); |
| @@ -12103,12 +12150,8 @@ fw_reset_abort_status: · 11 unmodified lines | ||
| 12103 | 12150 | netdev_err(bp->dev, "fw_health_status 0x%x\n", sts); |
| 12104 | 12151 | } |
| 12105 | 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 | 12153 | rtnl_lock(); |
| 12111 | − dev_close(bp->dev); | |
| 12154 | + bnxt_fw_reset_abort(bp, rc); | |
| 12112 | 12155 | rtnl_unlock(); |
| 12113 | 12156 | } |
| 12114 | 12157 | |
| @@ -12662,7 +12705,6 @@ static void bnxt_remove_one(struct pci_dev *pdev) · 547 unmodified lines | ||
| 12662 | 12705 | if (BNXT_PF(bp)) |
| 12663 | 12706 | devlink_port_type_clear(&bp->dl_port); |
| 12664 | 12707 | |
| 12665 | − bnxt_ptp_clear(bp); | |
| 12666 | 12708 | pci_disable_pcie_error_reporting(pdev); |
| 12667 | 12709 | unregister_netdev(dev); |
| 12668 | 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 | 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 | 13291 | bnxt_inv_fw_health_reg(bp); |
| 13255 | 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 | 13473 | if (netif_running(netdev)) |
| 13437 | 13474 | bnxt_close(netdev); |
| 13438 | 13475 | |
| 13439 | − pci_disable_device(pdev); | |
| 13476 | + if (pci_is_enabled(pdev)) | |
| 13477 | + pci_disable_device(pdev); | |
| 13440 | 13478 | bnxt_free_ctx_mem(bp); |
| 13441 | 13479 | kfree(bp->ctx); |
| 13442 | 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 | 433 | static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc) |
| 434 | 434 | { |
| 435 | 435 | int total_ets_bw = 0; |
| 436 | + bool zero = false; | |
| 436 | 437 | u8 max_tc = 0; |
| 437 | 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 | 454 | break; |
| 454 | 455 | case IEEE_8021QAZ_TSA_ETS: |
| 455 | 456 | total_ets_bw += ets->tc_tx_bw[i]; |
| 457 | + zero = zero || !ets->tc_tx_bw[i]; | |
| 456 | 458 | break; |
| 457 | 459 | default: |
| 458 | 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 | 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 | 472 | if (max_tc >= bp->max_tc) |
| 465 | 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 | 354 | bnxt_ptp_get_current_time(bp); |
| 355 | 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 | 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 | 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 | 394 | static const struct ptp_clock_info bnxt_ptp_caps = { |
| 405 | 395 | .owner = THIS_MODULE, |
| 406 | 396 | .name = "bnxt clock", |
| @@ -439,6 +429,7 @@ int bnxt_ptp_init(struct bnxt *bp) · 32 unmodified lines | ||
| 439 | 429 | ptp->cc.shift = 0; |
| 440 | 430 | ptp->cc.mult = 1; |
| 441 | 431 | |
| 432 | + ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD; | |
| 442 | 433 | timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real())); |
| 443 | 434 | |
| 444 | 435 | ptp->ptp_info = bnxt_ptp_caps; |
| @@ -450,7 +441,13 @@ int bnxt_ptp_init(struct bnxt *bp) · 5 unmodified lines | ||
| 450 | 441 | bnxt_unmap_ptp_regs(bp); |
| 451 | 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 | 451 | return 0; |
| 455 | 452 | } |
| 456 | 453 | |
| @@ -32,6 +32,10 @@ struct bnxt_ptp_cfg { · 31 unmodified lines | ||
| 32 | 32 | u64 current_time; |
| 33 | 33 | u64 old_time; |
| 34 | 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 | 39 | u16 tx_seqid; |
| 36 | 40 | struct bnxt *bp; |
| 37 | 41 | atomic_t tx_avail; |
| @@ -75,7 +79,6 @@ int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr); · 37 unmodified lines | ||
| 75 | 79 | int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr); |
| 76 | 80 | int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb); |
| 77 | 81 | int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts); |
| 78 | −void bnxt_ptp_start(struct bnxt *bp); | |
| 79 | 82 | int bnxt_ptp_init(struct bnxt *bp); |
| 80 | 83 | void bnxt_ptp_clear(struct bnxt *bp); |
| 81 | 84 | #endif |
| @@ -479,16 +479,17 @@ struct bnxt_en_dev *bnxt_ulp_probe(struct net_device *dev) · 478 unmodified lines | ||
| 479 | 479 | if (!edev) |
| 480 | 480 | return ERR_PTR(-ENOMEM); |
| 481 | 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 | 482 | edev->net = dev; |
| 487 | 483 | edev->pdev = bp->pdev; |
| 488 | 484 | edev->l2_db_size = bp->db_size; |
| 489 | 485 | edev->l2_db_size_nc = bp->db_size; |
| 490 | 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 | 493 | return bp->edev; |
| 493 | 494 | } |
| 494 | 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 | 420 | * bits 32:47 indicate the PVF num. |
| 421 | 421 | */ |
| 422 | 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 | 425 | /* for VF assigned queues. */ |
| 426 | 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 | 357 | int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; |
| 358 | 358 | void __iomem *ioaddr; |
| 359 | 359 | |
| 360 | − i = pci_enable_device(pdev); | |
| 360 | + i = pcim_enable_device(pdev); | |
| 361 | 361 | if (i) return i; |
| 362 | 362 | |
| 363 | 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 | 380 | ioaddr = pci_iomap(pdev, TULIP_BAR, netdev_res_size); |
| 381 | 381 | if (!ioaddr) |
| 382 | − goto err_out_free_res; | |
| 382 | + goto err_out_netdev; | |
| 383 | 383 | |
| 384 | 384 | for (i = 0; i < 3; i++) |
| 385 | 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 | 459 | err_out_cleardev: |
| 460 | 460 | pci_iounmap(pdev, ioaddr); |
| 461 | −err_out_free_res: | |
| 462 | − pci_release_regions(pdev); | |
| 463 | 461 | err_out_netdev: |
| 464 | 462 | free_netdev (dev); |
| 465 | 463 | return -ENODEV; |
| @@ -1526,7 +1524,6 @@ static void w840_remove1(struct pci_dev *pdev) · 1060 unmodified lines | ||
| 1526 | 1524 | if (dev) { |
| 1527 | 1525 | struct netdev_private *np = netdev_priv(dev); |
| 1528 | 1526 | unregister_netdev(dev); |
| 1529 | − pci_release_regions(pdev); | |
| 1530 | 1527 | pci_iounmap(pdev, np->base_addr); |
| 1531 | 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 | 2770 | if (err) |
| 2771 | 2771 | return err; |
| 2772 | 2772 | |
| 2773 | − err = dpaa2_switch_seed_bp(ethsw); | |
| 2774 | − if (err) | |
| 2775 | − goto err_free_dpbp; | |
| 2776 | − | |
| 2777 | 2773 | err = dpaa2_switch_alloc_rings(ethsw); |
| 2778 | 2774 | if (err) |
| 2779 | − goto err_drain_dpbp; | |
| 2775 | + goto err_free_dpbp; | |
| 2780 | 2776 | |
| 2781 | 2777 | err = dpaa2_switch_setup_dpio(ethsw); |
| 2782 | 2778 | if (err) |
| 2783 | 2779 | goto err_destroy_rings; |
| 2784 | 2780 | |
| 2781 | + err = dpaa2_switch_seed_bp(ethsw); | |
| 2782 | + if (err) | |
| 2783 | + goto err_deregister_dpio; | |
| 2784 | + | |
| 2785 | 2785 | err = dpsw_ctrl_if_enable(ethsw->mc_io, 0, ethsw->dpsw_handle); |
| 2786 | 2786 | if (err) { |
| 2787 | 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 | 2791 | return 0; |
| 2792 | 2792 | |
| 2793 | +err_drain_dpbp: | |
| 2794 | + dpaa2_switch_drain_bp(ethsw); | |
| 2793 | 2795 | err_deregister_dpio: |
| 2794 | 2796 | dpaa2_switch_free_dpio(ethsw); |
| 2795 | 2797 | err_destroy_rings: |
| 2796 | 2798 | dpaa2_switch_destroy_rings(ethsw); |
| 2797 | −err_drain_dpbp: | |
| 2798 | − dpaa2_switch_drain_bp(ethsw); | |
| 2799 | 2799 | err_free_dpbp: |
| 2800 | 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 | 524 | | SUPPORTED_Autoneg \ |
| 525 | 525 | | SUPPORTED_Pause \ |
| 526 | 526 | | SUPPORTED_Asym_Pause \ |
| 527 | + | SUPPORTED_FIBRE \ | |
| 527 | 528 | | SUPPORTED_MII) |
| 528 | 529 | |
| 529 | 530 | static DEFINE_MUTEX(eth_lock); |
| @@ -131,7 +131,7 @@ · 130 unmodified lines | ||
| 131 | 131 | /* buf unit size is cache_line_size, which is 64, so the shift is 6 */ |
| 132 | 132 | #define PPE_BUF_SIZE_SHIFT 6 |
| 133 | 133 | #define PPE_TX_BUF_HOLD BIT(31) |
| 134 | −#define CACHE_LINE_MASK 0x3F | |
| 134 | +#define SOC_CACHE_LINE_MASK 0x3F | |
| 135 | 135 | #else |
| 136 | 136 | #define PPE_CFG_QOS_VMID_GRP_SHIFT 8 |
| 137 | 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 | 531 | #if defined(CONFIG_HI13X1_GMAC) |
| 532 | 532 | desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV |
| 533 | 533 | | TX_RELEASE_TO_PPE | priv->port << TX_POOL_SHIFT); |
| 534 | − desc->data_offset = (__force u32)cpu_to_be32(phys & CACHE_LINE_MASK); | |
| 535 | − desc->send_addr = (__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 & ~SOC_CACHE_LINE_MASK); | |
| 536 | 536 | #else |
| 537 | 537 | desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV); |
| 538 | 538 | desc->send_addr = (__force u32)cpu_to_be32(phys); |
| @@ -98,6 +98,7 @@ struct hclgevf_mbx_resp_status { · 97 unmodified lines | ||
| 98 | 98 | u32 origin_mbx_msg; |
| 99 | 99 | bool received_resp; |
| 100 | 100 | int resp_status; |
| 101 | + u16 match_id; | |
| 101 | 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 | 144 | u8 mbx_need_resp; |
| 144 | 145 | u8 rsv1[1]; |
| 145 | 146 | u8 msg_len; |
| 146 | − u8 rsv2[3]; | |
| 147 | + u8 rsv2; | |
| 148 | + u16 match_id; | |
| 147 | 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 | 155 | u8 dest_vfid; |
| 154 | 156 | u8 rsv[3]; |
| 155 | 157 | u8 msg_len; |
| 156 | − u8 rsv1[3]; | |
| 158 | + u8 rsv1; | |
| 159 | + u16 match_id; | |
| 157 | 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 | 9552 | if (ret) |
| 9553 | 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 | 9556 | ret = hclge_set_port_vlan_filter_bypass(hdev, vport->vport_id, |
| 9557 | 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 | 9562 | ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, |
| 9560 | 9563 | HCLGE_FILTER_FE_INGRESS, |
| 9561 | 9564 | enable, 0); |
| 9565 | + } | |
| 9562 | 9566 | |
| 9563 | 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 | 48 | resp_pf_to_vf->dest_vfid = vf_to_pf_req->mbx_src_vfid; |
| 49 | 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 | 52 | resp_pf_to_vf->msg.code = HCLGE_MBX_PF_VF_RESP; |
| 52 | 53 | resp_pf_to_vf->msg.vf_mbx_msg_code = vf_to_pf_req->msg.code; |
| @@ -5,9 +5,27 @@ · 4 unmodified lines | ||
| 5 | 5 | #include "hclge_main.h" |
| 6 | 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 | 25 | static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) |
| 9 | 26 | { |
| 10 | 27 | struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp); |
| 28 | + struct hclge_ptp_cycle *cycle = &hdev->ptp->cycle; | |
| 11 | 29 | u64 adj_val, adj_base, diff; |
| 12 | 30 | unsigned long flags; |
| 13 | 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 | 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 | 40 | adj_val = adj_base * ppb; |
| 23 | 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 | 48 | /* This clock cycle is defined by three part: quotient, numerator |
| 31 | 49 | * and denominator. For example, 2.5ns, the quotient is 2, |
| 32 | − * denominator is fixed to HCLGE_PTP_CYCLE_ADJ_UNIT, and numerator | |
| 33 | − * is 0.5 * HCLGE_PTP_CYCLE_ADJ_UNIT. | |
| 50 | + * denominator is fixed to ptp->cycle.den, and numerator | |
| 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 | 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 | 58 | writel(numerator, hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG); |
| 40 | − writel(HCLGE_PTP_CYCLE_ADJ_UNIT, | |
| 41 | − hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG); | |
| 59 | + writel(cycle->den, hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG); | |
| 42 | 60 | writel(HCLGE_PTP_CYCLE_ADJ_EN, |
| 43 | 61 | hdev->ptp->io_base + HCLGE_PTP_CYCLE_CFG_REG); |
| 44 | 62 | spin_unlock_irqrestore(&hdev->ptp->lock, flags); |
| @@ -475,6 +493,10 @@ int hclge_ptp_init(struct hclge_dev *hdev) · 430 unmodified lines | ||
| 475 | 493 | ret = hclge_ptp_create_clock(hdev); |
| 476 | 494 | if (ret) |
| 477 | 495 | return ret; |
| 496 | + | |
| 497 | + ret = hclge_ptp_get_cycle(hdev); | |
| 498 | + if (ret) | |
| 499 | + return ret; | |
| 478 | 500 | } |
| 479 | 501 | |
| 480 | 502 | ret = hclge_ptp_int_en(hdev, true); |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #define HCLGE_PTP_TIME_ADJ_REG 0x60 |
| 30 | 30 | #define HCLGE_PTP_TIME_ADJ_EN BIT(0) |
| 31 | 31 | #define HCLGE_PTP_CYCLE_QUO_REG 0x64 |
| 32 | +#define HCLGE_PTP_CYCLE_QUO_MASK GENMASK(7, 0) | |
| 32 | 33 | #define HCLGE_PTP_CYCLE_DEN_REG 0x68 |
| 33 | 34 | #define HCLGE_PTP_CYCLE_NUM_REG 0x6C |
| 34 | 35 | #define HCLGE_PTP_CYCLE_CFG_REG 0x70 |
| @@ -37,9 +38,7 @@ · 2 unmodified lines | ||
| 37 | 38 | #define HCLGE_PTP_CUR_TIME_SEC_L_REG 0x78 |
| 38 | 39 | #define HCLGE_PTP_CUR_TIME_NSEC_REG 0x7C |
| 39 | 40 | |
| 40 | −#define HCLGE_PTP_CYCLE_ADJ_BASE 2 | |
| 41 | 41 | #define HCLGE_PTP_CYCLE_ADJ_MAX 500000000 |
| 42 | −#define HCLGE_PTP_CYCLE_ADJ_UNIT 100000000 | |
| 43 | 42 | #define HCLGE_PTP_SEC_H_OFFSET 32u |
| 44 | 43 | #define HCLGE_PTP_SEC_L_MASK GENMASK(31, 0) |
| 45 | 44 | |
| @@ -47,6 +46,12 @@ · 1 unmodified line | ||
| 47 | 46 | #define HCLGE_PTP_FLAG_TX_EN 1 |
| 48 | 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 | 55 | struct hclge_ptp { |
| 51 | 56 | struct hclge_dev *hdev; |
| 52 | 57 | struct ptp_clock *clock; |
| @@ -58,6 +63,7 @@ struct hclge_ptp { · 5 unmodified lines | ||
| 58 | 63 | spinlock_t lock; /* protects ptp registers */ |
| 59 | 64 | u32 ptp_cfg; |
| 60 | 65 | u32 last_tx_seqid; |
| 66 | + struct hclge_ptp_cycle cycle; | |
| 61 | 67 | unsigned long tx_start; |
| 62 | 68 | unsigned long tx_cnt; |
| 63 | 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 | 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 | 2654 | return hclgevf_set_vlan_filter(&hdev->nic, htons(ETH_P_8021Q), 0, |
| 2645 | 2655 | false); |
| 2646 | 2656 | } |
| @@ -13,6 +13,7 @@ static int hclgevf_resp_to_errno(u16 resp_code) · 12 unmodified lines | ||
| 13 | 13 | return resp_code ? -resp_code : 0; |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | +#define HCLGEVF_MBX_MATCH_ID_START 1 | |
| 16 | 17 | static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev *hdev) |
| 17 | 18 | { |
| 18 | 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 | 22 | hdev->mbx_resp.received_resp = false; |
| 22 | 23 | hdev->mbx_resp.origin_mbx_msg = 0; |
| 23 | 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 | 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 | 120 | if (need_resp) { |
| 116 | 121 | mutex_lock(&hdev->mbx_resp.mbx_mutex); |
| 117 | 122 | hclgevf_reset_mbx_resp_status(hdev); |
| 123 | + req->match_id = hdev->mbx_resp.match_id; | |
| 118 | 124 | status = hclgevf_cmd_send(&hdev->hw, &desc, 1); |
| 119 | 125 | if (status) { |
| 120 | 126 | dev_err(&hdev->pdev->dev, |
| @@ -211,6 +217,19 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) · 90 unmodified lines | ||
| 211 | 217 | resp->additional_info[i] = *temp; |
| 212 | 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 | 233 | break; |
| 215 | 234 | case HCLGE_MBX_LINK_STAT_CHANGE: |
| 216 | 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 | 1731 | tx_send_failed++; |
| 1732 | 1732 | tx_dropped++; |
| 1733 | 1733 | ret = NETDEV_TX_OK; |
| 1734 | − ibmvnic_tx_scrq_flush(adapter, tx_scrq); | |
| 1735 | 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 | 1752 | dev_kfree_skb_any(skb); |
| 1754 | 1753 | tx_send_failed++; |
| 1755 | 1754 | tx_dropped++; |
| 1755 | + ibmvnic_tx_scrq_flush(adapter, tx_scrq); | |
| 1756 | 1756 | ret = NETDEV_TX_OK; |
| 1757 | 1757 | goto out; |
| 1758 | 1758 | } |
| @@ -980,7 +980,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, · 979 unmodified lines | ||
| 980 | 980 | default: |
| 981 | 981 | /* if we got here and link is up something bad is afoot */ |
| 982 | 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 | 984 | hw_link_info->phy_type); |
| 985 | 985 | } |
| 986 | 986 | |
| @@ -5294,6 +5294,10 @@ flags_complete: · 4307 unmodified lines | ||
| 5294 | 5294 | dev_warn(&pf->pdev->dev, |
| 5295 | 5295 | "Device configuration forbids SW from starting the LLDP agent.\n"); |
| 5296 | 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 | 5301 | default: |
| 5298 | 5302 | dev_warn(&pf->pdev->dev, |
| 5299 | 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 | 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 | 4462 | struct i40e_pf *pf = vsi->back; |
| 4464 | 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 | 4466 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { |
| 4468 | 4467 | ret = i40e_control_wait_tx_q(vsi->seid, pf, |
| 4469 | 4468 | pf_q, |
| 4470 | − false /*is xdp*/, enable); | |
| 4469 | + false /*is xdp*/, true); | |
| 4471 | 4470 | if (ret) |
| 4472 | 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 | 4476 | ret = i40e_control_wait_tx_q(vsi->seid, pf, |
| 4478 | 4477 | pf_q + vsi->alloc_queue_pairs, |
| 4479 | − true /*is xdp*/, enable); | |
| 4478 | + true /*is xdp*/, true); | |
| 4480 | 4479 | if (ret) |
| 4481 | 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 | 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 | 4581 | struct i40e_pf *pf = vsi->back; |
| 4584 | 4582 | int i, pf_q, ret = 0; |
| 4585 | 4583 | |
| 4586 | 4584 | pf_q = vsi->base_queue; |
| 4587 | 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 | 4587 | if (ret) { |
| 4590 | 4588 | dev_info(&pf->pdev->dev, |
| 4591 | − "VSI seid %d Rx ring %d %sable timeout\n", | |
| 4592 | − vsi->seid, pf_q, (enable ? "en" : "dis")); | |
| 4589 | + "VSI seid %d Rx ring %d enable timeout\n", | |
| 4590 | + vsi->seid, pf_q); | |
| 4593 | 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 | 4595 | return ret; |
| 4604 | 4596 | } |
| 4605 | 4597 | |
| @@ -4612,29 +4604,47 @@ int i40e_vsi_start_rings(struct i40e_vsi *vsi) · 6 unmodified lines | ||
| 4612 | 4604 | int ret = 0; |
| 4613 | 4605 | |
| 4614 | 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 | 4608 | if (ret) |
| 4617 | 4609 | return ret; |
| 4618 | − ret = i40e_vsi_control_tx(vsi, true); | |
| 4610 | + ret = i40e_vsi_enable_tx(vsi); | |
| 4619 | 4611 | |
| 4620 | 4612 | return ret; |
| 4621 | 4613 | } |
| 4622 | 4614 | |
| 4615 | +#define I40E_DISABLE_TX_GAP_MSEC 50 | |
| 4616 | + | |
| 4623 | 4617 | /** |
| 4624 | 4618 | * i40e_vsi_stop_rings - Stop a VSI's rings |
| 4625 | 4619 | * @vsi: the VSI being configured |
| 4626 | 4620 | **/ |
| 4627 | 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 | 4626 | /* When port TX is suspended, don't wait */ |
| 4630 | 4627 | if (test_bit(__I40E_PORT_SUSPENDED, vsi->back->state)) |
| 4631 | 4628 | return i40e_vsi_stop_rings_no_wait(vsi); |
| 4632 | 4629 | |
| 4633 | − /* do rx first for enable and last for disable | |
| 4634 | − * Ignore return value, we need to shutdown whatever we can | |
| 4635 | − */ | |
| 4636 | − i40e_vsi_control_tx(vsi, false); | |
| 4637 | − i40e_vsi_control_rx(vsi, false); | |
| 4630 | + q_end = vsi->base_queue + vsi->num_queue_pairs; | |
| 4631 | + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) | |
| 4632 | + i40e_pre_tx_queue_cfg(&pf->hw, (u32)pf_q, false); | |
| 4633 | + | |
| 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 | 7291 | if (vsi->num_queue_pairs < |
| 7282 | 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 | 7295 | return -EINVAL; |
| 7284 | 7296 | } |
| 7285 | 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 | 13273 | .ndo_poll_controller = i40e_netpoll, |
| 13262 | 13274 | #endif |
| 13263 | 13275 | .ndo_setup_tc = __i40e_setup_tc, |
| 13276 | + .ndo_select_queue = i40e_lan_select_queue, | |
| 13264 | 13277 | .ndo_set_features = i40e_set_features, |
| 13265 | 13278 | .ndo_set_vf_mac = i40e_ndo_set_vf_mac, |
| 13266 | 13279 | .ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan, |
| @@ -3631,6 +3631,56 @@ dma_error: · 3630 unmodified lines | ||
| 3631 | 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 | 3685 | * i40e_xmit_xdp_ring - transmits an XDP buffer to an XDP Tx ring |
| 3636 | 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 | 452 | bool i40e_alloc_rx_buffers(struct i40e_ring *rxr, u16 cleaned_count); |
| 453 | 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 | 456 | void i40e_clean_tx_ring(struct i40e_ring *tx_ring); |
| 455 | 457 | void i40e_clean_rx_ring(struct i40e_ring *rx_ring); |
| 456 | 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 | 1825 | struct sk_buff *skb) |
| 1826 | 1826 | { |
| 1827 | 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 | 1831 | dma_sync_single_range_for_cpu(rx_ring->dev, |
| 1831 | 1832 | IXGBE_CB(skb)->dma, |
| @@ -10,4 +10,4 @@ obj-$(CONFIG_OCTEONTX2_AF) += rvu_af.o · 9 unmodified lines | ||
| 10 | 10 | rvu_mbox-y := mbox.o rvu_trace.o |
| 11 | 11 | rvu_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \ |
| 12 | 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 | 1505 | /* Add reference */ |
| 1506 | 1506 | cgx->lmac_idmap[lmac->lmac_id] = lmac; |
| 1507 | − cgx->mac_ops->mac_pause_frm_config(cgx, lmac->lmac_id, true); | |
| 1508 | 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 | 1511 | return cgx_lmac_verify_fwi_version(cgx); |
| @@ -151,7 +151,10 @@ enum npc_kpu_lh_ltype { · 150 unmodified lines | ||
| 151 | 151 | * Software assigns pkind for each incoming port such as CGX |
| 152 | 152 | * Ethernet interfaces, LBK interfaces, etc. |
| 153 | 153 | */ |
| 154 | +#define NPC_UNRESERVED_PKIND_COUNT NPC_RX_VLAN_EXDSA_PKIND | |
| 155 | + | |
| 154 | 156 | enum npc_pkind_type { |
| 157 | + NPC_RX_LBK_PKIND = 0ULL, | |
| 155 | 158 | NPC_RX_VLAN_EXDSA_PKIND = 56ULL, |
| 156 | 159 | NPC_RX_CHLEN24B_PKIND = 57ULL, |
| 157 | 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 | 392 | /* Get numVFs attached to this PF and first HWVF */ |
| 393 | 393 | cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf)); |
| 394 | − *numvfs = (cfg >> 12) & 0xFF; | |
| 395 | − *hwvf = cfg & 0xFFF; | |
| 394 | + if (numvfs) | |
| 395 | + *numvfs = (cfg >> 12) & 0xFF; | |
| 396 | + if (hwvf) | |
| 397 | + *hwvf = cfg & 0xFFF; | |
| 396 | 398 | } |
| 397 | 399 | |
| 398 | 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 | 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 | 1321 | struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); |
| 1320 | 1322 | int blkaddr = BLKADDR_NIX0, vf; |
| @@ -2859,6 +2861,12 @@ static int rvu_enable_sriov(struct rvu *rvu) · 1538 unmodified lines | ||
| 2859 | 2861 | if (!vfs) |
| 2860 | 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 | 2870 | /* Save VFs number for reference in VF interrupts handlers. |
| 2863 | 2871 | * Since interrupts might start arriving during SRIOV enablement |
| 2864 | 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 | 3009 | /* Initialize debugfs */ |
| 3002 | 3010 | rvu_dbg_init(rvu); |
| 3003 | 3011 | |
| 3012 | + mutex_init(&rvu->rswitch.switch_lock); | |
| 3013 | + | |
| 3004 | 3014 | return 0; |
| 3005 | 3015 | err_dl: |
| 3006 | 3016 | rvu_unregister_dl(rvu); |
| @@ -415,6 +415,16 @@ struct npc_kpu_profile_adapter { · 414 unmodified lines | ||
| 415 | 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 | 428 | struct rvu { |
| 419 | 429 | void __iomem *afreg_base; |
| 420 | 430 | void __iomem *pfreg_base; |
| @@ -445,6 +455,7 @@ struct rvu { · 24 unmodified lines | ||
| 445 | 455 | |
| 446 | 456 | /* CGX */ |
| 447 | 457 | #define PF_CGXMAP_BASE 1 /* PF 0 is reserved for RVU PF */ |
| 458 | + u16 cgx_mapped_vfs; /* maximum CGX mapped VFs */ | |
| 448 | 459 | u8 cgx_mapped_pfs; |
| 449 | 460 | u8 cgx_cnt_max; /* CGX port count max */ |
| 450 | 461 | u8 *pf2cgxlmac_map; /* pf to cgx_lmac map */ |
| @@ -477,6 +488,9 @@ struct rvu { · 26 unmodified lines | ||
| 477 | 488 | struct rvu_debugfs rvu_dbg; |
| 478 | 489 | #endif |
| 479 | 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 | 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 | 705 | struct nix_cn10k_aq_enq_req *aq_req, |
| 692 | 706 | struct nix_cn10k_aq_enq_rsp *aq_rsp, |
| 693 | 707 | u16 pcifunc, u8 ctype, u32 qidx); |
| 708 | +int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc); | |
| 694 | 709 | |
| 695 | 710 | /* NPC APIs */ |
| 696 | 711 | int rvu_npc_init(struct rvu *rvu); |
| @@ -768,4 +783,10 @@ void rvu_dbg_exit(struct rvu *rvu); · 71 unmodified lines | ||
| 768 | 783 | static inline void rvu_dbg_init(struct rvu *rvu) {} |
| 769 | 784 | static inline void rvu_dbg_exit(struct rvu *rvu) {} |
| 770 | 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 | 792 | #endif /* RVU_H */ |
| @@ -126,6 +126,7 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu) · 125 unmodified lines | ||
| 126 | 126 | unsigned long lmac_bmap; |
| 127 | 127 | int size, free_pkind; |
| 128 | 128 | int cgx, lmac, iter; |
| 129 | + int numvfs, hwvfs; | |
| 129 | 130 | |
| 130 | 131 | if (!cgx_cnt_max) |
| 131 | 132 | return 0; |
| @@ -166,6 +167,8 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu) · 34 unmodified lines | ||
| 166 | 167 | pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16; |
| 167 | 168 | rvu_map_cgx_nix_block(rvu, pf, cgx, lmac); |
| 168 | 169 | rvu->cgx_mapped_pfs++; |
| 170 | + rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvfs); | |
| 171 | + rvu->cgx_mapped_vfs += numvfs; | |
| 169 | 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 | 2113 | int entry_acnt, entry_ecnt; |
| 2114 | 2114 | int cntr_acnt, cntr_ecnt; |
| 2115 | 2115 | |
| 2116 | − /* Skip PF0 */ | |
| 2117 | − if (!pcifunc) | |
| 2118 | − return; | |
| 2119 | 2116 | rvu_npc_get_mcam_entry_alloc_info(rvu, pcifunc, blkaddr, |
| 2120 | 2117 | &entry_acnt, &entry_ecnt); |
| 2121 | 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 | 2295 | static void rvu_dbg_npc_mcam_show_action(struct seq_file *s, |
| 2299 | 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 | 2299 | switch (rule->tx_action.op) { |
| 2303 | 2300 | case NIX_TX_ACTIONOP_DROP: |
| 2304 | 2301 | seq_puts(s, "\taction: Drop\n"); |
| @@ -1364,6 +1364,44 @@ static void rvu_health_reporters_destroy(struct rvu *rvu) · 1363 unmodified lines | ||
| 1364 | 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 | 1405 | static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, |
| 1368 | 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 | 1411 | static const struct devlink_ops rvu_devlink_ops = { |
| 1374 | 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 | 1417 | int rvu_register_dl(struct rvu *rvu) |
| @@ -1380,14 +1420,9 @@ int rvu_register_dl(struct rvu *rvu) · 2 unmodified lines | ||
| 1380 | 1420 | struct devlink *dl; |
| 1381 | 1421 | int err; |
| 1382 | 1422 | |
| 1383 | − rvu_dl = kzalloc(sizeof(*rvu_dl), GFP_KERNEL); | |
| 1384 | − if (!rvu_dl) | |
| 1385 | − return -ENOMEM; | |
| 1386 | − | |
| 1387 | 1423 | dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink)); |
| 1388 | 1424 | if (!dl) { |
| 1389 | 1425 | dev_warn(rvu->dev, "devlink_alloc failed\n"); |
| 1390 | − kfree(rvu_dl); | |
| 1391 | 1426 | return -ENOMEM; |
| 1392 | 1427 | } |
| 1393 | 1428 | |
| @@ -1395,10 +1430,10 @@ int rvu_register_dl(struct rvu *rvu) · 1 unmodified line | ||
| 1395 | 1430 | if (err) { |
| 1396 | 1431 | dev_err(rvu->dev, "devlink register failed with error %d\n", err); |
| 1397 | 1432 | devlink_free(dl); |
| 1398 | − kfree(rvu_dl); | |
| 1399 | 1433 | return err; |
| 1400 | 1434 | } |
| 1401 | 1435 | |
| 1436 | + rvu_dl = devlink_priv(dl); | |
| 1402 | 1437 | rvu_dl->dl = dl; |
| 1403 | 1438 | rvu_dl->rvu = rvu; |
| 1404 | 1439 | rvu->rvu_dl = rvu_dl; |
| @@ -1417,5 +1452,4 @@ void rvu_unregister_dl(struct rvu *rvu) · 12 unmodified lines | ||
| 1417 | 1452 | rvu_health_reporters_destroy(rvu); |
| 1418 | 1453 | devlink_unregister(dl); |
| 1419 | 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 | 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 | 200 | rvu_write64(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0)); |
| 201 | 201 | err = rvu_poll_reg(rvu, blkaddr, NIX_AF_RX_SW_SYNC, BIT_ULL(0), true); |
| 202 | 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 | 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 | 309 | rvu_nix_chan_lbk(rvu, lbkid, vf + 1); |
| 299 | 310 | pfvf->rx_chan_cnt = 1; |
| 300 | 311 | pfvf->tx_chan_cnt = 1; |
| 312 | + rvu_npc_set_pkind(rvu, NPC_RX_LBK_PKIND, pfvf); | |
| 301 | 313 | rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf, |
| 302 | 314 | pfvf->rx_chan_base, |
| 303 | 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 | 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 | 1996 | int rvu_mbox_handler_nix_txschq_cfg(struct rvu *rvu, |
| 1956 | 1997 | struct nix_txschq_config *req, |
| 1957 | 1998 | struct msg_rsp *rsp) |
| @@ -2040,6 +2081,9 @@ int rvu_mbox_handler_nix_txschq_cfg(struct rvu *rvu, · 82 unmodified lines | ||
| 2040 | 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 | 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 | 3224 | if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf) |
| 3181 | 3225 | ether_addr_copy(pfvf->default_mac, req->mac_addr); |
| 3182 | 3226 | |
| 3227 | + rvu_switch_update_rules(rvu, pcifunc); | |
| 3228 | + | |
| 3183 | 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 | 3854 | vlan = &nix_hw->txvlan; |
| 3809 | 3855 | kfree(vlan->rsrc.bmap); |
| 3810 | 3856 | mutex_destroy(&vlan->rsrc_lock); |
| 3811 | − devm_kfree(rvu->dev, vlan->entry2pfvf_map); | |
| 3812 | 3857 | |
| 3813 | 3858 | mcast = &nix_hw->mcast; |
| 3814 | 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 | 3894 | pfvf = rvu_get_pfvf(rvu, pcifunc); |
| 3850 | 3895 | set_bit(NIXLF_INITIALIZED, &pfvf->flags); |
| 3851 | 3896 | |
| 3897 | + rvu_switch_update_rules(rvu, pcifunc); | |
| 3898 | + | |
| 3852 | 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 | 442 | owner = mcam->entry2pfvf_map[index]; |
| 443 | 443 | target_func = (entry->action >> 4) & 0xffff; |
| 444 | 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 | 447 | !(target_func & RVU_PFVF_FUNC_MASK)) |
| 447 | 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 | 470 | int bank = npc_get_bank(mcam, index); |
| 470 | 471 | int kw = 0, actbank, actindex; |
| 472 | + u8 tx_intf_mask = ~intf & 0x3; | |
| 473 | + u8 tx_intf = intf; | |
| 471 | 474 | u64 cam0, cam1; |
| 472 | 475 | |
| 473 | 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 | 492 | for (; bank < (actbank + mcam->banks_per_entry); bank++, kw = kw + 2) { |
| 490 | 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 | 503 | rvu_write64(rvu, blkaddr, |
| 492 | 504 | NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 1), |
| 493 | − intf); | |
| 505 | + tx_intf); | |
| 494 | 506 | rvu_write64(rvu, blkaddr, |
| 495 | 507 | NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 0), |
| 496 | − ~intf & 0x3); | |
| 508 | + tx_intf_mask); | |
| 497 | 509 | |
| 498 | 510 | /* Set the match key */ |
| 499 | 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 | 662 | eth_broadcast_addr((u8 *)&req.mask.dmac); |
| 651 | 663 | req.features = BIT_ULL(NPC_DMAC); |
| 652 | 664 | req.channel = chan; |
| 665 | + req.chan_mask = 0xFFFU; | |
| 653 | 666 | req.intf = pfvf->nix_rx_intf; |
| 654 | 667 | req.op = action.op; |
| 655 | 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 | 812 | eth_broadcast_addr((u8 *)&req.mask.dmac); |
| 800 | 813 | req.features = BIT_ULL(NPC_DMAC); |
| 801 | 814 | req.channel = chan; |
| 815 | + req.chan_mask = 0xFFFU; | |
| 802 | 816 | req.intf = pfvf->nix_rx_intf; |
| 803 | 817 | req.entry = index; |
| 804 | 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 | 1722 | struct rvu_hwinfo *hw = rvu->hw; |
| 1709 | 1723 | int num_pkinds, num_kpus, idx; |
| 1710 | − struct npc_pkind *pkind; | |
| 1711 | 1724 | |
| 1712 | 1725 | /* Disable all KPUs and their entries */ |
| 1713 | 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 | 1738 | * Check HW max count to avoid configuring junk or |
| 1726 | 1739 | * writing to unsupported CSR addresses. |
| 1727 | 1740 | */ |
| 1728 | − pkind = &hw->pkind; | |
| 1729 | 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 | 1744 | for (idx = 0; idx < num_pkinds; idx++) |
| 1733 | 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 | 1757 | int nixlf_count = rvu_get_nixlf_count(rvu); |
| 1746 | 1758 | struct npc_mcam *mcam = &rvu->hw->mcam; |
| 1747 | 1759 | int rsvd, err; |
| 1760 | + u16 index; | |
| 1761 | + int cntr; | |
| 1748 | 1762 | u64 cfg; |
| 1749 | 1763 | |
| 1750 | 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 | 1859 | if (!mcam->entry2target_pffunc) |
| 1846 | 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 | 1870 | mutex_init(&mcam->lock); |
| 1849 | 1871 | |
| 1850 | 1872 | return 0; |
| @@ -1867,7 +1889,8 @@ static void rvu_npc_hw_init(struct rvu *rvu, int blkaddr) · 16 unmodified lines | ||
| 1867 | 1889 | if (npc_const1 & BIT_ULL(63)) |
| 1868 | 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 | 1894 | hw->npc_kpu_entries = npc_const1 & 0xFFFULL; |
| 1872 | 1895 | hw->npc_kpus = (npc_const >> 8) & 0x1FULL; |
| 1873 | 1896 | hw->npc_intfs = npc_const & 0xFULL; |
| @@ -1978,6 +2001,10 @@ int rvu_npc_init(struct rvu *rvu) · 104 unmodified lines | ||
| 1978 | 2001 | err = rvu_alloc_bitmap(&pkind->rsrc); |
| 1979 | 2002 | if (err) |
| 1980 | 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 | 2009 | /* Allocate mem for pkind to PF and channel mapping info */ |
| 1983 | 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 | 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 | 2593 | return NPC_MCAM_ALLOC_DENIED; |
| 2567 | 2594 | |
| 2568 | 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 | 2609 | return NPC_MCAM_INVALID_REQ; |
| 2583 | 2610 | |
| 2584 | 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 | 2613 | return NPC_MCAM_INVALID_REQ; |
| 2587 | 2614 | |
| 2588 | 2615 | mutex_lock(&mcam->lock); |
| @@ -2594,7 +2621,7 @@ int rvu_mbox_handler_npc_mcam_free_entry(struct rvu *rvu, · 5 unmodified lines | ||
| 2594 | 2621 | if (rc) |
| 2595 | 2622 | goto exit; |
| 2596 | 2623 | |
| 2597 | − mcam->entry2pfvf_map[req->entry] = 0; | |
| 2624 | + mcam->entry2pfvf_map[req->entry] = NPC_MCAM_INVALID_MAP; | |
| 2598 | 2625 | mcam->entry2target_pffunc[req->entry] = 0x0; |
| 2599 | 2626 | npc_mcam_clear_bit(mcam, req->entry); |
| 2600 | 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 | 2706 | else |
| 2680 | 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 | 2711 | rc = NPC_MCAM_INVALID_REQ; |
| 2684 | 2712 | goto exit; |
| 2685 | 2713 | } |
| 2686 | 2714 | |
| 2687 | − if (npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf, | |
| 2688 | − pcifunc)) { | |
| 2715 | + if (!is_pffunc_af(pcifunc) && | |
| 2716 | + npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf, pcifunc)) { | |
| 2689 | 2717 | rc = NPC_MCAM_INVALID_REQ; |
| 2690 | 2718 | goto exit; |
| 2691 | 2719 | } |
| @@ -2836,7 +2864,7 @@ int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu, · 144 unmodified lines | ||
| 2836 | 2864 | return NPC_MCAM_INVALID_REQ; |
| 2837 | 2865 | |
| 2838 | 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 | 2868 | return NPC_MCAM_INVALID_REQ; |
| 2841 | 2869 | |
| 2842 | 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 | 3109 | if (rc) { |
| 3082 | 3110 | /* Free allocated MCAM entry */ |
| 3083 | 3111 | mutex_lock(&mcam->lock); |
| 3084 | − mcam->entry2pfvf_map[entry] = 0; | |
| 3112 | + mcam->entry2pfvf_map[entry] = NPC_MCAM_INVALID_MAP; | |
| 3085 | 3113 | npc_mcam_clear_bit(mcam, entry); |
| 3086 | 3114 | mutex_unlock(&mcam->lock); |
| 3087 | 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 | 911 | static void npc_update_rx_entry(struct rvu *rvu, struct rvu_pfvf *pfvf, |
| 912 | 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 | 917 | struct nix_rx_action action; |
| 916 | − u64 chan_mask; | |
| 917 | 918 | |
| 918 | − chan_mask = req->chan_mask ? req->chan_mask : ~0ULL; | |
| 919 | − npc_update_entry(rvu, NPC_CHAN, entry, req->channel, 0, chan_mask, 0, | |
| 920 | − NIX_INTF_RX); | |
| 919 | + if (rswitch->mode == DEVLINK_ESWITCH_MODE_SWITCHDEV && pf_set_vfs_mac) | |
| 920 | + req->chan_mask = 0x0; /* Do not care channel */ | |
| 921 | + | |
| 922 | + npc_update_entry(rvu, NPC_CHAN, entry, req->channel, 0, req->chan_mask, | |
| 923 | + 0, NIX_INTF_RX); | |
| 921 | 924 | |
| 922 | 925 | *(u64 *)&action = 0x00; |
| 923 | 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 | 952 | struct npc_install_flow_req *req, u16 target) |
| 950 | 953 | { |
| 951 | 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 | 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 | 966 | *(u64 *)&action = 0x00; |
| 957 | 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 | 1012 | req->intf); |
| 1003 | 1013 | |
| 1004 | 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 | 1016 | else |
| 1007 | 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 | 1174 | if (err) |
| 1165 | 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 | 1180 | return -EINVAL; |
| 1169 | 1181 | |
| 1170 | 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 | 1192 | eth_broadcast_addr((u8 *)&req->mask.dmac); |
| 1181 | 1193 | } |
| 1182 | 1194 | |
| 1195 | + /* Proceed if NIXLF is attached or not for TX rules */ | |
| 1183 | 1196 | err = nix_get_nixlf(rvu, target, &nixlf, NULL); |
| 1184 | 1197 | if (err && is_npc_intf_rx(req->intf) && !pf_set_vfs_mac) |
| 1185 | 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 | 924 | aq->cq.drop = RQ_DROP_LVL_CQ(pfvf->hw.rq_skid, cq->cqe_cnt); |
| 925 | 925 | aq->cq.drop_ena = 1; |
| 926 | 926 | |
| 927 | − /* Enable receive CQ backpressure */ | |
| 928 | − aq->cq.bp_ena = 1; | |
| 929 | − aq->cq.bpid = pfvf->bpid[0]; | |
| 927 | + if (!is_otx2_lbkvf(pfvf->pdev)) { | |
| 928 | + /* Enable receive CQ backpressure */ | |
| 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 | − aq->cq.bp = RQ_PASS_LVL_CQ(pfvf->hw.rq_skid, qset->rqe_cnt); | |
| 932 | + /* Set backpressure level is same as cq pass level */ | |
| 933 | + aq->cq.bp = RQ_PASS_LVL_CQ(pfvf->hw.rq_skid, qset->rqe_cnt); | |
| 934 | + } | |
| 933 | 935 | } |
| 934 | 936 | |
| 935 | 937 | /* Fill AQ info */ |
| @@ -1186,7 +1188,7 @@ static int otx2_aura_init(struct otx2_nic *pfvf, int aura_id, · 250 unmodified lines | ||
| 1186 | 1188 | aq->aura.fc_hyst_bits = 0; /* Store count on all updates */ |
| 1187 | 1189 | |
| 1188 | 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 | 1192 | aq->aura.bp_ena = 0; |
| 1191 | 1193 | aq->aura.nix0_bpid = pfvf->bpid[0]; |
| 1192 | 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 | 298 | err = otx2_set_real_num_queues(dev, channel->tx_count, |
| 299 | 299 | channel->rx_count); |
| 300 | 300 | if (err) |
| 301 | − goto fail; | |
| 301 | + return err; | |
| 302 | 302 | |
| 303 | 303 | pfvf->hw.rx_queues = channel->rx_count; |
| 304 | 304 | pfvf->hw.tx_queues = channel->tx_count; |
| 305 | 305 | pfvf->qset.cq_cnt = pfvf->hw.tx_queues + pfvf->hw.rx_queues; |
| 306 | 306 | |
| 307 | −fail: | |
| 308 | 307 | if (if_up) |
| 309 | − dev->netdev_ops->ndo_open(dev); | |
| 308 | + err = dev->netdev_ops->ndo_open(dev); | |
| 310 | 309 | |
| 311 | 310 | netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n", |
| 312 | 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 | 409 | qs->rqe_cnt = rx_count; |
| 411 | 410 | |
| 412 | 411 | if (if_up) |
| 413 | − netdev->netdev_ops->ndo_open(netdev); | |
| 412 | + return netdev->netdev_ops->ndo_open(netdev); | |
| 414 | 413 | |
| 415 | 414 | return 0; |
| 416 | 415 | } |
| @@ -1662,6 +1662,7 @@ int otx2_open(struct net_device *netdev) · 1661 unmodified lines | ||
| 1662 | 1662 | err_tx_stop_queues: |
| 1663 | 1663 | netif_tx_stop_all_queues(netdev); |
| 1664 | 1664 | netif_carrier_off(netdev); |
| 1665 | + pf->flags |= OTX2_FLAG_INTF_DOWN; | |
| 1665 | 1666 | err_free_cints: |
| 1666 | 1667 | otx2_free_cints(pf, qidx); |
| 1667 | 1668 | vec = pci_irq_vector(pf->pdev, |
| @@ -1689,6 +1690,10 @@ int otx2_stop(struct net_device *netdev) · 21 unmodified lines | ||
| 1689 | 1690 | struct otx2_rss_info *rss; |
| 1690 | 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 | 1697 | netif_carrier_off(netdev); |
| 1693 | 1698 | netif_tx_stop_all_queues(netdev); |
| 1694 | 1699 | |
| @@ -3535,6 +3535,7 @@ slave_start: · 3534 unmodified lines | ||
| 3535 | 3535 | |
| 3536 | 3536 | if (!SRIOV_VALID_STATE(dev->flags)) { |
| 3537 | 3537 | mlx4_err(dev, "Invalid SRIOV state\n"); |
| 3538 | + err = -EINVAL; | |
| 3538 | 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 | 500 | return 1; |
| 501 | 501 | } |
| 502 | 502 | |
| 503 | −/* This function is called with two flows: | |
| 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 | − */ | |
| 503 | +/* Must be called with intf_mutex held */ | |
| 507 | 504 | struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev) |
| 508 | 505 | { |
| 509 | 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 | 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 | 483 | int mlx5e_build_rq_param(struct mlx5_core_dev *mdev, |
| 475 | 484 | struct mlx5e_params *params, |
| 476 | 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 | 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 | 521 | MLX5_SET(wq, wq, log_wq_stride, |
| 513 | 522 | mlx5e_get_rqwq_log_stride(params->rq_wq_type, ndsegs)); |
| 514 | 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 | 482 | params->log_sq_size = orig->log_sq_size; |
| 483 | 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 | 488 | mlx5e_ptp_build_rq_param(c->mdev, c->netdev, c->priv->q_counter, cparams); |
| 489 | + } | |
| 487 | 490 | } |
| 488 | 491 | |
| 489 | 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 | 497 | int err; |
| 495 | 498 | |
| 496 | 499 | rq->wq_type = params->rq_wq_type; |
| 497 | − rq->pdev = mdev->device; | |
| 500 | + rq->pdev = c->pdev; | |
| 498 | 501 | rq->netdev = priv->netdev; |
| 499 | 502 | rq->priv = priv; |
| 500 | 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 | 37 | struct mlx5e_priv *priv = t->priv; |
| 38 | 38 | |
| 39 | 39 | rq->wq_type = params->rq_wq_type; |
| 40 | − rq->pdev = mdev->device; | |
| 40 | + rq->pdev = t->pdev; | |
| 41 | 41 | rq->netdev = priv->netdev; |
| 42 | 42 | rq->priv = priv; |
| 43 | 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 | 3385 | static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd) |
| 3386 | 3386 | { |
| 3387 | − int err = 0; | |
| 3387 | + int err; | |
| 3388 | 3388 | int i; |
| 3389 | 3389 | |
| 3390 | 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 | 3392 | if (err) |
| 3393 | 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 | 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 | 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 | 3852 | static netdev_features_t mlx5e_fix_features(struct net_device *netdev, |
| 3833 | 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 | 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)) { | |
| 3864 | − features &= ~NETIF_F_HW_TLS_RX; | |
| 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 | − } | |
| 3883 | + if (mlx5e_is_uplink_rep(priv)) | |
| 3884 | + features = mlx5e_fix_uplink_rep_features(netdev, features); | |
| 3872 | 3885 | |
| 3873 | 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 | 4872 | if (MLX5_CAP_ETH(mdev, scatter_fcs)) |
| 4860 | 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 | 4878 | netdev->features = netdev->hw_features; |
| 4863 | 4879 | |
| 4864 | 4880 | /* Defaults */ |
| @@ -4879,8 +4895,6 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) · 14 unmodified lines | ||
| 4879 | 4895 | netdev->hw_features |= NETIF_F_NTUPLE; |
| 4880 | 4896 | #endif |
| 4881 | 4897 | } |
| 4882 | − if (mlx5_qos_is_supported(mdev)) | |
| 4883 | − netdev->features |= NETIF_F_HW_TC; | |
| 4884 | 4898 | |
| 4885 | 4899 | netdev->features |= NETIF_F_HIGHDMA; |
| 4886 | 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 | 452 | static |
| 453 | 453 | struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex) |
| 454 | 454 | { |
| 455 | + struct mlx5_core_dev *mdev; | |
| 455 | 456 | struct net_device *netdev; |
| 456 | 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 | 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 | 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 | 687 | func_mdev = priv->mdev; |
| 668 | 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 | 694 | pair = mlx5_core_hairpin_create(func_mdev, peer_mdev, params); |
| 671 | 695 | if (IS_ERR(pair)) { |
| @@ -804,6 +828,11 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, · 132 unmodified lines | ||
| 804 | 828 | int err; |
| 805 | 829 | |
| 806 | 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 | 836 | if (!MLX5_CAP_GEN(priv->mdev, hairpin) || !MLX5_CAP_GEN(peer_mdev, hairpin)) { |
| 808 | 837 | NL_SET_ERR_MSG_MOD(extack, "hairpin is not supported"); |
| 809 | 838 | return -EOPNOTSUPP; |
| @@ -636,7 +636,7 @@ struct esw_vport_tbl_namespace { · 635 unmodified lines | ||
| 636 | 636 | }; |
| 637 | 637 | |
| 638 | 638 | struct mlx5_vport_tbl_attr { |
| 639 | − u16 chain; | |
| 639 | + u32 chain; | |
| 640 | 640 | u16 prio; |
| 641 | 641 | u16 vport; |
| 642 | 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 | 383 | dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_VPORT; |
| 384 | 384 | dest[dest_idx].vport.num = esw_attr->dests[attr_idx].rep->vport; |
| 385 | − dest[dest_idx].vport.vhca_id = | |
| 386 | − MLX5_CAP_GEN(esw_attr->dests[attr_idx].mdev, vhca_id); | |
| 387 | − if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) | |
| 385 | + if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) { | |
| 386 | + dest[dest_idx].vport.vhca_id = | |
| 387 | + MLX5_CAP_GEN(esw_attr->dests[attr_idx].mdev, vhca_id); | |
| 388 | 388 | dest[dest_idx].vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID; |
| 389 | + } | |
| 389 | 390 | if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) { |
| 390 | 391 | if (pkt_reformat) { |
| 391 | 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 | 2369 | switch (event) { |
| 2369 | 2370 | case ESW_OFFLOADS_DEVCOM_PAIR: |
| 2371 | + if (mlx5_get_next_phys_dev(esw->dev) != peer_esw->dev) | |
| 2372 | + break; | |
| 2373 | + | |
| 2370 | 2374 | if (mlx5_eswitch_vport_match_metadata_enabled(esw) != |
| 2371 | 2375 | mlx5_eswitch_vport_match_metadata_enabled(peer_esw)) |
| 2372 | 2376 | break; |
| @@ -1024,17 +1024,19 @@ static int connect_fwd_rules(struct mlx5_core_dev *dev, · 1023 unmodified lines | ||
| 1024 | 1024 | static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table *ft, |
| 1025 | 1025 | struct fs_prio *prio) |
| 1026 | 1026 | { |
| 1027 | − struct mlx5_flow_table *next_ft; | |
| 1027 | + struct mlx5_flow_table *next_ft, *first_ft; | |
| 1028 | 1028 | int err = 0; |
| 1029 | 1029 | |
| 1030 | 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 | 1035 | err = connect_prev_fts(dev, ft, prio); |
| 1034 | 1036 | if (err) |
| 1035 | 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 | 1040 | err = connect_fwd_rules(dev, ft, next_ft); |
| 1039 | 1041 | if (err) |
| 1040 | 1042 | return err; |
| @@ -2120,7 +2122,7 @@ static int disconnect_flow_table(struct mlx5_flow_table *ft) · 1079 unmodified lines | ||
| 2120 | 2122 | node.list) == ft)) |
| 2121 | 2123 | return 0; |
| 2122 | 2124 | |
| 2123 | − next_ft = find_next_chained_ft(prio); | |
| 2125 | + next_ft = find_next_ft(ft); | |
| 2124 | 2126 | err = connect_fwd_rules(dev, next_ft, ft); |
| 2125 | 2127 | if (err) |
| 2126 | 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 | 627 | fw_reporter_ctx.err_synd = health->synd; |
| 628 | 628 | fw_reporter_ctx.miss_counter = health->miss_counter; |
| 629 | − devlink_health_report(health->fw_fatal_reporter, | |
| 630 | − "FW fatal error reported", &fw_reporter_ctx); | |
| 629 | + if (devlink_health_report(health->fw_fatal_reporter, | |
| 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 | 641 | static const struct devlink_health_reporter_ops mlx5_fw_fatal_reporter_ops = { |
| @@ -3,6 +3,7 @@ config SPARX5_SWITCH · 2 unmodified lines | ||
| 3 | 3 | depends on NET_SWITCHDEV |
| 4 | 4 | depends on HAS_IOMEM |
| 5 | 5 | depends on OF |
| 6 | + depends on ARCH_SPARX5 || COMPILE_TEST | |
| 6 | 7 | select PHYLINK |
| 7 | 8 | select PHY_SPARX5_SERDES |
| 8 | 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 | 33 | static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr); |
| 34 | 34 | static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr); |
| 35 | 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 | 53 | cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); |
| 54 | 54 | qcq = container_of(dim, struct ionic_qcq, dim); |
| 55 | 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 | 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 | 90 | switch (w->type) { |
| 79 | 91 | case IONIC_DW_TYPE_RX_MODE: |
| 80 | − ionic_lif_rx_mode(lif, w->rx_mode); | |
| 92 | + ionic_lif_rx_mode(lif); | |
| 81 | 93 | break; |
| 82 | 94 | case IONIC_DW_TYPE_RX_ADDR_ADD: |
| 83 | 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 | 1313 | return 0; |
| 1302 | 1314 | } |
| 1303 | 1315 | |
| 1304 | −static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add, | |
| 1305 | − bool can_sleep) | |
| 1316 | +static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add) | |
| 1306 | 1317 | { |
| 1307 | − struct ionic_deferred_work *work; | |
| 1308 | 1318 | unsigned int nmfilters; |
| 1309 | 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 | 1340 | lif->nucast--; |
| 1331 | 1341 | } |
| 1332 | 1342 | |
| 1333 | − if (!can_sleep) { | |
| 1334 | − work = kzalloc(sizeof(*work), GFP_ATOMIC); | |
| 1335 | − if (!work) | |
| 1336 | − return -ENOMEM; | |
| 1337 | − work->type = add ? IONIC_DW_TYPE_RX_ADDR_ADD : | |
| 1338 | − IONIC_DW_TYPE_RX_ADDR_DEL; | |
| 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 | − } | |
| 1343 | + netdev_dbg(lif->netdev, "rx_filter %s %pM\n", | |
| 1344 | + add ? "add" : "del", addr); | |
| 1345 | + if (add) | |
| 1346 | + return ionic_lif_addr_add(lif, addr); | |
| 1347 | + else | |
| 1348 | + return ionic_lif_addr_del(lif, addr); | |
| 1351 | 1349 | |
| 1352 | 1350 | return 0; |
| 1353 | 1351 | } |
| 1354 | 1352 | |
| 1355 | 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); | |
| 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); | |
| 1355 | + return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR); | |
| 1363 | 1356 | } |
| 1364 | 1357 | |
| 1365 | 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); | |
| 1373 | −} | |
| 1374 | − | |
| 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 | − }; | |
| 1365 | + struct net_device *netdev = lif->netdev; | |
| 1366 | + unsigned int nfilters; | |
| 1367 | + unsigned int nd_flags; | |
| 1385 | 1368 | char buf[128]; |
| 1386 | − int err; | |
| 1369 | + u16 rx_mode; | |
| 1387 | 1370 | int i; |
| 1388 | 1371 | #define REMAIN(__x) (sizeof(buf) - (__x)) |
| 1389 | 1372 | |
| 1390 | − i = scnprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:", | |
| 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 | −} | |
| 1373 | + mutex_lock(&lif->config_lock); | |
| 1411 | 1374 | |
| 1412 | −static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep) | |
| 1413 | −{ | |
| 1414 | − struct ionic_lif *lif = netdev_priv(netdev); | |
| 1415 | − struct ionic_deferred_work *work; | |
| 1416 | − unsigned int nfilters; | |
| 1417 | − unsigned int rx_mode; | |
| 1375 | + /* grab the flags once for local use */ | |
| 1376 | + nd_flags = netdev->flags; | |
| 1418 | 1377 | |
| 1419 | 1378 | rx_mode = IONIC_RX_MODE_F_UNICAST; |
| 1420 | − rx_mode |= (netdev->flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0; | |
| 1421 | − rx_mode |= (netdev->flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0; | |
| 1422 | − rx_mode |= (netdev->flags & IFF_PROMISC) ? IONIC_RX_MODE_F_PROMISC : 0; | |
| 1423 | − rx_mode |= (netdev->flags & IFF_ALLMULTI) ? IONIC_RX_MODE_F_ALLMULTI : 0; | |
| 1379 | + rx_mode |= (nd_flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0; | |
| 1380 | + rx_mode |= (nd_flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0; | |
| 1381 | + rx_mode |= (nd_flags & IFF_PROMISC) ? IONIC_RX_MODE_F_PROMISC : 0; | |
| 1382 | + rx_mode |= (nd_flags & IFF_ALLMULTI) ? IONIC_RX_MODE_F_ALLMULTI : 0; | |
| 1424 | 1383 | |
| 1425 | 1384 | /* sync unicast addresses |
| 1426 | 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 | 1388 | * we remove our overflow flag and check the netdev flags |
| 1430 | 1389 | * to see if we can disable NIC PROMISC |
| 1431 | 1390 | */ |
| 1432 | − if (can_sleep) | |
| 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); | |
| 1391 | + __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del); | |
| 1436 | 1392 | nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); |
| 1437 | 1393 | if (netdev_uc_count(netdev) + 1 > nfilters) { |
| 1438 | 1394 | rx_mode |= IONIC_RX_MODE_F_PROMISC; |
| 1439 | 1395 | lif->uc_overflow = true; |
| 1440 | 1396 | } else if (lif->uc_overflow) { |
| 1441 | 1397 | lif->uc_overflow = false; |
| 1442 | − if (!(netdev->flags & IFF_PROMISC)) | |
| 1398 | + if (!(nd_flags & IFF_PROMISC)) | |
| 1443 | 1399 | rx_mode &= ~IONIC_RX_MODE_F_PROMISC; |
| 1444 | 1400 | } |
| 1445 | 1401 | |
| 1446 | 1402 | /* same for multicast */ |
| 1447 | − if (can_sleep) | |
| 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); | |
| 1403 | + __dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del); | |
| 1451 | 1404 | nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters); |
| 1452 | 1405 | if (netdev_mc_count(netdev) > nfilters) { |
| 1453 | 1406 | rx_mode |= IONIC_RX_MODE_F_ALLMULTI; |
| 1454 | 1407 | lif->mc_overflow = true; |
| 1455 | 1408 | } else if (lif->mc_overflow) { |
| 1456 | 1409 | lif->mc_overflow = false; |
| 1457 | − if (!(netdev->flags & IFF_ALLMULTI)) | |
| 1410 | + if (!(nd_flags & IFF_ALLMULTI)) | |
| 1458 | 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 | 1430 | if (lif->rx_mode != rx_mode) { |
| 1462 | − if (!can_sleep) { | |
| 1463 | − work = kzalloc(sizeof(*work), GFP_ATOMIC); | |
| 1464 | − if (!work) { | |
| 1465 | − netdev_err(lif->netdev, "rxmode change dropped\n"); | |
| 1466 | − return; | |
| 1467 | − } | |
| 1468 | − work->type = IONIC_DW_TYPE_RX_MODE; | |
| 1469 | − work->rx_mode = rx_mode; | |
| 1470 | − netdev_dbg(lif->netdev, "deferred: rx_mode\n"); | |
| 1471 | − ionic_lif_deferred_enqueue(&lif->deferred, work); | |
| 1472 | − } else { | |
| 1473 | − ionic_lif_rx_mode(lif, rx_mode); | |
| 1431 | + struct ionic_admin_ctx ctx = { | |
| 1432 | + .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), | |
| 1433 | + .cmd.rx_mode_set = { | |
| 1434 | + .opcode = IONIC_CMD_RX_MODE_SET, | |
| 1435 | + .lif_index = cpu_to_le16(lif->index), | |
| 1436 | + }, | |
| 1437 | + }; | |
| 1438 | + int err; | |
| 1439 | + | |
| 1440 | + ctx.cmd.rx_mode_set.rx_mode = cpu_to_le16(rx_mode); | |
| 1441 | + err = ionic_adminq_post_wait(lif, &ctx); | |
| 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 | 3051 | ionic_lif_qcq_deinit(lif, lif->notifyqcq); |
| 3059 | 3052 | ionic_lif_qcq_deinit(lif, lif->adminqcq); |
| 3060 | 3053 | |
| 3054 | + mutex_destroy(&lif->config_lock); | |
| 3061 | 3055 | mutex_destroy(&lif->queue_lock); |
| 3062 | 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 | 3180 | if (!ether_addr_equal(ctx.comp.lif_getattr.mac, |
| 3187 | 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 | 3183 | } else { |
| 3190 | 3184 | /* Update the netdev mac with the device's mac */ |
| 3191 | 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 | 3197 | netdev_dbg(lif->netdev, "adding station MAC addr %pM\n", |
| 3204 | 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 | 3201 | return 0; |
| 3208 | 3202 | } |
| @@ -3225,6 +3219,7 @@ int ionic_lif_init(struct ionic_lif *lif) · 16 unmodified lines | ||
| 3225 | 3219 | |
| 3226 | 3220 | lif->hw_index = le16_to_cpu(comp.hw_index); |
| 3227 | 3221 | mutex_init(&lif->queue_lock); |
| 3222 | + mutex_init(&lif->config_lock); | |
| 3228 | 3223 | |
| 3229 | 3224 | /* now that we have the hw_index we can figure out our doorbell page */ |
| 3230 | 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 | 108 | struct list_head list; |
| 109 | 109 | enum ionic_deferred_work_type type; |
| 110 | 110 | union { |
| 111 | − unsigned int rx_mode; | |
| 112 | 111 | u8 addr[ETH_ALEN]; |
| 113 | 112 | u8 fw_status; |
| 114 | 113 | }; |
| @@ -179,6 +178,7 @@ struct ionic_lif { · 64 unmodified lines | ||
| 179 | 178 | unsigned int index; |
| 180 | 179 | unsigned int hw_index; |
| 181 | 180 | struct mutex queue_lock; /* lock for queue structures */ |
| 181 | + struct mutex config_lock; /* lock for config actions */ | |
| 182 | 182 | spinlock_t adminq_lock; /* lock for AdminQ operations */ |
| 183 | 183 | struct ionic_qcq *adminqcq; |
| 184 | 184 | struct ionic_qcq *notifyqcq; |
| @@ -199,7 +199,7 @@ struct ionic_lif { · 14 unmodified lines | ||
| 199 | 199 | unsigned int nrxq_descs; |
| 200 | 200 | u32 rx_copybreak; |
| 201 | 201 | u64 rxq_features; |
| 202 | − unsigned int rx_mode; | |
| 202 | + u16 rx_mode; | |
| 203 | 203 | u64 hw_features; |
| 204 | 204 | bool registered; |
| 205 | 205 | bool mc_overflow; |
| @@ -302,7 +302,7 @@ int ionic_lif_identify(struct ionic *ionic, u8 lif_type, · 96 unmodified lines | ||
| 302 | 302 | int ionic_lif_size(struct ionic *ionic); |
| 303 | 303 | |
| 304 | 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 | 306 | int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr); |
| 307 | 307 | int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr); |
| 308 | 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 | 311 | void ionic_lif_alloc_phc(struct ionic_lif *lif); |
| 312 | 312 | void ionic_lif_free_phc(struct ionic_lif *lif); |
| 313 | 313 | #else |
| 314 | −static inline int ionic_lif_hwstamp_replay(struct ionic_lif *lif) | |
| 315 | −{ | |
| 316 | − return -EOPNOTSUPP; | |
| 317 | −} | |
| 314 | +static inline void ionic_lif_hwstamp_replay(struct ionic_lif *lif) {} | |
| 318 | 315 | |
| 319 | 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 | 188 | struct hwtstamp_config config; |
| 189 | 189 | int err; |
| 190 | 190 | |
| 191 | + if (!lif->phc || !lif->phc->ptp) | |
| 192 | + return -EOPNOTSUPP; | |
| 193 | + | |
| 191 | 194 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) |
| 192 | 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 | 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 | 211 | int err; |
| 209 | 212 | |
| 213 | + if (!lif->phc || !lif->phc->ptp) | |
| 214 | + return; | |
| 215 | + | |
| 210 | 216 | err = ionic_lif_hwstamp_set_ts_config(lif, NULL); |
| 211 | 217 | if (err) |
| 212 | 218 | netdev_info(lif->netdev, "hwstamp replay failed: %d\n", err); |
| 213 | − | |
| 214 | − return err; | |
| 215 | 219 | } |
| 216 | 220 | |
| 217 | 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)) { | |
| 278 | − if (comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_CALC) { | |
| 279 | − skb->ip_summed = CHECKSUM_COMPLETE; | |
| 280 | − skb->csum = (__force __wsum)le16_to_cpu(comp->csum); | |
| 281 | − stats->csum_complete++; | |
| 282 | − } | |
| 277 | + if (likely(netdev->features & NETIF_F_RXCSUM) && | |
| 278 | + (comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_CALC)) { | |
| 279 | + skb->ip_summed = CHECKSUM_COMPLETE; | |
| 280 | + skb->csum = (__force __wsum)le16_to_cpu(comp->csum); | |
| 281 | + stats->csum_complete++; | |
| 283 | 282 | } else { |
| 284 | 283 | stats->csum_none++; |
| 285 | 284 | } |
| @@ -451,11 +450,12 @@ void ionic_rx_empty(struct ionic_queue *q) · 165 unmodified lines | ||
| 451 | 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 | 455 | struct dim_sample dim_sample; |
| 457 | 456 | struct ionic_lif *lif; |
| 458 | 457 | unsigned int qi; |
| 458 | + u64 pkts, bytes; | |
| 459 | 459 | |
| 460 | 460 | if (!qcq->intr.dim_coal_hw) |
| 461 | 461 | return; |
| @@ -463,14 +463,23 @@ static void ionic_dim_update(struct ionic_qcq *qcq) · 1 unmodified line | ||
| 463 | 463 | lif = qcq->q.lif; |
| 464 | 464 | qi = qcq->cq.bound_q->index; |
| 465 | 465 | |
| 466 | − ionic_intr_coal_init(lif->ionic->idev.intr_ctrl, | |
| 467 | − lif->rxqcqs[qi]->intr.index, | |
| 468 | − qcq->intr.dim_coal_hw); | |
| 466 | + switch (napi_mode) { | |
| 467 | + case IONIC_LIF_F_TX_DIM_INTR: | |
| 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 | 481 | dim_update_sample(qcq->cq.bound_intr->rearm_count, |
| 471 | − lif->txqstats[qi].pkts, | |
| 472 | − lif->txqstats[qi].bytes, | |
| 473 | − &dim_sample); | |
| 482 | + pkts, bytes, &dim_sample); | |
| 474 | 483 | |
| 475 | 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 | 500 | ionic_tx_service, NULL, NULL); |
| 492 | 501 | |
| 493 | 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 | 504 | flags |= IONIC_INTR_CRED_UNMASK; |
| 496 | 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 | 539 | ionic_rx_fill(cq->bound_q); |
| 531 | 540 | |
| 532 | 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 | 543 | flags |= IONIC_INTR_CRED_UNMASK; |
| 535 | 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 | 585 | ionic_rx_fill(rxcq->bound_q); |
| 577 | 586 | |
| 578 | 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 | 589 | flags |= IONIC_INTR_CRED_UNMASK; |
| 581 | 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 | 831 | int qede_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) |
| 832 | 832 | { |
| 833 | 833 | struct qede_dev *edev = netdev_priv(dev); |
| 834 | − struct qede_vlan *vlan = NULL; | |
| 834 | + struct qede_vlan *vlan; | |
| 835 | 835 | int rc = 0; |
| 836 | 836 | |
| 837 | 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 | 842 | if (vlan->vid == vid) |
| 843 | 843 | break; |
| 844 | 844 | |
| 845 | − if (!vlan || (vlan->vid != vid)) { | |
| 845 | + if (list_entry_is_head(vlan, &edev->vlan_list, list)) { | |
| 846 | 846 | DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), |
| 847 | 847 | "Vlan isn't configured\n"); |
| 848 | 848 | goto out; |
| @@ -154,7 +154,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) · 153 unmodified lines | ||
| 154 | 154 | "driver lock acquired\n"); |
| 155 | 155 | return 1; |
| 156 | 156 | } |
| 157 | − ssleep(1); | |
| 157 | + mdelay(1000); | |
| 158 | 158 | } while (++i < 10); |
| 159 | 159 | |
| 160 | 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 | 3274 | if ((value & ISP_CONTROL_SR) == 0) |
| 3275 | 3275 | break; |
| 3276 | 3276 | |
| 3277 | − ssleep(1); | |
| 3277 | + mdelay(1000); | |
| 3278 | 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 | 3310 | ispControlStatus); |
| 3311 | 3311 | if ((value & ISP_CONTROL_FSR) == 0) |
| 3312 | 3312 | break; |
| 3313 | − ssleep(1); | |
| 3313 | + mdelay(1000); | |
| 3314 | 3314 | } while ((--max_wait_time)); |
| 3315 | 3315 | } |
| 3316 | 3316 | if (max_wait_time == 0) |
| @@ -5084,7 +5084,8 @@ static int r8169_mdio_register(struct rtl8169_private *tp) · 5083 unmodified lines | ||
| 5084 | 5084 | new_bus->priv = tp; |
| 5085 | 5085 | new_bus->parent = &pdev->dev; |
| 5086 | 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 | 5090 | new_bus->read = r8169_mdio_read_reg; |
| 5090 | 5091 | new_bus->write = r8169_mdio_write_reg; |
| @@ -864,7 +864,7 @@ enum GECMR_BIT { · 863 unmodified lines | ||
| 864 | 864 | |
| 865 | 865 | /* The Ethernet AVB descriptor definitions. */ |
| 866 | 866 | struct ravb_desc { |
| 867 | − __le16 ds; /* Descriptor size */ | |
| 867 | + __le16 ds; /* Descriptor size */ | |
| 868 | 868 | u8 cc; /* Content control MSBs (reserved) */ |
| 869 | 869 | u8 die_dt; /* Descriptor interrupt enable and type */ |
| 870 | 870 | __le32 dptr; /* Descriptor pointer */ |
| @@ -920,7 +920,7 @@ static int ravb_poll(struct napi_struct *napi, int budget) · 919 unmodified lines | ||
| 920 | 920 | if (ravb_rx(ndev, "a, q)) |
| 921 | 921 | goto out; |
| 922 | 922 | |
| 923 | − /* Processing RX Descriptor Ring */ | |
| 923 | + /* Processing TX Descriptor Ring */ | |
| 924 | 924 | spin_lock_irqsave(&priv->lock, flags); |
| 925 | 925 | /* Clear TX interrupt */ |
| 926 | 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 | 443 | #endif |
| 444 | 444 | |
| 445 | 445 | /* setup various bits in PCI command register */ |
| 446 | − ret = pci_enable_device(pci_dev); | |
| 446 | + ret = pcim_enable_device(pci_dev); | |
| 447 | 447 | if(ret) return ret; |
| 448 | 448 | |
| 449 | 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 | 469 | ioaddr = pci_iomap(pci_dev, 0, 0); |
| 470 | 470 | if (!ioaddr) { |
| 471 | 471 | ret = -ENOMEM; |
| 472 | − goto err_out_cleardev; | |
| 472 | + goto err_out; | |
| 473 | 473 | } |
| 474 | 474 | |
| 475 | 475 | sis_priv = netdev_priv(net_dev); |
| @@ -581,8 +581,6 @@ err_unmap_tx: · 105 unmodified lines | ||
| 581 | 581 | sis_priv->tx_ring_dma); |
| 582 | 582 | err_out_unmap: |
| 583 | 583 | pci_iounmap(pci_dev, ioaddr); |
| 584 | −err_out_cleardev: | |
| 585 | − pci_release_regions(pci_dev); | |
| 586 | 584 | err_out: |
| 587 | 585 | free_netdev(net_dev); |
| 588 | 586 | return ret; |
| @@ -2499,7 +2497,6 @@ static void sis900_remove(struct pci_dev *pci_dev) · 1910 unmodified lines | ||
| 2499 | 2497 | sis_priv->tx_ring_dma); |
| 2500 | 2498 | pci_iounmap(pci_dev, sis_priv->ioaddr); |
| 2501 | 2499 | free_netdev(net_dev); |
| 2502 | − pci_release_regions(pci_dev); | |
| 2503 | 2500 | } |
| 2504 | 2501 | |
| 2505 | 2502 | static int __maybe_unused sis900_suspend(struct device *dev) |
| @@ -1249,6 +1249,7 @@ const struct stmmac_ops dwmac410_ops = { · 1248 unmodified lines | ||
| 1249 | 1249 | .config_l3_filter = dwmac4_config_l3_filter, |
| 1250 | 1250 | .config_l4_filter = dwmac4_config_l4_filter, |
| 1251 | 1251 | .est_configure = dwmac5_est_configure, |
| 1252 | + .est_irq_status = dwmac5_est_irq_status, | |
| 1252 | 1253 | .fpe_configure = dwmac5_fpe_configure, |
| 1253 | 1254 | .fpe_send_mpacket = dwmac5_fpe_send_mpacket, |
| 1254 | 1255 | .fpe_irq_status = dwmac5_fpe_irq_status, |
| @@ -1300,6 +1301,7 @@ const struct stmmac_ops dwmac510_ops = { · 45 unmodified lines | ||
| 1300 | 1301 | .config_l3_filter = dwmac4_config_l3_filter, |
| 1301 | 1302 | .config_l4_filter = dwmac4_config_l4_filter, |
| 1302 | 1303 | .est_configure = dwmac5_est_configure, |
| 1304 | + .est_irq_status = dwmac5_est_irq_status, | |
| 1303 | 1305 | .fpe_configure = dwmac5_fpe_configure, |
| 1304 | 1306 | .fpe_send_mpacket = dwmac5_fpe_send_mpacket, |
| 1305 | 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 | 8191 | err = niu_pci_vpd_scan_props(np, here, end); |
| 8192 | 8192 | if (err < 0) |
| 8193 | 8193 | return err; |
| 8194 | + /* ret == 1 is not an error */ | |
| 8194 | 8195 | if (err == 1) |
| 8195 | − return -EINVAL; | |
| 8196 | + return 0; | |
| 8196 | 8197 | } |
| 8197 | 8198 | return 0; |
| 8198 | 8199 | } |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/kernel.h> |
| 15 | 15 | #include <linux/ptp_clock_kernel.h> |
| 16 | 16 | #include <linux/soc/ixp4xx/cpu.h> |
| 17 | +#include <linux/module.h> | |
| 18 | +#include <mach/ixp4xx-regs.h> | |
| 17 | 19 | |
| 18 | 20 | #include "ixp46x_ts.h" |
| 19 | 21 | |
| @@ -288,7 +288,7 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) · 287 unmodified lines | ||
| 288 | 288 | if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) { |
| 289 | 289 | if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E || |
| 290 | 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 | 292 | val |= BCM54XX_SHD_SCR3_RXCTXC_DIS; |
| 293 | 293 | else |
| 294 | 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 | 2495 | hso_net_init); |
| 2496 | 2496 | if (!net) { |
| 2497 | 2497 | dev_err(&interface->dev, "Unable to create ethernet device\n"); |
| 2498 | − goto exit; | |
| 2498 | + goto err_hso_dev; | |
| 2499 | 2499 | } |
| 2500 | 2500 | |
| 2501 | 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 | 2508 | USB_DIR_IN); |
| 2509 | 2509 | if (!hso_net->in_endp) { |
| 2510 | 2510 | dev_err(&interface->dev, "Can't find BULK IN endpoint\n"); |
| 2511 | − goto exit; | |
| 2511 | + goto err_net; | |
| 2512 | 2512 | } |
| 2513 | 2513 | hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, |
| 2514 | 2514 | USB_DIR_OUT); |
| 2515 | 2515 | if (!hso_net->out_endp) { |
| 2516 | 2516 | dev_err(&interface->dev, "Can't find BULK OUT endpoint\n"); |
| 2517 | − goto exit; | |
| 2517 | + goto err_net; | |
| 2518 | 2518 | } |
| 2519 | 2519 | SET_NETDEV_DEV(net, &interface->dev); |
| 2520 | 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 | 2523 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { |
| 2524 | 2524 | hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL); |
| 2525 | 2525 | if (!hso_net->mux_bulk_rx_urb_pool[i]) |
| 2526 | − goto exit; | |
| 2526 | + goto err_mux_bulk_rx; | |
| 2527 | 2527 | hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE, |
| 2528 | 2528 | GFP_KERNEL); |
| 2529 | 2529 | if (!hso_net->mux_bulk_rx_buf_pool[i]) |
| 2530 | − goto exit; | |
| 2530 | + goto err_mux_bulk_rx; | |
| 2531 | 2531 | } |
| 2532 | 2532 | hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
| 2533 | 2533 | if (!hso_net->mux_bulk_tx_urb) |
| 2534 | − goto exit; | |
| 2534 | + goto err_mux_bulk_rx; | |
| 2535 | 2535 | hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL); |
| 2536 | 2536 | if (!hso_net->mux_bulk_tx_buf) |
| 2537 | − goto exit; | |
| 2537 | + goto err_free_tx_urb; | |
| 2538 | 2538 | |
| 2539 | 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 | 2542 | result = register_netdev(net); |
| 2543 | 2543 | if (result) { |
| 2544 | 2544 | dev_err(&interface->dev, "Failed to register device\n"); |
| 2545 | − goto exit; | |
| 2545 | + goto err_free_tx_buf; | |
| 2546 | 2546 | } |
| 2547 | 2547 | |
| 2548 | 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 | 2550 | hso_create_rfkill(hso_dev, interface); |
| 2551 | 2551 | |
| 2552 | 2552 | return hso_dev; |
| 2553 | −exit: | |
| 2554 | − hso_free_net_device(hso_dev, true); | |
| 2553 | + | |
| 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 | 2568 | return NULL; |
| 2556 | 2569 | } |
| 2557 | 2570 | |
| @@ -1552,7 +1552,8 @@ static int · 1551 unmodified lines | ||
| 1552 | 1552 | rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex, |
| 1553 | 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 | 1558 | struct r8152 *tp = netdev_priv(netdev); |
| 1558 | 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 | 1562 | if (!is_valid_ether_addr(addr->sa_data)) |
| 1562 | 1563 | goto out1; |
| 1563 | 1564 | |
| 1564 | − ret = usb_autopm_get_interface(tp->intf); | |
| 1565 | − if (ret < 0) | |
| 1566 | − goto out1; | |
| 1565 | + if (!in_resume) { | |
| 1566 | + ret = usb_autopm_get_interface(tp->intf); | |
| 1567 | + if (ret < 0) | |
| 1568 | + goto out1; | |
| 1569 | + } | |
| 1567 | 1570 | |
| 1568 | 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 | 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 | 1583 | out1: |
| 1580 | 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 | 1592 | /* Devices containing proper chips can support a persistent |
| 1584 | 1593 | * host system provided MAC address. |
| 1585 | 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 | 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 | 1712 | struct net_device *dev = tp->netdev; |
| 1704 | 1713 | struct sockaddr sa; |
| @@ -1711,7 +1720,7 @@ static int set_ethernet_addr(struct r8152 *tp) · 6 unmodified lines | ||
| 1711 | 1720 | if (tp->version == RTL_VER_01) |
| 1712 | 1721 | ether_addr_copy(dev->dev_addr, sa.sa_data); |
| 1713 | 1722 | else |
| 1714 | − ret = rtl8152_set_mac_address(dev, &sa); | |
| 1723 | + ret = __rtl8152_set_mac_address(dev, &sa, in_resume); | |
| 1715 | 1724 | |
| 1716 | 1725 | return ret; |
| 1717 | 1726 | } |
| @@ -6763,9 +6772,10 @@ static int rtl8152_close(struct net_device *netdev) · 5045 unmodified lines | ||
| 6763 | 6772 | tp->rtl_ops.down(tp); |
| 6764 | 6773 | |
| 6765 | 6774 | mutex_unlock(&tp->control); |
| 6775 | + } | |
| 6766 | 6776 | |
| 6777 | + if (!res) | |
| 6767 | 6778 | usb_autopm_put_interface(tp->intf); |
| 6768 | − } | |
| 6769 | 6779 | |
| 6770 | 6780 | free_all_mem(tp); |
| 6771 | 6781 | |
| @@ -8443,7 +8453,7 @@ static int rtl8152_reset_resume(struct usb_interface *intf) · 1671 unmodified lines | ||
| 8443 | 8453 | clear_bit(SELECTIVE_SUSPEND, &tp->flags); |
| 8444 | 8454 | tp->rtl_ops.init(tp); |
| 8445 | 8455 | queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); |
| 8446 | − set_ethernet_addr(tp); | |
| 8456 | + set_ethernet_addr(tp, true); | |
| 8447 | 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 | 9654 | tp->rtl_fw.retry = true; |
| 9645 | 9655 | #endif |
| 9646 | 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 | 9659 | usb_set_intfdata(intf, tp); |
| 9650 | 9660 | |
| @@ -136,6 +136,29 @@ static struct ieee80211_supported_band band_5ghz = { · 135 unmodified lines | ||
| 136 | 136 | /* Assigned at module init. Guaranteed locally-administered and unicast. */ |
| 137 | 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 | 162 | /* Called with the rtnl lock held. */ |
| 140 | 163 | static int virt_wifi_scan(struct wiphy *wiphy, |
| 141 | 164 | struct cfg80211_scan_request *request) |
| @@ -156,28 +179,13 @@ static int virt_wifi_scan(struct wiphy *wiphy, · 14 unmodified lines | ||
| 156 | 179 | /* Acquires and releases the rdev BSS lock. */ |
| 157 | 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 | 182 | struct virt_wifi_wiphy_priv *priv = |
| 168 | 183 | container_of(work, struct virt_wifi_wiphy_priv, |
| 169 | 184 | scan_result.work); |
| 170 | 185 | struct wiphy *wiphy = priv_to_wiphy(priv); |
| 171 | 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, | |
| 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); | |
| 188 | + virt_wifi_inform_bss(wiphy); | |
| 181 | 189 | |
| 182 | 190 | /* Schedules work which acquires and releases the rtnl lock. */ |
| 183 | 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 | 233 | if (!could_schedule) |
| 226 | 234 | return -EBUSY; |
| 227 | 235 | |
| 228 | − if (sme->bssid) | |
| 236 | + if (sme->bssid) { | |
| 229 | 237 | ether_addr_copy(priv->connect_requested_bss, sme->bssid); |
| 230 | − else | |
| 238 | + } else { | |
| 239 | + virt_wifi_inform_bss(wiphy); | |
| 231 | 240 | eth_zero_addr(priv->connect_requested_bss); |
| 241 | + } | |
| 232 | 242 | |
| 233 | 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 | 251 | struct virt_wifi_netdev_priv *priv = |
| 242 | 252 | container_of(work, struct virt_wifi_netdev_priv, connect.work); |
| 243 | 253 | u8 *requested_bss = priv->connect_requested_bss; |
| 244 | − bool has_addr = !is_zero_ether_addr(requested_bss); | |
| 245 | 254 | bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); |
| 246 | 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 | 261 | status = WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 250 | 262 | else |
| 251 | 263 | priv->is_connected = true; |
| @@ -984,6 +984,8 @@ static void wwan_create_default_link(struct wwan_device *wwandev, · 983 unmodified lines | ||
| 984 | 984 | goto unlock; |
| 985 | 985 | } |
| 986 | 986 | |
| 987 | + rtnl_configure_link(dev, NULL); /* Link initialized, notify new link */ | |
| 988 | + | |
| 987 | 989 | unlock: |
| 988 | 990 | rtnl_unlock(); |
| 989 | 991 | |
| @@ -192,8 +192,7 @@ static void nfcsim_recv_wq(struct work_struct *work) · 191 unmodified lines | ||
| 192 | 192 | |
| 193 | 193 | if (!IS_ERR(skb)) |
| 194 | 194 | dev_kfree_skb(skb); |
| 195 | − | |
| 196 | − skb = ERR_PTR(-ENODEV); | |
| 195 | + return; | |
| 197 | 196 | } |
| 198 | 197 | |
| 199 | 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 | 423 | if (IS_ERR(tfm)) { |
| 424 | 424 | ret = PTR_ERR(tfm); |
| 425 | 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 | 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 | 900 | cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req))); |
| 901 | 901 | cmnd->write_zeroes.length = |
| 902 | 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 | 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 | 3811 | static void nvme_ns_remove(struct nvme_ns *ns) |
| 3809 | 3812 | { |
| 3813 | + bool last_path = false; | |
| 3814 | + | |
| 3810 | 3815 | if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags)) |
| 3811 | 3816 | return; |
| 3812 | 3817 | |
| @@ -3815,8 +3820,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) · 2 unmodified lines | ||
| 3815 | 3820 | |
| 3816 | 3821 | mutex_lock(&ns->ctrl->subsys->lock); |
| 3817 | 3822 | list_del_rcu(&ns->siblings); |
| 3818 | − if (list_empty(&ns->head->list)) | |
| 3819 | − list_del_init(&ns->head->entry); | |
| 3820 | 3823 | mutex_unlock(&ns->ctrl->subsys->lock); |
| 3821 | 3824 | |
| 3822 | 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 | 3839 | list_del_init(&ns->list); |
| 3837 | 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 | 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 | 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 | 765 | if (!head->disk) |
| 766 | 766 | return; |
| 767 | + kblockd_schedule_work(&head->requeue_work); | |
| 767 | 768 | if (head->disk->flags & GENHD_FL_UP) { |
| 768 | 769 | nvme_cdev_del(&head->cdev, &head->cdev_device); |
| 769 | 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 | 778 | blk_set_queue_dying(head->disk->queue); |
| 772 | 779 | /* make sure all pending bios are cleaned up */ |
| 773 | 780 | kblockd_schedule_work(&head->requeue_work); |
| @@ -716,14 +716,7 @@ void nvme_mpath_uninit(struct nvme_ctrl *ctrl); · 715 unmodified lines | ||
| 716 | 716 | void nvme_mpath_stop(struct nvme_ctrl *ctrl); |
| 717 | 717 | bool nvme_mpath_clear_current_path(struct nvme_ns *ns); |
| 718 | 718 | void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl); |
| 719 | − | |
| 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 | −} | |
| 719 | +void nvme_mpath_shutdown_disk(struct nvme_ns_head *head); | |
| 727 | 720 | |
| 728 | 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 | 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 | 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 | 2631 | bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); |
| 2632 | 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 | 2637 | result = -ENODEV; |
| 2636 | 2638 | goto out; |
| 2637 | 2639 | } |
| @@ -56,7 +56,7 @@ TRACE_EVENT(nvme_setup_cmd, · 55 unmodified lines | ||
| 56 | 56 | __field(u8, fctype) |
| 57 | 57 | __field(u16, cid) |
| 58 | 58 | __field(u32, nsid) |
| 59 | − __field(u64, metadata) | |
| 59 | + __field(bool, metadata) | |
| 60 | 60 | __array(u8, cdw10, 24) |
| 61 | 61 | ), |
| 62 | 62 | TP_fast_assign( |
| @@ -66,13 +66,13 @@ TRACE_EVENT(nvme_setup_cmd, · 3 unmodified lines | ||
| 66 | 66 | __entry->flags = cmd->common.flags; |
| 67 | 67 | __entry->cid = cmd->common.command_id; |
| 68 | 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 | 70 | __entry->fctype = cmd->fabrics.fctype; |
| 71 | 71 | __assign_disk_name(__entry->disk, req->rq_disk); |
| 72 | 72 | memcpy(__entry->cdw10, &cmd->common.cdw10, |
| 73 | 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 | 76 | __entry->ctrl_id, __print_disk_name(__entry->disk), |
| 77 | 77 | __entry->qid, __entry->cid, __entry->nsid, |
| 78 | 78 | __entry->flags, __entry->metadata, |
| @@ -46,34 +46,79 @@ · 45 unmodified lines | ||
| 46 | 46 | #define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE |
| 47 | 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 | 66 | /* List of supported CPU ids */ |
| 50 | 67 | #define AMD_CPU_ID_RV 0x15D0 |
| 51 | 68 | #define AMD_CPU_ID_RN 0x1630 |
| 52 | 69 | #define AMD_CPU_ID_PCO AMD_CPU_ID_RV |
| 53 | 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 | 73 | #define PMC_MSG_DELAY_MIN_US 100 |
| 57 | 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 | 79 | enum amd_pmc_def { |
| 60 | 80 | MSG_TEST = 0x01, |
| 61 | 81 | MSG_OS_HINT_PCO, |
| 62 | 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 | 106 | struct amd_pmc_dev { |
| 66 | 107 | void __iomem *regbase; |
| 67 | − void __iomem *smu_base; | |
| 108 | + void __iomem *smu_virt_addr; | |
| 109 | + void __iomem *fch_virt_addr; | |
| 68 | 110 | u32 base_addr; |
| 69 | 111 | u32 cpu_id; |
| 112 | + u32 active_ips; | |
| 70 | 113 | struct device *dev; |
| 114 | + struct mutex lock; /* generic mutex lock */ | |
| 71 | 115 | #if IS_ENABLED(CONFIG_DEBUG_FS) |
| 72 | 116 | struct dentry *dbgfs_dir; |
| 73 | 117 | #endif /* CONFIG_DEBUG_FS */ |
| 74 | 118 | }; |
| 75 | 119 | |
| 76 | 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 | 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 | 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 | 150 | #ifdef CONFIG_DEBUG_FS |
| 89 | 151 | static int smu_fw_info_show(struct seq_file *s, void *unused) |
| 90 | 152 | { |
| 91 | 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 | 176 | return 0; |
| 97 | 177 | } |
| 98 | 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 | 204 | static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev) |
| 101 | 205 | { |
| 102 | 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 | 211 | dev->dbgfs_dir = debugfs_create_dir("amd_pmc", NULL); |
| 108 | 212 | debugfs_create_file("smu_fw_info", 0644, dev->dbgfs_dir, dev, |
| 109 | 213 | &smu_fw_info_fops); |
| 214 | + debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev, | |
| 215 | + &s0ix_stats_fops); | |
| 110 | 216 | } |
| 111 | 217 | #else |
| 112 | 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 | 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 | 253 | static void amd_pmc_dump_registers(struct amd_pmc_dev *dev) |
| 122 | 254 | { |
| 123 | 255 | u32 value; |
| @@ -132,19 +264,19 @@ static void amd_pmc_dump_registers(struct amd_pmc_dev *dev) · 8 unmodified lines | ||
| 132 | 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 | 269 | int rc; |
| 138 | − u8 msg; | |
| 139 | 270 | u32 val; |
| 140 | 271 | |
| 272 | + mutex_lock(&dev->lock); | |
| 141 | 273 | /* Wait until we get a valid response */ |
| 142 | 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 | 276 | PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); |
| 145 | 277 | if (rc) { |
| 146 | 278 | dev_err(dev->dev, "failed to talk to SMU\n"); |
| 147 | − return rc; | |
| 279 | + goto out_unlock; | |
| 148 | 280 | } |
| 149 | 281 | |
| 150 | 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 | 286 | amd_pmc_reg_write(dev, AMD_PMC_REGISTER_ARGUMENT, set); |
| 155 | 287 | |
| 156 | 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 | 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 | 342 | static int __maybe_unused amd_pmc_suspend(struct device *dev) |
| 163 | 343 | { |
| 164 | 344 | struct amd_pmc_dev *pdev = dev_get_drvdata(dev); |
| 165 | 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 | 354 | if (rc) |
| 169 | 355 | dev_err(pdev->dev, "suspend failed\n"); |
| 170 | 356 | |
| 171 | − amd_pmc_dump_registers(pdev); | |
| 172 | − return 0; | |
| 357 | + return rc; | |
| 173 | 358 | } |
| 174 | 359 | |
| 175 | 360 | static int __maybe_unused amd_pmc_resume(struct device *dev) |
| 176 | 361 | { |
| 177 | 362 | struct amd_pmc_dev *pdev = dev_get_drvdata(dev); |
| 178 | 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 | 371 | if (rc) |
| 182 | 372 | dev_err(pdev->dev, "resume failed\n"); |
| 183 | 373 | |
| 184 | − amd_pmc_dump_registers(pdev); | |
| 185 | 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 | 381 | static const struct pci_device_id pmc_pci_ids[] = { |
| 382 | + { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_YC) }, | |
| 193 | 383 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_CZN) }, |
| 194 | 384 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RN) }, |
| 195 | 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 | 392 | struct amd_pmc_dev *dev = &pmc; |
| 203 | 393 | struct pci_dev *rdev; |
| 204 | − u32 base_addr_lo; | |
| 205 | − u32 base_addr_hi; | |
| 206 | − u64 base_addr; | |
| 394 | + u32 base_addr_lo, base_addr_hi; | |
| 395 | + u64 base_addr, fch_phys_addr; | |
| 207 | 396 | int err; |
| 208 | 397 | u32 val; |
| 209 | 398 | |
| @@ -248,16 +437,25 @@ static int amd_pmc_probe(struct platform_device *pdev) · 38 unmodified lines | ||
| 248 | 437 | pci_dev_put(rdev); |
| 249 | 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 | 440 | dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMC_BASE_ADDR_OFFSET, |
| 256 | 441 | AMD_PMC_MAPPING_SIZE); |
| 257 | 442 | if (!dev->regbase) |
| 258 | 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 | 460 | platform_set_drvdata(pdev, dev); |
| 263 | 461 | amd_pmc_dbgfs_register(dev); |
| @@ -269,11 +467,14 @@ static int amd_pmc_remove(struct platform_device *pdev) · 5 unmodified lines | ||
| 269 | 467 | struct amd_pmc_dev *dev = platform_get_drvdata(pdev); |
| 270 | 468 | |
| 271 | 469 | amd_pmc_dbgfs_unregister(dev); |
| 470 | + mutex_destroy(&dev->lock); | |
| 272 | 471 | return 0; |
| 273 | 472 | } |
| 274 | 473 | |
| 275 | 474 | static const struct acpi_device_id amd_pmc_acpi_ids[] = { |
| 276 | 475 | {"AMDI0005", 0}, |
| 476 | + {"AMDI0006", 0}, | |
| 477 | + {"AMDI0007", 0}, | |
| 277 | 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 | 142 | static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = { |
| 143 | 143 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"), |
| 144 | + DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE V2"), | |
| 144 | 145 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 GAMING X V2"), |
| 145 | 146 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"), |
| 146 | 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 | 25 | {"INT33D5", 0}, |
| 26 | 26 | {"INTC1051", 0}, |
| 27 | 27 | {"INTC1054", 0}, |
| 28 | + {"INTC1070", 0}, | |
| 28 | 29 | {"", 0}, |
| 29 | 30 | }; |
| 30 | 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 | 571 | else |
| 572 | 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 | 579 | out: |
| 575 | 580 | kfree(auth_str); |
| 576 | 581 | kfree(set_str); |
| @@ -647,6 +652,14 @@ static struct kobj_type tlmi_pwd_setting_ktype = { · 70 unmodified lines | ||
| 647 | 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 | 663 | /* ---- Initialisation --------------------------------------------------------- */ |
| 651 | 664 | static void tlmi_release_attr(void) |
| 652 | 665 | { |
| @@ -659,6 +672,7 @@ static void tlmi_release_attr(void) · 6 unmodified lines | ||
| 659 | 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 | 676 | kset_unregister(tlmi_priv.attribute_kset); |
| 663 | 677 | |
| 664 | 678 | /* Authentication structures */ |
| @@ -709,8 +723,8 @@ static int tlmi_sysfs_init(void) · 44 unmodified lines | ||
| 709 | 723 | |
| 710 | 724 | /* Build attribute */ |
| 711 | 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, | |
| 713 | − NULL, "%s", tlmi_priv.setting[i]->display_name); | |
| 726 | + ret = kobject_add(&tlmi_priv.setting[i]->kobj, NULL, | |
| 727 | + "%s", tlmi_priv.setting[i]->display_name); | |
| 714 | 728 | if (ret) |
| 715 | 729 | goto fail_create_attr; |
| 716 | 730 | |
| @@ -719,6 +733,10 @@ static int tlmi_sysfs_init(void) · 2 unmodified lines | ||
| 719 | 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 | 740 | /* Create authentication entries */ |
| 723 | 741 | tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL, |
| 724 | 742 | &tlmi_priv.class_dev->kobj); |
| @@ -727,8 +745,7 @@ static int tlmi_sysfs_init(void) · 2 unmodified lines | ||
| 727 | 745 | goto fail_create_attr; |
| 728 | 746 | } |
| 729 | 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, | |
| 731 | − NULL, "%s", "Admin"); | |
| 748 | + ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin"); | |
| 732 | 749 | if (ret) |
| 733 | 750 | goto fail_create_attr; |
| 734 | 751 | |
| @@ -737,8 +754,7 @@ static int tlmi_sysfs_init(void) · 2 unmodified lines | ||
| 737 | 754 | goto fail_create_attr; |
| 738 | 755 | |
| 739 | 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, | |
| 741 | − NULL, "%s", "System"); | |
| 757 | + ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "System"); | |
| 742 | 758 | if (ret) |
| 743 | 759 | goto fail_create_attr; |
| 744 | 760 | |
| @@ -818,6 +834,7 @@ static int tlmi_analyze(void) · 73 unmodified lines | ||
| 818 | 834 | pr_info("Error retrieving possible values for %d : %s\n", |
| 819 | 835 | i, setting->display_name); |
| 820 | 836 | } |
| 837 | + kobject_init(&setting->kobj, &tlmi_attr_setting_ktype); | |
| 821 | 838 | tlmi_priv.setting[i] = setting; |
| 822 | 839 | tlmi_priv.settings_count++; |
| 823 | 840 | kfree(item); |
| @@ -844,10 +861,12 @@ static int tlmi_analyze(void) · 20 unmodified lines | ||
| 844 | 861 | if (pwdcfg.password_state & TLMI_PAP_PWD) |
| 845 | 862 | tlmi_priv.pwd_admin->valid = true; |
| 846 | 863 | |
| 864 | + kobject_init(&tlmi_priv.pwd_admin->kobj, &tlmi_pwd_setting_ktype); | |
| 865 | + | |
| 847 | 866 | tlmi_priv.pwd_power = kzalloc(sizeof(struct tlmi_pwd_setting), GFP_KERNEL); |
| 848 | 867 | if (!tlmi_priv.pwd_power) { |
| 849 | 868 | ret = -ENOMEM; |
| 850 | − goto fail_clear_attr; | |
| 869 | + goto fail_free_pwd_admin; | |
| 851 | 870 | } |
| 852 | 871 | strscpy(tlmi_priv.pwd_power->kbdlang, "us", TLMI_LANG_MAXLEN); |
| 853 | 872 | tlmi_priv.pwd_power->encoding = TLMI_ENCODING_ASCII; |
| @@ -859,11 +878,19 @@ static int tlmi_analyze(void) · 5 unmodified lines | ||
| 859 | 878 | if (pwdcfg.password_state & TLMI_POP_PWD) |
| 860 | 879 | tlmi_priv.pwd_power->valid = true; |
| 861 | 880 | |
| 881 | + kobject_init(&tlmi_priv.pwd_power->kobj, &tlmi_pwd_setting_ktype); | |
| 882 | + | |
| 862 | 883 | return 0; |
| 863 | 884 | |
| 885 | +fail_free_pwd_admin: | |
| 886 | + kfree(tlmi_priv.pwd_admin); | |
| 864 | 887 | fail_clear_attr: |
| 865 | − for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) | |
| 866 | − kfree(tlmi_priv.setting[i]); | |
| 888 | + for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) { | |
| 889 | + if (tlmi_priv.setting[i]) { | |
| 890 | + kfree(tlmi_priv.setting[i]->possible_values); | |
| 891 | + kfree(tlmi_priv.setting[i]); | |
| 892 | + } | |
| 893 | + } | |
| 867 | 894 | return ret; |
| 868 | 895 | } |
| 869 | 896 | |
| @@ -60,6 +60,7 @@ struct think_lmi { · 59 unmodified lines | ||
| 60 | 60 | bool can_get_bios_selections; |
| 61 | 61 | bool can_set_bios_password; |
| 62 | 62 | bool can_get_password_settings; |
| 63 | + bool pending_changes; | |
| 63 | 64 | |
| 64 | 65 | struct tlmi_attr_setting *setting[TLMI_SETTINGS_COUNT]; |
| 65 | 66 | struct device *class_dev; |
| @@ -78,7 +78,7 @@ static int wl_add(struct acpi_device *device) · 77 unmodified lines | ||
| 78 | 78 | |
| 79 | 79 | err = wireless_input_setup(); |
| 80 | 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 | 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 | 294 | struct bd957x_regulator_data *r) |
| 295 | 295 | { |
| 296 | 296 | if ((severity == REGULATOR_SEVERITY_ERR && |
| 297 | − r->ovd_notif != REGULATOR_EVENT_OVER_TEMP) || | |
| 297 | + r->temp_notif != REGULATOR_EVENT_OVER_TEMP) || | |
| 298 | 298 | (severity == REGULATOR_SEVERITY_WARN && |
| 299 | − r->ovd_notif != REGULATOR_EVENT_OVER_TEMP_WARN)) { | |
| 299 | + r->temp_notif != REGULATOR_EVENT_OVER_TEMP_WARN)) { | |
| 300 | 300 | dev_warn(rdev_get_dev(rdev), |
| 301 | 301 | "Can't support both thermal WARN and ERR\n"); |
| 302 | 302 | if (severity == REGULATOR_SEVERITY_WARN) |
| @@ -366,9 +366,8 @@ static struct hi6421_regulator_info · 365 unmodified lines | ||
| 366 | 366 | |
| 367 | 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 | 371 | /* hi6421 spec requires regulator enablement must be serialized: |
| 373 | 372 | * - Because when BUCK, LDO switching from off to on, it will have |
| 374 | 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 | 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 | 388 | unsigned int reg_val; |
| 390 | 389 | |
| 390 | + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | |
| 391 | 391 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); |
| 392 | 392 | if (reg_val & info->mode_mask) |
| 393 | 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 | 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 | 401 | unsigned int reg_val; |
| 402 | 402 | |
| 403 | + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | |
| 403 | 404 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); |
| 404 | 405 | if (reg_val & info->mode_mask) |
| 405 | 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 | 411 | static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, |
| 411 | 412 | unsigned int mode) |
| 412 | 413 | { |
| 413 | − struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | |
| 414 | + struct hi6421_regulator_info *info; | |
| 414 | 415 | unsigned int new_mode; |
| 415 | 416 | |
| 417 | + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | |
| 416 | 418 | switch (mode) { |
| 417 | 419 | case REGULATOR_MODE_NORMAL: |
| 418 | 420 | new_mode = 0; |
| @@ -434,9 +436,10 @@ static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, · 15 unmodified lines | ||
| 434 | 436 | static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev, |
| 435 | 437 | unsigned int mode) |
| 436 | 438 | { |
| 437 | − struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); | |
| 439 | + struct hi6421_regulator_info *info; | |
| 438 | 440 | unsigned int new_mode; |
| 439 | 441 | |
| 442 | + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); | |
| 440 | 443 | switch (mode) { |
| 441 | 444 | case REGULATOR_MODE_NORMAL: |
| 442 | 445 | new_mode = 0; |
| @@ -459,7 +462,9 @@ static unsigned int · 16 unmodified lines | ||
| 459 | 462 | hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, |
| 460 | 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 | 469 | if (load_uA > info->eco_microamp) |
| 465 | 470 | return REGULATOR_MODE_NORMAL; |
| @@ -543,14 +548,13 @@ static int hi6421_regulator_probe(struct platform_device *pdev) · 77 unmodified lines | ||
| 543 | 548 | if (!pdata) |
| 544 | 549 | return -ENOMEM; |
| 545 | 550 | mutex_init(&pdata->lock); |
| 546 | − platform_set_drvdata(pdev, pdata); | |
| 547 | 551 | |
| 548 | 552 | for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { |
| 549 | 553 | /* assign per-regulator data */ |
| 550 | 554 | info = &hi6421_regulator_info[i]; |
| 551 | 555 | |
| 552 | 556 | config.dev = pdev->dev.parent; |
| 553 | − config.driver_data = info; | |
| 557 | + config.driver_data = pdata; | |
| 554 | 558 | config.regmap = pmic->regmap; |
| 555 | 559 | |
| 556 | 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 | 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 | 102 | int ret; |
| 103 | 103 | |
| 104 | − priv = dev_get_drvdata(rdev->dev.parent); | |
| 105 | 104 | /* cannot enable more than one regulator at one time */ |
| 106 | 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 | 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 | 122 | unsigned int reg_val; |
| 124 | 123 | |
| 124 | + sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc); | |
| 125 | 125 | regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); |
| 126 | 126 | |
| 127 | 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 | 133 | static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, |
| 134 | 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 | 137 | unsigned int val; |
| 138 | 138 | |
| 139 | + sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc); | |
| 139 | 140 | switch (mode) { |
| 140 | 141 | case REGULATOR_MODE_NORMAL: |
| 141 | 142 | val = 0; |
| @@ -159,7 +160,9 @@ hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev, · 17 unmodified lines | ||
| 159 | 160 | int input_uV, int output_uV, |
| 160 | 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 | 167 | if (!sreg->eco_uA || ((unsigned int)load_uA > sreg->eco_uA)) |
| 165 | 168 | return REGULATOR_MODE_NORMAL; |
| @@ -252,13 +255,12 @@ static int hi6421_spmi_regulator_probe(struct platform_device *pdev) · 86 unmodified lines | ||
| 252 | 255 | return -ENOMEM; |
| 253 | 256 | |
| 254 | 257 | mutex_init(&priv->enable_mutex); |
| 255 | − platform_set_drvdata(pdev, priv); | |
| 256 | 258 | |
| 257 | 259 | for (i = 0; i < ARRAY_SIZE(regulator_info); i++) { |
| 258 | 260 | info = ®ulator_info[i]; |
| 259 | 261 | |
| 260 | 262 | config.dev = pdev->dev.parent; |
| 261 | − config.driver_data = info; | |
| 263 | + config.driver_data = priv; | |
| 262 | 264 | config.regmap = pmic->regmap; |
| 263 | 265 | |
| 264 | 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 | 179 | for (i = 0; i < regulator_init_data->size; i++) { |
| 180 | 180 | config.dev = dev->parent; |
| 181 | 181 | config.driver_data = (mt_regulators + i); |
| 182 | − rdev = devm_regulator_register(dev->parent, | |
| 183 | − &(mt_regulators + i)->desc, | |
| 182 | + rdev = devm_regulator_register(dev, &(mt_regulators + i)->desc, | |
| 184 | 183 | &config); |
| 185 | 184 | if (IS_ERR(rdev)) { |
| 186 | 185 | dev_err(dev, "failed to register %s\n", |
| @@ -37,7 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #define RTMV20_WIDTH2_MASK GENMASK(7, 0) |
| 38 | 38 | #define RTMV20_LBPLVL_MASK GENMASK(3, 0) |
| 39 | 39 | #define RTMV20_LBPEN_MASK BIT(7) |
| 40 | −#define RTMV20_STROBEPOL_MASK BIT(1) | |
| 40 | +#define RTMV20_STROBEPOL_MASK BIT(0) | |
| 41 | 41 | #define RTMV20_VSYNPOL_MASK BIT(1) |
| 42 | 42 | #define RTMV20_FSINEN_MASK BIT(7) |
| 43 | 43 | #define RTMV20_ESEN_MASK BIT(6) |
| @@ -2642,6 +2642,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) · 2641 unmodified lines | ||
| 2642 | 2642 | //#endif |
| 2643 | 2643 | clear_bit(SCpnt->device->id * 8 + |
| 2644 | 2644 | (u8)(SCpnt->device->lun & 0x7), host->busyluns); |
| 2645 | + fallthrough; | |
| 2645 | 2646 | |
| 2646 | 2647 | /* |
| 2647 | 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 | 1375 | case IS_COMPLETE: |
| 1376 | 1376 | break; |
| 1377 | 1377 | } |
| 1378 | + break; | |
| 1378 | 1379 | |
| 1379 | 1380 | default: |
| 1380 | 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 | 2987 | * @ioc: per adapter object |
| 2988 | 2988 | * |
| 2989 | 2989 | * Freeing respective reply_queue from the list. |
| 2990 | 2990 | */ |
| 2991 | −static void | |
| 2992 | −_base_free_irq(struct MPT3SAS_ADAPTER *ioc) | |
| 2991 | +void | |
| 2992 | +mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc) | |
| 2993 | 2993 | { |
| 2994 | 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 | 3195 | * @ioc: per adapter object |
| 3196 | 3196 | * |
| 3197 | 3197 | */ |
| 3198 | −static void | |
| 3199 | −_base_disable_msix(struct MPT3SAS_ADAPTER *ioc) | |
| 3198 | +void | |
| 3199 | +mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc) | |
| 3200 | 3200 | { |
| 3201 | 3201 | if (!ioc->msix_enable) |
| 3202 | 3202 | return; |
| @@ -3304,8 +3304,8 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) · 101 unmodified lines | ||
| 3304 | 3304 | for (i = 0; i < ioc->reply_queue_count; i++) { |
| 3305 | 3305 | r = _base_request_irq(ioc, i); |
| 3306 | 3306 | if (r) { |
| 3307 | − _base_free_irq(ioc); | |
| 3308 | − _base_disable_msix(ioc); | |
| 3307 | + mpt3sas_base_free_irq(ioc); | |
| 3308 | + mpt3sas_base_disable_msix(ioc); | |
| 3309 | 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 | 3343 | dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); |
| 3344 | 3344 | |
| 3345 | − _base_free_irq(ioc); | |
| 3346 | − _base_disable_msix(ioc); | |
| 3345 | + mpt3sas_base_free_irq(ioc); | |
| 3346 | + mpt3sas_base_disable_msix(ioc); | |
| 3347 | 3347 | |
| 3348 | 3348 | kfree(ioc->replyPostRegisterIndex); |
| 3349 | 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 | 7617 | * @ioc: per adapter object |
| 7618 | 7618 | * @type: FORCE_BIG_HAMMER or SOFT_RESET |
| 7619 | 7619 | * |
| 7620 | 7620 | * Return: 0 for success, non-zero for failure. |
| 7621 | 7621 | */ |
| 7622 | −static int | |
| 7623 | −_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type) | |
| 7622 | +int | |
| 7623 | +mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type) | |
| 7624 | 7624 | { |
| 7625 | 7625 | u32 ioc_state; |
| 7626 | 7626 | int rc; |
| @@ -7897,7 +7897,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) · 270 unmodified lines | ||
| 7897 | 7897 | if (ioc->chip_phys && ioc->chip) { |
| 7898 | 7898 | mpt3sas_base_mask_interrupts(ioc); |
| 7899 | 7899 | ioc->shost_recovery = 1; |
| 7900 | − _base_make_ioc_ready(ioc, SOFT_RESET); | |
| 7900 | + mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET); | |
| 7901 | 7901 | ioc->shost_recovery = 0; |
| 7902 | 7902 | } |
| 7903 | 7903 | |
| @@ -8017,7 +8017,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) · 113 unmodified lines | ||
| 8017 | 8017 | ioc->build_sg_mpi = &_base_build_sg; |
| 8018 | 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 | 8021 | if (r) |
| 8022 | 8022 | goto out_free_resources; |
| 8023 | 8023 | |
| @@ -8471,7 +8471,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, · 447 unmodified lines | ||
| 8471 | 8471 | _base_pre_reset_handler(ioc); |
| 8472 | 8472 | mpt3sas_wait_for_commands_to_complete(ioc); |
| 8473 | 8473 | mpt3sas_base_mask_interrupts(ioc); |
| 8474 | − r = _base_make_ioc_ready(ioc, type); | |
| 8474 | + r = mpt3sas_base_make_ioc_ready(ioc, type); | |
| 8475 | 8475 | if (r) |
| 8476 | 8476 | goto out; |
| 8477 | 8477 | _base_clear_outstanding_commands(ioc); |
| @@ -1730,6 +1730,10 @@ do { ioc_err(ioc, "In func: %s\n", __func__); \ · 1729 unmodified lines | ||
| 1730 | 1730 | status, mpi_request, sz); } while (0) |
| 1731 | 1731 | |
| 1732 | 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 | 1738 | /* scsih shared API */ |
| 1735 | 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 | 11296 | _scsih_ir_shutdown(ioc); |
| 11297 | 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 | 439 | struct device *dev = container_of(kobj, struct device, kobj); |
| 440 | 440 | struct iscsi_iface *iface = iscsi_dev_to_iface(dev); |
| 441 | 441 | struct iscsi_transport *t = iface->transport; |
| 442 | − int param; | |
| 443 | − int param_type; | |
| 442 | + int param = -1; | |
| 444 | 443 | |
| 445 | 444 | if (attr == &dev_attr_iface_enabled.attr) |
| 446 | 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 | 446 | else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) |
| 476 | 447 | param = ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO; |
| 477 | 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 | 479 | param = ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN; |
| 509 | 480 | else if (attr == &dev_attr_iface_initiator_name.attr) |
| 510 | 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 | 514 | else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) { |
| 512 | 515 | if (attr == &dev_attr_ipv4_iface_ipaddress.attr) |
| 513 | 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 | 601 | return 0; |
| 599 | 602 | } |
| 600 | 603 | |
| 601 | − switch (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); | |
| 604 | + return t->attr_is_visible(ISCSI_NET_PARAM, param); | |
| 627 | 605 | } |
| 628 | 606 | |
| 629 | 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 | 354 | mr = spi_readl(as, MR); |
| 355 | − if (spi->cs_gpiod) | |
| 356 | − gpiod_set_value(spi->cs_gpiod, 1); | |
| 357 | 355 | } else { |
| 358 | 356 | u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; |
| 359 | 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 | 368 | mr = spi_readl(as, MR); |
| 371 | 369 | mr = SPI_BFINS(PCS, ~(1 << chip_select), mr); |
| 372 | − if (spi->cs_gpiod) | |
| 373 | − gpiod_set_value(spi->cs_gpiod, 1); | |
| 374 | 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 | 397 | if (!spi->cs_gpiod) |
| 402 | 398 | spi_writel(as, CR, SPI_BIT(LASTXFER)); |
| 403 | − else | |
| 404 | − gpiod_set_value(spi->cs_gpiod, 0); | |
| 405 | 399 | } |
| 406 | 400 | |
| 407 | 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 | 1477 | master->bus_num = pdev->id; |
| 1484 | 1478 | master->num_chipselect = 4; |
| 1485 | 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 | 1482 | master->transfer_one = atmel_spi_one_transfer; |
| 1488 | 1483 | master->set_cs = atmel_spi_set_cs; |
| 1489 | 1484 | master->cleanup = atmel_spi_cleanup; |
| @@ -83,6 +83,7 @@ MODULE_PARM_DESC(polling_limit_us, · 82 unmodified lines | ||
| 83 | 83 | * struct bcm2835_spi - BCM2835 SPI controller |
| 84 | 84 | * @regs: base address of register map |
| 85 | 85 | * @clk: core clock, divided to calculate serial clock |
| 86 | + * @clk_hz: core clock cached speed | |
| 86 | 87 | * @irq: interrupt, signals TX FIFO empty or RX FIFO ¾ full |
| 87 | 88 | * @tfr: SPI transfer currently processed |
| 88 | 89 | * @ctlr: SPI controller reverse lookup |
| @@ -116,6 +117,7 @@ MODULE_PARM_DESC(polling_limit_us, · 27 unmodified lines | ||
| 116 | 117 | struct bcm2835_spi { |
| 117 | 118 | void __iomem *regs; |
| 118 | 119 | struct clk *clk; |
| 120 | + unsigned long clk_hz; | |
| 119 | 121 | int irq; |
| 120 | 122 | struct spi_transfer *tfr; |
| 121 | 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 | 1048 | struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); |
| 1047 | 1049 | struct bcm2835_spidev *slv = spi_get_ctldata(spi); |
| 1048 | − unsigned long spi_hz, clk_hz, cdiv; | |
| 1050 | + unsigned long spi_hz, cdiv; | |
| 1049 | 1051 | unsigned long hz_per_byte, byte_limit; |
| 1050 | 1052 | u32 cs = slv->prepare_cs; |
| 1051 | 1053 | |
| 1052 | 1054 | /* set clock */ |
| 1053 | 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 | 1058 | cdiv = 2; /* clk_hz/2 is the fastest we can go */ |
| 1058 | 1059 | } else if (spi_hz) { |
| 1059 | 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 | 1062 | cdiv += (cdiv % 2); |
| 1062 | 1063 | |
| 1063 | 1064 | if (cdiv >= 65536) |
| @@ -1065,7 +1066,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, · 1 unmodified line | ||
| 1065 | 1066 | } else { |
| 1066 | 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 | 1070 | bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); |
| 1070 | 1071 | |
| 1071 | 1072 | /* handle all the 3-wire mode */ |
| @@ -1354,6 +1355,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) · 282 unmodified lines | ||
| 1354 | 1355 | return bs->irq ? bs->irq : -ENODEV; |
| 1355 | 1356 | |
| 1356 | 1357 | clk_prepare_enable(bs->clk); |
| 1358 | + bs->clk_hz = clk_get_rate(bs->clk); | |
| 1357 | 1359 | |
| 1358 | 1360 | err = bcm2835_dma_init(ctlr, &pdev->dev, bs); |
| 1359 | 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 | 310 | unsigned int dummy_clk; |
| 311 | 311 | |
| 312 | + if (!op->dummy.nbytes) | |
| 313 | + return 0; | |
| 314 | + | |
| 312 | 315 | dummy_clk = op->dummy.nbytes * (8 / op->dummy.buswidth); |
| 313 | 316 | if (dtr) |
| 314 | 317 | dummy_clk /= 2; |
| @@ -797,19 +800,20 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata, · 482 unmodified lines | ||
| 797 | 800 | reg = cqspi_calc_rdreg(f_pdata); |
| 798 | 801 | writel(reg, reg_base + CQSPI_REG_RD_INSTR); |
| 799 | 802 | |
| 800 | − if (f_pdata->dtr) { | |
| 801 | − /* | |
| 802 | − * Some flashes like the cypress Semper flash expect a 4-byte | |
| 803 | − * dummy address with the Read SR command in DTR mode, but this | |
| 804 | − * controller does not support sending address with the Read SR | |
| 805 | − * command. So, disable write completion polling on the | |
| 806 | − * controller's side. spi-nor will take care of polling the | |
| 807 | − * status register. | |
| 808 | − */ | |
| 809 | − reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL); | |
| 810 | − reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; | |
| 811 | − writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL); | |
| 812 | − } | |
| 803 | + /* | |
| 804 | + * SPI NAND flashes require the address of the status register to be | |
| 805 | + * passed in the Read SR command. Also, some SPI NOR flashes like the | |
| 806 | + * cypress Semper flash expect a 4-byte dummy address in the Read SR | |
| 807 | + * command in DTR mode. | |
| 808 | + * | |
| 809 | + * But this controller does not support address phase in the Read SR | |
| 810 | + * command when doing auto-HW polling. So, disable write completion | |
| 811 | + * polling on the controller's side. spinand and spi-nor will take | |
| 812 | + * care of polling the status register. | |
| 813 | + */ | |
| 814 | + reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL); | |
| 815 | + reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; | |
| 816 | + writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL); | |
| 813 | 817 | |
| 814 | 818 | reg = readl(reg_base + CQSPI_REG_SIZE); |
| 815 | 819 | reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; |
| @@ -517,6 +517,12 @@ static int cdns_spi_probe(struct platform_device *pdev) · 516 unmodified lines | ||
| 517 | 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 | 526 | ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); |
| 521 | 527 | if (ret < 0) |
| 522 | 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 | 537 | /* SPI controller initializations */ |
| 532 | 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 | 540 | irq = platform_get_irq(pdev, 0); |
| 540 | 541 | if (irq <= 0) { |
| 541 | 542 | ret = -ENXIO; |
| @@ -566,6 +567,9 @@ static int cdns_spi_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 566 | 567 | |
| 567 | 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 | 573 | ret = spi_register_master(master); |
| 570 | 574 | if (ret) { |
| 571 | 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 | 507 | struct spi_device *spi = msg->spi; |
| 508 | 508 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE; |
| 509 | − u32 testreg; | |
| 509 | + u32 testreg, delay; | |
| 510 | 510 | u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); |
| 511 | 511 | |
| 512 | 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 | 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 | 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 | 591 | struct spi_device *spi) |
| 575 | 592 | { |
| 576 | 593 | u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); |
| 577 | − u32 clk, delay; | |
| 594 | + u32 clk; | |
| 578 | 595 | |
| 579 | 596 | /* Clear BL field and set the right value */ |
| 580 | 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 | 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 | 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 | 427 | mtk_spi_setup_packet(master); |
| 428 | 428 | |
| 429 | 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 | 436 | remainder = xfer->len % 4; |
| 433 | 437 | if (remainder > 0) { |
| 434 | 438 | reg_val = 0; |
| 435 | − memcpy(®_val, xfer->tx_buf + (cnt * 4), remainder); | |
| 436 | − writel(reg_val, mdata->base + SPI_TX_DATA_REG); | |
| 439 | + if (xfer->tx_buf) { | |
| 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 | 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 | 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 | 806 | if (mdata->dev_comp->need_pad_sel) { |
| 803 | 807 | if (mdata->pad_num != master->num_chipselect) { |
| 804 | 808 | dev_err(&pdev->dev, |
| @@ -838,6 +842,12 @@ static int mtk_spi_probe(struct platform_device *pdev) · 33 unmodified lines | ||
| 838 | 842 | dev_notice(&pdev->dev, "SPI dma_set_mask(%d) failed, ret:%d\n", |
| 839 | 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 | 851 | return 0; |
| 842 | 852 | |
| 843 | 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 | 884 | ier = readl_relaxed(spi->base + STM32H7_SPI_IER); |
| 885 | 885 | |
| 886 | 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 | 892 | mask |= STM32H7_SPI_SR_SUSP; |
| 889 | 893 | /* |
| 890 | − * When TXTF is set, DXPIE and TXPIE are cleared. So in case of | |
| 891 | − * Full-Duplex, need to poll RXP event to know if there are remaining | |
| 892 | − * data, before disabling SPI. | |
| 894 | + * DXPIE is set in Full-Duplex, one IT will be raised if TXP and RXP | |
| 895 | + * are set. So in case of Full-Duplex, need to poll TXP and RXP event. | |
| 893 | 896 | */ |
| 894 | − if (spi->rx_buf && !spi->cur_usedma) | |
| 895 | − mask |= STM32H7_SPI_SR_RXP; | |
| 897 | + if ((spi->cur_comm == SPI_FULL_DUPLEX) && !spi->cur_usedma) | |
| 898 | + mask |= STM32H7_SPI_SR_TXP | STM32H7_SPI_SR_RXP; | |
| 896 | 899 | |
| 897 | 900 | if (!(sr & mask)) { |
| 898 | 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 | 1928 | master->can_dma = stm32_spi_can_dma; |
| 1926 | 1929 | |
| 1927 | 1930 | pm_runtime_set_active(&pdev->dev); |
| 1931 | + pm_runtime_get_noresume(&pdev->dev); | |
| 1928 | 1932 | pm_runtime_enable(&pdev->dev); |
| 1929 | 1933 | |
| 1930 | 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 | 1945 | err_pm_disable: |
| 1942 | 1946 | pm_runtime_disable(&pdev->dev); |
| 1947 | + pm_runtime_put_noidle(&pdev->dev); | |
| 1948 | + pm_runtime_set_suspended(&pdev->dev); | |
| 1943 | 1949 | err_dma_release: |
| 1944 | 1950 | if (spi->dma_tx) |
| 1945 | 1951 | dma_release_channel(spi->dma_tx); |
| @@ -1956,9 +1962,14 @@ static int stm32_spi_remove(struct platform_device *pdev) · 10 unmodified lines | ||
| 1956 | 1962 | struct spi_master *master = platform_get_drvdata(pdev); |
| 1957 | 1963 | struct stm32_spi *spi = spi_master_get_devdata(master); |
| 1958 | 1964 | |
| 1965 | + pm_runtime_get_sync(&pdev->dev); | |
| 1966 | + | |
| 1959 | 1967 | spi_unregister_master(master); |
| 1960 | 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 | 1973 | if (master->dma_tx) |
| 1963 | 1974 | dma_release_channel(master->dma_tx); |
| 1964 | 1975 | if (master->dma_rx) |
| @@ -1966,7 +1977,6 @@ static int stm32_spi_remove(struct platform_device *pdev) · 1 unmodified line | ||
| 1966 | 1977 | |
| 1967 | 1978 | clk_disable_unprepare(spi->clk); |
| 1968 | 1979 | |
| 1969 | − pm_runtime_disable(&pdev->dev); | |
| 1970 | 1980 | |
| 1971 | 1981 | pinctrl_pm_select_sleep_state(&pdev->dev); |
| 1972 | 1982 | |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include "target_core_alua.h" |
| 26 | 26 | |
| 27 | 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 | 29 | static sense_reason_t sbc_execute_unmap(struct se_cmd *cmd); |
| 30 | 30 | |
| 31 | 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 | 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 | 284 | struct se_device *dev = cmd->se_dev; |
| 285 | 285 | sector_t end_lba = dev->transport->get_blocks(dev) + 1; |
| 286 | 286 | unsigned int sectors = sbc_get_write_same_sectors(cmd); |
| 287 | 287 | sense_reason_t ret; |
| 288 | 288 | |
| 289 | − if ((flags[0] & 0x04) || (flags[0] & 0x02)) { | |
| 289 | + if ((flags & 0x04) || (flags & 0x02)) { | |
| 290 | 290 | pr_err("WRITE_SAME PBDATA and LBDATA" |
| 291 | 291 | " bits not supported for Block Discard" |
| 292 | 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 | 310 | /* We always have ANC_SUP == 0 so setting ANCHOR is always an error */ |
| 311 | − if (flags[0] & 0x10) { | |
| 311 | + if (flags & 0x10) { | |
| 312 | 312 | pr_warn("WRITE SAME with ANCHOR not supported\n"); |
| 313 | 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 | 316 | * Special case for WRITE_SAME w/ UNMAP=1 that ends up getting |
| 317 | 317 | * translated into block discard requests within backend code. |
| 318 | 318 | */ |
| 319 | − if (flags[0] & 0x08) { | |
| 319 | + if (flags & 0x08) { | |
| 320 | 320 | if (!ops->execute_unmap) |
| 321 | 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 | 331 | if (!ops->execute_write_same) |
| 332 | 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 | 335 | if (ret) |
| 336 | 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 | 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 | 721 | u32 sectors, bool is_write) |
| 722 | 722 | { |
| 723 | − u8 protect = cdb[1] >> 5; | |
| 724 | 723 | int sp_ops = cmd->se_sess->sup_prot_ops; |
| 725 | 724 | int pi_prot_type = dev->dev_attrib.pi_prot_type; |
| 726 | 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 | 767 | fallthrough; |
| 769 | 768 | default: |
| 770 | 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 | 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 | 842 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 844 | 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 | 846 | if (ret) |
| 848 | 847 | return ret; |
| 849 | 848 | |
| @@ -857,7 +856,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 7 unmodified lines | ||
| 857 | 856 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 858 | 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 | 860 | if (ret) |
| 862 | 861 | return ret; |
| 863 | 862 | |
| @@ -871,7 +870,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 7 unmodified lines | ||
| 871 | 870 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 872 | 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 | 874 | if (ret) |
| 876 | 875 | return ret; |
| 877 | 876 | |
| @@ -892,7 +891,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 14 unmodified lines | ||
| 892 | 891 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 893 | 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 | 895 | if (ret) |
| 897 | 896 | return ret; |
| 898 | 897 | |
| @@ -906,7 +905,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 7 unmodified lines | ||
| 906 | 905 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 907 | 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 | 909 | if (ret) |
| 911 | 910 | return ret; |
| 912 | 911 | |
| @@ -921,7 +920,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 8 unmodified lines | ||
| 921 | 920 | if (sbc_check_dpofua(dev, cmd, cdb)) |
| 922 | 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 | 924 | if (ret) |
| 926 | 925 | return ret; |
| 927 | 926 | |
| @@ -980,7 +979,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 52 unmodified lines | ||
| 980 | 979 | size = sbc_get_size(cmd, 1); |
| 981 | 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 | 983 | if (ret) |
| 985 | 984 | return ret; |
| 986 | 985 | break; |
| @@ -1079,7 +1078,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 92 unmodified lines | ||
| 1079 | 1078 | size = sbc_get_size(cmd, 1); |
| 1080 | 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 | 1082 | if (ret) |
| 1084 | 1083 | return ret; |
| 1085 | 1084 | break; |
| @@ -1097,7 +1096,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) · 11 unmodified lines | ||
| 1097 | 1096 | * Follow sbcr26 with WRITE_SAME (10) and check for the existence |
| 1098 | 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 | 1100 | if (ret) |
| 1102 | 1101 | return ret; |
| 1103 | 1102 | break; |
| @@ -886,7 +886,7 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) · 885 unmodified lines | ||
| 886 | 886 | INIT_WORK(&cmd->work, success ? target_complete_ok_work : |
| 887 | 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 | 890 | cpu = cmd->cpuid; |
| 891 | 891 | else |
| 892 | 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 | 826 | /* --- WWAN framework integration --- */ |
| 827 | −#ifdef CONFIG_WWAN | |
| 827 | +#ifdef CONFIG_WWAN_CORE | |
| 828 | 828 | static int wdm_wwan_port_start(struct wwan_port *port) |
| 829 | 829 | { |
| 830 | 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 | 963 | /* inbuf has been copied, it is safe to check for outstanding data */ |
| 964 | 964 | schedule_work(&desc->service_outs_intr); |
| 965 | 965 | } |
| 966 | −#else /* CONFIG_WWAN */ | |
| 966 | +#else /* CONFIG_WWAN_CORE */ | |
| 967 | 967 | static void wdm_wwan_init(struct wdm_device *desc) {} |
| 968 | 968 | static void wdm_wwan_deinit(struct wdm_device *desc) {} |
| 969 | 969 | static void wdm_wwan_rx(struct wdm_device *desc, int length) {} |
| 970 | −#endif /* CONFIG_WWAN */ | |
| 970 | +#endif /* CONFIG_WWAN_CORE */ | |
| 971 | 971 | |
| 972 | 972 | /* --- error handling --- */ |
| 973 | 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 | 1133 | "wIndex=%04x wLength=%04x\n", |
| 1134 | 1134 | ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, |
| 1135 | 1135 | ctrl->wIndex, ctrl->wLength); |
| 1136 | − if (ctrl->bRequestType & 0x80) { | |
| 1136 | + if ((ctrl->bRequestType & USB_DIR_IN) && ctrl->wLength) { | |
| 1137 | 1137 | pipe = usb_rcvctrlpipe(dev, 0); |
| 1138 | 1138 | snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, NULL, 0); |
| 1139 | 1139 | |
| @@ -48,6 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | #define USB_TP_TRANSMISSION_DELAY 40 /* ns */ |
| 50 | 50 | #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ |
| 51 | +#define USB_PING_RESPONSE_TIME 400 /* ns */ | |
| 51 | 52 | |
| 52 | 53 | /* Protect struct usb_device->state and ->children members |
| 53 | 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 | − * either U1 or U2. | |
| 186 | + * Set the Maximum Exit Latency (MEL) for the host to wakup up the path from | |
| 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 | 190 | static void usb_set_lpm_mel(struct usb_device *udev, |
| 189 | 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 | 195 | unsigned int hub_exit_latency) |
| 194 | 196 | { |
| 195 | 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 | |
| 201 | − * to the parent hub into U0. The parent hub must then decode the | |
| 202 | − * packet (hub header decode latency) to figure out which port it was | |
| 203 | − * bound for. | |
| 204 | − * | |
| 205 | − * The Hub Header decode latency is expressed in 0.1us intervals (0x1 | |
| 206 | − * means 0.1us). Multiply that by 100 to get nanoseconds. | |
| 200 | + * tMEL1. time to transition path from host to device into U0. | |
| 201 | + * MEL for parent already contains the delay up to parent, so only add | |
| 202 | + * the exit latency for the last link (pick the slower exit latency), | |
| 203 | + * and the hub header decode latency. See USB 3.1 section C 2.2.1 | |
| 204 | + * Store MEL in nanoseconds | |
| 207 | 205 | */ |
| 208 | 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 | |
| 213 | − * U0? The greater of either the hub exit latency or the device exit | |
| 214 | − * latency. | |
| 215 | − * | |
| 216 | − * The BOS U1/U2 exit latencies are expressed in 1us intervals. | |
| 217 | − * Multiply that by 1000 to get nanoseconds. | |
| 211 | + * tMEL2. Time to submit PING packet. Sum of tTPTransmissionDelay for | |
| 212 | + * each link + wHubDelay for each hub. Add only for last link. | |
| 213 | + * tMEL4, the time for PING_RESPONSE to traverse upstream is similar. | |
| 214 | + * Multiply by 2 to include it as well. | |
| 218 | 215 | */ |
| 219 | − device_mel = udev_exit_latency * 1000; | |
| 220 | − hub_mel = hub_exit_latency * 1000; | |
| 221 | − if (device_mel > hub_mel) | |
| 222 | − total_mel += device_mel; | |
| 223 | − else | |
| 224 | − total_mel += hub_mel; | |
| 216 | + total_mel += (__le16_to_cpu(hub->descriptor->u.ss.wHubDelay) + | |
| 217 | + USB_TP_TRANSMISSION_DELAY) * 2; | |
| 218 | + | |
| 219 | + /* | |
| 220 | + * tMEL3, tPingResponse. Time taken by device to generate PING_RESPONSE | |
| 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 | 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 | 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 | 4161 | * Enable the hub-initiated U1/U2 idle timeouts, and enable device-initiated |
| 4117 | 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 | 4229 | * U1/U2_ENABLE |
| 4185 | 4230 | */ |
| 4186 | 4231 | if (udev->actconfig && |
| 4187 | − usb_set_device_initiated_lpm(udev, state, true) == 0) { | |
| 4188 | − if (state == USB3_LPM_U1) | |
| 4189 | − udev->usb3_lpm_u1_enabled = 1; | |
| 4190 | − else if (state == USB3_LPM_U2) | |
| 4191 | − udev->usb3_lpm_u2_enabled = 1; | |
| 4192 | − } else { | |
| 4193 | − /* Don't request U1/U2 entry if the device | |
| 4194 | − * cannot transition to U1/U2. | |
| 4195 | − */ | |
| 4196 | − usb_set_lpm_timeout(udev, state, 0); | |
| 4197 | − hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); | |
| 4232 | + usb_device_may_initiate_lpm(udev, state)) { | |
| 4233 | + if (usb_set_device_initiated_lpm(udev, state, true)) { | |
| 4234 | + /* | |
| 4235 | + * Request to enable device initiated U1/U2 failed, | |
| 4236 | + * better to turn off lpm in this case. | |
| 4237 | + */ | |
| 4238 | + usb_set_lpm_timeout(udev, state, 0); | |
| 4239 | + hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); | |
| 4240 | + return; | |
| 4241 | + } | |
| 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 | 4250 | * Disable the hub-initiated U1/U2 idle timeouts, and disable device-initiated |
| 4203 | 4251 | * U1/U2 entry. |
| @@ -501,10 +501,6 @@ static const struct usb_device_id usb_quirk_list[] = { · 500 unmodified lines | ||
| 501 | 501 | /* DJI CineSSD */ |
| 502 | 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 | 504 | /* INTEL VALUE SSD */ |
| 509 | 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 | 383 | * 0 - No (default) |
| 384 | 384 | * 1 - Partial power down |
| 385 | 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 | 389 | * @lpm: Enable LPM support. |
| 387 | 390 | * 0 - No |
| 388 | 391 | * 1 - Yes |
| @@ -480,6 +483,7 @@ struct dwc2_core_params { · 91 unmodified lines | ||
| 480 | 483 | #define DWC2_POWER_DOWN_PARAM_NONE 0 |
| 481 | 484 | #define DWC2_POWER_DOWN_PARAM_PARTIAL 1 |
| 482 | 485 | #define DWC2_POWER_DOWN_PARAM_HIBERNATION 2 |
| 486 | + bool no_clock_gating; | |
| 483 | 487 | |
| 484 | 488 | bool lpm; |
| 485 | 489 | bool lpm_clock_gating; |
| @@ -556,7 +556,8 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) · 555 unmodified lines | ||
| 556 | 556 | * If neither hibernation nor partial power down are supported, |
| 557 | 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 | 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 | 2753 | if (hs_ep->send_zlp) { |
| 2754 | − dwc2_hsotg_program_zlp(hsotg, hs_ep); | |
| 2755 | 2754 | hs_ep->send_zlp = 0; |
| 2756 | − /* transfer will be completed on next complete interrupt */ | |
| 2757 | − return; | |
| 2755 | + if (!using_desc_dma(hsotg)) { | |
| 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 | 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 | 3902 | __func__); |
| 3901 | 3903 | } |
| 3902 | 3904 | } else { |
| 3905 | + /* Mask GINTSTS_GOUTNAKEFF interrupt */ | |
| 3906 | + dwc2_hsotg_disable_gsint(hsotg, GINTSTS_GOUTNAKEFF); | |
| 3907 | + | |
| 3903 | 3908 | if (!(dwc2_readl(hsotg, GINTSTS) & GINTSTS_GOUTNAKEFF)) |
| 3904 | 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 | 3926 | /* Wait for global nak to take effect */ |
| 3907 | 3927 | if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, |
| 3908 | 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 | 4368 | epctl = dwc2_readl(hs, epreg); |
| 4349 | 4369 | |
| 4350 | 4370 | if (value) { |
| 4371 | + /* Unmask GOUTNAKEFF interrupt */ | |
| 4372 | + dwc2_hsotg_en_gsint(hs, GINTSTS_GOUTNAKEFF); | |
| 4373 | + | |
| 4351 | 4374 | if (!(dwc2_readl(hs, GINTSTS) & GINTSTS_GOUTNAKEFF)) |
| 4352 | 4375 | dwc2_set_bit(hs, DCTL, DCTL_SGOUTNAK); |
| 4353 | 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 | 3338 | * If not hibernation nor partial power down are supported, |
| 3339 | 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 | 3343 | break; |
| 3343 | 3344 | } |
| 3344 | 3345 | |
| @@ -4402,7 +4403,8 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) · 1057 unmodified lines | ||
| 4402 | 4403 | * If not hibernation nor partial power down are supported, |
| 4403 | 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 | 4409 | /* After entering suspend, hardware is not accessible */ |
| 4408 | 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 | 76 | struct dwc2_core_params *p = &hsotg->params; |
| 77 | 77 | |
| 78 | 78 | p->power_down = DWC2_POWER_DOWN_PARAM_NONE; |
| 79 | + p->no_clock_gating = true; | |
| 79 | 80 | p->phy_utmi_width = 8; |
| 80 | 81 | } |
| 81 | 82 | |
| @@ -1279,6 +1279,7 @@ struct dwc3 { · 1278 unmodified lines | ||
| 1279 | 1279 | unsigned dis_metastability_quirk:1; |
| 1280 | 1280 | |
| 1281 | 1281 | unsigned dis_split_quirk:1; |
| 1282 | + unsigned async_callbacks:1; | |
| 1282 | 1283 | |
| 1283 | 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 | 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); | |
| 603 | − ret = dwc->gadget_driver->setup(dwc->gadget, ctrl); | |
| 604 | − spin_lock(&dwc->lock); | |
| 602 | + if (dwc->async_callbacks) { | |
| 603 | + spin_unlock(&dwc->lock); | |
| 604 | + ret = dwc->gadget_driver->setup(dwc->gadget, ctrl); | |
| 605 | + spin_lock(&dwc->lock); | |
| 606 | + } | |
| 605 | 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 | 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 | 2598 | static const struct usb_gadget_ops dwc3_gadget_ops = { |
| 2589 | 2599 | .get_frame = dwc3_gadget_get_frame, |
| 2590 | 2600 | .wakeup = dwc3_gadget_wakeup, |
| @@ -2596,6 +2606,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { · 5 unmodified lines | ||
| 2596 | 2606 | .udc_set_ssp_rate = dwc3_gadget_set_ssp_rate, |
| 2597 | 2607 | .get_config_params = dwc3_gadget_config_params, |
| 2598 | 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 | 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 | 3246 | spin_unlock(&dwc->lock); |
| 3236 | 3247 | dwc->gadget_driver->disconnect(dwc->gadget); |
| 3237 | 3248 | spin_lock(&dwc->lock); |
| @@ -3240,7 +3251,7 @@ static void dwc3_disconnect_gadget(struct dwc3 *dwc) · 2 unmodified lines | ||
| 3240 | 3251 | |
| 3241 | 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 | 3255 | spin_unlock(&dwc->lock); |
| 3245 | 3256 | dwc->gadget_driver->suspend(dwc->gadget); |
| 3246 | 3257 | spin_lock(&dwc->lock); |
| @@ -3249,7 +3260,7 @@ static void dwc3_suspend_gadget(struct dwc3 *dwc) · 2 unmodified lines | ||
| 3249 | 3260 | |
| 3250 | 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 | 3264 | spin_unlock(&dwc->lock); |
| 3254 | 3265 | dwc->gadget_driver->resume(dwc->gadget); |
| 3255 | 3266 | spin_lock(&dwc->lock); |
| @@ -3261,7 +3272,7 @@ static void dwc3_reset_gadget(struct dwc3 *dwc) · 5 unmodified lines | ||
| 3261 | 3272 | if (!dwc->gadget_driver) |
| 3262 | 3273 | return; |
| 3263 | 3274 | |
| 3264 | − if (dwc->gadget->speed != USB_SPEED_UNKNOWN) { | |
| 3275 | + if (dwc->async_callbacks && dwc->gadget->speed != USB_SPEED_UNKNOWN) { | |
| 3265 | 3276 | spin_unlock(&dwc->lock); |
| 3266 | 3277 | usb_gadget_udc_reset(dwc->gadget, dwc->gadget_driver); |
| 3267 | 3278 | spin_lock(&dwc->lock); |
| @@ -3585,7 +3596,7 @@ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) · 317 unmodified lines | ||
| 3585 | 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 | 3600 | spin_unlock(&dwc->lock); |
| 3590 | 3601 | dwc->gadget_driver->resume(dwc->gadget); |
| 3591 | 3602 | spin_lock(&dwc->lock); |
| @@ -1198,7 +1198,7 @@ void gserial_free_line(unsigned char port_num) · 1197 unmodified lines | ||
| 1198 | 1198 | struct gs_port *port; |
| 1199 | 1199 | |
| 1200 | 1200 | mutex_lock(&ports[port_num].lock); |
| 1201 | − if (WARN_ON(!ports[port_num].port)) { | |
| 1201 | + if (!ports[port_num].port) { | |
| 1202 | 1202 | mutex_unlock(&ports[port_num].lock); |
| 1203 | 1203 | return; |
| 1204 | 1204 | } |
| @@ -3853,6 +3853,7 @@ static int tegra_xudc_probe(struct platform_device *pdev) · 3852 unmodified lines | ||
| 3853 | 3853 | return 0; |
| 3854 | 3854 | |
| 3855 | 3855 | free_eps: |
| 3856 | + pm_runtime_disable(&pdev->dev); | |
| 3856 | 3857 | tegra_xudc_free_eps(xudc); |
| 3857 | 3858 | free_event_ring: |
| 3858 | 3859 | tegra_xudc_free_event_ring(xudc); |
| @@ -703,24 +703,28 @@ EXPORT_SYMBOL_GPL(ehci_setup); · 702 unmodified lines | ||
| 703 | 703 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
| 704 | 704 | { |
| 705 | 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 | 708 | int bh; |
| 708 | 709 | |
| 709 | 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 | 716 | /* e.g. cardbus physical eject */ |
| 714 | − if (status == ~(u32) 0) { | |
| 717 | + if (current_status == ~(u32) 0) { | |
| 715 | 718 | ehci_dbg (ehci, "device removed\n"); |
| 716 | 719 | goto dead; |
| 717 | 720 | } |
| 721 | + status |= current_status; | |
| 718 | 722 | |
| 719 | 723 | /* |
| 720 | 724 | * We don't use STS_FLR, but some controllers don't like it to |
| 721 | 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 | 729 | /* Shared IRQ? */ |
| 726 | 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 | 735 | /* clear (just) interrupts */ |
| 732 | 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 | 743 | cmd = ehci_readl(ehci, &ehci->regs->command); |
| 734 | 744 | bh = 0; |
| 735 | 745 | |
| @@ -153,8 +153,6 @@ struct max3421_hcd { · 152 unmodified lines | ||
| 153 | 153 | */ |
| 154 | 154 | struct urb *curr_urb; |
| 155 | 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 | 156 | int urb_done; /* > 0 -> no errors, < 0: errno */ |
| 159 | 157 | size_t curr_len; |
| 160 | 158 | u8 hien; |
| @@ -492,39 +490,17 @@ max3421_set_speed(struct usb_hcd *hcd, struct usb_device *dev) · 331 unmodified lines | ||
| 492 | 490 | * Caller must NOT hold HCD spinlock. |
| 493 | 491 | */ |
| 494 | 492 | static void |
| 495 | −max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum, | |
| 496 | − int force_toggles) | |
| 493 | +max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum) | |
| 497 | 494 | { |
| 498 | − struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); | |
| 499 | − int old_epnum, same_ep, rcvtog, sndtog; | |
| 500 | − struct usb_device *old_dev; | |
| 495 | + int rcvtog, sndtog; | |
| 501 | 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 | 498 | /* setup new endpoint's toggle bits: */ |
| 522 | 499 | rcvtog = usb_gettoggle(dev, epnum, 0); |
| 523 | 500 | sndtog = usb_gettoggle(dev, epnum, 1); |
| 524 | 501 | hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) | |
| 525 | 502 | BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); |
| 526 | 503 | |
| 527 | − max3421_hcd->loaded_epnum = epnum; | |
| 528 | 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 | 508 | * address-assignment so it's best to just always load the |
| 533 | 509 | * address whenever the end-point changed/was forced. |
| 534 | 510 | */ |
| 535 | − max3421_hcd->loaded_dev = dev; | |
| 536 | 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 | 642 | struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); |
| 668 | 643 | struct urb *urb, *curr_urb = NULL; |
| 669 | 644 | struct max3421_ep *max3421_ep; |
| 670 | − int epnum, force_toggles = 0; | |
| 645 | + int epnum; | |
| 671 | 646 | struct usb_host_endpoint *ep; |
| 672 | 647 | struct list_head *pos; |
| 673 | 648 | unsigned long flags; |
| @@ -777,7 +752,6 @@ done: · 103 unmodified lines | ||
| 777 | 752 | usb_settoggle(urb->dev, epnum, 0, 1); |
| 778 | 753 | usb_settoggle(urb->dev, epnum, 1, 1); |
| 779 | 754 | max3421_ep->pkt_state = PKT_STATE_SETUP; |
| 780 | − force_toggles = 1; | |
| 781 | 755 | } else |
| 782 | 756 | max3421_ep->pkt_state = PKT_STATE_TRANSFER; |
| 783 | 757 | } |
| @@ -785,7 +759,7 @@ done: · 1 unmodified line | ||
| 785 | 759 | spin_unlock_irqrestore(&max3421_hcd->lock, flags); |
| 786 | 760 | |
| 787 | 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 | 763 | max3421_set_speed(hcd, urb->dev); |
| 790 | 764 | max3421_next_transfer(hcd, 0); |
| 791 | 765 | return 1; |
| @@ -1379,6 +1353,16 @@ max3421_urb_done(struct usb_hcd *hcd) · 587 unmodified lines | ||
| 1379 | 1353 | status = 0; |
| 1380 | 1354 | urb = max3421_hcd->curr_urb; |
| 1381 | 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 | 1366 | max3421_hcd->curr_urb = NULL; |
| 1383 | 1367 | spin_lock_irqsave(&max3421_hcd->lock, flags); |
| 1384 | 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 | 1638 | * Inform the usbcore about resume-in-progress by returning |
| 1639 | 1639 | * a non-zero value even if there are no status changes. |
| 1640 | 1640 | */ |
| 1641 | + spin_lock_irqsave(&xhci->lock, flags); | |
| 1642 | + | |
| 1641 | 1643 | status = bus_state->resuming_ports; |
| 1642 | 1644 | |
| 1643 | 1645 | mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC; |
| 1644 | 1646 | |
| 1645 | − spin_lock_irqsave(&xhci->lock, flags); | |
| 1646 | 1647 | /* For each port, did anything change? If so, set that bit in buf. */ |
| 1647 | 1648 | for (i = 0; i < max_ports; i++) { |
| 1648 | 1649 | temp = readl(ports[i]->addr); |
| @@ -207,8 +207,7 @@ static int renesas_check_rom_state(struct pci_dev *pdev) · 206 unmodified lines | ||
| 207 | 207 | return 0; |
| 208 | 208 | |
| 209 | 209 | case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */ |
| 210 | − dev_dbg(&pdev->dev, "Unknown ROM status ...\n"); | |
| 211 | − break; | |
| 210 | + return 0; | |
| 212 | 211 | |
| 213 | 212 | case RENESAS_ROM_STATUS_ERROR: /* Error State */ |
| 214 | 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 | 224 | u8 fw_state; |
| 226 | 225 | int err; |
| 227 | 226 | |
| 228 | − /* | |
| 229 | − * Only if device has ROM and loaded FW we can skip loading and | |
| 230 | − * return success. Otherwise (even unknown state), attempt to load FW. | |
| 231 | − */ | |
| 232 | − if (renesas_check_rom(pdev) && !renesas_check_rom_state(pdev)) | |
| 233 | − return 0; | |
| 227 | + /* Check if device has ROM and loaded, if so skip everything */ | |
| 228 | + err = renesas_check_rom(pdev); | |
| 229 | + if (err) { /* we have rom */ | |
| 230 | + err = renesas_check_rom_state(pdev); | |
| 231 | + if (!err) | |
| 232 | + return err; | |
| 233 | + } | |
| 234 | 234 | |
| 235 | 235 | /* |
| 236 | 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 | 636 | { /* end: all zeroes */ } |
| 637 | 637 | }; |
| 638 | 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 | 645 | MODULE_FIRMWARE("renesas_usb_fw.mem"); |
| 646 | +#endif | |
| 640 | 647 | |
| 641 | 648 | /* pci driver glue; this is a "new style" PCI driver module */ |
| 642 | 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 | 87 | list_for_each_entry(usb_phy, &phy_list, head) { |
| 88 | 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 | 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 | 150 | struct usb_phy *usb_phy; |
| 151 | 151 | char uchger_state[50] = { 0 }; |
| 152 | 152 | char uchger_type[50] = { 0 }; |
| 153 | + unsigned long flags; | |
| 153 | 154 | |
| 155 | + spin_lock_irqsave(&phy_lock, flags); | |
| 154 | 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 | 162 | snprintf(uchger_state, ARRAY_SIZE(uchger_state), |
| 157 | 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 | 101 | #define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1) |
| 102 | 102 | #define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0) |
| 103 | 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 | 106 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) |
| 105 | 107 | { |
| 106 | 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 | 125 | if (chan) { |
| 124 | 126 | dmaengine_terminate_all(chan); |
| 125 | 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 | 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 | 155 | { USB_DEVICE(0x10C4, 0x89A4) }, /* CESINEL FTBC Flexible Thyristor Bridge Controller */ |
| 156 | 156 | { USB_DEVICE(0x10C4, 0x89FB) }, /* Qivicon ZigBee USB Radio Stick */ |
| 157 | 157 | { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ |
| 158 | + { USB_DEVICE(0x10C4, 0x8A5B) }, /* CEL EM3588 ZigBee USB Stick */ | |
| 158 | 159 | { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ |
| 159 | 160 | { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */ |
| 160 | 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 | 203 | { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ |
| 203 | 204 | { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ |
| 204 | 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, 0x0198) }, /* GE CS1000 M.2 Key E serial interface */ | |
| 206 | + { USB_DEVICE(0x1901, 0x0197) }, /* GE CS1000 M.2 Key E serial interface */ | |
| 207 | + { USB_DEVICE(0x1901, 0x0198) }, /* GE CS1000 Display serial interface */ | |
| 207 | 208 | { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */ |
| 208 | 209 | { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ |
| 209 | 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 | 238 | #define QUECTEL_PRODUCT_UC15 0x9090 |
| 239 | 239 | /* These u-blox products use Qualcomm's vendor ID */ |
| 240 | 240 | #define UBLOX_PRODUCT_R410M 0x90b2 |
| 241 | +#define UBLOX_PRODUCT_R6XX 0x90fa | |
| 241 | 242 | /* These Yuga products use Qualcomm's vendor ID */ |
| 242 | 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 | 1102 | /* u-blox products using Qualcomm vendor ID */ |
| 1102 | 1103 | { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), |
| 1103 | 1104 | .driver_info = RSVD(1) | RSVD(3) }, |
| 1105 | + { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R6XX), | |
| 1106 | + .driver_info = RSVD(3) }, | |
| 1104 | 1107 | /* Quectel products using Quectel vendor ID */ |
| 1105 | 1108 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21, 0xff, 0xff, 0xff), |
| 1106 | 1109 | .driver_info = NUMEP2 }, |
| @@ -45,6 +45,13 @@ UNUSUAL_DEV(0x059f, 0x105f, 0x0000, 0x9999, · 44 unmodified lines | ||
| 45 | 45 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 46 | 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 | 56 | * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI |
| 50 | 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 | 685 | if (!fwnode) |
| 686 | 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 | 698 | * When both VDD and VSYS power supplies are present, the low power |
| 690 | 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 | 748 | typec_set_pwr_opmode(chip->port, chip->pwr_opmode); |
| 740 | 749 | |
| 741 | 750 | if (client->irq) { |
| 742 | − ret = stusb160x_irq_init(chip, client->irq); | |
| 743 | − if (ret) | |
| 744 | − goto port_unregister; | |
| 745 | − | |
| 746 | 751 | chip->role_sw = fwnode_usb_role_switch_get(fwnode); |
| 747 | 752 | if (IS_ERR(chip->role_sw)) { |
| 748 | 753 | ret = PTR_ERR(chip->role_sw); |
| @@ -752,6 +757,10 @@ static int stusb160x_probe(struct i2c_client *client) · 3 unmodified lines | ||
| 752 | 757 | ret); |
| 753 | 758 | goto port_unregister; |
| 754 | 759 | } |
| 760 | + | |
| 761 | + ret = stusb160x_irq_init(chip, client->irq); | |
| 762 | + if (ret) | |
| 763 | + goto role_sw_put; | |
| 755 | 764 | } else { |
| 756 | 765 | /* |
| 757 | 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 | 785 | return 0; |
| 777 | 786 | |
| 787 | +role_sw_put: | |
| 788 | + if (chip->role_sw) | |
| 789 | + usb_role_switch_put(chip->role_sw); | |
| 778 | 790 | port_unregister: |
| 779 | 791 | typec_unregister_port(chip->port); |
| 780 | 792 | all_reg_disable: |
| @@ -629,6 +629,15 @@ static int tps6598x_probe(struct i2c_client *client) · 628 unmodified lines | ||
| 629 | 629 | if (!fwnode) |
| 630 | 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 | 641 | tps->role_sw = fwnode_usb_role_switch_get(fwnode); |
| 633 | 642 | if (IS_ERR(tps->role_sw)) { |
| 634 | 643 | ret = PTR_ERR(tps->role_sw); |
| @@ -168,21 +168,6 @@ config OSF4_COMPAT · 167 unmodified lines | ||
| 168 | 168 | with v4 shared libraries freely available from Compaq. If you're |
| 169 | 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 | 171 | config BINFMT_MISC |
| 187 | 172 | tristate "Kernel support for MISC binaries" |
| 188 | 173 | help |
| @@ -39,7 +39,6 @@ obj-$(CONFIG_FS_ENCRYPTION) += crypto/ · 38 unmodified lines | ||
| 39 | 39 | obj-$(CONFIG_FS_VERITY) += verity/ |
| 40 | 40 | obj-$(CONFIG_FILE_LOCKING) += locks.o |
| 41 | 41 | obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o |
| 42 | −obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o | |
| 43 | 42 | obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o |
| 44 | 43 | obj-$(CONFIG_BINFMT_SCRIPT) += binfmt_script.o |
| 45 | 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 | 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 | 33 | * CB.CallBack operation type |
| 38 | 34 | */ |
| 39 | −static CM_NAME(CallBack); | |
| 40 | 35 | static const struct afs_call_type afs_SRXCBCallBack = { |
| 41 | − .name = afs_SRXCBCallBack_name, | |
| 36 | + .name = "CB.CallBack", | |
| 42 | 37 | .deliver = afs_deliver_cb_callback, |
| 43 | 38 | .destructor = afs_cm_destructor, |
| 44 | 39 | .work = SRXAFSCB_CallBack, |
| @@ -47,9 +42,8 @@ static const struct afs_call_type afs_SRXCBCallBack = { · 2 unmodified lines | ||
| 47 | 42 | /* |
| 48 | 43 | * CB.InitCallBackState operation type |
| 49 | 44 | */ |
| 50 | −static CM_NAME(InitCallBackState); | |
| 51 | 45 | static const struct afs_call_type afs_SRXCBInitCallBackState = { |
| 52 | − .name = afs_SRXCBInitCallBackState_name, | |
| 46 | + .name = "CB.InitCallBackState", | |
| 53 | 47 | .deliver = afs_deliver_cb_init_call_back_state, |
| 54 | 48 | .destructor = afs_cm_destructor, |
| 55 | 49 | .work = SRXAFSCB_InitCallBackState, |
| @@ -58,9 +52,8 @@ static const struct afs_call_type afs_SRXCBInitCallBackState = { · 2 unmodified lines | ||
| 58 | 52 | /* |
| 59 | 53 | * CB.InitCallBackState3 operation type |
| 60 | 54 | */ |
| 61 | −static CM_NAME(InitCallBackState3); | |
| 62 | 55 | static const struct afs_call_type afs_SRXCBInitCallBackState3 = { |
| 63 | − .name = afs_SRXCBInitCallBackState3_name, | |
| 56 | + .name = "CB.InitCallBackState3", | |
| 64 | 57 | .deliver = afs_deliver_cb_init_call_back_state3, |
| 65 | 58 | .destructor = afs_cm_destructor, |
| 66 | 59 | .work = SRXAFSCB_InitCallBackState, |
| @@ -69,9 +62,8 @@ static const struct afs_call_type afs_SRXCBInitCallBackState3 = { · 2 unmodified lines | ||
| 69 | 62 | /* |
| 70 | 63 | * CB.Probe operation type |
| 71 | 64 | */ |
| 72 | −static CM_NAME(Probe); | |
| 73 | 65 | static const struct afs_call_type afs_SRXCBProbe = { |
| 74 | − .name = afs_SRXCBProbe_name, | |
| 66 | + .name = "CB.Probe", | |
| 75 | 67 | .deliver = afs_deliver_cb_probe, |
| 76 | 68 | .destructor = afs_cm_destructor, |
| 77 | 69 | .work = SRXAFSCB_Probe, |
| @@ -80,9 +72,8 @@ static const struct afs_call_type afs_SRXCBProbe = { · 2 unmodified lines | ||
| 80 | 72 | /* |
| 81 | 73 | * CB.ProbeUuid operation type |
| 82 | 74 | */ |
| 83 | −static CM_NAME(ProbeUuid); | |
| 84 | 75 | static const struct afs_call_type afs_SRXCBProbeUuid = { |
| 85 | − .name = afs_SRXCBProbeUuid_name, | |
| 76 | + .name = "CB.ProbeUuid", | |
| 86 | 77 | .deliver = afs_deliver_cb_probe_uuid, |
| 87 | 78 | .destructor = afs_cm_destructor, |
| 88 | 79 | .work = SRXAFSCB_ProbeUuid, |
| @@ -91,9 +82,8 @@ static const struct afs_call_type afs_SRXCBProbeUuid = { · 2 unmodified lines | ||
| 91 | 82 | /* |
| 92 | 83 | * CB.TellMeAboutYourself operation type |
| 93 | 84 | */ |
| 94 | −static CM_NAME(TellMeAboutYourself); | |
| 95 | 85 | static const struct afs_call_type afs_SRXCBTellMeAboutYourself = { |
| 96 | − .name = afs_SRXCBTellMeAboutYourself_name, | |
| 86 | + .name = "CB.TellMeAboutYourself", | |
| 97 | 87 | .deliver = afs_deliver_cb_tell_me_about_yourself, |
| 98 | 88 | .destructor = afs_cm_destructor, |
| 99 | 89 | .work = SRXAFSCB_TellMeAboutYourself, |
| @@ -102,9 +92,8 @@ static const struct afs_call_type afs_SRXCBTellMeAboutYourself = { · 2 unmodified lines | ||
| 102 | 92 | /* |
| 103 | 93 | * YFS CB.CallBack operation type |
| 104 | 94 | */ |
| 105 | −static CM_NAME(YFS_CallBack); | |
| 106 | 95 | static const struct afs_call_type afs_SRXYFSCB_CallBack = { |
| 107 | − .name = afs_SRXCBYFS_CallBack_name, | |
| 96 | + .name = "YFSCB.CallBack", | |
| 108 | 97 | .deliver = afs_deliver_yfs_cb_callback, |
| 109 | 98 | .destructor = afs_cm_destructor, |
| 110 | 99 | .work = SRXAFSCB_CallBack, |
| @@ -656,7 +656,6 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry, · 655 unmodified lines | ||
| 656 | 656 | return ret; |
| 657 | 657 | } |
| 658 | 658 | |
| 659 | − ret = -ENOENT; | |
| 660 | 659 | if (!cookie.found) { |
| 661 | 660 | _leave(" = -ENOENT [not found]"); |
| 662 | 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 | 2020 | if (d_count(new_dentry) > 2) { |
| 2022 | 2021 | /* copy the target dentry's name */ |
| 2023 | − ret = -ENOMEM; | |
| 2024 | 2022 | op->rename.tmp = d_alloc(new_dentry->d_parent, |
| 2025 | 2023 | &new_dentry->d_name); |
| 2026 | − if (!op->rename.tmp) | |
| 2024 | + if (!op->rename.tmp) { | |
| 2025 | + op->error = -ENOMEM; | |
| 2027 | 2026 | goto error; |
| 2027 | + } | |
| 2028 | 2028 | |
| 2029 | 2029 | ret = afs_sillyrename(new_dvnode, |
| 2030 | 2030 | AFS_FS_I(d_inode(new_dentry)), |
| 2031 | 2031 | new_dentry, op->key); |
| 2032 | − if (ret) | |
| 2032 | + if (ret) { | |
| 2033 | + op->error = ret; | |
| 2033 | 2034 | goto error; |
| 2035 | + } | |
| 2034 | 2036 | |
| 2035 | 2037 | op->dentry_2 = op->rename.tmp; |
| 2036 | 2038 | op->rename.rehash = NULL; |
| @@ -771,14 +771,20 @@ int afs_writepages(struct address_space *mapping, · 770 unmodified lines | ||
| 771 | 771 | if (wbc->range_cyclic) { |
| 772 | 772 | start = mapping->writeback_index * PAGE_SIZE; |
| 773 | 773 | ret = afs_writepages_region(mapping, wbc, start, LLONG_MAX, &next); |
| 774 | − if (start > 0 && wbc->nr_to_write > 0 && ret == 0) | |
| 775 | − ret = afs_writepages_region(mapping, wbc, 0, start, | |
| 776 | − &next); | |
| 777 | − mapping->writeback_index = next / PAGE_SIZE; | |
| 774 | + if (ret == 0) { | |
| 775 | + mapping->writeback_index = next / PAGE_SIZE; | |
| 776 | + if (start > 0 && wbc->nr_to_write > 0) { | |
| 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 | 784 | } else if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) { |
| 779 | 785 | ret = afs_writepages_region(mapping, wbc, 0, LLONG_MAX, &next); |
| 780 | − if (wbc->nr_to_write > 0) | |
| 781 | − mapping->writeback_index = next; | |
| 786 | + if (wbc->nr_to_write > 0 && ret == 0) | |
| 787 | + mapping->writeback_index = next / PAGE_SIZE; | |
| 782 | 788 | } else { |
| 783 | 789 | ret = afs_writepages_region(mapping, wbc, |
| 784 | 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 | 812 | free_percpu(bdev->bd_stats); |
| 813 | 813 | kfree(bdev->bd_meta_info); |
| 814 | 814 | |
| 815 | + if (!bdev_is_partition(bdev)) | |
| 816 | + kfree(bdev->bd_disk); | |
| 815 | 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 | 1488 | int btrfs_find_all_roots(struct btrfs_trans_handle *trans, |
| 1489 | 1489 | struct btrfs_fs_info *fs_info, u64 bytenr, |
| 1490 | 1490 | u64 time_seq, struct ulist **roots, |
| 1491 | − bool ignore_offset) | |
| 1491 | + bool ignore_offset, bool skip_commit_root_sem) | |
| 1492 | 1492 | { |
| 1493 | 1493 | int ret; |
| 1494 | 1494 | |
| 1495 | − if (!trans) | |
| 1495 | + if (!trans && !skip_commit_root_sem) | |
| 1496 | 1496 | down_read(&fs_info->commit_root_sem); |
| 1497 | 1497 | ret = btrfs_find_all_roots_safe(trans, fs_info, bytenr, |
| 1498 | 1498 | time_seq, roots, ignore_offset); |
| 1499 | − if (!trans) | |
| 1499 | + if (!trans && !skip_commit_root_sem) | |
| 1500 | 1500 | up_read(&fs_info->commit_root_sem); |
| 1501 | 1501 | return ret; |
| 1502 | 1502 | } |
| @@ -47,7 +47,8 @@ int btrfs_find_all_leafs(struct btrfs_trans_handle *trans, · 46 unmodified lines | ||
| 47 | 47 | const u64 *extent_item_pos, bool ignore_offset); |
| 48 | 48 | int btrfs_find_all_roots(struct btrfs_trans_handle *trans, |
| 49 | 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 | 52 | char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, |
| 52 | 53 | u32 name_len, unsigned long name_off, |
| 53 | 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 | 352 | btrfs_record_physical_zoned(inode, cb->start, bio); |
| 353 | 353 | btrfs_writepage_endio_finish_ordered(BTRFS_I(inode), NULL, |
| 354 | 354 | cb->start, cb->start + cb->len - 1, |
| 355 | − bio->bi_status == BLK_STS_OK); | |
| 355 | + !cb->errors); | |
| 356 | 356 | |
| 357 | 357 | end_compressed_writeback(inode, cb); |
| 358 | 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 | 974 | kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref); |
| 975 | 975 | |
| 976 | 976 | if (qrecord_inserted) |
| 977 | − btrfs_qgroup_trace_extent_post(fs_info, record); | |
| 977 | + btrfs_qgroup_trace_extent_post(trans, record); | |
| 978 | 978 | |
| 979 | 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 | 1071 | if (qrecord_inserted) |
| 1072 | − return btrfs_qgroup_trace_extent_post(fs_info, record); | |
| 1072 | + return btrfs_qgroup_trace_extent_post(trans, record); | |
| 1073 | 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 | 209 | static void csum_tree_block(struct extent_buffer *buf, u8 *result) |
| 210 | 210 | { |
| 211 | 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 | 213 | const int first_page_part = min_t(u32, PAGE_SIZE, fs_info->nodesize); |
| 214 | 214 | SHASH_DESC_ON_STACK(shash, fs_info->csum_shash); |
| 215 | 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 | 6019 | mutex_lock(&fs_info->fs_devices->device_list_mutex); |
| 6020 | 6020 | devices = &fs_info->fs_devices->devices; |
| 6021 | 6021 | list_for_each_entry(device, devices, dev_list) { |
| 6022 | + if (test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)) | |
| 6023 | + continue; | |
| 6024 | + | |
| 6022 | 6025 | ret = btrfs_trim_free_extents(device, &group_trimmed); |
| 6023 | 6026 | if (ret) { |
| 6024 | 6027 | dev_failed++; |
| @@ -2992,7 +2992,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) · 2991 unmodified lines | ||
| 2992 | 2992 | goto out; |
| 2993 | 2993 | } |
| 2994 | 2994 | |
| 2995 | − if (ordered_extent->disk) | |
| 2995 | + if (ordered_extent->bdev) | |
| 2996 | 2996 | btrfs_rewrite_logical_zoned(ordered_extent); |
| 2997 | 2997 | |
| 2998 | 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 | 190 | entry->truncated_len = (u64)-1; |
| 191 | 191 | entry->qgroup_rsv = ret; |
| 192 | 192 | entry->physical = (u64)-1; |
| 193 | − entry->disk = NULL; | |
| 194 | − entry->partno = (u8)-1; | |
| 195 | 193 | |
| 196 | 194 | ASSERT(type == BTRFS_ORDERED_REGULAR || |
| 197 | 195 | type == BTRFS_ORDERED_NOCOW || |
| @@ -145,8 +145,7 @@ struct btrfs_ordered_extent { · 144 unmodified lines | ||
| 145 | 145 | * command in a workqueue context |
| 146 | 146 | */ |
| 147 | 147 | u64 physical; |
| 148 | − struct gendisk *disk; | |
| 149 | − u8 partno; | |
| 148 | + struct block_device *bdev; | |
| 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 | 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 | 1708 | struct btrfs_qgroup_extent_record *qrecord) |
| 1709 | 1709 | { |
| 1710 | 1710 | struct ulist *old_root; |
| 1711 | 1711 | u64 bytenr = qrecord->bytenr; |
| 1712 | 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 | 1737 | if (ret < 0) { |
| 1716 | − fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT; | |
| 1717 | − btrfs_warn(fs_info, | |
| 1738 | + trans->fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT; | |
| 1739 | + btrfs_warn(trans->fs_info, | |
| 1718 | 1740 | "error accounting new delayed refs extent (err code: %d), quota inconsistent", |
| 1719 | 1741 | ret); |
| 1720 | 1742 | return 0; |
| @@ -1758,7 +1780,7 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr, · 37 unmodified lines | ||
| 1758 | 1780 | kfree(record); |
| 1759 | 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 | 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 | 2651 | /* Search commit root to find old_roots */ |
| 2630 | 2652 | ret = btrfs_find_all_roots(NULL, fs_info, |
| 2631 | 2653 | record->bytenr, 0, |
| 2632 | − &record->old_roots, false); | |
| 2654 | + &record->old_roots, false, false); | |
| 2633 | 2655 | if (ret < 0) |
| 2634 | 2656 | goto cleanup; |
| 2635 | 2657 | } |
| @@ -2645,7 +2667,7 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans) · 9 unmodified lines | ||
| 2645 | 2667 | * current root. It's safe inside commit_transaction(). |
| 2646 | 2668 | */ |
| 2647 | 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 | 2671 | if (ret < 0) |
| 2650 | 2672 | goto cleanup; |
| 2651 | 2673 | if (qgroup_to_skip) { |
| @@ -3179,7 +3201,7 @@ static int qgroup_rescan_leaf(struct btrfs_trans_handle *trans, · 527 unmodified lines | ||
| 3179 | 3201 | num_bytes = found.offset; |
| 3180 | 3202 | |
| 3181 | 3203 | ret = btrfs_find_all_roots(NULL, fs_info, found.objectid, 0, |
| 3182 | − &roots, false); | |
| 3204 | + &roots, false, false); | |
| 3183 | 3205 | if (ret < 0) |
| 3184 | 3206 | goto out; |
| 3185 | 3207 | /* For rescan, just pass old_roots as NULL */ |
| @@ -298,7 +298,7 @@ int btrfs_qgroup_trace_extent_nolock( · 297 unmodified lines | ||
| 298 | 298 | * using current root, then we can move all expensive backref walk out of |
| 299 | 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 | 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 | 224 | * quota. |
| 225 | 225 | */ |
| 226 | 226 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 227 | − false); | |
| 227 | + false, false); | |
| 228 | 228 | if (ret) { |
| 229 | 229 | ulist_free(old_roots); |
| 230 | 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 | 237 | return ret; |
| 238 | 238 | |
| 239 | 239 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 240 | − false); | |
| 240 | + false, false); | |
| 241 | 241 | if (ret) { |
| 242 | 242 | ulist_free(old_roots); |
| 243 | 243 | ulist_free(new_roots); |
| @@ -261,7 +261,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root, · 17 unmodified lines | ||
| 261 | 261 | new_roots = NULL; |
| 262 | 262 | |
| 263 | 263 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 264 | − false); | |
| 264 | + false, false); | |
| 265 | 265 | if (ret) { |
| 266 | 266 | ulist_free(old_roots); |
| 267 | 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 | 273 | return -EINVAL; |
| 274 | 274 | |
| 275 | 275 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 276 | − false); | |
| 276 | + false, false); | |
| 277 | 277 | if (ret) { |
| 278 | 278 | ulist_free(old_roots); |
| 279 | 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 | 327 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 328 | − false); | |
| 328 | + false, false); | |
| 329 | 329 | if (ret) { |
| 330 | 330 | ulist_free(old_roots); |
| 331 | 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 | 338 | return ret; |
| 339 | 339 | |
| 340 | 340 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 341 | − false); | |
| 341 | + false, false); | |
| 342 | 342 | if (ret) { |
| 343 | 343 | ulist_free(old_roots); |
| 344 | 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 | 362 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 363 | − false); | |
| 363 | + false, false); | |
| 364 | 364 | if (ret) { |
| 365 | 365 | ulist_free(old_roots); |
| 366 | 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 | 373 | return ret; |
| 374 | 374 | |
| 375 | 375 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 376 | − false); | |
| 376 | + false, false); | |
| 377 | 377 | if (ret) { |
| 378 | 378 | ulist_free(old_roots); |
| 379 | 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 | 403 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, |
| 404 | − false); | |
| 404 | + false, false); | |
| 405 | 405 | if (ret) { |
| 406 | 406 | ulist_free(old_roots); |
| 407 | 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 | 414 | return ret; |
| 415 | 415 | |
| 416 | 416 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, |
| 417 | − false); | |
| 417 | + false, false); | |
| 418 | 418 | if (ret) { |
| 419 | 419 | ulist_free(old_roots); |
| 420 | 420 | ulist_free(new_roots); |
| @@ -5526,16 +5526,29 @@ log_extents: · 5525 unmodified lines | ||
| 5526 | 5526 | spin_lock(&inode->lock); |
| 5527 | 5527 | inode->logged_trans = trans->transid; |
| 5528 | 5528 | /* |
| 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). | |
| 5531 | − * This is to prevent data loss when we do a write to the inode, | |
| 5532 | − * then the inode gets evicted after all delalloc was flushed, | |
| 5533 | − * then we log it exists (due to a rename for example) and then | |
| 5534 | − * fsync it. This last fsync would do nothing (not logging the | |
| 5535 | − * extents previously written). | |
| 5529 | + * Don't update last_log_commit if we logged that an inode exists. | |
| 5530 | + * We do this for two reasons: | |
| 5531 | + * | |
| 5532 | + * 1) We might have had buffered writes to this inode that were | |
| 5533 | + * flushed and had their ordered extents completed in this | |
| 5534 | + * transaction, but we did not previously log the inode with | |
| 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 || | |
| 5538 | − !test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags)) | |
| 5551 | + if (inode_only != LOG_INODE_EXISTS) | |
| 5539 | 5552 | inode->last_log_commit = inode->last_sub_trans; |
| 5540 | 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 | 6503 | * if this inode hasn't been logged and directory we're renaming it |
| 6491 | 6504 | * from hasn't been logged, we don't need to log it |
| 6492 | 6505 | */ |
| 6493 | − if (inode->logged_trans < trans->transid && | |
| 6494 | − (!old_dir || old_dir->logged_trans < trans->transid)) | |
| 6506 | + if (!inode_logged(trans, inode) && | |
| 6507 | + (!old_dir || !inode_logged(trans, old_dir))) | |
| 6495 | 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 | 1078 | if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) { |
| 1079 | 1079 | list_del_init(&device->dev_alloc_list); |
| 1080 | 1080 | clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state); |
| 1081 | + fs_devices->rw_devices--; | |
| 1081 | 1082 | } |
| 1082 | 1083 | list_del_init(&device->dev_list); |
| 1083 | 1084 | fs_devices->num_devices--; |
| @@ -1349,8 +1349,7 @@ void btrfs_record_physical_zoned(struct inode *inode, u64 file_offset, · 1348 unmodified lines | ||
| 1349 | 1349 | return; |
| 1350 | 1350 | |
| 1351 | 1351 | ordered->physical = physical; |
| 1352 | − ordered->disk = bio->bi_bdev->bd_disk; | |
| 1353 | − ordered->partno = bio->bi_bdev->bd_partno; | |
| 1352 | + ordered->bdev = bio->bi_bdev; | |
| 1354 | 1353 | |
| 1355 | 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 | 1361 | struct extent_map_tree *em_tree; |
| 1363 | 1362 | struct extent_map *em; |
| 1364 | 1363 | struct btrfs_ordered_sum *sum; |
| 1365 | − struct block_device *bdev; | |
| 1366 | 1364 | u64 orig_logical = ordered->disk_bytenr; |
| 1367 | 1365 | u64 *logical = NULL; |
| 1368 | 1366 | int nr, stripe_len; |
| 1369 | 1367 | |
| 1370 | 1368 | /* Zoned devices should not have partitions. So, we can assume it is 0 */ |
| 1371 | − ASSERT(ordered->partno == 0); | |
| 1372 | − bdev = bdgrab(ordered->disk->part0); | |
| 1373 | − if (WARN_ON(!bdev)) | |
| 1369 | + ASSERT(!bdev_is_partition(ordered->bdev)); | |
| 1370 | + if (WARN_ON(!ordered->bdev)) | |
| 1374 | 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 | 1374 | ordered->physical, &logical, &nr, |
| 1378 | 1375 | &stripe_len))) |
| 1379 | 1376 | goto out; |
| @@ -1402,7 +1399,6 @@ void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered) · 22 unmodified lines | ||
| 1402 | 1399 | |
| 1403 | 1400 | out: |
| 1404 | 1401 | kfree(logical); |
| 1405 | − bdput(bdev); | |
| 1406 | 1402 | } |
| 1407 | 1403 | |
| 1408 | 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 | 4456 | break; |
| 4457 | 4457 | case CEPH_MDS_SESSION_CLOSING: |
| 4458 | 4458 | /* Should never reach this when we're unmounting */ |
| 4459 | − WARN_ON_ONCE(true); | |
| 4459 | + WARN_ON_ONCE(s->s_ttl); | |
| 4460 | 4460 | fallthrough; |
| 4461 | 4461 | case CEPH_MDS_SESSION_NEW: |
| 4462 | 4462 | case CEPH_MDS_SESSION_RESTARTING: |
| @@ -873,8 +873,11 @@ PsxDelete: · 872 unmodified lines | ||
| 873 | 873 | InformationLevel) - 4; |
| 874 | 874 | offset = param_offset + params; |
| 875 | 875 | |
| 876 | − /* Setup pointer to Request Data (inode type) */ | |
| 877 | − pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset); | |
| 876 | + /* Setup pointer to Request Data (inode type). | |
| 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 | 881 | pRqD->type = cpu_to_le16(type); |
| 879 | 882 | pSMB->ParameterOffset = cpu_to_le16(param_offset); |
| 880 | 883 | pSMB->DataOffset = cpu_to_le16(offset); |
| @@ -1081,7 +1084,8 @@ PsxCreat: · 200 unmodified lines | ||
| 1081 | 1084 | param_offset = offsetof(struct smb_com_transaction2_spi_req, |
| 1082 | 1085 | InformationLevel) - 4; |
| 1083 | 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 | 1089 | pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); |
| 1086 | 1090 | pdata->Permissions = cpu_to_le64(mode); |
| 1087 | 1091 | pdata->PosixOpenFlags = cpu_to_le32(posix_flags); |
| @@ -220,7 +220,7 @@ cifs_reconnect(struct TCP_Server_Info *server) · 219 unmodified lines | ||
| 220 | 220 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 221 | 221 | struct super_block *sb = NULL; |
| 222 | 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 | 224 | struct dfs_cache_tgt_iterator *tgt_it = NULL; |
| 225 | 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 | 3131 | int rc; |
| 3132 | 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 | 3134 | struct dfs_cache_tgt_iterator *tgt_it = NULL; |
| 3135 | 3135 | struct smb3_fs_context tmp_ctx = {NULL}; |
| 3136 | 3136 | |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include "cifs_debug.h" |
| 20 | 20 | #include "cifs_unicode.h" |
| 21 | 21 | #include "smb2glob.h" |
| 22 | +#include "dns_resolve.h" | |
| 22 | 23 | |
| 23 | 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 | 913 | err_free_it: |
| 913 | 914 | list_for_each_entry_safe(it, nit, head, it_list) { |
| 915 | + list_del(&it->it_list); | |
| 914 | 916 | kfree(it->it_name); |
| 915 | 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 | 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 | 1487 | * Refresh all active dfs mounts regardless of whether they are in cache or not. |
| 1298 | 1488 | * (cache can be cleared) |
| @@ -1303,7 +1493,6 @@ static void refresh_mounts(struct cifs_ses **sessions) · 4 unmodified lines | ||
| 1303 | 1493 | struct cifs_ses *ses; |
| 1304 | 1494 | struct cifs_tcon *tcon, *ntcon; |
| 1305 | 1495 | struct list_head tcons; |
| 1306 | − unsigned int xid; | |
| 1307 | 1496 | |
| 1308 | 1497 | INIT_LIST_HEAD(&tcons); |
| 1309 | 1498 | |
| @@ -1321,44 +1510,8 @@ static void refresh_mounts(struct cifs_ses **sessions) · 11 unmodified lines | ||
| 1321 | 1510 | spin_unlock(&cifs_tcp_ses_lock); |
| 1322 | 1511 | |
| 1323 | 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 | 1513 | list_del_init(&tcon->ulist); |
| 1332 | − | |
| 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); | |
| 1514 | + refresh_tcon(sessions, tcon, false); | |
| 1362 | 1515 | cifs_put_tcon(tcon); |
| 1363 | 1516 | } |
| 1364 | 1517 | } |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/uuid.h> |
| 14 | 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 | 18 | struct dfs_cache_tgt_list { |
| 17 | 19 | int tl_numtgts; |
| 18 | 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 | 46 | void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id); |
| 45 | 47 | void dfs_cache_add_refsrv_session(const uuid_t *mount_id, struct cifs_ses *ses); |
| 46 | 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 | 51 | static inline struct dfs_cache_tgt_iterator * |
| 49 | 52 | dfs_cache_get_next_tgt(struct dfs_cache_tgt_list *tl, |
| @@ -4619,7 +4619,7 @@ read_complete: · 4618 unmodified lines | ||
| 4619 | 4619 | |
| 4620 | 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 | 4623 | int rc = -EACCES; |
| 4624 | 4624 | unsigned int xid; |
| 4625 | 4625 | |
| @@ -13,6 +13,9 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/magic.h> |
| 14 | 14 | #include <linux/security.h> |
| 15 | 15 | #include <net/net_namespace.h> |
| 16 | +#ifdef CONFIG_CIFS_DFS_UPCALL | |
| 17 | +#include "dfs_cache.h" | |
| 18 | +#endif | |
| 16 | 19 | */ |
| 17 | 20 | |
| 18 | 21 | #include <linux/ctype.h> |
| @@ -779,6 +782,10 @@ static int smb3_reconfigure(struct fs_context *fc) · 760 unmodified lines | ||
| 779 | 782 | smb3_cleanup_fs_context_contents(cifs_sb->ctx); |
| 780 | 783 | rc = smb3_fs_context_dup(cifs_sb->ctx, ctx); |
| 781 | 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 | 790 | return rc; |
| 784 | 791 | } |
| @@ -918,6 +925,13 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, · 133 unmodified lines | ||
| 918 | 925 | ctx->cred_uid = uid; |
| 919 | 926 | ctx->cruid_specified = true; |
| 920 | 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 | 935 | case Opt_backupgid: |
| 922 | 936 | gid = make_kgid(current_user_ns(), result.uint_32); |
| 923 | 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 | 3619 | struct cifs_io_parms io_parms = {0}; |
| 3620 | 3620 | int nbytes; |
| 3621 | + int rc = 0; | |
| 3621 | 3622 | struct kvec iov[2]; |
| 3622 | 3623 | |
| 3623 | 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 | 3626 | io_parms.tcon = tcon; |
| 3626 | 3627 | io_parms.persistent_fid = cfile->fid.persistent_fid; |
| 3627 | 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 */ | |
| 3632 | − iov[1].iov_base = buf; | |
| 3633 | − iov[1].iov_len = io_parms.length; | |
| 3634 | − return SMB2_write(xid, &io_parms, &nbytes, iov, 1); | |
| 3630 | + while (len) { | |
| 3631 | + io_parms.offset = off; | |
| 3632 | + io_parms.length = len; | |
| 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 | 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 | 3668 | (char **)&out_data, &out_data_len); |
| 3656 | 3669 | if (rc) |
| 3657 | 3670 | goto out; |
| 3658 | − /* | |
| 3659 | − * It is already all allocated | |
| 3660 | − */ | |
| 3661 | − if (out_data_len == 0) | |
| 3662 | − goto out; | |
| 3663 | 3671 | |
| 3664 | 3672 | buf = kzalloc(1024 * 1024, GFP_KERNEL); |
| 3665 | 3673 | if (buf == NULL) { |
| @@ -3782,6 +3790,24 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon, · 116 unmodified lines | ||
| 3782 | 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 | 3811 | if ((keep_size == true) || (i_size_read(inode) >= off + len)) { |
| 3786 | 3812 | /* |
| 3787 | 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 | 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 | 111 | struct inode *dir = page->mapping->host; |
| 112 | 112 | struct super_block *sb = dir->i_sb; |
| 113 | 113 | unsigned chunk_size = ext2_chunk_size(dir); |
| 114 | − char *kaddr = page_address(page); | |
| 115 | 114 | u32 max_inumber = le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count); |
| 116 | 115 | unsigned offs, rec_len; |
| 117 | 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 | 204 | if (!IS_ERR(page)) { |
| 206 | 205 | *page_addr = kmap_local_page(page); |
| 207 | 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 | 209 | goto fail; |
| 210 | 210 | } |
| 211 | 211 | } |
| @@ -584,10 +584,10 @@ out_unlock: · 372 unmodified lines | ||
| 584 | 584 | * ext2_delete_entry deletes a directory entry by merging it with the |
| 585 | 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 | 590 | struct inode *inode = page->mapping->host; |
| 590 | − char *kaddr = page_address(page); | |
| 591 | 591 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); |
| 592 | 592 | unsigned to = ((char *)dir - kaddr) + |
| 593 | 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 | 607 | de = ext2_next_entry(de); |
| 608 | 608 | } |
| 609 | 609 | if (pde) |
| 610 | − from = (char*)pde - (char*)page_address(page); | |
| 610 | + from = (char *)pde - kaddr; | |
| 611 | 611 | pos = page_offset(page) + from; |
| 612 | 612 | lock_page(page); |
| 613 | 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 | 740 | extern int ext2_make_empty(struct inode *, struct inode *); |
| 741 | 741 | extern struct ext2_dir_entry_2 *ext2_find_entry(struct inode *, const struct qstr *, |
| 742 | 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 | 745 | extern int ext2_empty_dir (struct inode *); |
| 745 | 746 | extern struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p, void **pa); |
| 746 | 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 | 293 | goto out; |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | − err = ext2_delete_entry (de, page); | |
| 296 | + err = ext2_delete_entry (de, page, page_addr); | |
| 297 | 297 | ext2_put_page(page, page_addr); |
| 298 | 298 | if (err) |
| 299 | 299 | goto out; |
| @@ -397,7 +397,7 @@ static int ext2_rename (struct user_namespace * mnt_userns, · 97 unmodified lines | ||
| 397 | 397 | old_inode->i_ctime = current_time(old_inode); |
| 398 | 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 | 402 | if (dir_de) { |
| 403 | 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 | 522 | smp_mb(); |
| 523 | 523 | |
| 524 | + if (IS_DAX(inode)) | |
| 525 | + return false; | |
| 526 | + | |
| 524 | 527 | /* while holding I_WB_SWITCH, no one else can update the association */ |
| 525 | 528 | spin_lock(&inode->i_lock); |
| 526 | 529 | if (!(inode->i_sb->s_flags & SB_ACTIVE) || |
| @@ -77,7 +77,7 @@ enum hugetlb_param { · 76 unmodified lines | ||
| 77 | 77 | static const struct fs_parameter_spec hugetlb_fs_parameters[] = { |
| 78 | 78 | fsparam_u32 ("gid", Opt_gid), |
| 79 | 79 | fsparam_string("min_size", Opt_min_size), |
| 80 | − fsparam_u32 ("mode", Opt_mode), | |
| 80 | + fsparam_u32oct("mode", Opt_mode), | |
| 81 | 81 | fsparam_string("nr_inodes", Opt_nr_inodes), |
| 82 | 82 | fsparam_string("pagesize", Opt_pagesize), |
| 83 | 83 | fsparam_string("size", Opt_size), |
| @@ -61,7 +61,6 @@ extern void __init chrdev_init(void); · 60 unmodified lines | ||
| 61 | 61 | */ |
| 62 | 62 | extern const struct fs_context_operations legacy_fs_context_ops; |
| 63 | 63 | extern int parse_monolithic_mount_data(struct fs_context *, void *); |
| 64 | −extern void fc_drop_locked(struct fs_context *); | |
| 65 | 64 | extern void vfs_clean_context(struct fs_context *fc); |
| 66 | 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 | 731 | int work_flags; |
| 732 | 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 | 740 | io_run_cancel(work, wqe); |
| 736 | 741 | return; |
| 737 | 742 | } |
| @@ -1279,8 +1279,17 @@ static void io_prep_async_link(struct io_kiocb *req) · 1278 unmodified lines | ||
| 1279 | 1279 | { |
| 1280 | 1280 | struct io_kiocb *cur; |
| 1281 | 1281 | |
| 1282 | − io_for_each_link(cur, req) | |
| 1283 | − io_prep_async_work(cur); | |
| 1282 | + if (req->flags & REQ_F_LINK_TIMEOUT) { | |
| 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 | 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 | 1304 | /* init ->work of the whole link before punting */ |
| 1296 | 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 | 1317 | trace_io_uring_queue_async_work(ctx, io_wq_is_hashed(&req->work), req, |
| 1298 | 1318 | &req->work, req->flags); |
| 1299 | 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 | 1959 | node = next; |
| 1940 | 1960 | } |
| 1941 | 1961 | if (wq_list_empty(&tctx->task_list)) { |
| 1962 | + spin_lock_irq(&tctx->task_lock); | |
| 1942 | 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 | 1966 | break; |
| 1967 | + } | |
| 1968 | + spin_unlock_irq(&tctx->task_lock); | |
| 1945 | 1969 | /* another tctx_task_work() is enqueued, yield */ |
| 1946 | 1970 | if (test_and_set_bit(0, &tctx->task_state)) |
| 1947 | 1971 | break; |
| @@ -2036,6 +2060,12 @@ static void io_req_task_queue(struct io_kiocb *req) · 88 unmodified lines | ||
| 2036 | 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 | 2069 | static inline void io_queue_next(struct io_kiocb *req) |
| 2040 | 2070 | { |
| 2041 | 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 | 2235 | * Find and free completed poll iocbs |
| 2206 | 2236 | */ |
| 2207 | 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 | 2240 | struct req_batch rb; |
| 2211 | 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 | 2250 | req = list_first_entry(done, struct io_kiocb, inflight_entry); |
| 2221 | 2251 | list_del(&req->inflight_entry); |
| 2222 | 2252 | |
| 2223 | − if (READ_ONCE(req->result) == -EAGAIN && | |
| 2253 | + if (READ_ONCE(req->result) == -EAGAIN && resubmit && | |
| 2224 | 2254 | !(req->flags & REQ_F_DONT_REISSUE)) { |
| 2225 | 2255 | req->iopoll_completed = 0; |
| 2226 | 2256 | req_ref_get(req); |
| 2227 | − io_queue_async_work(req); | |
| 2257 | + io_req_task_queue_reissue(req); | |
| 2228 | 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 | 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 | 2279 | struct io_kiocb *req, *tmp; |
| 2250 | 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 | 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 | 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 | 2335 | while (!list_empty(&ctx->iopoll_list)) { |
| 2306 | 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 | 2340 | /* let it sleep and repeat later if can't complete a request */ |
| 2311 | 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 | 2397 | list_empty(&ctx->iopoll_list)) |
| 2368 | 2398 | break; |
| 2369 | 2399 | } |
| 2370 | − ret = io_do_iopoll(ctx, &nr_events, min); | |
| 2400 | + ret = io_do_iopoll(ctx, &nr_events, min, true); | |
| 2371 | 2401 | } while (!ret && nr_events < min && !need_resched()); |
| 2372 | 2402 | out: |
| 2373 | 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 | 2448 | if (percpu_ref_is_dying(&ctx->refs)) |
| 2419 | 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 | 2456 | return true; |
| 2421 | 2457 | } |
| 2422 | 2458 | #else |
| @@ -2747,7 +2783,7 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, · 324 unmodified lines | ||
| 2747 | 2783 | req->flags &= ~REQ_F_REISSUE; |
| 2748 | 2784 | if (io_resubmit_prep(req)) { |
| 2749 | 2785 | req_ref_get(req); |
| 2750 | − io_queue_async_work(req); | |
| 2786 | + io_req_task_queue_reissue(req); | |
| 2751 | 2787 | } else { |
| 2752 | 2788 | int cflags = 0; |
| 2753 | 2789 | |
| @@ -4802,6 +4838,7 @@ IO_NETOP_FN(recv); · 2048 unmodified lines | ||
| 4802 | 4838 | struct io_poll_table { |
| 4803 | 4839 | struct poll_table_struct pt; |
| 4804 | 4840 | struct io_kiocb *req; |
| 4841 | + int nr_entries; | |
| 4805 | 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 | 4939 | if (req->poll.events & EPOLLONESHOT) |
| 4903 | 4940 | flags = 0; |
| 4904 | 4941 | if (!io_cqring_fill_event(ctx, req->user_data, error, flags)) { |
| 4905 | − io_poll_remove_waitqs(req); | |
| 4906 | 4942 | req->poll.done = true; |
| 4907 | 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 | 4962 | done = io_poll_complete(req, req->result); |
| 4927 | 4963 | if (done) { |
| 4964 | + io_poll_remove_double(req); | |
| 4928 | 4965 | hash_del(&req->hash_node); |
| 4929 | 4966 | } else { |
| 4930 | 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 | 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 | |
| 4999 | − * uses multiple waitqueues for poll handling (eg one for read, one | |
| 5000 | − * for write). Setup a separate io_poll_iocb if this happens. | |
| 5035 | + * The file being polled uses multiple waitqueues for poll handling | |
| 5036 | + * (e.g. one for read, one for write). Setup a separate io_poll_iocb | |
| 5037 | + * if this happens. | |
| 5001 | 5038 | */ |
| 5002 | − if (unlikely(poll->head)) { | |
| 5039 | + if (unlikely(pt->nr_entries)) { | |
| 5003 | 5040 | struct io_poll_iocb *poll_one = poll; |
| 5004 | 5041 | |
| 5005 | 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 | 5064 | *poll_ptr = poll; |
| 5028 | 5065 | } |
| 5029 | 5066 | |
| 5030 | − pt->error = 0; | |
| 5067 | + pt->nr_entries++; | |
| 5031 | 5068 | poll->head = head; |
| 5032 | 5069 | |
| 5033 | 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 | 5142 | ipt->pt._key = mask; |
| 5106 | 5143 | ipt->req = req; |
| 5107 | − ipt->error = -EINVAL; | |
| 5144 | + ipt->error = 0; | |
| 5145 | + ipt->nr_entries = 0; | |
| 5108 | 5146 | |
| 5109 | 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 | 5151 | spin_lock_irq(&ctx->completion_lock); |
| 5152 | + if (ipt->error || (mask && (poll->events & EPOLLONESHOT))) | |
| 5153 | + io_poll_remove_double(req); | |
| 5112 | 5154 | if (likely(poll->head)) { |
| 5113 | 5155 | spin_lock(&poll->head->lock); |
| 5114 | 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 | 5221 | ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, |
| 5180 | 5222 | io_async_wake); |
| 5181 | 5223 | if (ret || ipt.error) { |
| 5182 | − io_poll_remove_double(req); | |
| 5183 | 5224 | spin_unlock_irq(&ctx->completion_lock); |
| 5184 | 5225 | if (ret) |
| 5185 | 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 | 6834 | mutex_lock(&ctx->uring_lock); |
| 6794 | 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 | 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 | 7940 | struct io_wq_data data; |
| 7900 | 7941 | unsigned int concurrency; |
| 7901 | 7942 | |
| 7943 | + mutex_lock(&ctx->uring_lock); | |
| 7902 | 7944 | hash = ctx->hash_map; |
| 7903 | 7945 | if (!hash) { |
| 7904 | 7946 | hash = kzalloc(sizeof(*hash), GFP_KERNEL); |
| 7905 | − if (!hash) | |
| 7947 | + if (!hash) { | |
| 7948 | + mutex_unlock(&ctx->uring_lock); | |
| 7906 | 7949 | return ERR_PTR(-ENOMEM); |
| 7950 | + } | |
| 7907 | 7951 | refcount_set(&hash->refs, 1); |
| 7908 | 7952 | init_waitqueue_head(&hash->wait); |
| 7909 | 7953 | ctx->hash_map = hash; |
| 7910 | 7954 | } |
| 7955 | + mutex_unlock(&ctx->uring_lock); | |
| 7911 | 7956 | |
| 7912 | 7957 | data.hash = hash; |
| 7913 | 7958 | data.task = task; |
| @@ -7981,9 +8026,11 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx, · 67 unmodified lines | ||
| 7981 | 8026 | f = fdget(p->wq_fd); |
| 7982 | 8027 | if (!f.file) |
| 7983 | 8028 | return -ENXIO; |
| 7984 | − fdput(f); | |
| 7985 | − if (f.file->f_op != &io_uring_fops) | |
| 8029 | + if (f.file->f_op != &io_uring_fops) { | |
| 8030 | + fdput(f); | |
| 7986 | 8031 | return -EINVAL; |
| 8032 | + } | |
| 8033 | + fdput(f); | |
| 7987 | 8034 | } |
| 7988 | 8035 | if (ctx->flags & IORING_SETUP_SQPOLL) { |
| 7989 | 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 | 1571 | static int ocfs2_zero_partial_clusters(struct inode *inode, |
| 1533 | 1572 | u64 start, u64 len) |
| 1534 | 1573 | { |
| @@ -1538,6 +1577,7 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, · 3 unmodified lines | ||
| 1538 | 1577 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 1539 | 1578 | unsigned int csize = osb->s_clustersize; |
| 1540 | 1579 | handle_t *handle; |
| 1580 | + loff_t isize = i_size_read(inode); | |
| 1541 | 1581 | |
| 1542 | 1582 | /* |
| 1543 | 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 | 1598 | if ((start & (csize - 1)) == 0 && (end & (csize - 1)) == 0) |
| 1559 | 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 | 1621 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
| 1562 | 1622 | if (IS_ERR(handle)) { |
| 1563 | 1623 | ret = PTR_ERR(handle); |
| @@ -1855,45 +1915,6 @@ out: · 291 unmodified lines | ||
| 1855 | 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 | 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 | 1956 | goto out_inode_unlock; |
| 1936 | 1957 | } |
| 1937 | 1958 | |
| 1938 | − orig_isize = i_size_read(inode); | |
| 1939 | 1959 | switch (sr->l_whence) { |
| 1940 | 1960 | case 0: /*SEEK_SET*/ |
| 1941 | 1961 | break; |
| @@ -1943,7 +1963,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, · 1 unmodified line | ||
| 1943 | 1963 | sr->l_start += f_pos; |
| 1944 | 1964 | break; |
| 1945 | 1965 | case 2: /*SEEK_END*/ |
| 1946 | − sr->l_start += orig_isize; | |
| 1966 | + sr->l_start += i_size_read(inode); | |
| 1947 | 1967 | break; |
| 1948 | 1968 | default: |
| 1949 | 1969 | ret = -EINVAL; |
| @@ -1998,6 +2018,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, · 48 unmodified lines | ||
| 1998 | 2018 | ret = -EINVAL; |
| 1999 | 2019 | } |
| 2000 | 2020 | |
| 2021 | + orig_isize = i_size_read(inode); | |
| 2001 | 2022 | /* zeroout eof blocks in the cluster. */ |
| 2002 | 2023 | if (!ret && change_size && orig_isize < size) { |
| 2003 | 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 | 429 | #endif |
| 430 | 430 | |
| 431 | 431 | /* |
| 432 | − * Only wake up if the pipe started out empty, since | |
| 433 | − * otherwise there should be no readers waiting. | |
| 432 | + * Epoll nonsensically wants a wakeup whether the pipe | |
| 433 | + * was already empty or not. | |
| 434 | 434 | * |
| 435 | 435 | * If it wasn't empty we try to merge new data into |
| 436 | 436 | * the last buffer. |
| 437 | 437 | * |
| 438 | 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 | 440 | * spanning multiple pages. |
| 441 | 441 | */ |
| 442 | 442 | head = pipe->head; |
| 443 | − was_empty = pipe_empty(head, pipe->tail); | |
| 443 | + was_empty = true; | |
| 444 | 444 | chars = total_len & (PAGE_SIZE-1); |
| 445 | − if (chars && !was_empty) { | |
| 445 | + if (chars && !pipe_empty(head, pipe->tail)) { | |
| 446 | 446 | unsigned int mask = pipe->ring_size - 1; |
| 447 | 447 | struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask]; |
| 448 | 448 | int offset = buf->offset + buf->len; |
| @@ -387,6 +387,24 @@ void pathrelse(struct treepath *search_path) · 386 unmodified lines | ||
| 387 | 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 | 408 | static int is_leaf(char *buf, int blocksize, struct buffer_head *bh) |
| 391 | 409 | { |
| 392 | 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 | 472 | "(second one): %h", ih); |
| 455 | 473 | return 0; |
| 456 | 474 | } |
| 457 | − if (is_direntry_le_ih(ih) && (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE))) { | |
| 458 | − reiserfs_warning(NULL, "reiserfs-5093", | |
| 459 | − "item entry count seems wrong %h", | |
| 460 | − ih); | |
| 461 | − return 0; | |
| 475 | + if (is_direntry_le_ih(ih)) { | |
| 476 | + if (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE)) { | |
| 477 | + reiserfs_warning(NULL, "reiserfs-5093", | |
| 478 | + "item entry count seems wrong %h", | |
| 479 | + ih); | |
| 480 | + return 0; | |
| 481 | + } | |
| 482 | + return has_valid_deh_location(bh, ih); | |
| 462 | 483 | } |
| 463 | 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 | 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 | 2093 | s->s_root = d_make_root(root_inode); |
| 2086 | 2094 | if (!s->s_root) |
| 2087 | 2095 | goto error; |
| @@ -32,6 +32,9 @@ static void seq_set_overflow(struct seq_file *m) · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | static void *seq_buf_alloc(unsigned long size) |
| 34 | 34 | { |
| 35 | + if (unlikely(size > MAX_RW_COUNT)) | |
| 36 | + return NULL; | |
| 37 | + | |
| 35 | 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 | 1238 | static __always_inline int validate_range(struct mm_struct *mm, |
| 1239 | − __u64 *start, __u64 len) | |
| 1239 | + __u64 start, __u64 len) | |
| 1240 | 1240 | { |
| 1241 | 1241 | __u64 task_size = mm->task_size; |
| 1242 | 1242 | |
| 1243 | − *start = untagged_addr(*start); | |
| 1244 | − | |
| 1245 | − if (*start & ~PAGE_MASK) | |
| 1243 | + if (start & ~PAGE_MASK) | |
| 1246 | 1244 | return -EINVAL; |
| 1247 | 1245 | if (len & ~PAGE_MASK) |
| 1248 | 1246 | return -EINVAL; |
| 1249 | 1247 | if (!len) |
| 1250 | 1248 | return -EINVAL; |
| 1251 | − if (*start < mmap_min_addr) | |
| 1249 | + if (start < mmap_min_addr) | |
| 1252 | 1250 | return -EINVAL; |
| 1253 | − if (*start >= task_size) | |
| 1251 | + if (start >= task_size) | |
| 1254 | 1252 | return -EINVAL; |
| 1255 | − if (len > task_size - *start) | |
| 1253 | + if (len > task_size - start) | |
| 1256 | 1254 | return -EINVAL; |
| 1257 | 1255 | return 0; |
| 1258 | 1256 | } |
| @@ -1316,7 +1314,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 57 unmodified lines | ||
| 1316 | 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 | 1318 | uffdio_register.range.len); |
| 1321 | 1319 | if (ret) |
| 1322 | 1320 | goto out; |
| @@ -1522,7 +1520,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, · 199 unmodified lines | ||
| 1522 | 1520 | if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister))) |
| 1523 | 1521 | goto out; |
| 1524 | 1522 | |
| 1525 | − ret = validate_range(mm, &uffdio_unregister.start, | |
| 1523 | + ret = validate_range(mm, uffdio_unregister.start, | |
| 1526 | 1524 | uffdio_unregister.len); |
| 1527 | 1525 | if (ret) |
| 1528 | 1526 | goto out; |
| @@ -1671,7 +1669,7 @@ static int userfaultfd_wake(struct userfaultfd_ctx *ctx, · 142 unmodified lines | ||
| 1671 | 1669 | if (copy_from_user(&uffdio_wake, buf, sizeof(uffdio_wake))) |
| 1672 | 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 | 1673 | if (ret) |
| 1676 | 1674 | goto out; |
| 1677 | 1675 | |
| @@ -1711,7 +1709,7 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx, · 33 unmodified lines | ||
| 1711 | 1709 | sizeof(uffdio_copy)-sizeof(__s64))) |
| 1712 | 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 | 1713 | if (ret) |
| 1716 | 1714 | goto out; |
| 1717 | 1715 | /* |
| @@ -1768,7 +1766,7 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx, · 50 unmodified lines | ||
| 1768 | 1766 | sizeof(uffdio_zeropage)-sizeof(__s64))) |
| 1769 | 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 | 1770 | uffdio_zeropage.range.len); |
| 1773 | 1771 | if (ret) |
| 1774 | 1772 | goto out; |
| @@ -1818,7 +1816,7 @@ static int userfaultfd_writeprotect(struct userfaultfd_ctx *ctx, · 43 unmodified lines | ||
| 1818 | 1816 | sizeof(struct uffdio_writeprotect))) |
| 1819 | 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 | 1820 | uffdio_wp.range.len); |
| 1823 | 1821 | if (ret) |
| 1824 | 1822 | return ret; |
| @@ -1866,7 +1864,7 @@ static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg) · 41 unmodified lines | ||
| 1866 | 1864 | sizeof(uffdio_continue) - (sizeof(__s64)))) |
| 1867 | 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 | 1868 | uffdio_continue.range.len); |
| 1871 | 1869 | if (ret) |
| 1872 | 1870 | goto out; |
| @@ -411,7 +411,16 @@ struct xfs_log_dinode { · 410 unmodified lines | ||
| 411 | 411 | /* start of the extended dinode, writable fields */ |
| 412 | 412 | uint32_t di_crc; /* CRC of the inode */ |
| 413 | 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 | 424 | uint64_t di_flags2; /* more random flags */ |
| 416 | 425 | uint32_t di_cowextsize; /* basic cow extent size for file */ |
| 417 | 426 | uint8_t di_pad2[12]; /* more padding for future expansion */ |
| @@ -698,7 +698,8 @@ xlog_recover_do_inode_buffer( · 697 unmodified lines | ||
| 698 | 698 | static xfs_lsn_t |
| 699 | 699 | xlog_recover_get_buf_lsn( |
| 700 | 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 | 704 | uint32_t magic32; |
| 704 | 705 | uint16_t magic16; |
| @@ -706,11 +707,20 @@ xlog_recover_get_buf_lsn( · 1 unmodified line | ||
| 706 | 707 | void *blk = bp->b_addr; |
| 707 | 708 | uuid_t *uuid; |
| 708 | 709 | xfs_lsn_t lsn = -1; |
| 710 | + uint16_t blft; | |
| 709 | 711 | |
| 710 | 712 | /* v4 filesystems always recover immediately */ |
| 711 | 713 | if (!xfs_sb_version_hascrc(&mp->m_sb)) |
| 712 | 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 | 724 | magic32 = be32_to_cpu(*(__be32 *)blk); |
| 715 | 725 | switch (magic32) { |
| 716 | 726 | case XFS_ABTB_CRC_MAGIC: |
| @@ -796,6 +806,7 @@ xlog_recover_get_buf_lsn( · 79 unmodified lines | ||
| 796 | 806 | switch (magicda) { |
| 797 | 807 | case XFS_DIR3_LEAF1_MAGIC: |
| 798 | 808 | case XFS_DIR3_LEAFN_MAGIC: |
| 809 | + case XFS_ATTR3_LEAF_MAGIC: | |
| 799 | 810 | case XFS_DA3_NODE_MAGIC: |
| 800 | 811 | lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); |
| 801 | 812 | uuid = &((struct xfs_da3_blkinfo *)blk)->uuid; |
| @@ -919,7 +930,7 @@ xlog_recover_buf_commit_pass2( · 117 unmodified lines | ||
| 919 | 930 | * the verifier will be reset to match whatever recover turns that |
| 920 | 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 | 934 | if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) { |
| 924 | 935 | trace_xfs_log_recover_buf_skip(log, buf_f); |
| 925 | 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 | 145 | STATIC void |
| 146 | 146 | xfs_log_dinode_to_disk( |
| 147 | 147 | struct xfs_log_dinode *from, |
| 148 | − struct xfs_dinode *to) | |
| 148 | + struct xfs_dinode *to, | |
| 149 | + xfs_lsn_t lsn) | |
| 149 | 150 | { |
| 150 | 151 | to->di_magic = cpu_to_be16(from->di_magic); |
| 151 | 152 | to->di_mode = cpu_to_be16(from->di_mode); |
| @@ -182,7 +183,7 @@ xfs_log_dinode_to_disk( · 30 unmodified lines | ||
| 182 | 183 | to->di_flags2 = cpu_to_be64(from->di_flags2); |
| 183 | 184 | to->di_cowextsize = cpu_to_be32(from->di_cowextsize); |
| 184 | 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 | 187 | memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); |
| 187 | 188 | uuid_copy(&to->di_uuid, &from->di_uuid); |
| 188 | 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 | − * than the lsn of the transaction we are replaying. Note: we still | |
| 266 | − * need to replay an owner change even though the inode is more recent | |
| 267 | − * than the transaction as there is no guarantee that all the btree | |
| 268 | − * blocks are more recent than this transaction, too. | |
| 265 | + * If the inode has an LSN in it, recover the inode only if the on-disk | |
| 266 | + * inode's LSN is older than the lsn of the transaction we are | |
| 267 | + * replaying. We can have multiple checkpoints with the same start LSN, | |
| 268 | + * so the current LSN being equal to the on-disk LSN doesn't necessarily | |
| 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 | 280 | if (dip->di_version >= 3) { |
| 271 | 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 | 284 | trace_xfs_log_recover_inode_skip(log, in_f); |
| 275 | 285 | error = 0; |
| 276 | 286 | goto out_owner_change; |
| @@ -368,8 +378,17 @@ xlog_recover_inode_commit_pass2( · 91 unmodified lines | ||
| 368 | 378 | goto out_release; |
| 369 | 379 | } |
| 370 | 380 | |
| 371 | − /* recover the log dinode inode into the on disk inode */ | |
| 372 | − xfs_log_dinode_to_disk(ldip, dip); | |
| 381 | + /* | |
| 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 | 393 | fields = in_f->ilf_fields; |
| 375 | 394 | if (fields & XFS_ILOG_DEV) |
| @@ -78,13 +78,12 @@ xlog_verify_iclog( · 77 unmodified lines | ||
| 78 | 78 | STATIC void |
| 79 | 79 | xlog_verify_tail_lsn( |
| 80 | 80 | struct xlog *log, |
| 81 | − struct xlog_in_core *iclog, | |
| 82 | − xfs_lsn_t tail_lsn); | |
| 81 | + struct xlog_in_core *iclog); | |
| 83 | 82 | #else |
| 84 | 83 | #define xlog_verify_dest_ptr(a,b) |
| 85 | 84 | #define xlog_verify_grant_tail(a) |
| 86 | 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 | 87 | #endif |
| 89 | 88 | |
| 90 | 89 | STATIC int |
| @@ -487,51 +486,80 @@ out_error: · 396 unmodified lines | ||
| 487 | 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 | 490 | * Flush iclog to disk if this is the last reference to the given iclog and the |
| 515 | 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 | 516 | int |
| 518 | 517 | xlog_state_release_iclog( |
| 519 | 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 | 523 | lockdep_assert_held(&log->l_icloglock); |
| 523 | 524 | |
| 524 | 525 | trace_xlog_iclog_release(iclog, _RET_IP_); |
| 525 | 526 | if (iclog->ic_state == XLOG_STATE_IOERROR) |
| 526 | 527 | return -EIO; |
| 527 | 528 | |
| 528 | − if (atomic_dec_and_test(&iclog->ic_refcnt) && | |
| 529 | − __xlog_state_release_iclog(log, iclog)) { | |
| 530 | − spin_unlock(&log->l_icloglock); | |
| 531 | − xlog_sync(log, iclog); | |
| 532 | − spin_lock(&log->l_icloglock); | |
| 529 | + /* | |
| 530 | + * Grabbing the current log tail needs to be atomic w.r.t. the writing | |
| 531 | + * of the tail LSN into the iclog so we guarantee that the log tail does | |
| 532 | + * not move between deciding if a cache flush is required and writing | |
| 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 | 563 | return 0; |
| 536 | 564 | } |
| 537 | 565 | |
| @@ -773,6 +801,21 @@ xfs_log_mount_cancel( · 235 unmodified lines | ||
| 773 | 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 | 820 | * Wait for the iclog and all prior iclogs to be written disk as required by the |
| 778 | 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 | 870 | /* account for space used by record data */ |
| 828 | 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 | 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 | 902 | spin_lock(&log->l_icloglock); |
| 867 | 903 | iclog = log->l_iclog; |
| 868 | − atomic_inc(&iclog->ic_refcnt); | |
| 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); | |
| 904 | + error = xlog_force_iclog(iclog); | |
| 880 | 905 | xlog_wait_on_iclog(iclog); |
| 881 | 906 | |
| 882 | 907 | if (tic) { |
| @@ -1796,10 +1821,20 @@ xlog_write_iclog( · 913 unmodified lines | ||
| 1796 | 1821 | * metadata writeback and causing priority inversions. |
| 1797 | 1822 | */ |
| 1798 | 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 | 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 | 1835 | if (iclog->ic_flags & XLOG_ICL_NEED_FUA) |
| 1802 | 1836 | iclog->ic_bio.bi_opf |= REQ_FUA; |
| 1837 | + | |
| 1803 | 1838 | iclog->ic_flags &= ~(XLOG_ICL_NEED_FLUSH | XLOG_ICL_NEED_FUA); |
| 1804 | 1839 | |
| 1805 | 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 | 2345 | return 0; |
| 2311 | 2346 | |
| 2312 | 2347 | release_iclog: |
| 2313 | − error = xlog_state_release_iclog(log, iclog); | |
| 2348 | + error = xlog_state_release_iclog(log, iclog, 0); | |
| 2314 | 2349 | spin_unlock(&log->l_icloglock); |
| 2315 | 2350 | return error; |
| 2316 | 2351 | } |
| @@ -2529,7 +2564,7 @@ next_lv: · 212 unmodified lines | ||
| 2529 | 2564 | ASSERT(optype & XLOG_COMMIT_TRANS); |
| 2530 | 2565 | *commit_iclog = iclog; |
| 2531 | 2566 | } else { |
| 2532 | − error = xlog_state_release_iclog(log, iclog); | |
| 2567 | + error = xlog_state_release_iclog(log, iclog, 0); | |
| 2533 | 2568 | } |
| 2534 | 2569 | spin_unlock(&log->l_icloglock); |
| 2535 | 2570 | |
| @@ -2567,6 +2602,7 @@ xlog_state_activate_iclog( · 31 unmodified lines | ||
| 2567 | 2602 | memset(iclog->ic_header.h_cycle_data, 0, |
| 2568 | 2603 | sizeof(iclog->ic_header.h_cycle_data)); |
| 2569 | 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 | 3003 | * reference to the iclog. |
| 2968 | 3004 | */ |
| 2969 | 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 | 3007 | spin_unlock(&log->l_icloglock); |
| 2972 | 3008 | if (error) |
| 2973 | 3009 | return error; |
| @@ -3131,6 +3167,35 @@ xlog_state_switch_iclogs( · 157 unmodified lines | ||
| 3131 | 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 | 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 | 3231 | struct xlog *log = mp->m_log; |
| 3167 | 3232 | struct xlog_in_core *iclog; |
| 3168 | − xfs_lsn_t lsn; | |
| 3169 | 3233 | |
| 3170 | 3234 | XFS_STATS_INC(mp, xs_log_force); |
| 3171 | 3235 | trace_xfs_log_force(mp, 0, _RET_IP_); |
| @@ -3193,39 +3257,33 @@ xfs_log_force( · 21 unmodified lines | ||
| 3193 | 3257 | iclog = iclog->ic_prev; |
| 3194 | 3258 | } else if (iclog->ic_state == XLOG_STATE_ACTIVE) { |
| 3195 | 3259 | if (atomic_read(&iclog->ic_refcnt) == 0) { |
| 3196 | − /* | |
| 3197 | − * We are the only one with access to this iclog. | |
| 3198 | − * | |
| 3199 | − * Flush it out now. There should be a roundoff of zero | |
| 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)) | |
| 3260 | + /* We have exclusive access to this iclog. */ | |
| 3261 | + bool completed; | |
| 3262 | + | |
| 3263 | + if (xlog_force_and_check_iclog(iclog, &completed)) | |
| 3207 | 3264 | goto out_error; |
| 3208 | 3265 | |
| 3209 | − if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) | |
| 3266 | + if (completed) | |
| 3210 | 3267 | goto out_unlock; |
| 3211 | 3268 | } else { |
| 3212 | 3269 | /* |
| 3213 | − * Someone else is writing to this iclog. | |
| 3214 | − * | |
| 3215 | − * Use its call to flush out the data. However, the | |
| 3216 | − * other thread may not force out this LR, so we mark | |
| 3217 | − * it WANT_SYNC. | |
| 3270 | + * Someone else is still writing to this iclog, so we | |
| 3271 | + * need to ensure that when they release the iclog it | |
| 3272 | + * gets synced immediately as we may be waiting on it. | |
| 3218 | 3273 | */ |
| 3219 | 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 | 3287 | if (flags & XFS_LOG_SYNC) |
| 3230 | 3288 | return xlog_wait_on_iclog(iclog); |
| 3231 | 3289 | out_unlock: |
| @@ -3245,6 +3303,7 @@ xlog_force_lsn( · 13 unmodified lines | ||
| 3245 | 3303 | bool already_slept) |
| 3246 | 3304 | { |
| 3247 | 3305 | struct xlog_in_core *iclog; |
| 3306 | + bool completed; | |
| 3248 | 3307 | |
| 3249 | 3308 | spin_lock(&log->l_icloglock); |
| 3250 | 3309 | iclog = log->l_iclog; |
| @@ -3258,7 +3317,8 @@ xlog_force_lsn( · 7 unmodified lines | ||
| 3258 | 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 | 3323 | * We sleep here if we haven't already slept (e.g. this is the |
| 3264 | 3324 | * first time we've looked at the correct iclog buf) and the |
| @@ -3281,12 +3341,31 @@ xlog_force_lsn( · 16 unmodified lines | ||
| 3281 | 3341 | &log->l_icloglock); |
| 3282 | 3342 | return -EAGAIN; |
| 3283 | 3343 | } |
| 3284 | − atomic_inc(&iclog->ic_refcnt); | |
| 3285 | − xlog_state_switch_iclogs(log, iclog, 0); | |
| 3286 | − if (xlog_state_release_iclog(log, iclog)) | |
| 3344 | + if (xlog_force_and_check_iclog(iclog, &completed)) | |
| 3287 | 3345 | goto out_error; |
| 3288 | 3346 | if (log_flushed) |
| 3289 | 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 | 3371 | if (flags & XFS_LOG_SYNC) |
| @@ -3559,10 +3638,10 @@ xlog_verify_grant_tail( · 266 unmodified lines | ||
| 3559 | 3638 | STATIC void |
| 3560 | 3639 | xlog_verify_tail_lsn( |
| 3561 | 3640 | struct xlog *log, |
| 3562 | − struct xlog_in_core *iclog, | |
| 3563 | − xfs_lsn_t tail_lsn) | |
| 3641 | + struct xlog_in_core *iclog) | |
| 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 | 3646 | if (CYCLE_LSN(tail_lsn) == log->l_prev_cycle) { |
| 3568 | 3647 | blocks = |
| @@ -654,8 +654,9 @@ xlog_cil_push_work( · 653 unmodified lines | ||
| 654 | 654 | struct xfs_trans_header thdr; |
| 655 | 655 | struct xfs_log_iovec lhdr; |
| 656 | 656 | struct xfs_log_vec lvhdr = { NULL }; |
| 657 | + xfs_lsn_t preflush_tail_lsn; | |
| 657 | 658 | xfs_lsn_t commit_lsn; |
| 658 | − xfs_lsn_t push_seq; | |
| 659 | + xfs_csn_t push_seq; | |
| 659 | 660 | struct bio bio; |
| 660 | 661 | DECLARE_COMPLETION_ONSTACK(bdev_flush); |
| 661 | 662 | |
| @@ -730,7 +731,15 @@ xlog_cil_push_work( · 68 unmodified lines | ||
| 730 | 731 | * because we hold the flush lock exclusively. Hence we can now issue |
| 731 | 732 | * a cache flush to ensure all the completed metadata in the journal we |
| 732 | 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 | 743 | xfs_flush_bdev_async(&bio, log->l_mp->m_ddev_targp->bt_bdev, |
| 735 | 744 | &bdev_flush); |
| 736 | 745 | |
| @@ -941,7 +950,7 @@ restart: · 204 unmodified lines | ||
| 941 | 950 | * storage. |
| 942 | 951 | */ |
| 943 | 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 | 954 | spin_unlock(&log->l_icloglock); |
| 946 | 955 | return; |
| 947 | 956 | |
| @@ -59,6 +59,16 @@ enum xlog_iclog_state { · 58 unmodified lines | ||
| 59 | 59 | { XLOG_STATE_DIRTY, "XLOG_STATE_DIRTY" }, \ |
| 60 | 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 | 74 | * Log ticket flags |
| @@ -143,9 +153,6 @@ enum xlog_iclog_state { · 78 unmodified lines | ||
| 143 | 153 | |
| 144 | 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 | 156 | /* Ticket reservation region accounting */ |
| 150 | 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 | 504 | void xfs_log_ticket_ungrant(struct xlog *log, struct xlog_ticket *ticket); |
| 498 | 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 | 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 | 3944 | __field(uint32_t, state) |
| 3945 | 3945 | __field(int32_t, refcount) |
| 3946 | 3946 | __field(uint32_t, offset) |
| 3947 | + __field(uint32_t, flags) | |
| 3947 | 3948 | __field(unsigned long long, lsn) |
| 3948 | 3949 | __field(unsigned long, caller_ip) |
| 3949 | 3950 | ), |
| @@ -3952,15 +3953,17 @@ DECLARE_EVENT_CLASS(xlog_iclog_class, · 2 unmodified lines | ||
| 3952 | 3953 | __entry->state = iclog->ic_state; |
| 3953 | 3954 | __entry->refcount = atomic_read(&iclog->ic_refcnt); |
| 3954 | 3955 | __entry->offset = iclog->ic_offset; |
| 3956 | + __entry->flags = iclog->ic_flags; | |
| 3955 | 3957 | __entry->lsn = be64_to_cpu(iclog->ic_header.h_lsn); |
| 3956 | 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 | 3961 | MAJOR(__entry->dev), MINOR(__entry->dev), |
| 3960 | 3962 | __print_symbolic(__entry->state, XLOG_STATE_STRINGS), |
| 3961 | 3963 | __entry->refcount, |
| 3962 | 3964 | __entry->offset, |
| 3963 | 3965 | __entry->lsn, |
| 3966 | + __print_flags(__entry->flags, "|", XLOG_ICL_STRINGS), | |
| 3964 | 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 | 707 | * @hrv: Hardware Revision of the device, pass -1 to not check _HRV |
| 708 | 708 | * |
| 709 | 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 | 711 | #define for_each_acpi_dev_match(adev, hid, uid, hrv) \ |
| 717 | 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 | 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 | 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 | 68 | unsigned long arg); |
| 69 | 69 | |
| 70 | 70 | #define DRM_IOCTL_NR(n) _IOC_NR(n) |
| 71 | +#define DRM_IOCTL_TYPE(n) _IOC_TYPE(n) | |
| 71 | 72 | #define DRM_MAJOR 226 |
| 72 | 73 | |
| 73 | 74 | /** |
| @@ -57,7 +57,7 @@ struct blk_keyslot_manager; · 56 unmodified lines | ||
| 57 | 57 | * Maximum number of blkcg policies allowed to be registered concurrently. |
| 58 | 58 | * Defined here to simplify include dependency. |
| 59 | 59 | */ |
| 60 | −#define BLKCG_MAX_POLS 5 | |
| 60 | +#define BLKCG_MAX_POLS 6 | |
| 61 | 61 | |
| 62 | 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 | 134 | BPF_LINK_TYPE(BPF_LINK_TYPE_ITER, iter) |
| 135 | 135 | #ifdef CONFIG_NET |
| 136 | 136 | BPF_LINK_TYPE(BPF_LINK_TYPE_NETNS, netns) |
| 137 | +BPF_LINK_TYPE(BPF_LINK_TYPE_XDP, xdp) | |
| 137 | 138 | #endif |
| @@ -340,8 +340,8 @@ struct bpf_insn_aux_data { · 339 unmodified lines | ||
| 340 | 340 | }; |
| 341 | 341 | u64 map_key_state; /* constant (32 bit) key tracking for maps */ |
| 342 | 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 | 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 | 345 | bool zext_dst; /* this insn zero extends dst reg */ |
| 346 | 346 | u8 alu_state; /* used in combination with alu_limit */ |
| 347 | 347 | |
| @@ -414,6 +414,7 @@ struct bpf_verifier_env { · 66 unmodified lines | ||
| 414 | 414 | u32 used_map_cnt; /* number of used maps */ |
| 415 | 415 | u32 used_btf_cnt; /* number of used BTF objects */ |
| 416 | 416 | u32 id_gen; /* used to generate unique reg IDs */ |
| 417 | + bool explore_alu_limits; | |
| 417 | 418 | bool allow_ptr_leaks; |
| 418 | 419 | bool allow_uninit_stack; |
| 419 | 420 | bool allow_ptr_to_map_access; |
| @@ -2,7 +2,11 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef __LINUX_ENTRYKVM_H |
| 3 | 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 | 10 | #include <linux/tick.h> |
| 7 | 11 | |
| 8 | 12 | /* Transfer to guest mode work */ |
| @@ -73,6 +73,11 @@ struct ctl_table_header; · 72 unmodified lines | ||
| 73 | 73 | /* unused opcode to mark call to interpreter with arguments */ |
| 74 | 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 | 81 | /* As per nm, we expose JITed images as text (code) section for |
| 77 | 82 | * kallsyms. That way, tools like perf can find it to match |
| 78 | 83 | * addresses. |
| @@ -390,6 +395,16 @@ static inline bool insn_is_zext(const struct bpf_insn *insn) · 311 unmodified lines | ||
| 390 | 395 | .off = 0, \ |
| 391 | 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 | 408 | /* Internal classic blocks for direct assignment */ |
| 394 | 409 | |
| 395 | 410 | #define __BPF_STMT(CODE, K) \ |
| @@ -141,6 +141,7 @@ extern int vfs_get_tree(struct fs_context *fc); · 140 unmodified lines | ||
| 141 | 141 | extern void put_fs_context(struct fs_context *fc); |
| 142 | 142 | extern int vfs_parse_fs_param_source(struct fs_context *fc, |
| 143 | 143 | struct fs_parameter *param); |
| 144 | +extern void fc_drop_locked(struct fs_context *fc); | |
| 144 | 145 | |
| 145 | 146 | /* |
| 146 | 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 | 319 | VM_BUG_ON(offset + len > PAGE_SIZE); |
| 320 | 320 | memcpy(to + offset, from, len); |
| 321 | + flush_dcache_page(page); | |
| 321 | 322 | kunmap_local(to); |
| 322 | 323 | } |
| 323 | 324 | |
| 324 | 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 | 328 | memset(addr + offset, 0, len); |
| 328 | − kunmap_atomic(addr); | |
| 329 | + flush_dcache_page(page); | |
| 330 | + kunmap_local(addr); | |
| 329 | 331 | } |
| 330 | 332 | |
| 331 | 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 | 82 | /* Get the device * from ishtp device instance */ |
| 83 | 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 | 86 | /* Trace interface for clients */ |
| 85 | 87 | ishtp_print_log ishtp_trace_callback(struct ishtp_cl_device *cl_device); |
| 86 | 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 | 872 | void kvm_release_pfn_dirty(kvm_pfn_t pfn); |
| 873 | 873 | void kvm_set_pfn_dirty(kvm_pfn_t pfn); |
| 874 | 874 | void kvm_set_pfn_accessed(kvm_pfn_t pfn); |
| 875 | −void kvm_get_pfn(kvm_pfn_t pfn); | |
| 876 | 875 | |
| 877 | 876 | void kvm_release_pfn(kvm_pfn_t pfn, bool dirty, struct gfn_to_pfn_cache *cache); |
| 878 | 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 | 210 | #define for_each_mem_range(i, p_start, p_end) \ |
| 211 | 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 | 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 | 221 | #define for_each_mem_range_rev(i, p_start, p_end) \ |
| 222 | 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 | 226 | * for_each_reserved_mem_range - iterate over all reserved memblock areas |
| @@ -200,13 +200,13 @@ enum rt5033_reg { · 199 unmodified lines | ||
| 200 | 200 | #define RT5033_REGULATOR_BUCK_VOLTAGE_MIN 1000000U |
| 201 | 201 | #define RT5033_REGULATOR_BUCK_VOLTAGE_MAX 3000000U |
| 202 | 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 | 205 | /* RT5033 regulator LDO output voltage uV */ |
| 206 | 206 | #define RT5033_REGULATOR_LDO_VOLTAGE_MIN 1200000U |
| 207 | 207 | #define RT5033_REGULATOR_LDO_VOLTAGE_MAX 3000000U |
| 208 | 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 | 211 | /* RT5033 regulator SAFE LDO output voltage uV */ |
| 212 | 212 | #define RT5033_REGULATOR_SAFE_LDO_VOLTAGE 4900000U |
| @@ -632,43 +632,6 @@ static inline int PageTransCompound(struct page *page) · 631 unmodified lines | ||
| 632 | 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 | 636 | * PageTransTail returns true for both transparent huge pages |
| 674 | 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 | 1398 | #endif /* !__PAGETABLE_P4D_FOLDED */ |
| 1399 | 1399 | |
| 1400 | −#ifndef __PAGETABLE_PUD_FOLDED | |
| 1401 | 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 | 1401 | int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot); |
| 1402 | +int pud_clear_huge(pud_t *pud); | |
| 1416 | 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 | 1404 | int p4d_free_pud_page(p4d_t *p4d, unsigned long addr); |
| 1429 | 1405 | int pud_free_pmd_page(pud_t *pud, unsigned long addr); |
| 1430 | 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 | 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 | 319 | static inline void sk_psock_queue_msg(struct sk_psock *psock, |
| 289 | 320 | struct sk_msg *msg) |
| 290 | 321 | { |
| 291 | 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 | 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 | 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 | 443 | static inline struct sk_psock *sk_psock_get(struct sock *sk) |
| 428 | 444 | { |
| 429 | 445 | struct sk_psock *psock; |
| @@ -15,9 +15,11 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/if_ether.h> |
| 16 | 16 | |
| 17 | 17 | /* Lengths of frame formats */ |
| 18 | −#define LLC_PDU_LEN_I 4 /* header and 2 control bytes */ | |
| 19 | −#define LLC_PDU_LEN_S 4 | |
| 20 | −#define LLC_PDU_LEN_U 3 /* header and 1 control byte */ | |
| 18 | +#define LLC_PDU_LEN_I 4 /* header and 2 control bytes */ | |
| 19 | +#define LLC_PDU_LEN_S 4 | |
| 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 | 23 | /* Known SAP addresses */ |
| 22 | 24 | #define LLC_GLOBAL_SAP 0xFF |
| 23 | 25 | #define LLC_NULL_SAP 0x00 /* not network-layer visible */ |
| @@ -50,9 +52,10 @@ · 26 unmodified lines | ||
| 50 | 52 | #define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */ |
| 51 | 53 | #define LLC_PDU_TYPE_MASK 0x03 |
| 52 | 54 | |
| 53 | −#define LLC_PDU_TYPE_I 0 /* first bit */ | |
| 54 | −#define LLC_PDU_TYPE_S 1 /* first two bits */ | |
| 55 | −#define LLC_PDU_TYPE_U 3 /* first two bits */ | |
| 55 | +#define LLC_PDU_TYPE_I 0 /* first bit */ | |
| 56 | +#define LLC_PDU_TYPE_S 1 /* 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 | 60 | #define LLC_PDU_TYPE_IS_I(pdu) \ |
| 58 | 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 | 233 | static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type, |
| 231 | 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 | 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 | 248 | skb_push(skb, hlen); |
| 237 | 249 | skb_reset_network_header(skb); |
| 238 | 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 | 386 | xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */ |
| 375 | 387 | xid_info->type = svcs_supported; |
| 376 | 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 | 984 | } cacc; |
| 985 | 985 | |
| 986 | 986 | struct { |
| 987 | + __u32 last_rtx_chunks; | |
| 987 | 988 | __u16 pmtu; |
| 988 | 989 | __u16 probe_size; |
| 989 | 990 | __u16 probe_high; |
| @@ -1024,8 +1025,8 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu); · 34 unmodified lines | ||
| 1024 | 1025 | void sctp_transport_immediate_rtx(struct sctp_transport *); |
| 1025 | 1026 | void sctp_transport_dst_release(struct sctp_transport *t); |
| 1026 | 1027 | void sctp_transport_dst_confirm(struct sctp_transport *t); |
| 1027 | −void sctp_transport_pl_send(struct sctp_transport *t); | |
| 1028 | −void sctp_transport_pl_recv(struct sctp_transport *t); | |
| 1028 | +bool sctp_transport_pl_send(struct sctp_transport *t); | |
| 1029 | +bool sctp_transport_pl_recv(struct sctp_transport *t); | |
| 1029 | 1030 | |
| 1030 | 1031 | |
| 1031 | 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 | 1709 | struct rcu_head rcu; |
| 1710 | 1710 | }; |
| 1711 | 1711 | |
| 1712 | −extern unsigned int sysctl_tcp_fastopen_blackhole_timeout; | |
| 1713 | 1712 | void tcp_fastopen_active_disable(struct sock *sk); |
| 1714 | 1713 | bool tcp_fastopen_active_should_disable(struct sock *sk); |
| 1715 | 1714 | void tcp_fastopen_active_disable_ofo_check(struct sock *sk); |
| @@ -712,6 +712,12 @@ struct snd_soc_dai_link { · 711 unmodified lines | ||
| 712 | 712 | /* Do not create a PCM for this DAI link (Backend link) */ |
| 713 | 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 | 721 | #ifdef CONFIG_SND_SOC_TOPOLOGY |
| 716 | 722 | struct snd_soc_dobj dobj; /* For topology */ |
| 717 | 723 | #endif |
| @@ -174,6 +174,34 @@ enum afs_vl_operation { · 173 unmodified lines | ||
| 174 | 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 | 205 | enum afs_edit_dir_op { |
| 178 | 206 | afs_edit_dir_create, |
| 179 | 207 | afs_edit_dir_create_error, |
| @@ -436,6 +464,32 @@ enum afs_cb_break_reason { · 256 unmodified lines | ||
| 436 | 464 | EM(afs_YFSVL_GetCellName, "YFSVL.GetCellName") \ |
| 437 | 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 | 493 | #define afs_edit_dir_ops \ |
| 440 | 494 | EM(afs_edit_dir_create, "create") \ |
| 441 | 495 | EM(afs_edit_dir_create_error, "c_fail") \ |
| @@ -569,6 +623,8 @@ afs_server_traces; · 127 unmodified lines | ||
| 569 | 623 | afs_cell_traces; |
| 570 | 624 | afs_fs_operations; |
| 571 | 625 | afs_vl_operations; |
| 626 | +afs_cm_operations; | |
| 627 | +yfs_cm_operations; | |
| 572 | 628 | afs_edit_dir_ops; |
| 573 | 629 | afs_edit_dir_reasons; |
| 574 | 630 | afs_eproto_causes; |
| @@ -649,20 +705,21 @@ TRACE_EVENT(afs_cb_call, · 74 unmodified lines | ||
| 649 | 705 | |
| 650 | 706 | TP_STRUCT__entry( |
| 651 | 707 | __field(unsigned int, call ) |
| 652 | − __field(const char *, name ) | |
| 653 | 708 | __field(u32, op ) |
| 709 | + __field(u16, service_id ) | |
| 654 | 710 | ), |
| 655 | 711 | |
| 656 | 712 | TP_fast_assign( |
| 657 | 713 | __entry->call = call->debug_id; |
| 658 | − __entry->name = call->type->name; | |
| 659 | 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 | 719 | __entry->call, |
| 664 | − __entry->name, | |
| 665 | − __entry->op) | |
| 720 | + __entry->service_id == 2501 ? | |
| 721 | + __print_symbolic(__entry->op, yfs_cm_operations) : | |
| 722 | + __print_symbolic(__entry->op, afs_cm_operations)) | |
| 666 | 723 | ); |
| 667 | 724 | |
| 668 | 725 | TRACE_EVENT(afs_call, |
| @@ -136,7 +136,7 @@ DECLARE_EVENT_CLASS(net_dev_template, · 135 unmodified lines | ||
| 136 | 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 | 140 | __get_str(name), __entry->skbaddr, __entry->len) |
| 141 | 141 | ) |
| 142 | 142 | |
| @@ -41,11 +41,37 @@ TRACE_EVENT(qdisc_dequeue, · 40 unmodified lines | ||
| 41 | 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 | 45 | __entry->ifindex, __entry->handle, __entry->parent, |
| 46 | 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 | 75 | TRACE_EVENT(qdisc_reset, |
| 50 | 76 | |
| 51 | 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 | 2 | /* Copyright(c) 2019 Intel Corporation. All rights rsvd. */ |
| 3 | 3 | #ifndef _USR_IDXD_H_ |
| 4 | 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 | 3 | * Copyright (c) 2006 - 2021 Intel Corporation. All rights reserved. |
| 4 | 4 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | ||
| 32 | 32 | #include <linux/perf_event.h> |
| 33 | 33 | #include <linux/extable.h> |
| 34 | 34 | #include <linux/log2.h> |
| 35 | + | |
| 36 | +#include <asm/barrier.h> | |
| 35 | 37 | #include <asm/unaligned.h> |
| 36 | 38 | |
| 37 | 39 | /* Registers */ |
| @@ -1377,6 +1379,7 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn) · 1339 unmodified lines | ||
| 1377 | 1379 | /* Non-UAPI available opcodes. */ |
| 1378 | 1380 | [BPF_JMP | BPF_CALL_ARGS] = &&JMP_CALL_ARGS, |
| 1379 | 1381 | [BPF_JMP | BPF_TAIL_CALL] = &&JMP_TAIL_CALL, |
| 1382 | + [BPF_ST | BPF_NOSPEC] = &&ST_NOSPEC, | |
| 1380 | 1383 | [BPF_LDX | BPF_PROBE_MEM | BPF_B] = &&LDX_PROBE_MEM_B, |
| 1381 | 1384 | [BPF_LDX | BPF_PROBE_MEM | BPF_H] = &&LDX_PROBE_MEM_H, |
| 1382 | 1385 | [BPF_LDX | BPF_PROBE_MEM | BPF_W] = &&LDX_PROBE_MEM_W, |
| @@ -1621,7 +1624,21 @@ out: · 238 unmodified lines | ||
| 1621 | 1624 | COND_JMP(s, JSGE, >=) |
| 1622 | 1625 | COND_JMP(s, JSLE, <=) |
| 1623 | 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 | 1642 | #define LDST(SIZEOP, SIZE) \ |
| 1626 | 1643 | STX_MEM_##SIZEOP: \ |
| 1627 | 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 | 206 | verbose(cbs->private_data, "BUG_%02x\n", insn->code); |
| 207 | 207 | } |
| 208 | 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 | 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 | 220 | } else if (class == BPF_LDX) { |
| 219 | 221 | if (BPF_MODE(insn->code) != BPF_MEM) { |
| 220 | 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 | 2610 | cur = env->cur_state->frame[env->cur_state->curframe]; |
| 2611 | 2611 | if (value_regno >= 0) |
| 2612 | 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 | 2627 | if (reg && size == BPF_REG_SIZE && register_is_bounded(reg) && |
| 2615 | 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 | 2645 | verbose(env, "invalid size of register spill\n"); |
| 2633 | 2646 | return -EACCES; |
| 2634 | 2647 | } |
| 2635 | − | |
| 2636 | 2648 | if (state != cur && reg->type == PTR_TO_STACK) { |
| 2637 | 2649 | verbose(env, "cannot spill pointers to stack into stack frame of the caller\n"); |
| 2638 | 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 | 2652 | save_register_state(state, spi, reg); |
| 2677 | 2653 | } else { |
| 2678 | 2654 | u8 type = STACK_MISC; |
| @@ -3677,6 +3653,8 @@ continue_func: · 998 unmodified lines | ||
| 3677 | 3653 | if (tail_call_reachable) |
| 3678 | 3654 | for (j = 0; j < frame; j++) |
| 3679 | 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 | 3659 | /* end of for() loop means the last insn of the 'subprog' |
| 3682 | 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 | 6537 | alu_state |= off_is_imm ? BPF_ALU_IMMEDIATE : 0; |
| 6560 | 6538 | alu_state |= ptr_is_dst_reg ? |
| 6561 | 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 | 6548 | err = update_alu_sanitation_state(aux, alu_state, alu_limit); |
| @@ -9934,8 +9918,8 @@ next: · 3369 unmodified lines | ||
| 9934 | 9918 | } |
| 9935 | 9919 | |
| 9936 | 9920 | /* Returns true if (rold safe implies rcur safe) */ |
| 9937 | −static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, | |
| 9938 | − struct bpf_id_pair *idmap) | |
| 9921 | +static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, | |
| 9922 | + struct bpf_reg_state *rcur, struct bpf_id_pair *idmap) | |
| 9939 | 9923 | { |
| 9940 | 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 | 9945 | return false; |
| 9962 | 9946 | switch (rold->type) { |
| 9963 | 9947 | case SCALAR_VALUE: |
| 9948 | + if (env->explore_alu_limits) | |
| 9949 | + return false; | |
| 9964 | 9950 | if (rcur->type == SCALAR_VALUE) { |
| 9965 | 9951 | if (!rold->precise && !rcur->precise) |
| 9966 | 9952 | return true; |
| @@ -10051,9 +10037,8 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, · 84 unmodified lines | ||
| 10051 | 10037 | return false; |
| 10052 | 10038 | } |
| 10053 | 10039 | |
| 10054 | −static bool stacksafe(struct bpf_func_state *old, | |
| 10055 | − struct bpf_func_state *cur, | |
| 10056 | − struct bpf_id_pair *idmap) | |
| 10040 | +static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old, | |
| 10041 | + struct bpf_func_state *cur, struct bpf_id_pair *idmap) | |
| 10057 | 10042 | { |
| 10058 | 10043 | int i, spi; |
| 10059 | 10044 | |
| @@ -10098,9 +10083,8 @@ static bool stacksafe(struct bpf_func_state *old, · 38 unmodified lines | ||
| 10098 | 10083 | continue; |
| 10099 | 10084 | if (old->stack[spi].slot_type[0] != STACK_SPILL) |
| 10100 | 10085 | continue; |
| 10101 | − if (!regsafe(&old->stack[spi].spilled_ptr, | |
| 10102 | − &cur->stack[spi].spilled_ptr, | |
| 10103 | − idmap)) | |
| 10086 | + if (!regsafe(env, &old->stack[spi].spilled_ptr, | |
| 10087 | + &cur->stack[spi].spilled_ptr, idmap)) | |
| 10104 | 10088 | /* when explored and current stack slot are both storing |
| 10105 | 10089 | * spilled registers, check that stored pointers types |
| 10106 | 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 | 10142 | memset(env->idmap_scratch, 0, sizeof(env->idmap_scratch)); |
| 10159 | 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 | 10146 | return false; |
| 10162 | 10147 | |
| 10163 | − if (!stacksafe(old, cur, env->idmap_scratch)) | |
| 10148 | + if (!stacksafe(env, old, cur, env->idmap_scratch)) | |
| 10164 | 10149 | return false; |
| 10165 | 10150 | |
| 10166 | 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 | 11890 | for (i = 0; i < insn_cnt; i++, insn++) { |
| 11906 | 11891 | bpf_convert_ctx_access_t convert_ctx_access; |
| 11892 | + bool ctx_access; | |
| 11907 | 11893 | |
| 11908 | 11894 | if (insn->code == (BPF_LDX | BPF_MEM | BPF_B) || |
| 11909 | 11895 | insn->code == (BPF_LDX | BPF_MEM | BPF_H) || |
| 11910 | 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 | 11898 | type = BPF_READ; |
| 11913 | − else if (insn->code == (BPF_STX | BPF_MEM | BPF_B) || | |
| 11914 | − insn->code == (BPF_STX | BPF_MEM | BPF_H) || | |
| 11915 | − insn->code == (BPF_STX | BPF_MEM | BPF_W) || | |
| 11916 | − insn->code == (BPF_STX | BPF_MEM | BPF_DW)) | |
| 11899 | + ctx_access = true; | |
| 11900 | + } else if (insn->code == (BPF_STX | BPF_MEM | BPF_B) || | |
| 11901 | + insn->code == (BPF_STX | BPF_MEM | BPF_H) || | |
| 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 | 11908 | type = BPF_WRITE; |
| 11918 | − else | |
| 11909 | + ctx_access = BPF_CLASS(insn->code) == BPF_STX; | |
| 11910 | + } else { | |
| 11919 | 11911 | continue; |
| 11912 | + } | |
| 11920 | 11913 | |
| 11921 | 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 | 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 | 11917 | *insn, |
| 11918 | + BPF_ST_NOSPEC(), | |
| 11936 | 11919 | }; |
| 11937 | 11920 | |
| 11938 | 11921 | cnt = ARRAY_SIZE(patch); |
| @@ -11946,6 +11929,9 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) · 7 unmodified lines | ||
| 11946 | 11929 | continue; |
| 11947 | 11930 | } |
| 11948 | 11931 | |
| 11932 | + if (!ctx_access) | |
| 11933 | + continue; | |
| 11934 | + | |
| 11949 | 11935 | switch (env->insn_aux_data[i + delta].ptr_type) { |
| 11950 | 11936 | case PTR_TO_CTX: |
| 11951 | 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 | 12739 | static int do_check_common(struct bpf_verifier_env *env, int subprog) |
| 12785 | 12740 | { |
| 12786 | 12741 | bool pop_log = !(env->log.level & BPF_LOG_LEVEL2); |
| @@ -12857,9 +12812,6 @@ out: · 70 unmodified lines | ||
| 12857 | 12812 | if (!ret && pop_log) |
| 12858 | 12813 | bpf_vlog_reset(&env->log, 0); |
| 12859 | 12814 | free_states(env); |
| 12860 | − if (ret) | |
| 12861 | − /* clean aux data in case subprog was rejected */ | |
| 12862 | − sanitize_insn_aux_data(env); | |
| 12863 | 12815 | return ret; |
| 12864 | 12816 | } |
| 12865 | 12817 | |
| @@ -1221,9 +1221,7 @@ int cgroup1_get_tree(struct fs_context *fc) · 1220 unmodified lines | ||
| 1221 | 1221 | ret = cgroup_do_get_tree(fc); |
| 1222 | 1222 | |
| 1223 | 1223 | if (!ret && percpu_ref_is_dying(&ctx->root->cgrp.self.refcnt)) { |
| 1224 | − struct super_block *sb = fc->root->d_sb; | |
| 1225 | − dput(fc->root); | |
| 1226 | − deactivate_locked_super(sb); | |
| 1224 | + fc_drop_locked(fc); | |
| 1227 | 1225 | ret = 1; |
| 1228 | 1226 | } |
| 1229 | 1227 | |
| @@ -5,6 +5,13 @@ · 4 unmodified lines | ||
| 5 | 5 | */ |
| 6 | 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 | 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 | 19 | void *cpu_addr, dma_addr_t dma_addr, size_t size, |
| 13 | 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 | 23 | int ret; |
| 17 | 24 | |
| 18 | 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 | 39 | unsigned long user_count = vma_pages(vma); |
| 33 | 40 | unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; |
| 34 | 41 | unsigned long off = vma->vm_pgoff; |
| 42 | + struct page *page = dma_common_vaddr_to_page(cpu_addr); | |
| 35 | 43 | int ret = -ENXIO; |
| 36 | 44 | |
| 37 | 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 | 51 | return -ENXIO; |
| 44 | 52 | |
| 45 | 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 | 55 | user_count << PAGE_SHIFT, vma->vm_page_prot); |
| 48 | 56 | #else |
| 49 | 57 | return -ENXIO; |
| @@ -47,7 +47,7 @@ void __init idle_thread_set_boot_cpu(void) · 46 unmodified lines | ||
| 47 | 47 | * |
| 48 | 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 | 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 | 991 | if (!p) |
| 992 | 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 | 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 | 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 | 1010 | * Now re-arm for the new expiry time. |
| 1011 | 1011 | */ |
| @@ -207,6 +207,7 @@ struct timer_base { · 206 unmodified lines | ||
| 207 | 207 | unsigned int cpu; |
| 208 | 208 | bool next_expiry_recalc; |
| 209 | 209 | bool is_idle; |
| 210 | + bool timers_pending; | |
| 210 | 211 | DECLARE_BITMAP(pending_map, WHEEL_SIZE); |
| 211 | 212 | struct hlist_head vectors[WHEEL_SIZE]; |
| 212 | 213 | } ____cacheline_aligned; |
| @@ -595,6 +596,7 @@ static void enqueue_timer(struct timer_base *base, struct timer_list *timer, · 382 unmodified lines | ||
| 595 | 596 | * can reevaluate the wheel: |
| 596 | 597 | */ |
| 597 | 598 | base->next_expiry = bucket_expiry; |
| 599 | + base->timers_pending = true; | |
| 598 | 600 | base->next_expiry_recalc = false; |
| 599 | 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 | 1586 | base->next_expiry_recalc = false; |
| 1587 | + base->timers_pending = !(next == base->clk + NEXT_TIMER_MAX_DELTA); | |
| 1585 | 1588 | |
| 1586 | 1589 | return next; |
| 1587 | 1590 | } |
| @@ -1633,7 +1636,6 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) · 45 unmodified lines | ||
| 1633 | 1636 | struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); |
| 1634 | 1637 | u64 expires = KTIME_MAX; |
| 1635 | 1638 | unsigned long nextevt; |
| 1636 | − bool is_max_delta; | |
| 1637 | 1639 | |
| 1638 | 1640 | /* |
| 1639 | 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 | 1648 | if (base->next_expiry_recalc) |
| 1647 | 1649 | base->next_expiry = __next_timer_interrupt(base); |
| 1648 | 1650 | nextevt = base->next_expiry; |
| 1649 | − is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA); | |
| 1650 | 1651 | |
| 1651 | 1652 | /* |
| 1652 | 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 | 1665 | expires = basem; |
| 1665 | 1666 | base->is_idle = false; |
| 1666 | 1667 | } else { |
| 1667 | − if (!is_max_delta) | |
| 1668 | + if (base->timers_pending) | |
| 1668 | 1669 | expires = basem + (u64)(nextevt - basej) * TICK_NSEC; |
| 1669 | 1670 | /* |
| 1670 | 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 | 1948 | base = per_cpu_ptr(&timer_bases[b], cpu); |
| 1948 | 1949 | base->clk = jiffies; |
| 1949 | 1950 | base->next_expiry = base->clk + NEXT_TIMER_MAX_DELTA; |
| 1951 | + base->timers_pending = false; | |
| 1950 | 1952 | base->is_idle = false; |
| 1951 | 1953 | } |
| 1952 | 1954 | return 0; |
| @@ -5985,7 +5985,8 @@ ftrace_graph_release(struct inode *inode, struct file *file) · 5984 unmodified lines | ||
| 5985 | 5985 | * infrastructure to do the synchronization, thus we must do it |
| 5986 | 5986 | * ourselves. |
| 5987 | 5987 | */ |
| 5988 | − synchronize_rcu_tasks_rude(); | |
| 5988 | + if (old_hash != EMPTY_HASH) | |
| 5989 | + synchronize_rcu_tasks_rude(); | |
| 5989 | 5990 | |
| 5990 | 5991 | free_ftrace_hash(old_hash); |
| 5991 | 5992 | } |
| @@ -7544,7 +7545,7 @@ int ftrace_is_dead(void) · 1552 unmodified lines | ||
| 7544 | 7545 | */ |
| 7545 | 7546 | int register_ftrace_function(struct ftrace_ops *ops) |
| 7546 | 7547 | { |
| 7547 | − int ret = -1; | |
| 7548 | + int ret; | |
| 7548 | 7549 | |
| 7549 | 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 | 3880 | if (unlikely(!head)) |
| 3881 | 3881 | return true; |
| 3882 | 3882 | |
| 3883 | − return reader->read == rb_page_commit(reader) && | |
| 3884 | − (commit == reader || | |
| 3885 | − (commit == head && | |
| 3886 | − head->read == rb_page_commit(commit))); | |
| 3883 | + /* Reader should exhaust content in reader page */ | |
| 3884 | + if (reader->read != rb_page_commit(reader)) | |
| 3885 | + return false; | |
| 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 | 5609 | "\t [:name=histname1]\n" |
| 5610 | 5610 | "\t [:<handler>.<action>]\n" |
| 5611 | 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 | 5616 | "\t When a matching event is hit, an entry is added to a hash\n" |
| 5613 | 5617 | "\t table using the key(s) and value(s) named, and the value of a\n" |
| 5614 | 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 | 1111 | field->flags & HIST_FIELD_FL_ALIAS) |
| 1112 | 1112 | field_name = hist_field_name(field->operands[0], ++level); |
| 1113 | 1113 | else if (field->flags & HIST_FIELD_FL_CPU) |
| 1114 | − field_name = "cpu"; | |
| 1114 | + field_name = "common_cpu"; | |
| 1115 | 1115 | else if (field->flags & HIST_FIELD_FL_EXPR || |
| 1116 | 1116 | field->flags & HIST_FIELD_FL_VAR_REF) { |
| 1117 | 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 | 1991 | hist_data->enable_timestamps = true; |
| 1992 | 1992 | if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS) |
| 1993 | 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 | 1995 | *flags |= HIST_FIELD_FL_CPU; |
| 1996 | 1996 | else { |
| 1997 | 1997 | field = trace_find_event_field(file->event_call, field_name); |
| 1998 | 1998 | if (!field || !field->size) { |
| 1999 | − hist_err(tr, HIST_ERR_FIELD_NOT_FOUND, errpos(field_name)); | |
| 2000 | − field = ERR_PTR(-EINVAL); | |
| 2001 | − goto out; | |
| 1999 | + /* | |
| 2000 | + * For backward compatibility, if field_name | |
| 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 | 2014 | out: |
| @@ -5085,7 +5095,7 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) · 3080 unmodified lines | ||
| 5085 | 5095 | seq_printf(m, "%s=", hist_field->var.name); |
| 5086 | 5096 | |
| 5087 | 5097 | if (hist_field->flags & HIST_FIELD_FL_CPU) |
| 5088 | − seq_puts(m, "cpu"); | |
| 5098 | + seq_puts(m, "common_cpu"); | |
| 5089 | 5099 | else if (field_name) { |
| 5090 | 5100 | if (hist_field->flags & HIST_FIELD_FL_VAR_REF || |
| 5091 | 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 | 893 | dyn_event_init(&event->devent, &synth_event_ops); |
| 894 | 894 | |
| 895 | 895 | for (i = 0, j = 0; i < n_fields; i++) { |
| 896 | + fields[i]->field_pos = i; | |
| 896 | 897 | event->fields[i] = fields[i]; |
| 897 | 898 | |
| 898 | − if (fields[i]->is_dynamic) { | |
| 899 | − event->dynamic_fields[j] = fields[i]; | |
| 900 | − event->dynamic_fields[j]->field_pos = i; | |
| 899 | + if (fields[i]->is_dynamic) | |
| 901 | 900 | event->dynamic_fields[j++] = fields[i]; |
| 902 | − event->n_dynamic_fields++; | |
| 903 | − } | |
| 904 | 901 | } |
| 902 | + event->n_dynamic_fields = j; | |
| 905 | 903 | event->n_fields = n_fields; |
| 906 | 904 | out: |
| 907 | 905 | return event; |
| @@ -14,10 +14,10 @@ struct synth_field { · 13 unmodified lines | ||
| 14 | 14 | char *name; |
| 15 | 15 | size_t size; |
| 16 | 16 | unsigned int offset; |
| 17 | + unsigned int field_pos; | |
| 17 | 18 | bool is_signed; |
| 18 | 19 | bool is_string; |
| 19 | 20 | bool is_dynamic; |
| 20 | − bool field_pos; | |
| 21 | 21 | }; |
| 22 | 22 | |
| 23 | 23 | struct synth_event { |
| @@ -299,8 +299,8 @@ static int tracepoint_add_func(struct tracepoint *tp, · 298 unmodified lines | ||
| 299 | 299 | * a pointer to it. This array is referenced by __DO_TRACE from |
| 300 | 300 | * include/linux/tracepoint.h using rcu_dereference_sched(). |
| 301 | 301 | */ |
| 302 | − rcu_assign_pointer(tp->funcs, tp_funcs); | |
| 303 | 302 | tracepoint_update_call(tp, tp_funcs, false); |
| 303 | + rcu_assign_pointer(tp->funcs, tp_funcs); | |
| 304 | 304 | static_key_enable(&tp->key); |
| 305 | 305 | |
| 306 | 306 | release_probes(old); |
| @@ -3676,15 +3676,21 @@ static void pwq_unbound_release_workfn(struct work_struct *work) · 3675 unmodified lines | ||
| 3676 | 3676 | unbound_release_work); |
| 3677 | 3677 | struct workqueue_struct *wq = pwq->wq; |
| 3678 | 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))) | |
| 3682 | − return; | |
| 3681 | + /* | |
| 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); | |
| 3685 | − list_del_rcu(&pwq->pwqs_node); | |
| 3686 | − is_last = list_empty(&wq->pwqs); | |
| 3687 | − mutex_unlock(&wq->mutex); | |
| 3689 | + mutex_lock(&wq->mutex); | |
| 3690 | + list_del_rcu(&pwq->pwqs_node); | |
| 3691 | + is_last = list_empty(&wq->pwqs); | |
| 3692 | + mutex_unlock(&wq->mutex); | |
| 3693 | + } | |
| 3688 | 3694 | |
| 3689 | 3695 | mutex_lock(&wq_pool_mutex); |
| 3690 | 3696 | put_unbound_pool(pool); |
| @@ -683,9 +683,6 @@ config PARMAN · 682 unmodified lines | ||
| 683 | 683 | config OBJAGG |
| 684 | 684 | tristate "objagg" if COMPILE_TEST |
| 685 | 685 | |
| 686 | −config STRING_SELFTEST | |
| 687 | − tristate "Test string functions" | |
| 688 | − | |
| 689 | 686 | endmenu |
| 690 | 687 | |
| 691 | 688 | config GENERIC_IOREMAP |
| @@ -2180,6 +2180,9 @@ config ASYNC_RAID6_TEST · 2179 unmodified lines | ||
| 2180 | 2180 | config TEST_HEXDUMP |
| 2181 | 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 | 2186 | config TEST_STRING_HELPERS |
| 2184 | 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 | 398 | blkcg_unpin_online(blkcg); |
| 399 | 399 | |
| 400 | 400 | fprop_local_destroy_percpu(&wb->memcg_completions); |
| 401 | − percpu_ref_exit(&wb->refcnt); | |
| 402 | 401 | |
| 403 | 402 | spin_lock_irq(&cgwb_lock); |
| 404 | 403 | list_del(&wb->offline_node); |
| 405 | 404 | spin_unlock_irq(&cgwb_lock); |
| 406 | 405 | |
| 406 | + percpu_ref_exit(&wb->refcnt); | |
| 407 | 407 | wb_exit(wb); |
| 408 | 408 | WARN_ON_ONCE(!list_empty(&wb->b_attached)); |
| 409 | 409 | kfree_rcu(wb, rcu); |
| @@ -733,6 +733,22 @@ void kfence_shutdown_cache(struct kmem_cache *s) · 732 unmodified lines | ||
| 733 | 733 | |
| 734 | 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 | 753 | * allocation_gate only needs to become non-zero, so it doesn't make |
| 738 | 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 | 773 | if (!READ_ONCE(kfence_enabled)) |
| 758 | 774 | return NULL; |
| 759 | 775 | |
| 760 | − if (size > PAGE_SIZE) | |
| 761 | − return NULL; | |
| 762 | − | |
| 763 | 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 | 852 | tracepoint_synchronize_unregister(); |
| 853 | 853 | } |
| 854 | 854 | |
| 855 | −late_initcall(kfence_test_init); | |
| 855 | +late_initcall_sync(kfence_test_init); | |
| 856 | 856 | module_exit(kfence_test_exit); |
| 857 | 857 | |
| 858 | 858 | MODULE_LICENSE("GPL v2"); |
| @@ -947,7 +947,8 @@ static bool should_skip_region(struct memblock_type *type, · 946 unmodified lines | ||
| 947 | 947 | return true; |
| 948 | 948 | |
| 949 | 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 | 952 | return true; |
| 952 | 953 | |
| 953 | 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 | 3574 | unsigned long val; |
| 3575 | 3575 | |
| 3576 | 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 | 3579 | val = memcg_page_state(memcg, NR_FILE_PAGES) + |
| 3579 | 3580 | memcg_page_state(memcg, NR_ANON_MAPPED); |
| 3580 | 3581 | if (swap) |
| @@ -4026,8 +4026,17 @@ vm_fault_t finish_fault(struct vm_fault *vmf) · 4025 unmodified lines | ||
| 4026 | 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 | 4038 | return VM_FAULT_OOM; |
| 4039 | + } | |
| 4031 | 4040 | } |
| 4032 | 4041 | |
| 4033 | 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 | 2068 | LIST_HEAD(migratepages); |
| 2069 | 2069 | new_page_t *new; |
| 2070 | 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 | 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 | 156 | #define TRACE_MMAP_LOCK_EVENT(type, mm, ...) \ |
| 157 | 157 | do { \ |
| 158 | 158 | const char *memcg_path; \ |
| 159 | − preempt_disable(); \ | |
| 159 | + local_lock(&memcg_paths.lock); \ | |
| 160 | 160 | memcg_path = get_mm_memcg_path(mm); \ |
| 161 | 161 | trace_mmap_lock_##type(mm, \ |
| 162 | 162 | memcg_path != NULL ? memcg_path : "", \ |
| 163 | 163 | ##__VA_ARGS__); \ |
| 164 | 164 | if (likely(memcg_path != NULL)) \ |
| 165 | 165 | put_memcg_path_buf(); \ |
| 166 | − preempt_enable(); \ | |
| 166 | + local_unlock(&memcg_paths.lock); \ | |
| 167 | 167 | } while (0) |
| 168 | 168 | |
| 169 | 169 | #else /* !CONFIG_MEMCG */ |
| @@ -840,21 +840,24 @@ void init_mem_debugging_and_hardening(void) · 839 unmodified lines | ||
| 840 | 840 | } |
| 841 | 841 | #endif |
| 842 | 842 | |
| 843 | − if (_init_on_alloc_enabled_early) { | |
| 844 | − if (page_poisoning_requested) | |
| 845 | − pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, " | |
| 846 | − "will take precedence over init_on_alloc\n"); | |
| 847 | − else | |
| 848 | − static_branch_enable(&init_on_alloc); | |
| 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); | |
| 843 | + if ((_init_on_alloc_enabled_early || _init_on_free_enabled_early) && | |
| 844 | + page_poisoning_requested) { | |
| 845 | + pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, " | |
| 846 | + "will take precedence over init_on_alloc and init_on_free\n"); | |
| 847 | + _init_on_alloc_enabled_early = false; | |
| 848 | + _init_on_free_enabled_early = false; | |
| 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 | 861 | #ifdef CONFIG_DEBUG_PAGEALLOC |
| 859 | 862 | if (!debug_pagealloc_enabled()) |
| 860 | 863 | return; |
| @@ -152,6 +152,7 @@ static void secretmem_freepage(struct page *page) · 151 unmodified lines | ||
| 152 | 152 | } |
| 153 | 153 | |
| 154 | 154 | const struct address_space_operations secretmem_aops = { |
| 155 | + .set_page_dirty = __set_page_dirty_no_writeback, | |
| 155 | 156 | .freepage = secretmem_freepage, |
| 156 | 157 | .migratepage = secretmem_migratepage, |
| 157 | 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 | 346 | continue; |
| 347 | 347 | |
| 348 | 348 | page = virt_to_head_page(p[i]); |
| 349 | − objcgs = page_objcgs(page); | |
| 349 | + objcgs = page_objcgs_check(page); | |
| 350 | 350 | if (!objcgs) |
| 351 | 351 | continue; |
| 352 | 352 | |
| @@ -3236,6 +3236,16 @@ struct detached_freelist { · 3235 unmodified lines | ||
| 3236 | 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 | 3250 | * This function progressively scans the array with free objects (with |
| 3241 | 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 | 3282 | if (!s) { |
| 3273 | 3283 | /* Handle kalloc'ed objects */ |
| 3274 | 3284 | if (unlikely(!PageSlab(page))) { |
| 3275 | − BUG_ON(!PageCompound(page)); | |
| 3276 | − kfree_hook(object); | |
| 3277 | − __free_pages(page, compound_order(page)); | |
| 3285 | + free_nonslab_page(page); | |
| 3278 | 3286 | p[size] = NULL; /* mark object processed */ |
| 3279 | 3287 | return size; |
| 3280 | 3288 | } |
| @@ -4250,13 +4258,7 @@ void kfree(const void *x) · 969 unmodified lines | ||
| 4250 | 4258 | |
| 4251 | 4259 | page = virt_to_head_page(x); |
| 4252 | 4260 | if (unlikely(!PageSlab(page))) { |
| 4253 | − unsigned int order = compound_order(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); | |
| 4261 | + free_nonslab_page(page); | |
| 4260 | 4262 | return; |
| 4261 | 4263 | } |
| 4262 | 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 | 701 | void *data; |
| 702 | 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 | 707 | if (kattr->test.ctx_in || kattr->test.ctx_out) |
| 705 | 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 | 780 | struct net_device *dst_dev; |
| 781 | 781 | |
| 782 | 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 | 784 | continue; |
| 785 | 785 | |
| 786 | 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 | 539 | goto err; |
| 540 | 540 | |
| 541 | 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 | 544 | goto err; |
| 544 | 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 | 1076 | static bool j1939_session_deactivate(struct j1939_session *session) |
| 1077 | 1077 | { |
| 1078 | + struct j1939_priv *priv = session->priv; | |
| 1078 | 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 | 1086 | active = j1939_session_deactivate_locked(session); |
| 1082 | − j1939_session_list_unlock(session->priv); | |
| 1087 | + j1939_session_list_unlock(priv); | |
| 1083 | 1088 | |
| 1084 | 1089 | return active; |
| 1085 | 1090 | } |
| @@ -1869,7 +1874,7 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session, · 783 unmodified lines | ||
| 1869 | 1874 | if (!session->transmission) |
| 1870 | 1875 | j1939_tp_schedule_txtimer(session, 0); |
| 1871 | 1876 | } else { |
| 1872 | − j1939_tp_set_rxtimeout(session, 250); | |
| 1877 | + j1939_tp_set_rxtimeout(session, 750); | |
| 1873 | 1878 | } |
| 1874 | 1879 | session->last_cmd = 0xff; |
| 1875 | 1880 | consume_skb(se_skb); |
| @@ -546,10 +546,18 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 545 unmodified lines | ||
| 546 | 546 | return -EFAULT; |
| 547 | 547 | } |
| 548 | 548 | |
| 549 | + rtnl_lock(); | |
| 549 | 550 | lock_sock(sk); |
| 550 | 551 | |
| 551 | − if (ro->bound && ro->ifindex) | |
| 552 | + if (ro->bound && ro->ifindex) { | |
| 552 | 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 | 562 | if (ro->bound) { |
| 555 | 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 | 596 | dev_put(dev); |
| 589 | 597 | |
| 590 | 598 | release_sock(sk); |
| 599 | + rtnl_unlock(); | |
| 591 | 600 | |
| 592 | 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 | 610 | err_mask &= CAN_ERR_MASK; |
| 602 | 611 | |
| 612 | + rtnl_lock(); | |
| 603 | 613 | lock_sock(sk); |
| 604 | 614 | |
| 605 | − if (ro->bound && ro->ifindex) | |
| 615 | + if (ro->bound && ro->ifindex) { | |
| 606 | 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 | 623 | /* remove current error mask */ |
| 609 | 624 | if (ro->bound) { |
| @@ -627,6 +642,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 17 unmodified lines | ||
| 627 | 642 | dev_put(dev); |
| 628 | 643 | |
| 629 | 644 | release_sock(sk); |
| 645 | + rtnl_unlock(); | |
| 630 | 646 | |
| 631 | 647 | break; |
| 632 | 648 | |
| @@ -131,6 +131,7 @@ · 130 unmodified lines | ||
| 131 | 131 | #include <trace/events/napi.h> |
| 132 | 132 | #include <trace/events/net.h> |
| 133 | 133 | #include <trace/events/skb.h> |
| 134 | +#include <trace/events/qdisc.h> | |
| 134 | 135 | #include <linux/inetdevice.h> |
| 135 | 136 | #include <linux/cpu_rmap.h> |
| 136 | 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 | 3860 | static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, |
| 3848 | 3861 | struct net_device *dev, |
| 3849 | 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 | 3875 | * of q->seqlock to protect from racing with requeuing. |
| 3863 | 3876 | */ |
| 3864 | 3877 | if (unlikely(!nolock_qdisc_is_empty(q))) { |
| 3865 | − rc = q->enqueue(skb, q, &to_free) & | |
| 3866 | − NET_XMIT_MASK; | |
| 3878 | + rc = dev_qdisc_enqueue(skb, q, &to_free, txq); | |
| 3867 | 3879 | __qdisc_run(q); |
| 3868 | 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 | 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 | 3895 | qdisc_run(q); |
| 3884 | 3896 | |
| 3885 | 3897 | no_lock_out: |
| @@ -3923,7 +3935,7 @@ no_lock_out: · 37 unmodified lines | ||
| 3923 | 3935 | qdisc_run_end(q); |
| 3924 | 3936 | rc = NET_XMIT_SUCCESS; |
| 3925 | 3937 | } else { |
| 3926 | − rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK; | |
| 3938 | + rc = dev_qdisc_enqueue(skb, q, &to_free, txq); | |
| 3927 | 3939 | if (qdisc_run_begin(q)) { |
| 3928 | 3940 | if (unlikely(contended)) { |
| 3929 | 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 | 9712 | struct net_device *dev; |
| 9701 | 9713 | int err, fd; |
| 9702 | 9714 | |
| 9715 | + rtnl_lock(); | |
| 9703 | 9716 | dev = dev_get_by_index(net, attr->link_create.target_ifindex); |
| 9704 | − if (!dev) | |
| 9717 | + if (!dev) { | |
| 9718 | + rtnl_unlock(); | |
| 9705 | 9719 | return -EINVAL; |
| 9720 | + } | |
| 9706 | 9721 | |
| 9707 | 9722 | link = kzalloc(sizeof(*link), GFP_USER); |
| 9708 | 9723 | if (!link) { |
| 9709 | 9724 | err = -ENOMEM; |
| 9710 | − goto out_put_dev; | |
| 9725 | + goto unlock; | |
| 9711 | 9726 | } |
| 9712 | 9727 | |
| 9713 | 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 | 9732 | err = bpf_link_prime(&link->link, &link_primer); |
| 9718 | 9733 | if (err) { |
| 9719 | 9734 | kfree(link); |
| 9720 | − goto out_put_dev; | |
| 9735 | + goto unlock; | |
| 9721 | 9736 | } |
| 9722 | 9737 | |
| 9723 | − rtnl_lock(); | |
| 9724 | 9738 | err = dev_xdp_attach_link(dev, NULL, link); |
| 9725 | 9739 | rtnl_unlock(); |
| 9726 | 9740 | |
| 9727 | 9741 | if (err) { |
| 9742 | + link->dev = NULL; | |
| 9728 | 9743 | bpf_link_cleanup(&link_primer); |
| 9729 | 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 | 9749 | dev_put(dev); |
| 9735 | 9750 | return fd; |
| 9736 | 9751 | |
| 9752 | +unlock: | |
| 9753 | + rtnl_unlock(); | |
| 9754 | + | |
| 9737 | 9755 | out_put_dev: |
| 9738 | 9756 | dev_put(dev); |
| 9739 | 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 | 9329 | switch (attrs->flavour) { |
| 9330 | 9330 | case DEVLINK_PORT_FLAVOUR_PHYSICAL: |
| 9331 | − case DEVLINK_PORT_FLAVOUR_VIRTUAL: | |
| 9332 | 9331 | n = snprintf(name, len, "p%u", attrs->phys.port_number); |
| 9333 | 9332 | if (n < len && attrs->split) |
| 9334 | 9333 | n += snprintf(name + n, len - n, "s%u", |
| 9335 | 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 | 9335 | break; |
| 9344 | 9336 | case DEVLINK_PORT_FLAVOUR_CPU: |
| 9345 | 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 | 9373 | n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf, |
| 9382 | 9374 | attrs->pci_sf.sf); |
| 9383 | 9375 | break; |
| 9376 | + case DEVLINK_PORT_FLAVOUR_VIRTUAL: | |
| 9377 | + return -EOPNOTSUPP; | |
| 9384 | 9378 | } |
| 9385 | 9379 | |
| 9386 | 9380 | if (n >= len) |
| @@ -1504,7 +1504,7 @@ __be32 flow_get_u32_dst(const struct flow_keys *flow) · 1503 unmodified lines | ||
| 1504 | 1504 | } |
| 1505 | 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 | 1508 | * to have consistent hash within the two directions |
| 1509 | 1509 | */ |
| 1510 | 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 | 1515 | case FLOW_DISSECTOR_KEY_IPV4_ADDRS: |
| 1516 | 1516 | addr_diff = (__force u32)keys->addrs.v4addrs.dst - |
| 1517 | 1517 | (__force u32)keys->addrs.v4addrs.src; |
| 1518 | − if ((addr_diff < 0) || | |
| 1519 | − (addr_diff == 0 && | |
| 1520 | − ((__force u16)keys->ports.dst < | |
| 1521 | − (__force u16)keys->ports.src))) { | |
| 1518 | + if (addr_diff < 0) | |
| 1522 | 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 | 1523 | swap(keys->ports.src, keys->ports.dst); |
| 1524 | 1524 | } |
| 1525 | 1525 | break; |
| @@ -1527,13 +1527,13 @@ static inline void __flow_hash_consistentify(struct flow_keys *keys) · 1 unmodified line | ||
| 1527 | 1527 | addr_diff = memcmp(&keys->addrs.v6addrs.dst, |
| 1528 | 1528 | &keys->addrs.v6addrs.src, |
| 1529 | 1529 | sizeof(keys->addrs.v6addrs.dst)); |
| 1530 | − if ((addr_diff < 0) || | |
| 1531 | − (addr_diff == 0 && | |
| 1532 | − ((__force u16)keys->ports.dst < | |
| 1533 | − (__force u16)keys->ports.src))) { | |
| 1530 | + if (addr_diff < 0) { | |
| 1534 | 1531 | for (i = 0; i < 4; i++) |
| 1535 | 1532 | swap(keys->addrs.v6addrs.src.s6_addr32[i], |
| 1536 | 1533 | keys->addrs.v6addrs.dst.s6_addr32[i]); |
| 1534 | + } | |
| 1535 | + if ((__force u16)keys->ports.dst < | |
| 1536 | + (__force u16)keys->ports.src) { | |
| 1537 | 1537 | swap(keys->ports.src, keys->ports.dst); |
| 1538 | 1538 | } |
| 1539 | 1539 | break; |
| @@ -663,7 +663,7 @@ static void skb_release_data(struct sk_buff *skb) · 662 unmodified lines | ||
| 663 | 663 | if (skb->cloned && |
| 664 | 664 | atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1, |
| 665 | 665 | &shinfo->dataref)) |
| 666 | − return; | |
| 666 | + goto exit; | |
| 667 | 667 | |
| 668 | 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 | 674 | kfree_skb_list(shinfo->frag_list); |
| 675 | 675 | |
| 676 | 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 | 3023 | if (!from->head_frag || |
| 3013 | 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 | 3026 | hlen = skb_headlen(from); |
| 3027 | + if (!hlen) | |
| 3028 | + hlen = from->len; | |
| 3029 | + } | |
| 3016 | 3030 | |
| 3017 | 3031 | if (skb_has_frag_list(from)) |
| 3018 | 3032 | hlen = from->len; |
| @@ -508,10 +508,8 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, · 507 unmodified lines | ||
| 508 | 508 | if (skb_linearize(skb)) |
| 509 | 509 | return -EAGAIN; |
| 510 | 510 | num_sge = skb_to_sgvec(skb, msg->sg.data, 0, skb->len); |
| 511 | − if (unlikely(num_sge < 0)) { | |
| 512 | − kfree(msg); | |
| 511 | + if (unlikely(num_sge < 0)) | |
| 513 | 512 | return num_sge; |
| 514 | − } | |
| 515 | 513 | |
| 516 | 514 | copied = skb->len; |
| 517 | 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 | 529 | struct sock *sk = psock->sk; |
| 532 | 530 | struct sk_msg *msg; |
| 531 | + int err; | |
| 533 | 532 | |
| 534 | 533 | /* If we are receiving on the same sock skb->sk is already assigned, |
| 535 | 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 | 547 | * into user buffers. |
| 549 | 548 | */ |
| 550 | 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 | 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 | 562 | struct sk_msg *msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_ATOMIC); |
| 561 | 563 | struct sock *sk = psock->sk; |
| 564 | + int err; | |
| 562 | 565 | |
| 563 | 566 | if (unlikely(!msg)) |
| 564 | 567 | return -EAGAIN; |
| 565 | 568 | sk_msg_init(msg); |
| 566 | 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 | 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 | 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); | |
| 584 | − kfree_skb(skb); | |
| 592 | + spin_lock_bh(&psock->ingress_lock); | |
| 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 | 603 | static void sk_psock_backlog(struct work_struct *work) |
| 588 | 604 | { |
| 589 | 605 | struct sk_psock *psock = container_of(work, struct sk_psock, work); |
| 590 | 606 | struct sk_psock_work_state *state = &psock->work_state; |
| 591 | − struct sk_buff *skb; | |
| 607 | + struct sk_buff *skb = NULL; | |
| 592 | 608 | bool ingress; |
| 593 | 609 | u32 len, off; |
| 594 | 610 | int ret; |
| 595 | 611 | |
| 596 | 612 | mutex_lock(&psock->work_mutex); |
| 597 | − if (state->skb) { | |
| 613 | + if (unlikely(state->skb)) { | |
| 614 | + spin_lock_bh(&psock->ingress_lock); | |
| 598 | 615 | skb = state->skb; |
| 599 | 616 | len = state->len; |
| 600 | 617 | off = state->off; |
| 601 | 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 | 624 | while ((skb = skb_dequeue(&psock->ingress_skb))) { |
| 606 | 625 | len = skb->len; |
| @@ -615,9 +634,8 @@ start: · 8 unmodified lines | ||
| 615 | 634 | len, ingress); |
| 616 | 635 | if (ret <= 0) { |
| 617 | 636 | if (ret == -EAGAIN) { |
| 618 | − state->skb = skb; | |
| 619 | − state->len = len; | |
| 620 | − state->off = off; | |
| 637 | + sk_psock_skb_state(psock, state, skb, | |
| 638 | + len, off); | |
| 621 | 639 | goto end; |
| 622 | 640 | } |
| 623 | 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 | 734 | skb_bpf_redirect_clear(skb); |
| 717 | 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 | 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 | 791 | void sk_psock_drop(struct sock *sk, struct sk_psock *psock) |
| 769 | 792 | { |
| 770 | − sk_psock_stop(psock, false); | |
| 771 | − | |
| 772 | 793 | write_lock_bh(&sk->sk_callback_lock); |
| 773 | 794 | sk_psock_restore_proto(sk, psock); |
| 774 | 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 | 799 | sk_psock_stop_verdict(sk, psock); |
| 779 | 800 | write_unlock_bh(&sk->sk_callback_lock); |
| 780 | 801 | |
| 802 | + sk_psock_stop(psock, false); | |
| 803 | + | |
| 781 | 804 | INIT_RCU_WORK(&psock->rwork, sk_psock_destroy); |
| 782 | 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 | 816 | static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) |
| 817 | 817 | { |
| 818 | 818 | struct dn_scp *scp = DN_SK(sk); |
| 819 | − DEFINE_WAIT(wait); | |
| 819 | + DEFINE_WAIT_FUNC(wait, woken_wake_function); | |
| 820 | 820 | int err; |
| 821 | 821 | |
| 822 | 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 | 826 | scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk)); |
| 827 | 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 | 830 | for(;;) { |
| 831 | 831 | release_sock(sk); |
| 832 | 832 | if (scp->state == DN_CC) |
| 833 | − *timeo = schedule_timeout(*timeo); | |
| 833 | + *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo); | |
| 834 | 834 | lock_sock(sk); |
| 835 | 835 | err = 0; |
| 836 | 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 | 844 | err = -EAGAIN; |
| 845 | 845 | if (!*timeo) |
| 846 | 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 | 849 | if (err == 0) { |
| 851 | 850 | sk->sk_socket->state = SS_CONNECTED; |
| 852 | 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 | 857 | static int dn_wait_run(struct sock *sk, long *timeo) |
| 859 | 858 | { |
| 860 | 859 | struct dn_scp *scp = DN_SK(sk); |
| 861 | − DEFINE_WAIT(wait); | |
| 860 | + DEFINE_WAIT_FUNC(wait, woken_wake_function); | |
| 862 | 861 | int err = 0; |
| 863 | 862 | |
| 864 | 863 | if (scp->state == DN_RUN) |
| @@ -867,11 +866,11 @@ static int dn_wait_run(struct sock *sk, long *timeo) · 2 unmodified lines | ||
| 867 | 866 | if (!*timeo) |
| 868 | 867 | return -EALREADY; |
| 869 | 868 | |
| 870 | − prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | |
| 869 | + add_wait_queue(sk_sleep(sk), &wait); | |
| 871 | 870 | for(;;) { |
| 872 | 871 | release_sock(sk); |
| 873 | 872 | if (scp->state == DN_CI || scp->state == DN_CC) |
| 874 | − *timeo = schedule_timeout(*timeo); | |
| 873 | + *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo); | |
| 875 | 874 | lock_sock(sk); |
| 876 | 875 | err = 0; |
| 877 | 876 | if (scp->state == DN_RUN) |
| @@ -885,9 +884,8 @@ static int dn_wait_run(struct sock *sk, long *timeo) · 7 unmodified lines | ||
| 885 | 884 | err = -ETIMEDOUT; |
| 886 | 885 | if (!*timeo) |
| 887 | 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 | 889 | out: |
| 892 | 890 | if (err == 0) { |
| 893 | 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 | 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 | 1034 | struct sk_buff *skb = NULL; |
| 1037 | 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 | 1038 | for(;;) { |
| 1041 | 1039 | release_sock(sk); |
| 1042 | 1040 | skb = skb_dequeue(&sk->sk_receive_queue); |
| 1043 | 1041 | if (skb == NULL) { |
| 1044 | − *timeo = schedule_timeout(*timeo); | |
| 1042 | + *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo); | |
| 1045 | 1043 | skb = skb_dequeue(&sk->sk_receive_queue); |
| 1046 | 1044 | } |
| 1047 | 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 | 1054 | err = -EAGAIN; |
| 1057 | 1055 | if (!*timeo) |
| 1058 | 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 | 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 | 1808 | struct dsa_slave_priv *p = netdev_priv(slave); |
| 1809 | 1809 | const struct dsa_port *cpu_dp = dp->cpu_dp; |
| 1810 | 1810 | struct net_device *master = cpu_dp->master; |
| 1811 | + const struct dsa_switch *ds = dp->ds; | |
| 1811 | 1812 | |
| 1812 | 1813 | slave->needed_headroom = cpu_dp->tag_ops->needed_headroom; |
| 1813 | 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 | 1820 | slave->needed_tailroom += master->needed_tailroom; |
| 1820 | 1821 | |
| 1821 | 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 | 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 | 1890 | if (slave_dev == NULL) |
| 1882 | 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 | 1893 | slave_dev->ethtool_ops = &dsa_slave_ethtool_ops; |
| 1890 | 1894 | if (!is_zero_ether_addr(port->mac)) |
| 1891 | 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 | 53 | u8 *tag; |
| 54 | 54 | u8 *addr; |
| 55 | 55 | |
| 56 | + if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) | |
| 57 | + return NULL; | |
| 58 | + | |
| 56 | 59 | /* Tag encoding */ |
| 57 | 60 | tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); |
| 58 | 61 | addr = skb_mac_header(skb); |
| @@ -114,6 +117,9 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, · 55 unmodified lines | ||
| 114 | 117 | u8 *addr; |
| 115 | 118 | u16 val; |
| 116 | 119 | |
| 120 | + if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) | |
| 121 | + return NULL; | |
| 122 | + | |
| 117 | 123 | /* Tag encoding */ |
| 118 | 124 | tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN); |
| 119 | 125 | addr = skb_mac_header(skb); |
| @@ -164,6 +170,9 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb, · 44 unmodified lines | ||
| 164 | 170 | u8 *addr; |
| 165 | 171 | u8 *tag; |
| 166 | 172 | |
| 173 | + if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) | |
| 174 | + return NULL; | |
| 175 | + | |
| 167 | 176 | /* Tag encoding */ |
| 168 | 177 | tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); |
| 169 | 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 | 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 | 395 | err = IP_ECN_decapsulate(iph, skb); |
| 396 | 396 | if (unlikely(err)) { |
| @@ -503,7 +503,7 @@ static int __init tcp_bpf_v4_build_proto(void) · 502 unmodified lines | ||
| 503 | 503 | tcp_bpf_rebuild_protos(tcp_bpf_prots[TCP_BPF_IPV4], &tcp_prot); |
| 504 | 504 | return 0; |
| 505 | 505 | } |
| 506 | −core_initcall(tcp_bpf_v4_build_proto); | |
| 506 | +late_initcall(tcp_bpf_v4_build_proto); | |
| 507 | 507 | |
| 508 | 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 | 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 | 520 | atomic_inc(&net->ipv4.tfo_active_disable_times); |
| 511 | − net->ipv4.tfo_active_disable_stamp = jiffies; | |
| 521 | + | |
| 512 | 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 | 529 | bool tcp_fastopen_active_should_disable(struct sock *sk) |
| 520 | 530 | { |
| 521 | 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 | 532 | unsigned long timeout; |
| 533 | + int tfo_da_times; | |
| 524 | 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 | 540 | if (!tfo_da_times) |
| 527 | 541 | return false; |
| 528 | 542 | |
| 543 | + /* Paired with smp_mb__before_atomic() in tcp_fastopen_active_disable() */ | |
| 544 | + smp_rmb(); | |
| 545 | + | |
| 529 | 546 | /* Limit timeout to max: 2^6 * initial timeout */ |
| 530 | 547 | multiplier = 1 << min(tfo_da_times - 1, 6); |
| 531 | − timeout = multiplier * tfo_bh_timeout * HZ; | |
| 532 | − if (time_before(jiffies, sock_net(sk)->ipv4.tfo_active_disable_stamp + timeout)) | |
| 548 | + | |
| 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 | 553 | return true; |
| 534 | 554 | |
| 535 | 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 | 2965 | net->ipv4.sysctl_tcp_comp_sack_nr = 44; |
| 2966 | 2966 | net->ipv4.sysctl_tcp_fastopen = TFO_CLIENT_ENABLE; |
| 2967 | 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 | 2969 | atomic_set(&net->ipv4.tfo_active_disable_times, 0); |
| 2970 | 2970 | |
| 2971 | 2971 | /* Reno is always built in */ |
| @@ -645,10 +645,12 @@ static struct sock *__udp4_lib_err_encap(struct net *net, · 644 unmodified lines | ||
| 645 | 645 | const struct iphdr *iph, |
| 646 | 646 | struct udphdr *uh, |
| 647 | 647 | struct udp_table *udptable, |
| 648 | + struct sock *sk, | |
| 648 | 649 | struct sk_buff *skb, u32 info) |
| 649 | 650 | { |
| 651 | + int (*lookup)(struct sock *sk, struct sk_buff *skb); | |
| 650 | 652 | int network_offset, transport_offset; |
| 651 | − struct sock *sk; | |
| 653 | + struct udp_sock *up; | |
| 652 | 654 | |
| 653 | 655 | network_offset = skb_network_offset(skb); |
| 654 | 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 | 661 | /* Transport header needs to point to the UDP header */ |
| 660 | 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 | 674 | sk = __udp4_lib_lookup(net, iph->daddr, uh->source, |
| 663 | 675 | iph->saddr, uh->dest, skb->dev->ifindex, 0, |
| 664 | 676 | udptable, NULL); |
| 665 | 677 | if (sk) { |
| 666 | − int (*lookup)(struct sock *sk, struct sk_buff *skb); | |
| 667 | − struct udp_sock *up = udp_sk(sk); | |
| 678 | + up = udp_sk(sk); | |
| 668 | 679 | |
| 669 | 680 | lookup = READ_ONCE(up->encap_err_lookup); |
| 670 | 681 | if (!lookup || lookup(sk, skb)) |
| 671 | 682 | sk = NULL; |
| 672 | 683 | } |
| 673 | 684 | |
| 685 | +out: | |
| 674 | 686 | if (!sk) |
| 675 | 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 | 719 | sk = __udp4_lib_lookup(net, iph->daddr, uh->dest, |
| 708 | 720 | iph->saddr, uh->source, skb->dev->ifindex, |
| 709 | 721 | inet_sdif(skb), udptable, NULL); |
| 722 | + | |
| 710 | 723 | if (!sk || udp_sk(sk)->encap_type) { |
| 711 | 724 | /* No socket for error: try tunnels before discarding */ |
| 712 | − sk = ERR_PTR(-ENOENT); | |
| 713 | 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 | 727 | info); |
| 716 | 728 | if (!sk) |
| 717 | 729 | return 0; |
| 718 | − } | |
| 730 | + } else | |
| 731 | + sk = ERR_PTR(-ENOENT); | |
| 719 | 732 | |
| 720 | 733 | if (IS_ERR(sk)) { |
| 721 | 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 | 134 | udp_bpf_rebuild_protos(&udp_bpf_prots[UDP_BPF_IPV4], &udp_prot); |
| 135 | 135 | return 0; |
| 136 | 136 | } |
| 137 | −core_initcall(udp_bpf_v4_build_proto); | |
| 137 | +late_initcall(udp_bpf_v4_build_proto); | |
| 138 | 138 | |
| 139 | 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 | 75 | if (likely(nskb)) { |
| 76 | 76 | if (skb->sk) |
| 77 | − skb_set_owner_w(skb, skb->sk); | |
| 77 | + skb_set_owner_w(nskb, skb->sk); | |
| 78 | 78 | consume_skb(skb); |
| 79 | 79 | } else { |
| 80 | 80 | kfree_skb(skb); |
| @@ -549,9 +549,10 @@ int ip6_forward(struct sk_buff *skb) · 468 unmodified lines | ||
| 549 | 549 | if (net->ipv6.devconf_all->proxy_ndp && |
| 550 | 550 | pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) { |
| 551 | 551 | int proxied = ip6_forward_proxy_check(skb); |
| 552 | − if (proxied > 0) | |
| 552 | + if (proxied > 0) { | |
| 553 | + hdr->hop_limit--; | |
| 553 | 554 | return ip6_input(skb); |
| 554 | − else if (proxied < 0) { | |
| 555 | + } else if (proxied < 0) { | |
| 555 | 556 | __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS); |
| 556 | 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 | 3769 | err = PTR_ERR(rt->fib6_metrics); |
| 3770 | 3770 | /* Do not leave garbage there. */ |
| 3771 | 3771 | rt->fib6_metrics = (struct dst_metrics *)&dst_default_metrics; |
| 3772 | − goto out; | |
| 3772 | + goto out_free; | |
| 3773 | 3773 | } |
| 3774 | 3774 | |
| 3775 | 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 | 502 | const struct ipv6hdr *hdr, int offset, |
| 503 | 503 | struct udphdr *uh, |
| 504 | 504 | struct udp_table *udptable, |
| 505 | + struct sock *sk, | |
| 505 | 506 | struct sk_buff *skb, |
| 506 | 507 | struct inet6_skb_parm *opt, |
| 507 | 508 | u8 type, u8 code, __be32 info) |
| 508 | 509 | { |
| 510 | + int (*lookup)(struct sock *sk, struct sk_buff *skb); | |
| 509 | 511 | int network_offset, transport_offset; |
| 510 | − struct sock *sk; | |
| 512 | + struct udp_sock *up; | |
| 511 | 513 | |
| 512 | 514 | network_offset = skb_network_offset(skb); |
| 513 | 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 | 520 | /* Transport header needs to point to the UDP header */ |
| 519 | 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 | 533 | sk = __udp6_lib_lookup(net, &hdr->daddr, uh->source, |
| 522 | 534 | &hdr->saddr, uh->dest, |
| 523 | 535 | inet6_iif(skb), 0, udptable, skb); |
| 524 | 536 | if (sk) { |
| 525 | − int (*lookup)(struct sock *sk, struct sk_buff *skb); | |
| 526 | − struct udp_sock *up = udp_sk(sk); | |
| 537 | + up = udp_sk(sk); | |
| 527 | 538 | |
| 528 | 539 | lookup = READ_ONCE(up->encap_err_lookup); |
| 529 | 540 | if (!lookup || lookup(sk, skb)) |
| 530 | 541 | sk = NULL; |
| 531 | 542 | } |
| 532 | 543 | |
| 544 | +out: | |
| 533 | 545 | if (!sk) { |
| 534 | 546 | sk = ERR_PTR(__udp6_lib_err_encap_no_sk(skb, opt, type, code, |
| 535 | 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 | 571 | sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, |
| 560 | 572 | inet6_iif(skb), inet6_sdif(skb), udptable, NULL); |
| 573 | + | |
| 561 | 574 | if (!sk || udp_sk(sk)->encap_type) { |
| 562 | 575 | /* No socket for error: try tunnels before discarding */ |
| 563 | − sk = ERR_PTR(-ENOENT); | |
| 564 | 576 | if (static_branch_unlikely(&udpv6_encap_needed_key)) { |
| 565 | 577 | sk = __udp6_lib_err_encap(net, hdr, offset, uh, |
| 566 | − udptable, skb, | |
| 578 | + udptable, sk, skb, | |
| 567 | 579 | opt, type, code, info); |
| 568 | 580 | if (!sk) |
| 569 | 581 | return 0; |
| 570 | − } | |
| 582 | + } else | |
| 583 | + sk = ERR_PTR(-ENOENT); | |
| 571 | 584 | |
| 572 | 585 | if (IS_ERR(sk)) { |
| 573 | 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 | 99 | u8 rc = LLC_PDU_LEN_U; |
| 100 | 100 | |
| 101 | − if (addr->sllc_test || addr->sllc_xid) | |
| 101 | + if (addr->sllc_test) | |
| 102 | 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 | 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.