Required due to dependencies in following patches.
Unified · Split
| @@ -71,6 +71,9 @@ Chao Yu <chao@kernel.org> <chao2.yu@samsung.com> · 70 unmodified lines | ||
| 71 | 71 | Chao Yu <chao@kernel.org> <yuchao0@huawei.com> |
| 72 | 72 | Chris Chiu <chris.chiu@canonical.com> <chiu@endlessm.com> |
| 73 | 73 | Chris Chiu <chris.chiu@canonical.com> <chiu@endlessos.org> |
| 74 | +Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com> | |
| 75 | +Christian Borntraeger <borntraeger@linux.ibm.com> <cborntra@de.ibm.com> | |
| 76 | +Christian Borntraeger <borntraeger@linux.ibm.com> <borntrae@de.ibm.com> | |
| 74 | 77 | Christophe Ricard <christophe.ricard@gmail.com> |
| 75 | 78 | Christoph Hellwig <hch@lst.de> |
| 76 | 79 | Colin Ian King <colin.king@intel.com> <colin.king@canonical.com> |
| @@ -123,6 +126,8 @@ Greg Kroah-Hartman <gregkh@suse.de> · 46 unmodified lines | ||
| 123 | 126 | Greg Kroah-Hartman <greg@kroah.com> |
| 124 | 127 | Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com> |
| 125 | 128 | Gregory CLEMENT <gregory.clement@bootlin.com> <gregory.clement@free-electrons.com> |
| 129 | +Guo Ren <guoren@kernel.org> <guoren@linux.alibaba.com> | |
| 130 | +Guo Ren <guoren@kernel.org> <ren_guo@c-sky.com> | |
| 126 | 131 | Gustavo Padovan <gustavo@las.ic.unicamp.br> |
| 127 | 132 | Gustavo Padovan <padovan@profusion.mobi> |
| 128 | 133 | Hanjun Guo <guohanjun@huawei.com> <hanjun.guo@linaro.org> |
| @@ -25,6 +25,6 @@ Sub graphs of DRBD's state transitions · 24 unmodified lines | ||
| 25 | 25 | :alt: disk-states-8.dot |
| 26 | 26 | :align: center |
| 27 | 27 | |
| 28 | −.. kernel-figure:: node-states-8.dot | |
| 29 | − :alt: node-states-8.dot | |
| 28 | +.. kernel-figure:: peer-states-8.dot | |
| 29 | + :alt: peer-states-8.dot | |
| 30 | 30 | :align: center |
| @@ -1,8 +1,3 @@ | ||
| 1 | −digraph node_states { | |
| 2 | − Secondary -> Primary [ label = "ioctl_set_state()" ] | |
| 3 | − Primary -> Secondary [ label = "ioctl_set_state()" ] | |
| 4 | −} | |
| 5 | − | |
| 6 | 1 | digraph peer_states { |
| 7 | 2 | Secondary -> Primary [ label = "recv state packet" ] |
| 8 | 3 | Primary -> Secondary [ label = "recv state packet" ] |
| @@ -1520,15 +1520,15 @@ This sysfs attribute controls the keyboard "face" that will be shown on the · 1519 unmodified lines | ||
| 1520 | 1520 | Lenovo X1 Carbon 2nd gen (2014)'s adaptive keyboard. The value can be read |
| 1521 | 1521 | and set. |
| 1522 | 1522 | |
| 1523 | −- 1 = Home mode | |
| 1524 | −- 2 = Web-browser mode | |
| 1525 | −- 3 = Web-conference mode | |
| 1526 | −- 4 = Function mode | |
| 1527 | −- 5 = Layflat mode | |
| 1523 | +- 0 = Home mode | |
| 1524 | +- 1 = Web-browser mode | |
| 1525 | +- 2 = Web-conference mode | |
| 1526 | +- 3 = Function mode | |
| 1527 | +- 4 = Layflat mode | |
| 1528 | 1528 | |
| 1529 | 1529 | For more details about which buttons will appear depending on the mode, please |
| 1530 | 1530 | review the laptop's user guide: |
| 1531 | −http://www.lenovo.com/shop/americas/content/user_guides/x1carbon_2_ug_en.pdf | |
| 1531 | +https://download.lenovo.com/ibmdl/pub/pc/pccbbs/mobiles_pdf/x1carbon_2_ug_en.pdf | |
| 1532 | 1532 | |
| 1533 | 1533 | Battery charge control |
| 1534 | 1534 | ---------------------- |
| @@ -1099,7 +1099,7 @@ task_delayacct · 1098 unmodified lines | ||
| 1099 | 1099 | =============== |
| 1100 | 1100 | |
| 1101 | 1101 | Enables/disables task delay accounting (see |
| 1102 | −:doc:`accounting/delay-accounting.rst`). Enabling this feature incurs | |
| 1102 | +Documentation/accounting/delay-accounting.rst. Enabling this feature incurs | |
| 1103 | 1103 | a small amount of overhead in the scheduler but is useful for debugging |
| 1104 | 1104 | and performance tuning. It is required by some tools such as iotop. |
| 1105 | 1105 | |
| @@ -104,6 +104,8 @@ Discovery family · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | Not supported by the Linux kernel. |
| 106 | 106 | |
| 107 | + Homepage: | |
| 108 | + https://web.archive.org/web/20110924171043/http://www.marvell.com/embedded-processors/discovery-innovation/ | |
| 107 | 109 | Core: |
| 108 | 110 | Feroceon 88fr571-vd ARMv5 compatible |
| 109 | 111 | |
| @@ -120,6 +122,7 @@ EBU Armada family · 10 unmodified lines | ||
| 120 | 122 | - 88F6707 |
| 121 | 123 | - 88F6W11 |
| 122 | 124 | |
| 125 | + - Product infos: https://web.archive.org/web/20141002083258/http://www.marvell.com/embedded-processors/armada-370/ | |
| 123 | 126 | - Product Brief: https://web.archive.org/web/20121115063038/http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf |
| 124 | 127 | - Hardware Spec: https://web.archive.org/web/20140617183747/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-datasheet.pdf |
| 125 | 128 | - Functional Spec: https://web.archive.org/web/20140617183701/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf |
| @@ -127,9 +130,29 @@ EBU Armada family · 1 unmodified line | ||
| 127 | 130 | Core: |
| 128 | 131 | Sheeva ARMv7 compatible PJ4B |
| 129 | 132 | |
| 133 | + Armada XP Flavors: | |
| 134 | + - MV78230 | |
| 135 | + - MV78260 | |
| 136 | + - MV78460 | |
| 137 | + | |
| 138 | + NOTE: | |
| 139 | + not to be confused with the non-SMP 78xx0 SoCs | |
| 140 | + | |
| 141 | + - Product infos: https://web.archive.org/web/20150101215721/http://www.marvell.com/embedded-processors/armada-xp/ | |
| 142 | + - Product Brief: https://web.archive.org/web/20121021173528/http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf | |
| 143 | + - Functional Spec: https://web.archive.org/web/20180829171131/http://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf | |
| 144 | + - Hardware Specs: | |
| 145 | + - https://web.archive.org/web/20141127013651/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF | |
| 146 | + - https://web.archive.org/web/20141222000224/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF | |
| 147 | + - https://web.archive.org/web/20141222000230/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF | |
| 148 | + | |
| 149 | + Core: | |
| 150 | + Sheeva ARMv7 compatible Dual-core or Quad-core PJ4B-MP | |
| 151 | + | |
| 130 | 152 | Armada 375 Flavors: |
| 131 | 153 | - 88F6720 |
| 132 | 154 | |
| 155 | + - Product infos: https://web.archive.org/web/20140108032402/http://www.marvell.com/embedded-processors/armada-375/ | |
| 133 | 156 | - Product Brief: https://web.archive.org/web/20131216023516/http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf |
| 134 | 157 | |
| 135 | 158 | Core: |
| @@ -162,29 +185,6 @@ EBU Armada family · 26 unmodified lines | ||
| 162 | 185 | Core: |
| 163 | 186 | ARM Cortex-A9 |
| 164 | 187 | |
| 165 | − Armada XP Flavors: | |
| 166 | − - MV78230 | |
| 167 | − - MV78260 | |
| 168 | − - MV78460 | |
| 169 | − | |
| 170 | − NOTE: | |
| 171 | − not to be confused with the non-SMP 78xx0 SoCs | |
| 172 | − | |
| 173 | − Product Brief: | |
| 174 | − https://web.archive.org/web/20121021173528/http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf | |
| 175 | − | |
| 176 | − Functional Spec: | |
| 177 | − https://web.archive.org/web/20180829171131/http://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf | |
| 178 | − | |
| 179 | − - Hardware Specs: | |
| 180 | − | |
| 181 | − - https://web.archive.org/web/20141127013651/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF | |
| 182 | − - https://web.archive.org/web/20141222000224/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF | |
| 183 | − - https://web.archive.org/web/20141222000230/http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF | |
| 184 | − | |
| 185 | − Core: | |
| 186 | − Sheeva ARMv7 compatible Dual-core or Quad-core PJ4B-MP | |
| 187 | − | |
| 188 | 188 | Linux kernel mach directory: |
| 189 | 189 | arch/arm/mach-mvebu |
| 190 | 190 | Linux kernel plat directory: |
| @@ -436,7 +436,7 @@ Berlin family (Multimedia Solutions) · 245 unmodified lines | ||
| 436 | 436 | - Flavors: |
| 437 | 437 | - 88DE3010, Armada 1000 (no Linux support) |
| 438 | 438 | - Core: Marvell PJ1 (ARMv5TE), Dual-core |
| 439 | − - Product Brief: http://www.marvell.com.cn/digital-entertainment/assets/armada_1000_pb.pdf | |
| 439 | + - Product Brief: https://web.archive.org/web/20131103162620/http://www.marvell.com/digital-entertainment/assets/armada_1000_pb.pdf | |
| 440 | 440 | - 88DE3005, Armada 1500 Mini |
| 441 | 441 | - Design name: BG2CD |
| 442 | 442 | - Core: ARM Cortex-A9, PL310 L2CC |
| @@ -53,11 +53,10 @@ The number of bits that the PAC occupies in a pointer is 55 minus the · 52 unmodified lines | ||
| 53 | 53 | virtual address size configured by the kernel. For example, with a |
| 54 | 54 | virtual address size of 48, the PAC is 7 bits wide. |
| 55 | 55 | |
| 56 | −Recent versions of GCC can compile code with APIAKey-based return | |
| 57 | −address protection when passed the -msign-return-address option. This | |
| 58 | −uses instructions in the HINT space (unless -march=armv8.3-a or higher | |
| 59 | −is also passed), and such code can run on systems without the pointer | |
| 60 | −authentication extension. | |
| 56 | +When ARM64_PTR_AUTH_KERNEL is selected, the kernel will be compiled | |
| 57 | +with HINT space pointer authentication instructions protecting | |
| 58 | +function returns. Kernels built with this option will work on hardware | |
| 59 | +with or without pointer authentication support. | |
| 61 | 60 | |
| 62 | 61 | In addition to exec(), keys can also be reinitialized to random values |
| 63 | 62 | using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY, |
| @@ -15,7 +15,7 @@ that goes into great technical depth about the BPF Architecture. · 14 unmodified lines | ||
| 15 | 15 | libbpf |
| 16 | 16 | ====== |
| 17 | 17 | |
| 18 | −Documentation/bpf/libbpf/libbpf.rst is a userspace library for loading and interacting with bpf programs. | |
| 18 | +Documentation/bpf/libbpf/index.rst is a userspace library for loading and interacting with bpf programs. | |
| 19 | 19 | |
| 20 | 20 | BPF Type Format (BTF) |
| 21 | 21 | ===================== |
| @@ -249,11 +249,16 @@ except ImportError: · 248 unmodified lines | ||
| 249 | 249 | |
| 250 | 250 | html_static_path = ['sphinx-static'] |
| 251 | 251 | |
| 252 | −html_context = { | |
| 253 | − 'css_files': [ | |
| 254 | − '_static/theme_overrides.css', | |
| 255 | − ], | |
| 256 | −} | |
| 252 | +html_css_files = [ | |
| 253 | + 'theme_overrides.css', | |
| 254 | +] | |
| 255 | + | |
| 256 | +if major <= 1 and minor < 8: | |
| 257 | + html_context = { | |
| 258 | + 'css_files': [ | |
| 259 | + '_static/theme_overrides.css', | |
| 260 | + ], | |
| 261 | + } | |
| 257 | 262 | |
| 258 | 263 | # Add any extra paths that contain custom files (such as robots.txt or |
| 259 | 264 | # .htaccess) here, relative to this directory. These files are copied |
| @@ -73,12 +73,12 @@ CPUFREQ_POSTCHANGE. · 72 unmodified lines | ||
| 73 | 73 | The third argument is a struct cpufreq_freqs with the following |
| 74 | 74 | values: |
| 75 | 75 | |
| 76 | −===== =========================== | |
| 77 | −cpu number of the affected CPU | |
| 76 | +====== ====================================== | |
| 77 | +policy a pointer to the struct cpufreq_policy | |
| 78 | 78 | old old frequency |
| 79 | 79 | new new frequency |
| 80 | 80 | flags flags of the cpufreq driver |
| 81 | −===== =========================== | |
| 81 | +====== ====================================== | |
| 82 | 82 | |
| 83 | 83 | 3. CPUFreq Table Generation with Operating Performance Point (OPP) |
| 84 | 84 | ================================================================== |
| @@ -17,9 +17,10 @@ properties: · 16 unmodified lines | ||
| 17 | 17 | oneOf: |
| 18 | 18 | - enum: |
| 19 | 19 | - fsl,imx7ulp-lpi2c |
| 20 | − - fsl,imx8qm-lpi2c | |
| 21 | 20 | - items: |
| 22 | − - const: fsl,imx8qxp-lpi2c | |
| 21 | + - enum: | |
| 22 | + - fsl,imx8qxp-lpi2c | |
| 23 | + - fsl,imx8qm-lpi2c | |
| 23 | 24 | - const: fsl,imx7ulp-lpi2c |
| 24 | 25 | |
| 25 | 26 | reg: |
| @@ -136,7 +136,7 @@ examples: · 135 unmodified lines | ||
| 136 | 136 | samsung,syscon-phandle = <&pmu_system_controller>; |
| 137 | 137 | |
| 138 | 138 | /* NTC thermistor is a hwmon device */ |
| 139 | − ncp15wb473 { | |
| 139 | + thermistor { | |
| 140 | 140 | compatible = "murata,ncp15wb473"; |
| 141 | 141 | pullup-uv = <1800000>; |
| 142 | 142 | pullup-ohm = <47000>; |
| @@ -142,7 +142,7 @@ examples: · 141 unmodified lines | ||
| 142 | 142 | down { |
| 143 | 143 | label = "GPIO Key DOWN"; |
| 144 | 144 | linux,code = <108>; |
| 145 | − interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; | |
| 145 | + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; | |
| 146 | 146 | }; |
| 147 | 147 | }; |
| 148 | 148 | |
| @@ -79,6 +79,8 @@ properties: · 78 unmodified lines | ||
| 79 | 79 | |
| 80 | 80 | properties: |
| 81 | 81 | data-lanes: |
| 82 | + description: | |
| 83 | + Note that 'fsl,imx7-mipi-csi2' only supports up to 2 data lines. | |
| 82 | 84 | items: |
| 83 | 85 | minItems: 1 |
| 84 | 86 | maxItems: 4 |
| @@ -91,18 +93,6 @@ properties: · 6 unmodified lines | ||
| 91 | 93 | required: |
| 92 | 94 | - data-lanes |
| 93 | 95 | |
| 94 | − allOf: | |
| 95 | − - if: | |
| 96 | − properties: | |
| 97 | − compatible: | |
| 98 | − contains: | |
| 99 | − const: fsl,imx7-mipi-csi2 | |
| 100 | − then: | |
| 101 | − properties: | |
| 102 | − data-lanes: | |
| 103 | − items: | |
| 104 | − maxItems: 2 | |
| 105 | − | |
| 106 | 96 | port@1: |
| 107 | 97 | $ref: /schemas/graph.yaml#/properties/port |
| 108 | 98 | description: |
| @@ -91,6 +91,14 @@ properties: · 90 unmodified lines | ||
| 91 | 91 | compensate for the board being designed with the lanes |
| 92 | 92 | swapped. |
| 93 | 93 | |
| 94 | + enet-phy-lane-no-swap: | |
| 95 | + $ref: /schemas/types.yaml#/definitions/flag | |
| 96 | + description: | |
| 97 | + If set, indicates that PHY will disable swap of the | |
| 98 | + TX/RX lanes. This property allows the PHY to work correcly after | |
| 99 | + e.g. wrong bootstrap configuration caused by issues in PCB | |
| 100 | + layout design. | |
| 101 | + | |
| 94 | 102 | eee-broken-100tx: |
| 95 | 103 | $ref: /schemas/types.yaml#/definitions/flag |
| 96 | 104 | description: |
| @@ -29,7 +29,7 @@ properties: · 28 unmodified lines | ||
| 29 | 29 | - PHY_TYPE_PCIE |
| 30 | 30 | - PHY_TYPE_SATA |
| 31 | 31 | - PHY_TYPE_SGMII |
| 32 | − - PHY_TYPE_USB | |
| 32 | + - PHY_TYPE_USB3 | |
| 33 | 33 | - description: The PHY instance |
| 34 | 34 | minimum: 0 |
| 35 | 35 | maximum: 1 # for DP, SATA or USB |
| @@ -105,7 +105,7 @@ examples: · 104 unmodified lines | ||
| 105 | 105 | reg = <0x65>; |
| 106 | 106 | interrupt-parent = <&gpio1>; |
| 107 | 107 | interrupts = <16 IRQ_TYPE_EDGE_FALLING>; |
| 108 | − ti,watchdog-timer = <0>; | |
| 108 | + ti,watchdog-timeout-ms = <0>; | |
| 109 | 109 | ti,sc-ocp-limit-microamp = <2000000>; |
| 110 | 110 | ti,sc-ovp-limit-microvolt = <17800000>; |
| 111 | 111 | monitored-battery = <&bat>; |
| @@ -19,6 +19,9 @@ properties: · 18 unmodified lines | ||
| 19 | 19 | clocks: |
| 20 | 20 | maxItems: 1 |
| 21 | 21 | |
| 22 | + interrupts: | |
| 23 | + maxItems: 1 | |
| 24 | + | |
| 22 | 25 | "#sound-dai-cells": |
| 23 | 26 | const: 0 |
| 24 | 27 | |
| @@ -33,6 +33,7 @@ properties: · 32 unmodified lines | ||
| 33 | 33 | - rockchip,rk3328-spi |
| 34 | 34 | - rockchip,rk3368-spi |
| 35 | 35 | - rockchip,rk3399-spi |
| 36 | + - rockchip,rk3568-spi | |
| 36 | 37 | - rockchip,rv1126-spi |
| 37 | 38 | - const: rockchip,rk3066-spi |
| 38 | 39 | |
| @@ -27,7 +27,7 @@ Sphinx Install · 26 unmodified lines | ||
| 27 | 27 | ============== |
| 28 | 28 | |
| 29 | 29 | The ReST markups currently used by the Documentation/ files are meant to be |
| 30 | −built with ``Sphinx`` version 1.3 or higher. | |
| 30 | +built with ``Sphinx`` version 1.7 or higher. | |
| 31 | 31 | |
| 32 | 32 | There's a script that checks for the Sphinx requirements. Please see |
| 33 | 33 | :ref:`sphinx-pre-install` for further details. |
| @@ -43,10 +43,6 @@ or ``virtualenv``, depending on how your distribution packaged Python 3. · 9 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | .. note:: |
| 45 | 45 | |
| 46 | − #) Sphinx versions below 1.5 don't work properly with Python's | |
| 47 | − docutils version 0.13.1 or higher. So, if you're willing to use | |
| 48 | − those versions, you should run ``pip install 'docutils==0.12'``. | |
| 49 | − | |
| 50 | 46 | #) It is recommended to use the RTD theme for html output. Depending |
| 51 | 47 | on the Sphinx version, it should be installed separately, |
| 52 | 48 | with ``pip install sphinx_rtd_theme``. |
| @@ -55,13 +51,13 @@ or ``virtualenv``, depending on how your distribution packaged Python 3. · 2 unmodified lines | ||
| 55 | 51 | those expressions are written using LaTeX notation. It needs texlive |
| 56 | 52 | installed with amsfonts and amsmath in order to evaluate them. |
| 57 | 53 | |
| 58 | −In summary, if you want to install Sphinx version 1.7.9, you should do:: | |
| 54 | +In summary, if you want to install Sphinx version 2.4.4, you should do:: | |
| 59 | 55 | |
| 60 | − $ virtualenv sphinx_1.7.9 | |
| 61 | − $ . sphinx_1.7.9/bin/activate | |
| 62 | − (sphinx_1.7.9) $ pip install -r Documentation/sphinx/requirements.txt | |
| 56 | + $ virtualenv sphinx_2.4.4 | |
| 57 | + $ . sphinx_2.4.4/bin/activate | |
| 58 | + (sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt | |
| 63 | 59 | |
| 64 | −After running ``. sphinx_1.7.9/bin/activate``, the prompt will change, | |
| 60 | +After running ``. sphinx_2.4.4/bin/activate``, the prompt will change, | |
| 65 | 61 | in order to indicate that you're using the new environment. If you |
| 66 | 62 | open a new shell, you need to rerun this command to enter again at |
| 67 | 63 | the virtual environment before building the documentation. |
| @@ -81,7 +77,7 @@ output. · 13 unmodified lines | ||
| 81 | 77 | PDF and LaTeX builds |
| 82 | 78 | -------------------- |
| 83 | 79 | |
| 84 | −Such builds are currently supported only with Sphinx versions 1.4 and higher. | |
| 80 | +Such builds are currently supported only with Sphinx versions 2.4 and higher. | |
| 85 | 81 | |
| 86 | 82 | For PDF and LaTeX output, you'll also need ``XeLaTeX`` version 3.14159265. |
| 87 | 83 | |
| @@ -104,8 +100,8 @@ command line options for your distro:: · 16 unmodified lines | ||
| 104 | 100 | You should run: |
| 105 | 101 | |
| 106 | 102 | sudo dnf install -y texlive-luatex85 |
| 107 | − /usr/bin/virtualenv sphinx_1.7.9 | |
| 108 | − . sphinx_1.7.9/bin/activate | |
| 103 | + /usr/bin/virtualenv sphinx_2.4.4 | |
| 104 | + . sphinx_2.4.4/bin/activate | |
| 109 | 105 | pip install -r Documentation/sphinx/requirements.txt |
| 110 | 106 | |
| 111 | 107 | Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468. |
| @@ -35,7 +35,7 @@ This document describes only the kernel module and the interactions · 34 unmodified lines | ||
| 35 | 35 | required with any user-space program. Subsequent text refers to this |
| 36 | 36 | as the "automount daemon" or simply "the daemon". |
| 37 | 37 | |
| 38 | −"autofs" is a Linux kernel module with provides the "autofs" | |
| 38 | +"autofs" is a Linux kernel module which provides the "autofs" | |
| 39 | 39 | filesystem type. Several "autofs" filesystems can be mounted and they |
| 40 | 40 | can each be managed separately, or all managed by the same daemon. |
| 41 | 41 | |
| @@ -50,11 +50,11 @@ ksmbd.mountd (user space daemon) · 49 unmodified lines | ||
| 50 | 50 | -------------------------------- |
| 51 | 51 | |
| 52 | 52 | ksmbd.mountd is userspace process to, transfer user account and password that |
| 53 | −are registered using ksmbd.adduser(part of utils for user space). Further it | |
| 53 | +are registered using ksmbd.adduser (part of utils for user space). Further it | |
| 54 | 54 | allows sharing information parameters that parsed from smb.conf to ksmbd in |
| 55 | 55 | kernel. For the execution part it has a daemon which is continuously running |
| 56 | 56 | and connected to the kernel interface using netlink socket, it waits for the |
| 57 | −requests(dcerpc and share/user info). It handles RPC calls (at a minimum few | |
| 57 | +requests (dcerpc and share/user info). It handles RPC calls (at a minimum few | |
| 58 | 58 | dozen) that are most important for file server from NetShareEnum and |
| 59 | 59 | NetServerGetInfo. Complete DCE/RPC response is prepared from the user space |
| 60 | 60 | and passed over to the associated kernel thread for the client. |
| @@ -154,11 +154,11 @@ Each layer · 93 unmodified lines | ||
| 154 | 154 | 1. Enable all component prints |
| 155 | 155 | # sudo ksmbd.control -d "all" |
| 156 | 156 | |
| 157 | −2. Enable one of components(smb, auth, vfs, oplock, ipc, conn, rdma) | |
| 157 | +2. Enable one of components (smb, auth, vfs, oplock, ipc, conn, rdma) | |
| 158 | 158 | # sudo ksmbd.control -d "smb" |
| 159 | 159 | |
| 160 | −3. Show what prints are enable. | |
| 161 | − # cat/sys/class/ksmbd-control/debug | |
| 160 | +3. Show what prints are enabled. | |
| 161 | + # cat /sys/class/ksmbd-control/debug | |
| 162 | 162 | [smb] auth vfs oplock ipc conn [rdma] |
| 163 | 163 | |
| 164 | 164 | 4. Disable prints: |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | 3 | ================================= |
| 4 | −NETWORK FILESYSTEM HELPER LIBRARY | |
| 4 | +Network Filesystem Helper Library | |
| 5 | 5 | ================================= |
| 6 | 6 | |
| 7 | 7 | .. Contents: |
| @@ -37,22 +37,22 @@ into a common call framework. · 29 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | The following services are provided: |
| 39 | 39 | |
| 40 | − * Handles transparent huge pages (THPs). | |
| 40 | + * Handle folios that span multiple pages. | |
| 41 | 41 | |
| 42 | − * Insulates the netfs from VM interface changes. | |
| 42 | + * Insulate the netfs from VM interface changes. | |
| 43 | 43 | |
| 44 | − * Allows the netfs to arbitrarily split reads up into pieces, even ones that | |
| 45 | − don't match page sizes or page alignments and that may cross pages. | |
| 44 | + * Allow the netfs to arbitrarily split reads up into pieces, even ones that | |
| 45 | + don't match folio sizes or folio alignments and that may cross folios. | |
| 46 | 46 | |
| 47 | − * Allows the netfs to expand a readahead request in both directions to meet | |
| 48 | − its needs. | |
| 47 | + * Allow the netfs to expand a readahead request in both directions to meet its | |
| 48 | + needs. | |
| 49 | 49 | |
| 50 | − * Allows the netfs to partially fulfil a read, which will then be resubmitted. | |
| 50 | + * Allow the netfs to partially fulfil a read, which will then be resubmitted. | |
| 51 | 51 | |
| 52 | − * Handles local caching, allowing cached data and server-read data to be | |
| 52 | + * Handle local caching, allowing cached data and server-read data to be | |
| 53 | 53 | interleaved for a single request. |
| 54 | 54 | |
| 55 | − * Handles clearing of bufferage that aren't on the server. | |
| 55 | + * Handle clearing of bufferage that aren't on the server. | |
| 56 | 56 | |
| 57 | 57 | * Handle retrying of reads that failed, switching reads from the cache to the |
| 58 | 58 | server as necessary. |
| @@ -70,22 +70,22 @@ Read Helper Functions · 11 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | Three read helpers are provided:: |
| 72 | 72 | |
| 73 | − * void netfs_readahead(struct readahead_control *ractl, | |
| 74 | − const struct netfs_read_request_ops *ops, | |
| 75 | − void *netfs_priv);`` | |
| 76 | − * int netfs_readpage(struct file *file, | |
| 77 | − struct page *page, | |
| 78 | − const struct netfs_read_request_ops *ops, | |
| 79 | − void *netfs_priv); | |
| 80 | − * int netfs_write_begin(struct file *file, | |
| 81 | − struct address_space *mapping, | |
| 82 | − loff_t pos, | |
| 83 | − unsigned int len, | |
| 84 | − unsigned int flags, | |
| 85 | − struct page **_page, | |
| 86 | − void **_fsdata, | |
| 87 | − const struct netfs_read_request_ops *ops, | |
| 88 | − void *netfs_priv); | |
| 73 | + void netfs_readahead(struct readahead_control *ractl, | |
| 74 | + const struct netfs_read_request_ops *ops, | |
| 75 | + void *netfs_priv); | |
| 76 | + int netfs_readpage(struct file *file, | |
| 77 | + struct folio *folio, | |
| 78 | + const struct netfs_read_request_ops *ops, | |
| 79 | + void *netfs_priv); | |
| 80 | + int netfs_write_begin(struct file *file, | |
| 81 | + struct address_space *mapping, | |
| 82 | + loff_t pos, | |
| 83 | + unsigned int len, | |
| 84 | + unsigned int flags, | |
| 85 | + struct folio **_folio, | |
| 86 | + void **_fsdata, | |
| 87 | + const struct netfs_read_request_ops *ops, | |
| 88 | + void *netfs_priv); | |
| 89 | 89 | |
| 90 | 90 | Each corresponds to a VM operation, with the addition of a couple of parameters |
| 91 | 91 | for the use of the read helpers: |
| @@ -103,8 +103,8 @@ Both of these values will be stored into the read request structure. · 11 unmodified lines | ||
| 103 | 103 | For ->readahead() and ->readpage(), the network filesystem should just jump |
| 104 | 104 | into the corresponding read helper; whereas for ->write_begin(), it may be a |
| 105 | 105 | little more complicated as the network filesystem might want to flush |
| 106 | −conflicting writes or track dirty data and needs to put the acquired page if an | |
| 107 | −error occurs after calling the helper. | |
| 106 | +conflicting writes or track dirty data and needs to put the acquired folio if | |
| 107 | +an error occurs after calling the helper. | |
| 108 | 108 | |
| 109 | 109 | The helpers manage the read request, calling back into the network filesystem |
| 110 | 110 | through the suppplied table of operations. Waits will be performed as |
| @@ -253,7 +253,7 @@ through which it can issue requests and negotiate:: · 142 unmodified lines | ||
| 253 | 253 | void (*issue_op)(struct netfs_read_subrequest *subreq); |
| 254 | 254 | bool (*is_still_valid)(struct netfs_read_request *rreq); |
| 255 | 255 | int (*check_write_begin)(struct file *file, loff_t pos, unsigned len, |
| 256 | − struct page *page, void **_fsdata); | |
| 256 | + struct folio *folio, void **_fsdata); | |
| 257 | 257 | void (*done)(struct netfs_read_request *rreq); |
| 258 | 258 | void (*cleanup)(struct address_space *mapping, void *netfs_priv); |
| 259 | 259 | }; |
| @@ -313,13 +313,14 @@ The operations are as follows: · 53 unmodified lines | ||
| 313 | 313 | |
| 314 | 314 | There is no return value; the netfs_subreq_terminated() function should be |
| 315 | 315 | called to indicate whether or not the operation succeeded and how much data |
| 316 | − it transferred. The filesystem also should not deal with setting pages | |
| 316 | + it transferred. The filesystem also should not deal with setting folios | |
| 317 | 317 | uptodate, unlocking them or dropping their refs - the helpers need to deal |
| 318 | 318 | with this as they have to coordinate with copying to the local cache. |
| 319 | 319 | |
| 320 | − Note that the helpers have the pages locked, but not pinned. It is possible | |
| 321 | − to use the ITER_XARRAY iov iterator to refer to the range of the inode that | |
| 322 | − is being operated upon without the need to allocate large bvec tables. | |
| 320 | + Note that the helpers have the folios locked, but not pinned. It is | |
| 321 | + possible to use the ITER_XARRAY iov iterator to refer to the range of the | |
| 322 | + inode that is being operated upon without the need to allocate large bvec | |
| 323 | + tables. | |
| 323 | 324 | |
| 324 | 325 | * ``is_still_valid()`` |
| 325 | 326 | |
| @@ -330,15 +331,15 @@ The operations are as follows: · 4 unmodified lines | ||
| 330 | 331 | * ``check_write_begin()`` |
| 331 | 332 | |
| 332 | 333 | [Optional] This is called from the netfs_write_begin() helper once it has |
| 333 | − allocated/grabbed the page to be modified to allow the filesystem to flush | |
| 334 | + allocated/grabbed the folio to be modified to allow the filesystem to flush | |
| 334 | 335 | conflicting state before allowing it to be modified. |
| 335 | 336 | |
| 336 | − It should return 0 if everything is now fine, -EAGAIN if the page should be | |
| 337 | + It should return 0 if everything is now fine, -EAGAIN if the folio should be | |
| 337 | 338 | regrabbed and any other error code to abort the operation. |
| 338 | 339 | |
| 339 | 340 | * ``done`` |
| 340 | 341 | |
| 341 | − [Optional] This is called after the pages in the request have all been | |
| 342 | + [Optional] This is called after the folios in the request have all been | |
| 342 | 343 | unlocked (and marked uptodate if applicable). |
| 343 | 344 | |
| 344 | 345 | * ``cleanup`` |
| @@ -390,7 +391,7 @@ The read helpers work by the following general procedure: · 45 unmodified lines | ||
| 390 | 391 | * If NETFS_SREQ_CLEAR_TAIL was set, a short read will be cleared to the |
| 391 | 392 | end of the slice instead of reissuing. |
| 392 | 393 | |
| 393 | − * Once the data is read, the pages that have been fully read/cleared: | |
| 394 | + * Once the data is read, the folios that have been fully read/cleared: | |
| 394 | 395 | |
| 395 | 396 | * Will be marked uptodate. |
| 396 | 397 | |
| @@ -398,11 +399,11 @@ The read helpers work by the following general procedure: · 1 unmodified line | ||
| 398 | 399 | |
| 399 | 400 | * Unlocked |
| 400 | 401 | |
| 401 | − * Any pages that need writing to the cache will then have DIO writes issued. | |
| 402 | + * Any folios that need writing to the cache will then have DIO writes issued. | |
| 402 | 403 | |
| 403 | 404 | * Synchronous operations will wait for reading to be complete. |
| 404 | 405 | |
| 405 | − * Writes to the cache will proceed asynchronously and the pages will have the | |
| 406 | + * Writes to the cache will proceed asynchronously and the folios will have the | |
| 406 | 407 | PG_fscache mark removed when that completes. |
| 407 | 408 | |
| 408 | 409 | * The request structures will be cleaned up when everything has completed. |
| @@ -452,6 +453,9 @@ operation table looks like the following:: · 43 unmodified lines | ||
| 452 | 453 | netfs_io_terminated_t term_func, |
| 453 | 454 | void *term_func_priv); |
| 454 | 455 | |
| 456 | + int (*prepare_write)(struct netfs_cache_resources *cres, | |
| 457 | + loff_t *_start, size_t *_len, loff_t i_size); | |
| 458 | + | |
| 455 | 459 | int (*write)(struct netfs_cache_resources *cres, |
| 456 | 460 | loff_t start_pos, |
| 457 | 461 | struct iov_iter *iter, |
| @@ -509,6 +513,14 @@ The methods defined in the table are: · 51 unmodified lines | ||
| 509 | 513 | indicating whether the termination is definitely happening in the caller's |
| 510 | 514 | context. |
| 511 | 515 | |
| 516 | + * ``prepare_write()`` | |
| 517 | + | |
| 518 | + [Required] Called to adjust a write to the cache and check that there is | |
| 519 | + sufficient space in the cache. The start and length values indicate the | |
| 520 | + size of the write that netfslib is proposing, and this can be adjusted by | |
| 521 | + the cache to respect DIO boundaries. The file size is passed for | |
| 522 | + information. | |
| 523 | + | |
| 512 | 524 | * ``write()`` |
| 513 | 525 | |
| 514 | 526 | [Required] Called to write to the cache. The start file offset is given |
| @@ -525,4 +537,9 @@ not the read request structure as they could be used in other situations where · 10 unmodified lines | ||
| 525 | 537 | there isn't a read request structure as well, such as writing dirty data to the |
| 526 | 538 | cache. |
| 527 | 539 | |
| 540 | + | |
| 541 | +API Function Reference | |
| 542 | +====================== | |
| 543 | + | |
| 528 | 544 | .. kernel-doc:: include/linux/netfs.h |
| 545 | +.. kernel-doc:: fs/netfs/read_helper.c | |
| @@ -36,6 +36,8 @@ Key to symbols · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | =============== ============================================================= |
| 38 | 38 | S Start condition |
| 39 | +Sr Repeated start condition, used to switch from write to | |
| 40 | + read mode. | |
| 39 | 41 | P Stop condition |
| 40 | 42 | Rd/Wr (1 bit) Read/Write bit. Rd equals 1, Wr equals 0. |
| 41 | 43 | A, NA (1 bit) Acknowledge (ACK) and Not Acknowledge (NACK) bit |
| @@ -100,7 +102,7 @@ Implemented by i2c_smbus_read_byte_data() · 58 unmodified lines | ||
| 100 | 102 | This reads a single byte from a device, from a designated register. |
| 101 | 103 | The register is specified through the Comm byte:: |
| 102 | 104 | |
| 103 | − S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P | |
| 105 | + S Addr Wr [A] Comm [A] Sr Addr Rd [A] [Data] NA P | |
| 104 | 106 | |
| 105 | 107 | Functionality flag: I2C_FUNC_SMBUS_READ_BYTE_DATA |
| 106 | 108 | |
| @@ -114,7 +116,7 @@ This operation is very like Read Byte; again, data is read from a · 7 unmodified lines | ||
| 114 | 116 | device, from a designated register that is specified through the Comm |
| 115 | 117 | byte. But this time, the data is a complete word (16 bits):: |
| 116 | 118 | |
| 117 | − S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P | |
| 119 | + S Addr Wr [A] Comm [A] Sr Addr Rd [A] [DataLow] A [DataHigh] NA P | |
| 118 | 120 | |
| 119 | 121 | Functionality flag: I2C_FUNC_SMBUS_READ_WORD_DATA |
| 120 | 122 | |
| @@ -164,7 +166,7 @@ This command selects a device register (through the Comm byte), sends · 43 unmodified lines | ||
| 164 | 166 | 16 bits of data to it, and reads 16 bits of data in return:: |
| 165 | 167 | |
| 166 | 168 | S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] |
| 167 | − S Addr Rd [A] [DataLow] A [DataHigh] NA P | |
| 169 | + Sr Addr Rd [A] [DataLow] A [DataHigh] NA P | |
| 168 | 170 | |
| 169 | 171 | Functionality flag: I2C_FUNC_SMBUS_PROC_CALL |
| 170 | 172 | |
| @@ -181,7 +183,7 @@ of data is specified by the device in the Count byte. · 10 unmodified lines | ||
| 181 | 183 | :: |
| 182 | 184 | |
| 183 | 185 | S Addr Wr [A] Comm [A] |
| 184 | − S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P | |
| 186 | + Sr Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P | |
| 185 | 187 | |
| 186 | 188 | Functionality flag: I2C_FUNC_SMBUS_READ_BLOCK_DATA |
| 187 | 189 | |
| @@ -212,7 +214,7 @@ This command selects a device register (through the Comm byte), sends · 24 unmodified lines | ||
| 212 | 214 | 1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return:: |
| 213 | 215 | |
| 214 | 216 | S Addr Wr [A] Comm [A] Count [A] Data [A] ... |
| 215 | − S Addr Rd [A] [Count] A [Data] ... A P | |
| 217 | + Sr Addr Rd [A] [Count] A [Data] ... A P | |
| 216 | 218 | |
| 217 | 219 | Functionality flag: I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
| 218 | 220 | |
| @@ -300,7 +302,7 @@ This command reads a block of bytes from a device, from a · 81 unmodified lines | ||
| 300 | 302 | designated register that is specified through the Comm byte:: |
| 301 | 303 | |
| 302 | 304 | S Addr Wr [A] Comm [A] |
| 303 | − S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P | |
| 305 | + Sr Addr Rd [A] [Data] A [Data] A ... A [Data] NA P | |
| 304 | 306 | |
| 305 | 307 | Functionality flag: I2C_FUNC_SMBUS_READ_I2C_BLOCK |
| 306 | 308 | |
| @@ -439,11 +439,9 @@ preemption. The following substitution works on both kernels:: · 438 unmodified lines | ||
| 439 | 439 | spin_lock(&p->lock); |
| 440 | 440 | p->count += this_cpu_read(var2); |
| 441 | 441 | |
| 442 | −On a non-PREEMPT_RT kernel migrate_disable() maps to preempt_disable() | |
| 443 | −which makes the above code fully equivalent. On a PREEMPT_RT kernel | |
| 444 | 442 | migrate_disable() ensures that the task is pinned on the current CPU which |
| 445 | 443 | in turn guarantees that the per-CPU access to var1 and var2 are staying on |
| 446 | −the same CPU. | |
| 444 | +the same CPU while the task remains preemptible. | |
| 447 | 445 | |
| 448 | 446 | The migrate_disable() substitution is not valid for the following |
| 449 | 447 | scenario:: |
| @@ -456,9 +454,8 @@ scenario:: · 6 unmodified lines | ||
| 456 | 454 | p = this_cpu_ptr(&var1); |
| 457 | 455 | p->val = func2(); |
| 458 | 456 | |
| 459 | −While correct on a non-PREEMPT_RT kernel, this breaks on PREEMPT_RT because | |
| 460 | −here migrate_disable() does not protect against reentrancy from a | |
| 461 | −preempting task. A correct substitution for this case is:: | |
| 457 | +This breaks because migrate_disable() does not protect against reentrancy from | |
| 458 | +a preempting task. A correct substitution for this case is:: | |
| 462 | 459 | |
| 463 | 460 | func() |
| 464 | 461 | { |
| @@ -37,8 +37,7 @@ conn_reuse_mode - INTEGER · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | 0: disable any special handling on port reuse. The new |
| 39 | 39 | connection will be delivered to the same real server that was |
| 40 | − servicing the previous connection. This will effectively | |
| 41 | − disable expire_nodest_conn. | |
| 40 | + servicing the previous connection. | |
| 42 | 41 | |
| 43 | 42 | bit 1: enable rescheduling of new connections when it is safe. |
| 44 | 43 | That is, whenever expire_nodest_conn and for TCP sockets, when |
| @@ -486,8 +486,8 @@ of packets. · 485 unmodified lines | ||
| 486 | 486 | Drivers are free to use a more permissive configuration than the requested |
| 487 | 487 | configuration. It is expected that drivers should only implement directly the |
| 488 | 488 | most generic mode that can be supported. For example if the hardware can |
| 489 | −support HWTSTAMP_FILTER_V2_EVENT, then it should generally always upscale | |
| 490 | −HWTSTAMP_FILTER_V2_L2_SYNC_MESSAGE, and so forth, as HWTSTAMP_FILTER_V2_EVENT | |
| 489 | +support HWTSTAMP_FILTER_PTP_V2_EVENT, then it should generally always upscale | |
| 490 | +HWTSTAMP_FILTER_PTP_V2_L2_SYNC, and so forth, as HWTSTAMP_FILTER_PTP_V2_EVENT | |
| 491 | 491 | is more generic (and more useful to applications). |
| 492 | 492 | |
| 493 | 493 | A driver which supports hardware time stamping shall update the struct |
| @@ -84,6 +84,16 @@ CONFIG_ENERGY_MODEL must be enabled to use the EM framework. · 83 unmodified lines | ||
| 84 | 84 | 2.2 Registration of performance domains |
| 85 | 85 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 86 | 86 | |
| 87 | +Registration of 'advanced' EM | |
| 88 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 89 | + | |
| 90 | +The 'advanced' EM gets it's name due to the fact that the driver is allowed | |
| 91 | +to provide more precised power model. It's not limited to some implemented math | |
| 92 | +formula in the framework (like it's in 'simple' EM case). It can better reflect | |
| 93 | +the real power measurements performed for each performance state. Thus, this | |
| 94 | +registration method should be preferred in case considering EM static power | |
| 95 | +(leakage) is important. | |
| 96 | + | |
| 87 | 97 | Drivers are expected to register performance domains into the EM framework by |
| 88 | 98 | calling the following API:: |
| 89 | 99 | |
| @@ -103,6 +113,18 @@ to: return warning/error, stop working or panic. · 13 unmodified lines | ||
| 103 | 113 | See Section 3. for an example of driver implementing this |
| 104 | 114 | callback, or Section 2.4 for further documentation on this API |
| 105 | 115 | |
| 116 | +Registration of 'simple' EM | |
| 117 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 118 | + | |
| 119 | +The 'simple' EM is registered using the framework helper function | |
| 120 | +cpufreq_register_em_with_opp(). It implements a power model which is tight to | |
| 121 | +math formula:: | |
| 122 | + | |
| 123 | + Power = C * V^2 * f | |
| 124 | + | |
| 125 | +The EM which is registered using this method might not reflect correctly the | |
| 126 | +physics of a real device, e.g. when static power (leakage) is important. | |
| 127 | + | |
| 106 | 128 | |
| 107 | 129 | 2.3 Accessing performance domains |
| 108 | 130 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| @@ -138,6 +160,10 @@ or in Section 2.4 · 29 unmodified lines | ||
| 138 | 160 | 3. Example driver |
| 139 | 161 | ----------------- |
| 140 | 162 | |
| 163 | +The CPUFreq framework supports dedicated callback for registering | |
| 164 | +the EM for a given CPU(s) 'policy' object: cpufreq_driver::register_em(). | |
| 165 | +That callback has to be implemented properly for a given driver, | |
| 166 | +because the framework would call it at the right time during setup. | |
| 141 | 167 | This section provides a simple example of a CPUFreq driver registering a |
| 142 | 168 | performance domain in the Energy Model framework using the (fake) 'foo' |
| 143 | 169 | protocol. The driver implements an est_power() function to be provided to the |
| @@ -167,25 +193,22 @@ EM framework:: · 23 unmodified lines | ||
| 167 | 193 | 20 return 0; |
| 168 | 194 | 21 } |
| 169 | 195 | 22 |
| 170 | − 23 static int foo_cpufreq_init(struct cpufreq_policy *policy) | |
| 196 | + 23 static void foo_cpufreq_register_em(struct cpufreq_policy *policy) | |
| 171 | 197 | 24 { |
| 172 | 198 | 25 struct em_data_callback em_cb = EM_DATA_CB(est_power); |
| 173 | 199 | 26 struct device *cpu_dev; |
| 174 | − 27 int nr_opp, ret; | |
| 200 | + 27 int nr_opp; | |
| 175 | 201 | 28 |
| 176 | 202 | 29 cpu_dev = get_cpu_device(cpumask_first(policy->cpus)); |
| 177 | 203 | 30 |
| 178 | − 31 /* Do the actual CPUFreq init work ... */ | |
| 179 | − 32 ret = do_foo_cpufreq_init(policy); | |
| 180 | − 33 if (ret) | |
| 181 | − 34 return ret; | |
| 182 | − 35 | |
| 183 | − 36 /* Find the number of OPPs for this policy */ | |
| 184 | − 37 nr_opp = foo_get_nr_opp(policy); | |
| 204 | + 31 /* Find the number of OPPs for this policy */ | |
| 205 | + 32 nr_opp = foo_get_nr_opp(policy); | |
| 206 | + 33 | |
| 207 | + 34 /* And register the new performance domain */ | |
| 208 | + 35 em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus, | |
| 209 | + 36 true); | |
| 210 | + 37 } | |
| 185 | 211 | 38 |
| 186 | − 39 /* And register the new performance domain */ | |
| 187 | − 40 em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus, | |
| 188 | − 41 true); | |
| 189 | − 42 | |
| 190 | − 43 return 0; | |
| 191 | − 44 } | |
| 212 | + 39 static struct cpufreq_driver foo_cpufreq_driver = { | |
| 213 | + 40 .register_em = foo_cpufreq_register_em, | |
| 214 | + 41 }; | |
| @@ -35,6 +35,7 @@ GNU make 3.81 make --version · 34 unmodified lines | ||
| 35 | 35 | binutils 2.23 ld -v |
| 36 | 36 | flex 2.5.35 flex --version |
| 37 | 37 | bison 2.0 bison --version |
| 38 | +pahole 1.16 pahole --version | |
| 38 | 39 | util-linux 2.10o fdformat --version |
| 39 | 40 | kmod 13 depmod -V |
| 40 | 41 | e2fsprogs 1.41.4 e2fsck -V |
| @@ -54,7 +55,7 @@ mcelog 0.6 mcelog --version · 13 unmodified lines | ||
| 54 | 55 | iptables 1.4.2 iptables -V |
| 55 | 56 | openssl & libcrypto 1.0.0 openssl version |
| 56 | 57 | bc 1.06.95 bc --version |
| 57 | −Sphinx\ [#f1]_ 1.3 sphinx-build --version | |
| 58 | +Sphinx\ [#f1]_ 1.7 sphinx-build --version | |
| 58 | 59 | ====================== =============== ======================================== |
| 59 | 60 | |
| 60 | 61 | .. [#f1] Sphinx is needed only to build the Kernel documentation |
| @@ -108,6 +109,16 @@ Bison · 47 unmodified lines | ||
| 108 | 109 | Since Linux 4.16, the build system generates parsers |
| 109 | 110 | during build. This requires bison 2.0 or later. |
| 110 | 111 | |
| 112 | +pahole: | |
| 113 | +------- | |
| 114 | + | |
| 115 | +Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system | |
| 116 | +generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel | |
| 117 | +modules as well. This requires pahole v1.16 or later. | |
| 118 | + | |
| 119 | +It is found in the 'dwarves' or 'pahole' distro packages or from | |
| 120 | +https://fedorapeople.org/~acme/dwarves/. | |
| 121 | + | |
| 111 | 122 | Perl |
| 112 | 123 | ---- |
| 113 | 124 | |
| @@ -14,7 +14,8 @@ works, see Documentation/process/development-process.rst. Also, read · 13 unmodified lines | ||
| 14 | 14 | Documentation/process/submit-checklist.rst |
| 15 | 15 | for a list of items to check before submitting code. If you are submitting |
| 16 | 16 | a driver, also read Documentation/process/submitting-drivers.rst; for device |
| 17 | −tree binding patches, read Documentation/process/submitting-patches.rst. | |
| 17 | +tree binding patches, read | |
| 18 | +Documentation/devicetree/bindings/submitting-patches.rst. | |
| 18 | 19 | |
| 19 | 20 | This documentation assumes that you're using ``git`` to prepare your patches. |
| 20 | 21 | If you're unfamiliar with ``git``, you would be well-advised to learn how to |
| @@ -22,8 +23,8 @@ use it, it will make your life as a kernel developer and in general much · 1 unmodified line | ||
| 22 | 23 | easier. |
| 23 | 24 | |
| 24 | 25 | Some subsystems and maintainer trees have additional information about |
| 25 | −their workflow and expectations, see :ref:`Documentation/process/maintainer | |
| 26 | −handbooks <maintainer_handbooks_main>`. | |
| 26 | +their workflow and expectations, see | |
| 27 | +:ref:`Documentation/process/maintainer-handbooks.rst <maintainer_handbooks_main>`. | |
| 27 | 28 | |
| 28 | 29 | Obtain a current source tree |
| 29 | 30 | ---------------------------- |
| @@ -2442,11 +2442,10 @@ Or this simple script! · 2441 unmodified lines | ||
| 2442 | 2442 | #!/bin/bash |
| 2443 | 2443 | |
| 2444 | 2444 | tracefs=`sed -ne 's/^tracefs \(.*\) tracefs.*/\1/p' /proc/mounts` |
| 2445 | − echo nop > $tracefs/tracing/current_tracer | |
| 2446 | − echo 0 > $tracefs/tracing/tracing_on | |
| 2447 | − echo $$ > $tracefs/tracing/set_ftrace_pid | |
| 2448 | − echo function > $tracefs/tracing/current_tracer | |
| 2449 | − echo 1 > $tracefs/tracing/tracing_on | |
| 2445 | + echo 0 > $tracefs/tracing_on | |
| 2446 | + echo $$ > $tracefs/set_ftrace_pid | |
| 2447 | + echo function > $tracefs/current_tracer | |
| 2448 | + echo 1 > $tracefs/tracing_on | |
| 2450 | 2449 | exec "$@" |
| 2451 | 2450 | |
| 2452 | 2451 | |
| @@ -35,7 +35,7 @@ Installazione Sphinx · 34 unmodified lines | ||
| 35 | 35 | ==================== |
| 36 | 36 | |
| 37 | 37 | I marcatori ReST utilizzati nei file in Documentation/ sono pensati per essere |
| 38 | −processati da ``Sphinx`` nella versione 1.3 o superiore. | |
| 38 | +processati da ``Sphinx`` nella versione 1.7 o superiore. | |
| 39 | 39 | |
| 40 | 40 | Esiste uno script che verifica i requisiti Sphinx. Per ulteriori dettagli |
| 41 | 41 | consultate :ref:`it_sphinx-pre-install`. |
| @@ -53,11 +53,6 @@ pacchettizzato dalla vostra distribuzione. · 11 unmodified lines | ||
| 53 | 53 | |
| 54 | 54 | .. note:: |
| 55 | 55 | |
| 56 | − #) Le versioni di Sphinx inferiori alla 1.5 non funzionano bene | |
| 57 | − con il pacchetto Python docutils versione 0.13.1 o superiore. | |
| 58 | − Se volete usare queste versioni, allora dovere eseguire | |
| 59 | − ``pip install 'docutils==0.12'``. | |
| 60 | − | |
| 61 | 56 | #) Viene raccomandato l'uso del tema RTD per la documentazione in HTML. |
| 62 | 57 | A seconda della versione di Sphinx, potrebbe essere necessaria |
| 63 | 58 | l'installazione tramite il comando ``pip install sphinx_rtd_theme``. |
| @@ -67,13 +62,13 @@ pacchettizzato dalla vostra distribuzione. · 3 unmodified lines | ||
| 67 | 62 | utilizzando LaTeX. Per una corretta interpretazione, è necessario aver |
| 68 | 63 | installato texlive con i pacchetti amdfonts e amsmath. |
| 69 | 64 | |
| 70 | −Riassumendo, se volete installare la versione 1.7.9 di Sphinx dovete eseguire:: | |
| 65 | +Riassumendo, se volete installare la versione 2.4.4 di Sphinx dovete eseguire:: | |
| 71 | 66 | |
| 72 | − $ virtualenv sphinx_1.7.9 | |
| 73 | − $ . sphinx_1.7.9/bin/activate | |
| 74 | − (sphinx_1.7.9) $ pip install -r Documentation/sphinx/requirements.txt | |
| 67 | + $ virtualenv sphinx_2.4.4 | |
| 68 | + $ . sphinx_2.4.4/bin/activate | |
| 69 | + (sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt | |
| 75 | 70 | |
| 76 | −Dopo aver eseguito ``. sphinx_1.7.9/bin/activate``, il prompt cambierà per | |
| 71 | +Dopo aver eseguito ``. sphinx_2.4.4/bin/activate``, il prompt cambierà per | |
| 77 | 72 | indicare che state usando il nuovo ambiente. Se aprite un nuova sessione, |
| 78 | 73 | prima di generare la documentazione, dovrete rieseguire questo comando per |
| 79 | 74 | rientrare nell'ambiente virtuale. |
| @@ -94,7 +89,7 @@ Generazione in PDF e LaTeX · 14 unmodified lines | ||
| 94 | 89 | -------------------------- |
| 95 | 90 | |
| 96 | 91 | Al momento, la generazione di questi documenti è supportata solo dalle |
| 97 | −versioni di Sphinx superiori alla 1.4. | |
| 92 | +versioni di Sphinx superiori alla 2.4. | |
| 98 | 93 | |
| 99 | 94 | Per la generazione di PDF e LaTeX, avrete bisogno anche del pacchetto |
| 100 | 95 | ``XeLaTeX`` nella versione 3.14159265 |
| @@ -119,8 +114,8 @@ l'installazione:: · 18 unmodified lines | ||
| 119 | 114 | You should run: |
| 120 | 115 | |
| 121 | 116 | sudo dnf install -y texlive-luatex85 |
| 122 | − /usr/bin/virtualenv sphinx_1.7.9 | |
| 123 | − . sphinx_1.7.9/bin/activate | |
| 117 | + /usr/bin/virtualenv sphinx_2.4.4 | |
| 118 | + . sphinx_2.4.4/bin/activate | |
| 124 | 119 | pip install -r Documentation/sphinx/requirements.txt |
| 125 | 120 | |
| 126 | 121 | Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468. |
| @@ -57,7 +57,7 @@ mcelog 0.6 mcelog --version · 56 unmodified lines | ||
| 57 | 57 | iptables 1.4.2 iptables -V |
| 58 | 58 | openssl & libcrypto 1.0.0 openssl version |
| 59 | 59 | bc 1.06.95 bc --version |
| 60 | −Sphinx\ [#f1]_ 1.3 sphinx-build --version | |
| 60 | +Sphinx\ [#f1]_ 1.7 sphinx-build --version | |
| 61 | 61 | ====================== ================= ======================================== |
| 62 | 62 | |
| 63 | 63 | .. [#f1] Sphinx è necessario solo per produrre la documentazione del Kernel |
| @@ -26,7 +26,7 @@ reStructuredText文件可能包含包含来自源文件的结构化文档注释 · 25 unmodified lines | ||
| 26 | 26 | 安装Sphinx |
| 27 | 27 | ========== |
| 28 | 28 | |
| 29 | −Documentation/ 下的ReST文件现在使用sphinx1.3或更高版本构建。 | |
| 29 | +Documentation/ 下的ReST文件现在使用sphinx1.7或更高版本构建。 | |
| 30 | 30 | |
| 31 | 31 | 这有一个脚本可以检查Sphinx的依赖项。更多详细信息见 |
| 32 | 32 | :ref:`sphinx-pre-install_zh` 。 |
| @@ -40,22 +40,19 @@ Documentation/ 下的ReST文件现在使用sphinx1.3或更高版本构建。 · 7 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | .. note:: |
| 42 | 42 | |
| 43 | − #) 低于1.5版本的Sphinx无法与Python的0.13.1或更高版本docutils一起正常工作。 | |
| 44 | − 如果您想使用这些版本,那么应该运行 ``pip install 'docutils==0.12'`` 。 | |
| 45 | − | |
| 46 | 43 | #) html输出建议使用RTD主题。根据Sphinx版本的不同,它应该用 |
| 47 | 44 | ``pip install sphinx_rtd_theme`` 单独安装。 |
| 48 | 45 | |
| 49 | 46 | #) 一些ReST页面包含数学表达式。由于Sphinx的工作方式,这些表达式是使用 LaTeX |
| 50 | 47 | 编写的。它需要安装amsfonts和amsmath宏包,以便显示。 |
| 51 | 48 | |
| 52 | −总之,如您要安装Sphinx 1.7.9版本,应执行:: | |
| 49 | +总之,如您要安装Sphinx 2.4.4版本,应执行:: | |
| 53 | 50 | |
| 54 | − $ virtualenv sphinx_1.7.9 | |
| 55 | − $ . sphinx_1.7.9/bin/activate | |
| 56 | − (sphinx_1.7.9) $ pip install -r Documentation/sphinx/requirements.txt | |
| 51 | + $ virtualenv sphinx_2.4.4 | |
| 52 | + $ . sphinx_2.4.4/bin/activate | |
| 53 | + (sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt | |
| 57 | 54 | |
| 58 | −在运行 ``. sphinx_1.7.9/bin/activate`` 之后,提示符将变化,以指示您正在使用新 | |
| 55 | +在运行 ``. sphinx_2.4.4/bin/activate`` 之后,提示符将变化,以指示您正在使用新 | |
| 59 | 56 | 环境。如果您打开了一个新的shell,那么在构建文档之前,您需要重新运行此命令以再 |
| 60 | 57 | 次进入虚拟环境中。 |
| 61 | 58 | |
| @@ -71,7 +68,7 @@ Documentation/ 下的ReST文件现在使用sphinx1.3或更高版本构建。 · 9 unmodified lines | ||
| 71 | 68 | PDF和LaTeX构建 |
| 72 | 69 | -------------- |
| 73 | 70 | |
| 74 | −目前只有Sphinx 1.4及更高版本才支持这种构建。 | |
| 71 | +目前只有Sphinx 2.4及更高版本才支持这种构建。 | |
| 75 | 72 | |
| 76 | 73 | 对于PDF和LaTeX输出,还需要 ``XeLaTeX`` 3.14159265版本。(译注:此版本号真实 |
| 77 | 74 | 存在) |
| @@ -93,8 +90,8 @@ PDF和LaTeX构建 · 15 unmodified lines | ||
| 93 | 90 | You should run: |
| 94 | 91 | |
| 95 | 92 | sudo dnf install -y texlive-luatex85 |
| 96 | − /usr/bin/virtualenv sphinx_1.7.9 | |
| 97 | − . sphinx_1.7.9/bin/activate | |
| 93 | + /usr/bin/virtualenv sphinx_2.4.4 | |
| 94 | + . sphinx_2.4.4/bin/activate | |
| 98 | 95 | pip install -r Documentation/sphinx/requirements.txt |
| 99 | 96 | |
| 100 | 97 | Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468. |
| @@ -36,14 +36,14 @@ Linux内核管理风格 · 35 unmodified lines | ||
| 36 | 36 | 每个人都认为管理者做决定,而且决策很重要。决定越大越痛苦,管理者就必须越高级。 |
| 37 | 37 | 这很明显,但事实并非如此。 |
| 38 | 38 | |
| 39 | −游戏的名字是 **避免** 做出决定。尤其是,如果有人告诉你“选择(a)或(b), | |
| 39 | +最重要的是 **避免** 做出决定。尤其是,如果有人告诉你“选择(a)或(b), | |
| 40 | 40 | 我们真的需要你来做决定”,你就是陷入麻烦的管理者。你管理的人比你更了解细节, |
| 41 | 41 | 所以如果他们来找你做技术决策,你完蛋了。你显然没有能力为他们做这个决定。 |
| 42 | 42 | |
| 43 | 43 | (推论:如果你管理的人不比你更了解细节,你也会被搞砸,尽管原因完全不同。 |
| 44 | 44 | 也就是说,你的工作是错的,他们应该管理你的才智) |
| 45 | 45 | |
| 46 | −所以游戏的名字是 **避免** 做出决定,至少是那些大而痛苦的决定。做一些小的 | |
| 46 | +所以最重要的是 **避免** 做出决定,至少是那些大而痛苦的决定。做一些小的 | |
| 47 | 47 | 和非结果性的决定是很好的,并且使您看起来好像知道自己在做什么,所以内核管理者 |
| 48 | 48 | 需要做的是将那些大的和痛苦的决定变成那些没有人真正关心的小事情。 |
| 49 | 49 | |
| @@ -2263,6 +2263,15 @@ L: linux-iio@vger.kernel.org · 2262 unmodified lines | ||
| 2263 | 2263 | S: Maintained |
| 2264 | 2264 | F: drivers/counter/microchip-tcb-capture.c |
| 2265 | 2265 | |
| 2266 | +ARM/MILBEAUT ARCHITECTURE | |
| 2267 | +M: Taichi Sugaya <sugaya.taichi@socionext.com> | |
| 2268 | +M: Takao Orito <orito.takao@socionext.com> | |
| 2269 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 2270 | +S: Maintained | |
| 2271 | +F: arch/arm/boot/dts/milbeaut* | |
| 2272 | +F: arch/arm/mach-milbeaut/ | |
| 2273 | +N: milbeaut | |
| 2274 | + | |
| 2266 | 2275 | ARM/MIOA701 MACHINE SUPPORT |
| 2267 | 2276 | M: Robert Jarzmik <robert.jarzmik@free.fr> |
| 2268 | 2277 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -2729,10 +2738,11 @@ S: Maintained · 460 unmodified lines | ||
| 2729 | 2738 | F: drivers/memory/*emif* |
| 2730 | 2739 | |
| 2731 | 2740 | ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE |
| 2741 | +M: Nishanth Menon <nm@ti.com> | |
| 2732 | 2742 | M: Santosh Shilimkar <ssantosh@kernel.org> |
| 2733 | 2743 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2734 | 2744 | S: Maintained |
| 2735 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git | |
| 2745 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git | |
| 2736 | 2746 | F: arch/arm/boot/dts/keystone-* |
| 2737 | 2747 | F: arch/arm/mach-keystone/ |
| 2738 | 2748 | |
| @@ -3570,13 +3580,14 @@ L: netdev@vger.kernel.org · 831 unmodified lines | ||
| 3570 | 3580 | S: Supported |
| 3571 | 3581 | F: drivers/net/ethernet/broadcom/b44.* |
| 3572 | 3582 | |
| 3573 | −BROADCOM B53 ETHERNET SWITCH DRIVER | |
| 3583 | +BROADCOM B53/SF2 ETHERNET SWITCH DRIVER | |
| 3574 | 3584 | M: Florian Fainelli <f.fainelli@gmail.com> |
| 3575 | 3585 | L: netdev@vger.kernel.org |
| 3576 | 3586 | L: openwrt-devel@lists.openwrt.org (subscribers-only) |
| 3577 | 3587 | S: Supported |
| 3578 | 3588 | F: Documentation/devicetree/bindings/net/dsa/brcm,b53.yaml |
| 3579 | 3589 | F: drivers/net/dsa/b53/* |
| 3590 | +F: drivers/net/dsa/bcm_sf2* | |
| 3580 | 3591 | F: include/linux/dsa/brcm.h |
| 3581 | 3592 | F: include/linux/platform_data/b53.h |
| 3582 | 3593 | |
| @@ -3733,7 +3744,7 @@ F: drivers/scsi/bnx2i/ · 150 unmodified lines | ||
| 3733 | 3744 | BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER |
| 3734 | 3745 | M: Ariel Elior <aelior@marvell.com> |
| 3735 | 3746 | M: Sudarsana Kalluru <skalluru@marvell.com> |
| 3736 | −M: GR-everest-linux-l2@marvell.com | |
| 3747 | +M: Manish Chopra <manishc@marvell.com> | |
| 3737 | 3748 | L: netdev@vger.kernel.org |
| 3738 | 3749 | S: Supported |
| 3739 | 3750 | F: drivers/net/ethernet/broadcom/bnx2x/ |
| @@ -9318,7 +9329,6 @@ S: Maintained · 5578 unmodified lines | ||
| 9318 | 9329 | F: drivers/iio/pressure/dps310.c |
| 9319 | 9330 | |
| 9320 | 9331 | INFINIBAND SUBSYSTEM |
| 9321 | −M: Doug Ledford <dledford@redhat.com> | |
| 9322 | 9332 | M: Jason Gunthorpe <jgg@nvidia.com> |
| 9323 | 9333 | L: linux-rdma@vger.kernel.org |
| 9324 | 9334 | S: Supported |
| @@ -10269,9 +10279,9 @@ F: lib/Kconfig.kcsan · 944 unmodified lines | ||
| 10269 | 10279 | F: scripts/Makefile.kcsan |
| 10270 | 10280 | |
| 10271 | 10281 | KDUMP |
| 10272 | −M: Dave Young <dyoung@redhat.com> | |
| 10273 | 10282 | M: Baoquan He <bhe@redhat.com> |
| 10274 | 10283 | R: Vivek Goyal <vgoyal@redhat.com> |
| 10284 | +R: Dave Young <dyoung@redhat.com> | |
| 10275 | 10285 | L: kexec@lists.infradead.org |
| 10276 | 10286 | S: Maintained |
| 10277 | 10287 | W: http://lse.sourceforge.net/kdump/ |
| @@ -10445,7 +10455,7 @@ F: arch/riscv/include/uapi/asm/kvm* · 167 unmodified lines | ||
| 10445 | 10455 | F: arch/riscv/kvm/ |
| 10446 | 10456 | |
| 10447 | 10457 | KERNEL VIRTUAL MACHINE for s390 (KVM/s390) |
| 10448 | −M: Christian Borntraeger <borntraeger@de.ibm.com> | |
| 10458 | +M: Christian Borntraeger <borntraeger@linux.ibm.com> | |
| 10449 | 10459 | M: Janosch Frank <frankja@linux.ibm.com> |
| 10450 | 10460 | R: David Hildenbrand <david@redhat.com> |
| 10451 | 10461 | R: Claudio Imbrenda <imbrenda@linux.ibm.com> |
| @@ -12169,8 +12179,8 @@ F: drivers/net/ethernet/mellanox/mlx5/core/fpga/* · 1717 unmodified lines | ||
| 12169 | 12179 | F: include/linux/mlx5/mlx5_ifc_fpga.h |
| 12170 | 12180 | |
| 12171 | 12181 | MELLANOX ETHERNET SWITCH DRIVERS |
| 12172 | −M: Jiri Pirko <jiri@nvidia.com> | |
| 12173 | 12182 | M: Ido Schimmel <idosch@nvidia.com> |
| 12183 | +M: Petr Machata <petrm@nvidia.com> | |
| 12174 | 12184 | L: netdev@vger.kernel.org |
| 12175 | 12185 | S: Supported |
| 12176 | 12186 | W: http://www.mellanox.com |
| @@ -15593,7 +15603,7 @@ F: drivers/scsi/qedi/ · 3416 unmodified lines | ||
| 15593 | 15603 | |
| 15594 | 15604 | QLOGIC QL4xxx ETHERNET DRIVER |
| 15595 | 15605 | M: Ariel Elior <aelior@marvell.com> |
| 15596 | −M: GR-everest-linux-l2@marvell.com | |
| 15606 | +M: Manish Chopra <manishc@marvell.com> | |
| 15597 | 15607 | L: netdev@vger.kernel.org |
| 15598 | 15608 | S: Supported |
| 15599 | 15609 | F: drivers/net/ethernet/qlogic/qed/ |
| @@ -15760,6 +15770,15 @@ S: Maintained · 160 unmodified lines | ||
| 15760 | 15770 | F: Documentation/devicetree/bindings/net/qcom,ethqos.txt |
| 15761 | 15771 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |
| 15762 | 15772 | |
| 15773 | +QUALCOMM FASTRPC DRIVER | |
| 15774 | +M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
| 15775 | +M: Amol Maheshwari <amahesh@qti.qualcomm.com> | |
| 15776 | +L: linux-arm-msm@vger.kernel.org | |
| 15777 | +S: Maintained | |
| 15778 | +F: Documentation/devicetree/bindings/misc/qcom,fastrpc.txt | |
| 15779 | +F: drivers/misc/fastrpc.c | |
| 15780 | +F: include/uapi/misc/fastrpc.h | |
| 15781 | + | |
| 15763 | 15782 | QUALCOMM GENERIC INTERFACE I2C DRIVER |
| 15764 | 15783 | M: Akash Asthana <akashast@codeaurora.org> |
| 15765 | 15784 | M: Mukesh Savaliya <msavaliy@codeaurora.org> |
| @@ -15968,6 +15987,7 @@ F: arch/mips/generic/board-ranchu.c · 202 unmodified lines | ||
| 15968 | 15987 | |
| 15969 | 15988 | RANDOM NUMBER DRIVER |
| 15970 | 15989 | M: "Theodore Ts'o" <tytso@mit.edu> |
| 15990 | +M: Jason A. Donenfeld <Jason@zx2c4.com> | |
| 15971 | 15991 | S: Maintained |
| 15972 | 15992 | F: drivers/char/random.c |
| 15973 | 15993 | |
| @@ -16490,6 +16510,12 @@ T: git git://linuxtv.org/media_tree.git · 516 unmodified lines | ||
| 16490 | 16510 | F: Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml |
| 16491 | 16511 | F: drivers/media/platform/sunxi/sun8i-rotate/ |
| 16492 | 16512 | |
| 16513 | +RPMSG TTY DRIVER | |
| 16514 | +M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> | |
| 16515 | +L: linux-remoteproc@vger.kernel.org | |
| 16516 | +S: Maintained | |
| 16517 | +F: drivers/tty/rpmsg_tty.c | |
| 16518 | + | |
| 16493 | 16519 | RTL2830 MEDIA DRIVER |
| 16494 | 16520 | M: Antti Palosaari <crope@iki.fi> |
| 16495 | 16521 | L: linux-media@vger.kernel.org |
| @@ -16573,7 +16599,7 @@ F: drivers/video/fbdev/savage/ · 77 unmodified lines | ||
| 16573 | 16599 | S390 |
| 16574 | 16600 | M: Heiko Carstens <hca@linux.ibm.com> |
| 16575 | 16601 | M: Vasily Gorbik <gor@linux.ibm.com> |
| 16576 | −M: Christian Borntraeger <borntraeger@de.ibm.com> | |
| 16602 | +M: Christian Borntraeger <borntraeger@linux.ibm.com> | |
| 16577 | 16603 | R: Alexander Gordeev <agordeev@linux.ibm.com> |
| 16578 | 16604 | L: linux-s390@vger.kernel.org |
| 16579 | 16605 | S: Supported |
| @@ -16611,8 +16637,8 @@ W: http://www.ibm.com/developerworks/linux/linux390/ · 31 unmodified lines | ||
| 16611 | 16637 | F: drivers/iommu/s390-iommu.c |
| 16612 | 16638 | |
| 16613 | 16639 | S390 IUCV NETWORK LAYER |
| 16614 | −M: Julian Wiedmann <jwi@linux.ibm.com> | |
| 16615 | −M: Karsten Graul <kgraul@linux.ibm.com> | |
| 16640 | +M: Alexandra Winter <wintera@linux.ibm.com> | |
| 16641 | +M: Wenjia Zhang <wenjia@linux.ibm.com> | |
| 16616 | 16642 | L: linux-s390@vger.kernel.org |
| 16617 | 16643 | L: netdev@vger.kernel.org |
| 16618 | 16644 | S: Supported |
| @@ -16622,8 +16648,8 @@ F: include/net/iucv/ · 3 unmodified lines | ||
| 16622 | 16648 | F: net/iucv/ |
| 16623 | 16649 | |
| 16624 | 16650 | S390 NETWORK DRIVERS |
| 16625 | −M: Julian Wiedmann <jwi@linux.ibm.com> | |
| 16626 | −M: Karsten Graul <kgraul@linux.ibm.com> | |
| 16651 | +M: Alexandra Winter <wintera@linux.ibm.com> | |
| 16652 | +M: Wenjia Zhang <wenjia@linux.ibm.com> | |
| 16627 | 16653 | L: linux-s390@vger.kernel.org |
| 16628 | 16654 | L: netdev@vger.kernel.org |
| 16629 | 16655 | S: Supported |
| @@ -18483,6 +18509,7 @@ F: include/uapi/linux/pkt_sched.h · 1853 unmodified lines | ||
| 18483 | 18509 | F: include/uapi/linux/tc_act/ |
| 18484 | 18510 | F: include/uapi/linux/tc_ematch/ |
| 18485 | 18511 | F: net/sched/ |
| 18512 | +F: tools/testing/selftests/tc-testing | |
| 18486 | 18513 | |
| 18487 | 18514 | TC90522 MEDIA DRIVER |
| 18488 | 18515 | M: Akihiro Tsukada <tskd08@gmail.com> |
| @@ -19031,11 +19058,12 @@ F: drivers/mmc/host/tifm_sd.c · 542 unmodified lines | ||
| 19031 | 19058 | F: include/linux/tifm.h |
| 19032 | 19059 | |
| 19033 | 19060 | TI KEYSTONE MULTICORE NAVIGATOR DRIVERS |
| 19061 | +M: Nishanth Menon <nm@ti.com> | |
| 19034 | 19062 | M: Santosh Shilimkar <ssantosh@kernel.org> |
| 19035 | 19063 | L: linux-kernel@vger.kernel.org |
| 19036 | 19064 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 19037 | 19065 | S: Maintained |
| 19038 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git | |
| 19066 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git | |
| 19039 | 19067 | F: drivers/soc/ti/* |
| 19040 | 19068 | |
| 19041 | 19069 | TI LM49xxx FAMILY ASoC CODEC DRIVERS |
| @@ -20317,7 +20345,8 @@ F: arch/x86/include/asm/vmware.h · 1275 unmodified lines | ||
| 20317 | 20345 | F: arch/x86/kernel/cpu/vmware.c |
| 20318 | 20346 | |
| 20319 | 20347 | VMWARE PVRDMA DRIVER |
| 20320 | −M: Adit Ranadive <aditr@vmware.com> | |
| 20348 | +M: Bryan Tan <bryantan@vmware.com> | |
| 20349 | +M: Vishnu Dasa <vdasa@vmware.com> | |
| 20321 | 20350 | M: VMware PV-Drivers <pv-drivers@vmware.com> |
| 20322 | 20351 | L: linux-rdma@vger.kernel.org |
| 20323 | 20352 | S: Maintained |
| @@ -2,8 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 16 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc1 | |
| 6 | −NAME = Trick or Treat | |
| 5 | +EXTRAVERSION = -rc5 | |
| 6 | +NAME = Gobble Gobble | |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| 9 | 9 | # To see a list of typical targets execute "make help" |
| @@ -789,7 +789,7 @@ stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-strong · 779 unmodified lines | ||
| 789 | 789 | KBUILD_CFLAGS += $(stackp-flags-y) |
| 790 | 790 | |
| 791 | 791 | KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror |
| 792 | −KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) | |
| 792 | +KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH:"%"=%) | |
| 793 | 793 | |
| 794 | 794 | ifdef CONFIG_CC_IS_CLANG |
| 795 | 795 | KBUILD_CPPFLAGS += -Qunused-arguments |
| @@ -1374,17 +1374,17 @@ endif · 578 unmodified lines | ||
| 1374 | 1374 | |
| 1375 | 1375 | ifneq ($(dtstree),) |
| 1376 | 1376 | |
| 1377 | −%.dtb: dt_binding_check include/config/kernel.release scripts_dtc | |
| 1378 | − $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ $(dtstree)/$*.dt.yaml | |
| 1377 | +%.dtb: include/config/kernel.release scripts_dtc | |
| 1378 | + $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ | |
| 1379 | 1379 | |
| 1380 | −%.dtbo: dt_binding_check include/config/kernel.release scripts_dtc | |
| 1381 | − $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ $(dtstree)/$*.dt.yaml | |
| 1380 | +%.dtbo: include/config/kernel.release scripts_dtc | |
| 1381 | + $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ | |
| 1382 | 1382 | |
| 1383 | 1383 | PHONY += dtbs dtbs_install dtbs_check |
| 1384 | 1384 | dtbs: include/config/kernel.release scripts_dtc |
| 1385 | 1385 | $(Q)$(MAKE) $(build)=$(dtstree) |
| 1386 | 1386 | |
| 1387 | −ifneq ($(filter dtbs_check %.dtb %.dtbo, $(MAKECMDGOALS)),) | |
| 1387 | +ifneq ($(filter dtbs_check, $(MAKECMDGOALS)),) | |
| 1388 | 1388 | export CHECK_DTBS=y |
| 1389 | 1389 | dtbs: dt_binding_check |
| 1390 | 1390 | endif |
| @@ -991,6 +991,16 @@ config HAVE_ARCH_COMPAT_MMAP_BASES · 990 unmodified lines | ||
| 991 | 991 | and vice-versa 32-bit applications to call 64-bit mmap(). |
| 992 | 992 | Required for applications doing different bitness syscalls. |
| 993 | 993 | |
| 994 | +config PAGE_SIZE_LESS_THAN_64KB | |
| 995 | + def_bool y | |
| 996 | + depends on !ARM64_64K_PAGES | |
| 997 | + depends on !IA64_PAGE_SIZE_64KB | |
| 998 | + depends on !PAGE_SIZE_64KB | |
| 999 | + depends on !PARISC_PAGE_SIZE_64KB | |
| 1000 | + depends on !PPC_64K_PAGES | |
| 1001 | + depends on !PPC_256K_PAGES | |
| 1002 | + depends on !PAGE_SIZE_256KB | |
| 1003 | + | |
| 994 | 1004 | # This allows to use a set of generic functions to determine mmap base |
| 995 | 1005 | # address by giving priority to top-down scheme only if the process |
| 996 | 1006 | # is not in legacy mode (compat task, unlimited stack size or |
| @@ -488,3 +488,4 @@ · 487 unmodified lines | ||
| 488 | 488 | 556 common landlock_restrict_self sys_landlock_restrict_self |
| 489 | 489 | # 557 reserved for memfd_secret |
| 490 | 490 | 558 common process_mrelease sys_process_mrelease |
| 491 | +559 common futex_waitv sys_futex_waitv | |
| @@ -36,7 +36,6 @@ void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr); · 35 unmodified lines | ||
| 36 | 36 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 37 | 37 | |
| 38 | 38 | void flush_dcache_page(struct page *page); |
| 39 | −void flush_dcache_folio(struct folio *folio); | |
| 40 | 39 | |
| 41 | 40 | void dma_cache_wback_inv(phys_addr_t start, unsigned long sz); |
| 42 | 41 | void dma_cache_inv(phys_addr_t start, unsigned long sz); |
| @@ -1463,6 +1463,7 @@ config HIGHMEM · 1462 unmodified lines | ||
| 1463 | 1463 | bool "High Memory Support" |
| 1464 | 1464 | depends on MMU |
| 1465 | 1465 | select KMAP_LOCAL |
| 1466 | + select KMAP_LOCAL_NON_LINEAR_PTE_ARRAY | |
| 1466 | 1467 | help |
| 1467 | 1468 | The address space of ARM processors is only 4 Gigabytes large |
| 1468 | 1469 | and it has to accommodate user address space, kernel address |
| @@ -506,11 +506,17 @@ · 505 unmodified lines | ||
| 506 | 506 | #address-cells = <3>; |
| 507 | 507 | #interrupt-cells = <1>; |
| 508 | 508 | #size-cells = <2>; |
| 509 | − interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, | |
| 509 | + interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>, | |
| 510 | 510 | <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; |
| 511 | 511 | interrupt-names = "pcie", "msi"; |
| 512 | 512 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; |
| 513 | 513 | interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 |
| 514 | + IRQ_TYPE_LEVEL_HIGH>, | |
| 515 | + <0 0 0 2 &gicv2 GIC_SPI 144 | |
| 516 | + IRQ_TYPE_LEVEL_HIGH>, | |
| 517 | + <0 0 0 3 &gicv2 GIC_SPI 145 | |
| 518 | + IRQ_TYPE_LEVEL_HIGH>, | |
| 519 | + <0 0 0 4 &gicv2 GIC_SPI 146 | |
| 514 | 520 | IRQ_TYPE_LEVEL_HIGH>; |
| 515 | 521 | msi-controller; |
| 516 | 522 | msi-parent = <&pcie0>; |
| @@ -242,6 +242,8 @@ · 241 unmodified lines | ||
| 242 | 242 | |
| 243 | 243 | gpio-controller; |
| 244 | 244 | #gpio-cells = <2>; |
| 245 | + interrupt-controller; | |
| 246 | + #interrupt-cells = <2>; | |
| 245 | 247 | }; |
| 246 | 248 | |
| 247 | 249 | pcie0: pcie@12000 { |
| @@ -408,7 +410,7 @@ · 160 unmodified lines | ||
| 408 | 410 | i2c0: i2c@18009000 { |
| 409 | 411 | compatible = "brcm,iproc-i2c"; |
| 410 | 412 | reg = <0x18009000 0x50>; |
| 411 | − interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; | |
| 413 | + interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; | |
| 412 | 414 | #address-cells = <1>; |
| 413 | 415 | #size-cells = <0>; |
| 414 | 416 | clock-frequency = <100000>; |
| @@ -290,7 +290,6 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr · 289 unmodified lines | ||
| 290 | 290 | */ |
| 291 | 291 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 292 | 292 | extern void flush_dcache_page(struct page *); |
| 293 | −void flush_dcache_folio(struct folio *folio); | |
| 294 | 293 | |
| 295 | 294 | #define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1 |
| 296 | 295 | static inline void flush_kernel_vmap_range(void *addr, int size) |
| @@ -33,7 +33,7 @@ extern void __iomem *sdr_ctl_base_addr; · 32 unmodified lines | ||
| 33 | 33 | u32 socfpga_sdram_self_refresh(u32 sdr_base); |
| 34 | 34 | extern unsigned int socfpga_sdram_self_refresh_sz; |
| 35 | 35 | |
| 36 | −extern char secondary_trampoline, secondary_trampoline_end; | |
| 36 | +extern char secondary_trampoline[], secondary_trampoline_end[]; | |
| 37 | 37 | |
| 38 | 38 | extern unsigned long socfpga_cpu1start_addr; |
| 39 | 39 | |
| @@ -20,14 +20,14 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) |
| 22 | 22 | { |
| 23 | − int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; | |
| 23 | + int trampoline_size = secondary_trampoline_end - secondary_trampoline; | |
| 24 | 24 | |
| 25 | 25 | if (socfpga_cpu1start_addr) { |
| 26 | 26 | /* This will put CPU #1 into reset. */ |
| 27 | 27 | writel(RSTMGR_MPUMODRST_CPU1, |
| 28 | 28 | rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST); |
| 29 | 29 | |
| 30 | − memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); | |
| 30 | + memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size); | |
| 31 | 31 | |
| 32 | 32 | writel(__pa_symbol(secondary_startup), |
| 33 | 33 | sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff)); |
| @@ -45,12 +45,12 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) · 11 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle) |
| 47 | 47 | { |
| 48 | − int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; | |
| 48 | + int trampoline_size = secondary_trampoline_end - secondary_trampoline; | |
| 49 | 49 | |
| 50 | 50 | if (socfpga_cpu1start_addr) { |
| 51 | 51 | writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr + |
| 52 | 52 | SOCFPGA_A10_RSTMGR_MODMPURST); |
| 53 | − memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); | |
| 53 | + memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size); | |
| 54 | 54 | |
| 55 | 55 | writel(__pa_symbol(secondary_startup), |
| 56 | 56 | sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff)); |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * Copyright The Asahi Linux Contributors |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#include <dt-bindings/gpio/gpio.h> | |
| 10 | 11 | #include <dt-bindings/interrupt-controller/apple-aic.h> |
| 11 | 12 | #include <dt-bindings/interrupt-controller/irq.h> |
| 12 | 13 | #include <dt-bindings/pinctrl/apple.h> |
| @@ -281,7 +282,7 @@ · 268 unmodified lines | ||
| 281 | 282 | port00: pci@0,0 { |
| 282 | 283 | device_type = "pci"; |
| 283 | 284 | reg = <0x0 0x0 0x0 0x0 0x0>; |
| 284 | − reset-gpios = <&pinctrl_ap 152 0>; | |
| 285 | + reset-gpios = <&pinctrl_ap 152 GPIO_ACTIVE_LOW>; | |
| 285 | 286 | max-link-speed = <2>; |
| 286 | 287 | |
| 287 | 288 | #address-cells = <3>; |
| @@ -301,7 +302,7 @@ · 13 unmodified lines | ||
| 301 | 302 | port01: pci@1,0 { |
| 302 | 303 | device_type = "pci"; |
| 303 | 304 | reg = <0x800 0x0 0x0 0x0 0x0>; |
| 304 | − reset-gpios = <&pinctrl_ap 153 0>; | |
| 305 | + reset-gpios = <&pinctrl_ap 153 GPIO_ACTIVE_LOW>; | |
| 305 | 306 | max-link-speed = <2>; |
| 306 | 307 | |
| 307 | 308 | #address-cells = <3>; |
| @@ -321,7 +322,7 @@ · 13 unmodified lines | ||
| 321 | 322 | port02: pci@2,0 { |
| 322 | 323 | device_type = "pci"; |
| 323 | 324 | reg = <0x1000 0x0 0x0 0x0 0x0>; |
| 324 | − reset-gpios = <&pinctrl_ap 33 0>; | |
| 325 | + reset-gpios = <&pinctrl_ap 33 GPIO_ACTIVE_LOW>; | |
| 325 | 326 | max-link-speed = <1>; |
| 326 | 327 | |
| 327 | 328 | #address-cells = <3>; |
| @@ -296,8 +296,7 @@ · 295 unmodified lines | ||
| 296 | 296 | pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>; |
| 297 | 297 | phys = <&ufs_0_phy>; |
| 298 | 298 | phy-names = "ufs-phy"; |
| 299 | − samsung,sysreg = <&syscon_fsys2>; | |
| 300 | − samsung,ufs-shareability-reg-offset = <0x710>; | |
| 299 | + samsung,sysreg = <&syscon_fsys2 0x710>; | |
| 301 | 300 | status = "disabled"; |
| 302 | 301 | }; |
| 303 | 302 | }; |
| @@ -12,6 +12,17 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | #define HAVE_FUNCTION_GRAPH_FP_TEST |
| 14 | 14 | |
| 15 | +/* | |
| 16 | + * HAVE_FUNCTION_GRAPH_RET_ADDR_PTR means that the architecture can provide a | |
| 17 | + * "return address pointer" which can be used to uniquely identify a return | |
| 18 | + * address which has been overwritten. | |
| 19 | + * | |
| 20 | + * On arm64 we use the address of the caller's frame record, which remains the | |
| 21 | + * same for the lifetime of the instrumented function, unlike the return | |
| 22 | + * address in the LR. | |
| 23 | + */ | |
| 24 | +#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR | |
| 25 | + | |
| 15 | 26 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS |
| 16 | 27 | #define ARCH_SUPPORTS_FTRACE_OPS 1 |
| 17 | 28 | #else |
| @@ -91,7 +91,7 @@ · 90 unmodified lines | ||
| 91 | 91 | #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) |
| 92 | 92 | |
| 93 | 93 | /* TCR_EL2 Registers bits */ |
| 94 | −#define TCR_EL2_RES1 ((1 << 31) | (1 << 23)) | |
| 94 | +#define TCR_EL2_RES1 ((1U << 31) | (1 << 23)) | |
| 95 | 95 | #define TCR_EL2_TBI (1 << 20) |
| 96 | 96 | #define TCR_EL2_PS_SHIFT 16 |
| 97 | 97 | #define TCR_EL2_PS_MASK (7 << TCR_EL2_PS_SHIFT) |
| @@ -276,7 +276,7 @@ · 178 unmodified lines | ||
| 276 | 276 | #define CPTR_EL2_TFP_SHIFT 10 |
| 277 | 277 | |
| 278 | 278 | /* Hyp Coprocessor Trap Register */ |
| 279 | −#define CPTR_EL2_TCPAC (1 << 31) | |
| 279 | +#define CPTR_EL2_TCPAC (1U << 31) | |
| 280 | 280 | #define CPTR_EL2_TAM (1 << 30) |
| 281 | 281 | #define CPTR_EL2_TTA (1 << 20) |
| 282 | 282 | #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) |
| @@ -76,7 +76,7 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep, · 75 unmodified lines | ||
| 76 | 76 | static inline void |
| 77 | 77 | pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) |
| 78 | 78 | { |
| 79 | − VM_BUG_ON(mm != &init_mm); | |
| 79 | + VM_BUG_ON(mm && mm != &init_mm); | |
| 80 | 80 | __pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE | PMD_TABLE_UXN); |
| 81 | 81 | } |
| 82 | 82 | |
| @@ -47,9 +47,6 @@ struct stack_info { · 46 unmodified lines | ||
| 47 | 47 | * @prev_type: The type of stack this frame record was on, or a synthetic |
| 48 | 48 | * value of STACK_TYPE_UNKNOWN. This is used to detect a |
| 49 | 49 | * transition from one stack to another. |
| 50 | − * | |
| 51 | − * @graph: When FUNCTION_GRAPH_TRACER is selected, holds the index of a | |
| 52 | − * replacement lr value in the ftrace graph stack. | |
| 53 | 50 | */ |
| 54 | 51 | struct stackframe { |
| 55 | 52 | unsigned long fp; |
| @@ -57,9 +54,6 @@ struct stackframe { · 1 unmodified line | ||
| 57 | 54 | DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES); |
| 58 | 55 | unsigned long prev_fp; |
| 59 | 56 | enum stack_type prev_type; |
| 60 | −#ifdef CONFIG_FUNCTION_GRAPH_TRACER | |
| 61 | − int graph; | |
| 62 | −#endif | |
| 63 | 57 | #ifdef CONFIG_KRETPROBES |
| 64 | 58 | struct llist_node *kr_cur; |
| 65 | 59 | #endif |
| @@ -281,12 +281,22 @@ do { \ · 280 unmodified lines | ||
| 281 | 281 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
| 282 | 282 | } while (0) |
| 283 | 283 | |
| 284 | +/* | |
| 285 | + * We must not call into the scheduler between uaccess_ttbr0_enable() and | |
| 286 | + * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions, | |
| 287 | + * we must evaluate these outside of the critical section. | |
| 288 | + */ | |
| 284 | 289 | #define __raw_get_user(x, ptr, err) \ |
| 285 | 290 | do { \ |
| 291 | + __typeof__(*(ptr)) __user *__rgu_ptr = (ptr); \ | |
| 292 | + __typeof__(x) __rgu_val; \ | |
| 286 | 293 | __chk_user_ptr(ptr); \ |
| 294 | + \ | |
| 287 | 295 | uaccess_ttbr0_enable(); \ |
| 288 | − __raw_get_mem("ldtr", x, ptr, err); \ | |
| 296 | + __raw_get_mem("ldtr", __rgu_val, __rgu_ptr, err); \ | |
| 289 | 297 | uaccess_ttbr0_disable(); \ |
| 298 | + \ | |
| 299 | + (x) = __rgu_val; \ | |
| 290 | 300 | } while (0) |
| 291 | 301 | |
| 292 | 302 | #define __get_user_error(x, ptr, err) \ |
| @@ -310,14 +320,22 @@ do { \ · 17 unmodified lines | ||
| 310 | 320 | |
| 311 | 321 | #define get_user __get_user |
| 312 | 322 | |
| 323 | +/* | |
| 324 | + * We must not call into the scheduler between __uaccess_enable_tco_async() and | |
| 325 | + * __uaccess_disable_tco_async(). As `dst` and `src` may contain blocking | |
| 326 | + * functions, we must evaluate these outside of the critical section. | |
| 327 | + */ | |
| 313 | 328 | #define __get_kernel_nofault(dst, src, type, err_label) \ |
| 314 | 329 | do { \ |
| 330 | + __typeof__(dst) __gkn_dst = (dst); \ | |
| 331 | + __typeof__(src) __gkn_src = (src); \ | |
| 315 | 332 | int __gkn_err = 0; \ |
| 316 | 333 | \ |
| 317 | 334 | __uaccess_enable_tco_async(); \ |
| 318 | − __raw_get_mem("ldr", *((type *)(dst)), \ | |
| 319 | − (__force type *)(src), __gkn_err); \ | |
| 335 | + __raw_get_mem("ldr", *((type *)(__gkn_dst)), \ | |
| 336 | + (__force type *)(__gkn_src), __gkn_err); \ | |
| 320 | 337 | __uaccess_disable_tco_async(); \ |
| 338 | + \ | |
| 321 | 339 | if (unlikely(__gkn_err)) \ |
| 322 | 340 | goto err_label; \ |
| 323 | 341 | } while (0) |
| @@ -351,11 +369,19 @@ do { \ · 27 unmodified lines | ||
| 351 | 369 | } \ |
| 352 | 370 | } while (0) |
| 353 | 371 | |
| 372 | +/* | |
| 373 | + * We must not call into the scheduler between uaccess_ttbr0_enable() and | |
| 374 | + * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions, | |
| 375 | + * we must evaluate these outside of the critical section. | |
| 376 | + */ | |
| 354 | 377 | #define __raw_put_user(x, ptr, err) \ |
| 355 | 378 | do { \ |
| 356 | − __chk_user_ptr(ptr); \ | |
| 379 | + __typeof__(*(ptr)) __user *__rpu_ptr = (ptr); \ | |
| 380 | + __typeof__(*(ptr)) __rpu_val = (x); \ | |
| 381 | + __chk_user_ptr(__rpu_ptr); \ | |
| 382 | + \ | |
| 357 | 383 | uaccess_ttbr0_enable(); \ |
| 358 | − __raw_put_mem("sttr", x, ptr, err); \ | |
| 384 | + __raw_put_mem("sttr", __rpu_val, __rpu_ptr, err); \ | |
| 359 | 385 | uaccess_ttbr0_disable(); \ |
| 360 | 386 | } while (0) |
| 361 | 387 | |
| @@ -380,14 +406,22 @@ do { \ · 18 unmodified lines | ||
| 380 | 406 | |
| 381 | 407 | #define put_user __put_user |
| 382 | 408 | |
| 409 | +/* | |
| 410 | + * We must not call into the scheduler between __uaccess_enable_tco_async() and | |
| 411 | + * __uaccess_disable_tco_async(). As `dst` and `src` may contain blocking | |
| 412 | + * functions, we must evaluate these outside of the critical section. | |
| 413 | + */ | |
| 383 | 414 | #define __put_kernel_nofault(dst, src, type, err_label) \ |
| 384 | 415 | do { \ |
| 416 | + __typeof__(dst) __pkn_dst = (dst); \ | |
| 417 | + __typeof__(src) __pkn_src = (src); \ | |
| 385 | 418 | int __pkn_err = 0; \ |
| 386 | 419 | \ |
| 387 | 420 | __uaccess_enable_tco_async(); \ |
| 388 | − __raw_put_mem("str", *((type *)(src)), \ | |
| 389 | − (__force type *)(dst), __pkn_err); \ | |
| 421 | + __raw_put_mem("str", *((type *)(__pkn_src)), \ | |
| 422 | + (__force type *)(__pkn_dst), __pkn_err); \ | |
| 390 | 423 | __uaccess_disable_tco_async(); \ |
| 424 | + \ | |
| 391 | 425 | if (unlikely(__pkn_err)) \ |
| 392 | 426 | goto err_label; \ |
| 393 | 427 | } while(0) |
| @@ -77,11 +77,17 @@ · 76 unmodified lines | ||
| 77 | 77 | .endm |
| 78 | 78 | |
| 79 | 79 | SYM_CODE_START(ftrace_regs_caller) |
| 80 | +#ifdef BTI_C | |
| 81 | + BTI_C | |
| 82 | +#endif | |
| 80 | 83 | ftrace_regs_entry 1 |
| 81 | 84 | b ftrace_common |
| 82 | 85 | SYM_CODE_END(ftrace_regs_caller) |
| 83 | 86 | |
| 84 | 87 | SYM_CODE_START(ftrace_caller) |
| 88 | +#ifdef BTI_C | |
| 89 | + BTI_C | |
| 90 | +#endif | |
| 85 | 91 | ftrace_regs_entry 0 |
| 86 | 92 | b ftrace_common |
| 87 | 93 | SYM_CODE_END(ftrace_caller) |
| @@ -244,8 +244,6 @@ void arch_ftrace_update_code(int command) · 243 unmodified lines | ||
| 244 | 244 | * on the way back to parent. For this purpose, this function is called |
| 245 | 245 | * in _mcount() or ftrace_caller() to replace return address (*parent) on |
| 246 | 246 | * the call stack to return_to_handler. |
| 247 | − * | |
| 248 | − * Note that @frame_pointer is used only for sanity check later. | |
| 249 | 247 | */ |
| 250 | 248 | void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, |
| 251 | 249 | unsigned long frame_pointer) |
| @@ -263,8 +261,10 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, · 11 unmodified lines | ||
| 263 | 261 | */ |
| 264 | 262 | old = *parent; |
| 265 | 263 | |
| 266 | − if (!function_graph_enter(old, self_addr, frame_pointer, NULL)) | |
| 264 | + if (!function_graph_enter(old, self_addr, frame_pointer, | |
| 265 | + (void *)frame_pointer)) { | |
| 267 | 266 | *parent = return_hooker; |
| 267 | + } | |
| 268 | 268 | } |
| 269 | 269 | |
| 270 | 270 | #ifdef CONFIG_DYNAMIC_FTRACE |
| @@ -147,7 +147,7 @@ int machine_kexec_post_load(struct kimage *kimage) · 146 unmodified lines | ||
| 147 | 147 | if (rc) |
| 148 | 148 | return rc; |
| 149 | 149 | kimage->arch.ttbr1 = __pa(trans_pgd); |
| 150 | − kimage->arch.zero_page = __pa(empty_zero_page); | |
| 150 | + kimage->arch.zero_page = __pa_symbol(empty_zero_page); | |
| 151 | 151 | |
| 152 | 152 | reloc_size = __relocate_new_kernel_end - __relocate_new_kernel_start; |
| 153 | 153 | memcpy(reloc_code, __relocate_new_kernel_start, reloc_size); |
| @@ -38,9 +38,6 @@ void start_backtrace(struct stackframe *frame, unsigned long fp, · 37 unmodified lines | ||
| 38 | 38 | { |
| 39 | 39 | frame->fp = fp; |
| 40 | 40 | frame->pc = pc; |
| 41 | −#ifdef CONFIG_FUNCTION_GRAPH_TRACER | |
| 42 | − frame->graph = 0; | |
| 43 | −#endif | |
| 44 | 41 | #ifdef CONFIG_KRETPROBES |
| 45 | 42 | frame->kr_cur = NULL; |
| 46 | 43 | #endif |
| @@ -116,20 +113,23 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) · 69 unmodified lines | ||
| 116 | 113 | frame->prev_fp = fp; |
| 117 | 114 | frame->prev_type = info.type; |
| 118 | 115 | |
| 116 | + frame->pc = ptrauth_strip_insn_pac(frame->pc); | |
| 117 | + | |
| 119 | 118 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 120 | 119 | if (tsk->ret_stack && |
| 121 | − (ptrauth_strip_insn_pac(frame->pc) == (unsigned long)return_to_handler)) { | |
| 122 | − struct ftrace_ret_stack *ret_stack; | |
| 120 | + (frame->pc == (unsigned long)return_to_handler)) { | |
| 121 | + unsigned long orig_pc; | |
| 123 | 122 | /* |
| 124 | 123 | * This is a case where function graph tracer has |
| 125 | 124 | * modified a return address (LR) in a stack frame |
| 126 | 125 | * to hook a function return. |
| 127 | 126 | * So replace it to an original value. |
| 128 | 127 | */ |
| 129 | − ret_stack = ftrace_graph_get_ret_stack(tsk, frame->graph++); | |
| 130 | − if (WARN_ON_ONCE(!ret_stack)) | |
| 128 | + orig_pc = ftrace_graph_ret_addr(tsk, NULL, frame->pc, | |
| 129 | + (void *)frame->fp); | |
| 130 | + if (WARN_ON_ONCE(frame->pc == orig_pc)) | |
| 131 | 131 | return -EINVAL; |
| 132 | − frame->pc = ret_stack->ret; | |
| 132 | + frame->pc = orig_pc; | |
| 133 | 133 | } |
| 134 | 134 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
| 135 | 135 | #ifdef CONFIG_KRETPROBES |
| @@ -137,8 +137,6 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) · 1 unmodified line | ||
| 137 | 137 | frame->pc = kretprobe_find_ret_addr(tsk, (void *)frame->fp, &frame->kr_cur); |
| 138 | 138 | #endif |
| 139 | 139 | |
| 140 | − frame->pc = ptrauth_strip_insn_pac(frame->pc); | |
| 141 | − | |
| 142 | 140 | return 0; |
| 143 | 141 | } |
| 144 | 142 | NOKPROBE_SYMBOL(unwind_frame); |
| @@ -223,7 +223,14 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 222 unmodified lines | ||
| 223 | 223 | r = 1; |
| 224 | 224 | break; |
| 225 | 225 | case KVM_CAP_NR_VCPUS: |
| 226 | − r = num_online_cpus(); | |
| 226 | + /* | |
| 227 | + * ARM64 treats KVM_CAP_NR_CPUS differently from all other | |
| 228 | + * architectures, as it does not always bound it to | |
| 229 | + * KVM_CAP_MAX_VCPUS. It should not matter much because | |
| 230 | + * this is just an advisory value. | |
| 231 | + */ | |
| 232 | + r = min_t(unsigned int, num_online_cpus(), | |
| 233 | + kvm_arm_default_max_vcpus()); | |
| 227 | 234 | break; |
| 228 | 235 | case KVM_CAP_MAX_VCPUS: |
| 229 | 236 | case KVM_CAP_MAX_VCPU_ID: |
| @@ -403,6 +403,8 @@ typedef bool (*exit_handler_fn)(struct kvm_vcpu *, u64 *); · 402 unmodified lines | ||
| 403 | 403 | |
| 404 | 404 | static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu); |
| 405 | 405 | |
| 406 | +static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code); | |
| 407 | + | |
| 406 | 408 | /* |
| 407 | 409 | * Allow the hypervisor to handle the exit with an exit handler if it has one. |
| 408 | 410 | * |
| @@ -429,6 +431,18 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code) · 20 unmodified lines | ||
| 429 | 431 | */ |
| 430 | 432 | static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) |
| 431 | 433 | { |
| 434 | + /* | |
| 435 | + * Save PSTATE early so that we can evaluate the vcpu mode | |
| 436 | + * early on. | |
| 437 | + */ | |
| 438 | + vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR); | |
| 439 | + | |
| 440 | + /* | |
| 441 | + * Check whether we want to repaint the state one way or | |
| 442 | + * another. | |
| 443 | + */ | |
| 444 | + early_exit_filter(vcpu, exit_code); | |
| 445 | + | |
| 432 | 446 | if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) |
| 433 | 447 | vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR); |
| 434 | 448 | |
| @@ -70,7 +70,12 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) · 69 unmodified lines | ||
| 70 | 70 | static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt) |
| 71 | 71 | { |
| 72 | 72 | ctxt->regs.pc = read_sysreg_el2(SYS_ELR); |
| 73 | − ctxt->regs.pstate = read_sysreg_el2(SYS_SPSR); | |
| 73 | + /* | |
| 74 | + * Guest PSTATE gets saved at guest fixup time in all | |
| 75 | + * cases. We still need to handle the nVHE host side here. | |
| 76 | + */ | |
| 77 | + if (!has_vhe() && ctxt->__hyp_running_vcpu) | |
| 78 | + ctxt->regs.pstate = read_sysreg_el2(SYS_SPSR); | |
| 74 | 79 | |
| 75 | 80 | if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) |
| 76 | 81 | ctxt_sys_reg(ctxt, DISR_EL1) = read_sysreg_s(SYS_VDISR_EL2); |
| @@ -233,7 +233,7 @@ static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu) · 232 unmodified lines | ||
| 233 | 233 | * Returns false if the guest ran in AArch32 when it shouldn't have, and |
| 234 | 234 | * thus should exit to the host, or true if a the guest run loop can continue. |
| 235 | 235 | */ |
| 236 | −static bool handle_aarch32_guest(struct kvm_vcpu *vcpu, u64 *exit_code) | |
| 236 | +static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code) | |
| 237 | 237 | { |
| 238 | 238 | struct kvm *kvm = kern_hyp_va(vcpu->kvm); |
| 239 | 239 | |
| @@ -248,10 +248,7 @@ static bool handle_aarch32_guest(struct kvm_vcpu *vcpu, u64 *exit_code) · 8 unmodified lines | ||
| 248 | 248 | vcpu->arch.target = -1; |
| 249 | 249 | *exit_code &= BIT(ARM_EXIT_WITH_SERROR_BIT); |
| 250 | 250 | *exit_code |= ARM_EXCEPTION_IL; |
| 251 | − return false; | |
| 252 | 251 | } |
| 253 | − | |
| 254 | − return true; | |
| 255 | 252 | } |
| 256 | 253 | |
| 257 | 254 | /* Switch to the guest for legacy non-VHE systems */ |
| @@ -316,9 +313,6 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) · 58 unmodified lines | ||
| 316 | 313 | /* Jump in the fire! */ |
| 317 | 314 | exit_code = __guest_enter(vcpu); |
| 318 | 315 | |
| 319 | − if (unlikely(!handle_aarch32_guest(vcpu, &exit_code))) | |
| 320 | − break; | |
| 321 | − | |
| 322 | 316 | /* And we're baaack! */ |
| 323 | 317 | } while (fixup_guest_exit(vcpu, &exit_code)); |
| 324 | 318 | |
| @@ -112,6 +112,10 @@ static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu) · 111 unmodified lines | ||
| 112 | 112 | return hyp_exit_handlers; |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | +static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code) | |
| 116 | +{ | |
| 117 | +} | |
| 118 | + | |
| 115 | 119 | /* Switch to the guest for VHE systems running in EL2 */ |
| 116 | 120 | static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) |
| 117 | 121 | { |
| @@ -209,7 +209,7 @@ asmlinkage void do_trap_illinsn(struct pt_regs *regs) · 208 unmodified lines | ||
| 209 | 209 | |
| 210 | 210 | asmlinkage void do_trap_fpe(struct pt_regs *regs) |
| 211 | 211 | { |
| 212 | −#ifdef CONFIG_CPU_HAS_FP | |
| 212 | +#ifdef CONFIG_CPU_HAS_FPU | |
| 213 | 213 | return fpu_fpe(regs); |
| 214 | 214 | #else |
| 215 | 215 | do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->pc, |
| @@ -219,7 +219,7 @@ asmlinkage void do_trap_fpe(struct pt_regs *regs) · 3 unmodified lines | ||
| 219 | 219 | |
| 220 | 220 | asmlinkage void do_trap_priv(struct pt_regs *regs) |
| 221 | 221 | { |
| 222 | −#ifdef CONFIG_CPU_HAS_FP | |
| 222 | +#ifdef CONFIG_CPU_HAS_FPU | |
| 223 | 223 | if (user_mode(regs) && fpu_libc_helper(regs)) |
| 224 | 224 | return; |
| 225 | 225 | #endif |
| @@ -1,26 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | −/* | |
| 3 | − * Timer support for Hexagon | |
| 4 | − * | |
| 5 | − * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | |
| 6 | − */ | |
| 7 | − | |
| 8 | −#ifndef _ASM_TIMER_REGS_H | |
| 9 | −#define _ASM_TIMER_REGS_H | |
| 10 | − | |
| 11 | −/* This stuff should go into a platform specific file */ | |
| 12 | −#define TCX0_CLK_RATE 19200 | |
| 13 | −#define TIMER_ENABLE 0 | |
| 14 | −#define TIMER_CLR_ON_MATCH 1 | |
| 15 | − | |
| 16 | −/* | |
| 17 | − * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until | |
| 18 | − * release 1.1, and then it's "adjustable" and probably not defaulted. | |
| 19 | − */ | |
| 20 | −#define RTOS_TIMER_INT 3 | |
| 21 | −#ifdef CONFIG_HEXAGON_COMET | |
| 22 | −#define RTOS_TIMER_REGS_ADDR 0xAB000000UL | |
| 23 | −#endif | |
| 24 | −#define SLEEP_CLK_RATE 32000 | |
| 25 | − | |
| 26 | −#endif | |
| @@ -7,11 +7,10 @@ · 6 unmodified lines | ||
| 7 | 7 | #define _ASM_TIMEX_H |
| 8 | 8 | |
| 9 | 9 | #include <asm-generic/timex.h> |
| 10 | −#include <asm/timer-regs.h> | |
| 11 | 10 | #include <asm/hexagon_vm.h> |
| 12 | 11 | |
| 13 | 12 | /* Using TCX0 as our clock. CLOCK_TICK_RATE scheduled to be removed. */ |
| 14 | −#define CLOCK_TICK_RATE TCX0_CLK_RATE | |
| 13 | +#define CLOCK_TICK_RATE 19200 | |
| 15 | 14 | |
| 16 | 15 | #define ARCH_HAS_READ_CURRENT_TIMER |
| 17 | 16 | |
| @@ -0,0 +1 @@ | ||
| 1 | +vmlinux.lds | |
| @@ -17,9 +17,10 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/of_irq.h> |
| 18 | 18 | #include <linux/module.h> |
| 19 | 19 | |
| 20 | −#include <asm/timer-regs.h> | |
| 21 | 20 | #include <asm/hexagon_vm.h> |
| 22 | 21 | |
| 22 | +#define TIMER_ENABLE BIT(0) | |
| 23 | + | |
| 23 | 24 | /* |
| 24 | 25 | * For the clocksource we need: |
| 25 | 26 | * pcycle frequency (600MHz) |
| @@ -33,6 +34,13 @@ cycles_t pcycle_freq_mhz; · 7 unmodified lines | ||
| 33 | 34 | cycles_t thread_freq_mhz; |
| 34 | 35 | cycles_t sleep_clk_freq; |
| 35 | 36 | |
| 37 | +/* | |
| 38 | + * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until | |
| 39 | + * release 1.1, and then it's "adjustable" and probably not defaulted. | |
| 40 | + */ | |
| 41 | +#define RTOS_TIMER_INT 3 | |
| 42 | +#define RTOS_TIMER_REGS_ADDR 0xAB000000UL | |
| 43 | + | |
| 36 | 44 | static struct resource rtos_timer_resources[] = { |
| 37 | 45 | { |
| 38 | 46 | .start = RTOS_TIMER_REGS_ADDR, |
| @@ -80,7 +88,7 @@ static int set_next_event(unsigned long delta, struct clock_event_device *evt) · 41 unmodified lines | ||
| 80 | 88 | iowrite32(0, &rtos_timer->clear); |
| 81 | 89 | |
| 82 | 90 | iowrite32(delta, &rtos_timer->match); |
| 83 | − iowrite32(1 << TIMER_ENABLE, &rtos_timer->enable); | |
| 91 | + iowrite32(TIMER_ENABLE, &rtos_timer->enable); | |
| 84 | 92 | return 0; |
| 85 | 93 | } |
| 86 | 94 | |
| @@ -27,6 +27,7 @@ void __raw_readsw(const void __iomem *addr, void *data, int len) · 26 unmodified lines | ||
| 27 | 27 | *dst++ = *src; |
| 28 | 28 | |
| 29 | 29 | } |
| 30 | +EXPORT_SYMBOL(__raw_readsw); | |
| 30 | 31 | |
| 31 | 32 | /* |
| 32 | 33 | * __raw_writesw - read words a short at a time |
| @@ -47,6 +48,7 @@ void __raw_writesw(void __iomem *addr, const void *data, int len) · 14 unmodified lines | ||
| 47 | 48 | |
| 48 | 49 | |
| 49 | 50 | } |
| 51 | +EXPORT_SYMBOL(__raw_writesw); | |
| 50 | 52 | |
| 51 | 53 | /* Pretty sure len is pre-adjusted for the length of the access already */ |
| 52 | 54 | void __raw_readsl(const void __iomem *addr, void *data, int len) |
| @@ -62,6 +64,7 @@ void __raw_readsl(const void __iomem *addr, void *data, int len) · 9 unmodified lines | ||
| 62 | 64 | |
| 63 | 65 | |
| 64 | 66 | } |
| 67 | +EXPORT_SYMBOL(__raw_readsl); | |
| 65 | 68 | |
| 66 | 69 | void __raw_writesl(void __iomem *addr, const void *data, int len) |
| 67 | 70 | { |
| @@ -76,3 +79,4 @@ void __raw_writesl(void __iomem *addr, const void *data, int len) · 8 unmodified lines | ||
| 76 | 79 | |
| 77 | 80 | |
| 78 | 81 | } |
| 82 | +EXPORT_SYMBOL(__raw_writesl); | |
| @@ -369,3 +369,4 @@ · 368 unmodified lines | ||
| 369 | 369 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 370 | 370 | # 447 reserved for memfd_secret |
| 371 | 371 | 448 common process_mrelease sys_process_mrelease |
| 372 | +449 common futex_waitv sys_futex_waitv | |
| @@ -250,7 +250,6 @@ static inline void __flush_page_to_ram(void *vaddr) · 249 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 252 | 252 | #define flush_dcache_page(page) __flush_page_to_ram(page_address(page)) |
| 253 | −void flush_dcache_folio(struct folio *folio); | |
| 254 | 253 | #define flush_dcache_mmap_lock(mapping) do { } while (0) |
| 255 | 254 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) |
| 256 | 255 | #define flush_icache_page(vma, page) __flush_page_to_ram(page_address(page)) |
| @@ -448,3 +448,4 @@ · 447 unmodified lines | ||
| 448 | 448 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 449 | 449 | # 447 reserved for memfd_secret |
| 450 | 450 | 448 common process_mrelease sys_process_mrelease |
| 451 | +449 common futex_waitv sys_futex_waitv | |
| @@ -1145,7 +1145,7 @@ asmlinkage void set_esp0(unsigned long ssp) · 1144 unmodified lines | ||
| 1145 | 1145 | */ |
| 1146 | 1146 | asmlinkage void fpsp040_die(void) |
| 1147 | 1147 | { |
| 1148 | − force_fatal_sig(SIGSEGV); | |
| 1148 | + force_exit_sig(SIGSEGV); | |
| 1149 | 1149 | } |
| 1150 | 1150 | |
| 1151 | 1151 | #ifdef CONFIG_M68KFPU_EMU |
| @@ -454,3 +454,4 @@ · 453 unmodified lines | ||
| 454 | 454 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 455 | 455 | # 447 reserved for memfd_secret |
| 456 | 456 | 448 common process_mrelease sys_process_mrelease |
| 457 | +449 common futex_waitv sys_futex_waitv | |
| @@ -3097,7 +3097,7 @@ config STACKTRACE_SUPPORT · 3096 unmodified lines | ||
| 3097 | 3097 | config PGTABLE_LEVELS |
| 3098 | 3098 | int |
| 3099 | 3099 | default 4 if PAGE_SIZE_4KB && MIPS_VA_BITS_48 |
| 3100 | − default 3 if 64BIT && !PAGE_SIZE_64KB | |
| 3100 | + default 3 if 64BIT && (!PAGE_SIZE_64KB || MIPS_VA_BITS_48) | |
| 3101 | 3101 | default 2 |
| 3102 | 3102 | |
| 3103 | 3103 | config MIPS_AUTO_PFN_OFFSET |
| @@ -381,6 +381,12 @@ void clk_disable(struct clk *clk) · 380 unmodified lines | ||
| 381 | 381 | |
| 382 | 382 | EXPORT_SYMBOL(clk_disable); |
| 383 | 383 | |
| 384 | +struct clk *clk_get_parent(struct clk *clk) | |
| 385 | +{ | |
| 386 | + return NULL; | |
| 387 | +} | |
| 388 | +EXPORT_SYMBOL(clk_get_parent); | |
| 389 | + | |
| 384 | 390 | unsigned long clk_get_rate(struct clk *clk) |
| 385 | 391 | { |
| 386 | 392 | if (!clk) |
| @@ -52,7 +52,7 @@ endif · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o |
| 54 | 54 | |
| 55 | −vmlinuzobjs-$(CONFIG_KERNEL_ZSTD) += $(obj)/bswapdi.o | |
| 55 | +vmlinuzobjs-$(CONFIG_KERNEL_ZSTD) += $(obj)/bswapdi.o $(obj)/ashldi3.o | |
| 56 | 56 | |
| 57 | 57 | targets := $(notdir $(vmlinuzobjs-y)) |
| 58 | 58 | |
| @@ -75,7 +75,7 @@ static unsigned int __init gen_fdt_mem_array( · 74 unmodified lines | ||
| 75 | 75 | __init int yamon_dt_append_memory(void *fdt, |
| 76 | 76 | const struct yamon_mem_region *regions) |
| 77 | 77 | { |
| 78 | − unsigned long phys_memsize, memsize; | |
| 78 | + unsigned long phys_memsize = 0, memsize; | |
| 79 | 79 | __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES]; |
| 80 | 80 | unsigned int mem_entries; |
| 81 | 81 | int i, err, mem_off; |
| @@ -61,8 +61,6 @@ static inline void flush_dcache_page(struct page *page) · 60 unmodified lines | ||
| 61 | 61 | SetPageDcacheDirty(page); |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | −void flush_dcache_folio(struct folio *folio); | |
| 65 | − | |
| 66 | 64 | #define flush_dcache_mmap_lock(mapping) do { } while (0) |
| 67 | 65 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) |
| 68 | 66 | |
| @@ -1734,8 +1734,6 @@ static inline void decode_cpucfg(struct cpuinfo_mips *c) · 1733 unmodified lines | ||
| 1734 | 1734 | |
| 1735 | 1735 | static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) |
| 1736 | 1736 | { |
| 1737 | − decode_configs(c); | |
| 1738 | − | |
| 1739 | 1737 | /* All Loongson processors covered here define ExcCode 16 as GSExc. */ |
| 1740 | 1738 | c->options |= MIPS_CPU_GSEXCEX; |
| 1741 | 1739 | |
| @@ -1796,6 +1794,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) · 54 unmodified lines | ||
| 1796 | 1794 | panic("Unknown Loongson Processor ID!"); |
| 1797 | 1795 | break; |
| 1798 | 1796 | } |
| 1797 | + | |
| 1798 | + decode_configs(c); | |
| 1799 | 1799 | } |
| 1800 | 1800 | #else |
| 1801 | 1801 | static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) { } |
| @@ -185,7 +185,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) · 184 unmodified lines | ||
| 185 | 185 | seq_puts(m, " tx39_cache"); |
| 186 | 186 | if (cpu_has_octeon_cache) |
| 187 | 187 | seq_puts(m, " octeon_cache"); |
| 188 | − if (cpu_has_fpu) | |
| 188 | + if (raw_cpu_has_fpu) | |
| 189 | 189 | seq_puts(m, " fpu"); |
| 190 | 190 | if (cpu_has_32fpr) |
| 191 | 191 | seq_puts(m, " 32fpr"); |
| @@ -387,3 +387,4 @@ · 386 unmodified lines | ||
| 387 | 387 | 446 n32 landlock_restrict_self sys_landlock_restrict_self |
| 388 | 388 | # 447 reserved for memfd_secret |
| 389 | 389 | 448 n32 process_mrelease sys_process_mrelease |
| 390 | +449 n32 futex_waitv sys_futex_waitv | |
| @@ -363,3 +363,4 @@ · 362 unmodified lines | ||
| 363 | 363 | 446 n64 landlock_restrict_self sys_landlock_restrict_self |
| 364 | 364 | # 447 reserved for memfd_secret |
| 365 | 365 | 448 n64 process_mrelease sys_process_mrelease |
| 366 | +449 n64 futex_waitv sys_futex_waitv | |
| @@ -436,3 +436,4 @@ · 435 unmodified lines | ||
| 436 | 436 | 446 o32 landlock_restrict_self sys_landlock_restrict_self |
| 437 | 437 | # 447 reserved for memfd_secret |
| 438 | 438 | 448 o32 process_mrelease sys_process_mrelease |
| 439 | +449 o32 futex_waitv sys_futex_waitv | |
| @@ -1067,7 +1067,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 1066 unmodified lines | ||
| 1067 | 1067 | r = 1; |
| 1068 | 1068 | break; |
| 1069 | 1069 | case KVM_CAP_NR_VCPUS: |
| 1070 | − r = num_online_cpus(); | |
| 1070 | + r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS); | |
| 1071 | 1071 | break; |
| 1072 | 1072 | case KVM_CAP_MAX_VCPUS: |
| 1073 | 1073 | r = KVM_MAX_VCPUS; |
| @@ -158,6 +158,12 @@ void clk_deactivate(struct clk *clk) · 157 unmodified lines | ||
| 158 | 158 | } |
| 159 | 159 | EXPORT_SYMBOL(clk_deactivate); |
| 160 | 160 | |
| 161 | +struct clk *clk_get_parent(struct clk *clk) | |
| 162 | +{ | |
| 163 | + return NULL; | |
| 164 | +} | |
| 165 | +EXPORT_SYMBOL(clk_get_parent); | |
| 166 | + | |
| 161 | 167 | static inline u32 get_counter_resolution(void) |
| 162 | 168 | { |
| 163 | 169 | u32 res; |
| @@ -98,7 +98,7 @@ do { \ · 97 unmodified lines | ||
| 98 | 98 | #define emit(...) __emit(__VA_ARGS__) |
| 99 | 99 | |
| 100 | 100 | /* Workaround for R10000 ll/sc errata */ |
| 101 | −#ifdef CONFIG_WAR_R10000 | |
| 101 | +#ifdef CONFIG_WAR_R10000_LLSC | |
| 102 | 102 | #define LLSC_beqz beqzl |
| 103 | 103 | #else |
| 104 | 104 | #define LLSC_beqz beqz |
| @@ -27,7 +27,6 @@ void flush_cache_vunmap(unsigned long start, unsigned long end); · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 29 | 29 | void flush_dcache_page(struct page *page); |
| 30 | −void flush_dcache_folio(struct folio *folio); | |
| 31 | 30 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
| 32 | 31 | unsigned long vaddr, void *dst, void *src, int len); |
| 33 | 32 | void copy_from_user_page(struct vm_area_struct *vma, struct page *page, |
| @@ -29,7 +29,6 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, · 28 unmodified lines | ||
| 29 | 29 | unsigned long pfn); |
| 30 | 30 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 31 | 31 | void flush_dcache_page(struct page *page); |
| 32 | −void flush_dcache_folio(struct folio *folio); | |
| 33 | 32 | |
| 34 | 33 | extern void flush_icache_range(unsigned long start, unsigned long end); |
| 35 | 34 | extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); |
| @@ -15,7 +15,12 @@ · 14 unmodified lines | ||
| 15 | 15 | # Mike Shaver, Helge Deller and Martin K. Petersen |
| 16 | 16 | # |
| 17 | 17 | |
| 18 | +ifdef CONFIG_PARISC_SELF_EXTRACT | |
| 19 | +boot := arch/parisc/boot | |
| 20 | +KBUILD_IMAGE := $(boot)/bzImage | |
| 21 | +else | |
| 18 | 22 | KBUILD_IMAGE := vmlinuz |
| 23 | +endif | |
| 19 | 24 | |
| 20 | 25 | NM = sh $(srctree)/arch/parisc/nm |
| 21 | 26 | CHECKFLAGS += -D__hppa__=1 |
| @@ -231,6 +231,7 @@ CONFIG_CRYPTO_DEFLATE=y · 230 unmodified lines | ||
| 231 | 231 | CONFIG_CRC_CCITT=m |
| 232 | 232 | CONFIG_CRC_T10DIF=y |
| 233 | 233 | CONFIG_FONTS=y |
| 234 | +CONFIG_PRINTK_TIME=y | |
| 234 | 235 | CONFIG_MAGIC_SYSRQ=y |
| 235 | 236 | CONFIG_DEBUG_FS=y |
| 236 | 237 | CONFIG_DEBUG_MEMORY_INIT=y |
| @@ -1,7 +1,9 @@ | ||
| 1 | 1 | CONFIG_LOCALVERSION="-64bit" |
| 2 | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
| 3 | +CONFIG_KERNEL_LZ4=y | |
| 3 | 4 | CONFIG_SYSVIPC=y |
| 4 | 5 | CONFIG_POSIX_MQUEUE=y |
| 6 | +CONFIG_AUDIT=y | |
| 5 | 7 | CONFIG_BSD_PROCESS_ACCT=y |
| 6 | 8 | CONFIG_BSD_PROCESS_ACCT_V3=y |
| 7 | 9 | CONFIG_TASKSTATS=y |
| @@ -35,6 +37,7 @@ CONFIG_MODVERSIONS=y · 27 unmodified lines | ||
| 35 | 37 | CONFIG_BLK_DEV_INTEGRITY=y |
| 36 | 38 | CONFIG_BINFMT_MISC=m |
| 37 | 39 | # CONFIG_COMPACTION is not set |
| 40 | +CONFIG_MEMORY_FAILURE=y | |
| 38 | 41 | CONFIG_NET=y |
| 39 | 42 | CONFIG_PACKET=y |
| 40 | 43 | CONFIG_UNIX=y |
| @@ -65,12 +68,15 @@ CONFIG_SCSI_ISCSI_ATTRS=y · 24 unmodified lines | ||
| 65 | 68 | CONFIG_SCSI_SRP_ATTRS=y |
| 66 | 69 | CONFIG_ISCSI_BOOT_SYSFS=y |
| 67 | 70 | CONFIG_SCSI_MPT2SAS=y |
| 68 | −CONFIG_SCSI_LASI700=m | |
| 71 | +CONFIG_SCSI_LASI700=y | |
| 69 | 72 | CONFIG_SCSI_SYM53C8XX_2=y |
| 70 | 73 | CONFIG_SCSI_ZALON=y |
| 71 | 74 | CONFIG_SCSI_QLA_ISCSI=m |
| 72 | 75 | CONFIG_SCSI_DH=y |
| 73 | 76 | CONFIG_ATA=y |
| 77 | +CONFIG_SATA_SIL=y | |
| 78 | +CONFIG_SATA_SIS=y | |
| 79 | +CONFIG_SATA_VIA=y | |
| 74 | 80 | CONFIG_PATA_NS87415=y |
| 75 | 81 | CONFIG_PATA_SIL680=y |
| 76 | 82 | CONFIG_ATA_GENERIC=y |
| @@ -79,6 +85,7 @@ CONFIG_MD_LINEAR=m · 2 unmodified lines | ||
| 79 | 85 | CONFIG_BLK_DEV_DM=m |
| 80 | 86 | CONFIG_DM_RAID=m |
| 81 | 87 | CONFIG_DM_UEVENT=y |
| 88 | +CONFIG_DM_AUDIT=y | |
| 82 | 89 | CONFIG_FUSION=y |
| 83 | 90 | CONFIG_FUSION_SPI=y |
| 84 | 91 | CONFIG_FUSION_SAS=y |
| @@ -196,10 +203,15 @@ CONFIG_FB_MATROX_G=y · 111 unmodified lines | ||
| 196 | 203 | CONFIG_FB_MATROX_I2C=y |
| 197 | 204 | CONFIG_FB_MATROX_MAVEN=y |
| 198 | 205 | CONFIG_FB_RADEON=y |
| 206 | +CONFIG_LOGO=y | |
| 207 | +# CONFIG_LOGO_LINUX_CLUT224 is not set | |
| 199 | 208 | CONFIG_HIDRAW=y |
| 200 | 209 | CONFIG_HID_PID=y |
| 201 | 210 | CONFIG_USB_HIDDEV=y |
| 202 | 211 | CONFIG_USB=y |
| 212 | +CONFIG_USB_EHCI_HCD=y | |
| 213 | +CONFIG_USB_OHCI_HCD=y | |
| 214 | +CONFIG_USB_OHCI_HCD_PLATFORM=y | |
| 203 | 215 | CONFIG_UIO=y |
| 204 | 216 | CONFIG_UIO_PDRV_GENIRQ=m |
| 205 | 217 | CONFIG_UIO_AEC=m |
| @@ -3,38 +3,19 @@ · 2 unmodified lines | ||
| 3 | 3 | * Copyright (C) 1999 Hewlett-Packard (Frank Rowand) |
| 4 | 4 | * Copyright (C) 1999 Philipp Rumpf <prumpf@tux.org> |
| 5 | 5 | * Copyright (C) 1999 SuSE GmbH |
| 6 | + * Copyright (C) 2021 Helge Deller <deller@gmx.de> | |
| 6 | 7 | */ |
| 7 | 8 | |
| 8 | 9 | #ifndef _PARISC_ASSEMBLY_H |
| 9 | 10 | #define _PARISC_ASSEMBLY_H |
| 10 | 11 | |
| 11 | −#define CALLEE_FLOAT_FRAME_SIZE 80 | |
| 12 | − | |
| 13 | 12 | #ifdef CONFIG_64BIT |
| 14 | −#define LDREG ldd | |
| 15 | −#define STREG std | |
| 16 | −#define LDREGX ldd,s | |
| 17 | −#define LDREGM ldd,mb | |
| 18 | −#define STREGM std,ma | |
| 19 | −#define SHRREG shrd | |
| 20 | −#define SHLREG shld | |
| 21 | −#define ANDCM andcm,* | |
| 22 | −#define COND(x) * ## x | |
| 23 | 13 | #define RP_OFFSET 16 |
| 24 | 14 | #define FRAME_SIZE 128 |
| 25 | 15 | #define CALLEE_REG_FRAME_SIZE 144 |
| 26 | 16 | #define REG_SZ 8 |
| 27 | 17 | #define ASM_ULONG_INSN .dword |
| 28 | 18 | #else /* CONFIG_64BIT */ |
| 29 | −#define LDREG ldw | |
| 30 | −#define STREG stw | |
| 31 | −#define LDREGX ldwx,s | |
| 32 | −#define LDREGM ldwm | |
| 33 | −#define STREGM stwm | |
| 34 | −#define SHRREG shr | |
| 35 | −#define SHLREG shlw | |
| 36 | −#define ANDCM andcm | |
| 37 | −#define COND(x) x | |
| 38 | 19 | #define RP_OFFSET 20 |
| 39 | 20 | #define FRAME_SIZE 64 |
| 40 | 21 | #define CALLEE_REG_FRAME_SIZE 128 |
| @@ -45,6 +26,7 @@ · 4 unmodified lines | ||
| 45 | 26 | /* Frame alignment for 32- and 64-bit */ |
| 46 | 27 | #define FRAME_ALIGN 64 |
| 47 | 28 | |
| 29 | +#define CALLEE_FLOAT_FRAME_SIZE 80 | |
| 48 | 30 | #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) |
| 49 | 31 | |
| 50 | 32 | #ifdef CONFIG_PA20 |
| @@ -67,6 +49,28 @@ · 16 unmodified lines | ||
| 67 | 49 | |
| 68 | 50 | #ifdef __ASSEMBLY__ |
| 69 | 51 | |
| 52 | +#ifdef CONFIG_64BIT | |
| 53 | +#define LDREG ldd | |
| 54 | +#define STREG std | |
| 55 | +#define LDREGX ldd,s | |
| 56 | +#define LDREGM ldd,mb | |
| 57 | +#define STREGM std,ma | |
| 58 | +#define SHRREG shrd | |
| 59 | +#define SHLREG shld | |
| 60 | +#define ANDCM andcm,* | |
| 61 | +#define COND(x) * ## x | |
| 62 | +#else /* CONFIG_64BIT */ | |
| 63 | +#define LDREG ldw | |
| 64 | +#define STREG stw | |
| 65 | +#define LDREGX ldwx,s | |
| 66 | +#define LDREGM ldwm | |
| 67 | +#define STREGM stwm | |
| 68 | +#define SHRREG shr | |
| 69 | +#define SHLREG shlw | |
| 70 | +#define ANDCM andcm | |
| 71 | +#define COND(x) x | |
| 72 | +#endif | |
| 73 | + | |
| 70 | 74 | #ifdef CONFIG_64BIT |
| 71 | 75 | /* the 64-bit pa gnu assembler unfortunately defaults to .level 1.1 or 2.0 so |
| 72 | 76 | * work around that for now... */ |
| @@ -143,6 +147,17 @@ · 70 unmodified lines | ||
| 143 | 147 | extrd,u \r, 63-(\sa), 64-(\sa), \t |
| 144 | 148 | .endm |
| 145 | 149 | |
| 150 | + /* Extract unsigned for 32- and 64-bit | |
| 151 | + * The extru instruction leaves the most significant 32 bits of the | |
| 152 | + * target register in an undefined state on PA 2.0 systems. */ | |
| 153 | + .macro extru_safe r, p, len, t | |
| 154 | +#ifdef CONFIG_64BIT | |
| 155 | + extrd,u \r, 32+(\p), \len, \t | |
| 156 | +#else | |
| 157 | + extru \r, \p, \len, \t | |
| 158 | +#endif | |
| 159 | + .endm | |
| 160 | + | |
| 146 | 161 | /* load 32-bit 'value' into 'reg' compensating for the ldil |
| 147 | 162 | * sign-extension when running in wide mode. |
| 148 | 163 | * WARNING!! neither 'value' nor 'reg' can be expressions |
| @@ -50,7 +50,6 @@ void invalidate_kernel_vmap_range(void *vaddr, int size); · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 52 | 52 | void flush_dcache_page(struct page *page); |
| 53 | −void flush_dcache_folio(struct folio *folio); | |
| 54 | 53 | |
| 55 | 54 | #define flush_dcache_mmap_lock(mapping) xa_lock_irq(&mapping->i_pages) |
| 56 | 55 | #define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&mapping->i_pages) |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #ifndef __ASSEMBLY__ |
| 6 | 6 | |
| 7 | 7 | #include <linux/types.h> |
| 8 | +#include <linux/stringify.h> | |
| 8 | 9 | #include <asm/assembly.h> |
| 9 | 10 | |
| 10 | 11 | #define JUMP_LABEL_NOP_SIZE 4 |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _ASM_PARISC_RT_SIGFRAME_H |
| 3 | 3 | #define _ASM_PARISC_RT_SIGFRAME_H |
| 4 | 4 | |
| 5 | −#define SIGRETURN_TRAMP 3 | |
| 5 | +#define SIGRETURN_TRAMP 4 | |
| 6 | 6 | #define SIGRESTARTBLOCK_TRAMP 5 |
| 7 | 7 | #define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP) |
| 8 | 8 | |
| @@ -39,6 +39,7 @@ verify "$3" · 38 unmodified lines | ||
| 39 | 39 | if [ -n "${INSTALLKERNEL}" ]; then |
| 40 | 40 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
| 41 | 41 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
| 42 | + if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi | |
| 42 | 43 | fi |
| 43 | 44 | |
| 44 | 45 | # Default install |
| @@ -366,17 +366,9 @@ · 365 unmodified lines | ||
| 366 | 366 | */ |
| 367 | 367 | .macro L2_ptep pmd,pte,index,va,fault |
| 368 | 368 | #if CONFIG_PGTABLE_LEVELS == 3 |
| 369 | − extru \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index | |
| 369 | + extru_safe \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index | |
| 370 | 370 | #else |
| 371 | −# if defined(CONFIG_64BIT) | |
| 372 | − extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index | |
| 373 | − #else | |
| 374 | − # if PAGE_SIZE > 4096 | |
| 375 | − extru \va,31-ASM_PGDIR_SHIFT,32-ASM_PGDIR_SHIFT,\index | |
| 376 | − # else | |
| 377 | − extru \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index | |
| 378 | − # endif | |
| 379 | −# endif | |
| 371 | + extru_safe \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index | |
| 380 | 372 | #endif |
| 381 | 373 | dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */ |
| 382 | 374 | #if CONFIG_PGTABLE_LEVELS < 3 |
| @@ -386,7 +378,7 @@ · 3 unmodified lines | ||
| 386 | 378 | bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault |
| 387 | 379 | dep %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */ |
| 388 | 380 | SHLREG \pmd,PxD_VALUE_SHIFT,\pmd |
| 389 | − extru \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index | |
| 381 | + extru_safe \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index | |
| 390 | 382 | dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */ |
| 391 | 383 | shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */ |
| 392 | 384 | .endm |
| @@ -288,21 +288,22 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, · 287 unmodified lines | ||
| 288 | 288 | already in userspace. The first words of tramp are used to |
| 289 | 289 | save the previous sigrestartblock trampoline that might be |
| 290 | 290 | on the stack. We start the sigreturn trampoline at |
| 291 | − SIGRESTARTBLOCK_TRAMP. */ | |
| 291 | + SIGRESTARTBLOCK_TRAMP+X. */ | |
| 292 | 292 | err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0, |
| 293 | 293 | &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]); |
| 294 | − err |= __put_user(INSN_BLE_SR2_R0, | |
| 294 | + err |= __put_user(INSN_LDI_R20, | |
| 295 | 295 | &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]); |
| 296 | − err |= __put_user(INSN_LDI_R20, | |
| 296 | + err |= __put_user(INSN_BLE_SR2_R0, | |
| 297 | 297 | &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]); |
| 298 | + err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]); | |
| 298 | 299 | |
| 299 | − start = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]; | |
| 300 | − end = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]; | |
| 300 | + start = (unsigned long) &frame->tramp[0]; | |
| 301 | + end = (unsigned long) &frame->tramp[TRAMP_SIZE]; | |
| 301 | 302 | flush_user_dcache_range_asm(start, end); |
| 302 | 303 | flush_user_icache_range_asm(start, end); |
| 303 | 304 | |
| 304 | 305 | /* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP |
| 305 | − * TRAMP Words 5-7, Length 3 = SIGRETURN_TRAMP | |
| 306 | + * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP | |
| 306 | 307 | * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP |
| 307 | 308 | */ |
| 308 | 309 | rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP]; |
| @@ -36,7 +36,7 @@ struct compat_regfile { · 35 unmodified lines | ||
| 36 | 36 | compat_int_t rf_sar; |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | −#define COMPAT_SIGRETURN_TRAMP 3 | |
| 39 | +#define COMPAT_SIGRETURN_TRAMP 4 | |
| 40 | 40 | #define COMPAT_SIGRESTARTBLOCK_TRAMP 5 |
| 41 | 41 | #define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \ |
| 42 | 42 | COMPAT_SIGRESTARTBLOCK_TRAMP) |
| @@ -566,7 +566,7 @@ lws_compare_and_swap: · 565 unmodified lines | ||
| 566 | 566 | ldo R%lws_lock_start(%r20), %r28 |
| 567 | 567 | |
| 568 | 568 | /* Extract eight bits from r26 and hash lock (Bits 3-11) */ |
| 569 | − extru %r26, 28, 8, %r20 | |
| 569 | + extru_safe %r26, 28, 8, %r20 | |
| 570 | 570 | |
| 571 | 571 | /* Find lock to use, the hash is either one of 0 to |
| 572 | 572 | 15, multiplied by 16 (keep it 16-byte aligned) |
| @@ -751,7 +751,7 @@ cas2_lock_start: · 178 unmodified lines | ||
| 751 | 751 | ldo R%lws_lock_start(%r20), %r28 |
| 752 | 752 | |
| 753 | 753 | /* Extract eight bits from r26 and hash lock (Bits 3-11) */ |
| 754 | − extru %r26, 28, 8, %r20 | |
| 754 | + extru_safe %r26, 28, 8, %r20 | |
| 755 | 755 | |
| 756 | 756 | /* Find lock to use, the hash is either one of 0 to |
| 757 | 757 | 15, multiplied by 16 (keep it 16-byte aligned) |
| @@ -446,3 +446,4 @@ · 445 unmodified lines | ||
| 446 | 446 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 447 | 447 | # 447 reserved for memfd_secret |
| 448 | 448 | 448 common process_mrelease sys_process_mrelease |
| 449 | +449 common futex_waitv sys_futex_waitv | |
| @@ -249,30 +249,16 @@ void __init time_init(void) · 248 unmodified lines | ||
| 249 | 249 | static int __init init_cr16_clocksource(void) |
| 250 | 250 | { |
| 251 | 251 | /* |
| 252 | − * The cr16 interval timers are not syncronized across CPUs on | |
| 253 | − * different sockets, so mark them unstable and lower rating on | |
| 254 | − * multi-socket SMP systems. | |
| 252 | + * The cr16 interval timers are not syncronized across CPUs, even if | |
| 253 | + * they share the same socket. | |
| 255 | 254 | */ |
| 256 | 255 | if (num_online_cpus() > 1 && !running_on_qemu) { |
| 257 | − int cpu; | |
| 258 | − unsigned long cpu0_loc; | |
| 259 | − cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; | |
| 260 | − | |
| 261 | − for_each_online_cpu(cpu) { | |
| 262 | − if (cpu == 0) | |
| 263 | − continue; | |
| 264 | − if ((cpu0_loc != 0) && | |
| 265 | − (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)) | |
| 266 | − continue; | |
| 267 | − | |
| 268 | − /* mark sched_clock unstable */ | |
| 269 | − clear_sched_clock_stable(); | |
| 270 | − | |
| 271 | − clocksource_cr16.name = "cr16_unstable"; | |
| 272 | − clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; | |
| 273 | − clocksource_cr16.rating = 0; | |
| 274 | − break; | |
| 275 | − } | |
| 256 | + /* mark sched_clock unstable */ | |
| 257 | + clear_sched_clock_stable(); | |
| 258 | + | |
| 259 | + clocksource_cr16.name = "cr16_unstable"; | |
| 260 | + clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; | |
| 261 | + clocksource_cr16.rating = 0; | |
| 276 | 262 | } |
| 277 | 263 | |
| 278 | 264 | /* register at clocksource framework */ |
| @@ -57,8 +57,6 @@ SECTIONS · 56 unmodified lines | ||
| 57 | 57 | { |
| 58 | 58 | . = KERNEL_BINARY_TEXT_START; |
| 59 | 59 | |
| 60 | − _stext = .; /* start of kernel text, includes init code & data */ | |
| 61 | − | |
| 62 | 60 | __init_begin = .; |
| 63 | 61 | HEAD_TEXT_SECTION |
| 64 | 62 | MLONGCALL_DISCARD(INIT_TEXT_SECTION(8)) |
| @@ -82,6 +80,7 @@ SECTIONS · 17 unmodified lines | ||
| 82 | 80 | /* freed after init ends here */ |
| 83 | 81 | |
| 84 | 82 | _text = .; /* Text and read-only data */ |
| 83 | + _stext = .; | |
| 85 | 84 | MLONGCALL_KEEP(INIT_TEXT_SECTION(8)) |
| 86 | 85 | .text ALIGN(PAGE_SIZE) : { |
| 87 | 86 | TEXT_TEXT |
| @@ -196,3 +196,6 @@ clean-files := vmlinux.lds · 195 unmodified lines | ||
| 196 | 196 | # Force dependency (incbin is bad) |
| 197 | 197 | $(obj)/vdso32_wrapper.o : $(obj)/vdso32/vdso32.so.dbg |
| 198 | 198 | $(obj)/vdso64_wrapper.o : $(obj)/vdso64/vdso64.so.dbg |
| 199 | + | |
| 200 | +# for cleaning | |
| 201 | +subdir- += vdso32 vdso64 | |
| @@ -202,11 +202,11 @@ vmap_stack_overflow: · 201 unmodified lines | ||
| 202 | 202 | mfspr r1, SPRN_SPRG_THREAD |
| 203 | 203 | lwz r1, TASK_CPU - THREAD(r1) |
| 204 | 204 | slwi r1, r1, 3 |
| 205 | − addis r1, r1, emergency_ctx@ha | |
| 205 | + addis r1, r1, emergency_ctx-PAGE_OFFSET@ha | |
| 206 | 206 | #else |
| 207 | − lis r1, emergency_ctx@ha | |
| 207 | + lis r1, emergency_ctx-PAGE_OFFSET@ha | |
| 208 | 208 | #endif |
| 209 | − lwz r1, emergency_ctx@l(r1) | |
| 209 | + lwz r1, emergency_ctx-PAGE_OFFSET@l(r1) | |
| 210 | 210 | addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE |
| 211 | 211 | EXCEPTION_PROLOG_2 0 vmap_stack_overflow |
| 212 | 212 | prepare_transfer_to_handler |
| @@ -733,6 +733,7 @@ _GLOBAL(mmu_pin_tlb) · 732 unmodified lines | ||
| 733 | 733 | #ifdef CONFIG_PIN_TLB_DATA |
| 734 | 734 | LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) |
| 735 | 735 | LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED) |
| 736 | + li r8, 0 | |
| 736 | 737 | #ifdef CONFIG_PIN_TLB_IMMR |
| 737 | 738 | li r0, 3 |
| 738 | 739 | #else |
| @@ -741,26 +742,26 @@ _GLOBAL(mmu_pin_tlb) · 2 unmodified lines | ||
| 741 | 742 | mtctr r0 |
| 742 | 743 | cmpwi r4, 0 |
| 743 | 744 | beq 4f |
| 744 | − LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) | |
| 745 | 745 | LOAD_REG_ADDR(r9, _sinittext) |
| 746 | 746 | |
| 747 | 747 | 2: ori r0, r6, MD_EVALID |
| 748 | + ori r12, r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT | |
| 748 | 749 | mtspr SPRN_MD_CTR, r5 |
| 749 | 750 | mtspr SPRN_MD_EPN, r0 |
| 750 | 751 | mtspr SPRN_MD_TWC, r7 |
| 751 | − mtspr SPRN_MD_RPN, r8 | |
| 752 | + mtspr SPRN_MD_RPN, r12 | |
| 752 | 753 | addi r5, r5, 0x100 |
| 753 | 754 | addis r6, r6, SZ_8M@h |
| 754 | 755 | addis r8, r8, SZ_8M@h |
| 755 | 756 | cmplw r6, r9 |
| 756 | 757 | bdnzt lt, 2b |
| 757 | − | |
| 758 | −4: LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) | |
| 758 | +4: | |
| 759 | 759 | 2: ori r0, r6, MD_EVALID |
| 760 | + ori r12, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT | |
| 760 | 761 | mtspr SPRN_MD_CTR, r5 |
| 761 | 762 | mtspr SPRN_MD_EPN, r0 |
| 762 | 763 | mtspr SPRN_MD_TWC, r7 |
| 763 | − mtspr SPRN_MD_RPN, r8 | |
| 764 | + mtspr SPRN_MD_RPN, r12 | |
| 764 | 765 | addi r5, r5, 0x100 |
| 765 | 766 | addis r6, r6, SZ_8M@h |
| 766 | 767 | addis r8, r8, SZ_8M@h |
| @@ -781,7 +782,7 @@ _GLOBAL(mmu_pin_tlb) · 14 unmodified lines | ||
| 781 | 782 | #endif |
| 782 | 783 | #if defined(CONFIG_PIN_TLB_IMMR) || defined(CONFIG_PIN_TLB_DATA) |
| 783 | 784 | lis r0, (MD_RSV4I | MD_TWAM)@h |
| 784 | − mtspr SPRN_MI_CTR, r0 | |
| 785 | + mtspr SPRN_MD_CTR, r0 | |
| 785 | 786 | #endif |
| 786 | 787 | mtspr SPRN_SRR1, r10 |
| 787 | 788 | mtspr SPRN_SRR0, r11 |
| @@ -25,8 +25,14 @@ static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src) · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]); |
| 27 | 27 | } |
| 28 | −#define unsafe_get_user_sigset(dst, src, label) \ | |
| 29 | − unsafe_get_user((dst)->sig[0], (u64 __user *)&(src)->sig[0], label) | |
| 28 | +#define unsafe_get_user_sigset(dst, src, label) do { \ | |
| 29 | + sigset_t *__dst = dst; \ | |
| 30 | + const sigset_t __user *__src = src; \ | |
| 31 | + int i; \ | |
| 32 | + \ | |
| 33 | + for (i = 0; i < _NSIG_WORDS; i++) \ | |
| 34 | + unsafe_get_user(__dst->sig[i], &__src->sig[i], label); \ | |
| 35 | +} while (0) | |
| 30 | 36 | |
| 31 | 37 | #ifdef CONFIG_VSX |
| 32 | 38 | extern unsigned long copy_vsx_to_user(void __user *to, |
| @@ -1063,7 +1063,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, · 1062 unmodified lines | ||
| 1063 | 1063 | * We kill the task with a SIGSEGV in this situation. |
| 1064 | 1064 | */ |
| 1065 | 1065 | if (do_setcontext(new_ctx, regs, 0)) { |
| 1066 | − force_fatal_sig(SIGSEGV); | |
| 1066 | + force_exit_sig(SIGSEGV); | |
| 1067 | 1067 | return -EFAULT; |
| 1068 | 1068 | } |
| 1069 | 1069 | |
| @@ -704,7 +704,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, · 703 unmodified lines | ||
| 704 | 704 | */ |
| 705 | 705 | |
| 706 | 706 | if (__get_user_sigset(&set, &new_ctx->uc_sigmask)) { |
| 707 | − force_fatal_sig(SIGSEGV); | |
| 707 | + force_exit_sig(SIGSEGV); | |
| 708 | 708 | return -EFAULT; |
| 709 | 709 | } |
| 710 | 710 | set_current_blocked(&set); |
| @@ -713,7 +713,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, · 2 unmodified lines | ||
| 713 | 713 | return -EFAULT; |
| 714 | 714 | if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext)) { |
| 715 | 715 | user_read_access_end(); |
| 716 | − force_fatal_sig(SIGSEGV); | |
| 716 | + force_exit_sig(SIGSEGV); | |
| 717 | 717 | return -EFAULT; |
| 718 | 718 | } |
| 719 | 719 | user_read_access_end(); |
| @@ -528,3 +528,4 @@ · 527 unmodified lines | ||
| 528 | 528 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 529 | 529 | # 447 reserved for memfd_secret |
| 530 | 530 | 448 common process_mrelease sys_process_mrelease |
| 531 | +449 common futex_waitv sys_futex_waitv | |
| @@ -187,6 +187,12 @@ static void watchdog_smp_panic(int cpu, u64 tb) · 186 unmodified lines | ||
| 187 | 187 | if (sysctl_hardlockup_all_cpu_backtrace) |
| 188 | 188 | trigger_allbutself_cpu_backtrace(); |
| 189 | 189 | |
| 190 | + /* | |
| 191 | + * Force flush any remote buffers that might be stuck in IRQ context | |
| 192 | + * and therefore could not run their irq_work. | |
| 193 | + */ | |
| 194 | + printk_trigger_flush(); | |
| 195 | + | |
| 190 | 196 | if (hardlockup_panic) |
| 191 | 197 | nmi_panic(NULL, "Hard LOCKUP"); |
| 192 | 198 | |
| @@ -695,6 +695,7 @@ static void flush_guest_tlb(struct kvm *kvm) · 694 unmodified lines | ||
| 695 | 695 | "r" (0) : "memory"); |
| 696 | 696 | } |
| 697 | 697 | asm volatile("ptesync": : :"memory"); |
| 698 | + // POWER9 congruence-class TLBIEL leaves ERAT. Flush it now. | |
| 698 | 699 | asm volatile(PPC_RADIX_INVALIDATE_ERAT_GUEST : : :"memory"); |
| 699 | 700 | } else { |
| 700 | 701 | for (set = 0; set < kvm->arch.tlb_sets; ++set) { |
| @@ -705,7 +706,9 @@ static void flush_guest_tlb(struct kvm *kvm) · 4 unmodified lines | ||
| 705 | 706 | rb += PPC_BIT(51); /* increment set number */ |
| 706 | 707 | } |
| 707 | 708 | asm volatile("ptesync": : :"memory"); |
| 708 | − asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); | |
| 709 | + // POWER9 congruence-class TLBIEL leaves ERAT. Flush it now. | |
| 710 | + if (cpu_has_feature(CPU_FTR_ARCH_300)) | |
| 711 | + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); | |
| 709 | 712 | } |
| 710 | 713 | } |
| 711 | 714 | |
| @@ -2005,7 +2005,7 @@ hcall_real_table: · 2004 unmodified lines | ||
| 2005 | 2005 | .globl hcall_real_table_end |
| 2006 | 2006 | hcall_real_table_end: |
| 2007 | 2007 | |
| 2008 | −_GLOBAL(kvmppc_h_set_xdabr) | |
| 2008 | +_GLOBAL_TOC(kvmppc_h_set_xdabr) | |
| 2009 | 2009 | EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr) |
| 2010 | 2010 | andi. r0, r5, DABRX_USER | DABRX_KERNEL |
| 2011 | 2011 | beq 6f |
| @@ -2015,7 +2015,7 @@ EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr) · 3 unmodified lines | ||
| 2015 | 2015 | 6: li r3, H_PARAMETER |
| 2016 | 2016 | blr |
| 2017 | 2017 | |
| 2018 | −_GLOBAL(kvmppc_h_set_dabr) | |
| 2018 | +_GLOBAL_TOC(kvmppc_h_set_dabr) | |
| 2019 | 2019 | EXPORT_SYMBOL_GPL(kvmppc_h_set_dabr) |
| 2020 | 2020 | li r5, DABRX_USER | DABRX_KERNEL |
| 2021 | 2021 | 3: |
| @@ -641,9 +641,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 640 unmodified lines | ||
| 641 | 641 | * implementations just count online CPUs. |
| 642 | 642 | */ |
| 643 | 643 | if (hv_enabled) |
| 644 | − r = num_present_cpus(); | |
| 644 | + r = min_t(unsigned int, num_present_cpus(), KVM_MAX_VCPUS); | |
| 645 | 645 | else |
| 646 | − r = num_online_cpus(); | |
| 646 | + r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS); | |
| 647 | 647 | break; |
| 648 | 648 | case KVM_CAP_MAX_VCPUS: |
| 649 | 649 | r = KVM_MAX_VCPUS; |
| @@ -314,7 +314,7 @@ static unsigned long __init kaslr_choose_location(void *dt_ptr, phys_addr_t size · 313 unmodified lines | ||
| 314 | 314 | pr_warn("KASLR: No safe seed for randomizing the kernel base.\n"); |
| 315 | 315 | |
| 316 | 316 | ram = min_t(phys_addr_t, __max_low_memory, size); |
| 317 | − ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true, false); | |
| 317 | + ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true, true); | |
| 318 | 318 | linear_sz = min_t(unsigned long, ram, SZ_512M); |
| 319 | 319 | |
| 320 | 320 | /* If the linear size is smaller than 64M, do not randmize */ |
| @@ -645,7 +645,7 @@ static void early_init_this_mmu(void) · 644 unmodified lines | ||
| 645 | 645 | |
| 646 | 646 | if (map) |
| 647 | 647 | linear_map_top = map_mem_in_cams(linear_map_top, |
| 648 | − num_cams, true, true); | |
| 648 | + num_cams, false, true); | |
| 649 | 649 | } |
| 650 | 650 | #endif |
| 651 | 651 | |
| @@ -766,7 +766,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base, · 114 unmodified lines | ||
| 766 | 766 | num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; |
| 767 | 767 | |
| 768 | 768 | linear_sz = map_mem_in_cams(first_memblock_size, num_cams, |
| 769 | − false, true); | |
| 769 | + true, true); | |
| 770 | 770 | |
| 771 | 771 | ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); |
| 772 | 772 | } else |
| @@ -376,9 +376,9 @@ static void initialize_form2_numa_distance_lookup_table(void) · 375 unmodified lines | ||
| 376 | 376 | { |
| 377 | 377 | int i, j; |
| 378 | 378 | struct device_node *root; |
| 379 | − const __u8 *numa_dist_table; | |
| 379 | + const __u8 *form2_distances; | |
| 380 | 380 | const __be32 *numa_lookup_index; |
| 381 | − int numa_dist_table_length; | |
| 381 | + int form2_distances_length; | |
| 382 | 382 | int max_numa_index, distance_index; |
| 383 | 383 | |
| 384 | 384 | if (firmware_has_feature(FW_FEATURE_OPAL)) |
| @@ -392,45 +392,41 @@ static void initialize_form2_numa_distance_lookup_table(void) · 7 unmodified lines | ||
| 392 | 392 | max_numa_index = of_read_number(&numa_lookup_index[0], 1); |
| 393 | 393 | |
| 394 | 394 | /* first element of the array is the size and is encode-int */ |
| 395 | − numa_dist_table = of_get_property(root, "ibm,numa-distance-table", NULL); | |
| 396 | − numa_dist_table_length = of_read_number((const __be32 *)&numa_dist_table[0], 1); | |
| 395 | + form2_distances = of_get_property(root, "ibm,numa-distance-table", NULL); | |
| 396 | + form2_distances_length = of_read_number((const __be32 *)&form2_distances[0], 1); | |
| 397 | 397 | /* Skip the size which is encoded int */ |
| 398 | − numa_dist_table += sizeof(__be32); | |
| 398 | + form2_distances += sizeof(__be32); | |
| 399 | 399 | |
| 400 | − pr_debug("numa_dist_table_len = %d, numa_dist_indexes_len = %d\n", | |
| 401 | − numa_dist_table_length, max_numa_index); | |
| 400 | + pr_debug("form2_distances_len = %d, numa_dist_indexes_len = %d\n", | |
| 401 | + form2_distances_length, max_numa_index); | |
| 402 | 402 | |
| 403 | 403 | for (i = 0; i < max_numa_index; i++) |
| 404 | 404 | /* +1 skip the max_numa_index in the property */ |
| 405 | 405 | numa_id_index_table[i] = of_read_number(&numa_lookup_index[i + 1], 1); |
| 406 | 406 | |
| 407 | 407 | |
| 408 | − if (numa_dist_table_length != max_numa_index * max_numa_index) { | |
| 408 | + if (form2_distances_length != max_numa_index * max_numa_index) { | |
| 409 | 409 | WARN(1, "Wrong NUMA distance information\n"); |
| 410 | − /* consider everybody else just remote. */ | |
| 411 | − for (i = 0; i < max_numa_index; i++) { | |
| 412 | − for (j = 0; j < max_numa_index; j++) { | |
| 413 | − int nodeA = numa_id_index_table[i]; | |
| 414 | − int nodeB = numa_id_index_table[j]; | |
| 415 | − | |
| 416 | − if (nodeA == nodeB) | |
| 417 | − numa_distance_table[nodeA][nodeB] = LOCAL_DISTANCE; | |
| 418 | − else | |
| 419 | − numa_distance_table[nodeA][nodeB] = REMOTE_DISTANCE; | |
| 420 | − } | |
| 421 | − } | |
| 410 | + form2_distances = NULL; // don't use it | |
| 422 | 411 | } |
| 423 | − | |
| 424 | 412 | distance_index = 0; |
| 425 | 413 | for (i = 0; i < max_numa_index; i++) { |
| 426 | 414 | for (j = 0; j < max_numa_index; j++) { |
| 427 | 415 | int nodeA = numa_id_index_table[i]; |
| 428 | 416 | int nodeB = numa_id_index_table[j]; |
| 429 | − | |
| 430 | − numa_distance_table[nodeA][nodeB] = numa_dist_table[distance_index++]; | |
| 431 | − pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, numa_distance_table[nodeA][nodeB]); | |
| 417 | + int dist; | |
| 418 | + | |
| 419 | + if (form2_distances) | |
| 420 | + dist = form2_distances[distance_index++]; | |
| 421 | + else if (nodeA == nodeB) | |
| 422 | + dist = LOCAL_DISTANCE; | |
| 423 | + else | |
| 424 | + dist = REMOTE_DISTANCE; | |
| 425 | + numa_distance_table[nodeA][nodeB] = dist; | |
| 426 | + pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, dist); | |
| 432 | 427 | } |
| 433 | 428 | } |
| 429 | + | |
| 434 | 430 | of_node_put(root); |
| 435 | 431 | } |
| 436 | 432 | |
| @@ -186,7 +186,6 @@ err: · 185 unmodified lines | ||
| 186 | 186 | static int mcu_remove(struct i2c_client *client) |
| 187 | 187 | { |
| 188 | 188 | struct mcu *mcu = i2c_get_clientdata(client); |
| 189 | − int ret; | |
| 190 | 189 | |
| 191 | 190 | kthread_stop(shutdown_thread); |
| 192 | 191 | |
| @@ -1094,15 +1094,6 @@ static phys_addr_t ddw_memory_hotplug_max(void) · 1093 unmodified lines | ||
| 1094 | 1094 | phys_addr_t max_addr = memory_hotplug_max(); |
| 1095 | 1095 | struct device_node *memory; |
| 1096 | 1096 | |
| 1097 | − /* | |
| 1098 | − * The "ibm,pmemory" can appear anywhere in the address space. | |
| 1099 | − * Assuming it is still backed by page structs, set the upper limit | |
| 1100 | − * for the huge DMA window as MAX_PHYSMEM_BITS. | |
| 1101 | − */ | |
| 1102 | − if (of_find_node_by_type(NULL, "ibm,pmemory")) | |
| 1103 | − return (sizeof(phys_addr_t) * 8 <= MAX_PHYSMEM_BITS) ? | |
| 1104 | − (phys_addr_t) -1 : (1ULL << MAX_PHYSMEM_BITS); | |
| 1105 | − | |
| 1106 | 1097 | for_each_node_by_type(memory, "memory") { |
| 1107 | 1098 | unsigned long start, size; |
| 1108 | 1099 | int n_mem_addr_cells, n_mem_size_cells, len; |
| @@ -1238,7 +1229,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) · 129 unmodified lines | ||
| 1238 | 1229 | u32 ddw_avail[DDW_APPLICABLE_SIZE]; |
| 1239 | 1230 | struct dma_win *window; |
| 1240 | 1231 | struct property *win64; |
| 1241 | − bool ddw_enabled = false; | |
| 1242 | 1232 | struct failed_ddw_pdn *fpdn; |
| 1243 | 1233 | bool default_win_removed = false, direct_mapping = false; |
| 1244 | 1234 | bool pmem_present; |
| @@ -1253,7 +1243,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) · 8 unmodified lines | ||
| 1253 | 1243 | |
| 1254 | 1244 | if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) { |
| 1255 | 1245 | direct_mapping = (len >= max_ram_len); |
| 1256 | − ddw_enabled = true; | |
| 1257 | 1246 | goto out_unlock; |
| 1258 | 1247 | } |
| 1259 | 1248 | |
| @@ -1367,8 +1356,10 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) · 107 unmodified lines | ||
| 1367 | 1356 | len = order_base_2(query.largest_available_block << page_shift); |
| 1368 | 1357 | win_name = DMA64_PROPNAME; |
| 1369 | 1358 | } else { |
| 1370 | − direct_mapping = true; | |
| 1371 | − win_name = DIRECT64_PROPNAME; | |
| 1359 | + direct_mapping = !default_win_removed || | |
| 1360 | + (len == MAX_PHYSMEM_BITS) || | |
| 1361 | + (!pmem_present && (len == max_ram_len)); | |
| 1362 | + win_name = direct_mapping ? DIRECT64_PROPNAME : DMA64_PROPNAME; | |
| 1372 | 1363 | } |
| 1373 | 1364 | |
| 1374 | 1365 | ret = create_ddw(dev, ddw_avail, &create, page_shift, len); |
| @@ -1406,8 +1397,8 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) · 31 unmodified lines | ||
| 1406 | 1397 | dev_info(&dev->dev, "failed to map DMA window for %pOF: %d\n", |
| 1407 | 1398 | dn, ret); |
| 1408 | 1399 | |
| 1409 | − /* Make sure to clean DDW if any TCE was set*/ | |
| 1410 | − clean_dma_window(pdn, win64->value); | |
| 1400 | + /* Make sure to clean DDW if any TCE was set*/ | |
| 1401 | + clean_dma_window(pdn, win64->value); | |
| 1411 | 1402 | goto out_del_list; |
| 1412 | 1403 | } |
| 1413 | 1404 | } else { |
| @@ -1454,7 +1445,6 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) · 40 unmodified lines | ||
| 1454 | 1445 | spin_unlock(&dma_win_list_lock); |
| 1455 | 1446 | |
| 1456 | 1447 | dev->dev.archdata.dma_offset = win_addr; |
| 1457 | − ddw_enabled = true; | |
| 1458 | 1448 | goto out_unlock; |
| 1459 | 1449 | |
| 1460 | 1450 | out_del_list: |
| @@ -1490,10 +1480,10 @@ out_unlock: · 29 unmodified lines | ||
| 1490 | 1480 | * as RAM, then we failed to create a window to cover persistent |
| 1491 | 1481 | * memory and need to set the DMA limit. |
| 1492 | 1482 | */ |
| 1493 | − if (pmem_present && ddw_enabled && direct_mapping && len == max_ram_len) | |
| 1483 | + if (pmem_present && direct_mapping && len == max_ram_len) | |
| 1494 | 1484 | dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset + (1ULL << len); |
| 1495 | 1485 | |
| 1496 | − return ddw_enabled && direct_mapping; | |
| 1486 | + return direct_mapping; | |
| 1497 | 1487 | } |
| 1498 | 1488 | |
| 1499 | 1489 | static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) |
| @@ -3,7 +3,6 @@ config PPC_XIVE · 2 unmodified lines | ||
| 3 | 3 | bool |
| 4 | 4 | select PPC_SMP_MUXED_IPI |
| 5 | 5 | select HARDIRQS_SW_RESEND |
| 6 | − select IRQ_DOMAIN_NOMAP | |
| 7 | 6 | |
| 8 | 7 | config PPC_XIVE_NATIVE |
| 9 | 8 | bool |
| @@ -1443,8 +1443,7 @@ static const struct irq_domain_ops xive_irq_domain_ops = { · 1442 unmodified lines | ||
| 1443 | 1443 | |
| 1444 | 1444 | static void __init xive_init_host(struct device_node *np) |
| 1445 | 1445 | { |
| 1446 | − xive_irq_domain = irq_domain_add_nomap(np, XIVE_MAX_IRQ, | |
| 1447 | − &xive_irq_domain_ops, NULL); | |
| 1446 | + xive_irq_domain = irq_domain_add_tree(np, &xive_irq_domain_ops, NULL); | |
| 1448 | 1447 | if (WARN_ON(xive_irq_domain == NULL)) |
| 1449 | 1448 | return; |
| 1450 | 1449 | irq_set_default_host(xive_irq_domain); |
| @@ -107,11 +107,13 @@ PHONY += vdso_install · 106 unmodified lines | ||
| 107 | 107 | vdso_install: |
| 108 | 108 | $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ |
| 109 | 109 | |
| 110 | +ifeq ($(KBUILD_EXTMOD),) | |
| 110 | 111 | ifeq ($(CONFIG_MMU),y) |
| 111 | 112 | prepare: vdso_prepare |
| 112 | 113 | vdso_prepare: prepare0 |
| 113 | 114 | $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h |
| 114 | 115 | endif |
| 116 | +endif | |
| 115 | 117 | |
| 116 | 118 | ifneq ($(CONFIG_XIP_KERNEL),y) |
| 117 | 119 | ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy) |
| @@ -19,6 +19,8 @@ CONFIG_SOC_VIRT=y · 18 unmodified lines | ||
| 19 | 19 | CONFIG_SOC_MICROCHIP_POLARFIRE=y |
| 20 | 20 | CONFIG_SMP=y |
| 21 | 21 | CONFIG_HOTPLUG_CPU=y |
| 22 | +CONFIG_VIRTUALIZATION=y | |
| 23 | +CONFIG_KVM=m | |
| 22 | 24 | CONFIG_JUMP_LABEL=y |
| 23 | 25 | CONFIG_MODULES=y |
| 24 | 26 | CONFIG_MODULE_UNLOAD=y |
| @@ -19,6 +19,8 @@ CONFIG_SOC_VIRT=y · 18 unmodified lines | ||
| 19 | 19 | CONFIG_ARCH_RV32I=y |
| 20 | 20 | CONFIG_SMP=y |
| 21 | 21 | CONFIG_HOTPLUG_CPU=y |
| 22 | +CONFIG_VIRTUALIZATION=y | |
| 23 | +CONFIG_KVM=m | |
| 22 | 24 | CONFIG_JUMP_LABEL=y |
| 23 | 25 | CONFIG_MODULES=y |
| 24 | 26 | CONFIG_MODULE_UNLOAD=y |
| @@ -12,14 +12,12 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/types.h> |
| 13 | 13 | #include <linux/kvm.h> |
| 14 | 14 | #include <linux/kvm_types.h> |
| 15 | +#include <asm/csr.h> | |
| 15 | 16 | #include <asm/kvm_vcpu_fp.h> |
| 16 | 17 | #include <asm/kvm_vcpu_timer.h> |
| 17 | 18 | |
| 18 | −#ifdef CONFIG_64BIT | |
| 19 | −#define KVM_MAX_VCPUS (1U << 16) | |
| 20 | −#else | |
| 21 | −#define KVM_MAX_VCPUS (1U << 9) | |
| 22 | −#endif | |
| 19 | +#define KVM_MAX_VCPUS \ | |
| 20 | + ((HGATP_VMID_MASK >> HGATP_VMID_SHIFT) + 1) | |
| 23 | 21 | |
| 24 | 22 | #define KVM_HALT_POLL_NS_DEFAULT 500000 |
| 25 | 23 | |
| @@ -453,6 +453,12 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) · 452 unmodified lines | ||
| 453 | 453 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, |
| 454 | 454 | struct kvm_memory_slot *slot) |
| 455 | 455 | { |
| 456 | + gpa_t gpa = slot->base_gfn << PAGE_SHIFT; | |
| 457 | + phys_addr_t size = slot->npages << PAGE_SHIFT; | |
| 458 | + | |
| 459 | + spin_lock(&kvm->mmu_lock); | |
| 460 | + stage2_unmap_range(kvm, gpa, size, false); | |
| 461 | + spin_unlock(&kvm->mmu_lock); | |
| 456 | 462 | } |
| 457 | 463 | |
| 458 | 464 | void kvm_arch_commit_memory_region(struct kvm *kvm, |
| @@ -740,7 +740,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) · 739 unmodified lines | ||
| 740 | 740 | * Ensure we set mode to IN_GUEST_MODE after we disable |
| 741 | 741 | * interrupts and before the final VCPU requests check. |
| 742 | 742 | * See the comment in kvm_vcpu_exiting_guest_mode() and |
| 743 | − * Documentation/virtual/kvm/vcpu-requests.rst | |
| 743 | + * Documentation/virt/kvm/vcpu-requests.rst | |
| 744 | 744 | */ |
| 745 | 745 | vcpu->mode = IN_GUEST_MODE; |
| 746 | 746 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | −/** | |
| 2 | +/* | |
| 3 | 3 | * Copyright (c) 2019 Western Digital Corporation or its affiliates. |
| 4 | 4 | * |
| 5 | 5 | * Authors: |
| @@ -74,7 +74,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 73 unmodified lines | ||
| 74 | 74 | r = 1; |
| 75 | 75 | break; |
| 76 | 76 | case KVM_CAP_NR_VCPUS: |
| 77 | − r = num_online_cpus(); | |
| 77 | + r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS); | |
| 78 | 78 | break; |
| 79 | 79 | case KVM_CAP_MAX_VCPUS: |
| 80 | 80 | r = KVM_MAX_VCPUS; |
| @@ -47,7 +47,7 @@ config ARCH_SUPPORTS_UPROBES · 46 unmodified lines | ||
| 47 | 47 | config KASAN_SHADOW_OFFSET |
| 48 | 48 | hex |
| 49 | 49 | depends on KASAN |
| 50 | − default 0x18000000000000 | |
| 50 | + default 0x1C000000000000 | |
| 51 | 51 | |
| 52 | 52 | config S390 |
| 53 | 53 | def_bool y |
| @@ -194,6 +194,7 @@ config S390 · 140 unmodified lines | ||
| 194 | 194 | select HAVE_RELIABLE_STACKTRACE |
| 195 | 195 | select HAVE_RSEQ |
| 196 | 196 | select HAVE_SAMPLE_FTRACE_DIRECT |
| 197 | + select HAVE_SAMPLE_FTRACE_DIRECT_MULTI | |
| 197 | 198 | select HAVE_SOFTIRQ_ON_OWN_STACK |
| 198 | 199 | select HAVE_SYSCALL_TRACEPOINTS |
| 199 | 200 | select HAVE_VIRT_CPU_ACCOUNTING |
| @@ -77,10 +77,12 @@ KBUILD_AFLAGS_DECOMPRESSOR += $(aflags-y) · 76 unmodified lines | ||
| 77 | 77 | KBUILD_CFLAGS_DECOMPRESSOR += $(cflags-y) |
| 78 | 78 | |
| 79 | 79 | ifneq ($(call cc-option,-mstack-size=8192 -mstack-guard=128),) |
| 80 | −cflags-$(CONFIG_CHECK_STACK) += -mstack-size=$(STACK_SIZE) | |
| 81 | −ifeq ($(call cc-option,-mstack-size=8192),) | |
| 82 | −cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD) | |
| 83 | −endif | |
| 80 | + CC_FLAGS_CHECK_STACK := -mstack-size=$(STACK_SIZE) | |
| 81 | + ifeq ($(call cc-option,-mstack-size=8192),) | |
| 82 | + CC_FLAGS_CHECK_STACK += -mstack-guard=$(CONFIG_STACK_GUARD) | |
| 83 | + endif | |
| 84 | + export CC_FLAGS_CHECK_STACK | |
| 85 | + cflags-$(CONFIG_CHECK_STACK) += $(CC_FLAGS_CHECK_STACK) | |
| 84 | 86 | endif |
| 85 | 87 | |
| 86 | 88 | ifdef CONFIG_EXPOLINE |
| @@ -149,82 +149,56 @@ static void setup_ident_map_size(unsigned long max_physmem_end) · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | static void setup_kernel_memory_layout(void) |
| 151 | 151 | { |
| 152 | − bool vmalloc_size_verified = false; | |
| 153 | − unsigned long vmemmap_off; | |
| 154 | − unsigned long vspace_left; | |
| 152 | + unsigned long vmemmap_start; | |
| 155 | 153 | unsigned long rte_size; |
| 156 | 154 | unsigned long pages; |
| 157 | − unsigned long vmax; | |
| 158 | 155 | |
| 159 | 156 | pages = ident_map_size / PAGE_SIZE; |
| 160 | 157 | /* vmemmap contains a multiple of PAGES_PER_SECTION struct pages */ |
| 161 | 158 | vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page); |
| 162 | 159 | |
| 163 | 160 | /* choose kernel address space layout: 4 or 3 levels. */ |
| 164 | − vmemmap_off = round_up(ident_map_size, _REGION3_SIZE); | |
| 161 | + vmemmap_start = round_up(ident_map_size, _REGION3_SIZE); | |
| 165 | 162 | if (IS_ENABLED(CONFIG_KASAN) || |
| 166 | 163 | vmalloc_size > _REGION2_SIZE || |
| 167 | − vmemmap_off + vmemmap_size + vmalloc_size + MODULES_LEN > _REGION2_SIZE) | |
| 168 | − vmax = _REGION1_SIZE; | |
| 169 | − else | |
| 170 | − vmax = _REGION2_SIZE; | |
| 171 | − | |
| 172 | − /* keep vmemmap_off aligned to a top level region table entry */ | |
| 173 | − rte_size = vmax == _REGION1_SIZE ? _REGION2_SIZE : _REGION3_SIZE; | |
| 174 | − MODULES_END = vmax; | |
| 175 | − if (is_prot_virt_host()) { | |
| 176 | − /* | |
| 177 | − * forcing modules and vmalloc area under the ultravisor | |
| 178 | − * secure storage limit, so that any vmalloc allocation | |
| 179 | − * we do could be used to back secure guest storage. | |
| 180 | − */ | |
| 181 | − adjust_to_uv_max(&MODULES_END); | |
| 182 | − } | |
| 183 | − | |
| 184 | −#ifdef CONFIG_KASAN | |
| 185 | − if (MODULES_END < vmax) { | |
| 186 | − /* force vmalloc and modules below kasan shadow */ | |
| 187 | − MODULES_END = min(MODULES_END, KASAN_SHADOW_START); | |
| 164 | + vmemmap_start + vmemmap_size + vmalloc_size + MODULES_LEN > | |
| 165 | + _REGION2_SIZE) { | |
| 166 | + MODULES_END = _REGION1_SIZE; | |
| 167 | + rte_size = _REGION2_SIZE; | |
| 188 | 168 | } else { |
| 189 | − /* | |
| 190 | − * leave vmalloc and modules above kasan shadow but make | |
| 191 | − * sure they don't overlap with it | |
| 192 | − */ | |
| 193 | − vmalloc_size = min(vmalloc_size, vmax - KASAN_SHADOW_END - MODULES_LEN); | |
| 194 | − vmalloc_size_verified = true; | |
| 195 | − vspace_left = KASAN_SHADOW_START; | |
| 169 | + MODULES_END = _REGION2_SIZE; | |
| 170 | + rte_size = _REGION3_SIZE; | |
| 196 | 171 | } |
| 172 | + /* | |
| 173 | + * forcing modules and vmalloc area under the ultravisor | |
| 174 | + * secure storage limit, so that any vmalloc allocation | |
| 175 | + * we do could be used to back secure guest storage. | |
| 176 | + */ | |
| 177 | + adjust_to_uv_max(&MODULES_END); | |
| 178 | +#ifdef CONFIG_KASAN | |
| 179 | + /* force vmalloc and modules below kasan shadow */ | |
| 180 | + MODULES_END = min(MODULES_END, KASAN_SHADOW_START); | |
| 197 | 181 | #endif |
| 198 | 182 | MODULES_VADDR = MODULES_END - MODULES_LEN; |
| 199 | 183 | VMALLOC_END = MODULES_VADDR; |
| 200 | 184 | |
| 201 | − if (vmalloc_size_verified) { | |
| 202 | − VMALLOC_START = VMALLOC_END - vmalloc_size; | |
| 203 | − } else { | |
| 204 | − vmemmap_off = round_up(ident_map_size, rte_size); | |
| 205 | − | |
| 206 | − if (vmemmap_off + vmemmap_size > VMALLOC_END || | |
| 207 | − vmalloc_size > VMALLOC_END - vmemmap_off - vmemmap_size) { | |
| 208 | − /* | |
| 209 | − * allow vmalloc area to occupy up to 1/2 of | |
| 210 | − * the rest virtual space left. | |
| 211 | − */ | |
| 212 | − vmalloc_size = min(vmalloc_size, VMALLOC_END / 2); | |
| 213 | − } | |
| 214 | − VMALLOC_START = VMALLOC_END - vmalloc_size; | |
| 215 | − vspace_left = VMALLOC_START; | |
| 216 | − } | |
| 185 | + /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */ | |
| 186 | + vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE)); | |
| 187 | + VMALLOC_START = VMALLOC_END - vmalloc_size; | |
| 217 | 188 | |
| 218 | − pages = vspace_left / (PAGE_SIZE + sizeof(struct page)); | |
| 189 | + /* split remaining virtual space between 1:1 mapping & vmemmap array */ | |
| 190 | + pages = VMALLOC_START / (PAGE_SIZE + sizeof(struct page)); | |
| 219 | 191 | pages = SECTION_ALIGN_UP(pages); |
| 220 | − vmemmap_off = round_up(vspace_left - pages * sizeof(struct page), rte_size); | |
| 221 | − /* keep vmemmap left most starting from a fresh region table entry */ | |
| 222 | − vmemmap_off = min(vmemmap_off, round_up(ident_map_size, rte_size)); | |
| 223 | − /* take care that identity map is lower then vmemmap */ | |
| 224 | − ident_map_size = min(ident_map_size, vmemmap_off); | |
| 192 | + /* keep vmemmap_start aligned to a top level region table entry */ | |
| 193 | + vmemmap_start = round_down(VMALLOC_START - pages * sizeof(struct page), rte_size); | |
| 194 | + /* vmemmap_start is the future VMEM_MAX_PHYS, make sure it is within MAX_PHYSMEM */ | |
| 195 | + vmemmap_start = min(vmemmap_start, 1UL << MAX_PHYSMEM_BITS); | |
| 196 | + /* make sure identity map doesn't overlay with vmemmap */ | |
| 197 | + ident_map_size = min(ident_map_size, vmemmap_start); | |
| 225 | 198 | vmemmap_size = SECTION_ALIGN_UP(ident_map_size / PAGE_SIZE) * sizeof(struct page); |
| 226 | − VMALLOC_START = max(vmemmap_off + vmemmap_size, VMALLOC_START); | |
| 227 | − vmemmap = (struct page *)vmemmap_off; | |
| 199 | + /* make sure vmemmap doesn't overlay with vmalloc area */ | |
| 200 | + VMALLOC_START = max(vmemmap_start + vmemmap_size, VMALLOC_START); | |
| 201 | + vmemmap = (struct page *)vmemmap_start; | |
| 228 | 202 | } |
| 229 | 203 | |
| 230 | 204 | /* |
| @@ -403,7 +403,6 @@ CONFIG_DEVTMPFS=y · 402 unmodified lines | ||
| 403 | 403 | CONFIG_CONNECTOR=y |
| 404 | 404 | CONFIG_ZRAM=y |
| 405 | 405 | CONFIG_BLK_DEV_LOOP=m |
| 406 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 407 | 406 | CONFIG_BLK_DEV_DRBD=m |
| 408 | 407 | CONFIG_BLK_DEV_NBD=m |
| 409 | 408 | CONFIG_BLK_DEV_RAM=y |
| @@ -476,6 +475,7 @@ CONFIG_MACVLAN=m · 66 unmodified lines | ||
| 476 | 475 | CONFIG_MACVTAP=m |
| 477 | 476 | CONFIG_VXLAN=m |
| 478 | 477 | CONFIG_BAREUDP=m |
| 478 | +CONFIG_AMT=m | |
| 479 | 479 | CONFIG_TUN=m |
| 480 | 480 | CONFIG_VETH=m |
| 481 | 481 | CONFIG_VIRTIO_NET=m |
| @@ -489,6 +489,7 @@ CONFIG_NLMON=m · 7 unmodified lines | ||
| 489 | 489 | # CONFIG_NET_VENDOR_AMD is not set |
| 490 | 490 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 491 | 491 | # CONFIG_NET_VENDOR_ARC is not set |
| 492 | +# CONFIG_NET_VENDOR_ASIX is not set | |
| 492 | 493 | # CONFIG_NET_VENDOR_ATHEROS is not set |
| 493 | 494 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 494 | 495 | # CONFIG_NET_VENDOR_BROCADE is not set |
| @@ -571,6 +572,7 @@ CONFIG_WATCHDOG=y · 76 unmodified lines | ||
| 571 | 572 | CONFIG_WATCHDOG_NOWAYOUT=y |
| 572 | 573 | CONFIG_SOFT_WATCHDOG=m |
| 573 | 574 | CONFIG_DIAG288_WATCHDOG=m |
| 575 | +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set | |
| 574 | 576 | CONFIG_FB=y |
| 575 | 577 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 576 | 578 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y |
| @@ -775,12 +777,14 @@ CONFIG_CRC4=m · 198 unmodified lines | ||
| 775 | 777 | CONFIG_CRC7=m |
| 776 | 778 | CONFIG_CRC8=m |
| 777 | 779 | CONFIG_RANDOM32_SELFTEST=y |
| 780 | +CONFIG_XZ_DEC_MICROLZMA=y | |
| 778 | 781 | CONFIG_DMA_CMA=y |
| 779 | 782 | CONFIG_CMA_SIZE_MBYTES=0 |
| 780 | 783 | CONFIG_PRINTK_TIME=y |
| 781 | 784 | CONFIG_DYNAMIC_DEBUG=y |
| 782 | 785 | CONFIG_DEBUG_INFO=y |
| 783 | 786 | CONFIG_DEBUG_INFO_DWARF4=y |
| 787 | +CONFIG_DEBUG_INFO_BTF=y | |
| 784 | 788 | CONFIG_GDB_SCRIPTS=y |
| 785 | 789 | CONFIG_HEADERS_INSTALL=y |
| 786 | 790 | CONFIG_DEBUG_SECTION_MISMATCH=y |
| @@ -807,6 +811,7 @@ CONFIG_DEBUG_MEMORY_INIT=y · 20 unmodified lines | ||
| 807 | 811 | CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m |
| 808 | 812 | CONFIG_DEBUG_PER_CPU_MAPS=y |
| 809 | 813 | CONFIG_KFENCE=y |
| 814 | +CONFIG_KFENCE_STATIC_KEYS=y | |
| 810 | 815 | CONFIG_DEBUG_SHIRQ=y |
| 811 | 816 | CONFIG_PANIC_ON_OOPS=y |
| 812 | 817 | CONFIG_DETECT_HUNG_TASK=y |
| @@ -842,6 +847,7 @@ CONFIG_FTRACE_STARTUP_TEST=y · 29 unmodified lines | ||
| 842 | 847 | CONFIG_SAMPLES=y |
| 843 | 848 | CONFIG_SAMPLE_TRACE_PRINTK=m |
| 844 | 849 | CONFIG_SAMPLE_FTRACE_DIRECT=m |
| 850 | +CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m | |
| 845 | 851 | CONFIG_DEBUG_ENTRY=y |
| 846 | 852 | CONFIG_CIO_INJECT=y |
| 847 | 853 | CONFIG_KUNIT=m |
| @@ -860,7 +866,7 @@ CONFIG_FAIL_FUNCTION=y · 12 unmodified lines | ||
| 860 | 866 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y |
| 861 | 867 | CONFIG_LKDTM=m |
| 862 | 868 | CONFIG_TEST_MIN_HEAP=y |
| 863 | −CONFIG_KPROBES_SANITY_TEST=y | |
| 869 | +CONFIG_KPROBES_SANITY_TEST=m | |
| 864 | 870 | CONFIG_RBTREE_TEST=y |
| 865 | 871 | CONFIG_INTERVAL_TREE_TEST=m |
| 866 | 872 | CONFIG_PERCPU_TEST=m |
| @@ -394,7 +394,6 @@ CONFIG_DEVTMPFS=y · 393 unmodified lines | ||
| 394 | 394 | CONFIG_CONNECTOR=y |
| 395 | 395 | CONFIG_ZRAM=y |
| 396 | 396 | CONFIG_BLK_DEV_LOOP=m |
| 397 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 398 | 397 | CONFIG_BLK_DEV_DRBD=m |
| 399 | 398 | CONFIG_BLK_DEV_NBD=m |
| 400 | 399 | CONFIG_BLK_DEV_RAM=y |
| @@ -467,6 +466,7 @@ CONFIG_MACVLAN=m · 66 unmodified lines | ||
| 467 | 466 | CONFIG_MACVTAP=m |
| 468 | 467 | CONFIG_VXLAN=m |
| 469 | 468 | CONFIG_BAREUDP=m |
| 469 | +CONFIG_AMT=m | |
| 470 | 470 | CONFIG_TUN=m |
| 471 | 471 | CONFIG_VETH=m |
| 472 | 472 | CONFIG_VIRTIO_NET=m |
| @@ -480,6 +480,7 @@ CONFIG_NLMON=m · 7 unmodified lines | ||
| 480 | 480 | # CONFIG_NET_VENDOR_AMD is not set |
| 481 | 481 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 482 | 482 | # CONFIG_NET_VENDOR_ARC is not set |
| 483 | +# CONFIG_NET_VENDOR_ASIX is not set | |
| 483 | 484 | # CONFIG_NET_VENDOR_ATHEROS is not set |
| 484 | 485 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 485 | 486 | # CONFIG_NET_VENDOR_BROCADE is not set |
| @@ -762,12 +763,14 @@ CONFIG_PRIME_NUMBERS=m · 276 unmodified lines | ||
| 762 | 763 | CONFIG_CRC4=m |
| 763 | 764 | CONFIG_CRC7=m |
| 764 | 765 | CONFIG_CRC8=m |
| 766 | +CONFIG_XZ_DEC_MICROLZMA=y | |
| 765 | 767 | CONFIG_DMA_CMA=y |
| 766 | 768 | CONFIG_CMA_SIZE_MBYTES=0 |
| 767 | 769 | CONFIG_PRINTK_TIME=y |
| 768 | 770 | CONFIG_DYNAMIC_DEBUG=y |
| 769 | 771 | CONFIG_DEBUG_INFO=y |
| 770 | 772 | CONFIG_DEBUG_INFO_DWARF4=y |
| 773 | +CONFIG_DEBUG_INFO_BTF=y | |
| 771 | 774 | CONFIG_GDB_SCRIPTS=y |
| 772 | 775 | CONFIG_DEBUG_SECTION_MISMATCH=y |
| 773 | 776 | CONFIG_MAGIC_SYSRQ=y |
| @@ -792,9 +795,11 @@ CONFIG_HIST_TRIGGERS=y · 18 unmodified lines | ||
| 792 | 795 | CONFIG_SAMPLES=y |
| 793 | 796 | CONFIG_SAMPLE_TRACE_PRINTK=m |
| 794 | 797 | CONFIG_SAMPLE_FTRACE_DIRECT=m |
| 798 | +CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m | |
| 795 | 799 | CONFIG_KUNIT=m |
| 796 | 800 | CONFIG_KUNIT_DEBUGFS=y |
| 797 | 801 | CONFIG_LKDTM=m |
| 802 | +CONFIG_KPROBES_SANITY_TEST=m | |
| 798 | 803 | CONFIG_PERCPU_TEST=m |
| 799 | 804 | CONFIG_ATOMIC64_SELFTEST=y |
| 800 | 805 | CONFIG_TEST_BPF=m |
| @@ -65,9 +65,11 @@ CONFIG_ZFCP=y · 64 unmodified lines | ||
| 65 | 65 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 66 | 66 | CONFIG_LSM="yama,loadpin,safesetid,integrity" |
| 67 | 67 | # CONFIG_ZLIB_DFLTCC is not set |
| 68 | +CONFIG_XZ_DEC_MICROLZMA=y | |
| 68 | 69 | CONFIG_PRINTK_TIME=y |
| 69 | 70 | # CONFIG_SYMBOLIC_ERRNAME is not set |
| 70 | 71 | CONFIG_DEBUG_INFO=y |
| 72 | +CONFIG_DEBUG_INFO_BTF=y | |
| 71 | 73 | CONFIG_DEBUG_FS=y |
| 72 | 74 | CONFIG_DEBUG_KERNEL=y |
| 73 | 75 | CONFIG_PANIC_ON_OOPS=y |
| @@ -74,6 +74,12 @@ void *kexec_file_add_components(struct kimage *image, · 73 unmodified lines | ||
| 74 | 74 | int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val, |
| 75 | 75 | unsigned long addr); |
| 76 | 76 | |
| 77 | +#define ARCH_HAS_KIMAGE_ARCH | |
| 78 | + | |
| 79 | +struct kimage_arch { | |
| 80 | + void *ipl_buf; | |
| 81 | +}; | |
| 82 | + | |
| 77 | 83 | extern const struct kexec_file_ops s390_kexec_image_ops; |
| 78 | 84 | extern const struct kexec_file_ops s390_kexec_elf_ops; |
| 79 | 85 | |
| @@ -14,12 +14,13 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | /* I/O Map */ |
| 16 | 16 | #define ZPCI_IOMAP_SHIFT 48 |
| 17 | −#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL | |
| 17 | +#define ZPCI_IOMAP_ADDR_SHIFT 62 | |
| 18 | +#define ZPCI_IOMAP_ADDR_BASE (1UL << ZPCI_IOMAP_ADDR_SHIFT) | |
| 18 | 19 | #define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) |
| 19 | 20 | #define ZPCI_IOMAP_MAX_ENTRIES \ |
| 20 | − ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT)) | |
| 21 | + (1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT)) | |
| 21 | 22 | #define ZPCI_IOMAP_ADDR_IDX_MASK \ |
| 22 | − (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE) | |
| 23 | + ((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK) | |
| 23 | 24 | |
| 24 | 25 | struct zpci_iomap_entry { |
| 25 | 26 | u32 fh; |
| @@ -191,8 +191,8 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count) · 190 unmodified lines | ||
| 191 | 191 | return rc; |
| 192 | 192 | } else { |
| 193 | 193 | /* Check for swapped kdump oldmem areas */ |
| 194 | − if (oldmem_data.start && from - oldmem_data.size < oldmem_data.size) { | |
| 195 | − from -= oldmem_data.size; | |
| 194 | + if (oldmem_data.start && from - oldmem_data.start < oldmem_data.size) { | |
| 195 | + from -= oldmem_data.start; | |
| 196 | 196 | len = min(count, oldmem_data.size - from); |
| 197 | 197 | } else if (oldmem_data.start && from < oldmem_data.size) { |
| 198 | 198 | len = min(count, oldmem_data.size - from); |
| @@ -2156,7 +2156,7 @@ void *ipl_report_finish(struct ipl_report *report) · 2155 unmodified lines | ||
| 2156 | 2156 | |
| 2157 | 2157 | buf = vzalloc(report->size); |
| 2158 | 2158 | if (!buf) |
| 2159 | − return ERR_PTR(-ENOMEM); | |
| 2159 | + goto out; | |
| 2160 | 2160 | ptr = buf; |
| 2161 | 2161 | |
| 2162 | 2162 | memcpy(ptr, report->ipib, report->ipib->hdr.len); |
| @@ -2195,6 +2195,7 @@ void *ipl_report_finish(struct ipl_report *report) · 32 unmodified lines | ||
| 2195 | 2195 | } |
| 2196 | 2196 | |
| 2197 | 2197 | BUG_ON(ptr > buf + report->size); |
| 2198 | +out: | |
| 2198 | 2199 | return buf; |
| 2199 | 2200 | } |
| 2200 | 2201 | |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/kexec.h> |
| 13 | 13 | #include <linux/module_signature.h> |
| 14 | 14 | #include <linux/verification.h> |
| 15 | +#include <linux/vmalloc.h> | |
| 15 | 16 | #include <asm/boot_data.h> |
| 16 | 17 | #include <asm/ipl.h> |
| 17 | 18 | #include <asm/setup.h> |
| @@ -170,6 +171,7 @@ static int kexec_file_add_ipl_report(struct kimage *image, · 152 unmodified lines | ||
| 170 | 171 | struct kexec_buf buf; |
| 171 | 172 | unsigned long addr; |
| 172 | 173 | void *ptr, *end; |
| 174 | + int ret; | |
| 173 | 175 | |
| 174 | 176 | buf.image = image; |
| 175 | 177 | |
| @@ -199,9 +201,13 @@ static int kexec_file_add_ipl_report(struct kimage *image, · 23 unmodified lines | ||
| 199 | 201 | ptr += len; |
| 200 | 202 | } |
| 201 | 203 | |
| 204 | + ret = -ENOMEM; | |
| 202 | 205 | buf.buffer = ipl_report_finish(data->report); |
| 206 | + if (!buf.buffer) | |
| 207 | + goto out; | |
| 203 | 208 | buf.bufsz = data->report->size; |
| 204 | 209 | buf.memsz = buf.bufsz; |
| 210 | + image->arch.ipl_buf = buf.buffer; | |
| 205 | 211 | |
| 206 | 212 | data->memsz += buf.memsz; |
| 207 | 213 | |
| @@ -209,7 +215,9 @@ static int kexec_file_add_ipl_report(struct kimage *image, · 1 unmodified line | ||
| 209 | 215 | data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr); |
| 210 | 216 | *lc_ipl_parmblock_ptr = (__u32)buf.mem; |
| 211 | 217 | |
| 212 | − return kexec_add_buffer(&buf); | |
| 218 | + ret = kexec_add_buffer(&buf); | |
| 219 | +out: | |
| 220 | + return ret; | |
| 213 | 221 | } |
| 214 | 222 | |
| 215 | 223 | void *kexec_file_add_components(struct kimage *image, |
| @@ -322,3 +330,11 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, · 106 unmodified lines | ||
| 322 | 330 | } |
| 323 | 331 | return 0; |
| 324 | 332 | } |
| 333 | + | |
| 334 | +int arch_kimage_file_post_load_cleanup(struct kimage *image) | |
| 335 | +{ | |
| 336 | + vfree(image->arch.ipl_buf); | |
| 337 | + image->arch.ipl_buf = NULL; | |
| 338 | + | |
| 339 | + return kexec_image_post_load_cleanup_default(image); | |
| 340 | +} | |
| @@ -606,7 +606,7 @@ static void __init setup_resources(void) · 605 unmodified lines | ||
| 606 | 606 | |
| 607 | 607 | static void __init setup_memory_end(void) |
| 608 | 608 | { |
| 609 | − memblock_remove(ident_map_size, ULONG_MAX); | |
| 609 | + memblock_remove(ident_map_size, PHYS_ADDR_MAX - ident_map_size); | |
| 610 | 610 | max_pfn = max_low_pfn = PFN_DOWN(ident_map_size); |
| 611 | 611 | pr_notice("The maximum memory size is %luMB\n", ident_map_size >> 20); |
| 612 | 612 | } |
| @@ -637,14 +637,6 @@ static struct notifier_block kdump_mem_nb = { · 24 unmodified lines | ||
| 637 | 637 | |
| 638 | 638 | #endif |
| 639 | 639 | |
| 640 | −/* | |
| 641 | − * Make sure that the area above identity mapping is protected | |
| 642 | − */ | |
| 643 | −static void __init reserve_above_ident_map(void) | |
| 644 | −{ | |
| 645 | − memblock_reserve(ident_map_size, ULONG_MAX); | |
| 646 | −} | |
| 647 | − | |
| 648 | 640 | /* |
| 649 | 641 | * Reserve memory for kdump kernel to be loaded with kexec |
| 650 | 642 | */ |
| @@ -785,7 +777,6 @@ static void __init memblock_add_mem_detect_info(void) · 134 unmodified lines | ||
| 785 | 777 | } |
| 786 | 778 | memblock_set_bottom_up(false); |
| 787 | 779 | memblock_set_node(0, ULONG_MAX, &memblock.memory, 0); |
| 788 | − memblock_dump_all(); | |
| 789 | 780 | } |
| 790 | 781 | |
| 791 | 782 | /* |
| @@ -826,9 +817,6 @@ static void __init setup_memory(void) · 34 unmodified lines | ||
| 826 | 817 | storage_key_init_range(start, end); |
| 827 | 818 | |
| 828 | 819 | psw_set_key(PAGE_DEFAULT_KEY); |
| 829 | − | |
| 830 | − /* Only cosmetics */ | |
| 831 | − memblock_enforce_memory_limit(memblock_end_of_DRAM()); | |
| 832 | 820 | } |
| 833 | 821 | |
| 834 | 822 | static void __init relocate_amode31_section(void) |
| @@ -999,24 +987,24 @@ void __init setup_arch(char **cmdline_p) · 164 unmodified lines | ||
| 999 | 987 | setup_control_program_code(); |
| 1000 | 988 | |
| 1001 | 989 | /* Do some memory reservations *before* memory is added to memblock */ |
| 1002 | − reserve_above_ident_map(); | |
| 1003 | 990 | reserve_kernel(); |
| 1004 | 991 | reserve_initrd(); |
| 1005 | 992 | reserve_certificate_list(); |
| 1006 | 993 | reserve_mem_detect_info(); |
| 994 | + memblock_set_current_limit(ident_map_size); | |
| 1007 | 995 | memblock_allow_resize(); |
| 1008 | 996 | |
| 1009 | 997 | /* Get information about *all* installed memory */ |
| 1010 | 998 | memblock_add_mem_detect_info(); |
| 1011 | 999 | |
| 1012 | 1000 | free_mem_detect_info(); |
| 1001 | + setup_memory_end(); | |
| 1002 | + memblock_dump_all(); | |
| 1003 | + setup_memory(); | |
| 1013 | 1004 | |
| 1014 | 1005 | relocate_amode31_section(); |
| 1015 | 1006 | setup_cr(); |
| 1016 | − | |
| 1017 | 1007 | setup_uv(); |
| 1018 | − setup_memory_end(); | |
| 1019 | − setup_memory(); | |
| 1020 | 1008 | dma_contiguous_reserve(ident_map_size); |
| 1021 | 1009 | vmcp_cma_reserve(); |
| 1022 | 1010 | if (MACHINE_HAS_EDAT2) |
| @@ -451,3 +451,4 @@ · 450 unmodified lines | ||
| 451 | 451 | 446 common landlock_restrict_self sys_landlock_restrict_self sys_landlock_restrict_self |
| 452 | 452 | # 447 reserved for memfd_secret |
| 453 | 453 | 448 common process_mrelease sys_process_mrelease sys_process_mrelease |
| 454 | +449 common futex_waitv sys_futex_waitv sys_futex_waitv | |
| @@ -84,7 +84,7 @@ static void default_trap_handler(struct pt_regs *regs) · 83 unmodified lines | ||
| 84 | 84 | { |
| 85 | 85 | if (user_mode(regs)) { |
| 86 | 86 | report_user_fault(regs, SIGSEGV, 0); |
| 87 | − force_fatal_sig(SIGSEGV); | |
| 87 | + force_exit_sig(SIGSEGV); | |
| 88 | 88 | } else |
| 89 | 89 | die(regs, "Unknown program exception"); |
| 90 | 90 | } |
| @@ -22,7 +22,7 @@ KBUILD_AFLAGS_32 += -m31 -s · 21 unmodified lines | ||
| 22 | 22 | KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) |
| 23 | 23 | KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin |
| 24 | 24 | |
| 25 | −LDFLAGS_vdso32.so.dbg += -fPIC -shared -nostdlib -soname=linux-vdso32.so.1 \ | |
| 25 | +LDFLAGS_vdso32.so.dbg += -fPIC -shared -soname=linux-vdso32.so.1 \ | |
| 26 | 26 | --hash-style=both --build-id=sha1 -melf_s390 -T |
| 27 | 27 | |
| 28 | 28 | $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32) |
| @@ -8,8 +8,9 @@ ARCH_REL_TYPE_ABS += R_390_GOT|R_390_PLT · 7 unmodified lines | ||
| 8 | 8 | include $(srctree)/lib/vdso/Makefile |
| 9 | 9 | obj-vdso64 = vdso_user_wrapper.o note.o |
| 10 | 10 | obj-cvdso64 = vdso64_generic.o getcpu.o |
| 11 | −CFLAGS_REMOVE_getcpu.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) | |
| 12 | −CFLAGS_REMOVE_vdso64_generic.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) | |
| 11 | +VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) $(CC_FLAGS_CHECK_STACK) | |
| 12 | +CFLAGS_REMOVE_getcpu.o = $(VDSO_CFLAGS_REMOVE) | |
| 13 | +CFLAGS_REMOVE_vdso64_generic.o = $(VDSO_CFLAGS_REMOVE) | |
| 13 | 14 | |
| 14 | 15 | # Build rules |
| 15 | 16 | |
| @@ -25,7 +26,7 @@ KBUILD_AFLAGS_64 += -m64 -s · 9 unmodified lines | ||
| 25 | 26 | |
| 26 | 27 | KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) |
| 27 | 28 | KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin |
| 28 | −ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \ | |
| 29 | +ldflags-y := -fPIC -shared -soname=linux-vdso64.so.1 \ | |
| 29 | 30 | --hash-style=both --build-id=sha1 -T |
| 30 | 31 | |
| 31 | 32 | $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) |
| @@ -585,6 +585,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 584 unmodified lines | ||
| 585 | 585 | r = KVM_MAX_VCPUS; |
| 586 | 586 | else if (sclp.has_esca && sclp.has_64bscao) |
| 587 | 587 | r = KVM_S390_ESCA_CPU_SLOTS; |
| 588 | + if (ext == KVM_CAP_NR_VCPUS) | |
| 589 | + r = min_t(unsigned int, num_online_cpus(), r); | |
| 588 | 590 | break; |
| 589 | 591 | case KVM_CAP_S390_COW: |
| 590 | 592 | r = MACHINE_HAS_ESOP; |
| @@ -173,10 +173,11 @@ static noinline int unwindme_func4(struct unwindme *u) · 172 unmodified lines | ||
| 173 | 173 | } |
| 174 | 174 | |
| 175 | 175 | /* |
| 176 | − * trigger specification exception | |
| 176 | + * Trigger operation exception; use insn notation to bypass | |
| 177 | + * llvm's integrated assembler sanity checks. | |
| 177 | 178 | */ |
| 178 | 179 | asm volatile( |
| 179 | − " mvcl %%r1,%%r1\n" | |
| 180 | + " .insn e,0x0000\n" /* illegal opcode */ | |
| 180 | 181 | "0: nopr %%r7\n" |
| 181 | 182 | EX_TABLE(0b, 0b) |
| 182 | 183 | :); |
| @@ -43,7 +43,6 @@ extern void flush_cache_range(struct vm_area_struct *vma, · 42 unmodified lines | ||
| 43 | 43 | unsigned long start, unsigned long end); |
| 44 | 44 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 45 | 45 | void flush_dcache_page(struct page *page); |
| 46 | −void flush_dcache_folio(struct folio *folio); | |
| 47 | 46 | extern void flush_icache_range(unsigned long start, unsigned long end); |
| 48 | 47 | #define flush_icache_user_range flush_icache_range |
| 49 | 48 | extern void flush_icache_page(struct vm_area_struct *vma, |
| @@ -451,3 +451,4 @@ · 450 unmodified lines | ||
| 451 | 451 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 452 | 452 | # 447 reserved for memfd_secret |
| 453 | 453 | 448 common process_mrelease sys_process_mrelease |
| 454 | +449 common futex_waitv sys_futex_waitv | |
| @@ -244,7 +244,7 @@ static int setup_frame(struct ksignal *ksig, struct pt_regs *regs, · 243 unmodified lines | ||
| 244 | 244 | get_sigframe(ksig, regs, sigframe_size); |
| 245 | 245 | |
| 246 | 246 | if (invalid_frame_pointer(sf, sigframe_size)) { |
| 247 | − force_fatal_sig(SIGILL); | |
| 247 | + force_exit_sig(SIGILL); | |
| 248 | 248 | return -EINVAL; |
| 249 | 249 | } |
| 250 | 250 | |
| @@ -336,7 +336,7 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs, · 85 unmodified lines | ||
| 336 | 336 | sf = (struct rt_signal_frame __user *) |
| 337 | 337 | get_sigframe(ksig, regs, sigframe_size); |
| 338 | 338 | if (invalid_frame_pointer(sf, sigframe_size)) { |
| 339 | − force_fatal_sig(SIGILL); | |
| 339 | + force_exit_sig(SIGILL); | |
| 340 | 340 | return -EINVAL; |
| 341 | 341 | } |
| 342 | 342 | |
| @@ -494,3 +494,4 @@ · 493 unmodified lines | ||
| 494 | 494 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 495 | 495 | # 447 reserved for memfd_secret |
| 496 | 496 | 448 common process_mrelease sys_process_mrelease |
| 497 | +449 common futex_waitv sys_futex_waitv | |
| @@ -122,7 +122,7 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who) · 121 unmodified lines | ||
| 122 | 122 | if ((sp & 7) || |
| 123 | 123 | copy_to_user((char __user *) sp, &tp->reg_window[window], |
| 124 | 124 | sizeof(struct reg_window32))) { |
| 125 | − force_fatal_sig(SIGILL); | |
| 125 | + force_exit_sig(SIGILL); | |
| 126 | 126 | return; |
| 127 | 127 | } |
| 128 | 128 | } |
| @@ -193,7 +193,7 @@ config X86 · 192 unmodified lines | ||
| 193 | 193 | select HAVE_DYNAMIC_FTRACE_WITH_ARGS if X86_64 |
| 194 | 194 | select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS |
| 195 | 195 | select HAVE_SAMPLE_FTRACE_DIRECT if X86_64 |
| 196 | − select HAVE_SAMPLE_FTRACE_MULTI_DIRECT if X86_64 | |
| 196 | + select HAVE_SAMPLE_FTRACE_DIRECT_MULTI if X86_64 | |
| 197 | 197 | select HAVE_EBPF_JIT |
| 198 | 198 | select HAVE_EFFICIENT_UNALIGNED_ACCESS |
| 199 | 199 | select HAVE_EISA |
| @@ -1932,6 +1932,7 @@ config EFI · 1732 unmodified lines | ||
| 1932 | 1932 | depends on ACPI |
| 1933 | 1933 | select UCS2_STRING |
| 1934 | 1934 | select EFI_RUNTIME_WRAPPERS |
| 1935 | + select ARCH_USE_MEMREMAP_PROT | |
| 1935 | 1936 | help |
| 1936 | 1937 | This enables the kernel to use EFI runtime services that are |
| 1937 | 1938 | available (such as the EFI variable services). |
| @@ -574,6 +574,10 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL) · 573 unmodified lines | ||
| 574 | 574 | ud2 |
| 575 | 575 | 1: |
| 576 | 576 | #endif |
| 577 | +#ifdef CONFIG_XEN_PV | |
| 578 | + ALTERNATIVE "", "jmp xenpv_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV | |
| 579 | +#endif | |
| 580 | + | |
| 577 | 581 | POP_REGS pop_rdi=0 |
| 578 | 582 | |
| 579 | 583 | /* |
| @@ -890,6 +894,7 @@ SYM_CODE_START_LOCAL(paranoid_entry) · 310 unmodified lines | ||
| 890 | 894 | .Lparanoid_entry_checkgs: |
| 891 | 895 | /* EBX = 1 -> kernel GSBASE active, no restore required */ |
| 892 | 896 | movl $1, %ebx |
| 897 | + | |
| 893 | 898 | /* |
| 894 | 899 | * The kernel-enforced convention is a negative GSBASE indicates |
| 895 | 900 | * a kernel value. No SWAPGS needed on entry and exit. |
| @@ -897,21 +902,14 @@ SYM_CODE_START_LOCAL(paranoid_entry) · 1 unmodified line | ||
| 897 | 902 | movl $MSR_GS_BASE, %ecx |
| 898 | 903 | rdmsr |
| 899 | 904 | testl %edx, %edx |
| 900 | − jns .Lparanoid_entry_swapgs | |
| 901 | − ret | |
| 905 | + js .Lparanoid_kernel_gsbase | |
| 902 | 906 | |
| 903 | −.Lparanoid_entry_swapgs: | |
| 907 | + /* EBX = 0 -> SWAPGS required on exit */ | |
| 908 | + xorl %ebx, %ebx | |
| 904 | 909 | swapgs |
| 910 | +.Lparanoid_kernel_gsbase: | |
| 905 | 911 | |
| 906 | − /* | |
| 907 | − * The above SAVE_AND_SWITCH_TO_KERNEL_CR3 macro doesn't do an | |
| 908 | − * unconditional CR3 write, even in the PTI case. So do an lfence | |
| 909 | − * to prevent GS speculation, regardless of whether PTI is enabled. | |
| 910 | − */ | |
| 911 | 912 | FENCE_SWAPGS_KERNEL_ENTRY |
| 912 | − | |
| 913 | − /* EBX = 0 -> SWAPGS required on exit */ | |
| 914 | − xorl %ebx, %ebx | |
| 915 | 913 | ret |
| 916 | 914 | SYM_CODE_END(paranoid_entry) |
| 917 | 915 | |
| @@ -993,11 +991,6 @@ SYM_CODE_START_LOCAL(error_entry) · 75 unmodified lines | ||
| 993 | 991 | pushq %r12 |
| 994 | 992 | ret |
| 995 | 993 | |
| 996 | −.Lerror_entry_done_lfence: | |
| 997 | − FENCE_SWAPGS_KERNEL_ENTRY | |
| 998 | −.Lerror_entry_done: | |
| 999 | − ret | |
| 1000 | − | |
| 1001 | 994 | /* |
| 1002 | 995 | * There are two places in the kernel that can potentially fault with |
| 1003 | 996 | * usergs. Handle them here. B stepping K8s sometimes report a |
| @@ -1020,8 +1013,14 @@ SYM_CODE_START_LOCAL(error_entry) · 16 unmodified lines | ||
| 1020 | 1013 | * .Lgs_change's error handler with kernel gsbase. |
| 1021 | 1014 | */ |
| 1022 | 1015 | SWAPGS |
| 1023 | − FENCE_SWAPGS_USER_ENTRY | |
| 1024 | − jmp .Lerror_entry_done | |
| 1016 | + | |
| 1017 | + /* | |
| 1018 | + * Issue an LFENCE to prevent GS speculation, regardless of whether it is a | |
| 1019 | + * kernel or user gsbase. | |
| 1020 | + */ | |
| 1021 | +.Lerror_entry_done_lfence: | |
| 1022 | + FENCE_SWAPGS_KERNEL_ENTRY | |
| 1023 | + ret | |
| 1025 | 1024 | |
| 1026 | 1025 | .Lbstep_iret: |
| 1027 | 1026 | /* Fix truncated RIP */ |
| @@ -226,7 +226,7 @@ bool emulate_vsyscall(unsigned long error_code, · 225 unmodified lines | ||
| 226 | 226 | if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) { |
| 227 | 227 | warn_bad_vsyscall(KERN_DEBUG, regs, |
| 228 | 228 | "seccomp tried to change syscall nr or ip"); |
| 229 | − force_fatal_sig(SIGSYS); | |
| 229 | + force_exit_sig(SIGSYS); | |
| 230 | 230 | return true; |
| 231 | 231 | } |
| 232 | 232 | regs->orig_ax = -1; |
| @@ -2211,7 +2211,6 @@ intel_pmu_snapshot_branch_stack(struct perf_branch_entry *entries, unsigned int · 2210 unmodified lines | ||
| 2211 | 2211 | /* must not have branches... */ |
| 2212 | 2212 | local_irq_save(flags); |
| 2213 | 2213 | __intel_pmu_disable_all(false); /* we don't care about BTS */ |
| 2214 | − __intel_pmu_pebs_disable_all(); | |
| 2215 | 2214 | __intel_pmu_lbr_disable(); |
| 2216 | 2215 | /* ... until here */ |
| 2217 | 2216 | return __intel_pmu_snapshot_branch_stack(entries, cnt, flags); |
| @@ -2225,7 +2224,6 @@ intel_pmu_snapshot_arch_branch_stack(struct perf_branch_entry *entries, unsigned · 7 unmodified lines | ||
| 2225 | 2224 | /* must not have branches... */ |
| 2226 | 2225 | local_irq_save(flags); |
| 2227 | 2226 | __intel_pmu_disable_all(false); /* we don't care about BTS */ |
| 2228 | − __intel_pmu_pebs_disable_all(); | |
| 2229 | 2227 | __intel_pmu_arch_lbr_disable(); |
| 2230 | 2228 | /* ... until here */ |
| 2231 | 2229 | return __intel_pmu_snapshot_branch_stack(entries, cnt, flags); |
| @@ -3608,6 +3608,9 @@ static int skx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *ev · 3607 unmodified lines | ||
| 3608 | 3608 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; |
| 3609 | 3609 | struct extra_reg *er; |
| 3610 | 3610 | int idx = 0; |
| 3611 | + /* Any of the CHA events may be filtered by Thread/Core-ID.*/ | |
| 3612 | + if (event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN) | |
| 3613 | + idx = SKX_CHA_MSR_PMON_BOX_FILTER_TID; | |
| 3611 | 3614 | |
| 3612 | 3615 | for (er = skx_uncore_cha_extra_regs; er->msr; er++) { |
| 3613 | 3616 | if (er->event != (event->hw.config & er->config_mask)) |
| @@ -3675,6 +3678,7 @@ static struct event_constraint skx_uncore_iio_constraints[] = { · 61 unmodified lines | ||
| 3675 | 3678 | UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), |
| 3676 | 3679 | UNCORE_EVENT_CONSTRAINT(0xc5, 0xc), |
| 3677 | 3680 | UNCORE_EVENT_CONSTRAINT(0xd4, 0xc), |
| 3681 | + UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), | |
| 3678 | 3682 | EVENT_CONSTRAINT_END |
| 3679 | 3683 | }; |
| 3680 | 3684 | |
| @@ -4525,6 +4529,13 @@ static void snr_iio_cleanup_mapping(struct intel_uncore_type *type) · 844 unmodified lines | ||
| 4525 | 4529 | pmu_iio_cleanup_mapping(type, &snr_iio_mapping_group); |
| 4526 | 4530 | } |
| 4527 | 4531 | |
| 4532 | +static struct event_constraint snr_uncore_iio_constraints[] = { | |
| 4533 | + UNCORE_EVENT_CONSTRAINT(0x83, 0x3), | |
| 4534 | + UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), | |
| 4535 | + UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), | |
| 4536 | + EVENT_CONSTRAINT_END | |
| 4537 | +}; | |
| 4538 | + | |
| 4528 | 4539 | static struct intel_uncore_type snr_uncore_iio = { |
| 4529 | 4540 | .name = "iio", |
| 4530 | 4541 | .num_counters = 4, |
| @@ -4536,6 +4547,7 @@ static struct intel_uncore_type snr_uncore_iio = { · 5 unmodified lines | ||
| 4536 | 4547 | .event_mask_ext = SNR_IIO_PMON_RAW_EVENT_MASK_EXT, |
| 4537 | 4548 | .box_ctl = SNR_IIO_MSR_PMON_BOX_CTL, |
| 4538 | 4549 | .msr_offset = SNR_IIO_MSR_OFFSET, |
| 4550 | + .constraints = snr_uncore_iio_constraints, | |
| 4539 | 4551 | .ops = &ivbep_uncore_msr_ops, |
| 4540 | 4552 | .format_group = &snr_uncore_iio_format_group, |
| 4541 | 4553 | .attr_update = snr_iio_attr_update, |
| @@ -177,6 +177,9 @@ void set_hv_tscchange_cb(void (*cb)(void)) · 176 unmodified lines | ||
| 177 | 177 | return; |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | + if (!hv_vp_index) | |
| 181 | + return; | |
| 182 | + | |
| 180 | 183 | hv_reenlightenment_cb = cb; |
| 181 | 184 | |
| 182 | 185 | /* Make sure callback is registered before we write to MSRs */ |
| @@ -383,20 +386,13 @@ static void __init hv_get_partition_id(void) · 200 unmodified lines | ||
| 383 | 386 | */ |
| 384 | 387 | void __init hyperv_init(void) |
| 385 | 388 | { |
| 386 | − u64 guest_id, required_msrs; | |
| 389 | + u64 guest_id; | |
| 387 | 390 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 388 | 391 | int cpuhp; |
| 389 | 392 | |
| 390 | 393 | if (x86_hyper_type != X86_HYPER_MS_HYPERV) |
| 391 | 394 | return; |
| 392 | 395 | |
| 393 | − /* Absolutely required MSRs */ | |
| 394 | − required_msrs = HV_MSR_HYPERCALL_AVAILABLE | | |
| 395 | − HV_MSR_VP_INDEX_AVAILABLE; | |
| 396 | − | |
| 397 | − if ((ms_hyperv.features & required_msrs) != required_msrs) | |
| 398 | − return; | |
| 399 | − | |
| 400 | 396 | if (hv_common_init()) |
| 401 | 397 | return; |
| 402 | 398 | |
| @@ -102,12 +102,6 @@ extern void switch_fpu_return(void); · 101 unmodified lines | ||
| 102 | 102 | */ |
| 103 | 103 | extern int cpu_has_xfeatures(u64 xfeatures_mask, const char **feature_name); |
| 104 | 104 | |
| 105 | −/* | |
| 106 | − * Tasks that are not using SVA have mm->pasid set to zero to note that they | |
| 107 | − * will not have the valid bit set in MSR_IA32_PASID while they are running. | |
| 108 | − */ | |
| 109 | −#define PASID_DISABLED 0 | |
| 110 | − | |
| 111 | 105 | /* Trap handling */ |
| 112 | 106 | extern int fpu__exception_code(struct fpu *fpu, int trap_nr); |
| 113 | 107 | extern void fpu_sync_fpstate(struct fpu *fpu); |
| @@ -108,7 +108,7 @@ · 107 unmodified lines | ||
| 108 | 108 | #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ |
| 109 | 109 | #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ |
| 110 | 110 | |
| 111 | −#define INTEL_FAM6_RAPTOR_LAKE 0xB7 | |
| 111 | +#define INTEL_FAM6_RAPTORLAKE 0xB7 | |
| 112 | 112 | |
| 113 | 113 | /* "Small Core" Processors (Atom) */ |
| 114 | 114 | |
| @@ -97,7 +97,7 @@ · 96 unmodified lines | ||
| 97 | 97 | KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) |
| 98 | 98 | #define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26) |
| 99 | 99 | #define KVM_REQ_TLB_FLUSH_GUEST \ |
| 100 | − KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_NO_WAKEUP) | |
| 100 | + KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) | |
| 101 | 101 | #define KVM_REQ_APF_READY KVM_ARCH_REQ(28) |
| 102 | 102 | #define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29) |
| 103 | 103 | #define KVM_REQ_UPDATE_CPU_DIRTY_LOGGING \ |
| @@ -363,6 +363,7 @@ union kvm_mmu_extended_role { · 259 unmodified lines | ||
| 363 | 363 | unsigned int cr4_smap:1; |
| 364 | 364 | unsigned int cr4_smep:1; |
| 365 | 365 | unsigned int cr4_la57:1; |
| 366 | + unsigned int efer_lma:1; | |
| 366 | 367 | }; |
| 367 | 368 | }; |
| 368 | 369 | |
| @@ -1035,6 +1036,7 @@ struct kvm_x86_msr_filter { · 666 unmodified lines | ||
| 1035 | 1036 | #define APICV_INHIBIT_REASON_PIT_REINJ 4 |
| 1036 | 1037 | #define APICV_INHIBIT_REASON_X2APIC 5 |
| 1037 | 1038 | #define APICV_INHIBIT_REASON_BLOCKIRQ 6 |
| 1039 | +#define APICV_INHIBIT_REASON_ABSENT 7 | |
| 1038 | 1040 | |
| 1039 | 1041 | struct kvm_arch { |
| 1040 | 1042 | unsigned long n_used_mmu_pages; |
| @@ -73,4 +73,15 @@ · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | #define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK) |
| 75 | 75 | |
| 76 | +/* | |
| 77 | + * Error codes related to GHCB input that can be communicated back to the guest | |
| 78 | + * by setting the lower 32-bits of the GHCB SW_EXITINFO1 field to 2. | |
| 79 | + */ | |
| 80 | +#define GHCB_ERR_NOT_REGISTERED 1 | |
| 81 | +#define GHCB_ERR_INVALID_USAGE 2 | |
| 82 | +#define GHCB_ERR_INVALID_SCRATCH_AREA 3 | |
| 83 | +#define GHCB_ERR_MISSING_INPUT 4 | |
| 84 | +#define GHCB_ERR_INVALID_INPUT 5 | |
| 85 | +#define GHCB_ERR_INVALID_EVENT 6 | |
| 86 | + | |
| 76 | 87 | #endif |
| @@ -281,13 +281,13 @@ HYPERVISOR_callback_op(int cmd, void *arg) · 280 unmodified lines | ||
| 281 | 281 | return _hypercall2(int, callback_op, cmd, arg); |
| 282 | 282 | } |
| 283 | 283 | |
| 284 | −static inline int | |
| 284 | +static __always_inline int | |
| 285 | 285 | HYPERVISOR_set_debugreg(int reg, unsigned long value) |
| 286 | 286 | { |
| 287 | 287 | return _hypercall2(int, set_debugreg, reg, value); |
| 288 | 288 | } |
| 289 | 289 | |
| 290 | −static inline unsigned long | |
| 290 | +static __always_inline unsigned long | |
| 291 | 291 | HYPERVISOR_get_debugreg(int reg) |
| 292 | 292 | { |
| 293 | 293 | return _hypercall1(unsigned long, get_debugreg, reg); |
| @@ -64,6 +64,7 @@ void xen_arch_unregister_cpu(int num); · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | #ifdef CONFIG_PVH |
| 66 | 66 | void __init xen_pvh_init(struct boot_params *boot_params); |
| 67 | +void __init mem_map_via_hcall(struct boot_params *boot_params_p); | |
| 67 | 68 | #endif |
| 68 | 69 | |
| 69 | 70 | #endif /* _ASM_X86_XEN_HYPERVISOR_H */ |
| @@ -163,12 +163,22 @@ static uint32_t __init ms_hyperv_platform(void) · 162 unmodified lines | ||
| 163 | 163 | cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, |
| 164 | 164 | &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); |
| 165 | 165 | |
| 166 | − if (eax >= HYPERV_CPUID_MIN && | |
| 167 | − eax <= HYPERV_CPUID_MAX && | |
| 168 | − !memcmp("Microsoft Hv", hyp_signature, 12)) | |
| 169 | − return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS; | |
| 166 | + if (eax < HYPERV_CPUID_MIN || eax > HYPERV_CPUID_MAX || | |
| 167 | + memcmp("Microsoft Hv", hyp_signature, 12)) | |
| 168 | + return 0; | |
| 170 | 169 | |
| 171 | − return 0; | |
| 170 | + /* HYPERCALL and VP_INDEX MSRs are mandatory for all features. */ | |
| 171 | + eax = cpuid_eax(HYPERV_CPUID_FEATURES); | |
| 172 | + if (!(eax & HV_MSR_HYPERCALL_AVAILABLE)) { | |
| 173 | + pr_warn("x86/hyperv: HYPERCALL MSR not available.\n"); | |
| 174 | + return 0; | |
| 175 | + } | |
| 176 | + if (!(eax & HV_MSR_VP_INDEX_AVAILABLE)) { | |
| 177 | + pr_warn("x86/hyperv: VP_INDEX MSR not available.\n"); | |
| 178 | + return 0; | |
| 179 | + } | |
| 180 | + | |
| 181 | + return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS; | |
| 172 | 182 | } |
| 173 | 183 | |
| 174 | 184 | static unsigned char hv_get_nmi_reason(void) |
| @@ -28,8 +28,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ksgxd_waitq); · 27 unmodified lines | ||
| 28 | 28 | static LIST_HEAD(sgx_active_page_list); |
| 29 | 29 | static DEFINE_SPINLOCK(sgx_reclaimer_lock); |
| 30 | 30 | |
| 31 | −/* The free page list lock protected variables prepend the lock. */ | |
| 32 | −static unsigned long sgx_nr_free_pages; | |
| 31 | +static atomic_long_t sgx_nr_free_pages = ATOMIC_LONG_INIT(0); | |
| 33 | 32 | |
| 34 | 33 | /* Nodes with one or more EPC sections. */ |
| 35 | 34 | static nodemask_t sgx_numa_mask; |
| @@ -403,14 +402,15 @@ skip: · 367 unmodified lines | ||
| 403 | 402 | |
| 404 | 403 | spin_lock(&node->lock); |
| 405 | 404 | list_add_tail(&epc_page->list, &node->free_page_list); |
| 406 | − sgx_nr_free_pages++; | |
| 407 | 405 | spin_unlock(&node->lock); |
| 406 | + atomic_long_inc(&sgx_nr_free_pages); | |
| 408 | 407 | } |
| 409 | 408 | } |
| 410 | 409 | |
| 411 | 410 | static bool sgx_should_reclaim(unsigned long watermark) |
| 412 | 411 | { |
| 413 | − return sgx_nr_free_pages < watermark && !list_empty(&sgx_active_page_list); | |
| 412 | + return atomic_long_read(&sgx_nr_free_pages) < watermark && | |
| 413 | + !list_empty(&sgx_active_page_list); | |
| 414 | 414 | } |
| 415 | 415 | |
| 416 | 416 | static int ksgxd(void *p) |
| @@ -471,9 +471,9 @@ static struct sgx_epc_page *__sgx_alloc_epc_page_from_node(int nid) · 54 unmodified lines | ||
| 471 | 471 | |
| 472 | 472 | page = list_first_entry(&node->free_page_list, struct sgx_epc_page, list); |
| 473 | 473 | list_del_init(&page->list); |
| 474 | − sgx_nr_free_pages--; | |
| 475 | 474 | |
| 476 | 475 | spin_unlock(&node->lock); |
| 476 | + atomic_long_dec(&sgx_nr_free_pages); | |
| 477 | 477 | |
| 478 | 478 | return page; |
| 479 | 479 | } |
| @@ -625,9 +625,9 @@ void sgx_free_epc_page(struct sgx_epc_page *page) · 145 unmodified lines | ||
| 625 | 625 | spin_lock(&node->lock); |
| 626 | 626 | |
| 627 | 627 | list_add_tail(&page->list, &node->free_page_list); |
| 628 | − sgx_nr_free_pages++; | |
| 629 | 628 | |
| 630 | 629 | spin_unlock(&node->lock); |
| 630 | + atomic_long_inc(&sgx_nr_free_pages); | |
| 631 | 631 | } |
| 632 | 632 | |
| 633 | 633 | static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size, |
| @@ -118,7 +118,7 @@ static inline bool save_xstate_epilog(void __user *buf, int ia32_frame, · 117 unmodified lines | ||
| 118 | 118 | struct fpstate *fpstate) |
| 119 | 119 | { |
| 120 | 120 | struct xregs_state __user *x = buf; |
| 121 | − struct _fpx_sw_bytes sw_bytes; | |
| 121 | + struct _fpx_sw_bytes sw_bytes = {}; | |
| 122 | 122 | u32 xfeatures; |
| 123 | 123 | int err; |
| 124 | 124 | |
| @@ -964,6 +964,9 @@ unsigned long __get_wchan(struct task_struct *p) · 963 unmodified lines | ||
| 964 | 964 | struct unwind_state state; |
| 965 | 965 | unsigned long addr = 0; |
| 966 | 966 | |
| 967 | + if (!try_get_task_stack(p)) | |
| 968 | + return 0; | |
| 969 | + | |
| 967 | 970 | for (unwind_start(&state, p, NULL, NULL); !unwind_done(&state); |
| 968 | 971 | unwind_next_frame(&state)) { |
| 969 | 972 | addr = unwind_get_return_address(&state); |
| @@ -974,6 +977,8 @@ unsigned long __get_wchan(struct task_struct *p) · 4 unmodified lines | ||
| 974 | 977 | break; |
| 975 | 978 | } |
| 976 | 979 | |
| 980 | + put_task_stack(p); | |
| 981 | + | |
| 977 | 982 | return addr; |
| 978 | 983 | } |
| 979 | 984 | |
| @@ -742,6 +742,28 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) · 741 unmodified lines | ||
| 742 | 742 | return 0; |
| 743 | 743 | } |
| 744 | 744 | |
| 745 | +static char * __init prepare_command_line(void) | |
| 746 | +{ | |
| 747 | +#ifdef CONFIG_CMDLINE_BOOL | |
| 748 | +#ifdef CONFIG_CMDLINE_OVERRIDE | |
| 749 | + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); | |
| 750 | +#else | |
| 751 | + if (builtin_cmdline[0]) { | |
| 752 | + /* append boot loader cmdline to builtin */ | |
| 753 | + strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); | |
| 754 | + strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 755 | + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); | |
| 756 | + } | |
| 757 | +#endif | |
| 758 | +#endif | |
| 759 | + | |
| 760 | + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | |
| 761 | + | |
| 762 | + parse_early_param(); | |
| 763 | + | |
| 764 | + return command_line; | |
| 765 | +} | |
| 766 | + | |
| 745 | 767 | /* |
| 746 | 768 | * Determine if we were loaded by an EFI loader. If so, then we have also been |
| 747 | 769 | * passed the efi memmap, systab, etc., so we should use these data structures |
| @@ -830,6 +852,23 @@ void __init setup_arch(char **cmdline_p) · 82 unmodified lines | ||
| 830 | 852 | |
| 831 | 853 | x86_init.oem.arch_setup(); |
| 832 | 854 | |
| 855 | + /* | |
| 856 | + * x86_configure_nx() is called before parse_early_param() (called by | |
| 857 | + * prepare_command_line()) to detect whether hardware doesn't support | |
| 858 | + * NX (so that the early EHCI debug console setup can safely call | |
| 859 | + * set_fixmap()). It may then be called again from within noexec_setup() | |
| 860 | + * during parsing early parameters to honor the respective command line | |
| 861 | + * option. | |
| 862 | + */ | |
| 863 | + x86_configure_nx(); | |
| 864 | + | |
| 865 | + /* | |
| 866 | + * This parses early params and it needs to run before | |
| 867 | + * early_reserve_memory() because latter relies on such settings | |
| 868 | + * supplied as early params. | |
| 869 | + */ | |
| 870 | + *cmdline_p = prepare_command_line(); | |
| 871 | + | |
| 833 | 872 | /* |
| 834 | 873 | * Do some memory reservations *before* memory is added to memblock, so |
| 835 | 874 | * memblock allocations won't overwrite it. |
| @@ -863,33 +902,6 @@ void __init setup_arch(char **cmdline_p) · 27 unmodified lines | ||
| 863 | 902 | bss_resource.start = __pa_symbol(__bss_start); |
| 864 | 903 | bss_resource.end = __pa_symbol(__bss_stop)-1; |
| 865 | 904 | |
| 866 | −#ifdef CONFIG_CMDLINE_BOOL | |
| 867 | −#ifdef CONFIG_CMDLINE_OVERRIDE | |
| 868 | − strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); | |
| 869 | −#else | |
| 870 | − if (builtin_cmdline[0]) { | |
| 871 | − /* append boot loader cmdline to builtin */ | |
| 872 | − strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); | |
| 873 | − strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 874 | − strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); | |
| 875 | − } | |
| 876 | −#endif | |
| 877 | −#endif | |
| 878 | − | |
| 879 | − strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | |
| 880 | − *cmdline_p = command_line; | |
| 881 | − | |
| 882 | − /* | |
| 883 | − * x86_configure_nx() is called before parse_early_param() to detect | |
| 884 | − * whether hardware doesn't support NX (so that the early EHCI debug | |
| 885 | − * console setup can safely call set_fixmap()). It may then be called | |
| 886 | − * again from within noexec_setup() during parsing early parameters | |
| 887 | − * to honor the respective command line option. | |
| 888 | − */ | |
| 889 | − x86_configure_nx(); | |
| 890 | − | |
| 891 | − parse_early_param(); | |
| 892 | − | |
| 893 | 905 | #ifdef CONFIG_MEMORY_HOTPLUG |
| 894 | 906 | /* |
| 895 | 907 | * Memory used by the kernel cannot be hot-removed because Linux |
| @@ -294,11 +294,6 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, · 293 unmodified lines | ||
| 294 | 294 | char *dst, char *buf, size_t size) |
| 295 | 295 | { |
| 296 | 296 | unsigned long error_code = X86_PF_PROT | X86_PF_WRITE; |
| 297 | − char __user *target = (char __user *)dst; | |
| 298 | − u64 d8; | |
| 299 | − u32 d4; | |
| 300 | − u16 d2; | |
| 301 | − u8 d1; | |
| 302 | 297 | |
| 303 | 298 | /* |
| 304 | 299 | * This function uses __put_user() independent of whether kernel or user |
| @@ -320,26 +315,42 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, · 15 unmodified lines | ||
| 320 | 315 | * instructions here would cause infinite nesting. |
| 321 | 316 | */ |
| 322 | 317 | switch (size) { |
| 323 | − case 1: | |
| 318 | + case 1: { | |
| 319 | + u8 d1; | |
| 320 | + u8 __user *target = (u8 __user *)dst; | |
| 321 | + | |
| 324 | 322 | memcpy(&d1, buf, 1); |
| 325 | 323 | if (__put_user(d1, target)) |
| 326 | 324 | goto fault; |
| 327 | 325 | break; |
| 328 | − case 2: | |
| 326 | + } | |
| 327 | + case 2: { | |
| 328 | + u16 d2; | |
| 329 | + u16 __user *target = (u16 __user *)dst; | |
| 330 | + | |
| 329 | 331 | memcpy(&d2, buf, 2); |
| 330 | 332 | if (__put_user(d2, target)) |
| 331 | 333 | goto fault; |
| 332 | 334 | break; |
| 333 | − case 4: | |
| 335 | + } | |
| 336 | + case 4: { | |
| 337 | + u32 d4; | |
| 338 | + u32 __user *target = (u32 __user *)dst; | |
| 339 | + | |
| 334 | 340 | memcpy(&d4, buf, 4); |
| 335 | 341 | if (__put_user(d4, target)) |
| 336 | 342 | goto fault; |
| 337 | 343 | break; |
| 338 | − case 8: | |
| 344 | + } | |
| 345 | + case 8: { | |
| 346 | + u64 d8; | |
| 347 | + u64 __user *target = (u64 __user *)dst; | |
| 348 | + | |
| 339 | 349 | memcpy(&d8, buf, 8); |
| 340 | 350 | if (__put_user(d8, target)) |
| 341 | 351 | goto fault; |
| 342 | 352 | break; |
| 353 | + } | |
| 343 | 354 | default: |
| 344 | 355 | WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); |
| 345 | 356 | return ES_UNSUPPORTED; |
| @@ -362,11 +373,6 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, · 16 unmodified lines | ||
| 362 | 373 | char *src, char *buf, size_t size) |
| 363 | 374 | { |
| 364 | 375 | unsigned long error_code = X86_PF_PROT; |
| 365 | − char __user *s = (char __user *)src; | |
| 366 | − u64 d8; | |
| 367 | − u32 d4; | |
| 368 | − u16 d2; | |
| 369 | − u8 d1; | |
| 370 | 376 | |
| 371 | 377 | /* |
| 372 | 378 | * This function uses __get_user() independent of whether kernel or user |
| @@ -388,26 +394,41 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, · 15 unmodified lines | ||
| 388 | 394 | * instructions here would cause infinite nesting. |
| 389 | 395 | */ |
| 390 | 396 | switch (size) { |
| 391 | − case 1: | |
| 397 | + case 1: { | |
| 398 | + u8 d1; | |
| 399 | + u8 __user *s = (u8 __user *)src; | |
| 400 | + | |
| 392 | 401 | if (__get_user(d1, s)) |
| 393 | 402 | goto fault; |
| 394 | 403 | memcpy(buf, &d1, 1); |
| 395 | 404 | break; |
| 396 | − case 2: | |
| 405 | + } | |
| 406 | + case 2: { | |
| 407 | + u16 d2; | |
| 408 | + u16 __user *s = (u16 __user *)src; | |
| 409 | + | |
| 397 | 410 | if (__get_user(d2, s)) |
| 398 | 411 | goto fault; |
| 399 | 412 | memcpy(buf, &d2, 2); |
| 400 | 413 | break; |
| 401 | − case 4: | |
| 414 | + } | |
| 415 | + case 4: { | |
| 416 | + u32 d4; | |
| 417 | + u32 __user *s = (u32 __user *)src; | |
| 418 | + | |
| 402 | 419 | if (__get_user(d4, s)) |
| 403 | 420 | goto fault; |
| 404 | 421 | memcpy(buf, &d4, 4); |
| 405 | 422 | break; |
| 406 | − case 8: | |
| 423 | + } | |
| 424 | + case 8: { | |
| 425 | + u64 d8; | |
| 426 | + u64 __user *s = (u64 __user *)src; | |
| 407 | 427 | if (__get_user(d8, s)) |
| 408 | 428 | goto fault; |
| 409 | 429 | memcpy(buf, &d8, 8); |
| 410 | 430 | break; |
| 431 | + } | |
| 411 | 432 | default: |
| 412 | 433 | WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); |
| 413 | 434 | return ES_UNSUPPORTED; |
| @@ -579,6 +579,17 @@ static struct sched_domain_topology_level x86_numa_in_package_topology[] = { · 578 unmodified lines | ||
| 579 | 579 | { NULL, }, |
| 580 | 580 | }; |
| 581 | 581 | |
| 582 | +static struct sched_domain_topology_level x86_hybrid_topology[] = { | |
| 583 | +#ifdef CONFIG_SCHED_SMT | |
| 584 | + { cpu_smt_mask, x86_smt_flags, SD_INIT_NAME(SMT) }, | |
| 585 | +#endif | |
| 586 | +#ifdef CONFIG_SCHED_MC | |
| 587 | + { cpu_coregroup_mask, x86_core_flags, SD_INIT_NAME(MC) }, | |
| 588 | +#endif | |
| 589 | + { cpu_cpu_mask, SD_INIT_NAME(DIE) }, | |
| 590 | + { NULL, }, | |
| 591 | +}; | |
| 592 | + | |
| 582 | 593 | static struct sched_domain_topology_level x86_topology[] = { |
| 583 | 594 | #ifdef CONFIG_SCHED_SMT |
| 584 | 595 | { cpu_smt_mask, x86_smt_flags, SD_INIT_NAME(SMT) }, |
| @@ -1469,8 +1480,11 @@ void __init native_smp_cpus_done(unsigned int max_cpus) · 884 unmodified lines | ||
| 1469 | 1480 | |
| 1470 | 1481 | calculate_max_logical_packages(); |
| 1471 | 1482 | |
| 1483 | + /* XXX for now assume numa-in-package and hybrid don't overlap */ | |
| 1472 | 1484 | if (x86_has_numa_in_package) |
| 1473 | 1485 | set_sched_topology(x86_numa_in_package_topology); |
| 1486 | + if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) | |
| 1487 | + set_sched_topology(x86_hybrid_topology); | |
| 1474 | 1488 | |
| 1475 | 1489 | nmi_selftest(); |
| 1476 | 1490 | impress_friends(); |
| @@ -1180,6 +1180,12 @@ void mark_tsc_unstable(char *reason) · 1179 unmodified lines | ||
| 1180 | 1180 | |
| 1181 | 1181 | EXPORT_SYMBOL_GPL(mark_tsc_unstable); |
| 1182 | 1182 | |
| 1183 | +static void __init tsc_disable_clocksource_watchdog(void) | |
| 1184 | +{ | |
| 1185 | + clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY; | |
| 1186 | + clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; | |
| 1187 | +} | |
| 1188 | + | |
| 1183 | 1189 | static void __init check_system_tsc_reliable(void) |
| 1184 | 1190 | { |
| 1185 | 1191 | #if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC) |
| @@ -1196,6 +1202,23 @@ static void __init check_system_tsc_reliable(void) · 10 unmodified lines | ||
| 1196 | 1202 | #endif |
| 1197 | 1203 | if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) |
| 1198 | 1204 | tsc_clocksource_reliable = 1; |
| 1205 | + | |
| 1206 | + /* | |
| 1207 | + * Disable the clocksource watchdog when the system has: | |
| 1208 | + * - TSC running at constant frequency | |
| 1209 | + * - TSC which does not stop in C-States | |
| 1210 | + * - the TSC_ADJUST register which allows to detect even minimal | |
| 1211 | + * modifications | |
| 1212 | + * - not more than two sockets. As the number of sockets cannot be | |
| 1213 | + * evaluated at the early boot stage where this has to be | |
| 1214 | + * invoked, check the number of online memory nodes as a | |
| 1215 | + * fallback solution which is an reasonable estimate. | |
| 1216 | + */ | |
| 1217 | + if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && | |
| 1218 | + boot_cpu_has(X86_FEATURE_NONSTOP_TSC) && | |
| 1219 | + boot_cpu_has(X86_FEATURE_TSC_ADJUST) && | |
| 1220 | + nr_online_nodes <= 2) | |
| 1221 | + tsc_disable_clocksource_watchdog(); | |
| 1199 | 1222 | } |
| 1200 | 1223 | |
| 1201 | 1224 | /* |
| @@ -1387,9 +1410,6 @@ static int __init init_tsc_clocksource(void) · 185 unmodified lines | ||
| 1387 | 1410 | if (tsc_unstable) |
| 1388 | 1411 | goto unreg; |
| 1389 | 1412 | |
| 1390 | − if (tsc_clocksource_reliable || no_tsc_watchdog) | |
| 1391 | − clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; | |
| 1392 | − | |
| 1393 | 1413 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3)) |
| 1394 | 1414 | clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; |
| 1395 | 1415 | |
| @@ -1527,7 +1547,7 @@ void __init tsc_init(void) · 131 unmodified lines | ||
| 1527 | 1547 | } |
| 1528 | 1548 | |
| 1529 | 1549 | if (tsc_clocksource_reliable || no_tsc_watchdog) |
| 1530 | − clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY; | |
| 1550 | + tsc_disable_clocksource_watchdog(); | |
| 1531 | 1551 | |
| 1532 | 1552 | clocksource_register_khz(&clocksource_tsc_early, tsc_khz); |
| 1533 | 1553 | detect_art(); |
| @@ -30,6 +30,7 @@ struct tsc_adjust { · 29 unmodified lines | ||
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | 32 | static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust); |
| 33 | +static struct timer_list tsc_sync_check_timer; | |
| 33 | 34 | |
| 34 | 35 | /* |
| 35 | 36 | * TSC's on different sockets may be reset asynchronously. |
| @@ -77,6 +78,46 @@ void tsc_verify_tsc_adjust(bool resume) · 41 unmodified lines | ||
| 77 | 78 | } |
| 78 | 79 | } |
| 79 | 80 | |
| 81 | +/* | |
| 82 | + * Normally the tsc_sync will be checked every time system enters idle | |
| 83 | + * state, but there is still caveat that a system won't enter idle, | |
| 84 | + * either because it's too busy or configured purposely to not enter | |
| 85 | + * idle. | |
| 86 | + * | |
| 87 | + * So setup a periodic timer (every 10 minutes) to make sure the check | |
| 88 | + * is always on. | |
| 89 | + */ | |
| 90 | + | |
| 91 | +#define SYNC_CHECK_INTERVAL (HZ * 600) | |
| 92 | + | |
| 93 | +static void tsc_sync_check_timer_fn(struct timer_list *unused) | |
| 94 | +{ | |
| 95 | + int next_cpu; | |
| 96 | + | |
| 97 | + tsc_verify_tsc_adjust(false); | |
| 98 | + | |
| 99 | + /* Run the check for all onlined CPUs in turn */ | |
| 100 | + next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask); | |
| 101 | + if (next_cpu >= nr_cpu_ids) | |
| 102 | + next_cpu = cpumask_first(cpu_online_mask); | |
| 103 | + | |
| 104 | + tsc_sync_check_timer.expires += SYNC_CHECK_INTERVAL; | |
| 105 | + add_timer_on(&tsc_sync_check_timer, next_cpu); | |
| 106 | +} | |
| 107 | + | |
| 108 | +static int __init start_sync_check_timer(void) | |
| 109 | +{ | |
| 110 | + if (!cpu_feature_enabled(X86_FEATURE_TSC_ADJUST) || tsc_clocksource_reliable) | |
| 111 | + return 0; | |
| 112 | + | |
| 113 | + timer_setup(&tsc_sync_check_timer, tsc_sync_check_timer_fn, 0); | |
| 114 | + tsc_sync_check_timer.expires = jiffies + SYNC_CHECK_INTERVAL; | |
| 115 | + add_timer(&tsc_sync_check_timer); | |
| 116 | + | |
| 117 | + return 0; | |
| 118 | +} | |
| 119 | +late_initcall(start_sync_check_timer); | |
| 120 | + | |
| 80 | 121 | static void tsc_sanitize_first_cpu(struct tsc_adjust *cur, s64 bootval, |
| 81 | 122 | unsigned int cpu, bool bootcpu) |
| 82 | 123 | { |
| @@ -160,7 +160,7 @@ Efault_end: · 159 unmodified lines | ||
| 160 | 160 | user_access_end(); |
| 161 | 161 | Efault: |
| 162 | 162 | pr_alert("could not access userspace vm86 info\n"); |
| 163 | − force_fatal_sig(SIGSEGV); | |
| 163 | + force_exit_sig(SIGSEGV); | |
| 164 | 164 | goto exit_vm86; |
| 165 | 165 | } |
| 166 | 166 | |
| @@ -125,7 +125,7 @@ static void kvm_update_kvm_cpuid_base(struct kvm_vcpu *vcpu) · 124 unmodified lines | ||
| 125 | 125 | } |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | −struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu) | |
| 128 | +static struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu) | |
| 129 | 129 | { |
| 130 | 130 | u32 base = vcpu->arch.kvm_cpuid_base; |
| 131 | 131 | |
| @@ -1922,11 +1922,13 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool · 1921 unmodified lines | ||
| 1922 | 1922 | |
| 1923 | 1923 | all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL; |
| 1924 | 1924 | |
| 1925 | + if (all_cpus) | |
| 1926 | + goto check_and_send_ipi; | |
| 1927 | + | |
| 1925 | 1928 | if (!sparse_banks_len) |
| 1926 | 1929 | goto ret_success; |
| 1927 | 1930 | |
| 1928 | − if (!all_cpus && | |
| 1929 | − kvm_read_guest(kvm, | |
| 1931 | + if (kvm_read_guest(kvm, | |
| 1930 | 1932 | hc->ingpa + offsetof(struct hv_send_ipi_ex, |
| 1931 | 1933 | vp_set.bank_contents), |
| 1932 | 1934 | sparse_banks, |
| @@ -1934,6 +1936,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool · 1 unmodified line | ||
| 1934 | 1936 | return HV_STATUS_INVALID_HYPERCALL_INPUT; |
| 1935 | 1937 | } |
| 1936 | 1938 | |
| 1939 | +check_and_send_ipi: | |
| 1937 | 1940 | if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR)) |
| 1938 | 1941 | return HV_STATUS_INVALID_HYPERCALL_INPUT; |
| 1939 | 1942 | |
| @@ -2022,7 +2025,7 @@ static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result) · 82 unmodified lines | ||
| 2022 | 2025 | { |
| 2023 | 2026 | bool longmode; |
| 2024 | 2027 | |
| 2025 | − longmode = is_64_bit_mode(vcpu); | |
| 2028 | + longmode = is_64_bit_hypercall(vcpu); | |
| 2026 | 2029 | if (longmode) |
| 2027 | 2030 | kvm_rax_write(vcpu, result); |
| 2028 | 2031 | else { |
| @@ -2171,7 +2174,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) · 142 unmodified lines | ||
| 2171 | 2174 | } |
| 2172 | 2175 | |
| 2173 | 2176 | #ifdef CONFIG_X86_64 |
| 2174 | − if (is_64_bit_mode(vcpu)) { | |
| 2177 | + if (is_64_bit_hypercall(vcpu)) { | |
| 2175 | 2178 | hc.param = kvm_rcx_read(vcpu); |
| 2176 | 2179 | hc.ingpa = kvm_rdx_read(vcpu); |
| 2177 | 2180 | hc.outgpa = kvm_r8_read(vcpu); |
| @@ -81,7 +81,6 @@ struct kvm_ioapic { · 80 unmodified lines | ||
| 81 | 81 | unsigned long irq_states[IOAPIC_NUM_PINS]; |
| 82 | 82 | struct kvm_io_device dev; |
| 83 | 83 | struct kvm *kvm; |
| 84 | − void (*ack_notifier)(void *opaque, int irq); | |
| 85 | 84 | spinlock_t lock; |
| 86 | 85 | struct rtc_status rtc_status; |
| 87 | 86 | struct delayed_work eoi_inject; |
| @@ -56,7 +56,6 @@ struct kvm_pic { · 55 unmodified lines | ||
| 56 | 56 | struct kvm_io_device dev_master; |
| 57 | 57 | struct kvm_io_device dev_slave; |
| 58 | 58 | struct kvm_io_device dev_elcr; |
| 59 | − void (*ack_notifier)(void *opaque, int irq); | |
| 60 | 59 | unsigned long irq_states[PIC_NUM_PINS]; |
| 61 | 60 | }; |
| 62 | 61 | |
| @@ -707,7 +707,7 @@ static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) · 706 unmodified lines | ||
| 707 | 707 | static int apic_has_interrupt_for_ppr(struct kvm_lapic *apic, u32 ppr) |
| 708 | 708 | { |
| 709 | 709 | int highest_irr; |
| 710 | − if (apic->vcpu->arch.apicv_active) | |
| 710 | + if (kvm_x86_ops.sync_pir_to_irr) | |
| 711 | 711 | highest_irr = static_call(kvm_x86_sync_pir_to_irr)(apic->vcpu); |
| 712 | 712 | else |
| 713 | 713 | highest_irr = apic_find_highest_irr(apic); |
| @@ -1582,7 +1582,7 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) · 1581 unmodified lines | ||
| 1582 | 1582 | flush = kvm_handle_gfn_range(kvm, range, kvm_unmap_rmapp); |
| 1583 | 1583 | |
| 1584 | 1584 | if (is_tdp_mmu_enabled(kvm)) |
| 1585 | − flush |= kvm_tdp_mmu_unmap_gfn_range(kvm, range, flush); | |
| 1585 | + flush = kvm_tdp_mmu_unmap_gfn_range(kvm, range, flush); | |
| 1586 | 1586 | |
| 1587 | 1587 | return flush; |
| 1588 | 1588 | } |
| @@ -1936,7 +1936,11 @@ static void mmu_audit_disable(void) { } · 347 unmodified lines | ||
| 1936 | 1936 | |
| 1937 | 1937 | static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp) |
| 1938 | 1938 | { |
| 1939 | − return sp->role.invalid || | |
| 1939 | + if (sp->role.invalid) | |
| 1940 | + return true; | |
| 1941 | + | |
| 1942 | + /* TDP MMU pages due not use the MMU generation. */ | |
| 1943 | + return !sp->tdp_mmu_page && | |
| 1940 | 1944 | unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen); |
| 1941 | 1945 | } |
| 1942 | 1946 | |
| @@ -2173,10 +2177,10 @@ static void shadow_walk_init_using_root(struct kvm_shadow_walk_iterator *iterato · 230 unmodified lines | ||
| 2173 | 2177 | iterator->shadow_addr = root; |
| 2174 | 2178 | iterator->level = vcpu->arch.mmu->shadow_root_level; |
| 2175 | 2179 | |
| 2176 | − if (iterator->level == PT64_ROOT_4LEVEL && | |
| 2180 | + if (iterator->level >= PT64_ROOT_4LEVEL && | |
| 2177 | 2181 | vcpu->arch.mmu->root_level < PT64_ROOT_4LEVEL && |
| 2178 | 2182 | !vcpu->arch.mmu->direct_map) |
| 2179 | − --iterator->level; | |
| 2183 | + iterator->level = PT32E_ROOT_LEVEL; | |
| 2180 | 2184 | |
| 2181 | 2185 | if (iterator->level == PT32E_ROOT_LEVEL) { |
| 2182 | 2186 | /* |
| @@ -3976,6 +3980,20 @@ out_retry: · 1793 unmodified lines | ||
| 3976 | 3980 | return true; |
| 3977 | 3981 | } |
| 3978 | 3982 | |
| 3983 | +/* | |
| 3984 | + * Returns true if the page fault is stale and needs to be retried, i.e. if the | |
| 3985 | + * root was invalidated by a memslot update or a relevant mmu_notifier fired. | |
| 3986 | + */ | |
| 3987 | +static bool is_page_fault_stale(struct kvm_vcpu *vcpu, | |
| 3988 | + struct kvm_page_fault *fault, int mmu_seq) | |
| 3989 | +{ | |
| 3990 | + if (is_obsolete_sp(vcpu->kvm, to_shadow_page(vcpu->arch.mmu->root_hpa))) | |
| 3991 | + return true; | |
| 3992 | + | |
| 3993 | + return fault->slot && | |
| 3994 | + mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva); | |
| 3995 | +} | |
| 3996 | + | |
| 3979 | 3997 | static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) |
| 3980 | 3998 | { |
| 3981 | 3999 | bool is_tdp_mmu_fault = is_tdp_mmu(vcpu->arch.mmu); |
| @@ -4013,8 +4031,9 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault · 31 unmodified lines | ||
| 4013 | 4031 | else |
| 4014 | 4032 | write_lock(&vcpu->kvm->mmu_lock); |
| 4015 | 4033 | |
| 4016 | − if (fault->slot && mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva)) | |
| 4034 | + if (is_page_fault_stale(vcpu, fault, mmu_seq)) | |
| 4017 | 4035 | goto out_unlock; |
| 4036 | + | |
| 4018 | 4037 | r = make_mmu_pages_available(vcpu); |
| 4019 | 4038 | if (r) |
| 4020 | 4039 | goto out_unlock; |
| @@ -4682,6 +4701,7 @@ static union kvm_mmu_extended_role kvm_calc_mmu_role_ext(struct kvm_vcpu *vcpu, · 661 unmodified lines | ||
| 4682 | 4701 | /* PKEY and LA57 are active iff long mode is active. */ |
| 4683 | 4702 | ext.cr4_pke = ____is_efer_lma(regs) && ____is_cr4_pke(regs); |
| 4684 | 4703 | ext.cr4_la57 = ____is_efer_lma(regs) && ____is_cr4_la57(regs); |
| 4704 | + ext.efer_lma = ____is_efer_lma(regs); | |
| 4685 | 4705 | } |
| 4686 | 4706 | |
| 4687 | 4707 | ext.valid = 1; |
| @@ -4854,7 +4874,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, · 166 unmodified lines | ||
| 4854 | 4874 | struct kvm_mmu *context = &vcpu->arch.guest_mmu; |
| 4855 | 4875 | struct kvm_mmu_role_regs regs = { |
| 4856 | 4876 | .cr0 = cr0, |
| 4857 | − .cr4 = cr4, | |
| 4877 | + .cr4 = cr4 & ~X86_CR4_PKE, | |
| 4858 | 4878 | .efer = efer, |
| 4859 | 4879 | }; |
| 4860 | 4880 | union kvm_mmu_role new_role; |
| @@ -4918,7 +4938,7 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly, · 57 unmodified lines | ||
| 4918 | 4938 | context->direct_map = false; |
| 4919 | 4939 | |
| 4920 | 4940 | update_permission_bitmask(context, true); |
| 4921 | − update_pkru_bitmask(context); | |
| 4941 | + context->pkru_mask = 0; | |
| 4922 | 4942 | reset_rsvds_bits_mask_ept(vcpu, context, execonly); |
| 4923 | 4943 | reset_ept_shadow_zero_bits_mask(vcpu, context, execonly); |
| 4924 | 4944 | } |
| @@ -5024,6 +5044,14 @@ void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu) · 99 unmodified lines | ||
| 5024 | 5044 | /* |
| 5025 | 5045 | * Invalidate all MMU roles to force them to reinitialize as CPUID |
| 5026 | 5046 | * information is factored into reserved bit calculations. |
| 5047 | + * | |
| 5048 | + * Correctly handling multiple vCPU models with respect to paging and | |
| 5049 | + * physical address properties) in a single VM would require tracking | |
| 5050 | + * all relevant CPUID information in kvm_mmu_page_role. That is very | |
| 5051 | + * undesirable as it would increase the memory requirements for | |
| 5052 | + * gfn_track (see struct kvm_mmu_page_role comments). For now that | |
| 5053 | + * problem is swept under the rug; KVM's CPUID API is horrific and | |
| 5054 | + * it's all but impossible to solve it without introducing a new API. | |
| 5027 | 5055 | */ |
| 5028 | 5056 | vcpu->arch.root_mmu.mmu_role.ext.valid = 0; |
| 5029 | 5057 | vcpu->arch.guest_mmu.mmu_role.ext.valid = 0; |
| @@ -5031,24 +5059,10 @@ void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 5031 | 5059 | kvm_mmu_reset_context(vcpu); |
| 5032 | 5060 | |
| 5033 | 5061 | /* |
| 5034 | − * KVM does not correctly handle changing guest CPUID after KVM_RUN, as | |
| 5035 | − * MAXPHYADDR, GBPAGES support, AMD reserved bit behavior, etc.. aren't | |
| 5036 | − * tracked in kvm_mmu_page_role. As a result, KVM may miss guest page | |
| 5037 | − * faults due to reusing SPs/SPTEs. Alert userspace, but otherwise | |
| 5038 | − * sweep the problem under the rug. | |
| 5039 | − * | |
| 5040 | − * KVM's horrific CPUID ABI makes the problem all but impossible to | |
| 5041 | − * solve, as correctly handling multiple vCPU models (with respect to | |
| 5042 | − * paging and physical address properties) in a single VM would require | |
| 5043 | − * tracking all relevant CPUID information in kvm_mmu_page_role. That | |
| 5044 | − * is very undesirable as it would double the memory requirements for | |
| 5045 | − * gfn_track (see struct kvm_mmu_page_role comments), and in practice | |
| 5046 | − * no sane VMM mucks with the core vCPU model on the fly. | |
| 5062 | + * Changing guest CPUID after KVM_RUN is forbidden, see the comment in | |
| 5063 | + * kvm_arch_vcpu_ioctl(). | |
| 5047 | 5064 | */ |
| 5048 | − if (vcpu->arch.last_vmentry_cpu != -1) { | |
| 5049 | − pr_warn_ratelimited("KVM: KVM_SET_CPUID{,2} after KVM_RUN may cause guest instability\n"); | |
| 5050 | − pr_warn_ratelimited("KVM: KVM_SET_CPUID{,2} will fail after KVM_RUN starting with Linux 5.16\n"); | |
| 5051 | − } | |
| 5065 | + KVM_BUG_ON(vcpu->arch.last_vmentry_cpu != -1, vcpu->kvm); | |
| 5052 | 5066 | } |
| 5053 | 5067 | |
| 5054 | 5068 | void kvm_mmu_reset_context(struct kvm_vcpu *vcpu) |
| @@ -5368,7 +5382,7 @@ void kvm_mmu_invalidate_gva(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, · 313 unmodified lines | ||
| 5368 | 5382 | |
| 5369 | 5383 | void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva) |
| 5370 | 5384 | { |
| 5371 | − kvm_mmu_invalidate_gva(vcpu, vcpu->arch.mmu, gva, INVALID_PAGE); | |
| 5385 | + kvm_mmu_invalidate_gva(vcpu, vcpu->arch.walk_mmu, gva, INVALID_PAGE); | |
| 5372 | 5386 | ++vcpu->stat.invlpg; |
| 5373 | 5387 | } |
| 5374 | 5388 | EXPORT_SYMBOL_GPL(kvm_mmu_invlpg); |
| @@ -5853,8 +5867,6 @@ restart: · 478 unmodified lines | ||
| 5853 | 5867 | void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, |
| 5854 | 5868 | const struct kvm_memory_slot *slot) |
| 5855 | 5869 | { |
| 5856 | − bool flush = false; | |
| 5857 | − | |
| 5858 | 5870 | if (kvm_memslots_have_rmaps(kvm)) { |
| 5859 | 5871 | write_lock(&kvm->mmu_lock); |
| 5860 | 5872 | /* |
| @@ -5862,17 +5874,14 @@ void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, · 1 unmodified line | ||
| 5862 | 5874 | * logging at a 4k granularity and never creates collapsible |
| 5863 | 5875 | * 2m SPTEs during dirty logging. |
| 5864 | 5876 | */ |
| 5865 | − flush = slot_handle_level_4k(kvm, slot, kvm_mmu_zap_collapsible_spte, true); | |
| 5866 | − if (flush) | |
| 5877 | + if (slot_handle_level_4k(kvm, slot, kvm_mmu_zap_collapsible_spte, true)) | |
| 5867 | 5878 | kvm_arch_flush_remote_tlbs_memslot(kvm, slot); |
| 5868 | 5879 | write_unlock(&kvm->mmu_lock); |
| 5869 | 5880 | } |
| 5870 | 5881 | |
| 5871 | 5882 | if (is_tdp_mmu_enabled(kvm)) { |
| 5872 | 5883 | read_lock(&kvm->mmu_lock); |
| 5873 | − flush = kvm_tdp_mmu_zap_collapsible_sptes(kvm, slot, flush); | |
| 5874 | − if (flush) | |
| 5875 | − kvm_arch_flush_remote_tlbs_memslot(kvm, slot); | |
| 5884 | + kvm_tdp_mmu_zap_collapsible_sptes(kvm, slot); | |
| 5876 | 5885 | read_unlock(&kvm->mmu_lock); |
| 5877 | 5886 | } |
| 5878 | 5887 | } |
| @@ -6181,23 +6190,46 @@ void kvm_mmu_module_exit(void) · 302 unmodified lines | ||
| 6181 | 6190 | mmu_audit_disable(); |
| 6182 | 6191 | } |
| 6183 | 6192 | |
| 6193 | +/* | |
| 6194 | + * Calculate the effective recovery period, accounting for '0' meaning "let KVM | |
| 6195 | + * select a halving time of 1 hour". Returns true if recovery is enabled. | |
| 6196 | + */ | |
| 6197 | +static bool calc_nx_huge_pages_recovery_period(uint *period) | |
| 6198 | +{ | |
| 6199 | + /* | |
| 6200 | + * Use READ_ONCE to get the params, this may be called outside of the | |
| 6201 | + * param setters, e.g. by the kthread to compute its next timeout. | |
| 6202 | + */ | |
| 6203 | + bool enabled = READ_ONCE(nx_huge_pages); | |
| 6204 | + uint ratio = READ_ONCE(nx_huge_pages_recovery_ratio); | |
| 6205 | + | |
| 6206 | + if (!enabled || !ratio) | |
| 6207 | + return false; | |
| 6208 | + | |
| 6209 | + *period = READ_ONCE(nx_huge_pages_recovery_period_ms); | |
| 6210 | + if (!*period) { | |
| 6211 | + /* Make sure the period is not less than one second. */ | |
| 6212 | + ratio = min(ratio, 3600u); | |
| 6213 | + *period = 60 * 60 * 1000 / ratio; | |
| 6214 | + } | |
| 6215 | + return true; | |
| 6216 | +} | |
| 6217 | + | |
| 6184 | 6218 | static int set_nx_huge_pages_recovery_param(const char *val, const struct kernel_param *kp) |
| 6185 | 6219 | { |
| 6186 | 6220 | bool was_recovery_enabled, is_recovery_enabled; |
| 6187 | 6221 | uint old_period, new_period; |
| 6188 | 6222 | int err; |
| 6189 | 6223 | |
| 6190 | − was_recovery_enabled = nx_huge_pages_recovery_ratio; | |
| 6191 | − old_period = nx_huge_pages_recovery_period_ms; | |
| 6224 | + was_recovery_enabled = calc_nx_huge_pages_recovery_period(&old_period); | |
| 6192 | 6225 | |
| 6193 | 6226 | err = param_set_uint(val, kp); |
| 6194 | 6227 | if (err) |
| 6195 | 6228 | return err; |
| 6196 | 6229 | |
| 6197 | − is_recovery_enabled = nx_huge_pages_recovery_ratio; | |
| 6198 | − new_period = nx_huge_pages_recovery_period_ms; | |
| 6230 | + is_recovery_enabled = calc_nx_huge_pages_recovery_period(&new_period); | |
| 6199 | 6231 | |
| 6200 | − if (READ_ONCE(nx_huge_pages) && is_recovery_enabled && | |
| 6232 | + if (is_recovery_enabled && | |
| 6201 | 6233 | (!was_recovery_enabled || old_period > new_period)) { |
| 6202 | 6234 | struct kvm *kvm; |
| 6203 | 6235 | |
| @@ -6261,18 +6293,13 @@ static void kvm_recover_nx_lpages(struct kvm *kvm) · 57 unmodified lines | ||
| 6261 | 6293 | |
| 6262 | 6294 | static long get_nx_lpage_recovery_timeout(u64 start_time) |
| 6263 | 6295 | { |
| 6264 | − uint ratio = READ_ONCE(nx_huge_pages_recovery_ratio); | |
| 6265 | − uint period = READ_ONCE(nx_huge_pages_recovery_period_ms); | |
| 6296 | + bool enabled; | |
| 6297 | + uint period; | |
| 6266 | 6298 | |
| 6267 | − if (!period && ratio) { | |
| 6268 | − /* Make sure the period is not less than one second. */ | |
| 6269 | − ratio = min(ratio, 3600u); | |
| 6270 | − period = 60 * 60 * 1000 / ratio; | |
| 6271 | − } | |
| 6299 | + enabled = calc_nx_huge_pages_recovery_period(&period); | |
| 6272 | 6300 | |
| 6273 | − return READ_ONCE(nx_huge_pages) && ratio | |
| 6274 | − ? start_time + msecs_to_jiffies(period) - get_jiffies_64() | |
| 6275 | − : MAX_SCHEDULE_TIMEOUT; | |
| 6301 | + return enabled ? start_time + msecs_to_jiffies(period) - get_jiffies_64() | |
| 6302 | + : MAX_SCHEDULE_TIMEOUT; | |
| 6276 | 6303 | } |
| 6277 | 6304 | |
| 6278 | 6305 | static int kvm_nx_lpage_recovery_worker(struct kvm *kvm, uintptr_t data) |
| @@ -911,7 +911,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault · 910 unmodified lines | ||
| 911 | 911 | |
| 912 | 912 | r = RET_PF_RETRY; |
| 913 | 913 | write_lock(&vcpu->kvm->mmu_lock); |
| 914 | − if (fault->slot && mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva)) | |
| 914 | + | |
| 915 | + if (is_page_fault_stale(vcpu, fault, mmu_seq)) | |
| 915 | 916 | goto out_unlock; |
| 916 | 917 | |
| 917 | 918 | kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT); |
| @@ -317,9 +317,6 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt, · 316 unmodified lines | ||
| 317 | 317 | struct kvm_mmu_page *sp = sptep_to_sp(rcu_dereference(pt)); |
| 318 | 318 | int level = sp->role.level; |
| 319 | 319 | gfn_t base_gfn = sp->gfn; |
| 320 | − u64 old_child_spte; | |
| 321 | − u64 *sptep; | |
| 322 | − gfn_t gfn; | |
| 323 | 320 | int i; |
| 324 | 321 | |
| 325 | 322 | trace_kvm_mmu_prepare_zap_page(sp); |
| @@ -327,8 +324,9 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt, · 1 unmodified line | ||
| 327 | 324 | tdp_mmu_unlink_page(kvm, sp, shared); |
| 328 | 325 | |
| 329 | 326 | for (i = 0; i < PT64_ENT_PER_PAGE; i++) { |
| 330 | − sptep = rcu_dereference(pt) + i; | |
| 331 | − gfn = base_gfn + i * KVM_PAGES_PER_HPAGE(level); | |
| 327 | + u64 *sptep = rcu_dereference(pt) + i; | |
| 328 | + gfn_t gfn = base_gfn + i * KVM_PAGES_PER_HPAGE(level); | |
| 329 | + u64 old_child_spte; | |
| 332 | 330 | |
| 333 | 331 | if (shared) { |
| 334 | 332 | /* |
| @@ -374,7 +372,7 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt, · 39 unmodified lines | ||
| 374 | 372 | shared); |
| 375 | 373 | } |
| 376 | 374 | |
| 377 | − kvm_flush_remote_tlbs_with_address(kvm, gfn, | |
| 375 | + kvm_flush_remote_tlbs_with_address(kvm, base_gfn, | |
| 378 | 376 | KVM_PAGES_PER_HPAGE(level + 1)); |
| 379 | 377 | |
| 380 | 378 | call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback); |
| @@ -1033,9 +1031,9 @@ bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range, · 652 unmodified lines | ||
| 1033 | 1031 | { |
| 1034 | 1032 | struct kvm_mmu_page *root; |
| 1035 | 1033 | |
| 1036 | − for_each_tdp_mmu_root(kvm, root, range->slot->as_id) | |
| 1037 | − flush |= zap_gfn_range(kvm, root, range->start, range->end, | |
| 1038 | − range->may_block, flush, false); | |
| 1034 | + for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id, false) | |
| 1035 | + flush = zap_gfn_range(kvm, root, range->start, range->end, | |
| 1036 | + range->may_block, flush, false); | |
| 1039 | 1037 | |
| 1040 | 1038 | return flush; |
| 1041 | 1039 | } |
| @@ -1364,10 +1362,9 @@ void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm, · 322 unmodified lines | ||
| 1364 | 1362 | * Clear leaf entries which could be replaced by large mappings, for |
| 1365 | 1363 | * GFNs within the slot. |
| 1366 | 1364 | */ |
| 1367 | −static bool zap_collapsible_spte_range(struct kvm *kvm, | |
| 1365 | +static void zap_collapsible_spte_range(struct kvm *kvm, | |
| 1368 | 1366 | struct kvm_mmu_page *root, |
| 1369 | − const struct kvm_memory_slot *slot, | |
| 1370 | − bool flush) | |
| 1367 | + const struct kvm_memory_slot *slot) | |
| 1371 | 1368 | { |
| 1372 | 1369 | gfn_t start = slot->base_gfn; |
| 1373 | 1370 | gfn_t end = start + slot->npages; |
| @@ -1378,10 +1375,8 @@ static bool zap_collapsible_spte_range(struct kvm *kvm, · 4 unmodified lines | ||
| 1378 | 1375 | |
| 1379 | 1376 | tdp_root_for_each_pte(iter, root, start, end) { |
| 1380 | 1377 | retry: |
| 1381 | − if (tdp_mmu_iter_cond_resched(kvm, &iter, flush, true)) { | |
| 1382 | − flush = false; | |
| 1378 | + if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true)) | |
| 1383 | 1379 | continue; |
| 1384 | − } | |
| 1385 | 1380 | |
| 1386 | 1381 | if (!is_shadow_present_pte(iter.old_spte) || |
| 1387 | 1382 | !is_last_spte(iter.old_spte, iter.level)) |
| @@ -1393,6 +1388,7 @@ retry: · 5 unmodified lines | ||
| 1393 | 1388 | pfn, PG_LEVEL_NUM)) |
| 1394 | 1389 | continue; |
| 1395 | 1390 | |
| 1391 | + /* Note, a successful atomic zap also does a remote TLB flush. */ | |
| 1396 | 1392 | if (!tdp_mmu_zap_spte_atomic(kvm, &iter)) { |
| 1397 | 1393 | /* |
| 1398 | 1394 | * The iter must explicitly re-read the SPTE because |
| @@ -1401,30 +1397,24 @@ retry: · 2 unmodified lines | ||
| 1401 | 1397 | iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep)); |
| 1402 | 1398 | goto retry; |
| 1403 | 1399 | } |
| 1404 | − flush = true; | |
| 1405 | 1400 | } |
| 1406 | 1401 | |
| 1407 | 1402 | rcu_read_unlock(); |
| 1408 | − | |
| 1409 | − return flush; | |
| 1410 | 1403 | } |
| 1411 | 1404 | |
| 1412 | 1405 | /* |
| 1413 | 1406 | * Clear non-leaf entries (and free associated page tables) which could |
| 1414 | 1407 | * be replaced by large mappings, for GFNs within the slot. |
| 1415 | 1408 | */ |
| 1416 | −bool kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, | |
| 1417 | − const struct kvm_memory_slot *slot, | |
| 1418 | − bool flush) | |
| 1409 | +void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, | |
| 1410 | + const struct kvm_memory_slot *slot) | |
| 1419 | 1411 | { |
| 1420 | 1412 | struct kvm_mmu_page *root; |
| 1421 | 1413 | |
| 1422 | 1414 | lockdep_assert_held_read(&kvm->mmu_lock); |
| 1423 | 1415 | |
| 1424 | 1416 | for_each_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true) |
| 1425 | − flush = zap_collapsible_spte_range(kvm, root, slot, flush); | |
| 1426 | − | |
| 1427 | − return flush; | |
| 1417 | + zap_collapsible_spte_range(kvm, root, slot); | |
| 1428 | 1418 | } |
| 1429 | 1419 | |
| 1430 | 1420 | /* |
| @@ -64,9 +64,8 @@ void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm, · 63 unmodified lines | ||
| 64 | 64 | struct kvm_memory_slot *slot, |
| 65 | 65 | gfn_t gfn, unsigned long mask, |
| 66 | 66 | bool wrprot); |
| 67 | −bool kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, | |
| 68 | − const struct kvm_memory_slot *slot, | |
| 69 | − bool flush); | |
| 67 | +void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, | |
| 68 | + const struct kvm_memory_slot *slot); | |
| 70 | 69 | |
| 71 | 70 | bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, |
| 72 | 71 | struct kvm_memory_slot *slot, gfn_t gfn, |
| @@ -900,6 +900,7 @@ out: · 899 unmodified lines | ||
| 900 | 900 | bool svm_check_apicv_inhibit_reasons(ulong bit) |
| 901 | 901 | { |
| 902 | 902 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | |
| 903 | + BIT(APICV_INHIBIT_REASON_ABSENT) | | |
| 903 | 904 | BIT(APICV_INHIBIT_REASON_HYPERV) | |
| 904 | 905 | BIT(APICV_INHIBIT_REASON_NESTED) | |
| 905 | 906 | BIT(APICV_INHIBIT_REASON_IRQWIN) | |
| @@ -989,16 +990,18 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu) · 83 unmodified lines | ||
| 989 | 990 | static void avic_set_running(struct kvm_vcpu *vcpu, bool is_run) |
| 990 | 991 | { |
| 991 | 992 | struct vcpu_svm *svm = to_svm(vcpu); |
| 993 | + int cpu = get_cpu(); | |
| 992 | 994 | |
| 995 | + WARN_ON(cpu != vcpu->cpu); | |
| 993 | 996 | svm->avic_is_running = is_run; |
| 994 | 997 | |
| 995 | − if (!kvm_vcpu_apicv_active(vcpu)) | |
| 996 | − return; | |
| 997 | − | |
| 998 | − if (is_run) | |
| 999 | − avic_vcpu_load(vcpu, vcpu->cpu); | |
| 1000 | − else | |
| 1001 | − avic_vcpu_put(vcpu); | |
| 998 | + if (kvm_vcpu_apicv_active(vcpu)) { | |
| 999 | + if (is_run) | |
| 1000 | + avic_vcpu_load(vcpu, cpu); | |
| 1001 | + else | |
| 1002 | + avic_vcpu_put(vcpu); | |
| 1003 | + } | |
| 1004 | + put_cpu(); | |
| 1002 | 1005 | } |
| 1003 | 1006 | |
| 1004 | 1007 | void svm_vcpu_blocking(struct kvm_vcpu *vcpu) |
| @@ -281,7 +281,7 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu) · 280 unmodified lines | ||
| 281 | 281 | pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS; |
| 282 | 282 | |
| 283 | 283 | pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1; |
| 284 | − pmu->reserved_bits = 0xffffffff00200000ull; | |
| 284 | + pmu->reserved_bits = 0xfffffff000280000ull; | |
| 285 | 285 | pmu->version = 1; |
| 286 | 286 | /* not applicable to AMD; but clean them to prevent any fall out */ |
| 287 | 287 | pmu->counter_bitmask[KVM_PMC_FIXED] = 0; |
| @@ -237,7 +237,6 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) · 236 unmodified lines | ||
| 237 | 237 | static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) |
| 238 | 238 | { |
| 239 | 239 | struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; |
| 240 | − bool es_active = argp->id == KVM_SEV_ES_INIT; | |
| 241 | 240 | int asid, ret; |
| 242 | 241 | |
| 243 | 242 | if (kvm->created_vcpus) |
| @@ -247,7 +246,8 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) · 3 unmodified lines | ||
| 247 | 246 | if (unlikely(sev->active)) |
| 248 | 247 | return ret; |
| 249 | 248 | |
| 250 | − sev->es_active = es_active; | |
| 249 | + sev->active = true; | |
| 250 | + sev->es_active = argp->id == KVM_SEV_ES_INIT; | |
| 251 | 251 | asid = sev_asid_new(sev); |
| 252 | 252 | if (asid < 0) |
| 253 | 253 | goto e_no_asid; |
| @@ -257,8 +257,6 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) · 3 unmodified lines | ||
| 257 | 257 | if (ret) |
| 258 | 258 | goto e_free; |
| 259 | 259 | |
| 260 | − sev->active = true; | |
| 261 | − sev->asid = asid; | |
| 262 | 260 | INIT_LIST_HEAD(&sev->regions_list); |
| 263 | 261 | |
| 264 | 262 | return 0; |
| @@ -268,6 +266,7 @@ e_free: · 3 unmodified lines | ||
| 268 | 266 | sev->asid = 0; |
| 269 | 267 | e_no_asid: |
| 270 | 268 | sev->es_active = false; |
| 269 | + sev->active = false; | |
| 271 | 270 | return ret; |
| 272 | 271 | } |
| 273 | 272 | |
| @@ -1530,7 +1529,7 @@ static int sev_receive_finish(struct kvm *kvm, struct kvm_sev_cmd *argp) · 1256 unmodified lines | ||
| 1530 | 1529 | return sev_issue_cmd(kvm, SEV_CMD_RECEIVE_FINISH, &data, &argp->error); |
| 1531 | 1530 | } |
| 1532 | 1531 | |
| 1533 | −static bool cmd_allowed_from_miror(u32 cmd_id) | |
| 1532 | +static bool is_cmd_allowed_from_mirror(u32 cmd_id) | |
| 1534 | 1533 | { |
| 1535 | 1534 | /* |
| 1536 | 1535 | * Allow mirrors VM to call KVM_SEV_LAUNCH_UPDATE_VMSA to enable SEV-ES |
| @@ -1544,28 +1543,50 @@ static bool cmd_allowed_from_miror(u32 cmd_id) · 7 unmodified lines | ||
| 1544 | 1543 | return false; |
| 1545 | 1544 | } |
| 1546 | 1545 | |
| 1547 | −static int sev_lock_for_migration(struct kvm *kvm) | |
| 1546 | +static int sev_lock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm) | |
| 1548 | 1547 | { |
| 1549 | − struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; | |
| 1548 | + struct kvm_sev_info *dst_sev = &to_kvm_svm(dst_kvm)->sev_info; | |
| 1549 | + struct kvm_sev_info *src_sev = &to_kvm_svm(src_kvm)->sev_info; | |
| 1550 | + int r = -EBUSY; | |
| 1551 | + | |
| 1552 | + if (dst_kvm == src_kvm) | |
| 1553 | + return -EINVAL; | |
| 1550 | 1554 | |
| 1551 | 1555 | /* |
| 1552 | − * Bail if this VM is already involved in a migration to avoid deadlock | |
| 1553 | − * between two VMs trying to migrate to/from each other. | |
| 1556 | + * Bail if these VMs are already involved in a migration to avoid | |
| 1557 | + * deadlock between two VMs trying to migrate to/from each other. | |
| 1554 | 1558 | */ |
| 1555 | − if (atomic_cmpxchg_acquire(&sev->migration_in_progress, 0, 1)) | |
| 1559 | + if (atomic_cmpxchg_acquire(&dst_sev->migration_in_progress, 0, 1)) | |
| 1556 | 1560 | return -EBUSY; |
| 1557 | 1561 | |
| 1558 | − mutex_lock(&kvm->lock); | |
| 1562 | + if (atomic_cmpxchg_acquire(&src_sev->migration_in_progress, 0, 1)) | |
| 1563 | + goto release_dst; | |
| 1559 | 1564 | |
| 1565 | + r = -EINTR; | |
| 1566 | + if (mutex_lock_killable(&dst_kvm->lock)) | |
| 1567 | + goto release_src; | |
| 1568 | + if (mutex_lock_killable(&src_kvm->lock)) | |
| 1569 | + goto unlock_dst; | |
| 1560 | 1570 | return 0; |
| 1571 | + | |
| 1572 | +unlock_dst: | |
| 1573 | + mutex_unlock(&dst_kvm->lock); | |
| 1574 | +release_src: | |
| 1575 | + atomic_set_release(&src_sev->migration_in_progress, 0); | |
| 1576 | +release_dst: | |
| 1577 | + atomic_set_release(&dst_sev->migration_in_progress, 0); | |
| 1578 | + return r; | |
| 1561 | 1579 | } |
| 1562 | 1580 | |
| 1563 | −static void sev_unlock_after_migration(struct kvm *kvm) | |
| 1581 | +static void sev_unlock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm) | |
| 1564 | 1582 | { |
| 1565 | − struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; | |
| 1583 | + struct kvm_sev_info *dst_sev = &to_kvm_svm(dst_kvm)->sev_info; | |
| 1584 | + struct kvm_sev_info *src_sev = &to_kvm_svm(src_kvm)->sev_info; | |
| 1566 | 1585 | |
| 1567 | − mutex_unlock(&kvm->lock); | |
| 1568 | − atomic_set_release(&sev->migration_in_progress, 0); | |
| 1586 | + mutex_unlock(&dst_kvm->lock); | |
| 1587 | + mutex_unlock(&src_kvm->lock); | |
| 1588 | + atomic_set_release(&dst_sev->migration_in_progress, 0); | |
| 1589 | + atomic_set_release(&src_sev->migration_in_progress, 0); | |
| 1569 | 1590 | } |
| 1570 | 1591 | |
| 1571 | 1592 | |
| @@ -1608,14 +1629,15 @@ static void sev_migrate_from(struct kvm_sev_info *dst, · 36 unmodified lines | ||
| 1608 | 1629 | dst->asid = src->asid; |
| 1609 | 1630 | dst->handle = src->handle; |
| 1610 | 1631 | dst->pages_locked = src->pages_locked; |
| 1632 | + dst->enc_context_owner = src->enc_context_owner; | |
| 1611 | 1633 | |
| 1612 | 1634 | src->asid = 0; |
| 1613 | 1635 | src->active = false; |
| 1614 | 1636 | src->handle = 0; |
| 1615 | 1637 | src->pages_locked = 0; |
| 1638 | + src->enc_context_owner = NULL; | |
| 1616 | 1639 | |
| 1617 | − INIT_LIST_HEAD(&dst->regions_list); | |
| 1618 | − list_replace_init(&src->regions_list, &dst->regions_list); | |
| 1640 | + list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list); | |
| 1619 | 1641 | } |
| 1620 | 1642 | |
| 1621 | 1643 | static int sev_es_migrate_from(struct kvm *dst, struct kvm *src) |
| @@ -1667,15 +1689,6 @@ int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd) · 45 unmodified lines | ||
| 1667 | 1689 | bool charged = false; |
| 1668 | 1690 | int ret; |
| 1669 | 1691 | |
| 1670 | − ret = sev_lock_for_migration(kvm); | |
| 1671 | − if (ret) | |
| 1672 | − return ret; | |
| 1673 | − | |
| 1674 | − if (sev_guest(kvm)) { | |
| 1675 | − ret = -EINVAL; | |
| 1676 | − goto out_unlock; | |
| 1677 | − } | |
| 1678 | − | |
| 1679 | 1692 | source_kvm_file = fget(source_fd); |
| 1680 | 1693 | if (!file_is_kvm(source_kvm_file)) { |
| 1681 | 1694 | ret = -EBADF; |
| @@ -1683,16 +1696,26 @@ int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd) · 1 unmodified line | ||
| 1683 | 1696 | } |
| 1684 | 1697 | |
| 1685 | 1698 | source_kvm = source_kvm_file->private_data; |
| 1686 | − ret = sev_lock_for_migration(source_kvm); | |
| 1699 | + ret = sev_lock_two_vms(kvm, source_kvm); | |
| 1687 | 1700 | if (ret) |
| 1688 | 1701 | goto out_fput; |
| 1689 | 1702 | |
| 1690 | − if (!sev_guest(source_kvm)) { | |
| 1703 | + if (sev_guest(kvm) || !sev_guest(source_kvm)) { | |
| 1691 | 1704 | ret = -EINVAL; |
| 1692 | − goto out_source; | |
| 1705 | + goto out_unlock; | |
| 1693 | 1706 | } |
| 1694 | 1707 | |
| 1695 | 1708 | src_sev = &to_kvm_svm(source_kvm)->sev_info; |
| 1709 | + | |
| 1710 | + /* | |
| 1711 | + * VMs mirroring src's encryption context rely on it to keep the | |
| 1712 | + * ASID allocated, but below we are clearing src_sev->asid. | |
| 1713 | + */ | |
| 1714 | + if (src_sev->num_mirrored_vms) { | |
| 1715 | + ret = -EBUSY; | |
| 1716 | + goto out_unlock; | |
| 1717 | + } | |
| 1718 | + | |
| 1696 | 1719 | dst_sev->misc_cg = get_current_misc_cg(); |
| 1697 | 1720 | cg_cleanup_sev = dst_sev; |
| 1698 | 1721 | if (dst_sev->misc_cg != src_sev->misc_cg) { |
| @@ -1729,13 +1752,11 @@ out_dst_cgroup: · 30 unmodified lines | ||
| 1729 | 1752 | sev_misc_cg_uncharge(cg_cleanup_sev); |
| 1730 | 1753 | put_misc_cg(cg_cleanup_sev->misc_cg); |
| 1731 | 1754 | cg_cleanup_sev->misc_cg = NULL; |
| 1732 | −out_source: | |
| 1733 | − sev_unlock_after_migration(source_kvm); | |
| 1755 | +out_unlock: | |
| 1756 | + sev_unlock_two_vms(kvm, source_kvm); | |
| 1734 | 1757 | out_fput: |
| 1735 | 1758 | if (source_kvm_file) |
| 1736 | 1759 | fput(source_kvm_file); |
| 1737 | −out_unlock: | |
| 1738 | − sev_unlock_after_migration(kvm); | |
| 1739 | 1760 | return ret; |
| 1740 | 1761 | } |
| 1741 | 1762 | |
| @@ -1757,7 +1778,7 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp) · 15 unmodified lines | ||
| 1757 | 1778 | |
| 1758 | 1779 | /* Only the enc_context_owner handles some memory enc operations. */ |
| 1759 | 1780 | if (is_mirroring_enc_context(kvm) && |
| 1760 | − !cmd_allowed_from_miror(sev_cmd.id)) { | |
| 1781 | + !is_cmd_allowed_from_mirror(sev_cmd.id)) { | |
| 1761 | 1782 | r = -EINVAL; |
| 1762 | 1783 | goto out; |
| 1763 | 1784 | } |
| @@ -1954,71 +1975,60 @@ int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd) · 190 unmodified lines | ||
| 1954 | 1975 | { |
| 1955 | 1976 | struct file *source_kvm_file; |
| 1956 | 1977 | struct kvm *source_kvm; |
| 1957 | − struct kvm_sev_info source_sev, *mirror_sev; | |
| 1978 | + struct kvm_sev_info *source_sev, *mirror_sev; | |
| 1958 | 1979 | int ret; |
| 1959 | 1980 | |
| 1960 | 1981 | source_kvm_file = fget(source_fd); |
| 1961 | 1982 | if (!file_is_kvm(source_kvm_file)) { |
| 1962 | 1983 | ret = -EBADF; |
| 1963 | − goto e_source_put; | |
| 1984 | + goto e_source_fput; | |
| 1964 | 1985 | } |
| 1965 | 1986 | |
| 1966 | 1987 | source_kvm = source_kvm_file->private_data; |
| 1967 | − mutex_lock(&source_kvm->lock); | |
| 1968 | − | |
| 1969 | − if (!sev_guest(source_kvm)) { | |
| 1970 | − ret = -EINVAL; | |
| 1971 | − goto e_source_unlock; | |
| 1972 | − } | |
| 1988 | + ret = sev_lock_two_vms(kvm, source_kvm); | |
| 1989 | + if (ret) | |
| 1990 | + goto e_source_fput; | |
| 1973 | 1991 | |
| 1974 | − /* Mirrors of mirrors should work, but let's not get silly */ | |
| 1975 | − if (is_mirroring_enc_context(source_kvm) || source_kvm == kvm) { | |
| 1992 | + /* | |
| 1993 | + * Mirrors of mirrors should work, but let's not get silly. Also | |
| 1994 | + * disallow out-of-band SEV/SEV-ES init if the target is already an | |
| 1995 | + * SEV guest, or if vCPUs have been created. KVM relies on vCPUs being | |
| 1996 | + * created after SEV/SEV-ES initialization, e.g. to init intercepts. | |
| 1997 | + */ | |
| 1998 | + if (sev_guest(kvm) || !sev_guest(source_kvm) || | |
| 1999 | + is_mirroring_enc_context(source_kvm) || kvm->created_vcpus) { | |
| 1976 | 2000 | ret = -EINVAL; |
| 1977 | − goto e_source_unlock; | |
| 2001 | + goto e_unlock; | |
| 1978 | 2002 | } |
| 1979 | 2003 | |
| 1980 | − memcpy(&source_sev, &to_kvm_svm(source_kvm)->sev_info, | |
| 1981 | − sizeof(source_sev)); | |
| 1982 | − | |
| 1983 | 2004 | /* |
| 1984 | 2005 | * The mirror kvm holds an enc_context_owner ref so its asid can't |
| 1985 | 2006 | * disappear until we're done with it |
| 1986 | 2007 | */ |
| 2008 | + source_sev = &to_kvm_svm(source_kvm)->sev_info; | |
| 1987 | 2009 | kvm_get_kvm(source_kvm); |
| 1988 | − | |
| 1989 | − fput(source_kvm_file); | |
| 1990 | − mutex_unlock(&source_kvm->lock); | |
| 1991 | − mutex_lock(&kvm->lock); | |
| 1992 | − | |
| 1993 | − if (sev_guest(kvm)) { | |
| 1994 | − ret = -EINVAL; | |
| 1995 | − goto e_mirror_unlock; | |
| 1996 | − } | |
| 2010 | + source_sev->num_mirrored_vms++; | |
| 1997 | 2011 | |
| 1998 | 2012 | /* Set enc_context_owner and copy its encryption context over */ |
| 1999 | 2013 | mirror_sev = &to_kvm_svm(kvm)->sev_info; |
| 2000 | 2014 | mirror_sev->enc_context_owner = source_kvm; |
| 2001 | 2015 | mirror_sev->active = true; |
| 2002 | − mirror_sev->asid = source_sev.asid; | |
| 2003 | − mirror_sev->fd = source_sev.fd; | |
| 2004 | − mirror_sev->es_active = source_sev.es_active; | |
| 2005 | − mirror_sev->handle = source_sev.handle; | |
| 2016 | + mirror_sev->asid = source_sev->asid; | |
| 2017 | + mirror_sev->fd = source_sev->fd; | |
| 2018 | + mirror_sev->es_active = source_sev->es_active; | |
| 2019 | + mirror_sev->handle = source_sev->handle; | |
| 2020 | + INIT_LIST_HEAD(&mirror_sev->regions_list); | |
| 2021 | + ret = 0; | |
| 2022 | + | |
| 2006 | 2023 | /* |
| 2007 | 2024 | * Do not copy ap_jump_table. Since the mirror does not share the same |
| 2008 | 2025 | * KVM contexts as the original, and they may have different |
| 2009 | 2026 | * memory-views. |
| 2010 | 2027 | */ |
| 2011 | 2028 | |
| 2012 | − mutex_unlock(&kvm->lock); | |
| 2013 | − return 0; | |
| 2014 | − | |
| 2015 | −e_mirror_unlock: | |
| 2016 | − mutex_unlock(&kvm->lock); | |
| 2017 | − kvm_put_kvm(source_kvm); | |
| 2018 | − return ret; | |
| 2019 | −e_source_unlock: | |
| 2020 | − mutex_unlock(&source_kvm->lock); | |
| 2021 | −e_source_put: | |
| 2029 | +e_unlock: | |
| 2030 | + sev_unlock_two_vms(kvm, source_kvm); | |
| 2031 | +e_source_fput: | |
| 2022 | 2032 | if (source_kvm_file) |
| 2023 | 2033 | fput(source_kvm_file); |
| 2024 | 2034 | return ret; |
| @@ -2030,17 +2040,24 @@ void sev_vm_destroy(struct kvm *kvm) · 5 unmodified lines | ||
| 2030 | 2040 | struct list_head *head = &sev->regions_list; |
| 2031 | 2041 | struct list_head *pos, *q; |
| 2032 | 2042 | |
| 2043 | + WARN_ON(sev->num_mirrored_vms); | |
| 2044 | + | |
| 2033 | 2045 | if (!sev_guest(kvm)) |
| 2034 | 2046 | return; |
| 2035 | 2047 | |
| 2036 | 2048 | /* If this is a mirror_kvm release the enc_context_owner and skip sev cleanup */ |
| 2037 | 2049 | if (is_mirroring_enc_context(kvm)) { |
| 2038 | − kvm_put_kvm(sev->enc_context_owner); | |
| 2050 | + struct kvm *owner_kvm = sev->enc_context_owner; | |
| 2051 | + struct kvm_sev_info *owner_sev = &to_kvm_svm(owner_kvm)->sev_info; | |
| 2052 | + | |
| 2053 | + mutex_lock(&owner_kvm->lock); | |
| 2054 | + if (!WARN_ON(!owner_sev->num_mirrored_vms)) | |
| 2055 | + owner_sev->num_mirrored_vms--; | |
| 2056 | + mutex_unlock(&owner_kvm->lock); | |
| 2057 | + kvm_put_kvm(owner_kvm); | |
| 2039 | 2058 | return; |
| 2040 | 2059 | } |
| 2041 | 2060 | |
| 2042 | − mutex_lock(&kvm->lock); | |
| 2043 | − | |
| 2044 | 2061 | /* |
| 2045 | 2062 | * Ensure that all guest tagged cache entries are flushed before |
| 2046 | 2063 | * releasing the pages back to the system for use. CLFLUSH will |
| @@ -2060,8 +2077,6 @@ void sev_vm_destroy(struct kvm *kvm) · 13 unmodified lines | ||
| 2060 | 2077 | } |
| 2061 | 2078 | } |
| 2062 | 2079 | |
| 2063 | − mutex_unlock(&kvm->lock); | |
| 2064 | − | |
| 2065 | 2080 | sev_unbind_asid(kvm, sev->handle); |
| 2066 | 2081 | sev_asid_free(sev); |
| 2067 | 2082 | } |
| @@ -2245,7 +2260,7 @@ void sev_free_vcpu(struct kvm_vcpu *vcpu) · 177 unmodified lines | ||
| 2245 | 2260 | __free_page(virt_to_page(svm->sev_es.vmsa)); |
| 2246 | 2261 | |
| 2247 | 2262 | if (svm->sev_es.ghcb_sa_free) |
| 2248 | − kfree(svm->sev_es.ghcb_sa); | |
| 2263 | + kvfree(svm->sev_es.ghcb_sa); | |
| 2249 | 2264 | } |
| 2250 | 2265 | |
| 2251 | 2266 | static void dump_ghcb(struct vcpu_svm *svm) |
| @@ -2337,24 +2352,29 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) · 85 unmodified lines | ||
| 2337 | 2352 | memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); |
| 2338 | 2353 | } |
| 2339 | 2354 | |
| 2340 | −static int sev_es_validate_vmgexit(struct vcpu_svm *svm) | |
| 2355 | +static bool sev_es_validate_vmgexit(struct vcpu_svm *svm) | |
| 2341 | 2356 | { |
| 2342 | 2357 | struct kvm_vcpu *vcpu; |
| 2343 | 2358 | struct ghcb *ghcb; |
| 2344 | − u64 exit_code = 0; | |
| 2359 | + u64 exit_code; | |
| 2360 | + u64 reason; | |
| 2345 | 2361 | |
| 2346 | 2362 | ghcb = svm->sev_es.ghcb; |
| 2347 | 2363 | |
| 2348 | − /* Only GHCB Usage code 0 is supported */ | |
| 2349 | − if (ghcb->ghcb_usage) | |
| 2350 | − goto vmgexit_err; | |
| 2351 | − | |
| 2352 | 2364 | /* |
| 2353 | − * Retrieve the exit code now even though is may not be marked valid | |
| 2365 | + * Retrieve the exit code now even though it may not be marked valid | |
| 2354 | 2366 | * as it could help with debugging. |
| 2355 | 2367 | */ |
| 2356 | 2368 | exit_code = ghcb_get_sw_exit_code(ghcb); |
| 2357 | 2369 | |
| 2370 | + /* Only GHCB Usage code 0 is supported */ | |
| 2371 | + if (ghcb->ghcb_usage) { | |
| 2372 | + reason = GHCB_ERR_INVALID_USAGE; | |
| 2373 | + goto vmgexit_err; | |
| 2374 | + } | |
| 2375 | + | |
| 2376 | + reason = GHCB_ERR_MISSING_INPUT; | |
| 2377 | + | |
| 2358 | 2378 | if (!ghcb_sw_exit_code_is_valid(ghcb) || |
| 2359 | 2379 | !ghcb_sw_exit_info_1_is_valid(ghcb) || |
| 2360 | 2380 | !ghcb_sw_exit_info_2_is_valid(ghcb)) |
| @@ -2433,30 +2453,34 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) · 72 unmodified lines | ||
| 2433 | 2453 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: |
| 2434 | 2454 | break; |
| 2435 | 2455 | default: |
| 2456 | + reason = GHCB_ERR_INVALID_EVENT; | |
| 2436 | 2457 | goto vmgexit_err; |
| 2437 | 2458 | } |
| 2438 | 2459 | |
| 2439 | − return 0; | |
| 2460 | + return true; | |
| 2440 | 2461 | |
| 2441 | 2462 | vmgexit_err: |
| 2442 | 2463 | vcpu = &svm->vcpu; |
| 2443 | 2464 | |
| 2444 | − if (ghcb->ghcb_usage) { | |
| 2465 | + if (reason == GHCB_ERR_INVALID_USAGE) { | |
| 2445 | 2466 | vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n", |
| 2446 | 2467 | ghcb->ghcb_usage); |
| 2468 | + } else if (reason == GHCB_ERR_INVALID_EVENT) { | |
| 2469 | + vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is not valid\n", | |
| 2470 | + exit_code); | |
| 2447 | 2471 | } else { |
| 2448 | − vcpu_unimpl(vcpu, "vmgexit: exit reason %#llx is not valid\n", | |
| 2472 | + vcpu_unimpl(vcpu, "vmgexit: exit code %#llx input is not valid\n", | |
| 2449 | 2473 | exit_code); |
| 2450 | 2474 | dump_ghcb(svm); |
| 2451 | 2475 | } |
| 2452 | 2476 | |
| 2453 | − vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | |
| 2454 | − vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; | |
| 2455 | − vcpu->run->internal.ndata = 2; | |
| 2456 | − vcpu->run->internal.data[0] = exit_code; | |
| 2457 | − vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; | |
| 2477 | + /* Clear the valid entries fields */ | |
| 2478 | + memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); | |
| 2479 | + | |
| 2480 | + ghcb_set_sw_exit_info_1(ghcb, 2); | |
| 2481 | + ghcb_set_sw_exit_info_2(ghcb, reason); | |
| 2458 | 2482 | |
| 2459 | − return -EINVAL; | |
| 2483 | + return false; | |
| 2460 | 2484 | } |
| 2461 | 2485 | |
| 2462 | 2486 | void sev_es_unmap_ghcb(struct vcpu_svm *svm) |
| @@ -2478,7 +2502,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm) · 15 unmodified lines | ||
| 2478 | 2502 | svm->sev_es.ghcb_sa_sync = false; |
| 2479 | 2503 | } |
| 2480 | 2504 | |
| 2481 | − kfree(svm->sev_es.ghcb_sa); | |
| 2505 | + kvfree(svm->sev_es.ghcb_sa); | |
| 2482 | 2506 | svm->sev_es.ghcb_sa = NULL; |
| 2483 | 2507 | svm->sev_es.ghcb_sa_free = false; |
| 2484 | 2508 | } |
| @@ -2526,14 +2550,14 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 41 unmodified lines | ||
| 2526 | 2550 | scratch_gpa_beg = ghcb_get_sw_scratch(ghcb); |
| 2527 | 2551 | if (!scratch_gpa_beg) { |
| 2528 | 2552 | pr_err("vmgexit: scratch gpa not provided\n"); |
| 2529 | − return false; | |
| 2553 | + goto e_scratch; | |
| 2530 | 2554 | } |
| 2531 | 2555 | |
| 2532 | 2556 | scratch_gpa_end = scratch_gpa_beg + len; |
| 2533 | 2557 | if (scratch_gpa_end < scratch_gpa_beg) { |
| 2534 | 2558 | pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n", |
| 2535 | 2559 | len, scratch_gpa_beg); |
| 2536 | − return false; | |
| 2560 | + goto e_scratch; | |
| 2537 | 2561 | } |
| 2538 | 2562 | |
| 2539 | 2563 | if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) { |
| @@ -2551,7 +2575,7 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 11 unmodified lines | ||
| 2551 | 2575 | scratch_gpa_end > ghcb_scratch_end) { |
| 2552 | 2576 | pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n", |
| 2553 | 2577 | scratch_gpa_beg, scratch_gpa_end); |
| 2554 | − return false; | |
| 2578 | + goto e_scratch; | |
| 2555 | 2579 | } |
| 2556 | 2580 | |
| 2557 | 2581 | scratch_va = (void *)svm->sev_es.ghcb; |
| @@ -2564,18 +2588,18 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 6 unmodified lines | ||
| 2564 | 2588 | if (len > GHCB_SCRATCH_AREA_LIMIT) { |
| 2565 | 2589 | pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n", |
| 2566 | 2590 | len, GHCB_SCRATCH_AREA_LIMIT); |
| 2567 | − return false; | |
| 2591 | + goto e_scratch; | |
| 2568 | 2592 | } |
| 2569 | − scratch_va = kzalloc(len, GFP_KERNEL_ACCOUNT); | |
| 2593 | + scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT); | |
| 2570 | 2594 | if (!scratch_va) |
| 2571 | − return false; | |
| 2595 | + goto e_scratch; | |
| 2572 | 2596 | |
| 2573 | 2597 | if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) { |
| 2574 | 2598 | /* Unable to copy scratch area from guest */ |
| 2575 | 2599 | pr_err("vmgexit: kvm_read_guest for scratch area failed\n"); |
| 2576 | 2600 | |
| 2577 | − kfree(scratch_va); | |
| 2578 | − return false; | |
| 2601 | + kvfree(scratch_va); | |
| 2602 | + goto e_scratch; | |
| 2579 | 2603 | } |
| 2580 | 2604 | |
| 2581 | 2605 | /* |
| @@ -2592,6 +2616,12 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 10 unmodified lines | ||
| 2592 | 2616 | svm->sev_es.ghcb_sa_len = len; |
| 2593 | 2617 | |
| 2594 | 2618 | return true; |
| 2619 | + | |
| 2620 | +e_scratch: | |
| 2621 | + ghcb_set_sw_exit_info_1(ghcb, 2); | |
| 2622 | + ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_SCRATCH_AREA); | |
| 2623 | + | |
| 2624 | + return false; | |
| 2595 | 2625 | } |
| 2596 | 2626 | |
| 2597 | 2627 | static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask, |
| @@ -2642,7 +2672,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) · 44 unmodified lines | ||
| 2642 | 2672 | |
| 2643 | 2673 | ret = svm_invoke_exit_handler(vcpu, SVM_EXIT_CPUID); |
| 2644 | 2674 | if (!ret) { |
| 2645 | − ret = -EINVAL; | |
| 2675 | + /* Error, keep GHCB MSR value as-is */ | |
| 2646 | 2676 | break; |
| 2647 | 2677 | } |
| 2648 | 2678 | |
| @@ -2678,10 +2708,13 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) · 29 unmodified lines | ||
| 2678 | 2708 | GHCB_MSR_TERM_REASON_POS); |
| 2679 | 2709 | pr_info("SEV-ES guest requested termination: %#llx:%#llx\n", |
| 2680 | 2710 | reason_set, reason_code); |
| 2681 | − fallthrough; | |
| 2711 | + | |
| 2712 | + ret = -EINVAL; | |
| 2713 | + break; | |
| 2682 | 2714 | } |
| 2683 | 2715 | default: |
| 2684 | − ret = -EINVAL; | |
| 2716 | + /* Error, keep GHCB MSR value as-is */ | |
| 2717 | + break; | |
| 2685 | 2718 | } |
| 2686 | 2719 | |
| 2687 | 2720 | trace_kvm_vmgexit_msr_protocol_exit(svm->vcpu.vcpu_id, |
| @@ -2705,14 +2738,18 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 17 unmodified lines | ||
| 2705 | 2738 | |
| 2706 | 2739 | if (!ghcb_gpa) { |
| 2707 | 2740 | vcpu_unimpl(vcpu, "vmgexit: GHCB gpa is not set\n"); |
| 2708 | − return -EINVAL; | |
| 2741 | + | |
| 2742 | + /* Without a GHCB, just return right back to the guest */ | |
| 2743 | + return 1; | |
| 2709 | 2744 | } |
| 2710 | 2745 | |
| 2711 | 2746 | if (kvm_vcpu_map(vcpu, ghcb_gpa >> PAGE_SHIFT, &svm->sev_es.ghcb_map)) { |
| 2712 | 2747 | /* Unable to map GHCB from guest */ |
| 2713 | 2748 | vcpu_unimpl(vcpu, "vmgexit: error mapping GHCB [%#llx] from guest\n", |
| 2714 | 2749 | ghcb_gpa); |
| 2715 | − return -EINVAL; | |
| 2750 | + | |
| 2751 | + /* Without a GHCB, just return right back to the guest */ | |
| 2752 | + return 1; | |
| 2716 | 2753 | } |
| 2717 | 2754 | |
| 2718 | 2755 | svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva; |
| @@ -2722,15 +2759,14 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 2722 | 2759 | |
| 2723 | 2760 | exit_code = ghcb_get_sw_exit_code(ghcb); |
| 2724 | 2761 | |
| 2725 | − ret = sev_es_validate_vmgexit(svm); | |
| 2726 | − if (ret) | |
| 2727 | − return ret; | |
| 2762 | + if (!sev_es_validate_vmgexit(svm)) | |
| 2763 | + return 1; | |
| 2728 | 2764 | |
| 2729 | 2765 | sev_es_sync_from_ghcb(svm); |
| 2730 | 2766 | ghcb_set_sw_exit_info_1(ghcb, 0); |
| 2731 | 2767 | ghcb_set_sw_exit_info_2(ghcb, 0); |
| 2732 | 2768 | |
| 2733 | − ret = -EINVAL; | |
| 2769 | + ret = 1; | |
| 2734 | 2770 | switch (exit_code) { |
| 2735 | 2771 | case SVM_VMGEXIT_MMIO_READ: |
| 2736 | 2772 | if (!setup_vmgexit_scratch(svm, true, control->exit_info_2)) |
| @@ -2771,20 +2807,17 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 34 unmodified lines | ||
| 2771 | 2807 | default: |
| 2772 | 2808 | pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n", |
| 2773 | 2809 | control->exit_info_1); |
| 2774 | − ghcb_set_sw_exit_info_1(ghcb, 1); | |
| 2775 | − ghcb_set_sw_exit_info_2(ghcb, | |
| 2776 | − X86_TRAP_UD | | |
| 2777 | − SVM_EVTINJ_TYPE_EXEPT | | |
| 2778 | − SVM_EVTINJ_VALID); | |
| 2810 | + ghcb_set_sw_exit_info_1(ghcb, 2); | |
| 2811 | + ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_INPUT); | |
| 2779 | 2812 | } |
| 2780 | 2813 | |
| 2781 | − ret = 1; | |
| 2782 | 2814 | break; |
| 2783 | 2815 | } |
| 2784 | 2816 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: |
| 2785 | 2817 | vcpu_unimpl(vcpu, |
| 2786 | 2818 | "vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n", |
| 2787 | 2819 | control->exit_info_1, control->exit_info_2); |
| 2820 | + ret = -EINVAL; | |
| 2788 | 2821 | break; |
| 2789 | 2822 | default: |
| 2790 | 2823 | ret = svm_invoke_exit_handler(vcpu, exit_code); |
| @@ -2806,7 +2839,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) · 15 unmodified lines | ||
| 2806 | 2839 | return -EINVAL; |
| 2807 | 2840 | |
| 2808 | 2841 | if (!setup_vmgexit_scratch(svm, in, bytes)) |
| 2809 | − return -EINVAL; | |
| 2842 | + return 1; | |
| 2810 | 2843 | |
| 2811 | 2844 | return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->sev_es.ghcb_sa, |
| 2812 | 2845 | count, in); |
| @@ -4651,7 +4651,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { · 4650 unmodified lines | ||
| 4651 | 4651 | .load_eoi_exitmap = svm_load_eoi_exitmap, |
| 4652 | 4652 | .hwapic_irr_update = svm_hwapic_irr_update, |
| 4653 | 4653 | .hwapic_isr_update = svm_hwapic_isr_update, |
| 4654 | − .sync_pir_to_irr = kvm_lapic_find_highest_irr, | |
| 4655 | 4654 | .apicv_post_state_restore = avic_post_state_restore, |
| 4656 | 4655 | |
| 4657 | 4656 | .set_tss_addr = svm_set_tss_addr, |
| @@ -79,6 +79,7 @@ struct kvm_sev_info { · 78 unmodified lines | ||
| 79 | 79 | struct list_head regions_list; /* List of registered regions */ |
| 80 | 80 | u64 ap_jump_table; /* SEV-ES AP Jump Table address */ |
| 81 | 81 | struct kvm *enc_context_owner; /* Owner of copied encryption context */ |
| 82 | + unsigned long num_mirrored_vms; /* Number of VMs sharing this ASID */ | |
| 82 | 83 | struct misc_cg *misc_cg; /* For misc cgroup accounting */ |
| 83 | 84 | atomic_t migration_in_progress; |
| 84 | 85 | }; |
| @@ -247,7 +248,7 @@ static __always_inline bool sev_es_guest(struct kvm *kvm) · 162 unmodified lines | ||
| 247 | 248 | #ifdef CONFIG_KVM_AMD_SEV |
| 248 | 249 | struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; |
| 249 | 250 | |
| 250 | − return sev_guest(kvm) && sev->es_active; | |
| 251 | + return sev->es_active && !WARN_ON_ONCE(!sev->active); | |
| 251 | 252 | #else |
| 252 | 253 | return false; |
| 253 | 254 | #endif |
| @@ -670,33 +670,39 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, · 669 unmodified lines | ||
| 670 | 670 | static void nested_cache_shadow_vmcs12(struct kvm_vcpu *vcpu, |
| 671 | 671 | struct vmcs12 *vmcs12) |
| 672 | 672 | { |
| 673 | − struct kvm_host_map map; | |
| 674 | − struct vmcs12 *shadow; | |
| 673 | + struct vcpu_vmx *vmx = to_vmx(vcpu); | |
| 674 | + struct gfn_to_hva_cache *ghc = &vmx->nested.shadow_vmcs12_cache; | |
| 675 | 675 | |
| 676 | 676 | if (!nested_cpu_has_shadow_vmcs(vmcs12) || |
| 677 | 677 | vmcs12->vmcs_link_pointer == INVALID_GPA) |
| 678 | 678 | return; |
| 679 | 679 | |
| 680 | − shadow = get_shadow_vmcs12(vcpu); | |
| 681 | − | |
| 682 | − if (kvm_vcpu_map(vcpu, gpa_to_gfn(vmcs12->vmcs_link_pointer), &map)) | |
| 680 | + if (ghc->gpa != vmcs12->vmcs_link_pointer && | |
| 681 | + kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, | |
| 682 | + vmcs12->vmcs_link_pointer, VMCS12_SIZE)) | |
| 683 | 683 | return; |
| 684 | 684 | |
| 685 | − memcpy(shadow, map.hva, VMCS12_SIZE); | |
| 686 | − kvm_vcpu_unmap(vcpu, &map, false); | |
| 685 | + kvm_read_guest_cached(vmx->vcpu.kvm, ghc, get_shadow_vmcs12(vcpu), | |
| 686 | + VMCS12_SIZE); | |
| 687 | 687 | } |
| 688 | 688 | |
| 689 | 689 | static void nested_flush_cached_shadow_vmcs12(struct kvm_vcpu *vcpu, |
| 690 | 690 | struct vmcs12 *vmcs12) |
| 691 | 691 | { |
| 692 | 692 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 693 | + struct gfn_to_hva_cache *ghc = &vmx->nested.shadow_vmcs12_cache; | |
| 693 | 694 | |
| 694 | 695 | if (!nested_cpu_has_shadow_vmcs(vmcs12) || |
| 695 | 696 | vmcs12->vmcs_link_pointer == INVALID_GPA) |
| 696 | 697 | return; |
| 697 | 698 | |
| 698 | − kvm_write_guest(vmx->vcpu.kvm, vmcs12->vmcs_link_pointer, | |
| 699 | − get_shadow_vmcs12(vcpu), VMCS12_SIZE); | |
| 699 | + if (ghc->gpa != vmcs12->vmcs_link_pointer && | |
| 700 | + kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, | |
| 701 | + vmcs12->vmcs_link_pointer, VMCS12_SIZE)) | |
| 702 | + return; | |
| 703 | + | |
| 704 | + kvm_write_guest_cached(vmx->vcpu.kvm, ghc, get_shadow_vmcs12(vcpu), | |
| 705 | + VMCS12_SIZE); | |
| 700 | 706 | } |
| 701 | 707 | |
| 702 | 708 | /* |
| @@ -1156,29 +1162,26 @@ static void nested_vmx_transition_tlb_flush(struct kvm_vcpu *vcpu, · 453 unmodified lines | ||
| 1156 | 1162 | WARN_ON(!enable_vpid); |
| 1157 | 1163 | |
| 1158 | 1164 | /* |
| 1159 | − * If VPID is enabled and used by vmc12, but L2 does not have a unique | |
| 1160 | − * TLB tag (ASID), i.e. EPT is disabled and KVM was unable to allocate | |
| 1161 | − * a VPID for L2, flush the current context as the effective ASID is | |
| 1162 | − * common to both L1 and L2. | |
| 1163 | − * | |
| 1164 | − * Defer the flush so that it runs after vmcs02.EPTP has been set by | |
| 1165 | − * KVM_REQ_LOAD_MMU_PGD (if nested EPT is enabled) and to avoid | |
| 1166 | − * redundant flushes further down the nested pipeline. | |
| 1167 | − * | |
| 1168 | − * If a TLB flush isn't required due to any of the above, and vpid12 is | |
| 1169 | − * changing then the new "virtual" VPID (vpid12) will reuse the same | |
| 1170 | − * "real" VPID (vpid02), and so needs to be flushed. There's no direct | |
| 1171 | − * mapping between vpid02 and vpid12, vpid02 is per-vCPU and reused for | |
| 1172 | − * all nested vCPUs. Remember, a flush on VM-Enter does not invalidate | |
| 1173 | − * guest-physical mappings, so there is no need to sync the nEPT MMU. | |
| 1165 | + * VPID is enabled and in use by vmcs12. If vpid12 is changing, then | |
| 1166 | + * emulate a guest TLB flush as KVM does not track vpid12 history nor | |
| 1167 | + * is the VPID incorporated into the MMU context. I.e. KVM must assume | |
| 1168 | + * that the new vpid12 has never been used and thus represents a new | |
| 1169 | + * guest ASID that cannot have entries in the TLB. | |
| 1174 | 1170 | */ |
| 1175 | − if (!nested_has_guest_tlb_tag(vcpu)) { | |
| 1176 | − kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); | |
| 1177 | − } else if (is_vmenter && | |
| 1178 | − vmcs12->virtual_processor_id != vmx->nested.last_vpid) { | |
| 1171 | + if (is_vmenter && vmcs12->virtual_processor_id != vmx->nested.last_vpid) { | |
| 1179 | 1172 | vmx->nested.last_vpid = vmcs12->virtual_processor_id; |
| 1180 | − vpid_sync_context(nested_get_vpid02(vcpu)); | |
| 1173 | + kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); | |
| 1174 | + return; | |
| 1181 | 1175 | } |
| 1176 | + | |
| 1177 | + /* | |
| 1178 | + * If VPID is enabled, used by vmc12, and vpid12 is not changing but | |
| 1179 | + * does not have a unique TLB tag (ASID), i.e. EPT is disabled and | |
| 1180 | + * KVM was unable to allocate a VPID for L2, flush the current context | |
| 1181 | + * as the effective ASID is common to both L1 and L2. | |
| 1182 | + */ | |
| 1183 | + if (!nested_has_guest_tlb_tag(vcpu)) | |
| 1184 | + kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); | |
| 1182 | 1185 | } |
| 1183 | 1186 | |
| 1184 | 1187 | static bool is_bitwise_subset(u64 superset, u64 subset, u64 mask) |
| @@ -2588,8 +2591,10 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, · 1403 unmodified lines | ||
| 2588 | 2591 | |
| 2589 | 2592 | if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) && |
| 2590 | 2593 | WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL, |
| 2591 | − vmcs12->guest_ia32_perf_global_ctrl))) | |
| 2594 | + vmcs12->guest_ia32_perf_global_ctrl))) { | |
| 2595 | + *entry_failure_code = ENTRY_FAIL_DEFAULT; | |
| 2592 | 2596 | return -EINVAL; |
| 2597 | + } | |
| 2593 | 2598 | |
| 2594 | 2599 | kvm_rsp_write(vcpu, vmcs12->guest_rsp); |
| 2595 | 2600 | kvm_rip_write(vcpu, vmcs12->guest_rip); |
| @@ -2830,6 +2835,17 @@ static int nested_vmx_check_controls(struct kvm_vcpu *vcpu, · 234 unmodified lines | ||
| 2830 | 2835 | return 0; |
| 2831 | 2836 | } |
| 2832 | 2837 | |
| 2838 | +static int nested_vmx_check_address_space_size(struct kvm_vcpu *vcpu, | |
| 2839 | + struct vmcs12 *vmcs12) | |
| 2840 | +{ | |
| 2841 | +#ifdef CONFIG_X86_64 | |
| 2842 | + if (CC(!!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) != | |
| 2843 | + !!(vcpu->arch.efer & EFER_LMA))) | |
| 2844 | + return -EINVAL; | |
| 2845 | +#endif | |
| 2846 | + return 0; | |
| 2847 | +} | |
| 2848 | + | |
| 2833 | 2849 | static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, |
| 2834 | 2850 | struct vmcs12 *vmcs12) |
| 2835 | 2851 | { |
| @@ -2854,18 +2870,16 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, · 18 unmodified lines | ||
| 2854 | 2870 | return -EINVAL; |
| 2855 | 2871 | |
| 2856 | 2872 | #ifdef CONFIG_X86_64 |
| 2857 | − ia32e = !!(vcpu->arch.efer & EFER_LMA); | |
| 2873 | + ia32e = !!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE); | |
| 2858 | 2874 | #else |
| 2859 | 2875 | ia32e = false; |
| 2860 | 2876 | #endif |
| 2861 | 2877 | |
| 2862 | 2878 | if (ia32e) { |
| 2863 | − if (CC(!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE)) || | |
| 2864 | − CC(!(vmcs12->host_cr4 & X86_CR4_PAE))) | |
| 2879 | + if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE))) | |
| 2865 | 2880 | return -EINVAL; |
| 2866 | 2881 | } else { |
| 2867 | − if (CC(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) || | |
| 2868 | − CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) || | |
| 2882 | + if (CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) || | |
| 2869 | 2883 | CC(vmcs12->host_cr4 & X86_CR4_PCIDE) || |
| 2870 | 2884 | CC((vmcs12->host_rip) >> 32)) |
| 2871 | 2885 | return -EINVAL; |
| @@ -2910,9 +2924,9 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, · 38 unmodified lines | ||
| 2910 | 2924 | static int nested_vmx_check_vmcs_link_ptr(struct kvm_vcpu *vcpu, |
| 2911 | 2925 | struct vmcs12 *vmcs12) |
| 2912 | 2926 | { |
| 2913 | − int r = 0; | |
| 2914 | − struct vmcs12 *shadow; | |
| 2915 | − struct kvm_host_map map; | |
| 2927 | + struct vcpu_vmx *vmx = to_vmx(vcpu); | |
| 2928 | + struct gfn_to_hva_cache *ghc = &vmx->nested.shadow_vmcs12_cache; | |
| 2929 | + struct vmcs_hdr hdr; | |
| 2916 | 2930 | |
| 2917 | 2931 | if (vmcs12->vmcs_link_pointer == INVALID_GPA) |
| 2918 | 2932 | return 0; |
| @@ -2920,17 +2934,21 @@ static int nested_vmx_check_vmcs_link_ptr(struct kvm_vcpu *vcpu, · 1 unmodified line | ||
| 2920 | 2934 | if (CC(!page_address_valid(vcpu, vmcs12->vmcs_link_pointer))) |
| 2921 | 2935 | return -EINVAL; |
| 2922 | 2936 | |
| 2923 | − if (CC(kvm_vcpu_map(vcpu, gpa_to_gfn(vmcs12->vmcs_link_pointer), &map))) | |
| 2924 | − return -EINVAL; | |
| 2937 | + if (ghc->gpa != vmcs12->vmcs_link_pointer && | |
| 2938 | + CC(kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, | |
| 2939 | + vmcs12->vmcs_link_pointer, VMCS12_SIZE))) | |
| 2940 | + return -EINVAL; | |
| 2925 | 2941 | |
| 2926 | − shadow = map.hva; | |
| 2942 | + if (CC(kvm_read_guest_offset_cached(vcpu->kvm, ghc, &hdr, | |
| 2943 | + offsetof(struct vmcs12, hdr), | |
| 2944 | + sizeof(hdr)))) | |
| 2945 | + return -EINVAL; | |
| 2927 | 2946 | |
| 2928 | − if (CC(shadow->hdr.revision_id != VMCS12_REVISION) || | |
| 2929 | − CC(shadow->hdr.shadow_vmcs != nested_cpu_has_shadow_vmcs(vmcs12))) | |
| 2930 | − r = -EINVAL; | |
| 2947 | + if (CC(hdr.revision_id != VMCS12_REVISION) || | |
| 2948 | + CC(hdr.shadow_vmcs != nested_cpu_has_shadow_vmcs(vmcs12))) | |
| 2949 | + return -EINVAL; | |
| 2931 | 2950 | |
| 2932 | − kvm_vcpu_unmap(vcpu, &map, false); | |
| 2933 | − return r; | |
| 2951 | + return 0; | |
| 2934 | 2952 | } |
| 2935 | 2953 | |
| 2936 | 2954 | /* |
| @@ -3325,8 +3343,7 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, · 388 unmodified lines | ||
| 3325 | 3343 | }; |
| 3326 | 3344 | u32 failed_index; |
| 3327 | 3345 | |
| 3328 | − if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) | |
| 3329 | − kvm_vcpu_flush_tlb_current(vcpu); | |
| 3346 | + kvm_service_local_tlb_flush_requests(vcpu); | |
| 3330 | 3347 | |
| 3331 | 3348 | evaluate_pending_interrupts = exec_controls_get(vmx) & |
| 3332 | 3349 | (CPU_BASED_INTR_WINDOW_EXITING | CPU_BASED_NMI_WINDOW_EXITING); |
| @@ -3535,6 +3552,9 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) · 202 unmodified lines | ||
| 3535 | 3552 | if (nested_vmx_check_controls(vcpu, vmcs12)) |
| 3536 | 3553 | return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); |
| 3537 | 3554 | |
| 3555 | + if (nested_vmx_check_address_space_size(vcpu, vmcs12)) | |
| 3556 | + return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD); | |
| 3557 | + | |
| 3538 | 3558 | if (nested_vmx_check_host_state(vcpu, vmcs12)) |
| 3539 | 3559 | return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD); |
| 3540 | 3560 | |
| @@ -4480,9 +4500,8 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, · 939 unmodified lines | ||
| 4480 | 4500 | (void)nested_get_evmcs_page(vcpu); |
| 4481 | 4501 | } |
| 4482 | 4502 | |
| 4483 | − /* Service the TLB flush request for L2 before switching to L1. */ | |
| 4484 | − if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) | |
| 4485 | − kvm_vcpu_flush_tlb_current(vcpu); | |
| 4503 | + /* Service pending TLB flush requests for L2 before switching to L1. */ | |
| 4504 | + kvm_service_local_tlb_flush_requests(vcpu); | |
| 4486 | 4505 | |
| 4487 | 4506 | /* |
| 4488 | 4507 | * VCPU_EXREG_PDPTR will be clobbered in arch/x86/kvm/vmx/vmx.h between |
| @@ -4835,6 +4854,7 @@ static int enter_vmx_operation(struct kvm_vcpu *vcpu) · 346 unmodified lines | ||
| 4835 | 4854 | if (!vmx->nested.cached_vmcs12) |
| 4836 | 4855 | goto out_cached_vmcs12; |
| 4837 | 4856 | |
| 4857 | + vmx->nested.shadow_vmcs12_cache.gpa = INVALID_GPA; | |
| 4838 | 4858 | vmx->nested.cached_shadow_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL_ACCOUNT); |
| 4839 | 4859 | if (!vmx->nested.cached_shadow_vmcs12) |
| 4840 | 4860 | goto out_cached_shadow_vmcs12; |
| @@ -5264,10 +5284,10 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu) · 423 unmodified lines | ||
| 5264 | 5284 | return 1; |
| 5265 | 5285 | |
| 5266 | 5286 | if (vmx->nested.current_vmptr != vmptr) { |
| 5267 | − struct kvm_host_map map; | |
| 5268 | − struct vmcs12 *new_vmcs12; | |
| 5287 | + struct gfn_to_hva_cache *ghc = &vmx->nested.vmcs12_cache; | |
| 5288 | + struct vmcs_hdr hdr; | |
| 5269 | 5289 | |
| 5270 | − if (kvm_vcpu_map(vcpu, gpa_to_gfn(vmptr), &map)) { | |
| 5290 | + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, vmptr, VMCS12_SIZE)) { | |
| 5271 | 5291 | /* |
| 5272 | 5292 | * Reads from an unbacked page return all 1s, |
| 5273 | 5293 | * which means that the 32 bits located at the |
| @@ -5278,12 +5298,16 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu) · 4 unmodified lines | ||
| 5278 | 5298 | VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID); |
| 5279 | 5299 | } |
| 5280 | 5300 | |
| 5281 | − new_vmcs12 = map.hva; | |
| 5301 | + if (kvm_read_guest_offset_cached(vcpu->kvm, ghc, &hdr, | |
| 5302 | + offsetof(struct vmcs12, hdr), | |
| 5303 | + sizeof(hdr))) { | |
| 5304 | + return nested_vmx_fail(vcpu, | |
| 5305 | + VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID); | |
| 5306 | + } | |
| 5282 | 5307 | |
| 5283 | − if (new_vmcs12->hdr.revision_id != VMCS12_REVISION || | |
| 5284 | − (new_vmcs12->hdr.shadow_vmcs && | |
| 5308 | + if (hdr.revision_id != VMCS12_REVISION || | |
| 5309 | + (hdr.shadow_vmcs && | |
| 5285 | 5310 | !nested_cpu_has_vmx_shadow_vmcs(vcpu))) { |
| 5286 | − kvm_vcpu_unmap(vcpu, &map, false); | |
| 5287 | 5311 | return nested_vmx_fail(vcpu, |
| 5288 | 5312 | VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID); |
| 5289 | 5313 | } |
| @@ -5294,8 +5318,11 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu) · 4 unmodified lines | ||
| 5294 | 5318 | * Load VMCS12 from guest memory since it is not already |
| 5295 | 5319 | * cached. |
| 5296 | 5320 | */ |
| 5297 | − memcpy(vmx->nested.cached_vmcs12, new_vmcs12, VMCS12_SIZE); | |
| 5298 | − kvm_vcpu_unmap(vcpu, &map, false); | |
| 5321 | + if (kvm_read_guest_cached(vcpu->kvm, ghc, vmx->nested.cached_vmcs12, | |
| 5322 | + VMCS12_SIZE)) { | |
| 5323 | + return nested_vmx_fail(vcpu, | |
| 5324 | + VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID); | |
| 5325 | + } | |
| 5299 | 5326 | |
| 5300 | 5327 | set_current_vmptr(vmx, vmptr); |
| 5301 | 5328 | } |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <asm/cpu.h> |
| 6 | 6 | |
| 7 | 7 | #include "lapic.h" |
| 8 | +#include "irq.h" | |
| 8 | 9 | #include "posted_intr.h" |
| 9 | 10 | #include "trace.h" |
| 10 | 11 | #include "vmx.h" |
| @@ -77,13 +78,18 @@ after_clear_sn: · 66 unmodified lines | ||
| 77 | 78 | pi_set_on(pi_desc); |
| 78 | 79 | } |
| 79 | 80 | |
| 81 | +static bool vmx_can_use_vtd_pi(struct kvm *kvm) | |
| 82 | +{ | |
| 83 | + return irqchip_in_kernel(kvm) && enable_apicv && | |
| 84 | + kvm_arch_has_assigned_device(kvm) && | |
| 85 | + irq_remapping_cap(IRQ_POSTING_CAP); | |
| 86 | +} | |
| 87 | + | |
| 80 | 88 | void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu) |
| 81 | 89 | { |
| 82 | 90 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); |
| 83 | 91 | |
| 84 | − if (!kvm_arch_has_assigned_device(vcpu->kvm) || | |
| 85 | − !irq_remapping_cap(IRQ_POSTING_CAP) || | |
| 86 | − !kvm_vcpu_apicv_active(vcpu)) | |
| 92 | + if (!vmx_can_use_vtd_pi(vcpu->kvm)) | |
| 87 | 93 | return; |
| 88 | 94 | |
| 89 | 95 | /* Set SN when the vCPU is preempted */ |
| @@ -141,9 +147,7 @@ int pi_pre_block(struct kvm_vcpu *vcpu) · 51 unmodified lines | ||
| 141 | 147 | struct pi_desc old, new; |
| 142 | 148 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); |
| 143 | 149 | |
| 144 | − if (!kvm_arch_has_assigned_device(vcpu->kvm) || | |
| 145 | − !irq_remapping_cap(IRQ_POSTING_CAP) || | |
| 146 | − !kvm_vcpu_apicv_active(vcpu)) | |
| 150 | + if (!vmx_can_use_vtd_pi(vcpu->kvm)) | |
| 147 | 151 | return 0; |
| 148 | 152 | |
| 149 | 153 | WARN_ON(irqs_disabled()); |
| @@ -270,9 +274,7 @@ int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq, · 120 unmodified lines | ||
| 270 | 274 | struct vcpu_data vcpu_info; |
| 271 | 275 | int idx, ret = 0; |
| 272 | 276 | |
| 273 | − if (!kvm_arch_has_assigned_device(kvm) || | |
| 274 | − !irq_remapping_cap(IRQ_POSTING_CAP) || | |
| 275 | − !kvm_vcpu_apicv_active(kvm->vcpus[0])) | |
| 277 | + if (!vmx_can_use_vtd_pi(kvm)) | |
| 276 | 278 | return 0; |
| 277 | 279 | |
| 278 | 280 | idx = srcu_read_lock(&kvm->irq_srcu); |
| @@ -2646,15 +2646,6 @@ int alloc_loaded_vmcs(struct loaded_vmcs *loaded_vmcs) · 2645 unmodified lines | ||
| 2646 | 2646 | if (!loaded_vmcs->msr_bitmap) |
| 2647 | 2647 | goto out_vmcs; |
| 2648 | 2648 | memset(loaded_vmcs->msr_bitmap, 0xff, PAGE_SIZE); |
| 2649 | − | |
| 2650 | − if (IS_ENABLED(CONFIG_HYPERV) && | |
| 2651 | − static_branch_unlikely(&enable_evmcs) && | |
| 2652 | − (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) { | |
| 2653 | − struct hv_enlightened_vmcs *evmcs = | |
| 2654 | − (struct hv_enlightened_vmcs *)loaded_vmcs->vmcs; | |
| 2655 | − | |
| 2656 | − evmcs->hv_enlightenments_control.msr_bitmap = 1; | |
| 2657 | − } | |
| 2658 | 2649 | } |
| 2659 | 2650 | |
| 2660 | 2651 | memset(&loaded_vmcs->host_state, 0, sizeof(struct vmcs_host_state)); |
| @@ -2918,6 +2909,13 @@ static void vmx_flush_tlb_all(struct kvm_vcpu *vcpu) · 257 unmodified lines | ||
| 2918 | 2909 | } |
| 2919 | 2910 | } |
| 2920 | 2911 | |
| 2912 | +static inline int vmx_get_current_vpid(struct kvm_vcpu *vcpu) | |
| 2913 | +{ | |
| 2914 | + if (is_guest_mode(vcpu)) | |
| 2915 | + return nested_get_vpid02(vcpu); | |
| 2916 | + return to_vmx(vcpu)->vpid; | |
| 2917 | +} | |
| 2918 | + | |
| 2921 | 2919 | static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) |
| 2922 | 2920 | { |
| 2923 | 2921 | struct kvm_mmu *mmu = vcpu->arch.mmu; |
| @@ -2930,31 +2928,29 @@ static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) · 6 unmodified lines | ||
| 2930 | 2928 | if (enable_ept) |
| 2931 | 2929 | ept_sync_context(construct_eptp(vcpu, root_hpa, |
| 2932 | 2930 | mmu->shadow_root_level)); |
| 2933 | − else if (!is_guest_mode(vcpu)) | |
| 2934 | − vpid_sync_context(to_vmx(vcpu)->vpid); | |
| 2935 | 2931 | else |
| 2936 | − vpid_sync_context(nested_get_vpid02(vcpu)); | |
| 2932 | + vpid_sync_context(vmx_get_current_vpid(vcpu)); | |
| 2937 | 2933 | } |
| 2938 | 2934 | |
| 2939 | 2935 | static void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr) |
| 2940 | 2936 | { |
| 2941 | 2937 | /* |
| 2942 | − * vpid_sync_vcpu_addr() is a nop if vmx->vpid==0, see the comment in | |
| 2938 | + * vpid_sync_vcpu_addr() is a nop if vpid==0, see the comment in | |
| 2943 | 2939 | * vmx_flush_tlb_guest() for an explanation of why this is ok. |
| 2944 | 2940 | */ |
| 2945 | − vpid_sync_vcpu_addr(to_vmx(vcpu)->vpid, addr); | |
| 2941 | + vpid_sync_vcpu_addr(vmx_get_current_vpid(vcpu), addr); | |
| 2946 | 2942 | } |
| 2947 | 2943 | |
| 2948 | 2944 | static void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu) |
| 2949 | 2945 | { |
| 2950 | 2946 | /* |
| 2951 | − * vpid_sync_context() is a nop if vmx->vpid==0, e.g. if enable_vpid==0 | |
| 2952 | − * or a vpid couldn't be allocated for this vCPU. VM-Enter and VM-Exit | |
| 2953 | − * are required to flush GVA->{G,H}PA mappings from the TLB if vpid is | |
| 2947 | + * vpid_sync_context() is a nop if vpid==0, e.g. if enable_vpid==0 or a | |
| 2948 | + * vpid couldn't be allocated for this vCPU. VM-Enter and VM-Exit are | |
| 2949 | + * required to flush GVA->{G,H}PA mappings from the TLB if vpid is | |
| 2954 | 2950 | * disabled (VM-Enter with vpid enabled and vpid==0 is disallowed), |
| 2955 | 2951 | * i.e. no explicit INVVPID is necessary. |
| 2956 | 2952 | */ |
| 2957 | − vpid_sync_context(to_vmx(vcpu)->vpid); | |
| 2953 | + vpid_sync_context(vmx_get_current_vpid(vcpu)); | |
| 2958 | 2954 | } |
| 2959 | 2955 | |
| 2960 | 2956 | void vmx_ept_load_pdptrs(struct kvm_vcpu *vcpu) |
| @@ -6262,9 +6258,9 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) · 3301 unmodified lines | ||
| 6262 | 6258 | { |
| 6263 | 6259 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 6264 | 6260 | int max_irr; |
| 6265 | − bool max_irr_updated; | |
| 6261 | + bool got_posted_interrupt; | |
| 6266 | 6262 | |
| 6267 | − if (KVM_BUG_ON(!vcpu->arch.apicv_active, vcpu->kvm)) | |
| 6263 | + if (KVM_BUG_ON(!enable_apicv, vcpu->kvm)) | |
| 6268 | 6264 | return -EIO; |
| 6269 | 6265 | |
| 6270 | 6266 | if (pi_test_on(&vmx->pi_desc)) { |
| @@ -6274,22 +6270,33 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 6274 | 6270 | * But on x86 this is just a compiler barrier anyway. |
| 6275 | 6271 | */ |
| 6276 | 6272 | smp_mb__after_atomic(); |
| 6277 | − max_irr_updated = | |
| 6273 | + got_posted_interrupt = | |
| 6278 | 6274 | kvm_apic_update_irr(vcpu, vmx->pi_desc.pir, &max_irr); |
| 6279 | − | |
| 6280 | − /* | |
| 6281 | − * If we are running L2 and L1 has a new pending interrupt | |
| 6282 | − * which can be injected, this may cause a vmexit or it may | |
| 6283 | − * be injected into L2. Either way, this interrupt will be | |
| 6284 | − * processed via KVM_REQ_EVENT, not RVI, because we do not use | |
| 6285 | − * virtual interrupt delivery to inject L1 interrupts into L2. | |
| 6286 | − */ | |
| 6287 | − if (is_guest_mode(vcpu) && max_irr_updated) | |
| 6288 | − kvm_make_request(KVM_REQ_EVENT, vcpu); | |
| 6289 | 6275 | } else { |
| 6290 | 6276 | max_irr = kvm_lapic_find_highest_irr(vcpu); |
| 6277 | + got_posted_interrupt = false; | |
| 6291 | 6278 | } |
| 6292 | − vmx_hwapic_irr_update(vcpu, max_irr); | |
| 6279 | + | |
| 6280 | + /* | |
| 6281 | + * Newly recognized interrupts are injected via either virtual interrupt | |
| 6282 | + * delivery (RVI) or KVM_REQ_EVENT. Virtual interrupt delivery is | |
| 6283 | + * disabled in two cases: | |
| 6284 | + * | |
| 6285 | + * 1) If L2 is running and the vCPU has a new pending interrupt. If L1 | |
| 6286 | + * wants to exit on interrupts, KVM_REQ_EVENT is needed to synthesize a | |
| 6287 | + * VM-Exit to L1. If L1 doesn't want to exit, the interrupt is injected | |
| 6288 | + * into L2, but KVM doesn't use virtual interrupt delivery to inject | |
| 6289 | + * interrupts into L2, and so KVM_REQ_EVENT is again needed. | |
| 6290 | + * | |
| 6291 | + * 2) If APICv is disabled for this vCPU, assigned devices may still | |
| 6292 | + * attempt to post interrupts. The posted interrupt vector will cause | |
| 6293 | + * a VM-Exit and the subsequent entry will call sync_pir_to_irr. | |
| 6294 | + */ | |
| 6295 | + if (!is_guest_mode(vcpu) && kvm_vcpu_apicv_active(vcpu)) | |
| 6296 | + vmx_set_rvi(max_irr); | |
| 6297 | + else if (got_posted_interrupt) | |
| 6298 | + kvm_make_request(KVM_REQ_EVENT, vcpu); | |
| 6299 | + | |
| 6293 | 6300 | return max_irr; |
| 6294 | 6301 | } |
| 6295 | 6302 | |
| @@ -6826,6 +6833,19 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) · 530 unmodified lines | ||
| 6826 | 6833 | if (err < 0) |
| 6827 | 6834 | goto free_pml; |
| 6828 | 6835 | |
| 6836 | + /* | |
| 6837 | + * Use Hyper-V 'Enlightened MSR Bitmap' feature when KVM runs as a | |
| 6838 | + * nested (L1) hypervisor and Hyper-V in L0 supports it. Enable the | |
| 6839 | + * feature only for vmcs01, KVM currently isn't equipped to realize any | |
| 6840 | + * performance benefits from enabling it for vmcs02. | |
| 6841 | + */ | |
| 6842 | + if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs) && | |
| 6843 | + (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) { | |
| 6844 | + struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs; | |
| 6845 | + | |
| 6846 | + evmcs->hv_enlightenments_control.msr_bitmap = 1; | |
| 6847 | + } | |
| 6848 | + | |
| 6829 | 6849 | /* The MSR bitmap starts with all ones */ |
| 6830 | 6850 | bitmap_fill(vmx->shadow_msr_intercept.read, MAX_POSSIBLE_PASSTHROUGH_MSRS); |
| 6831 | 6851 | bitmap_fill(vmx->shadow_msr_intercept.write, MAX_POSSIBLE_PASSTHROUGH_MSRS); |
| @@ -7509,6 +7529,7 @@ static void hardware_unsetup(void) · 677 unmodified lines | ||
| 7509 | 7529 | static bool vmx_check_apicv_inhibit_reasons(ulong bit) |
| 7510 | 7530 | { |
| 7511 | 7531 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | |
| 7532 | + BIT(APICV_INHIBIT_REASON_ABSENT) | | |
| 7512 | 7533 | BIT(APICV_INHIBIT_REASON_HYPERV) | |
| 7513 | 7534 | BIT(APICV_INHIBIT_REASON_BLOCKIRQ); |
| 7514 | 7535 | |
| @@ -7761,10 +7782,10 @@ static __init int hardware_setup(void) · 246 unmodified lines | ||
| 7761 | 7782 | ple_window_shrink = 0; |
| 7762 | 7783 | } |
| 7763 | 7784 | |
| 7764 | − if (!cpu_has_vmx_apicv()) { | |
| 7785 | + if (!cpu_has_vmx_apicv()) | |
| 7765 | 7786 | enable_apicv = 0; |
| 7787 | + if (!enable_apicv) | |
| 7766 | 7788 | vmx_x86_ops.sync_pir_to_irr = NULL; |
| 7767 | − } | |
| 7768 | 7789 | |
| 7769 | 7790 | if (cpu_has_vmx_tsc_scaling()) { |
| 7770 | 7791 | kvm_has_tsc_control = true; |
| @@ -141,6 +141,16 @@ struct nested_vmx { · 140 unmodified lines | ||
| 141 | 141 | */ |
| 142 | 142 | struct vmcs12 *cached_shadow_vmcs12; |
| 143 | 143 | |
| 144 | + /* | |
| 145 | + * GPA to HVA cache for accessing vmcs12->vmcs_link_pointer | |
| 146 | + */ | |
| 147 | + struct gfn_to_hva_cache shadow_vmcs12_cache; | |
| 148 | + | |
| 149 | + /* | |
| 150 | + * GPA to HVA cache for VMCS12 | |
| 151 | + */ | |
| 152 | + struct gfn_to_hva_cache vmcs12_cache; | |
| 153 | + | |
| 144 | 154 | /* |
| 145 | 155 | * Indicates if the shadow vmcs or enlightened vmcs must be updated |
| 146 | 156 | * with the data held by struct vmcs12. |
| @@ -890,7 +890,8 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) · 889 unmodified lines | ||
| 890 | 890 | !load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu))) |
| 891 | 891 | return 1; |
| 892 | 892 | |
| 893 | − if (!(cr0 & X86_CR0_PG) && kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE)) | |
| 893 | + if (!(cr0 & X86_CR0_PG) && | |
| 894 | + (is_64_bit_mode(vcpu) || kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE))) | |
| 894 | 895 | return 1; |
| 895 | 896 | |
| 896 | 897 | static_call(kvm_x86_set_cr0)(vcpu, cr0); |
| @@ -3258,6 +3259,29 @@ static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu) · 2361 unmodified lines | ||
| 3258 | 3259 | static_call(kvm_x86_tlb_flush_guest)(vcpu); |
| 3259 | 3260 | } |
| 3260 | 3261 | |
| 3262 | + | |
| 3263 | +static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu) | |
| 3264 | +{ | |
| 3265 | + ++vcpu->stat.tlb_flush; | |
| 3266 | + static_call(kvm_x86_tlb_flush_current)(vcpu); | |
| 3267 | +} | |
| 3268 | + | |
| 3269 | +/* | |
| 3270 | + * Service "local" TLB flush requests, which are specific to the current MMU | |
| 3271 | + * context. In addition to the generic event handling in vcpu_enter_guest(), | |
| 3272 | + * TLB flushes that are targeted at an MMU context also need to be serviced | |
| 3273 | + * prior before nested VM-Enter/VM-Exit. | |
| 3274 | + */ | |
| 3275 | +void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu) | |
| 3276 | +{ | |
| 3277 | + if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) | |
| 3278 | + kvm_vcpu_flush_tlb_current(vcpu); | |
| 3279 | + | |
| 3280 | + if (kvm_check_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu)) | |
| 3281 | + kvm_vcpu_flush_tlb_guest(vcpu); | |
| 3282 | +} | |
| 3283 | +EXPORT_SYMBOL_GPL(kvm_service_local_tlb_flush_requests); | |
| 3284 | + | |
| 3261 | 3285 | static void record_steal_time(struct kvm_vcpu *vcpu) |
| 3262 | 3286 | { |
| 3263 | 3287 | struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; |
| @@ -3307,9 +3331,9 @@ static void record_steal_time(struct kvm_vcpu *vcpu) · 43 unmodified lines | ||
| 3307 | 3331 | "xor %1, %1\n" |
| 3308 | 3332 | "2:\n" |
| 3309 | 3333 | _ASM_EXTABLE_UA(1b, 2b) |
| 3310 | − : "+r" (st_preempted), | |
| 3311 | − "+&r" (err) | |
| 3312 | − : "m" (st->preempted)); | |
| 3334 | + : "+q" (st_preempted), | |
| 3335 | + "+&r" (err), | |
| 3336 | + "+m" (st->preempted)); | |
| 3313 | 3337 | if (err) |
| 3314 | 3338 | goto out; |
| 3315 | 3339 | |
| @@ -4133,6 +4157,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 817 unmodified lines | ||
| 4133 | 4157 | case KVM_CAP_SGX_ATTRIBUTE: |
| 4134 | 4158 | #endif |
| 4135 | 4159 | case KVM_CAP_VM_COPY_ENC_CONTEXT_FROM: |
| 4160 | + case KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM: | |
| 4136 | 4161 | case KVM_CAP_SREGS2: |
| 4137 | 4162 | case KVM_CAP_EXIT_ON_EMULATION_FAILURE: |
| 4138 | 4163 | case KVM_CAP_VCPU_ATTRIBUTES: |
| @@ -4179,7 +4204,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 40 unmodified lines | ||
| 4179 | 4204 | r = !static_call(kvm_x86_cpu_has_accelerated_tpr)(); |
| 4180 | 4205 | break; |
| 4181 | 4206 | case KVM_CAP_NR_VCPUS: |
| 4182 | − r = num_online_cpus(); | |
| 4207 | + r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS); | |
| 4183 | 4208 | break; |
| 4184 | 4209 | case KVM_CAP_MAX_VCPUS: |
| 4185 | 4210 | r = KVM_MAX_VCPUS; |
| @@ -4448,8 +4473,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) · 262 unmodified lines | ||
| 4448 | 4473 | static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, |
| 4449 | 4474 | struct kvm_lapic_state *s) |
| 4450 | 4475 | { |
| 4451 | − if (vcpu->arch.apicv_active) | |
| 4452 | − static_call(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 4476 | + static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 4453 | 4477 | |
| 4454 | 4478 | return kvm_apic_get_state(vcpu, s); |
| 4455 | 4479 | } |
| @@ -5124,6 +5148,17 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 668 unmodified lines | ||
| 5124 | 5148 | struct kvm_cpuid __user *cpuid_arg = argp; |
| 5125 | 5149 | struct kvm_cpuid cpuid; |
| 5126 | 5150 | |
| 5151 | + /* | |
| 5152 | + * KVM does not correctly handle changing guest CPUID after KVM_RUN, as | |
| 5153 | + * MAXPHYADDR, GBPAGES support, AMD reserved bit behavior, etc.. aren't | |
| 5154 | + * tracked in kvm_mmu_page_role. As a result, KVM may miss guest page | |
| 5155 | + * faults due to reusing SPs/SPTEs. In practice no sane VMM mucks with | |
| 5156 | + * the core vCPU model on the fly, so fail. | |
| 5157 | + */ | |
| 5158 | + r = -EINVAL; | |
| 5159 | + if (vcpu->arch.last_vmentry_cpu != -1) | |
| 5160 | + goto out; | |
| 5161 | + | |
| 5127 | 5162 | r = -EFAULT; |
| 5128 | 5163 | if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid))) |
| 5129 | 5164 | goto out; |
| @@ -5134,6 +5169,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 4 unmodified lines | ||
| 5134 | 5169 | struct kvm_cpuid2 __user *cpuid_arg = argp; |
| 5135 | 5170 | struct kvm_cpuid2 cpuid; |
| 5136 | 5171 | |
| 5172 | + /* | |
| 5173 | + * KVM_SET_CPUID{,2} after KVM_RUN is forbidded, see the comment in | |
| 5174 | + * KVM_SET_CPUID case above. | |
| 5175 | + */ | |
| 5176 | + r = -EINVAL; | |
| 5177 | + if (vcpu->arch.last_vmentry_cpu != -1) | |
| 5178 | + goto out; | |
| 5179 | + | |
| 5137 | 5180 | r = -EFAULT; |
| 5138 | 5181 | if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid))) |
| 5139 | 5182 | goto out; |
| @@ -5698,6 +5741,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, · 558 unmodified lines | ||
| 5698 | 5741 | smp_wmb(); |
| 5699 | 5742 | kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT; |
| 5700 | 5743 | kvm->arch.nr_reserved_ioapic_pins = cap->args[0]; |
| 5744 | + kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT); | |
| 5701 | 5745 | r = 0; |
| 5702 | 5746 | split_irqchip_unlock: |
| 5703 | 5747 | mutex_unlock(&kvm->lock); |
| @@ -6078,6 +6122,7 @@ set_identity_unlock: · 374 unmodified lines | ||
| 6078 | 6122 | /* Write kvm->irq_routing before enabling irqchip_in_kernel. */ |
| 6079 | 6123 | smp_wmb(); |
| 6080 | 6124 | kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL; |
| 6125 | + kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT); | |
| 6081 | 6126 | create_irqchip_unlock: |
| 6082 | 6127 | mutex_unlock(&kvm->lock); |
| 6083 | 6128 | break; |
| @@ -7077,7 +7122,13 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size, · 993 unmodified lines | ||
| 7077 | 7122 | unsigned short port, void *val, unsigned int count) |
| 7078 | 7123 | { |
| 7079 | 7124 | if (vcpu->arch.pio.count) { |
| 7080 | − /* Complete previous iteration. */ | |
| 7125 | + /* | |
| 7126 | + * Complete a previous iteration that required userspace I/O. | |
| 7127 | + * Note, @count isn't guaranteed to match pio.count as userspace | |
| 7128 | + * can modify ECX before rerunning the vCPU. Ignore any such | |
| 7129 | + * shenanigans as KVM doesn't support modifying the rep count, | |
| 7130 | + * and the emulator ensures @count doesn't overflow the buffer. | |
| 7131 | + */ | |
| 7081 | 7132 | } else { |
| 7082 | 7133 | int r = __emulator_pio_in(vcpu, size, port, count); |
| 7083 | 7134 | if (!r) |
| @@ -7086,7 +7137,6 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size, · 2 unmodified lines | ||
| 7086 | 7137 | /* Results already available, fall through. */ |
| 7087 | 7138 | } |
| 7088 | 7139 | |
| 7089 | − WARN_ON(count != vcpu->arch.pio.count); | |
| 7090 | 7140 | complete_emulator_pio_in(vcpu, val); |
| 7091 | 7141 | return 1; |
| 7092 | 7142 | } |
| @@ -8776,10 +8826,9 @@ static void kvm_apicv_init(struct kvm *kvm) · 1683 unmodified lines | ||
| 8776 | 8826 | { |
| 8777 | 8827 | init_rwsem(&kvm->arch.apicv_update_lock); |
| 8778 | 8828 | |
| 8779 | − if (enable_apicv) | |
| 8780 | − clear_bit(APICV_INHIBIT_REASON_DISABLE, | |
| 8781 | − &kvm->arch.apicv_inhibit_reasons); | |
| 8782 | − else | |
| 8829 | + set_bit(APICV_INHIBIT_REASON_ABSENT, | |
| 8830 | + &kvm->arch.apicv_inhibit_reasons); | |
| 8831 | + if (!enable_apicv) | |
| 8783 | 8832 | set_bit(APICV_INHIBIT_REASON_DISABLE, |
| 8784 | 8833 | &kvm->arch.apicv_inhibit_reasons); |
| 8785 | 8834 | } |
| @@ -8848,7 +8897,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) · 62 unmodified lines | ||
| 8848 | 8897 | |
| 8849 | 8898 | trace_kvm_hypercall(nr, a0, a1, a2, a3); |
| 8850 | 8899 | |
| 8851 | − op_64_bit = is_64_bit_mode(vcpu); | |
| 8900 | + op_64_bit = is_64_bit_hypercall(vcpu); | |
| 8852 | 8901 | if (!op_64_bit) { |
| 8853 | 8902 | nr &= 0xFFFFFFFF; |
| 8854 | 8903 | a0 &= 0xFFFFFFFF; |
| @@ -9528,8 +9577,7 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) · 673 unmodified lines | ||
| 9528 | 9577 | if (irqchip_split(vcpu->kvm)) |
| 9529 | 9578 | kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); |
| 9530 | 9579 | else { |
| 9531 | − if (vcpu->arch.apicv_active) | |
| 9532 | − static_call(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 9580 | + static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 9533 | 9581 | if (ioapic_in_kernel(vcpu->kvm)) |
| 9534 | 9582 | kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); |
| 9535 | 9583 | } |
| @@ -9547,12 +9595,16 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu) · 11 unmodified lines | ||
| 9547 | 9595 | if (!kvm_apic_hw_enabled(vcpu->arch.apic)) |
| 9548 | 9596 | return; |
| 9549 | 9597 | |
| 9550 | − if (to_hv_vcpu(vcpu)) | |
| 9598 | + if (to_hv_vcpu(vcpu)) { | |
| 9551 | 9599 | bitmap_or((ulong *)eoi_exit_bitmap, |
| 9552 | 9600 | vcpu->arch.ioapic_handled_vectors, |
| 9553 | 9601 | to_hv_synic(vcpu)->vec_bitmap, 256); |
| 9602 | + static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap); | |
| 9603 | + return; | |
| 9604 | + } | |
| 9554 | 9605 | |
| 9555 | − static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap); | |
| 9606 | + static_call(kvm_x86_load_eoi_exitmap)( | |
| 9607 | + vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors); | |
| 9556 | 9608 | } |
| 9557 | 9609 | |
| 9558 | 9610 | void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, |
| @@ -9644,10 +9696,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 85 unmodified lines | ||
| 9644 | 9696 | /* Flushing all ASIDs flushes the current ASID... */ |
| 9645 | 9697 | kvm_clear_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); |
| 9646 | 9698 | } |
| 9647 | − if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) | |
| 9648 | − kvm_vcpu_flush_tlb_current(vcpu); | |
| 9649 | − if (kvm_check_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu)) | |
| 9650 | − kvm_vcpu_flush_tlb_guest(vcpu); | |
| 9699 | + kvm_service_local_tlb_flush_requests(vcpu); | |
| 9651 | 9700 | |
| 9652 | 9701 | if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) { |
| 9653 | 9702 | vcpu->run->exit_reason = KVM_EXIT_TPR_ACCESS; |
| @@ -9798,10 +9847,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 144 unmodified lines | ||
| 9798 | 9847 | |
| 9799 | 9848 | /* |
| 9800 | 9849 | * This handles the case where a posted interrupt was |
| 9801 | − * notified with kvm_vcpu_kick. | |
| 9850 | + * notified with kvm_vcpu_kick. Assigned devices can | |
| 9851 | + * use the POSTED_INTR_VECTOR even if APICv is disabled, | |
| 9852 | + * so do it even if APICv is disabled on this vCPU. | |
| 9802 | 9853 | */ |
| 9803 | − if (kvm_lapic_enabled(vcpu) && vcpu->arch.apicv_active) | |
| 9804 | − static_call(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 9854 | + if (kvm_lapic_enabled(vcpu)) | |
| 9855 | + static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 9805 | 9856 | |
| 9806 | 9857 | if (kvm_vcpu_exit_request(vcpu)) { |
| 9807 | 9858 | vcpu->mode = OUTSIDE_GUEST_MODE; |
| @@ -9845,8 +9896,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 37 unmodified lines | ||
| 9845 | 9896 | if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST)) |
| 9846 | 9897 | break; |
| 9847 | 9898 | |
| 9848 | − if (vcpu->arch.apicv_active) | |
| 9849 | − static_call(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 9899 | + if (kvm_lapic_enabled(vcpu)) | |
| 9900 | + static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); | |
| 9850 | 9901 | |
| 9851 | 9902 | if (unlikely(kvm_vcpu_exit_request(vcpu))) { |
| 9852 | 9903 | exit_fastpath = EXIT_FASTPATH_EXIT_HANDLED; |
| @@ -103,6 +103,7 @@ static inline unsigned int __shrink_ple_window(unsigned int val, · 102 unmodified lines | ||
| 103 | 103 | |
| 104 | 104 | #define MSR_IA32_CR_PAT_DEFAULT 0x0007040600070406ULL |
| 105 | 105 | |
| 106 | +void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu); | |
| 106 | 107 | int kvm_check_nested_events(struct kvm_vcpu *vcpu); |
| 107 | 108 | |
| 108 | 109 | static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu) |
| @@ -153,12 +154,24 @@ static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu) · 44 unmodified lines | ||
| 153 | 154 | { |
| 154 | 155 | int cs_db, cs_l; |
| 155 | 156 | |
| 157 | + WARN_ON_ONCE(vcpu->arch.guest_state_protected); | |
| 158 | + | |
| 156 | 159 | if (!is_long_mode(vcpu)) |
| 157 | 160 | return false; |
| 158 | 161 | static_call(kvm_x86_get_cs_db_l_bits)(vcpu, &cs_db, &cs_l); |
| 159 | 162 | return cs_l; |
| 160 | 163 | } |
| 161 | 164 | |
| 165 | +static inline bool is_64_bit_hypercall(struct kvm_vcpu *vcpu) | |
| 166 | +{ | |
| 167 | + /* | |
| 168 | + * If running with protected guest state, the CS register is not | |
| 169 | + * accessible. The hypercall register values will have had to been | |
| 170 | + * provided in 64-bit mode, so assume the guest is in 64-bit. | |
| 171 | + */ | |
| 172 | + return vcpu->arch.guest_state_protected || is_64_bit_mode(vcpu); | |
| 173 | +} | |
| 174 | + | |
| 162 | 175 | static inline bool x86_exception_has_error_code(unsigned int vector) |
| 163 | 176 | { |
| 164 | 177 | static u32 exception_has_error_code = BIT(DF_VECTOR) | BIT(TS_VECTOR) | |
| @@ -173,12 +186,6 @@ static inline bool mmu_is_nested(struct kvm_vcpu *vcpu) · 8 unmodified lines | ||
| 173 | 186 | return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu; |
| 174 | 187 | } |
| 175 | 188 | |
| 176 | −static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu) | |
| 177 | −{ | |
| 178 | − ++vcpu->stat.tlb_flush; | |
| 179 | − static_call(kvm_x86_tlb_flush_current)(vcpu); | |
| 180 | −} | |
| 181 | − | |
| 182 | 189 | static inline int is_pae(struct kvm_vcpu *vcpu) |
| 183 | 190 | { |
| 184 | 191 | return kvm_read_cr4_bits(vcpu, X86_CR4_PAE); |
| @@ -127,9 +127,9 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state) · 126 unmodified lines | ||
| 127 | 127 | state_entry_time = vx->runstate_entry_time; |
| 128 | 128 | state_entry_time |= XEN_RUNSTATE_UPDATE; |
| 129 | 129 | |
| 130 | − BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->state_entry_time) != | |
| 130 | + BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, state_entry_time) != | |
| 131 | 131 | sizeof(state_entry_time)); |
| 132 | − BUILD_BUG_ON(sizeof(((struct compat_vcpu_runstate_info *)0)->state_entry_time) != | |
| 132 | + BUILD_BUG_ON(sizeof_field(struct compat_vcpu_runstate_info, state_entry_time) != | |
| 133 | 133 | sizeof(state_entry_time)); |
| 134 | 134 | |
| 135 | 135 | if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache, |
| @@ -144,9 +144,9 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state) · 8 unmodified lines | ||
| 144 | 144 | */ |
| 145 | 145 | BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state) != |
| 146 | 146 | offsetof(struct compat_vcpu_runstate_info, state)); |
| 147 | − BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->state) != | |
| 147 | + BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, state) != | |
| 148 | 148 | sizeof(vx->current_runstate)); |
| 149 | − BUILD_BUG_ON(sizeof(((struct compat_vcpu_runstate_info *)0)->state) != | |
| 149 | + BUILD_BUG_ON(sizeof_field(struct compat_vcpu_runstate_info, state) != | |
| 150 | 150 | sizeof(vx->current_runstate)); |
| 151 | 151 | |
| 152 | 152 | if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache, |
| @@ -163,9 +163,9 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state) · 10 unmodified lines | ||
| 163 | 163 | offsetof(struct vcpu_runstate_info, time) - sizeof(u64)); |
| 164 | 164 | BUILD_BUG_ON(offsetof(struct compat_vcpu_runstate_info, state_entry_time) != |
| 165 | 165 | offsetof(struct compat_vcpu_runstate_info, time) - sizeof(u64)); |
| 166 | − BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->time) != | |
| 167 | − sizeof(((struct compat_vcpu_runstate_info *)0)->time)); | |
| 168 | − BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->time) != | |
| 166 | + BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, time) != | |
| 167 | + sizeof_field(struct compat_vcpu_runstate_info, time)); | |
| 168 | + BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, time) != | |
| 169 | 169 | sizeof(vx->runstate_times)); |
| 170 | 170 | |
| 171 | 171 | if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache, |
| @@ -205,9 +205,9 @@ int __kvm_xen_has_interrupt(struct kvm_vcpu *v) · 33 unmodified lines | ||
| 205 | 205 | BUILD_BUG_ON(offsetof(struct vcpu_info, evtchn_upcall_pending) != |
| 206 | 206 | offsetof(struct compat_vcpu_info, evtchn_upcall_pending)); |
| 207 | 207 | BUILD_BUG_ON(sizeof(rc) != |
| 208 | − sizeof(((struct vcpu_info *)0)->evtchn_upcall_pending)); | |
| 208 | + sizeof_field(struct vcpu_info, evtchn_upcall_pending)); | |
| 209 | 209 | BUILD_BUG_ON(sizeof(rc) != |
| 210 | − sizeof(((struct compat_vcpu_info *)0)->evtchn_upcall_pending)); | |
| 210 | + sizeof_field(struct compat_vcpu_info, evtchn_upcall_pending)); | |
| 211 | 211 | |
| 212 | 212 | /* |
| 213 | 213 | * For efficiency, this mirrors the checks for using the valid |
| @@ -299,7 +299,7 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) · 85 unmodified lines | ||
| 299 | 299 | break; |
| 300 | 300 | |
| 301 | 301 | case KVM_XEN_ATTR_TYPE_SHARED_INFO: |
| 302 | − data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_gfn); | |
| 302 | + data->u.shared_info.gfn = kvm->arch.xen.shinfo_gfn; | |
| 303 | 303 | r = 0; |
| 304 | 304 | break; |
| 305 | 305 | |
| @@ -698,7 +698,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 392 unmodified lines | ||
| 698 | 698 | kvm_hv_hypercall_enabled(vcpu)) |
| 699 | 699 | return kvm_hv_hypercall(vcpu); |
| 700 | 700 | |
| 701 | − longmode = is_64_bit_mode(vcpu); | |
| 701 | + longmode = is_64_bit_hypercall(vcpu); | |
| 702 | 702 | if (!longmode) { |
| 703 | 703 | params[0] = (u32)kvm_rbx_read(vcpu); |
| 704 | 704 | params[1] = (u32)kvm_rcx_read(vcpu); |
| @@ -277,7 +277,8 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) · 276 unmodified lines | ||
| 277 | 277 | return; |
| 278 | 278 | } |
| 279 | 279 | |
| 280 | − new = early_memremap(data.phys_map, data.size); | |
| 280 | + new = early_memremap_prot(data.phys_map, data.size, | |
| 281 | + pgprot_val(pgprot_encrypted(FIXMAP_PAGE_NORMAL))); | |
| 281 | 282 | if (!new) { |
| 282 | 283 | pr_err("Failed to map new boot services memmap\n"); |
| 283 | 284 | return; |
| @@ -72,6 +72,7 @@ static void __init setup_real_mode(void) · 71 unmodified lines | ||
| 72 | 72 | #ifdef CONFIG_X86_64 |
| 73 | 73 | u64 *trampoline_pgd; |
| 74 | 74 | u64 efer; |
| 75 | + int i; | |
| 75 | 76 | #endif |
| 76 | 77 | |
| 77 | 78 | base = (unsigned char *)real_mode_header; |
| @@ -128,8 +129,17 @@ static void __init setup_real_mode(void) · 50 unmodified lines | ||
| 128 | 129 | trampoline_header->flags = 0; |
| 129 | 130 | |
| 130 | 131 | trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd); |
| 132 | + | |
| 133 | + /* Map the real mode stub as virtual == physical */ | |
| 131 | 134 | trampoline_pgd[0] = trampoline_pgd_entry.pgd; |
| 132 | − trampoline_pgd[511] = init_top_pgt[511].pgd; | |
| 135 | + | |
| 136 | + /* | |
| 137 | + * Include the entirety of the kernel mapping into the trampoline | |
| 138 | + * PGD. This way, all mappings present in the normal kernel page | |
| 139 | + * tables are usable while running on trampoline_pgd. | |
| 140 | + */ | |
| 141 | + for (i = pgd_index(__PAGE_OFFSET); i < PTRS_PER_PGD; i++) | |
| 142 | + trampoline_pgd[i] = init_top_pgt[i].pgd; | |
| 133 | 143 | #endif |
| 134 | 144 | |
| 135 | 145 | sme_sev_setup_real_mode(trampoline_header); |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #include <linux/init.h> |
| 22 | 22 | #include <linux/linkage.h> |
| 23 | +#include <../entry/calling.h> | |
| 23 | 24 | |
| 24 | 25 | .pushsection .noinstr.text, "ax" |
| 25 | 26 | /* |
| @@ -192,6 +193,25 @@ SYM_CODE_START(xen_iret) · 166 unmodified lines | ||
| 192 | 193 | jmp hypercall_iret |
| 193 | 194 | SYM_CODE_END(xen_iret) |
| 194 | 195 | |
| 196 | +/* | |
| 197 | + * XEN pv doesn't use trampoline stack, PER_CPU_VAR(cpu_tss_rw + TSS_sp0) is | |
| 198 | + * also the kernel stack. Reusing swapgs_restore_regs_and_return_to_usermode() | |
| 199 | + * in XEN pv would cause %rsp to move up to the top of the kernel stack and | |
| 200 | + * leave the IRET frame below %rsp, which is dangerous to be corrupted if #NMI | |
| 201 | + * interrupts. And swapgs_restore_regs_and_return_to_usermode() pushing the IRET | |
| 202 | + * frame at the same address is useless. | |
| 203 | + */ | |
| 204 | +SYM_CODE_START(xenpv_restore_regs_and_return_to_usermode) | |
| 205 | + UNWIND_HINT_REGS | |
| 206 | + POP_REGS | |
| 207 | + | |
| 208 | + /* stackleak_erase() can work safely on the kernel stack. */ | |
| 209 | + STACKLEAK_ERASE_NOCLOBBER | |
| 210 | + | |
| 211 | + addq $8, %rsp /* skip regs->orig_ax */ | |
| 212 | + jmp xen_iret | |
| 213 | +SYM_CODE_END(xenpv_restore_regs_and_return_to_usermode) | |
| 214 | + | |
| 195 | 215 | /* |
| 196 | 216 | * Xen handles syscall callbacks much like ordinary exceptions, which |
| 197 | 217 | * means we have: |
| @@ -121,7 +121,6 @@ void flush_cache_page(struct vm_area_struct*, · 120 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 123 | 123 | void flush_dcache_page(struct page *); |
| 124 | −void flush_dcache_folio(struct folio *); | |
| 125 | 124 | |
| 126 | 125 | void local_flush_cache_range(struct vm_area_struct *vma, |
| 127 | 126 | unsigned long start, unsigned long end); |
| @@ -138,9 +137,7 @@ void local_flush_cache_page(struct vm_area_struct *vma, · 10 unmodified lines | ||
| 138 | 137 | #define flush_cache_vunmap(start,end) do { } while (0) |
| 139 | 138 | |
| 140 | 139 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 |
| 141 | −#define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO | |
| 142 | 140 | #define flush_dcache_page(page) do { } while (0) |
| 143 | −static inline void flush_dcache_folio(struct folio *folio) { } | |
| 144 | 141 | |
| 145 | 142 | #define flush_icache_range local_flush_icache_range |
| 146 | 143 | #define flush_cache_page(vma, addr, pfn) do { } while (0) |
| @@ -419,3 +419,4 @@ · 418 unmodified lines | ||
| 419 | 419 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 420 | 420 | # 447 reserved for memfd_secret |
| 421 | 421 | 448 common process_mrelease sys_process_mrelease |
| 422 | +449 common futex_waitv sys_futex_waitv | |
| @@ -753,8 +753,7 @@ struct block_device *blkdev_get_no_open(dev_t dev) · 752 unmodified lines | ||
| 753 | 753 | |
| 754 | 754 | if (!bdev) |
| 755 | 755 | return NULL; |
| 756 | − if ((bdev->bd_disk->flags & GENHD_FL_HIDDEN) || | |
| 757 | − !try_module_get(bdev->bd_disk->fops->owner)) { | |
| 756 | + if ((bdev->bd_disk->flags & GENHD_FL_HIDDEN)) { | |
| 758 | 757 | put_device(&bdev->bd_device); |
| 759 | 758 | return NULL; |
| 760 | 759 | } |
| @@ -764,7 +763,6 @@ struct block_device *blkdev_get_no_open(dev_t dev) · 3 unmodified lines | ||
| 764 | 763 | |
| 765 | 764 | void blkdev_put_no_open(struct block_device *bdev) |
| 766 | 765 | { |
| 767 | − module_put(bdev->bd_disk->fops->owner); | |
| 768 | 766 | put_device(&bdev->bd_device); |
| 769 | 767 | } |
| 770 | 768 | |
| @@ -820,12 +818,14 @@ struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder) · 49 unmodified lines | ||
| 820 | 818 | ret = -ENXIO; |
| 821 | 819 | if (!disk_live(disk)) |
| 822 | 820 | goto abort_claiming; |
| 821 | + if (!try_module_get(disk->fops->owner)) | |
| 822 | + goto abort_claiming; | |
| 823 | 823 | if (bdev_is_partition(bdev)) |
| 824 | 824 | ret = blkdev_get_part(bdev, mode); |
| 825 | 825 | else |
| 826 | 826 | ret = blkdev_get_whole(bdev, mode); |
| 827 | 827 | if (ret) |
| 828 | − goto abort_claiming; | |
| 828 | + goto put_module; | |
| 829 | 829 | if (mode & FMODE_EXCL) { |
| 830 | 830 | bd_finish_claiming(bdev, holder); |
| 831 | 831 | |
| @@ -847,7 +847,8 @@ struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder) · 15 unmodified lines | ||
| 847 | 847 | if (unblock_events) |
| 848 | 848 | disk_unblock_events(disk); |
| 849 | 849 | return bdev; |
| 850 | − | |
| 850 | +put_module: | |
| 851 | + module_put(disk->fops->owner); | |
| 851 | 852 | abort_claiming: |
| 852 | 853 | if (mode & FMODE_EXCL) |
| 853 | 854 | bd_abort_claiming(bdev, holder); |
| @@ -956,6 +957,7 @@ void blkdev_put(struct block_device *bdev, fmode_t mode) · 102 unmodified lines | ||
| 956 | 957 | blkdev_put_whole(bdev, mode); |
| 957 | 958 | mutex_unlock(&disk->open_mutex); |
| 958 | 959 | |
| 960 | + module_put(disk->fops->owner); | |
| 959 | 961 | blkdev_put_no_open(bdev); |
| 960 | 962 | } |
| 961 | 963 | EXPORT_SYMBOL(blkdev_put); |
| @@ -640,7 +640,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, · 639 unmodified lines | ||
| 640 | 640 | */ |
| 641 | 641 | ret = blk_queue_enter(q, 0); |
| 642 | 642 | if (ret) |
| 643 | − return ret; | |
| 643 | + goto fail; | |
| 644 | 644 | |
| 645 | 645 | rcu_read_lock(); |
| 646 | 646 | spin_lock_irq(&q->queue_lock); |
| @@ -676,13 +676,13 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, · 29 unmodified lines | ||
| 676 | 676 | new_blkg = blkg_alloc(pos, q, GFP_KERNEL); |
| 677 | 677 | if (unlikely(!new_blkg)) { |
| 678 | 678 | ret = -ENOMEM; |
| 679 | − goto fail; | |
| 679 | + goto fail_exit_queue; | |
| 680 | 680 | } |
| 681 | 681 | |
| 682 | 682 | if (radix_tree_preload(GFP_KERNEL)) { |
| 683 | 683 | blkg_free(new_blkg); |
| 684 | 684 | ret = -ENOMEM; |
| 685 | − goto fail; | |
| 685 | + goto fail_exit_queue; | |
| 686 | 686 | } |
| 687 | 687 | |
| 688 | 688 | rcu_read_lock(); |
| @@ -722,9 +722,10 @@ fail_preloaded: · 33 unmodified lines | ||
| 722 | 722 | fail_unlock: |
| 723 | 723 | spin_unlock_irq(&q->queue_lock); |
| 724 | 724 | rcu_read_unlock(); |
| 725 | +fail_exit_queue: | |
| 726 | + blk_queue_exit(q); | |
| 725 | 727 | fail: |
| 726 | 728 | blkdev_put_no_open(bdev); |
| 727 | − blk_queue_exit(q); | |
| 728 | 729 | /* |
| 729 | 730 | * If queue was bypassing, we should retry. Do so after a |
| 730 | 731 | * short msleep(). It isn't strictly necessary but queue |
| @@ -363,8 +363,10 @@ void blk_cleanup_queue(struct request_queue *q) · 362 unmodified lines | ||
| 363 | 363 | blk_queue_flag_set(QUEUE_FLAG_DEAD, q); |
| 364 | 364 | |
| 365 | 365 | blk_sync_queue(q); |
| 366 | − if (queue_is_mq(q)) | |
| 366 | + if (queue_is_mq(q)) { | |
| 367 | + blk_mq_cancel_work_sync(q); | |
| 367 | 368 | blk_mq_exit_queue(q); |
| 369 | + } | |
| 368 | 370 | |
| 369 | 371 | /* |
| 370 | 372 | * In theory, request pool of sched_tags belongs to request queue. |
| @@ -1015,6 +1017,7 @@ EXPORT_SYMBOL(submit_bio); · 644 unmodified lines | ||
| 1015 | 1017 | /** |
| 1016 | 1018 | * bio_poll - poll for BIO completions |
| 1017 | 1019 | * @bio: bio to poll for |
| 1020 | + * @iob: batches of IO | |
| 1018 | 1021 | * @flags: BLK_POLL_* flags that control the behavior |
| 1019 | 1022 | * |
| 1020 | 1023 | * Poll for completions on queue associated with the bio. Returns number of |
| @@ -379,7 +379,7 @@ static void mq_flush_data_end_io(struct request *rq, blk_status_t error) · 378 unmodified lines | ||
| 379 | 379 | * @rq is being submitted. Analyze what needs to be done and put it on the |
| 380 | 380 | * right queue. |
| 381 | 381 | */ |
| 382 | −bool blk_insert_flush(struct request *rq) | |
| 382 | +void blk_insert_flush(struct request *rq) | |
| 383 | 383 | { |
| 384 | 384 | struct request_queue *q = rq->q; |
| 385 | 385 | unsigned long fflags = q->queue_flags; /* may change, cache */ |
| @@ -409,7 +409,7 @@ bool blk_insert_flush(struct request *rq) · 23 unmodified lines | ||
| 409 | 409 | */ |
| 410 | 410 | if (!policy) { |
| 411 | 411 | blk_mq_end_request(rq, 0); |
| 412 | − return true; | |
| 412 | + return; | |
| 413 | 413 | } |
| 414 | 414 | |
| 415 | 415 | BUG_ON(rq->bio != rq->biotail); /*assumes zero or single bio rq */ |
| @@ -420,8 +420,10 @@ bool blk_insert_flush(struct request *rq) · 4 unmodified lines | ||
| 420 | 420 | * for normal execution. |
| 421 | 421 | */ |
| 422 | 422 | if ((policy & REQ_FSEQ_DATA) && |
| 423 | − !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) | |
| 424 | − return false; | |
| 423 | + !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) { | |
| 424 | + blk_mq_request_bypass_insert(rq, false, true); | |
| 425 | + return; | |
| 426 | + } | |
| 425 | 427 | |
| 426 | 428 | /* |
| 427 | 429 | * @rq should go through flush machinery. Mark it part of flush |
| @@ -437,8 +439,6 @@ bool blk_insert_flush(struct request *rq) · 9 unmodified lines | ||
| 437 | 439 | spin_lock_irq(&fq->mq_flush_lock); |
| 438 | 440 | blk_flush_complete_seq(rq, fq, REQ_FSEQ_ACTIONS & ~policy, 0); |
| 439 | 441 | spin_unlock_irq(&fq->mq_flush_lock); |
| 440 | − | |
| 441 | − return true; | |
| 442 | 442 | } |
| 443 | 443 | |
| 444 | 444 | /** |
| @@ -860,13 +860,14 @@ void blk_mq_end_request_batch(struct io_comp_batch *iob) · 859 unmodified lines | ||
| 860 | 860 | if (iob->need_ts) |
| 861 | 861 | __blk_mq_end_request_acct(rq, now); |
| 862 | 862 | |
| 863 | + rq_qos_done(rq->q, rq); | |
| 864 | + | |
| 863 | 865 | WRITE_ONCE(rq->state, MQ_RQ_IDLE); |
| 864 | 866 | if (!refcount_dec_and_test(&rq->ref)) |
| 865 | 867 | continue; |
| 866 | 868 | |
| 867 | 869 | blk_crypto_free_request(rq); |
| 868 | 870 | blk_pm_mark_last_busy(rq); |
| 869 | − rq_qos_done(rq->q, rq); | |
| 870 | 871 | |
| 871 | 872 | if (nr_tags == TAG_COMP_BATCH || cur_hctx != rq->mq_hctx) { |
| 872 | 873 | if (cur_hctx) |
| @@ -2543,8 +2544,7 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, · 1670 unmodified lines | ||
| 2543 | 2544 | return NULL; |
| 2544 | 2545 | } |
| 2545 | 2546 | |
| 2546 | −static inline bool blk_mq_can_use_cached_rq(struct request *rq, | |
| 2547 | − struct bio *bio) | |
| 2547 | +static inline bool blk_mq_can_use_cached_rq(struct request *rq, struct bio *bio) | |
| 2548 | 2548 | { |
| 2549 | 2549 | if (blk_mq_get_hctx_type(bio->bi_opf) != rq->mq_hctx->type) |
| 2550 | 2550 | return false; |
| @@ -2565,7 +2565,6 @@ static inline struct request *blk_mq_get_request(struct request_queue *q, · 14 unmodified lines | ||
| 2565 | 2565 | bool checked = false; |
| 2566 | 2566 | |
| 2567 | 2567 | if (plug) { |
| 2568 | − | |
| 2569 | 2568 | rq = rq_list_peek(&plug->cached_rq); |
| 2570 | 2569 | if (rq && rq->q == q) { |
| 2571 | 2570 | if (unlikely(!submit_bio_checks(bio))) |
| @@ -2587,12 +2586,14 @@ static inline struct request *blk_mq_get_request(struct request_queue *q, · 15 unmodified lines | ||
| 2587 | 2586 | fallback: |
| 2588 | 2587 | if (unlikely(bio_queue_enter(bio))) |
| 2589 | 2588 | return NULL; |
| 2590 | − if (!checked && !submit_bio_checks(bio)) | |
| 2591 | − return NULL; | |
| 2589 | + if (unlikely(!checked && !submit_bio_checks(bio))) | |
| 2590 | + goto out_put; | |
| 2592 | 2591 | rq = blk_mq_get_new_requests(q, plug, bio, nsegs, same_queue_rq); |
| 2593 | − if (!rq) | |
| 2594 | − blk_queue_exit(q); | |
| 2595 | − return rq; | |
| 2592 | + if (rq) | |
| 2593 | + return rq; | |
| 2594 | +out_put: | |
| 2595 | + blk_queue_exit(q); | |
| 2596 | + return NULL; | |
| 2596 | 2597 | } |
| 2597 | 2598 | |
| 2598 | 2599 | /** |
| @@ -2647,8 +2648,10 @@ void blk_mq_submit_bio(struct bio *bio) · 48 unmodified lines | ||
| 2647 | 2648 | return; |
| 2648 | 2649 | } |
| 2649 | 2650 | |
| 2650 | − if (op_is_flush(bio->bi_opf) && blk_insert_flush(rq)) | |
| 2651 | + if (op_is_flush(bio->bi_opf)) { | |
| 2652 | + blk_insert_flush(rq); | |
| 2651 | 2653 | return; |
| 2654 | + } | |
| 2652 | 2655 | |
| 2653 | 2656 | if (plug && (q->nr_hw_queues == 1 || |
| 2654 | 2657 | blk_mq_is_shared_tags(rq->mq_hctx->flags) || |
| @@ -4417,6 +4420,19 @@ unsigned int blk_mq_rq_cpu(struct request *rq) · 1762 unmodified lines | ||
| 4417 | 4420 | } |
| 4418 | 4421 | EXPORT_SYMBOL(blk_mq_rq_cpu); |
| 4419 | 4422 | |
| 4423 | +void blk_mq_cancel_work_sync(struct request_queue *q) | |
| 4424 | +{ | |
| 4425 | + if (queue_is_mq(q)) { | |
| 4426 | + struct blk_mq_hw_ctx *hctx; | |
| 4427 | + int i; | |
| 4428 | + | |
| 4429 | + cancel_delayed_work_sync(&q->requeue_work); | |
| 4430 | + | |
| 4431 | + queue_for_each_hw_ctx(q, hctx, i) | |
| 4432 | + cancel_delayed_work_sync(&hctx->run_work); | |
| 4433 | + } | |
| 4434 | +} | |
| 4435 | + | |
| 4420 | 4436 | static int __init blk_mq_init(void) |
| 4421 | 4437 | { |
| 4422 | 4438 | int i; |
| @@ -128,6 +128,8 @@ extern void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx); · 127 unmodified lines | ||
| 128 | 128 | void blk_mq_free_plug_rqs(struct blk_plug *plug); |
| 129 | 129 | void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule); |
| 130 | 130 | |
| 131 | +void blk_mq_cancel_work_sync(struct request_queue *q); | |
| 132 | + | |
| 131 | 133 | void blk_mq_release(struct request_queue *q); |
| 132 | 134 | |
| 133 | 135 | static inline struct blk_mq_ctx *__blk_mq_get_ctx(struct request_queue *q, |
| @@ -791,16 +791,6 @@ static void blk_release_queue(struct kobject *kobj) · 790 unmodified lines | ||
| 791 | 791 | |
| 792 | 792 | blk_free_queue_stats(q->stats); |
| 793 | 793 | |
| 794 | − if (queue_is_mq(q)) { | |
| 795 | − struct blk_mq_hw_ctx *hctx; | |
| 796 | − int i; | |
| 797 | − | |
| 798 | − cancel_delayed_work_sync(&q->requeue_work); | |
| 799 | − | |
| 800 | − queue_for_each_hw_ctx(q, hctx, i) | |
| 801 | − cancel_delayed_work_sync(&hctx->run_work); | |
| 802 | − } | |
| 803 | − | |
| 804 | 794 | blk_exit_queue(q); |
| 805 | 795 | |
| 806 | 796 | blk_queue_free_zone_bitmaps(q); |
| @@ -271,7 +271,7 @@ void __blk_account_io_done(struct request *req, u64 now); · 270 unmodified lines | ||
| 271 | 271 | */ |
| 272 | 272 | #define ELV_ON_HASH(rq) ((rq)->rq_flags & RQF_HASHED) |
| 273 | 273 | |
| 274 | −bool blk_insert_flush(struct request *rq); | |
| 274 | +void blk_insert_flush(struct request *rq); | |
| 275 | 275 | |
| 276 | 276 | int elevator_switch_mq(struct request_queue *q, |
| 277 | 277 | struct elevator_type *new_e); |
| @@ -694,12 +694,18 @@ void elevator_init_mq(struct request_queue *q) · 693 unmodified lines | ||
| 694 | 694 | if (!e) |
| 695 | 695 | return; |
| 696 | 696 | |
| 697 | + /* | |
| 698 | + * We are called before adding disk, when there isn't any FS I/O, | |
| 699 | + * so freezing queue plus canceling dispatch work is enough to | |
| 700 | + * drain any dispatch activities originated from passthrough | |
| 701 | + * requests, then no need to quiesce queue which may add long boot | |
| 702 | + * latency, especially when lots of disks are involved. | |
| 703 | + */ | |
| 697 | 704 | blk_mq_freeze_queue(q); |
| 698 | − blk_mq_quiesce_queue(q); | |
| 705 | + blk_mq_cancel_work_sync(q); | |
| 699 | 706 | |
| 700 | 707 | err = blk_mq_init_sched(q, e); |
| 701 | 708 | |
| 702 | − blk_mq_unquiesce_queue(q); | |
| 703 | 709 | blk_mq_unfreeze_queue(q); |
| 704 | 710 | |
| 705 | 711 | if (err) { |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/falloc.h> |
| 16 | 16 | #include <linux/suspend.h> |
| 17 | 17 | #include <linux/fs.h> |
| 18 | +#include <linux/module.h> | |
| 18 | 19 | #include "blk.h" |
| 19 | 20 | |
| 20 | 21 | static inline struct inode *bdev_file_inode(struct file *file) |
| @@ -340,8 +341,7 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb, · 319 unmodified lines | ||
| 340 | 341 | } else { |
| 341 | 342 | ret = bio_iov_iter_get_pages(bio, iter); |
| 342 | 343 | if (unlikely(ret)) { |
| 343 | − bio->bi_status = BLK_STS_IOERR; | |
| 344 | − bio_endio(bio); | |
| 344 | + bio_put(bio); | |
| 345 | 345 | return ret; |
| 346 | 346 | } |
| 347 | 347 | } |
| @@ -1111,6 +1111,8 @@ static void disk_release(struct device *dev) · 1110 unmodified lines | ||
| 1111 | 1111 | might_sleep(); |
| 1112 | 1112 | WARN_ON_ONCE(disk_live(disk)); |
| 1113 | 1113 | |
| 1114 | + blk_mq_cancel_work_sync(disk->queue); | |
| 1115 | + | |
| 1114 | 1116 | disk_release_events(disk); |
| 1115 | 1117 | kfree(disk->random); |
| 1116 | 1118 | xa_destroy(&disk->part_tbl); |
| @@ -69,7 +69,14 @@ int ioprio_check_cap(int ioprio) · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | switch (class) { |
| 71 | 71 | case IOPRIO_CLASS_RT: |
| 72 | − if (!capable(CAP_SYS_NICE) && !capable(CAP_SYS_ADMIN)) | |
| 72 | + /* | |
| 73 | + * Originally this only checked for CAP_SYS_ADMIN, | |
| 74 | + * which was implicitly allowed for pid 0 by security | |
| 75 | + * modules such as SELinux. Make sure we check | |
| 76 | + * CAP_SYS_ADMIN first to avoid a denial/avc for | |
| 77 | + * possibly missing CAP_SYS_NICE permission. | |
| 78 | + */ | |
| 79 | + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE)) | |
| 73 | 80 | return -EPERM; |
| 74 | 81 | fallthrough; |
| 75 | 82 | /* rt has prio field too */ |
| @@ -213,6 +220,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) · 137 unmodified lines | ||
| 213 | 220 | pgrp = task_pgrp(current); |
| 214 | 221 | else |
| 215 | 222 | pgrp = find_vpid(who); |
| 223 | + read_lock(&tasklist_lock); | |
| 216 | 224 | do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { |
| 217 | 225 | tmpio = get_task_ioprio(p); |
| 218 | 226 | if (tmpio < 0) |
| @@ -222,6 +230,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) · 3 unmodified lines | ||
| 222 | 230 | else |
| 223 | 231 | ret = ioprio_best(ret, tmpio); |
| 224 | 232 | } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); |
| 233 | + read_unlock(&tasklist_lock); | |
| 234 | + | |
| 225 | 235 | break; |
| 226 | 236 | case IOPRIO_WHO_USER: |
| 227 | 237 | uid = make_kuid(current_user_ns(), who); |
| @@ -998,7 +998,14 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) · 997 unmodified lines | ||
| 998 | 998 | static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf) |
| 999 | 999 | { |
| 1000 | 1000 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); |
| 1001 | − struct cpc_register_resource *reg = &cpc_desc->cpc_regs[reg_idx]; | |
| 1001 | + struct cpc_register_resource *reg; | |
| 1002 | + | |
| 1003 | + if (!cpc_desc) { | |
| 1004 | + pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | |
| 1005 | + return -ENODEV; | |
| 1006 | + } | |
| 1007 | + | |
| 1008 | + reg = &cpc_desc->cpc_regs[reg_idx]; | |
| 1002 | 1009 | |
| 1003 | 1010 | if (CPC_IN_PCC(reg)) { |
| 1004 | 1011 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); |
| @@ -347,28 +347,3 @@ void acpi_device_notify_remove(struct device *dev) · 346 unmodified lines | ||
| 347 | 347 | |
| 348 | 348 | acpi_unbind_one(dev); |
| 349 | 349 | } |
| 350 | − | |
| 351 | −int acpi_dev_turn_off_if_unused(struct device *dev, void *not_used) | |
| 352 | −{ | |
| 353 | − struct acpi_device *adev = to_acpi_device(dev); | |
| 354 | − | |
| 355 | − /* | |
| 356 | − * Skip device objects with device IDs, because they may be in use even | |
| 357 | − * if they are not companions of any physical device objects. | |
| 358 | − */ | |
| 359 | − if (adev->pnp.type.hardware_id) | |
| 360 | − return 0; | |
| 361 | − | |
| 362 | − mutex_lock(&adev->physical_node_lock); | |
| 363 | − | |
| 364 | − /* | |
| 365 | − * Device objects without device IDs are not in use if they have no | |
| 366 | − * corresponding physical device objects. | |
| 367 | − */ | |
| 368 | − if (list_empty(&adev->physical_node_list)) | |
| 369 | − acpi_device_set_power(adev, ACPI_STATE_D3_COLD); | |
| 370 | − | |
| 371 | − mutex_unlock(&adev->physical_node_lock); | |
| 372 | − | |
| 373 | − return 0; | |
| 374 | −} | |
| @@ -117,7 +117,6 @@ bool acpi_device_is_battery(struct acpi_device *adev); · 116 unmodified lines | ||
| 117 | 117 | bool acpi_device_is_first_physical_node(struct acpi_device *adev, |
| 118 | 118 | const struct device *dev); |
| 119 | 119 | int acpi_bus_register_early_device(int type); |
| 120 | −int acpi_dev_turn_off_if_unused(struct device *dev, void *not_used); | |
| 121 | 120 | |
| 122 | 121 | /* -------------------------------------------------------------------------- |
| 123 | 122 | Device Matching and Notification |
| @@ -1084,21 +1084,17 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, · 1083 unmodified lines | ||
| 1084 | 1084 | * Returns parent node of an ACPI device or data firmware node or %NULL if |
| 1085 | 1085 | * not available. |
| 1086 | 1086 | */ |
| 1087 | −struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode) | |
| 1087 | +static struct fwnode_handle * | |
| 1088 | +acpi_node_get_parent(const struct fwnode_handle *fwnode) | |
| 1088 | 1089 | { |
| 1089 | 1090 | if (is_acpi_data_node(fwnode)) { |
| 1090 | 1091 | /* All data nodes have parent pointer so just return that */ |
| 1091 | 1092 | return to_acpi_data_node(fwnode)->parent; |
| 1092 | 1093 | } else if (is_acpi_device_node(fwnode)) { |
| 1093 | − acpi_handle handle, parent_handle; | |
| 1094 | − | |
| 1095 | − handle = to_acpi_device_node(fwnode)->handle; | |
| 1096 | − if (ACPI_SUCCESS(acpi_get_parent(handle, &parent_handle))) { | |
| 1097 | − struct acpi_device *adev; | |
| 1094 | + struct device *dev = to_acpi_device_node(fwnode)->dev.parent; | |
| 1098 | 1095 | |
| 1099 | − if (!acpi_bus_get_device(parent_handle, &adev)) | |
| 1100 | − return acpi_fwnode_handle(adev); | |
| 1101 | − } | |
| 1096 | + if (dev) | |
| 1097 | + return acpi_fwnode_handle(to_acpi_device(dev)); | |
| 1102 | 1098 | } |
| 1103 | 1099 | |
| 1104 | 1100 | return NULL; |
| @@ -2564,12 +2564,6 @@ int __init acpi_scan_init(void) · 2563 unmodified lines | ||
| 2564 | 2564 | } |
| 2565 | 2565 | } |
| 2566 | 2566 | |
| 2567 | − /* | |
| 2568 | − * Make sure that power management resources are not blocked by ACPI | |
| 2569 | − * device objects with no users. | |
| 2570 | − */ | |
| 2571 | − bus_for_each_dev(&acpi_bus_type, NULL, NULL, acpi_dev_turn_off_if_unused); | |
| 2572 | − | |
| 2573 | 2567 | acpi_turn_off_unused_power_resources(); |
| 2574 | 2568 | |
| 2575 | 2569 | acpi_scan_initialized = true; |
| @@ -2710,7 +2710,7 @@ static void binder_transaction(struct binder_proc *proc, · 2709 unmodified lines | ||
| 2710 | 2710 | t->from = thread; |
| 2711 | 2711 | else |
| 2712 | 2712 | t->from = NULL; |
| 2713 | − t->sender_euid = proc->cred->euid; | |
| 2713 | + t->sender_euid = task_euid(proc->tsk); | |
| 2714 | 2714 | t->to_proc = target_proc; |
| 2715 | 2715 | t->to_thread = target_thread; |
| 2716 | 2716 | t->code = tr->code; |
| @@ -4422,23 +4422,20 @@ static int binder_thread_release(struct binder_proc *proc, · 1705 unmodified lines | ||
| 4422 | 4422 | __release(&t->lock); |
| 4423 | 4423 | |
| 4424 | 4424 | /* |
| 4425 | − * If this thread used poll, make sure we remove the waitqueue | |
| 4426 | − * from any epoll data structures holding it with POLLFREE. | |
| 4427 | − * waitqueue_active() is safe to use here because we're holding | |
| 4428 | − * the inner lock. | |
| 4425 | + * If this thread used poll, make sure we remove the waitqueue from any | |
| 4426 | + * poll data structures holding it. | |
| 4429 | 4427 | */ |
| 4430 | − if ((thread->looper & BINDER_LOOPER_STATE_POLL) && | |
| 4431 | − waitqueue_active(&thread->wait)) { | |
| 4432 | − wake_up_poll(&thread->wait, EPOLLHUP | POLLFREE); | |
| 4433 | − } | |
| 4428 | + if (thread->looper & BINDER_LOOPER_STATE_POLL) | |
| 4429 | + wake_up_pollfree(&thread->wait); | |
| 4434 | 4430 | |
| 4435 | 4431 | binder_inner_proc_unlock(thread->proc); |
| 4436 | 4432 | |
| 4437 | 4433 | /* |
| 4438 | − * This is needed to avoid races between wake_up_poll() above and | |
| 4439 | − * and ep_remove_waitqueue() called for other reasons (eg the epoll file | |
| 4440 | − * descriptor being closed); ep_remove_waitqueue() holds an RCU read | |
| 4441 | − * lock, so we can be sure it's done after calling synchronize_rcu(). | |
| 4434 | + * This is needed to avoid races between wake_up_pollfree() above and | |
| 4435 | + * someone else removing the last entry from the queue for other reasons | |
| 4436 | + * (e.g. ep_remove_wait_queue() being called due to an epoll file | |
| 4437 | + * descriptor being closed). Such other users hold an RCU read lock, so | |
| 4438 | + * we can be sure they're done after we call synchronize_rcu(). | |
| 4442 | 4439 | */ |
| 4443 | 4440 | if (thread->looper & BINDER_LOOPER_STATE_POLL) |
| 4444 | 4441 | synchronize_rcu(); |
| @@ -438,6 +438,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { · 437 unmodified lines | ||
| 438 | 438 | /* AMD */ |
| 439 | 439 | { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ |
| 440 | 440 | { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ |
| 441 | + { PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */ | |
| 441 | 442 | /* AMD is using RAID class only for ahci controllers */ |
| 442 | 443 | { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| 443 | 444 | PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci }, |
| @@ -94,6 +94,7 @@ struct ceva_ahci_priv { · 93 unmodified lines | ||
| 94 | 94 | static unsigned int ceva_ahci_read_id(struct ata_device *dev, |
| 95 | 95 | struct ata_taskfile *tf, u16 *id) |
| 96 | 96 | { |
| 97 | + __le16 *__id = (__le16 *)id; | |
| 97 | 98 | u32 err_mask; |
| 98 | 99 | |
| 99 | 100 | err_mask = ata_do_dev_read_id(dev, tf, id); |
| @@ -103,7 +104,7 @@ static unsigned int ceva_ahci_read_id(struct ata_device *dev, · 3 unmodified lines | ||
| 103 | 104 | * Since CEVA controller does not support device sleep feature, we |
| 104 | 105 | * need to clear DEVSLP (bit 8) in word78 of the IDENTIFY DEVICE data. |
| 105 | 106 | */ |
| 106 | − id[ATA_ID_FEATURE_SUPP] &= cpu_to_le16(~(1 << 8)); | |
| 107 | + __id[ATA_ID_FEATURE_SUPP] &= cpu_to_le16(~(1 << 8)); | |
| 107 | 108 | |
| 108 | 109 | return 0; |
| 109 | 110 | } |
| @@ -2323,6 +2323,18 @@ int ahci_port_resume(struct ata_port *ap) · 2322 unmodified lines | ||
| 2323 | 2323 | EXPORT_SYMBOL_GPL(ahci_port_resume); |
| 2324 | 2324 | |
| 2325 | 2325 | #ifdef CONFIG_PM |
| 2326 | +static void ahci_handle_s2idle(struct ata_port *ap) | |
| 2327 | +{ | |
| 2328 | + void __iomem *port_mmio = ahci_port_base(ap); | |
| 2329 | + u32 devslp; | |
| 2330 | + | |
| 2331 | + if (pm_suspend_via_firmware()) | |
| 2332 | + return; | |
| 2333 | + devslp = readl(port_mmio + PORT_DEVSLP); | |
| 2334 | + if ((devslp & PORT_DEVSLP_ADSE)) | |
| 2335 | + ata_msleep(ap, devslp_idle_timeout); | |
| 2336 | +} | |
| 2337 | + | |
| 2326 | 2338 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) |
| 2327 | 2339 | { |
| 2328 | 2340 | const char *emsg = NULL; |
| @@ -2336,6 +2348,9 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) · 7 unmodified lines | ||
| 2336 | 2348 | ata_port_freeze(ap); |
| 2337 | 2349 | } |
| 2338 | 2350 | |
| 2351 | + if (acpi_storage_d3(ap->host->dev)) | |
| 2352 | + ahci_handle_s2idle(ap); | |
| 2353 | + | |
| 2339 | 2354 | ahci_rpm_put_port(ap); |
| 2340 | 2355 | return rc; |
| 2341 | 2356 | } |
| @@ -2031,8 +2031,9 @@ retry: · 2030 unmodified lines | ||
| 2031 | 2031 | dev->horkage |= ATA_HORKAGE_NO_DMA_LOG; |
| 2032 | 2032 | goto retry; |
| 2033 | 2033 | } |
| 2034 | − ata_dev_err(dev, "Read log page 0x%02x failed, Emask 0x%x\n", | |
| 2035 | − (unsigned int)page, err_mask); | |
| 2034 | + ata_dev_err(dev, | |
| 2035 | + "Read log 0x%02x page 0x%02x failed, Emask 0x%x\n", | |
| 2036 | + (unsigned int)log, (unsigned int)page, err_mask); | |
| 2036 | 2037 | } |
| 2037 | 2038 | |
| 2038 | 2039 | return err_mask; |
| @@ -2177,6 +2178,9 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev) · 138 unmodified lines | ||
| 2177 | 2178 | struct ata_port *ap = dev->link->ap; |
| 2178 | 2179 | unsigned int err_mask; |
| 2179 | 2180 | |
| 2181 | + if (!ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS)) | |
| 2182 | + return; | |
| 2183 | + | |
| 2180 | 2184 | err_mask = ata_read_log_page(dev, |
| 2181 | 2185 | ATA_LOG_IDENTIFY_DEVICE, |
| 2182 | 2186 | ATA_LOG_SATA_SETTINGS, |
| @@ -2453,7 +2457,8 @@ static void ata_dev_config_devslp(struct ata_device *dev) · 270 unmodified lines | ||
| 2453 | 2457 | * Check device sleep capability. Get DevSlp timing variables |
| 2454 | 2458 | * from SATA Settings page of Identify Device Data Log. |
| 2455 | 2459 | */ |
| 2456 | − if (!ata_id_has_devslp(dev->id)) | |
| 2460 | + if (!ata_id_has_devslp(dev->id) || | |
| 2461 | + !ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS)) | |
| 2457 | 2462 | return; |
| 2458 | 2463 | |
| 2459 | 2464 | err_mask = ata_read_log_page(dev, |
| @@ -3915,6 +3920,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { · 1455 unmodified lines | ||
| 3915 | 3920 | { "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA }, |
| 3916 | 3921 | /* Odd clown on sil3726/4726 PMPs */ |
| 3917 | 3922 | { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, |
| 3923 | + /* Similar story with ASMedia 1092 */ | |
| 3924 | + { "ASMT109x- Config", NULL, ATA_HORKAGE_DISABLE }, | |
| 3918 | 3925 | |
| 3919 | 3926 | /* Weird ATAPI devices */ |
| 3920 | 3927 | { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, |
| @@ -827,7 +827,7 @@ static ssize_t ata_scsi_lpm_show(struct device *dev, · 826 unmodified lines | ||
| 827 | 827 | if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) |
| 828 | 828 | return -EINVAL; |
| 829 | 829 | |
| 830 | − return snprintf(buf, PAGE_SIZE, "%s\n", | |
| 830 | + return sysfs_emit(buf, "%s\n", | |
| 831 | 831 | ata_lpm_policy_names[ap->target_lpm_policy]); |
| 832 | 832 | } |
| 833 | 833 | DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, |
| @@ -922,7 +922,7 @@ DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, · 88 unmodified lines | ||
| 922 | 922 | ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); |
| 923 | 923 | EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); |
| 924 | 924 | |
| 925 | −struct attribute *ata_ncq_sdev_attrs[] = { | |
| 925 | +static struct attribute *ata_ncq_sdev_attrs[] = { | |
| 926 | 926 | &dev_attr_unload_heads.attr, |
| 927 | 927 | &dev_attr_ncq_prio_enable.attr, |
| 928 | 928 | &dev_attr_ncq_prio_supported.attr, |
| @@ -55,14 +55,14 @@ static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc, · 54 unmodified lines | ||
| 55 | 55 | /* Transfer multiple of 2 bytes */ |
| 56 | 56 | if (rw == READ) { |
| 57 | 57 | if (swap) |
| 58 | − raw_insw_swapw((u16 *)data_addr, (u16 *)buf, words); | |
| 58 | + raw_insw_swapw(data_addr, (u16 *)buf, words); | |
| 59 | 59 | else |
| 60 | − raw_insw((u16 *)data_addr, (u16 *)buf, words); | |
| 60 | + raw_insw(data_addr, (u16 *)buf, words); | |
| 61 | 61 | } else { |
| 62 | 62 | if (swap) |
| 63 | − raw_outsw_swapw((u16 *)data_addr, (u16 *)buf, words); | |
| 63 | + raw_outsw_swapw(data_addr, (u16 *)buf, words); | |
| 64 | 64 | else |
| 65 | − raw_outsw((u16 *)data_addr, (u16 *)buf, words); | |
| 65 | + raw_outsw(data_addr, (u16 *)buf, words); | |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | /* Transfer trailing byte, if any. */ |
| @@ -74,16 +74,16 @@ static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc, · 5 unmodified lines | ||
| 74 | 74 | |
| 75 | 75 | if (rw == READ) { |
| 76 | 76 | if (swap) |
| 77 | − raw_insw_swapw((u16 *)data_addr, (u16 *)pad, 1); | |
| 77 | + raw_insw_swapw(data_addr, (u16 *)pad, 1); | |
| 78 | 78 | else |
| 79 | − raw_insw((u16 *)data_addr, (u16 *)pad, 1); | |
| 79 | + raw_insw(data_addr, (u16 *)pad, 1); | |
| 80 | 80 | *buf = pad[0]; |
| 81 | 81 | } else { |
| 82 | 82 | pad[0] = *buf; |
| 83 | 83 | if (swap) |
| 84 | − raw_outsw_swapw((u16 *)data_addr, (u16 *)pad, 1); | |
| 84 | + raw_outsw_swapw(data_addr, (u16 *)pad, 1); | |
| 85 | 85 | else |
| 86 | − raw_outsw((u16 *)data_addr, (u16 *)pad, 1); | |
| 86 | + raw_outsw(data_addr, (u16 *)pad, 1); | |
| 87 | 87 | } |
| 88 | 88 | words++; |
| 89 | 89 | } |
| @@ -1394,6 +1394,14 @@ static int sata_fsl_init_controller(struct ata_host *host) · 1393 unmodified lines | ||
| 1394 | 1394 | return 0; |
| 1395 | 1395 | } |
| 1396 | 1396 | |
| 1397 | +static void sata_fsl_host_stop(struct ata_host *host) | |
| 1398 | +{ | |
| 1399 | + struct sata_fsl_host_priv *host_priv = host->private_data; | |
| 1400 | + | |
| 1401 | + iounmap(host_priv->hcr_base); | |
| 1402 | + kfree(host_priv); | |
| 1403 | +} | |
| 1404 | + | |
| 1397 | 1405 | /* |
| 1398 | 1406 | * scsi mid-layer and libata interface structures |
| 1399 | 1407 | */ |
| @@ -1426,6 +1434,8 @@ static struct ata_port_operations sata_fsl_ops = { · 26 unmodified lines | ||
| 1426 | 1434 | .port_start = sata_fsl_port_start, |
| 1427 | 1435 | .port_stop = sata_fsl_port_stop, |
| 1428 | 1436 | |
| 1437 | + .host_stop = sata_fsl_host_stop, | |
| 1438 | + | |
| 1429 | 1439 | .pmp_attach = sata_fsl_pmp_attach, |
| 1430 | 1440 | .pmp_detach = sata_fsl_pmp_detach, |
| 1431 | 1441 | }; |
| @@ -1480,9 +1490,9 @@ static int sata_fsl_probe(struct platform_device *ofdev) · 48 unmodified lines | ||
| 1480 | 1490 | host_priv->ssr_base = ssr_base; |
| 1481 | 1491 | host_priv->csr_base = csr_base; |
| 1482 | 1492 | |
| 1483 | − irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); | |
| 1484 | − if (!irq) { | |
| 1485 | − dev_err(&ofdev->dev, "invalid irq from platform\n"); | |
| 1493 | + irq = platform_get_irq(ofdev, 0); | |
| 1494 | + if (irq < 0) { | |
| 1495 | + retval = irq; | |
| 1486 | 1496 | goto error_exit_with_cleanup; |
| 1487 | 1497 | } |
| 1488 | 1498 | host_priv->irq = irq; |
| @@ -1557,10 +1567,6 @@ static int sata_fsl_remove(struct platform_device *ofdev) · 68 unmodified lines | ||
| 1557 | 1567 | |
| 1558 | 1568 | ata_host_detach(host); |
| 1559 | 1569 | |
| 1560 | − irq_dispose_mapping(host_priv->irq); | |
| 1561 | − iounmap(host_priv->hcr_base); | |
| 1562 | − kfree(host_priv); | |
| 1563 | − | |
| 1564 | 1570 | return 0; |
| 1565 | 1571 | } |
| 1566 | 1572 | |
| @@ -2103,7 +2103,7 @@ static int loop_control_remove(int idx) · 2102 unmodified lines | ||
| 2103 | 2103 | int ret; |
| 2104 | 2104 | |
| 2105 | 2105 | if (idx < 0) { |
| 2106 | − pr_warn("deleting an unspecified loop device is not supported.\n"); | |
| 2106 | + pr_warn_once("deleting an unspecified loop device is not supported.\n"); | |
| 2107 | 2107 | return -EINVAL; |
| 2108 | 2108 | } |
| 2109 | 2109 | |
| @@ -316,7 +316,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, · 315 unmodified lines | ||
| 316 | 316 | struct request *req = bd->rq; |
| 317 | 317 | struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); |
| 318 | 318 | unsigned long flags; |
| 319 | − unsigned int num; | |
| 319 | + int num; | |
| 320 | 320 | int qid = hctx->queue_num; |
| 321 | 321 | bool notify = false; |
| 322 | 322 | blk_status_t status; |
| @@ -1049,7 +1049,6 @@ static struct virtio_driver virtio_blk = { · 726 unmodified lines | ||
| 1049 | 1049 | .feature_table_size = ARRAY_SIZE(features), |
| 1050 | 1050 | .feature_table_legacy = features_legacy, |
| 1051 | 1051 | .feature_table_size_legacy = ARRAY_SIZE(features_legacy), |
| 1052 | − .suppress_used_validation = true, | |
| 1053 | 1052 | .driver.name = KBUILD_MODNAME, |
| 1054 | 1053 | .driver.owner = THIS_MODULE, |
| 1055 | 1054 | .id_table = id_table, |
| @@ -1853,12 +1853,14 @@ static const struct block_device_operations zram_devops = { · 1852 unmodified lines | ||
| 1853 | 1853 | .owner = THIS_MODULE |
| 1854 | 1854 | }; |
| 1855 | 1855 | |
| 1856 | +#ifdef CONFIG_ZRAM_WRITEBACK | |
| 1856 | 1857 | static const struct block_device_operations zram_wb_devops = { |
| 1857 | 1858 | .open = zram_open, |
| 1858 | 1859 | .submit_bio = zram_submit_bio, |
| 1859 | 1860 | .swap_slot_free_notify = zram_slot_free_notify, |
| 1860 | 1861 | .owner = THIS_MODULE |
| 1861 | 1862 | }; |
| 1863 | +#endif | |
| 1862 | 1864 | |
| 1863 | 1865 | static DEVICE_ATTR_WO(compact); |
| 1864 | 1866 | static DEVICE_ATTR_RW(disksize); |
| @@ -881,7 +881,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) · 880 unmodified lines | ||
| 881 | 881 | } |
| 882 | 882 | EXPORT_SYMBOL_GPL(mhi_pm_suspend); |
| 883 | 883 | |
| 884 | −int mhi_pm_resume(struct mhi_controller *mhi_cntrl) | |
| 884 | +static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) | |
| 885 | 885 | { |
| 886 | 886 | struct mhi_chan *itr, *tmp; |
| 887 | 887 | struct device *dev = &mhi_cntrl->mhi_dev->dev; |
| @@ -898,8 +898,12 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) · 10 unmodified lines | ||
| 898 | 898 | if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) |
| 899 | 899 | return -EIO; |
| 900 | 900 | |
| 901 | − if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) | |
| 902 | − return -EINVAL; | |
| 901 | + if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) { | |
| 902 | + dev_warn(dev, "Resuming from non M3 state (%s)\n", | |
| 903 | + TO_MHI_STATE_STR(mhi_get_mhi_state(mhi_cntrl))); | |
| 904 | + if (!force) | |
| 905 | + return -EINVAL; | |
| 906 | + } | |
| 903 | 907 | |
| 904 | 908 | /* Notify clients about exiting LPM */ |
| 905 | 909 | list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { |
| @@ -940,8 +944,19 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) · 34 unmodified lines | ||
| 940 | 944 | |
| 941 | 945 | return 0; |
| 942 | 946 | } |
| 947 | + | |
| 948 | +int mhi_pm_resume(struct mhi_controller *mhi_cntrl) | |
| 949 | +{ | |
| 950 | + return __mhi_pm_resume(mhi_cntrl, false); | |
| 951 | +} | |
| 943 | 952 | EXPORT_SYMBOL_GPL(mhi_pm_resume); |
| 944 | 953 | |
| 954 | +int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl) | |
| 955 | +{ | |
| 956 | + return __mhi_pm_resume(mhi_cntrl, true); | |
| 957 | +} | |
| 958 | +EXPORT_SYMBOL_GPL(mhi_pm_resume_force); | |
| 959 | + | |
| 945 | 960 | int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) |
| 946 | 961 | { |
| 947 | 962 | int ret; |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #define MHI_PCI_DEFAULT_BAR_NUM 0 |
| 22 | 22 | |
| 23 | −#define MHI_POST_RESET_DELAY_MS 500 | |
| 23 | +#define MHI_POST_RESET_DELAY_MS 2000 | |
| 24 | 24 | |
| 25 | 25 | #define HEALTH_CHECK_PERIOD (HZ * 2) |
| 26 | 26 | |
| @@ -281,7 +281,7 @@ agp_ioc_init(void __iomem *ioc_regs) · 280 unmodified lines | ||
| 281 | 281 | return 0; |
| 282 | 282 | } |
| 283 | 283 | |
| 284 | −static int | |
| 284 | +static int __init | |
| 285 | 285 | lba_find_capability(int cap) |
| 286 | 286 | { |
| 287 | 287 | struct _parisc_agp_info *info = &parisc_agp_info; |
| @@ -366,7 +366,7 @@ fail: · 78 unmodified lines | ||
| 366 | 366 | return error; |
| 367 | 367 | } |
| 368 | 368 | |
| 369 | −static int | |
| 369 | +static int __init | |
| 370 | 370 | find_quicksilver(struct device *dev, void *data) |
| 371 | 371 | { |
| 372 | 372 | struct parisc_device **lba = data; |
| @@ -378,7 +378,7 @@ find_quicksilver(struct device *dev, void *data) · 5 unmodified lines | ||
| 378 | 378 | return 0; |
| 379 | 379 | } |
| 380 | 380 | |
| 381 | −static int | |
| 381 | +static int __init | |
| 382 | 382 | parisc_agp_init(void) |
| 383 | 383 | { |
| 384 | 384 | extern struct sba_device *sba_list; |
| @@ -191,6 +191,8 @@ struct ipmi_user { · 190 unmodified lines | ||
| 191 | 191 | struct work_struct remove_work; |
| 192 | 192 | }; |
| 193 | 193 | |
| 194 | +static struct workqueue_struct *remove_work_wq; | |
| 195 | + | |
| 194 | 196 | static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index) |
| 195 | 197 | __acquires(user->release_barrier) |
| 196 | 198 | { |
| @@ -1297,7 +1299,7 @@ static void free_user(struct kref *ref) · 1100 unmodified lines | ||
| 1297 | 1299 | struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); |
| 1298 | 1300 | |
| 1299 | 1301 | /* SRCU cleanup must happen in task context. */ |
| 1300 | − schedule_work(&user->remove_work); | |
| 1302 | + queue_work(remove_work_wq, &user->remove_work); | |
| 1301 | 1303 | } |
| 1302 | 1304 | |
| 1303 | 1305 | static void _ipmi_destroy_user(struct ipmi_user *user) |
| @@ -3918,9 +3920,11 @@ static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf, · 2614 unmodified lines | ||
| 3918 | 3920 | /* We didn't find a user, deliver an error response. */ |
| 3919 | 3921 | ipmi_inc_stat(intf, unhandled_commands); |
| 3920 | 3922 | |
| 3921 | − msg->data[0] = ((netfn + 1) << 2) | (msg->rsp[4] & 0x3); | |
| 3922 | − msg->data[1] = msg->rsp[2]; | |
| 3923 | − msg->data[2] = msg->rsp[4] & ~0x3; | |
| 3923 | + msg->data[0] = (netfn + 1) << 2; | |
| 3924 | + msg->data[0] |= msg->rsp[2] & 0x3; /* rqLUN */ | |
| 3925 | + msg->data[1] = msg->rsp[1]; /* Addr */ | |
| 3926 | + msg->data[2] = msg->rsp[2] & ~0x3; /* rqSeq */ | |
| 3927 | + msg->data[2] |= msg->rsp[0] & 0x3; /* rsLUN */ | |
| 3924 | 3928 | msg->data[3] = cmd; |
| 3925 | 3929 | msg->data[4] = IPMI_INVALID_CMD_COMPLETION_CODE; |
| 3926 | 3930 | msg->data_size = 5; |
| @@ -4455,13 +4459,24 @@ return_unspecified: · 528 unmodified lines | ||
| 4455 | 4459 | msg->rsp[2] = IPMI_ERR_UNSPECIFIED; |
| 4456 | 4460 | msg->rsp_size = 3; |
| 4457 | 4461 | } else if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) { |
| 4458 | − /* commands must have at least 3 bytes, responses 4. */ | |
| 4459 | − if (is_cmd && (msg->rsp_size < 3)) { | |
| 4462 | + /* commands must have at least 4 bytes, responses 5. */ | |
| 4463 | + if (is_cmd && (msg->rsp_size < 4)) { | |
| 4460 | 4464 | ipmi_inc_stat(intf, invalid_commands); |
| 4461 | 4465 | goto out; |
| 4462 | 4466 | } |
| 4463 | − if (!is_cmd && (msg->rsp_size < 4)) | |
| 4464 | − goto return_unspecified; | |
| 4467 | + if (!is_cmd && (msg->rsp_size < 5)) { | |
| 4468 | + ipmi_inc_stat(intf, invalid_ipmb_responses); | |
| 4469 | + /* Construct a valid error response. */ | |
| 4470 | + msg->rsp[0] = msg->data[0] & 0xfc; /* NetFN */ | |
| 4471 | + msg->rsp[0] |= (1 << 2); /* Make it a response */ | |
| 4472 | + msg->rsp[0] |= msg->data[2] & 3; /* rqLUN */ | |
| 4473 | + msg->rsp[1] = msg->data[1]; /* Addr */ | |
| 4474 | + msg->rsp[2] = msg->data[2] & 0xfc; /* rqSeq */ | |
| 4475 | + msg->rsp[2] |= msg->data[0] & 0x3; /* rsLUN */ | |
| 4476 | + msg->rsp[3] = msg->data[3]; /* Cmd */ | |
| 4477 | + msg->rsp[4] = IPMI_ERR_UNSPECIFIED; | |
| 4478 | + msg->rsp_size = 5; | |
| 4479 | + } | |
| 4465 | 4480 | } else if ((msg->data_size >= 2) |
| 4466 | 4481 | && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) |
| 4467 | 4482 | && (msg->data[1] == IPMI_SEND_MSG_CMD) |
| @@ -5031,6 +5046,7 @@ struct ipmi_smi_msg *ipmi_alloc_smi_msg(void) · 563 unmodified lines | ||
| 5031 | 5046 | if (rv) { |
| 5032 | 5047 | rv->done = free_smi_msg; |
| 5033 | 5048 | rv->user_data = NULL; |
| 5049 | + rv->type = IPMI_SMI_MSG_TYPE_NORMAL; | |
| 5034 | 5050 | atomic_inc(&smi_msg_inuse_count); |
| 5035 | 5051 | } |
| 5036 | 5052 | return rv; |
| @@ -5383,6 +5399,13 @@ static int ipmi_init_msghandler(void) · 346 unmodified lines | ||
| 5383 | 5399 | |
| 5384 | 5400 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
| 5385 | 5401 | |
| 5402 | + remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq"); | |
| 5403 | + if (!remove_work_wq) { | |
| 5404 | + pr_err("unable to create ipmi-msghandler-remove-wq workqueue"); | |
| 5405 | + rv = -ENOMEM; | |
| 5406 | + goto out; | |
| 5407 | + } | |
| 5408 | + | |
| 5386 | 5409 | initialized = true; |
| 5387 | 5410 | |
| 5388 | 5411 | out: |
| @@ -5408,6 +5431,8 @@ static void __exit cleanup_ipmi(void) · 19 unmodified lines | ||
| 5408 | 5431 | int count; |
| 5409 | 5432 | |
| 5410 | 5433 | if (initialized) { |
| 5434 | + destroy_workqueue(remove_work_wq); | |
| 5435 | + | |
| 5411 | 5436 | atomic_notifier_chain_unregister(&panic_notifier_list, |
| 5412 | 5437 | &panic_block); |
| 5413 | 5438 | |
| @@ -370,7 +370,7 @@ static struct platform_driver imx8qxp_lpcg_clk_driver = { · 369 unmodified lines | ||
| 370 | 370 | .probe = imx8qxp_lpcg_clk_probe, |
| 371 | 371 | }; |
| 372 | 372 | |
| 373 | −builtin_platform_driver(imx8qxp_lpcg_clk_driver); | |
| 373 | +module_platform_driver(imx8qxp_lpcg_clk_driver); | |
| 374 | 374 | |
| 375 | 375 | MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>"); |
| 376 | 376 | MODULE_DESCRIPTION("NXP i.MX8QXP LPCG clock driver"); |
| @@ -308,7 +308,7 @@ static struct platform_driver imx8qxp_clk_driver = { · 307 unmodified lines | ||
| 308 | 308 | }, |
| 309 | 309 | .probe = imx8qxp_clk_probe, |
| 310 | 310 | }; |
| 311 | −builtin_platform_driver(imx8qxp_clk_driver); | |
| 311 | +module_platform_driver(imx8qxp_clk_driver); | |
| 312 | 312 | |
| 313 | 313 | MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>"); |
| 314 | 314 | MODULE_DESCRIPTION("NXP i.MX8QXP clock driver"); |
| @@ -1429,6 +1429,15 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops); · 1428 unmodified lines | ||
| 1429 | 1429 | void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, |
| 1430 | 1430 | const struct alpha_pll_config *config) |
| 1431 | 1431 | { |
| 1432 | + /* | |
| 1433 | + * If the bootloader left the PLL enabled it's likely that there are | |
| 1434 | + * RCGs that will lock up if we disable the PLL below. | |
| 1435 | + */ | |
| 1436 | + if (trion_pll_is_enabled(pll, regmap)) { | |
| 1437 | + pr_debug("Trion PLL is already enabled, skipping configuration\n"); | |
| 1438 | + return; | |
| 1439 | + } | |
| 1440 | + | |
| 1432 | 1441 | clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); |
| 1433 | 1442 | regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL); |
| 1434 | 1443 | clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); |
| @@ -28,7 +28,7 @@ static u8 mux_get_parent(struct clk_hw *hw) · 27 unmodified lines | ||
| 28 | 28 | val &= mask; |
| 29 | 29 | |
| 30 | 30 | if (mux->parent_map) |
| 31 | − return qcom_find_src_index(hw, mux->parent_map, val); | |
| 31 | + return qcom_find_cfg_index(hw, mux->parent_map, val); | |
| 32 | 32 | |
| 33 | 33 | return val; |
| 34 | 34 | } |
| @@ -69,6 +69,18 @@ int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src) · 68 unmodified lines | ||
| 69 | 69 | } |
| 70 | 70 | EXPORT_SYMBOL_GPL(qcom_find_src_index); |
| 71 | 71 | |
| 72 | +int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map, u8 cfg) | |
| 73 | +{ | |
| 74 | + int i, num_parents = clk_hw_get_num_parents(hw); | |
| 75 | + | |
| 76 | + for (i = 0; i < num_parents; i++) | |
| 77 | + if (cfg == map[i].cfg) | |
| 78 | + return i; | |
| 79 | + | |
| 80 | + return -ENOENT; | |
| 81 | +} | |
| 82 | +EXPORT_SYMBOL_GPL(qcom_find_cfg_index); | |
| 83 | + | |
| 72 | 84 | struct regmap * |
| 73 | 85 | qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc) |
| 74 | 86 | { |
| @@ -49,6 +49,8 @@ extern void · 48 unmodified lines | ||
| 49 | 49 | qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count); |
| 50 | 50 | extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, |
| 51 | 51 | u8 src); |
| 52 | +extern int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map, | |
| 53 | + u8 cfg); | |
| 52 | 54 | |
| 53 | 55 | extern int qcom_cc_register_board_clk(struct device *dev, const char *path, |
| 54 | 56 | const char *name, unsigned long rate); |
| @@ -1121,7 +1121,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { · 1120 unmodified lines | ||
| 1121 | 1121 | .name = "gcc_sdcc1_apps_clk_src", |
| 1122 | 1122 | .parent_data = gcc_parent_data_1, |
| 1123 | 1123 | .num_parents = ARRAY_SIZE(gcc_parent_data_1), |
| 1124 | − .ops = &clk_rcg2_ops, | |
| 1124 | + .ops = &clk_rcg2_floor_ops, | |
| 1125 | 1125 | }, |
| 1126 | 1126 | }; |
| 1127 | 1127 | |
| @@ -1143,7 +1143,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { · 15 unmodified lines | ||
| 1143 | 1143 | .name = "gcc_sdcc1_ice_core_clk_src", |
| 1144 | 1144 | .parent_data = gcc_parent_data_0, |
| 1145 | 1145 | .num_parents = ARRAY_SIZE(gcc_parent_data_0), |
| 1146 | − .ops = &clk_rcg2_floor_ops, | |
| 1146 | + .ops = &clk_rcg2_ops, | |
| 1147 | 1147 | }, |
| 1148 | 1148 | }; |
| 1149 | 1149 | |
| @@ -543,8 +543,8 @@ static void __init of_syscon_icst_setup(struct device_node *np) · 542 unmodified lines | ||
| 543 | 543 | |
| 544 | 544 | regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype); |
| 545 | 545 | if (IS_ERR(regclk)) { |
| 546 | − kfree(name); | |
| 547 | 546 | pr_err("error setting up syscon ICST clock %s\n", name); |
| 547 | + kfree(name); | |
| 548 | 548 | return; |
| 549 | 549 | } |
| 550 | 550 | of_clk_add_provider(np, of_clk_src_simple_get, regclk); |
| @@ -394,8 +394,13 @@ EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); · 393 unmodified lines | ||
| 394 | 394 | |
| 395 | 395 | static atomic_t timer_unstable_counter_workaround_in_use = ATOMIC_INIT(0); |
| 396 | 396 | |
| 397 | −static void erratum_set_next_event_generic(const int access, unsigned long evt, | |
| 398 | − struct clock_event_device *clk) | |
| 397 | +/* | |
| 398 | + * Force the inlining of this function so that the register accesses | |
| 399 | + * can be themselves correctly inlined. | |
| 400 | + */ | |
| 401 | +static __always_inline | |
| 402 | +void erratum_set_next_event_generic(const int access, unsigned long evt, | |
| 403 | + struct clock_event_device *clk) | |
| 399 | 404 | { |
| 400 | 405 | unsigned long ctrl; |
| 401 | 406 | u64 cval; |
| @@ -47,7 +47,7 @@ static int __init timer_get_base_and_rate(struct device_node *np, · 46 unmodified lines | ||
| 47 | 47 | pr_warn("pclk for %pOFn is present, but could not be activated\n", |
| 48 | 48 | np); |
| 49 | 49 | |
| 50 | − if (!of_property_read_u32(np, "clock-freq", rate) && | |
| 50 | + if (!of_property_read_u32(np, "clock-freq", rate) || | |
| 51 | 51 | !of_property_read_u32(np, "clock-frequency", rate)) |
| 52 | 52 | return 0; |
| 53 | 53 | |
| @@ -1004,10 +1004,9 @@ static struct kobj_type ktype_cpufreq = { · 1003 unmodified lines | ||
| 1004 | 1004 | .release = cpufreq_sysfs_release, |
| 1005 | 1005 | }; |
| 1006 | 1006 | |
| 1007 | −static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu) | |
| 1007 | +static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu, | |
| 1008 | + struct device *dev) | |
| 1008 | 1009 | { |
| 1009 | − struct device *dev = get_cpu_device(cpu); | |
| 1010 | − | |
| 1011 | 1010 | if (unlikely(!dev)) |
| 1012 | 1011 | return; |
| 1013 | 1012 | |
| @@ -1296,8 +1295,9 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy) · 282 unmodified lines | ||
| 1296 | 1295 | |
| 1297 | 1296 | if (policy->max_freq_req) { |
| 1298 | 1297 | /* |
| 1299 | − * CPUFREQ_CREATE_POLICY notification is sent only after | |
| 1300 | − * successfully adding max_freq_req request. | |
| 1298 | + * Remove max_freq_req after sending CPUFREQ_REMOVE_POLICY | |
| 1299 | + * notification, since CPUFREQ_CREATE_POLICY notification was | |
| 1300 | + * sent after adding max_freq_req earlier. | |
| 1301 | 1301 | */ |
| 1302 | 1302 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
| 1303 | 1303 | CPUFREQ_REMOVE_POLICY, policy); |
| @@ -1391,7 +1391,7 @@ static int cpufreq_online(unsigned int cpu) · 87 unmodified lines | ||
| 1391 | 1391 | if (new_policy) { |
| 1392 | 1392 | for_each_cpu(j, policy->related_cpus) { |
| 1393 | 1393 | per_cpu(cpufreq_cpu_data, j) = policy; |
| 1394 | − add_cpu_dev_symlink(policy, j); | |
| 1394 | + add_cpu_dev_symlink(policy, j, get_cpu_device(j)); | |
| 1395 | 1395 | } |
| 1396 | 1396 | |
| 1397 | 1397 | policy->min_freq_req = kzalloc(2 * sizeof(*policy->min_freq_req), |
| @@ -1565,7 +1565,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) · 167 unmodified lines | ||
| 1565 | 1565 | /* Create sysfs link on CPU registration */ |
| 1566 | 1566 | policy = per_cpu(cpufreq_cpu_data, cpu); |
| 1567 | 1567 | if (policy) |
| 1568 | − add_cpu_dev_symlink(policy, cpu); | |
| 1568 | + add_cpu_dev_symlink(policy, cpu, dev); | |
| 1569 | 1569 | |
| 1570 | 1570 | return 0; |
| 1571 | 1571 | } |
| @@ -338,6 +338,8 @@ static void intel_pstste_sched_itmt_work_fn(struct work_struct *work) · 337 unmodified lines | ||
| 338 | 338 | |
| 339 | 339 | static DECLARE_WORK(sched_itmt_work, intel_pstste_sched_itmt_work_fn); |
| 340 | 340 | |
| 341 | +#define CPPC_MAX_PERF U8_MAX | |
| 342 | + | |
| 341 | 343 | static void intel_pstate_set_itmt_prio(int cpu) |
| 342 | 344 | { |
| 343 | 345 | struct cppc_perf_caps cppc_perf; |
| @@ -348,6 +350,14 @@ static void intel_pstate_set_itmt_prio(int cpu) · 4 unmodified lines | ||
| 348 | 350 | if (ret) |
| 349 | 351 | return; |
| 350 | 352 | |
| 353 | + /* | |
| 354 | + * On some systems with overclocking enabled, CPPC.highest_perf is hardcoded to 0xff. | |
| 355 | + * In this case we can't use CPPC.highest_perf to enable ITMT. | |
| 356 | + * In this case we can look at MSR_HWP_CAPABILITIES bits [8:0] to decide. | |
| 357 | + */ | |
| 358 | + if (cppc_perf.highest_perf == CPPC_MAX_PERF) | |
| 359 | + cppc_perf.highest_perf = HWP_HIGHEST_PERF(READ_ONCE(all_cpu_data[cpu]->hwp_cap_cached)); | |
| 360 | + | |
| 351 | 361 | /* |
| 352 | 362 | * The priorities can be set regardless of whether or not |
| 353 | 363 | * sched_set_itmt_support(true) has been called and it is valid to |
| @@ -1006,6 +1016,12 @@ static void intel_pstate_hwp_offline(struct cpudata *cpu) · 652 unmodified lines | ||
| 1006 | 1016 | */ |
| 1007 | 1017 | value &= ~GENMASK_ULL(31, 24); |
| 1008 | 1018 | value |= HWP_ENERGY_PERF_PREFERENCE(cpu->epp_cached); |
| 1019 | + /* | |
| 1020 | + * However, make sure that EPP will be set to "performance" when | |
| 1021 | + * the CPU is brought back online again and the "performance" | |
| 1022 | + * scaling algorithm is still in effect. | |
| 1023 | + */ | |
| 1024 | + cpu->epp_policy = CPUFREQ_POLICY_UNKNOWN; | |
| 1009 | 1025 | } |
| 1010 | 1026 | |
| 1011 | 1027 | /* |
| @@ -2353,6 +2369,7 @@ static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = { · 1341 unmodified lines | ||
| 2353 | 2369 | X86_MATCH(BROADWELL_D, core_funcs), |
| 2354 | 2370 | X86_MATCH(BROADWELL_X, core_funcs), |
| 2355 | 2371 | X86_MATCH(SKYLAKE_X, core_funcs), |
| 2372 | + X86_MATCH(ICELAKE_X, core_funcs), | |
| 2356 | 2373 | {} |
| 2357 | 2374 | }; |
| 2358 | 2375 | |
| @@ -290,7 +290,7 @@ static void system_heap_dma_buf_release(struct dma_buf *dmabuf) · 289 unmodified lines | ||
| 290 | 290 | int i; |
| 291 | 291 | |
| 292 | 292 | table = &buffer->sg_table; |
| 293 | − for_each_sg(table->sgl, sg, table->nents, i) { | |
| 293 | + for_each_sgtable_sg(table, sg, i) { | |
| 294 | 294 | struct page *page = sg_page(sg); |
| 295 | 295 | |
| 296 | 296 | __free_pages(page, compound_order(page)); |
| @@ -34,6 +34,12 @@ struct scmi_msg_resp_base_attributes { · 33 unmodified lines | ||
| 34 | 34 | __le16 reserved; |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | +struct scmi_msg_resp_base_discover_agent { | |
| 38 | + __le32 agent_id; | |
| 39 | + u8 name[SCMI_MAX_STR_SIZE]; | |
| 40 | +}; | |
| 41 | + | |
| 42 | + | |
| 37 | 43 | struct scmi_msg_base_error_notify { |
| 38 | 44 | __le32 event_control; |
| 39 | 45 | #define BASE_TP_NOTIFY_ALL BIT(0) |
| @@ -225,18 +231,21 @@ static int scmi_base_discover_agent_get(const struct scmi_protocol_handle *ph, · 185 unmodified lines | ||
| 225 | 231 | int id, char *name) |
| 226 | 232 | { |
| 227 | 233 | int ret; |
| 234 | + struct scmi_msg_resp_base_discover_agent *agent_info; | |
| 228 | 235 | struct scmi_xfer *t; |
| 229 | 236 | |
| 230 | 237 | ret = ph->xops->xfer_get_init(ph, BASE_DISCOVER_AGENT, |
| 231 | − sizeof(__le32), SCMI_MAX_STR_SIZE, &t); | |
| 238 | + sizeof(__le32), sizeof(*agent_info), &t); | |
| 232 | 239 | if (ret) |
| 233 | 240 | return ret; |
| 234 | 241 | |
| 235 | 242 | put_unaligned_le32(id, t->tx.buf); |
| 236 | 243 | |
| 237 | 244 | ret = ph->xops->do_xfer(ph, t); |
| 238 | − if (!ret) | |
| 239 | − strlcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE); | |
| 245 | + if (!ret) { | |
| 246 | + agent_info = t->rx.buf; | |
| 247 | + strlcpy(name, agent_info->name, SCMI_MAX_STR_SIZE); | |
| 248 | + } | |
| 240 | 249 | |
| 241 | 250 | ph->xops->xfer_put(ph, t); |
| 242 | 251 | |
| @@ -138,9 +138,7 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) · 137 unmodified lines | ||
| 138 | 138 | scmi_pd_data->domains = domains; |
| 139 | 139 | scmi_pd_data->num_domains = num_domains; |
| 140 | 140 | |
| 141 | − of_genpd_add_provider_onecell(np, scmi_pd_data); | |
| 142 | − | |
| 143 | − return 0; | |
| 141 | + return of_genpd_add_provider_onecell(np, scmi_pd_data); | |
| 144 | 142 | } |
| 145 | 143 | |
| 146 | 144 | static const struct scmi_device_id scmi_id_table[] = { |
| @@ -637,7 +637,7 @@ static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph, · 636 unmodified lines | ||
| 637 | 637 | if (ret) |
| 638 | 638 | return ret; |
| 639 | 639 | |
| 640 | − put_unaligned_le32(cpu_to_le32(sensor_id), t->tx.buf); | |
| 640 | + put_unaligned_le32(sensor_id, t->tx.buf); | |
| 641 | 641 | ret = ph->xops->do_xfer(ph, t); |
| 642 | 642 | if (!ret) { |
| 643 | 643 | struct sensors_info *si = ph->get_priv(ph); |
| @@ -82,7 +82,8 @@ static bool scmi_vio_have_vq_rx(struct virtio_device *vdev) · 81 unmodified lines | ||
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, |
| 85 | − struct scmi_vio_msg *msg) | |
| 85 | + struct scmi_vio_msg *msg, | |
| 86 | + struct device *dev) | |
| 86 | 87 | { |
| 87 | 88 | struct scatterlist sg_in; |
| 88 | 89 | int rc; |
| @@ -94,8 +95,7 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, · 5 unmodified lines | ||
| 94 | 95 | |
| 95 | 96 | rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC); |
| 96 | 97 | if (rc) |
| 97 | − dev_err_once(vioch->cinfo->dev, | |
| 98 | − "failed to add to virtqueue (%d)\n", rc); | |
| 98 | + dev_err_once(dev, "failed to add to virtqueue (%d)\n", rc); | |
| 99 | 99 | else |
| 100 | 100 | virtqueue_kick(vioch->vqueue); |
| 101 | 101 | |
| @@ -108,7 +108,7 @@ static void scmi_finalize_message(struct scmi_vio_channel *vioch, · 6 unmodified lines | ||
| 108 | 108 | struct scmi_vio_msg *msg) |
| 109 | 109 | { |
| 110 | 110 | if (vioch->is_rx) { |
| 111 | − scmi_vio_feed_vq_rx(vioch, msg); | |
| 111 | + scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev); | |
| 112 | 112 | } else { |
| 113 | 113 | /* Here IRQs are assumed to be already disabled by the caller */ |
| 114 | 114 | spin_lock(&vioch->lock); |
| @@ -269,7 +269,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 154 unmodified lines | ||
| 269 | 269 | list_add_tail(&msg->list, &vioch->free_list); |
| 270 | 270 | spin_unlock_irqrestore(&vioch->lock, flags); |
| 271 | 271 | } else { |
| 272 | − scmi_vio_feed_vq_rx(vioch, msg); | |
| 272 | + scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev); | |
| 273 | 273 | } |
| 274 | 274 | } |
| 275 | 275 | |
| @@ -156,7 +156,7 @@ static int scmi_voltage_descriptors_get(const struct scmi_protocol_handle *ph, · 155 unmodified lines | ||
| 156 | 156 | int cnt; |
| 157 | 157 | |
| 158 | 158 | cmd->domain_id = cpu_to_le32(v->id); |
| 159 | − cmd->level_index = desc_index; | |
| 159 | + cmd->level_index = cpu_to_le32(desc_index); | |
| 160 | 160 | ret = ph->xops->do_xfer(ph, tl); |
| 161 | 161 | if (ret) |
| 162 | 162 | break; |
| @@ -50,7 +50,7 @@ static int __init smccc_soc_init(void) · 49 unmodified lines | ||
| 50 | 50 | arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, |
| 51 | 51 | ARM_SMCCC_ARCH_SOC_ID, &res); |
| 52 | 52 | |
| 53 | − if (res.a0 == SMCCC_RET_NOT_SUPPORTED) { | |
| 53 | + if ((int)res.a0 == SMCCC_RET_NOT_SUPPORTED) { | |
| 54 | 54 | pr_info("ARCH_SOC_ID not implemented, skipping ....\n"); |
| 55 | 55 | return 0; |
| 56 | 56 | } |
| @@ -523,6 +523,7 @@ config GPIO_REG · 522 unmodified lines | ||
| 523 | 523 | config GPIO_ROCKCHIP |
| 524 | 524 | tristate "Rockchip GPIO support" |
| 525 | 525 | depends on ARCH_ROCKCHIP || COMPILE_TEST |
| 526 | + select GENERIC_IRQ_CHIP | |
| 526 | 527 | select GPIOLIB_IRQCHIP |
| 527 | 528 | default ARCH_ROCKCHIP |
| 528 | 529 | help |
| @@ -434,7 +434,7 @@ static void virtio_gpio_event_vq(struct virtqueue *vq) · 433 unmodified lines | ||
| 434 | 434 | ret = generic_handle_domain_irq(vgpio->gc.irq.domain, gpio); |
| 435 | 435 | if (ret) |
| 436 | 436 | dev_err(dev, "failed to handle interrupt: %d\n", ret); |
| 437 | − }; | |
| 437 | + } | |
| 438 | 438 | } |
| 439 | 439 | |
| 440 | 440 | static void virtio_gpio_request_vq(struct virtqueue *vq) |
| @@ -646,12 +646,6 @@ kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem, · 645 unmodified lines | ||
| 646 | 646 | if (IS_ERR(gobj)) |
| 647 | 647 | return PTR_ERR(gobj); |
| 648 | 648 | |
| 649 | − /* Import takes an extra reference on the dmabuf. Drop it now to | |
| 650 | − * avoid leaking it. We only need the one reference in | |
| 651 | − * kgd_mem->dmabuf. | |
| 652 | − */ | |
| 653 | − dma_buf_put(mem->dmabuf); | |
| 654 | − | |
| 655 | 649 | *bo = gem_to_amdgpu_bo(gobj); |
| 656 | 650 | (*bo)->flags |= AMDGPU_GEM_CREATE_PREEMPTIBLE; |
| 657 | 651 | (*bo)->parent = amdgpu_bo_ref(mem->bo); |
| @@ -1402,7 +1396,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( · 744 unmodified lines | ||
| 1402 | 1396 | struct sg_table *sg = NULL; |
| 1403 | 1397 | uint64_t user_addr = 0; |
| 1404 | 1398 | struct amdgpu_bo *bo; |
| 1405 | − struct drm_gem_object *gobj; | |
| 1399 | + struct drm_gem_object *gobj = NULL; | |
| 1406 | 1400 | u32 domain, alloc_domain; |
| 1407 | 1401 | u64 alloc_flags; |
| 1408 | 1402 | int ret; |
| @@ -1512,14 +1506,16 @@ allocate_init_user_pages_failed: · 103 unmodified lines | ||
| 1512 | 1506 | remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); |
| 1513 | 1507 | drm_vma_node_revoke(&gobj->vma_node, drm_priv); |
| 1514 | 1508 | err_node_allow: |
| 1515 | − drm_gem_object_put(gobj); | |
| 1516 | 1509 | /* Don't unreserve system mem limit twice */ |
| 1517 | 1510 | goto err_reserve_limit; |
| 1518 | 1511 | err_bo_create: |
| 1519 | 1512 | unreserve_mem_limit(adev, size, alloc_domain, !!sg); |
| 1520 | 1513 | err_reserve_limit: |
| 1521 | 1514 | mutex_destroy(&(*mem)->lock); |
| 1522 | − kfree(*mem); | |
| 1515 | + if (gobj) | |
| 1516 | + drm_gem_object_put(gobj); | |
| 1517 | + else | |
| 1518 | + kfree(*mem); | |
| 1523 | 1519 | err: |
| 1524 | 1520 | if (sg) { |
| 1525 | 1521 | sg_free_table(sg); |
| @@ -1569,6 +1569,18 @@ void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev, · 1568 unmodified lines | ||
| 1569 | 1569 | WREG32(adev->bios_scratch_reg_offset + 3, tmp); |
| 1570 | 1570 | } |
| 1571 | 1571 | |
| 1572 | +void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev, | |
| 1573 | + u32 backlight_level) | |
| 1574 | +{ | |
| 1575 | + u32 tmp = RREG32(adev->bios_scratch_reg_offset + 2); | |
| 1576 | + | |
| 1577 | + tmp &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK; | |
| 1578 | + tmp |= (backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) & | |
| 1579 | + ATOM_S2_CURRENT_BL_LEVEL_MASK; | |
| 1580 | + | |
| 1581 | + WREG32(adev->bios_scratch_reg_offset + 2, tmp); | |
| 1582 | +} | |
| 1583 | + | |
| 1572 | 1584 | bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev) |
| 1573 | 1585 | { |
| 1574 | 1586 | u32 tmp = RREG32(adev->bios_scratch_reg_offset + 7); |
| @@ -185,6 +185,8 @@ bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev); · 184 unmodified lines | ||
| 185 | 185 | void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock); |
| 186 | 186 | void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev, |
| 187 | 187 | bool hung); |
| 188 | +void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev, | |
| 189 | + u32 backlight_level); | |
| 188 | 190 | bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev); |
| 189 | 191 | |
| 190 | 192 | void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le); |
| @@ -827,6 +827,7 @@ static int amdgpu_connector_vga_get_modes(struct drm_connector *connector) · 826 unmodified lines | ||
| 827 | 827 | |
| 828 | 828 | amdgpu_connector_get_edid(connector); |
| 829 | 829 | ret = amdgpu_connector_ddc_get_modes(connector); |
| 830 | + amdgpu_get_native_mode(connector); | |
| 830 | 831 | |
| 831 | 832 | return ret; |
| 832 | 833 | } |
| @@ -3509,6 +3509,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 3508 unmodified lines | ||
| 3509 | 3509 | adev->rmmio_size = pci_resource_len(adev->pdev, 2); |
| 3510 | 3510 | } |
| 3511 | 3511 | |
| 3512 | + for (i = 0; i < AMD_IP_BLOCK_TYPE_NUM; i++) | |
| 3513 | + atomic_set(&adev->pm.pwr_state[i], POWER_STATE_UNKNOWN); | |
| 3514 | + | |
| 3512 | 3515 | adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size); |
| 3513 | 3516 | if (adev->rmmio == NULL) { |
| 3514 | 3517 | return -ENOMEM; |
| @@ -3830,7 +3833,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) · 315 unmodified lines | ||
| 3830 | 3833 | /* disable all interrupts */ |
| 3831 | 3834 | amdgpu_irq_disable_all(adev); |
| 3832 | 3835 | if (adev->mode_info.mode_config_initialized){ |
| 3833 | − if (!amdgpu_device_has_dc_support(adev)) | |
| 3836 | + if (!drm_drv_uses_atomic_modeset(adev_to_drm(adev))) | |
| 3834 | 3837 | drm_helper_force_disable_all(adev_to_drm(adev)); |
| 3835 | 3838 | else |
| 3836 | 3839 | drm_atomic_helper_shutdown(adev_to_drm(adev)); |
| @@ -4286,6 +4289,8 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, · 449 unmodified lines | ||
| 4286 | 4289 | { |
| 4287 | 4290 | int r; |
| 4288 | 4291 | |
| 4292 | + amdgpu_amdkfd_pre_reset(adev); | |
| 4293 | + | |
| 4289 | 4294 | if (from_hypervisor) |
| 4290 | 4295 | r = amdgpu_virt_request_full_gpu(adev, true); |
| 4291 | 4296 | else |
| @@ -5028,7 +5033,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 736 unmodified lines | ||
| 5028 | 5033 | |
| 5029 | 5034 | cancel_delayed_work_sync(&tmp_adev->delayed_init_work); |
| 5030 | 5035 | |
| 5031 | − amdgpu_amdkfd_pre_reset(tmp_adev); | |
| 5036 | + if (!amdgpu_sriov_vf(tmp_adev)) | |
| 5037 | + amdgpu_amdkfd_pre_reset(tmp_adev); | |
| 5032 | 5038 | |
| 5033 | 5039 | /* |
| 5034 | 5040 | * Mark these ASICs to be reseted as untracked first |
| @@ -5086,7 +5092,7 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */ · 51 unmodified lines | ||
| 5086 | 5092 | |
| 5087 | 5093 | tmp_vram_lost_counter = atomic_read(&((adev)->vram_lost_counter)); |
| 5088 | 5094 | /* Actual ASIC resets if needed.*/ |
| 5089 | − /* TODO Implement XGMI hive reset logic for SRIOV */ | |
| 5095 | + /* Host driver will handle XGMI hive reset for SRIOV */ | |
| 5090 | 5096 | if (amdgpu_sriov_vf(adev)) { |
| 5091 | 5097 | r = amdgpu_device_reset_sriov(adev, job ? false : true); |
| 5092 | 5098 | if (r) |
| @@ -5127,7 +5133,7 @@ skip_hw_reset: · 34 unmodified lines | ||
| 5127 | 5133 | drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res); |
| 5128 | 5134 | } |
| 5129 | 5135 | |
| 5130 | − if (!amdgpu_device_has_dc_support(tmp_adev) && !job_signaled) { | |
| 5136 | + if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) { | |
| 5131 | 5137 | drm_helper_resume_force_mode(adev_to_drm(tmp_adev)); |
| 5132 | 5138 | } |
| 5133 | 5139 | |
| @@ -5148,7 +5154,7 @@ skip_sched_resume: · 14 unmodified lines | ||
| 5148 | 5154 | list_for_each_entry(tmp_adev, device_list_handle, reset_list) { |
| 5149 | 5155 | /* unlock kfd: SRIOV would do it separately */ |
| 5150 | 5156 | if (!need_emergency_restart && !amdgpu_sriov_vf(tmp_adev)) |
| 5151 | − amdgpu_amdkfd_post_reset(tmp_adev); | |
| 5157 | + amdgpu_amdkfd_post_reset(tmp_adev); | |
| 5152 | 5158 | |
| 5153 | 5159 | /* kfd_post_reset will do nothing if kfd device is not initialized, |
| 5154 | 5160 | * need to bring up kfd here if it's not be initialized before |
| @@ -157,6 +157,8 @@ static int hw_id_map[MAX_HWIP] = { · 156 unmodified lines | ||
| 157 | 157 | [HDP_HWIP] = HDP_HWID, |
| 158 | 158 | [SDMA0_HWIP] = SDMA0_HWID, |
| 159 | 159 | [SDMA1_HWIP] = SDMA1_HWID, |
| 160 | + [SDMA2_HWIP] = SDMA2_HWID, | |
| 161 | + [SDMA3_HWIP] = SDMA3_HWID, | |
| 160 | 162 | [MMHUB_HWIP] = MMHUB_HWID, |
| 161 | 163 | [ATHUB_HWIP] = ATHUB_HWID, |
| 162 | 164 | [NBIO_HWIP] = NBIF_HWID, |
| @@ -248,8 +250,8 @@ get_from_vram: · 85 unmodified lines | ||
| 248 | 250 | |
| 249 | 251 | offset = offsetof(struct binary_header, binary_checksum) + |
| 250 | 252 | sizeof(bhdr->binary_checksum); |
| 251 | − size = bhdr->binary_size - offset; | |
| 252 | − checksum = bhdr->binary_checksum; | |
| 253 | + size = le16_to_cpu(bhdr->binary_size) - offset; | |
| 254 | + checksum = le16_to_cpu(bhdr->binary_checksum); | |
| 253 | 255 | |
| 254 | 256 | if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, |
| 255 | 257 | size, checksum)) { |
| @@ -270,7 +272,7 @@ get_from_vram: · 14 unmodified lines | ||
| 270 | 272 | } |
| 271 | 273 | |
| 272 | 274 | if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, |
| 273 | − ihdr->size, checksum)) { | |
| 275 | + le16_to_cpu(ihdr->size), checksum)) { | |
| 274 | 276 | DRM_ERROR("invalid ip discovery data table checksum\n"); |
| 275 | 277 | r = -EINVAL; |
| 276 | 278 | goto out; |
| @@ -282,7 +284,7 @@ get_from_vram: · 5 unmodified lines | ||
| 282 | 284 | ghdr = (struct gpu_info_header *)(adev->mman.discovery_bin + offset); |
| 283 | 285 | |
| 284 | 286 | if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, |
| 285 | − ghdr->size, checksum)) { | |
| 287 | + le32_to_cpu(ghdr->size), checksum)) { | |
| 286 | 288 | DRM_ERROR("invalid gc data table checksum\n"); |
| 287 | 289 | r = -EINVAL; |
| 288 | 290 | goto out; |
| @@ -489,10 +491,10 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev) · 200 unmodified lines | ||
| 489 | 491 | le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset)); |
| 490 | 492 | |
| 491 | 493 | for (i = 0; i < 32; i++) { |
| 492 | − if (le32_to_cpu(harvest_info->list[i].hw_id) == 0) | |
| 494 | + if (le16_to_cpu(harvest_info->list[i].hw_id) == 0) | |
| 493 | 495 | break; |
| 494 | 496 | |
| 495 | − switch (le32_to_cpu(harvest_info->list[i].hw_id)) { | |
| 497 | + switch (le16_to_cpu(harvest_info->list[i].hw_id)) { | |
| 496 | 498 | case VCN_HWID: |
| 497 | 499 | vcn_harvest_count++; |
| 498 | 500 | if (harvest_info->list[i].number_instance == 0) |
| @@ -587,6 +589,9 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev) · 88 unmodified lines | ||
| 587 | 589 | amdgpu_device_ip_block_add(adev, &nv_common_ip_block); |
| 588 | 590 | break; |
| 589 | 591 | default: |
| 592 | + dev_err(adev->dev, | |
| 593 | + "Failed to add common ip block(GC_HWIP:0x%x)\n", | |
| 594 | + adev->ip_versions[GC_HWIP][0]); | |
| 590 | 595 | return -EINVAL; |
| 591 | 596 | } |
| 592 | 597 | return 0; |
| @@ -619,6 +624,9 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev) · 26 unmodified lines | ||
| 619 | 624 | amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); |
| 620 | 625 | break; |
| 621 | 626 | default: |
| 627 | + dev_err(adev->dev, | |
| 628 | + "Failed to add gmc ip block(GC_HWIP:0x%x)\n", | |
| 629 | + adev->ip_versions[GC_HWIP][0]); | |
| 622 | 630 | return -EINVAL; |
| 623 | 631 | } |
| 624 | 632 | return 0; |
| @@ -648,6 +656,9 @@ static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev) · 23 unmodified lines | ||
| 648 | 656 | amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); |
| 649 | 657 | break; |
| 650 | 658 | default: |
| 659 | + dev_err(adev->dev, | |
| 660 | + "Failed to add ih ip block(OSSSYS_HWIP:0x%x)\n", | |
| 661 | + adev->ip_versions[OSSSYS_HWIP][0]); | |
| 651 | 662 | return -EINVAL; |
| 652 | 663 | } |
| 653 | 664 | return 0; |
| @@ -688,6 +699,9 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev) · 34 unmodified lines | ||
| 688 | 699 | amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); |
| 689 | 700 | break; |
| 690 | 701 | default: |
| 702 | + dev_err(adev->dev, | |
| 703 | + "Failed to add psp ip block(MP0_HWIP:0x%x)\n", | |
| 704 | + adev->ip_versions[MP0_HWIP][0]); | |
| 691 | 705 | return -EINVAL; |
| 692 | 706 | } |
| 693 | 707 | return 0; |
| @@ -726,6 +740,9 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev) · 32 unmodified lines | ||
| 726 | 740 | amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block); |
| 727 | 741 | break; |
| 728 | 742 | default: |
| 743 | + dev_err(adev->dev, | |
| 744 | + "Failed to add smu ip block(MP1_HWIP:0x%x)\n", | |
| 745 | + adev->ip_versions[MP1_HWIP][0]); | |
| 729 | 746 | return -EINVAL; |
| 730 | 747 | } |
| 731 | 748 | return 0; |
| @@ -753,6 +770,9 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev) · 21 unmodified lines | ||
| 753 | 770 | amdgpu_device_ip_block_add(adev, &dm_ip_block); |
| 754 | 771 | break; |
| 755 | 772 | default: |
| 773 | + dev_err(adev->dev, | |
| 774 | + "Failed to add dm ip block(DCE_HWIP:0x%x)\n", | |
| 775 | + adev->ip_versions[DCE_HWIP][0]); | |
| 756 | 776 | return -EINVAL; |
| 757 | 777 | } |
| 758 | 778 | } else if (adev->ip_versions[DCI_HWIP][0]) { |
| @@ -763,6 +783,9 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev) · 4 unmodified lines | ||
| 763 | 783 | amdgpu_device_ip_block_add(adev, &dm_ip_block); |
| 764 | 784 | break; |
| 765 | 785 | default: |
| 786 | + dev_err(adev->dev, | |
| 787 | + "Failed to add dm ip block(DCI_HWIP:0x%x)\n", | |
| 788 | + adev->ip_versions[DCI_HWIP][0]); | |
| 766 | 789 | return -EINVAL; |
| 767 | 790 | } |
| 768 | 791 | #endif |
| @@ -796,6 +819,9 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev) · 27 unmodified lines | ||
| 796 | 819 | amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); |
| 797 | 820 | break; |
| 798 | 821 | default: |
| 822 | + dev_err(adev->dev, | |
| 823 | + "Failed to add gfx ip block(GC_HWIP:0x%x)\n", | |
| 824 | + adev->ip_versions[GC_HWIP][0]); | |
| 799 | 825 | return -EINVAL; |
| 800 | 826 | } |
| 801 | 827 | return 0; |
| @@ -829,6 +855,9 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev) · 27 unmodified lines | ||
| 829 | 855 | amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); |
| 830 | 856 | break; |
| 831 | 857 | default: |
| 858 | + dev_err(adev->dev, | |
| 859 | + "Failed to add sdma ip block(SDMA0_HWIP:0x%x)\n", | |
| 860 | + adev->ip_versions[SDMA0_HWIP][0]); | |
| 832 | 861 | return -EINVAL; |
| 833 | 862 | } |
| 834 | 863 | return 0; |
| @@ -845,6 +874,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev) · 10 unmodified lines | ||
| 845 | 874 | amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block); |
| 846 | 875 | break; |
| 847 | 876 | default: |
| 877 | + dev_err(adev->dev, | |
| 878 | + "Failed to add uvd v7 ip block(UVD_HWIP:0x%x)\n", | |
| 879 | + adev->ip_versions[UVD_HWIP][0]); | |
| 848 | 880 | return -EINVAL; |
| 849 | 881 | } |
| 850 | 882 | switch (adev->ip_versions[VCE_HWIP][0]) { |
| @@ -855,6 +887,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev) · 4 unmodified lines | ||
| 855 | 887 | amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block); |
| 856 | 888 | break; |
| 857 | 889 | default: |
| 890 | + dev_err(adev->dev, | |
| 891 | + "Failed to add VCE v4 ip block(VCE_HWIP:0x%x)\n", | |
| 892 | + adev->ip_versions[VCE_HWIP][0]); | |
| 858 | 893 | return -EINVAL; |
| 859 | 894 | } |
| 860 | 895 | } else { |
| @@ -885,6 +920,7 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev) · 24 unmodified lines | ||
| 885 | 920 | case IP_VERSION(3, 0, 64): |
| 886 | 921 | case IP_VERSION(3, 1, 1): |
| 887 | 922 | case IP_VERSION(3, 0, 2): |
| 923 | + case IP_VERSION(3, 0, 192): | |
| 888 | 924 | amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); |
| 889 | 925 | if (!amdgpu_sriov_vf(adev)) |
| 890 | 926 | amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); |
| @@ -893,6 +929,9 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev) · 2 unmodified lines | ||
| 893 | 929 | amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); |
| 894 | 930 | break; |
| 895 | 931 | default: |
| 932 | + dev_err(adev->dev, | |
| 933 | + "Failed to add vcn/jpeg ip block(UVD_HWIP:0x%x)\n", | |
| 934 | + adev->ip_versions[UVD_HWIP][0]); | |
| 896 | 935 | return -EINVAL; |
| 897 | 936 | } |
| 898 | 937 | } |
| @@ -223,7 +223,7 @@ int amdgpu_ih_wait_on_checkpoint_process(struct amdgpu_device *adev, · 222 unmodified lines | ||
| 223 | 223 | */ |
| 224 | 224 | int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) |
| 225 | 225 | { |
| 226 | − unsigned int count = AMDGPU_IH_MAX_NUM_IVS; | |
| 226 | + unsigned int count; | |
| 227 | 227 | u32 wptr; |
| 228 | 228 | |
| 229 | 229 | if (!ih->enabled || adev->shutdown) |
| @@ -232,6 +232,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) · 2 unmodified lines | ||
| 232 | 232 | wptr = amdgpu_ih_get_wptr(adev, ih); |
| 233 | 233 | |
| 234 | 234 | restart_ih: |
| 235 | + count = AMDGPU_IH_MAX_NUM_IVS; | |
| 235 | 236 | DRM_DEBUG("%s: rptr %d, wptr %d\n", __func__, ih->rptr, wptr); |
| 236 | 237 | |
| 237 | 238 | /* Order reading of wptr vs. reading of IH ring data */ |
| @@ -135,6 +135,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) · 134 unmodified lines | ||
| 135 | 135 | break; |
| 136 | 136 | case IP_VERSION(3, 0, 0): |
| 137 | 137 | case IP_VERSION(3, 0, 64): |
| 138 | + case IP_VERSION(3, 0, 192): | |
| 138 | 139 | if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) |
| 139 | 140 | fw_name = FIRMWARE_SIENNA_CICHLID; |
| 140 | 141 | else |
| @@ -504,8 +504,8 @@ static int amdgpu_vkms_sw_fini(void *handle) · 503 unmodified lines | ||
| 504 | 504 | int i = 0; |
| 505 | 505 | |
| 506 | 506 | for (i = 0; i < adev->mode_info.num_crtc; i++) |
| 507 | − if (adev->mode_info.crtcs[i]) | |
| 508 | − hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer); | |
| 507 | + if (adev->amdgpu_vkms_output[i].vblank_hrtimer.function) | |
| 508 | + hrtimer_cancel(&adev->amdgpu_vkms_output[i].vblank_hrtimer); | |
| 509 | 509 | |
| 510 | 510 | kfree(adev->mode_info.bios_hardcoded_edid); |
| 511 | 511 | kfree(adev->amdgpu_vkms_output); |
| @@ -386,6 +386,7 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev) · 385 unmodified lines | ||
| 386 | 386 | "%s", "xgmi_hive_info"); |
| 387 | 387 | if (ret) { |
| 388 | 388 | dev_err(adev->dev, "XGMI: failed initializing kobject for xgmi hive\n"); |
| 389 | + kobject_put(&hive->kobj); | |
| 389 | 390 | kfree(hive); |
| 390 | 391 | hive = NULL; |
| 391 | 392 | goto pro_end; |
| @@ -7707,8 +7707,19 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev) · 7706 unmodified lines | ||
| 7707 | 7707 | switch (adev->ip_versions[GC_HWIP][0]) { |
| 7708 | 7708 | case IP_VERSION(10, 3, 1): |
| 7709 | 7709 | case IP_VERSION(10, 3, 3): |
| 7710 | − clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh) | | |
| 7711 | − ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh) << 32ULL); | |
| 7710 | + preempt_disable(); | |
| 7711 | + clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh); | |
| 7712 | + clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh); | |
| 7713 | + hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh); | |
| 7714 | + /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over | |
| 7715 | + * roughly every 42 seconds. | |
| 7716 | + */ | |
| 7717 | + if (hi_check != clock_hi) { | |
| 7718 | + clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh); | |
| 7719 | + clock_hi = hi_check; | |
| 7720 | + } | |
| 7721 | + preempt_enable(); | |
| 7722 | + clock = clock_lo | (clock_hi << 32ULL); | |
| 7712 | 7723 | break; |
| 7713 | 7724 | default: |
| 7714 | 7725 | preempt_disable(); |
| @@ -140,6 +140,11 @@ MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin"); · 139 unmodified lines | ||
| 140 | 140 | #define mmTCP_CHAN_STEER_5_ARCT 0x0b0c |
| 141 | 141 | #define mmTCP_CHAN_STEER_5_ARCT_BASE_IDX 0 |
| 142 | 142 | |
| 143 | +#define mmGOLDEN_TSC_COUNT_UPPER_Renoir 0x0025 | |
| 144 | +#define mmGOLDEN_TSC_COUNT_UPPER_Renoir_BASE_IDX 1 | |
| 145 | +#define mmGOLDEN_TSC_COUNT_LOWER_Renoir 0x0026 | |
| 146 | +#define mmGOLDEN_TSC_COUNT_LOWER_Renoir_BASE_IDX 1 | |
| 147 | + | |
| 143 | 148 | enum ta_ras_gfx_subblock { |
| 144 | 149 | /*CPC*/ |
| 145 | 150 | TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0, |
| @@ -4055,9 +4060,10 @@ static int gfx_v9_0_hw_fini(void *handle) · 3909 unmodified lines | ||
| 4055 | 4060 | |
| 4056 | 4061 | gfx_v9_0_cp_enable(adev, false); |
| 4057 | 4062 | |
| 4058 | − /* Skip suspend with A+A reset */ | |
| 4059 | − if (adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) { | |
| 4060 | − dev_dbg(adev->dev, "Device in reset. Skipping RLC halt\n"); | |
| 4063 | + /* Skip stopping RLC with A+A reset or when RLC controls GFX clock */ | |
| 4064 | + if ((adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) || | |
| 4065 | + (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2))) { | |
| 4066 | + dev_dbg(adev->dev, "Skipping RLC halt\n"); | |
| 4061 | 4067 | return 0; |
| 4062 | 4068 | } |
| 4063 | 4069 | |
| @@ -4238,19 +4244,38 @@ failed_kiq_read: · 174 unmodified lines | ||
| 4238 | 4244 | |
| 4239 | 4245 | static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev) |
| 4240 | 4246 | { |
| 4241 | − uint64_t clock; | |
| 4247 | + uint64_t clock, clock_lo, clock_hi, hi_check; | |
| 4242 | 4248 | |
| 4243 | − amdgpu_gfx_off_ctrl(adev, false); | |
| 4244 | − mutex_lock(&adev->gfx.gpu_clock_mutex); | |
| 4245 | − if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 0, 1) && amdgpu_sriov_runtime(adev)) { | |
| 4246 | − clock = gfx_v9_0_kiq_read_clock(adev); | |
| 4247 | − } else { | |
| 4248 | − WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); | |
| 4249 | − clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) | | |
| 4250 | − ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | |
| 4249 | + switch (adev->ip_versions[GC_HWIP][0]) { | |
| 4250 | + case IP_VERSION(9, 3, 0): | |
| 4251 | + preempt_disable(); | |
| 4252 | + clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir); | |
| 4253 | + clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir); | |
| 4254 | + hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir); | |
| 4255 | + /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over | |
| 4256 | + * roughly every 42 seconds. | |
| 4257 | + */ | |
| 4258 | + if (hi_check != clock_hi) { | |
| 4259 | + clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir); | |
| 4260 | + clock_hi = hi_check; | |
| 4261 | + } | |
| 4262 | + preempt_enable(); | |
| 4263 | + clock = clock_lo | (clock_hi << 32ULL); | |
| 4264 | + break; | |
| 4265 | + default: | |
| 4266 | + amdgpu_gfx_off_ctrl(adev, false); | |
| 4267 | + mutex_lock(&adev->gfx.gpu_clock_mutex); | |
| 4268 | + if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 0, 1) && amdgpu_sriov_runtime(adev)) { | |
| 4269 | + clock = gfx_v9_0_kiq_read_clock(adev); | |
| 4270 | + } else { | |
| 4271 | + WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); | |
| 4272 | + clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) | | |
| 4273 | + ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | |
| 4274 | + } | |
| 4275 | + mutex_unlock(&adev->gfx.gpu_clock_mutex); | |
| 4276 | + amdgpu_gfx_off_ctrl(adev, true); | |
| 4277 | + break; | |
| 4251 | 4278 | } |
| 4252 | − mutex_unlock(&adev->gfx.gpu_clock_mutex); | |
| 4253 | − amdgpu_gfx_off_ctrl(adev, true); | |
| 4254 | 4279 | return clock; |
| 4255 | 4280 | } |
| 4256 | 4281 | |
| @@ -160,6 +160,7 @@ static int navi10_ih_toggle_ring_interrupts(struct amdgpu_device *adev, · 159 unmodified lines | ||
| 160 | 160 | |
| 161 | 161 | tmp = RREG32(ih_regs->ih_rb_cntl); |
| 162 | 162 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0)); |
| 163 | + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1); | |
| 163 | 164 | /* enable_intr field is only valid in ring0 */ |
| 164 | 165 | if (ih == &adev->irq.ih) |
| 165 | 166 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0)); |
| @@ -275,10 +276,8 @@ static int navi10_ih_enable_ring(struct amdgpu_device *adev, · 109 unmodified lines | ||
| 275 | 276 | tmp = navi10_ih_rb_cntl(ih, tmp); |
| 276 | 277 | if (ih == &adev->irq.ih) |
| 277 | 278 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled); |
| 278 | − if (ih == &adev->irq.ih1) { | |
| 279 | − tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0); | |
| 279 | + if (ih == &adev->irq.ih1) | |
| 280 | 280 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1); |
| 281 | − } | |
| 282 | 281 | |
| 283 | 282 | if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) { |
| 284 | 283 | if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) { |
| @@ -319,7 +318,6 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev) · 34 unmodified lines | ||
| 319 | 318 | { |
| 320 | 319 | struct amdgpu_ih_ring *ih[] = {&adev->irq.ih, &adev->irq.ih1, &adev->irq.ih2}; |
| 321 | 320 | u32 ih_chicken; |
| 322 | − u32 tmp; | |
| 323 | 321 | int ret; |
| 324 | 322 | int i; |
| 325 | 323 | |
| @@ -363,15 +361,6 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev) · 37 unmodified lines | ||
| 363 | 361 | adev->nbio.funcs->ih_doorbell_range(adev, ih[0]->use_doorbell, |
| 364 | 362 | ih[0]->doorbell_index); |
| 365 | 363 | |
| 366 | − tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL); | |
| 367 | − tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL, | |
| 368 | − CLIENT18_IS_STORM_CLIENT, 1); | |
| 369 | − WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp); | |
| 370 | − | |
| 371 | − tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL); | |
| 372 | − tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1); | |
| 373 | − WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp); | |
| 374 | − | |
| 375 | 364 | pci_set_master(adev->pdev); |
| 376 | 365 | |
| 377 | 366 | /* enable interrupts */ |
| @@ -420,12 +409,19 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev, · 42 unmodified lines | ||
| 420 | 409 | u32 wptr, tmp; |
| 421 | 410 | struct amdgpu_ih_regs *ih_regs; |
| 422 | 411 | |
| 423 | − wptr = le32_to_cpu(*ih->wptr_cpu); | |
| 424 | − ih_regs = &ih->ih_regs; | |
| 412 | + if (ih == &adev->irq.ih) { | |
| 413 | + /* Only ring0 supports writeback. On other rings fall back | |
| 414 | + * to register-based code with overflow checking below. | |
| 415 | + */ | |
| 416 | + wptr = le32_to_cpu(*ih->wptr_cpu); | |
| 425 | 417 | |
| 426 | − if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) | |
| 427 | − goto out; | |
| 418 | + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) | |
| 419 | + goto out; | |
| 420 | + } | |
| 428 | 421 | |
| 422 | + ih_regs = &ih->ih_regs; | |
| 423 | + | |
| 424 | + /* Double check that the overflow wasn't already cleared. */ | |
| 429 | 425 | wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr); |
| 430 | 426 | if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) |
| 431 | 427 | goto out; |
| @@ -513,15 +509,11 @@ static int navi10_ih_self_irq(struct amdgpu_device *adev, · 81 unmodified lines | ||
| 513 | 509 | struct amdgpu_irq_src *source, |
| 514 | 510 | struct amdgpu_iv_entry *entry) |
| 515 | 511 | { |
| 516 | − uint32_t wptr = cpu_to_le32(entry->src_data[0]); | |
| 517 | − | |
| 518 | 512 | switch (entry->ring_id) { |
| 519 | 513 | case 1: |
| 520 | − *adev->irq.ih1.wptr_cpu = wptr; | |
| 521 | 514 | schedule_work(&adev->irq.ih1_work); |
| 522 | 515 | break; |
| 523 | 516 | case 2: |
| 524 | − *adev->irq.ih2.wptr_cpu = wptr; | |
| 525 | 517 | schedule_work(&adev->irq.ih2_work); |
| 526 | 518 | break; |
| 527 | 519 | default: break; |
| @@ -359,6 +359,10 @@ static void nbio_v2_3_init_registers(struct amdgpu_device *adev) · 358 unmodified lines | ||
| 359 | 359 | |
| 360 | 360 | if (def != data) |
| 361 | 361 | WREG32_PCIE(smnPCIE_CONFIG_CNTL, data); |
| 362 | + | |
| 363 | + if (amdgpu_sriov_vf(adev)) | |
| 364 | + adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, | |
| 365 | + mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; | |
| 362 | 366 | } |
| 363 | 367 | |
| 364 | 368 | #define NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT 0x00000000 // off by default, no gains over L1 |
| @@ -276,6 +276,10 @@ static void nbio_v6_1_init_registers(struct amdgpu_device *adev) · 275 unmodified lines | ||
| 276 | 276 | |
| 277 | 277 | if (def != data) |
| 278 | 278 | WREG32_PCIE(smnPCIE_CI_CNTL, data); |
| 279 | + | |
| 280 | + if (amdgpu_sriov_vf(adev)) | |
| 281 | + adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, | |
| 282 | + mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; | |
| 279 | 283 | } |
| 280 | 284 | |
| 281 | 285 | static void nbio_v6_1_program_ltr(struct amdgpu_device *adev) |
| @@ -273,7 +273,9 @@ const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = { · 272 unmodified lines | ||
| 273 | 273 | |
| 274 | 274 | static void nbio_v7_0_init_registers(struct amdgpu_device *adev) |
| 275 | 275 | { |
| 276 | − | |
| 276 | + if (amdgpu_sriov_vf(adev)) | |
| 277 | + adev->rmmio_remap.reg_offset = | |
| 278 | + SOC15_REG_OFFSET(NBIO, 0, mmHDP_MEM_COHERENCY_FLUSH_CNTL) << 2; | |
| 277 | 279 | } |
| 278 | 280 | |
| 279 | 281 | const struct amdgpu_nbio_funcs nbio_v7_0_funcs = { |
| @@ -371,6 +371,10 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev) · 370 unmodified lines | ||
| 371 | 371 | if (def != data) |
| 372 | 372 | WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL), data); |
| 373 | 373 | } |
| 374 | + | |
| 375 | + if (amdgpu_sriov_vf(adev)) | |
| 376 | + adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, | |
| 377 | + regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; | |
| 374 | 378 | } |
| 375 | 379 | |
| 376 | 380 | const struct amdgpu_nbio_funcs nbio_v7_2_funcs = { |
| @@ -362,7 +362,9 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald = { · 361 unmodified lines | ||
| 362 | 362 | |
| 363 | 363 | static void nbio_v7_4_init_registers(struct amdgpu_device *adev) |
| 364 | 364 | { |
| 365 | − | |
| 365 | + if (amdgpu_sriov_vf(adev)) | |
| 366 | + adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, | |
| 367 | + mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; | |
| 366 | 368 | } |
| 367 | 369 | |
| 368 | 370 | static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device *adev) |
| @@ -692,6 +694,9 @@ static void nbio_v7_4_program_aspm(struct amdgpu_device *adev) · 323 unmodified lines | ||
| 692 | 694 | { |
| 693 | 695 | uint32_t def, data; |
| 694 | 696 | |
| 697 | + if (adev->ip_versions[NBIO_HWIP][0] == IP_VERSION(7, 4, 4)) | |
| 698 | + return; | |
| 699 | + | |
| 695 | 700 | def = data = RREG32_PCIE(smnPCIE_LC_CNTL); |
| 696 | 701 | data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK; |
| 697 | 702 | data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK; |
| @@ -183,6 +183,7 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, · 182 unmodified lines | ||
| 183 | 183 | switch (adev->ip_versions[UVD_HWIP][0]) { |
| 184 | 184 | case IP_VERSION(3, 0, 0): |
| 185 | 185 | case IP_VERSION(3, 0, 64): |
| 186 | + case IP_VERSION(3, 0, 192): | |
| 186 | 187 | if (amdgpu_sriov_vf(adev)) { |
| 187 | 188 | if (encode) |
| 188 | 189 | *codecs = &sriov_sc_video_codecs_encode; |
| @@ -731,8 +732,10 @@ static int nv_common_early_init(void *handle) · 542 unmodified lines | ||
| 731 | 732 | #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) |
| 732 | 733 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 733 | 734 | |
| 734 | − adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; | |
| 735 | − adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; | |
| 735 | + if (!amdgpu_sriov_vf(adev)) { | |
| 736 | + adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; | |
| 737 | + adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; | |
| 738 | + } | |
| 736 | 739 | adev->smc_rreg = NULL; |
| 737 | 740 | adev->smc_wreg = NULL; |
| 738 | 741 | adev->pcie_rreg = &nv_pcie_rreg; |
| @@ -1032,7 +1035,7 @@ static int nv_common_hw_init(void *handle) · 293 unmodified lines | ||
| 1032 | 1035 | * for the purpose of expose those registers |
| 1033 | 1036 | * to process space |
| 1034 | 1037 | */ |
| 1035 | − if (adev->nbio.funcs->remap_hdp_registers) | |
| 1038 | + if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) | |
| 1036 | 1039 | adev->nbio.funcs->remap_hdp_registers(adev); |
| 1037 | 1040 | /* enable the doorbell aperture */ |
| 1038 | 1041 | nv_enable_doorbell_aperture(adev, true); |
| @@ -971,8 +971,10 @@ static int soc15_common_early_init(void *handle) · 970 unmodified lines | ||
| 971 | 971 | #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) |
| 972 | 972 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 973 | 973 | |
| 974 | − adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; | |
| 975 | − adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; | |
| 974 | + if (!amdgpu_sriov_vf(adev)) { | |
| 975 | + adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; | |
| 976 | + adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; | |
| 977 | + } | |
| 976 | 978 | adev->smc_rreg = NULL; |
| 977 | 979 | adev->smc_wreg = NULL; |
| 978 | 980 | adev->pcie_rreg = &soc15_pcie_rreg; |
| @@ -1285,7 +1287,7 @@ static int soc15_common_hw_init(void *handle) · 306 unmodified lines | ||
| 1285 | 1287 | * for the purpose of expose those registers |
| 1286 | 1288 | * to process space |
| 1287 | 1289 | */ |
| 1288 | − if (adev->nbio.funcs->remap_hdp_registers) | |
| 1290 | + if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) | |
| 1289 | 1291 | adev->nbio.funcs->remap_hdp_registers(adev); |
| 1290 | 1292 | |
| 1291 | 1293 | /* enable the doorbell aperture */ |
| @@ -1226,6 +1226,11 @@ static int stop_cpsch(struct device_queue_manager *dqm) · 1225 unmodified lines | ||
| 1226 | 1226 | bool hanging; |
| 1227 | 1227 | |
| 1228 | 1228 | dqm_lock(dqm); |
| 1229 | + if (!dqm->sched_running) { | |
| 1230 | + dqm_unlock(dqm); | |
| 1231 | + return 0; | |
| 1232 | + } | |
| 1233 | + | |
| 1229 | 1234 | if (!dqm->is_hws_hang) |
| 1230 | 1235 | unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); |
| 1231 | 1236 | hanging = dqm->is_hws_hang || dqm->is_resetting; |
| @@ -766,7 +766,7 @@ struct svm_range_list { · 765 unmodified lines | ||
| 766 | 766 | struct list_head deferred_range_list; |
| 767 | 767 | spinlock_t deferred_list_lock; |
| 768 | 768 | atomic_t evicted_ranges; |
| 769 | − bool drain_pagefaults; | |
| 769 | + atomic_t drain_pagefaults; | |
| 770 | 770 | struct delayed_work restore_work; |
| 771 | 771 | DECLARE_BITMAP(bitmap_supported, MAX_GPU_INSTANCE); |
| 772 | 772 | struct task_struct *faulting_task; |
| @@ -1574,7 +1574,6 @@ retry_flush_work: · 1573 unmodified lines | ||
| 1574 | 1574 | static void svm_range_restore_work(struct work_struct *work) |
| 1575 | 1575 | { |
| 1576 | 1576 | struct delayed_work *dwork = to_delayed_work(work); |
| 1577 | − struct amdkfd_process_info *process_info; | |
| 1578 | 1577 | struct svm_range_list *svms; |
| 1579 | 1578 | struct svm_range *prange; |
| 1580 | 1579 | struct kfd_process *p; |
| @@ -1594,12 +1593,10 @@ static void svm_range_restore_work(struct work_struct *work) · 13 unmodified lines | ||
| 1594 | 1593 | * the lifetime of this thread, kfd_process and mm will be valid. |
| 1595 | 1594 | */ |
| 1596 | 1595 | p = container_of(svms, struct kfd_process, svms); |
| 1597 | − process_info = p->kgd_process_info; | |
| 1598 | 1596 | mm = p->mm; |
| 1599 | 1597 | if (!mm) |
| 1600 | 1598 | return; |
| 1601 | 1599 | |
| 1602 | − mutex_lock(&process_info->lock); | |
| 1603 | 1600 | svm_range_list_lock_and_flush_work(svms, mm); |
| 1604 | 1601 | mutex_lock(&svms->lock); |
| 1605 | 1602 | |
| @@ -1652,7 +1649,6 @@ static void svm_range_restore_work(struct work_struct *work) · 46 unmodified lines | ||
| 1652 | 1649 | out_reschedule: |
| 1653 | 1650 | mutex_unlock(&svms->lock); |
| 1654 | 1651 | mmap_write_unlock(mm); |
| 1655 | − mutex_unlock(&process_info->lock); | |
| 1656 | 1652 | |
| 1657 | 1653 | /* If validation failed, reschedule another attempt */ |
| 1658 | 1654 | if (evicted_ranges) { |
| @@ -1968,10 +1964,16 @@ static void svm_range_drain_retry_fault(struct svm_range_list *svms) · 309 unmodified lines | ||
| 1968 | 1964 | struct kfd_process_device *pdd; |
| 1969 | 1965 | struct amdgpu_device *adev; |
| 1970 | 1966 | struct kfd_process *p; |
| 1967 | + int drain; | |
| 1971 | 1968 | uint32_t i; |
| 1972 | 1969 | |
| 1973 | 1970 | p = container_of(svms, struct kfd_process, svms); |
| 1974 | 1971 | |
| 1972 | +restart: | |
| 1973 | + drain = atomic_read(&svms->drain_pagefaults); | |
| 1974 | + if (!drain) | |
| 1975 | + return; | |
| 1976 | + | |
| 1975 | 1977 | for_each_set_bit(i, svms->bitmap_supported, p->n_pdds) { |
| 1976 | 1978 | pdd = p->pdds[i]; |
| 1977 | 1979 | if (!pdd) |
| @@ -1983,6 +1985,8 @@ static void svm_range_drain_retry_fault(struct svm_range_list *svms) · 5 unmodified lines | ||
| 1983 | 1985 | amdgpu_ih_wait_on_checkpoint_process(adev, &adev->irq.ih1); |
| 1984 | 1986 | pr_debug("drain retry fault gpu %d svms 0x%p done\n", i, svms); |
| 1985 | 1987 | } |
| 1988 | + if (atomic_cmpxchg(&svms->drain_pagefaults, drain, 0) != drain) | |
| 1989 | + goto restart; | |
| 1986 | 1990 | } |
| 1987 | 1991 | |
| 1988 | 1992 | static void svm_range_deferred_list_work(struct work_struct *work) |
| @@ -1990,43 +1994,41 @@ static void svm_range_deferred_list_work(struct work_struct *work) · 1 unmodified line | ||
| 1990 | 1994 | struct svm_range_list *svms; |
| 1991 | 1995 | struct svm_range *prange; |
| 1992 | 1996 | struct mm_struct *mm; |
| 1997 | + struct kfd_process *p; | |
| 1993 | 1998 | |
| 1994 | 1999 | svms = container_of(work, struct svm_range_list, deferred_list_work); |
| 1995 | 2000 | pr_debug("enter svms 0x%p\n", svms); |
| 1996 | 2001 | |
| 2002 | + p = container_of(svms, struct kfd_process, svms); | |
| 2003 | + /* Avoid mm is gone when inserting mmu notifier */ | |
| 2004 | + mm = get_task_mm(p->lead_thread); | |
| 2005 | + if (!mm) { | |
| 2006 | + pr_debug("svms 0x%p process mm gone\n", svms); | |
| 2007 | + return; | |
| 2008 | + } | |
| 2009 | +retry: | |
| 2010 | + mmap_write_lock(mm); | |
| 2011 | + | |
| 2012 | + /* Checking for the need to drain retry faults must be inside | |
| 2013 | + * mmap write lock to serialize with munmap notifiers. | |
| 2014 | + */ | |
| 2015 | + if (unlikely(atomic_read(&svms->drain_pagefaults))) { | |
| 2016 | + mmap_write_unlock(mm); | |
| 2017 | + svm_range_drain_retry_fault(svms); | |
| 2018 | + goto retry; | |
| 2019 | + } | |
| 2020 | + | |
| 1997 | 2021 | spin_lock(&svms->deferred_list_lock); |
| 1998 | 2022 | while (!list_empty(&svms->deferred_range_list)) { |
| 1999 | 2023 | prange = list_first_entry(&svms->deferred_range_list, |
| 2000 | 2024 | struct svm_range, deferred_list); |
| 2025 | + list_del_init(&prange->deferred_list); | |
| 2001 | 2026 | spin_unlock(&svms->deferred_list_lock); |
| 2027 | + | |
| 2002 | 2028 | pr_debug("prange 0x%p [0x%lx 0x%lx] op %d\n", prange, |
| 2003 | 2029 | prange->start, prange->last, prange->work_item.op); |
| 2004 | 2030 | |
| 2005 | − mm = prange->work_item.mm; | |
| 2006 | −retry: | |
| 2007 | − mmap_write_lock(mm); | |
| 2008 | 2031 | mutex_lock(&svms->lock); |
| 2009 | − | |
| 2010 | − /* Checking for the need to drain retry faults must be in | |
| 2011 | − * mmap write lock to serialize with munmap notifiers. | |
| 2012 | − * | |
| 2013 | − * Remove from deferred_list must be inside mmap write lock, | |
| 2014 | − * otherwise, svm_range_list_lock_and_flush_work may hold mmap | |
| 2015 | − * write lock, and continue because deferred_list is empty, then | |
| 2016 | − * deferred_list handle is blocked by mmap write lock. | |
| 2017 | − */ | |
| 2018 | − spin_lock(&svms->deferred_list_lock); | |
| 2019 | − if (unlikely(svms->drain_pagefaults)) { | |
| 2020 | − svms->drain_pagefaults = false; | |
| 2021 | − spin_unlock(&svms->deferred_list_lock); | |
| 2022 | − mutex_unlock(&svms->lock); | |
| 2023 | − mmap_write_unlock(mm); | |
| 2024 | − svm_range_drain_retry_fault(svms); | |
| 2025 | − goto retry; | |
| 2026 | − } | |
| 2027 | − list_del_init(&prange->deferred_list); | |
| 2028 | − spin_unlock(&svms->deferred_list_lock); | |
| 2029 | − | |
| 2030 | 2032 | mutex_lock(&prange->migrate_mutex); |
| 2031 | 2033 | while (!list_empty(&prange->child_list)) { |
| 2032 | 2034 | struct svm_range *pchild; |
| @@ -2042,12 +2044,13 @@ retry: · 9 unmodified lines | ||
| 2042 | 2044 | |
| 2043 | 2045 | svm_range_handle_list_op(svms, prange); |
| 2044 | 2046 | mutex_unlock(&svms->lock); |
| 2045 | − mmap_write_unlock(mm); | |
| 2046 | 2047 | |
| 2047 | 2048 | spin_lock(&svms->deferred_list_lock); |
| 2048 | 2049 | } |
| 2049 | 2050 | spin_unlock(&svms->deferred_list_lock); |
| 2050 | 2051 | |
| 2052 | + mmap_write_unlock(mm); | |
| 2053 | + mmput(mm); | |
| 2051 | 2054 | pr_debug("exit svms 0x%p\n", svms); |
| 2052 | 2055 | } |
| 2053 | 2056 | |
| @@ -2056,12 +2059,6 @@ svm_range_add_list_work(struct svm_range_list *svms, struct svm_range *prange, · 2 unmodified lines | ||
| 2056 | 2059 | struct mm_struct *mm, enum svm_work_list_ops op) |
| 2057 | 2060 | { |
| 2058 | 2061 | spin_lock(&svms->deferred_list_lock); |
| 2059 | − /* Make sure pending page faults are drained in the deferred worker | |
| 2060 | − * before the range is freed to avoid straggler interrupts on | |
| 2061 | − * unmapped memory causing "phantom faults". | |
| 2062 | − */ | |
| 2063 | − if (op == SVM_OP_UNMAP_RANGE) | |
| 2064 | − svms->drain_pagefaults = true; | |
| 2065 | 2062 | /* if prange is on the deferred list */ |
| 2066 | 2063 | if (!list_empty(&prange->deferred_list)) { |
| 2067 | 2064 | pr_debug("update exist prange 0x%p work op %d\n", prange, op); |
| @@ -2140,6 +2137,12 @@ svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange, · 72 unmodified lines | ||
| 2140 | 2137 | pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] [0x%lx 0x%lx]\n", svms, |
| 2141 | 2138 | prange, prange->start, prange->last, start, last); |
| 2142 | 2139 | |
| 2140 | + /* Make sure pending page faults are drained in the deferred worker | |
| 2141 | + * before the range is freed to avoid straggler interrupts on | |
| 2142 | + * unmapped memory causing "phantom faults". | |
| 2143 | + */ | |
| 2144 | + atomic_inc(&svms->drain_pagefaults); | |
| 2145 | + | |
| 2143 | 2146 | unmap_parent = start <= prange->start && last >= prange->last; |
| 2144 | 2147 | |
| 2145 | 2148 | list_for_each_entry(pchild, &prange->child_list, child_list) { |
| @@ -2559,20 +2562,13 @@ svm_range_count_fault(struct amdgpu_device *adev, struct kfd_process *p, · 413 unmodified lines | ||
| 2559 | 2562 | } |
| 2560 | 2563 | |
| 2561 | 2564 | static bool |
| 2562 | −svm_fault_allowed(struct mm_struct *mm, uint64_t addr, bool write_fault) | |
| 2565 | +svm_fault_allowed(struct vm_area_struct *vma, bool write_fault) | |
| 2563 | 2566 | { |
| 2564 | 2567 | unsigned long requested = VM_READ; |
| 2565 | − struct vm_area_struct *vma; | |
| 2566 | 2568 | |
| 2567 | 2569 | if (write_fault) |
| 2568 | 2570 | requested |= VM_WRITE; |
| 2569 | 2571 | |
| 2570 | − vma = find_vma(mm, addr << PAGE_SHIFT); | |
| 2571 | − if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) { | |
| 2572 | − pr_debug("address 0x%llx VMA is removed\n", addr); | |
| 2573 | − return true; | |
| 2574 | − } | |
| 2575 | − | |
| 2576 | 2572 | pr_debug("requested 0x%lx, vma permission flags 0x%lx\n", requested, |
| 2577 | 2573 | vma->vm_flags); |
| 2578 | 2574 | return (vma->vm_flags & requested) == requested; |
| @@ -2590,6 +2586,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, · 11 unmodified lines | ||
| 2590 | 2586 | int32_t best_loc; |
| 2591 | 2587 | int32_t gpuidx = MAX_GPU_INSTANCE; |
| 2592 | 2588 | bool write_locked = false; |
| 2589 | + struct vm_area_struct *vma; | |
| 2593 | 2590 | int r = 0; |
| 2594 | 2591 | |
| 2595 | 2592 | if (!KFD_IS_SVM_API_SUPPORTED(adev->kfd.dev)) { |
| @@ -2600,7 +2597,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, · 4 unmodified lines | ||
| 2600 | 2597 | p = kfd_lookup_process_by_pasid(pasid); |
| 2601 | 2598 | if (!p) { |
| 2602 | 2599 | pr_debug("kfd process not founded pasid 0x%x\n", pasid); |
| 2603 | − return -ESRCH; | |
| 2600 | + return 0; | |
| 2604 | 2601 | } |
| 2605 | 2602 | if (!p->xnack_enabled) { |
| 2606 | 2603 | pr_debug("XNACK not enabled for pasid 0x%x\n", pasid); |
| @@ -2611,10 +2608,19 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, · 4 unmodified lines | ||
| 2611 | 2608 | |
| 2612 | 2609 | pr_debug("restoring svms 0x%p fault address 0x%llx\n", svms, addr); |
| 2613 | 2610 | |
| 2611 | + if (atomic_read(&svms->drain_pagefaults)) { | |
| 2612 | + pr_debug("draining retry fault, drop fault 0x%llx\n", addr); | |
| 2613 | + r = 0; | |
| 2614 | + goto out; | |
| 2615 | + } | |
| 2616 | + | |
| 2617 | + /* p->lead_thread is available as kfd_process_wq_release flush the work | |
| 2618 | + * before releasing task ref. | |
| 2619 | + */ | |
| 2614 | 2620 | mm = get_task_mm(p->lead_thread); |
| 2615 | 2621 | if (!mm) { |
| 2616 | 2622 | pr_debug("svms 0x%p failed to get mm\n", svms); |
| 2617 | − r = -ESRCH; | |
| 2623 | + r = 0; | |
| 2618 | 2624 | goto out; |
| 2619 | 2625 | } |
| 2620 | 2626 | |
| @@ -2652,6 +2658,7 @@ retry_write_locked: · 31 unmodified lines | ||
| 2652 | 2658 | |
| 2653 | 2659 | if (svm_range_skip_recover(prange)) { |
| 2654 | 2660 | amdgpu_gmc_filter_faults_remove(adev, addr, pasid); |
| 2661 | + r = 0; | |
| 2655 | 2662 | goto out_unlock_range; |
| 2656 | 2663 | } |
| 2657 | 2664 | |
| @@ -2660,10 +2667,21 @@ retry_write_locked: · 2 unmodified lines | ||
| 2660 | 2667 | if (timestamp < AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING) { |
| 2661 | 2668 | pr_debug("svms 0x%p [0x%lx %lx] already restored\n", |
| 2662 | 2669 | svms, prange->start, prange->last); |
| 2670 | + r = 0; | |
| 2663 | 2671 | goto out_unlock_range; |
| 2664 | 2672 | } |
| 2665 | 2673 | |
| 2666 | − if (!svm_fault_allowed(mm, addr, write_fault)) { | |
| 2674 | + /* __do_munmap removed VMA, return success as we are handling stale | |
| 2675 | + * retry fault. | |
| 2676 | + */ | |
| 2677 | + vma = find_vma(mm, addr << PAGE_SHIFT); | |
| 2678 | + if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) { | |
| 2679 | + pr_debug("address 0x%llx VMA is removed\n", addr); | |
| 2680 | + r = 0; | |
| 2681 | + goto out_unlock_range; | |
| 2682 | + } | |
| 2683 | + | |
| 2684 | + if (!svm_fault_allowed(vma, write_fault)) { | |
| 2667 | 2685 | pr_debug("fault addr 0x%llx no %s permission\n", addr, |
| 2668 | 2686 | write_fault ? "write" : "read"); |
| 2669 | 2687 | r = -EPERM; |
| @@ -2741,6 +2759,14 @@ void svm_range_list_fini(struct kfd_process *p) · 71 unmodified lines | ||
| 2741 | 2759 | /* Ensure list work is finished before process is destroyed */ |
| 2742 | 2760 | flush_work(&p->svms.deferred_list_work); |
| 2743 | 2761 | |
| 2762 | + /* | |
| 2763 | + * Ensure no retry fault comes in afterwards, as page fault handler will | |
| 2764 | + * not find kfd process and take mm lock to recover fault. | |
| 2765 | + */ | |
| 2766 | + atomic_inc(&p->svms.drain_pagefaults); | |
| 2767 | + svm_range_drain_retry_fault(&p->svms); | |
| 2768 | + | |
| 2769 | + | |
| 2744 | 2770 | list_for_each_entry_safe(prange, next, &p->svms.list, list) { |
| 2745 | 2771 | svm_range_unlink(prange); |
| 2746 | 2772 | svm_range_remove_notifier(prange); |
| @@ -2761,6 +2787,7 @@ int svm_range_list_init(struct kfd_process *p) · 14 unmodified lines | ||
| 2761 | 2787 | mutex_init(&svms->lock); |
| 2762 | 2788 | INIT_LIST_HEAD(&svms->list); |
| 2763 | 2789 | atomic_set(&svms->evicted_ranges, 0); |
| 2790 | + atomic_set(&svms->drain_pagefaults, 0); | |
| 2764 | 2791 | INIT_DELAYED_WORK(&svms->restore_work, svm_range_restore_work); |
| 2765 | 2792 | INIT_WORK(&svms->deferred_list_work, svm_range_deferred_list_work); |
| 2766 | 2793 | INIT_LIST_HEAD(&svms->deferred_range_list); |
| @@ -3150,7 +3177,6 @@ static int · 383 unmodified lines | ||
| 3150 | 3177 | svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, |
| 3151 | 3178 | uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs) |
| 3152 | 3179 | { |
| 3153 | − struct amdkfd_process_info *process_info = p->kgd_process_info; | |
| 3154 | 3180 | struct mm_struct *mm = current->mm; |
| 3155 | 3181 | struct list_head update_list; |
| 3156 | 3182 | struct list_head insert_list; |
| @@ -3169,8 +3195,6 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, · 12 unmodified lines | ||
| 3169 | 3195 | |
| 3170 | 3196 | svms = &p->svms; |
| 3171 | 3197 | |
| 3172 | − mutex_lock(&process_info->lock); | |
| 3173 | − | |
| 3174 | 3198 | svm_range_list_lock_and_flush_work(svms, mm); |
| 3175 | 3199 | |
| 3176 | 3200 | r = svm_range_is_valid(p, start, size); |
| @@ -3246,8 +3270,6 @@ out_unlock_range: · 69 unmodified lines | ||
| 3246 | 3270 | mutex_unlock(&svms->lock); |
| 3247 | 3271 | mmap_read_unlock(mm); |
| 3248 | 3272 | out: |
| 3249 | − mutex_unlock(&process_info->lock); | |
| 3250 | − | |
| 3251 | 3273 | pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid, |
| 3252 | 3274 | &p->svms, start, start + size - 1, r); |
| 3253 | 3275 | |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | ||
| 51 | 51 | #include <drm/drm_hdcp.h> |
| 52 | 52 | #endif |
| 53 | 53 | #include "amdgpu_pm.h" |
| 54 | +#include "amdgpu_atombios.h" | |
| 54 | 55 | |
| 55 | 56 | #include "amd_shared.h" |
| 56 | 57 | #include "amdgpu_dm_irq.h" |
| @@ -2561,6 +2562,23 @@ static int dm_resume(void *handle) · 2504 unmodified lines | ||
| 2561 | 2562 | if (amdgpu_in_reset(adev)) { |
| 2562 | 2563 | dc_state = dm->cached_dc_state; |
| 2563 | 2564 | |
| 2565 | + /* | |
| 2566 | + * The dc->current_state is backed up into dm->cached_dc_state | |
| 2567 | + * before we commit 0 streams. | |
| 2568 | + * | |
| 2569 | + * DC will clear link encoder assignments on the real state | |
| 2570 | + * but the changes won't propagate over to the copy we made | |
| 2571 | + * before the 0 streams commit. | |
| 2572 | + * | |
| 2573 | + * DC expects that link encoder assignments are *not* valid | |
| 2574 | + * when committing a state, so as a workaround it needs to be | |
| 2575 | + * cleared here. | |
| 2576 | + */ | |
| 2577 | + link_enc_cfg_init(dm->dc, dc_state); | |
| 2578 | + | |
| 2579 | + if (dc_enable_dmub_notifications(adev->dm.dc)) | |
| 2580 | + amdgpu_dm_outbox_init(adev); | |
| 2581 | + | |
| 2564 | 2582 | r = dm_dmub_hw_init(adev); |
| 2565 | 2583 | if (r) |
| 2566 | 2584 | DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); |
| @@ -2572,8 +2590,8 @@ static int dm_resume(void *handle) · 5 unmodified lines | ||
| 2572 | 2590 | |
| 2573 | 2591 | for (i = 0; i < dc_state->stream_count; i++) { |
| 2574 | 2592 | dc_state->streams[i]->mode_changed = true; |
| 2575 | − for (j = 0; j < dc_state->stream_status->plane_count; j++) { | |
| 2576 | − dc_state->stream_status->plane_states[j]->update_flags.raw | |
| 2593 | + for (j = 0; j < dc_state->stream_status[i].plane_count; j++) { | |
| 2594 | + dc_state->stream_status[i].plane_states[j]->update_flags.raw | |
| 2577 | 2595 | = 0xffffffff; |
| 2578 | 2596 | } |
| 2579 | 2597 | } |
| @@ -2608,6 +2626,10 @@ static int dm_resume(void *handle) · 28 unmodified lines | ||
| 2608 | 2626 | /* TODO: Remove dc_state->dccg, use dc->dccg directly. */ |
| 2609 | 2627 | dc_resource_state_construct(dm->dc, dm_state->context); |
| 2610 | 2628 | |
| 2629 | + /* Re-enable outbox interrupts for DPIA. */ | |
| 2630 | + if (dc_enable_dmub_notifications(adev->dm.dc)) | |
| 2631 | + amdgpu_dm_outbox_init(adev); | |
| 2632 | + | |
| 2611 | 2633 | /* Before powering on DC we need to re-initialize DMUB. */ |
| 2612 | 2634 | r = dm_dmub_hw_init(adev); |
| 2613 | 2635 | if (r) |
| @@ -3909,6 +3931,9 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm, · 1295 unmodified lines | ||
| 3909 | 3931 | caps = dm->backlight_caps[bl_idx]; |
| 3910 | 3932 | |
| 3911 | 3933 | dm->brightness[bl_idx] = user_brightness; |
| 3934 | + /* update scratch register */ | |
| 3935 | + if (bl_idx == 0) | |
| 3936 | + amdgpu_atombios_scratch_regs_set_backlight_level(dm->adev, dm->brightness[bl_idx]); | |
| 3912 | 3937 | brightness = convert_brightness_from_user(&caps, dm->brightness[bl_idx]); |
| 3913 | 3938 | link = (struct dc_link *)dm->backlight_link[bl_idx]; |
| 3914 | 3939 | |
| @@ -4242,7 +4267,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 327 unmodified lines | ||
| 4242 | 4267 | } else if (dc_link_detect(link, DETECT_REASON_BOOT)) { |
| 4243 | 4268 | amdgpu_dm_update_connector_after_detect(aconnector); |
| 4244 | 4269 | register_backlight_device(dm, link); |
| 4245 | − | |
| 4270 | + if (dm->num_of_edps) | |
| 4271 | + update_connector_ext_caps(aconnector); | |
| 4246 | 4272 | if (psr_feature_enabled) |
| 4247 | 4273 | amdgpu_dm_set_psr_caps(link); |
| 4248 | 4274 | } |
| @@ -314,6 +314,14 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) · 313 unmodified lines | ||
| 314 | 314 | ret = -EINVAL; |
| 315 | 315 | goto cleanup; |
| 316 | 316 | } |
| 317 | + | |
| 318 | + if ((aconn->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) && | |
| 319 | + (aconn->base.connector_type != DRM_MODE_CONNECTOR_eDP)) { | |
| 320 | + DRM_DEBUG_DRIVER("No DP connector available for CRC source\n"); | |
| 321 | + ret = -EINVAL; | |
| 322 | + goto cleanup; | |
| 323 | + } | |
| 324 | + | |
| 317 | 325 | } |
| 318 | 326 | |
| 319 | 327 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| @@ -36,6 +36,8 @@ · 35 unmodified lines | ||
| 36 | 36 | #include "dm_helpers.h" |
| 37 | 37 | |
| 38 | 38 | #include "dc_link_ddc.h" |
| 39 | +#include "ddc_service_types.h" | |
| 40 | +#include "dpcd_defs.h" | |
| 39 | 41 | |
| 40 | 42 | #include "i2caux_interface.h" |
| 41 | 43 | #include "dmub_cmd.h" |
| @@ -157,6 +159,16 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { · 115 unmodified lines | ||
| 157 | 159 | }; |
| 158 | 160 | |
| 159 | 161 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 162 | +static bool needs_dsc_aux_workaround(struct dc_link *link) | |
| 163 | +{ | |
| 164 | + if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && | |
| 165 | + (link->dpcd_caps.dpcd_rev.raw == DPCD_REV_14 || link->dpcd_caps.dpcd_rev.raw == DPCD_REV_12) && | |
| 166 | + link->dpcd_caps.sink_count.bits.SINK_COUNT >= 2) | |
| 167 | + return true; | |
| 168 | + | |
| 169 | + return false; | |
| 170 | +} | |
| 171 | + | |
| 160 | 172 | static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector) |
| 161 | 173 | { |
| 162 | 174 | struct dc_sink *dc_sink = aconnector->dc_sink; |
| @@ -166,7 +178,7 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto · 3 unmodified lines | ||
| 166 | 178 | u8 *dsc_branch_dec_caps = NULL; |
| 167 | 179 | |
| 168 | 180 | aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port); |
| 169 | −#if defined(CONFIG_HP_HOOK_WORKAROUND) | |
| 181 | + | |
| 170 | 182 | /* |
| 171 | 183 | * drm_dp_mst_dsc_aux_for_port() will return NULL for certain configs |
| 172 | 184 | * because it only check the dsc/fec caps of the "port variable" and not the dock |
| @@ -176,10 +188,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto · 3 unmodified lines | ||
| 176 | 188 | * Workaround: explicitly check the use case above and use the mst dock's aux as dsc_aux |
| 177 | 189 | * |
| 178 | 190 | */ |
| 179 | − | |
| 180 | − if (!aconnector->dsc_aux && !port->parent->port_parent) | |
| 191 | + if (!aconnector->dsc_aux && !port->parent->port_parent && | |
| 192 | + needs_dsc_aux_workaround(aconnector->dc_link)) | |
| 181 | 193 | aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux; |
| 182 | −#endif | |
| 194 | + | |
| 183 | 195 | if (!aconnector->dsc_aux) |
| 184 | 196 | return false; |
| 185 | 197 | |
| @@ -758,6 +758,18 @@ static bool detect_dp(struct dc_link *link, · 757 unmodified lines | ||
| 758 | 758 | dal_ddc_service_set_transaction_type(link->ddc, |
| 759 | 759 | sink_caps->transaction_type); |
| 760 | 760 | |
| 761 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 762 | + /* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock | |
| 763 | + * reports DSC support. | |
| 764 | + */ | |
| 765 | + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && | |
| 766 | + link->type == dc_connection_mst_branch && | |
| 767 | + link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && | |
| 768 | + link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT && | |
| 769 | + !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around) | |
| 770 | + link->wa_flags.dpia_mst_dsc_always_on = true; | |
| 771 | +#endif | |
| 772 | + | |
| 761 | 773 | #if defined(CONFIG_DRM_AMD_DC_HDCP) |
| 762 | 774 | /* In case of fallback to SST when topology discovery below fails |
| 763 | 775 | * HDCP caps will be querried again later by the upper layer (caller |
| @@ -1203,6 +1215,10 @@ static bool dc_link_detect_helper(struct dc_link *link, · 439 unmodified lines | ||
| 1203 | 1215 | LINK_INFO("link=%d, mst branch is now Disconnected\n", |
| 1204 | 1216 | link->link_index); |
| 1205 | 1217 | |
| 1218 | + /* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */ | |
| 1219 | + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) | |
| 1220 | + link->wa_flags.dpia_mst_dsc_always_on = false; | |
| 1221 | + | |
| 1206 | 1222 | dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); |
| 1207 | 1223 | |
| 1208 | 1224 | link->mst_stream_alloc_table.stream_count = 0; |
| @@ -2138,7 +2138,7 @@ static enum link_training_result dp_perform_8b_10b_link_training( · 2137 unmodified lines | ||
| 2138 | 2138 | } |
| 2139 | 2139 | |
| 2140 | 2140 | for (lane = 0; lane < (uint8_t)lt_settings->link_settings.lane_count; lane++) |
| 2141 | − lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET = VOLTAGE_SWING_LEVEL0; | |
| 2141 | + lt_settings->dpcd_lane_settings[lane].raw = 0; | |
| 2142 | 2142 | } |
| 2143 | 2143 | |
| 2144 | 2144 | if (status == LINK_TRAINING_SUCCESS) { |
| @@ -1664,6 +1664,10 @@ bool dc_is_stream_unchanged( · 1663 unmodified lines | ||
| 1664 | 1664 | if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param) |
| 1665 | 1665 | return false; |
| 1666 | 1666 | |
| 1667 | + // Only Have Audio left to check whether it is same or not. This is a corner case for Tiled sinks | |
| 1668 | + if (old_stream->audio_info.mode_count != stream->audio_info.mode_count) | |
| 1669 | + return false; | |
| 1670 | + | |
| 1667 | 1671 | return true; |
| 1668 | 1672 | } |
| 1669 | 1673 | |
| @@ -2252,16 +2256,6 @@ enum dc_status dc_validate_global_state( · 582 unmodified lines | ||
| 2252 | 2256 | |
| 2253 | 2257 | if (!new_ctx) |
| 2254 | 2258 | return DC_ERROR_UNEXPECTED; |
| 2255 | −#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 2256 | − | |
| 2257 | − /* | |
| 2258 | − * Update link encoder to stream assignment. | |
| 2259 | − * TODO: Split out reason allocation from validation. | |
| 2260 | − */ | |
| 2261 | − if (dc->res_pool->funcs->link_encs_assign && fast_validate == false) | |
| 2262 | − dc->res_pool->funcs->link_encs_assign( | |
| 2263 | − dc, new_ctx, new_ctx->streams, new_ctx->stream_count); | |
| 2264 | −#endif | |
| 2265 | 2259 | |
| 2266 | 2260 | if (dc->res_pool->funcs->validate_global) { |
| 2267 | 2261 | result = dc->res_pool->funcs->validate_global(dc, new_ctx); |
| @@ -2313,6 +2307,16 @@ enum dc_status dc_validate_global_state( · 45 unmodified lines | ||
| 2313 | 2307 | if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate)) |
| 2314 | 2308 | result = DC_FAIL_BANDWIDTH_VALIDATE; |
| 2315 | 2309 | |
| 2310 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 2311 | + /* | |
| 2312 | + * Only update link encoder to stream assignment after bandwidth validation passed. | |
| 2313 | + * TODO: Split out assignment and validation. | |
| 2314 | + */ | |
| 2315 | + if (result == DC_OK && dc->res_pool->funcs->link_encs_assign && fast_validate == false) | |
| 2316 | + dc->res_pool->funcs->link_encs_assign( | |
| 2317 | + dc, new_ctx, new_ctx->streams, new_ctx->stream_count); | |
| 2318 | +#endif | |
| 2319 | + | |
| 2316 | 2320 | return result; |
| 2317 | 2321 | } |
| 2318 | 2322 | |
| @@ -508,7 +508,8 @@ union dpia_debug_options { · 507 unmodified lines | ||
| 508 | 508 | uint32_t disable_dpia:1; |
| 509 | 509 | uint32_t force_non_lttpr:1; |
| 510 | 510 | uint32_t extend_aux_rd_interval:1; |
| 511 | − uint32_t reserved:29; | |
| 511 | + uint32_t disable_mst_dsc_work_around:1; | |
| 512 | + uint32_t reserved:28; | |
| 512 | 513 | } bits; |
| 513 | 514 | uint32_t raw; |
| 514 | 515 | }; |
| @@ -191,6 +191,8 @@ struct dc_link { · 190 unmodified lines | ||
| 191 | 191 | bool dp_skip_DID2; |
| 192 | 192 | bool dp_skip_reset_segment; |
| 193 | 193 | bool dp_mot_reset_segment; |
| 194 | + /* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */ | |
| 195 | + bool dpia_mst_dsc_always_on; | |
| 194 | 196 | } wa_flags; |
| 195 | 197 | struct link_mst_stream_allocation_table mst_stream_alloc_table; |
| 196 | 198 | |
| @@ -224,6 +226,8 @@ static inline void get_edp_links(const struct dc *dc, · 27 unmodified lines | ||
| 224 | 226 | *edp_num = 0; |
| 225 | 227 | for (i = 0; i < dc->link_count; i++) { |
| 226 | 228 | // report any eDP links, even unconnected DDI's |
| 229 | + if (!dc->links[i]) | |
| 230 | + continue; | |
| 227 | 231 | if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) { |
| 228 | 232 | edp_links[*edp_num] = dc->links[i]; |
| 229 | 233 | if (++(*edp_num) == MAX_NUM_EDP) |
| @@ -1637,7 +1637,7 @@ void dcn10_reset_hw_ctx_wrap( · 1636 unmodified lines | ||
| 1637 | 1637 | |
| 1638 | 1638 | dcn10_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); |
| 1639 | 1639 | if (hws->funcs.enable_stream_gating) |
| 1640 | − hws->funcs.enable_stream_gating(dc, pipe_ctx); | |
| 1640 | + hws->funcs.enable_stream_gating(dc, pipe_ctx_old); | |
| 1641 | 1641 | if (old_clk) |
| 1642 | 1642 | old_clk->funcs->cs_power_down(old_clk); |
| 1643 | 1643 | } |
| @@ -2270,7 +2270,7 @@ void dcn20_reset_hw_ctx_wrap( · 2269 unmodified lines | ||
| 2270 | 2270 | |
| 2271 | 2271 | dcn20_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); |
| 2272 | 2272 | if (hws->funcs.enable_stream_gating) |
| 2273 | − hws->funcs.enable_stream_gating(dc, pipe_ctx); | |
| 2273 | + hws->funcs.enable_stream_gating(dc, pipe_ctx_old); | |
| 2274 | 2274 | if (old_clk) |
| 2275 | 2275 | old_clk->funcs->cs_power_down(old_clk); |
| 2276 | 2276 | } |
| @@ -602,7 +602,7 @@ void dcn31_reset_hw_ctx_wrap( · 601 unmodified lines | ||
| 602 | 602 | |
| 603 | 603 | dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); |
| 604 | 604 | if (hws->funcs.enable_stream_gating) |
| 605 | − hws->funcs.enable_stream_gating(dc, pipe_ctx); | |
| 605 | + hws->funcs.enable_stream_gating(dc, pipe_ctx_old); | |
| 606 | 606 | if (old_clk) |
| 607 | 607 | old_clk->funcs->cs_power_down(old_clk); |
| 608 | 608 | } |
| @@ -98,7 +98,8 @@ enum amd_ip_block_type { · 97 unmodified lines | ||
| 98 | 98 | AMD_IP_BLOCK_TYPE_ACP, |
| 99 | 99 | AMD_IP_BLOCK_TYPE_VCN, |
| 100 | 100 | AMD_IP_BLOCK_TYPE_MES, |
| 101 | − AMD_IP_BLOCK_TYPE_JPEG | |
| 101 | + AMD_IP_BLOCK_TYPE_JPEG, | |
| 102 | + AMD_IP_BLOCK_TYPE_NUM, | |
| 102 | 103 | }; |
| 103 | 104 | |
| 104 | 105 | enum amd_clockgating_state { |
| @@ -927,6 +927,13 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block · 926 unmodified lines | ||
| 927 | 927 | { |
| 928 | 928 | int ret = 0; |
| 929 | 929 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; |
| 930 | + enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON; | |
| 931 | + | |
| 932 | + if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) { | |
| 933 | + dev_dbg(adev->dev, "IP block%d already in the target %s state!", | |
| 934 | + block_type, gate ? "gate" : "ungate"); | |
| 935 | + return 0; | |
| 936 | + } | |
| 930 | 937 | |
| 931 | 938 | switch (block_type) { |
| 932 | 939 | case AMD_IP_BLOCK_TYPE_UVD: |
| @@ -979,6 +986,9 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block · 46 unmodified lines | ||
| 979 | 986 | break; |
| 980 | 987 | } |
| 981 | 988 | |
| 989 | + if (!ret) | |
| 990 | + atomic_set(&adev->pm.pwr_state[block_type], pwr_state); | |
| 991 | + | |
| 982 | 992 | return ret; |
| 983 | 993 | } |
| 984 | 994 | |
| @@ -417,6 +417,12 @@ struct amdgpu_dpm { · 416 unmodified lines | ||
| 417 | 417 | enum amd_dpm_forced_level forced_level; |
| 418 | 418 | }; |
| 419 | 419 | |
| 420 | +enum ip_power_state { | |
| 421 | + POWER_STATE_UNKNOWN, | |
| 422 | + POWER_STATE_ON, | |
| 423 | + POWER_STATE_OFF, | |
| 424 | +}; | |
| 425 | + | |
| 420 | 426 | struct amdgpu_pm { |
| 421 | 427 | struct mutex mutex; |
| 422 | 428 | u32 current_sclk; |
| @@ -452,6 +458,8 @@ struct amdgpu_pm { · 29 unmodified lines | ||
| 452 | 458 | struct i2c_adapter smu_i2c; |
| 453 | 459 | struct mutex smu_i2c_mutex; |
| 454 | 460 | struct list_head pm_attr_list; |
| 461 | + | |
| 462 | + atomic_t pwr_state[AMD_IP_BLOCK_TYPE_NUM]; | |
| 455 | 463 | }; |
| 456 | 464 | |
| 457 | 465 | #define R600_SSTU_DFLT 0 |
| @@ -1024,8 +1024,6 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 1023 unmodified lines | ||
| 1024 | 1024 | uint32_t min_freq, max_freq = 0; |
| 1025 | 1025 | uint32_t ret = 0; |
| 1026 | 1026 | |
| 1027 | − phm_get_sysfs_buf(&buf, &size); | |
| 1028 | − | |
| 1029 | 1027 | switch (type) { |
| 1030 | 1028 | case PP_SCLK: |
| 1031 | 1029 | smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now); |
| @@ -1038,13 +1036,13 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 6 unmodified lines | ||
| 1038 | 1036 | else |
| 1039 | 1037 | i = 1; |
| 1040 | 1038 | |
| 1041 | − size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", | |
| 1039 | + size += sprintf(buf + size, "0: %uMhz %s\n", | |
| 1042 | 1040 | data->gfx_min_freq_limit/100, |
| 1043 | 1041 | i == 0 ? "*" : ""); |
| 1044 | − size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", | |
| 1042 | + size += sprintf(buf + size, "1: %uMhz %s\n", | |
| 1045 | 1043 | i == 1 ? now : SMU10_UMD_PSTATE_GFXCLK, |
| 1046 | 1044 | i == 1 ? "*" : ""); |
| 1047 | − size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", | |
| 1045 | + size += sprintf(buf + size, "2: %uMhz %s\n", | |
| 1048 | 1046 | data->gfx_max_freq_limit/100, |
| 1049 | 1047 | i == 2 ? "*" : ""); |
| 1050 | 1048 | break; |
| @@ -1052,7 +1050,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 1 unmodified line | ||
| 1052 | 1050 | smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now); |
| 1053 | 1051 | |
| 1054 | 1052 | for (i = 0; i < mclk_table->count; i++) |
| 1055 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 1053 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 1056 | 1054 | i, |
| 1057 | 1055 | mclk_table->entries[i].clk / 100, |
| 1058 | 1056 | ((mclk_table->entries[i].clk / 100) |
| @@ -1067,10 +1065,10 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 8 unmodified lines | ||
| 1067 | 1065 | if (ret) |
| 1068 | 1066 | return ret; |
| 1069 | 1067 | |
| 1070 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); | |
| 1071 | − size += sysfs_emit_at(buf, size, "0: %10uMhz\n", | |
| 1068 | + size += sprintf(buf + size, "%s:\n", "OD_SCLK"); | |
| 1069 | + size += sprintf(buf + size, "0: %10uMhz\n", | |
| 1072 | 1070 | (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq); |
| 1073 | − size += sysfs_emit_at(buf, size, "1: %10uMhz\n", | |
| 1071 | + size += sprintf(buf + size, "1: %10uMhz\n", | |
| 1074 | 1072 | (data->gfx_actual_soft_max_freq > 0) ? data->gfx_actual_soft_max_freq : max_freq); |
| 1075 | 1073 | } |
| 1076 | 1074 | break; |
| @@ -1083,8 +1081,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, · 6 unmodified lines | ||
| 1083 | 1081 | if (ret) |
| 1084 | 1082 | return ret; |
| 1085 | 1083 | |
| 1086 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); | |
| 1087 | − size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", | |
| 1084 | + size += sprintf(buf + size, "%s:\n", "OD_RANGE"); | |
| 1085 | + size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", | |
| 1088 | 1086 | min_freq, max_freq); |
| 1089 | 1087 | } |
| 1090 | 1088 | break; |
| @@ -4914,8 +4914,6 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, · 4913 unmodified lines | ||
| 4914 | 4914 | int size = 0; |
| 4915 | 4915 | uint32_t i, now, clock, pcie_speed; |
| 4916 | 4916 | |
| 4917 | − phm_get_sysfs_buf(&buf, &size); | |
| 4918 | − | |
| 4919 | 4917 | switch (type) { |
| 4920 | 4918 | case PP_SCLK: |
| 4921 | 4919 | smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency, &clock); |
| @@ -4928,7 +4926,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, · 6 unmodified lines | ||
| 4928 | 4926 | now = i; |
| 4929 | 4927 | |
| 4930 | 4928 | for (i = 0; i < sclk_table->count; i++) |
| 4931 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 4929 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 4932 | 4930 | i, sclk_table->dpm_levels[i].value / 100, |
| 4933 | 4931 | (i == now) ? "*" : ""); |
| 4934 | 4932 | break; |
| @@ -4943,7 +4941,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, · 8 unmodified lines | ||
| 4943 | 4941 | now = i; |
| 4944 | 4942 | |
| 4945 | 4943 | for (i = 0; i < mclk_table->count; i++) |
| 4946 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 4944 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 4947 | 4945 | i, mclk_table->dpm_levels[i].value / 100, |
| 4948 | 4946 | (i == now) ? "*" : ""); |
| 4949 | 4947 | break; |
| @@ -4957,7 +4955,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, · 7 unmodified lines | ||
| 4957 | 4955 | now = i; |
| 4958 | 4956 | |
| 4959 | 4957 | for (i = 0; i < pcie_table->count; i++) |
| 4960 | − size += sysfs_emit_at(buf, size, "%d: %s %s\n", i, | |
| 4958 | + size += sprintf(buf + size, "%d: %s %s\n", i, | |
| 4961 | 4959 | (pcie_table->dpm_levels[i].value == 0) ? "2.5GT/s, x8" : |
| 4962 | 4960 | (pcie_table->dpm_levels[i].value == 1) ? "5.0GT/s, x16" : |
| 4963 | 4961 | (pcie_table->dpm_levels[i].value == 2) ? "8.0GT/s, x16" : "", |
| @@ -4965,32 +4963,32 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, · 1 unmodified line | ||
| 4965 | 4963 | break; |
| 4966 | 4964 | case OD_SCLK: |
| 4967 | 4965 | if (hwmgr->od_enabled) { |
| 4968 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); | |
| 4966 | + size += sprintf(buf + size, "%s:\n", "OD_SCLK"); | |
| 4969 | 4967 | for (i = 0; i < odn_sclk_table->num_of_pl; i++) |
| 4970 | − size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n", | |
| 4968 | + size += sprintf(buf + size, "%d: %10uMHz %10umV\n", | |
| 4971 | 4969 | i, odn_sclk_table->entries[i].clock/100, |
| 4972 | 4970 | odn_sclk_table->entries[i].vddc); |
| 4973 | 4971 | } |
| 4974 | 4972 | break; |
| 4975 | 4973 | case OD_MCLK: |
| 4976 | 4974 | if (hwmgr->od_enabled) { |
| 4977 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); | |
| 4975 | + size += sprintf(buf + size, "%s:\n", "OD_MCLK"); | |
| 4978 | 4976 | for (i = 0; i < odn_mclk_table->num_of_pl; i++) |
| 4979 | − size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n", | |
| 4977 | + size += sprintf(buf + size, "%d: %10uMHz %10umV\n", | |
| 4980 | 4978 | i, odn_mclk_table->entries[i].clock/100, |
| 4981 | 4979 | odn_mclk_table->entries[i].vddc); |
| 4982 | 4980 | } |
| 4983 | 4981 | break; |
| 4984 | 4982 | case OD_RANGE: |
| 4985 | 4983 | if (hwmgr->od_enabled) { |
| 4986 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); | |
| 4987 | − size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", | |
| 4984 | + size += sprintf(buf + size, "%s:\n", "OD_RANGE"); | |
| 4985 | + size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", | |
| 4988 | 4986 | data->golden_dpm_table.sclk_table.dpm_levels[0].value/100, |
| 4989 | 4987 | hwmgr->platform_descriptor.overdriveLimit.engineClock/100); |
| 4990 | − size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n", | |
| 4988 | + size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n", | |
| 4991 | 4989 | data->golden_dpm_table.mclk_table.dpm_levels[0].value/100, |
| 4992 | 4990 | hwmgr->platform_descriptor.overdriveLimit.memoryClock/100); |
| 4993 | − size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n", | |
| 4991 | + size += sprintf(buf + size, "VDDC: %7umV %11umV\n", | |
| 4994 | 4992 | data->odn_dpm_table.min_vddc, |
| 4995 | 4993 | data->odn_dpm_table.max_vddc); |
| 4996 | 4994 | } |
| @@ -1550,8 +1550,6 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr, · 1549 unmodified lines | ||
| 1550 | 1550 | uint32_t i, now; |
| 1551 | 1551 | int size = 0; |
| 1552 | 1552 | |
| 1553 | − phm_get_sysfs_buf(&buf, &size); | |
| 1554 | − | |
| 1555 | 1553 | switch (type) { |
| 1556 | 1554 | case PP_SCLK: |
| 1557 | 1555 | now = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, |
| @@ -1561,7 +1559,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr, · 3 unmodified lines | ||
| 1561 | 1559 | CURR_SCLK_INDEX); |
| 1562 | 1560 | |
| 1563 | 1561 | for (i = 0; i < sclk_table->count; i++) |
| 1564 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 1562 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 1565 | 1563 | i, sclk_table->entries[i].clk / 100, |
| 1566 | 1564 | (i == now) ? "*" : ""); |
| 1567 | 1565 | break; |
| @@ -1573,7 +1571,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr, · 5 unmodified lines | ||
| 1573 | 1571 | CURR_MCLK_INDEX); |
| 1574 | 1572 | |
| 1575 | 1573 | for (i = SMU8_NUM_NBPMEMORYCLOCK; i > 0; i--) |
| 1576 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 1574 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 1577 | 1575 | SMU8_NUM_NBPMEMORYCLOCK-i, data->sys_info.nbp_memory_clock[i-1] / 100, |
| 1578 | 1576 | (SMU8_NUM_NBPMEMORYCLOCK-i == now) ? "*" : ""); |
| 1579 | 1577 | break; |
| @@ -4639,8 +4639,6 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 4638 unmodified lines | ||
| 4639 | 4639 | |
| 4640 | 4640 | int i, now, size = 0, count = 0; |
| 4641 | 4641 | |
| 4642 | − phm_get_sysfs_buf(&buf, &size); | |
| 4643 | − | |
| 4644 | 4642 | switch (type) { |
| 4645 | 4643 | case PP_SCLK: |
| 4646 | 4644 | if (data->registry_data.sclk_dpm_key_disabled) |
| @@ -4654,7 +4652,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 7 unmodified lines | ||
| 4654 | 4652 | else |
| 4655 | 4653 | count = sclk_table->count; |
| 4656 | 4654 | for (i = 0; i < count; i++) |
| 4657 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 4655 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 4658 | 4656 | i, sclk_table->dpm_levels[i].value / 100, |
| 4659 | 4657 | (i == now) ? "*" : ""); |
| 4660 | 4658 | break; |
| @@ -4665,7 +4663,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 4 unmodified lines | ||
| 4665 | 4663 | smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now); |
| 4666 | 4664 | |
| 4667 | 4665 | for (i = 0; i < mclk_table->count; i++) |
| 4668 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 4666 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 4669 | 4667 | i, mclk_table->dpm_levels[i].value / 100, |
| 4670 | 4668 | (i == now) ? "*" : ""); |
| 4671 | 4669 | break; |
| @@ -4676,7 +4674,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 4 unmodified lines | ||
| 4676 | 4674 | smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now); |
| 4677 | 4675 | |
| 4678 | 4676 | for (i = 0; i < soc_table->count; i++) |
| 4679 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 4677 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 4680 | 4678 | i, soc_table->dpm_levels[i].value / 100, |
| 4681 | 4679 | (i == now) ? "*" : ""); |
| 4682 | 4680 | break; |
| @@ -4688,7 +4686,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 5 unmodified lines | ||
| 4688 | 4686 | PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now); |
| 4689 | 4687 | |
| 4690 | 4688 | for (i = 0; i < dcef_table->count; i++) |
| 4691 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 4689 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 4692 | 4690 | i, dcef_table->dpm_levels[i].value / 100, |
| 4693 | 4691 | (dcef_table->dpm_levels[i].value / 100 == now) ? |
| 4694 | 4692 | "*" : ""); |
| @@ -4702,7 +4700,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 7 unmodified lines | ||
| 4702 | 4700 | gen_speed = pptable->PcieGenSpeed[i]; |
| 4703 | 4701 | lane_width = pptable->PcieLaneCount[i]; |
| 4704 | 4702 | |
| 4705 | − size += sysfs_emit_at(buf, size, "%d: %s %s %s\n", i, | |
| 4703 | + size += sprintf(buf + size, "%d: %s %s %s\n", i, | |
| 4706 | 4704 | (gen_speed == 0) ? "2.5GT/s," : |
| 4707 | 4705 | (gen_speed == 1) ? "5.0GT/s," : |
| 4708 | 4706 | (gen_speed == 2) ? "8.0GT/s," : |
| @@ -4721,34 +4719,34 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, · 12 unmodified lines | ||
| 4721 | 4719 | |
| 4722 | 4720 | case OD_SCLK: |
| 4723 | 4721 | if (hwmgr->od_enabled) { |
| 4724 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); | |
| 4722 | + size += sprintf(buf + size, "%s:\n", "OD_SCLK"); | |
| 4725 | 4723 | podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk; |
| 4726 | 4724 | for (i = 0; i < podn_vdd_dep->count; i++) |
| 4727 | − size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n", | |
| 4725 | + size += sprintf(buf + size, "%d: %10uMhz %10umV\n", | |
| 4728 | 4726 | i, podn_vdd_dep->entries[i].clk / 100, |
| 4729 | 4727 | podn_vdd_dep->entries[i].vddc); |
| 4730 | 4728 | } |
| 4731 | 4729 | break; |
| 4732 | 4730 | case OD_MCLK: |
| 4733 | 4731 | if (hwmgr->od_enabled) { |
| 4734 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); | |
| 4732 | + size += sprintf(buf + size, "%s:\n", "OD_MCLK"); | |
| 4735 | 4733 | podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk; |
| 4736 | 4734 | for (i = 0; i < podn_vdd_dep->count; i++) |
| 4737 | − size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n", | |
| 4735 | + size += sprintf(buf + size, "%d: %10uMhz %10umV\n", | |
| 4738 | 4736 | i, podn_vdd_dep->entries[i].clk/100, |
| 4739 | 4737 | podn_vdd_dep->entries[i].vddc); |
| 4740 | 4738 | } |
| 4741 | 4739 | break; |
| 4742 | 4740 | case OD_RANGE: |
| 4743 | 4741 | if (hwmgr->od_enabled) { |
| 4744 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); | |
| 4745 | − size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", | |
| 4742 | + size += sprintf(buf + size, "%s:\n", "OD_RANGE"); | |
| 4743 | + size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", | |
| 4746 | 4744 | data->golden_dpm_table.gfx_table.dpm_levels[0].value/100, |
| 4747 | 4745 | hwmgr->platform_descriptor.overdriveLimit.engineClock/100); |
| 4748 | − size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n", | |
| 4746 | + size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n", | |
| 4749 | 4747 | data->golden_dpm_table.mem_table.dpm_levels[0].value/100, |
| 4750 | 4748 | hwmgr->platform_descriptor.overdriveLimit.memoryClock/100); |
| 4751 | − size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n", | |
| 4749 | + size += sprintf(buf + size, "VDDC: %7umV %11umV\n", | |
| 4752 | 4750 | data->odn_dpm_table.min_vddc, |
| 4753 | 4751 | data->odn_dpm_table.max_vddc); |
| 4754 | 4752 | } |
| @@ -2246,8 +2246,6 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, · 2245 unmodified lines | ||
| 2246 | 2246 | int i, now, size = 0; |
| 2247 | 2247 | struct pp_clock_levels_with_latency clocks; |
| 2248 | 2248 | |
| 2249 | − phm_get_sysfs_buf(&buf, &size); | |
| 2250 | − | |
| 2251 | 2249 | switch (type) { |
| 2252 | 2250 | case PP_SCLK: |
| 2253 | 2251 | PP_ASSERT_WITH_CODE( |
| @@ -2260,7 +2258,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, · 6 unmodified lines | ||
| 2260 | 2258 | "Attempt to get gfx clk levels Failed!", |
| 2261 | 2259 | return -1); |
| 2262 | 2260 | for (i = 0; i < clocks.num_levels; i++) |
| 2263 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 2261 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 2264 | 2262 | i, clocks.data[i].clocks_in_khz / 1000, |
| 2265 | 2263 | (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : ""); |
| 2266 | 2264 | break; |
| @@ -2276,7 +2274,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, · 9 unmodified lines | ||
| 2276 | 2274 | "Attempt to get memory clk levels Failed!", |
| 2277 | 2275 | return -1); |
| 2278 | 2276 | for (i = 0; i < clocks.num_levels; i++) |
| 2279 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 2277 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 2280 | 2278 | i, clocks.data[i].clocks_in_khz / 1000, |
| 2281 | 2279 | (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : ""); |
| 2282 | 2280 | break; |
| @@ -2294,7 +2292,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, · 11 unmodified lines | ||
| 2294 | 2292 | "Attempt to get soc clk levels Failed!", |
| 2295 | 2293 | return -1); |
| 2296 | 2294 | for (i = 0; i < clocks.num_levels; i++) |
| 2297 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 2295 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 2298 | 2296 | i, clocks.data[i].clocks_in_khz / 1000, |
| 2299 | 2297 | (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : ""); |
| 2300 | 2298 | break; |
| @@ -2312,7 +2310,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, · 11 unmodified lines | ||
| 2312 | 2310 | "Attempt to get dcef clk levels Failed!", |
| 2313 | 2311 | return -1); |
| 2314 | 2312 | for (i = 0; i < clocks.num_levels; i++) |
| 2315 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 2313 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 2316 | 2314 | i, clocks.data[i].clocks_in_khz / 1000, |
| 2317 | 2315 | (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : ""); |
| 2318 | 2316 | break; |
| @@ -3366,8 +3366,6 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 3365 unmodified lines | ||
| 3366 | 3366 | int ret = 0; |
| 3367 | 3367 | uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width; |
| 3368 | 3368 | |
| 3369 | − phm_get_sysfs_buf(&buf, &size); | |
| 3370 | − | |
| 3371 | 3369 | switch (type) { |
| 3372 | 3370 | case PP_SCLK: |
| 3373 | 3371 | ret = vega20_get_current_clk_freq(hwmgr, PPCLK_GFXCLK, &now); |
| @@ -3376,13 +3374,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 2 unmodified lines | ||
| 3376 | 3374 | return ret); |
| 3377 | 3375 | |
| 3378 | 3376 | if (vega20_get_sclks(hwmgr, &clocks)) { |
| 3379 | − size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n", | |
| 3377 | + size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", | |
| 3380 | 3378 | now / 100); |
| 3381 | 3379 | break; |
| 3382 | 3380 | } |
| 3383 | 3381 | |
| 3384 | 3382 | for (i = 0; i < clocks.num_levels; i++) |
| 3385 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 3383 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 3386 | 3384 | i, clocks.data[i].clocks_in_khz / 1000, |
| 3387 | 3385 | (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); |
| 3388 | 3386 | break; |
| @@ -3394,13 +3392,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 5 unmodified lines | ||
| 3394 | 3392 | return ret); |
| 3395 | 3393 | |
| 3396 | 3394 | if (vega20_get_memclocks(hwmgr, &clocks)) { |
| 3397 | − size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n", | |
| 3395 | + size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", | |
| 3398 | 3396 | now / 100); |
| 3399 | 3397 | break; |
| 3400 | 3398 | } |
| 3401 | 3399 | |
| 3402 | 3400 | for (i = 0; i < clocks.num_levels; i++) |
| 3403 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 3401 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 3404 | 3402 | i, clocks.data[i].clocks_in_khz / 1000, |
| 3405 | 3403 | (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); |
| 3406 | 3404 | break; |
| @@ -3412,13 +3410,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 5 unmodified lines | ||
| 3412 | 3410 | return ret); |
| 3413 | 3411 | |
| 3414 | 3412 | if (vega20_get_socclocks(hwmgr, &clocks)) { |
| 3415 | − size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n", | |
| 3413 | + size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", | |
| 3416 | 3414 | now / 100); |
| 3417 | 3415 | break; |
| 3418 | 3416 | } |
| 3419 | 3417 | |
| 3420 | 3418 | for (i = 0; i < clocks.num_levels; i++) |
| 3421 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 3419 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 3422 | 3420 | i, clocks.data[i].clocks_in_khz / 1000, |
| 3423 | 3421 | (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); |
| 3424 | 3422 | break; |
| @@ -3430,7 +3428,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 5 unmodified lines | ||
| 3430 | 3428 | return ret); |
| 3431 | 3429 | |
| 3432 | 3430 | for (i = 0; i < fclk_dpm_table->count; i++) |
| 3433 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 3431 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 3434 | 3432 | i, fclk_dpm_table->dpm_levels[i].value, |
| 3435 | 3433 | fclk_dpm_table->dpm_levels[i].value == (now / 100) ? "*" : ""); |
| 3436 | 3434 | break; |
| @@ -3442,13 +3440,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 5 unmodified lines | ||
| 3442 | 3440 | return ret); |
| 3443 | 3441 | |
| 3444 | 3442 | if (vega20_get_dcefclocks(hwmgr, &clocks)) { |
| 3445 | − size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n", | |
| 3443 | + size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", | |
| 3446 | 3444 | now / 100); |
| 3447 | 3445 | break; |
| 3448 | 3446 | } |
| 3449 | 3447 | |
| 3450 | 3448 | for (i = 0; i < clocks.num_levels; i++) |
| 3451 | − size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", | |
| 3449 | + size += sprintf(buf + size, "%d: %uMhz %s\n", | |
| 3452 | 3450 | i, clocks.data[i].clocks_in_khz / 1000, |
| 3453 | 3451 | (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); |
| 3454 | 3452 | break; |
| @@ -3462,7 +3460,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 7 unmodified lines | ||
| 3462 | 3460 | gen_speed = pptable->PcieGenSpeed[i]; |
| 3463 | 3461 | lane_width = pptable->PcieLaneCount[i]; |
| 3464 | 3462 | |
| 3465 | − size += sysfs_emit_at(buf, size, "%d: %s %s %dMhz %s\n", i, | |
| 3463 | + size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, | |
| 3466 | 3464 | (gen_speed == 0) ? "2.5GT/s," : |
| 3467 | 3465 | (gen_speed == 1) ? "5.0GT/s," : |
| 3468 | 3466 | (gen_speed == 2) ? "8.0GT/s," : |
| @@ -3483,18 +3481,18 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 14 unmodified lines | ||
| 3483 | 3481 | case OD_SCLK: |
| 3484 | 3482 | if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id && |
| 3485 | 3483 | od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) { |
| 3486 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); | |
| 3487 | − size += sysfs_emit_at(buf, size, "0: %10uMhz\n", | |
| 3484 | + size += sprintf(buf + size, "%s:\n", "OD_SCLK"); | |
| 3485 | + size += sprintf(buf + size, "0: %10uMhz\n", | |
| 3488 | 3486 | od_table->GfxclkFmin); |
| 3489 | − size += sysfs_emit_at(buf, size, "1: %10uMhz\n", | |
| 3487 | + size += sprintf(buf + size, "1: %10uMhz\n", | |
| 3490 | 3488 | od_table->GfxclkFmax); |
| 3491 | 3489 | } |
| 3492 | 3490 | break; |
| 3493 | 3491 | |
| 3494 | 3492 | case OD_MCLK: |
| 3495 | 3493 | if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) { |
| 3496 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); | |
| 3497 | − size += sysfs_emit_at(buf, size, "1: %10uMhz\n", | |
| 3494 | + size += sprintf(buf + size, "%s:\n", "OD_MCLK"); | |
| 3495 | + size += sprintf(buf + size, "1: %10uMhz\n", | |
| 3498 | 3496 | od_table->UclkFmax); |
| 3499 | 3497 | } |
| 3500 | 3498 | |
| @@ -3507,14 +3505,14 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 6 unmodified lines | ||
| 3507 | 3505 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id && |
| 3508 | 3506 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id && |
| 3509 | 3507 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) { |
| 3510 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_VDDC_CURVE"); | |
| 3511 | − size += sysfs_emit_at(buf, size, "0: %10uMhz %10dmV\n", | |
| 3508 | + size += sprintf(buf + size, "%s:\n", "OD_VDDC_CURVE"); | |
| 3509 | + size += sprintf(buf + size, "0: %10uMhz %10dmV\n", | |
| 3512 | 3510 | od_table->GfxclkFreq1, |
| 3513 | 3511 | od_table->GfxclkVolt1 / VOLTAGE_SCALE); |
| 3514 | − size += sysfs_emit_at(buf, size, "1: %10uMhz %10dmV\n", | |
| 3512 | + size += sprintf(buf + size, "1: %10uMhz %10dmV\n", | |
| 3515 | 3513 | od_table->GfxclkFreq2, |
| 3516 | 3514 | od_table->GfxclkVolt2 / VOLTAGE_SCALE); |
| 3517 | − size += sysfs_emit_at(buf, size, "2: %10uMhz %10dmV\n", | |
| 3515 | + size += sprintf(buf + size, "2: %10uMhz %10dmV\n", | |
| 3518 | 3516 | od_table->GfxclkFreq3, |
| 3519 | 3517 | od_table->GfxclkVolt3 / VOLTAGE_SCALE); |
| 3520 | 3518 | } |
| @@ -3522,17 +3520,17 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 1 unmodified line | ||
| 3522 | 3520 | break; |
| 3523 | 3521 | |
| 3524 | 3522 | case OD_RANGE: |
| 3525 | − size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); | |
| 3523 | + size += sprintf(buf + size, "%s:\n", "OD_RANGE"); | |
| 3526 | 3524 | |
| 3527 | 3525 | if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id && |
| 3528 | 3526 | od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) { |
| 3529 | − size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", | |
| 3527 | + size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n", | |
| 3530 | 3528 | od8_settings[OD8_SETTING_GFXCLK_FMIN].min_value, |
| 3531 | 3529 | od8_settings[OD8_SETTING_GFXCLK_FMAX].max_value); |
| 3532 | 3530 | } |
| 3533 | 3531 | |
| 3534 | 3532 | if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) { |
| 3535 | − size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n", | |
| 3533 | + size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n", | |
| 3536 | 3534 | od8_settings[OD8_SETTING_UCLK_FMAX].min_value, |
| 3537 | 3535 | od8_settings[OD8_SETTING_UCLK_FMAX].max_value); |
| 3538 | 3536 | } |
| @@ -3543,22 +3541,22 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, · 4 unmodified lines | ||
| 3543 | 3541 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id && |
| 3544 | 3542 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id && |
| 3545 | 3543 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) { |
| 3546 | − size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n", | |
| 3544 | + size += sprintf(buf + size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n", | |
| 3547 | 3545 | od8_settings[OD8_SETTING_GFXCLK_FREQ1].min_value, |
| 3548 | 3546 | od8_settings[OD8_SETTING_GFXCLK_FREQ1].max_value); |
| 3549 | − size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n", | |
| 3547 | + size += sprintf(buf + size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n", | |
| 3550 | 3548 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].min_value, |
| 3551 | 3549 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].max_value); |
| 3552 | − size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n", | |
| 3550 | + size += sprintf(buf + size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n", | |
| 3553 | 3551 | od8_settings[OD8_SETTING_GFXCLK_FREQ2].min_value, |
| 3554 | 3552 | od8_settings[OD8_SETTING_GFXCLK_FREQ2].max_value); |
| 3555 | − size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n", | |
| 3553 | + size += sprintf(buf + size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n", | |
| 3556 | 3554 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].min_value, |
| 3557 | 3555 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].max_value); |
| 3558 | − size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n", | |
| 3556 | + size += sprintf(buf + size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n", | |
| 3559 | 3557 | od8_settings[OD8_SETTING_GFXCLK_FREQ3].min_value, |
| 3560 | 3558 | od8_settings[OD8_SETTING_GFXCLK_FREQ3].max_value); |
| 3561 | − size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n", | |
| 3559 | + size += sprintf(buf + size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n", | |
| 3562 | 3560 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].min_value, |
| 3563 | 3561 | od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].max_value); |
| 3564 | 3562 | } |
| @@ -1468,7 +1468,7 @@ static int smu_disable_dpms(struct smu_context *smu) · 1467 unmodified lines | ||
| 1468 | 1468 | dev_err(adev->dev, "Failed to disable smu features.\n"); |
| 1469 | 1469 | } |
| 1470 | 1470 | |
| 1471 | − if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0) && | |
| 1471 | + if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2) && | |
| 1472 | 1472 | adev->gfx.rlc.funcs->stop) |
| 1473 | 1473 | adev->gfx.rlc.funcs->stop(adev); |
| 1474 | 1474 | |
| @@ -309,6 +309,7 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, · 308 unmodified lines | ||
| 309 | 309 | { |
| 310 | 310 | int ret = 0, size = 0; |
| 311 | 311 | uint32_t cur_value = 0; |
| 312 | + int i; | |
| 312 | 313 | |
| 313 | 314 | smu_cmn_get_sysfs_buf(&buf, &size); |
| 314 | 315 | |
| @@ -334,8 +335,6 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, · 19 unmodified lines | ||
| 334 | 335 | size += sysfs_emit_at(buf, size, "VDDC: %7umV %10umV\n", |
| 335 | 336 | CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX); |
| 336 | 337 | break; |
| 337 | − case SMU_GFXCLK: | |
| 338 | − case SMU_SCLK: | |
| 339 | 338 | case SMU_FCLK: |
| 340 | 339 | case SMU_MCLK: |
| 341 | 340 | case SMU_SOCCLK: |
| @@ -346,6 +345,25 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, · 4 unmodified lines | ||
| 346 | 345 | return ret; |
| 347 | 346 | size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value); |
| 348 | 347 | break; |
| 348 | + case SMU_SCLK: | |
| 349 | + case SMU_GFXCLK: | |
| 350 | + ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &cur_value); | |
| 351 | + if (ret) | |
| 352 | + return ret; | |
| 353 | + if (cur_value == CYAN_SKILLFISH_SCLK_MAX) | |
| 354 | + i = 2; | |
| 355 | + else if (cur_value == CYAN_SKILLFISH_SCLK_MIN) | |
| 356 | + i = 0; | |
| 357 | + else | |
| 358 | + i = 1; | |
| 359 | + size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MIN, | |
| 360 | + i == 0 ? "*" : ""); | |
| 361 | + size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", | |
| 362 | + i == 1 ? cur_value : cyan_skillfish_sclk_default, | |
| 363 | + i == 1 ? "*" : ""); | |
| 364 | + size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MAX, | |
| 365 | + i == 2 ? "*" : ""); | |
| 366 | + break; | |
| 349 | 367 | default: |
| 350 | 368 | dev_warn(smu->adev->dev, "Unsupported clock type\n"); |
| 351 | 369 | return ret; |
| @@ -1265,7 +1265,7 @@ static int navi10_print_clk_levels(struct smu_context *smu, · 1264 unmodified lines | ||
| 1265 | 1265 | enum smu_clk_type clk_type, char *buf) |
| 1266 | 1266 | { |
| 1267 | 1267 | uint16_t *curve_settings; |
| 1268 | − int i, size = 0, ret = 0; | |
| 1268 | + int i, levels, size = 0, ret = 0; | |
| 1269 | 1269 | uint32_t cur_value = 0, value = 0, count = 0; |
| 1270 | 1270 | uint32_t freq_values[3] = {0}; |
| 1271 | 1271 | uint32_t mark_index = 0; |
| @@ -1319,14 +1319,17 @@ static int navi10_print_clk_levels(struct smu_context *smu, · 47 unmodified lines | ||
| 1319 | 1319 | freq_values[1] = cur_value; |
| 1320 | 1320 | mark_index = cur_value == freq_values[0] ? 0 : |
| 1321 | 1321 | cur_value == freq_values[2] ? 2 : 1; |
| 1322 | − if (mark_index != 1) | |
| 1323 | − freq_values[1] = (freq_values[0] + freq_values[2]) / 2; | |
| 1324 | 1322 | |
| 1325 | − for (i = 0; i < 3; i++) { | |
| 1323 | + levels = 3; | |
| 1324 | + if (mark_index != 1) { | |
| 1325 | + levels = 2; | |
| 1326 | + freq_values[1] = freq_values[2]; | |
| 1327 | + } | |
| 1328 | + | |
| 1329 | + for (i = 0; i < levels; i++) { | |
| 1326 | 1330 | size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, freq_values[i], |
| 1327 | 1331 | i == mark_index ? "*" : ""); |
| 1328 | 1332 | } |
| 1329 | − | |
| 1330 | 1333 | } |
| 1331 | 1334 | break; |
| 1332 | 1335 | case SMU_PCIE: |
| @@ -683,6 +683,7 @@ static int vangogh_print_clk_levels(struct smu_context *smu, · 682 unmodified lines | ||
| 683 | 683 | int i, size = 0, ret = 0; |
| 684 | 684 | uint32_t cur_value = 0, value = 0, count = 0; |
| 685 | 685 | bool cur_value_match_level = false; |
| 686 | + uint32_t min, max; | |
| 686 | 687 | |
| 687 | 688 | memset(&metrics, 0, sizeof(metrics)); |
| 688 | 689 | |
| @@ -743,6 +744,13 @@ static int vangogh_print_clk_levels(struct smu_context *smu, · 54 unmodified lines | ||
| 743 | 744 | if (ret) |
| 744 | 745 | return ret; |
| 745 | 746 | break; |
| 747 | + case SMU_GFXCLK: | |
| 748 | + case SMU_SCLK: | |
| 749 | + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetGfxclkFrequency, 0, &cur_value); | |
| 750 | + if (ret) { | |
| 751 | + return ret; | |
| 752 | + } | |
| 753 | + break; | |
| 746 | 754 | default: |
| 747 | 755 | break; |
| 748 | 756 | } |
| @@ -768,6 +776,24 @@ static int vangogh_print_clk_levels(struct smu_context *smu, · 19 unmodified lines | ||
| 768 | 776 | if (!cur_value_match_level) |
| 769 | 777 | size += sysfs_emit_at(buf, size, " %uMhz *\n", cur_value); |
| 770 | 778 | break; |
| 779 | + case SMU_GFXCLK: | |
| 780 | + case SMU_SCLK: | |
| 781 | + min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; | |
| 782 | + max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; | |
| 783 | + if (cur_value == max) | |
| 784 | + i = 2; | |
| 785 | + else if (cur_value == min) | |
| 786 | + i = 0; | |
| 787 | + else | |
| 788 | + i = 1; | |
| 789 | + size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, | |
| 790 | + i == 0 ? "*" : ""); | |
| 791 | + size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", | |
| 792 | + i == 1 ? cur_value : VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, | |
| 793 | + i == 1 ? "*" : ""); | |
| 794 | + size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, | |
| 795 | + i == 2 ? "*" : ""); | |
| 796 | + break; | |
| 771 | 797 | default: |
| 772 | 798 | break; |
| 773 | 799 | } |
| @@ -697,6 +697,11 @@ static int yellow_carp_get_current_clk_freq(struct smu_context *smu, · 696 unmodified lines | ||
| 697 | 697 | case SMU_FCLK: |
| 698 | 698 | return smu_cmn_send_smc_msg_with_param(smu, |
| 699 | 699 | SMU_MSG_GetFclkFrequency, 0, value); |
| 700 | + case SMU_GFXCLK: | |
| 701 | + case SMU_SCLK: | |
| 702 | + return smu_cmn_send_smc_msg_with_param(smu, | |
| 703 | + SMU_MSG_GetGfxclkFrequency, 0, value); | |
| 704 | + break; | |
| 700 | 705 | default: |
| 701 | 706 | return -EINVAL; |
| 702 | 707 | } |
| @@ -967,6 +972,7 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu, · 264 unmodified lines | ||
| 967 | 972 | { |
| 968 | 973 | int i, size = 0, ret = 0; |
| 969 | 974 | uint32_t cur_value = 0, value = 0, count = 0; |
| 975 | + uint32_t min, max; | |
| 970 | 976 | |
| 971 | 977 | smu_cmn_get_sysfs_buf(&buf, &size); |
| 972 | 978 | |
| @@ -1005,6 +1011,27 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu, · 32 unmodified lines | ||
| 1005 | 1011 | cur_value == value ? "*" : ""); |
| 1006 | 1012 | } |
| 1007 | 1013 | break; |
| 1014 | + case SMU_GFXCLK: | |
| 1015 | + case SMU_SCLK: | |
| 1016 | + ret = yellow_carp_get_current_clk_freq(smu, clk_type, &cur_value); | |
| 1017 | + if (ret) | |
| 1018 | + goto print_clk_out; | |
| 1019 | + min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; | |
| 1020 | + max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; | |
| 1021 | + if (cur_value == max) | |
| 1022 | + i = 2; | |
| 1023 | + else if (cur_value == min) | |
| 1024 | + i = 0; | |
| 1025 | + else | |
| 1026 | + i = 1; | |
| 1027 | + size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, | |
| 1028 | + i == 0 ? "*" : ""); | |
| 1029 | + size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", | |
| 1030 | + i == 1 ? cur_value : YELLOW_CARP_UMD_PSTATE_GFXCLK, | |
| 1031 | + i == 1 ? "*" : ""); | |
| 1032 | + size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, | |
| 1033 | + i == 2 ? "*" : ""); | |
| 1034 | + break; | |
| 1008 | 1035 | default: |
| 1009 | 1036 | break; |
| 1010 | 1037 | } |
| @@ -24,5 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | #define __YELLOW_CARP_PPT_H__ |
| 25 | 25 | |
| 26 | 26 | extern void yellow_carp_set_ppt_funcs(struct smu_context *smu); |
| 27 | +#define YELLOW_CARP_UMD_PSTATE_GFXCLK 1100 | |
| 27 | 28 | |
| 28 | 29 | #endif |
| @@ -139,9 +139,13 @@ static void __smu_cmn_reg_print_error(struct smu_context *smu, · 138 unmodified lines | ||
| 139 | 139 | const char *message = smu_get_message_name(smu, msg); |
| 140 | 140 | |
| 141 | 141 | switch (reg_c2pmsg_90) { |
| 142 | − case SMU_RESP_NONE: | |
| 142 | + case SMU_RESP_NONE: { | |
| 143 | + u32 msg_idx = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66); | |
| 144 | + u32 prm = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82); | |
| 143 | 145 | dev_err_ratelimited(adev->dev, |
| 144 | − "SMU: I'm not done with your previous command!"); | |
| 146 | + "SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x%08X SMN_C2PMSG_82:0x%08X", | |
| 147 | + msg_idx, prm); | |
| 148 | + } | |
| 145 | 149 | break; |
| 146 | 150 | case SMU_RESP_OK: |
| 147 | 151 | /* The SMU executed the command. It completed with a |
| @@ -291,7 +291,7 @@ vga_pw_show(struct device *dev, struct device_attribute *attr, char *buf) · 290 unmodified lines | ||
| 291 | 291 | if (rc) |
| 292 | 292 | return rc; |
| 293 | 293 | |
| 294 | − return sprintf(buf, "%u\n", reg & 1); | |
| 294 | + return sprintf(buf, "%u\n", reg); | |
| 295 | 295 | } |
| 296 | 296 | static DEVICE_ATTR_RO(vga_pw); |
| 297 | 297 | |
| @@ -210,8 +210,13 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) · 209 unmodified lines | ||
| 210 | 210 | dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map); |
| 211 | 211 | drm_prime_gem_destroy(gem_obj, cma_obj->sgt); |
| 212 | 212 | } else if (cma_obj->vaddr) { |
| 213 | − dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, | |
| 214 | − cma_obj->vaddr, cma_obj->paddr); | |
| 213 | + if (cma_obj->map_noncoherent) | |
| 214 | + dma_free_noncoherent(gem_obj->dev->dev, cma_obj->base.size, | |
| 215 | + cma_obj->vaddr, cma_obj->paddr, | |
| 216 | + DMA_TO_DEVICE); | |
| 217 | + else | |
| 218 | + dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, | |
| 219 | + cma_obj->vaddr, cma_obj->paddr); | |
| 215 | 220 | } |
| 216 | 221 | |
| 217 | 222 | drm_gem_object_release(gem_obj); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/shmem_fs.h> |
| 10 | 10 | #include <linux/slab.h> |
| 11 | 11 | #include <linux/vmalloc.h> |
| 12 | +#include <linux/module.h> | |
| 12 | 13 | |
| 13 | 14 | #ifdef CONFIG_X86 |
| 14 | 15 | #include <asm/set_memory.h> |
| @@ -404,8 +404,17 @@ int drm_syncobj_find_fence(struct drm_file *file_private, · 403 unmodified lines | ||
| 404 | 404 | |
| 405 | 405 | if (*fence) { |
| 406 | 406 | ret = dma_fence_chain_find_seqno(fence, point); |
| 407 | − if (!ret) | |
| 407 | + if (!ret) { | |
| 408 | + /* If the requested seqno is already signaled | |
| 409 | + * drm_syncobj_find_fence may return a NULL | |
| 410 | + * fence. To make sure the recipient gets | |
| 411 | + * signalled, use a new fence instead. | |
| 412 | + */ | |
| 413 | + if (!*fence) | |
| 414 | + *fence = dma_fence_get_stub(); | |
| 415 | + | |
| 408 | 416 | goto out; |
| 417 | + } | |
| 409 | 418 | dma_fence_put(*fence); |
| 410 | 419 | } else { |
| 411 | 420 | ret = -EINVAL; |
| @@ -225,12 +225,29 @@ static int hyperv_vmbus_remove(struct hv_device *hdev) · 224 unmodified lines | ||
| 225 | 225 | { |
| 226 | 226 | struct drm_device *dev = hv_get_drvdata(hdev); |
| 227 | 227 | struct hyperv_drm_device *hv = to_hv(dev); |
| 228 | + struct pci_dev *pdev; | |
| 228 | 229 | |
| 229 | 230 | drm_dev_unplug(dev); |
| 230 | 231 | drm_atomic_helper_shutdown(dev); |
| 231 | 232 | vmbus_close(hdev->channel); |
| 232 | 233 | hv_set_drvdata(hdev, NULL); |
| 233 | − vmbus_free_mmio(hv->mem->start, hv->fb_size); | |
| 234 | + | |
| 235 | + /* | |
| 236 | + * Free allocated MMIO memory only on Gen2 VMs. | |
| 237 | + * On Gen1 VMs, release the PCI device | |
| 238 | + */ | |
| 239 | + if (efi_enabled(EFI_BOOT)) { | |
| 240 | + vmbus_free_mmio(hv->mem->start, hv->fb_size); | |
| 241 | + } else { | |
| 242 | + pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, | |
| 243 | + PCI_DEVICE_ID_HYPERV_VIDEO, NULL); | |
| 244 | + if (!pdev) { | |
| 245 | + drm_err(dev, "Unable to find PCI Hyper-V video\n"); | |
| 246 | + return -ENODEV; | |
| 247 | + } | |
| 248 | + pci_release_region(pdev, 0); | |
| 249 | + pci_dev_put(pdev); | |
| 250 | + } | |
| 234 | 251 | |
| 235 | 252 | return 0; |
| 236 | 253 | } |
| @@ -696,10 +696,7 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder, · 695 unmodified lines | ||
| 696 | 696 | intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val); |
| 697 | 697 | |
| 698 | 698 | for_each_dsi_phy(phy, intel_dsi->phys) { |
| 699 | − if (DISPLAY_VER(dev_priv) >= 12) | |
| 700 | − val |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); | |
| 701 | − else | |
| 702 | − val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); | |
| 699 | + val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); | |
| 703 | 700 | } |
| 704 | 701 | intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val); |
| 705 | 702 | |
| @@ -1135,8 +1132,6 @@ static void · 429 unmodified lines | ||
| 1135 | 1132 | gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, |
| 1136 | 1133 | const struct intel_crtc_state *crtc_state) |
| 1137 | 1134 | { |
| 1138 | − struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | |
| 1139 | − | |
| 1140 | 1135 | /* step 4a: power up all lanes of the DDI used by DSI */ |
| 1141 | 1136 | gen11_dsi_power_up_lanes(encoder); |
| 1142 | 1137 | |
| @@ -1162,8 +1157,7 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, · 19 unmodified lines | ||
| 1162 | 1157 | gen11_dsi_configure_transcoder(encoder, crtc_state); |
| 1163 | 1158 | |
| 1164 | 1159 | /* Step 4l: Gate DDI clocks */ |
| 1165 | − if (DISPLAY_VER(dev_priv) == 11) | |
| 1166 | − gen11_dsi_gate_clocks(encoder); | |
| 1160 | + gen11_dsi_gate_clocks(encoder); | |
| 1167 | 1161 | } |
| 1168 | 1162 | |
| 1169 | 1163 | static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) |
| @@ -1271,7 +1265,8 @@ static void adlp_set_lp_hs_wakeup_gb(struct intel_encoder *encoder) · 101 unmodified lines | ||
| 1271 | 1265 | if (DISPLAY_VER(i915) == 13) { |
| 1272 | 1266 | for_each_dsi_port(port, intel_dsi->ports) |
| 1273 | 1267 | intel_de_rmw(i915, TGL_DSI_CHKN_REG(port), |
| 1274 | − TGL_DSI_CHKN_LSHS_GB, 0x4); | |
| 1268 | + TGL_DSI_CHKN_LSHS_GB_MASK, | |
| 1269 | + TGL_DSI_CHKN_LSHS_GB(4)); | |
| 1275 | 1270 | } |
| 1276 | 1271 | } |
| 1277 | 1272 | |
| @@ -1640,6 +1640,9 @@ struct intel_dp { · 1639 unmodified lines | ||
| 1640 | 1640 | struct intel_dp_pcon_frl frl; |
| 1641 | 1641 | |
| 1642 | 1642 | struct intel_psr psr; |
| 1643 | + | |
| 1644 | + /* When we last wrote the OUI for eDP */ | |
| 1645 | + unsigned long last_oui_write; | |
| 1643 | 1646 | }; |
| 1644 | 1647 | |
| 1645 | 1648 | enum lspcon_vendor { |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/i2c.h> |
| 30 | 30 | #include <linux/notifier.h> |
| 31 | 31 | #include <linux/slab.h> |
| 32 | +#include <linux/timekeeping.h> | |
| 32 | 33 | #include <linux/types.h> |
| 33 | 34 | |
| 34 | 35 | #include <asm/byteorder.h> |
| @@ -1955,6 +1956,16 @@ intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful) · 1920 unmodified lines | ||
| 1955 | 1956 | |
| 1956 | 1957 | if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0) |
| 1957 | 1958 | drm_err(&i915->drm, "Failed to write source OUI\n"); |
| 1959 | + | |
| 1960 | + intel_dp->last_oui_write = jiffies; | |
| 1961 | +} | |
| 1962 | + | |
| 1963 | +void intel_dp_wait_source_oui(struct intel_dp *intel_dp) | |
| 1964 | +{ | |
| 1965 | + struct drm_i915_private *i915 = dp_to_i915(intel_dp); | |
| 1966 | + | |
| 1967 | + drm_dbg_kms(&i915->drm, "Performing OUI wait\n"); | |
| 1968 | + wait_remaining_ms_from_jiffies(intel_dp->last_oui_write, 30); | |
| 1958 | 1969 | } |
| 1959 | 1970 | |
| 1960 | 1971 | /* If the device supports it, try to set the power state appropriately */ |
| @@ -119,4 +119,6 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp, · 118 unmodified lines | ||
| 119 | 119 | const struct intel_crtc_state *crtc_state); |
| 120 | 120 | void intel_dp_phy_test(struct intel_encoder *encoder); |
| 121 | 121 | |
| 122 | +void intel_dp_wait_source_oui(struct intel_dp *intel_dp); | |
| 123 | + | |
| 122 | 124 | #endif /* __INTEL_DP_H__ */ |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | #include "intel_backlight.h" |
| 38 | 38 | #include "intel_display_types.h" |
| 39 | +#include "intel_dp.h" | |
| 39 | 40 | #include "intel_dp_aux_backlight.h" |
| 40 | 41 | |
| 41 | 42 | /* TODO: |
| @@ -106,6 +107,8 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector) · 64 unmodified lines | ||
| 106 | 107 | int ret; |
| 107 | 108 | u8 tcon_cap[4]; |
| 108 | 109 | |
| 110 | + intel_dp_wait_source_oui(intel_dp); | |
| 111 | + | |
| 109 | 112 | ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap)); |
| 110 | 113 | if (ret != sizeof(tcon_cap)) |
| 111 | 114 | return false; |
| @@ -204,6 +207,8 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state, · 92 unmodified lines | ||
| 204 | 207 | int ret; |
| 205 | 208 | u8 old_ctrl, ctrl; |
| 206 | 209 | |
| 210 | + intel_dp_wait_source_oui(intel_dp); | |
| 211 | + | |
| 207 | 212 | ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl); |
| 208 | 213 | if (ret != 1) { |
| 209 | 214 | drm_err(&i915->drm, "Failed to read current backlight control mode: %d\n", ret); |
| @@ -293,6 +298,13 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state, · 83 unmodified lines | ||
| 293 | 298 | struct intel_panel *panel = &connector->panel; |
| 294 | 299 | struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); |
| 295 | 300 | |
| 301 | + if (!panel->backlight.edp.vesa.info.aux_enable) { | |
| 302 | + u32 pwm_level = intel_backlight_invert_pwm_level(connector, | |
| 303 | + panel->backlight.pwm_level_max); | |
| 304 | + | |
| 305 | + panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level); | |
| 306 | + } | |
| 307 | + | |
| 296 | 308 | drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level); |
| 297 | 309 | } |
| 298 | 310 | |
| @@ -304,6 +316,10 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state · 5 unmodified lines | ||
| 304 | 316 | struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); |
| 305 | 317 | |
| 306 | 318 | drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info); |
| 319 | + | |
| 320 | + if (!panel->backlight.edp.vesa.info.aux_enable) | |
| 321 | + panel->backlight.pwm_funcs->disable(old_conn_state, | |
| 322 | + intel_backlight_invert_pwm_level(connector, 0)); | |
| 307 | 323 | } |
| 308 | 324 | |
| 309 | 325 | static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe) |
| @@ -321,6 +337,15 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, · 11 unmodified lines | ||
| 321 | 337 | if (ret < 0) |
| 322 | 338 | return ret; |
| 323 | 339 | |
| 340 | + if (!panel->backlight.edp.vesa.info.aux_enable) { | |
| 341 | + ret = panel->backlight.pwm_funcs->setup(connector, pipe); | |
| 342 | + if (ret < 0) { | |
| 343 | + drm_err(&i915->drm, | |
| 344 | + "Failed to setup PWM backlight controls for eDP backlight: %d\n", | |
| 345 | + ret); | |
| 346 | + return ret; | |
| 347 | + } | |
| 348 | + } | |
| 324 | 349 | panel->backlight.max = panel->backlight.edp.vesa.info.max; |
| 325 | 350 | panel->backlight.min = 0; |
| 326 | 351 | if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { |
| @@ -340,12 +365,7 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector) · 13 unmodified lines | ||
| 340 | 365 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
| 341 | 366 | struct drm_i915_private *i915 = dp_to_i915(intel_dp); |
| 342 | 367 | |
| 343 | − /* TODO: We currently only support AUX only backlight configurations, not backlights which | |
| 344 | − * require a mix of PWM and AUX controls to work. In the mean time, these machines typically | |
| 345 | − * work just fine using normal PWM controls anyway. | |
| 346 | − */ | |
| 347 | − if ((intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) && | |
| 348 | − drm_edp_backlight_supported(intel_dp->edp_dpcd)) { | |
| 368 | + if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) { | |
| 349 | 369 | drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n"); |
| 350 | 370 | return true; |
| 351 | 371 | } |
| @@ -3277,6 +3277,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, · 3276 unmodified lines | ||
| 3277 | 3277 | out_fence = eb_requests_create(&eb, in_fence, out_fence_fd); |
| 3278 | 3278 | if (IS_ERR(out_fence)) { |
| 3279 | 3279 | err = PTR_ERR(out_fence); |
| 3280 | + out_fence = NULL; | |
| 3280 | 3281 | if (eb.requests[0]) |
| 3281 | 3282 | goto err_request; |
| 3282 | 3283 | else |
| @@ -301,7 +301,7 @@ void intel_gt_suspend_prepare(struct intel_gt *gt) · 300 unmodified lines | ||
| 301 | 301 | user_forcewake(gt, true); |
| 302 | 302 | wait_for_suspend(gt); |
| 303 | 303 | |
| 304 | − intel_pxp_suspend(>->pxp, false); | |
| 304 | + intel_pxp_suspend_prepare(>->pxp); | |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | 307 | static suspend_state_t pm_suspend_target(void) |
| @@ -326,6 +326,7 @@ void intel_gt_suspend_late(struct intel_gt *gt) · 18 unmodified lines | ||
| 326 | 326 | GEM_BUG_ON(gt->awake); |
| 327 | 327 | |
| 328 | 328 | intel_uc_suspend(>->uc); |
| 329 | + intel_pxp_suspend(>->pxp); | |
| 329 | 330 | |
| 330 | 331 | /* |
| 331 | 332 | * On disabling the device, we want to turn off HW access to memory |
| @@ -353,7 +354,7 @@ void intel_gt_suspend_late(struct intel_gt *gt) · 21 unmodified lines | ||
| 353 | 354 | |
| 354 | 355 | void intel_gt_runtime_suspend(struct intel_gt *gt) |
| 355 | 356 | { |
| 356 | − intel_pxp_suspend(>->pxp, true); | |
| 357 | + intel_pxp_runtime_suspend(>->pxp); | |
| 357 | 358 | intel_uc_runtime_suspend(>->uc); |
| 358 | 359 | |
| 359 | 360 | GT_TRACE(gt, "\n"); |
| @@ -371,7 +372,7 @@ int intel_gt_runtime_resume(struct intel_gt *gt) · 11 unmodified lines | ||
| 371 | 372 | if (ret) |
| 372 | 373 | return ret; |
| 373 | 374 | |
| 374 | − intel_pxp_resume(>->pxp); | |
| 375 | + intel_pxp_runtime_resume(>->pxp); | |
| 375 | 376 | |
| 376 | 377 | return 0; |
| 377 | 378 | } |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/slab.h> /* fault-inject.h is not standalone! */ |
| 7 | 7 | |
| 8 | 8 | #include <linux/fault-inject.h> |
| 9 | +#include <linux/sched/mm.h> | |
| 9 | 10 | |
| 10 | 11 | #include "gem/i915_gem_lmem.h" |
| 11 | 12 | #include "i915_trace.h" |
| @@ -621,13 +621,6 @@ static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine, · 620 unmodified lines | ||
| 621 | 621 | FF_MODE2_GS_TIMER_MASK, |
| 622 | 622 | FF_MODE2_GS_TIMER_224, |
| 623 | 623 | 0, false); |
| 624 | − | |
| 625 | − /* | |
| 626 | − * Wa_14012131227:dg1 | |
| 627 | − * Wa_1508744258:tgl,rkl,dg1,adl-s,adl-p | |
| 628 | − */ | |
| 629 | − wa_masked_en(wal, GEN7_COMMON_SLICE_CHICKEN1, | |
| 630 | − GEN9_RHWO_OPTIMIZATION_DISABLE); | |
| 631 | 624 | } |
| 632 | 625 | |
| 633 | 626 | static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine, |
| @@ -1134,6 +1127,15 @@ icl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) · 500 unmodified lines | ||
| 1134 | 1127 | GAMT_CHKN_BIT_REG, |
| 1135 | 1128 | GAMT_CHKN_DISABLE_L3_COH_PIPE); |
| 1136 | 1129 | |
| 1130 | + /* Wa_1407352427:icl,ehl */ | |
| 1131 | + wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2, | |
| 1132 | + PSDUNIT_CLKGATE_DIS); | |
| 1133 | + | |
| 1134 | + /* Wa_1406680159:icl,ehl */ | |
| 1135 | + wa_write_or(wal, | |
| 1136 | + SUBSLICE_UNIT_LEVEL_CLKGATE, | |
| 1137 | + GWUNIT_CLKGATE_DIS); | |
| 1138 | + | |
| 1137 | 1139 | /* Wa_1607087056:icl,ehl,jsl */ |
| 1138 | 1140 | if (IS_ICELAKE(i915) || |
| 1139 | 1141 | IS_JSL_EHL_GT_STEP(i915, STEP_A0, STEP_B0)) |
| @@ -1859,15 +1861,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) · 719 unmodified lines | ||
| 1859 | 1861 | wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, |
| 1860 | 1862 | VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS); |
| 1861 | 1863 | |
| 1862 | − /* Wa_1407352427:icl,ehl */ | |
| 1863 | − wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2, | |
| 1864 | − PSDUNIT_CLKGATE_DIS); | |
| 1865 | − | |
| 1866 | − /* Wa_1406680159:icl,ehl */ | |
| 1867 | − wa_write_or(wal, | |
| 1868 | − SUBSLICE_UNIT_LEVEL_CLKGATE, | |
| 1869 | − GWUNIT_CLKGATE_DIS); | |
| 1870 | − | |
| 1871 | 1864 | /* |
| 1872 | 1865 | * Wa_1408767742:icl[a2..forever],ehl[all] |
| 1873 | 1866 | * Wa_1605460711:icl[a0..c0] |
| @@ -3080,8 +3080,8 @@ guc_create_parallel(struct intel_engine_cs **engines, · 3079 unmodified lines | ||
| 3080 | 3080 | |
| 3081 | 3081 | ce = intel_engine_create_virtual(siblings, num_siblings, |
| 3082 | 3082 | FORCE_VIRTUAL); |
| 3083 | − if (!ce) { | |
| 3084 | − err = ERR_PTR(-ENOMEM); | |
| 3083 | + if (IS_ERR(ce)) { | |
| 3084 | + err = ERR_CAST(ce); | |
| 3085 | 3085 | goto unwind; |
| 3086 | 3086 | } |
| 3087 | 3087 | |
| @@ -11717,7 +11717,9 @@ enum skl_power_gate { · 11716 unmodified lines | ||
| 11717 | 11717 | #define TGL_DSI_CHKN_REG(port) _MMIO_PORT(port, \ |
| 11718 | 11718 | _TGL_DSI_CHKN_REG_0, \ |
| 11719 | 11719 | _TGL_DSI_CHKN_REG_1) |
| 11720 | −#define TGL_DSI_CHKN_LSHS_GB REG_GENMASK(15, 12) | |
| 11720 | +#define TGL_DSI_CHKN_LSHS_GB_MASK REG_GENMASK(15, 12) | |
| 11721 | +#define TGL_DSI_CHKN_LSHS_GB(byte_clocks) REG_FIELD_PREP(TGL_DSI_CHKN_LSHS_GB_MASK, \ | |
| 11722 | + (byte_clocks)) | |
| 11721 | 11723 | |
| 11722 | 11724 | /* Display Stream Splitter Control */ |
| 11723 | 11725 | #define DSS_CTL1 _MMIO(0x67400) |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/sched.h> |
| 30 | 30 | #include <linux/sched/clock.h> |
| 31 | 31 | #include <linux/sched/signal.h> |
| 32 | +#include <linux/sched/mm.h> | |
| 32 | 33 | |
| 33 | 34 | #include "gem/i915_gem_context.h" |
| 34 | 35 | #include "gt/intel_breadcrumbs.h" |
| @@ -7,26 +7,29 @@ · 6 unmodified lines | ||
| 7 | 7 | #include "intel_pxp_irq.h" |
| 8 | 8 | #include "intel_pxp_pm.h" |
| 9 | 9 | #include "intel_pxp_session.h" |
| 10 | +#include "i915_drv.h" | |
| 10 | 11 | |
| 11 | −void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime) | |
| 12 | +void intel_pxp_suspend_prepare(struct intel_pxp *pxp) | |
| 12 | 13 | { |
| 13 | 14 | if (!intel_pxp_is_enabled(pxp)) |
| 14 | 15 | return; |
| 15 | 16 | |
| 16 | 17 | pxp->arb_is_valid = false; |
| 17 | 18 | |
| 18 | − /* | |
| 19 | − * Contexts using protected objects keep a runtime PM reference, so we | |
| 20 | − * can only runtime suspend when all of them have been either closed | |
| 21 | − * or banned. Therefore, there is no need to invalidate in that | |
| 22 | − * scenario. | |
| 23 | − */ | |
| 24 | − if (!runtime) | |
| 25 | − intel_pxp_invalidate(pxp); | |
| 19 | + intel_pxp_invalidate(pxp); | |
| 20 | +} | |
| 26 | 21 | |
| 27 | − intel_pxp_fini_hw(pxp); | |
| 22 | +void intel_pxp_suspend(struct intel_pxp *pxp) | |
| 23 | +{ | |
| 24 | + intel_wakeref_t wakeref; | |
| 28 | 25 | |
| 29 | − pxp->hw_state_invalidated = false; | |
| 26 | + if (!intel_pxp_is_enabled(pxp)) | |
| 27 | + return; | |
| 28 | + | |
| 29 | + with_intel_runtime_pm(&pxp_to_gt(pxp)->i915->runtime_pm, wakeref) { | |
| 30 | + intel_pxp_fini_hw(pxp); | |
| 31 | + pxp->hw_state_invalidated = false; | |
| 32 | + } | |
| 30 | 33 | } |
| 31 | 34 | |
| 32 | 35 | void intel_pxp_resume(struct intel_pxp *pxp) |
| @@ -44,3 +47,15 @@ void intel_pxp_resume(struct intel_pxp *pxp) · 11 unmodified lines | ||
| 44 | 47 | |
| 45 | 48 | intel_pxp_init_hw(pxp); |
| 46 | 49 | } |
| 50 | + | |
| 51 | +void intel_pxp_runtime_suspend(struct intel_pxp *pxp) | |
| 52 | +{ | |
| 53 | + if (!intel_pxp_is_enabled(pxp)) | |
| 54 | + return; | |
| 55 | + | |
| 56 | + pxp->arb_is_valid = false; | |
| 57 | + | |
| 58 | + intel_pxp_fini_hw(pxp); | |
| 59 | + | |
| 60 | + pxp->hw_state_invalidated = false; | |
| 61 | +} | |
| @@ -9,16 +9,29 @@ · 8 unmodified lines | ||
| 9 | 9 | #include "intel_pxp_types.h" |
| 10 | 10 | |
| 11 | 11 | #ifdef CONFIG_DRM_I915_PXP |
| 12 | −void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime); | |
| 12 | +void intel_pxp_suspend_prepare(struct intel_pxp *pxp); | |
| 13 | +void intel_pxp_suspend(struct intel_pxp *pxp); | |
| 13 | 14 | void intel_pxp_resume(struct intel_pxp *pxp); |
| 15 | +void intel_pxp_runtime_suspend(struct intel_pxp *pxp); | |
| 14 | 16 | #else |
| 15 | −static inline void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime) | |
| 17 | +static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp) | |
| 18 | +{ | |
| 19 | +} | |
| 20 | + | |
| 21 | +static inline void intel_pxp_suspend(struct intel_pxp *pxp) | |
| 16 | 22 | { |
| 17 | 23 | } |
| 18 | 24 | |
| 19 | 25 | static inline void intel_pxp_resume(struct intel_pxp *pxp) |
| 20 | 26 | { |
| 21 | 27 | } |
| 22 | −#endif | |
| 23 | 28 | |
| 29 | +static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp) | |
| 30 | +{ | |
| 31 | +} | |
| 32 | +#endif | |
| 33 | +static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp) | |
| 34 | +{ | |
| 35 | + intel_pxp_resume(pxp); | |
| 36 | +} | |
| 24 | 37 | #endif /* __INTEL_PXP_PM_H__ */ |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <linux/regulator/consumer.h> |
| 5 | 5 | #include <linux/reset.h> |
| 6 | 6 | #include <linux/clk.h> |
| 7 | +#include <linux/slab.h> | |
| 7 | 8 | #include <linux/dma-mapping.h> |
| 8 | 9 | #include <linux/platform_device.h> |
| 9 | 10 | |
| @@ -4,8 +4,8 @@ config DRM_MSM · 3 unmodified lines | ||
| 4 | 4 | tristate "MSM DRM" |
| 5 | 5 | depends on DRM |
| 6 | 6 | depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST |
| 7 | + depends on COMMON_CLK | |
| 7 | 8 | depends on IOMMU_SUPPORT |
| 8 | − depends on (OF && COMMON_CLK) || COMPILE_TEST | |
| 9 | 9 | depends on QCOM_OCMEM || QCOM_OCMEM=n |
| 10 | 10 | depends on QCOM_LLCC || QCOM_LLCC=n |
| 11 | 11 | depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n |
| @@ -23,8 +23,10 @@ msm-y := \ · 22 unmodified lines | ||
| 23 | 23 | hdmi/hdmi_i2c.o \ |
| 24 | 24 | hdmi/hdmi_phy.o \ |
| 25 | 25 | hdmi/hdmi_phy_8960.o \ |
| 26 | + hdmi/hdmi_phy_8996.o \ | |
| 26 | 27 | hdmi/hdmi_phy_8x60.o \ |
| 27 | 28 | hdmi/hdmi_phy_8x74.o \ |
| 29 | + hdmi/hdmi_pll_8960.o \ | |
| 28 | 30 | edp/edp.o \ |
| 29 | 31 | edp/edp_aux.o \ |
| 30 | 32 | edp/edp_bridge.o \ |
| @@ -37,6 +39,7 @@ msm-y := \ · 6 unmodified lines | ||
| 37 | 39 | disp/mdp4/mdp4_dtv_encoder.o \ |
| 38 | 40 | disp/mdp4/mdp4_lcdc_encoder.o \ |
| 39 | 41 | disp/mdp4/mdp4_lvds_connector.o \ |
| 42 | + disp/mdp4/mdp4_lvds_pll.o \ | |
| 40 | 43 | disp/mdp4/mdp4_irq.o \ |
| 41 | 44 | disp/mdp4/mdp4_kms.o \ |
| 42 | 45 | disp/mdp4/mdp4_plane.o \ |
| @@ -116,9 +119,6 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ · 73 unmodified lines | ||
| 116 | 119 | dp/dp_audio.o |
| 117 | 120 | |
| 118 | 121 | msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o |
| 119 | −msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o | |
| 120 | −msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o | |
| 121 | −msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_phy_8996.o | |
| 122 | 122 | |
| 123 | 123 | msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o |
| 124 | 124 | |
| @@ -1424,17 +1424,24 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) · 1423 unmodified lines | ||
| 1424 | 1424 | { |
| 1425 | 1425 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; |
| 1426 | 1426 | struct msm_gpu *gpu = &adreno_gpu->base; |
| 1427 | − u32 gpu_scid, cntl1_regval = 0; | |
| 1427 | + u32 cntl1_regval = 0; | |
| 1428 | 1428 | |
| 1429 | 1429 | if (IS_ERR(a6xx_gpu->llc_mmio)) |
| 1430 | 1430 | return; |
| 1431 | 1431 | |
| 1432 | 1432 | if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { |
| 1433 | − gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); | |
| 1433 | + u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); | |
| 1434 | 1434 | |
| 1435 | 1435 | gpu_scid &= 0x1f; |
| 1436 | 1436 | cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | |
| 1437 | 1437 | (gpu_scid << 15) | (gpu_scid << 20); |
| 1438 | + | |
| 1439 | + /* On A660, the SCID programming for UCHE traffic is done in | |
| 1440 | + * A6XX_GBIF_SCACHE_CNTL0[14:10] | |
| 1441 | + */ | |
| 1442 | + if (adreno_is_a660_family(adreno_gpu)) | |
| 1443 | + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | | |
| 1444 | + (1 << 8), (gpu_scid << 10) | (1 << 8)); | |
| 1438 | 1445 | } |
| 1439 | 1446 | |
| 1440 | 1447 | /* |
| @@ -1471,13 +1478,6 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) · 30 unmodified lines | ||
| 1471 | 1478 | } |
| 1472 | 1479 | |
| 1473 | 1480 | gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); |
| 1474 | − | |
| 1475 | − /* On A660, the SCID programming for UCHE traffic is done in | |
| 1476 | − * A6XX_GBIF_SCACHE_CNTL0[14:10] | |
| 1477 | − */ | |
| 1478 | − if (adreno_is_a660_family(adreno_gpu)) | |
| 1479 | − gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | | |
| 1480 | − (1 << 8), (gpu_scid << 10) | (1 << 8)); | |
| 1481 | 1481 | } |
| 1482 | 1482 | |
| 1483 | 1483 | static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) |
| @@ -1640,7 +1640,7 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) · 156 unmodified lines | ||
| 1640 | 1640 | return (unsigned long)busy_time; |
| 1641 | 1641 | } |
| 1642 | 1642 | |
| 1643 | −void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) | |
| 1643 | +static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) | |
| 1644 | 1644 | { |
| 1645 | 1645 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 1646 | 1646 | struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); |
| @@ -777,12 +777,12 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu, · 776 unmodified lines | ||
| 777 | 777 | struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); |
| 778 | 778 | |
| 779 | 779 | a6xx_state->gmu_registers = state_kcalloc(a6xx_state, |
| 780 | − 2, sizeof(*a6xx_state->gmu_registers)); | |
| 780 | + 3, sizeof(*a6xx_state->gmu_registers)); | |
| 781 | 781 | |
| 782 | 782 | if (!a6xx_state->gmu_registers) |
| 783 | 783 | return; |
| 784 | 784 | |
| 785 | − a6xx_state->nr_gmu_registers = 2; | |
| 785 | + a6xx_state->nr_gmu_registers = 3; | |
| 786 | 786 | |
| 787 | 787 | /* Get the CX GMU registers from AHB */ |
| 788 | 788 | _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0], |
| @@ -33,6 +33,7 @@ struct dp_aux_private { · 32 unmodified lines | ||
| 33 | 33 | bool read; |
| 34 | 34 | bool no_send_addr; |
| 35 | 35 | bool no_send_stop; |
| 36 | + bool initted; | |
| 36 | 37 | u32 offset; |
| 37 | 38 | u32 segment; |
| 38 | 39 | |
| @@ -331,6 +332,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, · 292 unmodified lines | ||
| 331 | 332 | } |
| 332 | 333 | |
| 333 | 334 | mutex_lock(&aux->mutex); |
| 335 | + if (!aux->initted) { | |
| 336 | + ret = -EIO; | |
| 337 | + goto exit; | |
| 338 | + } | |
| 334 | 339 | |
| 335 | 340 | dp_aux_update_offset_and_segment(aux, msg); |
| 336 | 341 | dp_aux_transfer_helper(aux, msg, true); |
| @@ -380,6 +385,8 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, · 43 unmodified lines | ||
| 380 | 385 | } |
| 381 | 386 | |
| 382 | 387 | aux->cmd_busy = false; |
| 388 | + | |
| 389 | +exit: | |
| 383 | 390 | mutex_unlock(&aux->mutex); |
| 384 | 391 | |
| 385 | 392 | return ret; |
| @@ -431,8 +438,13 @@ void dp_aux_init(struct drm_dp_aux *dp_aux) · 45 unmodified lines | ||
| 431 | 438 | |
| 432 | 439 | aux = container_of(dp_aux, struct dp_aux_private, dp_aux); |
| 433 | 440 | |
| 441 | + mutex_lock(&aux->mutex); | |
| 442 | + | |
| 434 | 443 | dp_catalog_aux_enable(aux->catalog, true); |
| 435 | 444 | aux->retry_cnt = 0; |
| 445 | + aux->initted = true; | |
| 446 | + | |
| 447 | + mutex_unlock(&aux->mutex); | |
| 436 | 448 | } |
| 437 | 449 | |
| 438 | 450 | void dp_aux_deinit(struct drm_dp_aux *dp_aux) |
| @@ -441,7 +453,12 @@ void dp_aux_deinit(struct drm_dp_aux *dp_aux) · 2 unmodified lines | ||
| 441 | 453 | |
| 442 | 454 | aux = container_of(dp_aux, struct dp_aux_private, dp_aux); |
| 443 | 455 | |
| 456 | + mutex_lock(&aux->mutex); | |
| 457 | + | |
| 458 | + aux->initted = false; | |
| 444 | 459 | dp_catalog_aux_enable(aux->catalog, false); |
| 460 | + | |
| 461 | + mutex_unlock(&aux->mutex); | |
| 445 | 462 | } |
| 446 | 463 | |
| 447 | 464 | int dp_aux_register(struct drm_dp_aux *dp_aux) |
| @@ -1658,6 +1658,8 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, · 1657 unmodified lines | ||
| 1658 | 1658 | if (!prop) { |
| 1659 | 1659 | DRM_DEV_DEBUG(dev, |
| 1660 | 1660 | "failed to find data lane mapping, using default\n"); |
| 1661 | + /* Set the number of date lanes to 4 by default. */ | |
| 1662 | + msm_host->num_data_lanes = 4; | |
| 1661 | 1663 | return 0; |
| 1662 | 1664 | } |
| 1663 | 1665 | |
| @@ -77,6 +77,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file) · 76 unmodified lines | ||
| 77 | 77 | goto free_priv; |
| 78 | 78 | |
| 79 | 79 | pm_runtime_get_sync(&gpu->pdev->dev); |
| 80 | + msm_gpu_hw_init(gpu); | |
| 80 | 81 | show_priv->state = gpu->funcs->gpu_state_get(gpu); |
| 81 | 82 | pm_runtime_put_sync(&gpu->pdev->dev); |
| 82 | 83 | |
| @@ -967,29 +967,18 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 966 unmodified lines | ||
| 967 | 967 | return ret; |
| 968 | 968 | } |
| 969 | 969 | |
| 970 | −static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, | |
| 971 | − struct drm_file *file) | |
| 970 | +static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, | |
| 971 | + ktime_t timeout) | |
| 972 | 972 | { |
| 973 | − struct msm_drm_private *priv = dev->dev_private; | |
| 974 | − struct drm_msm_wait_fence *args = data; | |
| 975 | − ktime_t timeout = to_ktime(args->timeout); | |
| 976 | − struct msm_gpu_submitqueue *queue; | |
| 977 | − struct msm_gpu *gpu = priv->gpu; | |
| 978 | 973 | struct dma_fence *fence; |
| 979 | 974 | int ret; |
| 980 | 975 | |
| 981 | − if (args->pad) { | |
| 982 | − DRM_ERROR("invalid pad: %08x\n", args->pad); | |
| 976 | + if (fence_id > queue->last_fence) { | |
| 977 | + DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n", | |
| 978 | + fence_id, queue->last_fence); | |
| 983 | 979 | return -EINVAL; |
| 984 | 980 | } |
| 985 | 981 | |
| 986 | − if (!gpu) | |
| 987 | − return 0; | |
| 988 | − | |
| 989 | − queue = msm_submitqueue_get(file->driver_priv, args->queueid); | |
| 990 | − if (!queue) | |
| 991 | − return -ENOENT; | |
| 992 | − | |
| 993 | 982 | /* |
| 994 | 983 | * Map submitqueue scoped "seqno" (which is actually an idr key) |
| 995 | 984 | * back to underlying dma-fence |
| @@ -1001,7 +990,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, · 5 unmodified lines | ||
| 1001 | 990 | ret = mutex_lock_interruptible(&queue->lock); |
| 1002 | 991 | if (ret) |
| 1003 | 992 | return ret; |
| 1004 | − fence = idr_find(&queue->fence_idr, args->fence); | |
| 993 | + fence = idr_find(&queue->fence_idr, fence_id); | |
| 1005 | 994 | if (fence) |
| 1006 | 995 | fence = dma_fence_get_rcu(fence); |
| 1007 | 996 | mutex_unlock(&queue->lock); |
| @@ -1017,6 +1006,32 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, · 9 unmodified lines | ||
| 1017 | 1006 | } |
| 1018 | 1007 | |
| 1019 | 1008 | dma_fence_put(fence); |
| 1009 | + | |
| 1010 | + return ret; | |
| 1011 | +} | |
| 1012 | + | |
| 1013 | +static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, | |
| 1014 | + struct drm_file *file) | |
| 1015 | +{ | |
| 1016 | + struct msm_drm_private *priv = dev->dev_private; | |
| 1017 | + struct drm_msm_wait_fence *args = data; | |
| 1018 | + struct msm_gpu_submitqueue *queue; | |
| 1019 | + int ret; | |
| 1020 | + | |
| 1021 | + if (args->pad) { | |
| 1022 | + DRM_ERROR("invalid pad: %08x\n", args->pad); | |
| 1023 | + return -EINVAL; | |
| 1024 | + } | |
| 1025 | + | |
| 1026 | + if (!priv->gpu) | |
| 1027 | + return 0; | |
| 1028 | + | |
| 1029 | + queue = msm_submitqueue_get(file->driver_priv, args->queueid); | |
| 1030 | + if (!queue) | |
| 1031 | + return -ENOENT; | |
| 1032 | + | |
| 1033 | + ret = wait_fence(queue, args->fence, to_ktime(args->timeout)); | |
| 1034 | + | |
| 1020 | 1035 | msm_submitqueue_put(queue); |
| 1021 | 1036 | |
| 1022 | 1037 | return ret; |
| @@ -1056,8 +1056,7 @@ static int msm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct · 1055 unmodified lines | ||
| 1056 | 1056 | { |
| 1057 | 1057 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 1058 | 1058 | |
| 1059 | − vma->vm_flags &= ~VM_PFNMAP; | |
| 1060 | − vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND; | |
| 1059 | + vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP; | |
| 1061 | 1060 | vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags)); |
| 1062 | 1061 | |
| 1063 | 1062 | return 0; |
| @@ -1121,7 +1120,7 @@ static int msm_gem_new_impl(struct drm_device *dev, · 57 unmodified lines | ||
| 1121 | 1120 | break; |
| 1122 | 1121 | fallthrough; |
| 1123 | 1122 | default: |
| 1124 | − DRM_DEV_ERROR(dev->dev, "invalid cache flag: %x\n", | |
| 1123 | + DRM_DEV_DEBUG(dev->dev, "invalid cache flag: %x\n", | |
| 1125 | 1124 | (flags & MSM_BO_CACHE_MASK)); |
| 1126 | 1125 | return -EINVAL; |
| 1127 | 1126 | } |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #include <linux/vmalloc.h> |
| 8 | +#include <linux/sched/mm.h> | |
| 8 | 9 | |
| 9 | 10 | #include "msm_drv.h" |
| 10 | 11 | #include "msm_gem.h" |
| @@ -772,6 +772,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 771 unmodified lines | ||
| 772 | 772 | args->nr_cmds); |
| 773 | 773 | if (IS_ERR(submit)) { |
| 774 | 774 | ret = PTR_ERR(submit); |
| 775 | + submit = NULL; | |
| 775 | 776 | goto out_unlock; |
| 776 | 777 | } |
| 777 | 778 | |
| @@ -904,6 +905,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 126 unmodified lines | ||
| 904 | 905 | drm_sched_entity_push_job(&submit->base); |
| 905 | 906 | |
| 906 | 907 | args->fence = submit->fence_id; |
| 908 | + queue->last_fence = submit->fence_id; | |
| 907 | 909 | |
| 908 | 910 | msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs); |
| 909 | 911 | msm_process_post_deps(post_deps, args->nr_out_syncobjs, |
| @@ -359,6 +359,8 @@ static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio, · 358 unmodified lines | ||
| 359 | 359 | * @ring_nr: the ringbuffer used by this submitqueue, which is determined |
| 360 | 360 | * by the submitqueue's priority |
| 361 | 361 | * @faults: the number of GPU hangs associated with this submitqueue |
| 362 | + * @last_fence: the sequence number of the last allocated fence (for error | |
| 363 | + * checking) | |
| 362 | 364 | * @ctx: the per-drm_file context associated with the submitqueue (ie. |
| 363 | 365 | * which set of pgtables do submits jobs associated with the |
| 364 | 366 | * submitqueue use) |
| @@ -374,6 +376,7 @@ struct msm_gpu_submitqueue { · 9 unmodified lines | ||
| 374 | 376 | u32 flags; |
| 375 | 377 | u32 ring_nr; |
| 376 | 378 | int faults; |
| 379 | + uint32_t last_fence; | |
| 377 | 380 | struct msm_file_private *ctx; |
| 378 | 381 | struct list_head node; |
| 379 | 382 | struct idr fence_idr; |
| @@ -20,6 +20,10 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, · 19 unmodified lines | ||
| 20 | 20 | struct msm_gpu *gpu = dev_to_gpu(dev); |
| 21 | 21 | struct dev_pm_opp *opp; |
| 22 | 22 | |
| 23 | + /* | |
| 24 | + * Note that devfreq_recommended_opp() can modify the freq | |
| 25 | + * to something that actually is in the opp table: | |
| 26 | + */ | |
| 23 | 27 | opp = devfreq_recommended_opp(dev, freq, flags); |
| 24 | 28 | |
| 25 | 29 | /* |
| @@ -28,6 +32,7 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, · 2 unmodified lines | ||
| 28 | 32 | */ |
| 29 | 33 | if (gpu->devfreq.idle_freq) { |
| 30 | 34 | gpu->devfreq.idle_freq = *freq; |
| 35 | + dev_pm_opp_put(opp); | |
| 31 | 36 | return 0; |
| 32 | 37 | } |
| 33 | 38 | |
| @@ -203,9 +208,6 @@ static void msm_devfreq_idle_work(struct kthread_work *work) · 169 unmodified lines | ||
| 203 | 208 | struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq); |
| 204 | 209 | unsigned long idle_freq, target_freq = 0; |
| 205 | 210 | |
| 206 | − if (!df->devfreq) | |
| 207 | − return; | |
| 208 | − | |
| 209 | 211 | /* |
| 210 | 212 | * Hold devfreq lock to synchronize with get_dev_status()/ |
| 211 | 213 | * target() callbacks |
| @@ -227,6 +229,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu) · 15 unmodified lines | ||
| 227 | 229 | { |
| 228 | 230 | struct msm_gpu_devfreq *df = &gpu->devfreq; |
| 229 | 231 | |
| 232 | + if (!df->devfreq) | |
| 233 | + return; | |
| 234 | + | |
| 230 | 235 | msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), |
| 231 | − HRTIMER_MODE_ABS); | |
| 236 | + HRTIMER_MODE_REL); | |
| 232 | 237 | } |
| @@ -2626,6 +2626,27 @@ nv174_chipset = { · 2625 unmodified lines | ||
| 2626 | 2626 | .fifo = { 0x00000001, ga102_fifo_new }, |
| 2627 | 2627 | }; |
| 2628 | 2628 | |
| 2629 | +static const struct nvkm_device_chip | |
| 2630 | +nv176_chipset = { | |
| 2631 | + .name = "GA106", | |
| 2632 | + .bar = { 0x00000001, tu102_bar_new }, | |
| 2633 | + .bios = { 0x00000001, nvkm_bios_new }, | |
| 2634 | + .devinit = { 0x00000001, ga100_devinit_new }, | |
| 2635 | + .fb = { 0x00000001, ga102_fb_new }, | |
| 2636 | + .gpio = { 0x00000001, ga102_gpio_new }, | |
| 2637 | + .i2c = { 0x00000001, gm200_i2c_new }, | |
| 2638 | + .imem = { 0x00000001, nv50_instmem_new }, | |
| 2639 | + .mc = { 0x00000001, ga100_mc_new }, | |
| 2640 | + .mmu = { 0x00000001, tu102_mmu_new }, | |
| 2641 | + .pci = { 0x00000001, gp100_pci_new }, | |
| 2642 | + .privring = { 0x00000001, gm200_privring_new }, | |
| 2643 | + .timer = { 0x00000001, gk20a_timer_new }, | |
| 2644 | + .top = { 0x00000001, ga100_top_new }, | |
| 2645 | + .disp = { 0x00000001, ga102_disp_new }, | |
| 2646 | + .dma = { 0x00000001, gv100_dma_new }, | |
| 2647 | + .fifo = { 0x00000001, ga102_fifo_new }, | |
| 2648 | +}; | |
| 2649 | + | |
| 2629 | 2650 | static const struct nvkm_device_chip |
| 2630 | 2651 | nv177_chipset = { |
| 2631 | 2652 | .name = "GA107", |
| @@ -3072,6 +3093,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, · 440 unmodified lines | ||
| 3072 | 3093 | case 0x168: device->chip = &nv168_chipset; break; |
| 3073 | 3094 | case 0x172: device->chip = &nv172_chipset; break; |
| 3074 | 3095 | case 0x174: device->chip = &nv174_chipset; break; |
| 3096 | + case 0x176: device->chip = &nv176_chipset; break; | |
| 3075 | 3097 | case 0x177: device->chip = &nv177_chipset; break; |
| 3076 | 3098 | default: |
| 3077 | 3099 | if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) { |
| @@ -62,7 +62,6 @@ gv100_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet, · 61 unmodified lines | ||
| 62 | 62 | nvkm_wr32(device, 0x6f0108 + hdmi, vendor_infoframe.header); |
| 63 | 63 | nvkm_wr32(device, 0x6f010c + hdmi, vendor_infoframe.subpack0_low); |
| 64 | 64 | nvkm_wr32(device, 0x6f0110 + hdmi, vendor_infoframe.subpack0_high); |
| 65 | − nvkm_wr32(device, 0x6f0110 + hdmi, 0x00000000); | |
| 66 | 65 | nvkm_wr32(device, 0x6f0114 + hdmi, 0x00000000); |
| 67 | 66 | nvkm_wr32(device, 0x6f0118 + hdmi, 0x00000000); |
| 68 | 67 | nvkm_wr32(device, 0x6f011c + hdmi, 0x00000000); |
| @@ -207,11 +207,13 @@ int · 206 unmodified lines | ||
| 207 | 207 | gm200_acr_wpr_parse(struct nvkm_acr *acr) |
| 208 | 208 | { |
| 209 | 209 | const struct wpr_header *hdr = (void *)acr->wpr_fw->data; |
| 210 | + struct nvkm_acr_lsfw *lsfw; | |
| 210 | 211 | |
| 211 | 212 | while (hdr->falcon_id != WPR_HEADER_V0_FALCON_ID_INVALID) { |
| 212 | 213 | wpr_header_dump(&acr->subdev, hdr); |
| 213 | − if (!nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id)) | |
| 214 | − return -ENOMEM; | |
| 214 | + lsfw = nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id); | |
| 215 | + if (IS_ERR(lsfw)) | |
| 216 | + return PTR_ERR(lsfw); | |
| 215 | 217 | } |
| 216 | 218 | |
| 217 | 219 | return 0; |
| @@ -161,11 +161,13 @@ int · 160 unmodified lines | ||
| 161 | 161 | gp102_acr_wpr_parse(struct nvkm_acr *acr) |
| 162 | 162 | { |
| 163 | 163 | const struct wpr_header_v1 *hdr = (void *)acr->wpr_fw->data; |
| 164 | + struct nvkm_acr_lsfw *lsfw; | |
| 164 | 165 | |
| 165 | 166 | while (hdr->falcon_id != WPR_HEADER_V1_FALCON_ID_INVALID) { |
| 166 | 167 | wpr_header_v1_dump(&acr->subdev, hdr); |
| 167 | − if (!nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id)) | |
| 168 | − return -ENOMEM; | |
| 168 | + lsfw = nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id); | |
| 169 | + if (IS_ERR(lsfw)) | |
| 170 | + return PTR_ERR(lsfw); | |
| 169 | 171 | } |
| 170 | 172 | |
| 171 | 173 | return 0; |
| @@ -704,9 +704,13 @@ int drm_sched_job_add_implicit_dependencies(struct drm_sched_job *job, · 703 unmodified lines | ||
| 704 | 704 | int ret; |
| 705 | 705 | |
| 706 | 706 | dma_resv_for_each_fence(&cursor, obj->resv, write, fence) { |
| 707 | + /* Make sure to grab an additional ref on the added fence */ | |
| 708 | + dma_fence_get(fence); | |
| 707 | 709 | ret = drm_sched_job_add_dependency(job, fence); |
| 708 | − if (ret) | |
| 710 | + if (ret) { | |
| 711 | + dma_fence_put(fence); | |
| 709 | 712 | return ret; |
| 713 | + } | |
| 710 | 714 | } |
| 711 | 715 | return 0; |
| 712 | 716 | } |
| @@ -46,6 +46,7 @@ config DRM_SUN6I_DSI · 45 unmodified lines | ||
| 46 | 46 | default MACH_SUN8I |
| 47 | 47 | select CRC_CCITT |
| 48 | 48 | select DRM_MIPI_DSI |
| 49 | + select RESET_CONTROLLER | |
| 49 | 50 | select PHY_SUN6I_MIPI_DPHY |
| 50 | 51 | help |
| 51 | 52 | Choose this option if you want have an Allwinner SoC with |
| @@ -1103,7 +1103,7 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, · 1102 unmodified lines | ||
| 1103 | 1103 | * as an indication that we're about to swap out. |
| 1104 | 1104 | */ |
| 1105 | 1105 | memset(&place, 0, sizeof(place)); |
| 1106 | − place.mem_type = TTM_PL_SYSTEM; | |
| 1106 | + place.mem_type = bo->resource->mem_type; | |
| 1107 | 1107 | if (!ttm_bo_evict_swapout_allowable(bo, ctx, &place, &locked, NULL)) |
| 1108 | 1108 | return -EBUSY; |
| 1109 | 1109 | |
| @@ -1135,6 +1135,7 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, · 25 unmodified lines | ||
| 1135 | 1135 | struct ttm_place hop; |
| 1136 | 1136 | |
| 1137 | 1137 | memset(&hop, 0, sizeof(hop)); |
| 1138 | + place.mem_type = TTM_PL_SYSTEM; | |
| 1138 | 1139 | ret = ttm_resource_alloc(bo, &place, &evict_mem); |
| 1139 | 1140 | if (unlikely(ret)) |
| 1140 | 1141 | goto out; |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <linux/sched.h> |
| 35 | 35 | #include <linux/shmem_fs.h> |
| 36 | 36 | #include <linux/file.h> |
| 37 | +#include <linux/module.h> | |
| 37 | 38 | #include <drm/drm_cache.h> |
| 38 | 39 | #include <drm/ttm/ttm_bo_driver.h> |
| 39 | 40 | |
| @@ -391,7 +391,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) · 390 unmodified lines | ||
| 391 | 391 | |
| 392 | 392 | bo = kzalloc(sizeof(*bo), GFP_KERNEL); |
| 393 | 393 | if (!bo) |
| 394 | − return ERR_PTR(-ENOMEM); | |
| 394 | + return NULL; | |
| 395 | 395 | |
| 396 | 396 | bo->madv = VC4_MADV_WILLNEED; |
| 397 | 397 | refcount_set(&bo->usecnt, 0); |
| @@ -337,10 +337,10 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) · 336 unmodified lines | ||
| 337 | 337 | struct drm_device *dev = state->dev; |
| 338 | 338 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 339 | 339 | struct vc4_hvs *hvs = vc4->hvs; |
| 340 | − struct drm_crtc_state *old_crtc_state; | |
| 341 | 340 | struct drm_crtc_state *new_crtc_state; |
| 342 | 341 | struct drm_crtc *crtc; |
| 343 | 342 | struct vc4_hvs_state *old_hvs_state; |
| 343 | + unsigned int channel; | |
| 344 | 344 | int i; |
| 345 | 345 | |
| 346 | 346 | for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { |
| @@ -353,30 +353,32 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) · 6 unmodified lines | ||
| 353 | 353 | vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel); |
| 354 | 354 | } |
| 355 | 355 | |
| 356 | − if (vc4->hvs->hvs5) | |
| 357 | − clk_set_min_rate(hvs->core_clk, 500000000); | |
| 358 | − | |
| 359 | 356 | old_hvs_state = vc4_hvs_get_old_global_state(state); |
| 360 | − if (!old_hvs_state) | |
| 357 | + if (IS_ERR(old_hvs_state)) | |
| 361 | 358 | return; |
| 362 | 359 | |
| 363 | − for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) { | |
| 364 | − struct vc4_crtc_state *vc4_crtc_state = | |
| 365 | − to_vc4_crtc_state(old_crtc_state); | |
| 366 | − unsigned int channel = vc4_crtc_state->assigned_channel; | |
| 360 | + for (channel = 0; channel < HVS_NUM_CHANNELS; channel++) { | |
| 361 | + struct drm_crtc_commit *commit; | |
| 367 | 362 | int ret; |
| 368 | 363 | |
| 369 | − if (channel == VC4_HVS_CHANNEL_DISABLED) | |
| 364 | + if (!old_hvs_state->fifo_state[channel].in_use) | |
| 370 | 365 | continue; |
| 371 | 366 | |
| 372 | − if (!old_hvs_state->fifo_state[channel].in_use) | |
| 367 | + commit = old_hvs_state->fifo_state[channel].pending_commit; | |
| 368 | + if (!commit) | |
| 373 | 369 | continue; |
| 374 | 370 | |
| 375 | − ret = drm_crtc_commit_wait(old_hvs_state->fifo_state[channel].pending_commit); | |
| 371 | + ret = drm_crtc_commit_wait(commit); | |
| 376 | 372 | if (ret) |
| 377 | 373 | drm_err(dev, "Timed out waiting for commit\n"); |
| 374 | + | |
| 375 | + drm_crtc_commit_put(commit); | |
| 376 | + old_hvs_state->fifo_state[channel].pending_commit = NULL; | |
| 378 | 377 | } |
| 379 | 378 | |
| 379 | + if (vc4->hvs->hvs5) | |
| 380 | + clk_set_min_rate(hvs->core_clk, 500000000); | |
| 381 | + | |
| 380 | 382 | drm_atomic_helper_commit_modeset_disables(dev, state); |
| 381 | 383 | |
| 382 | 384 | vc4_ctm_commit(vc4, state); |
| @@ -410,8 +412,8 @@ static int vc4_atomic_commit_setup(struct drm_atomic_state *state) · 27 unmodified lines | ||
| 410 | 412 | unsigned int i; |
| 411 | 413 | |
| 412 | 414 | hvs_state = vc4_hvs_get_new_global_state(state); |
| 413 | − if (!hvs_state) | |
| 414 | − return -EINVAL; | |
| 415 | + if (WARN_ON(IS_ERR(hvs_state))) | |
| 416 | + return PTR_ERR(hvs_state); | |
| 415 | 417 | |
| 416 | 418 | for_each_new_crtc_in_state(state, crtc, crtc_state, i) { |
| 417 | 419 | struct vc4_crtc_state *vc4_crtc_state = |
| @@ -668,12 +670,6 @@ vc4_hvs_channels_duplicate_state(struct drm_private_obj *obj) · 250 unmodified lines | ||
| 668 | 670 | |
| 669 | 671 | for (i = 0; i < HVS_NUM_CHANNELS; i++) { |
| 670 | 672 | state->fifo_state[i].in_use = old_state->fifo_state[i].in_use; |
| 671 | − | |
| 672 | − if (!old_state->fifo_state[i].pending_commit) | |
| 673 | − continue; | |
| 674 | − | |
| 675 | − state->fifo_state[i].pending_commit = | |
| 676 | − drm_crtc_commit_get(old_state->fifo_state[i].pending_commit); | |
| 677 | 673 | } |
| 678 | 674 | |
| 679 | 675 | return &state->base; |
| @@ -762,8 +758,8 @@ static int vc4_pv_muxing_atomic_check(struct drm_device *dev, · 82 unmodified lines | ||
| 762 | 758 | unsigned int i; |
| 763 | 759 | |
| 764 | 760 | hvs_new_state = vc4_hvs_get_global_state(state); |
| 765 | − if (!hvs_new_state) | |
| 766 | − return -EINVAL; | |
| 761 | + if (IS_ERR(hvs_new_state)) | |
| 762 | + return PTR_ERR(hvs_new_state); | |
| 767 | 763 | |
| 768 | 764 | for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++) |
| 769 | 765 | if (!hvs_new_state->fifo_state[i].in_use) |
| @@ -157,36 +157,6 @@ static void virtio_gpu_config_changed(struct virtio_device *vdev) · 156 unmodified lines | ||
| 157 | 157 | schedule_work(&vgdev->config_changed_work); |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | −static __poll_t virtio_gpu_poll(struct file *filp, | |
| 161 | − struct poll_table_struct *wait) | |
| 162 | −{ | |
| 163 | − struct drm_file *drm_file = filp->private_data; | |
| 164 | − struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv; | |
| 165 | − struct drm_device *dev = drm_file->minor->dev; | |
| 166 | − struct virtio_gpu_device *vgdev = dev->dev_private; | |
| 167 | − struct drm_pending_event *e = NULL; | |
| 168 | − __poll_t mask = 0; | |
| 169 | − | |
| 170 | − if (!vgdev->has_virgl_3d || !vfpriv || !vfpriv->ring_idx_mask) | |
| 171 | − return drm_poll(filp, wait); | |
| 172 | − | |
| 173 | − poll_wait(filp, &drm_file->event_wait, wait); | |
| 174 | − | |
| 175 | − if (!list_empty(&drm_file->event_list)) { | |
| 176 | − spin_lock_irq(&dev->event_lock); | |
| 177 | − e = list_first_entry(&drm_file->event_list, | |
| 178 | − struct drm_pending_event, link); | |
| 179 | − drm_file->event_space += e->event->length; | |
| 180 | − list_del(&e->link); | |
| 181 | − spin_unlock_irq(&dev->event_lock); | |
| 182 | − | |
| 183 | − kfree(e); | |
| 184 | − mask |= EPOLLIN | EPOLLRDNORM; | |
| 185 | − } | |
| 186 | − | |
| 187 | − return mask; | |
| 188 | −} | |
| 189 | − | |
| 190 | 160 | static struct virtio_device_id id_table[] = { |
| 191 | 161 | { VIRTIO_ID_GPU, VIRTIO_DEV_ANY_ID }, |
| 192 | 162 | { 0 }, |
| @@ -226,17 +196,7 @@ MODULE_AUTHOR("Dave Airlie <airlied@redhat.com>"); · 33 unmodified lines | ||
| 226 | 196 | MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>"); |
| 227 | 197 | MODULE_AUTHOR("Alon Levy"); |
| 228 | 198 | |
| 229 | −static const struct file_operations virtio_gpu_driver_fops = { | |
| 230 | − .owner = THIS_MODULE, | |
| 231 | − .open = drm_open, | |
| 232 | − .release = drm_release, | |
| 233 | − .unlocked_ioctl = drm_ioctl, | |
| 234 | − .compat_ioctl = drm_compat_ioctl, | |
| 235 | − .poll = virtio_gpu_poll, | |
| 236 | − .read = drm_read, | |
| 237 | − .llseek = noop_llseek, | |
| 238 | − .mmap = drm_gem_mmap | |
| 239 | −}; | |
| 199 | +DEFINE_DRM_GEM_FOPS(virtio_gpu_driver_fops); | |
| 240 | 200 | |
| 241 | 201 | static const struct drm_driver driver = { |
| 242 | 202 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC, |
| @@ -138,7 +138,6 @@ struct virtio_gpu_fence_driver { · 137 unmodified lines | ||
| 138 | 138 | spinlock_t lock; |
| 139 | 139 | }; |
| 140 | 140 | |
| 141 | −#define VIRTGPU_EVENT_FENCE_SIGNALED_INTERNAL 0x10000000 | |
| 142 | 141 | struct virtio_gpu_fence_event { |
| 143 | 142 | struct drm_pending_event base; |
| 144 | 143 | struct drm_event event; |
| @@ -54,7 +54,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev, · 53 unmodified lines | ||
| 54 | 54 | if (!e) |
| 55 | 55 | return -ENOMEM; |
| 56 | 56 | |
| 57 | − e->event.type = VIRTGPU_EVENT_FENCE_SIGNALED_INTERNAL; | |
| 57 | + e->event.type = VIRTGPU_EVENT_FENCE_SIGNALED; | |
| 58 | 58 | e->event.length = sizeof(e->event); |
| 59 | 59 | |
| 60 | 60 | ret = drm_event_reserve_init(dev, file, &e->base, &e->event); |
| @@ -773,6 +773,7 @@ static struct xenbus_driver xen_driver = { · 772 unmodified lines | ||
| 773 | 773 | .probe = xen_drv_probe, |
| 774 | 774 | .remove = xen_drv_remove, |
| 775 | 775 | .otherend_changed = displback_changed, |
| 776 | + .not_essential = true, | |
| 776 | 777 | }; |
| 777 | 778 | |
| 778 | 779 | static int __init xen_drv_init(void) |
| @@ -207,14 +207,14 @@ config HID_CHERRY · 206 unmodified lines | ||
| 207 | 207 | |
| 208 | 208 | config HID_CHICONY |
| 209 | 209 | tristate "Chicony devices" |
| 210 | − depends on HID | |
| 210 | + depends on USB_HID | |
| 211 | 211 | default !EXPERT |
| 212 | 212 | help |
| 213 | 213 | Support for Chicony Tactical pad and special keys on Chicony keyboards. |
| 214 | 214 | |
| 215 | 215 | config HID_CORSAIR |
| 216 | 216 | tristate "Corsair devices" |
| 217 | − depends on HID && USB && LEDS_CLASS | |
| 217 | + depends on USB_HID && LEDS_CLASS | |
| 218 | 218 | help |
| 219 | 219 | Support for Corsair devices that are not fully compliant with the |
| 220 | 220 | HID standard. |
| @@ -245,7 +245,7 @@ config HID_MACALLY · 24 unmodified lines | ||
| 245 | 245 | |
| 246 | 246 | config HID_PRODIKEYS |
| 247 | 247 | tristate "Prodikeys PC-MIDI Keyboard support" |
| 248 | − depends on HID && SND | |
| 248 | + depends on USB_HID && SND | |
| 249 | 249 | select SND_RAWMIDI |
| 250 | 250 | help |
| 251 | 251 | Support for Prodikeys PC-MIDI Keyboard device support. |
| @@ -560,7 +560,7 @@ config HID_LENOVO · 308 unmodified lines | ||
| 560 | 560 | |
| 561 | 561 | config HID_LOGITECH |
| 562 | 562 | tristate "Logitech devices" |
| 563 | − depends on HID | |
| 563 | + depends on USB_HID | |
| 564 | 564 | depends on LEDS_CLASS |
| 565 | 565 | default !EXPERT |
| 566 | 566 | help |
| @@ -951,7 +951,7 @@ config HID_SAITEK · 384 unmodified lines | ||
| 951 | 951 | |
| 952 | 952 | config HID_SAMSUNG |
| 953 | 953 | tristate "Samsung InfraRed remote control or keyboards" |
| 954 | − depends on HID | |
| 954 | + depends on USB_HID | |
| 955 | 955 | help |
| 956 | 956 | Support for Samsung InfraRed remote control or keyboards. |
| 957 | 957 | |
| @@ -854,7 +854,7 @@ static int asus_input_mapping(struct hid_device *hdev, · 853 unmodified lines | ||
| 854 | 854 | switch (usage->hid & HID_USAGE) { |
| 855 | 855 | case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break; |
| 856 | 856 | case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break; |
| 857 | − case 0x35: asus_map_key_clear(KEY_SCREENLOCK); break; | |
| 857 | + case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF); break; | |
| 858 | 858 | case 0x6c: asus_map_key_clear(KEY_SLEEP); break; |
| 859 | 859 | case 0x7c: asus_map_key_clear(KEY_MICMUTE); break; |
| 860 | 860 | case 0x82: asus_map_key_clear(KEY_CAMERA); break; |
| @@ -1028,8 +1028,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) · 167 unmodified lines | ||
| 1028 | 1028 | if (drvdata->quirks & QUIRK_IS_MULTITOUCH) |
| 1029 | 1029 | drvdata->tp = &asus_i2c_tp; |
| 1030 | 1030 | |
| 1031 | − if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && | |
| 1032 | − hid_is_using_ll_driver(hdev, &usb_hid_driver)) { | |
| 1031 | + if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) { | |
| 1033 | 1032 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
| 1034 | 1033 | |
| 1035 | 1034 | if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) { |
| @@ -1057,8 +1056,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) · 21 unmodified lines | ||
| 1057 | 1056 | drvdata->tp = &asus_t100chi_tp; |
| 1058 | 1057 | } |
| 1059 | 1058 | |
| 1060 | − if ((drvdata->quirks & QUIRK_MEDION_E1239T) && | |
| 1061 | − hid_is_using_ll_driver(hdev, &usb_hid_driver)) { | |
| 1059 | + if ((drvdata->quirks & QUIRK_MEDION_E1239T) && hid_is_usb(hdev)) { | |
| 1062 | 1060 | struct usb_host_interface *alt = |
| 1063 | 1061 | to_usb_interface(hdev->dev.parent)->altsetting; |
| 1064 | 1062 | |
| @@ -191,7 +191,7 @@ static void bigben_worker(struct work_struct *work) · 190 unmodified lines | ||
| 191 | 191 | struct bigben_device, worker); |
| 192 | 192 | struct hid_field *report_field = bigben->report->field[0]; |
| 193 | 193 | |
| 194 | − if (bigben->removed) | |
| 194 | + if (bigben->removed || !report_field) | |
| 195 | 195 | return; |
| 196 | 196 | |
| 197 | 197 | if (bigben->work_led) { |
| @@ -114,6 +114,9 @@ static int ch_probe(struct hid_device *hdev, const struct hid_device_id *id) · 113 unmodified lines | ||
| 114 | 114 | { |
| 115 | 115 | int ret; |
| 116 | 116 | |
| 117 | + if (!hid_is_usb(hdev)) | |
| 118 | + return -EINVAL; | |
| 119 | + | |
| 117 | 120 | hdev->quirks |= HID_QUIRK_INPUT_PER_APP; |
| 118 | 121 | ret = hid_parse(hdev); |
| 119 | 122 | if (ret) { |
| @@ -553,7 +553,12 @@ static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id) · 552 unmodified lines | ||
| 553 | 553 | int ret; |
| 554 | 554 | unsigned long quirks = id->driver_data; |
| 555 | 555 | struct corsair_drvdata *drvdata; |
| 556 | − struct usb_interface *usbif = to_usb_interface(dev->dev.parent); | |
| 556 | + struct usb_interface *usbif; | |
| 557 | + | |
| 558 | + if (!hid_is_usb(dev)) | |
| 559 | + return -EINVAL; | |
| 560 | + | |
| 561 | + usbif = to_usb_interface(dev->dev.parent); | |
| 557 | 562 | |
| 558 | 563 | drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata), |
| 559 | 564 | GFP_KERNEL); |
| @@ -50,7 +50,7 @@ struct elan_drvdata { · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | static int is_not_elan_touchpad(struct hid_device *hdev) |
| 52 | 52 | { |
| 53 | − if (hdev->bus == BUS_USB) { | |
| 53 | + if (hid_is_usb(hdev)) { | |
| 54 | 54 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
| 55 | 55 | |
| 56 | 56 | return (intf->altsetting->desc.bInterfaceNumber != |
| @@ -230,6 +230,9 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) · 229 unmodified lines | ||
| 230 | 230 | int ret; |
| 231 | 231 | struct usb_device *udev; |
| 232 | 232 | |
| 233 | + if (!hid_is_usb(hdev)) | |
| 234 | + return -EINVAL; | |
| 235 | + | |
| 233 | 236 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 234 | 237 | if (!priv) |
| 235 | 238 | return -ENOMEM; |
| @@ -915,6 +915,9 @@ static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id) · 914 unmodified lines | ||
| 915 | 915 | struct ft260_get_chip_version_report version; |
| 916 | 916 | int ret; |
| 917 | 917 | |
| 918 | + if (!hid_is_usb(hdev)) | |
| 919 | + return -EINVAL; | |
| 920 | + | |
| 918 | 921 | dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); |
| 919 | 922 | if (!dev) |
| 920 | 923 | return -ENOMEM; |
| @@ -966,24 +969,23 @@ static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id) · 45 unmodified lines | ||
| 966 | 969 | mutex_init(&dev->lock); |
| 967 | 970 | init_completion(&dev->wait); |
| 968 | 971 | |
| 972 | + ret = ft260_xfer_status(dev); | |
| 973 | + if (ret) | |
| 974 | + ft260_i2c_reset(hdev); | |
| 975 | + | |
| 976 | + i2c_set_adapdata(&dev->adap, dev); | |
| 969 | 977 | ret = i2c_add_adapter(&dev->adap); |
| 970 | 978 | if (ret) { |
| 971 | 979 | hid_err(hdev, "failed to add i2c adapter\n"); |
| 972 | 980 | goto err_hid_close; |
| 973 | 981 | } |
| 974 | 982 | |
| 975 | − i2c_set_adapdata(&dev->adap, dev); | |
| 976 | − | |
| 977 | 983 | ret = sysfs_create_group(&hdev->dev.kobj, &ft260_attr_group); |
| 978 | 984 | if (ret < 0) { |
| 979 | 985 | hid_err(hdev, "failed to create sysfs attrs\n"); |
| 980 | 986 | goto err_i2c_free; |
| 981 | 987 | } |
| 982 | 988 | |
| 983 | − ret = ft260_xfer_status(dev); | |
| 984 | − if (ret) | |
| 985 | − ft260_i2c_reset(hdev); | |
| 986 | − | |
| 987 | 989 | return 0; |
| 988 | 990 | |
| 989 | 991 | err_i2c_free: |
| @@ -585,6 +585,8 @@ static void hammer_remove(struct hid_device *hdev) · 584 unmodified lines | ||
| 585 | 585 | static const struct hid_device_id hammer_devices[] = { |
| 586 | 586 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 587 | 587 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) }, |
| 588 | + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | |
| 589 | + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) }, | |
| 588 | 590 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 589 | 591 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, |
| 590 | 592 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| @@ -140,12 +140,17 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type, · 139 unmodified lines | ||
| 140 | 140 | static int holtek_kbd_probe(struct hid_device *hdev, |
| 141 | 141 | const struct hid_device_id *id) |
| 142 | 142 | { |
| 143 | − struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | |
| 144 | − int ret = hid_parse(hdev); | |
| 143 | + struct usb_interface *intf; | |
| 144 | + int ret; | |
| 145 | + | |
| 146 | + if (!hid_is_usb(hdev)) | |
| 147 | + return -EINVAL; | |
| 145 | 148 | |
| 149 | + ret = hid_parse(hdev); | |
| 146 | 150 | if (!ret) |
| 147 | 151 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
| 148 | 152 | |
| 153 | + intf = to_usb_interface(hdev->dev.parent); | |
| 149 | 154 | if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) { |
| 150 | 155 | struct hid_input *hidinput; |
| 151 | 156 | list_for_each_entry(hidinput, &hdev->inputs, list) { |
| @@ -62,6 +62,14 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, · 61 unmodified lines | ||
| 62 | 62 | return rdesc; |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | +static int holtek_mouse_probe(struct hid_device *hdev, | |
| 66 | + const struct hid_device_id *id) | |
| 67 | +{ | |
| 68 | + if (!hid_is_usb(hdev)) | |
| 69 | + return -EINVAL; | |
| 70 | + return 0; | |
| 71 | +} | |
| 72 | + | |
| 65 | 73 | static const struct hid_device_id holtek_mouse_devices[] = { |
| 66 | 74 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, |
| 67 | 75 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, |
| @@ -83,6 +91,7 @@ static struct hid_driver holtek_mouse_driver = { · 15 unmodified lines | ||
| 83 | 91 | .name = "holtek_mouse", |
| 84 | 92 | .id_table = holtek_mouse_devices, |
| 85 | 93 | .report_fixup = holtek_mouse_report_fixup, |
| 94 | + .probe = holtek_mouse_probe, | |
| 86 | 95 | }; |
| 87 | 96 | |
| 88 | 97 | module_hid_driver(holtek_mouse_driver); |
| @@ -397,7 +397,9 @@ · 396 unmodified lines | ||
| 397 | 397 | #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 |
| 398 | 398 | #define USB_DEVICE_ID_HP_X2 0x074d |
| 399 | 399 | #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 |
| 400 | +#define I2C_DEVICE_ID_HP_ENVY_X360_15 0x2d05 | |
| 400 | 401 | #define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817 |
| 402 | +#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544 | |
| 401 | 403 | #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 |
| 402 | 404 | #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A |
| 403 | 405 | |
| @@ -500,6 +502,7 @@ · 96 unmodified lines | ||
| 500 | 502 | #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d |
| 501 | 503 | #define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 |
| 502 | 504 | #define USB_DEVICE_ID_GOOGLE_DON 0x5050 |
| 505 | +#define USB_DEVICE_ID_GOOGLE_EEL 0x5057 | |
| 503 | 506 | |
| 504 | 507 | #define USB_VENDOR_ID_GOTOP 0x08f2 |
| 505 | 508 | #define USB_DEVICE_ID_SUPER_Q2 0x007f |
| @@ -885,6 +888,7 @@ · 379 unmodified lines | ||
| 885 | 888 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 |
| 886 | 889 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 |
| 887 | 890 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da |
| 891 | +#define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de | |
| 888 | 892 | #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd |
| 889 | 893 | #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb |
| 890 | 894 | #define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0 |
| @@ -160,6 +160,7 @@ static int hidinput_setkeycode(struct input_dev *dev, · 159 unmodified lines | ||
| 160 | 160 | if (usage) { |
| 161 | 161 | *old_keycode = usage->type == EV_KEY ? |
| 162 | 162 | usage->code : KEY_RESERVED; |
| 163 | + usage->type = EV_KEY; | |
| 163 | 164 | usage->code = ke->keycode; |
| 164 | 165 | |
| 165 | 166 | clear_bit(*old_keycode, dev->keybit); |
| @@ -324,6 +325,10 @@ static const struct hid_device_id hid_battery_quirks[] = { · 158 unmodified lines | ||
| 324 | 325 | HID_BATTERY_QUIRK_IGNORE }, |
| 325 | 326 | { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), |
| 326 | 327 | HID_BATTERY_QUIRK_IGNORE }, |
| 328 | + { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN), | |
| 329 | + HID_BATTERY_QUIRK_IGNORE }, | |
| 330 | + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15), | |
| 331 | + HID_BATTERY_QUIRK_IGNORE }, | |
| 327 | 332 | { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15), |
| 328 | 333 | HID_BATTERY_QUIRK_IGNORE }, |
| 329 | 334 | { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN), |
| @@ -650,10 +655,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel · 320 unmodified lines | ||
| 650 | 655 | code += KEY_MACRO1; |
| 651 | 656 | else |
| 652 | 657 | code += BTN_TRIGGER_HAPPY - 0x1e; |
| 653 | − } else { | |
| 654 | − goto ignore; | |
| 658 | + break; | |
| 655 | 659 | } |
| 656 | − break; | |
| 660 | + fallthrough; | |
| 657 | 661 | default: |
| 658 | 662 | switch (field->physical) { |
| 659 | 663 | case HID_GD_MOUSE: |
| @@ -749,12 +749,18 @@ static int lg_raw_event(struct hid_device *hdev, struct hid_report *report, · 748 unmodified lines | ||
| 749 | 749 | |
| 750 | 750 | static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| 751 | 751 | { |
| 752 | − struct usb_interface *iface = to_usb_interface(hdev->dev.parent); | |
| 753 | − __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; | |
| 752 | + struct usb_interface *iface; | |
| 753 | + __u8 iface_num; | |
| 754 | 754 | unsigned int connect_mask = HID_CONNECT_DEFAULT; |
| 755 | 755 | struct lg_drv_data *drv_data; |
| 756 | 756 | int ret; |
| 757 | 757 | |
| 758 | + if (!hid_is_usb(hdev)) | |
| 759 | + return -EINVAL; | |
| 760 | + | |
| 761 | + iface = to_usb_interface(hdev->dev.parent); | |
| 762 | + iface_num = iface->cur_altsetting->desc.bInterfaceNumber; | |
| 763 | + | |
| 758 | 764 | /* G29 only work with the 1st interface */ |
| 759 | 765 | if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && |
| 760 | 766 | (iface_num != 0)) { |
| @@ -1777,7 +1777,7 @@ static int logi_dj_probe(struct hid_device *hdev, · 1776 unmodified lines | ||
| 1777 | 1777 | case recvr_type_bluetooth: no_dj_interfaces = 2; break; |
| 1778 | 1778 | case recvr_type_dinovo: no_dj_interfaces = 2; break; |
| 1779 | 1779 | } |
| 1780 | − if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) { | |
| 1780 | + if (hid_is_usb(hdev)) { | |
| 1781 | 1781 | intf = to_usb_interface(hdev->dev.parent); |
| 1782 | 1782 | if (intf && intf->altsetting->desc.bInterfaceNumber >= |
| 1783 | 1783 | no_dj_interfaces) { |
| @@ -256,8 +256,11 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda · 255 unmodified lines | ||
| 256 | 256 | unsigned long now = jiffies; |
| 257 | 257 | int step_x = msc->touches[id].scroll_x - x; |
| 258 | 258 | int step_y = msc->touches[id].scroll_y - y; |
| 259 | − int step_hr = ((64 - (int)scroll_speed) * msc->scroll_accel) / | |
| 260 | − SCROLL_HR_STEPS; | |
| 259 | + int step_hr = | |
| 260 | + max_t(int, | |
| 261 | + ((64 - (int)scroll_speed) * msc->scroll_accel) / | |
| 262 | + SCROLL_HR_STEPS, | |
| 263 | + 1); | |
| 261 | 264 | int step_x_hr = msc->touches[id].scroll_x_hr - x; |
| 262 | 265 | int step_y_hr = msc->touches[id].scroll_y_hr - y; |
| 263 | 266 | |
| @@ -1888,6 +1888,11 @@ static const struct hid_device_id mt_devices[] = { · 1887 unmodified lines | ||
| 1888 | 1888 | MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, |
| 1889 | 1889 | USB_DEVICE_ID_CVTOUCH_SCREEN) }, |
| 1890 | 1890 | |
| 1891 | + /* eGalax devices (SAW) */ | |
| 1892 | + { .driver_data = MT_CLS_EXPORT_ALL_INPUTS, | |
| 1893 | + MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | |
| 1894 | + USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER) }, | |
| 1895 | + | |
| 1891 | 1896 | /* eGalax devices (resistive) */ |
| 1892 | 1897 | { .driver_data = MT_CLS_EGALAX, |
| 1893 | 1898 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| @@ -189,6 +189,7 @@ struct joycon_rumble_amp_data { · 188 unmodified lines | ||
| 189 | 189 | u16 amp; |
| 190 | 190 | }; |
| 191 | 191 | |
| 192 | +#if IS_ENABLED(CONFIG_NINTENDO_FF) | |
| 192 | 193 | /* |
| 193 | 194 | * These tables are from |
| 194 | 195 | * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md |
| @@ -289,6 +290,10 @@ static const struct joycon_rumble_amp_data joycon_rumble_amplitudes[] = { · 94 unmodified lines | ||
| 289 | 290 | { 0xc2, 0x8070, 940 }, { 0xc4, 0x0071, 960 }, { 0xc6, 0x8071, 981 }, |
| 290 | 291 | { 0xc8, 0x0072, joycon_max_rumble_amp } |
| 291 | 292 | }; |
| 293 | +static const u16 JC_RUMBLE_DFLT_LOW_FREQ = 160; | |
| 294 | +static const u16 JC_RUMBLE_DFLT_HIGH_FREQ = 320; | |
| 295 | +#endif /* IS_ENABLED(CONFIG_NINTENDO_FF) */ | |
| 296 | +static const u16 JC_RUMBLE_PERIOD_MS = 50; | |
| 292 | 297 | |
| 293 | 298 | /* States for controller state machine */ |
| 294 | 299 | enum joycon_ctlr_state { |
| @@ -397,9 +402,6 @@ struct joycon_input_report { · 102 unmodified lines | ||
| 397 | 402 | #define JC_RUMBLE_DATA_SIZE 8 |
| 398 | 403 | #define JC_RUMBLE_QUEUE_SIZE 8 |
| 399 | 404 | |
| 400 | −static const u16 JC_RUMBLE_DFLT_LOW_FREQ = 160; | |
| 401 | −static const u16 JC_RUMBLE_DFLT_HIGH_FREQ = 320; | |
| 402 | −static const u16 JC_RUMBLE_PERIOD_MS = 50; | |
| 403 | 405 | static const unsigned short JC_RUMBLE_ZERO_AMP_PKT_CNT = 5; |
| 404 | 406 | |
| 405 | 407 | static const char * const joycon_player_led_names[] = { |
| @@ -1850,8 +1852,10 @@ static int joycon_leds_create(struct joycon_ctlr *ctlr) · 1444 unmodified lines | ||
| 1850 | 1852 | d_name, |
| 1851 | 1853 | "green", |
| 1852 | 1854 | joycon_player_led_names[i]); |
| 1853 | − if (!name) | |
| 1855 | + if (!name) { | |
| 1856 | + mutex_unlock(&joycon_input_num_mutex); | |
| 1854 | 1857 | return -ENOMEM; |
| 1858 | + } | |
| 1855 | 1859 | |
| 1856 | 1860 | led = &ctlr->leds[i]; |
| 1857 | 1861 | led->name = name; |
| @@ -1864,6 +1868,7 @@ static int joycon_leds_create(struct joycon_ctlr *ctlr) · 6 unmodified lines | ||
| 1864 | 1868 | ret = devm_led_classdev_register(&hdev->dev, led); |
| 1865 | 1869 | if (ret) { |
| 1866 | 1870 | hid_err(hdev, "Failed registering %s LED\n", led->name); |
| 1871 | + mutex_unlock(&joycon_input_num_mutex); | |
| 1867 | 1872 | return ret; |
| 1868 | 1873 | } |
| 1869 | 1874 | } |
| @@ -798,12 +798,18 @@ static int pk_raw_event(struct hid_device *hdev, struct hid_report *report, · 797 unmodified lines | ||
| 798 | 798 | static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| 799 | 799 | { |
| 800 | 800 | int ret; |
| 801 | − struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | |
| 802 | − unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | |
| 801 | + struct usb_interface *intf; | |
| 802 | + unsigned short ifnum; | |
| 803 | 803 | unsigned long quirks = id->driver_data; |
| 804 | 804 | struct pk_device *pk; |
| 805 | 805 | struct pcmidi_snd *pm = NULL; |
| 806 | 806 | |
| 807 | + if (!hid_is_usb(hdev)) | |
| 808 | + return -EINVAL; | |
| 809 | + | |
| 810 | + intf = to_usb_interface(hdev->dev.parent); | |
| 811 | + ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | |
| 812 | + | |
| 807 | 813 | pk = kzalloc(sizeof(*pk), GFP_KERNEL); |
| 808 | 814 | if (pk == NULL) { |
| 809 | 815 | hid_err(hdev, "can't alloc descriptor\n"); |
| @@ -124,6 +124,7 @@ static const struct hid_device_id hid_quirks[] = { · 123 unmodified lines | ||
| 124 | 124 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, |
| 125 | 125 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL }, |
| 126 | 126 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, |
| 127 | + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER), HID_QUIRK_NO_INIT_REPORTS }, | |
| 127 | 128 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, |
| 128 | 129 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, |
| 129 | 130 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, |
| @@ -344,6 +344,9 @@ static int arvo_probe(struct hid_device *hdev, · 343 unmodified lines | ||
| 344 | 344 | { |
| 345 | 345 | int retval; |
| 346 | 346 | |
| 347 | + if (!hid_is_usb(hdev)) | |
| 348 | + return -EINVAL; | |
| 349 | + | |
| 347 | 350 | retval = hid_parse(hdev); |
| 348 | 351 | if (retval) { |
| 349 | 352 | hid_err(hdev, "parse failed\n"); |
| @@ -324,6 +324,9 @@ static int isku_probe(struct hid_device *hdev, · 323 unmodified lines | ||
| 324 | 324 | { |
| 325 | 325 | int retval; |
| 326 | 326 | |
| 327 | + if (!hid_is_usb(hdev)) | |
| 328 | + return -EINVAL; | |
| 329 | + | |
| 327 | 330 | retval = hid_parse(hdev); |
| 328 | 331 | if (retval) { |
| 329 | 332 | hid_err(hdev, "parse failed\n"); |
| @@ -749,6 +749,9 @@ static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id) · 748 unmodified lines | ||
| 749 | 749 | { |
| 750 | 750 | int retval; |
| 751 | 751 | |
| 752 | + if (!hid_is_usb(hdev)) | |
| 753 | + return -EINVAL; | |
| 754 | + | |
| 752 | 755 | retval = hid_parse(hdev); |
| 753 | 756 | if (retval) { |
| 754 | 757 | hid_err(hdev, "parse failed\n"); |
| @@ -431,6 +431,9 @@ static int koneplus_probe(struct hid_device *hdev, · 430 unmodified lines | ||
| 431 | 431 | { |
| 432 | 432 | int retval; |
| 433 | 433 | |
| 434 | + if (!hid_is_usb(hdev)) | |
| 435 | + return -EINVAL; | |
| 436 | + | |
| 434 | 437 | retval = hid_parse(hdev); |
| 435 | 438 | if (retval) { |
| 436 | 439 | hid_err(hdev, "parse failed\n"); |
| @@ -133,6 +133,9 @@ static int konepure_probe(struct hid_device *hdev, · 132 unmodified lines | ||
| 133 | 133 | { |
| 134 | 134 | int retval; |
| 135 | 135 | |
| 136 | + if (!hid_is_usb(hdev)) | |
| 137 | + return -EINVAL; | |
| 138 | + | |
| 136 | 139 | retval = hid_parse(hdev); |
| 137 | 140 | if (retval) { |
| 138 | 141 | hid_err(hdev, "parse failed\n"); |
| @@ -501,6 +501,9 @@ static int kovaplus_probe(struct hid_device *hdev, · 500 unmodified lines | ||
| 501 | 501 | { |
| 502 | 502 | int retval; |
| 503 | 503 | |
| 504 | + if (!hid_is_usb(hdev)) | |
| 505 | + return -EINVAL; | |
| 506 | + | |
| 504 | 507 | retval = hid_parse(hdev); |
| 505 | 508 | if (retval) { |
| 506 | 509 | hid_err(hdev, "parse failed\n"); |
| @@ -160,6 +160,9 @@ static int lua_probe(struct hid_device *hdev, · 159 unmodified lines | ||
| 160 | 160 | { |
| 161 | 161 | int retval; |
| 162 | 162 | |
| 163 | + if (!hid_is_usb(hdev)) | |
| 164 | + return -EINVAL; | |
| 165 | + | |
| 163 | 166 | retval = hid_parse(hdev); |
| 164 | 167 | if (retval) { |
| 165 | 168 | hid_err(hdev, "parse failed\n"); |
| @@ -449,6 +449,9 @@ static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) · 448 unmodified lines | ||
| 449 | 449 | { |
| 450 | 450 | int retval; |
| 451 | 451 | |
| 452 | + if (!hid_is_usb(hdev)) | |
| 453 | + return -EINVAL; | |
| 454 | + | |
| 452 | 455 | retval = hid_parse(hdev); |
| 453 | 456 | if (retval) { |
| 454 | 457 | hid_err(hdev, "parse failed\n"); |
| @@ -141,6 +141,9 @@ static int ryos_probe(struct hid_device *hdev, · 140 unmodified lines | ||
| 141 | 141 | { |
| 142 | 142 | int retval; |
| 143 | 143 | |
| 144 | + if (!hid_is_usb(hdev)) | |
| 145 | + return -EINVAL; | |
| 146 | + | |
| 144 | 147 | retval = hid_parse(hdev); |
| 145 | 148 | if (retval) { |
| 146 | 149 | hid_err(hdev, "parse failed\n"); |
| @@ -113,6 +113,9 @@ static int savu_probe(struct hid_device *hdev, · 112 unmodified lines | ||
| 113 | 113 | { |
| 114 | 114 | int retval; |
| 115 | 115 | |
| 116 | + if (!hid_is_usb(hdev)) | |
| 117 | + return -EINVAL; | |
| 118 | + | |
| 116 | 119 | retval = hid_parse(hdev); |
| 117 | 120 | if (retval) { |
| 118 | 121 | hid_err(hdev, "parse failed\n"); |
| @@ -152,6 +152,9 @@ static int samsung_probe(struct hid_device *hdev, · 151 unmodified lines | ||
| 152 | 152 | int ret; |
| 153 | 153 | unsigned int cmask = HID_CONNECT_DEFAULT; |
| 154 | 154 | |
| 155 | + if (!hid_is_usb(hdev)) | |
| 156 | + return -EINVAL; | |
| 157 | + | |
| 155 | 158 | ret = hid_parse(hdev); |
| 156 | 159 | if (ret) { |
| 157 | 160 | hid_err(hdev, "parse failed\n"); |
| @@ -3000,7 +3000,6 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) · 2999 unmodified lines | ||
| 3000 | 3000 | sc->quirks = quirks; |
| 3001 | 3001 | hid_set_drvdata(hdev, sc); |
| 3002 | 3002 | sc->hdev = hdev; |
| 3003 | − usbdev = to_usb_device(sc->hdev->dev.parent->parent); | |
| 3004 | 3003 | |
| 3005 | 3004 | ret = hid_parse(hdev); |
| 3006 | 3005 | if (ret) { |
| @@ -3038,14 +3037,23 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) · 31 unmodified lines | ||
| 3038 | 3037 | */ |
| 3039 | 3038 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) { |
| 3040 | 3039 | hid_err(hdev, "failed to claim input\n"); |
| 3041 | − hid_hw_stop(hdev); | |
| 3042 | − return -ENODEV; | |
| 3040 | + ret = -ENODEV; | |
| 3041 | + goto err; | |
| 3043 | 3042 | } |
| 3044 | 3043 | |
| 3045 | 3044 | if (sc->quirks & (GHL_GUITAR_PS3WIIU | GHL_GUITAR_PS4)) { |
| 3045 | + if (!hid_is_usb(hdev)) { | |
| 3046 | + ret = -EINVAL; | |
| 3047 | + goto err; | |
| 3048 | + } | |
| 3049 | + | |
| 3050 | + usbdev = to_usb_device(sc->hdev->dev.parent->parent); | |
| 3051 | + | |
| 3046 | 3052 | sc->ghl_urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 3047 | − if (!sc->ghl_urb) | |
| 3048 | − return -ENOMEM; | |
| 3053 | + if (!sc->ghl_urb) { | |
| 3054 | + ret = -ENOMEM; | |
| 3055 | + goto err; | |
| 3056 | + } | |
| 3049 | 3057 | |
| 3050 | 3058 | if (sc->quirks & GHL_GUITAR_PS3WIIU) |
| 3051 | 3059 | ret = ghl_init_urb(sc, usbdev, ghl_ps3wiiu_magic_data, |
| @@ -3055,7 +3063,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) · 3 unmodified lines | ||
| 3055 | 3063 | ARRAY_SIZE(ghl_ps4_magic_data)); |
| 3056 | 3064 | if (ret) { |
| 3057 | 3065 | hid_err(hdev, "error preparing URB\n"); |
| 3058 | − return ret; | |
| 3066 | + goto err; | |
| 3059 | 3067 | } |
| 3060 | 3068 | |
| 3061 | 3069 | timer_setup(&sc->ghl_poke_timer, ghl_magic_poke, 0); |
| @@ -3064,6 +3072,10 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) · 2 unmodified lines | ||
| 3064 | 3072 | } |
| 3065 | 3073 | |
| 3066 | 3074 | return ret; |
| 3075 | + | |
| 3076 | +err: | |
| 3077 | + hid_hw_stop(hdev); | |
| 3078 | + return ret; | |
| 3067 | 3079 | } |
| 3068 | 3080 | |
| 3069 | 3081 | static void sony_remove(struct hid_device *hdev) |
| @@ -205,7 +205,7 @@ static void thrustmaster_model_handler(struct urb *urb) · 204 unmodified lines | ||
| 205 | 205 | struct tm_wheel *tm_wheel = hid_get_drvdata(hdev); |
| 206 | 206 | uint16_t model = 0; |
| 207 | 207 | int i, ret; |
| 208 | − const struct tm_wheel_info *twi = 0; | |
| 208 | + const struct tm_wheel_info *twi = NULL; | |
| 209 | 209 | |
| 210 | 210 | if (urb->status) { |
| 211 | 211 | hid_err(hdev, "URB to get model id failed with error %d\n", urb->status); |
| @@ -238,7 +238,7 @@ static void thrustmaster_model_handler(struct urb *urb) · 26 unmodified lines | ||
| 238 | 238 | tm_wheel->usb_dev, |
| 239 | 239 | usb_sndctrlpipe(tm_wheel->usb_dev, 0), |
| 240 | 240 | (char *)tm_wheel->change_request, |
| 241 | − 0, 0, // We do not expect any response from the wheel | |
| 241 | + NULL, 0, // We do not expect any response from the wheel | |
| 242 | 242 | thrustmaster_change_handler, |
| 243 | 243 | hdev |
| 244 | 244 | ); |
| @@ -272,7 +272,10 @@ static void thrustmaster_remove(struct hid_device *hdev) · 27 unmodified lines | ||
| 272 | 272 | static int thrustmaster_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| 273 | 273 | { |
| 274 | 274 | int ret = 0; |
| 275 | − struct tm_wheel *tm_wheel = 0; | |
| 275 | + struct tm_wheel *tm_wheel = NULL; | |
| 276 | + | |
| 277 | + if (!hid_is_usb(hdev)) | |
| 278 | + return -EINVAL; | |
| 276 | 279 | |
| 277 | 280 | ret = hid_parse(hdev); |
| 278 | 281 | if (ret) { |
| @@ -311,7 +311,7 @@ static int u2fzero_probe(struct hid_device *hdev, · 310 unmodified lines | ||
| 311 | 311 | unsigned int minor; |
| 312 | 312 | int ret; |
| 313 | 313 | |
| 314 | − if (!hid_is_using_ll_driver(hdev, &usb_hid_driver)) | |
| 314 | + if (!hid_is_usb(hdev)) | |
| 315 | 315 | return -EINVAL; |
| 316 | 316 | |
| 317 | 317 | dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); |
| @@ -164,6 +164,9 @@ static int uclogic_probe(struct hid_device *hdev, · 163 unmodified lines | ||
| 164 | 164 | struct uclogic_drvdata *drvdata = NULL; |
| 165 | 165 | bool params_initialized = false; |
| 166 | 166 | |
| 167 | + if (!hid_is_usb(hdev)) | |
| 168 | + return -EINVAL; | |
| 169 | + | |
| 167 | 170 | /* |
| 168 | 171 | * libinput requires the pad interface to be on a different node |
| 169 | 172 | * than the pen, so use QUIRK_MULTI_INPUT for all tablets. |
| @@ -843,8 +843,7 @@ int uclogic_params_init(struct uclogic_params *params, · 842 unmodified lines | ||
| 843 | 843 | struct uclogic_params p = {0, }; |
| 844 | 844 | |
| 845 | 845 | /* Check arguments */ |
| 846 | − if (params == NULL || hdev == NULL || | |
| 847 | − !hid_is_using_ll_driver(hdev, &usb_hid_driver)) { | |
| 846 | + if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) { | |
| 848 | 847 | rc = -EINVAL; |
| 849 | 848 | goto cleanup; |
| 850 | 849 | } |
| @@ -266,7 +266,8 @@ static void __maybe_unused ish_resume_handler(struct work_struct *work) · 265 unmodified lines | ||
| 266 | 266 | |
| 267 | 267 | if (ish_should_leave_d0i3(pdev) && !dev->suspend_flag |
| 268 | 268 | && IPC_IS_ISH_ILUP(fwsts)) { |
| 269 | − disable_irq_wake(pdev->irq); | |
| 269 | + if (device_may_wakeup(&pdev->dev)) | |
| 270 | + disable_irq_wake(pdev->irq); | |
| 270 | 271 | |
| 271 | 272 | ish_set_host_ready(dev); |
| 272 | 273 | |
| @@ -337,7 +338,8 @@ static int __maybe_unused ish_suspend(struct device *device) · 64 unmodified lines | ||
| 337 | 338 | */ |
| 338 | 339 | pci_save_state(pdev); |
| 339 | 340 | |
| 340 | − enable_irq_wake(pdev->irq); | |
| 341 | + if (device_may_wakeup(&pdev->dev)) | |
| 342 | + enable_irq_wake(pdev->irq); | |
| 341 | 343 | } |
| 342 | 344 | } else { |
| 343 | 345 | /* |
| @@ -76,9 +76,12 @@ enum ish_loader_commands { · 75 unmodified lines | ||
| 76 | 76 | #define LOADER_XFER_MODE_ISHTP BIT(1) |
| 77 | 77 | |
| 78 | 78 | /* ISH Transport Loader client unique GUID */ |
| 79 | −static const guid_t loader_ishtp_guid = | |
| 80 | − GUID_INIT(0xc804d06a, 0x55bd, 0x4ea7, | |
| 81 | − 0xad, 0xed, 0x1e, 0x31, 0x22, 0x8c, 0x76, 0xdc); | |
| 79 | +static const struct ishtp_device_id loader_ishtp_id_table[] = { | |
| 80 | + { .guid = GUID_INIT(0xc804d06a, 0x55bd, 0x4ea7, | |
| 81 | + 0xad, 0xed, 0x1e, 0x31, 0x22, 0x8c, 0x76, 0xdc) }, | |
| 82 | + { } | |
| 83 | +}; | |
| 84 | +MODULE_DEVICE_TABLE(ishtp, loader_ishtp_id_table); | |
| 82 | 85 | |
| 83 | 86 | #define FILENAME_SIZE 256 |
| 84 | 87 | |
| @@ -880,7 +883,7 @@ static int loader_init(struct ishtp_cl *loader_ishtp_cl, int reset) · 795 unmodified lines | ||
| 880 | 883 | |
| 881 | 884 | fw_client = |
| 882 | 885 | ishtp_fw_cl_get_client(ishtp_get_ishtp_device(loader_ishtp_cl), |
| 883 | − &loader_ishtp_guid); | |
| 886 | + &loader_ishtp_id_table[0].guid); | |
| 884 | 887 | if (!fw_client) { |
| 885 | 888 | dev_err(cl_data_to_dev(client_data), |
| 886 | 889 | "ISH client uuid not found\n"); |
| @@ -1057,7 +1060,7 @@ static int loader_ishtp_cl_reset(struct ishtp_cl_device *cl_device) · 170 unmodified lines | ||
| 1057 | 1060 | |
| 1058 | 1061 | static struct ishtp_cl_driver loader_ishtp_cl_driver = { |
| 1059 | 1062 | .name = "ish-loader", |
| 1060 | − .guid = &loader_ishtp_guid, | |
| 1063 | + .id = loader_ishtp_id_table, | |
| 1061 | 1064 | .probe = loader_ishtp_cl_probe, |
| 1062 | 1065 | .remove = loader_ishtp_cl_remove, |
| 1063 | 1066 | .reset = loader_ishtp_cl_reset, |
| @@ -1083,4 +1086,3 @@ MODULE_DESCRIPTION("ISH ISH-TP Host firmware Loader Client Driver"); · 19 unmodified lines | ||
| 1083 | 1086 | MODULE_AUTHOR("Rushikesh S Kadam <rushikesh.s.kadam@intel.com>"); |
| 1084 | 1087 | |
| 1085 | 1088 | MODULE_LICENSE("GPL v2"); |
| 1086 | −MODULE_ALIAS("ishtp:*"); | |
| @@ -12,9 +12,12 @@ · 11 unmodified lines | ||
| 12 | 12 | #include "ishtp-hid.h" |
| 13 | 13 | |
| 14 | 14 | /* ISH Transport protocol (ISHTP in short) GUID */ |
| 15 | −static const guid_t hid_ishtp_guid = | |
| 16 | − GUID_INIT(0x33AECD58, 0xB679, 0x4E54, | |
| 17 | − 0x9B, 0xD9, 0xA0, 0x4D, 0x34, 0xF0, 0xC2, 0x26); | |
| 15 | +static const struct ishtp_device_id hid_ishtp_id_table[] = { | |
| 16 | + { .guid = GUID_INIT(0x33AECD58, 0xB679, 0x4E54, | |
| 17 | + 0x9B, 0xD9, 0xA0, 0x4D, 0x34, 0xF0, 0xC2, 0x26), }, | |
| 18 | + { } | |
| 19 | +}; | |
| 20 | +MODULE_DEVICE_TABLE(ishtp, hid_ishtp_id_table); | |
| 18 | 21 | |
| 19 | 22 | /* Rx ring buffer pool size */ |
| 20 | 23 | #define HID_CL_RX_RING_SIZE 32 |
| @@ -662,7 +665,7 @@ static int hid_ishtp_cl_init(struct ishtp_cl *hid_ishtp_cl, int reset) · 641 unmodified lines | ||
| 662 | 665 | ishtp_set_tx_ring_size(hid_ishtp_cl, HID_CL_TX_RING_SIZE); |
| 663 | 666 | ishtp_set_rx_ring_size(hid_ishtp_cl, HID_CL_RX_RING_SIZE); |
| 664 | 667 | |
| 665 | − fw_client = ishtp_fw_cl_get_client(dev, &hid_ishtp_guid); | |
| 668 | + fw_client = ishtp_fw_cl_get_client(dev, &hid_ishtp_id_table[0].guid); | |
| 666 | 669 | if (!fw_client) { |
| 667 | 670 | dev_err(cl_data_to_dev(client_data), |
| 668 | 671 | "ish client uuid not found\n"); |
| @@ -945,7 +948,7 @@ static const struct dev_pm_ops hid_ishtp_pm_ops = { · 276 unmodified lines | ||
| 945 | 948 | |
| 946 | 949 | static struct ishtp_cl_driver hid_ishtp_cl_driver = { |
| 947 | 950 | .name = "ish-hid", |
| 948 | − .guid = &hid_ishtp_guid, | |
| 951 | + .id = hid_ishtp_id_table, | |
| 949 | 952 | .probe = hid_ishtp_cl_probe, |
| 950 | 953 | .remove = hid_ishtp_cl_remove, |
| 951 | 954 | .reset = hid_ishtp_cl_reset, |
| @@ -981,4 +984,3 @@ MODULE_AUTHOR("Daniel Drubin <daniel.drubin@intel.com>"); · 29 unmodified lines | ||
| 981 | 984 | MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); |
| 982 | 985 | |
| 983 | 986 | MODULE_LICENSE("GPL"); |
| 984 | −MODULE_ALIAS("ishtp:*"); | |
| @@ -241,7 +241,7 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv) · 240 unmodified lines | ||
| 241 | 241 | struct ishtp_cl_device *device = to_ishtp_cl_device(dev); |
| 242 | 242 | struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv); |
| 243 | 243 | |
| 244 | − return guid_equal(driver->guid, | |
| 244 | + return guid_equal(&driver->id[0].guid, | |
| 245 | 245 | &device->fw_client->props.protocol_name); |
| 246 | 246 | } |
| 247 | 247 | |
| @@ -350,7 +350,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, · 102 unmodified lines | ||
| 350 | 350 | { |
| 351 | 351 | int len; |
| 352 | 352 | |
| 353 | − len = snprintf(buf, PAGE_SIZE, "ishtp:%s\n", dev_name(dev)); | |
| 353 | + len = snprintf(buf, PAGE_SIZE, ISHTP_MODULE_PREFIX "%s\n", dev_name(dev)); | |
| 354 | 354 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
| 355 | 355 | } |
| 356 | 356 | static DEVICE_ATTR_RO(modalias); |
| @@ -363,7 +363,7 @@ ATTRIBUTE_GROUPS(ishtp_cl_dev); · 6 unmodified lines | ||
| 363 | 363 | |
| 364 | 364 | static int ishtp_cl_uevent(struct device *dev, struct kobj_uevent_env *env) |
| 365 | 365 | { |
| 366 | − if (add_uevent_var(env, "MODALIAS=ishtp:%s", dev_name(dev))) | |
| 366 | + if (add_uevent_var(env, "MODALIAS=" ISHTP_MODULE_PREFIX "%s", dev_name(dev))) | |
| 367 | 367 | return -ENOMEM; |
| 368 | 368 | return 0; |
| 369 | 369 | } |
| @@ -726,7 +726,7 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, · 725 unmodified lines | ||
| 726 | 726 | * Skip the query for this type and modify defaults based on |
| 727 | 727 | * interface number. |
| 728 | 728 | */ |
| 729 | − if (features->type == WIRELESS) { | |
| 729 | + if (features->type == WIRELESS && intf) { | |
| 730 | 730 | if (intf->cur_altsetting->desc.bInterfaceNumber == 0) |
| 731 | 731 | features->device_type = WACOM_DEVICETYPE_WL_MONITOR; |
| 732 | 732 | else |
| @@ -2214,7 +2214,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix) · 1481 unmodified lines | ||
| 2214 | 2214 | if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) { |
| 2215 | 2215 | char *product_name = wacom->hdev->name; |
| 2216 | 2216 | |
| 2217 | − if (hid_is_using_ll_driver(wacom->hdev, &usb_hid_driver)) { | |
| 2217 | + if (hid_is_usb(wacom->hdev)) { | |
| 2218 | 2218 | struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent); |
| 2219 | 2219 | struct usb_device *dev = interface_to_usbdev(intf); |
| 2220 | 2220 | product_name = dev->product; |
| @@ -2451,6 +2451,9 @@ static void wacom_wireless_work(struct work_struct *work) · 230 unmodified lines | ||
| 2451 | 2451 | |
| 2452 | 2452 | wacom_destroy_battery(wacom); |
| 2453 | 2453 | |
| 2454 | + if (!usbdev) | |
| 2455 | + return; | |
| 2456 | + | |
| 2454 | 2457 | /* Stylus interface */ |
| 2455 | 2458 | hdev1 = usb_get_intfdata(usbdev->config->interface[1]); |
| 2456 | 2459 | wacom1 = hid_get_drvdata(hdev1); |
| @@ -2730,8 +2733,6 @@ static void wacom_mode_change_work(struct work_struct *work) · 273 unmodified lines | ||
| 2730 | 2733 | static int wacom_probe(struct hid_device *hdev, |
| 2731 | 2734 | const struct hid_device_id *id) |
| 2732 | 2735 | { |
| 2733 | − struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | |
| 2734 | − struct usb_device *dev = interface_to_usbdev(intf); | |
| 2735 | 2736 | struct wacom *wacom; |
| 2736 | 2737 | struct wacom_wac *wacom_wac; |
| 2737 | 2738 | struct wacom_features *features; |
| @@ -2766,8 +2767,14 @@ static int wacom_probe(struct hid_device *hdev, · 28 unmodified lines | ||
| 2766 | 2767 | wacom_wac->hid_data.inputmode = -1; |
| 2767 | 2768 | wacom_wac->mode_report = -1; |
| 2768 | 2769 | |
| 2769 | − wacom->usbdev = dev; | |
| 2770 | − wacom->intf = intf; | |
| 2770 | + if (hid_is_usb(hdev)) { | |
| 2771 | + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | |
| 2772 | + struct usb_device *dev = interface_to_usbdev(intf); | |
| 2773 | + | |
| 2774 | + wacom->usbdev = dev; | |
| 2775 | + wacom->intf = intf; | |
| 2776 | + } | |
| 2777 | + | |
| 2771 | 2778 | mutex_init(&wacom->lock); |
| 2772 | 2779 | INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work); |
| 2773 | 2780 | INIT_WORK(&wacom->wireless_work, wacom_wireless_work); |
| @@ -2603,6 +2603,9 @@ static void wacom_wac_finger_event(struct hid_device *hdev, · 2602 unmodified lines | ||
| 2603 | 2603 | return; |
| 2604 | 2604 | |
| 2605 | 2605 | switch (equivalent_usage) { |
| 2606 | + case HID_DG_CONFIDENCE: | |
| 2607 | + wacom_wac->hid_data.confidence = value; | |
| 2608 | + break; | |
| 2606 | 2609 | case HID_GD_X: |
| 2607 | 2610 | wacom_wac->hid_data.x = value; |
| 2608 | 2611 | break; |
| @@ -2635,7 +2638,8 @@ static void wacom_wac_finger_event(struct hid_device *hdev, · 26 unmodified lines | ||
| 2635 | 2638 | } |
| 2636 | 2639 | |
| 2637 | 2640 | if (usage->usage_index + 1 == field->report_count) { |
| 2638 | − if (equivalent_usage == wacom_wac->hid_data.last_slot_field) | |
| 2641 | + if (equivalent_usage == wacom_wac->hid_data.last_slot_field && | |
| 2642 | + wacom_wac->hid_data.confidence) | |
| 2639 | 2643 | wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); |
| 2640 | 2644 | } |
| 2641 | 2645 | } |
| @@ -2653,6 +2657,8 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, · 11 unmodified lines | ||
| 2653 | 2657 | |
| 2654 | 2658 | wacom_wac->is_invalid_bt_frame = false; |
| 2655 | 2659 | |
| 2660 | + hid_data->confidence = true; | |
| 2661 | + | |
| 2656 | 2662 | for (i = 0; i < report->maxfield; i++) { |
| 2657 | 2663 | struct hid_field *field = report->field[i]; |
| 2658 | 2664 | int j; |
| @@ -301,6 +301,7 @@ struct hid_data { · 300 unmodified lines | ||
| 301 | 301 | bool barrelswitch; |
| 302 | 302 | bool barrelswitch2; |
| 303 | 303 | bool serialhi; |
| 304 | + bool confidence; | |
| 304 | 305 | int x; |
| 305 | 306 | int y; |
| 306 | 307 | int pressure; |
| @@ -480,7 +480,7 @@ module_param(pressure_report_delay, uint, (S_IRUGO | S_IWUSR)); · 479 unmodified lines | ||
| 480 | 480 | MODULE_PARM_DESC(pressure_report_delay, "Delay in secs in reporting pressure"); |
| 481 | 481 | static atomic_t trans_id = ATOMIC_INIT(0); |
| 482 | 482 | |
| 483 | −static int dm_ring_size = 20 * 1024; | |
| 483 | +static int dm_ring_size = VMBUS_RING_SIZE(16 * 1024); | |
| 484 | 484 | |
| 485 | 485 | /* |
| 486 | 486 | * Driver specific state. |
| @@ -729,7 +729,7 @@ static int corsairpsu_probe(struct hid_device *hdev, const struct hid_device_id · 728 unmodified lines | ||
| 729 | 729 | corsairpsu_check_cmd_support(priv); |
| 730 | 730 | |
| 731 | 731 | priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "corsairpsu", priv, |
| 732 | − &corsairpsu_chip_info, 0); | |
| 732 | + &corsairpsu_chip_info, NULL); | |
| 733 | 733 | |
| 734 | 734 | if (IS_ERR(priv->hwmon_dev)) { |
| 735 | 735 | ret = PTR_ERR(priv->hwmon_dev); |
| @@ -627,10 +627,9 @@ static void __init i8k_init_procfs(struct device *dev) · 626 unmodified lines | ||
| 627 | 627 | { |
| 628 | 628 | struct dell_smm_data *data = dev_get_drvdata(dev); |
| 629 | 629 | |
| 630 | − /* Register the proc entry */ | |
| 631 | − proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data); | |
| 632 | − | |
| 633 | − devm_add_action_or_reset(dev, i8k_exit_procfs, NULL); | |
| 630 | + /* Only register exit function if creation was successful */ | |
| 631 | + if (proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data)) | |
| 632 | + devm_add_action_or_reset(dev, i8k_exit_procfs, NULL); | |
| 634 | 633 | } |
| 635 | 634 | |
| 636 | 635 | #else |
| @@ -1527,7 +1527,7 @@ static u16 nct6775_wmi_read_value(struct nct6775_data *data, u16 reg) · 1526 unmodified lines | ||
| 1527 | 1527 | |
| 1528 | 1528 | nct6775_wmi_set_bank(data, reg); |
| 1529 | 1529 | |
| 1530 | − err = nct6775_asuswmi_read(data->bank, reg, &tmp); | |
| 1530 | + err = nct6775_asuswmi_read(data->bank, reg & 0xff, &tmp); | |
| 1531 | 1531 | if (err) |
| 1532 | 1532 | return 0; |
| 1533 | 1533 | |
| @@ -336,8 +336,6 @@ static int pwm_fan_probe(struct platform_device *pdev) · 335 unmodified lines | ||
| 336 | 336 | return ret; |
| 337 | 337 | } |
| 338 | 338 | |
| 339 | − ctx->pwm_value = MAX_PWM; | |
| 340 | − | |
| 341 | 339 | pwm_init_state(ctx->pwm, &ctx->pwm_state); |
| 342 | 340 | |
| 343 | 341 | /* |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | /* |
| 24 | 24 | * I2C command delays (in microseconds) |
| 25 | 25 | */ |
| 26 | −#define SHT4X_MEAS_DELAY 1000 | |
| 26 | +#define SHT4X_MEAS_DELAY_HPM 8200 /* see t_MEAS,h in datasheet */ | |
| 27 | 27 | #define SHT4X_DELAY_EXTRA 10000 |
| 28 | 28 | |
| 29 | 29 | /* |
| @@ -90,7 +90,7 @@ static int sht4x_read_values(struct sht4x_data *data) · 60 unmodified lines | ||
| 90 | 90 | if (ret < 0) |
| 91 | 91 | goto unlock; |
| 92 | 92 | |
| 93 | − usleep_range(SHT4X_MEAS_DELAY, SHT4X_MEAS_DELAY + SHT4X_DELAY_EXTRA); | |
| 93 | + usleep_range(SHT4X_MEAS_DELAY_HPM, SHT4X_MEAS_DELAY_HPM + SHT4X_DELAY_EXTRA); | |
| 94 | 94 | |
| 95 | 95 | ret = i2c_master_recv(client, raw_data, SHT4X_RESPONSE_LENGTH); |
| 96 | 96 | if (ret != SHT4X_RESPONSE_LENGTH) { |
| @@ -195,8 +195,9 @@ static u32 cbus_i2c_func(struct i2c_adapter *adapter) · 194 unmodified lines | ||
| 195 | 195 | } |
| 196 | 196 | |
| 197 | 197 | static const struct i2c_algorithm cbus_i2c_algo = { |
| 198 | − .smbus_xfer = cbus_i2c_smbus_xfer, | |
| 199 | − .functionality = cbus_i2c_func, | |
| 198 | + .smbus_xfer = cbus_i2c_smbus_xfer, | |
| 199 | + .smbus_xfer_atomic = cbus_i2c_smbus_xfer, | |
| 200 | + .functionality = cbus_i2c_func, | |
| 200 | 201 | }; |
| 201 | 202 | |
| 202 | 203 | static int cbus_i2c_remove(struct platform_device *pdev) |
| @@ -191,6 +191,7 @@ · 190 unmodified lines | ||
| 191 | 191 | #define SMBSLVSTS_HST_NTFY_STS BIT(0) |
| 192 | 192 | |
| 193 | 193 | /* Host Notify Command register bits */ |
| 194 | +#define SMBSLVCMD_SMBALERT_DISABLE BIT(2) | |
| 194 | 195 | #define SMBSLVCMD_HST_NTFY_INTREN BIT(0) |
| 195 | 196 | |
| 196 | 197 | #define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \ |
| @@ -259,6 +260,7 @@ struct i801_priv { · 62 unmodified lines | ||
| 259 | 260 | struct i2c_adapter adapter; |
| 260 | 261 | unsigned long smba; |
| 261 | 262 | unsigned char original_hstcfg; |
| 263 | + unsigned char original_hstcnt; | |
| 262 | 264 | unsigned char original_slvcmd; |
| 263 | 265 | struct pci_dev *pci_dev; |
| 264 | 266 | unsigned int features; |
| @@ -641,12 +643,20 @@ static irqreturn_t i801_isr(int irq, void *dev_id) · 376 unmodified lines | ||
| 641 | 643 | i801_isr_byte_done(priv); |
| 642 | 644 | |
| 643 | 645 | /* |
| 644 | − * Clear irq sources and report transaction result. | |
| 646 | + * Clear remaining IRQ sources: Completion of last command, errors | |
| 647 | + * and the SMB_ALERT signal. SMB_ALERT status is set after signal | |
| 648 | + * assertion independently of the interrupt generation being blocked | |
| 649 | + * or not so clear it always when the status is set. | |
| 650 | + */ | |
| 651 | + status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS | SMBHSTSTS_SMBALERT_STS; | |
| 652 | + if (status) | |
| 653 | + outb_p(status, SMBHSTSTS(priv)); | |
| 654 | + status &= ~SMBHSTSTS_SMBALERT_STS; /* SMB_ALERT not reported */ | |
| 655 | + /* | |
| 656 | + * Report transaction result. | |
| 645 | 657 | * ->status must be cleared before the next transaction is started. |
| 646 | 658 | */ |
| 647 | − status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; | |
| 648 | 659 | if (status) { |
| 649 | − outb_p(status, SMBHSTSTS(priv)); | |
| 650 | 660 | priv->status = status; |
| 651 | 661 | complete(&priv->done); |
| 652 | 662 | } |
| @@ -974,9 +984,13 @@ static void i801_enable_host_notify(struct i2c_adapter *adapter) · 321 unmodified lines | ||
| 974 | 984 | if (!(priv->features & FEATURE_HOST_NOTIFY)) |
| 975 | 985 | return; |
| 976 | 986 | |
| 977 | − if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd)) | |
| 978 | − outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd, | |
| 979 | − SMBSLVCMD(priv)); | |
| 987 | + /* | |
| 988 | + * Enable host notify interrupt and block the generation of interrupt | |
| 989 | + * from the SMB_ALERT signal because the driver does not support | |
| 990 | + * SMBus Alert. | |
| 991 | + */ | |
| 992 | + outb_p(SMBSLVCMD_HST_NTFY_INTREN | SMBSLVCMD_SMBALERT_DISABLE | | |
| 993 | + priv->original_slvcmd, SMBSLVCMD(priv)); | |
| 980 | 994 | |
| 981 | 995 | /* clear Host Notify bit to allow a new notification */ |
| 982 | 996 | outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv)); |
| @@ -1805,7 +1819,8 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) · 822 unmodified lines | ||
| 1805 | 1819 | outb_p(inb_p(SMBAUXCTL(priv)) & |
| 1806 | 1820 | ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); |
| 1807 | 1821 | |
| 1808 | − /* Remember original Host Notify setting */ | |
| 1822 | + /* Remember original Interrupt and Host Notify settings */ | |
| 1823 | + priv->original_hstcnt = inb_p(SMBHSTCNT(priv)) & ~SMBHSTCNT_KILL; | |
| 1809 | 1824 | if (priv->features & FEATURE_HOST_NOTIFY) |
| 1810 | 1825 | priv->original_slvcmd = inb_p(SMBSLVCMD(priv)); |
| 1811 | 1826 | |
| @@ -1869,6 +1884,7 @@ static void i801_remove(struct pci_dev *dev) · 57 unmodified lines | ||
| 1869 | 1884 | { |
| 1870 | 1885 | struct i801_priv *priv = pci_get_drvdata(dev); |
| 1871 | 1886 | |
| 1887 | + outb_p(priv->original_hstcnt, SMBHSTCNT(priv)); | |
| 1872 | 1888 | i801_disable_host_notify(priv); |
| 1873 | 1889 | i801_del_mux(priv); |
| 1874 | 1890 | i2c_del_adapter(&priv->adapter); |
| @@ -1892,6 +1908,7 @@ static void i801_shutdown(struct pci_dev *dev) · 17 unmodified lines | ||
| 1892 | 1908 | struct i801_priv *priv = pci_get_drvdata(dev); |
| 1893 | 1909 | |
| 1894 | 1910 | /* Restore config registers to avoid hard hang on some systems */ |
| 1911 | + outb_p(priv->original_hstcnt, SMBHSTCNT(priv)); | |
| 1895 | 1912 | i801_disable_host_notify(priv); |
| 1896 | 1913 | pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); |
| 1897 | 1914 | } |
| @@ -1901,6 +1918,7 @@ static int i801_suspend(struct device *dev) · 3 unmodified lines | ||
| 1901 | 1918 | { |
| 1902 | 1919 | struct i801_priv *priv = dev_get_drvdata(dev); |
| 1903 | 1920 | |
| 1921 | + outb_p(priv->original_hstcnt, SMBHSTCNT(priv)); | |
| 1904 | 1922 | pci_write_config_byte(priv->pci_dev, SMBHSTCFG, priv->original_hstcfg); |
| 1905 | 1923 | return 0; |
| 1906 | 1924 | } |
| @@ -636,7 +636,7 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) · 635 unmodified lines | ||
| 636 | 636 | status = readb(i2c->base + MPC_I2C_SR); |
| 637 | 637 | if (status & CSR_MIF) { |
| 638 | 638 | /* Wait up to 100us for transfer to properly complete */ |
| 639 | − readb_poll_timeout(i2c->base + MPC_I2C_SR, status, !(status & CSR_MCF), 0, 100); | |
| 639 | + readb_poll_timeout_atomic(i2c->base + MPC_I2C_SR, status, status & CSR_MCF, 0, 100); | |
| 640 | 640 | writeb(0, i2c->base + MPC_I2C_SR); |
| 641 | 641 | mpc_i2c_do_intr(i2c, status); |
| 642 | 642 | return IRQ_HANDLED; |
| @@ -423,8 +423,8 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) · 422 unmodified lines | ||
| 423 | 423 | if (!(ipd & REG_INT_MBRF)) |
| 424 | 424 | return; |
| 425 | 425 | |
| 426 | − /* ack interrupt */ | |
| 427 | − i2c_writel(i2c, REG_INT_MBRF, REG_IPD); | |
| 426 | + /* ack interrupt (read also produces a spurious START flag, clear it too) */ | |
| 427 | + i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD); | |
| 428 | 428 | |
| 429 | 429 | /* Can only handle a maximum of 32 bytes at a time */ |
| 430 | 430 | if (len > 32) |
| @@ -1493,6 +1493,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) · 1492 unmodified lines | ||
| 1493 | 1493 | { |
| 1494 | 1494 | struct stm32f7_i2c_dev *i2c_dev = data; |
| 1495 | 1495 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; |
| 1496 | + struct stm32_i2c_dma *dma = i2c_dev->dma; | |
| 1496 | 1497 | void __iomem *base = i2c_dev->base; |
| 1497 | 1498 | u32 status, mask; |
| 1498 | 1499 | int ret = IRQ_HANDLED; |
| @@ -1518,6 +1519,10 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) · 19 unmodified lines | ||
| 1518 | 1519 | dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n", |
| 1519 | 1520 | __func__, f7_msg->addr); |
| 1520 | 1521 | writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR); |
| 1522 | + if (i2c_dev->use_dma) { | |
| 1523 | + stm32f7_i2c_disable_dma_req(i2c_dev); | |
| 1524 | + dmaengine_terminate_async(dma->chan_using); | |
| 1525 | + } | |
| 1521 | 1526 | f7_msg->result = -ENXIO; |
| 1522 | 1527 | } |
| 1523 | 1528 | |
| @@ -1533,7 +1538,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) · 9 unmodified lines | ||
| 1533 | 1538 | /* Clear STOP flag */ |
| 1534 | 1539 | writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); |
| 1535 | 1540 | |
| 1536 | − if (i2c_dev->use_dma) { | |
| 1541 | + if (i2c_dev->use_dma && !f7_msg->result) { | |
| 1537 | 1542 | ret = IRQ_WAKE_THREAD; |
| 1538 | 1543 | } else { |
| 1539 | 1544 | i2c_dev->master_mode = false; |
| @@ -1546,7 +1551,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) · 6 unmodified lines | ||
| 1546 | 1551 | if (f7_msg->stop) { |
| 1547 | 1552 | mask = STM32F7_I2C_CR2_STOP; |
| 1548 | 1553 | stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask); |
| 1549 | − } else if (i2c_dev->use_dma) { | |
| 1554 | + } else if (i2c_dev->use_dma && !f7_msg->result) { | |
| 1550 | 1555 | ret = IRQ_WAKE_THREAD; |
| 1551 | 1556 | } else if (f7_msg->smbus) { |
| 1552 | 1557 | stm32f7_i2c_smbus_rep_start(i2c_dev); |
| @@ -1583,7 +1588,7 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data) · 30 unmodified lines | ||
| 1583 | 1588 | if (!ret) { |
| 1584 | 1589 | dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); |
| 1585 | 1590 | stm32f7_i2c_disable_dma_req(i2c_dev); |
| 1586 | − dmaengine_terminate_all(dma->chan_using); | |
| 1591 | + dmaengine_terminate_async(dma->chan_using); | |
| 1587 | 1592 | f7_msg->result = -ETIMEDOUT; |
| 1588 | 1593 | } |
| 1589 | 1594 | |
| @@ -1660,7 +1665,7 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) · 70 unmodified lines | ||
| 1660 | 1665 | /* Disable dma */ |
| 1661 | 1666 | if (i2c_dev->use_dma) { |
| 1662 | 1667 | stm32f7_i2c_disable_dma_req(i2c_dev); |
| 1663 | − dmaengine_terminate_all(dma->chan_using); | |
| 1668 | + dmaengine_terminate_async(dma->chan_using); | |
| 1664 | 1669 | } |
| 1665 | 1670 | |
| 1666 | 1671 | i2c_dev->master_mode = false; |
| @@ -1696,12 +1701,26 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, · 29 unmodified lines | ||
| 1696 | 1701 | time_left = wait_for_completion_timeout(&i2c_dev->complete, |
| 1697 | 1702 | i2c_dev->adap.timeout); |
| 1698 | 1703 | ret = f7_msg->result; |
| 1704 | + if (ret) { | |
| 1705 | + if (i2c_dev->use_dma) | |
| 1706 | + dmaengine_synchronize(dma->chan_using); | |
| 1707 | + | |
| 1708 | + /* | |
| 1709 | + * It is possible that some unsent data have already been | |
| 1710 | + * written into TXDR. To avoid sending old data in a | |
| 1711 | + * further transfer, flush TXDR in case of any error | |
| 1712 | + */ | |
| 1713 | + writel_relaxed(STM32F7_I2C_ISR_TXE, | |
| 1714 | + i2c_dev->base + STM32F7_I2C_ISR); | |
| 1715 | + goto pm_free; | |
| 1716 | + } | |
| 1699 | 1717 | |
| 1700 | 1718 | if (!time_left) { |
| 1701 | 1719 | dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n", |
| 1702 | 1720 | i2c_dev->msg->addr); |
| 1703 | 1721 | if (i2c_dev->use_dma) |
| 1704 | − dmaengine_terminate_all(dma->chan_using); | |
| 1722 | + dmaengine_terminate_sync(dma->chan_using); | |
| 1723 | + stm32f7_i2c_wait_free_bus(i2c_dev); | |
| 1705 | 1724 | ret = -ETIMEDOUT; |
| 1706 | 1725 | } |
| 1707 | 1726 | |
| @@ -1744,13 +1763,25 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, · 36 unmodified lines | ||
| 1744 | 1763 | timeout = wait_for_completion_timeout(&i2c_dev->complete, |
| 1745 | 1764 | i2c_dev->adap.timeout); |
| 1746 | 1765 | ret = f7_msg->result; |
| 1747 | − if (ret) | |
| 1766 | + if (ret) { | |
| 1767 | + if (i2c_dev->use_dma) | |
| 1768 | + dmaengine_synchronize(dma->chan_using); | |
| 1769 | + | |
| 1770 | + /* | |
| 1771 | + * It is possible that some unsent data have already been | |
| 1772 | + * written into TXDR. To avoid sending old data in a | |
| 1773 | + * further transfer, flush TXDR in case of any error | |
| 1774 | + */ | |
| 1775 | + writel_relaxed(STM32F7_I2C_ISR_TXE, | |
| 1776 | + i2c_dev->base + STM32F7_I2C_ISR); | |
| 1748 | 1777 | goto pm_free; |
| 1778 | + } | |
| 1749 | 1779 | |
| 1750 | 1780 | if (!timeout) { |
| 1751 | 1781 | dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr); |
| 1752 | 1782 | if (i2c_dev->use_dma) |
| 1753 | − dmaengine_terminate_all(dma->chan_using); | |
| 1783 | + dmaengine_terminate_sync(dma->chan_using); | |
| 1784 | + stm32f7_i2c_wait_free_bus(i2c_dev); | |
| 1754 | 1785 | ret = -ETIMEDOUT; |
| 1755 | 1786 | goto pm_free; |
| 1756 | 1787 | } |
| @@ -22,24 +22,24 @@ · 21 unmodified lines | ||
| 22 | 22 | /** |
| 23 | 23 | * struct virtio_i2c - virtio I2C data |
| 24 | 24 | * @vdev: virtio device for this controller |
| 25 | − * @completion: completion of virtio I2C message | |
| 26 | 25 | * @adap: I2C adapter for this controller |
| 27 | 26 | * @vq: the virtio virtqueue for communication |
| 28 | 27 | */ |
| 29 | 28 | struct virtio_i2c { |
| 30 | 29 | struct virtio_device *vdev; |
| 31 | − struct completion completion; | |
| 32 | 30 | struct i2c_adapter adap; |
| 33 | 31 | struct virtqueue *vq; |
| 34 | 32 | }; |
| 35 | 33 | |
| 36 | 34 | /** |
| 37 | 35 | * struct virtio_i2c_req - the virtio I2C request structure |
| 36 | + * @completion: completion of virtio I2C message | |
| 38 | 37 | * @out_hdr: the OUT header of the virtio I2C message |
| 39 | 38 | * @buf: the buffer into which data is read, or from which it's written |
| 40 | 39 | * @in_hdr: the IN header of the virtio I2C message |
| 41 | 40 | */ |
| 42 | 41 | struct virtio_i2c_req { |
| 42 | + struct completion completion; | |
| 43 | 43 | struct virtio_i2c_out_hdr out_hdr ____cacheline_aligned; |
| 44 | 44 | uint8_t *buf ____cacheline_aligned; |
| 45 | 45 | struct virtio_i2c_in_hdr in_hdr ____cacheline_aligned; |
| @@ -47,9 +47,11 @@ struct virtio_i2c_req { · 1 unmodified line | ||
| 47 | 47 | |
| 48 | 48 | static void virtio_i2c_msg_done(struct virtqueue *vq) |
| 49 | 49 | { |
| 50 | − struct virtio_i2c *vi = vq->vdev->priv; | |
| 50 | + struct virtio_i2c_req *req; | |
| 51 | + unsigned int len; | |
| 51 | 52 | |
| 52 | − complete(&vi->completion); | |
| 53 | + while ((req = virtqueue_get_buf(vq, &len))) | |
| 54 | + complete(&req->completion); | |
| 53 | 55 | } |
| 54 | 56 | |
| 55 | 57 | static int virtio_i2c_prepare_reqs(struct virtqueue *vq, |
| @@ -62,6 +64,8 @@ static int virtio_i2c_prepare_reqs(struct virtqueue *vq, · 6 unmodified lines | ||
| 62 | 64 | for (i = 0; i < num; i++) { |
| 63 | 65 | int outcnt = 0, incnt = 0; |
| 64 | 66 | |
| 67 | + init_completion(&reqs[i].completion); | |
| 68 | + | |
| 65 | 69 | /* |
| 66 | 70 | * Only 7-bit mode supported for this moment. For the address |
| 67 | 71 | * format, Please check the Virtio I2C Specification. |
| @@ -104,24 +108,17 @@ static int virtio_i2c_prepare_reqs(struct virtqueue *vq, · 36 unmodified lines | ||
| 104 | 108 | |
| 105 | 109 | static int virtio_i2c_complete_reqs(struct virtqueue *vq, |
| 106 | 110 | struct virtio_i2c_req *reqs, |
| 107 | − struct i2c_msg *msgs, int num, | |
| 108 | − bool timedout) | |
| 111 | + struct i2c_msg *msgs, int num) | |
| 109 | 112 | { |
| 110 | − struct virtio_i2c_req *req; | |
| 111 | − bool failed = timedout; | |
| 112 | − unsigned int len; | |
| 113 | + bool failed = false; | |
| 113 | 114 | int i, j = 0; |
| 114 | 115 | |
| 115 | 116 | for (i = 0; i < num; i++) { |
| 116 | − /* Detach the ith request from the vq */ | |
| 117 | − req = virtqueue_get_buf(vq, &len); | |
| 117 | + struct virtio_i2c_req *req = &reqs[i]; | |
| 118 | 118 | |
| 119 | − /* | |
| 120 | − * Condition req == &reqs[i] should always meet since we have | |
| 121 | − * total num requests in the vq. reqs[i] can never be NULL here. | |
| 122 | − */ | |
| 123 | − if (!failed && (WARN_ON(req != &reqs[i]) || | |
| 124 | − req->in_hdr.status != VIRTIO_I2C_MSG_OK)) | |
| 119 | + wait_for_completion(&req->completion); | |
| 120 | + | |
| 121 | + if (!failed && req->in_hdr.status != VIRTIO_I2C_MSG_OK) | |
| 125 | 122 | failed = true; |
| 126 | 123 | |
| 127 | 124 | i2c_put_dma_safe_msg_buf(reqs[i].buf, &msgs[i], !failed); |
| @@ -130,7 +127,7 @@ static int virtio_i2c_complete_reqs(struct virtqueue *vq, · 2 unmodified lines | ||
| 130 | 127 | j++; |
| 131 | 128 | } |
| 132 | 129 | |
| 133 | − return timedout ? -ETIMEDOUT : j; | |
| 130 | + return j; | |
| 134 | 131 | } |
| 135 | 132 | |
| 136 | 133 | static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, |
| @@ -139,7 +136,6 @@ static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, · 2 unmodified lines | ||
| 139 | 136 | struct virtio_i2c *vi = i2c_get_adapdata(adap); |
| 140 | 137 | struct virtqueue *vq = vi->vq; |
| 141 | 138 | struct virtio_i2c_req *reqs; |
| 142 | − unsigned long time_left; | |
| 143 | 139 | int count; |
| 144 | 140 | |
| 145 | 141 | reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL); |
| @@ -158,15 +154,9 @@ static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, · 12 unmodified lines | ||
| 158 | 154 | * remote here to clear the virtqueue, so we can try another set of |
| 159 | 155 | * messages later on. |
| 160 | 156 | */ |
| 161 | − | |
| 162 | − reinit_completion(&vi->completion); | |
| 163 | 157 | virtqueue_kick(vq); |
| 164 | 158 | |
| 165 | − time_left = wait_for_completion_timeout(&vi->completion, adap->timeout); | |
| 166 | − if (!time_left) | |
| 167 | − dev_err(&adap->dev, "virtio i2c backend timeout.\n"); | |
| 168 | − | |
| 169 | − count = virtio_i2c_complete_reqs(vq, reqs, msgs, count, !time_left); | |
| 159 | + count = virtio_i2c_complete_reqs(vq, reqs, msgs, count); | |
| 170 | 160 | |
| 171 | 161 | err_free: |
| 172 | 162 | kfree(reqs); |
| @@ -214,8 +204,6 @@ static int virtio_i2c_probe(struct virtio_device *vdev) · 41 unmodified lines | ||
| 214 | 204 | vdev->priv = vi; |
| 215 | 205 | vi->vdev = vdev; |
| 216 | 206 | |
| 217 | − init_completion(&vi->completion); | |
| 218 | − | |
| 219 | 207 | ret = virtio_i2c_setup_vqs(vi); |
| 220 | 208 | if (ret) |
| 221 | 209 | return ret; |
| @@ -1595,8 +1595,7 @@ static int kxcjk1013_probe(struct i2c_client *client, · 1594 unmodified lines | ||
| 1595 | 1595 | return 0; |
| 1596 | 1596 | |
| 1597 | 1597 | err_buffer_cleanup: |
| 1598 | − if (data->dready_trig) | |
| 1599 | − iio_triggered_buffer_cleanup(indio_dev); | |
| 1598 | + iio_triggered_buffer_cleanup(indio_dev); | |
| 1600 | 1599 | err_trigger_unregister: |
| 1601 | 1600 | if (data->dready_trig) |
| 1602 | 1601 | iio_trigger_unregister(data->dready_trig); |
| @@ -1618,8 +1617,8 @@ static int kxcjk1013_remove(struct i2c_client *client) · 15 unmodified lines | ||
| 1618 | 1617 | pm_runtime_disable(&client->dev); |
| 1619 | 1618 | pm_runtime_set_suspended(&client->dev); |
| 1620 | 1619 | |
| 1620 | + iio_triggered_buffer_cleanup(indio_dev); | |
| 1621 | 1621 | if (data->dready_trig) { |
| 1622 | − iio_triggered_buffer_cleanup(indio_dev); | |
| 1623 | 1622 | iio_trigger_unregister(data->dready_trig); |
| 1624 | 1623 | iio_trigger_unregister(data->motion_trig); |
| 1625 | 1624 | } |
| @@ -224,14 +224,14 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p) · 223 unmodified lines | ||
| 224 | 224 | hw_values.chan, |
| 225 | 225 | sizeof(hw_values.chan)); |
| 226 | 226 | if (ret) { |
| 227 | − dev_err(st->dev, | |
| 228 | − "error reading data\n"); | |
| 229 | − return ret; | |
| 227 | + dev_err(st->dev, "error reading data: %d\n", ret); | |
| 228 | + goto out; | |
| 230 | 229 | } |
| 231 | 230 | |
| 232 | 231 | iio_push_to_buffers_with_timestamp(indio_dev, |
| 233 | 232 | &hw_values, |
| 234 | 233 | iio_get_time_ns(indio_dev)); |
| 234 | +out: | |
| 235 | 235 | iio_trigger_notify_done(indio_dev->trig); |
| 236 | 236 | |
| 237 | 237 | return IRQ_HANDLED; |
| @@ -1470,7 +1470,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev) · 1469 unmodified lines | ||
| 1470 | 1470 | if (ret) |
| 1471 | 1471 | return ret; |
| 1472 | 1472 | |
| 1473 | − indio_dev->trig = trig; | |
| 1473 | + indio_dev->trig = iio_trigger_get(trig); | |
| 1474 | 1474 | |
| 1475 | 1475 | return 0; |
| 1476 | 1476 | } |
| @@ -532,7 +532,7 @@ config IMX7D_ADC · 531 unmodified lines | ||
| 532 | 532 | |
| 533 | 533 | config IMX8QXP_ADC |
| 534 | 534 | tristate "NXP IMX8QXP ADC driver" |
| 535 | − depends on ARCH_MXC_ARM64 || COMPILE_TEST | |
| 535 | + depends on ARCH_MXC || COMPILE_TEST | |
| 536 | 536 | depends on HAS_IOMEM |
| 537 | 537 | help |
| 538 | 538 | Say yes here to build support for IMX8QXP ADC. |
| @@ -480,8 +480,8 @@ static irqreturn_t ad7768_trigger_handler(int irq, void *p) · 479 unmodified lines | ||
| 480 | 480 | iio_push_to_buffers_with_timestamp(indio_dev, &st->data.scan, |
| 481 | 481 | iio_get_time_ns(indio_dev)); |
| 482 | 482 | |
| 483 | − iio_trigger_notify_done(indio_dev->trig); | |
| 484 | 483 | err_unlock: |
| 484 | + iio_trigger_notify_done(indio_dev->trig); | |
| 485 | 485 | mutex_unlock(&st->lock); |
| 486 | 486 | |
| 487 | 487 | return IRQ_HANDLED; |
| @@ -1586,7 +1586,8 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, · 1585 unmodified lines | ||
| 1586 | 1586 | *val = st->conversion_value; |
| 1587 | 1587 | ret = at91_adc_adjust_val_osr(st, val); |
| 1588 | 1588 | if (chan->scan_type.sign == 's') |
| 1589 | − *val = sign_extend32(*val, 11); | |
| 1589 | + *val = sign_extend32(*val, | |
| 1590 | + chan->scan_type.realbits - 1); | |
| 1590 | 1591 | st->conversion_done = false; |
| 1591 | 1592 | } |
| 1592 | 1593 | |
| @@ -251,19 +251,8 @@ static int axp22x_adc_raw(struct iio_dev *indio_dev, · 250 unmodified lines | ||
| 251 | 251 | struct iio_chan_spec const *chan, int *val) |
| 252 | 252 | { |
| 253 | 253 | struct axp20x_adc_iio *info = iio_priv(indio_dev); |
| 254 | − int size; | |
| 255 | 254 | |
| 256 | − /* | |
| 257 | − * N.B.: Unlike the Chinese datasheets tell, the charging current is | |
| 258 | − * stored on 12 bits, not 13 bits. Only discharging current is on 13 | |
| 259 | − * bits. | |
| 260 | − */ | |
| 261 | − if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I) | |
| 262 | − size = 13; | |
| 263 | − else | |
| 264 | − size = 12; | |
| 265 | − | |
| 266 | − *val = axp20x_read_variable_width(info->regmap, chan->address, size); | |
| 255 | + *val = axp20x_read_variable_width(info->regmap, chan->address, 12); | |
| 267 | 256 | if (*val < 0) |
| 268 | 257 | return *val; |
| 269 | 258 | |
| @@ -386,9 +375,8 @@ static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val, · 116 unmodified lines | ||
| 386 | 375 | return IIO_VAL_INT_PLUS_MICRO; |
| 387 | 376 | |
| 388 | 377 | case IIO_CURRENT: |
| 389 | − *val = 0; | |
| 390 | − *val2 = 500000; | |
| 391 | − return IIO_VAL_INT_PLUS_MICRO; | |
| 378 | + *val = 1; | |
| 379 | + return IIO_VAL_INT; | |
| 392 | 380 | |
| 393 | 381 | case IIO_TEMP: |
| 394 | 382 | *val = 100; |
| @@ -248,7 +248,6 @@ static int dln2_adc_set_chan_period(struct dln2_adc *dln2, · 247 unmodified lines | ||
| 248 | 248 | static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel) |
| 249 | 249 | { |
| 250 | 250 | int ret, i; |
| 251 | − struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev); | |
| 252 | 251 | u16 conflict; |
| 253 | 252 | __le16 value; |
| 254 | 253 | int olen = sizeof(value); |
| @@ -257,13 +256,9 @@ static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel) · 2 unmodified lines | ||
| 257 | 256 | .chan = channel, |
| 258 | 257 | }; |
| 259 | 258 | |
| 260 | − ret = iio_device_claim_direct_mode(indio_dev); | |
| 261 | − if (ret < 0) | |
| 262 | − return ret; | |
| 263 | − | |
| 264 | 259 | ret = dln2_adc_set_chan_enabled(dln2, channel, true); |
| 265 | 260 | if (ret < 0) |
| 266 | − goto release_direct; | |
| 261 | + return ret; | |
| 267 | 262 | |
| 268 | 263 | ret = dln2_adc_set_port_enabled(dln2, true, &conflict); |
| 269 | 264 | if (ret < 0) { |
| @@ -300,8 +295,6 @@ disable_port: · 30 unmodified lines | ||
| 300 | 295 | dln2_adc_set_port_enabled(dln2, false, NULL); |
| 301 | 296 | disable_chan: |
| 302 | 297 | dln2_adc_set_chan_enabled(dln2, channel, false); |
| 303 | −release_direct: | |
| 304 | − iio_device_release_direct_mode(indio_dev); | |
| 305 | 298 | |
| 306 | 299 | return ret; |
| 307 | 300 | } |
| @@ -337,10 +330,16 @@ static int dln2_adc_read_raw(struct iio_dev *indio_dev, · 29 unmodified lines | ||
| 337 | 330 | |
| 338 | 331 | switch (mask) { |
| 339 | 332 | case IIO_CHAN_INFO_RAW: |
| 333 | + ret = iio_device_claim_direct_mode(indio_dev); | |
| 334 | + if (ret < 0) | |
| 335 | + return ret; | |
| 336 | + | |
| 340 | 337 | mutex_lock(&dln2->mutex); |
| 341 | 338 | ret = dln2_adc_read(dln2, chan->channel); |
| 342 | 339 | mutex_unlock(&dln2->mutex); |
| 343 | 340 | |
| 341 | + iio_device_release_direct_mode(indio_dev); | |
| 342 | + | |
| 344 | 343 | if (ret < 0) |
| 345 | 344 | return ret; |
| 346 | 345 | |
| @@ -656,7 +655,11 @@ static int dln2_adc_probe(struct platform_device *pdev) · 309 unmodified lines | ||
| 656 | 655 | return -ENOMEM; |
| 657 | 656 | } |
| 658 | 657 | iio_trigger_set_drvdata(dln2->trig, dln2); |
| 659 | − devm_iio_trigger_register(dev, dln2->trig); | |
| 658 | + ret = devm_iio_trigger_register(dev, dln2->trig); | |
| 659 | + if (ret) { | |
| 660 | + dev_err(dev, "failed to register trigger: %d\n", ret); | |
| 661 | + return ret; | |
| 662 | + } | |
| 660 | 663 | iio_trigger_set_immutable(indio_dev, dln2->trig); |
| 661 | 664 | |
| 662 | 665 | ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, |
| @@ -1117,6 +1117,7 @@ static void stm32h7_adc_unprepare(struct iio_dev *indio_dev) · 1116 unmodified lines | ||
| 1117 | 1117 | { |
| 1118 | 1118 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1119 | 1119 | |
| 1120 | + stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0); | |
| 1120 | 1121 | stm32h7_adc_disable(indio_dev); |
| 1121 | 1122 | stm32_adc_int_ch_disable(adc); |
| 1122 | 1123 | stm32h7_adc_enter_pwr_down(adc); |
| @@ -1986,7 +1987,7 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n · 863 unmodified lines | ||
| 1986 | 1987 | /* Get calibration data for vrefint channel */ |
| 1987 | 1988 | ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint); |
| 1988 | 1989 | if (ret && ret != -ENOENT) { |
| 1989 | − return dev_err_probe(&indio_dev->dev, ret, | |
| 1990 | + return dev_err_probe(indio_dev->dev.parent, ret, | |
| 1990 | 1991 | "nvmem access error\n"); |
| 1991 | 1992 | } |
| 1992 | 1993 | if (ret == -ENOENT) |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #include <linux/bitfield.h> |
| 10 | +#include <linux/bitops.h> | |
| 10 | 11 | #include <linux/delay.h> |
| 11 | 12 | #include <linux/device.h> |
| 12 | 13 | #include <linux/kernel.h> |
| @@ -124,7 +125,7 @@ static int adxrs290_get_rate_data(struct iio_dev *indio_dev, const u8 cmd, int * · 111 unmodified lines | ||
| 124 | 125 | goto err_unlock; |
| 125 | 126 | } |
| 126 | 127 | |
| 127 | − *val = temp; | |
| 128 | + *val = sign_extend32(temp, 15); | |
| 128 | 129 | |
| 129 | 130 | err_unlock: |
| 130 | 131 | mutex_unlock(&st->lock); |
| @@ -146,7 +147,7 @@ static int adxrs290_get_temp_data(struct iio_dev *indio_dev, int *val) · 15 unmodified lines | ||
| 146 | 147 | } |
| 147 | 148 | |
| 148 | 149 | /* extract lower 12 bits temperature reading */ |
| 149 | − *val = temp & 0x0FFF; | |
| 150 | + *val = sign_extend32(temp, 11); | |
| 150 | 151 | |
| 151 | 152 | err_unlock: |
| 152 | 153 | mutex_unlock(&st->lock); |
| @@ -61,9 +61,9 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p) · 60 unmodified lines | ||
| 61 | 61 | |
| 62 | 62 | iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); |
| 63 | 63 | |
| 64 | +error_ret: | |
| 64 | 65 | iio_trigger_notify_done(indio_dev->trig); |
| 65 | 66 | |
| 66 | −error_ret: | |
| 67 | 67 | return IRQ_HANDLED; |
| 68 | 68 | } |
| 69 | 69 | |
| @@ -556,7 +556,6 @@ struct iio_trigger *viio_trigger_alloc(struct device *parent, · 555 unmodified lines | ||
| 556 | 556 | irq_modify_status(trig->subirq_base + i, |
| 557 | 557 | IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); |
| 558 | 558 | } |
| 559 | − get_device(&trig->dev); | |
| 560 | 559 | |
| 561 | 560 | return trig; |
| 562 | 561 | |
| @@ -1275,7 +1275,7 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p) · 1274 unmodified lines | ||
| 1275 | 1275 | ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1, |
| 1276 | 1276 | als_buf, sizeof(als_buf)); |
| 1277 | 1277 | if (ret < 0) |
| 1278 | − return ret; | |
| 1278 | + goto done; | |
| 1279 | 1279 | if (test_bit(0, indio_dev->active_scan_mask)) |
| 1280 | 1280 | scan.channels[j++] = le16_to_cpu(als_buf[1]); |
| 1281 | 1281 | if (test_bit(1, indio_dev->active_scan_mask)) |
| @@ -546,9 +546,8 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private) · 545 unmodified lines | ||
| 546 | 546 | mutex_lock(&data->lock); |
| 547 | 547 | ret = regmap_field_read(data->reg_flag_nf, &dir); |
| 548 | 548 | if (ret < 0) { |
| 549 | − dev_err(&data->client->dev, "register read failed\n"); | |
| 550 | − mutex_unlock(&data->lock); | |
| 551 | − return ret; | |
| 549 | + dev_err(&data->client->dev, "register read failed: %d\n", ret); | |
| 550 | + goto out; | |
| 552 | 551 | } |
| 553 | 552 | event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, |
| 554 | 553 | IIO_EV_TYPE_THRESH, |
| @@ -560,6 +559,7 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private) · 5 unmodified lines | ||
| 560 | 559 | ret = regmap_field_write(data->reg_flag_psint, 0); |
| 561 | 560 | if (ret < 0) |
| 562 | 561 | dev_err(&data->client->dev, "failed to reset interrupts\n"); |
| 562 | +out: | |
| 563 | 563 | mutex_unlock(&data->lock); |
| 564 | 564 | |
| 565 | 565 | return IRQ_HANDLED; |
| @@ -912,6 +912,6 @@ static struct platform_driver stm32_timer_trigger_driver = { · 911 unmodified lines | ||
| 912 | 912 | }; |
| 913 | 913 | module_platform_driver(stm32_timer_trigger_driver); |
| 914 | 914 | |
| 915 | −MODULE_ALIAS("platform: stm32-timer-trigger"); | |
| 915 | +MODULE_ALIAS("platform:stm32-timer-trigger"); | |
| 916 | 916 | MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver"); |
| 917 | 917 | MODULE_LICENSE("GPL v2"); |
| @@ -1906,7 +1906,8 @@ static int nldev_stat_set_mode_doit(struct sk_buff *msg, · 1905 unmodified lines | ||
| 1906 | 1906 | int ret; |
| 1907 | 1907 | |
| 1908 | 1908 | /* Currently only counter for QP is supported */ |
| 1909 | − if (nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_RES]) != RDMA_NLDEV_ATTR_RES_QP) | |
| 1909 | + if (!tb[RDMA_NLDEV_ATTR_STAT_RES] || | |
| 1910 | + nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_RES]) != RDMA_NLDEV_ATTR_RES_QP) | |
| 1910 | 1911 | return -EINVAL; |
| 1911 | 1912 | |
| 1912 | 1913 | mode = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_MODE]); |
| @@ -1232,6 +1232,9 @@ static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd, · 1231 unmodified lines | ||
| 1232 | 1232 | INIT_LIST_HEAD(&qp->rdma_mrs); |
| 1233 | 1233 | INIT_LIST_HEAD(&qp->sig_mrs); |
| 1234 | 1234 | |
| 1235 | + qp->send_cq = attr->send_cq; | |
| 1236 | + qp->recv_cq = attr->recv_cq; | |
| 1237 | + | |
| 1235 | 1238 | rdma_restrack_new(&qp->res, RDMA_RESTRACK_QP); |
| 1236 | 1239 | WARN_ONCE(!udata && !caller, "Missing kernel QP owner"); |
| 1237 | 1240 | rdma_restrack_set_name(&qp->res, udata ? NULL : caller); |
| @@ -8415,6 +8415,8 @@ static void receive_interrupt_common(struct hfi1_ctxtdata *rcd) · 8414 unmodified lines | ||
| 8415 | 8415 | */ |
| 8416 | 8416 | static void __hfi1_rcd_eoi_intr(struct hfi1_ctxtdata *rcd) |
| 8417 | 8417 | { |
| 8418 | + if (!rcd->rcvhdrq) | |
| 8419 | + return; | |
| 8418 | 8420 | clear_recv_intr(rcd); |
| 8419 | 8421 | if (check_packet_present(rcd)) |
| 8420 | 8422 | force_recv_intr(rcd); |
| @@ -1012,6 +1012,8 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread) · 1011 unmodified lines | ||
| 1012 | 1012 | struct hfi1_packet packet; |
| 1013 | 1013 | int skip_pkt = 0; |
| 1014 | 1014 | |
| 1015 | + if (!rcd->rcvhdrq) | |
| 1016 | + return RCV_PKT_OK; | |
| 1015 | 1017 | /* Control context will always use the slow path interrupt handler */ |
| 1016 | 1018 | needset = (rcd->ctxt == HFI1_CTRL_CTXT) ? 0 : 1; |
| 1017 | 1019 | |
| @@ -113,7 +113,6 @@ static int hfi1_create_kctxt(struct hfi1_devdata *dd, · 112 unmodified lines | ||
| 113 | 113 | rcd->fast_handler = get_dma_rtail_setting(rcd) ? |
| 114 | 114 | handle_receive_interrupt_dma_rtail : |
| 115 | 115 | handle_receive_interrupt_nodma_rtail; |
| 116 | − rcd->slow_handler = handle_receive_interrupt; | |
| 117 | 116 | |
| 118 | 117 | hfi1_set_seq_cnt(rcd, 1); |
| 119 | 118 | |
| @@ -334,6 +333,8 @@ int hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa, · 214 unmodified lines | ||
| 334 | 333 | rcd->numa_id = numa; |
| 335 | 334 | rcd->rcv_array_groups = dd->rcv_entries.ngroups; |
| 336 | 335 | rcd->rhf_rcv_function_map = normal_rhf_rcv_functions; |
| 336 | + rcd->slow_handler = handle_receive_interrupt; | |
| 337 | + rcd->do_interrupt = rcd->slow_handler; | |
| 337 | 338 | rcd->msix_intr = CCE_NUM_MSIX_VECTORS; |
| 338 | 339 | |
| 339 | 340 | mutex_init(&rcd->exp_mutex); |
| @@ -874,18 +875,6 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) · 534 unmodified lines | ||
| 874 | 875 | if (ret) |
| 875 | 876 | goto done; |
| 876 | 877 | |
| 877 | − /* allocate dummy tail memory for all receive contexts */ | |
| 878 | − dd->rcvhdrtail_dummy_kvaddr = dma_alloc_coherent(&dd->pcidev->dev, | |
| 879 | − sizeof(u64), | |
| 880 | − &dd->rcvhdrtail_dummy_dma, | |
| 881 | − GFP_KERNEL); | |
| 882 | − | |
| 883 | − if (!dd->rcvhdrtail_dummy_kvaddr) { | |
| 884 | − dd_dev_err(dd, "cannot allocate dummy tail memory\n"); | |
| 885 | − ret = -ENOMEM; | |
| 886 | − goto done; | |
| 887 | − } | |
| 888 | − | |
| 889 | 878 | /* dd->rcd can be NULL if early initialization failed */ |
| 890 | 879 | for (i = 0; dd->rcd && i < dd->first_dyn_alloc_ctxt; ++i) { |
| 891 | 880 | /* |
| @@ -898,8 +887,6 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) · 6 unmodified lines | ||
| 898 | 887 | if (!rcd) |
| 899 | 888 | continue; |
| 900 | 889 | |
| 901 | − rcd->do_interrupt = &handle_receive_interrupt; | |
| 902 | − | |
| 903 | 890 | lastfail = hfi1_create_rcvhdrq(dd, rcd); |
| 904 | 891 | if (!lastfail) |
| 905 | 892 | lastfail = hfi1_setup_eagerbufs(rcd); |
| @@ -1120,7 +1107,7 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd) · 214 unmodified lines | ||
| 1120 | 1107 | rcd->egrbufs.rcvtids = NULL; |
| 1121 | 1108 | |
| 1122 | 1109 | for (e = 0; e < rcd->egrbufs.alloced; e++) { |
| 1123 | − if (rcd->egrbufs.buffers[e].dma) | |
| 1110 | + if (rcd->egrbufs.buffers[e].addr) | |
| 1124 | 1111 | dma_free_coherent(&dd->pcidev->dev, |
| 1125 | 1112 | rcd->egrbufs.buffers[e].len, |
| 1126 | 1113 | rcd->egrbufs.buffers[e].addr, |
| @@ -1201,6 +1188,11 @@ void hfi1_free_devdata(struct hfi1_devdata *dd) · 74 unmodified lines | ||
| 1201 | 1188 | dd->tx_opstats = NULL; |
| 1202 | 1189 | kfree(dd->comp_vect); |
| 1203 | 1190 | dd->comp_vect = NULL; |
| 1191 | + if (dd->rcvhdrtail_dummy_kvaddr) | |
| 1192 | + dma_free_coherent(&dd->pcidev->dev, sizeof(u64), | |
| 1193 | + (void *)dd->rcvhdrtail_dummy_kvaddr, | |
| 1194 | + dd->rcvhdrtail_dummy_dma); | |
| 1195 | + dd->rcvhdrtail_dummy_kvaddr = NULL; | |
| 1204 | 1196 | sdma_clean(dd, dd->num_sdma); |
| 1205 | 1197 | rvt_dealloc_device(&dd->verbs_dev.rdi); |
| 1206 | 1198 | } |
| @@ -1298,6 +1290,15 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, · 91 unmodified lines | ||
| 1298 | 1290 | goto bail; |
| 1299 | 1291 | } |
| 1300 | 1292 | |
| 1293 | + /* allocate dummy tail memory for all receive contexts */ | |
| 1294 | + dd->rcvhdrtail_dummy_kvaddr = | |
| 1295 | + dma_alloc_coherent(&dd->pcidev->dev, sizeof(u64), | |
| 1296 | + &dd->rcvhdrtail_dummy_dma, GFP_KERNEL); | |
| 1297 | + if (!dd->rcvhdrtail_dummy_kvaddr) { | |
| 1298 | + ret = -ENOMEM; | |
| 1299 | + goto bail; | |
| 1300 | + } | |
| 1301 | + | |
| 1301 | 1302 | atomic_set(&dd->ipoib_rsm_usr_num, 0); |
| 1302 | 1303 | return dd; |
| 1303 | 1304 | |
| @@ -1505,13 +1506,6 @@ static void cleanup_device_data(struct hfi1_devdata *dd) · 201 unmodified lines | ||
| 1505 | 1506 | |
| 1506 | 1507 | free_credit_return(dd); |
| 1507 | 1508 | |
| 1508 | − if (dd->rcvhdrtail_dummy_kvaddr) { | |
| 1509 | − dma_free_coherent(&dd->pcidev->dev, sizeof(u64), | |
| 1510 | − (void *)dd->rcvhdrtail_dummy_kvaddr, | |
| 1511 | − dd->rcvhdrtail_dummy_dma); | |
| 1512 | − dd->rcvhdrtail_dummy_kvaddr = NULL; | |
| 1513 | − } | |
| 1514 | − | |
| 1515 | 1509 | /* |
| 1516 | 1510 | * Free any resources still in use (usually just kernel contexts) |
| 1517 | 1511 | * at unload; we do for ctxtcnt, because that's what we allocate. |
| @@ -838,8 +838,8 @@ struct sdma_engine *sdma_select_user_engine(struct hfi1_devdata *dd, · 837 unmodified lines | ||
| 838 | 838 | if (current->nr_cpus_allowed != 1) |
| 839 | 839 | goto out; |
| 840 | 840 | |
| 841 | − cpu_id = smp_processor_id(); | |
| 842 | 841 | rcu_read_lock(); |
| 842 | + cpu_id = smp_processor_id(); | |
| 843 | 843 | rht_node = rhashtable_lookup(dd->sdma_rht, &cpu_id, |
| 844 | 844 | sdma_rht_params); |
| 845 | 845 | |
| @@ -1628,8 +1628,7 @@ static int init_cntr_names(const char *names_in, const size_t names_len, · 1627 unmodified lines | ||
| 1628 | 1628 | n++; |
| 1629 | 1629 | |
| 1630 | 1630 | names_out = |
| 1631 | − kmalloc((n + num_extra_names) * sizeof(struct rdma_stat_desc) + | |
| 1632 | − names_len, | |
| 1631 | + kzalloc((n + num_extra_names) * sizeof(*q) + names_len, | |
| 1633 | 1632 | GFP_KERNEL); |
| 1634 | 1633 | if (!names_out) { |
| 1635 | 1634 | *num_cntrs = 0; |
| @@ -1637,7 +1636,7 @@ static int init_cntr_names(const char *names_in, const size_t names_len, · 1 unmodified line | ||
| 1637 | 1636 | return -ENOMEM; |
| 1638 | 1637 | } |
| 1639 | 1638 | |
| 1640 | − p = names_out + (n + num_extra_names) * sizeof(struct rdma_stat_desc); | |
| 1639 | + p = names_out + (n + num_extra_names) * sizeof(*q); | |
| 1641 | 1640 | memcpy(p, names_in, names_len); |
| 1642 | 1641 | |
| 1643 | 1642 | q = (struct rdma_stat_desc *)names_out; |
| @@ -33,6 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #include <linux/acpi.h> |
| 34 | 34 | #include <linux/etherdevice.h> |
| 35 | 35 | #include <linux/interrupt.h> |
| 36 | +#include <linux/iopoll.h> | |
| 36 | 37 | #include <linux/kernel.h> |
| 37 | 38 | #include <linux/types.h> |
| 38 | 39 | #include <net/addrconf.h> |
| @@ -1052,9 +1053,14 @@ static u32 hns_roce_v2_cmd_hw_resetting(struct hns_roce_dev *hr_dev, · 1013 unmodified lines | ||
| 1052 | 1053 | unsigned long instance_stage, |
| 1053 | 1054 | unsigned long reset_stage) |
| 1054 | 1055 | { |
| 1056 | +#define HW_RESET_TIMEOUT_US 1000000 | |
| 1057 | +#define HW_RESET_SLEEP_US 1000 | |
| 1058 | + | |
| 1055 | 1059 | struct hns_roce_v2_priv *priv = hr_dev->priv; |
| 1056 | 1060 | struct hnae3_handle *handle = priv->handle; |
| 1057 | 1061 | const struct hnae3_ae_ops *ops = handle->ae_algo->ops; |
| 1062 | + unsigned long val; | |
| 1063 | + int ret; | |
| 1058 | 1064 | |
| 1059 | 1065 | /* When hardware reset is detected, we should stop sending mailbox&cmq& |
| 1060 | 1066 | * doorbell to hardware. If now in .init_instance() function, we should |
| @@ -1066,7 +1072,11 @@ static u32 hns_roce_v2_cmd_hw_resetting(struct hns_roce_dev *hr_dev, · 5 unmodified lines | ||
| 1066 | 1072 | * again. |
| 1067 | 1073 | */ |
| 1068 | 1074 | hr_dev->dis_db = true; |
| 1069 | − if (!ops->get_hw_reset_stat(handle)) | |
| 1075 | + | |
| 1076 | + ret = read_poll_timeout(ops->ae_dev_reset_cnt, val, | |
| 1077 | + val > hr_dev->reset_cnt, HW_RESET_SLEEP_US, | |
| 1078 | + HW_RESET_TIMEOUT_US, false, handle); | |
| 1079 | + if (!ret) | |
| 1070 | 1080 | hr_dev->is_reset = true; |
| 1071 | 1081 | |
| 1072 | 1082 | if (!hr_dev->is_reset || reset_stage == HNS_ROCE_STATE_RST_INIT || |
| @@ -6391,10 +6401,8 @@ static int hns_roce_hw_v2_reset_notify_down(struct hnae3_handle *handle) · 5318 unmodified lines | ||
| 6391 | 6401 | if (!hr_dev) |
| 6392 | 6402 | return 0; |
| 6393 | 6403 | |
| 6394 | − hr_dev->is_reset = true; | |
| 6395 | 6404 | hr_dev->active = false; |
| 6396 | 6405 | hr_dev->dis_db = true; |
| 6397 | − | |
| 6398 | 6406 | hr_dev->state = HNS_ROCE_DEVICE_STATE_RST_DOWN; |
| 6399 | 6407 | |
| 6400 | 6408 | return 0; |
| @@ -60,6 +60,8 @@ static void irdma_iwarp_ce_handler(struct irdma_sc_cq *iwcq) · 59 unmodified lines | ||
| 60 | 60 | { |
| 61 | 61 | struct irdma_cq *cq = iwcq->back_cq; |
| 62 | 62 | |
| 63 | + if (!cq->user_mode) | |
| 64 | + cq->armed = false; | |
| 63 | 65 | if (cq->ibcq.comp_handler) |
| 64 | 66 | cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); |
| 65 | 67 | } |
| @@ -146,6 +148,7 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp, · 80 unmodified lines | ||
| 146 | 148 | qp->flush_code = FLUSH_PROT_ERR; |
| 147 | 149 | break; |
| 148 | 150 | case IRDMA_AE_AMP_BAD_QP: |
| 151 | + case IRDMA_AE_WQE_UNEXPECTED_OPCODE: | |
| 149 | 152 | qp->flush_code = FLUSH_LOC_QP_OP_ERR; |
| 150 | 153 | break; |
| 151 | 154 | case IRDMA_AE_AMP_BAD_STAG_KEY: |
| @@ -156,7 +159,6 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp, · 4 unmodified lines | ||
| 156 | 159 | case IRDMA_AE_PRIV_OPERATION_DENIED: |
| 157 | 160 | case IRDMA_AE_IB_INVALID_REQUEST: |
| 158 | 161 | case IRDMA_AE_IB_REMOTE_ACCESS_ERROR: |
| 159 | − case IRDMA_AE_IB_REMOTE_OP_ERROR: | |
| 160 | 162 | qp->flush_code = FLUSH_REM_ACCESS_ERR; |
| 161 | 163 | qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; |
| 162 | 164 | break; |
| @@ -184,6 +186,9 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp, · 21 unmodified lines | ||
| 184 | 186 | case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS: |
| 185 | 187 | qp->flush_code = FLUSH_MW_BIND_ERR; |
| 186 | 188 | break; |
| 189 | + case IRDMA_AE_IB_REMOTE_OP_ERROR: | |
| 190 | + qp->flush_code = FLUSH_REM_OP_ERR; | |
| 191 | + break; | |
| 187 | 192 | default: |
| 188 | 193 | qp->flush_code = FLUSH_FATAL_ERR; |
| 189 | 194 | break; |
| @@ -542,6 +542,7 @@ int irdma_ah_cqp_op(struct irdma_pci_f *rf, struct irdma_sc_ah *sc_ah, u8 cmd, · 541 unmodified lines | ||
| 542 | 542 | void (*callback_fcn)(struct irdma_cqp_request *cqp_request), |
| 543 | 543 | void *cb_param); |
| 544 | 544 | void irdma_gsi_ud_qp_ah_cb(struct irdma_cqp_request *cqp_request); |
| 545 | +bool irdma_cq_empty(struct irdma_cq *iwcq); | |
| 545 | 546 | int irdma_inetaddr_event(struct notifier_block *notifier, unsigned long event, |
| 546 | 547 | void *ptr); |
| 547 | 548 | int irdma_inet6addr_event(struct notifier_block *notifier, unsigned long event, |
| @@ -25,8 +25,7 @@ void irdma_destroy_pble_prm(struct irdma_hmc_pble_rsrc *pble_rsrc) · 24 unmodified lines | ||
| 25 | 25 | list_del(&chunk->list); |
| 26 | 26 | if (chunk->type == PBLE_SD_PAGED) |
| 27 | 27 | irdma_pble_free_paged_mem(chunk); |
| 28 | − if (chunk->bitmapbuf) | |
| 29 | − kfree(chunk->bitmapmem.va); | |
| 28 | + bitmap_free(chunk->bitmapbuf); | |
| 30 | 29 | kfree(chunk->chunkmem.va); |
| 31 | 30 | } |
| 32 | 31 | } |
| @@ -283,7 +282,6 @@ add_pble_prm(struct irdma_hmc_pble_rsrc *pble_rsrc) · 250 unmodified lines | ||
| 283 | 282 | "PBLE: next_fpm_addr = %llx chunk_size[%llu] = 0x%llx\n", |
| 284 | 283 | pble_rsrc->next_fpm_addr, chunk->size, chunk->size); |
| 285 | 284 | pble_rsrc->unallocated_pble -= (u32)(chunk->size >> 3); |
| 286 | − list_add(&chunk->list, &pble_rsrc->pinfo.clist); | |
| 287 | 285 | sd_reg_val = (sd_entry_type == IRDMA_SD_TYPE_PAGED) ? |
| 288 | 286 | sd_entry->u.pd_table.pd_page_addr.pa : |
| 289 | 287 | sd_entry->u.bp.addr.pa; |
| @@ -295,12 +293,12 @@ add_pble_prm(struct irdma_hmc_pble_rsrc *pble_rsrc) · 5 unmodified lines | ||
| 295 | 293 | goto error; |
| 296 | 294 | } |
| 297 | 295 | |
| 296 | + list_add(&chunk->list, &pble_rsrc->pinfo.clist); | |
| 298 | 297 | sd_entry->valid = true; |
| 299 | 298 | return 0; |
| 300 | 299 | |
| 301 | 300 | error: |
| 302 | − if (chunk->bitmapbuf) | |
| 303 | − kfree(chunk->bitmapmem.va); | |
| 301 | + bitmap_free(chunk->bitmapbuf); | |
| 304 | 302 | kfree(chunk->chunkmem.va); |
| 305 | 303 | |
| 306 | 304 | return ret_code; |
| @@ -78,7 +78,6 @@ struct irdma_chunk { · 77 unmodified lines | ||
| 78 | 78 | u32 pg_cnt; |
| 79 | 79 | enum irdma_alloc_type type; |
| 80 | 80 | struct irdma_sc_dev *dev; |
| 81 | − struct irdma_virt_mem bitmapmem; | |
| 82 | 81 | struct irdma_virt_mem chunkmem; |
| 83 | 82 | }; |
| 84 | 83 | |
| @@ -2239,15 +2239,10 @@ enum irdma_status_code irdma_prm_add_pble_mem(struct irdma_pble_prm *pprm, · 2238 unmodified lines | ||
| 2239 | 2239 | |
| 2240 | 2240 | sizeofbitmap = (u64)pchunk->size >> pprm->pble_shift; |
| 2241 | 2241 | |
| 2242 | − pchunk->bitmapmem.size = sizeofbitmap >> 3; | |
| 2243 | − pchunk->bitmapmem.va = kzalloc(pchunk->bitmapmem.size, GFP_KERNEL); | |
| 2244 | − | |
| 2245 | − if (!pchunk->bitmapmem.va) | |
| 2242 | + pchunk->bitmapbuf = bitmap_zalloc(sizeofbitmap, GFP_KERNEL); | |
| 2243 | + if (!pchunk->bitmapbuf) | |
| 2246 | 2244 | return IRDMA_ERR_NO_MEMORY; |
| 2247 | 2245 | |
| 2248 | − pchunk->bitmapbuf = pchunk->bitmapmem.va; | |
| 2249 | − bitmap_zero(pchunk->bitmapbuf, sizeofbitmap); | |
| 2250 | − | |
| 2251 | 2246 | pchunk->sizeofbitmap = sizeofbitmap; |
| 2252 | 2247 | /* each pble is 8 bytes hence shift by 3 */ |
| 2253 | 2248 | pprm->total_pble_alloc += pchunk->size >> 3; |
| @@ -2491,3 +2486,18 @@ void irdma_ib_qp_event(struct irdma_qp *iwqp, enum irdma_qp_event_type event) · 237 unmodified lines | ||
| 2491 | 2486 | ibevent.element.qp = &iwqp->ibqp; |
| 2492 | 2487 | iwqp->ibqp.event_handler(&ibevent, iwqp->ibqp.qp_context); |
| 2493 | 2488 | } |
| 2489 | + | |
| 2490 | +bool irdma_cq_empty(struct irdma_cq *iwcq) | |
| 2491 | +{ | |
| 2492 | + struct irdma_cq_uk *ukcq; | |
| 2493 | + u64 qword3; | |
| 2494 | + __le64 *cqe; | |
| 2495 | + u8 polarity; | |
| 2496 | + | |
| 2497 | + ukcq = &iwcq->sc_cq.cq_uk; | |
| 2498 | + cqe = IRDMA_GET_CURRENT_CQ_ELEM(ukcq); | |
| 2499 | + get_64bit_val(cqe, 24, &qword3); | |
| 2500 | + polarity = (u8)FIELD_GET(IRDMA_CQ_VALID, qword3); | |
| 2501 | + | |
| 2502 | + return polarity != ukcq->polarity; | |
| 2503 | +} | |
| @@ -3585,18 +3585,31 @@ static int irdma_req_notify_cq(struct ib_cq *ibcq, · 3584 unmodified lines | ||
| 3585 | 3585 | struct irdma_cq *iwcq; |
| 3586 | 3586 | struct irdma_cq_uk *ukcq; |
| 3587 | 3587 | unsigned long flags; |
| 3588 | − enum irdma_cmpl_notify cq_notify = IRDMA_CQ_COMPL_EVENT; | |
| 3588 | + enum irdma_cmpl_notify cq_notify; | |
| 3589 | + bool promo_event = false; | |
| 3590 | + int ret = 0; | |
| 3589 | 3591 | |
| 3592 | + cq_notify = notify_flags == IB_CQ_SOLICITED ? | |
| 3593 | + IRDMA_CQ_COMPL_SOLICITED : IRDMA_CQ_COMPL_EVENT; | |
| 3590 | 3594 | iwcq = to_iwcq(ibcq); |
| 3591 | 3595 | ukcq = &iwcq->sc_cq.cq_uk; |
| 3592 | − if (notify_flags == IB_CQ_SOLICITED) | |
| 3593 | − cq_notify = IRDMA_CQ_COMPL_SOLICITED; | |
| 3594 | 3596 | |
| 3595 | 3597 | spin_lock_irqsave(&iwcq->lock, flags); |
| 3596 | − irdma_uk_cq_request_notification(ukcq, cq_notify); | |
| 3598 | + /* Only promote to arm the CQ for any event if the last arm event was solicited. */ | |
| 3599 | + if (iwcq->last_notify == IRDMA_CQ_COMPL_SOLICITED && notify_flags != IB_CQ_SOLICITED) | |
| 3600 | + promo_event = true; | |
| 3601 | + | |
| 3602 | + if (!iwcq->armed || promo_event) { | |
| 3603 | + iwcq->armed = true; | |
| 3604 | + iwcq->last_notify = cq_notify; | |
| 3605 | + irdma_uk_cq_request_notification(ukcq, cq_notify); | |
| 3606 | + } | |
| 3607 | + | |
| 3608 | + if ((notify_flags & IB_CQ_REPORT_MISSED_EVENTS) && !irdma_cq_empty(iwcq)) | |
| 3609 | + ret = 1; | |
| 3597 | 3610 | spin_unlock_irqrestore(&iwcq->lock, flags); |
| 3598 | 3611 | |
| 3599 | − return 0; | |
| 3612 | + return ret; | |
| 3600 | 3613 | } |
| 3601 | 3614 | |
| 3602 | 3615 | static int irdma_roce_port_immutable(struct ib_device *ibdev, u32 port_num, |
| @@ -110,6 +110,8 @@ struct irdma_cq { · 109 unmodified lines | ||
| 110 | 110 | u16 cq_size; |
| 111 | 111 | u16 cq_num; |
| 112 | 112 | bool user_mode; |
| 113 | + bool armed; | |
| 114 | + enum irdma_cmpl_notify last_notify; | |
| 113 | 115 | u32 polled_cmpls; |
| 114 | 116 | u32 cq_mem_size; |
| 115 | 117 | struct irdma_dma_mem kmem; |
| @@ -2215,6 +2215,11 @@ static const struct ib_device_ops mlx4_ib_hw_stats_ops = { · 2214 unmodified lines | ||
| 2215 | 2215 | .get_hw_stats = mlx4_ib_get_hw_stats, |
| 2216 | 2216 | }; |
| 2217 | 2217 | |
| 2218 | +static const struct ib_device_ops mlx4_ib_hw_stats_ops1 = { | |
| 2219 | + .alloc_hw_device_stats = mlx4_ib_alloc_hw_device_stats, | |
| 2220 | + .get_hw_stats = mlx4_ib_get_hw_stats, | |
| 2221 | +}; | |
| 2222 | + | |
| 2218 | 2223 | static int mlx4_ib_alloc_diag_counters(struct mlx4_ib_dev *ibdev) |
| 2219 | 2224 | { |
| 2220 | 2225 | struct mlx4_ib_diag_counters *diag = ibdev->diag_counters; |
| @@ -2227,9 +2232,16 @@ static int mlx4_ib_alloc_diag_counters(struct mlx4_ib_dev *ibdev) · 6 unmodified lines | ||
| 2227 | 2232 | return 0; |
| 2228 | 2233 | |
| 2229 | 2234 | for (i = 0; i < MLX4_DIAG_COUNTERS_TYPES; i++) { |
| 2230 | − /* i == 1 means we are building port counters */ | |
| 2231 | − if (i && !per_port) | |
| 2232 | − continue; | |
| 2235 | + /* | |
| 2236 | + * i == 1 means we are building port counters, set a different | |
| 2237 | + * stats ops without port stats callback. | |
| 2238 | + */ | |
| 2239 | + if (i && !per_port) { | |
| 2240 | + ib_set_device_ops(&ibdev->ib_dev, | |
| 2241 | + &mlx4_ib_hw_stats_ops1); | |
| 2242 | + | |
| 2243 | + return 0; | |
| 2244 | + } | |
| 2233 | 2245 | |
| 2234 | 2246 | ret = __mlx4_ib_alloc_diag_counters(ibdev, &diag[i].descs, |
| 2235 | 2247 | &diag[i].offset, |
| @@ -664,7 +664,6 @@ struct mlx5_ib_mr { · 663 unmodified lines | ||
| 664 | 664 | |
| 665 | 665 | /* User MR data */ |
| 666 | 666 | struct mlx5_cache_ent *cache_ent; |
| 667 | − struct ib_umem *umem; | |
| 668 | 667 | |
| 669 | 668 | /* This is zero'd when the MR is allocated */ |
| 670 | 669 | union { |
| @@ -676,7 +675,7 @@ struct mlx5_ib_mr { · 5 unmodified lines | ||
| 676 | 675 | struct list_head list; |
| 677 | 676 | }; |
| 678 | 677 | |
| 679 | − /* Used only by kernel MRs (umem == NULL) */ | |
| 678 | + /* Used only by kernel MRs */ | |
| 680 | 679 | struct { |
| 681 | 680 | void *descs; |
| 682 | 681 | void *descs_alloc; |
| @@ -697,8 +696,9 @@ struct mlx5_ib_mr { · 14 unmodified lines | ||
| 697 | 696 | int data_length; |
| 698 | 697 | }; |
| 699 | 698 | |
| 700 | − /* Used only by User MRs (umem != NULL) */ | |
| 699 | + /* Used only by User MRs */ | |
| 701 | 700 | struct { |
| 701 | + struct ib_umem *umem; | |
| 702 | 702 | unsigned int page_shift; |
| 703 | 703 | /* Current access_flags */ |
| 704 | 704 | int access_flags; |
| @@ -1904,19 +1904,18 @@ err: · 1903 unmodified lines | ||
| 1904 | 1904 | return ret; |
| 1905 | 1905 | } |
| 1906 | 1906 | |
| 1907 | −static void | |
| 1908 | −mlx5_free_priv_descs(struct mlx5_ib_mr *mr) | |
| 1907 | +static void mlx5_free_priv_descs(struct mlx5_ib_mr *mr) | |
| 1909 | 1908 | { |
| 1910 | − if (!mr->umem && mr->descs) { | |
| 1911 | − struct ib_device *device = mr->ibmr.device; | |
| 1912 | − int size = mr->max_descs * mr->desc_size; | |
| 1913 | − struct mlx5_ib_dev *dev = to_mdev(device); | |
| 1909 | + struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device); | |
| 1910 | + int size = mr->max_descs * mr->desc_size; | |
| 1914 | 1911 | |
| 1915 | − dma_unmap_single(&dev->mdev->pdev->dev, mr->desc_map, size, | |
| 1916 | − DMA_TO_DEVICE); | |
| 1917 | − kfree(mr->descs_alloc); | |
| 1918 | − mr->descs = NULL; | |
| 1919 | − } | |
| 1912 | + if (!mr->descs) | |
| 1913 | + return; | |
| 1914 | + | |
| 1915 | + dma_unmap_single(&dev->mdev->pdev->dev, mr->desc_map, size, | |
| 1916 | + DMA_TO_DEVICE); | |
| 1917 | + kfree(mr->descs_alloc); | |
| 1918 | + mr->descs = NULL; | |
| 1920 | 1919 | } |
| 1921 | 1920 | |
| 1922 | 1921 | int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) |
| @@ -1992,7 +1991,8 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) · 69 unmodified lines | ||
| 1992 | 1991 | if (mr->cache_ent) { |
| 1993 | 1992 | mlx5_mr_cache_free(dev, mr); |
| 1994 | 1993 | } else { |
| 1995 | − mlx5_free_priv_descs(mr); | |
| 1994 | + if (!udata) | |
| 1995 | + mlx5_free_priv_descs(mr); | |
| 1996 | 1996 | kfree(mr); |
| 1997 | 1997 | } |
| 1998 | 1998 | return 0; |
| @@ -2079,7 +2079,6 @@ static struct mlx5_ib_mr *mlx5_ib_alloc_pi_mr(struct ib_pd *pd, · 80 unmodified lines | ||
| 2079 | 2079 | if (err) |
| 2080 | 2080 | goto err_free_in; |
| 2081 | 2081 | |
| 2082 | − mr->umem = NULL; | |
| 2083 | 2082 | kfree(in); |
| 2084 | 2083 | |
| 2085 | 2084 | return mr; |
| @@ -2206,7 +2205,6 @@ static struct ib_mr *__mlx5_ib_alloc_mr(struct ib_pd *pd, · 120 unmodified lines | ||
| 2206 | 2205 | } |
| 2207 | 2206 | |
| 2208 | 2207 | mr->ibmr.device = pd->device; |
| 2209 | − mr->umem = NULL; | |
| 2210 | 2208 | |
| 2211 | 2209 | switch (mr_type) { |
| 2212 | 2210 | case IB_MR_TYPE_MEM_REG: |
| @@ -359,6 +359,7 @@ int rxe_qp_from_init(struct rxe_dev *rxe, struct rxe_qp *qp, struct rxe_pd *pd, · 358 unmodified lines | ||
| 359 | 359 | |
| 360 | 360 | err2: |
| 361 | 361 | rxe_queue_cleanup(qp->sq.queue); |
| 362 | + qp->sq.queue = NULL; | |
| 362 | 363 | err1: |
| 363 | 364 | qp->pd = NULL; |
| 364 | 365 | qp->rcq = NULL; |
| @@ -19,7 +19,7 @@ void rtrs_clt_update_wc_stats(struct rtrs_clt_con *con) · 18 unmodified lines | ||
| 19 | 19 | int cpu; |
| 20 | 20 | |
| 21 | 21 | cpu = raw_smp_processor_id(); |
| 22 | − s = this_cpu_ptr(stats->pcpu_stats); | |
| 22 | + s = get_cpu_ptr(stats->pcpu_stats); | |
| 23 | 23 | if (con->cpu != cpu) { |
| 24 | 24 | s->cpu_migr.to++; |
| 25 | 25 | |
| @@ -27,14 +27,16 @@ void rtrs_clt_update_wc_stats(struct rtrs_clt_con *con) · 1 unmodified line | ||
| 27 | 27 | s = per_cpu_ptr(stats->pcpu_stats, con->cpu); |
| 28 | 28 | atomic_inc(&s->cpu_migr.from); |
| 29 | 29 | } |
| 30 | + put_cpu_ptr(stats->pcpu_stats); | |
| 30 | 31 | } |
| 31 | 32 | |
| 32 | 33 | void rtrs_clt_inc_failover_cnt(struct rtrs_clt_stats *stats) |
| 33 | 34 | { |
| 34 | 35 | struct rtrs_clt_stats_pcpu *s; |
| 35 | 36 | |
| 36 | − s = this_cpu_ptr(stats->pcpu_stats); | |
| 37 | + s = get_cpu_ptr(stats->pcpu_stats); | |
| 37 | 38 | s->rdma.failover_cnt++; |
| 39 | + put_cpu_ptr(stats->pcpu_stats); | |
| 38 | 40 | } |
| 39 | 41 | |
| 40 | 42 | int rtrs_clt_stats_migration_from_cnt_to_str(struct rtrs_clt_stats *stats, char *buf) |
| @@ -169,9 +171,10 @@ static inline void rtrs_clt_update_rdma_stats(struct rtrs_clt_stats *stats, · 128 unmodified lines | ||
| 169 | 171 | { |
| 170 | 172 | struct rtrs_clt_stats_pcpu *s; |
| 171 | 173 | |
| 172 | − s = this_cpu_ptr(stats->pcpu_stats); | |
| 174 | + s = get_cpu_ptr(stats->pcpu_stats); | |
| 173 | 175 | s->rdma.dir[d].cnt++; |
| 174 | 176 | s->rdma.dir[d].size_total += size; |
| 177 | + put_cpu_ptr(stats->pcpu_stats); | |
| 175 | 178 | } |
| 176 | 179 | |
| 177 | 180 | void rtrs_clt_update_all_stats(struct rtrs_clt_io_req *req, int dir) |
| @@ -542,6 +542,7 @@ static struct xenbus_driver xenkbd_driver = { · 541 unmodified lines | ||
| 542 | 542 | .remove = xenkbd_remove, |
| 543 | 543 | .resume = xenkbd_resume, |
| 544 | 544 | .otherend_changed = xenkbd_backend_changed, |
| 545 | + .not_essential = true, | |
| 545 | 546 | }; |
| 546 | 547 | |
| 547 | 548 | static int __init xenkbd_init(void) |
| @@ -929,10 +929,8 @@ static int __init amd_iommu_v2_init(void) · 928 unmodified lines | ||
| 929 | 929 | { |
| 930 | 930 | int ret; |
| 931 | 931 | |
| 932 | − pr_info("AMD IOMMUv2 driver by Joerg Roedel <jroedel@suse.de>\n"); | |
| 933 | − | |
| 934 | 932 | if (!amd_iommu_v2_supported()) { |
| 935 | − pr_info("AMD IOMMUv2 functionality not available on this system\n"); | |
| 933 | + pr_info("AMD IOMMUv2 functionality not available on this system - This is not a bug.\n"); | |
| 936 | 934 | /* |
| 937 | 935 | * Load anyway to provide the symbols to other modules |
| 938 | 936 | * which may use AMD IOMMUv2 optionally. |
| @@ -947,6 +945,8 @@ static int __init amd_iommu_v2_init(void) · 8 unmodified lines | ||
| 947 | 945 | |
| 948 | 946 | amd_iommu_register_ppr_notifier(&ppr_nb); |
| 949 | 947 | |
| 948 | + pr_info("AMD IOMMUv2 loaded and initialized\n"); | |
| 949 | + | |
| 950 | 950 | return 0; |
| 951 | 951 | |
| 952 | 952 | out: |
| @@ -144,6 +144,7 @@ static int cap_audit_static(struct intel_iommu *iommu, enum cap_audit_type type) · 143 unmodified lines | ||
| 144 | 144 | { |
| 145 | 145 | struct dmar_drhd_unit *d; |
| 146 | 146 | struct intel_iommu *i; |
| 147 | + int rc = 0; | |
| 147 | 148 | |
| 148 | 149 | rcu_read_lock(); |
| 149 | 150 | if (list_empty(&dmar_drhd_units)) |
| @@ -169,11 +170,11 @@ static int cap_audit_static(struct intel_iommu *iommu, enum cap_audit_type type) · 19 unmodified lines | ||
| 169 | 170 | */ |
| 170 | 171 | if (intel_cap_smts_sanity() && |
| 171 | 172 | !intel_cap_flts_sanity() && !intel_cap_slts_sanity()) |
| 172 | − return -EOPNOTSUPP; | |
| 173 | + rc = -EOPNOTSUPP; | |
| 173 | 174 | |
| 174 | 175 | out: |
| 175 | 176 | rcu_read_unlock(); |
| 176 | − return 0; | |
| 177 | + return rc; | |
| 177 | 178 | } |
| 178 | 179 | |
| 179 | 180 | int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu) |
| @@ -1339,13 +1339,11 @@ static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level, · 1338 unmodified lines | ||
| 1339 | 1339 | pte = &pte[pfn_level_offset(pfn, level)]; |
| 1340 | 1340 | |
| 1341 | 1341 | do { |
| 1342 | − unsigned long level_pfn; | |
| 1342 | + unsigned long level_pfn = pfn & level_mask(level); | |
| 1343 | 1343 | |
| 1344 | 1344 | if (!dma_pte_present(pte)) |
| 1345 | 1345 | goto next; |
| 1346 | 1346 | |
| 1347 | − level_pfn = pfn & level_mask(level); | |
| 1348 | − | |
| 1349 | 1347 | /* If range covers entire pagetable, free it */ |
| 1350 | 1348 | if (start_pfn <= level_pfn && |
| 1351 | 1349 | last_pfn >= level_pfn + level_size(level) - 1) { |
| @@ -1366,7 +1364,7 @@ static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level, · 14 unmodified lines | ||
| 1366 | 1364 | freelist); |
| 1367 | 1365 | } |
| 1368 | 1366 | next: |
| 1369 | − pfn += level_size(level); | |
| 1367 | + pfn = level_pfn + level_size(level); | |
| 1370 | 1368 | } while (!first_pte_in_page(++pte) && pfn <= last_pfn); |
| 1371 | 1369 | |
| 1372 | 1370 | if (first_pte) |
| @@ -200,8 +200,8 @@ static inline phys_addr_t rk_dte_pt_address(u32 dte) · 199 unmodified lines | ||
| 200 | 200 | #define DTE_HI_MASK2 GENMASK(7, 4) |
| 201 | 201 | #define DTE_HI_SHIFT1 24 /* shift bit 8 to bit 32 */ |
| 202 | 202 | #define DTE_HI_SHIFT2 32 /* shift bit 4 to bit 36 */ |
| 203 | −#define PAGE_DESC_HI_MASK1 GENMASK_ULL(39, 36) | |
| 204 | −#define PAGE_DESC_HI_MASK2 GENMASK_ULL(35, 32) | |
| 203 | +#define PAGE_DESC_HI_MASK1 GENMASK_ULL(35, 32) | |
| 204 | +#define PAGE_DESC_HI_MASK2 GENMASK_ULL(39, 36) | |
| 205 | 205 | |
| 206 | 206 | static inline phys_addr_t rk_dte_pt_address_v2(u32 dte) |
| 207 | 207 | { |
| @@ -707,7 +707,7 @@ static const struct irq_domain_ops aic_ipi_domain_ops = { · 706 unmodified lines | ||
| 707 | 707 | .free = aic_ipi_free, |
| 708 | 708 | }; |
| 709 | 709 | |
| 710 | −static int aic_init_smp(struct aic_irq_chip *irqc, struct device_node *node) | |
| 710 | +static int __init aic_init_smp(struct aic_irq_chip *irqc, struct device_node *node) | |
| 711 | 711 | { |
| 712 | 712 | struct irq_domain *ipi_domain; |
| 713 | 713 | int base_ipi; |
| @@ -232,16 +232,12 @@ static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq, · 231 unmodified lines | ||
| 232 | 232 | int hwirq, i; |
| 233 | 233 | |
| 234 | 234 | mutex_lock(&msi_used_lock); |
| 235 | + hwirq = bitmap_find_free_region(msi_used, PCI_MSI_DOORBELL_NR, | |
| 236 | + order_base_2(nr_irqs)); | |
| 237 | + mutex_unlock(&msi_used_lock); | |
| 235 | 238 | |
| 236 | − hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR, | |
| 237 | − 0, nr_irqs, 0); | |
| 238 | − if (hwirq >= PCI_MSI_DOORBELL_NR) { | |
| 239 | − mutex_unlock(&msi_used_lock); | |
| 239 | + if (hwirq < 0) | |
| 240 | 240 | return -ENOSPC; |
| 241 | − } | |
| 242 | − | |
| 243 | − bitmap_set(msi_used, hwirq, nr_irqs); | |
| 244 | − mutex_unlock(&msi_used_lock); | |
| 245 | 241 | |
| 246 | 242 | for (i = 0; i < nr_irqs; i++) { |
| 247 | 243 | irq_domain_set_info(domain, virq + i, hwirq + i, |
| @@ -250,7 +246,7 @@ static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq, · 2 unmodified lines | ||
| 250 | 246 | NULL, NULL); |
| 251 | 247 | } |
| 252 | 248 | |
| 253 | − return hwirq; | |
| 249 | + return 0; | |
| 254 | 250 | } |
| 255 | 251 | |
| 256 | 252 | static void armada_370_xp_msi_free(struct irq_domain *domain, |
| @@ -259,7 +255,7 @@ static void armada_370_xp_msi_free(struct irq_domain *domain, · 2 unmodified lines | ||
| 259 | 255 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); |
| 260 | 256 | |
| 261 | 257 | mutex_lock(&msi_used_lock); |
| 262 | − bitmap_clear(msi_used, d->hwirq, nr_irqs); | |
| 258 | + bitmap_release_region(msi_used, d->hwirq, order_base_2(nr_irqs)); | |
| 263 | 259 | mutex_unlock(&msi_used_lock); |
| 264 | 260 | } |
| 265 | 261 | |
| @@ -76,8 +76,8 @@ static void aspeed_scu_ic_irq_handler(struct irq_desc *desc) · 75 unmodified lines | ||
| 76 | 76 | generic_handle_domain_irq(scu_ic->irq_domain, |
| 77 | 77 | bit - scu_ic->irq_shift); |
| 78 | 78 | |
| 79 | − regmap_update_bits(scu_ic->scu, scu_ic->reg, mask, | |
| 80 | − BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT)); | |
| 79 | + regmap_write_bits(scu_ic->scu, scu_ic->reg, mask, | |
| 80 | + BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT)); | |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | 83 | chained_irq_exit(chip, desc); |
| @@ -238,6 +238,7 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, · 237 unmodified lines | ||
| 238 | 238 | } |
| 239 | 239 | |
| 240 | 240 | data->num_parent_irqs = platform_irq_count(pdev); |
| 241 | + put_device(&pdev->dev); | |
| 241 | 242 | if (data->num_parent_irqs <= 0) { |
| 242 | 243 | pr_err("invalid number of parent interrupts\n"); |
| 243 | 244 | ret = -ENOMEM; |
| @@ -742,7 +742,7 @@ static struct its_collection *its_build_invall_cmd(struct its_node *its, · 741 unmodified lines | ||
| 742 | 742 | |
| 743 | 743 | its_fixup_cmd(cmd); |
| 744 | 744 | |
| 745 | − return NULL; | |
| 745 | + return desc->its_invall_cmd.col; | |
| 746 | 746 | } |
| 747 | 747 | |
| 748 | 748 | static struct its_vpe *its_build_vinvall_cmd(struct its_node *its, |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #define pr_fmt(fmt) "irq-mips-gic: " fmt |
| 11 | 11 | |
| 12 | +#include <linux/bitfield.h> | |
| 12 | 13 | #include <linux/bitmap.h> |
| 13 | 14 | #include <linux/clocksource.h> |
| 14 | 15 | #include <linux/cpuhotplug.h> |
| @@ -735,8 +736,7 @@ static int __init gic_of_init(struct device_node *node, · 720 unmodified lines | ||
| 735 | 736 | mips_gic_base = ioremap(gic_base, gic_len); |
| 736 | 737 | |
| 737 | 738 | gicconfig = read_gic_config(); |
| 738 | − gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; | |
| 739 | − gic_shared_intrs >>= __ffs(GIC_CONFIG_NUMINTERRUPTS); | |
| 739 | + gic_shared_intrs = FIELD_GET(GIC_CONFIG_NUMINTERRUPTS, gicconfig); | |
| 740 | 740 | gic_shared_intrs = (gic_shared_intrs + 1) * 8; |
| 741 | 741 | |
| 742 | 742 | if (cpu_has_veic) { |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #define NVIC_ISER 0x000 |
| 28 | 28 | #define NVIC_ICER 0x080 |
| 29 | −#define NVIC_IPR 0x300 | |
| 29 | +#define NVIC_IPR 0x400 | |
| 30 | 30 | |
| 31 | 31 | #define NVIC_MAX_BANKS 16 |
| 32 | 32 | /* |
| @@ -2189,6 +2189,7 @@ super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) · 2188 unmodified lines | ||
| 2189 | 2189 | |
| 2190 | 2190 | if (!num_sectors || num_sectors > max_sectors) |
| 2191 | 2191 | num_sectors = max_sectors; |
| 2192 | + rdev->sb_start = sb_start; | |
| 2192 | 2193 | } |
| 2193 | 2194 | sb = page_address(rdev->sb_page); |
| 2194 | 2195 | sb->data_size = cpu_to_le64(num_sectors); |
| @@ -6270,7 +6271,8 @@ static void __md_stop(struct mddev *mddev) · 4075 unmodified lines | ||
| 6270 | 6271 | spin_lock(&mddev->lock); |
| 6271 | 6272 | mddev->pers = NULL; |
| 6272 | 6273 | spin_unlock(&mddev->lock); |
| 6273 | − pers->free(mddev, mddev->private); | |
| 6274 | + if (mddev->private) | |
| 6275 | + pers->free(mddev, mddev->private); | |
| 6274 | 6276 | mddev->private = NULL; |
| 6275 | 6277 | if (pers->sync_request && mddev->to_remove == NULL) |
| 6276 | 6278 | mddev->to_remove = &md_redundancy_group; |
| @@ -1199,6 +1199,7 @@ void cec_received_msg_ts(struct cec_adapter *adap, · 1198 unmodified lines | ||
| 1199 | 1199 | if (abort) |
| 1200 | 1200 | dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT; |
| 1201 | 1201 | msg->flags = dst->flags; |
| 1202 | + msg->sequence = dst->sequence; | |
| 1202 | 1203 | /* Remove it from the wait_queue */ |
| 1203 | 1204 | list_del_init(&data->list); |
| 1204 | 1205 | |
| @@ -241,6 +241,7 @@ static void *vb2_dma_sg_get_userptr(struct vb2_buffer *vb, struct device *dev, · 240 unmodified lines | ||
| 241 | 241 | buf->offset = vaddr & ~PAGE_MASK; |
| 242 | 242 | buf->size = size; |
| 243 | 243 | buf->dma_sgt = &buf->sg_table; |
| 244 | + buf->vb = vb; | |
| 244 | 245 | vec = vb2_create_framevec(vaddr, size); |
| 245 | 246 | if (IS_ERR(vec)) |
| 246 | 247 | goto userptr_fail_pfnvec; |
| @@ -642,6 +643,7 @@ static void *vb2_dma_sg_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, · 395 unmodified lines | ||
| 642 | 643 | buf->dma_dir = vb->vb2_queue->dma_dir; |
| 643 | 644 | buf->size = size; |
| 644 | 645 | buf->db_attach = dba; |
| 646 | + buf->vb = vb; | |
| 645 | 647 | |
| 646 | 648 | return buf; |
| 647 | 649 | } |
| @@ -7,9 +7,9 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/gpio/consumer.h> |
| 8 | 8 | #include <linux/i2c.h> |
| 9 | 9 | #include <linux/module.h> |
| 10 | −#include <linux/of_graph.h> | |
| 11 | 10 | #include <linux/pm_runtime.h> |
| 12 | 11 | #include <linux/pm.h> |
| 12 | +#include <linux/property.h> | |
| 13 | 13 | #include <linux/regulator/consumer.h> |
| 14 | 14 | #include <media/v4l2-ctrls.h> |
| 15 | 15 | #include <media/v4l2-device.h> |
| @@ -2176,7 +2176,7 @@ static struct i2c_driver hi846_i2c_driver = { · 2160 unmodified lines | ||
| 2176 | 2176 | .driver = { |
| 2177 | 2177 | .name = "hi846", |
| 2178 | 2178 | .pm = &hi846_pm_ops, |
| 2179 | − .of_match_table = of_match_ptr(hi846_of_match), | |
| 2179 | + .of_match_table = hi846_of_match, | |
| 2180 | 2180 | }, |
| 2181 | 2181 | .probe_new = hi846_probe, |
| 2182 | 2182 | .remove = hi846_remove, |
| @@ -751,10 +751,6 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *p64, · 750 unmodified lines | ||
| 751 | 751 | /* |
| 752 | 752 | * x86 is the only compat architecture with different struct alignment |
| 753 | 753 | * between 32-bit and 64-bit tasks. |
| 754 | − * | |
| 755 | − * On all other architectures, v4l2_event32 and v4l2_event32_time32 are | |
| 756 | − * the same as v4l2_event and v4l2_event_time32, so we can use the native | |
| 757 | − * handlers, converting v4l2_event to v4l2_event_time32 if necessary. | |
| 758 | 754 | */ |
| 759 | 755 | struct v4l2_event32 { |
| 760 | 756 | __u32 type; |
| @@ -772,21 +768,6 @@ struct v4l2_event32 { · 11 unmodified lines | ||
| 772 | 768 | __u32 reserved[8]; |
| 773 | 769 | }; |
| 774 | 770 | |
| 775 | −#ifdef CONFIG_COMPAT_32BIT_TIME | |
| 776 | −struct v4l2_event32_time32 { | |
| 777 | − __u32 type; | |
| 778 | − union { | |
| 779 | − compat_s64 value64; | |
| 780 | − __u8 data[64]; | |
| 781 | − } u; | |
| 782 | − __u32 pending; | |
| 783 | − __u32 sequence; | |
| 784 | − struct old_timespec32 timestamp; | |
| 785 | − __u32 id; | |
| 786 | − __u32 reserved[8]; | |
| 787 | −}; | |
| 788 | −#endif | |
| 789 | − | |
| 790 | 771 | static int put_v4l2_event32(struct v4l2_event *p64, |
| 791 | 772 | struct v4l2_event32 __user *p32) |
| 792 | 773 | { |
| @@ -802,7 +783,22 @@ static int put_v4l2_event32(struct v4l2_event *p64, · 9 unmodified lines | ||
| 802 | 783 | return 0; |
| 803 | 784 | } |
| 804 | 785 | |
| 786 | +#endif | |
| 787 | + | |
| 805 | 788 | #ifdef CONFIG_COMPAT_32BIT_TIME |
| 789 | +struct v4l2_event32_time32 { | |
| 790 | + __u32 type; | |
| 791 | + union { | |
| 792 | + compat_s64 value64; | |
| 793 | + __u8 data[64]; | |
| 794 | + } u; | |
| 795 | + __u32 pending; | |
| 796 | + __u32 sequence; | |
| 797 | + struct old_timespec32 timestamp; | |
| 798 | + __u32 id; | |
| 799 | + __u32 reserved[8]; | |
| 800 | +}; | |
| 801 | + | |
| 806 | 802 | static int put_v4l2_event32_time32(struct v4l2_event *p64, |
| 807 | 803 | struct v4l2_event32_time32 __user *p32) |
| 808 | 804 | { |
| @@ -818,7 +814,6 @@ static int put_v4l2_event32_time32(struct v4l2_event *p64, · 9 unmodified lines | ||
| 818 | 814 | return 0; |
| 819 | 815 | } |
| 820 | 816 | #endif |
| 821 | −#endif | |
| 822 | 817 | |
| 823 | 818 | struct v4l2_edid32 { |
| 824 | 819 | __u32 pad; |
| @@ -880,9 +875,7 @@ static int put_v4l2_edid32(struct v4l2_edid *p64, · 55 unmodified lines | ||
| 880 | 875 | #define VIDIOC_QUERYBUF32_TIME32 _IOWR('V', 9, struct v4l2_buffer32_time32) |
| 881 | 876 | #define VIDIOC_QBUF32_TIME32 _IOWR('V', 15, struct v4l2_buffer32_time32) |
| 882 | 877 | #define VIDIOC_DQBUF32_TIME32 _IOWR('V', 17, struct v4l2_buffer32_time32) |
| 883 | −#ifdef CONFIG_X86_64 | |
| 884 | 878 | #define VIDIOC_DQEVENT32_TIME32 _IOR ('V', 89, struct v4l2_event32_time32) |
| 885 | −#endif | |
| 886 | 879 | #define VIDIOC_PREPARE_BUF32_TIME32 _IOWR('V', 93, struct v4l2_buffer32_time32) |
| 887 | 880 | #endif |
| 888 | 881 | |
| @@ -936,10 +929,10 @@ unsigned int v4l2_compat_translate_cmd(unsigned int cmd) · 47 unmodified lines | ||
| 936 | 929 | #ifdef CONFIG_X86_64 |
| 937 | 930 | case VIDIOC_DQEVENT32: |
| 938 | 931 | return VIDIOC_DQEVENT; |
| 932 | +#endif | |
| 939 | 933 | #ifdef CONFIG_COMPAT_32BIT_TIME |
| 940 | 934 | case VIDIOC_DQEVENT32_TIME32: |
| 941 | 935 | return VIDIOC_DQEVENT; |
| 942 | −#endif | |
| 943 | 936 | #endif |
| 944 | 937 | } |
| 945 | 938 | return cmd; |
| @@ -1032,10 +1025,10 @@ int v4l2_compat_put_user(void __user *arg, void *parg, unsigned int cmd) · 86 unmodified lines | ||
| 1032 | 1025 | #ifdef CONFIG_X86_64 |
| 1033 | 1026 | case VIDIOC_DQEVENT32: |
| 1034 | 1027 | return put_v4l2_event32(parg, arg); |
| 1028 | +#endif | |
| 1035 | 1029 | #ifdef CONFIG_COMPAT_32BIT_TIME |
| 1036 | 1030 | case VIDIOC_DQEVENT32_TIME32: |
| 1037 | 1031 | return put_v4l2_event32_time32(parg, arg); |
| 1038 | −#endif | |
| 1039 | 1032 | #endif |
| 1040 | 1033 | } |
| 1041 | 1034 | return 0; |
| @@ -241,7 +241,7 @@ static void mtk_smi_larb_config_port_gen2_general(struct device *dev) · 240 unmodified lines | ||
| 241 | 241 | { |
| 242 | 242 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); |
| 243 | 243 | u32 reg, flags_general = larb->larb_gen->flags_general; |
| 244 | − const u8 *larbostd = larb->larb_gen->ostd[larb->larbid]; | |
| 244 | + const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL; | |
| 245 | 245 | int i; |
| 246 | 246 | |
| 247 | 247 | if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask) |
| @@ -1803,8 +1803,6 @@ static int rtsx_pci_runtime_suspend(struct device *device) · 1802 unmodified lines | ||
| 1803 | 1803 | mutex_lock(&pcr->pcr_mutex); |
| 1804 | 1804 | rtsx_pci_power_off(pcr, HOST_ENTER_S3); |
| 1805 | 1805 | |
| 1806 | − free_irq(pcr->irq, (void *)pcr); | |
| 1807 | − | |
| 1808 | 1806 | mutex_unlock(&pcr->pcr_mutex); |
| 1809 | 1807 | |
| 1810 | 1808 | pcr->is_runtime_suspended = true; |
| @@ -1825,8 +1823,6 @@ static int rtsx_pci_runtime_resume(struct device *device) · 14 unmodified lines | ||
| 1825 | 1823 | mutex_lock(&pcr->pcr_mutex); |
| 1826 | 1824 | |
| 1827 | 1825 | rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x00); |
| 1828 | − rtsx_pci_acquire_irq(pcr); | |
| 1829 | − synchronize_irq(pcr->irq); | |
| 1830 | 1826 | |
| 1831 | 1827 | if (pcr->ops->fetch_vendor_settings) |
| 1832 | 1828 | pcr->ops->fetch_vendor_settings(pcr); |
| @@ -376,7 +376,6 @@ MODULE_DEVICE_TABLE(spi, at25_spi_ids); · 375 unmodified lines | ||
| 376 | 376 | static int at25_probe(struct spi_device *spi) |
| 377 | 377 | { |
| 378 | 378 | struct at25_data *at25 = NULL; |
| 379 | − struct spi_eeprom chip; | |
| 380 | 379 | int err; |
| 381 | 380 | int sr; |
| 382 | 381 | u8 id[FM25_ID_LEN]; |
| @@ -389,15 +388,18 @@ static int at25_probe(struct spi_device *spi) · 6 unmodified lines | ||
| 389 | 388 | if (match && !strcmp(match->compatible, "cypress,fm25")) |
| 390 | 389 | is_fram = 1; |
| 391 | 390 | |
| 391 | + at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL); | |
| 392 | + if (!at25) | |
| 393 | + return -ENOMEM; | |
| 394 | + | |
| 392 | 395 | /* Chip description */ |
| 393 | − if (!spi->dev.platform_data) { | |
| 394 | − if (!is_fram) { | |
| 395 | − err = at25_fw_to_chip(&spi->dev, &chip); | |
| 396 | − if (err) | |
| 397 | − return err; | |
| 398 | − } | |
| 399 | − } else | |
| 400 | − chip = *(struct spi_eeprom *)spi->dev.platform_data; | |
| 396 | + if (spi->dev.platform_data) { | |
| 397 | + memcpy(&at25->chip, spi->dev.platform_data, sizeof(at25->chip)); | |
| 398 | + } else if (!is_fram) { | |
| 399 | + err = at25_fw_to_chip(&spi->dev, &at25->chip); | |
| 400 | + if (err) | |
| 401 | + return err; | |
| 402 | + } | |
| 401 | 403 | |
| 402 | 404 | /* Ping the chip ... the status register is pretty portable, |
| 403 | 405 | * unlike probing manufacturer IDs. We do expect that system |
| @@ -409,12 +411,7 @@ static int at25_probe(struct spi_device *spi) · 5 unmodified lines | ||
| 409 | 411 | return -ENXIO; |
| 410 | 412 | } |
| 411 | 413 | |
| 412 | − at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL); | |
| 413 | − if (!at25) | |
| 414 | − return -ENOMEM; | |
| 415 | − | |
| 416 | 414 | mutex_init(&at25->lock); |
| 417 | − at25->chip = chip; | |
| 418 | 415 | at25->spi = spi; |
| 419 | 416 | spi_set_drvdata(spi, at25); |
| 420 | 417 | |
| @@ -431,7 +428,7 @@ static int at25_probe(struct spi_device *spi) · 10 unmodified lines | ||
| 431 | 428 | dev_err(&spi->dev, "Error: unsupported size (id %02x)\n", id[7]); |
| 432 | 429 | return -ENODEV; |
| 433 | 430 | } |
| 434 | − chip.byte_len = int_pow(2, id[7] - 0x21 + 4) * 1024; | |
| 431 | + at25->chip.byte_len = int_pow(2, id[7] - 0x21 + 4) * 1024; | |
| 435 | 432 | |
| 436 | 433 | if (at25->chip.byte_len > 64 * 1024) |
| 437 | 434 | at25->chip.flags |= EE_ADDR3; |
| @@ -464,7 +461,7 @@ static int at25_probe(struct spi_device *spi) · 26 unmodified lines | ||
| 464 | 461 | at25->nvmem_config.type = is_fram ? NVMEM_TYPE_FRAM : NVMEM_TYPE_EEPROM; |
| 465 | 462 | at25->nvmem_config.name = dev_name(&spi->dev); |
| 466 | 463 | at25->nvmem_config.dev = &spi->dev; |
| 467 | − at25->nvmem_config.read_only = chip.flags & EE_READONLY; | |
| 464 | + at25->nvmem_config.read_only = at25->chip.flags & EE_READONLY; | |
| 468 | 465 | at25->nvmem_config.root_only = true; |
| 469 | 466 | at25->nvmem_config.owner = THIS_MODULE; |
| 470 | 467 | at25->nvmem_config.compat = true; |
| @@ -474,17 +471,18 @@ static int at25_probe(struct spi_device *spi) · 3 unmodified lines | ||
| 474 | 471 | at25->nvmem_config.priv = at25; |
| 475 | 472 | at25->nvmem_config.stride = 1; |
| 476 | 473 | at25->nvmem_config.word_size = 1; |
| 477 | − at25->nvmem_config.size = chip.byte_len; | |
| 474 | + at25->nvmem_config.size = at25->chip.byte_len; | |
| 478 | 475 | |
| 479 | 476 | at25->nvmem = devm_nvmem_register(&spi->dev, &at25->nvmem_config); |
| 480 | 477 | if (IS_ERR(at25->nvmem)) |
| 481 | 478 | return PTR_ERR(at25->nvmem); |
| 482 | 479 | |
| 483 | 480 | dev_info(&spi->dev, "%d %s %s %s%s, pagesize %u\n", |
| 484 | − (chip.byte_len < 1024) ? chip.byte_len : (chip.byte_len / 1024), | |
| 485 | − (chip.byte_len < 1024) ? "Byte" : "KByte", | |
| 481 | + (at25->chip.byte_len < 1024) ? | |
| 482 | + at25->chip.byte_len : (at25->chip.byte_len / 1024), | |
| 483 | + (at25->chip.byte_len < 1024) ? "Byte" : "KByte", | |
| 486 | 484 | at25->chip.name, is_fram ? "fram" : "eeprom", |
| 487 | − (chip.flags & EE_READONLY) ? " (readonly)" : "", | |
| 485 | + (at25->chip.flags & EE_READONLY) ? " (readonly)" : "", | |
| 488 | 486 | at25->chip.page_size); |
| 489 | 487 | return 0; |
| 490 | 488 | } |
| @@ -719,16 +719,18 @@ static int fastrpc_get_meta_size(struct fastrpc_invoke_ctx *ctx) · 718 unmodified lines | ||
| 719 | 719 | static u64 fastrpc_get_payload_size(struct fastrpc_invoke_ctx *ctx, int metalen) |
| 720 | 720 | { |
| 721 | 721 | u64 size = 0; |
| 722 | − int i; | |
| 722 | + int oix; | |
| 723 | 723 | |
| 724 | 724 | size = ALIGN(metalen, FASTRPC_ALIGN); |
| 725 | − for (i = 0; i < ctx->nscalars; i++) { | |
| 725 | + for (oix = 0; oix < ctx->nbufs; oix++) { | |
| 726 | + int i = ctx->olaps[oix].raix; | |
| 727 | + | |
| 726 | 728 | if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1) { |
| 727 | 729 | |
| 728 | − if (ctx->olaps[i].offset == 0) | |
| 730 | + if (ctx->olaps[oix].offset == 0) | |
| 729 | 731 | size = ALIGN(size, FASTRPC_ALIGN); |
| 730 | 732 | |
| 731 | − size += (ctx->olaps[i].mend - ctx->olaps[i].mstart); | |
| 733 | + size += (ctx->olaps[oix].mend - ctx->olaps[oix].mstart); | |
| 732 | 734 | } |
| 733 | 735 | } |
| 734 | 736 | |
| @@ -1514,6 +1514,12 @@ static int mmc_spi_remove(struct spi_device *spi) · 1513 unmodified lines | ||
| 1514 | 1514 | return 0; |
| 1515 | 1515 | } |
| 1516 | 1516 | |
| 1517 | +static const struct spi_device_id mmc_spi_dev_ids[] = { | |
| 1518 | + { "mmc-spi-slot"}, | |
| 1519 | + { }, | |
| 1520 | +}; | |
| 1521 | +MODULE_DEVICE_TABLE(spi, mmc_spi_dev_ids); | |
| 1522 | + | |
| 1517 | 1523 | static const struct of_device_id mmc_spi_of_match_table[] = { |
| 1518 | 1524 | { .compatible = "mmc-spi-slot", }, |
| 1519 | 1525 | {}, |
| @@ -1525,6 +1531,7 @@ static struct spi_driver mmc_spi_driver = { · 5 unmodified lines | ||
| 1525 | 1531 | .name = "mmc_spi", |
| 1526 | 1532 | .of_match_table = mmc_spi_of_match_table, |
| 1527 | 1533 | }, |
| 1534 | + .id_table = mmc_spi_dev_ids, | |
| 1528 | 1535 | .probe = mmc_spi_probe, |
| 1529 | 1536 | .remove = mmc_spi_remove, |
| 1530 | 1537 | }; |
| @@ -2291,8 +2291,10 @@ static int msdc_execute_hs400_tuning(struct mmc_host *mmc, struct mmc_card *card · 2290 unmodified lines | ||
| 2291 | 2291 | sdr_set_field(host->base + PAD_DS_TUNE, |
| 2292 | 2292 | PAD_DS_TUNE_DLY1, i); |
| 2293 | 2293 | ret = mmc_get_ext_csd(card, &ext_csd); |
| 2294 | − if (!ret) | |
| 2294 | + if (!ret) { | |
| 2295 | 2295 | result_dly1 |= (1 << i); |
| 2296 | + kfree(ext_csd); | |
| 2297 | + } | |
| 2296 | 2298 | } |
| 2297 | 2299 | host->hs400_tuning = false; |
| 2298 | 2300 | |
| @@ -673,7 +673,7 @@ static int renesas_sdhi_execute_tuning(struct mmc_host *mmc, u32 opcode) · 672 unmodified lines | ||
| 673 | 673 | |
| 674 | 674 | /* Issue CMD19 twice for each tap */ |
| 675 | 675 | for (i = 0; i < 2 * priv->tap_num; i++) { |
| 676 | − int cmd_error; | |
| 676 | + int cmd_error = 0; | |
| 677 | 677 | |
| 678 | 678 | /* Set sampling clock position */ |
| 679 | 679 | sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, i % priv->tap_num); |
| @@ -310,7 +310,6 @@ static struct esdhc_soc_data usdhc_imx8qxp_data = { · 309 unmodified lines | ||
| 310 | 310 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
| 311 | 311 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
| 312 | 312 | | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES |
| 313 | − | ESDHC_FLAG_CQHCI | |
| 314 | 313 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE |
| 315 | 314 | | ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME, |
| 316 | 315 | }; |
| @@ -319,7 +318,6 @@ static struct esdhc_soc_data usdhc_imx8mm_data = { · 2 unmodified lines | ||
| 319 | 318 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
| 320 | 319 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
| 321 | 320 | | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES |
| 322 | − | ESDHC_FLAG_CQHCI | |
| 323 | 321 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE, |
| 324 | 322 | }; |
| 325 | 323 | |
| @@ -771,7 +771,19 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, · 770 unmodified lines | ||
| 771 | 771 | len -= offset; |
| 772 | 772 | } |
| 773 | 773 | |
| 774 | − BUG_ON(len > 65536); | |
| 774 | + /* | |
| 775 | + * The block layer forces a minimum segment size of PAGE_SIZE, | |
| 776 | + * so 'len' can be too big here if PAGE_SIZE >= 64KiB. Write | |
| 777 | + * multiple descriptors, noting that the ADMA table is sized | |
| 778 | + * for 4KiB chunks anyway, so it will be big enough. | |
| 779 | + */ | |
| 780 | + while (len > host->max_adma) { | |
| 781 | + int n = 32 * 1024; /* 32KiB*/ | |
| 782 | + | |
| 783 | + __sdhci_adma_write_desc(host, &desc, addr, n, ADMA2_TRAN_VALID); | |
| 784 | + addr += n; | |
| 785 | + len -= n; | |
| 786 | + } | |
| 775 | 787 | |
| 776 | 788 | /* tran, valid */ |
| 777 | 789 | if (len) |
| @@ -3968,6 +3980,7 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, · 3190 unmodified lines | ||
| 3968 | 3980 | * descriptor for each segment, plus 1 for a nop end descriptor. |
| 3969 | 3981 | */ |
| 3970 | 3982 | host->adma_table_cnt = SDHCI_MAX_SEGS * 2 + 1; |
| 3983 | + host->max_adma = 65536; | |
| 3971 | 3984 | |
| 3972 | 3985 | host->max_timeout_count = 0xE; |
| 3973 | 3986 | |
| @@ -4633,10 +4646,12 @@ int sdhci_setup_host(struct sdhci_host *host) · 659 unmodified lines | ||
| 4633 | 4646 | * be larger than 64 KiB though. |
| 4634 | 4647 | */ |
| 4635 | 4648 | if (host->flags & SDHCI_USE_ADMA) { |
| 4636 | − if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) | |
| 4649 | + if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) { | |
| 4650 | + host->max_adma = 65532; /* 32-bit alignment */ | |
| 4637 | 4651 | mmc->max_seg_size = 65535; |
| 4638 | − else | |
| 4652 | + } else { | |
| 4639 | 4653 | mmc->max_seg_size = 65536; |
| 4654 | + } | |
| 4640 | 4655 | } else { |
| 4641 | 4656 | mmc->max_seg_size = mmc->max_req_size; |
| 4642 | 4657 | } |
| @@ -340,7 +340,8 @@ struct sdhci_adma2_64_desc { · 339 unmodified lines | ||
| 340 | 340 | |
| 341 | 341 | /* |
| 342 | 342 | * Maximum segments assuming a 512KiB maximum requisition size and a minimum |
| 343 | − * 4KiB page size. | |
| 343 | + * 4KiB page size. Note this also allows enough for multiple descriptors in | |
| 344 | + * case of PAGE_SIZE >= 64KiB. | |
| 344 | 345 | */ |
| 345 | 346 | #define SDHCI_MAX_SEGS 128 |
| 346 | 347 | |
| @@ -543,6 +544,7 @@ struct sdhci_host { · 196 unmodified lines | ||
| 543 | 544 | unsigned int blocks; /* remaining PIO blocks */ |
| 544 | 545 | |
| 545 | 546 | int sg_count; /* Mapped sg entries */ |
| 547 | + int max_adma; /* Max. length in ADMA descriptor */ | |
| 546 | 548 | |
| 547 | 549 | void *adma_table; /* ADMA descriptor table */ |
| 548 | 550 | void *align_buffer; /* Bounce buffer */ |
| @@ -96,6 +96,13 @@ struct dataflash { · 95 unmodified lines | ||
| 96 | 96 | struct mtd_info mtd; |
| 97 | 97 | }; |
| 98 | 98 | |
| 99 | +static const struct spi_device_id dataflash_dev_ids[] = { | |
| 100 | + { "at45" }, | |
| 101 | + { "dataflash" }, | |
| 102 | + { }, | |
| 103 | +}; | |
| 104 | +MODULE_DEVICE_TABLE(spi, dataflash_dev_ids); | |
| 105 | + | |
| 99 | 106 | #ifdef CONFIG_OF |
| 100 | 107 | static const struct of_device_id dataflash_dt_ids[] = { |
| 101 | 108 | { .compatible = "atmel,at45", }, |
| @@ -927,6 +934,7 @@ static struct spi_driver dataflash_driver = { · 825 unmodified lines | ||
| 927 | 934 | .name = "mtd_dataflash", |
| 928 | 935 | .of_match_table = of_match_ptr(dataflash_dt_ids), |
| 929 | 936 | }, |
| 937 | + .id_table = dataflash_dev_ids, | |
| 930 | 938 | |
| 931 | 939 | .probe = dataflash_probe, |
| 932 | 940 | .remove = dataflash_remove, |
| @@ -26,7 +26,7 @@ config MTD_NAND_DENALI_PCI · 25 unmodified lines | ||
| 26 | 26 | config MTD_NAND_DENALI_DT |
| 27 | 27 | tristate "Denali NAND controller as a DT device" |
| 28 | 28 | select MTD_NAND_DENALI |
| 29 | − depends on HAS_DMA && HAVE_CLK && OF | |
| 29 | + depends on HAS_DMA && HAVE_CLK && OF && HAS_IOMEM | |
| 30 | 30 | help |
| 31 | 31 | Enable the driver for NAND flash on platforms using a Denali NAND |
| 32 | 32 | controller as a DT device. |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | #include <linux/clk.h> |
| 17 | 17 | #include <linux/completion.h> |
| 18 | +#include <linux/delay.h> | |
| 18 | 19 | #include <linux/dmaengine.h> |
| 19 | 20 | #include <linux/dma-direction.h> |
| 20 | 21 | #include <linux/dma-mapping.h> |
| @@ -93,6 +94,14 @@ · 72 unmodified lines | ||
| 93 | 94 | |
| 94 | 95 | #define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ) |
| 95 | 96 | |
| 97 | +/* | |
| 98 | + * According to SPEAr300 Reference Manual (RM0082) | |
| 99 | + * TOUDEL = 7ns (Output delay from the flip-flops to the board) | |
| 100 | + * TINDEL = 5ns (Input delay from the board to the flipflop) | |
| 101 | + */ | |
| 102 | +#define TOUTDEL 7000 | |
| 103 | +#define TINDEL 5000 | |
| 104 | + | |
| 96 | 105 | struct fsmc_nand_timings { |
| 97 | 106 | u8 tclr; |
| 98 | 107 | u8 tar; |
| @@ -277,7 +286,7 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host, · 178 unmodified lines | ||
| 277 | 286 | { |
| 278 | 287 | unsigned long hclk = clk_get_rate(host->clk); |
| 279 | 288 | unsigned long hclkn = NSEC_PER_SEC / hclk; |
| 280 | − u32 thiz, thold, twait, tset; | |
| 289 | + u32 thiz, thold, twait, tset, twait_min; | |
| 281 | 290 | |
| 282 | 291 | if (sdrt->tRC_min < 30000) |
| 283 | 292 | return -EOPNOTSUPP; |
| @@ -309,13 +318,6 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host, · 25 unmodified lines | ||
| 309 | 318 | else if (tims->thold > FSMC_THOLD_MASK) |
| 310 | 319 | tims->thold = FSMC_THOLD_MASK; |
| 311 | 320 | |
| 312 | − twait = max(sdrt->tRP_min, sdrt->tWP_min); | |
| 313 | − tims->twait = DIV_ROUND_UP(twait / 1000, hclkn) - 1; | |
| 314 | − if (tims->twait == 0) | |
| 315 | − tims->twait = 1; | |
| 316 | − else if (tims->twait > FSMC_TWAIT_MASK) | |
| 317 | − tims->twait = FSMC_TWAIT_MASK; | |
| 318 | − | |
| 319 | 321 | tset = max(sdrt->tCS_min - sdrt->tWP_min, |
| 320 | 322 | sdrt->tCEA_max - sdrt->tREA_max); |
| 321 | 323 | tims->tset = DIV_ROUND_UP(tset / 1000, hclkn) - 1; |
| @@ -324,6 +326,21 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host, · 2 unmodified lines | ||
| 324 | 326 | else if (tims->tset > FSMC_TSET_MASK) |
| 325 | 327 | tims->tset = FSMC_TSET_MASK; |
| 326 | 328 | |
| 329 | + /* | |
| 330 | + * According to SPEAr300 Reference Manual (RM0082) which gives more | |
| 331 | + * information related to FSMSC timings than the SPEAr600 one (RM0305), | |
| 332 | + * twait >= tCEA - (tset * TCLK) + TOUTDEL + TINDEL | |
| 333 | + */ | |
| 334 | + twait_min = sdrt->tCEA_max - ((tims->tset + 1) * hclkn * 1000) | |
| 335 | + + TOUTDEL + TINDEL; | |
| 336 | + twait = max3(sdrt->tRP_min, sdrt->tWP_min, twait_min); | |
| 337 | + | |
| 338 | + tims->twait = DIV_ROUND_UP(twait / 1000, hclkn) - 1; | |
| 339 | + if (tims->twait == 0) | |
| 340 | + tims->twait = 1; | |
| 341 | + else if (tims->twait > FSMC_TWAIT_MASK) | |
| 342 | + tims->twait = FSMC_TWAIT_MASK; | |
| 343 | + | |
| 327 | 344 | return 0; |
| 328 | 345 | } |
| 329 | 346 | |
| @@ -664,6 +681,9 @@ static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op, · 334 unmodified lines | ||
| 664 | 681 | instr->ctx.waitrdy.timeout_ms); |
| 665 | 682 | break; |
| 666 | 683 | } |
| 684 | + | |
| 685 | + if (instr->delay_ns) | |
| 686 | + ndelay(instr->delay_ns); | |
| 667 | 687 | } |
| 668 | 688 | |
| 669 | 689 | return ret; |
| @@ -926,7 +926,7 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip, · 925 unmodified lines | ||
| 926 | 926 | struct nand_sdr_timings *spec_timings) |
| 927 | 927 | { |
| 928 | 928 | const struct nand_controller_ops *ops = chip->controller->ops; |
| 929 | − int best_mode = 0, mode, ret; | |
| 929 | + int best_mode = 0, mode, ret = -EOPNOTSUPP; | |
| 930 | 930 | |
| 931 | 931 | iface->type = NAND_SDR_IFACE; |
| 932 | 932 | |
| @@ -977,7 +977,7 @@ int nand_choose_best_nvddr_timings(struct nand_chip *chip, · 44 unmodified lines | ||
| 977 | 977 | struct nand_nvddr_timings *spec_timings) |
| 978 | 978 | { |
| 979 | 979 | const struct nand_controller_ops *ops = chip->controller->ops; |
| 980 | − int best_mode = 0, mode, ret; | |
| 980 | + int best_mode = 0, mode, ret = -EOPNOTSUPP; | |
| 981 | 981 | |
| 982 | 982 | iface->type = NAND_NVDDR_IFACE; |
| 983 | 983 | |
| @@ -1837,7 +1837,7 @@ int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock) · 853 unmodified lines | ||
| 1837 | 1837 | NAND_OP_CMD(NAND_CMD_ERASE1, 0), |
| 1838 | 1838 | NAND_OP_ADDR(2, addrs, 0), |
| 1839 | 1839 | NAND_OP_CMD(NAND_CMD_ERASE2, |
| 1840 | − NAND_COMMON_TIMING_MS(conf, tWB_max)), | |
| 1840 | + NAND_COMMON_TIMING_NS(conf, tWB_max)), | |
| 1841 | 1841 | NAND_OP_WAIT_RDY(NAND_COMMON_TIMING_MS(conf, tBERS_max), |
| 1842 | 1842 | 0), |
| 1843 | 1843 | }; |
| @@ -567,9 +567,7 @@ config XEN_NETDEV_BACKEND · 566 unmodified lines | ||
| 567 | 567 | config VMXNET3 |
| 568 | 568 | tristate "VMware VMXNET3 ethernet driver" |
| 569 | 569 | depends on PCI && INET |
| 570 | − depends on !(PAGE_SIZE_64KB || ARM64_64K_PAGES || \ | |
| 571 | − IA64_PAGE_SIZE_64KB || PARISC_PAGE_SIZE_64KB || \ | |
| 572 | − PPC_64K_PAGES) | |
| 570 | + depends on PAGE_SIZE_LESS_THAN_64KB | |
| 573 | 571 | help |
| 574 | 572 | This driver supports VMware's vmxnet3 virtual ethernet NIC. |
| 575 | 573 | To compile this driver as a module, choose M here: the |
| @@ -3286,7 +3286,7 @@ static void __exit amt_fini(void) · 3285 unmodified lines | ||
| 3286 | 3286 | { |
| 3287 | 3287 | rtnl_link_unregister(&amt_link_ops); |
| 3288 | 3288 | unregister_netdevice_notifier(&amt_notifier_block); |
| 3289 | − cancel_delayed_work(&source_gc_wq); | |
| 3289 | + cancel_delayed_work_sync(&source_gc_wq); | |
| 3290 | 3290 | __amt_source_gc_work(); |
| 3291 | 3291 | destroy_workqueue(amt_wq); |
| 3292 | 3292 | } |
| @@ -1501,14 +1501,14 @@ void bond_alb_monitor(struct work_struct *work) · 1500 unmodified lines | ||
| 1501 | 1501 | struct slave *slave; |
| 1502 | 1502 | |
| 1503 | 1503 | if (!bond_has_slaves(bond)) { |
| 1504 | − bond_info->tx_rebalance_counter = 0; | |
| 1504 | + atomic_set(&bond_info->tx_rebalance_counter, 0); | |
| 1505 | 1505 | bond_info->lp_counter = 0; |
| 1506 | 1506 | goto re_arm; |
| 1507 | 1507 | } |
| 1508 | 1508 | |
| 1509 | 1509 | rcu_read_lock(); |
| 1510 | 1510 | |
| 1511 | − bond_info->tx_rebalance_counter++; | |
| 1511 | + atomic_inc(&bond_info->tx_rebalance_counter); | |
| 1512 | 1512 | bond_info->lp_counter++; |
| 1513 | 1513 | |
| 1514 | 1514 | /* send learning packets */ |
| @@ -1530,7 +1530,7 @@ void bond_alb_monitor(struct work_struct *work) · 15 unmodified lines | ||
| 1530 | 1530 | } |
| 1531 | 1531 | |
| 1532 | 1532 | /* rebalance tx traffic */ |
| 1533 | − if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) { | |
| 1533 | + if (atomic_read(&bond_info->tx_rebalance_counter) >= BOND_TLB_REBALANCE_TICKS) { | |
| 1534 | 1534 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 1535 | 1535 | tlb_clear_slave(bond, slave, 1); |
| 1536 | 1536 | if (slave == rcu_access_pointer(bond->curr_active_slave)) { |
| @@ -1540,7 +1540,7 @@ void bond_alb_monitor(struct work_struct *work) · 3 unmodified lines | ||
| 1540 | 1540 | bond_info->unbalanced_load = 0; |
| 1541 | 1541 | } |
| 1542 | 1542 | } |
| 1543 | − bond_info->tx_rebalance_counter = 0; | |
| 1543 | + atomic_set(&bond_info->tx_rebalance_counter, 0); | |
| 1544 | 1544 | } |
| 1545 | 1545 | |
| 1546 | 1546 | if (bond_info->rlb_enabled) { |
| @@ -1610,7 +1610,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave) · 63 unmodified lines | ||
| 1610 | 1610 | tlb_init_slave(slave); |
| 1611 | 1611 | |
| 1612 | 1612 | /* order a rebalance ASAP */ |
| 1613 | − bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; | |
| 1613 | + atomic_set(&bond->alb_info.tx_rebalance_counter, | |
| 1614 | + BOND_TLB_REBALANCE_TICKS); | |
| 1614 | 1615 | |
| 1615 | 1616 | if (bond->alb_info.rlb_enabled) |
| 1616 | 1617 | bond->alb_info.rlb_rebalance = 1; |
| @@ -1647,7 +1648,8 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char · 30 unmodified lines | ||
| 1647 | 1648 | rlb_clear_slave(bond, slave); |
| 1648 | 1649 | } else if (link == BOND_LINK_UP) { |
| 1649 | 1650 | /* order a rebalance ASAP */ |
| 1650 | − bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; | |
| 1651 | + atomic_set(&bond_info->tx_rebalance_counter, | |
| 1652 | + BOND_TLB_REBALANCE_TICKS); | |
| 1651 | 1653 | if (bond->alb_info.rlb_enabled) { |
| 1652 | 1654 | bond->alb_info.rlb_rebalance = 1; |
| 1653 | 1655 | /* If the updelay module parameter is smaller than the |
| @@ -248,6 +248,9 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices"); · 247 unmodified lines | ||
| 248 | 248 | #define KVASER_PCIEFD_SPACK_EWLR BIT(23) |
| 249 | 249 | #define KVASER_PCIEFD_SPACK_EPLR BIT(24) |
| 250 | 250 | |
| 251 | +/* Kvaser KCAN_EPACK second word */ | |
| 252 | +#define KVASER_PCIEFD_EPACK_DIR_TX BIT(0) | |
| 253 | + | |
| 251 | 254 | struct kvaser_pciefd; |
| 252 | 255 | |
| 253 | 256 | struct kvaser_pciefd_can { |
| @@ -1285,7 +1288,10 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can, · 1031 unmodified lines | ||
| 1285 | 1288 | |
| 1286 | 1289 | can->err_rep_cnt++; |
| 1287 | 1290 | can->can.can_stats.bus_error++; |
| 1288 | − stats->rx_errors++; | |
| 1291 | + if (p->header[1] & KVASER_PCIEFD_EPACK_DIR_TX) | |
| 1292 | + stats->tx_errors++; | |
| 1293 | + else | |
| 1294 | + stats->rx_errors++; | |
| 1289 | 1295 | |
| 1290 | 1296 | can->bec.txerr = bec.txerr; |
| 1291 | 1297 | can->bec.rxerr = bec.rxerr; |
| @@ -204,16 +204,16 @@ enum m_can_reg { · 203 unmodified lines | ||
| 204 | 204 | |
| 205 | 205 | /* Interrupts for version 3.0.x */ |
| 206 | 206 | #define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE) |
| 207 | −#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_ELO | IR_BEU | \ | |
| 208 | − IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ | |
| 209 | − IR_RF1L | IR_RF0L) | |
| 207 | +#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_BEU | IR_BEC | \ | |
| 208 | + IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \ | |
| 209 | + IR_RF0L) | |
| 210 | 210 | #define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X) |
| 211 | 211 | |
| 212 | 212 | /* Interrupts for version >= 3.1.x */ |
| 213 | 213 | #define IR_ERR_LEC_31X (IR_PED | IR_PEA) |
| 214 | −#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_ELO | IR_BEU | \ | |
| 215 | − IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ | |
| 216 | − IR_RF1L | IR_RF0L) | |
| 214 | +#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_BEU | IR_BEC | \ | |
| 215 | + IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \ | |
| 216 | + IR_RF0L) | |
| 217 | 217 | #define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X) |
| 218 | 218 | |
| 219 | 219 | /* Interrupt Line Select (ILS) */ |
| @@ -517,7 +517,7 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs) · 297 unmodified lines | ||
| 517 | 517 | err = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_DATA, |
| 518 | 518 | cf->data, DIV_ROUND_UP(cf->len, 4)); |
| 519 | 519 | if (err) |
| 520 | − goto out_fail; | |
| 520 | + goto out_free_skb; | |
| 521 | 521 | } |
| 522 | 522 | |
| 523 | 523 | /* acknowledge rx fifo 0 */ |
| @@ -532,6 +532,8 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs) · 8 unmodified lines | ||
| 532 | 532 | |
| 533 | 533 | return 0; |
| 534 | 534 | |
| 535 | +out_free_skb: | |
| 536 | + kfree_skb(skb); | |
| 535 | 537 | out_fail: |
| 536 | 538 | netdev_err(dev, "FIFO read returned %d\n", err); |
| 537 | 539 | return err; |
| @@ -810,8 +812,6 @@ static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus) · 272 unmodified lines | ||
| 810 | 812 | { |
| 811 | 813 | if (irqstatus & IR_WDI) |
| 812 | 814 | netdev_err(dev, "Message RAM Watchdog event due to missing READY\n"); |
| 813 | − if (irqstatus & IR_ELO) | |
| 814 | − netdev_err(dev, "Error Logging Overflow\n"); | |
| 815 | 815 | if (irqstatus & IR_BEU) |
| 816 | 816 | netdev_err(dev, "Bit Error Uncorrected\n"); |
| 817 | 817 | if (irqstatus & IR_BEC) |
| @@ -1494,20 +1494,32 @@ static int m_can_dev_setup(struct m_can_classdev *cdev) · 676 unmodified lines | ||
| 1494 | 1494 | case 30: |
| 1495 | 1495 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */ |
| 1496 | 1496 | can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); |
| 1497 | − cdev->can.bittiming_const = &m_can_bittiming_const_30X; | |
| 1498 | − cdev->can.data_bittiming_const = &m_can_data_bittiming_const_30X; | |
| 1497 | + cdev->can.bittiming_const = cdev->bit_timing ? | |
| 1498 | + cdev->bit_timing : &m_can_bittiming_const_30X; | |
| 1499 | + | |
| 1500 | + cdev->can.data_bittiming_const = cdev->data_timing ? | |
| 1501 | + cdev->data_timing : | |
| 1502 | + &m_can_data_bittiming_const_30X; | |
| 1499 | 1503 | break; |
| 1500 | 1504 | case 31: |
| 1501 | 1505 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */ |
| 1502 | 1506 | can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); |
| 1503 | − cdev->can.bittiming_const = &m_can_bittiming_const_31X; | |
| 1504 | − cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X; | |
| 1507 | + cdev->can.bittiming_const = cdev->bit_timing ? | |
| 1508 | + cdev->bit_timing : &m_can_bittiming_const_31X; | |
| 1509 | + | |
| 1510 | + cdev->can.data_bittiming_const = cdev->data_timing ? | |
| 1511 | + cdev->data_timing : | |
| 1512 | + &m_can_data_bittiming_const_31X; | |
| 1505 | 1513 | break; |
| 1506 | 1514 | case 32: |
| 1507 | 1515 | case 33: |
| 1508 | 1516 | /* Support both MCAN version v3.2.x and v3.3.0 */ |
| 1509 | − cdev->can.bittiming_const = &m_can_bittiming_const_31X; | |
| 1510 | − cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X; | |
| 1517 | + cdev->can.bittiming_const = cdev->bit_timing ? | |
| 1518 | + cdev->bit_timing : &m_can_bittiming_const_31X; | |
| 1519 | + | |
| 1520 | + cdev->can.data_bittiming_const = cdev->data_timing ? | |
| 1521 | + cdev->data_timing : | |
| 1522 | + &m_can_data_bittiming_const_31X; | |
| 1511 | 1523 | |
| 1512 | 1524 | cdev->can.ctrlmode_supported |= |
| 1513 | 1525 | (m_can_niso_supported(cdev) ? |
| @@ -85,6 +85,9 @@ struct m_can_classdev { · 84 unmodified lines | ||
| 85 | 85 | struct sk_buff *tx_skb; |
| 86 | 86 | struct phy *transceiver; |
| 87 | 87 | |
| 88 | + const struct can_bittiming_const *bit_timing; | |
| 89 | + const struct can_bittiming_const *data_timing; | |
| 90 | + | |
| 88 | 91 | struct m_can_ops *ops; |
| 89 | 92 | |
| 90 | 93 | int version; |
| @@ -18,9 +18,14 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #define M_CAN_PCI_MMIO_BAR 0 |
| 20 | 20 | |
| 21 | −#define M_CAN_CLOCK_FREQ_EHL 100000000 | |
| 22 | 21 | #define CTL_CSR_INT_CTL_OFFSET 0x508 |
| 23 | 22 | |
| 23 | +struct m_can_pci_config { | |
| 24 | + const struct can_bittiming_const *bit_timing; | |
| 25 | + const struct can_bittiming_const *data_timing; | |
| 26 | + unsigned int clock_freq; | |
| 27 | +}; | |
| 28 | + | |
| 24 | 29 | struct m_can_pci_priv { |
| 25 | 30 | struct m_can_classdev cdev; |
| 26 | 31 | |
| @@ -42,8 +47,13 @@ static u32 iomap_read_reg(struct m_can_classdev *cdev, int reg) · 15 unmodified lines | ||
| 42 | 47 | static int iomap_read_fifo(struct m_can_classdev *cdev, int offset, void *val, size_t val_count) |
| 43 | 48 | { |
| 44 | 49 | struct m_can_pci_priv *priv = cdev_to_priv(cdev); |
| 50 | + void __iomem *src = priv->base + offset; | |
| 45 | 51 | |
| 46 | − ioread32_rep(priv->base + offset, val, val_count); | |
| 52 | + while (val_count--) { | |
| 53 | + *(unsigned int *)val = ioread32(src); | |
| 54 | + val += 4; | |
| 55 | + src += 4; | |
| 56 | + } | |
| 47 | 57 | |
| 48 | 58 | return 0; |
| 49 | 59 | } |
| @@ -61,8 +71,13 @@ static int iomap_write_fifo(struct m_can_classdev *cdev, int offset, · 11 unmodified lines | ||
| 61 | 71 | const void *val, size_t val_count) |
| 62 | 72 | { |
| 63 | 73 | struct m_can_pci_priv *priv = cdev_to_priv(cdev); |
| 74 | + void __iomem *dst = priv->base + offset; | |
| 64 | 75 | |
| 65 | − iowrite32_rep(priv->base + offset, val, val_count); | |
| 76 | + while (val_count--) { | |
| 77 | + iowrite32(*(unsigned int *)val, dst); | |
| 78 | + val += 4; | |
| 79 | + dst += 4; | |
| 80 | + } | |
| 66 | 81 | |
| 67 | 82 | return 0; |
| 68 | 83 | } |
| @@ -74,9 +89,40 @@ static struct m_can_ops m_can_pci_ops = { · 5 unmodified lines | ||
| 74 | 89 | .read_fifo = iomap_read_fifo, |
| 75 | 90 | }; |
| 76 | 91 | |
| 92 | +static const struct can_bittiming_const m_can_bittiming_const_ehl = { | |
| 93 | + .name = KBUILD_MODNAME, | |
| 94 | + .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | |
| 95 | + .tseg1_max = 64, | |
| 96 | + .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | |
| 97 | + .tseg2_max = 128, | |
| 98 | + .sjw_max = 128, | |
| 99 | + .brp_min = 1, | |
| 100 | + .brp_max = 512, | |
| 101 | + .brp_inc = 1, | |
| 102 | +}; | |
| 103 | + | |
| 104 | +static const struct can_bittiming_const m_can_data_bittiming_const_ehl = { | |
| 105 | + .name = KBUILD_MODNAME, | |
| 106 | + .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | |
| 107 | + .tseg1_max = 16, | |
| 108 | + .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | |
| 109 | + .tseg2_max = 8, | |
| 110 | + .sjw_max = 4, | |
| 111 | + .brp_min = 1, | |
| 112 | + .brp_max = 32, | |
| 113 | + .brp_inc = 1, | |
| 114 | +}; | |
| 115 | + | |
| 116 | +static const struct m_can_pci_config m_can_pci_ehl = { | |
| 117 | + .bit_timing = &m_can_bittiming_const_ehl, | |
| 118 | + .data_timing = &m_can_data_bittiming_const_ehl, | |
| 119 | + .clock_freq = 200000000, | |
| 120 | +}; | |
| 121 | + | |
| 77 | 122 | static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) |
| 78 | 123 | { |
| 79 | 124 | struct device *dev = &pci->dev; |
| 125 | + const struct m_can_pci_config *cfg; | |
| 80 | 126 | struct m_can_classdev *mcan_class; |
| 81 | 127 | struct m_can_pci_priv *priv; |
| 82 | 128 | void __iomem *base; |
| @@ -104,6 +150,8 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) · 21 unmodified lines | ||
| 104 | 150 | if (!mcan_class) |
| 105 | 151 | return -ENOMEM; |
| 106 | 152 | |
| 153 | + cfg = (const struct m_can_pci_config *)id->driver_data; | |
| 154 | + | |
| 107 | 155 | priv = cdev_to_priv(mcan_class); |
| 108 | 156 | |
| 109 | 157 | priv->base = base; |
| @@ -115,7 +163,9 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) · 5 unmodified lines | ||
| 115 | 163 | mcan_class->dev = &pci->dev; |
| 116 | 164 | mcan_class->net->irq = pci_irq_vector(pci, 0); |
| 117 | 165 | mcan_class->pm_clock_support = 1; |
| 118 | − mcan_class->can.clock.freq = id->driver_data; | |
| 166 | + mcan_class->bit_timing = cfg->bit_timing; | |
| 167 | + mcan_class->data_timing = cfg->data_timing; | |
| 168 | + mcan_class->can.clock.freq = cfg->clock_freq; | |
| 119 | 169 | mcan_class->ops = &m_can_pci_ops; |
| 120 | 170 | |
| 121 | 171 | pci_set_drvdata(pci, mcan_class); |
| @@ -168,8 +218,8 @@ static SIMPLE_DEV_PM_OPS(m_can_pci_pm_ops, · 46 unmodified lines | ||
| 168 | 218 | m_can_pci_suspend, m_can_pci_resume); |
| 169 | 219 | |
| 170 | 220 | static const struct pci_device_id m_can_pci_id_table[] = { |
| 171 | − { PCI_VDEVICE(INTEL, 0x4bc1), M_CAN_CLOCK_FREQ_EHL, }, | |
| 172 | − { PCI_VDEVICE(INTEL, 0x4bc2), M_CAN_CLOCK_FREQ_EHL, }, | |
| 221 | + { PCI_VDEVICE(INTEL, 0x4bc1), (kernel_ulong_t)&m_can_pci_ehl, }, | |
| 222 | + { PCI_VDEVICE(INTEL, 0x4bc2), (kernel_ulong_t)&m_can_pci_ehl, }, | |
| 173 | 223 | { } /* Terminating Entry */ |
| 174 | 224 | }; |
| 175 | 225 | MODULE_DEVICE_TABLE(pci, m_can_pci_id_table); |
| @@ -692,11 +692,11 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota) · 691 unmodified lines | ||
| 692 | 692 | cf->data[i + 1] = data_reg >> 8; |
| 693 | 693 | } |
| 694 | 694 | |
| 695 | − netif_receive_skb(skb); | |
| 696 | 695 | rcv_pkts++; |
| 697 | 696 | stats->rx_packets++; |
| 698 | 697 | quota--; |
| 699 | 698 | stats->rx_bytes += cf->len; |
| 699 | + netif_receive_skb(skb); | |
| 700 | 700 | |
| 701 | 701 | pch_fifo_thresh(priv, obj_num); |
| 702 | 702 | obj_num++; |
| @@ -234,7 +234,12 @@ static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base) · 233 unmodified lines | ||
| 234 | 234 | free_sja1000dev(dev); |
| 235 | 235 | } |
| 236 | 236 | |
| 237 | − err = request_irq(dev->irq, &ems_pcmcia_interrupt, IRQF_SHARED, | |
| 237 | + if (!card->channels) { | |
| 238 | + err = -ENODEV; | |
| 239 | + goto failure_cleanup; | |
| 240 | + } | |
| 241 | + | |
| 242 | + err = request_irq(pdev->irq, &ems_pcmcia_interrupt, IRQF_SHARED, | |
| 238 | 243 | DRV_NAME, card); |
| 239 | 244 | if (!err) |
| 240 | 245 | return 0; |
| @@ -28,10 +28,6 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #include "kvaser_usb.h" |
| 30 | 30 | |
| 31 | −/* Forward declaration */ | |
| 32 | −static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg; | |
| 33 | − | |
| 34 | −#define CAN_USB_CLOCK 8000000 | |
| 35 | 31 | #define MAX_USBCAN_NET_DEVICES 2 |
| 36 | 32 | |
| 37 | 33 | /* Command header size */ |
| @@ -80,6 +76,12 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg; · 42 unmodified lines | ||
| 80 | 76 | |
| 81 | 77 | #define CMD_LEAF_LOG_MESSAGE 106 |
| 82 | 78 | |
| 79 | +/* Leaf frequency options */ | |
| 80 | +#define KVASER_USB_LEAF_SWOPTION_FREQ_MASK 0x60 | |
| 81 | +#define KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK 0 | |
| 82 | +#define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5) | |
| 83 | +#define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6) | |
| 84 | + | |
| 83 | 85 | /* error factors */ |
| 84 | 86 | #define M16C_EF_ACKE BIT(0) |
| 85 | 87 | #define M16C_EF_CRCE BIT(1) |
| @@ -340,6 +342,50 @@ struct kvaser_usb_err_summary { · 254 unmodified lines | ||
| 340 | 342 | }; |
| 341 | 343 | }; |
| 342 | 344 | |
| 345 | +static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = { | |
| 346 | + .name = "kvaser_usb", | |
| 347 | + .tseg1_min = KVASER_USB_TSEG1_MIN, | |
| 348 | + .tseg1_max = KVASER_USB_TSEG1_MAX, | |
| 349 | + .tseg2_min = KVASER_USB_TSEG2_MIN, | |
| 350 | + .tseg2_max = KVASER_USB_TSEG2_MAX, | |
| 351 | + .sjw_max = KVASER_USB_SJW_MAX, | |
| 352 | + .brp_min = KVASER_USB_BRP_MIN, | |
| 353 | + .brp_max = KVASER_USB_BRP_MAX, | |
| 354 | + .brp_inc = KVASER_USB_BRP_INC, | |
| 355 | +}; | |
| 356 | + | |
| 357 | +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = { | |
| 358 | + .clock = { | |
| 359 | + .freq = 8000000, | |
| 360 | + }, | |
| 361 | + .timestamp_freq = 1, | |
| 362 | + .bittiming_const = &kvaser_usb_leaf_bittiming_const, | |
| 363 | +}; | |
| 364 | + | |
| 365 | +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = { | |
| 366 | + .clock = { | |
| 367 | + .freq = 16000000, | |
| 368 | + }, | |
| 369 | + .timestamp_freq = 1, | |
| 370 | + .bittiming_const = &kvaser_usb_leaf_bittiming_const, | |
| 371 | +}; | |
| 372 | + | |
| 373 | +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = { | |
| 374 | + .clock = { | |
| 375 | + .freq = 24000000, | |
| 376 | + }, | |
| 377 | + .timestamp_freq = 1, | |
| 378 | + .bittiming_const = &kvaser_usb_leaf_bittiming_const, | |
| 379 | +}; | |
| 380 | + | |
| 381 | +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = { | |
| 382 | + .clock = { | |
| 383 | + .freq = 32000000, | |
| 384 | + }, | |
| 385 | + .timestamp_freq = 1, | |
| 386 | + .bittiming_const = &kvaser_usb_leaf_bittiming_const, | |
| 387 | +}; | |
| 388 | + | |
| 343 | 389 | static void * |
| 344 | 390 | kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, |
| 345 | 391 | const struct sk_buff *skb, int *frame_len, |
| @@ -471,6 +517,27 @@ static int kvaser_usb_leaf_send_simple_cmd(const struct kvaser_usb *dev, · 125 unmodified lines | ||
| 471 | 517 | return rc; |
| 472 | 518 | } |
| 473 | 519 | |
| 520 | +static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, | |
| 521 | + const struct leaf_cmd_softinfo *softinfo) | |
| 522 | +{ | |
| 523 | + u32 sw_options = le32_to_cpu(softinfo->sw_options); | |
| 524 | + | |
| 525 | + dev->fw_version = le32_to_cpu(softinfo->fw_version); | |
| 526 | + dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); | |
| 527 | + | |
| 528 | + switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { | |
| 529 | + case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: | |
| 530 | + dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; | |
| 531 | + break; | |
| 532 | + case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: | |
| 533 | + dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz; | |
| 534 | + break; | |
| 535 | + case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: | |
| 536 | + dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz; | |
| 537 | + break; | |
| 538 | + } | |
| 539 | +} | |
| 540 | + | |
| 474 | 541 | static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) |
| 475 | 542 | { |
| 476 | 543 | struct kvaser_cmd cmd; |
| @@ -486,14 +553,13 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) · 9 unmodified lines | ||
| 486 | 553 | |
| 487 | 554 | switch (dev->card_data.leaf.family) { |
| 488 | 555 | case KVASER_LEAF: |
| 489 | − dev->fw_version = le32_to_cpu(cmd.u.leaf.softinfo.fw_version); | |
| 490 | − dev->max_tx_urbs = | |
| 491 | − le16_to_cpu(cmd.u.leaf.softinfo.max_outstanding_tx); | |
| 556 | + kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo); | |
| 492 | 557 | break; |
| 493 | 558 | case KVASER_USBCAN: |
| 494 | 559 | dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); |
| 495 | 560 | dev->max_tx_urbs = |
| 496 | 561 | le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx); |
| 562 | + dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz; | |
| 497 | 563 | break; |
| 498 | 564 | } |
| 499 | 565 | |
| @@ -1225,24 +1291,11 @@ static int kvaser_usb_leaf_init_card(struct kvaser_usb *dev) · 725 unmodified lines | ||
| 1225 | 1291 | { |
| 1226 | 1292 | struct kvaser_usb_dev_card_data *card_data = &dev->card_data; |
| 1227 | 1293 | |
| 1228 | − dev->cfg = &kvaser_usb_leaf_dev_cfg; | |
| 1229 | 1294 | card_data->ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; |
| 1230 | 1295 | |
| 1231 | 1296 | return 0; |
| 1232 | 1297 | } |
| 1233 | 1298 | |
| 1234 | −static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = { | |
| 1235 | − .name = "kvaser_usb", | |
| 1236 | − .tseg1_min = KVASER_USB_TSEG1_MIN, | |
| 1237 | − .tseg1_max = KVASER_USB_TSEG1_MAX, | |
| 1238 | − .tseg2_min = KVASER_USB_TSEG2_MIN, | |
| 1239 | − .tseg2_max = KVASER_USB_TSEG2_MAX, | |
| 1240 | − .sjw_max = KVASER_USB_SJW_MAX, | |
| 1241 | − .brp_min = KVASER_USB_BRP_MIN, | |
| 1242 | − .brp_max = KVASER_USB_BRP_MAX, | |
| 1243 | − .brp_inc = KVASER_USB_BRP_INC, | |
| 1244 | −}; | |
| 1245 | − | |
| 1246 | 1299 | static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) |
| 1247 | 1300 | { |
| 1248 | 1301 | struct kvaser_usb_net_priv *priv = netdev_priv(netdev); |
| @@ -1348,11 +1401,3 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = { · 99 unmodified lines | ||
| 1348 | 1401 | .dev_read_bulk_callback = kvaser_usb_leaf_read_bulk_callback, |
| 1349 | 1402 | .dev_frame_to_cmd = kvaser_usb_leaf_frame_to_cmd, |
| 1350 | 1403 | }; |
| 1351 | − | |
| 1352 | −static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg = { | |
| 1353 | − .clock = { | |
| 1354 | − .freq = CAN_USB_CLOCK, | |
| 1355 | − }, | |
| 1356 | − .timestamp_freq = 1, | |
| 1357 | − .bittiming_const = &kvaser_usb_leaf_bittiming_const, | |
| 1358 | −}; | |
| @@ -349,6 +349,19 @@ static const struct of_device_id b53_spi_of_match[] = { · 348 unmodified lines | ||
| 349 | 349 | }; |
| 350 | 350 | MODULE_DEVICE_TABLE(of, b53_spi_of_match); |
| 351 | 351 | |
| 352 | +static const struct spi_device_id b53_spi_ids[] = { | |
| 353 | + { .name = "bcm5325" }, | |
| 354 | + { .name = "bcm5365" }, | |
| 355 | + { .name = "bcm5395" }, | |
| 356 | + { .name = "bcm5397" }, | |
| 357 | + { .name = "bcm5398" }, | |
| 358 | + { .name = "bcm53115" }, | |
| 359 | + { .name = "bcm53125" }, | |
| 360 | + { .name = "bcm53128" }, | |
| 361 | + { /* sentinel */ } | |
| 362 | +}; | |
| 363 | +MODULE_DEVICE_TABLE(spi, b53_spi_ids); | |
| 364 | + | |
| 352 | 365 | static struct spi_driver b53_spi_driver = { |
| 353 | 366 | .driver = { |
| 354 | 367 | .name = "b53-switch", |
| @@ -357,6 +370,7 @@ static struct spi_driver b53_spi_driver = { · 2 unmodified lines | ||
| 357 | 370 | .probe = b53_spi_probe, |
| 358 | 371 | .remove = b53_spi_remove, |
| 359 | 372 | .shutdown = b53_spi_shutdown, |
| 373 | + .id_table = b53_spi_ids, | |
| 360 | 374 | }; |
| 361 | 375 | |
| 362 | 376 | module_spi_driver(b53_spi_driver); |
| @@ -1002,57 +1002,32 @@ static void ksz8_cfg_port_member(struct ksz_device *dev, int port, u8 member) · 1001 unmodified lines | ||
| 1002 | 1002 | data &= ~PORT_VLAN_MEMBERSHIP; |
| 1003 | 1003 | data |= (member & dev->port_mask); |
| 1004 | 1004 | ksz_pwrite8(dev, port, P_MIRROR_CTRL, data); |
| 1005 | − dev->ports[port].member = member; | |
| 1006 | 1005 | } |
| 1007 | 1006 | |
| 1008 | 1007 | static void ksz8_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) |
| 1009 | 1008 | { |
| 1010 | 1009 | struct ksz_device *dev = ds->priv; |
| 1011 | − int forward = dev->member; | |
| 1012 | 1010 | struct ksz_port *p; |
| 1013 | − int member = -1; | |
| 1014 | 1011 | u8 data; |
| 1015 | 1012 | |
| 1016 | − p = &dev->ports[port]; | |
| 1017 | − | |
| 1018 | 1013 | ksz_pread8(dev, port, P_STP_CTRL, &data); |
| 1019 | 1014 | data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE); |
| 1020 | 1015 | |
| 1021 | 1016 | switch (state) { |
| 1022 | 1017 | case BR_STATE_DISABLED: |
| 1023 | 1018 | data |= PORT_LEARN_DISABLE; |
| 1024 | − if (port < dev->phy_port_cnt) | |
| 1025 | − member = 0; | |
| 1026 | 1019 | break; |
| 1027 | 1020 | case BR_STATE_LISTENING: |
| 1028 | 1021 | data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE); |
| 1029 | − if (port < dev->phy_port_cnt && | |
| 1030 | − p->stp_state == BR_STATE_DISABLED) | |
| 1031 | − member = dev->host_mask | p->vid_member; | |
| 1032 | 1022 | break; |
| 1033 | 1023 | case BR_STATE_LEARNING: |
| 1034 | 1024 | data |= PORT_RX_ENABLE; |
| 1035 | 1025 | break; |
| 1036 | 1026 | case BR_STATE_FORWARDING: |
| 1037 | 1027 | data |= (PORT_TX_ENABLE | PORT_RX_ENABLE); |
| 1038 | − | |
| 1039 | − /* This function is also used internally. */ | |
| 1040 | − if (port == dev->cpu_port) | |
| 1041 | − break; | |
| 1042 | − | |
| 1043 | − /* Port is a member of a bridge. */ | |
| 1044 | − if (dev->br_member & BIT(port)) { | |
| 1045 | − dev->member |= BIT(port); | |
| 1046 | − member = dev->member; | |
| 1047 | − } else { | |
| 1048 | − member = dev->host_mask | p->vid_member; | |
| 1049 | − } | |
| 1050 | 1028 | break; |
| 1051 | 1029 | case BR_STATE_BLOCKING: |
| 1052 | 1030 | data |= PORT_LEARN_DISABLE; |
| 1053 | − if (port < dev->phy_port_cnt && | |
| 1054 | − p->stp_state == BR_STATE_DISABLED) | |
| 1055 | − member = dev->host_mask | p->vid_member; | |
| 1056 | 1031 | break; |
| 1057 | 1032 | default: |
| 1058 | 1033 | dev_err(ds->dev, "invalid STP state: %d\n", state); |
| @@ -1060,22 +1035,11 @@ static void ksz8_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) · 1 unmodified line | ||
| 1060 | 1035 | } |
| 1061 | 1036 | |
| 1062 | 1037 | ksz_pwrite8(dev, port, P_STP_CTRL, data); |
| 1038 | + | |
| 1039 | + p = &dev->ports[port]; | |
| 1063 | 1040 | p->stp_state = state; |
| 1064 | − /* Port membership may share register with STP state. */ | |
| 1065 | − if (member >= 0 && member != p->member) | |
| 1066 | − ksz8_cfg_port_member(dev, port, (u8)member); | |
| 1067 | − | |
| 1068 | − /* Check if forwarding needs to be updated. */ | |
| 1069 | − if (state != BR_STATE_FORWARDING) { | |
| 1070 | − if (dev->br_member & BIT(port)) | |
| 1071 | − dev->member &= ~BIT(port); | |
| 1072 | − } | |
| 1073 | 1041 | |
| 1074 | − /* When topology has changed the function ksz_update_port_member | |
| 1075 | − * should be called to modify port forwarding behavior. | |
| 1076 | − */ | |
| 1077 | − if (forward != dev->member) | |
| 1078 | − ksz_update_port_member(dev, port); | |
| 1042 | + ksz_update_port_member(dev, port); | |
| 1079 | 1043 | } |
| 1080 | 1044 | |
| 1081 | 1045 | static void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) |
| @@ -1341,7 +1305,7 @@ static void ksz8795_cpu_interface_select(struct ksz_device *dev, int port) · 259 unmodified lines | ||
| 1341 | 1305 | |
| 1342 | 1306 | static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) |
| 1343 | 1307 | { |
| 1344 | − struct ksz_port *p = &dev->ports[port]; | |
| 1308 | + struct dsa_switch *ds = dev->ds; | |
| 1345 | 1309 | struct ksz8 *ksz8 = dev->priv; |
| 1346 | 1310 | const u32 *masks; |
| 1347 | 1311 | u8 member; |
| @@ -1368,10 +1332,11 @@ static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) · 20 unmodified lines | ||
| 1368 | 1332 | if (!ksz_is_ksz88x3(dev)) |
| 1369 | 1333 | ksz8795_cpu_interface_select(dev, port); |
| 1370 | 1334 | |
| 1371 | − member = dev->port_mask; | |
| 1335 | + member = dsa_user_ports(ds); | |
| 1372 | 1336 | } else { |
| 1373 | − member = dev->host_mask | p->vid_member; | |
| 1337 | + member = BIT(dsa_upstream_port(ds, port)); | |
| 1374 | 1338 | } |
| 1339 | + | |
| 1375 | 1340 | ksz8_cfg_port_member(dev, port, member); |
| 1376 | 1341 | } |
| 1377 | 1342 | |
| @@ -1392,20 +1357,13 @@ static void ksz8_config_cpu_port(struct dsa_switch *ds) · 14 unmodified lines | ||
| 1392 | 1357 | ksz_cfg(dev, regs[S_TAIL_TAG_CTRL], masks[SW_TAIL_TAG_ENABLE], true); |
| 1393 | 1358 | |
| 1394 | 1359 | p = &dev->ports[dev->cpu_port]; |
| 1395 | − p->vid_member = dev->port_mask; | |
| 1396 | 1360 | p->on = 1; |
| 1397 | 1361 | |
| 1398 | 1362 | ksz8_port_setup(dev, dev->cpu_port, true); |
| 1399 | − dev->member = dev->host_mask; | |
| 1400 | 1363 | |
| 1401 | 1364 | for (i = 0; i < dev->phy_port_cnt; i++) { |
| 1402 | 1365 | p = &dev->ports[i]; |
| 1403 | 1366 | |
| 1404 | − /* Initialize to non-zero so that ksz_cfg_port_member() will | |
| 1405 | − * be called. | |
| 1406 | − */ | |
| 1407 | − p->vid_member = BIT(i); | |
| 1408 | − p->member = dev->port_mask; | |
| 1409 | 1367 | ksz8_port_stp_state_set(ds, i, BR_STATE_DISABLED); |
| 1410 | 1368 | |
| 1411 | 1369 | /* Last port may be disabled. */ |
| @@ -391,7 +391,6 @@ static void ksz9477_cfg_port_member(struct ksz_device *dev, int port, · 390 unmodified lines | ||
| 391 | 391 | u8 member) |
| 392 | 392 | { |
| 393 | 393 | ksz_pwrite32(dev, port, REG_PORT_VLAN_MEMBERSHIP__4, member); |
| 394 | − dev->ports[port].member = member; | |
| 395 | 394 | } |
| 396 | 395 | |
| 397 | 396 | static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, |
| @@ -400,8 +399,6 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 400 | 399 | struct ksz_device *dev = ds->priv; |
| 401 | 400 | struct ksz_port *p = &dev->ports[port]; |
| 402 | 401 | u8 data; |
| 403 | − int member = -1; | |
| 404 | − int forward = dev->member; | |
| 405 | 402 | |
| 406 | 403 | ksz_pread8(dev, port, P_STP_CTRL, &data); |
| 407 | 404 | data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE); |
| @@ -409,40 +406,18 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, · 1 unmodified line | ||
| 409 | 406 | switch (state) { |
| 410 | 407 | case BR_STATE_DISABLED: |
| 411 | 408 | data |= PORT_LEARN_DISABLE; |
| 412 | − if (port != dev->cpu_port) | |
| 413 | − member = 0; | |
| 414 | 409 | break; |
| 415 | 410 | case BR_STATE_LISTENING: |
| 416 | 411 | data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE); |
| 417 | − if (port != dev->cpu_port && | |
| 418 | − p->stp_state == BR_STATE_DISABLED) | |
| 419 | − member = dev->host_mask | p->vid_member; | |
| 420 | 412 | break; |
| 421 | 413 | case BR_STATE_LEARNING: |
| 422 | 414 | data |= PORT_RX_ENABLE; |
| 423 | 415 | break; |
| 424 | 416 | case BR_STATE_FORWARDING: |
| 425 | 417 | data |= (PORT_TX_ENABLE | PORT_RX_ENABLE); |
| 426 | − | |
| 427 | − /* This function is also used internally. */ | |
| 428 | − if (port == dev->cpu_port) | |
| 429 | − break; | |
| 430 | − | |
| 431 | − member = dev->host_mask | p->vid_member; | |
| 432 | − mutex_lock(&dev->dev_mutex); | |
| 433 | − | |
| 434 | − /* Port is a member of a bridge. */ | |
| 435 | − if (dev->br_member & (1 << port)) { | |
| 436 | − dev->member |= (1 << port); | |
| 437 | − member = dev->member; | |
| 438 | − } | |
| 439 | − mutex_unlock(&dev->dev_mutex); | |
| 440 | 418 | break; |
| 441 | 419 | case BR_STATE_BLOCKING: |
| 442 | 420 | data |= PORT_LEARN_DISABLE; |
| 443 | − if (port != dev->cpu_port && | |
| 444 | − p->stp_state == BR_STATE_DISABLED) | |
| 445 | − member = dev->host_mask | p->vid_member; | |
| 446 | 421 | break; |
| 447 | 422 | default: |
| 448 | 423 | dev_err(ds->dev, "invalid STP state: %d\n", state); |
| @@ -451,23 +426,8 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 451 | 426 | |
| 452 | 427 | ksz_pwrite8(dev, port, P_STP_CTRL, data); |
| 453 | 428 | p->stp_state = state; |
| 454 | − mutex_lock(&dev->dev_mutex); | |
| 455 | − /* Port membership may share register with STP state. */ | |
| 456 | − if (member >= 0 && member != p->member) | |
| 457 | − ksz9477_cfg_port_member(dev, port, (u8)member); | |
| 458 | − | |
| 459 | − /* Check if forwarding needs to be updated. */ | |
| 460 | − if (state != BR_STATE_FORWARDING) { | |
| 461 | − if (dev->br_member & (1 << port)) | |
| 462 | − dev->member &= ~(1 << port); | |
| 463 | − } | |
| 464 | 429 | |
| 465 | − /* When topology has changed the function ksz_update_port_member | |
| 466 | − * should be called to modify port forwarding behavior. | |
| 467 | − */ | |
| 468 | − if (forward != dev->member) | |
| 469 | − ksz_update_port_member(dev, port); | |
| 470 | − mutex_unlock(&dev->dev_mutex); | |
| 430 | + ksz_update_port_member(dev, port); | |
| 471 | 431 | } |
| 472 | 432 | |
| 473 | 433 | static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port) |
| @@ -1168,10 +1128,10 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port) · 694 unmodified lines | ||
| 1168 | 1128 | |
| 1169 | 1129 | static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) |
| 1170 | 1130 | { |
| 1171 | − u8 data8; | |
| 1172 | − u8 member; | |
| 1173 | − u16 data16; | |
| 1174 | 1131 | struct ksz_port *p = &dev->ports[port]; |
| 1132 | + struct dsa_switch *ds = dev->ds; | |
| 1133 | + u8 data8, member; | |
| 1134 | + u16 data16; | |
| 1175 | 1135 | |
| 1176 | 1136 | /* enable tag tail for host port */ |
| 1177 | 1137 | if (cpu_port) |
| @@ -1250,12 +1210,12 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) · 72 unmodified lines | ||
| 1250 | 1210 | ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8); |
| 1251 | 1211 | p->phydev.duplex = 1; |
| 1252 | 1212 | } |
| 1253 | − mutex_lock(&dev->dev_mutex); | |
| 1213 | + | |
| 1254 | 1214 | if (cpu_port) |
| 1255 | − member = dev->port_mask; | |
| 1215 | + member = dsa_user_ports(ds); | |
| 1256 | 1216 | else |
| 1257 | − member = dev->host_mask | p->vid_member; | |
| 1258 | − mutex_unlock(&dev->dev_mutex); | |
| 1217 | + member = BIT(dsa_upstream_port(ds, port)); | |
| 1218 | + | |
| 1259 | 1219 | ksz9477_cfg_port_member(dev, port, member); |
| 1260 | 1220 | |
| 1261 | 1221 | /* clear pending interrupts */ |
| @@ -1276,8 +1236,6 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds) · 14 unmodified lines | ||
| 1276 | 1236 | const char *prev_mode; |
| 1277 | 1237 | |
| 1278 | 1238 | dev->cpu_port = i; |
| 1279 | − dev->host_mask = (1 << dev->cpu_port); | |
| 1280 | − dev->port_mask |= dev->host_mask; | |
| 1281 | 1239 | p = &dev->ports[i]; |
| 1282 | 1240 | |
| 1283 | 1241 | /* Read from XMII register to determine host port |
| @@ -1312,23 +1270,15 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds) · 28 unmodified lines | ||
| 1312 | 1270 | |
| 1313 | 1271 | /* enable cpu port */ |
| 1314 | 1272 | ksz9477_port_setup(dev, i, true); |
| 1315 | − p->vid_member = dev->port_mask; | |
| 1316 | 1273 | p->on = 1; |
| 1317 | 1274 | } |
| 1318 | 1275 | } |
| 1319 | 1276 | |
| 1320 | − dev->member = dev->host_mask; | |
| 1321 | − | |
| 1322 | 1277 | for (i = 0; i < dev->port_cnt; i++) { |
| 1323 | 1278 | if (i == dev->cpu_port) |
| 1324 | 1279 | continue; |
| 1325 | 1280 | p = &dev->ports[i]; |
| 1326 | 1281 | |
| 1327 | − /* Initialize to non-zero so that ksz_cfg_port_member() will | |
| 1328 | − * be called. | |
| 1329 | − */ | |
| 1330 | − p->vid_member = (1 << i); | |
| 1331 | − p->member = dev->port_mask; | |
| 1332 | 1282 | ksz9477_port_stp_state_set(ds, i, BR_STATE_DISABLED); |
| 1333 | 1283 | p->on = 1; |
| 1334 | 1284 | if (i < dev->phy_port_cnt) |
| @@ -22,21 +22,40 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | void ksz_update_port_member(struct ksz_device *dev, int port) |
| 24 | 24 | { |
| 25 | − struct ksz_port *p; | |
| 25 | + struct ksz_port *p = &dev->ports[port]; | |
| 26 | + struct dsa_switch *ds = dev->ds; | |
| 27 | + u8 port_member = 0, cpu_port; | |
| 28 | + const struct dsa_port *dp; | |
| 26 | 29 | int i; |
| 27 | 30 | |
| 28 | − for (i = 0; i < dev->port_cnt; i++) { | |
| 29 | − if (i == port || i == dev->cpu_port) | |
| 31 | + if (!dsa_is_user_port(ds, port)) | |
| 32 | + return; | |
| 33 | + | |
| 34 | + dp = dsa_to_port(ds, port); | |
| 35 | + cpu_port = BIT(dsa_upstream_port(ds, port)); | |
| 36 | + | |
| 37 | + for (i = 0; i < ds->num_ports; i++) { | |
| 38 | + const struct dsa_port *other_dp = dsa_to_port(ds, i); | |
| 39 | + struct ksz_port *other_p = &dev->ports[i]; | |
| 40 | + u8 val = 0; | |
| 41 | + | |
| 42 | + if (!dsa_is_user_port(ds, i)) | |
| 30 | 43 | continue; |
| 31 | − p = &dev->ports[i]; | |
| 32 | − if (!(dev->member & (1 << i))) | |
| 44 | + if (port == i) | |
| 45 | + continue; | |
| 46 | + if (!dp->bridge_dev || dp->bridge_dev != other_dp->bridge_dev) | |
| 33 | 47 | continue; |
| 34 | 48 | |
| 35 | − /* Port is a member of the bridge and is forwarding. */ | |
| 36 | − if (p->stp_state == BR_STATE_FORWARDING && | |
| 37 | − p->member != dev->member) | |
| 38 | − dev->dev_ops->cfg_port_member(dev, i, dev->member); | |
| 49 | + if (other_p->stp_state == BR_STATE_FORWARDING && | |
| 50 | + p->stp_state == BR_STATE_FORWARDING) { | |
| 51 | + val |= BIT(port); | |
| 52 | + port_member |= BIT(i); | |
| 53 | + } | |
| 54 | + | |
| 55 | + dev->dev_ops->cfg_port_member(dev, i, val | cpu_port); | |
| 39 | 56 | } |
| 57 | + | |
| 58 | + dev->dev_ops->cfg_port_member(dev, port, port_member | cpu_port); | |
| 40 | 59 | } |
| 41 | 60 | EXPORT_SYMBOL_GPL(ksz_update_port_member); |
| 42 | 61 | |
| @@ -175,12 +194,6 @@ EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats); · 132 unmodified lines | ||
| 175 | 194 | int ksz_port_bridge_join(struct dsa_switch *ds, int port, |
| 176 | 195 | struct net_device *br) |
| 177 | 196 | { |
| 178 | − struct ksz_device *dev = ds->priv; | |
| 179 | − | |
| 180 | − mutex_lock(&dev->dev_mutex); | |
| 181 | − dev->br_member |= (1 << port); | |
| 182 | − mutex_unlock(&dev->dev_mutex); | |
| 183 | − | |
| 184 | 197 | /* port_stp_state_set() will be called after to put the port in |
| 185 | 198 | * appropriate state so there is no need to do anything. |
| 186 | 199 | */ |
| @@ -192,13 +205,6 @@ EXPORT_SYMBOL_GPL(ksz_port_bridge_join); · 5 unmodified lines | ||
| 192 | 205 | void ksz_port_bridge_leave(struct dsa_switch *ds, int port, |
| 193 | 206 | struct net_device *br) |
| 194 | 207 | { |
| 195 | − struct ksz_device *dev = ds->priv; | |
| 196 | − | |
| 197 | − mutex_lock(&dev->dev_mutex); | |
| 198 | − dev->br_member &= ~(1 << port); | |
| 199 | − dev->member &= ~(1 << port); | |
| 200 | − mutex_unlock(&dev->dev_mutex); | |
| 201 | − | |
| 202 | 208 | /* port_stp_state_set() will be called after to put the port in |
| 203 | 209 | * forwarding state so there is no need to do anything. |
| 204 | 210 | */ |
| @@ -25,8 +25,6 @@ struct ksz_port_mib { · 24 unmodified lines | ||
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | 27 | struct ksz_port { |
| 28 | − u16 member; | |
| 29 | − u16 vid_member; | |
| 30 | 28 | bool remove_tag; /* Remove Tag flag set, for ksz8795 only */ |
| 31 | 29 | int stp_state; |
| 32 | 30 | struct phy_device phydev; |
| @@ -83,8 +81,6 @@ struct ksz_device { · 50 unmodified lines | ||
| 83 | 81 | struct ksz_port *ports; |
| 84 | 82 | struct delayed_work mib_read; |
| 85 | 83 | unsigned long mib_read_interval; |
| 86 | − u16 br_member; | |
| 87 | − u16 member; | |
| 88 | 84 | u16 mirror_rx; |
| 89 | 85 | u16 mirror_tx; |
| 90 | 86 | u32 features; /* chip specific features */ |
| @@ -471,6 +471,12 @@ static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port) · 470 unmodified lines | ||
| 471 | 471 | u16 reg; |
| 472 | 472 | int err; |
| 473 | 473 | |
| 474 | + /* The 88e6250 family does not have the PHY detect bit. Instead, | |
| 475 | + * report whether the port is internal. | |
| 476 | + */ | |
| 477 | + if (chip->info->family == MV88E6XXX_FAMILY_6250) | |
| 478 | + return port < chip->info->num_internal_phys; | |
| 479 | + | |
| 474 | 480 | err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); |
| 475 | 481 | if (err) { |
| 476 | 482 | dev_err(chip->dev, |
| @@ -692,44 +698,48 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port, · 215 unmodified lines | ||
| 692 | 698 | { |
| 693 | 699 | struct mv88e6xxx_chip *chip = ds->priv; |
| 694 | 700 | struct mv88e6xxx_port *p; |
| 695 | − int err; | |
| 701 | + int err = 0; | |
| 696 | 702 | |
| 697 | 703 | p = &chip->ports[port]; |
| 698 | 704 | |
| 699 | − /* FIXME: is this the correct test? If we're in fixed mode on an | |
| 700 | − * internal port, why should we process this any different from | |
| 701 | − * PHY mode? On the other hand, the port may be automedia between | |
| 702 | − * an internal PHY and the serdes... | |
| 703 | − */ | |
| 704 | − if ((mode == MLO_AN_PHY) && mv88e6xxx_phy_is_internal(ds, port)) | |
| 705 | − return; | |
| 706 | − | |
| 707 | 705 | mv88e6xxx_reg_lock(chip); |
| 708 | − /* In inband mode, the link may come up at any time while the link | |
| 709 | − * is not forced down. Force the link down while we reconfigure the | |
| 710 | − * interface mode. | |
| 711 | − */ | |
| 712 | − if (mode == MLO_AN_INBAND && p->interface != state->interface && | |
| 713 | − chip->info->ops->port_set_link) | |
| 714 | − chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN); | |
| 715 | − | |
| 716 | − err = mv88e6xxx_port_config_interface(chip, port, state->interface); | |
| 717 | − if (err && err != -EOPNOTSUPP) | |
| 718 | − goto err_unlock; | |
| 719 | 706 | |
| 720 | − err = mv88e6xxx_serdes_pcs_config(chip, port, mode, state->interface, | |
| 721 | − state->advertising); | |
| 722 | − /* FIXME: we should restart negotiation if something changed - which | |
| 723 | − * is something we get if we convert to using phylinks PCS operations. | |
| 724 | − */ | |
| 725 | − if (err > 0) | |
| 726 | − err = 0; | |
| 707 | + if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) { | |
| 708 | + /* In inband mode, the link may come up at any time while the | |
| 709 | + * link is not forced down. Force the link down while we | |
| 710 | + * reconfigure the interface mode. | |
| 711 | + */ | |
| 712 | + if (mode == MLO_AN_INBAND && | |
| 713 | + p->interface != state->interface && | |
| 714 | + chip->info->ops->port_set_link) | |
| 715 | + chip->info->ops->port_set_link(chip, port, | |
| 716 | + LINK_FORCED_DOWN); | |
| 717 | + | |
| 718 | + err = mv88e6xxx_port_config_interface(chip, port, | |
| 719 | + state->interface); | |
| 720 | + if (err && err != -EOPNOTSUPP) | |
| 721 | + goto err_unlock; | |
| 722 | + | |
| 723 | + err = mv88e6xxx_serdes_pcs_config(chip, port, mode, | |
| 724 | + state->interface, | |
| 725 | + state->advertising); | |
| 726 | + /* FIXME: we should restart negotiation if something changed - | |
| 727 | + * which is something we get if we convert to using phylinks | |
| 728 | + * PCS operations. | |
| 729 | + */ | |
| 730 | + if (err > 0) | |
| 731 | + err = 0; | |
| 732 | + } | |
| 727 | 733 | |
| 728 | 734 | /* Undo the forced down state above after completing configuration |
| 729 | − * irrespective of its state on entry, which allows the link to come up. | |
| 735 | + * irrespective of its state on entry, which allows the link to come | |
| 736 | + * up in the in-band case where there is no separate SERDES. Also | |
| 737 | + * ensure that the link can come up if the PPU is in use and we are | |
| 738 | + * in PHY mode (we treat the PPU as an effective in-band mechanism.) | |
| 730 | 739 | */ |
| 731 | − if (mode == MLO_AN_INBAND && p->interface != state->interface && | |
| 732 | − chip->info->ops->port_set_link) | |
| 740 | + if (chip->info->ops->port_set_link && | |
| 741 | + ((mode == MLO_AN_INBAND && p->interface != state->interface) || | |
| 742 | + (mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port)))) | |
| 733 | 743 | chip->info->ops->port_set_link(chip, port, LINK_UNFORCED); |
| 734 | 744 | |
| 735 | 745 | p->interface = state->interface; |
| @@ -752,11 +762,10 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port, · 16 unmodified lines | ||
| 752 | 762 | ops = chip->info->ops; |
| 753 | 763 | |
| 754 | 764 | mv88e6xxx_reg_lock(chip); |
| 755 | − /* Internal PHYs propagate their configuration directly to the MAC. | |
| 756 | − * External PHYs depend on whether the PPU is enabled for this port. | |
| 765 | + /* Force the link down if we know the port may not be automatically | |
| 766 | + * updated by the switch or if we are using fixed-link mode. | |
| 757 | 767 | */ |
| 758 | − if (((!mv88e6xxx_phy_is_internal(ds, port) && | |
| 759 | − !mv88e6xxx_port_ppu_updates(chip, port)) || | |
| 768 | + if ((!mv88e6xxx_port_ppu_updates(chip, port) || | |
| 760 | 769 | mode == MLO_AN_FIXED) && ops->port_sync_link) |
| 761 | 770 | err = ops->port_sync_link(chip, port, mode, false); |
| 762 | 771 | mv88e6xxx_reg_unlock(chip); |
| @@ -779,11 +788,11 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port, · 16 unmodified lines | ||
| 779 | 788 | ops = chip->info->ops; |
| 780 | 789 | |
| 781 | 790 | mv88e6xxx_reg_lock(chip); |
| 782 | − /* Internal PHYs propagate their configuration directly to the MAC. | |
| 783 | − * External PHYs depend on whether the PPU is enabled for this port. | |
| 791 | + /* Configure and force the link up if we know that the port may not | |
| 792 | + * automatically updated by the switch or if we are using fixed-link | |
| 793 | + * mode. | |
| 784 | 794 | */ |
| 785 | − if ((!mv88e6xxx_phy_is_internal(ds, port) && | |
| 786 | − !mv88e6xxx_port_ppu_updates(chip, port)) || | |
| 795 | + if (!mv88e6xxx_port_ppu_updates(chip, port) || | |
| 787 | 796 | mode == MLO_AN_FIXED) { |
| 788 | 797 | /* FIXME: for an automedia port, should we force the link |
| 789 | 798 | * down here - what if the link comes up due to "other" media |
| @@ -50,11 +50,22 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, · 49 unmodified lines | ||
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, |
| 53 | − u16 status, u16 lpa, | |
| 53 | + u16 ctrl, u16 status, u16 lpa, | |
| 54 | 54 | struct phylink_link_state *state) |
| 55 | 55 | { |
| 56 | + state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK); | |
| 57 | + | |
| 56 | 58 | if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) { |
| 57 | − state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK); | |
| 59 | + /* The Spped and Duplex Resolved register is 1 if AN is enabled | |
| 60 | + * and complete, or if AN is disabled. So with disabled AN we | |
| 61 | + * still get here on link up. But we want to set an_complete | |
| 62 | + * only if AN was enabled, thus we look at BMCR_ANENABLE. | |
| 63 | + * (According to 802.3-2008 section 22.2.4.2.10, we should be | |
| 64 | + * able to get this same value from BMSR_ANEGCAPABLE, but tests | |
| 65 | + * show that these Marvell PHYs don't conform to this part of | |
| 66 | + * the specificaion - BMSR_ANEGCAPABLE is simply always 1.) | |
| 67 | + */ | |
| 68 | + state->an_complete = !!(ctrl & BMCR_ANENABLE); | |
| 58 | 69 | state->duplex = status & |
| 59 | 70 | MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ? |
| 60 | 71 | DUPLEX_FULL : DUPLEX_HALF; |
| @@ -81,6 +92,18 @@ static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, · 20 unmodified lines | ||
| 81 | 92 | dev_err(chip->dev, "invalid PHY speed\n"); |
| 82 | 93 | return -EINVAL; |
| 83 | 94 | } |
| 95 | + } else if (state->link && | |
| 96 | + state->interface != PHY_INTERFACE_MODE_SGMII) { | |
| 97 | + /* If Speed and Duplex Resolved register is 0 and link is up, it | |
| 98 | + * means that AN was enabled, but link partner had it disabled | |
| 99 | + * and the PHY invoked the Auto-Negotiation Bypass feature and | |
| 100 | + * linked anyway. | |
| 101 | + */ | |
| 102 | + state->duplex = DUPLEX_FULL; | |
| 103 | + if (state->interface == PHY_INTERFACE_MODE_2500BASEX) | |
| 104 | + state->speed = SPEED_2500; | |
| 105 | + else | |
| 106 | + state->speed = SPEED_1000; | |
| 84 | 107 | } else { |
| 85 | 108 | state->link = false; |
| 86 | 109 | } |
| @@ -168,9 +191,15 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, · 81 unmodified lines | ||
| 168 | 191 | int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, |
| 169 | 192 | int lane, struct phylink_link_state *state) |
| 170 | 193 | { |
| 171 | − u16 lpa, status; | |
| 194 | + u16 lpa, status, ctrl; | |
| 172 | 195 | int err; |
| 173 | 196 | |
| 197 | + err = mv88e6352_serdes_read(chip, MII_BMCR, &ctrl); | |
| 198 | + if (err) { | |
| 199 | + dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err); | |
| 200 | + return err; | |
| 201 | + } | |
| 202 | + | |
| 174 | 203 | err = mv88e6352_serdes_read(chip, 0x11, &status); |
| 175 | 204 | if (err) { |
| 176 | 205 | dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err); |
| @@ -183,7 +212,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, · 6 unmodified lines | ||
| 183 | 212 | return err; |
| 184 | 213 | } |
| 185 | 214 | |
| 186 | − return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state); | |
| 215 | + return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state); | |
| 187 | 216 | } |
| 188 | 217 | |
| 189 | 218 | int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, |
| @@ -801,7 +830,7 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, · 611 unmodified lines | ||
| 801 | 830 | bool up) |
| 802 | 831 | { |
| 803 | 832 | u8 cmode = chip->ports[port].cmode; |
| 804 | − int err = 0; | |
| 833 | + int err; | |
| 805 | 834 | |
| 806 | 835 | switch (cmode) { |
| 807 | 836 | case MV88E6XXX_PORT_STS_CMODE_SGMII: |
| @@ -813,6 +842,9 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, · 5 unmodified lines | ||
| 813 | 842 | case MV88E6XXX_PORT_STS_CMODE_RXAUI: |
| 814 | 843 | err = mv88e6390_serdes_power_10g(chip, lane, up); |
| 815 | 844 | break; |
| 845 | + default: | |
| 846 | + err = -EINVAL; | |
| 847 | + break; | |
| 816 | 848 | } |
| 817 | 849 | |
| 818 | 850 | if (!err && up) |
| @@ -883,9 +915,16 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, · 64 unmodified lines | ||
| 883 | 915 | static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, |
| 884 | 916 | int port, int lane, struct phylink_link_state *state) |
| 885 | 917 | { |
| 886 | − u16 lpa, status; | |
| 918 | + u16 lpa, status, ctrl; | |
| 887 | 919 | int err; |
| 888 | 920 | |
| 921 | + err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, | |
| 922 | + MV88E6390_SGMII_BMCR, &ctrl); | |
| 923 | + if (err) { | |
| 924 | + dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err); | |
| 925 | + return err; | |
| 926 | + } | |
| 927 | + | |
| 889 | 928 | err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, |
| 890 | 929 | MV88E6390_SGMII_PHY_STATUS, &status); |
| 891 | 930 | if (err) { |
| @@ -900,7 +939,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, · 8 unmodified lines | ||
| 900 | 939 | return err; |
| 901 | 940 | } |
| 902 | 941 | |
| 903 | − return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state); | |
| 942 | + return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state); | |
| 904 | 943 | } |
| 905 | 944 | |
| 906 | 945 | static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip, |
| @@ -1271,9 +1310,31 @@ void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p) · 364 unmodified lines | ||
| 1271 | 1310 | } |
| 1272 | 1311 | } |
| 1273 | 1312 | |
| 1274 | −static int mv88e6393x_serdes_port_errata(struct mv88e6xxx_chip *chip, int lane) | |
| 1313 | +static int mv88e6393x_serdes_power_lane(struct mv88e6xxx_chip *chip, int lane, | |
| 1314 | + bool on) | |
| 1275 | 1315 | { |
| 1276 | − u16 reg, pcs; | |
| 1316 | + u16 reg; | |
| 1317 | + int err; | |
| 1318 | + | |
| 1319 | + err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, | |
| 1320 | + MV88E6393X_SERDES_CTRL1, ®); | |
| 1321 | + if (err) | |
| 1322 | + return err; | |
| 1323 | + | |
| 1324 | + if (on) | |
| 1325 | + reg &= ~(MV88E6393X_SERDES_CTRL1_TX_PDOWN | | |
| 1326 | + MV88E6393X_SERDES_CTRL1_RX_PDOWN); | |
| 1327 | + else | |
| 1328 | + reg |= MV88E6393X_SERDES_CTRL1_TX_PDOWN | | |
| 1329 | + MV88E6393X_SERDES_CTRL1_RX_PDOWN; | |
| 1330 | + | |
| 1331 | + return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, | |
| 1332 | + MV88E6393X_SERDES_CTRL1, reg); | |
| 1333 | +} | |
| 1334 | + | |
| 1335 | +static int mv88e6393x_serdes_erratum_4_6(struct mv88e6xxx_chip *chip, int lane) | |
| 1336 | +{ | |
| 1337 | + u16 reg; | |
| 1277 | 1338 | int err; |
| 1278 | 1339 | |
| 1279 | 1340 | /* mv88e6393x family errata 4.6: |
| @@ -1284,26 +1345,45 @@ static int mv88e6393x_serdes_port_errata(struct mv88e6xxx_chip *chip, int lane) · 4 unmodified lines | ||
| 1284 | 1345 | * It seems that after this workaround the SERDES is automatically |
| 1285 | 1346 | * powered up (the bit is cleared), so power it down. |
| 1286 | 1347 | */ |
| 1287 | − if (lane == MV88E6393X_PORT0_LANE || lane == MV88E6393X_PORT9_LANE || | |
| 1288 | − lane == MV88E6393X_PORT10_LANE) { | |
| 1289 | − err = mv88e6390_serdes_read(chip, lane, | |
| 1290 | − MDIO_MMD_PHYXS, | |
| 1291 | − MV88E6393X_SERDES_POC, ®); | |
| 1292 | − if (err) | |
| 1293 | − return err; | |
| 1348 | + err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, | |
| 1349 | + MV88E6393X_SERDES_POC, ®); | |
| 1350 | + if (err) | |
| 1351 | + return err; | |
| 1294 | 1352 | |
| 1295 | − reg &= ~MV88E6393X_SERDES_POC_PDOWN; | |
| 1296 | − reg |= MV88E6393X_SERDES_POC_RESET; | |
| 1353 | + reg &= ~MV88E6393X_SERDES_POC_PDOWN; | |
| 1354 | + reg |= MV88E6393X_SERDES_POC_RESET; | |
| 1297 | 1355 | |
| 1298 | − err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, | |
| 1299 | − MV88E6393X_SERDES_POC, reg); | |
| 1300 | − if (err) | |
| 1301 | − return err; | |
| 1356 | + err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, | |
| 1357 | + MV88E6393X_SERDES_POC, reg); | |
| 1358 | + if (err) | |
| 1359 | + return err; | |
| 1302 | 1360 | |
| 1303 | − err = mv88e6390_serdes_power_sgmii(chip, lane, false); | |
| 1304 | − if (err) | |
| 1305 | − return err; | |
| 1306 | − } | |
| 1361 | + err = mv88e6390_serdes_power_sgmii(chip, lane, false); | |
| 1362 | + if (err) | |
| 1363 | + return err; | |
| 1364 | + | |
| 1365 | + return mv88e6393x_serdes_power_lane(chip, lane, false); | |
| 1366 | +} | |
| 1367 | + | |
| 1368 | +int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip) | |
| 1369 | +{ | |
| 1370 | + int err; | |
| 1371 | + | |
| 1372 | + err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT0_LANE); | |
| 1373 | + if (err) | |
| 1374 | + return err; | |
| 1375 | + | |
| 1376 | + err = mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT9_LANE); | |
| 1377 | + if (err) | |
| 1378 | + return err; | |
| 1379 | + | |
| 1380 | + return mv88e6393x_serdes_erratum_4_6(chip, MV88E6393X_PORT10_LANE); | |
| 1381 | +} | |
| 1382 | + | |
| 1383 | +static int mv88e6393x_serdes_erratum_4_8(struct mv88e6xxx_chip *chip, int lane) | |
| 1384 | +{ | |
| 1385 | + u16 reg, pcs; | |
| 1386 | + int err; | |
| 1307 | 1387 | |
| 1308 | 1388 | /* mv88e6393x family errata 4.8: |
| 1309 | 1389 | * When a SERDES port is operating in 1000BASE-X or SGMII mode link may |
| @@ -1334,38 +1414,152 @@ static int mv88e6393x_serdes_port_errata(struct mv88e6xxx_chip *chip, int lane) · 24 unmodified lines | ||
| 1334 | 1414 | MV88E6393X_ERRATA_4_8_REG, reg); |
| 1335 | 1415 | } |
| 1336 | 1416 | |
| 1337 | −int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip) | |
| 1417 | +static int mv88e6393x_serdes_erratum_5_2(struct mv88e6xxx_chip *chip, int lane, | |
| 1418 | + u8 cmode) | |
| 1419 | +{ | |
| 1420 | + static const struct { | |
| 1421 | + u16 dev, reg, val, mask; | |
| 1422 | + } fixes[] = { | |
| 1423 | + { MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff }, | |
| 1424 | + { MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff }, | |
| 1425 | + { MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff }, | |
| 1426 | + { MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f }, | |
| 1427 | + { MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 }, | |
| 1428 | + { MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff }, | |
| 1429 | + { MDIO_MMD_PHYXS, MV88E6393X_SERDES_POC, | |
| 1430 | + MV88E6393X_SERDES_POC_RESET, MV88E6393X_SERDES_POC_RESET }, | |
| 1431 | + }; | |
| 1432 | + int err, i; | |
| 1433 | + u16 reg; | |
| 1434 | + | |
| 1435 | + /* mv88e6393x family errata 5.2: | |
| 1436 | + * For optimal signal integrity the following sequence should be applied | |
| 1437 | + * to SERDES operating in 10G mode. These registers only apply to 10G | |
| 1438 | + * operation and have no effect on other speeds. | |
| 1439 | + */ | |
| 1440 | + if (cmode != MV88E6393X_PORT_STS_CMODE_10GBASER) | |
| 1441 | + return 0; | |
| 1442 | + | |
| 1443 | + for (i = 0; i < ARRAY_SIZE(fixes); ++i) { | |
| 1444 | + err = mv88e6390_serdes_read(chip, lane, fixes[i].dev, | |
| 1445 | + fixes[i].reg, ®); | |
| 1446 | + if (err) | |
| 1447 | + return err; | |
| 1448 | + | |
| 1449 | + reg &= ~fixes[i].mask; | |
| 1450 | + reg |= fixes[i].val; | |
| 1451 | + | |
| 1452 | + err = mv88e6390_serdes_write(chip, lane, fixes[i].dev, | |
| 1453 | + fixes[i].reg, reg); | |
| 1454 | + if (err) | |
| 1455 | + return err; | |
| 1456 | + } | |
| 1457 | + | |
| 1458 | + return 0; | |
| 1459 | +} | |
| 1460 | + | |
| 1461 | +static int mv88e6393x_serdes_fix_2500basex_an(struct mv88e6xxx_chip *chip, | |
| 1462 | + int lane, u8 cmode, bool on) | |
| 1338 | 1463 | { |
| 1464 | + u16 reg; | |
| 1339 | 1465 | int err; |
| 1340 | 1466 | |
| 1341 | − err = mv88e6393x_serdes_port_errata(chip, MV88E6393X_PORT0_LANE); | |
| 1467 | + if (cmode != MV88E6XXX_PORT_STS_CMODE_2500BASEX) | |
| 1468 | + return 0; | |
| 1469 | + | |
| 1470 | + /* Inband AN is broken on Amethyst in 2500base-x mode when set by | |
| 1471 | + * standard mechanism (via cmode). | |
| 1472 | + * We can get around this by configuring the PCS mode to 1000base-x | |
| 1473 | + * and then writing value 0x58 to register 1e.8000. (This must be done | |
| 1474 | + * while SerDes receiver and transmitter are disabled, which is, when | |
| 1475 | + * this function is called.) | |
| 1476 | + * It seem that when we do this configuration to 2500base-x mode (by | |
| 1477 | + * changing PCS mode to 1000base-x and frequency to 3.125 GHz from | |
| 1478 | + * 1.25 GHz) and then configure to sgmii or 1000base-x, the device | |
| 1479 | + * thinks that it already has SerDes at 1.25 GHz and does not change | |
| 1480 | + * the 1e.8000 register, leaving SerDes at 3.125 GHz. | |
| 1481 | + * To avoid this, change PCS mode back to 2500base-x when disabling | |
| 1482 | + * SerDes from 2500base-x mode. | |
| 1483 | + */ | |
| 1484 | + err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, | |
| 1485 | + MV88E6393X_SERDES_POC, ®); | |
| 1486 | + if (err) | |
| 1487 | + return err; | |
| 1488 | + | |
| 1489 | + reg &= ~(MV88E6393X_SERDES_POC_PCS_MASK | MV88E6393X_SERDES_POC_AN); | |
| 1490 | + if (on) | |
| 1491 | + reg |= MV88E6393X_SERDES_POC_PCS_1000BASEX | | |
| 1492 | + MV88E6393X_SERDES_POC_AN; | |
| 1493 | + else | |
| 1494 | + reg |= MV88E6393X_SERDES_POC_PCS_2500BASEX; | |
| 1495 | + reg |= MV88E6393X_SERDES_POC_RESET; | |
| 1496 | + | |
| 1497 | + err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, | |
| 1498 | + MV88E6393X_SERDES_POC, reg); | |
| 1342 | 1499 | if (err) |
| 1343 | 1500 | return err; |
| 1344 | 1501 | |
| 1345 | − err = mv88e6393x_serdes_port_errata(chip, MV88E6393X_PORT9_LANE); | |
| 1502 | + err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_VEND1, 0x8000, 0x58); | |
| 1346 | 1503 | if (err) |
| 1347 | 1504 | return err; |
| 1348 | 1505 | |
| 1349 | − return mv88e6393x_serdes_port_errata(chip, MV88E6393X_PORT10_LANE); | |
| 1506 | + return 0; | |
| 1350 | 1507 | } |
| 1351 | 1508 | |
| 1352 | 1509 | int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, |
| 1353 | 1510 | bool on) |
| 1354 | 1511 | { |
| 1355 | 1512 | u8 cmode = chip->ports[port].cmode; |
| 1513 | + int err; | |
| 1356 | 1514 | |
| 1357 | 1515 | if (port != 0 && port != 9 && port != 10) |
| 1358 | 1516 | return -EOPNOTSUPP; |
| 1359 | 1517 | |
| 1518 | + if (on) { | |
| 1519 | + err = mv88e6393x_serdes_erratum_4_8(chip, lane); | |
| 1520 | + if (err) | |
| 1521 | + return err; | |
| 1522 | + | |
| 1523 | + err = mv88e6393x_serdes_erratum_5_2(chip, lane, cmode); | |
| 1524 | + if (err) | |
| 1525 | + return err; | |
| 1526 | + | |
| 1527 | + err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode, | |
| 1528 | + true); | |
| 1529 | + if (err) | |
| 1530 | + return err; | |
| 1531 | + | |
| 1532 | + err = mv88e6393x_serdes_power_lane(chip, lane, true); | |
| 1533 | + if (err) | |
| 1534 | + return err; | |
| 1535 | + } | |
| 1536 | + | |
| 1360 | 1537 | switch (cmode) { |
| 1361 | 1538 | case MV88E6XXX_PORT_STS_CMODE_SGMII: |
| 1362 | 1539 | case MV88E6XXX_PORT_STS_CMODE_1000BASEX: |
| 1363 | 1540 | case MV88E6XXX_PORT_STS_CMODE_2500BASEX: |
| 1364 | − return mv88e6390_serdes_power_sgmii(chip, lane, on); | |
| 1541 | + err = mv88e6390_serdes_power_sgmii(chip, lane, on); | |
| 1542 | + break; | |
| 1365 | 1543 | case MV88E6393X_PORT_STS_CMODE_5GBASER: |
| 1366 | 1544 | case MV88E6393X_PORT_STS_CMODE_10GBASER: |
| 1367 | − return mv88e6390_serdes_power_10g(chip, lane, on); | |
| 1545 | + err = mv88e6390_serdes_power_10g(chip, lane, on); | |
| 1546 | + break; | |
| 1547 | + default: | |
| 1548 | + err = -EINVAL; | |
| 1549 | + break; | |
| 1368 | 1550 | } |
| 1369 | 1551 | |
| 1370 | − return 0; | |
| 1552 | + if (err) | |
| 1553 | + return err; | |
| 1554 | + | |
| 1555 | + if (!on) { | |
| 1556 | + err = mv88e6393x_serdes_power_lane(chip, lane, false); | |
| 1557 | + if (err) | |
| 1558 | + return err; | |
| 1559 | + | |
| 1560 | + err = mv88e6393x_serdes_fix_2500basex_an(chip, lane, cmode, | |
| 1561 | + false); | |
| 1562 | + } | |
| 1563 | + | |
| 1564 | + return err; | |
| 1371 | 1565 | } |
| @@ -93,6 +93,10 @@ · 92 unmodified lines | ||
| 93 | 93 | #define MV88E6393X_SERDES_POC_PCS_MASK 0x0007 |
| 94 | 94 | #define MV88E6393X_SERDES_POC_RESET BIT(15) |
| 95 | 95 | #define MV88E6393X_SERDES_POC_PDOWN BIT(5) |
| 96 | +#define MV88E6393X_SERDES_POC_AN BIT(3) | |
| 97 | +#define MV88E6393X_SERDES_CTRL1 0xf003 | |
| 98 | +#define MV88E6393X_SERDES_CTRL1_TX_PDOWN BIT(9) | |
| 99 | +#define MV88E6393X_SERDES_CTRL1_RX_PDOWN BIT(8) | |
| 96 | 100 | |
| 97 | 101 | #define MV88E6393X_ERRATA_4_8_REG 0xF074 |
| 98 | 102 | #define MV88E6393X_ERRATA_4_8_BIT BIT(14) |
| @@ -290,8 +290,11 @@ static int felix_setup_mmio_filtering(struct felix *felix) · 289 unmodified lines | ||
| 290 | 290 | } |
| 291 | 291 | } |
| 292 | 292 | |
| 293 | − if (cpu < 0) | |
| 293 | + if (cpu < 0) { | |
| 294 | + kfree(tagging_rule); | |
| 295 | + kfree(redirect_rule); | |
| 294 | 296 | return -EINVAL; |
| 297 | + } | |
| 295 | 298 | |
| 296 | 299 | tagging_rule->key_type = OCELOT_VCAP_KEY_ETYPE; |
| 297 | 300 | *(__be16 *)tagging_rule->key.etype.etype.value = htons(ETH_P_1588); |
| @@ -1256,8 +1256,12 @@ qca8k_setup(struct dsa_switch *ds) · 1255 unmodified lines | ||
| 1256 | 1256 | /* Set initial MTU for every port. |
| 1257 | 1257 | * We have only have a general MTU setting. So track |
| 1258 | 1258 | * every port and set the max across all port. |
| 1259 | + * Set per port MTU to 1500 as the MTU change function | |
| 1260 | + * will add the overhead and if its set to 1518 then it | |
| 1261 | + * will apply the overhead again and we will end up with | |
| 1262 | + * MTU of 1536 instead of 1518 | |
| 1259 | 1263 | */ |
| 1260 | − priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN; | |
| 1264 | + priv->port_mtu[i] = ETH_DATA_LEN; | |
| 1261 | 1265 | } |
| 1262 | 1266 | |
| 1263 | 1267 | /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ |
| @@ -1433,6 +1437,12 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, · 169 unmodified lines | ||
| 1433 | 1437 | |
| 1434 | 1438 | qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); |
| 1435 | 1439 | |
| 1440 | + /* From original code is reported port instability as SGMII also | |
| 1441 | + * require delay set. Apply advised values here or take them from DT. | |
| 1442 | + */ | |
| 1443 | + if (state->interface == PHY_INTERFACE_MODE_SGMII) | |
| 1444 | + qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); | |
| 1445 | + | |
| 1436 | 1446 | /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and |
| 1437 | 1447 | * falling edge is set writing in the PORT0 PAD reg |
| 1438 | 1448 | */ |
| @@ -1455,12 +1465,6 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, · 16 unmodified lines | ||
| 1455 | 1465 | QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, |
| 1456 | 1466 | val); |
| 1457 | 1467 | |
| 1458 | − /* From original code is reported port instability as SGMII also | |
| 1459 | − * require delay set. Apply advised values here or take them from DT. | |
| 1460 | − */ | |
| 1461 | − if (state->interface == PHY_INTERFACE_MODE_SGMII) | |
| 1462 | − qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); | |
| 1463 | − | |
| 1464 | 1468 | break; |
| 1465 | 1469 | default: |
| 1466 | 1470 | dev_err(ds->dev, "xMII mode %s not supported for port %d\n", |
| @@ -107,6 +107,7 @@ · 106 unmodified lines | ||
| 107 | 107 | #define RTL8365MB_LEARN_LIMIT_MAX_8365MB_VC 2112 |
| 108 | 108 | |
| 109 | 109 | /* Family-specific data and limits */ |
| 110 | +#define RTL8365MB_PHYADDRMAX 7 | |
| 110 | 111 | #define RTL8365MB_NUM_PHYREGS 32 |
| 111 | 112 | #define RTL8365MB_PHYREGMAX (RTL8365MB_NUM_PHYREGS - 1) |
| 112 | 113 | #define RTL8365MB_MAX_NUM_PORTS (RTL8365MB_CPU_PORT_NUM_8365MB_VC + 1) |
| @@ -176,7 +177,7 @@ · 63 unmodified lines | ||
| 176 | 177 | #define RTL8365MB_INDIRECT_ACCESS_STATUS_REG 0x1F01 |
| 177 | 178 | #define RTL8365MB_INDIRECT_ACCESS_ADDRESS_REG 0x1F02 |
| 178 | 179 | #define RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_5_1_MASK GENMASK(4, 0) |
| 179 | −#define RTL8365MB_INDIRECT_ACCESS_ADDRESS_PHYNUM_MASK GENMASK(6, 5) | |
| 180 | +#define RTL8365MB_INDIRECT_ACCESS_ADDRESS_PHYNUM_MASK GENMASK(7, 5) | |
| 180 | 181 | #define RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_9_6_MASK GENMASK(11, 8) |
| 181 | 182 | #define RTL8365MB_PHY_BASE 0x2000 |
| 182 | 183 | #define RTL8365MB_INDIRECT_ACCESS_WRITE_DATA_REG 0x1F03 |
| @@ -679,6 +680,9 @@ static int rtl8365mb_phy_read(struct realtek_smi *smi, int phy, int regnum) · 496 unmodified lines | ||
| 679 | 680 | u16 val; |
| 680 | 681 | int ret; |
| 681 | 682 | |
| 683 | + if (phy > RTL8365MB_PHYADDRMAX) | |
| 684 | + return -EINVAL; | |
| 685 | + | |
| 682 | 686 | if (regnum > RTL8365MB_PHYREGMAX) |
| 683 | 687 | return -EINVAL; |
| 684 | 688 | |
| @@ -704,6 +708,9 @@ static int rtl8365mb_phy_write(struct realtek_smi *smi, int phy, int regnum, · 19 unmodified lines | ||
| 704 | 708 | u32 ocp_addr; |
| 705 | 709 | int ret; |
| 706 | 710 | |
| 711 | + if (phy > RTL8365MB_PHYADDRMAX) | |
| 712 | + return -EINVAL; | |
| 713 | + | |
| 707 | 714 | if (regnum > RTL8365MB_PHYREGMAX) |
| 708 | 715 | return -EINVAL; |
| 709 | 716 | |
| @@ -1430,16 +1430,19 @@ static int altera_tse_probe(struct platform_device *pdev) · 1429 unmodified lines | ||
| 1430 | 1430 | priv->rxdescmem_busaddr = dma_res->start; |
| 1431 | 1431 | |
| 1432 | 1432 | } else { |
| 1433 | + ret = -ENODEV; | |
| 1433 | 1434 | goto err_free_netdev; |
| 1434 | 1435 | } |
| 1435 | 1436 | |
| 1436 | − if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) | |
| 1437 | + if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) { | |
| 1437 | 1438 | dma_set_coherent_mask(priv->device, |
| 1438 | 1439 | DMA_BIT_MASK(priv->dmaops->dmamask)); |
| 1439 | − else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) | |
| 1440 | + } else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) { | |
| 1440 | 1441 | dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32)); |
| 1441 | − else | |
| 1442 | + } else { | |
| 1443 | + ret = -EIO; | |
| 1442 | 1444 | goto err_free_netdev; |
| 1445 | + } | |
| 1443 | 1446 | |
| 1444 | 1447 | /* MAC address space */ |
| 1445 | 1448 | ret = request_and_map(pdev, "control_port", &control_port, |
| @@ -40,10 +40,12 @@ · 39 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | #define AQ_DEVICE_ID_AQC113DEV 0x00C0 |
| 42 | 42 | #define AQ_DEVICE_ID_AQC113CS 0x94C0 |
| 43 | +#define AQ_DEVICE_ID_AQC113CA 0x34C0 | |
| 43 | 44 | #define AQ_DEVICE_ID_AQC114CS 0x93C0 |
| 44 | 45 | #define AQ_DEVICE_ID_AQC113 0x04C0 |
| 45 | 46 | #define AQ_DEVICE_ID_AQC113C 0x14C0 |
| 46 | 47 | #define AQ_DEVICE_ID_AQC115C 0x12C0 |
| 48 | +#define AQ_DEVICE_ID_AQC116C 0x11C0 | |
| 47 | 49 | |
| 48 | 50 | #define HW_ATL_NIC_NAME "Marvell (aQuantia) AQtion 10Gbit Network Adapter" |
| 49 | 51 | |
| @@ -53,20 +55,19 @@ · 3 unmodified lines | ||
| 53 | 55 | |
| 54 | 56 | #define AQ_NIC_RATE_10G BIT(0) |
| 55 | 57 | #define AQ_NIC_RATE_5G BIT(1) |
| 56 | −#define AQ_NIC_RATE_5GSR BIT(2) | |
| 57 | −#define AQ_NIC_RATE_2G5 BIT(3) | |
| 58 | −#define AQ_NIC_RATE_1G BIT(4) | |
| 59 | −#define AQ_NIC_RATE_100M BIT(5) | |
| 60 | −#define AQ_NIC_RATE_10M BIT(6) | |
| 61 | −#define AQ_NIC_RATE_1G_HALF BIT(7) | |
| 62 | −#define AQ_NIC_RATE_100M_HALF BIT(8) | |
| 63 | −#define AQ_NIC_RATE_10M_HALF BIT(9) | |
| 58 | +#define AQ_NIC_RATE_2G5 BIT(2) | |
| 59 | +#define AQ_NIC_RATE_1G BIT(3) | |
| 60 | +#define AQ_NIC_RATE_100M BIT(4) | |
| 61 | +#define AQ_NIC_RATE_10M BIT(5) | |
| 62 | +#define AQ_NIC_RATE_1G_HALF BIT(6) | |
| 63 | +#define AQ_NIC_RATE_100M_HALF BIT(7) | |
| 64 | +#define AQ_NIC_RATE_10M_HALF BIT(8) | |
| 64 | 65 | |
| 65 | −#define AQ_NIC_RATE_EEE_10G BIT(10) | |
| 66 | −#define AQ_NIC_RATE_EEE_5G BIT(11) | |
| 67 | −#define AQ_NIC_RATE_EEE_2G5 BIT(12) | |
| 68 | −#define AQ_NIC_RATE_EEE_1G BIT(13) | |
| 69 | −#define AQ_NIC_RATE_EEE_100M BIT(14) | |
| 66 | +#define AQ_NIC_RATE_EEE_10G BIT(9) | |
| 67 | +#define AQ_NIC_RATE_EEE_5G BIT(10) | |
| 68 | +#define AQ_NIC_RATE_EEE_2G5 BIT(11) | |
| 69 | +#define AQ_NIC_RATE_EEE_1G BIT(12) | |
| 70 | +#define AQ_NIC_RATE_EEE_100M BIT(13) | |
| 70 | 71 | #define AQ_NIC_RATE_EEE_MSK (AQ_NIC_RATE_EEE_10G |\ |
| 71 | 72 | AQ_NIC_RATE_EEE_5G |\ |
| 72 | 73 | AQ_NIC_RATE_EEE_2G5 |\ |
| @@ -80,6 +80,8 @@ struct aq_hw_link_status_s { · 79 unmodified lines | ||
| 80 | 80 | }; |
| 81 | 81 | |
| 82 | 82 | struct aq_stats_s { |
| 83 | + u64 brc; | |
| 84 | + u64 btc; | |
| 83 | 85 | u64 uprc; |
| 84 | 86 | u64 mprc; |
| 85 | 87 | u64 bprc; |
| @@ -316,18 +316,22 @@ int aq_nic_ndev_register(struct aq_nic_s *self) · 315 unmodified lines | ||
| 316 | 316 | aq_macsec_init(self); |
| 317 | 317 | #endif |
| 318 | 318 | |
| 319 | − mutex_lock(&self->fwreq_mutex); | |
| 320 | − err = self->aq_fw_ops->get_mac_permanent(self->aq_hw, addr); | |
| 321 | − mutex_unlock(&self->fwreq_mutex); | |
| 322 | − if (err) | |
| 323 | − goto err_exit; | |
| 319 | + if (platform_get_ethdev_address(&self->pdev->dev, self->ndev) != 0) { | |
| 320 | + // If DT has none or an invalid one, ask device for MAC address | |
| 321 | + mutex_lock(&self->fwreq_mutex); | |
| 322 | + err = self->aq_fw_ops->get_mac_permanent(self->aq_hw, addr); | |
| 323 | + mutex_unlock(&self->fwreq_mutex); | |
| 324 | 324 | |
| 325 | − eth_hw_addr_set(self->ndev, addr); | |
| 325 | + if (err) | |
| 326 | + goto err_exit; | |
| 326 | 327 | |
| 327 | − if (!is_valid_ether_addr(self->ndev->dev_addr) || | |
| 328 | − !aq_nic_is_valid_ether_addr(self->ndev->dev_addr)) { | |
| 329 | − netdev_warn(self->ndev, "MAC is invalid, will use random."); | |
| 330 | − eth_hw_addr_random(self->ndev); | |
| 328 | + if (is_valid_ether_addr(addr) && | |
| 329 | + aq_nic_is_valid_ether_addr(addr)) { | |
| 330 | + eth_hw_addr_set(self->ndev, addr); | |
| 331 | + } else { | |
| 332 | + netdev_warn(self->ndev, "MAC is invalid, will use random."); | |
| 333 | + eth_hw_addr_random(self->ndev); | |
| 334 | + } | |
| 331 | 335 | } |
| 332 | 336 | |
| 333 | 337 | #if defined(AQ_CFG_MAC_ADDR_PERMANENT) |
| @@ -905,8 +909,14 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data) · 571 unmodified lines | ||
| 905 | 909 | data[++i] = stats->mbtc; |
| 906 | 910 | data[++i] = stats->bbrc; |
| 907 | 911 | data[++i] = stats->bbtc; |
| 908 | − data[++i] = stats->ubrc + stats->mbrc + stats->bbrc; | |
| 909 | − data[++i] = stats->ubtc + stats->mbtc + stats->bbtc; | |
| 912 | + if (stats->brc) | |
| 913 | + data[++i] = stats->brc; | |
| 914 | + else | |
| 915 | + data[++i] = stats->ubrc + stats->mbrc + stats->bbrc; | |
| 916 | + if (stats->btc) | |
| 917 | + data[++i] = stats->btc; | |
| 918 | + else | |
| 919 | + data[++i] = stats->ubtc + stats->mbtc + stats->bbtc; | |
| 910 | 920 | data[++i] = stats->dma_pkt_rc; |
| 911 | 921 | data[++i] = stats->dma_pkt_tc; |
| 912 | 922 | data[++i] = stats->dma_oct_rc; |
| @@ -49,6 +49,8 @@ static const struct pci_device_id aq_pci_tbl[] = { · 48 unmodified lines | ||
| 49 | 49 | { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113), }, |
| 50 | 50 | { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113C), }, |
| 51 | 51 | { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC115C), }, |
| 52 | + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113CA), }, | |
| 53 | + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC116C), }, | |
| 52 | 54 | |
| 53 | 55 | {} |
| 54 | 56 | }; |
| @@ -85,7 +87,10 @@ static const struct aq_board_revision_s hw_atl_boards[] = { · 30 unmodified lines | ||
| 85 | 87 | { AQ_DEVICE_ID_AQC113CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, |
| 86 | 88 | { AQ_DEVICE_ID_AQC114CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, |
| 87 | 89 | { AQ_DEVICE_ID_AQC113C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, |
| 88 | − { AQ_DEVICE_ID_AQC115C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, | |
| 90 | + { AQ_DEVICE_ID_AQC115C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc115c, }, | |
| 91 | + { AQ_DEVICE_ID_AQC113CA, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, | |
| 92 | + { AQ_DEVICE_ID_AQC116C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc116c, }, | |
| 93 | + | |
| 89 | 94 | }; |
| 90 | 95 | |
| 91 | 96 | MODULE_DEVICE_TABLE(pci, aq_pci_tbl); |
| @@ -298,13 +298,14 @@ bool aq_ring_tx_clean(struct aq_ring_s *self) · 297 unmodified lines | ||
| 298 | 298 | } |
| 299 | 299 | } |
| 300 | 300 | |
| 301 | − if (unlikely(buff->is_eop)) { | |
| 301 | + if (unlikely(buff->is_eop && buff->skb)) { | |
| 302 | 302 | u64_stats_update_begin(&self->stats.tx.syncp); |
| 303 | 303 | ++self->stats.tx.packets; |
| 304 | 304 | self->stats.tx.bytes += buff->skb->len; |
| 305 | 305 | u64_stats_update_end(&self->stats.tx.syncp); |
| 306 | 306 | |
| 307 | 307 | dev_kfree_skb_any(buff->skb); |
| 308 | + buff->skb = NULL; | |
| 308 | 309 | } |
| 309 | 310 | buff->pa = 0U; |
| 310 | 311 | buff->eop_index = 0xffffU; |
| @@ -362,9 +362,6 @@ unsigned int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u · 361 unmodified lines | ||
| 362 | 362 | { |
| 363 | 363 | unsigned int count; |
| 364 | 364 | |
| 365 | − WARN_ONCE(!aq_vec_is_valid_tc(self, tc), | |
| 366 | − "Invalid tc %u (#rx=%u, #tx=%u)\n", | |
| 367 | − tc, self->rx_rings, self->tx_rings); | |
| 368 | 365 | if (!aq_vec_is_valid_tc(self, tc)) |
| 369 | 366 | return 0; |
| 370 | 367 | |
| @@ -559,6 +559,11 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self, · 558 unmodified lines | ||
| 559 | 559 | goto err_exit; |
| 560 | 560 | |
| 561 | 561 | if (fw.len == 0xFFFFU) { |
| 562 | + if (sw.len > sizeof(self->rpc)) { | |
| 563 | + printk(KERN_INFO "Invalid sw len: %x\n", sw.len); | |
| 564 | + err = -EINVAL; | |
| 565 | + goto err_exit; | |
| 566 | + } | |
| 562 | 567 | err = hw_atl_utils_fw_rpc_call(self, sw.len); |
| 563 | 568 | if (err < 0) |
| 564 | 569 | goto err_exit; |
| @@ -567,6 +572,11 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self, · 2 unmodified lines | ||
| 567 | 572 | |
| 568 | 573 | if (rpc) { |
| 569 | 574 | if (fw.len) { |
| 575 | + if (fw.len > sizeof(self->rpc)) { | |
| 576 | + printk(KERN_INFO "Invalid fw len: %x\n", fw.len); | |
| 577 | + err = -EINVAL; | |
| 578 | + goto err_exit; | |
| 579 | + } | |
| 570 | 580 | err = |
| 571 | 581 | hw_atl_utils_fw_downld_dwords(self, |
| 572 | 582 | self->rpc_addr, |
| @@ -857,12 +867,20 @@ static int hw_atl_fw1x_deinit(struct aq_hw_s *self) · 284 unmodified lines | ||
| 857 | 867 | int hw_atl_utils_update_stats(struct aq_hw_s *self) |
| 858 | 868 | { |
| 859 | 869 | struct aq_stats_s *cs = &self->curr_stats; |
| 870 | + struct aq_stats_s curr_stats = *cs; | |
| 860 | 871 | struct hw_atl_utils_mbox mbox; |
| 872 | + bool corrupted_stats = false; | |
| 861 | 873 | |
| 862 | 874 | hw_atl_utils_mpi_read_stats(self, &mbox); |
| 863 | 875 | |
| 864 | −#define AQ_SDELTA(_N_) (self->curr_stats._N_ += \ | |
| 865 | − mbox.stats._N_ - self->last_stats._N_) | |
| 876 | +#define AQ_SDELTA(_N_) \ | |
| 877 | +do { \ | |
| 878 | + if (!corrupted_stats && \ | |
| 879 | + ((s64)(mbox.stats._N_ - self->last_stats._N_)) >= 0) \ | |
| 880 | + curr_stats._N_ += mbox.stats._N_ - self->last_stats._N_; \ | |
| 881 | + else \ | |
| 882 | + corrupted_stats = true; \ | |
| 883 | +} while (0) | |
| 866 | 884 | |
| 867 | 885 | if (self->aq_link_status.mbps) { |
| 868 | 886 | AQ_SDELTA(uprc); |
| @@ -882,6 +900,9 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self) · 13 unmodified lines | ||
| 882 | 900 | AQ_SDELTA(bbrc); |
| 883 | 901 | AQ_SDELTA(bbtc); |
| 884 | 902 | AQ_SDELTA(dpc); |
| 903 | + | |
| 904 | + if (!corrupted_stats) | |
| 905 | + *cs = curr_stats; | |
| 885 | 906 | } |
| 886 | 907 | #undef AQ_SDELTA |
| 887 | 908 | |
| @@ -132,9 +132,6 @@ static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed) · 131 unmodified lines | ||
| 132 | 132 | if (speed & AQ_NIC_RATE_5G) |
| 133 | 133 | rate |= FW2X_RATE_5G; |
| 134 | 134 | |
| 135 | − if (speed & AQ_NIC_RATE_5GSR) | |
| 136 | − rate |= FW2X_RATE_5G; | |
| 137 | − | |
| 138 | 135 | if (speed & AQ_NIC_RATE_2G5) |
| 139 | 136 | rate |= FW2X_RATE_2G5; |
| 140 | 137 | |
| @@ -65,11 +65,25 @@ const struct aq_hw_caps_s hw_atl2_caps_aqc113 = { · 64 unmodified lines | ||
| 65 | 65 | AQ_NIC_RATE_5G | |
| 66 | 66 | AQ_NIC_RATE_2G5 | |
| 67 | 67 | AQ_NIC_RATE_1G | |
| 68 | − AQ_NIC_RATE_1G_HALF | | |
| 69 | 68 | AQ_NIC_RATE_100M | |
| 70 | − AQ_NIC_RATE_100M_HALF | | |
| 71 | − AQ_NIC_RATE_10M | | |
| 72 | − AQ_NIC_RATE_10M_HALF, | |
| 69 | + AQ_NIC_RATE_10M, | |
| 70 | +}; | |
| 71 | + | |
| 72 | +const struct aq_hw_caps_s hw_atl2_caps_aqc115c = { | |
| 73 | + DEFAULT_BOARD_BASIC_CAPABILITIES, | |
| 74 | + .media_type = AQ_HW_MEDIA_TYPE_TP, | |
| 75 | + .link_speed_msk = AQ_NIC_RATE_2G5 | | |
| 76 | + AQ_NIC_RATE_1G | | |
| 77 | + AQ_NIC_RATE_100M | | |
| 78 | + AQ_NIC_RATE_10M, | |
| 79 | +}; | |
| 80 | + | |
| 81 | +const struct aq_hw_caps_s hw_atl2_caps_aqc116c = { | |
| 82 | + DEFAULT_BOARD_BASIC_CAPABILITIES, | |
| 83 | + .media_type = AQ_HW_MEDIA_TYPE_TP, | |
| 84 | + .link_speed_msk = AQ_NIC_RATE_1G | | |
| 85 | + AQ_NIC_RATE_100M | | |
| 86 | + AQ_NIC_RATE_10M, | |
| 73 | 87 | }; |
| 74 | 88 | |
| 75 | 89 | static u32 hw_atl2_sem_act_rslvr_get(struct aq_hw_s *self) |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | #include "aq_common.h" |
| 10 | 10 | |
| 11 | 11 | extern const struct aq_hw_caps_s hw_atl2_caps_aqc113; |
| 12 | +extern const struct aq_hw_caps_s hw_atl2_caps_aqc115c; | |
| 13 | +extern const struct aq_hw_caps_s hw_atl2_caps_aqc116c; | |
| 12 | 14 | extern const struct aq_hw_ops hw_atl2_ops; |
| 13 | 15 | |
| 14 | 16 | #endif /* HW_ATL2_H */ |
| @@ -239,7 +239,8 @@ struct version_s { · 238 unmodified lines | ||
| 239 | 239 | u8 minor; |
| 240 | 240 | u16 build; |
| 241 | 241 | } phy; |
| 242 | − u32 rsvd; | |
| 242 | + u32 drv_iface_ver:4; | |
| 243 | + u32 rsvd:28; | |
| 243 | 244 | }; |
| 244 | 245 | |
| 245 | 246 | struct link_status_s { |
| @@ -424,7 +425,7 @@ struct cable_diag_status_s { · 178 unmodified lines | ||
| 424 | 425 | u16 rsvd2; |
| 425 | 426 | }; |
| 426 | 427 | |
| 427 | −struct statistics_s { | |
| 428 | +struct statistics_a0_s { | |
| 428 | 429 | struct { |
| 429 | 430 | u32 link_up; |
| 430 | 431 | u32 link_down; |
| @@ -457,6 +458,33 @@ struct statistics_s { · 26 unmodified lines | ||
| 457 | 458 | u32 reserve_fw_gap; |
| 458 | 459 | }; |
| 459 | 460 | |
| 461 | +struct __packed statistics_b0_s { | |
| 462 | + u64 rx_good_octets; | |
| 463 | + u64 rx_pause_frames; | |
| 464 | + u64 rx_good_frames; | |
| 465 | + u64 rx_errors; | |
| 466 | + u64 rx_unicast_frames; | |
| 467 | + u64 rx_multicast_frames; | |
| 468 | + u64 rx_broadcast_frames; | |
| 469 | + | |
| 470 | + u64 tx_good_octets; | |
| 471 | + u64 tx_pause_frames; | |
| 472 | + u64 tx_good_frames; | |
| 473 | + u64 tx_errors; | |
| 474 | + u64 tx_unicast_frames; | |
| 475 | + u64 tx_multicast_frames; | |
| 476 | + u64 tx_broadcast_frames; | |
| 477 | + | |
| 478 | + u32 main_loop_cycles; | |
| 479 | +}; | |
| 480 | + | |
| 481 | +struct __packed statistics_s { | |
| 482 | + union __packed { | |
| 483 | + struct statistics_a0_s a0; | |
| 484 | + struct statistics_b0_s b0; | |
| 485 | + }; | |
| 486 | +}; | |
| 487 | + | |
| 460 | 488 | struct filter_caps_s { |
| 461 | 489 | u8 l2_filters_base_index:6; |
| 462 | 490 | u8 flexible_filter_mask:2; |
| @@ -545,7 +573,7 @@ struct management_status_s { · 82 unmodified lines | ||
| 545 | 573 | u32 rsvd5; |
| 546 | 574 | }; |
| 547 | 575 | |
| 548 | −struct fw_interface_out { | |
| 576 | +struct __packed fw_interface_out { | |
| 549 | 577 | struct transaction_counter_s transaction_id; |
| 550 | 578 | struct version_s version; |
| 551 | 579 | struct link_status_s link_status; |
| @@ -569,7 +597,6 @@ struct fw_interface_out { · 17 unmodified lines | ||
| 569 | 597 | struct core_dump_s core_dump; |
| 570 | 598 | u32 rsvd11; |
| 571 | 599 | struct statistics_s stats; |
| 572 | − u32 rsvd12; | |
| 573 | 600 | struct filter_caps_s filter_caps; |
| 574 | 601 | struct device_caps_s device_caps; |
| 575 | 602 | u32 rsvd13; |
| @@ -592,6 +619,9 @@ struct fw_interface_out { · 16 unmodified lines | ||
| 592 | 619 | #define AQ_HOST_MODE_LOW_POWER 3U |
| 593 | 620 | #define AQ_HOST_MODE_SHUTDOWN 4U |
| 594 | 621 | |
| 622 | +#define AQ_A2_FW_INTERFACE_A0 0 | |
| 623 | +#define AQ_A2_FW_INTERFACE_B0 1 | |
| 624 | + | |
| 595 | 625 | int hw_atl2_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops); |
| 596 | 626 | |
| 597 | 627 | int hw_atl2_utils_soft_reset(struct aq_hw_s *self); |
| @@ -84,7 +84,7 @@ static int hw_atl2_shared_buffer_read_block(struct aq_hw_s *self, · 83 unmodified lines | ||
| 84 | 84 | if (cnt > AQ_A2_FW_READ_TRY_MAX) |
| 85 | 85 | return -ETIME; |
| 86 | 86 | if (tid1.transaction_cnt_a != tid1.transaction_cnt_b) |
| 87 | − udelay(1); | |
| 87 | + mdelay(1); | |
| 88 | 88 | } while (tid1.transaction_cnt_a != tid1.transaction_cnt_b); |
| 89 | 89 | |
| 90 | 90 | hw_atl2_mif_shared_buf_read(self, offset, (u32 *)data, dwords); |
| @@ -154,7 +154,7 @@ static void a2_link_speed_mask2fw(u32 speed, · 63 unmodified lines | ||
| 154 | 154 | { |
| 155 | 155 | link_options->rate_10G = !!(speed & AQ_NIC_RATE_10G); |
| 156 | 156 | link_options->rate_5G = !!(speed & AQ_NIC_RATE_5G); |
| 157 | − link_options->rate_N5G = !!(speed & AQ_NIC_RATE_5GSR); | |
| 157 | + link_options->rate_N5G = link_options->rate_5G; | |
| 158 | 158 | link_options->rate_2P5G = !!(speed & AQ_NIC_RATE_2G5); |
| 159 | 159 | link_options->rate_N2P5G = link_options->rate_2P5G; |
| 160 | 160 | link_options->rate_1G = !!(speed & AQ_NIC_RATE_1G); |
| @@ -192,8 +192,6 @@ static u32 a2_fw_lkp_to_mask(struct lkp_link_caps_s *lkp_link_caps) · 31 unmodified lines | ||
| 192 | 192 | rate |= AQ_NIC_RATE_10G; |
| 193 | 193 | if (lkp_link_caps->rate_5G) |
| 194 | 194 | rate |= AQ_NIC_RATE_5G; |
| 195 | − if (lkp_link_caps->rate_N5G) | |
| 196 | − rate |= AQ_NIC_RATE_5GSR; | |
| 197 | 195 | if (lkp_link_caps->rate_2P5G) |
| 198 | 196 | rate |= AQ_NIC_RATE_2G5; |
| 199 | 197 | if (lkp_link_caps->rate_1G) |
| @@ -335,15 +333,22 @@ static int aq_a2_fw_get_mac_permanent(struct aq_hw_s *self, u8 *mac) · 135 unmodified lines | ||
| 335 | 333 | return 0; |
| 336 | 334 | } |
| 337 | 335 | |
| 338 | −static int aq_a2_fw_update_stats(struct aq_hw_s *self) | |
| 336 | +static void aq_a2_fill_a0_stats(struct aq_hw_s *self, | |
| 337 | + struct statistics_s *stats) | |
| 339 | 338 | { |
| 340 | 339 | struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; |
| 341 | − struct statistics_s stats; | |
| 342 | − | |
| 343 | − hw_atl2_shared_buffer_read_safe(self, stats, &stats); | |
| 344 | − | |
| 345 | −#define AQ_SDELTA(_N_, _F_) (self->curr_stats._N_ += \ | |
| 346 | − stats.msm._F_ - priv->last_stats.msm._F_) | |
| 340 | + struct aq_stats_s *cs = &self->curr_stats; | |
| 341 | + struct aq_stats_s curr_stats = *cs; | |
| 342 | + bool corrupted_stats = false; | |
| 343 | + | |
| 344 | +#define AQ_SDELTA(_N, _F) \ | |
| 345 | +do { \ | |
| 346 | + if (!corrupted_stats && \ | |
| 347 | + ((s64)(stats->a0.msm._F - priv->last_stats.a0.msm._F)) >= 0) \ | |
| 348 | + curr_stats._N += stats->a0.msm._F - priv->last_stats.a0.msm._F;\ | |
| 349 | + else \ | |
| 350 | + corrupted_stats = true; \ | |
| 351 | +} while (0) | |
| 347 | 352 | |
| 348 | 353 | if (self->aq_link_status.mbps) { |
| 349 | 354 | AQ_SDELTA(uprc, rx_unicast_frames); |
| @@ -362,17 +367,76 @@ static int aq_a2_fw_update_stats(struct aq_hw_s *self) · 12 unmodified lines | ||
| 362 | 367 | AQ_SDELTA(mbtc, tx_multicast_octets); |
| 363 | 368 | AQ_SDELTA(bbrc, rx_broadcast_octets); |
| 364 | 369 | AQ_SDELTA(bbtc, tx_broadcast_octets); |
| 370 | + | |
| 371 | + if (!corrupted_stats) | |
| 372 | + *cs = curr_stats; | |
| 365 | 373 | } |
| 366 | 374 | #undef AQ_SDELTA |
| 367 | − self->curr_stats.dma_pkt_rc = | |
| 368 | − hw_atl_stats_rx_dma_good_pkt_counter_get(self); | |
| 369 | − self->curr_stats.dma_pkt_tc = | |
| 370 | − hw_atl_stats_tx_dma_good_pkt_counter_get(self); | |
| 371 | − self->curr_stats.dma_oct_rc = | |
| 372 | − hw_atl_stats_rx_dma_good_octet_counter_get(self); | |
| 373 | − self->curr_stats.dma_oct_tc = | |
| 374 | − hw_atl_stats_tx_dma_good_octet_counter_get(self); | |
| 375 | − self->curr_stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self); | |
| 375 | + | |
| 376 | +} | |
| 377 | + | |
| 378 | +static void aq_a2_fill_b0_stats(struct aq_hw_s *self, | |
| 379 | + struct statistics_s *stats) | |
| 380 | +{ | |
| 381 | + struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; | |
| 382 | + struct aq_stats_s *cs = &self->curr_stats; | |
| 383 | + struct aq_stats_s curr_stats = *cs; | |
| 384 | + bool corrupted_stats = false; | |
| 385 | + | |
| 386 | +#define AQ_SDELTA(_N, _F) \ | |
| 387 | +do { \ | |
| 388 | + if (!corrupted_stats && \ | |
| 389 | + ((s64)(stats->b0._F - priv->last_stats.b0._F)) >= 0) \ | |
| 390 | + curr_stats._N += stats->b0._F - priv->last_stats.b0._F; \ | |
| 391 | + else \ | |
| 392 | + corrupted_stats = true; \ | |
| 393 | +} while (0) | |
| 394 | + | |
| 395 | + if (self->aq_link_status.mbps) { | |
| 396 | + AQ_SDELTA(uprc, rx_unicast_frames); | |
| 397 | + AQ_SDELTA(mprc, rx_multicast_frames); | |
| 398 | + AQ_SDELTA(bprc, rx_broadcast_frames); | |
| 399 | + AQ_SDELTA(erpr, rx_errors); | |
| 400 | + AQ_SDELTA(brc, rx_good_octets); | |
| 401 | + | |
| 402 | + AQ_SDELTA(uptc, tx_unicast_frames); | |
| 403 | + AQ_SDELTA(mptc, tx_multicast_frames); | |
| 404 | + AQ_SDELTA(bptc, tx_broadcast_frames); | |
| 405 | + AQ_SDELTA(erpt, tx_errors); | |
| 406 | + AQ_SDELTA(btc, tx_good_octets); | |
| 407 | + | |
| 408 | + if (!corrupted_stats) | |
| 409 | + *cs = curr_stats; | |
| 410 | + } | |
| 411 | +#undef AQ_SDELTA | |
| 412 | +} | |
| 413 | + | |
| 414 | +static int aq_a2_fw_update_stats(struct aq_hw_s *self) | |
| 415 | +{ | |
| 416 | + struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; | |
| 417 | + struct aq_stats_s *cs = &self->curr_stats; | |
| 418 | + struct statistics_s stats; | |
| 419 | + struct version_s version; | |
| 420 | + int err; | |
| 421 | + | |
| 422 | + err = hw_atl2_shared_buffer_read_safe(self, version, &version); | |
| 423 | + if (err) | |
| 424 | + return err; | |
| 425 | + | |
| 426 | + err = hw_atl2_shared_buffer_read_safe(self, stats, &stats); | |
| 427 | + if (err) | |
| 428 | + return err; | |
| 429 | + | |
| 430 | + if (version.drv_iface_ver == AQ_A2_FW_INTERFACE_A0) | |
| 431 | + aq_a2_fill_a0_stats(self, &stats); | |
| 432 | + else | |
| 433 | + aq_a2_fill_b0_stats(self, &stats); | |
| 434 | + | |
| 435 | + cs->dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counter_get(self); | |
| 436 | + cs->dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counter_get(self); | |
| 437 | + cs->dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counter_get(self); | |
| 438 | + cs->dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counter_get(self); | |
| 439 | + cs->dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self); | |
| 376 | 440 | |
| 377 | 441 | memcpy(&priv->last_stats, &stats, sizeof(stats)); |
| 378 | 442 | |
| @@ -499,9 +563,9 @@ u32 hw_atl2_utils_get_fw_version(struct aq_hw_s *self) · 120 unmodified lines | ||
| 499 | 563 | hw_atl2_shared_buffer_read_safe(self, version, &version); |
| 500 | 564 | |
| 501 | 565 | /* A2 FW version is stored in reverse order */ |
| 502 | − return version.mac.major << 24 | | |
| 503 | − version.mac.minor << 16 | | |
| 504 | − version.mac.build; | |
| 566 | + return version.bundle.major << 24 | | |
| 567 | + version.bundle.minor << 16 | | |
| 568 | + version.bundle.build; | |
| 505 | 569 | } |
| 506 | 570 | |
| 507 | 571 | int hw_atl2_utils_get_action_resolve_table_caps(struct aq_hw_s *self, |
| @@ -127,9 +127,9 @@ struct ax88796c_device { · 126 unmodified lines | ||
| 127 | 127 | #define AX_PRIV_FLAGS_MASK (AX_CAP_COMP) |
| 128 | 128 | |
| 129 | 129 | unsigned long flags; |
| 130 | − #define EVENT_INTR BIT(0) | |
| 131 | − #define EVENT_TX BIT(1) | |
| 132 | − #define EVENT_SET_MULTI BIT(2) | |
| 130 | + #define EVENT_INTR 0 | |
| 131 | + #define EVENT_TX 1 | |
| 132 | + #define EVENT_SET_MULTI 2 | |
| 133 | 133 | |
| 134 | 134 | }; |
| 135 | 135 | |
| @@ -34,7 +34,7 @@ int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status) · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | /* OP */ |
| 36 | 36 | ax_spi->cmd_buf[0] = AX_SPICMD_READ_STATUS; |
| 37 | − ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)&status, 3); | |
| 37 | + ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)status, 3); | |
| 38 | 38 | if (ret) |
| 39 | 39 | dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); |
| 40 | 40 | else |
| @@ -708,7 +708,9 @@ static int bcm4908_enet_probe(struct platform_device *pdev) · 707 unmodified lines | ||
| 708 | 708 | |
| 709 | 709 | enet->irq_tx = platform_get_irq_byname(pdev, "tx"); |
| 710 | 710 | |
| 711 | − dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); | |
| 711 | + err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); | |
| 712 | + if (err) | |
| 713 | + return err; | |
| 712 | 714 | |
| 713 | 715 | err = bcm4908_enet_dma_alloc(enet); |
| 714 | 716 | if (err) |
| @@ -635,11 +635,13 @@ static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, · 634 unmodified lines | ||
| 635 | 635 | { |
| 636 | 636 | int i, rc; |
| 637 | 637 | struct bnx2x_ilt *ilt = BP_ILT(bp); |
| 638 | − struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; | |
| 638 | + struct ilt_client_info *ilt_cli; | |
| 639 | 639 | |
| 640 | 640 | if (!ilt || !ilt->lines) |
| 641 | 641 | return -1; |
| 642 | 642 | |
| 643 | + ilt_cli = &ilt->clients[cli_num]; | |
| 644 | + | |
| 643 | 645 | if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM)) |
| 644 | 646 | return 0; |
| 645 | 647 | |
| @@ -2258,6 +2258,16 @@ static inline void bnxt_db_write(struct bnxt *bp, struct bnxt_db_info *db, · 2257 unmodified lines | ||
| 2258 | 2258 | } |
| 2259 | 2259 | } |
| 2260 | 2260 | |
| 2261 | +/* Must hold rtnl_lock */ | |
| 2262 | +static inline bool bnxt_sriov_cfg(struct bnxt *bp) | |
| 2263 | +{ | |
| 2264 | +#if defined(CONFIG_BNXT_SRIOV) | |
| 2265 | + return BNXT_PF(bp) && (bp->pf.active_vfs || bp->sriov_cfg); | |
| 2266 | +#else | |
| 2267 | + return false; | |
| 2268 | +#endif | |
| 2269 | +} | |
| 2270 | + | |
| 2261 | 2271 | extern const u16 bnxt_lhint_arr[]; |
| 2262 | 2272 | |
| 2263 | 2273 | int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, |
| @@ -360,7 +360,7 @@ bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack, · 359 unmodified lines | ||
| 360 | 360 | NL_SET_ERR_MSG_MOD(extack, "Live patch already applied"); |
| 361 | 361 | break; |
| 362 | 362 | default: |
| 363 | − netdev_err(bp->dev, "Unexpected live patch error: %hhd\n", err); | |
| 363 | + netdev_err(bp->dev, "Unexpected live patch error: %d\n", err); | |
| 364 | 364 | NL_SET_ERR_MSG_MOD(extack, "Failed to activate live patch"); |
| 365 | 365 | break; |
| 366 | 366 | } |
| @@ -441,12 +441,13 @@ static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change, · 74 unmodified lines | ||
| 441 | 441 | |
| 442 | 442 | switch (action) { |
| 443 | 443 | case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: { |
| 444 | − if (BNXT_PF(bp) && bp->pf.active_vfs) { | |
| 444 | + rtnl_lock(); | |
| 445 | + if (bnxt_sriov_cfg(bp)) { | |
| 445 | 446 | NL_SET_ERR_MSG_MOD(extack, |
| 446 | − "reload is unsupported when VFs are allocated"); | |
| 447 | + "reload is unsupported while VFs are allocated or being configured"); | |
| 448 | + rtnl_unlock(); | |
| 447 | 449 | return -EOPNOTSUPP; |
| 448 | 450 | } |
| 449 | − rtnl_lock(); | |
| 450 | 451 | if (bp->dev->reg_state == NETREG_UNREGISTERED) { |
| 451 | 452 | rtnl_unlock(); |
| 452 | 453 | return -ENODEV; |
| @@ -1868,7 +1868,7 @@ static int bnxt_tc_setup_indr_block_cb(enum tc_setup_type type, · 1867 unmodified lines | ||
| 1868 | 1868 | struct flow_cls_offload *flower = type_data; |
| 1869 | 1869 | struct bnxt *bp = priv->bp; |
| 1870 | 1870 | |
| 1871 | − if (flower->common.chain_index) | |
| 1871 | + if (!tc_cls_can_offload_and_chain0(bp->dev, type_data)) | |
| 1872 | 1872 | return -EOPNOTSUPP; |
| 1873 | 1873 | |
| 1874 | 1874 | switch (type) { |
| @@ -3196,6 +3196,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, · 3195 unmodified lines | ||
| 3196 | 3196 | } |
| 3197 | 3197 | if (adapter->registered_device_map == 0) { |
| 3198 | 3198 | dev_err(&pdev->dev, "could not register any net devices\n"); |
| 3199 | + err = -EINVAL; | |
| 3199 | 3200 | goto err_disable_interrupts; |
| 3200 | 3201 | } |
| 3201 | 3202 | |
| @@ -4709,6 +4709,10 @@ type3_infoblock(struct net_device *dev, u_char count, u_char *p) · 4708 unmodified lines | ||
| 4709 | 4709 | lp->ibn = 3; |
| 4710 | 4710 | lp->active = *p++; |
| 4711 | 4711 | if (MOTO_SROM_BUG) lp->active = 0; |
| 4712 | + /* if (MOTO_SROM_BUG) statement indicates lp->active could | |
| 4713 | + * be 8 (i.e. the size of array lp->phy) */ | |
| 4714 | + if (WARN_ON(lp->active >= ARRAY_SIZE(lp->phy))) | |
| 4715 | + return -EINVAL; | |
| 4712 | 4716 | lp->phy[lp->active].gep = (*p ? p : NULL); p += (2 * (*p) + 1); |
| 4713 | 4717 | lp->phy[lp->active].rst = (*p ? p : NULL); p += (2 * (*p) + 1); |
| 4714 | 4718 | lp->phy[lp->active].mc = get_unaligned_le16(p); p += 2; |
| @@ -5000,19 +5004,23 @@ mii_get_phy(struct net_device *dev) · 285 unmodified lines | ||
| 5000 | 5004 | } |
| 5001 | 5005 | if ((j == limit) && (i < DE4X5_MAX_MII)) { |
| 5002 | 5006 | for (k=0; k < DE4X5_MAX_PHY && lp->phy[k].id; k++); |
| 5003 | − lp->phy[k].addr = i; | |
| 5004 | − lp->phy[k].id = id; | |
| 5005 | − lp->phy[k].spd.reg = GENERIC_REG; /* ANLPA register */ | |
| 5006 | − lp->phy[k].spd.mask = GENERIC_MASK; /* 100Mb/s technologies */ | |
| 5007 | − lp->phy[k].spd.value = GENERIC_VALUE; /* TX & T4, H/F Duplex */ | |
| 5008 | − lp->mii_cnt++; | |
| 5009 | − lp->active++; | |
| 5010 | − printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n", dev->name); | |
| 5011 | − j = de4x5_debug; | |
| 5012 | − de4x5_debug |= DEBUG_MII; | |
| 5013 | − de4x5_dbg_mii(dev, k); | |
| 5014 | − de4x5_debug = j; | |
| 5015 | − printk("\n"); | |
| 5007 | + if (k < DE4X5_MAX_PHY) { | |
| 5008 | + lp->phy[k].addr = i; | |
| 5009 | + lp->phy[k].id = id; | |
| 5010 | + lp->phy[k].spd.reg = GENERIC_REG; /* ANLPA register */ | |
| 5011 | + lp->phy[k].spd.mask = GENERIC_MASK; /* 100Mb/s technologies */ | |
| 5012 | + lp->phy[k].spd.value = GENERIC_VALUE; /* TX & T4, H/F Duplex */ | |
| 5013 | + lp->mii_cnt++; | |
| 5014 | + lp->active++; | |
| 5015 | + printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n", dev->name); | |
| 5016 | + j = de4x5_debug; | |
| 5017 | + de4x5_debug |= DEBUG_MII; | |
| 5018 | + de4x5_dbg_mii(dev, k); | |
| 5019 | + de4x5_debug = j; | |
| 5020 | + printk("\n"); | |
| 5021 | + } else { | |
| 5022 | + goto purgatory; | |
| 5023 | + } | |
| 5016 | 5024 | } |
| 5017 | 5025 | } |
| 5018 | 5026 | purgatory: |
| @@ -4550,10 +4550,12 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev) · 4549 unmodified lines | ||
| 4550 | 4550 | |
| 4551 | 4551 | fsl_mc_portal_free(priv->mc_io); |
| 4552 | 4552 | |
| 4553 | − free_netdev(net_dev); | |
| 4553 | + destroy_workqueue(priv->dpaa2_ptp_wq); | |
| 4554 | 4554 | |
| 4555 | 4555 | dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name); |
| 4556 | 4556 | |
| 4557 | + free_netdev(net_dev); | |
| 4558 | + | |
| 4557 | 4559 | return 0; |
| 4558 | 4560 | } |
| 4559 | 4561 | |
| @@ -377,6 +377,9 @@ struct bufdesc_ex { · 376 unmodified lines | ||
| 377 | 377 | #define FEC_ENET_WAKEUP ((uint)0x00020000) /* Wakeup request */ |
| 378 | 378 | #define FEC_ENET_TXF (FEC_ENET_TXF_0 | FEC_ENET_TXF_1 | FEC_ENET_TXF_2) |
| 379 | 379 | #define FEC_ENET_RXF (FEC_ENET_RXF_0 | FEC_ENET_RXF_1 | FEC_ENET_RXF_2) |
| 380 | +#define FEC_ENET_RXF_GET(X) (((X) == 0) ? FEC_ENET_RXF_0 : \ | |
| 381 | + (((X) == 1) ? FEC_ENET_RXF_1 : \ | |
| 382 | + FEC_ENET_RXF_2)) | |
| 380 | 383 | #define FEC_ENET_TS_AVAIL ((uint)0x00010000) |
| 381 | 384 | #define FEC_ENET_TS_TIMER ((uint)0x00008000) |
| 382 | 385 | |
| @@ -1480,7 +1480,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) · 1479 unmodified lines | ||
| 1480 | 1480 | break; |
| 1481 | 1481 | pkt_received++; |
| 1482 | 1482 | |
| 1483 | − writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT); | |
| 1483 | + writel(FEC_ENET_RXF_GET(queue_id), fep->hwp + FEC_IEVENT); | |
| 1484 | 1484 | |
| 1485 | 1485 | /* Check for errors. */ |
| 1486 | 1486 | status ^= BD_ENET_RX_LAST; |
| @@ -68,6 +68,9 @@ struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi, · 67 unmodified lines | ||
| 68 | 68 | set_protocol = ctx->curr_frag_cnt == ctx->expected_frag_cnt - 1; |
| 69 | 69 | } else { |
| 70 | 70 | skb = napi_alloc_skb(napi, len); |
| 71 | + | |
| 72 | + if (unlikely(!skb)) | |
| 73 | + return NULL; | |
| 71 | 74 | set_protocol = true; |
| 72 | 75 | } |
| 73 | 76 | __skb_put(skb, len); |
| @@ -400,6 +400,10 @@ static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, · 399 unmodified lines | ||
| 400 | 400 | return; |
| 401 | 401 | |
| 402 | 402 | if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { |
| 403 | + /* DSAF_MAX_PORT_NUM is 6, but DSAF_GE_NUM is 8. | |
| 404 | + We need check to prevent array overflow */ | |
| 405 | + if (port >= DSAF_MAX_PORT_NUM) | |
| 406 | + return; | |
| 403 | 407 | reg_val_1 = 0x1 << port; |
| 404 | 408 | port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off; |
| 405 | 409 | /* there is difference between V1 and V2 in register.*/ |
| @@ -1081,7 +1081,8 @@ static void hns3_dump_page_pool_info(struct hns3_enet_ring *ring, · 1080 unmodified lines | ||
| 1081 | 1081 | u32 j = 0; |
| 1082 | 1082 | |
| 1083 | 1083 | sprintf(result[j++], "%u", index); |
| 1084 | − sprintf(result[j++], "%u", ring->page_pool->pages_state_hold_cnt); | |
| 1084 | + sprintf(result[j++], "%u", | |
| 1085 | + READ_ONCE(ring->page_pool->pages_state_hold_cnt)); | |
| 1085 | 1086 | sprintf(result[j++], "%u", |
| 1086 | 1087 | atomic_read(&ring->page_pool->pages_state_release_cnt)); |
| 1087 | 1088 | sprintf(result[j++], "%u", ring->page_pool->p.pool_size); |
| @@ -1106,6 +1107,11 @@ hns3_dbg_page_pool_info(struct hnae3_handle *h, char *buf, int len) · 18 unmodified lines | ||
| 1106 | 1107 | return -EFAULT; |
| 1107 | 1108 | } |
| 1108 | 1109 | |
| 1110 | + if (!priv->ring[h->kinfo.num_tqps].page_pool) { | |
| 1111 | + dev_err(&h->pdev->dev, "page pool is not initialized\n"); | |
| 1112 | + return -EFAULT; | |
| 1113 | + } | |
| 1114 | + | |
| 1109 | 1115 | for (i = 0; i < ARRAY_SIZE(page_pool_info_items); i++) |
| 1110 | 1116 | result[i] = &data_str[i][0]; |
| 1111 | 1117 | |
| @@ -987,6 +987,7 @@ static int hns3_set_reset(struct net_device *netdev, u32 *flags) · 986 unmodified lines | ||
| 987 | 987 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); |
| 988 | 988 | const struct hnae3_ae_ops *ops = h->ae_algo->ops; |
| 989 | 989 | const struct hns3_reset_type_map *rst_type_map; |
| 990 | + enum ethtool_reset_flags rst_flags; | |
| 990 | 991 | u32 i, size; |
| 991 | 992 | |
| 992 | 993 | if (ops->ae_dev_resetting && ops->ae_dev_resetting(h)) |
| @@ -1006,6 +1007,7 @@ static int hns3_set_reset(struct net_device *netdev, u32 *flags) · 13 unmodified lines | ||
| 1006 | 1007 | for (i = 0; i < size; i++) { |
| 1007 | 1008 | if (rst_type_map[i].rst_flags == *flags) { |
| 1008 | 1009 | rst_type = rst_type_map[i].rst_type; |
| 1010 | + rst_flags = rst_type_map[i].rst_flags; | |
| 1009 | 1011 | break; |
| 1010 | 1012 | } |
| 1011 | 1013 | } |
| @@ -1021,6 +1023,8 @@ static int hns3_set_reset(struct net_device *netdev, u32 *flags) · 9 unmodified lines | ||
| 1021 | 1023 | |
| 1022 | 1024 | ops->reset_event(h->pdev, h); |
| 1023 | 1025 | |
| 1026 | + *flags &= ~rst_flags; | |
| 1027 | + | |
| 1024 | 1028 | return 0; |
| 1025 | 1029 | } |
| 1026 | 1030 | |
| @@ -703,9 +703,9 @@ static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size) · 702 unmodified lines | ||
| 703 | 703 | roundup_size = ilog2(roundup_size); |
| 704 | 704 | |
| 705 | 705 | for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { |
| 706 | − tc_valid[i] = !!(hdev->hw_tc_map & BIT(i)); | |
| 706 | + tc_valid[i] = 1; | |
| 707 | 707 | tc_size[i] = roundup_size; |
| 708 | − tc_offset[i] = rss_size * i; | |
| 708 | + tc_offset[i] = (hdev->hw_tc_map & BIT(i)) ? rss_size * i : 0; | |
| 709 | 709 | } |
| 710 | 710 | |
| 711 | 711 | hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_TC_MODE, false); |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/interrupt.h> |
| 9 | 9 | #include <linux/etherdevice.h> |
| 10 | 10 | #include <linux/netdevice.h> |
| 11 | +#include <linux/module.h> | |
| 11 | 12 | |
| 12 | 13 | #include "hinic_hw_dev.h" |
| 13 | 14 | #include "hinic_dev.h" |
| @@ -628,17 +628,9 @@ static bool reuse_rx_pools(struct ibmvnic_adapter *adapter) · 627 unmodified lines | ||
| 628 | 628 | old_buff_size = adapter->prev_rx_buf_sz; |
| 629 | 629 | new_buff_size = adapter->cur_rx_buf_sz; |
| 630 | 630 | |
| 631 | − /* Require buff size to be exactly same for now */ | |
| 632 | − if (old_buff_size != new_buff_size) | |
| 633 | − return false; | |
| 634 | − | |
| 635 | − if (old_num_pools == new_num_pools && old_pool_size == new_pool_size) | |
| 636 | − return true; | |
| 637 | − | |
| 638 | − if (old_num_pools < adapter->min_rx_queues || | |
| 639 | − old_num_pools > adapter->max_rx_queues || | |
| 640 | − old_pool_size < adapter->min_rx_add_entries_per_subcrq || | |
| 641 | − old_pool_size > adapter->max_rx_add_entries_per_subcrq) | |
| 631 | + if (old_buff_size != new_buff_size || | |
| 632 | + old_num_pools != new_num_pools || | |
| 633 | + old_pool_size != new_pool_size) | |
| 642 | 634 | return false; |
| 643 | 635 | |
| 644 | 636 | return true; |
| @@ -874,17 +866,9 @@ static bool reuse_tx_pools(struct ibmvnic_adapter *adapter) · 229 unmodified lines | ||
| 874 | 866 | old_mtu = adapter->prev_mtu; |
| 875 | 867 | new_mtu = adapter->req_mtu; |
| 876 | 868 | |
| 877 | − /* Require MTU to be exactly same to reuse pools for now */ | |
| 878 | − if (old_mtu != new_mtu) | |
| 879 | − return false; | |
| 880 | − | |
| 881 | − if (old_num_pools == new_num_pools && old_pool_size == new_pool_size) | |
| 882 | − return true; | |
| 883 | − | |
| 884 | − if (old_num_pools < adapter->min_tx_queues || | |
| 885 | − old_num_pools > adapter->max_tx_queues || | |
| 886 | − old_pool_size < adapter->min_tx_entries_per_subcrq || | |
| 887 | − old_pool_size > adapter->max_tx_entries_per_subcrq) | |
| 869 | + if (old_mtu != new_mtu || | |
| 870 | + old_num_pools != new_num_pools || | |
| 871 | + old_pool_size != new_pool_size) | |
| 888 | 872 | return false; |
| 889 | 873 | |
| 890 | 874 | return true; |
| @@ -3003,9 +3003,10 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) · 3002 unmodified lines | ||
| 3003 | 3003 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 3004 | 3004 | struct nic *nic = netdev_priv(netdev); |
| 3005 | 3005 | |
| 3006 | + netif_device_detach(netdev); | |
| 3007 | + | |
| 3006 | 3008 | if (netif_running(netdev)) |
| 3007 | 3009 | e100_down(nic); |
| 3008 | − netif_device_detach(netdev); | |
| 3009 | 3010 | |
| 3010 | 3011 | if ((nic->flags & wol_magic) | e100_asf(nic)) { |
| 3011 | 3012 | /* enable reverse auto-negotiation */ |
| @@ -3022,7 +3023,7 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) · 10 unmodified lines | ||
| 3022 | 3023 | *enable_wake = false; |
| 3023 | 3024 | } |
| 3024 | 3025 | |
| 3025 | − pci_clear_master(pdev); | |
| 3026 | + pci_disable_device(pdev); | |
| 3026 | 3027 | } |
| 3027 | 3028 | |
| 3028 | 3029 | static int __e100_power_off(struct pci_dev *pdev, bool wake) |
| @@ -3042,8 +3043,6 @@ static int __maybe_unused e100_suspend(struct device *dev_d) · 13 unmodified lines | ||
| 3042 | 3043 | |
| 3043 | 3044 | __e100_shutdown(to_pci_dev(dev_d), &wake); |
| 3044 | 3045 | |
| 3045 | − device_wakeup_disable(dev_d); | |
| 3046 | − | |
| 3047 | 3046 | return 0; |
| 3048 | 3047 | } |
| 3049 | 3048 | |
| @@ -3051,6 +3050,14 @@ static int __maybe_unused e100_resume(struct device *dev_d) · 1 unmodified line | ||
| 3051 | 3050 | { |
| 3052 | 3051 | struct net_device *netdev = dev_get_drvdata(dev_d); |
| 3053 | 3052 | struct nic *nic = netdev_priv(netdev); |
| 3053 | + int err; | |
| 3054 | + | |
| 3055 | + err = pci_enable_device(to_pci_dev(dev_d)); | |
| 3056 | + if (err) { | |
| 3057 | + netdev_err(netdev, "Resume cannot enable PCI device, aborting\n"); | |
| 3058 | + return err; | |
| 3059 | + } | |
| 3060 | + pci_set_master(to_pci_dev(dev_d)); | |
| 3054 | 3061 | |
| 3055 | 3062 | /* disable reverse auto-negotiation */ |
| 3056 | 3063 | if (nic->phy == phy_82552_v) { |
| @@ -3062,10 +3069,11 @@ static int __maybe_unused e100_resume(struct device *dev_d) · 5 unmodified lines | ||
| 3062 | 3069 | smartspeed & ~(E100_82552_REV_ANEG)); |
| 3063 | 3070 | } |
| 3064 | 3071 | |
| 3065 | − netif_device_attach(netdev); | |
| 3066 | 3072 | if (netif_running(netdev)) |
| 3067 | 3073 | e100_up(nic); |
| 3068 | 3074 | |
| 3075 | + netif_device_attach(netdev); | |
| 3076 | + | |
| 3069 | 3077 | return 0; |
| 3070 | 3078 | } |
| 3071 | 3079 | |
| @@ -161,6 +161,7 @@ enum i40e_vsi_state_t { · 160 unmodified lines | ||
| 161 | 161 | __I40E_VSI_OVERFLOW_PROMISC, |
| 162 | 162 | __I40E_VSI_REINIT_REQUESTED, |
| 163 | 163 | __I40E_VSI_DOWN_REQUESTED, |
| 164 | + __I40E_VSI_RELEASING, | |
| 164 | 165 | /* This must be last as it determines the size of the BITMAP */ |
| 165 | 166 | __I40E_VSI_STATE_SIZE__, |
| 166 | 167 | }; |
| @@ -1247,6 +1248,7 @@ void i40e_ptp_restore_hw_time(struct i40e_pf *pf); · 1080 unmodified lines | ||
| 1247 | 1248 | void i40e_ptp_init(struct i40e_pf *pf); |
| 1248 | 1249 | void i40e_ptp_stop(struct i40e_pf *pf); |
| 1249 | 1250 | int i40e_ptp_alloc_pins(struct i40e_pf *pf); |
| 1251 | +int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset); | |
| 1250 | 1252 | int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi); |
| 1251 | 1253 | i40e_status i40e_get_partition_bw_setting(struct i40e_pf *pf); |
| 1252 | 1254 | i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf); |
| @@ -553,6 +553,14 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n, · 552 unmodified lines | ||
| 553 | 553 | dev_info(&pf->pdev->dev, "vsi %d not found\n", vsi_seid); |
| 554 | 554 | return; |
| 555 | 555 | } |
| 556 | + if (vsi->type != I40E_VSI_MAIN && | |
| 557 | + vsi->type != I40E_VSI_FDIR && | |
| 558 | + vsi->type != I40E_VSI_VMDQ2) { | |
| 559 | + dev_info(&pf->pdev->dev, | |
| 560 | + "vsi %d type %d descriptor rings not available\n", | |
| 561 | + vsi_seid, vsi->type); | |
| 562 | + return; | |
| 563 | + } | |
| 556 | 564 | if (type == RING_TYPE_XDP && !i40e_enabled_xdp_vsi(vsi)) { |
| 557 | 565 | dev_info(&pf->pdev->dev, "XDP not enabled on VSI %d\n", vsi_seid); |
| 558 | 566 | return; |
| @@ -1790,6 +1790,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, · 1789 unmodified lines | ||
| 1790 | 1790 | bool is_add) |
| 1791 | 1791 | { |
| 1792 | 1792 | struct i40e_pf *pf = vsi->back; |
| 1793 | + u16 num_tc_qps = 0; | |
| 1793 | 1794 | u16 sections = 0; |
| 1794 | 1795 | u8 netdev_tc = 0; |
| 1795 | 1796 | u16 numtc = 1; |
| @@ -1797,13 +1798,33 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, · 1 unmodified line | ||
| 1797 | 1798 | u8 offset; |
| 1798 | 1799 | u16 qmap; |
| 1799 | 1800 | int i; |
| 1800 | − u16 num_tc_qps = 0; | |
| 1801 | 1801 | |
| 1802 | 1802 | sections = I40E_AQ_VSI_PROP_QUEUE_MAP_VALID; |
| 1803 | 1803 | offset = 0; |
| 1804 | + /* zero out queue mapping, it will get updated on the end of the function */ | |
| 1805 | + memset(ctxt->info.queue_mapping, 0, sizeof(ctxt->info.queue_mapping)); | |
| 1806 | + | |
| 1807 | + if (vsi->type == I40E_VSI_MAIN) { | |
| 1808 | + /* This code helps add more queue to the VSI if we have | |
| 1809 | + * more cores than RSS can support, the higher cores will | |
| 1810 | + * be served by ATR or other filters. Furthermore, the | |
| 1811 | + * non-zero req_queue_pairs says that user requested a new | |
| 1812 | + * queue count via ethtool's set_channels, so use this | |
| 1813 | + * value for queues distribution across traffic classes | |
| 1814 | + */ | |
| 1815 | + if (vsi->req_queue_pairs > 0) | |
| 1816 | + vsi->num_queue_pairs = vsi->req_queue_pairs; | |
| 1817 | + else if (pf->flags & I40E_FLAG_MSIX_ENABLED) | |
| 1818 | + vsi->num_queue_pairs = pf->num_lan_msix; | |
| 1819 | + } | |
| 1804 | 1820 | |
| 1805 | 1821 | /* Number of queues per enabled TC */ |
| 1806 | − num_tc_qps = vsi->alloc_queue_pairs; | |
| 1822 | + if (vsi->type == I40E_VSI_MAIN || | |
| 1823 | + (vsi->type == I40E_VSI_SRIOV && vsi->num_queue_pairs != 0)) | |
| 1824 | + num_tc_qps = vsi->num_queue_pairs; | |
| 1825 | + else | |
| 1826 | + num_tc_qps = vsi->alloc_queue_pairs; | |
| 1827 | + | |
| 1807 | 1828 | if (enabled_tc && (vsi->back->flags & I40E_FLAG_DCB_ENABLED)) { |
| 1808 | 1829 | /* Find numtc from enabled TC bitmap */ |
| 1809 | 1830 | for (i = 0, numtc = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { |
| @@ -1881,15 +1902,11 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, · 71 unmodified lines | ||
| 1881 | 1902 | } |
| 1882 | 1903 | ctxt->info.tc_mapping[i] = cpu_to_le16(qmap); |
| 1883 | 1904 | } |
| 1884 | − | |
| 1885 | − /* Set actual Tx/Rx queue pairs */ | |
| 1886 | − vsi->num_queue_pairs = offset; | |
| 1887 | − if ((vsi->type == I40E_VSI_MAIN) && (numtc == 1)) { | |
| 1888 | − if (vsi->req_queue_pairs > 0) | |
| 1889 | − vsi->num_queue_pairs = vsi->req_queue_pairs; | |
| 1890 | − else if (pf->flags & I40E_FLAG_MSIX_ENABLED) | |
| 1891 | − vsi->num_queue_pairs = pf->num_lan_msix; | |
| 1892 | − } | |
| 1905 | + /* Do not change previously set num_queue_pairs for PFs and VFs*/ | |
| 1906 | + if ((vsi->type == I40E_VSI_MAIN && numtc != 1) || | |
| 1907 | + (vsi->type == I40E_VSI_SRIOV && vsi->num_queue_pairs == 0) || | |
| 1908 | + (vsi->type != I40E_VSI_MAIN && vsi->type != I40E_VSI_SRIOV)) | |
| 1909 | + vsi->num_queue_pairs = offset; | |
| 1893 | 1910 | |
| 1894 | 1911 | /* Scheduler section valid can only be set for ADD VSI */ |
| 1895 | 1912 | if (is_add) { |
| @@ -2623,7 +2640,8 @@ static void i40e_sync_filters_subtask(struct i40e_pf *pf) · 727 unmodified lines | ||
| 2623 | 2640 | |
| 2624 | 2641 | for (v = 0; v < pf->num_alloc_vsi; v++) { |
| 2625 | 2642 | if (pf->vsi[v] && |
| 2626 | − (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED)) { | |
| 2643 | + (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED) && | |
| 2644 | + !test_bit(__I40E_VSI_RELEASING, pf->vsi[v]->state)) { | |
| 2627 | 2645 | int ret = i40e_sync_vsi_filters(pf->vsi[v]); |
| 2628 | 2646 | |
| 2629 | 2647 | if (ret) { |
| @@ -5426,6 +5444,58 @@ static void i40e_vsi_update_queue_map(struct i40e_vsi *vsi, · 2796 unmodified lines | ||
| 5426 | 5444 | sizeof(vsi->info.tc_mapping)); |
| 5427 | 5445 | } |
| 5428 | 5446 | |
| 5447 | +/** | |
| 5448 | + * i40e_update_adq_vsi_queues - update queue mapping for ADq VSI | |
| 5449 | + * @vsi: the VSI being reconfigured | |
| 5450 | + * @vsi_offset: offset from main VF VSI | |
| 5451 | + */ | |
| 5452 | +int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset) | |
| 5453 | +{ | |
| 5454 | + struct i40e_vsi_context ctxt = {}; | |
| 5455 | + struct i40e_pf *pf; | |
| 5456 | + struct i40e_hw *hw; | |
| 5457 | + int ret; | |
| 5458 | + | |
| 5459 | + if (!vsi) | |
| 5460 | + return I40E_ERR_PARAM; | |
| 5461 | + pf = vsi->back; | |
| 5462 | + hw = &pf->hw; | |
| 5463 | + | |
| 5464 | + ctxt.seid = vsi->seid; | |
| 5465 | + ctxt.pf_num = hw->pf_id; | |
| 5466 | + ctxt.vf_num = vsi->vf_id + hw->func_caps.vf_base_id + vsi_offset; | |
| 5467 | + ctxt.uplink_seid = vsi->uplink_seid; | |
| 5468 | + ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL; | |
| 5469 | + ctxt.flags = I40E_AQ_VSI_TYPE_VF; | |
| 5470 | + ctxt.info = vsi->info; | |
| 5471 | + | |
| 5472 | + i40e_vsi_setup_queue_map(vsi, &ctxt, vsi->tc_config.enabled_tc, | |
| 5473 | + false); | |
| 5474 | + if (vsi->reconfig_rss) { | |
| 5475 | + vsi->rss_size = min_t(int, pf->alloc_rss_size, | |
| 5476 | + vsi->num_queue_pairs); | |
| 5477 | + ret = i40e_vsi_config_rss(vsi); | |
| 5478 | + if (ret) { | |
| 5479 | + dev_info(&pf->pdev->dev, "Failed to reconfig rss for num_queues\n"); | |
| 5480 | + return ret; | |
| 5481 | + } | |
| 5482 | + vsi->reconfig_rss = false; | |
| 5483 | + } | |
| 5484 | + | |
| 5485 | + ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); | |
| 5486 | + if (ret) { | |
| 5487 | + dev_info(&pf->pdev->dev, "Update vsi config failed, err %s aq_err %s\n", | |
| 5488 | + i40e_stat_str(hw, ret), | |
| 5489 | + i40e_aq_str(hw, hw->aq.asq_last_status)); | |
| 5490 | + return ret; | |
| 5491 | + } | |
| 5492 | + /* update the local VSI info with updated queue map */ | |
| 5493 | + i40e_vsi_update_queue_map(vsi, &ctxt); | |
| 5494 | + vsi->info.valid_sections = 0; | |
| 5495 | + | |
| 5496 | + return ret; | |
| 5497 | +} | |
| 5498 | + | |
| 5429 | 5499 | /** |
| 5430 | 5500 | * i40e_vsi_config_tc - Configure VSI Tx Scheduler for given TC map |
| 5431 | 5501 | * @vsi: VSI to be configured |
| @@ -5716,24 +5786,6 @@ static void i40e_remove_queue_channels(struct i40e_vsi *vsi) · 284 unmodified lines | ||
| 5716 | 5786 | INIT_LIST_HEAD(&vsi->ch_list); |
| 5717 | 5787 | } |
| 5718 | 5788 | |
| 5719 | −/** | |
| 5720 | − * i40e_is_any_channel - channel exist or not | |
| 5721 | − * @vsi: ptr to VSI to which channels are associated with | |
| 5722 | − * | |
| 5723 | − * Returns true or false if channel(s) exist for associated VSI or not | |
| 5724 | − **/ | |
| 5725 | −static bool i40e_is_any_channel(struct i40e_vsi *vsi) | |
| 5726 | −{ | |
| 5727 | − struct i40e_channel *ch, *ch_tmp; | |
| 5728 | − | |
| 5729 | − list_for_each_entry_safe(ch, ch_tmp, &vsi->ch_list, list) { | |
| 5730 | − if (ch->initialized) | |
| 5731 | − return true; | |
| 5732 | − } | |
| 5733 | − | |
| 5734 | − return false; | |
| 5735 | −} | |
| 5736 | − | |
| 5737 | 5789 | /** |
| 5738 | 5790 | * i40e_get_max_queues_for_channel |
| 5739 | 5791 | * @vsi: ptr to VSI to which channels are associated with |
| @@ -6240,26 +6292,15 @@ int i40e_create_queue_channel(struct i40e_vsi *vsi, · 500 unmodified lines | ||
| 6240 | 6292 | /* By default we are in VEPA mode, if this is the first VF/VMDq |
| 6241 | 6293 | * VSI to be added switch to VEB mode. |
| 6242 | 6294 | */ |
| 6243 | − if ((!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) || | |
| 6244 | − (!i40e_is_any_channel(vsi))) { | |
| 6245 | − if (!is_power_of_2(vsi->tc_config.tc_info[0].qcount)) { | |
| 6246 | − dev_dbg(&pf->pdev->dev, | |
| 6247 | − "Failed to create channel. Override queues (%u) not power of 2\n", | |
| 6248 | − vsi->tc_config.tc_info[0].qcount); | |
| 6249 | − return -EINVAL; | |
| 6250 | − } | |
| 6251 | 6295 | |
| 6252 | − if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { | |
| 6253 | − pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; | |
| 6296 | + if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { | |
| 6297 | + pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; | |
| 6254 | 6298 | |
| 6255 | − if (vsi->type == I40E_VSI_MAIN) { | |
| 6256 | − if (pf->flags & I40E_FLAG_TC_MQPRIO) | |
| 6257 | − i40e_do_reset(pf, I40E_PF_RESET_FLAG, | |
| 6258 | − true); | |
| 6259 | − else | |
| 6260 | − i40e_do_reset_safe(pf, | |
| 6261 | − I40E_PF_RESET_FLAG); | |
| 6262 | − } | |
| 6299 | + if (vsi->type == I40E_VSI_MAIN) { | |
| 6300 | + if (pf->flags & I40E_FLAG_TC_MQPRIO) | |
| 6301 | + i40e_do_reset(pf, I40E_PF_RESET_FLAG, true); | |
| 6302 | + else | |
| 6303 | + i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); | |
| 6263 | 6304 | } |
| 6264 | 6305 | /* now onwards for main VSI, number of queues will be value |
| 6265 | 6306 | * of TC0's queue count |
| @@ -7912,12 +7953,20 @@ config_tc: · 1646 unmodified lines | ||
| 7912 | 7953 | vsi->seid); |
| 7913 | 7954 | need_reset = true; |
| 7914 | 7955 | goto exit; |
| 7915 | − } else { | |
| 7916 | − dev_info(&vsi->back->pdev->dev, | |
| 7917 | − "Setup channel (id:%u) utilizing num_queues %d\n", | |
| 7918 | − vsi->seid, vsi->tc_config.tc_info[0].qcount); | |
| 7956 | + } else if (enabled_tc && | |
| 7957 | + (!is_power_of_2(vsi->tc_config.tc_info[0].qcount))) { | |
| 7958 | + netdev_info(netdev, | |
| 7959 | + "Failed to create channel. Override queues (%u) not power of 2\n", | |
| 7960 | + vsi->tc_config.tc_info[0].qcount); | |
| 7961 | + ret = -EINVAL; | |
| 7962 | + need_reset = true; | |
| 7963 | + goto exit; | |
| 7919 | 7964 | } |
| 7920 | 7965 | |
| 7966 | + dev_info(&vsi->back->pdev->dev, | |
| 7967 | + "Setup channel (id:%u) utilizing num_queues %d\n", | |
| 7968 | + vsi->seid, vsi->tc_config.tc_info[0].qcount); | |
| 7969 | + | |
| 7921 | 7970 | if (pf->flags & I40E_FLAG_TC_MQPRIO) { |
| 7922 | 7971 | if (vsi->mqprio_qopt.max_rate[0]) { |
| 7923 | 7972 | u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; |
| @@ -8482,9 +8531,8 @@ static int i40e_configure_clsflower(struct i40e_vsi *vsi, · 558 unmodified lines | ||
| 8482 | 8531 | err = i40e_add_del_cloud_filter(vsi, filter, true); |
| 8483 | 8532 | |
| 8484 | 8533 | if (err) { |
| 8485 | − dev_err(&pf->pdev->dev, | |
| 8486 | − "Failed to add cloud filter, err %s\n", | |
| 8487 | − i40e_stat_str(&pf->hw, err)); | |
| 8534 | + dev_err(&pf->pdev->dev, "Failed to add cloud filter, err %d\n", | |
| 8535 | + err); | |
| 8488 | 8536 | goto err; |
| 8489 | 8537 | } |
| 8490 | 8538 | |
| @@ -13771,7 +13819,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi) · 5280 unmodified lines | ||
| 13771 | 13819 | dev_info(&pf->pdev->dev, "Can't remove PF VSI\n"); |
| 13772 | 13820 | return -ENODEV; |
| 13773 | 13821 | } |
| 13774 | − | |
| 13822 | + set_bit(__I40E_VSI_RELEASING, vsi->state); | |
| 13775 | 13823 | uplink_seid = vsi->uplink_seid; |
| 13776 | 13824 | if (vsi->type != I40E_VSI_SRIOV) { |
| 13777 | 13825 | if (vsi->netdev_registered) { |
| @@ -183,17 +183,18 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf) · 182 unmodified lines | ||
| 183 | 183 | /***********************misc routines*****************************/ |
| 184 | 184 | |
| 185 | 185 | /** |
| 186 | − * i40e_vc_disable_vf | |
| 186 | + * i40e_vc_reset_vf | |
| 187 | 187 | * @vf: pointer to the VF info |
| 188 | − * | |
| 189 | − * Disable the VF through a SW reset. | |
| 188 | + * @notify_vf: notify vf about reset or not | |
| 189 | + * Reset VF handler. | |
| 190 | 190 | **/ |
| 191 | −static inline void i40e_vc_disable_vf(struct i40e_vf *vf) | |
| 191 | +static void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf) | |
| 192 | 192 | { |
| 193 | 193 | struct i40e_pf *pf = vf->pf; |
| 194 | 194 | int i; |
| 195 | 195 | |
| 196 | − i40e_vc_notify_vf_reset(vf); | |
| 196 | + if (notify_vf) | |
| 197 | + i40e_vc_notify_vf_reset(vf); | |
| 197 | 198 | |
| 198 | 199 | /* We want to ensure that an actual reset occurs initiated after this |
| 199 | 200 | * function was called. However, we do not want to wait forever, so |
| @@ -211,9 +212,14 @@ static inline void i40e_vc_disable_vf(struct i40e_vf *vf) · 11 unmodified lines | ||
| 211 | 212 | usleep_range(10000, 20000); |
| 212 | 213 | } |
| 213 | 214 | |
| 214 | − dev_warn(&vf->pf->pdev->dev, | |
| 215 | − "Failed to initiate reset for VF %d after 200 milliseconds\n", | |
| 216 | − vf->vf_id); | |
| 215 | + if (notify_vf) | |
| 216 | + dev_warn(&vf->pf->pdev->dev, | |
| 217 | + "Failed to initiate reset for VF %d after 200 milliseconds\n", | |
| 218 | + vf->vf_id); | |
| 219 | + else | |
| 220 | + dev_dbg(&vf->pf->pdev->dev, | |
| 221 | + "Failed to initiate reset for VF %d after 200 milliseconds\n", | |
| 222 | + vf->vf_id); | |
| 217 | 223 | } |
| 218 | 224 | |
| 219 | 225 | /** |
| @@ -674,14 +680,13 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id, · 454 unmodified lines | ||
| 674 | 680 | u16 vsi_queue_id, |
| 675 | 681 | struct virtchnl_rxq_info *info) |
| 676 | 682 | { |
| 683 | + u16 pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id); | |
| 677 | 684 | struct i40e_pf *pf = vf->pf; |
| 685 | + struct i40e_vsi *vsi = pf->vsi[vf->lan_vsi_idx]; | |
| 678 | 686 | struct i40e_hw *hw = &pf->hw; |
| 679 | 687 | struct i40e_hmc_obj_rxq rx_ctx; |
| 680 | − u16 pf_queue_id; | |
| 681 | 688 | int ret = 0; |
| 682 | 689 | |
| 683 | − pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id); | |
| 684 | − | |
| 685 | 690 | /* clear the context structure first */ |
| 686 | 691 | memset(&rx_ctx, 0, sizeof(struct i40e_hmc_obj_rxq)); |
| 687 | 692 | |
| @@ -719,6 +724,10 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id, · 31 unmodified lines | ||
| 719 | 724 | } |
| 720 | 725 | rx_ctx.rxmax = info->max_pkt_size; |
| 721 | 726 | |
| 727 | + /* if port VLAN is configured increase the max packet size */ | |
| 728 | + if (vsi->info.pvid) | |
| 729 | + rx_ctx.rxmax += VLAN_HLEN; | |
| 730 | + | |
| 722 | 731 | /* enable 32bytes desc always */ |
| 723 | 732 | rx_ctx.dsize = 1; |
| 724 | 733 | |
| @@ -1939,6 +1948,32 @@ static int i40e_vc_send_resp_to_vf(struct i40e_vf *vf, · 1214 unmodified lines | ||
| 1939 | 1948 | return i40e_vc_send_msg_to_vf(vf, opcode, retval, NULL, 0); |
| 1940 | 1949 | } |
| 1941 | 1950 | |
| 1951 | +/** | |
| 1952 | + * i40e_sync_vf_state | |
| 1953 | + * @vf: pointer to the VF info | |
| 1954 | + * @state: VF state | |
| 1955 | + * | |
| 1956 | + * Called from a VF message to synchronize the service with a potential | |
| 1957 | + * VF reset state | |
| 1958 | + **/ | |
| 1959 | +static bool i40e_sync_vf_state(struct i40e_vf *vf, enum i40e_vf_states state) | |
| 1960 | +{ | |
| 1961 | + int i; | |
| 1962 | + | |
| 1963 | + /* When handling some messages, it needs VF state to be set. | |
| 1964 | + * It is possible that this flag is cleared during VF reset, | |
| 1965 | + * so there is a need to wait until the end of the reset to | |
| 1966 | + * handle the request message correctly. | |
| 1967 | + */ | |
| 1968 | + for (i = 0; i < I40E_VF_STATE_WAIT_COUNT; i++) { | |
| 1969 | + if (test_bit(state, &vf->vf_states)) | |
| 1970 | + return true; | |
| 1971 | + usleep_range(10000, 20000); | |
| 1972 | + } | |
| 1973 | + | |
| 1974 | + return test_bit(state, &vf->vf_states); | |
| 1975 | +} | |
| 1976 | + | |
| 1942 | 1977 | /** |
| 1943 | 1978 | * i40e_vc_get_version_msg |
| 1944 | 1979 | * @vf: pointer to the VF info |
| @@ -1999,7 +2034,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) · 54 unmodified lines | ||
| 1999 | 2034 | size_t len = 0; |
| 2000 | 2035 | int ret; |
| 2001 | 2036 | |
| 2002 | − if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { | |
| 2037 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_INIT)) { | |
| 2003 | 2038 | aq_ret = I40E_ERR_PARAM; |
| 2004 | 2039 | goto err; |
| 2005 | 2040 | } |
| @@ -2105,20 +2140,6 @@ err: · 99 unmodified lines | ||
| 2105 | 2140 | return ret; |
| 2106 | 2141 | } |
| 2107 | 2142 | |
| 2108 | −/** | |
| 2109 | − * i40e_vc_reset_vf_msg | |
| 2110 | − * @vf: pointer to the VF info | |
| 2111 | − * | |
| 2112 | − * called from the VF to reset itself, | |
| 2113 | − * unlike other virtchnl messages, PF driver | |
| 2114 | − * doesn't send the response back to the VF | |
| 2115 | − **/ | |
| 2116 | −static void i40e_vc_reset_vf_msg(struct i40e_vf *vf) | |
| 2117 | −{ | |
| 2118 | − if (test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) | |
| 2119 | − i40e_reset_vf(vf, false); | |
| 2120 | −} | |
| 2121 | − | |
| 2122 | 2143 | /** |
| 2123 | 2144 | * i40e_vc_config_promiscuous_mode_msg |
| 2124 | 2145 | * @vf: pointer to the VF info |
| @@ -2136,7 +2157,7 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf, u8 *msg) · 11 unmodified lines | ||
| 2136 | 2157 | bool allmulti = false; |
| 2137 | 2158 | bool alluni = false; |
| 2138 | 2159 | |
| 2139 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 2160 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 2140 | 2161 | aq_ret = I40E_ERR_PARAM; |
| 2141 | 2162 | goto err_out; |
| 2142 | 2163 | } |
| @@ -2217,13 +2238,14 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) · 74 unmodified lines | ||
| 2217 | 2238 | struct virtchnl_vsi_queue_config_info *qci = |
| 2218 | 2239 | (struct virtchnl_vsi_queue_config_info *)msg; |
| 2219 | 2240 | struct virtchnl_queue_pair_info *qpi; |
| 2220 | − struct i40e_pf *pf = vf->pf; | |
| 2221 | 2241 | u16 vsi_id, vsi_queue_id = 0; |
| 2222 | − u16 num_qps_all = 0; | |
| 2242 | + struct i40e_pf *pf = vf->pf; | |
| 2223 | 2243 | i40e_status aq_ret = 0; |
| 2224 | 2244 | int i, j = 0, idx = 0; |
| 2245 | + struct i40e_vsi *vsi; | |
| 2246 | + u16 num_qps_all = 0; | |
| 2225 | 2247 | |
| 2226 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 2248 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 2227 | 2249 | aq_ret = I40E_ERR_PARAM; |
| 2228 | 2250 | goto error_param; |
| 2229 | 2251 | } |
| @@ -2310,9 +2332,15 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) · 80 unmodified lines | ||
| 2310 | 2332 | pf->vsi[vf->lan_vsi_idx]->num_queue_pairs = |
| 2311 | 2333 | qci->num_queue_pairs; |
| 2312 | 2334 | } else { |
| 2313 | − for (i = 0; i < vf->num_tc; i++) | |
| 2314 | − pf->vsi[vf->ch[i].vsi_idx]->num_queue_pairs = | |
| 2315 | − vf->ch[i].num_qps; | |
| 2335 | + for (i = 0; i < vf->num_tc; i++) { | |
| 2336 | + vsi = pf->vsi[vf->ch[i].vsi_idx]; | |
| 2337 | + vsi->num_queue_pairs = vf->ch[i].num_qps; | |
| 2338 | + | |
| 2339 | + if (i40e_update_adq_vsi_queues(vsi, i)) { | |
| 2340 | + aq_ret = I40E_ERR_CONFIG; | |
| 2341 | + goto error_param; | |
| 2342 | + } | |
| 2343 | + } | |
| 2316 | 2344 | } |
| 2317 | 2345 | |
| 2318 | 2346 | error_param: |
| @@ -2366,7 +2394,7 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg) · 47 unmodified lines | ||
| 2366 | 2394 | i40e_status aq_ret = 0; |
| 2367 | 2395 | int i; |
| 2368 | 2396 | |
| 2369 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 2397 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 2370 | 2398 | aq_ret = I40E_ERR_PARAM; |
| 2371 | 2399 | goto error_param; |
| 2372 | 2400 | } |
| @@ -2538,7 +2566,7 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg) · 165 unmodified lines | ||
| 2538 | 2566 | struct i40e_pf *pf = vf->pf; |
| 2539 | 2567 | i40e_status aq_ret = 0; |
| 2540 | 2568 | |
| 2541 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 2569 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 2542 | 2570 | aq_ret = I40E_ERR_PARAM; |
| 2543 | 2571 | goto error_param; |
| 2544 | 2572 | } |
| @@ -2588,7 +2616,7 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg) · 43 unmodified lines | ||
| 2588 | 2616 | u8 cur_pairs = vf->num_queue_pairs; |
| 2589 | 2617 | struct i40e_pf *pf = vf->pf; |
| 2590 | 2618 | |
| 2591 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) | |
| 2619 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) | |
| 2592 | 2620 | return -EINVAL; |
| 2593 | 2621 | |
| 2594 | 2622 | if (req_pairs > I40E_MAX_VF_QUEUES) { |
| @@ -2607,8 +2635,7 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg) · 12 unmodified lines | ||
| 2607 | 2635 | } else { |
| 2608 | 2636 | /* successful request */ |
| 2609 | 2637 | vf->num_req_queues = req_pairs; |
| 2610 | − i40e_vc_notify_vf_reset(vf); | |
| 2611 | − i40e_reset_vf(vf, false); | |
| 2638 | + i40e_vc_reset_vf(vf, true); | |
| 2612 | 2639 | return 0; |
| 2613 | 2640 | } |
| 2614 | 2641 | |
| @@ -2634,7 +2661,7 @@ static int i40e_vc_get_stats_msg(struct i40e_vf *vf, u8 *msg) · 19 unmodified lines | ||
| 2634 | 2661 | |
| 2635 | 2662 | memset(&stats, 0, sizeof(struct i40e_eth_stats)); |
| 2636 | 2663 | |
| 2637 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 2664 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 2638 | 2665 | aq_ret = I40E_ERR_PARAM; |
| 2639 | 2666 | goto error_param; |
| 2640 | 2667 | } |
| @@ -2751,7 +2778,7 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg) · 110 unmodified lines | ||
| 2751 | 2778 | i40e_status ret = 0; |
| 2752 | 2779 | int i; |
| 2753 | 2780 | |
| 2754 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | |
| 2781 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || | |
| 2755 | 2782 | !i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) { |
| 2756 | 2783 | ret = I40E_ERR_PARAM; |
| 2757 | 2784 | goto error_param; |
| @@ -2823,7 +2850,7 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg) · 65 unmodified lines | ||
| 2823 | 2850 | i40e_status ret = 0; |
| 2824 | 2851 | int i; |
| 2825 | 2852 | |
| 2826 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | |
| 2853 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || | |
| 2827 | 2854 | !i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) { |
| 2828 | 2855 | ret = I40E_ERR_PARAM; |
| 2829 | 2856 | goto error_param; |
| @@ -2967,7 +2994,7 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg) · 137 unmodified lines | ||
| 2967 | 2994 | i40e_status aq_ret = 0; |
| 2968 | 2995 | int i; |
| 2969 | 2996 | |
| 2970 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | |
| 2997 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || | |
| 2971 | 2998 | !i40e_vc_isvalid_vsi_id(vf, vfl->vsi_id)) { |
| 2972 | 2999 | aq_ret = I40E_ERR_PARAM; |
| 2973 | 3000 | goto error_param; |
| @@ -3087,9 +3114,9 @@ static int i40e_vc_config_rss_key(struct i40e_vf *vf, u8 *msg) · 113 unmodified lines | ||
| 3087 | 3114 | struct i40e_vsi *vsi = NULL; |
| 3088 | 3115 | i40e_status aq_ret = 0; |
| 3089 | 3116 | |
| 3090 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | |
| 3117 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || | |
| 3091 | 3118 | !i40e_vc_isvalid_vsi_id(vf, vrk->vsi_id) || |
| 3092 | − (vrk->key_len != I40E_HKEY_ARRAY_SIZE)) { | |
| 3119 | + vrk->key_len != I40E_HKEY_ARRAY_SIZE) { | |
| 3093 | 3120 | aq_ret = I40E_ERR_PARAM; |
| 3094 | 3121 | goto err; |
| 3095 | 3122 | } |
| @@ -3118,9 +3145,9 @@ static int i40e_vc_config_rss_lut(struct i40e_vf *vf, u8 *msg) · 22 unmodified lines | ||
| 3118 | 3145 | i40e_status aq_ret = 0; |
| 3119 | 3146 | u16 i; |
| 3120 | 3147 | |
| 3121 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | |
| 3148 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || | |
| 3122 | 3149 | !i40e_vc_isvalid_vsi_id(vf, vrl->vsi_id) || |
| 3123 | − (vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE)) { | |
| 3150 | + vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE) { | |
| 3124 | 3151 | aq_ret = I40E_ERR_PARAM; |
| 3125 | 3152 | goto err; |
| 3126 | 3153 | } |
| @@ -3153,7 +3180,7 @@ static int i40e_vc_get_rss_hena(struct i40e_vf *vf, u8 *msg) · 26 unmodified lines | ||
| 3153 | 3180 | i40e_status aq_ret = 0; |
| 3154 | 3181 | int len = 0; |
| 3155 | 3182 | |
| 3156 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 3183 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 3157 | 3184 | aq_ret = I40E_ERR_PARAM; |
| 3158 | 3185 | goto err; |
| 3159 | 3186 | } |
| @@ -3189,7 +3216,7 @@ static int i40e_vc_set_rss_hena(struct i40e_vf *vf, u8 *msg) · 29 unmodified lines | ||
| 3189 | 3216 | struct i40e_hw *hw = &pf->hw; |
| 3190 | 3217 | i40e_status aq_ret = 0; |
| 3191 | 3218 | |
| 3192 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 3219 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 3193 | 3220 | aq_ret = I40E_ERR_PARAM; |
| 3194 | 3221 | goto err; |
| 3195 | 3222 | } |
| @@ -3214,7 +3241,7 @@ static int i40e_vc_enable_vlan_stripping(struct i40e_vf *vf, u8 *msg) · 18 unmodified lines | ||
| 3214 | 3241 | i40e_status aq_ret = 0; |
| 3215 | 3242 | struct i40e_vsi *vsi; |
| 3216 | 3243 | |
| 3217 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 3244 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 3218 | 3245 | aq_ret = I40E_ERR_PARAM; |
| 3219 | 3246 | goto err; |
| 3220 | 3247 | } |
| @@ -3240,7 +3267,7 @@ static int i40e_vc_disable_vlan_stripping(struct i40e_vf *vf, u8 *msg) · 19 unmodified lines | ||
| 3240 | 3267 | i40e_status aq_ret = 0; |
| 3241 | 3268 | struct i40e_vsi *vsi; |
| 3242 | 3269 | |
| 3243 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 3270 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 3244 | 3271 | aq_ret = I40E_ERR_PARAM; |
| 3245 | 3272 | goto err; |
| 3246 | 3273 | } |
| @@ -3467,7 +3494,7 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg) · 220 unmodified lines | ||
| 3467 | 3494 | i40e_status aq_ret = 0; |
| 3468 | 3495 | int i, ret; |
| 3469 | 3496 | |
| 3470 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 3497 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 3471 | 3498 | aq_ret = I40E_ERR_PARAM; |
| 3472 | 3499 | goto err; |
| 3473 | 3500 | } |
| @@ -3598,7 +3625,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) · 124 unmodified lines | ||
| 3598 | 3625 | i40e_status aq_ret = 0; |
| 3599 | 3626 | int i, ret; |
| 3600 | 3627 | |
| 3601 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 3628 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 3602 | 3629 | aq_ret = I40E_ERR_PARAM; |
| 3603 | 3630 | goto err_out; |
| 3604 | 3631 | } |
| @@ -3707,7 +3734,7 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg) · 102 unmodified lines | ||
| 3707 | 3734 | i40e_status aq_ret = 0; |
| 3708 | 3735 | u64 speed = 0; |
| 3709 | 3736 | |
| 3710 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 3737 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 3711 | 3738 | aq_ret = I40E_ERR_PARAM; |
| 3712 | 3739 | goto err; |
| 3713 | 3740 | } |
| @@ -3796,15 +3823,9 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg) · 82 unmodified lines | ||
| 3796 | 3823 | |
| 3797 | 3824 | /* set this flag only after making sure all inputs are sane */ |
| 3798 | 3825 | vf->adq_enabled = true; |
| 3799 | − /* num_req_queues is set when user changes number of queues via ethtool | |
| 3800 | − * and this causes issue for default VSI(which depends on this variable) | |
| 3801 | − * when ADq is enabled, hence reset it. | |
| 3802 | − */ | |
| 3803 | − vf->num_req_queues = 0; | |
| 3804 | 3826 | |
| 3805 | 3827 | /* reset the VF in order to allocate resources */ |
| 3806 | − i40e_vc_notify_vf_reset(vf); | |
| 3807 | − i40e_reset_vf(vf, false); | |
| 3828 | + i40e_vc_reset_vf(vf, true); | |
| 3808 | 3829 | |
| 3809 | 3830 | return I40E_SUCCESS; |
| 3810 | 3831 | |
| @@ -3824,7 +3845,7 @@ static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg) · 13 unmodified lines | ||
| 3824 | 3845 | struct i40e_pf *pf = vf->pf; |
| 3825 | 3846 | i40e_status aq_ret = 0; |
| 3826 | 3847 | |
| 3827 | − if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | |
| 3848 | + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { | |
| 3828 | 3849 | aq_ret = I40E_ERR_PARAM; |
| 3829 | 3850 | goto err; |
| 3830 | 3851 | } |
| @@ -3844,8 +3865,7 @@ static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg) · 13 unmodified lines | ||
| 3844 | 3865 | } |
| 3845 | 3866 | |
| 3846 | 3867 | /* reset the VF in order to allocate resources */ |
| 3847 | − i40e_vc_notify_vf_reset(vf); | |
| 3848 | − i40e_reset_vf(vf, false); | |
| 3868 | + i40e_vc_reset_vf(vf, true); | |
| 3849 | 3869 | |
| 3850 | 3870 | return I40E_SUCCESS; |
| 3851 | 3871 | |
| @@ -3907,7 +3927,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode, · 55 unmodified lines | ||
| 3907 | 3927 | i40e_vc_notify_vf_link_state(vf); |
| 3908 | 3928 | break; |
| 3909 | 3929 | case VIRTCHNL_OP_RESET_VF: |
| 3910 | − i40e_vc_reset_vf_msg(vf); | |
| 3930 | + i40e_vc_reset_vf(vf, false); | |
| 3911 | 3931 | ret = 0; |
| 3912 | 3932 | break; |
| 3913 | 3933 | case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: |
| @@ -4161,7 +4181,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) · 247 unmodified lines | ||
| 4161 | 4181 | /* Force the VF interface down so it has to bring up with new MAC |
| 4162 | 4182 | * address |
| 4163 | 4183 | */ |
| 4164 | − i40e_vc_disable_vf(vf); | |
| 4184 | + i40e_vc_reset_vf(vf, true); | |
| 4165 | 4185 | dev_info(&pf->pdev->dev, "Bring down and up the VF interface to make this change effective.\n"); |
| 4166 | 4186 | |
| 4167 | 4187 | error_param: |
| @@ -4169,34 +4189,6 @@ error_param: · 1 unmodified line | ||
| 4169 | 4189 | return ret; |
| 4170 | 4190 | } |
| 4171 | 4191 | |
| 4172 | −/** | |
| 4173 | − * i40e_vsi_has_vlans - True if VSI has configured VLANs | |
| 4174 | − * @vsi: pointer to the vsi | |
| 4175 | − * | |
| 4176 | − * Check if a VSI has configured any VLANs. False if we have a port VLAN or if | |
| 4177 | − * we have no configured VLANs. Do not call while holding the | |
| 4178 | − * mac_filter_hash_lock. | |
| 4179 | − */ | |
| 4180 | −static bool i40e_vsi_has_vlans(struct i40e_vsi *vsi) | |
| 4181 | −{ | |
| 4182 | − bool have_vlans; | |
| 4183 | − | |
| 4184 | − /* If we have a port VLAN, then the VSI cannot have any VLANs | |
| 4185 | − * configured, as all MAC/VLAN filters will be assigned to the PVID. | |
| 4186 | − */ | |
| 4187 | − if (vsi->info.pvid) | |
| 4188 | − return false; | |
| 4189 | − | |
| 4190 | − /* Since we don't have a PVID, we know that if the device is in VLAN | |
| 4191 | − * mode it must be because of a VLAN filter configured on this VSI. | |
| 4192 | − */ | |
| 4193 | − spin_lock_bh(&vsi->mac_filter_hash_lock); | |
| 4194 | − have_vlans = i40e_is_vsi_in_vlan(vsi); | |
| 4195 | − spin_unlock_bh(&vsi->mac_filter_hash_lock); | |
| 4196 | − | |
| 4197 | − return have_vlans; | |
| 4198 | −} | |
| 4199 | − | |
| 4200 | 4192 | /** |
| 4201 | 4193 | * i40e_ndo_set_vf_port_vlan |
| 4202 | 4194 | * @netdev: network interface device structure |
| @@ -4253,19 +4245,9 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, · 50 unmodified lines | ||
| 4253 | 4245 | /* duplicate request, so just return success */ |
| 4254 | 4246 | goto error_pvid; |
| 4255 | 4247 | |
| 4256 | − if (i40e_vsi_has_vlans(vsi)) { | |
| 4257 | − dev_err(&pf->pdev->dev, | |
| 4258 | − "VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n", | |
| 4259 | − vf_id); | |
| 4260 | − /* Administrator Error - knock the VF offline until he does | |
| 4261 | − * the right thing by reconfiguring his network correctly | |
| 4262 | − * and then reloading the VF driver. | |
| 4263 | − */ | |
| 4264 | − i40e_vc_disable_vf(vf); | |
| 4265 | − /* During reset the VF got a new VSI, so refresh the pointer. */ | |
| 4266 | − vsi = pf->vsi[vf->lan_vsi_idx]; | |
| 4267 | − } | |
| 4268 | − | |
| 4248 | + i40e_vc_reset_vf(vf, true); | |
| 4249 | + /* During reset the VF got a new VSI, so refresh a pointer. */ | |
| 4250 | + vsi = pf->vsi[vf->lan_vsi_idx]; | |
| 4269 | 4251 | /* Locked once because multiple functions below iterate list */ |
| 4270 | 4252 | spin_lock_bh(&vsi->mac_filter_hash_lock); |
| 4271 | 4253 | |
| @@ -4641,7 +4623,7 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting) · 369 unmodified lines | ||
| 4641 | 4623 | goto out; |
| 4642 | 4624 | |
| 4643 | 4625 | vf->trusted = setting; |
| 4644 | − i40e_vc_disable_vf(vf); | |
| 4626 | + i40e_vc_reset_vf(vf, true); | |
| 4645 | 4627 | dev_info(&pf->pdev->dev, "VF %u is now %strusted\n", |
| 4646 | 4628 | vf_id, setting ? "" : "un"); |
| 4647 | 4629 | |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #define I40E_MAX_VF_PROMISC_FLAGS 3 |
| 20 | 20 | |
| 21 | +#define I40E_VF_STATE_WAIT_COUNT 20 | |
| 22 | + | |
| 21 | 23 | /* Various queue ctrls */ |
| 22 | 24 | enum i40e_queue_ctrl { |
| 23 | 25 | I40E_QUEUE_CTRL_UNKNOWN = 0, |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | #include "iavf_txrx.h" |
| 40 | 40 | #include "iavf_fdir.h" |
| 41 | 41 | #include "iavf_adv_rss.h" |
| 42 | +#include <linux/bitmap.h> | |
| 42 | 43 | |
| 43 | 44 | #define DEFAULT_DEBUG_LEVEL_SHIFT 3 |
| 44 | 45 | #define PFX "iavf: " |
| @@ -304,6 +305,7 @@ struct iavf_adapter { · 259 unmodified lines | ||
| 304 | 305 | #define IAVF_FLAG_AQ_DEL_FDIR_FILTER BIT(26) |
| 305 | 306 | #define IAVF_FLAG_AQ_ADD_ADV_RSS_CFG BIT(27) |
| 306 | 307 | #define IAVF_FLAG_AQ_DEL_ADV_RSS_CFG BIT(28) |
| 308 | +#define IAVF_FLAG_AQ_REQUEST_STATS BIT(29) | |
| 307 | 309 | |
| 308 | 310 | /* OS defined structs */ |
| 309 | 311 | struct net_device *netdev; |
| @@ -443,6 +445,7 @@ int iavf_up(struct iavf_adapter *adapter); · 133 unmodified lines | ||
| 443 | 445 | void iavf_down(struct iavf_adapter *adapter); |
| 444 | 446 | int iavf_process_config(struct iavf_adapter *adapter); |
| 445 | 447 | void iavf_schedule_reset(struct iavf_adapter *adapter); |
| 448 | +void iavf_schedule_request_stats(struct iavf_adapter *adapter); | |
| 446 | 449 | void iavf_reset(struct iavf_adapter *adapter); |
| 447 | 450 | void iavf_set_ethtool_ops(struct net_device *netdev); |
| 448 | 451 | void iavf_update_stats(struct iavf_adapter *adapter); |
| @@ -500,4 +503,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter); · 51 unmodified lines | ||
| 500 | 503 | void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter); |
| 501 | 504 | struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, |
| 502 | 505 | const u8 *macaddr); |
| 506 | +int iavf_lock_timeout(struct mutex *lock, unsigned int msecs); | |
| 503 | 507 | #endif /* _IAVF_H_ */ |
| @@ -354,6 +354,9 @@ static void iavf_get_ethtool_stats(struct net_device *netdev, · 353 unmodified lines | ||
| 354 | 354 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 355 | 355 | unsigned int i; |
| 356 | 356 | |
| 357 | + /* Explicitly request stats refresh */ | |
| 358 | + iavf_schedule_request_stats(adapter); | |
| 359 | + | |
| 357 | 360 | iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats); |
| 358 | 361 | |
| 359 | 362 | rcu_read_lock(); |
| @@ -612,23 +615,44 @@ static int iavf_set_ringparam(struct net_device *netdev, · 252 unmodified lines | ||
| 612 | 615 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
| 613 | 616 | return -EINVAL; |
| 614 | 617 | |
| 615 | − new_tx_count = clamp_t(u32, ring->tx_pending, | |
| 616 | − IAVF_MIN_TXD, | |
| 617 | − IAVF_MAX_TXD); | |
| 618 | − new_tx_count = ALIGN(new_tx_count, IAVF_REQ_DESCRIPTOR_MULTIPLE); | |
| 618 | + if (ring->tx_pending > IAVF_MAX_TXD || | |
| 619 | + ring->tx_pending < IAVF_MIN_TXD || | |
| 620 | + ring->rx_pending > IAVF_MAX_RXD || | |
| 621 | + ring->rx_pending < IAVF_MIN_RXD) { | |
| 622 | + netdev_err(netdev, "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d] (increment %d)\n", | |
| 623 | + ring->tx_pending, ring->rx_pending, IAVF_MIN_TXD, | |
| 624 | + IAVF_MAX_RXD, IAVF_REQ_DESCRIPTOR_MULTIPLE); | |
| 625 | + return -EINVAL; | |
| 626 | + } | |
| 627 | + | |
| 628 | + new_tx_count = ALIGN(ring->tx_pending, IAVF_REQ_DESCRIPTOR_MULTIPLE); | |
| 629 | + if (new_tx_count != ring->tx_pending) | |
| 630 | + netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n", | |
| 631 | + new_tx_count); | |
| 619 | 632 | |
| 620 | − new_rx_count = clamp_t(u32, ring->rx_pending, | |
| 621 | − IAVF_MIN_RXD, | |
| 622 | − IAVF_MAX_RXD); | |
| 623 | − new_rx_count = ALIGN(new_rx_count, IAVF_REQ_DESCRIPTOR_MULTIPLE); | |
| 633 | + new_rx_count = ALIGN(ring->rx_pending, IAVF_REQ_DESCRIPTOR_MULTIPLE); | |
| 634 | + if (new_rx_count != ring->rx_pending) | |
| 635 | + netdev_info(netdev, "Requested Rx descriptor count rounded up to %d\n", | |
| 636 | + new_rx_count); | |
| 624 | 637 | |
| 625 | 638 | /* if nothing to do return success */ |
| 626 | 639 | if ((new_tx_count == adapter->tx_desc_count) && |
| 627 | − (new_rx_count == adapter->rx_desc_count)) | |
| 640 | + (new_rx_count == adapter->rx_desc_count)) { | |
| 641 | + netdev_dbg(netdev, "Nothing to change, descriptor count is same as requested\n"); | |
| 628 | 642 | return 0; |
| 643 | + } | |
| 644 | + | |
| 645 | + if (new_tx_count != adapter->tx_desc_count) { | |
| 646 | + netdev_dbg(netdev, "Changing Tx descriptor count from %d to %d\n", | |
| 647 | + adapter->tx_desc_count, new_tx_count); | |
| 648 | + adapter->tx_desc_count = new_tx_count; | |
| 649 | + } | |
| 629 | 650 | |
| 630 | − adapter->tx_desc_count = new_tx_count; | |
| 631 | − adapter->rx_desc_count = new_rx_count; | |
| 651 | + if (new_rx_count != adapter->rx_desc_count) { | |
| 652 | + netdev_dbg(netdev, "Changing Rx descriptor count from %d to %d\n", | |
| 653 | + adapter->rx_desc_count, new_rx_count); | |
| 654 | + adapter->rx_desc_count = new_rx_count; | |
| 655 | + } | |
| 632 | 656 | |
| 633 | 657 | if (netif_running(netdev)) { |
| 634 | 658 | adapter->flags |= IAVF_FLAG_RESET_NEEDED; |
| @@ -723,12 +747,31 @@ static int iavf_get_per_queue_coalesce(struct net_device *netdev, u32 queue, · 88 unmodified lines | ||
| 723 | 747 | * |
| 724 | 748 | * Change the ITR settings for a specific queue. |
| 725 | 749 | **/ |
| 726 | −static void iavf_set_itr_per_queue(struct iavf_adapter *adapter, | |
| 727 | − struct ethtool_coalesce *ec, int queue) | |
| 750 | +static int iavf_set_itr_per_queue(struct iavf_adapter *adapter, | |
| 751 | + struct ethtool_coalesce *ec, int queue) | |
| 728 | 752 | { |
| 729 | 753 | struct iavf_ring *rx_ring = &adapter->rx_rings[queue]; |
| 730 | 754 | struct iavf_ring *tx_ring = &adapter->tx_rings[queue]; |
| 731 | 755 | struct iavf_q_vector *q_vector; |
| 756 | + u16 itr_setting; | |
| 757 | + | |
| 758 | + itr_setting = rx_ring->itr_setting & ~IAVF_ITR_DYNAMIC; | |
| 759 | + | |
| 760 | + if (ec->rx_coalesce_usecs != itr_setting && | |
| 761 | + ec->use_adaptive_rx_coalesce) { | |
| 762 | + netif_info(adapter, drv, adapter->netdev, | |
| 763 | + "Rx interrupt throttling cannot be changed if adaptive-rx is enabled\n"); | |
| 764 | + return -EINVAL; | |
| 765 | + } | |
| 766 | + | |
| 767 | + itr_setting = tx_ring->itr_setting & ~IAVF_ITR_DYNAMIC; | |
| 768 | + | |
| 769 | + if (ec->tx_coalesce_usecs != itr_setting && | |
| 770 | + ec->use_adaptive_tx_coalesce) { | |
| 771 | + netif_info(adapter, drv, adapter->netdev, | |
| 772 | + "Tx interrupt throttling cannot be changed if adaptive-tx is enabled\n"); | |
| 773 | + return -EINVAL; | |
| 774 | + } | |
| 732 | 775 | |
| 733 | 776 | rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs); |
| 734 | 777 | tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs); |
| @@ -751,6 +794,7 @@ static void iavf_set_itr_per_queue(struct iavf_adapter *adapter, · 16 unmodified lines | ||
| 751 | 794 | * the Tx and Rx ITR values based on the values we have entered |
| 752 | 795 | * into the q_vector, no need to write the values now. |
| 753 | 796 | */ |
| 797 | + return 0; | |
| 754 | 798 | } |
| 755 | 799 | |
| 756 | 800 | /** |
| @@ -792,9 +836,11 @@ static int __iavf_set_coalesce(struct net_device *netdev, · 35 unmodified lines | ||
| 792 | 836 | */ |
| 793 | 837 | if (queue < 0) { |
| 794 | 838 | for (i = 0; i < adapter->num_active_queues; i++) |
| 795 | − iavf_set_itr_per_queue(adapter, ec, i); | |
| 839 | + if (iavf_set_itr_per_queue(adapter, ec, i)) | |
| 840 | + return -EINVAL; | |
| 796 | 841 | } else if (queue < adapter->num_active_queues) { |
| 797 | − iavf_set_itr_per_queue(adapter, ec, queue); | |
| 842 | + if (iavf_set_itr_per_queue(adapter, ec, queue)) | |
| 843 | + return -EINVAL; | |
| 798 | 844 | } else { |
| 799 | 845 | netif_info(adapter, drv, netdev, "Invalid queue value, queue range is 0 - %d\n", |
| 800 | 846 | adapter->num_active_queues - 1); |
| @@ -1776,6 +1822,7 @@ static int iavf_set_channels(struct net_device *netdev, · 975 unmodified lines | ||
| 1776 | 1822 | { |
| 1777 | 1823 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 1778 | 1824 | u32 num_req = ch->combined_count; |
| 1825 | + int i; | |
| 1779 | 1826 | |
| 1780 | 1827 | if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) && |
| 1781 | 1828 | adapter->num_tc) { |
| @@ -1786,7 +1833,7 @@ static int iavf_set_channels(struct net_device *netdev, · 4 unmodified lines | ||
| 1786 | 1833 | /* All of these should have already been checked by ethtool before this |
| 1787 | 1834 | * even gets to us, but just to be sure. |
| 1788 | 1835 | */ |
| 1789 | − if (num_req > adapter->vsi_res->num_queue_pairs) | |
| 1836 | + if (num_req == 0 || num_req > adapter->vsi_res->num_queue_pairs) | |
| 1790 | 1837 | return -EINVAL; |
| 1791 | 1838 | |
| 1792 | 1839 | if (num_req == adapter->num_active_queues) |
| @@ -1798,6 +1845,20 @@ static int iavf_set_channels(struct net_device *netdev, · 5 unmodified lines | ||
| 1798 | 1845 | adapter->num_req_queues = num_req; |
| 1799 | 1846 | adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED; |
| 1800 | 1847 | iavf_schedule_reset(adapter); |
| 1848 | + | |
| 1849 | + /* wait for the reset is done */ | |
| 1850 | + for (i = 0; i < IAVF_RESET_WAIT_COMPLETE_COUNT; i++) { | |
| 1851 | + msleep(IAVF_RESET_WAIT_MS); | |
| 1852 | + if (adapter->flags & IAVF_FLAG_RESET_PENDING) | |
| 1853 | + continue; | |
| 1854 | + break; | |
| 1855 | + } | |
| 1856 | + if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) { | |
| 1857 | + adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; | |
| 1858 | + adapter->num_active_queues = num_req; | |
| 1859 | + return -EOPNOTSUPP; | |
| 1860 | + } | |
| 1861 | + | |
| 1801 | 1862 | return 0; |
| 1802 | 1863 | } |
| 1803 | 1864 | |
| @@ -1844,14 +1905,13 @@ static int iavf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, · 40 unmodified lines | ||
| 1844 | 1905 | |
| 1845 | 1906 | if (hfunc) |
| 1846 | 1907 | *hfunc = ETH_RSS_HASH_TOP; |
| 1847 | − if (!indir) | |
| 1848 | − return 0; | |
| 1849 | − | |
| 1850 | − memcpy(key, adapter->rss_key, adapter->rss_key_size); | |
| 1908 | + if (key) | |
| 1909 | + memcpy(key, adapter->rss_key, adapter->rss_key_size); | |
| 1851 | 1910 | |
| 1852 | − /* Each 32 bits pointed by 'indir' is stored with a lut entry */ | |
| 1853 | − for (i = 0; i < adapter->rss_lut_size; i++) | |
| 1854 | − indir[i] = (u32)adapter->rss_lut[i]; | |
| 1911 | + if (indir) | |
| 1912 | + /* Each 32 bits pointed by 'indir' is stored with a lut entry */ | |
| 1913 | + for (i = 0; i < adapter->rss_lut_size; i++) | |
| 1914 | + indir[i] = (u32)adapter->rss_lut[i]; | |
| 1855 | 1915 | |
| 1856 | 1916 | return 0; |
| 1857 | 1917 | } |
| @@ -147,7 +147,7 @@ enum iavf_status iavf_free_virt_mem_d(struct iavf_hw *hw, · 146 unmodified lines | ||
| 147 | 147 | * |
| 148 | 148 | * Returns 0 on success, negative on failure |
| 149 | 149 | **/ |
| 150 | −static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs) | |
| 150 | +int iavf_lock_timeout(struct mutex *lock, unsigned int msecs) | |
| 151 | 151 | { |
| 152 | 152 | unsigned int wait, delay = 10; |
| 153 | 153 | |
| @@ -174,6 +174,19 @@ void iavf_schedule_reset(struct iavf_adapter *adapter) · 20 unmodified lines | ||
| 174 | 174 | } |
| 175 | 175 | } |
| 176 | 176 | |
| 177 | +/** | |
| 178 | + * iavf_schedule_request_stats - Set the flags and schedule statistics request | |
| 179 | + * @adapter: board private structure | |
| 180 | + * | |
| 181 | + * Sets IAVF_FLAG_AQ_REQUEST_STATS flag so iavf_watchdog_task() will explicitly | |
| 182 | + * request and refresh ethtool stats | |
| 183 | + **/ | |
| 184 | +void iavf_schedule_request_stats(struct iavf_adapter *adapter) | |
| 185 | +{ | |
| 186 | + adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_STATS; | |
| 187 | + mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0); | |
| 188 | +} | |
| 189 | + | |
| 177 | 190 | /** |
| 178 | 191 | * iavf_tx_timeout - Respond to a Tx Hang |
| 179 | 192 | * @netdev: network interface device structure |
| @@ -696,6 +709,21 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan) · 516 unmodified lines | ||
| 696 | 709 | spin_unlock_bh(&adapter->mac_vlan_list_lock); |
| 697 | 710 | } |
| 698 | 711 | |
| 712 | +/** | |
| 713 | + * iavf_restore_filters | |
| 714 | + * @adapter: board private structure | |
| 715 | + * | |
| 716 | + * Restore existing non MAC filters when VF netdev comes back up | |
| 717 | + **/ | |
| 718 | +static void iavf_restore_filters(struct iavf_adapter *adapter) | |
| 719 | +{ | |
| 720 | + u16 vid; | |
| 721 | + | |
| 722 | + /* re-add all VLAN filters */ | |
| 723 | + for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID) | |
| 724 | + iavf_add_vlan(adapter, vid); | |
| 725 | +} | |
| 726 | + | |
| 699 | 727 | /** |
| 700 | 728 | * iavf_vlan_rx_add_vid - Add a VLAN filter to a device |
| 701 | 729 | * @netdev: network device struct |
| @@ -709,8 +737,11 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev, · 7 unmodified lines | ||
| 709 | 737 | |
| 710 | 738 | if (!VLAN_ALLOWED(adapter)) |
| 711 | 739 | return -EIO; |
| 740 | + | |
| 712 | 741 | if (iavf_add_vlan(adapter, vid) == NULL) |
| 713 | 742 | return -ENOMEM; |
| 743 | + | |
| 744 | + set_bit(vid, adapter->vsi.active_vlans); | |
| 714 | 745 | return 0; |
| 715 | 746 | } |
| 716 | 747 | |
| @@ -725,11 +756,10 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev, · 8 unmodified lines | ||
| 725 | 756 | { |
| 726 | 757 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 727 | 758 | |
| 728 | − if (VLAN_ALLOWED(adapter)) { | |
| 729 | − iavf_del_vlan(adapter, vid); | |
| 730 | − return 0; | |
| 731 | − } | |
| 732 | − return -EIO; | |
| 759 | + iavf_del_vlan(adapter, vid); | |
| 760 | + clear_bit(vid, adapter->vsi.active_vlans); | |
| 761 | + | |
| 762 | + return 0; | |
| 733 | 763 | } |
| 734 | 764 | |
| 735 | 765 | /** |
| @@ -1639,8 +1669,7 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter) · 903 unmodified lines | ||
| 1639 | 1669 | iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC); |
| 1640 | 1670 | return 0; |
| 1641 | 1671 | } |
| 1642 | − | |
| 1643 | − if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) && | |
| 1672 | + if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) || | |
| 1644 | 1673 | (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) { |
| 1645 | 1674 | iavf_set_promiscuous(adapter, 0); |
| 1646 | 1675 | return 0; |
| @@ -1688,6 +1717,11 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter) · 41 unmodified lines | ||
| 1688 | 1717 | iavf_del_adv_rss_cfg(adapter); |
| 1689 | 1718 | return 0; |
| 1690 | 1719 | } |
| 1720 | + if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_STATS) { | |
| 1721 | + iavf_request_stats(adapter); | |
| 1722 | + return 0; | |
| 1723 | + } | |
| 1724 | + | |
| 1691 | 1725 | return -EAGAIN; |
| 1692 | 1726 | } |
| 1693 | 1727 | |
| @@ -2123,8 +2157,8 @@ static void iavf_disable_vf(struct iavf_adapter *adapter) · 429 unmodified lines | ||
| 2123 | 2157 | |
| 2124 | 2158 | iavf_free_misc_irq(adapter); |
| 2125 | 2159 | iavf_reset_interrupt_capability(adapter); |
| 2126 | − iavf_free_queues(adapter); | |
| 2127 | 2160 | iavf_free_q_vectors(adapter); |
| 2161 | + iavf_free_queues(adapter); | |
| 2128 | 2162 | memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE); |
| 2129 | 2163 | iavf_shutdown_adminq(&adapter->hw); |
| 2130 | 2164 | adapter->netdev->flags &= ~IFF_UP; |
| @@ -2152,7 +2186,6 @@ static void iavf_reset_task(struct work_struct *work) · 21 unmodified lines | ||
| 2152 | 2186 | struct net_device *netdev = adapter->netdev; |
| 2153 | 2187 | struct iavf_hw *hw = &adapter->hw; |
| 2154 | 2188 | struct iavf_mac_filter *f, *ftmp; |
| 2155 | − struct iavf_vlan_filter *vlf; | |
| 2156 | 2189 | struct iavf_cloud_filter *cf; |
| 2157 | 2190 | u32 reg_val; |
| 2158 | 2191 | int i = 0, err; |
| @@ -2215,6 +2248,7 @@ static void iavf_reset_task(struct work_struct *work) · 56 unmodified lines | ||
| 2215 | 2248 | } |
| 2216 | 2249 | |
| 2217 | 2250 | pci_set_master(adapter->pdev); |
| 2251 | + pci_restore_msi_state(adapter->pdev); | |
| 2218 | 2252 | |
| 2219 | 2253 | if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) { |
| 2220 | 2254 | dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n", |
| @@ -2233,6 +2267,7 @@ continue_reset: · 12 unmodified lines | ||
| 2233 | 2267 | (adapter->state == __IAVF_RESETTING)); |
| 2234 | 2268 | |
| 2235 | 2269 | if (running) { |
| 2270 | + netdev->flags &= ~IFF_UP; | |
| 2236 | 2271 | netif_carrier_off(netdev); |
| 2237 | 2272 | netif_tx_stop_all_queues(netdev); |
| 2238 | 2273 | adapter->link_up = false; |
| @@ -2292,11 +2327,6 @@ continue_reset: · 53 unmodified lines | ||
| 2292 | 2327 | list_for_each_entry(f, &adapter->mac_filter_list, list) { |
| 2293 | 2328 | f->add = true; |
| 2294 | 2329 | } |
| 2295 | − /* re-add all VLAN filters */ | |
| 2296 | − list_for_each_entry(vlf, &adapter->vlan_filter_list, list) { | |
| 2297 | − vlf->add = true; | |
| 2298 | − } | |
| 2299 | − | |
| 2300 | 2330 | spin_unlock_bh(&adapter->mac_vlan_list_lock); |
| 2301 | 2331 | |
| 2302 | 2332 | /* check if TCs are running and re-add all cloud filters */ |
| @@ -2310,7 +2340,6 @@ continue_reset: · 7 unmodified lines | ||
| 2310 | 2340 | spin_unlock_bh(&adapter->cloud_filter_list_lock); |
| 2311 | 2341 | |
| 2312 | 2342 | adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER; |
| 2313 | − adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER; | |
| 2314 | 2343 | adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER; |
| 2315 | 2344 | iavf_misc_irq_enable(adapter); |
| 2316 | 2345 | |
| @@ -2344,7 +2373,7 @@ continue_reset: · 27 unmodified lines | ||
| 2344 | 2373 | * to __IAVF_RUNNING |
| 2345 | 2374 | */ |
| 2346 | 2375 | iavf_up_complete(adapter); |
| 2347 | − | |
| 2376 | + netdev->flags |= IFF_UP; | |
| 2348 | 2377 | iavf_irq_enable(adapter, true); |
| 2349 | 2378 | } else { |
| 2350 | 2379 | iavf_change_state(adapter, __IAVF_DOWN); |
| @@ -2357,8 +2386,10 @@ continue_reset: · 6 unmodified lines | ||
| 2357 | 2386 | reset_err: |
| 2358 | 2387 | mutex_unlock(&adapter->client_lock); |
| 2359 | 2388 | mutex_unlock(&adapter->crit_lock); |
| 2360 | − if (running) | |
| 2389 | + if (running) { | |
| 2361 | 2390 | iavf_change_state(adapter, __IAVF_RUNNING); |
| 2391 | + netdev->flags |= IFF_UP; | |
| 2392 | + } | |
| 2362 | 2393 | dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); |
| 2363 | 2394 | iavf_close(netdev); |
| 2364 | 2395 | } |
| @@ -2410,7 +2441,7 @@ static void iavf_adminq_task(struct work_struct *work) · 45 unmodified lines | ||
| 2410 | 2441 | |
| 2411 | 2442 | /* check for error indications */ |
| 2412 | 2443 | val = rd32(hw, hw->aq.arq.len); |
| 2413 | − if (val == 0xdeadbeef) /* indicates device in reset */ | |
| 2444 | + if (val == 0xdeadbeef || val == 0xffffffff) /* device in reset */ | |
| 2414 | 2445 | goto freedom; |
| 2415 | 2446 | oldval = val; |
| 2416 | 2447 | if (val & IAVF_VF_ARQLEN1_ARQVFE_MASK) { |
| @@ -3095,8 +3126,10 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, · 678 unmodified lines | ||
| 3095 | 3126 | return -ENOMEM; |
| 3096 | 3127 | |
| 3097 | 3128 | while (!mutex_trylock(&adapter->crit_lock)) { |
| 3098 | − if (--count == 0) | |
| 3099 | − goto err; | |
| 3129 | + if (--count == 0) { | |
| 3130 | + kfree(filter); | |
| 3131 | + return err; | |
| 3132 | + } | |
| 3100 | 3133 | udelay(1); |
| 3101 | 3134 | } |
| 3102 | 3135 | |
| @@ -3107,11 +3140,11 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, · 4 unmodified lines | ||
| 3107 | 3140 | /* start out with flow type and eth type IPv4 to begin with */ |
| 3108 | 3141 | filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW; |
| 3109 | 3142 | err = iavf_parse_cls_flower(adapter, cls_flower, filter); |
| 3110 | − if (err < 0) | |
| 3143 | + if (err) | |
| 3111 | 3144 | goto err; |
| 3112 | 3145 | |
| 3113 | 3146 | err = iavf_handle_tclass(adapter, tc, filter); |
| 3114 | − if (err < 0) | |
| 3147 | + if (err) | |
| 3115 | 3148 | goto err; |
| 3116 | 3149 | |
| 3117 | 3150 | /* add filter to the list */ |
| @@ -3308,6 +3341,9 @@ static int iavf_open(struct net_device *netdev) · 190 unmodified lines | ||
| 3308 | 3341 | |
| 3309 | 3342 | spin_unlock_bh(&adapter->mac_vlan_list_lock); |
| 3310 | 3343 | |
| 3344 | + /* Restore VLAN filters that were removed with IFF_DOWN */ | |
| 3345 | + iavf_restore_filters(adapter); | |
| 3346 | + | |
| 3311 | 3347 | iavf_configure(adapter); |
| 3312 | 3348 | |
| 3313 | 3349 | iavf_up_complete(adapter); |
| @@ -3415,11 +3451,16 @@ static int iavf_set_features(struct net_device *netdev, · 101 unmodified lines | ||
| 3415 | 3451 | { |
| 3416 | 3452 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 3417 | 3453 | |
| 3418 | − /* Don't allow changing VLAN_RX flag when adapter is not capable | |
| 3419 | − * of VLAN offload | |
| 3454 | + /* Don't allow enabling VLAN features when adapter is not capable | |
| 3455 | + * of VLAN offload/filtering | |
| 3420 | 3456 | */ |
| 3421 | 3457 | if (!VLAN_ALLOWED(adapter)) { |
| 3422 | − if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX) | |
| 3458 | + netdev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_RX | | |
| 3459 | + NETIF_F_HW_VLAN_CTAG_TX | | |
| 3460 | + NETIF_F_HW_VLAN_CTAG_FILTER); | |
| 3461 | + if (features & (NETIF_F_HW_VLAN_CTAG_RX | | |
| 3462 | + NETIF_F_HW_VLAN_CTAG_TX | | |
| 3463 | + NETIF_F_HW_VLAN_CTAG_FILTER)) | |
| 3423 | 3464 | return -EINVAL; |
| 3424 | 3465 | } else if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX) { |
| 3425 | 3466 | if (features & NETIF_F_HW_VLAN_CTAG_RX) |
| @@ -3503,7 +3544,8 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev, · 77 unmodified lines | ||
| 3503 | 3544 | { |
| 3504 | 3545 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 3505 | 3546 | |
| 3506 | − if (!(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) | |
| 3547 | + if (adapter->vf_res && | |
| 3548 | + !(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) | |
| 3507 | 3549 | features &= ~(NETIF_F_HW_VLAN_CTAG_TX | |
| 3508 | 3550 | NETIF_F_HW_VLAN_CTAG_RX | |
| 3509 | 3551 | NETIF_F_HW_VLAN_CTAG_FILTER); |
| @@ -607,7 +607,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter) · 606 unmodified lines | ||
| 607 | 607 | if (f->add) |
| 608 | 608 | count++; |
| 609 | 609 | } |
| 610 | − if (!count) { | |
| 610 | + if (!count || !VLAN_ALLOWED(adapter)) { | |
| 611 | 611 | adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER; |
| 612 | 612 | spin_unlock_bh(&adapter->mac_vlan_list_lock); |
| 613 | 613 | return; |
| @@ -673,9 +673,19 @@ void iavf_del_vlans(struct iavf_adapter *adapter) · 59 unmodified lines | ||
| 673 | 673 | |
| 674 | 674 | spin_lock_bh(&adapter->mac_vlan_list_lock); |
| 675 | 675 | |
| 676 | − list_for_each_entry(f, &adapter->vlan_filter_list, list) { | |
| 677 | − if (f->remove) | |
| 676 | + list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { | |
| 677 | + /* since VLAN capabilities are not allowed, we dont want to send | |
| 678 | + * a VLAN delete request because it will most likely fail and | |
| 679 | + * create unnecessary errors/noise, so just free the VLAN | |
| 680 | + * filters marked for removal to enable bailing out before | |
| 681 | + * sending a virtchnl message | |
| 682 | + */ | |
| 683 | + if (f->remove && !VLAN_ALLOWED(adapter)) { | |
| 684 | + list_del(&f->list); | |
| 685 | + kfree(f); | |
| 686 | + } else if (f->remove) { | |
| 678 | 687 | count++; |
| 688 | + } | |
| 679 | 689 | } |
| 680 | 690 | if (!count) { |
| 681 | 691 | adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER; |
| @@ -784,6 +794,8 @@ void iavf_request_stats(struct iavf_adapter *adapter) · 102 unmodified lines | ||
| 784 | 794 | /* no error message, this isn't crucial */ |
| 785 | 795 | return; |
| 786 | 796 | } |
| 797 | + | |
| 798 | + adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_STATS; | |
| 787 | 799 | adapter->current_op = VIRTCHNL_OP_GET_STATS; |
| 788 | 800 | vqs.vsi_id = adapter->vsi_res->vsi_id; |
| 789 | 801 | /* queue maps are ignored for this message - only the vsi is used */ |
| @@ -1722,8 +1734,37 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 932 unmodified lines | ||
| 1722 | 1734 | } |
| 1723 | 1735 | spin_lock_bh(&adapter->mac_vlan_list_lock); |
| 1724 | 1736 | iavf_add_filter(adapter, adapter->hw.mac.addr); |
| 1737 | + | |
| 1738 | + if (VLAN_ALLOWED(adapter)) { | |
| 1739 | + if (!list_empty(&adapter->vlan_filter_list)) { | |
| 1740 | + struct iavf_vlan_filter *vlf; | |
| 1741 | + | |
| 1742 | + /* re-add all VLAN filters over virtchnl */ | |
| 1743 | + list_for_each_entry(vlf, | |
| 1744 | + &adapter->vlan_filter_list, | |
| 1745 | + list) | |
| 1746 | + vlf->add = true; | |
| 1747 | + | |
| 1748 | + adapter->aq_required |= | |
| 1749 | + IAVF_FLAG_AQ_ADD_VLAN_FILTER; | |
| 1750 | + } | |
| 1751 | + } | |
| 1752 | + | |
| 1725 | 1753 | spin_unlock_bh(&adapter->mac_vlan_list_lock); |
| 1726 | 1754 | iavf_process_config(adapter); |
| 1755 | + | |
| 1756 | + /* unlock crit_lock before acquiring rtnl_lock as other | |
| 1757 | + * processes holding rtnl_lock could be waiting for the same | |
| 1758 | + * crit_lock | |
| 1759 | + */ | |
| 1760 | + mutex_unlock(&adapter->crit_lock); | |
| 1761 | + rtnl_lock(); | |
| 1762 | + netdev_update_features(adapter->netdev); | |
| 1763 | + rtnl_unlock(); | |
| 1764 | + if (iavf_lock_timeout(&adapter->crit_lock, 10000)) | |
| 1765 | + dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", | |
| 1766 | + __FUNCTION__); | |
| 1767 | + | |
| 1727 | 1768 | } |
| 1728 | 1769 | break; |
| 1729 | 1770 | case VIRTCHNL_OP_ENABLE_QUEUES: |
| @@ -97,6 +97,9 @@ static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets) · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | new_cfg->etscfg.maxtcs = pf->hw.func_caps.common_cap.maxtc; |
| 99 | 99 | |
| 100 | + if (!bwcfg) | |
| 101 | + new_cfg->etscfg.tcbwtable[0] = 100; | |
| 102 | + | |
| 100 | 103 | if (!bwrec) |
| 101 | 104 | new_cfg->etsrec.tcbwtable[0] = 100; |
| 102 | 105 | |
| @@ -167,15 +170,18 @@ static u8 ice_dcbnl_setdcbx(struct net_device *netdev, u8 mode) · 64 unmodified lines | ||
| 167 | 170 | if (mode == pf->dcbx_cap) |
| 168 | 171 | return ICE_DCB_NO_HW_CHG; |
| 169 | 172 | |
| 170 | − pf->dcbx_cap = mode; | |
| 171 | 173 | qos_cfg = &pf->hw.port_info->qos_cfg; |
| 172 | − if (mode & DCB_CAP_DCBX_VER_CEE) { | |
| 173 | − if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP) | |
| 174 | − return ICE_DCB_NO_HW_CHG; | |
| 174 | + | |
| 175 | + /* DSCP configuration is not DCBx negotiated */ | |
| 176 | + if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP) | |
| 177 | + return ICE_DCB_NO_HW_CHG; | |
| 178 | + | |
| 179 | + pf->dcbx_cap = mode; | |
| 180 | + | |
| 181 | + if (mode & DCB_CAP_DCBX_VER_CEE) | |
| 175 | 182 | qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE; |
| 176 | − } else { | |
| 183 | + else | |
| 177 | 184 | qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE; |
| 178 | − } | |
| 179 | 185 | |
| 180 | 186 | dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode); |
| 181 | 187 | return ICE_DCB_HW_CHG_RST; |
| @@ -1268,7 +1268,7 @@ ice_fdir_write_all_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input, · 1267 unmodified lines | ||
| 1268 | 1268 | bool is_tun = tun == ICE_FD_HW_SEG_TUN; |
| 1269 | 1269 | int err; |
| 1270 | 1270 | |
| 1271 | − if (is_tun && !ice_get_open_tunnel_port(&pf->hw, &port_num)) | |
| 1271 | + if (is_tun && !ice_get_open_tunnel_port(&pf->hw, &port_num, TNL_ALL)) | |
| 1272 | 1272 | continue; |
| 1273 | 1273 | err = ice_fdir_write_fltr(pf, input, add, is_tun); |
| 1274 | 1274 | if (err) |
| @@ -1652,7 +1652,7 @@ int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd) · 377 unmodified lines | ||
| 1652 | 1652 | } |
| 1653 | 1653 | |
| 1654 | 1654 | /* return error if not an update and no available filters */ |
| 1655 | − fltrs_needed = ice_get_open_tunnel_port(hw, &tunnel_port) ? 2 : 1; | |
| 1655 | + fltrs_needed = ice_get_open_tunnel_port(hw, &tunnel_port, TNL_ALL) ? 2 : 1; | |
| 1656 | 1656 | if (!ice_fdir_find_fltr_by_idx(hw, fsp->location) && |
| 1657 | 1657 | ice_fdir_num_avail_fltr(hw, pf->vsi[vsi->idx]) < fltrs_needed) { |
| 1658 | 1658 | dev_err(dev, "Failed to add filter. The maximum number of flow director filters has been reached.\n"); |
| @@ -924,7 +924,7 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, · 923 unmodified lines | ||
| 924 | 924 | memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len); |
| 925 | 925 | loc = pkt; |
| 926 | 926 | } else { |
| 927 | − if (!ice_get_open_tunnel_port(hw, &tnl_port)) | |
| 927 | + if (!ice_get_open_tunnel_port(hw, &tnl_port, TNL_ALL)) | |
| 928 | 928 | return ICE_ERR_DOES_NOT_EXIST; |
| 929 | 929 | if (!ice_fdir_pkt[idx].tun_pkt) |
| 930 | 930 | return ICE_ERR_PARAM; |
| @@ -1899,9 +1899,11 @@ static struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld) · 1898 unmodified lines | ||
| 1899 | 1899 | * ice_get_open_tunnel_port - retrieve an open tunnel port |
| 1900 | 1900 | * @hw: pointer to the HW structure |
| 1901 | 1901 | * @port: returns open port |
| 1902 | + * @type: type of tunnel, can be TNL_LAST if it doesn't matter | |
| 1902 | 1903 | */ |
| 1903 | 1904 | bool |
| 1904 | −ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port) | |
| 1905 | +ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port, | |
| 1906 | + enum ice_tunnel_type type) | |
| 1905 | 1907 | { |
| 1906 | 1908 | bool res = false; |
| 1907 | 1909 | u16 i; |
| @@ -1909,7 +1911,8 @@ ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port) · 1 unmodified line | ||
| 1909 | 1911 | mutex_lock(&hw->tnl_lock); |
| 1910 | 1912 | |
| 1911 | 1913 | for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) |
| 1912 | − if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].port) { | |
| 1914 | + if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].port && | |
| 1915 | + (type == TNL_LAST || type == hw->tnl.tbl[i].type)) { | |
| 1913 | 1916 | *port = hw->tnl.tbl[i].port; |
| 1914 | 1917 | res = true; |
| 1915 | 1918 | break; |
| @@ -33,7 +33,8 @@ enum ice_status · 32 unmodified lines | ||
| 33 | 33 | ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, |
| 34 | 34 | unsigned long *bm, struct list_head *fv_list); |
| 35 | 35 | bool |
| 36 | −ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port); | |
| 36 | +ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port, | |
| 37 | + enum ice_tunnel_type type); | |
| 37 | 38 | int ice_udp_tunnel_set_port(struct net_device *netdev, unsigned int table, |
| 38 | 39 | unsigned int idx, struct udp_tunnel_info *ti); |
| 39 | 40 | int ice_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table, |
| @@ -89,8 +89,13 @@ static int ice_vsi_alloc_arrays(struct ice_vsi *vsi) · 88 unmodified lines | ||
| 89 | 89 | if (!vsi->rx_rings) |
| 90 | 90 | goto err_rings; |
| 91 | 91 | |
| 92 | − /* XDP will have vsi->alloc_txq Tx queues as well, so double the size */ | |
| 93 | − vsi->txq_map = devm_kcalloc(dev, (2 * vsi->alloc_txq), | |
| 92 | + /* txq_map needs to have enough space to track both Tx (stack) rings | |
| 93 | + * and XDP rings; at this point vsi->num_xdp_txq might not be set, | |
| 94 | + * so use num_possible_cpus() as we want to always provide XDP ring | |
| 95 | + * per CPU, regardless of queue count settings from user that might | |
| 96 | + * have come from ethtool's set_channels() callback; | |
| 97 | + */ | |
| 98 | + vsi->txq_map = devm_kcalloc(dev, (vsi->alloc_txq + num_possible_cpus()), | |
| 94 | 99 | sizeof(*vsi->txq_map), GFP_KERNEL); |
| 95 | 100 | |
| 96 | 101 | if (!vsi->txq_map) |
| @@ -2609,7 +2609,18 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog) · 2608 unmodified lines | ||
| 2609 | 2609 | ice_stat_str(status)); |
| 2610 | 2610 | goto clear_xdp_rings; |
| 2611 | 2611 | } |
| 2612 | − ice_vsi_assign_bpf_prog(vsi, prog); | |
| 2612 | + | |
| 2613 | + /* assign the prog only when it's not already present on VSI; | |
| 2614 | + * this flow is a subject of both ethtool -L and ndo_bpf flows; | |
| 2615 | + * VSI rebuild that happens under ethtool -L can expose us to | |
| 2616 | + * the bpf_prog refcount issues as we would be swapping same | |
| 2617 | + * bpf_prog pointers from vsi->xdp_prog and calling bpf_prog_put | |
| 2618 | + * on it as it would be treated as an 'old_prog'; for ndo_bpf | |
| 2619 | + * this is not harmful as dev_xdp_install bumps the refcount | |
| 2620 | + * before calling the op exposed by the driver; | |
| 2621 | + */ | |
| 2622 | + if (!ice_is_xdp_ena_vsi(vsi)) | |
| 2623 | + ice_vsi_assign_bpf_prog(vsi, prog); | |
| 2613 | 2624 | |
| 2614 | 2625 | return 0; |
| 2615 | 2626 | clear_xdp_rings: |
| @@ -2785,6 +2796,11 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, · 169 unmodified lines | ||
| 2785 | 2796 | if (xdp_ring_err) |
| 2786 | 2797 | NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed"); |
| 2787 | 2798 | } else { |
| 2799 | + /* safe to call even when prog == vsi->xdp_prog as | |
| 2800 | + * dev_xdp_install in net/core/dev.c incremented prog's | |
| 2801 | + * refcount so corresponding bpf_prog_put won't cause | |
| 2802 | + * underflow | |
| 2803 | + */ | |
| 2788 | 2804 | ice_vsi_assign_bpf_prog(vsi, prog); |
| 2789 | 2805 | } |
| 2790 | 2806 | |
| @@ -5865,6 +5881,9 @@ static int ice_up_complete(struct ice_vsi *vsi) · 3074 unmodified lines | ||
| 5865 | 5881 | netif_carrier_on(vsi->netdev); |
| 5866 | 5882 | } |
| 5867 | 5883 | |
| 5884 | + /* clear this now, and the first stats read will be used as baseline */ | |
| 5885 | + vsi->stat_offsets_loaded = false; | |
| 5886 | + | |
| 5868 | 5887 | ice_service_task_schedule(pf); |
| 5869 | 5888 | |
| 5870 | 5889 | return 0; |
| @@ -5911,14 +5930,15 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp, struct ice_q_stats st · 40 unmodified lines | ||
| 5911 | 5930 | /** |
| 5912 | 5931 | * ice_update_vsi_tx_ring_stats - Update VSI Tx ring stats counters |
| 5913 | 5932 | * @vsi: the VSI to be updated |
| 5933 | + * @vsi_stats: the stats struct to be updated | |
| 5914 | 5934 | * @rings: rings to work on |
| 5915 | 5935 | * @count: number of rings |
| 5916 | 5936 | */ |
| 5917 | 5937 | static void |
| 5918 | −ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings, | |
| 5919 | − u16 count) | |
| 5938 | +ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, | |
| 5939 | + struct rtnl_link_stats64 *vsi_stats, | |
| 5940 | + struct ice_tx_ring **rings, u16 count) | |
| 5920 | 5941 | { |
| 5921 | − struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats; | |
| 5922 | 5942 | u16 i; |
| 5923 | 5943 | |
| 5924 | 5944 | for (i = 0; i < count; i++) { |
| @@ -5942,15 +5962,13 @@ ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings, · 17 unmodified lines | ||
| 5942 | 5962 | */ |
| 5943 | 5963 | static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) |
| 5944 | 5964 | { |
| 5945 | − struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats; | |
| 5965 | + struct rtnl_link_stats64 *vsi_stats; | |
| 5946 | 5966 | u64 pkts, bytes; |
| 5947 | 5967 | int i; |
| 5948 | 5968 | |
| 5949 | − /* reset netdev stats */ | |
| 5950 | − vsi_stats->tx_packets = 0; | |
| 5951 | − vsi_stats->tx_bytes = 0; | |
| 5952 | − vsi_stats->rx_packets = 0; | |
| 5953 | − vsi_stats->rx_bytes = 0; | |
| 5969 | + vsi_stats = kzalloc(sizeof(*vsi_stats), GFP_ATOMIC); | |
| 5970 | + if (!vsi_stats) | |
| 5971 | + return; | |
| 5954 | 5972 | |
| 5955 | 5973 | /* reset non-netdev (extended) stats */ |
| 5956 | 5974 | vsi->tx_restart = 0; |
| @@ -5962,7 +5980,8 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) · 5 unmodified lines | ||
| 5962 | 5980 | rcu_read_lock(); |
| 5963 | 5981 | |
| 5964 | 5982 | /* update Tx rings counters */ |
| 5965 | − ice_update_vsi_tx_ring_stats(vsi, vsi->tx_rings, vsi->num_txq); | |
| 5983 | + ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->tx_rings, | |
| 5984 | + vsi->num_txq); | |
| 5966 | 5985 | |
| 5967 | 5986 | /* update Rx rings counters */ |
| 5968 | 5987 | ice_for_each_rxq(vsi, i) { |
| @@ -5977,10 +5996,17 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) · 8 unmodified lines | ||
| 5977 | 5996 | |
| 5978 | 5997 | /* update XDP Tx rings counters */ |
| 5979 | 5998 | if (ice_is_xdp_ena_vsi(vsi)) |
| 5980 | − ice_update_vsi_tx_ring_stats(vsi, vsi->xdp_rings, | |
| 5999 | + ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->xdp_rings, | |
| 5981 | 6000 | vsi->num_xdp_txq); |
| 5982 | 6001 | |
| 5983 | 6002 | rcu_read_unlock(); |
| 6003 | + | |
| 6004 | + vsi->net_stats.tx_packets = vsi_stats->tx_packets; | |
| 6005 | + vsi->net_stats.tx_bytes = vsi_stats->tx_bytes; | |
| 6006 | + vsi->net_stats.rx_packets = vsi_stats->rx_packets; | |
| 6007 | + vsi->net_stats.rx_bytes = vsi_stats->rx_bytes; | |
| 6008 | + | |
| 6009 | + kfree(vsi_stats); | |
| 5984 | 6010 | } |
| 5985 | 6011 | |
| 5986 | 6012 | /** |
| @@ -3796,10 +3796,13 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { · 3795 unmodified lines | ||
| 3796 | 3796 | * ice_find_recp - find a recipe |
| 3797 | 3797 | * @hw: pointer to the hardware structure |
| 3798 | 3798 | * @lkup_exts: extension sequence to match |
| 3799 | + * @tun_type: type of recipe tunnel | |
| 3799 | 3800 | * |
| 3800 | 3801 | * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found. |
| 3801 | 3802 | */ |
| 3802 | −static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts) | |
| 3803 | +static u16 | |
| 3804 | +ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, | |
| 3805 | + enum ice_sw_tunnel_type tun_type) | |
| 3803 | 3806 | { |
| 3804 | 3807 | bool refresh_required = true; |
| 3805 | 3808 | struct ice_sw_recipe *recp; |
| @@ -3860,8 +3863,9 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts) · 54 unmodified lines | ||
| 3860 | 3863 | } |
| 3861 | 3864 | /* If for "i"th recipe the found was never set to false |
| 3862 | 3865 | * then it means we found our match |
| 3866 | + * Also tun type of recipe needs to be checked | |
| 3863 | 3867 | */ |
| 3864 | − if (found) | |
| 3868 | + if (found && recp[i].tun_type == tun_type) | |
| 3865 | 3869 | return i; /* Return the recipe ID */ |
| 3866 | 3870 | } |
| 3867 | 3871 | } |
| @@ -4651,11 +4655,12 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, · 783 unmodified lines | ||
| 4651 | 4655 | } |
| 4652 | 4656 | |
| 4653 | 4657 | /* Look for a recipe which matches our requested fv / mask list */ |
| 4654 | − *rid = ice_find_recp(hw, lkup_exts); | |
| 4658 | + *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type); | |
| 4655 | 4659 | if (*rid < ICE_MAX_NUM_RECIPES) |
| 4656 | 4660 | /* Success if found a recipe that match the existing criteria */ |
| 4657 | 4661 | goto err_unroll; |
| 4658 | 4662 | |
| 4663 | + rm->tun_type = rinfo->tun_type; | |
| 4659 | 4664 | /* Recipe we need does not exist, add a recipe */ |
| 4660 | 4665 | status = ice_add_sw_recipe(hw, rm, profiles); |
| 4661 | 4666 | if (status) |
| @@ -4958,11 +4963,13 @@ ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type, · 296 unmodified lines | ||
| 4958 | 4963 | |
| 4959 | 4964 | switch (tun_type) { |
| 4960 | 4965 | case ICE_SW_TUN_VXLAN: |
| 4966 | + if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN)) | |
| 4967 | + return ICE_ERR_CFG; | |
| 4968 | + break; | |
| 4961 | 4969 | case ICE_SW_TUN_GENEVE: |
| 4962 | − if (!ice_get_open_tunnel_port(hw, &open_port)) | |
| 4970 | + if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE)) | |
| 4963 | 4971 | return ICE_ERR_CFG; |
| 4964 | 4972 | break; |
| 4965 | − | |
| 4966 | 4973 | default: |
| 4967 | 4974 | /* Nothing needs to be done for this tunnel type */ |
| 4968 | 4975 | return 0; |
| @@ -5555,7 +5562,7 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, · 586 unmodified lines | ||
| 5555 | 5562 | if (status) |
| 5556 | 5563 | return status; |
| 5557 | 5564 | |
| 5558 | − rid = ice_find_recp(hw, &lkup_exts); | |
| 5565 | + rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type); | |
| 5559 | 5566 | /* If did not find a recipe that match the existing criteria */ |
| 5560 | 5567 | if (rid == ICE_MAX_NUM_RECIPES) |
| 5561 | 5568 | return ICE_ERR_PARAM; |
| @@ -74,21 +74,13 @@ static enum ice_protocol_type ice_proto_type_from_ipv6(bool inner) · 73 unmodified lines | ||
| 74 | 74 | return inner ? ICE_IPV6_IL : ICE_IPV6_OFOS; |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | −static enum ice_protocol_type | |
| 78 | −ice_proto_type_from_l4_port(bool inner, u16 ip_proto) | |
| 77 | +static enum ice_protocol_type ice_proto_type_from_l4_port(u16 ip_proto) | |
| 79 | 78 | { |
| 80 | − if (inner) { | |
| 81 | − switch (ip_proto) { | |
| 82 | − case IPPROTO_UDP: | |
| 83 | − return ICE_UDP_ILOS; | |
| 84 | − } | |
| 85 | − } else { | |
| 86 | − switch (ip_proto) { | |
| 87 | − case IPPROTO_TCP: | |
| 88 | − return ICE_TCP_IL; | |
| 89 | − case IPPROTO_UDP: | |
| 90 | − return ICE_UDP_OF; | |
| 91 | − } | |
| 79 | + switch (ip_proto) { | |
| 80 | + case IPPROTO_TCP: | |
| 81 | + return ICE_TCP_IL; | |
| 82 | + case IPPROTO_UDP: | |
| 83 | + return ICE_UDP_ILOS; | |
| 92 | 84 | } |
| 93 | 85 | |
| 94 | 86 | return 0; |
| @@ -191,8 +183,9 @@ ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr, · 96 unmodified lines | ||
| 191 | 183 | i++; |
| 192 | 184 | } |
| 193 | 185 | |
| 194 | − if (flags & ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT) { | |
| 195 | − list[i].type = ice_proto_type_from_l4_port(false, hdr->l3_key.ip_proto); | |
| 186 | + if ((flags & ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT) && | |
| 187 | + hdr->l3_key.ip_proto == IPPROTO_UDP) { | |
| 188 | + list[i].type = ICE_UDP_OF; | |
| 196 | 189 | list[i].h_u.l4_hdr.dst_port = hdr->l4_key.dst_port; |
| 197 | 190 | list[i].m_u.l4_hdr.dst_port = hdr->l4_mask.dst_port; |
| 198 | 191 | i++; |
| @@ -317,7 +310,7 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags, · 118 unmodified lines | ||
| 317 | 310 | ICE_TC_FLWR_FIELD_SRC_L4_PORT)) { |
| 318 | 311 | struct ice_tc_l4_hdr *l4_key, *l4_mask; |
| 319 | 312 | |
| 320 | − list[i].type = ice_proto_type_from_l4_port(inner, headers->l3_key.ip_proto); | |
| 313 | + list[i].type = ice_proto_type_from_l4_port(headers->l3_key.ip_proto); | |
| 321 | 314 | l4_key = &headers->l4_key; |
| 322 | 315 | l4_mask = &headers->l4_mask; |
| 323 | 316 | |
| @@ -802,7 +795,8 @@ ice_parse_tunnel_attr(struct net_device *dev, struct flow_rule *rule, · 478 unmodified lines | ||
| 802 | 795 | headers->l3_mask.ttl = match.mask->ttl; |
| 803 | 796 | } |
| 804 | 797 | |
| 805 | − if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS)) { | |
| 798 | + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS) && | |
| 799 | + fltr->tunnel_type != TNL_VXLAN && fltr->tunnel_type != TNL_GENEVE) { | |
| 806 | 800 | struct flow_match_ports match; |
| 807 | 801 | |
| 808 | 802 | flow_rule_match_enc_ports(rule, &match); |
| @@ -1617,6 +1617,7 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr) · 1616 unmodified lines | ||
| 1617 | 1617 | ice_vc_set_default_allowlist(vf); |
| 1618 | 1618 | |
| 1619 | 1619 | ice_vf_fdir_exit(vf); |
| 1620 | + ice_vf_fdir_init(vf); | |
| 1620 | 1621 | /* clean VF control VSI when resetting VFs since it should be |
| 1621 | 1622 | * setup only when VF creates its first FDIR rule. |
| 1622 | 1623 | */ |
| @@ -1747,6 +1748,7 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr) · 124 unmodified lines | ||
| 1747 | 1748 | } |
| 1748 | 1749 | |
| 1749 | 1750 | ice_vf_fdir_exit(vf); |
| 1751 | + ice_vf_fdir_init(vf); | |
| 1750 | 1752 | /* clean VF control VSI when resetting VF since it should be setup |
| 1751 | 1753 | * only when VF creates its first FDIR rule. |
| 1752 | 1754 | */ |
| @@ -2021,6 +2023,10 @@ static int ice_ena_vfs(struct ice_pf *pf, u16 num_vfs) · 268 unmodified lines | ||
| 2021 | 2023 | if (ret) |
| 2022 | 2024 | goto err_unroll_sriov; |
| 2023 | 2025 | |
| 2026 | + /* rearm global interrupts */ | |
| 2027 | + if (test_and_clear_bit(ICE_OICR_INTR_DIS, pf->state)) | |
| 2028 | + ice_irq_dynamic_ena(hw, NULL, NULL); | |
| 2029 | + | |
| 2024 | 2030 | return 0; |
| 2025 | 2031 | |
| 2026 | 2032 | err_unroll_sriov: |
| @@ -383,6 +383,7 @@ bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring, u16 count) · 382 unmodified lines | ||
| 383 | 383 | while (i--) { |
| 384 | 384 | dma = xsk_buff_xdp_get_dma(*xdp); |
| 385 | 385 | rx_desc->read.pkt_addr = cpu_to_le64(dma); |
| 386 | + rx_desc->wb.status_error0 = 0; | |
| 386 | 387 | |
| 387 | 388 | rx_desc++; |
| 388 | 389 | xdp++; |
| @@ -8026,7 +8026,7 @@ static int igb_poll(struct napi_struct *napi, int budget) · 8025 unmodified lines | ||
| 8026 | 8026 | if (likely(napi_complete_done(napi, work_done))) |
| 8027 | 8027 | igb_ring_irq_enable(q_vector); |
| 8028 | 8028 | |
| 8029 | − return min(work_done, budget - 1); | |
| 8029 | + return work_done; | |
| 8030 | 8030 | } |
| 8031 | 8031 | |
| 8032 | 8032 | /** |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/io.h> |
| 26 | 26 | #include <linux/dma-mapping.h> |
| 27 | 27 | #include <linux/module.h> |
| 28 | +#include <linux/property.h> | |
| 28 | 29 | |
| 29 | 30 | #include <asm/checksum.h> |
| 30 | 31 | |
| @@ -239,6 +240,7 @@ ltq_etop_hw_init(struct net_device *dev) · 208 unmodified lines | ||
| 239 | 240 | { |
| 240 | 241 | struct ltq_etop_priv *priv = netdev_priv(dev); |
| 241 | 242 | int i; |
| 243 | + int err; | |
| 242 | 244 | |
| 243 | 245 | ltq_pmu_enable(PMU_PPE); |
| 244 | 246 | |
| @@ -273,7 +275,13 @@ ltq_etop_hw_init(struct net_device *dev) · 28 unmodified lines | ||
| 273 | 275 | |
| 274 | 276 | if (IS_TX(i)) { |
| 275 | 277 | ltq_dma_alloc_tx(&ch->dma); |
| 276 | − request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv); | |
| 278 | + err = request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv); | |
| 279 | + if (err) { | |
| 280 | + netdev_err(dev, | |
| 281 | + "Unable to get Tx DMA IRQ %d\n", | |
| 282 | + irq); | |
| 283 | + return err; | |
| 284 | + } | |
| 277 | 285 | } else if (IS_RX(i)) { |
| 278 | 286 | ltq_dma_alloc_rx(&ch->dma); |
| 279 | 287 | for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM; |
| @@ -281,7 +289,13 @@ ltq_etop_hw_init(struct net_device *dev) · 1 unmodified line | ||
| 281 | 289 | if (ltq_etop_alloc_skb(ch)) |
| 282 | 290 | return -ENOMEM; |
| 283 | 291 | ch->dma.desc = 0; |
| 284 | − request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv); | |
| 292 | + err = request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv); | |
| 293 | + if (err) { | |
| 294 | + netdev_err(dev, | |
| 295 | + "Unable to get Rx DMA IRQ %d\n", | |
| 296 | + irq); | |
| 297 | + return err; | |
| 298 | + } | |
| 285 | 299 | } |
| 286 | 300 | ch->dma.irq = irq; |
| 287 | 301 | } |
| @@ -726,7 +740,7 @@ static struct platform_driver ltq_mii_driver = { · 438 unmodified lines | ||
| 726 | 740 | }, |
| 727 | 741 | }; |
| 728 | 742 | |
| 729 | −int __init | |
| 743 | +static int __init | |
| 730 | 744 | init_ltq_etop(void) |
| 731 | 745 | { |
| 732 | 746 | int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe); |
| @@ -429,12 +429,14 @@ static const struct of_device_id orion_mdio_match[] = { · 428 unmodified lines | ||
| 429 | 429 | }; |
| 430 | 430 | MODULE_DEVICE_TABLE(of, orion_mdio_match); |
| 431 | 431 | |
| 432 | +#ifdef CONFIG_ACPI | |
| 432 | 433 | static const struct acpi_device_id orion_mdio_acpi_match[] = { |
| 433 | 434 | { "MRVL0100", BUS_TYPE_SMI }, |
| 434 | 435 | { "MRVL0101", BUS_TYPE_XSMI }, |
| 435 | 436 | { }, |
| 436 | 437 | }; |
| 437 | 438 | MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match); |
| 439 | +#endif | |
| 438 | 440 | |
| 439 | 441 | static struct platform_driver orion_mdio_driver = { |
| 440 | 442 | .probe = orion_mdio_probe, |
| @@ -2960,11 +2960,11 @@ static int mvpp2_rxq_init(struct mvpp2_port *port, · 2959 unmodified lines | ||
| 2960 | 2960 | mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size); |
| 2961 | 2961 | |
| 2962 | 2962 | if (priv->percpu_pools) { |
| 2963 | − err = xdp_rxq_info_reg(&rxq->xdp_rxq_short, port->dev, rxq->id, 0); | |
| 2963 | + err = xdp_rxq_info_reg(&rxq->xdp_rxq_short, port->dev, rxq->logic_rxq, 0); | |
| 2964 | 2964 | if (err < 0) |
| 2965 | 2965 | goto err_free_dma; |
| 2966 | 2966 | |
| 2967 | − err = xdp_rxq_info_reg(&rxq->xdp_rxq_long, port->dev, rxq->id, 0); | |
| 2967 | + err = xdp_rxq_info_reg(&rxq->xdp_rxq_long, port->dev, rxq->logic_rxq, 0); | |
| 2968 | 2968 | if (err < 0) |
| 2969 | 2969 | goto err_unregister_rxq_short; |
| 2970 | 2970 | |
| @@ -5017,11 +5017,13 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu) · 2046 unmodified lines | ||
| 5017 | 5017 | mtu = ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8); |
| 5018 | 5018 | } |
| 5019 | 5019 | |
| 5020 | + if (port->xdp_prog && mtu > MVPP2_MAX_RX_BUF_SIZE) { | |
| 5021 | + netdev_err(dev, "Illegal MTU value %d (> %d) for XDP mode\n", | |
| 5022 | + mtu, (int)MVPP2_MAX_RX_BUF_SIZE); | |
| 5023 | + return -EINVAL; | |
| 5024 | + } | |
| 5025 | + | |
| 5020 | 5026 | if (MVPP2_RX_PKT_SIZE(mtu) > MVPP2_BM_LONG_PKT_SIZE) { |
| 5021 | − if (port->xdp_prog) { | |
| 5022 | − netdev_err(dev, "Jumbo frames are not supported with XDP\n"); | |
| 5023 | − return -EINVAL; | |
| 5024 | − } | |
| 5025 | 5027 | if (priv->percpu_pools) { |
| 5026 | 5028 | netdev_warn(dev, "mtu %d too high, switching to shared buffers", mtu); |
| 5027 | 5029 | mvpp2_bm_switch_buffers(priv, false); |
| @@ -5307,8 +5309,8 @@ static int mvpp2_xdp_setup(struct mvpp2_port *port, struct netdev_bpf *bpf) · 279 unmodified lines | ||
| 5307 | 5309 | bool running = netif_running(port->dev); |
| 5308 | 5310 | bool reset = !prog != !port->xdp_prog; |
| 5309 | 5311 | |
| 5310 | − if (port->dev->mtu > ETH_DATA_LEN) { | |
| 5311 | − NL_SET_ERR_MSG_MOD(bpf->extack, "XDP is not supported with jumbo frames enabled"); | |
| 5312 | + if (port->dev->mtu > MVPP2_MAX_RX_BUF_SIZE) { | |
| 5313 | + NL_SET_ERR_MSG_MOD(bpf->extack, "MTU too large for XDP"); | |
| 5312 | 5314 | return -EOPNOTSUPP; |
| 5313 | 5315 | } |
| 5314 | 5316 | |
| @@ -7456,7 +7458,7 @@ static int mvpp2_probe(struct platform_device *pdev) · 2141 unmodified lines | ||
| 7456 | 7458 | |
| 7457 | 7459 | shared = num_present_cpus() - priv->nthreads; |
| 7458 | 7460 | if (shared > 0) |
| 7459 | − bitmap_fill(&priv->lock_map, | |
| 7461 | + bitmap_set(&priv->lock_map, 0, | |
| 7460 | 7462 | min_t(int, shared, MVPP2_MAX_THREADS)); |
| 7461 | 7463 | |
| 7462 | 7464 | for (i = 0; i < MVPP2_MAX_THREADS; i++) { |
| @@ -2341,7 +2341,7 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw, · 2340 unmodified lines | ||
| 2341 | 2341 | goto free_regions; |
| 2342 | 2342 | break; |
| 2343 | 2343 | default: |
| 2344 | − return err; | |
| 2344 | + goto free_regions; | |
| 2345 | 2345 | } |
| 2346 | 2346 | |
| 2347 | 2347 | mw->mbox_wq = alloc_workqueue(name, |
| @@ -236,10 +236,11 @@ static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp, · 235 unmodified lines | ||
| 236 | 236 | u64 lmt_addr, val, tbl_base; |
| 237 | 237 | int pf, vf, num_vfs, hw_vfs; |
| 238 | 238 | void __iomem *lmt_map_base; |
| 239 | − int index = 0, off = 0; | |
| 240 | − int bytes_not_copied; | |
| 241 | 239 | int buf_size = 10240; |
| 240 | + size_t off = 0; | |
| 241 | + int index = 0; | |
| 242 | 242 | char *buf; |
| 243 | + int ret; | |
| 243 | 244 | |
| 244 | 245 | /* don't allow partial reads */ |
| 245 | 246 | if (*ppos != 0) |
| @@ -303,15 +304,17 @@ static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp, · 57 unmodified lines | ||
| 303 | 304 | } |
| 304 | 305 | off += scnprintf(&buf[off], buf_size - 1 - off, "\n"); |
| 305 | 306 | |
| 306 | − bytes_not_copied = copy_to_user(buffer, buf, off); | |
| 307 | + ret = min(off, count); | |
| 308 | + if (copy_to_user(buffer, buf, ret)) | |
| 309 | + ret = -EFAULT; | |
| 307 | 310 | kfree(buf); |
| 308 | 311 | |
| 309 | 312 | iounmap(lmt_map_base); |
| 310 | − if (bytes_not_copied) | |
| 311 | − return -EFAULT; | |
| 313 | + if (ret < 0) | |
| 314 | + return ret; | |
| 312 | 315 | |
| 313 | − *ppos = off; | |
| 314 | − return off; | |
| 316 | + *ppos = ret; | |
| 317 | + return ret; | |
| 315 | 318 | } |
| 316 | 319 | |
| 317 | 320 | RVU_DEBUG_FOPS(lmtst_map_table, lmtst_map_table_display, NULL); |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | ||
| 5 | 5 | * |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | +#include <linux/module.h> | |
| 9 | + | |
| 8 | 10 | #include "otx2_common.h" |
| 9 | 11 | #include "otx2_ptp.h" |
| 10 | 12 | |
| @@ -497,8 +497,8 @@ int prestera_bridge_port_join(struct net_device *br_dev, · 496 unmodified lines | ||
| 497 | 497 | |
| 498 | 498 | br_port = prestera_bridge_port_add(bridge, port->dev); |
| 499 | 499 | if (IS_ERR(br_port)) { |
| 500 | − err = PTR_ERR(br_port); | |
| 501 | − goto err_brport_create; | |
| 500 | + prestera_bridge_put(bridge); | |
| 501 | + return PTR_ERR(br_port); | |
| 502 | 502 | } |
| 503 | 503 | |
| 504 | 504 | err = switchdev_bridge_port_offload(br_port->dev, port->dev, NULL, |
| @@ -519,8 +519,6 @@ err_port_join: · 14 unmodified lines | ||
| 519 | 519 | switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL); |
| 520 | 520 | err_switchdev_offload: |
| 521 | 521 | prestera_bridge_port_put(br_port); |
| 522 | −err_brport_create: | |
| 523 | − prestera_bridge_put(bridge); | |
| 524 | 522 | return err; |
| 525 | 523 | } |
| 526 | 524 | |
| @@ -1124,7 +1122,7 @@ static int prestera_switchdev_blk_event(struct notifier_block *unused, · 597 unmodified lines | ||
| 1124 | 1122 | prestera_port_obj_attr_set); |
| 1125 | 1123 | break; |
| 1126 | 1124 | default: |
| 1127 | − err = -EOPNOTSUPP; | |
| 1125 | + return NOTIFY_DONE; | |
| 1128 | 1126 | } |
| 1129 | 1127 | |
| 1130 | 1128 | return notifier_from_errno(err); |
| @@ -670,7 +670,7 @@ void __init mlx4_en_init_ptys2ethtool_map(void) · 669 unmodified lines | ||
| 670 | 670 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_T, SPEED_1000, |
| 671 | 671 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT); |
| 672 | 672 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_CX_SGMII, SPEED_1000, |
| 673 | − ETHTOOL_LINK_MODE_1000baseKX_Full_BIT); | |
| 673 | + ETHTOOL_LINK_MODE_1000baseX_Full_BIT); | |
| 674 | 674 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_KX, SPEED_1000, |
| 675 | 675 | ETHTOOL_LINK_MODE_1000baseKX_Full_BIT); |
| 676 | 676 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_T, SPEED_10000, |
| @@ -682,9 +682,9 @@ void __init mlx4_en_init_ptys2ethtool_map(void) · 5 unmodified lines | ||
| 682 | 682 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KR, SPEED_10000, |
| 683 | 683 | ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); |
| 684 | 684 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CR, SPEED_10000, |
| 685 | − ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); | |
| 685 | + ETHTOOL_LINK_MODE_10000baseCR_Full_BIT); | |
| 686 | 686 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_SR, SPEED_10000, |
| 687 | − ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); | |
| 687 | + ETHTOOL_LINK_MODE_10000baseSR_Full_BIT); | |
| 688 | 688 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_20GBASE_KR2, SPEED_20000, |
| 689 | 689 | ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, |
| 690 | 690 | ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT); |
| @@ -2286,9 +2286,14 @@ int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv, · 2285 unmodified lines | ||
| 2286 | 2286 | bool carry_xdp_prog) |
| 2287 | 2287 | { |
| 2288 | 2288 | struct bpf_prog *xdp_prog; |
| 2289 | − int i, t; | |
| 2289 | + int i, t, ret; | |
| 2290 | 2290 | |
| 2291 | − mlx4_en_copy_priv(tmp, priv, prof); | |
| 2291 | + ret = mlx4_en_copy_priv(tmp, priv, prof); | |
| 2292 | + if (ret) { | |
| 2293 | + en_warn(priv, "%s: mlx4_en_copy_priv() failed, return\n", | |
| 2294 | + __func__); | |
| 2295 | + return ret; | |
| 2296 | + } | |
| 2292 | 2297 | |
| 2293 | 2298 | if (mlx4_en_alloc_resources(tmp)) { |
| 2294 | 2299 | en_warn(priv, |
| @@ -339,6 +339,9 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, · 338 unmodified lines | ||
| 339 | 339 | case MLX5_CMD_OP_PAGE_FAULT_RESUME: |
| 340 | 340 | case MLX5_CMD_OP_QUERY_ESW_FUNCTIONS: |
| 341 | 341 | case MLX5_CMD_OP_DEALLOC_SF: |
| 342 | + case MLX5_CMD_OP_DESTROY_UCTX: | |
| 343 | + case MLX5_CMD_OP_DESTROY_UMEM: | |
| 344 | + case MLX5_CMD_OP_MODIFY_RQT: | |
| 342 | 345 | return MLX5_CMD_STAT_OK; |
| 343 | 346 | |
| 344 | 347 | case MLX5_CMD_OP_QUERY_HCA_CAP: |
| @@ -444,7 +447,6 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, · 99 unmodified lines | ||
| 444 | 447 | case MLX5_CMD_OP_MODIFY_TIS: |
| 445 | 448 | case MLX5_CMD_OP_QUERY_TIS: |
| 446 | 449 | case MLX5_CMD_OP_CREATE_RQT: |
| 447 | − case MLX5_CMD_OP_MODIFY_RQT: | |
| 448 | 450 | case MLX5_CMD_OP_QUERY_RQT: |
| 449 | 451 | |
| 450 | 452 | case MLX5_CMD_OP_CREATE_FLOW_TABLE: |
| @@ -464,9 +466,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, · 13 unmodified lines | ||
| 464 | 466 | case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: |
| 465 | 467 | case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: |
| 466 | 468 | case MLX5_CMD_OP_CREATE_UCTX: |
| 467 | − case MLX5_CMD_OP_DESTROY_UCTX: | |
| 468 | 469 | case MLX5_CMD_OP_CREATE_UMEM: |
| 469 | − case MLX5_CMD_OP_DESTROY_UMEM: | |
| 470 | 470 | case MLX5_CMD_OP_ALLOC_MEMIC: |
| 471 | 471 | case MLX5_CMD_OP_MODIFY_XRQ: |
| 472 | 472 | case MLX5_CMD_OP_RELEASE_XRQ_ERROR: |
| @@ -164,13 +164,14 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) · 163 unmodified lines | ||
| 164 | 164 | MLX5_SET(destroy_cq_in, in, cqn, cq->cqn); |
| 165 | 165 | MLX5_SET(destroy_cq_in, in, uid, cq->uid); |
| 166 | 166 | err = mlx5_cmd_exec_in(dev, destroy_cq, in); |
| 167 | + if (err) | |
| 168 | + return err; | |
| 167 | 169 | |
| 168 | 170 | synchronize_irq(cq->irqn); |
| 169 | − | |
| 170 | 171 | mlx5_cq_put(cq); |
| 171 | 172 | wait_for_completion(&cq->free); |
| 172 | 173 | |
| 173 | − return err; | |
| 174 | + return 0; | |
| 174 | 175 | } |
| 175 | 176 | EXPORT_SYMBOL(mlx5_core_destroy_cq); |
| 176 | 177 | |
| @@ -507,6 +507,8 @@ void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) · 506 unmodified lines | ||
| 507 | 507 | if (!mlx5_debugfs_root) |
| 508 | 508 | return; |
| 509 | 509 | |
| 510 | − if (cq->dbg) | |
| 510 | + if (cq->dbg) { | |
| 511 | 511 | rem_res_tree(cq->dbg); |
| 512 | + cq->dbg = NULL; | |
| 513 | + } | |
| 512 | 514 | } |
| @@ -13,6 +13,9 @@ struct mlx5e_rx_res { · 12 unmodified lines | ||
| 13 | 13 | unsigned int max_nch; |
| 14 | 14 | u32 drop_rqn; |
| 15 | 15 | |
| 16 | + struct mlx5e_packet_merge_param pkt_merge_param; | |
| 17 | + struct rw_semaphore pkt_merge_param_sem; | |
| 18 | + | |
| 16 | 19 | struct mlx5e_rss *rss[MLX5E_MAX_NUM_RSS]; |
| 17 | 20 | bool rss_active; |
| 18 | 21 | u32 rss_rqns[MLX5E_INDIR_RQT_SIZE]; |
| @@ -392,6 +395,7 @@ static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res) · 373 unmodified lines | ||
| 392 | 395 | if (err) |
| 393 | 396 | goto out; |
| 394 | 397 | |
| 398 | + /* Separated from the channels RQs, does not share pkt_merge state with them */ | |
| 395 | 399 | mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, |
| 396 | 400 | mlx5e_rqt_get_rqtn(&res->ptp.rqt), |
| 397 | 401 | inner_ft_support); |
| @@ -447,6 +451,9 @@ int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev, · 49 unmodified lines | ||
| 447 | 451 | res->max_nch = max_nch; |
| 448 | 452 | res->drop_rqn = drop_rqn; |
| 449 | 453 | |
| 454 | + res->pkt_merge_param = *init_pkt_merge_param; | |
| 455 | + init_rwsem(&res->pkt_merge_param_sem); | |
| 456 | + | |
| 450 | 457 | err = mlx5e_rx_res_rss_init_def(res, init_pkt_merge_param, init_nch); |
| 451 | 458 | if (err) |
| 452 | 459 | goto err_out; |
| @@ -513,7 +520,7 @@ u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res) · 60 unmodified lines | ||
| 513 | 520 | return mlx5e_tir_get_tirn(&res->ptp.tir); |
| 514 | 521 | } |
| 515 | 522 | |
| 516 | −u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix) | |
| 523 | +static u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix) | |
| 517 | 524 | { |
| 518 | 525 | return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt); |
| 519 | 526 | } |
| @@ -656,6 +663,9 @@ int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res, · 136 unmodified lines | ||
| 656 | 663 | if (!builder) |
| 657 | 664 | return -ENOMEM; |
| 658 | 665 | |
| 666 | + down_write(&res->pkt_merge_param_sem); | |
| 667 | + res->pkt_merge_param = *pkt_merge_param; | |
| 668 | + | |
| 659 | 669 | mlx5e_tir_builder_build_packet_merge(builder, pkt_merge_param); |
| 660 | 670 | |
| 661 | 671 | final_err = 0; |
| @@ -681,6 +691,7 @@ int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res, · 19 unmodified lines | ||
| 681 | 691 | } |
| 682 | 692 | } |
| 683 | 693 | |
| 694 | + up_write(&res->pkt_merge_param_sem); | |
| 684 | 695 | mlx5e_tir_builder_free(builder); |
| 685 | 696 | return final_err; |
| 686 | 697 | } |
| @@ -689,3 +700,31 @@ struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res * · 2 unmodified lines | ||
| 689 | 700 | { |
| 690 | 701 | return mlx5e_rss_get_hash(res->rss[0]); |
| 691 | 702 | } |
| 703 | + | |
| 704 | +int mlx5e_rx_res_tls_tir_create(struct mlx5e_rx_res *res, unsigned int rxq, | |
| 705 | + struct mlx5e_tir *tir) | |
| 706 | +{ | |
| 707 | + bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT; | |
| 708 | + struct mlx5e_tir_builder *builder; | |
| 709 | + u32 rqtn; | |
| 710 | + int err; | |
| 711 | + | |
| 712 | + builder = mlx5e_tir_builder_alloc(false); | |
| 713 | + if (!builder) | |
| 714 | + return -ENOMEM; | |
| 715 | + | |
| 716 | + rqtn = mlx5e_rx_res_get_rqtn_direct(res, rxq); | |
| 717 | + | |
| 718 | + mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, rqtn, | |
| 719 | + inner_ft_support); | |
| 720 | + mlx5e_tir_builder_build_direct(builder); | |
| 721 | + mlx5e_tir_builder_build_tls(builder); | |
| 722 | + down_read(&res->pkt_merge_param_sem); | |
| 723 | + mlx5e_tir_builder_build_packet_merge(builder, &res->pkt_merge_param); | |
| 724 | + err = mlx5e_tir_init(tir, builder, res->mdev, false); | |
| 725 | + up_read(&res->pkt_merge_param_sem); | |
| 726 | + | |
| 727 | + mlx5e_tir_builder_free(builder); | |
| 728 | + | |
| 729 | + return err; | |
| 730 | +} | |
| @@ -37,9 +37,6 @@ u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types · 36 unmodified lines | ||
| 37 | 37 | u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt); |
| 38 | 38 | u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res); |
| 39 | 39 | |
| 40 | −/* RQTN getters for modules that create their own TIRs */ | |
| 41 | −u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix); | |
| 42 | − | |
| 43 | 40 | /* Activate/deactivate API */ |
| 44 | 41 | void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs); |
| 45 | 42 | void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res); |
| @@ -69,4 +66,7 @@ struct mlx5e_rss *mlx5e_rx_res_rss_get(struct mlx5e_rx_res *res, u32 rss_idx); · 23 unmodified lines | ||
| 69 | 66 | /* Workaround for hairpin */ |
| 70 | 67 | struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res); |
| 71 | 68 | |
| 69 | +/* Accel TIRs */ | |
| 70 | +int mlx5e_rx_res_tls_tir_create(struct mlx5e_rx_res *res, unsigned int rxq, | |
| 71 | + struct mlx5e_tir *tir); | |
| 72 | 72 | #endif /* __MLX5_EN_RX_RES_H__ */ |
| @@ -1356,9 +1356,13 @@ mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv, · 1355 unmodified lines | ||
| 1356 | 1356 | int |
| 1357 | 1357 | mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, |
| 1358 | 1358 | struct mlx5_flow_attr *attr, |
| 1359 | + struct mlx5e_tc_mod_hdr_acts *mod_acts, | |
| 1359 | 1360 | const struct flow_action_entry *act, |
| 1360 | 1361 | struct netlink_ext_ack *extack) |
| 1361 | 1362 | { |
| 1363 | + bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR; | |
| 1364 | + int err; | |
| 1365 | + | |
| 1362 | 1366 | if (!priv) { |
| 1363 | 1367 | NL_SET_ERR_MSG_MOD(extack, |
| 1364 | 1368 | "offload of ct action isn't available"); |
| @@ -1369,6 +1373,17 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, · 4 unmodified lines | ||
| 1369 | 1373 | attr->ct_attr.ct_action = act->ct.action; |
| 1370 | 1374 | attr->ct_attr.nf_ft = act->ct.flow_table; |
| 1371 | 1375 | |
| 1376 | + if (!clear_action) | |
| 1377 | + goto out; | |
| 1378 | + | |
| 1379 | + err = mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0); | |
| 1380 | + if (err) { | |
| 1381 | + NL_SET_ERR_MSG_MOD(extack, "Failed to set registers for ct clear"); | |
| 1382 | + return err; | |
| 1383 | + } | |
| 1384 | + attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; | |
| 1385 | + | |
| 1386 | +out: | |
| 1372 | 1387 | return 0; |
| 1373 | 1388 | } |
| 1374 | 1389 | |
| @@ -1898,23 +1913,16 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv, · 523 unmodified lines | ||
| 1898 | 1913 | |
| 1899 | 1914 | memcpy(pre_ct_attr, attr, attr_sz); |
| 1900 | 1915 | |
| 1901 | − err = mlx5_tc_ct_entry_set_registers(ct_priv, mod_acts, 0, 0, 0, 0); | |
| 1902 | − if (err) { | |
| 1903 | − ct_dbg("Failed to set register for ct clear"); | |
| 1904 | − goto err_set_registers; | |
| 1905 | − } | |
| 1906 | − | |
| 1907 | 1916 | mod_hdr = mlx5_modify_header_alloc(priv->mdev, ct_priv->ns_type, |
| 1908 | 1917 | mod_acts->num_actions, |
| 1909 | 1918 | mod_acts->actions); |
| 1910 | 1919 | if (IS_ERR(mod_hdr)) { |
| 1911 | 1920 | err = PTR_ERR(mod_hdr); |
| 1912 | 1921 | ct_dbg("Failed to add create ct clear mod hdr"); |
| 1913 | − goto err_set_registers; | |
| 1922 | + goto err_mod_hdr; | |
| 1914 | 1923 | } |
| 1915 | 1924 | |
| 1916 | 1925 | pre_ct_attr->modify_hdr = mod_hdr; |
| 1917 | − pre_ct_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; | |
| 1918 | 1926 | |
| 1919 | 1927 | rule = mlx5_tc_rule_insert(priv, orig_spec, pre_ct_attr); |
| 1920 | 1928 | if (IS_ERR(rule)) { |
| @@ -1930,7 +1938,7 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv, · 9 unmodified lines | ||
| 1930 | 1938 | |
| 1931 | 1939 | err_insert: |
| 1932 | 1940 | mlx5_modify_header_dealloc(priv->mdev, mod_hdr); |
| 1933 | −err_set_registers: | |
| 1941 | +err_mod_hdr: | |
| 1934 | 1942 | netdev_warn(priv->netdev, |
| 1935 | 1943 | "Failed to offload ct clear flow, err %d\n", err); |
| 1936 | 1944 | kfree(pre_ct_attr); |
| @@ -110,6 +110,7 @@ int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec); · 109 unmodified lines | ||
| 110 | 110 | int |
| 111 | 111 | mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, |
| 112 | 112 | struct mlx5_flow_attr *attr, |
| 113 | + struct mlx5e_tc_mod_hdr_acts *mod_acts, | |
| 113 | 114 | const struct flow_action_entry *act, |
| 114 | 115 | struct netlink_ext_ack *extack); |
| 115 | 116 | |
| @@ -172,6 +173,7 @@ mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec) · 56 unmodified lines | ||
| 172 | 173 | static inline int |
| 173 | 174 | mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, |
| 174 | 175 | struct mlx5_flow_attr *attr, |
| 176 | + struct mlx5e_tc_mod_hdr_acts *mod_acts, | |
| 175 | 177 | const struct flow_action_entry *act, |
| 176 | 178 | struct netlink_ext_ack *extack) |
| 177 | 179 | { |
| @@ -102,6 +102,7 @@ struct mlx5e_tc_flow { · 101 unmodified lines | ||
| 102 | 102 | refcount_t refcnt; |
| 103 | 103 | struct rcu_head rcu_head; |
| 104 | 104 | struct completion init_done; |
| 105 | + struct completion del_hw_done; | |
| 105 | 106 | int tunnel_id; /* the mapped tunnel id of this flow */ |
| 106 | 107 | struct mlx5_flow_attr *attr; |
| 107 | 108 | }; |
| @@ -245,8 +245,14 @@ static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow, · 244 unmodified lines | ||
| 245 | 245 | struct list_head *flow_list, |
| 246 | 246 | int index) |
| 247 | 247 | { |
| 248 | − if (IS_ERR(mlx5e_flow_get(flow))) | |
| 248 | + if (IS_ERR(mlx5e_flow_get(flow))) { | |
| 249 | + /* Flow is being deleted concurrently. Wait for it to be | |
| 250 | + * unoffloaded from hardware, otherwise deleting encap will | |
| 251 | + * fail. | |
| 252 | + */ | |
| 253 | + wait_for_completion(&flow->del_hw_done); | |
| 249 | 254 | return; |
| 255 | + } | |
| 250 | 256 | wait_for_completion(&flow->init_done); |
| 251 | 257 | |
| 252 | 258 | flow->tmp_entry_index = index; |
| @@ -191,7 +191,7 @@ static void mlx5e_ipsec_set_swp(struct sk_buff *skb, · 190 unmodified lines | ||
| 191 | 191 | eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2; |
| 192 | 192 | eseg->swp_inner_l4_offset = |
| 193 | 193 | (skb->csum_start + skb->head - skb->data) / 2; |
| 194 | − if (skb->protocol == htons(ETH_P_IPV6)) | |
| 194 | + if (inner_ip_hdr(skb)->version == 6) | |
| 195 | 195 | eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6; |
| 196 | 196 | break; |
| 197 | 197 | default: |
| @@ -55,6 +55,7 @@ struct mlx5e_ktls_offload_context_rx { · 54 unmodified lines | ||
| 55 | 55 | DECLARE_BITMAP(flags, MLX5E_NUM_PRIV_RX_FLAGS); |
| 56 | 56 | |
| 57 | 57 | /* resync */ |
| 58 | + spinlock_t lock; /* protects resync fields */ | |
| 58 | 59 | struct mlx5e_ktls_rx_resync_ctx resync; |
| 59 | 60 | struct list_head list; |
| 60 | 61 | }; |
| @@ -99,25 +100,6 @@ mlx5e_ktls_rx_resync_create_resp_list(void) · 38 unmodified lines | ||
| 99 | 100 | return resp_list; |
| 100 | 101 | } |
| 101 | 102 | |
| 102 | −static int mlx5e_ktls_create_tir(struct mlx5_core_dev *mdev, struct mlx5e_tir *tir, u32 rqtn) | |
| 103 | −{ | |
| 104 | − struct mlx5e_tir_builder *builder; | |
| 105 | − int err; | |
| 106 | − | |
| 107 | − builder = mlx5e_tir_builder_alloc(false); | |
| 108 | − if (!builder) | |
| 109 | − return -ENOMEM; | |
| 110 | − | |
| 111 | − mlx5e_tir_builder_build_rqt(builder, mdev->mlx5e_res.hw_objs.td.tdn, rqtn, false); | |
| 112 | − mlx5e_tir_builder_build_direct(builder); | |
| 113 | − mlx5e_tir_builder_build_tls(builder); | |
| 114 | − err = mlx5e_tir_init(tir, builder, mdev, false); | |
| 115 | − | |
| 116 | − mlx5e_tir_builder_free(builder); | |
| 117 | − | |
| 118 | − return err; | |
| 119 | −} | |
| 120 | − | |
| 121 | 103 | static void accel_rule_handle_work(struct work_struct *work) |
| 122 | 104 | { |
| 123 | 105 | struct mlx5e_ktls_offload_context_rx *priv_rx; |
| @@ -386,14 +368,18 @@ static void resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_r · 262 unmodified lines | ||
| 386 | 368 | struct mlx5e_icosq *sq; |
| 387 | 369 | bool trigger_poll; |
| 388 | 370 | |
| 389 | − memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq)); | |
| 390 | − | |
| 391 | 371 | sq = &c->async_icosq; |
| 392 | 372 | ktls_resync = sq->ktls_resync; |
| 373 | + trigger_poll = false; | |
| 393 | 374 | |
| 394 | 375 | spin_lock_bh(&ktls_resync->lock); |
| 395 | − list_add_tail(&priv_rx->list, &ktls_resync->list); | |
| 396 | − trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state); | |
| 376 | + spin_lock_bh(&priv_rx->lock); | |
| 377 | + memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq)); | |
| 378 | + if (list_empty(&priv_rx->list)) { | |
| 379 | + list_add_tail(&priv_rx->list, &ktls_resync->list); | |
| 380 | + trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state); | |
| 381 | + } | |
| 382 | + spin_unlock_bh(&priv_rx->lock); | |
| 397 | 383 | spin_unlock_bh(&ktls_resync->lock); |
| 398 | 384 | |
| 399 | 385 | if (!trigger_poll) |
| @@ -604,7 +590,6 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk, · 204 unmodified lines | ||
| 604 | 590 | struct mlx5_core_dev *mdev; |
| 605 | 591 | struct mlx5e_priv *priv; |
| 606 | 592 | int rxq, err; |
| 607 | − u32 rqtn; | |
| 608 | 593 | |
| 609 | 594 | tls_ctx = tls_get_ctx(sk); |
| 610 | 595 | priv = netdev_priv(netdev); |
| @@ -617,6 +602,8 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk, · 6 unmodified lines | ||
| 617 | 602 | if (err) |
| 618 | 603 | goto err_create_key; |
| 619 | 604 | |
| 605 | + INIT_LIST_HEAD(&priv_rx->list); | |
| 606 | + spin_lock_init(&priv_rx->lock); | |
| 620 | 607 | priv_rx->crypto_info = |
| 621 | 608 | *(struct tls12_crypto_info_aes_gcm_128 *)crypto_info; |
| 622 | 609 | |
| @@ -628,9 +615,7 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk, · 5 unmodified lines | ||
| 628 | 615 | priv_rx->sw_stats = &priv->tls->sw_stats; |
| 629 | 616 | mlx5e_set_ktls_rx_priv_ctx(tls_ctx, priv_rx); |
| 630 | 617 | |
| 631 | − rqtn = mlx5e_rx_res_get_rqtn_direct(priv->rx_res, rxq); | |
| 632 | − | |
| 633 | − err = mlx5e_ktls_create_tir(mdev, &priv_rx->tir, rqtn); | |
| 618 | + err = mlx5e_rx_res_tls_tir_create(priv->rx_res, rxq, &priv_rx->tir); | |
| 634 | 619 | if (err) |
| 635 | 620 | goto err_create_tir; |
| 636 | 621 | |
| @@ -730,10 +715,14 @@ bool mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget) · 93 unmodified lines | ||
| 730 | 715 | priv_rx = list_first_entry(&local_list, |
| 731 | 716 | struct mlx5e_ktls_offload_context_rx, |
| 732 | 717 | list); |
| 718 | + spin_lock(&priv_rx->lock); | |
| 733 | 719 | cseg = post_static_params(sq, priv_rx); |
| 734 | − if (IS_ERR(cseg)) | |
| 720 | + if (IS_ERR(cseg)) { | |
| 721 | + spin_unlock(&priv_rx->lock); | |
| 735 | 722 | break; |
| 736 | − list_del(&priv_rx->list); | |
| 723 | + } | |
| 724 | + list_del_init(&priv_rx->list); | |
| 725 | + spin_unlock(&priv_rx->lock); | |
| 737 | 726 | db_cseg = cseg; |
| 738 | 727 | } |
| 739 | 728 | if (db_cseg) |
| @@ -1080,6 +1080,10 @@ static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = { · 1079 unmodified lines | ||
| 1080 | 1080 | &MLX5E_STATS_GRP(pme), |
| 1081 | 1081 | &MLX5E_STATS_GRP(channels), |
| 1082 | 1082 | &MLX5E_STATS_GRP(per_port_buff_congest), |
| 1083 | +#ifdef CONFIG_MLX5_EN_IPSEC | |
| 1084 | + &MLX5E_STATS_GRP(ipsec_sw), | |
| 1085 | + &MLX5E_STATS_GRP(ipsec_hw), | |
| 1086 | +#endif | |
| 1083 | 1087 | }; |
| 1084 | 1088 | |
| 1085 | 1089 | static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv) |
| @@ -543,13 +543,13 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, · 542 unmodified lines | ||
| 543 | 543 | u16 klm_entries, u16 index) |
| 544 | 544 | { |
| 545 | 545 | struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; |
| 546 | − u16 entries, pi, i, header_offset, err, wqe_bbs, new_entries; | |
| 546 | + u16 entries, pi, header_offset, err, wqe_bbs, new_entries; | |
| 547 | 547 | u32 lkey = rq->mdev->mlx5e_res.hw_objs.mkey; |
| 548 | 548 | struct page *page = shampo->last_page; |
| 549 | 549 | u64 addr = shampo->last_addr; |
| 550 | 550 | struct mlx5e_dma_info *dma_info; |
| 551 | 551 | struct mlx5e_umr_wqe *umr_wqe; |
| 552 | − int headroom; | |
| 552 | + int headroom, i; | |
| 553 | 553 | |
| 554 | 554 | headroom = rq->buff.headroom; |
| 555 | 555 | new_entries = klm_entries - (shampo->pi & (MLX5_UMR_KLM_ALIGNMENT - 1)); |
| @@ -601,9 +601,7 @@ update_klm: · 45 unmodified lines | ||
| 601 | 601 | |
| 602 | 602 | err_unmap: |
| 603 | 603 | while (--i >= 0) { |
| 604 | − if (--index < 0) | |
| 605 | − index = shampo->hd_per_wq - 1; | |
| 606 | − dma_info = &shampo->info[index]; | |
| 604 | + dma_info = &shampo->info[--index]; | |
| 607 | 605 | if (!(i & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1))) { |
| 608 | 606 | dma_info->addr = ALIGN_DOWN(dma_info->addr, PAGE_SIZE); |
| 609 | 607 | mlx5e_page_release(rq, dma_info, true); |
| @@ -1600,6 +1600,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, · 1599 unmodified lines | ||
| 1600 | 1600 | else |
| 1601 | 1601 | mlx5e_tc_unoffload_fdb_rules(esw, flow, attr); |
| 1602 | 1602 | } |
| 1603 | + complete_all(&flow->del_hw_done); | |
| 1603 | 1604 | |
| 1604 | 1605 | if (mlx5_flow_has_geneve_opt(flow)) |
| 1605 | 1606 | mlx5_geneve_tlv_option_del(priv->mdev->geneve); |
| @@ -3607,7 +3608,9 @@ parse_tc_nic_actions(struct mlx5e_priv *priv, · 2001 unmodified lines | ||
| 3607 | 3608 | attr->dest_chain = act->chain_index; |
| 3608 | 3609 | break; |
| 3609 | 3610 | case FLOW_ACTION_CT: |
| 3610 | − err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, act, extack); | |
| 3611 | + err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, | |
| 3612 | + &parse_attr->mod_hdr_acts, | |
| 3613 | + act, extack); | |
| 3611 | 3614 | if (err) |
| 3612 | 3615 | return err; |
| 3613 | 3616 | |
| @@ -4276,7 +4279,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, · 662 unmodified lines | ||
| 4276 | 4279 | NL_SET_ERR_MSG_MOD(extack, "Sample action with connection tracking is not supported"); |
| 4277 | 4280 | return -EOPNOTSUPP; |
| 4278 | 4281 | } |
| 4279 | − err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, act, extack); | |
| 4282 | + err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, | |
| 4283 | + &parse_attr->mod_hdr_acts, | |
| 4284 | + act, extack); | |
| 4280 | 4285 | if (err) |
| 4281 | 4286 | return err; |
| 4282 | 4287 | |
| @@ -4465,6 +4470,7 @@ mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size, · 182 unmodified lines | ||
| 4465 | 4470 | INIT_LIST_HEAD(&flow->l3_to_l2_reformat); |
| 4466 | 4471 | refcount_set(&flow->refcnt, 1); |
| 4467 | 4472 | init_completion(&flow->init_done); |
| 4473 | + init_completion(&flow->del_hw_done); | |
| 4468 | 4474 | |
| 4469 | 4475 | *__flow = flow; |
| 4470 | 4476 | *__parse_attr = parse_attr; |
| @@ -130,7 +130,7 @@ static u32 esw_qos_calculate_min_rate_divider(struct mlx5_eswitch *esw, · 129 unmodified lines | ||
| 130 | 130 | /* If vports min rate divider is 0 but their group has bw_share configured, then |
| 131 | 131 | * need to set bw_share for vports to minimal value. |
| 132 | 132 | */ |
| 133 | − if (!group_level && !max_guarantee && group->bw_share) | |
| 133 | + if (!group_level && !max_guarantee && group && group->bw_share) | |
| 134 | 134 | return 1; |
| 135 | 135 | return 0; |
| 136 | 136 | } |
| @@ -423,7 +423,7 @@ static int esw_qos_vport_update_group(struct mlx5_eswitch *esw, · 286 unmodified lines | ||
| 423 | 423 | return err; |
| 424 | 424 | |
| 425 | 425 | /* Recalculate bw share weights of old and new groups */ |
| 426 | − if (vport->qos.bw_share) { | |
| 426 | + if (vport->qos.bw_share || new_group->bw_share) { | |
| 427 | 427 | esw_qos_normalize_vports_min_rate(esw, curr_group, extack); |
| 428 | 428 | esw_qos_normalize_vports_min_rate(esw, new_group, extack); |
| 429 | 429 | } |
| @@ -1305,12 +1305,17 @@ abort: · 1304 unmodified lines | ||
| 1305 | 1305 | */ |
| 1306 | 1306 | int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) |
| 1307 | 1307 | { |
| 1308 | + bool toggle_lag; | |
| 1308 | 1309 | int ret; |
| 1309 | 1310 | |
| 1310 | 1311 | if (!mlx5_esw_allowed(esw)) |
| 1311 | 1312 | return 0; |
| 1312 | 1313 | |
| 1313 | − mlx5_lag_disable_change(esw->dev); | |
| 1314 | + toggle_lag = esw->mode == MLX5_ESWITCH_NONE; | |
| 1315 | + | |
| 1316 | + if (toggle_lag) | |
| 1317 | + mlx5_lag_disable_change(esw->dev); | |
| 1318 | + | |
| 1314 | 1319 | down_write(&esw->mode_lock); |
| 1315 | 1320 | if (esw->mode == MLX5_ESWITCH_NONE) { |
| 1316 | 1321 | ret = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_LEGACY, num_vfs); |
| @@ -1324,7 +1329,10 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) · 7 unmodified lines | ||
| 1324 | 1329 | esw->esw_funcs.num_vfs = num_vfs; |
| 1325 | 1330 | } |
| 1326 | 1331 | up_write(&esw->mode_lock); |
| 1327 | − mlx5_lag_enable_change(esw->dev); | |
| 1332 | + | |
| 1333 | + if (toggle_lag) | |
| 1334 | + mlx5_lag_enable_change(esw->dev); | |
| 1335 | + | |
| 1328 | 1336 | return ret; |
| 1329 | 1337 | } |
| 1330 | 1338 | |
| @@ -1572,6 +1580,11 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) · 241 unmodified lines | ||
| 1572 | 1580 | esw->enabled_vports = 0; |
| 1573 | 1581 | esw->mode = MLX5_ESWITCH_NONE; |
| 1574 | 1582 | esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE; |
| 1583 | + if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, reformat) && | |
| 1584 | + MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap)) | |
| 1585 | + esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC; | |
| 1586 | + else | |
| 1587 | + esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE; | |
| 1575 | 1588 | |
| 1576 | 1589 | dev->priv.eswitch = esw; |
| 1577 | 1590 | BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head); |
| @@ -1934,7 +1947,7 @@ free_out: · 356 unmodified lines | ||
| 1934 | 1947 | return err; |
| 1935 | 1948 | } |
| 1936 | 1949 | |
| 1937 | −u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev) | |
| 1950 | +u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev) | |
| 1938 | 1951 | { |
| 1939 | 1952 | struct mlx5_eswitch *esw = dev->priv.eswitch; |
| 1940 | 1953 | |
| @@ -1948,7 +1961,7 @@ mlx5_eswitch_get_encap_mode(const struct mlx5_core_dev *dev) · 7 unmodified lines | ||
| 1948 | 1961 | struct mlx5_eswitch *esw; |
| 1949 | 1962 | |
| 1950 | 1963 | esw = dev->priv.eswitch; |
| 1951 | − return mlx5_esw_allowed(esw) ? esw->offloads.encap : | |
| 1964 | + return (mlx5_eswitch_mode(dev) == MLX5_ESWITCH_OFFLOADS) ? esw->offloads.encap : | |
| 1952 | 1965 | DEVLINK_ESWITCH_ENCAP_MODE_NONE; |
| 1953 | 1966 | } |
| 1954 | 1967 | EXPORT_SYMBOL(mlx5_eswitch_get_encap_mode); |
| @@ -329,14 +329,25 @@ static bool · 328 unmodified lines | ||
| 329 | 329 | esw_is_indir_table(struct mlx5_eswitch *esw, struct mlx5_flow_attr *attr) |
| 330 | 330 | { |
| 331 | 331 | struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr; |
| 332 | + bool result = false; | |
| 332 | 333 | int i; |
| 333 | 334 | |
| 334 | − for (i = esw_attr->split_count; i < esw_attr->out_count; i++) | |
| 335 | + /* Indirect table is supported only for flows with in_port uplink | |
| 336 | + * and the destination is vport on the same eswitch as the uplink, | |
| 337 | + * return false in case at least one of destinations doesn't meet | |
| 338 | + * this criteria. | |
| 339 | + */ | |
| 340 | + for (i = esw_attr->split_count; i < esw_attr->out_count; i++) { | |
| 335 | 341 | if (esw_attr->dests[i].rep && |
| 336 | 342 | mlx5_esw_indir_table_needed(esw, attr, esw_attr->dests[i].rep->vport, |
| 337 | − esw_attr->dests[i].mdev)) | |
| 338 | − return true; | |
| 339 | − return false; | |
| 343 | + esw_attr->dests[i].mdev)) { | |
| 344 | + result = true; | |
| 345 | + } else { | |
| 346 | + result = false; | |
| 347 | + break; | |
| 348 | + } | |
| 349 | + } | |
| 350 | + return result; | |
| 340 | 351 | } |
| 341 | 352 | |
| 342 | 353 | static int |
| @@ -2512,6 +2523,7 @@ static int esw_set_master_egress_rule(struct mlx5_core_dev *master, · 2169 unmodified lines | ||
| 2512 | 2523 | struct mlx5_eswitch *esw = master->priv.eswitch; |
| 2513 | 2524 | struct mlx5_flow_table_attr ft_attr = { |
| 2514 | 2525 | .max_fte = 1, .prio = 0, .level = 0, |
| 2526 | + .flags = MLX5_FLOW_TABLE_OTHER_VPORT, | |
| 2515 | 2527 | }; |
| 2516 | 2528 | struct mlx5_flow_namespace *egress_ns; |
| 2517 | 2529 | struct mlx5_flow_table *acl; |
| @@ -3183,12 +3195,6 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) · 665 unmodified lines | ||
| 3183 | 3195 | u64 mapping_id; |
| 3184 | 3196 | int err; |
| 3185 | 3197 | |
| 3186 | − if (MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, reformat) && | |
| 3187 | − MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, decap)) | |
| 3188 | − esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC; | |
| 3189 | − else | |
| 3190 | − esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE; | |
| 3191 | − | |
| 3192 | 3198 | mutex_init(&esw->offloads.termtbl_mutex); |
| 3193 | 3199 | mlx5_rdma_enable_roce(esw->dev); |
| 3194 | 3200 | |
| @@ -3286,7 +3292,6 @@ void esw_offloads_disable(struct mlx5_eswitch *esw) · 91 unmodified lines | ||
| 3286 | 3292 | esw_offloads_metadata_uninit(esw); |
| 3287 | 3293 | mlx5_rdma_disable_roce(esw->dev); |
| 3288 | 3294 | mutex_destroy(&esw->offloads.termtbl_mutex); |
| 3289 | − esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE; | |
| 3290 | 3295 | } |
| 3291 | 3296 | |
| 3292 | 3297 | static int esw_mode_from_devlink(u16 mode, u16 *mlx5_mode) |
| @@ -3630,7 +3635,7 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, · 337 unmodified lines | ||
| 3630 | 3635 | *encap = esw->offloads.encap; |
| 3631 | 3636 | unlock: |
| 3632 | 3637 | up_write(&esw->mode_lock); |
| 3633 | − return 0; | |
| 3638 | + return err; | |
| 3634 | 3639 | } |
| 3635 | 3640 | |
| 3636 | 3641 | static bool |
| @@ -40,7 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | #define MLX5_FC_STATS_PERIOD msecs_to_jiffies(1000) |
| 41 | 41 | /* Max number of counters to query in bulk read is 32K */ |
| 42 | 42 | #define MLX5_SW_MAX_COUNTERS_BULK BIT(15) |
| 43 | −#define MLX5_SF_NUM_COUNTERS_BULK 6 | |
| 43 | +#define MLX5_SF_NUM_COUNTERS_BULK 8 | |
| 44 | 44 | #define MLX5_FC_POOL_MAX_THRESHOLD BIT(18) |
| 45 | 45 | #define MLX5_FC_POOL_USED_BUFF_RATIO 10 |
| 46 | 46 | |
| @@ -835,6 +835,9 @@ void mlx5_start_health_poll(struct mlx5_core_dev *dev) · 834 unmodified lines | ||
| 835 | 835 | |
| 836 | 836 | health->timer.expires = jiffies + msecs_to_jiffies(poll_interval_ms); |
| 837 | 837 | add_timer(&health->timer); |
| 838 | + | |
| 839 | + if (mlx5_core_is_pf(dev) && MLX5_CAP_MCAM_REG(dev, mrtc)) | |
| 840 | + queue_delayed_work(health->wq, &health->update_fw_log_ts_work, 0); | |
| 838 | 841 | } |
| 839 | 842 | |
| 840 | 843 | void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health) |
| @@ -902,8 +905,6 @@ int mlx5_health_init(struct mlx5_core_dev *dev) · 61 unmodified lines | ||
| 902 | 905 | INIT_WORK(&health->fatal_report_work, mlx5_fw_fatal_reporter_err_work); |
| 903 | 906 | INIT_WORK(&health->report_work, mlx5_fw_reporter_err_work); |
| 904 | 907 | INIT_DELAYED_WORK(&health->update_fw_log_ts_work, mlx5_health_log_ts_update); |
| 905 | − if (mlx5_core_is_pf(dev)) | |
| 906 | − queue_delayed_work(health->wq, &health->update_fw_log_ts_work, 0); | |
| 907 | 908 | |
| 908 | 909 | return 0; |
| 909 | 910 | |
| @@ -615,6 +615,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, · 614 unmodified lines | ||
| 615 | 615 | bool is_bonded, is_in_lag, mode_supported; |
| 616 | 616 | int bond_status = 0; |
| 617 | 617 | int num_slaves = 0; |
| 618 | + int changed = 0; | |
| 618 | 619 | int idx; |
| 619 | 620 | |
| 620 | 621 | if (!netif_is_lag_master(upper)) |
| @@ -653,27 +654,27 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, · 32 unmodified lines | ||
| 653 | 654 | */ |
| 654 | 655 | is_in_lag = num_slaves == MLX5_MAX_PORTS && bond_status == 0x3; |
| 655 | 656 | |
| 656 | − if (!mlx5_lag_is_ready(ldev) && is_in_lag) { | |
| 657 | − NL_SET_ERR_MSG_MOD(info->info.extack, | |
| 658 | − "Can't activate LAG offload, PF is configured with more than 64 VFs"); | |
| 659 | − return 0; | |
| 660 | − } | |
| 661 | − | |
| 662 | 657 | /* Lag mode must be activebackup or hash. */ |
| 663 | 658 | mode_supported = tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP || |
| 664 | 659 | tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH; |
| 665 | 660 | |
| 666 | − if (is_in_lag && !mode_supported) | |
| 667 | − NL_SET_ERR_MSG_MOD(info->info.extack, | |
| 668 | − "Can't activate LAG offload, TX type isn't supported"); | |
| 669 | − | |
| 670 | 661 | is_bonded = is_in_lag && mode_supported; |
| 671 | 662 | if (tracker->is_bonded != is_bonded) { |
| 672 | 663 | tracker->is_bonded = is_bonded; |
| 673 | − return 1; | |
| 664 | + changed = 1; | |
| 674 | 665 | } |
| 675 | 666 | |
| 676 | − return 0; | |
| 667 | + if (!is_in_lag) | |
| 668 | + return changed; | |
| 669 | + | |
| 670 | + if (!mlx5_lag_is_ready(ldev)) | |
| 671 | + NL_SET_ERR_MSG_MOD(info->info.extack, | |
| 672 | + "Can't activate LAG offload, PF is configured with more than 64 VFs"); | |
| 673 | + else if (!mode_supported) | |
| 674 | + NL_SET_ERR_MSG_MOD(info->info.extack, | |
| 675 | + "Can't activate LAG offload, TX type isn't supported"); | |
| 676 | + | |
| 677 | + return changed; | |
| 677 | 678 | } |
| 678 | 679 | |
| 679 | 680 | static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev, |
| @@ -716,9 +717,6 @@ static int mlx5_lag_netdev_event(struct notifier_block *this, · 36 unmodified lines | ||
| 716 | 717 | |
| 717 | 718 | ldev = container_of(this, struct mlx5_lag, nb); |
| 718 | 719 | |
| 719 | − if (!mlx5_lag_is_ready(ldev) && event == NETDEV_CHANGELOWERSTATE) | |
| 720 | − return NOTIFY_DONE; | |
| 721 | − | |
| 722 | 720 | tracker = ldev->tracker; |
| 723 | 721 | |
| 724 | 722 | switch (event) { |
| @@ -608,4 +608,5 @@ void mlx5_lag_port_sel_destroy(struct mlx5_lag *ldev) · 607 unmodified lines | ||
| 608 | 608 | if (port_sel->tunnel) |
| 609 | 609 | mlx5_destroy_ttc_table(port_sel->inner.ttc); |
| 610 | 610 | mlx5_lag_destroy_definers(ldev); |
| 611 | + memset(port_sel, 0, sizeof(*port_sel)); | |
| 611 | 612 | } |
| @@ -31,11 +31,11 @@ static void tout_set(struct mlx5_core_dev *dev, u64 val, enum mlx5_timeouts_type · 30 unmodified lines | ||
| 31 | 31 | dev->timeouts->to[type] = val; |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | −static void tout_set_def_val(struct mlx5_core_dev *dev) | |
| 34 | +void mlx5_tout_set_def_val(struct mlx5_core_dev *dev) | |
| 35 | 35 | { |
| 36 | 36 | int i; |
| 37 | 37 | |
| 38 | − for (i = MLX5_TO_FW_PRE_INIT_TIMEOUT_MS; i < MAX_TIMEOUT_TYPES; i++) | |
| 38 | + for (i = 0; i < MAX_TIMEOUT_TYPES; i++) | |
| 39 | 39 | tout_set(dev, tout_def_sw_val[i], i); |
| 40 | 40 | } |
| 41 | 41 | |
| @@ -45,7 +45,6 @@ int mlx5_tout_init(struct mlx5_core_dev *dev) · 3 unmodified lines | ||
| 45 | 45 | if (!dev->timeouts) |
| 46 | 46 | return -ENOMEM; |
| 47 | 47 | |
| 48 | − tout_set_def_val(dev); | |
| 49 | 48 | return 0; |
| 50 | 49 | } |
| 51 | 50 | |
| @@ -34,6 +34,7 @@ int mlx5_tout_init(struct mlx5_core_dev *dev); · 33 unmodified lines | ||
| 34 | 34 | void mlx5_tout_cleanup(struct mlx5_core_dev *dev); |
| 35 | 35 | void mlx5_tout_query_iseg(struct mlx5_core_dev *dev); |
| 36 | 36 | int mlx5_tout_query_dtor(struct mlx5_core_dev *dev); |
| 37 | +void mlx5_tout_set_def_val(struct mlx5_core_dev *dev); | |
| 37 | 38 | u64 _mlx5_tout_ms(struct mlx5_core_dev *dev, enum mlx5_timeouts_types type); |
| 38 | 39 | |
| 39 | 40 | #define mlx5_tout_ms(dev, type) _mlx5_tout_ms(dev, MLX5_TO_##type##_MS) |
| @@ -992,11 +992,7 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot) · 991 unmodified lines | ||
| 992 | 992 | if (mlx5_core_is_pf(dev)) |
| 993 | 993 | pcie_print_link_status(dev->pdev); |
| 994 | 994 | |
| 995 | − err = mlx5_tout_init(dev); | |
| 996 | − if (err) { | |
| 997 | − mlx5_core_err(dev, "Failed initializing timeouts, aborting\n"); | |
| 998 | − return err; | |
| 999 | − } | |
| 995 | + mlx5_tout_set_def_val(dev); | |
| 1000 | 996 | |
| 1001 | 997 | /* wait for firmware to accept initialization segments configurations |
| 1002 | 998 | */ |
| @@ -1005,13 +1001,13 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot) · 2 unmodified lines | ||
| 1005 | 1001 | if (err) { |
| 1006 | 1002 | mlx5_core_err(dev, "Firmware over %llu MS in pre-initializing state, aborting\n", |
| 1007 | 1003 | mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT)); |
| 1008 | − goto err_tout_cleanup; | |
| 1004 | + return err; | |
| 1009 | 1005 | } |
| 1010 | 1006 | |
| 1011 | 1007 | err = mlx5_cmd_init(dev); |
| 1012 | 1008 | if (err) { |
| 1013 | 1009 | mlx5_core_err(dev, "Failed initializing command interface, aborting\n"); |
| 1014 | − goto err_tout_cleanup; | |
| 1010 | + return err; | |
| 1015 | 1011 | } |
| 1016 | 1012 | |
| 1017 | 1013 | mlx5_tout_query_iseg(dev); |
| @@ -1075,18 +1071,16 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot) · 57 unmodified lines | ||
| 1075 | 1071 | |
| 1076 | 1072 | mlx5_set_driver_version(dev); |
| 1077 | 1073 | |
| 1078 | − mlx5_start_health_poll(dev); | |
| 1079 | − | |
| 1080 | 1074 | err = mlx5_query_hca_caps(dev); |
| 1081 | 1075 | if (err) { |
| 1082 | 1076 | mlx5_core_err(dev, "query hca failed\n"); |
| 1083 | − goto stop_health; | |
| 1077 | + goto reclaim_boot_pages; | |
| 1084 | 1078 | } |
| 1085 | 1079 | |
| 1080 | + mlx5_start_health_poll(dev); | |
| 1081 | + | |
| 1086 | 1082 | return 0; |
| 1087 | 1083 | |
| 1088 | −stop_health: | |
| 1089 | − mlx5_stop_health_poll(dev, boot); | |
| 1090 | 1084 | reclaim_boot_pages: |
| 1091 | 1085 | mlx5_reclaim_startup_pages(dev); |
| 1092 | 1086 | err_disable_hca: |
| @@ -1094,8 +1088,6 @@ err_disable_hca: · 1 unmodified line | ||
| 1094 | 1088 | err_cmd_cleanup: |
| 1095 | 1089 | mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); |
| 1096 | 1090 | mlx5_cmd_cleanup(dev); |
| 1097 | −err_tout_cleanup: | |
| 1098 | − mlx5_tout_cleanup(dev); | |
| 1099 | 1091 | |
| 1100 | 1092 | return err; |
| 1101 | 1093 | } |
| @@ -1114,7 +1106,6 @@ static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot) · 12 unmodified lines | ||
| 1114 | 1106 | mlx5_core_disable_hca(dev, 0); |
| 1115 | 1107 | mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); |
| 1116 | 1108 | mlx5_cmd_cleanup(dev); |
| 1117 | − mlx5_tout_cleanup(dev); | |
| 1118 | 1109 | |
| 1119 | 1110 | return 0; |
| 1120 | 1111 | } |
| @@ -1476,6 +1467,12 @@ int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx) · 355 unmodified lines | ||
| 1476 | 1467 | mlx5_debugfs_root); |
| 1477 | 1468 | INIT_LIST_HEAD(&priv->traps); |
| 1478 | 1469 | |
| 1470 | + err = mlx5_tout_init(dev); | |
| 1471 | + if (err) { | |
| 1472 | + mlx5_core_err(dev, "Failed initializing timeouts, aborting\n"); | |
| 1473 | + goto err_timeout_init; | |
| 1474 | + } | |
| 1475 | + | |
| 1479 | 1476 | err = mlx5_health_init(dev); |
| 1480 | 1477 | if (err) |
| 1481 | 1478 | goto err_health_init; |
| @@ -1501,6 +1498,8 @@ err_adev_init: · 19 unmodified lines | ||
| 1501 | 1498 | err_pagealloc_init: |
| 1502 | 1499 | mlx5_health_cleanup(dev); |
| 1503 | 1500 | err_health_init: |
| 1501 | + mlx5_tout_cleanup(dev); | |
| 1502 | +err_timeout_init: | |
| 1504 | 1503 | debugfs_remove(dev->priv.dbg_root); |
| 1505 | 1504 | mutex_destroy(&priv->pgdir_mutex); |
| 1506 | 1505 | mutex_destroy(&priv->alloc_mutex); |
| @@ -1518,6 +1517,7 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev) · 11 unmodified lines | ||
| 1518 | 1517 | mlx5_adev_cleanup(dev); |
| 1519 | 1518 | mlx5_pagealloc_cleanup(dev); |
| 1520 | 1519 | mlx5_health_cleanup(dev); |
| 1520 | + mlx5_tout_cleanup(dev); | |
| 1521 | 1521 | debugfs_remove_recursive(dev->priv.dbg_root); |
| 1522 | 1522 | mutex_destroy(&priv->pgdir_mutex); |
| 1523 | 1523 | mutex_destroy(&priv->alloc_mutex); |
| @@ -135,25 +135,14 @@ static void dr_domain_fill_uplink_caps(struct mlx5dr_domain *dmn, · 134 unmodified lines | ||
| 135 | 135 | |
| 136 | 136 | static int dr_domain_query_vport(struct mlx5dr_domain *dmn, |
| 137 | 137 | u16 vport_number, |
| 138 | + bool other_vport, | |
| 138 | 139 | struct mlx5dr_cmd_vport_cap *vport_caps) |
| 139 | 140 | { |
| 140 | − u16 cmd_vport = vport_number; | |
| 141 | − bool other_vport = true; | |
| 142 | 141 | int ret; |
| 143 | 142 | |
| 144 | − if (vport_number == MLX5_VPORT_UPLINK) { | |
| 145 | − dr_domain_fill_uplink_caps(dmn, vport_caps); | |
| 146 | − return 0; | |
| 147 | − } | |
| 148 | − | |
| 149 | − if (dmn->info.caps.is_ecpf && vport_number == MLX5_VPORT_ECPF) { | |
| 150 | − other_vport = false; | |
| 151 | − cmd_vport = 0; | |
| 152 | − } | |
| 153 | − | |
| 154 | 143 | ret = mlx5dr_cmd_query_esw_vport_context(dmn->mdev, |
| 155 | 144 | other_vport, |
| 156 | − cmd_vport, | |
| 145 | + vport_number, | |
| 157 | 146 | &vport_caps->icm_address_rx, |
| 158 | 147 | &vport_caps->icm_address_tx); |
| 159 | 148 | if (ret) |
| @@ -161,7 +150,7 @@ static int dr_domain_query_vport(struct mlx5dr_domain *dmn, · 1 unmodified line | ||
| 161 | 150 | |
| 162 | 151 | ret = mlx5dr_cmd_query_gvmi(dmn->mdev, |
| 163 | 152 | other_vport, |
| 164 | − cmd_vport, | |
| 153 | + vport_number, | |
| 165 | 154 | &vport_caps->vport_gvmi); |
| 166 | 155 | if (ret) |
| 167 | 156 | return ret; |
| @@ -176,9 +165,15 @@ static int dr_domain_query_esw_mngr(struct mlx5dr_domain *dmn) · 8 unmodified lines | ||
| 176 | 165 | { |
| 177 | 166 | return dr_domain_query_vport(dmn, |
| 178 | 167 | dmn->info.caps.is_ecpf ? MLX5_VPORT_ECPF : 0, |
| 168 | + false, | |
| 179 | 169 | &dmn->info.caps.vports.esw_manager_caps); |
| 180 | 170 | } |
| 181 | 171 | |
| 172 | +static void dr_domain_query_uplink(struct mlx5dr_domain *dmn) | |
| 173 | +{ | |
| 174 | + dr_domain_fill_uplink_caps(dmn, &dmn->info.caps.vports.uplink_caps); | |
| 175 | +} | |
| 176 | + | |
| 182 | 177 | static struct mlx5dr_cmd_vport_cap * |
| 183 | 178 | dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport) |
| 184 | 179 | { |
| @@ -190,7 +185,7 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport) · 5 unmodified lines | ||
| 190 | 185 | if (!vport_caps) |
| 191 | 186 | return NULL; |
| 192 | 187 | |
| 193 | − ret = dr_domain_query_vport(dmn, vport, vport_caps); | |
| 188 | + ret = dr_domain_query_vport(dmn, vport, true, vport_caps); | |
| 194 | 189 | if (ret) { |
| 195 | 190 | kvfree(vport_caps); |
| 196 | 191 | return NULL; |
| @@ -207,16 +202,26 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport) · 10 unmodified lines | ||
| 207 | 202 | return vport_caps; |
| 208 | 203 | } |
| 209 | 204 | |
| 205 | +static bool dr_domain_is_esw_mgr_vport(struct mlx5dr_domain *dmn, u16 vport) | |
| 206 | +{ | |
| 207 | + struct mlx5dr_cmd_caps *caps = &dmn->info.caps; | |
| 208 | + | |
| 209 | + return (caps->is_ecpf && vport == MLX5_VPORT_ECPF) || | |
| 210 | + (!caps->is_ecpf && vport == 0); | |
| 211 | +} | |
| 212 | + | |
| 210 | 213 | struct mlx5dr_cmd_vport_cap * |
| 211 | 214 | mlx5dr_domain_get_vport_cap(struct mlx5dr_domain *dmn, u16 vport) |
| 212 | 215 | { |
| 213 | 216 | struct mlx5dr_cmd_caps *caps = &dmn->info.caps; |
| 214 | 217 | struct mlx5dr_cmd_vport_cap *vport_caps; |
| 215 | 218 | |
| 216 | − if ((caps->is_ecpf && vport == MLX5_VPORT_ECPF) || | |
| 217 | − (!caps->is_ecpf && vport == 0)) | |
| 219 | + if (dr_domain_is_esw_mgr_vport(dmn, vport)) | |
| 218 | 220 | return &caps->vports.esw_manager_caps; |
| 219 | 221 | |
| 222 | + if (vport == MLX5_VPORT_UPLINK) | |
| 223 | + return &caps->vports.uplink_caps; | |
| 224 | + | |
| 220 | 225 | vport_load: |
| 221 | 226 | vport_caps = xa_load(&caps->vports.vports_caps_xa, vport); |
| 222 | 227 | if (vport_caps) |
| @@ -241,17 +246,6 @@ static void dr_domain_clear_vports(struct mlx5dr_domain *dmn) · 18 unmodified lines | ||
| 241 | 246 | } |
| 242 | 247 | } |
| 243 | 248 | |
| 244 | −static int dr_domain_query_uplink(struct mlx5dr_domain *dmn) | |
| 245 | −{ | |
| 246 | − struct mlx5dr_cmd_vport_cap *vport_caps; | |
| 247 | − | |
| 248 | − vport_caps = mlx5dr_domain_get_vport_cap(dmn, MLX5_VPORT_UPLINK); | |
| 249 | − if (!vport_caps) | |
| 250 | − return -EINVAL; | |
| 251 | − | |
| 252 | − return 0; | |
| 253 | −} | |
| 254 | − | |
| 255 | 249 | static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev, |
| 256 | 250 | struct mlx5dr_domain *dmn) |
| 257 | 251 | { |
| @@ -281,11 +275,7 @@ static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev, · 23 unmodified lines | ||
| 281 | 275 | goto free_vports_caps_xa; |
| 282 | 276 | } |
| 283 | 277 | |
| 284 | − ret = dr_domain_query_uplink(dmn); | |
| 285 | − if (ret) { | |
| 286 | − mlx5dr_err(dmn, "Failed to query uplink vport caps (err: %d)", ret); | |
| 287 | − goto free_vports_caps_xa; | |
| 288 | − } | |
| 278 | + dr_domain_query_uplink(dmn); | |
| 289 | 279 | |
| 290 | 280 | return 0; |
| 291 | 281 | |
| @@ -924,11 +924,12 @@ static int dr_matcher_init(struct mlx5dr_matcher *matcher, · 923 unmodified lines | ||
| 924 | 924 | |
| 925 | 925 | /* Check that all mask data was consumed */ |
| 926 | 926 | for (i = 0; i < consumed_mask.match_sz; i++) { |
| 927 | − if (consumed_mask.match_buf[i]) { | |
| 928 | − mlx5dr_dbg(dmn, "Match param mask contains unsupported parameters\n"); | |
| 929 | − ret = -EOPNOTSUPP; | |
| 930 | − goto free_consumed_mask; | |
| 931 | − } | |
| 927 | + if (!((u8 *)consumed_mask.match_buf)[i]) | |
| 928 | + continue; | |
| 929 | + | |
| 930 | + mlx5dr_dbg(dmn, "Match param mask contains unsupported parameters\n"); | |
| 931 | + ret = -EOPNOTSUPP; | |
| 932 | + goto free_consumed_mask; | |
| 932 | 933 | } |
| 933 | 934 | |
| 934 | 935 | ret = 0; |
| @@ -764,6 +764,7 @@ struct mlx5dr_roce_cap { · 763 unmodified lines | ||
| 764 | 764 | |
| 765 | 765 | struct mlx5dr_vports { |
| 766 | 766 | struct mlx5dr_cmd_vport_cap esw_manager_caps; |
| 767 | + struct mlx5dr_cmd_vport_cap uplink_caps; | |
| 767 | 768 | struct xarray vports_caps_xa; |
| 768 | 769 | }; |
| 769 | 770 | |
| @@ -2153,7 +2153,7 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg, · 2152 unmodified lines | ||
| 2153 | 2153 | max_ports = mlxsw_core_max_ports(mlxsw_sp->core); |
| 2154 | 2154 | local_port = mlxsw_reg_pude_local_port_get(pude_pl); |
| 2155 | 2155 | |
| 2156 | − if (WARN_ON_ONCE(local_port >= max_ports)) | |
| 2156 | + if (WARN_ON_ONCE(!local_port || local_port >= max_ports)) | |
| 2157 | 2157 | return; |
| 2158 | 2158 | mlxsw_sp_port = mlxsw_sp->ports[local_port]; |
| 2159 | 2159 | if (!mlxsw_sp_port) |
| @@ -3290,10 +3290,10 @@ mlxsw_sp_resources_rif_mac_profile_register(struct mlxsw_core *mlxsw_core) · 1130 unmodified lines | ||
| 3290 | 3290 | u8 max_rif_mac_profiles; |
| 3291 | 3291 | |
| 3292 | 3292 | if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_RIF_MAC_PROFILES)) |
| 3293 | − return -EIO; | |
| 3294 | − | |
| 3295 | − max_rif_mac_profiles = MLXSW_CORE_RES_GET(mlxsw_core, | |
| 3296 | − MAX_RIF_MAC_PROFILES); | |
| 3293 | + max_rif_mac_profiles = 1; | |
| 3294 | + else | |
| 3295 | + max_rif_mac_profiles = MLXSW_CORE_RES_GET(mlxsw_core, | |
| 3296 | + MAX_RIF_MAC_PROFILES); | |
| 3297 | 3297 | devlink_resource_size_params_init(&size_params, max_rif_mac_profiles, |
| 3298 | 3298 | max_rif_mac_profiles, 1, |
| 3299 | 3299 | DEVLINK_RESOURCE_UNIT_ENTRY); |
| @@ -914,8 +914,7 @@ static int lan743x_phy_reset(struct lan743x_adapter *adapter) · 913 unmodified lines | ||
| 914 | 914 | } |
| 915 | 915 | |
| 916 | 916 | static void lan743x_phy_update_flowcontrol(struct lan743x_adapter *adapter, |
| 917 | − u8 duplex, u16 local_adv, | |
| 918 | − u16 remote_adv) | |
| 917 | + u16 local_adv, u16 remote_adv) | |
| 919 | 918 | { |
| 920 | 919 | struct lan743x_phy *phy = &adapter->phy; |
| 921 | 920 | u8 cap; |
| @@ -943,7 +942,6 @@ static void lan743x_phy_link_status_change(struct net_device *netdev) · 21 unmodified lines | ||
| 943 | 942 | |
| 944 | 943 | phy_print_status(phydev); |
| 945 | 944 | if (phydev->state == PHY_RUNNING) { |
| 946 | − struct ethtool_link_ksettings ksettings; | |
| 947 | 945 | int remote_advertisement = 0; |
| 948 | 946 | int local_advertisement = 0; |
| 949 | 947 | |
| @@ -980,18 +978,14 @@ static void lan743x_phy_link_status_change(struct net_device *netdev) · 30 unmodified lines | ||
| 980 | 978 | } |
| 981 | 979 | lan743x_csr_write(adapter, MAC_CR, data); |
| 982 | 980 | |
| 983 | − memset(&ksettings, 0, sizeof(ksettings)); | |
| 984 | − phy_ethtool_get_link_ksettings(netdev, &ksettings); | |
| 985 | 981 | local_advertisement = |
| 986 | 982 | linkmode_adv_to_mii_adv_t(phydev->advertising); |
| 987 | 983 | remote_advertisement = |
| 988 | 984 | linkmode_adv_to_mii_adv_t(phydev->lp_advertising); |
| 989 | 985 | |
| 990 | − lan743x_phy_update_flowcontrol(adapter, | |
| 991 | − ksettings.base.duplex, | |
| 992 | − local_advertisement, | |
| 986 | + lan743x_phy_update_flowcontrol(adapter, local_advertisement, | |
| 993 | 987 | remote_advertisement); |
| 994 | − lan743x_ptp_update_latency(adapter, ksettings.base.speed); | |
| 988 | + lan743x_ptp_update_latency(adapter, phydev->speed); | |
| 995 | 989 | } |
| 996 | 990 | } |
| 997 | 991 | |
| @@ -480,16 +480,16 @@ static int mana_hwc_create_wq(struct hw_channel_context *hwc, · 479 unmodified lines | ||
| 480 | 480 | if (err) |
| 481 | 481 | goto out; |
| 482 | 482 | |
| 483 | − err = mana_hwc_alloc_dma_buf(hwc, q_depth, max_msg_size, | |
| 484 | − &hwc_wq->msg_buf); | |
| 485 | − if (err) | |
| 486 | − goto out; | |
| 487 | − | |
| 488 | 483 | hwc_wq->hwc = hwc; |
| 489 | 484 | hwc_wq->gdma_wq = queue; |
| 490 | 485 | hwc_wq->queue_depth = q_depth; |
| 491 | 486 | hwc_wq->hwc_cq = hwc_cq; |
| 492 | 487 | |
| 488 | + err = mana_hwc_alloc_dma_buf(hwc, q_depth, max_msg_size, | |
| 489 | + &hwc_wq->msg_buf); | |
| 490 | + if (err) | |
| 491 | + goto out; | |
| 492 | + | |
| 493 | 493 | *hwc_wq_ptr = hwc_wq; |
| 494 | 494 | return 0; |
| 495 | 495 | out: |
| @@ -1278,6 +1278,225 @@ int ocelot_fdb_dump(struct ocelot *ocelot, int port, · 1277 unmodified lines | ||
| 1278 | 1278 | } |
| 1279 | 1279 | EXPORT_SYMBOL(ocelot_fdb_dump); |
| 1280 | 1280 | |
| 1281 | +static void ocelot_populate_l2_ptp_trap_key(struct ocelot_vcap_filter *trap) | |
| 1282 | +{ | |
| 1283 | + trap->key_type = OCELOT_VCAP_KEY_ETYPE; | |
| 1284 | + *(__be16 *)trap->key.etype.etype.value = htons(ETH_P_1588); | |
| 1285 | + *(__be16 *)trap->key.etype.etype.mask = htons(0xffff); | |
| 1286 | +} | |
| 1287 | + | |
| 1288 | +static void | |
| 1289 | +ocelot_populate_ipv4_ptp_event_trap_key(struct ocelot_vcap_filter *trap) | |
| 1290 | +{ | |
| 1291 | + trap->key_type = OCELOT_VCAP_KEY_IPV4; | |
| 1292 | + trap->key.ipv4.dport.value = PTP_EV_PORT; | |
| 1293 | + trap->key.ipv4.dport.mask = 0xffff; | |
| 1294 | +} | |
| 1295 | + | |
| 1296 | +static void | |
| 1297 | +ocelot_populate_ipv6_ptp_event_trap_key(struct ocelot_vcap_filter *trap) | |
| 1298 | +{ | |
| 1299 | + trap->key_type = OCELOT_VCAP_KEY_IPV6; | |
| 1300 | + trap->key.ipv6.dport.value = PTP_EV_PORT; | |
| 1301 | + trap->key.ipv6.dport.mask = 0xffff; | |
| 1302 | +} | |
| 1303 | + | |
| 1304 | +static void | |
| 1305 | +ocelot_populate_ipv4_ptp_general_trap_key(struct ocelot_vcap_filter *trap) | |
| 1306 | +{ | |
| 1307 | + trap->key_type = OCELOT_VCAP_KEY_IPV4; | |
| 1308 | + trap->key.ipv4.dport.value = PTP_GEN_PORT; | |
| 1309 | + trap->key.ipv4.dport.mask = 0xffff; | |
| 1310 | +} | |
| 1311 | + | |
| 1312 | +static void | |
| 1313 | +ocelot_populate_ipv6_ptp_general_trap_key(struct ocelot_vcap_filter *trap) | |
| 1314 | +{ | |
| 1315 | + trap->key_type = OCELOT_VCAP_KEY_IPV6; | |
| 1316 | + trap->key.ipv6.dport.value = PTP_GEN_PORT; | |
| 1317 | + trap->key.ipv6.dport.mask = 0xffff; | |
| 1318 | +} | |
| 1319 | + | |
| 1320 | +static int ocelot_trap_add(struct ocelot *ocelot, int port, | |
| 1321 | + unsigned long cookie, | |
| 1322 | + void (*populate)(struct ocelot_vcap_filter *f)) | |
| 1323 | +{ | |
| 1324 | + struct ocelot_vcap_block *block_vcap_is2; | |
| 1325 | + struct ocelot_vcap_filter *trap; | |
| 1326 | + bool new = false; | |
| 1327 | + int err; | |
| 1328 | + | |
| 1329 | + block_vcap_is2 = &ocelot->block[VCAP_IS2]; | |
| 1330 | + | |
| 1331 | + trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie, | |
| 1332 | + false); | |
| 1333 | + if (!trap) { | |
| 1334 | + trap = kzalloc(sizeof(*trap), GFP_KERNEL); | |
| 1335 | + if (!trap) | |
| 1336 | + return -ENOMEM; | |
| 1337 | + | |
| 1338 | + populate(trap); | |
| 1339 | + trap->prio = 1; | |
| 1340 | + trap->id.cookie = cookie; | |
| 1341 | + trap->id.tc_offload = false; | |
| 1342 | + trap->block_id = VCAP_IS2; | |
| 1343 | + trap->type = OCELOT_VCAP_FILTER_OFFLOAD; | |
| 1344 | + trap->lookup = 0; | |
| 1345 | + trap->action.cpu_copy_ena = true; | |
| 1346 | + trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; | |
| 1347 | + trap->action.port_mask = 0; | |
| 1348 | + new = true; | |
| 1349 | + } | |
| 1350 | + | |
| 1351 | + trap->ingress_port_mask |= BIT(port); | |
| 1352 | + | |
| 1353 | + if (new) | |
| 1354 | + err = ocelot_vcap_filter_add(ocelot, trap, NULL); | |
| 1355 | + else | |
| 1356 | + err = ocelot_vcap_filter_replace(ocelot, trap); | |
| 1357 | + if (err) { | |
| 1358 | + trap->ingress_port_mask &= ~BIT(port); | |
| 1359 | + if (!trap->ingress_port_mask) | |
| 1360 | + kfree(trap); | |
| 1361 | + return err; | |
| 1362 | + } | |
| 1363 | + | |
| 1364 | + return 0; | |
| 1365 | +} | |
| 1366 | + | |
| 1367 | +static int ocelot_trap_del(struct ocelot *ocelot, int port, | |
| 1368 | + unsigned long cookie) | |
| 1369 | +{ | |
| 1370 | + struct ocelot_vcap_block *block_vcap_is2; | |
| 1371 | + struct ocelot_vcap_filter *trap; | |
| 1372 | + | |
| 1373 | + block_vcap_is2 = &ocelot->block[VCAP_IS2]; | |
| 1374 | + | |
| 1375 | + trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie, | |
| 1376 | + false); | |
| 1377 | + if (!trap) | |
| 1378 | + return 0; | |
| 1379 | + | |
| 1380 | + trap->ingress_port_mask &= ~BIT(port); | |
| 1381 | + if (!trap->ingress_port_mask) | |
| 1382 | + return ocelot_vcap_filter_del(ocelot, trap); | |
| 1383 | + | |
| 1384 | + return ocelot_vcap_filter_replace(ocelot, trap); | |
| 1385 | +} | |
| 1386 | + | |
| 1387 | +static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port) | |
| 1388 | +{ | |
| 1389 | + unsigned long l2_cookie = ocelot->num_phys_ports + 1; | |
| 1390 | + | |
| 1391 | + return ocelot_trap_add(ocelot, port, l2_cookie, | |
| 1392 | + ocelot_populate_l2_ptp_trap_key); | |
| 1393 | +} | |
| 1394 | + | |
| 1395 | +static int ocelot_l2_ptp_trap_del(struct ocelot *ocelot, int port) | |
| 1396 | +{ | |
| 1397 | + unsigned long l2_cookie = ocelot->num_phys_ports + 1; | |
| 1398 | + | |
| 1399 | + return ocelot_trap_del(ocelot, port, l2_cookie); | |
| 1400 | +} | |
| 1401 | + | |
| 1402 | +static int ocelot_ipv4_ptp_trap_add(struct ocelot *ocelot, int port) | |
| 1403 | +{ | |
| 1404 | + unsigned long ipv4_gen_cookie = ocelot->num_phys_ports + 2; | |
| 1405 | + unsigned long ipv4_ev_cookie = ocelot->num_phys_ports + 3; | |
| 1406 | + int err; | |
| 1407 | + | |
| 1408 | + err = ocelot_trap_add(ocelot, port, ipv4_ev_cookie, | |
| 1409 | + ocelot_populate_ipv4_ptp_event_trap_key); | |
| 1410 | + if (err) | |
| 1411 | + return err; | |
| 1412 | + | |
| 1413 | + err = ocelot_trap_add(ocelot, port, ipv4_gen_cookie, | |
| 1414 | + ocelot_populate_ipv4_ptp_general_trap_key); | |
| 1415 | + if (err) | |
| 1416 | + ocelot_trap_del(ocelot, port, ipv4_ev_cookie); | |
| 1417 | + | |
| 1418 | + return err; | |
| 1419 | +} | |
| 1420 | + | |
| 1421 | +static int ocelot_ipv4_ptp_trap_del(struct ocelot *ocelot, int port) | |
| 1422 | +{ | |
| 1423 | + unsigned long ipv4_gen_cookie = ocelot->num_phys_ports + 2; | |
| 1424 | + unsigned long ipv4_ev_cookie = ocelot->num_phys_ports + 3; | |
| 1425 | + int err; | |
| 1426 | + | |
| 1427 | + err = ocelot_trap_del(ocelot, port, ipv4_ev_cookie); | |
| 1428 | + err |= ocelot_trap_del(ocelot, port, ipv4_gen_cookie); | |
| 1429 | + return err; | |
| 1430 | +} | |
| 1431 | + | |
| 1432 | +static int ocelot_ipv6_ptp_trap_add(struct ocelot *ocelot, int port) | |
| 1433 | +{ | |
| 1434 | + unsigned long ipv6_gen_cookie = ocelot->num_phys_ports + 4; | |
| 1435 | + unsigned long ipv6_ev_cookie = ocelot->num_phys_ports + 5; | |
| 1436 | + int err; | |
| 1437 | + | |
| 1438 | + err = ocelot_trap_add(ocelot, port, ipv6_ev_cookie, | |
| 1439 | + ocelot_populate_ipv6_ptp_event_trap_key); | |
| 1440 | + if (err) | |
| 1441 | + return err; | |
| 1442 | + | |
| 1443 | + err = ocelot_trap_add(ocelot, port, ipv6_gen_cookie, | |
| 1444 | + ocelot_populate_ipv6_ptp_general_trap_key); | |
| 1445 | + if (err) | |
| 1446 | + ocelot_trap_del(ocelot, port, ipv6_ev_cookie); | |
| 1447 | + | |
| 1448 | + return err; | |
| 1449 | +} | |
| 1450 | + | |
| 1451 | +static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port) | |
| 1452 | +{ | |
| 1453 | + unsigned long ipv6_gen_cookie = ocelot->num_phys_ports + 4; | |
| 1454 | + unsigned long ipv6_ev_cookie = ocelot->num_phys_ports + 5; | |
| 1455 | + int err; | |
| 1456 | + | |
| 1457 | + err = ocelot_trap_del(ocelot, port, ipv6_ev_cookie); | |
| 1458 | + err |= ocelot_trap_del(ocelot, port, ipv6_gen_cookie); | |
| 1459 | + return err; | |
| 1460 | +} | |
| 1461 | + | |
| 1462 | +static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port, | |
| 1463 | + bool l2, bool l4) | |
| 1464 | +{ | |
| 1465 | + int err; | |
| 1466 | + | |
| 1467 | + if (l2) | |
| 1468 | + err = ocelot_l2_ptp_trap_add(ocelot, port); | |
| 1469 | + else | |
| 1470 | + err = ocelot_l2_ptp_trap_del(ocelot, port); | |
| 1471 | + if (err) | |
| 1472 | + return err; | |
| 1473 | + | |
| 1474 | + if (l4) { | |
| 1475 | + err = ocelot_ipv4_ptp_trap_add(ocelot, port); | |
| 1476 | + if (err) | |
| 1477 | + goto err_ipv4; | |
| 1478 | + | |
| 1479 | + err = ocelot_ipv6_ptp_trap_add(ocelot, port); | |
| 1480 | + if (err) | |
| 1481 | + goto err_ipv6; | |
| 1482 | + } else { | |
| 1483 | + err = ocelot_ipv4_ptp_trap_del(ocelot, port); | |
| 1484 | + | |
| 1485 | + err |= ocelot_ipv6_ptp_trap_del(ocelot, port); | |
| 1486 | + } | |
| 1487 | + if (err) | |
| 1488 | + return err; | |
| 1489 | + | |
| 1490 | + return 0; | |
| 1491 | + | |
| 1492 | +err_ipv6: | |
| 1493 | + ocelot_ipv4_ptp_trap_del(ocelot, port); | |
| 1494 | +err_ipv4: | |
| 1495 | + if (l2) | |
| 1496 | + ocelot_l2_ptp_trap_del(ocelot, port); | |
| 1497 | + return err; | |
| 1498 | +} | |
| 1499 | + | |
| 1281 | 1500 | int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) |
| 1282 | 1501 | { |
| 1283 | 1502 | return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config, |
| @@ -1288,7 +1507,9 @@ EXPORT_SYMBOL(ocelot_hwstamp_get); · 4 unmodified lines | ||
| 1288 | 1507 | int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) |
| 1289 | 1508 | { |
| 1290 | 1509 | struct ocelot_port *ocelot_port = ocelot->ports[port]; |
| 1510 | + bool l2 = false, l4 = false; | |
| 1291 | 1511 | struct hwtstamp_config cfg; |
| 1512 | + int err; | |
| 1292 | 1513 | |
| 1293 | 1514 | if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) |
| 1294 | 1515 | return -EFAULT; |
| @@ -1320,28 +1541,42 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) · 25 unmodified lines | ||
| 1320 | 1541 | switch (cfg.rx_filter) { |
| 1321 | 1542 | case HWTSTAMP_FILTER_NONE: |
| 1322 | 1543 | break; |
| 1323 | − case HWTSTAMP_FILTER_ALL: | |
| 1324 | − case HWTSTAMP_FILTER_SOME: | |
| 1325 | − case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | |
| 1326 | − case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | |
| 1327 | − case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | |
| 1328 | − case HWTSTAMP_FILTER_NTP_ALL: | |
| 1329 | 1544 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: |
| 1330 | 1545 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: |
| 1331 | 1546 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: |
| 1547 | + l4 = true; | |
| 1548 | + break; | |
| 1332 | 1549 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: |
| 1333 | 1550 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: |
| 1334 | 1551 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: |
| 1552 | + l2 = true; | |
| 1553 | + break; | |
| 1335 | 1554 | case HWTSTAMP_FILTER_PTP_V2_EVENT: |
| 1336 | 1555 | case HWTSTAMP_FILTER_PTP_V2_SYNC: |
| 1337 | 1556 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: |
| 1338 | − cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | |
| 1557 | + l2 = true; | |
| 1558 | + l4 = true; | |
| 1339 | 1559 | break; |
| 1340 | 1560 | default: |
| 1341 | 1561 | mutex_unlock(&ocelot->ptp_lock); |
| 1342 | 1562 | return -ERANGE; |
| 1343 | 1563 | } |
| 1344 | 1564 | |
| 1565 | + err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); | |
| 1566 | + if (err) { | |
| 1567 | + mutex_unlock(&ocelot->ptp_lock); | |
| 1568 | + return err; | |
| 1569 | + } | |
| 1570 | + | |
| 1571 | + if (l2 && l4) | |
| 1572 | + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | |
| 1573 | + else if (l2) | |
| 1574 | + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; | |
| 1575 | + else if (l4) | |
| 1576 | + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; | |
| 1577 | + else | |
| 1578 | + cfg.rx_filter = HWTSTAMP_FILTER_NONE; | |
| 1579 | + | |
| 1345 | 1580 | /* Commit back the result & save it */ |
| 1346 | 1581 | memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg)); |
| 1347 | 1582 | mutex_unlock(&ocelot->ptp_lock); |
| @@ -1444,7 +1679,10 @@ int ocelot_get_ts_info(struct ocelot *ocelot, int port, · 96 unmodified lines | ||
| 1444 | 1679 | SOF_TIMESTAMPING_RAW_HARDWARE; |
| 1445 | 1680 | info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) | |
| 1446 | 1681 | BIT(HWTSTAMP_TX_ONESTEP_SYNC); |
| 1447 | − info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); | |
| 1682 | + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | | |
| 1683 | + BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) | | |
| 1684 | + BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | | |
| 1685 | + BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT); | |
| 1448 | 1686 | |
| 1449 | 1687 | return 0; |
| 1450 | 1688 | } |
| @@ -1217,6 +1217,22 @@ int ocelot_vcap_filter_del(struct ocelot *ocelot, · 1216 unmodified lines | ||
| 1217 | 1217 | } |
| 1218 | 1218 | EXPORT_SYMBOL(ocelot_vcap_filter_del); |
| 1219 | 1219 | |
| 1220 | +int ocelot_vcap_filter_replace(struct ocelot *ocelot, | |
| 1221 | + struct ocelot_vcap_filter *filter) | |
| 1222 | +{ | |
| 1223 | + struct ocelot_vcap_block *block = &ocelot->block[filter->block_id]; | |
| 1224 | + int index; | |
| 1225 | + | |
| 1226 | + index = ocelot_vcap_block_get_filter_index(block, filter); | |
| 1227 | + if (index < 0) | |
| 1228 | + return index; | |
| 1229 | + | |
| 1230 | + vcap_entry_set(ocelot, index, filter); | |
| 1231 | + | |
| 1232 | + return 0; | |
| 1233 | +} | |
| 1234 | +EXPORT_SYMBOL(ocelot_vcap_filter_replace); | |
| 1235 | + | |
| 1220 | 1236 | int ocelot_vcap_filter_stats_update(struct ocelot *ocelot, |
| 1221 | 1237 | struct ocelot_vcap_filter *filter) |
| 1222 | 1238 | { |
| @@ -120,7 +120,7 @@ static const struct net_device_ops xtsonic_netdev_ops = { · 119 unmodified lines | ||
| 120 | 120 | .ndo_set_mac_address = eth_mac_addr, |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | −static int __init sonic_probe1(struct net_device *dev) | |
| 123 | +static int sonic_probe1(struct net_device *dev) | |
| 124 | 124 | { |
| 125 | 125 | unsigned int silicon_revision; |
| 126 | 126 | struct sonic_local *lp = netdev_priv(dev); |
| @@ -565,7 +565,6 @@ struct nfp_net_dp { · 564 unmodified lines | ||
| 565 | 565 | * @exn_name: Name for Exception interrupt |
| 566 | 566 | * @shared_handler: Handler for shared interrupts |
| 567 | 567 | * @shared_name: Name for shared interrupt |
| 568 | − * @me_freq_mhz: ME clock_freq (MHz) | |
| 569 | 568 | * @reconfig_lock: Protects @reconfig_posted, @reconfig_timer_active, |
| 570 | 569 | * @reconfig_sync_present and HW reconfiguration request |
| 571 | 570 | * regs/machinery from async requests (sync must take |
| @@ -650,8 +649,6 @@ struct nfp_net { · 78 unmodified lines | ||
| 650 | 649 | irq_handler_t shared_handler; |
| 651 | 650 | char shared_name[IFNAMSIZ + 8]; |
| 652 | 651 | |
| 653 | − u32 me_freq_mhz; | |
| 654 | − | |
| 655 | 652 | bool link_up; |
| 656 | 653 | spinlock_t link_status_lock; |
| 657 | 654 | |
| @@ -1344,7 +1344,7 @@ static int nfp_net_set_coalesce(struct net_device *netdev, · 1343 unmodified lines | ||
| 1344 | 1344 | * ME timestamp ticks. There are 16 ME clock cycles for each timestamp |
| 1345 | 1345 | * count. |
| 1346 | 1346 | */ |
| 1347 | − factor = nn->me_freq_mhz / 16; | |
| 1347 | + factor = nn->tlv_caps.me_freq_mhz / 16; | |
| 1348 | 1348 | |
| 1349 | 1349 | /* Each pair of (usecs, max_frames) fields specifies that interrupts |
| 1350 | 1350 | * should be coalesced until |
| @@ -803,8 +803,10 @@ int nfp_cpp_area_cache_add(struct nfp_cpp *cpp, size_t size) · 802 unmodified lines | ||
| 803 | 803 | return -ENOMEM; |
| 804 | 804 | |
| 805 | 805 | cache = kzalloc(sizeof(*cache), GFP_KERNEL); |
| 806 | − if (!cache) | |
| 806 | + if (!cache) { | |
| 807 | + nfp_cpp_area_free(area); | |
| 807 | 808 | return -ENOMEM; |
| 809 | + } | |
| 808 | 810 | |
| 809 | 811 | cache->id = 0; |
| 810 | 812 | cache->addr = 0; |
| @@ -1209,7 +1209,7 @@ static void *nixge_get_nvmem_address(struct device *dev) · 1208 unmodified lines | ||
| 1209 | 1209 | |
| 1210 | 1210 | cell = nvmem_cell_get(dev, "address"); |
| 1211 | 1211 | if (IS_ERR(cell)) |
| 1212 | − return NULL; | |
| 1212 | + return cell; | |
| 1213 | 1213 | |
| 1214 | 1214 | mac = nvmem_cell_read(cell, &cell_size); |
| 1215 | 1215 | nvmem_cell_put(cell); |
| @@ -1282,7 +1282,7 @@ static int nixge_probe(struct platform_device *pdev) · 66 unmodified lines | ||
| 1282 | 1282 | ndev->max_mtu = NIXGE_JUMBO_MTU; |
| 1283 | 1283 | |
| 1284 | 1284 | mac_addr = nixge_get_nvmem_address(&pdev->dev); |
| 1285 | − if (mac_addr && is_valid_ether_addr(mac_addr)) { | |
| 1285 | + if (!IS_ERR(mac_addr) && is_valid_ether_addr(mac_addr)) { | |
| 1286 | 1286 | eth_hw_addr_set(ndev, mac_addr); |
| 1287 | 1287 | kfree(mac_addr); |
| 1288 | 1288 | } else { |
| @@ -1045,7 +1045,7 @@ static int qed_int_deassertion(struct qed_hwfn *p_hwfn, · 1044 unmodified lines | ||
| 1045 | 1045 | if (!parities) |
| 1046 | 1046 | continue; |
| 1047 | 1047 | |
| 1048 | − for (j = 0, bit_idx = 0; bit_idx < 32; j++) { | |
| 1048 | + for (j = 0, bit_idx = 0; bit_idx < 32 && j < 32; j++) { | |
| 1049 | 1049 | struct aeu_invert_reg_bit *p_bit = &p_aeu->bits[j]; |
| 1050 | 1050 | |
| 1051 | 1051 | if (qed_int_is_parity_flag(p_hwfn, p_bit) && |
| @@ -1083,7 +1083,7 @@ static int qed_int_deassertion(struct qed_hwfn *p_hwfn, · 31 unmodified lines | ||
| 1083 | 1083 | * to current group, making them responsible for the |
| 1084 | 1084 | * previous assertion. |
| 1085 | 1085 | */ |
| 1086 | − for (j = 0, bit_idx = 0; bit_idx < 32; j++) { | |
| 1086 | + for (j = 0, bit_idx = 0; bit_idx < 32 && j < 32; j++) { | |
| 1087 | 1087 | long unsigned int bitmask; |
| 1088 | 1088 | u8 bit, bit_len; |
| 1089 | 1089 | |
| @@ -1382,7 +1382,7 @@ static void qed_int_sb_attn_init(struct qed_hwfn *p_hwfn, · 292 unmodified lines | ||
| 1382 | 1382 | memset(sb_info->parity_mask, 0, sizeof(u32) * NUM_ATTN_REGS); |
| 1383 | 1383 | for (i = 0; i < NUM_ATTN_REGS; i++) { |
| 1384 | 1384 | /* j is array index, k is bit index */ |
| 1385 | − for (j = 0, k = 0; k < 32; j++) { | |
| 1385 | + for (j = 0, k = 0; k < 32 && j < 32; j++) { | |
| 1386 | 1386 | struct aeu_invert_reg_bit *p_aeu; |
| 1387 | 1387 | |
| 1388 | 1388 | p_aeu = &aeu_descs[i].bits[j]; |
| @@ -1643,6 +1643,13 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1642 unmodified lines | ||
| 1643 | 1643 | data_split = true; |
| 1644 | 1644 | } |
| 1645 | 1645 | } else { |
| 1646 | + if (unlikely(skb->len > ETH_TX_MAX_NON_LSO_PKT_LEN)) { | |
| 1647 | + DP_ERR(edev, "Unexpected non LSO skb length = 0x%x\n", skb->len); | |
| 1648 | + qede_free_failed_tx_pkt(txq, first_bd, 0, false); | |
| 1649 | + qede_update_tx_producer(txq); | |
| 1650 | + return NETDEV_TX_OK; | |
| 1651 | + } | |
| 1652 | + | |
| 1646 | 1653 | val |= ((skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) << |
| 1647 | 1654 | ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT); |
| 1648 | 1655 | } |
| @@ -3480,20 +3480,19 @@ static int ql_adapter_up(struct ql3_adapter *qdev) · 3479 unmodified lines | ||
| 3480 | 3480 | |
| 3481 | 3481 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); |
| 3482 | 3482 | |
| 3483 | − err = ql_wait_for_drvr_lock(qdev); | |
| 3484 | − if (err) { | |
| 3485 | − err = ql_adapter_initialize(qdev); | |
| 3486 | − if (err) { | |
| 3487 | − netdev_err(ndev, "Unable to initialize adapter\n"); | |
| 3488 | − goto err_init; | |
| 3489 | − } | |
| 3490 | − netdev_err(ndev, "Releasing driver lock\n"); | |
| 3491 | − ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); | |
| 3492 | − } else { | |
| 3483 | + if (!ql_wait_for_drvr_lock(qdev)) { | |
| 3493 | 3484 | netdev_err(ndev, "Could not acquire driver lock\n"); |
| 3485 | + err = -ENODEV; | |
| 3494 | 3486 | goto err_lock; |
| 3495 | 3487 | } |
| 3496 | 3488 | |
| 3489 | + err = ql_adapter_initialize(qdev); | |
| 3490 | + if (err) { | |
| 3491 | + netdev_err(ndev, "Unable to initialize adapter\n"); | |
| 3492 | + goto err_init; | |
| 3493 | + } | |
| 3494 | + ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); | |
| 3495 | + | |
| 3497 | 3496 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); |
| 3498 | 3497 | |
| 3499 | 3498 | set_bit(QL_ADAPTER_UP, &qdev->flags); |
| @@ -1077,8 +1077,14 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter) · 1076 unmodified lines | ||
| 1077 | 1077 | sds_mbx_size = sizeof(struct qlcnic_sds_mbx); |
| 1078 | 1078 | context_id = recv_ctx->context_id; |
| 1079 | 1079 | num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS; |
| 1080 | − ahw->hw_ops->alloc_mbx_args(&cmd, adapter, | |
| 1081 | − QLCNIC_CMD_ADD_RCV_RINGS); | |
| 1080 | + err = ahw->hw_ops->alloc_mbx_args(&cmd, adapter, | |
| 1081 | + QLCNIC_CMD_ADD_RCV_RINGS); | |
| 1082 | + if (err) { | |
| 1083 | + dev_err(&adapter->pdev->dev, | |
| 1084 | + "Failed to alloc mbx args %d\n", err); | |
| 1085 | + return err; | |
| 1086 | + } | |
| 1087 | + | |
| 1082 | 1088 | cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16); |
| 1083 | 1089 | |
| 1084 | 1090 | /* set up status rings, mbx 2-81 */ |
| @@ -5217,8 +5217,8 @@ static int rtl_get_ether_clk(struct rtl8169_private *tp) · 5216 unmodified lines | ||
| 5217 | 5217 | |
| 5218 | 5218 | static void rtl_init_mac_address(struct rtl8169_private *tp) |
| 5219 | 5219 | { |
| 5220 | + u8 mac_addr[ETH_ALEN] __aligned(2) = {}; | |
| 5220 | 5221 | struct net_device *dev = tp->dev; |
| 5221 | − u8 mac_addr[ETH_ALEN]; | |
| 5222 | 5222 | int rc; |
| 5223 | 5223 | |
| 5224 | 5224 | rc = eth_platform_get_mac_address(tp_to_dev(tp), mac_addr); |
| @@ -5233,7 +5233,8 @@ static void rtl_init_mac_address(struct rtl8169_private *tp) · 8 unmodified lines | ||
| 5233 | 5233 | if (is_valid_ether_addr(mac_addr)) |
| 5234 | 5234 | goto done; |
| 5235 | 5235 | |
| 5236 | − eth_hw_addr_random(dev); | |
| 5236 | + eth_random_addr(mac_addr); | |
| 5237 | + dev->addr_assign_type = NET_ADDR_RANDOM; | |
| 5237 | 5238 | dev_warn(tp_to_dev(tp), "can't read MAC address, setting random one\n"); |
| 5238 | 5239 | done: |
| 5239 | 5240 | eth_hw_addr_set(dev, mac_addr); |
| @@ -392,7 +392,7 @@ static int sis96x_get_mac_addr(struct pci_dev *pci_dev, · 391 unmodified lines | ||
| 392 | 392 | /* get MAC address from EEPROM */ |
| 393 | 393 | for (i = 0; i < 3; i++) |
| 394 | 394 | addr[i] = read_eeprom(ioaddr, i + EEPROMMACAddr); |
| 395 | − eth_hw_addr_set(net_dev, (u8 *)addr); | |
| 395 | + eth_hw_addr_set(net_dev, (u8 *)addr); | |
| 396 | 396 | |
| 397 | 397 | rc = 1; |
| 398 | 398 | break; |
| @@ -485,8 +485,28 @@ static int socfpga_dwmac_resume(struct device *dev) · 484 unmodified lines | ||
| 485 | 485 | } |
| 486 | 486 | #endif /* CONFIG_PM_SLEEP */ |
| 487 | 487 | |
| 488 | −static SIMPLE_DEV_PM_OPS(socfpga_dwmac_pm_ops, stmmac_suspend, | |
| 489 | − socfpga_dwmac_resume); | |
| 488 | +static int __maybe_unused socfpga_dwmac_runtime_suspend(struct device *dev) | |
| 489 | +{ | |
| 490 | + struct net_device *ndev = dev_get_drvdata(dev); | |
| 491 | + struct stmmac_priv *priv = netdev_priv(ndev); | |
| 492 | + | |
| 493 | + stmmac_bus_clks_config(priv, false); | |
| 494 | + | |
| 495 | + return 0; | |
| 496 | +} | |
| 497 | + | |
| 498 | +static int __maybe_unused socfpga_dwmac_runtime_resume(struct device *dev) | |
| 499 | +{ | |
| 500 | + struct net_device *ndev = dev_get_drvdata(dev); | |
| 501 | + struct stmmac_priv *priv = netdev_priv(ndev); | |
| 502 | + | |
| 503 | + return stmmac_bus_clks_config(priv, true); | |
| 504 | +} | |
| 505 | + | |
| 506 | +static const struct dev_pm_ops socfpga_dwmac_pm_ops = { | |
| 507 | + SET_SYSTEM_SLEEP_PM_OPS(stmmac_suspend, socfpga_dwmac_resume) | |
| 508 | + SET_RUNTIME_PM_OPS(socfpga_dwmac_runtime_suspend, socfpga_dwmac_runtime_resume, NULL) | |
| 509 | +}; | |
| 490 | 510 | |
| 491 | 511 | static const struct socfpga_dwmac_ops socfpga_gen5_ops = { |
| 492 | 512 | .set_phy_mode = socfpga_gen5_set_phy_mode, |
| @@ -314,6 +314,7 @@ int stmmac_mdio_reset(struct mii_bus *mii); · 313 unmodified lines | ||
| 314 | 314 | int stmmac_xpcs_setup(struct mii_bus *mii); |
| 315 | 315 | void stmmac_set_ethtool_ops(struct net_device *netdev); |
| 316 | 316 | |
| 317 | +int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags); | |
| 317 | 318 | void stmmac_ptp_register(struct stmmac_priv *priv); |
| 318 | 319 | void stmmac_ptp_unregister(struct stmmac_priv *priv); |
| 319 | 320 | int stmmac_open(struct net_device *dev); |
| @@ -50,6 +50,13 @@ · 49 unmodified lines | ||
| 50 | 50 | #include "dwxgmac2.h" |
| 51 | 51 | #include "hwif.h" |
| 52 | 52 | |
| 53 | +/* As long as the interface is active, we keep the timestamping counter enabled | |
| 54 | + * with fine resolution and binary rollover. This avoid non-monotonic behavior | |
| 55 | + * (clock jumps) when changing timestamping settings at runtime. | |
| 56 | + */ | |
| 57 | +#define STMMAC_HWTS_ACTIVE (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | \ | |
| 58 | + PTP_TCR_TSCTRLSSR) | |
| 59 | + | |
| 53 | 60 | #define STMMAC_ALIGN(x) ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16) |
| 54 | 61 | #define TSO_MAX_BUFF_SIZE (SZ_16K - 1) |
| 55 | 62 | |
| @@ -511,6 +518,14 @@ bool stmmac_eee_init(struct stmmac_priv *priv) · 455 unmodified lines | ||
| 511 | 518 | return true; |
| 512 | 519 | } |
| 513 | 520 | |
| 521 | +static inline u32 stmmac_cdc_adjust(struct stmmac_priv *priv) | |
| 522 | +{ | |
| 523 | + /* Correct the clk domain crossing(CDC) error */ | |
| 524 | + if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) | |
| 525 | + return (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate; | |
| 526 | + return 0; | |
| 527 | +} | |
| 528 | + | |
| 514 | 529 | /* stmmac_get_tx_hwtstamp - get HW TX timestamps |
| 515 | 530 | * @priv: driver private structure |
| 516 | 531 | * @p : descriptor pointer |
| @@ -524,7 +539,6 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, · 7 unmodified lines | ||
| 524 | 539 | { |
| 525 | 540 | struct skb_shared_hwtstamps shhwtstamp; |
| 526 | 541 | bool found = false; |
| 527 | − s64 adjust = 0; | |
| 528 | 542 | u64 ns = 0; |
| 529 | 543 | |
| 530 | 544 | if (!priv->hwts_tx_en) |
| @@ -543,12 +557,7 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, · 12 unmodified lines | ||
| 543 | 557 | } |
| 544 | 558 | |
| 545 | 559 | if (found) { |
| 546 | − /* Correct the clk domain crossing(CDC) error */ | |
| 547 | − if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) { | |
| 548 | − adjust += -(2 * (NSEC_PER_SEC / | |
| 549 | − priv->plat->clk_ptp_rate)); | |
| 550 | − ns += adjust; | |
| 551 | − } | |
| 560 | + ns -= stmmac_cdc_adjust(priv); | |
| 552 | 561 | |
| 553 | 562 | memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); |
| 554 | 563 | shhwtstamp.hwtstamp = ns_to_ktime(ns); |
| @@ -573,7 +582,6 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, · 18 unmodified lines | ||
| 573 | 582 | { |
| 574 | 583 | struct skb_shared_hwtstamps *shhwtstamp = NULL; |
| 575 | 584 | struct dma_desc *desc = p; |
| 576 | − u64 adjust = 0; | |
| 577 | 585 | u64 ns = 0; |
| 578 | 586 | |
| 579 | 587 | if (!priv->hwts_rx_en) |
| @@ -586,11 +594,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, · 6 unmodified lines | ||
| 586 | 594 | if (stmmac_get_rx_timestamp_status(priv, p, np, priv->adv_ts)) { |
| 587 | 595 | stmmac_get_timestamp(priv, desc, priv->adv_ts, &ns); |
| 588 | 596 | |
| 589 | − /* Correct the clk domain crossing(CDC) error */ | |
| 590 | − if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) { | |
| 591 | − adjust += 2 * (NSEC_PER_SEC / priv->plat->clk_ptp_rate); | |
| 592 | − ns -= adjust; | |
| 593 | − } | |
| 597 | + ns -= stmmac_cdc_adjust(priv); | |
| 594 | 598 | |
| 595 | 599 | netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); |
| 596 | 600 | shhwtstamp = skb_hwtstamps(skb); |
| @@ -616,8 +620,6 @@ static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) · 19 unmodified lines | ||
| 616 | 620 | { |
| 617 | 621 | struct stmmac_priv *priv = netdev_priv(dev); |
| 618 | 622 | struct hwtstamp_config config; |
| 619 | − struct timespec64 now; | |
| 620 | − u64 temp = 0; | |
| 621 | 623 | u32 ptp_v2 = 0; |
| 622 | 624 | u32 tstamp_all = 0; |
| 623 | 625 | u32 ptp_over_ipv4_udp = 0; |
| @@ -626,11 +628,6 @@ static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) · 2 unmodified lines | ||
| 626 | 628 | u32 snap_type_sel = 0; |
| 627 | 629 | u32 ts_master_en = 0; |
| 628 | 630 | u32 ts_event_en = 0; |
| 629 | − u32 sec_inc = 0; | |
| 630 | − u32 value = 0; | |
| 631 | − bool xmac; | |
| 632 | − | |
| 633 | − xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; | |
| 634 | 631 | |
| 635 | 632 | if (!(priv->dma_cap.time_stamp || priv->adv_ts)) { |
| 636 | 633 | netdev_alert(priv->dev, "No support for HW time stamping\n"); |
| @@ -792,42 +789,17 @@ static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) · 155 unmodified lines | ||
| 792 | 789 | priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1); |
| 793 | 790 | priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON; |
| 794 | 791 | |
| 795 | − if (!priv->hwts_tx_en && !priv->hwts_rx_en) | |
| 796 | − stmmac_config_hw_tstamping(priv, priv->ptpaddr, 0); | |
| 797 | − else { | |
| 798 | − value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR | | |
| 799 | − tstamp_all | ptp_v2 | ptp_over_ethernet | | |
| 800 | − ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en | | |
| 801 | − ts_master_en | snap_type_sel); | |
| 802 | − stmmac_config_hw_tstamping(priv, priv->ptpaddr, value); | |
| 803 | − | |
| 804 | − /* program Sub Second Increment reg */ | |
| 805 | − stmmac_config_sub_second_increment(priv, | |
| 806 | − priv->ptpaddr, priv->plat->clk_ptp_rate, | |
| 807 | − xmac, &sec_inc); | |
| 808 | − temp = div_u64(1000000000ULL, sec_inc); | |
| 809 | − | |
| 810 | − /* Store sub second increment and flags for later use */ | |
| 811 | − priv->sub_second_inc = sec_inc; | |
| 812 | − priv->systime_flags = value; | |
| 813 | − | |
| 814 | − /* calculate default added value: | |
| 815 | − * formula is : | |
| 816 | − * addend = (2^32)/freq_div_ratio; | |
| 817 | − * where, freq_div_ratio = 1e9ns/sec_inc | |
| 818 | − */ | |
| 819 | − temp = (u64)(temp << 32); | |
| 820 | − priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); | |
| 821 | − stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend); | |
| 822 | − | |
| 823 | − /* initialize system time */ | |
| 824 | − ktime_get_real_ts64(&now); | |
| 792 | + priv->systime_flags = STMMAC_HWTS_ACTIVE; | |
| 825 | 793 | |
| 826 | − /* lower 32 bits of tv_sec are safe until y2106 */ | |
| 827 | − stmmac_init_systime(priv, priv->ptpaddr, | |
| 828 | − (u32)now.tv_sec, now.tv_nsec); | |
| 794 | + if (priv->hwts_tx_en || priv->hwts_rx_en) { | |
| 795 | + priv->systime_flags |= tstamp_all | ptp_v2 | | |
| 796 | + ptp_over_ethernet | ptp_over_ipv6_udp | | |
| 797 | + ptp_over_ipv4_udp | ts_event_en | | |
| 798 | + ts_master_en | snap_type_sel; | |
| 829 | 799 | } |
| 830 | 800 | |
| 801 | + stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags); | |
| 802 | + | |
| 831 | 803 | memcpy(&priv->tstamp_config, &config, sizeof(config)); |
| 832 | 804 | |
| 833 | 805 | return copy_to_user(ifr->ifr_data, &config, |
| @@ -855,6 +827,66 @@ static int stmmac_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) · 21 unmodified lines | ||
| 855 | 827 | sizeof(*config)) ? -EFAULT : 0; |
| 856 | 828 | } |
| 857 | 829 | |
| 830 | +/** | |
| 831 | + * stmmac_init_tstamp_counter - init hardware timestamping counter | |
| 832 | + * @priv: driver private structure | |
| 833 | + * @systime_flags: timestamping flags | |
| 834 | + * Description: | |
| 835 | + * Initialize hardware counter for packet timestamping. | |
| 836 | + * This is valid as long as the interface is open and not suspended. | |
| 837 | + * Will be rerun after resuming from suspend, case in which the timestamping | |
| 838 | + * flags updated by stmmac_hwtstamp_set() also need to be restored. | |
| 839 | + */ | |
| 840 | +int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags) | |
| 841 | +{ | |
| 842 | + bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; | |
| 843 | + struct timespec64 now; | |
| 844 | + u32 sec_inc = 0; | |
| 845 | + u64 temp = 0; | |
| 846 | + int ret; | |
| 847 | + | |
| 848 | + if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) | |
| 849 | + return -EOPNOTSUPP; | |
| 850 | + | |
| 851 | + ret = clk_prepare_enable(priv->plat->clk_ptp_ref); | |
| 852 | + if (ret < 0) { | |
| 853 | + netdev_warn(priv->dev, | |
| 854 | + "failed to enable PTP reference clock: %pe\n", | |
| 855 | + ERR_PTR(ret)); | |
| 856 | + return ret; | |
| 857 | + } | |
| 858 | + | |
| 859 | + stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags); | |
| 860 | + priv->systime_flags = systime_flags; | |
| 861 | + | |
| 862 | + /* program Sub Second Increment reg */ | |
| 863 | + stmmac_config_sub_second_increment(priv, priv->ptpaddr, | |
| 864 | + priv->plat->clk_ptp_rate, | |
| 865 | + xmac, &sec_inc); | |
| 866 | + temp = div_u64(1000000000ULL, sec_inc); | |
| 867 | + | |
| 868 | + /* Store sub second increment for later use */ | |
| 869 | + priv->sub_second_inc = sec_inc; | |
| 870 | + | |
| 871 | + /* calculate default added value: | |
| 872 | + * formula is : | |
| 873 | + * addend = (2^32)/freq_div_ratio; | |
| 874 | + * where, freq_div_ratio = 1e9ns/sec_inc | |
| 875 | + */ | |
| 876 | + temp = (u64)(temp << 32); | |
| 877 | + priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate); | |
| 878 | + stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend); | |
| 879 | + | |
| 880 | + /* initialize system time */ | |
| 881 | + ktime_get_real_ts64(&now); | |
| 882 | + | |
| 883 | + /* lower 32 bits of tv_sec are safe until y2106 */ | |
| 884 | + stmmac_init_systime(priv, priv->ptpaddr, (u32)now.tv_sec, now.tv_nsec); | |
| 885 | + | |
| 886 | + return 0; | |
| 887 | +} | |
| 888 | +EXPORT_SYMBOL_GPL(stmmac_init_tstamp_counter); | |
| 889 | + | |
| 858 | 890 | /** |
| 859 | 891 | * stmmac_init_ptp - init PTP |
| 860 | 892 | * @priv: driver private structure |
| @@ -865,9 +897,11 @@ static int stmmac_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) · 4 unmodified lines | ||
| 865 | 897 | static int stmmac_init_ptp(struct stmmac_priv *priv) |
| 866 | 898 | { |
| 867 | 899 | bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; |
| 900 | + int ret; | |
| 868 | 901 | |
| 869 | − if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) | |
| 870 | − return -EOPNOTSUPP; | |
| 902 | + ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE); | |
| 903 | + if (ret) | |
| 904 | + return ret; | |
| 871 | 905 | |
| 872 | 906 | priv->adv_ts = 0; |
| 873 | 907 | /* Check if adv_ts can be enabled for dwmac 4.x / xgmac core */ |
| @@ -3275,10 +3309,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) · 2401 unmodified lines | ||
| 3275 | 3309 | stmmac_mmc_setup(priv); |
| 3276 | 3310 | |
| 3277 | 3311 | if (init_ptp) { |
| 3278 | − ret = clk_prepare_enable(priv->plat->clk_ptp_ref); | |
| 3279 | − if (ret < 0) | |
| 3280 | − netdev_warn(priv->dev, "failed to enable PTP reference clock: %d\n", ret); | |
| 3281 | − | |
| 3282 | 3312 | ret = stmmac_init_ptp(priv); |
| 3283 | 3313 | if (ret == -EOPNOTSUPP) |
| 3284 | 3314 | netdev_warn(priv->dev, "PTP not supported by HW\n"); |
| @@ -3772,6 +3802,8 @@ int stmmac_release(struct net_device *dev) · 487 unmodified lines | ||
| 3772 | 3802 | struct stmmac_priv *priv = netdev_priv(dev); |
| 3773 | 3803 | u32 chan; |
| 3774 | 3804 | |
| 3805 | + netif_tx_disable(dev); | |
| 3806 | + | |
| 3775 | 3807 | if (device_may_wakeup(priv->device)) |
| 3776 | 3808 | phylink_speed_down(priv->phylink, false); |
| 3777 | 3809 | /* Stop and disconnect the PHY */ |
| @@ -5164,12 +5196,13 @@ read_again: · 1386 unmodified lines | ||
| 5164 | 5196 | if (likely(!(status & rx_not_ls)) && |
| 5165 | 5197 | (likely(priv->synopsys_id >= DWMAC_CORE_4_00) || |
| 5166 | 5198 | unlikely(status != llc_snap))) { |
| 5167 | − if (buf2_len) | |
| 5199 | + if (buf2_len) { | |
| 5168 | 5200 | buf2_len -= ETH_FCS_LEN; |
| 5169 | − else | |
| 5201 | + len -= ETH_FCS_LEN; | |
| 5202 | + } else if (buf1_len) { | |
| 5170 | 5203 | buf1_len -= ETH_FCS_LEN; |
| 5171 | − | |
| 5172 | − len -= ETH_FCS_LEN; | |
| 5204 | + len -= ETH_FCS_LEN; | |
| 5205 | + } | |
| 5173 | 5206 | } |
| 5174 | 5207 | |
| 5175 | 5208 | if (!skb) { |
| @@ -5507,8 +5540,6 @@ static int stmmac_set_features(struct net_device *netdev, · 331 unmodified lines | ||
| 5507 | 5540 | netdev_features_t features) |
| 5508 | 5541 | { |
| 5509 | 5542 | struct stmmac_priv *priv = netdev_priv(netdev); |
| 5510 | − bool sph_en; | |
| 5511 | − u32 chan; | |
| 5512 | 5543 | |
| 5513 | 5544 | /* Keep the COE Type in case of csum is supporting */ |
| 5514 | 5545 | if (features & NETIF_F_RXCSUM) |
| @@ -5520,10 +5551,13 @@ static int stmmac_set_features(struct net_device *netdev, · 5 unmodified lines | ||
| 5520 | 5551 | */ |
| 5521 | 5552 | stmmac_rx_ipc(priv, priv->hw); |
| 5522 | 5553 | |
| 5523 | − sph_en = (priv->hw->rx_csum > 0) && priv->sph; | |
| 5554 | + if (priv->sph_cap) { | |
| 5555 | + bool sph_en = (priv->hw->rx_csum > 0) && priv->sph; | |
| 5556 | + u32 chan; | |
| 5524 | 5557 | |
| 5525 | − for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++) | |
| 5526 | − stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan); | |
| 5558 | + for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++) | |
| 5559 | + stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan); | |
| 5560 | + } | |
| 5527 | 5561 | |
| 5528 | 5562 | return 0; |
| 5529 | 5563 | } |
| @@ -816,7 +816,7 @@ static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev) · 815 unmodified lines | ||
| 816 | 816 | if (ret) |
| 817 | 817 | return ret; |
| 818 | 818 | |
| 819 | − clk_prepare_enable(priv->plat->clk_ptp_ref); | |
| 819 | + stmmac_init_tstamp_counter(priv, priv->systime_flags); | |
| 820 | 820 | } |
| 821 | 821 | |
| 822 | 822 | return 0; |
| @@ -306,7 +306,6 @@ static void sp_setup(struct net_device *dev) · 305 unmodified lines | ||
| 306 | 306 | { |
| 307 | 307 | /* Finish setting up the DEVICE info. */ |
| 308 | 308 | dev->netdev_ops = &sp_netdev_ops; |
| 309 | − dev->needs_free_netdev = true; | |
| 310 | 309 | dev->mtu = SIXP_MTU; |
| 311 | 310 | dev->hard_header_len = AX25_MAX_HEADER_LEN; |
| 312 | 311 | dev->header_ops = &ax25_header_ops; |
| @@ -31,6 +31,8 @@ · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | #define AX_MTU 236 |
| 33 | 33 | |
| 34 | +/* some arch define END as assembly function ending, just undef it */ | |
| 35 | +#undef END | |
| 34 | 36 | /* SLIP/KISS protocol characters. */ |
| 35 | 37 | #define END 0300 /* indicates end of frame */ |
| 36 | 38 | #define ESC 0333 /* indicates byte stuffing */ |
| @@ -661,22 +661,6 @@ void ipa_cmd_pipeline_clear_wait(struct ipa *ipa) · 660 unmodified lines | ||
| 661 | 661 | wait_for_completion(&ipa->completion); |
| 662 | 662 | } |
| 663 | 663 | |
| 664 | −void ipa_cmd_pipeline_clear(struct ipa *ipa) | |
| 665 | −{ | |
| 666 | − u32 count = ipa_cmd_pipeline_clear_count(); | |
| 667 | − struct gsi_trans *trans; | |
| 668 | − | |
| 669 | − trans = ipa_cmd_trans_alloc(ipa, count); | |
| 670 | − if (trans) { | |
| 671 | − ipa_cmd_pipeline_clear_add(trans); | |
| 672 | − gsi_trans_commit_wait(trans); | |
| 673 | − ipa_cmd_pipeline_clear_wait(ipa); | |
| 674 | − } else { | |
| 675 | − dev_err(&ipa->pdev->dev, | |
| 676 | − "error allocating %u entry tag transaction\n", count); | |
| 677 | − } | |
| 678 | −} | |
| 679 | − | |
| 680 | 664 | static struct ipa_cmd_info * |
| 681 | 665 | ipa_cmd_info_alloc(struct ipa_endpoint *endpoint, u32 tre_count) |
| 682 | 666 | { |
| @@ -163,12 +163,6 @@ u32 ipa_cmd_pipeline_clear_count(void); · 162 unmodified lines | ||
| 163 | 163 | */ |
| 164 | 164 | void ipa_cmd_pipeline_clear_wait(struct ipa *ipa); |
| 165 | 165 | |
| 166 | −/** | |
| 167 | − * ipa_cmd_pipeline_clear() - Clear the hardware pipeline | |
| 168 | − * @ipa: - IPA pointer | |
| 169 | − */ | |
| 170 | −void ipa_cmd_pipeline_clear(struct ipa *ipa); | |
| 171 | − | |
| 172 | 166 | /** |
| 173 | 167 | * ipa_cmd_trans_alloc() - Allocate a transaction for the command TX endpoint |
| 174 | 168 | * @ipa: IPA pointer |
| @@ -853,6 +853,7 @@ static void ipa_endpoint_init_hol_block_timer(struct ipa_endpoint *endpoint, · 852 unmodified lines | ||
| 853 | 853 | u32 offset; |
| 854 | 854 | u32 val; |
| 855 | 855 | |
| 856 | + /* This should only be changed when HOL_BLOCK_EN is disabled */ | |
| 856 | 857 | offset = IPA_REG_ENDP_INIT_HOL_BLOCK_TIMER_N_OFFSET(endpoint_id); |
| 857 | 858 | val = hol_block_timer_val(ipa, microseconds); |
| 858 | 859 | iowrite32(val, ipa->reg_virt + offset); |
| @@ -868,6 +869,9 @@ ipa_endpoint_init_hol_block_enable(struct ipa_endpoint *endpoint, bool enable) · 9 unmodified lines | ||
| 868 | 869 | val = enable ? HOL_BLOCK_EN_FMASK : 0; |
| 869 | 870 | offset = IPA_REG_ENDP_INIT_HOL_BLOCK_EN_N_OFFSET(endpoint_id); |
| 870 | 871 | iowrite32(val, endpoint->ipa->reg_virt + offset); |
| 872 | + /* When enabling, the register must be written twice for IPA v4.5+ */ | |
| 873 | + if (enable && endpoint->ipa->version >= IPA_VERSION_4_5) | |
| 874 | + iowrite32(val, endpoint->ipa->reg_virt + offset); | |
| 871 | 875 | } |
| 872 | 876 | |
| 873 | 877 | void ipa_endpoint_modem_hol_block_clear_all(struct ipa *ipa) |
| @@ -880,6 +884,7 @@ void ipa_endpoint_modem_hol_block_clear_all(struct ipa *ipa) · 6 unmodified lines | ||
| 880 | 884 | if (endpoint->toward_ipa || endpoint->ee_id != GSI_EE_MODEM) |
| 881 | 885 | continue; |
| 882 | 886 | |
| 887 | + ipa_endpoint_init_hol_block_enable(endpoint, false); | |
| 883 | 888 | ipa_endpoint_init_hol_block_timer(endpoint, 0); |
| 884 | 889 | ipa_endpoint_init_hol_block_enable(endpoint, true); |
| 885 | 890 | } |
| @@ -1631,8 +1636,6 @@ void ipa_endpoint_suspend(struct ipa *ipa) · 745 unmodified lines | ||
| 1631 | 1636 | if (ipa->modem_netdev) |
| 1632 | 1637 | ipa_modem_suspend(ipa->modem_netdev); |
| 1633 | 1638 | |
| 1634 | − ipa_cmd_pipeline_clear(ipa); | |
| 1635 | − | |
| 1636 | 1639 | ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]); |
| 1637 | 1640 | ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]); |
| 1638 | 1641 | } |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include "ipa_reg.h" |
| 29 | 29 | #include "ipa_mem.h" |
| 30 | 30 | #include "ipa_table.h" |
| 31 | +#include "ipa_smp2p.h" | |
| 31 | 32 | #include "ipa_modem.h" |
| 32 | 33 | #include "ipa_uc.h" |
| 33 | 34 | #include "ipa_interrupt.h" |
| @@ -801,6 +802,11 @@ static int ipa_remove(struct platform_device *pdev) · 767 unmodified lines | ||
| 801 | 802 | struct device *dev = &pdev->dev; |
| 802 | 803 | int ret; |
| 803 | 804 | |
| 805 | + /* Prevent the modem from triggering a call to ipa_setup(). This | |
| 806 | + * also ensures a modem-initiated setup that's underway completes. | |
| 807 | + */ | |
| 808 | + ipa_smp2p_irq_disable_setup(ipa); | |
| 809 | + | |
| 804 | 810 | ret = pm_runtime_get_sync(dev); |
| 805 | 811 | if (WARN_ON(ret < 0)) |
| 806 | 812 | goto out_power_put; |
| @@ -339,9 +339,6 @@ int ipa_modem_stop(struct ipa *ipa) · 338 unmodified lines | ||
| 339 | 339 | if (state != IPA_MODEM_STATE_RUNNING) |
| 340 | 340 | return -EBUSY; |
| 341 | 341 | |
| 342 | − /* Prevent the modem from triggering a call to ipa_setup() */ | |
| 343 | − ipa_smp2p_disable(ipa); | |
| 344 | − | |
| 345 | 342 | /* Clean up the netdev and endpoints if it was started */ |
| 346 | 343 | if (netdev) { |
| 347 | 344 | struct ipa_priv *priv = netdev_priv(netdev); |
| @@ -369,6 +366,9 @@ static void ipa_modem_crashed(struct ipa *ipa) · 21 unmodified lines | ||
| 369 | 366 | struct device *dev = &ipa->pdev->dev; |
| 370 | 367 | int ret; |
| 371 | 368 | |
| 369 | + /* Prevent the modem from triggering a call to ipa_setup() */ | |
| 370 | + ipa_smp2p_irq_disable_setup(ipa); | |
| 371 | + | |
| 372 | 372 | ret = pm_runtime_get_sync(dev); |
| 373 | 373 | if (ret < 0) { |
| 374 | 374 | dev_err(dev, "error %d getting power to handle crash\n", ret); |
| @@ -52,7 +52,7 @@ static bool ipa_resource_limits_valid(struct ipa *ipa, · 51 unmodified lines | ||
| 52 | 52 | return false; |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | − group_count = data->rsrc_group_src_count; | |
| 55 | + group_count = data->rsrc_group_dst_count; | |
| 56 | 56 | if (!group_count || group_count > IPA_RESOURCE_GROUP_MAX) |
| 57 | 57 | return false; |
| 58 | 58 | |
| @@ -53,7 +53,7 @@ · 52 unmodified lines | ||
| 53 | 53 | * @setup_ready_irq: IPA interrupt triggered by modem to signal GSI ready |
| 54 | 54 | * @power_on: Whether IPA power is on |
| 55 | 55 | * @notified: Whether modem has been notified of power state |
| 56 | − * @disabled: Whether setup ready interrupt handling is disabled | |
| 56 | + * @setup_disabled: Whether setup ready interrupt handler is disabled | |
| 57 | 57 | * @mutex: Mutex protecting ready-interrupt/shutdown interlock |
| 58 | 58 | * @panic_notifier: Panic notifier structure |
| 59 | 59 | */ |
| @@ -67,7 +67,7 @@ struct ipa_smp2p { · 7 unmodified lines | ||
| 67 | 67 | u32 setup_ready_irq; |
| 68 | 68 | bool power_on; |
| 69 | 69 | bool notified; |
| 70 | − bool disabled; | |
| 70 | + bool setup_disabled; | |
| 71 | 71 | struct mutex mutex; |
| 72 | 72 | struct notifier_block panic_notifier; |
| 73 | 73 | }; |
| @@ -155,11 +155,9 @@ static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id) · 81 unmodified lines | ||
| 155 | 155 | struct device *dev; |
| 156 | 156 | int ret; |
| 157 | 157 | |
| 158 | − mutex_lock(&smp2p->mutex); | |
| 159 | − | |
| 160 | − if (smp2p->disabled) | |
| 161 | − goto out_mutex_unlock; | |
| 162 | − smp2p->disabled = true; /* If any others arrive, ignore them */ | |
| 158 | + /* Ignore any (spurious) interrupts received after the first */ | |
| 159 | + if (smp2p->ipa->setup_complete) | |
| 160 | + return IRQ_HANDLED; | |
| 163 | 161 | |
| 164 | 162 | /* Power needs to be active for setup */ |
| 165 | 163 | dev = &smp2p->ipa->pdev->dev; |
| @@ -176,8 +174,6 @@ static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id) · 10 unmodified lines | ||
| 176 | 174 | out_power_put: |
| 177 | 175 | pm_runtime_mark_last_busy(dev); |
| 178 | 176 | (void)pm_runtime_put_autosuspend(dev); |
| 179 | −out_mutex_unlock: | |
| 180 | − mutex_unlock(&smp2p->mutex); | |
| 181 | 177 | |
| 182 | 178 | return IRQ_HANDLED; |
| 183 | 179 | } |
| @@ -313,7 +309,7 @@ void ipa_smp2p_exit(struct ipa *ipa) · 129 unmodified lines | ||
| 313 | 309 | kfree(smp2p); |
| 314 | 310 | } |
| 315 | 311 | |
| 316 | −void ipa_smp2p_disable(struct ipa *ipa) | |
| 312 | +void ipa_smp2p_irq_disable_setup(struct ipa *ipa) | |
| 317 | 313 | { |
| 318 | 314 | struct ipa_smp2p *smp2p = ipa->smp2p; |
| 319 | 315 | |
| @@ -322,7 +318,10 @@ void ipa_smp2p_disable(struct ipa *ipa) · 2 unmodified lines | ||
| 322 | 318 | |
| 323 | 319 | mutex_lock(&smp2p->mutex); |
| 324 | 320 | |
| 325 | − smp2p->disabled = true; | |
| 321 | + if (!smp2p->setup_disabled) { | |
| 322 | + disable_irq(smp2p->setup_ready_irq); | |
| 323 | + smp2p->setup_disabled = true; | |
| 324 | + } | |
| 326 | 325 | |
| 327 | 326 | mutex_unlock(&smp2p->mutex); |
| 328 | 327 | } |
| @@ -27,13 +27,12 @@ int ipa_smp2p_init(struct ipa *ipa, bool modem_init); · 26 unmodified lines | ||
| 27 | 27 | void ipa_smp2p_exit(struct ipa *ipa); |
| 28 | 28 | |
| 29 | 29 | /** |
| 30 | − * ipa_smp2p_disable() - Prevent "ipa-setup-ready" interrupt handling | |
| 30 | + * ipa_smp2p_irq_disable_setup() - Disable the "setup ready" interrupt | |
| 31 | 31 | * @ipa: IPA pointer |
| 32 | 32 | * |
| 33 | − * Prevent handling of the "setup ready" interrupt from the modem. | |
| 34 | − * This is used before initiating shutdown of the driver. | |
| 33 | + * Disable the "ipa-setup-ready" interrupt from the modem. | |
| 35 | 34 | */ |
| 36 | −void ipa_smp2p_disable(struct ipa *ipa); | |
| 35 | +void ipa_smp2p_irq_disable_setup(struct ipa *ipa); | |
| 37 | 36 | |
| 38 | 37 | /** |
| 39 | 38 | * ipa_smp2p_notify_reset() - Reset modem notification state |
| @@ -61,6 +61,13 @@ static int aspeed_mdio_read(struct mii_bus *bus, int addr, int regnum) · 60 unmodified lines | ||
| 61 | 61 | |
| 62 | 62 | iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL); |
| 63 | 63 | |
| 64 | + rc = readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl, | |
| 65 | + !(ctrl & ASPEED_MDIO_CTRL_FIRE), | |
| 66 | + ASPEED_MDIO_INTERVAL_US, | |
| 67 | + ASPEED_MDIO_TIMEOUT_US); | |
| 68 | + if (rc < 0) | |
| 69 | + return rc; | |
| 70 | + | |
| 64 | 71 | rc = readl_poll_timeout(ctx->base + ASPEED_MDIO_DATA, data, |
| 65 | 72 | data & ASPEED_MDIO_DATA_IDLE, |
| 66 | 73 | ASPEED_MDIO_INTERVAL_US, |
| @@ -710,6 +710,7 @@ static void phylink_resolve(struct work_struct *w) · 709 unmodified lines | ||
| 710 | 710 | struct phylink_link_state link_state; |
| 711 | 711 | struct net_device *ndev = pl->netdev; |
| 712 | 712 | bool mac_config = false; |
| 713 | + bool retrigger = false; | |
| 713 | 714 | bool cur_link_state; |
| 714 | 715 | |
| 715 | 716 | mutex_lock(&pl->state_mutex); |
| @@ -723,6 +724,7 @@ static void phylink_resolve(struct work_struct *w) · 7 unmodified lines | ||
| 723 | 724 | link_state.link = false; |
| 724 | 725 | } else if (pl->mac_link_dropped) { |
| 725 | 726 | link_state.link = false; |
| 727 | + retrigger = true; | |
| 726 | 728 | } else { |
| 727 | 729 | switch (pl->cur_link_an_mode) { |
| 728 | 730 | case MLO_AN_PHY: |
| @@ -739,6 +741,19 @@ static void phylink_resolve(struct work_struct *w) · 10 unmodified lines | ||
| 739 | 741 | case MLO_AN_INBAND: |
| 740 | 742 | phylink_mac_pcs_get_state(pl, &link_state); |
| 741 | 743 | |
| 744 | + /* The PCS may have a latching link-fail indicator. | |
| 745 | + * If the link was up, bring the link down and | |
| 746 | + * re-trigger the resolve. Otherwise, re-read the | |
| 747 | + * PCS state to get the current status of the link. | |
| 748 | + */ | |
| 749 | + if (!link_state.link) { | |
| 750 | + if (cur_link_state) | |
| 751 | + retrigger = true; | |
| 752 | + else | |
| 753 | + phylink_mac_pcs_get_state(pl, | |
| 754 | + &link_state); | |
| 755 | + } | |
| 756 | + | |
| 742 | 757 | /* If we have a phy, the "up" state is the union of |
| 743 | 758 | * both the PHY and the MAC |
| 744 | 759 | */ |
33 more lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 262 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 162 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 220 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 1081 lines aren’t shown here.
This diff is large: its 1080 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 238 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 274 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 159 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 343 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 150 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 198 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 217 lines aren’t shown here.
This diff is large: its 175 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 221 lines aren’t shown here.
This diff is large: its 335 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 391 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 223 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 197 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 856 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 275 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 213 lines aren’t shown here.
This diff is large: its 222 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 697 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 242 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 308 lines aren’t shown here.