Merge series from Biju Das <biju.das.jz@bp.renesas.com>: As per RZ/G2L HW manual, VBUS enable can be controlled by the VBOUT bit of the VBUS Control Register(VBENCTL) register in the USBPHY Control. But this IP is in the Reset block. Reset driver exposes this register as regmap and instantiate the USB VBUS regulator device. Consumers(phy device) can use regulator APIs to control VBUS as controlling is done in the atomic context using a new API which is added for the purpose.
Unified · Split
| @@ -608,6 +608,7 @@ Simon Kelley <simon@thekelleys.org.uk> · 607 unmodified lines | ||
| 608 | 608 | Sricharan Ramabadhran <quic_srichara@quicinc.com> <sricharan@codeaurora.org> |
| 609 | 609 | Srinivas Ramana <quic_sramana@quicinc.com> <sramana@codeaurora.org> |
| 610 | 610 | Sriram R <quic_srirrama@quicinc.com> <srirrama@codeaurora.org> |
| 611 | +Stanislav Fomichev <sdf@fomichev.me> <sdf@google.com> | |
| 611 | 612 | Stefan Wahren <wahrenst@gmx.net> <stefan.wahren@i2se.com> |
| 612 | 613 | Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr> |
| 613 | 614 | Stephen Hemminger <stephen@networkplumber.org> <shemminger@linux-foundation.org> |
| @@ -2192,12 +2192,6 @@ · 2191 unmodified lines | ||
| 2192 | 2192 | Format: 0 | 1 |
| 2193 | 2193 | Default set by CONFIG_INIT_ON_FREE_DEFAULT_ON. |
| 2194 | 2194 | |
| 2195 | − init_mlocked_on_free= [MM] Fill freed userspace memory with zeroes if | |
| 2196 | − it was mlock'ed and not explicitly munlock'ed | |
| 2197 | − afterwards. | |
| 2198 | − Format: 0 | 1 | |
| 2199 | − Default set by CONFIG_INIT_MLOCKED_ON_FREE_DEFAULT_ON | |
| 2200 | − | |
| 2201 | 2195 | init_pkru= [X86] Specify the default memory protection keys rights |
| 2202 | 2196 | register contents for all processes. 0x55555554 by |
| 2203 | 2197 | default (disallow access to all but pkey 0). Can |
| @@ -59,8 +59,8 @@ properties: · 58 unmodified lines | ||
| 59 | 59 | - 3 |
| 60 | 60 | |
| 61 | 61 | dma-channels: |
| 62 | − minItems: 1 | |
| 63 | − maxItems: 64 | |
| 62 | + minimum: 1 | |
| 63 | + maximum: 64 | |
| 64 | 64 | |
| 65 | 65 | clocks: |
| 66 | 66 | minItems: 1 |
| @@ -77,7 +77,7 @@ required: · 76 unmodified lines | ||
| 77 | 77 | - clocks |
| 78 | 78 | |
| 79 | 79 | allOf: |
| 80 | − - $ref: i2c-controller.yaml | |
| 80 | + - $ref: /schemas/i2c/i2c-controller.yaml# | |
| 81 | 81 | - if: |
| 82 | 82 | properties: |
| 83 | 83 | compatible: |
| @@ -21,7 +21,7 @@ description: | · 20 unmodified lines | ||
| 21 | 21 | google,cros-ec-spi or google,cros-ec-i2c. |
| 22 | 22 | |
| 23 | 23 | allOf: |
| 24 | − - $ref: i2c-controller.yaml# | |
| 24 | + - $ref: /schemas/i2c/i2c-controller.yaml# | |
| 25 | 25 | |
| 26 | 26 | properties: |
| 27 | 27 | compatible: |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| 2 | 2 | <!-- Created with Inkscape (http://www.inkscape.org/) --> |
| 3 | +<!-- Updated to inclusive terminology by Wolfram Sang --> | |
| 3 | 4 | |
| 4 | 5 | <svg |
| 5 | 6 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
| @@ -1120,7 +1121,7 @@ · 1114 unmodified lines | ||
| 1120 | 1121 | <rect |
| 1121 | 1122 | style="opacity:1;fill:#ffb9b9;fill-opacity:1;stroke:#f00000;stroke-width:2.8125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" |
| 1122 | 1123 | id="rect4424-3-2-9-7" |
| 1123 | − width="112.5" | |
| 1124 | + width="134.5" | |
| 1124 | 1125 | height="113.75008" |
| 1125 | 1126 | x="112.5" |
| 1126 | 1127 | y="471.11221" |
| @@ -1133,15 +1134,15 @@ · 6 unmodified lines | ||
| 1133 | 1134 | y="521.46259" |
| 1134 | 1135 | id="text4349"><tspan |
| 1135 | 1136 | sodipodi:role="line" |
| 1136 | − x="167.5354" | |
| 1137 | + x="178.5354" | |
| 1137 | 1138 | y="521.46259" |
| 1138 | 1139 | style="font-size:25px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle" |
| 1139 | 1140 | id="tspan1273">I2C</tspan><tspan |
| 1140 | 1141 | sodipodi:role="line" |
| 1141 | − x="167.5354" | |
| 1142 | + x="178.5354" | |
| 1142 | 1143 | y="552.71259" |
| 1143 | 1144 | style="font-size:25px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle" |
| 1144 | − id="tspan1285">Master</tspan></text> | |
| 1145 | + id="tspan1285">Controller</tspan></text> | |
| 1145 | 1146 | <rect |
| 1146 | 1147 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#b9ffb9;fill-opacity:1;fill-rule:nonzero;stroke:#006400;stroke-width:2.8125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" |
| 1147 | 1148 | id="rect4424-3-2-9-7-3-3-5-3" |
| @@ -1171,7 +1172,7 @@ · 23 unmodified lines | ||
| 1171 | 1172 | x="318.59131" |
| 1172 | 1173 | y="552.08752" |
| 1173 | 1174 | style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px" |
| 1174 | − id="tspan1287">Slave</tspan></text> | |
| 1175 | + id="tspan1287">Target</tspan></text> | |
| 1175 | 1176 | <path |
| 1176 | 1177 | style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968767;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" |
| 1177 | 1178 | d="m 112.49995,677.36223 c 712.50005,0 712.50005,0 712.50005,0" |
| @@ -1233,7 +1234,7 @@ · 55 unmodified lines | ||
| 1233 | 1234 | x="468.59131" |
| 1234 | 1235 | y="552.08746" |
| 1235 | 1236 | style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px" |
| 1236 | − id="tspan1287-6">Slave</tspan></text> | |
| 1237 | + id="tspan1287-6">Target</tspan></text> | |
| 1237 | 1238 | <rect |
| 1238 | 1239 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#b9ffb9;fill-opacity:1;fill-rule:nonzero;stroke:#006400;stroke-width:2.8125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" |
| 1239 | 1240 | id="rect4424-3-2-9-7-3-3-5-3-1" |
| @@ -1258,7 +1259,7 @@ · 18 unmodified lines | ||
| 1258 | 1259 | x="618.59131" |
| 1259 | 1260 | y="552.08746" |
| 1260 | 1261 | style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px" |
| 1261 | − id="tspan1287-9">Slave</tspan></text> | |
| 1262 | + id="tspan1287-9">Target</tspan></text> | |
| 1262 | 1263 | <path |
| 1263 | 1264 | style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#DotM)" |
| 1264 | 1265 | d="m 150,583.61221 v 93.75" |
| @@ -3,29 +3,27 @@ Introduction to I2C and SMBus · 2 unmodified lines | ||
| 3 | 3 | ============================= |
| 4 | 4 | |
| 5 | 5 | I²C (pronounce: I squared C and written I2C in the kernel documentation) is |
| 6 | −a protocol developed by Philips. It is a slow two-wire protocol (variable | |
| 7 | −speed, up to 400 kHz), with a high speed extension (3.4 MHz). It provides | |
| 6 | +a protocol developed by Philips. It is a two-wire protocol with variable | |
| 7 | +speed (typically up to 400 kHz, high speed modes up to 5 MHz). It provides | |
| 8 | 8 | an inexpensive bus for connecting many types of devices with infrequent or |
| 9 | −low bandwidth communications needs. I2C is widely used with embedded | |
| 10 | −systems. Some systems use variants that don't meet branding requirements, | |
| 9 | +low bandwidth communications needs. I2C is widely used with embedded | |
| 10 | +systems. Some systems use variants that don't meet branding requirements, | |
| 11 | 11 | and so are not advertised as being I2C but come under different names, |
| 12 | 12 | e.g. TWI (Two Wire Interface), IIC. |
| 13 | 13 | |
| 14 | −The latest official I2C specification is the `"I2C-bus specification and user | |
| 15 | −manual" (UM10204) <https://www.nxp.com/webapp/Download?colCode=UM10204>`_ | |
| 16 | −published by NXP Semiconductors. However, you need to log-in to the site to | |
| 17 | −access the PDF. An older version of the specification (revision 6) is archived | |
| 18 | −`here <https://web.archive.org/web/20210813122132/https://www.nxp.com/docs/en/user-guide/UM10204.pdf>`_. | |
| 14 | +The latest official I2C specification is the `"I²C-bus specification and user | |
| 15 | +manual" (UM10204) <https://www.nxp.com/docs/en/user-guide/UM10204.pdf>`_ | |
| 16 | +published by NXP Semiconductors, version 7 as of this writing. | |
| 19 | 17 | |
| 20 | 18 | SMBus (System Management Bus) is based on the I2C protocol, and is mostly |
| 21 | −a subset of I2C protocols and signaling. Many I2C devices will work on an | |
| 19 | +a subset of I2C protocols and signaling. Many I2C devices will work on an | |
| 22 | 20 | SMBus, but some SMBus protocols add semantics beyond what is required to |
| 23 | −achieve I2C branding. Modern PC mainboards rely on SMBus. The most common | |
| 21 | +achieve I2C branding. Modern PC mainboards rely on SMBus. The most common | |
| 24 | 22 | devices connected through SMBus are RAM modules configured using I2C EEPROMs, |
| 25 | 23 | and hardware monitoring chips. |
| 26 | 24 | |
| 27 | 25 | Because the SMBus is mostly a subset of the generalized I2C bus, we can |
| 28 | −use its protocols on many I2C systems. However, there are systems that don't | |
| 26 | +use its protocols on many I2C systems. However, there are systems that don't | |
| 29 | 27 | meet both SMBus and I2C electrical constraints; and others which can't |
| 30 | 28 | implement all the common SMBus protocol semantics or messages. |
| 31 | 29 | |
| @@ -33,29 +31,52 @@ implement all the common SMBus protocol semantics or messages. · 1 unmodified line | ||
| 33 | 31 | Terminology |
| 34 | 32 | =========== |
| 35 | 33 | |
| 36 | −Using the terminology from the official documentation, the I2C bus connects | |
| 37 | −one or more *master* chips and one or more *slave* chips. | |
| 34 | +The I2C bus connects one or more controller chips and one or more target chips. | |
| 38 | 35 | |
| 39 | 36 | .. kernel-figure:: i2c_bus.svg |
| 40 | − :alt: Simple I2C bus with one master and 3 slaves | |
| 37 | + :alt: Simple I2C bus with one controller and 3 targets | |
| 41 | 38 | |
| 42 | 39 | Simple I2C bus |
| 43 | 40 | |
| 44 | −A **master** chip is a node that starts communications with slaves. In the | |
| 45 | −Linux kernel implementation it is called an **adapter** or bus. Adapter | |
| 46 | −drivers are in the ``drivers/i2c/busses/`` subdirectory. | |
| 41 | +A **controller** chip is a node that starts communications with targets. In the | |
| 42 | +Linux kernel implementation it is also called an "adapter" or "bus". Controller | |
| 43 | +drivers are usually in the ``drivers/i2c/busses/`` subdirectory. | |
| 47 | 44 | |
| 48 | −An **algorithm** contains general code that can be used to implement a | |
| 49 | −whole class of I2C adapters. Each specific adapter driver either depends on | |
| 50 | −an algorithm driver in the ``drivers/i2c/algos/`` subdirectory, or includes | |
| 51 | −its own implementation. | |
| 45 | +An **algorithm** contains general code that can be used to implement a whole | |
| 46 | +class of I2C controllers. Each specific controller driver either depends on an | |
| 47 | +algorithm driver in the ``drivers/i2c/algos/`` subdirectory, or includes its | |
| 48 | +own implementation. | |
| 52 | 49 | |
| 53 | −A **slave** chip is a node that responds to communications when addressed | |
| 54 | −by the master. In Linux it is called a **client**. Client drivers are kept | |
| 55 | −in a directory specific to the feature they provide, for example | |
| 56 | −``drivers/media/gpio/`` for GPIO expanders and ``drivers/media/i2c/`` for | |
| 50 | +A **target** chip is a node that responds to communications when addressed by a | |
| 51 | +controller. In the Linux kernel implementation it is also called a "client". | |
| 52 | +While targets are usually separate external chips, Linux can also act as a | |
| 53 | +target (needs hardware support) and respond to another controller on the bus. | |
| 54 | +This is then called a **local target**. In contrast, an external chip is called | |
| 55 | +a **remote target**. | |
| 56 | + | |
| 57 | +Target drivers are kept in a directory specific to the feature they provide, | |
| 58 | +for example ``drivers/gpio/`` for GPIO expanders and ``drivers/media/i2c/`` for | |
| 57 | 59 | video-related chips. |
| 58 | 60 | |
| 59 | −For the example configuration in figure, you will need a driver for your | |
| 60 | −I2C adapter, and drivers for your I2C devices (usually one driver for each | |
| 61 | −device). | |
| 61 | +For the example configuration in the figure above, you will need one driver for | |
| 62 | +the I2C controller, and drivers for your I2C targets. Usually one driver for | |
| 63 | +each target. | |
| 64 | + | |
| 65 | +Synonyms | |
| 66 | +-------- | |
| 67 | + | |
| 68 | +As mentioned above, the Linux I2C implementation historically uses the terms | |
| 69 | +"adapter" for controller and "client" for target. A number of data structures | |
| 70 | +have these synonyms in their name. So, when discussing implementation details, | |
| 71 | +you should be aware of these terms as well. The official wording is preferred, | |
| 72 | +though. | |
| 73 | + | |
| 74 | +Outdated terminology | |
| 75 | +-------------------- | |
| 76 | + | |
| 77 | +In earlier I2C specifications, controller was named "master" and target was | |
| 78 | +named "slave". These terms have been obsoleted with v7 of the specification and | |
| 79 | +their use is also discouraged by the Linux Kernel Code of Conduct. You may | |
| 80 | +still find them in references to documentation which has not been updated. The | |
| 81 | +general attitude, however, is to use the inclusive terms: controller and | |
| 82 | +target. Work to replace the old terminology in the Linux Kernel is on-going. | |
| @@ -123,8 +123,6 @@ operations: · 122 unmodified lines | ||
| 123 | 123 | doc: dump pending nfsd rpc |
| 124 | 124 | attribute-set: rpc-status |
| 125 | 125 | dump: |
| 126 | − pre: nfsd-nl-rpc-status-get-start | |
| 127 | − post: nfsd-nl-rpc-status-get-done | |
| 128 | 126 | reply: |
| 129 | 127 | attributes: |
| 130 | 128 | - xid |
| @@ -227,3 +227,9 @@ directly written to the voltage selector register, use:: · 226 unmodified lines | ||
| 227 | 227 | |
| 228 | 228 | int regulator_list_hardware_vsel(struct regulator *regulator, |
| 229 | 229 | unsigned selector); |
| 230 | + | |
| 231 | +To access the hardware for enabling/disabling the regulator, consumers must | |
| 232 | +use regulator_get_exclusive(), as it can't work if there's more than one | |
| 233 | +consumer. To enable/disable regulator use:: | |
| 234 | + | |
| 235 | + int regulator_hardware_enable(struct regulator *regulator, bool enable); | |
| @@ -32,6 +32,7 @@ Security-related interfaces · 31 unmodified lines | ||
| 32 | 32 | seccomp_filter |
| 33 | 33 | landlock |
| 34 | 34 | lsm |
| 35 | + mfd_noexec | |
| 35 | 36 | spec_ctrl |
| 36 | 37 | tee |
| 37 | 38 | |
| @@ -0,0 +1,86 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +================================== | |
| 4 | +Introduction of non-executable mfd | |
| 5 | +================================== | |
| 6 | +:Author: | |
| 7 | + Daniel Verkamp <dverkamp@chromium.org> | |
| 8 | + Jeff Xu <jeffxu@chromium.org> | |
| 9 | + | |
| 10 | +:Contributor: | |
| 11 | + Aleksa Sarai <cyphar@cyphar.com> | |
| 12 | + | |
| 13 | +Since Linux introduced the memfd feature, memfds have always had their | |
| 14 | +execute bit set, and the memfd_create() syscall doesn't allow setting | |
| 15 | +it differently. | |
| 16 | + | |
| 17 | +However, in a secure-by-default system, such as ChromeOS, (where all | |
| 18 | +executables should come from the rootfs, which is protected by verified | |
| 19 | +boot), this executable nature of memfd opens a door for NoExec bypass | |
| 20 | +and enables “confused deputy attack”. E.g, in VRP bug [1]: cros_vm | |
| 21 | +process created a memfd to share the content with an external process, | |
| 22 | +however the memfd is overwritten and used for executing arbitrary code | |
| 23 | +and root escalation. [2] lists more VRP of this kind. | |
| 24 | + | |
| 25 | +On the other hand, executable memfd has its legit use: runc uses memfd’s | |
| 26 | +seal and executable feature to copy the contents of the binary then | |
| 27 | +execute them. For such a system, we need a solution to differentiate runc's | |
| 28 | +use of executable memfds and an attacker's [3]. | |
| 29 | + | |
| 30 | +To address those above: | |
| 31 | + - Let memfd_create() set X bit at creation time. | |
| 32 | + - Let memfd be sealed for modifying X bit when NX is set. | |
| 33 | + - Add a new pid namespace sysctl: vm.memfd_noexec to help applications in | |
| 34 | + migrating and enforcing non-executable MFD. | |
| 35 | + | |
| 36 | +User API | |
| 37 | +======== | |
| 38 | +``int memfd_create(const char *name, unsigned int flags)`` | |
| 39 | + | |
| 40 | +``MFD_NOEXEC_SEAL`` | |
| 41 | + When MFD_NOEXEC_SEAL bit is set in the ``flags``, memfd is created | |
| 42 | + with NX. F_SEAL_EXEC is set and the memfd can't be modified to | |
| 43 | + add X later. MFD_ALLOW_SEALING is also implied. | |
| 44 | + This is the most common case for the application to use memfd. | |
| 45 | + | |
| 46 | +``MFD_EXEC`` | |
| 47 | + When MFD_EXEC bit is set in the ``flags``, memfd is created with X. | |
| 48 | + | |
| 49 | +Note: | |
| 50 | + ``MFD_NOEXEC_SEAL`` implies ``MFD_ALLOW_SEALING``. In case that | |
| 51 | + an app doesn't want sealing, it can add F_SEAL_SEAL after creation. | |
| 52 | + | |
| 53 | + | |
| 54 | +Sysctl: | |
| 55 | +======== | |
| 56 | +``pid namespaced sysctl vm.memfd_noexec`` | |
| 57 | + | |
| 58 | +The new pid namespaced sysctl vm.memfd_noexec has 3 values: | |
| 59 | + | |
| 60 | + - 0: MEMFD_NOEXEC_SCOPE_EXEC | |
| 61 | + memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like | |
| 62 | + MFD_EXEC was set. | |
| 63 | + | |
| 64 | + - 1: MEMFD_NOEXEC_SCOPE_NOEXEC_SEAL | |
| 65 | + memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like | |
| 66 | + MFD_NOEXEC_SEAL was set. | |
| 67 | + | |
| 68 | + - 2: MEMFD_NOEXEC_SCOPE_NOEXEC_ENFORCED | |
| 69 | + memfd_create() without MFD_NOEXEC_SEAL will be rejected. | |
| 70 | + | |
| 71 | +The sysctl allows finer control of memfd_create for old software that | |
| 72 | +doesn't set the executable bit; for example, a container with | |
| 73 | +vm.memfd_noexec=1 means the old software will create non-executable memfd | |
| 74 | +by default while new software can create executable memfd by setting | |
| 75 | +MFD_EXEC. | |
| 76 | + | |
| 77 | +The value of vm.memfd_noexec is passed to child namespace at creation | |
| 78 | +time. In addition, the setting is hierarchical, i.e. during memfd_create, | |
| 79 | +we will search from current ns to root ns and use the most restrictive | |
| 80 | +setting. | |
| 81 | + | |
| 82 | +[1] https://crbug.com/1305267 | |
| 83 | + | |
| 84 | +[2] https://bugs.chromium.org/p/chromium/issues/list?q=type%3Dbug-security%20memfd%20escalation&can=1 | |
| 85 | + | |
| 86 | +[3] https://lwn.net/Articles/781013/ | |
| @@ -62,12 +62,21 @@ shared page with scale and offset values into user space. User · 61 unmodified lines | ||
| 62 | 62 | space code performs the same algorithm of reading the TSC and |
| 63 | 63 | applying the scale and offset to get the constant 10 MHz clock. |
| 64 | 64 | |
| 65 | −Linux clockevents are based on Hyper-V synthetic timer 0. While | |
| 66 | −Hyper-V offers 4 synthetic timers for each CPU, Linux only uses | |
| 67 | −timer 0. Interrupts from stimer0 are recorded on the "HVS" line in | |
| 68 | −/proc/interrupts. Clockevents based on the virtualized PIT and | |
| 69 | −local APIC timer also work, but the Hyper-V synthetic timer is | |
| 70 | −preferred. | |
| 65 | +Linux clockevents are based on Hyper-V synthetic timer 0 (stimer0). | |
| 66 | +While Hyper-V offers 4 synthetic timers for each CPU, Linux only uses | |
| 67 | +timer 0. In older versions of Hyper-V, an interrupt from stimer0 | |
| 68 | +results in a VMBus control message that is demultiplexed by | |
| 69 | +vmbus_isr() as described in the Documentation/virt/hyperv/vmbus.rst | |
| 70 | +documentation. In newer versions of Hyper-V, stimer0 interrupts can | |
| 71 | +be mapped to an architectural interrupt, which is referred to as | |
| 72 | +"Direct Mode". Linux prefers to use Direct Mode when available. Since | |
| 73 | +x86/x64 doesn't support per-CPU interrupts, Direct Mode statically | |
| 74 | +allocates an x86 interrupt vector (HYPERV_STIMER0_VECTOR) across all CPUs | |
| 75 | +and explicitly codes it to call the stimer0 interrupt handler. Hence | |
| 76 | +interrupts from stimer0 are recorded on the "HVS" line in /proc/interrupts | |
| 77 | +rather than being associated with a Linux IRQ. Clockevents based on the | |
| 78 | +virtualized PIT and local APIC timer also work, but Hyper-V stimer0 | |
| 79 | +is preferred. | |
| 71 | 80 | |
| 72 | 81 | The driver for the Hyper-V synthetic system clock and timers is |
| 73 | 82 | drivers/clocksource/hyperv_timer.c. |
| @@ -40,7 +40,7 @@ Linux guests communicate with Hyper-V in four different ways: · 39 unmodified lines | ||
| 40 | 40 | arm64, these synthetic registers must be accessed using explicit |
| 41 | 41 | hypercalls. |
| 42 | 42 | |
| 43 | −* VMbus: VMbus is a higher-level software construct that is built on | |
| 43 | +* VMBus: VMBus is a higher-level software construct that is built on | |
| 44 | 44 | the other 3 mechanisms. It is a message passing interface between |
| 45 | 45 | the Hyper-V host and the Linux guest. It uses memory that is shared |
| 46 | 46 | between Hyper-V and the guest, along with various signaling |
| @@ -54,8 +54,8 @@ x86/x64 architecture only. · 7 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | .. _Hyper-V Top Level Functional Spec (TLFS): https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs |
| 56 | 56 | |
| 57 | −VMbus is not documented. This documentation provides a high-level | |
| 58 | −overview of VMbus and how it works, but the details can be discerned | |
| 57 | +VMBus is not documented. This documentation provides a high-level | |
| 58 | +overview of VMBus and how it works, but the details can be discerned | |
| 59 | 59 | only from the code. |
| 60 | 60 | |
| 61 | 61 | Sharing Memory |
| @@ -74,7 +74,7 @@ follows: · 12 unmodified lines | ||
| 74 | 74 | physical address space. How Hyper-V is told about the GPA or list |
| 75 | 75 | of GPAs varies. In some cases, a single GPA is written to a |
| 76 | 76 | synthetic register. In other cases, a GPA or list of GPAs is sent |
| 77 | − in a VMbus message. | |
| 77 | + in a VMBus message. | |
| 78 | 78 | |
| 79 | 79 | * Hyper-V translates the GPAs into "real" physical memory addresses, |
| 80 | 80 | and creates a virtual mapping that it can use to access the memory. |
| @@ -133,9 +133,9 @@ only the CPUs actually present in the VM, so Linux does not report · 52 unmodified lines | ||
| 133 | 133 | any hot-add CPUs. |
| 134 | 134 | |
| 135 | 135 | A Linux guest CPU may be taken offline using the normal Linux |
| 136 | −mechanisms, provided no VMbus channel interrupts are assigned to | |
| 137 | −the CPU. See the section on VMbus Interrupts for more details | |
| 138 | −on how VMbus channel interrupts can be re-assigned to permit | |
| 136 | +mechanisms, provided no VMBus channel interrupts are assigned to | |
| 137 | +the CPU. See the section on VMBus Interrupts for more details | |
| 138 | +on how VMBus channel interrupts can be re-assigned to permit | |
| 139 | 139 | taking a CPU offline. |
| 140 | 140 | |
| 141 | 141 | 32-bit and 64-bit |
| @@ -169,14 +169,14 @@ and functionality. Hyper-V indicates feature/function availability · 27 unmodified lines | ||
| 169 | 169 | via flags in synthetic MSRs that Hyper-V provides to the guest, |
| 170 | 170 | and the guest code tests these flags. |
| 171 | 171 | |
| 172 | −VMbus has its own protocol version that is negotiated during the | |
| 173 | −initial VMbus connection from the guest to Hyper-V. This version | |
| 172 | +VMBus has its own protocol version that is negotiated during the | |
| 173 | +initial VMBus connection from the guest to Hyper-V. This version | |
| 174 | 174 | number is also output to dmesg during boot. This version number |
| 175 | 175 | is checked in a few places in the code to determine if specific |
| 176 | 176 | functionality is present. |
| 177 | 177 | |
| 178 | −Furthermore, each synthetic device on VMbus also has a protocol | |
| 179 | −version that is separate from the VMbus protocol version. Device | |
| 178 | +Furthermore, each synthetic device on VMBus also has a protocol | |
| 179 | +version that is separate from the VMBus protocol version. Device | |
| 180 | 180 | drivers for these synthetic devices typically negotiate the device |
| 181 | 181 | protocol version, and may test that protocol version to determine |
| 182 | 182 | if specific device functionality is present. |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | −VMbus | |
| 3 | +VMBus | |
| 4 | 4 | ===== |
| 5 | −VMbus is a software construct provided by Hyper-V to guest VMs. It | |
| 5 | +VMBus is a software construct provided by Hyper-V to guest VMs. It | |
| 6 | 6 | consists of a control path and common facilities used by synthetic |
| 7 | 7 | devices that Hyper-V presents to guest VMs. The control path is |
| 8 | 8 | used to offer synthetic devices to the guest VM and, in some cases, |
| @@ -12,9 +12,9 @@ and the synthetic device implementation that is part of Hyper-V, and · 3 unmodified lines | ||
| 12 | 12 | signaling primitives to allow Hyper-V and the guest to interrupt |
| 13 | 13 | each other. |
| 14 | 14 | |
| 15 | −VMbus is modeled in Linux as a bus, with the expected /sys/bus/vmbus | |
| 16 | −entry in a running Linux guest. The VMbus driver (drivers/hv/vmbus_drv.c) | |
| 17 | −establishes the VMbus control path with the Hyper-V host, then | |
| 15 | +VMBus is modeled in Linux as a bus, with the expected /sys/bus/vmbus | |
| 16 | +entry in a running Linux guest. The VMBus driver (drivers/hv/vmbus_drv.c) | |
| 17 | +establishes the VMBus control path with the Hyper-V host, then | |
| 18 | 18 | registers itself as a Linux bus driver. It implements the standard |
| 19 | 19 | bus functions for adding and removing devices to/from the bus. |
| 20 | 20 | |
| @@ -49,9 +49,9 @@ synthetic NIC is referred to as "netvsc" and the Linux driver for · 28 unmodified lines | ||
| 49 | 49 | the synthetic SCSI controller is "storvsc". These drivers contain |
| 50 | 50 | functions with names like "storvsc_connect_to_vsp". |
| 51 | 51 | |
| 52 | −VMbus channels | |
| 52 | +VMBus channels | |
| 53 | 53 | -------------- |
| 54 | −An instance of a synthetic device uses VMbus channels to communicate | |
| 54 | +An instance of a synthetic device uses VMBus channels to communicate | |
| 55 | 55 | between the VSP and the VSC. Channels are bi-directional and used |
| 56 | 56 | for passing messages. Most synthetic devices use a single channel, |
| 57 | 57 | but the synthetic SCSI controller and synthetic NIC may use multiple |
| @@ -73,7 +73,7 @@ write indices and some control flags, followed by the memory for the · 15 unmodified lines | ||
| 73 | 73 | actual ring. The size of the ring is determined by the VSC in the |
| 74 | 74 | guest and is specific to each synthetic device. The list of GPAs |
| 75 | 75 | making up the ring is communicated to the Hyper-V host over the |
| 76 | −VMbus control path as a GPA Descriptor List (GPADL). See function | |
| 76 | +VMBus control path as a GPA Descriptor List (GPADL). See function | |
| 77 | 77 | vmbus_establish_gpadl(). |
| 78 | 78 | |
| 79 | 79 | Each ring buffer is mapped into contiguous Linux kernel virtual |
| @@ -102,10 +102,10 @@ resources. For Windows Server 2019 and later, this limit is · 22 unmodified lines | ||
| 102 | 102 | approximately 1280 Mbytes. For versions prior to Windows Server |
| 103 | 103 | 2019, the limit is approximately 384 Mbytes. |
| 104 | 104 | |
| 105 | −VMbus messages | |
| 106 | −-------------- | |
| 107 | −All VMbus messages have a standard header that includes the message | |
| 108 | −length, the offset of the message payload, some flags, and a | |
| 105 | +VMBus channel messages | |
| 106 | +---------------------- | |
| 107 | +All messages sent in a VMBus channel have a standard header that includes | |
| 108 | +the message length, the offset of the message payload, some flags, and a | |
| 109 | 109 | transactionID. The portion of the message after the header is |
| 110 | 110 | unique to each VSP/VSC pair. |
| 111 | 111 | |
| @@ -137,7 +137,7 @@ control message contains a list of GPAs that describe the data · 25 unmodified lines | ||
| 137 | 137 | buffer. For example, the storvsc driver uses this approach to |
| 138 | 138 | specify the data buffers to/from which disk I/O is done. |
| 139 | 139 | |
| 140 | −Three functions exist to send VMbus messages: | |
| 140 | +Three functions exist to send VMBus channel messages: | |
| 141 | 141 | |
| 142 | 142 | 1. vmbus_sendpacket(): Control-only messages and messages with |
| 143 | 143 | embedded data -- no GPAs |
| @@ -154,20 +154,51 @@ Historically, Linux guests have trusted Hyper-V to send well-formed · 10 unmodified lines | ||
| 154 | 154 | and valid messages, and Linux drivers for synthetic devices did not |
| 155 | 155 | fully validate messages. With the introduction of processor |
| 156 | 156 | technologies that fully encrypt guest memory and that allow the |
| 157 | −guest to not trust the hypervisor (AMD SNP-SEV, Intel TDX), trusting | |
| 157 | +guest to not trust the hypervisor (AMD SEV-SNP, Intel TDX), trusting | |
| 158 | 158 | the Hyper-V host is no longer a valid assumption. The drivers for |
| 159 | −VMbus synthetic devices are being updated to fully validate any | |
| 159 | +VMBus synthetic devices are being updated to fully validate any | |
| 160 | 160 | values read from memory that is shared with Hyper-V, which includes |
| 161 | −messages from VMbus devices. To facilitate such validation, | |
| 161 | +messages from VMBus devices. To facilitate such validation, | |
| 162 | 162 | messages read by the guest from the "in" ring buffer are copied to a |
| 163 | 163 | temporary buffer that is not shared with Hyper-V. Validation is |
| 164 | 164 | performed in this temporary buffer without the risk of Hyper-V |
| 165 | 165 | maliciously modifying the message after it is validated but before |
| 166 | 166 | it is used. |
| 167 | 167 | |
| 168 | −VMbus interrupts | |
| 168 | +Synthetic Interrupt Controller (synic) | |
| 169 | +-------------------------------------- | |
| 170 | +Hyper-V provides each guest CPU with a synthetic interrupt controller | |
| 171 | +that is used by VMBus for host-guest communication. While each synic | |
| 172 | +defines 16 synthetic interrupts (SINT), Linux uses only one of the 16 | |
| 173 | +(VMBUS_MESSAGE_SINT). All interrupts related to communication between | |
| 174 | +the Hyper-V host and a guest CPU use that SINT. | |
| 175 | + | |
| 176 | +The SINT is mapped to a single per-CPU architectural interrupt (i.e, | |
| 177 | +an 8-bit x86/x64 interrupt vector, or an arm64 PPI INTID). Because | |
| 178 | +each CPU in the guest has a synic and may receive VMBus interrupts, | |
| 179 | +they are best modeled in Linux as per-CPU interrupts. This model works | |
| 180 | +well on arm64 where a single per-CPU Linux IRQ is allocated for | |
| 181 | +VMBUS_MESSAGE_SINT. This IRQ appears in /proc/interrupts as an IRQ labelled | |
| 182 | +"Hyper-V VMbus". Since x86/x64 lacks support for per-CPU IRQs, an x86 | |
| 183 | +interrupt vector is statically allocated (HYPERVISOR_CALLBACK_VECTOR) | |
| 184 | +across all CPUs and explicitly coded to call vmbus_isr(). In this case, | |
| 185 | +there's no Linux IRQ, and the interrupts are visible in aggregate in | |
| 186 | +/proc/interrupts on the "HYP" line. | |
| 187 | + | |
| 188 | +The synic provides the means to demultiplex the architectural interrupt into | |
| 189 | +one or more logical interrupts and route the logical interrupt to the proper | |
| 190 | +VMBus handler in Linux. This demultiplexing is done by vmbus_isr() and | |
| 191 | +related functions that access synic data structures. | |
| 192 | + | |
| 193 | +The synic is not modeled in Linux as an irq chip or irq domain, | |
| 194 | +and the demultiplexed logical interrupts are not Linux IRQs. As such, | |
| 195 | +they don't appear in /proc/interrupts or /proc/irq. The CPU | |
| 196 | +affinity for one of these logical interrupts is controlled via an | |
| 197 | +entry under /sys/bus/vmbus as described below. | |
| 198 | + | |
| 199 | +VMBus interrupts | |
| 169 | 200 | ---------------- |
| 170 | −VMbus provides a mechanism for the guest to interrupt the host when | |
| 201 | +VMBus provides a mechanism for the guest to interrupt the host when | |
| 171 | 202 | the guest has queued new messages in a ring buffer. The host |
| 172 | 203 | expects that the guest will send an interrupt only when an "out" |
| 173 | 204 | ring buffer transitions from empty to non-empty. If the guest sends |
| @@ -176,63 +207,55 @@ unnecessary. If a guest sends an excessive number of unnecessary · 2 unmodified lines | ||
| 176 | 207 | interrupts, the host may throttle that guest by suspending its |
| 177 | 208 | execution for a few seconds to prevent a denial-of-service attack. |
| 178 | 209 | |
| 179 | −Similarly, the host will interrupt the guest when it sends a new | |
| 180 | −message on the VMbus control path, or when a VMbus channel "in" ring | |
| 181 | −buffer transitions from empty to non-empty. Each CPU in the guest | |
| 182 | −may receive VMbus interrupts, so they are best modeled as per-CPU | |
| 183 | −interrupts in Linux. This model works well on arm64 where a single | |
| 184 | −per-CPU IRQ is allocated for VMbus. Since x86/x64 lacks support for | |
| 185 | −per-CPU IRQs, an x86 interrupt vector is statically allocated (see | |
| 186 | −HYPERVISOR_CALLBACK_VECTOR) across all CPUs and explicitly coded to | |
| 187 | −call the VMbus interrupt service routine. These interrupts are | |
| 188 | −visible in /proc/interrupts on the "HYP" line. | |
| 189 | − | |
| 190 | −The guest CPU that a VMbus channel will interrupt is selected by the | |
| 210 | +Similarly, the host will interrupt the guest via the synic when | |
| 211 | +it sends a new message on the VMBus control path, or when a VMBus | |
| 212 | +channel "in" ring buffer transitions from empty to non-empty due to | |
| 213 | +the host inserting a new VMBus channel message. The control message stream | |
| 214 | +and each VMBus channel "in" ring buffer are separate logical interrupts | |
| 215 | +that are demultiplexed by vmbus_isr(). It demultiplexes by first checking | |
| 216 | +for channel interrupts by calling vmbus_chan_sched(), which looks at a synic | |
| 217 | +bitmap to determine which channels have pending interrupts on this CPU. | |
| 218 | +If multiple channels have pending interrupts for this CPU, they are | |
| 219 | +processed sequentially. When all channel interrupts have been processed, | |
| 220 | +vmbus_isr() checks for and processes any messages received on the VMBus | |
| 221 | +control path. | |
| 222 | + | |
| 223 | +The guest CPU that a VMBus channel will interrupt is selected by the | |
| 191 | 224 | guest when the channel is created, and the host is informed of that |
| 192 | −selection. VMbus devices are broadly grouped into two categories: | |
| 225 | +selection. VMBus devices are broadly grouped into two categories: | |
| 193 | 226 | |
| 194 | −1. "Slow" devices that need only one VMbus channel. The devices | |
| 227 | +1. "Slow" devices that need only one VMBus channel. The devices | |
| 195 | 228 | (such as keyboard, mouse, heartbeat, and timesync) generate |
| 196 | − relatively few interrupts. Their VMbus channels are all | |
| 229 | + relatively few interrupts. Their VMBus channels are all | |
| 197 | 230 | assigned to interrupt the VMBUS_CONNECT_CPU, which is always |
| 198 | 231 | CPU 0. |
| 199 | 232 | |
| 200 | −2. "High speed" devices that may use multiple VMbus channels for | |
| 233 | +2. "High speed" devices that may use multiple VMBus channels for | |
| 201 | 234 | higher parallelism and performance. These devices include the |
| 202 | − synthetic SCSI controller and synthetic NIC. Their VMbus | |
| 235 | + synthetic SCSI controller and synthetic NIC. Their VMBus | |
| 203 | 236 | channels interrupts are assigned to CPUs that are spread out |
| 204 | 237 | among the available CPUs in the VM so that interrupts on |
| 205 | 238 | multiple channels can be processed in parallel. |
| 206 | 239 | |
| 207 | −The assignment of VMbus channel interrupts to CPUs is done in the | |
| 240 | +The assignment of VMBus channel interrupts to CPUs is done in the | |
| 208 | 241 | function init_vp_index(). This assignment is done outside of the |
| 209 | 242 | normal Linux interrupt affinity mechanism, so the interrupts are |
| 210 | 243 | neither "unmanaged" nor "managed" interrupts. |
| 211 | 244 | |
| 212 | −The CPU that a VMbus channel will interrupt can be seen in | |
| 245 | +The CPU that a VMBus channel will interrupt can be seen in | |
| 213 | 246 | /sys/bus/vmbus/devices/<deviceGUID>/ channels/<channelRelID>/cpu. |
| 214 | 247 | When running on later versions of Hyper-V, the CPU can be changed |
| 215 | −by writing a new value to this sysfs entry. Because the interrupt | |
| 216 | −assignment is done outside of the normal Linux affinity mechanism, | |
| 217 | −there are no entries in /proc/irq corresponding to individual | |
| 218 | −VMbus channel interrupts. | |
| 248 | +by writing a new value to this sysfs entry. Because VMBus channel | |
| 249 | +interrupts are not Linux IRQs, there are no entries in /proc/interrupts | |
| 250 | +or /proc/irq corresponding to individual VMBus channel interrupts. | |
| 219 | 251 | |
| 220 | 252 | An online CPU in a Linux guest may not be taken offline if it has |
| 221 | −VMbus channel interrupts assigned to it. Any such channel | |
| 253 | +VMBus channel interrupts assigned to it. Any such channel | |
| 222 | 254 | interrupts must first be manually reassigned to another CPU as |
| 223 | 255 | described above. When no channel interrupts are assigned to the |
| 224 | 256 | CPU, it can be taken offline. |
| 225 | 257 | |
| 226 | −When a guest CPU receives a VMbus interrupt from the host, the | |
| 227 | −function vmbus_isr() handles the interrupt. It first checks for | |
| 228 | −channel interrupts by calling vmbus_chan_sched(), which looks at a | |
| 229 | −bitmap setup by the host to determine which channels have pending | |
| 230 | −interrupts on this CPU. If multiple channels have pending | |
| 231 | −interrupts for this CPU, they are processed sequentially. When all | |
| 232 | −channel interrupts have been processed, vmbus_isr() checks for and | |
| 233 | −processes any message received on the VMbus control path. | |
| 234 | − | |
| 235 | −The VMbus channel interrupt handling code is designed to work | |
| 258 | +The VMBus channel interrupt handling code is designed to work | |
| 236 | 259 | correctly even if an interrupt is received on a CPU other than the |
| 237 | 260 | CPU assigned to the channel. Specifically, the code does not use |
| 238 | 261 | CPU-based exclusion for correctness. In normal operation, Hyper-V |
| @@ -242,23 +265,23 @@ when Hyper-V will make the transition. The code must work correctly · 3 unmodified lines | ||
| 242 | 265 | even if there is a time lag before Hyper-V starts interrupting the |
| 243 | 266 | new CPU. See comments in target_cpu_store(). |
| 244 | 267 | |
| 245 | −VMbus device creation/deletion | |
| 268 | +VMBus device creation/deletion | |
| 246 | 269 | ------------------------------ |
| 247 | 270 | Hyper-V and the Linux guest have a separate message-passing path |
| 248 | 271 | that is used for synthetic device creation and deletion. This |
| 249 | −path does not use a VMbus channel. See vmbus_post_msg() and | |
| 272 | +path does not use a VMBus channel. See vmbus_post_msg() and | |
| 250 | 273 | vmbus_on_msg_dpc(). |
| 251 | 274 | |
| 252 | 275 | The first step is for the guest to connect to the generic |
| 253 | −Hyper-V VMbus mechanism. As part of establishing this connection, | |
| 254 | −the guest and Hyper-V agree on a VMbus protocol version they will | |
| 276 | +Hyper-V VMBus mechanism. As part of establishing this connection, | |
| 277 | +the guest and Hyper-V agree on a VMBus protocol version they will | |
| 255 | 278 | use. This negotiation allows newer Linux kernels to run on older |
| 256 | 279 | Hyper-V versions, and vice versa. |
| 257 | 280 | |
| 258 | 281 | The guest then tells Hyper-V to "send offers". Hyper-V sends an |
| 259 | 282 | offer message to the guest for each synthetic device that the VM |
| 260 | −is configured to have. Each VMbus device type has a fixed GUID | |
| 261 | −known as the "class ID", and each VMbus device instance is also | |
| 283 | +is configured to have. Each VMBus device type has a fixed GUID | |
| 284 | +known as the "class ID", and each VMBus device instance is also | |
| 262 | 285 | identified by a GUID. The offer message from Hyper-V contains |
| 263 | 286 | both GUIDs to uniquely (within the VM) identify the device. |
| 264 | 287 | There is one offer message for each device instance, so a VM with |
| @@ -275,7 +298,7 @@ type based on the class ID, and invokes the correct driver to set up · 10 unmodified lines | ||
| 275 | 298 | the device. Driver/device matching is performed using the standard |
| 276 | 299 | Linux mechanism. |
| 277 | 300 | |
| 278 | −The device driver probe function opens the primary VMbus channel to | |
| 301 | +The device driver probe function opens the primary VMBus channel to | |
| 279 | 302 | the corresponding VSP. It allocates guest memory for the channel |
| 280 | 303 | ring buffers and shares the ring buffer with the Hyper-V host by |
| 281 | 304 | giving the host a list of GPAs for the ring buffer memory. See |
| @@ -285,7 +308,7 @@ Once the ring buffer is set up, the device driver and VSP exchange · 3 unmodified lines | ||
| 285 | 308 | setup messages via the primary channel. These messages may include |
| 286 | 309 | negotiating the device protocol version to be used between the Linux |
| 287 | 310 | VSC and the VSP on the Hyper-V host. The setup messages may also |
| 288 | −include creating additional VMbus channels, which are somewhat | |
| 311 | +include creating additional VMBus channels, which are somewhat | |
| 289 | 312 | mis-named as "sub-channels" since they are functionally |
| 290 | 313 | equivalent to the primary channel once they are created. |
| 291 | 314 | |
| @@ -3980,7 +3980,7 @@ R: Song Liu <song@kernel.org> · 3979 unmodified lines | ||
| 3980 | 3980 | R: Yonghong Song <yonghong.song@linux.dev> |
| 3981 | 3981 | R: John Fastabend <john.fastabend@gmail.com> |
| 3982 | 3982 | R: KP Singh <kpsingh@kernel.org> |
| 3983 | −R: Stanislav Fomichev <sdf@google.com> | |
| 3983 | +R: Stanislav Fomichev <sdf@fomichev.me> | |
| 3984 | 3984 | R: Hao Luo <haoluo@google.com> |
| 3985 | 3985 | R: Jiri Olsa <jolsa@kernel.org> |
| 3986 | 3986 | L: bpf@vger.kernel.org |
| @@ -5295,7 +5295,7 @@ F: drivers/infiniband/hw/usnic/ · 1308 unmodified lines | ||
| 5295 | 5295 | |
| 5296 | 5296 | CLANG CONTROL FLOW INTEGRITY SUPPORT |
| 5297 | 5297 | M: Sami Tolvanen <samitolvanen@google.com> |
| 5298 | −M: Kees Cook <keescook@chromium.org> | |
| 5298 | +M: Kees Cook <kees@kernel.org> | |
| 5299 | 5299 | R: Nathan Chancellor <nathan@kernel.org> |
| 5300 | 5300 | L: llvm@lists.linux.dev |
| 5301 | 5301 | S: Supported |
| @@ -8211,7 +8211,7 @@ F: rust/kernel/net/phy.rs · 2909 unmodified lines | ||
| 8211 | 8211 | |
| 8212 | 8212 | EXEC & BINFMT API, ELF |
| 8213 | 8213 | R: Eric Biederman <ebiederm@xmission.com> |
| 8214 | −R: Kees Cook <keescook@chromium.org> | |
| 8214 | +R: Kees Cook <kees@kernel.org> | |
| 8215 | 8215 | L: linux-mm@kvack.org |
| 8216 | 8216 | S: Supported |
| 8217 | 8217 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve |
| @@ -8612,7 +8612,7 @@ S: Maintained · 394 unmodified lines | ||
| 8612 | 8612 | F: drivers/net/ethernet/nvidia/* |
| 8613 | 8613 | |
| 8614 | 8614 | FORTIFY_SOURCE |
| 8615 | −M: Kees Cook <keescook@chromium.org> | |
| 8615 | +M: Kees Cook <kees@kernel.org> | |
| 8616 | 8616 | L: linux-hardening@vger.kernel.org |
| 8617 | 8617 | S: Supported |
| 8618 | 8618 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening |
| @@ -9102,7 +9102,7 @@ F: include/linux/mfd/gsc.h · 483 unmodified lines | ||
| 9102 | 9102 | F: include/linux/platform_data/gsc_hwmon.h |
| 9103 | 9103 | |
| 9104 | 9104 | GCC PLUGINS |
| 9105 | −M: Kees Cook <keescook@chromium.org> | |
| 9105 | +M: Kees Cook <kees@kernel.org> | |
| 9106 | 9106 | L: linux-hardening@vger.kernel.org |
| 9107 | 9107 | S: Maintained |
| 9108 | 9108 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening |
| @@ -9236,7 +9236,7 @@ S: Maintained · 127 unmodified lines | ||
| 9236 | 9236 | F: drivers/input/touchscreen/resistive-adc-touch.c |
| 9237 | 9237 | |
| 9238 | 9238 | GENERIC STRING LIBRARY |
| 9239 | −M: Kees Cook <keescook@chromium.org> | |
| 9239 | +M: Kees Cook <kees@kernel.org> | |
| 9240 | 9240 | R: Andy Shevchenko <andy@kernel.org> |
| 9241 | 9241 | L: linux-hardening@vger.kernel.org |
| 9242 | 9242 | S: Supported |
| @@ -11950,7 +11950,7 @@ F: scripts/package/ · 2707 unmodified lines | ||
| 11950 | 11950 | F: usr/ |
| 11951 | 11951 | |
| 11952 | 11952 | KERNEL HARDENING (not covered by other areas) |
| 11953 | −M: Kees Cook <keescook@chromium.org> | |
| 11953 | +M: Kees Cook <kees@kernel.org> | |
| 11954 | 11954 | R: Gustavo A. R. Silva <gustavoars@kernel.org> |
| 11955 | 11955 | L: linux-hardening@vger.kernel.org |
| 11956 | 11956 | S: Supported |
| @@ -12382,7 +12382,6 @@ F: drivers/video/backlight/ktz8866.c · 425 unmodified lines | ||
| 12382 | 12382 | |
| 12383 | 12383 | KVM PARAVIRT (KVM/paravirt) |
| 12384 | 12384 | M: Paolo Bonzini <pbonzini@redhat.com> |
| 12385 | −R: Wanpeng Li <wanpengli@tencent.com> | |
| 12386 | 12385 | R: Vitaly Kuznetsov <vkuznets@redhat.com> |
| 12387 | 12386 | L: kvm@vger.kernel.org |
| 12388 | 12387 | S: Supported |
| @@ -12478,7 +12477,7 @@ F: drivers/scsi/53c700* · 89 unmodified lines | ||
| 12478 | 12477 | |
| 12479 | 12478 | LEAKING_ADDRESSES |
| 12480 | 12479 | M: Tycho Andersen <tycho@tycho.pizza> |
| 12481 | −R: Kees Cook <keescook@chromium.org> | |
| 12480 | +R: Kees Cook <kees@kernel.org> | |
| 12482 | 12481 | L: linux-hardening@vger.kernel.org |
| 12483 | 12482 | S: Maintained |
| 12484 | 12483 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening |
| @@ -12774,7 +12773,7 @@ F: arch/powerpc/platforms/8xx/ · 289 unmodified lines | ||
| 12774 | 12773 | F: arch/powerpc/platforms/83xx/ |
| 12775 | 12774 | |
| 12776 | 12775 | LINUX KERNEL DUMP TEST MODULE (LKDTM) |
| 12777 | −M: Kees Cook <keescook@chromium.org> | |
| 12776 | +M: Kees Cook <kees@kernel.org> | |
| 12778 | 12777 | S: Maintained |
| 12779 | 12778 | F: drivers/misc/lkdtm/* |
| 12780 | 12779 | F: tools/testing/selftests/lkdtm/* |
| @@ -12904,7 +12903,7 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ · 123 unmodified lines | ||
| 12904 | 12903 | F: drivers/media/usb/dvb-usb-v2/lmedm04* |
| 12905 | 12904 | |
| 12906 | 12905 | LOADPIN SECURITY MODULE |
| 12907 | −M: Kees Cook <keescook@chromium.org> | |
| 12906 | +M: Kees Cook <kees@kernel.org> | |
| 12908 | 12907 | S: Supported |
| 12909 | 12908 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening |
| 12910 | 12909 | F: Documentation/admin-guide/LSM/LoadPin.rst |
| @@ -17996,7 +17995,7 @@ F: tools/testing/selftests/proc/ · 5085 unmodified lines | ||
| 17996 | 17995 | |
| 17997 | 17996 | PROC SYSCTL |
| 17998 | 17997 | M: Luis Chamberlain <mcgrof@kernel.org> |
| 17999 | −M: Kees Cook <keescook@chromium.org> | |
| 17998 | +M: Kees Cook <kees@kernel.org> | |
| 18000 | 17999 | M: Joel Granados <j.granados@samsung.com> |
| 18001 | 18000 | L: linux-kernel@vger.kernel.org |
| 18002 | 18001 | L: linux-fsdevel@vger.kernel.org |
| @@ -18052,7 +18051,7 @@ F: Documentation/devicetree/bindings/net/pse-pd/ · 49 unmodified lines | ||
| 18052 | 18051 | F: drivers/net/pse-pd/ |
| 18053 | 18052 | |
| 18054 | 18053 | PSTORE FILESYSTEM |
| 18055 | −M: Kees Cook <keescook@chromium.org> | |
| 18054 | +M: Kees Cook <kees@kernel.org> | |
| 18056 | 18055 | R: Tony Luck <tony.luck@intel.com> |
| 18057 | 18056 | R: Guilherme G. Piccoli <gpiccoli@igalia.com> |
| 18058 | 18057 | L: linux-hardening@vger.kernel.org |
| @@ -20058,7 +20057,7 @@ F: drivers/media/cec/platform/seco/seco-cec.c · 1999 unmodified lines | ||
| 20058 | 20057 | F: drivers/media/cec/platform/seco/seco-cec.h |
| 20059 | 20058 | |
| 20060 | 20059 | SECURE COMPUTING |
| 20061 | −M: Kees Cook <keescook@chromium.org> | |
| 20060 | +M: Kees Cook <kees@kernel.org> | |
| 20062 | 20061 | R: Andy Lutomirski <luto@amacapital.net> |
| 20063 | 20062 | R: Will Drewry <wad@chromium.org> |
| 20064 | 20063 | S: Supported |
| @@ -22972,7 +22971,7 @@ F: drivers/block/ublk_drv.c · 2907 unmodified lines | ||
| 22972 | 22971 | F: include/uapi/linux/ublk_cmd.h |
| 22973 | 22972 | |
| 22974 | 22973 | UBSAN |
| 22975 | −M: Kees Cook <keescook@chromium.org> | |
| 22974 | +M: Kees Cook <kees@kernel.org> | |
| 22976 | 22975 | R: Marco Elver <elver@google.com> |
| 22977 | 22976 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 22978 | 22977 | R: Andrey Ryabinin <ryabinin.a.a@gmail.com> |
| @@ -23974,7 +23973,6 @@ VMALLOC · 995 unmodified lines | ||
| 23974 | 23973 | M: Andrew Morton <akpm@linux-foundation.org> |
| 23975 | 23974 | R: Uladzislau Rezki <urezki@gmail.com> |
| 23976 | 23975 | R: Christoph Hellwig <hch@infradead.org> |
| 23977 | −R: Lorenzo Stoakes <lstoakes@gmail.com> | |
| 23978 | 23976 | L: linux-mm@kvack.org |
| 23979 | 23977 | S: Maintained |
| 23980 | 23978 | W: http://www.linux-mm.org |
| @@ -24810,7 +24808,7 @@ F: drivers/net/hamradio/yam* · 829 unmodified lines | ||
| 24810 | 24808 | F: include/linux/yam.h |
| 24811 | 24809 | |
| 24812 | 24810 | YAMA SECURITY MODULE |
| 24813 | −M: Kees Cook <keescook@chromium.org> | |
| 24811 | +M: Kees Cook <kees@kernel.org> | |
| 24814 | 24812 | S: Supported |
| 24815 | 24813 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening |
| 24816 | 24814 | F: Documentation/admin-guide/LSM/Yama.rst |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 10 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc4 | |
| 5 | +EXTRAVERSION = -rc5 | |
| 6 | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -85,7 +85,7 @@ · 84 unmodified lines | ||
| 85 | 85 | }; |
| 86 | 86 | }; |
| 87 | 87 | |
| 88 | − panel { | |
| 88 | + panel_dpi: panel { | |
| 89 | 89 | compatible = "sii,43wvf1g"; |
| 90 | 90 | pinctrl-names = "default"; |
| 91 | 91 | pinctrl-0 = <&pinctrl_display_power>; |
| @@ -10,8 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | /plugin/; |
| 11 | 11 | |
| 12 | 12 | &{/} { |
| 13 | − /delete-node/ panel; | |
| 14 | − | |
| 15 | 13 | hdmi: connector-hdmi { |
| 16 | 14 | compatible = "hdmi-connector"; |
| 17 | 15 | label = "hdmi"; |
| @@ -82,6 +80,10 @@ · 64 unmodified lines | ||
| 82 | 80 | }; |
| 83 | 81 | }; |
| 84 | 82 | |
| 83 | +&panel_dpi { | |
| 84 | + status = "disabled"; | |
| 85 | +}; | |
| 86 | + | |
| 85 | 87 | &tve { |
| 86 | 88 | status = "disabled"; |
| 87 | 89 | }; |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <asm/mach/map.h> |
| 15 | 15 | #include <asm/mmu_context.h> |
| 16 | 16 | #include <asm/ptrace.h> |
| 17 | +#include <asm/uaccess.h> | |
| 17 | 18 | |
| 18 | 19 | #ifdef CONFIG_EFI |
| 19 | 20 | void efi_init(void); |
| @@ -25,6 +26,18 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, boo · 5 unmodified lines | ||
| 25 | 26 | #define arch_efi_call_virt_setup() efi_virtmap_load() |
| 26 | 27 | #define arch_efi_call_virt_teardown() efi_virtmap_unload() |
| 27 | 28 | |
| 29 | +#ifdef CONFIG_CPU_TTBR0_PAN | |
| 30 | +#undef arch_efi_call_virt | |
| 31 | +#define arch_efi_call_virt(p, f, args...) ({ \ | |
| 32 | + unsigned int flags = uaccess_save_and_enable(); \ | |
| 33 | + efi_status_t res = _Generic((p)->f(args), \ | |
| 34 | + efi_status_t: (p)->f(args), \ | |
| 35 | + default: ((p)->f(args), EFI_ABORTED)); \ | |
| 36 | + uaccess_restore(flags); \ | |
| 37 | + res; \ | |
| 38 | +}) | |
| 39 | +#endif | |
| 40 | + | |
| 28 | 41 | #define ARCH_EFI_IRQ_FLAGS_MASK \ |
| 29 | 42 | (PSR_J_BIT | PSR_E_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | \ |
| 30 | 43 | PSR_T_BIT | MODE_MASK) |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <dt-bindings/phy/phy-imx8-pcie.h> |
| 7 | 7 | #include <dt-bindings/pwm/pwm.h> |
| 8 | 8 | #include "imx8mm.dtsi" |
| 9 | +#include "imx8mm-overdrive.dtsi" | |
| 9 | 10 | |
| 10 | 11 | / { |
| 11 | 12 | chosen { |
| @@ -935,7 +936,7 @@ · 923 unmodified lines | ||
| 935 | 936 | /* Verdin GPIO_9_DSI (pulled-up as active-low) */ |
| 936 | 937 | pinctrl_gpio_9_dsi: gpio9dsigrp { |
| 937 | 938 | fsl,pins = |
| 938 | − <MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x146>; /* SODIMM 17 */ | |
| 939 | + <MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x1c6>; /* SODIMM 17 */ | |
| 939 | 940 | }; |
| 940 | 941 | |
| 941 | 942 | /* Verdin GPIO_10_DSI (pulled-up as active-low) */ |
| @@ -254,7 +254,7 @@ · 253 unmodified lines | ||
| 254 | 254 | <&clk IMX8MP_CLK_CLKOUT2>, |
| 255 | 255 | <&clk IMX8MP_AUDIO_PLL2_OUT>; |
| 256 | 256 | assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; |
| 257 | − assigned-clock-rates = <13000000>, <13000000>, <156000000>; | |
| 257 | + assigned-clock-rates = <13000000>, <13000000>, <208000000>; | |
| 258 | 258 | reset-gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>; |
| 259 | 259 | status = "disabled"; |
| 260 | 260 | |
| @@ -219,7 +219,7 @@ · 218 unmodified lines | ||
| 219 | 219 | |
| 220 | 220 | bluetooth { |
| 221 | 221 | compatible = "brcm,bcm4330-bt"; |
| 222 | − shutdown-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; | |
| 222 | + shutdown-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; | |
| 223 | 223 | }; |
| 224 | 224 | }; |
| 225 | 225 | |
| @@ -36,7 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | regulator-name = "SD1_SPWR"; |
| 37 | 37 | regulator-min-microvolt = <3000000>; |
| 38 | 38 | regulator-max-microvolt = <3000000>; |
| 39 | − gpio = <&lsio_gpio4 19 GPIO_ACTIVE_HIGH>; | |
| 39 | + gpio = <&lsio_gpio4 7 GPIO_ACTIVE_HIGH>; | |
| 40 | 40 | enable-active-high; |
| 41 | 41 | }; |
| 42 | 42 | |
| @@ -296,7 +296,6 @@ · 295 unmodified lines | ||
| 296 | 296 | vmmc-supply = <®_usdhc2_vmmc>; |
| 297 | 297 | bus-width = <4>; |
| 298 | 298 | status = "okay"; |
| 299 | − no-sdio; | |
| 300 | 299 | no-mmc; |
| 301 | 300 | }; |
| 302 | 301 | |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include <linux/efi.h> |
| 11 | 11 | #include <linux/init.h> |
| 12 | +#include <linux/kmemleak.h> | |
| 12 | 13 | #include <linux/screen_info.h> |
| 13 | 14 | #include <linux/vmalloc.h> |
| 14 | 15 | |
| @@ -213,6 +214,7 @@ l: if (!p) { · 198 unmodified lines | ||
| 213 | 214 | return -ENOMEM; |
| 214 | 215 | } |
| 215 | 216 | |
| 217 | + kmemleak_not_leak(p); | |
| 216 | 218 | efi_rt_stack_top = p + THREAD_SIZE; |
| 217 | 219 | return 0; |
| 218 | 220 | } |
| @@ -177,6 +177,14 @@ static void ffa_retrieve_req(struct arm_smccc_res *res, u32 len) · 176 unmodified lines | ||
| 177 | 177 | res); |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | +static void ffa_rx_release(struct arm_smccc_res *res) | |
| 181 | +{ | |
| 182 | + arm_smccc_1_1_smc(FFA_RX_RELEASE, | |
| 183 | + 0, 0, | |
| 184 | + 0, 0, 0, 0, 0, | |
| 185 | + res); | |
| 186 | +} | |
| 187 | + | |
| 180 | 188 | static void do_ffa_rxtx_map(struct arm_smccc_res *res, |
| 181 | 189 | struct kvm_cpu_context *ctxt) |
| 182 | 190 | { |
| @@ -543,16 +551,19 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res, · 360 unmodified lines | ||
| 543 | 551 | if (WARN_ON(offset > len || |
| 544 | 552 | fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) { |
| 545 | 553 | ret = FFA_RET_ABORTED; |
| 554 | + ffa_rx_release(res); | |
| 546 | 555 | goto out_unlock; |
| 547 | 556 | } |
| 548 | 557 | |
| 549 | 558 | if (len > ffa_desc_buf.len) { |
| 550 | 559 | ret = FFA_RET_NO_MEMORY; |
| 560 | + ffa_rx_release(res); | |
| 551 | 561 | goto out_unlock; |
| 552 | 562 | } |
| 553 | 563 | |
| 554 | 564 | buf = ffa_desc_buf.buf; |
| 555 | 565 | memcpy(buf, hyp_buffers.rx, fraglen); |
| 566 | + ffa_rx_release(res); | |
| 556 | 567 | |
| 557 | 568 | for (fragoff = fraglen; fragoff < len; fragoff += fraglen) { |
| 558 | 569 | ffa_mem_frag_rx(res, handle_lo, handle_hi, fragoff); |
| @@ -563,6 +574,7 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res, · 4 unmodified lines | ||
| 563 | 574 | |
| 564 | 575 | fraglen = res->a3; |
| 565 | 576 | memcpy((void *)buf + fragoff, hyp_buffers.rx, fraglen); |
| 577 | + ffa_rx_release(res); | |
| 566 | 578 | } |
| 567 | 579 | |
| 568 | 580 | ffa_mem_reclaim(res, handle_lo, handle_hi, flags); |
| @@ -391,7 +391,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm) · 390 unmodified lines | ||
| 391 | 391 | |
| 392 | 392 | if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { |
| 393 | 393 | list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list) |
| 394 | − vgic_v3_free_redist_region(rdreg); | |
| 394 | + vgic_v3_free_redist_region(kvm, rdreg); | |
| 395 | 395 | INIT_LIST_HEAD(&dist->rd_regions); |
| 396 | 396 | } else { |
| 397 | 397 | dist->vgic_cpu_base = VGIC_ADDR_UNDEF; |
| @@ -919,8 +919,19 @@ free: · 918 unmodified lines | ||
| 919 | 919 | return ret; |
| 920 | 920 | } |
| 921 | 921 | |
| 922 | −void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg) | |
| 922 | +void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg) | |
| 923 | 923 | { |
| 924 | + struct kvm_vcpu *vcpu; | |
| 925 | + unsigned long c; | |
| 926 | + | |
| 927 | + lockdep_assert_held(&kvm->arch.config_lock); | |
| 928 | + | |
| 929 | + /* Garbage collect the region */ | |
| 930 | + kvm_for_each_vcpu(c, vcpu, kvm) { | |
| 931 | + if (vcpu->arch.vgic_cpu.rdreg == rdreg) | |
| 932 | + vcpu->arch.vgic_cpu.rdreg = NULL; | |
| 933 | + } | |
| 934 | + | |
| 924 | 935 | list_del(&rdreg->list); |
| 925 | 936 | kfree(rdreg); |
| 926 | 937 | } |
| @@ -945,7 +956,7 @@ int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count) · 18 unmodified lines | ||
| 945 | 956 | |
| 946 | 957 | mutex_lock(&kvm->arch.config_lock); |
| 947 | 958 | rdreg = vgic_v3_rdist_region_from_index(kvm, index); |
| 948 | − vgic_v3_free_redist_region(rdreg); | |
| 959 | + vgic_v3_free_redist_region(kvm, rdreg); | |
| 949 | 960 | mutex_unlock(&kvm->arch.config_lock); |
| 950 | 961 | return ret; |
| 951 | 962 | } |
| @@ -316,7 +316,7 @@ vgic_v3_rd_region_size(struct kvm *kvm, struct vgic_redist_region *rdreg) · 315 unmodified lines | ||
| 316 | 316 | |
| 317 | 317 | struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm, |
| 318 | 318 | u32 index); |
| 319 | −void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg); | |
| 319 | +void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg); | |
| 320 | 320 | |
| 321 | 321 | bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size); |
| 322 | 322 | |
| @@ -143,7 +143,7 @@ config LOONGARCH · 142 unmodified lines | ||
| 143 | 143 | select HAVE_LIVEPATCH |
| 144 | 144 | select HAVE_MOD_ARCH_SPECIFIC |
| 145 | 145 | select HAVE_NMI |
| 146 | − select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS | |
| 146 | + select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB && !CC_IS_CLANG | |
| 147 | 147 | select HAVE_PCI |
| 148 | 148 | select HAVE_PERF_EVENTS |
| 149 | 149 | select HAVE_PERF_REGS |
| @@ -261,6 +261,9 @@ config AS_HAS_EXPLICIT_RELOCS · 111 unmodified lines | ||
| 261 | 261 | config AS_HAS_FCSR_CLASS |
| 262 | 262 | def_bool $(as-instr,movfcsr2gr \$t0$(comma)\$fcsr0) |
| 263 | 263 | |
| 264 | +config AS_HAS_THIN_ADD_SUB | |
| 265 | + def_bool $(cc-option,-Wa$(comma)-mthin-add-sub) | |
| 266 | + | |
| 264 | 267 | config AS_HAS_LSX_EXTENSION |
| 265 | 268 | def_bool $(as-instr,vld \$vr0$(comma)\$a0$(comma)0) |
| 266 | 269 | |
| @@ -28,6 +28,7 @@ config UNWINDER_PROLOGUE · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | config UNWINDER_ORC |
| 30 | 30 | bool "ORC unwinder" |
| 31 | + depends on HAVE_OBJTOOL | |
| 31 | 32 | select OBJTOOL |
| 32 | 33 | help |
| 33 | 34 | This option enables the ORC (Oops Rewind Capability) unwinder for |
| @@ -75,6 +75,8 @@ do { \ · 74 unmodified lines | ||
| 75 | 75 | #define CSR_MWPC_NUM 0x3f |
| 76 | 76 | |
| 77 | 77 | #define CTRL_PLV_ENABLE 0x1e |
| 78 | +#define CTRL_PLV0_ENABLE 0x02 | |
| 79 | +#define CTRL_PLV3_ENABLE 0x10 | |
| 78 | 80 | |
| 79 | 81 | #define MWPnCFG3_LoadEn 8 |
| 80 | 82 | #define MWPnCFG3_StoreEn 9 |
| @@ -101,7 +103,7 @@ struct perf_event; · 20 unmodified lines | ||
| 101 | 103 | struct perf_event_attr; |
| 102 | 104 | |
| 103 | 105 | extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, |
| 104 | − int *gen_len, int *gen_type, int *offset); | |
| 106 | + int *gen_len, int *gen_type); | |
| 105 | 107 | extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw); |
| 106 | 108 | extern int hw_breakpoint_arch_parse(struct perf_event *bp, |
| 107 | 109 | const struct perf_event_attr *attr, |
| @@ -174,11 +174,21 @@ void flush_ptrace_hw_breakpoint(struct task_struct *tsk) · 173 unmodified lines | ||
| 174 | 174 | static int hw_breakpoint_control(struct perf_event *bp, |
| 175 | 175 | enum hw_breakpoint_ops ops) |
| 176 | 176 | { |
| 177 | − u32 ctrl; | |
| 177 | + u32 ctrl, privilege; | |
| 178 | 178 | int i, max_slots, enable; |
| 179 | + struct pt_regs *regs; | |
| 179 | 180 | struct perf_event **slots; |
| 180 | 181 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
| 181 | 182 | |
| 183 | + if (arch_check_bp_in_kernelspace(info)) | |
| 184 | + privilege = CTRL_PLV0_ENABLE; | |
| 185 | + else | |
| 186 | + privilege = CTRL_PLV3_ENABLE; | |
| 187 | + | |
| 188 | + /* Whether bp belongs to a task. */ | |
| 189 | + if (bp->hw.target) | |
| 190 | + regs = task_pt_regs(bp->hw.target); | |
| 191 | + | |
| 182 | 192 | if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { |
| 183 | 193 | /* Breakpoint */ |
| 184 | 194 | slots = this_cpu_ptr(bp_on_reg); |
| @@ -197,31 +207,38 @@ static int hw_breakpoint_control(struct perf_event *bp, · 12 unmodified lines | ||
| 197 | 207 | switch (ops) { |
| 198 | 208 | case HW_BREAKPOINT_INSTALL: |
| 199 | 209 | /* Set the FWPnCFG/MWPnCFG 1~4 register. */ |
| 200 | − write_wb_reg(CSR_CFG_ADDR, i, 0, info->address); | |
| 201 | − write_wb_reg(CSR_CFG_ADDR, i, 1, info->address); | |
| 202 | − write_wb_reg(CSR_CFG_MASK, i, 0, info->mask); | |
| 203 | − write_wb_reg(CSR_CFG_MASK, i, 1, info->mask); | |
| 204 | − write_wb_reg(CSR_CFG_ASID, i, 0, 0); | |
| 205 | − write_wb_reg(CSR_CFG_ASID, i, 1, 0); | |
| 206 | 210 | if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { |
| 207 | − write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE); | |
| 211 | + write_wb_reg(CSR_CFG_ADDR, i, 0, info->address); | |
| 212 | + write_wb_reg(CSR_CFG_MASK, i, 0, info->mask); | |
| 213 | + write_wb_reg(CSR_CFG_ASID, i, 0, 0); | |
| 214 | + write_wb_reg(CSR_CFG_CTRL, i, 0, privilege); | |
| 208 | 215 | } else { |
| 216 | + write_wb_reg(CSR_CFG_ADDR, i, 1, info->address); | |
| 217 | + write_wb_reg(CSR_CFG_MASK, i, 1, info->mask); | |
| 218 | + write_wb_reg(CSR_CFG_ASID, i, 1, 0); | |
| 209 | 219 | ctrl = encode_ctrl_reg(info->ctrl); |
| 210 | − write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | CTRL_PLV_ENABLE); | |
| 220 | + write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | privilege); | |
| 211 | 221 | } |
| 212 | 222 | enable = csr_read64(LOONGARCH_CSR_CRMD); |
| 213 | 223 | csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD); |
| 224 | + if (bp->hw.target) | |
| 225 | + regs->csr_prmd |= CSR_PRMD_PWE; | |
| 214 | 226 | break; |
| 215 | 227 | case HW_BREAKPOINT_UNINSTALL: |
| 216 | 228 | /* Reset the FWPnCFG/MWPnCFG 1~4 register. */ |
| 217 | − write_wb_reg(CSR_CFG_ADDR, i, 0, 0); | |
| 218 | − write_wb_reg(CSR_CFG_ADDR, i, 1, 0); | |
| 219 | − write_wb_reg(CSR_CFG_MASK, i, 0, 0); | |
| 220 | − write_wb_reg(CSR_CFG_MASK, i, 1, 0); | |
| 221 | − write_wb_reg(CSR_CFG_CTRL, i, 0, 0); | |
| 222 | − write_wb_reg(CSR_CFG_CTRL, i, 1, 0); | |
| 223 | − write_wb_reg(CSR_CFG_ASID, i, 0, 0); | |
| 224 | − write_wb_reg(CSR_CFG_ASID, i, 1, 0); | |
| 229 | + if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { | |
| 230 | + write_wb_reg(CSR_CFG_ADDR, i, 0, 0); | |
| 231 | + write_wb_reg(CSR_CFG_MASK, i, 0, 0); | |
| 232 | + write_wb_reg(CSR_CFG_CTRL, i, 0, 0); | |
| 233 | + write_wb_reg(CSR_CFG_ASID, i, 0, 0); | |
| 234 | + } else { | |
| 235 | + write_wb_reg(CSR_CFG_ADDR, i, 1, 0); | |
| 236 | + write_wb_reg(CSR_CFG_MASK, i, 1, 0); | |
| 237 | + write_wb_reg(CSR_CFG_CTRL, i, 1, 0); | |
| 238 | + write_wb_reg(CSR_CFG_ASID, i, 1, 0); | |
| 239 | + } | |
| 240 | + if (bp->hw.target) | |
| 241 | + regs->csr_prmd &= ~CSR_PRMD_PWE; | |
| 225 | 242 | break; |
| 226 | 243 | } |
| 227 | 244 | |
| @@ -283,7 +300,7 @@ int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw) · 55 unmodified lines | ||
| 283 | 300 | * to generic breakpoint descriptions. |
| 284 | 301 | */ |
| 285 | 302 | int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, |
| 286 | − int *gen_len, int *gen_type, int *offset) | |
| 303 | + int *gen_len, int *gen_type) | |
| 287 | 304 | { |
| 288 | 305 | /* Type */ |
| 289 | 306 | switch (ctrl.type) { |
| @@ -303,11 +320,6 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, · 13 unmodified lines | ||
| 303 | 320 | return -EINVAL; |
| 304 | 321 | } |
| 305 | 322 | |
| 306 | − if (!ctrl.len) | |
| 307 | − return -EINVAL; | |
| 308 | − | |
| 309 | − *offset = __ffs(ctrl.len); | |
| 310 | − | |
| 311 | 323 | /* Len */ |
| 312 | 324 | switch (ctrl.len) { |
| 313 | 325 | case LOONGARCH_BREAKPOINT_LEN_1: |
| @@ -386,21 +398,17 @@ int hw_breakpoint_arch_parse(struct perf_event *bp, · 72 unmodified lines | ||
| 386 | 398 | struct arch_hw_breakpoint *hw) |
| 387 | 399 | { |
| 388 | 400 | int ret; |
| 389 | − u64 alignment_mask, offset; | |
| 401 | + u64 alignment_mask; | |
| 390 | 402 | |
| 391 | 403 | /* Build the arch_hw_breakpoint. */ |
| 392 | 404 | ret = arch_build_bp_info(bp, attr, hw); |
| 393 | 405 | if (ret) |
| 394 | 406 | return ret; |
| 395 | 407 | |
| 396 | − if (hw->ctrl.type != LOONGARCH_BREAKPOINT_EXECUTE) | |
| 397 | − alignment_mask = 0x7; | |
| 398 | − else | |
| 408 | + if (hw->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { | |
| 399 | 409 | alignment_mask = 0x3; |
| 400 | − offset = hw->address & alignment_mask; | |
| 401 | − | |
| 402 | − hw->address &= ~alignment_mask; | |
| 403 | − hw->ctrl.len <<= offset; | |
| 410 | + hw->address &= ~alignment_mask; | |
| 411 | + } | |
| 404 | 412 | |
| 405 | 413 | return 0; |
| 406 | 414 | } |
| @@ -471,12 +479,15 @@ void breakpoint_handler(struct pt_regs *regs) · 64 unmodified lines | ||
| 471 | 479 | slots = this_cpu_ptr(bp_on_reg); |
| 472 | 480 | |
| 473 | 481 | for (i = 0; i < boot_cpu_data.watch_ireg_count; ++i) { |
| 474 | − bp = slots[i]; | |
| 475 | − if (bp == NULL) | |
| 476 | − continue; | |
| 477 | − perf_bp_event(bp, regs); | |
| 482 | + if ((csr_read32(LOONGARCH_CSR_FWPS) & (0x1 << i))) { | |
| 483 | + bp = slots[i]; | |
| 484 | + if (bp == NULL) | |
| 485 | + continue; | |
| 486 | + perf_bp_event(bp, regs); | |
| 487 | + csr_write32(0x1 << i, LOONGARCH_CSR_FWPS); | |
| 488 | + update_bp_registers(regs, 0, 0); | |
| 489 | + } | |
| 478 | 490 | } |
| 479 | − update_bp_registers(regs, 0, 0); | |
| 480 | 491 | } |
| 481 | 492 | NOKPROBE_SYMBOL(breakpoint_handler); |
| 482 | 493 | |
| @@ -488,12 +499,15 @@ void watchpoint_handler(struct pt_regs *regs) · 5 unmodified lines | ||
| 488 | 499 | slots = this_cpu_ptr(wp_on_reg); |
| 489 | 500 | |
| 490 | 501 | for (i = 0; i < boot_cpu_data.watch_dreg_count; ++i) { |
| 491 | − wp = slots[i]; | |
| 492 | − if (wp == NULL) | |
| 493 | − continue; | |
| 494 | − perf_bp_event(wp, regs); | |
| 502 | + if ((csr_read32(LOONGARCH_CSR_MWPS) & (0x1 << i))) { | |
| 503 | + wp = slots[i]; | |
| 504 | + if (wp == NULL) | |
| 505 | + continue; | |
| 506 | + perf_bp_event(wp, regs); | |
| 507 | + csr_write32(0x1 << i, LOONGARCH_CSR_MWPS); | |
| 508 | + update_bp_registers(regs, 0, 1); | |
| 509 | + } | |
| 495 | 510 | } |
| 496 | − update_bp_registers(regs, 0, 1); | |
| 497 | 511 | } |
| 498 | 512 | NOKPROBE_SYMBOL(watchpoint_handler); |
| 499 | 513 | |
| @@ -494,28 +494,14 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type, · 493 unmodified lines | ||
| 494 | 494 | struct arch_hw_breakpoint_ctrl ctrl, |
| 495 | 495 | struct perf_event_attr *attr) |
| 496 | 496 | { |
| 497 | − int err, len, type, offset; | |
| 497 | + int err, len, type; | |
| 498 | 498 | |
| 499 | − err = arch_bp_generic_fields(ctrl, &len, &type, &offset); | |
| 499 | + err = arch_bp_generic_fields(ctrl, &len, &type); | |
| 500 | 500 | if (err) |
| 501 | 501 | return err; |
| 502 | 502 | |
| 503 | − switch (note_type) { | |
| 504 | − case NT_LOONGARCH_HW_BREAK: | |
| 505 | − if ((type & HW_BREAKPOINT_X) != type) | |
| 506 | − return -EINVAL; | |
| 507 | − break; | |
| 508 | − case NT_LOONGARCH_HW_WATCH: | |
| 509 | − if ((type & HW_BREAKPOINT_RW) != type) | |
| 510 | − return -EINVAL; | |
| 511 | − break; | |
| 512 | − default: | |
| 513 | − return -EINVAL; | |
| 514 | − } | |
| 515 | − | |
| 516 | 503 | attr->bp_len = len; |
| 517 | 504 | attr->bp_type = type; |
| 518 | − attr->bp_addr += offset; | |
| 519 | 505 | |
| 520 | 506 | return 0; |
| 521 | 507 | } |
| @@ -609,10 +595,27 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type, · 87 unmodified lines | ||
| 609 | 595 | return PTR_ERR(bp); |
| 610 | 596 | |
| 611 | 597 | attr = bp->attr; |
| 612 | − decode_ctrl_reg(uctrl, &ctrl); | |
| 613 | − err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr); | |
| 614 | − if (err) | |
| 615 | − return err; | |
| 598 | + | |
| 599 | + switch (note_type) { | |
| 600 | + case NT_LOONGARCH_HW_BREAK: | |
| 601 | + ctrl.type = LOONGARCH_BREAKPOINT_EXECUTE; | |
| 602 | + ctrl.len = LOONGARCH_BREAKPOINT_LEN_4; | |
| 603 | + break; | |
| 604 | + case NT_LOONGARCH_HW_WATCH: | |
| 605 | + decode_ctrl_reg(uctrl, &ctrl); | |
| 606 | + break; | |
| 607 | + default: | |
| 608 | + return -EINVAL; | |
| 609 | + } | |
| 610 | + | |
| 611 | + if (uctrl & CTRL_PLV_ENABLE) { | |
| 612 | + err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr); | |
| 613 | + if (err) | |
| 614 | + return err; | |
| 615 | + attr.disabled = 0; | |
| 616 | + } else { | |
| 617 | + attr.disabled = 1; | |
| 618 | + } | |
| 616 | 619 | |
| 617 | 620 | return modify_user_hw_breakpoint(bp, &attr); |
| 618 | 621 | } |
| @@ -643,6 +646,10 @@ static int ptrace_hbp_set_addr(unsigned int note_type, · 24 unmodified lines | ||
| 643 | 646 | struct perf_event *bp; |
| 644 | 647 | struct perf_event_attr attr; |
| 645 | 648 | |
| 649 | + /* Kernel-space address cannot be monitored by user-space */ | |
| 650 | + if ((unsigned long)addr >= XKPRANGE) | |
| 651 | + return -EINVAL; | |
| 652 | + | |
| 646 | 653 | bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx); |
| 647 | 654 | if (IS_ERR(bp)) |
| 648 | 655 | return PTR_ERR(bp); |
| @@ -761,7 +761,7 @@ static void kvm_handle_service(struct kvm_vcpu *vcpu) · 760 unmodified lines | ||
| 761 | 761 | default: |
| 762 | 762 | ret = KVM_HCALL_INVALID_CODE; |
| 763 | 763 | break; |
| 764 | − }; | |
| 764 | + } | |
| 765 | 765 | |
| 766 | 766 | kvm_write_reg(vcpu, LOONGARCH_GPR_A0, ret); |
| 767 | 767 | } |
| @@ -110,7 +110,8 @@ static void bcm6358_quirks(void) · 109 unmodified lines | ||
| 110 | 110 | * RAC flush causes kernel panics on BCM6358 when booting from TP1 |
| 111 | 111 | * because the bootloader is not initializing it properly. |
| 112 | 112 | */ |
| 113 | − bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)); | |
| 113 | + bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) || | |
| 114 | + !!BMIPS_GET_CBR(); | |
| 114 | 115 | } |
| 115 | 116 | |
| 116 | 117 | static void bcm6368_quirks(void) |
| @@ -322,7 +322,7 @@ static inline void ehb(void) · 321 unmodified lines | ||
| 322 | 322 | " .set push \n" \ |
| 323 | 323 | " .set "MIPS_ISA_LEVEL" \n" \ |
| 324 | 324 | _ASM_SET_MFTC0 \ |
| 325 | − " mftc0 $1, " #rt ", " #sel " \n" \ | |
| 325 | + " mftc0 %0, " #rt ", " #sel " \n" \ | |
| 326 | 326 | _ASM_UNSET_MFTC0 \ |
| 327 | 327 | " .set pop \n" \ |
| 328 | 328 | : "=r" (__res)); \ |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | 17 o32 break sys_ni_syscall |
| 28 | 28 | # 18 was sys_stat |
| 29 | 29 | 18 o32 unused18 sys_ni_syscall |
| 30 | −19 o32 lseek sys_lseek | |
| 30 | +19 o32 lseek sys_lseek compat_sys_lseek | |
| 31 | 31 | 20 o32 getpid sys_getpid |
| 32 | 32 | 21 o32 mount sys_mount |
| 33 | 33 | 22 o32 umount sys_oldumount |
| @@ -112,8 +112,8 @@ retry: · 111 unmodified lines | ||
| 112 | 112 | * gives them time to settle |
| 113 | 113 | */ |
| 114 | 114 | if (where == PCI_VENDOR_ID) { |
| 115 | − if (ret == 0xffffffff || ret == 0x00000000 || | |
| 116 | − ret == 0x0000ffff || ret == 0xffff0000) { | |
| 115 | + if (*val == 0xffffffff || *val == 0x00000000 || | |
| 116 | + *val == 0x0000ffff || *val == 0xffff0000) { | |
| 117 | 117 | if (delay > 4) |
| 118 | 118 | return 0; |
| 119 | 119 | delay *= 2; |
| @@ -1,3 +1,5 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | aesp10-ppc.S |
| 3 | +aesp8-ppc.S | |
| 3 | 4 | ghashp10-ppc.S |
| 5 | +ghashp8-ppc.S | |
| @@ -130,14 +130,16 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd, · 129 unmodified lines | ||
| 130 | 130 | } |
| 131 | 131 | rcu_read_unlock(); |
| 132 | 132 | |
| 133 | − fdput(f); | |
| 134 | − | |
| 135 | − if (!found) | |
| 133 | + if (!found) { | |
| 134 | + fdput(f); | |
| 136 | 135 | return -EINVAL; |
| 136 | + } | |
| 137 | 137 | |
| 138 | 138 | table_group = iommu_group_get_iommudata(grp); |
| 139 | − if (WARN_ON(!table_group)) | |
| 139 | + if (WARN_ON(!table_group)) { | |
| 140 | + fdput(f); | |
| 140 | 141 | return -EFAULT; |
| 142 | + } | |
| 141 | 143 | |
| 142 | 144 | for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { |
| 143 | 145 | struct iommu_table *tbltmp = table_group->tables[i]; |
| @@ -158,8 +160,10 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd, · 14 unmodified lines | ||
| 158 | 160 | break; |
| 159 | 161 | } |
| 160 | 162 | } |
| 161 | − if (!tbl) | |
| 163 | + if (!tbl) { | |
| 164 | + fdput(f); | |
| 162 | 165 | return -EINVAL; |
| 166 | + } | |
| 163 | 167 | |
| 164 | 168 | rcu_read_lock(); |
| 165 | 169 | list_for_each_entry_rcu(stit, &stt->iommu_tables, next) { |
| @@ -170,6 +174,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd, · 4 unmodified lines | ||
| 170 | 174 | /* stit is being destroyed */ |
| 171 | 175 | iommu_tce_table_put(tbl); |
| 172 | 176 | rcu_read_unlock(); |
| 177 | + fdput(f); | |
| 173 | 178 | return -ENOTTY; |
| 174 | 179 | } |
| 175 | 180 | /* |
| @@ -177,6 +182,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd, · 1 unmodified line | ||
| 177 | 182 | * its KVM reference counter and can return. |
| 178 | 183 | */ |
| 179 | 184 | rcu_read_unlock(); |
| 185 | + fdput(f); | |
| 180 | 186 | return 0; |
| 181 | 187 | } |
| 182 | 188 | rcu_read_unlock(); |
| @@ -184,6 +190,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd, · 1 unmodified line | ||
| 184 | 190 | stit = kzalloc(sizeof(*stit), GFP_KERNEL); |
| 185 | 191 | if (!stit) { |
| 186 | 192 | iommu_tce_table_put(tbl); |
| 193 | + fdput(f); | |
| 187 | 194 | return -ENOMEM; |
| 188 | 195 | } |
| 189 | 196 | |
| @@ -192,6 +199,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd, · 2 unmodified lines | ||
| 192 | 199 | |
| 193 | 200 | list_add_rcu(&stit->next, &stt->iommu_tables); |
| 194 | 201 | |
| 202 | + fdput(f); | |
| 195 | 203 | return 0; |
| 196 | 204 | } |
| 197 | 205 | |
| @@ -45,6 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | no-1-8-v; |
| 46 | 46 | no-mmc; |
| 47 | 47 | no-sdio; |
| 48 | + disable-wp; | |
| 48 | 49 | }; |
| 49 | 50 | |
| 50 | 51 | &uart0 { |
| @@ -401,7 +401,6 @@ extern int __init efi_memmap_alloc(unsigned int num_entries, · 400 unmodified lines | ||
| 401 | 401 | struct efi_memory_map_data *data); |
| 402 | 402 | extern void __efi_memmap_free(u64 phys, unsigned long size, |
| 403 | 403 | unsigned long flags); |
| 404 | −#define __efi_memmap_free __efi_memmap_free | |
| 405 | 404 | |
| 406 | 405 | extern int __init efi_memmap_install(struct efi_memory_map_data *data); |
| 407 | 406 | extern int __init efi_memmap_split_count(efi_memory_desc_t *md, |
| @@ -519,7 +519,8 @@ void free_rmid(u32 closid, u32 rmid) · 518 unmodified lines | ||
| 519 | 519 | * allows architectures that ignore the closid parameter to avoid an |
| 520 | 520 | * unnecessary check. |
| 521 | 521 | */ |
| 522 | − if (idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID, | |
| 522 | + if (!resctrl_arch_mon_capable() || | |
| 523 | + idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID, | |
| 523 | 524 | RESCTRL_RESERVED_RMID)) |
| 524 | 525 | return; |
| 525 | 526 | |
| @@ -2843,7 +2843,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 2842 unmodified lines | ||
| 2843 | 2843 | |
| 2844 | 2844 | if (sev_es_prevent_msr_access(vcpu, msr_info)) { |
| 2845 | 2845 | msr_info->data = 0; |
| 2846 | − return -EINVAL; | |
| 2846 | + return vcpu->kvm->arch.has_protected_state ? -EINVAL : 0; | |
| 2847 | 2847 | } |
| 2848 | 2848 | |
| 2849 | 2849 | switch (msr_info->index) { |
| @@ -2998,7 +2998,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) · 148 unmodified lines | ||
| 2998 | 2998 | u64 data = msr->data; |
| 2999 | 2999 | |
| 3000 | 3000 | if (sev_es_prevent_msr_access(vcpu, msr)) |
| 3001 | − return -EINVAL; | |
| 3001 | + return vcpu->kvm->arch.has_protected_state ? -EINVAL : 0; | |
| 3002 | 3002 | |
| 3003 | 3003 | switch (ecx) { |
| 3004 | 3004 | case MSR_AMD64_TSC_RATIO: |
| @@ -10718,13 +10718,12 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) · 10717 unmodified lines | ||
| 10718 | 10718 | |
| 10719 | 10719 | bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256); |
| 10720 | 10720 | |
| 10721 | + static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 10722 | + | |
| 10721 | 10723 | if (irqchip_split(vcpu->kvm)) |
| 10722 | 10724 | kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); |
| 10723 | − else { | |
| 10724 | − static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 10725 | − if (ioapic_in_kernel(vcpu->kvm)) | |
| 10726 | − kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); | |
| 10727 | − } | |
| 10725 | + else if (ioapic_in_kernel(vcpu->kvm)) | |
| 10726 | + kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); | |
| 10728 | 10727 | |
| 10729 | 10728 | if (is_guest_mode(vcpu)) |
| 10730 | 10729 | vcpu->arch.load_eoi_exitmap_pending = true; |
| @@ -92,12 +92,22 @@ int __init efi_memmap_alloc(unsigned int num_entries, · 91 unmodified lines | ||
| 92 | 92 | */ |
| 93 | 93 | int __init efi_memmap_install(struct efi_memory_map_data *data) |
| 94 | 94 | { |
| 95 | + unsigned long size = efi.memmap.desc_size * efi.memmap.nr_map; | |
| 96 | + unsigned long flags = efi.memmap.flags; | |
| 97 | + u64 phys = efi.memmap.phys_map; | |
| 98 | + int ret; | |
| 99 | + | |
| 95 | 100 | efi_memmap_unmap(); |
| 96 | 101 | |
| 97 | 102 | if (efi_enabled(EFI_PARAVIRT)) |
| 98 | 103 | return 0; |
| 99 | 104 | |
| 100 | − return __efi_memmap_init(data); | |
| 105 | + ret = __efi_memmap_init(data); | |
| 106 | + if (ret) | |
| 107 | + return ret; | |
| 108 | + | |
| 109 | + __efi_memmap_free(phys, size, flags); | |
| 110 | + return 0; | |
| 101 | 111 | } |
| 102 | 112 | |
| 103 | 113 | /** |
| @@ -44,7 +44,6 @@ acpi_ex_system_memory_space_handler(u32 function, · 43 unmodified lines | ||
| 44 | 44 | struct acpi_mem_mapping *mm = mem_info->cur_mm; |
| 45 | 45 | u32 length; |
| 46 | 46 | acpi_size map_length; |
| 47 | − acpi_size page_boundary_map_length; | |
| 48 | 47 | #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED |
| 49 | 48 | u32 remainder; |
| 50 | 49 | #endif |
| @@ -138,26 +137,8 @@ acpi_ex_system_memory_space_handler(u32 function, · 87 unmodified lines | ||
| 138 | 137 | map_length = (acpi_size) |
| 139 | 138 | ((mem_info->address + mem_info->length) - address); |
| 140 | 139 | |
| 141 | − /* | |
| 142 | − * If mapping the entire remaining portion of the region will cross | |
| 143 | − * a page boundary, just map up to the page boundary, do not cross. | |
| 144 | − * On some systems, crossing a page boundary while mapping regions | |
| 145 | − * can cause warnings if the pages have different attributes | |
| 146 | − * due to resource management. | |
| 147 | − * | |
| 148 | − * This has the added benefit of constraining a single mapping to | |
| 149 | − * one page, which is similar to the original code that used a 4k | |
| 150 | − * maximum window. | |
| 151 | − */ | |
| 152 | − page_boundary_map_length = (acpi_size) | |
| 153 | − (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address); | |
| 154 | − if (page_boundary_map_length == 0) { | |
| 155 | − page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE; | |
| 156 | − } | |
| 157 | − | |
| 158 | − if (map_length > page_boundary_map_length) { | |
| 159 | − map_length = page_boundary_map_length; | |
| 160 | − } | |
| 140 | + if (map_length > ACPI_DEFAULT_PAGE_SIZE) | |
| 141 | + map_length = ACPI_DEFAULT_PAGE_SIZE; | |
| 161 | 142 | |
| 162 | 143 | /* Create a new mapping starting at the address given */ |
| 163 | 144 | |
| @@ -302,6 +302,10 @@ void acpi_mipi_check_crs_csi2(acpi_handle handle); · 301 unmodified lines | ||
| 302 | 302 | void acpi_mipi_scan_crs_csi2(void); |
| 303 | 303 | void acpi_mipi_init_crs_csi2_swnodes(void); |
| 304 | 304 | void acpi_mipi_crs_csi2_cleanup(void); |
| 305 | +#ifdef CONFIG_X86 | |
| 305 | 306 | bool acpi_graph_ignore_port(acpi_handle handle); |
| 307 | +#else | |
| 308 | +static inline bool acpi_graph_ignore_port(acpi_handle handle) { return false; } | |
| 309 | +#endif | |
| 306 | 310 | |
| 307 | 311 | #endif /* _ACPI_INTERNAL_H_ */ |
| @@ -725,14 +725,20 @@ void acpi_mipi_crs_csi2_cleanup(void) · 724 unmodified lines | ||
| 725 | 725 | acpi_mipi_del_crs_csi2(csi2); |
| 726 | 726 | } |
| 727 | 727 | |
| 728 | −static const struct dmi_system_id dmi_ignore_port_nodes[] = { | |
| 729 | − { | |
| 730 | − .matches = { | |
| 731 | − DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 732 | − DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 9315"), | |
| 733 | − }, | |
| 734 | − }, | |
| 735 | − { } | |
| 728 | +#ifdef CONFIG_X86 | |
| 729 | +#include <asm/cpu_device_id.h> | |
| 730 | +#include <asm/intel-family.h> | |
| 731 | + | |
| 732 | +/* CPU matches for Dell generations with broken ACPI MIPI DISCO info */ | |
| 733 | +static const struct x86_cpu_id dell_broken_mipi_disco_cpu_gens[] = { | |
| 734 | + X86_MATCH_VFM(INTEL_TIGERLAKE, NULL), | |
| 735 | + X86_MATCH_VFM(INTEL_TIGERLAKE_L, NULL), | |
| 736 | + X86_MATCH_VFM(INTEL_ALDERLAKE, NULL), | |
| 737 | + X86_MATCH_VFM(INTEL_ALDERLAKE_L, NULL), | |
| 738 | + X86_MATCH_VFM(INTEL_RAPTORLAKE, NULL), | |
| 739 | + X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL), | |
| 740 | + X86_MATCH_VFM(INTEL_RAPTORLAKE_S, NULL), | |
| 741 | + {} | |
| 736 | 742 | }; |
| 737 | 743 | |
| 738 | 744 | static const char *strnext(const char *s1, const char *s2) |
| @@ -761,7 +767,10 @@ bool acpi_graph_ignore_port(acpi_handle handle) · 22 unmodified lines | ||
| 761 | 767 | static bool dmi_tested, ignore_port; |
| 762 | 768 | |
| 763 | 769 | if (!dmi_tested) { |
| 764 | − ignore_port = dmi_first_match(dmi_ignore_port_nodes); | |
| 770 | + if (dmi_name_in_vendors("Dell Inc.") && | |
| 771 | + x86_match_cpu(dell_broken_mipi_disco_cpu_gens)) | |
| 772 | + ignore_port = true; | |
| 773 | + | |
| 765 | 774 | dmi_tested = true; |
| 766 | 775 | } |
| 767 | 776 | |
| @@ -794,3 +803,4 @@ out_free: · 26 unmodified lines | ||
| 794 | 803 | kfree(orig_path); |
| 795 | 804 | return false; |
| 796 | 805 | } |
| 806 | +#endif | |
| @@ -1735,6 +1735,14 @@ static void ahci_update_initial_lpm_policy(struct ata_port *ap) · 1734 unmodified lines | ||
| 1735 | 1735 | if (ap->pflags & ATA_PFLAG_EXTERNAL) |
| 1736 | 1736 | return; |
| 1737 | 1737 | |
| 1738 | + /* If no LPM states are supported by the HBA, do not bother with LPM */ | |
| 1739 | + if ((ap->host->flags & ATA_HOST_NO_PART) && | |
| 1740 | + (ap->host->flags & ATA_HOST_NO_SSC) && | |
| 1741 | + (ap->host->flags & ATA_HOST_NO_DEVSLP)) { | |
| 1742 | + ata_port_dbg(ap, "no LPM states supported, not enabling LPM\n"); | |
| 1743 | + return; | |
| 1744 | + } | |
| 1745 | + | |
| 1738 | 1746 | /* user modified policy via module param */ |
| 1739 | 1747 | if (mobile_lpm_policy != -1) { |
| 1740 | 1748 | policy = mobile_lpm_policy; |
| @@ -394,7 +394,7 @@ config LS2X_APB_DMA · 393 unmodified lines | ||
| 394 | 394 | |
| 395 | 395 | config MCF_EDMA |
| 396 | 396 | tristate "Freescale eDMA engine support, ColdFire mcf5441x SoCs" |
| 397 | − depends on M5441x || COMPILE_TEST | |
| 397 | + depends on M5441x || (COMPILE_TEST && FSL_EDMA=n) | |
| 398 | 398 | select DMA_ENGINE |
| 399 | 399 | select DMA_VIRTUAL_CHANNELS |
| 400 | 400 | help |
| @@ -611,11 +611,13 @@ static void irq_process_work_list(struct idxd_irq_entry *irq_entry) · 610 unmodified lines | ||
| 611 | 611 | |
| 612 | 612 | spin_unlock(&irq_entry->list_lock); |
| 613 | 613 | |
| 614 | − list_for_each_entry(desc, &flist, list) { | |
| 614 | + list_for_each_entry_safe(desc, n, &flist, list) { | |
| 615 | 615 | /* |
| 616 | 616 | * Check against the original status as ABORT is software defined |
| 617 | 617 | * and 0xff, which DSA_COMP_STATUS_MASK can mask out. |
| 618 | 618 | */ |
| 619 | + list_del(&desc->list); | |
| 620 | + | |
| 619 | 621 | if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) { |
| 620 | 622 | idxd_desc_complete(desc, IDXD_COMPLETE_ABORT, true); |
| 621 | 623 | continue; |
| @@ -534,18 +534,6 @@ err_out: · 533 unmodified lines | ||
| 534 | 534 | return err; |
| 535 | 535 | } |
| 536 | 536 | |
| 537 | −static int ioat_register(struct ioatdma_device *ioat_dma) | |
| 538 | −{ | |
| 539 | − int err = dma_async_device_register(&ioat_dma->dma_dev); | |
| 540 | − | |
| 541 | − if (err) { | |
| 542 | − ioat_disable_interrupts(ioat_dma); | |
| 543 | − dma_pool_destroy(ioat_dma->completion_pool); | |
| 544 | − } | |
| 545 | − | |
| 546 | − return err; | |
| 547 | −} | |
| 548 | − | |
| 549 | 537 | static void ioat_dma_remove(struct ioatdma_device *ioat_dma) |
| 550 | 538 | { |
| 551 | 539 | struct dma_device *dma = &ioat_dma->dma_dev; |
| @@ -1181,9 +1169,9 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca) · 629 unmodified lines | ||
| 1181 | 1169 | ioat_chan->reg_base + IOAT_DCACTRL_OFFSET); |
| 1182 | 1170 | } |
| 1183 | 1171 | |
| 1184 | − err = ioat_register(ioat_dma); | |
| 1172 | + err = dma_async_device_register(&ioat_dma->dma_dev); | |
| 1185 | 1173 | if (err) |
| 1186 | − return err; | |
| 1174 | + goto err_disable_interrupts; | |
| 1187 | 1175 | |
| 1188 | 1176 | ioat_kobject_add(ioat_dma, &ioat_ktype); |
| 1189 | 1177 | |
| @@ -1192,20 +1180,29 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca) · 2 unmodified lines | ||
| 1192 | 1180 | |
| 1193 | 1181 | /* disable relaxed ordering */ |
| 1194 | 1182 | err = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &val16); |
| 1195 | − if (err) | |
| 1196 | − return pcibios_err_to_errno(err); | |
| 1183 | + if (err) { | |
| 1184 | + err = pcibios_err_to_errno(err); | |
| 1185 | + goto err_disable_interrupts; | |
| 1186 | + } | |
| 1197 | 1187 | |
| 1198 | 1188 | /* clear relaxed ordering enable */ |
| 1199 | 1189 | val16 &= ~PCI_EXP_DEVCTL_RELAX_EN; |
| 1200 | 1190 | err = pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, val16); |
| 1201 | − if (err) | |
| 1202 | − return pcibios_err_to_errno(err); | |
| 1191 | + if (err) { | |
| 1192 | + err = pcibios_err_to_errno(err); | |
| 1193 | + goto err_disable_interrupts; | |
| 1194 | + } | |
| 1203 | 1195 | |
| 1204 | 1196 | if (ioat_dma->cap & IOAT_CAP_DPS) |
| 1205 | 1197 | writeb(ioat_pending_level + 1, |
| 1206 | 1198 | ioat_dma->reg_base + IOAT_PREFETCH_LIMIT_OFFSET); |
| 1207 | 1199 | |
| 1208 | 1200 | return 0; |
| 1201 | + | |
| 1202 | +err_disable_interrupts: | |
| 1203 | + ioat_disable_interrupts(ioat_dma); | |
| 1204 | + dma_pool_destroy(ioat_dma->completion_pool); | |
| 1205 | + return err; | |
| 1209 | 1206 | } |
| 1210 | 1207 | |
| 1211 | 1208 | static void ioat_shutdown(struct pci_dev *pdev) |
| @@ -1350,6 +1347,8 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 138 unmodified lines | ||
| 1350 | 1347 | void __iomem * const *iomap; |
| 1351 | 1348 | struct device *dev = &pdev->dev; |
| 1352 | 1349 | struct ioatdma_device *device; |
| 1350 | + unsigned int i; | |
| 1351 | + u8 version; | |
| 1353 | 1352 | int err; |
| 1354 | 1353 | |
| 1355 | 1354 | err = pcim_enable_device(pdev); |
| @@ -1363,6 +1362,10 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 7 unmodified lines | ||
| 1363 | 1362 | if (!iomap) |
| 1364 | 1363 | return -ENOMEM; |
| 1365 | 1364 | |
| 1365 | + version = readb(iomap[IOAT_MMIO_BAR] + IOAT_VER_OFFSET); | |
| 1366 | + if (version < IOAT_VER_3_0) | |
| 1367 | + return -ENODEV; | |
| 1368 | + | |
| 1366 | 1369 | err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |
| 1367 | 1370 | if (err) |
| 1368 | 1371 | return err; |
| @@ -1373,17 +1376,18 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 4 unmodified lines | ||
| 1373 | 1376 | pci_set_master(pdev); |
| 1374 | 1377 | pci_set_drvdata(pdev, device); |
| 1375 | 1378 | |
| 1376 | − device->version = readb(device->reg_base + IOAT_VER_OFFSET); | |
| 1379 | + device->version = version; | |
| 1377 | 1380 | if (device->version >= IOAT_VER_3_4) |
| 1378 | 1381 | ioat_dca_enabled = 0; |
| 1379 | − if (device->version >= IOAT_VER_3_0) { | |
| 1380 | − if (is_skx_ioat(pdev)) | |
| 1381 | − device->version = IOAT_VER_3_2; | |
| 1382 | − err = ioat3_dma_probe(device, ioat_dca_enabled); | |
| 1383 | − } else | |
| 1384 | − return -ENODEV; | |
| 1385 | 1382 | |
| 1383 | + if (is_skx_ioat(pdev)) | |
| 1384 | + device->version = IOAT_VER_3_2; | |
| 1385 | + | |
| 1386 | + err = ioat3_dma_probe(device, ioat_dca_enabled); | |
| 1386 | 1387 | if (err) { |
| 1388 | + for (i = 0; i < IOAT_MAX_CHANS; i++) | |
| 1389 | + kfree(device->idx[i]); | |
| 1390 | + kfree(device); | |
| 1387 | 1391 | dev_err(dev, "Intel(R) I/OAT DMA Engine init failed\n"); |
| 1388 | 1392 | return -ENODEV; |
| 1389 | 1393 | } |
| @@ -1445,6 +1449,7 @@ module_init(ioat_init_module); · 55 unmodified lines | ||
| 1445 | 1449 | static void __exit ioat_exit_module(void) |
| 1446 | 1450 | { |
| 1447 | 1451 | pci_unregister_driver(&ioat_pci_driver); |
| 1452 | + kmem_cache_destroy(ioat_sed_cache); | |
| 1448 | 1453 | kmem_cache_destroy(ioat_cache); |
| 1449 | 1454 | } |
| 1450 | 1455 | module_exit(ioat_exit_module); |
| @@ -200,12 +200,9 @@ of_k3_udma_glue_parse_chn_by_id(struct device_node *udmax_np, struct k3_udma_glu · 199 unmodified lines | ||
| 200 | 200 | |
| 201 | 201 | ret = of_k3_udma_glue_parse(udmax_np, common); |
| 202 | 202 | if (ret) |
| 203 | − goto out_put_spec; | |
| 203 | + return ret; | |
| 204 | 204 | |
| 205 | 205 | ret = of_k3_udma_glue_parse_chn_common(common, thread_id, tx_chn); |
| 206 | − | |
| 207 | −out_put_spec: | |
| 208 | − of_node_put(udmax_np); | |
| 209 | 206 | return ret; |
| 210 | 207 | } |
| 211 | 208 | |
| @@ -885,11 +885,11 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id) · 884 unmodified lines | ||
| 885 | 885 | u32 st; |
| 886 | 886 | bool repeat_tx; |
| 887 | 887 | |
| 888 | + spin_lock(&xchan->vchan.lock); | |
| 889 | + | |
| 888 | 890 | if (xchan->stop_requested) |
| 889 | 891 | complete(&xchan->last_interrupt); |
| 890 | 892 | |
| 891 | − spin_lock(&xchan->vchan.lock); | |
| 892 | − | |
| 893 | 893 | /* get submitted request */ |
| 894 | 894 | vd = vchan_next_desc(&xchan->vchan); |
| 895 | 895 | if (!vd) |
| @@ -15,10 +15,6 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <asm/early_ioremap.h> |
| 16 | 16 | #include <asm/efi.h> |
| 17 | 17 | |
| 18 | −#ifndef __efi_memmap_free | |
| 19 | −#define __efi_memmap_free(phys, size, flags) do { } while (0) | |
| 20 | −#endif | |
| 21 | − | |
| 22 | 18 | /** |
| 23 | 19 | * __efi_memmap_init - Common code for mapping the EFI memory map |
| 24 | 20 | * @data: EFI memory map data |
| @@ -51,11 +47,6 @@ int __init __efi_memmap_init(struct efi_memory_map_data *data) · 26 unmodified lines | ||
| 51 | 47 | return -ENOMEM; |
| 52 | 48 | } |
| 53 | 49 | |
| 54 | − if (efi.memmap.flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB)) | |
| 55 | − __efi_memmap_free(efi.memmap.phys_map, | |
| 56 | − efi.memmap.desc_size * efi.memmap.nr_map, | |
| 57 | − efi.memmap.flags); | |
| 58 | − | |
| 59 | 50 | map.phys_map = data->phys_map; |
| 60 | 51 | map.nr_map = data->size / data->desc_size; |
| 61 | 52 | map.map_end = map.map + data->size; |
| @@ -497,10 +497,12 @@ int psci_cpu_suspend_enter(u32 state) · 496 unmodified lines | ||
| 497 | 497 | |
| 498 | 498 | static int psci_system_suspend(unsigned long unused) |
| 499 | 499 | { |
| 500 | + int err; | |
| 500 | 501 | phys_addr_t pa_cpu_resume = __pa_symbol(cpu_resume); |
| 501 | 502 | |
| 502 | − return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), | |
| 503 | + err = invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), | |
| 503 | 504 | pa_cpu_resume, 0, 0); |
| 505 | + return psci_to_linux_errno(err); | |
| 504 | 506 | } |
| 505 | 507 | |
| 506 | 508 | static int psci_system_suspend_enter(suspend_state_t state) |
| @@ -41,8 +41,6 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <linux/dma-buf.h> |
| 42 | 42 | #include <linux/dma-fence-array.h> |
| 43 | 43 | #include <linux/pci-p2pdma.h> |
| 44 | −#include <linux/pm_runtime.h> | |
| 45 | −#include "amdgpu_trace.h" | |
| 46 | 44 | |
| 47 | 45 | /** |
| 48 | 46 | * amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation |
| @@ -58,42 +56,11 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, · 9 unmodified lines | ||
| 58 | 56 | struct drm_gem_object *obj = dmabuf->priv; |
| 59 | 57 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); |
| 60 | 58 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); |
| 61 | − int r; | |
| 62 | 59 | |
| 63 | 60 | if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) |
| 64 | 61 | attach->peer2peer = false; |
| 65 | 62 | |
| 66 | − r = pm_runtime_get_sync(adev_to_drm(adev)->dev); | |
| 67 | − trace_amdgpu_runpm_reference_dumps(1, __func__); | |
| 68 | − if (r < 0) | |
| 69 | − goto out; | |
| 70 | − | |
| 71 | 63 | return 0; |
| 72 | − | |
| 73 | −out: | |
| 74 | − pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); | |
| 75 | − trace_amdgpu_runpm_reference_dumps(0, __func__); | |
| 76 | − return r; | |
| 77 | −} | |
| 78 | − | |
| 79 | −/** | |
| 80 | − * amdgpu_dma_buf_detach - &dma_buf_ops.detach implementation | |
| 81 | − * | |
| 82 | − * @dmabuf: DMA-buf where we remove the attachment from | |
| 83 | − * @attach: the attachment to remove | |
| 84 | − * | |
| 85 | − * Called when an attachment is removed from the DMA-buf. | |
| 86 | − */ | |
| 87 | −static void amdgpu_dma_buf_detach(struct dma_buf *dmabuf, | |
| 88 | − struct dma_buf_attachment *attach) | |
| 89 | −{ | |
| 90 | − struct drm_gem_object *obj = dmabuf->priv; | |
| 91 | − struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); | |
| 92 | − struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); | |
| 93 | − | |
| 94 | − pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); | |
| 95 | − pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); | |
| 96 | − trace_amdgpu_runpm_reference_dumps(0, __func__); | |
| 97 | 64 | } |
| 98 | 65 | |
| 99 | 66 | /** |
| @@ -267,7 +234,6 @@ static int amdgpu_dma_buf_begin_cpu_access(struct dma_buf *dma_buf, · 167 unmodified lines | ||
| 267 | 234 | |
| 268 | 235 | const struct dma_buf_ops amdgpu_dmabuf_ops = { |
| 269 | 236 | .attach = amdgpu_dma_buf_attach, |
| 270 | − .detach = amdgpu_dma_buf_detach, | |
| 271 | 237 | .pin = amdgpu_dma_buf_pin, |
| 272 | 238 | .unpin = amdgpu_dma_buf_unpin, |
| 273 | 239 | .map_dma_buf = amdgpu_dma_buf_map, |
| @@ -181,7 +181,6 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, struct amd · 180 unmodified lines | ||
| 181 | 181 | amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, |
| 182 | 182 | seq, flags | AMDGPU_FENCE_FLAG_INT); |
| 183 | 183 | pm_runtime_get_noresume(adev_to_drm(adev)->dev); |
| 184 | − trace_amdgpu_runpm_reference_dumps(1, __func__); | |
| 185 | 184 | ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask]; |
| 186 | 185 | if (unlikely(rcu_dereference_protected(*ptr, 1))) { |
| 187 | 186 | struct dma_fence *old; |
| @@ -309,7 +308,6 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring) · 121 unmodified lines | ||
| 309 | 308 | dma_fence_put(fence); |
| 310 | 309 | pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); |
| 311 | 310 | pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); |
| 312 | − trace_amdgpu_runpm_reference_dumps(0, __func__); | |
| 313 | 311 | } while (last_seq != seq); |
| 314 | 312 | |
| 315 | 313 | return true; |
| @@ -684,12 +684,17 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, · 683 unmodified lines | ||
| 684 | 684 | struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring; |
| 685 | 685 | struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst]; |
| 686 | 686 | unsigned int ndw; |
| 687 | − signed long r; | |
| 687 | + int r; | |
| 688 | 688 | uint32_t seq; |
| 689 | 689 | |
| 690 | − if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready || | |
| 691 | − !down_read_trylock(&adev->reset_domain->sem)) { | |
| 690 | + /* | |
| 691 | + * A GPU reset should flush all TLBs anyway, so no need to do | |
| 692 | + * this while one is ongoing. | |
| 693 | + */ | |
| 694 | + if (!down_read_trylock(&adev->reset_domain->sem)) | |
| 695 | + return 0; | |
| 692 | 696 | |
| 697 | + if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) { | |
| 693 | 698 | if (adev->gmc.flush_tlb_needs_extra_type_2) |
| 694 | 699 | adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid, |
| 695 | 700 | 2, all_hub, |
| @@ -703,43 +708,40 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, · 7 unmodified lines | ||
| 703 | 708 | adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid, |
| 704 | 709 | flush_type, all_hub, |
| 705 | 710 | inst); |
| 706 | − return 0; | |
| 707 | − } | |
| 711 | + r = 0; | |
| 712 | + } else { | |
| 713 | + /* 2 dwords flush + 8 dwords fence */ | |
| 714 | + ndw = kiq->pmf->invalidate_tlbs_size + 8; | |
| 708 | 715 | |
| 709 | − /* 2 dwords flush + 8 dwords fence */ | |
| 710 | − ndw = kiq->pmf->invalidate_tlbs_size + 8; | |
| 716 | + if (adev->gmc.flush_tlb_needs_extra_type_2) | |
| 717 | + ndw += kiq->pmf->invalidate_tlbs_size; | |
| 711 | 718 | |
| 712 | − if (adev->gmc.flush_tlb_needs_extra_type_2) | |
| 713 | − ndw += kiq->pmf->invalidate_tlbs_size; | |
| 719 | + if (adev->gmc.flush_tlb_needs_extra_type_0) | |
| 720 | + ndw += kiq->pmf->invalidate_tlbs_size; | |
| 714 | 721 | |
| 715 | − if (adev->gmc.flush_tlb_needs_extra_type_0) | |
| 716 | − ndw += kiq->pmf->invalidate_tlbs_size; | |
| 722 | + spin_lock(&adev->gfx.kiq[inst].ring_lock); | |
| 723 | + amdgpu_ring_alloc(ring, ndw); | |
| 724 | + if (adev->gmc.flush_tlb_needs_extra_type_2) | |
| 725 | + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub); | |
| 717 | 726 | |
| 718 | − spin_lock(&adev->gfx.kiq[inst].ring_lock); | |
| 719 | − amdgpu_ring_alloc(ring, ndw); | |
| 720 | − if (adev->gmc.flush_tlb_needs_extra_type_2) | |
| 721 | − kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub); | |
| 727 | + if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0) | |
| 728 | + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub); | |
| 722 | 729 | |
| 723 | − if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0) | |
| 724 | − kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub); | |
| 730 | + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub); | |
| 731 | + r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT); | |
| 732 | + if (r) { | |
| 733 | + amdgpu_ring_undo(ring); | |
| 734 | + spin_unlock(&adev->gfx.kiq[inst].ring_lock); | |
| 735 | + goto error_unlock_reset; | |
| 736 | + } | |
| 725 | 737 | |
| 726 | − kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub); | |
| 727 | − r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT); | |
| 728 | − if (r) { | |
| 729 | − amdgpu_ring_undo(ring); | |
| 738 | + amdgpu_ring_commit(ring); | |
| 730 | 739 | spin_unlock(&adev->gfx.kiq[inst].ring_lock); |
| 731 | − goto error_unlock_reset; | |
| 732 | − } | |
| 733 | − | |
| 734 | − amdgpu_ring_commit(ring); | |
| 735 | − spin_unlock(&adev->gfx.kiq[inst].ring_lock); | |
| 736 | − r = amdgpu_fence_wait_polling(ring, seq, usec_timeout); | |
| 737 | − if (r < 1) { | |
| 738 | − dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r); | |
| 739 | − r = -ETIME; | |
| 740 | − goto error_unlock_reset; | |
| 740 | + if (amdgpu_fence_wait_polling(ring, seq, usec_timeout) < 1) { | |
| 741 | + dev_err(adev->dev, "timeout waiting for kiq fence\n"); | |
| 742 | + r = -ETIME; | |
| 743 | + } | |
| 741 | 744 | } |
| 742 | − r = 0; | |
| 743 | 745 | |
| 744 | 746 | error_unlock_reset: |
| 745 | 747 | up_read(&adev->reset_domain->sem); |
| @@ -554,21 +554,6 @@ TRACE_EVENT(amdgpu_reset_reg_dumps, · 553 unmodified lines | ||
| 554 | 554 | __entry->value) |
| 555 | 555 | ); |
| 556 | 556 | |
| 557 | −TRACE_EVENT(amdgpu_runpm_reference_dumps, | |
| 558 | − TP_PROTO(uint32_t index, const char *func), | |
| 559 | − TP_ARGS(index, func), | |
| 560 | − TP_STRUCT__entry( | |
| 561 | − __field(uint32_t, index) | |
| 562 | − __string(func, func) | |
| 563 | − ), | |
| 564 | − TP_fast_assign( | |
| 565 | − __entry->index = index; | |
| 566 | − __assign_str(func); | |
| 567 | − ), | |
| 568 | − TP_printk("amdgpu runpm reference dump 0x%x: 0x%s\n", | |
| 569 | − __entry->index, | |
| 570 | − __get_str(func)) | |
| 571 | −); | |
| 572 | 557 | #undef AMDGPU_JOB_GET_TIMELINE_NAME |
| 573 | 558 | #endif |
| 574 | 559 | |
| @@ -4195,9 +4195,10 @@ static u32 gfx_v9_4_3_get_cu_active_bitmap(struct amdgpu_device *adev, int xcc_i · 4194 unmodified lines | ||
| 4195 | 4195 | static int gfx_v9_4_3_get_cu_info(struct amdgpu_device *adev, |
| 4196 | 4196 | struct amdgpu_cu_info *cu_info) |
| 4197 | 4197 | { |
| 4198 | − int i, j, k, counter, xcc_id, active_cu_number = 0; | |
| 4199 | − u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; | |
| 4198 | + int i, j, k, prev_counter, counter, xcc_id, active_cu_number = 0; | |
| 4199 | + u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0, tmp; | |
| 4200 | 4200 | unsigned disable_masks[4 * 4]; |
| 4201 | + bool is_symmetric_cus; | |
| 4201 | 4202 | |
| 4202 | 4203 | if (!adev || !cu_info) |
| 4203 | 4204 | return -EINVAL; |
| @@ -4215,6 +4216,7 @@ static int gfx_v9_4_3_get_cu_info(struct amdgpu_device *adev, · 11 unmodified lines | ||
| 4215 | 4216 | |
| 4216 | 4217 | mutex_lock(&adev->grbm_idx_mutex); |
| 4217 | 4218 | for (xcc_id = 0; xcc_id < NUM_XCC(adev->gfx.xcc_mask); xcc_id++) { |
| 4219 | + is_symmetric_cus = true; | |
| 4218 | 4220 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { |
| 4219 | 4221 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { |
| 4220 | 4222 | mask = 1; |
| @@ -4242,6 +4244,15 @@ static int gfx_v9_4_3_get_cu_info(struct amdgpu_device *adev, · 21 unmodified lines | ||
| 4242 | 4244 | ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); |
| 4243 | 4245 | cu_info->ao_cu_bitmap[i][j] = ao_bitmap; |
| 4244 | 4246 | } |
| 4247 | + if (i && is_symmetric_cus && prev_counter != counter) | |
| 4248 | + is_symmetric_cus = false; | |
| 4249 | + prev_counter = counter; | |
| 4250 | + } | |
| 4251 | + if (is_symmetric_cus) { | |
| 4252 | + tmp = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_CPC_DEBUG); | |
| 4253 | + tmp = REG_SET_FIELD(tmp, CP_CPC_DEBUG, CPC_HARVESTING_RELAUNCH_DISABLE, 1); | |
| 4254 | + tmp = REG_SET_FIELD(tmp, CP_CPC_DEBUG, CPC_HARVESTING_DISPATCH_DISABLE, 1); | |
| 4255 | + WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_CPC_DEBUG, tmp); | |
| 4245 | 4256 | } |
| 4246 | 4257 | gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, |
| 4247 | 4258 | xcc_id); |
| @@ -154,18 +154,18 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, · 153 unmodified lines | ||
| 154 | 154 | void *pkt, int size, |
| 155 | 155 | int api_status_off) |
| 156 | 156 | { |
| 157 | − int ndw = size / 4; | |
| 158 | − signed long r; | |
| 159 | − union MESAPI__MISC *x_pkt = pkt; | |
| 160 | − struct MES_API_STATUS *api_status; | |
| 157 | + union MESAPI__QUERY_MES_STATUS mes_status_pkt; | |
| 158 | + signed long timeout = 3000000; /* 3000 ms */ | |
| 161 | 159 | struct amdgpu_device *adev = mes->adev; |
| 162 | 160 | struct amdgpu_ring *ring = &mes->ring; |
| 163 | − unsigned long flags; | |
| 164 | − signed long timeout = 3000000; /* 3000 ms */ | |
| 161 | + struct MES_API_STATUS *api_status; | |
| 162 | + union MESAPI__MISC *x_pkt = pkt; | |
| 165 | 163 | const char *op_str, *misc_op_str; |
| 166 | − u32 fence_offset; | |
| 167 | − u64 fence_gpu_addr; | |
| 168 | − u64 *fence_ptr; | |
| 164 | + unsigned long flags; | |
| 165 | + u64 status_gpu_addr; | |
| 166 | + u32 status_offset; | |
| 167 | + u64 *status_ptr; | |
| 168 | + signed long r; | |
| 169 | 169 | int ret; |
| 170 | 170 | |
| 171 | 171 | if (x_pkt->header.opcode >= MES_SCH_API_MAX) |
| @@ -177,28 +177,38 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, · 5 unmodified lines | ||
| 177 | 177 | /* Worst case in sriov where all other 15 VF timeout, each VF needs about 600ms */ |
| 178 | 178 | timeout = 15 * 600 * 1000; |
| 179 | 179 | } |
| 180 | − BUG_ON(size % 4 != 0); | |
| 181 | 180 | |
| 182 | − ret = amdgpu_device_wb_get(adev, &fence_offset); | |
| 181 | + ret = amdgpu_device_wb_get(adev, &status_offset); | |
| 183 | 182 | if (ret) |
| 184 | 183 | return ret; |
| 185 | − fence_gpu_addr = | |
| 186 | − adev->wb.gpu_addr + (fence_offset * 4); | |
| 187 | − fence_ptr = (u64 *)&adev->wb.wb[fence_offset]; | |
| 188 | − *fence_ptr = 0; | |
| 184 | + | |
| 185 | + status_gpu_addr = adev->wb.gpu_addr + (status_offset * 4); | |
| 186 | + status_ptr = (u64 *)&adev->wb.wb[status_offset]; | |
| 187 | + *status_ptr = 0; | |
| 189 | 188 | |
| 190 | 189 | spin_lock_irqsave(&mes->ring_lock, flags); |
| 191 | − if (amdgpu_ring_alloc(ring, ndw)) { | |
| 192 | − spin_unlock_irqrestore(&mes->ring_lock, flags); | |
| 193 | − amdgpu_device_wb_free(adev, fence_offset); | |
| 194 | − return -ENOMEM; | |
| 195 | − } | |
| 190 | + r = amdgpu_ring_alloc(ring, (size + sizeof(mes_status_pkt)) / 4); | |
| 191 | + if (r) | |
| 192 | + goto error_unlock_free; | |
| 196 | 193 | |
| 197 | 194 | api_status = (struct MES_API_STATUS *)((char *)pkt + api_status_off); |
| 198 | − api_status->api_completion_fence_addr = fence_gpu_addr; | |
| 195 | + api_status->api_completion_fence_addr = status_gpu_addr; | |
| 199 | 196 | api_status->api_completion_fence_value = 1; |
| 200 | 197 | |
| 201 | − amdgpu_ring_write_multiple(ring, pkt, ndw); | |
| 198 | + amdgpu_ring_write_multiple(ring, pkt, size / 4); | |
| 199 | + | |
| 200 | + memset(&mes_status_pkt, 0, sizeof(mes_status_pkt)); | |
| 201 | + mes_status_pkt.header.type = MES_API_TYPE_SCHEDULER; | |
| 202 | + mes_status_pkt.header.opcode = MES_SCH_API_QUERY_SCHEDULER_STATUS; | |
| 203 | + mes_status_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS; | |
| 204 | + mes_status_pkt.api_status.api_completion_fence_addr = | |
| 205 | + ring->fence_drv.gpu_addr; | |
| 206 | + mes_status_pkt.api_status.api_completion_fence_value = | |
| 207 | + ++ring->fence_drv.sync_seq; | |
| 208 | + | |
| 209 | + amdgpu_ring_write_multiple(ring, &mes_status_pkt, | |
| 210 | + sizeof(mes_status_pkt) / 4); | |
| 211 | + | |
| 202 | 212 | amdgpu_ring_commit(ring); |
| 203 | 213 | spin_unlock_irqrestore(&mes->ring_lock, flags); |
| 204 | 214 | |
| @@ -206,15 +216,16 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, · 1 unmodified line | ||
| 206 | 216 | misc_op_str = mes_v11_0_get_misc_op_string(x_pkt); |
| 207 | 217 | |
| 208 | 218 | if (misc_op_str) |
| 209 | − dev_dbg(adev->dev, "MES msg=%s (%s) was emitted\n", op_str, misc_op_str); | |
| 219 | + dev_dbg(adev->dev, "MES msg=%s (%s) was emitted\n", op_str, | |
| 220 | + misc_op_str); | |
| 210 | 221 | else if (op_str) |
| 211 | 222 | dev_dbg(adev->dev, "MES msg=%s was emitted\n", op_str); |
| 212 | 223 | else |
| 213 | − dev_dbg(adev->dev, "MES msg=%d was emitted\n", x_pkt->header.opcode); | |
| 224 | + dev_dbg(adev->dev, "MES msg=%d was emitted\n", | |
| 225 | + x_pkt->header.opcode); | |
| 214 | 226 | |
| 215 | − r = amdgpu_mes_fence_wait_polling(fence_ptr, (u64)1, timeout); | |
| 216 | − amdgpu_device_wb_free(adev, fence_offset); | |
| 217 | − if (r < 1) { | |
| 227 | + r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq, timeout); | |
| 228 | + if (r < 1 || !*status_ptr) { | |
| 218 | 229 | |
| 219 | 230 | if (misc_op_str) |
| 220 | 231 | dev_err(adev->dev, "MES failed to respond to msg=%s (%s)\n", |
| @@ -229,10 +240,19 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, · 8 unmodified lines | ||
| 229 | 240 | while (halt_if_hws_hang) |
| 230 | 241 | schedule(); |
| 231 | 242 | |
| 232 | − return -ETIMEDOUT; | |
| 243 | + r = -ETIMEDOUT; | |
| 244 | + goto error_wb_free; | |
| 233 | 245 | } |
| 234 | 246 | |
| 247 | + amdgpu_device_wb_free(adev, status_offset); | |
| 235 | 248 | return 0; |
| 249 | + | |
| 250 | +error_unlock_free: | |
| 251 | + spin_unlock_irqrestore(&mes->ring_lock, flags); | |
| 252 | + | |
| 253 | +error_wb_free: | |
| 254 | + amdgpu_device_wb_free(adev, status_offset); | |
| 255 | + return r; | |
| 236 | 256 | } |
| 237 | 257 | |
| 238 | 258 | static int convert_to_mes_queue_type(int queue_type) |
| @@ -32,7 +32,9 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "mp/mp_14_0_2_sh_mask.h" |
| 33 | 33 | |
| 34 | 34 | MODULE_FIRMWARE("amdgpu/psp_14_0_2_sos.bin"); |
| 35 | +MODULE_FIRMWARE("amdgpu/psp_14_0_2_ta.bin"); | |
| 35 | 36 | MODULE_FIRMWARE("amdgpu/psp_14_0_3_sos.bin"); |
| 37 | +MODULE_FIRMWARE("amdgpu/psp_14_0_3_ta.bin"); | |
| 36 | 38 | |
| 37 | 39 | /* For large FW files the time to complete can be very long */ |
| 38 | 40 | #define USBC_PD_POLLING_LIMIT_S 240 |
| @@ -64,6 +66,9 @@ static int psp_v14_0_init_microcode(struct psp_context *psp) · 25 unmodified lines | ||
| 64 | 66 | case IP_VERSION(14, 0, 2): |
| 65 | 67 | case IP_VERSION(14, 0, 3): |
| 66 | 68 | err = psp_init_sos_microcode(psp, ucode_prefix); |
| 69 | + if (err) | |
| 70 | + return err; | |
| 71 | + err = psp_init_ta_microcode(psp, ucode_prefix); | |
| 67 | 72 | if (err) |
| 68 | 73 | return err; |
| 69 | 74 | break; |
| @@ -8,7 +8,7 @@ config DRM_AMD_DC · 7 unmodified lines | ||
| 8 | 8 | depends on BROKEN || !CC_IS_CLANG || ARM64 || RISCV || SPARC64 || X86_64 |
| 9 | 9 | select SND_HDA_COMPONENT if SND_HDA_CORE |
| 10 | 10 | # !CC_IS_CLANG: https://github.com/ClangBuiltLinux/linux/issues/1752 |
| 11 | − select DRM_AMD_DC_FP if ARCH_HAS_KERNEL_FPU_SUPPORT && (!ARM64 || !CC_IS_CLANG) | |
| 11 | + select DRM_AMD_DC_FP if ARCH_HAS_KERNEL_FPU_SUPPORT && !(CC_IS_CLANG && (ARM64 || RISCV)) | |
| 12 | 12 | help |
| 13 | 13 | Choose this option if you want to use the new display engine |
| 14 | 14 | support for AMDGPU. This adds required support for Vega and |
| @@ -9169,9 +9169,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 9168 unmodified lines | ||
| 9169 | 9169 | |
| 9170 | 9170 | trace_amdgpu_dm_atomic_commit_tail_begin(state); |
| 9171 | 9171 | |
| 9172 | − if (dm->dc->caps.ips_support && dm->dc->idle_optimizations_allowed) | |
| 9173 | − dc_allow_idle_optimizations(dm->dc, false); | |
| 9174 | − | |
| 9175 | 9172 | drm_atomic_helper_update_legacy_modeset_state(dev, state); |
| 9176 | 9173 | drm_dp_mst_atomic_wait_for_dependencies(state); |
| 9177 | 9174 | |
| @@ -11440,6 +11437,12 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev) · 2262 unmodified lines | ||
| 11440 | 11437 | mutex_unlock(&adev->dm.dc_lock); |
| 11441 | 11438 | } |
| 11442 | 11439 | |
| 11440 | +static inline void amdgpu_dm_exit_ips_for_hw_access(struct dc *dc) | |
| 11441 | +{ | |
| 11442 | + if (dc->ctx->dmub_srv && !dc->ctx->dmub_srv->idle_exit_counter) | |
| 11443 | + dc_exit_ips_for_hw_access(dc); | |
| 11444 | +} | |
| 11445 | + | |
| 11443 | 11446 | void dm_write_reg_func(const struct dc_context *ctx, uint32_t address, |
| 11444 | 11447 | u32 value, const char *func_name) |
| 11445 | 11448 | { |
| @@ -11450,6 +11453,8 @@ void dm_write_reg_func(const struct dc_context *ctx, uint32_t address, · 4 unmodified lines | ||
| 11450 | 11453 | return; |
| 11451 | 11454 | } |
| 11452 | 11455 | #endif |
| 11456 | + | |
| 11457 | + amdgpu_dm_exit_ips_for_hw_access(ctx->dc); | |
| 11453 | 11458 | cgs_write_register(ctx->cgs_device, address, value); |
| 11454 | 11459 | trace_amdgpu_dc_wreg(&ctx->perf_trace->write_count, address, value); |
| 11455 | 11460 | } |
| @@ -11473,6 +11478,8 @@ uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address, · 17 unmodified lines | ||
| 11473 | 11478 | return 0; |
| 11474 | 11479 | } |
| 11475 | 11480 | |
| 11481 | + amdgpu_dm_exit_ips_for_hw_access(ctx->dc); | |
| 11482 | + | |
| 11476 | 11483 | value = cgs_read_register(ctx->cgs_device, address); |
| 11477 | 11484 | |
| 11478 | 11485 | trace_amdgpu_dc_rreg(&ctx->perf_trace->read_count, address, value); |
| @@ -177,7 +177,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = { · 176 unmodified lines | ||
| 177 | 177 | .urgent_latency_pixel_data_only_us = 4.0, |
| 178 | 178 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, |
| 179 | 179 | .urgent_latency_vm_data_only_us = 4.0, |
| 180 | − .dram_clock_change_latency_us = 11.72, | |
| 180 | + .dram_clock_change_latency_us = 34.0, | |
| 181 | 181 | .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, |
| 182 | 182 | .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, |
| 183 | 183 | .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, |
| @@ -215,7 +215,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_51_soc = { · 214 unmodified lines | ||
| 215 | 215 | .urgent_latency_pixel_data_only_us = 4.0, |
| 216 | 216 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, |
| 217 | 217 | .urgent_latency_vm_data_only_us = 4.0, |
| 218 | − .dram_clock_change_latency_us = 11.72, | |
| 218 | + .dram_clock_change_latency_us = 34, | |
| 219 | 219 | .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, |
| 220 | 220 | .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, |
| 221 | 221 | .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, |
| @@ -1439,3 +1439,75 @@ void dcn35_set_long_vblank(struct pipe_ctx **pipe_ctx, · 1438 unmodified lines | ||
| 1439 | 1439 | } |
| 1440 | 1440 | } |
| 1441 | 1441 | } |
| 1442 | + | |
| 1443 | +static bool should_avoid_empty_tu(struct pipe_ctx *pipe_ctx) | |
| 1444 | +{ | |
| 1445 | + /* Calculate average pixel count per TU, return false if under ~2.00 to | |
| 1446 | + * avoid empty TUs. This is only required for DPIA tunneling as empty TUs | |
| 1447 | + * are legal to generate for native DP links. Assume TU size 64 as there | |
| 1448 | + * is currently no scenario where it's reprogrammed from HW default. | |
| 1449 | + * MTPs have no such limitation, so this does not affect MST use cases. | |
| 1450 | + */ | |
| 1451 | + unsigned int pix_clk_mhz; | |
| 1452 | + unsigned int symclk_mhz; | |
| 1453 | + unsigned int avg_pix_per_tu_x1000; | |
| 1454 | + unsigned int tu_size_bytes = 64; | |
| 1455 | + struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; | |
| 1456 | + struct dc_link_settings *link_settings = &pipe_ctx->link_config.dp_link_settings; | |
| 1457 | + const struct dc *dc = pipe_ctx->stream->link->dc; | |
| 1458 | + | |
| 1459 | + if (pipe_ctx->stream->link->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) | |
| 1460 | + return false; | |
| 1461 | + | |
| 1462 | + // Not necessary for MST configurations | |
| 1463 | + if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) | |
| 1464 | + return false; | |
| 1465 | + | |
| 1466 | + pix_clk_mhz = timing->pix_clk_100hz / 10000; | |
| 1467 | + | |
| 1468 | + // If this is true, can't block due to dynamic ODM | |
| 1469 | + if (pix_clk_mhz > dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz) | |
| 1470 | + return false; | |
| 1471 | + | |
| 1472 | + switch (link_settings->link_rate) { | |
| 1473 | + case LINK_RATE_LOW: | |
| 1474 | + symclk_mhz = 162; | |
| 1475 | + break; | |
| 1476 | + case LINK_RATE_HIGH: | |
| 1477 | + symclk_mhz = 270; | |
| 1478 | + break; | |
| 1479 | + case LINK_RATE_HIGH2: | |
| 1480 | + symclk_mhz = 540; | |
| 1481 | + break; | |
| 1482 | + case LINK_RATE_HIGH3: | |
| 1483 | + symclk_mhz = 810; | |
| 1484 | + break; | |
| 1485 | + default: | |
| 1486 | + // We shouldn't be tunneling any other rates, something is wrong | |
| 1487 | + ASSERT(0); | |
| 1488 | + return false; | |
| 1489 | + } | |
| 1490 | + | |
| 1491 | + avg_pix_per_tu_x1000 = (1000 * pix_clk_mhz * tu_size_bytes) | |
| 1492 | + / (symclk_mhz * link_settings->lane_count); | |
| 1493 | + | |
| 1494 | + // Add small empirically-decided margin to account for potential jitter | |
| 1495 | + return (avg_pix_per_tu_x1000 < 2020); | |
| 1496 | +} | |
| 1497 | + | |
| 1498 | +bool dcn35_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx) | |
| 1499 | +{ | |
| 1500 | + struct dc *dc = pipe_ctx->stream->ctx->dc; | |
| 1501 | + | |
| 1502 | + if (!is_h_timing_divisible_by_2(pipe_ctx->stream)) | |
| 1503 | + return false; | |
| 1504 | + | |
| 1505 | + if (should_avoid_empty_tu(pipe_ctx)) | |
| 1506 | + return false; | |
| 1507 | + | |
| 1508 | + if (dc_is_dp_signal(pipe_ctx->stream->signal) && !dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) && | |
| 1509 | + dc->debug.enable_dp_dig_pixel_rate_div_policy) | |
| 1510 | + return true; | |
| 1511 | + | |
| 1512 | + return false; | |
| 1513 | +} | |
| @@ -95,4 +95,6 @@ void dcn35_set_static_screen_control(struct pipe_ctx **pipe_ctx, · 94 unmodified lines | ||
| 95 | 95 | void dcn35_set_long_vblank(struct pipe_ctx **pipe_ctx, |
| 96 | 96 | int num_pipes, uint32_t v_total_min, uint32_t v_total_max); |
| 97 | 97 | |
| 98 | +bool dcn35_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx); | |
| 99 | + | |
| 98 | 100 | #endif /* __DC_HWSS_DCN35_H__ */ |
| @@ -158,7 +158,7 @@ static const struct hwseq_private_funcs dcn35_private_funcs = { · 157 unmodified lines | ||
| 158 | 158 | .setup_hpo_hw_control = dcn35_setup_hpo_hw_control, |
| 159 | 159 | .calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values, |
| 160 | 160 | .set_pixels_per_cycle = dcn32_set_pixels_per_cycle, |
| 161 | − .is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy, | |
| 161 | + .is_dp_dig_pixel_rate_div_policy = dcn35_is_dp_dig_pixel_rate_div_policy, | |
| 162 | 162 | .dsc_pg_control = dcn35_dsc_pg_control, |
| 163 | 163 | .dsc_pg_status = dcn32_dsc_pg_status, |
| 164 | 164 | .enable_plane = dcn35_enable_plane, |
| @@ -164,6 +164,8 @@ static void sumo_construct_vid_mapping_table(struct amdgpu_device *adev, · 163 unmodified lines | ||
| 164 | 164 | |
| 165 | 165 | for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { |
| 166 | 166 | if (table[i].ulSupportedSCLK != 0) { |
| 167 | + if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) | |
| 168 | + continue; | |
| 167 | 169 | vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = |
| 168 | 170 | table[i].usVoltageID; |
| 169 | 171 | vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = |
| @@ -442,6 +442,10 @@ bool intel_dp_has_bigjoiner(struct intel_dp *intel_dp) · 441 unmodified lines | ||
| 442 | 442 | struct intel_encoder *encoder = &intel_dig_port->base; |
| 443 | 443 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
| 444 | 444 | |
| 445 | + /* eDP MSO is not compatible with joiner */ | |
| 446 | + if (intel_dp->mso_link_count) | |
| 447 | + return false; | |
| 448 | + | |
| 445 | 449 | return DISPLAY_VER(dev_priv) >= 12 || |
| 446 | 450 | (DISPLAY_VER(dev_priv) == 11 && |
| 447 | 451 | encoder->port != PORT_A); |
| @@ -1619,6 +1619,8 @@ void sumo_construct_vid_mapping_table(struct radeon_device *rdev, · 1618 unmodified lines | ||
| 1619 | 1619 | |
| 1620 | 1620 | for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { |
| 1621 | 1621 | if (table[i].ulSupportedSCLK != 0) { |
| 1622 | + if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) | |
| 1623 | + continue; | |
| 1622 | 1624 | vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = |
| 1623 | 1625 | table[i].usVoltageID; |
| 1624 | 1626 | vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | config DRM_VMWGFX |
| 3 | 3 | tristate "DRM driver for VMware Virtual GPU" |
| 4 | 4 | depends on DRM && PCI && MMU |
| 5 | − depends on X86 || ARM64 | |
| 5 | + depends on (X86 && HYPERVISOR_GUEST) || ARM64 | |
| 6 | 6 | select DRM_TTM |
| 7 | 7 | select DRM_TTM_HELPER |
| 8 | 8 | select MAPPING_DIRTY_HELPERS |
| @@ -631,8 +631,6 @@ int xe_guc_enable_communication(struct xe_guc *guc) · 630 unmodified lines | ||
| 631 | 631 | struct xe_device *xe = guc_to_xe(guc); |
| 632 | 632 | int err; |
| 633 | 633 | |
| 634 | − guc_enable_irq(guc); | |
| 635 | − | |
| 636 | 634 | if (IS_SRIOV_VF(xe) && xe_device_has_memirq(xe)) { |
| 637 | 635 | struct xe_gt *gt = guc_to_gt(guc); |
| 638 | 636 | struct xe_tile *tile = gt_to_tile(gt); |
| @@ -640,6 +638,8 @@ int xe_guc_enable_communication(struct xe_guc *guc) · 1 unmodified line | ||
| 640 | 638 | err = xe_memirq_init_guc(&tile->sriov.vf.memirq, guc); |
| 641 | 639 | if (err) |
| 642 | 640 | return err; |
| 641 | + } else { | |
| 642 | + guc_enable_irq(guc); | |
| 643 | 643 | } |
| 644 | 644 | |
| 645 | 645 | xe_mmio_rmw32(guc_to_gt(guc), PMINTRMSK, |
| @@ -45,8 +45,8 @@ int hv_init(void) · 44 unmodified lines | ||
| 45 | 45 | * This involves a hypercall. |
| 46 | 46 | */ |
| 47 | 47 | int hv_post_message(union hv_connection_id connection_id, |
| 48 | − enum hv_message_type message_type, | |
| 49 | − void *payload, size_t payload_size) | |
| 48 | + enum hv_message_type message_type, | |
| 49 | + void *payload, size_t payload_size) | |
| 50 | 50 | { |
| 51 | 51 | struct hv_input_post_message *aligned_msg; |
| 52 | 52 | unsigned long flags; |
| @@ -86,7 +86,7 @@ int hv_post_message(union hv_connection_id connection_id, · 33 unmodified lines | ||
| 86 | 86 | status = HV_STATUS_INVALID_PARAMETER; |
| 87 | 87 | } else { |
| 88 | 88 | status = hv_do_hypercall(HVCALL_POST_MESSAGE, |
| 89 | − aligned_msg, NULL); | |
| 89 | + aligned_msg, NULL); | |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | local_irq_restore(flags); |
| @@ -111,7 +111,7 @@ int hv_synic_alloc(void) · 18 unmodified lines | ||
| 111 | 111 | |
| 112 | 112 | hv_context.hv_numa_map = kcalloc(nr_node_ids, sizeof(struct cpumask), |
| 113 | 113 | GFP_KERNEL); |
| 114 | − if (hv_context.hv_numa_map == NULL) { | |
| 114 | + if (!hv_context.hv_numa_map) { | |
| 115 | 115 | pr_err("Unable to allocate NUMA map\n"); |
| 116 | 116 | goto err; |
| 117 | 117 | } |
| @@ -120,11 +120,11 @@ int hv_synic_alloc(void) · 2 unmodified lines | ||
| 120 | 120 | hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); |
| 121 | 121 | |
| 122 | 122 | tasklet_init(&hv_cpu->msg_dpc, |
| 123 | − vmbus_on_msg_dpc, (unsigned long) hv_cpu); | |
| 123 | + vmbus_on_msg_dpc, (unsigned long)hv_cpu); | |
| 124 | 124 | |
| 125 | 125 | if (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) { |
| 126 | 126 | hv_cpu->post_msg_page = (void *)get_zeroed_page(GFP_ATOMIC); |
| 127 | − if (hv_cpu->post_msg_page == NULL) { | |
| 127 | + if (!hv_cpu->post_msg_page) { | |
| 128 | 128 | pr_err("Unable to allocate post msg page\n"); |
| 129 | 129 | goto err; |
| 130 | 130 | } |
| @@ -147,14 +147,14 @@ int hv_synic_alloc(void) · 16 unmodified lines | ||
| 147 | 147 | if (!ms_hyperv.paravisor_present && !hv_root_partition) { |
| 148 | 148 | hv_cpu->synic_message_page = |
| 149 | 149 | (void *)get_zeroed_page(GFP_ATOMIC); |
| 150 | − if (hv_cpu->synic_message_page == NULL) { | |
| 150 | + if (!hv_cpu->synic_message_page) { | |
| 151 | 151 | pr_err("Unable to allocate SYNIC message page\n"); |
| 152 | 152 | goto err; |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | 155 | hv_cpu->synic_event_page = |
| 156 | 156 | (void *)get_zeroed_page(GFP_ATOMIC); |
| 157 | − if (hv_cpu->synic_event_page == NULL) { | |
| 157 | + if (!hv_cpu->synic_event_page) { | |
| 158 | 158 | pr_err("Unable to allocate SYNIC event page\n"); |
| 159 | 159 | |
| 160 | 160 | free_page((unsigned long)hv_cpu->synic_message_page); |
| @@ -203,14 +203,13 @@ err: · 42 unmodified lines | ||
| 203 | 203 | return ret; |
| 204 | 204 | } |
| 205 | 205 | |
| 206 | − | |
| 207 | 206 | void hv_synic_free(void) |
| 208 | 207 | { |
| 209 | 208 | int cpu, ret; |
| 210 | 209 | |
| 211 | 210 | for_each_present_cpu(cpu) { |
| 212 | − struct hv_per_cpu_context *hv_cpu | |
| 213 | − = per_cpu_ptr(hv_context.cpu_context, cpu); | |
| 211 | + struct hv_per_cpu_context *hv_cpu = | |
| 212 | + per_cpu_ptr(hv_context.cpu_context, cpu); | |
| 214 | 213 | |
| 215 | 214 | /* It's better to leak the page if the encryption fails. */ |
| 216 | 215 | if (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) { |
| @@ -262,8 +261,8 @@ void hv_synic_free(void) · 45 unmodified lines | ||
| 262 | 261 | */ |
| 263 | 262 | void hv_synic_enable_regs(unsigned int cpu) |
| 264 | 263 | { |
| 265 | − struct hv_per_cpu_context *hv_cpu | |
| 266 | − = per_cpu_ptr(hv_context.cpu_context, cpu); | |
| 264 | + struct hv_per_cpu_context *hv_cpu = | |
| 265 | + per_cpu_ptr(hv_context.cpu_context, cpu); | |
| 267 | 266 | union hv_synic_simp simp; |
| 268 | 267 | union hv_synic_siefp siefp; |
| 269 | 268 | union hv_synic_sint shared_sint; |
| @@ -277,8 +276,8 @@ void hv_synic_enable_regs(unsigned int cpu) · 7 unmodified lines | ||
| 277 | 276 | /* Mask out vTOM bit. ioremap_cache() maps decrypted */ |
| 278 | 277 | u64 base = (simp.base_simp_gpa << HV_HYP_PAGE_SHIFT) & |
| 279 | 278 | ~ms_hyperv.shared_gpa_boundary; |
| 280 | − hv_cpu->synic_message_page | |
| 281 | − = (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); | |
| 279 | + hv_cpu->synic_message_page = | |
| 280 | + (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); | |
| 282 | 281 | if (!hv_cpu->synic_message_page) |
| 283 | 282 | pr_err("Fail to map synic message page.\n"); |
| 284 | 283 | } else { |
| @@ -296,8 +295,8 @@ void hv_synic_enable_regs(unsigned int cpu) · 11 unmodified lines | ||
| 296 | 295 | /* Mask out vTOM bit. ioremap_cache() maps decrypted */ |
| 297 | 296 | u64 base = (siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT) & |
| 298 | 297 | ~ms_hyperv.shared_gpa_boundary; |
| 299 | − hv_cpu->synic_event_page | |
| 300 | − = (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); | |
| 298 | + hv_cpu->synic_event_page = | |
| 299 | + (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); | |
| 301 | 300 | if (!hv_cpu->synic_event_page) |
| 302 | 301 | pr_err("Fail to map synic event page.\n"); |
| 303 | 302 | } else { |
| @@ -348,8 +347,8 @@ int hv_synic_init(unsigned int cpu) · 44 unmodified lines | ||
| 348 | 347 | */ |
| 349 | 348 | void hv_synic_disable_regs(unsigned int cpu) |
| 350 | 349 | { |
| 351 | − struct hv_per_cpu_context *hv_cpu | |
| 352 | − = per_cpu_ptr(hv_context.cpu_context, cpu); | |
| 350 | + struct hv_per_cpu_context *hv_cpu = | |
| 351 | + per_cpu_ptr(hv_context.cpu_context, cpu); | |
| 353 | 352 | union hv_synic_sint shared_sint; |
| 354 | 353 | union hv_synic_simp simp; |
| 355 | 354 | union hv_synic_siefp siefp; |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/notifier.h> |
| 26 | 26 | #include <linux/percpu_counter.h> |
| 27 | 27 | #include <linux/page_reporting.h> |
| 28 | +#include <linux/sizes.h> | |
| 28 | 29 | |
| 29 | 30 | #include <linux/hyperv.h> |
| 30 | 31 | #include <asm/hyperv-tlfs.h> |
| @@ -41,8 +42,6 @@ · 10 unmodified lines | ||
| 41 | 42 | * Begin protocol definitions. |
| 42 | 43 | */ |
| 43 | 44 | |
| 44 | − | |
| 45 | − | |
| 46 | 45 | /* |
| 47 | 46 | * Protocol versions. The low word is the minor version, the high word the major |
| 48 | 47 | * version. |
| @@ -71,8 +70,6 @@ enum { · 22 unmodified lines | ||
| 71 | 70 | DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN10 |
| 72 | 71 | }; |
| 73 | 72 | |
| 74 | − | |
| 75 | − | |
| 76 | 73 | /* |
| 77 | 74 | * Message Types |
| 78 | 75 | */ |
| @@ -101,7 +98,6 @@ enum dm_message_type { · 22 unmodified lines | ||
| 101 | 98 | DM_VERSION_1_MAX = 12 |
| 102 | 99 | }; |
| 103 | 100 | |
| 104 | − | |
| 105 | 101 | /* |
| 106 | 102 | * Structures defining the dynamic memory management |
| 107 | 103 | * protocol. |
| @@ -115,7 +111,6 @@ union dm_version { · 7 unmodified lines | ||
| 115 | 111 | __u32 version; |
| 116 | 112 | } __packed; |
| 117 | 113 | |
| 118 | − | |
| 119 | 114 | union dm_caps { |
| 120 | 115 | struct { |
| 121 | 116 | __u64 balloon:1; |
| @@ -148,8 +143,6 @@ union dm_mem_page_range { · 26 unmodified lines | ||
| 148 | 143 | __u64 page_range; |
| 149 | 144 | } __packed; |
| 150 | 145 | |
| 151 | − | |
| 152 | − | |
| 153 | 146 | /* |
| 154 | 147 | * The header for all dynamic memory messages: |
| 155 | 148 | * |
| @@ -174,7 +167,6 @@ struct dm_message { · 18 unmodified lines | ||
| 174 | 167 | __u8 data[]; /* enclosed message */ |
| 175 | 168 | } __packed; |
| 176 | 169 | |
| 177 | − | |
| 178 | 170 | /* |
| 179 | 171 | * Specific message types supporting the dynamic memory protocol. |
| 180 | 172 | */ |
| @@ -271,7 +263,6 @@ struct dm_status { · 90 unmodified lines | ||
| 271 | 263 | __u32 io_diff; |
| 272 | 264 | } __packed; |
| 273 | 265 | |
| 274 | − | |
| 275 | 266 | /* |
| 276 | 267 | * Message to ask the guest to allocate memory - balloon up message. |
| 277 | 268 | * This message is sent from the host to the guest. The guest may not be |
| @@ -286,14 +277,13 @@ struct dm_balloon { · 8 unmodified lines | ||
| 286 | 277 | __u32 reservedz; |
| 287 | 278 | } __packed; |
| 288 | 279 | |
| 289 | − | |
| 290 | 280 | /* |
| 291 | 281 | * Balloon response message; this message is sent from the guest |
| 292 | 282 | * to the host in response to the balloon message. |
| 293 | 283 | * |
| 294 | 284 | * reservedz: Reserved; must be set to zero. |
| 295 | 285 | * more_pages: If FALSE, this is the last message of the transaction. |
| 296 | − * if TRUE there will atleast one more message from the guest. | |
| 286 | + * if TRUE there will be at least one more message from the guest. | |
| 297 | 287 | * |
| 298 | 288 | * range_count: The number of ranges in the range array. |
| 299 | 289 | * |
| @@ -314,7 +304,7 @@ struct dm_balloon_response { · 14 unmodified lines | ||
| 314 | 304 | * to the guest to give guest more memory. |
| 315 | 305 | * |
| 316 | 306 | * more_pages: If FALSE, this is the last message of the transaction. |
| 317 | − * if TRUE there will atleast one more message from the guest. | |
| 307 | + * if TRUE there will be at least one more message from the guest. | |
| 318 | 308 | * |
| 319 | 309 | * reservedz: Reserved; must be set to zero. |
| 320 | 310 | * |
| @@ -342,7 +332,6 @@ struct dm_unballoon_response { · 21 unmodified lines | ||
| 342 | 332 | struct dm_header hdr; |
| 343 | 333 | } __packed; |
| 344 | 334 | |
| 345 | − | |
| 346 | 335 | /* |
| 347 | 336 | * Hot add request message. Message sent from the host to the guest. |
| 348 | 337 | * |
| @@ -390,7 +379,6 @@ enum dm_info_type { · 41 unmodified lines | ||
| 390 | 379 | MAX_INFO_TYPE |
| 391 | 380 | }; |
| 392 | 381 | |
| 393 | − | |
| 394 | 382 | /* |
| 395 | 383 | * Header for the information message. |
| 396 | 384 | */ |
| @@ -425,11 +413,11 @@ struct dm_info_msg { · 28 unmodified lines | ||
| 425 | 413 | * The range start_pfn : end_pfn specifies the range |
| 426 | 414 | * that the host has asked us to hot add. The range |
| 427 | 415 | * start_pfn : ha_end_pfn specifies the range that we have |
| 428 | − * currently hot added. We hot add in multiples of 128M | |
| 429 | − * chunks; it is possible that we may not be able to bring | |
| 430 | − * online all the pages in the region. The range | |
| 416 | + * currently hot added. We hot add in chunks equal to the | |
| 417 | + * memory block size; it is possible that we may not be able | |
| 418 | + * to bring online all the pages in the region. The range | |
| 431 | 419 | * covered_start_pfn:covered_end_pfn defines the pages that can |
| 432 | − * be brough online. | |
| 420 | + * be brought online. | |
| 433 | 421 | */ |
| 434 | 422 | |
| 435 | 423 | struct hv_hotadd_state { |
| @@ -480,10 +468,10 @@ static unsigned long last_post_time; · 44 unmodified lines | ||
| 480 | 468 | |
| 481 | 469 | static int hv_hypercall_multi_failure; |
| 482 | 470 | |
| 483 | −module_param(hot_add, bool, (S_IRUGO | S_IWUSR)); | |
| 471 | +module_param(hot_add, bool, 0644); | |
| 484 | 472 | MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add"); |
| 485 | 473 | |
| 486 | −module_param(pressure_report_delay, uint, (S_IRUGO | S_IWUSR)); | |
| 474 | +module_param(pressure_report_delay, uint, 0644); | |
| 487 | 475 | MODULE_PARM_DESC(pressure_report_delay, "Delay in secs in reporting pressure"); |
| 488 | 476 | static atomic_t trans_id = ATOMIC_INIT(0); |
| 489 | 477 | |
| @@ -502,11 +490,13 @@ enum hv_dm_state { · 12 unmodified lines | ||
| 502 | 490 | DM_INIT_ERROR |
| 503 | 491 | }; |
| 504 | 492 | |
| 505 | − | |
| 506 | 493 | static __u8 recv_buffer[HV_HYP_PAGE_SIZE]; |
| 507 | 494 | static __u8 balloon_up_send_buffer[HV_HYP_PAGE_SIZE]; |
| 495 | + | |
| 496 | +static unsigned long ha_pages_in_chunk; | |
| 497 | +#define HA_BYTES_IN_CHUNK (ha_pages_in_chunk << PAGE_SHIFT) | |
| 498 | + | |
| 508 | 499 | #define PAGES_IN_2M (2 * 1024 * 1024 / PAGE_SIZE) |
| 509 | −#define HA_CHUNK (128 * 1024 * 1024 / PAGE_SIZE) | |
| 510 | 500 | |
| 511 | 501 | struct hv_dynmem_device { |
| 512 | 502 | struct hv_device *dev; |
| @@ -595,12 +585,12 @@ static inline bool has_pfn_is_backed(struct hv_hotadd_state *has, · 82 unmodified lines | ||
| 595 | 585 | struct hv_hotadd_gap *gap; |
| 596 | 586 | |
| 597 | 587 | /* The page is not backed. */ |
| 598 | − if ((pfn < has->covered_start_pfn) || (pfn >= has->covered_end_pfn)) | |
| 588 | + if (pfn < has->covered_start_pfn || pfn >= has->covered_end_pfn) | |
| 599 | 589 | return false; |
| 600 | 590 | |
| 601 | 591 | /* Check for gaps. */ |
| 602 | 592 | list_for_each_entry(gap, &has->gap_list, list) { |
| 603 | − if ((pfn >= gap->start_pfn) && (pfn < gap->end_pfn)) | |
| 593 | + if (pfn >= gap->start_pfn && pfn < gap->end_pfn) | |
| 604 | 594 | return false; |
| 605 | 595 | } |
| 606 | 596 | |
| @@ -724,28 +714,21 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size, · 117 unmodified lines | ||
| 724 | 714 | unsigned long processed_pfn; |
| 725 | 715 | unsigned long total_pfn = pfn_count; |
| 726 | 716 | |
| 727 | − for (i = 0; i < (size/HA_CHUNK); i++) { | |
| 728 | − start_pfn = start + (i * HA_CHUNK); | |
| 717 | + for (i = 0; i < (size/ha_pages_in_chunk); i++) { | |
| 718 | + start_pfn = start + (i * ha_pages_in_chunk); | |
| 729 | 719 | |
| 730 | 720 | scoped_guard(spinlock_irqsave, &dm_device.ha_lock) { |
| 731 | − has->ha_end_pfn += HA_CHUNK; | |
| 732 | − | |
| 733 | − if (total_pfn > HA_CHUNK) { | |
| 734 | − processed_pfn = HA_CHUNK; | |
| 735 | − total_pfn -= HA_CHUNK; | |
| 736 | − } else { | |
| 737 | − processed_pfn = total_pfn; | |
| 738 | − total_pfn = 0; | |
| 739 | − } | |
| 740 | − | |
| 741 | − has->covered_end_pfn += processed_pfn; | |
| 721 | + has->ha_end_pfn += ha_pages_in_chunk; | |
| 722 | + processed_pfn = umin(total_pfn, ha_pages_in_chunk); | |
| 723 | + total_pfn -= processed_pfn; | |
| 724 | + has->covered_end_pfn += processed_pfn; | |
| 742 | 725 | } |
| 743 | 726 | |
| 744 | 727 | reinit_completion(&dm_device.ol_waitevent); |
| 745 | 728 | |
| 746 | 729 | nid = memory_add_physaddr_to_nid(PFN_PHYS(start_pfn)); |
| 747 | 730 | ret = add_memory(nid, PFN_PHYS((start_pfn)), |
| 748 | − (HA_CHUNK << PAGE_SHIFT), MHP_MERGE_RESOURCE); | |
| 731 | + HA_BYTES_IN_CHUNK, MHP_MERGE_RESOURCE); | |
| 749 | 732 | |
| 750 | 733 | if (ret) { |
| 751 | 734 | pr_err("hot_add memory failed error is %d\n", ret); |
| @@ -760,7 +743,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size, · 8 unmodified lines | ||
| 760 | 743 | do_hot_add = false; |
| 761 | 744 | } |
| 762 | 745 | scoped_guard(spinlock_irqsave, &dm_device.ha_lock) { |
| 763 | − has->ha_end_pfn -= HA_CHUNK; | |
| 746 | + has->ha_end_pfn -= ha_pages_in_chunk; | |
| 764 | 747 | has->covered_end_pfn -= processed_pfn; |
| 765 | 748 | } |
| 766 | 749 | break; |
| @@ -787,8 +770,8 @@ static void hv_online_page(struct page *pg, unsigned int order) · 20 unmodified lines | ||
| 787 | 770 | guard(spinlock_irqsave)(&dm_device.ha_lock); |
| 788 | 771 | list_for_each_entry(has, &dm_device.ha_region_list, list) { |
| 789 | 772 | /* The page belongs to a different HAS. */ |
| 790 | − if ((pfn < has->start_pfn) || | |
| 791 | − (pfn + (1UL << order) > has->end_pfn)) | |
| 773 | + if (pfn < has->start_pfn || | |
| 774 | + (pfn + (1UL << order) > has->end_pfn)) | |
| 792 | 775 | continue; |
| 793 | 776 | |
| 794 | 777 | hv_bring_pgs_online(has, pfn, 1UL << order); |
| @@ -800,7 +783,7 @@ static int pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt) · 5 unmodified lines | ||
| 800 | 783 | { |
| 801 | 784 | struct hv_hotadd_state *has; |
| 802 | 785 | struct hv_hotadd_gap *gap; |
| 803 | − unsigned long residual, new_inc; | |
| 786 | + unsigned long residual; | |
| 804 | 787 | int ret = 0; |
| 805 | 788 | |
| 806 | 789 | guard(spinlock_irqsave)(&dm_device.ha_lock); |
| @@ -836,15 +819,9 @@ static int pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt) · 29 unmodified lines | ||
| 836 | 819 | * our current limit; extend it. |
| 837 | 820 | */ |
| 838 | 821 | if ((start_pfn + pfn_cnt) > has->end_pfn) { |
| 822 | + /* Extend the region by multiples of ha_pages_in_chunk */ | |
| 839 | 823 | residual = (start_pfn + pfn_cnt - has->end_pfn); |
| 840 | − /* | |
| 841 | − * Extend the region by multiples of HA_CHUNK. | |
| 842 | − */ | |
| 843 | − new_inc = (residual / HA_CHUNK) * HA_CHUNK; | |
| 844 | − if (residual % HA_CHUNK) | |
| 845 | − new_inc += HA_CHUNK; | |
| 846 | − | |
| 847 | − has->end_pfn += new_inc; | |
| 824 | + has->end_pfn += ALIGN(residual, ha_pages_in_chunk); | |
| 848 | 825 | } |
| 849 | 826 | |
| 850 | 827 | ret = 1; |
| @@ -855,7 +832,7 @@ static int pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt) · 4 unmodified lines | ||
| 855 | 832 | } |
| 856 | 833 | |
| 857 | 834 | static unsigned long handle_pg_range(unsigned long pg_start, |
| 858 | − unsigned long pg_count) | |
| 835 | + unsigned long pg_count) | |
| 859 | 836 | { |
| 860 | 837 | unsigned long start_pfn = pg_start; |
| 861 | 838 | unsigned long pfn_cnt = pg_count; |
| @@ -866,7 +843,7 @@ static unsigned long handle_pg_range(unsigned long pg_start, · 4 unmodified lines | ||
| 866 | 843 | unsigned long res = 0, flags; |
| 867 | 844 | |
| 868 | 845 | pr_debug("Hot adding %lu pages starting at pfn 0x%lx.\n", pg_count, |
| 869 | − pg_start); | |
| 846 | + pg_start); | |
| 870 | 847 | |
| 871 | 848 | spin_lock_irqsave(&dm_device.ha_lock, flags); |
| 872 | 849 | list_for_each_entry(has, &dm_device.ha_region_list, list) { |
| @@ -902,22 +879,19 @@ static unsigned long handle_pg_range(unsigned long pg_start, · 29 unmodified lines | ||
| 902 | 879 | if (start_pfn > has->start_pfn && |
| 903 | 880 | online_section_nr(pfn_to_section_nr(start_pfn))) |
| 904 | 881 | hv_bring_pgs_online(has, start_pfn, pgs_ol); |
| 905 | − | |
| 906 | 882 | } |
| 907 | 883 | |
| 908 | − if ((has->ha_end_pfn < has->end_pfn) && (pfn_cnt > 0)) { | |
| 884 | + if (has->ha_end_pfn < has->end_pfn && pfn_cnt > 0) { | |
| 909 | 885 | /* |
| 910 | 886 | * We have some residual hot add range |
| 911 | 887 | * that needs to be hot added; hot add |
| 912 | 888 | * it now. Hot add a multiple of |
| 913 | − * HA_CHUNK that fully covers the pages | |
| 889 | + * ha_pages_in_chunk that fully covers the pages | |
| 914 | 890 | * we have. |
| 915 | 891 | */ |
| 916 | 892 | size = (has->end_pfn - has->ha_end_pfn); |
| 917 | 893 | if (pfn_cnt <= size) { |
| 918 | − size = ((pfn_cnt / HA_CHUNK) * HA_CHUNK); | |
| 919 | − if (pfn_cnt % HA_CHUNK) | |
| 920 | − size += HA_CHUNK; | |
| 894 | + size = ALIGN(pfn_cnt, ha_pages_in_chunk); | |
| 921 | 895 | } else { |
| 922 | 896 | pfn_cnt = size; |
| 923 | 897 | } |
| @@ -1010,10 +984,7 @@ static void hot_add_req(struct work_struct *dummy) · 86 unmodified lines | ||
| 1010 | 984 | rg_start = dm->ha_wrk.ha_region_range.finfo.start_page; |
| 1011 | 985 | rg_sz = dm->ha_wrk.ha_region_range.finfo.page_cnt; |
| 1012 | 986 | |
| 1013 | − if ((rg_start == 0) && (!dm->host_specified_ha_region)) { | |
| 1014 | − unsigned long region_size; | |
| 1015 | − unsigned long region_start; | |
| 1016 | − | |
| 987 | + if (rg_start == 0 && !dm->host_specified_ha_region) { | |
| 1017 | 988 | /* |
| 1018 | 989 | * The host has not specified the hot-add region. |
| 1019 | 990 | * Based on the hot-add page range being specified, |
| @@ -1021,19 +992,13 @@ static void hot_add_req(struct work_struct *dummy) · 1 unmodified line | ||
| 1021 | 992 | * that need to be hot-added while ensuring the alignment |
| 1022 | 993 | * and size requirements of Linux as it relates to hot-add. |
| 1023 | 994 | */ |
| 1024 | − region_size = (pfn_cnt / HA_CHUNK) * HA_CHUNK; | |
| 1025 | − if (pfn_cnt % HA_CHUNK) | |
| 1026 | − region_size += HA_CHUNK; | |
| 1027 | − | |
| 1028 | − region_start = (pg_start / HA_CHUNK) * HA_CHUNK; | |
| 1029 | − | |
| 1030 | − rg_start = region_start; | |
| 1031 | − rg_sz = region_size; | |
| 995 | + rg_start = ALIGN_DOWN(pg_start, ha_pages_in_chunk); | |
| 996 | + rg_sz = ALIGN(pfn_cnt, ha_pages_in_chunk); | |
| 1032 | 997 | } |
| 1033 | 998 | |
| 1034 | 999 | if (do_hot_add) |
| 1035 | 1000 | resp.page_count = process_hot_add(pg_start, pfn_cnt, |
| 1036 | − rg_start, rg_sz); | |
| 1001 | + rg_start, rg_sz); | |
| 1037 | 1002 | |
| 1038 | 1003 | dm->num_pages_added += resp.page_count; |
| 1039 | 1004 | #endif |
| @@ -1211,11 +1176,10 @@ static void post_status(struct hv_dynmem_device *dm) · 171 unmodified lines | ||
| 1211 | 1176 | sizeof(struct dm_status), |
| 1212 | 1177 | (unsigned long)NULL, |
| 1213 | 1178 | VM_PKT_DATA_INBAND, 0); |
| 1214 | − | |
| 1215 | 1179 | } |
| 1216 | 1180 | |
| 1217 | 1181 | static void free_balloon_pages(struct hv_dynmem_device *dm, |
| 1218 | − union dm_mem_page_range *range_array) | |
| 1182 | + union dm_mem_page_range *range_array) | |
| 1219 | 1183 | { |
| 1220 | 1184 | int num_pages = range_array->finfo.page_cnt; |
| 1221 | 1185 | __u64 start_frame = range_array->finfo.start_page; |
| @@ -1231,8 +1195,6 @@ static void free_balloon_pages(struct hv_dynmem_device *dm, · 9 unmodified lines | ||
| 1231 | 1195 | } |
| 1232 | 1196 | } |
| 1233 | 1197 | |
| 1234 | − | |
| 1235 | − | |
| 1236 | 1198 | static unsigned int alloc_balloon_pages(struct hv_dynmem_device *dm, |
| 1237 | 1199 | unsigned int num_pages, |
| 1238 | 1200 | struct dm_balloon_response *bl_resp, |
| @@ -1278,7 +1240,6 @@ static unsigned int alloc_balloon_pages(struct hv_dynmem_device *dm, · 39 unmodified lines | ||
| 1278 | 1240 | page_to_pfn(pg); |
| 1279 | 1241 | bl_resp->range_array[i].finfo.page_cnt = alloc_unit; |
| 1280 | 1242 | bl_resp->hdr.size += sizeof(union dm_mem_page_range); |
| 1281 | − | |
| 1282 | 1243 | } |
| 1283 | 1244 | |
| 1284 | 1245 | return i * alloc_unit; |
| @@ -1332,7 +1293,7 @@ static void balloon_up(struct work_struct *dummy) · 47 unmodified lines | ||
| 1332 | 1293 | |
| 1333 | 1294 | if (num_ballooned == 0 || num_ballooned == num_pages) { |
| 1334 | 1295 | pr_debug("Ballooned %u out of %u requested pages.\n", |
| 1335 | − num_pages, dm_device.balloon_wrk.num_pages); | |
| 1296 | + num_pages, dm_device.balloon_wrk.num_pages); | |
| 1336 | 1297 | |
| 1337 | 1298 | bl_resp->more_pages = 0; |
| 1338 | 1299 | done = true; |
| @@ -1366,16 +1327,15 @@ static void balloon_up(struct work_struct *dummy) · 27 unmodified lines | ||
| 1366 | 1327 | |
| 1367 | 1328 | for (i = 0; i < bl_resp->range_count; i++) |
| 1368 | 1329 | free_balloon_pages(&dm_device, |
| 1369 | − &bl_resp->range_array[i]); | |
| 1330 | + &bl_resp->range_array[i]); | |
| 1370 | 1331 | |
| 1371 | 1332 | done = true; |
| 1372 | 1333 | } |
| 1373 | 1334 | } |
| 1374 | − | |
| 1375 | 1335 | } |
| 1376 | 1336 | |
| 1377 | 1337 | static void balloon_down(struct hv_dynmem_device *dm, |
| 1378 | − struct dm_unballoon_request *req) | |
| 1338 | + struct dm_unballoon_request *req) | |
| 1379 | 1339 | { |
| 1380 | 1340 | union dm_mem_page_range *range_array = req->range_array; |
| 1381 | 1341 | int range_count = req->range_count; |
| @@ -1389,7 +1349,7 @@ static void balloon_down(struct hv_dynmem_device *dm, · 7 unmodified lines | ||
| 1389 | 1349 | } |
| 1390 | 1350 | |
| 1391 | 1351 | pr_debug("Freed %u ballooned pages.\n", |
| 1392 | − prev_pages_ballooned - dm->num_pages_ballooned); | |
| 1352 | + prev_pages_ballooned - dm->num_pages_ballooned); | |
| 1393 | 1353 | |
| 1394 | 1354 | if (req->more_pages == 1) |
| 1395 | 1355 | return; |
| @@ -1414,8 +1374,7 @@ static int dm_thread_func(void *dm_dev) · 18 unmodified lines | ||
| 1414 | 1374 | struct hv_dynmem_device *dm = dm_dev; |
| 1415 | 1375 | |
| 1416 | 1376 | while (!kthread_should_stop()) { |
| 1417 | − wait_for_completion_interruptible_timeout( | |
| 1418 | − &dm_device.config_event, 1*HZ); | |
| 1377 | + wait_for_completion_interruptible_timeout(&dm_device.config_event, 1 * HZ); | |
| 1419 | 1378 | /* |
| 1420 | 1379 | * The host expects us to post information on the memory |
| 1421 | 1380 | * pressure every second. |
| @@ -1439,9 +1398,8 @@ static int dm_thread_func(void *dm_dev) · 17 unmodified lines | ||
| 1439 | 1398 | return 0; |
| 1440 | 1399 | } |
| 1441 | 1400 | |
| 1442 | − | |
| 1443 | 1401 | static void version_resp(struct hv_dynmem_device *dm, |
| 1444 | − struct dm_version_response *vresp) | |
| 1402 | + struct dm_version_response *vresp) | |
| 1445 | 1403 | { |
| 1446 | 1404 | struct dm_version_request version_req; |
| 1447 | 1405 | int ret; |
| @@ -1502,7 +1460,7 @@ version_error: · 54 unmodified lines | ||
| 1502 | 1460 | } |
| 1503 | 1461 | |
| 1504 | 1462 | static void cap_resp(struct hv_dynmem_device *dm, |
| 1505 | − struct dm_capabilities_resp_msg *cap_resp) | |
| 1463 | + struct dm_capabilities_resp_msg *cap_resp) | |
| 1506 | 1464 | { |
| 1507 | 1465 | if (!cap_resp->is_accepted) { |
| 1508 | 1466 | pr_err("Capabilities not accepted by host\n"); |
| @@ -1535,7 +1493,7 @@ static void balloon_onchannelcallback(void *context) · 26 unmodified lines | ||
| 1535 | 1493 | switch (dm_hdr->type) { |
| 1536 | 1494 | case DM_VERSION_RESPONSE: |
| 1537 | 1495 | version_resp(dm, |
| 1538 | − (struct dm_version_response *)dm_msg); | |
| 1496 | + (struct dm_version_response *)dm_msg); | |
| 1539 | 1497 | break; |
| 1540 | 1498 | |
| 1541 | 1499 | case DM_CAPABILITIES_RESPONSE: |
| @@ -1565,7 +1523,7 @@ static void balloon_onchannelcallback(void *context) · 23 unmodified lines | ||
| 1565 | 1523 | |
| 1566 | 1524 | dm->state = DM_BALLOON_DOWN; |
| 1567 | 1525 | balloon_down(dm, |
| 1568 | − (struct dm_unballoon_request *)recv_buffer); | |
| 1526 | + (struct dm_unballoon_request *)recv_buffer); | |
| 1569 | 1527 | break; |
| 1570 | 1528 | |
| 1571 | 1529 | case DM_MEM_HOT_ADD_REQUEST: |
| @@ -1603,17 +1561,15 @@ static void balloon_onchannelcallback(void *context) · 31 unmodified lines | ||
| 1603 | 1561 | |
| 1604 | 1562 | default: |
| 1605 | 1563 | pr_warn_ratelimited("Unhandled message: type: %d\n", dm_hdr->type); |
| 1606 | − | |
| 1607 | 1564 | } |
| 1608 | 1565 | } |
| 1609 | − | |
| 1610 | 1566 | } |
| 1611 | 1567 | |
| 1612 | 1568 | #define HV_LARGE_REPORTING_ORDER 9 |
| 1613 | 1569 | #define HV_LARGE_REPORTING_LEN (HV_HYP_PAGE_SIZE << \ |
| 1614 | 1570 | HV_LARGE_REPORTING_ORDER) |
| 1615 | 1571 | static int hv_free_page_report(struct page_reporting_dev_info *pr_dev_info, |
| 1616 | − struct scatterlist *sgl, unsigned int nents) | |
| 1572 | + struct scatterlist *sgl, unsigned int nents) | |
| 1617 | 1573 | { |
| 1618 | 1574 | unsigned long flags; |
| 1619 | 1575 | struct hv_memory_hint *hint; |
| @@ -1648,7 +1604,7 @@ static int hv_free_page_report(struct page_reporting_dev_info *pr_dev_info, · 28 unmodified lines | ||
| 1648 | 1604 | */ |
| 1649 | 1605 | |
| 1650 | 1606 | /* page reporting for pages 2MB or higher */ |
| 1651 | − if (order >= HV_LARGE_REPORTING_ORDER ) { | |
| 1607 | + if (order >= HV_LARGE_REPORTING_ORDER) { | |
| 1652 | 1608 | range->page.largepage = 1; |
| 1653 | 1609 | range->page_size = HV_GPA_PAGE_RANGE_PAGE_SIZE_2MB; |
| 1654 | 1610 | range->base_large_pfn = page_to_hvpfn( |
| @@ -1662,23 +1618,21 @@ static int hv_free_page_report(struct page_reporting_dev_info *pr_dev_info, · 7 unmodified lines | ||
| 1662 | 1618 | range->page.additional_pages = |
| 1663 | 1619 | (sg->length / HV_HYP_PAGE_SIZE) - 1; |
| 1664 | 1620 | } |
| 1665 | − | |
| 1666 | 1621 | } |
| 1667 | 1622 | |
| 1668 | 1623 | status = hv_do_rep_hypercall(HV_EXT_CALL_MEMORY_HEAT_HINT, nents, 0, |
| 1669 | 1624 | hint, NULL); |
| 1670 | 1625 | local_irq_restore(flags); |
| 1671 | 1626 | if (!hv_result_success(status)) { |
| 1672 | − | |
| 1673 | 1627 | pr_err("Cold memory discard hypercall failed with status %llx\n", |
| 1674 | − status); | |
| 1628 | + status); | |
| 1675 | 1629 | if (hv_hypercall_multi_failure > 0) |
| 1676 | 1630 | hv_hypercall_multi_failure++; |
| 1677 | 1631 | |
| 1678 | 1632 | if (hv_result(status) == HV_STATUS_INVALID_PARAMETER) { |
| 1679 | 1633 | pr_err("Underlying Hyper-V does not support order less than 9. Hypercall failed\n"); |
| 1680 | 1634 | pr_err("Defaulting to page_reporting_order %d\n", |
| 1681 | − pageblock_order); | |
| 1635 | + pageblock_order); | |
| 1682 | 1636 | page_reporting_order = pageblock_order; |
| 1683 | 1637 | hv_hypercall_multi_failure++; |
| 1684 | 1638 | return -EINVAL; |
| @@ -1712,7 +1666,7 @@ static void enable_page_reporting(void) · 27 unmodified lines | ||
| 1712 | 1666 | pr_err("Failed to enable cold memory discard: %d\n", ret); |
| 1713 | 1667 | } else { |
| 1714 | 1668 | pr_info("Cold memory discard hint enabled with order %d\n", |
| 1715 | − page_reporting_order); | |
| 1669 | + page_reporting_order); | |
| 1716 | 1670 | } |
| 1717 | 1671 | } |
| 1718 | 1672 | |
| @@ -1795,7 +1749,7 @@ static int balloon_connect_vsp(struct hv_device *dev) · 76 unmodified lines | ||
| 1795 | 1749 | if (ret) |
| 1796 | 1750 | goto out; |
| 1797 | 1751 | |
| 1798 | − t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ); | |
| 1752 | + t = wait_for_completion_timeout(&dm_device.host_event, 5 * HZ); | |
| 1799 | 1753 | if (t == 0) { |
| 1800 | 1754 | ret = -ETIMEDOUT; |
| 1801 | 1755 | goto out; |
| @@ -1831,10 +1785,13 @@ static int balloon_connect_vsp(struct hv_device *dev) · 29 unmodified lines | ||
| 1831 | 1785 | cap_msg.caps.cap_bits.hot_add = hot_add_enabled(); |
| 1832 | 1786 | |
| 1833 | 1787 | /* |
| 1834 | − * Specify our alignment requirements as it relates | |
| 1835 | − * memory hot-add. Specify 128MB alignment. | |
| 1788 | + * Specify our alignment requirements for memory hot-add. The value is | |
| 1789 | + * the log base 2 of the number of megabytes in a chunk. For example, | |
| 1790 | + * with 256 MiB chunks, the value is 8. The number of MiB in a chunk | |
| 1791 | + * must be a power of 2. | |
| 1836 | 1792 | */ |
| 1837 | − cap_msg.caps.cap_bits.hot_add_alignment = 7; | |
| 1793 | + cap_msg.caps.cap_bits.hot_add_alignment = | |
| 1794 | + ilog2(HA_BYTES_IN_CHUNK / SZ_1M); | |
| 1838 | 1795 | |
| 1839 | 1796 | /* |
| 1840 | 1797 | * Currently the host does not use these |
| @@ -1850,7 +1807,7 @@ static int balloon_connect_vsp(struct hv_device *dev) · 9 unmodified lines | ||
| 1850 | 1807 | if (ret) |
| 1851 | 1808 | goto out; |
| 1852 | 1809 | |
| 1853 | − t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ); | |
| 1810 | + t = wait_for_completion_timeout(&dm_device.host_event, 5 * HZ); | |
| 1854 | 1811 | if (t == 0) { |
| 1855 | 1812 | ret = -ETIMEDOUT; |
| 1856 | 1813 | goto out; |
| @@ -1891,8 +1848,8 @@ static int hv_balloon_debug_show(struct seq_file *f, void *offset) · 34 unmodified lines | ||
| 1891 | 1848 | char *sname; |
| 1892 | 1849 | |
| 1893 | 1850 | seq_printf(f, "%-22s: %u.%u\n", "host_version", |
| 1894 | − DYNMEM_MAJOR_VERSION(dm->version), | |
| 1895 | − DYNMEM_MINOR_VERSION(dm->version)); | |
| 1851 | + DYNMEM_MAJOR_VERSION(dm->version), | |
| 1852 | + DYNMEM_MINOR_VERSION(dm->version)); | |
| 1896 | 1853 | |
| 1897 | 1854 | seq_printf(f, "%-22s:", "capabilities"); |
| 1898 | 1855 | if (ballooning_enabled()) |
| @@ -1941,10 +1898,10 @@ static int hv_balloon_debug_show(struct seq_file *f, void *offset) · 42 unmodified lines | ||
| 1941 | 1898 | seq_printf(f, "%-22s: %u\n", "pages_ballooned", dm->num_pages_ballooned); |
| 1942 | 1899 | |
| 1943 | 1900 | seq_printf(f, "%-22s: %lu\n", "total_pages_committed", |
| 1944 | − get_pages_committed(dm)); | |
| 1901 | + get_pages_committed(dm)); | |
| 1945 | 1902 | |
| 1946 | 1903 | seq_printf(f, "%-22s: %llu\n", "max_dynamic_page_count", |
| 1947 | − dm->max_dynamic_page_count); | |
| 1904 | + dm->max_dynamic_page_count); | |
| 1948 | 1905 | |
| 1949 | 1906 | return 0; |
| 1950 | 1907 | } |
| @@ -1954,7 +1911,7 @@ DEFINE_SHOW_ATTRIBUTE(hv_balloon_debug); · 3 unmodified lines | ||
| 1954 | 1911 | static void hv_balloon_debugfs_init(struct hv_dynmem_device *b) |
| 1955 | 1912 | { |
| 1956 | 1913 | debugfs_create_file("hv-balloon", 0444, NULL, b, |
| 1957 | − &hv_balloon_debug_fops); | |
| 1914 | + &hv_balloon_debug_fops); | |
| 1958 | 1915 | } |
| 1959 | 1916 | |
| 1960 | 1917 | static void hv_balloon_debugfs_exit(struct hv_dynmem_device *b) |
| @@ -1984,8 +1941,23 @@ static int balloon_probe(struct hv_device *dev, · 23 unmodified lines | ||
| 1984 | 1941 | hot_add = false; |
| 1985 | 1942 | |
| 1986 | 1943 | #ifdef CONFIG_MEMORY_HOTPLUG |
| 1944 | + /* | |
| 1945 | + * Hot-add must operate in chunks that are of size equal to the | |
| 1946 | + * memory block size because that's what the core add_memory() | |
| 1947 | + * interface requires. The Hyper-V interface requires that the memory | |
| 1948 | + * block size be a power of 2, which is guaranteed by the check in | |
| 1949 | + * memory_dev_init(). | |
| 1950 | + */ | |
| 1951 | + ha_pages_in_chunk = memory_block_size_bytes() / PAGE_SIZE; | |
| 1987 | 1952 | do_hot_add = hot_add; |
| 1988 | 1953 | #else |
| 1954 | + /* | |
| 1955 | + * Without MEMORY_HOTPLUG, the guest returns a failure status for all | |
| 1956 | + * hot add requests from Hyper-V, and the chunk size is used only to | |
| 1957 | + * specify alignment to Hyper-V as required by the host/guest protocol. | |
| 1958 | + * Somewhat arbitrarily, use 128 MiB. | |
| 1959 | + */ | |
| 1960 | + ha_pages_in_chunk = SZ_128M / PAGE_SIZE; | |
| 1989 | 1961 | do_hot_add = false; |
| 1990 | 1962 | #endif |
| 1991 | 1963 | dm_device.dev = dev; |
| @@ -2097,7 +2069,6 @@ static int balloon_suspend(struct hv_device *hv_dev) · 105 unmodified lines | ||
| 2097 | 2069 | tasklet_enable(&hv_dev->channel->callback_event); |
| 2098 | 2070 | |
| 2099 | 2071 | return 0; |
| 2100 | − | |
| 2101 | 2072 | } |
| 2102 | 2073 | |
| 2103 | 2074 | static int balloon_resume(struct hv_device *dev) |
| @@ -2156,7 +2127,6 @@ static struct hv_driver balloon_drv = { · 52 unmodified lines | ||
| 2156 | 2127 | |
| 2157 | 2128 | static int __init init_balloon_drv(void) |
| 2158 | 2129 | { |
| 2159 | − | |
| 2160 | 2130 | return vmbus_driver_register(&balloon_drv); |
| 2161 | 2131 | } |
| 2162 | 2132 | |
| @@ -431,8 +431,8 @@ static int ocores_init(struct device *dev, struct ocores_i2c *i2c) · 430 unmodified lines | ||
| 431 | 431 | oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); |
| 432 | 432 | |
| 433 | 433 | /* Init the device */ |
| 434 | − oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); | |
| 435 | 434 | oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); |
| 435 | + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); | |
| 436 | 436 | |
| 437 | 437 | return 0; |
| 438 | 438 | } |
| @@ -107,8 +107,6 @@ struct bnxt_re_gsi_context { · 106 unmodified lines | ||
| 107 | 107 | struct bnxt_re_sqp_entries *sqp_tbl; |
| 108 | 108 | }; |
| 109 | 109 | |
| 110 | −#define BNXT_RE_MIN_MSIX 2 | |
| 111 | −#define BNXT_RE_MAX_MSIX 9 | |
| 112 | 110 | #define BNXT_RE_AEQ_IDX 0 |
| 113 | 111 | #define BNXT_RE_NQ_IDX 1 |
| 114 | 112 | #define BNXT_RE_GEN_P5_MAX_VF 64 |
| @@ -168,7 +166,7 @@ struct bnxt_re_dev { · 53 unmodified lines | ||
| 168 | 166 | struct bnxt_qplib_rcfw rcfw; |
| 169 | 167 | |
| 170 | 168 | /* NQ */ |
| 171 | − struct bnxt_qplib_nq nq[BNXT_RE_MAX_MSIX]; | |
| 169 | + struct bnxt_qplib_nq nq[BNXT_MAX_ROCE_MSIX]; | |
| 172 | 170 | |
| 173 | 171 | /* Device Resources */ |
| 174 | 172 | struct bnxt_qplib_dev_attr dev_attr; |
| @@ -112,6 +112,7 @@ struct ib_mr *mana_ib_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length, · 111 unmodified lines | ||
| 112 | 112 | "start 0x%llx, iova 0x%llx length 0x%llx access_flags 0x%x", |
| 113 | 113 | start, iova, length, access_flags); |
| 114 | 114 | |
| 115 | + access_flags &= ~IB_ACCESS_OPTIONAL; | |
| 115 | 116 | if (access_flags & ~VALID_MR_FLAGS) |
| 116 | 117 | return ERR_PTR(-EINVAL); |
| 117 | 118 | |
| @@ -3759,10 +3759,10 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev) · 3758 unmodified lines | ||
| 3759 | 3759 | spin_lock_init(&dev->dm.lock); |
| 3760 | 3760 | dev->dm.dev = mdev; |
| 3761 | 3761 | return 0; |
| 3762 | −err: | |
| 3763 | − mlx5r_macsec_dealloc_gids(dev); | |
| 3764 | 3762 | err_mp: |
| 3765 | 3763 | mlx5_ib_cleanup_multiport_master(dev); |
| 3764 | +err: | |
| 3765 | + mlx5r_macsec_dealloc_gids(dev); | |
| 3766 | 3766 | return err; |
| 3767 | 3767 | } |
| 3768 | 3768 | |
| @@ -246,6 +246,7 @@ static void set_cache_mkc(struct mlx5_cache_ent *ent, void *mkc) · 245 unmodified lines | ||
| 246 | 246 | MLX5_SET(mkc, mkc, access_mode_1_0, ent->rb_key.access_mode & 0x3); |
| 247 | 247 | MLX5_SET(mkc, mkc, access_mode_4_2, |
| 248 | 248 | (ent->rb_key.access_mode >> 2) & 0x7); |
| 249 | + MLX5_SET(mkc, mkc, ma_translation_mode, !!ent->rb_key.ats); | |
| 249 | 250 | |
| 250 | 251 | MLX5_SET(mkc, mkc, translations_octword_size, |
| 251 | 252 | get_mkc_octo_size(ent->rb_key.access_mode, |
| @@ -641,10 +642,8 @@ static int mlx5_cache_ent_insert(struct mlx5_mkey_cache *cache, · 389 unmodified lines | ||
| 641 | 642 | new = &((*new)->rb_left); |
| 642 | 643 | if (cmp < 0) |
| 643 | 644 | new = &((*new)->rb_right); |
| 644 | − if (cmp == 0) { | |
| 645 | − mutex_unlock(&cache->rb_lock); | |
| 645 | + if (cmp == 0) | |
| 646 | 646 | return -EEXIST; |
| 647 | − } | |
| 648 | 647 | } |
| 649 | 648 | |
| 650 | 649 | /* Add new node and rebalance tree. */ |
| @@ -719,6 +718,8 @@ static struct mlx5_ib_mr *_mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev, · 68 unmodified lines | ||
| 719 | 718 | } |
| 720 | 719 | mr->mmkey.cache_ent = ent; |
| 721 | 720 | mr->mmkey.type = MLX5_MKEY_MR; |
| 721 | + mr->mmkey.rb_key = ent->rb_key; | |
| 722 | + mr->mmkey.cacheable = true; | |
| 722 | 723 | init_waitqueue_head(&mr->mmkey.wait); |
| 723 | 724 | return mr; |
| 724 | 725 | } |
| @@ -1169,7 +1170,6 @@ static struct mlx5_ib_mr *alloc_cacheable_mr(struct ib_pd *pd, · 444 unmodified lines | ||
| 1169 | 1170 | mr->ibmr.pd = pd; |
| 1170 | 1171 | mr->umem = umem; |
| 1171 | 1172 | mr->page_shift = order_base_2(page_size); |
| 1172 | − mr->mmkey.cacheable = true; | |
| 1173 | 1173 | set_mr_fields(dev, mr, umem->length, access_flags, iova); |
| 1174 | 1174 | |
| 1175 | 1175 | return mr; |
| @@ -199,17 +199,20 @@ int mlx5_ib_create_srq(struct ib_srq *ib_srq, · 198 unmodified lines | ||
| 199 | 199 | int err; |
| 200 | 200 | struct mlx5_srq_attr in = {}; |
| 201 | 201 | __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz); |
| 202 | + __u32 max_sge_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq) / | |
| 203 | + sizeof(struct mlx5_wqe_data_seg); | |
| 202 | 204 | |
| 203 | 205 | if (init_attr->srq_type != IB_SRQT_BASIC && |
| 204 | 206 | init_attr->srq_type != IB_SRQT_XRC && |
| 205 | 207 | init_attr->srq_type != IB_SRQT_TM) |
| 206 | 208 | return -EOPNOTSUPP; |
| 207 | 209 | |
| 208 | − /* Sanity check SRQ size before proceeding */ | |
| 209 | − if (init_attr->attr.max_wr >= max_srq_wqes) { | |
| 210 | − mlx5_ib_dbg(dev, "max_wr %d, cap %d\n", | |
| 211 | − init_attr->attr.max_wr, | |
| 212 | − max_srq_wqes); | |
| 210 | + /* Sanity check SRQ and sge size before proceeding */ | |
| 211 | + if (init_attr->attr.max_wr >= max_srq_wqes || | |
| 212 | + init_attr->attr.max_sge > max_sge_sz) { | |
| 213 | + mlx5_ib_dbg(dev, "max_wr %d,wr_cap %d,max_sge %d, sge_cap:%d\n", | |
| 214 | + init_attr->attr.max_wr, max_srq_wqes, | |
| 215 | + init_attr->attr.max_sge, max_sge_sz); | |
| 213 | 216 | return -EINVAL; |
| 214 | 217 | } |
| 215 | 218 | |
| @@ -344,6 +344,19 @@ static enum resp_states rxe_resp_check_length(struct rxe_qp *qp, · 343 unmodified lines | ||
| 344 | 344 | * receive buffer later. For rmda operations additional |
| 345 | 345 | * length checks are performed in check_rkey. |
| 346 | 346 | */ |
| 347 | + if ((qp_type(qp) == IB_QPT_GSI) || (qp_type(qp) == IB_QPT_UD)) { | |
| 348 | + unsigned int payload = payload_size(pkt); | |
| 349 | + unsigned int recv_buffer_len = 0; | |
| 350 | + int i; | |
| 351 | + | |
| 352 | + for (i = 0; i < qp->resp.wqe->dma.num_sge; i++) | |
| 353 | + recv_buffer_len += qp->resp.wqe->dma.sge[i].length; | |
| 354 | + if (payload + 40 > recv_buffer_len) { | |
| 355 | + rxe_dbg_qp(qp, "The receive buffer is too small for this UD packet.\n"); | |
| 356 | + return RESPST_ERR_LENGTH; | |
| 357 | + } | |
| 358 | + } | |
| 359 | + | |
| 347 | 360 | if (pkt->mask & RXE_PAYLOAD_MASK && ((qp_type(qp) == IB_QPT_RC) || |
| 348 | 361 | (qp_type(qp) == IB_QPT_UC))) { |
| 349 | 362 | unsigned int mtu = qp->mtu; |
| @@ -812,7 +812,7 @@ static void copy_inline_data_to_wqe(struct rxe_send_wqe *wqe, · 811 unmodified lines | ||
| 812 | 812 | int i; |
| 813 | 813 | |
| 814 | 814 | for (i = 0; i < ibwr->num_sge; i++, sge++) { |
| 815 | − memcpy(p, ib_virt_dma_to_page(sge->addr), sge->length); | |
| 815 | + memcpy(p, ib_virt_dma_to_ptr(sge->addr), sge->length); | |
| 816 | 816 | p += sge->length; |
| 817 | 817 | } |
| 818 | 818 | } |
| @@ -210,6 +210,7 @@ static const struct regmap_access_table axp313a_volatile_table = { · 209 unmodified lines | ||
| 210 | 210 | |
| 211 | 211 | static const struct regmap_range axp717_writeable_ranges[] = { |
| 212 | 212 | regmap_reg_range(AXP717_IRQ0_EN, AXP717_IRQ4_EN), |
| 213 | + regmap_reg_range(AXP717_IRQ0_STATE, AXP717_IRQ4_STATE), | |
| 213 | 214 | regmap_reg_range(AXP717_DCDC_OUTPUT_CONTROL, AXP717_CPUSLDO_CONTROL), |
| 214 | 215 | }; |
| 215 | 216 | |
| @@ -732,9 +732,6 @@ tx_done: · 731 unmodified lines | ||
| 732 | 732 | return NETDEV_TX_OK; |
| 733 | 733 | |
| 734 | 734 | tx_dma_error: |
| 735 | − if (BNXT_TX_PTP_IS_SET(lflags)) | |
| 736 | − atomic_inc(&bp->ptp_cfg->tx_avail); | |
| 737 | − | |
| 738 | 735 | last_frag = i; |
| 739 | 736 | |
| 740 | 737 | /* start back at beginning and unmap skb */ |
| @@ -756,6 +753,8 @@ tx_dma_error: · 15 unmodified lines | ||
| 756 | 753 | tx_free: |
| 757 | 754 | dev_kfree_skb_any(skb); |
| 758 | 755 | tx_kick_pending: |
| 756 | + if (BNXT_TX_PTP_IS_SET(lflags)) | |
| 757 | + atomic_inc(&bp->ptp_cfg->tx_avail); | |
| 759 | 758 | if (txr->kick_pending) |
| 760 | 759 | bnxt_txr_db_kick(bp, txr, txr->tx_prod); |
| 761 | 760 | txr->tx_buf_ring[txr->tx_prod].skb = NULL; |
| @@ -8996,6 +8995,7 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) · 8234 unmodified lines | ||
| 8996 | 8995 | memcpy(vf->mac_addr, resp->mac_address, ETH_ALEN); |
| 8997 | 8996 | #endif |
| 8998 | 8997 | } |
| 8998 | + bp->tso_max_segs = le16_to_cpu(resp->max_tso_segs); | |
| 8999 | 8999 | |
| 9000 | 9000 | hwrm_func_qcaps_exit: |
| 9001 | 9001 | hwrm_req_drop(bp, req); |
| @@ -15363,6 +15363,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 6361 unmodified lines | ||
| 15363 | 15363 | dev->priv_flags |= IFF_UNICAST_FLT; |
| 15364 | 15364 | |
| 15365 | 15365 | netif_set_tso_max_size(dev, GSO_MAX_SIZE); |
| 15366 | + if (bp->tso_max_segs) | |
| 15367 | + netif_set_tso_max_segs(dev, bp->tso_max_segs); | |
| 15366 | 15368 | |
| 15367 | 15369 | dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT | |
| 15368 | 15370 | NETDEV_XDP_ACT_RX_SG; |
| @@ -2318,6 +2318,7 @@ struct bnxt { · 2317 unmodified lines | ||
| 2318 | 2318 | u8 rss_hash_key_updated:1; |
| 2319 | 2319 | |
| 2320 | 2320 | u16 max_mtu; |
| 2321 | + u16 tso_max_segs; | |
| 2321 | 2322 | u8 max_tc; |
| 2322 | 2323 | u8 max_lltc; /* lossless TCs */ |
| 2323 | 2324 | struct bnxt_queue_info q_info[BNXT_MAX_QUEUE]; |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * |
| 3 | 3 | * Copyright (c) 2014-2016 Broadcom Corporation |
| 4 | 4 | * Copyright (c) 2014-2018 Broadcom Limited |
| 5 | − * Copyright (c) 2018-2023 Broadcom Inc. | |
| 5 | + * Copyright (c) 2018-2024 Broadcom Inc. | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -500,7 +500,11 @@ struct cmd_nums { · 491 unmodified lines | ||
| 500 | 500 | #define HWRM_TFC_IF_TBL_GET 0x399UL |
| 501 | 501 | #define HWRM_TFC_TBL_SCOPE_CONFIG_GET 0x39aUL |
| 502 | 502 | #define HWRM_TFC_RESC_USAGE_QUERY 0x39bUL |
| 503 | + #define HWRM_QUEUE_PFCWD_TIMEOUT_QCAPS 0x39cUL | |
| 504 | + #define HWRM_QUEUE_PFCWD_TIMEOUT_CFG 0x39dUL | |
| 505 | + #define HWRM_QUEUE_PFCWD_TIMEOUT_QCFG 0x39eUL | |
| 503 | 506 | #define HWRM_SV 0x400UL |
| 507 | + #define HWRM_DBG_LOG_BUFFER_FLUSH 0xff0fUL | |
| 504 | 508 | #define HWRM_DBG_READ_DIRECT 0xff10UL |
| 505 | 509 | #define HWRM_DBG_READ_INDIRECT 0xff11UL |
| 506 | 510 | #define HWRM_DBG_WRITE_DIRECT 0xff12UL |
| @@ -609,8 +613,8 @@ struct hwrm_err_output { · 102 unmodified lines | ||
| 609 | 613 | #define HWRM_VERSION_MAJOR 1 |
| 610 | 614 | #define HWRM_VERSION_MINOR 10 |
| 611 | 615 | #define HWRM_VERSION_UPDATE 3 |
| 612 | −#define HWRM_VERSION_RSVD 39 | |
| 613 | −#define HWRM_VERSION_STR "1.10.3.39" | |
| 616 | +#define HWRM_VERSION_RSVD 44 | |
| 617 | +#define HWRM_VERSION_STR "1.10.3.44" | |
| 614 | 618 | |
| 615 | 619 | /* hwrm_ver_get_input (size:192b/24B) */ |
| 616 | 620 | struct hwrm_ver_get_input { |
| @@ -664,6 +668,7 @@ struct hwrm_ver_get_output { · 47 unmodified lines | ||
| 664 | 668 | #define VER_GET_RESP_DEV_CAPS_CFG_CFA_TFLIB_SUPPORTED 0x2000UL |
| 665 | 669 | #define VER_GET_RESP_DEV_CAPS_CFG_CFA_TRUFLOW_SUPPORTED 0x4000UL |
| 666 | 670 | #define VER_GET_RESP_DEV_CAPS_CFG_SECURE_BOOT_CAPABLE 0x8000UL |
| 671 | + #define VER_GET_RESP_DEV_CAPS_CFG_SECURE_SOC_CAPABLE 0x10000UL | |
| 667 | 672 | u8 roce_fw_maj_8b; |
| 668 | 673 | u8 roce_fw_min_8b; |
| 669 | 674 | u8 roce_fw_bld_8b; |
| @@ -843,7 +848,9 @@ struct hwrm_async_event_cmpl { · 173 unmodified lines | ||
| 843 | 848 | #define ASYNC_EVENT_CMPL_EVENT_ID_HW_DOORBELL_RECOVERY_READ_ERROR 0x49UL |
| 844 | 849 | #define ASYNC_EVENT_CMPL_EVENT_ID_CTX_ERROR 0x4aUL |
| 845 | 850 | #define ASYNC_EVENT_CMPL_EVENT_ID_UDCC_SESSION_CHANGE 0x4bUL |
| 846 | − #define ASYNC_EVENT_CMPL_EVENT_ID_MAX_RGTR_EVENT_ID 0x4cUL | |
| 851 | + #define ASYNC_EVENT_CMPL_EVENT_ID_DBG_BUF_PRODUCER 0x4cUL | |
| 852 | + #define ASYNC_EVENT_CMPL_EVENT_ID_PEER_MMAP_CHANGE 0x4dUL | |
| 853 | + #define ASYNC_EVENT_CMPL_EVENT_ID_MAX_RGTR_EVENT_ID 0x4eUL | |
| 847 | 854 | #define ASYNC_EVENT_CMPL_EVENT_ID_FW_TRACE_MSG 0xfeUL |
| 848 | 855 | #define ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR 0xffUL |
| 849 | 856 | #define ASYNC_EVENT_CMPL_EVENT_ID_LAST ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR |
| @@ -1326,13 +1333,13 @@ struct hwrm_async_event_cmpl_error_report_base { · 476 unmodified lines | ||
| 1326 | 1333 | u8 timestamp_lo; |
| 1327 | 1334 | __le16 timestamp_hi; |
| 1328 | 1335 | __le32 event_data1; |
| 1329 | − #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_MASK 0xffUL | |
| 1330 | − #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_SFT 0 | |
| 1331 | − #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_RESERVED 0x0UL | |
| 1332 | − #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_PAUSE_STORM 0x1UL | |
| 1333 | − #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_INVALID_SIGNAL 0x2UL | |
| 1334 | − #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_NVM 0x3UL | |
| 1335 | − #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DOORBELL_DROP_THRESHOLD 0x4UL | |
| 1336 | + #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_MASK 0xffUL | |
| 1337 | + #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_SFT 0 | |
| 1338 | + #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_RESERVED 0x0UL | |
| 1339 | + #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_PAUSE_STORM 0x1UL | |
| 1340 | + #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_INVALID_SIGNAL 0x2UL | |
| 1341 | + #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_NVM 0x3UL | |
| 1342 | + #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DOORBELL_DROP_THRESHOLD 0x4UL | |
| 1336 | 1343 | #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_THERMAL_THRESHOLD 0x5UL |
| 1337 | 1344 | #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DUAL_DATA_RATE_NOT_SUPPORTED 0x6UL |
| 1338 | 1345 | #define ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_LAST ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DUAL_DATA_RATE_NOT_SUPPORTED |
| @@ -1814,6 +1821,9 @@ struct hwrm_func_qcaps_output { · 475 unmodified lines | ||
| 1814 | 1821 | #define FUNC_QCAPS_RESP_FLAGS_EXT2_SW_MAX_RESOURCE_LIMITS_SUPPORTED 0x800000UL |
| 1815 | 1822 | #define FUNC_QCAPS_RESP_FLAGS_EXT2_TF_INGRESS_NIC_FLOW_SUPPORTED 0x1000000UL |
| 1816 | 1823 | #define FUNC_QCAPS_RESP_FLAGS_EXT2_LPBK_STATS_SUPPORTED 0x2000000UL |
| 1824 | + #define FUNC_QCAPS_RESP_FLAGS_EXT2_TF_EGRESS_NIC_FLOW_SUPPORTED 0x4000000UL | |
| 1825 | + #define FUNC_QCAPS_RESP_FLAGS_EXT2_MULTI_LOSSLESS_QUEUES_SUPPORTED 0x8000000UL | |
| 1826 | + #define FUNC_QCAPS_RESP_FLAGS_EXT2_PEER_MMAP_SUPPORTED 0x10000000UL | |
| 1817 | 1827 | __le16 tunnel_disable_flag; |
| 1818 | 1828 | #define FUNC_QCAPS_RESP_TUNNEL_DISABLE_FLAG_DISABLE_VXLAN 0x1UL |
| 1819 | 1829 | #define FUNC_QCAPS_RESP_TUNNEL_DISABLE_FLAG_DISABLE_NGE 0x2UL |
| @@ -1828,7 +1838,7 @@ struct hwrm_func_qcaps_output { · 8 unmodified lines | ||
| 1828 | 1838 | #define FUNC_QCAPS_RESP_XID_PARTITION_CAP_RX_CK 0x2UL |
| 1829 | 1839 | u8 device_serial_number[8]; |
| 1830 | 1840 | __le16 ctxs_per_partition; |
| 1831 | − u8 unused_2[2]; | |
| 1841 | + __le16 max_tso_segs; | |
| 1832 | 1842 | __le32 roce_vf_max_av; |
| 1833 | 1843 | __le32 roce_vf_max_cq; |
| 1834 | 1844 | __le32 roce_vf_max_mrw; |
| @@ -2449,6 +2459,7 @@ struct hwrm_func_drv_rgtr_input { · 614 unmodified lines | ||
| 2449 | 2459 | #define FUNC_DRV_RGTR_REQ_FLAGS_NPAR_1_2_SUPPORT 0x200UL |
| 2450 | 2460 | #define FUNC_DRV_RGTR_REQ_FLAGS_ASYM_QUEUE_CFG_SUPPORT 0x400UL |
| 2451 | 2461 | #define FUNC_DRV_RGTR_REQ_FLAGS_TF_INGRESS_NIC_FLOW_MODE 0x800UL |
| 2462 | + #define FUNC_DRV_RGTR_REQ_FLAGS_TF_EGRESS_NIC_FLOW_MODE 0x1000UL | |
| 2452 | 2463 | __le32 enables; |
| 2453 | 2464 | #define FUNC_DRV_RGTR_REQ_ENABLES_OS_TYPE 0x1UL |
| 2454 | 2465 | #define FUNC_DRV_RGTR_REQ_ENABLES_VER 0x2UL |
| @@ -3660,22 +3671,24 @@ struct hwrm_func_backing_store_cfg_v2_input { · 1205 unmodified lines | ||
| 3660 | 3671 | __le16 target_id; |
| 3661 | 3672 | __le64 resp_addr; |
| 3662 | 3673 | __le16 type; |
| 3663 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_QP 0x0UL | |
| 3664 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SRQ 0x1UL | |
| 3665 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_CQ 0x2UL | |
| 3666 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_VNIC 0x3UL | |
| 3667 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_STAT 0x4UL | |
| 3668 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SP_TQM_RING 0x5UL | |
| 3669 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_FP_TQM_RING 0x6UL | |
| 3670 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_MRAV 0xeUL | |
| 3671 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_TIM 0xfUL | |
| 3672 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_MP_TQM_RING 0x15UL | |
| 3673 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SQ_DB_SHADOW 0x16UL | |
| 3674 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_RQ_DB_SHADOW 0x17UL | |
| 3675 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SRQ_DB_SHADOW 0x18UL | |
| 3676 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_CQ_DB_SHADOW 0x19UL | |
| 3677 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_TBL_SCOPE 0x1cUL | |
| 3678 | − #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_XID_PARTITION 0x1dUL | |
| 3674 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_QP 0x0UL | |
| 3675 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SRQ 0x1UL | |
| 3676 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_CQ 0x2UL | |
| 3677 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_VNIC 0x3UL | |
| 3678 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_STAT 0x4UL | |
| 3679 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SP_TQM_RING 0x5UL | |
| 3680 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_FP_TQM_RING 0x6UL | |
| 3681 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_MRAV 0xeUL | |
| 3682 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_TIM 0xfUL | |
| 3683 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_TX_CK 0x13UL | |
| 3684 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_RX_CK 0x14UL | |
| 3685 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_MP_TQM_RING 0x15UL | |
| 3686 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SQ_DB_SHADOW 0x16UL | |
| 3687 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_RQ_DB_SHADOW 0x17UL | |
| 3688 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SRQ_DB_SHADOW 0x18UL | |
| 3689 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_CQ_DB_SHADOW 0x19UL | |
| 3690 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_TBL_SCOPE 0x1cUL | |
| 3691 | + #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_XID_PARTITION 0x1dUL | |
| 3679 | 3692 | #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SRT_TRACE 0x1eUL |
| 3680 | 3693 | #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_SRT2_TRACE 0x1fUL |
| 3681 | 3694 | #define FUNC_BACKING_STORE_CFG_V2_REQ_TYPE_CRT_TRACE 0x20UL |
| @@ -3772,18 +3785,20 @@ struct hwrm_func_backing_store_qcfg_v2_output { · 90 unmodified lines | ||
| 3772 | 3785 | __le16 seq_id; |
| 3773 | 3786 | __le16 resp_len; |
| 3774 | 3787 | __le16 type; |
| 3775 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_QP 0x0UL | |
| 3776 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_SRQ 0x1UL | |
| 3777 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_CQ 0x2UL | |
| 3778 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_VNIC 0x3UL | |
| 3779 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_STAT 0x4UL | |
| 3780 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_SP_TQM_RING 0x5UL | |
| 3781 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_FP_TQM_RING 0x6UL | |
| 3782 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_MRAV 0xeUL | |
| 3783 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_TIM 0xfUL | |
| 3784 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_MP_TQM_RING 0x15UL | |
| 3785 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_TBL_SCOPE 0x1cUL | |
| 3786 | − #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_XID_PARTITION 0x1dUL | |
| 3788 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_QP 0x0UL | |
| 3789 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_SRQ 0x1UL | |
| 3790 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_CQ 0x2UL | |
| 3791 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_VNIC 0x3UL | |
| 3792 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_STAT 0x4UL | |
| 3793 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_SP_TQM_RING 0x5UL | |
| 3794 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_FP_TQM_RING 0x6UL | |
| 3795 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_MRAV 0xeUL | |
| 3796 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_TIM 0xfUL | |
| 3797 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_TX_CK 0x13UL | |
| 3798 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_RX_CK 0x14UL | |
| 3799 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_MP_TQM_RING 0x15UL | |
| 3800 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_TBL_SCOPE 0x1cUL | |
| 3801 | + #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_XID_PARTITION 0x1dUL | |
| 3787 | 3802 | #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_SRT_TRACE 0x1eUL |
| 3788 | 3803 | #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_SRT2_TRACE 0x1fUL |
| 3789 | 3804 | #define FUNC_BACKING_STORE_QCFG_V2_RESP_TYPE_CRT_TRACE 0x20UL |
| @@ -3876,22 +3891,24 @@ struct hwrm_func_backing_store_qcaps_v2_input { · 86 unmodified lines | ||
| 3876 | 3891 | __le16 target_id; |
| 3877 | 3892 | __le64 resp_addr; |
| 3878 | 3893 | __le16 type; |
| 3879 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_QP 0x0UL | |
| 3880 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SRQ 0x1UL | |
| 3881 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_CQ 0x2UL | |
| 3882 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_VNIC 0x3UL | |
| 3883 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_STAT 0x4UL | |
| 3884 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SP_TQM_RING 0x5UL | |
| 3885 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_FP_TQM_RING 0x6UL | |
| 3886 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_MRAV 0xeUL | |
| 3887 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_TIM 0xfUL | |
| 3888 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_MP_TQM_RING 0x15UL | |
| 3889 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SQ_DB_SHADOW 0x16UL | |
| 3890 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_RQ_DB_SHADOW 0x17UL | |
| 3891 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SRQ_DB_SHADOW 0x18UL | |
| 3892 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_CQ_DB_SHADOW 0x19UL | |
| 3893 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_TBL_SCOPE 0x1cUL | |
| 3894 | − #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_XID_PARTITION 0x1dUL | |
| 3894 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_QP 0x0UL | |
| 3895 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SRQ 0x1UL | |
| 3896 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_CQ 0x2UL | |
| 3897 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_VNIC 0x3UL | |
| 3898 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_STAT 0x4UL | |
| 3899 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SP_TQM_RING 0x5UL | |
| 3900 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_FP_TQM_RING 0x6UL | |
| 3901 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_MRAV 0xeUL | |
| 3902 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_TIM 0xfUL | |
| 3903 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_TX_CK 0x13UL | |
| 3904 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_RX_CK 0x14UL | |
| 3905 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_MP_TQM_RING 0x15UL | |
| 3906 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SQ_DB_SHADOW 0x16UL | |
| 3907 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_RQ_DB_SHADOW 0x17UL | |
| 3908 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SRQ_DB_SHADOW 0x18UL | |
| 3909 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_CQ_DB_SHADOW 0x19UL | |
| 3910 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_TBL_SCOPE 0x1cUL | |
| 3911 | + #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_XID_PARTITION 0x1dUL | |
| 3895 | 3912 | #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SRT_TRACE 0x1eUL |
| 3896 | 3913 | #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_SRT2_TRACE 0x1fUL |
| 3897 | 3914 | #define FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_CRT_TRACE 0x20UL |
| @@ -3911,22 +3928,24 @@ struct hwrm_func_backing_store_qcaps_v2_output { · 13 unmodified lines | ||
| 3911 | 3928 | __le16 seq_id; |
| 3912 | 3929 | __le16 resp_len; |
| 3913 | 3930 | __le16 type; |
| 3914 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_QP 0x0UL | |
| 3915 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SRQ 0x1UL | |
| 3916 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_CQ 0x2UL | |
| 3917 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_VNIC 0x3UL | |
| 3918 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_STAT 0x4UL | |
| 3919 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SP_TQM_RING 0x5UL | |
| 3920 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_FP_TQM_RING 0x6UL | |
| 3921 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_MRAV 0xeUL | |
| 3922 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_TIM 0xfUL | |
| 3923 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_MP_TQM_RING 0x15UL | |
| 3924 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SQ_DB_SHADOW 0x16UL | |
| 3925 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_RQ_DB_SHADOW 0x17UL | |
| 3926 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SRQ_DB_SHADOW 0x18UL | |
| 3927 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_CQ_DB_SHADOW 0x19UL | |
| 3928 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_TBL_SCOPE 0x1cUL | |
| 3929 | − #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_XID_PARTITION 0x1dUL | |
| 3931 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_QP 0x0UL | |
| 3932 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SRQ 0x1UL | |
| 3933 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_CQ 0x2UL | |
| 3934 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_VNIC 0x3UL | |
| 3935 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_STAT 0x4UL | |
| 3936 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SP_TQM_RING 0x5UL | |
| 3937 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_FP_TQM_RING 0x6UL | |
| 3938 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_MRAV 0xeUL | |
| 3939 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_TIM 0xfUL | |
| 3940 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_TX_CK 0x13UL | |
| 3941 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_RX_CK 0x14UL | |
| 3942 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_MP_TQM_RING 0x15UL | |
| 3943 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SQ_DB_SHADOW 0x16UL | |
| 3944 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_RQ_DB_SHADOW 0x17UL | |
| 3945 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SRQ_DB_SHADOW 0x18UL | |
| 3946 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_CQ_DB_SHADOW 0x19UL | |
| 3947 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_TBL_SCOPE 0x1cUL | |
| 3948 | + #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_XID_PARTITION 0x1dUL | |
| 3930 | 3949 | #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SRT_TRACE 0x1eUL |
| 3931 | 3950 | #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_SRT2_TRACE 0x1fUL |
| 3932 | 3951 | #define FUNC_BACKING_STORE_QCAPS_V2_RESP_TYPE_CRT_TRACE 0x20UL |
| @@ -4202,7 +4221,8 @@ struct hwrm_port_phy_cfg_input { · 269 unmodified lines | ||
| 4202 | 4221 | #define PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_100GB_PAM4_112 0x3eaUL |
| 4203 | 4222 | #define PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_200GB_PAM4_112 0x7d2UL |
| 4204 | 4223 | #define PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_400GB_PAM4_112 0xfa2UL |
| 4205 | − #define PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_LAST PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_400GB_PAM4_112 | |
| 4224 | + #define PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_800GB_PAM4_112 0x1f42UL | |
| 4225 | + #define PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_LAST PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_800GB_PAM4_112 | |
| 4206 | 4226 | __le16 auto_link_speeds2_mask; |
| 4207 | 4227 | #define PORT_PHY_CFG_REQ_AUTO_LINK_SPEEDS2_MASK_1GB 0x1UL |
| 4208 | 4228 | #define PORT_PHY_CFG_REQ_AUTO_LINK_SPEEDS2_MASK_10GB 0x2UL |
| @@ -4217,6 +4237,7 @@ struct hwrm_port_phy_cfg_input { · 8 unmodified lines | ||
| 4217 | 4237 | #define PORT_PHY_CFG_REQ_AUTO_LINK_SPEEDS2_MASK_100GB_PAM4_112 0x400UL |
| 4218 | 4238 | #define PORT_PHY_CFG_REQ_AUTO_LINK_SPEEDS2_MASK_200GB_PAM4_112 0x800UL |
| 4219 | 4239 | #define PORT_PHY_CFG_REQ_AUTO_LINK_SPEEDS2_MASK_400GB_PAM4_112 0x1000UL |
| 4240 | + #define PORT_PHY_CFG_REQ_AUTO_LINK_SPEEDS2_MASK_800GB_PAM4_112 0x2000UL | |
| 4220 | 4241 | u8 unused_2[6]; |
| 4221 | 4242 | }; |
| 4222 | 4243 | |
| @@ -4292,6 +4313,7 @@ struct hwrm_port_phy_qcfg_output { · 69 unmodified lines | ||
| 4292 | 4313 | #define PORT_PHY_QCFG_RESP_LINK_SPEED_100GB 0x3e8UL |
| 4293 | 4314 | #define PORT_PHY_QCFG_RESP_LINK_SPEED_200GB 0x7d0UL |
| 4294 | 4315 | #define PORT_PHY_QCFG_RESP_LINK_SPEED_400GB 0xfa0UL |
| 4316 | + #define PORT_PHY_QCFG_RESP_LINK_SPEED_800GB 0x1f40UL | |
| 4295 | 4317 | #define PORT_PHY_QCFG_RESP_LINK_SPEED_10MB 0xffffUL |
| 4296 | 4318 | #define PORT_PHY_QCFG_RESP_LINK_SPEED_LAST PORT_PHY_QCFG_RESP_LINK_SPEED_10MB |
| 4297 | 4319 | u8 duplex_cfg; |
| @@ -4451,7 +4473,13 @@ struct hwrm_port_phy_qcfg_output { · 153 unmodified lines | ||
| 4451 | 4473 | #define PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR4 0x35UL |
| 4452 | 4474 | #define PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR4 0x36UL |
| 4453 | 4475 | #define PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER4 0x37UL |
| 4454 | − #define PORT_PHY_QCFG_RESP_PHY_TYPE_LAST PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER4 | |
| 4476 | + #define PORT_PHY_QCFG_RESP_PHY_TYPE_800G_BASECR8 0x38UL | |
| 4477 | + #define PORT_PHY_QCFG_RESP_PHY_TYPE_800G_BASESR8 0x39UL | |
| 4478 | + #define PORT_PHY_QCFG_RESP_PHY_TYPE_800G_BASELR8 0x3aUL | |
| 4479 | + #define PORT_PHY_QCFG_RESP_PHY_TYPE_800G_BASEER8 0x3bUL | |
| 4480 | + #define PORT_PHY_QCFG_RESP_PHY_TYPE_800G_BASEFR8 0x3cUL | |
| 4481 | + #define PORT_PHY_QCFG_RESP_PHY_TYPE_800G_BASEDR8 0x3dUL | |
| 4482 | + #define PORT_PHY_QCFG_RESP_PHY_TYPE_LAST PORT_PHY_QCFG_RESP_PHY_TYPE_800G_BASEDR8 | |
| 4455 | 4483 | u8 media_type; |
| 4456 | 4484 | #define PORT_PHY_QCFG_RESP_MEDIA_TYPE_UNKNOWN 0x0UL |
| 4457 | 4485 | #define PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP 0x1UL |
| @@ -5049,33 +5077,43 @@ struct hwrm_port_qstats_ext_output { · 591 unmodified lines | ||
| 5049 | 5077 | u8 valid; |
| 5050 | 5078 | }; |
| 5051 | 5079 | |
| 5052 | −/* hwrm_port_lpbk_qstats_input (size:128b/16B) */ | |
| 5080 | +/* hwrm_port_lpbk_qstats_input (size:256b/32B) */ | |
| 5053 | 5081 | struct hwrm_port_lpbk_qstats_input { |
| 5054 | 5082 | __le16 req_type; |
| 5055 | 5083 | __le16 cmpl_ring; |
| 5056 | 5084 | __le16 seq_id; |
| 5057 | 5085 | __le16 target_id; |
| 5058 | 5086 | __le64 resp_addr; |
| 5087 | + __le16 lpbk_stat_size; | |
| 5088 | + u8 flags; | |
| 5089 | + #define PORT_LPBK_QSTATS_REQ_FLAGS_COUNTER_MASK 0x1UL | |
| 5090 | + u8 unused_0[5]; | |
| 5091 | + __le64 lpbk_stat_host_addr; | |
| 5059 | 5092 | }; |
| 5060 | 5093 | |
| 5061 | −/* hwrm_port_lpbk_qstats_output (size:768b/96B) */ | |
| 5094 | +/* hwrm_port_lpbk_qstats_output (size:128b/16B) */ | |
| 5062 | 5095 | struct hwrm_port_lpbk_qstats_output { |
| 5063 | 5096 | __le16 error_code; |
| 5064 | 5097 | __le16 req_type; |
| 5065 | 5098 | __le16 seq_id; |
| 5066 | 5099 | __le16 resp_len; |
| 5100 | + __le16 lpbk_stat_size; | |
| 5101 | + u8 unused_0[5]; | |
| 5102 | + u8 valid; | |
| 5103 | +}; | |
| 5104 | + | |
| 5105 | +/* port_lpbk_stats (size:640b/80B) */ | |
| 5106 | +struct port_lpbk_stats { | |
| 5067 | 5107 | __le64 lpbk_ucast_frames; |
| 5068 | 5108 | __le64 lpbk_mcast_frames; |
| 5069 | 5109 | __le64 lpbk_bcast_frames; |
| 5070 | 5110 | __le64 lpbk_ucast_bytes; |
| 5071 | 5111 | __le64 lpbk_mcast_bytes; |
| 5072 | 5112 | __le64 lpbk_bcast_bytes; |
| 5073 | − __le64 tx_stat_discard; | |
| 5074 | − __le64 tx_stat_error; | |
| 5075 | − __le64 rx_stat_discard; | |
| 5076 | − __le64 rx_stat_error; | |
| 5077 | − u8 unused_0[7]; | |
| 5078 | − u8 valid; | |
| 5113 | + __le64 lpbk_tx_discards; | |
| 5114 | + __le64 lpbk_tx_errors; | |
| 5115 | + __le64 lpbk_rx_discards; | |
| 5116 | + __le64 lpbk_rx_errors; | |
| 5079 | 5117 | }; |
| 5080 | 5118 | |
| 5081 | 5119 | /* hwrm_port_ecn_qstats_input (size:256b/32B) */ |
| @@ -5140,13 +5178,15 @@ struct hwrm_port_clr_stats_output { · 58 unmodified lines | ||
| 5140 | 5178 | u8 valid; |
| 5141 | 5179 | }; |
| 5142 | 5180 | |
| 5143 | −/* hwrm_port_lpbk_clr_stats_input (size:128b/16B) */ | |
| 5181 | +/* hwrm_port_lpbk_clr_stats_input (size:192b/24B) */ | |
| 5144 | 5182 | struct hwrm_port_lpbk_clr_stats_input { |
| 5145 | 5183 | __le16 req_type; |
| 5146 | 5184 | __le16 cmpl_ring; |
| 5147 | 5185 | __le16 seq_id; |
| 5148 | 5186 | __le16 target_id; |
| 5149 | 5187 | __le64 resp_addr; |
| 5188 | + __le16 port_id; | |
| 5189 | + u8 unused_0[6]; | |
| 5150 | 5190 | }; |
| 5151 | 5191 | |
| 5152 | 5192 | /* hwrm_port_lpbk_clr_stats_output (size:128b/16B) */ |
| @@ -5287,10 +5327,11 @@ struct hwrm_port_phy_qcaps_output { · 134 unmodified lines | ||
| 5287 | 5327 | #define PORT_PHY_QCAPS_RESP_SUPPORTED_PAM4_SPEEDS_FORCE_MODE_100G 0x2UL |
| 5288 | 5328 | #define PORT_PHY_QCAPS_RESP_SUPPORTED_PAM4_SPEEDS_FORCE_MODE_200G 0x4UL |
| 5289 | 5329 | __le16 flags2; |
| 5290 | − #define PORT_PHY_QCAPS_RESP_FLAGS2_PAUSE_UNSUPPORTED 0x1UL | |
| 5291 | − #define PORT_PHY_QCAPS_RESP_FLAGS2_PFC_UNSUPPORTED 0x2UL | |
| 5292 | − #define PORT_PHY_QCAPS_RESP_FLAGS2_BANK_ADDR_SUPPORTED 0x4UL | |
| 5293 | − #define PORT_PHY_QCAPS_RESP_FLAGS2_SPEEDS2_SUPPORTED 0x8UL | |
| 5330 | + #define PORT_PHY_QCAPS_RESP_FLAGS2_PAUSE_UNSUPPORTED 0x1UL | |
| 5331 | + #define PORT_PHY_QCAPS_RESP_FLAGS2_PFC_UNSUPPORTED 0x2UL | |
| 5332 | + #define PORT_PHY_QCAPS_RESP_FLAGS2_BANK_ADDR_SUPPORTED 0x4UL | |
| 5333 | + #define PORT_PHY_QCAPS_RESP_FLAGS2_SPEEDS2_SUPPORTED 0x8UL | |
| 5334 | + #define PORT_PHY_QCAPS_RESP_FLAGS2_REMOTE_LPBK_UNSUPPORTED 0x10UL | |
| 5294 | 5335 | u8 internal_port_cnt; |
| 5295 | 5336 | u8 unused_0; |
| 5296 | 5337 | __le16 supported_speeds2_force_mode; |
| @@ -7443,17 +7484,17 @@ struct hwrm_cfa_l2_filter_cfg_input { · 2146 unmodified lines | ||
| 7443 | 7484 | __le16 target_id; |
| 7444 | 7485 | __le64 resp_addr; |
| 7445 | 7486 | __le32 flags; |
| 7446 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_PATH 0x1UL | |
| 7447 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_PATH_TX 0x0UL | |
| 7448 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_PATH_RX 0x1UL | |
| 7449 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_PATH_LAST CFA_L2_FILTER_CFG_REQ_FLAGS_PATH_RX | |
| 7450 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_DROP 0x2UL | |
| 7451 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_MASK 0xcUL | |
| 7452 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_SFT 2 | |
| 7453 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_NO_ROCE_L2 (0x0UL << 2) | |
| 7454 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_L2 (0x1UL << 2) | |
| 7455 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_ROCE (0x2UL << 2) | |
| 7456 | − #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_LAST CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_ROCE | |
| 7487 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_PATH 0x1UL | |
| 7488 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_PATH_TX 0x0UL | |
| 7489 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_PATH_RX 0x1UL | |
| 7490 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_PATH_LAST CFA_L2_FILTER_CFG_REQ_FLAGS_PATH_RX | |
| 7491 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_DROP 0x2UL | |
| 7492 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_MASK 0xcUL | |
| 7493 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_SFT 2 | |
| 7494 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_NO_ROCE_L2 (0x0UL << 2) | |
| 7495 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_L2 (0x1UL << 2) | |
| 7496 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_ROCE (0x2UL << 2) | |
| 7497 | + #define CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_LAST CFA_L2_FILTER_CFG_REQ_FLAGS_TRAFFIC_ROCE | |
| 7457 | 7498 | #define CFA_L2_FILTER_CFG_REQ_FLAGS_REMAP_OP_MASK 0x30UL |
| 7458 | 7499 | #define CFA_L2_FILTER_CFG_REQ_FLAGS_REMAP_OP_SFT 4 |
| 7459 | 7500 | #define CFA_L2_FILTER_CFG_REQ_FLAGS_REMAP_OP_NO_UPDATE (0x0UL << 4) |
| @@ -8520,17 +8561,17 @@ struct hwrm_tunnel_dst_port_query_input { · 1060 unmodified lines | ||
| 8520 | 8561 | __le16 target_id; |
| 8521 | 8562 | __le64 resp_addr; |
| 8522 | 8563 | u8 tunnel_type; |
| 8523 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN 0x1UL | |
| 8524 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_GENEVE 0x5UL | |
| 8525 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 8526 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_IPGRE_V1 0xaUL | |
| 8527 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_L2_ETYPE 0xbUL | |
| 8528 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN_GPE_V6 0xcUL | |
| 8529 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_CUSTOM_GRE 0xdUL | |
| 8530 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_ECPRI 0xeUL | |
| 8531 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_SRV6 0xfUL | |
| 8532 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN_GPE 0x10UL | |
| 8533 | − #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_GRE 0x11UL | |
| 8564 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN 0x1UL | |
| 8565 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_GENEVE 0x5UL | |
| 8566 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 8567 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_IPGRE_V1 0xaUL | |
| 8568 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_L2_ETYPE 0xbUL | |
| 8569 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN_GPE_V6 0xcUL | |
| 8570 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_CUSTOM_GRE 0xdUL | |
| 8571 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_ECPRI 0xeUL | |
| 8572 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_SRV6 0xfUL | |
| 8573 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN_GPE 0x10UL | |
| 8574 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_GRE 0x11UL | |
| 8534 | 8575 | #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_ULP_DYN_UPAR 0x12UL |
| 8535 | 8576 | #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_ULP_DYN_UPAR_RES01 0x13UL |
| 8536 | 8577 | #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_ULP_DYN_UPAR_RES02 0x14UL |
| @@ -8576,17 +8617,17 @@ struct hwrm_tunnel_dst_port_alloc_input { · 39 unmodified lines | ||
| 8576 | 8617 | __le16 target_id; |
| 8577 | 8618 | __le64 resp_addr; |
| 8578 | 8619 | u8 tunnel_type; |
| 8579 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN 0x1UL | |
| 8580 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE 0x5UL | |
| 8581 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 8582 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_IPGRE_V1 0xaUL | |
| 8583 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_L2_ETYPE 0xbUL | |
| 8584 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN_GPE_V6 0xcUL | |
| 8585 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_CUSTOM_GRE 0xdUL | |
| 8586 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_ECPRI 0xeUL | |
| 8587 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_SRV6 0xfUL | |
| 8588 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN_GPE 0x10UL | |
| 8589 | − #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GRE 0x11UL | |
| 8620 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN 0x1UL | |
| 8621 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE 0x5UL | |
| 8622 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 8623 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_IPGRE_V1 0xaUL | |
| 8624 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_L2_ETYPE 0xbUL | |
| 8625 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN_GPE_V6 0xcUL | |
| 8626 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_CUSTOM_GRE 0xdUL | |
| 8627 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_ECPRI 0xeUL | |
| 8628 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_SRV6 0xfUL | |
| 8629 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN_GPE 0x10UL | |
| 8630 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GRE 0x11UL | |
| 8590 | 8631 | #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_ULP_DYN_UPAR 0x12UL |
| 8591 | 8632 | #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_ULP_DYN_UPAR_RES01 0x13UL |
| 8592 | 8633 | #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_ULP_DYN_UPAR_RES02 0x14UL |
| @@ -8635,17 +8676,17 @@ struct hwrm_tunnel_dst_port_free_input { · 42 unmodified lines | ||
| 8635 | 8676 | __le16 target_id; |
| 8636 | 8677 | __le64 resp_addr; |
| 8637 | 8678 | u8 tunnel_type; |
| 8638 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN 0x1UL | |
| 8639 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE 0x5UL | |
| 8640 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 8641 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_IPGRE_V1 0xaUL | |
| 8642 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_L2_ETYPE 0xbUL | |
| 8643 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN_GPE_V6 0xcUL | |
| 8644 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_CUSTOM_GRE 0xdUL | |
| 8645 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_ECPRI 0xeUL | |
| 8646 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_SRV6 0xfUL | |
| 8647 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN_GPE 0x10UL | |
| 8648 | − #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GRE 0x11UL | |
| 8679 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN 0x1UL | |
| 8680 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE 0x5UL | |
| 8681 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 8682 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_IPGRE_V1 0xaUL | |
| 8683 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_L2_ETYPE 0xbUL | |
| 8684 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN_GPE_V6 0xcUL | |
| 8685 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_CUSTOM_GRE 0xdUL | |
| 8686 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_ECPRI 0xeUL | |
| 8687 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_SRV6 0xfUL | |
| 8688 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN_GPE 0x10UL | |
| 8689 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GRE 0x11UL | |
| 8649 | 8690 | #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_ULP_DYN_UPAR 0x12UL |
| 8650 | 8691 | #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_ULP_DYN_UPAR_RES01 0x13UL |
| 8651 | 8692 | #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_ULP_DYN_UPAR_RES02 0x14UL |
| @@ -9109,6 +9150,7 @@ struct hwrm_struct_hdr { · 457 unmodified lines | ||
| 9109 | 9150 | #define STRUCT_HDR_STRUCT_ID_LLDP_GENERIC 0x424UL |
| 9110 | 9151 | #define STRUCT_HDR_STRUCT_ID_LLDP_DEVICE 0x426UL |
| 9111 | 9152 | #define STRUCT_HDR_STRUCT_ID_POWER_BKUP 0x427UL |
| 9153 | + #define STRUCT_HDR_STRUCT_ID_PEER_MMAP 0x429UL | |
| 9112 | 9154 | #define STRUCT_HDR_STRUCT_ID_AFM_OPAQUE 0x1UL |
| 9113 | 9155 | #define STRUCT_HDR_STRUCT_ID_PORT_DESCRIPTION 0xaUL |
| 9114 | 9156 | #define STRUCT_HDR_STRUCT_ID_RSS_V2 0x64UL |
| @@ -9758,6 +9800,9 @@ struct hwrm_dbg_coredump_initiate_input { · 643 unmodified lines | ||
| 9758 | 9800 | __le16 instance; |
| 9759 | 9801 | __le16 unused_0; |
| 9760 | 9802 | u8 seg_flags; |
| 9803 | + #define DBG_COREDUMP_INITIATE_REQ_SEG_FLAGS_LIVE_DATA 0x1UL | |
| 9804 | + #define DBG_COREDUMP_INITIATE_REQ_SEG_FLAGS_CRASH_DATA 0x2UL | |
| 9805 | + #define DBG_COREDUMP_INITIATE_REQ_SEG_FLAGS_COLLECT_CTX_L1_CACHE 0x4UL | |
| 9761 | 9806 | u8 unused_1[7]; |
| 9762 | 9807 | }; |
| 9763 | 9808 | |
| @@ -10433,13 +10478,13 @@ struct hwrm_selftest_irq_output { · 669 unmodified lines | ||
| 10433 | 10478 | |
| 10434 | 10479 | /* dbc_dbc (size:64b/8B) */ |
| 10435 | 10480 | struct dbc_dbc { |
| 10436 | − u32 index; | |
| 10481 | + __le32 index; | |
| 10437 | 10482 | #define DBC_DBC_INDEX_MASK 0xffffffUL |
| 10438 | 10483 | #define DBC_DBC_INDEX_SFT 0 |
| 10439 | 10484 | #define DBC_DBC_EPOCH 0x1000000UL |
| 10440 | 10485 | #define DBC_DBC_TOGGLE_MASK 0x6000000UL |
| 10441 | 10486 | #define DBC_DBC_TOGGLE_SFT 25 |
| 10442 | − u32 type_path_xid; | |
| 10487 | + __le32 type_path_xid; | |
| 10443 | 10488 | #define DBC_DBC_XID_MASK 0xfffffUL |
| 10444 | 10489 | #define DBC_DBC_XID_SFT 0 |
| 10445 | 10490 | #define DBC_DBC_PATH_MASK 0x3000000UL |
| @@ -1339,6 +1339,7 @@ ice_dwnld_cfg_bufs_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 start, · 1338 unmodified lines | ||
| 1339 | 1339 | |
| 1340 | 1340 | for (i = 0; i < count; i++) { |
| 1341 | 1341 | bool last = false; |
| 1342 | + int try_cnt = 0; | |
| 1342 | 1343 | int status; |
| 1343 | 1344 | |
| 1344 | 1345 | bh = (struct ice_buf_hdr *)(bufs + start + i); |
| @@ -1346,8 +1347,26 @@ ice_dwnld_cfg_bufs_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 start, · 1 unmodified line | ||
| 1346 | 1347 | if (indicate_last) |
| 1347 | 1348 | last = ice_is_last_download_buffer(bh, i, count); |
| 1348 | 1349 | |
| 1349 | − status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last, | |
| 1350 | − &offset, &info, NULL); | |
| 1350 | + while (1) { | |
| 1351 | + status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, | |
| 1352 | + last, &offset, &info, | |
| 1353 | + NULL); | |
| 1354 | + if (hw->adminq.sq_last_status != ICE_AQ_RC_ENOSEC && | |
| 1355 | + hw->adminq.sq_last_status != ICE_AQ_RC_EBADSIG) | |
| 1356 | + break; | |
| 1357 | + | |
| 1358 | + try_cnt++; | |
| 1359 | + | |
| 1360 | + if (try_cnt == 5) | |
| 1361 | + break; | |
| 1362 | + | |
| 1363 | + msleep(20); | |
| 1364 | + } | |
| 1365 | + | |
| 1366 | + if (try_cnt) | |
| 1367 | + dev_dbg(ice_hw_to_dev(hw), | |
| 1368 | + "ice_aq_download_pkg number of retries: %d\n", | |
| 1369 | + try_cnt); | |
| 1351 | 1370 | |
| 1352 | 1371 | /* Save AQ status from download package */ |
| 1353 | 1372 | if (status) { |
| @@ -805,6 +805,9 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup) · 804 unmodified lines | ||
| 805 | 805 | } |
| 806 | 806 | |
| 807 | 807 | switch (vsi->port_info->phy.link_info.link_speed) { |
| 808 | + case ICE_AQ_LINK_SPEED_200GB: | |
| 809 | + speed = "200 G"; | |
| 810 | + break; | |
| 808 | 811 | case ICE_AQ_LINK_SPEED_100GB: |
| 809 | 812 | speed = "100 G"; |
| 810 | 813 | break; |
| @@ -5564,7 +5567,7 @@ static int ice_suspend(struct device *dev) · 4753 unmodified lines | ||
| 5564 | 5567 | */ |
| 5565 | 5568 | disabled = ice_service_task_stop(pf); |
| 5566 | 5569 | |
| 5567 | − ice_unplug_aux_dev(pf); | |
| 5570 | + ice_deinit_rdma(pf); | |
| 5568 | 5571 | |
| 5569 | 5572 | /* Already suspended?, then there is nothing to do */ |
| 5570 | 5573 | if (test_and_set_bit(ICE_SUSPENDED, pf->state)) { |
| @@ -5644,6 +5647,11 @@ static int ice_resume(struct device *dev) · 73 unmodified lines | ||
| 5644 | 5647 | if (ret) |
| 5645 | 5648 | dev_err(dev, "Cannot restore interrupt scheme: %d\n", ret); |
| 5646 | 5649 | |
| 5650 | + ret = ice_init_rdma(pf); | |
| 5651 | + if (ret) | |
| 5652 | + dev_err(dev, "Reinitialize RDMA during resume failed: %d\n", | |
| 5653 | + ret); | |
| 5654 | + | |
| 5647 | 5655 | clear_bit(ICE_DOWN, pf->state); |
| 5648 | 5656 | /* Now perform PF reset and rebuild */ |
| 5649 | 5657 | reset_type = ICE_RESET_PFR; |
| @@ -1899,7 +1899,8 @@ ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, · 1898 unmodified lines | ||
| 1899 | 1899 | lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || |
| 1900 | 1900 | lkup_type == ICE_SW_LKUP_PROMISC || |
| 1901 | 1901 | lkup_type == ICE_SW_LKUP_PROMISC_VLAN || |
| 1902 | − lkup_type == ICE_SW_LKUP_DFLT) { | |
| 1902 | + lkup_type == ICE_SW_LKUP_DFLT || | |
| 1903 | + lkup_type == ICE_SW_LKUP_LAST) { | |
| 1903 | 1904 | sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP); |
| 1904 | 1905 | } else if (lkup_type == ICE_SW_LKUP_VLAN) { |
| 1905 | 1906 | if (opc == ice_aqc_opc_alloc_res) |
| @@ -2922,7 +2923,8 @@ ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, · 1016 unmodified lines | ||
| 2922 | 2923 | lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || |
| 2923 | 2924 | lkup_type == ICE_SW_LKUP_PROMISC || |
| 2924 | 2925 | lkup_type == ICE_SW_LKUP_PROMISC_VLAN || |
| 2925 | − lkup_type == ICE_SW_LKUP_DFLT) | |
| 2926 | + lkup_type == ICE_SW_LKUP_DFLT || | |
| 2927 | + lkup_type == ICE_SW_LKUP_LAST) | |
| 2926 | 2928 | rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR : |
| 2927 | 2929 | ICE_AQC_SW_RULES_T_VSI_LIST_SET; |
| 2928 | 2930 | else if (lkup_type == ICE_SW_LKUP_VLAN) |
| @@ -4014,7 +4014,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, · 4013 unmodified lines | ||
| 4014 | 4014 | } |
| 4015 | 4015 | } |
| 4016 | 4016 | |
| 4017 | − skb = build_skb(data, frag_size); | |
| 4017 | + if (frag_size) | |
| 4018 | + skb = build_skb(data, frag_size); | |
| 4019 | + else | |
| 4020 | + skb = slab_build_skb(data); | |
| 4018 | 4021 | if (!skb) { |
| 4019 | 4022 | netdev_warn(port->dev, "skb build failed\n"); |
| 4020 | 4023 | goto err_drop_frame; |
| @@ -9,10 +9,9 @@ obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o otx2_ptp.o · 8 unmodified lines | ||
| 9 | 9 | rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \ |
| 10 | 10 | otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \ |
| 11 | 11 | otx2_devlink.o qos_sq.o qos.o |
| 12 | −rvu_nicvf-y := otx2_vf.o otx2_devlink.o | |
| 12 | +rvu_nicvf-y := otx2_vf.o | |
| 13 | 13 | |
| 14 | 14 | rvu_nicpf-$(CONFIG_DCB) += otx2_dcbnl.o |
| 15 | −rvu_nicvf-$(CONFIG_DCB) += otx2_dcbnl.o | |
| 16 | 15 | rvu_nicpf-$(CONFIG_MACSEC) += cn10k_macsec.o |
| 17 | 16 | |
| 18 | 17 | ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af |
| @@ -54,6 +54,7 @@ int otx2_pfc_txschq_config(struct otx2_nic *pfvf) · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | return 0; |
| 56 | 56 | } |
| 57 | +EXPORT_SYMBOL(otx2_pfc_txschq_config); | |
| 57 | 58 | |
| 58 | 59 | static int otx2_pfc_txschq_alloc_one(struct otx2_nic *pfvf, u8 prio) |
| 59 | 60 | { |
| @@ -122,6 +123,7 @@ int otx2_pfc_txschq_alloc(struct otx2_nic *pfvf) · 62 unmodified lines | ||
| 122 | 123 | |
| 123 | 124 | return 0; |
| 124 | 125 | } |
| 126 | +EXPORT_SYMBOL(otx2_pfc_txschq_alloc); | |
| 125 | 127 | |
| 126 | 128 | static int otx2_pfc_txschq_stop_one(struct otx2_nic *pfvf, u8 prio) |
| 127 | 129 | { |
| @@ -260,6 +262,7 @@ update_sq_smq_map: · 132 unmodified lines | ||
| 260 | 262 | |
| 261 | 263 | return 0; |
| 262 | 264 | } |
| 265 | +EXPORT_SYMBOL(otx2_pfc_txschq_update); | |
| 263 | 266 | |
| 264 | 267 | int otx2_pfc_txschq_stop(struct otx2_nic *pfvf) |
| 265 | 268 | { |
| @@ -282,6 +285,7 @@ int otx2_pfc_txschq_stop(struct otx2_nic *pfvf) · 16 unmodified lines | ||
| 282 | 285 | |
| 283 | 286 | return 0; |
| 284 | 287 | } |
| 288 | +EXPORT_SYMBOL(otx2_pfc_txschq_stop); | |
| 285 | 289 | |
| 286 | 290 | int otx2_config_priority_flow_ctrl(struct otx2_nic *pfvf) |
| 287 | 291 | { |
| @@ -321,6 +325,7 @@ unlock: · 33 unmodified lines | ||
| 321 | 325 | mutex_unlock(&pfvf->mbox.lock); |
| 322 | 326 | return err; |
| 323 | 327 | } |
| 328 | +EXPORT_SYMBOL(otx2_config_priority_flow_ctrl); | |
| 324 | 329 | |
| 325 | 330 | void otx2_update_bpid_in_rqctx(struct otx2_nic *pfvf, int vlan_prio, int qidx, |
| 326 | 331 | bool pfc_enable) |
| @@ -385,6 +390,7 @@ out: · 58 unmodified lines | ||
| 385 | 390 | "Updating BPIDs in CQ and Aura contexts of RQ%d failed with err %d\n", |
| 386 | 391 | qidx, err); |
| 387 | 392 | } |
| 393 | +EXPORT_SYMBOL(otx2_update_bpid_in_rqctx); | |
| 388 | 394 | |
| 389 | 395 | static int otx2_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc) |
| 390 | 396 | { |
| @@ -472,3 +478,4 @@ int otx2_dcbnl_set_ops(struct net_device *dev) · 81 unmodified lines | ||
| 472 | 478 | |
| 473 | 479 | return 0; |
| 474 | 480 | } |
| 481 | +EXPORT_SYMBOL(otx2_dcbnl_set_ops); | |
| @@ -113,6 +113,7 @@ err_dl: · 112 unmodified lines | ||
| 113 | 113 | devlink_free(dl); |
| 114 | 114 | return err; |
| 115 | 115 | } |
| 116 | +EXPORT_SYMBOL(otx2_register_dl); | |
| 116 | 117 | |
| 117 | 118 | void otx2_unregister_dl(struct otx2_nic *pfvf) |
| 118 | 119 | { |
| @@ -124,3 +125,4 @@ void otx2_unregister_dl(struct otx2_nic *pfvf) · 5 unmodified lines | ||
| 124 | 125 | ARRAY_SIZE(otx2_dl_params)); |
| 125 | 126 | devlink_free(dl); |
| 126 | 127 | } |
| 128 | +EXPORT_SYMBOL(otx2_unregister_dl); | |
| @@ -1174,8 +1174,11 @@ bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq, · 1173 unmodified lines | ||
| 1174 | 1174 | |
| 1175 | 1175 | if (skb_shinfo(skb)->gso_size && !is_hw_tso_supported(pfvf, skb)) { |
| 1176 | 1176 | /* Insert vlan tag before giving pkt to tso */ |
| 1177 | − if (skb_vlan_tag_present(skb)) | |
| 1177 | + if (skb_vlan_tag_present(skb)) { | |
| 1178 | 1178 | skb = __vlan_hwaccel_push_inside(skb); |
| 1179 | + if (!skb) | |
| 1180 | + return true; | |
| 1181 | + } | |
| 1179 | 1182 | otx2_sq_append_tso(pfvf, sq, skb, qidx); |
| 1180 | 1183 | return true; |
| 1181 | 1184 | } |
| @@ -1127,8 +1127,12 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev, · 1126 unmodified lines | ||
| 1127 | 1127 | if (netdev->phydev) |
| 1128 | 1128 | phy_ethtool_get_wol(netdev->phydev, wol); |
| 1129 | 1129 | |
| 1130 | − wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | | |
| 1131 | − WAKE_MAGIC | WAKE_PHY | WAKE_ARP; | |
| 1130 | + if (wol->supported != adapter->phy_wol_supported) | |
| 1131 | + netif_warn(adapter, drv, adapter->netdev, | |
| 1132 | + "PHY changed its supported WOL! old=%x, new=%x\n", | |
| 1133 | + adapter->phy_wol_supported, wol->supported); | |
| 1134 | + | |
| 1135 | + wol->supported |= MAC_SUPPORTED_WAKES; | |
| 1132 | 1136 | |
| 1133 | 1137 | if (adapter->is_pci11x1x) |
| 1134 | 1138 | wol->supported |= WAKE_MAGICSECURE; |
| @@ -1143,7 +1147,39 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev, · 8 unmodified lines | ||
| 1143 | 1147 | { |
| 1144 | 1148 | struct lan743x_adapter *adapter = netdev_priv(netdev); |
| 1145 | 1149 | |
| 1150 | + /* WAKE_MAGICSEGURE is a modifier of and only valid together with | |
| 1151 | + * WAKE_MAGIC | |
| 1152 | + */ | |
| 1153 | + if ((wol->wolopts & WAKE_MAGICSECURE) && !(wol->wolopts & WAKE_MAGIC)) | |
| 1154 | + return -EINVAL; | |
| 1155 | + | |
| 1156 | + if (netdev->phydev) { | |
| 1157 | + struct ethtool_wolinfo phy_wol; | |
| 1158 | + int ret; | |
| 1159 | + | |
| 1160 | + phy_wol.wolopts = wol->wolopts & adapter->phy_wol_supported; | |
| 1161 | + | |
| 1162 | + /* If WAKE_MAGICSECURE was requested, filter out WAKE_MAGIC | |
| 1163 | + * for PHYs that do not support WAKE_MAGICSECURE | |
| 1164 | + */ | |
| 1165 | + if (wol->wolopts & WAKE_MAGICSECURE && | |
| 1166 | + !(adapter->phy_wol_supported & WAKE_MAGICSECURE)) | |
| 1167 | + phy_wol.wolopts &= ~WAKE_MAGIC; | |
| 1168 | + | |
| 1169 | + ret = phy_ethtool_set_wol(netdev->phydev, &phy_wol); | |
| 1170 | + if (ret && (ret != -EOPNOTSUPP)) | |
| 1171 | + return ret; | |
| 1172 | + | |
| 1173 | + if (ret == -EOPNOTSUPP) | |
| 1174 | + adapter->phy_wolopts = 0; | |
| 1175 | + else | |
| 1176 | + adapter->phy_wolopts = phy_wol.wolopts; | |
| 1177 | + } else { | |
| 1178 | + adapter->phy_wolopts = 0; | |
| 1179 | + } | |
| 1180 | + | |
| 1146 | 1181 | adapter->wolopts = 0; |
| 1182 | + wol->wolopts &= ~adapter->phy_wolopts; | |
| 1147 | 1183 | if (wol->wolopts & WAKE_UCAST) |
| 1148 | 1184 | adapter->wolopts |= WAKE_UCAST; |
| 1149 | 1185 | if (wol->wolopts & WAKE_MCAST) |
| @@ -1164,10 +1200,10 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev, · 14 unmodified lines | ||
| 1164 | 1200 | memset(adapter->sopass, 0, sizeof(u8) * SOPASS_MAX); |
| 1165 | 1201 | } |
| 1166 | 1202 | |
| 1203 | + wol->wolopts = adapter->wolopts | adapter->phy_wolopts; | |
| 1167 | 1204 | device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts); |
| 1168 | 1205 | |
| 1169 | − return netdev->phydev ? phy_ethtool_set_wol(netdev->phydev, wol) | |
| 1170 | − : -ENETDOWN; | |
| 1206 | + return 0; | |
| 1171 | 1207 | } |
| 1172 | 1208 | #endif /* CONFIG_PM */ |
| 1173 | 1209 | |
| @@ -3118,6 +3118,17 @@ static int lan743x_netdev_open(struct net_device *netdev) · 3117 unmodified lines | ||
| 3118 | 3118 | if (ret) |
| 3119 | 3119 | goto close_tx; |
| 3120 | 3120 | } |
| 3121 | + | |
| 3122 | +#ifdef CONFIG_PM | |
| 3123 | + if (adapter->netdev->phydev) { | |
| 3124 | + struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; | |
| 3125 | + | |
| 3126 | + phy_ethtool_get_wol(netdev->phydev, &wol); | |
| 3127 | + adapter->phy_wol_supported = wol.supported; | |
| 3128 | + adapter->phy_wolopts = wol.wolopts; | |
| 3129 | + } | |
| 3130 | +#endif | |
| 3131 | + | |
| 3121 | 3132 | return 0; |
| 3122 | 3133 | |
| 3123 | 3134 | close_tx: |
| @@ -3575,7 +3586,7 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) · 451 unmodified lines | ||
| 3575 | 3586 | |
| 3576 | 3587 | /* clear wake settings */ |
| 3577 | 3588 | pmtctl = lan743x_csr_read(adapter, PMT_CTL); |
| 3578 | − pmtctl |= PMT_CTL_WUPS_MASK_; | |
| 3589 | + pmtctl |= PMT_CTL_WUPS_MASK_ | PMT_CTL_RES_CLR_WKP_MASK_; | |
| 3579 | 3590 | pmtctl &= ~(PMT_CTL_GPIO_WAKEUP_EN_ | PMT_CTL_EEE_WAKEUP_EN_ | |
| 3580 | 3591 | PMT_CTL_WOL_EN_ | PMT_CTL_MAC_D3_RX_CLK_OVR_ | |
| 3581 | 3592 | PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_ | PMT_CTL_ETH_PHY_WAKE_EN_); |
| @@ -3587,10 +3598,9 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) · 5 unmodified lines | ||
| 3587 | 3598 | |
| 3588 | 3599 | pmtctl |= PMT_CTL_ETH_PHY_D3_COLD_OVR_ | PMT_CTL_ETH_PHY_D3_OVR_; |
| 3589 | 3600 | |
| 3590 | − if (adapter->wolopts & WAKE_PHY) { | |
| 3591 | − pmtctl |= PMT_CTL_ETH_PHY_EDPD_PLL_CTL_; | |
| 3601 | + if (adapter->phy_wolopts) | |
| 3592 | 3602 | pmtctl |= PMT_CTL_ETH_PHY_WAKE_EN_; |
| 3593 | − } | |
| 3603 | + | |
| 3594 | 3604 | if (adapter->wolopts & WAKE_MAGIC) { |
| 3595 | 3605 | wucsr |= MAC_WUCSR_MPEN_; |
| 3596 | 3606 | macrx |= MAC_RX_RXEN_; |
| @@ -3686,7 +3696,7 @@ static int lan743x_pm_suspend(struct device *dev) · 89 unmodified lines | ||
| 3686 | 3696 | lan743x_csr_write(adapter, MAC_WUCSR2, 0); |
| 3687 | 3697 | lan743x_csr_write(adapter, MAC_WK_SRC, 0xFFFFFFFF); |
| 3688 | 3698 | |
| 3689 | − if (adapter->wolopts) | |
| 3699 | + if (adapter->wolopts || adapter->phy_wolopts) | |
| 3690 | 3700 | lan743x_pm_set_wol(adapter); |
| 3691 | 3701 | |
| 3692 | 3702 | if (adapter->is_pci11x1x) { |
| @@ -3710,6 +3720,7 @@ static int lan743x_pm_resume(struct device *dev) · 17 unmodified lines | ||
| 3710 | 3720 | struct pci_dev *pdev = to_pci_dev(dev); |
| 3711 | 3721 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 3712 | 3722 | struct lan743x_adapter *adapter = netdev_priv(netdev); |
| 3723 | + u32 data; | |
| 3713 | 3724 | int ret; |
| 3714 | 3725 | |
| 3715 | 3726 | pci_set_power_state(pdev, PCI_D0); |
| @@ -3728,6 +3739,30 @@ static int lan743x_pm_resume(struct device *dev) · 12 unmodified lines | ||
| 3728 | 3739 | return ret; |
| 3729 | 3740 | } |
| 3730 | 3741 | |
| 3742 | + ret = lan743x_csr_read(adapter, MAC_WK_SRC); | |
| 3743 | + netif_dbg(adapter, drv, adapter->netdev, | |
| 3744 | + "Wakeup source : 0x%08X\n", ret); | |
| 3745 | + | |
| 3746 | + /* Clear the wol configuration and status bits. Note that | |
| 3747 | + * the status bits are "Write One to Clear (W1C)" | |
| 3748 | + */ | |
| 3749 | + data = MAC_WUCSR_EEE_TX_WAKE_ | MAC_WUCSR_EEE_RX_WAKE_ | | |
| 3750 | + MAC_WUCSR_RFE_WAKE_FR_ | MAC_WUCSR_PFDA_FR_ | MAC_WUCSR_WUFR_ | | |
| 3751 | + MAC_WUCSR_MPR_ | MAC_WUCSR_BCAST_FR_; | |
| 3752 | + lan743x_csr_write(adapter, MAC_WUCSR, data); | |
| 3753 | + | |
| 3754 | + data = MAC_WUCSR2_NS_RCD_ | MAC_WUCSR2_ARP_RCD_ | | |
| 3755 | + MAC_WUCSR2_IPV6_TCPSYN_RCD_ | MAC_WUCSR2_IPV4_TCPSYN_RCD_; | |
| 3756 | + lan743x_csr_write(adapter, MAC_WUCSR2, data); | |
| 3757 | + | |
| 3758 | + data = MAC_WK_SRC_ETH_PHY_WK_ | MAC_WK_SRC_IPV6_TCPSYN_RCD_WK_ | | |
| 3759 | + MAC_WK_SRC_IPV4_TCPSYN_RCD_WK_ | MAC_WK_SRC_EEE_TX_WK_ | | |
| 3760 | + MAC_WK_SRC_EEE_RX_WK_ | MAC_WK_SRC_RFE_FR_WK_ | | |
| 3761 | + MAC_WK_SRC_PFDA_FR_WK_ | MAC_WK_SRC_MP_FR_WK_ | | |
| 3762 | + MAC_WK_SRC_BCAST_FR_WK_ | MAC_WK_SRC_WU_FR_WK_ | | |
| 3763 | + MAC_WK_SRC_WK_FR_SAVED_; | |
| 3764 | + lan743x_csr_write(adapter, MAC_WK_SRC, data); | |
| 3765 | + | |
| 3731 | 3766 | /* open netdev when netdev is at running state while resume. |
| 3732 | 3767 | * For instance, it is true when system wakesup after pm-suspend |
| 3733 | 3768 | * However, it is false when system wakes up after suspend GUI menu |
| @@ -3736,9 +3771,6 @@ static int lan743x_pm_resume(struct device *dev) · 2 unmodified lines | ||
| 3736 | 3771 | lan743x_netdev_open(netdev); |
| 3737 | 3772 | |
| 3738 | 3773 | netif_device_attach(netdev); |
| 3739 | − ret = lan743x_csr_read(adapter, MAC_WK_SRC); | |
| 3740 | − netif_info(adapter, drv, adapter->netdev, | |
| 3741 | − "Wakeup source : 0x%08X\n", ret); | |
| 3742 | 3774 | |
| 3743 | 3775 | return 0; |
| 3744 | 3776 | } |
| @@ -61,6 +61,7 @@ · 60 unmodified lines | ||
| 61 | 61 | #define PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_ BIT(18) |
| 62 | 62 | #define PMT_CTL_GPIO_WAKEUP_EN_ BIT(15) |
| 63 | 63 | #define PMT_CTL_EEE_WAKEUP_EN_ BIT(13) |
| 64 | +#define PMT_CTL_RES_CLR_WKP_MASK_ GENMASK(9, 8) | |
| 64 | 65 | #define PMT_CTL_READY_ BIT(7) |
| 65 | 66 | #define PMT_CTL_ETH_PHY_RST_ BIT(4) |
| 66 | 67 | #define PMT_CTL_WOL_EN_ BIT(3) |
| @@ -227,12 +228,31 @@ · 160 unmodified lines | ||
| 227 | 228 | #define MAC_WUCSR (0x140) |
| 228 | 229 | #define MAC_MP_SO_EN_ BIT(21) |
| 229 | 230 | #define MAC_WUCSR_RFE_WAKE_EN_ BIT(14) |
| 231 | +#define MAC_WUCSR_EEE_TX_WAKE_ BIT(13) | |
| 232 | +#define MAC_WUCSR_EEE_RX_WAKE_ BIT(11) | |
| 233 | +#define MAC_WUCSR_RFE_WAKE_FR_ BIT(9) | |
| 234 | +#define MAC_WUCSR_PFDA_FR_ BIT(7) | |
| 235 | +#define MAC_WUCSR_WUFR_ BIT(6) | |
| 236 | +#define MAC_WUCSR_MPR_ BIT(5) | |
| 237 | +#define MAC_WUCSR_BCAST_FR_ BIT(4) | |
| 230 | 238 | #define MAC_WUCSR_PFDA_EN_ BIT(3) |
| 231 | 239 | #define MAC_WUCSR_WAKE_EN_ BIT(2) |
| 232 | 240 | #define MAC_WUCSR_MPEN_ BIT(1) |
| 233 | 241 | #define MAC_WUCSR_BCST_EN_ BIT(0) |
| 234 | 242 | |
| 235 | 243 | #define MAC_WK_SRC (0x144) |
| 244 | +#define MAC_WK_SRC_ETH_PHY_WK_ BIT(17) | |
| 245 | +#define MAC_WK_SRC_IPV6_TCPSYN_RCD_WK_ BIT(16) | |
| 246 | +#define MAC_WK_SRC_IPV4_TCPSYN_RCD_WK_ BIT(15) | |
| 247 | +#define MAC_WK_SRC_EEE_TX_WK_ BIT(14) | |
| 248 | +#define MAC_WK_SRC_EEE_RX_WK_ BIT(13) | |
| 249 | +#define MAC_WK_SRC_RFE_FR_WK_ BIT(12) | |
| 250 | +#define MAC_WK_SRC_PFDA_FR_WK_ BIT(11) | |
| 251 | +#define MAC_WK_SRC_MP_FR_WK_ BIT(10) | |
| 252 | +#define MAC_WK_SRC_BCAST_FR_WK_ BIT(9) | |
| 253 | +#define MAC_WK_SRC_WU_FR_WK_ BIT(8) | |
| 254 | +#define MAC_WK_SRC_WK_FR_SAVED_ BIT(7) | |
| 255 | + | |
| 236 | 256 | #define MAC_MP_SO_HI (0x148) |
| 237 | 257 | #define MAC_MP_SO_LO (0x14C) |
| 238 | 258 | |
| @@ -295,6 +315,10 @@ · 56 unmodified lines | ||
| 295 | 315 | #define RFE_INDX(index) (0x580 + (index << 2)) |
| 296 | 316 | |
| 297 | 317 | #define MAC_WUCSR2 (0x600) |
| 318 | +#define MAC_WUCSR2_NS_RCD_ BIT(7) | |
| 319 | +#define MAC_WUCSR2_ARP_RCD_ BIT(6) | |
| 320 | +#define MAC_WUCSR2_IPV6_TCPSYN_RCD_ BIT(5) | |
| 321 | +#define MAC_WUCSR2_IPV4_TCPSYN_RCD_ BIT(4) | |
| 298 | 322 | |
| 299 | 323 | #define SGMII_ACC (0x720) |
| 300 | 324 | #define SGMII_ACC_SGMII_BZY_ BIT(31) |
| @@ -1018,6 +1042,8 @@ enum lan743x_sgmii_lsd { · 717 unmodified lines | ||
| 1018 | 1042 | LINK_2500_SLAVE |
| 1019 | 1043 | }; |
| 1020 | 1044 | |
| 1045 | +#define MAC_SUPPORTED_WAKES (WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | \ | |
| 1046 | + WAKE_MAGIC | WAKE_ARP) | |
| 1021 | 1047 | struct lan743x_adapter { |
| 1022 | 1048 | struct net_device *netdev; |
| 1023 | 1049 | struct mii_bus *mdiobus; |
| @@ -1025,6 +1051,8 @@ struct lan743x_adapter { · 1 unmodified line | ||
| 1025 | 1051 | #ifdef CONFIG_PM |
| 1026 | 1052 | u32 wolopts; |
| 1027 | 1053 | u8 sopass[SOPASS_MAX]; |
| 1054 | + u32 phy_wolopts; | |
| 1055 | + u32 phy_wol_supported; | |
| 1028 | 1056 | #endif |
| 1029 | 1057 | struct pci_dev *pdev; |
| 1030 | 1058 | struct lan743x_csr csr; |
| @@ -98,10 +98,8 @@ qcaspi_info_show(struct seq_file *s, void *what) · 97 unmodified lines | ||
| 98 | 98 | |
| 99 | 99 | seq_printf(s, "IRQ : %d\n", |
| 100 | 100 | qca->spi_dev->irq); |
| 101 | − seq_printf(s, "INTR REQ : %u\n", | |
| 102 | − qca->intr_req); | |
| 103 | − seq_printf(s, "INTR SVC : %u\n", | |
| 104 | − qca->intr_svc); | |
| 101 | + seq_printf(s, "INTR : %lx\n", | |
| 102 | + qca->intr); | |
| 105 | 103 | |
| 106 | 104 | seq_printf(s, "SPI max speed : %lu\n", |
| 107 | 105 | (unsigned long)qca->spi_dev->max_speed_hz); |
| @@ -35,6 +35,8 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | #define MAX_DMA_BURST_LEN 5000 |
| 37 | 37 | |
| 38 | +#define SPI_INTR 0 | |
| 39 | + | |
| 38 | 40 | /* Modules parameters */ |
| 39 | 41 | #define QCASPI_CLK_SPEED_MIN 1000000 |
| 40 | 42 | #define QCASPI_CLK_SPEED_MAX 16000000 |
| @@ -579,14 +581,14 @@ qcaspi_spi_thread(void *data) · 538 unmodified lines | ||
| 579 | 581 | continue; |
| 580 | 582 | } |
| 581 | 583 | |
| 582 | − if ((qca->intr_req == qca->intr_svc) && | |
| 584 | + if (!test_bit(SPI_INTR, &qca->intr) && | |
| 583 | 585 | !qca->txr.skb[qca->txr.head]) |
| 584 | 586 | schedule(); |
| 585 | 587 | |
| 586 | 588 | set_current_state(TASK_RUNNING); |
| 587 | 589 | |
| 588 | − netdev_dbg(qca->net_dev, "have work to do. int: %d, tx_skb: %p\n", | |
| 589 | − qca->intr_req - qca->intr_svc, | |
| 590 | + netdev_dbg(qca->net_dev, "have work to do. int: %lu, tx_skb: %p\n", | |
| 591 | + qca->intr, | |
| 590 | 592 | qca->txr.skb[qca->txr.head]); |
| 591 | 593 | |
| 592 | 594 | qcaspi_qca7k_sync(qca, QCASPI_EVENT_UPDATE); |
| @@ -600,8 +602,7 @@ qcaspi_spi_thread(void *data) · 7 unmodified lines | ||
| 600 | 602 | msleep(QCASPI_QCA7K_REBOOT_TIME_MS); |
| 601 | 603 | } |
| 602 | 604 | |
| 603 | − if (qca->intr_svc != qca->intr_req) { | |
| 604 | − qca->intr_svc = qca->intr_req; | |
| 605 | + if (test_and_clear_bit(SPI_INTR, &qca->intr)) { | |
| 605 | 606 | start_spi_intr_handling(qca, &intr_cause); |
| 606 | 607 | |
| 607 | 608 | if (intr_cause & SPI_INT_CPU_ON) { |
| @@ -663,7 +664,7 @@ qcaspi_intr_handler(int irq, void *data) · 55 unmodified lines | ||
| 663 | 664 | { |
| 664 | 665 | struct qcaspi *qca = data; |
| 665 | 666 | |
| 666 | − qca->intr_req++; | |
| 667 | + set_bit(SPI_INTR, &qca->intr); | |
| 667 | 668 | if (qca->spi_thread) |
| 668 | 669 | wake_up_process(qca->spi_thread); |
| 669 | 670 | |
| @@ -679,8 +680,7 @@ qcaspi_netdev_open(struct net_device *dev) · 9 unmodified lines | ||
| 679 | 680 | if (!qca) |
| 680 | 681 | return -EINVAL; |
| 681 | 682 | |
| 682 | − qca->intr_req = 1; | |
| 683 | − qca->intr_svc = 0; | |
| 683 | + set_bit(SPI_INTR, &qca->intr); | |
| 684 | 684 | qca->sync = QCASPI_SYNC_UNKNOWN; |
| 685 | 685 | qcafrm_fsm_init_spi(&qca->frm_handle); |
| 686 | 686 | |
| @@ -81,8 +81,7 @@ struct qcaspi { · 80 unmodified lines | ||
| 81 | 81 | struct qcafrm_handle frm_handle; |
| 82 | 82 | struct sk_buff *rx_skb; |
| 83 | 83 | |
| 84 | − unsigned int intr_req; | |
| 85 | − unsigned int intr_svc; | |
| 84 | + unsigned long intr; | |
| 86 | 85 | u16 reset_count; |
| 87 | 86 | |
| 88 | 87 | #ifdef CONFIG_DEBUG_FS |
| @@ -218,6 +218,7 @@ static void timestamp_interrupt(struct stmmac_priv *priv) · 217 unmodified lines | ||
| 218 | 218 | { |
| 219 | 219 | u32 num_snapshot, ts_status, tsync_int; |
| 220 | 220 | struct ptp_clock_event event; |
| 221 | + u32 acr_value, channel; | |
| 221 | 222 | unsigned long flags; |
| 222 | 223 | u64 ptp_time; |
| 223 | 224 | int i; |
| @@ -243,12 +244,15 @@ static void timestamp_interrupt(struct stmmac_priv *priv) · 19 unmodified lines | ||
| 243 | 244 | num_snapshot = (ts_status & GMAC_TIMESTAMP_ATSNS_MASK) >> |
| 244 | 245 | GMAC_TIMESTAMP_ATSNS_SHIFT; |
| 245 | 246 | |
| 247 | + acr_value = readl(priv->ptpaddr + PTP_ACR); | |
| 248 | + channel = ilog2(FIELD_GET(PTP_ACR_MASK, acr_value)); | |
| 249 | + | |
| 246 | 250 | for (i = 0; i < num_snapshot; i++) { |
| 247 | 251 | read_lock_irqsave(&priv->ptp_lock, flags); |
| 248 | 252 | get_ptptime(priv->ptpaddr, &ptp_time); |
| 249 | 253 | read_unlock_irqrestore(&priv->ptp_lock, flags); |
| 250 | 254 | event.type = PTP_CLOCK_EXTTS; |
| 251 | − event.index = 0; | |
| 255 | + event.index = channel; | |
| 252 | 256 | event.timestamp = ptp_time; |
| 253 | 257 | ptp_clock_event(priv->ptp_clock, &event); |
| 254 | 258 | } |
| @@ -358,24 +358,28 @@ static int tc_setup_cbs(struct stmmac_priv *priv, · 357 unmodified lines | ||
| 358 | 358 | |
| 359 | 359 | port_transmit_rate_kbps = qopt->idleslope - qopt->sendslope; |
| 360 | 360 | |
| 361 | − /* Port Transmit Rate and Speed Divider */ | |
| 362 | − switch (div_s64(port_transmit_rate_kbps, 1000)) { | |
| 363 | − case SPEED_10000: | |
| 364 | − case SPEED_5000: | |
| 365 | − ptr = 32; | |
| 366 | − break; | |
| 367 | − case SPEED_2500: | |
| 368 | − case SPEED_1000: | |
| 369 | − ptr = 8; | |
| 370 | − break; | |
| 371 | − case SPEED_100: | |
| 372 | − ptr = 4; | |
| 373 | − break; | |
| 374 | − default: | |
| 375 | − netdev_err(priv->dev, | |
| 376 | − "Invalid portTransmitRate %lld (idleSlope - sendSlope)\n", | |
| 377 | − port_transmit_rate_kbps); | |
| 378 | − return -EINVAL; | |
| 361 | + if (qopt->enable) { | |
| 362 | + /* Port Transmit Rate and Speed Divider */ | |
| 363 | + switch (div_s64(port_transmit_rate_kbps, 1000)) { | |
| 364 | + case SPEED_10000: | |
| 365 | + case SPEED_5000: | |
| 366 | + ptr = 32; | |
| 367 | + break; | |
| 368 | + case SPEED_2500: | |
| 369 | + case SPEED_1000: | |
| 370 | + ptr = 8; | |
| 371 | + break; | |
| 372 | + case SPEED_100: | |
| 373 | + ptr = 4; | |
| 374 | + break; | |
| 375 | + default: | |
| 376 | + netdev_err(priv->dev, | |
| 377 | + "Invalid portTransmitRate %lld (idleSlope - sendSlope)\n", | |
| 378 | + port_transmit_rate_kbps); | |
| 379 | + return -EINVAL; | |
| 380 | + } | |
| 381 | + } else { | |
| 382 | + ptr = 0; | |
| 379 | 383 | } |
| 380 | 384 | |
| 381 | 385 | mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use; |
| @@ -17,6 +17,11 @@ · 16 unmodified lines | ||
| 17 | 17 | #define DP83TG720S_PHY_RESET 0x1f |
| 18 | 18 | #define DP83TG720S_HW_RESET BIT(15) |
| 19 | 19 | |
| 20 | +#define DP83TG720S_LPS_CFG3 0x18c | |
| 21 | +/* Power modes are documented as bit fields but used as values */ | |
| 22 | +/* Power Mode 0 is Normal mode */ | |
| 23 | +#define DP83TG720S_LPS_CFG3_PWR_MODE_0 BIT(0) | |
| 24 | + | |
| 20 | 25 | #define DP83TG720S_RGMII_DELAY_CTRL 0x602 |
| 21 | 26 | /* In RGMII mode, Enable or disable the internal delay for RXD */ |
| 22 | 27 | #define DP83TG720S_RGMII_RX_CLK_SEL BIT(1) |
| @@ -31,11 +36,20 @@ · 8 unmodified lines | ||
| 31 | 36 | |
| 32 | 37 | static int dp83tg720_config_aneg(struct phy_device *phydev) |
| 33 | 38 | { |
| 39 | + int ret; | |
| 40 | + | |
| 34 | 41 | /* Autoneg is not supported and this PHY supports only one speed. |
| 35 | 42 | * We need to care only about master/slave configuration if it was |
| 36 | 43 | * changed by user. |
| 37 | 44 | */ |
| 38 | − return genphy_c45_pma_baset1_setup_master_slave(phydev); | |
| 45 | + ret = genphy_c45_pma_baset1_setup_master_slave(phydev); | |
| 46 | + if (ret) | |
| 47 | + return ret; | |
| 48 | + | |
| 49 | + /* Re-read role configuration to make changes visible even if | |
| 50 | + * the link is in administrative down state. | |
| 51 | + */ | |
| 52 | + return genphy_c45_pma_baset1_read_master_slave(phydev); | |
| 39 | 53 | } |
| 40 | 54 | |
| 41 | 55 | static int dp83tg720_read_status(struct phy_device *phydev) |
| @@ -64,6 +78,8 @@ static int dp83tg720_read_status(struct phy_device *phydev) · 22 unmodified lines | ||
| 64 | 78 | return ret; |
| 65 | 79 | |
| 66 | 80 | /* After HW reset we need to restore master/slave configuration. |
| 81 | + * genphy_c45_pma_baset1_read_master_slave() call will be done | |
| 82 | + * by the dp83tg720_config_aneg() function. | |
| 67 | 83 | */ |
| 68 | 84 | ret = dp83tg720_config_aneg(phydev); |
| 69 | 85 | if (ret) |
| @@ -154,10 +170,24 @@ static int dp83tg720_config_init(struct phy_device *phydev) · 84 unmodified lines | ||
| 154 | 170 | */ |
| 155 | 171 | usleep_range(1000, 2000); |
| 156 | 172 | |
| 157 | − if (phy_interface_is_rgmii(phydev)) | |
| 158 | − return dp83tg720_config_rgmii_delay(phydev); | |
| 173 | + if (phy_interface_is_rgmii(phydev)) { | |
| 174 | + ret = dp83tg720_config_rgmii_delay(phydev); | |
| 175 | + if (ret) | |
| 176 | + return ret; | |
| 177 | + } | |
| 178 | + | |
| 179 | + /* In case the PHY is bootstrapped in managed mode, we need to | |
| 180 | + * wake it. | |
| 181 | + */ | |
| 182 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LPS_CFG3, | |
| 183 | + DP83TG720S_LPS_CFG3_PWR_MODE_0); | |
| 184 | + if (ret) | |
| 185 | + return ret; | |
| 159 | 186 | |
| 160 | − return 0; | |
| 187 | + /* Make role configuration visible for ethtool on init and after | |
| 188 | + * rest. | |
| 189 | + */ | |
| 190 | + return genphy_c45_pma_baset1_read_master_slave(phydev); | |
| 161 | 191 | } |
| 162 | 192 | |
| 163 | 193 | static struct phy_driver dp83tg720_driver[] = { |
| @@ -107,6 +107,7 @@ struct gpy_priv { · 106 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | u8 fw_major; |
| 109 | 109 | u8 fw_minor; |
| 110 | + u32 wolopts; | |
| 110 | 111 | |
| 111 | 112 | /* It takes 3 seconds to fully switch out of loopback mode before |
| 112 | 113 | * it can safely re-enter loopback mode. Record the time when |
| @@ -221,6 +222,15 @@ static int gpy_hwmon_register(struct phy_device *phydev) · 108 unmodified lines | ||
| 221 | 222 | } |
| 222 | 223 | #endif |
| 223 | 224 | |
| 225 | +static int gpy_ack_interrupt(struct phy_device *phydev) | |
| 226 | +{ | |
| 227 | + int ret; | |
| 228 | + | |
| 229 | + /* Clear all pending interrupts */ | |
| 230 | + ret = phy_read(phydev, PHY_ISTAT); | |
| 231 | + return ret < 0 ? ret : 0; | |
| 232 | +} | |
| 233 | + | |
| 224 | 234 | static int gpy_mbox_read(struct phy_device *phydev, u32 addr) |
| 225 | 235 | { |
| 226 | 236 | struct gpy_priv *priv = phydev->priv; |
| @@ -262,16 +272,8 @@ out: · 35 unmodified lines | ||
| 262 | 272 | |
| 263 | 273 | static int gpy_config_init(struct phy_device *phydev) |
| 264 | 274 | { |
| 265 | − int ret; | |
| 266 | − | |
| 267 | − /* Mask all interrupts */ | |
| 268 | − ret = phy_write(phydev, PHY_IMASK, 0); | |
| 269 | − if (ret) | |
| 270 | − return ret; | |
| 271 | − | |
| 272 | − /* Clear all pending interrupts */ | |
| 273 | − ret = phy_read(phydev, PHY_ISTAT); | |
| 274 | − return ret < 0 ? ret : 0; | |
| 275 | + /* Nothing to configure. Configuration Requirement Placeholder */ | |
| 276 | + return 0; | |
| 275 | 277 | } |
| 276 | 278 | |
| 277 | 279 | static int gpy21x_config_init(struct phy_device *phydev) |
| @@ -627,11 +629,23 @@ static int gpy_read_status(struct phy_device *phydev) · 349 unmodified lines | ||
| 627 | 629 | |
| 628 | 630 | static int gpy_config_intr(struct phy_device *phydev) |
| 629 | 631 | { |
| 632 | + struct gpy_priv *priv = phydev->priv; | |
| 630 | 633 | u16 mask = 0; |
| 634 | + int ret; | |
| 635 | + | |
| 636 | + ret = gpy_ack_interrupt(phydev); | |
| 637 | + if (ret) | |
| 638 | + return ret; | |
| 631 | 639 | |
| 632 | 640 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
| 633 | 641 | mask = PHY_IMASK_MASK; |
| 634 | 642 | |
| 643 | + if (priv->wolopts & WAKE_MAGIC) | |
| 644 | + mask |= PHY_IMASK_WOL; | |
| 645 | + | |
| 646 | + if (priv->wolopts & WAKE_PHY) | |
| 647 | + mask |= PHY_IMASK_LSTC; | |
| 648 | + | |
| 635 | 649 | return phy_write(phydev, PHY_IMASK, mask); |
| 636 | 650 | } |
| 637 | 651 | |
| @@ -678,6 +692,7 @@ static int gpy_set_wol(struct phy_device *phydev, · 40 unmodified lines | ||
| 678 | 692 | struct ethtool_wolinfo *wol) |
| 679 | 693 | { |
| 680 | 694 | struct net_device *attach_dev = phydev->attached_dev; |
| 695 | + struct gpy_priv *priv = phydev->priv; | |
| 681 | 696 | int ret; |
| 682 | 697 | |
| 683 | 698 | if (wol->wolopts & WAKE_MAGIC) { |
| @@ -725,6 +740,8 @@ static int gpy_set_wol(struct phy_device *phydev, · 41 unmodified lines | ||
| 725 | 740 | ret = phy_read(phydev, PHY_ISTAT); |
| 726 | 741 | if (ret < 0) |
| 727 | 742 | return ret; |
| 743 | + | |
| 744 | + priv->wolopts |= WAKE_MAGIC; | |
| 728 | 745 | } else { |
| 729 | 746 | /* Disable magic packet matching */ |
| 730 | 747 | ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, |
| @@ -732,6 +749,13 @@ static int gpy_set_wol(struct phy_device *phydev, · 1 unmodified line | ||
| 732 | 749 | WOL_EN); |
| 733 | 750 | if (ret < 0) |
| 734 | 751 | return ret; |
| 752 | + | |
| 753 | + /* Disable the WOL interrupt */ | |
| 754 | + ret = phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_WOL); | |
| 755 | + if (ret < 0) | |
| 756 | + return ret; | |
| 757 | + | |
| 758 | + priv->wolopts &= ~WAKE_MAGIC; | |
| 735 | 759 | } |
| 736 | 760 | |
| 737 | 761 | if (wol->wolopts & WAKE_PHY) { |
| @@ -748,9 +772,11 @@ static int gpy_set_wol(struct phy_device *phydev, · 10 unmodified lines | ||
| 748 | 772 | if (ret & (PHY_IMASK_MASK & ~PHY_IMASK_LSTC)) |
| 749 | 773 | phy_trigger_machine(phydev); |
| 750 | 774 | |
| 775 | + priv->wolopts |= WAKE_PHY; | |
| 751 | 776 | return 0; |
| 752 | 777 | } |
| 753 | 778 | |
| 779 | + priv->wolopts &= ~WAKE_PHY; | |
| 754 | 780 | /* Disable the link state change interrupt */ |
| 755 | 781 | return phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_LSTC); |
| 756 | 782 | } |
| @@ -758,18 +784,10 @@ static int gpy_set_wol(struct phy_device *phydev, · 1 unmodified line | ||
| 758 | 784 | static void gpy_get_wol(struct phy_device *phydev, |
| 759 | 785 | struct ethtool_wolinfo *wol) |
| 760 | 786 | { |
| 761 | − int ret; | |
| 787 | + struct gpy_priv *priv = phydev->priv; | |
| 762 | 788 | |
| 763 | 789 | wol->supported = WAKE_MAGIC | WAKE_PHY; |
| 764 | − wol->wolopts = 0; | |
| 765 | − | |
| 766 | − ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, VPSPEC2_WOL_CTL); | |
| 767 | − if (ret & WOL_EN) | |
| 768 | − wol->wolopts |= WAKE_MAGIC; | |
| 769 | − | |
| 770 | − ret = phy_read(phydev, PHY_IMASK); | |
| 771 | − if (ret & PHY_IMASK_LSTC) | |
| 772 | − wol->wolopts |= WAKE_PHY; | |
| 790 | + wol->wolopts = priv->wolopts; | |
| 773 | 791 | } |
| 774 | 792 | |
| 775 | 793 | static int gpy_loopback(struct phy_device *phydev, bool enable) |
| @@ -174,7 +174,6 @@ struct ax88179_data { · 173 unmodified lines | ||
| 174 | 174 | u32 wol_supported; |
| 175 | 175 | u32 wolopts; |
| 176 | 176 | u8 disconnecting; |
| 177 | − u8 initialized; | |
| 178 | 177 | }; |
| 179 | 178 | |
| 180 | 179 | struct ax88179_int_data { |
| @@ -1678,12 +1677,21 @@ static int ax88179_reset(struct usbnet *dev) · 1497 unmodified lines | ||
| 1678 | 1677 | |
| 1679 | 1678 | static int ax88179_net_reset(struct usbnet *dev) |
| 1680 | 1679 | { |
| 1681 | − struct ax88179_data *ax179_data = dev->driver_priv; | |
| 1680 | + u16 tmp16; | |
| 1682 | 1681 | |
| 1683 | − if (ax179_data->initialized) | |
| 1682 | + ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, GMII_PHY_PHYSR, | |
| 1683 | + 2, &tmp16); | |
| 1684 | + if (tmp16) { | |
| 1685 | + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, | |
| 1686 | + 2, 2, &tmp16); | |
| 1687 | + if (!(tmp16 & AX_MEDIUM_RECEIVE_EN)) { | |
| 1688 | + tmp16 |= AX_MEDIUM_RECEIVE_EN; | |
| 1689 | + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, | |
| 1690 | + 2, 2, &tmp16); | |
| 1691 | + } | |
| 1692 | + } else { | |
| 1684 | 1693 | ax88179_reset(dev); |
| 1685 | − else | |
| 1686 | − ax179_data->initialized = 1; | |
| 1694 | + } | |
| 1687 | 1695 | |
| 1688 | 1696 | return 0; |
| 1689 | 1697 | } |
| @@ -778,7 +778,8 @@ static int rtl8150_get_link_ksettings(struct net_device *netdev, · 777 unmodified lines | ||
| 778 | 778 | struct ethtool_link_ksettings *ecmd) |
| 779 | 779 | { |
| 780 | 780 | rtl8150_t *dev = netdev_priv(netdev); |
| 781 | − short lpa, bmcr; | |
| 781 | + short lpa = 0; | |
| 782 | + short bmcr = 0; | |
| 782 | 783 | u32 supported; |
| 783 | 784 | |
| 784 | 785 | supported = (SUPPORTED_10baseT_Half | |
| @@ -1360,6 +1360,10 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev, · 1359 unmodified lines | ||
| 1360 | 1360 | if (unlikely(hdr->hdr.gso_type)) |
| 1361 | 1361 | goto err_xdp; |
| 1362 | 1362 | |
| 1363 | + /* Partially checksummed packets must be dropped. */ | |
| 1364 | + if (unlikely(hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) | |
| 1365 | + goto err_xdp; | |
| 1366 | + | |
| 1363 | 1367 | buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + |
| 1364 | 1368 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
| 1365 | 1369 | |
| @@ -1677,6 +1681,10 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi, · 311 unmodified lines | ||
| 1677 | 1681 | if (unlikely(hdr->hdr.gso_type)) |
| 1678 | 1682 | return NULL; |
| 1679 | 1683 | |
| 1684 | + /* Partially checksummed packets must be dropped. */ | |
| 1685 | + if (unlikely(hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) | |
| 1686 | + return NULL; | |
| 1687 | + | |
| 1680 | 1688 | /* Now XDP core assumes frag size is PAGE_SIZE, but buffers |
| 1681 | 1689 | * with headroom may add hole in truesize, which |
| 1682 | 1690 | * make their length exceed PAGE_SIZE. So we disabled the |
| @@ -1943,6 +1951,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, · 260 unmodified lines | ||
| 1943 | 1951 | struct net_device *dev = vi->dev; |
| 1944 | 1952 | struct sk_buff *skb; |
| 1945 | 1953 | struct virtio_net_common_hdr *hdr; |
| 1954 | + u8 flags; | |
| 1946 | 1955 | |
| 1947 | 1956 | if (unlikely(len < vi->hdr_len + ETH_HLEN)) { |
| 1948 | 1957 | pr_debug("%s: short packet %i\n", dev->name, len); |
| @@ -1951,6 +1960,15 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, · 2 unmodified lines | ||
| 1951 | 1960 | return; |
| 1952 | 1961 | } |
| 1953 | 1962 | |
| 1963 | + /* 1. Save the flags early, as the XDP program might overwrite them. | |
| 1964 | + * These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID | |
| 1965 | + * stay valid after XDP processing. | |
| 1966 | + * 2. XDP doesn't work with partially checksummed packets (refer to | |
| 1967 | + * virtnet_xdp_set()), so packets marked as | |
| 1968 | + * VIRTIO_NET_HDR_F_NEEDS_CSUM get dropped during XDP processing. | |
| 1969 | + */ | |
| 1970 | + flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags; | |
| 1971 | + | |
| 1954 | 1972 | if (vi->mergeable_rx_bufs) |
| 1955 | 1973 | skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit, |
| 1956 | 1974 | stats); |
| @@ -1966,7 +1984,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, · 9 unmodified lines | ||
| 1966 | 1984 | if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report) |
| 1967 | 1985 | virtio_skb_set_hash(&hdr->hash_v1_hdr, skb); |
| 1968 | 1986 | |
| 1969 | − if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID) | |
| 1987 | + if (flags & VIRTIO_NET_HDR_F_DATA_VALID) | |
| 1970 | 1988 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 1971 | 1989 | |
| 1972 | 1990 | if (virtio_net_hdr_to_skb(skb, &hdr->hdr, |
| @@ -5666,8 +5684,16 @@ static int virtnet_probe(struct virtio_device *vdev) · 3693 unmodified lines | ||
| 5666 | 5684 | dev->features |= dev->hw_features & NETIF_F_ALL_TSO; |
| 5667 | 5685 | /* (!csum && gso) case will be fixed by register_netdev() */ |
| 5668 | 5686 | } |
| 5669 | − if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) | |
| 5670 | − dev->features |= NETIF_F_RXCSUM; | |
| 5687 | + | |
| 5688 | + /* 1. With VIRTIO_NET_F_GUEST_CSUM negotiation, the driver doesn't | |
| 5689 | + * need to calculate checksums for partially checksummed packets, | |
| 5690 | + * as they're considered valid by the upper layer. | |
| 5691 | + * 2. Without VIRTIO_NET_F_GUEST_CSUM negotiation, the driver only | |
| 5692 | + * receives fully checksummed packets. The device may assist in | |
| 5693 | + * validating these packets' checksums, so the driver won't have to. | |
| 5694 | + */ | |
| 5695 | + dev->features |= NETIF_F_RXCSUM; | |
| 5696 | + | |
| 5671 | 5697 | if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || |
| 5672 | 5698 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) |
| 5673 | 5699 | dev->features |= NETIF_F_GRO_HW; |
| @@ -4795,7 +4795,7 @@ static int iwl_mvm_roc_station(struct iwl_mvm *mvm, · 4794 unmodified lines | ||
| 4795 | 4795 | |
| 4796 | 4796 | if (fw_ver == IWL_FW_CMD_VER_UNKNOWN) { |
| 4797 | 4797 | ret = iwl_mvm_send_aux_roc_cmd(mvm, channel, vif, duration); |
| 4798 | − } else if (fw_ver == 3) { | |
| 4798 | + } else if (fw_ver >= 3) { | |
| 4799 | 4799 | ret = iwl_mvm_roc_add_cmd(mvm, channel, vif, duration, |
| 4800 | 4800 | ROC_ACTIVITY_HOTSPOT); |
| 4801 | 4801 | } else { |
| @@ -1830,7 +1830,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm, · 1829 unmodified lines | ||
| 1830 | 1830 | */ |
| 1831 | 1831 | if (!iwl_mvm_is_scan_fragmented(params->type)) { |
| 1832 | 1832 | if (!cfg80211_channel_is_psc(params->channels[i]) || |
| 1833 | − flags & IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN) { | |
| 1833 | + psc_no_listen) { | |
| 1834 | 1834 | if (unsolicited_probe_on_chan) { |
| 1835 | 1835 | max_s_ssids = 2; |
| 1836 | 1836 | max_bssids = 6; |
| @@ -1238,6 +1238,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) · 1237 unmodified lines | ||
| 1238 | 1238 | if (te_data->id >= SESSION_PROTECT_CONF_MAX_ID) { |
| 1239 | 1239 | IWL_DEBUG_TE(mvm, |
| 1240 | 1240 | "No remain on channel event\n"); |
| 1241 | + mutex_unlock(&mvm->mutex); | |
| 1241 | 1242 | return; |
| 1242 | 1243 | } |
| 1243 | 1244 | |
| @@ -1253,6 +1254,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) · 9 unmodified lines | ||
| 1253 | 1254 | te_data = iwl_mvm_get_roc_te(mvm); |
| 1254 | 1255 | if (!te_data) { |
| 1255 | 1256 | IWL_WARN(mvm, "No remain on channel event\n"); |
| 1257 | + mutex_unlock(&mvm->mutex); | |
| 1256 | 1258 | return; |
| 1257 | 1259 | } |
| 1258 | 1260 | |
| @@ -187,6 +187,31 @@ static const unsigned int qmp_v6_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { · 186 unmodified lines | ||
| 187 | 187 | [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V6_TX_TRANSCEIVER_BIAS_EN, |
| 188 | 188 | }; |
| 189 | 189 | |
| 190 | +static const unsigned int qmp_v6_n4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { | |
| 191 | + [QPHY_SW_RESET] = QPHY_V6_N4_PCS_SW_RESET, | |
| 192 | + [QPHY_START_CTRL] = QPHY_V6_N4_PCS_START_CONTROL, | |
| 193 | + [QPHY_PCS_STATUS] = QPHY_V6_N4_PCS_PCS_STATUS1, | |
| 194 | + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_N4_PCS_POWER_DOWN_CONTROL, | |
| 195 | + | |
| 196 | + /* In PCS_USB */ | |
| 197 | + [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL, | |
| 198 | + [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, | |
| 199 | + | |
| 200 | + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL, | |
| 201 | + [QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS, | |
| 202 | + [QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS, | |
| 203 | + [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, | |
| 204 | + | |
| 205 | + [QPHY_DP_PHY_STATUS] = QSERDES_V6_DP_PHY_STATUS, | |
| 206 | + [QPHY_DP_PHY_VCO_DIV] = QSERDES_V6_DP_PHY_VCO_DIV, | |
| 207 | + | |
| 208 | + [QPHY_TX_TX_POL_INV] = QSERDES_V6_N4_TX_TX_POL_INV, | |
| 209 | + [QPHY_TX_TX_DRV_LVL] = QSERDES_V6_N4_TX_TX_DRV_LVL, | |
| 210 | + [QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V6_N4_TX_TX_EMP_POST1_LVL, | |
| 211 | + [QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V6_N4_TX_HIGHZ_DRVR_EN, | |
| 212 | + [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V6_N4_TX_TRANSCEIVER_BIAS_EN, | |
| 213 | +}; | |
| 214 | + | |
| 190 | 215 | static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = { |
| 191 | 216 | QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), |
| 192 | 217 | QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14), |
| @@ -997,6 +1022,31 @@ static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl[] = { · 804 unmodified lines | ||
| 997 | 1022 | QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f), |
| 998 | 1023 | }; |
| 999 | 1024 | |
| 1025 | +static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl[] = { | |
| 1026 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SVS_MODE_CLK_SEL, 0x15), | |
| 1027 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x3b), | |
| 1028 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x02), | |
| 1029 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x0c), | |
| 1030 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_BUF_ENABLE, 0x06), | |
| 1031 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x30), | |
| 1032 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x07), | |
| 1033 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36), | |
| 1034 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16), | |
| 1035 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06), | |
| 1036 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), | |
| 1037 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0x00), | |
| 1038 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xc0), | |
| 1039 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x12), | |
| 1040 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), | |
| 1041 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0, 0x00), | |
| 1042 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x00), | |
| 1043 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a), | |
| 1044 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x14), | |
| 1045 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_CTRL, 0x00), | |
| 1046 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x17), | |
| 1047 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f), | |
| 1048 | +}; | |
| 1049 | + | |
| 1000 | 1050 | static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = { |
| 1001 | 1051 | QMP_PHY_INIT_CFG(QSERDES_V6_TX_VMODE_CTRL1, 0x40), |
| 1002 | 1052 | QMP_PHY_INIT_CFG(QSERDES_V6_TX_PRE_STALL_LDO_BOOST_EN, 0x30), |
| @@ -1011,6 +1061,19 @@ static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = { · 8 unmodified lines | ||
| 1011 | 1061 | QMP_PHY_INIT_CFG(QSERDES_V6_TX_TX_BAND, 0x4), |
| 1012 | 1062 | }; |
| 1013 | 1063 | |
| 1064 | +static const struct qmp_phy_init_tbl qmp_v6_n4_dp_tx_tbl[] = { | |
| 1065 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_VMODE_CTRL1, 0x40), | |
| 1066 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_PRE_STALL_LDO_BOOST_EN, 0x00), | |
| 1067 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_INTERFACE_SELECT, 0xff), | |
| 1068 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_CLKBUF_ENABLE, 0x0f), | |
| 1069 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RESET_TSYNC_EN, 0x03), | |
| 1070 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_TRAN_DRVR_EMP_EN, 0x0f), | |
| 1071 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00), | |
| 1072 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_TX, 0x11), | |
| 1073 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_RX, 0x11), | |
| 1074 | + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_TX_BAND, 0x1), | |
| 1075 | +}; | |
| 1076 | + | |
| 1014 | 1077 | static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_rbr[] = { |
| 1015 | 1078 | QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05), |
| 1016 | 1079 | QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), |
| @@ -1059,6 +1122,74 @@ static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_hbr3[] = { · 42 unmodified lines | ||
| 1059 | 1122 | QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), |
| 1060 | 1123 | }; |
| 1061 | 1124 | |
| 1125 | +static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_rbr[] = { | |
| 1126 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05), | |
| 1127 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), | |
| 1128 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x04), | |
| 1129 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b), | |
| 1130 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x37), | |
| 1131 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x04), | |
| 1132 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71), | |
| 1133 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), | |
| 1134 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), | |
| 1135 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_ADJ_PER1, 0x00), | |
| 1136 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x6b), | |
| 1137 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), | |
| 1138 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x92), | |
| 1139 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), | |
| 1140 | +}; | |
| 1141 | + | |
| 1142 | +static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr[] = { | |
| 1143 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x03), | |
| 1144 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), | |
| 1145 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08), | |
| 1146 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b), | |
| 1147 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x07), | |
| 1148 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07), | |
| 1149 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71), | |
| 1150 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), | |
| 1151 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), | |
| 1152 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_ADJ_PER1, 0x00), | |
| 1153 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x6b), | |
| 1154 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), | |
| 1155 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x92), | |
| 1156 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), | |
| 1157 | +}; | |
| 1158 | + | |
| 1159 | +static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr2[] = { | |
| 1160 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01), | |
| 1161 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x46), | |
| 1162 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08), | |
| 1163 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x05), | |
| 1164 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x0f), | |
| 1165 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0e), | |
| 1166 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x97), | |
| 1167 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x10), | |
| 1168 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), | |
| 1169 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_ADJ_PER1, 0x00), | |
| 1170 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x6b), | |
| 1171 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), | |
| 1172 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x18), | |
| 1173 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x02), | |
| 1174 | +}; | |
| 1175 | + | |
| 1176 | +static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr3[] = { | |
| 1177 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x00), | |
| 1178 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), | |
| 1179 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08), | |
| 1180 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b), | |
| 1181 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x17), | |
| 1182 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x15), | |
| 1183 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71), | |
| 1184 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), | |
| 1185 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), | |
| 1186 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_ADJ_PER1, 0x00), | |
| 1187 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x6b), | |
| 1188 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), | |
| 1189 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x92), | |
| 1190 | + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), | |
| 1191 | +}; | |
| 1192 | + | |
| 1062 | 1193 | static const struct qmp_phy_init_tbl sc8280xp_usb43dp_serdes_tbl[] = { |
| 1063 | 1194 | QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01), |
| 1064 | 1195 | QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31), |
| @@ -1273,20 +1404,20 @@ static const struct qmp_phy_init_tbl x1e80100_usb43dp_rx_tbl[] = { · 208 unmodified lines | ||
| 1273 | 1404 | }; |
| 1274 | 1405 | |
| 1275 | 1406 | static const struct qmp_phy_init_tbl x1e80100_usb43dp_pcs_tbl[] = { |
| 1276 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), | |
| 1277 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), | |
| 1278 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_LOCK_DETECT_CONFIG1, 0xc4), | |
| 1279 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_LOCK_DETECT_CONFIG2, 0x89), | |
| 1280 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_LOCK_DETECT_CONFIG3, 0x20), | |
| 1281 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_LOCK_DETECT_CONFIG6, 0x13), | |
| 1282 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_REFGEN_REQ_CONFIG1, 0x21), | |
| 1283 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_RX_SIGDET_LVL, 0x55), | |
| 1284 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_CDR_RESET_TIME, 0x0a), | |
| 1285 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_ALIGN_DETECT_CONFIG1, 0xd4), | |
| 1286 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_ALIGN_DETECT_CONFIG2, 0x30), | |
| 1287 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_PCS_TX_RX_CONFIG, 0x0c), | |
| 1288 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_EQ_CONFIG1, 0x4b), | |
| 1289 | − QMP_PHY_INIT_CFG(QPHY_V6_PCS_EQ_CONFIG5, 0x10), | |
| 1407 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), | |
| 1408 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), | |
| 1409 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG1, 0xc4), | |
| 1410 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG2, 0x89), | |
| 1411 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG3, 0x20), | |
| 1412 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG6, 0x13), | |
| 1413 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_REFGEN_REQ_CONFIG1, 0x21), | |
| 1414 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RX_SIGDET_LVL, 0x55), | |
| 1415 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RX_CONFIG, 0x0a), | |
| 1416 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_ALIGN_DETECT_CONFIG1, 0xd4), | |
| 1417 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_ALIGN_DETECT_CONFIG2, 0x30), | |
| 1418 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_PCS_TX_RX_CONFIG, 0x0c), | |
| 1419 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_EQ_CONFIG1, 0x4b), | |
| 1420 | + QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_EQ_CONFIG5, 0x10), | |
| 1290 | 1421 | }; |
| 1291 | 1422 | |
| 1292 | 1423 | static const struct qmp_phy_init_tbl x1e80100_usb43dp_pcs_usb_tbl[] = { |
| @@ -1794,22 +1925,22 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = { · 501 unmodified lines | ||
| 1794 | 1925 | .pcs_usb_tbl = x1e80100_usb43dp_pcs_usb_tbl, |
| 1795 | 1926 | .pcs_usb_tbl_num = ARRAY_SIZE(x1e80100_usb43dp_pcs_usb_tbl), |
| 1796 | 1927 | |
| 1797 | − .dp_serdes_tbl = qmp_v6_dp_serdes_tbl, | |
| 1798 | − .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl), | |
| 1799 | − .dp_tx_tbl = qmp_v6_dp_tx_tbl, | |
| 1800 | − .dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_dp_tx_tbl), | |
| 1928 | + .dp_serdes_tbl = qmp_v6_n4_dp_serdes_tbl, | |
| 1929 | + .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl), | |
| 1930 | + .dp_tx_tbl = qmp_v6_n4_dp_tx_tbl, | |
| 1931 | + .dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_n4_dp_tx_tbl), | |
| 1801 | 1932 | |
| 1802 | − .serdes_tbl_rbr = qmp_v6_dp_serdes_tbl_rbr, | |
| 1803 | − .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_rbr), | |
| 1804 | − .serdes_tbl_hbr = qmp_v6_dp_serdes_tbl_hbr, | |
| 1805 | − .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr), | |
| 1806 | − .serdes_tbl_hbr2 = qmp_v6_dp_serdes_tbl_hbr2, | |
| 1807 | − .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr2), | |
| 1808 | − .serdes_tbl_hbr3 = qmp_v6_dp_serdes_tbl_hbr3, | |
| 1809 | − .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr3), | |
| 1933 | + .serdes_tbl_rbr = qmp_v6_n4_dp_serdes_tbl_rbr, | |
| 1934 | + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl_rbr), | |
| 1935 | + .serdes_tbl_hbr = qmp_v6_n4_dp_serdes_tbl_hbr, | |
| 1936 | + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl_hbr), | |
| 1937 | + .serdes_tbl_hbr2 = qmp_v6_n4_dp_serdes_tbl_hbr2, | |
| 1938 | + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl_hbr2), | |
| 1939 | + .serdes_tbl_hbr3 = qmp_v6_n4_dp_serdes_tbl_hbr3, | |
| 1940 | + .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl_hbr3), | |
| 1810 | 1941 | |
| 1811 | − .swing_hbr_rbr = &qmp_dp_v5_voltage_swing_hbr_rbr, | |
| 1812 | − .pre_emphasis_hbr_rbr = &qmp_dp_v5_pre_emphasis_hbr_rbr, | |
| 1942 | + .swing_hbr_rbr = &qmp_dp_v6_voltage_swing_hbr_rbr, | |
| 1943 | + .pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr, | |
| 1813 | 1944 | .swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2, |
| 1814 | 1945 | .pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2, |
| 1815 | 1946 | |
| @@ -1822,7 +1953,7 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = { · 6 unmodified lines | ||
| 1822 | 1953 | .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), |
| 1823 | 1954 | .vreg_list = qmp_phy_vreg_l, |
| 1824 | 1955 | .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), |
| 1825 | − .regs = qmp_v45_usb3phy_regs_layout, | |
| 1956 | + .regs = qmp_v6_n4_usb3phy_regs_layout, | |
| 1826 | 1957 | }; |
| 1827 | 1958 | |
| 1828 | 1959 | static const struct qmp_phy_cfg sm6350_usb3dpphy_cfg = { |
| @@ -0,0 +1,32 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* | |
| 3 | + * Copyright (c) 2023, Linaro Limited | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#ifndef QCOM_PHY_QMP_PCS_V6_N4_H_ | |
| 7 | +#define QCOM_PHY_QMP_PCS_V6_N4_H_ | |
| 8 | + | |
| 9 | +/* Only for QMP V6 N4 PHY - USB/PCIe PCS registers */ | |
| 10 | +#define QPHY_V6_N4_PCS_SW_RESET 0x000 | |
| 11 | +#define QPHY_V6_N4_PCS_PCS_STATUS1 0x014 | |
| 12 | +#define QPHY_V6_N4_PCS_POWER_DOWN_CONTROL 0x040 | |
| 13 | +#define QPHY_V6_N4_PCS_START_CONTROL 0x044 | |
| 14 | +#define QPHY_V6_N4_PCS_POWER_STATE_CONFIG1 0x090 | |
| 15 | +#define QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG1 0x0c4 | |
| 16 | +#define QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG2 0x0c8 | |
| 17 | +#define QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG3 0x0cc | |
| 18 | +#define QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG6 0x0d8 | |
| 19 | +#define QPHY_V6_N4_PCS_REFGEN_REQ_CONFIG1 0x0dc | |
| 20 | +#define QPHY_V6_N4_PCS_RX_SIGDET_LVL 0x188 | |
| 21 | +#define QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 | |
| 22 | +#define QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 | |
| 23 | +#define QPHY_V6_N4_PCS_RATE_SLEW_CNTRL1 0x198 | |
| 24 | +#define QPHY_V6_N4_PCS_RX_CONFIG 0x1b0 | |
| 25 | +#define QPHY_V6_N4_PCS_ALIGN_DETECT_CONFIG1 0x1c0 | |
| 26 | +#define QPHY_V6_N4_PCS_ALIGN_DETECT_CONFIG2 0x1c4 | |
| 27 | +#define QPHY_V6_N4_PCS_PCS_TX_RX_CONFIG 0x1d0 | |
| 28 | +#define QPHY_V6_N4_PCS_EQ_CONFIG1 0x1dc | |
| 29 | +#define QPHY_V6_N4_PCS_EQ_CONFIG2 0x1e0 | |
| 30 | +#define QPHY_V6_N4_PCS_EQ_CONFIG5 0x1ec | |
| 31 | + | |
| 32 | +#endif | |
| @@ -6,11 +6,24 @@ · 5 unmodified lines | ||
| 6 | 6 | #ifndef QCOM_PHY_QMP_QSERDES_TXRX_V6_N4_H_ |
| 7 | 7 | #define QCOM_PHY_QMP_QSERDES_TXRX_V6_N4_H_ |
| 8 | 8 | |
| 9 | +#define QSERDES_V6_N4_TX_CLKBUF_ENABLE 0x08 | |
| 10 | +#define QSERDES_V6_N4_TX_TX_EMP_POST1_LVL 0x0c | |
| 11 | +#define QSERDES_V6_N4_TX_TX_DRV_LVL 0x14 | |
| 12 | +#define QSERDES_V6_N4_TX_RESET_TSYNC_EN 0x1c | |
| 13 | +#define QSERDES_V6_N4_TX_PRE_STALL_LDO_BOOST_EN 0x20 | |
| 9 | 14 | #define QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_TX 0x30 |
| 10 | 15 | #define QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_RX 0x34 |
| 16 | +#define QSERDES_V6_N4_TX_TRANSCEIVER_BIAS_EN 0x48 | |
| 17 | +#define QSERDES_V6_N4_TX_HIGHZ_DRVR_EN 0x4c | |
| 18 | +#define QSERDES_V6_N4_TX_TX_POL_INV 0x50 | |
| 19 | +#define QSERDES_V6_N4_TX_PARRATE_REC_DETECT_IDLE_EN 0x54 | |
| 11 | 20 | #define QSERDES_V6_N4_TX_LANE_MODE_1 0x78 |
| 12 | 21 | #define QSERDES_V6_N4_TX_LANE_MODE_2 0x7c |
| 13 | 22 | #define QSERDES_V6_N4_TX_LANE_MODE_3 0x80 |
| 23 | +#define QSERDES_V6_N4_TX_TRAN_DRVR_EMP_EN 0xac | |
| 24 | +#define QSERDES_V6_N4_TX_TX_BAND 0xd8 | |
| 25 | +#define QSERDES_V6_N4_TX_INTERFACE_SELECT 0xe4 | |
| 26 | +#define QSERDES_V6_N4_TX_VMODE_CTRL1 0xb0 | |
| 14 | 27 | |
| 15 | 28 | #define QSERDES_V6_N4_RX_UCDR_FO_GAIN_RATE2 0x8 |
| 16 | 29 | #define QSERDES_V6_N4_RX_UCDR_SO_GAIN_RATE2 0x18 |
| @@ -46,6 +46,8 @@ · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | #include "phy-qcom-qmp-pcs-v6.h" |
| 48 | 48 | |
| 49 | +#include "phy-qcom-qmp-pcs-v6-n4.h" | |
| 50 | + | |
| 49 | 51 | #include "phy-qcom-qmp-pcs-v6_20.h" |
| 50 | 52 | |
| 51 | 53 | #include "phy-qcom-qmp-pcs-v7.h" |
| @@ -296,8 +296,7 @@ static ssize_t max_vclocks_store(struct device *dev, · 295 unmodified lines | ||
| 296 | 296 | if (max < ptp->n_vclocks) |
| 297 | 297 | goto out; |
| 298 | 298 | |
| 299 | − size = sizeof(int) * max; | |
| 300 | − vclock_index = kzalloc(size, GFP_KERNEL); | |
| 299 | + vclock_index = kcalloc(max, sizeof(int), GFP_KERNEL); | |
| 301 | 300 | if (!vclock_index) { |
| 302 | 301 | err = -ENOMEM; |
| 303 | 302 | goto out; |
| @@ -321,22 +321,30 @@ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch, · 320 unmodified lines | ||
| 321 | 321 | * First we need to find the minimal value for prescaler such that |
| 322 | 322 | * |
| 323 | 323 | * period_ns * clkrate |
| 324 | − * ------------------------------ | |
| 324 | + * ------------------------------ < max_arr + 1 | |
| 325 | 325 | * NSEC_PER_SEC * (prescaler + 1) |
| 326 | 326 | * |
| 327 | − * isn't bigger than max_arr. | |
| 327 | + * This equation is equivalent to | |
| 328 | + * | |
| 329 | + * period_ns * clkrate | |
| 330 | + * ---------------------------- < prescaler + 1 | |
| 331 | + * NSEC_PER_SEC * (max_arr + 1) | |
| 332 | + * | |
| 333 | + * Using integer division and knowing that the right hand side is | |
| 334 | + * integer, this is further equivalent to | |
| 335 | + * | |
| 336 | + * (period_ns * clkrate) // (NSEC_PER_SEC * (max_arr + 1)) ≤ prescaler | |
| 328 | 337 | */ |
| 329 | 338 | |
| 330 | 339 | prescaler = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), |
| 331 | − (u64)NSEC_PER_SEC * priv->max_arr); | |
| 332 | − if (prescaler > 0) | |
| 333 | − prescaler -= 1; | |
| 334 | − | |
| 340 | + (u64)NSEC_PER_SEC * ((u64)priv->max_arr + 1)); | |
| 335 | 341 | if (prescaler > MAX_TIM_PSC) |
| 336 | 342 | return -EINVAL; |
| 337 | 343 | |
| 338 | 344 | prd = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), |
| 339 | 345 | (u64)NSEC_PER_SEC * (prescaler + 1)); |
| 346 | + if (!prd) | |
| 347 | + return -EINVAL; | |
| 340 | 348 | |
| 341 | 349 | /* |
| 342 | 350 | * All channels share the same prescaler and counter so when two |
| @@ -673,7 +681,8 @@ static int stm32_pwm_probe(struct platform_device *pdev) · 330 unmodified lines | ||
| 673 | 681 | * .apply() won't overflow. |
| 674 | 682 | */ |
| 675 | 683 | if (clk_get_rate(priv->clk) > 1000000000) |
| 676 | − return dev_err_probe(dev, -EINVAL, "Failed to lock clock\n"); | |
| 684 | + return dev_err_probe(dev, -EINVAL, "Clock freq too high (%lu)\n", | |
| 685 | + clk_get_rate(priv->clk)); | |
| 677 | 686 | |
| 678 | 687 | chip->ops = &stm32pwm_ops; |
| 679 | 688 | |
| @@ -1634,6 +1634,15 @@ config REGULATOR_UNIPHIER · 1633 unmodified lines | ||
| 1634 | 1634 | help |
| 1635 | 1635 | Support for regulators implemented on Socionext UniPhier SoCs. |
| 1636 | 1636 | |
| 1637 | +config REGULATOR_RZG2L_VBCTRL | |
| 1638 | + tristate "Renesas RZ/G2L USB VBUS regulator driver" | |
| 1639 | + depends on ARCH_RZG2L || COMPILE_TEST | |
| 1640 | + depends on OF | |
| 1641 | + select REGMAP_MMIO | |
| 1642 | + default ARCH_RZG2L | |
| 1643 | + help | |
| 1644 | + Support for VBUS regulators implemented on Renesas RZ/G2L SoCs. | |
| 1645 | + | |
| 1637 | 1646 | config REGULATOR_VCTRL |
| 1638 | 1647 | tristate "Voltage controlled regulators" |
| 1639 | 1648 | depends on OF |
| @@ -189,6 +189,7 @@ obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o · 188 unmodified lines | ||
| 189 | 189 | obj-$(CONFIG_REGULATOR_TPS68470) += tps68470-regulator.o |
| 190 | 190 | obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o |
| 191 | 191 | obj-$(CONFIG_REGULATOR_UNIPHIER) += uniphier-regulator.o |
| 192 | +obj-$(CONFIG_REGULATOR_RZG2L_VBCTRL) += renesas-usb-vbus-regulator.o | |
| 192 | 193 | obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o |
| 193 | 194 | obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o |
| 194 | 195 | obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += vqmmc-ipq4019-regulator.o |
| @@ -140,7 +140,7 @@ · 139 unmodified lines | ||
| 140 | 140 | |
| 141 | 141 | #define AXP717_DCDC1_NUM_VOLTAGES 88 |
| 142 | 142 | #define AXP717_DCDC2_NUM_VOLTAGES 107 |
| 143 | −#define AXP717_DCDC3_NUM_VOLTAGES 104 | |
| 143 | +#define AXP717_DCDC3_NUM_VOLTAGES 103 | |
| 144 | 144 | #define AXP717_DCDC_V_OUT_MASK GENMASK(6, 0) |
| 145 | 145 | #define AXP717_LDO_V_OUT_MASK GENMASK(4, 0) |
| 146 | 146 | |
| @@ -763,10 +763,15 @@ static const struct linear_range axp717_dcdc1_ranges[] = { · 616 unmodified lines | ||
| 763 | 763 | REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000), |
| 764 | 764 | }; |
| 765 | 765 | |
| 766 | +/* | |
| 767 | + * The manual says that the last voltage is 3.4V, encoded as 0b1101011 (107), | |
| 768 | + * but every other method proves that this is wrong, so it's really 106 that | |
| 769 | + * programs the final 3.4V. | |
| 770 | + */ | |
| 766 | 771 | static const struct linear_range axp717_dcdc2_ranges[] = { |
| 767 | 772 | REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000), |
| 768 | 773 | REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000), |
| 769 | − REGULATOR_LINEAR_RANGE(1600000, 88, 107, 100000), | |
| 774 | + REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000), | |
| 770 | 775 | }; |
| 771 | 776 | |
| 772 | 777 | static const struct linear_range axp717_dcdc3_ranges[] = { |
| @@ -790,40 +795,40 @@ static const struct regulator_desc axp717_regulators[] = { · 17 unmodified lines | ||
| 790 | 795 | AXP_DESC(AXP717, DCDC4, "dcdc4", "vin4", 1000, 3700, 100, |
| 791 | 796 | AXP717_DCDC4_CONTROL, AXP717_DCDC_V_OUT_MASK, |
| 792 | 797 | AXP717_DCDC_OUTPUT_CONTROL, BIT(3)), |
| 793 | − AXP_DESC(AXP717, ALDO1, "aldo1", "vin1", 500, 3500, 100, | |
| 798 | + AXP_DESC(AXP717, ALDO1, "aldo1", "aldoin", 500, 3500, 100, | |
| 794 | 799 | AXP717_ALDO1_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 795 | 800 | AXP717_LDO0_OUTPUT_CONTROL, BIT(0)), |
| 796 | − AXP_DESC(AXP717, ALDO2, "aldo2", "vin1", 500, 3500, 100, | |
| 801 | + AXP_DESC(AXP717, ALDO2, "aldo2", "aldoin", 500, 3500, 100, | |
| 797 | 802 | AXP717_ALDO2_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 798 | 803 | AXP717_LDO0_OUTPUT_CONTROL, BIT(1)), |
| 799 | − AXP_DESC(AXP717, ALDO3, "aldo3", "vin1", 500, 3500, 100, | |
| 804 | + AXP_DESC(AXP717, ALDO3, "aldo3", "aldoin", 500, 3500, 100, | |
| 800 | 805 | AXP717_ALDO3_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 801 | 806 | AXP717_LDO0_OUTPUT_CONTROL, BIT(2)), |
| 802 | − AXP_DESC(AXP717, ALDO4, "aldo4", "vin1", 500, 3500, 100, | |
| 807 | + AXP_DESC(AXP717, ALDO4, "aldo4", "aldoin", 500, 3500, 100, | |
| 803 | 808 | AXP717_ALDO4_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 804 | 809 | AXP717_LDO0_OUTPUT_CONTROL, BIT(3)), |
| 805 | − AXP_DESC(AXP717, BLDO1, "bldo1", "vin1", 500, 3500, 100, | |
| 810 | + AXP_DESC(AXP717, BLDO1, "bldo1", "bldoin", 500, 3500, 100, | |
| 806 | 811 | AXP717_BLDO1_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 807 | 812 | AXP717_LDO0_OUTPUT_CONTROL, BIT(4)), |
| 808 | − AXP_DESC(AXP717, BLDO2, "bldo2", "vin1", 500, 3500, 100, | |
| 813 | + AXP_DESC(AXP717, BLDO2, "bldo2", "bldoin", 500, 3500, 100, | |
| 809 | 814 | AXP717_BLDO2_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 810 | 815 | AXP717_LDO0_OUTPUT_CONTROL, BIT(5)), |
| 811 | − AXP_DESC(AXP717, BLDO3, "bldo3", "vin1", 500, 3500, 100, | |
| 816 | + AXP_DESC(AXP717, BLDO3, "bldo3", "bldoin", 500, 3500, 100, | |
| 812 | 817 | AXP717_BLDO3_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 813 | 818 | AXP717_LDO0_OUTPUT_CONTROL, BIT(6)), |
| 814 | − AXP_DESC(AXP717, BLDO4, "bldo4", "vin1", 500, 3500, 100, | |
| 819 | + AXP_DESC(AXP717, BLDO4, "bldo4", "bldoin", 500, 3500, 100, | |
| 815 | 820 | AXP717_BLDO4_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 816 | 821 | AXP717_LDO0_OUTPUT_CONTROL, BIT(7)), |
| 817 | − AXP_DESC(AXP717, CLDO1, "cldo1", "vin1", 500, 3500, 100, | |
| 822 | + AXP_DESC(AXP717, CLDO1, "cldo1", "cldoin", 500, 3500, 100, | |
| 818 | 823 | AXP717_CLDO1_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 819 | 824 | AXP717_LDO1_OUTPUT_CONTROL, BIT(0)), |
| 820 | − AXP_DESC(AXP717, CLDO2, "cldo2", "vin1", 500, 3500, 100, | |
| 825 | + AXP_DESC(AXP717, CLDO2, "cldo2", "cldoin", 500, 3500, 100, | |
| 821 | 826 | AXP717_CLDO2_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 822 | 827 | AXP717_LDO1_OUTPUT_CONTROL, BIT(1)), |
| 823 | − AXP_DESC(AXP717, CLDO3, "cldo3", "vin1", 500, 3500, 100, | |
| 828 | + AXP_DESC(AXP717, CLDO3, "cldo3", "cldoin", 500, 3500, 100, | |
| 824 | 829 | AXP717_CLDO3_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 825 | 830 | AXP717_LDO1_OUTPUT_CONTROL, BIT(2)), |
| 826 | − AXP_DESC(AXP717, CLDO4, "cldo4", "vin1", 500, 3500, 100, | |
| 831 | + AXP_DESC(AXP717, CLDO4, "cldo4", "cldoin", 500, 3500, 100, | |
| 827 | 832 | AXP717_CLDO4_CONTROL, AXP717_LDO_V_OUT_MASK, |
| 828 | 833 | AXP717_LDO1_OUTPUT_CONTROL, BIT(3)), |
| 829 | 834 | AXP_DESC(AXP717, CPUSLDO, "cpusldo", "vin1", 500, 1400, 50, |
| @@ -256,7 +256,7 @@ static int buck12_set_hw_dvs_levels(struct device_node *np, · 255 unmodified lines | ||
| 256 | 256 | * 10: 2.50mV/usec 10mV 4uS |
| 257 | 257 | * 11: 1.25mV/usec 10mV 8uS |
| 258 | 258 | */ |
| 259 | −static const unsigned int bd7181x_ramp_table[] = { 1250, 2500, 5000, 10000 }; | |
| 259 | +static const unsigned int bd7181x_ramp_table[] = { 10000, 5000, 2500, 1250 }; | |
| 260 | 260 | |
| 261 | 261 | static int bd7181x_led_set_current_limit(struct regulator_dev *rdev, |
| 262 | 262 | int min_uA, int max_uA) |
| @@ -3347,6 +3347,7 @@ struct regmap *regulator_get_regmap(struct regulator *regulator) · 3346 unmodified lines | ||
| 3347 | 3347 | |
| 3348 | 3348 | return map ? map : ERR_PTR(-EOPNOTSUPP); |
| 3349 | 3349 | } |
| 3350 | +EXPORT_SYMBOL_GPL(regulator_get_regmap); | |
| 3350 | 3351 | |
| 3351 | 3352 | /** |
| 3352 | 3353 | * regulator_get_hardware_vsel_register - get the HW voltage selector register |
| @@ -3407,6 +3408,34 @@ int regulator_list_hardware_vsel(struct regulator *regulator, · 54 unmodified lines | ||
| 3407 | 3408 | } |
| 3408 | 3409 | EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel); |
| 3409 | 3410 | |
| 3411 | +/** | |
| 3412 | + * regulator_hardware_enable - access the HW for enable/disable regulator | |
| 3413 | + * @regulator: regulator source | |
| 3414 | + * @enable: true for enable, false for disable | |
| 3415 | + * | |
| 3416 | + * Request that the regulator be enabled/disabled with the regulator output at | |
| 3417 | + * the predefined voltage or current value. | |
| 3418 | + * | |
| 3419 | + * On success 0 is returned, otherwise a negative errno is returned. | |
| 3420 | + */ | |
| 3421 | +int regulator_hardware_enable(struct regulator *regulator, bool enable) | |
| 3422 | +{ | |
| 3423 | + struct regulator_dev *rdev = regulator->rdev; | |
| 3424 | + const struct regulator_ops *ops = rdev->desc->ops; | |
| 3425 | + int ret = -EOPNOTSUPP; | |
| 3426 | + | |
| 3427 | + if (!rdev->exclusive || !ops || !ops->enable || !ops->disable) | |
| 3428 | + return ret; | |
| 3429 | + | |
| 3430 | + if (enable) | |
| 3431 | + ret = ops->enable(rdev); | |
| 3432 | + else | |
| 3433 | + ret = ops->disable(rdev); | |
| 3434 | + | |
| 3435 | + return ret; | |
| 3436 | +} | |
| 3437 | +EXPORT_SYMBOL_GPL(regulator_hardware_enable); | |
| 3438 | + | |
| 3410 | 3439 | /** |
| 3411 | 3440 | * regulator_get_linear_step - return the voltage step size between VSEL values |
| 3412 | 3441 | * @regulator: regulator source |
| @@ -0,0 +1,74 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +// | |
| 3 | +// Renesas USB VBUS output regulator driver | |
| 4 | +// | |
| 5 | +// Copyright (C) 2024 Renesas Electronics Corporation | |
| 6 | +// | |
| 7 | + | |
| 8 | +#include <linux/module.h> | |
| 9 | +#include <linux/err.h> | |
| 10 | +#include <linux/kernel.h> | |
| 11 | +#include <linux/of.h> | |
| 12 | +#include <linux/platform_device.h> | |
| 13 | +#include <linux/regmap.h> | |
| 14 | +#include <linux/regulator/driver.h> | |
| 15 | +#include <linux/regulator/of_regulator.h> | |
| 16 | + | |
| 17 | +static const struct regulator_ops rzg2l_usb_vbus_reg_ops = { | |
| 18 | + .enable = regulator_enable_regmap, | |
| 19 | + .disable = regulator_disable_regmap, | |
| 20 | + .is_enabled = regulator_is_enabled_regmap, | |
| 21 | +}; | |
| 22 | + | |
| 23 | +static const struct regulator_desc rzg2l_usb_vbus_rdesc = { | |
| 24 | + .name = "vbus", | |
| 25 | + .of_match = of_match_ptr("regulator-vbus"), | |
| 26 | + .ops = &rzg2l_usb_vbus_reg_ops, | |
| 27 | + .type = REGULATOR_VOLTAGE, | |
| 28 | + .owner = THIS_MODULE, | |
| 29 | + .enable_reg = 0, | |
| 30 | + .enable_mask = BIT(0), | |
| 31 | + .enable_is_inverted = true, | |
| 32 | + .fixed_uV = 5000000, | |
| 33 | + .n_voltages = 1, | |
| 34 | +}; | |
| 35 | + | |
| 36 | +static int rzg2l_usb_vbus_regulator_probe(struct platform_device *pdev) | |
| 37 | +{ | |
| 38 | + struct regulator_config config = { }; | |
| 39 | + struct device *dev = &pdev->dev; | |
| 40 | + struct regulator_dev *rdev; | |
| 41 | + | |
| 42 | + config.regmap = dev_get_regmap(dev->parent, NULL); | |
| 43 | + if (!config.regmap) | |
| 44 | + return dev_err_probe(dev, -ENOENT, "Failed to get regmap\n"); | |
| 45 | + | |
| 46 | + config.dev = dev; | |
| 47 | + config.of_node = of_get_child_by_name(dev->parent->of_node, "regulator-vbus"); | |
| 48 | + if (!config.of_node) | |
| 49 | + return dev_err_probe(dev, -ENODEV, "regulator node not found\n"); | |
| 50 | + | |
| 51 | + rdev = devm_regulator_register(dev, &rzg2l_usb_vbus_rdesc, &config); | |
| 52 | + if (IS_ERR(rdev)) { | |
| 53 | + of_node_put(config.of_node); | |
| 54 | + return dev_err_probe(dev, PTR_ERR(rdev), | |
| 55 | + "not able to register vbus regulator\n"); | |
| 56 | + } | |
| 57 | + | |
| 58 | + of_node_put(config.of_node); | |
| 59 | + | |
| 60 | + return 0; | |
| 61 | +} | |
| 62 | + | |
| 63 | +static struct platform_driver rzg2l_usb_vbus_regulator_driver = { | |
| 64 | + .probe = rzg2l_usb_vbus_regulator_probe, | |
| 65 | + .driver = { | |
| 66 | + .name = "rzg2l-usb-vbus-regulator", | |
| 67 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, | |
| 68 | + }, | |
| 69 | +}; | |
| 70 | +module_platform_driver(rzg2l_usb_vbus_regulator_driver); | |
| 71 | + | |
| 72 | +MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>"); | |
| 73 | +MODULE_DESCRIPTION("Renesas RZ/G2L USB Vbus Regulator Driver"); | |
| 74 | +MODULE_LICENSE("GPL"); | |
| @@ -653,18 +653,14 @@ static int tps6594_regulator_probe(struct platform_device *pdev) · 652 unmodified lines | ||
| 653 | 653 | } |
| 654 | 654 | } |
| 655 | 655 | |
| 656 | − if (tps->chip_id == LP8764) { | |
| 657 | − nr_buck = ARRAY_SIZE(buck_regs); | |
| 658 | − nr_ldo = 0; | |
| 659 | − nr_types = REGS_INT_NB; | |
| 660 | − } else if (tps->chip_id == TPS65224) { | |
| 656 | + if (tps->chip_id == TPS65224) { | |
| 661 | 657 | nr_buck = ARRAY_SIZE(tps65224_buck_regs); |
| 662 | 658 | nr_ldo = ARRAY_SIZE(tps65224_ldo_regs); |
| 663 | − nr_types = REGS_INT_NB; | |
| 659 | + nr_types = TPS65224_REGS_INT_NB; | |
| 664 | 660 | } else { |
| 665 | 661 | nr_buck = ARRAY_SIZE(buck_regs); |
| 666 | − nr_ldo = ARRAY_SIZE(tps6594_ldo_regs); | |
| 667 | − nr_types = TPS65224_REGS_INT_NB; | |
| 662 | + nr_ldo = (tps->chip_id == LP8764) ? 0 : ARRAY_SIZE(tps6594_ldo_regs); | |
| 663 | + nr_types = REGS_INT_NB; | |
| 668 | 664 | } |
| 669 | 665 | |
| 670 | 666 | reg_irq_nb = nr_types * (nr_buck + nr_ldo); |
| @@ -63,6 +63,7 @@ · 62 unmodified lines | ||
| 63 | 63 | #include <scsi/scsi_cmnd.h> |
| 64 | 64 | #include <scsi/scsi_dbg.h> |
| 65 | 65 | #include <scsi/scsi_device.h> |
| 66 | +#include <scsi/scsi_devinfo.h> | |
| 66 | 67 | #include <scsi/scsi_driver.h> |
| 67 | 68 | #include <scsi/scsi_eh.h> |
| 68 | 69 | #include <scsi/scsi_host.h> |
| @@ -3118,6 +3119,9 @@ static void sd_read_io_hints(struct scsi_disk *sdkp, unsigned char *buffer) · 3049 unmodified lines | ||
| 3118 | 3119 | struct scsi_mode_data data; |
| 3119 | 3120 | int res; |
| 3120 | 3121 | |
| 3122 | + if (sdp->sdev_bflags & BLIST_SKIP_IO_HINTS) | |
| 3123 | + return; | |
| 3124 | + | |
| 3121 | 3125 | res = scsi_mode_sense(sdp, /*dbd=*/0x8, /*modepage=*/0x0a, |
| 3122 | 3126 | /*subpage=*/0x05, buffer, SD_BUF_SIZE, SD_TIMEOUT, |
| 3123 | 3127 | sdkp->max_retries, &data, &sshdr); |
| @@ -127,8 +127,8 @@ static void tegra_fuse_print_sku_info(struct tegra_sku_info *tegra_sku_info) · 126 unmodified lines | ||
| 127 | 127 | |
| 128 | 128 | static int tegra_fuse_add_lookups(struct tegra_fuse *fuse) |
| 129 | 129 | { |
| 130 | − fuse->lookups = kmemdup_array(fuse->soc->lookups, sizeof(*fuse->lookups), | |
| 131 | − fuse->soc->num_lookups, GFP_KERNEL); | |
| 130 | + fuse->lookups = kmemdup_array(fuse->soc->lookups, fuse->soc->num_lookups, | |
| 131 | + sizeof(*fuse->lookups), GFP_KERNEL); | |
| 132 | 132 | if (!fuse->lookups) |
| 133 | 133 | return -ENOMEM; |
| 134 | 134 | |
| @@ -571,6 +571,9 @@ static int sdw_master_read_amd_prop(struct sdw_bus *bus) · 570 unmodified lines | ||
| 571 | 571 | amd_manager->wake_en_mask = wake_en_mask; |
| 572 | 572 | fwnode_property_read_u32(link, "amd-sdw-power-mode", &power_mode_mask); |
| 573 | 573 | amd_manager->power_mode_mask = power_mode_mask; |
| 574 | + | |
| 575 | + fwnode_handle_put(link); | |
| 576 | + | |
| 574 | 577 | return 0; |
| 575 | 578 | } |
| 576 | 579 | |
| @@ -155,8 +155,10 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus) · 154 unmodified lines | ||
| 155 | 155 | SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY; |
| 156 | 156 | |
| 157 | 157 | intel_prop = devm_kzalloc(bus->dev, sizeof(*intel_prop), GFP_KERNEL); |
| 158 | − if (!intel_prop) | |
| 158 | + if (!intel_prop) { | |
| 159 | + fwnode_handle_put(link); | |
| 159 | 160 | return -ENOMEM; |
| 161 | + } | |
| 160 | 162 | |
| 161 | 163 | /* initialize with hardware defaults, in case the properties are not found */ |
| 162 | 164 | intel_prop->doaise = 0x1; |
| @@ -184,6 +186,8 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus) · 21 unmodified lines | ||
| 184 | 186 | intel_prop->dodse, |
| 185 | 187 | intel_prop->dods); |
| 186 | 188 | |
| 189 | + fwnode_handle_put(link); | |
| 190 | + | |
| 187 | 191 | return 0; |
| 188 | 192 | } |
| 189 | 193 | |
| @@ -66,8 +66,10 @@ int sdw_master_read_prop(struct sdw_bus *bus) · 65 unmodified lines | ||
| 66 | 66 | prop->clk_freq = devm_kcalloc(bus->dev, prop->num_clk_freq, |
| 67 | 67 | sizeof(*prop->clk_freq), |
| 68 | 68 | GFP_KERNEL); |
| 69 | − if (!prop->clk_freq) | |
| 69 | + if (!prop->clk_freq) { | |
| 70 | + fwnode_handle_put(link); | |
| 70 | 71 | return -ENOMEM; |
| 72 | + } | |
| 71 | 73 | |
| 72 | 74 | fwnode_property_read_u32_array(link, |
| 73 | 75 | "mipi-sdw-clock-frequencies-supported", |
| @@ -92,8 +94,10 @@ int sdw_master_read_prop(struct sdw_bus *bus) · 18 unmodified lines | ||
| 92 | 94 | prop->clk_gears = devm_kcalloc(bus->dev, prop->num_clk_gears, |
| 93 | 95 | sizeof(*prop->clk_gears), |
| 94 | 96 | GFP_KERNEL); |
| 95 | − if (!prop->clk_gears) | |
| 97 | + if (!prop->clk_gears) { | |
| 98 | + fwnode_handle_put(link); | |
| 96 | 99 | return -ENOMEM; |
| 100 | + } | |
| 97 | 101 | |
| 98 | 102 | fwnode_property_read_u32_array(link, |
| 99 | 103 | "mipi-sdw-supported-clock-gears", |
| @@ -116,6 +120,8 @@ int sdw_master_read_prop(struct sdw_bus *bus) · 16 unmodified lines | ||
| 116 | 120 | fwnode_property_read_u32(link, "mipi-sdw-command-error-threshold", |
| 117 | 121 | &prop->err_threshold); |
| 118 | 122 | |
| 123 | + fwnode_handle_put(link); | |
| 124 | + | |
| 119 | 125 | return 0; |
| 120 | 126 | } |
| 121 | 127 | EXPORT_SYMBOL(sdw_master_read_prop); |
| @@ -197,8 +203,10 @@ static int sdw_slave_read_dpn(struct sdw_slave *slave, · 75 unmodified lines | ||
| 197 | 203 | dpn[i].num_words, |
| 198 | 204 | sizeof(*dpn[i].words), |
| 199 | 205 | GFP_KERNEL); |
| 200 | − if (!dpn[i].words) | |
| 206 | + if (!dpn[i].words) { | |
| 207 | + fwnode_handle_put(node); | |
| 201 | 208 | return -ENOMEM; |
| 209 | + } | |
| 202 | 210 | |
| 203 | 211 | fwnode_property_read_u32_array(node, |
| 204 | 212 | "mipi-sdw-port-wordlength-configs", |
| @@ -236,8 +244,10 @@ static int sdw_slave_read_dpn(struct sdw_slave *slave, · 31 unmodified lines | ||
| 236 | 244 | dpn[i].num_channels, |
| 237 | 245 | sizeof(*dpn[i].channels), |
| 238 | 246 | GFP_KERNEL); |
| 239 | − if (!dpn[i].channels) | |
| 247 | + if (!dpn[i].channels) { | |
| 248 | + fwnode_handle_put(node); | |
| 240 | 249 | return -ENOMEM; |
| 250 | + } | |
| 241 | 251 | |
| 242 | 252 | fwnode_property_read_u32_array(node, |
| 243 | 253 | "mipi-sdw-channel-number-list", |
| @@ -251,8 +261,10 @@ static int sdw_slave_read_dpn(struct sdw_slave *slave, · 7 unmodified lines | ||
| 251 | 261 | dpn[i].num_ch_combinations, |
| 252 | 262 | sizeof(*dpn[i].ch_combinations), |
| 253 | 263 | GFP_KERNEL); |
| 254 | − if (!dpn[i].ch_combinations) | |
| 264 | + if (!dpn[i].ch_combinations) { | |
| 265 | + fwnode_handle_put(node); | |
| 255 | 266 | return -ENOMEM; |
| 267 | + } | |
| 256 | 268 | |
| 257 | 269 | fwnode_property_read_u32_array(node, |
| 258 | 270 | "mipi-sdw-channel-combination-list", |
| @@ -274,6 +286,8 @@ static int sdw_slave_read_dpn(struct sdw_slave *slave, · 15 unmodified lines | ||
| 274 | 286 | |
| 275 | 287 | /* TODO: Read audio mode */ |
| 276 | 288 | |
| 289 | + fwnode_handle_put(node); | |
| 290 | + | |
| 277 | 291 | i++; |
| 278 | 292 | } |
| 279 | 293 | |
| @@ -348,10 +362,14 @@ int sdw_slave_read_prop(struct sdw_slave *slave) · 68 unmodified lines | ||
| 348 | 362 | prop->dp0_prop = devm_kzalloc(&slave->dev, |
| 349 | 363 | sizeof(*prop->dp0_prop), |
| 350 | 364 | GFP_KERNEL); |
| 351 | − if (!prop->dp0_prop) | |
| 365 | + if (!prop->dp0_prop) { | |
| 366 | + fwnode_handle_put(port); | |
| 352 | 367 | return -ENOMEM; |
| 368 | + } | |
| 353 | 369 | |
| 354 | 370 | sdw_slave_read_dp0(slave, port, prop->dp0_prop); |
| 371 | + | |
| 372 | + fwnode_handle_put(port); | |
| 355 | 373 | } |
| 356 | 374 | |
| 357 | 375 | /* |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/units.h> |
| 27 | 27 | |
| 28 | 28 | #define CS42L43_FIFO_SIZE 16 |
| 29 | −#define CS42L43_SPI_ROOT_HZ (40 * HZ_PER_MHZ) | |
| 29 | +#define CS42L43_SPI_ROOT_HZ 49152000 | |
| 30 | 30 | #define CS42L43_SPI_MAX_LENGTH 65532 |
| 31 | 31 | |
| 32 | 32 | enum cs42l43_spi_cmd { |
| @@ -54,7 +54,7 @@ static const struct software_node ampr = { · 21 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | static struct spi_board_info ampl_info = { |
| 56 | 56 | .modalias = "cs35l56", |
| 57 | − .max_speed_hz = 20 * HZ_PER_MHZ, | |
| 57 | + .max_speed_hz = 11 * HZ_PER_MHZ, | |
| 58 | 58 | .chip_select = 0, |
| 59 | 59 | .mode = SPI_MODE_0, |
| 60 | 60 | .swnode = &l, |
| @@ -62,7 +62,7 @@ static struct spi_board_info ampl_info = { · 1 unmodified line | ||
| 62 | 62 | |
| 63 | 63 | static struct spi_board_info ampr_info = { |
| 64 | 64 | .modalias = "cs35l56", |
| 65 | − .max_speed_hz = 20 * HZ_PER_MHZ, | |
| 65 | + .max_speed_hz = 11 * HZ_PER_MHZ, | |
| 66 | 66 | .chip_select = 1, |
| 67 | 67 | .mode = SPI_MODE_0, |
| 68 | 68 | .swnode = &r, |
| @@ -660,18 +660,8 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, · 659 unmodified lines | ||
| 660 | 660 | ctrl |= (spi_imx->target_burst * 8 - 1) |
| 661 | 661 | << MX51_ECSPI_CTRL_BL_OFFSET; |
| 662 | 662 | else { |
| 663 | − if (spi_imx->usedma) { | |
| 664 | − ctrl |= (spi_imx->bits_per_word - 1) | |
| 665 | − << MX51_ECSPI_CTRL_BL_OFFSET; | |
| 666 | − } else { | |
| 667 | − if (spi_imx->count >= MX51_ECSPI_CTRL_MAX_BURST) | |
| 668 | − ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1) | |
| 669 | − << MX51_ECSPI_CTRL_BL_OFFSET; | |
| 670 | − else | |
| 671 | − ctrl |= (spi_imx->count / DIV_ROUND_UP(spi_imx->bits_per_word, | |
| 672 | − BITS_PER_BYTE) * spi_imx->bits_per_word - 1) | |
| 673 | − << MX51_ECSPI_CTRL_BL_OFFSET; | |
| 674 | − } | |
| 663 | + ctrl |= (spi_imx->bits_per_word - 1) | |
| 664 | + << MX51_ECSPI_CTRL_BL_OFFSET; | |
| 675 | 665 | } |
| 676 | 666 | |
| 677 | 667 | /* set clock speed */ |
| @@ -349,7 +349,7 @@ static int stm32_qspi_wait_poll_status(struct stm32_qspi *qspi) · 348 unmodified lines | ||
| 349 | 349 | |
| 350 | 350 | static int stm32_qspi_get_mode(u8 buswidth) |
| 351 | 351 | { |
| 352 | − if (buswidth == 4) | |
| 352 | + if (buswidth >= 4) | |
| 353 | 353 | return CCR_BUSWIDTH_4; |
| 354 | 354 | |
| 355 | 355 | return buswidth; |
| @@ -653,9 +653,7 @@ static int stm32_qspi_setup(struct spi_device *spi) · 297 unmodified lines | ||
| 653 | 653 | return -EINVAL; |
| 654 | 654 | |
| 655 | 655 | mode = spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL); |
| 656 | − if ((mode == SPI_TX_OCTAL || mode == SPI_RX_OCTAL) || | |
| 657 | − ((mode == (SPI_TX_OCTAL | SPI_RX_OCTAL)) && | |
| 658 | − gpiod_count(qspi->dev, "cs") == -ENOENT)) { | |
| 656 | + if (mode && gpiod_count(qspi->dev, "cs") == -ENOENT) { | |
| 659 | 657 | dev_err(qspi->dev, "spi-rx-bus-width\\/spi-tx-bus-width\\/cs-gpios\n"); |
| 660 | 658 | dev_err(qspi->dev, "configuration not supported\n"); |
| 661 | 659 | |
| @@ -676,10 +674,10 @@ static int stm32_qspi_setup(struct spi_device *spi) · 14 unmodified lines | ||
| 676 | 674 | qspi->cr_reg = CR_APMS | 3 << CR_FTHRES_SHIFT | CR_SSHIFT | CR_EN; |
| 677 | 675 | |
| 678 | 676 | /* |
| 679 | − * Dual flash mode is only enable in case SPI_TX_OCTAL and SPI_TX_OCTAL | |
| 680 | − * are both set in spi->mode and "cs-gpios" properties is found in DT | |
| 677 | + * Dual flash mode is only enable in case SPI_TX_OCTAL or SPI_RX_OCTAL | |
| 678 | + * is set in spi->mode and "cs-gpios" properties is found in DT | |
| 681 | 679 | */ |
| 682 | − if (mode == (SPI_TX_OCTAL | SPI_RX_OCTAL)) { | |
| 680 | + if (mode) { | |
| 683 | 681 | qspi->cr_reg |= CR_DFM; |
| 684 | 682 | dev_dbg(qspi->dev, "Dual flash mode enable"); |
| 685 | 683 | } |
| @@ -689,10 +689,12 @@ static int __spi_add_device(struct spi_device *spi) · 688 unmodified lines | ||
| 689 | 689 | * Make sure that multiple logical CS doesn't map to the same physical CS. |
| 690 | 690 | * For example, spi->chip_select[0] != spi->chip_select[1] and so on. |
| 691 | 691 | */ |
| 692 | − for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) { | |
| 693 | − status = spi_dev_check_cs(dev, spi, idx, spi, idx + 1); | |
| 694 | − if (status) | |
| 695 | − return status; | |
| 692 | + if (!spi_controller_is_target(ctlr)) { | |
| 693 | + for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) { | |
| 694 | + status = spi_dev_check_cs(dev, spi, idx, spi, idx + 1); | |
| 695 | + if (status) | |
| 696 | + return status; | |
| 697 | + } | |
| 696 | 698 | } |
| 697 | 699 | |
| 698 | 700 | /* Set the bus ID string */ |
| @@ -4156,7 +4158,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) · 3457 unmodified lines | ||
| 4156 | 4158 | return -EINVAL; |
| 4157 | 4159 | if (xfer->tx_nbits != SPI_NBITS_SINGLE && |
| 4158 | 4160 | xfer->tx_nbits != SPI_NBITS_DUAL && |
| 4159 | − xfer->tx_nbits != SPI_NBITS_QUAD) | |
| 4161 | + xfer->tx_nbits != SPI_NBITS_QUAD && | |
| 4162 | + xfer->tx_nbits != SPI_NBITS_OCTAL) | |
| 4160 | 4163 | return -EINVAL; |
| 4161 | 4164 | if ((xfer->tx_nbits == SPI_NBITS_DUAL) && |
| 4162 | 4165 | !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) |
| @@ -4171,7 +4174,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) · 8 unmodified lines | ||
| 4171 | 4174 | return -EINVAL; |
| 4172 | 4175 | if (xfer->rx_nbits != SPI_NBITS_SINGLE && |
| 4173 | 4176 | xfer->rx_nbits != SPI_NBITS_DUAL && |
| 4174 | − xfer->rx_nbits != SPI_NBITS_QUAD) | |
| 4177 | + xfer->rx_nbits != SPI_NBITS_QUAD && | |
| 4178 | + xfer->rx_nbits != SPI_NBITS_OCTAL) | |
| 4175 | 4179 | return -EINVAL; |
| 4176 | 4180 | if ((xfer->rx_nbits == SPI_NBITS_DUAL) && |
| 4177 | 4181 | !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) |
| @@ -150,7 +150,7 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid) · 149 unmodified lines | ||
| 150 | 150 | { |
| 151 | 151 | struct proc_thermal_pci *pci_info = devid; |
| 152 | 152 | struct proc_thermal_device *proc_priv; |
| 153 | − int ret = IRQ_HANDLED; | |
| 153 | + int ret = IRQ_NONE; | |
| 154 | 154 | u32 status; |
| 155 | 155 | |
| 156 | 156 | proc_priv = pci_info->proc_priv; |
| @@ -175,6 +175,7 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid) · 18 unmodified lines | ||
| 175 | 175 | /* Disable enable interrupt flag */ |
| 176 | 176 | proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0); |
| 177 | 177 | pkg_thermal_schedule_work(&pci_info->work); |
| 178 | + ret = IRQ_HANDLED; | |
| 178 | 179 | } |
| 179 | 180 | |
| 180 | 181 | pci_write_config_byte(pci_info->pdev, 0xdc, 0x01); |
| @@ -769,7 +769,11 @@ static int lvts_golden_temp_init(struct device *dev, u8 *calib, · 768 unmodified lines | ||
| 769 | 769 | */ |
| 770 | 770 | gt = (((u32 *)calib)[0] >> lvts_data->gt_calib_bit_offset) & 0xff; |
| 771 | 771 | |
| 772 | − if (gt && gt < LVTS_GOLDEN_TEMP_MAX) | |
| 772 | + /* A zero value for gt means that device has invalid efuse data */ | |
| 773 | + if (!gt) | |
| 774 | + return -ENODATA; | |
| 775 | + | |
| 776 | + if (gt < LVTS_GOLDEN_TEMP_MAX) | |
| 773 | 777 | golden_temp = gt; |
| 774 | 778 | |
| 775 | 779 | golden_temp_offset = golden_temp * 500 + lvts_data->temp_offset; |
| @@ -1458,7 +1462,6 @@ static const struct lvts_ctrl_data mt8188_lvts_mcu_data_ctrl[] = { · 682 unmodified lines | ||
| 1458 | 1462 | }, |
| 1459 | 1463 | VALID_SENSOR_MAP(1, 1, 1, 1), |
| 1460 | 1464 | .offset = 0x0, |
| 1461 | − .mode = LVTS_MSR_FILTERED_MODE, | |
| 1462 | 1465 | }, |
| 1463 | 1466 | { |
| 1464 | 1467 | .lvts_sensor = { |
| @@ -1469,7 +1472,6 @@ static const struct lvts_ctrl_data mt8188_lvts_mcu_data_ctrl[] = { · 4 unmodified lines | ||
| 1469 | 1472 | }, |
| 1470 | 1473 | VALID_SENSOR_MAP(1, 1, 0, 0), |
| 1471 | 1474 | .offset = 0x100, |
| 1472 | − .mode = LVTS_MSR_FILTERED_MODE, | |
| 1473 | 1475 | } |
| 1474 | 1476 | }; |
| 1475 | 1477 | |
| @@ -1483,7 +1485,6 @@ static const struct lvts_ctrl_data mt8188_lvts_ap_data_ctrl[] = { · 7 unmodified lines | ||
| 1483 | 1485 | }, |
| 1484 | 1486 | VALID_SENSOR_MAP(0, 1, 0, 0), |
| 1485 | 1487 | .offset = 0x0, |
| 1486 | − .mode = LVTS_MSR_FILTERED_MODE, | |
| 1487 | 1488 | }, |
| 1488 | 1489 | { |
| 1489 | 1490 | .lvts_sensor = { |
| @@ -1496,7 +1497,6 @@ static const struct lvts_ctrl_data mt8188_lvts_ap_data_ctrl[] = { · 6 unmodified lines | ||
| 1496 | 1497 | }, |
| 1497 | 1498 | VALID_SENSOR_MAP(1, 1, 1, 0), |
| 1498 | 1499 | .offset = 0x100, |
| 1499 | − .mode = LVTS_MSR_FILTERED_MODE, | |
| 1500 | 1500 | }, |
| 1501 | 1501 | { |
| 1502 | 1502 | .lvts_sensor = { |
| @@ -1507,7 +1507,6 @@ static const struct lvts_ctrl_data mt8188_lvts_ap_data_ctrl[] = { · 4 unmodified lines | ||
| 1507 | 1507 | }, |
| 1508 | 1508 | VALID_SENSOR_MAP(1, 1, 0, 0), |
| 1509 | 1509 | .offset = 0x200, |
| 1510 | − .mode = LVTS_MSR_FILTERED_MODE, | |
| 1511 | 1510 | }, |
| 1512 | 1511 | { |
| 1513 | 1512 | .lvts_sensor = { |
| @@ -1518,7 +1517,6 @@ static const struct lvts_ctrl_data mt8188_lvts_ap_data_ctrl[] = { · 4 unmodified lines | ||
| 1518 | 1517 | }, |
| 1519 | 1518 | VALID_SENSOR_MAP(1, 1, 0, 0), |
| 1520 | 1519 | .offset = 0x300, |
| 1521 | − .mode = LVTS_MSR_FILTERED_MODE, | |
| 1522 | 1520 | } |
| 1523 | 1521 | }; |
| 1524 | 1522 | |
| @@ -1406,6 +1406,7 @@ thermal_zone_device_register_with_trips(const char *type, · 1405 unmodified lines | ||
| 1406 | 1406 | ida_init(&tz->ida); |
| 1407 | 1407 | mutex_init(&tz->lock); |
| 1408 | 1408 | init_completion(&tz->removal); |
| 1409 | + init_completion(&tz->resume); | |
| 1409 | 1410 | id = ida_alloc(&thermal_tz_ida, GFP_KERNEL); |
| 1410 | 1411 | if (id < 0) { |
| 1411 | 1412 | result = id; |
| @@ -1651,6 +1652,9 @@ static void thermal_zone_device_resume(struct work_struct *work) · 239 unmodified lines | ||
| 1651 | 1652 | thermal_zone_device_init(tz); |
| 1652 | 1653 | __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); |
| 1653 | 1654 | |
| 1655 | + complete(&tz->resume); | |
| 1656 | + tz->resuming = false; | |
| 1657 | + | |
| 1654 | 1658 | mutex_unlock(&tz->lock); |
| 1655 | 1659 | } |
| 1656 | 1660 | |
| @@ -1668,6 +1672,20 @@ static int thermal_pm_notify(struct notifier_block *nb, · 11 unmodified lines | ||
| 1668 | 1672 | list_for_each_entry(tz, &thermal_tz_list, node) { |
| 1669 | 1673 | mutex_lock(&tz->lock); |
| 1670 | 1674 | |
| 1675 | + if (tz->resuming) { | |
| 1676 | + /* | |
| 1677 | + * thermal_zone_device_resume() queued up for | |
| 1678 | + * this zone has not acquired the lock yet, so | |
| 1679 | + * release it to let the function run and wait | |
| 1680 | + * util it has done the work. | |
| 1681 | + */ | |
| 1682 | + mutex_unlock(&tz->lock); | |
| 1683 | + | |
| 1684 | + wait_for_completion(&tz->resume); | |
| 1685 | + | |
| 1686 | + mutex_lock(&tz->lock); | |
| 1687 | + } | |
| 1688 | + | |
| 1671 | 1689 | tz->suspended = true; |
| 1672 | 1690 | |
| 1673 | 1691 | mutex_unlock(&tz->lock); |
| @@ -1685,6 +1703,9 @@ static int thermal_pm_notify(struct notifier_block *nb, · 11 unmodified lines | ||
| 1685 | 1703 | |
| 1686 | 1704 | cancel_delayed_work(&tz->poll_queue); |
| 1687 | 1705 | |
| 1706 | + reinit_completion(&tz->resume); | |
| 1707 | + tz->resuming = true; | |
| 1708 | + | |
| 1688 | 1709 | /* |
| 1689 | 1710 | * Replace the work function with the resume one, which |
| 1690 | 1711 | * will restore the original work function and schedule |
| @@ -1709,6 +1730,12 @@ static int thermal_pm_notify(struct notifier_block *nb, · 18 unmodified lines | ||
| 1709 | 1730 | |
| 1710 | 1731 | static struct notifier_block thermal_pm_nb = { |
| 1711 | 1732 | .notifier_call = thermal_pm_notify, |
| 1733 | + /* | |
| 1734 | + * Run at the lowest priority to avoid interference between the thermal | |
| 1735 | + * zone resume work items spawned by thermal_pm_notify() and the other | |
| 1736 | + * PM notifiers. | |
| 1737 | + */ | |
| 1738 | + .priority = INT_MIN, | |
| 1712 | 1739 | }; |
| 1713 | 1740 | |
| 1714 | 1741 | static int __init thermal_init(void) |
| @@ -55,6 +55,7 @@ struct thermal_governor { · 54 unmodified lines | ||
| 55 | 55 | * @type: the thermal zone device type |
| 56 | 56 | * @device: &struct device for this thermal zone |
| 57 | 57 | * @removal: removal completion |
| 58 | + * @resume: resume completion | |
| 58 | 59 | * @trip_temp_attrs: attributes for trip points for sysfs: trip temperature |
| 59 | 60 | * @trip_type_attrs: attributes for trip points for sysfs: trip type |
| 60 | 61 | * @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis |
| @@ -89,6 +90,7 @@ struct thermal_governor { · 28 unmodified lines | ||
| 89 | 90 | * @poll_queue: delayed work for polling |
| 90 | 91 | * @notify_event: Last notification event |
| 91 | 92 | * @suspended: thermal zone suspend indicator |
| 93 | + * @resuming: indicates whether or not thermal zone resume is in progress | |
| 92 | 94 | * @trips: array of struct thermal_trip objects |
| 93 | 95 | */ |
| 94 | 96 | struct thermal_zone_device { |
| @@ -96,6 +98,7 @@ struct thermal_zone_device { · 1 unmodified line | ||
| 96 | 98 | char type[THERMAL_NAME_LENGTH]; |
| 97 | 99 | struct device device; |
| 98 | 100 | struct completion removal; |
| 101 | + struct completion resume; | |
| 99 | 102 | struct attribute_group trips_attribute_group; |
| 100 | 103 | struct thermal_attr *trip_temp_attrs; |
| 101 | 104 | struct thermal_attr *trip_type_attrs; |
| @@ -123,6 +126,7 @@ struct thermal_zone_device { · 21 unmodified lines | ||
| 123 | 126 | struct delayed_work poll_queue; |
| 124 | 127 | enum thermal_notify_event notify_event; |
| 125 | 128 | bool suspended; |
| 129 | + bool resuming; | |
| 126 | 130 | #ifdef CONFIG_THERMAL_DEBUGFS |
| 127 | 131 | struct thermal_debugfs *debugfs; |
| 128 | 132 | #endif |
| @@ -8787,6 +8787,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params) · 8786 unmodified lines | ||
| 8787 | 8787 | (hba->quirks & UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH)) { |
| 8788 | 8788 | /* Reset the device and controller before doing reinit */ |
| 8789 | 8789 | ufshcd_device_reset(hba); |
| 8790 | + ufs_put_device_desc(hba); | |
| 8790 | 8791 | ufshcd_hba_stop(hba); |
| 8791 | 8792 | ufshcd_vops_reinit_notify(hba); |
| 8792 | 8793 | ret = ufshcd_hba_enable(hba); |
| @@ -79,6 +79,12 @@ static int slave_alloc (struct scsi_device *sdev) · 78 unmodified lines | ||
| 79 | 79 | if (us->protocol == USB_PR_BULK && us->max_lun > 0) |
| 80 | 80 | sdev->sdev_bflags |= BLIST_FORCELUN; |
| 81 | 81 | |
| 82 | + /* | |
| 83 | + * Some USB storage devices reset if the IO advice hints grouping mode | |
| 84 | + * page is queried. Hence skip that mode page. | |
| 85 | + */ | |
| 86 | + sdev->sdev_bflags |= BLIST_SKIP_IO_HINTS; | |
| 87 | + | |
| 82 | 88 | return 0; |
| 83 | 89 | } |
| 84 | 90 | |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <scsi/scsi.h> |
| 22 | 22 | #include <scsi/scsi_eh.h> |
| 23 | 23 | #include <scsi/scsi_dbg.h> |
| 24 | +#include <scsi/scsi_devinfo.h> | |
| 24 | 25 | #include <scsi/scsi_cmnd.h> |
| 25 | 26 | #include <scsi/scsi_device.h> |
| 26 | 27 | #include <scsi/scsi_host.h> |
| @@ -820,6 +821,12 @@ static int uas_slave_alloc(struct scsi_device *sdev) · 793 unmodified lines | ||
| 820 | 821 | struct uas_dev_info *devinfo = |
| 821 | 822 | (struct uas_dev_info *)sdev->host->hostdata; |
| 822 | 823 | |
| 824 | + /* | |
| 825 | + * Some USB storage devices reset if the IO advice hints grouping mode | |
| 826 | + * page is queried. Hence skip that mode page. | |
| 827 | + */ | |
| 828 | + sdev->sdev_bflags |= BLIST_SKIP_IO_HINTS; | |
| 829 | + | |
| 823 | 830 | sdev->hostdata = devinfo; |
| 824 | 831 | return 0; |
| 825 | 832 | } |
| @@ -259,6 +259,14 @@ int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k, · 258 unmodified lines | ||
| 259 | 259 | "invalid data type (got %u should be %u)", |
| 260 | 260 | a.v->data_type, alloc_data_type(*a.v, a.v->data_type)); |
| 261 | 261 | |
| 262 | + for (unsigned i = 0; i < 2; i++) | |
| 263 | + bkey_fsck_err_on(a.v->io_time[i] > LRU_TIME_MAX, | |
| 264 | + c, err, | |
| 265 | + alloc_key_io_time_bad, | |
| 266 | + "invalid io_time[%s]: %llu, max %llu", | |
| 267 | + i == READ ? "read" : "write", | |
| 268 | + a.v->io_time[i], LRU_TIME_MAX); | |
| 269 | + | |
| 262 | 270 | switch (a.v->data_type) { |
| 263 | 271 | case BCH_DATA_free: |
| 264 | 272 | case BCH_DATA_need_gc_gens: |
| @@ -757,8 +765,8 @@ int bch2_trigger_alloc(struct btree_trans *trans, · 492 unmodified lines | ||
| 757 | 765 | alloc_data_type_set(new_a, new_a->data_type); |
| 758 | 766 | |
| 759 | 767 | if (bch2_bucket_sectors_total(*new_a) > bch2_bucket_sectors_total(*old_a)) { |
| 760 | − new_a->io_time[READ] = max_t(u64, 1, atomic64_read(&c->io_clock[READ].now)); | |
| 761 | − new_a->io_time[WRITE]= max_t(u64, 1, atomic64_read(&c->io_clock[WRITE].now)); | |
| 768 | + new_a->io_time[READ] = bch2_current_io_time(c, READ); | |
| 769 | + new_a->io_time[WRITE]= bch2_current_io_time(c, WRITE); | |
| 762 | 770 | SET_BCH_ALLOC_V4_NEED_INC_GEN(new_a, true); |
| 763 | 771 | SET_BCH_ALLOC_V4_NEED_DISCARD(new_a, true); |
| 764 | 772 | } |
| @@ -768,6 +776,7 @@ int bch2_trigger_alloc(struct btree_trans *trans, · 3 unmodified lines | ||
| 768 | 776 | !bch2_bucket_is_open_safe(c, new.k->p.inode, new.k->p.offset)) { |
| 769 | 777 | new_a->gen++; |
| 770 | 778 | SET_BCH_ALLOC_V4_NEED_INC_GEN(new_a, false); |
| 779 | + alloc_data_type_set(new_a, new_a->data_type); | |
| 771 | 780 | } |
| 772 | 781 | |
| 773 | 782 | if (old_a->data_type != new_a->data_type || |
| @@ -781,7 +790,7 @@ int bch2_trigger_alloc(struct btree_trans *trans, · 7 unmodified lines | ||
| 781 | 790 | |
| 782 | 791 | if (new_a->data_type == BCH_DATA_cached && |
| 783 | 792 | !new_a->io_time[READ]) |
| 784 | − new_a->io_time[READ] = max_t(u64, 1, atomic64_read(&c->io_clock[READ].now)); | |
| 793 | + new_a->io_time[READ] = bch2_current_io_time(c, READ); | |
| 785 | 794 | |
| 786 | 795 | u64 old_lru = alloc_lru_idx_read(*old_a); |
| 787 | 796 | u64 new_lru = alloc_lru_idx_read(*new_a); |
| @@ -882,7 +891,7 @@ int bch2_trigger_alloc(struct btree_trans *trans, · 94 unmodified lines | ||
| 882 | 891 | closure_wake_up(&c->freelist_wait); |
| 883 | 892 | |
| 884 | 893 | if (statechange(a->data_type == BCH_DATA_need_discard) && |
| 885 | − !bch2_bucket_is_open(c, new.k->p.inode, new.k->p.offset) && | |
| 894 | + !bch2_bucket_is_open_safe(c, new.k->p.inode, new.k->p.offset) && | |
| 886 | 895 | bucket_flushed(new_a)) |
| 887 | 896 | bch2_discard_one_bucket_fast(c, new.k->p); |
| 888 | 897 | |
| @@ -1579,7 +1588,7 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans, · 690 unmodified lines | ||
| 1579 | 1588 | if (ret) |
| 1580 | 1589 | goto err; |
| 1581 | 1590 | |
| 1582 | − a_mut->v.io_time[READ] = atomic64_read(&c->io_clock[READ].now); | |
| 1591 | + a_mut->v.io_time[READ] = bch2_current_io_time(c, READ); | |
| 1583 | 1592 | ret = bch2_trans_update(trans, alloc_iter, |
| 1584 | 1593 | &a_mut->k_i, BTREE_TRIGGER_norun); |
| 1585 | 1594 | if (ret) |
| @@ -1634,7 +1643,7 @@ static int discard_in_flight_add(struct bch_fs *c, struct bpos bucket) · 48 unmodified lines | ||
| 1634 | 1643 | mutex_lock(&c->discard_buckets_in_flight_lock); |
| 1635 | 1644 | darray_for_each(c->discard_buckets_in_flight, i) |
| 1636 | 1645 | if (bkey_eq(*i, bucket)) { |
| 1637 | − ret = -EEXIST; | |
| 1646 | + ret = -BCH_ERR_EEXIST_discard_in_flight_add; | |
| 1638 | 1647 | goto out; |
| 1639 | 1648 | } |
| 1640 | 1649 | |
| @@ -1788,8 +1797,9 @@ static int bch2_discard_one_bucket(struct btree_trans *trans, · 147 unmodified lines | ||
| 1788 | 1797 | } |
| 1789 | 1798 | |
| 1790 | 1799 | SET_BCH_ALLOC_V4_NEED_DISCARD(&a->v, false); |
| 1791 | − alloc_data_type_set(&a->v, a->v.data_type); | |
| 1792 | 1800 | write: |
| 1801 | + alloc_data_type_set(&a->v, a->v.data_type); | |
| 1802 | + | |
| 1793 | 1803 | ret = bch2_trans_update(trans, &iter, &a->k_i, 0) ?: |
| 1794 | 1804 | bch2_trans_commit(trans, NULL, NULL, |
| 1795 | 1805 | BCH_WATERMARK_btree| |
| @@ -1975,8 +1985,8 @@ static int invalidate_one_bucket(struct btree_trans *trans, · 179 unmodified lines | ||
| 1975 | 1985 | a->v.data_type = 0; |
| 1976 | 1986 | a->v.dirty_sectors = 0; |
| 1977 | 1987 | a->v.cached_sectors = 0; |
| 1978 | − a->v.io_time[READ] = atomic64_read(&c->io_clock[READ].now); | |
| 1979 | − a->v.io_time[WRITE] = atomic64_read(&c->io_clock[WRITE].now); | |
| 1988 | + a->v.io_time[READ] = bch2_current_io_time(c, READ); | |
| 1989 | + a->v.io_time[WRITE] = bch2_current_io_time(c, WRITE); | |
| 1980 | 1990 | |
| 1981 | 1991 | ret = bch2_trans_commit(trans, NULL, NULL, |
| 1982 | 1992 | BCH_WATERMARK_btree| |
| @@ -2011,6 +2021,21 @@ err: · 28 unmodified lines | ||
| 2011 | 2021 | goto out; |
| 2012 | 2022 | } |
| 2013 | 2023 | |
| 2024 | +static struct bkey_s_c next_lru_key(struct btree_trans *trans, struct btree_iter *iter, | |
| 2025 | + struct bch_dev *ca, bool *wrapped) | |
| 2026 | +{ | |
| 2027 | + struct bkey_s_c k; | |
| 2028 | +again: | |
| 2029 | + k = bch2_btree_iter_peek_upto(iter, lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX)); | |
| 2030 | + if (!k.k && !*wrapped) { | |
| 2031 | + bch2_btree_iter_set_pos(iter, lru_pos(ca->dev_idx, 0, 0)); | |
| 2032 | + *wrapped = true; | |
| 2033 | + goto again; | |
| 2034 | + } | |
| 2035 | + | |
| 2036 | + return k; | |
| 2037 | +} | |
| 2038 | + | |
| 2014 | 2039 | static void bch2_do_invalidates_work(struct work_struct *work) |
| 2015 | 2040 | { |
| 2016 | 2041 | struct bch_fs *c = container_of(work, struct bch_fs, invalidate_work); |
| @@ -2024,12 +2049,33 @@ static void bch2_do_invalidates_work(struct work_struct *work) · 7 unmodified lines | ||
| 2024 | 2049 | for_each_member_device(c, ca) { |
| 2025 | 2050 | s64 nr_to_invalidate = |
| 2026 | 2051 | should_invalidate_buckets(ca, bch2_dev_usage_read(ca)); |
| 2052 | + struct btree_iter iter; | |
| 2053 | + bool wrapped = false; | |
| 2054 | + | |
| 2055 | + bch2_trans_iter_init(trans, &iter, BTREE_ID_lru, | |
| 2056 | + lru_pos(ca->dev_idx, 0, | |
| 2057 | + ((bch2_current_io_time(c, READ) + U32_MAX) & | |
| 2058 | + LRU_TIME_MAX)), 0); | |
| 2027 | 2059 | |
| 2028 | − ret = for_each_btree_key_upto(trans, iter, BTREE_ID_lru, | |
| 2029 | − lru_pos(ca->dev_idx, 0, 0), | |
| 2030 | − lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX), | |
| 2031 | − BTREE_ITER_intent, k, | |
| 2032 | − invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate)); | |
| 2060 | + while (true) { | |
| 2061 | + bch2_trans_begin(trans); | |
| 2062 | + | |
| 2063 | + struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped); | |
| 2064 | + ret = bkey_err(k); | |
| 2065 | + if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) | |
| 2066 | + continue; | |
| 2067 | + if (ret) | |
| 2068 | + break; | |
| 2069 | + if (!k.k) | |
| 2070 | + break; | |
| 2071 | + | |
| 2072 | + ret = invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate); | |
| 2073 | + if (ret) | |
| 2074 | + break; | |
| 2075 | + | |
| 2076 | + bch2_btree_iter_advance(&iter); | |
| 2077 | + } | |
| 2078 | + bch2_trans_iter_exit(trans, &iter); | |
| 2033 | 2079 | |
| 2034 | 2080 | if (ret < 0) { |
| 2035 | 2081 | bch2_dev_put(ca); |
| @@ -2204,7 +2250,7 @@ int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev, · 168 unmodified lines | ||
| 2204 | 2250 | if (ret) |
| 2205 | 2251 | return ret; |
| 2206 | 2252 | |
| 2207 | − now = atomic64_read(&c->io_clock[rw].now); | |
| 2253 | + now = bch2_current_io_time(c, rw); | |
| 2208 | 2254 | if (a->v.io_time[rw] == now) |
| 2209 | 2255 | goto out; |
| 2210 | 2256 | |
| @@ -141,7 +141,13 @@ static inline u64 alloc_lru_idx_fragmentation(struct bch_alloc_v4 a, · 140 unmodified lines | ||
| 141 | 141 | !bch2_bucket_sectors_fragmented(ca, a)) |
| 142 | 142 | return 0; |
| 143 | 143 | |
| 144 | − u64 d = bch2_bucket_sectors_dirty(a); | |
| 144 | + /* | |
| 145 | + * avoid overflowing LRU_TIME_BITS on a corrupted fs, when | |
| 146 | + * bucket_sectors_dirty is (much) bigger than bucket_size | |
| 147 | + */ | |
| 148 | + u64 d = min(bch2_bucket_sectors_dirty(a), | |
| 149 | + ca->mi.bucket_size); | |
| 150 | + | |
| 145 | 151 | return div_u64(d * (1ULL << 31), ca->mi.bucket_size); |
| 146 | 152 | } |
| 147 | 153 | |
| @@ -1214,6 +1214,11 @@ static inline s64 bch2_current_time(const struct bch_fs *c) · 1213 unmodified lines | ||
| 1214 | 1214 | return timespec_to_bch2_time(c, now); |
| 1215 | 1215 | } |
| 1216 | 1216 | |
| 1217 | +static inline u64 bch2_current_io_time(const struct bch_fs *c, int rw) | |
| 1218 | +{ | |
| 1219 | + return max(1ULL, (u64) atomic64_read(&c->io_clock[rw].now) & LRU_TIME_MAX); | |
| 1220 | +} | |
| 1221 | + | |
| 1217 | 1222 | static inline struct stdio_redirect *bch2_fs_stdio_redirect(struct bch_fs *c) |
| 1218 | 1223 | { |
| 1219 | 1224 | struct stdio_redirect *stdio = c->stdio; |
| @@ -476,6 +476,9 @@ struct bch_lru { · 475 unmodified lines | ||
| 476 | 476 | |
| 477 | 477 | #define LRU_ID_STRIPES (1U << 16) |
| 478 | 478 | |
| 479 | +#define LRU_TIME_BITS 48 | |
| 480 | +#define LRU_TIME_MAX ((1ULL << LRU_TIME_BITS) - 1) | |
| 481 | + | |
| 479 | 482 | /* Optional/variable size superblock sections: */ |
| 480 | 483 | |
| 481 | 484 | struct bch_sb_field { |
| @@ -987,8 +990,9 @@ enum bch_version_upgrade_opts { · 505 unmodified lines | ||
| 987 | 990 | |
| 988 | 991 | #define BCH_ERROR_ACTIONS() \ |
| 989 | 992 | x(continue, 0) \ |
| 990 | − x(ro, 1) \ | |
| 991 | − x(panic, 2) | |
| 993 | + x(fix_safe, 1) \ | |
| 994 | + x(panic, 2) \ | |
| 995 | + x(ro, 3) | |
| 992 | 996 | |
| 993 | 997 | enum bch_error_actions { |
| 994 | 998 | #define x(t, n) BCH_ON_ERROR_##t = n, |
| @@ -1382,9 +1386,10 @@ enum btree_id { · 387 unmodified lines | ||
| 1382 | 1386 | |
| 1383 | 1387 | /* |
| 1384 | 1388 | * Maximum number of btrees that we will _ever_ have under the current scheme, |
| 1385 | − * where we refer to them with bitfields | |
| 1389 | + * where we refer to them with 64 bit bitfields - and we also need a bit for | |
| 1390 | + * the interior btree node type: | |
| 1386 | 1391 | */ |
| 1387 | −#define BTREE_ID_NR_MAX 64 | |
| 1392 | +#define BTREE_ID_NR_MAX 63 | |
| 1388 | 1393 | |
| 1389 | 1394 | static inline bool btree_id_is_alloc(enum btree_id id) |
| 1390 | 1395 | { |
| @@ -1064,7 +1064,7 @@ void bch2_bkey_swab_key(const struct bkey_format *_f, struct bkey_packed *k) · 1063 unmodified lines | ||
| 1064 | 1064 | { |
| 1065 | 1065 | const struct bkey_format *f = bkey_packed(k) ? _f : &bch2_bkey_format_current; |
| 1066 | 1066 | u8 *l = k->key_start; |
| 1067 | − u8 *h = (u8 *) (k->_data + f->key_u64s) - 1; | |
| 1067 | + u8 *h = (u8 *) ((u64 *) k->_data + f->key_u64s) - 1; | |
| 1068 | 1068 | |
| 1069 | 1069 | while (l < h) { |
| 1070 | 1070 | swap(*l, *h); |
| @@ -398,8 +398,12 @@ void __bch2_bkey_compat(unsigned level, enum btree_id btree_id, · 397 unmodified lines | ||
| 398 | 398 | for (i = 0; i < nr_compat; i++) |
| 399 | 399 | switch (!write ? i : nr_compat - 1 - i) { |
| 400 | 400 | case 0: |
| 401 | − if (big_endian != CPU_BIG_ENDIAN) | |
| 401 | + if (big_endian != CPU_BIG_ENDIAN) { | |
| 402 | + bch2_bkey_swab_key(f, k); | |
| 403 | + } else if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG)) { | |
| 402 | 404 | bch2_bkey_swab_key(f, k); |
| 405 | + bch2_bkey_swab_key(f, k); | |
| 406 | + } | |
| 403 | 407 | break; |
| 404 | 408 | case 1: |
| 405 | 409 | if (version < bcachefs_metadata_version_bkey_renumber) |
| @@ -129,7 +129,8 @@ static inline void bch2_bkey_compat(unsigned level, enum btree_id btree_id, · 128 unmodified lines | ||
| 129 | 129 | struct bkey_packed *k) |
| 130 | 130 | { |
| 131 | 131 | if (version < bcachefs_metadata_version_current || |
| 132 | − big_endian != CPU_BIG_ENDIAN) | |
| 132 | + big_endian != CPU_BIG_ENDIAN || | |
| 133 | + IS_ENABLED(CONFIG_BCACHEFS_DEBUG)) | |
| 133 | 134 | __bch2_bkey_compat(level, btree_id, version, |
| 134 | 135 | big_endian, write, f, k); |
| 135 | 136 | |
| @@ -3161,6 +3161,7 @@ struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx) · 3160 unmodified lines | ||
| 3161 | 3161 | list_add_done: |
| 3162 | 3162 | seqmutex_unlock(&c->btree_trans_lock); |
| 3163 | 3163 | got_trans: |
| 3164 | + trans->ref.closure_get_happened = false; | |
| 3164 | 3165 | trans->c = c; |
| 3165 | 3166 | trans->last_begin_time = local_clock(); |
| 3166 | 3167 | trans->fn_idx = fn_idx; |
| @@ -3235,7 +3236,6 @@ void bch2_trans_put(struct btree_trans *trans) · 68 unmodified lines | ||
| 3235 | 3236 | trans_for_each_update(trans, i) |
| 3236 | 3237 | __btree_path_put(trans->paths + i->path, true); |
| 3237 | 3238 | trans->nr_updates = 0; |
| 3238 | − trans->locking_wait.task = NULL; | |
| 3239 | 3239 | |
| 3240 | 3240 | check_btree_paths_leaked(trans); |
| 3241 | 3241 | |
| @@ -3256,6 +3256,13 @@ void bch2_trans_put(struct btree_trans *trans) · 14 unmodified lines | ||
| 3256 | 3256 | if (unlikely(trans->journal_replay_not_finished)) |
| 3257 | 3257 | bch2_journal_keys_put(c); |
| 3258 | 3258 | |
| 3259 | + /* | |
| 3260 | + * trans->ref protects trans->locking_wait.task, btree_paths arary; used | |
| 3261 | + * by cycle detector | |
| 3262 | + */ | |
| 3263 | + closure_sync(&trans->ref); | |
| 3264 | + trans->locking_wait.task = NULL; | |
| 3265 | + | |
| 3259 | 3266 | unsigned long *paths_allocated = trans->paths_allocated; |
| 3260 | 3267 | trans->paths_allocated = NULL; |
| 3261 | 3268 | trans->paths = NULL; |
| @@ -3273,8 +3280,6 @@ void bch2_trans_put(struct btree_trans *trans) · 11 unmodified lines | ||
| 3273 | 3280 | trans = this_cpu_xchg(c->btree_trans_bufs->trans, trans); |
| 3274 | 3281 | |
| 3275 | 3282 | if (trans) { |
| 3276 | − closure_sync(&trans->ref); | |
| 3277 | − | |
| 3278 | 3283 | seqmutex_lock(&c->btree_trans_lock); |
| 3279 | 3284 | list_del(&trans->list); |
| 3280 | 3285 | seqmutex_unlock(&c->btree_trans_lock); |
| @@ -761,13 +761,13 @@ static inline bool btree_node_type_needs_gc(enum btree_node_type type) · 760 unmodified lines | ||
| 761 | 761 | |
| 762 | 762 | static inline bool btree_node_type_is_extents(enum btree_node_type type) |
| 763 | 763 | { |
| 764 | − const unsigned mask = 0 | |
| 764 | + const u64 mask = 0 | |
| 765 | 765 | #define x(name, nr, flags, ...) |((!!((flags) & BTREE_ID_EXTENTS)) << (nr + 1)) |
| 766 | 766 | BCH_BTREE_IDS() |
| 767 | 767 | #undef x |
| 768 | 768 | ; |
| 769 | 769 | |
| 770 | − return (1U << type) & mask; | |
| 770 | + return BIT_ULL(type) & mask; | |
| 771 | 771 | } |
| 772 | 772 | |
| 773 | 773 | static inline bool btree_id_is_extents(enum btree_id btree) |
| @@ -777,35 +777,35 @@ static inline bool btree_id_is_extents(enum btree_id btree) · 3 unmodified lines | ||
| 777 | 777 | |
| 778 | 778 | static inline bool btree_type_has_snapshots(enum btree_id id) |
| 779 | 779 | { |
| 780 | − const unsigned mask = 0 | |
| 780 | + const u64 mask = 0 | |
| 781 | 781 | #define x(name, nr, flags, ...) |((!!((flags) & BTREE_ID_SNAPSHOTS)) << nr) |
| 782 | 782 | BCH_BTREE_IDS() |
| 783 | 783 | #undef x |
| 784 | 784 | ; |
| 785 | 785 | |
| 786 | − return (1U << id) & mask; | |
| 786 | + return BIT_ULL(id) & mask; | |
| 787 | 787 | } |
| 788 | 788 | |
| 789 | 789 | static inline bool btree_type_has_snapshot_field(enum btree_id id) |
| 790 | 790 | { |
| 791 | − const unsigned mask = 0 | |
| 791 | + const u64 mask = 0 | |
| 792 | 792 | #define x(name, nr, flags, ...) |((!!((flags) & (BTREE_ID_SNAPSHOT_FIELD|BTREE_ID_SNAPSHOTS))) << nr) |
| 793 | 793 | BCH_BTREE_IDS() |
| 794 | 794 | #undef x |
| 795 | 795 | ; |
| 796 | 796 | |
| 797 | − return (1U << id) & mask; | |
| 797 | + return BIT_ULL(id) & mask; | |
| 798 | 798 | } |
| 799 | 799 | |
| 800 | 800 | static inline bool btree_type_has_ptrs(enum btree_id id) |
| 801 | 801 | { |
| 802 | − const unsigned mask = 0 | |
| 802 | + const u64 mask = 0 | |
| 803 | 803 | #define x(name, nr, flags, ...) |((!!((flags) & BTREE_ID_DATA)) << nr) |
| 804 | 804 | BCH_BTREE_IDS() |
| 805 | 805 | #undef x |
| 806 | 806 | ; |
| 807 | 807 | |
| 808 | − return (1U << id) & mask; | |
| 808 | + return BIT_ULL(id) & mask; | |
| 809 | 809 | } |
| 810 | 810 | |
| 811 | 811 | struct btree_root { |
| @@ -116,6 +116,9 @@ · 115 unmodified lines | ||
| 116 | 116 | x(ENOENT, ENOENT_dev_idx_not_found) \ |
| 117 | 117 | x(ENOTEMPTY, ENOTEMPTY_dir_not_empty) \ |
| 118 | 118 | x(ENOTEMPTY, ENOTEMPTY_subvol_not_empty) \ |
| 119 | + x(EEXIST, EEXIST_str_hash_set) \ | |
| 120 | + x(EEXIST, EEXIST_discard_in_flight_add) \ | |
| 121 | + x(EEXIST, EEXIST_subvolume_create) \ | |
| 119 | 122 | x(0, open_buckets_empty) \ |
| 120 | 123 | x(0, freelist_empty) \ |
| 121 | 124 | x(BCH_ERR_freelist_empty, no_buckets_found) \ |
| @@ -15,6 +15,7 @@ bool bch2_inconsistent_error(struct bch_fs *c) · 14 unmodified lines | ||
| 15 | 15 | switch (c->opts.errors) { |
| 16 | 16 | case BCH_ON_ERROR_continue: |
| 17 | 17 | return false; |
| 18 | + case BCH_ON_ERROR_fix_safe: | |
| 18 | 19 | case BCH_ON_ERROR_ro: |
| 19 | 20 | if (bch2_fs_emergency_read_only(c)) |
| 20 | 21 | bch_err(c, "inconsistency detected - emergency read only at journal seq %llu", |
| @@ -191,6 +192,12 @@ static void prt_actioning(struct printbuf *out, const char *action) · 170 unmodified lines | ||
| 191 | 192 | prt_str(out, "ing"); |
| 192 | 193 | } |
| 193 | 194 | |
| 195 | +static const u8 fsck_flags_extra[] = { | |
| 196 | +#define x(t, n, flags) [BCH_FSCK_ERR_##t] = flags, | |
| 197 | + BCH_SB_ERRS() | |
| 198 | +#undef x | |
| 199 | +}; | |
| 200 | + | |
| 194 | 201 | int bch2_fsck_err(struct bch_fs *c, |
| 195 | 202 | enum bch_fsck_flags flags, |
| 196 | 203 | enum bch_sb_error_id err, |
| @@ -203,6 +210,9 @@ int bch2_fsck_err(struct bch_fs *c, · 6 unmodified lines | ||
| 203 | 210 | int ret = -BCH_ERR_fsck_ignore; |
| 204 | 211 | const char *action_orig = "fix?", *action = action_orig; |
| 205 | 212 | |
| 213 | + if (!WARN_ON(err >= ARRAY_SIZE(fsck_flags_extra))) | |
| 214 | + flags |= fsck_flags_extra[err]; | |
| 215 | + | |
| 206 | 216 | if ((flags & FSCK_CAN_FIX) && |
| 207 | 217 | test_bit(err, c->sb.errors_silent)) |
| 208 | 218 | return -BCH_ERR_fsck_fix; |
| @@ -265,7 +275,14 @@ int bch2_fsck_err(struct bch_fs *c, · 56 unmodified lines | ||
| 265 | 275 | prt_printf(out, bch2_log_msg(c, "")); |
| 266 | 276 | #endif |
| 267 | 277 | |
| 268 | − if (!test_bit(BCH_FS_fsck_running, &c->flags)) { | |
| 278 | + if ((flags & FSCK_CAN_FIX) && | |
| 279 | + (flags & FSCK_AUTOFIX) && | |
| 280 | + (c->opts.errors == BCH_ON_ERROR_continue || | |
| 281 | + c->opts.errors == BCH_ON_ERROR_fix_safe)) { | |
| 282 | + prt_str(out, ", "); | |
| 283 | + prt_actioning(out, action); | |
| 284 | + ret = -BCH_ERR_fsck_fix; | |
| 285 | + } else if (!test_bit(BCH_FS_fsck_running, &c->flags)) { | |
| 269 | 286 | if (c->opts.errors != BCH_ON_ERROR_continue || |
| 270 | 287 | !(flags & (FSCK_CAN_FIX|FSCK_CAN_IGNORE))) { |
| 271 | 288 | prt_str(out, ", shutting down"); |
| @@ -108,13 +108,6 @@ struct fsck_err_state { · 107 unmodified lines | ||
| 108 | 108 | char *last_msg; |
| 109 | 109 | }; |
| 110 | 110 | |
| 111 | −enum bch_fsck_flags { | |
| 112 | − FSCK_CAN_FIX = 1 << 0, | |
| 113 | − FSCK_CAN_IGNORE = 1 << 1, | |
| 114 | − FSCK_NEED_FSCK = 1 << 2, | |
| 115 | − FSCK_NO_RATELIMIT = 1 << 3, | |
| 116 | −}; | |
| 117 | − | |
| 118 | 111 | #define fsck_err_count(_c, _err) bch2_sb_err_count(_c, BCH_FSCK_ERR_##_err) |
| 119 | 112 | |
| 120 | 113 | __printf(4, 5) __cold |
| @@ -373,7 +373,7 @@ retry: · 372 unmodified lines | ||
| 373 | 373 | } |
| 374 | 374 | |
| 375 | 375 | if (dst_dentry->d_inode) { |
| 376 | − error = -EEXIST; | |
| 376 | + error = -BCH_ERR_EEXIST_subvolume_create; | |
| 377 | 377 | goto err3; |
| 378 | 378 | } |
| 379 | 379 | |
| @@ -188,6 +188,12 @@ static struct bch_inode_info *bch2_inode_insert(struct bch_fs *c, struct bch_ino · 187 unmodified lines | ||
| 188 | 188 | BUG_ON(!old); |
| 189 | 189 | |
| 190 | 190 | if (unlikely(old != inode)) { |
| 191 | + /* | |
| 192 | + * bcachefs doesn't use I_NEW; we have no use for it since we | |
| 193 | + * only insert fully created inodes in the inode hash table. But | |
| 194 | + * discard_new_inode() expects it to be set... | |
| 195 | + */ | |
| 196 | + inode->v.i_flags |= I_NEW; | |
| 191 | 197 | discard_new_inode(&inode->v); |
| 192 | 198 | inode = old; |
| 193 | 199 | } else { |
| @@ -195,8 +201,10 @@ static struct bch_inode_info *bch2_inode_insert(struct bch_fs *c, struct bch_ino · 1 unmodified line | ||
| 195 | 201 | list_add(&inode->ei_vfs_inode_list, &c->vfs_inodes_list); |
| 196 | 202 | mutex_unlock(&c->vfs_inodes_lock); |
| 197 | 203 | /* |
| 198 | − * we really don't want insert_inode_locked2() to be setting | |
| 199 | − * I_NEW... | |
| 204 | + * Again, I_NEW makes no sense for bcachefs. This is only needed | |
| 205 | + * for clearing I_NEW, but since the inode was already fully | |
| 206 | + * created and initialized we didn't actually want | |
| 207 | + * inode_insert5() to set it for us. | |
| 200 | 208 | */ |
| 201 | 209 | unlock_new_inode(&inode->v); |
| 202 | 210 | } |
| @@ -1157,6 +1165,7 @@ static const struct file_operations bch_file_operations = { · 954 unmodified lines | ||
| 1157 | 1165 | .read_iter = bch2_read_iter, |
| 1158 | 1166 | .write_iter = bch2_write_iter, |
| 1159 | 1167 | .mmap = bch2_mmap, |
| 1168 | + .get_unmapped_area = thp_get_unmapped_area, | |
| 1160 | 1169 | .fsync = bch2_fsync, |
| 1161 | 1170 | .splice_read = filemap_splice_read, |
| 1162 | 1171 | .splice_write = iter_file_splice_write, |
| @@ -1488,11 +1497,6 @@ static void bch2_vfs_inode_init(struct btree_trans *trans, subvol_inum inum, · 325 unmodified lines | ||
| 1488 | 1497 | bch2_iget5_set(&inode->v, &inum); |
| 1489 | 1498 | bch2_inode_update_after_write(trans, inode, bi, ~0); |
| 1490 | 1499 | |
| 1491 | − if (BCH_SUBVOLUME_SNAP(subvol)) | |
| 1492 | − set_bit(EI_INODE_SNAPSHOT, &inode->ei_flags); | |
| 1493 | − else | |
| 1494 | − clear_bit(EI_INODE_SNAPSHOT, &inode->ei_flags); | |
| 1495 | − | |
| 1496 | 1500 | inode->v.i_blocks = bi->bi_sectors; |
| 1497 | 1501 | inode->v.i_ino = bi->bi_inum; |
| 1498 | 1502 | inode->v.i_rdev = bi->bi_dev; |
| @@ -1504,6 +1508,9 @@ static void bch2_vfs_inode_init(struct btree_trans *trans, subvol_inum inum, · 5 unmodified lines | ||
| 1504 | 1508 | inode->ei_qid = bch_qid(bi); |
| 1505 | 1509 | inode->ei_subvol = inum.subvol; |
| 1506 | 1510 | |
| 1511 | + if (BCH_SUBVOLUME_SNAP(subvol)) | |
| 1512 | + set_bit(EI_INODE_SNAPSHOT, &inode->ei_flags); | |
| 1513 | + | |
| 1507 | 1514 | inode->v.i_mapping->a_ops = &bch_address_space_operations; |
| 1508 | 1515 | |
| 1509 | 1516 | switch (inode->v.i_mode & S_IFMT) { |
| @@ -1167,6 +1167,9 @@ void bch2_dev_journal_stop(struct journal *j, struct bch_dev *ca) · 1166 unmodified lines | ||
| 1167 | 1167 | |
| 1168 | 1168 | void bch2_fs_journal_stop(struct journal *j) |
| 1169 | 1169 | { |
| 1170 | + if (!test_bit(JOURNAL_running, &j->flags)) | |
| 1171 | + return; | |
| 1172 | + | |
| 1170 | 1173 | bch2_journal_reclaim_stop(j); |
| 1171 | 1174 | bch2_journal_flush_all_pins(j); |
| 1172 | 1175 | |
| @@ -1967,7 +1967,6 @@ CLOSURE_CALLBACK(bch2_journal_write) · 1966 unmodified lines | ||
| 1967 | 1967 | struct journal *j = container_of(w, struct journal, buf[w->idx]); |
| 1968 | 1968 | struct bch_fs *c = container_of(j, struct bch_fs, journal); |
| 1969 | 1969 | struct bch_replicas_padded replicas; |
| 1970 | − struct printbuf journal_debug_buf = PRINTBUF; | |
| 1971 | 1970 | unsigned nr_rw_members = 0; |
| 1972 | 1971 | int ret; |
| 1973 | 1972 | |
| @@ -2011,11 +2010,15 @@ CLOSURE_CALLBACK(bch2_journal_write) · 37 unmodified lines | ||
| 2011 | 2010 | } |
| 2012 | 2011 | |
| 2013 | 2012 | if (ret) { |
| 2014 | − __bch2_journal_debug_to_text(&journal_debug_buf, j); | |
| 2013 | + struct printbuf buf = PRINTBUF; | |
| 2014 | + buf.atomic++; | |
| 2015 | + | |
| 2016 | + prt_printf(&buf, bch2_fmt(c, "Unable to allocate journal write: %s"), | |
| 2017 | + bch2_err_str(ret)); | |
| 2018 | + __bch2_journal_debug_to_text(&buf, j); | |
| 2015 | 2019 | spin_unlock(&j->lock); |
| 2016 | − bch_err(c, "Unable to allocate journal write:\n%s", | |
| 2017 | − journal_debug_buf.buf); | |
| 2018 | − printbuf_exit(&journal_debug_buf); | |
| 2020 | + bch2_print_string_as_lines(KERN_ERR, buf.buf); | |
| 2021 | + printbuf_exit(&buf); | |
| 2019 | 2022 | goto err; |
| 2020 | 2023 | } |
| 2021 | 2024 | |
| @@ -2,9 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _BCACHEFS_LRU_H |
| 3 | 3 | #define _BCACHEFS_LRU_H |
| 4 | 4 | |
| 5 | −#define LRU_TIME_BITS 48 | |
| 6 | −#define LRU_TIME_MAX ((1ULL << LRU_TIME_BITS) - 1) | |
| 7 | − | |
| 8 | 5 | static inline u64 lru_pos_id(struct bpos pos) |
| 9 | 6 | { |
| 10 | 7 | return pos.inode >> LRU_TIME_BITS; |
| @@ -137,7 +137,7 @@ enum fsck_err_opts { · 136 unmodified lines | ||
| 137 | 137 | x(errors, u8, \ |
| 138 | 138 | OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ |
| 139 | 139 | OPT_STR(bch2_error_actions), \ |
| 140 | − BCH_SB_ERROR_ACTION, BCH_ON_ERROR_ro, \ | |
| 140 | + BCH_SB_ERROR_ACTION, BCH_ON_ERROR_fix_safe, \ | |
| 141 | 141 | NULL, "Action to take on filesystem error") \ |
| 142 | 142 | x(metadata_replicas, u8, \ |
| 143 | 143 | OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ |
| @@ -326,6 +326,12 @@ static int journal_replay_entry_early(struct bch_fs *c, · 325 unmodified lines | ||
| 326 | 326 | case BCH_JSET_ENTRY_btree_root: { |
| 327 | 327 | struct btree_root *r; |
| 328 | 328 | |
| 329 | + if (fsck_err_on(entry->btree_id >= BTREE_ID_NR_MAX, | |
| 330 | + c, invalid_btree_id, | |
| 331 | + "invalid btree id %u (max %u)", | |
| 332 | + entry->btree_id, BTREE_ID_NR_MAX)) | |
| 333 | + return 0; | |
| 334 | + | |
| 329 | 335 | while (entry->btree_id >= c->btree_roots_extra.nr + BTREE_ID_NR) { |
| 330 | 336 | ret = darray_push(&c->btree_roots_extra, (struct btree_root) { NULL }); |
| 331 | 337 | if (ret) |
| @@ -415,7 +421,7 @@ static int journal_replay_entry_early(struct bch_fs *c, · 83 unmodified lines | ||
| 415 | 421 | atomic64_set(&c->io_clock[clock->rw].now, le64_to_cpu(clock->time)); |
| 416 | 422 | } |
| 417 | 423 | } |
| 418 | − | |
| 424 | +fsck_err: | |
| 419 | 425 | return ret; |
| 420 | 426 | } |
| 421 | 427 | |
| @@ -658,10 +664,10 @@ int bch2_fs_recovery(struct bch_fs *c) · 236 unmodified lines | ||
| 658 | 664 | if (check_version_upgrade(c)) |
| 659 | 665 | write_sb = true; |
| 660 | 666 | |
| 667 | + c->recovery_passes_explicit |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0])); | |
| 668 | + | |
| 661 | 669 | if (write_sb) |
| 662 | 670 | bch2_write_super(c); |
| 663 | − | |
| 664 | − c->recovery_passes_explicit |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0])); | |
| 665 | 671 | mutex_unlock(&c->sb_lock); |
| 666 | 672 | |
| 667 | 673 | if (c->opts.fsck && IS_ENABLED(CONFIG_BCACHEFS_DEBUG)) |
| @@ -228,7 +228,7 @@ int bch2_sb_downgrade_update(struct bch_fs *c) · 227 unmodified lines | ||
| 228 | 228 | |
| 229 | 229 | dst = (void *) &darray_top(table); |
| 230 | 230 | dst->version = cpu_to_le16(src->version); |
| 231 | − dst->recovery_passes[0] = cpu_to_le64(src->recovery_passes); | |
| 231 | + dst->recovery_passes[0] = cpu_to_le64(bch2_recovery_passes_to_stable(src->recovery_passes)); | |
| 232 | 232 | dst->recovery_passes[1] = 0; |
| 233 | 233 | dst->nr_errors = cpu_to_le16(src->nr_errors); |
| 234 | 234 | for (unsigned i = 0; i < src->nr_errors; i++) |
| @@ -2,281 +2,294 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _BCACHEFS_SB_ERRORS_FORMAT_H |
| 3 | 3 | #define _BCACHEFS_SB_ERRORS_FORMAT_H |
| 4 | 4 | |
| 5 | −#define BCH_SB_ERRS() \ | |
| 6 | − x(clean_but_journal_not_empty, 0) \ | |
| 7 | − x(dirty_but_no_journal_entries, 1) \ | |
| 8 | − x(dirty_but_no_journal_entries_post_drop_nonflushes, 2) \ | |
| 9 | − x(sb_clean_journal_seq_mismatch, 3) \ | |
| 10 | − x(sb_clean_btree_root_mismatch, 4) \ | |
| 11 | − x(sb_clean_missing, 5) \ | |
| 12 | − x(jset_unsupported_version, 6) \ | |
| 13 | − x(jset_unknown_csum, 7) \ | |
| 14 | − x(jset_last_seq_newer_than_seq, 8) \ | |
| 15 | − x(jset_past_bucket_end, 9) \ | |
| 16 | − x(jset_seq_blacklisted, 10) \ | |
| 17 | − x(journal_entries_missing, 11) \ | |
| 18 | − x(journal_entry_replicas_not_marked, 12) \ | |
| 19 | − x(journal_entry_past_jset_end, 13) \ | |
| 20 | − x(journal_entry_replicas_data_mismatch, 14) \ | |
| 21 | − x(journal_entry_bkey_u64s_0, 15) \ | |
| 22 | − x(journal_entry_bkey_past_end, 16) \ | |
| 23 | − x(journal_entry_bkey_bad_format, 17) \ | |
| 24 | − x(journal_entry_bkey_invalid, 18) \ | |
| 25 | − x(journal_entry_btree_root_bad_size, 19) \ | |
| 26 | − x(journal_entry_blacklist_bad_size, 20) \ | |
| 27 | − x(journal_entry_blacklist_v2_bad_size, 21) \ | |
| 28 | − x(journal_entry_blacklist_v2_start_past_end, 22) \ | |
| 29 | − x(journal_entry_usage_bad_size, 23) \ | |
| 30 | − x(journal_entry_data_usage_bad_size, 24) \ | |
| 31 | − x(journal_entry_clock_bad_size, 25) \ | |
| 32 | − x(journal_entry_clock_bad_rw, 26) \ | |
| 33 | − x(journal_entry_dev_usage_bad_size, 27) \ | |
| 34 | − x(journal_entry_dev_usage_bad_dev, 28) \ | |
| 35 | − x(journal_entry_dev_usage_bad_pad, 29) \ | |
| 36 | − x(btree_node_unreadable, 30) \ | |
| 37 | − x(btree_node_fault_injected, 31) \ | |
| 38 | − x(btree_node_bad_magic, 32) \ | |
| 39 | − x(btree_node_bad_seq, 33) \ | |
| 40 | − x(btree_node_unsupported_version, 34) \ | |
| 41 | − x(btree_node_bset_older_than_sb_min, 35) \ | |
| 42 | − x(btree_node_bset_newer_than_sb, 36) \ | |
| 43 | − x(btree_node_data_missing, 37) \ | |
| 44 | − x(btree_node_bset_after_end, 38) \ | |
| 45 | − x(btree_node_replicas_sectors_written_mismatch, 39) \ | |
| 46 | − x(btree_node_replicas_data_mismatch, 40) \ | |
| 47 | − x(bset_unknown_csum, 41) \ | |
| 48 | − x(bset_bad_csum, 42) \ | |
| 49 | − x(bset_past_end_of_btree_node, 43) \ | |
| 50 | − x(bset_wrong_sector_offset, 44) \ | |
| 51 | − x(bset_empty, 45) \ | |
| 52 | − x(bset_bad_seq, 46) \ | |
| 53 | − x(bset_blacklisted_journal_seq, 47) \ | |
| 54 | − x(first_bset_blacklisted_journal_seq, 48) \ | |
| 55 | − x(btree_node_bad_btree, 49) \ | |
| 56 | − x(btree_node_bad_level, 50) \ | |
| 57 | − x(btree_node_bad_min_key, 51) \ | |
| 58 | − x(btree_node_bad_max_key, 52) \ | |
| 59 | − x(btree_node_bad_format, 53) \ | |
| 60 | − x(btree_node_bkey_past_bset_end, 54) \ | |
| 61 | − x(btree_node_bkey_bad_format, 55) \ | |
| 62 | − x(btree_node_bad_bkey, 56) \ | |
| 63 | − x(btree_node_bkey_out_of_order, 57) \ | |
| 64 | − x(btree_root_bkey_invalid, 58) \ | |
| 65 | − x(btree_root_read_error, 59) \ | |
| 66 | − x(btree_root_bad_min_key, 60) \ | |
| 67 | − x(btree_root_bad_max_key, 61) \ | |
| 68 | − x(btree_node_read_error, 62) \ | |
| 69 | − x(btree_node_topology_bad_min_key, 63) \ | |
| 70 | − x(btree_node_topology_bad_max_key, 64) \ | |
| 71 | − x(btree_node_topology_overwritten_by_prev_node, 65) \ | |
| 72 | − x(btree_node_topology_overwritten_by_next_node, 66) \ | |
| 73 | − x(btree_node_topology_interior_node_empty, 67) \ | |
| 74 | − x(fs_usage_hidden_wrong, 68) \ | |
| 75 | − x(fs_usage_btree_wrong, 69) \ | |
| 76 | − x(fs_usage_data_wrong, 70) \ | |
| 77 | − x(fs_usage_cached_wrong, 71) \ | |
| 78 | − x(fs_usage_reserved_wrong, 72) \ | |
| 79 | − x(fs_usage_persistent_reserved_wrong, 73) \ | |
| 80 | − x(fs_usage_nr_inodes_wrong, 74) \ | |
| 81 | − x(fs_usage_replicas_wrong, 75) \ | |
| 82 | − x(dev_usage_buckets_wrong, 76) \ | |
| 83 | − x(dev_usage_sectors_wrong, 77) \ | |
| 84 | − x(dev_usage_fragmented_wrong, 78) \ | |
| 85 | − x(dev_usage_buckets_ec_wrong, 79) \ | |
| 86 | − x(bkey_version_in_future, 80) \ | |
| 87 | − x(bkey_u64s_too_small, 81) \ | |
| 88 | − x(bkey_invalid_type_for_btree, 82) \ | |
| 89 | − x(bkey_extent_size_zero, 83) \ | |
| 90 | − x(bkey_extent_size_greater_than_offset, 84) \ | |
| 91 | − x(bkey_size_nonzero, 85) \ | |
| 92 | − x(bkey_snapshot_nonzero, 86) \ | |
| 93 | − x(bkey_snapshot_zero, 87) \ | |
| 94 | − x(bkey_at_pos_max, 88) \ | |
| 95 | − x(bkey_before_start_of_btree_node, 89) \ | |
| 96 | − x(bkey_after_end_of_btree_node, 90) \ | |
| 97 | − x(bkey_val_size_nonzero, 91) \ | |
| 98 | − x(bkey_val_size_too_small, 92) \ | |
| 99 | − x(alloc_v1_val_size_bad, 93) \ | |
| 100 | − x(alloc_v2_unpack_error, 94) \ | |
| 101 | − x(alloc_v3_unpack_error, 95) \ | |
| 102 | − x(alloc_v4_val_size_bad, 96) \ | |
| 103 | − x(alloc_v4_backpointers_start_bad, 97) \ | |
| 104 | − x(alloc_key_data_type_bad, 98) \ | |
| 105 | − x(alloc_key_empty_but_have_data, 99) \ | |
| 106 | − x(alloc_key_dirty_sectors_0, 100) \ | |
| 107 | − x(alloc_key_data_type_inconsistency, 101) \ | |
| 108 | − x(alloc_key_to_missing_dev_bucket, 102) \ | |
| 109 | − x(alloc_key_cached_inconsistency, 103) \ | |
| 110 | − x(alloc_key_cached_but_read_time_zero, 104) \ | |
| 111 | − x(alloc_key_to_missing_lru_entry, 105) \ | |
| 112 | − x(alloc_key_data_type_wrong, 106) \ | |
| 113 | − x(alloc_key_gen_wrong, 107) \ | |
| 114 | − x(alloc_key_dirty_sectors_wrong, 108) \ | |
| 115 | − x(alloc_key_cached_sectors_wrong, 109) \ | |
| 116 | − x(alloc_key_stripe_wrong, 110) \ | |
| 117 | − x(alloc_key_stripe_redundancy_wrong, 111) \ | |
| 118 | − x(bucket_sector_count_overflow, 112) \ | |
| 119 | − x(bucket_metadata_type_mismatch, 113) \ | |
| 120 | − x(need_discard_key_wrong, 114) \ | |
| 121 | − x(freespace_key_wrong, 115) \ | |
| 122 | − x(freespace_hole_missing, 116) \ | |
| 123 | − x(bucket_gens_val_size_bad, 117) \ | |
| 124 | − x(bucket_gens_key_wrong, 118) \ | |
| 125 | − x(bucket_gens_hole_wrong, 119) \ | |
| 126 | − x(bucket_gens_to_invalid_dev, 120) \ | |
| 127 | − x(bucket_gens_to_invalid_buckets, 121) \ | |
| 128 | − x(bucket_gens_nonzero_for_invalid_buckets, 122) \ | |
| 129 | − x(need_discard_freespace_key_to_invalid_dev_bucket, 123) \ | |
| 130 | − x(need_discard_freespace_key_bad, 124) \ | |
| 131 | − x(backpointer_bucket_offset_wrong, 125) \ | |
| 132 | − x(backpointer_to_missing_device, 126) \ | |
| 133 | − x(backpointer_to_missing_alloc, 127) \ | |
| 134 | − x(backpointer_to_missing_ptr, 128) \ | |
| 135 | − x(lru_entry_at_time_0, 129) \ | |
| 136 | − x(lru_entry_to_invalid_bucket, 130) \ | |
| 137 | − x(lru_entry_bad, 131) \ | |
| 138 | − x(btree_ptr_val_too_big, 132) \ | |
| 139 | − x(btree_ptr_v2_val_too_big, 133) \ | |
| 140 | − x(btree_ptr_has_non_ptr, 134) \ | |
| 141 | − x(extent_ptrs_invalid_entry, 135) \ | |
| 142 | − x(extent_ptrs_no_ptrs, 136) \ | |
| 143 | − x(extent_ptrs_too_many_ptrs, 137) \ | |
| 144 | − x(extent_ptrs_redundant_crc, 138) \ | |
| 145 | − x(extent_ptrs_redundant_stripe, 139) \ | |
| 146 | − x(extent_ptrs_unwritten, 140) \ | |
| 147 | − x(extent_ptrs_written_and_unwritten, 141) \ | |
| 148 | − x(ptr_to_invalid_device, 142) \ | |
| 149 | − x(ptr_to_duplicate_device, 143) \ | |
| 150 | − x(ptr_after_last_bucket, 144) \ | |
| 151 | − x(ptr_before_first_bucket, 145) \ | |
| 152 | − x(ptr_spans_multiple_buckets, 146) \ | |
| 153 | − x(ptr_to_missing_backpointer, 147) \ | |
| 154 | − x(ptr_to_missing_alloc_key, 148) \ | |
| 155 | − x(ptr_to_missing_replicas_entry, 149) \ | |
| 156 | − x(ptr_to_missing_stripe, 150) \ | |
| 157 | − x(ptr_to_incorrect_stripe, 151) \ | |
| 158 | − x(ptr_gen_newer_than_bucket_gen, 152) \ | |
| 159 | − x(ptr_too_stale, 153) \ | |
| 160 | − x(stale_dirty_ptr, 154) \ | |
| 161 | − x(ptr_bucket_data_type_mismatch, 155) \ | |
| 162 | − x(ptr_cached_and_erasure_coded, 156) \ | |
| 163 | − x(ptr_crc_uncompressed_size_too_small, 157) \ | |
| 164 | − x(ptr_crc_csum_type_unknown, 158) \ | |
| 165 | − x(ptr_crc_compression_type_unknown, 159) \ | |
| 166 | − x(ptr_crc_redundant, 160) \ | |
| 167 | − x(ptr_crc_uncompressed_size_too_big, 161) \ | |
| 168 | − x(ptr_crc_nonce_mismatch, 162) \ | |
| 169 | − x(ptr_stripe_redundant, 163) \ | |
| 170 | − x(reservation_key_nr_replicas_invalid, 164) \ | |
| 171 | − x(reflink_v_refcount_wrong, 165) \ | |
| 172 | − x(reflink_p_to_missing_reflink_v, 166) \ | |
| 173 | − x(stripe_pos_bad, 167) \ | |
| 174 | − x(stripe_val_size_bad, 168) \ | |
| 175 | − x(stripe_sector_count_wrong, 169) \ | |
| 176 | − x(snapshot_tree_pos_bad, 170) \ | |
| 177 | − x(snapshot_tree_to_missing_snapshot, 171) \ | |
| 178 | − x(snapshot_tree_to_missing_subvol, 172) \ | |
| 179 | − x(snapshot_tree_to_wrong_subvol, 173) \ | |
| 180 | − x(snapshot_tree_to_snapshot_subvol, 174) \ | |
| 181 | − x(snapshot_pos_bad, 175) \ | |
| 182 | − x(snapshot_parent_bad, 176) \ | |
| 183 | − x(snapshot_children_not_normalized, 177) \ | |
| 184 | − x(snapshot_child_duplicate, 178) \ | |
| 185 | − x(snapshot_child_bad, 179) \ | |
| 186 | − x(snapshot_skiplist_not_normalized, 180) \ | |
| 187 | − x(snapshot_skiplist_bad, 181) \ | |
| 188 | − x(snapshot_should_not_have_subvol, 182) \ | |
| 189 | − x(snapshot_to_bad_snapshot_tree, 183) \ | |
| 190 | − x(snapshot_bad_depth, 184) \ | |
| 191 | − x(snapshot_bad_skiplist, 185) \ | |
| 192 | − x(subvol_pos_bad, 186) \ | |
| 193 | − x(subvol_not_master_and_not_snapshot, 187) \ | |
| 194 | − x(subvol_to_missing_root, 188) \ | |
| 195 | − x(subvol_root_wrong_bi_subvol, 189) \ | |
| 196 | − x(bkey_in_missing_snapshot, 190) \ | |
| 197 | − x(inode_pos_inode_nonzero, 191) \ | |
| 198 | − x(inode_pos_blockdev_range, 192) \ | |
| 199 | − x(inode_unpack_error, 193) \ | |
| 200 | − x(inode_str_hash_invalid, 194) \ | |
| 201 | − x(inode_v3_fields_start_bad, 195) \ | |
| 202 | − x(inode_snapshot_mismatch, 196) \ | |
| 203 | − x(inode_unlinked_but_clean, 197) \ | |
| 204 | − x(inode_unlinked_but_nlink_nonzero, 198) \ | |
| 205 | − x(inode_checksum_type_invalid, 199) \ | |
| 206 | − x(inode_compression_type_invalid, 200) \ | |
| 207 | − x(inode_subvol_root_but_not_dir, 201) \ | |
| 208 | − x(inode_i_size_dirty_but_clean, 202) \ | |
| 209 | − x(inode_i_sectors_dirty_but_clean, 203) \ | |
| 210 | − x(inode_i_sectors_wrong, 204) \ | |
| 211 | − x(inode_dir_wrong_nlink, 205) \ | |
| 212 | − x(inode_dir_multiple_links, 206) \ | |
| 213 | − x(inode_multiple_links_but_nlink_0, 207) \ | |
| 214 | − x(inode_wrong_backpointer, 208) \ | |
| 215 | − x(inode_wrong_nlink, 209) \ | |
| 216 | − x(inode_unreachable, 210) \ | |
| 217 | − x(deleted_inode_but_clean, 211) \ | |
| 218 | − x(deleted_inode_missing, 212) \ | |
| 219 | − x(deleted_inode_is_dir, 213) \ | |
| 220 | − x(deleted_inode_not_unlinked, 214) \ | |
| 221 | − x(extent_overlapping, 215) \ | |
| 222 | − x(extent_in_missing_inode, 216) \ | |
| 223 | − x(extent_in_non_reg_inode, 217) \ | |
| 224 | − x(extent_past_end_of_inode, 218) \ | |
| 225 | − x(dirent_empty_name, 219) \ | |
| 226 | − x(dirent_val_too_big, 220) \ | |
| 227 | − x(dirent_name_too_long, 221) \ | |
| 228 | − x(dirent_name_embedded_nul, 222) \ | |
| 229 | − x(dirent_name_dot_or_dotdot, 223) \ | |
| 230 | − x(dirent_name_has_slash, 224) \ | |
| 231 | − x(dirent_d_type_wrong, 225) \ | |
| 232 | − x(inode_bi_parent_wrong, 226) \ | |
| 233 | − x(dirent_in_missing_dir_inode, 227) \ | |
| 234 | − x(dirent_in_non_dir_inode, 228) \ | |
| 235 | − x(dirent_to_missing_inode, 229) \ | |
| 236 | − x(dirent_to_missing_subvol, 230) \ | |
| 237 | − x(dirent_to_itself, 231) \ | |
| 238 | − x(quota_type_invalid, 232) \ | |
| 239 | − x(xattr_val_size_too_small, 233) \ | |
| 240 | − x(xattr_val_size_too_big, 234) \ | |
| 241 | − x(xattr_invalid_type, 235) \ | |
| 242 | − x(xattr_name_invalid_chars, 236) \ | |
| 243 | − x(xattr_in_missing_inode, 237) \ | |
| 244 | − x(root_subvol_missing, 238) \ | |
| 245 | − x(root_dir_missing, 239) \ | |
| 246 | − x(root_inode_not_dir, 240) \ | |
| 247 | − x(dir_loop, 241) \ | |
| 248 | − x(hash_table_key_duplicate, 242) \ | |
| 249 | − x(hash_table_key_wrong_offset, 243) \ | |
| 250 | − x(unlinked_inode_not_on_deleted_list, 244) \ | |
| 251 | − x(reflink_p_front_pad_bad, 245) \ | |
| 252 | − x(journal_entry_dup_same_device, 246) \ | |
| 253 | − x(inode_bi_subvol_missing, 247) \ | |
| 254 | − x(inode_bi_subvol_wrong, 248) \ | |
| 255 | − x(inode_points_to_missing_dirent, 249) \ | |
| 256 | − x(inode_points_to_wrong_dirent, 250) \ | |
| 257 | − x(inode_bi_parent_nonzero, 251) \ | |
| 258 | − x(dirent_to_missing_parent_subvol, 252) \ | |
| 259 | − x(dirent_not_visible_in_parent_subvol, 253) \ | |
| 260 | − x(subvol_fs_path_parent_wrong, 254) \ | |
| 261 | − x(subvol_root_fs_path_parent_nonzero, 255) \ | |
| 262 | − x(subvol_children_not_set, 256) \ | |
| 263 | − x(subvol_children_bad, 257) \ | |
| 264 | − x(subvol_loop, 258) \ | |
| 265 | − x(subvol_unreachable, 259) \ | |
| 266 | − x(btree_node_bkey_bad_u64s, 260) \ | |
| 267 | − x(btree_node_topology_empty_interior_node, 261) \ | |
| 268 | − x(btree_ptr_v2_min_key_bad, 262) \ | |
| 269 | − x(btree_root_unreadable_and_scan_found_nothing, 263) \ | |
| 270 | − x(snapshot_node_missing, 264) \ | |
| 271 | − x(dup_backpointer_to_bad_csum_extent, 265) \ | |
| 272 | − x(btree_bitmap_not_marked, 266) \ | |
| 273 | − x(sb_clean_entry_overrun, 267) \ | |
| 274 | − x(btree_ptr_v2_written_0, 268) \ | |
| 275 | − x(subvol_snapshot_bad, 269) \ | |
| 276 | − x(subvol_inode_bad, 270) | |
| 5 | +enum bch_fsck_flags { | |
| 6 | + FSCK_CAN_FIX = 1 << 0, | |
| 7 | + FSCK_CAN_IGNORE = 1 << 1, | |
| 8 | + FSCK_NEED_FSCK = 1 << 2, | |
| 9 | + FSCK_NO_RATELIMIT = 1 << 3, | |
| 10 | + FSCK_AUTOFIX = 1 << 4, | |
| 11 | +}; | |
| 12 | + | |
| 13 | +#define BCH_SB_ERRS() \ | |
| 14 | + x(clean_but_journal_not_empty, 0, 0) \ | |
| 15 | + x(dirty_but_no_journal_entries, 1, 0) \ | |
| 16 | + x(dirty_but_no_journal_entries_post_drop_nonflushes, 2, 0) \ | |
| 17 | + x(sb_clean_journal_seq_mismatch, 3, 0) \ | |
| 18 | + x(sb_clean_btree_root_mismatch, 4, 0) \ | |
| 19 | + x(sb_clean_missing, 5, 0) \ | |
| 20 | + x(jset_unsupported_version, 6, 0) \ | |
| 21 | + x(jset_unknown_csum, 7, 0) \ | |
| 22 | + x(jset_last_seq_newer_than_seq, 8, 0) \ | |
| 23 | + x(jset_past_bucket_end, 9, 0) \ | |
| 24 | + x(jset_seq_blacklisted, 10, 0) \ | |
| 25 | + x(journal_entries_missing, 11, 0) \ | |
| 26 | + x(journal_entry_replicas_not_marked, 12, 0) \ | |
| 27 | + x(journal_entry_past_jset_end, 13, 0) \ | |
| 28 | + x(journal_entry_replicas_data_mismatch, 14, 0) \ | |
| 29 | + x(journal_entry_bkey_u64s_0, 15, 0) \ | |
| 30 | + x(journal_entry_bkey_past_end, 16, 0) \ | |
| 31 | + x(journal_entry_bkey_bad_format, 17, 0) \ | |
| 32 | + x(journal_entry_bkey_invalid, 18, 0) \ | |
| 33 | + x(journal_entry_btree_root_bad_size, 19, 0) \ | |
| 34 | + x(journal_entry_blacklist_bad_size, 20, 0) \ | |
| 35 | + x(journal_entry_blacklist_v2_bad_size, 21, 0) \ | |
| 36 | + x(journal_entry_blacklist_v2_start_past_end, 22, 0) \ | |
| 37 | + x(journal_entry_usage_bad_size, 23, 0) \ | |
| 38 | + x(journal_entry_data_usage_bad_size, 24, 0) \ | |
| 39 | + x(journal_entry_clock_bad_size, 25, 0) \ | |
| 40 | + x(journal_entry_clock_bad_rw, 26, 0) \ | |
| 41 | + x(journal_entry_dev_usage_bad_size, 27, 0) \ | |
| 42 | + x(journal_entry_dev_usage_bad_dev, 28, 0) \ | |
| 43 | + x(journal_entry_dev_usage_bad_pad, 29, 0) \ | |
| 44 | + x(btree_node_unreadable, 30, 0) \ | |
| 45 | + x(btree_node_fault_injected, 31, 0) \ | |
| 46 | + x(btree_node_bad_magic, 32, 0) \ | |
| 47 | + x(btree_node_bad_seq, 33, 0) \ | |
| 48 | + x(btree_node_unsupported_version, 34, 0) \ | |
| 49 | + x(btree_node_bset_older_than_sb_min, 35, 0) \ | |
| 50 | + x(btree_node_bset_newer_than_sb, 36, 0) \ | |
| 51 | + x(btree_node_data_missing, 37, 0) \ | |
| 52 | + x(btree_node_bset_after_end, 38, 0) \ | |
| 53 | + x(btree_node_replicas_sectors_written_mismatch, 39, 0) \ | |
| 54 | + x(btree_node_replicas_data_mismatch, 40, 0) \ | |
| 55 | + x(bset_unknown_csum, 41, 0) \ | |
| 56 | + x(bset_bad_csum, 42, 0) \ | |
| 57 | + x(bset_past_end_of_btree_node, 43, 0) \ | |
| 58 | + x(bset_wrong_sector_offset, 44, 0) \ | |
| 59 | + x(bset_empty, 45, 0) \ | |
| 60 | + x(bset_bad_seq, 46, 0) \ | |
| 61 | + x(bset_blacklisted_journal_seq, 47, 0) \ | |
| 62 | + x(first_bset_blacklisted_journal_seq, 48, 0) \ | |
| 63 | + x(btree_node_bad_btree, 49, 0) \ | |
| 64 | + x(btree_node_bad_level, 50, 0) \ | |
| 65 | + x(btree_node_bad_min_key, 51, 0) \ | |
| 66 | + x(btree_node_bad_max_key, 52, 0) \ | |
| 67 | + x(btree_node_bad_format, 53, 0) \ | |
| 68 | + x(btree_node_bkey_past_bset_end, 54, 0) \ | |
| 69 | + x(btree_node_bkey_bad_format, 55, 0) \ | |
| 70 | + x(btree_node_bad_bkey, 56, 0) \ | |
| 71 | + x(btree_node_bkey_out_of_order, 57, 0) \ | |
| 72 | + x(btree_root_bkey_invalid, 58, 0) \ | |
| 73 | + x(btree_root_read_error, 59, 0) \ | |
| 74 | + x(btree_root_bad_min_key, 60, 0) \ | |
| 75 | + x(btree_root_bad_max_key, 61, 0) \ | |
| 76 | + x(btree_node_read_error, 62, 0) \ | |
| 77 | + x(btree_node_topology_bad_min_key, 63, 0) \ | |
| 78 | + x(btree_node_topology_bad_max_key, 64, 0) \ | |
| 79 | + x(btree_node_topology_overwritten_by_prev_node, 65, 0) \ | |
| 80 | + x(btree_node_topology_overwritten_by_next_node, 66, 0) \ | |
| 81 | + x(btree_node_topology_interior_node_empty, 67, 0) \ | |
| 82 | + x(fs_usage_hidden_wrong, 68, FSCK_AUTOFIX) \ | |
| 83 | + x(fs_usage_btree_wrong, 69, FSCK_AUTOFIX) \ | |
| 84 | + x(fs_usage_data_wrong, 70, FSCK_AUTOFIX) \ | |
| 85 | + x(fs_usage_cached_wrong, 71, FSCK_AUTOFIX) \ | |
| 86 | + x(fs_usage_reserved_wrong, 72, FSCK_AUTOFIX) \ | |
| 87 | + x(fs_usage_persistent_reserved_wrong, 73, FSCK_AUTOFIX) \ | |
| 88 | + x(fs_usage_nr_inodes_wrong, 74, FSCK_AUTOFIX) \ | |
| 89 | + x(fs_usage_replicas_wrong, 75, FSCK_AUTOFIX) \ | |
| 90 | + x(dev_usage_buckets_wrong, 76, FSCK_AUTOFIX) \ | |
| 91 | + x(dev_usage_sectors_wrong, 77, FSCK_AUTOFIX) \ | |
| 92 | + x(dev_usage_fragmented_wrong, 78, FSCK_AUTOFIX) \ | |
| 93 | + x(dev_usage_buckets_ec_wrong, 79, FSCK_AUTOFIX) \ | |
| 94 | + x(bkey_version_in_future, 80, 0) \ | |
| 95 | + x(bkey_u64s_too_small, 81, 0) \ | |
| 96 | + x(bkey_invalid_type_for_btree, 82, 0) \ | |
| 97 | + x(bkey_extent_size_zero, 83, 0) \ | |
| 98 | + x(bkey_extent_size_greater_than_offset, 84, 0) \ | |
| 99 | + x(bkey_size_nonzero, 85, 0) \ | |
| 100 | + x(bkey_snapshot_nonzero, 86, 0) \ | |
| 101 | + x(bkey_snapshot_zero, 87, 0) \ | |
| 102 | + x(bkey_at_pos_max, 88, 0) \ | |
| 103 | + x(bkey_before_start_of_btree_node, 89, 0) \ | |
| 104 | + x(bkey_after_end_of_btree_node, 90, 0) \ | |
| 105 | + x(bkey_val_size_nonzero, 91, 0) \ | |
| 106 | + x(bkey_val_size_too_small, 92, 0) \ | |
| 107 | + x(alloc_v1_val_size_bad, 93, 0) \ | |
| 108 | + x(alloc_v2_unpack_error, 94, 0) \ | |
| 109 | + x(alloc_v3_unpack_error, 95, 0) \ | |
| 110 | + x(alloc_v4_val_size_bad, 96, 0) \ | |
| 111 | + x(alloc_v4_backpointers_start_bad, 97, 0) \ | |
| 112 | + x(alloc_key_data_type_bad, 98, 0) \ | |
| 113 | + x(alloc_key_empty_but_have_data, 99, 0) \ | |
| 114 | + x(alloc_key_dirty_sectors_0, 100, 0) \ | |
| 115 | + x(alloc_key_data_type_inconsistency, 101, 0) \ | |
| 116 | + x(alloc_key_to_missing_dev_bucket, 102, 0) \ | |
| 117 | + x(alloc_key_cached_inconsistency, 103, 0) \ | |
| 118 | + x(alloc_key_cached_but_read_time_zero, 104, 0) \ | |
| 119 | + x(alloc_key_to_missing_lru_entry, 105, 0) \ | |
| 120 | + x(alloc_key_data_type_wrong, 106, FSCK_AUTOFIX) \ | |
| 121 | + x(alloc_key_gen_wrong, 107, FSCK_AUTOFIX) \ | |
| 122 | + x(alloc_key_dirty_sectors_wrong, 108, FSCK_AUTOFIX) \ | |
| 123 | + x(alloc_key_cached_sectors_wrong, 109, FSCK_AUTOFIX) \ | |
| 124 | + x(alloc_key_stripe_wrong, 110, FSCK_AUTOFIX) \ | |
| 125 | + x(alloc_key_stripe_redundancy_wrong, 111, FSCK_AUTOFIX) \ | |
| 126 | + x(bucket_sector_count_overflow, 112, 0) \ | |
| 127 | + x(bucket_metadata_type_mismatch, 113, 0) \ | |
| 128 | + x(need_discard_key_wrong, 114, 0) \ | |
| 129 | + x(freespace_key_wrong, 115, 0) \ | |
| 130 | + x(freespace_hole_missing, 116, 0) \ | |
| 131 | + x(bucket_gens_val_size_bad, 117, 0) \ | |
| 132 | + x(bucket_gens_key_wrong, 118, 0) \ | |
| 133 | + x(bucket_gens_hole_wrong, 119, 0) \ | |
| 134 | + x(bucket_gens_to_invalid_dev, 120, 0) \ | |
| 135 | + x(bucket_gens_to_invalid_buckets, 121, 0) \ | |
| 136 | + x(bucket_gens_nonzero_for_invalid_buckets, 122, 0) \ | |
| 137 | + x(need_discard_freespace_key_to_invalid_dev_bucket, 123, 0) \ | |
| 138 | + x(need_discard_freespace_key_bad, 124, 0) \ | |
| 139 | + x(backpointer_bucket_offset_wrong, 125, 0) \ | |
| 140 | + x(backpointer_to_missing_device, 126, 0) \ | |
| 141 | + x(backpointer_to_missing_alloc, 127, 0) \ | |
| 142 | + x(backpointer_to_missing_ptr, 128, 0) \ | |
| 143 | + x(lru_entry_at_time_0, 129, 0) \ | |
| 144 | + x(lru_entry_to_invalid_bucket, 130, 0) \ | |
| 145 | + x(lru_entry_bad, 131, 0) \ | |
| 146 | + x(btree_ptr_val_too_big, 132, 0) \ | |
| 147 | + x(btree_ptr_v2_val_too_big, 133, 0) \ | |
| 148 | + x(btree_ptr_has_non_ptr, 134, 0) \ | |
| 149 | + x(extent_ptrs_invalid_entry, 135, 0) \ | |
| 150 | + x(extent_ptrs_no_ptrs, 136, 0) \ | |
| 151 | + x(extent_ptrs_too_many_ptrs, 137, 0) \ | |
| 152 | + x(extent_ptrs_redundant_crc, 138, 0) \ | |
| 153 | + x(extent_ptrs_redundant_stripe, 139, 0) \ | |
| 154 | + x(extent_ptrs_unwritten, 140, 0) \ | |
| 155 | + x(extent_ptrs_written_and_unwritten, 141, 0) \ | |
| 156 | + x(ptr_to_invalid_device, 142, 0) \ | |
| 157 | + x(ptr_to_duplicate_device, 143, 0) \ | |
| 158 | + x(ptr_after_last_bucket, 144, 0) \ | |
| 159 | + x(ptr_before_first_bucket, 145, 0) \ | |
| 160 | + x(ptr_spans_multiple_buckets, 146, 0) \ | |
| 161 | + x(ptr_to_missing_backpointer, 147, 0) \ | |
| 162 | + x(ptr_to_missing_alloc_key, 148, 0) \ | |
| 163 | + x(ptr_to_missing_replicas_entry, 149, 0) \ | |
| 164 | + x(ptr_to_missing_stripe, 150, 0) \ | |
| 165 | + x(ptr_to_incorrect_stripe, 151, 0) \ | |
| 166 | + x(ptr_gen_newer_than_bucket_gen, 152, 0) \ | |
| 167 | + x(ptr_too_stale, 153, 0) \ | |
| 168 | + x(stale_dirty_ptr, 154, 0) \ | |
| 169 | + x(ptr_bucket_data_type_mismatch, 155, 0) \ | |
| 170 | + x(ptr_cached_and_erasure_coded, 156, 0) \ | |
| 171 | + x(ptr_crc_uncompressed_size_too_small, 157, 0) \ | |
| 172 | + x(ptr_crc_csum_type_unknown, 158, 0) \ | |
| 173 | + x(ptr_crc_compression_type_unknown, 159, 0) \ | |
| 174 | + x(ptr_crc_redundant, 160, 0) \ | |
| 175 | + x(ptr_crc_uncompressed_size_too_big, 161, 0) \ | |
| 176 | + x(ptr_crc_nonce_mismatch, 162, 0) \ | |
| 177 | + x(ptr_stripe_redundant, 163, 0) \ | |
| 178 | + x(reservation_key_nr_replicas_invalid, 164, 0) \ | |
| 179 | + x(reflink_v_refcount_wrong, 165, 0) \ | |
| 180 | + x(reflink_p_to_missing_reflink_v, 166, 0) \ | |
| 181 | + x(stripe_pos_bad, 167, 0) \ | |
| 182 | + x(stripe_val_size_bad, 168, 0) \ | |
| 183 | + x(stripe_sector_count_wrong, 169, 0) \ | |
| 184 | + x(snapshot_tree_pos_bad, 170, 0) \ | |
| 185 | + x(snapshot_tree_to_missing_snapshot, 171, 0) \ | |
| 186 | + x(snapshot_tree_to_missing_subvol, 172, 0) \ | |
| 187 | + x(snapshot_tree_to_wrong_subvol, 173, 0) \ | |
| 188 | + x(snapshot_tree_to_snapshot_subvol, 174, 0) \ | |
| 189 | + x(snapshot_pos_bad, 175, 0) \ | |
| 190 | + x(snapshot_parent_bad, 176, 0) \ | |
| 191 | + x(snapshot_children_not_normalized, 177, 0) \ | |
| 192 | + x(snapshot_child_duplicate, 178, 0) \ | |
| 193 | + x(snapshot_child_bad, 179, 0) \ | |
| 194 | + x(snapshot_skiplist_not_normalized, 180, 0) \ | |
| 195 | + x(snapshot_skiplist_bad, 181, 0) \ | |
| 196 | + x(snapshot_should_not_have_subvol, 182, 0) \ | |
| 197 | + x(snapshot_to_bad_snapshot_tree, 183, 0) \ | |
| 198 | + x(snapshot_bad_depth, 184, 0) \ | |
| 199 | + x(snapshot_bad_skiplist, 185, 0) \ | |
| 200 | + x(subvol_pos_bad, 186, 0) \ | |
| 201 | + x(subvol_not_master_and_not_snapshot, 187, 0) \ | |
| 202 | + x(subvol_to_missing_root, 188, 0) \ | |
| 203 | + x(subvol_root_wrong_bi_subvol, 189, 0) \ | |
| 204 | + x(bkey_in_missing_snapshot, 190, 0) \ | |
| 205 | + x(inode_pos_inode_nonzero, 191, 0) \ | |
| 206 | + x(inode_pos_blockdev_range, 192, 0) \ | |
| 207 | + x(inode_unpack_error, 193, 0) \ | |
| 208 | + x(inode_str_hash_invalid, 194, 0) \ | |
| 209 | + x(inode_v3_fields_start_bad, 195, 0) \ | |
| 210 | + x(inode_snapshot_mismatch, 196, 0) \ | |
| 211 | + x(inode_unlinked_but_clean, 197, 0) \ | |
| 212 | + x(inode_unlinked_but_nlink_nonzero, 198, 0) \ | |
| 213 | + x(inode_checksum_type_invalid, 199, 0) \ | |
| 214 | + x(inode_compression_type_invalid, 200, 0) \ | |
| 215 | + x(inode_subvol_root_but_not_dir, 201, 0) \ | |
| 216 | + x(inode_i_size_dirty_but_clean, 202, 0) \ | |
| 217 | + x(inode_i_sectors_dirty_but_clean, 203, 0) \ | |
| 218 | + x(inode_i_sectors_wrong, 204, 0) \ | |
| 219 | + x(inode_dir_wrong_nlink, 205, 0) \ | |
| 220 | + x(inode_dir_multiple_links, 206, 0) \ | |
| 221 | + x(inode_multiple_links_but_nlink_0, 207, 0) \ | |
| 222 | + x(inode_wrong_backpointer, 208, 0) \ | |
| 223 | + x(inode_wrong_nlink, 209, 0) \ | |
| 224 | + x(inode_unreachable, 210, 0) \ | |
| 225 | + x(deleted_inode_but_clean, 211, 0) \ | |
| 226 | + x(deleted_inode_missing, 212, 0) \ | |
| 227 | + x(deleted_inode_is_dir, 213, 0) \ | |
| 228 | + x(deleted_inode_not_unlinked, 214, 0) \ | |
| 229 | + x(extent_overlapping, 215, 0) \ | |
| 230 | + x(extent_in_missing_inode, 216, 0) \ | |
| 231 | + x(extent_in_non_reg_inode, 217, 0) \ | |
| 232 | + x(extent_past_end_of_inode, 218, 0) \ | |
| 233 | + x(dirent_empty_name, 219, 0) \ | |
| 234 | + x(dirent_val_too_big, 220, 0) \ | |
| 235 | + x(dirent_name_too_long, 221, 0) \ | |
| 236 | + x(dirent_name_embedded_nul, 222, 0) \ | |
| 237 | + x(dirent_name_dot_or_dotdot, 223, 0) \ | |
| 238 | + x(dirent_name_has_slash, 224, 0) \ | |
| 239 | + x(dirent_d_type_wrong, 225, 0) \ | |
| 240 | + x(inode_bi_parent_wrong, 226, 0) \ | |
| 241 | + x(dirent_in_missing_dir_inode, 227, 0) \ | |
| 242 | + x(dirent_in_non_dir_inode, 228, 0) \ | |
| 243 | + x(dirent_to_missing_inode, 229, 0) \ | |
| 244 | + x(dirent_to_missing_subvol, 230, 0) \ | |
| 245 | + x(dirent_to_itself, 231, 0) \ | |
| 246 | + x(quota_type_invalid, 232, 0) \ | |
| 247 | + x(xattr_val_size_too_small, 233, 0) \ | |
| 248 | + x(xattr_val_size_too_big, 234, 0) \ | |
| 249 | + x(xattr_invalid_type, 235, 0) \ | |
| 250 | + x(xattr_name_invalid_chars, 236, 0) \ | |
| 251 | + x(xattr_in_missing_inode, 237, 0) \ | |
| 252 | + x(root_subvol_missing, 238, 0) \ | |
| 253 | + x(root_dir_missing, 239, 0) \ | |
| 254 | + x(root_inode_not_dir, 240, 0) \ | |
| 255 | + x(dir_loop, 241, 0) \ | |
| 256 | + x(hash_table_key_duplicate, 242, 0) \ | |
| 257 | + x(hash_table_key_wrong_offset, 243, 0) \ | |
| 258 | + x(unlinked_inode_not_on_deleted_list, 244, 0) \ | |
| 259 | + x(reflink_p_front_pad_bad, 245, 0) \ | |
| 260 | + x(journal_entry_dup_same_device, 246, 0) \ | |
| 261 | + x(inode_bi_subvol_missing, 247, 0) \ | |
| 262 | + x(inode_bi_subvol_wrong, 248, 0) \ | |
| 263 | + x(inode_points_to_missing_dirent, 249, 0) \ | |
| 264 | + x(inode_points_to_wrong_dirent, 250, 0) \ | |
| 265 | + x(inode_bi_parent_nonzero, 251, 0) \ | |
| 266 | + x(dirent_to_missing_parent_subvol, 252, 0) \ | |
| 267 | + x(dirent_not_visible_in_parent_subvol, 253, 0) \ | |
| 268 | + x(subvol_fs_path_parent_wrong, 254, 0) \ | |
| 269 | + x(subvol_root_fs_path_parent_nonzero, 255, 0) \ | |
| 270 | + x(subvol_children_not_set, 256, 0) \ | |
| 271 | + x(subvol_children_bad, 257, 0) \ | |
| 272 | + x(subvol_loop, 258, 0) \ | |
| 273 | + x(subvol_unreachable, 259, 0) \ | |
| 274 | + x(btree_node_bkey_bad_u64s, 260, 0) \ | |
| 275 | + x(btree_node_topology_empty_interior_node, 261, 0) \ | |
| 276 | + x(btree_ptr_v2_min_key_bad, 262, 0) \ | |
| 277 | + x(btree_root_unreadable_and_scan_found_nothing, 263, 0) \ | |
| 278 | + x(snapshot_node_missing, 264, 0) \ | |
| 279 | + x(dup_backpointer_to_bad_csum_extent, 265, 0) \ | |
| 280 | + x(btree_bitmap_not_marked, 266, 0) \ | |
| 281 | + x(sb_clean_entry_overrun, 267, 0) \ | |
| 282 | + x(btree_ptr_v2_written_0, 268, 0) \ | |
| 283 | + x(subvol_snapshot_bad, 269, 0) \ | |
| 284 | + x(subvol_inode_bad, 270, 0) \ | |
| 285 | + x(alloc_key_stripe_sectors_wrong, 271, 0) \ | |
| 286 | + x(accounting_mismatch, 272, 0) \ | |
| 287 | + x(accounting_replicas_not_marked, 273, 0) \ | |
| 288 | + x(invalid_btree_id, 274, 0) \ | |
| 289 | + x(alloc_key_io_time_bad, 275, 0) | |
| 277 | 290 | |
| 278 | 291 | enum bch_sb_error_id { |
| 279 | −#define x(t, n) BCH_FSCK_ERR_##t = n, | |
| 292 | +#define x(t, n, ...) BCH_FSCK_ERR_##t = n, | |
| 280 | 293 | BCH_SB_ERRS() |
| 281 | 294 | #undef x |
| 282 | 295 | BCH_SB_ERR_MAX |
| @@ -1565,13 +1565,6 @@ int bch2_delete_dead_snapshots(struct bch_fs *c) · 1564 unmodified lines | ||
| 1565 | 1565 | if (!test_and_clear_bit(BCH_FS_need_delete_dead_snapshots, &c->flags)) |
| 1566 | 1566 | return 0; |
| 1567 | 1567 | |
| 1568 | − if (!test_bit(BCH_FS_started, &c->flags)) { | |
| 1569 | − ret = bch2_fs_read_write_early(c); | |
| 1570 | − bch_err_msg(c, ret, "deleting dead snapshots: error going rw"); | |
| 1571 | − if (ret) | |
| 1572 | − return ret; | |
| 1573 | − } | |
| 1574 | − | |
| 1575 | 1568 | trans = bch2_trans_get(c); |
| 1576 | 1569 | |
| 1577 | 1570 | /* |
| @@ -1687,6 +1680,8 @@ void bch2_delete_dead_snapshots_work(struct work_struct *work) · 109 unmodified lines | ||
| 1687 | 1680 | { |
| 1688 | 1681 | struct bch_fs *c = container_of(work, struct bch_fs, snapshot_delete_work); |
| 1689 | 1682 | |
| 1683 | + set_worker_desc("bcachefs-delete-dead-snapshots/%s", c->name); | |
| 1684 | + | |
| 1690 | 1685 | bch2_delete_dead_snapshots(c); |
| 1691 | 1686 | bch2_write_ref_put(c, BCH_WRITE_REF_delete_dead_snapshots); |
| 1692 | 1687 | } |
| @@ -300,7 +300,7 @@ not_found: · 299 unmodified lines | ||
| 300 | 300 | if (!found && (flags & STR_HASH_must_replace)) { |
| 301 | 301 | ret = -BCH_ERR_ENOENT_str_hash_set_must_replace; |
| 302 | 302 | } else if (found && (flags & STR_HASH_must_create)) { |
| 303 | − ret = -EEXIST; | |
| 303 | + ret = -BCH_ERR_EEXIST_str_hash_set; | |
| 304 | 304 | } else { |
| 305 | 305 | if (!found && slot.path) |
| 306 | 306 | swap(iter, slot); |
| @@ -649,9 +649,10 @@ reread: · 648 unmodified lines | ||
| 649 | 649 | |
| 650 | 650 | bytes = vstruct_bytes(sb->sb); |
| 651 | 651 | |
| 652 | − if (bytes > 512ULL << min(BCH_SB_LAYOUT_SIZE_BITS_MAX, sb->sb->layout.sb_max_size_bits)) { | |
| 653 | − prt_printf(err, "Invalid superblock: too big (got %zu bytes, layout max %lu)", | |
| 654 | − bytes, 512UL << sb->sb->layout.sb_max_size_bits); | |
| 652 | + u64 sb_size = 512ULL << min(BCH_SB_LAYOUT_SIZE_BITS_MAX, sb->sb->layout.sb_max_size_bits); | |
| 653 | + if (bytes > sb_size) { | |
| 654 | + prt_printf(err, "Invalid superblock: too big (got %zu bytes, layout max %llu)", | |
| 655 | + bytes, sb_size); | |
| 655 | 656 | return -BCH_ERR_invalid_sb_too_big; |
| 656 | 657 | } |
| 657 | 658 | |
| @@ -912,9 +912,9 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) · 911 unmodified lines | ||
| 912 | 912 | bch2_io_clock_init(&c->io_clock[WRITE]) ?: |
| 913 | 913 | bch2_fs_journal_init(&c->journal) ?: |
| 914 | 914 | bch2_fs_replicas_init(c) ?: |
| 915 | + bch2_fs_btree_iter_init(c) ?: | |
| 915 | 916 | bch2_fs_btree_cache_init(c) ?: |
| 916 | 917 | bch2_fs_btree_key_cache_init(&c->btree_key_cache) ?: |
| 917 | − bch2_fs_btree_iter_init(c) ?: | |
| 918 | 918 | bch2_fs_btree_interior_update_init(c) ?: |
| 919 | 919 | bch2_fs_buckets_waiting_for_journal_init(c) ?: |
| 920 | 920 | bch2_fs_btree_write_buffer_init(c) ?: |
| @@ -931,12 +931,13 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) · 10 unmodified lines | ||
| 931 | 931 | if (ret) |
| 932 | 932 | goto err; |
| 933 | 933 | |
| 934 | − for (i = 0; i < c->sb.nr_devices; i++) | |
| 935 | − if (bch2_member_exists(c->disk_sb.sb, i) && | |
| 936 | − bch2_dev_alloc(c, i)) { | |
| 937 | − ret = -EEXIST; | |
| 934 | + for (i = 0; i < c->sb.nr_devices; i++) { | |
| 935 | + if (!bch2_member_exists(c->disk_sb.sb, i)) | |
| 936 | + continue; | |
| 937 | + ret = bch2_dev_alloc(c, i); | |
| 938 | + if (ret) | |
| 938 | 939 | goto err; |
| 939 | − } | |
| 940 | + } | |
| 940 | 941 | |
| 941 | 942 | bch2_journal_entry_res_resize(&c->journal, |
| 942 | 943 | &c->btree_root_journal_res, |
| @@ -741,7 +741,9 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num) · 740 unmodified lines | ||
| 741 | 741 | ret = btrfs_bio_csum(bbio); |
| 742 | 742 | if (ret) |
| 743 | 743 | goto fail_put_bio; |
| 744 | − } else if (use_append) { | |
| 744 | + } else if (use_append || | |
| 745 | + (btrfs_is_zoned(fs_info) && inode && | |
| 746 | + inode->flags & BTRFS_INODE_NODATASUM)) { | |
| 745 | 747 | ret = btrfs_alloc_dummy_sum(bbio); |
| 746 | 748 | if (ret) |
| 747 | 749 | goto fail_put_bio; |
| @@ -1785,6 +1785,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) · 1784 unmodified lines | ||
| 1785 | 1785 | container_of(work, struct btrfs_fs_info, reclaim_bgs_work); |
| 1786 | 1786 | struct btrfs_block_group *bg; |
| 1787 | 1787 | struct btrfs_space_info *space_info; |
| 1788 | + LIST_HEAD(retry_list); | |
| 1788 | 1789 | |
| 1789 | 1790 | if (!test_bit(BTRFS_FS_OPEN, &fs_info->flags)) |
| 1790 | 1791 | return; |
| @@ -1921,8 +1922,11 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) · 130 unmodified lines | ||
| 1921 | 1922 | } |
| 1922 | 1923 | |
| 1923 | 1924 | next: |
| 1924 | − if (ret) | |
| 1925 | − btrfs_mark_bg_to_reclaim(bg); | |
| 1925 | + if (ret) { | |
| 1926 | + /* Refcount held by the reclaim_bgs list after splice. */ | |
| 1927 | + btrfs_get_block_group(bg); | |
| 1928 | + list_add_tail(&bg->bg_list, &retry_list); | |
| 1929 | + } | |
| 1926 | 1930 | btrfs_put_block_group(bg); |
| 1927 | 1931 | |
| 1928 | 1932 | mutex_unlock(&fs_info->reclaim_bgs_lock); |
| @@ -1942,6 +1946,9 @@ next: · 13 unmodified lines | ||
| 1942 | 1946 | spin_unlock(&fs_info->unused_bgs_lock); |
| 1943 | 1947 | mutex_unlock(&fs_info->reclaim_bgs_lock); |
| 1944 | 1948 | end: |
| 1949 | + spin_lock(&fs_info->unused_bgs_lock); | |
| 1950 | + list_splice_tail(&retry_list, &fs_info->reclaim_bgs); | |
| 1951 | + spin_unlock(&fs_info->unused_bgs_lock); | |
| 1945 | 1952 | btrfs_exclop_finish(fs_info); |
| 1946 | 1953 | sb_end_write(fs_info->sb); |
| 1947 | 1954 | } |
| @@ -44,9 +44,7 @@ static const struct nla_policy nfsd_listener_set_nl_policy[NFSD_A_SERVER_SOCK_AD · 43 unmodified lines | ||
| 44 | 44 | static const struct genl_split_ops nfsd_nl_ops[] = { |
| 45 | 45 | { |
| 46 | 46 | .cmd = NFSD_CMD_RPC_STATUS_GET, |
| 47 | − .start = nfsd_nl_rpc_status_get_start, | |
| 48 | 47 | .dumpit = nfsd_nl_rpc_status_get_dumpit, |
| 49 | − .done = nfsd_nl_rpc_status_get_done, | |
| 50 | 48 | .flags = GENL_CMD_CAP_DUMP, |
| 51 | 49 | }, |
| 52 | 50 | { |
| @@ -15,9 +15,6 @@ · 14 unmodified lines | ||
| 15 | 15 | extern const struct nla_policy nfsd_sock_nl_policy[NFSD_A_SOCK_TRANSPORT_NAME + 1]; |
| 16 | 16 | extern const struct nla_policy nfsd_version_nl_policy[NFSD_A_VERSION_ENABLED + 1]; |
| 17 | 17 | |
| 18 | −int nfsd_nl_rpc_status_get_start(struct netlink_callback *cb); | |
| 19 | −int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb); | |
| 20 | − | |
| 21 | 18 | int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb, |
| 22 | 19 | struct netlink_callback *cb); |
| 23 | 20 | int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info); |
| @@ -1460,28 +1460,6 @@ static int create_proc_exports_entry(void) · 1459 unmodified lines | ||
| 1460 | 1460 | |
| 1461 | 1461 | unsigned int nfsd_net_id; |
| 1462 | 1462 | |
| 1463 | −/** | |
| 1464 | − * nfsd_nl_rpc_status_get_start - Prepare rpc_status_get dumpit | |
| 1465 | − * @cb: netlink metadata and command arguments | |
| 1466 | − * | |
| 1467 | − * Return values: | |
| 1468 | − * %0: The rpc_status_get command may proceed | |
| 1469 | − * %-ENODEV: There is no NFSD running in this namespace | |
| 1470 | − */ | |
| 1471 | −int nfsd_nl_rpc_status_get_start(struct netlink_callback *cb) | |
| 1472 | −{ | |
| 1473 | − struct nfsd_net *nn = net_generic(sock_net(cb->skb->sk), nfsd_net_id); | |
| 1474 | − int ret = -ENODEV; | |
| 1475 | − | |
| 1476 | − mutex_lock(&nfsd_mutex); | |
| 1477 | − if (nn->nfsd_serv) | |
| 1478 | − ret = 0; | |
| 1479 | − else | |
| 1480 | − mutex_unlock(&nfsd_mutex); | |
| 1481 | − | |
| 1482 | − return ret; | |
| 1483 | −} | |
| 1484 | − | |
| 1485 | 1463 | static int nfsd_genl_rpc_status_compose_msg(struct sk_buff *skb, |
| 1486 | 1464 | struct netlink_callback *cb, |
| 1487 | 1465 | struct nfsd_genl_rqstp *rqstp) |
| @@ -1558,8 +1536,16 @@ static int nfsd_genl_rpc_status_compose_msg(struct sk_buff *skb, · 70 unmodified lines | ||
| 1558 | 1536 | int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb, |
| 1559 | 1537 | struct netlink_callback *cb) |
| 1560 | 1538 | { |
| 1561 | − struct nfsd_net *nn = net_generic(sock_net(skb->sk), nfsd_net_id); | |
| 1562 | 1539 | int i, ret, rqstp_index = 0; |
| 1540 | + struct nfsd_net *nn; | |
| 1541 | + | |
| 1542 | + mutex_lock(&nfsd_mutex); | |
| 1543 | + | |
| 1544 | + nn = net_generic(sock_net(skb->sk), nfsd_net_id); | |
| 1545 | + if (!nn->nfsd_serv) { | |
| 1546 | + ret = -ENODEV; | |
| 1547 | + goto out_unlock; | |
| 1548 | + } | |
| 1563 | 1549 | |
| 1564 | 1550 | rcu_read_lock(); |
| 1565 | 1551 | |
| @@ -1636,22 +1622,10 @@ int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb, · 70 unmodified lines | ||
| 1636 | 1622 | ret = skb->len; |
| 1637 | 1623 | out: |
| 1638 | 1624 | rcu_read_unlock(); |
| 1639 | − | |
| 1640 | − return ret; | |
| 1641 | −} | |
| 1642 | − | |
| 1643 | −/** | |
| 1644 | − * nfsd_nl_rpc_status_get_done - rpc_status_get dumpit post-processing | |
| 1645 | − * @cb: netlink metadata and command arguments | |
| 1646 | − * | |
| 1647 | − * Return values: | |
| 1648 | − * %0: Success | |
| 1649 | − */ | |
| 1650 | −int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb) | |
| 1651 | −{ | |
| 1625 | +out_unlock: | |
| 1652 | 1626 | mutex_unlock(&nfsd_mutex); |
| 1653 | 1627 | |
| 1654 | − return 0; | |
| 1628 | + return ret; | |
| 1655 | 1629 | } |
| 1656 | 1630 | |
| 1657 | 1631 | /** |
| @@ -479,12 +479,6 @@ bail: · 478 unmodified lines | ||
| 479 | 479 | return status; |
| 480 | 480 | } |
| 481 | 481 | |
| 482 | − | |
| 483 | −struct ocfs2_triggers { | |
| 484 | − struct jbd2_buffer_trigger_type ot_triggers; | |
| 485 | − int ot_offset; | |
| 486 | −}; | |
| 487 | − | |
| 488 | 482 | static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger_type *triggers) |
| 489 | 483 | { |
| 490 | 484 | return container_of(triggers, struct ocfs2_triggers, ot_triggers); |
| @@ -548,85 +542,76 @@ static void ocfs2_db_frozen_trigger(struct jbd2_buffer_trigger_type *triggers, · 57 unmodified lines | ||
| 548 | 542 | static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers, |
| 549 | 543 | struct buffer_head *bh) |
| 550 | 544 | { |
| 545 | + struct ocfs2_triggers *ot = to_ocfs2_trigger(triggers); | |
| 546 | + | |
| 551 | 547 | mlog(ML_ERROR, |
| 552 | 548 | "ocfs2_abort_trigger called by JBD2. bh = 0x%lx, " |
| 553 | 549 | "bh->b_blocknr = %llu\n", |
| 554 | 550 | (unsigned long)bh, |
| 555 | 551 | (unsigned long long)bh->b_blocknr); |
| 556 | 552 | |
| 557 | − ocfs2_error(bh->b_assoc_map->host->i_sb, | |
| 553 | + ocfs2_error(ot->sb, | |
| 558 | 554 | "JBD2 has aborted our journal, ocfs2 cannot continue\n"); |
| 559 | 555 | } |
| 560 | 556 | |
| 561 | −static struct ocfs2_triggers di_triggers = { | |
| 562 | − .ot_triggers = { | |
| 563 | − .t_frozen = ocfs2_frozen_trigger, | |
| 564 | − .t_abort = ocfs2_abort_trigger, | |
| 565 | − }, | |
| 566 | − .ot_offset = offsetof(struct ocfs2_dinode, i_check), | |
| 567 | −}; | |
| 568 | − | |
| 569 | −static struct ocfs2_triggers eb_triggers = { | |
| 570 | − .ot_triggers = { | |
| 571 | − .t_frozen = ocfs2_frozen_trigger, | |
| 572 | − .t_abort = ocfs2_abort_trigger, | |
| 573 | − }, | |
| 574 | − .ot_offset = offsetof(struct ocfs2_extent_block, h_check), | |
| 575 | −}; | |
| 576 | − | |
| 577 | −static struct ocfs2_triggers rb_triggers = { | |
| 578 | − .ot_triggers = { | |
| 579 | − .t_frozen = ocfs2_frozen_trigger, | |
| 580 | − .t_abort = ocfs2_abort_trigger, | |
| 581 | − }, | |
| 582 | − .ot_offset = offsetof(struct ocfs2_refcount_block, rf_check), | |
| 583 | −}; | |
| 584 | − | |
| 585 | −static struct ocfs2_triggers gd_triggers = { | |
| 586 | − .ot_triggers = { | |
| 587 | − .t_frozen = ocfs2_frozen_trigger, | |
| 588 | − .t_abort = ocfs2_abort_trigger, | |
| 589 | − }, | |
| 590 | − .ot_offset = offsetof(struct ocfs2_group_desc, bg_check), | |
| 591 | −}; | |
| 592 | − | |
| 593 | −static struct ocfs2_triggers db_triggers = { | |
| 594 | − .ot_triggers = { | |
| 595 | − .t_frozen = ocfs2_db_frozen_trigger, | |
| 596 | − .t_abort = ocfs2_abort_trigger, | |
| 597 | − }, | |
| 598 | −}; | |
| 557 | +static void ocfs2_setup_csum_triggers(struct super_block *sb, | |
| 558 | + enum ocfs2_journal_trigger_type type, | |
| 559 | + struct ocfs2_triggers *ot) | |
| 560 | +{ | |
| 561 | + BUG_ON(type >= OCFS2_JOURNAL_TRIGGER_COUNT); | |
| 599 | 562 | |
| 600 | −static struct ocfs2_triggers xb_triggers = { | |
| 601 | − .ot_triggers = { | |
| 602 | − .t_frozen = ocfs2_frozen_trigger, | |
| 603 | − .t_abort = ocfs2_abort_trigger, | |
| 604 | − }, | |
| 605 | − .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check), | |
| 606 | −}; | |
| 563 | + switch (type) { | |
| 564 | + case OCFS2_JTR_DI: | |
| 565 | + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; | |
| 566 | + ot->ot_offset = offsetof(struct ocfs2_dinode, i_check); | |
| 567 | + break; | |
| 568 | + case OCFS2_JTR_EB: | |
| 569 | + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; | |
| 570 | + ot->ot_offset = offsetof(struct ocfs2_extent_block, h_check); | |
| 571 | + break; | |
| 572 | + case OCFS2_JTR_RB: | |
| 573 | + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; | |
| 574 | + ot->ot_offset = offsetof(struct ocfs2_refcount_block, rf_check); | |
| 575 | + break; | |
| 576 | + case OCFS2_JTR_GD: | |
| 577 | + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; | |
| 578 | + ot->ot_offset = offsetof(struct ocfs2_group_desc, bg_check); | |
| 579 | + break; | |
| 580 | + case OCFS2_JTR_DB: | |
| 581 | + ot->ot_triggers.t_frozen = ocfs2_db_frozen_trigger; | |
| 582 | + break; | |
| 583 | + case OCFS2_JTR_XB: | |
| 584 | + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; | |
| 585 | + ot->ot_offset = offsetof(struct ocfs2_xattr_block, xb_check); | |
| 586 | + break; | |
| 587 | + case OCFS2_JTR_DQ: | |
| 588 | + ot->ot_triggers.t_frozen = ocfs2_dq_frozen_trigger; | |
| 589 | + break; | |
| 590 | + case OCFS2_JTR_DR: | |
| 591 | + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; | |
| 592 | + ot->ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check); | |
| 593 | + break; | |
| 594 | + case OCFS2_JTR_DL: | |
| 595 | + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; | |
| 596 | + ot->ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check); | |
| 597 | + break; | |
| 598 | + case OCFS2_JTR_NONE: | |
| 599 | + /* To make compiler happy... */ | |
| 600 | + return; | |
| 601 | + } | |
| 607 | 602 | |
| 608 | −static struct ocfs2_triggers dq_triggers = { | |
| 609 | − .ot_triggers = { | |
| 610 | − .t_frozen = ocfs2_dq_frozen_trigger, | |
| 611 | − .t_abort = ocfs2_abort_trigger, | |
| 612 | − }, | |
| 613 | −}; | |
| 603 | + ot->ot_triggers.t_abort = ocfs2_abort_trigger; | |
| 604 | + ot->sb = sb; | |
| 605 | +} | |
| 614 | 606 | |
| 615 | −static struct ocfs2_triggers dr_triggers = { | |
| 616 | − .ot_triggers = { | |
| 617 | − .t_frozen = ocfs2_frozen_trigger, | |
| 618 | − .t_abort = ocfs2_abort_trigger, | |
| 619 | − }, | |
| 620 | − .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check), | |
| 621 | −}; | |
| 607 | +void ocfs2_initialize_journal_triggers(struct super_block *sb, | |
| 608 | + struct ocfs2_triggers triggers[]) | |
| 609 | +{ | |
| 610 | + enum ocfs2_journal_trigger_type type; | |
| 622 | 611 | |
| 623 | −static struct ocfs2_triggers dl_triggers = { | |
| 624 | − .ot_triggers = { | |
| 625 | − .t_frozen = ocfs2_frozen_trigger, | |
| 626 | − .t_abort = ocfs2_abort_trigger, | |
| 627 | − }, | |
| 628 | − .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check), | |
| 629 | −}; | |
| 612 | + for (type = OCFS2_JTR_DI; type < OCFS2_JOURNAL_TRIGGER_COUNT; type++) | |
| 613 | + ocfs2_setup_csum_triggers(sb, type, &triggers[type]); | |
| 614 | +} | |
| 630 | 615 | |
| 631 | 616 | static int __ocfs2_journal_access(handle_t *handle, |
| 632 | 617 | struct ocfs2_caching_info *ci, |
| @@ -708,56 +693,91 @@ static int __ocfs2_journal_access(handle_t *handle, · 75 unmodified lines | ||
| 708 | 693 | int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci, |
| 709 | 694 | struct buffer_head *bh, int type) |
| 710 | 695 | { |
| 711 | − return __ocfs2_journal_access(handle, ci, bh, &di_triggers, type); | |
| 696 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 697 | + | |
| 698 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 699 | + &osb->s_journal_triggers[OCFS2_JTR_DI], | |
| 700 | + type); | |
| 712 | 701 | } |
| 713 | 702 | |
| 714 | 703 | int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci, |
| 715 | 704 | struct buffer_head *bh, int type) |
| 716 | 705 | { |
| 717 | − return __ocfs2_journal_access(handle, ci, bh, &eb_triggers, type); | |
| 706 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 707 | + | |
| 708 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 709 | + &osb->s_journal_triggers[OCFS2_JTR_EB], | |
| 710 | + type); | |
| 718 | 711 | } |
| 719 | 712 | |
| 720 | 713 | int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci, |
| 721 | 714 | struct buffer_head *bh, int type) |
| 722 | 715 | { |
| 723 | − return __ocfs2_journal_access(handle, ci, bh, &rb_triggers, | |
| 716 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 717 | + | |
| 718 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 719 | + &osb->s_journal_triggers[OCFS2_JTR_RB], | |
| 724 | 720 | type); |
| 725 | 721 | } |
| 726 | 722 | |
| 727 | 723 | int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci, |
| 728 | 724 | struct buffer_head *bh, int type) |
| 729 | 725 | { |
| 730 | − return __ocfs2_journal_access(handle, ci, bh, &gd_triggers, type); | |
| 726 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 727 | + | |
| 728 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 729 | + &osb->s_journal_triggers[OCFS2_JTR_GD], | |
| 730 | + type); | |
| 731 | 731 | } |
| 732 | 732 | |
| 733 | 733 | int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci, |
| 734 | 734 | struct buffer_head *bh, int type) |
| 735 | 735 | { |
| 736 | − return __ocfs2_journal_access(handle, ci, bh, &db_triggers, type); | |
| 736 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 737 | + | |
| 738 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 739 | + &osb->s_journal_triggers[OCFS2_JTR_DB], | |
| 740 | + type); | |
| 737 | 741 | } |
| 738 | 742 | |
| 739 | 743 | int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci, |
| 740 | 744 | struct buffer_head *bh, int type) |
| 741 | 745 | { |
| 742 | − return __ocfs2_journal_access(handle, ci, bh, &xb_triggers, type); | |
| 746 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 747 | + | |
| 748 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 749 | + &osb->s_journal_triggers[OCFS2_JTR_XB], | |
| 750 | + type); | |
| 743 | 751 | } |
| 744 | 752 | |
| 745 | 753 | int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci, |
| 746 | 754 | struct buffer_head *bh, int type) |
| 747 | 755 | { |
| 748 | − return __ocfs2_journal_access(handle, ci, bh, &dq_triggers, type); | |
| 756 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 757 | + | |
| 758 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 759 | + &osb->s_journal_triggers[OCFS2_JTR_DQ], | |
| 760 | + type); | |
| 749 | 761 | } |
| 750 | 762 | |
| 751 | 763 | int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci, |
| 752 | 764 | struct buffer_head *bh, int type) |
| 753 | 765 | { |
| 754 | − return __ocfs2_journal_access(handle, ci, bh, &dr_triggers, type); | |
| 766 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 767 | + | |
| 768 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 769 | + &osb->s_journal_triggers[OCFS2_JTR_DR], | |
| 770 | + type); | |
| 755 | 771 | } |
| 756 | 772 | |
| 757 | 773 | int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci, |
| 758 | 774 | struct buffer_head *bh, int type) |
| 759 | 775 | { |
| 760 | − return __ocfs2_journal_access(handle, ci, bh, &dl_triggers, type); | |
| 776 | + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); | |
| 777 | + | |
| 778 | + return __ocfs2_journal_access(handle, ci, bh, | |
| 779 | + &osb->s_journal_triggers[OCFS2_JTR_DL], | |
| 780 | + type); | |
| 761 | 781 | } |
| 762 | 782 | |
| 763 | 783 | int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci, |
| @@ -778,13 +798,15 @@ void ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh) · 14 unmodified lines | ||
| 778 | 798 | if (!is_handle_aborted(handle)) { |
| 779 | 799 | journal_t *journal = handle->h_transaction->t_journal; |
| 780 | 800 | |
| 781 | − mlog(ML_ERROR, "jbd2_journal_dirty_metadata failed. " | |
| 782 | − "Aborting transaction and journal.\n"); | |
| 801 | + mlog(ML_ERROR, "jbd2_journal_dirty_metadata failed: " | |
| 802 | + "handle type %u started at line %u, credits %u/%u " | |
| 803 | + "errcode %d. Aborting transaction and journal.\n", | |
| 804 | + handle->h_type, handle->h_line_no, | |
| 805 | + handle->h_requested_credits, | |
| 806 | + jbd2_handle_buffer_credits(handle), status); | |
| 783 | 807 | handle->h_err = status; |
| 784 | 808 | jbd2_journal_abort_handle(handle); |
| 785 | 809 | jbd2_journal_abort(journal, status); |
| 786 | − ocfs2_abort(bh->b_assoc_map->host->i_sb, | |
| 787 | − "Journal already aborted.\n"); | |
| 788 | 810 | } |
| 789 | 811 | } |
| 790 | 812 | } |
| @@ -284,6 +284,30 @@ enum ocfs2_mount_options · 283 unmodified lines | ||
| 284 | 284 | #define OCFS2_OSB_ERROR_FS 0x0004 |
| 285 | 285 | #define OCFS2_DEFAULT_ATIME_QUANTUM 60 |
| 286 | 286 | |
| 287 | +struct ocfs2_triggers { | |
| 288 | + struct jbd2_buffer_trigger_type ot_triggers; | |
| 289 | + int ot_offset; | |
| 290 | + struct super_block *sb; | |
| 291 | +}; | |
| 292 | + | |
| 293 | +enum ocfs2_journal_trigger_type { | |
| 294 | + OCFS2_JTR_DI, | |
| 295 | + OCFS2_JTR_EB, | |
| 296 | + OCFS2_JTR_RB, | |
| 297 | + OCFS2_JTR_GD, | |
| 298 | + OCFS2_JTR_DB, | |
| 299 | + OCFS2_JTR_XB, | |
| 300 | + OCFS2_JTR_DQ, | |
| 301 | + OCFS2_JTR_DR, | |
| 302 | + OCFS2_JTR_DL, | |
| 303 | + OCFS2_JTR_NONE /* This must be the last entry */ | |
| 304 | +}; | |
| 305 | + | |
| 306 | +#define OCFS2_JOURNAL_TRIGGER_COUNT OCFS2_JTR_NONE | |
| 307 | + | |
| 308 | +void ocfs2_initialize_journal_triggers(struct super_block *sb, | |
| 309 | + struct ocfs2_triggers triggers[]); | |
| 310 | + | |
| 287 | 311 | struct ocfs2_journal; |
| 288 | 312 | struct ocfs2_slot_info; |
| 289 | 313 | struct ocfs2_recovery_map; |
| @@ -351,6 +375,9 @@ struct ocfs2_super · 61 unmodified lines | ||
| 351 | 375 | struct ocfs2_journal *journal; |
| 352 | 376 | unsigned long osb_commit_interval; |
| 353 | 377 | |
| 378 | + /* Journal triggers for checksum */ | |
| 379 | + struct ocfs2_triggers s_journal_triggers[OCFS2_JOURNAL_TRIGGER_COUNT]; | |
| 380 | + | |
| 354 | 381 | struct delayed_work la_enable_wq; |
| 355 | 382 | |
| 356 | 383 | /* |
| @@ -1075,9 +1075,11 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) · 1074 unmodified lines | ||
| 1075 | 1075 | debugfs_create_file("fs_state", S_IFREG|S_IRUSR, osb->osb_debug_root, |
| 1076 | 1076 | osb, &ocfs2_osb_debug_fops); |
| 1077 | 1077 | |
| 1078 | − if (ocfs2_meta_ecc(osb)) | |
| 1078 | + if (ocfs2_meta_ecc(osb)) { | |
| 1079 | + ocfs2_initialize_journal_triggers(sb, osb->s_journal_triggers); | |
| 1079 | 1080 | ocfs2_blockcheck_stats_debugfs_install( &osb->osb_ecc_stats, |
| 1080 | 1081 | osb->osb_debug_root); |
| 1082 | + } | |
| 1081 | 1083 | |
| 1082 | 1084 | status = ocfs2_mount_volume(sb); |
| 1083 | 1085 | if (status < 0) |
| @@ -1314,10 +1314,6 @@ static int ovl_create_tmpfile(struct file *file, struct dentry *dentry, · 1313 unmodified lines | ||
| 1314 | 1314 | int flags = file->f_flags | OVL_OPEN_FLAGS; |
| 1315 | 1315 | int err; |
| 1316 | 1316 | |
| 1317 | − err = ovl_copy_up(dentry->d_parent); | |
| 1318 | − if (err) | |
| 1319 | − return err; | |
| 1320 | − | |
| 1321 | 1317 | old_cred = ovl_override_creds(dentry->d_sb); |
| 1322 | 1318 | err = ovl_setup_cred_for_create(dentry, inode, mode, old_cred); |
| 1323 | 1319 | if (err) |
| @@ -1360,6 +1356,10 @@ static int ovl_tmpfile(struct mnt_idmap *idmap, struct inode *dir, · 36 unmodified lines | ||
| 1360 | 1356 | if (!OVL_FS(dentry->d_sb)->tmpfile) |
| 1361 | 1357 | return -EOPNOTSUPP; |
| 1362 | 1358 | |
| 1359 | + err = ovl_copy_up(dentry->d_parent); | |
| 1360 | + if (err) | |
| 1361 | + return err; | |
| 1362 | + | |
| 1363 | 1363 | err = ovl_want_write(dentry); |
| 1364 | 1364 | if (err) |
| 1365 | 1365 | return err; |
| @@ -181,6 +181,10 @@ static int ovl_check_encode_origin(struct dentry *dentry) · 180 unmodified lines | ||
| 181 | 181 | struct ovl_fs *ofs = OVL_FS(dentry->d_sb); |
| 182 | 182 | bool decodable = ofs->config.nfs_export; |
| 183 | 183 | |
| 184 | + /* No upper layer? */ | |
| 185 | + if (!ovl_upper_mnt(ofs)) | |
| 186 | + return 1; | |
| 187 | + | |
| 184 | 188 | /* Lower file handle for non-upper non-decodable */ |
| 185 | 189 | if (!ovl_dentry_upper(dentry) && !decodable) |
| 186 | 190 | return 1; |
| @@ -209,7 +213,7 @@ static int ovl_check_encode_origin(struct dentry *dentry) · 22 unmodified lines | ||
| 209 | 213 | * ovl_connect_layer() will try to make origin's layer "connected" by |
| 210 | 214 | * copying up a "connectable" ancestor. |
| 211 | 215 | */ |
| 212 | − if (d_is_dir(dentry) && ovl_upper_mnt(ofs) && decodable) | |
| 216 | + if (d_is_dir(dentry) && decodable) | |
| 213 | 217 | return ovl_connect_layer(dentry); |
| 214 | 218 | |
| 215 | 219 | /* Lower file handle for indexed and non-upper dir/non-dir */ |
| @@ -134,7 +134,7 @@ module_param(enable_oplocks, bool, 0644); · 133 unmodified lines | ||
| 134 | 134 | MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1"); |
| 135 | 135 | |
| 136 | 136 | module_param(enable_gcm_256, bool, 0644); |
| 137 | −MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: n/N/0"); | |
| 137 | +MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/0"); | |
| 138 | 138 | |
| 139 | 139 | module_param(require_gcm_256, bool, 0644); |
| 140 | 140 | MODULE_PARM_DESC(require_gcm_256, "Require strongest (256 bit) GCM encryption. Default: n/N/0"); |
| @@ -1494,6 +1494,8 @@ struct cifs_aio_ctx { · 1493 unmodified lines | ||
| 1494 | 1494 | struct cifs_io_request { |
| 1495 | 1495 | struct netfs_io_request rreq; |
| 1496 | 1496 | struct cifsFileInfo *cfile; |
| 1497 | + struct TCP_Server_Info *server; | |
| 1498 | + pid_t pid; | |
| 1497 | 1499 | }; |
| 1498 | 1500 | |
| 1499 | 1501 | /* asynchronous read support */ |
| @@ -1504,7 +1506,6 @@ struct cifs_io_subrequest { · 4 unmodified lines | ||
| 1504 | 1506 | struct cifs_io_request *req; |
| 1505 | 1507 | }; |
| 1506 | 1508 | ssize_t got_bytes; |
| 1507 | − pid_t pid; | |
| 1508 | 1509 | unsigned int xid; |
| 1509 | 1510 | int result; |
| 1510 | 1511 | bool have_xid; |
| @@ -1345,8 +1345,8 @@ cifs_async_readv(struct cifs_io_subrequest *rdata) · 1344 unmodified lines | ||
| 1345 | 1345 | if (rc) |
| 1346 | 1346 | return rc; |
| 1347 | 1347 | |
| 1348 | − smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid); | |
| 1349 | − smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16)); | |
| 1348 | + smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid); | |
| 1349 | + smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16)); | |
| 1350 | 1350 | |
| 1351 | 1351 | smb->AndXCommand = 0xFF; /* none */ |
| 1352 | 1352 | smb->Fid = rdata->req->cfile->fid.netfid; |
| @@ -1689,8 +1689,8 @@ cifs_async_writev(struct cifs_io_subrequest *wdata) · 336 unmodified lines | ||
| 1689 | 1689 | if (rc) |
| 1690 | 1690 | goto async_writev_out; |
| 1691 | 1691 | |
| 1692 | − smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid); | |
| 1693 | − smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16)); | |
| 1692 | + smb->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid); | |
| 1693 | + smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16)); | |
| 1694 | 1694 | |
| 1695 | 1695 | smb->AndXCommand = 0xFF; /* none */ |
| 1696 | 1696 | smb->Fid = wdata->req->cfile->fid.netfid; |
| @@ -134,17 +134,15 @@ fail: · 133 unmodified lines | ||
| 134 | 134 | static bool cifs_clamp_length(struct netfs_io_subrequest *subreq) |
| 135 | 135 | { |
| 136 | 136 | struct netfs_io_request *rreq = subreq->rreq; |
| 137 | − struct TCP_Server_Info *server; | |
| 138 | 137 | struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq); |
| 139 | 138 | struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq); |
| 139 | + struct TCP_Server_Info *server = req->server; | |
| 140 | 140 | struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb); |
| 141 | 141 | size_t rsize = 0; |
| 142 | 142 | int rc; |
| 143 | 143 | |
| 144 | 144 | rdata->xid = get_xid(); |
| 145 | 145 | rdata->have_xid = true; |
| 146 | − | |
| 147 | − server = cifs_pick_channel(tlink_tcon(req->cfile->tlink)->ses); | |
| 148 | 146 | rdata->server = server; |
| 149 | 147 | |
| 150 | 148 | if (cifs_sb->ctx->rsize == 0) |
| @@ -179,15 +177,8 @@ static void cifs_req_issue_read(struct netfs_io_subrequest *subreq) · 28 unmodified lines | ||
| 179 | 177 | struct netfs_io_request *rreq = subreq->rreq; |
| 180 | 178 | struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq); |
| 181 | 179 | struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq); |
| 182 | − struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb); | |
| 183 | − pid_t pid; | |
| 184 | 180 | int rc = 0; |
| 185 | 181 | |
| 186 | − if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | |
| 187 | − pid = req->cfile->pid; | |
| 188 | − else | |
| 189 | − pid = current->tgid; // Ummm... This may be a workqueue | |
| 190 | − | |
| 191 | 182 | cifs_dbg(FYI, "%s: op=%08x[%x] mapping=%p len=%zu/%zu\n", |
| 192 | 183 | __func__, rreq->debug_id, subreq->debug_index, rreq->mapping, |
| 193 | 184 | subreq->transferred, subreq->len); |
| @@ -201,16 +192,8 @@ static void cifs_req_issue_read(struct netfs_io_subrequest *subreq) · 7 unmodified lines | ||
| 201 | 192 | } |
| 202 | 193 | |
| 203 | 194 | __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags); |
| 204 | − rdata->pid = pid; | |
| 205 | − | |
| 206 | − rc = adjust_credits(rdata->server, &rdata->credits, rdata->subreq.len); | |
| 207 | − if (!rc) { | |
| 208 | − if (rdata->req->cfile->invalidHandle) | |
| 209 | − rc = -EAGAIN; | |
| 210 | − else | |
| 211 | − rc = rdata->server->ops->async_readv(rdata); | |
| 212 | − } | |
| 213 | 195 | |
| 196 | + rc = rdata->server->ops->async_readv(rdata); | |
| 214 | 197 | out: |
| 215 | 198 | if (rc) |
| 216 | 199 | netfs_subreq_terminated(subreq, rc, false); |
| @@ -245,11 +228,15 @@ static int cifs_init_request(struct netfs_io_request *rreq, struct file *file) · 28 unmodified lines | ||
| 245 | 228 | |
| 246 | 229 | rreq->rsize = cifs_sb->ctx->rsize; |
| 247 | 230 | rreq->wsize = cifs_sb->ctx->wsize; |
| 231 | + req->pid = current->tgid; // Ummm... This may be a workqueue | |
| 248 | 232 | |
| 249 | 233 | if (file) { |
| 250 | 234 | open_file = file->private_data; |
| 251 | 235 | rreq->netfs_priv = file->private_data; |
| 252 | 236 | req->cfile = cifsFileInfo_get(open_file); |
| 237 | + req->server = cifs_pick_channel(tlink_tcon(req->cfile->tlink)->ses); | |
| 238 | + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | |
| 239 | + req->pid = req->cfile->pid; | |
| 253 | 240 | } else if (rreq->origin != NETFS_WRITEBACK) { |
| 254 | 241 | WARN_ON_ONCE(1); |
| 255 | 242 | return -EIO; |
| @@ -3200,8 +3187,6 @@ static int cifs_swap_rw(struct kiocb *iocb, struct iov_iter *iter) · 2944 unmodified lines | ||
| 3200 | 3187 | { |
| 3201 | 3188 | ssize_t ret; |
| 3202 | 3189 | |
| 3203 | − WARN_ON_ONCE(iov_iter_count(iter) != PAGE_SIZE); | |
| 3204 | − | |
| 3205 | 3190 | if (iov_iter_rw(iter) == READ) |
| 3206 | 3191 | ret = netfs_unbuffered_read_iter_locked(iocb, iter); |
| 3207 | 3192 | else |
| @@ -4484,6 +4484,16 @@ smb2_new_read_req(void **buf, unsigned int *total_len, · 4483 unmodified lines | ||
| 4484 | 4484 | return rc; |
| 4485 | 4485 | } |
| 4486 | 4486 | |
| 4487 | +static void smb2_readv_worker(struct work_struct *work) | |
| 4488 | +{ | |
| 4489 | + struct cifs_io_subrequest *rdata = | |
| 4490 | + container_of(work, struct cifs_io_subrequest, subreq.work); | |
| 4491 | + | |
| 4492 | + netfs_subreq_terminated(&rdata->subreq, | |
| 4493 | + (rdata->result == 0 || rdata->result == -EAGAIN) ? | |
| 4494 | + rdata->got_bytes : rdata->result, true); | |
| 4495 | +} | |
| 4496 | + | |
| 4487 | 4497 | static void |
| 4488 | 4498 | smb2_readv_callback(struct mid_q_entry *mid) |
| 4489 | 4499 | { |
| @@ -4578,9 +4588,8 @@ smb2_readv_callback(struct mid_q_entry *mid) · 88 unmodified lines | ||
| 4578 | 4588 | rdata->result = 0; |
| 4579 | 4589 | } |
| 4580 | 4590 | rdata->credits.value = 0; |
| 4581 | − netfs_subreq_terminated(&rdata->subreq, | |
| 4582 | − (rdata->result == 0 || rdata->result == -EAGAIN) ? | |
| 4583 | − rdata->got_bytes : rdata->result, true); | |
| 4591 | + INIT_WORK(&rdata->subreq.work, smb2_readv_worker); | |
| 4592 | + queue_work(cifsiod_wq, &rdata->subreq.work); | |
| 4584 | 4593 | release_mid(mid); |
| 4585 | 4594 | add_credits(server, &credits, 0); |
| 4586 | 4595 | } |
| @@ -4612,7 +4621,7 @@ smb2_async_readv(struct cifs_io_subrequest *rdata) · 25 unmodified lines | ||
| 4612 | 4621 | io_parms.length = rdata->subreq.len; |
| 4613 | 4622 | io_parms.persistent_fid = rdata->req->cfile->fid.persistent_fid; |
| 4614 | 4623 | io_parms.volatile_fid = rdata->req->cfile->fid.volatile_fid; |
| 4615 | − io_parms.pid = rdata->pid; | |
| 4624 | + io_parms.pid = rdata->req->pid; | |
| 4616 | 4625 | |
| 4617 | 4626 | rc = smb2_new_read_req( |
| 4618 | 4627 | (void **) &buf, &total_len, &io_parms, rdata, 0, 0); |
| @@ -4864,7 +4873,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata) · 245 unmodified lines | ||
| 4864 | 4873 | .length = wdata->subreq.len, |
| 4865 | 4874 | .persistent_fid = wdata->req->cfile->fid.persistent_fid, |
| 4866 | 4875 | .volatile_fid = wdata->req->cfile->fid.volatile_fid, |
| 4867 | − .pid = wdata->pid, | |
| 4876 | + .pid = wdata->req->pid, | |
| 4868 | 4877 | }; |
| 4869 | 4878 | io_parms = &_io_parms; |
| 4870 | 4879 | |
| @@ -2548,11 +2548,26 @@ xfs_ifree_cluster( · 2547 unmodified lines | ||
| 2548 | 2548 | * This buffer may not have been correctly initialised as we |
| 2549 | 2549 | * didn't read it from disk. That's not important because we are |
| 2550 | 2550 | * only using to mark the buffer as stale in the log, and to |
| 2551 | − * attach stale cached inodes on it. That means it will never be | |
| 2552 | − * dispatched for IO. If it is, we want to know about it, and we | |
| 2553 | − * want it to fail. We can acheive this by adding a write | |
| 2554 | − * verifier to the buffer. | |
| 2551 | + * attach stale cached inodes on it. | |
| 2552 | + * | |
| 2553 | + * For the inode that triggered the cluster freeing, this | |
| 2554 | + * attachment may occur in xfs_inode_item_precommit() after we | |
| 2555 | + * have marked this buffer stale. If this buffer was not in | |
| 2556 | + * memory before xfs_ifree_cluster() started, it will not be | |
| 2557 | + * marked XBF_DONE and this will cause problems later in | |
| 2558 | + * xfs_inode_item_precommit() when we trip over a (stale, !done) | |
| 2559 | + * buffer to attached to the transaction. | |
| 2560 | + * | |
| 2561 | + * Hence we have to mark the buffer as XFS_DONE here. This is | |
| 2562 | + * safe because we are also marking the buffer as XBF_STALE and | |
| 2563 | + * XFS_BLI_STALE. That means it will never be dispatched for | |
| 2564 | + * IO and it won't be unlocked until the cluster freeing has | |
| 2565 | + * been committed to the journal and the buffer unpinned. If it | |
| 2566 | + * is written, we want to know about it, and we want it to | |
| 2567 | + * fail. We can acheive this by adding a write verifier to the | |
| 2568 | + * buffer. | |
| 2555 | 2569 | */ |
| 2570 | + bp->b_flags |= XBF_DONE; | |
| 2556 | 2571 | bp->b_ops = &xfs_inode_buf_ops; |
| 2557 | 2572 | |
| 2558 | 2573 | /* |
| @@ -746,6 +746,8 @@ struct bpf_verifier_env { · 745 unmodified lines | ||
| 746 | 746 | /* Same as scratched_regs but for stack slots */ |
| 747 | 747 | u64 scratched_stack_slots; |
| 748 | 748 | u64 prev_log_pos, prev_insn_print_pos; |
| 749 | + /* buffer used to temporary hold constants as scalar registers */ | |
| 750 | + struct bpf_reg_state fake_reg[2]; | |
| 749 | 751 | /* buffer used to generate temporary string representations, |
| 750 | 752 | * e.g., in reg_type_str() to generate reg_type string |
| 751 | 753 | */ |
| @@ -82,7 +82,7 @@ · 81 unmodified lines | ||
| 82 | 82 | * as to avoid issues such as the compiler inlining or eliding either a static |
| 83 | 83 | * kfunc, or a global kfunc in an LTO build. |
| 84 | 84 | */ |
| 85 | −#define __bpf_kfunc __used noinline | |
| 85 | +#define __bpf_kfunc __used __retain noinline | |
| 86 | 86 | |
| 87 | 87 | #define __bpf_kfunc_start_defs() \ |
| 88 | 88 | __diag_push(); \ |
| @@ -143,6 +143,29 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { } · 142 unmodified lines | ||
| 143 | 143 | # define __preserve_most |
| 144 | 144 | #endif |
| 145 | 145 | |
| 146 | +/* | |
| 147 | + * Annotating a function/variable with __retain tells the compiler to place | |
| 148 | + * the object in its own section and set the flag SHF_GNU_RETAIN. This flag | |
| 149 | + * instructs the linker to retain the object during garbage-cleanup or LTO | |
| 150 | + * phases. | |
| 151 | + * | |
| 152 | + * Note that the __used macro is also used to prevent functions or data | |
| 153 | + * being optimized out, but operates at the compiler/IR-level and may still | |
| 154 | + * allow unintended removal of objects during linking. | |
| 155 | + * | |
| 156 | + * Optional: only supported since gcc >= 11, clang >= 13 | |
| 157 | + * | |
| 158 | + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-retain-function-attribute | |
| 159 | + * clang: https://clang.llvm.org/docs/AttributeReference.html#retain | |
| 160 | + */ | |
| 161 | +#if __has_attribute(__retain__) && \ | |
| 162 | + (defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || \ | |
| 163 | + defined(CONFIG_LTO_CLANG)) | |
| 164 | +# define __retain __attribute__((__retain__)) | |
| 165 | +#else | |
| 166 | +# define __retain | |
| 167 | +#endif | |
| 168 | + | |
| 146 | 169 | /* Compiler specific macros. */ |
| 147 | 170 | #ifdef __clang__ |
| 148 | 171 | #include <linux/compiler-clang.h> |
| @@ -960,8 +960,6 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr); · 959 unmodified lines | ||
| 960 | 960 | #define builtin_i2c_driver(__i2c_driver) \ |
| 961 | 961 | builtin_driver(__i2c_driver, i2c_add_driver) |
| 962 | 962 | |
| 963 | −#endif /* I2C */ | |
| 964 | − | |
| 965 | 963 | /* must call put_device() when done with returned i2c_client device */ |
| 966 | 964 | struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode); |
| 967 | 965 | |
| @@ -971,6 +969,28 @@ struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode); · 3 unmodified lines | ||
| 971 | 969 | /* must call i2c_put_adapter() when done with returned i2c_adapter device */ |
| 972 | 970 | struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode); |
| 973 | 971 | |
| 972 | +#else /* I2C */ | |
| 973 | + | |
| 974 | +static inline struct i2c_client * | |
| 975 | +i2c_find_device_by_fwnode(struct fwnode_handle *fwnode) | |
| 976 | +{ | |
| 977 | + return NULL; | |
| 978 | +} | |
| 979 | + | |
| 980 | +static inline struct i2c_adapter * | |
| 981 | +i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode) | |
| 982 | +{ | |
| 983 | + return NULL; | |
| 984 | +} | |
| 985 | + | |
| 986 | +static inline struct i2c_adapter * | |
| 987 | +i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode) | |
| 988 | +{ | |
| 989 | + return NULL; | |
| 990 | +} | |
| 991 | + | |
| 992 | +#endif /* !I2C */ | |
| 993 | + | |
| 974 | 994 | #if IS_ENABLED(CONFIG_OF) |
| 975 | 995 | /* must call put_device() when done with returned i2c_client device */ |
| 976 | 996 | static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) |
| @@ -21,6 +21,8 @@ enum kcov_mode { · 20 unmodified lines | ||
| 21 | 21 | KCOV_MODE_TRACE_PC = 2, |
| 22 | 22 | /* Collecting comparison operands mode. */ |
| 23 | 23 | KCOV_MODE_TRACE_CMP = 3, |
| 24 | + /* The process owns a KCOV remote reference. */ | |
| 25 | + KCOV_MODE_REMOTE = 4, | |
| 24 | 26 | }; |
| 25 | 27 | |
| 26 | 28 | #define KCOV_IN_CTXSW (1 << 30) |
| @@ -413,7 +413,7 @@ LSM_HOOK(void, LSM_RET_VOID, key_post_create_or_update, struct key *keyring, · 412 unmodified lines | ||
| 413 | 413 | |
| 414 | 414 | #ifdef CONFIG_AUDIT |
| 415 | 415 | LSM_HOOK(int, 0, audit_rule_init, u32 field, u32 op, char *rulestr, |
| 416 | − void **lsmrule) | |
| 416 | + void **lsmrule, gfp_t gfp) | |
| 417 | 417 | LSM_HOOK(int, 0, audit_rule_known, struct audit_krule *krule) |
| 418 | 418 | LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule) |
| 419 | 419 | LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule) |
| @@ -3776,14 +3776,7 @@ DECLARE_STATIC_KEY_MAYBE(CONFIG_INIT_ON_FREE_DEFAULT_ON, init_on_free); · 3775 unmodified lines | ||
| 3776 | 3776 | static inline bool want_init_on_free(void) |
| 3777 | 3777 | { |
| 3778 | 3778 | return static_branch_maybe(CONFIG_INIT_ON_FREE_DEFAULT_ON, |
| 3779 | − &init_on_free); | |
| 3780 | −} | |
| 3781 | − | |
| 3782 | −DECLARE_STATIC_KEY_MAYBE(CONFIG_INIT_MLOCKED_ON_FREE_DEFAULT_ON, init_mlocked_on_free); | |
| 3783 | −static inline bool want_init_mlocked_on_free(void) | |
| 3784 | −{ | |
| 3785 | − return static_branch_maybe(CONFIG_INIT_MLOCKED_ON_FREE_DEFAULT_ON, | |
| 3786 | − &init_mlocked_on_free); | |
| 3779 | + &init_on_free); | |
| 3787 | 3780 | } |
| 3788 | 3781 | |
| 3789 | 3782 | extern bool _debug_pagealloc_enabled_early; |
| @@ -15,6 +15,11 @@ · 14 unmodified lines | ||
| 15 | 15 | #define NUMA_NO_NODE (-1) |
| 16 | 16 | #define NUMA_NO_MEMBLK (-1) |
| 17 | 17 | |
| 18 | +static inline bool numa_valid_node(int nid) | |
| 19 | +{ | |
| 20 | + return nid >= 0 && nid < MAX_NUMNODES; | |
| 21 | +} | |
| 22 | + | |
| 18 | 23 | /* optionally keep NUMA memory info available post init */ |
| 19 | 24 | #ifdef CONFIG_NUMA_KEEP_MEMINFO |
| 20 | 25 | #define __initdata_or_meminfo |
| @@ -381,6 +381,10 @@ static inline void mapping_set_large_folios(struct address_space *mapping) · 380 unmodified lines | ||
| 381 | 381 | */ |
| 382 | 382 | static inline bool mapping_large_folio_support(struct address_space *mapping) |
| 383 | 383 | { |
| 384 | + /* AS_LARGE_FOLIO_SUPPORT is only reasonable for pagecache folios */ | |
| 385 | + VM_WARN_ONCE((unsigned long)mapping & PAGE_MAPPING_ANON, | |
| 386 | + "Anonymous mapping always supports large folio"); | |
| 387 | + | |
| 384 | 388 | return IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && |
| 385 | 389 | test_bit(AS_LARGE_FOLIO_SUPPORT, &mapping->flags); |
| 386 | 390 | } |
| @@ -37,6 +37,9 @@ static inline union codetag_ref *get_page_tag_ref(struct page *page) · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | static inline void put_page_tag_ref(union codetag_ref *ref) |
| 39 | 39 | { |
| 40 | + if (WARN_ON(!ref)) | |
| 41 | + return; | |
| 42 | + | |
| 40 | 43 | page_ext_put(page_ext_from_codetag_ref(ref)); |
| 41 | 44 | } |
| 42 | 45 | |
| @@ -102,9 +105,11 @@ static inline struct alloc_tag *pgalloc_tag_get(struct page *page) · 59 unmodified lines | ||
| 102 | 105 | union codetag_ref *ref = get_page_tag_ref(page); |
| 103 | 106 | |
| 104 | 107 | alloc_tag_sub_check(ref); |
| 105 | − if (ref && ref->ct) | |
| 106 | − tag = ct_to_alloc_tag(ref->ct); | |
| 107 | − put_page_tag_ref(ref); | |
| 108 | + if (ref) { | |
| 109 | + if (ref->ct) | |
| 110 | + tag = ct_to_alloc_tag(ref->ct); | |
| 111 | + put_page_tag_ref(ref); | |
| 112 | + } | |
| 108 | 113 | } |
| 109 | 114 | |
| 110 | 115 | return tag; |
| @@ -250,6 +250,7 @@ int regulator_get_hardware_vsel_register(struct regulator *regulator, · 249 unmodified lines | ||
| 250 | 250 | unsigned *vsel_mask); |
| 251 | 251 | int regulator_list_hardware_vsel(struct regulator *regulator, |
| 252 | 252 | unsigned selector); |
| 253 | +int regulator_hardware_enable(struct regulator *regulator, bool enable); | |
| 253 | 254 | |
| 254 | 255 | /* regulator notifier block */ |
| 255 | 256 | int regulator_register_notifier(struct regulator *regulator, |
| @@ -571,6 +572,12 @@ static inline int regulator_list_hardware_vsel(struct regulator *regulator, · 315 unmodified lines | ||
| 571 | 572 | return -EOPNOTSUPP; |
| 572 | 573 | } |
| 573 | 574 | |
| 575 | +static inline int regulator_hardware_enable(struct regulator *regulator, | |
| 576 | + bool enable) | |
| 577 | +{ | |
| 578 | + return -EOPNOTSUPP; | |
| 579 | +} | |
| 580 | + | |
| 574 | 581 | static inline int regulator_register_notifier(struct regulator *regulator, |
| 575 | 582 | struct notifier_block *nb) |
| 576 | 583 | { |
| @@ -2048,7 +2048,8 @@ static inline void security_key_post_create_or_update(struct key *keyring, · 2047 unmodified lines | ||
| 2048 | 2048 | |
| 2049 | 2049 | #ifdef CONFIG_AUDIT |
| 2050 | 2050 | #ifdef CONFIG_SECURITY |
| 2051 | −int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule); | |
| 2051 | +int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule, | |
| 2052 | + gfp_t gfp); | |
| 2052 | 2053 | int security_audit_rule_known(struct audit_krule *krule); |
| 2053 | 2054 | int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule); |
| 2054 | 2055 | void security_audit_rule_free(void *lsmrule); |
| @@ -2056,7 +2057,7 @@ void security_audit_rule_free(void *lsmrule); · 1 unmodified line | ||
| 2056 | 2057 | #else |
| 2057 | 2058 | |
| 2058 | 2059 | static inline int security_audit_rule_init(u32 field, u32 op, char *rulestr, |
| 2059 | − void **lsmrule) | |
| 2060 | + void **lsmrule, gfp_t gfp) | |
| 2060 | 2061 | { |
| 2061 | 2062 | return 0; |
| 2062 | 2063 | } |
| @@ -1085,12 +1085,13 @@ struct spi_transfer { · 1084 unmodified lines | ||
| 1085 | 1085 | unsigned dummy_data:1; |
| 1086 | 1086 | unsigned cs_off:1; |
| 1087 | 1087 | unsigned cs_change:1; |
| 1088 | − unsigned tx_nbits:3; | |
| 1089 | − unsigned rx_nbits:3; | |
| 1088 | + unsigned tx_nbits:4; | |
| 1089 | + unsigned rx_nbits:4; | |
| 1090 | 1090 | unsigned timestamped:1; |
| 1091 | 1091 | #define SPI_NBITS_SINGLE 0x01 /* 1-bit transfer */ |
| 1092 | 1092 | #define SPI_NBITS_DUAL 0x02 /* 2-bit transfer */ |
| 1093 | 1093 | #define SPI_NBITS_QUAD 0x04 /* 4-bit transfer */ |
| 1094 | +#define SPI_NBITS_OCTAL 0x08 /* 8-bit transfer */ | |
| 1094 | 1095 | u8 bits_per_word; |
| 1095 | 1096 | struct spi_delay delay; |
| 1096 | 1097 | struct spi_delay cs_change_delay; |
| @@ -289,7 +289,7 @@ extern void *kmemdup_noprof(const void *src, size_t len, gfp_t gfp) __realloc_si · 288 unmodified lines | ||
| 289 | 289 | |
| 290 | 290 | extern void *kvmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2); |
| 291 | 291 | extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp); |
| 292 | −extern void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp) | |
| 292 | +extern void *kmemdup_array(const void *src, size_t count, size_t element_size, gfp_t gfp) | |
| 293 | 293 | __realloc_size(2, 3); |
| 294 | 294 | |
| 295 | 295 | /* lib/argv_split.c */ |
| @@ -15,6 +15,9 @@ struct netns_nf { · 14 unmodified lines | ||
| 15 | 15 | const struct nf_logger __rcu *nf_loggers[NFPROTO_NUMPROTO]; |
| 16 | 16 | #ifdef CONFIG_SYSCTL |
| 17 | 17 | struct ctl_table_header *nf_log_dir_header; |
| 18 | +#ifdef CONFIG_LWTUNNEL | |
| 19 | + struct ctl_table_header *nf_lwtnl_dir_header; | |
| 20 | +#endif | |
| 18 | 21 | #endif |
| 19 | 22 | struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS]; |
| 20 | 23 | struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS]; |
| @@ -69,8 +69,10 @@ · 68 unmodified lines | ||
| 69 | 69 | #define BLIST_RETRY_ITF ((__force blist_flags_t)(1ULL << 32)) |
| 70 | 70 | /* Always retry ABORTED_COMMAND with ASC 0xc1 */ |
| 71 | 71 | #define BLIST_RETRY_ASC_C1 ((__force blist_flags_t)(1ULL << 33)) |
| 72 | +/* Do not query the IO Advice Hints Grouping mode page */ | |
| 73 | +#define BLIST_SKIP_IO_HINTS ((__force blist_flags_t)(1ULL << 34)) | |
| 72 | 74 | |
| 73 | −#define __BLIST_LAST_USED BLIST_RETRY_ASC_C1 | |
| 75 | +#define __BLIST_LAST_USED BLIST_SKIP_IO_HINTS | |
| 74 | 76 | |
| 75 | 77 | #define __BLIST_HIGH_UNUSED (~(__BLIST_LAST_USED | \ |
| 76 | 78 | (__force blist_flags_t) \ |
| @@ -883,7 +883,7 @@ config GCC10_NO_ARRAY_BOUNDS · 882 unmodified lines | ||
| 883 | 883 | |
| 884 | 884 | config CC_NO_ARRAY_BOUNDS |
| 885 | 885 | bool |
| 886 | − default y if CC_IS_GCC && GCC_VERSION >= 100000 && GCC10_NO_ARRAY_BOUNDS | |
| 886 | + default y if CC_IS_GCC && GCC_VERSION >= 90000 && GCC10_NO_ARRAY_BOUNDS | |
| 887 | 887 | |
| 888 | 888 | # Currently, disable -Wstringop-overflow for GCC globally. |
| 889 | 889 | config GCC_NO_STRINGOP_OVERFLOW |
| @@ -1068,7 +1068,6 @@ int io_import_fixed(int ddir, struct iov_iter *iter, · 1067 unmodified lines | ||
| 1068 | 1068 | * branch doesn't expect non PAGE_SIZE'd chunks. |
| 1069 | 1069 | */ |
| 1070 | 1070 | iter->bvec = bvec; |
| 1071 | − iter->nr_segs = bvec->bv_len; | |
| 1072 | 1071 | iter->count -= offset; |
| 1073 | 1072 | iter->iov_offset = offset; |
| 1074 | 1073 | } else { |
| @@ -529,7 +529,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, · 528 unmodified lines | ||
| 529 | 529 | entry->rule.buflen += f_val; |
| 530 | 530 | f->lsm_str = str; |
| 531 | 531 | err = security_audit_rule_init(f->type, f->op, str, |
| 532 | − (void **)&f->lsm_rule); | |
| 532 | + (void **)&f->lsm_rule, | |
| 533 | + GFP_KERNEL); | |
| 533 | 534 | /* Keep currently invalid fields around in case they |
| 534 | 535 | * become valid after a policy reload. */ |
| 535 | 536 | if (err == -EINVAL) { |
| @@ -799,7 +800,7 @@ static inline int audit_dupe_lsm_field(struct audit_field *df, · 263 unmodified lines | ||
| 799 | 800 | |
| 800 | 801 | /* our own (refreshed) copy of lsm_rule */ |
| 801 | 802 | ret = security_audit_rule_init(df->type, df->op, df->lsm_str, |
| 802 | − (void **)&df->lsm_rule); | |
| 803 | + (void **)&df->lsm_rule, GFP_KERNEL); | |
| 803 | 804 | /* Keep currently invalid fields around in case they |
| 804 | 805 | * become valid after a policy reload. */ |
| 805 | 806 | if (ret == -EINVAL) { |
| @@ -4549,11 +4549,12 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, · 4548 unmodified lines | ||
| 4549 | 4549 | state->stack[spi].spilled_ptr.id = 0; |
| 4550 | 4550 | } else if (!reg && !(off % BPF_REG_SIZE) && is_bpf_st_mem(insn) && |
| 4551 | 4551 | env->bpf_capable) { |
| 4552 | − struct bpf_reg_state fake_reg = {}; | |
| 4552 | + struct bpf_reg_state *tmp_reg = &env->fake_reg[0]; | |
| 4553 | 4553 | |
| 4554 | − __mark_reg_known(&fake_reg, insn->imm); | |
| 4555 | − fake_reg.type = SCALAR_VALUE; | |
| 4556 | − save_register_state(env, state, spi, &fake_reg, size); | |
| 4554 | + memset(tmp_reg, 0, sizeof(*tmp_reg)); | |
| 4555 | + __mark_reg_known(tmp_reg, insn->imm); | |
| 4556 | + tmp_reg->type = SCALAR_VALUE; | |
| 4557 | + save_register_state(env, state, spi, tmp_reg, size); | |
| 4557 | 4558 | } else if (reg && is_spillable_regtype(reg->type)) { |
| 4558 | 4559 | /* register containing pointer is being spilled into stack */ |
| 4559 | 4560 | if (size != BPF_REG_SIZE) { |
| @@ -15113,7 +15114,6 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, · 10553 unmodified lines | ||
| 15113 | 15114 | struct bpf_reg_state *regs = this_branch->frame[this_branch->curframe]->regs; |
| 15114 | 15115 | struct bpf_reg_state *dst_reg, *other_branch_regs, *src_reg = NULL; |
| 15115 | 15116 | struct bpf_reg_state *eq_branch_regs; |
| 15116 | − struct bpf_reg_state fake_reg = {}; | |
| 15117 | 15117 | u8 opcode = BPF_OP(insn->code); |
| 15118 | 15118 | bool is_jmp32; |
| 15119 | 15119 | int pred = -1; |
| @@ -15179,7 +15179,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, · 59 unmodified lines | ||
| 15179 | 15179 | verbose(env, "BPF_JMP/JMP32 uses reserved fields\n"); |
| 15180 | 15180 | return -EINVAL; |
| 15181 | 15181 | } |
| 15182 | − src_reg = &fake_reg; | |
| 15182 | + src_reg = &env->fake_reg[0]; | |
| 15183 | + memset(src_reg, 0, sizeof(*src_reg)); | |
| 15183 | 15184 | src_reg->type = SCALAR_VALUE; |
| 15184 | 15185 | __mark_reg_known(src_reg, insn->imm); |
| 15185 | 15186 | } |
| @@ -15239,10 +15240,16 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, · 53 unmodified lines | ||
| 15239 | 15240 | &other_branch_regs[insn->src_reg], |
| 15240 | 15241 | dst_reg, src_reg, opcode, is_jmp32); |
| 15241 | 15242 | } else /* BPF_SRC(insn->code) == BPF_K */ { |
| 15243 | + /* reg_set_min_max() can mangle the fake_reg. Make a copy | |
| 15244 | + * so that these are two different memory locations. The | |
| 15245 | + * src_reg is not used beyond here in context of K. | |
| 15246 | + */ | |
| 15247 | + memcpy(&env->fake_reg[1], &env->fake_reg[0], | |
| 15248 | + sizeof(env->fake_reg[0])); | |
| 15242 | 15249 | err = reg_set_min_max(env, |
| 15243 | 15250 | &other_branch_regs[insn->dst_reg], |
| 15244 | − src_reg /* fake one */, | |
| 15245 | − dst_reg, src_reg /* same fake one */, | |
| 15251 | + &env->fake_reg[0], | |
| 15252 | + dst_reg, &env->fake_reg[1], | |
| 15246 | 15253 | opcode, is_jmp32); |
| 15247 | 15254 | } |
| 15248 | 15255 | if (err) |
| @@ -20313,7 +20320,7 @@ patch_map_ops_generic: · 5064 unmodified lines | ||
| 20313 | 20320 | goto next_insn; |
| 20314 | 20321 | } |
| 20315 | 20322 | |
| 20316 | −#ifdef CONFIG_X86_64 | |
| 20323 | +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) | |
| 20317 | 20324 | /* Implement bpf_get_smp_processor_id() inline. */ |
| 20318 | 20325 | if (insn->imm == BPF_FUNC_get_smp_processor_id && |
| 20319 | 20326 | prog->jit_requested && bpf_jit_supports_percpu_insn()) { |
| @@ -18,7 +18,9 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/mm.h> |
| 19 | 19 | #include "gcov.h" |
| 20 | 20 | |
| 21 | −#if (__GNUC__ >= 10) | |
| 21 | +#if (__GNUC__ >= 14) | |
| 22 | +#define GCOV_COUNTERS 9 | |
| 23 | +#elif (__GNUC__ >= 10) | |
| 22 | 24 | #define GCOV_COUNTERS 8 |
| 23 | 25 | #elif (__GNUC__ >= 7) |
| 24 | 26 | #define GCOV_COUNTERS 9 |
| @@ -632,6 +632,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, · 631 unmodified lines | ||
| 632 | 632 | return -EINVAL; |
| 633 | 633 | kcov->mode = mode; |
| 634 | 634 | t->kcov = kcov; |
| 635 | + t->kcov_mode = KCOV_MODE_REMOTE; | |
| 635 | 636 | kcov->t = t; |
| 636 | 637 | kcov->remote = true; |
| 637 | 638 | kcov->remote_size = remote_arg->area_size; |
| @@ -218,6 +218,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) · 217 unmodified lines | ||
| 218 | 218 | */ |
| 219 | 219 | do { |
| 220 | 220 | clear_thread_flag(TIF_SIGPENDING); |
| 221 | + clear_thread_flag(TIF_NOTIFY_SIGNAL); | |
| 221 | 222 | rc = kernel_wait4(-1, NULL, __WALL, NULL); |
| 222 | 223 | } while (rc != -ECHILD); |
| 223 | 224 | |
| @@ -1136,7 +1136,7 @@ config PREEMPTIRQ_DELAY_TEST · 1135 unmodified lines | ||
| 1136 | 1136 | |
| 1137 | 1137 | config SYNTH_EVENT_GEN_TEST |
| 1138 | 1138 | tristate "Test module for in-kernel synthetic event generation" |
| 1139 | − depends on SYNTH_EVENTS | |
| 1139 | + depends on SYNTH_EVENTS && m | |
| 1140 | 1140 | help |
| 1141 | 1141 | This option creates a test module to check the base |
| 1142 | 1142 | functionality of in-kernel synthetic event definition and |
| @@ -1149,7 +1149,7 @@ config SYNTH_EVENT_GEN_TEST · 6 unmodified lines | ||
| 1149 | 1149 | |
| 1150 | 1150 | config KPROBE_EVENT_GEN_TEST |
| 1151 | 1151 | tristate "Test module for in-kernel kprobe event generation" |
| 1152 | − depends on KPROBE_EVENTS | |
| 1152 | + depends on KPROBE_EVENTS && m | |
| 1153 | 1153 | help |
| 1154 | 1154 | This option creates a test module to check the base |
| 1155 | 1155 | functionality of in-kernel kprobe event definition. |
| @@ -539,13 +539,7 @@ config CPUMASK_OFFSTACK · 538 unmodified lines | ||
| 539 | 539 | stack overflow. |
| 540 | 540 | |
| 541 | 541 | config FORCE_NR_CPUS |
| 542 | − bool "Set number of CPUs at compile time" | |
| 543 | − depends on SMP && EXPERT && !COMPILE_TEST | |
| 544 | − help | |
| 545 | − Say Yes if you have NR_CPUS set to an actual number of possible | |
| 546 | − CPUs in your system, not to a default value. This forces the core | |
| 547 | − code to rely on compile-time value and optimize kernel routines | |
| 548 | − better. | |
| 542 | + def_bool !SMP | |
| 549 | 543 | |
| 550 | 544 | config CPU_RMAP |
| 551 | 545 | bool |
| @@ -227,6 +227,7 @@ struct page_ext_operations page_alloc_tagging_ops = { · 226 unmodified lines | ||
| 227 | 227 | }; |
| 228 | 228 | EXPORT_SYMBOL(page_alloc_tagging_ops); |
| 229 | 229 | |
| 230 | +#ifdef CONFIG_SYSCTL | |
| 230 | 231 | static struct ctl_table memory_allocation_profiling_sysctls[] = { |
| 231 | 232 | { |
| 232 | 233 | .procname = "mem_profiling", |
| @@ -241,6 +242,17 @@ static struct ctl_table memory_allocation_profiling_sysctls[] = { · 8 unmodified lines | ||
| 241 | 242 | { } |
| 242 | 243 | }; |
| 243 | 244 | |
| 245 | +static void __init sysctl_init(void) | |
| 246 | +{ | |
| 247 | + if (!mem_profiling_support) | |
| 248 | + memory_allocation_profiling_sysctls[0].mode = 0444; | |
| 249 | + | |
| 250 | + register_sysctl_init("vm", memory_allocation_profiling_sysctls); | |
| 251 | +} | |
| 252 | +#else /* CONFIG_SYSCTL */ | |
| 253 | +static inline void sysctl_init(void) {} | |
| 254 | +#endif /* CONFIG_SYSCTL */ | |
| 255 | + | |
| 244 | 256 | static int __init alloc_tag_init(void) |
| 245 | 257 | { |
| 246 | 258 | const struct codetag_type_desc desc = { |
| @@ -253,9 +265,7 @@ static int __init alloc_tag_init(void) · 6 unmodified lines | ||
| 253 | 265 | if (IS_ERR(alloc_tag_cttype)) |
| 254 | 266 | return PTR_ERR(alloc_tag_cttype); |
| 255 | 267 | |
| 256 | − if (!mem_profiling_support) | |
| 257 | − memory_allocation_profiling_sysctls[0].mode = 0444; | |
| 258 | − register_sysctl_init("vm", memory_allocation_profiling_sysctls); | |
| 268 | + sysctl_init(); | |
| 259 | 269 | procfs_init(); |
| 260 | 270 | |
| 261 | 271 | return 0; |
| @@ -17,12 +17,18 @@ static inline void closure_put_after_sub(struct closure *cl, int flags) · 16 unmodified lines | ||
| 17 | 17 | { |
| 18 | 18 | int r = flags & CLOSURE_REMAINING_MASK; |
| 19 | 19 | |
| 20 | − BUG_ON(flags & CLOSURE_GUARD_MASK); | |
| 21 | − BUG_ON(!r && (flags & ~CLOSURE_DESTRUCTOR)); | |
| 20 | + if (WARN(flags & CLOSURE_GUARD_MASK, | |
| 21 | + "closure has guard bits set: %x (%u)", | |
| 22 | + flags & CLOSURE_GUARD_MASK, (unsigned) __fls(r))) | |
| 23 | + r &= ~CLOSURE_GUARD_MASK; | |
| 22 | 24 | |
| 23 | 25 | if (!r) { |
| 24 | 26 | smp_acquire__after_ctrl_dep(); |
| 25 | 27 | |
| 28 | + WARN(flags & ~CLOSURE_DESTRUCTOR, | |
| 29 | + "closure ref hit 0 with incorrect flags set: %x (%u)", | |
| 30 | + flags & ~CLOSURE_DESTRUCTOR, (unsigned) __fls(flags)); | |
| 31 | + | |
| 26 | 32 | cl->closure_get_happened = false; |
| 27 | 33 | |
| 28 | 34 | if (cl->fn && !(flags & CLOSURE_DESTRUCTOR)) { |
| @@ -374,7 +374,7 @@ static const char * const test_strs[] = { · 373 unmodified lines | ||
| 374 | 374 | for (i = 0; i < ARRAY_SIZE(test_strs); i++) { \ |
| 375 | 375 | len = strlen(test_strs[i]); \ |
| 376 | 376 | KUNIT_EXPECT_EQ(test, __builtin_constant_p(len), 0); \ |
| 377 | − checker(len, kmemdup_array(test_strs[i], len, 1, gfp), \ | |
| 377 | + checker(len, kmemdup_array(test_strs[i], 1, len, gfp), \ | |
| 378 | 378 | kfree(p)); \ |
| 379 | 379 | checker(len, kmemdup(test_strs[i], len, gfp), \ |
| 380 | 380 | kfree(p)); \ |
| @@ -1178,14 +1178,28 @@ struct foo { · 1177 unmodified lines | ||
| 1178 | 1178 | s16 array[] __counted_by(counter); |
| 1179 | 1179 | }; |
| 1180 | 1180 | |
| 1181 | +struct bar { | |
| 1182 | + int a; | |
| 1183 | + u32 counter; | |
| 1184 | + s16 array[]; | |
| 1185 | +}; | |
| 1186 | + | |
| 1181 | 1187 | static void DEFINE_FLEX_test(struct kunit *test) |
| 1182 | 1188 | { |
| 1183 | − DEFINE_RAW_FLEX(struct foo, two, array, 2); | |
| 1189 | + /* Using _RAW_ on a __counted_by struct will initialize "counter" to zero */ | |
| 1190 | + DEFINE_RAW_FLEX(struct foo, two_but_zero, array, 2); | |
| 1191 | +#if __has_attribute(__counted_by__) | |
| 1192 | + int expected_raw_size = sizeof(struct foo); | |
| 1193 | +#else | |
| 1194 | + int expected_raw_size = sizeof(struct foo) + 2 * sizeof(s16); | |
| 1195 | +#endif | |
| 1196 | + /* Without annotation, it will always be on-stack size. */ | |
| 1197 | + DEFINE_RAW_FLEX(struct bar, two, array, 2); | |
| 1184 | 1198 | DEFINE_FLEX(struct foo, eight, array, counter, 8); |
| 1185 | 1199 | DEFINE_FLEX(struct foo, empty, array, counter, 0); |
| 1186 | 1200 | |
| 1187 | − KUNIT_EXPECT_EQ(test, __struct_size(two), | |
| 1188 | − sizeof(struct foo) + sizeof(s16) + sizeof(s16)); | |
| 1201 | + KUNIT_EXPECT_EQ(test, __struct_size(two_but_zero), expected_raw_size); | |
| 1202 | + KUNIT_EXPECT_EQ(test, __struct_size(two), sizeof(struct bar) + 2 * sizeof(s16)); | |
| 1189 | 1203 | KUNIT_EXPECT_EQ(test, __struct_size(eight), 24); |
| 1190 | 1204 | KUNIT_EXPECT_EQ(test, __struct_size(empty), sizeof(struct foo)); |
| 1191 | 1205 | } |
| @@ -40,22 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | * Please refer Documentation/mm/arch_pgtable_helpers.rst for the semantics |
| 41 | 41 | * expectations that are being validated here. All future changes in here |
| 42 | 42 | * or the documentation need to be in sync. |
| 43 | − * | |
| 44 | − * On s390 platform, the lower 4 bits are used to identify given page table | |
| 45 | − * entry type. But these bits might affect the ability to clear entries with | |
| 46 | − * pxx_clear() because of how dynamic page table folding works on s390. So | |
| 47 | − * while loading up the entries do not change the lower 4 bits. It does not | |
| 48 | − * have affect any other platform. Also avoid the 62nd bit on ppc64 that is | |
| 49 | − * used to mark a pte entry. | |
| 50 | 43 | */ |
| 51 | −#define S390_SKIP_MASK GENMASK(3, 0) | |
| 52 | −#if __BITS_PER_LONG == 64 | |
| 53 | −#define PPC64_SKIP_MASK GENMASK(62, 62) | |
| 54 | −#else | |
| 55 | −#define PPC64_SKIP_MASK 0x0 | |
| 56 | −#endif | |
| 57 | −#define ARCH_SKIP_MASK (S390_SKIP_MASK | PPC64_SKIP_MASK) | |
| 58 | −#define RANDOM_ORVALUE (GENMASK(BITS_PER_LONG - 1, 0) & ~ARCH_SKIP_MASK) | |
| 59 | 44 | #define RANDOM_NZVALUE GENMASK(7, 0) |
| 60 | 45 | |
| 61 | 46 | struct pgtable_debug_args { |
| @@ -511,8 +496,7 @@ static void __init pud_clear_tests(struct pgtable_debug_args *args) · 449 unmodified lines | ||
| 511 | 496 | return; |
| 512 | 497 | |
| 513 | 498 | pr_debug("Validating PUD clear\n"); |
| 514 | − pud = __pud(pud_val(pud) | RANDOM_ORVALUE); | |
| 515 | − WRITE_ONCE(*args->pudp, pud); | |
| 499 | + WARN_ON(pud_none(pud)); | |
| 516 | 500 | pud_clear(args->pudp); |
| 517 | 501 | pud = READ_ONCE(*args->pudp); |
| 518 | 502 | WARN_ON(!pud_none(pud)); |
| @@ -548,8 +532,7 @@ static void __init p4d_clear_tests(struct pgtable_debug_args *args) · 29 unmodified lines | ||
| 548 | 532 | return; |
| 549 | 533 | |
| 550 | 534 | pr_debug("Validating P4D clear\n"); |
| 551 | − p4d = __p4d(p4d_val(p4d) | RANDOM_ORVALUE); | |
| 552 | − WRITE_ONCE(*args->p4dp, p4d); | |
| 535 | + WARN_ON(p4d_none(p4d)); | |
| 553 | 536 | p4d_clear(args->p4dp); |
| 554 | 537 | p4d = READ_ONCE(*args->p4dp); |
| 555 | 538 | WARN_ON(!p4d_none(p4d)); |
| @@ -582,8 +565,7 @@ static void __init pgd_clear_tests(struct pgtable_debug_args *args) · 26 unmodified lines | ||
| 582 | 565 | return; |
| 583 | 566 | |
| 584 | 567 | pr_debug("Validating PGD clear\n"); |
| 585 | − pgd = __pgd(pgd_val(pgd) | RANDOM_ORVALUE); | |
| 586 | − WRITE_ONCE(*args->pgdp, pgd); | |
| 568 | + WARN_ON(pgd_none(pgd)); | |
| 587 | 569 | pgd_clear(args->pgdp); |
| 588 | 570 | pgd = READ_ONCE(*args->pgdp); |
| 589 | 571 | WARN_ON(!pgd_none(pgd)); |
| @@ -634,10 +616,8 @@ static void __init pte_clear_tests(struct pgtable_debug_args *args) · 44 unmodified lines | ||
| 634 | 616 | if (WARN_ON(!args->ptep)) |
| 635 | 617 | return; |
| 636 | 618 | |
| 637 | −#ifndef CONFIG_RISCV | |
| 638 | − pte = __pte(pte_val(pte) | RANDOM_ORVALUE); | |
| 639 | −#endif | |
| 640 | 619 | set_pte_at(args->mm, args->vaddr, args->ptep, pte); |
| 620 | + WARN_ON(pte_none(pte)); | |
| 641 | 621 | flush_dcache_page(page); |
| 642 | 622 | barrier(); |
| 643 | 623 | ptep_clear(args->mm, args->vaddr, args->ptep); |
| @@ -650,8 +630,7 @@ static void __init pmd_clear_tests(struct pgtable_debug_args *args) · 6 unmodified lines | ||
| 650 | 630 | pmd_t pmd = READ_ONCE(*args->pmdp); |
| 651 | 631 | |
| 652 | 632 | pr_debug("Validating PMD clear\n"); |
| 653 | − pmd = __pmd(pmd_val(pmd) | RANDOM_ORVALUE); | |
| 654 | − WRITE_ONCE(*args->pmdp, pmd); | |
| 633 | + WARN_ON(pmd_none(pmd)); | |
| 655 | 634 | pmd_clear(args->pmdp); |
| 656 | 635 | pmd = READ_ONCE(*args->pmdp); |
| 657 | 636 | WARN_ON(!pmd_none(pmd)); |
| @@ -3009,30 +3009,36 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list, · 3008 unmodified lines | ||
| 3009 | 3009 | if (new_order >= folio_order(folio)) |
| 3010 | 3010 | return -EINVAL; |
| 3011 | 3011 | |
| 3012 | − /* Cannot split anonymous THP to order-1 */ | |
| 3013 | − if (new_order == 1 && folio_test_anon(folio)) { | |
| 3014 | − VM_WARN_ONCE(1, "Cannot split to order-1 folio"); | |
| 3015 | − return -EINVAL; | |
| 3016 | − } | |
| 3017 | − | |
| 3018 | − if (new_order) { | |
| 3019 | − /* Only swapping a whole PMD-mapped folio is supported */ | |
| 3020 | − if (folio_test_swapcache(folio)) | |
| 3012 | + if (folio_test_anon(folio)) { | |
| 3013 | + /* order-1 is not supported for anonymous THP. */ | |
| 3014 | + if (new_order == 1) { | |
| 3015 | + VM_WARN_ONCE(1, "Cannot split to order-1 folio"); | |
| 3021 | 3016 | return -EINVAL; |
| 3017 | + } | |
| 3018 | + } else if (new_order) { | |
| 3022 | 3019 | /* Split shmem folio to non-zero order not supported */ |
| 3023 | 3020 | if (shmem_mapping(folio->mapping)) { |
| 3024 | 3021 | VM_WARN_ONCE(1, |
| 3025 | 3022 | "Cannot split shmem folio to non-0 order"); |
| 3026 | 3023 | return -EINVAL; |
| 3027 | 3024 | } |
| 3028 | − /* No split if the file system does not support large folio */ | |
| 3029 | − if (!mapping_large_folio_support(folio->mapping)) { | |
| 3025 | + /* | |
| 3026 | + * No split if the file system does not support large folio. | |
| 3027 | + * Note that we might still have THPs in such mappings due to | |
| 3028 | + * CONFIG_READ_ONLY_THP_FOR_FS. But in that case, the mapping | |
| 3029 | + * does not actually support large folios properly. | |
| 3030 | + */ | |
| 3031 | + if (IS_ENABLED(CONFIG_READ_ONLY_THP_FOR_FS) && | |
| 3032 | + !mapping_large_folio_support(folio->mapping)) { | |
| 3030 | 3033 | VM_WARN_ONCE(1, |
| 3031 | 3034 | "Cannot split file folio to non-0 order"); |
| 3032 | 3035 | return -EINVAL; |
| 3033 | 3036 | } |
| 3034 | 3037 | } |
| 3035 | 3038 | |
| 3039 | + /* Only swapping a whole PMD-mapped folio is supported */ | |
| 3040 | + if (folio_test_swapcache(folio) && new_order) | |
| 3041 | + return -EINVAL; | |
| 3036 | 3042 | |
| 3037 | 3043 | is_hzp = is_huge_zero_folio(folio); |
| 3038 | 3044 | if (is_hzp) { |
| @@ -588,7 +588,6 @@ extern void __putback_isolated_page(struct page *page, unsigned int order, · 587 unmodified lines | ||
| 588 | 588 | extern void memblock_free_pages(struct page *page, unsigned long pfn, |
| 589 | 589 | unsigned int order); |
| 590 | 590 | extern void __free_pages_core(struct page *page, unsigned int order); |
| 591 | −extern void kernel_init_pages(struct page *page, int numpages); | |
| 592 | 591 | |
| 593 | 592 | /* |
| 594 | 593 | * This will have no effect, other than possibly generating a warning, if the |
| @@ -754,7 +754,7 @@ bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_byt · 753 unmodified lines | ||
| 754 | 754 | |
| 755 | 755 | /* calculate lose page */ |
| 756 | 756 | for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) { |
| 757 | − if (nid == NUMA_NO_NODE) | |
| 757 | + if (!numa_valid_node(nid)) | |
| 758 | 758 | nr_pages += end_pfn - start_pfn; |
| 759 | 759 | } |
| 760 | 760 | |
| @@ -1061,7 +1061,7 @@ static bool should_skip_region(struct memblock_type *type, · 300 unmodified lines | ||
| 1061 | 1061 | return false; |
| 1062 | 1062 | |
| 1063 | 1063 | /* only memory regions are associated with nodes, check it */ |
| 1064 | − if (nid != NUMA_NO_NODE && nid != m_nid) | |
| 1064 | + if (numa_valid_node(nid) && nid != m_nid) | |
| 1065 | 1065 | return true; |
| 1066 | 1066 | |
| 1067 | 1067 | /* skip hotpluggable memory regions if needed */ |
| @@ -1118,10 +1118,6 @@ void __next_mem_range(u64 *idx, int nid, enum memblock_flags flags, · 50 unmodified lines | ||
| 1118 | 1118 | int idx_a = *idx & 0xffffffff; |
| 1119 | 1119 | int idx_b = *idx >> 32; |
| 1120 | 1120 | |
| 1121 | − if (WARN_ONCE(nid == MAX_NUMNODES, | |
| 1122 | − "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) | |
| 1123 | − nid = NUMA_NO_NODE; | |
| 1124 | − | |
| 1125 | 1121 | for (; idx_a < type_a->cnt; idx_a++) { |
| 1126 | 1122 | struct memblock_region *m = &type_a->regions[idx_a]; |
| 1127 | 1123 | |
| @@ -1215,9 +1211,6 @@ void __init_memblock __next_mem_range_rev(u64 *idx, int nid, · 87 unmodified lines | ||
| 1215 | 1211 | int idx_a = *idx & 0xffffffff; |
| 1216 | 1212 | int idx_b = *idx >> 32; |
| 1217 | 1213 | |
| 1218 | − if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) | |
| 1219 | − nid = NUMA_NO_NODE; | |
| 1220 | − | |
| 1221 | 1214 | if (*idx == (u64)ULLONG_MAX) { |
| 1222 | 1215 | idx_a = type_a->cnt - 1; |
| 1223 | 1216 | if (type_b != NULL) |
| @@ -1303,7 +1296,7 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid, · 79 unmodified lines | ||
| 1303 | 1296 | |
| 1304 | 1297 | if (PFN_UP(r->base) >= PFN_DOWN(r->base + r->size)) |
| 1305 | 1298 | continue; |
| 1306 | − if (nid == MAX_NUMNODES || nid == r_nid) | |
| 1299 | + if (!numa_valid_node(nid) || nid == r_nid) | |
| 1307 | 1300 | break; |
| 1308 | 1301 | } |
| 1309 | 1302 | if (*idx >= type->cnt) { |
| @@ -1339,10 +1332,6 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size, · 29 unmodified lines | ||
| 1339 | 1332 | int start_rgn, end_rgn; |
| 1340 | 1333 | int i, ret; |
| 1341 | 1334 | |
| 1342 | − if (WARN_ONCE(nid == MAX_NUMNODES, | |
| 1343 | − "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) | |
| 1344 | − nid = NUMA_NO_NODE; | |
| 1345 | − | |
| 1346 | 1335 | ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn); |
| 1347 | 1336 | if (ret) |
| 1348 | 1337 | return ret; |
| @@ -1452,9 +1441,6 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, · 103 unmodified lines | ||
| 1452 | 1441 | enum memblock_flags flags = choose_memblock_flags(); |
| 1453 | 1442 | phys_addr_t found; |
| 1454 | 1443 | |
| 1455 | − if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) | |
| 1456 | − nid = NUMA_NO_NODE; | |
| 1457 | − | |
| 1458 | 1444 | if (!align) { |
| 1459 | 1445 | /* Can't use WARNs this early in boot on powerpc */ |
| 1460 | 1446 | dump_stack(); |
| @@ -1467,7 +1453,7 @@ again: · 6 unmodified lines | ||
| 1467 | 1453 | if (found && !memblock_reserve(found, size)) |
| 1468 | 1454 | goto done; |
| 1469 | 1455 | |
| 1470 | − if (nid != NUMA_NO_NODE && !exact_nid) { | |
| 1456 | + if (numa_valid_node(nid) && !exact_nid) { | |
| 1471 | 1457 | found = memblock_find_in_range_node(size, align, start, |
| 1472 | 1458 | end, NUMA_NO_NODE, |
| 1473 | 1459 | flags); |
| @@ -1987,7 +1973,7 @@ static void __init_memblock memblock_dump(struct memblock_type *type) · 513 unmodified lines | ||
| 1987 | 1973 | end = base + size - 1; |
| 1988 | 1974 | flags = rgn->flags; |
| 1989 | 1975 | #ifdef CONFIG_NUMA |
| 1990 | − if (memblock_get_region_node(rgn) != MAX_NUMNODES) | |
| 1976 | + if (numa_valid_node(memblock_get_region_node(rgn))) | |
| 1991 | 1977 | snprintf(nid_buf, sizeof(nid_buf), " on node %d", |
| 1992 | 1978 | memblock_get_region_node(rgn)); |
| 1993 | 1979 | #endif |
| @@ -2181,7 +2167,7 @@ static void __init memmap_init_reserved_pages(void) · 187 unmodified lines | ||
| 2181 | 2167 | start = region->base; |
| 2182 | 2168 | end = start + region->size; |
| 2183 | 2169 | |
| 2184 | − if (nid == NUMA_NO_NODE || nid >= MAX_NUMNODES) | |
| 2170 | + if (!numa_valid_node(nid)) | |
| 2185 | 2171 | nid = early_pfn_to_nid(PFN_DOWN(start)); |
| 2186 | 2172 | |
| 2187 | 2173 | reserve_bootmem_region(start, end, nid); |
| @@ -2272,7 +2258,7 @@ static int memblock_debug_show(struct seq_file *m, void *private) · 84 unmodified lines | ||
| 2272 | 2258 | |
| 2273 | 2259 | seq_printf(m, "%4d: ", i); |
| 2274 | 2260 | seq_printf(m, "%pa..%pa ", ®->base, &end); |
| 2275 | − if (nid != MAX_NUMNODES) | |
| 2261 | + if (numa_valid_node(nid)) | |
| 2276 | 2262 | seq_printf(m, "%4d ", nid); |
| 2277 | 2263 | else |
| 2278 | 2264 | seq_printf(m, "%4c ", 'x'); |
| @@ -7745,8 +7745,7 @@ void __mem_cgroup_uncharge_folios(struct folio_batch *folios) · 7744 unmodified lines | ||
| 7745 | 7745 | * @new: Replacement folio. |
| 7746 | 7746 | * |
| 7747 | 7747 | * Charge @new as a replacement folio for @old. @old will |
| 7748 | − * be uncharged upon free. This is only used by the page cache | |
| 7749 | − * (in replace_page_cache_folio()). | |
| 7748 | + * be uncharged upon free. | |
| 7750 | 7749 | * |
| 7751 | 7750 | * Both folios must be locked, @new->mapping must be set up. |
| 7752 | 7751 | */ |
| @@ -1507,12 +1507,6 @@ static __always_inline void zap_present_folio_ptes(struct mmu_gather *tlb, · 1506 unmodified lines | ||
| 1507 | 1507 | if (unlikely(folio_mapcount(folio) < 0)) |
| 1508 | 1508 | print_bad_pte(vma, addr, ptent, page); |
| 1509 | 1509 | } |
| 1510 | − | |
| 1511 | − if (want_init_mlocked_on_free() && folio_test_mlocked(folio) && | |
| 1512 | − !delay_rmap && folio_test_anon(folio)) { | |
| 1513 | − kernel_init_pages(page, folio_nr_pages(folio)); | |
| 1514 | − } | |
| 1515 | − | |
| 1516 | 1510 | if (unlikely(__tlb_remove_folio_pages(tlb, page, nr, delay_rmap))) { |
| 1517 | 1511 | *force_flush = true; |
| 1518 | 1512 | *force_break = true; |
| @@ -5106,10 +5100,16 @@ static void numa_rebuild_large_mapping(struct vm_fault *vmf, struct vm_area_stru · 3587 unmodified lines | ||
| 5106 | 5100 | bool ignore_writable, bool pte_write_upgrade) |
| 5107 | 5101 | { |
| 5108 | 5102 | int nr = pte_pfn(fault_pte) - folio_pfn(folio); |
| 5109 | − unsigned long start = max(vmf->address - nr * PAGE_SIZE, vma->vm_start); | |
| 5110 | − unsigned long end = min(vmf->address + (folio_nr_pages(folio) - nr) * PAGE_SIZE, vma->vm_end); | |
| 5111 | − pte_t *start_ptep = vmf->pte - (vmf->address - start) / PAGE_SIZE; | |
| 5112 | − unsigned long addr; | |
| 5103 | + unsigned long start, end, addr = vmf->address; | |
| 5104 | + unsigned long addr_start = addr - (nr << PAGE_SHIFT); | |
| 5105 | + unsigned long pt_start = ALIGN_DOWN(addr, PMD_SIZE); | |
| 5106 | + pte_t *start_ptep; | |
| 5107 | + | |
| 5108 | + /* Stay within the VMA and within the page table. */ | |
| 5109 | + start = max3(addr_start, pt_start, vma->vm_start); | |
| 5110 | + end = min3(addr_start + folio_size(folio), pt_start + PMD_SIZE, | |
| 5111 | + vma->vm_end); | |
| 5112 | + start_ptep = vmf->pte - ((addr - start) >> PAGE_SHIFT); | |
| 5113 | 5113 | |
| 5114 | 5114 | /* Restore all PTEs' mapping of the large folio */ |
| 5115 | 5115 | for (addr = start; addr != end; start_ptep++, addr += PAGE_SIZE) { |
| @@ -1654,7 +1654,12 @@ static int migrate_pages_batch(struct list_head *from, · 1653 unmodified lines | ||
| 1654 | 1654 | |
| 1655 | 1655 | /* |
| 1656 | 1656 | * The rare folio on the deferred split list should |
| 1657 | − * be split now. It should not count as a failure. | |
| 1657 | + * be split now. It should not count as a failure: | |
| 1658 | + * but increment nr_failed because, without doing so, | |
| 1659 | + * migrate_pages() may report success with (split but | |
| 1660 | + * unmigrated) pages still on its fromlist; whereas it | |
| 1661 | + * always reports success when its fromlist is empty. | |
| 1662 | + * | |
| 1658 | 1663 | * Only check it without removing it from the list. |
| 1659 | 1664 | * Since the folio can be on deferred_split_scan() |
| 1660 | 1665 | * local list and removing it can cause the local list |
| @@ -1669,6 +1674,7 @@ static int migrate_pages_batch(struct list_head *from, · 8 unmodified lines | ||
| 1669 | 1674 | if (nr_pages > 2 && |
| 1670 | 1675 | !list_empty(&folio->_deferred_list)) { |
| 1671 | 1676 | if (try_split_folio(folio, split_folios) == 0) { |
| 1677 | + nr_failed++; | |
| 1672 | 1678 | stats->nr_thp_split += is_thp; |
| 1673 | 1679 | stats->nr_split++; |
| 1674 | 1680 | continue; |
| @@ -2523,9 +2523,6 @@ EXPORT_SYMBOL(init_on_alloc); · 2522 unmodified lines | ||
| 2523 | 2523 | DEFINE_STATIC_KEY_MAYBE(CONFIG_INIT_ON_FREE_DEFAULT_ON, init_on_free); |
| 2524 | 2524 | EXPORT_SYMBOL(init_on_free); |
| 2525 | 2525 | |
| 2526 | −DEFINE_STATIC_KEY_MAYBE(CONFIG_INIT_MLOCKED_ON_FREE_DEFAULT_ON, init_mlocked_on_free); | |
| 2527 | −EXPORT_SYMBOL(init_mlocked_on_free); | |
| 2528 | − | |
| 2529 | 2526 | static bool _init_on_alloc_enabled_early __read_mostly |
| 2530 | 2527 | = IS_ENABLED(CONFIG_INIT_ON_ALLOC_DEFAULT_ON); |
| 2531 | 2528 | static int __init early_init_on_alloc(char *buf) |
| @@ -2543,14 +2540,6 @@ static int __init early_init_on_free(char *buf) · 11 unmodified lines | ||
| 2543 | 2540 | } |
| 2544 | 2541 | early_param("init_on_free", early_init_on_free); |
| 2545 | 2542 | |
| 2546 | −static bool _init_mlocked_on_free_enabled_early __read_mostly | |
| 2547 | − = IS_ENABLED(CONFIG_INIT_MLOCKED_ON_FREE_DEFAULT_ON); | |
| 2548 | −static int __init early_init_mlocked_on_free(char *buf) | |
| 2549 | −{ | |
| 2550 | − return kstrtobool(buf, &_init_mlocked_on_free_enabled_early); | |
| 2551 | −} | |
| 2552 | −early_param("init_mlocked_on_free", early_init_mlocked_on_free); | |
| 2553 | − | |
| 2554 | 2543 | DEFINE_STATIC_KEY_MAYBE(CONFIG_DEBUG_VM, check_pages_enabled); |
| 2555 | 2544 | |
| 2556 | 2545 | /* |
| @@ -2578,21 +2567,12 @@ static void __init mem_debugging_and_hardening_init(void) · 21 unmodified lines | ||
| 2578 | 2567 | } |
| 2579 | 2568 | #endif |
| 2580 | 2569 | |
| 2581 | − if ((_init_on_alloc_enabled_early || _init_on_free_enabled_early || | |
| 2582 | − _init_mlocked_on_free_enabled_early) && | |
| 2570 | + if ((_init_on_alloc_enabled_early || _init_on_free_enabled_early) && | |
| 2583 | 2571 | page_poisoning_requested) { |
| 2584 | 2572 | pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, " |
| 2585 | − "will take precedence over init_on_alloc, init_on_free " | |
| 2586 | − "and init_mlocked_on_free\n"); | |
| 2573 | + "will take precedence over init_on_alloc and init_on_free\n"); | |
| 2587 | 2574 | _init_on_alloc_enabled_early = false; |
| 2588 | 2575 | _init_on_free_enabled_early = false; |
| 2589 | − _init_mlocked_on_free_enabled_early = false; | |
| 2590 | − } | |
| 2591 | − | |
| 2592 | − if (_init_mlocked_on_free_enabled_early && _init_on_free_enabled_early) { | |
| 2593 | − pr_info("mem auto-init: init_on_free is on, " | |
| 2594 | − "will take precedence over init_mlocked_on_free\n"); | |
| 2595 | − _init_mlocked_on_free_enabled_early = false; | |
| 2596 | 2576 | } |
| 2597 | 2577 | |
| 2598 | 2578 | if (_init_on_alloc_enabled_early) { |
| @@ -2609,17 +2589,9 @@ static void __init mem_debugging_and_hardening_init(void) · 10 unmodified lines | ||
| 2609 | 2589 | static_branch_disable(&init_on_free); |
| 2610 | 2590 | } |
| 2611 | 2591 | |
| 2612 | − if (_init_mlocked_on_free_enabled_early) { | |
| 2613 | − want_check_pages = true; | |
| 2614 | − static_branch_enable(&init_mlocked_on_free); | |
| 2615 | − } else { | |
| 2616 | − static_branch_disable(&init_mlocked_on_free); | |
| 2617 | − } | |
| 2618 | − | |
| 2619 | − if (IS_ENABLED(CONFIG_KMSAN) && (_init_on_alloc_enabled_early || | |
| 2620 | − _init_on_free_enabled_early || _init_mlocked_on_free_enabled_early)) | |
| 2621 | − pr_info("mem auto-init: please make sure init_on_alloc, init_on_free and " | |
| 2622 | − "init_mlocked_on_free are disabled when running KMSAN\n"); | |
| 2592 | + if (IS_ENABLED(CONFIG_KMSAN) && | |
| 2593 | + (_init_on_alloc_enabled_early || _init_on_free_enabled_early)) | |
| 2594 | + pr_info("mem auto-init: please make sure init_on_alloc and init_on_free are disabled when running KMSAN\n"); | |
| 2623 | 2595 | |
| 2624 | 2596 | #ifdef CONFIG_DEBUG_PAGEALLOC |
| 2625 | 2597 | if (debug_pagealloc_enabled()) { |
| @@ -2658,10 +2630,9 @@ static void __init report_meminit(void) · 32 unmodified lines | ||
| 2658 | 2630 | else |
| 2659 | 2631 | stack = "off"; |
| 2660 | 2632 | |
| 2661 | − pr_info("mem auto-init: stack:%s, heap alloc:%s, heap free:%s, mlocked free:%s\n", | |
| 2633 | + pr_info("mem auto-init: stack:%s, heap alloc:%s, heap free:%s\n", | |
| 2662 | 2634 | stack, want_init_on_alloc(GFP_KERNEL) ? "on" : "off", |
| 2663 | − want_init_on_free() ? "on" : "off", | |
| 2664 | − want_init_mlocked_on_free() ? "on" : "off"); | |
| 2635 | + want_init_on_free() ? "on" : "off"); | |
| 2665 | 2636 | if (want_init_on_free()) |
| 2666 | 2637 | pr_info("mem auto-init: clearing system memory may take some time...\n"); |
| 2667 | 2638 | } |
| @@ -1016,7 +1016,7 @@ static inline bool should_skip_kasan_poison(struct page *page) · 1015 unmodified lines | ||
| 1016 | 1016 | return page_kasan_tag(page) == KASAN_TAG_KERNEL; |
| 1017 | 1017 | } |
| 1018 | 1018 | |
| 1019 | −void kernel_init_pages(struct page *page, int numpages) | |
| 1019 | +static void kernel_init_pages(struct page *page, int numpages) | |
| 1020 | 1020 | { |
| 1021 | 1021 | int i; |
| 1022 | 1022 | |
| @@ -73,6 +73,9 @@ static void page_table_check_clear(unsigned long pfn, unsigned long pgcnt) · 72 unmodified lines | ||
| 73 | 73 | page = pfn_to_page(pfn); |
| 74 | 74 | page_ext = page_ext_get(page); |
| 75 | 75 | |
| 76 | + if (!page_ext) | |
| 77 | + return; | |
| 78 | + | |
| 76 | 79 | BUG_ON(PageSlab(page)); |
| 77 | 80 | anon = PageAnon(page); |
| 78 | 81 | |
| @@ -110,6 +113,9 @@ static void page_table_check_set(unsigned long pfn, unsigned long pgcnt, · 31 unmodified lines | ||
| 110 | 113 | page = pfn_to_page(pfn); |
| 111 | 114 | page_ext = page_ext_get(page); |
| 112 | 115 | |
| 116 | + if (!page_ext) | |
| 117 | + return; | |
| 118 | + | |
| 113 | 119 | BUG_ON(PageSlab(page)); |
| 114 | 120 | anon = PageAnon(page); |
| 115 | 121 | |
| @@ -140,7 +146,10 @@ void __page_table_check_zero(struct page *page, unsigned int order) · 24 unmodified lines | ||
| 140 | 146 | BUG_ON(PageSlab(page)); |
| 141 | 147 | |
| 142 | 148 | page_ext = page_ext_get(page); |
| 143 | − BUG_ON(!page_ext); | |
| 149 | + | |
| 150 | + if (!page_ext) | |
| 151 | + return; | |
| 152 | + | |
| 144 | 153 | for (i = 0; i < (1ul << order); i++) { |
| 145 | 154 | struct page_table_check *ptc = get_page_table_check(page_ext); |
| 146 | 155 | |
| @@ -1786,7 +1786,7 @@ static int shmem_replace_folio(struct folio **foliop, gfp_t gfp, · 1785 unmodified lines | ||
| 1786 | 1786 | xa_lock_irq(&swap_mapping->i_pages); |
| 1787 | 1787 | error = shmem_replace_entry(swap_mapping, swap_index, old, new); |
| 1788 | 1788 | if (!error) { |
| 1789 | − mem_cgroup_migrate(old, new); | |
| 1789 | + mem_cgroup_replace_folio(old, new); | |
| 1790 | 1790 | __lruvec_stat_mod_folio(new, NR_FILE_PAGES, 1); |
| 1791 | 1791 | __lruvec_stat_mod_folio(new, NR_SHMEM, 1); |
| 1792 | 1792 | __lruvec_stat_mod_folio(old, NR_FILE_PAGES, -1); |
| @@ -139,14 +139,14 @@ EXPORT_SYMBOL(kmemdup_noprof); · 138 unmodified lines | ||
| 139 | 139 | * kmemdup_array - duplicate a given array. |
| 140 | 140 | * |
| 141 | 141 | * @src: array to duplicate. |
| 142 | − * @element_size: size of each element of array. | |
| 143 | 142 | * @count: number of elements to duplicate from array. |
| 143 | + * @element_size: size of each element of array. | |
| 144 | 144 | * @gfp: GFP mask to use. |
| 145 | 145 | * |
| 146 | 146 | * Return: duplicated array of @src or %NULL in case of error, |
| 147 | 147 | * result is physically contiguous. Use kfree() to free. |
| 148 | 148 | */ |
| 149 | −void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp) | |
| 149 | +void *kmemdup_array(const void *src, size_t count, size_t element_size, gfp_t gfp) | |
| 150 | 150 | { |
| 151 | 151 | return kmemdup(src, size_mul(element_size, count), gfp); |
| 152 | 152 | } |
| @@ -1665,6 +1665,11 @@ static DEFINE_PER_CPU(struct bpf_scratchpad, bpf_sp); · 1664 unmodified lines | ||
| 1665 | 1665 | static inline int __bpf_try_make_writable(struct sk_buff *skb, |
| 1666 | 1666 | unsigned int write_len) |
| 1667 | 1667 | { |
| 1668 | +#ifdef CONFIG_DEBUG_NET | |
| 1669 | + /* Avoid a splat in pskb_may_pull_reason() */ | |
| 1670 | + if (write_len > INT_MAX) | |
| 1671 | + return -EINVAL; | |
| 1672 | +#endif | |
| 1668 | 1673 | return skb_ensure_writable(skb, write_len); |
| 1669 | 1674 | } |
| 1670 | 1675 | |
| @@ -693,11 +693,16 @@ EXPORT_SYMBOL_GPL(__put_net); · 692 unmodified lines | ||
| 693 | 693 | * get_net_ns - increment the refcount of the network namespace |
| 694 | 694 | * @ns: common namespace (net) |
| 695 | 695 | * |
| 696 | − * Returns the net's common namespace. | |
| 696 | + * Returns the net's common namespace or ERR_PTR() if ref is zero. | |
| 697 | 697 | */ |
| 698 | 698 | struct ns_common *get_net_ns(struct ns_common *ns) |
| 699 | 699 | { |
| 700 | − return &get_net(container_of(ns, struct net, ns))->ns; | |
| 700 | + struct net *net; | |
| 701 | + | |
| 702 | + net = maybe_get_net(container_of(ns, struct net, ns)); | |
| 703 | + if (net) | |
| 704 | + return &net->ns; | |
| 705 | + return ERR_PTR(-EINVAL); | |
| 701 | 706 | } |
| 702 | 707 | EXPORT_SYMBOL_GPL(get_net_ns); |
| 703 | 708 | |
| @@ -59,22 +59,22 @@ XDP_METADATA_KFUNC_xxx · 58 unmodified lines | ||
| 59 | 59 | nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_RX_METADATA_FEATURES, |
| 60 | 60 | xdp_rx_meta, NETDEV_A_DEV_PAD) || |
| 61 | 61 | nla_put_u64_64bit(rsp, NETDEV_A_DEV_XSK_FEATURES, |
| 62 | − xsk_features, NETDEV_A_DEV_PAD)) { | |
| 63 | − genlmsg_cancel(rsp, hdr); | |
| 64 | − return -EINVAL; | |
| 65 | − } | |
| 62 | + xsk_features, NETDEV_A_DEV_PAD)) | |
| 63 | + goto err_cancel_msg; | |
| 66 | 64 | |
| 67 | 65 | if (netdev->xdp_features & NETDEV_XDP_ACT_XSK_ZEROCOPY) { |
| 68 | 66 | if (nla_put_u32(rsp, NETDEV_A_DEV_XDP_ZC_MAX_SEGS, |
| 69 | − netdev->xdp_zc_max_segs)) { | |
| 70 | − genlmsg_cancel(rsp, hdr); | |
| 71 | − return -EINVAL; | |
| 72 | − } | |
| 67 | + netdev->xdp_zc_max_segs)) | |
| 68 | + goto err_cancel_msg; | |
| 73 | 69 | } |
| 74 | 70 | |
| 75 | 71 | genlmsg_end(rsp, hdr); |
| 76 | 72 | |
| 77 | 73 | return 0; |
| 74 | + | |
| 75 | +err_cancel_msg: | |
| 76 | + genlmsg_cancel(rsp, hdr); | |
| 77 | + return -EMSGSIZE; | |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | 80 | static void |
| @@ -3742,6 +3742,9 @@ void sk_common_release(struct sock *sk) · 3741 unmodified lines | ||
| 3742 | 3742 | |
| 3743 | 3743 | sk->sk_prot->unhash(sk); |
| 3744 | 3744 | |
| 3745 | + if (sk->sk_socket) | |
| 3746 | + sk->sk_socket->sk = NULL; | |
| 3747 | + | |
| 3745 | 3748 | /* |
| 3746 | 3749 | * In this point socket cannot receive new packets, but it is possible |
| 3747 | 3750 | * that some packets are in flight because some CPU runs receiver and |
| @@ -1810,6 +1810,29 @@ static int cipso_v4_genopt(unsigned char *buf, u32 buf_len, · 1809 unmodified lines | ||
| 1810 | 1810 | return CIPSO_V4_HDR_LEN + ret_val; |
| 1811 | 1811 | } |
| 1812 | 1812 | |
| 1813 | +static int cipso_v4_get_actual_opt_len(const unsigned char *data, int len) | |
| 1814 | +{ | |
| 1815 | + int iter = 0, optlen = 0; | |
| 1816 | + | |
| 1817 | + /* determining the new total option length is tricky because of | |
| 1818 | + * the padding necessary, the only thing i can think to do at | |
| 1819 | + * this point is walk the options one-by-one, skipping the | |
| 1820 | + * padding at the end to determine the actual option size and | |
| 1821 | + * from there we can determine the new total option length | |
| 1822 | + */ | |
| 1823 | + while (iter < len) { | |
| 1824 | + if (data[iter] == IPOPT_END) { | |
| 1825 | + break; | |
| 1826 | + } else if (data[iter] == IPOPT_NOP) { | |
| 1827 | + iter++; | |
| 1828 | + } else { | |
| 1829 | + iter += data[iter + 1]; | |
| 1830 | + optlen = iter; | |
| 1831 | + } | |
| 1832 | + } | |
| 1833 | + return optlen; | |
| 1834 | +} | |
| 1835 | + | |
| 1813 | 1836 | /** |
| 1814 | 1837 | * cipso_v4_sock_setattr - Add a CIPSO option to a socket |
| 1815 | 1838 | * @sk: the socket |
| @@ -1986,7 +2009,6 @@ static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr) · 170 unmodified lines | ||
| 1986 | 2009 | u8 cipso_len; |
| 1987 | 2010 | u8 cipso_off; |
| 1988 | 2011 | unsigned char *cipso_ptr; |
| 1989 | − int iter; | |
| 1990 | 2012 | int optlen_new; |
| 1991 | 2013 | |
| 1992 | 2014 | cipso_off = opt->opt.cipso - sizeof(struct iphdr); |
| @@ -2006,19 +2028,8 @@ static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr) · 13 unmodified lines | ||
| 2006 | 2028 | memmove(cipso_ptr, cipso_ptr + cipso_len, |
| 2007 | 2029 | opt->opt.optlen - cipso_off - cipso_len); |
| 2008 | 2030 | |
| 2009 | − /* determining the new total option length is tricky because of | |
| 2010 | − * the padding necessary, the only thing i can think to do at | |
| 2011 | − * this point is walk the options one-by-one, skipping the | |
| 2012 | − * padding at the end to determine the actual option size and | |
| 2013 | − * from there we can determine the new total option length */ | |
| 2014 | − iter = 0; | |
| 2015 | − optlen_new = 0; | |
| 2016 | − while (iter < opt->opt.optlen) | |
| 2017 | − if (opt->opt.__data[iter] != IPOPT_NOP) { | |
| 2018 | − iter += opt->opt.__data[iter + 1]; | |
| 2019 | − optlen_new = iter; | |
| 2020 | − } else | |
| 2021 | − iter++; | |
| 2031 | + optlen_new = cipso_v4_get_actual_opt_len(opt->opt.__data, | |
| 2032 | + opt->opt.optlen); | |
| 2022 | 2033 | hdr_delta = opt->opt.optlen; |
| 2023 | 2034 | opt->opt.optlen = (optlen_new + 3) & ~3; |
| 2024 | 2035 | hdr_delta -= opt->opt.optlen; |
| @@ -2238,7 +2249,8 @@ int cipso_v4_skbuff_setattr(struct sk_buff *skb, · 213 unmodified lines | ||
| 2238 | 2249 | */ |
| 2239 | 2250 | int cipso_v4_skbuff_delattr(struct sk_buff *skb) |
| 2240 | 2251 | { |
| 2241 | − int ret_val; | |
| 2252 | + int ret_val, cipso_len, hdr_len_actual, new_hdr_len_actual, new_hdr_len, | |
| 2253 | + hdr_len_delta; | |
| 2242 | 2254 | struct iphdr *iph; |
| 2243 | 2255 | struct ip_options *opt = &IPCB(skb)->opt; |
| 2244 | 2256 | unsigned char *cipso_ptr; |
| @@ -2251,16 +2263,37 @@ int cipso_v4_skbuff_delattr(struct sk_buff *skb) · 6 unmodified lines | ||
| 2251 | 2263 | if (ret_val < 0) |
| 2252 | 2264 | return ret_val; |
| 2253 | 2265 | |
| 2254 | − /* the easiest thing to do is just replace the cipso option with noop | |
| 2255 | − * options since we don't change the size of the packet, although we | |
| 2256 | − * still need to recalculate the checksum */ | |
| 2257 | − | |
| 2258 | 2266 | iph = ip_hdr(skb); |
| 2259 | 2267 | cipso_ptr = (unsigned char *)iph + opt->cipso; |
| 2260 | − memset(cipso_ptr, IPOPT_NOOP, cipso_ptr[1]); | |
| 2268 | + cipso_len = cipso_ptr[1]; | |
| 2269 | + | |
| 2270 | + hdr_len_actual = sizeof(struct iphdr) + | |
| 2271 | + cipso_v4_get_actual_opt_len((unsigned char *)(iph + 1), | |
| 2272 | + opt->optlen); | |
| 2273 | + new_hdr_len_actual = hdr_len_actual - cipso_len; | |
| 2274 | + new_hdr_len = (new_hdr_len_actual + 3) & ~3; | |
| 2275 | + hdr_len_delta = (iph->ihl << 2) - new_hdr_len; | |
| 2276 | + | |
| 2277 | + /* 1. shift any options after CIPSO to the left */ | |
| 2278 | + memmove(cipso_ptr, cipso_ptr + cipso_len, | |
| 2279 | + new_hdr_len_actual - opt->cipso); | |
| 2280 | + /* 2. move the whole IP header to its new place */ | |
| 2281 | + memmove((unsigned char *)iph + hdr_len_delta, iph, new_hdr_len_actual); | |
| 2282 | + /* 3. adjust the skb layout */ | |
| 2283 | + skb_pull(skb, hdr_len_delta); | |
| 2284 | + skb_reset_network_header(skb); | |
| 2285 | + iph = ip_hdr(skb); | |
| 2286 | + /* 4. re-fill new padding with IPOPT_END (may now be longer) */ | |
| 2287 | + memset((unsigned char *)iph + new_hdr_len_actual, IPOPT_END, | |
| 2288 | + new_hdr_len - new_hdr_len_actual); | |
| 2289 | + | |
| 2290 | + opt->optlen -= hdr_len_delta; | |
| 2261 | 2291 | opt->cipso = 0; |
| 2262 | 2292 | opt->is_changed = 1; |
| 2263 | − | |
| 2293 | + if (hdr_len_delta != 0) { | |
| 2294 | + iph->ihl = new_hdr_len >> 2; | |
| 2295 | + iph_set_totlen(iph, skb->len); | |
| 2296 | + } | |
| 2264 | 2297 | ip_send_check(iph); |
| 2265 | 2298 | |
| 2266 | 2299 | return 0; |
| @@ -1968,8 +1968,10 @@ static int tcp_ao_info_cmd(struct sock *sk, unsigned short int family, · 1967 unmodified lines | ||
| 1968 | 1968 | first = true; |
| 1969 | 1969 | } |
| 1970 | 1970 | |
| 1971 | − if (cmd.ao_required && tcp_ao_required_verify(sk)) | |
| 1972 | − return -EKEYREJECTED; | |
| 1971 | + if (cmd.ao_required && tcp_ao_required_verify(sk)) { | |
| 1972 | + err = -EKEYREJECTED; | |
| 1973 | + goto out; | |
| 1974 | + } | |
| 1973 | 1975 | |
| 1974 | 1976 | /* For sockets in TCP_CLOSED it's possible set keys that aren't |
| 1975 | 1977 | * matching the future peer (address/port/VRF/etc), |
| @@ -6296,6 +6296,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, · 6295 unmodified lines | ||
| 6296 | 6296 | skb_rbtree_walk_from(data) |
| 6297 | 6297 | tcp_mark_skb_lost(sk, data); |
| 6298 | 6298 | tcp_xmit_retransmit_queue(sk); |
| 6299 | + tp->retrans_stamp = 0; | |
| 6299 | 6300 | NET_INC_STATS(sock_net(sk), |
| 6300 | 6301 | LINUX_MIB_TCPFASTOPENACTIVEFAIL); |
| 6301 | 6302 | return true; |
| @@ -2514,7 +2514,8 @@ int __init fib6_init(void) · 2513 unmodified lines | ||
| 2514 | 2514 | goto out_kmem_cache_create; |
| 2515 | 2515 | |
| 2516 | 2516 | ret = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_GETROUTE, NULL, |
| 2517 | − inet6_dump_fib, RTNL_FLAG_DUMP_UNLOCKED); | |
| 2517 | + inet6_dump_fib, RTNL_FLAG_DUMP_UNLOCKED | | |
| 2518 | + RTNL_FLAG_DUMP_SPLIT_NLM_DONE); | |
| 2518 | 2519 | if (ret) |
| 2519 | 2520 | goto out_unregister_subsys; |
| 2520 | 2521 | |
| @@ -638,6 +638,8 @@ static void rt6_probe(struct fib6_nh *fib6_nh) · 637 unmodified lines | ||
| 638 | 638 | rcu_read_lock(); |
| 639 | 639 | last_probe = READ_ONCE(fib6_nh->last_probe); |
| 640 | 640 | idev = __in6_dev_get(dev); |
| 641 | + if (!idev) | |
| 642 | + goto out; | |
| 641 | 643 | neigh = __ipv6_neigh_lookup_noref(dev, nh_gw); |
| 642 | 644 | if (neigh) { |
| 643 | 645 | if (READ_ONCE(neigh->nud_state) & NUD_VALID) |
| @@ -3603,7 +3605,7 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, · 2959 unmodified lines | ||
| 3603 | 3605 | if (!dev) |
| 3604 | 3606 | goto out; |
| 3605 | 3607 | |
| 3606 | − if (idev->cnf.disable_ipv6) { | |
| 3608 | + if (!idev || idev->cnf.disable_ipv6) { | |
| 3607 | 3609 | NL_SET_ERR_MSG(extack, "IPv6 is disabled on nexthop device"); |
| 3608 | 3610 | err = -EACCES; |
| 3609 | 3611 | goto out; |
| @@ -941,8 +941,8 @@ static int input_action_end_dx6(struct sk_buff *skb, · 940 unmodified lines | ||
| 941 | 941 | |
| 942 | 942 | if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) |
| 943 | 943 | return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, |
| 944 | − dev_net(skb->dev), NULL, skb, NULL, | |
| 945 | − skb_dst(skb)->dev, input_action_end_dx6_finish); | |
| 944 | + dev_net(skb->dev), NULL, skb, skb->dev, | |
| 945 | + NULL, input_action_end_dx6_finish); | |
| 946 | 946 | |
| 947 | 947 | return input_action_end_dx6_finish(dev_net(skb->dev), NULL, skb); |
| 948 | 948 | drop: |
| @@ -991,8 +991,8 @@ static int input_action_end_dx4(struct sk_buff *skb, · 42 unmodified lines | ||
| 991 | 991 | |
| 992 | 992 | if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) |
| 993 | 993 | return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, |
| 994 | − dev_net(skb->dev), NULL, skb, NULL, | |
| 995 | − skb_dst(skb)->dev, input_action_end_dx4_finish); | |
| 994 | + dev_net(skb->dev), NULL, skb, skb->dev, | |
| 995 | + NULL, input_action_end_dx4_finish); | |
| 996 | 996 | |
| 997 | 997 | return input_action_end_dx4_finish(dev_net(skb->dev), NULL, skb); |
| 998 | 998 | drop: |
| @@ -56,12 +56,18 @@ static int xfrm6_get_saddr(struct net *net, int oif, · 55 unmodified lines | ||
| 56 | 56 | { |
| 57 | 57 | struct dst_entry *dst; |
| 58 | 58 | struct net_device *dev; |
| 59 | + struct inet6_dev *idev; | |
| 59 | 60 | |
| 60 | 61 | dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr, mark); |
| 61 | 62 | if (IS_ERR(dst)) |
| 62 | 63 | return -EHOSTUNREACH; |
| 63 | 64 | |
| 64 | − dev = ip6_dst_idev(dst)->dev; | |
| 65 | + idev = ip6_dst_idev(dst); | |
| 66 | + if (!idev) { | |
| 67 | + dst_release(dst); | |
| 68 | + return -EHOSTUNREACH; | |
| 69 | + } | |
| 70 | + dev = idev->dev; | |
| 65 | 71 | ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6); |
| 66 | 72 | dst_release(dst); |
| 67 | 73 | return 0; |
| @@ -311,6 +311,18 @@ int drv_assign_vif_chanctx(struct ieee80211_local *local, · 310 unmodified lines | ||
| 311 | 311 | might_sleep(); |
| 312 | 312 | lockdep_assert_wiphy(local->hw.wiphy); |
| 313 | 313 | |
| 314 | + /* | |
| 315 | + * We should perhaps push emulate chanctx down and only | |
| 316 | + * make it call ->config() when the chanctx is actually | |
| 317 | + * assigned here (and unassigned below), but that's yet | |
| 318 | + * another change to all drivers to add assign/unassign | |
| 319 | + * emulation callbacks. Maybe later. | |
| 320 | + */ | |
| 321 | + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && | |
| 322 | + local->emulate_chanctx && | |
| 323 | + !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) | |
| 324 | + return 0; | |
| 325 | + | |
| 314 | 326 | if (!check_sdata_in_driver(sdata)) |
| 315 | 327 | return -EIO; |
| 316 | 328 | |
| @@ -338,6 +350,11 @@ void drv_unassign_vif_chanctx(struct ieee80211_local *local, · 21 unmodified lines | ||
| 338 | 350 | might_sleep(); |
| 339 | 351 | lockdep_assert_wiphy(local->hw.wiphy); |
| 340 | 352 | |
| 353 | + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && | |
| 354 | + local->emulate_chanctx && | |
| 355 | + !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) | |
| 356 | + return; | |
| 357 | + | |
| 341 | 358 | if (!check_sdata_in_driver(sdata)) |
| 342 | 359 | return; |
| 343 | 360 | |
| @@ -686,6 +686,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do · 685 unmodified lines | ||
| 686 | 686 | ieee80211_del_virtual_monitor(local); |
| 687 | 687 | |
| 688 | 688 | ieee80211_recalc_idle(local); |
| 689 | + ieee80211_recalc_offload(local); | |
| 689 | 690 | |
| 690 | 691 | if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) |
| 691 | 692 | break; |
| @@ -1121,9 +1122,6 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) · 429 unmodified lines | ||
| 1121 | 1122 | struct ieee80211_sub_if_data *sdata; |
| 1122 | 1123 | int ret; |
| 1123 | 1124 | |
| 1124 | − if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) | |
| 1125 | − return 0; | |
| 1126 | − | |
| 1127 | 1125 | ASSERT_RTNL(); |
| 1128 | 1126 | lockdep_assert_wiphy(local->hw.wiphy); |
| 1129 | 1127 | |
| @@ -1145,11 +1143,13 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) · 15 unmodified lines | ||
| 1145 | 1143 | |
| 1146 | 1144 | ieee80211_set_default_queues(sdata); |
| 1147 | 1145 | |
| 1148 | − ret = drv_add_interface(local, sdata); | |
| 1149 | − if (WARN_ON(ret)) { | |
| 1150 | − /* ok .. stupid driver, it asked for this! */ | |
| 1151 | − kfree(sdata); | |
| 1152 | − return ret; | |
| 1146 | + if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) { | |
| 1147 | + ret = drv_add_interface(local, sdata); | |
| 1148 | + if (WARN_ON(ret)) { | |
| 1149 | + /* ok .. stupid driver, it asked for this! */ | |
| 1150 | + kfree(sdata); | |
| 1151 | + return ret; | |
| 1152 | + } | |
| 1153 | 1153 | } |
| 1154 | 1154 | |
| 1155 | 1155 | set_bit(SDATA_STATE_RUNNING, &sdata->state); |
| @@ -1187,9 +1187,6 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) · 31 unmodified lines | ||
| 1187 | 1187 | { |
| 1188 | 1188 | struct ieee80211_sub_if_data *sdata; |
| 1189 | 1189 | |
| 1190 | − if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) | |
| 1191 | − return; | |
| 1192 | − | |
| 1193 | 1190 | ASSERT_RTNL(); |
| 1194 | 1191 | lockdep_assert_wiphy(local->hw.wiphy); |
| 1195 | 1192 | |
| @@ -1209,7 +1206,8 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) · 13 unmodified lines | ||
| 1209 | 1206 | |
| 1210 | 1207 | ieee80211_link_release_channel(&sdata->deflink); |
| 1211 | 1208 | |
| 1212 | − drv_remove_interface(local, sdata); | |
| 1209 | + if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) | |
| 1210 | + drv_remove_interface(local, sdata); | |
| 1213 | 1211 | |
| 1214 | 1212 | kfree(sdata); |
| 1215 | 1213 | } |
| @@ -358,7 +358,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_sub_if_data *sdata) · 357 unmodified lines | ||
| 358 | 358 | struct cfg80211_scan_request *req; |
| 359 | 359 | struct cfg80211_chan_def chandef; |
| 360 | 360 | u8 bands_used = 0; |
| 361 | − int i, ielen, n_chans; | |
| 361 | + int i, ielen; | |
| 362 | + u32 *n_chans; | |
| 362 | 363 | u32 flags = 0; |
| 363 | 364 | |
| 364 | 365 | req = rcu_dereference_protected(local->scan_req, |
| @@ -368,34 +369,34 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_sub_if_data *sdata) · 3 unmodified lines | ||
| 368 | 369 | return false; |
| 369 | 370 | |
| 370 | 371 | if (ieee80211_hw_check(&local->hw, SINGLE_SCAN_ON_ALL_BANDS)) { |
| 372 | + local->hw_scan_req->req.n_channels = req->n_channels; | |
| 373 | + | |
| 371 | 374 | for (i = 0; i < req->n_channels; i++) { |
| 372 | 375 | local->hw_scan_req->req.channels[i] = req->channels[i]; |
| 373 | 376 | bands_used |= BIT(req->channels[i]->band); |
| 374 | 377 | } |
| 375 | − | |
| 376 | − n_chans = req->n_channels; | |
| 377 | 378 | } else { |
| 378 | 379 | do { |
| 379 | 380 | if (local->hw_scan_band == NUM_NL80211_BANDS) |
| 380 | 381 | return false; |
| 381 | 382 | |
| 382 | − n_chans = 0; | |
| 383 | + n_chans = &local->hw_scan_req->req.n_channels; | |
| 384 | + *n_chans = 0; | |
| 383 | 385 | |
| 384 | 386 | for (i = 0; i < req->n_channels; i++) { |
| 385 | 387 | if (req->channels[i]->band != |
| 386 | 388 | local->hw_scan_band) |
| 387 | 389 | continue; |
| 388 | − local->hw_scan_req->req.channels[n_chans] = | |
| 390 | + local->hw_scan_req->req.channels[(*n_chans)++] = | |
| 389 | 391 | req->channels[i]; |
| 390 | − n_chans++; | |
| 392 | + | |
| 391 | 393 | bands_used |= BIT(req->channels[i]->band); |
| 392 | 394 | } |
| 393 | 395 | |
| 394 | 396 | local->hw_scan_band++; |
| 395 | − } while (!n_chans); | |
| 397 | + } while (!*n_chans); | |
| 396 | 398 | } |
| 397 | 399 | |
| 398 | − local->hw_scan_req->req.n_channels = n_chans; | |
| 399 | 400 | ieee80211_prepare_scan_chandef(&chandef); |
| 400 | 401 | |
| 401 | 402 | if (req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT) |
| @@ -1843,7 +1843,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) · 1842 unmodified lines | ||
| 1843 | 1843 | |
| 1844 | 1844 | /* add interfaces */ |
| 1845 | 1845 | sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata); |
| 1846 | − if (sdata) { | |
| 1846 | + if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) { | |
| 1847 | 1847 | /* in HW restart it exists already */ |
| 1848 | 1848 | WARN_ON(local->resuming); |
| 1849 | 1849 | res = drv_add_interface(local, sdata); |
| @@ -815,12 +815,21 @@ int __init netfilter_init(void) · 814 unmodified lines | ||
| 815 | 815 | if (ret < 0) |
| 816 | 816 | goto err; |
| 817 | 817 | |
| 818 | +#ifdef CONFIG_LWTUNNEL | |
| 819 | + ret = netfilter_lwtunnel_init(); | |
| 820 | + if (ret < 0) | |
| 821 | + goto err_lwtunnel_pernet; | |
| 822 | +#endif | |
| 818 | 823 | ret = netfilter_log_init(); |
| 819 | 824 | if (ret < 0) |
| 820 | − goto err_pernet; | |
| 825 | + goto err_log_pernet; | |
| 821 | 826 | |
| 822 | 827 | return 0; |
| 823 | −err_pernet: | |
| 828 | +err_log_pernet: | |
| 829 | +#ifdef CONFIG_LWTUNNEL | |
| 830 | + netfilter_lwtunnel_fini(); | |
| 831 | +err_lwtunnel_pernet: | |
| 832 | +#endif | |
| 824 | 833 | unregister_pernet_subsys(&netfilter_net_ops); |
| 825 | 834 | err: |
| 826 | 835 | return ret; |
| @@ -53,12 +53,13 @@ MODULE_DESCRIPTION("core IP set support"); · 52 unmodified lines | ||
| 53 | 53 | MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); |
| 54 | 54 | |
| 55 | 55 | /* When the nfnl mutex or ip_set_ref_lock is held: */ |
| 56 | −#define ip_set_dereference(p) \ | |
| 57 | − rcu_dereference_protected(p, \ | |
| 56 | +#define ip_set_dereference(inst) \ | |
| 57 | + rcu_dereference_protected((inst)->ip_set_list, \ | |
| 58 | 58 | lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \ |
| 59 | − lockdep_is_held(&ip_set_ref_lock)) | |
| 59 | + lockdep_is_held(&ip_set_ref_lock) || \ | |
| 60 | + (inst)->is_deleted) | |
| 60 | 61 | #define ip_set(inst, id) \ |
| 61 | − ip_set_dereference((inst)->ip_set_list)[id] | |
| 62 | + ip_set_dereference(inst)[id] | |
| 62 | 63 | #define ip_set_ref_netlink(inst,id) \ |
| 63 | 64 | rcu_dereference_raw((inst)->ip_set_list)[id] |
| 64 | 65 | #define ip_set_dereference_nfnl(p) \ |
| @@ -1133,7 +1134,7 @@ static int ip_set_create(struct sk_buff *skb, const struct nfnl_info *info, · 1068 unmodified lines | ||
| 1133 | 1134 | if (!list) |
| 1134 | 1135 | goto cleanup; |
| 1135 | 1136 | /* nfnl mutex is held, both lists are valid */ |
| 1136 | − tmp = ip_set_dereference(inst->ip_set_list); | |
| 1137 | + tmp = ip_set_dereference(inst); | |
| 1137 | 1138 | memcpy(list, tmp, sizeof(struct ip_set *) * inst->ip_set_max); |
| 1138 | 1139 | rcu_assign_pointer(inst->ip_set_list, list); |
| 1139 | 1140 | /* Make sure all current packets have passed through */ |
| @@ -22,9 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <net/netfilter/nf_conntrack_acct.h> |
| 23 | 23 | #include <net/netfilter/nf_conntrack_zones.h> |
| 24 | 24 | #include <net/netfilter/nf_conntrack_timestamp.h> |
| 25 | −#ifdef CONFIG_LWTUNNEL | |
| 26 | −#include <net/netfilter/nf_hooks_lwtunnel.h> | |
| 27 | −#endif | |
| 28 | 25 | #include <linux/rculist_nulls.h> |
| 29 | 26 | |
| 30 | 27 | static bool enable_hooks __read_mostly; |
| @@ -612,9 +609,6 @@ enum nf_ct_sysctl_index { · 581 unmodified lines | ||
| 612 | 609 | NF_SYSCTL_CT_PROTO_TIMEOUT_GRE, |
| 613 | 610 | NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM, |
| 614 | 611 | #endif |
| 615 | −#ifdef CONFIG_LWTUNNEL | |
| 616 | − NF_SYSCTL_CT_LWTUNNEL, | |
| 617 | −#endif | |
| 618 | 612 | |
| 619 | 613 | NF_SYSCTL_CT_LAST_SYSCTL, |
| 620 | 614 | }; |
| @@ -946,15 +940,6 @@ static struct ctl_table nf_ct_sysctl_table[] = { · 325 unmodified lines | ||
| 946 | 940 | .proc_handler = proc_dointvec_jiffies, |
| 947 | 941 | }, |
| 948 | 942 | #endif |
| 949 | −#ifdef CONFIG_LWTUNNEL | |
| 950 | − [NF_SYSCTL_CT_LWTUNNEL] = { | |
| 951 | − .procname = "nf_hooks_lwtunnel", | |
| 952 | − .data = NULL, | |
| 953 | − .maxlen = sizeof(int), | |
| 954 | − .mode = 0644, | |
| 955 | − .proc_handler = nf_hooks_lwtunnel_sysctl_handler, | |
| 956 | − }, | |
| 957 | −#endif | |
| 958 | 943 | }; |
| 959 | 944 | |
| 960 | 945 | static struct ctl_table nf_ct_netfilter_table[] = { |
| @@ -3,6 +3,9 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/sysctl.h> |
| 4 | 4 | #include <net/lwtunnel.h> |
| 5 | 5 | #include <net/netfilter/nf_hooks_lwtunnel.h> |
| 6 | +#include <linux/netfilter.h> | |
| 7 | + | |
| 8 | +#include "nf_internals.h" | |
| 6 | 9 | |
| 7 | 10 | static inline int nf_hooks_lwtunnel_get(void) |
| 8 | 11 | { |
| @@ -50,4 +53,68 @@ int nf_hooks_lwtunnel_sysctl_handler(struct ctl_table *table, int write, · 41 unmodified lines | ||
| 50 | 53 | return ret; |
| 51 | 54 | } |
| 52 | 55 | EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_sysctl_handler); |
| 56 | + | |
| 57 | +static struct ctl_table nf_lwtunnel_sysctl_table[] = { | |
| 58 | + { | |
| 59 | + .procname = "nf_hooks_lwtunnel", | |
| 60 | + .data = NULL, | |
| 61 | + .maxlen = sizeof(int), | |
| 62 | + .mode = 0644, | |
| 63 | + .proc_handler = nf_hooks_lwtunnel_sysctl_handler, | |
| 64 | + }, | |
| 65 | +}; | |
| 66 | + | |
| 67 | +static int __net_init nf_lwtunnel_net_init(struct net *net) | |
| 68 | +{ | |
| 69 | + struct ctl_table_header *hdr; | |
| 70 | + struct ctl_table *table; | |
| 71 | + | |
| 72 | + table = nf_lwtunnel_sysctl_table; | |
| 73 | + if (!net_eq(net, &init_net)) { | |
| 74 | + table = kmemdup(nf_lwtunnel_sysctl_table, | |
| 75 | + sizeof(nf_lwtunnel_sysctl_table), | |
| 76 | + GFP_KERNEL); | |
| 77 | + if (!table) | |
| 78 | + goto err_alloc; | |
| 79 | + } | |
| 80 | + | |
| 81 | + hdr = register_net_sysctl_sz(net, "net/netfilter", table, | |
| 82 | + ARRAY_SIZE(nf_lwtunnel_sysctl_table)); | |
| 83 | + if (!hdr) | |
| 84 | + goto err_reg; | |
| 85 | + | |
| 86 | + net->nf.nf_lwtnl_dir_header = hdr; | |
| 87 | + | |
| 88 | + return 0; | |
| 89 | +err_reg: | |
| 90 | + if (!net_eq(net, &init_net)) | |
| 91 | + kfree(table); | |
| 92 | +err_alloc: | |
| 93 | + return -ENOMEM; | |
| 94 | +} | |
| 95 | + | |
| 96 | +static void __net_exit nf_lwtunnel_net_exit(struct net *net) | |
| 97 | +{ | |
| 98 | + const struct ctl_table *table; | |
| 99 | + | |
| 100 | + table = net->nf.nf_lwtnl_dir_header->ctl_table_arg; | |
| 101 | + unregister_net_sysctl_table(net->nf.nf_lwtnl_dir_header); | |
| 102 | + if (!net_eq(net, &init_net)) | |
| 103 | + kfree(table); | |
| 104 | +} | |
| 105 | + | |
| 106 | +static struct pernet_operations nf_lwtunnel_net_ops = { | |
| 107 | + .init = nf_lwtunnel_net_init, | |
| 108 | + .exit = nf_lwtunnel_net_exit, | |
| 109 | +}; | |
| 110 | + | |
| 111 | +int __init netfilter_lwtunnel_init(void) | |
| 112 | +{ | |
| 113 | + return register_pernet_subsys(&nf_lwtunnel_net_ops); | |
| 114 | +} | |
| 115 | + | |
| 116 | +void netfilter_lwtunnel_fini(void) | |
| 117 | +{ | |
| 118 | + unregister_pernet_subsys(&nf_lwtunnel_net_ops); | |
| 119 | +} | |
| 53 | 120 | #endif /* CONFIG_SYSCTL */ |
| @@ -29,6 +29,12 @@ void nf_queue_nf_hook_drop(struct net *net); · 28 unmodified lines | ||
| 29 | 29 | /* nf_log.c */ |
| 30 | 30 | int __init netfilter_log_init(void); |
| 31 | 31 | |
| 32 | +#ifdef CONFIG_LWTUNNEL | |
| 33 | +/* nf_hooks_lwtunnel.c */ | |
| 34 | +int __init netfilter_lwtunnel_init(void); | |
| 35 | +void netfilter_lwtunnel_fini(void); | |
| 36 | +#endif | |
| 37 | + | |
| 32 | 38 | /* core.c */ |
| 33 | 39 | void nf_hook_entries_delete_raw(struct nf_hook_entries __rcu **pp, |
| 34 | 40 | const struct nf_hook_ops *reg); |
| @@ -121,7 +121,8 @@ static void nr_heartbeat_expiry(struct timer_list *t) · 120 unmodified lines | ||
| 121 | 121 | is accepted() it isn't 'dead' so doesn't get removed. */ |
| 122 | 122 | if (sock_flag(sk, SOCK_DESTROY) || |
| 123 | 123 | (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { |
| 124 | − sock_hold(sk); | |
| 124 | + if (sk->sk_state == TCP_LISTEN) | |
| 125 | + sock_hold(sk); | |
| 125 | 126 | bh_unlock_sock(sk); |
| 126 | 127 | nr_destroy_socket(sk); |
| 127 | 128 | goto out; |
| @@ -830,7 +830,6 @@ int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, · 829 unmodified lines | ||
| 830 | 830 | u32 max; |
| 831 | 831 | |
| 832 | 832 | if (*index) { |
| 833 | −again: | |
| 834 | 833 | rcu_read_lock(); |
| 835 | 834 | p = idr_find(&idrinfo->action_idr, *index); |
| 836 | 835 | |
| @@ -839,7 +838,7 @@ again: · 2 unmodified lines | ||
| 839 | 838 | * index but did not assign the pointer yet. |
| 840 | 839 | */ |
| 841 | 840 | rcu_read_unlock(); |
| 842 | − goto again; | |
| 841 | + return -EAGAIN; | |
| 843 | 842 | } |
| 844 | 843 | |
| 845 | 844 | if (!p) { |
| @@ -41,21 +41,26 @@ static struct workqueue_struct *act_ct_wq; · 40 unmodified lines | ||
| 41 | 41 | static struct rhashtable zones_ht; |
| 42 | 42 | static DEFINE_MUTEX(zones_mutex); |
| 43 | 43 | |
| 44 | +struct zones_ht_key { | |
| 45 | + struct net *net; | |
| 46 | + u16 zone; | |
| 47 | +}; | |
| 48 | + | |
| 44 | 49 | struct tcf_ct_flow_table { |
| 45 | 50 | struct rhash_head node; /* In zones tables */ |
| 46 | 51 | |
| 47 | 52 | struct rcu_work rwork; |
| 48 | 53 | struct nf_flowtable nf_ft; |
| 49 | 54 | refcount_t ref; |
| 50 | − u16 zone; | |
| 55 | + struct zones_ht_key key; | |
| 51 | 56 | |
| 52 | 57 | bool dying; |
| 53 | 58 | }; |
| 54 | 59 | |
| 55 | 60 | static const struct rhashtable_params zones_params = { |
| 56 | 61 | .head_offset = offsetof(struct tcf_ct_flow_table, node), |
| 57 | − .key_offset = offsetof(struct tcf_ct_flow_table, zone), | |
| 58 | − .key_len = sizeof_field(struct tcf_ct_flow_table, zone), | |
| 62 | + .key_offset = offsetof(struct tcf_ct_flow_table, key), | |
| 63 | + .key_len = sizeof_field(struct tcf_ct_flow_table, key), | |
| 59 | 64 | .automatic_shrinking = true, |
| 60 | 65 | }; |
| 61 | 66 | |
| @@ -316,11 +321,12 @@ static struct nf_flowtable_type flowtable_ct = { · 254 unmodified lines | ||
| 316 | 321 | |
| 317 | 322 | static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params) |
| 318 | 323 | { |
| 324 | + struct zones_ht_key key = { .net = net, .zone = params->zone }; | |
| 319 | 325 | struct tcf_ct_flow_table *ct_ft; |
| 320 | 326 | int err = -ENOMEM; |
| 321 | 327 | |
| 322 | 328 | mutex_lock(&zones_mutex); |
| 323 | − ct_ft = rhashtable_lookup_fast(&zones_ht, ¶ms->zone, zones_params); | |
| 329 | + ct_ft = rhashtable_lookup_fast(&zones_ht, &key, zones_params); | |
| 324 | 330 | if (ct_ft && refcount_inc_not_zero(&ct_ft->ref)) |
| 325 | 331 | goto out_unlock; |
| 326 | 332 | |
| @@ -329,7 +335,7 @@ static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params) · 2 unmodified lines | ||
| 329 | 335 | goto err_alloc; |
| 330 | 336 | refcount_set(&ct_ft->ref, 1); |
| 331 | 337 | |
| 332 | − ct_ft->zone = params->zone; | |
| 338 | + ct_ft->key = key; | |
| 333 | 339 | err = rhashtable_insert_fast(&zones_ht, &ct_ft->node, zones_params); |
| 334 | 340 | if (err) |
| 335 | 341 | goto err_insert; |
| @@ -1421,12 +1421,13 @@ static void *svc_pool_stats_start(struct seq_file *m, loff_t *pos) · 1420 unmodified lines | ||
| 1421 | 1421 | |
| 1422 | 1422 | dprintk("svc_pool_stats_start, *pidx=%u\n", pidx); |
| 1423 | 1423 | |
| 1424 | + if (!si->serv) | |
| 1425 | + return NULL; | |
| 1426 | + | |
| 1424 | 1427 | mutex_lock(si->mutex); |
| 1425 | 1428 | |
| 1426 | 1429 | if (!pidx) |
| 1427 | 1430 | return SEQ_START_TOKEN; |
| 1428 | − if (!si->serv) | |
| 1429 | − return NULL; | |
| 1430 | 1431 | return pidx > si->serv->sv_nrpools ? NULL |
| 1431 | 1432 | : &si->serv->sv_pools[pidx - 1]; |
| 1432 | 1433 | } |
| @@ -1458,7 +1459,8 @@ static void svc_pool_stats_stop(struct seq_file *m, void *p) · 25 unmodified lines | ||
| 1458 | 1459 | { |
| 1459 | 1460 | struct svc_info *si = m->private; |
| 1460 | 1461 | |
| 1461 | − mutex_unlock(si->mutex); | |
| 1462 | + if (si->serv) | |
| 1463 | + mutex_unlock(si->mutex); | |
| 1462 | 1464 | } |
| 1463 | 1465 | |
| 1464 | 1466 | static int svc_pool_stats_show(struct seq_file *m, void *p) |
| @@ -2105,6 +2105,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) · 2104 unmodified lines | ||
| 2105 | 2105 | } else { |
| 2106 | 2106 | n = tipc_node_find_by_id(net, ehdr->id); |
| 2107 | 2107 | } |
| 2108 | + skb_dst_force(skb); | |
| 2108 | 2109 | tipc_crypto_rcv(net, (n) ? n->crypto_rx : NULL, &skb, b); |
| 2109 | 2110 | if (!skb) |
| 2110 | 2111 | return; |
| @@ -3416,10 +3416,14 @@ int cfg80211_wext_siwscan(struct net_device *dev, · 3415 unmodified lines | ||
| 3416 | 3416 | wiphy = &rdev->wiphy; |
| 3417 | 3417 | |
| 3418 | 3418 | /* Determine number of channels, needed to allocate creq */ |
| 3419 | − if (wreq && wreq->num_channels) | |
| 3419 | + if (wreq && wreq->num_channels) { | |
| 3420 | + /* Passed from userspace so should be checked */ | |
| 3421 | + if (unlikely(wreq->num_channels > IW_MAX_FREQUENCIES)) | |
| 3422 | + return -EINVAL; | |
| 3420 | 3423 | n_channels = wreq->num_channels; |
| 3421 | − else | |
| 3424 | + } else { | |
| 3422 | 3425 | n_channels = ieee80211_get_num_supported_channels(wiphy); |
| 3426 | + } | |
| 3423 | 3427 | |
| 3424 | 3428 | creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + |
| 3425 | 3429 | n_channels * sizeof(void *), |
| @@ -3493,8 +3497,10 @@ int cfg80211_wext_siwscan(struct net_device *dev, · 67 unmodified lines | ||
| 3493 | 3497 | memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); |
| 3494 | 3498 | creq->ssids[0].ssid_len = wreq->essid_len; |
| 3495 | 3499 | } |
| 3496 | − if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) | |
| 3500 | + if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) { | |
| 3501 | + creq->ssids = NULL; | |
| 3497 | 3502 | creq->n_ssids = 0; |
| 3503 | + } | |
| 3498 | 3504 | } |
| 3499 | 3505 | |
| 3500 | 3506 | for (i = 0; i < NUM_NL80211_BANDS; i++) |
| @@ -4,7 +4,6 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | use super::{AllocError, Flags}; |
| 6 | 6 | use alloc::vec::Vec; |
| 7 | −use core::ptr; | |
| 8 | 7 | |
| 9 | 8 | /// Extensions to [`Vec`]. |
| 10 | 9 | pub trait VecExt<T>: Sized { |
| @@ -141,7 +140,11 @@ impl<T> VecExt<T> for Vec<T> { · 130 unmodified lines | ||
| 141 | 140 | // `krealloc_aligned`. A `Vec<T>`'s `ptr` value is not guaranteed to be NULL and might be |
| 142 | 141 | // dangling after being created with `Vec::new`. Instead, we can rely on `Vec<T>`'s capacity |
| 143 | 142 | // to be zero if no memory has been allocated yet. |
| 144 | − let ptr = if cap == 0 { ptr::null_mut() } else { old_ptr }; | |
| 143 | + let ptr = if cap == 0 { | |
| 144 | + core::ptr::null_mut() | |
| 145 | + } else { | |
| 146 | + old_ptr | |
| 147 | + }; | |
| 145 | 148 | |
| 146 | 149 | // SAFETY: `ptr` is valid because it's either NULL or comes from a previous call to |
| 147 | 150 | // `krealloc_aligned`. We also verified that the type is not a ZST. |
| @@ -255,21 +255,6 @@ config INIT_ON_FREE_DEFAULT_ON · 254 unmodified lines | ||
| 255 | 255 | touching "cold" memory areas. Most cases see 3-5% impact. Some |
| 256 | 256 | synthetic workloads have measured as high as 8%. |
| 257 | 257 | |
| 258 | −config INIT_MLOCKED_ON_FREE_DEFAULT_ON | |
| 259 | − bool "Enable mlocked memory zeroing on free" | |
| 260 | − depends on !KMSAN | |
| 261 | − help | |
| 262 | − This config has the effect of setting "init_mlocked_on_free=1" | |
| 263 | − on the kernel command line. If it is enabled, all mlocked process | |
| 264 | − memory is zeroed when freed. This restriction to mlocked memory | |
| 265 | − improves performance over "init_on_free" but can still be used to | |
| 266 | − protect confidential data like key material from content exposures | |
| 267 | − to other processes, as well as live forensics and cold boot attacks. | |
| 268 | − Any non-mlocked memory is not cleared before it is reassigned. This | |
| 269 | − configuration can be overwritten by setting "init_mlocked_on_free=0" | |
| 270 | − on the command line. The "init_on_free" boot option takes | |
| 271 | − precedence over "init_mlocked_on_free". | |
| 272 | − | |
| 273 | 258 | config CC_HAS_ZERO_CALL_USED_REGS |
| 274 | 259 | def_bool $(cc-option,-fzero-call-used-regs=used-gpr) |
| 275 | 260 | # https://github.com/ClangBuiltLinux/linux/issues/1766 |
| @@ -217,7 +217,7 @@ void aa_audit_rule_free(void *vrule) · 216 unmodified lines | ||
| 217 | 217 | } |
| 218 | 218 | } |
| 219 | 219 | |
| 220 | −int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |
| 220 | +int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, gfp_t gfp) | |
| 221 | 221 | { |
| 222 | 222 | struct aa_audit_rule *rule; |
| 223 | 223 | |
| @@ -230,14 +230,14 @@ int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) · 6 unmodified lines | ||
| 230 | 230 | return -EINVAL; |
| 231 | 231 | } |
| 232 | 232 | |
| 233 | − rule = kzalloc(sizeof(struct aa_audit_rule), GFP_KERNEL); | |
| 233 | + rule = kzalloc(sizeof(struct aa_audit_rule), gfp); | |
| 234 | 234 | |
| 235 | 235 | if (!rule) |
| 236 | 236 | return -ENOMEM; |
| 237 | 237 | |
| 238 | 238 | /* Currently rules are treated as coming from the root ns */ |
| 239 | 239 | rule->label = aa_label_parse(&root_ns->unconfined->label, rulestr, |
| 240 | − GFP_KERNEL, true, false); | |
| 240 | + gfp, true, false); | |
| 241 | 241 | if (IS_ERR(rule->label)) { |
| 242 | 242 | int err = PTR_ERR(rule->label); |
| 243 | 243 | aa_audit_rule_free(rule); |
| @@ -200,7 +200,7 @@ static inline int complain_error(int error) · 199 unmodified lines | ||
| 200 | 200 | } |
| 201 | 201 | |
| 202 | 202 | void aa_audit_rule_free(void *vrule); |
| 203 | −int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule); | |
| 203 | +int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, gfp_t gfp); | |
| 204 | 204 | int aa_audit_rule_known(struct audit_krule *rule); |
| 205 | 205 | int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule); |
| 206 | 206 | |
| @@ -546,7 +546,7 @@ static inline void ima_free_modsig(struct modsig *modsig) · 545 unmodified lines | ||
| 546 | 546 | #else |
| 547 | 547 | |
| 548 | 548 | static inline int ima_filter_rule_init(u32 field, u32 op, char *rulestr, |
| 549 | − void **lsmrule) | |
| 549 | + void **lsmrule, gfp_t gfp) | |
| 550 | 550 | { |
| 551 | 551 | return -EINVAL; |
| 552 | 552 | } |
| @@ -401,7 +401,8 @@ static void ima_free_rule(struct ima_rule_entry *entry) · 400 unmodified lines | ||
| 401 | 401 | kfree(entry); |
| 402 | 402 | } |
| 403 | 403 | |
| 404 | −static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) | |
| 404 | +static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry, | |
| 405 | + gfp_t gfp) | |
| 405 | 406 | { |
| 406 | 407 | struct ima_rule_entry *nentry; |
| 407 | 408 | int i; |
| @@ -410,7 +411,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) · 2 unmodified lines | ||
| 410 | 411 | * Immutable elements are copied over as pointers and data; only |
| 411 | 412 | * lsm rules can change |
| 412 | 413 | */ |
| 413 | − nentry = kmemdup(entry, sizeof(*nentry), GFP_KERNEL); | |
| 414 | + nentry = kmemdup(entry, sizeof(*nentry), gfp); | |
| 414 | 415 | if (!nentry) |
| 415 | 416 | return NULL; |
| 416 | 417 | |
| @@ -425,7 +426,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) · 8 unmodified lines | ||
| 425 | 426 | |
| 426 | 427 | ima_filter_rule_init(nentry->lsm[i].type, Audit_equal, |
| 427 | 428 | nentry->lsm[i].args_p, |
| 428 | − &nentry->lsm[i].rule); | |
| 429 | + &nentry->lsm[i].rule, | |
| 430 | + gfp); | |
| 429 | 431 | if (!nentry->lsm[i].rule) |
| 430 | 432 | pr_warn("rule for LSM \'%s\' is undefined\n", |
| 431 | 433 | nentry->lsm[i].args_p); |
| @@ -438,7 +440,7 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry) · 6 unmodified lines | ||
| 438 | 440 | int i; |
| 439 | 441 | struct ima_rule_entry *nentry; |
| 440 | 442 | |
| 441 | − nentry = ima_lsm_copy_rule(entry); | |
| 443 | + nentry = ima_lsm_copy_rule(entry, GFP_KERNEL); | |
| 442 | 444 | if (!nentry) |
| 443 | 445 | return -ENOMEM; |
| 444 | 446 | |
| @@ -664,7 +666,7 @@ retry: · 219 unmodified lines | ||
| 664 | 666 | } |
| 665 | 667 | |
| 666 | 668 | if (rc == -ESTALE && !rule_reinitialized) { |
| 667 | − lsm_rule = ima_lsm_copy_rule(rule); | |
| 669 | + lsm_rule = ima_lsm_copy_rule(rule, GFP_ATOMIC); | |
| 668 | 670 | if (lsm_rule) { |
| 669 | 671 | rule_reinitialized = true; |
| 670 | 672 | goto retry; |
| @@ -1140,7 +1142,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, · 469 unmodified lines | ||
| 1140 | 1142 | entry->lsm[lsm_rule].type = audit_type; |
| 1141 | 1143 | result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal, |
| 1142 | 1144 | entry->lsm[lsm_rule].args_p, |
| 1143 | − &entry->lsm[lsm_rule].rule); | |
| 1145 | + &entry->lsm[lsm_rule].rule, | |
| 1146 | + GFP_KERNEL); | |
| 1144 | 1147 | if (!entry->lsm[lsm_rule].rule) { |
| 1145 | 1148 | pr_warn("rule for LSM \'%s\' is undefined\n", |
| 1146 | 1149 | entry->lsm[lsm_rule].args_p); |
| @@ -5332,15 +5332,17 @@ void security_key_post_create_or_update(struct key *keyring, struct key *key, · 5331 unmodified lines | ||
| 5332 | 5332 | * @op: rule operator |
| 5333 | 5333 | * @rulestr: rule context |
| 5334 | 5334 | * @lsmrule: receive buffer for audit rule struct |
| 5335 | + * @gfp: GFP flag used for kmalloc | |
| 5335 | 5336 | * |
| 5336 | 5337 | * Allocate and initialize an LSM audit rule structure. |
| 5337 | 5338 | * |
| 5338 | 5339 | * Return: Return 0 if @lsmrule has been successfully set, -EINVAL in case of |
| 5339 | 5340 | * an invalid rule. |
| 5340 | 5341 | */ |
| 5341 | −int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) | |
| 5342 | +int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule, | |
| 5343 | + gfp_t gfp) | |
| 5342 | 5344 | { |
| 5343 | − return call_int_hook(audit_rule_init, field, op, rulestr, lsmrule); | |
| 5345 | + return call_int_hook(audit_rule_init, field, op, rulestr, lsmrule, gfp); | |
| 5344 | 5346 | } |
| 5345 | 5347 | |
| 5346 | 5348 | /** |
| @@ -21,12 +21,14 @@ · 20 unmodified lines | ||
| 21 | 21 | * @op: the operator the rule uses |
| 22 | 22 | * @rulestr: the text "target" of the rule |
| 23 | 23 | * @rule: pointer to the new rule structure returned via this |
| 24 | + * @gfp: GFP flag used for kmalloc | |
| 24 | 25 | * |
| 25 | 26 | * Returns 0 if successful, -errno if not. On success, the rule structure |
| 26 | 27 | * will be allocated internally. The caller must free this structure with |
| 27 | 28 | * selinux_audit_rule_free() after use. |
| 28 | 29 | */ |
| 29 | −int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule); | |
| 30 | +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule, | |
| 31 | + gfp_t gfp); | |
| 30 | 32 | |
| 31 | 33 | /** |
| 32 | 34 | * selinux_audit_rule_free - free an selinux audit rule structure. |
| @@ -3507,7 +3507,8 @@ void selinux_audit_rule_free(void *vrule) · 3506 unmodified lines | ||
| 3507 | 3507 | } |
| 3508 | 3508 | } |
| 3509 | 3509 | |
| 3510 | −int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |
| 3510 | +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, | |
| 3511 | + gfp_t gfp) | |
| 3511 | 3512 | { |
| 3512 | 3513 | struct selinux_state *state = &selinux_state; |
| 3513 | 3514 | struct selinux_policy *policy; |
| @@ -3548,7 +3549,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) · 34 unmodified lines | ||
| 3548 | 3549 | return -EINVAL; |
| 3549 | 3550 | } |
| 3550 | 3551 | |
| 3551 | − tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); | |
| 3552 | + tmprule = kzalloc(sizeof(struct selinux_audit_rule), gfp); | |
| 3552 | 3553 | if (!tmprule) |
| 3553 | 3554 | return -ENOMEM; |
| 3554 | 3555 | context_init(&tmprule->au_ctxt); |
| @@ -4693,11 +4693,13 @@ static int smack_post_notification(const struct cred *w_cred, · 4692 unmodified lines | ||
| 4693 | 4693 | * @op: required testing operator (=, !=, >, <, ...) |
| 4694 | 4694 | * @rulestr: smack label to be audited |
| 4695 | 4695 | * @vrule: pointer to save our own audit rule representation |
| 4696 | + * @gfp: type of the memory for the allocation | |
| 4696 | 4697 | * |
| 4697 | 4698 | * Prepare to audit cases where (@field @op @rulestr) is true. |
| 4698 | 4699 | * The label to be audited is created if necessay. |
| 4699 | 4700 | */ |
| 4700 | −static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |
| 4701 | +static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, | |
| 4702 | + gfp_t gfp) | |
| 4701 | 4703 | { |
| 4702 | 4704 | struct smack_known *skp; |
| 4703 | 4705 | char **rule = (char **)vrule; |
| @@ -111,6 +111,7 @@ static void report_access(const char *access, struct task_struct *target, · 110 unmodified lines | ||
| 111 | 111 | |
| 112 | 112 | /** |
| 113 | 113 | * yama_relation_cleanup - remove invalid entries from the relation list |
| 114 | + * @work: unused | |
| 114 | 115 | * |
| 115 | 116 | */ |
| 116 | 117 | static void yama_relation_cleanup(struct work_struct *work) |
| @@ -1075,6 +1075,8 @@ static const struct seq_ev_to_ump seq_ev_ump_encoders[] = { · 1074 unmodified lines | ||
| 1075 | 1075 | system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, |
| 1076 | 1076 | { SNDRV_SEQ_EVENT_SENSING, UMP_SYSTEM_STATUS_ACTIVE_SENSING, |
| 1077 | 1077 | system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, |
| 1078 | + { SNDRV_SEQ_EVENT_RESET, UMP_SYSTEM_STATUS_RESET, | |
| 1079 | + system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, | |
| 1078 | 1080 | }; |
| 1079 | 1081 | |
| 1080 | 1082 | static const struct seq_ev_to_ump *find_ump_encoder(int type) |
| @@ -18,7 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | static int dsp_driver; |
| 19 | 19 | |
| 20 | 20 | module_param(dsp_driver, int, 0444); |
| 21 | −MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)"); | |
| 21 | +MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF, 4=AVS)"); | |
| 22 | 22 | |
| 23 | 23 | #define FLAG_SST BIT(0) |
| 24 | 24 | #define FLAG_SOF BIT(1) |
| @@ -204,6 +204,7 @@ module_param(numWriteBufs, int, 0); · 203 unmodified lines | ||
| 204 | 204 | static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */ |
| 205 | 205 | module_param(writeBufSize, int, 0); |
| 206 | 206 | |
| 207 | +MODULE_DESCRIPTION("Atari/Amiga/Q40 core DMA sound driver"); | |
| 207 | 208 | MODULE_LICENSE("GPL"); |
| 208 | 209 | |
| 209 | 210 | static int sq_unit = -1; |
| @@ -162,6 +162,7 @@ config SND_HDA_SCODEC_CS35L56_I2C · 161 unmodified lines | ||
| 162 | 162 | depends on ACPI || COMPILE_TEST |
| 163 | 163 | depends on SND_SOC |
| 164 | 164 | select FW_CS_DSP |
| 165 | + imply SERIAL_MULTI_INSTANTIATE | |
| 165 | 166 | select SND_HDA_GENERIC |
| 166 | 167 | select SND_SOC_CS35L56_SHARED |
| 167 | 168 | select SND_HDA_SCODEC_CS35L56 |
| @@ -178,6 +179,7 @@ config SND_HDA_SCODEC_CS35L56_SPI · 10 unmodified lines | ||
| 178 | 179 | depends on ACPI || COMPILE_TEST |
| 179 | 180 | depends on SND_SOC |
| 180 | 181 | select FW_CS_DSP |
| 182 | + imply SERIAL_MULTI_INSTANTIATE | |
| 181 | 183 | select SND_HDA_GENERIC |
| 182 | 184 | select SND_SOC_CS35L56_SHARED |
| 183 | 185 | select SND_HDA_SCODEC_CS35L56 |
| @@ -1495,7 +1495,7 @@ static void cs35l41_hda_unbind(struct device *dev, struct device *master, void * · 1494 unmodified lines | ||
| 1495 | 1495 | if (comps[cs35l41->index].dev == dev) { |
| 1496 | 1496 | memset(&comps[cs35l41->index], 0, sizeof(*comps)); |
| 1497 | 1497 | sleep_flags = lock_system_sleep(); |
| 1498 | − device_link_remove(&comps->codec->core.dev, cs35l41->dev); | |
| 1498 | + device_link_remove(&cs35l41->codec->core.dev, cs35l41->dev); | |
| 1499 | 1499 | unlock_system_sleep(sleep_flags); |
| 1500 | 1500 | } |
| 1501 | 1501 | } |
| @@ -2019,6 +2019,8 @@ void cs35l41_hda_remove(struct device *dev) · 517 unmodified lines | ||
| 2019 | 2019 | { |
| 2020 | 2020 | struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); |
| 2021 | 2021 | |
| 2022 | + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); | |
| 2023 | + | |
| 2022 | 2024 | pm_runtime_get_sync(cs35l41->dev); |
| 2023 | 2025 | pm_runtime_dont_use_autosuspend(cs35l41->dev); |
| 2024 | 2026 | pm_runtime_disable(cs35l41->dev); |
| @@ -2026,8 +2028,6 @@ void cs35l41_hda_remove(struct device *dev) · 1 unmodified line | ||
| 2026 | 2028 | if (cs35l41->halo_initialized) |
| 2027 | 2029 | cs35l41_remove_dsp(cs35l41); |
| 2028 | 2030 | |
| 2029 | − component_del(cs35l41->dev, &cs35l41_hda_comp_ops); | |
| 2030 | − | |
| 2031 | 2031 | acpi_dev_put(cs35l41->dacpi); |
| 2032 | 2032 | |
| 2033 | 2033 | pm_runtime_put_noidle(cs35l41->dev); |
| @@ -128,6 +128,10 @@ static const struct cs35l41_config cs35l41_config_table[] = { · 127 unmodified lines | ||
| 128 | 128 | { "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, |
| 129 | 129 | { "17AA38B6", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, |
| 130 | 130 | { "17AA38B7", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, |
| 131 | + { "17AA38C7", 4, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT }, 0, 2, -1, 1000, 4500, 24 }, | |
| 132 | + { "17AA38C8", 4, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT }, 0, 2, -1, 1000, 4500, 24 }, | |
| 133 | + { "17AA38F9", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 }, | |
| 134 | + { "17AA38FA", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 }, | |
| 131 | 135 | {} |
| 132 | 136 | }; |
| 133 | 137 | |
| @@ -529,6 +533,10 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = { · 395 unmodified lines | ||
| 529 | 533 | { "CSC3551", "17AA38B5", generic_dsd_config }, |
| 530 | 534 | { "CSC3551", "17AA38B6", generic_dsd_config }, |
| 531 | 535 | { "CSC3551", "17AA38B7", generic_dsd_config }, |
| 536 | + { "CSC3551", "17AA38C7", generic_dsd_config }, | |
| 537 | + { "CSC3551", "17AA38C8", generic_dsd_config }, | |
| 538 | + { "CSC3551", "17AA38F9", generic_dsd_config }, | |
| 539 | + { "CSC3551", "17AA38FA", generic_dsd_config }, | |
| 532 | 540 | {} |
| 533 | 541 | }; |
| 534 | 542 | |
| @@ -735,6 +735,8 @@ static void cs35l56_hda_unbind(struct device *dev, struct device *master, void * · 734 unmodified lines | ||
| 735 | 735 | if (comps[cs35l56->index].dev == dev) |
| 736 | 736 | memset(&comps[cs35l56->index], 0, sizeof(*comps)); |
| 737 | 737 | |
| 738 | + cs35l56->codec = NULL; | |
| 739 | + | |
| 738 | 740 | dev_dbg(cs35l56->base.dev, "Unbound\n"); |
| 739 | 741 | } |
| 740 | 742 | |
| @@ -840,6 +842,9 @@ static int cs35l56_hda_system_resume(struct device *dev) · 99 unmodified lines | ||
| 840 | 842 | |
| 841 | 843 | cs35l56->suspended = false; |
| 842 | 844 | |
| 845 | + if (!cs35l56->codec) | |
| 846 | + return 0; | |
| 847 | + | |
| 843 | 848 | ret = cs35l56_is_fw_reload_needed(&cs35l56->base); |
| 844 | 849 | dev_dbg(cs35l56->base.dev, "fw_reload_needed: %d\n", ret); |
| 845 | 850 | if (ret > 0) { |
| @@ -1072,12 +1077,12 @@ void cs35l56_hda_remove(struct device *dev) · 226 unmodified lines | ||
| 1072 | 1077 | { |
| 1073 | 1078 | struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev); |
| 1074 | 1079 | |
| 1080 | + component_del(cs35l56->base.dev, &cs35l56_hda_comp_ops); | |
| 1081 | + | |
| 1075 | 1082 | pm_runtime_dont_use_autosuspend(cs35l56->base.dev); |
| 1076 | 1083 | pm_runtime_get_sync(cs35l56->base.dev); |
| 1077 | 1084 | pm_runtime_disable(cs35l56->base.dev); |
| 1078 | 1085 | |
| 1079 | − component_del(cs35l56->base.dev, &cs35l56_hda_comp_ops); | |
| 1080 | − | |
| 1081 | 1086 | cs_dsp_remove(&cs35l56->cs_dsp); |
| 1082 | 1087 | |
| 1083 | 1088 | kfree(cs35l56->system_name); |
| @@ -583,10 +583,14 @@ static void alc_shutup_pins(struct hda_codec *codec) · 582 unmodified lines | ||
| 583 | 583 | switch (codec->core.vendor_id) { |
| 584 | 584 | case 0x10ec0236: |
| 585 | 585 | case 0x10ec0256: |
| 586 | + case 0x10ec0257: | |
| 586 | 587 | case 0x19e58326: |
| 587 | 588 | case 0x10ec0283: |
| 589 | + case 0x10ec0285: | |
| 588 | 590 | case 0x10ec0286: |
| 591 | + case 0x10ec0287: | |
| 589 | 592 | case 0x10ec0288: |
| 593 | + case 0x10ec0295: | |
| 590 | 594 | case 0x10ec0298: |
| 591 | 595 | alc_headset_mic_no_shutup(codec); |
| 592 | 596 | break; |
| @@ -7520,6 +7524,7 @@ enum { · 6927 unmodified lines | ||
| 7520 | 7524 | ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1, |
| 7521 | 7525 | ALC287_FIXUP_LENOVO_THKPAD_WH_ALC1318, |
| 7522 | 7526 | ALC256_FIXUP_CHROME_BOOK, |
| 7527 | + ALC287_FIXUP_LENOVO_14ARP8_LEGION_IAH7, | |
| 7523 | 7528 | }; |
| 7524 | 7529 | |
| 7525 | 7530 | /* A special fixup for Lenovo C940 and Yoga Duet 7; |
| @@ -7559,6 +7564,21 @@ static void alc287_fixup_lenovo_14irp8_duetitl(struct hda_codec *codec, · 33 unmodified lines | ||
| 7559 | 7564 | __snd_hda_apply_fixup(codec, id, action, 0); |
| 7560 | 7565 | } |
| 7561 | 7566 | |
| 7567 | +/* Similar to above the Lenovo Yoga Pro 7 14ARP8 PCI SSID matches the codec SSID of the | |
| 7568 | + Legion Y9000X 2022 IAH7.*/ | |
| 7569 | +static void alc287_fixup_lenovo_14arp8_legion_iah7(struct hda_codec *codec, | |
| 7570 | + const struct hda_fixup *fix, | |
| 7571 | + int action) | |
| 7572 | +{ | |
| 7573 | + int id; | |
| 7574 | + | |
| 7575 | + if (codec->core.subsystem_id == 0x17aa386e) | |
| 7576 | + id = ALC287_FIXUP_CS35L41_I2C_2; /* Legion Y9000X 2022 IAH7 */ | |
| 7577 | + else | |
| 7578 | + id = ALC285_FIXUP_SPEAKER2_TO_DAC1; /* Yoga Pro 7 14ARP8 */ | |
| 7579 | + __snd_hda_apply_fixup(codec, id, action, 0); | |
| 7580 | +} | |
| 7581 | + | |
| 7562 | 7582 | /* Another hilarious PCI SSID conflict with Lenovo Legion Pro 7 16ARX8H (with |
| 7563 | 7583 | * TAS2781 codec) and Legion 7i 16IAX7 (with CS35L41 codec); |
| 7564 | 7584 | * we apply a corresponding fixup depending on the codec SSID instead |
| @@ -9658,6 +9678,10 @@ static const struct hda_fixup alc269_fixups[] = { · 2093 unmodified lines | ||
| 9658 | 9678 | .chained = true, |
| 9659 | 9679 | .chain_id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK, |
| 9660 | 9680 | }, |
| 9681 | + [ALC287_FIXUP_LENOVO_14ARP8_LEGION_IAH7] = { | |
| 9682 | + .type = HDA_FIXUP_FUNC, | |
| 9683 | + .v.func = alc287_fixup_lenovo_14arp8_legion_iah7, | |
| 9684 | + }, | |
| 9661 | 9685 | [ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN] = { |
| 9662 | 9686 | .type = HDA_FIXUP_FUNC, |
| 9663 | 9687 | .v.func = alc287_fixup_yoga9_14iap7_bass_spk_pin, |
| @@ -10194,6 +10218,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 530 unmodified lines | ||
| 10194 | 10218 | SND_PCI_QUIRK(0x103c, 0x8c70, "HP EliteBook 835 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), |
| 10195 | 10219 | SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), |
| 10196 | 10220 | SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), |
| 10221 | + SND_PCI_QUIRK(0x103c, 0x8c7b, "HP ProBook 445 G11", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | |
| 10222 | + SND_PCI_QUIRK(0x103c, 0x8c7c, "HP ProBook 445 G11", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | |
| 10223 | + SND_PCI_QUIRK(0x103c, 0x8c7d, "HP ProBook 465 G11", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | |
| 10224 | + SND_PCI_QUIRK(0x103c, 0x8c7e, "HP ProBook 465 G11", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | |
| 10197 | 10225 | SND_PCI_QUIRK(0x103c, 0x8c89, "HP ProBook 460 G11", ALC236_FIXUP_HP_GPIO_LED), |
| 10198 | 10226 | SND_PCI_QUIRK(0x103c, 0x8c8a, "HP EliteBook 630", ALC236_FIXUP_HP_GPIO_LED), |
| 10199 | 10227 | SND_PCI_QUIRK(0x103c, 0x8c8c, "HP EliteBook 660", ALC236_FIXUP_HP_GPIO_LED), |
| @@ -10502,7 +10530,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 302 unmodified lines | ||
| 10502 | 10530 | SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS), |
| 10503 | 10531 | SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7), |
| 10504 | 10532 | SND_PCI_QUIRK(0x17aa, 0x3819, "Lenovo 13s Gen2 ITL", ALC287_FIXUP_13S_GEN2_SPEAKERS), |
| 10505 | − SND_PCI_QUIRK(0x17aa, 0x3820, "Yoga Duet 7 13ITL6", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), | |
| 10533 | + SND_PCI_QUIRK(0x17aa, 0x3820, "IdeaPad 330-17IKB 81DM", ALC269_FIXUP_ASPIRE_HEADSET_MIC), | |
| 10506 | 10534 | SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS), |
| 10507 | 10535 | SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF), |
| 10508 | 10536 | SND_PCI_QUIRK(0x17aa, 0x3834, "Lenovo IdeaPad Slim 9i 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), |
| @@ -10516,7 +10544,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 7 unmodified lines | ||
| 10516 | 10544 | SND_PCI_QUIRK(0x17aa, 0x3865, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2), |
| 10517 | 10545 | SND_PCI_QUIRK(0x17aa, 0x3866, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2), |
| 10518 | 10546 | SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), |
| 10519 | − SND_PCI_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7", ALC287_FIXUP_CS35L41_I2C_2), | |
| 10547 | + SND_PCI_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7 / Yoga Pro 7 14ARP8", ALC287_FIXUP_LENOVO_14ARP8_LEGION_IAH7), | |
| 10520 | 10548 | SND_PCI_QUIRK(0x17aa, 0x386f, "Legion Pro 7/7i", ALC287_FIXUP_LENOVO_LEGION_7), |
| 10521 | 10549 | SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C), |
| 10522 | 10550 | SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2), |
| @@ -10527,6 +10555,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 4 unmodified lines | ||
| 10527 | 10555 | SND_PCI_QUIRK(0x17aa, 0x3882, "Lenovo Yoga Pro 7 14APH8", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), |
| 10528 | 10556 | SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL", ALC287_FIXUP_TAS2781_I2C), |
| 10529 | 10557 | SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C), |
| 10558 | + SND_PCI_QUIRK(0x17aa, 0x3891, "Lenovo Yoga Pro 7 14AHP9", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), | |
| 10530 | 10559 | SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C), |
| 10531 | 10560 | SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C), |
| 10532 | 10561 | SND_PCI_QUIRK(0x17aa, 0x38a9, "Thinkbook 16P", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), |
| @@ -10540,10 +10569,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 7 unmodified lines | ||
| 10540 | 10569 | SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C), |
| 10541 | 10570 | SND_PCI_QUIRK(0x17aa, 0x38bf, "Yoga S980-14.5 proX LX Dual", ALC287_FIXUP_TAS2781_I2C), |
| 10542 | 10571 | SND_PCI_QUIRK(0x17aa, 0x38c3, "Y980 DUAL", ALC287_FIXUP_TAS2781_I2C), |
| 10572 | + SND_PCI_QUIRK(0x17aa, 0x38c7, "Thinkbook 13x Gen 4", ALC287_FIXUP_CS35L41_I2C_4), | |
| 10573 | + SND_PCI_QUIRK(0x17aa, 0x38c8, "Thinkbook 13x Gen 4", ALC287_FIXUP_CS35L41_I2C_4), | |
| 10543 | 10574 | SND_PCI_QUIRK(0x17aa, 0x38cb, "Y790 YG DUAL", ALC287_FIXUP_TAS2781_I2C), |
| 10544 | 10575 | SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL", ALC287_FIXUP_TAS2781_I2C), |
| 10545 | 10576 | SND_PCI_QUIRK(0x17aa, 0x38d2, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN), |
| 10546 | 10577 | SND_PCI_QUIRK(0x17aa, 0x38d7, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN), |
| 10578 | + SND_PCI_QUIRK(0x17aa, 0x38f9, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2), | |
| 10579 | + SND_PCI_QUIRK(0x17aa, 0x38fa, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2), | |
| 10547 | 10580 | SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), |
| 10548 | 10581 | SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), |
| 10549 | 10582 | SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), |
| @@ -10581,6 +10614,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 31 unmodified lines | ||
| 10581 | 10614 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ |
| 10582 | 10615 | SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), |
| 10583 | 10616 | SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), |
| 10617 | + SND_PCI_QUIRK(0x1c6c, 0x122a, "Positivo N14AP7", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | |
| 10584 | 10618 | SND_PCI_QUIRK(0x1c6c, 0x1251, "Positivo N14KP6-TG", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 10585 | 10619 | SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_SET_COEF_DEFAULTS), |
| 10586 | 10620 | SND_PCI_QUIRK(0x1d05, 0x1096, "TongFang GMxMRxx", ALC269_FIXUP_NO_SHUTUP), |
| @@ -10605,7 +10639,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 18 unmodified lines | ||
| 10605 | 10639 | SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), |
| 10606 | 10640 | SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC295_FIXUP_CHROME_BOOK), |
| 10607 | 10641 | SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), |
| 10608 | − SND_PCI_QUIRK(0xf111, 0x0005, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), | |
| 10609 | 10642 | SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), |
| 10610 | 10643 | |
| 10611 | 10644 | #if 0 |
| @@ -777,11 +777,11 @@ static void tas2781_hda_remove(struct device *dev) · 776 unmodified lines | ||
| 777 | 777 | { |
| 778 | 778 | struct tas2781_hda *tas_hda = dev_get_drvdata(dev); |
| 779 | 779 | |
| 780 | + component_del(tas_hda->dev, &tas2781_hda_comp_ops); | |
| 781 | + | |
| 780 | 782 | pm_runtime_get_sync(tas_hda->dev); |
| 781 | 783 | pm_runtime_disable(tas_hda->dev); |
| 782 | 784 | |
| 783 | − component_del(tas_hda->dev, &tas2781_hda_comp_ops); | |
| 784 | − | |
| 785 | 785 | pm_runtime_put_noidle(tas_hda->dev); |
| 786 | 786 | |
| 787 | 787 | tasdevice_remove(tas_hda->priv); |
| @@ -17,6 +17,7 @@ endif · 16 unmodified lines | ||
| 17 | 17 | MAKEFLAGS += -r |
| 18 | 18 | |
| 19 | 19 | override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include |
| 20 | +override CFLAGS += -Wno-address-of-packed-member | |
| 20 | 21 | |
| 21 | 22 | ALL_TARGETS := hv_kvp_daemon hv_vss_daemon |
| 22 | 23 | ifneq ($(ARCH), aarch64) |
| @@ -53,6 +53,7 @@ · 52 unmodified lines | ||
| 53 | 53 | #include "verifier_movsx.skel.h" |
| 54 | 54 | #include "verifier_netfilter_ctx.skel.h" |
| 55 | 55 | #include "verifier_netfilter_retcode.skel.h" |
| 56 | +#include "verifier_or_jmp32_k.skel.h" | |
| 56 | 57 | #include "verifier_precision.skel.h" |
| 57 | 58 | #include "verifier_prevent_map_lookup.skel.h" |
| 58 | 59 | #include "verifier_raw_stack.skel.h" |
| @@ -170,6 +171,7 @@ void test_verifier_meta_access(void) { RUN(verifier_meta_access); } · 111 unmodified lines | ||
| 170 | 171 | void test_verifier_movsx(void) { RUN(verifier_movsx); } |
| 171 | 172 | void test_verifier_netfilter_ctx(void) { RUN(verifier_netfilter_ctx); } |
| 172 | 173 | void test_verifier_netfilter_retcode(void) { RUN(verifier_netfilter_retcode); } |
| 174 | +void test_verifier_or_jmp32_k(void) { RUN(verifier_or_jmp32_k); } | |
| 173 | 175 | void test_verifier_precision(void) { RUN(verifier_precision); } |
| 174 | 176 | void test_verifier_prevent_map_lookup(void) { RUN(verifier_prevent_map_lookup); } |
| 175 | 177 | void test_verifier_raw_stack(void) { RUN(verifier_raw_stack); } |
| @@ -0,0 +1,41 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +#include <linux/bpf.h> | |
| 4 | +#include <bpf/bpf_helpers.h> | |
| 5 | +#include "bpf_misc.h" | |
| 6 | + | |
| 7 | +SEC("socket") | |
| 8 | +__description("or_jmp32_k: bit ops + branch on unknown value") | |
| 9 | +__failure | |
| 10 | +__msg("R0 invalid mem access 'scalar'") | |
| 11 | +__naked void or_jmp32_k(void) | |
| 12 | +{ | |
| 13 | + asm volatile (" \ | |
| 14 | + r0 = 0xffffffff; \ | |
| 15 | + r0 /= 1; \ | |
| 16 | + r1 = 0; \ | |
| 17 | + w1 = -1; \ | |
| 18 | + w1 >>= 1; \ | |
| 19 | + w0 &= w1; \ | |
| 20 | + w0 |= 2; \ | |
| 21 | + if w0 != 0x7ffffffd goto l1; \ | |
| 22 | + r0 = 1; \ | |
| 23 | + exit; \ | |
| 24 | +l3: \ | |
| 25 | + r0 = 5; \ | |
| 26 | + *(u64*)(r0 - 8) = r0; \ | |
| 27 | + exit; \ | |
| 28 | +l2: \ | |
| 29 | + w0 -= 0xe; \ | |
| 30 | + if w0 == 1 goto l3; \ | |
| 31 | + r0 = 4; \ | |
| 32 | + exit; \ | |
| 33 | +l1: \ | |
| 34 | + w0 -= 0x7ffffff0; \ | |
| 35 | + if w0 s>= 0xe goto l2; \ | |
| 36 | + r0 = 3; \ | |
| 37 | + exit; \ | |
| 38 | +" ::: __clobber_all); | |
| 39 | +} | |
| 40 | + | |
| 41 | +char _license[] SEC("license") = "GPL"; | |
| @@ -1,2 +1,8 @@ | ||
| 1 | −CONFIG_VIRTIO_NET=y | |
| 1 | +CONFIG_BPF_SYSCALL=y | |
| 2 | +CONFIG_CGROUP_BPF=y | |
| 3 | +CONFIG_IPV6=y | |
| 4 | +CONFIG_IPV6_MULTIPLE_TABLES=y | |
| 5 | +CONFIG_NET_L3_MASTER_DEV=y | |
| 6 | +CONFIG_NET_VRF=m | |
| 2 | 7 | CONFIG_VIRTIO_DEBUG=y |
| 8 | +CONFIG_VIRTIO_NET=y | |
| @@ -1,6 +1,15 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | 2 | |
| 3 | −CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined -static-libasan $(KHDR_INCLUDES) | |
| 3 | +CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined $(KHDR_INCLUDES) | |
| 4 | + | |
| 5 | +# gcc requires -static-libasan in order to ensure that Address Sanitizer's | |
| 6 | +# library is the first one loaded. However, clang already statically links the | |
| 7 | +# Address Sanitizer if -fsanitize is specified. Therefore, simply omit | |
| 8 | +# -static-libasan for clang builds. | |
| 9 | +ifeq ($(LLVM),) | |
| 10 | + CFLAGS += -static-libasan | |
| 11 | +endif | |
| 12 | + | |
| 4 | 13 | TEST_GEN_PROGS := fchmodat2_test |
| 5 | 14 | |
| 6 | 15 | include ../lib.mk |
| @@ -125,8 +125,16 @@ static uint32_t old_root_id, old_parent_id; · 124 unmodified lines | ||
| 125 | 125 | |
| 126 | 126 | static void cleanup_namespace(void) |
| 127 | 127 | { |
| 128 | − fchdir(orig_root); | |
| 129 | − chroot("."); | |
| 128 | + int ret; | |
| 129 | + | |
| 130 | + ret = fchdir(orig_root); | |
| 131 | + if (ret == -1) | |
| 132 | + ksft_perror("fchdir to original root"); | |
| 133 | + | |
| 134 | + ret = chroot("."); | |
| 135 | + if (ret == -1) | |
| 136 | + ksft_perror("chroot to original root"); | |
| 137 | + | |
| 130 | 138 | umount2(root_mntpoint, MNT_DETACH); |
| 131 | 139 | rmdir(root_mntpoint); |
| 132 | 140 | } |
| @@ -277,6 +277,7 @@ struct kvm_x86_cpu_property { · 276 unmodified lines | ||
| 277 | 277 | #define X86_PROPERTY_MAX_EXT_LEAF KVM_X86_CPU_PROPERTY(0x80000000, 0, EAX, 0, 31) |
| 278 | 278 | #define X86_PROPERTY_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 0, 7) |
| 279 | 279 | #define X86_PROPERTY_MAX_VIRT_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 8, 15) |
| 280 | +#define X86_PROPERTY_GUEST_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 16, 23) | |
| 280 | 281 | #define X86_PROPERTY_SEV_C_BIT KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 0, 5) |
| 281 | 282 | #define X86_PROPERTY_PHYS_ADDR_REDUCTION KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 6, 11) |
| 282 | 283 | |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include "kvm_util.h" |
| 11 | 11 | #include "processor.h" |
| 12 | +#include "sbi.h" | |
| 12 | 13 | |
| 13 | 14 | void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu) |
| 14 | 15 | { |
| @@ -1247,9 +1247,20 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm) · 1246 unmodified lines | ||
| 1247 | 1247 | { |
| 1248 | 1248 | const unsigned long num_ht_pages = 12 << (30 - vm->page_shift); /* 12 GiB */ |
| 1249 | 1249 | unsigned long ht_gfn, max_gfn, max_pfn; |
| 1250 | − uint8_t maxphyaddr; | |
| 1250 | + uint8_t maxphyaddr, guest_maxphyaddr; | |
| 1251 | 1251 | |
| 1252 | − max_gfn = (1ULL << (vm->pa_bits - vm->page_shift)) - 1; | |
| 1252 | + /* | |
| 1253 | + * Use "guest MAXPHYADDR" from KVM if it's available. Guest MAXPHYADDR | |
| 1254 | + * enumerates the max _mappable_ GPA, which can be less than the raw | |
| 1255 | + * MAXPHYADDR, e.g. if MAXPHYADDR=52, KVM is using TDP, and the CPU | |
| 1256 | + * doesn't support 5-level TDP. | |
| 1257 | + */ | |
| 1258 | + guest_maxphyaddr = kvm_cpu_property(X86_PROPERTY_GUEST_MAX_PHY_ADDR); | |
| 1259 | + guest_maxphyaddr = guest_maxphyaddr ?: vm->pa_bits; | |
| 1260 | + TEST_ASSERT(guest_maxphyaddr <= vm->pa_bits, | |
| 1261 | + "Guest MAXPHYADDR should never be greater than raw MAXPHYADDR"); | |
| 1262 | + | |
| 1263 | + max_gfn = (1ULL << (guest_maxphyaddr - vm->page_shift)) - 1; | |
| 1253 | 1264 | |
| 1254 | 1265 | /* Avoid reserved HyperTransport region on AMD processors. */ |
| 1255 | 1266 | if (!host_cpu_is_amd) |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * |
| 7 | 7 | */ |
| 8 | 8 | #include "kvm_util.h" |
| 9 | +#include "ucall_common.h" | |
| 9 | 10 | |
| 10 | 11 | #define LABEL_ADDRESS(v) ((uint64_t)&(v)) |
| 11 | 12 | |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include "processor.h" |
| 16 | 16 | #include "sbi.h" |
| 17 | 17 | #include "arch_timer.h" |
| 18 | +#include "ucall_common.h" | |
| 18 | 19 | |
| 19 | 20 | /* Maximum counters(firmware + hardware) */ |
| 20 | 21 | #define RISCV_MAX_PMU_COUNTERS 64 |
| @@ -105,11 +105,11 @@ void test_features(uint32_t vm_type, uint64_t supported_features) · 104 unmodified lines | ||
| 105 | 105 | int i; |
| 106 | 106 | |
| 107 | 107 | for (i = 0; i < 64; i++) { |
| 108 | − if (!(supported_features & (1u << i))) | |
| 108 | + if (!(supported_features & BIT_ULL(i))) | |
| 109 | 109 | test_init2_invalid(vm_type, |
| 110 | 110 | &(struct kvm_sev_init){ .vmsa_features = BIT_ULL(i) }, |
| 111 | 111 | "unknown feature"); |
| 112 | − else if (KNOWN_FEATURES & (1u << i)) | |
| 112 | + else if (KNOWN_FEATURES & BIT_ULL(i)) | |
| 113 | 113 | test_init2(vm_type, |
| 114 | 114 | &(struct kvm_sev_init){ .vmsa_features = BIT_ULL(i) }); |
| 115 | 115 | } |
| @@ -67,7 +67,8 @@ int main(void) · 66 unmodified lines | ||
| 67 | 67 | dump_maps(); |
| 68 | 68 | ksft_exit_fail_msg("Error: munmap failed!?\n"); |
| 69 | 69 | } |
| 70 | − ksft_test_result_pass("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 70 | + ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 71 | + ksft_test_result_pass("mmap() 5*PAGE_SIZE at base\n"); | |
| 71 | 72 | |
| 72 | 73 | addr = base_addr + page_size; |
| 73 | 74 | size = 3 * page_size; |
| @@ -76,7 +77,8 @@ int main(void) · 2 unmodified lines | ||
| 76 | 77 | dump_maps(); |
| 77 | 78 | ksft_exit_fail_msg("Error: first mmap() failed unexpectedly\n"); |
| 78 | 79 | } |
| 79 | − ksft_test_result_pass("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 80 | + ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 81 | + ksft_test_result_pass("mmap() 3*PAGE_SIZE at base+PAGE_SIZE\n"); | |
| 80 | 82 | |
| 81 | 83 | /* |
| 82 | 84 | * Exact same mapping again: |
| @@ -93,7 +95,8 @@ int main(void) · 10 unmodified lines | ||
| 93 | 95 | dump_maps(); |
| 94 | 96 | ksft_exit_fail_msg("Error:1: mmap() succeeded when it shouldn't have\n"); |
| 95 | 97 | } |
| 96 | − ksft_test_result_pass("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 98 | + ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 99 | + ksft_test_result_pass("mmap() 5*PAGE_SIZE at base\n"); | |
| 97 | 100 | |
| 98 | 101 | /* |
| 99 | 102 | * Second mapping contained within first: |
| @@ -111,7 +114,8 @@ int main(void) · 11 unmodified lines | ||
| 111 | 114 | dump_maps(); |
| 112 | 115 | ksft_exit_fail_msg("Error:2: mmap() succeeded when it shouldn't have\n"); |
| 113 | 116 | } |
| 114 | − ksft_test_result_pass("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 117 | + ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 118 | + ksft_test_result_pass("mmap() 2*PAGE_SIZE at base+PAGE_SIZE\n"); | |
| 115 | 119 | |
| 116 | 120 | /* |
| 117 | 121 | * Overlap end of existing mapping: |
| @@ -128,7 +132,8 @@ int main(void) · 10 unmodified lines | ||
| 128 | 132 | dump_maps(); |
| 129 | 133 | ksft_exit_fail_msg("Error:3: mmap() succeeded when it shouldn't have\n"); |
| 130 | 134 | } |
| 131 | − ksft_test_result_pass("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 135 | + ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 136 | + ksft_test_result_pass("mmap() 2*PAGE_SIZE at base+(3*PAGE_SIZE)\n"); | |
| 132 | 137 | |
| 133 | 138 | /* |
| 134 | 139 | * Overlap start of existing mapping: |
| @@ -145,7 +150,8 @@ int main(void) · 10 unmodified lines | ||
| 145 | 150 | dump_maps(); |
| 146 | 151 | ksft_exit_fail_msg("Error:4: mmap() succeeded when it shouldn't have\n"); |
| 147 | 152 | } |
| 148 | − ksft_test_result_pass("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 153 | + ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 154 | + ksft_test_result_pass("mmap() 2*PAGE_SIZE bytes at base\n"); | |
| 149 | 155 | |
| 150 | 156 | /* |
| 151 | 157 | * Adjacent to start of existing mapping: |
| @@ -162,7 +168,8 @@ int main(void) · 10 unmodified lines | ||
| 162 | 168 | dump_maps(); |
| 163 | 169 | ksft_exit_fail_msg("Error:5: mmap() failed when it shouldn't have\n"); |
| 164 | 170 | } |
| 165 | − ksft_test_result_pass("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 171 | + ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 172 | + ksft_test_result_pass("mmap() PAGE_SIZE at base\n"); | |
| 166 | 173 | |
| 167 | 174 | /* |
| 168 | 175 | * Adjacent to end of existing mapping: |
| @@ -179,7 +186,8 @@ int main(void) · 10 unmodified lines | ||
| 179 | 186 | dump_maps(); |
| 180 | 187 | ksft_exit_fail_msg("Error:6: mmap() failed when it shouldn't have\n"); |
| 181 | 188 | } |
| 182 | − ksft_test_result_pass("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 189 | + ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); | |
| 190 | + ksft_test_result_pass("mmap() PAGE_SIZE at base+(4*PAGE_SIZE)\n"); | |
| 183 | 191 | |
| 184 | 192 | addr = base_addr; |
| 185 | 193 | size = 5 * page_size; |
| @@ -43,6 +43,8 @@ TEST_PROGS += srv6_hl2encap_red_l2vpn_test.sh · 42 unmodified lines | ||
| 43 | 43 | TEST_PROGS += srv6_end_next_csid_l3vpn_test.sh |
| 44 | 44 | TEST_PROGS += srv6_end_x_next_csid_l3vpn_test.sh |
| 45 | 45 | TEST_PROGS += srv6_end_flavors_test.sh |
| 46 | +TEST_PROGS += srv6_end_dx4_netfilter_test.sh | |
| 47 | +TEST_PROGS += srv6_end_dx6_netfilter_test.sh | |
| 46 | 48 | TEST_PROGS += vrf_strict_mode_test.sh |
| 47 | 49 | TEST_PROGS += arp_ndisc_evict_nocarrier.sh |
| 48 | 50 | TEST_PROGS += ndisc_unsolicited_na_test.sh |
| @@ -101,3 +101,5 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=m · 100 unmodified lines | ||
| 101 | 101 | CONFIG_CRYPTO_ARIA=y |
| 102 | 102 | CONFIG_XFRM_INTERFACE=m |
| 103 | 103 | CONFIG_XFRM_USER=m |
| 104 | +CONFIG_IP_NF_MATCH_RPFILTER=m | |
| 105 | +CONFIG_IP6_NF_MATCH_RPFILTER=m | |
| @@ -160,10 +160,12 @@ make_connection() · 159 unmodified lines | ||
| 160 | 160 | local is_v6=$1 |
| 161 | 161 | local app_port=$app4_port |
| 162 | 162 | local connect_addr="10.0.1.1" |
| 163 | + local client_addr="10.0.1.2" | |
| 163 | 164 | local listen_addr="0.0.0.0" |
| 164 | 165 | if [ "$is_v6" = "v6" ] |
| 165 | 166 | then |
| 166 | 167 | connect_addr="dead:beef:1::1" |
| 168 | + client_addr="dead:beef:1::2" | |
| 167 | 169 | listen_addr="::" |
| 168 | 170 | app_port=$app6_port |
| 169 | 171 | else |
| @@ -206,6 +208,7 @@ make_connection() · 36 unmodified lines | ||
| 206 | 208 | [ "$server_serverside" = 1 ] |
| 207 | 209 | then |
| 208 | 210 | test_pass |
| 211 | + print_title "Connection info: ${client_addr}:${client_port} -> ${connect_addr}:${app_port}" | |
| 209 | 212 | else |
| 210 | 213 | test_fail "Expected tokens (c:${client_token} - s:${server_token}) and server (c:${client_serverside} - s:${server_serverside})" |
| 211 | 214 | mptcp_lib_result_print_all_tap |
| @@ -297,7 +300,7 @@ test_announce() · 85 unmodified lines | ||
| 297 | 300 | ip netns exec "$ns2"\ |
| 298 | 301 | ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id $client_addr_id dev\ |
| 299 | 302 | ns2eth1 |
| 300 | − print_test "ADD_ADDR id:${client_addr_id} 10.0.2.2 (ns2) => ns1, reuse port" | |
| 303 | + print_test "ADD_ADDR id:client 10.0.2.2 (ns2) => ns1, reuse port" | |
| 301 | 304 | sleep 0.5 |
| 302 | 305 | verify_announce_event $server_evts $ANNOUNCED $server4_token "10.0.2.2" $client_addr_id \ |
| 303 | 306 | "$client4_port" |
| @@ -306,7 +309,7 @@ test_announce() · 2 unmodified lines | ||
| 306 | 309 | :>"$server_evts" |
| 307 | 310 | ip netns exec "$ns2" ./pm_nl_ctl ann\ |
| 308 | 311 | dead:beef:2::2 token "$client6_token" id $client_addr_id dev ns2eth1 |
| 309 | − print_test "ADD_ADDR6 id:${client_addr_id} dead:beef:2::2 (ns2) => ns1, reuse port" | |
| 312 | + print_test "ADD_ADDR6 id:client dead:beef:2::2 (ns2) => ns1, reuse port" | |
| 310 | 313 | sleep 0.5 |
| 311 | 314 | verify_announce_event "$server_evts" "$ANNOUNCED" "$server6_token" "dead:beef:2::2"\ |
| 312 | 315 | "$client_addr_id" "$client6_port" "v6" |
| @@ -316,7 +319,7 @@ test_announce() · 3 unmodified lines | ||
| 316 | 319 | client_addr_id=$((client_addr_id+1)) |
| 317 | 320 | ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ |
| 318 | 321 | $client_addr_id dev ns2eth1 port $new4_port |
| 319 | − print_test "ADD_ADDR id:${client_addr_id} 10.0.2.2 (ns2) => ns1, new port" | |
| 322 | + print_test "ADD_ADDR id:client+1 10.0.2.2 (ns2) => ns1, new port" | |
| 320 | 323 | sleep 0.5 |
| 321 | 324 | verify_announce_event "$server_evts" "$ANNOUNCED" "$server4_token" "10.0.2.2"\ |
| 322 | 325 | "$client_addr_id" "$new4_port" |
| @@ -327,7 +330,7 @@ test_announce() · 4 unmodified lines | ||
| 327 | 330 | # ADD_ADDR from the server to client machine reusing the subflow port |
| 328 | 331 | ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ |
| 329 | 332 | $server_addr_id dev ns1eth2 |
| 330 | − print_test "ADD_ADDR id:${server_addr_id} 10.0.2.1 (ns1) => ns2, reuse port" | |
| 333 | + print_test "ADD_ADDR id:server 10.0.2.1 (ns1) => ns2, reuse port" | |
| 331 | 334 | sleep 0.5 |
| 332 | 335 | verify_announce_event "$client_evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ |
| 333 | 336 | "$server_addr_id" "$app4_port" |
| @@ -336,7 +339,7 @@ test_announce() · 2 unmodified lines | ||
| 336 | 339 | :>"$client_evts" |
| 337 | 340 | ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\ |
| 338 | 341 | $server_addr_id dev ns1eth2 |
| 339 | − print_test "ADD_ADDR6 id:${server_addr_id} dead:beef:2::1 (ns1) => ns2, reuse port" | |
| 342 | + print_test "ADD_ADDR6 id:server dead:beef:2::1 (ns1) => ns2, reuse port" | |
| 340 | 343 | sleep 0.5 |
| 341 | 344 | verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "dead:beef:2::1"\ |
| 342 | 345 | "$server_addr_id" "$app6_port" "v6" |
| @@ -346,7 +349,7 @@ test_announce() · 3 unmodified lines | ||
| 346 | 349 | server_addr_id=$((server_addr_id+1)) |
| 347 | 350 | ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ |
| 348 | 351 | $server_addr_id dev ns1eth2 port $new4_port |
| 349 | − print_test "ADD_ADDR id:${server_addr_id} 10.0.2.1 (ns1) => ns2, new port" | |
| 352 | + print_test "ADD_ADDR id:server+1 10.0.2.1 (ns1) => ns2, new port" | |
| 350 | 353 | sleep 0.5 |
| 351 | 354 | verify_announce_event "$client_evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ |
| 352 | 355 | "$server_addr_id" "$new4_port" |
| @@ -380,7 +383,7 @@ test_remove() · 27 unmodified lines | ||
| 380 | 383 | local invalid_token=$(( client4_token - 1 )) |
| 381 | 384 | ip netns exec "$ns2" ./pm_nl_ctl rem token $invalid_token id\ |
| 382 | 385 | $client_addr_id > /dev/null 2>&1 |
| 383 | − print_test "RM_ADDR id:${client_addr_id} ns2 => ns1, invalid token" | |
| 386 | + print_test "RM_ADDR id:client ns2 => ns1, invalid token" | |
| 384 | 387 | local type |
| 385 | 388 | type=$(mptcp_lib_evts_get_info type "$server_evts") |
| 386 | 389 | if [ "$type" = "" ] |
| @@ -394,7 +397,7 @@ test_remove() · 7 unmodified lines | ||
| 394 | 397 | local invalid_id=$(( client_addr_id + 1 )) |
| 395 | 398 | ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ |
| 396 | 399 | $invalid_id > /dev/null 2>&1 |
| 397 | − print_test "RM_ADDR id:${invalid_id} ns2 => ns1, invalid id" | |
| 400 | + print_test "RM_ADDR id:client+1 ns2 => ns1, invalid id" | |
| 398 | 401 | type=$(mptcp_lib_evts_get_info type "$server_evts") |
| 399 | 402 | if [ "$type" = "" ] |
| 400 | 403 | then |
| @@ -407,7 +410,7 @@ test_remove() · 6 unmodified lines | ||
| 407 | 410 | :>"$server_evts" |
| 408 | 411 | ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ |
| 409 | 412 | $client_addr_id |
| 410 | − print_test "RM_ADDR id:${client_addr_id} ns2 => ns1" | |
| 413 | + print_test "RM_ADDR id:client ns2 => ns1" | |
| 411 | 414 | sleep 0.5 |
| 412 | 415 | verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" |
| 413 | 416 | |
| @@ -416,7 +419,7 @@ test_remove() · 2 unmodified lines | ||
| 416 | 419 | client_addr_id=$(( client_addr_id - 1 )) |
| 417 | 420 | ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ |
| 418 | 421 | $client_addr_id |
| 419 | − print_test "RM_ADDR id:${client_addr_id} ns2 => ns1" | |
| 422 | + print_test "RM_ADDR id:client-1 ns2 => ns1" | |
| 420 | 423 | sleep 0.5 |
| 421 | 424 | verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" |
| 422 | 425 | |
| @@ -424,7 +427,7 @@ test_remove() · 1 unmodified line | ||
| 424 | 427 | :>"$server_evts" |
| 425 | 428 | ip netns exec "$ns2" ./pm_nl_ctl rem token "$client6_token" id\ |
| 426 | 429 | $client_addr_id |
| 427 | − print_test "RM_ADDR6 id:${client_addr_id} ns2 => ns1" | |
| 430 | + print_test "RM_ADDR6 id:client-1 ns2 => ns1" | |
| 428 | 431 | sleep 0.5 |
| 429 | 432 | verify_remove_event "$server_evts" "$REMOVED" "$server6_token" "$client_addr_id" |
| 430 | 433 | |
| @@ -434,7 +437,7 @@ test_remove() · 3 unmodified lines | ||
| 434 | 437 | # RM_ADDR from the server to client machine |
| 435 | 438 | ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ |
| 436 | 439 | $server_addr_id |
| 437 | − print_test "RM_ADDR id:${server_addr_id} ns1 => ns2" | |
| 440 | + print_test "RM_ADDR id:server ns1 => ns2" | |
| 438 | 441 | sleep 0.5 |
| 439 | 442 | verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" |
| 440 | 443 | |
| @@ -443,7 +446,7 @@ test_remove() · 2 unmodified lines | ||
| 443 | 446 | server_addr_id=$(( server_addr_id - 1 )) |
| 444 | 447 | ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ |
| 445 | 448 | $server_addr_id |
| 446 | − print_test "RM_ADDR id:${server_addr_id} ns1 => ns2" | |
| 449 | + print_test "RM_ADDR id:server-1 ns1 => ns2" | |
| 447 | 450 | sleep 0.5 |
| 448 | 451 | verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" |
| 449 | 452 | |
| @@ -451,7 +454,7 @@ test_remove() · 1 unmodified line | ||
| 451 | 454 | :>"$client_evts" |
| 452 | 455 | ip netns exec "$ns1" ./pm_nl_ctl rem token "$server6_token" id\ |
| 453 | 456 | $server_addr_id |
| 454 | − print_test "RM_ADDR6 id:${server_addr_id} ns1 => ns2" | |
| 457 | + print_test "RM_ADDR6 id:server-1 ns1 => ns2" | |
| 455 | 458 | sleep 0.5 |
| 456 | 459 | verify_remove_event "$client_evts" "$REMOVED" "$client6_token" "$server_addr_id" |
| 457 | 460 | } |
| @@ -479,8 +482,14 @@ verify_subflow_events() · 21 unmodified lines | ||
| 479 | 482 | local locid |
| 480 | 483 | local remid |
| 481 | 484 | local info |
| 485 | + local e_dport_txt | |
| 482 | 486 | |
| 483 | − info="${e_saddr} (${e_from}) => ${e_daddr}:${e_dport} (${e_to})" | |
| 487 | + # only display the fixed ports | |
| 488 | + if [ "${e_dport}" -ge "${app4_port}" ] && [ "${e_dport}" -le "${app6_port}" ]; then | |
| 489 | + e_dport_txt=":${e_dport}" | |
| 490 | + fi | |
| 491 | + | |
| 492 | + info="${e_saddr} (${e_from}) => ${e_daddr}${e_dport_txt} (${e_to})" | |
| 484 | 493 | |
| 485 | 494 | if [ "$e_type" = "$SUB_ESTABLISHED" ] |
| 486 | 495 | then |
| @@ -766,7 +775,7 @@ test_subflows_v4_v6_mix() · 279 unmodified lines | ||
| 766 | 775 | :>"$client_evts" |
| 767 | 776 | ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server6_token" id\ |
| 768 | 777 | $server_addr_id dev ns1eth2 |
| 769 | − print_test "ADD_ADDR4 id:${server_addr_id} 10.0.2.1 (ns1) => ns2, reuse port" | |
| 778 | + print_test "ADD_ADDR4 id:server 10.0.2.1 (ns1) => ns2, reuse port" | |
| 770 | 779 | sleep 0.5 |
| 771 | 780 | verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "10.0.2.1"\ |
| 772 | 781 | "$server_addr_id" "$app6_port" |
| @@ -861,7 +870,7 @@ test_listener() · 88 unmodified lines | ||
| 861 | 870 | local listener_pid=$! |
| 862 | 871 | |
| 863 | 872 | sleep 0.5 |
| 864 | − print_test "CREATE_LISTENER 10.0.2.2:$client4_port" | |
| 873 | + print_test "CREATE_LISTENER 10.0.2.2 (client port)" | |
| 865 | 874 | verify_listener_events $client_evts $LISTENER_CREATED $AF_INET 10.0.2.2 $client4_port |
| 866 | 875 | |
| 867 | 876 | # ADD_ADDR from client to server machine reusing the subflow port |
| @@ -878,13 +887,14 @@ test_listener() · 10 unmodified lines | ||
| 878 | 887 | mptcp_lib_kill_wait $listener_pid |
| 879 | 888 | |
| 880 | 889 | sleep 0.5 |
| 881 | − print_test "CLOSE_LISTENER 10.0.2.2:$client4_port" | |
| 890 | + print_test "CLOSE_LISTENER 10.0.2.2 (client port)" | |
| 882 | 891 | verify_listener_events $client_evts $LISTENER_CLOSED $AF_INET 10.0.2.2 $client4_port |
| 883 | 892 | } |
| 884 | 893 | |
| 885 | 894 | print_title "Make connections" |
| 886 | 895 | make_connection |
| 887 | 896 | make_connection "v6" |
| 897 | +print_title "Will be using address IDs ${client_addr_id} (client) and ${server_addr_id} (server)" | |
| 888 | 898 | |
| 889 | 899 | test_announce |
| 890 | 900 | test_remove |
| @@ -1,4 +1,4 @@ | ||
| 1 | −#!/bin/sh | |
| 1 | +#!/bin/bash | |
| 2 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | # |
| 4 | 4 | # OVS kernel module self tests |
| @@ -531,7 +531,7 @@ class ovsactions(nla): · 530 unmodified lines | ||
| 531 | 531 | for flat_act in parse_flat_map: |
| 532 | 532 | if parse_starts_block(actstr, flat_act[0], False): |
| 533 | 533 | actstr = actstr[len(flat_act[0]):] |
| 534 | − self["attrs"].append([flat_act[1]]) | |
| 534 | + self["attrs"].append([flat_act[1], True]) | |
| 535 | 535 | actstr = actstr[strspn(actstr, ", ") :] |
| 536 | 536 | parsed = True |
| 537 | 537 | |
| @@ -0,0 +1,335 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +# SPDX-License-Identifier: GPL-2.0 | |
| 3 | +# | |
| 4 | +# author: Jianguo Wu <wujianguo@chinatelecom.cn> | |
| 5 | +# | |
| 6 | +# Mostly copied from tools/testing/selftests/net/srv6_end_dt4_l3vpn_test.sh. | |
| 7 | +# | |
| 8 | +# This script is designed for testing the support of netfilter hooks for | |
| 9 | +# SRv6 End.DX4 behavior. | |
| 10 | +# | |
| 11 | +# Hereafter a network diagram is shown, where one tenants (named 100) offer | |
| 12 | +# IPv4 L3 VPN services allowing hosts to communicate with each other across | |
| 13 | +# an IPv6 network. | |
| 14 | +# | |
| 15 | +# Routers rt-1 and rt-2 implement IPv4 L3 VPN services leveraging the SRv6 | |
| 16 | +# architecture. The key components for such VPNs are: a) SRv6 Encap behavior, | |
| 17 | +# b) SRv6 End.DX4 behavior. | |
| 18 | +# | |
| 19 | +# To explain how an IPv4 L3 VPN based on SRv6 works, let us briefly consider an | |
| 20 | +# example where, within the same domain of tenant 100, the host hs-1 pings | |
| 21 | +# the host hs-2. | |
| 22 | +# | |
| 23 | +# First of all, L2 reachability of the host hs-2 is taken into account by | |
| 24 | +# the router rt-1 which acts as an arp proxy. | |
| 25 | +# | |
| 26 | +# When the host hs-1 sends an IPv4 packet destined to hs-2, the router rt-1 | |
| 27 | +# receives the packet on the internal veth-t100 interface, rt-1 contains the | |
| 28 | +# SRv6 Encap route for encapsulating the IPv4 packet in a IPv6 plus the Segment | |
| 29 | +# Routing Header (SRH) packet. This packet is sent through the (IPv6) core | |
| 30 | +# network up to the router rt-2 that receives it on veth0 interface. | |
| 31 | +# | |
| 32 | +# The rt-2 router uses the 'localsid' routing table to process incoming | |
| 33 | +# IPv6+SRH packets which belong to the VPN of the tenant 100. For each of these | |
| 34 | +# packets, the SRv6 End.DX4 behavior removes the outer IPv6+SRH headers and | |
| 35 | +# routs the packet to the specified nexthop. Afterwards, the packet is sent to | |
| 36 | +# the host hs-2 through the veth-t100 interface. | |
| 37 | +# | |
| 38 | +# The ping response follows the same processing but this time the role of rt-1 | |
| 39 | +# and rt-2 are swapped. | |
| 40 | +# | |
| 41 | +# And when net.netfilter.nf_hooks_lwtunnel is set to 1 in rt-1 or rt-2, and a | |
| 42 | +# rpfilter iptables rule is added, SRv6 packets will go through netfilter PREROUTING | |
| 43 | +# hooks. | |
| 44 | +# | |
| 45 | +# | |
| 46 | +# +-------------------+ +-------------------+ | |
| 47 | +# | | | | | |
| 48 | +# | hs-1 netns | | hs-2 netns | | |
| 49 | +# | | | | | |
| 50 | +# | +-------------+ | | +-------------+ | | |
| 51 | +# | | veth0 | | | | veth0 | | | |
| 52 | +# | | 10.0.0.1/24 | | | | 10.0.0.2/24 | | | |
| 53 | +# | +-------------+ | | +-------------+ | | |
| 54 | +# | . | | . | | |
| 55 | +# +-------------------+ +-------------------+ | |
| 56 | +# . . | |
| 57 | +# . . | |
| 58 | +# . . | |
| 59 | +# +-----------------------------------+ +-----------------------------------+ | |
| 60 | +# | . | | . | | |
| 61 | +# | +---------------+ | | +---------------- | | |
| 62 | +# | | veth-t100 | | | | veth-t100 | | | |
| 63 | +# | | 10.0.0.11/24 | +----------+ | | +----------+ | 10.0.0.22/24 | | | |
| 64 | +# | +-------+-------+ | route | | | | route | +-------+-------- | | |
| 65 | +# | | table | | | | table | | | |
| 66 | +# | +----------+ | | +----------+ | | |
| 67 | +# | +--------------+ | | +--------------+ | | |
| 68 | +# | | veth0 | | | | veth0 | | | |
| 69 | +# | | 2001:11::1/64 |.|...|.| 2001:11::2/64 | | | |
| 70 | +# | +--------------+ | | +--------------+ | | |
| 71 | +# | | | | | |
| 72 | +# | rt-1 netns | | rt-2 netns | | |
| 73 | +# | | | | | |
| 74 | +# +-----------------------------------+ +-----------------------------------+ | |
| 75 | +# | |
| 76 | +# ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 77 | +# | Network configuration | | |
| 78 | +# ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 79 | +# | |
| 80 | +# rt-1: localsid table | |
| 81 | +# +----------------------------------------------------------------+ | |
| 82 | +# |SID |Action | | |
| 83 | +# +----------------------------------------------------------------+ | |
| 84 | +# |fc00:21:100::6004|apply SRv6 End.DX4 nh4 10.0.0.1 dev veth-t100 | | |
| 85 | +# +----------------------------------------------------------------+ | |
| 86 | +# | |
| 87 | +# rt-1: route table | |
| 88 | +# +---------------------------------------------------+ | |
| 89 | +# |host |Action | | |
| 90 | +# +---------------------------------------------------+ | |
| 91 | +# |10.0.0.2 |apply seg6 encap segs fc00:12:100::6004| | |
| 92 | +# +---------------------------------------------------+ | |
| 93 | +# |10.0.0.0/24|forward to dev veth_t100 | | |
| 94 | +# +---------------------------------------------------+ | |
| 95 | +# | |
| 96 | +# | |
| 97 | +# rt-2: localsid table | |
| 98 | +# +---------------------------------------------------------------+ | |
| 99 | +# |SID |Action | | |
| 100 | +# +---------------------------------------------------------------+ | |
| 101 | +# |fc00:12:100::6004|apply SRv6 End.DX4 nh4 10.0.0.2 dev veth-t100| | |
| 102 | +# +---------------------------------------------------------------+ | |
| 103 | +# | |
| 104 | +# rt-2: route table | |
| 105 | +# +---------------------------------------------------+ | |
| 106 | +# |host |Action | | |
| 107 | +# +---------------------------------------------------+ | |
| 108 | +# |10.0.0.1 |apply seg6 encap segs fc00:21:100::6004| | |
| 109 | +# +---------------------------------------------------+ | |
| 110 | +# |10.0.0.0/24|forward to dev veth_t100 | | |
| 111 | +# +---------------------------------------------------+ | |
| 112 | +# | |
| 113 | + | |
| 114 | +# Kselftest framework requirement - SKIP code is 4. | |
| 115 | +ksft_skip=4 | |
| 116 | + | |
| 117 | +readonly IPv6_RT_NETWORK=2001:11 | |
| 118 | +readonly IPv4_HS_NETWORK=10.0.0 | |
| 119 | +readonly SID_LOCATOR=fc00 | |
| 120 | + | |
| 121 | +PING_TIMEOUT_SEC=4 | |
| 122 | + | |
| 123 | +ret=0 | |
| 124 | + | |
| 125 | +PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} | |
| 126 | + | |
| 127 | +log_test() | |
| 128 | +{ | |
| 129 | + local rc=$1 | |
| 130 | + local expected=$2 | |
| 131 | + local msg="$3" | |
| 132 | + | |
| 133 | + if [ ${rc} -eq ${expected} ]; then | |
| 134 | + nsuccess=$((nsuccess+1)) | |
| 135 | + printf "\n TEST: %-60s [ OK ]\n" "${msg}" | |
| 136 | + else | |
| 137 | + ret=1 | |
| 138 | + nfail=$((nfail+1)) | |
| 139 | + printf "\n TEST: %-60s [FAIL]\n" "${msg}" | |
| 140 | + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then | |
| 141 | + echo | |
| 142 | + echo "hit enter to continue, 'q' to quit" | |
| 143 | + read a | |
| 144 | + [ "$a" = "q" ] && exit 1 | |
| 145 | + fi | |
| 146 | + fi | |
| 147 | +} | |
| 148 | + | |
| 149 | +print_log_test_results() | |
| 150 | +{ | |
| 151 | + if [ "$TESTS" != "none" ]; then | |
| 152 | + printf "\nTests passed: %3d\n" ${nsuccess} | |
| 153 | + printf "Tests failed: %3d\n" ${nfail} | |
| 154 | + fi | |
| 155 | +} | |
| 156 | + | |
| 157 | +log_section() | |
| 158 | +{ | |
| 159 | + echo | |
| 160 | + echo "################################################################################" | |
| 161 | + echo "TEST SECTION: $*" | |
| 162 | + echo "################################################################################" | |
| 163 | +} | |
| 164 | + | |
| 165 | +cleanup() | |
| 166 | +{ | |
| 167 | + ip link del veth-rt-1 2>/dev/null || true | |
| 168 | + ip link del veth-rt-2 2>/dev/null || true | |
| 169 | + | |
| 170 | + # destroy routers rt-* and hosts hs-* | |
| 171 | + for ns in $(ip netns show | grep -E 'rt-*|hs-*'); do | |
| 172 | + ip netns del ${ns} || true | |
| 173 | + done | |
| 174 | +} | |
| 175 | + | |
| 176 | +# Setup the basic networking for the routers | |
| 177 | +setup_rt_networking() | |
| 178 | +{ | |
| 179 | + local rt=$1 | |
| 180 | + local nsname=rt-${rt} | |
| 181 | + | |
| 182 | + ip netns add ${nsname} | |
| 183 | + | |
| 184 | + ip netns exec ${nsname} sysctl -wq net.ipv6.conf.all.accept_dad=0 | |
| 185 | + ip netns exec ${nsname} sysctl -wq net.ipv6.conf.default.accept_dad=0 | |
| 186 | + | |
| 187 | + ip link set veth-rt-${rt} netns ${nsname} | |
| 188 | + ip -netns ${nsname} link set veth-rt-${rt} name veth0 | |
| 189 | + | |
| 190 | + ip -netns ${nsname} addr add ${IPv6_RT_NETWORK}::${rt}/64 dev veth0 nodad | |
| 191 | + ip -netns ${nsname} link set veth0 up | |
| 192 | + ip -netns ${nsname} link set lo up | |
| 193 | + | |
| 194 | + ip netns exec ${nsname} sysctl -wq net.ipv4.ip_forward=1 | |
| 195 | + ip netns exec ${nsname} sysctl -wq net.ipv6.conf.all.forwarding=1 | |
| 196 | +} | |
| 197 | + | |
| 198 | +setup_rt_netfilter() | |
| 199 | +{ | |
| 200 | + local rt=$1 | |
| 201 | + local nsname=rt-${rt} | |
| 202 | + | |
| 203 | + ip netns exec ${nsname} sysctl -wq net.netfilter.nf_hooks_lwtunnel=1 | |
| 204 | + ip netns exec ${nsname} iptables -t raw -A PREROUTING -m rpfilter --invert -j DROP | |
| 205 | +} | |
| 206 | + | |
| 207 | +setup_hs() | |
| 208 | +{ | |
| 209 | + local hs=$1 | |
| 210 | + local rt=$2 | |
| 211 | + local tid=$3 | |
| 212 | + local hsname=hs-${hs} | |
| 213 | + local rtname=rt-${rt} | |
| 214 | + local rtveth=veth-t${tid} | |
| 215 | + | |
| 216 | + # set the networking for the host | |
| 217 | + ip netns add ${hsname} | |
| 218 | + | |
| 219 | + ip -netns ${hsname} link add veth0 type veth peer name ${rtveth} | |
| 220 | + ip -netns ${hsname} link set ${rtveth} netns ${rtname} | |
| 221 | + ip -netns ${hsname} addr add ${IPv4_HS_NETWORK}.${hs}/24 dev veth0 | |
| 222 | + ip -netns ${hsname} link set veth0 up | |
| 223 | + ip -netns ${hsname} link set lo up | |
| 224 | + | |
| 225 | + ip -netns ${rtname} addr add ${IPv4_HS_NETWORK}.${rt}${hs}/24 dev ${rtveth} | |
| 226 | + ip -netns ${rtname} link set ${rtveth} up | |
| 227 | + | |
| 228 | + ip netns exec ${rtname} sysctl -wq net.ipv4.conf.${rtveth}.proxy_arp=1 | |
| 229 | +} | |
| 230 | + | |
| 231 | +setup_vpn_config() | |
| 232 | +{ | |
| 233 | + local hssrc=$1 | |
| 234 | + local rtsrc=$2 | |
| 235 | + local hsdst=$3 | |
| 236 | + local rtdst=$4 | |
| 237 | + local tid=$5 | |
| 238 | + | |
| 239 | + local hssrc_name=hs-t${tid}-${hssrc} | |
| 240 | + local hsdst_name=hs-t${tid}-${hsdst} | |
| 241 | + local rtsrc_name=rt-${rtsrc} | |
| 242 | + local rtdst_name=rt-${rtdst} | |
| 243 | + local vpn_sid=${SID_LOCATOR}:${hssrc}${hsdst}:${tid}::6004 | |
| 244 | + | |
| 245 | + # set the encap route for encapsulating packets which arrive from the | |
| 246 | + # host hssrc and destined to the access router rtsrc. | |
| 247 | + ip -netns ${rtsrc_name} -4 route add ${IPv4_HS_NETWORK}.${hsdst}/32 \ | |
| 248 | + encap seg6 mode encap segs ${vpn_sid} dev veth0 | |
| 249 | + ip -netns ${rtsrc_name} -6 route add ${vpn_sid}/128 \ | |
| 250 | + via 2001:11::${rtdst} dev veth0 | |
| 251 | + | |
| 252 | + # set the decap route for decapsulating packets which arrive from | |
| 253 | + # the rtdst router and destined to the hsdst host. | |
| 254 | + ip -netns ${rtdst_name} -6 route add ${vpn_sid}/128 \ | |
| 255 | + encap seg6local action End.DX4 nh4 ${IPv4_HS_NETWORK}.${hsdst} dev veth-t${tid} | |
| 256 | +} | |
| 257 | + | |
| 258 | +setup() | |
| 259 | +{ | |
| 260 | + ip link add veth-rt-1 type veth peer name veth-rt-2 | |
| 261 | + # setup the networking for router rt-1 and router rt-2 | |
| 262 | + setup_rt_networking 1 | |
| 263 | + setup_rt_networking 2 | |
| 264 | + | |
| 265 | + # setup two hosts for the tenant 100. | |
| 266 | + # - host hs-1 is directly connected to the router rt-1; | |
| 267 | + # - host hs-2 is directly connected to the router rt-2. | |
| 268 | + setup_hs 1 1 100 | |
| 269 | + setup_hs 2 2 100 | |
| 270 | + | |
| 271 | + # setup the IPv4 L3 VPN which connects the host hs-1 and host hs-2. | |
| 272 | + setup_vpn_config 1 1 2 2 100 #args: src_host src_router dst_host dst_router tenant | |
| 273 | + setup_vpn_config 2 2 1 1 100 | |
| 274 | +} | |
| 275 | + | |
| 276 | +check_hs_connectivity() | |
| 277 | +{ | |
| 278 | + local hssrc=$1 | |
| 279 | + local hsdst=$2 | |
| 280 | + local tid=$3 | |
| 281 | + | |
| 282 | + ip netns exec hs-${hssrc} ping -c 1 -W ${PING_TIMEOUT_SEC} \ | |
| 283 | + ${IPv4_HS_NETWORK}.${hsdst} >/dev/null 2>&1 | |
| 284 | +} | |
| 285 | + | |
| 286 | +check_and_log_hs_connectivity() | |
| 287 | +{ | |
| 288 | + local hssrc=$1 | |
| 289 | + local hsdst=$2 | |
| 290 | + local tid=$3 | |
| 291 | + | |
| 292 | + check_hs_connectivity ${hssrc} ${hsdst} ${tid} | |
| 293 | + log_test $? 0 "Hosts connectivity: hs-${hssrc} -> hs-${hsdst} (tenant ${tid})" | |
| 294 | +} | |
| 295 | + | |
| 296 | +host_tests() | |
| 297 | +{ | |
| 298 | + log_section "SRv6 VPN connectivity test among hosts in the same tenant" | |
| 299 | + | |
| 300 | + check_and_log_hs_connectivity 1 2 100 | |
| 301 | + check_and_log_hs_connectivity 2 1 100 | |
| 302 | +} | |
| 303 | + | |
| 304 | +router_netfilter_tests() | |
| 305 | +{ | |
| 306 | + log_section "SRv6 VPN connectivity test with netfilter enabled in routers" | |
| 307 | + setup_rt_netfilter 1 | |
| 308 | + setup_rt_netfilter 2 | |
| 309 | + | |
| 310 | + check_and_log_hs_connectivity 1 2 100 | |
| 311 | + check_and_log_hs_connectivity 2 1 100 | |
| 312 | +} | |
| 313 | + | |
| 314 | +if [ "$(id -u)" -ne 0 ];then | |
| 315 | + echo "SKIP: Need root privileges" | |
| 316 | + exit $ksft_skip | |
| 317 | +fi | |
| 318 | + | |
| 319 | +if [ ! -x "$(command -v ip)" ]; then | |
| 320 | + echo "SKIP: Could not run test without ip tool" | |
| 321 | + exit $ksft_skip | |
| 322 | +fi | |
| 323 | + | |
| 324 | +cleanup &>/dev/null | |
| 325 | + | |
| 326 | +setup | |
| 327 | + | |
| 328 | +host_tests | |
| 329 | +router_netfilter_tests | |
| 330 | + | |
| 331 | +print_log_test_results | |
| 332 | + | |
| 333 | +cleanup &>/dev/null | |
| 334 | + | |
| 335 | +exit ${ret} | |
| @@ -0,0 +1,340 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +# SPDX-License-Identifier: GPL-2.0 | |
| 3 | +# | |
| 4 | +# author: Jianguo Wu <wujianguo@chinatelecom.cn> | |
| 5 | +# | |
| 6 | +# Mostly copied from tools/testing/selftests/net/srv6_end_dt6_l3vpn_test.sh. | |
| 7 | +# | |
| 8 | +# This script is designed for testing the support of netfilter hooks for | |
| 9 | +# SRv6 End.DX4 behavior. | |
| 10 | +# | |
| 11 | +# Hereafter a network diagram is shown, where one tenants (named 100) offer | |
| 12 | +# IPv6 L3 VPN services allowing hosts to communicate with each other across | |
| 13 | +# an IPv6 network. | |
| 14 | +# | |
| 15 | +# Routers rt-1 and rt-2 implement IPv6 L3 VPN services leveraging the SRv6 | |
| 16 | +# architecture. The key components for such VPNs are: a) SRv6 Encap behavior, | |
| 17 | +# b) SRv6 End.DX4 behavior. | |
| 18 | +# | |
| 19 | +# To explain how an IPv6 L3 VPN based on SRv6 works, let us briefly consider an | |
| 20 | +# example where, within the same domain of tenant 100, the host hs-1 pings | |
| 21 | +# the host hs-2. | |
| 22 | +# | |
| 23 | +# First of all, L2 reachability of the host hs-2 is taken into account by | |
| 24 | +# the router rt-1 which acts as an arp proxy. | |
| 25 | +# | |
| 26 | +# When the host hs-1 sends an IPv6 packet destined to hs-2, the router rt-1 | |
| 27 | +# receives the packet on the internal veth-t100 interface, rt-1 contains the | |
| 28 | +# SRv6 Encap route for encapsulating the IPv6 packet in a IPv6 plus the Segment | |
| 29 | +# Routing Header (SRH) packet. This packet is sent through the (IPv6) core | |
| 30 | +# network up to the router rt-2 that receives it on veth0 interface. | |
| 31 | +# | |
| 32 | +# The rt-2 router uses the 'localsid' routing table to process incoming | |
| 33 | +# IPv6+SRH packets which belong to the VPN of the tenant 100. For each of these | |
| 34 | +# packets, the SRv6 End.DX4 behavior removes the outer IPv6+SRH headers and | |
| 35 | +# routs the packet to the specified nexthop. Afterwards, the packet is sent to | |
| 36 | +# the host hs-2 through the veth-t100 interface. | |
| 37 | +# | |
| 38 | +# The ping response follows the same processing but this time the role of rt-1 | |
| 39 | +# and rt-2 are swapped. | |
| 40 | +# | |
| 41 | +# And when net.netfilter.nf_hooks_lwtunnel is set to 1 in rt-1 or rt-2, and a | |
| 42 | +# rpfilter iptables rule is added, SRv6 packets will go through netfilter PREROUTING | |
| 43 | +# hooks. | |
| 44 | +# | |
| 45 | +# | |
| 46 | +# +-------------------+ +-------------------+ | |
| 47 | +# | | | | | |
| 48 | +# | hs-1 netns | | hs-2 netns | | |
| 49 | +# | | | | | |
| 50 | +# | +-------------+ | | +-------------+ | | |
| 51 | +# | | veth0 | | | | veth0 | | | |
| 52 | +# | | cafe::1/64 | | | | cafe::2/64 | | | |
| 53 | +# | +-------------+ | | +-------------+ | | |
| 54 | +# | . | | . | | |
| 55 | +# +-------------------+ +-------------------+ | |
| 56 | +# . . | |
| 57 | +# . . | |
| 58 | +# . . | |
| 59 | +# +-----------------------------------+ +-----------------------------------+ | |
| 60 | +# | . | | . | | |
| 61 | +# | +---------------+ | | +---------------- | | |
| 62 | +# | | veth-t100 | | | | veth-t100 | | | |
| 63 | +# | | cafe::11/64 | +----------+ | | +----------+ | cafe::22/64 | | | |
| 64 | +# | +-------+-------+ | route | | | | route | +-------+-------- | | |
| 65 | +# | | table | | | | table | | | |
| 66 | +# | +----------+ | | +----------+ | | |
| 67 | +# | +--------------+ | | +--------------+ | | |
| 68 | +# | | veth0 | | | | veth0 | | | |
| 69 | +# | | 2001:11::1/64 |.|...|.| 2001:11::2/64 | | | |
| 70 | +# | +--------------+ | | +--------------+ | | |
| 71 | +# | | | | | |
| 72 | +# | rt-1 netns | | rt-2 netns | | |
| 73 | +# | | | | | |
| 74 | +# +-----------------------------------+ +-----------------------------------+ | |
| 75 | +# | |
| 76 | +# ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 77 | +# | Network configuration | | |
| 78 | +# ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 79 | +# | |
| 80 | +# rt-1: localsid table | |
| 81 | +# +----------------------------------------------------------------+ | |
| 82 | +# |SID |Action | | |
| 83 | +# +----------------------------------------------------------------+ | |
| 84 | +# |fc00:21:100::6004|apply SRv6 End.DX6 nh6 cafe::1 dev veth-t100 | | |
| 85 | +# +----------------------------------------------------------------+ | |
| 86 | +# | |
| 87 | +# rt-1: route table | |
| 88 | +# +---------------------------------------------------+ | |
| 89 | +# |host |Action | | |
| 90 | +# +---------------------------------------------------+ | |
| 91 | +# |cafe::2 |apply seg6 encap segs fc00:12:100::6004| | |
| 92 | +# +---------------------------------------------------+ | |
| 93 | +# |cafe::/64 |forward to dev veth_t100 | | |
| 94 | +# +---------------------------------------------------+ | |
| 95 | +# | |
| 96 | +# | |
| 97 | +# rt-2: localsid table | |
| 98 | +# +---------------------------------------------------------------+ | |
| 99 | +# |SID |Action | | |
| 100 | +# +---------------------------------------------------------------+ | |
| 101 | +# |fc00:12:100::6004|apply SRv6 End.DX6 nh6 cafe::2 dev veth-t100 | | |
| 102 | +# +---------------------------------------------------------------+ | |
| 103 | +# | |
| 104 | +# rt-2: route table | |
| 105 | +# +---------------------------------------------------+ | |
| 106 | +# |host |Action | | |
| 107 | +# +---------------------------------------------------+ | |
| 108 | +# |cafe::1 |apply seg6 encap segs fc00:21:100::6004| | |
| 109 | +# +---------------------------------------------------+ | |
| 110 | +# |cafe::/64 |forward to dev veth_t100 | | |
| 111 | +# +---------------------------------------------------+ | |
| 112 | +# | |
| 113 | + | |
| 114 | +# Kselftest framework requirement - SKIP code is 4. | |
| 115 | +ksft_skip=4 | |
| 116 | + | |
| 117 | +readonly IPv6_RT_NETWORK=2001:11 | |
| 118 | +readonly IPv6_HS_NETWORK=cafe | |
| 119 | +readonly SID_LOCATOR=fc00 | |
| 120 | + | |
| 121 | +PING_TIMEOUT_SEC=4 | |
| 122 | + | |
| 123 | +ret=0 | |
| 124 | + | |
| 125 | +PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} | |
| 126 | + | |
| 127 | +log_test() | |
| 128 | +{ | |
| 129 | + local rc=$1 | |
| 130 | + local expected=$2 | |
| 131 | + local msg="$3" | |
| 132 | + | |
| 133 | + if [ ${rc} -eq ${expected} ]; then | |
| 134 | + nsuccess=$((nsuccess+1)) | |
| 135 | + printf "\n TEST: %-60s [ OK ]\n" "${msg}" | |
| 136 | + else | |
| 137 | + ret=1 | |
| 138 | + nfail=$((nfail+1)) | |
| 139 | + printf "\n TEST: %-60s [FAIL]\n" "${msg}" | |
| 140 | + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then | |
| 141 | + echo | |
| 142 | + echo "hit enter to continue, 'q' to quit" | |
| 143 | + read a | |
| 144 | + [ "$a" = "q" ] && exit 1 | |
| 145 | + fi | |
| 146 | + fi | |
| 147 | +} | |
| 148 | + | |
| 149 | +print_log_test_results() | |
| 150 | +{ | |
| 151 | + if [ "$TESTS" != "none" ]; then | |
| 152 | + printf "\nTests passed: %3d\n" ${nsuccess} | |
| 153 | + printf "Tests failed: %3d\n" ${nfail} | |
| 154 | + fi | |
| 155 | +} | |
| 156 | + | |
| 157 | +log_section() | |
| 158 | +{ | |
| 159 | + echo | |
| 160 | + echo "################################################################################" | |
| 161 | + echo "TEST SECTION: $*" | |
| 162 | + echo "################################################################################" | |
| 163 | +} | |
| 164 | + | |
| 165 | +cleanup() | |
| 166 | +{ | |
| 167 | + ip link del veth-rt-1 2>/dev/null || true | |
| 168 | + ip link del veth-rt-2 2>/dev/null || true | |
| 169 | + | |
| 170 | + # destroy routers rt-* and hosts hs-* | |
| 171 | + for ns in $(ip netns show | grep -E 'rt-*|hs-*'); do | |
| 172 | + ip netns del ${ns} || true | |
| 173 | + done | |
| 174 | +} | |
| 175 | + | |
| 176 | +# Setup the basic networking for the routers | |
| 177 | +setup_rt_networking() | |
| 178 | +{ | |
| 179 | + local rt=$1 | |
| 180 | + local nsname=rt-${rt} | |
| 181 | + | |
| 182 | + ip netns add ${nsname} | |
| 183 | + | |
| 184 | + ip netns exec ${nsname} sysctl -wq net.ipv6.conf.all.accept_dad=0 | |
| 185 | + ip netns exec ${nsname} sysctl -wq net.ipv6.conf.default.accept_dad=0 | |
| 186 | + | |
| 187 | + ip link set veth-rt-${rt} netns ${nsname} | |
| 188 | + ip -netns ${nsname} link set veth-rt-${rt} name veth0 | |
| 189 | + | |
| 190 | + ip -netns ${nsname} addr add ${IPv6_RT_NETWORK}::${rt}/64 dev veth0 nodad | |
| 191 | + ip -netns ${nsname} link set veth0 up | |
| 192 | + ip -netns ${nsname} link set lo up | |
| 193 | + | |
| 194 | + ip netns exec ${nsname} sysctl -wq net.ipv6.conf.all.forwarding=1 | |
| 195 | +} | |
| 196 | + | |
| 197 | +setup_rt_netfilter() | |
| 198 | +{ | |
| 199 | + local rt=$1 | |
| 200 | + local nsname=rt-${rt} | |
| 201 | + | |
| 202 | + ip netns exec ${nsname} sysctl -wq net.netfilter.nf_hooks_lwtunnel=1 | |
| 203 | + ip netns exec ${nsname} ip6tables -t raw -A PREROUTING -m rpfilter --invert -j DROP | |
| 204 | +} | |
| 205 | + | |
| 206 | +setup_hs() | |
| 207 | +{ | |
| 208 | + local hs=$1 | |
| 209 | + local rt=$2 | |
| 210 | + local tid=$3 | |
| 211 | + local hsname=hs-${hs} | |
| 212 | + local rtname=rt-${rt} | |
| 213 | + local rtveth=veth-t${tid} | |
| 214 | + | |
| 215 | + # set the networking for the host | |
| 216 | + ip netns add ${hsname} | |
| 217 | + | |
| 218 | + ip -netns ${hsname} link add veth0 type veth peer name ${rtveth} | |
| 219 | + ip -netns ${hsname} link set ${rtveth} netns ${rtname} | |
| 220 | + ip -netns ${hsname} addr add ${IPv6_HS_NETWORK}::${hs}/64 dev veth0 nodad | |
| 221 | + ip -netns ${hsname} link set veth0 up | |
| 222 | + ip -netns ${hsname} link set lo up | |
| 223 | + | |
| 224 | + ip -netns ${rtname} addr add ${IPv6_HS_NETWORK}::${rt}${hs}/64 dev ${rtveth} | |
| 225 | + ip -netns ${rtname} link set ${rtveth} up | |
| 226 | + | |
| 227 | + ip netns exec ${rtname} sysctl -wq net.ipv6.conf.all.accept_dad=0 | |
| 228 | + ip netns exec ${rtname} sysctl -wq net.ipv6.conf.default.accept_dad=0 | |
| 229 | + | |
| 230 | + ip netns exec ${rtname} sysctl -wq net.ipv6.conf.${rtveth}.proxy_ndp=1 | |
| 231 | +} | |
| 232 | + | |
| 233 | +setup_vpn_config() | |
| 234 | +{ | |
| 235 | + local hssrc=$1 | |
| 236 | + local rtsrc=$2 | |
| 237 | + local hsdst=$3 | |
| 238 | + local rtdst=$4 | |
| 239 | + local tid=$5 | |
| 240 | + | |
| 241 | + local hssrc_name=hs-t${tid}-${hssrc} | |
| 242 | + local hsdst_name=hs-t${tid}-${hsdst} | |
| 243 | + local rtsrc_name=rt-${rtsrc} | |
| 244 | + local rtdst_name=rt-${rtdst} | |
| 245 | + local rtveth=veth-t${tid} | |
| 246 | + local vpn_sid=${SID_LOCATOR}:${hssrc}${hsdst}:${tid}::6004 | |
| 247 | + | |
| 248 | + ip -netns ${rtsrc_name} -6 neigh add proxy ${IPv6_HS_NETWORK}::${hsdst} dev ${rtveth} | |
| 249 | + | |
| 250 | + # set the encap route for encapsulating packets which arrive from the | |
| 251 | + # host hssrc and destined to the access router rtsrc. | |
| 252 | + ip -netns ${rtsrc_name} -6 route add ${IPv6_HS_NETWORK}::${hsdst}/128 \ | |
| 253 | + encap seg6 mode encap segs ${vpn_sid} dev veth0 | |
| 254 | + ip -netns ${rtsrc_name} -6 route add ${vpn_sid}/128 \ | |
| 255 | + via 2001:11::${rtdst} dev veth0 | |
| 256 | + | |
| 257 | + # set the decap route for decapsulating packets which arrive from | |
| 258 | + # the rtdst router and destined to the hsdst host. | |
| 259 | + ip -netns ${rtdst_name} -6 route add ${vpn_sid}/128 \ | |
| 260 | + encap seg6local action End.DX6 nh6 ${IPv6_HS_NETWORK}::${hsdst} dev veth-t${tid} | |
| 261 | +} | |
| 262 | + | |
| 263 | +setup() | |
| 264 | +{ | |
| 265 | + ip link add veth-rt-1 type veth peer name veth-rt-2 | |
| 266 | + # setup the networking for router rt-1 and router rt-2 | |
| 267 | + setup_rt_networking 1 | |
| 268 | + setup_rt_networking 2 | |
| 269 | + | |
| 270 | + # setup two hosts for the tenant 100. | |
| 271 | + # - host hs-1 is directly connected to the router rt-1; | |
| 272 | + # - host hs-2 is directly connected to the router rt-2. | |
| 273 | + setup_hs 1 1 100 | |
| 274 | + setup_hs 2 2 100 | |
| 275 | + | |
| 276 | + # setup the IPv4 L3 VPN which connects the host hs-1 and host hs-2. | |
| 277 | + setup_vpn_config 1 1 2 2 100 #args: src_host src_router dst_host dst_router tenant | |
| 278 | + setup_vpn_config 2 2 1 1 100 | |
| 279 | +} | |
| 280 | + | |
| 281 | +check_hs_connectivity() | |
| 282 | +{ | |
| 283 | + local hssrc=$1 | |
| 284 | + local hsdst=$2 | |
| 285 | + local tid=$3 | |
| 286 | + | |
| 287 | + ip netns exec hs-${hssrc} ping -6 -c 1 -W ${PING_TIMEOUT_SEC} \ | |
| 288 | + ${IPv6_HS_NETWORK}::${hsdst} >/dev/null 2>&1 | |
| 289 | +} | |
| 290 | + | |
| 291 | +check_and_log_hs_connectivity() | |
| 292 | +{ | |
| 293 | + local hssrc=$1 | |
| 294 | + local hsdst=$2 | |
| 295 | + local tid=$3 | |
| 296 | + | |
| 297 | + check_hs_connectivity ${hssrc} ${hsdst} ${tid} | |
| 298 | + log_test $? 0 "Hosts connectivity: hs-${hssrc} -> hs-${hsdst} (tenant ${tid})" | |
| 299 | +} | |
| 300 | + | |
| 301 | +host_tests() | |
| 302 | +{ | |
| 303 | + log_section "SRv6 VPN connectivity test among hosts in the same tenant" | |
| 304 | + | |
| 305 | + check_and_log_hs_connectivity 1 2 100 | |
| 306 | + check_and_log_hs_connectivity 2 1 100 | |
| 307 | +} | |
| 308 | + | |
| 309 | +router_netfilter_tests() | |
| 310 | +{ | |
| 311 | + log_section "SRv6 VPN connectivity test with netfilter enabled in routers" | |
| 312 | + setup_rt_netfilter 1 | |
| 313 | + setup_rt_netfilter 2 | |
| 314 | + | |
| 315 | + check_and_log_hs_connectivity 1 2 100 | |
| 316 | + check_and_log_hs_connectivity 2 1 100 | |
| 317 | +} | |
| 318 | + | |
| 319 | +if [ "$(id -u)" -ne 0 ];then | |
| 320 | + echo "SKIP: Need root privileges" | |
| 321 | + exit $ksft_skip | |
| 322 | +fi | |
| 323 | + | |
| 324 | +if [ ! -x "$(command -v ip)" ]; then | |
| 325 | + echo "SKIP: Could not run test without ip tool" | |
| 326 | + exit $ksft_skip | |
| 327 | +fi | |
| 328 | + | |
| 329 | +cleanup &>/dev/null | |
| 330 | + | |
| 331 | +setup | |
| 332 | + | |
| 333 | +host_tests | |
| 334 | +router_netfilter_tests | |
| 335 | + | |
| 336 | +print_log_test_results | |
| 337 | + | |
| 338 | +cleanup &>/dev/null | |
| 339 | + | |
| 340 | +exit ${ret} | |
| @@ -1,8 +1,18 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | 2 | |
| 3 | −CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined -static-libasan | |
| 3 | +CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined | |
| 4 | 4 | TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test |
| 5 | 5 | |
| 6 | +# gcc requires -static-libasan in order to ensure that Address Sanitizer's | |
| 7 | +# library is the first one loaded. However, clang already statically links the | |
| 8 | +# Address Sanitizer if -fsanitize is specified. Therefore, simply omit | |
| 9 | +# -static-libasan for clang builds. | |
| 10 | +ifeq ($(LLVM),) | |
| 11 | + CFLAGS += -static-libasan | |
| 12 | +endif | |
| 13 | + | |
| 14 | +LOCAL_HDRS += helpers.h | |
| 15 | + | |
| 6 | 16 | include ../lib.mk |
| 7 | 17 | |
| 8 | −$(TEST_GEN_PROGS): helpers.c helpers.h | |
| 18 | +$(TEST_GEN_PROGS): helpers.c | |
| @@ -194,14 +194,14 @@ int main(int argc, char *argv[]) · 193 unmodified lines | ||
| 194 | 194 | ksft_set_plan(7); |
| 195 | 195 | |
| 196 | 196 | ksft_print_msg("Running on:\n"); |
| 197 | − ksft_print_msg(""); | |
| 197 | + ksft_print_msg("%s", ""); | |
| 198 | 198 | system("uname -a"); |
| 199 | 199 | |
| 200 | 200 | ksft_print_msg("Current BPF sysctl settings:\n"); |
| 201 | 201 | /* Avoid using "sysctl" which may not be installed. */ |
| 202 | − ksft_print_msg(""); | |
| 202 | + ksft_print_msg("%s", ""); | |
| 203 | 203 | system("grep -H . /proc/sys/net/core/bpf_jit_enable"); |
| 204 | − ksft_print_msg(""); | |
| 204 | + ksft_print_msg("%s", ""); | |
| 205 | 205 | system("grep -H . /proc/sys/net/core/bpf_jit_harden"); |
| 206 | 206 | |
| 207 | 207 | affinity(); |
| @@ -55,6 +55,9 @@ static void kvm_reset_dirty_gfn(struct kvm *kvm, u32 slot, u64 offset, u64 mask) · 54 unmodified lines | ||
| 55 | 55 | struct kvm_memory_slot *memslot; |
| 56 | 56 | int as_id, id; |
| 57 | 57 | |
| 58 | + if (!mask) | |
| 59 | + return; | |
| 60 | + | |
| 58 | 61 | as_id = slot >> 16; |
| 59 | 62 | id = (u16)slot; |
| 60 | 63 | |
| @@ -510,8 +510,10 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, · 509 unmodified lines | ||
| 510 | 510 | } |
| 511 | 511 | |
| 512 | 512 | if (folio_test_hwpoison(folio)) { |
| 513 | + folio_unlock(folio); | |
| 514 | + folio_put(folio); | |
| 513 | 515 | r = -EHWPOISON; |
| 514 | − goto out_unlock; | |
| 516 | + goto out_fput; | |
| 515 | 517 | } |
| 516 | 518 | |
| 517 | 519 | page = folio_file_page(folio, index); |
| @@ -522,7 +524,6 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, · 4 unmodified lines | ||
| 522 | 524 | |
| 523 | 525 | r = 0; |
| 524 | 526 | |
| 525 | −out_unlock: | |
| 526 | 527 | folio_unlock(folio); |
| 527 | 528 | out_fput: |
| 528 | 529 | fput(file); |
| @@ -651,7 +651,7 @@ static __always_inline kvm_mn_ret_t __kvm_handle_hva_range(struct kvm *kvm, · 650 unmodified lines | ||
| 651 | 651 | range->on_lock(kvm); |
| 652 | 652 | |
| 653 | 653 | if (IS_KVM_NULL_FN(range->handler)) |
| 654 | − break; | |
| 654 | + goto mmu_unlock; | |
| 655 | 655 | } |
| 656 | 656 | r.ret |= range->handler(kvm, &gfn_range); |
| 657 | 657 | } |
| @@ -660,6 +660,7 @@ static __always_inline kvm_mn_ret_t __kvm_handle_hva_range(struct kvm *kvm, · 2 unmodified lines | ||
| 660 | 660 | if (range->flush_on_ret && r.ret) |
| 661 | 661 | kvm_flush_remote_tlbs(kvm); |
| 662 | 662 | |
| 663 | +mmu_unlock: | |
| 663 | 664 | if (r.found_memslot) |
| 664 | 665 | KVM_MMU_UNLOCK(kvm); |
| 665 | 666 | |
| @@ -4025,12 +4026,13 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode) · 3359 unmodified lines | ||
| 4025 | 4026 | { |
| 4026 | 4027 | struct kvm *kvm = me->kvm; |
| 4027 | 4028 | struct kvm_vcpu *vcpu; |
| 4028 | − int last_boosted_vcpu = me->kvm->last_boosted_vcpu; | |
| 4029 | + int last_boosted_vcpu; | |
| 4029 | 4030 | unsigned long i; |
| 4030 | 4031 | int yielded = 0; |
| 4031 | 4032 | int try = 3; |
| 4032 | 4033 | int pass; |
| 4033 | 4034 | |
| 4035 | + last_boosted_vcpu = READ_ONCE(kvm->last_boosted_vcpu); | |
| 4034 | 4036 | kvm_vcpu_set_in_spin_loop(me, true); |
| 4035 | 4037 | /* |
| 4036 | 4038 | * We boost the priority of a VCPU that is runnable but not |
| @@ -4068,7 +4070,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode) · 31 unmodified lines | ||
| 4068 | 4070 | |
| 4069 | 4071 | yielded = kvm_vcpu_yield_to(vcpu); |
| 4070 | 4072 | if (yielded > 0) { |
| 4071 | − kvm->last_boosted_vcpu = i; | |
| 4073 | + WRITE_ONCE(kvm->last_boosted_vcpu, i); | |
| 4072 | 4074 | break; |
| 4073 | 4075 | } else if (yielded < 0) { |
| 4074 | 4076 | try--; |
| @@ -4427,7 +4429,7 @@ static long kvm_vcpu_ioctl(struct file *filp, · 352 unmodified lines | ||
| 4427 | 4429 | struct kvm_regs *kvm_regs; |
| 4428 | 4430 | |
| 4429 | 4431 | r = -ENOMEM; |
| 4430 | − kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL_ACCOUNT); | |
| 4432 | + kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL); | |
| 4431 | 4433 | if (!kvm_regs) |
| 4432 | 4434 | goto out; |
| 4433 | 4435 | r = kvm_arch_vcpu_ioctl_get_regs(vcpu, kvm_regs); |
| @@ -4454,8 +4456,7 @@ out_free1: · 20 unmodified lines | ||
| 4454 | 4456 | break; |
| 4455 | 4457 | } |
| 4456 | 4458 | case KVM_GET_SREGS: { |
| 4457 | − kvm_sregs = kzalloc(sizeof(struct kvm_sregs), | |
| 4458 | − GFP_KERNEL_ACCOUNT); | |
| 4459 | + kvm_sregs = kzalloc(sizeof(struct kvm_sregs), GFP_KERNEL); | |
| 4459 | 4460 | r = -ENOMEM; |
| 4460 | 4461 | if (!kvm_sregs) |
| 4461 | 4462 | goto out; |
| @@ -4547,7 +4548,7 @@ out_free1: · 85 unmodified lines | ||
| 4547 | 4548 | break; |
| 4548 | 4549 | } |
| 4549 | 4550 | case KVM_GET_FPU: { |
| 4550 | − fpu = kzalloc(sizeof(struct kvm_fpu), GFP_KERNEL_ACCOUNT); | |
| 4551 | + fpu = kzalloc(sizeof(struct kvm_fpu), GFP_KERNEL); | |
| 4551 | 4552 | r = -ENOMEM; |
| 4552 | 4553 | if (!fpu) |
| 4553 | 4554 | goto out; |
| @@ -6210,7 +6211,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm) · 1656 unmodified lines | ||
| 6210 | 6211 | active = kvm_active_vms; |
| 6211 | 6212 | mutex_unlock(&kvm_lock); |
| 6212 | 6213 | |
| 6213 | − env = kzalloc(sizeof(*env), GFP_KERNEL_ACCOUNT); | |
| 6214 | + env = kzalloc(sizeof(*env), GFP_KERNEL); | |
| 6214 | 6215 | if (!env) |
| 6215 | 6216 | return; |
| 6216 | 6217 | |
| @@ -6226,7 +6227,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm) · 9 unmodified lines | ||
| 6226 | 6227 | add_uevent_var(env, "PID=%d", kvm->userspace_pid); |
| 6227 | 6228 | |
| 6228 | 6229 | if (!IS_ERR(kvm->debugfs_dentry)) { |
| 6229 | − char *tmp, *p = kmalloc(PATH_MAX, GFP_KERNEL_ACCOUNT); | |
| 6230 | + char *tmp, *p = kmalloc(PATH_MAX, GFP_KERNEL); | |
| 6230 | 6231 | |
| 6231 | 6232 | if (p) { |
| 6232 | 6233 | tmp = dentry_path_raw(kvm->debugfs_dentry, p, PATH_MAX); |