We need the fixes in here as well, and also resolve some merge conflicts in: drivers/misc/eeprom/at25.c
Unified · Split
| @@ -126,6 +126,8 @@ Greg Kroah-Hartman <gregkh@suse.de> · 125 unmodified lines | |||
| 126 | Greg Kroah-Hartman <greg@kroah.com> | 126 | Greg Kroah-Hartman <greg@kroah.com> |
| 127 | Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com> | 127 | Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com> |
| 128 | Gregory CLEMENT <gregory.clement@bootlin.com> <gregory.clement@free-electrons.com> | 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> | ||
| 129 | Gustavo Padovan <gustavo@las.ic.unicamp.br> | 131 | Gustavo Padovan <gustavo@las.ic.unicamp.br> |
| 130 | Gustavo Padovan <padovan@profusion.mobi> | 132 | Gustavo Padovan <padovan@profusion.mobi> |
| 131 | Hanjun Guo <guohanjun@huawei.com> <hanjun.guo@linaro.org> | 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 | :alt: disk-states-8.dot | 25 | :alt: disk-states-8.dot |
| 26 | :align: center | 26 | :align: center |
| 27 | 27 | ||
| 28 | .. kernel-figure:: node-states-8.dot | 28 | .. kernel-figure:: peer-states-8.dot |
| 29 | :alt: node-states-8.dot | 29 | :alt: peer-states-8.dot |
| 30 | :align: center | 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 | digraph peer_states { | 1 | digraph peer_states { |
| 7 | Secondary -> Primary [ label = "recv state packet" ] | 2 | Secondary -> Primary [ label = "recv state packet" ] |
| 8 | Primary -> Secondary [ label = "recv state packet" ] | 3 | Primary -> Secondary [ label = "recv state packet" ] |
| @@ -53,11 +53,10 @@ The number of bits that the PAC occupies in a pointer is 55 minus the · 52 unmodified lines | |||
| 53 | virtual address size configured by the kernel. For example, with a | 53 | virtual address size configured by the kernel. For example, with a |
| 54 | virtual address size of 48, the PAC is 7 bits wide. | 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 | 56 | When ARM64_PTR_AUTH_KERNEL is selected, the kernel will be compiled |
| 57 | address protection when passed the -msign-return-address option. This | 57 | with HINT space pointer authentication instructions protecting |
| 58 | uses instructions in the HINT space (unless -march=armv8.3-a or higher | 58 | function returns. Kernels built with this option will work on hardware |
| 59 | is also passed), and such code can run on systems without the pointer | 59 | with or without pointer authentication support. |
| 60 | authentication extension. | ||
| 61 | 60 | ||
| 62 | In addition to exec(), keys can also be reinitialized to random values | 61 | In addition to exec(), keys can also be reinitialized to random values |
| 63 | using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY, | 62 | using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY, |
| @@ -249,11 +249,16 @@ except ImportError: · 248 unmodified lines | |||
| 249 | 249 | ||
| 250 | html_static_path = ['sphinx-static'] | 250 | html_static_path = ['sphinx-static'] |
| 251 | 251 | ||
| 252 | html_context = { | 252 | html_css_files = [ |
| 253 | 'css_files': [ | 253 | 'theme_overrides.css', |
| 254 | '_static/theme_overrides.css', | 254 | ] |
| 255 | ], | 255 | |
| 256 | } | 256 | if major <= 1 and minor < 8: |
| 257 | html_context = { | ||
| 258 | 'css_files': [ | ||
| 259 | '_static/theme_overrides.css', | ||
| 260 | ], | ||
| 261 | } | ||
| 257 | 262 | ||
| 258 | # Add any extra paths that contain custom files (such as robots.txt or | 263 | # Add any extra paths that contain custom files (such as robots.txt or |
| 259 | # .htaccess) here, relative to this directory. These files are copied | 264 | # .htaccess) here, relative to this directory. These files are copied |
| @@ -73,12 +73,12 @@ CPUFREQ_POSTCHANGE. · 72 unmodified lines | |||
| 73 | The third argument is a struct cpufreq_freqs with the following | 73 | The third argument is a struct cpufreq_freqs with the following |
| 74 | values: | 74 | values: |
| 75 | 75 | ||
| 76 | ===== =========================== | 76 | ====== ====================================== |
| 77 | cpu number of the affected CPU | 77 | policy a pointer to the struct cpufreq_policy |
| 78 | old old frequency | 78 | old old frequency |
| 79 | new new frequency | 79 | new new frequency |
| 80 | flags flags of the cpufreq driver | 80 | flags flags of the cpufreq driver |
| 81 | ===== =========================== | 81 | ====== ====================================== |
| 82 | 82 | ||
| 83 | 3. CPUFreq Table Generation with Operating Performance Point (OPP) | 83 | 3. CPUFreq Table Generation with Operating Performance Point (OPP) |
| 84 | ================================================================== | 84 | ================================================================== |
| @@ -136,7 +136,7 @@ examples: · 135 unmodified lines | |||
| 136 | samsung,syscon-phandle = <&pmu_system_controller>; | 136 | samsung,syscon-phandle = <&pmu_system_controller>; |
| 137 | 137 | ||
| 138 | /* NTC thermistor is a hwmon device */ | 138 | /* NTC thermistor is a hwmon device */ |
| 139 | ncp15wb473 { | 139 | thermistor { |
| 140 | compatible = "murata,ncp15wb473"; | 140 | compatible = "murata,ncp15wb473"; |
| 141 | pullup-uv = <1800000>; | 141 | pullup-uv = <1800000>; |
| 142 | pullup-ohm = <47000>; | 142 | pullup-ohm = <47000>; |
| @@ -142,7 +142,7 @@ examples: · 141 unmodified lines | |||
| 142 | down { | 142 | down { |
| 143 | label = "GPIO Key DOWN"; | 143 | label = "GPIO Key DOWN"; |
| 144 | linux,code = <108>; | 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 | properties: | 80 | properties: |
| 81 | data-lanes: | 81 | data-lanes: |
| 82 | description: | ||
| 83 | Note that 'fsl,imx7-mipi-csi2' only supports up to 2 data lines. | ||
| 82 | items: | 84 | items: |
| 83 | minItems: 1 | 85 | minItems: 1 |
| 84 | maxItems: 4 | 86 | maxItems: 4 |
| @@ -91,18 +93,6 @@ properties: · 6 unmodified lines | |||
| 91 | required: | 93 | required: |
| 92 | - data-lanes | 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 | port@1: | 96 | port@1: |
| 107 | $ref: /schemas/graph.yaml#/properties/port | 97 | $ref: /schemas/graph.yaml#/properties/port |
| 108 | description: | 98 | description: |
| @@ -91,6 +91,14 @@ properties: · 90 unmodified lines | |||
| 91 | compensate for the board being designed with the lanes | 91 | compensate for the board being designed with the lanes |
| 92 | swapped. | 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 | eee-broken-100tx: | 102 | eee-broken-100tx: |
| 95 | $ref: /schemas/types.yaml#/definitions/flag | 103 | $ref: /schemas/types.yaml#/definitions/flag |
| 96 | description: | 104 | description: |
| @@ -29,7 +29,7 @@ properties: · 28 unmodified lines | |||
| 29 | - PHY_TYPE_PCIE | 29 | - PHY_TYPE_PCIE |
| 30 | - PHY_TYPE_SATA | 30 | - PHY_TYPE_SATA |
| 31 | - PHY_TYPE_SGMII | 31 | - PHY_TYPE_SGMII |
| 32 | - PHY_TYPE_USB | 32 | - PHY_TYPE_USB3 |
| 33 | - description: The PHY instance | 33 | - description: The PHY instance |
| 34 | minimum: 0 | 34 | minimum: 0 |
| 35 | maximum: 1 # for DP, SATA or USB | 35 | maximum: 1 # for DP, SATA or USB |
| @@ -105,7 +105,7 @@ examples: · 104 unmodified lines | |||
| 105 | reg = <0x65>; | 105 | reg = <0x65>; |
| 106 | interrupt-parent = <&gpio1>; | 106 | interrupt-parent = <&gpio1>; |
| 107 | interrupts = <16 IRQ_TYPE_EDGE_FALLING>; | 107 | interrupts = <16 IRQ_TYPE_EDGE_FALLING>; |
| 108 | ti,watchdog-timer = <0>; | 108 | ti,watchdog-timeout-ms = <0>; |
| 109 | ti,sc-ocp-limit-microamp = <2000000>; | 109 | ti,sc-ocp-limit-microamp = <2000000>; |
| 110 | ti,sc-ovp-limit-microvolt = <17800000>; | 110 | ti,sc-ovp-limit-microvolt = <17800000>; |
| 111 | monitored-battery = <&bat>; | 111 | monitored-battery = <&bat>; |
| @@ -19,6 +19,9 @@ properties: · 18 unmodified lines | |||
| 19 | clocks: | 19 | clocks: |
| 20 | maxItems: 1 | 20 | maxItems: 1 |
| 21 | 21 | ||
| 22 | interrupts: | ||
| 23 | maxItems: 1 | ||
| 24 | |||
| 22 | "#sound-dai-cells": | 25 | "#sound-dai-cells": |
| 23 | const: 0 | 26 | const: 0 |
| 24 | 27 | ||
| @@ -33,6 +33,7 @@ properties: · 32 unmodified lines | |||
| 33 | - rockchip,rk3328-spi | 33 | - rockchip,rk3328-spi |
| 34 | - rockchip,rk3368-spi | 34 | - rockchip,rk3368-spi |
| 35 | - rockchip,rk3399-spi | 35 | - rockchip,rk3399-spi |
| 36 | - rockchip,rk3568-spi | ||
| 36 | - rockchip,rv1126-spi | 37 | - rockchip,rv1126-spi |
| 37 | - const: rockchip,rk3066-spi | 38 | - const: rockchip,rk3066-spi |
| 38 | 39 | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0 | 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 | .. Contents: | 7 | .. Contents: |
| @@ -37,22 +37,22 @@ into a common call framework. · 29 unmodified lines | |||
| 37 | 37 | ||
| 38 | The following services are provided: | 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 | 44 | * Allow 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. | 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 | 47 | * Allow the netfs to expand a readahead request in both directions to meet its |
| 48 | its needs. | 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 | interleaved for a single request. | 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 | * Handle retrying of reads that failed, switching reads from the cache to the | 57 | * Handle retrying of reads that failed, switching reads from the cache to the |
| 58 | server as necessary. | 58 | server as necessary. |
| @@ -70,22 +70,22 @@ Read Helper Functions · 11 unmodified lines | |||
| 70 | 70 | ||
| 71 | Three read helpers are provided:: | 71 | Three read helpers are provided:: |
| 72 | 72 | ||
| 73 | * void netfs_readahead(struct readahead_control *ractl, | 73 | void netfs_readahead(struct readahead_control *ractl, |
| 74 | const struct netfs_read_request_ops *ops, | 74 | const struct netfs_read_request_ops *ops, |
| 75 | void *netfs_priv);`` | 75 | void *netfs_priv); |
| 76 | * int netfs_readpage(struct file *file, | 76 | int netfs_readpage(struct file *file, |
| 77 | struct page *page, | 77 | struct folio *folio, |
| 78 | const struct netfs_read_request_ops *ops, | 78 | const struct netfs_read_request_ops *ops, |
| 79 | void *netfs_priv); | 79 | void *netfs_priv); |
| 80 | * int netfs_write_begin(struct file *file, | 80 | int netfs_write_begin(struct file *file, |
| 81 | struct address_space *mapping, | 81 | struct address_space *mapping, |
| 82 | loff_t pos, | 82 | loff_t pos, |
| 83 | unsigned int len, | 83 | unsigned int len, |
| 84 | unsigned int flags, | 84 | unsigned int flags, |
| 85 | struct page **_page, | 85 | struct folio **_folio, |
| 86 | void **_fsdata, | 86 | void **_fsdata, |
| 87 | const struct netfs_read_request_ops *ops, | 87 | const struct netfs_read_request_ops *ops, |
| 88 | void *netfs_priv); | 88 | void *netfs_priv); |
| 89 | 89 | ||
| 90 | Each corresponds to a VM operation, with the addition of a couple of parameters | 90 | Each corresponds to a VM operation, with the addition of a couple of parameters |
| 91 | for the use of the read helpers: | 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 | For ->readahead() and ->readpage(), the network filesystem should just jump | 103 | For ->readahead() and ->readpage(), the network filesystem should just jump |
| 104 | into the corresponding read helper; whereas for ->write_begin(), it may be a | 104 | into the corresponding read helper; whereas for ->write_begin(), it may be a |
| 105 | little more complicated as the network filesystem might want to flush | 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 | 106 | conflicting writes or track dirty data and needs to put the acquired folio if |
| 107 | error occurs after calling the helper. | 107 | an error occurs after calling the helper. |
| 108 | 108 | ||
| 109 | The helpers manage the read request, calling back into the network filesystem | 109 | The helpers manage the read request, calling back into the network filesystem |
| 110 | through the suppplied table of operations. Waits will be performed as | 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 | void (*issue_op)(struct netfs_read_subrequest *subreq); | 253 | void (*issue_op)(struct netfs_read_subrequest *subreq); |
| 254 | bool (*is_still_valid)(struct netfs_read_request *rreq); | 254 | bool (*is_still_valid)(struct netfs_read_request *rreq); |
| 255 | int (*check_write_begin)(struct file *file, loff_t pos, unsigned len, | 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 | void (*done)(struct netfs_read_request *rreq); | 257 | void (*done)(struct netfs_read_request *rreq); |
| 258 | void (*cleanup)(struct address_space *mapping, void *netfs_priv); | 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 | There is no return value; the netfs_subreq_terminated() function should be | 314 | There is no return value; the netfs_subreq_terminated() function should be |
| 315 | called to indicate whether or not the operation succeeded and how much data | 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 | uptodate, unlocking them or dropping their refs - the helpers need to deal | 317 | uptodate, unlocking them or dropping their refs - the helpers need to deal |
| 318 | with this as they have to coordinate with copying to the local cache. | 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 | 320 | Note that the helpers have the folios locked, but not pinned. It is |
| 321 | to use the ITER_XARRAY iov iterator to refer to the range of the inode that | 321 | possible to use the ITER_XARRAY iov iterator to refer to the range of the |
| 322 | is being operated upon without the need to allocate large bvec tables. | 322 | inode that is being operated upon without the need to allocate large bvec |
| 323 | tables. | ||
| 323 | 324 | ||
| 324 | * ``is_still_valid()`` | 325 | * ``is_still_valid()`` |
| 325 | 326 | ||
| @@ -330,15 +331,15 @@ The operations are as follows: · 4 unmodified lines | |||
| 330 | * ``check_write_begin()`` | 331 | * ``check_write_begin()`` |
| 331 | 332 | ||
| 332 | [Optional] This is called from the netfs_write_begin() helper once it has | 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 | conflicting state before allowing it to be modified. | 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 | regrabbed and any other error code to abort the operation. | 338 | regrabbed and any other error code to abort the operation. |
| 338 | 339 | ||
| 339 | * ``done`` | 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 | unlocked (and marked uptodate if applicable). | 343 | unlocked (and marked uptodate if applicable). |
| 343 | 344 | ||
| 344 | * ``cleanup`` | 345 | * ``cleanup`` |
| @@ -390,7 +391,7 @@ The read helpers work by the following general procedure: · 45 unmodified lines | |||
| 390 | * If NETFS_SREQ_CLEAR_TAIL was set, a short read will be cleared to the | 391 | * If NETFS_SREQ_CLEAR_TAIL was set, a short read will be cleared to the |
| 391 | end of the slice instead of reissuing. | 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 | * Will be marked uptodate. | 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 | * Unlocked | 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 | * Synchronous operations will wait for reading to be complete. | 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 | PG_fscache mark removed when that completes. | 407 | PG_fscache mark removed when that completes. |
| 407 | 408 | ||
| 408 | * The request structures will be cleaned up when everything has completed. | 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 | netfs_io_terminated_t term_func, | 453 | netfs_io_terminated_t term_func, |
| 453 | void *term_func_priv); | 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 | int (*write)(struct netfs_cache_resources *cres, | 459 | int (*write)(struct netfs_cache_resources *cres, |
| 456 | loff_t start_pos, | 460 | loff_t start_pos, |
| 457 | struct iov_iter *iter, | 461 | struct iov_iter *iter, |
| @@ -509,6 +513,14 @@ The methods defined in the table are: · 51 unmodified lines | |||
| 509 | indicating whether the termination is definitely happening in the caller's | 513 | indicating whether the termination is definitely happening in the caller's |
| 510 | context. | 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 | * ``write()`` | 524 | * ``write()`` |
| 513 | 525 | ||
| 514 | [Required] Called to write to the cache. The start file offset is given | 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 | there isn't a read request structure as well, such as writing dirty data to the | 537 | there isn't a read request structure as well, such as writing dirty data to the |
| 526 | cache. | 538 | cache. |
| 527 | 539 | ||
| 540 | |||
| 541 | API Function Reference | ||
| 542 | ====================== | ||
| 543 | |||
| 528 | .. kernel-doc:: include/linux/netfs.h | 544 | .. kernel-doc:: include/linux/netfs.h |
| 545 | .. kernel-doc:: fs/netfs/read_helper.c | ||
| @@ -439,11 +439,9 @@ preemption. The following substitution works on both kernels:: · 438 unmodified lines | |||
| 439 | spin_lock(&p->lock); | 439 | spin_lock(&p->lock); |
| 440 | p->count += this_cpu_read(var2); | 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 | migrate_disable() ensures that the task is pinned on the current CPU which | 442 | migrate_disable() ensures that the task is pinned on the current CPU which |
| 445 | in turn guarantees that the per-CPU access to var1 and var2 are staying on | 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 | The migrate_disable() substitution is not valid for the following | 446 | The migrate_disable() substitution is not valid for the following |
| 449 | scenario:: | 447 | scenario:: |
| @@ -456,9 +454,8 @@ scenario:: · 6 unmodified lines | |||
| 456 | p = this_cpu_ptr(&var1); | 454 | p = this_cpu_ptr(&var1); |
| 457 | p->val = func2(); | 455 | p->val = func2(); |
| 458 | 456 | ||
| 459 | While correct on a non-PREEMPT_RT kernel, this breaks on PREEMPT_RT because | 457 | This breaks because migrate_disable() does not protect against reentrancy from |
| 460 | here migrate_disable() does not protect against reentrancy from a | 458 | a preempting task. A correct substitution for this case is:: |
| 461 | preempting task. A correct substitution for this case is:: | ||
| 462 | 459 | ||
| 463 | func() | 460 | func() |
| 464 | { | 461 | { |
| @@ -35,6 +35,7 @@ GNU make 3.81 make --version · 34 unmodified lines | |||
| 35 | binutils 2.23 ld -v | 35 | binutils 2.23 ld -v |
| 36 | flex 2.5.35 flex --version | 36 | flex 2.5.35 flex --version |
| 37 | bison 2.0 bison --version | 37 | bison 2.0 bison --version |
| 38 | pahole 1.16 pahole --version | ||
| 38 | util-linux 2.10o fdformat --version | 39 | util-linux 2.10o fdformat --version |
| 39 | kmod 13 depmod -V | 40 | kmod 13 depmod -V |
| 40 | e2fsprogs 1.41.4 e2fsck -V | 41 | e2fsprogs 1.41.4 e2fsck -V |
| @@ -108,6 +109,16 @@ Bison · 67 unmodified lines | |||
| 108 | Since Linux 4.16, the build system generates parsers | 109 | Since Linux 4.16, the build system generates parsers |
| 109 | during build. This requires bison 2.0 or later. | 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 | Perl | 122 | Perl |
| 112 | ---- | 123 | ---- |
| 113 | 124 | ||
| @@ -14,7 +14,8 @@ works, see Documentation/process/development-process.rst. Also, read · 13 unmodified lines | |||
| 14 | Documentation/process/submit-checklist.rst | 14 | Documentation/process/submit-checklist.rst |
| 15 | for a list of items to check before submitting code. If you are submitting | 15 | for a list of items to check before submitting code. If you are submitting |
| 16 | a driver, also read Documentation/process/submitting-drivers.rst; for device | 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 | This documentation assumes that you're using ``git`` to prepare your patches. | 20 | This documentation assumes that you're using ``git`` to prepare your patches. |
| 20 | If you're unfamiliar with ``git``, you would be well-advised to learn how to | 21 | If you're unfamiliar with ``git``, you would be well-advised to learn how to |
| @@ -9331,7 +9331,6 @@ S: Maintained · 9330 unmodified lines | |||
| 9331 | F: drivers/iio/pressure/dps310.c | 9331 | F: drivers/iio/pressure/dps310.c |
| 9332 | 9332 | ||
| 9333 | INFINIBAND SUBSYSTEM | 9333 | INFINIBAND SUBSYSTEM |
| 9334 | M: Doug Ledford <dledford@redhat.com> | ||
| 9335 | M: Jason Gunthorpe <jgg@nvidia.com> | 9334 | M: Jason Gunthorpe <jgg@nvidia.com> |
| 9336 | L: linux-rdma@vger.kernel.org | 9335 | L: linux-rdma@vger.kernel.org |
| 9337 | S: Supported | 9336 | S: Supported |
| @@ -10282,9 +10281,9 @@ F: lib/Kconfig.kcsan · 944 unmodified lines | |||
| 10282 | F: scripts/Makefile.kcsan | 10281 | F: scripts/Makefile.kcsan |
| 10283 | 10282 | ||
| 10284 | KDUMP | 10283 | KDUMP |
| 10285 | M: Dave Young <dyoung@redhat.com> | ||
| 10286 | M: Baoquan He <bhe@redhat.com> | 10284 | M: Baoquan He <bhe@redhat.com> |
| 10287 | R: Vivek Goyal <vgoyal@redhat.com> | 10285 | R: Vivek Goyal <vgoyal@redhat.com> |
| 10286 | R: Dave Young <dyoung@redhat.com> | ||
| 10288 | L: kexec@lists.infradead.org | 10287 | L: kexec@lists.infradead.org |
| 10289 | S: Maintained | 10288 | S: Maintained |
| 10290 | W: http://lse.sourceforge.net/kdump/ | 10289 | W: http://lse.sourceforge.net/kdump/ |
| @@ -12182,8 +12181,8 @@ F: drivers/net/ethernet/mellanox/mlx5/core/fpga/* · 1891 unmodified lines | |||
| 12182 | F: include/linux/mlx5/mlx5_ifc_fpga.h | 12181 | F: include/linux/mlx5/mlx5_ifc_fpga.h |
| 12183 | 12182 | ||
| 12184 | MELLANOX ETHERNET SWITCH DRIVERS | 12183 | MELLANOX ETHERNET SWITCH DRIVERS |
| 12185 | M: Jiri Pirko <jiri@nvidia.com> | ||
| 12186 | M: Ido Schimmel <idosch@nvidia.com> | 12184 | M: Ido Schimmel <idosch@nvidia.com> |
| 12185 | M: Petr Machata <petrm@nvidia.com> | ||
| 12187 | L: netdev@vger.kernel.org | 12186 | L: netdev@vger.kernel.org |
| 12188 | S: Supported | 12187 | S: Supported |
| 12189 | W: http://www.mellanox.com | 12188 | W: http://www.mellanox.com |
| @@ -15773,6 +15772,15 @@ S: Maintained · 3583 unmodified lines | |||
| 15773 | F: Documentation/devicetree/bindings/net/qcom,ethqos.txt | 15772 | F: Documentation/devicetree/bindings/net/qcom,ethqos.txt |
| 15774 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 15773 | F: drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |
| 15775 | 15774 | ||
| 15775 | QUALCOMM FASTRPC DRIVER | ||
| 15776 | M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||
| 15777 | M: Amol Maheshwari <amahesh@qti.qualcomm.com> | ||
| 15778 | L: linux-arm-msm@vger.kernel.org | ||
| 15779 | S: Maintained | ||
| 15780 | F: Documentation/devicetree/bindings/misc/qcom,fastrpc.txt | ||
| 15781 | F: drivers/misc/fastrpc.c | ||
| 15782 | F: include/uapi/misc/fastrpc.h | ||
| 15783 | |||
| 15776 | QUALCOMM GENERIC INTERFACE I2C DRIVER | 15784 | QUALCOMM GENERIC INTERFACE I2C DRIVER |
| 15777 | M: Akash Asthana <akashast@codeaurora.org> | 15785 | M: Akash Asthana <akashast@codeaurora.org> |
| 15778 | M: Mukesh Savaliya <msavaliy@codeaurora.org> | 15786 | M: Mukesh Savaliya <msavaliy@codeaurora.org> |
| @@ -15981,6 +15989,7 @@ F: arch/mips/generic/board-ranchu.c · 202 unmodified lines | |||
| 15981 | 15989 | ||
| 15982 | RANDOM NUMBER DRIVER | 15990 | RANDOM NUMBER DRIVER |
| 15983 | M: "Theodore Ts'o" <tytso@mit.edu> | 15991 | M: "Theodore Ts'o" <tytso@mit.edu> |
| 15992 | M: Jason A. Donenfeld <Jason@zx2c4.com> | ||
| 15984 | S: Maintained | 15993 | S: Maintained |
| 15985 | F: drivers/char/random.c | 15994 | F: drivers/char/random.c |
| 15986 | 15995 | ||
| @@ -16503,6 +16512,12 @@ T: git git://linuxtv.org/media_tree.git · 516 unmodified lines | |||
| 16503 | F: Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml | 16512 | F: Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml |
| 16504 | F: drivers/media/platform/sunxi/sun8i-rotate/ | 16513 | F: drivers/media/platform/sunxi/sun8i-rotate/ |
| 16505 | 16514 | ||
| 16515 | RPMSG TTY DRIVER | ||
| 16516 | M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> | ||
| 16517 | L: linux-remoteproc@vger.kernel.org | ||
| 16518 | S: Maintained | ||
| 16519 | F: drivers/tty/rpmsg_tty.c | ||
| 16520 | |||
| 16506 | RTL2830 MEDIA DRIVER | 16521 | RTL2830 MEDIA DRIVER |
| 16507 | M: Antti Palosaari <crope@iki.fi> | 16522 | M: Antti Palosaari <crope@iki.fi> |
| 16508 | L: linux-media@vger.kernel.org | 16523 | L: linux-media@vger.kernel.org |
| @@ -16624,8 +16639,8 @@ W: http://www.ibm.com/developerworks/linux/linux390/ · 115 unmodified lines | |||
| 16624 | F: drivers/iommu/s390-iommu.c | 16639 | F: drivers/iommu/s390-iommu.c |
| 16625 | 16640 | ||
| 16626 | S390 IUCV NETWORK LAYER | 16641 | S390 IUCV NETWORK LAYER |
| 16627 | M: Julian Wiedmann <jwi@linux.ibm.com> | 16642 | M: Alexandra Winter <wintera@linux.ibm.com> |
| 16628 | M: Karsten Graul <kgraul@linux.ibm.com> | 16643 | M: Wenjia Zhang <wenjia@linux.ibm.com> |
| 16629 | L: linux-s390@vger.kernel.org | 16644 | L: linux-s390@vger.kernel.org |
| 16630 | L: netdev@vger.kernel.org | 16645 | L: netdev@vger.kernel.org |
| 16631 | S: Supported | 16646 | S: Supported |
| @@ -16635,8 +16650,8 @@ F: include/net/iucv/ · 3 unmodified lines | |||
| 16635 | F: net/iucv/ | 16650 | F: net/iucv/ |
| 16636 | 16651 | ||
| 16637 | S390 NETWORK DRIVERS | 16652 | S390 NETWORK DRIVERS |
| 16638 | M: Julian Wiedmann <jwi@linux.ibm.com> | 16653 | M: Alexandra Winter <wintera@linux.ibm.com> |
| 16639 | M: Karsten Graul <kgraul@linux.ibm.com> | 16654 | M: Wenjia Zhang <wenjia@linux.ibm.com> |
| 16640 | L: linux-s390@vger.kernel.org | 16655 | L: linux-s390@vger.kernel.org |
| 16641 | L: netdev@vger.kernel.org | 16656 | L: netdev@vger.kernel.org |
| 16642 | S: Supported | 16657 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 16 | 3 | PATCHLEVEL = 16 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc3 | 5 | EXTRAVERSION = -rc5 |
| 6 | NAME = Gobble Gobble | 6 | NAME = Gobble Gobble |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -789,7 +789,7 @@ stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-strong · 780 unmodified lines | |||
| 789 | KBUILD_CFLAGS += $(stackp-flags-y) | 789 | KBUILD_CFLAGS += $(stackp-flags-y) |
| 790 | 790 | ||
| 791 | KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror | 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 | ifdef CONFIG_CC_IS_CLANG | 794 | ifdef CONFIG_CC_IS_CLANG |
| 795 | KBUILD_CPPFLAGS += -Qunused-arguments | 795 | KBUILD_CPPFLAGS += -Qunused-arguments |
| @@ -1374,17 +1374,17 @@ endif · 578 unmodified lines | |||
| 1374 | 1374 | ||
| 1375 | ifneq ($(dtstree),) | 1375 | ifneq ($(dtstree),) |
| 1376 | 1376 | ||
| 1377 | %.dtb: dt_binding_check include/config/kernel.release scripts_dtc | 1377 | %.dtb: include/config/kernel.release scripts_dtc |
| 1378 | $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ $(dtstree)/$*.dt.yaml | 1378 | $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ |
| 1379 | 1379 | ||
| 1380 | %.dtbo: dt_binding_check include/config/kernel.release scripts_dtc | 1380 | %.dtbo: include/config/kernel.release scripts_dtc |
| 1381 | $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ $(dtstree)/$*.dt.yaml | 1381 | $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ |
| 1382 | 1382 | ||
| 1383 | PHONY += dtbs dtbs_install dtbs_check | 1383 | PHONY += dtbs dtbs_install dtbs_check |
| 1384 | dtbs: include/config/kernel.release scripts_dtc | 1384 | dtbs: include/config/kernel.release scripts_dtc |
| 1385 | $(Q)$(MAKE) $(build)=$(dtstree) | 1385 | $(Q)$(MAKE) $(build)=$(dtstree) |
| 1386 | 1386 | ||
| 1387 | ifneq ($(filter dtbs_check %.dtb %.dtbo, $(MAKECMDGOALS)),) | 1387 | ifneq ($(filter dtbs_check, $(MAKECMDGOALS)),) |
| 1388 | export CHECK_DTBS=y | 1388 | export CHECK_DTBS=y |
| 1389 | dtbs: dt_binding_check | 1389 | dtbs: dt_binding_check |
| 1390 | endif | 1390 | endif |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | * Copyright The Asahi Linux Contributors | 7 | * Copyright The Asahi Linux Contributors |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <dt-bindings/gpio/gpio.h> | ||
| 10 | #include <dt-bindings/interrupt-controller/apple-aic.h> | 11 | #include <dt-bindings/interrupt-controller/apple-aic.h> |
| 11 | #include <dt-bindings/interrupt-controller/irq.h> | 12 | #include <dt-bindings/interrupt-controller/irq.h> |
| 12 | #include <dt-bindings/pinctrl/apple.h> | 13 | #include <dt-bindings/pinctrl/apple.h> |
| @@ -281,7 +282,7 @@ · 268 unmodified lines | |||
| 281 | port00: pci@0,0 { | 282 | port00: pci@0,0 { |
| 282 | device_type = "pci"; | 283 | device_type = "pci"; |
| 283 | reg = <0x0 0x0 0x0 0x0 0x0>; | 284 | reg = <0x0 0x0 0x0 0x0 0x0>; |
| 284 | reset-gpios = <&pinctrl_ap 152 0>; | 285 | reset-gpios = <&pinctrl_ap 152 GPIO_ACTIVE_LOW>; |
| 285 | max-link-speed = <2>; | 286 | max-link-speed = <2>; |
| 286 | 287 | ||
| 287 | #address-cells = <3>; | 288 | #address-cells = <3>; |
| @@ -301,7 +302,7 @@ · 13 unmodified lines | |||
| 301 | port01: pci@1,0 { | 302 | port01: pci@1,0 { |
| 302 | device_type = "pci"; | 303 | device_type = "pci"; |
| 303 | reg = <0x800 0x0 0x0 0x0 0x0>; | 304 | reg = <0x800 0x0 0x0 0x0 0x0>; |
| 304 | reset-gpios = <&pinctrl_ap 153 0>; | 305 | reset-gpios = <&pinctrl_ap 153 GPIO_ACTIVE_LOW>; |
| 305 | max-link-speed = <2>; | 306 | max-link-speed = <2>; |
| 306 | 307 | ||
| 307 | #address-cells = <3>; | 308 | #address-cells = <3>; |
| @@ -321,7 +322,7 @@ · 13 unmodified lines | |||
| 321 | port02: pci@2,0 { | 322 | port02: pci@2,0 { |
| 322 | device_type = "pci"; | 323 | device_type = "pci"; |
| 323 | reg = <0x1000 0x0 0x0 0x0 0x0>; | 324 | reg = <0x1000 0x0 0x0 0x0 0x0>; |
| 324 | reset-gpios = <&pinctrl_ap 33 0>; | 325 | reset-gpios = <&pinctrl_ap 33 GPIO_ACTIVE_LOW>; |
| 325 | max-link-speed = <1>; | 326 | max-link-speed = <1>; |
| 326 | 327 | ||
| 327 | #address-cells = <3>; | 328 | #address-cells = <3>; |
| @@ -91,7 +91,7 @@ · 90 unmodified lines | |||
| 91 | #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) | 91 | #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) |
| 92 | 92 | ||
| 93 | /* TCR_EL2 Registers bits */ | 93 | /* TCR_EL2 Registers bits */ |
| 94 | #define TCR_EL2_RES1 ((1 << 31) | (1 << 23)) | 94 | #define TCR_EL2_RES1 ((1U << 31) | (1 << 23)) |
| 95 | #define TCR_EL2_TBI (1 << 20) | 95 | #define TCR_EL2_TBI (1 << 20) |
| 96 | #define TCR_EL2_PS_SHIFT 16 | 96 | #define TCR_EL2_PS_SHIFT 16 |
| 97 | #define TCR_EL2_PS_MASK (7 << TCR_EL2_PS_SHIFT) | 97 | #define TCR_EL2_PS_MASK (7 << TCR_EL2_PS_SHIFT) |
| @@ -276,7 +276,7 @@ · 178 unmodified lines | |||
| 276 | #define CPTR_EL2_TFP_SHIFT 10 | 276 | #define CPTR_EL2_TFP_SHIFT 10 |
| 277 | 277 | ||
| 278 | /* Hyp Coprocessor Trap Register */ | 278 | /* Hyp Coprocessor Trap Register */ |
| 279 | #define CPTR_EL2_TCPAC (1 << 31) | 279 | #define CPTR_EL2_TCPAC (1U << 31) |
| 280 | #define CPTR_EL2_TAM (1 << 30) | 280 | #define CPTR_EL2_TAM (1 << 30) |
| 281 | #define CPTR_EL2_TTA (1 << 20) | 281 | #define CPTR_EL2_TTA (1 << 20) |
| 282 | #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) | 282 | #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) |
| @@ -77,11 +77,17 @@ · 76 unmodified lines | |||
| 77 | .endm | 77 | .endm |
| 78 | 78 | ||
| 79 | SYM_CODE_START(ftrace_regs_caller) | 79 | SYM_CODE_START(ftrace_regs_caller) |
| 80 | #ifdef BTI_C | ||
| 81 | BTI_C | ||
| 82 | #endif | ||
| 80 | ftrace_regs_entry 1 | 83 | ftrace_regs_entry 1 |
| 81 | b ftrace_common | 84 | b ftrace_common |
| 82 | SYM_CODE_END(ftrace_regs_caller) | 85 | SYM_CODE_END(ftrace_regs_caller) |
| 83 | 86 | ||
| 84 | SYM_CODE_START(ftrace_caller) | 87 | SYM_CODE_START(ftrace_caller) |
| 88 | #ifdef BTI_C | ||
| 89 | BTI_C | ||
| 90 | #endif | ||
| 85 | ftrace_regs_entry 0 | 91 | ftrace_regs_entry 0 |
| 86 | b ftrace_common | 92 | b ftrace_common |
| 87 | SYM_CODE_END(ftrace_caller) | 93 | SYM_CODE_END(ftrace_caller) |
| @@ -147,7 +147,7 @@ int machine_kexec_post_load(struct kimage *kimage) · 146 unmodified lines | |||
| 147 | if (rc) | 147 | if (rc) |
| 148 | return rc; | 148 | return rc; |
| 149 | kimage->arch.ttbr1 = __pa(trans_pgd); | 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 | reloc_size = __relocate_new_kernel_end - __relocate_new_kernel_start; | 152 | reloc_size = __relocate_new_kernel_end - __relocate_new_kernel_start; |
| 153 | memcpy(reloc_code, __relocate_new_kernel_start, reloc_size); | 153 | memcpy(reloc_code, __relocate_new_kernel_start, reloc_size); |
| @@ -403,6 +403,8 @@ typedef bool (*exit_handler_fn)(struct kvm_vcpu *, u64 *); · 402 unmodified lines | |||
| 403 | 403 | ||
| 404 | static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu); | 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 | * Allow the hypervisor to handle the exit with an exit handler if it has one. | 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 | static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) | 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 | if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) | 446 | if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) |
| 433 | vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR); | 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 | static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt) | 70 | static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt) |
| 71 | { | 71 | { |
| 72 | ctxt->regs.pc = read_sysreg_el2(SYS_ELR); | 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 | if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) | 80 | if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) |
| 76 | ctxt_sys_reg(ctxt, DISR_EL1) = read_sysreg_s(SYS_VDISR_EL2); | 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 | * Returns false if the guest ran in AArch32 when it shouldn't have, and | 233 | * Returns false if the guest ran in AArch32 when it shouldn't have, and |
| 234 | * thus should exit to the host, or true if a the guest run loop can continue. | 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 | struct kvm *kvm = kern_hyp_va(vcpu->kvm); | 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 | vcpu->arch.target = -1; | 248 | vcpu->arch.target = -1; |
| 249 | *exit_code &= BIT(ARM_EXIT_WITH_SERROR_BIT); | 249 | *exit_code &= BIT(ARM_EXIT_WITH_SERROR_BIT); |
| 250 | *exit_code |= ARM_EXCEPTION_IL; | 250 | *exit_code |= ARM_EXCEPTION_IL; |
| 251 | return false; | ||
| 252 | } | 251 | } |
| 253 | |||
| 254 | return true; | ||
| 255 | } | 252 | } |
| 256 | 253 | ||
| 257 | /* Switch to the guest for legacy non-VHE systems */ | 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 | /* Jump in the fire! */ | 313 | /* Jump in the fire! */ |
| 317 | exit_code = __guest_enter(vcpu); | 314 | exit_code = __guest_enter(vcpu); |
| 318 | 315 | ||
| 319 | if (unlikely(!handle_aarch32_guest(vcpu, &exit_code))) | ||
| 320 | break; | ||
| 321 | |||
| 322 | /* And we're baaack! */ | 316 | /* And we're baaack! */ |
| 323 | } while (fixup_guest_exit(vcpu, &exit_code)); | 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 | return hyp_exit_handlers; | 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 | /* Switch to the guest for VHE systems running in EL2 */ | 119 | /* Switch to the guest for VHE systems running in EL2 */ |
| 116 | static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) | 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 | asmlinkage void do_trap_fpe(struct pt_regs *regs) | 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 | return fpu_fpe(regs); | 213 | return fpu_fpe(regs); |
| 214 | #else | 214 | #else |
| 215 | do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->pc, | 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 | asmlinkage void do_trap_priv(struct pt_regs *regs) | 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 | if (user_mode(regs) && fpu_libc_helper(regs)) | 223 | if (user_mode(regs) && fpu_libc_helper(regs)) |
| 224 | return; | 224 | return; |
| 225 | #endif | 225 | #endif |
| @@ -98,7 +98,7 @@ do { \ · 97 unmodified lines | |||
| 98 | #define emit(...) __emit(__VA_ARGS__) | 98 | #define emit(...) __emit(__VA_ARGS__) |
| 99 | 99 | ||
| 100 | /* Workaround for R10000 ll/sc errata */ | 100 | /* Workaround for R10000 ll/sc errata */ |
| 101 | #ifdef CONFIG_WAR_R10000 | 101 | #ifdef CONFIG_WAR_R10000_LLSC |
| 102 | #define LLSC_beqz beqzl | 102 | #define LLSC_beqz beqzl |
| 103 | #else | 103 | #else |
| 104 | #define LLSC_beqz beqz | 104 | #define LLSC_beqz beqz |
| @@ -15,7 +15,12 @@ · 14 unmodified lines | |||
| 15 | # Mike Shaver, Helge Deller and Martin K. Petersen | 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 | KBUILD_IMAGE := vmlinuz | 22 | KBUILD_IMAGE := vmlinuz |
| 23 | endif | ||
| 19 | 24 | ||
| 20 | NM = sh $(srctree)/arch/parisc/nm | 25 | NM = sh $(srctree)/arch/parisc/nm |
| 21 | CHECKFLAGS += -D__hppa__=1 | 26 | CHECKFLAGS += -D__hppa__=1 |
| @@ -1,7 +1,9 @@ | |||
| 1 | CONFIG_LOCALVERSION="-64bit" | 1 | CONFIG_LOCALVERSION="-64bit" |
| 2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
| 3 | CONFIG_KERNEL_LZ4=y | ||
| 3 | CONFIG_SYSVIPC=y | 4 | CONFIG_SYSVIPC=y |
| 4 | CONFIG_POSIX_MQUEUE=y | 5 | CONFIG_POSIX_MQUEUE=y |
| 6 | CONFIG_AUDIT=y | ||
| 5 | CONFIG_BSD_PROCESS_ACCT=y | 7 | CONFIG_BSD_PROCESS_ACCT=y |
| 6 | CONFIG_BSD_PROCESS_ACCT_V3=y | 8 | CONFIG_BSD_PROCESS_ACCT_V3=y |
| 7 | CONFIG_TASKSTATS=y | 9 | CONFIG_TASKSTATS=y |
| @@ -35,6 +37,7 @@ CONFIG_MODVERSIONS=y · 27 unmodified lines | |||
| 35 | CONFIG_BLK_DEV_INTEGRITY=y | 37 | CONFIG_BLK_DEV_INTEGRITY=y |
| 36 | CONFIG_BINFMT_MISC=m | 38 | CONFIG_BINFMT_MISC=m |
| 37 | # CONFIG_COMPACTION is not set | 39 | # CONFIG_COMPACTION is not set |
| 40 | CONFIG_MEMORY_FAILURE=y | ||
| 38 | CONFIG_NET=y | 41 | CONFIG_NET=y |
| 39 | CONFIG_PACKET=y | 42 | CONFIG_PACKET=y |
| 40 | CONFIG_UNIX=y | 43 | CONFIG_UNIX=y |
| @@ -65,12 +68,15 @@ CONFIG_SCSI_ISCSI_ATTRS=y · 24 unmodified lines | |||
| 65 | CONFIG_SCSI_SRP_ATTRS=y | 68 | CONFIG_SCSI_SRP_ATTRS=y |
| 66 | CONFIG_ISCSI_BOOT_SYSFS=y | 69 | CONFIG_ISCSI_BOOT_SYSFS=y |
| 67 | CONFIG_SCSI_MPT2SAS=y | 70 | CONFIG_SCSI_MPT2SAS=y |
| 68 | CONFIG_SCSI_LASI700=m | 71 | CONFIG_SCSI_LASI700=y |
| 69 | CONFIG_SCSI_SYM53C8XX_2=y | 72 | CONFIG_SCSI_SYM53C8XX_2=y |
| 70 | CONFIG_SCSI_ZALON=y | 73 | CONFIG_SCSI_ZALON=y |
| 71 | CONFIG_SCSI_QLA_ISCSI=m | 74 | CONFIG_SCSI_QLA_ISCSI=m |
| 72 | CONFIG_SCSI_DH=y | 75 | CONFIG_SCSI_DH=y |
| 73 | CONFIG_ATA=y | 76 | CONFIG_ATA=y |
| 77 | CONFIG_SATA_SIL=y | ||
| 78 | CONFIG_SATA_SIS=y | ||
| 79 | CONFIG_SATA_VIA=y | ||
| 74 | CONFIG_PATA_NS87415=y | 80 | CONFIG_PATA_NS87415=y |
| 75 | CONFIG_PATA_SIL680=y | 81 | CONFIG_PATA_SIL680=y |
| 76 | CONFIG_ATA_GENERIC=y | 82 | CONFIG_ATA_GENERIC=y |
| @@ -79,6 +85,7 @@ CONFIG_MD_LINEAR=m · 2 unmodified lines | |||
| 79 | CONFIG_BLK_DEV_DM=m | 85 | CONFIG_BLK_DEV_DM=m |
| 80 | CONFIG_DM_RAID=m | 86 | CONFIG_DM_RAID=m |
| 81 | CONFIG_DM_UEVENT=y | 87 | CONFIG_DM_UEVENT=y |
| 88 | CONFIG_DM_AUDIT=y | ||
| 82 | CONFIG_FUSION=y | 89 | CONFIG_FUSION=y |
| 83 | CONFIG_FUSION_SPI=y | 90 | CONFIG_FUSION_SPI=y |
| 84 | CONFIG_FUSION_SAS=y | 91 | CONFIG_FUSION_SAS=y |
| @@ -196,10 +203,15 @@ CONFIG_FB_MATROX_G=y · 111 unmodified lines | |||
| 196 | CONFIG_FB_MATROX_I2C=y | 203 | CONFIG_FB_MATROX_I2C=y |
| 197 | CONFIG_FB_MATROX_MAVEN=y | 204 | CONFIG_FB_MATROX_MAVEN=y |
| 198 | CONFIG_FB_RADEON=y | 205 | CONFIG_FB_RADEON=y |
| 206 | CONFIG_LOGO=y | ||
| 207 | # CONFIG_LOGO_LINUX_CLUT224 is not set | ||
| 199 | CONFIG_HIDRAW=y | 208 | CONFIG_HIDRAW=y |
| 200 | CONFIG_HID_PID=y | 209 | CONFIG_HID_PID=y |
| 201 | CONFIG_USB_HIDDEV=y | 210 | CONFIG_USB_HIDDEV=y |
| 202 | CONFIG_USB=y | 211 | CONFIG_USB=y |
| 212 | CONFIG_USB_EHCI_HCD=y | ||
| 213 | CONFIG_USB_OHCI_HCD=y | ||
| 214 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
| 203 | CONFIG_UIO=y | 215 | CONFIG_UIO=y |
| 204 | CONFIG_UIO_PDRV_GENIRQ=m | 216 | CONFIG_UIO_PDRV_GENIRQ=m |
| 205 | CONFIG_UIO_AEC=m | 217 | CONFIG_UIO_AEC=m |
| @@ -39,6 +39,7 @@ verify "$3" · 38 unmodified lines | |||
| 39 | if [ -n "${INSTALLKERNEL}" ]; then | 39 | if [ -n "${INSTALLKERNEL}" ]; then |
| 40 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi | 40 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
| 41 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi | 41 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
| 42 | if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi | ||
| 42 | fi | 43 | fi |
| 43 | 44 | ||
| 44 | # Default install | 45 | # Default install |
| @@ -249,30 +249,16 @@ void __init time_init(void) · 248 unmodified lines | |||
| 249 | static int __init init_cr16_clocksource(void) | 249 | static int __init init_cr16_clocksource(void) |
| 250 | { | 250 | { |
| 251 | /* | 251 | /* |
| 252 | * The cr16 interval timers are not syncronized across CPUs on | 252 | * The cr16 interval timers are not syncronized across CPUs, even if |
| 253 | * different sockets, so mark them unstable and lower rating on | 253 | * they share the same socket. |
| 254 | * multi-socket SMP systems. | ||
| 255 | */ | 254 | */ |
| 256 | if (num_online_cpus() > 1 && !running_on_qemu) { | 255 | if (num_online_cpus() > 1 && !running_on_qemu) { |
| 257 | int cpu; | 256 | /* mark sched_clock unstable */ |
| 258 | unsigned long cpu0_loc; | 257 | clear_sched_clock_stable(); |
| 259 | cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; | 258 | |
| 260 | 259 | clocksource_cr16.name = "cr16_unstable"; | |
| 261 | for_each_online_cpu(cpu) { | 260 | clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; |
| 262 | if (cpu == 0) | 261 | clocksource_cr16.rating = 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 | } | ||
| 276 | } | 262 | } |
| 277 | 263 | ||
| 278 | /* register at clocksource framework */ | 264 | /* register at clocksource framework */ |
| @@ -12,14 +12,12 @@ · 11 unmodified lines | |||
| 12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 13 | #include <linux/kvm.h> | 13 | #include <linux/kvm.h> |
| 14 | #include <linux/kvm_types.h> | 14 | #include <linux/kvm_types.h> |
| 15 | #include <asm/csr.h> | ||
| 15 | #include <asm/kvm_vcpu_fp.h> | 16 | #include <asm/kvm_vcpu_fp.h> |
| 16 | #include <asm/kvm_vcpu_timer.h> | 17 | #include <asm/kvm_vcpu_timer.h> |
| 17 | 18 | ||
| 18 | #ifdef CONFIG_64BIT | 19 | #define KVM_MAX_VCPUS \ |
| 19 | #define KVM_MAX_VCPUS (1U << 16) | 20 | ((HGATP_VMID_MASK >> HGATP_VMID_SHIFT) + 1) |
| 20 | #else | ||
| 21 | #define KVM_MAX_VCPUS (1U << 9) | ||
| 22 | #endif | ||
| 23 | 21 | ||
| 24 | #define KVM_HALT_POLL_NS_DEFAULT 500000 | 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 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | 453 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, |
| 454 | struct kvm_memory_slot *slot) | 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 | void kvm_arch_commit_memory_region(struct kvm *kvm, | 464 | void kvm_arch_commit_memory_region(struct kvm *kvm, |
| @@ -403,7 +403,6 @@ CONFIG_DEVTMPFS=y · 402 unmodified lines | |||
| 403 | CONFIG_CONNECTOR=y | 403 | CONFIG_CONNECTOR=y |
| 404 | CONFIG_ZRAM=y | 404 | CONFIG_ZRAM=y |
| 405 | CONFIG_BLK_DEV_LOOP=m | 405 | CONFIG_BLK_DEV_LOOP=m |
| 406 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
| 407 | CONFIG_BLK_DEV_DRBD=m | 406 | CONFIG_BLK_DEV_DRBD=m |
| 408 | CONFIG_BLK_DEV_NBD=m | 407 | CONFIG_BLK_DEV_NBD=m |
| 409 | CONFIG_BLK_DEV_RAM=y | 408 | CONFIG_BLK_DEV_RAM=y |
| @@ -476,6 +475,7 @@ CONFIG_MACVLAN=m · 66 unmodified lines | |||
| 476 | CONFIG_MACVTAP=m | 475 | CONFIG_MACVTAP=m |
| 477 | CONFIG_VXLAN=m | 476 | CONFIG_VXLAN=m |
| 478 | CONFIG_BAREUDP=m | 477 | CONFIG_BAREUDP=m |
| 478 | CONFIG_AMT=m | ||
| 479 | CONFIG_TUN=m | 479 | CONFIG_TUN=m |
| 480 | CONFIG_VETH=m | 480 | CONFIG_VETH=m |
| 481 | CONFIG_VIRTIO_NET=m | 481 | CONFIG_VIRTIO_NET=m |
| @@ -489,6 +489,7 @@ CONFIG_NLMON=m · 7 unmodified lines | |||
| 489 | # CONFIG_NET_VENDOR_AMD is not set | 489 | # CONFIG_NET_VENDOR_AMD is not set |
| 490 | # CONFIG_NET_VENDOR_AQUANTIA is not set | 490 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 491 | # CONFIG_NET_VENDOR_ARC is not set | 491 | # CONFIG_NET_VENDOR_ARC is not set |
| 492 | # CONFIG_NET_VENDOR_ASIX is not set | ||
| 492 | # CONFIG_NET_VENDOR_ATHEROS is not set | 493 | # CONFIG_NET_VENDOR_ATHEROS is not set |
| 493 | # CONFIG_NET_VENDOR_BROADCOM is not set | 494 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 494 | # CONFIG_NET_VENDOR_BROCADE is not set | 495 | # CONFIG_NET_VENDOR_BROCADE is not set |
| @@ -571,6 +572,7 @@ CONFIG_WATCHDOG=y · 76 unmodified lines | |||
| 571 | CONFIG_WATCHDOG_NOWAYOUT=y | 572 | CONFIG_WATCHDOG_NOWAYOUT=y |
| 572 | CONFIG_SOFT_WATCHDOG=m | 573 | CONFIG_SOFT_WATCHDOG=m |
| 573 | CONFIG_DIAG288_WATCHDOG=m | 574 | CONFIG_DIAG288_WATCHDOG=m |
| 575 | # CONFIG_DRM_DEBUG_MODESET_LOCK is not set | ||
| 574 | CONFIG_FB=y | 576 | CONFIG_FB=y |
| 575 | CONFIG_FRAMEBUFFER_CONSOLE=y | 577 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 576 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | 578 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y |
| @@ -775,12 +777,14 @@ CONFIG_CRC4=m · 198 unmodified lines | |||
| 775 | CONFIG_CRC7=m | 777 | CONFIG_CRC7=m |
| 776 | CONFIG_CRC8=m | 778 | CONFIG_CRC8=m |
| 777 | CONFIG_RANDOM32_SELFTEST=y | 779 | CONFIG_RANDOM32_SELFTEST=y |
| 780 | CONFIG_XZ_DEC_MICROLZMA=y | ||
| 778 | CONFIG_DMA_CMA=y | 781 | CONFIG_DMA_CMA=y |
| 779 | CONFIG_CMA_SIZE_MBYTES=0 | 782 | CONFIG_CMA_SIZE_MBYTES=0 |
| 780 | CONFIG_PRINTK_TIME=y | 783 | CONFIG_PRINTK_TIME=y |
| 781 | CONFIG_DYNAMIC_DEBUG=y | 784 | CONFIG_DYNAMIC_DEBUG=y |
| 782 | CONFIG_DEBUG_INFO=y | 785 | CONFIG_DEBUG_INFO=y |
| 783 | CONFIG_DEBUG_INFO_DWARF4=y | 786 | CONFIG_DEBUG_INFO_DWARF4=y |
| 787 | CONFIG_DEBUG_INFO_BTF=y | ||
| 784 | CONFIG_GDB_SCRIPTS=y | 788 | CONFIG_GDB_SCRIPTS=y |
| 785 | CONFIG_HEADERS_INSTALL=y | 789 | CONFIG_HEADERS_INSTALL=y |
| 786 | CONFIG_DEBUG_SECTION_MISMATCH=y | 790 | CONFIG_DEBUG_SECTION_MISMATCH=y |
| @@ -807,6 +811,7 @@ CONFIG_DEBUG_MEMORY_INIT=y · 20 unmodified lines | |||
| 807 | CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m | 811 | CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m |
| 808 | CONFIG_DEBUG_PER_CPU_MAPS=y | 812 | CONFIG_DEBUG_PER_CPU_MAPS=y |
| 809 | CONFIG_KFENCE=y | 813 | CONFIG_KFENCE=y |
| 814 | CONFIG_KFENCE_STATIC_KEYS=y | ||
| 810 | CONFIG_DEBUG_SHIRQ=y | 815 | CONFIG_DEBUG_SHIRQ=y |
| 811 | CONFIG_PANIC_ON_OOPS=y | 816 | CONFIG_PANIC_ON_OOPS=y |
| 812 | CONFIG_DETECT_HUNG_TASK=y | 817 | CONFIG_DETECT_HUNG_TASK=y |
| @@ -842,6 +847,7 @@ CONFIG_FTRACE_STARTUP_TEST=y · 29 unmodified lines | |||
| 842 | CONFIG_SAMPLES=y | 847 | CONFIG_SAMPLES=y |
| 843 | CONFIG_SAMPLE_TRACE_PRINTK=m | 848 | CONFIG_SAMPLE_TRACE_PRINTK=m |
| 844 | CONFIG_SAMPLE_FTRACE_DIRECT=m | 849 | CONFIG_SAMPLE_FTRACE_DIRECT=m |
| 850 | CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m | ||
| 845 | CONFIG_DEBUG_ENTRY=y | 851 | CONFIG_DEBUG_ENTRY=y |
| 846 | CONFIG_CIO_INJECT=y | 852 | CONFIG_CIO_INJECT=y |
| 847 | CONFIG_KUNIT=m | 853 | CONFIG_KUNIT=m |
| @@ -860,7 +866,7 @@ CONFIG_FAIL_FUNCTION=y · 12 unmodified lines | |||
| 860 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y | 866 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y |
| 861 | CONFIG_LKDTM=m | 867 | CONFIG_LKDTM=m |
| 862 | CONFIG_TEST_MIN_HEAP=y | 868 | CONFIG_TEST_MIN_HEAP=y |
| 863 | CONFIG_KPROBES_SANITY_TEST=y | 869 | CONFIG_KPROBES_SANITY_TEST=m |
| 864 | CONFIG_RBTREE_TEST=y | 870 | CONFIG_RBTREE_TEST=y |
| 865 | CONFIG_INTERVAL_TREE_TEST=m | 871 | CONFIG_INTERVAL_TREE_TEST=m |
| 866 | CONFIG_PERCPU_TEST=m | 872 | CONFIG_PERCPU_TEST=m |
| @@ -394,7 +394,6 @@ CONFIG_DEVTMPFS=y · 393 unmodified lines | |||
| 394 | CONFIG_CONNECTOR=y | 394 | CONFIG_CONNECTOR=y |
| 395 | CONFIG_ZRAM=y | 395 | CONFIG_ZRAM=y |
| 396 | CONFIG_BLK_DEV_LOOP=m | 396 | CONFIG_BLK_DEV_LOOP=m |
| 397 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
| 398 | CONFIG_BLK_DEV_DRBD=m | 397 | CONFIG_BLK_DEV_DRBD=m |
| 399 | CONFIG_BLK_DEV_NBD=m | 398 | CONFIG_BLK_DEV_NBD=m |
| 400 | CONFIG_BLK_DEV_RAM=y | 399 | CONFIG_BLK_DEV_RAM=y |
| @@ -467,6 +466,7 @@ CONFIG_MACVLAN=m · 66 unmodified lines | |||
| 467 | CONFIG_MACVTAP=m | 466 | CONFIG_MACVTAP=m |
| 468 | CONFIG_VXLAN=m | 467 | CONFIG_VXLAN=m |
| 469 | CONFIG_BAREUDP=m | 468 | CONFIG_BAREUDP=m |
| 469 | CONFIG_AMT=m | ||
| 470 | CONFIG_TUN=m | 470 | CONFIG_TUN=m |
| 471 | CONFIG_VETH=m | 471 | CONFIG_VETH=m |
| 472 | CONFIG_VIRTIO_NET=m | 472 | CONFIG_VIRTIO_NET=m |
| @@ -480,6 +480,7 @@ CONFIG_NLMON=m · 7 unmodified lines | |||
| 480 | # CONFIG_NET_VENDOR_AMD is not set | 480 | # CONFIG_NET_VENDOR_AMD is not set |
| 481 | # CONFIG_NET_VENDOR_AQUANTIA is not set | 481 | # CONFIG_NET_VENDOR_AQUANTIA is not set |
| 482 | # CONFIG_NET_VENDOR_ARC is not set | 482 | # CONFIG_NET_VENDOR_ARC is not set |
| 483 | # CONFIG_NET_VENDOR_ASIX is not set | ||
| 483 | # CONFIG_NET_VENDOR_ATHEROS is not set | 484 | # CONFIG_NET_VENDOR_ATHEROS is not set |
| 484 | # CONFIG_NET_VENDOR_BROADCOM is not set | 485 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 485 | # CONFIG_NET_VENDOR_BROCADE is not set | 486 | # CONFIG_NET_VENDOR_BROCADE is not set |
| @@ -762,12 +763,14 @@ CONFIG_PRIME_NUMBERS=m · 276 unmodified lines | |||
| 762 | CONFIG_CRC4=m | 763 | CONFIG_CRC4=m |
| 763 | CONFIG_CRC7=m | 764 | CONFIG_CRC7=m |
| 764 | CONFIG_CRC8=m | 765 | CONFIG_CRC8=m |
| 766 | CONFIG_XZ_DEC_MICROLZMA=y | ||
| 765 | CONFIG_DMA_CMA=y | 767 | CONFIG_DMA_CMA=y |
| 766 | CONFIG_CMA_SIZE_MBYTES=0 | 768 | CONFIG_CMA_SIZE_MBYTES=0 |
| 767 | CONFIG_PRINTK_TIME=y | 769 | CONFIG_PRINTK_TIME=y |
| 768 | CONFIG_DYNAMIC_DEBUG=y | 770 | CONFIG_DYNAMIC_DEBUG=y |
| 769 | CONFIG_DEBUG_INFO=y | 771 | CONFIG_DEBUG_INFO=y |
| 770 | CONFIG_DEBUG_INFO_DWARF4=y | 772 | CONFIG_DEBUG_INFO_DWARF4=y |
| 773 | CONFIG_DEBUG_INFO_BTF=y | ||
| 771 | CONFIG_GDB_SCRIPTS=y | 774 | CONFIG_GDB_SCRIPTS=y |
| 772 | CONFIG_DEBUG_SECTION_MISMATCH=y | 775 | CONFIG_DEBUG_SECTION_MISMATCH=y |
| 773 | CONFIG_MAGIC_SYSRQ=y | 776 | CONFIG_MAGIC_SYSRQ=y |
| @@ -792,9 +795,11 @@ CONFIG_HIST_TRIGGERS=y · 18 unmodified lines | |||
| 792 | CONFIG_SAMPLES=y | 795 | CONFIG_SAMPLES=y |
| 793 | CONFIG_SAMPLE_TRACE_PRINTK=m | 796 | CONFIG_SAMPLE_TRACE_PRINTK=m |
| 794 | CONFIG_SAMPLE_FTRACE_DIRECT=m | 797 | CONFIG_SAMPLE_FTRACE_DIRECT=m |
| 798 | CONFIG_SAMPLE_FTRACE_DIRECT_MULTI=m | ||
| 795 | CONFIG_KUNIT=m | 799 | CONFIG_KUNIT=m |
| 796 | CONFIG_KUNIT_DEBUGFS=y | 800 | CONFIG_KUNIT_DEBUGFS=y |
| 797 | CONFIG_LKDTM=m | 801 | CONFIG_LKDTM=m |
| 802 | CONFIG_KPROBES_SANITY_TEST=m | ||
| 798 | CONFIG_PERCPU_TEST=m | 803 | CONFIG_PERCPU_TEST=m |
| 799 | CONFIG_ATOMIC64_SELFTEST=y | 804 | CONFIG_ATOMIC64_SELFTEST=y |
| 800 | CONFIG_TEST_BPF=m | 805 | CONFIG_TEST_BPF=m |
| @@ -65,9 +65,11 @@ CONFIG_ZFCP=y · 64 unmodified lines | |||
| 65 | # CONFIG_NETWORK_FILESYSTEMS is not set | 65 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 66 | CONFIG_LSM="yama,loadpin,safesetid,integrity" | 66 | CONFIG_LSM="yama,loadpin,safesetid,integrity" |
| 67 | # CONFIG_ZLIB_DFLTCC is not set | 67 | # CONFIG_ZLIB_DFLTCC is not set |
| 68 | CONFIG_XZ_DEC_MICROLZMA=y | ||
| 68 | CONFIG_PRINTK_TIME=y | 69 | CONFIG_PRINTK_TIME=y |
| 69 | # CONFIG_SYMBOLIC_ERRNAME is not set | 70 | # CONFIG_SYMBOLIC_ERRNAME is not set |
| 70 | CONFIG_DEBUG_INFO=y | 71 | CONFIG_DEBUG_INFO=y |
| 72 | CONFIG_DEBUG_INFO_BTF=y | ||
| 71 | CONFIG_DEBUG_FS=y | 73 | CONFIG_DEBUG_FS=y |
| 72 | CONFIG_DEBUG_KERNEL=y | 74 | CONFIG_DEBUG_KERNEL=y |
| 73 | CONFIG_PANIC_ON_OOPS=y | 75 | CONFIG_PANIC_ON_OOPS=y |
| @@ -14,12 +14,13 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | /* I/O Map */ | 15 | /* I/O Map */ |
| 16 | #define ZPCI_IOMAP_SHIFT 48 | 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 | #define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) | 19 | #define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) |
| 19 | #define ZPCI_IOMAP_MAX_ENTRIES \ | 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 | #define ZPCI_IOMAP_ADDR_IDX_MASK \ | 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 | struct zpci_iomap_entry { | 25 | struct zpci_iomap_entry { |
| 25 | u32 fh; | 26 | u32 fh; |
| @@ -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 | asm volatile( | 179 | asm volatile( |
| 179 | " mvcl %%r1,%%r1\n" | 180 | " .insn e,0x0000\n" /* illegal opcode */ |
| 180 | "0: nopr %%r7\n" | 181 | "0: nopr %%r7\n" |
| 181 | EX_TABLE(0b, 0b) | 182 | EX_TABLE(0b, 0b) |
| 182 | :); | 183 | :); |
| @@ -1932,6 +1932,7 @@ config EFI · 1931 unmodified lines | |||
| 1932 | depends on ACPI | 1932 | depends on ACPI |
| 1933 | select UCS2_STRING | 1933 | select UCS2_STRING |
| 1934 | select EFI_RUNTIME_WRAPPERS | 1934 | select EFI_RUNTIME_WRAPPERS |
| 1935 | select ARCH_USE_MEMREMAP_PROT | ||
| 1935 | help | 1936 | help |
| 1936 | This enables the kernel to use EFI runtime services that are | 1937 | This enables the kernel to use EFI runtime services that are |
| 1937 | available (such as the EFI variable services). | 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 | ud2 | 574 | ud2 |
| 575 | 1: | 575 | 1: |
| 576 | #endif | 576 | #endif |
| 577 | #ifdef CONFIG_XEN_PV | ||
| 578 | ALTERNATIVE "", "jmp xenpv_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV | ||
| 579 | #endif | ||
| 580 | |||
| 577 | POP_REGS pop_rdi=0 | 581 | POP_REGS pop_rdi=0 |
| 578 | 582 | ||
| 579 | /* | 583 | /* |
| @@ -890,6 +894,7 @@ SYM_CODE_START_LOCAL(paranoid_entry) · 310 unmodified lines | |||
| 890 | .Lparanoid_entry_checkgs: | 894 | .Lparanoid_entry_checkgs: |
| 891 | /* EBX = 1 -> kernel GSBASE active, no restore required */ | 895 | /* EBX = 1 -> kernel GSBASE active, no restore required */ |
| 892 | movl $1, %ebx | 896 | movl $1, %ebx |
| 897 | |||
| 893 | /* | 898 | /* |
| 894 | * The kernel-enforced convention is a negative GSBASE indicates | 899 | * The kernel-enforced convention is a negative GSBASE indicates |
| 895 | * a kernel value. No SWAPGS needed on entry and exit. | 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 | movl $MSR_GS_BASE, %ecx | 902 | movl $MSR_GS_BASE, %ecx |
| 898 | rdmsr | 903 | rdmsr |
| 899 | testl %edx, %edx | 904 | testl %edx, %edx |
| 900 | jns .Lparanoid_entry_swapgs | 905 | js .Lparanoid_kernel_gsbase |
| 901 | ret | ||
| 902 | 906 | ||
| 903 | .Lparanoid_entry_swapgs: | 907 | /* EBX = 0 -> SWAPGS required on exit */ |
| 908 | xorl %ebx, %ebx | ||
| 904 | swapgs | 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 | FENCE_SWAPGS_KERNEL_ENTRY | 912 | FENCE_SWAPGS_KERNEL_ENTRY |
| 912 | |||
| 913 | /* EBX = 0 -> SWAPGS required on exit */ | ||
| 914 | xorl %ebx, %ebx | ||
| 915 | ret | 913 | ret |
| 916 | SYM_CODE_END(paranoid_entry) | 914 | SYM_CODE_END(paranoid_entry) |
| 917 | 915 | ||
| @@ -993,11 +991,6 @@ SYM_CODE_START_LOCAL(error_entry) · 75 unmodified lines | |||
| 993 | pushq %r12 | 991 | pushq %r12 |
| 994 | ret | 992 | ret |
| 995 | 993 | ||
| 996 | .Lerror_entry_done_lfence: | ||
| 997 | FENCE_SWAPGS_KERNEL_ENTRY | ||
| 998 | .Lerror_entry_done: | ||
| 999 | ret | ||
| 1000 | |||
| 1001 | /* | 994 | /* |
| 1002 | * There are two places in the kernel that can potentially fault with | 995 | * There are two places in the kernel that can potentially fault with |
| 1003 | * usergs. Handle them here. B stepping K8s sometimes report a | 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 | * .Lgs_change's error handler with kernel gsbase. | 1013 | * .Lgs_change's error handler with kernel gsbase. |
| 1021 | */ | 1014 | */ |
| 1022 | SWAPGS | 1015 | SWAPGS |
| 1023 | FENCE_SWAPGS_USER_ENTRY | 1016 | |
| 1024 | jmp .Lerror_entry_done | 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 | .Lbstep_iret: | 1025 | .Lbstep_iret: |
| 1027 | /* Fix truncated RIP */ | 1026 | /* Fix truncated RIP */ |
| @@ -108,7 +108,7 @@ · 107 unmodified lines | |||
| 108 | #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ | 108 | #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ |
| 109 | #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ | 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 | /* "Small Core" Processors (Atom) */ | 113 | /* "Small Core" Processors (Atom) */ |
| 114 | 114 | ||
| @@ -97,7 +97,7 @@ · 96 unmodified lines | |||
| 97 | KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) | 97 | KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) |
| 98 | #define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26) | 98 | #define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26) |
| 99 | #define KVM_REQ_TLB_FLUSH_GUEST \ | 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 | #define KVM_REQ_APF_READY KVM_ARCH_REQ(28) | 101 | #define KVM_REQ_APF_READY KVM_ARCH_REQ(28) |
| 102 | #define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29) | 102 | #define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29) |
| 103 | #define KVM_REQ_UPDATE_CPU_DIRTY_LOGGING \ | 103 | #define KVM_REQ_UPDATE_CPU_DIRTY_LOGGING \ |
| @@ -1036,6 +1036,7 @@ struct kvm_x86_msr_filter { · 932 unmodified lines | |||
| 1036 | #define APICV_INHIBIT_REASON_PIT_REINJ 4 | 1036 | #define APICV_INHIBIT_REASON_PIT_REINJ 4 |
| 1037 | #define APICV_INHIBIT_REASON_X2APIC 5 | 1037 | #define APICV_INHIBIT_REASON_X2APIC 5 |
| 1038 | #define APICV_INHIBIT_REASON_BLOCKIRQ 6 | 1038 | #define APICV_INHIBIT_REASON_BLOCKIRQ 6 |
| 1039 | #define APICV_INHIBIT_REASON_ABSENT 7 | ||
| 1039 | 1040 | ||
| 1040 | struct kvm_arch { | 1041 | struct kvm_arch { |
| 1041 | unsigned long n_used_mmu_pages; | 1042 | unsigned long n_used_mmu_pages; |
| @@ -73,4 +73,15 @@ · 72 unmodified lines | |||
| 73 | 73 | ||
| 74 | #define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK) | 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 | #endif | 87 | #endif |
| @@ -118,7 +118,7 @@ static inline bool save_xstate_epilog(void __user *buf, int ia32_frame, · 117 unmodified lines | |||
| 118 | struct fpstate *fpstate) | 118 | struct fpstate *fpstate) |
| 119 | { | 119 | { |
| 120 | struct xregs_state __user *x = buf; | 120 | struct xregs_state __user *x = buf; |
| 121 | struct _fpx_sw_bytes sw_bytes; | 121 | struct _fpx_sw_bytes sw_bytes = {}; |
| 122 | u32 xfeatures; | 122 | u32 xfeatures; |
| 123 | int err; | 123 | int err; |
| 124 | 124 | ||
| @@ -294,11 +294,6 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, · 293 unmodified lines | |||
| 294 | char *dst, char *buf, size_t size) | 294 | char *dst, char *buf, size_t size) |
| 295 | { | 295 | { |
| 296 | unsigned long error_code = X86_PF_PROT | X86_PF_WRITE; | 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 | * This function uses __put_user() independent of whether kernel or user | 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 | * instructions here would cause infinite nesting. | 315 | * instructions here would cause infinite nesting. |
| 321 | */ | 316 | */ |
| 322 | switch (size) { | 317 | switch (size) { |
| 323 | case 1: | 318 | case 1: { |
| 319 | u8 d1; | ||
| 320 | u8 __user *target = (u8 __user *)dst; | ||
| 321 | |||
| 324 | memcpy(&d1, buf, 1); | 322 | memcpy(&d1, buf, 1); |
| 325 | if (__put_user(d1, target)) | 323 | if (__put_user(d1, target)) |
| 326 | goto fault; | 324 | goto fault; |
| 327 | break; | 325 | break; |
| 328 | case 2: | 326 | } |
| 327 | case 2: { | ||
| 328 | u16 d2; | ||
| 329 | u16 __user *target = (u16 __user *)dst; | ||
| 330 | |||
| 329 | memcpy(&d2, buf, 2); | 331 | memcpy(&d2, buf, 2); |
| 330 | if (__put_user(d2, target)) | 332 | if (__put_user(d2, target)) |
| 331 | goto fault; | 333 | goto fault; |
| 332 | break; | 334 | break; |
| 333 | case 4: | 335 | } |
| 336 | case 4: { | ||
| 337 | u32 d4; | ||
| 338 | u32 __user *target = (u32 __user *)dst; | ||
| 339 | |||
| 334 | memcpy(&d4, buf, 4); | 340 | memcpy(&d4, buf, 4); |
| 335 | if (__put_user(d4, target)) | 341 | if (__put_user(d4, target)) |
| 336 | goto fault; | 342 | goto fault; |
| 337 | break; | 343 | break; |
| 338 | case 8: | 344 | } |
| 345 | case 8: { | ||
| 346 | u64 d8; | ||
| 347 | u64 __user *target = (u64 __user *)dst; | ||
| 348 | |||
| 339 | memcpy(&d8, buf, 8); | 349 | memcpy(&d8, buf, 8); |
| 340 | if (__put_user(d8, target)) | 350 | if (__put_user(d8, target)) |
| 341 | goto fault; | 351 | goto fault; |
| 342 | break; | 352 | break; |
| 353 | } | ||
| 343 | default: | 354 | default: |
| 344 | WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); | 355 | WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); |
| 345 | return ES_UNSUPPORTED; | 356 | return ES_UNSUPPORTED; |
| @@ -362,11 +373,6 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, · 16 unmodified lines | |||
| 362 | char *src, char *buf, size_t size) | 373 | char *src, char *buf, size_t size) |
| 363 | { | 374 | { |
| 364 | unsigned long error_code = X86_PF_PROT; | 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 | * This function uses __get_user() independent of whether kernel or user | 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 | * instructions here would cause infinite nesting. | 394 | * instructions here would cause infinite nesting. |
| 389 | */ | 395 | */ |
| 390 | switch (size) { | 396 | switch (size) { |
| 391 | case 1: | 397 | case 1: { |
| 398 | u8 d1; | ||
| 399 | u8 __user *s = (u8 __user *)src; | ||
| 400 | |||
| 392 | if (__get_user(d1, s)) | 401 | if (__get_user(d1, s)) |
| 393 | goto fault; | 402 | goto fault; |
| 394 | memcpy(buf, &d1, 1); | 403 | memcpy(buf, &d1, 1); |
| 395 | break; | 404 | break; |
| 396 | case 2: | 405 | } |
| 406 | case 2: { | ||
| 407 | u16 d2; | ||
| 408 | u16 __user *s = (u16 __user *)src; | ||
| 409 | |||
| 397 | if (__get_user(d2, s)) | 410 | if (__get_user(d2, s)) |
| 398 | goto fault; | 411 | goto fault; |
| 399 | memcpy(buf, &d2, 2); | 412 | memcpy(buf, &d2, 2); |
| 400 | break; | 413 | break; |
| 401 | case 4: | 414 | } |
| 415 | case 4: { | ||
| 416 | u32 d4; | ||
| 417 | u32 __user *s = (u32 __user *)src; | ||
| 418 | |||
| 402 | if (__get_user(d4, s)) | 419 | if (__get_user(d4, s)) |
| 403 | goto fault; | 420 | goto fault; |
| 404 | memcpy(buf, &d4, 4); | 421 | memcpy(buf, &d4, 4); |
| 405 | break; | 422 | break; |
| 406 | case 8: | 423 | } |
| 424 | case 8: { | ||
| 425 | u64 d8; | ||
| 426 | u64 __user *s = (u64 __user *)src; | ||
| 407 | if (__get_user(d8, s)) | 427 | if (__get_user(d8, s)) |
| 408 | goto fault; | 428 | goto fault; |
| 409 | memcpy(buf, &d8, 8); | 429 | memcpy(buf, &d8, 8); |
| 410 | break; | 430 | break; |
| 431 | } | ||
| 411 | default: | 432 | default: |
| 412 | WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); | 433 | WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); |
| 413 | return ES_UNSUPPORTED; | 434 | return ES_UNSUPPORTED; |
| @@ -579,6 +579,17 @@ static struct sched_domain_topology_level x86_numa_in_package_topology[] = { · 578 unmodified lines | |||
| 579 | { NULL, }, | 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 | static struct sched_domain_topology_level x86_topology[] = { | 593 | static struct sched_domain_topology_level x86_topology[] = { |
| 583 | #ifdef CONFIG_SCHED_SMT | 594 | #ifdef CONFIG_SCHED_SMT |
| 584 | { cpu_smt_mask, x86_smt_flags, SD_INIT_NAME(SMT) }, | 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 | calculate_max_logical_packages(); | 1481 | calculate_max_logical_packages(); |
| 1471 | 1482 | ||
| 1483 | /* XXX for now assume numa-in-package and hybrid don't overlap */ | ||
| 1472 | if (x86_has_numa_in_package) | 1484 | if (x86_has_numa_in_package) |
| 1473 | set_sched_topology(x86_numa_in_package_topology); | 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 | nmi_selftest(); | 1489 | nmi_selftest(); |
| 1476 | impress_friends(); | 1490 | impress_friends(); |
| @@ -1180,6 +1180,12 @@ void mark_tsc_unstable(char *reason) · 1179 unmodified lines | |||
| 1180 | 1180 | ||
| 1181 | EXPORT_SYMBOL_GPL(mark_tsc_unstable); | 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 | static void __init check_system_tsc_reliable(void) | 1189 | static void __init check_system_tsc_reliable(void) |
| 1184 | { | 1190 | { |
| 1185 | #if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC) | 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 | #endif | 1202 | #endif |
| 1197 | if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) | 1203 | if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) |
| 1198 | tsc_clocksource_reliable = 1; | 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 | if (tsc_unstable) | 1410 | if (tsc_unstable) |
| 1388 | goto unreg; | 1411 | goto unreg; |
| 1389 | 1412 | ||
| 1390 | if (tsc_clocksource_reliable || no_tsc_watchdog) | ||
| 1391 | clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; | ||
| 1392 | |||
| 1393 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3)) | 1413 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3)) |
| 1394 | clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; | 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 | if (tsc_clocksource_reliable || no_tsc_watchdog) | 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 | clocksource_register_khz(&clocksource_tsc_early, tsc_khz); | 1552 | clocksource_register_khz(&clocksource_tsc_early, tsc_khz); |
| 1533 | detect_art(); | 1553 | detect_art(); |
| @@ -30,6 +30,7 @@ struct tsc_adjust { · 29 unmodified lines | |||
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust); | 32 | static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust); |
| 33 | static struct timer_list tsc_sync_check_timer; | ||
| 33 | 34 | ||
| 34 | /* | 35 | /* |
| 35 | * TSC's on different sockets may be reset asynchronously. | 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 | static void tsc_sanitize_first_cpu(struct tsc_adjust *cur, s64 bootval, | 121 | static void tsc_sanitize_first_cpu(struct tsc_adjust *cur, s64 bootval, |
| 81 | unsigned int cpu, bool bootcpu) | 122 | unsigned int cpu, bool bootcpu) |
| 82 | { | 123 | { |
| @@ -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 | all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL; | 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 | if (!sparse_banks_len) | 1928 | if (!sparse_banks_len) |
| 1926 | goto ret_success; | 1929 | goto ret_success; |
| 1927 | 1930 | ||
| 1928 | if (!all_cpus && | 1931 | if (kvm_read_guest(kvm, |
| 1929 | kvm_read_guest(kvm, | ||
| 1930 | hc->ingpa + offsetof(struct hv_send_ipi_ex, | 1932 | hc->ingpa + offsetof(struct hv_send_ipi_ex, |
| 1931 | vp_set.bank_contents), | 1933 | vp_set.bank_contents), |
| 1932 | sparse_banks, | 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 | return HV_STATUS_INVALID_HYPERCALL_INPUT; | 1936 | return HV_STATUS_INVALID_HYPERCALL_INPUT; |
| 1935 | } | 1937 | } |
| 1936 | 1938 | ||
| 1939 | check_and_send_ipi: | ||
| 1937 | if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR)) | 1940 | if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR)) |
| 1938 | return HV_STATUS_INVALID_HYPERCALL_INPUT; | 1941 | return HV_STATUS_INVALID_HYPERCALL_INPUT; |
| 1939 | 1942 | ||
| @@ -81,7 +81,6 @@ struct kvm_ioapic { · 80 unmodified lines | |||
| 81 | unsigned long irq_states[IOAPIC_NUM_PINS]; | 81 | unsigned long irq_states[IOAPIC_NUM_PINS]; |
| 82 | struct kvm_io_device dev; | 82 | struct kvm_io_device dev; |
| 83 | struct kvm *kvm; | 83 | struct kvm *kvm; |
| 84 | void (*ack_notifier)(void *opaque, int irq); | ||
| 85 | spinlock_t lock; | 84 | spinlock_t lock; |
| 86 | struct rtc_status rtc_status; | 85 | struct rtc_status rtc_status; |
| 87 | struct delayed_work eoi_inject; | 86 | struct delayed_work eoi_inject; |
| @@ -56,7 +56,6 @@ struct kvm_pic { · 55 unmodified lines | |||
| 56 | struct kvm_io_device dev_master; | 56 | struct kvm_io_device dev_master; |
| 57 | struct kvm_io_device dev_slave; | 57 | struct kvm_io_device dev_slave; |
| 58 | struct kvm_io_device dev_elcr; | 58 | struct kvm_io_device dev_elcr; |
| 59 | void (*ack_notifier)(void *opaque, int irq); | ||
| 60 | unsigned long irq_states[PIC_NUM_PINS]; | 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 | static int apic_has_interrupt_for_ppr(struct kvm_lapic *apic, u32 ppr) | 707 | static int apic_has_interrupt_for_ppr(struct kvm_lapic *apic, u32 ppr) |
| 708 | { | 708 | { |
| 709 | int highest_irr; | 709 | int highest_irr; |
| 710 | if (apic->vcpu->arch.apicv_active) | 710 | if (kvm_x86_ops.sync_pir_to_irr) |
| 711 | highest_irr = static_call(kvm_x86_sync_pir_to_irr)(apic->vcpu); | 711 | highest_irr = static_call(kvm_x86_sync_pir_to_irr)(apic->vcpu); |
| 712 | else | 712 | else |
| 713 | highest_irr = apic_find_highest_irr(apic); | 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 | flush = kvm_handle_gfn_range(kvm, range, kvm_unmap_rmapp); | 1582 | flush = kvm_handle_gfn_range(kvm, range, kvm_unmap_rmapp); |
| 1583 | 1583 | ||
| 1584 | if (is_tdp_mmu_enabled(kvm)) | 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 | return flush; | 1587 | return flush; |
| 1588 | } | 1588 | } |
| @@ -1936,7 +1936,11 @@ static void mmu_audit_disable(void) { } · 347 unmodified lines | |||
| 1936 | 1936 | ||
| 1937 | static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp) | 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 | unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen); | 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 | iterator->shadow_addr = root; | 2177 | iterator->shadow_addr = root; |
| 2174 | iterator->level = vcpu->arch.mmu->shadow_root_level; | 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 | vcpu->arch.mmu->root_level < PT64_ROOT_4LEVEL && | 2181 | vcpu->arch.mmu->root_level < PT64_ROOT_4LEVEL && |
| 2178 | !vcpu->arch.mmu->direct_map) | 2182 | !vcpu->arch.mmu->direct_map) |
| 2179 | --iterator->level; | 2183 | iterator->level = PT32E_ROOT_LEVEL; |
| 2180 | 2184 | ||
| 2181 | if (iterator->level == PT32E_ROOT_LEVEL) { | 2185 | if (iterator->level == PT32E_ROOT_LEVEL) { |
| 2182 | /* | 2186 | /* |
| @@ -3976,6 +3980,20 @@ out_retry: · 1793 unmodified lines | |||
| 3976 | return true; | 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 | static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) | 3997 | static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) |
| 3980 | { | 3998 | { |
| 3981 | bool is_tdp_mmu_fault = is_tdp_mmu(vcpu->arch.mmu); | 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 | else | 4031 | else |
| 4014 | write_lock(&vcpu->kvm->mmu_lock); | 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 | goto out_unlock; | 4035 | goto out_unlock; |
| 4036 | |||
| 4018 | r = make_mmu_pages_available(vcpu); | 4037 | r = make_mmu_pages_available(vcpu); |
| 4019 | if (r) | 4038 | if (r) |
| 4020 | goto out_unlock; | 4039 | goto out_unlock; |
| @@ -4855,7 +4874,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, · 834 unmodified lines | |||
| 4855 | struct kvm_mmu *context = &vcpu->arch.guest_mmu; | 4874 | struct kvm_mmu *context = &vcpu->arch.guest_mmu; |
| 4856 | struct kvm_mmu_role_regs regs = { | 4875 | struct kvm_mmu_role_regs regs = { |
| 4857 | .cr0 = cr0, | 4876 | .cr0 = cr0, |
| 4858 | .cr4 = cr4, | 4877 | .cr4 = cr4 & ~X86_CR4_PKE, |
| 4859 | .efer = efer, | 4878 | .efer = efer, |
| 4860 | }; | 4879 | }; |
| 4861 | union kvm_mmu_role new_role; | 4880 | union kvm_mmu_role new_role; |
| @@ -4919,7 +4938,7 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly, · 57 unmodified lines | |||
| 4919 | context->direct_map = false; | 4938 | context->direct_map = false; |
| 4920 | 4939 | ||
| 4921 | update_permission_bitmask(context, true); | 4940 | update_permission_bitmask(context, true); |
| 4922 | update_pkru_bitmask(context); | 4941 | context->pkru_mask = 0; |
| 4923 | reset_rsvds_bits_mask_ept(vcpu, context, execonly); | 4942 | reset_rsvds_bits_mask_ept(vcpu, context, execonly); |
| 4924 | reset_ept_shadow_zero_bits_mask(vcpu, context, execonly); | 4943 | reset_ept_shadow_zero_bits_mask(vcpu, context, execonly); |
| 4925 | } | 4944 | } |
| @@ -5025,6 +5044,14 @@ void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu) · 99 unmodified lines | |||
| 5025 | /* | 5044 | /* |
| 5026 | * Invalidate all MMU roles to force them to reinitialize as CPUID | 5045 | * Invalidate all MMU roles to force them to reinitialize as CPUID |
| 5027 | * information is factored into reserved bit calculations. | 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. | ||
| 5028 | */ | 5055 | */ |
| 5029 | vcpu->arch.root_mmu.mmu_role.ext.valid = 0; | 5056 | vcpu->arch.root_mmu.mmu_role.ext.valid = 0; |
| 5030 | vcpu->arch.guest_mmu.mmu_role.ext.valid = 0; | 5057 | vcpu->arch.guest_mmu.mmu_role.ext.valid = 0; |
| @@ -5032,24 +5059,10 @@ void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu) · 1 unmodified line | |||
| 5032 | kvm_mmu_reset_context(vcpu); | 5059 | kvm_mmu_reset_context(vcpu); |
| 5033 | 5060 | ||
| 5034 | /* | 5061 | /* |
| 5035 | * KVM does not correctly handle changing guest CPUID after KVM_RUN, as | 5062 | * Changing guest CPUID after KVM_RUN is forbidden, see the comment in |
| 5036 | * MAXPHYADDR, GBPAGES support, AMD reserved bit behavior, etc.. aren't | 5063 | * kvm_arch_vcpu_ioctl(). |
| 5037 | * tracked in kvm_mmu_page_role. As a result, KVM may miss guest page | ||
| 5038 | * faults due to reusing SPs/SPTEs. Alert userspace, but otherwise | ||
| 5039 | * sweep the problem under the rug. | ||
| 5040 | * | ||
| 5041 | * KVM's horrific CPUID ABI makes the problem all but impossible to | ||
| 5042 | * solve, as correctly handling multiple vCPU models (with respect to | ||
| 5043 | * paging and physical address properties) in a single VM would require | ||
| 5044 | * tracking all relevant CPUID information in kvm_mmu_page_role. That | ||
| 5045 | * is very undesirable as it would double the memory requirements for | ||
| 5046 | * gfn_track (see struct kvm_mmu_page_role comments), and in practice | ||
| 5047 | * no sane VMM mucks with the core vCPU model on the fly. | ||
| 5048 | */ | 5064 | */ |
| 5049 | if (vcpu->arch.last_vmentry_cpu != -1) { | 5065 | KVM_BUG_ON(vcpu->arch.last_vmentry_cpu != -1, vcpu->kvm); |
| 5050 | pr_warn_ratelimited("KVM: KVM_SET_CPUID{,2} after KVM_RUN may cause guest instability\n"); | ||
| 5051 | pr_warn_ratelimited("KVM: KVM_SET_CPUID{,2} will fail after KVM_RUN starting with Linux 5.16\n"); | ||
| 5052 | } | ||
| 5053 | } | 5066 | } |
| 5054 | 5067 | ||
| 5055 | void kvm_mmu_reset_context(struct kvm_vcpu *vcpu) | 5068 | void kvm_mmu_reset_context(struct kvm_vcpu *vcpu) |
| @@ -5369,7 +5382,7 @@ void kvm_mmu_invalidate_gva(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, · 313 unmodified lines | |||
| 5369 | 5382 | ||
| 5370 | void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva) | 5383 | void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva) |
| 5371 | { | 5384 | { |
| 5372 | kvm_mmu_invalidate_gva(vcpu, vcpu->arch.mmu, gva, INVALID_PAGE); | 5385 | kvm_mmu_invalidate_gva(vcpu, vcpu->arch.walk_mmu, gva, INVALID_PAGE); |
| 5373 | ++vcpu->stat.invlpg; | 5386 | ++vcpu->stat.invlpg; |
| 5374 | } | 5387 | } |
| 5375 | EXPORT_SYMBOL_GPL(kvm_mmu_invlpg); | 5388 | EXPORT_SYMBOL_GPL(kvm_mmu_invlpg); |
| @@ -5854,8 +5867,6 @@ restart: · 478 unmodified lines | |||
| 5854 | void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, | 5867 | void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, |
| 5855 | const struct kvm_memory_slot *slot) | 5868 | const struct kvm_memory_slot *slot) |
| 5856 | { | 5869 | { |
| 5857 | bool flush = false; | ||
| 5858 | |||
| 5859 | if (kvm_memslots_have_rmaps(kvm)) { | 5870 | if (kvm_memslots_have_rmaps(kvm)) { |
| 5860 | write_lock(&kvm->mmu_lock); | 5871 | write_lock(&kvm->mmu_lock); |
| 5861 | /* | 5872 | /* |
| @@ -5863,17 +5874,14 @@ void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, · 1 unmodified line | |||
| 5863 | * logging at a 4k granularity and never creates collapsible | 5874 | * logging at a 4k granularity and never creates collapsible |
| 5864 | * 2m SPTEs during dirty logging. | 5875 | * 2m SPTEs during dirty logging. |
| 5865 | */ | 5876 | */ |
| 5866 | flush = slot_handle_level_4k(kvm, slot, kvm_mmu_zap_collapsible_spte, true); | 5877 | if (slot_handle_level_4k(kvm, slot, kvm_mmu_zap_collapsible_spte, true)) |
| 5867 | if (flush) | ||
| 5868 | kvm_arch_flush_remote_tlbs_memslot(kvm, slot); | 5878 | kvm_arch_flush_remote_tlbs_memslot(kvm, slot); |
| 5869 | write_unlock(&kvm->mmu_lock); | 5879 | write_unlock(&kvm->mmu_lock); |
| 5870 | } | 5880 | } |
| 5871 | 5881 | ||
| 5872 | if (is_tdp_mmu_enabled(kvm)) { | 5882 | if (is_tdp_mmu_enabled(kvm)) { |
| 5873 | read_lock(&kvm->mmu_lock); | 5883 | read_lock(&kvm->mmu_lock); |
| 5874 | flush = kvm_tdp_mmu_zap_collapsible_sptes(kvm, slot, flush); | 5884 | kvm_tdp_mmu_zap_collapsible_sptes(kvm, slot); |
| 5875 | if (flush) | ||
| 5876 | kvm_arch_flush_remote_tlbs_memslot(kvm, slot); | ||
| 5877 | read_unlock(&kvm->mmu_lock); | 5885 | read_unlock(&kvm->mmu_lock); |
| 5878 | } | 5886 | } |
| 5879 | } | 5887 | } |
| @@ -6182,23 +6190,46 @@ void kvm_mmu_module_exit(void) · 302 unmodified lines | |||
| 6182 | mmu_audit_disable(); | 6190 | mmu_audit_disable(); |
| 6183 | } | 6191 | } |
| 6184 | 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 | |||
| 6185 | static int set_nx_huge_pages_recovery_param(const char *val, const struct kernel_param *kp) | 6218 | static int set_nx_huge_pages_recovery_param(const char *val, const struct kernel_param *kp) |
| 6186 | { | 6219 | { |
| 6187 | bool was_recovery_enabled, is_recovery_enabled; | 6220 | bool was_recovery_enabled, is_recovery_enabled; |
| 6188 | uint old_period, new_period; | 6221 | uint old_period, new_period; |
| 6189 | int err; | 6222 | int err; |
| 6190 | 6223 | ||
| 6191 | was_recovery_enabled = nx_huge_pages_recovery_ratio; | 6224 | was_recovery_enabled = calc_nx_huge_pages_recovery_period(&old_period); |
| 6192 | old_period = nx_huge_pages_recovery_period_ms; | ||
| 6193 | 6225 | ||
| 6194 | err = param_set_uint(val, kp); | 6226 | err = param_set_uint(val, kp); |
| 6195 | if (err) | 6227 | if (err) |
| 6196 | return err; | 6228 | return err; |
| 6197 | 6229 | ||
| 6198 | is_recovery_enabled = nx_huge_pages_recovery_ratio; | 6230 | is_recovery_enabled = calc_nx_huge_pages_recovery_period(&new_period); |
| 6199 | new_period = nx_huge_pages_recovery_period_ms; | ||
| 6200 | 6231 | ||
| 6201 | if (READ_ONCE(nx_huge_pages) && is_recovery_enabled && | 6232 | if (is_recovery_enabled && |
| 6202 | (!was_recovery_enabled || old_period > new_period)) { | 6233 | (!was_recovery_enabled || old_period > new_period)) { |
| 6203 | struct kvm *kvm; | 6234 | struct kvm *kvm; |
| 6204 | 6235 | ||
| @@ -6262,18 +6293,13 @@ static void kvm_recover_nx_lpages(struct kvm *kvm) · 57 unmodified lines | |||
| 6262 | 6293 | ||
| 6263 | static long get_nx_lpage_recovery_timeout(u64 start_time) | 6294 | static long get_nx_lpage_recovery_timeout(u64 start_time) |
| 6264 | { | 6295 | { |
| 6265 | uint ratio = READ_ONCE(nx_huge_pages_recovery_ratio); | 6296 | bool enabled; |
| 6266 | uint period = READ_ONCE(nx_huge_pages_recovery_period_ms); | 6297 | uint period; |
| 6267 | 6298 | ||
| 6268 | if (!period && ratio) { | 6299 | enabled = calc_nx_huge_pages_recovery_period(&period); |
| 6269 | /* Make sure the period is not less than one second. */ | ||
| 6270 | ratio = min(ratio, 3600u); | ||
| 6271 | period = 60 * 60 * 1000 / ratio; | ||
| 6272 | } | ||
| 6273 | 6300 | ||
| 6274 | return READ_ONCE(nx_huge_pages) && ratio | 6301 | return enabled ? start_time + msecs_to_jiffies(period) - get_jiffies_64() |
| 6275 | ? start_time + msecs_to_jiffies(period) - get_jiffies_64() | 6302 | : MAX_SCHEDULE_TIMEOUT; |
| 6276 | : MAX_SCHEDULE_TIMEOUT; | ||
| 6277 | } | 6303 | } |
| 6278 | 6304 | ||
| 6279 | static int kvm_nx_lpage_recovery_worker(struct kvm *kvm, uintptr_t data) | 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 | r = RET_PF_RETRY; | 912 | r = RET_PF_RETRY; |
| 913 | write_lock(&vcpu->kvm->mmu_lock); | 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 | goto out_unlock; | 916 | goto out_unlock; |
| 916 | 917 | ||
| 917 | kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT); | 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 | struct kvm_mmu_page *sp = sptep_to_sp(rcu_dereference(pt)); | 317 | struct kvm_mmu_page *sp = sptep_to_sp(rcu_dereference(pt)); |
| 318 | int level = sp->role.level; | 318 | int level = sp->role.level; |
| 319 | gfn_t base_gfn = sp->gfn; | 319 | gfn_t base_gfn = sp->gfn; |
| 320 | u64 old_child_spte; | ||
| 321 | u64 *sptep; | ||
| 322 | gfn_t gfn; | ||
| 323 | int i; | 320 | int i; |
| 324 | 321 | ||
| 325 | trace_kvm_mmu_prepare_zap_page(sp); | 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 | tdp_mmu_unlink_page(kvm, sp, shared); | 324 | tdp_mmu_unlink_page(kvm, sp, shared); |
| 328 | 325 | ||
| 329 | for (i = 0; i < PT64_ENT_PER_PAGE; i++) { | 326 | for (i = 0; i < PT64_ENT_PER_PAGE; i++) { |
| 330 | sptep = rcu_dereference(pt) + i; | 327 | u64 *sptep = rcu_dereference(pt) + i; |
| 331 | gfn = base_gfn + i * KVM_PAGES_PER_HPAGE(level); | 328 | gfn_t gfn = base_gfn + i * KVM_PAGES_PER_HPAGE(level); |
| 329 | u64 old_child_spte; | ||
| 332 | 330 | ||
| 333 | if (shared) { | 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 | shared); | 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 | KVM_PAGES_PER_HPAGE(level + 1)); | 376 | KVM_PAGES_PER_HPAGE(level + 1)); |
| 379 | 377 | ||
| 380 | call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback); | 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 | struct kvm_mmu_page *root; | 1032 | struct kvm_mmu_page *root; |
| 1035 | 1033 | ||
| 1036 | for_each_tdp_mmu_root(kvm, root, range->slot->as_id) | 1034 | for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id, false) |
| 1037 | flush |= zap_gfn_range(kvm, root, range->start, range->end, | 1035 | flush = zap_gfn_range(kvm, root, range->start, range->end, |
| 1038 | range->may_block, flush, false); | 1036 | range->may_block, flush, false); |
| 1039 | 1037 | ||
| 1040 | return flush; | 1038 | return flush; |
| 1041 | } | 1039 | } |
| @@ -1364,10 +1362,9 @@ void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm, · 322 unmodified lines | |||
| 1364 | * Clear leaf entries which could be replaced by large mappings, for | 1362 | * Clear leaf entries which could be replaced by large mappings, for |
| 1365 | * GFNs within the slot. | 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 | struct kvm_mmu_page *root, | 1366 | struct kvm_mmu_page *root, |
| 1369 | const struct kvm_memory_slot *slot, | 1367 | const struct kvm_memory_slot *slot) |
| 1370 | bool flush) | ||
| 1371 | { | 1368 | { |
| 1372 | gfn_t start = slot->base_gfn; | 1369 | gfn_t start = slot->base_gfn; |
| 1373 | gfn_t end = start + slot->npages; | 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 | tdp_root_for_each_pte(iter, root, start, end) { | 1376 | tdp_root_for_each_pte(iter, root, start, end) { |
| 1380 | retry: | 1377 | retry: |
| 1381 | if (tdp_mmu_iter_cond_resched(kvm, &iter, flush, true)) { | 1378 | if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true)) |
| 1382 | flush = false; | ||
| 1383 | continue; | 1379 | continue; |
| 1384 | } | ||
| 1385 | 1380 | ||
| 1386 | if (!is_shadow_present_pte(iter.old_spte) || | 1381 | if (!is_shadow_present_pte(iter.old_spte) || |
| 1387 | !is_last_spte(iter.old_spte, iter.level)) | 1382 | !is_last_spte(iter.old_spte, iter.level)) |
| @@ -1393,6 +1388,7 @@ retry: · 5 unmodified lines | |||
| 1393 | pfn, PG_LEVEL_NUM)) | 1388 | pfn, PG_LEVEL_NUM)) |
| 1394 | continue; | 1389 | continue; |
| 1395 | 1390 | ||
| 1391 | /* Note, a successful atomic zap also does a remote TLB flush. */ | ||
| 1396 | if (!tdp_mmu_zap_spte_atomic(kvm, &iter)) { | 1392 | if (!tdp_mmu_zap_spte_atomic(kvm, &iter)) { |
| 1397 | /* | 1393 | /* |
| 1398 | * The iter must explicitly re-read the SPTE because | 1394 | * The iter must explicitly re-read the SPTE because |
| @@ -1401,30 +1397,24 @@ retry: · 2 unmodified lines | |||
| 1401 | iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep)); | 1397 | iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep)); |
| 1402 | goto retry; | 1398 | goto retry; |
| 1403 | } | 1399 | } |
| 1404 | flush = true; | ||
| 1405 | } | 1400 | } |
| 1406 | 1401 | ||
| 1407 | rcu_read_unlock(); | 1402 | rcu_read_unlock(); |
| 1408 | |||
| 1409 | return flush; | ||
| 1410 | } | 1403 | } |
| 1411 | 1404 | ||
| 1412 | /* | 1405 | /* |
| 1413 | * Clear non-leaf entries (and free associated page tables) which could | 1406 | * Clear non-leaf entries (and free associated page tables) which could |
| 1414 | * be replaced by large mappings, for GFNs within the slot. | 1407 | * be replaced by large mappings, for GFNs within the slot. |
| 1415 | */ | 1408 | */ |
| 1416 | bool kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, | 1409 | void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, |
| 1417 | const struct kvm_memory_slot *slot, | 1410 | const struct kvm_memory_slot *slot) |
| 1418 | bool flush) | ||
| 1419 | { | 1411 | { |
| 1420 | struct kvm_mmu_page *root; | 1412 | struct kvm_mmu_page *root; |
| 1421 | 1413 | ||
| 1422 | lockdep_assert_held_read(&kvm->mmu_lock); | 1414 | lockdep_assert_held_read(&kvm->mmu_lock); |
| 1423 | 1415 | ||
| 1424 | for_each_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true) | 1416 | for_each_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true) |
| 1425 | flush = zap_collapsible_spte_range(kvm, root, slot, flush); | 1417 | zap_collapsible_spte_range(kvm, root, slot); |
| 1426 | |||
| 1427 | return flush; | ||
| 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 | struct kvm_memory_slot *slot, | 64 | struct kvm_memory_slot *slot, |
| 65 | gfn_t gfn, unsigned long mask, | 65 | gfn_t gfn, unsigned long mask, |
| 66 | bool wrprot); | 66 | bool wrprot); |
| 67 | bool kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, | 67 | void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, |
| 68 | const struct kvm_memory_slot *slot, | 68 | const struct kvm_memory_slot *slot); |
| 69 | bool flush); | ||
| 70 | 69 | ||
| 71 | bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, | 70 | bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, |
| 72 | struct kvm_memory_slot *slot, gfn_t gfn, | 71 | struct kvm_memory_slot *slot, gfn_t gfn, |
| @@ -900,6 +900,7 @@ out: · 899 unmodified lines | |||
| 900 | bool svm_check_apicv_inhibit_reasons(ulong bit) | 900 | bool svm_check_apicv_inhibit_reasons(ulong bit) |
| 901 | { | 901 | { |
| 902 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | | 902 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | |
| 903 | BIT(APICV_INHIBIT_REASON_ABSENT) | | ||
| 903 | BIT(APICV_INHIBIT_REASON_HYPERV) | | 904 | BIT(APICV_INHIBIT_REASON_HYPERV) | |
| 904 | BIT(APICV_INHIBIT_REASON_NESTED) | | 905 | BIT(APICV_INHIBIT_REASON_NESTED) | |
| 905 | BIT(APICV_INHIBIT_REASON_IRQWIN) | | 906 | BIT(APICV_INHIBIT_REASON_IRQWIN) | |
| @@ -989,16 +990,18 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu) · 83 unmodified lines | |||
| 989 | static void avic_set_running(struct kvm_vcpu *vcpu, bool is_run) | 990 | static void avic_set_running(struct kvm_vcpu *vcpu, bool is_run) |
| 990 | { | 991 | { |
| 991 | struct vcpu_svm *svm = to_svm(vcpu); | 992 | struct vcpu_svm *svm = to_svm(vcpu); |
| 993 | int cpu = get_cpu(); | ||
| 992 | 994 | ||
| 995 | WARN_ON(cpu != vcpu->cpu); | ||
| 993 | svm->avic_is_running = is_run; | 996 | svm->avic_is_running = is_run; |
| 994 | 997 | ||
| 995 | if (!kvm_vcpu_apicv_active(vcpu)) | 998 | if (kvm_vcpu_apicv_active(vcpu)) { |
| 996 | return; | 999 | if (is_run) |
| 997 | 1000 | avic_vcpu_load(vcpu, cpu); | |
| 998 | if (is_run) | 1001 | else |
| 999 | avic_vcpu_load(vcpu, vcpu->cpu); | 1002 | avic_vcpu_put(vcpu); |
| 1000 | else | 1003 | } |
| 1001 | avic_vcpu_put(vcpu); | 1004 | put_cpu(); |
| 1002 | } | 1005 | } |
| 1003 | 1006 | ||
| 1004 | void svm_vcpu_blocking(struct kvm_vcpu *vcpu) | 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 | pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS; | 281 | pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS; |
| 282 | 282 | ||
| 283 | pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1; | 283 | pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1; |
| 284 | pmu->reserved_bits = 0xffffffff00200000ull; | 284 | pmu->reserved_bits = 0xfffffff000280000ull; |
| 285 | pmu->version = 1; | 285 | pmu->version = 1; |
| 286 | /* not applicable to AMD; but clean them to prevent any fall out */ | 286 | /* not applicable to AMD; but clean them to prevent any fall out */ |
| 287 | pmu->counter_bitmask[KVM_PMC_FIXED] = 0; | 287 | pmu->counter_bitmask[KVM_PMC_FIXED] = 0; |
| @@ -1543,28 +1543,50 @@ static bool is_cmd_allowed_from_mirror(u32 cmd_id) · 1542 unmodified lines | |||
| 1543 | return false; | 1543 | return false; |
| 1544 | } | 1544 | } |
| 1545 | 1545 | ||
| 1546 | static int sev_lock_for_migration(struct kvm *kvm) | 1546 | static int sev_lock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm) |
| 1547 | { | 1547 | { |
| 1548 | 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; | ||
| 1549 | 1554 | ||
| 1550 | /* | 1555 | /* |
| 1551 | * Bail if this VM is already involved in a migration to avoid deadlock | 1556 | * Bail if these VMs are already involved in a migration to avoid |
| 1552 | * between two VMs trying to migrate to/from each other. | 1557 | * deadlock between two VMs trying to migrate to/from each other. |
| 1553 | */ | 1558 | */ |
| 1554 | if (atomic_cmpxchg_acquire(&sev->migration_in_progress, 0, 1)) | 1559 | if (atomic_cmpxchg_acquire(&dst_sev->migration_in_progress, 0, 1)) |
| 1555 | return -EBUSY; | 1560 | return -EBUSY; |
| 1556 | 1561 | ||
| 1557 | mutex_lock(&kvm->lock); | 1562 | if (atomic_cmpxchg_acquire(&src_sev->migration_in_progress, 0, 1)) |
| 1563 | goto release_dst; | ||
| 1558 | 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; | ||
| 1559 | return 0; | 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; | ||
| 1560 | } | 1579 | } |
| 1561 | 1580 | ||
| 1562 | static void sev_unlock_after_migration(struct kvm *kvm) | 1581 | static void sev_unlock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm) |
| 1563 | { | 1582 | { |
| 1564 | 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; | ||
| 1565 | 1585 | ||
| 1566 | mutex_unlock(&kvm->lock); | 1586 | mutex_unlock(&dst_kvm->lock); |
| 1567 | atomic_set_release(&sev->migration_in_progress, 0); | 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); | ||
| 1568 | } | 1590 | } |
| 1569 | 1591 | ||
| 1570 | 1592 | ||
| @@ -1607,14 +1629,15 @@ static void sev_migrate_from(struct kvm_sev_info *dst, · 36 unmodified lines | |||
| 1607 | dst->asid = src->asid; | 1629 | dst->asid = src->asid; |
| 1608 | dst->handle = src->handle; | 1630 | dst->handle = src->handle; |
| 1609 | dst->pages_locked = src->pages_locked; | 1631 | dst->pages_locked = src->pages_locked; |
| 1632 | dst->enc_context_owner = src->enc_context_owner; | ||
| 1610 | 1633 | ||
| 1611 | src->asid = 0; | 1634 | src->asid = 0; |
| 1612 | src->active = false; | 1635 | src->active = false; |
| 1613 | src->handle = 0; | 1636 | src->handle = 0; |
| 1614 | src->pages_locked = 0; | 1637 | src->pages_locked = 0; |
| 1638 | src->enc_context_owner = NULL; | ||
| 1615 | 1639 | ||
| 1616 | INIT_LIST_HEAD(&dst->regions_list); | 1640 | list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list); |
| 1617 | list_replace_init(&src->regions_list, &dst->regions_list); | ||
| 1618 | } | 1641 | } |
| 1619 | 1642 | ||
| 1620 | static int sev_es_migrate_from(struct kvm *dst, struct kvm *src) | 1643 | static int sev_es_migrate_from(struct kvm *dst, struct kvm *src) |
| @@ -1666,15 +1689,6 @@ int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd) · 45 unmodified lines | |||
| 1666 | bool charged = false; | 1689 | bool charged = false; |
| 1667 | int ret; | 1690 | int ret; |
| 1668 | 1691 | ||
| 1669 | ret = sev_lock_for_migration(kvm); | ||
| 1670 | if (ret) | ||
| 1671 | return ret; | ||
| 1672 | |||
| 1673 | if (sev_guest(kvm)) { | ||
| 1674 | ret = -EINVAL; | ||
| 1675 | goto out_unlock; | ||
| 1676 | } | ||
| 1677 | |||
| 1678 | source_kvm_file = fget(source_fd); | 1692 | source_kvm_file = fget(source_fd); |
| 1679 | if (!file_is_kvm(source_kvm_file)) { | 1693 | if (!file_is_kvm(source_kvm_file)) { |
| 1680 | ret = -EBADF; | 1694 | ret = -EBADF; |
| @@ -1682,16 +1696,26 @@ int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd) · 1 unmodified line | |||
| 1682 | } | 1696 | } |
| 1683 | 1697 | ||
| 1684 | source_kvm = source_kvm_file->private_data; | 1698 | source_kvm = source_kvm_file->private_data; |
| 1685 | ret = sev_lock_for_migration(source_kvm); | 1699 | ret = sev_lock_two_vms(kvm, source_kvm); |
| 1686 | if (ret) | 1700 | if (ret) |
| 1687 | goto out_fput; | 1701 | goto out_fput; |
| 1688 | 1702 | ||
| 1689 | if (!sev_guest(source_kvm)) { | 1703 | if (sev_guest(kvm) || !sev_guest(source_kvm)) { |
| 1690 | ret = -EINVAL; | 1704 | ret = -EINVAL; |
| 1691 | goto out_source; | 1705 | goto out_unlock; |
| 1692 | } | 1706 | } |
| 1693 | 1707 | ||
| 1694 | src_sev = &to_kvm_svm(source_kvm)->sev_info; | 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 | |||
| 1695 | dst_sev->misc_cg = get_current_misc_cg(); | 1719 | dst_sev->misc_cg = get_current_misc_cg(); |
| 1696 | cg_cleanup_sev = dst_sev; | 1720 | cg_cleanup_sev = dst_sev; |
| 1697 | if (dst_sev->misc_cg != src_sev->misc_cg) { | 1721 | if (dst_sev->misc_cg != src_sev->misc_cg) { |
| @@ -1728,13 +1752,11 @@ out_dst_cgroup: · 30 unmodified lines | |||
| 1728 | sev_misc_cg_uncharge(cg_cleanup_sev); | 1752 | sev_misc_cg_uncharge(cg_cleanup_sev); |
| 1729 | put_misc_cg(cg_cleanup_sev->misc_cg); | 1753 | put_misc_cg(cg_cleanup_sev->misc_cg); |
| 1730 | cg_cleanup_sev->misc_cg = NULL; | 1754 | cg_cleanup_sev->misc_cg = NULL; |
| 1731 | out_source: | 1755 | out_unlock: |
| 1732 | sev_unlock_after_migration(source_kvm); | 1756 | sev_unlock_two_vms(kvm, source_kvm); |
| 1733 | out_fput: | 1757 | out_fput: |
| 1734 | if (source_kvm_file) | 1758 | if (source_kvm_file) |
| 1735 | fput(source_kvm_file); | 1759 | fput(source_kvm_file); |
| 1736 | out_unlock: | ||
| 1737 | sev_unlock_after_migration(kvm); | ||
| 1738 | return ret; | 1760 | return ret; |
| 1739 | } | 1761 | } |
| 1740 | 1762 | ||
| @@ -1953,76 +1975,60 @@ int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd) · 212 unmodified lines | |||
| 1953 | { | 1975 | { |
| 1954 | struct file *source_kvm_file; | 1976 | struct file *source_kvm_file; |
| 1955 | struct kvm *source_kvm; | 1977 | struct kvm *source_kvm; |
| 1956 | struct kvm_sev_info source_sev, *mirror_sev; | 1978 | struct kvm_sev_info *source_sev, *mirror_sev; |
| 1957 | int ret; | 1979 | int ret; |
| 1958 | 1980 | ||
| 1959 | source_kvm_file = fget(source_fd); | 1981 | source_kvm_file = fget(source_fd); |
| 1960 | if (!file_is_kvm(source_kvm_file)) { | 1982 | if (!file_is_kvm(source_kvm_file)) { |
| 1961 | ret = -EBADF; | 1983 | ret = -EBADF; |
| 1962 | goto e_source_put; | 1984 | goto e_source_fput; |
| 1963 | } | 1985 | } |
| 1964 | 1986 | ||
| 1965 | source_kvm = source_kvm_file->private_data; | 1987 | source_kvm = source_kvm_file->private_data; |
| 1966 | mutex_lock(&source_kvm->lock); | 1988 | ret = sev_lock_two_vms(kvm, source_kvm); |
| 1967 | 1989 | if (ret) | |
| 1968 | if (!sev_guest(source_kvm)) { | 1990 | goto e_source_fput; |
| 1969 | ret = -EINVAL; | ||
| 1970 | goto e_source_unlock; | ||
| 1971 | } | ||
| 1972 | 1991 | ||
| 1973 | /* Mirrors of mirrors should work, but let's not get silly */ | 1992 | /* |
| 1974 | if (is_mirroring_enc_context(source_kvm) || source_kvm == kvm) { | 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) { | ||
| 1975 | ret = -EINVAL; | 2000 | ret = -EINVAL; |
| 1976 | goto e_source_unlock; | 2001 | goto e_unlock; |
| 1977 | } | 2002 | } |
| 1978 | 2003 | ||
| 1979 | memcpy(&source_sev, &to_kvm_svm(source_kvm)->sev_info, | ||
| 1980 | sizeof(source_sev)); | ||
| 1981 | |||
| 1982 | /* | 2004 | /* |
| 1983 | * The mirror kvm holds an enc_context_owner ref so its asid can't | 2005 | * The mirror kvm holds an enc_context_owner ref so its asid can't |
| 1984 | * disappear until we're done with it | 2006 | * disappear until we're done with it |
| 1985 | */ | 2007 | */ |
| 2008 | source_sev = &to_kvm_svm(source_kvm)->sev_info; | ||
| 1986 | kvm_get_kvm(source_kvm); | 2009 | kvm_get_kvm(source_kvm); |
| 1987 | 2010 | source_sev->num_mirrored_vms++; | |
| 1988 | fput(source_kvm_file); | ||
| 1989 | mutex_unlock(&source_kvm->lock); | ||
| 1990 | mutex_lock(&kvm->lock); | ||
| 1991 | |||
| 1992 | /* | ||
| 1993 | * Disallow out-of-band SEV/SEV-ES init if the target is already an | ||
| 1994 | * SEV guest, or if vCPUs have been created. KVM relies on vCPUs being | ||
| 1995 | * created after SEV/SEV-ES initialization, e.g. to init intercepts. | ||
| 1996 | */ | ||
| 1997 | if (sev_guest(kvm) || kvm->created_vcpus) { | ||
| 1998 | ret = -EINVAL; | ||
| 1999 | goto e_mirror_unlock; | ||
| 2000 | } | ||
| 2001 | 2011 | ||
| 2002 | /* Set enc_context_owner and copy its encryption context over */ | 2012 | /* Set enc_context_owner and copy its encryption context over */ |
| 2003 | mirror_sev = &to_kvm_svm(kvm)->sev_info; | 2013 | mirror_sev = &to_kvm_svm(kvm)->sev_info; |
| 2004 | mirror_sev->enc_context_owner = source_kvm; | 2014 | mirror_sev->enc_context_owner = source_kvm; |
| 2005 | mirror_sev->active = true; | 2015 | mirror_sev->active = true; |
| 2006 | mirror_sev->asid = source_sev.asid; | 2016 | mirror_sev->asid = source_sev->asid; |
| 2007 | mirror_sev->fd = source_sev.fd; | 2017 | mirror_sev->fd = source_sev->fd; |
| 2008 | mirror_sev->es_active = source_sev.es_active; | 2018 | mirror_sev->es_active = source_sev->es_active; |
| 2009 | mirror_sev->handle = source_sev.handle; | 2019 | mirror_sev->handle = source_sev->handle; |
| 2020 | INIT_LIST_HEAD(&mirror_sev->regions_list); | ||
| 2021 | ret = 0; | ||
| 2022 | |||
| 2010 | /* | 2023 | /* |
| 2011 | * Do not copy ap_jump_table. Since the mirror does not share the same | 2024 | * Do not copy ap_jump_table. Since the mirror does not share the same |
| 2012 | * KVM contexts as the original, and they may have different | 2025 | * KVM contexts as the original, and they may have different |
| 2013 | * memory-views. | 2026 | * memory-views. |
| 2014 | */ | 2027 | */ |
| 2015 | 2028 | ||
| 2016 | mutex_unlock(&kvm->lock); | 2029 | e_unlock: |
| 2017 | return 0; | 2030 | sev_unlock_two_vms(kvm, source_kvm); |
| 2018 | 2031 | e_source_fput: | |
| 2019 | e_mirror_unlock: | ||
| 2020 | mutex_unlock(&kvm->lock); | ||
| 2021 | kvm_put_kvm(source_kvm); | ||
| 2022 | return ret; | ||
| 2023 | e_source_unlock: | ||
| 2024 | mutex_unlock(&source_kvm->lock); | ||
| 2025 | e_source_put: | ||
| 2026 | if (source_kvm_file) | 2032 | if (source_kvm_file) |
| 2027 | fput(source_kvm_file); | 2033 | fput(source_kvm_file); |
| 2028 | return ret; | 2034 | return ret; |
| @@ -2034,17 +2040,24 @@ void sev_vm_destroy(struct kvm *kvm) · 5 unmodified lines | |||
| 2034 | struct list_head *head = &sev->regions_list; | 2040 | struct list_head *head = &sev->regions_list; |
| 2035 | struct list_head *pos, *q; | 2041 | struct list_head *pos, *q; |
| 2036 | 2042 | ||
| 2043 | WARN_ON(sev->num_mirrored_vms); | ||
| 2044 | |||
| 2037 | if (!sev_guest(kvm)) | 2045 | if (!sev_guest(kvm)) |
| 2038 | return; | 2046 | return; |
| 2039 | 2047 | ||
| 2040 | /* If this is a mirror_kvm release the enc_context_owner and skip sev cleanup */ | 2048 | /* If this is a mirror_kvm release the enc_context_owner and skip sev cleanup */ |
| 2041 | if (is_mirroring_enc_context(kvm)) { | 2049 | if (is_mirroring_enc_context(kvm)) { |
| 2042 | 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); | ||
| 2043 | return; | 2058 | return; |
| 2044 | } | 2059 | } |
| 2045 | 2060 | ||
| 2046 | mutex_lock(&kvm->lock); | ||
| 2047 | |||
| 2048 | /* | 2061 | /* |
| 2049 | * Ensure that all guest tagged cache entries are flushed before | 2062 | * Ensure that all guest tagged cache entries are flushed before |
| 2050 | * releasing the pages back to the system for use. CLFLUSH will | 2063 | * releasing the pages back to the system for use. CLFLUSH will |
| @@ -2064,8 +2077,6 @@ void sev_vm_destroy(struct kvm *kvm) · 13 unmodified lines | |||
| 2064 | } | 2077 | } |
| 2065 | } | 2078 | } |
| 2066 | 2079 | ||
| 2067 | mutex_unlock(&kvm->lock); | ||
| 2068 | |||
| 2069 | sev_unbind_asid(kvm, sev->handle); | 2080 | sev_unbind_asid(kvm, sev->handle); |
| 2070 | sev_asid_free(sev); | 2081 | sev_asid_free(sev); |
| 2071 | } | 2082 | } |
| @@ -2249,7 +2260,7 @@ void sev_free_vcpu(struct kvm_vcpu *vcpu) · 177 unmodified lines | |||
| 2249 | __free_page(virt_to_page(svm->sev_es.vmsa)); | 2260 | __free_page(virt_to_page(svm->sev_es.vmsa)); |
| 2250 | 2261 | ||
| 2251 | if (svm->sev_es.ghcb_sa_free) | 2262 | if (svm->sev_es.ghcb_sa_free) |
| 2252 | kfree(svm->sev_es.ghcb_sa); | 2263 | kvfree(svm->sev_es.ghcb_sa); |
| 2253 | } | 2264 | } |
| 2254 | 2265 | ||
| 2255 | static void dump_ghcb(struct vcpu_svm *svm) | 2266 | static void dump_ghcb(struct vcpu_svm *svm) |
| @@ -2341,24 +2352,29 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) · 85 unmodified lines | |||
| 2341 | memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); | 2352 | memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); |
| 2342 | } | 2353 | } |
| 2343 | 2354 | ||
| 2344 | static int sev_es_validate_vmgexit(struct vcpu_svm *svm) | 2355 | static bool sev_es_validate_vmgexit(struct vcpu_svm *svm) |
| 2345 | { | 2356 | { |
| 2346 | struct kvm_vcpu *vcpu; | 2357 | struct kvm_vcpu *vcpu; |
| 2347 | struct ghcb *ghcb; | 2358 | struct ghcb *ghcb; |
| 2348 | u64 exit_code = 0; | 2359 | u64 exit_code; |
| 2360 | u64 reason; | ||
| 2349 | 2361 | ||
| 2350 | ghcb = svm->sev_es.ghcb; | 2362 | ghcb = svm->sev_es.ghcb; |
| 2351 | 2363 | ||
| 2352 | /* Only GHCB Usage code 0 is supported */ | ||
| 2353 | if (ghcb->ghcb_usage) | ||
| 2354 | goto vmgexit_err; | ||
| 2355 | |||
| 2356 | /* | 2364 | /* |
| 2357 | * 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 |
| 2358 | * as it could help with debugging. | 2366 | * as it could help with debugging. |
| 2359 | */ | 2367 | */ |
| 2360 | exit_code = ghcb_get_sw_exit_code(ghcb); | 2368 | exit_code = ghcb_get_sw_exit_code(ghcb); |
| 2361 | 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 | |||
| 2362 | if (!ghcb_sw_exit_code_is_valid(ghcb) || | 2378 | if (!ghcb_sw_exit_code_is_valid(ghcb) || |
| 2363 | !ghcb_sw_exit_info_1_is_valid(ghcb) || | 2379 | !ghcb_sw_exit_info_1_is_valid(ghcb) || |
| 2364 | !ghcb_sw_exit_info_2_is_valid(ghcb)) | 2380 | !ghcb_sw_exit_info_2_is_valid(ghcb)) |
| @@ -2437,30 +2453,34 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) · 72 unmodified lines | |||
| 2437 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: | 2453 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: |
| 2438 | break; | 2454 | break; |
| 2439 | default: | 2455 | default: |
| 2456 | reason = GHCB_ERR_INVALID_EVENT; | ||
| 2440 | goto vmgexit_err; | 2457 | goto vmgexit_err; |
| 2441 | } | 2458 | } |
| 2442 | 2459 | ||
| 2443 | return 0; | 2460 | return true; |
| 2444 | 2461 | ||
| 2445 | vmgexit_err: | 2462 | vmgexit_err: |
| 2446 | vcpu = &svm->vcpu; | 2463 | vcpu = &svm->vcpu; |
| 2447 | 2464 | ||
| 2448 | if (ghcb->ghcb_usage) { | 2465 | if (reason == GHCB_ERR_INVALID_USAGE) { |
| 2449 | vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n", | 2466 | vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n", |
| 2450 | ghcb->ghcb_usage); | 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); | ||
| 2451 | } else { | 2471 | } else { |
| 2452 | vcpu_unimpl(vcpu, "vmgexit: exit reason %#llx is not valid\n", | 2472 | vcpu_unimpl(vcpu, "vmgexit: exit code %#llx input is not valid\n", |
| 2453 | exit_code); | 2473 | exit_code); |
| 2454 | dump_ghcb(svm); | 2474 | dump_ghcb(svm); |
| 2455 | } | 2475 | } |
| 2456 | 2476 | ||
| 2457 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | 2477 | /* Clear the valid entries fields */ |
| 2458 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; | 2478 | memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); |
| 2459 | vcpu->run->internal.ndata = 2; | 2479 | |
| 2460 | vcpu->run->internal.data[0] = exit_code; | 2480 | ghcb_set_sw_exit_info_1(ghcb, 2); |
| 2461 | vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; | 2481 | ghcb_set_sw_exit_info_2(ghcb, reason); |
| 2462 | 2482 | ||
| 2463 | return -EINVAL; | 2483 | return false; |
| 2464 | } | 2484 | } |
| 2465 | 2485 | ||
| 2466 | void sev_es_unmap_ghcb(struct vcpu_svm *svm) | 2486 | void sev_es_unmap_ghcb(struct vcpu_svm *svm) |
| @@ -2482,7 +2502,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm) · 15 unmodified lines | |||
| 2482 | svm->sev_es.ghcb_sa_sync = false; | 2502 | svm->sev_es.ghcb_sa_sync = false; |
| 2483 | } | 2503 | } |
| 2484 | 2504 | ||
| 2485 | kfree(svm->sev_es.ghcb_sa); | 2505 | kvfree(svm->sev_es.ghcb_sa); |
| 2486 | svm->sev_es.ghcb_sa = NULL; | 2506 | svm->sev_es.ghcb_sa = NULL; |
| 2487 | svm->sev_es.ghcb_sa_free = false; | 2507 | svm->sev_es.ghcb_sa_free = false; |
| 2488 | } | 2508 | } |
| @@ -2530,14 +2550,14 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 41 unmodified lines | |||
| 2530 | scratch_gpa_beg = ghcb_get_sw_scratch(ghcb); | 2550 | scratch_gpa_beg = ghcb_get_sw_scratch(ghcb); |
| 2531 | if (!scratch_gpa_beg) { | 2551 | if (!scratch_gpa_beg) { |
| 2532 | pr_err("vmgexit: scratch gpa not provided\n"); | 2552 | pr_err("vmgexit: scratch gpa not provided\n"); |
| 2533 | return false; | 2553 | goto e_scratch; |
| 2534 | } | 2554 | } |
| 2535 | 2555 | ||
| 2536 | scratch_gpa_end = scratch_gpa_beg + len; | 2556 | scratch_gpa_end = scratch_gpa_beg + len; |
| 2537 | if (scratch_gpa_end < scratch_gpa_beg) { | 2557 | if (scratch_gpa_end < scratch_gpa_beg) { |
| 2538 | pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n", | 2558 | pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n", |
| 2539 | len, scratch_gpa_beg); | 2559 | len, scratch_gpa_beg); |
| 2540 | return false; | 2560 | goto e_scratch; |
| 2541 | } | 2561 | } |
| 2542 | 2562 | ||
| 2543 | if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) { | 2563 | if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) { |
| @@ -2555,7 +2575,7 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 11 unmodified lines | |||
| 2555 | scratch_gpa_end > ghcb_scratch_end) { | 2575 | scratch_gpa_end > ghcb_scratch_end) { |
| 2556 | pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n", | 2576 | pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n", |
| 2557 | scratch_gpa_beg, scratch_gpa_end); | 2577 | scratch_gpa_beg, scratch_gpa_end); |
| 2558 | return false; | 2578 | goto e_scratch; |
| 2559 | } | 2579 | } |
| 2560 | 2580 | ||
| 2561 | scratch_va = (void *)svm->sev_es.ghcb; | 2581 | scratch_va = (void *)svm->sev_es.ghcb; |
| @@ -2568,18 +2588,18 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 6 unmodified lines | |||
| 2568 | if (len > GHCB_SCRATCH_AREA_LIMIT) { | 2588 | if (len > GHCB_SCRATCH_AREA_LIMIT) { |
| 2569 | pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n", | 2589 | pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n", |
| 2570 | len, GHCB_SCRATCH_AREA_LIMIT); | 2590 | len, GHCB_SCRATCH_AREA_LIMIT); |
| 2571 | return false; | 2591 | goto e_scratch; |
| 2572 | } | 2592 | } |
| 2573 | scratch_va = kzalloc(len, GFP_KERNEL_ACCOUNT); | 2593 | scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT); |
| 2574 | if (!scratch_va) | 2594 | if (!scratch_va) |
| 2575 | return false; | 2595 | goto e_scratch; |
| 2576 | 2596 | ||
| 2577 | if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) { | 2597 | if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) { |
| 2578 | /* Unable to copy scratch area from guest */ | 2598 | /* Unable to copy scratch area from guest */ |
| 2579 | pr_err("vmgexit: kvm_read_guest for scratch area failed\n"); | 2599 | pr_err("vmgexit: kvm_read_guest for scratch area failed\n"); |
| 2580 | 2600 | ||
| 2581 | kfree(scratch_va); | 2601 | kvfree(scratch_va); |
| 2582 | return false; | 2602 | goto e_scratch; |
| 2583 | } | 2603 | } |
| 2584 | 2604 | ||
| 2585 | /* | 2605 | /* |
| @@ -2596,6 +2616,12 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) · 10 unmodified lines | |||
| 2596 | svm->sev_es.ghcb_sa_len = len; | 2616 | svm->sev_es.ghcb_sa_len = len; |
| 2597 | 2617 | ||
| 2598 | return true; | 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; | ||
| 2599 | } | 2625 | } |
| 2600 | 2626 | ||
| 2601 | static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask, | 2627 | static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask, |
| @@ -2646,7 +2672,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) · 44 unmodified lines | |||
| 2646 | 2672 | ||
| 2647 | ret = svm_invoke_exit_handler(vcpu, SVM_EXIT_CPUID); | 2673 | ret = svm_invoke_exit_handler(vcpu, SVM_EXIT_CPUID); |
| 2648 | if (!ret) { | 2674 | if (!ret) { |
| 2649 | ret = -EINVAL; | 2675 | /* Error, keep GHCB MSR value as-is */ |
| 2650 | break; | 2676 | break; |
| 2651 | } | 2677 | } |
| 2652 | 2678 | ||
| @@ -2682,10 +2708,13 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) · 29 unmodified lines | |||
| 2682 | GHCB_MSR_TERM_REASON_POS); | 2708 | GHCB_MSR_TERM_REASON_POS); |
| 2683 | pr_info("SEV-ES guest requested termination: %#llx:%#llx\n", | 2709 | pr_info("SEV-ES guest requested termination: %#llx:%#llx\n", |
| 2684 | reason_set, reason_code); | 2710 | reason_set, reason_code); |
| 2685 | fallthrough; | 2711 | |
| 2712 | ret = -EINVAL; | ||
| 2713 | break; | ||
| 2686 | } | 2714 | } |
| 2687 | default: | 2715 | default: |
| 2688 | ret = -EINVAL; | 2716 | /* Error, keep GHCB MSR value as-is */ |
| 2717 | break; | ||
| 2689 | } | 2718 | } |
| 2690 | 2719 | ||
| 2691 | trace_kvm_vmgexit_msr_protocol_exit(svm->vcpu.vcpu_id, | 2720 | trace_kvm_vmgexit_msr_protocol_exit(svm->vcpu.vcpu_id, |
| @@ -2709,14 +2738,18 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 17 unmodified lines | |||
| 2709 | 2738 | ||
| 2710 | if (!ghcb_gpa) { | 2739 | if (!ghcb_gpa) { |
| 2711 | vcpu_unimpl(vcpu, "vmgexit: GHCB gpa is not set\n"); | 2740 | vcpu_unimpl(vcpu, "vmgexit: GHCB gpa is not set\n"); |
| 2712 | return -EINVAL; | 2741 | |
| 2742 | /* Without a GHCB, just return right back to the guest */ | ||
| 2743 | return 1; | ||
| 2713 | } | 2744 | } |
| 2714 | 2745 | ||
| 2715 | if (kvm_vcpu_map(vcpu, ghcb_gpa >> PAGE_SHIFT, &svm->sev_es.ghcb_map)) { | 2746 | if (kvm_vcpu_map(vcpu, ghcb_gpa >> PAGE_SHIFT, &svm->sev_es.ghcb_map)) { |
| 2716 | /* Unable to map GHCB from guest */ | 2747 | /* Unable to map GHCB from guest */ |
| 2717 | vcpu_unimpl(vcpu, "vmgexit: error mapping GHCB [%#llx] from guest\n", | 2748 | vcpu_unimpl(vcpu, "vmgexit: error mapping GHCB [%#llx] from guest\n", |
| 2718 | ghcb_gpa); | 2749 | ghcb_gpa); |
| 2719 | return -EINVAL; | 2750 | |
| 2751 | /* Without a GHCB, just return right back to the guest */ | ||
| 2752 | return 1; | ||
| 2720 | } | 2753 | } |
| 2721 | 2754 | ||
| 2722 | svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva; | 2755 | svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva; |
| @@ -2726,15 +2759,14 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 3 unmodified lines | |||
| 2726 | 2759 | ||
| 2727 | exit_code = ghcb_get_sw_exit_code(ghcb); | 2760 | exit_code = ghcb_get_sw_exit_code(ghcb); |
| 2728 | 2761 | ||
| 2729 | ret = sev_es_validate_vmgexit(svm); | 2762 | if (!sev_es_validate_vmgexit(svm)) |
| 2730 | if (ret) | 2763 | return 1; |
| 2731 | return ret; | ||
| 2732 | 2764 | ||
| 2733 | sev_es_sync_from_ghcb(svm); | 2765 | sev_es_sync_from_ghcb(svm); |
| 2734 | ghcb_set_sw_exit_info_1(ghcb, 0); | 2766 | ghcb_set_sw_exit_info_1(ghcb, 0); |
| 2735 | ghcb_set_sw_exit_info_2(ghcb, 0); | 2767 | ghcb_set_sw_exit_info_2(ghcb, 0); |
| 2736 | 2768 | ||
| 2737 | ret = -EINVAL; | 2769 | ret = 1; |
| 2738 | switch (exit_code) { | 2770 | switch (exit_code) { |
| 2739 | case SVM_VMGEXIT_MMIO_READ: | 2771 | case SVM_VMGEXIT_MMIO_READ: |
| 2740 | if (!setup_vmgexit_scratch(svm, true, control->exit_info_2)) | 2772 | if (!setup_vmgexit_scratch(svm, true, control->exit_info_2)) |
| @@ -2775,20 +2807,17 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) · 34 unmodified lines | |||
| 2775 | default: | 2807 | default: |
| 2776 | pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n", | 2808 | pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n", |
| 2777 | control->exit_info_1); | 2809 | control->exit_info_1); |
| 2778 | ghcb_set_sw_exit_info_1(ghcb, 1); | 2810 | ghcb_set_sw_exit_info_1(ghcb, 2); |
| 2779 | ghcb_set_sw_exit_info_2(ghcb, | 2811 | ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_INPUT); |
| 2780 | X86_TRAP_UD | | ||
| 2781 | SVM_EVTINJ_TYPE_EXEPT | | ||
| 2782 | SVM_EVTINJ_VALID); | ||
| 2783 | } | 2812 | } |
| 2784 | 2813 | ||
| 2785 | ret = 1; | ||
| 2786 | break; | 2814 | break; |
| 2787 | } | 2815 | } |
| 2788 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: | 2816 | case SVM_VMGEXIT_UNSUPPORTED_EVENT: |
| 2789 | vcpu_unimpl(vcpu, | 2817 | vcpu_unimpl(vcpu, |
| 2790 | "vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n", | 2818 | "vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n", |
| 2791 | control->exit_info_1, control->exit_info_2); | 2819 | control->exit_info_1, control->exit_info_2); |
| 2820 | ret = -EINVAL; | ||
| 2792 | break; | 2821 | break; |
| 2793 | default: | 2822 | default: |
| 2794 | ret = svm_invoke_exit_handler(vcpu, exit_code); | 2823 | ret = svm_invoke_exit_handler(vcpu, exit_code); |
| @@ -2810,7 +2839,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) · 15 unmodified lines | |||
| 2810 | return -EINVAL; | 2839 | return -EINVAL; |
| 2811 | 2840 | ||
| 2812 | if (!setup_vmgexit_scratch(svm, in, bytes)) | 2841 | if (!setup_vmgexit_scratch(svm, in, bytes)) |
| 2813 | return -EINVAL; | 2842 | return 1; |
| 2814 | 2843 | ||
| 2815 | return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->sev_es.ghcb_sa, | 2844 | return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->sev_es.ghcb_sa, |
| 2816 | count, in); | 2845 | count, in); |
| @@ -4651,7 +4651,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { · 4650 unmodified lines | |||
| 4651 | .load_eoi_exitmap = svm_load_eoi_exitmap, | 4651 | .load_eoi_exitmap = svm_load_eoi_exitmap, |
| 4652 | .hwapic_irr_update = svm_hwapic_irr_update, | 4652 | .hwapic_irr_update = svm_hwapic_irr_update, |
| 4653 | .hwapic_isr_update = svm_hwapic_isr_update, | 4653 | .hwapic_isr_update = svm_hwapic_isr_update, |
| 4654 | .sync_pir_to_irr = kvm_lapic_find_highest_irr, | ||
| 4655 | .apicv_post_state_restore = avic_post_state_restore, | 4654 | .apicv_post_state_restore = avic_post_state_restore, |
| 4656 | 4655 | ||
| 4657 | .set_tss_addr = svm_set_tss_addr, | 4656 | .set_tss_addr = svm_set_tss_addr, |
| @@ -79,6 +79,7 @@ struct kvm_sev_info { · 78 unmodified lines | |||
| 79 | struct list_head regions_list; /* List of registered regions */ | 79 | struct list_head regions_list; /* List of registered regions */ |
| 80 | u64 ap_jump_table; /* SEV-ES AP Jump Table address */ | 80 | u64 ap_jump_table; /* SEV-ES AP Jump Table address */ |
| 81 | struct kvm *enc_context_owner; /* Owner of copied encryption context */ | 81 | struct kvm *enc_context_owner; /* Owner of copied encryption context */ |
| 82 | unsigned long num_mirrored_vms; /* Number of VMs sharing this ASID */ | ||
| 82 | struct misc_cg *misc_cg; /* For misc cgroup accounting */ | 83 | struct misc_cg *misc_cg; /* For misc cgroup accounting */ |
| 83 | atomic_t migration_in_progress; | 84 | atomic_t migration_in_progress; |
| 84 | }; | 85 | }; |
| @@ -1162,29 +1162,26 @@ static void nested_vmx_transition_tlb_flush(struct kvm_vcpu *vcpu, · 1161 unmodified lines | |||
| 1162 | WARN_ON(!enable_vpid); | 1162 | WARN_ON(!enable_vpid); |
| 1163 | 1163 | ||
| 1164 | /* | 1164 | /* |
| 1165 | * If VPID is enabled and used by vmc12, but L2 does not have a unique | 1165 | * VPID is enabled and in use by vmcs12. If vpid12 is changing, then |
| 1166 | * TLB tag (ASID), i.e. EPT is disabled and KVM was unable to allocate | 1166 | * emulate a guest TLB flush as KVM does not track vpid12 history nor |
| 1167 | * a VPID for L2, flush the current context as the effective ASID is | 1167 | * is the VPID incorporated into the MMU context. I.e. KVM must assume |
| 1168 | * common to both L1 and L2. | 1168 | * that the new vpid12 has never been used and thus represents a new |
| 1169 | * | 1169 | * guest ASID that cannot have entries in the TLB. |
| 1170 | * Defer the flush so that it runs after vmcs02.EPTP has been set by | ||
| 1171 | * KVM_REQ_LOAD_MMU_PGD (if nested EPT is enabled) and to avoid | ||
| 1172 | * redundant flushes further down the nested pipeline. | ||
| 1173 | * | ||
| 1174 | * If a TLB flush isn't required due to any of the above, and vpid12 is | ||
| 1175 | * changing then the new "virtual" VPID (vpid12) will reuse the same | ||
| 1176 | * "real" VPID (vpid02), and so needs to be flushed. There's no direct | ||
| 1177 | * mapping between vpid02 and vpid12, vpid02 is per-vCPU and reused for | ||
| 1178 | * all nested vCPUs. Remember, a flush on VM-Enter does not invalidate | ||
| 1179 | * guest-physical mappings, so there is no need to sync the nEPT MMU. | ||
| 1180 | */ | 1170 | */ |
| 1181 | if (!nested_has_guest_tlb_tag(vcpu)) { | 1171 | if (is_vmenter && vmcs12->virtual_processor_id != vmx->nested.last_vpid) { |
| 1182 | kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); | ||
| 1183 | } else if (is_vmenter && | ||
| 1184 | vmcs12->virtual_processor_id != vmx->nested.last_vpid) { | ||
| 1185 | vmx->nested.last_vpid = vmcs12->virtual_processor_id; | 1172 | vmx->nested.last_vpid = vmcs12->virtual_processor_id; |
| 1186 | vpid_sync_context(nested_get_vpid02(vcpu)); | 1173 | kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); |
| 1174 | return; | ||
| 1187 | } | 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); | ||
| 1188 | } | 1185 | } |
| 1189 | 1186 | ||
| 1190 | static bool is_bitwise_subset(u64 superset, u64 subset, u64 mask) | 1187 | static bool is_bitwise_subset(u64 superset, u64 subset, u64 mask) |
| @@ -2594,8 +2591,10 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, · 1403 unmodified lines | |||
| 2594 | 2591 | ||
| 2595 | if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) && | 2592 | if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) && |
| 2596 | WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL, | 2593 | WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL, |
| 2597 | vmcs12->guest_ia32_perf_global_ctrl))) | 2594 | vmcs12->guest_ia32_perf_global_ctrl))) { |
| 2595 | *entry_failure_code = ENTRY_FAIL_DEFAULT; | ||
| 2598 | return -EINVAL; | 2596 | return -EINVAL; |
| 2597 | } | ||
| 2599 | 2598 | ||
| 2600 | kvm_rsp_write(vcpu, vmcs12->guest_rsp); | 2599 | kvm_rsp_write(vcpu, vmcs12->guest_rsp); |
| 2601 | kvm_rip_write(vcpu, vmcs12->guest_rip); | 2600 | kvm_rip_write(vcpu, vmcs12->guest_rip); |
| @@ -3344,8 +3343,7 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, · 742 unmodified lines | |||
| 3344 | }; | 3343 | }; |
| 3345 | u32 failed_index; | 3344 | u32 failed_index; |
| 3346 | 3345 | ||
| 3347 | if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) | 3346 | kvm_service_local_tlb_flush_requests(vcpu); |
| 3348 | kvm_vcpu_flush_tlb_current(vcpu); | ||
| 3349 | 3347 | ||
| 3350 | evaluate_pending_interrupts = exec_controls_get(vmx) & | 3348 | evaluate_pending_interrupts = exec_controls_get(vmx) & |
| 3351 | (CPU_BASED_INTR_WINDOW_EXITING | CPU_BASED_NMI_WINDOW_EXITING); | 3349 | (CPU_BASED_INTR_WINDOW_EXITING | CPU_BASED_NMI_WINDOW_EXITING); |
| @@ -4502,9 +4500,8 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, · 1150 unmodified lines | |||
| 4502 | (void)nested_get_evmcs_page(vcpu); | 4500 | (void)nested_get_evmcs_page(vcpu); |
| 4503 | } | 4501 | } |
| 4504 | 4502 | ||
| 4505 | /* Service the TLB flush request for L2 before switching to L1. */ | 4503 | /* Service pending TLB flush requests for L2 before switching to L1. */ |
| 4506 | if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) | 4504 | kvm_service_local_tlb_flush_requests(vcpu); |
| 4507 | kvm_vcpu_flush_tlb_current(vcpu); | ||
| 4508 | 4505 | ||
| 4509 | /* | 4506 | /* |
| 4510 | * VCPU_EXREG_PDPTR will be clobbered in arch/x86/kvm/vmx/vmx.h between | 4507 | * VCPU_EXREG_PDPTR will be clobbered in arch/x86/kvm/vmx/vmx.h between |
| @@ -4857,6 +4854,7 @@ static int enter_vmx_operation(struct kvm_vcpu *vcpu) · 346 unmodified lines | |||
| 4857 | if (!vmx->nested.cached_vmcs12) | 4854 | if (!vmx->nested.cached_vmcs12) |
| 4858 | goto out_cached_vmcs12; | 4855 | goto out_cached_vmcs12; |
| 4859 | 4856 | ||
| 4857 | vmx->nested.shadow_vmcs12_cache.gpa = INVALID_GPA; | ||
| 4860 | vmx->nested.cached_shadow_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL_ACCOUNT); | 4858 | vmx->nested.cached_shadow_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL_ACCOUNT); |
| 4861 | if (!vmx->nested.cached_shadow_vmcs12) | 4859 | if (!vmx->nested.cached_shadow_vmcs12) |
| 4862 | goto out_cached_shadow_vmcs12; | 4860 | goto out_cached_shadow_vmcs12; |
| @@ -5289,8 +5287,7 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu) · 426 unmodified lines | |||
| 5289 | struct gfn_to_hva_cache *ghc = &vmx->nested.vmcs12_cache; | 5287 | struct gfn_to_hva_cache *ghc = &vmx->nested.vmcs12_cache; |
| 5290 | struct vmcs_hdr hdr; | 5288 | struct vmcs_hdr hdr; |
| 5291 | 5289 | ||
| 5292 | if (ghc->gpa != vmptr && | 5290 | if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, vmptr, VMCS12_SIZE)) { |
| 5293 | kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, vmptr, VMCS12_SIZE)) { | ||
| 5294 | /* | 5291 | /* |
| 5295 | * Reads from an unbacked page return all 1s, | 5292 | * Reads from an unbacked page return all 1s, |
| 5296 | * which means that the 32 bits located at the | 5293 | * which means that the 32 bits located at the |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | #include <asm/cpu.h> | 5 | #include <asm/cpu.h> |
| 6 | 6 | ||
| 7 | #include "lapic.h" | 7 | #include "lapic.h" |
| 8 | #include "irq.h" | ||
| 8 | #include "posted_intr.h" | 9 | #include "posted_intr.h" |
| 9 | #include "trace.h" | 10 | #include "trace.h" |
| 10 | #include "vmx.h" | 11 | #include "vmx.h" |
| @@ -77,13 +78,18 @@ after_clear_sn: · 66 unmodified lines | |||
| 77 | pi_set_on(pi_desc); | 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 | void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu) | 88 | void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu) |
| 81 | { | 89 | { |
| 82 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); | 90 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); |
| 83 | 91 | ||
| 84 | if (!kvm_arch_has_assigned_device(vcpu->kvm) || | 92 | if (!vmx_can_use_vtd_pi(vcpu->kvm)) |
| 85 | !irq_remapping_cap(IRQ_POSTING_CAP) || | ||
| 86 | !kvm_vcpu_apicv_active(vcpu)) | ||
| 87 | return; | 93 | return; |
| 88 | 94 | ||
| 89 | /* Set SN when the vCPU is preempted */ | 95 | /* Set SN when the vCPU is preempted */ |
| @@ -141,9 +147,7 @@ int pi_pre_block(struct kvm_vcpu *vcpu) · 51 unmodified lines | |||
| 141 | struct pi_desc old, new; | 147 | struct pi_desc old, new; |
| 142 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); | 148 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); |
| 143 | 149 | ||
| 144 | if (!kvm_arch_has_assigned_device(vcpu->kvm) || | 150 | if (!vmx_can_use_vtd_pi(vcpu->kvm)) |
| 145 | !irq_remapping_cap(IRQ_POSTING_CAP) || | ||
| 146 | !kvm_vcpu_apicv_active(vcpu)) | ||
| 147 | return 0; | 151 | return 0; |
| 148 | 152 | ||
| 149 | WARN_ON(irqs_disabled()); | 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 | struct vcpu_data vcpu_info; | 274 | struct vcpu_data vcpu_info; |
| 271 | int idx, ret = 0; | 275 | int idx, ret = 0; |
| 272 | 276 | ||
| 273 | if (!kvm_arch_has_assigned_device(kvm) || | 277 | if (!vmx_can_use_vtd_pi(kvm)) |
| 274 | !irq_remapping_cap(IRQ_POSTING_CAP) || | ||
| 275 | !kvm_vcpu_apicv_active(kvm->vcpus[0])) | ||
| 276 | return 0; | 278 | return 0; |
| 277 | 279 | ||
| 278 | idx = srcu_read_lock(&kvm->irq_srcu); | 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 | if (!loaded_vmcs->msr_bitmap) | 2646 | if (!loaded_vmcs->msr_bitmap) |
| 2647 | goto out_vmcs; | 2647 | goto out_vmcs; |
| 2648 | memset(loaded_vmcs->msr_bitmap, 0xff, PAGE_SIZE); | 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 | memset(&loaded_vmcs->host_state, 0, sizeof(struct vmcs_host_state)); | 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 | static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) | 2919 | static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) |
| 2922 | { | 2920 | { |
| 2923 | struct kvm_mmu *mmu = vcpu->arch.mmu; | 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 | if (enable_ept) | 2928 | if (enable_ept) |
| 2931 | ept_sync_context(construct_eptp(vcpu, root_hpa, | 2929 | ept_sync_context(construct_eptp(vcpu, root_hpa, |
| 2932 | mmu->shadow_root_level)); | 2930 | mmu->shadow_root_level)); |
| 2933 | else if (!is_guest_mode(vcpu)) | ||
| 2934 | vpid_sync_context(to_vmx(vcpu)->vpid); | ||
| 2935 | else | 2931 | else |
| 2936 | vpid_sync_context(nested_get_vpid02(vcpu)); | 2932 | vpid_sync_context(vmx_get_current_vpid(vcpu)); |
| 2937 | } | 2933 | } |
| 2938 | 2934 | ||
| 2939 | static void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr) | 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 | * vmx_flush_tlb_guest() for an explanation of why this is ok. | 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 | static void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu) | 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 | 2947 | * vpid_sync_context() is a nop if vpid==0, e.g. if enable_vpid==0 or a |
| 2952 | * or a vpid couldn't be allocated for this vCPU. VM-Enter and VM-Exit | 2948 | * vpid couldn't be allocated for this vCPU. VM-Enter and VM-Exit are |
| 2953 | * are required to flush GVA->{G,H}PA mappings from the TLB if vpid is | 2949 | * required to flush GVA->{G,H}PA mappings from the TLB if vpid is |
| 2954 | * disabled (VM-Enter with vpid enabled and vpid==0 is disallowed), | 2950 | * disabled (VM-Enter with vpid enabled and vpid==0 is disallowed), |
| 2955 | * i.e. no explicit INVVPID is necessary. | 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 | void vmx_ept_load_pdptrs(struct kvm_vcpu *vcpu) | 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 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 6259 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 6264 | int max_irr; | 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 | return -EIO; | 6264 | return -EIO; |
| 6269 | 6265 | ||
| 6270 | if (pi_test_on(&vmx->pi_desc)) { | 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 | * But on x86 this is just a compiler barrier anyway. | 6270 | * But on x86 this is just a compiler barrier anyway. |
| 6275 | */ | 6271 | */ |
| 6276 | smp_mb__after_atomic(); | 6272 | smp_mb__after_atomic(); |
| 6277 | max_irr_updated = | 6273 | got_posted_interrupt = |
| 6278 | kvm_apic_update_irr(vcpu, vmx->pi_desc.pir, &max_irr); | 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 | } else { | 6275 | } else { |
| 6290 | max_irr = kvm_lapic_find_highest_irr(vcpu); | 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 | return max_irr; | 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 | if (err < 0) | 6833 | if (err < 0) |
| 6827 | goto free_pml; | 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 | /* The MSR bitmap starts with all ones */ | 6849 | /* The MSR bitmap starts with all ones */ |
| 6830 | bitmap_fill(vmx->shadow_msr_intercept.read, MAX_POSSIBLE_PASSTHROUGH_MSRS); | 6850 | bitmap_fill(vmx->shadow_msr_intercept.read, MAX_POSSIBLE_PASSTHROUGH_MSRS); |
| 6831 | bitmap_fill(vmx->shadow_msr_intercept.write, MAX_POSSIBLE_PASSTHROUGH_MSRS); | 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 | static bool vmx_check_apicv_inhibit_reasons(ulong bit) | 7529 | static bool vmx_check_apicv_inhibit_reasons(ulong bit) |
| 7510 | { | 7530 | { |
| 7511 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | | 7531 | ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) | |
| 7532 | BIT(APICV_INHIBIT_REASON_ABSENT) | | ||
| 7512 | BIT(APICV_INHIBIT_REASON_HYPERV) | | 7533 | BIT(APICV_INHIBIT_REASON_HYPERV) | |
| 7513 | BIT(APICV_INHIBIT_REASON_BLOCKIRQ); | 7534 | BIT(APICV_INHIBIT_REASON_BLOCKIRQ); |
| 7514 | 7535 | ||
| @@ -7761,10 +7782,10 @@ static __init int hardware_setup(void) · 246 unmodified lines | |||
| 7761 | ple_window_shrink = 0; | 7782 | ple_window_shrink = 0; |
| 7762 | } | 7783 | } |
| 7763 | 7784 | ||
| 7764 | if (!cpu_has_vmx_apicv()) { | 7785 | if (!cpu_has_vmx_apicv()) |
| 7765 | enable_apicv = 0; | 7786 | enable_apicv = 0; |
| 7787 | if (!enable_apicv) | ||
| 7766 | vmx_x86_ops.sync_pir_to_irr = NULL; | 7788 | vmx_x86_ops.sync_pir_to_irr = NULL; |
| 7767 | } | ||
| 7768 | 7789 | ||
| 7769 | if (cpu_has_vmx_tsc_scaling()) { | 7790 | if (cpu_has_vmx_tsc_scaling()) { |
| 7770 | kvm_has_tsc_control = true; | 7791 | kvm_has_tsc_control = true; |
| @@ -890,7 +890,8 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) · 889 unmodified lines | |||
| 890 | !load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu))) | 890 | !load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu))) |
| 891 | return 1; | 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 | return 1; | 895 | return 1; |
| 895 | 896 | ||
| 896 | static_call(kvm_x86_set_cr0)(vcpu, cr0); | 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 | static_call(kvm_x86_tlb_flush_guest)(vcpu); | 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 | static void record_steal_time(struct kvm_vcpu *vcpu) | 3285 | static void record_steal_time(struct kvm_vcpu *vcpu) |
| 3262 | { | 3286 | { |
| 3263 | struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; | 3287 | struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; |
| @@ -4133,6 +4157,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 869 unmodified lines | |||
| 4133 | case KVM_CAP_SGX_ATTRIBUTE: | 4157 | case KVM_CAP_SGX_ATTRIBUTE: |
| 4134 | #endif | 4158 | #endif |
| 4135 | case KVM_CAP_VM_COPY_ENC_CONTEXT_FROM: | 4159 | case KVM_CAP_VM_COPY_ENC_CONTEXT_FROM: |
| 4160 | case KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM: | ||
| 4136 | case KVM_CAP_SREGS2: | 4161 | case KVM_CAP_SREGS2: |
| 4137 | case KVM_CAP_EXIT_ON_EMULATION_FAILURE: | 4162 | case KVM_CAP_EXIT_ON_EMULATION_FAILURE: |
| 4138 | case KVM_CAP_VCPU_ATTRIBUTES: | 4163 | case KVM_CAP_VCPU_ATTRIBUTES: |
| @@ -4448,8 +4473,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) · 309 unmodified lines | |||
| 4448 | static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, | 4473 | static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, |
| 4449 | struct kvm_lapic_state *s) | 4474 | struct kvm_lapic_state *s) |
| 4450 | { | 4475 | { |
| 4451 | if (vcpu->arch.apicv_active) | 4476 | static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); |
| 4452 | static_call(kvm_x86_sync_pir_to_irr)(vcpu); | ||
| 4453 | 4477 | ||
| 4454 | return kvm_apic_get_state(vcpu, s); | 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 | struct kvm_cpuid __user *cpuid_arg = argp; | 5148 | struct kvm_cpuid __user *cpuid_arg = argp; |
| 5125 | struct kvm_cpuid cpuid; | 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 | r = -EFAULT; | 5162 | r = -EFAULT; |
| 5128 | if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid))) | 5163 | if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid))) |
| 5129 | goto out; | 5164 | goto out; |
| @@ -5134,6 +5169,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 4 unmodified lines | |||
| 5134 | struct kvm_cpuid2 __user *cpuid_arg = argp; | 5169 | struct kvm_cpuid2 __user *cpuid_arg = argp; |
| 5135 | struct kvm_cpuid2 cpuid; | 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 | r = -EFAULT; | 5180 | r = -EFAULT; |
| 5138 | if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid))) | 5181 | if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid))) |
| 5139 | goto out; | 5182 | goto out; |
| @@ -5698,6 +5741,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, · 558 unmodified lines | |||
| 5698 | smp_wmb(); | 5741 | smp_wmb(); |
| 5699 | kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT; | 5742 | kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT; |
| 5700 | kvm->arch.nr_reserved_ioapic_pins = cap->args[0]; | 5743 | kvm->arch.nr_reserved_ioapic_pins = cap->args[0]; |
| 5744 | kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT); | ||
| 5701 | r = 0; | 5745 | r = 0; |
| 5702 | split_irqchip_unlock: | 5746 | split_irqchip_unlock: |
| 5703 | mutex_unlock(&kvm->lock); | 5747 | mutex_unlock(&kvm->lock); |
| @@ -6078,6 +6122,7 @@ set_identity_unlock: · 374 unmodified lines | |||
| 6078 | /* Write kvm->irq_routing before enabling irqchip_in_kernel. */ | 6122 | /* Write kvm->irq_routing before enabling irqchip_in_kernel. */ |
| 6079 | smp_wmb(); | 6123 | smp_wmb(); |
| 6080 | kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL; | 6124 | kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL; |
| 6125 | kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT); | ||
| 6081 | create_irqchip_unlock: | 6126 | create_irqchip_unlock: |
| 6082 | mutex_unlock(&kvm->lock); | 6127 | mutex_unlock(&kvm->lock); |
| 6083 | break; | 6128 | break; |
| @@ -7077,7 +7122,13 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size, · 993 unmodified lines | |||
| 7077 | unsigned short port, void *val, unsigned int count) | 7122 | unsigned short port, void *val, unsigned int count) |
| 7078 | { | 7123 | { |
| 7079 | if (vcpu->arch.pio.count) { | 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 | } else { | 7132 | } else { |
| 7082 | int r = __emulator_pio_in(vcpu, size, port, count); | 7133 | int r = __emulator_pio_in(vcpu, size, port, count); |
| 7083 | if (!r) | 7134 | if (!r) |
| @@ -7086,7 +7137,6 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size, · 2 unmodified lines | |||
| 7086 | /* Results already available, fall through. */ | 7137 | /* Results already available, fall through. */ |
| 7087 | } | 7138 | } |
| 7088 | 7139 | ||
| 7089 | WARN_ON(count != vcpu->arch.pio.count); | ||
| 7090 | complete_emulator_pio_in(vcpu, val); | 7140 | complete_emulator_pio_in(vcpu, val); |
| 7091 | return 1; | 7141 | return 1; |
| 7092 | } | 7142 | } |
| @@ -8776,10 +8826,9 @@ static void kvm_apicv_init(struct kvm *kvm) · 1683 unmodified lines | |||
| 8776 | { | 8826 | { |
| 8777 | init_rwsem(&kvm->arch.apicv_update_lock); | 8827 | init_rwsem(&kvm->arch.apicv_update_lock); |
| 8778 | 8828 | ||
| 8779 | if (enable_apicv) | 8829 | set_bit(APICV_INHIBIT_REASON_ABSENT, |
| 8780 | clear_bit(APICV_INHIBIT_REASON_DISABLE, | 8830 | &kvm->arch.apicv_inhibit_reasons); |
| 8781 | &kvm->arch.apicv_inhibit_reasons); | 8831 | if (!enable_apicv) |
| 8782 | else | ||
| 8783 | set_bit(APICV_INHIBIT_REASON_DISABLE, | 8832 | set_bit(APICV_INHIBIT_REASON_DISABLE, |
| 8784 | &kvm->arch.apicv_inhibit_reasons); | 8833 | &kvm->arch.apicv_inhibit_reasons); |
| 8785 | } | 8834 | } |
| @@ -9528,8 +9577,7 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) · 742 unmodified lines | |||
| 9528 | if (irqchip_split(vcpu->kvm)) | 9577 | if (irqchip_split(vcpu->kvm)) |
| 9529 | kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); | 9578 | kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); |
| 9530 | else { | 9579 | else { |
| 9531 | if (vcpu->arch.apicv_active) | 9580 | static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); |
| 9532 | static_call(kvm_x86_sync_pir_to_irr)(vcpu); | ||
| 9533 | if (ioapic_in_kernel(vcpu->kvm)) | 9581 | if (ioapic_in_kernel(vcpu->kvm)) |
| 9534 | kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); | 9582 | kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); |
| 9535 | } | 9583 | } |
| @@ -9648,10 +9696,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 112 unmodified lines | |||
| 9648 | /* Flushing all ASIDs flushes the current ASID... */ | 9696 | /* Flushing all ASIDs flushes the current ASID... */ |
| 9649 | kvm_clear_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); | 9697 | kvm_clear_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); |
| 9650 | } | 9698 | } |
| 9651 | if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) | 9699 | kvm_service_local_tlb_flush_requests(vcpu); |
| 9652 | kvm_vcpu_flush_tlb_current(vcpu); | ||
| 9653 | if (kvm_check_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu)) | ||
| 9654 | kvm_vcpu_flush_tlb_guest(vcpu); | ||
| 9655 | 9700 | ||
| 9656 | if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) { | 9701 | if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) { |
| 9657 | vcpu->run->exit_reason = KVM_EXIT_TPR_ACCESS; | 9702 | vcpu->run->exit_reason = KVM_EXIT_TPR_ACCESS; |
| @@ -9802,10 +9847,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 144 unmodified lines | |||
| 9802 | 9847 | ||
| 9803 | /* | 9848 | /* |
| 9804 | * This handles the case where a posted interrupt was | 9849 | * This handles the case where a posted interrupt was |
| 9805 | * 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. | ||
| 9806 | */ | 9853 | */ |
| 9807 | if (kvm_lapic_enabled(vcpu) && vcpu->arch.apicv_active) | 9854 | if (kvm_lapic_enabled(vcpu)) |
| 9808 | static_call(kvm_x86_sync_pir_to_irr)(vcpu); | 9855 | static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); |
| 9809 | 9856 | ||
| 9810 | if (kvm_vcpu_exit_request(vcpu)) { | 9857 | if (kvm_vcpu_exit_request(vcpu)) { |
| 9811 | vcpu->mode = OUTSIDE_GUEST_MODE; | 9858 | vcpu->mode = OUTSIDE_GUEST_MODE; |
| @@ -9849,8 +9896,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 37 unmodified lines | |||
| 9849 | if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST)) | 9896 | if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST)) |
| 9850 | break; | 9897 | break; |
| 9851 | 9898 | ||
| 9852 | if (vcpu->arch.apicv_active) | 9899 | if (kvm_lapic_enabled(vcpu)) |
| 9853 | static_call(kvm_x86_sync_pir_to_irr)(vcpu); | 9900 | static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); |
| 9854 | 9901 | ||
| 9855 | if (unlikely(kvm_vcpu_exit_request(vcpu))) { | 9902 | if (unlikely(kvm_vcpu_exit_request(vcpu))) { |
| 9856 | exit_fastpath = EXIT_FASTPATH_EXIT_HANDLED; | 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 | #define MSR_IA32_CR_PAT_DEFAULT 0x0007040600070406ULL | 104 | #define MSR_IA32_CR_PAT_DEFAULT 0x0007040600070406ULL |
| 105 | 105 | ||
| 106 | void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu); | ||
| 106 | int kvm_check_nested_events(struct kvm_vcpu *vcpu); | 107 | int kvm_check_nested_events(struct kvm_vcpu *vcpu); |
| 107 | 108 | ||
| 108 | static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu) | 109 | static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu) |
| @@ -185,12 +186,6 @@ static inline bool mmu_is_nested(struct kvm_vcpu *vcpu) · 76 unmodified lines | |||
| 185 | return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu; | 186 | return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu; |
| 186 | } | 187 | } |
| 187 | 188 | ||
| 188 | static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu) | ||
| 189 | { | ||
| 190 | ++vcpu->stat.tlb_flush; | ||
| 191 | static_call(kvm_x86_tlb_flush_current)(vcpu); | ||
| 192 | } | ||
| 193 | |||
| 194 | static inline int is_pae(struct kvm_vcpu *vcpu) | 189 | static inline int is_pae(struct kvm_vcpu *vcpu) |
| 195 | { | 190 | { |
| 196 | return kvm_read_cr4_bits(vcpu, X86_CR4_PAE); | 191 | return kvm_read_cr4_bits(vcpu, X86_CR4_PAE); |
| @@ -277,7 +277,8 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) · 276 unmodified lines | |||
| 277 | return; | 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 | if (!new) { | 282 | if (!new) { |
| 282 | pr_err("Failed to map new boot services memmap\n"); | 283 | pr_err("Failed to map new boot services memmap\n"); |
| 283 | return; | 284 | return; |
| @@ -72,6 +72,7 @@ static void __init setup_real_mode(void) · 71 unmodified lines | |||
| 72 | #ifdef CONFIG_X86_64 | 72 | #ifdef CONFIG_X86_64 |
| 73 | u64 *trampoline_pgd; | 73 | u64 *trampoline_pgd; |
| 74 | u64 efer; | 74 | u64 efer; |
| 75 | int i; | ||
| 75 | #endif | 76 | #endif |
| 76 | 77 | ||
| 77 | base = (unsigned char *)real_mode_header; | 78 | base = (unsigned char *)real_mode_header; |
| @@ -128,8 +129,17 @@ static void __init setup_real_mode(void) · 50 unmodified lines | |||
| 128 | trampoline_header->flags = 0; | 129 | trampoline_header->flags = 0; |
| 129 | 130 | ||
| 130 | trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd); | 131 | trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd); |
| 132 | |||
| 133 | /* Map the real mode stub as virtual == physical */ | ||
| 131 | trampoline_pgd[0] = trampoline_pgd_entry.pgd; | 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 | #endif | 143 | #endif |
| 134 | 144 | ||
| 135 | sme_sev_setup_real_mode(trampoline_header); | 145 | sme_sev_setup_real_mode(trampoline_header); |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/linkage.h> | 22 | #include <linux/linkage.h> |
| 23 | #include <../entry/calling.h> | ||
| 23 | 24 | ||
| 24 | .pushsection .noinstr.text, "ax" | 25 | .pushsection .noinstr.text, "ax" |
| 25 | /* | 26 | /* |
| @@ -192,6 +193,25 @@ SYM_CODE_START(xen_iret) · 166 unmodified lines | |||
| 192 | jmp hypercall_iret | 193 | jmp hypercall_iret |
| 193 | SYM_CODE_END(xen_iret) | 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 | * Xen handles syscall callbacks much like ordinary exceptions, which | 216 | * Xen handles syscall callbacks much like ordinary exceptions, which |
| 197 | * means we have: | 217 | * means we have: |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/falloc.h> | 15 | #include <linux/falloc.h> |
| 16 | #include <linux/suspend.h> | 16 | #include <linux/suspend.h> |
| 17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| 18 | #include <linux/module.h> | ||
| 18 | #include "blk.h" | 19 | #include "blk.h" |
| 19 | 20 | ||
| 20 | static inline struct inode *bdev_file_inode(struct file *file) | 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 | } else { | 341 | } else { |
| 341 | ret = bio_iov_iter_get_pages(bio, iter); | 342 | ret = bio_iov_iter_get_pages(bio, iter); |
| 342 | if (unlikely(ret)) { | 343 | if (unlikely(ret)) { |
| 343 | bio->bi_status = BLK_STS_IOERR; | 344 | bio_put(bio); |
| 344 | bio_endio(bio); | ||
| 345 | return ret; | 345 | return ret; |
| 346 | } | 346 | } |
| 347 | } | 347 | } |
| @@ -220,6 +220,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) · 219 unmodified lines | |||
| 220 | pgrp = task_pgrp(current); | 220 | pgrp = task_pgrp(current); |
| 221 | else | 221 | else |
| 222 | pgrp = find_vpid(who); | 222 | pgrp = find_vpid(who); |
| 223 | read_lock(&tasklist_lock); | ||
| 223 | do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { | 224 | do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { |
| 224 | tmpio = get_task_ioprio(p); | 225 | tmpio = get_task_ioprio(p); |
| 225 | if (tmpio < 0) | 226 | if (tmpio < 0) |
| @@ -229,6 +230,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) · 3 unmodified lines | |||
| 229 | else | 230 | else |
| 230 | ret = ioprio_best(ret, tmpio); | 231 | ret = ioprio_best(ret, tmpio); |
| 231 | } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); | 232 | } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); |
| 233 | read_unlock(&tasklist_lock); | ||
| 234 | |||
| 232 | break; | 235 | break; |
| 233 | case IOPRIO_WHO_USER: | 236 | case IOPRIO_WHO_USER: |
| 234 | uid = make_kuid(current_user_ns(), who); | 237 | uid = make_kuid(current_user_ns(), who); |
| @@ -4743,23 +4743,20 @@ static int binder_thread_release(struct binder_proc *proc, · 4742 unmodified lines | |||
| 4743 | __release(&t->lock); | 4743 | __release(&t->lock); |
| 4744 | 4744 | ||
| 4745 | /* | 4745 | /* |
| 4746 | * If this thread used poll, make sure we remove the waitqueue | 4746 | * If this thread used poll, make sure we remove the waitqueue from any |
| 4747 | * from any epoll data structures holding it with POLLFREE. | 4747 | * poll data structures holding it. |
| 4748 | * waitqueue_active() is safe to use here because we're holding | ||
| 4749 | * the inner lock. | ||
| 4750 | */ | 4748 | */ |
| 4751 | if ((thread->looper & BINDER_LOOPER_STATE_POLL) && | 4749 | if (thread->looper & BINDER_LOOPER_STATE_POLL) |
| 4752 | waitqueue_active(&thread->wait)) { | 4750 | wake_up_pollfree(&thread->wait); |
| 4753 | wake_up_poll(&thread->wait, EPOLLHUP | POLLFREE); | ||
| 4754 | } | ||
| 4755 | 4751 | ||
| 4756 | binder_inner_proc_unlock(thread->proc); | 4752 | binder_inner_proc_unlock(thread->proc); |
| 4757 | 4753 | ||
| 4758 | /* | 4754 | /* |
| 4759 | * This is needed to avoid races between wake_up_poll() above and | 4755 | * This is needed to avoid races between wake_up_pollfree() above and |
| 4760 | * and ep_remove_waitqueue() called for other reasons (eg the epoll file | 4756 | * someone else removing the last entry from the queue for other reasons |
| 4761 | * descriptor being closed); ep_remove_waitqueue() holds an RCU read | 4757 | * (e.g. ep_remove_wait_queue() being called due to an epoll file |
| 4762 | * lock, so we can be sure it's done after calling synchronize_rcu(). | 4758 | * descriptor being closed). Such other users hold an RCU read lock, so |
| 4759 | * we can be sure they're done after we call synchronize_rcu(). | ||
| 4763 | */ | 4760 | */ |
| 4764 | if (thread->looper & BINDER_LOOPER_STATE_POLL) | 4761 | if (thread->looper & BINDER_LOOPER_STATE_POLL) |
| 4765 | synchronize_rcu(); | 4762 | synchronize_rcu(); |
| @@ -94,6 +94,7 @@ struct ceva_ahci_priv { · 93 unmodified lines | |||
| 94 | static unsigned int ceva_ahci_read_id(struct ata_device *dev, | 94 | static unsigned int ceva_ahci_read_id(struct ata_device *dev, |
| 95 | struct ata_taskfile *tf, u16 *id) | 95 | struct ata_taskfile *tf, u16 *id) |
| 96 | { | 96 | { |
| 97 | __le16 *__id = (__le16 *)id; | ||
| 97 | u32 err_mask; | 98 | u32 err_mask; |
| 98 | 99 | ||
| 99 | err_mask = ata_do_dev_read_id(dev, tf, id); | 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 | * Since CEVA controller does not support device sleep feature, we | 104 | * Since CEVA controller does not support device sleep feature, we |
| 104 | * need to clear DEVSLP (bit 8) in word78 of the IDENTIFY DEVICE data. | 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 | return 0; | 109 | return 0; |
| 109 | } | 110 | } |
| @@ -3920,6 +3920,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { · 3919 unmodified lines | |||
| 3920 | { "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA }, | 3920 | { "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA }, |
| 3921 | /* Odd clown on sil3726/4726 PMPs */ | 3921 | /* Odd clown on sil3726/4726 PMPs */ |
| 3922 | { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, | 3922 | { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, |
| 3923 | /* Similar story with ASMedia 1092 */ | ||
| 3924 | { "ASMT109x- Config", NULL, ATA_HORKAGE_DISABLE }, | ||
| 3923 | 3925 | ||
| 3924 | /* Weird ATAPI devices */ | 3926 | /* Weird ATAPI devices */ |
| 3925 | { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, | 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 | if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) | 827 | if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) |
| 828 | return -EINVAL; | 828 | return -EINVAL; |
| 829 | 829 | ||
| 830 | return snprintf(buf, PAGE_SIZE, "%s\n", | 830 | return sysfs_emit(buf, "%s\n", |
| 831 | ata_lpm_policy_names[ap->target_lpm_policy]); | 831 | ata_lpm_policy_names[ap->target_lpm_policy]); |
| 832 | } | 832 | } |
| 833 | DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, | 833 | DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, |
| @@ -55,14 +55,14 @@ static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc, · 54 unmodified lines | |||
| 55 | /* Transfer multiple of 2 bytes */ | 55 | /* Transfer multiple of 2 bytes */ |
| 56 | if (rw == READ) { | 56 | if (rw == READ) { |
| 57 | if (swap) | 57 | if (swap) |
| 58 | raw_insw_swapw((u16 *)data_addr, (u16 *)buf, words); | 58 | raw_insw_swapw(data_addr, (u16 *)buf, words); |
| 59 | else | 59 | else |
| 60 | raw_insw((u16 *)data_addr, (u16 *)buf, words); | 60 | raw_insw(data_addr, (u16 *)buf, words); |
| 61 | } else { | 61 | } else { |
| 62 | if (swap) | 62 | if (swap) |
| 63 | raw_outsw_swapw((u16 *)data_addr, (u16 *)buf, words); | 63 | raw_outsw_swapw(data_addr, (u16 *)buf, words); |
| 64 | else | 64 | else |
| 65 | raw_outsw((u16 *)data_addr, (u16 *)buf, words); | 65 | raw_outsw(data_addr, (u16 *)buf, words); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | /* Transfer trailing byte, if any. */ | 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 | if (rw == READ) { | 75 | if (rw == READ) { |
| 76 | if (swap) | 76 | if (swap) |
| 77 | raw_insw_swapw((u16 *)data_addr, (u16 *)pad, 1); | 77 | raw_insw_swapw(data_addr, (u16 *)pad, 1); |
| 78 | else | 78 | else |
| 79 | raw_insw((u16 *)data_addr, (u16 *)pad, 1); | 79 | raw_insw(data_addr, (u16 *)pad, 1); |
| 80 | *buf = pad[0]; | 80 | *buf = pad[0]; |
| 81 | } else { | 81 | } else { |
| 82 | pad[0] = *buf; | 82 | pad[0] = *buf; |
| 83 | if (swap) | 83 | if (swap) |
| 84 | raw_outsw_swapw((u16 *)data_addr, (u16 *)pad, 1); | 84 | raw_outsw_swapw(data_addr, (u16 *)pad, 1); |
| 85 | else | 85 | else |
| 86 | raw_outsw((u16 *)data_addr, (u16 *)pad, 1); | 86 | raw_outsw(data_addr, (u16 *)pad, 1); |
| 87 | } | 87 | } |
| 88 | words++; | 88 | words++; |
| 89 | } | 89 | } |
| @@ -1394,6 +1394,14 @@ static int sata_fsl_init_controller(struct ata_host *host) · 1393 unmodified lines | |||
| 1394 | return 0; | 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 | * scsi mid-layer and libata interface structures | 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 | .port_start = sata_fsl_port_start, | 1434 | .port_start = sata_fsl_port_start, |
| 1427 | .port_stop = sata_fsl_port_stop, | 1435 | .port_stop = sata_fsl_port_stop, |
| 1428 | 1436 | ||
| 1437 | .host_stop = sata_fsl_host_stop, | ||
| 1438 | |||
| 1429 | .pmp_attach = sata_fsl_pmp_attach, | 1439 | .pmp_attach = sata_fsl_pmp_attach, |
| 1430 | .pmp_detach = sata_fsl_pmp_detach, | 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 | host_priv->ssr_base = ssr_base; | 1490 | host_priv->ssr_base = ssr_base; |
| 1481 | host_priv->csr_base = csr_base; | 1491 | host_priv->csr_base = csr_base; |
| 1482 | 1492 | ||
| 1483 | irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); | 1493 | irq = platform_get_irq(ofdev, 0); |
| 1484 | if (!irq) { | 1494 | if (irq < 0) { |
| 1485 | dev_err(&ofdev->dev, "invalid irq from platform\n"); | 1495 | retval = irq; |
| 1486 | goto error_exit_with_cleanup; | 1496 | goto error_exit_with_cleanup; |
| 1487 | } | 1497 | } |
| 1488 | host_priv->irq = irq; | 1498 | host_priv->irq = irq; |
| @@ -1557,10 +1567,6 @@ static int sata_fsl_remove(struct platform_device *ofdev) · 68 unmodified lines | |||
| 1557 | 1567 | ||
| 1558 | ata_host_detach(host); | 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 | return 0; | 1570 | return 0; |
| 1565 | } | 1571 | } |
| 1566 | 1572 | ||
| @@ -2103,7 +2103,7 @@ static int loop_control_remove(int idx) · 2102 unmodified lines | |||
| 2103 | int ret; | 2103 | int ret; |
| 2104 | 2104 | ||
| 2105 | if (idx < 0) { | 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 | return -EINVAL; | 2107 | return -EINVAL; |
| 2108 | } | 2108 | } |
| 2109 | 2109 | ||
| @@ -881,7 +881,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) · 880 unmodified lines | |||
| 881 | } | 881 | } |
| 882 | EXPORT_SYMBOL_GPL(mhi_pm_suspend); | 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 | struct mhi_chan *itr, *tmp; | 886 | struct mhi_chan *itr, *tmp; |
| 887 | struct device *dev = &mhi_cntrl->mhi_dev->dev; | 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 | if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) | 898 | if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) |
| 899 | return -EIO; | 899 | return -EIO; |
| 900 | 900 | ||
| 901 | if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) | 901 | if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) { |
| 902 | return -EINVAL; | 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 | /* Notify clients about exiting LPM */ | 908 | /* Notify clients about exiting LPM */ |
| 905 | list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { | 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 | return 0; | 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 | EXPORT_SYMBOL_GPL(mhi_pm_resume); | 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 | int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) | 960 | int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) |
| 946 | { | 961 | { |
| 947 | int ret; | 962 | int ret; |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | #define MHI_PCI_DEFAULT_BAR_NUM 0 | 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 | #define HEALTH_CHECK_PERIOD (HZ * 2) | 25 | #define HEALTH_CHECK_PERIOD (HZ * 2) |
| 26 | 26 | ||
| @@ -281,7 +281,7 @@ agp_ioc_init(void __iomem *ioc_regs) · 280 unmodified lines | |||
| 281 | return 0; | 281 | return 0; |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | static int | 284 | static int __init |
| 285 | lba_find_capability(int cap) | 285 | lba_find_capability(int cap) |
| 286 | { | 286 | { |
| 287 | struct _parisc_agp_info *info = &parisc_agp_info; | 287 | struct _parisc_agp_info *info = &parisc_agp_info; |
| @@ -366,7 +366,7 @@ fail: · 78 unmodified lines | |||
| 366 | return error; | 366 | return error; |
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | static int | 369 | static int __init |
| 370 | find_quicksilver(struct device *dev, void *data) | 370 | find_quicksilver(struct device *dev, void *data) |
| 371 | { | 371 | { |
| 372 | struct parisc_device **lba = data; | 372 | struct parisc_device **lba = data; |
| @@ -378,7 +378,7 @@ find_quicksilver(struct device *dev, void *data) · 5 unmodified lines | |||
| 378 | return 0; | 378 | return 0; |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | static int | 381 | static int __init |
| 382 | parisc_agp_init(void) | 382 | parisc_agp_init(void) |
| 383 | { | 383 | { |
| 384 | extern struct sba_device *sba_list; | 384 | extern struct sba_device *sba_list; |
| @@ -191,6 +191,8 @@ struct ipmi_user { · 190 unmodified lines | |||
| 191 | struct work_struct remove_work; | 191 | struct work_struct remove_work; |
| 192 | }; | 192 | }; |
| 193 | 193 | ||
| 194 | static struct workqueue_struct *remove_work_wq; | ||
| 195 | |||
| 194 | static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index) | 196 | static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index) |
| 195 | __acquires(user->release_barrier) | 197 | __acquires(user->release_barrier) |
| 196 | { | 198 | { |
| @@ -1297,7 +1299,7 @@ static void free_user(struct kref *ref) · 1100 unmodified lines | |||
| 1297 | struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); | 1299 | struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); |
| 1298 | 1300 | ||
| 1299 | /* SRCU cleanup must happen in task context. */ | 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 | static void _ipmi_destroy_user(struct ipmi_user *user) | 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 | /* We didn't find a user, deliver an error response. */ | 3920 | /* We didn't find a user, deliver an error response. */ |
| 3919 | ipmi_inc_stat(intf, unhandled_commands); | 3921 | ipmi_inc_stat(intf, unhandled_commands); |
| 3920 | 3922 | ||
| 3921 | msg->data[0] = ((netfn + 1) << 2) | (msg->rsp[4] & 0x3); | 3923 | msg->data[0] = (netfn + 1) << 2; |
| 3922 | msg->data[1] = msg->rsp[2]; | 3924 | msg->data[0] |= msg->rsp[2] & 0x3; /* rqLUN */ |
| 3923 | msg->data[2] = msg->rsp[4] & ~0x3; | 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 | msg->data[3] = cmd; | 3928 | msg->data[3] = cmd; |
| 3925 | msg->data[4] = IPMI_INVALID_CMD_COMPLETION_CODE; | 3929 | msg->data[4] = IPMI_INVALID_CMD_COMPLETION_CODE; |
| 3926 | msg->data_size = 5; | 3930 | msg->data_size = 5; |
| @@ -4455,13 +4459,24 @@ return_unspecified: · 528 unmodified lines | |||
| 4455 | msg->rsp[2] = IPMI_ERR_UNSPECIFIED; | 4459 | msg->rsp[2] = IPMI_ERR_UNSPECIFIED; |
| 4456 | msg->rsp_size = 3; | 4460 | msg->rsp_size = 3; |
| 4457 | } else if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) { | 4461 | } else if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) { |
| 4458 | /* commands must have at least 3 bytes, responses 4. */ | 4462 | /* commands must have at least 4 bytes, responses 5. */ |
| 4459 | if (is_cmd && (msg->rsp_size < 3)) { | 4463 | if (is_cmd && (msg->rsp_size < 4)) { |
| 4460 | ipmi_inc_stat(intf, invalid_commands); | 4464 | ipmi_inc_stat(intf, invalid_commands); |
| 4461 | goto out; | 4465 | goto out; |
| 4462 | } | 4466 | } |
| 4463 | if (!is_cmd && (msg->rsp_size < 4)) | 4467 | if (!is_cmd && (msg->rsp_size < 5)) { |
| 4464 | goto return_unspecified; | 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 | } else if ((msg->data_size >= 2) | 4480 | } else if ((msg->data_size >= 2) |
| 4466 | && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) | 4481 | && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) |
| 4467 | && (msg->data[1] == IPMI_SEND_MSG_CMD) | 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 | if (rv) { | 5046 | if (rv) { |
| 5032 | rv->done = free_smi_msg; | 5047 | rv->done = free_smi_msg; |
| 5033 | rv->user_data = NULL; | 5048 | rv->user_data = NULL; |
| 5049 | rv->type = IPMI_SMI_MSG_TYPE_NORMAL; | ||
| 5034 | atomic_inc(&smi_msg_inuse_count); | 5050 | atomic_inc(&smi_msg_inuse_count); |
| 5035 | } | 5051 | } |
| 5036 | return rv; | 5052 | return rv; |
| @@ -5383,6 +5399,13 @@ static int ipmi_init_msghandler(void) · 346 unmodified lines | |||
| 5383 | 5399 | ||
| 5384 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | 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 | initialized = true; | 5409 | initialized = true; |
| 5387 | 5410 | ||
| 5388 | out: | 5411 | out: |
| @@ -5408,6 +5431,8 @@ static void __exit cleanup_ipmi(void) · 19 unmodified lines | |||
| 5408 | int count; | 5431 | int count; |
| 5409 | 5432 | ||
| 5410 | if (initialized) { | 5433 | if (initialized) { |
| 5434 | destroy_workqueue(remove_work_wq); | ||
| 5435 | |||
| 5411 | atomic_notifier_chain_unregister(&panic_notifier_list, | 5436 | atomic_notifier_chain_unregister(&panic_notifier_list, |
| 5412 | &panic_block); | 5437 | &panic_block); |
| 5413 | 5438 | ||
| @@ -370,7 +370,7 @@ static struct platform_driver imx8qxp_lpcg_clk_driver = { · 369 unmodified lines | |||
| 370 | .probe = imx8qxp_lpcg_clk_probe, | 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 | MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>"); | 375 | MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>"); |
| 376 | MODULE_DESCRIPTION("NXP i.MX8QXP LPCG clock driver"); | 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 | .probe = imx8qxp_clk_probe, | 309 | .probe = imx8qxp_clk_probe, |
| 310 | }; | 310 | }; |
| 311 | builtin_platform_driver(imx8qxp_clk_driver); | 311 | module_platform_driver(imx8qxp_clk_driver); |
| 312 | 312 | ||
| 313 | MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>"); | 313 | MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>"); |
| 314 | MODULE_DESCRIPTION("NXP i.MX8QXP clock driver"); | 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 | void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, | 1429 | void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, |
| 1430 | const struct alpha_pll_config *config) | 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 | clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); | 1441 | clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); |
| 1433 | regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL); | 1442 | regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL); |
| 1434 | clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); | 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 | val &= mask; | 28 | val &= mask; |
| 29 | 29 | ||
| 30 | if (mux->parent_map) | 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 | return val; | 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 | EXPORT_SYMBOL_GPL(qcom_find_src_index); | 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 | struct regmap * | 84 | struct regmap * |
| 73 | qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc) | 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 | qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count); | 49 | qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count); |
| 50 | extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, | 50 | extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, |
| 51 | u8 src); | 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 | extern int qcom_cc_register_board_clk(struct device *dev, const char *path, | 55 | extern int qcom_cc_register_board_clk(struct device *dev, const char *path, |
| 54 | const char *name, unsigned long rate); | 56 | const char *name, unsigned long rate); |
| @@ -1121,7 +1121,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { · 1120 unmodified lines | |||
| 1121 | .name = "gcc_sdcc1_apps_clk_src", | 1121 | .name = "gcc_sdcc1_apps_clk_src", |
| 1122 | .parent_data = gcc_parent_data_1, | 1122 | .parent_data = gcc_parent_data_1, |
| 1123 | .num_parents = ARRAY_SIZE(gcc_parent_data_1), | 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 | .name = "gcc_sdcc1_ice_core_clk_src", | 1143 | .name = "gcc_sdcc1_ice_core_clk_src", |
| 1144 | .parent_data = gcc_parent_data_0, | 1144 | .parent_data = gcc_parent_data_0, |
| 1145 | .num_parents = ARRAY_SIZE(gcc_parent_data_0), | 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 | regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype); | 544 | regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype); |
| 545 | if (IS_ERR(regclk)) { | 545 | if (IS_ERR(regclk)) { |
| 546 | kfree(name); | ||
| 547 | pr_err("error setting up syscon ICST clock %s\n", name); | 546 | pr_err("error setting up syscon ICST clock %s\n", name); |
| 547 | kfree(name); | ||
| 548 | return; | 548 | return; |
| 549 | } | 549 | } |
| 550 | of_clk_add_provider(np, of_clk_src_simple_get, regclk); | 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 | static atomic_t timer_unstable_counter_workaround_in_use = ATOMIC_INIT(0); | 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, | 397 | /* |
| 398 | struct clock_event_device *clk) | 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 | unsigned long ctrl; | 405 | unsigned long ctrl; |
| 401 | u64 cval; | 406 | u64 cval; |
| @@ -47,7 +47,7 @@ static int __init timer_get_base_and_rate(struct device_node *np, · 46 unmodified lines | |||
| 47 | pr_warn("pclk for %pOFn is present, but could not be activated\n", | 47 | pr_warn("pclk for %pOFn is present, but could not be activated\n", |
| 48 | np); | 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 | !of_property_read_u32(np, "clock-frequency", rate)) | 51 | !of_property_read_u32(np, "clock-frequency", rate)) |
| 52 | return 0; | 52 | return 0; |
| 53 | 53 | ||
| @@ -1004,10 +1004,9 @@ static struct kobj_type ktype_cpufreq = { · 1003 unmodified lines | |||
| 1004 | .release = cpufreq_sysfs_release, | 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 | if (unlikely(!dev)) | 1010 | if (unlikely(!dev)) |
| 1012 | return; | 1011 | return; |
| 1013 | 1012 | ||
| @@ -1296,8 +1295,9 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy) · 282 unmodified lines | |||
| 1296 | 1295 | ||
| 1297 | if (policy->max_freq_req) { | 1296 | if (policy->max_freq_req) { |
| 1298 | /* | 1297 | /* |
| 1299 | * CPUFREQ_CREATE_POLICY notification is sent only after | 1298 | * Remove max_freq_req after sending CPUFREQ_REMOVE_POLICY |
| 1300 | * successfully adding max_freq_req request. | 1299 | * notification, since CPUFREQ_CREATE_POLICY notification was |
| 1300 | * sent after adding max_freq_req earlier. | ||
| 1301 | */ | 1301 | */ |
| 1302 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1302 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
| 1303 | CPUFREQ_REMOVE_POLICY, policy); | 1303 | CPUFREQ_REMOVE_POLICY, policy); |
| @@ -1391,7 +1391,7 @@ static int cpufreq_online(unsigned int cpu) · 87 unmodified lines | |||
| 1391 | if (new_policy) { | 1391 | if (new_policy) { |
| 1392 | for_each_cpu(j, policy->related_cpus) { | 1392 | for_each_cpu(j, policy->related_cpus) { |
| 1393 | per_cpu(cpufreq_cpu_data, j) = policy; | 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 | policy->min_freq_req = kzalloc(2 * sizeof(*policy->min_freq_req), | 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 | /* Create sysfs link on CPU registration */ | 1565 | /* Create sysfs link on CPU registration */ |
| 1566 | policy = per_cpu(cpufreq_cpu_data, cpu); | 1566 | policy = per_cpu(cpufreq_cpu_data, cpu); |
| 1567 | if (policy) | 1567 | if (policy) |
| 1568 | add_cpu_dev_symlink(policy, cpu); | 1568 | add_cpu_dev_symlink(policy, cpu, dev); |
| 1569 | 1569 | ||
| 1570 | return 0; | 1570 | return 0; |
| 1571 | } | 1571 | } |
| @@ -290,7 +290,7 @@ static void system_heap_dma_buf_release(struct dma_buf *dmabuf) · 289 unmodified lines | |||
| 290 | int i; | 290 | int i; |
| 291 | 291 | ||
| 292 | table = &buffer->sg_table; | 292 | table = &buffer->sg_table; |
| 293 | for_each_sg(table->sgl, sg, table->nents, i) { | 293 | for_each_sgtable_sg(table, sg, i) { |
| 294 | struct page *page = sg_page(sg); | 294 | struct page *page = sg_page(sg); |
| 295 | 295 | ||
| 296 | __free_pages(page, compound_order(page)); | 296 | __free_pages(page, compound_order(page)); |
| @@ -1396,7 +1396,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( · 1395 unmodified lines | |||
| 1396 | struct sg_table *sg = NULL; | 1396 | struct sg_table *sg = NULL; |
| 1397 | uint64_t user_addr = 0; | 1397 | uint64_t user_addr = 0; |
| 1398 | struct amdgpu_bo *bo; | 1398 | struct amdgpu_bo *bo; |
| 1399 | struct drm_gem_object *gobj; | 1399 | struct drm_gem_object *gobj = NULL; |
| 1400 | u32 domain, alloc_domain; | 1400 | u32 domain, alloc_domain; |
| 1401 | u64 alloc_flags; | 1401 | u64 alloc_flags; |
| 1402 | int ret; | 1402 | int ret; |
| @@ -1506,14 +1506,16 @@ allocate_init_user_pages_failed: · 103 unmodified lines | |||
| 1506 | remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); | 1506 | remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); |
| 1507 | drm_vma_node_revoke(&gobj->vma_node, drm_priv); | 1507 | drm_vma_node_revoke(&gobj->vma_node, drm_priv); |
| 1508 | err_node_allow: | 1508 | err_node_allow: |
| 1509 | drm_gem_object_put(gobj); | ||
| 1510 | /* Don't unreserve system mem limit twice */ | 1509 | /* Don't unreserve system mem limit twice */ |
| 1511 | goto err_reserve_limit; | 1510 | goto err_reserve_limit; |
| 1512 | err_bo_create: | 1511 | err_bo_create: |
| 1513 | unreserve_mem_limit(adev, size, alloc_domain, !!sg); | 1512 | unreserve_mem_limit(adev, size, alloc_domain, !!sg); |
| 1514 | err_reserve_limit: | 1513 | err_reserve_limit: |
| 1515 | mutex_destroy(&(*mem)->lock); | 1514 | mutex_destroy(&(*mem)->lock); |
| 1516 | kfree(*mem); | 1515 | if (gobj) |
| 1516 | drm_gem_object_put(gobj); | ||
| 1517 | else | ||
| 1518 | kfree(*mem); | ||
| 1517 | err: | 1519 | err: |
| 1518 | if (sg) { | 1520 | if (sg) { |
| 1519 | sg_free_table(sg); | 1521 | sg_free_table(sg); |
| @@ -3833,7 +3833,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) · 3832 unmodified lines | |||
| 3833 | /* disable all interrupts */ | 3833 | /* disable all interrupts */ |
| 3834 | amdgpu_irq_disable_all(adev); | 3834 | amdgpu_irq_disable_all(adev); |
| 3835 | if (adev->mode_info.mode_config_initialized){ | 3835 | if (adev->mode_info.mode_config_initialized){ |
| 3836 | if (!amdgpu_device_has_dc_support(adev)) | 3836 | if (!drm_drv_uses_atomic_modeset(adev_to_drm(adev))) |
| 3837 | drm_helper_force_disable_all(adev_to_drm(adev)); | 3837 | drm_helper_force_disable_all(adev_to_drm(adev)); |
| 3838 | else | 3838 | else |
| 3839 | drm_atomic_helper_shutdown(adev_to_drm(adev)); | 3839 | drm_atomic_helper_shutdown(adev_to_drm(adev)); |
| @@ -4289,6 +4289,8 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, · 449 unmodified lines | |||
| 4289 | { | 4289 | { |
| 4290 | int r; | 4290 | int r; |
| 4291 | 4291 | ||
| 4292 | amdgpu_amdkfd_pre_reset(adev); | ||
| 4293 | |||
| 4292 | if (from_hypervisor) | 4294 | if (from_hypervisor) |
| 4293 | r = amdgpu_virt_request_full_gpu(adev, true); | 4295 | r = amdgpu_virt_request_full_gpu(adev, true); |
| 4294 | else | 4296 | else |
| @@ -4316,6 +4318,7 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, · 21 unmodified lines | |||
| 4316 | 4318 | ||
| 4317 | amdgpu_irq_gpu_reset_resume_helper(adev); | 4319 | amdgpu_irq_gpu_reset_resume_helper(adev); |
| 4318 | r = amdgpu_ib_ring_tests(adev); | 4320 | r = amdgpu_ib_ring_tests(adev); |
| 4321 | amdgpu_amdkfd_post_reset(adev); | ||
| 4319 | 4322 | ||
| 4320 | error: | 4323 | error: |
| 4321 | if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) { | 4324 | if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) { |
| @@ -5030,7 +5033,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 708 unmodified lines | |||
| 5030 | 5033 | ||
| 5031 | cancel_delayed_work_sync(&tmp_adev->delayed_init_work); | 5034 | cancel_delayed_work_sync(&tmp_adev->delayed_init_work); |
| 5032 | 5035 | ||
| 5033 | amdgpu_amdkfd_pre_reset(tmp_adev); | 5036 | if (!amdgpu_sriov_vf(tmp_adev)) |
| 5037 | amdgpu_amdkfd_pre_reset(tmp_adev); | ||
| 5034 | 5038 | ||
| 5035 | /* | 5039 | /* |
| 5036 | * Mark these ASICs to be reseted as untracked first | 5040 | * Mark these ASICs to be reseted as untracked first |
| @@ -5129,7 +5133,7 @@ skip_hw_reset: · 92 unmodified lines | |||
| 5129 | drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res); | 5133 | drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res); |
| 5130 | } | 5134 | } |
| 5131 | 5135 | ||
| 5132 | if (!amdgpu_device_has_dc_support(tmp_adev) && !job_signaled) { | 5136 | if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) { |
| 5133 | drm_helper_resume_force_mode(adev_to_drm(tmp_adev)); | 5137 | drm_helper_resume_force_mode(adev_to_drm(tmp_adev)); |
| 5134 | } | 5138 | } |
| 5135 | 5139 | ||
| @@ -5148,9 +5152,9 @@ skip_hw_reset: · 12 unmodified lines | |||
| 5148 | 5152 | ||
| 5149 | skip_sched_resume: | 5153 | skip_sched_resume: |
| 5150 | list_for_each_entry(tmp_adev, device_list_handle, reset_list) { | 5154 | list_for_each_entry(tmp_adev, device_list_handle, reset_list) { |
| 5151 | /* unlock kfd */ | 5155 | /* unlock kfd: SRIOV would do it separately */ |
| 5152 | if (!need_emergency_restart) | 5156 | if (!need_emergency_restart && !amdgpu_sriov_vf(tmp_adev)) |
| 5153 | amdgpu_amdkfd_post_reset(tmp_adev); | 5157 | amdgpu_amdkfd_post_reset(tmp_adev); |
| 5154 | 5158 | ||
| 5155 | /* kfd_post_reset will do nothing if kfd device is not initialized, | 5159 | /* kfd_post_reset will do nothing if kfd device is not initialized, |
| 5156 | * need to bring up kfd here if it's not be initialized before | 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 | [HDP_HWIP] = HDP_HWID, | 157 | [HDP_HWIP] = HDP_HWID, |
| 158 | [SDMA0_HWIP] = SDMA0_HWID, | 158 | [SDMA0_HWIP] = SDMA0_HWID, |
| 159 | [SDMA1_HWIP] = SDMA1_HWID, | 159 | [SDMA1_HWIP] = SDMA1_HWID, |
| 160 | [SDMA2_HWIP] = SDMA2_HWID, | ||
| 161 | [SDMA3_HWIP] = SDMA3_HWID, | ||
| 160 | [MMHUB_HWIP] = MMHUB_HWID, | 162 | [MMHUB_HWIP] = MMHUB_HWID, |
| 161 | [ATHUB_HWIP] = ATHUB_HWID, | 163 | [ATHUB_HWIP] = ATHUB_HWID, |
| 162 | [NBIO_HWIP] = NBIF_HWID, | 164 | [NBIO_HWIP] = NBIF_HWID, |
| @@ -918,6 +920,7 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev) · 755 unmodified lines | |||
| 918 | case IP_VERSION(3, 0, 64): | 920 | case IP_VERSION(3, 0, 64): |
| 919 | case IP_VERSION(3, 1, 1): | 921 | case IP_VERSION(3, 1, 1): |
| 920 | case IP_VERSION(3, 0, 2): | 922 | case IP_VERSION(3, 0, 2): |
| 923 | case IP_VERSION(3, 0, 192): | ||
| 921 | amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); | 924 | amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); |
| 922 | if (!amdgpu_sriov_vf(adev)) | 925 | if (!amdgpu_sriov_vf(adev)) |
| 923 | amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); | 926 | amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); |
| @@ -135,6 +135,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) · 134 unmodified lines | |||
| 135 | break; | 135 | break; |
| 136 | case IP_VERSION(3, 0, 0): | 136 | case IP_VERSION(3, 0, 0): |
| 137 | case IP_VERSION(3, 0, 64): | 137 | case IP_VERSION(3, 0, 64): |
| 138 | case IP_VERSION(3, 0, 192): | ||
| 138 | if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) | 139 | if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) |
| 139 | fw_name = FIRMWARE_SIENNA_CICHLID; | 140 | fw_name = FIRMWARE_SIENNA_CICHLID; |
| 140 | else | 141 | else |
| @@ -504,8 +504,8 @@ static int amdgpu_vkms_sw_fini(void *handle) · 503 unmodified lines | |||
| 504 | int i = 0; | 504 | int i = 0; |
| 505 | 505 | ||
| 506 | for (i = 0; i < adev->mode_info.num_crtc; i++) | 506 | for (i = 0; i < adev->mode_info.num_crtc; i++) |
| 507 | if (adev->mode_info.crtcs[i]) | 507 | if (adev->amdgpu_vkms_output[i].vblank_hrtimer.function) |
| 508 | hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer); | 508 | hrtimer_cancel(&adev->amdgpu_vkms_output[i].vblank_hrtimer); |
| 509 | 509 | ||
| 510 | kfree(adev->mode_info.bios_hardcoded_edid); | 510 | kfree(adev->mode_info.bios_hardcoded_edid); |
| 511 | kfree(adev->amdgpu_vkms_output); | 511 | kfree(adev->amdgpu_vkms_output); |
| @@ -4060,9 +4060,10 @@ static int gfx_v9_0_hw_fini(void *handle) · 4059 unmodified lines | |||
| 4060 | 4060 | ||
| 4061 | gfx_v9_0_cp_enable(adev, false); | 4061 | gfx_v9_0_cp_enable(adev, false); |
| 4062 | 4062 | ||
| 4063 | /* Skip suspend with A+A reset */ | 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)) { | 4064 | if ((adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) || |
| 4065 | dev_dbg(adev->dev, "Device in reset. Skipping RLC halt\n"); | 4065 | (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2))) { |
| 4066 | dev_dbg(adev->dev, "Skipping RLC halt\n"); | ||
| 4066 | return 0; | 4067 | return 0; |
| 4067 | } | 4068 | } |
| 4068 | 4069 | ||
| @@ -183,6 +183,7 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, · 182 unmodified lines | |||
| 183 | switch (adev->ip_versions[UVD_HWIP][0]) { | 183 | switch (adev->ip_versions[UVD_HWIP][0]) { |
| 184 | case IP_VERSION(3, 0, 0): | 184 | case IP_VERSION(3, 0, 0): |
| 185 | case IP_VERSION(3, 0, 64): | 185 | case IP_VERSION(3, 0, 64): |
| 186 | case IP_VERSION(3, 0, 192): | ||
| 186 | if (amdgpu_sriov_vf(adev)) { | 187 | if (amdgpu_sriov_vf(adev)) { |
| 187 | if (encode) | 188 | if (encode) |
| 188 | *codecs = &sriov_sc_video_codecs_encode; | 189 | *codecs = &sriov_sc_video_codecs_encode; |
| @@ -1574,7 +1574,6 @@ retry_flush_work: · 1573 unmodified lines | |||
| 1574 | static void svm_range_restore_work(struct work_struct *work) | 1574 | static void svm_range_restore_work(struct work_struct *work) |
| 1575 | { | 1575 | { |
| 1576 | struct delayed_work *dwork = to_delayed_work(work); | 1576 | struct delayed_work *dwork = to_delayed_work(work); |
| 1577 | struct amdkfd_process_info *process_info; | ||
| 1578 | struct svm_range_list *svms; | 1577 | struct svm_range_list *svms; |
| 1579 | struct svm_range *prange; | 1578 | struct svm_range *prange; |
| 1580 | struct kfd_process *p; | 1579 | struct kfd_process *p; |
| @@ -1594,12 +1593,10 @@ static void svm_range_restore_work(struct work_struct *work) · 13 unmodified lines | |||
| 1594 | * the lifetime of this thread, kfd_process and mm will be valid. | 1593 | * the lifetime of this thread, kfd_process and mm will be valid. |
| 1595 | */ | 1594 | */ |
| 1596 | p = container_of(svms, struct kfd_process, svms); | 1595 | p = container_of(svms, struct kfd_process, svms); |
| 1597 | process_info = p->kgd_process_info; | ||
| 1598 | mm = p->mm; | 1596 | mm = p->mm; |
| 1599 | if (!mm) | 1597 | if (!mm) |
| 1600 | return; | 1598 | return; |
| 1601 | 1599 | ||
| 1602 | mutex_lock(&process_info->lock); | ||
| 1603 | svm_range_list_lock_and_flush_work(svms, mm); | 1600 | svm_range_list_lock_and_flush_work(svms, mm); |
| 1604 | mutex_lock(&svms->lock); | 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 | out_reschedule: | 1649 | out_reschedule: |
| 1653 | mutex_unlock(&svms->lock); | 1650 | mutex_unlock(&svms->lock); |
| 1654 | mmap_write_unlock(mm); | 1651 | mmap_write_unlock(mm); |
| 1655 | mutex_unlock(&process_info->lock); | ||
| 1656 | 1652 | ||
| 1657 | /* If validation failed, reschedule another attempt */ | 1653 | /* If validation failed, reschedule another attempt */ |
| 1658 | if (evicted_ranges) { | 1654 | if (evicted_ranges) { |
| @@ -2614,6 +2610,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, · 955 unmodified lines | |||
| 2614 | 2610 | ||
| 2615 | if (atomic_read(&svms->drain_pagefaults)) { | 2611 | if (atomic_read(&svms->drain_pagefaults)) { |
| 2616 | pr_debug("draining retry fault, drop fault 0x%llx\n", addr); | 2612 | pr_debug("draining retry fault, drop fault 0x%llx\n", addr); |
| 2613 | r = 0; | ||
| 2617 | goto out; | 2614 | goto out; |
| 2618 | } | 2615 | } |
| 2619 | 2616 | ||
| @@ -2623,6 +2620,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, · 3 unmodified lines | |||
| 2623 | mm = get_task_mm(p->lead_thread); | 2620 | mm = get_task_mm(p->lead_thread); |
| 2624 | if (!mm) { | 2621 | if (!mm) { |
| 2625 | pr_debug("svms 0x%p failed to get mm\n", svms); | 2622 | pr_debug("svms 0x%p failed to get mm\n", svms); |
| 2623 | r = 0; | ||
| 2626 | goto out; | 2624 | goto out; |
| 2627 | } | 2625 | } |
| 2628 | 2626 | ||
| @@ -2660,6 +2658,7 @@ retry_write_locked: · 31 unmodified lines | |||
| 2660 | 2658 | ||
| 2661 | if (svm_range_skip_recover(prange)) { | 2659 | if (svm_range_skip_recover(prange)) { |
| 2662 | amdgpu_gmc_filter_faults_remove(adev, addr, pasid); | 2660 | amdgpu_gmc_filter_faults_remove(adev, addr, pasid); |
| 2661 | r = 0; | ||
| 2663 | goto out_unlock_range; | 2662 | goto out_unlock_range; |
| 2664 | } | 2663 | } |
| 2665 | 2664 | ||
| @@ -2668,6 +2667,7 @@ retry_write_locked: · 2 unmodified lines | |||
| 2668 | if (timestamp < AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING) { | 2667 | if (timestamp < AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING) { |
| 2669 | pr_debug("svms 0x%p [0x%lx %lx] already restored\n", | 2668 | pr_debug("svms 0x%p [0x%lx %lx] already restored\n", |
| 2670 | svms, prange->start, prange->last); | 2669 | svms, prange->start, prange->last); |
| 2670 | r = 0; | ||
| 2671 | goto out_unlock_range; | 2671 | goto out_unlock_range; |
| 2672 | } | 2672 | } |
| 2673 | 2673 | ||
| @@ -3177,7 +3177,6 @@ static int · 503 unmodified lines | |||
| 3177 | svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, | 3177 | svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, |
| 3178 | uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs) | 3178 | uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs) |
| 3179 | { | 3179 | { |
| 3180 | struct amdkfd_process_info *process_info = p->kgd_process_info; | ||
| 3181 | struct mm_struct *mm = current->mm; | 3180 | struct mm_struct *mm = current->mm; |
| 3182 | struct list_head update_list; | 3181 | struct list_head update_list; |
| 3183 | struct list_head insert_list; | 3182 | struct list_head insert_list; |
| @@ -3196,8 +3195,6 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, · 12 unmodified lines | |||
| 3196 | 3195 | ||
| 3197 | svms = &p->svms; | 3196 | svms = &p->svms; |
| 3198 | 3197 | ||
| 3199 | mutex_lock(&process_info->lock); | ||
| 3200 | |||
| 3201 | svm_range_list_lock_and_flush_work(svms, mm); | 3198 | svm_range_list_lock_and_flush_work(svms, mm); |
| 3202 | 3199 | ||
| 3203 | r = svm_range_is_valid(p, start, size); | 3200 | r = svm_range_is_valid(p, start, size); |
| @@ -3273,8 +3270,6 @@ out_unlock_range: · 69 unmodified lines | |||
| 3273 | mutex_unlock(&svms->lock); | 3270 | mutex_unlock(&svms->lock); |
| 3274 | mmap_read_unlock(mm); | 3271 | mmap_read_unlock(mm); |
| 3275 | out: | 3272 | out: |
| 3276 | mutex_unlock(&process_info->lock); | ||
| 3277 | |||
| 3278 | pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid, | 3273 | pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid, |
| 3279 | &p->svms, start, start + size - 1, r); | 3274 | &p->svms, start, start + size - 1, r); |
| 3280 | 3275 | ||
| @@ -2576,7 +2576,8 @@ static int dm_resume(void *handle) · 2575 unmodified lines | |||
| 2576 | */ | 2576 | */ |
| 2577 | link_enc_cfg_init(dm->dc, dc_state); | 2577 | link_enc_cfg_init(dm->dc, dc_state); |
| 2578 | 2578 | ||
| 2579 | amdgpu_dm_outbox_init(adev); | 2579 | if (dc_enable_dmub_notifications(adev->dm.dc)) |
| 2580 | amdgpu_dm_outbox_init(adev); | ||
| 2580 | 2581 | ||
| 2581 | r = dm_dmub_hw_init(adev); | 2582 | r = dm_dmub_hw_init(adev); |
| 2582 | if (r) | 2583 | if (r) |
| @@ -2625,6 +2626,10 @@ static int dm_resume(void *handle) · 42 unmodified lines | |||
| 2625 | /* TODO: Remove dc_state->dccg, use dc->dccg directly. */ | 2626 | /* TODO: Remove dc_state->dccg, use dc->dccg directly. */ |
| 2626 | dc_resource_state_construct(dm->dc, dm_state->context); | 2627 | dc_resource_state_construct(dm->dc, dm_state->context); |
| 2627 | 2628 | ||
| 2629 | /* Re-enable outbox interrupts for DPIA. */ | ||
| 2630 | if (dc_enable_dmub_notifications(adev->dm.dc)) | ||
| 2631 | amdgpu_dm_outbox_init(adev); | ||
| 2632 | |||
| 2628 | /* Before powering on DC we need to re-initialize DMUB. */ | 2633 | /* Before powering on DC we need to re-initialize DMUB. */ |
| 2629 | r = dm_dmub_hw_init(adev); | 2634 | r = dm_dmub_hw_init(adev); |
| 2630 | if (r) | 2635 | if (r) |
| @@ -314,6 +314,14 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) · 313 unmodified lines | |||
| 314 | ret = -EINVAL; | 314 | ret = -EINVAL; |
| 315 | goto cleanup; | 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 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) | 327 | #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) |
| @@ -36,6 +36,8 @@ · 35 unmodified lines | |||
| 36 | #include "dm_helpers.h" | 36 | #include "dm_helpers.h" |
| 37 | 37 | ||
| 38 | #include "dc_link_ddc.h" | 38 | #include "dc_link_ddc.h" |
| 39 | #include "ddc_service_types.h" | ||
| 40 | #include "dpcd_defs.h" | ||
| 39 | 41 | ||
| 40 | #include "i2caux_interface.h" | 42 | #include "i2caux_interface.h" |
| 41 | #include "dmub_cmd.h" | 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 | #if defined(CONFIG_DRM_AMD_DC_DCN) | 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 | static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector) | 172 | static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector) |
| 161 | { | 173 | { |
| 162 | struct dc_sink *dc_sink = aconnector->dc_sink; | 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 | u8 *dsc_branch_dec_caps = NULL; | 178 | u8 *dsc_branch_dec_caps = NULL; |
| 167 | 179 | ||
| 168 | aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port); | 180 | aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port); |
| 169 | #if defined(CONFIG_HP_HOOK_WORKAROUND) | 181 | |
| 170 | /* | 182 | /* |
| 171 | * drm_dp_mst_dsc_aux_for_port() will return NULL for certain configs | 183 | * drm_dp_mst_dsc_aux_for_port() will return NULL for certain configs |
| 172 | * because it only check the dsc/fec caps of the "port variable" and not the dock | 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 | * Workaround: explicitly check the use case above and use the mst dock's aux as dsc_aux | 188 | * Workaround: explicitly check the use case above and use the mst dock's aux as dsc_aux |
| 177 | * | 189 | * |
| 178 | */ | 190 | */ |
| 179 | 191 | if (!aconnector->dsc_aux && !port->parent->port_parent && | |
| 180 | if (!aconnector->dsc_aux && !port->parent->port_parent) | 192 | needs_dsc_aux_workaround(aconnector->dc_link)) |
| 181 | aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux; | 193 | aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux; |
| 182 | #endif | 194 | |
| 183 | if (!aconnector->dsc_aux) | 195 | if (!aconnector->dsc_aux) |
| 184 | return false; | 196 | return false; |
| 185 | 197 | ||
| @@ -758,6 +758,18 @@ static bool detect_dp(struct dc_link *link, · 757 unmodified lines | |||
| 758 | dal_ddc_service_set_transaction_type(link->ddc, | 758 | dal_ddc_service_set_transaction_type(link->ddc, |
| 759 | sink_caps->transaction_type); | 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 | #if defined(CONFIG_DRM_AMD_DC_HDCP) | 773 | #if defined(CONFIG_DRM_AMD_DC_HDCP) |
| 762 | /* In case of fallback to SST when topology discovery below fails | 774 | /* In case of fallback to SST when topology discovery below fails |
| 763 | * HDCP caps will be querried again later by the upper layer (caller | 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 | LINK_INFO("link=%d, mst branch is now Disconnected\n", | 1215 | LINK_INFO("link=%d, mst branch is now Disconnected\n", |
| 1204 | link->link_index); | 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 | dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); | 1222 | dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); |
| 1207 | 1223 | ||
| 1208 | link->mst_stream_alloc_table.stream_count = 0; | 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 | for (lane = 0; lane < (uint8_t)lt_settings->link_settings.lane_count; lane++) | 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 | if (status == LINK_TRAINING_SUCCESS) { | 2144 | if (status == LINK_TRAINING_SUCCESS) { |
| @@ -1664,6 +1664,10 @@ bool dc_is_stream_unchanged( · 1663 unmodified lines | |||
| 1664 | if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param) | 1664 | if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param) |
| 1665 | return false; | 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 | return true; | 1671 | return true; |
| 1668 | } | 1672 | } |
| 1669 | 1673 | ||
| @@ -2252,16 +2256,6 @@ enum dc_status dc_validate_global_state( · 582 unmodified lines | |||
| 2252 | 2256 | ||
| 2253 | if (!new_ctx) | 2257 | if (!new_ctx) |
| 2254 | return DC_ERROR_UNEXPECTED; | 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 | if (dc->res_pool->funcs->validate_global) { | 2260 | if (dc->res_pool->funcs->validate_global) { |
| 2267 | result = dc->res_pool->funcs->validate_global(dc, new_ctx); | 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 | if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate)) | 2307 | if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate)) |
| 2314 | result = DC_FAIL_BANDWIDTH_VALIDATE; | 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 | return result; | 2320 | return result; |
| 2317 | } | 2321 | } |
| 2318 | 2322 | ||
| @@ -508,7 +508,8 @@ union dpia_debug_options { · 507 unmodified lines | |||
| 508 | uint32_t disable_dpia:1; | 508 | uint32_t disable_dpia:1; |
| 509 | uint32_t force_non_lttpr:1; | 509 | uint32_t force_non_lttpr:1; |
| 510 | uint32_t extend_aux_rd_interval:1; | 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 | } bits; | 513 | } bits; |
| 513 | uint32_t raw; | 514 | uint32_t raw; |
| 514 | }; | 515 | }; |
| @@ -191,6 +191,8 @@ struct dc_link { · 190 unmodified lines | |||
| 191 | bool dp_skip_DID2; | 191 | bool dp_skip_DID2; |
| 192 | bool dp_skip_reset_segment; | 192 | bool dp_skip_reset_segment; |
| 193 | bool dp_mot_reset_segment; | 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 | } wa_flags; | 196 | } wa_flags; |
| 195 | struct link_mst_stream_allocation_table mst_stream_alloc_table; | 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 | *edp_num = 0; | 226 | *edp_num = 0; |
| 225 | for (i = 0; i < dc->link_count; i++) { | 227 | for (i = 0; i < dc->link_count; i++) { |
| 226 | // report any eDP links, even unconnected DDI's | 228 | // report any eDP links, even unconnected DDI's |
| 229 | if (!dc->links[i]) | ||
| 230 | continue; | ||
| 227 | if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) { | 231 | if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) { |
| 228 | edp_links[*edp_num] = dc->links[i]; | 232 | edp_links[*edp_num] = dc->links[i]; |
| 229 | if (++(*edp_num) == MAX_NUM_EDP) | 233 | if (++(*edp_num) == MAX_NUM_EDP) |
| @@ -1468,7 +1468,7 @@ static int smu_disable_dpms(struct smu_context *smu) · 1467 unmodified lines | |||
| 1468 | dev_err(adev->dev, "Failed to disable smu features.\n"); | 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 | adev->gfx.rlc.funcs->stop) | 1472 | adev->gfx.rlc.funcs->stop) |
| 1473 | adev->gfx.rlc.funcs->stop(adev); | 1473 | adev->gfx.rlc.funcs->stop(adev); |
| 1474 | 1474 | ||
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/shmem_fs.h> | 9 | #include <linux/shmem_fs.h> |
| 10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
| 11 | #include <linux/vmalloc.h> | 11 | #include <linux/vmalloc.h> |
| 12 | #include <linux/module.h> | ||
| 12 | 13 | ||
| 13 | #ifdef CONFIG_X86 | 14 | #ifdef CONFIG_X86 |
| 14 | #include <asm/set_memory.h> | 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 | if (*fence) { | 405 | if (*fence) { |
| 406 | ret = dma_fence_chain_find_seqno(fence, point); | 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 | goto out; | 416 | goto out; |
| 417 | } | ||
| 409 | dma_fence_put(*fence); | 418 | dma_fence_put(*fence); |
| 410 | } else { | 419 | } else { |
| 411 | ret = -EINVAL; | 420 | ret = -EINVAL; |
| @@ -1640,6 +1640,9 @@ struct intel_dp { · 1639 unmodified lines | |||
| 1640 | struct intel_dp_pcon_frl frl; | 1640 | struct intel_dp_pcon_frl frl; |
| 1641 | 1641 | ||
| 1642 | struct intel_psr psr; | 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 | enum lspcon_vendor { | 1648 | enum lspcon_vendor { |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
| 30 | #include <linux/notifier.h> | 30 | #include <linux/notifier.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/timekeeping.h> | ||
| 32 | #include <linux/types.h> | 33 | #include <linux/types.h> |
| 33 | 34 | ||
| 34 | #include <asm/byteorder.h> | 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 | if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0) | 1957 | if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0) |
| 1957 | drm_err(&i915->drm, "Failed to write source OUI\n"); | 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 | /* If the device supports it, try to set the power state appropriately */ | 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 | const struct intel_crtc_state *crtc_state); | 119 | const struct intel_crtc_state *crtc_state); |
| 120 | void intel_dp_phy_test(struct intel_encoder *encoder); | 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 | #endif /* __INTEL_DP_H__ */ | 124 | #endif /* __INTEL_DP_H__ */ |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | |||
| 36 | 36 | ||
| 37 | #include "intel_backlight.h" | 37 | #include "intel_backlight.h" |
| 38 | #include "intel_display_types.h" | 38 | #include "intel_display_types.h" |
| 39 | #include "intel_dp.h" | ||
| 39 | #include "intel_dp_aux_backlight.h" | 40 | #include "intel_dp_aux_backlight.h" |
| 40 | 41 | ||
| 41 | /* TODO: | 42 | /* TODO: |
| @@ -106,6 +107,8 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector) · 64 unmodified lines | |||
| 106 | int ret; | 107 | int ret; |
| 107 | u8 tcon_cap[4]; | 108 | u8 tcon_cap[4]; |
| 108 | 109 | ||
| 110 | intel_dp_wait_source_oui(intel_dp); | ||
| 111 | |||
| 109 | ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap)); | 112 | ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap)); |
| 110 | if (ret != sizeof(tcon_cap)) | 113 | if (ret != sizeof(tcon_cap)) |
| 111 | return false; | 114 | return false; |
| @@ -204,6 +207,8 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state, · 92 unmodified lines | |||
| 204 | int ret; | 207 | int ret; |
| 205 | u8 old_ctrl, ctrl; | 208 | u8 old_ctrl, ctrl; |
| 206 | 209 | ||
| 210 | intel_dp_wait_source_oui(intel_dp); | ||
| 211 | |||
| 207 | ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl); | 212 | ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl); |
| 208 | if (ret != 1) { | 213 | if (ret != 1) { |
| 209 | drm_err(&i915->drm, "Failed to read current backlight control mode: %d\n", ret); | 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 | struct intel_panel *panel = &connector->panel; | 298 | struct intel_panel *panel = &connector->panel; |
| 294 | struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); | 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 | drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level); | 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 | struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); | 316 | struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); |
| 305 | 317 | ||
| 306 | drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info); | 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 | static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe) | 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 | if (ret < 0) | 337 | if (ret < 0) |
| 322 | return ret; | 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 | panel->backlight.max = panel->backlight.edp.vesa.info.max; | 349 | panel->backlight.max = panel->backlight.edp.vesa.info.max; |
| 325 | panel->backlight.min = 0; | 350 | panel->backlight.min = 0; |
| 326 | if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { | 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 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 365 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
| 341 | struct drm_i915_private *i915 = dp_to_i915(intel_dp); | 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 | 368 | if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) { |
| 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)) { | ||
| 349 | drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n"); | 369 | drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n"); |
| 350 | return true; | 370 | return true; |
| 351 | } | 371 | } |
| @@ -3277,6 +3277,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, · 3276 unmodified lines | |||
| 3277 | out_fence = eb_requests_create(&eb, in_fence, out_fence_fd); | 3277 | out_fence = eb_requests_create(&eb, in_fence, out_fence_fd); |
| 3278 | if (IS_ERR(out_fence)) { | 3278 | if (IS_ERR(out_fence)) { |
| 3279 | err = PTR_ERR(out_fence); | 3279 | err = PTR_ERR(out_fence); |
| 3280 | out_fence = NULL; | ||
| 3280 | if (eb.requests[0]) | 3281 | if (eb.requests[0]) |
| 3281 | goto err_request; | 3282 | goto err_request; |
| 3282 | else | 3283 | else |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/slab.h> /* fault-inject.h is not standalone! */ | 6 | #include <linux/slab.h> /* fault-inject.h is not standalone! */ |
| 7 | 7 | ||
| 8 | #include <linux/fault-inject.h> | 8 | #include <linux/fault-inject.h> |
| 9 | #include <linux/sched/mm.h> | ||
| 9 | 10 | ||
| 10 | #include "gem/i915_gem_lmem.h" | 11 | #include "gem/i915_gem_lmem.h" |
| 11 | #include "i915_trace.h" | 12 | #include "i915_trace.h" |
| @@ -621,13 +621,6 @@ static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine, · 620 unmodified lines | |||
| 621 | FF_MODE2_GS_TIMER_MASK, | 621 | FF_MODE2_GS_TIMER_MASK, |
| 622 | FF_MODE2_GS_TIMER_224, | 622 | FF_MODE2_GS_TIMER_224, |
| 623 | 0, false); | 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 | static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine, | 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 | GAMT_CHKN_BIT_REG, | 1127 | GAMT_CHKN_BIT_REG, |
| 1135 | GAMT_CHKN_DISABLE_L3_COH_PIPE); | 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 | /* Wa_1607087056:icl,ehl,jsl */ | 1139 | /* Wa_1607087056:icl,ehl,jsl */ |
| 1138 | if (IS_ICELAKE(i915) || | 1140 | if (IS_ICELAKE(i915) || |
| 1139 | IS_JSL_EHL_GT_STEP(i915, STEP_A0, STEP_B0)) | 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 | wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, | 1861 | wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, |
| 1860 | VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS); | 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 | * Wa_1408767742:icl[a2..forever],ehl[all] | 1865 | * Wa_1408767742:icl[a2..forever],ehl[all] |
| 1873 | * Wa_1605460711:icl[a0..c0] | 1866 | * Wa_1605460711:icl[a0..c0] |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 30 | #include <linux/sched/clock.h> | 30 | #include <linux/sched/clock.h> |
| 31 | #include <linux/sched/signal.h> | 31 | #include <linux/sched/signal.h> |
| 32 | #include <linux/sched/mm.h> | ||
| 32 | 33 | ||
| 33 | #include "gem/i915_gem_context.h" | 34 | #include "gem/i915_gem_context.h" |
| 34 | #include "gt/intel_breadcrumbs.h" | 35 | #include "gt/intel_breadcrumbs.h" |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | #include <linux/regulator/consumer.h> | 4 | #include <linux/regulator/consumer.h> |
| 5 | #include <linux/reset.h> | 5 | #include <linux/reset.h> |
| 6 | #include <linux/clk.h> | 6 | #include <linux/clk.h> |
| 7 | #include <linux/slab.h> | ||
| 7 | #include <linux/dma-mapping.h> | 8 | #include <linux/dma-mapping.h> |
| 8 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
| 9 | 10 | ||
| @@ -4,8 +4,8 @@ config DRM_MSM · 3 unmodified lines | |||
| 4 | tristate "MSM DRM" | 4 | tristate "MSM DRM" |
| 5 | depends on DRM | 5 | depends on DRM |
| 6 | depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST | 6 | depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST |
| 7 | depends on COMMON_CLK | ||
| 7 | depends on IOMMU_SUPPORT | 8 | depends on IOMMU_SUPPORT |
| 8 | depends on (OF && COMMON_CLK) || COMPILE_TEST | ||
| 9 | depends on QCOM_OCMEM || QCOM_OCMEM=n | 9 | depends on QCOM_OCMEM || QCOM_OCMEM=n |
| 10 | depends on QCOM_LLCC || QCOM_LLCC=n | 10 | depends on QCOM_LLCC || QCOM_LLCC=n |
| 11 | depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n | 11 | depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n |
| @@ -23,8 +23,10 @@ msm-y := \ · 22 unmodified lines | |||
| 23 | hdmi/hdmi_i2c.o \ | 23 | hdmi/hdmi_i2c.o \ |
| 24 | hdmi/hdmi_phy.o \ | 24 | hdmi/hdmi_phy.o \ |
| 25 | hdmi/hdmi_phy_8960.o \ | 25 | hdmi/hdmi_phy_8960.o \ |
| 26 | hdmi/hdmi_phy_8996.o \ | ||
| 26 | hdmi/hdmi_phy_8x60.o \ | 27 | hdmi/hdmi_phy_8x60.o \ |
| 27 | hdmi/hdmi_phy_8x74.o \ | 28 | hdmi/hdmi_phy_8x74.o \ |
| 29 | hdmi/hdmi_pll_8960.o \ | ||
| 28 | edp/edp.o \ | 30 | edp/edp.o \ |
| 29 | edp/edp_aux.o \ | 31 | edp/edp_aux.o \ |
| 30 | edp/edp_bridge.o \ | 32 | edp/edp_bridge.o \ |
| @@ -37,6 +39,7 @@ msm-y := \ · 6 unmodified lines | |||
| 37 | disp/mdp4/mdp4_dtv_encoder.o \ | 39 | disp/mdp4/mdp4_dtv_encoder.o \ |
| 38 | disp/mdp4/mdp4_lcdc_encoder.o \ | 40 | disp/mdp4/mdp4_lcdc_encoder.o \ |
| 39 | disp/mdp4/mdp4_lvds_connector.o \ | 41 | disp/mdp4/mdp4_lvds_connector.o \ |
| 42 | disp/mdp4/mdp4_lvds_pll.o \ | ||
| 40 | disp/mdp4/mdp4_irq.o \ | 43 | disp/mdp4/mdp4_irq.o \ |
| 41 | disp/mdp4/mdp4_kms.o \ | 44 | disp/mdp4/mdp4_kms.o \ |
| 42 | disp/mdp4/mdp4_plane.o \ | 45 | disp/mdp4/mdp4_plane.o \ |
| @@ -116,9 +119,6 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ · 73 unmodified lines | |||
| 116 | dp/dp_audio.o | 119 | dp/dp_audio.o |
| 117 | 120 | ||
| 118 | msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o | 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 | msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o | 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 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; | 1425 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; |
| 1426 | struct msm_gpu *gpu = &adreno_gpu->base; | 1426 | struct msm_gpu *gpu = &adreno_gpu->base; |
| 1427 | u32 gpu_scid, cntl1_regval = 0; | 1427 | u32 cntl1_regval = 0; |
| 1428 | 1428 | ||
| 1429 | if (IS_ERR(a6xx_gpu->llc_mmio)) | 1429 | if (IS_ERR(a6xx_gpu->llc_mmio)) |
| 1430 | return; | 1430 | return; |
| 1431 | 1431 | ||
| 1432 | if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { | 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 | gpu_scid &= 0x1f; | 1435 | gpu_scid &= 0x1f; |
| 1436 | cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | | 1436 | cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | |
| 1437 | (gpu_scid << 15) | (gpu_scid << 20); | 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 | gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); | 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 | static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) | 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 | return (unsigned long)busy_time; | 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 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | 1645 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 1646 | struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); | 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 | struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); | 777 | struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); |
| 778 | 778 | ||
| 779 | a6xx_state->gmu_registers = state_kcalloc(a6xx_state, | 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 | if (!a6xx_state->gmu_registers) | 782 | if (!a6xx_state->gmu_registers) |
| 783 | return; | 783 | return; |
| 784 | 784 | ||
| 785 | a6xx_state->nr_gmu_registers = 2; | 785 | a6xx_state->nr_gmu_registers = 3; |
| 786 | 786 | ||
| 787 | /* Get the CX GMU registers from AHB */ | 787 | /* Get the CX GMU registers from AHB */ |
| 788 | _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0], | 788 | _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0], |
| @@ -33,6 +33,7 @@ struct dp_aux_private { · 32 unmodified lines | |||
| 33 | bool read; | 33 | bool read; |
| 34 | bool no_send_addr; | 34 | bool no_send_addr; |
| 35 | bool no_send_stop; | 35 | bool no_send_stop; |
| 36 | bool initted; | ||
| 36 | u32 offset; | 37 | u32 offset; |
| 37 | u32 segment; | 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 | mutex_lock(&aux->mutex); | 334 | mutex_lock(&aux->mutex); |
| 335 | if (!aux->initted) { | ||
| 336 | ret = -EIO; | ||
| 337 | goto exit; | ||
| 338 | } | ||
| 334 | 339 | ||
| 335 | dp_aux_update_offset_and_segment(aux, msg); | 340 | dp_aux_update_offset_and_segment(aux, msg); |
| 336 | dp_aux_transfer_helper(aux, msg, true); | 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 | aux->cmd_busy = false; | 387 | aux->cmd_busy = false; |
| 388 | |||
| 389 | exit: | ||
| 383 | mutex_unlock(&aux->mutex); | 390 | mutex_unlock(&aux->mutex); |
| 384 | 391 | ||
| 385 | return ret; | 392 | return ret; |
| @@ -431,8 +438,13 @@ void dp_aux_init(struct drm_dp_aux *dp_aux) · 45 unmodified lines | |||
| 431 | 438 | ||
| 432 | aux = container_of(dp_aux, struct dp_aux_private, dp_aux); | 439 | aux = container_of(dp_aux, struct dp_aux_private, dp_aux); |
| 433 | 440 | ||
| 441 | mutex_lock(&aux->mutex); | ||
| 442 | |||
| 434 | dp_catalog_aux_enable(aux->catalog, true); | 443 | dp_catalog_aux_enable(aux->catalog, true); |
| 435 | aux->retry_cnt = 0; | 444 | aux->retry_cnt = 0; |
| 445 | aux->initted = true; | ||
| 446 | |||
| 447 | mutex_unlock(&aux->mutex); | ||
| 436 | } | 448 | } |
| 437 | 449 | ||
| 438 | void dp_aux_deinit(struct drm_dp_aux *dp_aux) | 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 | aux = container_of(dp_aux, struct dp_aux_private, dp_aux); | 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 | dp_catalog_aux_enable(aux->catalog, false); | 459 | dp_catalog_aux_enable(aux->catalog, false); |
| 460 | |||
| 461 | mutex_unlock(&aux->mutex); | ||
| 445 | } | 462 | } |
| 446 | 463 | ||
| 447 | int dp_aux_register(struct drm_dp_aux *dp_aux) | 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 | if (!prop) { | 1658 | if (!prop) { |
| 1659 | DRM_DEV_DEBUG(dev, | 1659 | DRM_DEV_DEBUG(dev, |
| 1660 | "failed to find data lane mapping, using default\n"); | 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 | return 0; | 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 | goto free_priv; | 77 | goto free_priv; |
| 78 | 78 | ||
| 79 | pm_runtime_get_sync(&gpu->pdev->dev); | 79 | pm_runtime_get_sync(&gpu->pdev->dev); |
| 80 | msm_gpu_hw_init(gpu); | ||
| 80 | show_priv->state = gpu->funcs->gpu_state_get(gpu); | 81 | show_priv->state = gpu->funcs->gpu_state_get(gpu); |
| 81 | pm_runtime_put_sync(&gpu->pdev->dev); | 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 | return ret; | 967 | return ret; |
| 968 | } | 968 | } |
| 969 | 969 | ||
| 970 | static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, | 970 | static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, |
| 971 | struct drm_file *file) | 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 | struct dma_fence *fence; | 973 | struct dma_fence *fence; |
| 979 | int ret; | 974 | int ret; |
| 980 | 975 | ||
| 981 | if (args->pad) { | 976 | if (fence_id > queue->last_fence) { |
| 982 | DRM_ERROR("invalid pad: %08x\n", args->pad); | 977 | DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n", |
| 978 | fence_id, queue->last_fence); | ||
| 983 | return -EINVAL; | 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 | * Map submitqueue scoped "seqno" (which is actually an idr key) | 983 | * Map submitqueue scoped "seqno" (which is actually an idr key) |
| 995 | * back to underlying dma-fence | 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 | ret = mutex_lock_interruptible(&queue->lock); | 990 | ret = mutex_lock_interruptible(&queue->lock); |
| 1002 | if (ret) | 991 | if (ret) |
| 1003 | return ret; | 992 | return ret; |
| 1004 | fence = idr_find(&queue->fence_idr, args->fence); | 993 | fence = idr_find(&queue->fence_idr, fence_id); |
| 1005 | if (fence) | 994 | if (fence) |
| 1006 | fence = dma_fence_get_rcu(fence); | 995 | fence = dma_fence_get_rcu(fence); |
| 1007 | mutex_unlock(&queue->lock); | 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 | dma_fence_put(fence); | 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 | msm_submitqueue_put(queue); | 1035 | msm_submitqueue_put(queue); |
| 1021 | 1036 | ||
| 1022 | return ret; | 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 | struct msm_gem_object *msm_obj = to_msm_bo(obj); | 1057 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 1058 | 1058 | ||
| 1059 | vma->vm_flags &= ~VM_PFNMAP; | 1059 | vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP; |
| 1060 | vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND; | ||
| 1061 | vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags)); | 1060 | vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags)); |
| 1062 | 1061 | ||
| 1063 | return 0; | 1062 | return 0; |
| @@ -1121,7 +1120,7 @@ static int msm_gem_new_impl(struct drm_device *dev, · 57 unmodified lines | |||
| 1121 | break; | 1120 | break; |
| 1122 | fallthrough; | 1121 | fallthrough; |
| 1123 | default: | 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 | (flags & MSM_BO_CACHE_MASK)); | 1124 | (flags & MSM_BO_CACHE_MASK)); |
| 1126 | return -EINVAL; | 1125 | return -EINVAL; |
| 1127 | } | 1126 | } |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/vmalloc.h> | 7 | #include <linux/vmalloc.h> |
| 8 | #include <linux/sched/mm.h> | ||
| 8 | 9 | ||
| 9 | #include "msm_drv.h" | 10 | #include "msm_drv.h" |
| 10 | #include "msm_gem.h" | 11 | #include "msm_gem.h" |
| @@ -772,6 +772,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 771 unmodified lines | |||
| 772 | args->nr_cmds); | 772 | args->nr_cmds); |
| 773 | if (IS_ERR(submit)) { | 773 | if (IS_ERR(submit)) { |
| 774 | ret = PTR_ERR(submit); | 774 | ret = PTR_ERR(submit); |
| 775 | submit = NULL; | ||
| 775 | goto out_unlock; | 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 | drm_sched_entity_push_job(&submit->base); | 905 | drm_sched_entity_push_job(&submit->base); |
| 905 | 906 | ||
| 906 | args->fence = submit->fence_id; | 907 | args->fence = submit->fence_id; |
| 908 | queue->last_fence = submit->fence_id; | ||
| 907 | 909 | ||
| 908 | msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs); | 910 | msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs); |
| 909 | msm_process_post_deps(post_deps, args->nr_out_syncobjs, | 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 | * @ring_nr: the ringbuffer used by this submitqueue, which is determined | 359 | * @ring_nr: the ringbuffer used by this submitqueue, which is determined |
| 360 | * by the submitqueue's priority | 360 | * by the submitqueue's priority |
| 361 | * @faults: the number of GPU hangs associated with this submitqueue | 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 | * @ctx: the per-drm_file context associated with the submitqueue (ie. | 364 | * @ctx: the per-drm_file context associated with the submitqueue (ie. |
| 363 | * which set of pgtables do submits jobs associated with the | 365 | * which set of pgtables do submits jobs associated with the |
| 364 | * submitqueue use) | 366 | * submitqueue use) |
| @@ -374,6 +376,7 @@ struct msm_gpu_submitqueue { · 9 unmodified lines | |||
| 374 | u32 flags; | 376 | u32 flags; |
| 375 | u32 ring_nr; | 377 | u32 ring_nr; |
| 376 | int faults; | 378 | int faults; |
| 379 | uint32_t last_fence; | ||
| 377 | struct msm_file_private *ctx; | 380 | struct msm_file_private *ctx; |
| 378 | struct list_head node; | 381 | struct list_head node; |
| 379 | struct idr fence_idr; | 382 | struct idr fence_idr; |
| @@ -20,6 +20,10 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, · 19 unmodified lines | |||
| 20 | struct msm_gpu *gpu = dev_to_gpu(dev); | 20 | struct msm_gpu *gpu = dev_to_gpu(dev); |
| 21 | struct dev_pm_opp *opp; | 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 | opp = devfreq_recommended_opp(dev, freq, flags); | 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 | if (gpu->devfreq.idle_freq) { | 33 | if (gpu->devfreq.idle_freq) { |
| 30 | gpu->devfreq.idle_freq = *freq; | 34 | gpu->devfreq.idle_freq = *freq; |
| 35 | dev_pm_opp_put(opp); | ||
| 31 | return 0; | 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 | struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq); | 208 | struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq); |
| 204 | unsigned long idle_freq, target_freq = 0; | 209 | unsigned long idle_freq, target_freq = 0; |
| 205 | 210 | ||
| 206 | if (!df->devfreq) | ||
| 207 | return; | ||
| 208 | |||
| 209 | /* | 211 | /* |
| 210 | * Hold devfreq lock to synchronize with get_dev_status()/ | 212 | * Hold devfreq lock to synchronize with get_dev_status()/ |
| 211 | * target() callbacks | 213 | * target() callbacks |
| @@ -227,6 +229,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu) · 15 unmodified lines | |||
| 227 | { | 229 | { |
| 228 | struct msm_gpu_devfreq *df = &gpu->devfreq; | 230 | struct msm_gpu_devfreq *df = &gpu->devfreq; |
| 229 | 231 | ||
| 232 | if (!df->devfreq) | ||
| 233 | return; | ||
| 234 | |||
| 230 | msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), | 235 | msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), |
| 231 | HRTIMER_MODE_ABS); | 236 | HRTIMER_MODE_REL); |
| 232 | } | 237 | } |
| @@ -1103,7 +1103,7 @@ int ttm_bo_swapout(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx, · 1102 unmodified lines | |||
| 1103 | * as an indication that we're about to swap out. | 1103 | * as an indication that we're about to swap out. |
| 1104 | */ | 1104 | */ |
| 1105 | memset(&place, 0, sizeof(place)); | 1105 | memset(&place, 0, sizeof(place)); |
| 1106 | place.mem_type = TTM_PL_SYSTEM; | 1106 | place.mem_type = bo->resource->mem_type; |
| 1107 | if (!ttm_bo_evict_swapout_allowable(bo, ctx, &place, &locked, NULL)) | 1107 | if (!ttm_bo_evict_swapout_allowable(bo, ctx, &place, &locked, NULL)) |
| 1108 | return -EBUSY; | 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 | struct ttm_place hop; | 1135 | struct ttm_place hop; |
| 1136 | 1136 | ||
| 1137 | memset(&hop, 0, sizeof(hop)); | 1137 | memset(&hop, 0, sizeof(hop)); |
| 1138 | place.mem_type = TTM_PL_SYSTEM; | ||
| 1138 | ret = ttm_resource_alloc(bo, &place, &evict_mem); | 1139 | ret = ttm_resource_alloc(bo, &place, &evict_mem); |
| 1139 | if (unlikely(ret)) | 1140 | if (unlikely(ret)) |
| 1140 | goto out; | 1141 | goto out; |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
| 35 | #include <linux/shmem_fs.h> | 35 | #include <linux/shmem_fs.h> |
| 36 | #include <linux/file.h> | 36 | #include <linux/file.h> |
| 37 | #include <linux/module.h> | ||
| 37 | #include <drm/drm_cache.h> | 38 | #include <drm/drm_cache.h> |
| 38 | #include <drm/ttm/ttm_bo_driver.h> | 39 | #include <drm/ttm/ttm_bo_driver.h> |
| 39 | 40 | ||
| @@ -337,10 +337,10 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) · 336 unmodified lines | |||
| 337 | struct drm_device *dev = state->dev; | 337 | struct drm_device *dev = state->dev; |
| 338 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 338 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 339 | struct vc4_hvs *hvs = vc4->hvs; | 339 | struct vc4_hvs *hvs = vc4->hvs; |
| 340 | struct drm_crtc_state *old_crtc_state; | ||
| 341 | struct drm_crtc_state *new_crtc_state; | 340 | struct drm_crtc_state *new_crtc_state; |
| 342 | struct drm_crtc *crtc; | 341 | struct drm_crtc *crtc; |
| 343 | struct vc4_hvs_state *old_hvs_state; | 342 | struct vc4_hvs_state *old_hvs_state; |
| 343 | unsigned int channel; | ||
| 344 | int i; | 344 | int i; |
| 345 | 345 | ||
| 346 | for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { | 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 | vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel); | 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 | old_hvs_state = vc4_hvs_get_old_global_state(state); | 356 | old_hvs_state = vc4_hvs_get_old_global_state(state); |
| 360 | if (!old_hvs_state) | 357 | if (IS_ERR(old_hvs_state)) |
| 361 | return; | 358 | return; |
| 362 | 359 | ||
| 363 | for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) { | 360 | for (channel = 0; channel < HVS_NUM_CHANNELS; channel++) { |
| 364 | struct vc4_crtc_state *vc4_crtc_state = | 361 | struct drm_crtc_commit *commit; |
| 365 | to_vc4_crtc_state(old_crtc_state); | ||
| 366 | unsigned int channel = vc4_crtc_state->assigned_channel; | ||
| 367 | int ret; | 362 | int ret; |
| 368 | 363 | ||
| 369 | if (channel == VC4_HVS_CHANNEL_DISABLED) | 364 | if (!old_hvs_state->fifo_state[channel].in_use) |
| 370 | continue; | 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 | continue; | 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 | if (ret) | 372 | if (ret) |
| 377 | drm_err(dev, "Timed out waiting for commit\n"); | 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 | drm_atomic_helper_commit_modeset_disables(dev, state); | 382 | drm_atomic_helper_commit_modeset_disables(dev, state); |
| 381 | 383 | ||
| 382 | vc4_ctm_commit(vc4, state); | 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 | unsigned int i; | 412 | unsigned int i; |
| 411 | 413 | ||
| 412 | hvs_state = vc4_hvs_get_new_global_state(state); | 414 | hvs_state = vc4_hvs_get_new_global_state(state); |
| 413 | if (!hvs_state) | 415 | if (WARN_ON(IS_ERR(hvs_state))) |
| 414 | return -EINVAL; | 416 | return PTR_ERR(hvs_state); |
| 415 | 417 | ||
| 416 | for_each_new_crtc_in_state(state, crtc, crtc_state, i) { | 418 | for_each_new_crtc_in_state(state, crtc, crtc_state, i) { |
| 417 | struct vc4_crtc_state *vc4_crtc_state = | 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 | for (i = 0; i < HVS_NUM_CHANNELS; i++) { | 671 | for (i = 0; i < HVS_NUM_CHANNELS; i++) { |
| 670 | state->fifo_state[i].in_use = old_state->fifo_state[i].in_use; | 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 | return &state->base; | 675 | return &state->base; |
| @@ -762,8 +758,8 @@ static int vc4_pv_muxing_atomic_check(struct drm_device *dev, · 82 unmodified lines | |||
| 762 | unsigned int i; | 758 | unsigned int i; |
| 763 | 759 | ||
| 764 | hvs_new_state = vc4_hvs_get_global_state(state); | 760 | hvs_new_state = vc4_hvs_get_global_state(state); |
| 765 | if (!hvs_new_state) | 761 | if (IS_ERR(hvs_new_state)) |
| 766 | return -EINVAL; | 762 | return PTR_ERR(hvs_new_state); |
| 767 | 763 | ||
| 768 | for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++) | 764 | for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++) |
| 769 | if (!hvs_new_state->fifo_state[i].in_use) | 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 | schedule_work(&vgdev->config_changed_work); | 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 | static struct virtio_device_id id_table[] = { | 160 | static struct virtio_device_id id_table[] = { |
| 191 | { VIRTIO_ID_GPU, VIRTIO_DEV_ANY_ID }, | 161 | { VIRTIO_ID_GPU, VIRTIO_DEV_ANY_ID }, |
| 192 | { 0 }, | 162 | { 0 }, |
| @@ -226,17 +196,7 @@ MODULE_AUTHOR("Dave Airlie <airlied@redhat.com>"); · 33 unmodified lines | |||
| 226 | MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>"); | 196 | MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>"); |
| 227 | MODULE_AUTHOR("Alon Levy"); | 197 | MODULE_AUTHOR("Alon Levy"); |
| 228 | 198 | ||
| 229 | static const struct file_operations virtio_gpu_driver_fops = { | 199 | DEFINE_DRM_GEM_FOPS(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 | }; | ||
| 240 | 200 | ||
| 241 | static const struct drm_driver driver = { | 201 | static const struct drm_driver driver = { |
| 242 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC, | 202 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC, |
| @@ -138,7 +138,6 @@ struct virtio_gpu_fence_driver { · 137 unmodified lines | |||
| 138 | spinlock_t lock; | 138 | spinlock_t lock; |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | #define VIRTGPU_EVENT_FENCE_SIGNALED_INTERNAL 0x10000000 | ||
| 142 | struct virtio_gpu_fence_event { | 141 | struct virtio_gpu_fence_event { |
| 143 | struct drm_pending_event base; | 142 | struct drm_pending_event base; |
| 144 | struct drm_event event; | 143 | struct drm_event event; |
| @@ -54,7 +54,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev, · 53 unmodified lines | |||
| 54 | if (!e) | 54 | if (!e) |
| 55 | return -ENOMEM; | 55 | return -ENOMEM; |
| 56 | 56 | ||
| 57 | e->event.type = VIRTGPU_EVENT_FENCE_SIGNALED_INTERNAL; | 57 | e->event.type = VIRTGPU_EVENT_FENCE_SIGNALED; |
| 58 | e->event.length = sizeof(e->event); | 58 | e->event.length = sizeof(e->event); |
| 59 | 59 | ||
| 60 | ret = drm_event_reserve_init(dev, file, &e->base, &e->event); | 60 | ret = drm_event_reserve_init(dev, file, &e->base, &e->event); |
| @@ -207,14 +207,14 @@ config HID_CHERRY · 206 unmodified lines | |||
| 207 | 207 | ||
| 208 | config HID_CHICONY | 208 | config HID_CHICONY |
| 209 | tristate "Chicony devices" | 209 | tristate "Chicony devices" |
| 210 | depends on HID | 210 | depends on USB_HID |
| 211 | default !EXPERT | 211 | default !EXPERT |
| 212 | help | 212 | help |
| 213 | Support for Chicony Tactical pad and special keys on Chicony keyboards. | 213 | Support for Chicony Tactical pad and special keys on Chicony keyboards. |
| 214 | 214 | ||
| 215 | config HID_CORSAIR | 215 | config HID_CORSAIR |
| 216 | tristate "Corsair devices" | 216 | tristate "Corsair devices" |
| 217 | depends on HID && USB && LEDS_CLASS | 217 | depends on USB_HID && LEDS_CLASS |
| 218 | help | 218 | help |
| 219 | Support for Corsair devices that are not fully compliant with the | 219 | Support for Corsair devices that are not fully compliant with the |
| 220 | HID standard. | 220 | HID standard. |
| @@ -245,7 +245,7 @@ config HID_MACALLY · 24 unmodified lines | |||
| 245 | 245 | ||
| 246 | config HID_PRODIKEYS | 246 | config HID_PRODIKEYS |
| 247 | tristate "Prodikeys PC-MIDI Keyboard support" | 247 | tristate "Prodikeys PC-MIDI Keyboard support" |
| 248 | depends on HID && SND | 248 | depends on USB_HID && SND |
| 249 | select SND_RAWMIDI | 249 | select SND_RAWMIDI |
| 250 | help | 250 | help |
| 251 | Support for Prodikeys PC-MIDI Keyboard device support. | 251 | Support for Prodikeys PC-MIDI Keyboard device support. |
| @@ -560,7 +560,7 @@ config HID_LENOVO · 308 unmodified lines | |||
| 560 | 560 | ||
| 561 | config HID_LOGITECH | 561 | config HID_LOGITECH |
| 562 | tristate "Logitech devices" | 562 | tristate "Logitech devices" |
| 563 | depends on HID | 563 | depends on USB_HID |
| 564 | depends on LEDS_CLASS | 564 | depends on LEDS_CLASS |
| 565 | default !EXPERT | 565 | default !EXPERT |
| 566 | help | 566 | help |
| @@ -951,7 +951,7 @@ config HID_SAITEK · 384 unmodified lines | |||
| 951 | 951 | ||
| 952 | config HID_SAMSUNG | 952 | config HID_SAMSUNG |
| 953 | tristate "Samsung InfraRed remote control or keyboards" | 953 | tristate "Samsung InfraRed remote control or keyboards" |
| 954 | depends on HID | 954 | depends on USB_HID |
| 955 | help | 955 | help |
| 956 | Support for Samsung InfraRed remote control or keyboards. | 956 | Support for Samsung InfraRed remote control or keyboards. |
| 957 | 957 | ||
| @@ -1028,8 +1028,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) · 1027 unmodified lines | |||
| 1028 | if (drvdata->quirks & QUIRK_IS_MULTITOUCH) | 1028 | if (drvdata->quirks & QUIRK_IS_MULTITOUCH) |
| 1029 | drvdata->tp = &asus_i2c_tp; | 1029 | drvdata->tp = &asus_i2c_tp; |
| 1030 | 1030 | ||
| 1031 | if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && | 1031 | if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) { |
| 1032 | hid_is_using_ll_driver(hdev, &usb_hid_driver)) { | ||
| 1033 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 1032 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
| 1034 | 1033 | ||
| 1035 | if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) { | 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 | drvdata->tp = &asus_t100chi_tp; | 1056 | drvdata->tp = &asus_t100chi_tp; |
| 1058 | } | 1057 | } |
| 1059 | 1058 | ||
| 1060 | if ((drvdata->quirks & QUIRK_MEDION_E1239T) && | 1059 | if ((drvdata->quirks & QUIRK_MEDION_E1239T) && hid_is_usb(hdev)) { |
| 1061 | hid_is_using_ll_driver(hdev, &usb_hid_driver)) { | ||
| 1062 | struct usb_host_interface *alt = | 1060 | struct usb_host_interface *alt = |
| 1063 | to_usb_interface(hdev->dev.parent)->altsetting; | 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 | struct bigben_device, worker); | 191 | struct bigben_device, worker); |
| 192 | struct hid_field *report_field = bigben->report->field[0]; | 192 | struct hid_field *report_field = bigben->report->field[0]; |
| 193 | 193 | ||
| 194 | if (bigben->removed) | 194 | if (bigben->removed || !report_field) |
| 195 | return; | 195 | return; |
| 196 | 196 | ||
| 197 | if (bigben->work_led) { | 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 | int ret; | 115 | int ret; |
| 116 | 116 | ||
| 117 | if (!hid_is_usb(hdev)) | ||
| 118 | return -EINVAL; | ||
| 119 | |||
| 117 | hdev->quirks |= HID_QUIRK_INPUT_PER_APP; | 120 | hdev->quirks |= HID_QUIRK_INPUT_PER_APP; |
| 118 | ret = hid_parse(hdev); | 121 | ret = hid_parse(hdev); |
| 119 | if (ret) { | 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 | int ret; | 553 | int ret; |
| 554 | unsigned long quirks = id->driver_data; | 554 | unsigned long quirks = id->driver_data; |
| 555 | struct corsair_drvdata *drvdata; | 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 | drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata), | 563 | drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata), |
| 559 | GFP_KERNEL); | 564 | GFP_KERNEL); |
| @@ -50,7 +50,7 @@ struct elan_drvdata { · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | static int is_not_elan_touchpad(struct hid_device *hdev) | 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 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 54 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
| 55 | 55 | ||
| 56 | return (intf->altsetting->desc.bInterfaceNumber != | 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 | int ret; | 230 | int ret; |
| 231 | struct usb_device *udev; | 231 | struct usb_device *udev; |
| 232 | 232 | ||
| 233 | if (!hid_is_usb(hdev)) | ||
| 234 | return -EINVAL; | ||
| 235 | |||
| 233 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 236 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 234 | if (!priv) | 237 | if (!priv) |
| 235 | return -ENOMEM; | 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 | struct ft260_get_chip_version_report version; | 915 | struct ft260_get_chip_version_report version; |
| 916 | int ret; | 916 | int ret; |
| 917 | 917 | ||
| 918 | if (!hid_is_usb(hdev)) | ||
| 919 | return -EINVAL; | ||
| 920 | |||
| 918 | dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); | 921 | dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); |
| 919 | if (!dev) | 922 | if (!dev) |
| 920 | return -ENOMEM; | 923 | return -ENOMEM; |
| @@ -585,6 +585,8 @@ static void hammer_remove(struct hid_device *hdev) · 584 unmodified lines | |||
| 585 | static const struct hid_device_id hammer_devices[] = { | 585 | static const struct hid_device_id hammer_devices[] = { |
| 586 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 586 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 587 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) }, | 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 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 590 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 589 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, | 591 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, |
| 590 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 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 | static int holtek_kbd_probe(struct hid_device *hdev, | 140 | static int holtek_kbd_probe(struct hid_device *hdev, |
| 141 | const struct hid_device_id *id) | 141 | const struct hid_device_id *id) |
| 142 | { | 142 | { |
| 143 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 143 | struct usb_interface *intf; |
| 144 | int ret = hid_parse(hdev); | 144 | int ret; |
| 145 | |||
| 146 | if (!hid_is_usb(hdev)) | ||
| 147 | return -EINVAL; | ||
| 145 | 148 | ||
| 149 | ret = hid_parse(hdev); | ||
| 146 | if (!ret) | 150 | if (!ret) |
| 147 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 151 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
| 148 | 152 | ||
| 153 | intf = to_usb_interface(hdev->dev.parent); | ||
| 149 | if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) { | 154 | if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) { |
| 150 | struct hid_input *hidinput; | 155 | struct hid_input *hidinput; |
| 151 | list_for_each_entry(hidinput, &hdev->inputs, list) { | 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 | return rdesc; | 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 | static const struct hid_device_id holtek_mouse_devices[] = { | 73 | static const struct hid_device_id holtek_mouse_devices[] = { |
| 66 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, | 74 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, |
| 67 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, | 75 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, |
| @@ -83,6 +91,7 @@ static struct hid_driver holtek_mouse_driver = { · 15 unmodified lines | |||
| 83 | .name = "holtek_mouse", | 91 | .name = "holtek_mouse", |
| 84 | .id_table = holtek_mouse_devices, | 92 | .id_table = holtek_mouse_devices, |
| 85 | .report_fixup = holtek_mouse_report_fixup, | 93 | .report_fixup = holtek_mouse_report_fixup, |
| 94 | .probe = holtek_mouse_probe, | ||
| 86 | }; | 95 | }; |
| 87 | 96 | ||
| 88 | module_hid_driver(holtek_mouse_driver); | 97 | module_hid_driver(holtek_mouse_driver); |
| @@ -399,6 +399,7 @@ · 398 unmodified lines | |||
| 399 | #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 | 399 | #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 |
| 400 | #define I2C_DEVICE_ID_HP_ENVY_X360_15 0x2d05 | 400 | #define I2C_DEVICE_ID_HP_ENVY_X360_15 0x2d05 |
| 401 | #define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817 | 401 | #define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817 |
| 402 | #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544 | ||
| 402 | #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 | 403 | #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 |
| 403 | #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A | 404 | #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A |
| 404 | 405 | ||
| @@ -501,6 +502,7 @@ · 96 unmodified lines | |||
| 501 | #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d | 502 | #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d |
| 502 | #define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 | 503 | #define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 |
| 503 | #define USB_DEVICE_ID_GOOGLE_DON 0x5050 | 504 | #define USB_DEVICE_ID_GOOGLE_DON 0x5050 |
| 505 | #define USB_DEVICE_ID_GOOGLE_EEL 0x5057 | ||
| 504 | 506 | ||
| 505 | #define USB_VENDOR_ID_GOTOP 0x08f2 | 507 | #define USB_VENDOR_ID_GOTOP 0x08f2 |
| 506 | #define USB_DEVICE_ID_SUPER_Q2 0x007f | 508 | #define USB_DEVICE_ID_SUPER_Q2 0x007f |
| @@ -886,6 +888,7 @@ · 379 unmodified lines | |||
| 886 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 | 888 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 |
| 887 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | 889 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 |
| 888 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da | 890 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da |
| 891 | #define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de | ||
| 889 | #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd | 892 | #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd |
| 890 | #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb | 893 | #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb |
| 891 | #define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0 | 894 | #define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0 |
| @@ -325,6 +325,8 @@ static const struct hid_device_id hid_battery_quirks[] = { · 324 unmodified lines | |||
| 325 | HID_BATTERY_QUIRK_IGNORE }, | 325 | HID_BATTERY_QUIRK_IGNORE }, |
| 326 | { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), | 326 | { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), |
| 327 | HID_BATTERY_QUIRK_IGNORE }, | 327 | HID_BATTERY_QUIRK_IGNORE }, |
| 328 | { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN), | ||
| 329 | HID_BATTERY_QUIRK_IGNORE }, | ||
| 328 | { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15), | 330 | { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15), |
| 329 | HID_BATTERY_QUIRK_IGNORE }, | 331 | HID_BATTERY_QUIRK_IGNORE }, |
| 330 | { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15), | 332 | { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15), |
| @@ -749,12 +749,18 @@ static int lg_raw_event(struct hid_device *hdev, struct hid_report *report, · 748 unmodified lines | |||
| 749 | 749 | ||
| 750 | static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | 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); | 752 | struct usb_interface *iface; |
| 753 | __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; | 753 | __u8 iface_num; |
| 754 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | 754 | unsigned int connect_mask = HID_CONNECT_DEFAULT; |
| 755 | struct lg_drv_data *drv_data; | 755 | struct lg_drv_data *drv_data; |
| 756 | int ret; | 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 | /* G29 only work with the 1st interface */ | 764 | /* G29 only work with the 1st interface */ |
| 759 | if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && | 765 | if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && |
| 760 | (iface_num != 0)) { | 766 | (iface_num != 0)) { |
| @@ -1777,7 +1777,7 @@ static int logi_dj_probe(struct hid_device *hdev, · 1776 unmodified lines | |||
| 1777 | case recvr_type_bluetooth: no_dj_interfaces = 2; break; | 1777 | case recvr_type_bluetooth: no_dj_interfaces = 2; break; |
| 1778 | case recvr_type_dinovo: no_dj_interfaces = 2; break; | 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 | intf = to_usb_interface(hdev->dev.parent); | 1781 | intf = to_usb_interface(hdev->dev.parent); |
| 1782 | if (intf && intf->altsetting->desc.bInterfaceNumber >= | 1782 | if (intf && intf->altsetting->desc.bInterfaceNumber >= |
| 1783 | no_dj_interfaces) { | 1783 | no_dj_interfaces) { |
| @@ -798,12 +798,18 @@ static int pk_raw_event(struct hid_device *hdev, struct hid_report *report, · 797 unmodified lines | |||
| 798 | static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) | 798 | static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| 799 | { | 799 | { |
| 800 | int ret; | 800 | int ret; |
| 801 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 801 | struct usb_interface *intf; |
| 802 | unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | 802 | unsigned short ifnum; |
| 803 | unsigned long quirks = id->driver_data; | 803 | unsigned long quirks = id->driver_data; |
| 804 | struct pk_device *pk; | 804 | struct pk_device *pk; |
| 805 | struct pcmidi_snd *pm = NULL; | 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 | pk = kzalloc(sizeof(*pk), GFP_KERNEL); | 813 | pk = kzalloc(sizeof(*pk), GFP_KERNEL); |
| 808 | if (pk == NULL) { | 814 | if (pk == NULL) { |
| 809 | hid_err(hdev, "can't alloc descriptor\n"); | 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 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, | 124 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, |
| 125 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL }, | 125 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL }, |
| 126 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, | 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 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, | 128 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, |
| 128 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, | 129 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, |
| 129 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, | 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 | int retval; | 345 | int retval; |
| 346 | 346 | ||
| 347 | if (!hid_is_usb(hdev)) | ||
| 348 | return -EINVAL; | ||
| 349 | |||
| 347 | retval = hid_parse(hdev); | 350 | retval = hid_parse(hdev); |
| 348 | if (retval) { | 351 | if (retval) { |
| 349 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 325 | int retval; |
| 326 | 326 | ||
| 327 | if (!hid_is_usb(hdev)) | ||
| 328 | return -EINVAL; | ||
| 329 | |||
| 327 | retval = hid_parse(hdev); | 330 | retval = hid_parse(hdev); |
| 328 | if (retval) { | 331 | if (retval) { |
| 329 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 750 | int retval; |
| 751 | 751 | ||
| 752 | if (!hid_is_usb(hdev)) | ||
| 753 | return -EINVAL; | ||
| 754 | |||
| 752 | retval = hid_parse(hdev); | 755 | retval = hid_parse(hdev); |
| 753 | if (retval) { | 756 | if (retval) { |
| 754 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 432 | int retval; |
| 433 | 433 | ||
| 434 | if (!hid_is_usb(hdev)) | ||
| 435 | return -EINVAL; | ||
| 436 | |||
| 434 | retval = hid_parse(hdev); | 437 | retval = hid_parse(hdev); |
| 435 | if (retval) { | 438 | if (retval) { |
| 436 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 134 | int retval; |
| 135 | 135 | ||
| 136 | if (!hid_is_usb(hdev)) | ||
| 137 | return -EINVAL; | ||
| 138 | |||
| 136 | retval = hid_parse(hdev); | 139 | retval = hid_parse(hdev); |
| 137 | if (retval) { | 140 | if (retval) { |
| 138 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 502 | int retval; |
| 503 | 503 | ||
| 504 | if (!hid_is_usb(hdev)) | ||
| 505 | return -EINVAL; | ||
| 506 | |||
| 504 | retval = hid_parse(hdev); | 507 | retval = hid_parse(hdev); |
| 505 | if (retval) { | 508 | if (retval) { |
| 506 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 161 | int retval; |
| 162 | 162 | ||
| 163 | if (!hid_is_usb(hdev)) | ||
| 164 | return -EINVAL; | ||
| 165 | |||
| 163 | retval = hid_parse(hdev); | 166 | retval = hid_parse(hdev); |
| 164 | if (retval) { | 167 | if (retval) { |
| 165 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 450 | int retval; |
| 451 | 451 | ||
| 452 | if (!hid_is_usb(hdev)) | ||
| 453 | return -EINVAL; | ||
| 454 | |||
| 452 | retval = hid_parse(hdev); | 455 | retval = hid_parse(hdev); |
| 453 | if (retval) { | 456 | if (retval) { |
| 454 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 142 | int retval; |
| 143 | 143 | ||
| 144 | if (!hid_is_usb(hdev)) | ||
| 145 | return -EINVAL; | ||
| 146 | |||
| 144 | retval = hid_parse(hdev); | 147 | retval = hid_parse(hdev); |
| 145 | if (retval) { | 148 | if (retval) { |
| 146 | hid_err(hdev, "parse failed\n"); | 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 | int retval; | 114 | int retval; |
| 115 | 115 | ||
| 116 | if (!hid_is_usb(hdev)) | ||
| 117 | return -EINVAL; | ||
| 118 | |||
| 116 | retval = hid_parse(hdev); | 119 | retval = hid_parse(hdev); |
| 117 | if (retval) { | 120 | if (retval) { |
| 118 | hid_err(hdev, "parse failed\n"); | 121 | hid_err(hdev, "parse failed\n"); |
| @@ -152,6 +152,9 @@ static int samsung_probe(struct hid_device *hdev, · 151 unmodified lines | |||
| 152 | int ret; | 152 | int ret; |
| 153 | unsigned int cmask = HID_CONNECT_DEFAULT; | 153 | unsigned int cmask = HID_CONNECT_DEFAULT; |
| 154 | 154 | ||
| 155 | if (!hid_is_usb(hdev)) | ||
| 156 | return -EINVAL; | ||
| 157 | |||
| 155 | ret = hid_parse(hdev); | 158 | ret = hid_parse(hdev); |
| 156 | if (ret) { | 159 | if (ret) { |
| 157 | hid_err(hdev, "parse failed\n"); | 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 | sc->quirks = quirks; | 3000 | sc->quirks = quirks; |
| 3001 | hid_set_drvdata(hdev, sc); | 3001 | hid_set_drvdata(hdev, sc); |
| 3002 | sc->hdev = hdev; | 3002 | sc->hdev = hdev; |
| 3003 | usbdev = to_usb_device(sc->hdev->dev.parent->parent); | ||
| 3004 | 3003 | ||
| 3005 | ret = hid_parse(hdev); | 3004 | ret = hid_parse(hdev); |
| 3006 | if (ret) { | 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 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) { | 3038 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) { |
| 3040 | hid_err(hdev, "failed to claim input\n"); | 3039 | hid_err(hdev, "failed to claim input\n"); |
| 3041 | hid_hw_stop(hdev); | 3040 | ret = -ENODEV; |
| 3042 | return -ENODEV; | 3041 | goto err; |
| 3043 | } | 3042 | } |
| 3044 | 3043 | ||
| 3045 | if (sc->quirks & (GHL_GUITAR_PS3WIIU | GHL_GUITAR_PS4)) { | 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 | sc->ghl_urb = usb_alloc_urb(0, GFP_ATOMIC); | 3052 | sc->ghl_urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 3047 | if (!sc->ghl_urb) | 3053 | if (!sc->ghl_urb) { |
| 3048 | return -ENOMEM; | 3054 | ret = -ENOMEM; |
| 3055 | goto err; | ||
| 3056 | } | ||
| 3049 | 3057 | ||
| 3050 | if (sc->quirks & GHL_GUITAR_PS3WIIU) | 3058 | if (sc->quirks & GHL_GUITAR_PS3WIIU) |
| 3051 | ret = ghl_init_urb(sc, usbdev, ghl_ps3wiiu_magic_data, | 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 | ARRAY_SIZE(ghl_ps4_magic_data)); | 3063 | ARRAY_SIZE(ghl_ps4_magic_data)); |
| 3056 | if (ret) { | 3064 | if (ret) { |
| 3057 | hid_err(hdev, "error preparing URB\n"); | 3065 | hid_err(hdev, "error preparing URB\n"); |
| 3058 | return ret; | 3066 | goto err; |
| 3059 | } | 3067 | } |
| 3060 | 3068 | ||
| 3061 | timer_setup(&sc->ghl_poke_timer, ghl_magic_poke, 0); | 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 | return ret; | 3074 | return ret; |
| 3075 | |||
| 3076 | err: | ||
| 3077 | hid_hw_stop(hdev); | ||
| 3078 | return ret; | ||
| 3067 | } | 3079 | } |
| 3068 | 3080 | ||
| 3069 | static void sony_remove(struct hid_device *hdev) | 3081 | static void sony_remove(struct hid_device *hdev) |
| @@ -274,6 +274,9 @@ static int thrustmaster_probe(struct hid_device *hdev, const struct hid_device_i · 273 unmodified lines | |||
| 274 | int ret = 0; | 274 | int ret = 0; |
| 275 | struct tm_wheel *tm_wheel = NULL; | 275 | struct tm_wheel *tm_wheel = NULL; |
| 276 | 276 | ||
| 277 | if (!hid_is_usb(hdev)) | ||
| 278 | return -EINVAL; | ||
| 279 | |||
| 277 | ret = hid_parse(hdev); | 280 | ret = hid_parse(hdev); |
| 278 | if (ret) { | 281 | if (ret) { |
| 279 | hid_err(hdev, "parse failed with error %d\n", ret); | 282 | hid_err(hdev, "parse failed with error %d\n", ret); |
| @@ -311,7 +311,7 @@ static int u2fzero_probe(struct hid_device *hdev, · 310 unmodified lines | |||
| 311 | unsigned int minor; | 311 | unsigned int minor; |
| 312 | int ret; | 312 | int ret; |
| 313 | 313 | ||
| 314 | if (!hid_is_using_ll_driver(hdev, &usb_hid_driver)) | 314 | if (!hid_is_usb(hdev)) |
| 315 | return -EINVAL; | 315 | return -EINVAL; |
| 316 | 316 | ||
| 317 | dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); | 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 | struct uclogic_drvdata *drvdata = NULL; | 164 | struct uclogic_drvdata *drvdata = NULL; |
| 165 | bool params_initialized = false; | 165 | bool params_initialized = false; |
| 166 | 166 | ||
| 167 | if (!hid_is_usb(hdev)) | ||
| 168 | return -EINVAL; | ||
| 169 | |||
| 167 | /* | 170 | /* |
| 168 | * libinput requires the pad interface to be on a different node | 171 | * libinput requires the pad interface to be on a different node |
| 169 | * than the pen, so use QUIRK_MULTI_INPUT for all tablets. | 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 | struct uclogic_params p = {0, }; | 843 | struct uclogic_params p = {0, }; |
| 844 | 844 | ||
| 845 | /* Check arguments */ | 845 | /* Check arguments */ |
| 846 | if (params == NULL || hdev == NULL || | 846 | if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) { |
| 847 | !hid_is_using_ll_driver(hdev, &usb_hid_driver)) { | ||
| 848 | rc = -EINVAL; | 847 | rc = -EINVAL; |
| 849 | goto cleanup; | 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 | if (ish_should_leave_d0i3(pdev) && !dev->suspend_flag | 267 | if (ish_should_leave_d0i3(pdev) && !dev->suspend_flag |
| 268 | && IPC_IS_ISH_ILUP(fwsts)) { | 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 | ish_set_host_ready(dev); | 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 | pci_save_state(pdev); | 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 | } else { | 344 | } else { |
| 343 | /* | 345 | /* |
| @@ -726,7 +726,7 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, · 725 unmodified lines | |||
| 726 | * Skip the query for this type and modify defaults based on | 726 | * Skip the query for this type and modify defaults based on |
| 727 | * interface number. | 727 | * interface number. |
| 728 | */ | 728 | */ |
| 729 | if (features->type == WIRELESS) { | 729 | if (features->type == WIRELESS && intf) { |
| 730 | if (intf->cur_altsetting->desc.bInterfaceNumber == 0) | 730 | if (intf->cur_altsetting->desc.bInterfaceNumber == 0) |
| 731 | features->device_type = WACOM_DEVICETYPE_WL_MONITOR; | 731 | features->device_type = WACOM_DEVICETYPE_WL_MONITOR; |
| 732 | else | 732 | else |
| @@ -2214,7 +2214,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix) · 1481 unmodified lines | |||
| 2214 | if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) { | 2214 | if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) { |
| 2215 | char *product_name = wacom->hdev->name; | 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 | struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent); | 2218 | struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent); |
| 2219 | struct usb_device *dev = interface_to_usbdev(intf); | 2219 | struct usb_device *dev = interface_to_usbdev(intf); |
| 2220 | product_name = dev->product; | 2220 | product_name = dev->product; |
| @@ -2451,6 +2451,9 @@ static void wacom_wireless_work(struct work_struct *work) · 230 unmodified lines | |||
| 2451 | 2451 | ||
| 2452 | wacom_destroy_battery(wacom); | 2452 | wacom_destroy_battery(wacom); |
| 2453 | 2453 | ||
| 2454 | if (!usbdev) | ||
| 2455 | return; | ||
| 2456 | |||
| 2454 | /* Stylus interface */ | 2457 | /* Stylus interface */ |
| 2455 | hdev1 = usb_get_intfdata(usbdev->config->interface[1]); | 2458 | hdev1 = usb_get_intfdata(usbdev->config->interface[1]); |
| 2456 | wacom1 = hid_get_drvdata(hdev1); | 2459 | wacom1 = hid_get_drvdata(hdev1); |
| @@ -2730,8 +2733,6 @@ static void wacom_mode_change_work(struct work_struct *work) · 273 unmodified lines | |||
| 2730 | static int wacom_probe(struct hid_device *hdev, | 2733 | static int wacom_probe(struct hid_device *hdev, |
| 2731 | const struct hid_device_id *id) | 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 | struct wacom *wacom; | 2736 | struct wacom *wacom; |
| 2736 | struct wacom_wac *wacom_wac; | 2737 | struct wacom_wac *wacom_wac; |
| 2737 | struct wacom_features *features; | 2738 | struct wacom_features *features; |
| @@ -2766,8 +2767,14 @@ static int wacom_probe(struct hid_device *hdev, · 28 unmodified lines | |||
| 2766 | wacom_wac->hid_data.inputmode = -1; | 2767 | wacom_wac->hid_data.inputmode = -1; |
| 2767 | wacom_wac->mode_report = -1; | 2768 | wacom_wac->mode_report = -1; |
| 2768 | 2769 | ||
| 2769 | wacom->usbdev = dev; | 2770 | if (hid_is_usb(hdev)) { |
| 2770 | wacom->intf = intf; | 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 | mutex_init(&wacom->lock); | 2778 | mutex_init(&wacom->lock); |
| 2772 | INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work); | 2779 | INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work); |
| 2773 | INIT_WORK(&wacom->wireless_work, wacom_wireless_work); | 2780 | INIT_WORK(&wacom->wireless_work, wacom_wireless_work); |
| @@ -729,7 +729,7 @@ static int corsairpsu_probe(struct hid_device *hdev, const struct hid_device_id · 728 unmodified lines | |||
| 729 | corsairpsu_check_cmd_support(priv); | 729 | corsairpsu_check_cmd_support(priv); |
| 730 | 730 | ||
| 731 | priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "corsairpsu", priv, | 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 | if (IS_ERR(priv->hwmon_dev)) { | 734 | if (IS_ERR(priv->hwmon_dev)) { |
| 735 | ret = PTR_ERR(priv->hwmon_dev); | 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 | struct dell_smm_data *data = dev_get_drvdata(dev); | 628 | struct dell_smm_data *data = dev_get_drvdata(dev); |
| 629 | 629 | ||
| 630 | /* Register the proc entry */ | 630 | /* Only register exit function if creation was successful */ |
| 631 | proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data); | 631 | if (proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data)) |
| 632 | 632 | devm_add_action_or_reset(dev, i8k_exit_procfs, NULL); | |
| 633 | devm_add_action_or_reset(dev, i8k_exit_procfs, NULL); | ||
| 634 | } | 633 | } |
| 635 | 634 | ||
| 636 | #else | 635 | #else |
| @@ -1527,7 +1527,7 @@ static u16 nct6775_wmi_read_value(struct nct6775_data *data, u16 reg) · 1526 unmodified lines | |||
| 1527 | 1527 | ||
| 1528 | nct6775_wmi_set_bank(data, reg); | 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 | if (err) | 1531 | if (err) |
| 1532 | return 0; | 1532 | return 0; |
| 1533 | 1533 | ||
| @@ -336,8 +336,6 @@ static int pwm_fan_probe(struct platform_device *pdev) · 335 unmodified lines | |||
| 336 | return ret; | 336 | return ret; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | ctx->pwm_value = MAX_PWM; | ||
| 340 | |||
| 341 | pwm_init_state(ctx->pwm, &ctx->pwm_state); | 339 | pwm_init_state(ctx->pwm, &ctx->pwm_state); |
| 342 | 340 | ||
| 343 | /* | 341 | /* |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | |||
| 23 | /* | 23 | /* |
| 24 | * I2C command delays (in microseconds) | 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 | #define SHT4X_DELAY_EXTRA 10000 | 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 | if (ret < 0) | 90 | if (ret < 0) |
| 91 | goto unlock; | 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 | ret = i2c_master_recv(client, raw_data, SHT4X_RESPONSE_LENGTH); | 95 | ret = i2c_master_recv(client, raw_data, SHT4X_RESPONSE_LENGTH); |
| 96 | if (ret != SHT4X_RESPONSE_LENGTH) { | 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 | static const struct i2c_algorithm cbus_i2c_algo = { | 197 | static const struct i2c_algorithm cbus_i2c_algo = { |
| 198 | .smbus_xfer = cbus_i2c_smbus_xfer, | 198 | .smbus_xfer = cbus_i2c_smbus_xfer, |
| 199 | .functionality = cbus_i2c_func, | 199 | .smbus_xfer_atomic = cbus_i2c_smbus_xfer, |
| 200 | .functionality = cbus_i2c_func, | ||
| 200 | }; | 201 | }; |
| 201 | 202 | ||
| 202 | static int cbus_i2c_remove(struct platform_device *pdev) | 203 | static int cbus_i2c_remove(struct platform_device *pdev) |
| @@ -636,7 +636,7 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) · 635 unmodified lines | |||
| 636 | status = readb(i2c->base + MPC_I2C_SR); | 636 | status = readb(i2c->base + MPC_I2C_SR); |
| 637 | if (status & CSR_MIF) { | 637 | if (status & CSR_MIF) { |
| 638 | /* Wait up to 100us for transfer to properly complete */ | 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 | writeb(0, i2c->base + MPC_I2C_SR); | 640 | writeb(0, i2c->base + MPC_I2C_SR); |
| 641 | mpc_i2c_do_intr(i2c, status); | 641 | mpc_i2c_do_intr(i2c, status); |
| 642 | return IRQ_HANDLED; | 642 | return IRQ_HANDLED; |
| @@ -423,8 +423,8 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) · 422 unmodified lines | |||
| 423 | if (!(ipd & REG_INT_MBRF)) | 423 | if (!(ipd & REG_INT_MBRF)) |
| 424 | return; | 424 | return; |
| 425 | 425 | ||
| 426 | /* ack interrupt */ | 426 | /* ack interrupt (read also produces a spurious START flag, clear it too) */ |
| 427 | i2c_writel(i2c, REG_INT_MBRF, REG_IPD); | 427 | i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD); |
| 428 | 428 | ||
| 429 | /* Can only handle a maximum of 32 bytes at a time */ | 429 | /* Can only handle a maximum of 32 bytes at a time */ |
| 430 | if (len > 32) | 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 | struct stm32f7_i2c_dev *i2c_dev = data; | 1494 | struct stm32f7_i2c_dev *i2c_dev = data; |
| 1495 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; | 1495 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; |
| 1496 | struct stm32_i2c_dma *dma = i2c_dev->dma; | ||
| 1496 | void __iomem *base = i2c_dev->base; | 1497 | void __iomem *base = i2c_dev->base; |
| 1497 | u32 status, mask; | 1498 | u32 status, mask; |
| 1498 | int ret = IRQ_HANDLED; | 1499 | int ret = IRQ_HANDLED; |
| @@ -1518,6 +1519,10 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) · 19 unmodified lines | |||
| 1518 | dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n", | 1519 | dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n", |
| 1519 | __func__, f7_msg->addr); | 1520 | __func__, f7_msg->addr); |
| 1520 | writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR); | 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 | f7_msg->result = -ENXIO; | 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 | /* Clear STOP flag */ | 1538 | /* Clear STOP flag */ |
| 1534 | writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); | 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 | ret = IRQ_WAKE_THREAD; | 1542 | ret = IRQ_WAKE_THREAD; |
| 1538 | } else { | 1543 | } else { |
| 1539 | i2c_dev->master_mode = false; | 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 | if (f7_msg->stop) { | 1551 | if (f7_msg->stop) { |
| 1547 | mask = STM32F7_I2C_CR2_STOP; | 1552 | mask = STM32F7_I2C_CR2_STOP; |
| 1548 | stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask); | 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 | ret = IRQ_WAKE_THREAD; | 1555 | ret = IRQ_WAKE_THREAD; |
| 1551 | } else if (f7_msg->smbus) { | 1556 | } else if (f7_msg->smbus) { |
| 1552 | stm32f7_i2c_smbus_rep_start(i2c_dev); | 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 | if (!ret) { | 1588 | if (!ret) { |
| 1584 | dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); | 1589 | dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); |
| 1585 | stm32f7_i2c_disable_dma_req(i2c_dev); | 1590 | stm32f7_i2c_disable_dma_req(i2c_dev); |
| 1586 | dmaengine_terminate_all(dma->chan_using); | 1591 | dmaengine_terminate_async(dma->chan_using); |
| 1587 | f7_msg->result = -ETIMEDOUT; | 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 | /* Disable dma */ | 1665 | /* Disable dma */ |
| 1661 | if (i2c_dev->use_dma) { | 1666 | if (i2c_dev->use_dma) { |
| 1662 | stm32f7_i2c_disable_dma_req(i2c_dev); | 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 | i2c_dev->master_mode = false; | 1671 | i2c_dev->master_mode = false; |
| @@ -1696,12 +1701,26 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, · 29 unmodified lines | |||
| 1696 | time_left = wait_for_completion_timeout(&i2c_dev->complete, | 1701 | time_left = wait_for_completion_timeout(&i2c_dev->complete, |
| 1697 | i2c_dev->adap.timeout); | 1702 | i2c_dev->adap.timeout); |
| 1698 | ret = f7_msg->result; | 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 | if (!time_left) { | 1718 | if (!time_left) { |
| 1701 | dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n", | 1719 | dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n", |
| 1702 | i2c_dev->msg->addr); | 1720 | i2c_dev->msg->addr); |
| 1703 | if (i2c_dev->use_dma) | 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 | ret = -ETIMEDOUT; | 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 | timeout = wait_for_completion_timeout(&i2c_dev->complete, | 1763 | timeout = wait_for_completion_timeout(&i2c_dev->complete, |
| 1745 | i2c_dev->adap.timeout); | 1764 | i2c_dev->adap.timeout); |
| 1746 | ret = f7_msg->result; | 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 | goto pm_free; | 1777 | goto pm_free; |
| 1778 | } | ||
| 1749 | 1779 | ||
| 1750 | if (!timeout) { | 1780 | if (!timeout) { |
| 1751 | dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr); | 1781 | dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr); |
| 1752 | if (i2c_dev->use_dma) | 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 | ret = -ETIMEDOUT; | 1785 | ret = -ETIMEDOUT; |
| 1755 | goto pm_free; | 1786 | goto pm_free; |
| 1756 | } | 1787 | } |
| @@ -22,24 +22,24 @@ · 21 unmodified lines | |||
| 22 | /** | 22 | /** |
| 23 | * struct virtio_i2c - virtio I2C data | 23 | * struct virtio_i2c - virtio I2C data |
| 24 | * @vdev: virtio device for this controller | 24 | * @vdev: virtio device for this controller |
| 25 | * @completion: completion of virtio I2C message | ||
| 26 | * @adap: I2C adapter for this controller | 25 | * @adap: I2C adapter for this controller |
| 27 | * @vq: the virtio virtqueue for communication | 26 | * @vq: the virtio virtqueue for communication |
| 28 | */ | 27 | */ |
| 29 | struct virtio_i2c { | 28 | struct virtio_i2c { |
| 30 | struct virtio_device *vdev; | 29 | struct virtio_device *vdev; |
| 31 | struct completion completion; | ||
| 32 | struct i2c_adapter adap; | 30 | struct i2c_adapter adap; |
| 33 | struct virtqueue *vq; | 31 | struct virtqueue *vq; |
| 34 | }; | 32 | }; |
| 35 | 33 | ||
| 36 | /** | 34 | /** |
| 37 | * struct virtio_i2c_req - the virtio I2C request structure | 35 | * struct virtio_i2c_req - the virtio I2C request structure |
| 36 | * @completion: completion of virtio I2C message | ||
| 38 | * @out_hdr: the OUT header of the virtio I2C message | 37 | * @out_hdr: the OUT header of the virtio I2C message |
| 39 | * @buf: the buffer into which data is read, or from which it's written | 38 | * @buf: the buffer into which data is read, or from which it's written |
| 40 | * @in_hdr: the IN header of the virtio I2C message | 39 | * @in_hdr: the IN header of the virtio I2C message |
| 41 | */ | 40 | */ |
| 42 | struct virtio_i2c_req { | 41 | struct virtio_i2c_req { |
| 42 | struct completion completion; | ||
| 43 | struct virtio_i2c_out_hdr out_hdr ____cacheline_aligned; | 43 | struct virtio_i2c_out_hdr out_hdr ____cacheline_aligned; |
| 44 | uint8_t *buf ____cacheline_aligned; | 44 | uint8_t *buf ____cacheline_aligned; |
| 45 | struct virtio_i2c_in_hdr in_hdr ____cacheline_aligned; | 45 | struct virtio_i2c_in_hdr in_hdr ____cacheline_aligned; |
| @@ -47,9 +47,11 @@ struct virtio_i2c_req { · 1 unmodified line | |||
| 47 | 47 | ||
| 48 | static void virtio_i2c_msg_done(struct virtqueue *vq) | 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 | static int virtio_i2c_prepare_reqs(struct virtqueue *vq, | 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 | for (i = 0; i < num; i++) { | 64 | for (i = 0; i < num; i++) { |
| 63 | int outcnt = 0, incnt = 0; | 65 | int outcnt = 0, incnt = 0; |
| 64 | 66 | ||
| 67 | init_completion(&reqs[i].completion); | ||
| 68 | |||
| 65 | /* | 69 | /* |
| 66 | * Only 7-bit mode supported for this moment. For the address | 70 | * Only 7-bit mode supported for this moment. For the address |
| 67 | * format, Please check the Virtio I2C Specification. | 71 | * format, Please check the Virtio I2C Specification. |
| @@ -106,21 +110,15 @@ static int virtio_i2c_complete_reqs(struct virtqueue *vq, · 38 unmodified lines | |||
| 106 | struct virtio_i2c_req *reqs, | 110 | struct virtio_i2c_req *reqs, |
| 107 | struct i2c_msg *msgs, int num) | 111 | struct i2c_msg *msgs, int num) |
| 108 | { | 112 | { |
| 109 | struct virtio_i2c_req *req; | ||
| 110 | bool failed = false; | 113 | bool failed = false; |
| 111 | unsigned int len; | ||
| 112 | int i, j = 0; | 114 | int i, j = 0; |
| 113 | 115 | ||
| 114 | for (i = 0; i < num; i++) { | 116 | for (i = 0; i < num; i++) { |
| 115 | /* Detach the ith request from the vq */ | 117 | struct virtio_i2c_req *req = &reqs[i]; |
| 116 | req = virtqueue_get_buf(vq, &len); | ||
| 117 | 118 | ||
| 118 | /* | 119 | wait_for_completion(&req->completion); |
| 119 | * Condition req == &reqs[i] should always meet since we have | 120 | |
| 120 | * total num requests in the vq. reqs[i] can never be NULL here. | 121 | if (!failed && req->in_hdr.status != VIRTIO_I2C_MSG_OK) |
| 121 | */ | ||
| 122 | if (!failed && (WARN_ON(req != &reqs[i]) || | ||
| 123 | req->in_hdr.status != VIRTIO_I2C_MSG_OK)) | ||
| 124 | failed = true; | 122 | failed = true; |
| 125 | 123 | ||
| 126 | i2c_put_dma_safe_msg_buf(reqs[i].buf, &msgs[i], !failed); | 124 | i2c_put_dma_safe_msg_buf(reqs[i].buf, &msgs[i], !failed); |
| @@ -156,12 +154,8 @@ static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, · 29 unmodified lines | |||
| 156 | * remote here to clear the virtqueue, so we can try another set of | 154 | * remote here to clear the virtqueue, so we can try another set of |
| 157 | * messages later on. | 155 | * messages later on. |
| 158 | */ | 156 | */ |
| 159 | |||
| 160 | reinit_completion(&vi->completion); | ||
| 161 | virtqueue_kick(vq); | 157 | virtqueue_kick(vq); |
| 162 | 158 | ||
| 163 | wait_for_completion(&vi->completion); | ||
| 164 | |||
| 165 | count = virtio_i2c_complete_reqs(vq, reqs, msgs, count); | 159 | count = virtio_i2c_complete_reqs(vq, reqs, msgs, count); |
| 166 | 160 | ||
| 167 | err_free: | 161 | err_free: |
| @@ -210,8 +204,6 @@ static int virtio_i2c_probe(struct virtio_device *vdev) · 42 unmodified lines | |||
| 210 | vdev->priv = vi; | 204 | vdev->priv = vi; |
| 211 | vi->vdev = vdev; | 205 | vi->vdev = vdev; |
| 212 | 206 | ||
| 213 | init_completion(&vi->completion); | ||
| 214 | |||
| 215 | ret = virtio_i2c_setup_vqs(vi); | 207 | ret = virtio_i2c_setup_vqs(vi); |
| 216 | if (ret) | 208 | if (ret) |
| 217 | return ret; | 209 | return ret; |
| @@ -1595,8 +1595,7 @@ static int kxcjk1013_probe(struct i2c_client *client, · 1594 unmodified lines | |||
| 1595 | return 0; | 1595 | return 0; |
| 1596 | 1596 | ||
| 1597 | err_buffer_cleanup: | 1597 | err_buffer_cleanup: |
| 1598 | if (data->dready_trig) | 1598 | iio_triggered_buffer_cleanup(indio_dev); |
| 1599 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 1600 | err_trigger_unregister: | 1599 | err_trigger_unregister: |
| 1601 | if (data->dready_trig) | 1600 | if (data->dready_trig) |
| 1602 | iio_trigger_unregister(data->dready_trig); | 1601 | iio_trigger_unregister(data->dready_trig); |
| @@ -1618,8 +1617,8 @@ static int kxcjk1013_remove(struct i2c_client *client) · 15 unmodified lines | |||
| 1618 | pm_runtime_disable(&client->dev); | 1617 | pm_runtime_disable(&client->dev); |
| 1619 | pm_runtime_set_suspended(&client->dev); | 1618 | pm_runtime_set_suspended(&client->dev); |
| 1620 | 1619 | ||
| 1620 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 1621 | if (data->dready_trig) { | 1621 | if (data->dready_trig) { |
| 1622 | iio_triggered_buffer_cleanup(indio_dev); | ||
| 1623 | iio_trigger_unregister(data->dready_trig); | 1622 | iio_trigger_unregister(data->dready_trig); |
| 1624 | iio_trigger_unregister(data->motion_trig); | 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 | hw_values.chan, | 224 | hw_values.chan, |
| 225 | sizeof(hw_values.chan)); | 225 | sizeof(hw_values.chan)); |
| 226 | if (ret) { | 226 | if (ret) { |
| 227 | dev_err(st->dev, | 227 | dev_err(st->dev, "error reading data: %d\n", ret); |
| 228 | "error reading data\n"); | 228 | goto out; |
| 229 | return ret; | ||
| 230 | } | 229 | } |
| 231 | 230 | ||
| 232 | iio_push_to_buffers_with_timestamp(indio_dev, | 231 | iio_push_to_buffers_with_timestamp(indio_dev, |
| 233 | &hw_values, | 232 | &hw_values, |
| 234 | iio_get_time_ns(indio_dev)); | 233 | iio_get_time_ns(indio_dev)); |
| 234 | out: | ||
| 235 | iio_trigger_notify_done(indio_dev->trig); | 235 | iio_trigger_notify_done(indio_dev->trig); |
| 236 | 236 | ||
| 237 | return IRQ_HANDLED; | 237 | return IRQ_HANDLED; |
| @@ -1470,7 +1470,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev) · 1469 unmodified lines | |||
| 1470 | if (ret) | 1470 | if (ret) |
| 1471 | return ret; | 1471 | return ret; |
| 1472 | 1472 | ||
| 1473 | indio_dev->trig = trig; | 1473 | indio_dev->trig = iio_trigger_get(trig); |
| 1474 | 1474 | ||
| 1475 | return 0; | 1475 | return 0; |
| 1476 | } | 1476 | } |
| @@ -532,7 +532,7 @@ config IMX7D_ADC · 531 unmodified lines | |||
| 532 | 532 | ||
| 533 | config IMX8QXP_ADC | 533 | config IMX8QXP_ADC |
| 534 | tristate "NXP IMX8QXP ADC driver" | 534 | tristate "NXP IMX8QXP ADC driver" |
| 535 | depends on ARCH_MXC_ARM64 || COMPILE_TEST | 535 | depends on ARCH_MXC || COMPILE_TEST |
| 536 | depends on HAS_IOMEM | 536 | depends on HAS_IOMEM |
| 537 | help | 537 | help |
| 538 | Say yes here to build support for IMX8QXP ADC. | 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 | iio_push_to_buffers_with_timestamp(indio_dev, &st->data.scan, | 480 | iio_push_to_buffers_with_timestamp(indio_dev, &st->data.scan, |
| 481 | iio_get_time_ns(indio_dev)); | 481 | iio_get_time_ns(indio_dev)); |
| 482 | 482 | ||
| 483 | iio_trigger_notify_done(indio_dev->trig); | ||
| 484 | err_unlock: | 483 | err_unlock: |
| 484 | iio_trigger_notify_done(indio_dev->trig); | ||
| 485 | mutex_unlock(&st->lock); | 485 | mutex_unlock(&st->lock); |
| 486 | 486 | ||
| 487 | return IRQ_HANDLED; | 487 | return IRQ_HANDLED; |
| @@ -1586,7 +1586,8 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, · 1585 unmodified lines | |||
| 1586 | *val = st->conversion_value; | 1586 | *val = st->conversion_value; |
| 1587 | ret = at91_adc_adjust_val_osr(st, val); | 1587 | ret = at91_adc_adjust_val_osr(st, val); |
| 1588 | if (chan->scan_type.sign == 's') | 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 | st->conversion_done = false; | 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 | struct iio_chan_spec const *chan, int *val) | 251 | struct iio_chan_spec const *chan, int *val) |
| 252 | { | 252 | { |
| 253 | struct axp20x_adc_iio *info = iio_priv(indio_dev); | 253 | struct axp20x_adc_iio *info = iio_priv(indio_dev); |
| 254 | int size; | ||
| 255 | 254 | ||
| 256 | /* | 255 | *val = axp20x_read_variable_width(info->regmap, chan->address, 12); |
| 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); | ||
| 267 | if (*val < 0) | 256 | if (*val < 0) |
| 268 | return *val; | 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 | return IIO_VAL_INT_PLUS_MICRO; | 375 | return IIO_VAL_INT_PLUS_MICRO; |
| 387 | 376 | ||
| 388 | case IIO_CURRENT: | 377 | case IIO_CURRENT: |
| 389 | *val = 0; | 378 | *val = 1; |
| 390 | *val2 = 500000; | 379 | return IIO_VAL_INT; |
| 391 | return IIO_VAL_INT_PLUS_MICRO; | ||
| 392 | 380 | ||
| 393 | case IIO_TEMP: | 381 | case IIO_TEMP: |
| 394 | *val = 100; | 382 | *val = 100; |
| @@ -248,7 +248,6 @@ static int dln2_adc_set_chan_period(struct dln2_adc *dln2, · 247 unmodified lines | |||
| 248 | static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel) | 248 | static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel) |
| 249 | { | 249 | { |
| 250 | int ret, i; | 250 | int ret, i; |
| 251 | struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev); | ||
| 252 | u16 conflict; | 251 | u16 conflict; |
| 253 | __le16 value; | 252 | __le16 value; |
| 254 | int olen = sizeof(value); | 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 | .chan = channel, | 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 | ret = dln2_adc_set_chan_enabled(dln2, channel, true); | 259 | ret = dln2_adc_set_chan_enabled(dln2, channel, true); |
| 265 | if (ret < 0) | 260 | if (ret < 0) |
| 266 | goto release_direct; | 261 | return ret; |
| 267 | 262 | ||
| 268 | ret = dln2_adc_set_port_enabled(dln2, true, &conflict); | 263 | ret = dln2_adc_set_port_enabled(dln2, true, &conflict); |
| 269 | if (ret < 0) { | 264 | if (ret < 0) { |
| @@ -300,8 +295,6 @@ disable_port: · 30 unmodified lines | |||
| 300 | dln2_adc_set_port_enabled(dln2, false, NULL); | 295 | dln2_adc_set_port_enabled(dln2, false, NULL); |
| 301 | disable_chan: | 296 | disable_chan: |
| 302 | dln2_adc_set_chan_enabled(dln2, channel, false); | 297 | dln2_adc_set_chan_enabled(dln2, channel, false); |
| 303 | release_direct: | ||
| 304 | iio_device_release_direct_mode(indio_dev); | ||
| 305 | 298 | ||
| 306 | return ret; | 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 | switch (mask) { | 331 | switch (mask) { |
| 339 | case IIO_CHAN_INFO_RAW: | 332 | case IIO_CHAN_INFO_RAW: |
| 333 | ret = iio_device_claim_direct_mode(indio_dev); | ||
| 334 | if (ret < 0) | ||
| 335 | return ret; | ||
| 336 | |||
| 340 | mutex_lock(&dln2->mutex); | 337 | mutex_lock(&dln2->mutex); |
| 341 | ret = dln2_adc_read(dln2, chan->channel); | 338 | ret = dln2_adc_read(dln2, chan->channel); |
| 342 | mutex_unlock(&dln2->mutex); | 339 | mutex_unlock(&dln2->mutex); |
| 343 | 340 | ||
| 341 | iio_device_release_direct_mode(indio_dev); | ||
| 342 | |||
| 344 | if (ret < 0) | 343 | if (ret < 0) |
| 345 | return ret; | 344 | return ret; |
| 346 | 345 | ||
| @@ -656,7 +655,11 @@ static int dln2_adc_probe(struct platform_device *pdev) · 309 unmodified lines | |||
| 656 | return -ENOMEM; | 655 | return -ENOMEM; |
| 657 | } | 656 | } |
| 658 | iio_trigger_set_drvdata(dln2->trig, dln2); | 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 | iio_trigger_set_immutable(indio_dev, dln2->trig); | 663 | iio_trigger_set_immutable(indio_dev, dln2->trig); |
| 661 | 664 | ||
| 662 | ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, | 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 | struct stm32_adc *adc = iio_priv(indio_dev); | 1118 | struct stm32_adc *adc = iio_priv(indio_dev); |
| 1119 | 1119 | ||
| 1120 | stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0); | ||
| 1120 | stm32h7_adc_disable(indio_dev); | 1121 | stm32h7_adc_disable(indio_dev); |
| 1121 | stm32_adc_int_ch_disable(adc); | 1122 | stm32_adc_int_ch_disable(adc); |
| 1122 | stm32h7_adc_enter_pwr_down(adc); | 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 | /* Get calibration data for vrefint channel */ | 1987 | /* Get calibration data for vrefint channel */ |
| 1987 | ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint); | 1988 | ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint); |
| 1988 | if (ret && ret != -ENOENT) { | 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 | "nvmem access error\n"); | 1991 | "nvmem access error\n"); |
| 1991 | } | 1992 | } |
| 1992 | if (ret == -ENOENT) | 1993 | if (ret == -ENOENT) |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/bitfield.h> | 9 | #include <linux/bitfield.h> |
| 10 | #include <linux/bitops.h> | ||
| 10 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| 11 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 12 | #include <linux/kernel.h> | 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 | goto err_unlock; | 125 | goto err_unlock; |
| 125 | } | 126 | } |
| 126 | 127 | ||
| 127 | *val = temp; | 128 | *val = sign_extend32(temp, 15); |
| 128 | 129 | ||
| 129 | err_unlock: | 130 | err_unlock: |
| 130 | mutex_unlock(&st->lock); | 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 | /* extract lower 12 bits temperature reading */ | 149 | /* extract lower 12 bits temperature reading */ |
| 149 | *val = temp & 0x0FFF; | 150 | *val = sign_extend32(temp, 11); |
| 150 | 151 | ||
| 151 | err_unlock: | 152 | err_unlock: |
| 152 | mutex_unlock(&st->lock); | 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 | iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); | 62 | iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); |
| 63 | 63 | ||
| 64 | error_ret: | ||
| 64 | iio_trigger_notify_done(indio_dev->trig); | 65 | iio_trigger_notify_done(indio_dev->trig); |
| 65 | 66 | ||
| 66 | error_ret: | ||
| 67 | return IRQ_HANDLED; | 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 | irq_modify_status(trig->subirq_base + i, | 556 | irq_modify_status(trig->subirq_base + i, |
| 557 | IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); | 557 | IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); |
| 558 | } | 558 | } |
| 559 | get_device(&trig->dev); | ||
| 560 | 559 | ||
| 561 | return trig; | 560 | return trig; |
| 562 | 561 | ||
| @@ -1275,7 +1275,7 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p) · 1274 unmodified lines | |||
| 1275 | ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1, | 1275 | ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1, |
| 1276 | als_buf, sizeof(als_buf)); | 1276 | als_buf, sizeof(als_buf)); |
| 1277 | if (ret < 0) | 1277 | if (ret < 0) |
| 1278 | return ret; | 1278 | goto done; |
| 1279 | if (test_bit(0, indio_dev->active_scan_mask)) | 1279 | if (test_bit(0, indio_dev->active_scan_mask)) |
| 1280 | scan.channels[j++] = le16_to_cpu(als_buf[1]); | 1280 | scan.channels[j++] = le16_to_cpu(als_buf[1]); |
| 1281 | if (test_bit(1, indio_dev->active_scan_mask)) | 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 | mutex_lock(&data->lock); | 546 | mutex_lock(&data->lock); |
| 547 | ret = regmap_field_read(data->reg_flag_nf, &dir); | 547 | ret = regmap_field_read(data->reg_flag_nf, &dir); |
| 548 | if (ret < 0) { | 548 | if (ret < 0) { |
| 549 | dev_err(&data->client->dev, "register read failed\n"); | 549 | dev_err(&data->client->dev, "register read failed: %d\n", ret); |
| 550 | mutex_unlock(&data->lock); | 550 | goto out; |
| 551 | return ret; | ||
| 552 | } | 551 | } |
| 553 | event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, | 552 | event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, |
| 554 | IIO_EV_TYPE_THRESH, | 553 | IIO_EV_TYPE_THRESH, |
| @@ -560,6 +559,7 @@ static irqreturn_t stk3310_irq_event_handler(int irq, void *private) · 5 unmodified lines | |||
| 560 | ret = regmap_field_write(data->reg_flag_psint, 0); | 559 | ret = regmap_field_write(data->reg_flag_psint, 0); |
| 561 | if (ret < 0) | 560 | if (ret < 0) |
| 562 | dev_err(&data->client->dev, "failed to reset interrupts\n"); | 561 | dev_err(&data->client->dev, "failed to reset interrupts\n"); |
| 562 | out: | ||
| 563 | mutex_unlock(&data->lock); | 563 | mutex_unlock(&data->lock); |
| 564 | 564 | ||
| 565 | return IRQ_HANDLED; | 565 | return IRQ_HANDLED; |
| @@ -912,6 +912,6 @@ static struct platform_driver stm32_timer_trigger_driver = { · 911 unmodified lines | |||
| 912 | }; | 912 | }; |
| 913 | module_platform_driver(stm32_timer_trigger_driver); | 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 | MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver"); | 916 | MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver"); |
| 917 | MODULE_LICENSE("GPL v2"); | 917 | MODULE_LICENSE("GPL v2"); |
| @@ -8415,6 +8415,8 @@ static void receive_interrupt_common(struct hfi1_ctxtdata *rcd) · 8414 unmodified lines | |||
| 8415 | */ | 8415 | */ |
| 8416 | static void __hfi1_rcd_eoi_intr(struct hfi1_ctxtdata *rcd) | 8416 | static void __hfi1_rcd_eoi_intr(struct hfi1_ctxtdata *rcd) |
| 8417 | { | 8417 | { |
| 8418 | if (!rcd->rcvhdrq) | ||
| 8419 | return; | ||
| 8418 | clear_recv_intr(rcd); | 8420 | clear_recv_intr(rcd); |
| 8419 | if (check_packet_present(rcd)) | 8421 | if (check_packet_present(rcd)) |
| 8420 | force_recv_intr(rcd); | 8422 | force_recv_intr(rcd); |
| @@ -1012,6 +1012,8 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread) · 1011 unmodified lines | |||
| 1012 | struct hfi1_packet packet; | 1012 | struct hfi1_packet packet; |
| 1013 | int skip_pkt = 0; | 1013 | int skip_pkt = 0; |
| 1014 | 1014 | ||
| 1015 | if (!rcd->rcvhdrq) | ||
| 1016 | return RCV_PKT_OK; | ||
| 1015 | /* Control context will always use the slow path interrupt handler */ | 1017 | /* Control context will always use the slow path interrupt handler */ |
| 1016 | needset = (rcd->ctxt == HFI1_CTRL_CTXT) ? 0 : 1; | 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 | rcd->fast_handler = get_dma_rtail_setting(rcd) ? | 113 | rcd->fast_handler = get_dma_rtail_setting(rcd) ? |
| 114 | handle_receive_interrupt_dma_rtail : | 114 | handle_receive_interrupt_dma_rtail : |
| 115 | handle_receive_interrupt_nodma_rtail; | 115 | handle_receive_interrupt_nodma_rtail; |
| 116 | rcd->slow_handler = handle_receive_interrupt; | ||
| 117 | 116 | ||
| 118 | hfi1_set_seq_cnt(rcd, 1); | 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 | rcd->numa_id = numa; | 333 | rcd->numa_id = numa; |
| 335 | rcd->rcv_array_groups = dd->rcv_entries.ngroups; | 334 | rcd->rcv_array_groups = dd->rcv_entries.ngroups; |
| 336 | rcd->rhf_rcv_function_map = normal_rhf_rcv_functions; | 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 | rcd->msix_intr = CCE_NUM_MSIX_VECTORS; | 338 | rcd->msix_intr = CCE_NUM_MSIX_VECTORS; |
| 338 | 339 | ||
| 339 | mutex_init(&rcd->exp_mutex); | 340 | mutex_init(&rcd->exp_mutex); |
| @@ -874,18 +875,6 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) · 534 unmodified lines | |||
| 874 | if (ret) | 875 | if (ret) |
| 875 | goto done; | 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 | /* dd->rcd can be NULL if early initialization failed */ | 878 | /* dd->rcd can be NULL if early initialization failed */ |
| 890 | for (i = 0; dd->rcd && i < dd->first_dyn_alloc_ctxt; ++i) { | 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 | if (!rcd) | 887 | if (!rcd) |
| 899 | continue; | 888 | continue; |
| 900 | 889 | ||
| 901 | rcd->do_interrupt = &handle_receive_interrupt; | ||
| 902 | |||
| 903 | lastfail = hfi1_create_rcvhdrq(dd, rcd); | 890 | lastfail = hfi1_create_rcvhdrq(dd, rcd); |
| 904 | if (!lastfail) | 891 | if (!lastfail) |
| 905 | lastfail = hfi1_setup_eagerbufs(rcd); | 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 | rcd->egrbufs.rcvtids = NULL; | 1107 | rcd->egrbufs.rcvtids = NULL; |
| 1121 | 1108 | ||
| 1122 | for (e = 0; e < rcd->egrbufs.alloced; e++) { | 1109 | for (e = 0; e < rcd->egrbufs.alloced; e++) { |
| 1123 | if (rcd->egrbufs.buffers[e].dma) | 1110 | if (rcd->egrbufs.buffers[e].addr) |
| 1124 | dma_free_coherent(&dd->pcidev->dev, | 1111 | dma_free_coherent(&dd->pcidev->dev, |
| 1125 | rcd->egrbufs.buffers[e].len, | 1112 | rcd->egrbufs.buffers[e].len, |
| 1126 | rcd->egrbufs.buffers[e].addr, | 1113 | rcd->egrbufs.buffers[e].addr, |
| @@ -1201,6 +1188,11 @@ void hfi1_free_devdata(struct hfi1_devdata *dd) · 74 unmodified lines | |||
| 1201 | dd->tx_opstats = NULL; | 1188 | dd->tx_opstats = NULL; |
| 1202 | kfree(dd->comp_vect); | 1189 | kfree(dd->comp_vect); |
| 1203 | dd->comp_vect = NULL; | 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 | sdma_clean(dd, dd->num_sdma); | 1196 | sdma_clean(dd, dd->num_sdma); |
| 1205 | rvt_dealloc_device(&dd->verbs_dev.rdi); | 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 | goto bail; | 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 | atomic_set(&dd->ipoib_rsm_usr_num, 0); | 1302 | atomic_set(&dd->ipoib_rsm_usr_num, 0); |
| 1302 | return dd; | 1303 | return dd; |
| 1303 | 1304 | ||
| @@ -1505,13 +1506,6 @@ static void cleanup_device_data(struct hfi1_devdata *dd) · 201 unmodified lines | |||
| 1505 | 1506 | ||
| 1506 | free_credit_return(dd); | 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 | * Free any resources still in use (usually just kernel contexts) | 1510 | * Free any resources still in use (usually just kernel contexts) |
| 1517 | * at unload; we do for ctxtcnt, because that's what we allocate. | 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 | if (current->nr_cpus_allowed != 1) | 838 | if (current->nr_cpus_allowed != 1) |
| 839 | goto out; | 839 | goto out; |
| 840 | 840 | ||
| 841 | cpu_id = smp_processor_id(); | ||
| 842 | rcu_read_lock(); | 841 | rcu_read_lock(); |
| 842 | cpu_id = smp_processor_id(); | ||
| 843 | rht_node = rhashtable_lookup(dd->sdma_rht, &cpu_id, | 843 | rht_node = rhashtable_lookup(dd->sdma_rht, &cpu_id, |
| 844 | sdma_rht_params); | 844 | sdma_rht_params); |
| 845 | 845 | ||
| @@ -33,6 +33,7 @@ · 32 unmodified lines | |||
| 33 | #include <linux/acpi.h> | 33 | #include <linux/acpi.h> |
| 34 | #include <linux/etherdevice.h> | 34 | #include <linux/etherdevice.h> |
| 35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
| 36 | #include <linux/iopoll.h> | ||
| 36 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
| 37 | #include <linux/types.h> | 38 | #include <linux/types.h> |
| 38 | #include <net/addrconf.h> | 39 | #include <net/addrconf.h> |
| @@ -1050,9 +1051,14 @@ static u32 hns_roce_v2_cmd_hw_resetting(struct hns_roce_dev *hr_dev, · 1011 unmodified lines | |||
| 1050 | unsigned long instance_stage, | 1051 | unsigned long instance_stage, |
| 1051 | unsigned long reset_stage) | 1052 | unsigned long reset_stage) |
| 1052 | { | 1053 | { |
| 1054 | #define HW_RESET_TIMEOUT_US 1000000 | ||
| 1055 | #define HW_RESET_SLEEP_US 1000 | ||
| 1056 | |||
| 1053 | struct hns_roce_v2_priv *priv = hr_dev->priv; | 1057 | struct hns_roce_v2_priv *priv = hr_dev->priv; |
| 1054 | struct hnae3_handle *handle = priv->handle; | 1058 | struct hnae3_handle *handle = priv->handle; |
| 1055 | const struct hnae3_ae_ops *ops = handle->ae_algo->ops; | 1059 | const struct hnae3_ae_ops *ops = handle->ae_algo->ops; |
| 1060 | unsigned long val; | ||
| 1061 | int ret; | ||
| 1056 | 1062 | ||
| 1057 | /* When hardware reset is detected, we should stop sending mailbox&cmq& | 1063 | /* When hardware reset is detected, we should stop sending mailbox&cmq& |
| 1058 | * doorbell to hardware. If now in .init_instance() function, we should | 1064 | * doorbell to hardware. If now in .init_instance() function, we should |
| @@ -1064,7 +1070,11 @@ static u32 hns_roce_v2_cmd_hw_resetting(struct hns_roce_dev *hr_dev, · 5 unmodified lines | |||
| 1064 | * again. | 1070 | * again. |
| 1065 | */ | 1071 | */ |
| 1066 | hr_dev->dis_db = true; | 1072 | hr_dev->dis_db = true; |
| 1067 | if (!ops->get_hw_reset_stat(handle)) | 1073 | |
| 1074 | ret = read_poll_timeout(ops->ae_dev_reset_cnt, val, | ||
| 1075 | val > hr_dev->reset_cnt, HW_RESET_SLEEP_US, | ||
| 1076 | HW_RESET_TIMEOUT_US, false, handle); | ||
| 1077 | if (!ret) | ||
| 1068 | hr_dev->is_reset = true; | 1078 | hr_dev->is_reset = true; |
| 1069 | 1079 | ||
| 1070 | if (!hr_dev->is_reset || reset_stage == HNS_ROCE_STATE_RST_INIT || | 1080 | if (!hr_dev->is_reset || reset_stage == HNS_ROCE_STATE_RST_INIT || |
| @@ -6387,10 +6397,8 @@ static int hns_roce_hw_v2_reset_notify_down(struct hnae3_handle *handle) · 5316 unmodified lines | |||
| 6387 | if (!hr_dev) | 6397 | if (!hr_dev) |
| 6388 | return 0; | 6398 | return 0; |
| 6389 | 6399 | ||
| 6390 | hr_dev->is_reset = true; | ||
| 6391 | hr_dev->active = false; | 6400 | hr_dev->active = false; |
| 6392 | hr_dev->dis_db = true; | 6401 | hr_dev->dis_db = true; |
| 6393 | |||
| 6394 | hr_dev->state = HNS_ROCE_DEVICE_STATE_RST_DOWN; | 6402 | hr_dev->state = HNS_ROCE_DEVICE_STATE_RST_DOWN; |
| 6395 | 6403 | ||
| 6396 | return 0; | 6404 | return 0; |
| @@ -60,6 +60,8 @@ static void irdma_iwarp_ce_handler(struct irdma_sc_cq *iwcq) · 59 unmodified lines | |||
| 60 | { | 60 | { |
| 61 | struct irdma_cq *cq = iwcq->back_cq; | 61 | struct irdma_cq *cq = iwcq->back_cq; |
| 62 | 62 | ||
| 63 | if (!cq->user_mode) | ||
| 64 | cq->armed = false; | ||
| 63 | if (cq->ibcq.comp_handler) | 65 | if (cq->ibcq.comp_handler) |
| 64 | cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); | 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 | qp->flush_code = FLUSH_PROT_ERR; | 148 | qp->flush_code = FLUSH_PROT_ERR; |
| 147 | break; | 149 | break; |
| 148 | case IRDMA_AE_AMP_BAD_QP: | 150 | case IRDMA_AE_AMP_BAD_QP: |
| 151 | case IRDMA_AE_WQE_UNEXPECTED_OPCODE: | ||
| 149 | qp->flush_code = FLUSH_LOC_QP_OP_ERR; | 152 | qp->flush_code = FLUSH_LOC_QP_OP_ERR; |
| 150 | break; | 153 | break; |
| 151 | case IRDMA_AE_AMP_BAD_STAG_KEY: | 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 | case IRDMA_AE_PRIV_OPERATION_DENIED: | 159 | case IRDMA_AE_PRIV_OPERATION_DENIED: |
| 157 | case IRDMA_AE_IB_INVALID_REQUEST: | 160 | case IRDMA_AE_IB_INVALID_REQUEST: |
| 158 | case IRDMA_AE_IB_REMOTE_ACCESS_ERROR: | 161 | case IRDMA_AE_IB_REMOTE_ACCESS_ERROR: |
| 159 | case IRDMA_AE_IB_REMOTE_OP_ERROR: | ||
| 160 | qp->flush_code = FLUSH_REM_ACCESS_ERR; | 162 | qp->flush_code = FLUSH_REM_ACCESS_ERR; |
| 161 | qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; | 163 | qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; |
| 162 | break; | 164 | break; |
| @@ -184,6 +186,9 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp, · 21 unmodified lines | |||
| 184 | case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS: | 186 | case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS: |
| 185 | qp->flush_code = FLUSH_MW_BIND_ERR; | 187 | qp->flush_code = FLUSH_MW_BIND_ERR; |
| 186 | break; | 188 | break; |
| 189 | case IRDMA_AE_IB_REMOTE_OP_ERROR: | ||
| 190 | qp->flush_code = FLUSH_REM_OP_ERR; | ||
| 191 | break; | ||
| 187 | default: | 192 | default: |
| 188 | qp->flush_code = FLUSH_FATAL_ERR; | 193 | qp->flush_code = FLUSH_FATAL_ERR; |
| 189 | break; | 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 | void (*callback_fcn)(struct irdma_cqp_request *cqp_request), | 542 | void (*callback_fcn)(struct irdma_cqp_request *cqp_request), |
| 543 | void *cb_param); | 543 | void *cb_param); |
| 544 | void irdma_gsi_ud_qp_ah_cb(struct irdma_cqp_request *cqp_request); | 544 | void irdma_gsi_ud_qp_ah_cb(struct irdma_cqp_request *cqp_request); |
| 545 | bool irdma_cq_empty(struct irdma_cq *iwcq); | ||
| 545 | int irdma_inetaddr_event(struct notifier_block *notifier, unsigned long event, | 546 | int irdma_inetaddr_event(struct notifier_block *notifier, unsigned long event, |
| 546 | void *ptr); | 547 | void *ptr); |
| 547 | int irdma_inet6addr_event(struct notifier_block *notifier, unsigned long event, | 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 | list_del(&chunk->list); | 25 | list_del(&chunk->list); |
| 26 | if (chunk->type == PBLE_SD_PAGED) | 26 | if (chunk->type == PBLE_SD_PAGED) |
| 27 | irdma_pble_free_paged_mem(chunk); | 27 | irdma_pble_free_paged_mem(chunk); |
| 28 | if (chunk->bitmapbuf) | 28 | bitmap_free(chunk->bitmapbuf); |
| 29 | kfree(chunk->bitmapmem.va); | ||
| 30 | kfree(chunk->chunkmem.va); | 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 | "PBLE: next_fpm_addr = %llx chunk_size[%llu] = 0x%llx\n", | 282 | "PBLE: next_fpm_addr = %llx chunk_size[%llu] = 0x%llx\n", |
| 284 | pble_rsrc->next_fpm_addr, chunk->size, chunk->size); | 283 | pble_rsrc->next_fpm_addr, chunk->size, chunk->size); |
| 285 | pble_rsrc->unallocated_pble -= (u32)(chunk->size >> 3); | 284 | pble_rsrc->unallocated_pble -= (u32)(chunk->size >> 3); |
| 286 | list_add(&chunk->list, &pble_rsrc->pinfo.clist); | ||
| 287 | sd_reg_val = (sd_entry_type == IRDMA_SD_TYPE_PAGED) ? | 285 | sd_reg_val = (sd_entry_type == IRDMA_SD_TYPE_PAGED) ? |
| 288 | sd_entry->u.pd_table.pd_page_addr.pa : | 286 | sd_entry->u.pd_table.pd_page_addr.pa : |
| 289 | sd_entry->u.bp.addr.pa; | 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 | goto error; | 293 | goto error; |
| 296 | } | 294 | } |
| 297 | 295 | ||
| 296 | list_add(&chunk->list, &pble_rsrc->pinfo.clist); | ||
| 298 | sd_entry->valid = true; | 297 | sd_entry->valid = true; |
| 299 | return 0; | 298 | return 0; |
| 300 | 299 | ||
| 301 | error: | 300 | error: |
| 302 | if (chunk->bitmapbuf) | 301 | bitmap_free(chunk->bitmapbuf); |
| 303 | kfree(chunk->bitmapmem.va); | ||
| 304 | kfree(chunk->chunkmem.va); | 302 | kfree(chunk->chunkmem.va); |
| 305 | 303 | ||
| 306 | return ret_code; | 304 | return ret_code; |
| @@ -78,7 +78,6 @@ struct irdma_chunk { · 77 unmodified lines | |||
| 78 | u32 pg_cnt; | 78 | u32 pg_cnt; |
| 79 | enum irdma_alloc_type type; | 79 | enum irdma_alloc_type type; |
| 80 | struct irdma_sc_dev *dev; | 80 | struct irdma_sc_dev *dev; |
| 81 | struct irdma_virt_mem bitmapmem; | ||
| 82 | struct irdma_virt_mem chunkmem; | 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 | sizeofbitmap = (u64)pchunk->size >> pprm->pble_shift; | 2240 | sizeofbitmap = (u64)pchunk->size >> pprm->pble_shift; |
| 2241 | 2241 | ||
| 2242 | pchunk->bitmapmem.size = sizeofbitmap >> 3; | 2242 | pchunk->bitmapbuf = bitmap_zalloc(sizeofbitmap, GFP_KERNEL); |
| 2243 | pchunk->bitmapmem.va = kzalloc(pchunk->bitmapmem.size, GFP_KERNEL); | 2243 | if (!pchunk->bitmapbuf) |
| 2244 | |||
| 2245 | if (!pchunk->bitmapmem.va) | ||
| 2246 | return IRDMA_ERR_NO_MEMORY; | 2244 | return IRDMA_ERR_NO_MEMORY; |
| 2247 | 2245 | ||
| 2248 | pchunk->bitmapbuf = pchunk->bitmapmem.va; | ||
| 2249 | bitmap_zero(pchunk->bitmapbuf, sizeofbitmap); | ||
| 2250 | |||
| 2251 | pchunk->sizeofbitmap = sizeofbitmap; | 2246 | pchunk->sizeofbitmap = sizeofbitmap; |
| 2252 | /* each pble is 8 bytes hence shift by 3 */ | 2247 | /* each pble is 8 bytes hence shift by 3 */ |
| 2253 | pprm->total_pble_alloc += pchunk->size >> 3; | 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 | ibevent.element.qp = &iwqp->ibqp; | 2486 | ibevent.element.qp = &iwqp->ibqp; |
| 2492 | iwqp->ibqp.event_handler(&ibevent, iwqp->ibqp.qp_context); | 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 | } | ||
| @@ -3584,18 +3584,31 @@ static int irdma_req_notify_cq(struct ib_cq *ibcq, · 3583 unmodified lines | |||
| 3584 | struct irdma_cq *iwcq; | 3584 | struct irdma_cq *iwcq; |
| 3585 | struct irdma_cq_uk *ukcq; | 3585 | struct irdma_cq_uk *ukcq; |
| 3586 | unsigned long flags; | 3586 | unsigned long flags; |
| 3587 | enum irdma_cmpl_notify cq_notify = IRDMA_CQ_COMPL_EVENT; | 3587 | enum irdma_cmpl_notify cq_notify; |
| 3588 | bool promo_event = false; | ||
| 3589 | int ret = 0; | ||
| 3588 | 3590 | ||
| 3591 | cq_notify = notify_flags == IB_CQ_SOLICITED ? | ||
| 3592 | IRDMA_CQ_COMPL_SOLICITED : IRDMA_CQ_COMPL_EVENT; | ||
| 3589 | iwcq = to_iwcq(ibcq); | 3593 | iwcq = to_iwcq(ibcq); |
| 3590 | ukcq = &iwcq->sc_cq.cq_uk; | 3594 | ukcq = &iwcq->sc_cq.cq_uk; |
| 3591 | if (notify_flags == IB_CQ_SOLICITED) | ||
| 3592 | cq_notify = IRDMA_CQ_COMPL_SOLICITED; | ||
| 3593 | 3595 | ||
| 3594 | spin_lock_irqsave(&iwcq->lock, flags); | 3596 | spin_lock_irqsave(&iwcq->lock, flags); |
| 3595 | irdma_uk_cq_request_notification(ukcq, cq_notify); | 3597 | /* Only promote to arm the CQ for any event if the last arm event was solicited. */ |
| 3598 | if (iwcq->last_notify == IRDMA_CQ_COMPL_SOLICITED && notify_flags != IB_CQ_SOLICITED) | ||
| 3599 | promo_event = true; | ||
| 3600 | |||
| 3601 | if (!iwcq->armed || promo_event) { | ||
| 3602 | iwcq->armed = true; | ||
| 3603 | iwcq->last_notify = cq_notify; | ||
| 3604 | irdma_uk_cq_request_notification(ukcq, cq_notify); | ||
| 3605 | } | ||
| 3606 | |||
| 3607 | if ((notify_flags & IB_CQ_REPORT_MISSED_EVENTS) && !irdma_cq_empty(iwcq)) | ||
| 3608 | ret = 1; | ||
| 3596 | spin_unlock_irqrestore(&iwcq->lock, flags); | 3609 | spin_unlock_irqrestore(&iwcq->lock, flags); |
| 3597 | 3610 | ||
| 3598 | return 0; | 3611 | return ret; |
| 3599 | } | 3612 | } |
| 3600 | 3613 | ||
| 3601 | static int irdma_roce_port_immutable(struct ib_device *ibdev, u32 port_num, | 3614 | static int irdma_roce_port_immutable(struct ib_device *ibdev, u32 port_num, |
| @@ -110,6 +110,8 @@ struct irdma_cq { · 109 unmodified lines | |||
| 110 | u16 cq_size; | 110 | u16 cq_size; |
| 111 | u16 cq_num; | 111 | u16 cq_num; |
| 112 | bool user_mode; | 112 | bool user_mode; |
| 113 | bool armed; | ||
| 114 | enum irdma_cmpl_notify last_notify; | ||
| 113 | u32 polled_cmpls; | 115 | u32 polled_cmpls; |
| 114 | u32 cq_mem_size; | 116 | u32 cq_mem_size; |
| 115 | struct irdma_dma_mem kmem; | 117 | struct irdma_dma_mem kmem; |
| @@ -664,7 +664,6 @@ struct mlx5_ib_mr { · 663 unmodified lines | |||
| 664 | 664 | ||
| 665 | /* User MR data */ | 665 | /* User MR data */ |
| 666 | struct mlx5_cache_ent *cache_ent; | 666 | struct mlx5_cache_ent *cache_ent; |
| 667 | struct ib_umem *umem; | ||
| 668 | 667 | ||
| 669 | /* This is zero'd when the MR is allocated */ | 668 | /* This is zero'd when the MR is allocated */ |
| 670 | union { | 669 | union { |
| @@ -676,7 +675,7 @@ struct mlx5_ib_mr { · 5 unmodified lines | |||
| 676 | struct list_head list; | 675 | struct list_head list; |
| 677 | }; | 676 | }; |
| 678 | 677 | ||
| 679 | /* Used only by kernel MRs (umem == NULL) */ | 678 | /* Used only by kernel MRs */ |
| 680 | struct { | 679 | struct { |
| 681 | void *descs; | 680 | void *descs; |
| 682 | void *descs_alloc; | 681 | void *descs_alloc; |
| @@ -697,8 +696,9 @@ struct mlx5_ib_mr { · 14 unmodified lines | |||
| 697 | int data_length; | 696 | int data_length; |
| 698 | }; | 697 | }; |
| 699 | 698 | ||
| 700 | /* Used only by User MRs (umem != NULL) */ | 699 | /* Used only by User MRs */ |
| 701 | struct { | 700 | struct { |
| 701 | struct ib_umem *umem; | ||
| 702 | unsigned int page_shift; | 702 | unsigned int page_shift; |
| 703 | /* Current access_flags */ | 703 | /* Current access_flags */ |
| 704 | int access_flags; | 704 | int access_flags; |
| @@ -1904,19 +1904,18 @@ err: · 1903 unmodified lines | |||
| 1904 | return ret; | 1904 | return ret; |
| 1905 | } | 1905 | } |
| 1906 | 1906 | ||
| 1907 | static void | 1907 | static void mlx5_free_priv_descs(struct mlx5_ib_mr *mr) |
| 1908 | mlx5_free_priv_descs(struct mlx5_ib_mr *mr) | ||
| 1909 | { | 1908 | { |
| 1910 | if (!mr->umem && mr->descs) { | 1909 | struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device); |
| 1911 | struct ib_device *device = mr->ibmr.device; | 1910 | int size = mr->max_descs * mr->desc_size; |
| 1912 | int size = mr->max_descs * mr->desc_size; | ||
| 1913 | struct mlx5_ib_dev *dev = to_mdev(device); | ||
| 1914 | 1911 | ||
| 1915 | dma_unmap_single(&dev->mdev->pdev->dev, mr->desc_map, size, | 1912 | if (!mr->descs) |
| 1916 | DMA_TO_DEVICE); | 1913 | return; |
| 1917 | kfree(mr->descs_alloc); | 1914 | |
| 1918 | mr->descs = NULL; | 1915 | dma_unmap_single(&dev->mdev->pdev->dev, mr->desc_map, size, |
| 1919 | } | 1916 | DMA_TO_DEVICE); |
| 1917 | kfree(mr->descs_alloc); | ||
| 1918 | mr->descs = NULL; | ||
| 1920 | } | 1919 | } |
| 1921 | 1920 | ||
| 1922 | int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) | 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 | if (mr->cache_ent) { | 1991 | if (mr->cache_ent) { |
| 1993 | mlx5_mr_cache_free(dev, mr); | 1992 | mlx5_mr_cache_free(dev, mr); |
| 1994 | } else { | 1993 | } else { |
| 1995 | mlx5_free_priv_descs(mr); | 1994 | if (!udata) |
| 1995 | mlx5_free_priv_descs(mr); | ||
| 1996 | kfree(mr); | 1996 | kfree(mr); |
| 1997 | } | 1997 | } |
| 1998 | return 0; | 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 | if (err) | 2079 | if (err) |
| 2080 | goto err_free_in; | 2080 | goto err_free_in; |
| 2081 | 2081 | ||
| 2082 | mr->umem = NULL; | ||
| 2083 | kfree(in); | 2082 | kfree(in); |
| 2084 | 2083 | ||
| 2085 | return mr; | 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 | mr->ibmr.device = pd->device; | 2207 | mr->ibmr.device = pd->device; |
| 2209 | mr->umem = NULL; | ||
| 2210 | 2208 | ||
| 2211 | switch (mr_type) { | 2209 | switch (mr_type) { |
| 2212 | case IB_MR_TYPE_MEM_REG: | 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 | err2: | 360 | err2: |
| 361 | rxe_queue_cleanup(qp->sq.queue); | 361 | rxe_queue_cleanup(qp->sq.queue); |
| 362 | qp->sq.queue = NULL; | ||
| 362 | err1: | 363 | err1: |
| 363 | qp->pd = NULL; | 364 | qp->pd = NULL; |
| 364 | qp->rcq = NULL; | 365 | qp->rcq = NULL; |
| @@ -19,7 +19,7 @@ void rtrs_clt_update_wc_stats(struct rtrs_clt_con *con) · 18 unmodified lines | |||
| 19 | int cpu; | 19 | int cpu; |
| 20 | 20 | ||
| 21 | cpu = raw_smp_processor_id(); | 21 | cpu = raw_smp_processor_id(); |
| 22 | s = this_cpu_ptr(stats->pcpu_stats); | 22 | s = get_cpu_ptr(stats->pcpu_stats); |
| 23 | if (con->cpu != cpu) { | 23 | if (con->cpu != cpu) { |
| 24 | s->cpu_migr.to++; | 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 | s = per_cpu_ptr(stats->pcpu_stats, con->cpu); | 27 | s = per_cpu_ptr(stats->pcpu_stats, con->cpu); |
| 28 | atomic_inc(&s->cpu_migr.from); | 28 | atomic_inc(&s->cpu_migr.from); |
| 29 | } | 29 | } |
| 30 | put_cpu_ptr(stats->pcpu_stats); | ||
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | void rtrs_clt_inc_failover_cnt(struct rtrs_clt_stats *stats) | 33 | void rtrs_clt_inc_failover_cnt(struct rtrs_clt_stats *stats) |
| 33 | { | 34 | { |
| 34 | struct rtrs_clt_stats_pcpu *s; | 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 | s->rdma.failover_cnt++; | 38 | s->rdma.failover_cnt++; |
| 39 | put_cpu_ptr(stats->pcpu_stats); | ||
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | int rtrs_clt_stats_migration_from_cnt_to_str(struct rtrs_clt_stats *stats, char *buf) | 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 | struct rtrs_clt_stats_pcpu *s; | 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 | s->rdma.dir[d].cnt++; | 175 | s->rdma.dir[d].cnt++; |
| 174 | s->rdma.dir[d].size_total += size; | 176 | s->rdma.dir[d].size_total += size; |
| 177 | put_cpu_ptr(stats->pcpu_stats); | ||
| 175 | } | 178 | } |
| 176 | 179 | ||
| 177 | void rtrs_clt_update_all_stats(struct rtrs_clt_io_req *req, int dir) | 180 | void rtrs_clt_update_all_stats(struct rtrs_clt_io_req *req, int dir) |
| @@ -707,7 +707,7 @@ static const struct irq_domain_ops aic_ipi_domain_ops = { · 706 unmodified lines | |||
| 707 | .free = aic_ipi_free, | 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 | struct irq_domain *ipi_domain; | 712 | struct irq_domain *ipi_domain; |
| 713 | int base_ipi; | 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 | int hwirq, i; | 232 | int hwirq, i; |
| 233 | 233 | ||
| 234 | mutex_lock(&msi_used_lock); | 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, | 239 | if (hwirq < 0) |
| 237 | 0, nr_irqs, 0); | ||
| 238 | if (hwirq >= PCI_MSI_DOORBELL_NR) { | ||
| 239 | mutex_unlock(&msi_used_lock); | ||
| 240 | return -ENOSPC; | 240 | return -ENOSPC; |
| 241 | } | ||
| 242 | |||
| 243 | bitmap_set(msi_used, hwirq, nr_irqs); | ||
| 244 | mutex_unlock(&msi_used_lock); | ||
| 245 | 241 | ||
| 246 | for (i = 0; i < nr_irqs; i++) { | 242 | for (i = 0; i < nr_irqs; i++) { |
| 247 | irq_domain_set_info(domain, virq + i, hwirq + i, | 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 | NULL, NULL); | 246 | NULL, NULL); |
| 251 | } | 247 | } |
| 252 | 248 | ||
| 253 | return hwirq; | 249 | return 0; |
| 254 | } | 250 | } |
| 255 | 251 | ||
| 256 | static void armada_370_xp_msi_free(struct irq_domain *domain, | 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 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); | 255 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); |
| 260 | 256 | ||
| 261 | mutex_lock(&msi_used_lock); | 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 | mutex_unlock(&msi_used_lock); | 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 | generic_handle_domain_irq(scu_ic->irq_domain, | 76 | generic_handle_domain_irq(scu_ic->irq_domain, |
| 77 | bit - scu_ic->irq_shift); | 77 | bit - scu_ic->irq_shift); |
| 78 | 78 | ||
| 79 | regmap_update_bits(scu_ic->scu, scu_ic->reg, mask, | 79 | regmap_write_bits(scu_ic->scu, scu_ic->reg, mask, |
| 80 | BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT)); | 80 | BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT)); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | chained_irq_exit(chip, desc); | 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 | data->num_parent_irqs = platform_irq_count(pdev); | 240 | data->num_parent_irqs = platform_irq_count(pdev); |
| 241 | put_device(&pdev->dev); | ||
| 241 | if (data->num_parent_irqs <= 0) { | 242 | if (data->num_parent_irqs <= 0) { |
| 242 | pr_err("invalid number of parent interrupts\n"); | 243 | pr_err("invalid number of parent interrupts\n"); |
| 243 | ret = -ENOMEM; | 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 | its_fixup_cmd(cmd); | 743 | its_fixup_cmd(cmd); |
| 744 | 744 | ||
| 745 | return NULL; | 745 | return desc->its_invall_cmd.col; |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 748 | static struct its_vpe *its_build_vinvall_cmd(struct its_node *its, | 748 | static struct its_vpe *its_build_vinvall_cmd(struct its_node *its, |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #define pr_fmt(fmt) "irq-mips-gic: " fmt | 10 | #define pr_fmt(fmt) "irq-mips-gic: " fmt |
| 11 | 11 | ||
| 12 | #include <linux/bitfield.h> | ||
| 12 | #include <linux/bitmap.h> | 13 | #include <linux/bitmap.h> |
| 13 | #include <linux/clocksource.h> | 14 | #include <linux/clocksource.h> |
| 14 | #include <linux/cpuhotplug.h> | 15 | #include <linux/cpuhotplug.h> |
| @@ -735,8 +736,7 @@ static int __init gic_of_init(struct device_node *node, · 720 unmodified lines | |||
| 735 | mips_gic_base = ioremap(gic_base, gic_len); | 736 | mips_gic_base = ioremap(gic_base, gic_len); |
| 736 | 737 | ||
| 737 | gicconfig = read_gic_config(); | 738 | gicconfig = read_gic_config(); |
| 738 | gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; | 739 | gic_shared_intrs = FIELD_GET(GIC_CONFIG_NUMINTERRUPTS, gicconfig); |
| 739 | gic_shared_intrs >>= __ffs(GIC_CONFIG_NUMINTERRUPTS); | ||
| 740 | gic_shared_intrs = (gic_shared_intrs + 1) * 8; | 740 | gic_shared_intrs = (gic_shared_intrs + 1) * 8; |
| 741 | 741 | ||
| 742 | if (cpu_has_veic) { | 742 | if (cpu_has_veic) { |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | #define NVIC_ISER 0x000 | 27 | #define NVIC_ISER 0x000 |
| 28 | #define NVIC_ICER 0x080 | 28 | #define NVIC_ICER 0x080 |
| 29 | #define NVIC_IPR 0x300 | 29 | #define NVIC_IPR 0x400 |
| 30 | 30 | ||
| 31 | #define NVIC_MAX_BANKS 16 | 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 | if (!num_sectors || num_sectors > max_sectors) | 2190 | if (!num_sectors || num_sectors > max_sectors) |
| 2191 | num_sectors = max_sectors; | 2191 | num_sectors = max_sectors; |
| 2192 | rdev->sb_start = sb_start; | ||
| 2192 | } | 2193 | } |
| 2193 | sb = page_address(rdev->sb_page); | 2194 | sb = page_address(rdev->sb_page); |
| 2194 | sb->data_size = cpu_to_le64(num_sectors); | 2195 | sb->data_size = cpu_to_le64(num_sectors); |
| @@ -6270,7 +6271,8 @@ static void __md_stop(struct mddev *mddev) · 4075 unmodified lines | |||
| 6270 | spin_lock(&mddev->lock); | 6271 | spin_lock(&mddev->lock); |
| 6271 | mddev->pers = NULL; | 6272 | mddev->pers = NULL; |
| 6272 | spin_unlock(&mddev->lock); | 6273 | spin_unlock(&mddev->lock); |
| 6273 | pers->free(mddev, mddev->private); | 6274 | if (mddev->private) |
| 6275 | pers->free(mddev, mddev->private); | ||
| 6274 | mddev->private = NULL; | 6276 | mddev->private = NULL; |
| 6275 | if (pers->sync_request && mddev->to_remove == NULL) | 6277 | if (pers->sync_request && mddev->to_remove == NULL) |
| 6276 | mddev->to_remove = &md_redundancy_group; | 6278 | mddev->to_remove = &md_redundancy_group; |
| @@ -1803,8 +1803,6 @@ static int rtsx_pci_runtime_suspend(struct device *device) · 1802 unmodified lines | |||
| 1803 | mutex_lock(&pcr->pcr_mutex); | 1803 | mutex_lock(&pcr->pcr_mutex); |
| 1804 | rtsx_pci_power_off(pcr, HOST_ENTER_S3); | 1804 | rtsx_pci_power_off(pcr, HOST_ENTER_S3); |
| 1805 | 1805 | ||
| 1806 | free_irq(pcr->irq, (void *)pcr); | ||
| 1807 | |||
| 1808 | mutex_unlock(&pcr->pcr_mutex); | 1806 | mutex_unlock(&pcr->pcr_mutex); |
| 1809 | 1807 | ||
| 1810 | pcr->is_runtime_suspended = true; | 1808 | pcr->is_runtime_suspended = true; |
| @@ -1825,8 +1823,6 @@ static int rtsx_pci_runtime_resume(struct device *device) · 14 unmodified lines | |||
| 1825 | mutex_lock(&pcr->pcr_mutex); | 1823 | mutex_lock(&pcr->pcr_mutex); |
| 1826 | 1824 | ||
| 1827 | rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x00); | 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 | if (pcr->ops->fetch_vendor_settings) | 1827 | if (pcr->ops->fetch_vendor_settings) |
| 1832 | pcr->ops->fetch_vendor_settings(pcr); | 1828 | pcr->ops->fetch_vendor_settings(pcr); |
| @@ -440,10 +440,6 @@ static int at25_probe(struct spi_device *spi) · 439 unmodified lines | |||
| 440 | return -ENXIO; | 440 | return -ENXIO; |
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL); | ||
| 444 | if (!at25) | ||
| 445 | return -ENOMEM; | ||
| 446 | |||
| 447 | mutex_init(&at25->lock); | 443 | mutex_init(&at25->lock); |
| 448 | at25->spi = spi; | 444 | at25->spi = spi; |
| 449 | spi_set_drvdata(spi, at25); | 445 | spi_set_drvdata(spi, at25); |
| @@ -493,7 +489,8 @@ static int at25_probe(struct spi_device *spi) · 43 unmodified lines | |||
| 493 | return PTR_ERR(at25->nvmem); | 489 | return PTR_ERR(at25->nvmem); |
| 494 | 490 | ||
| 495 | dev_info(&spi->dev, "%d %s %s %s%s, pagesize %u\n", | 491 | dev_info(&spi->dev, "%d %s %s %s%s, pagesize %u\n", |
| 496 | (at25->chip.byte_len < 1024) ? at25->chip.byte_len : (at25->chip.byte_len / 1024), | 492 | (at25->chip.byte_len < 1024) ? |
| 493 | at25->chip.byte_len : (at25->chip.byte_len / 1024), | ||
| 497 | (at25->chip.byte_len < 1024) ? "Byte" : "KByte", | 494 | (at25->chip.byte_len < 1024) ? "Byte" : "KByte", |
| 498 | at25->chip.name, is_fram ? "fram" : "eeprom", | 495 | at25->chip.name, is_fram ? "fram" : "eeprom", |
| 499 | (at25->chip.flags & EE_READONLY) ? " (readonly)" : "", | 496 | (at25->chip.flags & EE_READONLY) ? " (readonly)" : "", |
| @@ -719,16 +719,18 @@ static int fastrpc_get_meta_size(struct fastrpc_invoke_ctx *ctx) · 718 unmodified lines | |||
| 719 | static u64 fastrpc_get_payload_size(struct fastrpc_invoke_ctx *ctx, int metalen) | 719 | static u64 fastrpc_get_payload_size(struct fastrpc_invoke_ctx *ctx, int metalen) |
| 720 | { | 720 | { |
| 721 | u64 size = 0; | 721 | u64 size = 0; |
| 722 | int i; | 722 | int oix; |
| 723 | 723 | ||
| 724 | size = ALIGN(metalen, FASTRPC_ALIGN); | 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 | if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1) { | 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 | size = ALIGN(size, FASTRPC_ALIGN); | 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 | ||
| @@ -2291,8 +2291,10 @@ static int msdc_execute_hs400_tuning(struct mmc_host *mmc, struct mmc_card *card · 2290 unmodified lines | |||
| 2291 | sdr_set_field(host->base + PAD_DS_TUNE, | 2291 | sdr_set_field(host->base + PAD_DS_TUNE, |
| 2292 | PAD_DS_TUNE_DLY1, i); | 2292 | PAD_DS_TUNE_DLY1, i); |
| 2293 | ret = mmc_get_ext_csd(card, &ext_csd); | 2293 | ret = mmc_get_ext_csd(card, &ext_csd); |
| 2294 | if (!ret) | 2294 | if (!ret) { |
| 2295 | result_dly1 |= (1 << i); | 2295 | result_dly1 |= (1 << i); |
| 2296 | kfree(ext_csd); | ||
| 2297 | } | ||
| 2296 | } | 2298 | } |
| 2297 | host->hs400_tuning = false; | 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 | /* Issue CMD19 twice for each tap */ | 674 | /* Issue CMD19 twice for each tap */ |
| 675 | for (i = 0; i < 2 * priv->tap_num; i++) { | 675 | for (i = 0; i < 2 * priv->tap_num; i++) { |
| 676 | int cmd_error; | 676 | int cmd_error = 0; |
| 677 | 677 | ||
| 678 | /* Set sampling clock position */ | 678 | /* Set sampling clock position */ |
| 679 | sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, i % priv->tap_num); | 679 | sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, i % priv->tap_num); |
| @@ -96,6 +96,13 @@ struct dataflash { · 95 unmodified lines | |||
| 96 | struct mtd_info mtd; | 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 | #ifdef CONFIG_OF | 106 | #ifdef CONFIG_OF |
| 100 | static const struct of_device_id dataflash_dt_ids[] = { | 107 | static const struct of_device_id dataflash_dt_ids[] = { |
| 101 | { .compatible = "atmel,at45", }, | 108 | { .compatible = "atmel,at45", }, |
| @@ -927,6 +934,7 @@ static struct spi_driver dataflash_driver = { · 825 unmodified lines | |||
| 927 | .name = "mtd_dataflash", | 934 | .name = "mtd_dataflash", |
| 928 | .of_match_table = of_match_ptr(dataflash_dt_ids), | 935 | .of_match_table = of_match_ptr(dataflash_dt_ids), |
| 929 | }, | 936 | }, |
| 937 | .id_table = dataflash_dev_ids, | ||
| 930 | 938 | ||
| 931 | .probe = dataflash_probe, | 939 | .probe = dataflash_probe, |
| 932 | .remove = dataflash_remove, | 940 | .remove = dataflash_remove, |
| @@ -26,7 +26,7 @@ config MTD_NAND_DENALI_PCI · 25 unmodified lines | |||
| 26 | config MTD_NAND_DENALI_DT | 26 | config MTD_NAND_DENALI_DT |
| 27 | tristate "Denali NAND controller as a DT device" | 27 | tristate "Denali NAND controller as a DT device" |
| 28 | select MTD_NAND_DENALI | 28 | select MTD_NAND_DENALI |
| 29 | depends on HAS_DMA && HAVE_CLK && OF | 29 | depends on HAS_DMA && HAVE_CLK && OF && HAS_IOMEM |
| 30 | help | 30 | help |
| 31 | Enable the driver for NAND flash on platforms using a Denali NAND | 31 | Enable the driver for NAND flash on platforms using a Denali NAND |
| 32 | controller as a DT device. | 32 | controller as a DT device. |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
| 17 | #include <linux/completion.h> | 17 | #include <linux/completion.h> |
| 18 | #include <linux/delay.h> | ||
| 18 | #include <linux/dmaengine.h> | 19 | #include <linux/dmaengine.h> |
| 19 | #include <linux/dma-direction.h> | 20 | #include <linux/dma-direction.h> |
| 20 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
| @@ -93,6 +94,14 @@ · 72 unmodified lines | |||
| 93 | 94 | ||
| 94 | #define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ) | 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 | struct fsmc_nand_timings { | 105 | struct fsmc_nand_timings { |
| 97 | u8 tclr; | 106 | u8 tclr; |
| 98 | u8 tar; | 107 | u8 tar; |
| @@ -277,7 +286,7 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host, · 178 unmodified lines | |||
| 277 | { | 286 | { |
| 278 | unsigned long hclk = clk_get_rate(host->clk); | 287 | unsigned long hclk = clk_get_rate(host->clk); |
| 279 | unsigned long hclkn = NSEC_PER_SEC / hclk; | 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 | if (sdrt->tRC_min < 30000) | 291 | if (sdrt->tRC_min < 30000) |
| 283 | return -EOPNOTSUPP; | 292 | return -EOPNOTSUPP; |
| @@ -309,13 +318,6 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host, · 25 unmodified lines | |||
| 309 | else if (tims->thold > FSMC_THOLD_MASK) | 318 | else if (tims->thold > FSMC_THOLD_MASK) |
| 310 | tims->thold = FSMC_THOLD_MASK; | 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 | tset = max(sdrt->tCS_min - sdrt->tWP_min, | 321 | tset = max(sdrt->tCS_min - sdrt->tWP_min, |
| 320 | sdrt->tCEA_max - sdrt->tREA_max); | 322 | sdrt->tCEA_max - sdrt->tREA_max); |
| 321 | tims->tset = DIV_ROUND_UP(tset / 1000, hclkn) - 1; | 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 | else if (tims->tset > FSMC_TSET_MASK) | 326 | else if (tims->tset > FSMC_TSET_MASK) |
| 325 | tims->tset = FSMC_TSET_MASK; | 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 | return 0; | 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 | instr->ctx.waitrdy.timeout_ms); | 681 | instr->ctx.waitrdy.timeout_ms); |
| 665 | break; | 682 | break; |
| 666 | } | 683 | } |
| 684 | |||
| 685 | if (instr->delay_ns) | ||
| 686 | ndelay(instr->delay_ns); | ||
| 667 | } | 687 | } |
| 668 | 688 | ||
| 669 | return ret; | 689 | return ret; |
| @@ -926,7 +926,7 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip, · 925 unmodified lines | |||
| 926 | struct nand_sdr_timings *spec_timings) | 926 | struct nand_sdr_timings *spec_timings) |
| 927 | { | 927 | { |
| 928 | const struct nand_controller_ops *ops = chip->controller->ops; | 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 | iface->type = NAND_SDR_IFACE; | 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 | struct nand_nvddr_timings *spec_timings) | 977 | struct nand_nvddr_timings *spec_timings) |
| 978 | { | 978 | { |
| 979 | const struct nand_controller_ops *ops = chip->controller->ops; | 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 | iface->type = NAND_NVDDR_IFACE; | 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 | NAND_OP_CMD(NAND_CMD_ERASE1, 0), | 1837 | NAND_OP_CMD(NAND_CMD_ERASE1, 0), |
| 1838 | NAND_OP_ADDR(2, addrs, 0), | 1838 | NAND_OP_ADDR(2, addrs, 0), |
| 1839 | NAND_OP_CMD(NAND_CMD_ERASE2, | 1839 | NAND_OP_CMD(NAND_CMD_ERASE2, |
| 1840 | NAND_COMMON_TIMING_MS(conf, tWB_max)), | 1840 | NAND_COMMON_TIMING_NS(conf, tWB_max)), |
| 1841 | NAND_OP_WAIT_RDY(NAND_COMMON_TIMING_MS(conf, tBERS_max), | 1841 | NAND_OP_WAIT_RDY(NAND_COMMON_TIMING_MS(conf, tBERS_max), |
| 1842 | 0), | 1842 | 0), |
| 1843 | }; | 1843 | }; |
| @@ -1501,14 +1501,14 @@ void bond_alb_monitor(struct work_struct *work) · 1500 unmodified lines | |||
| 1501 | struct slave *slave; | 1501 | struct slave *slave; |
| 1502 | 1502 | ||
| 1503 | if (!bond_has_slaves(bond)) { | 1503 | if (!bond_has_slaves(bond)) { |
| 1504 | bond_info->tx_rebalance_counter = 0; | 1504 | atomic_set(&bond_info->tx_rebalance_counter, 0); |
| 1505 | bond_info->lp_counter = 0; | 1505 | bond_info->lp_counter = 0; |
| 1506 | goto re_arm; | 1506 | goto re_arm; |
| 1507 | } | 1507 | } |
| 1508 | 1508 | ||
| 1509 | rcu_read_lock(); | 1509 | rcu_read_lock(); |
| 1510 | 1510 | ||
| 1511 | bond_info->tx_rebalance_counter++; | 1511 | atomic_inc(&bond_info->tx_rebalance_counter); |
| 1512 | bond_info->lp_counter++; | 1512 | bond_info->lp_counter++; |
| 1513 | 1513 | ||
| 1514 | /* send learning packets */ | 1514 | /* send learning packets */ |
| @@ -1530,7 +1530,7 @@ void bond_alb_monitor(struct work_struct *work) · 15 unmodified lines | |||
| 1530 | } | 1530 | } |
| 1531 | 1531 | ||
| 1532 | /* rebalance tx traffic */ | 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 | bond_for_each_slave_rcu(bond, slave, iter) { | 1534 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 1535 | tlb_clear_slave(bond, slave, 1); | 1535 | tlb_clear_slave(bond, slave, 1); |
| 1536 | if (slave == rcu_access_pointer(bond->curr_active_slave)) { | 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 | bond_info->unbalanced_load = 0; | 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 | if (bond_info->rlb_enabled) { | 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 | tlb_init_slave(slave); | 1610 | tlb_init_slave(slave); |
| 1611 | 1611 | ||
| 1612 | /* order a rebalance ASAP */ | 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 | if (bond->alb_info.rlb_enabled) | 1616 | if (bond->alb_info.rlb_enabled) |
| 1616 | bond->alb_info.rlb_rebalance = 1; | 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 | rlb_clear_slave(bond, slave); | 1648 | rlb_clear_slave(bond, slave); |
| 1648 | } else if (link == BOND_LINK_UP) { | 1649 | } else if (link == BOND_LINK_UP) { |
| 1649 | /* order a rebalance ASAP */ | 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 | if (bond->alb_info.rlb_enabled) { | 1653 | if (bond->alb_info.rlb_enabled) { |
| 1652 | bond->alb_info.rlb_rebalance = 1; | 1654 | bond->alb_info.rlb_rebalance = 1; |
| 1653 | /* If the updelay module parameter is smaller than the | 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 | #define KVASER_PCIEFD_SPACK_EWLR BIT(23) | 248 | #define KVASER_PCIEFD_SPACK_EWLR BIT(23) |
| 249 | #define KVASER_PCIEFD_SPACK_EPLR BIT(24) | 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 | struct kvaser_pciefd; | 254 | struct kvaser_pciefd; |
| 252 | 255 | ||
| 253 | struct kvaser_pciefd_can { | 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 | can->err_rep_cnt++; | 1289 | can->err_rep_cnt++; |
| 1287 | can->can.can_stats.bus_error++; | 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 | can->bec.txerr = bec.txerr; | 1296 | can->bec.txerr = bec.txerr; |
| 1291 | can->bec.rxerr = bec.rxerr; | 1297 | can->bec.rxerr = bec.rxerr; |
| @@ -204,16 +204,16 @@ enum m_can_reg { · 203 unmodified lines | |||
| 204 | 204 | ||
| 205 | /* Interrupts for version 3.0.x */ | 205 | /* Interrupts for version 3.0.x */ |
| 206 | #define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE) | 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 | \ | 207 | #define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_BEU | IR_BEC | \ |
| 208 | IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ | 208 | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \ |
| 209 | IR_RF1L | IR_RF0L) | 209 | IR_RF0L) |
| 210 | #define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X) | 210 | #define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X) |
| 211 | 211 | ||
| 212 | /* Interrupts for version >= 3.1.x */ | 212 | /* Interrupts for version >= 3.1.x */ |
| 213 | #define IR_ERR_LEC_31X (IR_PED | IR_PEA) | 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 | \ | 214 | #define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_BEU | IR_BEC | \ |
| 215 | IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ | 215 | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \ |
| 216 | IR_RF1L | IR_RF0L) | 216 | IR_RF0L) |
| 217 | #define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X) | 217 | #define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X) |
| 218 | 218 | ||
| 219 | /* Interrupt Line Select (ILS) */ | 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 | err = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_DATA, | 517 | err = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_DATA, |
| 518 | cf->data, DIV_ROUND_UP(cf->len, 4)); | 518 | cf->data, DIV_ROUND_UP(cf->len, 4)); |
| 519 | if (err) | 519 | if (err) |
| 520 | goto out_fail; | 520 | goto out_free_skb; |
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | /* acknowledge rx fifo 0 */ | 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 | return 0; | 533 | return 0; |
| 534 | 534 | ||
| 535 | out_free_skb: | ||
| 536 | kfree_skb(skb); | ||
| 535 | out_fail: | 537 | out_fail: |
| 536 | netdev_err(dev, "FIFO read returned %d\n", err); | 538 | netdev_err(dev, "FIFO read returned %d\n", err); |
| 537 | return err; | 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 | if (irqstatus & IR_WDI) | 813 | if (irqstatus & IR_WDI) |
| 812 | netdev_err(dev, "Message RAM Watchdog event due to missing READY\n"); | 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 | if (irqstatus & IR_BEU) | 815 | if (irqstatus & IR_BEU) |
| 816 | netdev_err(dev, "Bit Error Uncorrected\n"); | 816 | netdev_err(dev, "Bit Error Uncorrected\n"); |
| 817 | if (irqstatus & IR_BEC) | 817 | if (irqstatus & IR_BEC) |
| @@ -1494,20 +1494,32 @@ static int m_can_dev_setup(struct m_can_classdev *cdev) · 676 unmodified lines | |||
| 1494 | case 30: | 1494 | case 30: |
| 1495 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */ | 1495 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */ |
| 1496 | can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); | 1496 | can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); |
| 1497 | cdev->can.bittiming_const = &m_can_bittiming_const_30X; | 1497 | cdev->can.bittiming_const = cdev->bit_timing ? |
| 1498 | cdev->can.data_bittiming_const = &m_can_data_bittiming_const_30X; | 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 | break; | 1503 | break; |
| 1500 | case 31: | 1504 | case 31: |
| 1501 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */ | 1505 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */ |
| 1502 | can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); | 1506 | can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); |
| 1503 | cdev->can.bittiming_const = &m_can_bittiming_const_31X; | 1507 | cdev->can.bittiming_const = cdev->bit_timing ? |
| 1504 | cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X; | 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 | break; | 1513 | break; |
| 1506 | case 32: | 1514 | case 32: |
| 1507 | case 33: | 1515 | case 33: |
| 1508 | /* Support both MCAN version v3.2.x and v3.3.0 */ | 1516 | /* Support both MCAN version v3.2.x and v3.3.0 */ |
| 1509 | cdev->can.bittiming_const = &m_can_bittiming_const_31X; | 1517 | cdev->can.bittiming_const = cdev->bit_timing ? |
| 1510 | cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X; | 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 | cdev->can.ctrlmode_supported |= | 1524 | cdev->can.ctrlmode_supported |= |
| 1513 | (m_can_niso_supported(cdev) ? | 1525 | (m_can_niso_supported(cdev) ? |
| @@ -85,6 +85,9 @@ struct m_can_classdev { · 84 unmodified lines | |||
| 85 | struct sk_buff *tx_skb; | 85 | struct sk_buff *tx_skb; |
| 86 | struct phy *transceiver; | 86 | struct phy *transceiver; |
| 87 | 87 | ||
| 88 | const struct can_bittiming_const *bit_timing; | ||
| 89 | const struct can_bittiming_const *data_timing; | ||
| 90 | |||
| 88 | struct m_can_ops *ops; | 91 | struct m_can_ops *ops; |
| 89 | 92 | ||
| 90 | int version; | 93 | int version; |
| @@ -18,9 +18,14 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define M_CAN_PCI_MMIO_BAR 0 | 19 | #define M_CAN_PCI_MMIO_BAR 0 |
| 20 | 20 | ||
| 21 | #define M_CAN_CLOCK_FREQ_EHL 100000000 | ||
| 22 | #define CTL_CSR_INT_CTL_OFFSET 0x508 | 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 | struct m_can_pci_priv { | 29 | struct m_can_pci_priv { |
| 25 | struct m_can_classdev cdev; | 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 | static int iomap_read_fifo(struct m_can_classdev *cdev, int offset, void *val, size_t val_count) | 47 | static int iomap_read_fifo(struct m_can_classdev *cdev, int offset, void *val, size_t val_count) |
| 43 | { | 48 | { |
| 44 | struct m_can_pci_priv *priv = cdev_to_priv(cdev); | 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 | return 0; | 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 | const void *val, size_t val_count) | 71 | const void *val, size_t val_count) |
| 62 | { | 72 | { |
| 63 | struct m_can_pci_priv *priv = cdev_to_priv(cdev); | 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 | return 0; | 82 | return 0; |
| 68 | } | 83 | } |
| @@ -74,9 +89,40 @@ static struct m_can_ops m_can_pci_ops = { · 5 unmodified lines | |||
| 74 | .read_fifo = iomap_read_fifo, | 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 | static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) | 122 | static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) |
| 78 | { | 123 | { |
| 79 | struct device *dev = &pci->dev; | 124 | struct device *dev = &pci->dev; |
| 125 | const struct m_can_pci_config *cfg; | ||
| 80 | struct m_can_classdev *mcan_class; | 126 | struct m_can_classdev *mcan_class; |
| 81 | struct m_can_pci_priv *priv; | 127 | struct m_can_pci_priv *priv; |
| 82 | void __iomem *base; | 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 | if (!mcan_class) | 150 | if (!mcan_class) |
| 105 | return -ENOMEM; | 151 | return -ENOMEM; |
| 106 | 152 | ||
| 153 | cfg = (const struct m_can_pci_config *)id->driver_data; | ||
| 154 | |||
| 107 | priv = cdev_to_priv(mcan_class); | 155 | priv = cdev_to_priv(mcan_class); |
| 108 | 156 | ||
| 109 | priv->base = base; | 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 | mcan_class->dev = &pci->dev; | 163 | mcan_class->dev = &pci->dev; |
| 116 | mcan_class->net->irq = pci_irq_vector(pci, 0); | 164 | mcan_class->net->irq = pci_irq_vector(pci, 0); |
| 117 | mcan_class->pm_clock_support = 1; | 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 | mcan_class->ops = &m_can_pci_ops; | 169 | mcan_class->ops = &m_can_pci_ops; |
| 120 | 170 | ||
| 121 | pci_set_drvdata(pci, mcan_class); | 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 | m_can_pci_suspend, m_can_pci_resume); | 218 | m_can_pci_suspend, m_can_pci_resume); |
| 169 | 219 | ||
| 170 | static const struct pci_device_id m_can_pci_id_table[] = { | 220 | static const struct pci_device_id m_can_pci_id_table[] = { |
| 171 | { PCI_VDEVICE(INTEL, 0x4bc1), M_CAN_CLOCK_FREQ_EHL, }, | 221 | { PCI_VDEVICE(INTEL, 0x4bc1), (kernel_ulong_t)&m_can_pci_ehl, }, |
| 172 | { PCI_VDEVICE(INTEL, 0x4bc2), M_CAN_CLOCK_FREQ_EHL, }, | 222 | { PCI_VDEVICE(INTEL, 0x4bc2), (kernel_ulong_t)&m_can_pci_ehl, }, |
| 173 | { } /* Terminating Entry */ | 223 | { } /* Terminating Entry */ |
| 174 | }; | 224 | }; |
| 175 | MODULE_DEVICE_TABLE(pci, m_can_pci_id_table); | 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 | cf->data[i + 1] = data_reg >> 8; | 692 | cf->data[i + 1] = data_reg >> 8; |
| 693 | } | 693 | } |
| 694 | 694 | ||
| 695 | netif_receive_skb(skb); | ||
| 696 | rcv_pkts++; | 695 | rcv_pkts++; |
| 697 | stats->rx_packets++; | 696 | stats->rx_packets++; |
| 698 | quota--; | 697 | quota--; |
| 699 | stats->rx_bytes += cf->len; | 698 | stats->rx_bytes += cf->len; |
| 699 | netif_receive_skb(skb); | ||
| 700 | 700 | ||
| 701 | pch_fifo_thresh(priv, obj_num); | 701 | pch_fifo_thresh(priv, obj_num); |
| 702 | obj_num++; | 702 | obj_num++; |
| @@ -234,7 +234,12 @@ static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base) · 233 unmodified lines | |||
| 234 | free_sja1000dev(dev); | 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 | DRV_NAME, card); | 243 | DRV_NAME, card); |
| 239 | if (!err) | 244 | if (!err) |
| 240 | return 0; | 245 | return 0; |
| @@ -28,10 +28,6 @@ · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | #include "kvaser_usb.h" | 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 | #define MAX_USBCAN_NET_DEVICES 2 | 31 | #define MAX_USBCAN_NET_DEVICES 2 |
| 36 | 32 | ||
| 37 | /* Command header size */ | 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 | #define CMD_LEAF_LOG_MESSAGE 106 | 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 | /* error factors */ | 85 | /* error factors */ |
| 84 | #define M16C_EF_ACKE BIT(0) | 86 | #define M16C_EF_ACKE BIT(0) |
| 85 | #define M16C_EF_CRCE BIT(1) | 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 | static void * | 389 | static void * |
| 344 | kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, | 390 | kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, |
| 345 | const struct sk_buff *skb, int *frame_len, | 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 | return rc; | 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 | static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) | 541 | static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) |
| 475 | { | 542 | { |
| 476 | struct kvaser_cmd cmd; | 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 | switch (dev->card_data.leaf.family) { | 554 | switch (dev->card_data.leaf.family) { |
| 488 | case KVASER_LEAF: | 555 | case KVASER_LEAF: |
| 489 | dev->fw_version = le32_to_cpu(cmd.u.leaf.softinfo.fw_version); | 556 | kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo); |
| 490 | dev->max_tx_urbs = | ||
| 491 | le16_to_cpu(cmd.u.leaf.softinfo.max_outstanding_tx); | ||
| 492 | break; | 557 | break; |
| 493 | case KVASER_USBCAN: | 558 | case KVASER_USBCAN: |
| 494 | dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); | 559 | dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); |
| 495 | dev->max_tx_urbs = | 560 | dev->max_tx_urbs = |
| 496 | le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx); | 561 | le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx); |
| 562 | dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz; | ||
| 497 | break; | 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 | struct kvaser_usb_dev_card_data *card_data = &dev->card_data; | 1292 | struct kvaser_usb_dev_card_data *card_data = &dev->card_data; |
| 1227 | 1293 | ||
| 1228 | dev->cfg = &kvaser_usb_leaf_dev_cfg; | ||
| 1229 | card_data->ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; | 1294 | card_data->ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; |
| 1230 | 1295 | ||
| 1231 | return 0; | 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 | static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) | 1299 | static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) |
| 1247 | { | 1300 | { |
| 1248 | struct kvaser_usb_net_priv *priv = netdev_priv(netdev); | 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 | .dev_read_bulk_callback = kvaser_usb_leaf_read_bulk_callback, | 1401 | .dev_read_bulk_callback = kvaser_usb_leaf_read_bulk_callback, |
| 1349 | .dev_frame_to_cmd = kvaser_usb_leaf_frame_to_cmd, | 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 | MODULE_DEVICE_TABLE(of, b53_spi_of_match); | 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 | static struct spi_driver b53_spi_driver = { | 365 | static struct spi_driver b53_spi_driver = { |
| 353 | .driver = { | 366 | .driver = { |
| 354 | .name = "b53-switch", | 367 | .name = "b53-switch", |
| @@ -357,6 +370,7 @@ static struct spi_driver b53_spi_driver = { · 2 unmodified lines | |||
| 357 | .probe = b53_spi_probe, | 370 | .probe = b53_spi_probe, |
| 358 | .remove = b53_spi_remove, | 371 | .remove = b53_spi_remove, |
| 359 | .shutdown = b53_spi_shutdown, | 372 | .shutdown = b53_spi_shutdown, |
| 373 | .id_table = b53_spi_ids, | ||
| 360 | }; | 374 | }; |
| 361 | 375 | ||
| 362 | module_spi_driver(b53_spi_driver); | 376 | module_spi_driver(b53_spi_driver); |
| @@ -471,6 +471,12 @@ static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port) · 470 unmodified lines | |||
| 471 | u16 reg; | 471 | u16 reg; |
| 472 | int err; | 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 | err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); | 480 | err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); |
| 475 | if (err) { | 481 | if (err) { |
| 476 | dev_err(chip->dev, | 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 | struct mv88e6xxx_chip *chip = ds->priv; | 699 | struct mv88e6xxx_chip *chip = ds->priv; |
| 694 | struct mv88e6xxx_port *p; | 700 | struct mv88e6xxx_port *p; |
| 695 | int err; | 701 | int err = 0; |
| 696 | 702 | ||
| 697 | p = &chip->ports[port]; | 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 | mv88e6xxx_reg_lock(chip); | 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, | 707 | if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) { |
| 721 | state->advertising); | 708 | /* In inband mode, the link may come up at any time while the |
| 722 | /* FIXME: we should restart negotiation if something changed - which | 709 | * link is not forced down. Force the link down while we |
| 723 | * is something we get if we convert to using phylinks PCS operations. | 710 | * reconfigure the interface mode. |
| 724 | */ | 711 | */ |
| 725 | if (err > 0) | 712 | if (mode == MLO_AN_INBAND && |
| 726 | err = 0; | 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 | /* Undo the forced down state above after completing configuration | 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 && | 740 | if (chip->info->ops->port_set_link && |
| 732 | 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 | chip->info->ops->port_set_link(chip, port, LINK_UNFORCED); | 743 | chip->info->ops->port_set_link(chip, port, LINK_UNFORCED); |
| 734 | 744 | ||
| 735 | p->interface = state->interface; | 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 | ops = chip->info->ops; | 762 | ops = chip->info->ops; |
| 753 | 763 | ||
| 754 | mv88e6xxx_reg_lock(chip); | 764 | mv88e6xxx_reg_lock(chip); |
| 755 | /* Internal PHYs propagate their configuration directly to the MAC. | 765 | /* Force the link down if we know the port may not be automatically |
| 756 | * External PHYs depend on whether the PPU is enabled for this port. | 766 | * updated by the switch or if we are using fixed-link mode. |
| 757 | */ | 767 | */ |
| 758 | if (((!mv88e6xxx_phy_is_internal(ds, port) && | 768 | if ((!mv88e6xxx_port_ppu_updates(chip, port) || |
| 759 | !mv88e6xxx_port_ppu_updates(chip, port)) || | ||
| 760 | mode == MLO_AN_FIXED) && ops->port_sync_link) | 769 | mode == MLO_AN_FIXED) && ops->port_sync_link) |
| 761 | err = ops->port_sync_link(chip, port, mode, false); | 770 | err = ops->port_sync_link(chip, port, mode, false); |
| 762 | mv88e6xxx_reg_unlock(chip); | 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 | ops = chip->info->ops; | 788 | ops = chip->info->ops; |
| 780 | 789 | ||
| 781 | mv88e6xxx_reg_lock(chip); | 790 | mv88e6xxx_reg_lock(chip); |
| 782 | /* Internal PHYs propagate their configuration directly to the MAC. | 791 | /* Configure and force the link up if we know that the port may not |
| 783 | * External PHYs depend on whether the PPU is enabled for this port. | 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) && | 795 | if (!mv88e6xxx_port_ppu_updates(chip, port) || |
| 786 | !mv88e6xxx_port_ppu_updates(chip, port)) || | ||
| 787 | mode == MLO_AN_FIXED) { | 796 | mode == MLO_AN_FIXED) { |
| 788 | /* FIXME: for an automedia port, should we force the link | 797 | /* FIXME: for an automedia port, should we force the link |
| 789 | * down here - what if the link comes up due to "other" media | 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 | static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, | 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 | struct phylink_link_state *state) | 54 | struct phylink_link_state *state) |
| 55 | { | 55 | { |
| 56 | state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK); | ||
| 57 | |||
| 56 | if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) { | 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 | state->duplex = status & | 69 | state->duplex = status & |
| 59 | MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ? | 70 | MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ? |
| 60 | DUPLEX_FULL : DUPLEX_HALF; | 71 | DUPLEX_FULL : DUPLEX_HALF; |
| @@ -81,6 +92,18 @@ static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, · 20 unmodified lines | |||
| 81 | dev_err(chip->dev, "invalid PHY speed\n"); | 92 | dev_err(chip->dev, "invalid PHY speed\n"); |
| 82 | return -EINVAL; | 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 | } else { | 107 | } else { |
| 85 | state->link = false; | 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 | int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, | 191 | int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, |
| 169 | int lane, struct phylink_link_state *state) | 192 | int lane, struct phylink_link_state *state) |
| 170 | { | 193 | { |
| 171 | u16 lpa, status; | 194 | u16 lpa, status, ctrl; |
| 172 | int err; | 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 | err = mv88e6352_serdes_read(chip, 0x11, &status); | 203 | err = mv88e6352_serdes_read(chip, 0x11, &status); |
| 175 | if (err) { | 204 | if (err) { |
| 176 | dev_err(chip->dev, "can't read Serdes PHY status: %d\n", err); | 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 | return err; | 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 | int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, | 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 | bool up) | 830 | bool up) |
| 802 | { | 831 | { |
| 803 | u8 cmode = chip->ports[port].cmode; | 832 | u8 cmode = chip->ports[port].cmode; |
| 804 | int err = 0; | 833 | int err; |
| 805 | 834 | ||
| 806 | switch (cmode) { | 835 | switch (cmode) { |
| 807 | case MV88E6XXX_PORT_STS_CMODE_SGMII: | 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 | case MV88E6XXX_PORT_STS_CMODE_RXAUI: | 842 | case MV88E6XXX_PORT_STS_CMODE_RXAUI: |
| 814 | err = mv88e6390_serdes_power_10g(chip, lane, up); | 843 | err = mv88e6390_serdes_power_10g(chip, lane, up); |
| 815 | break; | 844 | break; |
| 845 | default: | ||
| 846 | err = -EINVAL; | ||
| 847 | break; | ||
| 816 | } | 848 | } |
| 817 | 849 | ||
| 818 | if (!err && up) | 850 | if (!err && up) |
| @@ -883,9 +915,16 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, · 64 unmodified lines | |||
| 883 | static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, | 915 | static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, |
| 884 | int port, int lane, struct phylink_link_state *state) | 916 | int port, int lane, struct phylink_link_state *state) |
| 885 | { | 917 | { |
| 886 | u16 lpa, status; | 918 | u16 lpa, status, ctrl; |
| 887 | int err; | 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 | err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, | 928 | err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, |
| 890 | MV88E6390_SGMII_PHY_STATUS, &status); | 929 | MV88E6390_SGMII_PHY_STATUS, &status); |
| 891 | if (err) { | 930 | if (err) { |
| @@ -900,7 +939,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, · 8 unmodified lines | |||
| 900 | return err; | 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 | static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip, | 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 | int err; | 1338 | int err; |
| 1278 | 1339 | ||
| 1279 | /* mv88e6393x family errata 4.6: | 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 | * It seems that after this workaround the SERDES is automatically | 1345 | * It seems that after this workaround the SERDES is automatically |
| 1285 | * powered up (the bit is cleared), so power it down. | 1346 | * powered up (the bit is cleared), so power it down. |
| 1286 | */ | 1347 | */ |
| 1287 | if (lane == MV88E6393X_PORT0_LANE || lane == MV88E6393X_PORT9_LANE || | 1348 | err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, |
| 1288 | lane == MV88E6393X_PORT10_LANE) { | 1349 | MV88E6393X_SERDES_POC, ®); |
| 1289 | err = mv88e6390_serdes_read(chip, lane, | 1350 | if (err) |
| 1290 | MDIO_MMD_PHYXS, | 1351 | return err; |
| 1291 | MV88E6393X_SERDES_POC, ®); | ||
| 1292 | if (err) | ||
| 1293 | return err; | ||
| 1294 | 1352 | ||
| 1295 | reg &= ~MV88E6393X_SERDES_POC_PDOWN; | 1353 | reg &= ~MV88E6393X_SERDES_POC_PDOWN; |
| 1296 | reg |= MV88E6393X_SERDES_POC_RESET; | 1354 | reg |= MV88E6393X_SERDES_POC_RESET; |
| 1297 | 1355 | ||
| 1298 | err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, | 1356 | err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, |
| 1299 | MV88E6393X_SERDES_POC, reg); | 1357 | MV88E6393X_SERDES_POC, reg); |
| 1300 | if (err) | 1358 | if (err) |
| 1301 | return err; | 1359 | return err; |
| 1302 | 1360 | ||
| 1303 | err = mv88e6390_serdes_power_sgmii(chip, lane, false); | 1361 | err = mv88e6390_serdes_power_sgmii(chip, lane, false); |
| 1304 | if (err) | 1362 | if (err) |
| 1305 | return err; | 1363 | return err; |
| 1306 | } | 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 | /* mv88e6393x family errata 4.8: | 1388 | /* mv88e6393x family errata 4.8: |
| 1309 | * When a SERDES port is operating in 1000BASE-X or SGMII mode link may | 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 | MV88E6393X_ERRATA_4_8_REG, reg); | 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 | int err; | 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 | if (err) | 1499 | if (err) |
| 1343 | return err; | 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 | if (err) | 1503 | if (err) |
| 1347 | return err; | 1504 | return err; |
| 1348 | 1505 | ||
| 1349 | return mv88e6393x_serdes_port_errata(chip, MV88E6393X_PORT10_LANE); | 1506 | return 0; |
| 1350 | } | 1507 | } |
| 1351 | 1508 | ||
| 1352 | int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, | 1509 | int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, |
| 1353 | bool on) | 1510 | bool on) |
| 1354 | { | 1511 | { |
| 1355 | u8 cmode = chip->ports[port].cmode; | 1512 | u8 cmode = chip->ports[port].cmode; |
| 1513 | int err; | ||
| 1356 | 1514 | ||
| 1357 | if (port != 0 && port != 9 && port != 10) | 1515 | if (port != 0 && port != 9 && port != 10) |
| 1358 | return -EOPNOTSUPP; | 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 | switch (cmode) { | 1537 | switch (cmode) { |
| 1361 | case MV88E6XXX_PORT_STS_CMODE_SGMII: | 1538 | case MV88E6XXX_PORT_STS_CMODE_SGMII: |
| 1362 | case MV88E6XXX_PORT_STS_CMODE_1000BASEX: | 1539 | case MV88E6XXX_PORT_STS_CMODE_1000BASEX: |
| 1363 | case MV88E6XXX_PORT_STS_CMODE_2500BASEX: | 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 | case MV88E6393X_PORT_STS_CMODE_5GBASER: | 1543 | case MV88E6393X_PORT_STS_CMODE_5GBASER: |
| 1366 | case MV88E6393X_PORT_STS_CMODE_10GBASER: | 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 | #define MV88E6393X_SERDES_POC_PCS_MASK 0x0007 | 93 | #define MV88E6393X_SERDES_POC_PCS_MASK 0x0007 |
| 94 | #define MV88E6393X_SERDES_POC_RESET BIT(15) | 94 | #define MV88E6393X_SERDES_POC_RESET BIT(15) |
| 95 | #define MV88E6393X_SERDES_POC_PDOWN BIT(5) | 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 | #define MV88E6393X_ERRATA_4_8_REG 0xF074 | 101 | #define MV88E6393X_ERRATA_4_8_REG 0xF074 |
| 98 | #define MV88E6393X_ERRATA_4_8_BIT BIT(14) | 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 | return -EINVAL; | 296 | return -EINVAL; |
| 297 | } | ||
| 295 | 298 | ||
| 296 | tagging_rule->key_type = OCELOT_VCAP_KEY_ETYPE; | 299 | tagging_rule->key_type = OCELOT_VCAP_KEY_ETYPE; |
| 297 | *(__be16 *)tagging_rule->key.etype.etype.value = htons(ETH_P_1588); | 300 | *(__be16 *)tagging_rule->key.etype.etype.value = htons(ETH_P_1588); |
| @@ -107,6 +107,7 @@ · 106 unmodified lines | |||
| 107 | #define RTL8365MB_LEARN_LIMIT_MAX_8365MB_VC 2112 | 107 | #define RTL8365MB_LEARN_LIMIT_MAX_8365MB_VC 2112 |
| 108 | 108 | ||
| 109 | /* Family-specific data and limits */ | 109 | /* Family-specific data and limits */ |
| 110 | #define RTL8365MB_PHYADDRMAX 7 | ||
| 110 | #define RTL8365MB_NUM_PHYREGS 32 | 111 | #define RTL8365MB_NUM_PHYREGS 32 |
| 111 | #define RTL8365MB_PHYREGMAX (RTL8365MB_NUM_PHYREGS - 1) | 112 | #define RTL8365MB_PHYREGMAX (RTL8365MB_NUM_PHYREGS - 1) |
| 112 | #define RTL8365MB_MAX_NUM_PORTS (RTL8365MB_CPU_PORT_NUM_8365MB_VC + 1) | 113 | #define RTL8365MB_MAX_NUM_PORTS (RTL8365MB_CPU_PORT_NUM_8365MB_VC + 1) |
| @@ -176,7 +177,7 @@ · 63 unmodified lines | |||
| 176 | #define RTL8365MB_INDIRECT_ACCESS_STATUS_REG 0x1F01 | 177 | #define RTL8365MB_INDIRECT_ACCESS_STATUS_REG 0x1F01 |
| 177 | #define RTL8365MB_INDIRECT_ACCESS_ADDRESS_REG 0x1F02 | 178 | #define RTL8365MB_INDIRECT_ACCESS_ADDRESS_REG 0x1F02 |
| 178 | #define RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_5_1_MASK GENMASK(4, 0) | 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 | #define RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_9_6_MASK GENMASK(11, 8) | 181 | #define RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_9_6_MASK GENMASK(11, 8) |
| 181 | #define RTL8365MB_PHY_BASE 0x2000 | 182 | #define RTL8365MB_PHY_BASE 0x2000 |
| 182 | #define RTL8365MB_INDIRECT_ACCESS_WRITE_DATA_REG 0x1F03 | 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 | u16 val; | 680 | u16 val; |
| 680 | int ret; | 681 | int ret; |
| 681 | 682 | ||
| 683 | if (phy > RTL8365MB_PHYADDRMAX) | ||
| 684 | return -EINVAL; | ||
| 685 | |||
| 682 | if (regnum > RTL8365MB_PHYREGMAX) | 686 | if (regnum > RTL8365MB_PHYREGMAX) |
| 683 | return -EINVAL; | 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 | u32 ocp_addr; | 708 | u32 ocp_addr; |
| 705 | int ret; | 709 | int ret; |
| 706 | 710 | ||
| 711 | if (phy > RTL8365MB_PHYADDRMAX) | ||
| 712 | return -EINVAL; | ||
| 713 | |||
| 707 | if (regnum > RTL8365MB_PHYREGMAX) | 714 | if (regnum > RTL8365MB_PHYREGMAX) |
| 708 | return -EINVAL; | 715 | return -EINVAL; |
| 709 | 716 | ||
| @@ -1430,16 +1430,19 @@ static int altera_tse_probe(struct platform_device *pdev) · 1429 unmodified lines | |||
| 1430 | priv->rxdescmem_busaddr = dma_res->start; | 1430 | priv->rxdescmem_busaddr = dma_res->start; |
| 1431 | 1431 | ||
| 1432 | } else { | 1432 | } else { |
| 1433 | ret = -ENODEV; | ||
| 1433 | goto err_free_netdev; | 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 | dma_set_coherent_mask(priv->device, | 1438 | dma_set_coherent_mask(priv->device, |
| 1438 | DMA_BIT_MASK(priv->dmaops->dmamask)); | 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 | dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32)); | 1441 | dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32)); |
| 1441 | else | 1442 | } else { |
| 1443 | ret = -EIO; | ||
| 1442 | goto err_free_netdev; | 1444 | goto err_free_netdev; |
| 1445 | } | ||
| 1443 | 1446 | ||
| 1444 | /* MAC address space */ | 1447 | /* MAC address space */ |
| 1445 | ret = request_and_map(pdev, "control_port", &control_port, | 1448 | ret = request_and_map(pdev, "control_port", &control_port, |
| @@ -40,10 +40,12 @@ · 39 unmodified lines | |||
| 40 | 40 | ||
| 41 | #define AQ_DEVICE_ID_AQC113DEV 0x00C0 | 41 | #define AQ_DEVICE_ID_AQC113DEV 0x00C0 |
| 42 | #define AQ_DEVICE_ID_AQC113CS 0x94C0 | 42 | #define AQ_DEVICE_ID_AQC113CS 0x94C0 |
| 43 | #define AQ_DEVICE_ID_AQC113CA 0x34C0 | ||
| 43 | #define AQ_DEVICE_ID_AQC114CS 0x93C0 | 44 | #define AQ_DEVICE_ID_AQC114CS 0x93C0 |
| 44 | #define AQ_DEVICE_ID_AQC113 0x04C0 | 45 | #define AQ_DEVICE_ID_AQC113 0x04C0 |
| 45 | #define AQ_DEVICE_ID_AQC113C 0x14C0 | 46 | #define AQ_DEVICE_ID_AQC113C 0x14C0 |
| 46 | #define AQ_DEVICE_ID_AQC115C 0x12C0 | 47 | #define AQ_DEVICE_ID_AQC115C 0x12C0 |
| 48 | #define AQ_DEVICE_ID_AQC116C 0x11C0 | ||
| 47 | 49 | ||
| 48 | #define HW_ATL_NIC_NAME "Marvell (aQuantia) AQtion 10Gbit Network Adapter" | 50 | #define HW_ATL_NIC_NAME "Marvell (aQuantia) AQtion 10Gbit Network Adapter" |
| 49 | 51 | ||
| @@ -53,20 +55,19 @@ · 3 unmodified lines | |||
| 53 | 55 | ||
| 54 | #define AQ_NIC_RATE_10G BIT(0) | 56 | #define AQ_NIC_RATE_10G BIT(0) |
| 55 | #define AQ_NIC_RATE_5G BIT(1) | 57 | #define AQ_NIC_RATE_5G BIT(1) |
| 56 | #define AQ_NIC_RATE_5GSR BIT(2) | 58 | #define AQ_NIC_RATE_2G5 BIT(2) |
| 57 | #define AQ_NIC_RATE_2G5 BIT(3) | 59 | #define AQ_NIC_RATE_1G BIT(3) |
| 58 | #define AQ_NIC_RATE_1G BIT(4) | 60 | #define AQ_NIC_RATE_100M BIT(4) |
| 59 | #define AQ_NIC_RATE_100M BIT(5) | 61 | #define AQ_NIC_RATE_10M BIT(5) |
| 60 | #define AQ_NIC_RATE_10M BIT(6) | 62 | #define AQ_NIC_RATE_1G_HALF BIT(6) |
| 61 | #define AQ_NIC_RATE_1G_HALF BIT(7) | 63 | #define AQ_NIC_RATE_100M_HALF BIT(7) |
| 62 | #define AQ_NIC_RATE_100M_HALF BIT(8) | 64 | #define AQ_NIC_RATE_10M_HALF BIT(8) |
| 63 | #define AQ_NIC_RATE_10M_HALF BIT(9) | ||
| 64 | 65 | ||
| 65 | #define AQ_NIC_RATE_EEE_10G BIT(10) | 66 | #define AQ_NIC_RATE_EEE_10G BIT(9) |
| 66 | #define AQ_NIC_RATE_EEE_5G BIT(11) | 67 | #define AQ_NIC_RATE_EEE_5G BIT(10) |
| 67 | #define AQ_NIC_RATE_EEE_2G5 BIT(12) | 68 | #define AQ_NIC_RATE_EEE_2G5 BIT(11) |
| 68 | #define AQ_NIC_RATE_EEE_1G BIT(13) | 69 | #define AQ_NIC_RATE_EEE_1G BIT(12) |
| 69 | #define AQ_NIC_RATE_EEE_100M BIT(14) | 70 | #define AQ_NIC_RATE_EEE_100M BIT(13) |
| 70 | #define AQ_NIC_RATE_EEE_MSK (AQ_NIC_RATE_EEE_10G |\ | 71 | #define AQ_NIC_RATE_EEE_MSK (AQ_NIC_RATE_EEE_10G |\ |
| 71 | AQ_NIC_RATE_EEE_5G |\ | 72 | AQ_NIC_RATE_EEE_5G |\ |
| 72 | AQ_NIC_RATE_EEE_2G5 |\ | 73 | AQ_NIC_RATE_EEE_2G5 |\ |
| @@ -80,6 +80,8 @@ struct aq_hw_link_status_s { · 79 unmodified lines | |||
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | struct aq_stats_s { | 82 | struct aq_stats_s { |
| 83 | u64 brc; | ||
| 84 | u64 btc; | ||
| 83 | u64 uprc; | 85 | u64 uprc; |
| 84 | u64 mprc; | 86 | u64 mprc; |
| 85 | u64 bprc; | 87 | u64 bprc; |
| @@ -316,18 +316,22 @@ int aq_nic_ndev_register(struct aq_nic_s *self) · 315 unmodified lines | |||
| 316 | aq_macsec_init(self); | 316 | aq_macsec_init(self); |
| 317 | #endif | 317 | #endif |
| 318 | 318 | ||
| 319 | mutex_lock(&self->fwreq_mutex); | 319 | if (platform_get_ethdev_address(&self->pdev->dev, self->ndev) != 0) { |
| 320 | err = self->aq_fw_ops->get_mac_permanent(self->aq_hw, addr); | 320 | // If DT has none or an invalid one, ask device for MAC address |
| 321 | mutex_unlock(&self->fwreq_mutex); | 321 | mutex_lock(&self->fwreq_mutex); |
| 322 | if (err) | 322 | err = self->aq_fw_ops->get_mac_permanent(self->aq_hw, addr); |
| 323 | goto err_exit; | 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 | if (is_valid_ether_addr(addr) && |
| 328 | !aq_nic_is_valid_ether_addr(self->ndev->dev_addr)) { | 329 | aq_nic_is_valid_ether_addr(addr)) { |
| 329 | netdev_warn(self->ndev, "MAC is invalid, will use random."); | 330 | eth_hw_addr_set(self->ndev, addr); |
| 330 | eth_hw_addr_random(self->ndev); | 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 | #if defined(AQ_CFG_MAC_ADDR_PERMANENT) | 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 | data[++i] = stats->mbtc; | 909 | data[++i] = stats->mbtc; |
| 906 | data[++i] = stats->bbrc; | 910 | data[++i] = stats->bbrc; |
| 907 | data[++i] = stats->bbtc; | 911 | data[++i] = stats->bbtc; |
| 908 | data[++i] = stats->ubrc + stats->mbrc + stats->bbrc; | 912 | if (stats->brc) |
| 909 | data[++i] = stats->ubtc + stats->mbtc + stats->bbtc; | 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 | data[++i] = stats->dma_pkt_rc; | 920 | data[++i] = stats->dma_pkt_rc; |
| 911 | data[++i] = stats->dma_pkt_tc; | 921 | data[++i] = stats->dma_pkt_tc; |
| 912 | data[++i] = stats->dma_oct_rc; | 922 | data[++i] = stats->dma_oct_rc; |
| @@ -49,6 +49,8 @@ static const struct pci_device_id aq_pci_tbl[] = { · 48 unmodified lines | |||
| 49 | { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113), }, | 49 | { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113), }, |
| 50 | { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113C), }, | 50 | { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113C), }, |
| 51 | { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC115C), }, | 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 | { AQ_DEVICE_ID_AQC113CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, | 87 | { AQ_DEVICE_ID_AQC113CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, |
| 86 | { AQ_DEVICE_ID_AQC114CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, | 88 | { AQ_DEVICE_ID_AQC114CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, |
| 87 | { AQ_DEVICE_ID_AQC113C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, | 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 | MODULE_DEVICE_TABLE(pci, aq_pci_tbl); | 96 | MODULE_DEVICE_TABLE(pci, aq_pci_tbl); |
| @@ -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 | unsigned int count; | 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 | if (!aq_vec_is_valid_tc(self, tc)) | 365 | if (!aq_vec_is_valid_tc(self, tc)) |
| 369 | return 0; | 366 | return 0; |
| 370 | 367 | ||
| @@ -867,12 +867,20 @@ static int hw_atl_fw1x_deinit(struct aq_hw_s *self) · 866 unmodified lines | |||
| 867 | int hw_atl_utils_update_stats(struct aq_hw_s *self) | 867 | int hw_atl_utils_update_stats(struct aq_hw_s *self) |
| 868 | { | 868 | { |
| 869 | struct aq_stats_s *cs = &self->curr_stats; | 869 | struct aq_stats_s *cs = &self->curr_stats; |
| 870 | struct aq_stats_s curr_stats = *cs; | ||
| 870 | struct hw_atl_utils_mbox mbox; | 871 | struct hw_atl_utils_mbox mbox; |
| 872 | bool corrupted_stats = false; | ||
| 871 | 873 | ||
| 872 | hw_atl_utils_mpi_read_stats(self, &mbox); | 874 | hw_atl_utils_mpi_read_stats(self, &mbox); |
| 873 | 875 | ||
| 874 | #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \ | 876 | #define AQ_SDELTA(_N_) \ |
| 875 | mbox.stats._N_ - self->last_stats._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) | ||
| 876 | 884 | ||
| 877 | if (self->aq_link_status.mbps) { | 885 | if (self->aq_link_status.mbps) { |
| 878 | AQ_SDELTA(uprc); | 886 | AQ_SDELTA(uprc); |
| @@ -892,6 +900,9 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self) · 13 unmodified lines | |||
| 892 | AQ_SDELTA(bbrc); | 900 | AQ_SDELTA(bbrc); |
| 893 | AQ_SDELTA(bbtc); | 901 | AQ_SDELTA(bbtc); |
| 894 | AQ_SDELTA(dpc); | 902 | AQ_SDELTA(dpc); |
| 903 | |||
| 904 | if (!corrupted_stats) | ||
| 905 | *cs = curr_stats; | ||
| 895 | } | 906 | } |
| 896 | #undef AQ_SDELTA | 907 | #undef AQ_SDELTA |
| 897 | 908 | ||
| @@ -132,9 +132,6 @@ static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed) · 131 unmodified lines | |||
| 132 | if (speed & AQ_NIC_RATE_5G) | 132 | if (speed & AQ_NIC_RATE_5G) |
| 133 | rate |= FW2X_RATE_5G; | 133 | rate |= FW2X_RATE_5G; |
| 134 | 134 | ||
| 135 | if (speed & AQ_NIC_RATE_5GSR) | ||
| 136 | rate |= FW2X_RATE_5G; | ||
| 137 | |||
| 138 | if (speed & AQ_NIC_RATE_2G5) | 135 | if (speed & AQ_NIC_RATE_2G5) |
| 139 | rate |= FW2X_RATE_2G5; | 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 | AQ_NIC_RATE_5G | | 65 | AQ_NIC_RATE_5G | |
| 66 | AQ_NIC_RATE_2G5 | | 66 | AQ_NIC_RATE_2G5 | |
| 67 | AQ_NIC_RATE_1G | | 67 | AQ_NIC_RATE_1G | |
| 68 | AQ_NIC_RATE_1G_HALF | | ||
| 69 | AQ_NIC_RATE_100M | | 68 | AQ_NIC_RATE_100M | |
| 70 | AQ_NIC_RATE_100M_HALF | | 69 | AQ_NIC_RATE_10M, |
| 71 | AQ_NIC_RATE_10M | | 70 | }; |
| 72 | AQ_NIC_RATE_10M_HALF, | 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 | static u32 hw_atl2_sem_act_rslvr_get(struct aq_hw_s *self) | 89 | static u32 hw_atl2_sem_act_rslvr_get(struct aq_hw_s *self) |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | |||
| 9 | #include "aq_common.h" | 9 | #include "aq_common.h" |
| 10 | 10 | ||
| 11 | extern const struct aq_hw_caps_s hw_atl2_caps_aqc113; | 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 | extern const struct aq_hw_ops hw_atl2_ops; | 14 | extern const struct aq_hw_ops hw_atl2_ops; |
| 13 | 15 | ||
| 14 | #endif /* HW_ATL2_H */ | 16 | #endif /* HW_ATL2_H */ |
| @@ -239,7 +239,8 @@ struct version_s { · 238 unmodified lines | |||
| 239 | u8 minor; | 239 | u8 minor; |
| 240 | u16 build; | 240 | u16 build; |
| 241 | } phy; | 241 | } phy; |
| 242 | u32 rsvd; | 242 | u32 drv_iface_ver:4; |
| 243 | u32 rsvd:28; | ||
| 243 | }; | 244 | }; |
| 244 | 245 | ||
| 245 | struct link_status_s { | 246 | struct link_status_s { |
| @@ -424,7 +425,7 @@ struct cable_diag_status_s { · 178 unmodified lines | |||
| 424 | u16 rsvd2; | 425 | u16 rsvd2; |
| 425 | }; | 426 | }; |
| 426 | 427 | ||
| 427 | struct statistics_s { | 428 | struct statistics_a0_s { |
| 428 | struct { | 429 | struct { |
| 429 | u32 link_up; | 430 | u32 link_up; |
| 430 | u32 link_down; | 431 | u32 link_down; |
| @@ -457,6 +458,33 @@ struct statistics_s { · 26 unmodified lines | |||
| 457 | u32 reserve_fw_gap; | 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 | struct filter_caps_s { | 488 | struct filter_caps_s { |
| 461 | u8 l2_filters_base_index:6; | 489 | u8 l2_filters_base_index:6; |
| 462 | u8 flexible_filter_mask:2; | 490 | u8 flexible_filter_mask:2; |
| @@ -545,7 +573,7 @@ struct management_status_s { · 82 unmodified lines | |||
| 545 | u32 rsvd5; | 573 | u32 rsvd5; |
| 546 | }; | 574 | }; |
| 547 | 575 | ||
| 548 | struct fw_interface_out { | 576 | struct __packed fw_interface_out { |
| 549 | struct transaction_counter_s transaction_id; | 577 | struct transaction_counter_s transaction_id; |
| 550 | struct version_s version; | 578 | struct version_s version; |
| 551 | struct link_status_s link_status; | 579 | struct link_status_s link_status; |
| @@ -569,7 +597,6 @@ struct fw_interface_out { · 17 unmodified lines | |||
| 569 | struct core_dump_s core_dump; | 597 | struct core_dump_s core_dump; |
| 570 | u32 rsvd11; | 598 | u32 rsvd11; |
| 571 | struct statistics_s stats; | 599 | struct statistics_s stats; |
| 572 | u32 rsvd12; | ||
| 573 | struct filter_caps_s filter_caps; | 600 | struct filter_caps_s filter_caps; |
| 574 | struct device_caps_s device_caps; | 601 | struct device_caps_s device_caps; |
| 575 | u32 rsvd13; | 602 | u32 rsvd13; |
| @@ -592,6 +619,9 @@ struct fw_interface_out { · 16 unmodified lines | |||
| 592 | #define AQ_HOST_MODE_LOW_POWER 3U | 619 | #define AQ_HOST_MODE_LOW_POWER 3U |
| 593 | #define AQ_HOST_MODE_SHUTDOWN 4U | 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 | int hw_atl2_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops); | 625 | int hw_atl2_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops); |
| 596 | 626 | ||
| 597 | int hw_atl2_utils_soft_reset(struct aq_hw_s *self); | 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 | if (cnt > AQ_A2_FW_READ_TRY_MAX) | 84 | if (cnt > AQ_A2_FW_READ_TRY_MAX) |
| 85 | return -ETIME; | 85 | return -ETIME; |
| 86 | if (tid1.transaction_cnt_a != tid1.transaction_cnt_b) | 86 | if (tid1.transaction_cnt_a != tid1.transaction_cnt_b) |
| 87 | udelay(1); | 87 | mdelay(1); |
| 88 | } while (tid1.transaction_cnt_a != tid1.transaction_cnt_b); | 88 | } while (tid1.transaction_cnt_a != tid1.transaction_cnt_b); |
| 89 | 89 | ||
| 90 | hw_atl2_mif_shared_buf_read(self, offset, (u32 *)data, dwords); | 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 | link_options->rate_10G = !!(speed & AQ_NIC_RATE_10G); | 155 | link_options->rate_10G = !!(speed & AQ_NIC_RATE_10G); |
| 156 | link_options->rate_5G = !!(speed & AQ_NIC_RATE_5G); | 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 | link_options->rate_2P5G = !!(speed & AQ_NIC_RATE_2G5); | 158 | link_options->rate_2P5G = !!(speed & AQ_NIC_RATE_2G5); |
| 159 | link_options->rate_N2P5G = link_options->rate_2P5G; | 159 | link_options->rate_N2P5G = link_options->rate_2P5G; |
| 160 | link_options->rate_1G = !!(speed & AQ_NIC_RATE_1G); | 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 | rate |= AQ_NIC_RATE_10G; | 192 | rate |= AQ_NIC_RATE_10G; |
| 193 | if (lkp_link_caps->rate_5G) | 193 | if (lkp_link_caps->rate_5G) |
| 194 | rate |= AQ_NIC_RATE_5G; | 194 | rate |= AQ_NIC_RATE_5G; |
| 195 | if (lkp_link_caps->rate_N5G) | ||
| 196 | rate |= AQ_NIC_RATE_5GSR; | ||
| 197 | if (lkp_link_caps->rate_2P5G) | 195 | if (lkp_link_caps->rate_2P5G) |
| 198 | rate |= AQ_NIC_RATE_2G5; | 196 | rate |= AQ_NIC_RATE_2G5; |
| 199 | if (lkp_link_caps->rate_1G) | 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 | return 0; | 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 | struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; | 339 | struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; |
| 341 | struct statistics_s stats; | 340 | struct aq_stats_s *cs = &self->curr_stats; |
| 342 | 341 | struct aq_stats_s curr_stats = *cs; | |
| 343 | hw_atl2_shared_buffer_read_safe(self, stats, &stats); | 342 | bool corrupted_stats = false; |
| 344 | 343 | ||
| 345 | #define AQ_SDELTA(_N_, _F_) (self->curr_stats._N_ += \ | 344 | #define AQ_SDELTA(_N, _F) \ |
| 346 | stats.msm._F_ - priv->last_stats.msm._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 | if (self->aq_link_status.mbps) { | 353 | if (self->aq_link_status.mbps) { |
| 349 | AQ_SDELTA(uprc, rx_unicast_frames); | 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 | AQ_SDELTA(mbtc, tx_multicast_octets); | 367 | AQ_SDELTA(mbtc, tx_multicast_octets); |
| 363 | AQ_SDELTA(bbrc, rx_broadcast_octets); | 368 | AQ_SDELTA(bbrc, rx_broadcast_octets); |
| 364 | AQ_SDELTA(bbtc, tx_broadcast_octets); | 369 | AQ_SDELTA(bbtc, tx_broadcast_octets); |
| 370 | |||
| 371 | if (!corrupted_stats) | ||
| 372 | *cs = curr_stats; | ||
| 365 | } | 373 | } |
| 366 | #undef AQ_SDELTA | 374 | #undef AQ_SDELTA |
| 367 | self->curr_stats.dma_pkt_rc = | 375 | |
| 368 | hw_atl_stats_rx_dma_good_pkt_counter_get(self); | 376 | } |
| 369 | self->curr_stats.dma_pkt_tc = | 377 | |
| 370 | hw_atl_stats_tx_dma_good_pkt_counter_get(self); | 378 | static void aq_a2_fill_b0_stats(struct aq_hw_s *self, |
| 371 | self->curr_stats.dma_oct_rc = | 379 | struct statistics_s *stats) |
| 372 | hw_atl_stats_rx_dma_good_octet_counter_get(self); | 380 | { |
| 373 | self->curr_stats.dma_oct_tc = | 381 | struct hw_atl2_priv *priv = (struct hw_atl2_priv *)self->priv; |
| 374 | hw_atl_stats_tx_dma_good_octet_counter_get(self); | 382 | struct aq_stats_s *cs = &self->curr_stats; |
| 375 | self->curr_stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self); | 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 | memcpy(&priv->last_stats, &stats, sizeof(stats)); | 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 | hw_atl2_shared_buffer_read_safe(self, version, &version); | 563 | hw_atl2_shared_buffer_read_safe(self, version, &version); |
| 500 | 564 | ||
| 501 | /* A2 FW version is stored in reverse order */ | 565 | /* A2 FW version is stored in reverse order */ |
| 502 | return version.mac.major << 24 | | 566 | return version.bundle.major << 24 | |
| 503 | version.mac.minor << 16 | | 567 | version.bundle.minor << 16 | |
| 504 | version.mac.build; | 568 | version.bundle.build; |
| 505 | } | 569 | } |
| 506 | 570 | ||
| 507 | int hw_atl2_utils_get_action_resolve_table_caps(struct aq_hw_s *self, | 571 | int hw_atl2_utils_get_action_resolve_table_caps(struct aq_hw_s *self, |
| @@ -708,7 +708,9 @@ static int bcm4908_enet_probe(struct platform_device *pdev) · 707 unmodified lines | |||
| 708 | 708 | ||
| 709 | enet->irq_tx = platform_get_irq_byname(pdev, "tx"); | 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 | err = bcm4908_enet_dma_alloc(enet); | 715 | err = bcm4908_enet_dma_alloc(enet); |
| 714 | if (err) | 716 | if (err) |
| @@ -4550,6 +4550,8 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev) · 4549 unmodified lines | |||
| 4550 | 4550 | ||
| 4551 | fsl_mc_portal_free(priv->mc_io); | 4551 | fsl_mc_portal_free(priv->mc_io); |
| 4552 | 4552 | ||
| 4553 | destroy_workqueue(priv->dpaa2_ptp_wq); | ||
| 4554 | |||
| 4553 | dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name); | 4555 | dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name); |
| 4554 | 4556 | ||
| 4555 | free_netdev(net_dev); | 4557 | free_netdev(net_dev); |
| @@ -377,6 +377,9 @@ struct bufdesc_ex { · 376 unmodified lines | |||
| 377 | #define FEC_ENET_WAKEUP ((uint)0x00020000) /* Wakeup request */ | 377 | #define FEC_ENET_WAKEUP ((uint)0x00020000) /* Wakeup request */ |
| 378 | #define FEC_ENET_TXF (FEC_ENET_TXF_0 | FEC_ENET_TXF_1 | FEC_ENET_TXF_2) | 378 | #define FEC_ENET_TXF (FEC_ENET_TXF_0 | FEC_ENET_TXF_1 | FEC_ENET_TXF_2) |
| 379 | #define FEC_ENET_RXF (FEC_ENET_RXF_0 | FEC_ENET_RXF_1 | FEC_ENET_RXF_2) | 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 | #define FEC_ENET_TS_AVAIL ((uint)0x00010000) | 383 | #define FEC_ENET_TS_AVAIL ((uint)0x00010000) |
| 381 | #define FEC_ENET_TS_TIMER ((uint)0x00008000) | 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 | break; | 1480 | break; |
| 1481 | pkt_received++; | 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 | /* Check for errors. */ | 1485 | /* Check for errors. */ |
| 1486 | status ^= BD_ENET_RX_LAST; | 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 | set_protocol = ctx->curr_frag_cnt == ctx->expected_frag_cnt - 1; | 68 | set_protocol = ctx->curr_frag_cnt == ctx->expected_frag_cnt - 1; |
| 69 | } else { | 69 | } else { |
| 70 | skb = napi_alloc_skb(napi, len); | 70 | skb = napi_alloc_skb(napi, len); |
| 71 | |||
| 72 | if (unlikely(!skb)) | ||
| 73 | return NULL; | ||
| 71 | set_protocol = true; | 74 | set_protocol = true; |
| 72 | } | 75 | } |
| 73 | __skb_put(skb, len); | 76 | __skb_put(skb, len); |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | #include <linux/interrupt.h> | 8 | #include <linux/interrupt.h> |
| 9 | #include <linux/etherdevice.h> | 9 | #include <linux/etherdevice.h> |
| 10 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
| 11 | #include <linux/module.h> | ||
| 11 | 12 | ||
| 12 | #include "hinic_hw_dev.h" | 13 | #include "hinic_hw_dev.h" |
| 13 | #include "hinic_dev.h" | 14 | #include "hinic_dev.h" |
| @@ -628,17 +628,9 @@ static bool reuse_rx_pools(struct ibmvnic_adapter *adapter) · 627 unmodified lines | |||
| 628 | old_buff_size = adapter->prev_rx_buf_sz; | 628 | old_buff_size = adapter->prev_rx_buf_sz; |
| 629 | new_buff_size = adapter->cur_rx_buf_sz; | 629 | new_buff_size = adapter->cur_rx_buf_sz; |
| 630 | 630 | ||
| 631 | /* Require buff size to be exactly same for now */ | 631 | if (old_buff_size != new_buff_size || |
| 632 | if (old_buff_size != new_buff_size) | 632 | old_num_pools != new_num_pools || |
| 633 | return false; | 633 | old_pool_size != new_pool_size) |
| 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) | ||
| 642 | return false; | 634 | return false; |
| 643 | 635 | ||
| 644 | return true; | 636 | return true; |
| @@ -874,17 +866,9 @@ static bool reuse_tx_pools(struct ibmvnic_adapter *adapter) · 229 unmodified lines | |||
| 874 | old_mtu = adapter->prev_mtu; | 866 | old_mtu = adapter->prev_mtu; |
| 875 | new_mtu = adapter->req_mtu; | 867 | new_mtu = adapter->req_mtu; |
| 876 | 868 | ||
| 877 | /* Require MTU to be exactly same to reuse pools for now */ | 869 | if (old_mtu != new_mtu || |
| 878 | if (old_mtu != new_mtu) | 870 | old_num_pools != new_num_pools || |
| 879 | return false; | 871 | old_pool_size != new_pool_size) |
| 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) | ||
| 888 | return false; | 872 | return false; |
| 889 | 873 | ||
| 890 | return true; | 874 | return true; |
| @@ -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 | dev_info(&pf->pdev->dev, "vsi %d not found\n", vsi_seid); | 553 | dev_info(&pf->pdev->dev, "vsi %d not found\n", vsi_seid); |
| 554 | return; | 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 | if (type == RING_TYPE_XDP && !i40e_enabled_xdp_vsi(vsi)) { | 564 | if (type == RING_TYPE_XDP && !i40e_enabled_xdp_vsi(vsi)) { |
| 557 | dev_info(&pf->pdev->dev, "XDP not enabled on VSI %d\n", vsi_seid); | 565 | dev_info(&pf->pdev->dev, "XDP not enabled on VSI %d\n", vsi_seid); |
| 558 | return; | 566 | return; |
| @@ -1948,6 +1948,32 @@ static int i40e_vc_send_resp_to_vf(struct i40e_vf *vf, · 1947 unmodified lines | |||
| 1948 | return i40e_vc_send_msg_to_vf(vf, opcode, retval, NULL, 0); | 1948 | return i40e_vc_send_msg_to_vf(vf, opcode, retval, NULL, 0); |
| 1949 | } | 1949 | } |
| 1950 | 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 | |||
| 1951 | /** | 1977 | /** |
| 1952 | * i40e_vc_get_version_msg | 1978 | * i40e_vc_get_version_msg |
| 1953 | * @vf: pointer to the VF info | 1979 | * @vf: pointer to the VF info |
| @@ -2008,7 +2034,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) · 54 unmodified lines | |||
| 2008 | size_t len = 0; | 2034 | size_t len = 0; |
| 2009 | int ret; | 2035 | int ret; |
| 2010 | 2036 | ||
| 2011 | if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { | 2037 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_INIT)) { |
| 2012 | aq_ret = I40E_ERR_PARAM; | 2038 | aq_ret = I40E_ERR_PARAM; |
| 2013 | goto err; | 2039 | goto err; |
| 2014 | } | 2040 | } |
| @@ -2131,7 +2157,7 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf, u8 *msg) · 116 unmodified lines | |||
| 2131 | bool allmulti = false; | 2157 | bool allmulti = false; |
| 2132 | bool alluni = false; | 2158 | bool alluni = false; |
| 2133 | 2159 | ||
| 2134 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 2160 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 2135 | aq_ret = I40E_ERR_PARAM; | 2161 | aq_ret = I40E_ERR_PARAM; |
| 2136 | goto err_out; | 2162 | goto err_out; |
| 2137 | } | 2163 | } |
| @@ -2219,7 +2245,7 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) · 81 unmodified lines | |||
| 2219 | struct i40e_vsi *vsi; | 2245 | struct i40e_vsi *vsi; |
| 2220 | u16 num_qps_all = 0; | 2246 | u16 num_qps_all = 0; |
| 2221 | 2247 | ||
| 2222 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 2248 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 2223 | aq_ret = I40E_ERR_PARAM; | 2249 | aq_ret = I40E_ERR_PARAM; |
| 2224 | goto error_param; | 2250 | goto error_param; |
| 2225 | } | 2251 | } |
| @@ -2368,7 +2394,7 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg) · 142 unmodified lines | |||
| 2368 | i40e_status aq_ret = 0; | 2394 | i40e_status aq_ret = 0; |
| 2369 | int i; | 2395 | int i; |
| 2370 | 2396 | ||
| 2371 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 2397 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 2372 | aq_ret = I40E_ERR_PARAM; | 2398 | aq_ret = I40E_ERR_PARAM; |
| 2373 | goto error_param; | 2399 | goto error_param; |
| 2374 | } | 2400 | } |
| @@ -2540,7 +2566,7 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg) · 165 unmodified lines | |||
| 2540 | struct i40e_pf *pf = vf->pf; | 2566 | struct i40e_pf *pf = vf->pf; |
| 2541 | i40e_status aq_ret = 0; | 2567 | i40e_status aq_ret = 0; |
| 2542 | 2568 | ||
| 2543 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 2569 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 2544 | aq_ret = I40E_ERR_PARAM; | 2570 | aq_ret = I40E_ERR_PARAM; |
| 2545 | goto error_param; | 2571 | goto error_param; |
| 2546 | } | 2572 | } |
| @@ -2590,7 +2616,7 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg) · 43 unmodified lines | |||
| 2590 | u8 cur_pairs = vf->num_queue_pairs; | 2616 | u8 cur_pairs = vf->num_queue_pairs; |
| 2591 | struct i40e_pf *pf = vf->pf; | 2617 | struct i40e_pf *pf = vf->pf; |
| 2592 | 2618 | ||
| 2593 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) | 2619 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) |
| 2594 | return -EINVAL; | 2620 | return -EINVAL; |
| 2595 | 2621 | ||
| 2596 | if (req_pairs > I40E_MAX_VF_QUEUES) { | 2622 | if (req_pairs > I40E_MAX_VF_QUEUES) { |
| @@ -2635,7 +2661,7 @@ static int i40e_vc_get_stats_msg(struct i40e_vf *vf, u8 *msg) · 38 unmodified lines | |||
| 2635 | 2661 | ||
| 2636 | memset(&stats, 0, sizeof(struct i40e_eth_stats)); | 2662 | memset(&stats, 0, sizeof(struct i40e_eth_stats)); |
| 2637 | 2663 | ||
| 2638 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 2664 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 2639 | aq_ret = I40E_ERR_PARAM; | 2665 | aq_ret = I40E_ERR_PARAM; |
| 2640 | goto error_param; | 2666 | goto error_param; |
| 2641 | } | 2667 | } |
| @@ -2752,7 +2778,7 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg) · 110 unmodified lines | |||
| 2752 | i40e_status ret = 0; | 2778 | i40e_status ret = 0; |
| 2753 | int i; | 2779 | int i; |
| 2754 | 2780 | ||
| 2755 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | 2781 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || |
| 2756 | !i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) { | 2782 | !i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) { |
| 2757 | ret = I40E_ERR_PARAM; | 2783 | ret = I40E_ERR_PARAM; |
| 2758 | goto error_param; | 2784 | goto error_param; |
| @@ -2824,7 +2850,7 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg) · 65 unmodified lines | |||
| 2824 | i40e_status ret = 0; | 2850 | i40e_status ret = 0; |
| 2825 | int i; | 2851 | int i; |
| 2826 | 2852 | ||
| 2827 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | 2853 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || |
| 2828 | !i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) { | 2854 | !i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) { |
| 2829 | ret = I40E_ERR_PARAM; | 2855 | ret = I40E_ERR_PARAM; |
| 2830 | goto error_param; | 2856 | goto error_param; |
| @@ -2968,7 +2994,7 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg) · 137 unmodified lines | |||
| 2968 | i40e_status aq_ret = 0; | 2994 | i40e_status aq_ret = 0; |
| 2969 | int i; | 2995 | int i; |
| 2970 | 2996 | ||
| 2971 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | 2997 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || |
| 2972 | !i40e_vc_isvalid_vsi_id(vf, vfl->vsi_id)) { | 2998 | !i40e_vc_isvalid_vsi_id(vf, vfl->vsi_id)) { |
| 2973 | aq_ret = I40E_ERR_PARAM; | 2999 | aq_ret = I40E_ERR_PARAM; |
| 2974 | goto error_param; | 3000 | goto error_param; |
| @@ -3088,9 +3114,9 @@ static int i40e_vc_config_rss_key(struct i40e_vf *vf, u8 *msg) · 113 unmodified lines | |||
| 3088 | struct i40e_vsi *vsi = NULL; | 3114 | struct i40e_vsi *vsi = NULL; |
| 3089 | i40e_status aq_ret = 0; | 3115 | i40e_status aq_ret = 0; |
| 3090 | 3116 | ||
| 3091 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | 3117 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || |
| 3092 | !i40e_vc_isvalid_vsi_id(vf, vrk->vsi_id) || | 3118 | !i40e_vc_isvalid_vsi_id(vf, vrk->vsi_id) || |
| 3093 | (vrk->key_len != I40E_HKEY_ARRAY_SIZE)) { | 3119 | vrk->key_len != I40E_HKEY_ARRAY_SIZE) { |
| 3094 | aq_ret = I40E_ERR_PARAM; | 3120 | aq_ret = I40E_ERR_PARAM; |
| 3095 | goto err; | 3121 | goto err; |
| 3096 | } | 3122 | } |
| @@ -3119,9 +3145,9 @@ static int i40e_vc_config_rss_lut(struct i40e_vf *vf, u8 *msg) · 22 unmodified lines | |||
| 3119 | i40e_status aq_ret = 0; | 3145 | i40e_status aq_ret = 0; |
| 3120 | u16 i; | 3146 | u16 i; |
| 3121 | 3147 | ||
| 3122 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || | 3148 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || |
| 3123 | !i40e_vc_isvalid_vsi_id(vf, vrl->vsi_id) || | 3149 | !i40e_vc_isvalid_vsi_id(vf, vrl->vsi_id) || |
| 3124 | (vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE)) { | 3150 | vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE) { |
| 3125 | aq_ret = I40E_ERR_PARAM; | 3151 | aq_ret = I40E_ERR_PARAM; |
| 3126 | goto err; | 3152 | goto err; |
| 3127 | } | 3153 | } |
| @@ -3154,7 +3180,7 @@ static int i40e_vc_get_rss_hena(struct i40e_vf *vf, u8 *msg) · 26 unmodified lines | |||
| 3154 | i40e_status aq_ret = 0; | 3180 | i40e_status aq_ret = 0; |
| 3155 | int len = 0; | 3181 | int len = 0; |
| 3156 | 3182 | ||
| 3157 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 3183 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 3158 | aq_ret = I40E_ERR_PARAM; | 3184 | aq_ret = I40E_ERR_PARAM; |
| 3159 | goto err; | 3185 | goto err; |
| 3160 | } | 3186 | } |
| @@ -3190,7 +3216,7 @@ static int i40e_vc_set_rss_hena(struct i40e_vf *vf, u8 *msg) · 29 unmodified lines | |||
| 3190 | struct i40e_hw *hw = &pf->hw; | 3216 | struct i40e_hw *hw = &pf->hw; |
| 3191 | i40e_status aq_ret = 0; | 3217 | i40e_status aq_ret = 0; |
| 3192 | 3218 | ||
| 3193 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 3219 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 3194 | aq_ret = I40E_ERR_PARAM; | 3220 | aq_ret = I40E_ERR_PARAM; |
| 3195 | goto err; | 3221 | goto err; |
| 3196 | } | 3222 | } |
| @@ -3215,7 +3241,7 @@ static int i40e_vc_enable_vlan_stripping(struct i40e_vf *vf, u8 *msg) · 18 unmodified lines | |||
| 3215 | i40e_status aq_ret = 0; | 3241 | i40e_status aq_ret = 0; |
| 3216 | struct i40e_vsi *vsi; | 3242 | struct i40e_vsi *vsi; |
| 3217 | 3243 | ||
| 3218 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 3244 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 3219 | aq_ret = I40E_ERR_PARAM; | 3245 | aq_ret = I40E_ERR_PARAM; |
| 3220 | goto err; | 3246 | goto err; |
| 3221 | } | 3247 | } |
| @@ -3241,7 +3267,7 @@ static int i40e_vc_disable_vlan_stripping(struct i40e_vf *vf, u8 *msg) · 19 unmodified lines | |||
| 3241 | i40e_status aq_ret = 0; | 3267 | i40e_status aq_ret = 0; |
| 3242 | struct i40e_vsi *vsi; | 3268 | struct i40e_vsi *vsi; |
| 3243 | 3269 | ||
| 3244 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 3270 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 3245 | aq_ret = I40E_ERR_PARAM; | 3271 | aq_ret = I40E_ERR_PARAM; |
| 3246 | goto err; | 3272 | goto err; |
| 3247 | } | 3273 | } |
| @@ -3468,7 +3494,7 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg) · 220 unmodified lines | |||
| 3468 | i40e_status aq_ret = 0; | 3494 | i40e_status aq_ret = 0; |
| 3469 | int i, ret; | 3495 | int i, ret; |
| 3470 | 3496 | ||
| 3471 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 3497 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 3472 | aq_ret = I40E_ERR_PARAM; | 3498 | aq_ret = I40E_ERR_PARAM; |
| 3473 | goto err; | 3499 | goto err; |
| 3474 | } | 3500 | } |
| @@ -3599,7 +3625,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) · 124 unmodified lines | |||
| 3599 | i40e_status aq_ret = 0; | 3625 | i40e_status aq_ret = 0; |
| 3600 | int i, ret; | 3626 | int i, ret; |
| 3601 | 3627 | ||
| 3602 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 3628 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 3603 | aq_ret = I40E_ERR_PARAM; | 3629 | aq_ret = I40E_ERR_PARAM; |
| 3604 | goto err_out; | 3630 | goto err_out; |
| 3605 | } | 3631 | } |
| @@ -3708,7 +3734,7 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg) · 102 unmodified lines | |||
| 3708 | i40e_status aq_ret = 0; | 3734 | i40e_status aq_ret = 0; |
| 3709 | u64 speed = 0; | 3735 | u64 speed = 0; |
| 3710 | 3736 | ||
| 3711 | if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { | 3737 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 3712 | aq_ret = I40E_ERR_PARAM; | 3738 | aq_ret = I40E_ERR_PARAM; |
| 3713 | goto err; | 3739 | goto err; |
| 3714 | } | 3740 | } |
| @@ -3797,11 +3823,6 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg) · 82 unmodified lines | |||
| 3797 | 3823 | ||
| 3798 | /* set this flag only after making sure all inputs are sane */ | 3824 | /* set this flag only after making sure all inputs are sane */ |
| 3799 | vf->adq_enabled = true; | 3825 | vf->adq_enabled = true; |
| 3800 | /* num_req_queues is set when user changes number of queues via ethtool | ||
| 3801 | * and this causes issue for default VSI(which depends on this variable) | ||
| 3802 | * when ADq is enabled, hence reset it. | ||
| 3803 | */ | ||
| 3804 | vf->num_req_queues = 0; | ||
| 3805 | 3826 | ||
| 3806 | /* reset the VF in order to allocate resources */ | 3827 | /* reset the VF in order to allocate resources */ |
| 3807 | i40e_vc_reset_vf(vf, true); | 3828 | i40e_vc_reset_vf(vf, true); |
| @@ -3824,7 +3845,7 @@ static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg) · 16 unmodified lines | |||
| 3824 | struct i40e_pf *pf = vf->pf; | 3845 | struct i40e_pf *pf = vf->pf; |
| 3825 | i40e_status aq_ret = 0; | 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 | aq_ret = I40E_ERR_PARAM; | 3849 | aq_ret = I40E_ERR_PARAM; |
| 3829 | goto err; | 3850 | goto err; |
| 3830 | } | 3851 | } |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define I40E_MAX_VF_PROMISC_FLAGS 3 | 19 | #define I40E_MAX_VF_PROMISC_FLAGS 3 |
| 20 | 20 | ||
| 21 | #define I40E_VF_STATE_WAIT_COUNT 20 | ||
| 22 | |||
| 21 | /* Various queue ctrls */ | 23 | /* Various queue ctrls */ |
| 22 | enum i40e_queue_ctrl { | 24 | enum i40e_queue_ctrl { |
| 23 | I40E_QUEUE_CTRL_UNKNOWN = 0, | 25 | I40E_QUEUE_CTRL_UNKNOWN = 0, |
| @@ -615,23 +615,44 @@ static int iavf_set_ringparam(struct net_device *netdev, · 614 unmodified lines | |||
| 615 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 615 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
| 616 | return -EINVAL; | 616 | return -EINVAL; |
| 617 | 617 | ||
| 618 | new_tx_count = clamp_t(u32, ring->tx_pending, | 618 | if (ring->tx_pending > IAVF_MAX_TXD || |
| 619 | IAVF_MIN_TXD, | 619 | ring->tx_pending < IAVF_MIN_TXD || |
| 620 | IAVF_MAX_TXD); | 620 | ring->rx_pending > IAVF_MAX_RXD || |
| 621 | new_tx_count = ALIGN(new_tx_count, IAVF_REQ_DESCRIPTOR_MULTIPLE); | 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 | } | ||
| 622 | 627 | ||
| 623 | new_rx_count = clamp_t(u32, ring->rx_pending, | 628 | new_tx_count = ALIGN(ring->tx_pending, IAVF_REQ_DESCRIPTOR_MULTIPLE); |
| 624 | IAVF_MIN_RXD, | 629 | if (new_tx_count != ring->tx_pending) |
| 625 | IAVF_MAX_RXD); | 630 | netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n", |
| 626 | new_rx_count = ALIGN(new_rx_count, IAVF_REQ_DESCRIPTOR_MULTIPLE); | 631 | new_tx_count); |
| 632 | |||
| 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); | ||
| 627 | 637 | ||
| 628 | /* if nothing to do return success */ | 638 | /* if nothing to do return success */ |
| 629 | if ((new_tx_count == adapter->tx_desc_count) && | 639 | if ((new_tx_count == adapter->tx_desc_count) && |
| 630 | (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"); | ||
| 631 | return 0; | 642 | return 0; |
| 643 | } | ||
| 632 | 644 | ||
| 633 | adapter->tx_desc_count = new_tx_count; | 645 | if (new_tx_count != adapter->tx_desc_count) { |
| 634 | adapter->rx_desc_count = new_rx_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 | } | ||
| 650 | |||
| 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 | } | ||
| 635 | 656 | ||
| 636 | if (netif_running(netdev)) { | 657 | if (netif_running(netdev)) { |
| 637 | adapter->flags |= IAVF_FLAG_RESET_NEEDED; | 658 | adapter->flags |= IAVF_FLAG_RESET_NEEDED; |
| @@ -2248,6 +2248,7 @@ static void iavf_reset_task(struct work_struct *work) · 2247 unmodified lines | |||
| 2248 | } | 2248 | } |
| 2249 | 2249 | ||
| 2250 | pci_set_master(adapter->pdev); | 2250 | pci_set_master(adapter->pdev); |
| 2251 | pci_restore_msi_state(adapter->pdev); | ||
| 2251 | 2252 | ||
| 2252 | if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) { | 2253 | if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) { |
| 2253 | dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n", | 2254 | dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n", |
| @@ -97,6 +97,9 @@ static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets) · 96 unmodified lines | |||
| 97 | 97 | ||
| 98 | new_cfg->etscfg.maxtcs = pf->hw.func_caps.common_cap.maxtc; | 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 | if (!bwrec) | 103 | if (!bwrec) |
| 101 | new_cfg->etsrec.tcbwtable[0] = 100; | 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 | if (mode == pf->dcbx_cap) | 170 | if (mode == pf->dcbx_cap) |
| 168 | return ICE_DCB_NO_HW_CHG; | 171 | return ICE_DCB_NO_HW_CHG; |
| 169 | 172 | ||
| 170 | pf->dcbx_cap = mode; | ||
| 171 | qos_cfg = &pf->hw.port_info->qos_cfg; | 173 | qos_cfg = &pf->hw.port_info->qos_cfg; |
| 172 | if (mode & DCB_CAP_DCBX_VER_CEE) { | 174 | |
| 173 | if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP) | 175 | /* DSCP configuration is not DCBx negotiated */ |
| 174 | return ICE_DCB_NO_HW_CHG; | 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 | qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE; | 182 | qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE; |
| 176 | } else { | 183 | else |
| 177 | qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE; | 184 | qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE; |
| 178 | } | ||
| 179 | 185 | ||
| 180 | dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode); | 186 | dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode); |
| 181 | return ICE_DCB_HW_CHG_RST; | 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 | bool is_tun = tun == ICE_FD_HW_SEG_TUN; | 1268 | bool is_tun = tun == ICE_FD_HW_SEG_TUN; |
| 1269 | int err; | 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 | continue; | 1272 | continue; |
| 1273 | err = ice_fdir_write_fltr(pf, input, add, is_tun); | 1273 | err = ice_fdir_write_fltr(pf, input, add, is_tun); |
| 1274 | if (err) | 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 | /* return error if not an update and no available filters */ | 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 | if (!ice_fdir_find_fltr_by_idx(hw, fsp->location) && | 1656 | if (!ice_fdir_find_fltr_by_idx(hw, fsp->location) && |
| 1657 | ice_fdir_num_avail_fltr(hw, pf->vsi[vsi->idx]) < fltrs_needed) { | 1657 | ice_fdir_num_avail_fltr(hw, pf->vsi[vsi->idx]) < fltrs_needed) { |
| 1658 | dev_err(dev, "Failed to add filter. The maximum number of flow director filters has been reached.\n"); | 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 | memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len); | 924 | memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len); |
| 925 | loc = pkt; | 925 | loc = pkt; |
| 926 | } else { | 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 | return ICE_ERR_DOES_NOT_EXIST; | 928 | return ICE_ERR_DOES_NOT_EXIST; |
| 929 | if (!ice_fdir_pkt[idx].tun_pkt) | 929 | if (!ice_fdir_pkt[idx].tun_pkt) |
| 930 | return ICE_ERR_PARAM; | 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 | * ice_get_open_tunnel_port - retrieve an open tunnel port | 1899 | * ice_get_open_tunnel_port - retrieve an open tunnel port |
| 1900 | * @hw: pointer to the HW structure | 1900 | * @hw: pointer to the HW structure |
| 1901 | * @port: returns open port | 1901 | * @port: returns open port |
| 1902 | * @type: type of tunnel, can be TNL_LAST if it doesn't matter | ||
| 1902 | */ | 1903 | */ |
| 1903 | bool | 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 | bool res = false; | 1908 | bool res = false; |
| 1907 | u16 i; | 1909 | u16 i; |
| @@ -1909,7 +1911,8 @@ ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port) · 1 unmodified line | |||
| 1909 | mutex_lock(&hw->tnl_lock); | 1911 | mutex_lock(&hw->tnl_lock); |
| 1910 | 1912 | ||
| 1911 | for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) | 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 | *port = hw->tnl.tbl[i].port; | 1916 | *port = hw->tnl.tbl[i].port; |
| 1914 | res = true; | 1917 | res = true; |
| 1915 | break; | 1918 | break; |
| @@ -33,7 +33,8 @@ enum ice_status · 32 unmodified lines | |||
| 33 | ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, | 33 | ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, |
| 34 | unsigned long *bm, struct list_head *fv_list); | 34 | unsigned long *bm, struct list_head *fv_list); |
| 35 | bool | 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 | int ice_udp_tunnel_set_port(struct net_device *netdev, unsigned int table, | 38 | int ice_udp_tunnel_set_port(struct net_device *netdev, unsigned int table, |
| 38 | unsigned int idx, struct udp_tunnel_info *ti); | 39 | unsigned int idx, struct udp_tunnel_info *ti); |
| 39 | int ice_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table, | 40 | int ice_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table, |
| @@ -5881,6 +5881,9 @@ static int ice_up_complete(struct ice_vsi *vsi) · 5880 unmodified lines | |||
| 5881 | netif_carrier_on(vsi->netdev); | 5881 | netif_carrier_on(vsi->netdev); |
| 5882 | } | 5882 | } |
| 5883 | 5883 | ||
| 5884 | /* clear this now, and the first stats read will be used as baseline */ | ||
| 5885 | vsi->stat_offsets_loaded = false; | ||
| 5886 | |||
| 5884 | ice_service_task_schedule(pf); | 5887 | ice_service_task_schedule(pf); |
| 5885 | 5888 | ||
| 5886 | return 0; | 5889 | return 0; |
| @@ -5927,14 +5930,15 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp, struct ice_q_stats st · 40 unmodified lines | |||
| 5927 | /** | 5930 | /** |
| 5928 | * ice_update_vsi_tx_ring_stats - Update VSI Tx ring stats counters | 5931 | * ice_update_vsi_tx_ring_stats - Update VSI Tx ring stats counters |
| 5929 | * @vsi: the VSI to be updated | 5932 | * @vsi: the VSI to be updated |
| 5933 | * @vsi_stats: the stats struct to be updated | ||
| 5930 | * @rings: rings to work on | 5934 | * @rings: rings to work on |
| 5931 | * @count: number of rings | 5935 | * @count: number of rings |
| 5932 | */ | 5936 | */ |
| 5933 | static void | 5937 | static void |
| 5934 | ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings, | 5938 | ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, |
| 5935 | u16 count) | 5939 | struct rtnl_link_stats64 *vsi_stats, |
| 5940 | struct ice_tx_ring **rings, u16 count) | ||
| 5936 | { | 5941 | { |
| 5937 | struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats; | ||
| 5938 | u16 i; | 5942 | u16 i; |
| 5939 | 5943 | ||
| 5940 | for (i = 0; i < count; i++) { | 5944 | for (i = 0; i < count; i++) { |
| @@ -5958,15 +5962,13 @@ ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings, · 17 unmodified lines | |||
| 5958 | */ | 5962 | */ |
| 5959 | static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) | 5963 | static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) |
| 5960 | { | 5964 | { |
| 5961 | struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats; | 5965 | struct rtnl_link_stats64 *vsi_stats; |
| 5962 | u64 pkts, bytes; | 5966 | u64 pkts, bytes; |
| 5963 | int i; | 5967 | int i; |
| 5964 | 5968 | ||
| 5965 | /* reset netdev stats */ | 5969 | vsi_stats = kzalloc(sizeof(*vsi_stats), GFP_ATOMIC); |
| 5966 | vsi_stats->tx_packets = 0; | 5970 | if (!vsi_stats) |
| 5967 | vsi_stats->tx_bytes = 0; | 5971 | return; |
| 5968 | vsi_stats->rx_packets = 0; | ||
| 5969 | vsi_stats->rx_bytes = 0; | ||
| 5970 | 5972 | ||
| 5971 | /* reset non-netdev (extended) stats */ | 5973 | /* reset non-netdev (extended) stats */ |
| 5972 | vsi->tx_restart = 0; | 5974 | vsi->tx_restart = 0; |
| @@ -5978,7 +5980,8 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) · 5 unmodified lines | |||
| 5978 | rcu_read_lock(); | 5980 | rcu_read_lock(); |
| 5979 | 5981 | ||
| 5980 | /* update Tx rings counters */ | 5982 | /* update Tx rings counters */ |
| 5981 | 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); | ||
| 5982 | 5985 | ||
| 5983 | /* update Rx rings counters */ | 5986 | /* update Rx rings counters */ |
| 5984 | ice_for_each_rxq(vsi, i) { | 5987 | ice_for_each_rxq(vsi, i) { |
| @@ -5993,10 +5996,17 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) · 8 unmodified lines | |||
| 5993 | 5996 | ||
| 5994 | /* update XDP Tx rings counters */ | 5997 | /* update XDP Tx rings counters */ |
| 5995 | if (ice_is_xdp_ena_vsi(vsi)) | 5998 | if (ice_is_xdp_ena_vsi(vsi)) |
| 5996 | ice_update_vsi_tx_ring_stats(vsi, vsi->xdp_rings, | 5999 | ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->xdp_rings, |
| 5997 | vsi->num_xdp_txq); | 6000 | vsi->num_xdp_txq); |
| 5998 | 6001 | ||
| 5999 | rcu_read_unlock(); | 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); | ||
| 6000 | } | 6010 | } |
| 6001 | 6011 | ||
| 6002 | /** | 6012 | /** |
| @@ -3796,10 +3796,13 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { · 3795 unmodified lines | |||
| 3796 | * ice_find_recp - find a recipe | 3796 | * ice_find_recp - find a recipe |
| 3797 | * @hw: pointer to the hardware structure | 3797 | * @hw: pointer to the hardware structure |
| 3798 | * @lkup_exts: extension sequence to match | 3798 | * @lkup_exts: extension sequence to match |
| 3799 | * @tun_type: type of recipe tunnel | ||
| 3799 | * | 3800 | * |
| 3800 | * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found. | 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 | bool refresh_required = true; | 3807 | bool refresh_required = true; |
| 3805 | struct ice_sw_recipe *recp; | 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 | /* If for "i"th recipe the found was never set to false | 3864 | /* If for "i"th recipe the found was never set to false |
| 3862 | * then it means we found our match | 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 | return i; /* Return the recipe ID */ | 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 | /* Look for a recipe which matches our requested fv / mask list */ | 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 | if (*rid < ICE_MAX_NUM_RECIPES) | 4659 | if (*rid < ICE_MAX_NUM_RECIPES) |
| 4656 | /* Success if found a recipe that match the existing criteria */ | 4660 | /* Success if found a recipe that match the existing criteria */ |
| 4657 | goto err_unroll; | 4661 | goto err_unroll; |
| 4658 | 4662 | ||
| 4663 | rm->tun_type = rinfo->tun_type; | ||
| 4659 | /* Recipe we need does not exist, add a recipe */ | 4664 | /* Recipe we need does not exist, add a recipe */ |
| 4660 | status = ice_add_sw_recipe(hw, rm, profiles); | 4665 | status = ice_add_sw_recipe(hw, rm, profiles); |
| 4661 | if (status) | 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 | switch (tun_type) { | 4964 | switch (tun_type) { |
| 4960 | case ICE_SW_TUN_VXLAN: | 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 | case ICE_SW_TUN_GENEVE: | 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 | return ICE_ERR_CFG; | 4971 | return ICE_ERR_CFG; |
| 4964 | break; | 4972 | break; |
| 4965 | |||
| 4966 | default: | 4973 | default: |
| 4967 | /* Nothing needs to be done for this tunnel type */ | 4974 | /* Nothing needs to be done for this tunnel type */ |
| 4968 | return 0; | 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 | if (status) | 5562 | if (status) |
| 5556 | return status; | 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 | /* If did not find a recipe that match the existing criteria */ | 5566 | /* If did not find a recipe that match the existing criteria */ |
| 5560 | if (rid == ICE_MAX_NUM_RECIPES) | 5567 | if (rid == ICE_MAX_NUM_RECIPES) |
| 5561 | return ICE_ERR_PARAM; | 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 | return inner ? ICE_IPV6_IL : ICE_IPV6_OFOS; | 74 | return inner ? ICE_IPV6_IL : ICE_IPV6_OFOS; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | static enum ice_protocol_type | 77 | static enum ice_protocol_type ice_proto_type_from_l4_port(u16 ip_proto) |
| 78 | ice_proto_type_from_l4_port(bool inner, u16 ip_proto) | ||
| 79 | { | 78 | { |
| 80 | if (inner) { | 79 | switch (ip_proto) { |
| 81 | switch (ip_proto) { | 80 | case IPPROTO_TCP: |
| 82 | case IPPROTO_UDP: | 81 | return ICE_TCP_IL; |
| 83 | return ICE_UDP_ILOS; | 82 | case IPPROTO_UDP: |
| 84 | } | 83 | return ICE_UDP_ILOS; |
| 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 | } | ||
| 92 | } | 84 | } |
| 93 | 85 | ||
| 94 | return 0; | 86 | return 0; |
| @@ -191,8 +183,9 @@ ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr, · 96 unmodified lines | |||
| 191 | i++; | 183 | i++; |
| 192 | } | 184 | } |
| 193 | 185 | ||
| 194 | if (flags & ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT) { | 186 | 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); | 187 | hdr->l3_key.ip_proto == IPPROTO_UDP) { |
| 188 | list[i].type = ICE_UDP_OF; | ||
| 196 | list[i].h_u.l4_hdr.dst_port = hdr->l4_key.dst_port; | 189 | list[i].h_u.l4_hdr.dst_port = hdr->l4_key.dst_port; |
| 197 | list[i].m_u.l4_hdr.dst_port = hdr->l4_mask.dst_port; | 190 | list[i].m_u.l4_hdr.dst_port = hdr->l4_mask.dst_port; |
| 198 | i++; | 191 | i++; |
| @@ -317,7 +310,7 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags, · 118 unmodified lines | |||
| 317 | ICE_TC_FLWR_FIELD_SRC_L4_PORT)) { | 310 | ICE_TC_FLWR_FIELD_SRC_L4_PORT)) { |
| 318 | struct ice_tc_l4_hdr *l4_key, *l4_mask; | 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 | l4_key = &headers->l4_key; | 314 | l4_key = &headers->l4_key; |
| 322 | l4_mask = &headers->l4_mask; | 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 | headers->l3_mask.ttl = match.mask->ttl; | 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 | struct flow_match_ports match; | 800 | struct flow_match_ports match; |
| 807 | 801 | ||
| 808 | flow_rule_match_enc_ports(rule, &match); | 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 | ice_vc_set_default_allowlist(vf); | 1617 | ice_vc_set_default_allowlist(vf); |
| 1618 | 1618 | ||
| 1619 | ice_vf_fdir_exit(vf); | 1619 | ice_vf_fdir_exit(vf); |
| 1620 | ice_vf_fdir_init(vf); | ||
| 1620 | /* clean VF control VSI when resetting VFs since it should be | 1621 | /* clean VF control VSI when resetting VFs since it should be |
| 1621 | * setup only when VF creates its first FDIR rule. | 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 | ice_vf_fdir_exit(vf); | 1750 | ice_vf_fdir_exit(vf); |
| 1751 | ice_vf_fdir_init(vf); | ||
| 1750 | /* clean VF control VSI when resetting VF since it should be setup | 1752 | /* clean VF control VSI when resetting VF since it should be setup |
| 1751 | * only when VF creates its first FDIR rule. | 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 | if (ret) | 2023 | if (ret) |
| 2022 | goto err_unroll_sriov; | 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 | return 0; | 2030 | return 0; |
| 2025 | 2031 | ||
| 2026 | err_unroll_sriov: | 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 | while (i--) { | 383 | while (i--) { |
| 384 | dma = xsk_buff_xdp_get_dma(*xdp); | 384 | dma = xsk_buff_xdp_get_dma(*xdp); |
| 385 | rx_desc->read.pkt_addr = cpu_to_le64(dma); | 385 | rx_desc->read.pkt_addr = cpu_to_le64(dma); |
| 386 | rx_desc->wb.status_error0 = 0; | ||
| 386 | 387 | ||
| 387 | rx_desc++; | 388 | rx_desc++; |
| 388 | xdp++; | 389 | xdp++; |
| @@ -2960,11 +2960,11 @@ static int mvpp2_rxq_init(struct mvpp2_port *port, · 2959 unmodified lines | |||
| 2960 | mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size); | 2960 | mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size); |
| 2961 | 2961 | ||
| 2962 | if (priv->percpu_pools) { | 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 | if (err < 0) | 2964 | if (err < 0) |
| 2965 | goto err_free_dma; | 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 | if (err < 0) | 2968 | if (err < 0) |
| 2969 | goto err_unregister_rxq_short; | 2969 | goto err_unregister_rxq_short; |
| 2970 | 2970 | ||
| @@ -7458,7 +7458,7 @@ static int mvpp2_probe(struct platform_device *pdev) · 4487 unmodified lines | |||
| 7458 | 7458 | ||
| 7459 | shared = num_present_cpus() - priv->nthreads; | 7459 | shared = num_present_cpus() - priv->nthreads; |
| 7460 | if (shared > 0) | 7460 | if (shared > 0) |
| 7461 | bitmap_fill(&priv->lock_map, | 7461 | bitmap_set(&priv->lock_map, 0, |
| 7462 | min_t(int, shared, MVPP2_MAX_THREADS)); | 7462 | min_t(int, shared, MVPP2_MAX_THREADS)); |
| 7463 | 7463 | ||
| 7464 | for (i = 0; i < MVPP2_MAX_THREADS; i++) { | 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 | goto free_regions; | 2341 | goto free_regions; |
| 2342 | break; | 2342 | break; |
| 2343 | default: | 2343 | default: |
| 2344 | return err; | 2344 | goto free_regions; |
| 2345 | } | 2345 | } |
| 2346 | 2346 | ||
| 2347 | mw->mbox_wq = alloc_workqueue(name, | 2347 | mw->mbox_wq = alloc_workqueue(name, |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | |||
| 5 | * | 5 | * |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <linux/module.h> | ||
| 9 | |||
| 8 | #include "otx2_common.h" | 10 | #include "otx2_common.h" |
| 9 | #include "otx2_ptp.h" | 11 | #include "otx2_ptp.h" |
| 10 | 12 | ||
| @@ -670,7 +670,7 @@ void __init mlx4_en_init_ptys2ethtool_map(void) · 669 unmodified lines | |||
| 670 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_T, SPEED_1000, | 670 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_T, SPEED_1000, |
| 671 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT); | 671 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT); |
| 672 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_CX_SGMII, SPEED_1000, | 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 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_KX, SPEED_1000, | 674 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_KX, SPEED_1000, |
| 675 | ETHTOOL_LINK_MODE_1000baseKX_Full_BIT); | 675 | ETHTOOL_LINK_MODE_1000baseKX_Full_BIT); |
| 676 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_T, SPEED_10000, | 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 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KR, SPEED_10000, | 682 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KR, SPEED_10000, |
| 683 | ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); | 683 | ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); |
| 684 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CR, SPEED_10000, | 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 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_SR, SPEED_10000, | 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 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_20GBASE_KR2, SPEED_20000, | 688 | MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_20GBASE_KR2, SPEED_20000, |
| 689 | ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, | 689 | ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, |
| 690 | ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT); | 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 | bool carry_xdp_prog) | 2286 | bool carry_xdp_prog) |
| 2287 | { | 2287 | { |
| 2288 | struct bpf_prog *xdp_prog; | 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 | if (mlx4_en_alloc_resources(tmp)) { | 2298 | if (mlx4_en_alloc_resources(tmp)) { |
| 2294 | en_warn(priv, | 2299 | en_warn(priv, |
| @@ -341,6 +341,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, · 340 unmodified lines | |||
| 341 | case MLX5_CMD_OP_DEALLOC_SF: | 341 | case MLX5_CMD_OP_DEALLOC_SF: |
| 342 | case MLX5_CMD_OP_DESTROY_UCTX: | 342 | case MLX5_CMD_OP_DESTROY_UCTX: |
| 343 | case MLX5_CMD_OP_DESTROY_UMEM: | 343 | case MLX5_CMD_OP_DESTROY_UMEM: |
| 344 | case MLX5_CMD_OP_MODIFY_RQT: | ||
| 344 | return MLX5_CMD_STAT_OK; | 345 | return MLX5_CMD_STAT_OK; |
| 345 | 346 | ||
| 346 | case MLX5_CMD_OP_QUERY_HCA_CAP: | 347 | case MLX5_CMD_OP_QUERY_HCA_CAP: |
| @@ -446,7 +447,6 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, · 99 unmodified lines | |||
| 446 | case MLX5_CMD_OP_MODIFY_TIS: | 447 | case MLX5_CMD_OP_MODIFY_TIS: |
| 447 | case MLX5_CMD_OP_QUERY_TIS: | 448 | case MLX5_CMD_OP_QUERY_TIS: |
| 448 | case MLX5_CMD_OP_CREATE_RQT: | 449 | case MLX5_CMD_OP_CREATE_RQT: |
| 449 | case MLX5_CMD_OP_MODIFY_RQT: | ||
| 450 | case MLX5_CMD_OP_QUERY_RQT: | 450 | case MLX5_CMD_OP_QUERY_RQT: |
| 451 | 451 | ||
| 452 | case MLX5_CMD_OP_CREATE_FLOW_TABLE: | 452 | case MLX5_CMD_OP_CREATE_FLOW_TABLE: |
| @@ -13,6 +13,9 @@ struct mlx5e_rx_res { · 12 unmodified lines | |||
| 13 | unsigned int max_nch; | 13 | unsigned int max_nch; |
| 14 | u32 drop_rqn; | 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 | struct mlx5e_rss *rss[MLX5E_MAX_NUM_RSS]; | 19 | struct mlx5e_rss *rss[MLX5E_MAX_NUM_RSS]; |
| 17 | bool rss_active; | 20 | bool rss_active; |
| 18 | u32 rss_rqns[MLX5E_INDIR_RQT_SIZE]; | 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 | if (err) | 395 | if (err) |
| 393 | goto out; | 396 | goto out; |
| 394 | 397 | ||
| 398 | /* Separated from the channels RQs, does not share pkt_merge state with them */ | ||
| 395 | mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, | 399 | mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, |
| 396 | mlx5e_rqt_get_rqtn(&res->ptp.rqt), | 400 | mlx5e_rqt_get_rqtn(&res->ptp.rqt), |
| 397 | inner_ft_support); | 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 | res->max_nch = max_nch; | 451 | res->max_nch = max_nch; |
| 448 | res->drop_rqn = drop_rqn; | 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 | err = mlx5e_rx_res_rss_init_def(res, init_pkt_merge_param, init_nch); | 457 | err = mlx5e_rx_res_rss_init_def(res, init_pkt_merge_param, init_nch); |
| 451 | if (err) | 458 | if (err) |
| 452 | goto err_out; | 459 | goto err_out; |
| @@ -513,7 +520,7 @@ u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res) · 60 unmodified lines | |||
| 513 | return mlx5e_tir_get_tirn(&res->ptp.tir); | 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 | return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt); | 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 | if (!builder) | 663 | if (!builder) |
| 657 | return -ENOMEM; | 664 | return -ENOMEM; |
| 658 | 665 | ||
| 666 | down_write(&res->pkt_merge_param_sem); | ||
| 667 | res->pkt_merge_param = *pkt_merge_param; | ||
| 668 | |||
| 659 | mlx5e_tir_builder_build_packet_merge(builder, pkt_merge_param); | 669 | mlx5e_tir_builder_build_packet_merge(builder, pkt_merge_param); |
| 660 | 670 | ||
| 661 | final_err = 0; | 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 | mlx5e_tir_builder_free(builder); | 695 | mlx5e_tir_builder_free(builder); |
| 685 | return final_err; | 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 | return mlx5e_rss_get_hash(res->rss[0]); | 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 | u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt); | 37 | u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt); |
| 38 | u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res); | 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 | /* Activate/deactivate API */ | 40 | /* Activate/deactivate API */ |
| 44 | void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs); | 41 | void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs); |
| 45 | void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res); | 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 | /* Workaround for hairpin */ | 66 | /* Workaround for hairpin */ |
| 70 | struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res); | 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 | #endif /* __MLX5_EN_RX_RES_H__ */ | 72 | #endif /* __MLX5_EN_RX_RES_H__ */ |
| @@ -191,7 +191,7 @@ static void mlx5e_ipsec_set_swp(struct sk_buff *skb, · 190 unmodified lines | |||
| 191 | eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2; | 191 | eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2; |
| 192 | eseg->swp_inner_l4_offset = | 192 | eseg->swp_inner_l4_offset = |
| 193 | (skb->csum_start + skb->head - skb->data) / 2; | 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 | eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6; | 195 | eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6; |
| 196 | break; | 196 | break; |
| 197 | default: | 197 | default: |
| @@ -100,25 +100,6 @@ mlx5e_ktls_rx_resync_create_resp_list(void) · 99 unmodified lines | |||
| 100 | return resp_list; | 100 | return resp_list; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static int mlx5e_ktls_create_tir(struct mlx5_core_dev *mdev, struct mlx5e_tir *tir, u32 rqtn) | ||
| 104 | { | ||
| 105 | struct mlx5e_tir_builder *builder; | ||
| 106 | int err; | ||
| 107 | |||
| 108 | builder = mlx5e_tir_builder_alloc(false); | ||
| 109 | if (!builder) | ||
| 110 | return -ENOMEM; | ||
| 111 | |||
| 112 | mlx5e_tir_builder_build_rqt(builder, mdev->mlx5e_res.hw_objs.td.tdn, rqtn, false); | ||
| 113 | mlx5e_tir_builder_build_direct(builder); | ||
| 114 | mlx5e_tir_builder_build_tls(builder); | ||
| 115 | err = mlx5e_tir_init(tir, builder, mdev, false); | ||
| 116 | |||
| 117 | mlx5e_tir_builder_free(builder); | ||
| 118 | |||
| 119 | return err; | ||
| 120 | } | ||
| 121 | |||
| 122 | static void accel_rule_handle_work(struct work_struct *work) | 103 | static void accel_rule_handle_work(struct work_struct *work) |
| 123 | { | 104 | { |
| 124 | struct mlx5e_ktls_offload_context_rx *priv_rx; | 105 | struct mlx5e_ktls_offload_context_rx *priv_rx; |
| @@ -609,7 +590,6 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk, · 484 unmodified lines | |||
| 609 | struct mlx5_core_dev *mdev; | 590 | struct mlx5_core_dev *mdev; |
| 610 | struct mlx5e_priv *priv; | 591 | struct mlx5e_priv *priv; |
| 611 | int rxq, err; | 592 | int rxq, err; |
| 612 | u32 rqtn; | ||
| 613 | 593 | ||
| 614 | tls_ctx = tls_get_ctx(sk); | 594 | tls_ctx = tls_get_ctx(sk); |
| 615 | priv = netdev_priv(netdev); | 595 | priv = netdev_priv(netdev); |
| @@ -635,9 +615,7 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk, · 19 unmodified lines | |||
| 635 | priv_rx->sw_stats = &priv->tls->sw_stats; | 615 | priv_rx->sw_stats = &priv->tls->sw_stats; |
| 636 | mlx5e_set_ktls_rx_priv_ctx(tls_ctx, priv_rx); | 616 | mlx5e_set_ktls_rx_priv_ctx(tls_ctx, priv_rx); |
| 637 | 617 | ||
| 638 | rqtn = mlx5e_rx_res_get_rqtn_direct(priv->rx_res, rxq); | 618 | err = mlx5e_rx_res_tls_tir_create(priv->rx_res, rxq, &priv_rx->tir); |
| 639 | |||
| 640 | err = mlx5e_ktls_create_tir(mdev, &priv_rx->tir, rqtn); | ||
| 641 | if (err) | 619 | if (err) |
| 642 | goto err_create_tir; | 620 | goto err_create_tir; |
| 643 | 621 | ||
| @@ -1080,6 +1080,10 @@ static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = { · 1079 unmodified lines | |||
| 1080 | &MLX5E_STATS_GRP(pme), | 1080 | &MLX5E_STATS_GRP(pme), |
| 1081 | &MLX5E_STATS_GRP(channels), | 1081 | &MLX5E_STATS_GRP(channels), |
| 1082 | &MLX5E_STATS_GRP(per_port_buff_congest), | 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 | static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv) | 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 | u16 klm_entries, u16 index) | 543 | u16 klm_entries, u16 index) |
| 544 | { | 544 | { |
| 545 | struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; | 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 | u32 lkey = rq->mdev->mlx5e_res.hw_objs.mkey; | 547 | u32 lkey = rq->mdev->mlx5e_res.hw_objs.mkey; |
| 548 | struct page *page = shampo->last_page; | 548 | struct page *page = shampo->last_page; |
| 549 | u64 addr = shampo->last_addr; | 549 | u64 addr = shampo->last_addr; |
| 550 | struct mlx5e_dma_info *dma_info; | 550 | struct mlx5e_dma_info *dma_info; |
| 551 | struct mlx5e_umr_wqe *umr_wqe; | 551 | struct mlx5e_umr_wqe *umr_wqe; |
| 552 | int headroom; | 552 | int headroom, i; |
| 553 | 553 | ||
| 554 | headroom = rq->buff.headroom; | 554 | headroom = rq->buff.headroom; |
| 555 | new_entries = klm_entries - (shampo->pi & (MLX5_UMR_KLM_ALIGNMENT - 1)); | 555 | new_entries = klm_entries - (shampo->pi & (MLX5_UMR_KLM_ALIGNMENT - 1)); |
| @@ -601,9 +601,7 @@ update_klm: · 45 unmodified lines | |||
| 601 | 601 | ||
| 602 | err_unmap: | 602 | err_unmap: |
| 603 | while (--i >= 0) { | 603 | while (--i >= 0) { |
| 604 | if (--index < 0) | 604 | dma_info = &shampo->info[--index]; |
| 605 | index = shampo->hd_per_wq - 1; | ||
| 606 | dma_info = &shampo->info[index]; | ||
| 607 | if (!(i & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1))) { | 605 | if (!(i & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1))) { |
| 608 | dma_info->addr = ALIGN_DOWN(dma_info->addr, PAGE_SIZE); | 606 | dma_info->addr = ALIGN_DOWN(dma_info->addr, PAGE_SIZE); |
| 609 | mlx5e_page_release(rq, dma_info, true); | 607 | mlx5e_page_release(rq, dma_info, true); |
| @@ -130,7 +130,7 @@ static u32 esw_qos_calculate_min_rate_divider(struct mlx5_eswitch *esw, · 129 unmodified lines | |||
| 130 | /* If vports min rate divider is 0 but their group has bw_share configured, then | 130 | /* If vports min rate divider is 0 but their group has bw_share configured, then |
| 131 | * need to set bw_share for vports to minimal value. | 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 | return 1; | 134 | return 1; |
| 135 | return 0; | 135 | return 0; |
| 136 | } | 136 | } |
| @@ -423,7 +423,7 @@ static int esw_qos_vport_update_group(struct mlx5_eswitch *esw, · 286 unmodified lines | |||
| 423 | return err; | 423 | return err; |
| 424 | 424 | ||
| 425 | /* Recalculate bw share weights of old and new groups */ | 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 | esw_qos_normalize_vports_min_rate(esw, curr_group, extack); | 427 | esw_qos_normalize_vports_min_rate(esw, curr_group, extack); |
| 428 | esw_qos_normalize_vports_min_rate(esw, new_group, extack); | 428 | esw_qos_normalize_vports_min_rate(esw, new_group, extack); |
| 429 | } | 429 | } |
| @@ -329,14 +329,25 @@ static bool · 328 unmodified lines | |||
| 329 | esw_is_indir_table(struct mlx5_eswitch *esw, struct mlx5_flow_attr *attr) | 329 | esw_is_indir_table(struct mlx5_eswitch *esw, struct mlx5_flow_attr *attr) |
| 330 | { | 330 | { |
| 331 | struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr; | 331 | struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr; |
| 332 | bool result = false; | ||
| 332 | int i; | 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 | if (esw_attr->dests[i].rep && | 341 | if (esw_attr->dests[i].rep && |
| 336 | mlx5_esw_indir_table_needed(esw, attr, esw_attr->dests[i].rep->vport, | 342 | mlx5_esw_indir_table_needed(esw, attr, esw_attr->dests[i].rep->vport, |
| 337 | esw_attr->dests[i].mdev)) | 343 | esw_attr->dests[i].mdev)) { |
| 338 | return true; | 344 | result = true; |
| 339 | return false; | 345 | } else { |
| 346 | result = false; | ||
| 347 | break; | ||
| 348 | } | ||
| 349 | } | ||
| 350 | return result; | ||
| 340 | } | 351 | } |
| 341 | 352 | ||
| 342 | static int | 353 | static int |
| @@ -2512,6 +2523,7 @@ static int esw_set_master_egress_rule(struct mlx5_core_dev *master, · 2169 unmodified lines | |||
| 2512 | struct mlx5_eswitch *esw = master->priv.eswitch; | 2523 | struct mlx5_eswitch *esw = master->priv.eswitch; |
| 2513 | struct mlx5_flow_table_attr ft_attr = { | 2524 | struct mlx5_flow_table_attr ft_attr = { |
| 2514 | .max_fte = 1, .prio = 0, .level = 0, | 2525 | .max_fte = 1, .prio = 0, .level = 0, |
| 2526 | .flags = MLX5_FLOW_TABLE_OTHER_VPORT, | ||
| 2515 | }; | 2527 | }; |
| 2516 | struct mlx5_flow_namespace *egress_ns; | 2528 | struct mlx5_flow_namespace *egress_ns; |
| 2517 | struct mlx5_flow_table *acl; | 2529 | struct mlx5_flow_table *acl; |
| @@ -835,6 +835,9 @@ void mlx5_start_health_poll(struct mlx5_core_dev *dev) · 834 unmodified lines | |||
| 835 | 835 | ||
| 836 | health->timer.expires = jiffies + msecs_to_jiffies(poll_interval_ms); | 836 | health->timer.expires = jiffies + msecs_to_jiffies(poll_interval_ms); |
| 837 | add_timer(&health->timer); | 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 | void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health) | 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 | INIT_WORK(&health->fatal_report_work, mlx5_fw_fatal_reporter_err_work); | 905 | INIT_WORK(&health->fatal_report_work, mlx5_fw_fatal_reporter_err_work); |
| 903 | INIT_WORK(&health->report_work, mlx5_fw_reporter_err_work); | 906 | INIT_WORK(&health->report_work, mlx5_fw_reporter_err_work); |
| 904 | INIT_DELAYED_WORK(&health->update_fw_log_ts_work, mlx5_health_log_ts_update); | 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 | return 0; | 909 | return 0; |
| 909 | 910 | ||
| @@ -608,4 +608,5 @@ void mlx5_lag_port_sel_destroy(struct mlx5_lag *ldev) · 607 unmodified lines | |||
| 608 | if (port_sel->tunnel) | 608 | if (port_sel->tunnel) |
| 609 | mlx5_destroy_ttc_table(port_sel->inner.ttc); | 609 | mlx5_destroy_ttc_table(port_sel->inner.ttc); |
| 610 | mlx5_lag_destroy_definers(ldev); | 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 | dev->timeouts->to[type] = val; | 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 | int i; | 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 | tout_set(dev, tout_def_sw_val[i], i); | 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 | if (!dev->timeouts) | 45 | if (!dev->timeouts) |
| 46 | return -ENOMEM; | 46 | return -ENOMEM; |
| 47 | 47 | ||
| 48 | tout_set_def_val(dev); | ||
| 49 | return 0; | 48 | return 0; |
| 50 | } | 49 | } |
| 51 | 50 | ||
| @@ -34,6 +34,7 @@ int mlx5_tout_init(struct mlx5_core_dev *dev); · 33 unmodified lines | |||
| 34 | void mlx5_tout_cleanup(struct mlx5_core_dev *dev); | 34 | void mlx5_tout_cleanup(struct mlx5_core_dev *dev); |
| 35 | void mlx5_tout_query_iseg(struct mlx5_core_dev *dev); | 35 | void mlx5_tout_query_iseg(struct mlx5_core_dev *dev); |
| 36 | int mlx5_tout_query_dtor(struct mlx5_core_dev *dev); | 36 | int mlx5_tout_query_dtor(struct mlx5_core_dev *dev); |
| 37 | void mlx5_tout_set_def_val(struct mlx5_core_dev *dev); | ||
| 37 | u64 _mlx5_tout_ms(struct mlx5_core_dev *dev, enum mlx5_timeouts_types type); | 38 | u64 _mlx5_tout_ms(struct mlx5_core_dev *dev, enum mlx5_timeouts_types type); |
| 38 | 39 | ||
| 39 | #define mlx5_tout_ms(dev, type) _mlx5_tout_ms(dev, MLX5_TO_##type##_MS) | 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 | if (mlx5_core_is_pf(dev)) | 992 | if (mlx5_core_is_pf(dev)) |
| 993 | pcie_print_link_status(dev->pdev); | 993 | pcie_print_link_status(dev->pdev); |
| 994 | 994 | ||
| 995 | err = mlx5_tout_init(dev); | 995 | mlx5_tout_set_def_val(dev); |
| 996 | if (err) { | ||
| 997 | mlx5_core_err(dev, "Failed initializing timeouts, aborting\n"); | ||
| 998 | return err; | ||
| 999 | } | ||
| 1000 | 996 | ||
| 1001 | /* wait for firmware to accept initialization segments configurations | 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 | if (err) { | 1001 | if (err) { |
| 1006 | mlx5_core_err(dev, "Firmware over %llu MS in pre-initializing state, aborting\n", | 1002 | mlx5_core_err(dev, "Firmware over %llu MS in pre-initializing state, aborting\n", |
| 1007 | mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT)); | 1003 | mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT)); |
| 1008 | goto err_tout_cleanup; | 1004 | return err; |
| 1009 | } | 1005 | } |
| 1010 | 1006 | ||
| 1011 | err = mlx5_cmd_init(dev); | 1007 | err = mlx5_cmd_init(dev); |
| 1012 | if (err) { | 1008 | if (err) { |
| 1013 | mlx5_core_err(dev, "Failed initializing command interface, aborting\n"); | 1009 | mlx5_core_err(dev, "Failed initializing command interface, aborting\n"); |
| 1014 | goto err_tout_cleanup; | 1010 | return err; |
| 1015 | } | 1011 | } |
| 1016 | 1012 | ||
| 1017 | mlx5_tout_query_iseg(dev); | 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 | mlx5_set_driver_version(dev); | 1072 | mlx5_set_driver_version(dev); |
| 1077 | 1073 | ||
| 1078 | mlx5_start_health_poll(dev); | ||
| 1079 | |||
| 1080 | err = mlx5_query_hca_caps(dev); | 1074 | err = mlx5_query_hca_caps(dev); |
| 1081 | if (err) { | 1075 | if (err) { |
| 1082 | mlx5_core_err(dev, "query hca failed\n"); | 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 | return 0; | 1082 | return 0; |
| 1087 | 1083 | ||
| 1088 | stop_health: | ||
| 1089 | mlx5_stop_health_poll(dev, boot); | ||
| 1090 | reclaim_boot_pages: | 1084 | reclaim_boot_pages: |
| 1091 | mlx5_reclaim_startup_pages(dev); | 1085 | mlx5_reclaim_startup_pages(dev); |
| 1092 | err_disable_hca: | 1086 | err_disable_hca: |
| @@ -1094,8 +1088,6 @@ err_disable_hca: · 1 unmodified line | |||
| 1094 | err_cmd_cleanup: | 1088 | err_cmd_cleanup: |
| 1095 | mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); | 1089 | mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); |
| 1096 | mlx5_cmd_cleanup(dev); | 1090 | mlx5_cmd_cleanup(dev); |
| 1097 | err_tout_cleanup: | ||
| 1098 | mlx5_tout_cleanup(dev); | ||
| 1099 | 1091 | ||
| 1100 | return err; | 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 | mlx5_core_disable_hca(dev, 0); | 1106 | mlx5_core_disable_hca(dev, 0); |
| 1115 | mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); | 1107 | mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); |
| 1116 | mlx5_cmd_cleanup(dev); | 1108 | mlx5_cmd_cleanup(dev); |
| 1117 | mlx5_tout_cleanup(dev); | ||
| 1118 | 1109 | ||
| 1119 | return 0; | 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 | mlx5_debugfs_root); | 1467 | mlx5_debugfs_root); |
| 1477 | INIT_LIST_HEAD(&priv->traps); | 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 | err = mlx5_health_init(dev); | 1476 | err = mlx5_health_init(dev); |
| 1480 | if (err) | 1477 | if (err) |
| 1481 | goto err_health_init; | 1478 | goto err_health_init; |
| @@ -1501,6 +1498,8 @@ err_adev_init: · 19 unmodified lines | |||
| 1501 | err_pagealloc_init: | 1498 | err_pagealloc_init: |
| 1502 | mlx5_health_cleanup(dev); | 1499 | mlx5_health_cleanup(dev); |
| 1503 | err_health_init: | 1500 | err_health_init: |
| 1501 | mlx5_tout_cleanup(dev); | ||
| 1502 | err_timeout_init: | ||
| 1504 | debugfs_remove(dev->priv.dbg_root); | 1503 | debugfs_remove(dev->priv.dbg_root); |
| 1505 | mutex_destroy(&priv->pgdir_mutex); | 1504 | mutex_destroy(&priv->pgdir_mutex); |
| 1506 | mutex_destroy(&priv->alloc_mutex); | 1505 | mutex_destroy(&priv->alloc_mutex); |
| @@ -1518,6 +1517,7 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev) · 11 unmodified lines | |||
| 1518 | mlx5_adev_cleanup(dev); | 1517 | mlx5_adev_cleanup(dev); |
| 1519 | mlx5_pagealloc_cleanup(dev); | 1518 | mlx5_pagealloc_cleanup(dev); |
| 1520 | mlx5_health_cleanup(dev); | 1519 | mlx5_health_cleanup(dev); |
| 1520 | mlx5_tout_cleanup(dev); | ||
| 1521 | debugfs_remove_recursive(dev->priv.dbg_root); | 1521 | debugfs_remove_recursive(dev->priv.dbg_root); |
| 1522 | mutex_destroy(&priv->pgdir_mutex); | 1522 | mutex_destroy(&priv->pgdir_mutex); |
| 1523 | mutex_destroy(&priv->alloc_mutex); | 1523 | mutex_destroy(&priv->alloc_mutex); |
| @@ -480,16 +480,16 @@ static int mana_hwc_create_wq(struct hw_channel_context *hwc, · 479 unmodified lines | |||
| 480 | if (err) | 480 | if (err) |
| 481 | goto out; | 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 | hwc_wq->hwc = hwc; | 483 | hwc_wq->hwc = hwc; |
| 489 | hwc_wq->gdma_wq = queue; | 484 | hwc_wq->gdma_wq = queue; |
| 490 | hwc_wq->queue_depth = q_depth; | 485 | hwc_wq->queue_depth = q_depth; |
| 491 | hwc_wq->hwc_cq = hwc_cq; | 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 | *hwc_wq_ptr = hwc_wq; | 493 | *hwc_wq_ptr = hwc_wq; |
| 494 | return 0; | 494 | return 0; |
| 495 | out: | 495 | out: |
| @@ -1563,8 +1563,10 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) · 1562 unmodified lines | |||
| 1563 | } | 1563 | } |
| 1564 | 1564 | ||
| 1565 | err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); | 1565 | err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); |
| 1566 | if (err) | 1566 | if (err) { |
| 1567 | mutex_unlock(&ocelot->ptp_lock); | ||
| 1567 | return err; | 1568 | return err; |
| 1569 | } | ||
| 1568 | 1570 | ||
| 1569 | if (l2 && l4) | 1571 | if (l2 && l4) |
| 1570 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | 1572 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; |
| @@ -120,7 +120,7 @@ static const struct net_device_ops xtsonic_netdev_ops = { · 119 unmodified lines | |||
| 120 | .ndo_set_mac_address = eth_mac_addr, | 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 | unsigned int silicon_revision; | 125 | unsigned int silicon_revision; |
| 126 | struct sonic_local *lp = netdev_priv(dev); | 126 | struct sonic_local *lp = netdev_priv(dev); |
| @@ -803,8 +803,10 @@ int nfp_cpp_area_cache_add(struct nfp_cpp *cpp, size_t size) · 802 unmodified lines | |||
| 803 | return -ENOMEM; | 803 | return -ENOMEM; |
| 804 | 804 | ||
| 805 | cache = kzalloc(sizeof(*cache), GFP_KERNEL); | 805 | cache = kzalloc(sizeof(*cache), GFP_KERNEL); |
| 806 | if (!cache) | 806 | if (!cache) { |
| 807 | nfp_cpp_area_free(area); | ||
| 807 | return -ENOMEM; | 808 | return -ENOMEM; |
| 809 | } | ||
| 808 | 810 | ||
| 809 | cache->id = 0; | 811 | cache->id = 0; |
| 810 | cache->addr = 0; | 812 | cache->addr = 0; |
| @@ -1643,6 +1643,13 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1642 unmodified lines | |||
| 1643 | data_split = true; | 1643 | data_split = true; |
| 1644 | } | 1644 | } |
| 1645 | } else { | 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 | val |= ((skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) << | 1653 | val |= ((skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) << |
| 1647 | ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT); | 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 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); | 3481 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); |
| 3482 | 3482 | ||
| 3483 | err = ql_wait_for_drvr_lock(qdev); | 3483 | if (!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 { | ||
| 3493 | netdev_err(ndev, "Could not acquire driver lock\n"); | 3484 | netdev_err(ndev, "Could not acquire driver lock\n"); |
| 3485 | err = -ENODEV; | ||
| 3494 | goto err_lock; | 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 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | 3496 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); |
| 3498 | 3497 | ||
| 3499 | set_bit(QL_ADAPTER_UP, &qdev->flags); | 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 | sds_mbx_size = sizeof(struct qlcnic_sds_mbx); | 1077 | sds_mbx_size = sizeof(struct qlcnic_sds_mbx); |
| 1078 | context_id = recv_ctx->context_id; | 1078 | context_id = recv_ctx->context_id; |
| 1079 | num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS; | 1079 | num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS; |
| 1080 | ahw->hw_ops->alloc_mbx_args(&cmd, adapter, | 1080 | err = ahw->hw_ops->alloc_mbx_args(&cmd, adapter, |
| 1081 | QLCNIC_CMD_ADD_RCV_RINGS); | 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 | cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16); | 1088 | cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16); |
| 1083 | 1089 | ||
| 1084 | /* set up status rings, mbx 2-81 */ | 1090 | /* set up status rings, mbx 2-81 */ |
| @@ -5540,8 +5540,6 @@ static int stmmac_set_features(struct net_device *netdev, · 5539 unmodified lines | |||
| 5540 | netdev_features_t features) | 5540 | netdev_features_t features) |
| 5541 | { | 5541 | { |
| 5542 | struct stmmac_priv *priv = netdev_priv(netdev); | 5542 | struct stmmac_priv *priv = netdev_priv(netdev); |
| 5543 | bool sph_en; | ||
| 5544 | u32 chan; | ||
| 5545 | 5543 | ||
| 5546 | /* Keep the COE Type in case of csum is supporting */ | 5544 | /* Keep the COE Type in case of csum is supporting */ |
| 5547 | if (features & NETIF_F_RXCSUM) | 5545 | if (features & NETIF_F_RXCSUM) |
| @@ -5553,10 +5551,13 @@ static int stmmac_set_features(struct net_device *netdev, · 5 unmodified lines | |||
| 5553 | */ | 5551 | */ |
| 5554 | stmmac_rx_ipc(priv, priv->hw); | 5552 | stmmac_rx_ipc(priv, priv->hw); |
| 5555 | 5553 | ||
| 5556 | 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; | ||
| 5557 | 5557 | ||
| 5558 | for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++) | 5558 | for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++) |
| 5559 | stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan); | 5559 | stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan); |
| 5560 | } | ||
| 5560 | 5561 | ||
| 5561 | return 0; | 5562 | return 0; |
| 5562 | } | 5563 | } |
| @@ -1388,6 +1388,7 @@ EXPORT_SYMBOL_GPL(phylink_stop); · 1387 unmodified lines | |||
| 1388 | * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan | 1388 | * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan |
| 1389 | * | 1389 | * |
| 1390 | * Handle a network device suspend event. There are several cases: | 1390 | * Handle a network device suspend event. There are several cases: |
| 1391 | * | ||
| 1391 | * - If Wake-on-Lan is not active, we can bring down the link between | 1392 | * - If Wake-on-Lan is not active, we can bring down the link between |
| 1392 | * the MAC and PHY by calling phylink_stop(). | 1393 | * the MAC and PHY by calling phylink_stop(). |
| 1393 | * - If Wake-on-Lan is active, and being handled only by the PHY, we | 1394 | * - If Wake-on-Lan is active, and being handled only by the PHY, we |
| @@ -181,6 +181,8 @@ static u32 cdc_ncm_check_tx_max(struct usbnet *dev, u32 new_tx) · 180 unmodified lines | |||
| 181 | min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth32); | 181 | min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth32); |
| 182 | 182 | ||
| 183 | max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)); | 183 | max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)); |
| 184 | if (max == 0) | ||
| 185 | max = CDC_NCM_NTB_MAX_SIZE_TX; /* dwNtbOutMaxSize not set */ | ||
| 184 | 186 | ||
| 185 | /* some devices set dwNtbOutMaxSize too low for the above default */ | 187 | /* some devices set dwNtbOutMaxSize too low for the above default */ |
| 186 | min = min(min, max); | 188 | min = min(min, max); |
| @@ -2228,7 +2228,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) · 2227 unmodified lines | |||
| 2228 | if (dev->domain_data.phyirq > 0) | 2228 | if (dev->domain_data.phyirq > 0) |
| 2229 | phydev->irq = dev->domain_data.phyirq; | 2229 | phydev->irq = dev->domain_data.phyirq; |
| 2230 | else | 2230 | else |
| 2231 | phydev->irq = 0; | 2231 | phydev->irq = PHY_POLL; |
| 2232 | netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq); | 2232 | netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq); |
| 2233 | 2233 | ||
| 2234 | /* set to AUTOMDIX */ | 2234 | /* set to AUTOMDIX */ |
| @@ -3261,7 +3261,7 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) · 3260 unmodified lines | |||
| 3261 | 3261 | ||
| 3262 | #ifdef CONFIG_PCI_MSI | 3262 | #ifdef CONFIG_PCI_MSI |
| 3263 | if (adapter->intr.type == VMXNET3_IT_MSIX) { | 3263 | if (adapter->intr.type == VMXNET3_IT_MSIX) { |
| 3264 | int i, nvec; | 3264 | int i, nvec, nvec_allocated; |
| 3265 | 3265 | ||
| 3266 | nvec = adapter->share_intr == VMXNET3_INTR_TXSHARE ? | 3266 | nvec = adapter->share_intr == VMXNET3_INTR_TXSHARE ? |
| 3267 | 1 : adapter->num_tx_queues; | 3267 | 1 : adapter->num_tx_queues; |
| @@ -3274,14 +3274,15 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) · 6 unmodified lines | |||
| 3274 | for (i = 0; i < nvec; i++) | 3274 | for (i = 0; i < nvec; i++) |
| 3275 | adapter->intr.msix_entries[i].entry = i; | 3275 | adapter->intr.msix_entries[i].entry = i; |
| 3276 | 3276 | ||
| 3277 | nvec = vmxnet3_acquire_msix_vectors(adapter, nvec); | 3277 | nvec_allocated = vmxnet3_acquire_msix_vectors(adapter, nvec); |
| 3278 | if (nvec < 0) | 3278 | if (nvec_allocated < 0) |
| 3279 | goto msix_err; | 3279 | goto msix_err; |
| 3280 | 3280 | ||
| 3281 | /* If we cannot allocate one MSIx vector per queue | 3281 | /* If we cannot allocate one MSIx vector per queue |
| 3282 | * then limit the number of rx queues to 1 | 3282 | * then limit the number of rx queues to 1 |
| 3283 | */ | 3283 | */ |
| 3284 | if (nvec == VMXNET3_LINUX_MIN_MSIX_VECT) { | 3284 | if (nvec_allocated == VMXNET3_LINUX_MIN_MSIX_VECT && |
| 3285 | nvec != VMXNET3_LINUX_MIN_MSIX_VECT) { | ||
| 3285 | if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE | 3286 | if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE |
| 3286 | || adapter->num_rx_queues != 1) { | 3287 | || adapter->num_rx_queues != 1) { |
| 3287 | adapter->share_intr = VMXNET3_INTR_TXSHARE; | 3288 | adapter->share_intr = VMXNET3_INTR_TXSHARE; |
| @@ -3291,14 +3292,14 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) · 3 unmodified lines | |||
| 3291 | } | 3292 | } |
| 3292 | } | 3293 | } |
| 3293 | 3294 | ||
| 3294 | adapter->intr.num_intrs = nvec; | 3295 | adapter->intr.num_intrs = nvec_allocated; |
| 3295 | return; | 3296 | return; |
| 3296 | 3297 | ||
| 3297 | msix_err: | 3298 | msix_err: |
| 3298 | /* If we cannot allocate MSIx vectors use only one rx queue */ | 3299 | /* If we cannot allocate MSIx vectors use only one rx queue */ |
| 3299 | dev_info(&adapter->pdev->dev, | 3300 | dev_info(&adapter->pdev->dev, |
| 3300 | "Failed to enable MSI-X, error %d. " | 3301 | "Failed to enable MSI-X, error %d. " |
| 3301 | "Limiting #rx queues to 1, try MSI.\n", nvec); | 3302 | "Limiting #rx queues to 1, try MSI.\n", nvec_allocated); |
| 3302 | 3303 | ||
| 3303 | adapter->intr.type = VMXNET3_IT_MSI; | 3304 | adapter->intr.type = VMXNET3_IT_MSI; |
| 3304 | } | 3305 | } |
| @@ -497,6 +497,7 @@ static netdev_tx_t vrf_process_v6_outbound(struct sk_buff *skb, · 496 unmodified lines | |||
| 497 | /* strip the ethernet header added for pass through VRF device */ | 497 | /* strip the ethernet header added for pass through VRF device */ |
| 498 | __skb_pull(skb, skb_network_offset(skb)); | 498 | __skb_pull(skb, skb_network_offset(skb)); |
| 499 | 499 | ||
| 500 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | ||
| 500 | ret = vrf_ip6_local_out(net, skb->sk, skb); | 501 | ret = vrf_ip6_local_out(net, skb->sk, skb); |
| 501 | if (unlikely(net_xmit_eval(ret))) | 502 | if (unlikely(net_xmit_eval(ret))) |
| 502 | dev->stats.tx_errors++; | 503 | dev->stats.tx_errors++; |
| @@ -579,6 +580,7 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb, · 76 unmodified lines | |||
| 579 | RT_SCOPE_LINK); | 580 | RT_SCOPE_LINK); |
| 580 | } | 581 | } |
| 581 | 582 | ||
| 583 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | ||
| 582 | ret = vrf_ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); | 584 | ret = vrf_ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); |
| 583 | if (unlikely(net_xmit_eval(ret))) | 585 | if (unlikely(net_xmit_eval(ret))) |
| 584 | vrf_dev->stats.tx_errors++; | 586 | vrf_dev->stats.tx_errors++; |
| @@ -768,8 +770,6 @@ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev, · 183 unmodified lines | |||
| 768 | 770 | ||
| 769 | skb->dev = vrf_dev; | 771 | skb->dev = vrf_dev; |
| 770 | 772 | ||
| 771 | vrf_nf_set_untracked(skb); | ||
| 772 | |||
| 773 | err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, | 773 | err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, |
| 774 | skb, NULL, vrf_dev, vrf_ip6_out_direct_finish); | 774 | skb, NULL, vrf_dev, vrf_ip6_out_direct_finish); |
| 775 | 775 | ||
| @@ -790,6 +790,8 @@ static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev, · 14 unmodified lines | |||
| 790 | if (rt6_need_strict(&ipv6_hdr(skb)->daddr)) | 790 | if (rt6_need_strict(&ipv6_hdr(skb)->daddr)) |
| 791 | return skb; | 791 | return skb; |
| 792 | 792 | ||
| 793 | vrf_nf_set_untracked(skb); | ||
| 794 | |||
| 793 | if (qdisc_tx_is_default(vrf_dev) || | 795 | if (qdisc_tx_is_default(vrf_dev) || |
| 794 | IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) | 796 | IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) |
| 795 | return vrf_ip6_out_direct(vrf_dev, sk, skb); | 797 | return vrf_ip6_out_direct(vrf_dev, sk, skb); |
| @@ -998,8 +1000,6 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev, · 202 unmodified lines | |||
| 998 | 1000 | ||
| 999 | skb->dev = vrf_dev; | 1001 | skb->dev = vrf_dev; |
| 1000 | 1002 | ||
| 1001 | vrf_nf_set_untracked(skb); | ||
| 1002 | |||
| 1003 | err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk, | 1003 | err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk, |
| 1004 | skb, NULL, vrf_dev, vrf_ip_out_direct_finish); | 1004 | skb, NULL, vrf_dev, vrf_ip_out_direct_finish); |
| 1005 | 1005 | ||
| @@ -1021,6 +1021,8 @@ static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev, · 15 unmodified lines | |||
| 1021 | ipv4_is_lbcast(ip_hdr(skb)->daddr)) | 1021 | ipv4_is_lbcast(ip_hdr(skb)->daddr)) |
| 1022 | return skb; | 1022 | return skb; |
| 1023 | 1023 | ||
| 1024 | vrf_nf_set_untracked(skb); | ||
| 1025 | |||
| 1024 | if (qdisc_tx_is_default(vrf_dev) || | 1026 | if (qdisc_tx_is_default(vrf_dev) || |
| 1025 | IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) | 1027 | IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) |
| 1026 | return vrf_ip_out_direct(vrf_dev, sk, skb); | 1028 | return vrf_ip_out_direct(vrf_dev, sk, skb); |
| @@ -163,7 +163,7 @@ static bool node_placement(struct allowedips_node __rcu *trie, const u8 *key, · 162 unmodified lines | |||
| 163 | return exact; | 163 | return exact; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static inline void connect_node(struct allowedips_node **parent, u8 bit, struct allowedips_node *node) | 166 | static inline void connect_node(struct allowedips_node __rcu **parent, u8 bit, struct allowedips_node *node) |
| 167 | { | 167 | { |
| 168 | node->parent_bit_packed = (unsigned long)parent | bit; | 168 | node->parent_bit_packed = (unsigned long)parent | bit; |
| 169 | rcu_assign_pointer(*parent, node); | 169 | rcu_assign_pointer(*parent, node); |
| @@ -98,6 +98,7 @@ static int wg_stop(struct net_device *dev) · 97 unmodified lines | |||
| 98 | { | 98 | { |
| 99 | struct wg_device *wg = netdev_priv(dev); | 99 | struct wg_device *wg = netdev_priv(dev); |
| 100 | struct wg_peer *peer; | 100 | struct wg_peer *peer; |
| 101 | struct sk_buff *skb; | ||
| 101 | 102 | ||
| 102 | mutex_lock(&wg->device_update_lock); | 103 | mutex_lock(&wg->device_update_lock); |
| 103 | list_for_each_entry(peer, &wg->peer_list, peer_list) { | 104 | list_for_each_entry(peer, &wg->peer_list, peer_list) { |
| @@ -108,7 +109,9 @@ static int wg_stop(struct net_device *dev) · 4 unmodified lines | |||
| 108 | wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake); | 109 | wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake); |
| 109 | } | 110 | } |
| 110 | mutex_unlock(&wg->device_update_lock); | 111 | mutex_unlock(&wg->device_update_lock); |
| 111 | skb_queue_purge(&wg->incoming_handshakes); | 112 | while ((skb = ptr_ring_consume(&wg->handshake_queue.ring)) != NULL) |
| 113 | kfree_skb(skb); | ||
| 114 | atomic_set(&wg->handshake_queue_len, 0); | ||
| 112 | wg_socket_reinit(wg, NULL, NULL); | 115 | wg_socket_reinit(wg, NULL, NULL); |
| 113 | return 0; | 116 | return 0; |
| 114 | } | 117 | } |
| @@ -235,14 +238,13 @@ static void wg_destruct(struct net_device *dev) · 120 unmodified lines | |||
| 235 | destroy_workqueue(wg->handshake_receive_wq); | 238 | destroy_workqueue(wg->handshake_receive_wq); |
| 236 | destroy_workqueue(wg->handshake_send_wq); | 239 | destroy_workqueue(wg->handshake_send_wq); |
| 237 | destroy_workqueue(wg->packet_crypt_wq); | 240 | destroy_workqueue(wg->packet_crypt_wq); |
| 238 | wg_packet_queue_free(&wg->decrypt_queue); | 241 | wg_packet_queue_free(&wg->handshake_queue, true); |
| 239 | wg_packet_queue_free(&wg->encrypt_queue); | 242 | wg_packet_queue_free(&wg->decrypt_queue, false); |
| 243 | wg_packet_queue_free(&wg->encrypt_queue, false); | ||
| 240 | rcu_barrier(); /* Wait for all the peers to be actually freed. */ | 244 | rcu_barrier(); /* Wait for all the peers to be actually freed. */ |
| 241 | wg_ratelimiter_uninit(); | 245 | wg_ratelimiter_uninit(); |
| 242 | memzero_explicit(&wg->static_identity, sizeof(wg->static_identity)); | 246 | memzero_explicit(&wg->static_identity, sizeof(wg->static_identity)); |
| 243 | skb_queue_purge(&wg->incoming_handshakes); | ||
| 244 | free_percpu(dev->tstats); | 247 | free_percpu(dev->tstats); |
| 245 | free_percpu(wg->incoming_handshakes_worker); | ||
| 246 | kvfree(wg->index_hashtable); | 248 | kvfree(wg->index_hashtable); |
| 247 | kvfree(wg->peer_hashtable); | 249 | kvfree(wg->peer_hashtable); |
| 248 | mutex_unlock(&wg->device_update_lock); | 250 | mutex_unlock(&wg->device_update_lock); |
| @@ -298,7 +300,6 @@ static int wg_newlink(struct net *src_net, struct net_device *dev, · 49 unmodified lines | |||
| 298 | init_rwsem(&wg->static_identity.lock); | 300 | init_rwsem(&wg->static_identity.lock); |
| 299 | mutex_init(&wg->socket_update_lock); | 301 | mutex_init(&wg->socket_update_lock); |
| 300 | mutex_init(&wg->device_update_lock); | 302 | mutex_init(&wg->device_update_lock); |
| 301 | skb_queue_head_init(&wg->incoming_handshakes); | ||
| 302 | wg_allowedips_init(&wg->peer_allowedips); | 303 | wg_allowedips_init(&wg->peer_allowedips); |
| 303 | wg_cookie_checker_init(&wg->cookie_checker, wg); | 304 | wg_cookie_checker_init(&wg->cookie_checker, wg); |
| 304 | INIT_LIST_HEAD(&wg->peer_list); | 305 | INIT_LIST_HEAD(&wg->peer_list); |
| @@ -316,16 +317,10 @@ static int wg_newlink(struct net *src_net, struct net_device *dev, · 11 unmodified lines | |||
| 316 | if (!dev->tstats) | 317 | if (!dev->tstats) |
| 317 | goto err_free_index_hashtable; | 318 | goto err_free_index_hashtable; |
| 318 | 319 | ||
| 319 | wg->incoming_handshakes_worker = | ||
| 320 | wg_packet_percpu_multicore_worker_alloc( | ||
| 321 | wg_packet_handshake_receive_worker, wg); | ||
| 322 | if (!wg->incoming_handshakes_worker) | ||
| 323 | goto err_free_tstats; | ||
| 324 | |||
| 325 | wg->handshake_receive_wq = alloc_workqueue("wg-kex-%s", | 320 | wg->handshake_receive_wq = alloc_workqueue("wg-kex-%s", |
| 326 | WQ_CPU_INTENSIVE | WQ_FREEZABLE, 0, dev->name); | 321 | WQ_CPU_INTENSIVE | WQ_FREEZABLE, 0, dev->name); |
| 327 | if (!wg->handshake_receive_wq) | 322 | if (!wg->handshake_receive_wq) |
| 328 | goto err_free_incoming_handshakes; | 323 | goto err_free_tstats; |
| 329 | 324 | ||
| 330 | wg->handshake_send_wq = alloc_workqueue("wg-kex-%s", | 325 | wg->handshake_send_wq = alloc_workqueue("wg-kex-%s", |
| 331 | WQ_UNBOUND | WQ_FREEZABLE, 0, dev->name); | 326 | WQ_UNBOUND | WQ_FREEZABLE, 0, dev->name); |
| @@ -347,10 +342,15 @@ static int wg_newlink(struct net *src_net, struct net_device *dev, · 15 unmodified lines | |||
| 347 | if (ret < 0) | 342 | if (ret < 0) |
| 348 | goto err_free_encrypt_queue; | 343 | goto err_free_encrypt_queue; |
| 349 | 344 | ||
| 350 | ret = wg_ratelimiter_init(); | 345 | ret = wg_packet_queue_init(&wg->handshake_queue, wg_packet_handshake_receive_worker, |
| 346 | MAX_QUEUED_INCOMING_HANDSHAKES); | ||
| 351 | if (ret < 0) | 347 | if (ret < 0) |
| 352 | goto err_free_decrypt_queue; | 348 | goto err_free_decrypt_queue; |
| 353 | 349 | ||
| 350 | ret = wg_ratelimiter_init(); | ||
| 351 | if (ret < 0) | ||
| 352 | goto err_free_handshake_queue; | ||
| 353 | |||
| 354 | ret = register_netdevice(dev); | 354 | ret = register_netdevice(dev); |
| 355 | if (ret < 0) | 355 | if (ret < 0) |
| 356 | goto err_uninit_ratelimiter; | 356 | goto err_uninit_ratelimiter; |
| @@ -367,18 +367,18 @@ static int wg_newlink(struct net *src_net, struct net_device *dev, · 10 unmodified lines | |||
| 367 | 367 | ||
| 368 | err_uninit_ratelimiter: | 368 | err_uninit_ratelimiter: |
| 369 | wg_ratelimiter_uninit(); | 369 | wg_ratelimiter_uninit(); |
| 370 | err_free_handshake_queue: | ||
| 371 | wg_packet_queue_free(&wg->handshake_queue, false); | ||
| 370 | err_free_decrypt_queue: | 372 | err_free_decrypt_queue: |
| 371 | wg_packet_queue_free(&wg->decrypt_queue); | 373 | wg_packet_queue_free(&wg->decrypt_queue, false); |
| 372 | err_free_encrypt_queue: | 374 | err_free_encrypt_queue: |
| 373 | wg_packet_queue_free(&wg->encrypt_queue); | 375 | wg_packet_queue_free(&wg->encrypt_queue, false); |
| 374 | err_destroy_packet_crypt: | 376 | err_destroy_packet_crypt: |
| 375 | destroy_workqueue(wg->packet_crypt_wq); | 377 | destroy_workqueue(wg->packet_crypt_wq); |
| 376 | err_destroy_handshake_send: | 378 | err_destroy_handshake_send: |
| 377 | destroy_workqueue(wg->handshake_send_wq); | 379 | destroy_workqueue(wg->handshake_send_wq); |
| 378 | err_destroy_handshake_receive: | 380 | err_destroy_handshake_receive: |
| 379 | destroy_workqueue(wg->handshake_receive_wq); | 381 | destroy_workqueue(wg->handshake_receive_wq); |
| 380 | err_free_incoming_handshakes: | ||
| 381 | free_percpu(wg->incoming_handshakes_worker); | ||
| 382 | err_free_tstats: | 382 | err_free_tstats: |
| 383 | free_percpu(dev->tstats); | 383 | free_percpu(dev->tstats); |
| 384 | err_free_index_hashtable: | 384 | err_free_index_hashtable: |
| @@ -398,6 +398,7 @@ static struct rtnl_link_ops link_ops __read_mostly = { · 13 unmodified lines | |||
| 398 | static void wg_netns_pre_exit(struct net *net) | 398 | static void wg_netns_pre_exit(struct net *net) |
| 399 | { | 399 | { |
| 400 | struct wg_device *wg; | 400 | struct wg_device *wg; |
| 401 | struct wg_peer *peer; | ||
| 401 | 402 | ||
| 402 | rtnl_lock(); | 403 | rtnl_lock(); |
| 403 | list_for_each_entry(wg, &device_list, device_list) { | 404 | list_for_each_entry(wg, &device_list, device_list) { |
| @@ -407,6 +408,8 @@ static void wg_netns_pre_exit(struct net *net) · 3 unmodified lines | |||
| 407 | mutex_lock(&wg->device_update_lock); | 408 | mutex_lock(&wg->device_update_lock); |
| 408 | rcu_assign_pointer(wg->creating_net, NULL); | 409 | rcu_assign_pointer(wg->creating_net, NULL); |
| 409 | wg_socket_reinit(wg, NULL, NULL); | 410 | wg_socket_reinit(wg, NULL, NULL); |
| 411 | list_for_each_entry(peer, &wg->peer_list, peer_list) | ||
| 412 | wg_socket_clear_peer_endpoint_src(peer); | ||
| 410 | mutex_unlock(&wg->device_update_lock); | 413 | mutex_unlock(&wg->device_update_lock); |
| 411 | } | 414 | } |
| 412 | } | 415 | } |
| @@ -39,21 +39,18 @@ struct prev_queue { · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | struct wg_device { | 40 | struct wg_device { |
| 41 | struct net_device *dev; | 41 | struct net_device *dev; |
| 42 | struct crypt_queue encrypt_queue, decrypt_queue; | 42 | struct crypt_queue encrypt_queue, decrypt_queue, handshake_queue; |
| 43 | struct sock __rcu *sock4, *sock6; | 43 | struct sock __rcu *sock4, *sock6; |
| 44 | struct net __rcu *creating_net; | 44 | struct net __rcu *creating_net; |
| 45 | struct noise_static_identity static_identity; | 45 | struct noise_static_identity static_identity; |
| 46 | struct workqueue_struct *handshake_receive_wq, *handshake_send_wq; | 46 | struct workqueue_struct *packet_crypt_wq,*handshake_receive_wq, *handshake_send_wq; |
| 47 | struct workqueue_struct *packet_crypt_wq; | ||
| 48 | struct sk_buff_head incoming_handshakes; | ||
| 49 | int incoming_handshake_cpu; | ||
| 50 | struct multicore_worker __percpu *incoming_handshakes_worker; | ||
| 51 | struct cookie_checker cookie_checker; | 47 | struct cookie_checker cookie_checker; |
| 52 | struct pubkey_hashtable *peer_hashtable; | 48 | struct pubkey_hashtable *peer_hashtable; |
| 53 | struct index_hashtable *index_hashtable; | 49 | struct index_hashtable *index_hashtable; |
| 54 | struct allowedips peer_allowedips; | 50 | struct allowedips peer_allowedips; |
| 55 | struct mutex device_update_lock, socket_update_lock; | 51 | struct mutex device_update_lock, socket_update_lock; |
| 56 | struct list_head device_list, peer_list; | 52 | struct list_head device_list, peer_list; |
| 53 | atomic_t handshake_queue_len; | ||
| 57 | unsigned int num_peers, device_update_gen; | 54 | unsigned int num_peers, device_update_gen; |
| 58 | u32 fwmark; | 55 | u32 fwmark; |
| 59 | u16 incoming_port; | 56 | u16 incoming_port; |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/genetlink.h> | 17 | #include <linux/genetlink.h> |
| 18 | #include <net/rtnetlink.h> | 18 | #include <net/rtnetlink.h> |
| 19 | 19 | ||
| 20 | static int __init mod_init(void) | 20 | static int __init wg_mod_init(void) |
| 21 | { | 21 | { |
| 22 | int ret; | 22 | int ret; |
| 23 | 23 | ||
| @@ -60,7 +60,7 @@ err_allowedips: · 36 unmodified lines | |||
| 60 | return ret; | 60 | return ret; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | static void __exit mod_exit(void) | 63 | static void __exit wg_mod_exit(void) |
| 64 | { | 64 | { |
| 65 | wg_genetlink_uninit(); | 65 | wg_genetlink_uninit(); |
| 66 | wg_device_uninit(); | 66 | wg_device_uninit(); |
| @@ -68,8 +68,8 @@ static void __exit mod_exit(void) · 1 unmodified line | |||
| 68 | wg_allowedips_slab_uninit(); | 68 | wg_allowedips_slab_uninit(); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | module_init(mod_init); | 71 | module_init(wg_mod_init); |
| 72 | module_exit(mod_exit); | 72 | module_exit(wg_mod_exit); |
| 73 | MODULE_LICENSE("GPL v2"); | 73 | MODULE_LICENSE("GPL v2"); |
| 74 | MODULE_DESCRIPTION("WireGuard secure network tunnel"); | 74 | MODULE_DESCRIPTION("WireGuard secure network tunnel"); |
| 75 | MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>"); | 75 | MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>"); |
| @@ -38,11 +38,11 @@ int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function, · 37 unmodified lines | |||
| 38 | return 0; | 38 | return 0; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | void wg_packet_queue_free(struct crypt_queue *queue) | 41 | void wg_packet_queue_free(struct crypt_queue *queue, bool purge) |
| 42 | { | 42 | { |
| 43 | free_percpu(queue->worker); | 43 | free_percpu(queue->worker); |
| 44 | WARN_ON(!__ptr_ring_empty(&queue->ring)); | 44 | WARN_ON(!purge && !__ptr_ring_empty(&queue->ring)); |
| 45 | ptr_ring_cleanup(&queue->ring, NULL); | 45 | ptr_ring_cleanup(&queue->ring, purge ? (void(*)(void*))kfree_skb : NULL); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | #define NEXT(skb) ((skb)->prev) | 48 | #define NEXT(skb) ((skb)->prev) |
| @@ -23,7 +23,7 @@ struct sk_buff; · 22 unmodified lines | |||
| 23 | /* queueing.c APIs: */ | 23 | /* queueing.c APIs: */ |
| 24 | int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function, | 24 | int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function, |
| 25 | unsigned int len); | 25 | unsigned int len); |
| 26 | void wg_packet_queue_free(struct crypt_queue *queue); | 26 | void wg_packet_queue_free(struct crypt_queue *queue, bool purge); |
| 27 | struct multicore_worker __percpu * | 27 | struct multicore_worker __percpu * |
| 28 | wg_packet_percpu_multicore_worker_alloc(work_func_t function, void *ptr); | 28 | wg_packet_percpu_multicore_worker_alloc(work_func_t function, void *ptr); |
| 29 | 29 | ||
| @@ -176,12 +176,12 @@ int wg_ratelimiter_init(void) · 175 unmodified lines | |||
| 176 | (1U << 14) / sizeof(struct hlist_head))); | 176 | (1U << 14) / sizeof(struct hlist_head))); |
| 177 | max_entries = table_size * 8; | 177 | max_entries = table_size * 8; |
| 178 | 178 | ||
| 179 | table_v4 = kvzalloc(table_size * sizeof(*table_v4), GFP_KERNEL); | 179 | table_v4 = kvcalloc(table_size, sizeof(*table_v4), GFP_KERNEL); |
| 180 | if (unlikely(!table_v4)) | 180 | if (unlikely(!table_v4)) |
| 181 | goto err_kmemcache; | 181 | goto err_kmemcache; |
| 182 | 182 | ||
| 183 | #if IS_ENABLED(CONFIG_IPV6) | 183 | #if IS_ENABLED(CONFIG_IPV6) |
| 184 | table_v6 = kvzalloc(table_size * sizeof(*table_v6), GFP_KERNEL); | 184 | table_v6 = kvcalloc(table_size, sizeof(*table_v6), GFP_KERNEL); |
| 185 | if (unlikely(!table_v6)) { | 185 | if (unlikely(!table_v6)) { |
| 186 | kvfree(table_v4); | 186 | kvfree(table_v4); |
| 187 | goto err_kmemcache; | 187 | goto err_kmemcache; |
| @@ -116,8 +116,8 @@ static void wg_receive_handshake_packet(struct wg_device *wg, · 115 unmodified lines | |||
| 116 | return; | 116 | return; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | under_load = skb_queue_len(&wg->incoming_handshakes) >= | 119 | under_load = atomic_read(&wg->handshake_queue_len) >= |
| 120 | MAX_QUEUED_INCOMING_HANDSHAKES / 8; | 120 | MAX_QUEUED_INCOMING_HANDSHAKES / 8; |
| 121 | if (under_load) { | 121 | if (under_load) { |
| 122 | last_under_load = ktime_get_coarse_boottime_ns(); | 122 | last_under_load = ktime_get_coarse_boottime_ns(); |
| 123 | } else if (last_under_load) { | 123 | } else if (last_under_load) { |
| @@ -212,13 +212,14 @@ static void wg_receive_handshake_packet(struct wg_device *wg, · 88 unmodified lines | |||
| 212 | 212 | ||
| 213 | void wg_packet_handshake_receive_worker(struct work_struct *work) | 213 | void wg_packet_handshake_receive_worker(struct work_struct *work) |
| 214 | { | 214 | { |
| 215 | struct wg_device *wg = container_of(work, struct multicore_worker, | 215 | struct crypt_queue *queue = container_of(work, struct multicore_worker, work)->ptr; |
| 216 | work)->ptr; | 216 | struct wg_device *wg = container_of(queue, struct wg_device, handshake_queue); |
| 217 | struct sk_buff *skb; | 217 | struct sk_buff *skb; |
| 218 | 218 | ||
| 219 | while ((skb = skb_dequeue(&wg->incoming_handshakes)) != NULL) { | 219 | while ((skb = ptr_ring_consume_bh(&queue->ring)) != NULL) { |
| 220 | wg_receive_handshake_packet(wg, skb); | 220 | wg_receive_handshake_packet(wg, skb); |
| 221 | dev_kfree_skb(skb); | 221 | dev_kfree_skb(skb); |
| 222 | atomic_dec(&wg->handshake_queue_len); | ||
| 222 | cond_resched(); | 223 | cond_resched(); |
| 223 | } | 224 | } |
| 224 | } | 225 | } |
| @@ -553,22 +554,28 @@ void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb) · 328 unmodified lines | |||
| 553 | case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION): | 554 | case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION): |
| 554 | case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE): | 555 | case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE): |
| 555 | case cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE): { | 556 | case cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE): { |
| 556 | int cpu; | 557 | int cpu, ret = -EBUSY; |
| 557 | 558 | ||
| 558 | if (skb_queue_len(&wg->incoming_handshakes) > | 559 | if (unlikely(!rng_is_initialized())) |
| 559 | MAX_QUEUED_INCOMING_HANDSHAKES || | 560 | goto drop; |
| 560 | unlikely(!rng_is_initialized())) { | 561 | if (atomic_read(&wg->handshake_queue_len) > MAX_QUEUED_INCOMING_HANDSHAKES / 2) { |
| 562 | if (spin_trylock_bh(&wg->handshake_queue.ring.producer_lock)) { | ||
| 563 | ret = __ptr_ring_produce(&wg->handshake_queue.ring, skb); | ||
| 564 | spin_unlock_bh(&wg->handshake_queue.ring.producer_lock); | ||
| 565 | } | ||
| 566 | } else | ||
| 567 | ret = ptr_ring_produce_bh(&wg->handshake_queue.ring, skb); | ||
| 568 | if (ret) { | ||
| 569 | drop: | ||
| 561 | net_dbg_skb_ratelimited("%s: Dropping handshake packet from %pISpfsc\n", | 570 | net_dbg_skb_ratelimited("%s: Dropping handshake packet from %pISpfsc\n", |
| 562 | wg->dev->name, skb); | 571 | wg->dev->name, skb); |
| 563 | goto err; | 572 | goto err; |
| 564 | } | 573 | } |
| 565 | skb_queue_tail(&wg->incoming_handshakes, skb); | 574 | atomic_inc(&wg->handshake_queue_len); |
| 566 | /* Queues up a call to packet_process_queued_handshake_ | 575 | cpu = wg_cpumask_next_online(&wg->handshake_queue.last_cpu); |
| 567 | * packets(skb): | 576 | /* Queues up a call to packet_process_queued_handshake_packets(skb): */ |
| 568 | */ | ||
| 569 | cpu = wg_cpumask_next_online(&wg->incoming_handshake_cpu); | ||
| 570 | queue_work_on(cpu, wg->handshake_receive_wq, | 577 | queue_work_on(cpu, wg->handshake_receive_wq, |
| 571 | &per_cpu_ptr(wg->incoming_handshakes_worker, cpu)->work); | 578 | &per_cpu_ptr(wg->handshake_queue.worker, cpu)->work); |
| 572 | break; | 579 | break; |
| 573 | } | 580 | } |
| 574 | case cpu_to_le32(MESSAGE_DATA): | 581 | case cpu_to_le32(MESSAGE_DATA): |
| @@ -308,7 +308,7 @@ void wg_socket_clear_peer_endpoint_src(struct wg_peer *peer) · 307 unmodified lines | |||
| 308 | { | 308 | { |
| 309 | write_lock_bh(&peer->endpoint_lock); | 309 | write_lock_bh(&peer->endpoint_lock); |
| 310 | memset(&peer->endpoint.src6, 0, sizeof(peer->endpoint.src6)); | 310 | memset(&peer->endpoint.src6, 0, sizeof(peer->endpoint.src6)); |
| 311 | dst_cache_reset(&peer->endpoint_cache); | 311 | dst_cache_reset_now(&peer->endpoint_cache); |
| 312 | write_unlock_bh(&peer->endpoint_lock); | 312 | write_unlock_bh(&peer->endpoint_lock); |
| 313 | } | 313 | } |
| 314 | 314 | ||
| @@ -533,7 +533,11 @@ static int ath11k_mhi_set_state(struct ath11k_pci *ab_pci, · 532 unmodified lines | |||
| 533 | ret = mhi_pm_suspend(ab_pci->mhi_ctrl); | 533 | ret = mhi_pm_suspend(ab_pci->mhi_ctrl); |
| 534 | break; | 534 | break; |
| 535 | case ATH11K_MHI_RESUME: | 535 | case ATH11K_MHI_RESUME: |
| 536 | ret = mhi_pm_resume(ab_pci->mhi_ctrl); | 536 | /* Do force MHI resume as some devices like QCA6390, WCN6855 |
| 537 | * are not in M3 state but they are functional. So just ignore | ||
| 538 | * the MHI state while resuming. | ||
| 539 | */ | ||
| 540 | ret = mhi_pm_resume_force(ab_pci->mhi_ctrl); | ||
| 537 | break; | 541 | break; |
| 538 | case ATH11K_MHI_TRIGGER_RDDM: | 542 | case ATH11K_MHI_TRIGGER_RDDM: |
| 539 | ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl); | 543 | ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl); |
| @@ -86,6 +86,7 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans, · 85 unmodified lines | |||
| 86 | if (len < tlv_len) { | 86 | if (len < tlv_len) { |
| 87 | IWL_ERR(trans, "invalid TLV len: %zd/%u\n", | 87 | IWL_ERR(trans, "invalid TLV len: %zd/%u\n", |
| 88 | len, tlv_len); | 88 | len, tlv_len); |
| 89 | kfree(reduce_power_data); | ||
| 89 | reduce_power_data = ERR_PTR(-EINVAL); | 90 | reduce_power_data = ERR_PTR(-EINVAL); |
| 90 | goto out; | 91 | goto out; |
| 91 | } | 92 | } |
| @@ -105,6 +106,7 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans, · 13 unmodified lines | |||
| 105 | IWL_DEBUG_FW(trans, | 106 | IWL_DEBUG_FW(trans, |
| 106 | "Couldn't allocate (more) reduce_power_data\n"); | 107 | "Couldn't allocate (more) reduce_power_data\n"); |
| 107 | 108 | ||
| 109 | kfree(reduce_power_data); | ||
| 108 | reduce_power_data = ERR_PTR(-ENOMEM); | 110 | reduce_power_data = ERR_PTR(-ENOMEM); |
| 109 | goto out; | 111 | goto out; |
| 110 | } | 112 | } |
| @@ -134,6 +136,10 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans, · 23 unmodified lines | |||
| 134 | done: | 136 | done: |
| 135 | if (!size) { | 137 | if (!size) { |
| 136 | IWL_DEBUG_FW(trans, "Empty REDUCE_POWER, skipping.\n"); | 138 | IWL_DEBUG_FW(trans, "Empty REDUCE_POWER, skipping.\n"); |
| 139 | /* Better safe than sorry, but 'reduce_power_data' should | ||
| 140 | * always be NULL if !size. | ||
| 141 | */ | ||
| 142 | kfree(reduce_power_data); | ||
| 137 | reduce_power_data = ERR_PTR(-ENOENT); | 143 | reduce_power_data = ERR_PTR(-ENOENT); |
| 138 | goto out; | 144 | goto out; |
| 139 | } | 145 | } |
| @@ -1313,23 +1313,31 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op) · 1312 unmodified lines | |||
| 1313 | const struct iwl_op_mode_ops *ops = op->ops; | 1313 | const struct iwl_op_mode_ops *ops = op->ops; |
| 1314 | struct dentry *dbgfs_dir = NULL; | 1314 | struct dentry *dbgfs_dir = NULL; |
| 1315 | struct iwl_op_mode *op_mode = NULL; | 1315 | struct iwl_op_mode *op_mode = NULL; |
| 1316 | int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY; | ||
| 1317 | |||
| 1318 | for (retry = 0; retry <= max_retry; retry++) { | ||
| 1316 | 1319 | ||
| 1317 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1320 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 1318 | drv->dbgfs_op_mode = debugfs_create_dir(op->name, | 1321 | drv->dbgfs_op_mode = debugfs_create_dir(op->name, |
| 1319 | drv->dbgfs_drv); | 1322 | drv->dbgfs_drv); |
| 1320 | dbgfs_dir = drv->dbgfs_op_mode; | 1323 | dbgfs_dir = drv->dbgfs_op_mode; |
| 1321 | #endif | 1324 | #endif |
| 1322 | 1325 | ||
| 1323 | op_mode = ops->start(drv->trans, drv->trans->cfg, &drv->fw, dbgfs_dir); | 1326 | op_mode = ops->start(drv->trans, drv->trans->cfg, |
| 1327 | &drv->fw, dbgfs_dir); | ||
| 1328 | |||
| 1329 | if (op_mode) | ||
| 1330 | return op_mode; | ||
| 1331 | |||
| 1332 | IWL_ERR(drv, "retry init count %d\n", retry); | ||
| 1324 | 1333 | ||
| 1325 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1334 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 1326 | if (!op_mode) { | ||
| 1327 | debugfs_remove_recursive(drv->dbgfs_op_mode); | 1335 | debugfs_remove_recursive(drv->dbgfs_op_mode); |
| 1328 | drv->dbgfs_op_mode = NULL; | 1336 | drv->dbgfs_op_mode = NULL; |
| 1329 | } | ||
| 1330 | #endif | 1337 | #endif |
| 1338 | } | ||
| 1331 | 1339 | ||
| 1332 | return op_mode; | 1340 | return NULL; |
| 1333 | } | 1341 | } |
| 1334 | 1342 | ||
| 1335 | static void _iwl_op_mode_stop(struct iwl_drv *drv) | 1343 | static void _iwl_op_mode_stop(struct iwl_drv *drv) |
| @@ -89,4 +89,7 @@ void iwl_drv_stop(struct iwl_drv *drv); · 88 unmodified lines | |||
| 89 | #define IWL_EXPORT_SYMBOL(sym) | 89 | #define IWL_EXPORT_SYMBOL(sym) |
| 90 | #endif | 90 | #endif |
| 91 | 91 | ||
| 92 | /* max retry for init flow */ | ||
| 93 | #define IWL_MAX_INIT_RETRY 2 | ||
| 94 | |||
| 92 | #endif /* __iwl_drv_h__ */ | 95 | #endif /* __iwl_drv_h__ */ |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include <net/ieee80211_radiotap.h> | 16 | #include <net/ieee80211_radiotap.h> |
| 17 | #include <net/tcp.h> | 17 | #include <net/tcp.h> |
| 18 | 18 | ||
| 19 | #include "iwl-drv.h" | ||
| 19 | #include "iwl-op-mode.h" | 20 | #include "iwl-op-mode.h" |
| 20 | #include "iwl-io.h" | 21 | #include "iwl-io.h" |
| 21 | #include "mvm.h" | 22 | #include "mvm.h" |
| @@ -1117,9 +1118,30 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw) · 1095 unmodified lines | |||
| 1117 | { | 1118 | { |
| 1118 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 1119 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
| 1119 | int ret; | 1120 | int ret; |
| 1121 | int retry, max_retry = 0; | ||
| 1120 | 1122 | ||
| 1121 | mutex_lock(&mvm->mutex); | 1123 | mutex_lock(&mvm->mutex); |
| 1122 | ret = __iwl_mvm_mac_start(mvm); | 1124 | |
| 1125 | /* we are starting the mac not in error flow, and restart is enabled */ | ||
| 1126 | if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) && | ||
| 1127 | iwlwifi_mod_params.fw_restart) { | ||
| 1128 | max_retry = IWL_MAX_INIT_RETRY; | ||
| 1129 | /* | ||
| 1130 | * This will prevent mac80211 recovery flows to trigger during | ||
| 1131 | * init failures | ||
| 1132 | */ | ||
| 1133 | set_bit(IWL_MVM_STATUS_STARTING, &mvm->status); | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | for (retry = 0; retry <= max_retry; retry++) { | ||
| 1137 | ret = __iwl_mvm_mac_start(mvm); | ||
| 1138 | if (!ret) | ||
| 1139 | break; | ||
| 1140 | |||
| 1141 | IWL_ERR(mvm, "mac start retry %d\n", retry); | ||
| 1142 | } | ||
| 1143 | clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status); | ||
| 1144 | |||
| 1123 | mutex_unlock(&mvm->mutex); | 1145 | mutex_unlock(&mvm->mutex); |
| 1124 | 1146 | ||
| 1125 | return ret; | 1147 | return ret; |
| @@ -1123,6 +1123,8 @@ struct iwl_mvm { · 1122 unmodified lines | |||
| 1123 | * @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running | 1123 | * @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running |
| 1124 | * @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA | 1124 | * @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA |
| 1125 | * @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it) | 1125 | * @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it) |
| 1126 | * @IWL_MVM_STATUS_STARTING: starting mac, | ||
| 1127 | * used to disable restart flow while in STARTING state | ||
| 1126 | */ | 1128 | */ |
| 1127 | enum iwl_mvm_status { | 1129 | enum iwl_mvm_status { |
| 1128 | IWL_MVM_STATUS_HW_RFKILL, | 1130 | IWL_MVM_STATUS_HW_RFKILL, |
| @@ -1134,6 +1136,7 @@ enum iwl_mvm_status { · 5 unmodified lines | |||
| 1134 | IWL_MVM_STATUS_FIRMWARE_RUNNING, | 1136 | IWL_MVM_STATUS_FIRMWARE_RUNNING, |
| 1135 | IWL_MVM_STATUS_NEED_FLUSH_P2P, | 1137 | IWL_MVM_STATUS_NEED_FLUSH_P2P, |
| 1136 | IWL_MVM_STATUS_IN_D3, | 1138 | IWL_MVM_STATUS_IN_D3, |
| 1139 | IWL_MVM_STATUS_STARTING, | ||
| 1137 | }; | 1140 | }; |
| 1138 | 1141 | ||
| 1139 | /* Keep track of completed init configuration */ | 1142 | /* Keep track of completed init configuration */ |
| @@ -686,6 +686,7 @@ static int iwl_mvm_start_get_nvm(struct iwl_mvm *mvm) · 685 unmodified lines | |||
| 686 | int ret; | 686 | int ret; |
| 687 | 687 | ||
| 688 | rtnl_lock(); | 688 | rtnl_lock(); |
| 689 | wiphy_lock(mvm->hw->wiphy); | ||
| 689 | mutex_lock(&mvm->mutex); | 690 | mutex_lock(&mvm->mutex); |
| 690 | 691 | ||
| 691 | ret = iwl_run_init_mvm_ucode(mvm); | 692 | ret = iwl_run_init_mvm_ucode(mvm); |
| @@ -701,6 +702,7 @@ static int iwl_mvm_start_get_nvm(struct iwl_mvm *mvm) · 9 unmodified lines | |||
| 701 | iwl_mvm_stop_device(mvm); | 702 | iwl_mvm_stop_device(mvm); |
| 702 | 703 | ||
| 703 | mutex_unlock(&mvm->mutex); | 704 | mutex_unlock(&mvm->mutex); |
| 705 | wiphy_unlock(mvm->hw->wiphy); | ||
| 704 | rtnl_unlock(); | 706 | rtnl_unlock(); |
| 705 | 707 | ||
| 706 | if (ret < 0) | 708 | if (ret < 0) |
| @@ -1600,6 +1602,9 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) · 893 unmodified lines | |||
| 1600 | */ | 1602 | */ |
| 1601 | if (!mvm->fw_restart && fw_error) { | 1603 | if (!mvm->fw_restart && fw_error) { |
| 1602 | iwl_fw_error_collect(&mvm->fwrt, false); | 1604 | iwl_fw_error_collect(&mvm->fwrt, false); |
| 1605 | } else if (test_bit(IWL_MVM_STATUS_STARTING, | ||
| 1606 | &mvm->status)) { | ||
| 1607 | IWL_ERR(mvm, "Starting mac, retry will be triggered anyway\n"); | ||
| 1603 | } else if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { | 1608 | } else if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { |
| 1604 | struct iwl_mvm_reprobe *reprobe; | 1609 | struct iwl_mvm_reprobe *reprobe; |
| 1605 | 1610 | ||
| @@ -1339,9 +1339,13 @@ iwl_pci_find_dev_info(u16 device, u16 subsystem_device, · 1338 unmodified lines | |||
| 1339 | u16 mac_type, u8 mac_step, | 1339 | u16 mac_type, u8 mac_step, |
| 1340 | u16 rf_type, u8 cdb, u8 rf_id, u8 no_160, u8 cores) | 1340 | u16 rf_type, u8 cdb, u8 rf_id, u8 no_160, u8 cores) |
| 1341 | { | 1341 | { |
| 1342 | int num_devices = ARRAY_SIZE(iwl_dev_info_table); | ||
| 1342 | int i; | 1343 | int i; |
| 1343 | 1344 | ||
| 1344 | for (i = ARRAY_SIZE(iwl_dev_info_table) - 1; i >= 0; i--) { | 1345 | if (!num_devices) |
| 1346 | return NULL; | ||
| 1347 | |||
| 1348 | for (i = num_devices - 1; i >= 0; i--) { | ||
| 1345 | const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i]; | 1349 | const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i]; |
| 1346 | 1350 | ||
| 1347 | if (dev_info->device != (u16)IWL_CFG_ANY && | 1351 | if (dev_info->device != (u16)IWL_CFG_ANY && |
| @@ -1442,8 +1446,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 94 unmodified lines | |||
| 1442 | */ | 1446 | */ |
| 1443 | if (iwl_trans->trans_cfg->rf_id && | 1447 | if (iwl_trans->trans_cfg->rf_id && |
| 1444 | iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000 && | 1448 | iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000 && |
| 1445 | !CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans)) | 1449 | !CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans)) { |
| 1450 | ret = -EINVAL; | ||
| 1446 | goto out_free_trans; | 1451 | goto out_free_trans; |
| 1452 | } | ||
| 1447 | 1453 | ||
| 1448 | dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device, | 1454 | dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device, |
| 1449 | CSR_HW_REV_TYPE(iwl_trans->hw_rev), | 1455 | CSR_HW_REV_TYPE(iwl_trans->hw_rev), |
| @@ -143,8 +143,6 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 142 unmodified lines | |||
| 143 | if (!wcid) | 143 | if (!wcid) |
| 144 | wcid = &dev->mt76.global_wcid; | 144 | wcid = &dev->mt76.global_wcid; |
| 145 | 145 | ||
| 146 | pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); | ||
| 147 | |||
| 148 | if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) { | 146 | if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) { |
| 149 | struct mt7615_phy *phy = &dev->phy; | 147 | struct mt7615_phy *phy = &dev->phy; |
| 150 | 148 | ||
| @@ -164,6 +162,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 13 unmodified lines | |||
| 164 | if (id < 0) | 162 | if (id < 0) |
| 165 | return id; | 163 | return id; |
| 166 | 164 | ||
| 165 | pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); | ||
| 167 | mt7615_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, sta, | 166 | mt7615_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, sta, |
| 168 | pid, key, false); | 167 | pid, key, false); |
| 169 | 168 | ||
| @@ -43,19 +43,11 @@ EXPORT_SYMBOL_GPL(mt7663_usb_sdio_reg_map); · 42 unmodified lines | |||
| 43 | static void | 43 | static void |
| 44 | mt7663_usb_sdio_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid, | 44 | mt7663_usb_sdio_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid, |
| 45 | enum mt76_txq_id qid, struct ieee80211_sta *sta, | 45 | enum mt76_txq_id qid, struct ieee80211_sta *sta, |
| 46 | struct ieee80211_key_conf *key, int pid, | ||
| 46 | struct sk_buff *skb) | 47 | struct sk_buff *skb) |
| 47 | { | 48 | { |
| 48 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 49 | __le32 *txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE); |
| 49 | struct ieee80211_key_conf *key = info->control.hw_key; | ||
| 50 | __le32 *txwi; | ||
| 51 | int pid; | ||
| 52 | |||
| 53 | if (!wcid) | ||
| 54 | wcid = &dev->mt76.global_wcid; | ||
| 55 | |||
| 56 | pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb); | ||
| 57 | 50 | ||
| 58 | txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE); | ||
| 59 | memset(txwi, 0, MT_USB_TXD_SIZE); | 51 | memset(txwi, 0, MT_USB_TXD_SIZE); |
| 60 | mt7615_mac_write_txwi(dev, txwi, skb, wcid, sta, pid, key, false); | 52 | mt7615_mac_write_txwi(dev, txwi, skb, wcid, sta, pid, key, false); |
| 61 | skb_push(skb, MT_USB_TXD_SIZE); | 53 | skb_push(skb, MT_USB_TXD_SIZE); |
| @@ -194,10 +186,14 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 132 unmodified lines | |||
| 194 | struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); | 186 | struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); |
| 195 | struct sk_buff *skb = tx_info->skb; | 187 | struct sk_buff *skb = tx_info->skb; |
| 196 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 188 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 189 | struct ieee80211_key_conf *key = info->control.hw_key; | ||
| 197 | struct mt7615_sta *msta; | 190 | struct mt7615_sta *msta; |
| 198 | int pad; | 191 | int pad, err, pktid; |
| 199 | 192 | ||
| 200 | msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL; | 193 | msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL; |
| 194 | if (!wcid) | ||
| 195 | wcid = &dev->mt76.global_wcid; | ||
| 196 | |||
| 201 | if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && | 197 | if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && |
| 202 | msta && !msta->rate_probe) { | 198 | msta && !msta->rate_probe) { |
| 203 | /* request to configure sampling rate */ | 199 | /* request to configure sampling rate */ |
| @@ -207,7 +203,8 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 3 unmodified lines | |||
| 207 | spin_unlock_bh(&dev->mt76.lock); | 203 | spin_unlock_bh(&dev->mt76.lock); |
| 208 | } | 204 | } |
| 209 | 205 | ||
| 210 | mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, skb); | 206 | pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb); |
| 207 | mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, key, pktid, skb); | ||
| 211 | if (mt76_is_usb(mdev)) { | 208 | if (mt76_is_usb(mdev)) { |
| 212 | u32 len = skb->len; | 209 | u32 len = skb->len; |
| 213 | 210 | ||
| @@ -217,7 +214,12 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 3 unmodified lines | |||
| 217 | pad = round_up(skb->len, 4) - skb->len; | 214 | pad = round_up(skb->len, 4) - skb->len; |
| 218 | } | 215 | } |
| 219 | 216 | ||
| 220 | return mt76_skb_adjust_pad(skb, pad); | 217 | err = mt76_skb_adjust_pad(skb, pad); |
| 218 | if (err) | ||
| 219 | /* Release pktid in case of error. */ | ||
| 220 | idr_remove(&wcid->pktid, pktid); | ||
| 221 | |||
| 222 | return err; | ||
| 221 | } | 223 | } |
| 222 | EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_prepare_skb); | 224 | EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_prepare_skb); |
| 223 | 225 | ||
| @@ -72,6 +72,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data, · 71 unmodified lines | |||
| 72 | bool ampdu = IEEE80211_SKB_CB(tx_info->skb)->flags & IEEE80211_TX_CTL_AMPDU; | 72 | bool ampdu = IEEE80211_SKB_CB(tx_info->skb)->flags & IEEE80211_TX_CTL_AMPDU; |
| 73 | enum mt76_qsel qsel; | 73 | enum mt76_qsel qsel; |
| 74 | u32 flags; | 74 | u32 flags; |
| 75 | int err; | ||
| 75 | 76 | ||
| 76 | mt76_insert_hdr_pad(tx_info->skb); | 77 | mt76_insert_hdr_pad(tx_info->skb); |
| 77 | 78 | ||
| @@ -106,7 +107,12 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data, · 28 unmodified lines | |||
| 106 | ewma_pktlen_add(&msta->pktlen, tx_info->skb->len); | 107 | ewma_pktlen_add(&msta->pktlen, tx_info->skb->len); |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | return mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags); | 110 | err = mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags); |
| 111 | if (err && wcid) | ||
| 112 | /* Release pktid in case of error. */ | ||
| 113 | idr_remove(&wcid->pktid, pid); | ||
| 114 | |||
| 115 | return err; | ||
| 110 | } | 116 | } |
| 111 | EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb); | 117 | EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb); |
| 112 | 118 | ||
| @@ -1151,8 +1151,14 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 1150 unmodified lines | |||
| 1151 | } | 1151 | } |
| 1152 | } | 1152 | } |
| 1153 | 1153 | ||
| 1154 | pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); | 1154 | t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size); |
| 1155 | t->skb = tx_info->skb; | ||
| 1156 | |||
| 1157 | id = mt76_token_consume(mdev, &t); | ||
| 1158 | if (id < 0) | ||
| 1159 | return id; | ||
| 1155 | 1160 | ||
| 1161 | pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); | ||
| 1156 | mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key, | 1162 | mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key, |
| 1157 | false); | 1163 | false); |
| 1158 | 1164 | ||
| @@ -1178,13 +1184,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 19 unmodified lines | |||
| 1178 | txp->bss_idx = mvif->idx; | 1184 | txp->bss_idx = mvif->idx; |
| 1179 | } | 1185 | } |
| 1180 | 1186 | ||
| 1181 | t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size); | ||
| 1182 | t->skb = tx_info->skb; | ||
| 1183 | |||
| 1184 | id = mt76_token_consume(mdev, &t); | ||
| 1185 | if (id < 0) | ||
| 1186 | return id; | ||
| 1187 | |||
| 1188 | txp->token = cpu_to_le16(id); | 1187 | txp->token = cpu_to_le16(id); |
| 1189 | if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) | 1188 | if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) |
| 1190 | txp->rept_wds_wcid = cpu_to_le16(wcid->idx); | 1189 | txp->rept_wds_wcid = cpu_to_le16(wcid->idx); |
| @@ -176,7 +176,7 @@ mt7915_get_phy_mode(struct ieee80211_vif *vif, struct ieee80211_sta *sta) · 175 unmodified lines | |||
| 176 | if (ht_cap->ht_supported) | 176 | if (ht_cap->ht_supported) |
| 177 | mode |= PHY_MODE_GN; | 177 | mode |= PHY_MODE_GN; |
| 178 | 178 | ||
| 179 | if (he_cap->has_he) | 179 | if (he_cap && he_cap->has_he) |
| 180 | mode |= PHY_MODE_AX_24G; | 180 | mode |= PHY_MODE_AX_24G; |
| 181 | } else if (band == NL80211_BAND_5GHZ) { | 181 | } else if (band == NL80211_BAND_5GHZ) { |
| 182 | mode |= PHY_MODE_A; | 182 | mode |= PHY_MODE_A; |
| @@ -187,7 +187,7 @@ mt7915_get_phy_mode(struct ieee80211_vif *vif, struct ieee80211_sta *sta) · 4 unmodified lines | |||
| 187 | if (vht_cap->vht_supported) | 187 | if (vht_cap->vht_supported) |
| 188 | mode |= PHY_MODE_AC; | 188 | mode |= PHY_MODE_AC; |
| 189 | 189 | ||
| 190 | if (he_cap->has_he) | 190 | if (he_cap && he_cap->has_he) |
| 191 | mode |= PHY_MODE_AX_5G; | 191 | mode |= PHY_MODE_AX_5G; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| @@ -142,15 +142,11 @@ out: · 141 unmodified lines | |||
| 142 | static void | 142 | static void |
| 143 | mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid, | 143 | mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid, |
| 144 | enum mt76_txq_id qid, struct ieee80211_sta *sta, | 144 | enum mt76_txq_id qid, struct ieee80211_sta *sta, |
| 145 | struct ieee80211_key_conf *key, int pid, | ||
| 145 | struct sk_buff *skb) | 146 | struct sk_buff *skb) |
| 146 | { | 147 | { |
| 147 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 148 | __le32 *txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE); |
| 148 | struct ieee80211_key_conf *key = info->control.hw_key; | ||
| 149 | __le32 *txwi; | ||
| 150 | int pid; | ||
| 151 | 149 | ||
| 152 | pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb); | ||
| 153 | txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE); | ||
| 154 | memset(txwi, 0, MT_SDIO_TXD_SIZE); | 150 | memset(txwi, 0, MT_SDIO_TXD_SIZE); |
| 155 | mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false); | 151 | mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false); |
| 156 | skb_push(skb, MT_SDIO_TXD_SIZE); | 152 | skb_push(skb, MT_SDIO_TXD_SIZE); |
| @@ -163,8 +159,9 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 6 unmodified lines | |||
| 163 | { | 159 | { |
| 164 | struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); | 160 | struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); |
| 165 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); | 161 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); |
| 162 | struct ieee80211_key_conf *key = info->control.hw_key; | ||
| 166 | struct sk_buff *skb = tx_info->skb; | 163 | struct sk_buff *skb = tx_info->skb; |
| 167 | int pad; | 164 | int err, pad, pktid; |
| 168 | 165 | ||
| 169 | if (unlikely(tx_info->skb->len <= ETH_HLEN)) | 166 | if (unlikely(tx_info->skb->len <= ETH_HLEN)) |
| 170 | return -EINVAL; | 167 | return -EINVAL; |
| @@ -181,12 +178,18 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, · 10 unmodified lines | |||
| 181 | } | 178 | } |
| 182 | } | 179 | } |
| 183 | 180 | ||
| 184 | mt7921s_write_txwi(dev, wcid, qid, sta, skb); | 181 | pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb); |
| 182 | mt7921s_write_txwi(dev, wcid, qid, sta, key, pktid, skb); | ||
| 185 | 183 | ||
| 186 | mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA); | 184 | mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA); |
| 187 | pad = round_up(skb->len, 4) - skb->len; | 185 | pad = round_up(skb->len, 4) - skb->len; |
| 188 | 186 | ||
| 189 | return mt76_skb_adjust_pad(skb, pad); | 187 | err = mt76_skb_adjust_pad(skb, pad); |
| 188 | if (err) | ||
| 189 | /* Release pktid in case of error. */ | ||
| 190 | idr_remove(&wcid->pktid, pktid); | ||
| 191 | |||
| 192 | return err; | ||
| 190 | } | 193 | } |
| 191 | 194 | ||
| 192 | void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e) | 195 | void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e) |
| @@ -173,7 +173,7 @@ mt76_tx_status_skb_get(struct mt76_dev *dev, struct mt76_wcid *wcid, int pktid, · 172 unmodified lines | |||
| 173 | if (!(cb->flags & MT_TX_CB_DMA_DONE)) | 173 | if (!(cb->flags & MT_TX_CB_DMA_DONE)) |
| 174 | continue; | 174 | continue; |
| 175 | 175 | ||
| 176 | if (!time_is_after_jiffies(cb->jiffies + | 176 | if (time_is_after_jiffies(cb->jiffies + |
| 177 | MT_TX_STATUS_SKB_TIMEOUT)) | 177 | MT_TX_STATUS_SKB_TIMEOUT)) |
| 178 | continue; | 178 | continue; |
| 179 | } | 179 | } |
| @@ -25,6 +25,9 @@ static bool rt2x00usb_check_usb_error(struct rt2x00_dev *rt2x00dev, int status) · 24 unmodified lines | |||
| 25 | if (status == -ENODEV || status == -ENOENT) | 25 | if (status == -ENODEV || status == -ENOENT) |
| 26 | return true; | 26 | return true; |
| 27 | 27 | ||
| 28 | if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) | ||
| 29 | return false; | ||
| 30 | |||
| 28 | if (status == -EPROTO || status == -ETIMEDOUT) | 31 | if (status == -EPROTO || status == -ETIMEDOUT) |
| 29 | rt2x00dev->num_proto_errs++; | 32 | rt2x00dev->num_proto_errs++; |
| 30 | else | 33 | else |
| @@ -91,7 +91,6 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, · 90 unmodified lines | |||
| 91 | info->section_num = GET_FW_HDR_SEC_NUM(fw); | 91 | info->section_num = GET_FW_HDR_SEC_NUM(fw); |
| 92 | info->hdr_len = RTW89_FW_HDR_SIZE + | 92 | info->hdr_len = RTW89_FW_HDR_SIZE + |
| 93 | info->section_num * RTW89_FW_SECTION_HDR_SIZE; | 93 | info->section_num * RTW89_FW_SECTION_HDR_SIZE; |
| 94 | SET_FW_HDR_PART_SIZE(fw, FWDL_SECTION_PER_PKT_LEN); | ||
| 95 | 94 | ||
| 96 | bin = fw + info->hdr_len; | 95 | bin = fw + info->hdr_len; |
| 97 | 96 | ||
| @@ -275,6 +274,7 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 l · 177 unmodified lines | |||
| 275 | } | 274 | } |
| 276 | 275 | ||
| 277 | skb_put_data(skb, fw, len); | 276 | skb_put_data(skb, fw, len); |
| 277 | SET_FW_HDR_PART_SIZE(skb->data, FWDL_SECTION_PER_PKT_LEN); | ||
| 278 | rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, | 278 | rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, |
| 279 | H2C_CAT_MAC, H2C_CL_MAC_FWDL, | 279 | H2C_CAT_MAC, H2C_CL_MAC_FWDL, |
| 280 | H2C_FUNC_MAC_FWHDR_DL, len); | 280 | H2C_FUNC_MAC_FWHDR_DL, len); |
| @@ -282,8 +282,10 @@ struct rtw89_h2creg_sch_tx_en { · 281 unmodified lines | |||
| 282 | le32_get_bits(*((__le32 *)(fwhdr) + 6), GENMASK(15, 8)) | 282 | le32_get_bits(*((__le32 *)(fwhdr) + 6), GENMASK(15, 8)) |
| 283 | #define GET_FW_HDR_CMD_VERSERION(fwhdr) \ | 283 | #define GET_FW_HDR_CMD_VERSERION(fwhdr) \ |
| 284 | le32_get_bits(*((__le32 *)(fwhdr) + 7), GENMASK(31, 24)) | 284 | le32_get_bits(*((__le32 *)(fwhdr) + 7), GENMASK(31, 24)) |
| 285 | #define SET_FW_HDR_PART_SIZE(fwhdr, val) \ | 285 | static inline void SET_FW_HDR_PART_SIZE(void *fwhdr, u32 val) |
| 286 | le32p_replace_bits((__le32 *)(fwhdr) + 7, val, GENMASK(15, 0)) | 286 | { |
| 287 | le32p_replace_bits((__le32 *)fwhdr + 7, val, GENMASK(15, 0)); | ||
| 288 | } | ||
| 287 | 289 | ||
| 288 | #define SET_CTRL_INFO_MACID(table, val) \ | 290 | #define SET_CTRL_INFO_MACID(table, val) \ |
| 289 | le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0)) | 291 | le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0)) |
| @@ -181,9 +181,9 @@ void ipc_imem_hrtimer_stop(struct hrtimer *hr_timer) · 180 unmodified lines | |||
| 181 | bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem) | 181 | bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem) |
| 182 | { | 182 | { |
| 183 | struct ipc_mem_channel *channel; | 183 | struct ipc_mem_channel *channel; |
| 184 | bool hpda_ctrl_pending = false; | ||
| 184 | struct sk_buff_head *ul_list; | 185 | struct sk_buff_head *ul_list; |
| 185 | bool hpda_pending = false; | 186 | bool hpda_pending = false; |
| 186 | bool forced_hpdu = false; | ||
| 187 | struct ipc_pipe *pipe; | 187 | struct ipc_pipe *pipe; |
| 188 | int i; | 188 | int i; |
| 189 | 189 | ||
| @@ -200,15 +200,19 @@ bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem) · 10 unmodified lines | |||
| 200 | ul_list = &channel->ul_list; | 200 | ul_list = &channel->ul_list; |
| 201 | 201 | ||
| 202 | /* Fill the transfer descriptor with the uplink buffer info. */ | 202 | /* Fill the transfer descriptor with the uplink buffer info. */ |
| 203 | hpda_pending |= ipc_protocol_ul_td_send(ipc_imem->ipc_protocol, | 203 | if (!ipc_imem_check_wwan_ips(channel)) { |
| 204 | hpda_ctrl_pending |= | ||
| 205 | ipc_protocol_ul_td_send(ipc_imem->ipc_protocol, | ||
| 204 | pipe, ul_list); | 206 | pipe, ul_list); |
| 205 | 207 | } else { | |
| 206 | /* forced HP update needed for non data channels */ | 208 | hpda_pending |= |
| 207 | if (hpda_pending && !ipc_imem_check_wwan_ips(channel)) | 209 | ipc_protocol_ul_td_send(ipc_imem->ipc_protocol, |
| 208 | forced_hpdu = true; | 210 | pipe, ul_list); |
| 211 | } | ||
| 209 | } | 212 | } |
| 210 | 213 | ||
| 211 | if (forced_hpdu) { | 214 | /* forced HP update needed for non data channels */ |
| 215 | if (hpda_ctrl_pending) { | ||
| 212 | hpda_pending = false; | 216 | hpda_pending = false; |
| 213 | ipc_protocol_doorbell_trigger(ipc_imem->ipc_protocol, | 217 | ipc_protocol_doorbell_trigger(ipc_imem->ipc_protocol, |
| 214 | IPC_HP_UL_WRITE_TD); | 218 | IPC_HP_UL_WRITE_TD); |
| @@ -527,6 +531,9 @@ static void ipc_imem_run_state_worker(struct work_struct *instance) · 312 unmodified lines | |||
| 527 | return; | 531 | return; |
| 528 | } | 532 | } |
| 529 | 533 | ||
| 534 | if (test_and_clear_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag)) | ||
| 535 | ipc_devlink_deinit(ipc_imem->ipc_devlink); | ||
| 536 | |||
| 530 | if (!ipc_imem_setup_cp_mux_cap_init(ipc_imem, &mux_cfg)) | 537 | if (!ipc_imem_setup_cp_mux_cap_init(ipc_imem, &mux_cfg)) |
| 531 | ipc_imem->mux = ipc_mux_init(&mux_cfg, ipc_imem); | 538 | ipc_imem->mux = ipc_mux_init(&mux_cfg, ipc_imem); |
| 532 | 539 | ||
| @@ -1167,7 +1174,7 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem) · 634 unmodified lines | |||
| 1167 | ipc_port_deinit(ipc_imem->ipc_port); | 1174 | ipc_port_deinit(ipc_imem->ipc_port); |
| 1168 | } | 1175 | } |
| 1169 | 1176 | ||
| 1170 | if (ipc_imem->ipc_devlink) | 1177 | if (test_and_clear_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag)) |
| 1171 | ipc_devlink_deinit(ipc_imem->ipc_devlink); | 1178 | ipc_devlink_deinit(ipc_imem->ipc_devlink); |
| 1172 | 1179 | ||
| 1173 | ipc_imem_device_ipc_uninit(ipc_imem); | 1180 | ipc_imem_device_ipc_uninit(ipc_imem); |
| @@ -1263,7 +1270,6 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, · 89 unmodified lines | |||
| 1263 | 1270 | ||
| 1264 | ipc_imem->pci_device_id = device_id; | 1271 | ipc_imem->pci_device_id = device_id; |
| 1265 | 1272 | ||
| 1266 | ipc_imem->ev_cdev_write_pending = false; | ||
| 1267 | ipc_imem->cp_version = 0; | 1273 | ipc_imem->cp_version = 0; |
| 1268 | ipc_imem->device_sleep = IPC_HOST_SLEEP_ENTER_SLEEP; | 1274 | ipc_imem->device_sleep = IPC_HOST_SLEEP_ENTER_SLEEP; |
| 1269 | 1275 | ||
| @@ -1331,6 +1337,8 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, · 61 unmodified lines | |||
| 1331 | 1337 | ||
| 1332 | if (ipc_flash_link_establish(ipc_imem)) | 1338 | if (ipc_flash_link_establish(ipc_imem)) |
| 1333 | goto devlink_channel_fail; | 1339 | goto devlink_channel_fail; |
| 1340 | |||
| 1341 | set_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag); | ||
| 1334 | } | 1342 | } |
| 1335 | return ipc_imem; | 1343 | return ipc_imem; |
| 1336 | devlink_channel_fail: | 1344 | devlink_channel_fail: |
| @@ -101,6 +101,7 @@ struct ipc_chnl_cfg; · 100 unmodified lines | |||
| 101 | #define IOSM_CHIP_INFO_SIZE_MAX 100 | 101 | #define IOSM_CHIP_INFO_SIZE_MAX 100 |
| 102 | 102 | ||
| 103 | #define FULLY_FUNCTIONAL 0 | 103 | #define FULLY_FUNCTIONAL 0 |
| 104 | #define IOSM_DEVLINK_INIT 1 | ||
| 104 | 105 | ||
| 105 | /* List of the supported UL/DL pipes. */ | 106 | /* List of the supported UL/DL pipes. */ |
| 106 | enum ipc_mem_pipes { | 107 | enum ipc_mem_pipes { |
| @@ -335,8 +336,6 @@ enum ipc_phase { · 228 unmodified lines | |||
| 335 | * process the irq actions. | 336 | * process the irq actions. |
| 336 | * @flag: Flag to monitor the state of driver | 337 | * @flag: Flag to monitor the state of driver |
| 337 | * @td_update_timer_suspended: if true then td update timer suspend | 338 | * @td_update_timer_suspended: if true then td update timer suspend |
| 338 | * @ev_cdev_write_pending: 0 means inform the IPC tasklet to pass | ||
| 339 | * the accumulated uplink buffers to CP. | ||
| 340 | * @ev_mux_net_transmit_pending:0 means inform the IPC tasklet to pass | 339 | * @ev_mux_net_transmit_pending:0 means inform the IPC tasklet to pass |
| 341 | * @reset_det_n: Reset detect flag | 340 | * @reset_det_n: Reset detect flag |
| 342 | * @pcie_wake_n: Pcie wake flag | 341 | * @pcie_wake_n: Pcie wake flag |
| @@ -374,7 +373,6 @@ struct iosm_imem { · 31 unmodified lines | |||
| 374 | u8 ev_irq_pending[IPC_IRQ_VECTORS]; | 373 | u8 ev_irq_pending[IPC_IRQ_VECTORS]; |
| 375 | unsigned long flag; | 374 | unsigned long flag; |
| 376 | u8 td_update_timer_suspended:1, | 375 | u8 td_update_timer_suspended:1, |
| 377 | ev_cdev_write_pending:1, | ||
| 378 | ev_mux_net_transmit_pending:1, | 376 | ev_mux_net_transmit_pending:1, |
| 379 | reset_det_n:1, | 377 | reset_det_n:1, |
| 380 | pcie_wake_n:1; | 378 | pcie_wake_n:1; |
| @@ -41,7 +41,6 @@ void ipc_imem_sys_wwan_close(struct iosm_imem *ipc_imem, int if_id, · 40 unmodified lines | |||
| 41 | static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg, | 41 | static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg, |
| 42 | void *msg, size_t size) | 42 | void *msg, size_t size) |
| 43 | { | 43 | { |
| 44 | ipc_imem->ev_cdev_write_pending = false; | ||
| 45 | ipc_imem_ul_send(ipc_imem); | 44 | ipc_imem_ul_send(ipc_imem); |
| 46 | 45 | ||
| 47 | return 0; | 46 | return 0; |
| @@ -50,11 +49,6 @@ static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg, · 2 unmodified lines | |||
| 50 | /* Through tasklet to do sio write. */ | 49 | /* Through tasklet to do sio write. */ |
| 51 | static int ipc_imem_call_cdev_write(struct iosm_imem *ipc_imem) | 50 | static int ipc_imem_call_cdev_write(struct iosm_imem *ipc_imem) |
| 52 | { | 51 | { |
| 53 | if (ipc_imem->ev_cdev_write_pending) | ||
| 54 | return -1; | ||
| 55 | |||
| 56 | ipc_imem->ev_cdev_write_pending = true; | ||
| 57 | |||
| 58 | return ipc_task_queue_send_task(ipc_imem, ipc_imem_tq_cdev_write, 0, | 52 | return ipc_task_queue_send_task(ipc_imem, ipc_imem_tq_cdev_write, 0, |
| 59 | NULL, 0, false); | 53 | NULL, 0, false); |
| 60 | } | 54 | } |
| @@ -450,6 +444,7 @@ void ipc_imem_sys_devlink_close(struct iosm_devlink *ipc_devlink) · 389 unmodified lines | |||
| 450 | /* Release the pipe resources */ | 444 | /* Release the pipe resources */ |
| 451 | ipc_imem_pipe_cleanup(ipc_imem, &channel->ul_pipe); | 445 | ipc_imem_pipe_cleanup(ipc_imem, &channel->ul_pipe); |
| 452 | ipc_imem_pipe_cleanup(ipc_imem, &channel->dl_pipe); | 446 | ipc_imem_pipe_cleanup(ipc_imem, &channel->dl_pipe); |
| 447 | ipc_imem->nr_of_channels--; | ||
| 453 | } | 448 | } |
| 454 | 449 | ||
| 455 | void ipc_imem_sys_devlink_notify_rx(struct iosm_devlink *ipc_devlink, | 450 | void ipc_imem_sys_devlink_notify_rx(struct iosm_devlink *ipc_devlink, |
| @@ -666,6 +666,7 @@ blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl, · 665 unmodified lines | |||
| 666 | struct request *rq) | 666 | struct request *rq) |
| 667 | { | 667 | { |
| 668 | if (ctrl->state != NVME_CTRL_DELETING_NOIO && | 668 | if (ctrl->state != NVME_CTRL_DELETING_NOIO && |
| 669 | ctrl->state != NVME_CTRL_DELETING && | ||
| 669 | ctrl->state != NVME_CTRL_DEAD && | 670 | ctrl->state != NVME_CTRL_DEAD && |
| 670 | !test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags) && | 671 | !test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags) && |
| 671 | !blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH)) | 672 | !blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH)) |
| @@ -1749,9 +1750,20 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) · 1077 unmodified lines | |||
| 1749 | */ | 1750 | */ |
| 1750 | if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT))) | 1751 | if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT))) |
| 1751 | return -EINVAL; | 1752 | return -EINVAL; |
| 1752 | if (ctrl->max_integrity_segments) | 1753 | |
| 1753 | ns->features |= | 1754 | ns->features |= NVME_NS_EXT_LBAS; |
| 1754 | (NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS); | 1755 | |
| 1756 | /* | ||
| 1757 | * The current fabrics transport drivers support namespace | ||
| 1758 | * metadata formats only if nvme_ns_has_pi() returns true. | ||
| 1759 | * Suppress support for all other formats so the namespace will | ||
| 1760 | * have a 0 capacity and not be usable through the block stack. | ||
| 1761 | * | ||
| 1762 | * Note, this check will need to be modified if any drivers | ||
| 1763 | * gain the ability to use other metadata formats. | ||
| 1764 | */ | ||
| 1765 | if (ctrl->max_integrity_segments && nvme_ns_has_pi(ns)) | ||
| 1766 | ns->features |= NVME_NS_METADATA_SUPPORTED; | ||
| 1755 | } else { | 1767 | } else { |
| 1756 | /* | 1768 | /* |
| 1757 | * For PCIe controllers, we can't easily remap the separate | 1769 | * For PCIe controllers, we can't easily remap the separate |
| @@ -2696,8 +2708,9 @@ static bool nvme_validate_cntlid(struct nvme_subsystem *subsys, · 938 unmodified lines | |||
| 2696 | 2708 | ||
| 2697 | if (tmp->cntlid == ctrl->cntlid) { | 2709 | if (tmp->cntlid == ctrl->cntlid) { |
| 2698 | dev_err(ctrl->device, | 2710 | dev_err(ctrl->device, |
| 2699 | "Duplicate cntlid %u with %s, rejecting\n", | 2711 | "Duplicate cntlid %u with %s, subsys %s, rejecting\n", |
| 2700 | ctrl->cntlid, dev_name(tmp->device)); | 2712 | ctrl->cntlid, dev_name(tmp->device), |
| 2713 | subsys->subnqn); | ||
| 2701 | return false; | 2714 | return false; |
| 2702 | } | 2715 | } |
| 2703 | 2716 | ||
| @@ -866,7 +866,7 @@ int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) · 865 unmodified lines | |||
| 866 | } | 866 | } |
| 867 | if (ana_log_size > ctrl->ana_log_size) { | 867 | if (ana_log_size > ctrl->ana_log_size) { |
| 868 | nvme_mpath_stop(ctrl); | 868 | nvme_mpath_stop(ctrl); |
| 869 | kfree(ctrl->ana_log_buf); | 869 | nvme_mpath_uninit(ctrl); |
| 870 | ctrl->ana_log_buf = kmalloc(ana_log_size, GFP_KERNEL); | 870 | ctrl->ana_log_buf = kmalloc(ana_log_size, GFP_KERNEL); |
| 871 | if (!ctrl->ana_log_buf) | 871 | if (!ctrl->ana_log_buf) |
| 872 | return -ENOMEM; | 872 | return -ENOMEM; |
| @@ -886,4 +886,5 @@ void nvme_mpath_uninit(struct nvme_ctrl *ctrl) · 13 unmodified lines | |||
| 886 | { | 886 | { |
| 887 | kfree(ctrl->ana_log_buf); | 887 | kfree(ctrl->ana_log_buf); |
| 888 | ctrl->ana_log_buf = NULL; | 888 | ctrl->ana_log_buf = NULL; |
| 889 | ctrl->ana_log_size = 0; | ||
| 889 | } | 890 | } |
| @@ -709,7 +709,7 @@ static inline bool nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, · 708 unmodified lines | |||
| 709 | return true; | 709 | return true; |
| 710 | if (ctrl->ops->flags & NVME_F_FABRICS && | 710 | if (ctrl->ops->flags & NVME_F_FABRICS && |
| 711 | ctrl->state == NVME_CTRL_DELETING) | 711 | ctrl->state == NVME_CTRL_DELETING) |
| 712 | return true; | 712 | return queue_live; |
| 713 | return __nvme_check_ready(ctrl, rq, queue_live); | 713 | return __nvme_check_ready(ctrl, rq, queue_live); |
| 714 | } | 714 | } |
| 715 | int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, | 715 | int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, |
| @@ -166,7 +166,10 @@ static int nvme_zone_parse_entry(struct nvme_ns *ns, · 165 unmodified lines | |||
| 166 | zone.len = ns->zsze; | 166 | zone.len = ns->zsze; |
| 167 | zone.capacity = nvme_lba_to_sect(ns, le64_to_cpu(entry->zcap)); | 167 | zone.capacity = nvme_lba_to_sect(ns, le64_to_cpu(entry->zcap)); |
| 168 | zone.start = nvme_lba_to_sect(ns, le64_to_cpu(entry->zslba)); | 168 | zone.start = nvme_lba_to_sect(ns, le64_to_cpu(entry->zslba)); |
| 169 | zone.wp = nvme_lba_to_sect(ns, le64_to_cpu(entry->wp)); | 169 | if (zone.cond == BLK_ZONE_COND_FULL) |
| 170 | zone.wp = zone.start + zone.len; | ||
| 171 | else | ||
| 172 | zone.wp = nvme_lba_to_sect(ns, le64_to_cpu(entry->wp)); | ||
| 170 | 173 | ||
| 171 | return cb(&zone, idx, data); | 174 | return cb(&zone, idx, data); |
| 172 | } | 175 | } |
| @@ -922,7 +922,14 @@ static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue, · 921 unmodified lines | |||
| 922 | size_t data_len = le32_to_cpu(req->cmd->common.dptr.sgl.length); | 922 | size_t data_len = le32_to_cpu(req->cmd->common.dptr.sgl.length); |
| 923 | int ret; | 923 | int ret; |
| 924 | 924 | ||
| 925 | if (!nvme_is_write(cmd->req.cmd) || | 925 | /* |
| 926 | * This command has not been processed yet, hence we are trying to | ||
| 927 | * figure out if there is still pending data left to receive. If | ||
| 928 | * we don't, we can simply prepare for the next pdu and bail out, | ||
| 929 | * otherwise we will need to prepare a buffer and receive the | ||
| 930 | * stale data before continuing forward. | ||
| 931 | */ | ||
| 932 | if (!nvme_is_write(cmd->req.cmd) || !data_len || | ||
| 926 | data_len > cmd->req.port->inline_data_size) { | 933 | data_len > cmd->req.port->inline_data_size) { |
| 927 | nvmet_prepare_receive_pdu(queue); | 934 | nvmet_prepare_receive_pdu(queue); |
| 928 | return; | 935 | return; |
| @@ -76,6 +76,26 @@ struct device_node *of_irq_find_parent(struct device_node *child) · 75 unmodified lines | |||
| 76 | } | 76 | } |
| 77 | EXPORT_SYMBOL_GPL(of_irq_find_parent); | 77 | EXPORT_SYMBOL_GPL(of_irq_find_parent); |
| 78 | 78 | ||
| 79 | /* | ||
| 80 | * These interrupt controllers abuse interrupt-map for unspeakable | ||
| 81 | * reasons and rely on the core code to *ignore* it (the drivers do | ||
| 82 | * their own parsing of the property). | ||
| 83 | * | ||
| 84 | * If you think of adding to the list for something *new*, think | ||
| 85 | * again. There is a high chance that you will be sent back to the | ||
| 86 | * drawing board. | ||
| 87 | */ | ||
| 88 | static const char * const of_irq_imap_abusers[] = { | ||
| 89 | "CBEA,platform-spider-pic", | ||
| 90 | "sti,platform-spider-pic", | ||
| 91 | "realtek,rtl-intc", | ||
| 92 | "fsl,ls1021a-extirq", | ||
| 93 | "fsl,ls1043a-extirq", | ||
| 94 | "fsl,ls1088a-extirq", | ||
| 95 | "renesas,rza1-irqc", | ||
| 96 | NULL, | ||
| 97 | }; | ||
| 98 | |||
| 79 | /** | 99 | /** |
| 80 | * of_irq_parse_raw - Low level interrupt tree parsing | 100 | * of_irq_parse_raw - Low level interrupt tree parsing |
| 81 | * @addr: address specifier (start of "reg" property of the device) in be32 format | 101 | * @addr: address specifier (start of "reg" property of the device) in be32 format |
| @@ -159,12 +179,15 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) · 77 unmodified lines | |||
| 159 | /* | 179 | /* |
| 160 | * Now check if cursor is an interrupt-controller and | 180 | * Now check if cursor is an interrupt-controller and |
| 161 | * if it is then we are done, unless there is an | 181 | * if it is then we are done, unless there is an |
| 162 | * interrupt-map which takes precedence. | 182 | * interrupt-map which takes precedence except on one |
| 183 | * of these broken platforms that want to parse | ||
| 184 | * interrupt-map themselves for $reason. | ||
| 163 | */ | 185 | */ |
| 164 | bool intc = of_property_read_bool(ipar, "interrupt-controller"); | 186 | bool intc = of_property_read_bool(ipar, "interrupt-controller"); |
| 165 | 187 | ||
| 166 | imap = of_get_property(ipar, "interrupt-map", &imaplen); | 188 | imap = of_get_property(ipar, "interrupt-map", &imaplen); |
| 167 | if (imap == NULL && intc) { | 189 | if (intc && |
| 190 | (!imap || of_device_compatible_match(ipar, of_irq_imap_abusers))) { | ||
| 168 | pr_debug(" -> got it !\n"); | 191 | pr_debug(" -> got it !\n"); |
| 169 | return 0; | 192 | return 0; |
| 170 | } | 193 | } |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/phy/phy.h> | 20 | #include <linux/phy/phy.h> |
| 21 | #include <linux/regulator/consumer.h> | 21 | #include <linux/regulator/consumer.h> |
| 22 | #include <linux/module.h> | ||
| 22 | 23 | ||
| 23 | #include "pcie-designware.h" | 24 | #include "pcie-designware.h" |
| 24 | 25 | ||
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/pm_domain.h> | 18 | #include <linux/pm_domain.h> |
| 19 | #include <linux/regmap.h> | 19 | #include <linux/regmap.h> |
| 20 | #include <linux/reset.h> | 20 | #include <linux/reset.h> |
| 21 | #include <linux/module.h> | ||
| 21 | 22 | ||
| 22 | #include "pcie-designware.h" | 23 | #include "pcie-designware.h" |
| 23 | 24 | ||
| @@ -32,7 +32,6 @@ · 31 unmodified lines | |||
| 32 | #define PCIE_CORE_DEV_ID_REG 0x0 | 32 | #define PCIE_CORE_DEV_ID_REG 0x0 |
| 33 | #define PCIE_CORE_CMD_STATUS_REG 0x4 | 33 | #define PCIE_CORE_CMD_STATUS_REG 0x4 |
| 34 | #define PCIE_CORE_DEV_REV_REG 0x8 | 34 | #define PCIE_CORE_DEV_REV_REG 0x8 |
| 35 | #define PCIE_CORE_EXP_ROM_BAR_REG 0x30 | ||
| 36 | #define PCIE_CORE_PCIEXP_CAP 0xc0 | 35 | #define PCIE_CORE_PCIEXP_CAP 0xc0 |
| 37 | #define PCIE_CORE_ERR_CAPCTL_REG 0x118 | 36 | #define PCIE_CORE_ERR_CAPCTL_REG 0x118 |
| 38 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) | 37 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) |
| @@ -774,10 +773,6 @@ advk_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge, · 735 unmodified lines | |||
| 774 | *value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); | 773 | *value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); |
| 775 | return PCI_BRIDGE_EMUL_HANDLED; | 774 | return PCI_BRIDGE_EMUL_HANDLED; |
| 776 | 775 | ||
| 777 | case PCI_ROM_ADDRESS1: | ||
| 778 | *value = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG); | ||
| 779 | return PCI_BRIDGE_EMUL_HANDLED; | ||
| 780 | |||
| 781 | case PCI_INTERRUPT_LINE: { | 776 | case PCI_INTERRUPT_LINE: { |
| 782 | /* | 777 | /* |
| 783 | * From the whole 32bit register we support reading from HW only | 778 | * From the whole 32bit register we support reading from HW only |
| @@ -810,10 +805,6 @@ advk_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, · 26 unmodified lines | |||
| 810 | advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG); | 805 | advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG); |
| 811 | break; | 806 | break; |
| 812 | 807 | ||
| 813 | case PCI_ROM_ADDRESS1: | ||
| 814 | advk_writel(pcie, new, PCIE_CORE_EXP_ROM_BAR_REG); | ||
| 815 | break; | ||
| 816 | |||
| 817 | case PCI_INTERRUPT_LINE: | 808 | case PCI_INTERRUPT_LINE: |
| 818 | if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) { | 809 | if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) { |
| 819 | u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG); | 810 | u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG); |
| @@ -516,7 +516,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, · 515 unmodified lines | |||
| 516 | int ret, i; | 516 | int ret, i; |
| 517 | 517 | ||
| 518 | reset = gpiod_get_from_of_node(np, "reset-gpios", 0, | 518 | reset = gpiod_get_from_of_node(np, "reset-gpios", 0, |
| 519 | GPIOD_OUT_LOW, "#PERST"); | 519 | GPIOD_OUT_LOW, "PERST#"); |
| 520 | if (IS_ERR(reset)) | 520 | if (IS_ERR(reset)) |
| 521 | return PTR_ERR(reset); | 521 | return PTR_ERR(reset); |
| 522 | 522 | ||
| @@ -539,12 +539,22 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, · 16 unmodified lines | |||
| 539 | 539 | ||
| 540 | rmw_set(PORT_APPCLK_EN, port->base + PORT_APPCLK); | 540 | rmw_set(PORT_APPCLK_EN, port->base + PORT_APPCLK); |
| 541 | 541 | ||
| 542 | /* Assert PERST# before setting up the clock */ | ||
| 543 | gpiod_set_value(reset, 1); | ||
| 544 | |||
| 542 | ret = apple_pcie_setup_refclk(pcie, port); | 545 | ret = apple_pcie_setup_refclk(pcie, port); |
| 543 | if (ret < 0) | 546 | if (ret < 0) |
| 544 | return ret; | 547 | return ret; |
| 545 | 548 | ||
| 549 | /* The minimal Tperst-clk value is 100us (PCIe CEM r5.0, 2.9.2) */ | ||
| 550 | usleep_range(100, 200); | ||
| 551 | |||
| 552 | /* Deassert PERST# */ | ||
| 546 | rmw_set(PORT_PERST_OFF, port->base + PORT_PERST); | 553 | rmw_set(PORT_PERST_OFF, port->base + PORT_PERST); |
| 547 | gpiod_set_value(reset, 1); | 554 | gpiod_set_value(reset, 0); |
| 555 | |||
| 556 | /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */ | ||
| 557 | msleep(100); | ||
| 548 | 558 | ||
| 549 | ret = readl_relaxed_poll_timeout(port->base + PORT_STATUS, stat, | 559 | ret = readl_relaxed_poll_timeout(port->base + PORT_STATUS, stat, |
| 550 | stat & PORT_STATUS_READY, 100, 250000); | 560 | stat & PORT_STATUS_READY, 100, 250000); |
| @@ -757,8 +757,8 @@ static int hi3670_pcie_phy_get_resources(struct hi3670_pcie_phy *phy, · 756 unmodified lines | |||
| 757 | return PTR_ERR(phy->sysctrl); | 757 | return PTR_ERR(phy->sysctrl); |
| 758 | 758 | ||
| 759 | phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl"); | 759 | phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl"); |
| 760 | if (IS_ERR(phy->sysctrl)) | 760 | if (IS_ERR(phy->pmctrl)) |
| 761 | return PTR_ERR(phy->sysctrl); | 761 | return PTR_ERR(phy->pmctrl); |
| 762 | 762 | ||
| 763 | /* clocks */ | 763 | /* clocks */ |
| 764 | phy->phy_ref_clk = devm_clk_get(dev, "phy_ref"); | 764 | phy->phy_ref_clk = devm_clk_get(dev, "phy_ref"); |
| @@ -82,9 +82,9 @@ · 81 unmodified lines | |||
| 82 | * struct mvebu_cp110_utmi - PHY driver data | 82 | * struct mvebu_cp110_utmi - PHY driver data |
| 83 | * | 83 | * |
| 84 | * @regs: PHY registers | 84 | * @regs: PHY registers |
| 85 | * @syscom: Regmap with system controller registers | 85 | * @syscon: Regmap with system controller registers |
| 86 | * @dev: device driver handle | 86 | * @dev: device driver handle |
| 87 | * @caps: PHY capabilities | 87 | * @ops: phy ops |
| 88 | */ | 88 | */ |
| 89 | struct mvebu_cp110_utmi { | 89 | struct mvebu_cp110_utmi { |
| 90 | void __iomem *regs; | 90 | void __iomem *regs; |
| @@ -127,12 +127,13 @@ struct phy_drvdata { · 126 unmodified lines | |||
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | /** | 129 | /** |
| 130 | * Write register and read back masked value to confirm it is written | 130 | * usb_phy_write_readback() - Write register and read back masked value to |
| 131 | * confirm it is written | ||
| 131 | * | 132 | * |
| 132 | * @base - QCOM DWC3 PHY base virtual address. | 133 | * @phy_dwc3: QCOM DWC3 phy context |
| 133 | * @offset - register offset. | 134 | * @offset: register offset. |
| 134 | * @mask - register bitmask specifying what should be updated | 135 | * @mask: register bitmask specifying what should be updated |
| 135 | * @val - value to write. | 136 | * @val: value to write. |
| 136 | */ | 137 | */ |
| 137 | static inline void usb_phy_write_readback(struct usb_phy *phy_dwc3, | 138 | static inline void usb_phy_write_readback(struct usb_phy *phy_dwc3, |
| 138 | u32 offset, | 139 | u32 offset, |
| @@ -171,11 +172,11 @@ static int wait_for_latch(void __iomem *addr) · 32 unmodified lines | |||
| 171 | } | 172 | } |
| 172 | 173 | ||
| 173 | /** | 174 | /** |
| 174 | * Write SSPHY register | 175 | * usb_ss_write_phycreg() - Write SSPHY register |
| 175 | * | 176 | * |
| 176 | * @base - QCOM DWC3 PHY base virtual address. | 177 | * @phy_dwc3: QCOM DWC3 phy context |
| 177 | * @addr - SSPHY address to write. | 178 | * @addr: SSPHY address to write. |
| 178 | * @val - value to write. | 179 | * @val: value to write. |
| 179 | */ | 180 | */ |
| 180 | static int usb_ss_write_phycreg(struct usb_phy *phy_dwc3, | 181 | static int usb_ss_write_phycreg(struct usb_phy *phy_dwc3, |
| 181 | u32 addr, u32 val) | 182 | u32 addr, u32 val) |
| @@ -209,10 +210,11 @@ err_wait: · 27 unmodified lines | |||
| 209 | } | 210 | } |
| 210 | 211 | ||
| 211 | /** | 212 | /** |
| 212 | * Read SSPHY register. | 213 | * usb_ss_read_phycreg() - Read SSPHY register. |
| 213 | * | 214 | * |
| 214 | * @base - QCOM DWC3 PHY base virtual address. | 215 | * @phy_dwc3: QCOM DWC3 phy context |
| 215 | * @addr - SSPHY address to read. | 216 | * @addr: SSPHY address to read. |
| 217 | * @val: pointer in which read is store. | ||
| 216 | */ | 218 | */ |
| 217 | static int usb_ss_read_phycreg(struct usb_phy *phy_dwc3, | 219 | static int usb_ss_read_phycreg(struct usb_phy *phy_dwc3, |
| 218 | u32 addr, u32 *val) | 220 | u32 addr, u32 *val) |
| @@ -2973,6 +2973,9 @@ struct qmp_phy_combo_cfg { · 2972 unmodified lines | |||
| 2973 | * @qmp: QMP phy to which this lane belongs | 2973 | * @qmp: QMP phy to which this lane belongs |
| 2974 | * @lane_rst: lane's reset controller | 2974 | * @lane_rst: lane's reset controller |
| 2975 | * @mode: current PHY mode | 2975 | * @mode: current PHY mode |
| 2976 | * @dp_aux_cfg: Display port aux config | ||
| 2977 | * @dp_opts: Display port optional config | ||
| 2978 | * @dp_clks: Display port clocks | ||
| 2976 | */ | 2979 | */ |
| 2977 | struct qmp_phy { | 2980 | struct qmp_phy { |
| 2978 | struct phy *phy; | 2981 | struct phy *phy; |
| @@ -1,5 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /** | 2 | /* |
| 3 | * Copyright (C) 2016 Linaro Ltd | 3 | * Copyright (C) 2016 Linaro Ltd |
| 4 | */ | 4 | */ |
| 5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
| @@ -478,7 +478,7 @@ static void stm32_usbphyc_phy_tuning(struct stm32_usbphyc *usbphyc, · 477 unmodified lines | |||
| 478 | if (!of_property_read_bool(np, "st,no-lsfs-fb-cap")) | 478 | if (!of_property_read_bool(np, "st,no-lsfs-fb-cap")) |
| 479 | usbphyc_phy->tune |= LFSCAPEN; | 479 | usbphyc_phy->tune |= LFSCAPEN; |
| 480 | 480 | ||
| 481 | if (of_property_read_bool(np, "st,slow-hs-slew-rate")) | 481 | if (of_property_read_bool(np, "st,decrease-hs-slew-rate")) |
| 482 | usbphyc_phy->tune |= HSDRVSLEW; | 482 | usbphyc_phy->tune |= HSDRVSLEW; |
| 483 | 483 | ||
| 484 | ret = of_property_read_u32(np, "st,tune-hs-dc-level", &val); | 484 | ret = of_property_read_u32(np, "st,tune-hs-dc-level", &val); |
| @@ -1,5 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /** | 2 | /* |
| 3 | * PCIe SERDES driver for AM654x SoC | 3 | * PCIe SERDES driver for AM654x SoC |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2018 - 2019 Texas Instruments Incorporated - http://www.ti.com/ | 5 | * Copyright (C) 2018 - 2019 Texas Instruments Incorporated - http://www.ti.com/ |
| @@ -1,5 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /** | 2 | /* |
| 3 | * Wrapper driver for SERDES used in J721E | 3 | * Wrapper driver for SERDES used in J721E |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ | 5 | * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ |
| @@ -89,9 +89,9 @@ static inline void omap_usb_writel(void __iomem *addr, unsigned int offset, · 88 unmodified lines | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | /** | 91 | /** |
| 92 | * omap_usb2_set_comparator - links the comparator present in the system with | 92 | * omap_usb2_set_comparator() - links the comparator present in the system with this phy |
| 93 | * this phy | 93 | * |
| 94 | * @comparator - the companion phy(comparator) for this phy | 94 | * @comparator: the companion phy(comparator) for this phy |
| 95 | * | 95 | * |
| 96 | * The phy companion driver should call this API passing the phy_companion | 96 | * The phy companion driver should call this API passing the phy_companion |
| 97 | * filled with set_vbus and start_srp to be used by usb phy. | 97 | * filled with set_vbus and start_srp to be used by usb phy. |
| @@ -1,5 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /** | 2 | /* |
| 3 | * tusb1210.c - TUSB1210 USB ULPI PHY driver | 3 | * tusb1210.c - TUSB1210 USB ULPI PHY driver |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2015 Intel Corporation | 5 | * Copyright (C) 2015 Intel Corporation |
| @@ -76,7 +76,7 @@ · 75 unmodified lines | |||
| 76 | #define AMD_CPU_ID_CZN AMD_CPU_ID_RN | 76 | #define AMD_CPU_ID_CZN AMD_CPU_ID_RN |
| 77 | #define AMD_CPU_ID_YC 0x14B5 | 77 | #define AMD_CPU_ID_YC 0x14B5 |
| 78 | 78 | ||
| 79 | #define PMC_MSG_DELAY_MIN_US 100 | 79 | #define PMC_MSG_DELAY_MIN_US 50 |
| 80 | #define RESPONSE_REGISTER_LOOP_MAX 20000 | 80 | #define RESPONSE_REGISTER_LOOP_MAX 20000 |
| 81 | 81 | ||
| 82 | #define SOC_SUBSYSTEM_IP_MAX 12 | 82 | #define SOC_SUBSYSTEM_IP_MAX 12 |
| @@ -99,6 +99,13 @@ static const struct dmi_system_id button_array_table[] = { · 98 unmodified lines | |||
| 99 | DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), | 99 | DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), |
| 100 | }, | 100 | }, |
| 101 | }, | 101 | }, |
| 102 | { | ||
| 103 | .ident = "Microsoft Surface Go 3", | ||
| 104 | .matches = { | ||
| 105 | DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), | ||
| 106 | DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"), | ||
| 107 | }, | ||
| 108 | }, | ||
| 102 | { } | 109 | { } |
| 103 | }; | 110 | }; |
| 104 | 111 | ||
| @@ -657,6 +657,18 @@ static int acpi_add(struct acpi_device *device) · 656 unmodified lines | |||
| 657 | if (product && strlen(product) > 4) | 657 | if (product && strlen(product) > 4) |
| 658 | switch (product[4]) { | 658 | switch (product[4]) { |
| 659 | case '5': | 659 | case '5': |
| 660 | if (strlen(product) > 5) | ||
| 661 | switch (product[5]) { | ||
| 662 | case 'N': | ||
| 663 | year = 2021; | ||
| 664 | break; | ||
| 665 | case '0': | ||
| 666 | year = 2016; | ||
| 667 | break; | ||
| 668 | default: | ||
| 669 | year = 2022; | ||
| 670 | } | ||
| 671 | break; | ||
| 660 | case '6': | 672 | case '6': |
| 661 | year = 2016; | 673 | year = 2016; |
| 662 | break; | 674 | break; |
| @@ -3015,6 +3015,8 @@ static struct attribute *hotkey_attributes[] = { · 3014 unmodified lines | |||
| 3015 | &dev_attr_hotkey_all_mask.attr, | 3015 | &dev_attr_hotkey_all_mask.attr, |
| 3016 | &dev_attr_hotkey_adaptive_all_mask.attr, | 3016 | &dev_attr_hotkey_adaptive_all_mask.attr, |
| 3017 | &dev_attr_hotkey_recommended_mask.attr, | 3017 | &dev_attr_hotkey_recommended_mask.attr, |
| 3018 | &dev_attr_hotkey_tablet_mode.attr, | ||
| 3019 | &dev_attr_hotkey_radio_sw.attr, | ||
| 3018 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | 3020 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL |
| 3019 | &dev_attr_hotkey_source_mask.attr, | 3021 | &dev_attr_hotkey_source_mask.attr, |
| 3020 | &dev_attr_hotkey_poll_freq.attr, | 3022 | &dev_attr_hotkey_poll_freq.attr, |
| @@ -5726,11 +5728,11 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { · 2705 unmodified lines | |||
| 5726 | "tpacpi::standby", | 5728 | "tpacpi::standby", |
| 5727 | "tpacpi::dock_status1", | 5729 | "tpacpi::dock_status1", |
| 5728 | "tpacpi::dock_status2", | 5730 | "tpacpi::dock_status2", |
| 5729 | "tpacpi::unknown_led2", | 5731 | "tpacpi::lid_logo_dot", |
| 5730 | "tpacpi::unknown_led3", | 5732 | "tpacpi::unknown_led3", |
| 5731 | "tpacpi::thinkvantage", | 5733 | "tpacpi::thinkvantage", |
| 5732 | }; | 5734 | }; |
| 5733 | #define TPACPI_SAFE_LEDS 0x1081U | 5735 | #define TPACPI_SAFE_LEDS 0x1481U |
| 5734 | 5736 | ||
| 5735 | static inline bool tpacpi_is_led_restricted(const unsigned int led) | 5737 | static inline bool tpacpi_is_led_restricted(const unsigned int led) |
| 5736 | { | 5738 | { |
| @@ -905,6 +905,16 @@ static const struct ts_dmi_data trekstor_primetab_t13b_data = { · 904 unmodified lines | |||
| 905 | .properties = trekstor_primetab_t13b_props, | 905 | .properties = trekstor_primetab_t13b_props, |
| 906 | }; | 906 | }; |
| 907 | 907 | ||
| 908 | static const struct property_entry trekstor_surftab_duo_w1_props[] = { | ||
| 909 | PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), | ||
| 910 | { } | ||
| 911 | }; | ||
| 912 | |||
| 913 | static const struct ts_dmi_data trekstor_surftab_duo_w1_data = { | ||
| 914 | .acpi_name = "GDIX1001:00", | ||
| 915 | .properties = trekstor_surftab_duo_w1_props, | ||
| 916 | }; | ||
| 917 | |||
| 908 | static const struct property_entry trekstor_surftab_twin_10_1_props[] = { | 918 | static const struct property_entry trekstor_surftab_twin_10_1_props[] = { |
| 909 | PROPERTY_ENTRY_U32("touchscreen-min-x", 20), | 919 | PROPERTY_ENTRY_U32("touchscreen-min-x", 20), |
| 910 | PROPERTY_ENTRY_U32("touchscreen-min-y", 0), | 920 | PROPERTY_ENTRY_U32("touchscreen-min-y", 0), |
| @@ -1502,6 +1512,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { · 591 unmodified lines | |||
| 1502 | DMI_MATCH(DMI_PRODUCT_NAME, "Primetab T13B"), | 1512 | DMI_MATCH(DMI_PRODUCT_NAME, "Primetab T13B"), |
| 1503 | }, | 1513 | }, |
| 1504 | }, | 1514 | }, |
| 1515 | { | ||
| 1516 | /* TrekStor SurfTab duo W1 10.1 ST10432-10b */ | ||
| 1517 | .driver_data = (void *)&trekstor_surftab_duo_w1_data, | ||
| 1518 | .matches = { | ||
| 1519 | DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"), | ||
| 1520 | DMI_MATCH(DMI_PRODUCT_NAME, "SurfTab duo W1 10.1 (VT4)"), | ||
| 1521 | }, | ||
| 1522 | }, | ||
| 1505 | { | 1523 | { |
| 1506 | /* TrekStor SurfTab twin 10.1 ST10432-8 */ | 1524 | /* TrekStor SurfTab twin 10.1 ST10432-8 */ |
| 1507 | .driver_data = (void *)&trekstor_surftab_twin_10_1_data, | 1525 | .driver_data = (void *)&trekstor_surftab_twin_10_1_data, |
| @@ -463,17 +463,12 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent) · 462 unmodified lines | |||
| 463 | 463 | ||
| 464 | static int __init init_dtpm(void) | 464 | static int __init init_dtpm(void) |
| 465 | { | 465 | { |
| 466 | struct dtpm_descr *dtpm_descr; | ||
| 467 | |||
| 468 | pct = powercap_register_control_type(NULL, "dtpm", NULL); | 466 | pct = powercap_register_control_type(NULL, "dtpm", NULL); |
| 469 | if (IS_ERR(pct)) { | 467 | if (IS_ERR(pct)) { |
| 470 | pr_err("Failed to register control type\n"); | 468 | pr_err("Failed to register control type\n"); |
| 471 | return PTR_ERR(pct); | 469 | return PTR_ERR(pct); |
| 472 | } | 470 | } |
| 473 | 471 | ||
| 474 | for_each_dtpm_table(dtpm_descr) | ||
| 475 | dtpm_descr->init(); | ||
| 476 | |||
| 477 | return 0; | 472 | return 0; |
| 478 | } | 473 | } |
| 479 | late_initcall(init_dtpm); | 474 | late_initcall(init_dtpm); |
| @@ -5095,14 +5095,9 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, · 5094 unmodified lines | |||
| 5095 | /* NPort Recovery mode or node is just allocated */ | 5095 | /* NPort Recovery mode or node is just allocated */ |
| 5096 | if (!lpfc_nlp_not_used(ndlp)) { | 5096 | if (!lpfc_nlp_not_used(ndlp)) { |
| 5097 | /* A LOGO is completing and the node is in NPR state. | 5097 | /* A LOGO is completing and the node is in NPR state. |
| 5098 | * If this a fabric node that cleared its transport | 5098 | * Just unregister the RPI because the node is still |
| 5099 | * registration, release the rpi. | 5099 | * required. |
| 5100 | */ | 5100 | */ |
| 5101 | spin_lock_irq(&ndlp->lock); | ||
| 5102 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | ||
| 5103 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
| 5104 | ndlp->nlp_flag |= NLP_RELEASE_RPI; | ||
| 5105 | spin_unlock_irq(&ndlp->lock); | ||
| 5106 | lpfc_unreg_rpi(vport, ndlp); | 5101 | lpfc_unreg_rpi(vport, ndlp); |
| 5107 | } else { | 5102 | } else { |
| 5108 | /* Indicate the node has already released, should | 5103 | /* Indicate the node has already released, should |
| @@ -282,12 +282,12 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, · 281 unmodified lines | |||
| 282 | if (rc) { | 282 | if (rc) { |
| 283 | pm8001_dbg(pm8001_ha, FAIL, | 283 | pm8001_dbg(pm8001_ha, FAIL, |
| 284 | "pm8001_setup_irq failed [ret: %d]\n", rc); | 284 | "pm8001_setup_irq failed [ret: %d]\n", rc); |
| 285 | goto err_out_shost; | 285 | goto err_out; |
| 286 | } | 286 | } |
| 287 | /* Request Interrupt */ | 287 | /* Request Interrupt */ |
| 288 | rc = pm8001_request_irq(pm8001_ha); | 288 | rc = pm8001_request_irq(pm8001_ha); |
| 289 | if (rc) | 289 | if (rc) |
| 290 | goto err_out_shost; | 290 | goto err_out; |
| 291 | 291 | ||
| 292 | count = pm8001_ha->max_q_num; | 292 | count = pm8001_ha->max_q_num; |
| 293 | /* Queues are chosen based on the number of cores/msix availability */ | 293 | /* Queues are chosen based on the number of cores/msix availability */ |
| @@ -423,8 +423,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, · 129 unmodified lines | |||
| 423 | pm8001_tag_init(pm8001_ha); | 423 | pm8001_tag_init(pm8001_ha); |
| 424 | return 0; | 424 | return 0; |
| 425 | 425 | ||
| 426 | err_out_shost: | ||
| 427 | scsi_remove_host(pm8001_ha->shost); | ||
| 428 | err_out_nodev: | 426 | err_out_nodev: |
| 429 | for (i = 0; i < pm8001_ha->max_memcnt; i++) { | 427 | for (i = 0; i < pm8001_ha->max_memcnt; i++) { |
| 430 | if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) { | 428 | if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) { |
| @@ -732,7 +732,6 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, · 731 unmodified lines | |||
| 732 | { | 732 | { |
| 733 | struct qedi_work_map *work, *work_tmp; | 733 | struct qedi_work_map *work, *work_tmp; |
| 734 | u32 proto_itt = cqe->itid; | 734 | u32 proto_itt = cqe->itid; |
| 735 | itt_t protoitt = 0; | ||
| 736 | int found = 0; | 735 | int found = 0; |
| 737 | struct qedi_cmd *qedi_cmd = NULL; | 736 | struct qedi_cmd *qedi_cmd = NULL; |
| 738 | u32 iscsi_cid; | 737 | u32 iscsi_cid; |
| @@ -812,16 +811,12 @@ unlock: · 73 unmodified lines | |||
| 812 | return; | 811 | return; |
| 813 | 812 | ||
| 814 | check_cleanup_reqs: | 813 | check_cleanup_reqs: |
| 815 | if (qedi_conn->cmd_cleanup_req > 0) { | 814 | if (atomic_inc_return(&qedi_conn->cmd_cleanup_cmpl) == |
| 816 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_TID, | 815 | qedi_conn->cmd_cleanup_req) { |
| 816 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_SCSI_TM, | ||
| 817 | "Freeing tid=0x%x for cid=0x%x\n", | 817 | "Freeing tid=0x%x for cid=0x%x\n", |
| 818 | cqe->itid, qedi_conn->iscsi_conn_id); | 818 | cqe->itid, qedi_conn->iscsi_conn_id); |
| 819 | qedi_conn->cmd_cleanup_cmpl++; | ||
| 820 | wake_up(&qedi_conn->wait_queue); | 819 | wake_up(&qedi_conn->wait_queue); |
| 821 | } else { | ||
| 822 | QEDI_ERR(&qedi->dbg_ctx, | ||
| 823 | "Delayed or untracked cleanup response, itt=0x%x, tid=0x%x, cid=0x%x\n", | ||
| 824 | protoitt, cqe->itid, qedi_conn->iscsi_conn_id); | ||
| 825 | } | 820 | } |
| 826 | } | 821 | } |
| 827 | 822 | ||
| @@ -1163,7 +1158,7 @@ int qedi_cleanup_all_io(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn, · 335 unmodified lines | |||
| 1163 | } | 1158 | } |
| 1164 | 1159 | ||
| 1165 | qedi_conn->cmd_cleanup_req = 0; | 1160 | qedi_conn->cmd_cleanup_req = 0; |
| 1166 | qedi_conn->cmd_cleanup_cmpl = 0; | 1161 | atomic_set(&qedi_conn->cmd_cleanup_cmpl, 0); |
| 1167 | 1162 | ||
| 1168 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_SCSI_TM, | 1163 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_SCSI_TM, |
| 1169 | "active_cmd_count=%d, cid=0x%x, in_recovery=%d, lun_reset=%d\n", | 1164 | "active_cmd_count=%d, cid=0x%x, in_recovery=%d, lun_reset=%d\n", |
| @@ -1215,16 +1210,15 @@ int qedi_cleanup_all_io(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn, · 45 unmodified lines | |||
| 1215 | qedi_conn->iscsi_conn_id); | 1210 | qedi_conn->iscsi_conn_id); |
| 1216 | 1211 | ||
| 1217 | rval = wait_event_interruptible_timeout(qedi_conn->wait_queue, | 1212 | rval = wait_event_interruptible_timeout(qedi_conn->wait_queue, |
| 1218 | ((qedi_conn->cmd_cleanup_req == | 1213 | (qedi_conn->cmd_cleanup_req == |
| 1219 | qedi_conn->cmd_cleanup_cmpl) || | 1214 | atomic_read(&qedi_conn->cmd_cleanup_cmpl)) || |
| 1220 | test_bit(QEDI_IN_RECOVERY, | 1215 | test_bit(QEDI_IN_RECOVERY, &qedi->flags), |
| 1221 | &qedi->flags)), | 1216 | 5 * HZ); |
| 1222 | 5 * HZ); | ||
| 1223 | if (rval) { | 1217 | if (rval) { |
| 1224 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_SCSI_TM, | 1218 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_SCSI_TM, |
| 1225 | "i/o cmd_cleanup_req=%d, equal to cmd_cleanup_cmpl=%d, cid=0x%x\n", | 1219 | "i/o cmd_cleanup_req=%d, equal to cmd_cleanup_cmpl=%d, cid=0x%x\n", |
| 1226 | qedi_conn->cmd_cleanup_req, | 1220 | qedi_conn->cmd_cleanup_req, |
| 1227 | qedi_conn->cmd_cleanup_cmpl, | 1221 | atomic_read(&qedi_conn->cmd_cleanup_cmpl), |
| 1228 | qedi_conn->iscsi_conn_id); | 1222 | qedi_conn->iscsi_conn_id); |
| 1229 | 1223 | ||
| 1230 | return 0; | 1224 | return 0; |
| @@ -1233,7 +1227,7 @@ int qedi_cleanup_all_io(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn, · 2 unmodified lines | |||
| 1233 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_SCSI_TM, | 1227 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_SCSI_TM, |
| 1234 | "i/o cmd_cleanup_req=%d, not equal to cmd_cleanup_cmpl=%d, cid=0x%x\n", | 1228 | "i/o cmd_cleanup_req=%d, not equal to cmd_cleanup_cmpl=%d, cid=0x%x\n", |
| 1235 | qedi_conn->cmd_cleanup_req, | 1229 | qedi_conn->cmd_cleanup_req, |
| 1236 | qedi_conn->cmd_cleanup_cmpl, | 1230 | atomic_read(&qedi_conn->cmd_cleanup_cmpl), |
| 1237 | qedi_conn->iscsi_conn_id); | 1231 | qedi_conn->iscsi_conn_id); |
| 1238 | 1232 | ||
| 1239 | iscsi_host_for_each_session(qedi->shost, | 1233 | iscsi_host_for_each_session(qedi->shost, |
| @@ -1242,11 +1236,10 @@ int qedi_cleanup_all_io(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn, · 2 unmodified lines | |||
| 1242 | 1236 | ||
| 1243 | /* Enable IOs for all other sessions except current.*/ | 1237 | /* Enable IOs for all other sessions except current.*/ |
| 1244 | if (!wait_event_interruptible_timeout(qedi_conn->wait_queue, | 1238 | if (!wait_event_interruptible_timeout(qedi_conn->wait_queue, |
| 1245 | (qedi_conn->cmd_cleanup_req == | 1239 | (qedi_conn->cmd_cleanup_req == |
| 1246 | qedi_conn->cmd_cleanup_cmpl) || | 1240 | atomic_read(&qedi_conn->cmd_cleanup_cmpl)) || |
| 1247 | test_bit(QEDI_IN_RECOVERY, | 1241 | test_bit(QEDI_IN_RECOVERY, &qedi->flags), |
| 1248 | &qedi->flags), | 1242 | 5 * HZ)) { |
| 1249 | 5 * HZ)) { | ||
| 1250 | iscsi_host_for_each_session(qedi->shost, | 1243 | iscsi_host_for_each_session(qedi->shost, |
| 1251 | qedi_mark_device_available); | 1244 | qedi_mark_device_available); |
| 1252 | return -1; | 1245 | return -1; |
| @@ -1266,7 +1259,7 @@ void qedi_clearsq(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn, · 13 unmodified lines | |||
| 1266 | 1259 | ||
| 1267 | qedi_ep = qedi_conn->ep; | 1260 | qedi_ep = qedi_conn->ep; |
| 1268 | qedi_conn->cmd_cleanup_req = 0; | 1261 | qedi_conn->cmd_cleanup_req = 0; |
| 1269 | qedi_conn->cmd_cleanup_cmpl = 0; | 1262 | atomic_set(&qedi_conn->cmd_cleanup_cmpl, 0); |
| 1270 | 1263 | ||
| 1271 | if (!qedi_ep) { | 1264 | if (!qedi_ep) { |
| 1272 | QEDI_WARN(&qedi->dbg_ctx, | 1265 | QEDI_WARN(&qedi->dbg_ctx, |
| @@ -412,7 +412,7 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session, · 411 unmodified lines | |||
| 412 | qedi_conn->iscsi_conn_id = qedi_ep->iscsi_cid; | 412 | qedi_conn->iscsi_conn_id = qedi_ep->iscsi_cid; |
| 413 | qedi_conn->fw_cid = qedi_ep->fw_cid; | 413 | qedi_conn->fw_cid = qedi_ep->fw_cid; |
| 414 | qedi_conn->cmd_cleanup_req = 0; | 414 | qedi_conn->cmd_cleanup_req = 0; |
| 415 | qedi_conn->cmd_cleanup_cmpl = 0; | 415 | atomic_set(&qedi_conn->cmd_cleanup_cmpl, 0); |
| 416 | 416 | ||
| 417 | if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn)) { | 417 | if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn)) { |
| 418 | rc = -EINVAL; | 418 | rc = -EINVAL; |
| @@ -155,7 +155,7 @@ struct qedi_conn { · 154 unmodified lines | |||
| 155 | spinlock_t list_lock; /* internal conn lock */ | 155 | spinlock_t list_lock; /* internal conn lock */ |
| 156 | u32 active_cmd_count; | 156 | u32 active_cmd_count; |
| 157 | u32 cmd_cleanup_req; | 157 | u32 cmd_cleanup_req; |
| 158 | u32 cmd_cleanup_cmpl; | 158 | atomic_t cmd_cleanup_cmpl; |
| 159 | 159 | ||
| 160 | u32 iscsi_conn_id; | 160 | u32 iscsi_conn_id; |
| 161 | int itt; | 161 | int itt; |
| @@ -2491,6 +2491,9 @@ ql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...) · 2490 unmodified lines | |||
| 2491 | struct va_format vaf; | 2491 | struct va_format vaf; |
| 2492 | char pbuf[64]; | 2492 | char pbuf[64]; |
| 2493 | 2493 | ||
| 2494 | if (!ql_mask_match(level) && !trace_ql_dbg_log_enabled()) | ||
| 2495 | return; | ||
| 2496 | |||
| 2494 | va_start(va, fmt); | 2497 | va_start(va, fmt); |
| 2495 | 2498 | ||
| 2496 | vaf.fmt = fmt; | 2499 | vaf.fmt = fmt; |
| @@ -4342,7 +4342,7 @@ static int resp_report_zones(struct scsi_cmnd *scp, · 4341 unmodified lines | |||
| 4342 | rep_max_zones = min((alloc_len - 64) >> ilog2(RZONES_DESC_HD), | 4342 | rep_max_zones = min((alloc_len - 64) >> ilog2(RZONES_DESC_HD), |
| 4343 | max_zones); | 4343 | max_zones); |
| 4344 | 4344 | ||
| 4345 | arr = kcalloc(RZONES_DESC_HD, alloc_len, GFP_ATOMIC); | 4345 | arr = kzalloc(alloc_len, GFP_ATOMIC); |
| 4346 | if (!arr) { | 4346 | if (!arr) { |
| 4347 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, | 4347 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, |
| 4348 | INSUFF_RES_ASCQ); | 4348 | INSUFF_RES_ASCQ); |
| @@ -421,6 +421,13 @@ static int ufs_intel_lkf_init(struct ufs_hba *hba) · 420 unmodified lines | |||
| 421 | return err; | 421 | return err; |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | static int ufs_intel_adl_init(struct ufs_hba *hba) | ||
| 425 | { | ||
| 426 | hba->nop_out_timeout = 200; | ||
| 427 | hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; | ||
| 428 | return ufs_intel_common_init(hba); | ||
| 429 | } | ||
| 430 | |||
| 424 | static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = { | 431 | static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = { |
| 425 | .name = "intel-pci", | 432 | .name = "intel-pci", |
| 426 | .init = ufs_intel_common_init, | 433 | .init = ufs_intel_common_init, |
| @@ -449,6 +456,15 @@ static struct ufs_hba_variant_ops ufs_intel_lkf_hba_vops = { · 22 unmodified lines | |||
| 449 | .device_reset = ufs_intel_device_reset, | 456 | .device_reset = ufs_intel_device_reset, |
| 450 | }; | 457 | }; |
| 451 | 458 | ||
| 459 | static struct ufs_hba_variant_ops ufs_intel_adl_hba_vops = { | ||
| 460 | .name = "intel-pci", | ||
| 461 | .init = ufs_intel_adl_init, | ||
| 462 | .exit = ufs_intel_common_exit, | ||
| 463 | .link_startup_notify = ufs_intel_link_startup_notify, | ||
| 464 | .resume = ufs_intel_resume, | ||
| 465 | .device_reset = ufs_intel_device_reset, | ||
| 466 | }; | ||
| 467 | |||
| 452 | #ifdef CONFIG_PM_SLEEP | 468 | #ifdef CONFIG_PM_SLEEP |
| 453 | static int ufshcd_pci_restore(struct device *dev) | 469 | static int ufshcd_pci_restore(struct device *dev) |
| 454 | { | 470 | { |
| @@ -563,6 +579,8 @@ static const struct pci_device_id ufshcd_pci_tbl[] = { · 108 unmodified lines | |||
| 563 | { PCI_VDEVICE(INTEL, 0x4B41), (kernel_ulong_t)&ufs_intel_ehl_hba_vops }, | 579 | { PCI_VDEVICE(INTEL, 0x4B41), (kernel_ulong_t)&ufs_intel_ehl_hba_vops }, |
| 564 | { PCI_VDEVICE(INTEL, 0x4B43), (kernel_ulong_t)&ufs_intel_ehl_hba_vops }, | 580 | { PCI_VDEVICE(INTEL, 0x4B43), (kernel_ulong_t)&ufs_intel_ehl_hba_vops }, |
| 565 | { PCI_VDEVICE(INTEL, 0x98FA), (kernel_ulong_t)&ufs_intel_lkf_hba_vops }, | 581 | { PCI_VDEVICE(INTEL, 0x98FA), (kernel_ulong_t)&ufs_intel_lkf_hba_vops }, |
| 582 | { PCI_VDEVICE(INTEL, 0x51FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops }, | ||
| 583 | { PCI_VDEVICE(INTEL, 0x54FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops }, | ||
| 566 | { } /* terminate list */ | 584 | { } /* terminate list */ |
| 567 | }; | 585 | }; |
| 568 | 586 | ||
| @@ -29,7 +29,7 @@ static const char * const fivr_strings[] = { · 28 unmodified lines | |||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | static const struct mmio_reg tgl_fivr_mmio_regs[] = { | 31 | static const struct mmio_reg tgl_fivr_mmio_regs[] = { |
| 32 | { 0, 0x5A18, 3, 0x7, 12}, /* vco_ref_code_lo */ | 32 | { 0, 0x5A18, 3, 0x7, 11}, /* vco_ref_code_lo */ |
| 33 | { 0, 0x5A18, 8, 0xFF, 16}, /* vco_ref_code_hi */ | 33 | { 0, 0x5A18, 8, 0xFF, 16}, /* vco_ref_code_hi */ |
| 34 | { 0, 0x5A08, 8, 0xFF, 0}, /* spread_spectrum_pct */ | 34 | { 0, 0x5A08, 8, 0xFF, 0}, /* spread_spectrum_pct */ |
| 35 | { 0, 0x5A08, 1, 0x1, 8}, /* spread_spectrum_clk_enable */ | 35 | { 0, 0x5A08, 1, 0x1, 8}, /* spread_spectrum_clk_enable */ |
| @@ -237,6 +237,7 @@ struct brcmuart_priv { · 236 unmodified lines | |||
| 237 | u32 rx_err; | 237 | u32 rx_err; |
| 238 | u32 rx_timeout; | 238 | u32 rx_timeout; |
| 239 | u32 rx_abort; | 239 | u32 rx_abort; |
| 240 | u32 saved_mctrl; | ||
| 240 | }; | 241 | }; |
| 241 | 242 | ||
| 242 | static struct dentry *brcmuart_debugfs_root; | 243 | static struct dentry *brcmuart_debugfs_root; |
| @@ -1133,16 +1134,27 @@ static int brcmuart_remove(struct platform_device *pdev) · 890 unmodified lines | |||
| 1133 | static int __maybe_unused brcmuart_suspend(struct device *dev) | 1134 | static int __maybe_unused brcmuart_suspend(struct device *dev) |
| 1134 | { | 1135 | { |
| 1135 | struct brcmuart_priv *priv = dev_get_drvdata(dev); | 1136 | struct brcmuart_priv *priv = dev_get_drvdata(dev); |
| 1137 | struct uart_8250_port *up = serial8250_get_port(priv->line); | ||
| 1138 | struct uart_port *port = &up->port; | ||
| 1136 | 1139 | ||
| 1137 | serial8250_suspend_port(priv->line); | 1140 | serial8250_suspend_port(priv->line); |
| 1138 | clk_disable_unprepare(priv->baud_mux_clk); | 1141 | clk_disable_unprepare(priv->baud_mux_clk); |
| 1139 | 1142 | ||
| 1143 | /* | ||
| 1144 | * This will prevent resume from enabling RTS before the | ||
| 1145 | * baud rate has been resored. | ||
| 1146 | */ | ||
| 1147 | priv->saved_mctrl = port->mctrl; | ||
| 1148 | port->mctrl = 0; | ||
| 1149 | |||
| 1140 | return 0; | 1150 | return 0; |
| 1141 | } | 1151 | } |
| 1142 | 1152 | ||
| 1143 | static int __maybe_unused brcmuart_resume(struct device *dev) | 1153 | static int __maybe_unused brcmuart_resume(struct device *dev) |
| 1144 | { | 1154 | { |
| 1145 | struct brcmuart_priv *priv = dev_get_drvdata(dev); | 1155 | struct brcmuart_priv *priv = dev_get_drvdata(dev); |
| 1156 | struct uart_8250_port *up = serial8250_get_port(priv->line); | ||
| 1157 | struct uart_port *port = &up->port; | ||
| 1146 | int ret; | 1158 | int ret; |
| 1147 | 1159 | ||
| 1148 | ret = clk_prepare_enable(priv->baud_mux_clk); | 1160 | ret = clk_prepare_enable(priv->baud_mux_clk); |
| @@ -1165,6 +1177,7 @@ static int __maybe_unused brcmuart_resume(struct device *dev) · 16 unmodified lines | |||
| 1165 | start_rx_dma(serial8250_get_port(priv->line)); | 1177 | start_rx_dma(serial8250_get_port(priv->line)); |
| 1166 | } | 1178 | } |
| 1167 | serial8250_resume_port(priv->line); | 1179 | serial8250_resume_port(priv->line); |
| 1180 | port->mctrl = priv->saved_mctrl; | ||
| 1168 | return 0; | 1181 | return 0; |
| 1169 | } | 1182 | } |
| 1170 | 1183 | ||
| @@ -1324,29 +1324,33 @@ pericom_do_set_divisor(struct uart_port *port, unsigned int baud, · 1323 unmodified lines | |||
| 1324 | { | 1324 | { |
| 1325 | int scr; | 1325 | int scr; |
| 1326 | int lcr; | 1326 | int lcr; |
| 1327 | int actual_baud; | ||
| 1328 | int tolerance; | ||
| 1329 | 1327 | ||
| 1330 | for (scr = 5 ; scr <= 15 ; scr++) { | 1328 | for (scr = 16; scr > 4; scr--) { |
| 1331 | actual_baud = 921600 * 16 / scr; | 1329 | unsigned int maxrate = port->uartclk / scr; |
| 1332 | tolerance = actual_baud / 50; | 1330 | unsigned int divisor = max(maxrate / baud, 1U); |
| 1331 | int delta = maxrate / divisor - baud; | ||
| 1333 | 1332 | ||
| 1334 | if ((baud < actual_baud + tolerance) && | 1333 | if (baud > maxrate + baud / 50) |
| 1335 | (baud > actual_baud - tolerance)) { | 1334 | continue; |
| 1336 | 1335 | ||
| 1336 | if (delta > baud / 50) | ||
| 1337 | divisor++; | ||
| 1338 | |||
| 1339 | if (divisor > 0xffff) | ||
| 1340 | continue; | ||
| 1341 | |||
| 1342 | /* Update delta due to possible divisor change */ | ||
| 1343 | delta = maxrate / divisor - baud; | ||
| 1344 | if (abs(delta) < baud / 50) { | ||
| 1337 | lcr = serial_port_in(port, UART_LCR); | 1345 | lcr = serial_port_in(port, UART_LCR); |
| 1338 | serial_port_out(port, UART_LCR, lcr | 0x80); | 1346 | serial_port_out(port, UART_LCR, lcr | 0x80); |
| 1339 | 1347 | serial_port_out(port, UART_DLL, divisor & 0xff); | |
| 1340 | serial_port_out(port, UART_DLL, 1); | 1348 | serial_port_out(port, UART_DLM, divisor >> 8 & 0xff); |
| 1341 | serial_port_out(port, UART_DLM, 0); | ||
| 1342 | serial_port_out(port, 2, 16 - scr); | 1349 | serial_port_out(port, 2, 16 - scr); |
| 1343 | serial_port_out(port, UART_LCR, lcr); | 1350 | serial_port_out(port, UART_LCR, lcr); |
| 1344 | return; | 1351 | return; |
| 1345 | } else if (baud > actual_baud) { | ||
| 1346 | break; | ||
| 1347 | } | 1352 | } |
| 1348 | } | 1353 | } |
| 1349 | serial8250_do_set_divisor(port, baud, quot, quot_frac); | ||
| 1350 | } | 1354 | } |
| 1351 | static int pci_pericom_setup(struct serial_private *priv, | 1355 | static int pci_pericom_setup(struct serial_private *priv, |
| 1352 | const struct pciserial_board *board, | 1356 | const struct pciserial_board *board, |
| @@ -2291,12 +2295,19 @@ static struct pci_serial_quirk pci_serial_quirks[] = { · 938 unmodified lines | |||
| 2291 | .setup = pci_pericom_setup_four_at_eight, | 2295 | .setup = pci_pericom_setup_four_at_eight, |
| 2292 | }, | 2296 | }, |
| 2293 | { | 2297 | { |
| 2294 | .vendor = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S, | 2298 | .vendor = PCI_VENDOR_ID_ACCESIO, |
| 2295 | .device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4, | 2299 | .device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4, |
| 2296 | .subvendor = PCI_ANY_ID, | 2300 | .subvendor = PCI_ANY_ID, |
| 2297 | .subdevice = PCI_ANY_ID, | 2301 | .subdevice = PCI_ANY_ID, |
| 2298 | .setup = pci_pericom_setup_four_at_eight, | 2302 | .setup = pci_pericom_setup_four_at_eight, |
| 2299 | }, | 2303 | }, |
| 2304 | { | ||
| 2305 | .vendor = PCI_VENDOR_ID_ACCESIO, | ||
| 2306 | .device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S, | ||
| 2307 | .subvendor = PCI_ANY_ID, | ||
| 2308 | .subdevice = PCI_ANY_ID, | ||
| 2309 | .setup = pci_pericom_setup_four_at_eight, | ||
| 2310 | }, | ||
| 2300 | { | 2311 | { |
| 2301 | .vendor = PCI_VENDOR_ID_ACCESIO, | 2312 | .vendor = PCI_VENDOR_ID_ACCESIO, |
| 2302 | .device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4, | 2313 | .device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4, |
| @@ -2024,13 +2024,6 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) · 2023 unmodified lines | |||
| 2024 | struct uart_8250_port *up = up_to_u8250p(port); | 2024 | struct uart_8250_port *up = up_to_u8250p(port); |
| 2025 | unsigned char mcr; | 2025 | unsigned char mcr; |
| 2026 | 2026 | ||
| 2027 | if (port->rs485.flags & SER_RS485_ENABLED) { | ||
| 2028 | if (serial8250_in_MCR(up) & UART_MCR_RTS) | ||
| 2029 | mctrl |= TIOCM_RTS; | ||
| 2030 | else | ||
| 2031 | mctrl &= ~TIOCM_RTS; | ||
| 2032 | } | ||
| 2033 | |||
| 2034 | mcr = serial8250_TIOCM_to_MCR(mctrl); | 2027 | mcr = serial8250_TIOCM_to_MCR(mctrl); |
| 2035 | 2028 | ||
| 2036 | mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; | 2029 | mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; |
| @@ -1533,7 +1533,7 @@ config SERIAL_LITEUART · 1532 unmodified lines | |||
| 1533 | tristate "LiteUART serial port support" | 1533 | tristate "LiteUART serial port support" |
| 1534 | depends on HAS_IOMEM | 1534 | depends on HAS_IOMEM |
| 1535 | depends on OF || COMPILE_TEST | 1535 | depends on OF || COMPILE_TEST |
| 1536 | depends on LITEX | 1536 | depends on LITEX || COMPILE_TEST |
| 1537 | select SERIAL_CORE | 1537 | select SERIAL_CORE |
| 1538 | help | 1538 | help |
| 1539 | This driver is for the FPGA-based LiteUART serial controller from LiteX | 1539 | This driver is for the FPGA-based LiteUART serial controller from LiteX |
| @@ -2947,6 +2947,7 @@ MODULE_DEVICE_TABLE(of, sbsa_uart_of_match); · 2946 unmodified lines | |||
| 2947 | 2947 | ||
| 2948 | static const struct acpi_device_id __maybe_unused sbsa_uart_acpi_match[] = { | 2948 | static const struct acpi_device_id __maybe_unused sbsa_uart_acpi_match[] = { |
| 2949 | { "ARMH0011", 0 }, | 2949 | { "ARMH0011", 0 }, |
| 2950 | { "ARMHB000", 0 }, | ||
| 2950 | {}, | 2951 | {}, |
| 2951 | }; | 2952 | }; |
| 2952 | MODULE_DEVICE_TABLE(acpi, sbsa_uart_acpi_match); | 2953 | MODULE_DEVICE_TABLE(acpi, sbsa_uart_acpi_match); |
| @@ -2625,6 +2625,7 @@ OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup); · 2624 unmodified lines | |||
| 2625 | OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup); | 2625 | OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup); |
| 2626 | OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1028a-lpuart", ls1028a_early_console_setup); | 2626 | OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1028a-lpuart", ls1028a_early_console_setup); |
| 2627 | OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup); | 2627 | OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup); |
| 2628 | OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8qxp-lpuart", lpuart32_imx_early_console_setup); | ||
| 2628 | EARLYCON_DECLARE(lpuart, lpuart_early_console_setup); | 2629 | EARLYCON_DECLARE(lpuart, lpuart_early_console_setup); |
| 2629 | EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup); | 2630 | EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup); |
| 2630 | 2631 | ||
| @@ -270,8 +270,10 @@ static int liteuart_probe(struct platform_device *pdev) · 269 unmodified lines | |||
| 270 | 270 | ||
| 271 | /* get membase */ | 271 | /* get membase */ |
| 272 | port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); | 272 | port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); |
| 273 | if (IS_ERR(port->membase)) | 273 | if (IS_ERR(port->membase)) { |
| 274 | return PTR_ERR(port->membase); | 274 | ret = PTR_ERR(port->membase); |
| 275 | goto err_erase_id; | ||
| 276 | } | ||
| 275 | 277 | ||
| 276 | /* values not from device tree */ | 278 | /* values not from device tree */ |
| 277 | port->dev = &pdev->dev; | 279 | port->dev = &pdev->dev; |
| @@ -285,7 +287,18 @@ static int liteuart_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 285 | port->line = dev_id; | 287 | port->line = dev_id; |
| 286 | spin_lock_init(&port->lock); | 288 | spin_lock_init(&port->lock); |
| 287 | 289 | ||
| 288 | return uart_add_one_port(&liteuart_driver, &uart->port); | 290 | platform_set_drvdata(pdev, port); |
| 291 | |||
| 292 | ret = uart_add_one_port(&liteuart_driver, &uart->port); | ||
| 293 | if (ret) | ||
| 294 | goto err_erase_id; | ||
| 295 | |||
| 296 | return 0; | ||
| 297 | |||
| 298 | err_erase_id: | ||
| 299 | xa_erase(&liteuart_array, uart->id); | ||
| 300 | |||
| 301 | return ret; | ||
| 289 | } | 302 | } |
| 290 | 303 | ||
| 291 | static int liteuart_remove(struct platform_device *pdev) | 304 | static int liteuart_remove(struct platform_device *pdev) |
| @@ -293,6 +306,7 @@ static int liteuart_remove(struct platform_device *pdev) · 1 unmodified line | |||
| 293 | struct uart_port *port = platform_get_drvdata(pdev); | 306 | struct uart_port *port = platform_get_drvdata(pdev); |
| 294 | struct liteuart_port *uart = to_liteuart_port(port); | 307 | struct liteuart_port *uart = to_liteuart_port(port); |
| 295 | 308 | ||
| 309 | uart_remove_one_port(&liteuart_driver, port); | ||
| 296 | xa_erase(&liteuart_array, uart->id); | 310 | xa_erase(&liteuart_array, uart->id); |
| 297 | 311 | ||
| 298 | return 0; | 312 | return 0; |
| @@ -598,6 +598,9 @@ static void msm_start_rx_dma(struct msm_port *msm_port) · 597 unmodified lines | |||
| 598 | u32 val; | 598 | u32 val; |
| 599 | int ret; | 599 | int ret; |
| 600 | 600 | ||
| 601 | if (IS_ENABLED(CONFIG_CONSOLE_POLL)) | ||
| 602 | return; | ||
| 603 | |||
| 601 | if (!dma->chan) | 604 | if (!dma->chan) |
| 602 | return; | 605 | return; |
| 603 | 606 | ||
| @@ -1506,7 +1506,7 @@ static struct tegra_uart_chip_data tegra20_uart_chip_data = { · 1505 unmodified lines | |||
| 1506 | .fifo_mode_enable_status = false, | 1506 | .fifo_mode_enable_status = false, |
| 1507 | .uart_max_port = 5, | 1507 | .uart_max_port = 5, |
| 1508 | .max_dma_burst_bytes = 4, | 1508 | .max_dma_burst_bytes = 4, |
| 1509 | .error_tolerance_low_range = 0, | 1509 | .error_tolerance_low_range = -4, |
| 1510 | .error_tolerance_high_range = 4, | 1510 | .error_tolerance_high_range = 4, |
| 1511 | }; | 1511 | }; |
| 1512 | 1512 | ||
| @@ -1517,7 +1517,7 @@ static struct tegra_uart_chip_data tegra30_uart_chip_data = { · 4 unmodified lines | |||
| 1517 | .fifo_mode_enable_status = false, | 1517 | .fifo_mode_enable_status = false, |
| 1518 | .uart_max_port = 5, | 1518 | .uart_max_port = 5, |
| 1519 | .max_dma_burst_bytes = 4, | 1519 | .max_dma_burst_bytes = 4, |
| 1520 | .error_tolerance_low_range = 0, | 1520 | .error_tolerance_low_range = -4, |
| 1521 | .error_tolerance_high_range = 4, | 1521 | .error_tolerance_high_range = 4, |
| 1522 | }; | 1522 | }; |
| 1523 | 1523 | ||
| @@ -1075,6 +1075,11 @@ uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) · 1074 unmodified lines | |||
| 1075 | goto out; | 1075 | goto out; |
| 1076 | 1076 | ||
| 1077 | if (!tty_io_error(tty)) { | 1077 | if (!tty_io_error(tty)) { |
| 1078 | if (uport->rs485.flags & SER_RS485_ENABLED) { | ||
| 1079 | set &= ~TIOCM_RTS; | ||
| 1080 | clear &= ~TIOCM_RTS; | ||
| 1081 | } | ||
| 1082 | |||
| 1078 | uart_update_mctrl(uport, set, clear); | 1083 | uart_update_mctrl(uport, set, clear); |
| 1079 | ret = 0; | 1084 | ret = 0; |
| 1080 | } | 1085 | } |
| @@ -1549,6 +1554,7 @@ static void uart_tty_port_shutdown(struct tty_port *port) · 468 unmodified lines | |||
| 1549 | { | 1554 | { |
| 1550 | struct uart_state *state = container_of(port, struct uart_state, port); | 1555 | struct uart_state *state = container_of(port, struct uart_state, port); |
| 1551 | struct uart_port *uport = uart_port_check(state); | 1556 | struct uart_port *uport = uart_port_check(state); |
| 1557 | char *buf; | ||
| 1552 | 1558 | ||
| 1553 | /* | 1559 | /* |
| 1554 | * At this point, we stop accepting input. To do this, we | 1560 | * At this point, we stop accepting input. To do this, we |
| @@ -1570,8 +1576,18 @@ static void uart_tty_port_shutdown(struct tty_port *port) · 15 unmodified lines | |||
| 1570 | */ | 1576 | */ |
| 1571 | tty_port_set_suspended(port, 0); | 1577 | tty_port_set_suspended(port, 0); |
| 1572 | 1578 | ||
| 1573 | uart_change_pm(state, UART_PM_STATE_OFF); | 1579 | /* |
| 1580 | * Free the transmit buffer. | ||
| 1581 | */ | ||
| 1582 | spin_lock_irq(&uport->lock); | ||
| 1583 | buf = state->xmit.buf; | ||
| 1584 | state->xmit.buf = NULL; | ||
| 1585 | spin_unlock_irq(&uport->lock); | ||
| 1574 | 1586 | ||
| 1587 | if (buf) | ||
| 1588 | free_page((unsigned long)buf); | ||
| 1589 | |||
| 1590 | uart_change_pm(state, UART_PM_STATE_OFF); | ||
| 1575 | } | 1591 | } |
| 1576 | 1592 | ||
| 1577 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | 1593 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) |
| @@ -337,19 +337,6 @@ static void cdns3_ep_inc_deq(struct cdns3_endpoint *priv_ep) · 336 unmodified lines | |||
| 337 | cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs); | 337 | cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | static void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req) | ||
| 341 | { | ||
| 342 | struct cdns3_endpoint *priv_ep = priv_req->priv_ep; | ||
| 343 | int current_trb = priv_req->start_trb; | ||
| 344 | |||
| 345 | while (current_trb != priv_req->end_trb) { | ||
| 346 | cdns3_ep_inc_deq(priv_ep); | ||
| 347 | current_trb = priv_ep->dequeue; | ||
| 348 | } | ||
| 349 | |||
| 350 | cdns3_ep_inc_deq(priv_ep); | ||
| 351 | } | ||
| 352 | |||
| 353 | /** | 340 | /** |
| 354 | * cdns3_allow_enable_l1 - enable/disable permits to transition to L1. | 341 | * cdns3_allow_enable_l1 - enable/disable permits to transition to L1. |
| 355 | * @priv_dev: Extended gadget object | 342 | * @priv_dev: Extended gadget object |
| @@ -1517,10 +1504,11 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, · 1161 unmodified lines | |||
| 1517 | 1504 | ||
| 1518 | trb = priv_ep->trb_pool + priv_ep->dequeue; | 1505 | trb = priv_ep->trb_pool + priv_ep->dequeue; |
| 1519 | 1506 | ||
| 1520 | /* Request was dequeued and TRB was changed to TRB_LINK. */ | 1507 | /* The TRB was changed as link TRB, and the request was handled at ep_dequeue */ |
| 1521 | if (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) { | 1508 | while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) { |
| 1522 | trace_cdns3_complete_trb(priv_ep, trb); | 1509 | trace_cdns3_complete_trb(priv_ep, trb); |
| 1523 | cdns3_move_deq_to_next_trb(priv_req); | 1510 | cdns3_ep_inc_deq(priv_ep); |
| 1511 | trb = priv_ep->trb_pool + priv_ep->dequeue; | ||
| 1524 | } | 1512 | } |
| 1525 | 1513 | ||
| 1526 | if (!request->stream_id) { | 1514 | if (!request->stream_id) { |
| @@ -987,6 +987,9 @@ int cdnsp_endpoint_init(struct cdnsp_device *pdev, · 986 unmodified lines | |||
| 987 | 987 | ||
| 988 | /* Set up the endpoint ring. */ | 988 | /* Set up the endpoint ring. */ |
| 989 | pep->ring = cdnsp_ring_alloc(pdev, 2, ring_type, max_packet, mem_flags); | 989 | pep->ring = cdnsp_ring_alloc(pdev, 2, ring_type, max_packet, mem_flags); |
| 990 | if (!pep->ring) | ||
| 991 | return -ENOMEM; | ||
| 992 | |||
| 990 | pep->skip = false; | 993 | pep->skip = false; |
| 991 | 994 | ||
| 992 | /* Fill the endpoint context */ | 995 | /* Fill the endpoint context */ |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
| 13 | #include <linux/slab.h> | ||
| 13 | #include "core.h" | 14 | #include "core.h" |
| 14 | #include "drd.h" | 15 | #include "drd.h" |
| 15 | #include "host-export.h" | 16 | #include "host-export.h" |
| @@ -406,7 +406,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, · 405 unmodified lines | |||
| 406 | * the USB-2 spec requires such endpoints to have wMaxPacketSize = 0 | 406 | * the USB-2 spec requires such endpoints to have wMaxPacketSize = 0 |
| 407 | * (see the end of section 5.6.3), so don't warn about them. | 407 | * (see the end of section 5.6.3), so don't warn about them. |
| 408 | */ | 408 | */ |
| 409 | maxp = usb_endpoint_maxp(&endpoint->desc); | 409 | maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize); |
| 410 | if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) { | 410 | if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) { |
| 411 | dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n", | 411 | dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n", |
| 412 | cfgno, inum, asnum, d->bEndpointAddress); | 412 | cfgno, inum, asnum, d->bEndpointAddress); |
| @@ -422,9 +422,9 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, · 9 unmodified lines | |||
| 422 | maxpacket_maxes = full_speed_maxpacket_maxes; | 422 | maxpacket_maxes = full_speed_maxpacket_maxes; |
| 423 | break; | 423 | break; |
| 424 | case USB_SPEED_HIGH: | 424 | case USB_SPEED_HIGH: |
| 425 | /* Bits 12..11 are allowed only for HS periodic endpoints */ | 425 | /* Multiple-transactions bits are allowed only for HS periodic endpoints */ |
| 426 | if (usb_endpoint_xfer_int(d) || usb_endpoint_xfer_isoc(d)) { | 426 | if (usb_endpoint_xfer_int(d) || usb_endpoint_xfer_isoc(d)) { |
| 427 | i = maxp & (BIT(12) | BIT(11)); | 427 | i = maxp & USB_EP_MAXP_MULT_MASK; |
| 428 | maxp &= ~i; | 428 | maxp &= ~i; |
| 429 | } | 429 | } |
| 430 | fallthrough; | 430 | fallthrough; |
| @@ -434,6 +434,9 @@ static const struct usb_device_id usb_quirk_list[] = { · 433 unmodified lines | |||
| 434 | { USB_DEVICE(0x1532, 0x0116), .driver_info = | 434 | { USB_DEVICE(0x1532, 0x0116), .driver_info = |
| 435 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, | 435 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, |
| 436 | 436 | ||
| 437 | /* Lenovo Powered USB-C Travel Hub (4X90S92381, RTL8153 GigE) */ | ||
| 438 | { USB_DEVICE(0x17ef, 0x721e), .driver_info = USB_QUIRK_NO_LPM }, | ||
| 439 | |||
| 437 | /* Lenovo ThinkCenter A630Z TI024Gen3 usb-audio */ | 440 | /* Lenovo ThinkCenter A630Z TI024Gen3 usb-audio */ |
| 438 | { USB_DEVICE(0x17ef, 0xa012), .driver_info = | 441 | { USB_DEVICE(0x17ef, 0xa012), .driver_info = |
| 439 | USB_QUIRK_DISCONNECT_SUSPEND }, | 442 | USB_QUIRK_DISCONNECT_SUSPEND }, |
| @@ -649,7 +649,6 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev) · 648 unmodified lines | |||
| 649 | struct dwc3_qcom *qcom = platform_get_drvdata(pdev); | 649 | struct dwc3_qcom *qcom = platform_get_drvdata(pdev); |
| 650 | struct device_node *np = pdev->dev.of_node, *dwc3_np; | 650 | struct device_node *np = pdev->dev.of_node, *dwc3_np; |
| 651 | struct device *dev = &pdev->dev; | 651 | struct device *dev = &pdev->dev; |
| 652 | struct property *prop; | ||
| 653 | int ret; | 652 | int ret; |
| 654 | 653 | ||
| 655 | dwc3_np = of_get_compatible_child(np, "snps,dwc3"); | 654 | dwc3_np = of_get_compatible_child(np, "snps,dwc3"); |
| @@ -658,20 +657,6 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev) · 2 unmodified lines | |||
| 658 | return -ENODEV; | 657 | return -ENODEV; |
| 659 | } | 658 | } |
| 660 | 659 | ||
| 661 | prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL); | ||
| 662 | if (!prop) { | ||
| 663 | ret = -ENOMEM; | ||
| 664 | dev_err(dev, "unable to allocate memory for property\n"); | ||
| 665 | goto node_put; | ||
| 666 | } | ||
| 667 | |||
| 668 | prop->name = "tx-fifo-resize"; | ||
| 669 | ret = of_add_property(dwc3_np, prop); | ||
| 670 | if (ret) { | ||
| 671 | dev_err(dev, "unable to add property\n"); | ||
| 672 | goto node_put; | ||
| 673 | } | ||
| 674 | |||
| 675 | ret = of_platform_populate(np, NULL, NULL, dev); | 660 | ret = of_platform_populate(np, NULL, NULL, dev); |
| 676 | if (ret) { | 661 | if (ret) { |
| 677 | dev_err(dev, "failed to register dwc3 core - %d\n", ret); | 662 | dev_err(dev, "failed to register dwc3 core - %d\n", ret); |
| @@ -1679,6 +1679,18 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) · 1678 unmodified lines | |||
| 1679 | struct usb_function *f = NULL; | 1679 | struct usb_function *f = NULL; |
| 1680 | u8 endp; | 1680 | u8 endp; |
| 1681 | 1681 | ||
| 1682 | if (w_length > USB_COMP_EP0_BUFSIZ) { | ||
| 1683 | if (ctrl->bRequestType == USB_DIR_OUT) { | ||
| 1684 | goto done; | ||
| 1685 | } else { | ||
| 1686 | /* Cast away the const, we are going to overwrite on purpose. */ | ||
| 1687 | __le16 *temp = (__le16 *)&ctrl->wLength; | ||
| 1688 | |||
| 1689 | *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ); | ||
| 1690 | w_length = USB_COMP_EP0_BUFSIZ; | ||
| 1691 | } | ||
| 1692 | } | ||
| 1693 | |||
| 1682 | /* partial re-init of the response message; the function or the | 1694 | /* partial re-init of the response message; the function or the |
| 1683 | * gadget might need to intercept e.g. a control-OUT completion | 1695 | * gadget might need to intercept e.g. a control-OUT completion |
| 1684 | * when we delegate to it. | 1696 | * when we delegate to it. |
| @@ -2209,7 +2221,7 @@ int composite_dev_prepare(struct usb_composite_driver *composite, · 524 unmodified lines | |||
| 2209 | if (!cdev->req) | 2221 | if (!cdev->req) |
| 2210 | return -ENOMEM; | 2222 | return -ENOMEM; |
| 2211 | 2223 | ||
| 2212 | cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); | 2224 | cdev->req->buf = kzalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); |
| 2213 | if (!cdev->req->buf) | 2225 | if (!cdev->req->buf) |
| 2214 | goto fail; | 2226 | goto fail; |
| 2215 | 2227 | ||
| @@ -137,7 +137,7 @@ static int dbgp_enable_ep_req(struct usb_ep *ep) · 136 unmodified lines | |||
| 137 | goto fail_1; | 137 | goto fail_1; |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | req->buf = kmalloc(DBGP_REQ_LEN, GFP_KERNEL); | 140 | req->buf = kzalloc(DBGP_REQ_LEN, GFP_KERNEL); |
| 141 | if (!req->buf) { | 141 | if (!req->buf) { |
| 142 | err = -ENOMEM; | 142 | err = -ENOMEM; |
| 143 | stp = 2; | 143 | stp = 2; |
| @@ -345,6 +345,19 @@ static int dbgp_setup(struct usb_gadget *gadget, · 201 unmodified lines | |||
| 345 | void *data = NULL; | 345 | void *data = NULL; |
| 346 | u16 len = 0; | 346 | u16 len = 0; |
| 347 | 347 | ||
| 348 | if (length > DBGP_REQ_LEN) { | ||
| 349 | if (ctrl->bRequestType == USB_DIR_OUT) { | ||
| 350 | return err; | ||
| 351 | } else { | ||
| 352 | /* Cast away the const, we are going to overwrite on purpose. */ | ||
| 353 | __le16 *temp = (__le16 *)&ctrl->wLength; | ||
| 354 | |||
| 355 | *temp = cpu_to_le16(DBGP_REQ_LEN); | ||
| 356 | length = DBGP_REQ_LEN; | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 360 | |||
| 348 | if (request == USB_REQ_GET_DESCRIPTOR) { | 361 | if (request == USB_REQ_GET_DESCRIPTOR) { |
| 349 | switch (value>>8) { | 362 | switch (value>>8) { |
| 350 | case USB_DT_DEVICE: | 363 | case USB_DT_DEVICE: |
| @@ -110,6 +110,8 @@ enum ep0_state { · 109 unmodified lines | |||
| 110 | /* enough for the whole queue: most events invalidate others */ | 110 | /* enough for the whole queue: most events invalidate others */ |
| 111 | #define N_EVENT 5 | 111 | #define N_EVENT 5 |
| 112 | 112 | ||
| 113 | #define RBUF_SIZE 256 | ||
| 114 | |||
| 113 | struct dev_data { | 115 | struct dev_data { |
| 114 | spinlock_t lock; | 116 | spinlock_t lock; |
| 115 | refcount_t count; | 117 | refcount_t count; |
| @@ -144,7 +146,7 @@ struct dev_data { · 28 unmodified lines | |||
| 144 | struct dentry *dentry; | 146 | struct dentry *dentry; |
| 145 | 147 | ||
| 146 | /* except this scratch i/o buffer for ep0 */ | 148 | /* except this scratch i/o buffer for ep0 */ |
| 147 | u8 rbuf [256]; | 149 | u8 rbuf[RBUF_SIZE]; |
| 148 | }; | 150 | }; |
| 149 | 151 | ||
| 150 | static inline void get_dev (struct dev_data *data) | 152 | static inline void get_dev (struct dev_data *data) |
| @@ -1331,6 +1333,18 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) · 1180 unmodified lines | |||
| 1331 | u16 w_value = le16_to_cpu(ctrl->wValue); | 1333 | u16 w_value = le16_to_cpu(ctrl->wValue); |
| 1332 | u16 w_length = le16_to_cpu(ctrl->wLength); | 1334 | u16 w_length = le16_to_cpu(ctrl->wLength); |
| 1333 | 1335 | ||
| 1336 | if (w_length > RBUF_SIZE) { | ||
| 1337 | if (ctrl->bRequestType == USB_DIR_OUT) { | ||
| 1338 | return value; | ||
| 1339 | } else { | ||
| 1340 | /* Cast away the const, we are going to overwrite on purpose. */ | ||
| 1341 | __le16 *temp = (__le16 *)&ctrl->wLength; | ||
| 1342 | |||
| 1343 | *temp = cpu_to_le16(RBUF_SIZE); | ||
| 1344 | w_length = RBUF_SIZE; | ||
| 1345 | } | ||
| 1346 | } | ||
| 1347 | |||
| 1334 | spin_lock (&dev->lock); | 1348 | spin_lock (&dev->lock); |
| 1335 | dev->setup_abort = 0; | 1349 | dev->setup_abort = 0; |
| 1336 | if (dev->state == STATE_DEV_UNCONNECTED) { | 1350 | if (dev->state == STATE_DEV_UNCONNECTED) { |
| @@ -717,6 +717,7 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci, · 716 unmodified lines | |||
| 717 | continue; | 717 | continue; |
| 718 | 718 | ||
| 719 | retval = xhci_disable_slot(xhci, i); | 719 | retval = xhci_disable_slot(xhci, i); |
| 720 | xhci_free_virt_device(xhci, i); | ||
| 720 | if (retval) | 721 | if (retval) |
| 721 | xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n", | 722 | xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n", |
| 722 | i, retval); | 723 | i, retval); |
| @@ -366,7 +366,9 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, · 365 unmodified lines | |||
| 366 | /* Must be called with xhci->lock held, releases and aquires lock back */ | 366 | /* Must be called with xhci->lock held, releases and aquires lock back */ |
| 367 | static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) | 367 | static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) |
| 368 | { | 368 | { |
| 369 | u32 temp_32; | 369 | struct xhci_segment *new_seg = xhci->cmd_ring->deq_seg; |
| 370 | union xhci_trb *new_deq = xhci->cmd_ring->dequeue; | ||
| 371 | u64 crcr; | ||
| 370 | int ret; | 372 | int ret; |
| 371 | 373 | ||
| 372 | xhci_dbg(xhci, "Abort command ring\n"); | 374 | xhci_dbg(xhci, "Abort command ring\n"); |
| @@ -375,13 +377,18 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) · 2 unmodified lines | |||
| 375 | 377 | ||
| 376 | /* | 378 | /* |
| 377 | * The control bits like command stop, abort are located in lower | 379 | * The control bits like command stop, abort are located in lower |
| 378 | * dword of the command ring control register. Limit the write | 380 | * dword of the command ring control register. |
| 379 | * to the lower dword to avoid corrupting the command ring pointer | 381 | * Some controllers require all 64 bits to be written to abort the ring. |
| 380 | * in case if the command ring is stopped by the time upper dword | 382 | * Make sure the upper dword is valid, pointing to the next command, |
| 381 | * is written. | 383 | * avoiding corrupting the command ring pointer in case the command ring |
| 384 | * is stopped by the time the upper dword is written. | ||
| 382 | */ | 385 | */ |
| 383 | temp_32 = readl(&xhci->op_regs->cmd_ring); | 386 | next_trb(xhci, NULL, &new_seg, &new_deq); |
| 384 | writel(temp_32 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); | 387 | if (trb_is_link(new_deq)) |
| 388 | next_trb(xhci, NULL, &new_seg, &new_deq); | ||
| 389 | |||
| 390 | crcr = xhci_trb_virt_to_dma(new_seg, new_deq); | ||
| 391 | xhci_write_64(xhci, crcr | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); | ||
| 385 | 392 | ||
| 386 | /* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the | 393 | /* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the |
| 387 | * completion of the Command Abort operation. If CRR is not negated in 5 | 394 | * completion of the Command Abort operation. If CRR is not negated in 5 |
| @@ -1518,7 +1525,6 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id) · 1130 unmodified lines | |||
| 1518 | if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) | 1525 | if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) |
| 1519 | /* Delete default control endpoint resources */ | 1526 | /* Delete default control endpoint resources */ |
| 1520 | xhci_free_device_endpoint_resources(xhci, virt_dev, true); | 1527 | xhci_free_device_endpoint_resources(xhci, virt_dev, true); |
| 1521 | xhci_free_virt_device(xhci, slot_id); | ||
| 1522 | } | 1528 | } |
| 1523 | 1529 | ||
| 1524 | static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id, | 1530 | static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id, |
| @@ -3934,7 +3934,6 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) · 3933 unmodified lines | |||
| 3934 | struct xhci_slot_ctx *slot_ctx; | 3934 | struct xhci_slot_ctx *slot_ctx; |
| 3935 | int i, ret; | 3935 | int i, ret; |
| 3936 | 3936 | ||
| 3937 | #ifndef CONFIG_USB_DEFAULT_PERSIST | ||
| 3938 | /* | 3937 | /* |
| 3939 | * We called pm_runtime_get_noresume when the device was attached. | 3938 | * We called pm_runtime_get_noresume when the device was attached. |
| 3940 | * Decrement the counter here to allow controller to runtime suspend | 3939 | * Decrement the counter here to allow controller to runtime suspend |
| @@ -3942,7 +3941,6 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) · 1 unmodified line | |||
| 3942 | */ | 3941 | */ |
| 3943 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 3942 | if (xhci->quirks & XHCI_RESET_ON_RESUME) |
| 3944 | pm_runtime_put_noidle(hcd->self.controller); | 3943 | pm_runtime_put_noidle(hcd->self.controller); |
| 3945 | #endif | ||
| 3946 | 3944 | ||
| 3947 | ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); | 3945 | ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); |
| 3948 | /* If the host is halted due to driver unload, we still need to free the | 3946 | /* If the host is halted due to driver unload, we still need to free the |
| @@ -3961,9 +3959,8 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) · 12 unmodified lines | |||
| 3961 | del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); | 3959 | del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); |
| 3962 | } | 3960 | } |
| 3963 | virt_dev->udev = NULL; | 3961 | virt_dev->udev = NULL; |
| 3964 | ret = xhci_disable_slot(xhci, udev->slot_id); | 3962 | xhci_disable_slot(xhci, udev->slot_id); |
| 3965 | if (ret) | 3963 | xhci_free_virt_device(xhci, udev->slot_id); |
| 3966 | xhci_free_virt_device(xhci, udev->slot_id); | ||
| 3967 | } | 3964 | } |
| 3968 | 3965 | ||
| 3969 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) | 3966 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) |
| @@ -3973,7 +3970,7 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) · 3 unmodified lines | |||
| 3973 | u32 state; | 3970 | u32 state; |
| 3974 | int ret = 0; | 3971 | int ret = 0; |
| 3975 | 3972 | ||
| 3976 | command = xhci_alloc_command(xhci, false, GFP_KERNEL); | 3973 | command = xhci_alloc_command(xhci, true, GFP_KERNEL); |
| 3977 | if (!command) | 3974 | if (!command) |
| 3978 | return -ENOMEM; | 3975 | return -ENOMEM; |
| 3979 | 3976 | ||
| @@ -3998,6 +3995,15 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) · 18 unmodified lines | |||
| 3998 | } | 3995 | } |
| 3999 | xhci_ring_cmd_db(xhci); | 3996 | xhci_ring_cmd_db(xhci); |
| 4000 | spin_unlock_irqrestore(&xhci->lock, flags); | 3997 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 3998 | |||
| 3999 | wait_for_completion(command->completion); | ||
| 4000 | |||
| 4001 | if (command->status != COMP_SUCCESS) | ||
| 4002 | xhci_warn(xhci, "Unsuccessful disable slot %u command, status %d\n", | ||
| 4003 | slot_id, command->status); | ||
| 4004 | |||
| 4005 | xhci_free_command(xhci, command); | ||
| 4006 | |||
| 4001 | return ret; | 4007 | return ret; |
| 4002 | } | 4008 | } |
| 4003 | 4009 | ||
| @@ -4094,23 +4100,20 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) · 90 unmodified lines | |||
| 4094 | 4100 | ||
| 4095 | xhci_debugfs_create_slot(xhci, slot_id); | 4101 | xhci_debugfs_create_slot(xhci, slot_id); |
| 4096 | 4102 | ||
| 4097 | #ifndef CONFIG_USB_DEFAULT_PERSIST | ||
| 4098 | /* | 4103 | /* |
| 4099 | * If resetting upon resume, we can't put the controller into runtime | 4104 | * If resetting upon resume, we can't put the controller into runtime |
| 4100 | * suspend if there is a device attached. | 4105 | * suspend if there is a device attached. |
| 4101 | */ | 4106 | */ |
| 4102 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 4107 | if (xhci->quirks & XHCI_RESET_ON_RESUME) |
| 4103 | pm_runtime_get_noresume(hcd->self.controller); | 4108 | pm_runtime_get_noresume(hcd->self.controller); |
| 4104 | #endif | ||
| 4105 | 4109 | ||
| 4106 | /* Is this a LS or FS device under a HS hub? */ | 4110 | /* Is this a LS or FS device under a HS hub? */ |
| 4107 | /* Hub or peripherial? */ | 4111 | /* Hub or peripherial? */ |
| 4108 | return 1; | 4112 | return 1; |
| 4109 | 4113 | ||
| 4110 | disable_slot: | 4114 | disable_slot: |
| 4111 | ret = xhci_disable_slot(xhci, udev->slot_id); | 4115 | xhci_disable_slot(xhci, udev->slot_id); |
| 4112 | if (ret) | 4116 | xhci_free_virt_device(xhci, udev->slot_id); |
| 4113 | xhci_free_virt_device(xhci, udev->slot_id); | ||
| 4114 | 4117 | ||
| 4115 | return 0; | 4118 | return 0; |
| 4116 | } | 4119 | } |
| @@ -4240,6 +4243,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, · 123 unmodified lines | |||
| 4240 | 4243 | ||
| 4241 | mutex_unlock(&xhci->mutex); | 4244 | mutex_unlock(&xhci->mutex); |
| 4242 | ret = xhci_disable_slot(xhci, udev->slot_id); | 4245 | ret = xhci_disable_slot(xhci, udev->slot_id); |
| 4246 | xhci_free_virt_device(xhci, udev->slot_id); | ||
| 4243 | if (!ret) | 4247 | if (!ret) |
| 4244 | xhci_alloc_dev(hcd, udev); | 4248 | xhci_alloc_dev(hcd, udev); |
| 4245 | kfree(command->completion); | 4249 | kfree(command->completion); |
| @@ -4110,11 +4110,7 @@ static void run_state_machine(struct tcpm_port *port) · 4109 unmodified lines | |||
| 4110 | tcpm_try_src(port) ? SRC_TRY | 4110 | tcpm_try_src(port) ? SRC_TRY |
| 4111 | : SNK_ATTACHED, | 4111 | : SNK_ATTACHED, |
| 4112 | 0); | 4112 | 0); |
| 4113 | else | ||
| 4114 | /* Wait for VBUS, but not forever */ | ||
| 4115 | tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON); | ||
| 4116 | break; | 4113 | break; |
| 4117 | |||
| 4118 | case SRC_TRY: | 4114 | case SRC_TRY: |
| 4119 | port->try_src_count++; | 4115 | port->try_src_count++; |
| 4120 | tcpm_set_cc(port, tcpm_rp_cc(port)); | 4116 | tcpm_set_cc(port, tcpm_rp_cc(port)); |
| @@ -98,7 +98,8 @@ static ssize_t vfio_pci_igd_rw(struct vfio_pci_core_device *vdev, · 97 unmodified lines | |||
| 98 | version = cpu_to_le16(0x0201); | 98 | version = cpu_to_le16(0x0201); |
| 99 | 99 | ||
| 100 | if (igd_opregion_shift_copy(buf, &off, | 100 | if (igd_opregion_shift_copy(buf, &off, |
| 101 | &version + (pos - OPREGION_VERSION), | 101 | (u8 *)&version + |
| 102 | (pos - OPREGION_VERSION), | ||
| 102 | &pos, &remaining, bytes)) | 103 | &pos, &remaining, bytes)) |
| 103 | return -EFAULT; | 104 | return -EFAULT; |
| 104 | } | 105 | } |
| @@ -121,7 +122,7 @@ static ssize_t vfio_pci_igd_rw(struct vfio_pci_core_device *vdev, · 16 unmodified lines | |||
| 121 | OPREGION_SIZE : 0); | 122 | OPREGION_SIZE : 0); |
| 122 | 123 | ||
| 123 | if (igd_opregion_shift_copy(buf, &off, | 124 | if (igd_opregion_shift_copy(buf, &off, |
| 124 | &rvda + (pos - OPREGION_RVDA), | 125 | (u8 *)&rvda + (pos - OPREGION_RVDA), |
| 125 | &pos, &remaining, bytes)) | 126 | &pos, &remaining, bytes)) |
| 126 | return -EFAULT; | 127 | return -EFAULT; |
| 127 | } | 128 | } |
| @@ -232,7 +232,7 @@ static inline bool vfio_iommu_driver_allowed(struct vfio_container *container, · 231 unmodified lines | |||
| 232 | } | 232 | } |
| 233 | #endif /* CONFIG_VFIO_NOIOMMU */ | 233 | #endif /* CONFIG_VFIO_NOIOMMU */ |
| 234 | 234 | ||
| 235 | /** | 235 | /* |
| 236 | * IOMMU driver registration | 236 | * IOMMU driver registration |
| 237 | */ | 237 | */ |
| 238 | int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops) | 238 | int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops) |
| @@ -285,7 +285,7 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb, · 46 unmodified lines | |||
| 285 | unsigned long action, void *data); | 285 | unsigned long action, void *data); |
| 286 | static void vfio_group_get(struct vfio_group *group); | 286 | static void vfio_group_get(struct vfio_group *group); |
| 287 | 287 | ||
| 288 | /** | 288 | /* |
| 289 | * Container objects - containers are created when /dev/vfio/vfio is | 289 | * Container objects - containers are created when /dev/vfio/vfio is |
| 290 | * opened, but their lifecycle extends until the last user is done, so | 290 | * opened, but their lifecycle extends until the last user is done, so |
| 291 | * it's freed via kref. Must support container/group/device being | 291 | * it's freed via kref. Must support container/group/device being |
| @@ -309,7 +309,7 @@ static void vfio_container_put(struct vfio_container *container) · 17 unmodified lines | |||
| 309 | kref_put(&container->kref, vfio_container_release); | 309 | kref_put(&container->kref, vfio_container_release); |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | /** | 312 | /* |
| 313 | * Group objects - create, release, get, put, search | 313 | * Group objects - create, release, get, put, search |
| 314 | */ | 314 | */ |
| 315 | static struct vfio_group * | 315 | static struct vfio_group * |
| @@ -488,7 +488,7 @@ static struct vfio_group *vfio_group_get_from_dev(struct device *dev) · 172 unmodified lines | |||
| 488 | return group; | 488 | return group; |
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | /** | 491 | /* |
| 492 | * Device objects - create, release, get, put, search | 492 | * Device objects - create, release, get, put, search |
| 493 | */ | 493 | */ |
| 494 | /* Device reference always implies a group reference */ | 494 | /* Device reference always implies a group reference */ |
| @@ -595,7 +595,7 @@ static int vfio_dev_viable(struct device *dev, void *data) · 100 unmodified lines | |||
| 595 | return ret; | 595 | return ret; |
| 596 | } | 596 | } |
| 597 | 597 | ||
| 598 | /** | 598 | /* |
| 599 | * Async device support | 599 | * Async device support |
| 600 | */ | 600 | */ |
| 601 | static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev) | 601 | static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev) |
| @@ -689,7 +689,7 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb, · 87 unmodified lines | |||
| 689 | return NOTIFY_OK; | 689 | return NOTIFY_OK; |
| 690 | } | 690 | } |
| 691 | 691 | ||
| 692 | /** | 692 | /* |
| 693 | * VFIO driver API | 693 | * VFIO driver API |
| 694 | */ | 694 | */ |
| 695 | void vfio_init_group_dev(struct vfio_device *device, struct device *dev, | 695 | void vfio_init_group_dev(struct vfio_device *device, struct device *dev, |
| @@ -831,7 +831,7 @@ int vfio_register_emulated_iommu_dev(struct vfio_device *device) · 135 unmodified lines | |||
| 831 | } | 831 | } |
| 832 | EXPORT_SYMBOL_GPL(vfio_register_emulated_iommu_dev); | 832 | EXPORT_SYMBOL_GPL(vfio_register_emulated_iommu_dev); |
| 833 | 833 | ||
| 834 | /** | 834 | /* |
| 835 | * Get a reference to the vfio_device for a device. Even if the | 835 | * Get a reference to the vfio_device for a device. Even if the |
| 836 | * caller thinks they own the device, they could be racing with a | 836 | * caller thinks they own the device, they could be racing with a |
| 837 | * release call path, so we can't trust drvdata for the shortcut. | 837 | * release call path, so we can't trust drvdata for the shortcut. |
| @@ -965,7 +965,7 @@ void vfio_unregister_group_dev(struct vfio_device *device) · 127 unmodified lines | |||
| 965 | } | 965 | } |
| 966 | EXPORT_SYMBOL_GPL(vfio_unregister_group_dev); | 966 | EXPORT_SYMBOL_GPL(vfio_unregister_group_dev); |
| 967 | 967 | ||
| 968 | /** | 968 | /* |
| 969 | * VFIO base fd, /dev/vfio/vfio | 969 | * VFIO base fd, /dev/vfio/vfio |
| 970 | */ | 970 | */ |
| 971 | static long vfio_ioctl_check_extension(struct vfio_container *container, | 971 | static long vfio_ioctl_check_extension(struct vfio_container *container, |
| @@ -1183,7 +1183,7 @@ static const struct file_operations vfio_fops = { · 211 unmodified lines | |||
| 1183 | .compat_ioctl = compat_ptr_ioctl, | 1183 | .compat_ioctl = compat_ptr_ioctl, |
| 1184 | }; | 1184 | }; |
| 1185 | 1185 | ||
| 1186 | /** | 1186 | /* |
| 1187 | * VFIO Group fd, /dev/vfio/$GROUP | 1187 | * VFIO Group fd, /dev/vfio/$GROUP |
| 1188 | */ | 1188 | */ |
| 1189 | static void __vfio_group_unset_container(struct vfio_group *group) | 1189 | static void __vfio_group_unset_container(struct vfio_group *group) |
| @@ -1536,7 +1536,7 @@ static const struct file_operations vfio_group_fops = { · 346 unmodified lines | |||
| 1536 | .release = vfio_group_fops_release, | 1536 | .release = vfio_group_fops_release, |
| 1537 | }; | 1537 | }; |
| 1538 | 1538 | ||
| 1539 | /** | 1539 | /* |
| 1540 | * VFIO Device fd | 1540 | * VFIO Device fd |
| 1541 | */ | 1541 | */ |
| 1542 | static int vfio_device_fops_release(struct inode *inode, struct file *filep) | 1542 | static int vfio_device_fops_release(struct inode *inode, struct file *filep) |
| @@ -1611,7 +1611,7 @@ static const struct file_operations vfio_device_fops = { · 68 unmodified lines | |||
| 1611 | .mmap = vfio_device_fops_mmap, | 1611 | .mmap = vfio_device_fops_mmap, |
| 1612 | }; | 1612 | }; |
| 1613 | 1613 | ||
| 1614 | /** | 1614 | /* |
| 1615 | * External user API, exported by symbols to be linked dynamically. | 1615 | * External user API, exported by symbols to be linked dynamically. |
| 1616 | * | 1616 | * |
| 1617 | * The protocol includes: | 1617 | * The protocol includes: |
| @@ -1659,7 +1659,7 @@ struct vfio_group *vfio_group_get_external_user(struct file *filep) · 41 unmodified lines | |||
| 1659 | } | 1659 | } |
| 1660 | EXPORT_SYMBOL_GPL(vfio_group_get_external_user); | 1660 | EXPORT_SYMBOL_GPL(vfio_group_get_external_user); |
| 1661 | 1661 | ||
| 1662 | /** | 1662 | /* |
| 1663 | * External user API, exported by symbols to be linked dynamically. | 1663 | * External user API, exported by symbols to be linked dynamically. |
| 1664 | * The external user passes in a device pointer | 1664 | * The external user passes in a device pointer |
| 1665 | * to verify that: | 1665 | * to verify that: |
| @@ -1725,7 +1725,7 @@ long vfio_external_check_extension(struct vfio_group *group, unsigned long arg) · 59 unmodified lines | |||
| 1725 | } | 1725 | } |
| 1726 | EXPORT_SYMBOL_GPL(vfio_external_check_extension); | 1726 | EXPORT_SYMBOL_GPL(vfio_external_check_extension); |
| 1727 | 1727 | ||
| 1728 | /** | 1728 | /* |
| 1729 | * Sub-module support | 1729 | * Sub-module support |
| 1730 | */ | 1730 | */ |
| 1731 | /* | 1731 | /* |
| @@ -2272,7 +2272,7 @@ struct iommu_domain *vfio_group_iommu_domain(struct vfio_group *group) · 540 unmodified lines | |||
| 2272 | } | 2272 | } |
| 2273 | EXPORT_SYMBOL_GPL(vfio_group_iommu_domain); | 2273 | EXPORT_SYMBOL_GPL(vfio_group_iommu_domain); |
| 2274 | 2274 | ||
| 2275 | /** | 2275 | /* |
| 2276 | * Module/class support | 2276 | * Module/class support |
| 2277 | */ | 2277 | */ |
| 2278 | static char *vfio_devnode(struct device *dev, umode_t *mode) | 2278 | static char *vfio_devnode(struct device *dev, umode_t *mode) |
| @@ -366,11 +366,17 @@ static void vgacon_init(struct vc_data *c, int init) · 365 unmodified lines | |||
| 366 | struct uni_pagedir *p; | 366 | struct uni_pagedir *p; |
| 367 | 367 | ||
| 368 | /* | 368 | /* |
| 369 | * We cannot be loaded as a module, therefore init is always 1, | 369 | * We cannot be loaded as a module, therefore init will be 1 |
| 370 | * but vgacon_init can be called more than once, and init will | 370 | * if we are the default console, however if we are a fallback |
| 371 | * not be 1. | 371 | * console, for example if fbcon has failed registration, then |
| 372 | * init will be 0, so we need to make sure our boot parameters | ||
| 373 | * have been copied to the console structure for vgacon_resize | ||
| 374 | * ultimately called by vc_resize. Any subsequent calls to | ||
| 375 | * vgacon_init init will have init set to 0 too. | ||
| 372 | */ | 376 | */ |
| 373 | c->vc_can_do_color = vga_can_do_color; | 377 | c->vc_can_do_color = vga_can_do_color; |
| 378 | c->vc_scan_lines = vga_scan_lines; | ||
| 379 | c->vc_font.height = c->vc_cell_height = vga_video_font_height; | ||
| 374 | 380 | ||
| 375 | /* set dimensions manually if init != 0 since vc_resize() will fail */ | 381 | /* set dimensions manually if init != 0 since vc_resize() will fail */ |
| 376 | if (init) { | 382 | if (init) { |
| @@ -379,8 +385,6 @@ static void vgacon_init(struct vc_data *c, int init) · 2 unmodified lines | |||
| 379 | } else | 385 | } else |
| 380 | vc_resize(c, vga_video_num_columns, vga_video_num_lines); | 386 | vc_resize(c, vga_video_num_columns, vga_video_num_lines); |
| 381 | 387 | ||
| 382 | c->vc_scan_lines = vga_scan_lines; | ||
| 383 | c->vc_font.height = c->vc_cell_height = vga_video_font_height; | ||
| 384 | c->vc_complement_mask = 0x7700; | 388 | c->vc_complement_mask = 0x7700; |
| 385 | if (vga_512_chars) | 389 | if (vga_512_chars) |
| 386 | c->vc_hi_font_mask = 0x0800; | 390 | c->vc_hi_font_mask = 0x0800; |
| @@ -181,8 +181,9 @@ struct poll_iocb { · 180 unmodified lines | |||
| 181 | struct file *file; | 181 | struct file *file; |
| 182 | struct wait_queue_head *head; | 182 | struct wait_queue_head *head; |
| 183 | __poll_t events; | 183 | __poll_t events; |
| 184 | bool done; | ||
| 185 | bool cancelled; | 184 | bool cancelled; |
| 185 | bool work_scheduled; | ||
| 186 | bool work_need_resched; | ||
| 186 | struct wait_queue_entry wait; | 187 | struct wait_queue_entry wait; |
| 187 | struct work_struct work; | 188 | struct work_struct work; |
| 188 | }; | 189 | }; |
| @@ -1619,6 +1620,51 @@ static void aio_poll_put_work(struct work_struct *work) · 1430 unmodified lines | |||
| 1619 | iocb_put(iocb); | 1620 | iocb_put(iocb); |
| 1620 | } | 1621 | } |
| 1621 | 1622 | ||
| 1623 | /* | ||
| 1624 | * Safely lock the waitqueue which the request is on, synchronizing with the | ||
| 1625 | * case where the ->poll() provider decides to free its waitqueue early. | ||
| 1626 | * | ||
| 1627 | * Returns true on success, meaning that req->head->lock was locked, req->wait | ||
| 1628 | * is on req->head, and an RCU read lock was taken. Returns false if the | ||
| 1629 | * request was already removed from its waitqueue (which might no longer exist). | ||
| 1630 | */ | ||
| 1631 | static bool poll_iocb_lock_wq(struct poll_iocb *req) | ||
| 1632 | { | ||
| 1633 | wait_queue_head_t *head; | ||
| 1634 | |||
| 1635 | /* | ||
| 1636 | * While we hold the waitqueue lock and the waitqueue is nonempty, | ||
| 1637 | * wake_up_pollfree() will wait for us. However, taking the waitqueue | ||
| 1638 | * lock in the first place can race with the waitqueue being freed. | ||
| 1639 | * | ||
| 1640 | * We solve this as eventpoll does: by taking advantage of the fact that | ||
| 1641 | * all users of wake_up_pollfree() will RCU-delay the actual free. If | ||
| 1642 | * we enter rcu_read_lock() and see that the pointer to the queue is | ||
| 1643 | * non-NULL, we can then lock it without the memory being freed out from | ||
| 1644 | * under us, then check whether the request is still on the queue. | ||
| 1645 | * | ||
| 1646 | * Keep holding rcu_read_lock() as long as we hold the queue lock, in | ||
| 1647 | * case the caller deletes the entry from the queue, leaving it empty. | ||
| 1648 | * In that case, only RCU prevents the queue memory from being freed. | ||
| 1649 | */ | ||
| 1650 | rcu_read_lock(); | ||
| 1651 | head = smp_load_acquire(&req->head); | ||
| 1652 | if (head) { | ||
| 1653 | spin_lock(&head->lock); | ||
| 1654 | if (!list_empty(&req->wait.entry)) | ||
| 1655 | return true; | ||
| 1656 | spin_unlock(&head->lock); | ||
| 1657 | } | ||
| 1658 | rcu_read_unlock(); | ||
| 1659 | return false; | ||
| 1660 | } | ||
| 1661 | |||
| 1662 | static void poll_iocb_unlock_wq(struct poll_iocb *req) | ||
| 1663 | { | ||
| 1664 | spin_unlock(&req->head->lock); | ||
| 1665 | rcu_read_unlock(); | ||
| 1666 | } | ||
| 1667 | |||
| 1622 | static void aio_poll_complete_work(struct work_struct *work) | 1668 | static void aio_poll_complete_work(struct work_struct *work) |
| 1623 | { | 1669 | { |
| 1624 | struct poll_iocb *req = container_of(work, struct poll_iocb, work); | 1670 | struct poll_iocb *req = container_of(work, struct poll_iocb, work); |
| @@ -1638,14 +1684,27 @@ static void aio_poll_complete_work(struct work_struct *work) · 13 unmodified lines | |||
| 1638 | * avoid further branches in the fast path. | 1684 | * avoid further branches in the fast path. |
| 1639 | */ | 1685 | */ |
| 1640 | spin_lock_irq(&ctx->ctx_lock); | 1686 | spin_lock_irq(&ctx->ctx_lock); |
| 1641 | if (!mask && !READ_ONCE(req->cancelled)) { | 1687 | if (poll_iocb_lock_wq(req)) { |
| 1642 | add_wait_queue(req->head, &req->wait); | 1688 | if (!mask && !READ_ONCE(req->cancelled)) { |
| 1643 | spin_unlock_irq(&ctx->ctx_lock); | 1689 | /* |
| 1644 | return; | 1690 | * The request isn't actually ready to be completed yet. |
| 1645 | } | 1691 | * Reschedule completion if another wakeup came in. |
| 1692 | */ | ||
| 1693 | if (req->work_need_resched) { | ||
| 1694 | schedule_work(&req->work); | ||
| 1695 | req->work_need_resched = false; | ||
| 1696 | } else { | ||
| 1697 | req->work_scheduled = false; | ||
| 1698 | } | ||
| 1699 | poll_iocb_unlock_wq(req); | ||
| 1700 | spin_unlock_irq(&ctx->ctx_lock); | ||
| 1701 | return; | ||
| 1702 | } | ||
| 1703 | list_del_init(&req->wait.entry); | ||
| 1704 | poll_iocb_unlock_wq(req); | ||
| 1705 | } /* else, POLLFREE has freed the waitqueue, so we must complete */ | ||
| 1646 | list_del_init(&iocb->ki_list); | 1706 | list_del_init(&iocb->ki_list); |
| 1647 | iocb->ki_res.res = mangle_poll(mask); | 1707 | iocb->ki_res.res = mangle_poll(mask); |
| 1648 | req->done = true; | ||
| 1649 | spin_unlock_irq(&ctx->ctx_lock); | 1708 | spin_unlock_irq(&ctx->ctx_lock); |
| 1650 | 1709 | ||
| 1651 | iocb_put(iocb); | 1710 | iocb_put(iocb); |
| @@ -1657,13 +1716,14 @@ static int aio_poll_cancel(struct kiocb *iocb) · 5 unmodified lines | |||
| 1657 | struct aio_kiocb *aiocb = container_of(iocb, struct aio_kiocb, rw); | 1716 | struct aio_kiocb *aiocb = container_of(iocb, struct aio_kiocb, rw); |
| 1658 | struct poll_iocb *req = &aiocb->poll; | 1717 | struct poll_iocb *req = &aiocb->poll; |
| 1659 | 1718 | ||
| 1660 | spin_lock(&req->head->lock); | 1719 | if (poll_iocb_lock_wq(req)) { |
| 1661 | WRITE_ONCE(req->cancelled, true); | 1720 | WRITE_ONCE(req->cancelled, true); |
| 1662 | if (!list_empty(&req->wait.entry)) { | 1721 | if (!req->work_scheduled) { |
| 1663 | list_del_init(&req->wait.entry); | 1722 | schedule_work(&aiocb->poll.work); |
| 1664 | schedule_work(&aiocb->poll.work); | 1723 | req->work_scheduled = true; |
| 1665 | } | 1724 | } |
| 1666 | spin_unlock(&req->head->lock); | 1725 | poll_iocb_unlock_wq(req); |
| 1726 | } /* else, the request was force-cancelled by POLLFREE already */ | ||
| 1667 | 1727 | ||
| 1668 | return 0; | 1728 | return 0; |
| 1669 | } | 1729 | } |
| @@ -1680,21 +1740,27 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, · 10 unmodified lines | |||
| 1680 | if (mask && !(mask & req->events)) | 1740 | if (mask && !(mask & req->events)) |
| 1681 | return 0; | 1741 | return 0; |
| 1682 | 1742 | ||
| 1683 | list_del_init(&req->wait.entry); | 1743 | /* |
| 1684 | 1744 | * Complete the request inline if possible. This requires that three | |
| 1685 | if (mask && spin_trylock_irqsave(&iocb->ki_ctx->ctx_lock, flags)) { | 1745 | * conditions be met: |
| 1746 | * 1. An event mask must have been passed. If a plain wakeup was done | ||
| 1747 | * instead, then mask == 0 and we have to call vfs_poll() to get | ||
| 1748 | * the events, so inline completion isn't possible. | ||
| 1749 | * 2. The completion work must not have already been scheduled. | ||
| 1750 | * 3. ctx_lock must not be busy. We have to use trylock because we | ||
| 1751 | * already hold the waitqueue lock, so this inverts the normal | ||
| 1752 | * locking order. Use irqsave/irqrestore because not all | ||
| 1753 | * filesystems (e.g. fuse) call this function with IRQs disabled, | ||
| 1754 | * yet IRQs have to be disabled before ctx_lock is obtained. | ||
| 1755 | */ | ||
| 1756 | if (mask && !req->work_scheduled && | ||
| 1757 | spin_trylock_irqsave(&iocb->ki_ctx->ctx_lock, flags)) { | ||
| 1686 | struct kioctx *ctx = iocb->ki_ctx; | 1758 | struct kioctx *ctx = iocb->ki_ctx; |
| 1687 | 1759 | ||
| 1688 | /* | 1760 | list_del_init(&req->wait.entry); |
| 1689 | * Try to complete the iocb inline if we can. Use | ||
| 1690 | * irqsave/irqrestore because not all filesystems (e.g. fuse) | ||
| 1691 | * call this function with IRQs disabled and because IRQs | ||
| 1692 | * have to be disabled before ctx_lock is obtained. | ||
| 1693 | */ | ||
| 1694 | list_del(&iocb->ki_list); | 1761 | list_del(&iocb->ki_list); |
| 1695 | iocb->ki_res.res = mangle_poll(mask); | 1762 | iocb->ki_res.res = mangle_poll(mask); |
| 1696 | req->done = true; | 1763 | if (iocb->ki_eventfd && !eventfd_signal_allowed()) { |
| 1697 | if (iocb->ki_eventfd && eventfd_signal_allowed()) { | ||
| 1698 | iocb = NULL; | 1764 | iocb = NULL; |
| 1699 | INIT_WORK(&req->work, aio_poll_put_work); | 1765 | INIT_WORK(&req->work, aio_poll_put_work); |
| 1700 | schedule_work(&req->work); | 1766 | schedule_work(&req->work); |
| @@ -1703,7 +1769,43 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, · 2 unmodified lines | |||
| 1703 | if (iocb) | 1769 | if (iocb) |
| 1704 | iocb_put(iocb); | 1770 | iocb_put(iocb); |
| 1705 | } else { | 1771 | } else { |
| 1706 | schedule_work(&req->work); | 1772 | /* |
| 1773 | * Schedule the completion work if needed. If it was already | ||
| 1774 | * scheduled, record that another wakeup came in. | ||
| 1775 | * | ||
| 1776 | * Don't remove the request from the waitqueue here, as it might | ||
| 1777 | * not actually be complete yet (we won't know until vfs_poll() | ||
| 1778 | * is called), and we must not miss any wakeups. POLLFREE is an | ||
| 1779 | * exception to this; see below. | ||
| 1780 | */ | ||
| 1781 | if (req->work_scheduled) { | ||
| 1782 | req->work_need_resched = true; | ||
| 1783 | } else { | ||
| 1784 | schedule_work(&req->work); | ||
| 1785 | req->work_scheduled = true; | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | /* | ||
| 1789 | * If the waitqueue is being freed early but we can't complete | ||
| 1790 | * the request inline, we have to tear down the request as best | ||
| 1791 | * we can. That means immediately removing the request from its | ||
| 1792 | * waitqueue and preventing all further accesses to the | ||
| 1793 | * waitqueue via the request. We also need to schedule the | ||
| 1794 | * completion work (done above). Also mark the request as | ||
| 1795 | * cancelled, to potentially skip an unneeded call to ->poll(). | ||
| 1796 | */ | ||
| 1797 | if (mask & POLLFREE) { | ||
| 1798 | WRITE_ONCE(req->cancelled, true); | ||
| 1799 | list_del_init(&req->wait.entry); | ||
| 1800 | |||
| 1801 | /* | ||
| 1802 | * Careful: this *must* be the last step, since as soon | ||
| 1803 | * as req->head is NULL'ed out, the request can be | ||
| 1804 | * completed and freed, since aio_poll_complete_work() | ||
| 1805 | * will no longer need to take the waitqueue lock. | ||
| 1806 | */ | ||
| 1807 | smp_store_release(&req->head, NULL); | ||
| 1808 | } | ||
| 1707 | } | 1809 | } |
| 1708 | return 1; | 1810 | return 1; |
| 1709 | } | 1811 | } |
| @@ -1711,6 +1813,7 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, · 1 unmodified line | |||
| 1711 | struct aio_poll_table { | 1813 | struct aio_poll_table { |
| 1712 | struct poll_table_struct pt; | 1814 | struct poll_table_struct pt; |
| 1713 | struct aio_kiocb *iocb; | 1815 | struct aio_kiocb *iocb; |
| 1816 | bool queued; | ||
| 1714 | int error; | 1817 | int error; |
| 1715 | }; | 1818 | }; |
| 1716 | 1819 | ||
| @@ -1721,11 +1824,12 @@ aio_poll_queue_proc(struct file *file, struct wait_queue_head *head, · 4 unmodified lines | |||
| 1721 | struct aio_poll_table *pt = container_of(p, struct aio_poll_table, pt); | 1824 | struct aio_poll_table *pt = container_of(p, struct aio_poll_table, pt); |
| 1722 | 1825 | ||
| 1723 | /* multiple wait queues per file are not supported */ | 1826 | /* multiple wait queues per file are not supported */ |
| 1724 | if (unlikely(pt->iocb->poll.head)) { | 1827 | if (unlikely(pt->queued)) { |
| 1725 | pt->error = -EINVAL; | 1828 | pt->error = -EINVAL; |
| 1726 | return; | 1829 | return; |
| 1727 | } | 1830 | } |
| 1728 | 1831 | ||
| 1832 | pt->queued = true; | ||
| 1729 | pt->error = 0; | 1833 | pt->error = 0; |
| 1730 | pt->iocb->poll.head = head; | 1834 | pt->iocb->poll.head = head; |
| 1731 | add_wait_queue(head, &pt->iocb->poll.wait); | 1835 | add_wait_queue(head, &pt->iocb->poll.wait); |
| @@ -1750,12 +1854,14 @@ static int aio_poll(struct aio_kiocb *aiocb, const struct iocb *iocb) · 18 unmodified lines | |||
| 1750 | req->events = demangle_poll(iocb->aio_buf) | EPOLLERR | EPOLLHUP; | 1854 | req->events = demangle_poll(iocb->aio_buf) | EPOLLERR | EPOLLHUP; |
| 1751 | 1855 | ||
| 1752 | req->head = NULL; | 1856 | req->head = NULL; |
| 1753 | req->done = false; | ||
| 1754 | req->cancelled = false; | 1857 | req->cancelled = false; |
| 1858 | req->work_scheduled = false; | ||
| 1859 | req->work_need_resched = false; | ||
| 1755 | 1860 | ||
| 1756 | apt.pt._qproc = aio_poll_queue_proc; | 1861 | apt.pt._qproc = aio_poll_queue_proc; |
| 1757 | apt.pt._key = req->events; | 1862 | apt.pt._key = req->events; |
| 1758 | apt.iocb = aiocb; | 1863 | apt.iocb = aiocb; |
| 1864 | apt.queued = false; | ||
| 1759 | apt.error = -EINVAL; /* same as no support for IOCB_CMD_POLL */ | 1865 | apt.error = -EINVAL; /* same as no support for IOCB_CMD_POLL */ |
| 1760 | 1866 | ||
| 1761 | /* initialized the list so that we can do list_empty checks */ | 1867 | /* initialized the list so that we can do list_empty checks */ |
| @@ -1764,23 +1870,35 @@ static int aio_poll(struct aio_kiocb *aiocb, const struct iocb *iocb) · 2 unmodified lines | |||
| 1764 | 1870 | ||
| 1765 | mask = vfs_poll(req->file, &apt.pt) & req->events; | 1871 | mask = vfs_poll(req->file, &apt.pt) & req->events; |
| 1766 | spin_lock_irq(&ctx->ctx_lock); | 1872 | spin_lock_irq(&ctx->ctx_lock); |
| 1767 | if (likely(req->head)) { | 1873 | if (likely(apt.queued)) { |
| 1768 | spin_lock(&req->head->lock); | 1874 | bool on_queue = poll_iocb_lock_wq(req); |
| 1769 | if (unlikely(list_empty(&req->wait.entry))) { | 1875 | |
| 1770 | if (apt.error) | 1876 | if (!on_queue || req->work_scheduled) { |
| 1877 | /* | ||
| 1878 | * aio_poll_wake() already either scheduled the async | ||
| 1879 | * completion work, or completed the request inline. | ||
| 1880 | */ | ||
| 1881 | if (apt.error) /* unsupported case: multiple queues */ | ||
| 1771 | cancel = true; | 1882 | cancel = true; |
| 1772 | apt.error = 0; | 1883 | apt.error = 0; |
| 1773 | mask = 0; | 1884 | mask = 0; |
| 1774 | } | 1885 | } |
| 1775 | if (mask || apt.error) { | 1886 | if (mask || apt.error) { |
| 1887 | /* Steal to complete synchronously. */ | ||
| 1776 | list_del_init(&req->wait.entry); | 1888 | list_del_init(&req->wait.entry); |
| 1777 | } else if (cancel) { | 1889 | } else if (cancel) { |
| 1890 | /* Cancel if possible (may be too late though). */ | ||
| 1778 | WRITE_ONCE(req->cancelled, true); | 1891 | WRITE_ONCE(req->cancelled, true); |
| 1779 | } else if (!req->done) { /* actually waiting for an event */ | 1892 | } else if (on_queue) { |
| 1893 | /* | ||
| 1894 | * Actually waiting for an event, so add the request to | ||
| 1895 | * active_reqs so that it can be cancelled if needed. | ||
| 1896 | */ | ||
| 1780 | list_add_tail(&aiocb->ki_list, &ctx->active_reqs); | 1897 | list_add_tail(&aiocb->ki_list, &ctx->active_reqs); |
| 1781 | aiocb->ki_cancel = aio_poll_cancel; | 1898 | aiocb->ki_cancel = aio_poll_cancel; |
| 1782 | } | 1899 | } |
| 1783 | spin_unlock(&req->head->lock); | 1900 | if (on_queue) |
| 1901 | poll_iocb_unlock_wq(req); | ||
| 1784 | } | 1902 | } |
| 1785 | if (mask) { /* no async, we'd stolen it */ | 1903 | if (mask) { /* no async, we'd stolen it */ |
| 1786 | aiocb->ki_res.res = mangle_poll(mask); | 1904 | aiocb->ki_res.res = mangle_poll(mask); |
| @@ -143,10 +143,13 @@ int btrfs_check_data_free_space(struct btrfs_inode *inode, · 142 unmodified lines | |||
| 143 | 143 | ||
| 144 | /* Use new btrfs_qgroup_reserve_data to reserve precious data space. */ | 144 | /* Use new btrfs_qgroup_reserve_data to reserve precious data space. */ |
| 145 | ret = btrfs_qgroup_reserve_data(inode, reserved, start, len); | 145 | ret = btrfs_qgroup_reserve_data(inode, reserved, start, len); |
| 146 | if (ret < 0) | 146 | if (ret < 0) { |
| 147 | btrfs_free_reserved_data_space_noquota(fs_info, len); | 147 | btrfs_free_reserved_data_space_noquota(fs_info, len); |
| 148 | else | 148 | extent_changeset_free(*reserved); |
| 149 | *reserved = NULL; | ||
| 150 | } else { | ||
| 149 | ret = 0; | 151 | ret = 0; |
| 152 | } | ||
| 150 | return ret; | 153 | return ret; |
| 151 | } | 154 | } |
| 152 | 155 | ||
| @@ -452,8 +455,11 @@ int btrfs_delalloc_reserve_space(struct btrfs_inode *inode, · 299 unmodified lines | |||
| 452 | if (ret < 0) | 455 | if (ret < 0) |
| 453 | return ret; | 456 | return ret; |
| 454 | ret = btrfs_delalloc_reserve_metadata(inode, len); | 457 | ret = btrfs_delalloc_reserve_metadata(inode, len); |
| 455 | if (ret < 0) | 458 | if (ret < 0) { |
| 456 | btrfs_free_reserved_data_space(inode, *reserved, start, len); | 459 | btrfs_free_reserved_data_space(inode, *reserved, start, len); |
| 460 | extent_changeset_free(*reserved); | ||
| 461 | *reserved = NULL; | ||
| 462 | } | ||
| 457 | return ret; | 463 | return ret; |
| 458 | } | 464 | } |
| 459 | 465 | ||
| @@ -6051,6 +6051,9 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) · 6050 unmodified lines | |||
| 6051 | int dev_ret = 0; | 6051 | int dev_ret = 0; |
| 6052 | int ret = 0; | 6052 | int ret = 0; |
| 6053 | 6053 | ||
| 6054 | if (range->start == U64_MAX) | ||
| 6055 | return -EINVAL; | ||
| 6056 | |||
| 6054 | /* | 6057 | /* |
| 6055 | * Check range overflow if range->len is set. | 6058 | * Check range overflow if range->len is set. |
| 6056 | * The default range->len is U64_MAX. | 6059 | * The default range->len is U64_MAX. |
| @@ -4313,6 +4313,20 @@ static void set_btree_ioerr(struct page *page, struct extent_buffer *eb) · 4312 unmodified lines | |||
| 4313 | if (test_and_set_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags)) | 4313 | if (test_and_set_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags)) |
| 4314 | return; | 4314 | return; |
| 4315 | 4315 | ||
| 4316 | /* | ||
| 4317 | * A read may stumble upon this buffer later, make sure that it gets an | ||
| 4318 | * error and knows there was an error. | ||
| 4319 | */ | ||
| 4320 | clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); | ||
| 4321 | |||
| 4322 | /* | ||
| 4323 | * We need to set the mapping with the io error as well because a write | ||
| 4324 | * error will flip the file system readonly, and then syncfs() will | ||
| 4325 | * return a 0 because we are readonly if we don't modify the err seq for | ||
| 4326 | * the superblock. | ||
| 4327 | */ | ||
| 4328 | mapping_set_error(page->mapping, -EIO); | ||
| 4329 | |||
| 4316 | /* | 4330 | /* |
| 4317 | * If we error out, we should add back the dirty_metadata_bytes | 4331 | * If we error out, we should add back the dirty_metadata_bytes |
| 4318 | * to make it consistent. | 4332 | * to make it consistent. |
| @@ -3187,10 +3187,8 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg) · 3186 unmodified lines | |||
| 3187 | return -EPERM; | 3187 | return -EPERM; |
| 3188 | 3188 | ||
| 3189 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 3189 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
| 3190 | if (IS_ERR(vol_args)) { | 3190 | if (IS_ERR(vol_args)) |
| 3191 | ret = PTR_ERR(vol_args); | 3191 | return PTR_ERR(vol_args); |
| 3192 | goto out; | ||
| 3193 | } | ||
| 3194 | 3192 | ||
| 3195 | if (vol_args->flags & ~BTRFS_DEVICE_REMOVE_ARGS_MASK) { | 3193 | if (vol_args->flags & ~BTRFS_DEVICE_REMOVE_ARGS_MASK) { |
| 3196 | ret = -EOPNOTSUPP; | 3194 | ret = -EOPNOTSUPP; |
| @@ -334,7 +334,8 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id, · 333 unmodified lines | |||
| 334 | key.offset = ref_id; | 334 | key.offset = ref_id; |
| 335 | again: | 335 | again: |
| 336 | ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); | 336 | ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); |
| 337 | BUG_ON(ret < 0); | 337 | if (ret < 0) |
| 338 | goto out; | ||
| 338 | if (ret == 0) { | 339 | if (ret == 0) { |
| 339 | leaf = path->nodes[0]; | 340 | leaf = path->nodes[0]; |
| 340 | ref = btrfs_item_ptr(leaf, path->slots[0], | 341 | ref = btrfs_item_ptr(leaf, path->slots[0], |
| @@ -2908,6 +2908,8 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, · 2907 unmodified lines | |||
| 2908 | path->nodes[*level]->len); | 2908 | path->nodes[*level]->len); |
| 2909 | if (ret) | 2909 | if (ret) |
| 2910 | return ret; | 2910 | return ret; |
| 2911 | btrfs_redirty_list_add(trans->transaction, | ||
| 2912 | next); | ||
| 2911 | } else { | 2913 | } else { |
| 2912 | if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) | 2914 | if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) |
| 2913 | clear_extent_buffer_dirty(next); | 2915 | clear_extent_buffer_dirty(next); |
| @@ -2988,6 +2990,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, · 74 unmodified lines | |||
| 2988 | next->start, next->len); | 2990 | next->start, next->len); |
| 2989 | if (ret) | 2991 | if (ret) |
| 2990 | goto out; | 2992 | goto out; |
| 2993 | btrfs_redirty_list_add(trans->transaction, next); | ||
| 2991 | } else { | 2994 | } else { |
| 2992 | if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) | 2995 | if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) |
| 2993 | clear_extent_buffer_dirty(next); | 2996 | clear_extent_buffer_dirty(next); |
| @@ -3438,8 +3441,6 @@ static void free_log_tree(struct btrfs_trans_handle *trans, · 444 unmodified lines | |||
| 3438 | EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT); | 3441 | EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT); |
| 3439 | extent_io_tree_release(&log->log_csum_range); | 3442 | extent_io_tree_release(&log->log_csum_range); |
| 3440 | 3443 | ||
| 3441 | if (trans && log->node) | ||
| 3442 | btrfs_redirty_list_add(trans->transaction, log->node); | ||
| 3443 | btrfs_put_root(log); | 3444 | btrfs_put_root(log); |
| 3444 | } | 3445 | } |
| 3445 | 3446 | ||
| @@ -1860,6 +1860,7 @@ int btrfs_zone_finish(struct btrfs_block_group *block_group) · 1859 unmodified lines | |||
| 1860 | block_group->alloc_offset = block_group->zone_capacity; | 1860 | block_group->alloc_offset = block_group->zone_capacity; |
| 1861 | block_group->free_space_ctl->free_space = 0; | 1861 | block_group->free_space_ctl->free_space = 0; |
| 1862 | btrfs_clear_treelog_bg(block_group); | 1862 | btrfs_clear_treelog_bg(block_group); |
| 1863 | btrfs_clear_data_reloc_bg(block_group); | ||
| 1863 | spin_unlock(&block_group->lock); | 1864 | spin_unlock(&block_group->lock); |
| 1864 | 1865 | ||
| 1865 | ret = blkdev_zone_mgmt(device->bdev, REQ_OP_ZONE_FINISH, | 1866 | ret = blkdev_zone_mgmt(device->bdev, REQ_OP_ZONE_FINISH, |
| @@ -1942,6 +1943,7 @@ void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 len · 76 unmodified lines | |||
| 1942 | ASSERT(block_group->alloc_offset == block_group->zone_capacity); | 1943 | ASSERT(block_group->alloc_offset == block_group->zone_capacity); |
| 1943 | ASSERT(block_group->free_space_ctl->free_space == 0); | 1944 | ASSERT(block_group->free_space_ctl->free_space == 0); |
| 1944 | btrfs_clear_treelog_bg(block_group); | 1945 | btrfs_clear_treelog_bg(block_group); |
| 1946 | btrfs_clear_data_reloc_bg(block_group); | ||
| 1945 | spin_unlock(&block_group->lock); | 1947 | spin_unlock(&block_group->lock); |
| 1946 | 1948 | ||
| 1947 | map = block_group->physical_map; | 1949 | map = block_group->physical_map; |
| @@ -1562,6 +1562,10 @@ smbd_connected: · 1561 unmodified lines | |||
| 1562 | /* fscache server cookies are based on primary channel only */ | 1562 | /* fscache server cookies are based on primary channel only */ |
| 1563 | if (!CIFS_SERVER_IS_CHAN(tcp_ses)) | 1563 | if (!CIFS_SERVER_IS_CHAN(tcp_ses)) |
| 1564 | cifs_fscache_get_client_cookie(tcp_ses); | 1564 | cifs_fscache_get_client_cookie(tcp_ses); |
| 1565 | #ifdef CONFIG_CIFS_FSCACHE | ||
| 1566 | else | ||
| 1567 | tcp_ses->fscache = tcp_ses->primary_server->fscache; | ||
| 1568 | #endif /* CONFIG_CIFS_FSCACHE */ | ||
| 1565 | 1569 | ||
| 1566 | /* queue echo request delayed work */ | 1570 | /* queue echo request delayed work */ |
| 1567 | queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval); | 1571 | queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval); |
| @@ -3046,12 +3050,6 @@ static int mount_get_conns(struct mount_ctx *mnt_ctx) · 1478 unmodified lines | |||
| 3046 | cifs_dbg(VFS, "read only mount of RW share\n"); | 3050 | cifs_dbg(VFS, "read only mount of RW share\n"); |
| 3047 | /* no need to log a RW mount of a typical RW share */ | 3051 | /* no need to log a RW mount of a typical RW share */ |
| 3048 | } | 3052 | } |
| 3049 | /* | ||
| 3050 | * The cookie is initialized from volume info returned above. | ||
| 3051 | * Inside cifs_fscache_get_super_cookie it checks | ||
| 3052 | * that we do not get super cookie twice. | ||
| 3053 | */ | ||
| 3054 | cifs_fscache_get_super_cookie(tcon); | ||
| 3055 | } | 3053 | } |
| 3056 | 3054 | ||
| 3057 | /* | 3055 | /* |
| @@ -3426,6 +3424,7 @@ static int connect_dfs_root(struct mount_ctx *mnt_ctx, struct dfs_cache_tgt_list · 368 unmodified lines | |||
| 3426 | */ | 3424 | */ |
| 3427 | mount_put_conns(mnt_ctx); | 3425 | mount_put_conns(mnt_ctx); |
| 3428 | mount_get_dfs_conns(mnt_ctx); | 3426 | mount_get_dfs_conns(mnt_ctx); |
| 3427 | set_root_ses(mnt_ctx); | ||
| 3429 | 3428 | ||
| 3430 | full_path = build_unc_path_to_root(ctx, cifs_sb, true); | 3429 | full_path = build_unc_path_to_root(ctx, cifs_sb, true); |
| 3431 | if (IS_ERR(full_path)) | 3430 | if (IS_ERR(full_path)) |
| @@ -16,14 +16,7 @@ · 15 unmodified lines | |||
| 16 | * Key layout of CIFS server cache index object | 16 | * Key layout of CIFS server cache index object |
| 17 | */ | 17 | */ |
| 18 | struct cifs_server_key { | 18 | struct cifs_server_key { |
| 19 | struct { | 19 | __u64 conn_id; |
| 20 | uint16_t family; /* address family */ | ||
| 21 | __be16 port; /* IP port */ | ||
| 22 | } hdr; | ||
| 23 | union { | ||
| 24 | struct in_addr ipv4_addr; | ||
| 25 | struct in6_addr ipv6_addr; | ||
| 26 | }; | ||
| 27 | } __packed; | 20 | } __packed; |
| 28 | 21 | ||
| 29 | /* | 22 | /* |
| @@ -31,42 +24,23 @@ struct cifs_server_key { · 1 unmodified line | |||
| 31 | */ | 24 | */ |
| 32 | void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) | 25 | void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) |
| 33 | { | 26 | { |
| 34 | const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr; | ||
| 35 | const struct sockaddr_in *addr = (struct sockaddr_in *) sa; | ||
| 36 | const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa; | ||
| 37 | struct cifs_server_key key; | 27 | struct cifs_server_key key; |
| 38 | uint16_t key_len = sizeof(key.hdr); | ||
| 39 | |||
| 40 | memset(&key, 0, sizeof(key)); | ||
| 41 | 28 | ||
| 42 | /* | 29 | /* |
| 43 | * Should not be a problem as sin_family/sin6_family overlays | 30 | * Check if cookie was already initialized so don't reinitialize it. |
| 44 | * sa_family field | 31 | * In the future, as we integrate with newer fscache features, |
| 32 | * we may want to instead add a check if cookie has changed | ||
| 45 | */ | 33 | */ |
| 46 | key.hdr.family = sa->sa_family; | 34 | if (server->fscache) |
| 47 | switch (sa->sa_family) { | ||
| 48 | case AF_INET: | ||
| 49 | key.hdr.port = addr->sin_port; | ||
| 50 | key.ipv4_addr = addr->sin_addr; | ||
| 51 | key_len += sizeof(key.ipv4_addr); | ||
| 52 | break; | ||
| 53 | |||
| 54 | case AF_INET6: | ||
| 55 | key.hdr.port = addr6->sin6_port; | ||
| 56 | key.ipv6_addr = addr6->sin6_addr; | ||
| 57 | key_len += sizeof(key.ipv6_addr); | ||
| 58 | break; | ||
| 59 | |||
| 60 | default: | ||
| 61 | cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family); | ||
| 62 | server->fscache = NULL; | ||
| 63 | return; | 35 | return; |
| 64 | } | 36 | |
| 37 | memset(&key, 0, sizeof(key)); | ||
| 38 | key.conn_id = server->conn_id; | ||
| 65 | 39 | ||
| 66 | server->fscache = | 40 | server->fscache = |
| 67 | fscache_acquire_cookie(cifs_fscache_netfs.primary_index, | 41 | fscache_acquire_cookie(cifs_fscache_netfs.primary_index, |
| 68 | &cifs_fscache_server_index_def, | 42 | &cifs_fscache_server_index_def, |
| 69 | &key, key_len, | 43 | &key, sizeof(key), |
| 70 | NULL, 0, | 44 | NULL, 0, |
| 71 | server, 0, true); | 45 | server, 0, true); |
| 72 | cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", | 46 | cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", |
| @@ -92,7 +66,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) · 19 unmodified lines | |||
| 92 | * In the future, as we integrate with newer fscache features, | 66 | * In the future, as we integrate with newer fscache features, |
| 93 | * we may want to instead add a check if cookie has changed | 67 | * we may want to instead add a check if cookie has changed |
| 94 | */ | 68 | */ |
| 95 | if (tcon->fscache == NULL) | 69 | if (tcon->fscache) |
| 96 | return; | 70 | return; |
| 97 | 71 | ||
| 98 | sharename = extract_sharename(tcon->treeName); | 72 | sharename = extract_sharename(tcon->treeName); |
| @@ -1376,6 +1376,13 @@ iget_no_retry: · 1375 unmodified lines | |||
| 1376 | inode = ERR_PTR(rc); | 1376 | inode = ERR_PTR(rc); |
| 1377 | } | 1377 | } |
| 1378 | 1378 | ||
| 1379 | /* | ||
| 1380 | * The cookie is initialized from volume info returned above. | ||
| 1381 | * Inside cifs_fscache_get_super_cookie it checks | ||
| 1382 | * that we do not get super cookie twice. | ||
| 1383 | */ | ||
| 1384 | cifs_fscache_get_super_cookie(tcon); | ||
| 1385 | |||
| 1379 | out: | 1386 | out: |
| 1380 | kfree(path); | 1387 | kfree(path); |
| 1381 | free_xid(xid); | 1388 | free_xid(xid); |
| @@ -590,8 +590,8 @@ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, · 589 unmodified lines | |||
| 590 | { | 590 | { |
| 591 | unsigned int tioffset; /* challenge message target info area */ | 591 | unsigned int tioffset; /* challenge message target info area */ |
| 592 | unsigned int tilen; /* challenge message target info area length */ | 592 | unsigned int tilen; /* challenge message target info area length */ |
| 593 | |||
| 594 | CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; | 593 | CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; |
| 594 | __u32 server_flags; | ||
| 595 | 595 | ||
| 596 | if (blob_len < sizeof(CHALLENGE_MESSAGE)) { | 596 | if (blob_len < sizeof(CHALLENGE_MESSAGE)) { |
| 597 | cifs_dbg(VFS, "challenge blob len %d too small\n", blob_len); | 597 | cifs_dbg(VFS, "challenge blob len %d too small\n", blob_len); |
| @@ -609,12 +609,37 @@ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, · 11 unmodified lines | |||
| 609 | return -EINVAL; | 609 | return -EINVAL; |
| 610 | } | 610 | } |
| 611 | 611 | ||
| 612 | server_flags = le32_to_cpu(pblob->NegotiateFlags); | ||
| 613 | cifs_dbg(FYI, "%s: negotiate=0x%08x challenge=0x%08x\n", __func__, | ||
| 614 | ses->ntlmssp->client_flags, server_flags); | ||
| 615 | |||
| 616 | if ((ses->ntlmssp->client_flags & (NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN)) && | ||
| 617 | (!(server_flags & NTLMSSP_NEGOTIATE_56) && !(server_flags & NTLMSSP_NEGOTIATE_128))) { | ||
| 618 | cifs_dbg(VFS, "%s: requested signing/encryption but server did not return either 56-bit or 128-bit session key size\n", | ||
| 619 | __func__); | ||
| 620 | return -EINVAL; | ||
| 621 | } | ||
| 622 | if (!(server_flags & NTLMSSP_NEGOTIATE_NTLM) && !(server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC)) { | ||
| 623 | cifs_dbg(VFS, "%s: server does not seem to support either NTLMv1 or NTLMv2\n", __func__); | ||
| 624 | return -EINVAL; | ||
| 625 | } | ||
| 626 | if (ses->server->sign && !(server_flags & NTLMSSP_NEGOTIATE_SIGN)) { | ||
| 627 | cifs_dbg(VFS, "%s: forced packet signing but server does not seem to support it\n", | ||
| 628 | __func__); | ||
| 629 | return -EOPNOTSUPP; | ||
| 630 | } | ||
| 631 | if ((ses->ntlmssp->client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && | ||
| 632 | !(server_flags & NTLMSSP_NEGOTIATE_KEY_XCH)) | ||
| 633 | pr_warn_once("%s: authentication has been weakened as server does not support key exchange\n", | ||
| 634 | __func__); | ||
| 635 | |||
| 636 | ses->ntlmssp->server_flags = server_flags; | ||
| 637 | |||
| 612 | memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE); | 638 | memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE); |
| 613 | /* BB we could decode pblob->NegotiateFlags; some may be useful */ | ||
| 614 | /* In particular we can examine sign flags */ | 639 | /* In particular we can examine sign flags */ |
| 615 | /* BB spec says that if AvId field of MsvAvTimestamp is populated then | 640 | /* BB spec says that if AvId field of MsvAvTimestamp is populated then |
| 616 | we must set the MIC field of the AUTHENTICATE_MESSAGE */ | 641 | we must set the MIC field of the AUTHENTICATE_MESSAGE */ |
| 617 | ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags); | 642 | |
| 618 | tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset); | 643 | tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset); |
| 619 | tilen = le16_to_cpu(pblob->TargetInfoArray.Length); | 644 | tilen = le16_to_cpu(pblob->TargetInfoArray.Length); |
| 620 | if (tioffset > blob_len || tioffset + tilen > blob_len) { | 645 | if (tioffset > blob_len || tioffset + tilen > blob_len) { |
| @@ -721,13 +746,13 @@ int build_ntlmssp_negotiate_blob(unsigned char **pbuffer, · 100 unmodified lines | |||
| 721 | flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | | 746 | flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | |
| 722 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | | 747 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | |
| 723 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC | | 748 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC | |
| 724 | NTLMSSP_NEGOTIATE_SEAL; | 749 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_SEAL | |
| 725 | if (server->sign) | 750 | NTLMSSP_NEGOTIATE_SIGN; |
| 726 | flags |= NTLMSSP_NEGOTIATE_SIGN; | ||
| 727 | if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess) | 751 | if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess) |
| 728 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; | 752 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; |
| 729 | 753 | ||
| 730 | tmp = *pbuffer + sizeof(NEGOTIATE_MESSAGE); | 754 | tmp = *pbuffer + sizeof(NEGOTIATE_MESSAGE); |
| 755 | ses->ntlmssp->client_flags = flags; | ||
| 731 | sec_blob->NegotiateFlags = cpu_to_le32(flags); | 756 | sec_blob->NegotiateFlags = cpu_to_le32(flags); |
| 732 | 757 | ||
| 733 | /* these fields should be null in negotiate phase MS-NLMP 3.1.5.1.1 */ | 758 | /* these fields should be null in negotiate phase MS-NLMP 3.1.5.1.1 */ |
| @@ -779,15 +804,8 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer, · 45 unmodified lines | |||
| 779 | memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); | 804 | memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); |
| 780 | sec_blob->MessageType = NtLmAuthenticate; | 805 | sec_blob->MessageType = NtLmAuthenticate; |
| 781 | 806 | ||
| 782 | flags = NTLMSSP_NEGOTIATE_56 | | 807 | flags = ses->ntlmssp->server_flags | NTLMSSP_REQUEST_TARGET | |
| 783 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | | 808 | NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED; |
| 784 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | | ||
| 785 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC | | ||
| 786 | NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED; | ||
| 787 | if (ses->server->sign) | ||
| 788 | flags |= NTLMSSP_NEGOTIATE_SIGN; | ||
| 789 | if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess) | ||
| 790 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; | ||
| 791 | 809 | ||
| 792 | tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE); | 810 | tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE); |
| 793 | sec_blob->NegotiateFlags = cpu_to_le32(flags); | 811 | sec_blob->NegotiateFlags = cpu_to_le32(flags); |
| @@ -834,9 +852,9 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer, · 40 unmodified lines | |||
| 834 | *pbuffer, &tmp, | 852 | *pbuffer, &tmp, |
| 835 | nls_cp); | 853 | nls_cp); |
| 836 | 854 | ||
| 837 | if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) || | 855 | if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && |
| 838 | (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC)) | 856 | (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess) && |
| 839 | && !calc_seckey(ses)) { | 857 | !calc_seckey(ses)) { |
| 840 | memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); | 858 | memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); |
| 841 | sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer); | 859 | sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer); |
| 842 | sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); | 860 | sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); |
| @@ -858,6 +858,10 @@ loop: · 857 unmodified lines | |||
| 858 | file = NULL; | 858 | file = NULL; |
| 859 | else if (!get_file_rcu_many(file, refs)) | 859 | else if (!get_file_rcu_many(file, refs)) |
| 860 | goto loop; | 860 | goto loop; |
| 861 | else if (files_lookup_fd_raw(files, fd) != file) { | ||
| 862 | fput_many(file, refs); | ||
| 863 | goto loop; | ||
| 864 | } | ||
| 861 | } | 865 | } |
| 862 | rcu_read_unlock(); | 866 | rcu_read_unlock(); |
| 863 | 867 | ||
| @@ -1857,7 +1857,6 @@ void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs) · 1856 unmodified lines | |||
| 1857 | 1857 | ||
| 1858 | void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state) | 1858 | void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state) |
| 1859 | { | 1859 | { |
| 1860 | struct gfs2_holder mock_gh = { .gh_gl = gl, .gh_state = state, }; | ||
| 1861 | unsigned long delay = 0; | 1860 | unsigned long delay = 0; |
| 1862 | unsigned long holdtime; | 1861 | unsigned long holdtime; |
| 1863 | unsigned long now = jiffies; | 1862 | unsigned long now = jiffies; |
| @@ -1890,8 +1889,13 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state) · 26 unmodified lines | |||
| 1890 | * keep the glock until the last strong holder is done with it. | 1889 | * keep the glock until the last strong holder is done with it. |
| 1891 | */ | 1890 | */ |
| 1892 | if (!find_first_strong_holder(gl)) { | 1891 | if (!find_first_strong_holder(gl)) { |
| 1893 | if (state == LM_ST_UNLOCKED) | 1892 | struct gfs2_holder mock_gh = { |
| 1894 | mock_gh.gh_state = LM_ST_EXCLUSIVE; | 1893 | .gh_gl = gl, |
| 1894 | .gh_state = (state == LM_ST_UNLOCKED) ? | ||
| 1895 | LM_ST_EXCLUSIVE : state, | ||
| 1896 | .gh_iflags = BIT(HIF_HOLDER) | ||
| 1897 | }; | ||
| 1898 | |||
| 1895 | demote_incompat_holders(gl, &mock_gh); | 1899 | demote_incompat_holders(gl, &mock_gh); |
| 1896 | } | 1900 | } |
| 1897 | handle_callback(gl, state, delay, true); | 1901 | handle_callback(gl, state, delay, true); |
| @@ -40,37 +40,6 @@ static const struct inode_operations gfs2_file_iops; · 39 unmodified lines | |||
| 40 | static const struct inode_operations gfs2_dir_iops; | 40 | static const struct inode_operations gfs2_dir_iops; |
| 41 | static const struct inode_operations gfs2_symlink_iops; | 41 | static const struct inode_operations gfs2_symlink_iops; |
| 42 | 42 | ||
| 43 | static int iget_test(struct inode *inode, void *opaque) | ||
| 44 | { | ||
| 45 | u64 no_addr = *(u64 *)opaque; | ||
| 46 | |||
| 47 | return GFS2_I(inode)->i_no_addr == no_addr; | ||
| 48 | } | ||
| 49 | |||
| 50 | static int iget_set(struct inode *inode, void *opaque) | ||
| 51 | { | ||
| 52 | u64 no_addr = *(u64 *)opaque; | ||
| 53 | |||
| 54 | GFS2_I(inode)->i_no_addr = no_addr; | ||
| 55 | inode->i_ino = no_addr; | ||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) | ||
| 60 | { | ||
| 61 | struct inode *inode; | ||
| 62 | |||
| 63 | repeat: | ||
| 64 | inode = iget5_locked(sb, no_addr, iget_test, iget_set, &no_addr); | ||
| 65 | if (!inode) | ||
| 66 | return inode; | ||
| 67 | if (is_bad_inode(inode)) { | ||
| 68 | iput(inode); | ||
| 69 | goto repeat; | ||
| 70 | } | ||
| 71 | return inode; | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | 43 | /** |
| 75 | * gfs2_set_iop - Sets inode operations | 44 | * gfs2_set_iop - Sets inode operations |
| 76 | * @inode: The inode with correct i_mode filled in | 45 | * @inode: The inode with correct i_mode filled in |
| @@ -104,6 +73,22 @@ static void gfs2_set_iop(struct inode *inode) · 27 unmodified lines | |||
| 104 | } | 73 | } |
| 105 | } | 74 | } |
| 106 | 75 | ||
| 76 | static int iget_test(struct inode *inode, void *opaque) | ||
| 77 | { | ||
| 78 | u64 no_addr = *(u64 *)opaque; | ||
| 79 | |||
| 80 | return GFS2_I(inode)->i_no_addr == no_addr; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int iget_set(struct inode *inode, void *opaque) | ||
| 84 | { | ||
| 85 | u64 no_addr = *(u64 *)opaque; | ||
| 86 | |||
| 87 | GFS2_I(inode)->i_no_addr = no_addr; | ||
| 88 | inode->i_ino = no_addr; | ||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 107 | /** | 92 | /** |
| 108 | * gfs2_inode_lookup - Lookup an inode | 93 | * gfs2_inode_lookup - Lookup an inode |
| 109 | * @sb: The super block | 94 | * @sb: The super block |
| @@ -132,12 +117,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, · 22 unmodified lines | |||
| 132 | { | 117 | { |
| 133 | struct inode *inode; | 118 | struct inode *inode; |
| 134 | struct gfs2_inode *ip; | 119 | struct gfs2_inode *ip; |
| 135 | struct gfs2_glock *io_gl = NULL; | ||
| 136 | struct gfs2_holder i_gh; | 120 | struct gfs2_holder i_gh; |
| 137 | int error; | 121 | int error; |
| 138 | 122 | ||
| 139 | gfs2_holder_mark_uninitialized(&i_gh); | 123 | gfs2_holder_mark_uninitialized(&i_gh); |
| 140 | inode = gfs2_iget(sb, no_addr); | 124 | inode = iget5_locked(sb, no_addr, iget_test, iget_set, &no_addr); |
| 141 | if (!inode) | 125 | if (!inode) |
| 142 | return ERR_PTR(-ENOMEM); | 126 | return ERR_PTR(-ENOMEM); |
| 143 | 127 | ||
| @@ -145,22 +129,16 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, · 1 unmodified line | |||
| 145 | 129 | ||
| 146 | if (inode->i_state & I_NEW) { | 130 | if (inode->i_state & I_NEW) { |
| 147 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 131 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
| 132 | struct gfs2_glock *io_gl; | ||
| 148 | 133 | ||
| 149 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 134 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
| 150 | if (unlikely(error)) | 135 | if (unlikely(error)) |
| 151 | goto fail; | 136 | goto fail; |
| 152 | flush_delayed_work(&ip->i_gl->gl_work); | ||
| 153 | |||
| 154 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | ||
| 155 | if (unlikely(error)) | ||
| 156 | goto fail; | ||
| 157 | if (blktype != GFS2_BLKST_UNLINKED) | ||
| 158 | gfs2_cancel_delete_work(io_gl); | ||
| 159 | 137 | ||
| 160 | if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) { | 138 | if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) { |
| 161 | /* | 139 | /* |
| 162 | * The GL_SKIP flag indicates to skip reading the inode | 140 | * The GL_SKIP flag indicates to skip reading the inode |
| 163 | * block. We read the inode with gfs2_inode_refresh | 141 | * block. We read the inode when instantiating it |
| 164 | * after possibly checking the block type. | 142 | * after possibly checking the block type. |
| 165 | */ | 143 | */ |
| 166 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, | 144 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, |
| @@ -181,24 +159,31 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, · 14 unmodified lines | |||
| 181 | } | 159 | } |
| 182 | } | 160 | } |
| 183 | 161 | ||
| 184 | glock_set_object(ip->i_gl, ip); | ||
| 185 | set_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags); | 162 | set_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags); |
| 186 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 163 | |
| 164 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | ||
| 187 | if (unlikely(error)) | 165 | if (unlikely(error)) |
| 188 | goto fail; | 166 | goto fail; |
| 189 | glock_set_object(ip->i_iopen_gh.gh_gl, ip); | 167 | if (blktype != GFS2_BLKST_UNLINKED) |
| 168 | gfs2_cancel_delete_work(io_gl); | ||
| 169 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | ||
| 190 | gfs2_glock_put(io_gl); | 170 | gfs2_glock_put(io_gl); |
| 191 | io_gl = NULL; | 171 | if (unlikely(error)) |
| 172 | goto fail; | ||
| 192 | 173 | ||
| 193 | /* Lowest possible timestamp; will be overwritten in gfs2_dinode_in. */ | 174 | /* Lowest possible timestamp; will be overwritten in gfs2_dinode_in. */ |
| 194 | inode->i_atime.tv_sec = 1LL << (8 * sizeof(inode->i_atime.tv_sec) - 1); | 175 | inode->i_atime.tv_sec = 1LL << (8 * sizeof(inode->i_atime.tv_sec) - 1); |
| 195 | inode->i_atime.tv_nsec = 0; | 176 | inode->i_atime.tv_nsec = 0; |
| 196 | 177 | ||
| 178 | glock_set_object(ip->i_gl, ip); | ||
| 179 | |||
| 197 | if (type == DT_UNKNOWN) { | 180 | if (type == DT_UNKNOWN) { |
| 198 | /* Inode glock must be locked already */ | 181 | /* Inode glock must be locked already */ |
| 199 | error = gfs2_instantiate(&i_gh); | 182 | error = gfs2_instantiate(&i_gh); |
| 200 | if (error) | 183 | if (error) { |
| 184 | glock_clear_object(ip->i_gl, ip); | ||
| 201 | goto fail; | 185 | goto fail; |
| 186 | } | ||
| 202 | } else { | 187 | } else { |
| 203 | ip->i_no_formal_ino = no_formal_ino; | 188 | ip->i_no_formal_ino = no_formal_ino; |
| 204 | inode->i_mode = DT2IF(type); | 189 | inode->i_mode = DT2IF(type); |
| @@ -206,31 +191,23 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, · 1 unmodified line | |||
| 206 | 191 | ||
| 207 | if (gfs2_holder_initialized(&i_gh)) | 192 | if (gfs2_holder_initialized(&i_gh)) |
| 208 | gfs2_glock_dq_uninit(&i_gh); | 193 | gfs2_glock_dq_uninit(&i_gh); |
| 194 | glock_set_object(ip->i_iopen_gh.gh_gl, ip); | ||
| 209 | 195 | ||
| 210 | gfs2_set_iop(inode); | 196 | gfs2_set_iop(inode); |
| 197 | unlock_new_inode(inode); | ||
| 211 | } | 198 | } |
| 212 | 199 | ||
| 213 | if (no_formal_ino && ip->i_no_formal_ino && | 200 | if (no_formal_ino && ip->i_no_formal_ino && |
| 214 | no_formal_ino != ip->i_no_formal_ino) { | 201 | no_formal_ino != ip->i_no_formal_ino) { |
| 215 | error = -ESTALE; | ||
| 216 | if (inode->i_state & I_NEW) | ||
| 217 | goto fail; | ||
| 218 | iput(inode); | 202 | iput(inode); |
| 219 | return ERR_PTR(error); | 203 | return ERR_PTR(-ESTALE); |
| 220 | } | 204 | } |
| 221 | 205 | ||
| 222 | if (inode->i_state & I_NEW) | ||
| 223 | unlock_new_inode(inode); | ||
| 224 | |||
| 225 | return inode; | 206 | return inode; |
| 226 | 207 | ||
| 227 | fail: | 208 | fail: |
| 228 | if (gfs2_holder_initialized(&ip->i_iopen_gh)) { | 209 | if (gfs2_holder_initialized(&ip->i_iopen_gh)) |
| 229 | glock_clear_object(ip->i_iopen_gh.gh_gl, ip); | ||
| 230 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 210 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
| 231 | } | ||
| 232 | if (io_gl) | ||
| 233 | gfs2_glock_put(io_gl); | ||
| 234 | if (gfs2_holder_initialized(&i_gh)) | 211 | if (gfs2_holder_initialized(&i_gh)) |
| 235 | gfs2_glock_dq_uninit(&i_gh); | 212 | gfs2_glock_dq_uninit(&i_gh); |
| 236 | iget_failed(inode); | 213 | iget_failed(inode); |
| @@ -730,18 +707,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, · 493 unmodified lines | |||
| 730 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 707 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
| 731 | if (error) | 708 | if (error) |
| 732 | goto fail_free_inode; | 709 | goto fail_free_inode; |
| 733 | flush_delayed_work(&ip->i_gl->gl_work); | ||
| 734 | 710 | ||
| 735 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | 711 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
| 736 | if (error) | 712 | if (error) |
| 737 | goto fail_free_inode; | 713 | goto fail_free_inode; |
| 738 | gfs2_cancel_delete_work(io_gl); | 714 | gfs2_cancel_delete_work(io_gl); |
| 739 | 715 | ||
| 716 | error = insert_inode_locked4(inode, ip->i_no_addr, iget_test, &ip->i_no_addr); | ||
| 717 | BUG_ON(error); | ||
| 718 | |||
| 740 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); | 719 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
| 741 | if (error) | 720 | if (error) |
| 742 | goto fail_gunlock2; | 721 | goto fail_gunlock2; |
| 743 | 722 | ||
| 744 | glock_set_object(ip->i_gl, ip); | ||
| 745 | error = gfs2_trans_begin(sdp, blocks, 0); | 723 | error = gfs2_trans_begin(sdp, blocks, 0); |
| 746 | if (error) | 724 | if (error) |
| 747 | goto fail_gunlock2; | 725 | goto fail_gunlock2; |
| @@ -757,9 +735,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, · 9 unmodified lines | |||
| 757 | if (error) | 735 | if (error) |
| 758 | goto fail_gunlock2; | 736 | goto fail_gunlock2; |
| 759 | 737 | ||
| 738 | glock_set_object(ip->i_gl, ip); | ||
| 760 | glock_set_object(io_gl, ip); | 739 | glock_set_object(io_gl, ip); |
| 761 | gfs2_set_iop(inode); | 740 | gfs2_set_iop(inode); |
| 762 | insert_inode_hash(inode); | ||
| 763 | 741 | ||
| 764 | free_vfs_inode = 0; /* After this point, the inode is no longer | 742 | free_vfs_inode = 0; /* After this point, the inode is no longer |
| 765 | considered free. Any failures need to undo | 743 | considered free. Any failures need to undo |
| @@ -801,17 +779,17 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, · 35 unmodified lines | |||
| 801 | gfs2_glock_dq_uninit(ghs + 1); | 779 | gfs2_glock_dq_uninit(ghs + 1); |
| 802 | gfs2_glock_put(io_gl); | 780 | gfs2_glock_put(io_gl); |
| 803 | gfs2_qa_put(dip); | 781 | gfs2_qa_put(dip); |
| 782 | unlock_new_inode(inode); | ||
| 804 | return error; | 783 | return error; |
| 805 | 784 | ||
| 806 | fail_gunlock3: | 785 | fail_gunlock3: |
| 786 | glock_clear_object(ip->i_gl, ip); | ||
| 807 | glock_clear_object(io_gl, ip); | 787 | glock_clear_object(io_gl, ip); |
| 808 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 788 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
| 809 | fail_gunlock2: | 789 | fail_gunlock2: |
| 810 | glock_clear_object(io_gl, ip); | ||
| 811 | gfs2_glock_put(io_gl); | 790 | gfs2_glock_put(io_gl); |
| 812 | fail_free_inode: | 791 | fail_free_inode: |
| 813 | if (ip->i_gl) { | 792 | if (ip->i_gl) { |
| 814 | glock_clear_object(ip->i_gl, ip); | ||
| 815 | if (free_vfs_inode) /* else evict will do the put for us */ | 793 | if (free_vfs_inode) /* else evict will do the put for us */ |
| 816 | gfs2_glock_put(ip->i_gl); | 794 | gfs2_glock_put(ip->i_gl); |
| 817 | } | 795 | } |
| @@ -829,7 +807,10 @@ fail_gunlock: · 11 unmodified lines | |||
| 829 | mark_inode_dirty(inode); | 807 | mark_inode_dirty(inode); |
| 830 | set_bit(free_vfs_inode ? GIF_FREE_VFS_INODE : GIF_ALLOC_FAILED, | 808 | set_bit(free_vfs_inode ? GIF_FREE_VFS_INODE : GIF_ALLOC_FAILED, |
| 831 | &GFS2_I(inode)->i_flags); | 809 | &GFS2_I(inode)->i_flags); |
| 832 | iput(inode); | 810 | if (inode->i_state & I_NEW) |
| 811 | iget_failed(inode); | ||
| 812 | else | ||
| 813 | iput(inode); | ||
| 833 | } | 814 | } |
| 834 | if (gfs2_holder_initialized(ghs + 1)) | 815 | if (gfs2_holder_initialized(ghs + 1)) |
| 835 | gfs2_glock_dq_uninit(ghs + 1); | 816 | gfs2_glock_dq_uninit(ghs + 1); |
| @@ -142,6 +142,7 @@ static bool io_acct_cancel_pending_work(struct io_wqe *wqe, · 141 unmodified lines | |||
| 142 | struct io_wqe_acct *acct, | 142 | struct io_wqe_acct *acct, |
| 143 | struct io_cb_cancel_data *match); | 143 | struct io_cb_cancel_data *match); |
| 144 | static void create_worker_cb(struct callback_head *cb); | 144 | static void create_worker_cb(struct callback_head *cb); |
| 145 | static void io_wq_cancel_tw_create(struct io_wq *wq); | ||
| 145 | 146 | ||
| 146 | static bool io_worker_get(struct io_worker *worker) | 147 | static bool io_worker_get(struct io_worker *worker) |
| 147 | { | 148 | { |
| @@ -357,12 +358,22 @@ static bool io_queue_worker_create(struct io_worker *worker, · 209 unmodified lines | |||
| 357 | test_and_set_bit_lock(0, &worker->create_state)) | 358 | test_and_set_bit_lock(0, &worker->create_state)) |
| 358 | goto fail_release; | 359 | goto fail_release; |
| 359 | 360 | ||
| 361 | atomic_inc(&wq->worker_refs); | ||
| 360 | init_task_work(&worker->create_work, func); | 362 | init_task_work(&worker->create_work, func); |
| 361 | worker->create_index = acct->index; | 363 | worker->create_index = acct->index; |
| 362 | if (!task_work_add(wq->task, &worker->create_work, TWA_SIGNAL)) { | 364 | if (!task_work_add(wq->task, &worker->create_work, TWA_SIGNAL)) { |
| 363 | clear_bit_unlock(0, &worker->create_state); | 365 | /* |
| 366 | * EXIT may have been set after checking it above, check after | ||
| 367 | * adding the task_work and remove any creation item if it is | ||
| 368 | * now set. wq exit does that too, but we can have added this | ||
| 369 | * work item after we canceled in io_wq_exit_workers(). | ||
| 370 | */ | ||
| 371 | if (test_bit(IO_WQ_BIT_EXIT, &wq->state)) | ||
| 372 | io_wq_cancel_tw_create(wq); | ||
| 373 | io_worker_ref_put(wq); | ||
| 364 | return true; | 374 | return true; |
| 365 | } | 375 | } |
| 376 | io_worker_ref_put(wq); | ||
| 366 | clear_bit_unlock(0, &worker->create_state); | 377 | clear_bit_unlock(0, &worker->create_state); |
| 367 | fail_release: | 378 | fail_release: |
| 368 | io_worker_release(worker); | 379 | io_worker_release(worker); |
| @@ -714,6 +725,13 @@ static bool io_wq_work_match_all(struct io_wq_work *work, void *data) · 345 unmodified lines | |||
| 714 | 725 | ||
| 715 | static inline bool io_should_retry_thread(long err) | 726 | static inline bool io_should_retry_thread(long err) |
| 716 | { | 727 | { |
| 728 | /* | ||
| 729 | * Prevent perpetual task_work retry, if the task (or its group) is | ||
| 730 | * exiting. | ||
| 731 | */ | ||
| 732 | if (fatal_signal_pending(current)) | ||
| 733 | return false; | ||
| 734 | |||
| 717 | switch (err) { | 735 | switch (err) { |
| 718 | case -EAGAIN: | 736 | case -EAGAIN: |
| 719 | case -ERESTARTSYS: | 737 | case -ERESTARTSYS: |
| @@ -1191,13 +1209,9 @@ void io_wq_exit_start(struct io_wq *wq) · 471 unmodified lines | |||
| 1191 | set_bit(IO_WQ_BIT_EXIT, &wq->state); | 1209 | set_bit(IO_WQ_BIT_EXIT, &wq->state); |
| 1192 | } | 1210 | } |
| 1193 | 1211 | ||
| 1194 | static void io_wq_exit_workers(struct io_wq *wq) | 1212 | static void io_wq_cancel_tw_create(struct io_wq *wq) |
| 1195 | { | 1213 | { |
| 1196 | struct callback_head *cb; | 1214 | struct callback_head *cb; |
| 1197 | int node; | ||
| 1198 | |||
| 1199 | if (!wq->task) | ||
| 1200 | return; | ||
| 1201 | 1215 | ||
| 1202 | while ((cb = task_work_cancel_match(wq->task, io_task_work_match, wq)) != NULL) { | 1216 | while ((cb = task_work_cancel_match(wq->task, io_task_work_match, wq)) != NULL) { |
| 1203 | struct io_worker *worker; | 1217 | struct io_worker *worker; |
| @@ -1205,6 +1219,16 @@ static void io_wq_exit_workers(struct io_wq *wq) · 1 unmodified line | |||
| 1205 | worker = container_of(cb, struct io_worker, create_work); | 1219 | worker = container_of(cb, struct io_worker, create_work); |
| 1206 | io_worker_cancel_cb(worker); | 1220 | io_worker_cancel_cb(worker); |
| 1207 | } | 1221 | } |
| 1222 | } | ||
| 1223 | |||
| 1224 | static void io_wq_exit_workers(struct io_wq *wq) | ||
| 1225 | { | ||
| 1226 | int node; | ||
| 1227 | |||
| 1228 | if (!wq->task) | ||
| 1229 | return; | ||
| 1230 | |||
| 1231 | io_wq_cancel_tw_create(wq); | ||
| 1208 | 1232 | ||
| 1209 | rcu_read_lock(); | 1233 | rcu_read_lock(); |
| 1210 | for_each_node(node) { | 1234 | for_each_node(node) { |
| @@ -9824,7 +9824,7 @@ static __cold void io_uring_drop_tctx_refs(struct task_struct *task) · 9823 unmodified lines | |||
| 9824 | 9824 | ||
| 9825 | /* | 9825 | /* |
| 9826 | * Find any io_uring ctx that this task has registered or done IO on, and cancel | 9826 | * Find any io_uring ctx that this task has registered or done IO on, and cancel |
| 9827 | * requests. @sqd should be not-null IIF it's an SQPOLL thread cancellation. | 9827 | * requests. @sqd should be not-null IFF it's an SQPOLL thread cancellation. |
| 9828 | */ | 9828 | */ |
| 9829 | static __cold void io_uring_cancel_generic(bool cancel_all, | 9829 | static __cold void io_uring_cancel_generic(bool cancel_all, |
| 9830 | struct io_sq_data *sqd) | 9830 | struct io_sq_data *sqd) |
| @@ -9866,8 +9866,10 @@ static __cold void io_uring_cancel_generic(bool cancel_all, · 35 unmodified lines | |||
| 9866 | cancel_all); | 9866 | cancel_all); |
| 9867 | } | 9867 | } |
| 9868 | 9868 | ||
| 9869 | prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE); | 9869 | prepare_to_wait(&tctx->wait, &wait, TASK_INTERRUPTIBLE); |
| 9870 | io_run_task_work(); | ||
| 9870 | io_uring_drop_tctx_refs(current); | 9871 | io_uring_drop_tctx_refs(current); |
| 9872 | |||
| 9871 | /* | 9873 | /* |
| 9872 | * If we've seen completions, retry without waiting. This | 9874 | * If we've seen completions, retry without waiting. This |
| 9873 | * avoids a race where a completion comes in before we did | 9875 | * avoids a race where a completion comes in before we did |
| @@ -354,16 +354,11 @@ static void netfs_rreq_write_to_cache_work(struct work_struct *work) · 353 unmodified lines | |||
| 354 | netfs_rreq_do_write_to_cache(rreq); | 354 | netfs_rreq_do_write_to_cache(rreq); |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | static void netfs_rreq_write_to_cache(struct netfs_read_request *rreq, | 357 | static void netfs_rreq_write_to_cache(struct netfs_read_request *rreq) |
| 358 | bool was_async) | ||
| 359 | { | 358 | { |
| 360 | if (was_async) { | 359 | rreq->work.func = netfs_rreq_write_to_cache_work; |
| 361 | rreq->work.func = netfs_rreq_write_to_cache_work; | 360 | if (!queue_work(system_unbound_wq, &rreq->work)) |
| 362 | if (!queue_work(system_unbound_wq, &rreq->work)) | 361 | BUG(); |
| 363 | BUG(); | ||
| 364 | } else { | ||
| 365 | netfs_rreq_do_write_to_cache(rreq); | ||
| 366 | } | ||
| 367 | } | 362 | } |
| 368 | 363 | ||
| 369 | /* | 364 | /* |
| @@ -558,7 +553,7 @@ again: · 188 unmodified lines | |||
| 558 | wake_up_bit(&rreq->flags, NETFS_RREQ_IN_PROGRESS); | 553 | wake_up_bit(&rreq->flags, NETFS_RREQ_IN_PROGRESS); |
| 559 | 554 | ||
| 560 | if (test_bit(NETFS_RREQ_WRITE_TO_CACHE, &rreq->flags)) | 555 | if (test_bit(NETFS_RREQ_WRITE_TO_CACHE, &rreq->flags)) |
| 561 | return netfs_rreq_write_to_cache(rreq, was_async); | 556 | return netfs_rreq_write_to_cache(rreq); |
| 562 | 557 | ||
| 563 | netfs_rreq_completed(rreq, was_async); | 558 | netfs_rreq_completed(rreq, was_async); |
| 564 | } | 559 | } |
| @@ -960,7 +955,7 @@ int netfs_readpage(struct file *file, · 395 unmodified lines | |||
| 960 | rreq = netfs_alloc_read_request(ops, netfs_priv, file); | 955 | rreq = netfs_alloc_read_request(ops, netfs_priv, file); |
| 961 | if (!rreq) { | 956 | if (!rreq) { |
| 962 | if (netfs_priv) | 957 | if (netfs_priv) |
| 963 | ops->cleanup(netfs_priv, folio_file_mapping(folio)); | 958 | ops->cleanup(folio_file_mapping(folio), netfs_priv); |
| 964 | folio_unlock(folio); | 959 | folio_unlock(folio); |
| 965 | return -ENOMEM; | 960 | return -ENOMEM; |
| 966 | } | 961 | } |
| @@ -1008,8 +1003,8 @@ out: · 41 unmodified lines | |||
| 1008 | } | 1003 | } |
| 1009 | EXPORT_SYMBOL(netfs_readpage); | 1004 | EXPORT_SYMBOL(netfs_readpage); |
| 1010 | 1005 | ||
| 1011 | /** | 1006 | /* |
| 1012 | * netfs_skip_folio_read - prep a folio for writing without reading first | 1007 | * Prepare a folio for writing without reading first |
| 1013 | * @folio: The folio being prepared | 1008 | * @folio: The folio being prepared |
| 1014 | * @pos: starting position for the write | 1009 | * @pos: starting position for the write |
| 1015 | * @len: length of write | 1010 | * @len: length of write |
| @@ -1191,7 +1186,7 @@ have_folio: · 175 unmodified lines | |||
| 1191 | goto error; | 1186 | goto error; |
| 1192 | have_folio_no_wait: | 1187 | have_folio_no_wait: |
| 1193 | if (netfs_priv) | 1188 | if (netfs_priv) |
| 1194 | ops->cleanup(netfs_priv, mapping); | 1189 | ops->cleanup(mapping, netfs_priv); |
| 1195 | *_folio = folio; | 1190 | *_folio = folio; |
| 1196 | _leave(" = 0"); | 1191 | _leave(" = 0"); |
| 1197 | return 0; | 1192 | return 0; |
| @@ -1202,7 +1197,7 @@ error: · 4 unmodified lines | |||
| 1202 | folio_unlock(folio); | 1197 | folio_unlock(folio); |
| 1203 | folio_put(folio); | 1198 | folio_put(folio); |
| 1204 | if (netfs_priv) | 1199 | if (netfs_priv) |
| 1205 | ops->cleanup(netfs_priv, mapping); | 1200 | ops->cleanup(mapping, netfs_priv); |
| 1206 | _leave(" = %d", ret); | 1201 | _leave(" = %d", ret); |
| 1207 | return ret; | 1202 | return ret; |
| 1208 | } | 1203 | } |
| @@ -2156,6 +2156,7 @@ static struct notifier_block nfsd4_cld_block = { · 2155 unmodified lines | |||
| 2156 | int | 2156 | int |
| 2157 | register_cld_notifier(void) | 2157 | register_cld_notifier(void) |
| 2158 | { | 2158 | { |
| 2159 | WARN_ON(!nfsd_net_id); | ||
| 2159 | return rpc_pipefs_notifier_register(&nfsd4_cld_block); | 2160 | return rpc_pipefs_notifier_register(&nfsd4_cld_block); |
| 2160 | } | 2161 | } |
| 2161 | 2162 | ||
| @@ -1207,6 +1207,11 @@ hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp) · 1206 unmodified lines | |||
| 1207 | return 0; | 1207 | return 0; |
| 1208 | } | 1208 | } |
| 1209 | 1209 | ||
| 1210 | static bool delegation_hashed(struct nfs4_delegation *dp) | ||
| 1211 | { | ||
| 1212 | return !(list_empty(&dp->dl_perfile)); | ||
| 1213 | } | ||
| 1214 | |||
| 1210 | static bool | 1215 | static bool |
| 1211 | unhash_delegation_locked(struct nfs4_delegation *dp) | 1216 | unhash_delegation_locked(struct nfs4_delegation *dp) |
| 1212 | { | 1217 | { |
| @@ -1214,7 +1219,7 @@ unhash_delegation_locked(struct nfs4_delegation *dp) · 1 unmodified line | |||
| 1214 | 1219 | ||
| 1215 | lockdep_assert_held(&state_lock); | 1220 | lockdep_assert_held(&state_lock); |
| 1216 | 1221 | ||
| 1217 | if (list_empty(&dp->dl_perfile)) | 1222 | if (!delegation_hashed(dp)) |
| 1218 | return false; | 1223 | return false; |
| 1219 | 1224 | ||
| 1220 | dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID; | 1225 | dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID; |
| @@ -4598,7 +4603,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb) · 3377 unmodified lines | |||
| 4598 | * queued for a lease break. Don't queue it again. | 4603 | * queued for a lease break. Don't queue it again. |
| 4599 | */ | 4604 | */ |
| 4600 | spin_lock(&state_lock); | 4605 | spin_lock(&state_lock); |
| 4601 | if (dp->dl_time == 0) { | 4606 | if (delegation_hashed(dp) && dp->dl_time == 0) { |
| 4602 | dp->dl_time = ktime_get_boottime_seconds(); | 4607 | dp->dl_time = ktime_get_boottime_seconds(); |
| 4603 | list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); | 4608 | list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); |
| 4604 | } | 4609 | } |
| @@ -1521,12 +1521,9 @@ static int __init init_nfsd(void) · 1520 unmodified lines | |||
| 1521 | int retval; | 1521 | int retval; |
| 1522 | printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); | 1522 | printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); |
| 1523 | 1523 | ||
| 1524 | retval = register_cld_notifier(); | ||
| 1525 | if (retval) | ||
| 1526 | return retval; | ||
| 1527 | retval = nfsd4_init_slabs(); | 1524 | retval = nfsd4_init_slabs(); |
| 1528 | if (retval) | 1525 | if (retval) |
| 1529 | goto out_unregister_notifier; | 1526 | return retval; |
| 1530 | retval = nfsd4_init_pnfs(); | 1527 | retval = nfsd4_init_pnfs(); |
| 1531 | if (retval) | 1528 | if (retval) |
| 1532 | goto out_free_slabs; | 1529 | goto out_free_slabs; |
| @@ -1545,9 +1542,14 @@ static int __init init_nfsd(void) · 12 unmodified lines | |||
| 1545 | goto out_free_exports; | 1542 | goto out_free_exports; |
| 1546 | retval = register_pernet_subsys(&nfsd_net_ops); | 1543 | retval = register_pernet_subsys(&nfsd_net_ops); |
| 1547 | if (retval < 0) | 1544 | if (retval < 0) |
| 1545 | goto out_free_filesystem; | ||
| 1546 | retval = register_cld_notifier(); | ||
| 1547 | if (retval) | ||
| 1548 | goto out_free_all; | 1548 | goto out_free_all; |
| 1549 | return 0; | 1549 | return 0; |
| 1550 | out_free_all: | 1550 | out_free_all: |
| 1551 | unregister_pernet_subsys(&nfsd_net_ops); | ||
| 1552 | out_free_filesystem: | ||
| 1551 | unregister_filesystem(&nfsd_fs_type); | 1553 | unregister_filesystem(&nfsd_fs_type); |
| 1552 | out_free_exports: | 1554 | out_free_exports: |
| 1553 | remove_proc_entry("fs/nfs/exports", NULL); | 1555 | remove_proc_entry("fs/nfs/exports", NULL); |
| @@ -1561,13 +1563,12 @@ out_free_pnfs: · 7 unmodified lines | |||
| 1561 | nfsd4_exit_pnfs(); | 1563 | nfsd4_exit_pnfs(); |
| 1562 | out_free_slabs: | 1564 | out_free_slabs: |
| 1563 | nfsd4_free_slabs(); | 1565 | nfsd4_free_slabs(); |
| 1564 | out_unregister_notifier: | ||
| 1565 | unregister_cld_notifier(); | ||
| 1566 | return retval; | 1566 | return retval; |
| 1567 | } | 1567 | } |
| 1568 | 1568 | ||
| 1569 | static void __exit exit_nfsd(void) | 1569 | static void __exit exit_nfsd(void) |
| 1570 | { | 1570 | { |
| 1571 | unregister_cld_notifier(); | ||
| 1571 | unregister_pernet_subsys(&nfsd_net_ops); | 1572 | unregister_pernet_subsys(&nfsd_net_ops); |
| 1572 | nfsd_drc_slab_free(); | 1573 | nfsd_drc_slab_free(); |
| 1573 | remove_proc_entry("fs/nfs/exports", NULL); | 1574 | remove_proc_entry("fs/nfs/exports", NULL); |
| @@ -1577,7 +1578,6 @@ static void __exit exit_nfsd(void) · 3 unmodified lines | |||
| 1577 | nfsd4_free_slabs(); | 1578 | nfsd4_free_slabs(); |
| 1578 | nfsd4_exit_pnfs(); | 1579 | nfsd4_exit_pnfs(); |
| 1579 | unregister_filesystem(&nfsd_fs_type); | 1580 | unregister_filesystem(&nfsd_fs_type); |
| 1580 | unregister_cld_notifier(); | ||
| 1581 | } | 1581 | } |
| 1582 | 1582 | ||
| 1583 | MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); | 1583 | MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); |
| @@ -35,17 +35,7 @@ · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | void signalfd_cleanup(struct sighand_struct *sighand) | 36 | void signalfd_cleanup(struct sighand_struct *sighand) |
| 37 | { | 37 | { |
| 38 | wait_queue_head_t *wqh = &sighand->signalfd_wqh; | 38 | wake_up_pollfree(&sighand->signalfd_wqh); |
| 39 | /* | ||
| 40 | * The lockless check can race with remove_wait_queue() in progress, | ||
| 41 | * but in this case its caller should run under rcu_read_lock() and | ||
| 42 | * sighand_cachep is SLAB_TYPESAFE_BY_RCU, we can safely return. | ||
| 43 | */ | ||
| 44 | if (likely(!waitqueue_active(wqh))) | ||
| 45 | return; | ||
| 46 | |||
| 47 | /* wait_queue_entry_t->func(POLLFREE) should do remove_wait_queue() */ | ||
| 48 | wake_up_poll(wqh, EPOLLHUP | POLLFREE); | ||
| 49 | } | 39 | } |
| 50 | 40 | ||
| 51 | struct signalfd_ctx { | 41 | struct signalfd_ctx { |
| @@ -72,16 +72,3 @@ void cifs_arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int l · 71 unmodified lines | |||
| 72 | ctx->y = y; | 72 | ctx->y = y; |
| 73 | } | 73 | } |
| 74 | EXPORT_SYMBOL_GPL(cifs_arc4_crypt); | 74 | EXPORT_SYMBOL_GPL(cifs_arc4_crypt); |
| 75 | |||
| 76 | static int __init | ||
| 77 | init_smbfs_common(void) | ||
| 78 | { | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | static void __init | ||
| 82 | exit_smbfs_common(void) | ||
| 83 | { | ||
| 84 | } | ||
| 85 | |||
| 86 | module_init(init_smbfs_common) | ||
| 87 | module_exit(exit_smbfs_common) | ||
| @@ -161,6 +161,77 @@ struct tracefs_fs_info { · 160 unmodified lines | |||
| 161 | struct tracefs_mount_opts mount_opts; | 161 | struct tracefs_mount_opts mount_opts; |
| 162 | }; | 162 | }; |
| 163 | 163 | ||
| 164 | static void change_gid(struct dentry *dentry, kgid_t gid) | ||
| 165 | { | ||
| 166 | if (!dentry->d_inode) | ||
| 167 | return; | ||
| 168 | dentry->d_inode->i_gid = gid; | ||
| 169 | } | ||
| 170 | |||
| 171 | /* | ||
| 172 | * Taken from d_walk, but without he need for handling renames. | ||
| 173 | * Nothing can be renamed while walking the list, as tracefs | ||
| 174 | * does not support renames. This is only called when mounting | ||
| 175 | * or remounting the file system, to set all the files to | ||
| 176 | * the given gid. | ||
| 177 | */ | ||
| 178 | static void set_gid(struct dentry *parent, kgid_t gid) | ||
| 179 | { | ||
| 180 | struct dentry *this_parent; | ||
| 181 | struct list_head *next; | ||
| 182 | |||
| 183 | this_parent = parent; | ||
| 184 | spin_lock(&this_parent->d_lock); | ||
| 185 | |||
| 186 | change_gid(this_parent, gid); | ||
| 187 | repeat: | ||
| 188 | next = this_parent->d_subdirs.next; | ||
| 189 | resume: | ||
| 190 | while (next != &this_parent->d_subdirs) { | ||
| 191 | struct list_head *tmp = next; | ||
| 192 | struct dentry *dentry = list_entry(tmp, struct dentry, d_child); | ||
| 193 | next = tmp->next; | ||
| 194 | |||
| 195 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | ||
| 196 | |||
| 197 | change_gid(dentry, gid); | ||
| 198 | |||
| 199 | if (!list_empty(&dentry->d_subdirs)) { | ||
| 200 | spin_unlock(&this_parent->d_lock); | ||
| 201 | spin_release(&dentry->d_lock.dep_map, _RET_IP_); | ||
| 202 | this_parent = dentry; | ||
| 203 | spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_); | ||
| 204 | goto repeat; | ||
| 205 | } | ||
| 206 | spin_unlock(&dentry->d_lock); | ||
| 207 | } | ||
| 208 | /* | ||
| 209 | * All done at this level ... ascend and resume the search. | ||
| 210 | */ | ||
| 211 | rcu_read_lock(); | ||
| 212 | ascend: | ||
| 213 | if (this_parent != parent) { | ||
| 214 | struct dentry *child = this_parent; | ||
| 215 | this_parent = child->d_parent; | ||
| 216 | |||
| 217 | spin_unlock(&child->d_lock); | ||
| 218 | spin_lock(&this_parent->d_lock); | ||
| 219 | |||
| 220 | /* go into the first sibling still alive */ | ||
| 221 | do { | ||
| 222 | next = child->d_child.next; | ||
| 223 | if (next == &this_parent->d_subdirs) | ||
| 224 | goto ascend; | ||
| 225 | child = list_entry(next, struct dentry, d_child); | ||
| 226 | } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)); | ||
| 227 | rcu_read_unlock(); | ||
| 228 | goto resume; | ||
| 229 | } | ||
| 230 | rcu_read_unlock(); | ||
| 231 | spin_unlock(&this_parent->d_lock); | ||
| 232 | return; | ||
| 233 | } | ||
| 234 | |||
| 164 | static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) | 235 | static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) |
| 165 | { | 236 | { |
| 166 | substring_t args[MAX_OPT_ARGS]; | 237 | substring_t args[MAX_OPT_ARGS]; |
| @@ -193,6 +264,7 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) · 26 unmodified lines | |||
| 193 | if (!gid_valid(gid)) | 264 | if (!gid_valid(gid)) |
| 194 | return -EINVAL; | 265 | return -EINVAL; |
| 195 | opts->gid = gid; | 266 | opts->gid = gid; |
| 267 | set_gid(tracefs_mount->mnt_root, gid); | ||
| 196 | break; | 268 | break; |
| 197 | case Opt_mode: | 269 | case Opt_mode: |
| 198 | if (match_octal(&args[0], &option)) | 270 | if (match_octal(&args[0], &option)) |
| @@ -414,6 +486,8 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, · 215 unmodified lines | |||
| 414 | inode->i_mode = mode; | 486 | inode->i_mode = mode; |
| 415 | inode->i_fop = fops ? fops : &tracefs_file_operations; | 487 | inode->i_fop = fops ? fops : &tracefs_file_operations; |
| 416 | inode->i_private = data; | 488 | inode->i_private = data; |
| 489 | inode->i_uid = d_inode(dentry->d_parent)->i_uid; | ||
| 490 | inode->i_gid = d_inode(dentry->d_parent)->i_gid; | ||
| 417 | d_instantiate(dentry, inode); | 491 | d_instantiate(dentry, inode); |
| 418 | fsnotify_create(dentry->d_parent->d_inode, dentry); | 492 | fsnotify_create(dentry->d_parent->d_inode, dentry); |
| 419 | return end_creating(dentry); | 493 | return end_creating(dentry); |
| @@ -436,6 +510,8 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, · 16 unmodified lines | |||
| 436 | inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP; | 510 | inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP; |
| 437 | inode->i_op = ops; | 511 | inode->i_op = ops; |
| 438 | inode->i_fop = &simple_dir_operations; | 512 | inode->i_fop = &simple_dir_operations; |
| 513 | inode->i_uid = d_inode(dentry->d_parent)->i_uid; | ||
| 514 | inode->i_gid = d_inode(dentry->d_parent)->i_gid; | ||
| 439 | 515 | ||
| 440 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ | 516 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ |
| 441 | inc_nlink(inode); | 517 | inc_nlink(inode); |
| @@ -3122,7 +3122,6 @@ xfs_rename( · 3121 unmodified lines | |||
| 3122 | * appropriately. | 3122 | * appropriately. |
| 3123 | */ | 3123 | */ |
| 3124 | if (flags & RENAME_WHITEOUT) { | 3124 | if (flags & RENAME_WHITEOUT) { |
| 3125 | ASSERT(!(flags & (RENAME_NOREPLACE | RENAME_EXCHANGE))); | ||
| 3126 | error = xfs_rename_alloc_whiteout(mnt_userns, target_dp, &wip); | 3125 | error = xfs_rename_alloc_whiteout(mnt_userns, target_dp, &wip); |
| 3127 | if (error) | 3126 | if (error) |
| 3128 | return error; | 3127 | return error; |
| @@ -1765,7 +1765,10 @@ static int · 1764 unmodified lines | |||
| 1765 | xfs_remount_ro( | 1765 | xfs_remount_ro( |
| 1766 | struct xfs_mount *mp) | 1766 | struct xfs_mount *mp) |
| 1767 | { | 1767 | { |
| 1768 | int error; | 1768 | struct xfs_icwalk icw = { |
| 1769 | .icw_flags = XFS_ICWALK_FLAG_SYNC, | ||
| 1770 | }; | ||
| 1771 | int error; | ||
| 1769 | 1772 | ||
| 1770 | /* | 1773 | /* |
| 1771 | * Cancel background eofb scanning so it cannot race with the final | 1774 | * Cancel background eofb scanning so it cannot race with the final |
| @@ -1773,8 +1776,13 @@ xfs_remount_ro( · 1 unmodified line | |||
| 1773 | */ | 1776 | */ |
| 1774 | xfs_blockgc_stop(mp); | 1777 | xfs_blockgc_stop(mp); |
| 1775 | 1778 | ||
| 1776 | /* Get rid of any leftover CoW reservations... */ | 1779 | /* |
| 1777 | error = xfs_blockgc_free_space(mp, NULL); | 1780 | * Clear out all remaining COW staging extents and speculative post-EOF |
| 1781 | * preallocations so that we don't leave inodes requiring inactivation | ||
| 1782 | * cleanups during reclaim on a read-only mount. We must process every | ||
| 1783 | * cached inode, so this requires a synchronous cache scan. | ||
| 1784 | */ | ||
| 1785 | error = xfs_blockgc_free_space(mp, &icw); | ||
| 1778 | if (error) { | 1786 | if (error) { |
| 1779 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | 1787 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
| 1780 | return error; | 1788 | return error; |
| @@ -732,6 +732,7 @@ int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr) · 731 unmodified lines | |||
| 732 | struct bpf_trampoline *bpf_trampoline_get(u64 key, | 732 | struct bpf_trampoline *bpf_trampoline_get(u64 key, |
| 733 | struct bpf_attach_target_info *tgt_info); | 733 | struct bpf_attach_target_info *tgt_info); |
| 734 | void bpf_trampoline_put(struct bpf_trampoline *tr); | 734 | void bpf_trampoline_put(struct bpf_trampoline *tr); |
| 735 | int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs); | ||
| 735 | #define BPF_DISPATCHER_INIT(_name) { \ | 736 | #define BPF_DISPATCHER_INIT(_name) { \ |
| 736 | .mutex = __MUTEX_INITIALIZER(_name.mutex), \ | 737 | .mutex = __MUTEX_INITIALIZER(_name.mutex), \ |
| 737 | .func = &_name##_func, \ | 738 | .func = &_name##_func, \ |
| @@ -1352,28 +1353,16 @@ extern struct mutex bpf_stats_enabled_mutex; · 614 unmodified lines | |||
| 1352 | * kprobes, tracepoints) to prevent deadlocks on map operations as any of | 1353 | * kprobes, tracepoints) to prevent deadlocks on map operations as any of |
| 1353 | * these events can happen inside a region which holds a map bucket lock | 1354 | * these events can happen inside a region which holds a map bucket lock |
| 1354 | * and can deadlock on it. | 1355 | * and can deadlock on it. |
| 1355 | * | ||
| 1356 | * Use the preemption safe inc/dec variants on RT because migrate disable | ||
| 1357 | * is preemptible on RT and preemption in the middle of the RMW operation | ||
| 1358 | * might lead to inconsistent state. Use the raw variants for non RT | ||
| 1359 | * kernels as migrate_disable() maps to preempt_disable() so the slightly | ||
| 1360 | * more expensive save operation can be avoided. | ||
| 1361 | */ | 1356 | */ |
| 1362 | static inline void bpf_disable_instrumentation(void) | 1357 | static inline void bpf_disable_instrumentation(void) |
| 1363 | { | 1358 | { |
| 1364 | migrate_disable(); | 1359 | migrate_disable(); |
| 1365 | if (IS_ENABLED(CONFIG_PREEMPT_RT)) | 1360 | this_cpu_inc(bpf_prog_active); |
| 1366 | this_cpu_inc(bpf_prog_active); | ||
| 1367 | else | ||
| 1368 | __this_cpu_inc(bpf_prog_active); | ||
| 1369 | } | 1361 | } |
| 1370 | 1362 | ||
| 1371 | static inline void bpf_enable_instrumentation(void) | 1363 | static inline void bpf_enable_instrumentation(void) |
| 1372 | { | 1364 | { |
| 1373 | if (IS_ENABLED(CONFIG_PREEMPT_RT)) | 1365 | this_cpu_dec(bpf_prog_active); |
| 1374 | this_cpu_dec(bpf_prog_active); | ||
| 1375 | else | ||
| 1376 | __this_cpu_dec(bpf_prog_active); | ||
| 1377 | migrate_enable(); | 1366 | migrate_enable(); |
| 1378 | } | 1367 | } |
| 1379 | 1368 | ||
| @@ -245,7 +245,10 @@ struct kfunc_btf_id_set { · 244 unmodified lines | |||
| 245 | struct module *owner; | 245 | struct module *owner; |
| 246 | }; | 246 | }; |
| 247 | 247 | ||
| 248 | struct kfunc_btf_id_list; | 248 | struct kfunc_btf_id_list { |
| 249 | struct list_head list; | ||
| 250 | struct mutex mutex; | ||
| 251 | }; | ||
| 249 | 252 | ||
| 250 | #ifdef CONFIG_DEBUG_INFO_BTF_MODULES | 253 | #ifdef CONFIG_DEBUG_INFO_BTF_MODULES |
| 251 | void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l, | 254 | void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l, |
| @@ -254,6 +257,9 @@ void unregister_kfunc_btf_id_set(struct kfunc_btf_id_list *l, · 2 unmodified lines | |||
| 254 | struct kfunc_btf_id_set *s); | 257 | struct kfunc_btf_id_set *s); |
| 255 | bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, | 258 | bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, |
| 256 | struct module *owner); | 259 | struct module *owner); |
| 260 | |||
| 261 | extern struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list; | ||
| 262 | extern struct kfunc_btf_id_list prog_test_kfunc_list; | ||
| 257 | #else | 263 | #else |
| 258 | static inline void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l, | 264 | static inline void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l, |
| 259 | struct kfunc_btf_id_set *s) | 265 | struct kfunc_btf_id_set *s) |
| @@ -268,13 +274,13 @@ static inline bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, · 8 unmodified lines | |||
| 268 | { | 274 | { |
| 269 | return false; | 275 | return false; |
| 270 | } | 276 | } |
| 277 | |||
| 278 | static struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list __maybe_unused; | ||
| 279 | static struct kfunc_btf_id_list prog_test_kfunc_list __maybe_unused; | ||
| 271 | #endif | 280 | #endif |
| 272 | 281 | ||
| 273 | #define DEFINE_KFUNC_BTF_ID_SET(set, name) \ | 282 | #define DEFINE_KFUNC_BTF_ID_SET(set, name) \ |
| 274 | struct kfunc_btf_id_set name = { LIST_HEAD_INIT(name.list), (set), \ | 283 | struct kfunc_btf_id_set name = { LIST_HEAD_INIT(name.list), (set), \ |
| 275 | THIS_MODULE } | 284 | THIS_MODULE } |
| 276 | 285 | ||
| 277 | extern struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list; | ||
| 278 | extern struct kfunc_btf_id_list prog_test_kfunc_list; | ||
| 279 | |||
| 280 | #endif | 286 | #endif |
| @@ -3,7 +3,6 @@ · 2 unmodified lines | |||
| 3 | #define _LINUX_CACHEINFO_H | 3 | #define _LINUX_CACHEINFO_H |
| 4 | 4 | ||
| 5 | #include <linux/bitops.h> | 5 | #include <linux/bitops.h> |
| 6 | #include <linux/cpu.h> | ||
| 7 | #include <linux/cpumask.h> | 6 | #include <linux/cpumask.h> |
| 8 | #include <linux/smp.h> | 7 | #include <linux/smp.h> |
| 9 | 8 | ||
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <linux/math.h> | 22 | #include <linux/math.h> |
| 23 | #include <linux/sched.h> | ||
| 23 | 24 | ||
| 24 | extern unsigned long loops_per_jiffy; | 25 | extern unsigned long loops_per_jiffy; |
| 25 | 26 | ||
| @@ -58,7 +59,18 @@ void calibrate_delay(void); · 32 unmodified lines | |||
| 58 | void __attribute__((weak)) calibration_delay_done(void); | 59 | void __attribute__((weak)) calibration_delay_done(void); |
| 59 | void msleep(unsigned int msecs); | 60 | void msleep(unsigned int msecs); |
| 60 | unsigned long msleep_interruptible(unsigned int msecs); | 61 | unsigned long msleep_interruptible(unsigned int msecs); |
| 61 | void usleep_range(unsigned long min, unsigned long max); | 62 | void usleep_range_state(unsigned long min, unsigned long max, |
| 63 | unsigned int state); | ||
| 64 | |||
| 65 | static inline void usleep_range(unsigned long min, unsigned long max) | ||
| 66 | { | ||
| 67 | usleep_range_state(min, max, TASK_UNINTERRUPTIBLE); | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline void usleep_idle_range(unsigned long min, unsigned long max) | ||
| 71 | { | ||
| 72 | usleep_range_state(min, max, TASK_IDLE); | ||
| 73 | } | ||
| 62 | 74 | ||
| 63 | static inline void ssleep(unsigned int seconds) | 75 | static inline void ssleep(unsigned int seconds) |
| 64 | { | 76 | { |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/klist.h> | 18 | #include <linux/klist.h> |
| 19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
| 20 | #include <linux/device/bus.h> | 20 | #include <linux/device/bus.h> |
| 21 | #include <linux/module.h> | ||
| 21 | 22 | ||
| 22 | /** | 23 | /** |
| 23 | * enum probe_type - device driver probe type to try | 24 | * enum probe_type - device driver probe type to try |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #define __LINUX_FILTER_H__ | 6 | #define __LINUX_FILTER_H__ |
| 7 | 7 | ||
| 8 | #include <linux/atomic.h> | 8 | #include <linux/atomic.h> |
| 9 | #include <linux/bpf.h> | ||
| 9 | #include <linux/refcount.h> | 10 | #include <linux/refcount.h> |
| 10 | #include <linux/compat.h> | 11 | #include <linux/compat.h> |
| 11 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
| @@ -26,7 +27,6 @@ · 14 unmodified lines | |||
| 26 | 27 | ||
| 27 | #include <asm/byteorder.h> | 28 | #include <asm/byteorder.h> |
| 28 | #include <uapi/linux/filter.h> | 29 | #include <uapi/linux/filter.h> |
| 29 | #include <uapi/linux/bpf.h> | ||
| 30 | 30 | ||
| 31 | struct sk_buff; | 31 | struct sk_buff; |
| 32 | struct sock; | 32 | struct sock; |
| @@ -640,9 +640,6 @@ static __always_inline u32 bpf_prog_run(const struct bpf_prog *prog, const void · 607 unmodified lines | |||
| 640 | * This uses migrate_disable/enable() explicitly to document that the | 640 | * This uses migrate_disable/enable() explicitly to document that the |
| 641 | * invocation of a BPF program does not require reentrancy protection | 641 | * invocation of a BPF program does not require reentrancy protection |
| 642 | * against a BPF program which is invoked from a preempting task. | 642 | * against a BPF program which is invoked from a preempting task. |
| 643 | * | ||
| 644 | * For non RT enabled kernels migrate_disable/enable() maps to | ||
| 645 | * preempt_disable/enable(), i.e. it disables also preemption. | ||
| 646 | */ | 643 | */ |
| 647 | static inline u32 bpf_prog_run_pin_on_cpu(const struct bpf_prog *prog, | 644 | static inline u32 bpf_prog_run_pin_on_cpu(const struct bpf_prog *prog, |
| 648 | const void *ctx) | 645 | const void *ctx) |
| @@ -840,6 +840,11 @@ static inline bool hid_is_using_ll_driver(struct hid_device *hdev, · 839 unmodified lines | |||
| 840 | return hdev->ll_driver == driver; | 840 | return hdev->ll_driver == driver; |
| 841 | } | 841 | } |
| 842 | 842 | ||
| 843 | static inline bool hid_is_usb(struct hid_device *hdev) | ||
| 844 | { | ||
| 845 | return hid_is_using_ll_driver(hdev, &usb_hid_driver); | ||
| 846 | } | ||
| 847 | |||
| 843 | #define PM_HINT_FULLON 1<<5 | 848 | #define PM_HINT_FULLON 1<<5 |
| 844 | #define PM_HINT_NORMAL 1<<1 | 849 | #define PM_HINT_NORMAL 1<<1 |
| 845 | 850 | ||
| @@ -153,6 +153,8 @@ struct kretprobe { · 152 unmodified lines | |||
| 153 | struct kretprobe_holder *rph; | 153 | struct kretprobe_holder *rph; |
| 154 | }; | 154 | }; |
| 155 | 155 | ||
| 156 | #define KRETPROBE_MAX_DATA_SIZE 4096 | ||
| 157 | |||
| 156 | struct kretprobe_instance { | 158 | struct kretprobe_instance { |
| 157 | union { | 159 | union { |
| 158 | struct freelist_node freelist; | 160 | struct freelist_node freelist; |
| @@ -663,6 +663,19 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl); · 662 unmodified lines | |||
| 663 | */ | 663 | */ |
| 664 | int mhi_pm_resume(struct mhi_controller *mhi_cntrl); | 664 | int mhi_pm_resume(struct mhi_controller *mhi_cntrl); |
| 665 | 665 | ||
| 666 | /** | ||
| 667 | * mhi_pm_resume_force - Force resume MHI from suspended state | ||
| 668 | * @mhi_cntrl: MHI controller | ||
| 669 | * | ||
| 670 | * Resume the device irrespective of its MHI state. As per the MHI spec, devices | ||
| 671 | * has to be in M3 state during resume. But some devices seem to be in a | ||
| 672 | * different MHI state other than M3 but they continue working fine if allowed. | ||
| 673 | * This API is intented to be used for such devices. | ||
| 674 | * | ||
| 675 | * Return: 0 if the resume succeeds, a negative error code otherwise | ||
| 676 | */ | ||
| 677 | int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl); | ||
| 678 | |||
| 666 | /** | 679 | /** |
| 667 | * mhi_download_rddm_image - Download ramdump image from device for | 680 | * mhi_download_rddm_image - Download ramdump image from device for |
| 668 | * debugging purpose. | 681 | * debugging purpose. |
| @@ -9698,7 +9698,10 @@ struct mlx5_ifc_mcam_access_reg_bits { · 9697 unmodified lines | |||
| 9698 | u8 regs_84_to_68[0x11]; | 9698 | u8 regs_84_to_68[0x11]; |
| 9699 | u8 tracer_registers[0x4]; | 9699 | u8 tracer_registers[0x4]; |
| 9700 | 9700 | ||
| 9701 | u8 regs_63_to_32[0x20]; | 9701 | u8 regs_63_to_46[0x12]; |
| 9702 | u8 mrtc[0x1]; | ||
| 9703 | u8 regs_44_to_32[0xd]; | ||
| 9704 | |||
| 9702 | u8 regs_31_to_0[0x20]; | 9705 | u8 regs_31_to_0[0x20]; |
| 9703 | }; | 9706 | }; |
| 9704 | 9707 | ||
| @@ -4404,7 +4404,8 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) · 4403 unmodified lines | |||
| 4404 | static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) | 4404 | static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) |
| 4405 | { | 4405 | { |
| 4406 | spin_lock(&txq->_xmit_lock); | 4406 | spin_lock(&txq->_xmit_lock); |
| 4407 | txq->xmit_lock_owner = cpu; | 4407 | /* Pairs with READ_ONCE() in __dev_queue_xmit() */ |
| 4408 | WRITE_ONCE(txq->xmit_lock_owner, cpu); | ||
| 4408 | } | 4409 | } |
| 4409 | 4410 | ||
| 4410 | static inline bool __netif_tx_acquire(struct netdev_queue *txq) | 4411 | static inline bool __netif_tx_acquire(struct netdev_queue *txq) |
| @@ -4421,26 +4422,32 @@ static inline void __netif_tx_release(struct netdev_queue *txq) · 10 unmodified lines | |||
| 4421 | static inline void __netif_tx_lock_bh(struct netdev_queue *txq) | 4422 | static inline void __netif_tx_lock_bh(struct netdev_queue *txq) |
| 4422 | { | 4423 | { |
| 4423 | spin_lock_bh(&txq->_xmit_lock); | 4424 | spin_lock_bh(&txq->_xmit_lock); |
| 4424 | txq->xmit_lock_owner = smp_processor_id(); | 4425 | /* Pairs with READ_ONCE() in __dev_queue_xmit() */ |
| 4426 | WRITE_ONCE(txq->xmit_lock_owner, smp_processor_id()); | ||
| 4425 | } | 4427 | } |
| 4426 | 4428 | ||
| 4427 | static inline bool __netif_tx_trylock(struct netdev_queue *txq) | 4429 | static inline bool __netif_tx_trylock(struct netdev_queue *txq) |
| 4428 | { | 4430 | { |
| 4429 | bool ok = spin_trylock(&txq->_xmit_lock); | 4431 | bool ok = spin_trylock(&txq->_xmit_lock); |
| 4430 | if (likely(ok)) | 4432 | |
| 4431 | txq->xmit_lock_owner = smp_processor_id(); | 4433 | if (likely(ok)) { |
| 4434 | /* Pairs with READ_ONCE() in __dev_queue_xmit() */ | ||
| 4435 | WRITE_ONCE(txq->xmit_lock_owner, smp_processor_id()); | ||
| 4436 | } | ||
| 4432 | return ok; | 4437 | return ok; |
| 4433 | } | 4438 | } |
| 4434 | 4439 | ||
| 4435 | static inline void __netif_tx_unlock(struct netdev_queue *txq) | 4440 | static inline void __netif_tx_unlock(struct netdev_queue *txq) |
| 4436 | { | 4441 | { |
| 4437 | txq->xmit_lock_owner = -1; | 4442 | /* Pairs with READ_ONCE() in __dev_queue_xmit() */ |
| 4443 | WRITE_ONCE(txq->xmit_lock_owner, -1); | ||
| 4438 | spin_unlock(&txq->_xmit_lock); | 4444 | spin_unlock(&txq->_xmit_lock); |
| 4439 | } | 4445 | } |
| 4440 | 4446 | ||
| 4441 | static inline void __netif_tx_unlock_bh(struct netdev_queue *txq) | 4447 | static inline void __netif_tx_unlock_bh(struct netdev_queue *txq) |
| 4442 | { | 4448 | { |
| 4443 | txq->xmit_lock_owner = -1; | 4449 | /* Pairs with READ_ONCE() in __dev_queue_xmit() */ |
| 4450 | WRITE_ONCE(txq->xmit_lock_owner, -1); | ||
| 4444 | spin_unlock_bh(&txq->_xmit_lock); | 4451 | spin_unlock_bh(&txq->_xmit_lock); |
| 4445 | } | 4452 | } |
| 4446 | 4453 | ||
| @@ -51,9 +51,9 @@ · 50 unmodified lines | |||
| 51 | #define _LINUX_PERCPU_REFCOUNT_H | 51 | #define _LINUX_PERCPU_REFCOUNT_H |
| 52 | 52 | ||
| 53 | #include <linux/atomic.h> | 53 | #include <linux/atomic.h> |
| 54 | #include <linux/kernel.h> | ||
| 55 | #include <linux/percpu.h> | 54 | #include <linux/percpu.h> |
| 56 | #include <linux/rcupdate.h> | 55 | #include <linux/rcupdate.h> |
| 56 | #include <linux/types.h> | ||
| 57 | #include <linux/gfp.h> | 57 | #include <linux/gfp.h> |
| 58 | 58 | ||
| 59 | struct percpu_ref; | 59 | struct percpu_ref; |
| @@ -538,11 +538,12 @@ struct macsec_ops; · 537 unmodified lines | |||
| 538 | * @mac_managed_pm: Set true if MAC driver takes of suspending/resuming PHY | 538 | * @mac_managed_pm: Set true if MAC driver takes of suspending/resuming PHY |
| 539 | * @state: State of the PHY for management purposes | 539 | * @state: State of the PHY for management purposes |
| 540 | * @dev_flags: Device-specific flags used by the PHY driver. | 540 | * @dev_flags: Device-specific flags used by the PHY driver. |
| 541 | * Bits [15:0] are free to use by the PHY driver to communicate | 541 | * |
| 542 | * driver specific behavior. | 542 | * - Bits [15:0] are free to use by the PHY driver to communicate |
| 543 | * Bits [23:16] are currently reserved for future use. | 543 | * driver specific behavior. |
| 544 | * Bits [31:24] are reserved for defining generic | 544 | * - Bits [23:16] are currently reserved for future use. |
| 545 | * PHY driver behavior. | 545 | * - Bits [31:24] are reserved for defining generic |
| 546 | * PHY driver behavior. | ||
| 546 | * @irq: IRQ number of the PHY's interrupt (-1 if none) | 547 | * @irq: IRQ number of the PHY's interrupt (-1 if none) |
| 547 | * @phy_timer: The timer for handling the state machine | 548 | * @phy_timer: The timer for handling the state machine |
| 548 | * @phylink: Pointer to phylink instance for this PHY | 549 | * @phylink: Pointer to phylink instance for this PHY |
| @@ -129,7 +129,7 @@ static inline bool pm_runtime_suspended(struct device *dev) · 128 unmodified lines | |||
| 129 | * pm_runtime_active - Check whether or not a device is runtime-active. | 129 | * pm_runtime_active - Check whether or not a device is runtime-active. |
| 130 | * @dev: Target device. | 130 | * @dev: Target device. |
| 131 | * | 131 | * |
| 132 | * Return %true if runtime PM is enabled for @dev and its runtime PM status is | 132 | * Return %true if runtime PM is disabled for @dev or its runtime PM status is |
| 133 | * %RPM_ACTIVE, or %false otherwise. | 133 | * %RPM_ACTIVE, or %false otherwise. |
| 134 | * | 134 | * |
| 135 | * Note that the return value of this function can only be trusted if it is | 135 | * Note that the return value of this function can only be trusted if it is |
| @@ -499,7 +499,8 @@ struct regulator_irq_data { · 498 unmodified lines | |||
| 499 | * best to shut-down regulator(s) or reboot the SOC if error | 499 | * best to shut-down regulator(s) or reboot the SOC if error |
| 500 | * handling is repeatedly failing. If fatal_cnt is given the IRQ | 500 | * handling is repeatedly failing. If fatal_cnt is given the IRQ |
| 501 | * handling is aborted if it fails for fatal_cnt times and die() | 501 | * handling is aborted if it fails for fatal_cnt times and die() |
| 502 | * callback (if populated) or BUG() is called to try to prevent | 502 | * callback (if populated) is called. If die() is not populated |
| 503 | * poweroff for the system is attempted in order to prevent any | ||
| 503 | * further damage. | 504 | * further damage. |
| 504 | * @reread_ms: The time which is waited before attempting to re-read status | 505 | * @reread_ms: The time which is waited before attempting to re-read status |
| 505 | * at the worker if IC reading fails. Immediate re-read is done | 506 | * at the worker if IC reading fails. Immediate re-read is done |
| @@ -516,11 +517,12 @@ struct regulator_irq_data { · 10 unmodified lines | |||
| 516 | * @data: Driver private data pointer which will be passed as such to | 517 | * @data: Driver private data pointer which will be passed as such to |
| 517 | * the renable, map_event and die callbacks in regulator_irq_data. | 518 | * the renable, map_event and die callbacks in regulator_irq_data. |
| 518 | * @die: Protection callback. If IC status reading or recovery actions | 519 | * @die: Protection callback. If IC status reading or recovery actions |
| 519 | * fail fatal_cnt times this callback or BUG() is called. This | 520 | * fail fatal_cnt times this callback is called or system is |
| 520 | * callback should implement a final protection attempt like | 521 | * powered off. This callback should implement a final protection |
| 521 | * disabling the regulator. If protection succeeded this may | 522 | * attempt like disabling the regulator. If protection succeeded |
| 522 | * return 0. If anything else is returned the core assumes final | 523 | * die() may return 0. If anything else is returned the core |
| 523 | * protection failed and calls BUG() as a last resort. | 524 | * assumes final protection failed and attempts to perform a |
| 525 | * poweroff as a last resort. | ||
| 524 | * @map_event: Driver callback to map IRQ status into regulator devices with | 526 | * @map_event: Driver callback to map IRQ status into regulator devices with |
| 525 | * events / errors. NOTE: callback MUST initialize both the | 527 | * events / errors. NOTE: callback MUST initialize both the |
| 526 | * errors and notifs for all rdevs which it signals having | 528 | * errors and notifs for all rdevs which it signals having |
| @@ -18,15 +18,16 @@ · 17 unmodified lines | |||
| 18 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ | 18 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
| 19 | 19 | ||
| 20 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN | 20 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN |
| 21 | extern void task_cputime(struct task_struct *t, | 21 | extern bool task_cputime(struct task_struct *t, |
| 22 | u64 *utime, u64 *stime); | 22 | u64 *utime, u64 *stime); |
| 23 | extern u64 task_gtime(struct task_struct *t); | 23 | extern u64 task_gtime(struct task_struct *t); |
| 24 | #else | 24 | #else |
| 25 | static inline void task_cputime(struct task_struct *t, | 25 | static inline bool task_cputime(struct task_struct *t, |
| 26 | u64 *utime, u64 *stime) | 26 | u64 *utime, u64 *stime) |
| 27 | { | 27 | { |
| 28 | *utime = t->utime; | 28 | *utime = t->utime; |
| 29 | *stime = t->stime; | 29 | *stime = t->stime; |
| 30 | return false; | ||
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | static inline u64 task_gtime(struct task_struct *t) | 33 | static inline u64 task_gtime(struct task_struct *t) |
| @@ -27,9 +27,7 @@ static inline bool siphash_key_is_zero(const siphash_key_t *key) · 26 unmodified lines | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key); | 29 | u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key); |
| 30 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 31 | u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key); | 30 | u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key); |
| 32 | #endif | ||
| 33 | 31 | ||
| 34 | u64 siphash_1u64(const u64 a, const siphash_key_t *key); | 32 | u64 siphash_1u64(const u64 a, const siphash_key_t *key); |
| 35 | u64 siphash_2u64(const u64 a, const u64 b, const siphash_key_t *key); | 33 | u64 siphash_2u64(const u64 a, const u64 b, const siphash_key_t *key); |
| @@ -82,10 +80,9 @@ static inline u64 ___siphash_aligned(const __le64 *data, size_t len, · 46 unmodified lines | |||
| 82 | static inline u64 siphash(const void *data, size_t len, | 80 | static inline u64 siphash(const void *data, size_t len, |
| 83 | const siphash_key_t *key) | 81 | const siphash_key_t *key) |
| 84 | { | 82 | { |
| 85 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | 83 | if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) || |
| 86 | if (!IS_ALIGNED((unsigned long)data, SIPHASH_ALIGNMENT)) | 84 | !IS_ALIGNED((unsigned long)data, SIPHASH_ALIGNMENT)) |
| 87 | return __siphash_unaligned(data, len, key); | 85 | return __siphash_unaligned(data, len, key); |
| 88 | #endif | ||
| 89 | return ___siphash_aligned(data, len, key); | 86 | return ___siphash_aligned(data, len, key); |
| 90 | } | 87 | } |
| 91 | 88 | ||
| @@ -96,10 +93,8 @@ typedef struct { · 4 unmodified lines | |||
| 96 | 93 | ||
| 97 | u32 __hsiphash_aligned(const void *data, size_t len, | 94 | u32 __hsiphash_aligned(const void *data, size_t len, |
| 98 | const hsiphash_key_t *key); | 95 | const hsiphash_key_t *key); |
| 99 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 100 | u32 __hsiphash_unaligned(const void *data, size_t len, | 96 | u32 __hsiphash_unaligned(const void *data, size_t len, |
| 101 | const hsiphash_key_t *key); | 97 | const hsiphash_key_t *key); |
| 102 | #endif | ||
| 103 | 98 | ||
| 104 | u32 hsiphash_1u32(const u32 a, const hsiphash_key_t *key); | 99 | u32 hsiphash_1u32(const u32 a, const hsiphash_key_t *key); |
| 105 | u32 hsiphash_2u32(const u32 a, const u32 b, const hsiphash_key_t *key); | 100 | u32 hsiphash_2u32(const u32 a, const u32 b, const hsiphash_key_t *key); |
| @@ -135,10 +130,9 @@ static inline u32 ___hsiphash_aligned(const __le32 *data, size_t len, · 29 unmodified lines | |||
| 135 | static inline u32 hsiphash(const void *data, size_t len, | 130 | static inline u32 hsiphash(const void *data, size_t len, |
| 136 | const hsiphash_key_t *key) | 131 | const hsiphash_key_t *key) |
| 137 | { | 132 | { |
| 138 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | 133 | if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) || |
| 139 | if (!IS_ALIGNED((unsigned long)data, HSIPHASH_ALIGNMENT)) | 134 | !IS_ALIGNED((unsigned long)data, HSIPHASH_ALIGNMENT)) |
| 140 | return __hsiphash_unaligned(data, len, key); | 135 | return __hsiphash_unaligned(data, len, key); |
| 141 | #endif | ||
| 142 | return ___hsiphash_aligned(data, len, key); | 136 | return ___hsiphash_aligned(data, len, key); |
| 143 | } | 137 | } |
| 144 | 138 | ||
| @@ -217,6 +217,7 @@ void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode, void · 216 unmodified lines | |||
| 217 | void __wake_up_locked_sync_key(struct wait_queue_head *wq_head, unsigned int mode, void *key); | 217 | void __wake_up_locked_sync_key(struct wait_queue_head *wq_head, unsigned int mode, void *key); |
| 218 | void __wake_up_locked(struct wait_queue_head *wq_head, unsigned int mode, int nr); | 218 | void __wake_up_locked(struct wait_queue_head *wq_head, unsigned int mode, int nr); |
| 219 | void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode); | 219 | void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode); |
| 220 | void __wake_up_pollfree(struct wait_queue_head *wq_head); | ||
| 220 | 221 | ||
| 221 | #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) | 222 | #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) |
| 222 | #define wake_up_nr(x, nr) __wake_up(x, TASK_NORMAL, nr, NULL) | 223 | #define wake_up_nr(x, nr) __wake_up(x, TASK_NORMAL, nr, NULL) |
| @@ -245,6 +246,31 @@ void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode); · 22 unmodified lines | |||
| 245 | #define wake_up_interruptible_sync_poll_locked(x, m) \ | 246 | #define wake_up_interruptible_sync_poll_locked(x, m) \ |
| 246 | __wake_up_locked_sync_key((x), TASK_INTERRUPTIBLE, poll_to_key(m)) | 247 | __wake_up_locked_sync_key((x), TASK_INTERRUPTIBLE, poll_to_key(m)) |
| 247 | 248 | ||
| 249 | /** | ||
| 250 | * wake_up_pollfree - signal that a polled waitqueue is going away | ||
| 251 | * @wq_head: the wait queue head | ||
| 252 | * | ||
| 253 | * In the very rare cases where a ->poll() implementation uses a waitqueue whose | ||
| 254 | * lifetime is tied to a task rather than to the 'struct file' being polled, | ||
| 255 | * this function must be called before the waitqueue is freed so that | ||
| 256 | * non-blocking polls (e.g. epoll) are notified that the queue is going away. | ||
| 257 | * | ||
| 258 | * The caller must also RCU-delay the freeing of the wait_queue_head, e.g. via | ||
| 259 | * an explicit synchronize_rcu() or call_rcu(), or via SLAB_TYPESAFE_BY_RCU. | ||
| 260 | */ | ||
| 261 | static inline void wake_up_pollfree(struct wait_queue_head *wq_head) | ||
| 262 | { | ||
| 263 | /* | ||
| 264 | * For performance reasons, we don't always take the queue lock here. | ||
| 265 | * Therefore, we might race with someone removing the last entry from | ||
| 266 | * the queue, and proceed while they still hold the queue lock. | ||
| 267 | * However, rcu_read_lock() is required to be held in such cases, so we | ||
| 268 | * can safely proceed with an RCU-delayed free. | ||
| 269 | */ | ||
| 270 | if (waitqueue_active(wq_head)) | ||
| 271 | __wake_up_pollfree(wq_head); | ||
| 272 | } | ||
| 273 | |||
| 248 | #define ___wait_cond_timeout(condition) \ | 274 | #define ___wait_cond_timeout(condition) \ |
| 249 | ({ \ | 275 | ({ \ |
| 250 | bool __cond = (condition); \ | 276 | bool __cond = (condition); \ |
| @@ -126,7 +126,7 @@ struct tlb_slave_info { · 125 unmodified lines | |||
| 126 | struct alb_bond_info { | 126 | struct alb_bond_info { |
| 127 | struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */ | 127 | struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */ |
| 128 | u32 unbalanced_load; | 128 | u32 unbalanced_load; |
| 129 | int tx_rebalance_counter; | 129 | atomic_t tx_rebalance_counter; |
| 130 | int lp_counter; | 130 | int lp_counter; |
| 131 | /* -------- rlb parameters -------- */ | 131 | /* -------- rlb parameters -------- */ |
| 132 | int rlb_enabled; | 132 | int rlb_enabled; |
| @@ -132,6 +132,19 @@ static inline void sk_mark_napi_id(struct sock *sk, const struct sk_buff *skb) · 131 unmodified lines | |||
| 132 | #ifdef CONFIG_NET_RX_BUSY_POLL | 132 | #ifdef CONFIG_NET_RX_BUSY_POLL |
| 133 | if (unlikely(READ_ONCE(sk->sk_napi_id) != skb->napi_id)) | 133 | if (unlikely(READ_ONCE(sk->sk_napi_id) != skb->napi_id)) |
| 134 | WRITE_ONCE(sk->sk_napi_id, skb->napi_id); | 134 | WRITE_ONCE(sk->sk_napi_id, skb->napi_id); |
| 135 | #endif | ||
| 136 | sk_rx_queue_update(sk, skb); | ||
| 137 | } | ||
| 138 | |||
| 139 | /* Variant of sk_mark_napi_id() for passive flow setup, | ||
| 140 | * as sk->sk_napi_id and sk->sk_rx_queue_mapping content | ||
| 141 | * needs to be set. | ||
| 142 | */ | ||
| 143 | static inline void sk_mark_napi_id_set(struct sock *sk, | ||
| 144 | const struct sk_buff *skb) | ||
| 145 | { | ||
| 146 | #ifdef CONFIG_NET_RX_BUSY_POLL | ||
| 147 | WRITE_ONCE(sk->sk_napi_id, skb->napi_id); | ||
| 135 | #endif | 148 | #endif |
| 136 | sk_rx_queue_set(sk, skb); | 149 | sk_rx_queue_set(sk, skb); |
| 137 | } | 150 | } |
| @@ -79,6 +79,17 @@ static inline void dst_cache_reset(struct dst_cache *dst_cache) · 78 unmodified lines | |||
| 79 | dst_cache->reset_ts = jiffies; | 79 | dst_cache->reset_ts = jiffies; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | /** | ||
| 83 | * dst_cache_reset_now - invalidate the cache contents immediately | ||
| 84 | * @dst_cache: the cache | ||
| 85 | * | ||
| 86 | * The caller must be sure there are no concurrent users, as this frees | ||
| 87 | * all dst_cache users immediately, rather than waiting for the next | ||
| 88 | * per-cpu usage like dst_cache_reset does. Most callers should use the | ||
| 89 | * higher speed lazily-freed dst_cache_reset function instead. | ||
| 90 | */ | ||
| 91 | void dst_cache_reset_now(struct dst_cache *dst_cache); | ||
| 92 | |||
| 82 | /** | 93 | /** |
| 83 | * dst_cache_init - initialize the cache, allocating the required storage | 94 | * dst_cache_init - initialize the cache, allocating the required storage |
| 84 | * @dst_cache: the cache | 95 | * @dst_cache: the cache |
| @@ -69,7 +69,7 @@ struct fib_rules_ops { · 68 unmodified lines | |||
| 69 | int (*action)(struct fib_rule *, | 69 | int (*action)(struct fib_rule *, |
| 70 | struct flowi *, int, | 70 | struct flowi *, int, |
| 71 | struct fib_lookup_arg *); | 71 | struct fib_lookup_arg *); |
| 72 | bool (*suppress)(struct fib_rule *, | 72 | bool (*suppress)(struct fib_rule *, int, |
| 73 | struct fib_lookup_arg *); | 73 | struct fib_lookup_arg *); |
| 74 | int (*match)(struct fib_rule *, | 74 | int (*match)(struct fib_rule *, |
| 75 | struct flowi *, int); | 75 | struct flowi *, int); |
| @@ -218,7 +218,9 @@ INDIRECT_CALLABLE_DECLARE(int fib4_rule_action(struct fib_rule *rule, · 142 unmodified lines | |||
| 218 | struct fib_lookup_arg *arg)); | 218 | struct fib_lookup_arg *arg)); |
| 219 | 219 | ||
| 220 | INDIRECT_CALLABLE_DECLARE(bool fib6_rule_suppress(struct fib_rule *rule, | 220 | INDIRECT_CALLABLE_DECLARE(bool fib6_rule_suppress(struct fib_rule *rule, |
| 221 | int flags, | ||
| 221 | struct fib_lookup_arg *arg)); | 222 | struct fib_lookup_arg *arg)); |
| 222 | INDIRECT_CALLABLE_DECLARE(bool fib4_rule_suppress(struct fib_rule *rule, | 223 | INDIRECT_CALLABLE_DECLARE(bool fib4_rule_suppress(struct fib_rule *rule, |
| 224 | int flags, | ||
| 223 | struct fib_lookup_arg *arg)); | 225 | struct fib_lookup_arg *arg)); |
| 224 | #endif | 226 | #endif |
| @@ -438,7 +438,7 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, · 437 unmodified lines | |||
| 438 | #ifdef CONFIG_IP_ROUTE_CLASSID | 438 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 439 | static inline int fib_num_tclassid_users(struct net *net) | 439 | static inline int fib_num_tclassid_users(struct net *net) |
| 440 | { | 440 | { |
| 441 | return net->ipv4.fib_num_tclassid_users; | 441 | return atomic_read(&net->ipv4.fib_num_tclassid_users); |
| 442 | } | 442 | } |
| 443 | #else | 443 | #else |
| 444 | static inline int fib_num_tclassid_users(struct net *net) | 444 | static inline int fib_num_tclassid_users(struct net *net) |
| @@ -276,14 +276,14 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb) · 275 unmodified lines | |||
| 276 | /* jiffies until ct expires, 0 if already expired */ | 276 | /* jiffies until ct expires, 0 if already expired */ |
| 277 | static inline unsigned long nf_ct_expires(const struct nf_conn *ct) | 277 | static inline unsigned long nf_ct_expires(const struct nf_conn *ct) |
| 278 | { | 278 | { |
| 279 | s32 timeout = ct->timeout - nfct_time_stamp; | 279 | s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp; |
| 280 | 280 | ||
| 281 | return timeout > 0 ? timeout : 0; | 281 | return timeout > 0 ? timeout : 0; |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | static inline bool nf_ct_is_expired(const struct nf_conn *ct) | 284 | static inline bool nf_ct_is_expired(const struct nf_conn *ct) |
| 285 | { | 285 | { |
| 286 | return (__s32)(ct->timeout - nfct_time_stamp) <= 0; | 286 | return (__s32)(READ_ONCE(ct->timeout) - nfct_time_stamp) <= 0; |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | /* use after obtaining a reference count */ | 289 | /* use after obtaining a reference count */ |
| @@ -302,7 +302,7 @@ static inline bool nf_ct_should_gc(const struct nf_conn *ct) · 12 unmodified lines | |||
| 302 | static inline void nf_ct_offload_timeout(struct nf_conn *ct) | 302 | static inline void nf_ct_offload_timeout(struct nf_conn *ct) |
| 303 | { | 303 | { |
| 304 | if (nf_ct_expires(ct) < NF_CT_DAY / 2) | 304 | if (nf_ct_expires(ct) < NF_CT_DAY / 2) |
| 305 | ct->timeout = nfct_time_stamp + NF_CT_DAY; | 305 | WRITE_ONCE(ct->timeout, nfct_time_stamp + NF_CT_DAY); |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | struct kernel_param; | 308 | struct kernel_param; |
| @@ -65,7 +65,7 @@ struct netns_ipv4 { · 64 unmodified lines | |||
| 65 | bool fib_has_custom_local_routes; | 65 | bool fib_has_custom_local_routes; |
| 66 | bool fib_offload_disabled; | 66 | bool fib_offload_disabled; |
| 67 | #ifdef CONFIG_IP_ROUTE_CLASSID | 67 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 68 | int fib_num_tclassid_users; | 68 | atomic_t fib_num_tclassid_users; |
| 69 | #endif | 69 | #endif |
| 70 | struct hlist_head *fib_table_hash; | 70 | struct hlist_head *fib_table_hash; |
| 71 | struct sock *fibnl; | 71 | struct sock *fibnl; |
| @@ -1913,18 +1913,31 @@ static inline int sk_tx_queue_get(const struct sock *sk) · 1912 unmodified lines | |||
| 1913 | return -1; | 1913 | return -1; |
| 1914 | } | 1914 | } |
| 1915 | 1915 | ||
| 1916 | static inline void sk_rx_queue_set(struct sock *sk, const struct sk_buff *skb) | 1916 | static inline void __sk_rx_queue_set(struct sock *sk, |
| 1917 | const struct sk_buff *skb, | ||
| 1918 | bool force_set) | ||
| 1917 | { | 1919 | { |
| 1918 | #ifdef CONFIG_SOCK_RX_QUEUE_MAPPING | 1920 | #ifdef CONFIG_SOCK_RX_QUEUE_MAPPING |
| 1919 | if (skb_rx_queue_recorded(skb)) { | 1921 | if (skb_rx_queue_recorded(skb)) { |
| 1920 | u16 rx_queue = skb_get_rx_queue(skb); | 1922 | u16 rx_queue = skb_get_rx_queue(skb); |
| 1921 | 1923 | ||
| 1922 | if (unlikely(READ_ONCE(sk->sk_rx_queue_mapping) != rx_queue)) | 1924 | if (force_set || |
| 1925 | unlikely(READ_ONCE(sk->sk_rx_queue_mapping) != rx_queue)) | ||
| 1923 | WRITE_ONCE(sk->sk_rx_queue_mapping, rx_queue); | 1926 | WRITE_ONCE(sk->sk_rx_queue_mapping, rx_queue); |
| 1924 | } | 1927 | } |
| 1925 | #endif | 1928 | #endif |
| 1926 | } | 1929 | } |
| 1927 | 1930 | ||
| 1931 | static inline void sk_rx_queue_set(struct sock *sk, const struct sk_buff *skb) | ||
| 1932 | { | ||
| 1933 | __sk_rx_queue_set(sk, skb, true); | ||
| 1934 | } | ||
| 1935 | |||
| 1936 | static inline void sk_rx_queue_update(struct sock *sk, const struct sk_buff *skb) | ||
| 1937 | { | ||
| 1938 | __sk_rx_queue_set(sk, skb, false); | ||
| 1939 | } | ||
| 1940 | |||
| 1928 | static inline void sk_rx_queue_clear(struct sock *sk) | 1941 | static inline void sk_rx_queue_clear(struct sock *sk) |
| 1929 | { | 1942 | { |
| 1930 | #ifdef CONFIG_SOCK_RX_QUEUE_MAPPING | 1943 | #ifdef CONFIG_SOCK_RX_QUEUE_MAPPING |
| @@ -2430,19 +2443,22 @@ static inline void sk_stream_moderate_sndbuf(struct sock *sk) · 499 unmodified lines | |||
| 2430 | * @sk: socket | 2443 | * @sk: socket |
| 2431 | * | 2444 | * |
| 2432 | * Use the per task page_frag instead of the per socket one for | 2445 | * Use the per task page_frag instead of the per socket one for |
| 2433 | * optimization when we know that we're in the normal context and owns | 2446 | * optimization when we know that we're in process context and own |
| 2434 | * everything that's associated with %current. | 2447 | * everything that's associated with %current. |
| 2435 | * | 2448 | * |
| 2436 | * gfpflags_allow_blocking() isn't enough here as direct reclaim may nest | 2449 | * Both direct reclaim and page faults can nest inside other |
| 2437 | * inside other socket operations and end up recursing into sk_page_frag() | 2450 | * socket operations and end up recursing into sk_page_frag() |
| 2438 | * while it's already in use. | 2451 | * while it's already in use: explicitly avoid task page_frag |
| 2452 | * usage if the caller is potentially doing any of them. | ||
| 2453 | * This assumes that page fault handlers use the GFP_NOFS flags. | ||
| 2439 | * | 2454 | * |
| 2440 | * Return: a per task page_frag if context allows that, | 2455 | * Return: a per task page_frag if context allows that, |
| 2441 | * otherwise a per socket one. | 2456 | * otherwise a per socket one. |
| 2442 | */ | 2457 | */ |
| 2443 | static inline struct page_frag *sk_page_frag(struct sock *sk) | 2458 | static inline struct page_frag *sk_page_frag(struct sock *sk) |
| 2444 | { | 2459 | { |
| 2445 | if (gfpflags_normal_context(sk->sk_allocation)) | 2460 | if ((sk->sk_allocation & (__GFP_DIRECT_RECLAIM | __GFP_MEMALLOC | __GFP_FS)) == |
| 2461 | (__GFP_DIRECT_RECLAIM | __GFP_FS)) | ||
| 2446 | return ¤t->task_frag; | 2462 | return ¤t->task_frag; |
| 2447 | 2463 | ||
| 2448 | return &sk->sk_frag; | 2464 | return &sk->sk_frag; |
| @@ -147,7 +147,7 @@ struct snd_soc_acpi_link_adr { · 146 unmodified lines | |||
| 147 | */ | 147 | */ |
| 148 | /* Descriptor for SST ASoC machine driver */ | 148 | /* Descriptor for SST ASoC machine driver */ |
| 149 | struct snd_soc_acpi_mach { | 149 | struct snd_soc_acpi_mach { |
| 150 | const u8 id[ACPI_ID_LEN]; | 150 | u8 id[ACPI_ID_LEN]; |
| 151 | const struct snd_soc_acpi_codecs *comp_ids; | 151 | const struct snd_soc_acpi_codecs *comp_ids; |
| 152 | const u32 link_mask; | 152 | const u32 link_mask; |
| 153 | const struct snd_soc_acpi_link_adr *links; | 153 | const struct snd_soc_acpi_link_adr *links; |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | |||
| 29 | #define POLLRDHUP 0x2000 | 29 | #define POLLRDHUP 0x2000 |
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #define POLLFREE (__force __poll_t)0x4000 /* currently only for epoll */ | 32 | #define POLLFREE (__force __poll_t)0x4000 |
| 33 | 33 | ||
| 34 | #define POLL_BUSY_LOOP (__force __poll_t)0x8000 | 34 | #define POLL_BUSY_LOOP (__force __poll_t)0x8000 |
| 35 | 35 | ||
| @@ -196,6 +196,13 @@ struct drm_virtgpu_context_init { · 195 unmodified lines | |||
| 196 | __u64 ctx_set_params; | 196 | __u64 ctx_set_params; |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | /* | ||
| 200 | * Event code that's given when VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK is in | ||
| 201 | * effect. The event size is sizeof(drm_event), since there is no additional | ||
| 202 | * payload. | ||
| 203 | */ | ||
| 204 | #define VIRTGPU_EVENT_FENCE_SIGNALED 0x90000000 | ||
| 205 | |||
| 199 | #define DRM_IOCTL_VIRTGPU_MAP \ | 206 | #define DRM_IOCTL_VIRTGPU_MAP \ |
| 200 | DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map) | 207 | DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map) |
| 201 | 208 | ||
| @@ -117,7 +117,7 @@ · 116 unmodified lines | |||
| 117 | #define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */ | 117 | #define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */ |
| 118 | #define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */ | 118 | #define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */ |
| 119 | 119 | ||
| 120 | #define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than this value | 120 | #define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is more than this value |
| 121 | * then the frame is Ethernet II. Else it is 802.3 */ | 121 | * then the frame is Ethernet II. Else it is 802.3 */ |
| 122 | 122 | ||
| 123 | /* | 123 | /* |
| @@ -66,10 +66,17 @@ struct rlimit64 { · 65 unmodified lines | |||
| 66 | #define _STK_LIM (8*1024*1024) | 66 | #define _STK_LIM (8*1024*1024) |
| 67 | 67 | ||
| 68 | /* | 68 | /* |
| 69 | * GPG2 wants 64kB of mlocked memory, to make sure pass phrases | 69 | * Limit the amount of locked memory by some sane default: |
| 70 | * and other sensitive information are never written to disk. | 70 | * root can always increase this limit if needed. |
| 71 | * | ||
| 72 | * The main use-cases are (1) preventing sensitive memory | ||
| 73 | * from being swapped; (2) real-time operations; (3) via | ||
| 74 | * IOURING_REGISTER_BUFFERS. | ||
| 75 | * | ||
| 76 | * The first two don't need much. The latter will take as | ||
| 77 | * much as it can get. 8MB is a reasonably sane default. | ||
| 71 | */ | 78 | */ |
| 72 | #define MLOCK_LIMIT ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024) | 79 | #define MLOCK_LIMIT (8*1024*1024) |
| 73 | 80 | ||
| 74 | /* | 81 | /* |
| 75 | * Due to binary compatibility, the actual resource numbers | 82 | * Due to binary compatibility, the actual resource numbers |
| @@ -6346,11 +6346,6 @@ BTF_ID_LIST_GLOBAL_SINGLE(btf_task_struct_ids, struct, task_struct) · 6345 unmodified lines | |||
| 6346 | 6346 | ||
| 6347 | /* BTF ID set registration API for modules */ | 6347 | /* BTF ID set registration API for modules */ |
| 6348 | 6348 | ||
| 6349 | struct kfunc_btf_id_list { | ||
| 6350 | struct list_head list; | ||
| 6351 | struct mutex mutex; | ||
| 6352 | }; | ||
| 6353 | |||
| 6354 | #ifdef CONFIG_DEBUG_INFO_BTF_MODULES | 6349 | #ifdef CONFIG_DEBUG_INFO_BTF_MODULES |
| 6355 | 6350 | ||
| 6356 | void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l, | 6351 | void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l, |
| @@ -6376,8 +6371,6 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, · 19 unmodified lines | |||
| 6376 | { | 6371 | { |
| 6377 | struct kfunc_btf_id_set *s; | 6372 | struct kfunc_btf_id_set *s; |
| 6378 | 6373 | ||
| 6379 | if (!owner) | ||
| 6380 | return false; | ||
| 6381 | mutex_lock(&klist->mutex); | 6374 | mutex_lock(&klist->mutex); |
| 6382 | list_for_each_entry(s, &klist->list, list) { | 6375 | list_for_each_entry(s, &klist->list, list) { |
| 6383 | if (s->owner == owner && btf_id_set_contains(s->set, kfunc_id)) { | 6376 | if (s->owner == owner && btf_id_set_contains(s->set, kfunc_id)) { |
| @@ -6389,8 +6382,6 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, · 5 unmodified lines | |||
| 6389 | return false; | 6382 | return false; |
| 6390 | } | 6383 | } |
| 6391 | 6384 | ||
| 6392 | #endif | ||
| 6393 | |||
| 6394 | #define DEFINE_KFUNC_BTF_ID_LIST(name) \ | 6385 | #define DEFINE_KFUNC_BTF_ID_LIST(name) \ |
| 6395 | struct kfunc_btf_id_list name = { LIST_HEAD_INIT(name.list), \ | 6386 | struct kfunc_btf_id_list name = { LIST_HEAD_INIT(name.list), \ |
| 6396 | __MUTEX_INITIALIZER(name.mutex) }; \ | 6387 | __MUTEX_INITIALIZER(name.mutex) }; \ |
| @@ -6398,3 +6389,5 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, · 1 unmodified line | |||
| 6398 | 6389 | ||
| 6399 | DEFINE_KFUNC_BTF_ID_LIST(bpf_tcp_ca_kfunc_list); | 6390 | DEFINE_KFUNC_BTF_ID_LIST(bpf_tcp_ca_kfunc_list); |
| 6400 | DEFINE_KFUNC_BTF_ID_LIST(prog_test_kfunc_list); | 6391 | DEFINE_KFUNC_BTF_ID_LIST(prog_test_kfunc_list); |
| 6392 | |||
| 6393 | #endif | ||
| @@ -8422,7 +8422,7 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, · 8421 unmodified lines | |||
| 8422 | 8422 | ||
| 8423 | new_range = dst_reg->off; | 8423 | new_range = dst_reg->off; |
| 8424 | if (range_right_open) | 8424 | if (range_right_open) |
| 8425 | new_range--; | 8425 | new_range++; |
| 8426 | 8426 | ||
| 8427 | /* Examples for register markings: | 8427 | /* Examples for register markings: |
| 8428 | * | 8428 | * |
| @@ -2086,6 +2086,9 @@ int register_kretprobe(struct kretprobe *rp) · 2085 unmodified lines | |||
| 2086 | } | 2086 | } |
| 2087 | } | 2087 | } |
| 2088 | 2088 | ||
| 2089 | if (rp->data_size > KRETPROBE_MAX_DATA_SIZE) | ||
| 2090 | return -E2BIG; | ||
| 2091 | |||
| 2089 | rp->kp.pre_handler = pre_handler_kretprobe; | 2092 | rp->kp.pre_handler = pre_handler_kretprobe; |
| 2090 | rp->kp.post_handler = NULL; | 2093 | rp->kp.post_handler = NULL; |
| 2091 | 2094 | ||
| @@ -1918,7 +1918,7 @@ static void __init init_uclamp_rq(struct rq *rq) · 1917 unmodified lines | |||
| 1918 | }; | 1918 | }; |
| 1919 | } | 1919 | } |
| 1920 | 1920 | ||
| 1921 | rq->uclamp_flags = 0; | 1921 | rq->uclamp_flags = UCLAMP_FLAG_IDLE; |
| 1922 | } | 1922 | } |
| 1923 | 1923 | ||
| 1924 | static void __init init_uclamp(void) | 1924 | static void __init init_uclamp(void) |
| @@ -6617,11 +6617,11 @@ static int __init setup_preempt_mode(char *str) · 4692 unmodified lines | |||
| 6617 | int mode = sched_dynamic_mode(str); | 6617 | int mode = sched_dynamic_mode(str); |
| 6618 | if (mode < 0) { | 6618 | if (mode < 0) { |
| 6619 | pr_warn("Dynamic Preempt: unsupported mode: %s\n", str); | 6619 | pr_warn("Dynamic Preempt: unsupported mode: %s\n", str); |
| 6620 | return 1; | 6620 | return 0; |
| 6621 | } | 6621 | } |
| 6622 | 6622 | ||
| 6623 | sched_dynamic_update(mode); | 6623 | sched_dynamic_update(mode); |
| 6624 | return 0; | 6624 | return 1; |
| 6625 | } | 6625 | } |
| 6626 | __setup("preempt=", setup_preempt_mode); | 6626 | __setup("preempt=", setup_preempt_mode); |
| 6627 | 6627 | ||
| @@ -615,7 +615,8 @@ void task_cputime_adjusted(struct task_struct *p, u64 *ut, u64 *st) · 614 unmodified lines | |||
| 615 | .sum_exec_runtime = p->se.sum_exec_runtime, | 615 | .sum_exec_runtime = p->se.sum_exec_runtime, |
| 616 | }; | 616 | }; |
| 617 | 617 | ||
| 618 | task_cputime(p, &cputime.utime, &cputime.stime); | 618 | if (task_cputime(p, &cputime.utime, &cputime.stime)) |
| 619 | cputime.sum_exec_runtime = task_sched_runtime(p); | ||
| 619 | cputime_adjust(&cputime, &p->prev_cputime, ut, st); | 620 | cputime_adjust(&cputime, &p->prev_cputime, ut, st); |
| 620 | } | 621 | } |
| 621 | EXPORT_SYMBOL_GPL(task_cputime_adjusted); | 622 | EXPORT_SYMBOL_GPL(task_cputime_adjusted); |
| @@ -828,19 +829,21 @@ u64 task_gtime(struct task_struct *t) · 206 unmodified lines | |||
| 828 | * add up the pending nohz execution time since the last | 829 | * add up the pending nohz execution time since the last |
| 829 | * cputime snapshot. | 830 | * cputime snapshot. |
| 830 | */ | 831 | */ |
| 831 | void task_cputime(struct task_struct *t, u64 *utime, u64 *stime) | 832 | bool task_cputime(struct task_struct *t, u64 *utime, u64 *stime) |
| 832 | { | 833 | { |
| 833 | struct vtime *vtime = &t->vtime; | 834 | struct vtime *vtime = &t->vtime; |
| 834 | unsigned int seq; | 835 | unsigned int seq; |
| 835 | u64 delta; | 836 | u64 delta; |
| 837 | int ret; | ||
| 836 | 838 | ||
| 837 | if (!vtime_accounting_enabled()) { | 839 | if (!vtime_accounting_enabled()) { |
| 838 | *utime = t->utime; | 840 | *utime = t->utime; |
| 839 | *stime = t->stime; | 841 | *stime = t->stime; |
| 840 | return; | 842 | return false; |
| 841 | } | 843 | } |
| 842 | 844 | ||
| 843 | do { | 845 | do { |
| 846 | ret = false; | ||
| 844 | seq = read_seqcount_begin(&vtime->seqcount); | 847 | seq = read_seqcount_begin(&vtime->seqcount); |
| 845 | 848 | ||
| 846 | *utime = t->utime; | 849 | *utime = t->utime; |
| @@ -850,6 +853,7 @@ void task_cputime(struct task_struct *t, u64 *utime, u64 *stime) · 3 unmodified lines | |||
| 850 | if (vtime->state < VTIME_SYS) | 853 | if (vtime->state < VTIME_SYS) |
| 851 | continue; | 854 | continue; |
| 852 | 855 | ||
| 856 | ret = true; | ||
| 853 | delta = vtime_delta(vtime); | 857 | delta = vtime_delta(vtime); |
| 854 | 858 | ||
| 855 | /* | 859 | /* |
| @@ -861,6 +865,8 @@ void task_cputime(struct task_struct *t, u64 *utime, u64 *stime) · 5 unmodified lines | |||
| 861 | else | 865 | else |
| 862 | *utime += vtime->utime + delta; | 866 | *utime += vtime->utime + delta; |
| 863 | } while (read_seqcount_retry(&vtime->seqcount, seq)); | 867 | } while (read_seqcount_retry(&vtime->seqcount, seq)); |
| 868 | |||
| 869 | return ret; | ||
| 864 | } | 870 | } |
| 865 | 871 | ||
| 866 | static int vtime_state_fetch(struct vtime *vtime, int cpu) | 872 | static int vtime_state_fetch(struct vtime *vtime, int cpu) |
| @@ -238,6 +238,13 @@ void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode) · 237 unmodified lines | |||
| 238 | } | 238 | } |
| 239 | EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */ | 239 | EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */ |
| 240 | 240 | ||
| 241 | void __wake_up_pollfree(struct wait_queue_head *wq_head) | ||
| 242 | { | ||
| 243 | __wake_up(wq_head, TASK_NORMAL, 0, poll_to_key(EPOLLHUP | POLLFREE)); | ||
| 244 | /* POLLFREE must have cleared the queue. */ | ||
| 245 | WARN_ON_ONCE(waitqueue_active(wq_head)); | ||
| 246 | } | ||
| 247 | |||
| 241 | /* | 248 | /* |
| 242 | * Note: we use "set_current_state()" _after_ the wait-queue add, | 249 | * Note: we use "set_current_state()" _after_ the wait-queue add, |
| 243 | * because we need a memory barrier there on SMP, so that any | 250 | * because we need a memory barrier there on SMP, so that any |
| @@ -595,7 +595,8 @@ void irq_enter_rcu(void) · 594 unmodified lines | |||
| 595 | { | 595 | { |
| 596 | __irq_enter_raw(); | 596 | __irq_enter_raw(); |
| 597 | 597 | ||
| 598 | if (is_idle_task(current) && (irq_count() == HARDIRQ_OFFSET)) | 598 | if (tick_nohz_full_cpu(smp_processor_id()) || |
| 599 | (is_idle_task(current) && (irq_count() == HARDIRQ_OFFSET))) | ||
| 599 | tick_irq_enter(); | 600 | tick_irq_enter(); |
| 600 | 601 | ||
| 601 | account_hardirq_enter(current); | 602 | account_hardirq_enter(current); |
| @@ -1375,6 +1375,13 @@ static inline void tick_nohz_irq_enter(void) · 1374 unmodified lines | |||
| 1375 | now = ktime_get(); | 1375 | now = ktime_get(); |
| 1376 | if (ts->idle_active) | 1376 | if (ts->idle_active) |
| 1377 | tick_nohz_stop_idle(ts, now); | 1377 | tick_nohz_stop_idle(ts, now); |
| 1378 | /* | ||
| 1379 | * If all CPUs are idle. We may need to update a stale jiffies value. | ||
| 1380 | * Note nohz_full is a special case: a timekeeper is guaranteed to stay | ||
| 1381 | * alive but it might be busy looping with interrupts disabled in some | ||
| 1382 | * rare case (typically stop machine). So we must make sure we have a | ||
| 1383 | * last resort. | ||
| 1384 | */ | ||
| 1378 | if (ts->tick_stopped) | 1385 | if (ts->tick_stopped) |
| 1379 | tick_nohz_update_jiffies(now); | 1386 | tick_nohz_update_jiffies(now); |
| 1380 | } | 1387 | } |
| @@ -2054,26 +2054,28 @@ unsigned long msleep_interruptible(unsigned int msecs) · 2053 unmodified lines | |||
| 2054 | EXPORT_SYMBOL(msleep_interruptible); | 2054 | EXPORT_SYMBOL(msleep_interruptible); |
| 2055 | 2055 | ||
| 2056 | /** | 2056 | /** |
| 2057 | * usleep_range - Sleep for an approximate time | 2057 | * usleep_range_state - Sleep for an approximate time in a given state |
| 2058 | * @min: Minimum time in usecs to sleep | 2058 | * @min: Minimum time in usecs to sleep |
| 2059 | * @max: Maximum time in usecs to sleep | 2059 | * @max: Maximum time in usecs to sleep |
| 2060 | * @state: State of the current task that will be while sleeping | ||
| 2060 | * | 2061 | * |
| 2061 | * In non-atomic context where the exact wakeup time is flexible, use | 2062 | * In non-atomic context where the exact wakeup time is flexible, use |
| 2062 | * usleep_range() instead of udelay(). The sleep improves responsiveness | 2063 | * usleep_range_state() instead of udelay(). The sleep improves responsiveness |
| 2063 | * by avoiding the CPU-hogging busy-wait of udelay(), and the range reduces | 2064 | * by avoiding the CPU-hogging busy-wait of udelay(), and the range reduces |
| 2064 | * power usage by allowing hrtimers to take advantage of an already- | 2065 | * power usage by allowing hrtimers to take advantage of an already- |
| 2065 | * scheduled interrupt instead of scheduling a new one just for this sleep. | 2066 | * scheduled interrupt instead of scheduling a new one just for this sleep. |
| 2066 | */ | 2067 | */ |
| 2067 | void __sched usleep_range(unsigned long min, unsigned long max) | 2068 | void __sched usleep_range_state(unsigned long min, unsigned long max, |
| 2069 | unsigned int state) | ||
| 2068 | { | 2070 | { |
| 2069 | ktime_t exp = ktime_add_us(ktime_get(), min); | 2071 | ktime_t exp = ktime_add_us(ktime_get(), min); |
| 2070 | u64 delta = (u64)(max - min) * NSEC_PER_USEC; | 2072 | u64 delta = (u64)(max - min) * NSEC_PER_USEC; |
| 2071 | 2073 | ||
| 2072 | for (;;) { | 2074 | for (;;) { |
| 2073 | __set_current_state(TASK_UNINTERRUPTIBLE); | 2075 | __set_current_state(state); |
| 2074 | /* Do not return before the requested sleep time has elapsed */ | 2076 | /* Do not return before the requested sleep time has elapsed */ |
| 2075 | if (!schedule_hrtimeout_range(&exp, delta, HRTIMER_MODE_ABS)) | 2077 | if (!schedule_hrtimeout_range(&exp, delta, HRTIMER_MODE_ABS)) |
| 2076 | break; | 2078 | break; |
| 2077 | } | 2079 | } |
| 2078 | } | 2080 | } |
| 2079 | EXPORT_SYMBOL(usleep_range); | 2081 | EXPORT_SYMBOL(usleep_range_state); |
| @@ -5217,6 +5217,7 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr) · 5216 unmodified lines | |||
| 5217 | { | 5217 | { |
| 5218 | struct ftrace_direct_func *direct; | 5218 | struct ftrace_direct_func *direct; |
| 5219 | struct ftrace_func_entry *entry; | 5219 | struct ftrace_func_entry *entry; |
| 5220 | struct ftrace_hash *hash; | ||
| 5220 | int ret = -ENODEV; | 5221 | int ret = -ENODEV; |
| 5221 | 5222 | ||
| 5222 | mutex_lock(&direct_mutex); | 5223 | mutex_lock(&direct_mutex); |
| @@ -5225,7 +5226,8 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr) · 2 unmodified lines | |||
| 5225 | if (!entry) | 5226 | if (!entry) |
| 5226 | goto out_unlock; | 5227 | goto out_unlock; |
| 5227 | 5228 | ||
| 5228 | if (direct_functions->count == 1) | 5229 | hash = direct_ops.func_hash->filter_hash; |
| 5230 | if (hash->count == 1) | ||
| 5229 | unregister_ftrace_function(&direct_ops); | 5231 | unregister_ftrace_function(&direct_ops); |
| 5230 | 5232 | ||
| 5231 | ret = ftrace_set_filter_ip(&direct_ops, ip, 1, 0); | 5233 | ret = ftrace_set_filter_ip(&direct_ops, ip, 1, 0); |
| @@ -5540,6 +5542,10 @@ int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr) · 308 unmodified lines | |||
| 5540 | err = unregister_ftrace_function(ops); | 5542 | err = unregister_ftrace_function(ops); |
| 5541 | remove_direct_functions_hash(hash, addr); | 5543 | remove_direct_functions_hash(hash, addr); |
| 5542 | mutex_unlock(&direct_mutex); | 5544 | mutex_unlock(&direct_mutex); |
| 5545 | |||
| 5546 | /* cleanup for possible another register call */ | ||
| 5547 | ops->func = NULL; | ||
| 5548 | ops->trampoline = 0; | ||
| 5543 | return err; | 5549 | return err; |
| 5544 | } | 5550 | } |
| 5545 | EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi); | 5551 | EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi); |
| @@ -3757,7 +3757,7 @@ static int check_synth_field(struct synth_event *event, · 3756 unmodified lines | |||
| 3757 | 3757 | ||
| 3758 | if (strcmp(field->type, hist_field->type) != 0) { | 3758 | if (strcmp(field->type, hist_field->type) != 0) { |
| 3759 | if (field->size != hist_field->size || | 3759 | if (field->size != hist_field->size || |
| 3760 | field->is_signed != hist_field->is_signed) | 3760 | (!field->is_string && field->is_signed != hist_field->is_signed)) |
| 3761 | return -EINVAL; | 3761 | return -EINVAL; |
| 3762 | } | 3762 | } |
| 3763 | 3763 | ||
| @@ -1237,9 +1237,8 @@ static int __create_synth_event(const char *name, const char *raw_fields) · 1236 unmodified lines | |||
| 1237 | argv + consumed, &consumed, | 1237 | argv + consumed, &consumed, |
| 1238 | &field_version); | 1238 | &field_version); |
| 1239 | if (IS_ERR(field)) { | 1239 | if (IS_ERR(field)) { |
| 1240 | argv_free(argv); | ||
| 1241 | ret = PTR_ERR(field); | 1240 | ret = PTR_ERR(field); |
| 1242 | goto err; | 1241 | goto err_free_arg; |
| 1243 | } | 1242 | } |
| 1244 | 1243 | ||
| 1245 | /* | 1244 | /* |
| @@ -1262,18 +1261,19 @@ static int __create_synth_event(const char *name, const char *raw_fields) · 16 unmodified lines | |||
| 1262 | if (cmd_version > 1 && n_fields_this_loop >= 1) { | 1261 | if (cmd_version > 1 && n_fields_this_loop >= 1) { |
| 1263 | synth_err(SYNTH_ERR_INVALID_CMD, errpos(field_str)); | 1262 | synth_err(SYNTH_ERR_INVALID_CMD, errpos(field_str)); |
| 1264 | ret = -EINVAL; | 1263 | ret = -EINVAL; |
| 1265 | goto err; | 1264 | goto err_free_arg; |
| 1266 | } | 1265 | } |
| 1267 | 1266 | ||
| 1268 | fields[n_fields++] = field; | 1267 | fields[n_fields++] = field; |
| 1269 | if (n_fields == SYNTH_FIELDS_MAX) { | 1268 | if (n_fields == SYNTH_FIELDS_MAX) { |
| 1270 | synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0); | 1269 | synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0); |
| 1271 | ret = -EINVAL; | 1270 | ret = -EINVAL; |
| 1272 | goto err; | 1271 | goto err_free_arg; |
| 1273 | } | 1272 | } |
| 1274 | 1273 | ||
| 1275 | n_fields_this_loop++; | 1274 | n_fields_this_loop++; |
| 1276 | } | 1275 | } |
| 1276 | argv_free(argv); | ||
| 1277 | 1277 | ||
| 1278 | if (consumed < argc) { | 1278 | if (consumed < argc) { |
| 1279 | synth_err(SYNTH_ERR_INVALID_CMD, 0); | 1279 | synth_err(SYNTH_ERR_INVALID_CMD, 0); |
| @@ -1281,7 +1281,6 @@ static int __create_synth_event(const char *name, const char *raw_fields) · 1 unmodified line | |||
| 1281 | goto err; | 1281 | goto err; |
| 1282 | } | 1282 | } |
| 1283 | 1283 | ||
| 1284 | argv_free(argv); | ||
| 1285 | } | 1284 | } |
| 1286 | 1285 | ||
| 1287 | if (n_fields == 0) { | 1286 | if (n_fields == 0) { |
| @@ -1307,6 +1306,8 @@ static int __create_synth_event(const char *name, const char *raw_fields) · 19 unmodified lines | |||
| 1307 | kfree(saved_fields); | 1306 | kfree(saved_fields); |
| 1308 | 1307 | ||
| 1309 | return ret; | 1308 | return ret; |
| 1309 | err_free_arg: | ||
| 1310 | argv_free(argv); | ||
| 1310 | err: | 1311 | err: |
| 1311 | for (i = 0; i < n_fields; i++) | 1312 | for (i = 0; i < n_fields; i++) |
| 1312 | free_synth_field(fields[i]); | 1313 | free_synth_field(fields[i]); |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/jhash.h> | 15 | #include <linux/jhash.h> |
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | #include <linux/sort.h> | 17 | #include <linux/sort.h> |
| 18 | #include <linux/kmemleak.h> | ||
| 18 | 19 | ||
| 19 | #include "tracing_map.h" | 20 | #include "tracing_map.h" |
| 20 | #include "trace.h" | 21 | #include "trace.h" |
| @@ -307,6 +308,7 @@ static void tracing_map_array_free(struct tracing_map_array *a) · 286 unmodified lines | |||
| 307 | for (i = 0; i < a->n_pages; i++) { | 308 | for (i = 0; i < a->n_pages; i++) { |
| 308 | if (!a->pages[i]) | 309 | if (!a->pages[i]) |
| 309 | break; | 310 | break; |
| 311 | kmemleak_free(a->pages[i]); | ||
| 310 | free_page((unsigned long)a->pages[i]); | 312 | free_page((unsigned long)a->pages[i]); |
| 311 | } | 313 | } |
| 312 | 314 | ||
| @@ -342,6 +344,7 @@ static struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts, · 29 unmodified lines | |||
| 342 | a->pages[i] = (void *)get_zeroed_page(GFP_KERNEL); | 344 | a->pages[i] = (void *)get_zeroed_page(GFP_KERNEL); |
| 343 | if (!a->pages[i]) | 345 | if (!a->pages[i]) |
| 344 | goto free; | 346 | goto free; |
| 347 | kmemleak_alloc(a->pages[i], PAGE_SIZE, 1, GFP_KERNEL); | ||
| 345 | } | 348 | } |
| 346 | out: | 349 | out: |
| 347 | return a; | 350 | return a; |
| @@ -316,6 +316,7 @@ config DEBUG_INFO_BTF · 315 unmodified lines | |||
| 316 | bool "Generate BTF typeinfo" | 316 | bool "Generate BTF typeinfo" |
| 317 | depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED | 317 | depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED |
| 318 | depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST | 318 | depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST |
| 319 | depends on BPF_SYSCALL | ||
| 319 | help | 320 | help |
| 320 | Generate deduplicated BTF type information from DWARF debug info. | 321 | Generate deduplicated BTF type information from DWARF debug info. |
| 321 | Turning this on expects presence of pahole tool, which will convert | 322 | Turning this on expects presence of pahole tool, which will convert |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | SIPROUND; \ | 49 | SIPROUND; \ |
| 50 | return (v0 ^ v1) ^ (v2 ^ v3); | 50 | return (v0 ^ v1) ^ (v2 ^ v3); |
| 51 | 51 | ||
| 52 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 52 | u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key) | 53 | u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key) |
| 53 | { | 54 | { |
| 54 | const u8 *end = data + len - (len % sizeof(u64)); | 55 | const u8 *end = data + len - (len % sizeof(u64)); |
| @@ -80,8 +81,8 @@ u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key) · 25 unmodified lines | |||
| 80 | POSTAMBLE | 81 | POSTAMBLE |
| 81 | } | 82 | } |
| 82 | EXPORT_SYMBOL(__siphash_aligned); | 83 | EXPORT_SYMBOL(__siphash_aligned); |
| 84 | #endif | ||
| 83 | 85 | ||
| 84 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 85 | u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key) | 86 | u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key) |
| 86 | { | 87 | { |
| 87 | const u8 *end = data + len - (len % sizeof(u64)); | 88 | const u8 *end = data + len - (len % sizeof(u64)); |
| @@ -113,7 +114,6 @@ u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key) · 25 unmodified lines | |||
| 113 | POSTAMBLE | 114 | POSTAMBLE |
| 114 | } | 115 | } |
| 115 | EXPORT_SYMBOL(__siphash_unaligned); | 116 | EXPORT_SYMBOL(__siphash_unaligned); |
| 116 | #endif | ||
| 117 | 117 | ||
| 118 | /** | 118 | /** |
| 119 | * siphash_1u64 - compute 64-bit siphash PRF value of a u64 | 119 | * siphash_1u64 - compute 64-bit siphash PRF value of a u64 |
| @@ -250,6 +250,7 @@ EXPORT_SYMBOL(siphash_3u32); · 130 unmodified lines | |||
| 250 | HSIPROUND; \ | 250 | HSIPROUND; \ |
| 251 | return (v0 ^ v1) ^ (v2 ^ v3); | 251 | return (v0 ^ v1) ^ (v2 ^ v3); |
| 252 | 252 | ||
| 253 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 253 | u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key) | 254 | u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key) |
| 254 | { | 255 | { |
| 255 | const u8 *end = data + len - (len % sizeof(u64)); | 256 | const u8 *end = data + len - (len % sizeof(u64)); |
| @@ -280,8 +281,8 @@ u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key) · 24 unmodified lines | |||
| 280 | HPOSTAMBLE | 281 | HPOSTAMBLE |
| 281 | } | 282 | } |
| 282 | EXPORT_SYMBOL(__hsiphash_aligned); | 283 | EXPORT_SYMBOL(__hsiphash_aligned); |
| 284 | #endif | ||
| 283 | 285 | ||
| 284 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 285 | u32 __hsiphash_unaligned(const void *data, size_t len, | 286 | u32 __hsiphash_unaligned(const void *data, size_t len, |
| 286 | const hsiphash_key_t *key) | 287 | const hsiphash_key_t *key) |
| 287 | { | 288 | { |
| @@ -313,7 +314,6 @@ u32 __hsiphash_unaligned(const void *data, size_t len, · 25 unmodified lines | |||
| 313 | HPOSTAMBLE | 314 | HPOSTAMBLE |
| 314 | } | 315 | } |
| 315 | EXPORT_SYMBOL(__hsiphash_unaligned); | 316 | EXPORT_SYMBOL(__hsiphash_unaligned); |
| 316 | #endif | ||
| 317 | 317 | ||
| 318 | /** | 318 | /** |
| 319 | * hsiphash_1u32 - compute 64-bit hsiphash PRF value of a u32 | 319 | * hsiphash_1u32 - compute 64-bit hsiphash PRF value of a u32 |
| @@ -418,6 +418,7 @@ EXPORT_SYMBOL(hsiphash_4u32); · 98 unmodified lines | |||
| 418 | HSIPROUND; \ | 418 | HSIPROUND; \ |
| 419 | return v1 ^ v3; | 419 | return v1 ^ v3; |
| 420 | 420 | ||
| 421 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 421 | u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key) | 422 | u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key) |
| 422 | { | 423 | { |
| 423 | const u8 *end = data + len - (len % sizeof(u32)); | 424 | const u8 *end = data + len - (len % sizeof(u32)); |
| @@ -438,8 +439,8 @@ u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key) · 14 unmodified lines | |||
| 438 | HPOSTAMBLE | 439 | HPOSTAMBLE |
| 439 | } | 440 | } |
| 440 | EXPORT_SYMBOL(__hsiphash_aligned); | 441 | EXPORT_SYMBOL(__hsiphash_aligned); |
| 442 | #endif | ||
| 441 | 443 | ||
| 442 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
| 443 | u32 __hsiphash_unaligned(const void *data, size_t len, | 444 | u32 __hsiphash_unaligned(const void *data, size_t len, |
| 444 | const hsiphash_key_t *key) | 445 | const hsiphash_key_t *key) |
| 445 | { | 446 | { |
| @@ -461,7 +462,6 @@ u32 __hsiphash_unaligned(const void *data, size_t len, · 15 unmodified lines | |||
| 461 | HPOSTAMBLE | 462 | HPOSTAMBLE |
| 462 | } | 463 | } |
| 463 | EXPORT_SYMBOL(__hsiphash_unaligned); | 464 | EXPORT_SYMBOL(__hsiphash_unaligned); |
| 464 | #endif | ||
| 465 | 465 | ||
| 466 | /** | 466 | /** |
| 467 | * hsiphash_1u32 - compute 32-bit hsiphash PRF value of a u32 | 467 | * hsiphash_1u32 - compute 32-bit hsiphash PRF value of a u32 |
| @@ -428,7 +428,7 @@ config THP_SWAP · 427 unmodified lines | |||
| 428 | # UP and nommu archs use km based percpu allocator | 428 | # UP and nommu archs use km based percpu allocator |
| 429 | # | 429 | # |
| 430 | config NEED_PER_CPU_KM | 430 | config NEED_PER_CPU_KM |
| 431 | depends on !SMP | 431 | depends on !SMP || !MMU |
| 432 | bool | 432 | bool |
| 433 | default y | 433 | default y |
| 434 | 434 | ||
| @@ -945,6 +945,13 @@ void bdi_unregister(struct backing_dev_info *bdi) · 944 unmodified lines | |||
| 945 | wb_shutdown(&bdi->wb); | 945 | wb_shutdown(&bdi->wb); |
| 946 | cgwb_bdi_unregister(bdi); | 946 | cgwb_bdi_unregister(bdi); |
| 947 | 947 | ||
| 948 | /* | ||
| 949 | * If this BDI's min ratio has been set, use bdi_set_min_ratio() to | ||
| 950 | * update the global bdi_min_ratio. | ||
| 951 | */ | ||
| 952 | if (bdi->min_ratio) | ||
| 953 | bdi_set_min_ratio(bdi, 0); | ||
| 954 | |||
| 948 | if (bdi->dev) { | 955 | if (bdi->dev) { |
| 949 | bdi_debug_unregister(bdi); | 956 | bdi_debug_unregister(bdi); |
| 950 | device_unregister(bdi->dev); | 957 | device_unregister(bdi->dev); |
| @@ -282,7 +282,6 @@ int damon_set_targets(struct damon_ctx *ctx, · 281 unmodified lines | |||
| 282 | for (i = 0; i < nr_ids; i++) { | 282 | for (i = 0; i < nr_ids; i++) { |
| 283 | t = damon_new_target(ids[i]); | 283 | t = damon_new_target(ids[i]); |
| 284 | if (!t) { | 284 | if (!t) { |
| 285 | pr_err("Failed to alloc damon_target\n"); | ||
| 286 | /* The caller should do cleanup of the ids itself */ | 285 | /* The caller should do cleanup of the ids itself */ |
| 287 | damon_for_each_target_safe(t, next, ctx) | 286 | damon_for_each_target_safe(t, next, ctx) |
| 288 | damon_destroy_target(t); | 287 | damon_destroy_target(t); |
| @@ -312,16 +311,10 @@ int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int, · 23 unmodified lines | |||
| 312 | unsigned long aggr_int, unsigned long primitive_upd_int, | 311 | unsigned long aggr_int, unsigned long primitive_upd_int, |
| 313 | unsigned long min_nr_reg, unsigned long max_nr_reg) | 312 | unsigned long min_nr_reg, unsigned long max_nr_reg) |
| 314 | { | 313 | { |
| 315 | if (min_nr_reg < 3) { | 314 | if (min_nr_reg < 3) |
| 316 | pr_err("min_nr_regions (%lu) must be at least 3\n", | ||
| 317 | min_nr_reg); | ||
| 318 | return -EINVAL; | 315 | return -EINVAL; |
| 319 | } | 316 | if (min_nr_reg > max_nr_reg) |
| 320 | if (min_nr_reg > max_nr_reg) { | ||
| 321 | pr_err("invalid nr_regions. min (%lu) > max (%lu)\n", | ||
| 322 | min_nr_reg, max_nr_reg); | ||
| 323 | return -EINVAL; | 317 | return -EINVAL; |
| 324 | } | ||
| 325 | 318 | ||
| 326 | ctx->sample_interval = sample_int; | 319 | ctx->sample_interval = sample_int; |
| 327 | ctx->aggr_interval = aggr_int; | 320 | ctx->aggr_interval = aggr_int; |
| @@ -980,10 +973,11 @@ static unsigned long damos_wmark_wait_us(struct damos *scheme) · 652 unmodified lines | |||
| 980 | 973 | ||
| 981 | static void kdamond_usleep(unsigned long usecs) | 974 | static void kdamond_usleep(unsigned long usecs) |
| 982 | { | 975 | { |
| 983 | if (usecs > 100 * 1000) | 976 | /* See Documentation/timers/timers-howto.rst for the thresholds */ |
| 984 | schedule_timeout_interruptible(usecs_to_jiffies(usecs)); | 977 | if (usecs > 20 * USEC_PER_MSEC) |
| 978 | schedule_timeout_idle(usecs_to_jiffies(usecs)); | ||
| 985 | else | 979 | else |
| 986 | usleep_range(usecs, usecs + 1); | 980 | usleep_idle_range(usecs, usecs + 1); |
| 987 | } | 981 | } |
| 988 | 982 | ||
| 989 | /* Returns negative error code if it's not activated but should return */ | 983 | /* Returns negative error code if it's not activated but should return */ |
| @@ -1038,7 +1032,7 @@ static int kdamond_fn(void *data) · 48 unmodified lines | |||
| 1038 | ctx->callback.after_sampling(ctx)) | 1032 | ctx->callback.after_sampling(ctx)) |
| 1039 | done = true; | 1033 | done = true; |
| 1040 | 1034 | ||
| 1041 | usleep_range(ctx->sample_interval, ctx->sample_interval + 1); | 1035 | kdamond_usleep(ctx->sample_interval); |
| 1042 | 1036 | ||
| 1043 | if (ctx->primitive.check_accesses) | 1037 | if (ctx->primitive.check_accesses) |
| 1044 | max_nr_accesses = ctx->primitive.check_accesses(ctx); | 1038 | max_nr_accesses = ctx->primitive.check_accesses(ctx); |
| @@ -210,10 +210,8 @@ static struct damos **str_to_schemes(const char *str, ssize_t len, · 209 unmodified lines | |||
| 210 | &wmarks.low, &parsed); | 210 | &wmarks.low, &parsed); |
| 211 | if (ret != 18) | 211 | if (ret != 18) |
| 212 | break; | 212 | break; |
| 213 | if (!damos_action_valid(action)) { | 213 | if (!damos_action_valid(action)) |
| 214 | pr_err("wrong action %d\n", action); | ||
| 215 | goto fail; | 214 | goto fail; |
| 216 | } | ||
| 217 | 215 | ||
| 218 | pos += parsed; | 216 | pos += parsed; |
| 219 | scheme = damon_new_scheme(min_sz, max_sz, min_nr_a, max_nr_a, | 217 | scheme = damon_new_scheme(min_sz, max_sz, min_nr_a, max_nr_a, |
| @@ -135,7 +135,6 @@ static void damon_do_test_apply_three_regions(struct kunit *test, · 134 unmodified lines | |||
| 135 | struct damon_addr_range *three_regions, | 135 | struct damon_addr_range *three_regions, |
| 136 | unsigned long *expected, int nr_expected) | 136 | unsigned long *expected, int nr_expected) |
| 137 | { | 137 | { |
| 138 | struct damon_ctx *ctx = damon_new_ctx(); | ||
| 139 | struct damon_target *t; | 138 | struct damon_target *t; |
| 140 | struct damon_region *r; | 139 | struct damon_region *r; |
| 141 | int i; | 140 | int i; |
| @@ -145,7 +144,6 @@ static void damon_do_test_apply_three_regions(struct kunit *test, · 3 unmodified lines | |||
| 145 | r = damon_new_region(regions[i * 2], regions[i * 2 + 1]); | 144 | r = damon_new_region(regions[i * 2], regions[i * 2 + 1]); |
| 146 | damon_add_region(r, t); | 145 | damon_add_region(r, t); |
| 147 | } | 146 | } |
| 148 | damon_add_target(ctx, t); | ||
| 149 | 147 | ||
| 150 | damon_va_apply_three_regions(t, three_regions); | 148 | damon_va_apply_three_regions(t, three_regions); |
| 151 | 149 | ||
| @@ -154,8 +152,6 @@ static void damon_do_test_apply_three_regions(struct kunit *test, · 2 unmodified lines | |||
| 154 | KUNIT_EXPECT_EQ(test, r->ar.start, expected[i * 2]); | 152 | KUNIT_EXPECT_EQ(test, r->ar.start, expected[i * 2]); |
| 155 | KUNIT_EXPECT_EQ(test, r->ar.end, expected[i * 2 + 1]); | 153 | KUNIT_EXPECT_EQ(test, r->ar.end, expected[i * 2 + 1]); |
| 156 | } | 154 | } |
| 157 | |||
| 158 | damon_destroy_ctx(ctx); | ||
| 159 | } | 155 | } |
| 160 | 156 | ||
| 161 | /* | 157 | /* |
| @@ -252,60 +248,59 @@ static void damon_test_apply_three_regions4(struct kunit *test) · 90 unmodified lines | |||
| 252 | new_three_regions, expected, ARRAY_SIZE(expected)); | 248 | new_three_regions, expected, ARRAY_SIZE(expected)); |
| 253 | } | 249 | } |
| 254 | 250 | ||
| 255 | static void damon_test_split_evenly(struct kunit *test) | 251 | static void damon_test_split_evenly_fail(struct kunit *test, |
| 252 | unsigned long start, unsigned long end, unsigned int nr_pieces) | ||
| 256 | { | 253 | { |
| 257 | struct damon_ctx *c = damon_new_ctx(); | 254 | struct damon_target *t = damon_new_target(42); |
| 258 | struct damon_target *t; | 255 | struct damon_region *r = damon_new_region(start, end); |
| 259 | struct damon_region *r; | ||
| 260 | unsigned long i; | ||
| 261 | |||
| 262 | KUNIT_EXPECT_EQ(test, damon_va_evenly_split_region(NULL, NULL, 5), | ||
| 263 | -EINVAL); | ||
| 264 | |||
| 265 | t = damon_new_target(42); | ||
| 266 | r = damon_new_region(0, 100); | ||
| 267 | KUNIT_EXPECT_EQ(test, damon_va_evenly_split_region(t, r, 0), -EINVAL); | ||
| 268 | 256 | ||
| 269 | damon_add_region(r, t); | 257 | damon_add_region(r, t); |
| 270 | KUNIT_EXPECT_EQ(test, damon_va_evenly_split_region(t, r, 10), 0); | 258 | KUNIT_EXPECT_EQ(test, |
| 271 | KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 10u); | 259 | damon_va_evenly_split_region(t, r, nr_pieces), -EINVAL); |
| 260 | KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1u); | ||
| 272 | 261 | ||
| 273 | i = 0; | ||
| 274 | damon_for_each_region(r, t) { | 262 | damon_for_each_region(r, t) { |
| 275 | KUNIT_EXPECT_EQ(test, r->ar.start, i++ * 10); | 263 | KUNIT_EXPECT_EQ(test, r->ar.start, start); |
| 276 | KUNIT_EXPECT_EQ(test, r->ar.end, i * 10); | 264 | KUNIT_EXPECT_EQ(test, r->ar.end, end); |
| 277 | } | 265 | } |
| 266 | |||
| 278 | damon_free_target(t); | 267 | damon_free_target(t); |
| 268 | } | ||
| 269 | |||
| 270 | static void damon_test_split_evenly_succ(struct kunit *test, | ||
| 271 | unsigned long start, unsigned long end, unsigned int nr_pieces) | ||
| 272 | { | ||
| 273 | struct damon_target *t = damon_new_target(42); | ||
| 274 | struct damon_region *r = damon_new_region(start, end); | ||
| 275 | unsigned long expected_width = (end - start) / nr_pieces; | ||
| 276 | unsigned long i = 0; | ||
| 279 | 277 | ||
| 280 | t = damon_new_target(42); | ||
| 281 | r = damon_new_region(5, 59); | ||
| 282 | damon_add_region(r, t); | 278 | damon_add_region(r, t); |
| 283 | KUNIT_EXPECT_EQ(test, damon_va_evenly_split_region(t, r, 5), 0); | 279 | KUNIT_EXPECT_EQ(test, |
| 284 | KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 5u); | 280 | damon_va_evenly_split_region(t, r, nr_pieces), 0); |
| 281 | KUNIT_EXPECT_EQ(test, damon_nr_regions(t), nr_pieces); | ||
| 285 | 282 | ||
| 286 | i = 0; | ||
| 287 | damon_for_each_region(r, t) { | 283 | damon_for_each_region(r, t) { |
| 288 | if (i == 4) | 284 | if (i == nr_pieces - 1) |
| 289 | break; | 285 | break; |
| 290 | KUNIT_EXPECT_EQ(test, r->ar.start, 5 + 10 * i++); | 286 | KUNIT_EXPECT_EQ(test, |
| 291 | KUNIT_EXPECT_EQ(test, r->ar.end, 5 + 10 * i); | 287 | r->ar.start, start + i++ * expected_width); |
| 288 | KUNIT_EXPECT_EQ(test, r->ar.end, start + i * expected_width); | ||
| 292 | } | 289 | } |
| 293 | KUNIT_EXPECT_EQ(test, r->ar.start, 5 + 10 * i); | 290 | KUNIT_EXPECT_EQ(test, r->ar.start, start + i * expected_width); |
| 294 | KUNIT_EXPECT_EQ(test, r->ar.end, 59ul); | 291 | KUNIT_EXPECT_EQ(test, r->ar.end, end); |
| 295 | damon_free_target(t); | 292 | damon_free_target(t); |
| 293 | } | ||
| 296 | 294 | ||
| 297 | t = damon_new_target(42); | 295 | static void damon_test_split_evenly(struct kunit *test) |
| 298 | r = damon_new_region(5, 6); | 296 | { |
| 299 | damon_add_region(r, t); | 297 | KUNIT_EXPECT_EQ(test, damon_va_evenly_split_region(NULL, NULL, 5), |
| 300 | KUNIT_EXPECT_EQ(test, damon_va_evenly_split_region(t, r, 2), -EINVAL); | 298 | -EINVAL); |
| 301 | KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1u); | ||
| 302 | 299 | ||
| 303 | damon_for_each_region(r, t) { | 300 | damon_test_split_evenly_fail(test, 0, 100, 0); |
| 304 | KUNIT_EXPECT_EQ(test, r->ar.start, 5ul); | 301 | damon_test_split_evenly_succ(test, 0, 100, 10); |
| 305 | KUNIT_EXPECT_EQ(test, r->ar.end, 6ul); | 302 | damon_test_split_evenly_succ(test, 5, 59, 5); |
| 306 | } | 303 | damon_test_split_evenly_fail(test, 5, 6, 2); |
| 307 | damon_free_target(t); | ||
| 308 | damon_destroy_ctx(c); | ||
| 309 | } | 304 | } |
| 310 | 305 | ||
| 311 | static struct kunit_case damon_test_cases[] = { | 306 | static struct kunit_case damon_test_cases[] = { |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/mmu_notifier.h> | 13 | #include <linux/mmu_notifier.h> |
| 14 | #include <linux/page_idle.h> | 14 | #include <linux/page_idle.h> |
| 15 | #include <linux/pagewalk.h> | 15 | #include <linux/pagewalk.h> |
| 16 | #include <linux/sched/mm.h> | ||
| 16 | 17 | ||
| 17 | #include "prmtv-common.h" | 18 | #include "prmtv-common.h" |
| 18 | 19 | ||
| @@ -626,7 +627,6 @@ int damon_va_apply_scheme(struct damon_ctx *ctx, struct damon_target *t, · 607 unmodified lines | |||
| 626 | case DAMOS_STAT: | 627 | case DAMOS_STAT: |
| 627 | return 0; | 628 | return 0; |
| 628 | default: | 629 | default: |
| 629 | pr_warn("Wrong action %d\n", scheme->action); | ||
| 630 | return -EINVAL; | 630 | return -EINVAL; |
| 631 | } | 631 | } |
| 632 | 632 | ||
| @@ -3253,8 +3253,6 @@ static struct page *next_uptodate_page(struct page *page, · 3252 unmodified lines | |||
| 3253 | goto skip; | 3253 | goto skip; |
| 3254 | if (!PageUptodate(page) || PageReadahead(page)) | 3254 | if (!PageUptodate(page) || PageReadahead(page)) |
| 3255 | goto skip; | 3255 | goto skip; |
| 3256 | if (PageHWPoison(page)) | ||
| 3257 | goto skip; | ||
| 3258 | if (!trylock_page(page)) | 3256 | if (!trylock_page(page)) |
| 3259 | goto skip; | 3257 | goto skip; |
| 3260 | if (page->mapping != mapping) | 3258 | if (page->mapping != mapping) |
| @@ -2973,7 +2973,7 @@ int __alloc_bootmem_huge_page(struct hstate *h, int nid) · 2972 unmodified lines | |||
| 2973 | struct huge_bootmem_page *m = NULL; /* initialize for clang */ | 2973 | struct huge_bootmem_page *m = NULL; /* initialize for clang */ |
| 2974 | int nr_nodes, node; | 2974 | int nr_nodes, node; |
| 2975 | 2975 | ||
| 2976 | if (nid >= nr_online_nodes) | 2976 | if (nid != NUMA_NO_NODE && nid >= nr_online_nodes) |
| 2977 | return 0; | 2977 | return 0; |
| 2978 | /* do node specific alloc */ | 2978 | /* do node specific alloc */ |
| 2979 | if (nid != NUMA_NO_NODE) { | 2979 | if (nid != NUMA_NO_NODE) { |
| @@ -776,24 +776,6 @@ void __mod_lruvec_kmem_state(void *p, enum node_stat_item idx, int val) · 775 unmodified lines | |||
| 776 | rcu_read_unlock(); | 776 | rcu_read_unlock(); |
| 777 | } | 777 | } |
| 778 | 778 | ||
| 779 | /* | ||
| 780 | * mod_objcg_mlstate() may be called with irq enabled, so | ||
| 781 | * mod_memcg_lruvec_state() should be used. | ||
| 782 | */ | ||
| 783 | static inline void mod_objcg_mlstate(struct obj_cgroup *objcg, | ||
| 784 | struct pglist_data *pgdat, | ||
| 785 | enum node_stat_item idx, int nr) | ||
| 786 | { | ||
| 787 | struct mem_cgroup *memcg; | ||
| 788 | struct lruvec *lruvec; | ||
| 789 | |||
| 790 | rcu_read_lock(); | ||
| 791 | memcg = obj_cgroup_memcg(objcg); | ||
| 792 | lruvec = mem_cgroup_lruvec(memcg, pgdat); | ||
| 793 | mod_memcg_lruvec_state(lruvec, idx, nr); | ||
| 794 | rcu_read_unlock(); | ||
| 795 | } | ||
| 796 | |||
| 797 | /** | 779 | /** |
| 798 | * __count_memcg_events - account VM events in a cgroup | 780 | * __count_memcg_events - account VM events in a cgroup |
| 799 | * @memcg: the memory cgroup | 781 | * @memcg: the memory cgroup |
| @@ -2137,41 +2119,6 @@ static bool obj_stock_flush_required(struct memcg_stock_pcp *stock, · 1337 unmodified lines | |||
| 2137 | } | 2119 | } |
| 2138 | #endif | 2120 | #endif |
| 2139 | 2121 | ||
| 2140 | /* | ||
| 2141 | * Most kmem_cache_alloc() calls are from user context. The irq disable/enable | ||
| 2142 | * sequence used in this case to access content from object stock is slow. | ||
| 2143 | * To optimize for user context access, there are now two object stocks for | ||
| 2144 | * task context and interrupt context access respectively. | ||
| 2145 | * | ||
| 2146 | * The task context object stock can be accessed by disabling preemption only | ||
| 2147 | * which is cheap in non-preempt kernel. The interrupt context object stock | ||
| 2148 | * can only be accessed after disabling interrupt. User context code can | ||
| 2149 | * access interrupt object stock, but not vice versa. | ||
| 2150 | */ | ||
| 2151 | static inline struct obj_stock *get_obj_stock(unsigned long *pflags) | ||
| 2152 | { | ||
| 2153 | struct memcg_stock_pcp *stock; | ||
| 2154 | |||
| 2155 | if (likely(in_task())) { | ||
| 2156 | *pflags = 0UL; | ||
| 2157 | preempt_disable(); | ||
| 2158 | stock = this_cpu_ptr(&memcg_stock); | ||
| 2159 | return &stock->task_obj; | ||
| 2160 | } | ||
| 2161 | |||
| 2162 | local_irq_save(*pflags); | ||
| 2163 | stock = this_cpu_ptr(&memcg_stock); | ||
| 2164 | return &stock->irq_obj; | ||
| 2165 | } | ||
| 2166 | |||
| 2167 | static inline void put_obj_stock(unsigned long flags) | ||
| 2168 | { | ||
| 2169 | if (likely(in_task())) | ||
| 2170 | preempt_enable(); | ||
| 2171 | else | ||
| 2172 | local_irq_restore(flags); | ||
| 2173 | } | ||
| 2174 | |||
| 2175 | /** | 2122 | /** |
| 2176 | * consume_stock: Try to consume stocked charge on this cpu. | 2123 | * consume_stock: Try to consume stocked charge on this cpu. |
| 2177 | * @memcg: memcg to consume from. | 2124 | * @memcg: memcg to consume from. |
| @@ -2816,6 +2763,59 @@ retry: · 638 unmodified lines | |||
| 2816 | */ | 2763 | */ |
| 2817 | #define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT) | 2764 | #define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT) |
| 2818 | 2765 | ||
| 2766 | /* | ||
| 2767 | * Most kmem_cache_alloc() calls are from user context. The irq disable/enable | ||
| 2768 | * sequence used in this case to access content from object stock is slow. | ||
| 2769 | * To optimize for user context access, there are now two object stocks for | ||
| 2770 | * task context and interrupt context access respectively. | ||
| 2771 | * | ||
| 2772 | * The task context object stock can be accessed by disabling preemption only | ||
| 2773 | * which is cheap in non-preempt kernel. The interrupt context object stock | ||
| 2774 | * can only be accessed after disabling interrupt. User context code can | ||
| 2775 | * access interrupt object stock, but not vice versa. | ||
| 2776 | */ | ||
| 2777 | static inline struct obj_stock *get_obj_stock(unsigned long *pflags) | ||
| 2778 | { | ||
| 2779 | struct memcg_stock_pcp *stock; | ||
| 2780 | |||
| 2781 | if (likely(in_task())) { | ||
| 2782 | *pflags = 0UL; | ||
| 2783 | preempt_disable(); | ||
| 2784 | stock = this_cpu_ptr(&memcg_stock); | ||
| 2785 | return &stock->task_obj; | ||
| 2786 | } | ||
| 2787 | |||
| 2788 | local_irq_save(*pflags); | ||
| 2789 | stock = this_cpu_ptr(&memcg_stock); | ||
| 2790 | return &stock->irq_obj; | ||
| 2791 | } | ||
| 2792 | |||
| 2793 | static inline void put_obj_stock(unsigned long flags) | ||
| 2794 | { | ||
| 2795 | if (likely(in_task())) | ||
| 2796 | preempt_enable(); | ||
| 2797 | else | ||
| 2798 | local_irq_restore(flags); | ||
| 2799 | } | ||
| 2800 | |||
| 2801 | /* | ||
| 2802 | * mod_objcg_mlstate() may be called with irq enabled, so | ||
| 2803 | * mod_memcg_lruvec_state() should be used. | ||
| 2804 | */ | ||
| 2805 | static inline void mod_objcg_mlstate(struct obj_cgroup *objcg, | ||
| 2806 | struct pglist_data *pgdat, | ||
| 2807 | enum node_stat_item idx, int nr) | ||
| 2808 | { | ||
| 2809 | struct mem_cgroup *memcg; | ||
| 2810 | struct lruvec *lruvec; | ||
| 2811 | |||
| 2812 | rcu_read_lock(); | ||
| 2813 | memcg = obj_cgroup_memcg(objcg); | ||
| 2814 | lruvec = mem_cgroup_lruvec(memcg, pgdat); | ||
| 2815 | mod_memcg_lruvec_state(lruvec, idx, nr); | ||
| 2816 | rcu_read_unlock(); | ||
| 2817 | } | ||
| 2818 | |||
| 2819 | int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s, | 2819 | int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s, |
| 2820 | gfp_t gfp, bool new_page) | 2820 | gfp_t gfp, bool new_page) |
| 2821 | { | 2821 | { |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include <linux/memblock.h> | 35 | #include <linux/memblock.h> |
| 36 | #include <linux/compaction.h> | 36 | #include <linux/compaction.h> |
| 37 | #include <linux/rmap.h> | 37 | #include <linux/rmap.h> |
| 38 | #include <linux/module.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/tlbflush.h> | 40 | #include <asm/tlbflush.h> |
| 40 | 41 | ||
| @@ -5081,6 +5081,7 @@ struct loc_track { · 5080 unmodified lines | |||
| 5081 | unsigned long max; | 5081 | unsigned long max; |
| 5082 | unsigned long count; | 5082 | unsigned long count; |
| 5083 | struct location *loc; | 5083 | struct location *loc; |
| 5084 | loff_t idx; | ||
| 5084 | }; | 5085 | }; |
| 5085 | 5086 | ||
| 5086 | static struct dentry *slab_debugfs_root; | 5087 | static struct dentry *slab_debugfs_root; |
| @@ -6052,11 +6053,11 @@ __initcall(slab_sysfs_init); · 965 unmodified lines | |||
| 6052 | #if defined(CONFIG_SLUB_DEBUG) && defined(CONFIG_DEBUG_FS) | 6053 | #if defined(CONFIG_SLUB_DEBUG) && defined(CONFIG_DEBUG_FS) |
| 6053 | static int slab_debugfs_show(struct seq_file *seq, void *v) | 6054 | static int slab_debugfs_show(struct seq_file *seq, void *v) |
| 6054 | { | 6055 | { |
| 6055 | |||
| 6056 | struct location *l; | ||
| 6057 | unsigned int idx = *(unsigned int *)v; | ||
| 6058 | struct loc_track *t = seq->private; | 6056 | struct loc_track *t = seq->private; |
| 6057 | struct location *l; | ||
| 6058 | unsigned long idx; | ||
| 6059 | 6059 | ||
| 6060 | idx = (unsigned long) t->idx; | ||
| 6060 | if (idx < t->count) { | 6061 | if (idx < t->count) { |
| 6061 | l = &t->loc[idx]; | 6062 | l = &t->loc[idx]; |
| 6062 | 6063 | ||
| @@ -6105,16 +6106,18 @@ static void *slab_debugfs_next(struct seq_file *seq, void *v, loff_t *ppos) · 42 unmodified lines | |||
| 6105 | { | 6106 | { |
| 6106 | struct loc_track *t = seq->private; | 6107 | struct loc_track *t = seq->private; |
| 6107 | 6108 | ||
| 6108 | v = ppos; | 6109 | t->idx = ++(*ppos); |
| 6109 | ++*ppos; | ||
| 6110 | if (*ppos <= t->count) | 6110 | if (*ppos <= t->count) |
| 6111 | return v; | 6111 | return ppos; |
| 6112 | 6112 | ||
| 6113 | return NULL; | 6113 | return NULL; |
| 6114 | } | 6114 | } |
| 6115 | 6115 | ||
| 6116 | static void *slab_debugfs_start(struct seq_file *seq, loff_t *ppos) | 6116 | static void *slab_debugfs_start(struct seq_file *seq, loff_t *ppos) |
| 6117 | { | 6117 | { |
| 6118 | struct loc_track *t = seq->private; | ||
| 6119 | |||
| 6120 | t->idx = *ppos; | ||
| 6118 | return ppos; | 6121 | return ppos; |
| 6119 | } | 6122 | } |
| 6120 | 6123 | ||
| @@ -30,6 +30,7 @@ · 29 unmodified lines | |||
| 30 | #include <linux/swap_slots.h> | 30 | #include <linux/swap_slots.h> |
| 31 | #include <linux/cpu.h> | 31 | #include <linux/cpu.h> |
| 32 | #include <linux/cpumask.h> | 32 | #include <linux/cpumask.h> |
| 33 | #include <linux/slab.h> | ||
| 33 | #include <linux/vmalloc.h> | 34 | #include <linux/vmalloc.h> |
| 34 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
| 35 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
| @@ -4210,7 +4210,10 @@ static int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev) · 4209 unmodified lines | |||
| 4210 | if (dev->flags & IFF_UP) { | 4210 | if (dev->flags & IFF_UP) { |
| 4211 | int cpu = smp_processor_id(); /* ok because BHs are off */ | 4211 | int cpu = smp_processor_id(); /* ok because BHs are off */ |
| 4212 | 4212 | ||
| 4213 | if (txq->xmit_lock_owner != cpu) { | 4213 | /* Other cpus might concurrently change txq->xmit_lock_owner |
| 4214 | * to -1 or to their cpu id, but not to our id. | ||
| 4215 | */ | ||
| 4216 | if (READ_ONCE(txq->xmit_lock_owner) != cpu) { | ||
| 4214 | if (dev_xmit_recursion()) | 4217 | if (dev_xmit_recursion()) |
| 4215 | goto recursion_alert; | 4218 | goto recursion_alert; |
| 4216 | 4219 | ||
| @@ -4110,14 +4110,6 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) · 4109 unmodified lines | |||
| 4110 | return err; | 4110 | return err; |
| 4111 | } | 4111 | } |
| 4112 | 4112 | ||
| 4113 | if (info->attrs[DEVLINK_ATTR_NETNS_PID] || | ||
| 4114 | info->attrs[DEVLINK_ATTR_NETNS_FD] || | ||
| 4115 | info->attrs[DEVLINK_ATTR_NETNS_ID]) { | ||
| 4116 | dest_net = devlink_netns_get(skb, info); | ||
| 4117 | if (IS_ERR(dest_net)) | ||
| 4118 | return PTR_ERR(dest_net); | ||
| 4119 | } | ||
| 4120 | |||
| 4121 | if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION]) | 4113 | if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION]) |
| 4122 | action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]); | 4114 | action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]); |
| 4123 | else | 4115 | else |
| @@ -4160,6 +4152,14 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) · 36 unmodified lines | |||
| 4160 | return -EINVAL; | 4152 | return -EINVAL; |
| 4161 | } | 4153 | } |
| 4162 | } | 4154 | } |
| 4155 | if (info->attrs[DEVLINK_ATTR_NETNS_PID] || | ||
| 4156 | info->attrs[DEVLINK_ATTR_NETNS_FD] || | ||
| 4157 | info->attrs[DEVLINK_ATTR_NETNS_ID]) { | ||
| 4158 | dest_net = devlink_netns_get(skb, info); | ||
| 4159 | if (IS_ERR(dest_net)) | ||
| 4160 | return PTR_ERR(dest_net); | ||
| 4161 | } | ||
| 4162 | |||
| 4163 | err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); | 4163 | err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); |
| 4164 | 4164 | ||
| 4165 | if (dest_net) | 4165 | if (dest_net) |
| @@ -162,3 +162,22 @@ void dst_cache_destroy(struct dst_cache *dst_cache) · 161 unmodified lines | |||
| 162 | free_percpu(dst_cache->cache); | 162 | free_percpu(dst_cache->cache); |
| 163 | } | 163 | } |
| 164 | EXPORT_SYMBOL_GPL(dst_cache_destroy); | 164 | EXPORT_SYMBOL_GPL(dst_cache_destroy); |
| 165 | |||
| 166 | void dst_cache_reset_now(struct dst_cache *dst_cache) | ||
| 167 | { | ||
| 168 | int i; | ||
| 169 | |||
| 170 | if (!dst_cache->cache) | ||
| 171 | return; | ||
| 172 | |||
| 173 | dst_cache->reset_ts = jiffies; | ||
| 174 | for_each_possible_cpu(i) { | ||
| 175 | struct dst_cache_pcpu *idst = per_cpu_ptr(dst_cache->cache, i); | ||
| 176 | struct dst_entry *dst = idst->dst; | ||
| 177 | |||
| 178 | idst->cookie = 0; | ||
| 179 | idst->dst = NULL; | ||
| 180 | dst_release(dst); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | EXPORT_SYMBOL_GPL(dst_cache_reset_now); | ||
| @@ -323,7 +323,7 @@ jumped: · 322 unmodified lines | |||
| 323 | if (!err && ops->suppress && INDIRECT_CALL_MT(ops->suppress, | 323 | if (!err && ops->suppress && INDIRECT_CALL_MT(ops->suppress, |
| 324 | fib6_rule_suppress, | 324 | fib6_rule_suppress, |
| 325 | fib4_rule_suppress, | 325 | fib4_rule_suppress, |
| 326 | rule, arg)) | 326 | rule, flags, arg)) |
| 327 | continue; | 327 | continue; |
| 328 | 328 | ||
| 329 | if (err != -EAGAIN) { | 329 | if (err != -EAGAIN) { |
| @@ -763,11 +763,10 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, · 762 unmodified lines | |||
| 763 | 763 | ||
| 764 | ASSERT_RTNL(); | 764 | ASSERT_RTNL(); |
| 765 | 765 | ||
| 766 | n = kmalloc(sizeof(*n) + key_len, GFP_KERNEL); | 766 | n = kzalloc(sizeof(*n) + key_len, GFP_KERNEL); |
| 767 | if (!n) | 767 | if (!n) |
| 768 | goto out; | 768 | goto out; |
| 769 | 769 | ||
| 770 | n->protocol = 0; | ||
| 771 | write_pnet(&n->net, net); | 770 | write_pnet(&n->net, net); |
| 772 | memcpy(n->key, pkey, key_len); | 771 | memcpy(n->key, pkey, key_len); |
| 773 | n->dev = dev; | 772 | n->dev = dev; |
| @@ -1124,6 +1124,8 @@ void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock) · 1123 unmodified lines | |||
| 1124 | 1124 | ||
| 1125 | void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock) | 1125 | void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock) |
| 1126 | { | 1126 | { |
| 1127 | psock_set_prog(&psock->progs.stream_parser, NULL); | ||
| 1128 | |||
| 1127 | if (!psock->saved_data_ready) | 1129 | if (!psock->saved_data_ready) |
| 1128 | return; | 1130 | return; |
| 1129 | 1131 | ||
| @@ -1212,6 +1214,9 @@ void sk_psock_start_verdict(struct sock *sk, struct sk_psock *psock) · 82 unmodified lines | |||
| 1212 | 1214 | ||
| 1213 | void sk_psock_stop_verdict(struct sock *sk, struct sk_psock *psock) | 1215 | void sk_psock_stop_verdict(struct sock *sk, struct sk_psock *psock) |
| 1214 | { | 1216 | { |
| 1217 | psock_set_prog(&psock->progs.stream_verdict, NULL); | ||
| 1218 | psock_set_prog(&psock->progs.skb_verdict, NULL); | ||
| 1219 | |||
| 1215 | if (!psock->saved_data_ready) | 1220 | if (!psock->saved_data_ready) |
| 1216 | return; | 1221 | return; |
| 1217 | 1222 | ||
| @@ -167,8 +167,11 @@ static void sock_map_del_link(struct sock *sk, · 166 unmodified lines | |||
| 167 | write_lock_bh(&sk->sk_callback_lock); | 167 | write_lock_bh(&sk->sk_callback_lock); |
| 168 | if (strp_stop) | 168 | if (strp_stop) |
| 169 | sk_psock_stop_strp(sk, psock); | 169 | sk_psock_stop_strp(sk, psock); |
| 170 | else | 170 | if (verdict_stop) |
| 171 | sk_psock_stop_verdict(sk, psock); | 171 | sk_psock_stop_verdict(sk, psock); |
| 172 | |||
| 173 | if (psock->psock_update_sk_prot) | ||
| 174 | psock->psock_update_sk_prot(sk, psock, false); | ||
| 172 | write_unlock_bh(&sk->sk_callback_lock); | 175 | write_unlock_bh(&sk->sk_callback_lock); |
| 173 | } | 176 | } |
| 174 | } | 177 | } |
| @@ -282,6 +285,12 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk) · 107 unmodified lines | |||
| 282 | 285 | ||
| 283 | if (msg_parser) | 286 | if (msg_parser) |
| 284 | psock_set_prog(&psock->progs.msg_parser, msg_parser); | 287 | psock_set_prog(&psock->progs.msg_parser, msg_parser); |
| 288 | if (stream_parser) | ||
| 289 | psock_set_prog(&psock->progs.stream_parser, stream_parser); | ||
| 290 | if (stream_verdict) | ||
| 291 | psock_set_prog(&psock->progs.stream_verdict, stream_verdict); | ||
| 292 | if (skb_verdict) | ||
| 293 | psock_set_prog(&psock->progs.skb_verdict, skb_verdict); | ||
| 285 | 294 | ||
| 286 | ret = sock_map_init_proto(sk, psock); | 295 | ret = sock_map_init_proto(sk, psock); |
| 287 | if (ret < 0) | 296 | if (ret < 0) |
| @@ -292,14 +301,10 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk) · 4 unmodified lines | |||
| 292 | ret = sk_psock_init_strp(sk, psock); | 301 | ret = sk_psock_init_strp(sk, psock); |
| 293 | if (ret) | 302 | if (ret) |
| 294 | goto out_unlock_drop; | 303 | goto out_unlock_drop; |
| 295 | psock_set_prog(&psock->progs.stream_verdict, stream_verdict); | ||
| 296 | psock_set_prog(&psock->progs.stream_parser, stream_parser); | ||
| 297 | sk_psock_start_strp(sk, psock); | 304 | sk_psock_start_strp(sk, psock); |
| 298 | } else if (!stream_parser && stream_verdict && !psock->saved_data_ready) { | 305 | } else if (!stream_parser && stream_verdict && !psock->saved_data_ready) { |
| 299 | psock_set_prog(&psock->progs.stream_verdict, stream_verdict); | ||
| 300 | sk_psock_start_verdict(sk,psock); | 306 | sk_psock_start_verdict(sk,psock); |
| 301 | } else if (!stream_verdict && skb_verdict && !psock->saved_data_ready) { | 307 | } else if (!stream_verdict && skb_verdict && !psock->saved_data_ready) { |
| 302 | psock_set_prog(&psock->progs.skb_verdict, skb_verdict); | ||
| 303 | sk_psock_start_verdict(sk, psock); | 308 | sk_psock_start_verdict(sk, psock); |
| 304 | } | 309 | } |
| 305 | write_unlock_bh(&sk->sk_callback_lock); | 310 | write_unlock_bh(&sk->sk_callback_lock); |
| @@ -40,7 +40,8 @@ int ethnl_ops_begin(struct net_device *dev) · 39 unmodified lines | |||
| 40 | if (dev->dev.parent) | 40 | if (dev->dev.parent) |
| 41 | pm_runtime_get_sync(dev->dev.parent); | 41 | pm_runtime_get_sync(dev->dev.parent); |
| 42 | 42 | ||
| 43 | if (!netif_device_present(dev)) { | 43 | if (!netif_device_present(dev) || |
| 44 | dev->reg_state == NETREG_UNREGISTERING) { | ||
| 44 | ret = -ENODEV; | 45 | ret = -ENODEV; |
| 45 | goto err; | 46 | goto err; |
| 46 | } | 47 | } |
| @@ -1582,7 +1582,7 @@ static int __net_init fib_net_init(struct net *net) · 1581 unmodified lines | |||
| 1582 | int error; | 1582 | int error; |
| 1583 | 1583 | ||
| 1584 | #ifdef CONFIG_IP_ROUTE_CLASSID | 1584 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 1585 | net->ipv4.fib_num_tclassid_users = 0; | 1585 | atomic_set(&net->ipv4.fib_num_tclassid_users, 0); |
| 1586 | #endif | 1586 | #endif |
| 1587 | error = ip_fib_net_init(net); | 1587 | error = ip_fib_net_init(net); |
| 1588 | if (error < 0) | 1588 | if (error < 0) |
| @@ -141,6 +141,7 @@ INDIRECT_CALLABLE_SCOPE int fib4_rule_action(struct fib_rule *rule, · 140 unmodified lines | |||
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | INDIRECT_CALLABLE_SCOPE bool fib4_rule_suppress(struct fib_rule *rule, | 143 | INDIRECT_CALLABLE_SCOPE bool fib4_rule_suppress(struct fib_rule *rule, |
| 144 | int flags, | ||
| 144 | struct fib_lookup_arg *arg) | 145 | struct fib_lookup_arg *arg) |
| 145 | { | 146 | { |
| 146 | struct fib_result *result = (struct fib_result *) arg->result; | 147 | struct fib_result *result = (struct fib_result *) arg->result; |
| @@ -263,7 +264,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, · 116 unmodified lines | |||
| 263 | if (tb[FRA_FLOW]) { | 264 | if (tb[FRA_FLOW]) { |
| 264 | rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); | 265 | rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); |
| 265 | if (rule4->tclassid) | 266 | if (rule4->tclassid) |
| 266 | net->ipv4.fib_num_tclassid_users++; | 267 | atomic_inc(&net->ipv4.fib_num_tclassid_users); |
| 267 | } | 268 | } |
| 268 | #endif | 269 | #endif |
| 269 | 270 | ||
| @@ -295,7 +296,7 @@ static int fib4_rule_delete(struct fib_rule *rule) · 25 unmodified lines | |||
| 295 | 296 | ||
| 296 | #ifdef CONFIG_IP_ROUTE_CLASSID | 297 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 297 | if (((struct fib4_rule *)rule)->tclassid) | 298 | if (((struct fib4_rule *)rule)->tclassid) |
| 298 | net->ipv4.fib_num_tclassid_users--; | 299 | atomic_dec(&net->ipv4.fib_num_tclassid_users); |
| 299 | #endif | 300 | #endif |
| 300 | net->ipv4.fib_has_custom_rules = true; | 301 | net->ipv4.fib_has_custom_rules = true; |
| 301 | 302 | ||
| @@ -220,7 +220,7 @@ void fib_nh_release(struct net *net, struct fib_nh *fib_nh) · 219 unmodified lines | |||
| 220 | { | 220 | { |
| 221 | #ifdef CONFIG_IP_ROUTE_CLASSID | 221 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 222 | if (fib_nh->nh_tclassid) | 222 | if (fib_nh->nh_tclassid) |
| 223 | net->ipv4.fib_num_tclassid_users--; | 223 | atomic_dec(&net->ipv4.fib_num_tclassid_users); |
| 224 | #endif | 224 | #endif |
| 225 | fib_nh_common_release(&fib_nh->nh_common); | 225 | fib_nh_common_release(&fib_nh->nh_common); |
| 226 | } | 226 | } |
| @@ -632,7 +632,7 @@ int fib_nh_init(struct net *net, struct fib_nh *nh, · 405 unmodified lines | |||
| 632 | #ifdef CONFIG_IP_ROUTE_CLASSID | 632 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 633 | nh->nh_tclassid = cfg->fc_flow; | 633 | nh->nh_tclassid = cfg->fc_flow; |
| 634 | if (nh->nh_tclassid) | 634 | if (nh->nh_tclassid) |
| 635 | net->ipv4.fib_num_tclassid_users++; | 635 | atomic_inc(&net->ipv4.fib_num_tclassid_users); |
| 636 | #endif | 636 | #endif |
| 637 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 637 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
| 638 | nh->fib_nh_weight = nh_weight; | 638 | nh->fib_nh_weight = nh_weight; |
| @@ -721,7 +721,7 @@ static struct request_sock *inet_reqsk_clone(struct request_sock *req, · 720 unmodified lines | |||
| 721 | 721 | ||
| 722 | sk_node_init(&nreq_sk->sk_node); | 722 | sk_node_init(&nreq_sk->sk_node); |
| 723 | nreq_sk->sk_tx_queue_mapping = req_sk->sk_tx_queue_mapping; | 723 | nreq_sk->sk_tx_queue_mapping = req_sk->sk_tx_queue_mapping; |
| 724 | #ifdef CONFIG_XPS | 724 | #ifdef CONFIG_SOCK_RX_QUEUE_MAPPING |
| 725 | nreq_sk->sk_rx_queue_mapping = req_sk->sk_rx_queue_mapping; | 725 | nreq_sk->sk_rx_queue_mapping = req_sk->sk_rx_queue_mapping; |
| 726 | #endif | 726 | #endif |
| 727 | nreq_sk->sk_incoming_cpu = req_sk->sk_incoming_cpu; | 727 | nreq_sk->sk_incoming_cpu = req_sk->sk_incoming_cpu; |
| @@ -829,8 +829,8 @@ int tcp_child_process(struct sock *parent, struct sock *child, · 828 unmodified lines | |||
| 829 | int ret = 0; | 829 | int ret = 0; |
| 830 | int state = child->sk_state; | 830 | int state = child->sk_state; |
| 831 | 831 | ||
| 832 | /* record NAPI ID of child */ | 832 | /* record sk_napi_id and sk_rx_queue_mapping of child. */ |
| 833 | sk_mark_napi_id(child, skb); | 833 | sk_mark_napi_id_set(child, skb); |
| 834 | 834 | ||
| 835 | tcp_segs_in(tcp_sk(child), skb); | 835 | tcp_segs_in(tcp_sk(child), skb); |
| 836 | if (!sock_owned_by_user(child)) { | 836 | if (!sock_owned_by_user(child)) { |
| @@ -916,7 +916,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4, · 915 unmodified lines | |||
| 916 | kfree_skb(skb); | 916 | kfree_skb(skb); |
| 917 | return -EINVAL; | 917 | return -EINVAL; |
| 918 | } | 918 | } |
| 919 | if (skb->len > cork->gso_size * UDP_MAX_SEGMENTS) { | 919 | if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) { |
| 920 | kfree_skb(skb); | 920 | kfree_skb(skb); |
| 921 | return -EINVAL; | 921 | return -EINVAL; |
| 922 | } | 922 | } |
| @@ -267,6 +267,7 @@ INDIRECT_CALLABLE_SCOPE int fib6_rule_action(struct fib_rule *rule, · 266 unmodified lines | |||
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | INDIRECT_CALLABLE_SCOPE bool fib6_rule_suppress(struct fib_rule *rule, | 269 | INDIRECT_CALLABLE_SCOPE bool fib6_rule_suppress(struct fib_rule *rule, |
| 270 | int flags, | ||
| 270 | struct fib_lookup_arg *arg) | 271 | struct fib_lookup_arg *arg) |
| 271 | { | 272 | { |
| 272 | struct fib6_result *res = arg->result; | 273 | struct fib6_result *res = arg->result; |
| @@ -294,8 +295,7 @@ INDIRECT_CALLABLE_SCOPE bool fib6_rule_suppress(struct fib_rule *rule, · 21 unmodified lines | |||
| 294 | return false; | 295 | return false; |
| 295 | 296 | ||
| 296 | suppress_route: | 297 | suppress_route: |
| 297 | if (!(arg->flags & FIB_LOOKUP_NOREF)) | 298 | ip6_rt_put_flags(rt, flags); |
| 298 | ip6_rt_put(rt); | ||
| 299 | return true; | 299 | return true; |
| 300 | } | 300 | } |
| 301 | 301 | ||
| @@ -248,9 +248,9 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, · 247 unmodified lines | |||
| 248 | * memcmp() alone below is sufficient, right? | 248 | * memcmp() alone below is sufficient, right? |
| 249 | */ | 249 | */ |
| 250 | if ((first_word & htonl(0xF00FFFFF)) || | 250 | if ((first_word & htonl(0xF00FFFFF)) || |
| 251 | !ipv6_addr_equal(&iph->saddr, &iph2->saddr) || | 251 | !ipv6_addr_equal(&iph->saddr, &iph2->saddr) || |
| 252 | !ipv6_addr_equal(&iph->daddr, &iph2->daddr) || | 252 | !ipv6_addr_equal(&iph->daddr, &iph2->daddr) || |
| 253 | *(u16 *)&iph->nexthdr != *(u16 *)&iph2->nexthdr) { | 253 | *(u16 *)&iph->nexthdr != *(u16 *)&iph2->nexthdr) { |
| 254 | not_same_flow: | 254 | not_same_flow: |
| 255 | NAPI_GRO_CB(p)->same_flow = 0; | 255 | NAPI_GRO_CB(p)->same_flow = 0; |
| 256 | continue; | 256 | continue; |
| @@ -161,6 +161,14 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) · 160 unmodified lines | |||
| 161 | hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb)); | 161 | hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb)); |
| 162 | 162 | ||
| 163 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | 163 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); |
| 164 | |||
| 165 | /* the control block has been erased, so we have to set the | ||
| 166 | * iif once again. | ||
| 167 | * We read the receiving interface index directly from the | ||
| 168 | * skb->skb_iif as it is done in the IPv4 receiving path (i.e.: | ||
| 169 | * ip_rcv_core(...)). | ||
| 170 | */ | ||
| 171 | IP6CB(skb)->iif = skb->skb_iif; | ||
| 164 | } | 172 | } |
| 165 | 173 | ||
| 166 | hdr->nexthdr = NEXTHDR_ROUTING; | 174 | hdr->nexthdr = NEXTHDR_ROUTING; |
| @@ -952,7 +952,7 @@ static int mctp_route_add(struct mctp_dev *mdev, mctp_eid_t daddr_start, · 951 unmodified lines | |||
| 952 | } | 952 | } |
| 953 | 953 | ||
| 954 | static int mctp_route_remove(struct mctp_dev *mdev, mctp_eid_t daddr_start, | 954 | static int mctp_route_remove(struct mctp_dev *mdev, mctp_eid_t daddr_start, |
| 955 | unsigned int daddr_extent) | 955 | unsigned int daddr_extent, unsigned char type) |
| 956 | { | 956 | { |
| 957 | struct net *net = dev_net(mdev->dev); | 957 | struct net *net = dev_net(mdev->dev); |
| 958 | struct mctp_route *rt, *tmp; | 958 | struct mctp_route *rt, *tmp; |
| @@ -969,7 +969,8 @@ static int mctp_route_remove(struct mctp_dev *mdev, mctp_eid_t daddr_start, · 10 unmodified lines | |||
| 969 | 969 | ||
| 970 | list_for_each_entry_safe(rt, tmp, &net->mctp.routes, list) { | 970 | list_for_each_entry_safe(rt, tmp, &net->mctp.routes, list) { |
| 971 | if (rt->dev == mdev && | 971 | if (rt->dev == mdev && |
| 972 | rt->min == daddr_start && rt->max == daddr_end) { | 972 | rt->min == daddr_start && rt->max == daddr_end && |
| 973 | rt->type == type) { | ||
| 973 | list_del_rcu(&rt->list); | 974 | list_del_rcu(&rt->list); |
| 974 | /* TODO: immediate RTM_DELROUTE */ | 975 | /* TODO: immediate RTM_DELROUTE */ |
| 975 | mctp_route_release(rt); | 976 | mctp_route_release(rt); |
| @@ -987,7 +988,7 @@ int mctp_route_add_local(struct mctp_dev *mdev, mctp_eid_t addr) · 11 unmodified lines | |||
| 987 | 988 | ||
| 988 | int mctp_route_remove_local(struct mctp_dev *mdev, mctp_eid_t addr) | 989 | int mctp_route_remove_local(struct mctp_dev *mdev, mctp_eid_t addr) |
| 989 | { | 990 | { |
| 990 | return mctp_route_remove(mdev, addr, 0); | 991 | return mctp_route_remove(mdev, addr, 0, RTN_LOCAL); |
| 991 | } | 992 | } |
| 992 | 993 | ||
| 993 | /* removes all entries for a given device */ | 994 | /* removes all entries for a given device */ |
| @@ -1195,7 +1196,7 @@ static int mctp_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, · 201 unmodified lines | |||
| 1195 | if (rtm->rtm_type != RTN_UNICAST) | 1196 | if (rtm->rtm_type != RTN_UNICAST) |
| 1196 | return -EINVAL; | 1197 | return -EINVAL; |
| 1197 | 1198 | ||
| 1198 | rc = mctp_route_remove(mdev, daddr_start, rtm->rtm_dst_len); | 1199 | rc = mctp_route_remove(mdev, daddr_start, rtm->rtm_dst_len, RTN_UNICAST); |
| 1199 | return rc; | 1200 | return rc; |
| 1200 | } | 1201 | } |
| 1201 | 1202 | ||
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 12 | static netdev_tx_t mctp_test_dev_tx(struct sk_buff *skb, | 12 | static netdev_tx_t mctp_test_dev_tx(struct sk_buff *skb, |
| 13 | struct net_device *ndev) | 13 | struct net_device *ndev) |
| 14 | { | 14 | { |
| 15 | kfree(skb); | 15 | kfree_skb(skb); |
| 16 | return NETDEV_TX_OK; | 16 | return NETDEV_TX_OK; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| @@ -409,7 +409,7 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev, · 408 unmodified lines | |||
| 409 | goto err; | 409 | goto err; |
| 410 | 410 | ||
| 411 | /* Find the output device */ | 411 | /* Find the output device */ |
| 412 | out_dev = rcu_dereference(nh->nh_dev); | 412 | out_dev = nh->nh_dev; |
| 413 | if (!mpls_output_possible(out_dev)) | 413 | if (!mpls_output_possible(out_dev)) |
| 414 | goto tx_err; | 414 | goto tx_err; |
| 415 | 415 | ||
| @@ -698,7 +698,7 @@ static int mpls_nh_assign_dev(struct net *net, struct mpls_route *rt, · 282 unmodified lines | |||
| 698 | (dev->addr_len != nh->nh_via_alen)) | 698 | (dev->addr_len != nh->nh_via_alen)) |
| 699 | goto errout; | 699 | goto errout; |
| 700 | 700 | ||
| 701 | RCU_INIT_POINTER(nh->nh_dev, dev); | 701 | nh->nh_dev = dev; |
| 702 | 702 | ||
| 703 | if (!(dev->flags & IFF_UP)) { | 703 | if (!(dev->flags & IFF_UP)) { |
| 704 | nh->nh_flags |= RTNH_F_DEAD; | 704 | nh->nh_flags |= RTNH_F_DEAD; |
| @@ -1491,26 +1491,53 @@ static void mpls_dev_destroy_rcu(struct rcu_head *head) · 786 unmodified lines | |||
| 1491 | kfree(mdev); | 1491 | kfree(mdev); |
| 1492 | } | 1492 | } |
| 1493 | 1493 | ||
| 1494 | static void mpls_ifdown(struct net_device *dev, int event) | 1494 | static int mpls_ifdown(struct net_device *dev, int event) |
| 1495 | { | 1495 | { |
| 1496 | struct mpls_route __rcu **platform_label; | 1496 | struct mpls_route __rcu **platform_label; |
| 1497 | struct net *net = dev_net(dev); | 1497 | struct net *net = dev_net(dev); |
| 1498 | u8 alive, deleted; | ||
| 1499 | unsigned index; | 1498 | unsigned index; |
| 1500 | 1499 | ||
| 1501 | platform_label = rtnl_dereference(net->mpls.platform_label); | 1500 | platform_label = rtnl_dereference(net->mpls.platform_label); |
| 1502 | for (index = 0; index < net->mpls.platform_labels; index++) { | 1501 | for (index = 0; index < net->mpls.platform_labels; index++) { |
| 1503 | struct mpls_route *rt = rtnl_dereference(platform_label[index]); | 1502 | struct mpls_route *rt = rtnl_dereference(platform_label[index]); |
| 1503 | bool nh_del = false; | ||
| 1504 | u8 alive = 0; | ||
| 1504 | 1505 | ||
| 1505 | if (!rt) | 1506 | if (!rt) |
| 1506 | continue; | 1507 | continue; |
| 1507 | 1508 | ||
| 1508 | alive = 0; | 1509 | if (event == NETDEV_UNREGISTER) { |
| 1509 | deleted = 0; | 1510 | u8 deleted = 0; |
| 1511 | |||
| 1512 | for_nexthops(rt) { | ||
| 1513 | if (!nh->nh_dev || nh->nh_dev == dev) | ||
| 1514 | deleted++; | ||
| 1515 | if (nh->nh_dev == dev) | ||
| 1516 | nh_del = true; | ||
| 1517 | } endfor_nexthops(rt); | ||
| 1518 | |||
| 1519 | /* if there are no more nexthops, delete the route */ | ||
| 1520 | if (deleted == rt->rt_nhn) { | ||
| 1521 | mpls_route_update(net, index, NULL, NULL); | ||
| 1522 | continue; | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | if (nh_del) { | ||
| 1526 | size_t size = sizeof(*rt) + rt->rt_nhn * | ||
| 1527 | rt->rt_nh_size; | ||
| 1528 | struct mpls_route *orig = rt; | ||
| 1529 | |||
| 1530 | rt = kmalloc(size, GFP_KERNEL); | ||
| 1531 | if (!rt) | ||
| 1532 | return -ENOMEM; | ||
| 1533 | memcpy(rt, orig, size); | ||
| 1534 | } | ||
| 1535 | } | ||
| 1536 | |||
| 1510 | change_nexthops(rt) { | 1537 | change_nexthops(rt) { |
| 1511 | unsigned int nh_flags = nh->nh_flags; | 1538 | unsigned int nh_flags = nh->nh_flags; |
| 1512 | 1539 | ||
| 1513 | if (rtnl_dereference(nh->nh_dev) != dev) | 1540 | if (nh->nh_dev != dev) |
| 1514 | goto next; | 1541 | goto next; |
| 1515 | 1542 | ||
| 1516 | switch (event) { | 1543 | switch (event) { |
| @@ -1523,23 +1550,22 @@ static void mpls_ifdown(struct net_device *dev, int event) · 6 unmodified lines | |||
| 1523 | break; | 1550 | break; |
| 1524 | } | 1551 | } |
| 1525 | if (event == NETDEV_UNREGISTER) | 1552 | if (event == NETDEV_UNREGISTER) |
| 1526 | RCU_INIT_POINTER(nh->nh_dev, NULL); | 1553 | nh->nh_dev = NULL; |
| 1527 | 1554 | ||
| 1528 | if (nh->nh_flags != nh_flags) | 1555 | if (nh->nh_flags != nh_flags) |
| 1529 | WRITE_ONCE(nh->nh_flags, nh_flags); | 1556 | WRITE_ONCE(nh->nh_flags, nh_flags); |
| 1530 | next: | 1557 | next: |
| 1531 | if (!(nh_flags & (RTNH_F_DEAD | RTNH_F_LINKDOWN))) | 1558 | if (!(nh_flags & (RTNH_F_DEAD | RTNH_F_LINKDOWN))) |
| 1532 | alive++; | 1559 | alive++; |
| 1533 | if (!rtnl_dereference(nh->nh_dev)) | ||
| 1534 | deleted++; | ||
| 1535 | } endfor_nexthops(rt); | 1560 | } endfor_nexthops(rt); |
| 1536 | 1561 | ||
| 1537 | WRITE_ONCE(rt->rt_nhn_alive, alive); | 1562 | WRITE_ONCE(rt->rt_nhn_alive, alive); |
| 1538 | 1563 | ||
| 1539 | /* if there are no more nexthops, delete the route */ | 1564 | if (nh_del) |
| 1540 | if (event == NETDEV_UNREGISTER && deleted == rt->rt_nhn) | 1565 | mpls_route_update(net, index, rt, NULL); |
| 1541 | mpls_route_update(net, index, NULL, NULL); | ||
| 1542 | } | 1566 | } |
| 1567 | |||
| 1568 | return 0; | ||
| 1543 | } | 1569 | } |
| 1544 | 1570 | ||
| 1545 | static void mpls_ifup(struct net_device *dev, unsigned int flags) | 1571 | static void mpls_ifup(struct net_device *dev, unsigned int flags) |
| @@ -1559,14 +1585,12 @@ static void mpls_ifup(struct net_device *dev, unsigned int flags) · 13 unmodified lines | |||
| 1559 | alive = 0; | 1585 | alive = 0; |
| 1560 | change_nexthops(rt) { | 1586 | change_nexthops(rt) { |
| 1561 | unsigned int nh_flags = nh->nh_flags; | 1587 | unsigned int nh_flags = nh->nh_flags; |
| 1562 | struct net_device *nh_dev = | ||
| 1563 | rtnl_dereference(nh->nh_dev); | ||
| 1564 | 1588 | ||
| 1565 | if (!(nh_flags & flags)) { | 1589 | if (!(nh_flags & flags)) { |
| 1566 | alive++; | 1590 | alive++; |
| 1567 | continue; | 1591 | continue; |
| 1568 | } | 1592 | } |
| 1569 | if (nh_dev != dev) | 1593 | if (nh->nh_dev != dev) |
| 1570 | continue; | 1594 | continue; |
| 1571 | alive++; | 1595 | alive++; |
| 1572 | nh_flags &= ~flags; | 1596 | nh_flags &= ~flags; |
| @@ -1597,8 +1621,12 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event, · 24 unmodified lines | |||
| 1597 | return NOTIFY_OK; | 1621 | return NOTIFY_OK; |
| 1598 | 1622 | ||
| 1599 | switch (event) { | 1623 | switch (event) { |
| 1624 | int err; | ||
| 1625 | |||
| 1600 | case NETDEV_DOWN: | 1626 | case NETDEV_DOWN: |
| 1601 | mpls_ifdown(dev, event); | 1627 | err = mpls_ifdown(dev, event); |
| 1628 | if (err) | ||
| 1629 | return notifier_from_errno(err); | ||
| 1602 | break; | 1630 | break; |
| 1603 | case NETDEV_UP: | 1631 | case NETDEV_UP: |
| 1604 | flags = dev_get_flags(dev); | 1632 | flags = dev_get_flags(dev); |
| @@ -1609,13 +1637,18 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event, · 4 unmodified lines | |||
| 1609 | break; | 1637 | break; |
| 1610 | case NETDEV_CHANGE: | 1638 | case NETDEV_CHANGE: |
| 1611 | flags = dev_get_flags(dev); | 1639 | flags = dev_get_flags(dev); |
| 1612 | if (flags & (IFF_RUNNING | IFF_LOWER_UP)) | 1640 | if (flags & (IFF_RUNNING | IFF_LOWER_UP)) { |
| 1613 | mpls_ifup(dev, RTNH_F_DEAD | RTNH_F_LINKDOWN); | 1641 | mpls_ifup(dev, RTNH_F_DEAD | RTNH_F_LINKDOWN); |
| 1614 | else | 1642 | } else { |
| 1615 | mpls_ifdown(dev, event); | 1643 | err = mpls_ifdown(dev, event); |
| 1644 | if (err) | ||
| 1645 | return notifier_from_errno(err); | ||
| 1646 | } | ||
| 1616 | break; | 1647 | break; |
| 1617 | case NETDEV_UNREGISTER: | 1648 | case NETDEV_UNREGISTER: |
| 1618 | mpls_ifdown(dev, event); | 1649 | err = mpls_ifdown(dev, event); |
| 1650 | if (err) | ||
| 1651 | return notifier_from_errno(err); | ||
| 1619 | mdev = mpls_dev_get(dev); | 1652 | mdev = mpls_dev_get(dev); |
| 1620 | if (mdev) { | 1653 | if (mdev) { |
| 1621 | mpls_dev_sysctl_unregister(dev, mdev); | 1654 | mpls_dev_sysctl_unregister(dev, mdev); |
| @@ -1626,8 +1659,6 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event, · 4 unmodified lines | |||
| 1626 | case NETDEV_CHANGENAME: | 1659 | case NETDEV_CHANGENAME: |
| 1627 | mdev = mpls_dev_get(dev); | 1660 | mdev = mpls_dev_get(dev); |
| 1628 | if (mdev) { | 1661 | if (mdev) { |
| 1629 | int err; | ||
| 1630 | |||
| 1631 | mpls_dev_sysctl_unregister(dev, mdev); | 1662 | mpls_dev_sysctl_unregister(dev, mdev); |
| 1632 | err = mpls_dev_sysctl_register(dev, mdev); | 1663 | err = mpls_dev_sysctl_register(dev, mdev); |
| 1633 | if (err) | 1664 | if (err) |
| @@ -1994,7 +2025,7 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event, · 360 unmodified lines | |||
| 1994 | nla_put_via(skb, nh->nh_via_table, mpls_nh_via(rt, nh), | 2025 | nla_put_via(skb, nh->nh_via_table, mpls_nh_via(rt, nh), |
| 1995 | nh->nh_via_alen)) | 2026 | nh->nh_via_alen)) |
| 1996 | goto nla_put_failure; | 2027 | goto nla_put_failure; |
| 1997 | dev = rtnl_dereference(nh->nh_dev); | 2028 | dev = nh->nh_dev; |
| 1998 | if (dev && nla_put_u32(skb, RTA_OIF, dev->ifindex)) | 2029 | if (dev && nla_put_u32(skb, RTA_OIF, dev->ifindex)) |
| 1999 | goto nla_put_failure; | 2030 | goto nla_put_failure; |
| 2000 | if (nh->nh_flags & RTNH_F_LINKDOWN) | 2031 | if (nh->nh_flags & RTNH_F_LINKDOWN) |
| @@ -2012,7 +2043,7 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event, · 11 unmodified lines | |||
| 2012 | goto nla_put_failure; | 2043 | goto nla_put_failure; |
| 2013 | 2044 | ||
| 2014 | for_nexthops(rt) { | 2045 | for_nexthops(rt) { |
| 2015 | dev = rtnl_dereference(nh->nh_dev); | 2046 | dev = nh->nh_dev; |
| 2016 | if (!dev) | 2047 | if (!dev) |
| 2017 | continue; | 2048 | continue; |
| 2018 | 2049 | ||
| @@ -2123,18 +2154,14 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh, · 104 unmodified lines | |||
| 2123 | static bool mpls_rt_uses_dev(struct mpls_route *rt, | 2154 | static bool mpls_rt_uses_dev(struct mpls_route *rt, |
| 2124 | const struct net_device *dev) | 2155 | const struct net_device *dev) |
| 2125 | { | 2156 | { |
| 2126 | struct net_device *nh_dev; | ||
| 2127 | |||
| 2128 | if (rt->rt_nhn == 1) { | 2157 | if (rt->rt_nhn == 1) { |
| 2129 | struct mpls_nh *nh = rt->rt_nh; | 2158 | struct mpls_nh *nh = rt->rt_nh; |
| 2130 | 2159 | ||
| 2131 | nh_dev = rtnl_dereference(nh->nh_dev); | 2160 | if (nh->nh_dev == dev) |
| 2132 | if (dev == nh_dev) | ||
| 2133 | return true; | 2161 | return true; |
| 2134 | } else { | 2162 | } else { |
| 2135 | for_nexthops(rt) { | 2163 | for_nexthops(rt) { |
| 2136 | nh_dev = rtnl_dereference(nh->nh_dev); | 2164 | if (nh->nh_dev == dev) |
| 2137 | if (nh_dev == dev) | ||
| 2138 | return true; | 2165 | return true; |
| 2139 | } endfor_nexthops(rt); | 2166 | } endfor_nexthops(rt); |
| 2140 | } | 2167 | } |
| @@ -2222,7 +2249,7 @@ static inline size_t lfib_nlmsg_size(struct mpls_route *rt) · 81 unmodified lines | |||
| 2222 | size_t nhsize = 0; | 2249 | size_t nhsize = 0; |
| 2223 | 2250 | ||
| 2224 | for_nexthops(rt) { | 2251 | for_nexthops(rt) { |
| 2225 | if (!rtnl_dereference(nh->nh_dev)) | 2252 | if (!nh->nh_dev) |
| 2226 | continue; | 2253 | continue; |
| 2227 | nhsize += nla_total_size(sizeof(struct rtnexthop)); | 2254 | nhsize += nla_total_size(sizeof(struct rtnexthop)); |
| 2228 | /* RTA_VIA */ | 2255 | /* RTA_VIA */ |
| @@ -2468,7 +2495,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, · 239 unmodified lines | |||
| 2468 | nla_put_via(skb, nh->nh_via_table, mpls_nh_via(rt, nh), | 2495 | nla_put_via(skb, nh->nh_via_table, mpls_nh_via(rt, nh), |
| 2469 | nh->nh_via_alen)) | 2496 | nh->nh_via_alen)) |
| 2470 | goto nla_put_failure; | 2497 | goto nla_put_failure; |
| 2471 | dev = rtnl_dereference(nh->nh_dev); | 2498 | dev = nh->nh_dev; |
| 2472 | if (dev && nla_put_u32(skb, RTA_OIF, dev->ifindex)) | 2499 | if (dev && nla_put_u32(skb, RTA_OIF, dev->ifindex)) |
| 2473 | goto nla_put_failure; | 2500 | goto nla_put_failure; |
| 2474 | 2501 | ||
| @@ -2507,7 +2534,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) · 32 unmodified lines | |||
| 2507 | rt0 = mpls_rt_alloc(1, lo->addr_len, 0); | 2534 | rt0 = mpls_rt_alloc(1, lo->addr_len, 0); |
| 2508 | if (IS_ERR(rt0)) | 2535 | if (IS_ERR(rt0)) |
| 2509 | goto nort0; | 2536 | goto nort0; |
| 2510 | RCU_INIT_POINTER(rt0->rt_nh->nh_dev, lo); | 2537 | rt0->rt_nh->nh_dev = lo; |
| 2511 | rt0->rt_protocol = RTPROT_KERNEL; | 2538 | rt0->rt_protocol = RTPROT_KERNEL; |
| 2512 | rt0->rt_payload_type = MPT_IPV4; | 2539 | rt0->rt_payload_type = MPT_IPV4; |
| 2513 | rt0->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT; | 2540 | rt0->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT; |
| @@ -2521,7 +2548,7 @@ static int resize_platform_label_table(struct net *net, size_t limit) · 7 unmodified lines | |||
| 2521 | rt2 = mpls_rt_alloc(1, lo->addr_len, 0); | 2548 | rt2 = mpls_rt_alloc(1, lo->addr_len, 0); |
| 2522 | if (IS_ERR(rt2)) | 2549 | if (IS_ERR(rt2)) |
| 2523 | goto nort2; | 2550 | goto nort2; |
| 2524 | RCU_INIT_POINTER(rt2->rt_nh->nh_dev, lo); | 2551 | rt2->rt_nh->nh_dev = lo; |
| 2525 | rt2->rt_protocol = RTPROT_KERNEL; | 2552 | rt2->rt_protocol = RTPROT_KERNEL; |
| 2526 | rt2->rt_payload_type = MPT_IPV6; | 2553 | rt2->rt_payload_type = MPT_IPV6; |
| 2527 | rt2->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT; | 2554 | rt2->rt_ttl_propagate = MPLS_TTL_PROP_DEFAULT; |
| @@ -87,7 +87,7 @@ enum mpls_payload_type { · 86 unmodified lines | |||
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | struct mpls_nh { /* next hop label forwarding entry */ | 89 | struct mpls_nh { /* next hop label forwarding entry */ |
| 90 | struct net_device __rcu *nh_dev; | 90 | struct net_device *nh_dev; |
| 91 | 91 | ||
| 92 | /* nh_flags is accessed under RCU in the packet path; it is | 92 | /* nh_flags is accessed under RCU in the packet path; it is |
| 93 | * modified handling netdev events with rtnl lock held | 93 | * modified handling netdev events with rtnl lock held |
| @@ -684,7 +684,7 @@ bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report) · 683 unmodified lines | |||
| 684 | 684 | ||
| 685 | tstamp = nf_conn_tstamp_find(ct); | 685 | tstamp = nf_conn_tstamp_find(ct); |
| 686 | if (tstamp) { | 686 | if (tstamp) { |
| 687 | s32 timeout = ct->timeout - nfct_time_stamp; | 687 | s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp; |
| 688 | 688 | ||
| 689 | tstamp->stop = ktime_get_real_ns(); | 689 | tstamp->stop = ktime_get_real_ns(); |
| 690 | if (timeout < 0) | 690 | if (timeout < 0) |
| @@ -1036,7 +1036,7 @@ static int nf_ct_resolve_clash_harder(struct sk_buff *skb, u32 repl_idx) · 345 unmodified lines | |||
| 1036 | } | 1036 | } |
| 1037 | 1037 | ||
| 1038 | /* We want the clashing entry to go away real soon: 1 second timeout. */ | 1038 | /* We want the clashing entry to go away real soon: 1 second timeout. */ |
| 1039 | loser_ct->timeout = nfct_time_stamp + HZ; | 1039 | WRITE_ONCE(loser_ct->timeout, nfct_time_stamp + HZ); |
| 1040 | 1040 | ||
| 1041 | /* IPS_NAT_CLASH removes the entry automatically on the first | 1041 | /* IPS_NAT_CLASH removes the entry automatically on the first |
| 1042 | * reply. Also prevents UDP tracker from moving the entry to | 1042 | * reply. Also prevents UDP tracker from moving the entry to |
| @@ -1560,7 +1560,7 @@ __nf_conntrack_alloc(struct net *net, · 517 unmodified lines | |||
| 1560 | /* save hash for reusing when confirming */ | 1560 | /* save hash for reusing when confirming */ |
| 1561 | *(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash; | 1561 | *(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash; |
| 1562 | ct->status = 0; | 1562 | ct->status = 0; |
| 1563 | ct->timeout = 0; | 1563 | WRITE_ONCE(ct->timeout, 0); |
| 1564 | write_pnet(&ct->ct_net, net); | 1564 | write_pnet(&ct->ct_net, net); |
| 1565 | memset(&ct->__nfct_init_offset, 0, | 1565 | memset(&ct->__nfct_init_offset, 0, |
| 1566 | offsetof(struct nf_conn, proto) - | 1566 | offsetof(struct nf_conn, proto) - |
| @@ -1998,7 +1998,7 @@ static int ctnetlink_change_timeout(struct nf_conn *ct, · 1997 unmodified lines | |||
| 1998 | 1998 | ||
| 1999 | if (timeout > INT_MAX) | 1999 | if (timeout > INT_MAX) |
| 2000 | timeout = INT_MAX; | 2000 | timeout = INT_MAX; |
| 2001 | ct->timeout = nfct_time_stamp + (u32)timeout; | 2001 | WRITE_ONCE(ct->timeout, nfct_time_stamp + (u32)timeout); |
| 2002 | 2002 | ||
| 2003 | if (test_bit(IPS_DYING_BIT, &ct->status)) | 2003 | if (test_bit(IPS_DYING_BIT, &ct->status)) |
| 2004 | return -ETIME; | 2004 | return -ETIME; |
| @@ -201,8 +201,8 @@ static void flow_offload_fixup_ct_timeout(struct nf_conn *ct) · 200 unmodified lines | |||
| 201 | if (timeout < 0) | 201 | if (timeout < 0) |
| 202 | timeout = 0; | 202 | timeout = 0; |
| 203 | 203 | ||
| 204 | if (nf_flow_timeout_delta(ct->timeout) > (__s32)timeout) | 204 | if (nf_flow_timeout_delta(READ_ONCE(ct->timeout)) > (__s32)timeout) |
| 205 | ct->timeout = nfct_time_stamp + timeout; | 205 | WRITE_ONCE(ct->timeout, nfct_time_stamp + timeout); |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | static void flow_offload_fixup_ct_state(struct nf_conn *ct) | 208 | static void flow_offload_fixup_ct_state(struct nf_conn *ct) |
| @@ -387,7 +387,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, · 386 unmodified lines | |||
| 387 | struct net_device *indev; | 387 | struct net_device *indev; |
| 388 | struct net_device *outdev; | 388 | struct net_device *outdev; |
| 389 | struct nf_conn *ct = NULL; | 389 | struct nf_conn *ct = NULL; |
| 390 | enum ip_conntrack_info ctinfo; | 390 | enum ip_conntrack_info ctinfo = 0; |
| 391 | struct nfnl_ct_hook *nfnl_ct; | 391 | struct nfnl_ct_hook *nfnl_ct; |
| 392 | bool csum_verify; | 392 | bool csum_verify; |
| 393 | char *secdata = NULL; | 393 | char *secdata = NULL; |
| @@ -236,7 +236,7 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr, · 235 unmodified lines | |||
| 236 | 236 | ||
| 237 | tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len); | 237 | tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len); |
| 238 | if (!tcph) | 238 | if (!tcph) |
| 239 | return; | 239 | goto err; |
| 240 | 240 | ||
| 241 | opt = (u8 *)tcph; | 241 | opt = (u8 *)tcph; |
| 242 | for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { | 242 | for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { |
| @@ -251,16 +251,16 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr, · 8 unmodified lines | |||
| 251 | continue; | 251 | continue; |
| 252 | 252 | ||
| 253 | if (i + optl > tcphdr_len || priv->len + priv->offset > optl) | 253 | if (i + optl > tcphdr_len || priv->len + priv->offset > optl) |
| 254 | return; | 254 | goto err; |
| 255 | 255 | ||
| 256 | if (skb_ensure_writable(pkt->skb, | 256 | if (skb_ensure_writable(pkt->skb, |
| 257 | nft_thoff(pkt) + i + priv->len)) | 257 | nft_thoff(pkt) + i + priv->len)) |
| 258 | return; | 258 | goto err; |
| 259 | 259 | ||
| 260 | tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, | 260 | tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, |
| 261 | &tcphdr_len); | 261 | &tcphdr_len); |
| 262 | if (!tcph) | 262 | if (!tcph) |
| 263 | return; | 263 | goto err; |
| 264 | 264 | ||
| 265 | offset = i + priv->offset; | 265 | offset = i + priv->offset; |
| 266 | 266 | ||
| @@ -303,6 +303,9 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr, · 36 unmodified lines | |||
| 303 | 303 | ||
| 304 | return; | 304 | return; |
| 305 | } | 305 | } |
| 306 | return; | ||
| 307 | err: | ||
| 308 | regs->verdict.code = NFT_BREAK; | ||
| 306 | } | 309 | } |
| 307 | 310 | ||
| 308 | static void nft_exthdr_sctp_eval(const struct nft_expr *expr, | 311 | static void nft_exthdr_sctp_eval(const struct nft_expr *expr, |
| @@ -886,7 +886,7 @@ static int nft_pipapo_avx2_lookup_8b_6(unsigned long *map, unsigned long *fill, · 885 unmodified lines | |||
| 886 | NFT_PIPAPO_AVX2_BUCKET_LOAD8(4, lt, 4, pkt[4], bsize); | 886 | NFT_PIPAPO_AVX2_BUCKET_LOAD8(4, lt, 4, pkt[4], bsize); |
| 887 | 887 | ||
| 888 | NFT_PIPAPO_AVX2_AND(5, 0, 1); | 888 | NFT_PIPAPO_AVX2_AND(5, 0, 1); |
| 889 | NFT_PIPAPO_AVX2_BUCKET_LOAD8(6, lt, 6, pkt[5], bsize); | 889 | NFT_PIPAPO_AVX2_BUCKET_LOAD8(6, lt, 5, pkt[5], bsize); |
| 890 | NFT_PIPAPO_AVX2_AND(7, 2, 3); | 890 | NFT_PIPAPO_AVX2_AND(7, 2, 3); |
| 891 | 891 | ||
| 892 | /* Stall */ | 892 | /* Stall */ |
| @@ -1852,6 +1852,11 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) · 1851 unmodified lines | |||
| 1852 | if (msg->msg_flags & MSG_OOB) | 1852 | if (msg->msg_flags & MSG_OOB) |
| 1853 | return -EOPNOTSUPP; | 1853 | return -EOPNOTSUPP; |
| 1854 | 1854 | ||
| 1855 | if (len == 0) { | ||
| 1856 | pr_warn_once("Zero length message leads to an empty skb\n"); | ||
| 1857 | return -ENODATA; | ||
| 1858 | } | ||
| 1859 | |||
| 1855 | err = scm_send(sock, msg, &scm, true); | 1860 | err = scm_send(sock, msg, &scm, true); |
| 1856 | if (err < 0) | 1861 | if (err < 0) |
| 1857 | return err; | 1862 | return err; |
| @@ -636,8 +636,10 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb) · 635 unmodified lines | |||
| 636 | { | 636 | { |
| 637 | struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; | 637 | struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; |
| 638 | 638 | ||
| 639 | nfc_device_iter_exit(iter); | 639 | if (iter) { |
| 640 | kfree(iter); | 640 | nfc_device_iter_exit(iter); |
| 641 | kfree(iter); | ||
| 642 | } | ||
| 641 | 643 | ||
| 642 | return 0; | 644 | return 0; |
| 643 | } | 645 | } |
| @@ -1392,8 +1394,10 @@ static int nfc_genl_dump_ses_done(struct netlink_callback *cb) · 748 unmodified lines | |||
| 1392 | { | 1394 | { |
| 1393 | struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; | 1395 | struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; |
| 1394 | 1396 | ||
| 1395 | nfc_device_iter_exit(iter); | 1397 | if (iter) { |
| 1396 | kfree(iter); | 1398 | nfc_device_iter_exit(iter); |
| 1399 | kfree(iter); | ||
| 1400 | } | ||
| 1397 | 1401 | ||
| 1398 | return 0; | 1402 | return 0; |
| 1399 | } | 1403 | } |
| @@ -500,7 +500,7 @@ void rds_tcp_tune(struct socket *sock) · 499 unmodified lines | |||
| 500 | sk->sk_userlocks |= SOCK_SNDBUF_LOCK; | 500 | sk->sk_userlocks |= SOCK_SNDBUF_LOCK; |
| 501 | } | 501 | } |
| 502 | if (rtn->rcvbuf_size > 0) { | 502 | if (rtn->rcvbuf_size > 0) { |
| 503 | sk->sk_sndbuf = rtn->rcvbuf_size; | 503 | sk->sk_rcvbuf = rtn->rcvbuf_size; |
| 504 | sk->sk_userlocks |= SOCK_RCVBUF_LOCK; | 504 | sk->sk_userlocks |= SOCK_RCVBUF_LOCK; |
| 505 | } | 505 | } |
| 506 | release_sock(sk); | 506 | release_sock(sk); |
| @@ -135,16 +135,20 @@ struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *bundle) · 134 unmodified lines | |||
| 135 | return bundle; | 135 | return bundle; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static void rxrpc_free_bundle(struct rxrpc_bundle *bundle) | ||
| 139 | { | ||
| 140 | rxrpc_put_peer(bundle->params.peer); | ||
| 141 | kfree(bundle); | ||
| 142 | } | ||
| 143 | |||
| 138 | void rxrpc_put_bundle(struct rxrpc_bundle *bundle) | 144 | void rxrpc_put_bundle(struct rxrpc_bundle *bundle) |
| 139 | { | 145 | { |
| 140 | unsigned int d = bundle->debug_id; | 146 | unsigned int d = bundle->debug_id; |
| 141 | unsigned int u = atomic_dec_return(&bundle->usage); | 147 | unsigned int u = atomic_dec_return(&bundle->usage); |
| 142 | 148 | ||
| 143 | _debug("PUT B=%x %u", d, u); | 149 | _debug("PUT B=%x %u", d, u); |
| 144 | if (u == 0) { | 150 | if (u == 0) |
| 145 | rxrpc_put_peer(bundle->params.peer); | 151 | rxrpc_free_bundle(bundle); |
| 146 | kfree(bundle); | ||
| 147 | } | ||
| 148 | } | 152 | } |
| 149 | 153 | ||
| 150 | /* | 154 | /* |
| @@ -328,7 +332,7 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c · 177 unmodified lines | |||
| 328 | return candidate; | 332 | return candidate; |
| 329 | 333 | ||
| 330 | found_bundle_free: | 334 | found_bundle_free: |
| 331 | kfree(candidate); | 335 | rxrpc_free_bundle(candidate); |
| 332 | found_bundle: | 336 | found_bundle: |
| 333 | rxrpc_get_bundle(bundle); | 337 | rxrpc_get_bundle(bundle); |
| 334 | spin_unlock(&local->client_bundles_lock); | 338 | spin_unlock(&local->client_bundles_lock); |
| @@ -299,6 +299,12 @@ static struct rxrpc_peer *rxrpc_create_peer(struct rxrpc_sock *rx, · 298 unmodified lines | |||
| 299 | return peer; | 299 | return peer; |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | static void rxrpc_free_peer(struct rxrpc_peer *peer) | ||
| 303 | { | ||
| 304 | rxrpc_put_local(peer->local); | ||
| 305 | kfree_rcu(peer, rcu); | ||
| 306 | } | ||
| 307 | |||
| 302 | /* | 308 | /* |
| 303 | * Set up a new incoming peer. There shouldn't be any other matching peers | 309 | * Set up a new incoming peer. There shouldn't be any other matching peers |
| 304 | * since we've already done a search in the list from the non-reentrant context | 310 | * since we've already done a search in the list from the non-reentrant context |
| @@ -365,7 +371,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_sock *rx, · 60 unmodified lines | |||
| 365 | spin_unlock_bh(&rxnet->peer_hash_lock); | 371 | spin_unlock_bh(&rxnet->peer_hash_lock); |
| 366 | 372 | ||
| 367 | if (peer) | 373 | if (peer) |
| 368 | kfree(candidate); | 374 | rxrpc_free_peer(candidate); |
| 369 | else | 375 | else |
| 370 | peer = candidate; | 376 | peer = candidate; |
| 371 | } | 377 | } |
| @@ -420,8 +426,7 @@ static void __rxrpc_put_peer(struct rxrpc_peer *peer) · 48 unmodified lines | |||
| 420 | list_del_init(&peer->keepalive_link); | 426 | list_del_init(&peer->keepalive_link); |
| 421 | spin_unlock_bh(&rxnet->peer_hash_lock); | 427 | spin_unlock_bh(&rxnet->peer_hash_lock); |
| 422 | 428 | ||
| 423 | rxrpc_put_local(peer->local); | 429 | rxrpc_free_peer(peer); |
| 424 | kfree_rcu(peer, rcu); | ||
| 425 | } | 430 | } |
| 426 | 431 | ||
| 427 | /* | 432 | /* |
| @@ -457,8 +462,7 @@ void rxrpc_put_peer_locked(struct rxrpc_peer *peer) · 29 unmodified lines | |||
| 457 | if (n == 0) { | 462 | if (n == 0) { |
| 458 | hash_del_rcu(&peer->hash_link); | 463 | hash_del_rcu(&peer->hash_link); |
| 459 | list_del_init(&peer->keepalive_link); | 464 | list_del_init(&peer->keepalive_link); |
| 460 | rxrpc_put_local(peer->local); | 465 | rxrpc_free_peer(peer); |
| 461 | kfree_rcu(peer, rcu); | ||
| 462 | } | 466 | } |
| 463 | } | 467 | } |
| 464 | 468 | ||
| @@ -531,6 +531,7 @@ static void fq_pie_destroy(struct Qdisc *sch) · 530 unmodified lines | |||
| 531 | struct fq_pie_sched_data *q = qdisc_priv(sch); | 531 | struct fq_pie_sched_data *q = qdisc_priv(sch); |
| 532 | 532 | ||
| 533 | tcf_block_put(q->block); | 533 | tcf_block_put(q->block); |
| 534 | q->p_params.tupdate = 0; | ||
| 534 | del_timer_sync(&q->adapt_timer); | 535 | del_timer_sync(&q->adapt_timer); |
| 535 | kvfree(q->flows); | 536 | kvfree(q->flows); |
| 536 | } | 537 | } |
| @@ -195,6 +195,7 @@ int smc_close_active(struct smc_sock *smc) · 194 unmodified lines | |||
| 195 | int old_state; | 195 | int old_state; |
| 196 | long timeout; | 196 | long timeout; |
| 197 | int rc = 0; | 197 | int rc = 0; |
| 198 | int rc1 = 0; | ||
| 198 | 199 | ||
| 199 | timeout = current->flags & PF_EXITING ? | 200 | timeout = current->flags & PF_EXITING ? |
| 200 | 0 : sock_flag(sk, SOCK_LINGER) ? | 201 | 0 : sock_flag(sk, SOCK_LINGER) ? |
| @@ -232,8 +233,11 @@ again: · 31 unmodified lines | |||
| 232 | /* actively shutdown clcsock before peer close it, | 233 | /* actively shutdown clcsock before peer close it, |
| 233 | * prevent peer from entering TIME_WAIT state. | 234 | * prevent peer from entering TIME_WAIT state. |
| 234 | */ | 235 | */ |
| 235 | if (smc->clcsock && smc->clcsock->sk) | 236 | if (smc->clcsock && smc->clcsock->sk) { |
| 236 | rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); | 237 | rc1 = kernel_sock_shutdown(smc->clcsock, |
| 238 | SHUT_RDWR); | ||
| 239 | rc = rc ? rc : rc1; | ||
| 240 | } | ||
| 237 | } else { | 241 | } else { |
| 238 | /* peer event has changed the state */ | 242 | /* peer event has changed the state */ |
| 239 | goto again; | 243 | goto again; |
| @@ -625,18 +625,17 @@ int smcd_nl_get_lgr(struct sk_buff *skb, struct netlink_callback *cb) · 624 unmodified lines | |||
| 625 | void smc_lgr_cleanup_early(struct smc_connection *conn) | 625 | void smc_lgr_cleanup_early(struct smc_connection *conn) |
| 626 | { | 626 | { |
| 627 | struct smc_link_group *lgr = conn->lgr; | 627 | struct smc_link_group *lgr = conn->lgr; |
| 628 | struct list_head *lgr_list; | ||
| 629 | spinlock_t *lgr_lock; | 628 | spinlock_t *lgr_lock; |
| 630 | 629 | ||
| 631 | if (!lgr) | 630 | if (!lgr) |
| 632 | return; | 631 | return; |
| 633 | 632 | ||
| 634 | smc_conn_free(conn); | 633 | smc_conn_free(conn); |
| 635 | lgr_list = smc_lgr_list_head(lgr, &lgr_lock); | 634 | smc_lgr_list_head(lgr, &lgr_lock); |
| 636 | spin_lock_bh(lgr_lock); | 635 | spin_lock_bh(lgr_lock); |
| 637 | /* do not use this link group for new connections */ | 636 | /* do not use this link group for new connections */ |
| 638 | if (!list_empty(lgr_list)) | 637 | if (!list_empty(&lgr->list)) |
| 639 | list_del_init(lgr_list); | 638 | list_del_init(&lgr->list); |
| 640 | spin_unlock_bh(lgr_lock); | 639 | spin_unlock_bh(lgr_lock); |
| 641 | __smc_lgr_terminate(lgr, true); | 640 | __smc_lgr_terminate(lgr, true); |
| 642 | } | 641 | } |
| @@ -521,7 +521,7 @@ static int tls_do_encryption(struct sock *sk, · 520 unmodified lines | |||
| 521 | memcpy(&rec->iv_data[iv_offset], tls_ctx->tx.iv, | 521 | memcpy(&rec->iv_data[iv_offset], tls_ctx->tx.iv, |
| 522 | prot->iv_size + prot->salt_size); | 522 | prot->iv_size + prot->salt_size); |
| 523 | 523 | ||
| 524 | xor_iv_with_seq(prot, rec->iv_data, tls_ctx->tx.rec_seq); | 524 | xor_iv_with_seq(prot, rec->iv_data + iv_offset, tls_ctx->tx.rec_seq); |
| 525 | 525 | ||
| 526 | sge->offset += prot->prepend_size; | 526 | sge->offset += prot->prepend_size; |
| 527 | sge->length -= prot->prepend_size; | 527 | sge->length -= prot->prepend_size; |
| @@ -1499,7 +1499,7 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb, · 971 unmodified lines | |||
| 1499 | else | 1499 | else |
| 1500 | memcpy(iv + iv_offset, tls_ctx->rx.iv, prot->salt_size); | 1500 | memcpy(iv + iv_offset, tls_ctx->rx.iv, prot->salt_size); |
| 1501 | 1501 | ||
| 1502 | xor_iv_with_seq(prot, iv, tls_ctx->rx.rec_seq); | 1502 | xor_iv_with_seq(prot, iv + iv_offset, tls_ctx->rx.rec_seq); |
| 1503 | 1503 | ||
| 1504 | /* Prepare AAD */ | 1504 | /* Prepare AAD */ |
| 1505 | tls_make_aad(aad, rxm->full_len - prot->overhead_size + | 1505 | tls_make_aad(aad, rxm->full_len - prot->overhead_size + |
| @@ -4,6 +4,7 @@ obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct.o · 3 unmodified lines | |||
| 4 | obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-too.o | 4 | obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-too.o |
| 5 | obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-modify.o | 5 | obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-modify.o |
| 6 | obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace-direct-multi.o | 6 | obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace-direct-multi.o |
| 7 | obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace-direct-multi-modify.o | ||
| 7 | 8 | ||
| 8 | CFLAGS_sample-trace-array.o := -I$(src) | 9 | CFLAGS_sample-trace-array.o := -I$(src) |
| 9 | obj-$(CONFIG_SAMPLE_TRACE_ARRAY) += sample-trace-array.o | 10 | obj-$(CONFIG_SAMPLE_TRACE_ARRAY) += sample-trace-array.o |
| @@ -0,0 +1,152 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | #include <linux/module.h> | ||
| 3 | #include <linux/kthread.h> | ||
| 4 | #include <linux/ftrace.h> | ||
| 5 | #include <asm/asm-offsets.h> | ||
| 6 | |||
| 7 | void my_direct_func1(unsigned long ip) | ||
| 8 | { | ||
| 9 | trace_printk("my direct func1 ip %lx\n", ip); | ||
| 10 | } | ||
| 11 | |||
| 12 | void my_direct_func2(unsigned long ip) | ||
| 13 | { | ||
| 14 | trace_printk("my direct func2 ip %lx\n", ip); | ||
| 15 | } | ||
| 16 | |||
| 17 | extern void my_tramp1(void *); | ||
| 18 | extern void my_tramp2(void *); | ||
| 19 | |||
| 20 | #ifdef CONFIG_X86_64 | ||
| 21 | |||
| 22 | asm ( | ||
| 23 | " .pushsection .text, \"ax\", @progbits\n" | ||
| 24 | " .type my_tramp1, @function\n" | ||
| 25 | " .globl my_tramp1\n" | ||
| 26 | " my_tramp1:" | ||
| 27 | " pushq %rbp\n" | ||
| 28 | " movq %rsp, %rbp\n" | ||
| 29 | " pushq %rdi\n" | ||
| 30 | " movq 8(%rbp), %rdi\n" | ||
| 31 | " call my_direct_func1\n" | ||
| 32 | " popq %rdi\n" | ||
| 33 | " leave\n" | ||
| 34 | " ret\n" | ||
| 35 | " .size my_tramp1, .-my_tramp1\n" | ||
| 36 | " .type my_tramp2, @function\n" | ||
| 37 | "\n" | ||
| 38 | " .globl my_tramp2\n" | ||
| 39 | " my_tramp2:" | ||
| 40 | " pushq %rbp\n" | ||
| 41 | " movq %rsp, %rbp\n" | ||
| 42 | " pushq %rdi\n" | ||
| 43 | " movq 8(%rbp), %rdi\n" | ||
| 44 | " call my_direct_func2\n" | ||
| 45 | " popq %rdi\n" | ||
| 46 | " leave\n" | ||
| 47 | " ret\n" | ||
| 48 | " .size my_tramp2, .-my_tramp2\n" | ||
| 49 | " .popsection\n" | ||
| 50 | ); | ||
| 51 | |||
| 52 | #endif /* CONFIG_X86_64 */ | ||
| 53 | |||
| 54 | #ifdef CONFIG_S390 | ||
| 55 | |||
| 56 | asm ( | ||
| 57 | " .pushsection .text, \"ax\", @progbits\n" | ||
| 58 | " .type my_tramp1, @function\n" | ||
| 59 | " .globl my_tramp1\n" | ||
| 60 | " my_tramp1:" | ||
| 61 | " lgr %r1,%r15\n" | ||
| 62 | " stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n" | ||
| 63 | " stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n" | ||
| 64 | " aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n" | ||
| 65 | " stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n" | ||
| 66 | " lgr %r2,%r0\n" | ||
| 67 | " brasl %r14,my_direct_func1\n" | ||
| 68 | " aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n" | ||
| 69 | " lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n" | ||
| 70 | " lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n" | ||
| 71 | " lgr %r1,%r0\n" | ||
| 72 | " br %r1\n" | ||
| 73 | " .size my_tramp1, .-my_tramp1\n" | ||
| 74 | "\n" | ||
| 75 | " .type my_tramp2, @function\n" | ||
| 76 | " .globl my_tramp2\n" | ||
| 77 | " my_tramp2:" | ||
| 78 | " lgr %r1,%r15\n" | ||
| 79 | " stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n" | ||
| 80 | " stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n" | ||
| 81 | " aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n" | ||
| 82 | " stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n" | ||
| 83 | " lgr %r2,%r0\n" | ||
| 84 | " brasl %r14,my_direct_func2\n" | ||
| 85 | " aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n" | ||
| 86 | " lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n" | ||
| 87 | " lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n" | ||
| 88 | " lgr %r1,%r0\n" | ||
| 89 | " br %r1\n" | ||
| 90 | " .size my_tramp2, .-my_tramp2\n" | ||
| 91 | " .popsection\n" | ||
| 92 | ); | ||
| 93 | |||
| 94 | #endif /* CONFIG_S390 */ | ||
| 95 | |||
| 96 | static unsigned long my_tramp = (unsigned long)my_tramp1; | ||
| 97 | static unsigned long tramps[2] = { | ||
| 98 | (unsigned long)my_tramp1, | ||
| 99 | (unsigned long)my_tramp2, | ||
| 100 | }; | ||
| 101 | |||
| 102 | static struct ftrace_ops direct; | ||
| 103 | |||
| 104 | static int simple_thread(void *arg) | ||
| 105 | { | ||
| 106 | static int t; | ||
| 107 | int ret = 0; | ||
| 108 | |||
| 109 | while (!kthread_should_stop()) { | ||
| 110 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 111 | schedule_timeout(2 * HZ); | ||
| 112 | |||
| 113 | if (ret) | ||
| 114 | continue; | ||
| 115 | t ^= 1; | ||
| 116 | ret = modify_ftrace_direct_multi(&direct, tramps[t]); | ||
| 117 | if (!ret) | ||
| 118 | my_tramp = tramps[t]; | ||
| 119 | WARN_ON_ONCE(ret); | ||
| 120 | } | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | static struct task_struct *simple_tsk; | ||
| 126 | |||
| 127 | static int __init ftrace_direct_multi_init(void) | ||
| 128 | { | ||
| 129 | int ret; | ||
| 130 | |||
| 131 | ftrace_set_filter_ip(&direct, (unsigned long) wake_up_process, 0, 0); | ||
| 132 | ftrace_set_filter_ip(&direct, (unsigned long) schedule, 0, 0); | ||
| 133 | |||
| 134 | ret = register_ftrace_direct_multi(&direct, my_tramp); | ||
| 135 | |||
| 136 | if (!ret) | ||
| 137 | simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn"); | ||
| 138 | return ret; | ||
| 139 | } | ||
| 140 | |||
| 141 | static void __exit ftrace_direct_multi_exit(void) | ||
| 142 | { | ||
| 143 | kthread_stop(simple_tsk); | ||
| 144 | unregister_ftrace_direct_multi(&direct, my_tramp); | ||
| 145 | } | ||
| 146 | |||
| 147 | module_init(ftrace_direct_multi_init); | ||
| 148 | module_exit(ftrace_direct_multi_exit); | ||
| 149 | |||
| 150 | MODULE_AUTHOR("Jiri Olsa"); | ||
| 151 | MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct_multi()"); | ||
| 152 | MODULE_LICENSE("GPL"); | ||
| @@ -264,6 +264,7 @@ static int copy_ctl_value_to_user(void __user *userdata, · 263 unmodified lines | |||
| 264 | struct snd_ctl_elem_value *data, | 264 | struct snd_ctl_elem_value *data, |
| 265 | int type, int count) | 265 | int type, int count) |
| 266 | { | 266 | { |
| 267 | struct snd_ctl_elem_value32 __user *data32 = userdata; | ||
| 267 | int i, size; | 268 | int i, size; |
| 268 | 269 | ||
| 269 | if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || | 270 | if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || |
| @@ -280,6 +281,8 @@ static int copy_ctl_value_to_user(void __user *userdata, · 10 unmodified lines | |||
| 280 | if (copy_to_user(valuep, data->value.bytes.data, size)) | 281 | if (copy_to_user(valuep, data->value.bytes.data, size)) |
| 281 | return -EFAULT; | 282 | return -EFAULT; |
| 282 | } | 283 | } |
| 284 | if (copy_to_user(&data32->id, &data->id, sizeof(data32->id))) | ||
| 285 | return -EFAULT; | ||
| 283 | return 0; | 286 | return 0; |
| 284 | } | 287 | } |
| 285 | 288 | ||
| @@ -147,7 +147,7 @@ snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params, · 146 unmodified lines | |||
| 147 | * | 147 | * |
| 148 | * Return the maximum value for field PAR. | 148 | * Return the maximum value for field PAR. |
| 149 | */ | 149 | */ |
| 150 | static unsigned int | 150 | static int |
| 151 | snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, | 151 | snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, |
| 152 | snd_pcm_hw_param_t var, int *dir) | 152 | snd_pcm_hw_param_t var, int *dir) |
| 153 | { | 153 | { |
| @@ -682,18 +682,24 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, · 528 unmodified lines | |||
| 682 | struct snd_pcm_hw_params *oss_params, | 682 | struct snd_pcm_hw_params *oss_params, |
| 683 | struct snd_pcm_hw_params *slave_params) | 683 | struct snd_pcm_hw_params *slave_params) |
| 684 | { | 684 | { |
| 685 | size_t s; | 685 | ssize_t s; |
| 686 | size_t oss_buffer_size, oss_period_size, oss_periods; | 686 | ssize_t oss_buffer_size; |
| 687 | size_t min_period_size, max_period_size; | 687 | ssize_t oss_period_size, oss_periods; |
| 688 | ssize_t min_period_size, max_period_size; | ||
| 688 | struct snd_pcm_runtime *runtime = substream->runtime; | 689 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 689 | size_t oss_frame_size; | 690 | size_t oss_frame_size; |
| 690 | 691 | ||
| 691 | oss_frame_size = snd_pcm_format_physical_width(params_format(oss_params)) * | 692 | oss_frame_size = snd_pcm_format_physical_width(params_format(oss_params)) * |
| 692 | params_channels(oss_params) / 8; | 693 | params_channels(oss_params) / 8; |
| 693 | 694 | ||
| 695 | oss_buffer_size = snd_pcm_hw_param_value_max(slave_params, | ||
| 696 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | ||
| 697 | NULL); | ||
| 698 | if (oss_buffer_size <= 0) | ||
| 699 | return -EINVAL; | ||
| 694 | oss_buffer_size = snd_pcm_plug_client_size(substream, | 700 | oss_buffer_size = snd_pcm_plug_client_size(substream, |
| 695 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; | 701 | oss_buffer_size * oss_frame_size); |
| 696 | if (!oss_buffer_size) | 702 | if (oss_buffer_size <= 0) |
| 697 | return -EINVAL; | 703 | return -EINVAL; |
| 698 | oss_buffer_size = rounddown_pow_of_two(oss_buffer_size); | 704 | oss_buffer_size = rounddown_pow_of_two(oss_buffer_size); |
| 699 | if (atomic_read(&substream->mmap_count)) { | 705 | if (atomic_read(&substream->mmap_count)) { |
| @@ -730,7 +736,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, · 30 unmodified lines | |||
| 730 | 736 | ||
| 731 | min_period_size = snd_pcm_plug_client_size(substream, | 737 | min_period_size = snd_pcm_plug_client_size(substream, |
| 732 | snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); | 738 | snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); |
| 733 | if (min_period_size) { | 739 | if (min_period_size > 0) { |
| 734 | min_period_size *= oss_frame_size; | 740 | min_period_size *= oss_frame_size; |
| 735 | min_period_size = roundup_pow_of_two(min_period_size); | 741 | min_period_size = roundup_pow_of_two(min_period_size); |
| 736 | if (oss_period_size < min_period_size) | 742 | if (oss_period_size < min_period_size) |
| @@ -739,7 +745,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, · 2 unmodified lines | |||
| 739 | 745 | ||
| 740 | max_period_size = snd_pcm_plug_client_size(substream, | 746 | max_period_size = snd_pcm_plug_client_size(substream, |
| 741 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); | 747 | snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); |
| 742 | if (max_period_size) { | 748 | if (max_period_size > 0) { |
| 743 | max_period_size *= oss_frame_size; | 749 | max_period_size *= oss_frame_size; |
| 744 | max_period_size = rounddown_pow_of_two(max_period_size); | 750 | max_period_size = rounddown_pow_of_two(max_period_size); |
| 745 | if (oss_period_size > max_period_size) | 751 | if (oss_period_size > max_period_size) |
| @@ -752,7 +758,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, · 6 unmodified lines | |||
| 752 | oss_periods = substream->oss.setup.periods; | 758 | oss_periods = substream->oss.setup.periods; |
| 753 | 759 | ||
| 754 | s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL); | 760 | s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL); |
| 755 | if (runtime->oss.maxfrags && s > runtime->oss.maxfrags) | 761 | if (s > 0 && runtime->oss.maxfrags && s > runtime->oss.maxfrags) |
| 756 | s = runtime->oss.maxfrags; | 762 | s = runtime->oss.maxfrags; |
| 757 | if (oss_periods > s) | 763 | if (oss_periods > s) |
| 758 | oss_periods = s; | 764 | oss_periods = s; |
| @@ -878,8 +884,15 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) · 119 unmodified lines | |||
| 878 | err = -EINVAL; | 884 | err = -EINVAL; |
| 879 | goto failure; | 885 | goto failure; |
| 880 | } | 886 | } |
| 881 | choose_rate(substream, sparams, runtime->oss.rate); | 887 | |
| 882 | snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, NULL); | 888 | err = choose_rate(substream, sparams, runtime->oss.rate); |
| 889 | if (err < 0) | ||
| 890 | goto failure; | ||
| 891 | err = snd_pcm_hw_param_near(substream, sparams, | ||
| 892 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
| 893 | runtime->oss.channels, NULL); | ||
| 894 | if (err < 0) | ||
| 895 | goto failure; | ||
| 883 | 896 | ||
| 884 | format = snd_pcm_oss_format_from(runtime->oss.format); | 897 | format = snd_pcm_oss_format_from(runtime->oss.format); |
| 885 | 898 | ||
| @@ -1956,7 +1969,7 @@ static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsign · 1070 unmodified lines | |||
| 1956 | if (runtime->oss.subdivision || runtime->oss.fragshift) | 1969 | if (runtime->oss.subdivision || runtime->oss.fragshift) |
| 1957 | return -EINVAL; | 1970 | return -EINVAL; |
| 1958 | fragshift = val & 0xffff; | 1971 | fragshift = val & 0xffff; |
| 1959 | if (fragshift >= 31) | 1972 | if (fragshift >= 25) /* should be large enough */ |
| 1960 | return -EINVAL; | 1973 | return -EINVAL; |
| 1961 | runtime->oss.fragshift = fragshift; | 1974 | runtime->oss.fragshift = fragshift; |
| 1962 | runtime->oss.maxfrags = (val >> 16) & 0xffff; | 1975 | runtime->oss.maxfrags = (val >> 16) & 0xffff; |
| @@ -252,6 +252,11 @@ static const struct config_entry config_table[] = { · 251 unmodified lines | |||
| 252 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | 252 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
| 253 | .device = 0x02c8, | 253 | .device = 0x02c8, |
| 254 | }, | 254 | }, |
| 255 | { | ||
| 256 | .flags = FLAG_SOF, | ||
| 257 | .device = 0x02c8, | ||
| 258 | .codec_hid = "ESSX8336", | ||
| 259 | }, | ||
| 255 | /* Cometlake-H */ | 260 | /* Cometlake-H */ |
| 256 | { | 261 | { |
| 257 | .flags = FLAG_SOF, | 262 | .flags = FLAG_SOF, |
| @@ -276,6 +281,11 @@ static const struct config_entry config_table[] = { · 18 unmodified lines | |||
| 276 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | 281 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
| 277 | .device = 0x06c8, | 282 | .device = 0x06c8, |
| 278 | }, | 283 | }, |
| 284 | { | ||
| 285 | .flags = FLAG_SOF, | ||
| 286 | .device = 0x06c8, | ||
| 287 | .codec_hid = "ESSX8336", | ||
| 288 | }, | ||
| 279 | #endif | 289 | #endif |
| 280 | 290 | ||
| 281 | /* Icelake */ | 291 | /* Icelake */ |
| @@ -335,7 +335,10 @@ enum { · 334 unmodified lines | |||
| 335 | ((pci)->device == 0x0c0c) || \ | 335 | ((pci)->device == 0x0c0c) || \ |
| 336 | ((pci)->device == 0x0d0c) || \ | 336 | ((pci)->device == 0x0d0c) || \ |
| 337 | ((pci)->device == 0x160c) || \ | 337 | ((pci)->device == 0x160c) || \ |
| 338 | ((pci)->device == 0x490d)) | 338 | ((pci)->device == 0x490d) || \ |
| 339 | ((pci)->device == 0x4f90) || \ | ||
| 340 | ((pci)->device == 0x4f91) || \ | ||
| 341 | ((pci)->device == 0x4f92)) | ||
| 339 | 342 | ||
| 340 | #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) | 343 | #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) |
| 341 | 344 | ||
| @@ -2473,6 +2476,13 @@ static const struct pci_device_id azx_ids[] = { · 2131 unmodified lines | |||
| 2473 | /* DG1 */ | 2476 | /* DG1 */ |
| 2474 | { PCI_DEVICE(0x8086, 0x490d), | 2477 | { PCI_DEVICE(0x8086, 0x490d), |
| 2475 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | 2478 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, |
| 2479 | /* DG2 */ | ||
| 2480 | { PCI_DEVICE(0x8086, 0x4f90), | ||
| 2481 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | ||
| 2482 | { PCI_DEVICE(0x8086, 0x4f91), | ||
| 2483 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | ||
| 2484 | { PCI_DEVICE(0x8086, 0x4f92), | ||
| 2485 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | ||
| 2476 | /* Alderlake-S */ | 2486 | /* Alderlake-S */ |
| 2477 | { PCI_DEVICE(0x8086, 0x7ad0), | 2487 | { PCI_DEVICE(0x8086, 0x7ad0), |
| 2478 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | 2488 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, |
| @@ -438,6 +438,15 @@ int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, · 437 unmodified lines | |||
| 438 | #define for_each_hda_codec_node(nid, codec) \ | 438 | #define for_each_hda_codec_node(nid, codec) \ |
| 439 | for ((nid) = (codec)->core.start_nid; (nid) < (codec)->core.end_nid; (nid)++) | 439 | for ((nid) = (codec)->core.start_nid; (nid) < (codec)->core.end_nid; (nid)++) |
| 440 | 440 | ||
| 441 | /* Set the codec power_state flag to indicate to allow unsol event handling; | ||
| 442 | * see hda_codec_unsol_event() in hda_bind.c. Calling this might confuse the | ||
| 443 | * state tracking, so use with care. | ||
| 444 | */ | ||
| 445 | static inline void snd_hda_codec_allow_unsol_events(struct hda_codec *codec) | ||
| 446 | { | ||
| 447 | codec->core.dev.power.power_state = PMSG_ON; | ||
| 448 | } | ||
| 449 | |||
| 441 | /* | 450 | /* |
| 442 | * get widget capabilities | 451 | * get widget capabilities |
| 443 | */ | 452 | */ |
| @@ -750,6 +750,11 @@ static void cs42l42_resume(struct sub_codec *cs42l42) · 749 unmodified lines | |||
| 750 | if (cs42l42->full_scale_vol) | 750 | if (cs42l42->full_scale_vol) |
| 751 | cs8409_i2c_write(cs42l42, 0x2001, 0x01); | 751 | cs8409_i2c_write(cs42l42, 0x2001, 0x01); |
| 752 | 752 | ||
| 753 | /* we have to explicitly allow unsol event handling even during the | ||
| 754 | * resume phase so that the jack event is processed properly | ||
| 755 | */ | ||
| 756 | snd_hda_codec_allow_unsol_events(cs42l42->codec); | ||
| 757 | |||
| 753 | cs42l42_enable_jack_detect(cs42l42); | 758 | cs42l42_enable_jack_detect(cs42l42); |
| 754 | } | 759 | } |
| 755 | 760 | ||
| @@ -4380,10 +4380,11 @@ HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi), · 4379 unmodified lines | |||
| 4380 | HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi), | 4380 | HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi), |
| 4381 | HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI", patch_i915_tgl_hdmi), | 4381 | HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI", patch_i915_tgl_hdmi), |
| 4382 | HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI", patch_i915_tgl_hdmi), | 4382 | HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI", patch_i915_tgl_hdmi), |
| 4383 | HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_tgl_hdmi), | ||
| 4384 | HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi), | 4383 | HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi), |
| 4384 | HDA_CODEC_ENTRY(0x80862819, "DG2 HDMI", patch_i915_tgl_hdmi), | ||
| 4385 | HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi), | 4385 | HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi), |
| 4386 | HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi), | 4386 | HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi), |
| 4387 | HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_tgl_hdmi), | ||
| 4387 | HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), | 4388 | HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), |
| 4388 | HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), | 4389 | HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), |
| 4389 | HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi), | 4390 | HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi), |
| @@ -6503,22 +6503,26 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec, · 6502 unmodified lines | |||
| 6503 | /* for alc285_fixup_ideapad_s740_coef() */ | 6503 | /* for alc285_fixup_ideapad_s740_coef() */ |
| 6504 | #include "ideapad_s740_helper.c" | 6504 | #include "ideapad_s740_helper.c" |
| 6505 | 6505 | ||
| 6506 | static void alc256_fixup_tongfang_reset_persistent_settings(struct hda_codec *codec, | 6506 | static const struct coef_fw alc256_fixup_set_coef_defaults_coefs[] = { |
| 6507 | const struct hda_fixup *fix, | 6507 | WRITE_COEF(0x10, 0x0020), WRITE_COEF(0x24, 0x0000), |
| 6508 | int action) | 6508 | WRITE_COEF(0x26, 0x0000), WRITE_COEF(0x29, 0x3000), |
| 6509 | WRITE_COEF(0x37, 0xfe05), WRITE_COEF(0x45, 0x5089), | ||
| 6510 | {} | ||
| 6511 | }; | ||
| 6512 | |||
| 6513 | static void alc256_fixup_set_coef_defaults(struct hda_codec *codec, | ||
| 6514 | const struct hda_fixup *fix, | ||
| 6515 | int action) | ||
| 6509 | { | 6516 | { |
| 6510 | /* | 6517 | /* |
| 6511 | * A certain other OS sets these coeffs to different values. On at least one TongFang | 6518 | * A certain other OS sets these coeffs to different values. On at least |
| 6512 | * barebone these settings might survive even a cold reboot. So to restore a clean slate the | 6519 | * one TongFang barebone these settings might survive even a cold |
| 6513 | * values are explicitly reset to default here. Without this, the external microphone is | 6520 | * reboot. So to restore a clean slate the values are explicitly reset |
| 6514 | * always in a plugged-in state, while the internal microphone is always in an unplugged | 6521 | * to default here. Without this, the external microphone is always in a |
| 6515 | * state, breaking the ability to use the internal microphone. | 6522 | * plugged-in state, while the internal microphone is always in an |
| 6516 | */ | 6523 | * unplugged state, breaking the ability to use the internal microphone. |
| 6517 | alc_write_coef_idx(codec, 0x24, 0x0000); | 6524 | */ |
| 6518 | alc_write_coef_idx(codec, 0x26, 0x0000); | 6525 | alc_process_coef_fw(codec, alc256_fixup_set_coef_defaults_coefs); |
| 6519 | alc_write_coef_idx(codec, 0x29, 0x3000); | ||
| 6520 | alc_write_coef_idx(codec, 0x37, 0xfe05); | ||
| 6521 | alc_write_coef_idx(codec, 0x45, 0x5089); | ||
| 6522 | } | 6526 | } |
| 6523 | 6527 | ||
| 6524 | static const struct coef_fw alc233_fixup_no_audio_jack_coefs[] = { | 6528 | static const struct coef_fw alc233_fixup_no_audio_jack_coefs[] = { |
| @@ -6759,7 +6763,7 @@ enum { · 234 unmodified lines | |||
| 6759 | ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE, | 6763 | ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE, |
| 6760 | ALC287_FIXUP_YOGA7_14ITL_SPEAKERS, | 6764 | ALC287_FIXUP_YOGA7_14ITL_SPEAKERS, |
| 6761 | ALC287_FIXUP_13S_GEN2_SPEAKERS, | 6765 | ALC287_FIXUP_13S_GEN2_SPEAKERS, |
| 6762 | ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS, | 6766 | ALC256_FIXUP_SET_COEF_DEFAULTS, |
| 6763 | ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE, | 6767 | ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE, |
| 6764 | ALC233_FIXUP_NO_AUDIO_JACK, | 6768 | ALC233_FIXUP_NO_AUDIO_JACK, |
| 6765 | }; | 6769 | }; |
| @@ -8465,9 +8469,9 @@ static const struct hda_fixup alc269_fixups[] = { · 1699 unmodified lines | |||
| 8465 | .chained = true, | 8469 | .chained = true, |
| 8466 | .chain_id = ALC269_FIXUP_HEADSET_MODE, | 8470 | .chain_id = ALC269_FIXUP_HEADSET_MODE, |
| 8467 | }, | 8471 | }, |
| 8468 | [ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS] = { | 8472 | [ALC256_FIXUP_SET_COEF_DEFAULTS] = { |
| 8469 | .type = HDA_FIXUP_FUNC, | 8473 | .type = HDA_FIXUP_FUNC, |
| 8470 | .v.func = alc256_fixup_tongfang_reset_persistent_settings, | 8474 | .v.func = alc256_fixup_set_coef_defaults, |
| 8471 | }, | 8475 | }, |
| 8472 | [ALC245_FIXUP_HP_GPIO_LED] = { | 8476 | [ALC245_FIXUP_HP_GPIO_LED] = { |
| 8473 | .type = HDA_FIXUP_FUNC, | 8477 | .type = HDA_FIXUP_FUNC, |
| @@ -8929,7 +8933,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 455 unmodified lines | |||
| 8929 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ | 8933 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ |
| 8930 | SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), | 8934 | SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), |
| 8931 | SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), | 8935 | SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), |
| 8932 | SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS), | 8936 | SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_SET_COEF_DEFAULTS), |
| 8933 | SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC), | 8937 | SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC), |
| 8934 | SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE), | 8938 | SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 8935 | SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), | 8939 | SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), |
| @@ -10231,6 +10235,27 @@ static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec, · 1295 unmodified lines | |||
| 10231 | } | 10235 | } |
| 10232 | } | 10236 | } |
| 10233 | 10237 | ||
| 10238 | static void alc897_hp_automute_hook(struct hda_codec *codec, | ||
| 10239 | struct hda_jack_callback *jack) | ||
| 10240 | { | ||
| 10241 | struct alc_spec *spec = codec->spec; | ||
| 10242 | int vref; | ||
| 10243 | |||
| 10244 | snd_hda_gen_hp_automute(codec, jack); | ||
| 10245 | vref = spec->gen.hp_jack_present ? (PIN_HP | AC_PINCTL_VREF_100) : PIN_HP; | ||
| 10246 | snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
| 10247 | vref); | ||
| 10248 | } | ||
| 10249 | |||
| 10250 | static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec, | ||
| 10251 | const struct hda_fixup *fix, int action) | ||
| 10252 | { | ||
| 10253 | struct alc_spec *spec = codec->spec; | ||
| 10254 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
| 10255 | spec->gen.hp_automute_hook = alc897_hp_automute_hook; | ||
| 10256 | } | ||
| 10257 | } | ||
| 10258 | |||
| 10234 | static const struct coef_fw alc668_coefs[] = { | 10259 | static const struct coef_fw alc668_coefs[] = { |
| 10235 | WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0), | 10260 | WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0), |
| 10236 | WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80), | 10261 | WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80), |
| @@ -10311,6 +10336,8 @@ enum { · 74 unmodified lines | |||
| 10311 | ALC668_FIXUP_ASUS_NO_HEADSET_MIC, | 10336 | ALC668_FIXUP_ASUS_NO_HEADSET_MIC, |
| 10312 | ALC668_FIXUP_HEADSET_MIC, | 10337 | ALC668_FIXUP_HEADSET_MIC, |
| 10313 | ALC668_FIXUP_MIC_DET_COEF, | 10338 | ALC668_FIXUP_MIC_DET_COEF, |
| 10339 | ALC897_FIXUP_LENOVO_HEADSET_MIC, | ||
| 10340 | ALC897_FIXUP_HEADSET_MIC_PIN, | ||
| 10314 | }; | 10341 | }; |
| 10315 | 10342 | ||
| 10316 | static const struct hda_fixup alc662_fixups[] = { | 10343 | static const struct hda_fixup alc662_fixups[] = { |
| @@ -10717,6 +10744,19 @@ static const struct hda_fixup alc662_fixups[] = { · 400 unmodified lines | |||
| 10717 | {} | 10744 | {} |
| 10718 | }, | 10745 | }, |
| 10719 | }, | 10746 | }, |
| 10747 | [ALC897_FIXUP_LENOVO_HEADSET_MIC] = { | ||
| 10748 | .type = HDA_FIXUP_FUNC, | ||
| 10749 | .v.func = alc897_fixup_lenovo_headset_mic, | ||
| 10750 | }, | ||
| 10751 | [ALC897_FIXUP_HEADSET_MIC_PIN] = { | ||
| 10752 | .type = HDA_FIXUP_PINS, | ||
| 10753 | .v.pins = (const struct hda_pintbl[]) { | ||
| 10754 | { 0x1a, 0x03a11050 }, | ||
| 10755 | { } | ||
| 10756 | }, | ||
| 10757 | .chained = true, | ||
| 10758 | .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MIC | ||
| 10759 | }, | ||
| 10720 | }; | 10760 | }; |
| 10721 | 10761 | ||
| 10722 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 10762 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
| @@ -10761,6 +10801,10 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { · 38 unmodified lines | |||
| 10761 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 10801 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
| 10762 | SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), | 10802 | SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), |
| 10763 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS), | 10803 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS), |
| 10804 | SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN), | ||
| 10805 | SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN), | ||
| 10806 | SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN), | ||
| 10807 | SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN), | ||
| 10764 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 10808 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
| 10765 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), | 10809 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), |
| 10766 | SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO), | 10810 | SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO), |
| @@ -146,10 +146,11 @@ static int snd_acp6x_probe(struct pci_dev *pci, · 145 unmodified lines | |||
| 146 | { | 146 | { |
| 147 | struct acp6x_dev_data *adata; | 147 | struct acp6x_dev_data *adata; |
| 148 | struct platform_device_info pdevinfo[ACP6x_DEVS]; | 148 | struct platform_device_info pdevinfo[ACP6x_DEVS]; |
| 149 | int ret, index; | 149 | int index = 0; |
| 150 | int val = 0x00; | 150 | int val = 0x00; |
| 151 | u32 addr; | 151 | u32 addr; |
| 152 | unsigned int irqflags; | 152 | unsigned int irqflags; |
| 153 | int ret; | ||
| 153 | 154 | ||
| 154 | irqflags = IRQF_SHARED; | 155 | irqflags = IRQF_SHARED; |
| 155 | /* Yellow Carp device check */ | 156 | /* Yellow Carp device check */ |
| @@ -42,34 +42,6 @@ static const struct spi_device_id cs35l41_id_spi[] = { · 41 unmodified lines | |||
| 42 | 42 | ||
| 43 | MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); | 43 | MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); |
| 44 | 44 | ||
| 45 | static void cs35l41_spi_otp_setup(struct cs35l41_private *cs35l41, | ||
| 46 | bool is_pre_setup, unsigned int *freq) | ||
| 47 | { | ||
| 48 | struct spi_device *spi; | ||
| 49 | u32 orig_spi_freq; | ||
| 50 | |||
| 51 | spi = to_spi_device(cs35l41->dev); | ||
| 52 | |||
| 53 | if (!spi) { | ||
| 54 | dev_err(cs35l41->dev, "%s: No SPI device\n", __func__); | ||
| 55 | return; | ||
| 56 | } | ||
| 57 | |||
| 58 | if (is_pre_setup) { | ||
| 59 | orig_spi_freq = spi->max_speed_hz; | ||
| 60 | if (orig_spi_freq > CS35L41_SPI_MAX_FREQ_OTP) { | ||
| 61 | spi->max_speed_hz = CS35L41_SPI_MAX_FREQ_OTP; | ||
| 62 | spi_setup(spi); | ||
| 63 | } | ||
| 64 | *freq = orig_spi_freq; | ||
| 65 | } else { | ||
| 66 | if (spi->max_speed_hz != *freq) { | ||
| 67 | spi->max_speed_hz = *freq; | ||
| 68 | spi_setup(spi); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | static int cs35l41_spi_probe(struct spi_device *spi) | 45 | static int cs35l41_spi_probe(struct spi_device *spi) |
| 74 | { | 46 | { |
| 75 | const struct regmap_config *regmap_config = &cs35l41_regmap_spi; | 47 | const struct regmap_config *regmap_config = &cs35l41_regmap_spi; |
| @@ -81,6 +53,9 @@ static int cs35l41_spi_probe(struct spi_device *spi) · 5 unmodified lines | |||
| 81 | if (!cs35l41) | 53 | if (!cs35l41) |
| 82 | return -ENOMEM; | 54 | return -ENOMEM; |
| 83 | 55 | ||
| 56 | spi->max_speed_hz = CS35L41_SPI_MAX_FREQ; | ||
| 57 | spi_setup(spi); | ||
| 58 | |||
| 84 | spi_set_drvdata(spi, cs35l41); | 59 | spi_set_drvdata(spi, cs35l41); |
| 85 | cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); | 60 | cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); |
| 86 | if (IS_ERR(cs35l41->regmap)) { | 61 | if (IS_ERR(cs35l41->regmap)) { |
| @@ -91,7 +66,6 @@ static int cs35l41_spi_probe(struct spi_device *spi) · 4 unmodified lines | |||
| 91 | 66 | ||
| 92 | cs35l41->dev = &spi->dev; | 67 | cs35l41->dev = &spi->dev; |
| 93 | cs35l41->irq = spi->irq; | 68 | cs35l41->irq = spi->irq; |
| 94 | cs35l41->otp_setup = cs35l41_spi_otp_setup; | ||
| 95 | 69 | ||
| 96 | return cs35l41_probe(cs35l41, pdata); | 70 | return cs35l41_probe(cs35l41, pdata); |
| 97 | } | 71 | } |
| @@ -302,7 +302,6 @@ static int cs35l41_otp_unpack(void *data) · 301 unmodified lines | |||
| 302 | const struct cs35l41_otp_packed_element_t *otp_map; | 302 | const struct cs35l41_otp_packed_element_t *otp_map; |
| 303 | struct cs35l41_private *cs35l41 = data; | 303 | struct cs35l41_private *cs35l41 = data; |
| 304 | int bit_offset, word_offset, ret, i; | 304 | int bit_offset, word_offset, ret, i; |
| 305 | unsigned int orig_spi_freq; | ||
| 306 | unsigned int bit_sum = 8; | 305 | unsigned int bit_sum = 8; |
| 307 | u32 otp_val, otp_id_reg; | 306 | u32 otp_val, otp_id_reg; |
| 308 | u32 *otp_mem; | 307 | u32 *otp_mem; |
| @@ -326,9 +325,6 @@ static int cs35l41_otp_unpack(void *data) · 17 unmodified lines | |||
| 326 | goto err_otp_unpack; | 325 | goto err_otp_unpack; |
| 327 | } | 326 | } |
| 328 | 327 | ||
| 329 | if (cs35l41->otp_setup) | ||
| 330 | cs35l41->otp_setup(cs35l41, true, &orig_spi_freq); | ||
| 331 | |||
| 332 | ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, | 328 | ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, |
| 333 | CS35L41_OTP_SIZE_WORDS); | 329 | CS35L41_OTP_SIZE_WORDS); |
| 334 | if (ret < 0) { | 330 | if (ret < 0) { |
| @@ -336,9 +332,6 @@ static int cs35l41_otp_unpack(void *data) · 1 unmodified line | |||
| 336 | goto err_otp_unpack; | 332 | goto err_otp_unpack; |
| 337 | } | 333 | } |
| 338 | 334 | ||
| 339 | if (cs35l41->otp_setup) | ||
| 340 | cs35l41->otp_setup(cs35l41, false, &orig_spi_freq); | ||
| 341 | |||
| 342 | otp_map = otp_map_match->map; | 335 | otp_map = otp_map_match->map; |
| 343 | 336 | ||
| 344 | bit_offset = otp_map_match->bit_offset; | 337 | bit_offset = otp_map_match->bit_offset; |
| @@ -726,7 +726,7 @@ · 725 unmodified lines | |||
| 726 | #define CS35L41_FS2_WINDOW_MASK 0x00FFF800 | 726 | #define CS35L41_FS2_WINDOW_MASK 0x00FFF800 |
| 727 | #define CS35L41_FS2_WINDOW_SHIFT 12 | 727 | #define CS35L41_FS2_WINDOW_SHIFT 12 |
| 728 | 728 | ||
| 729 | #define CS35L41_SPI_MAX_FREQ_OTP 4000000 | 729 | #define CS35L41_SPI_MAX_FREQ 4000000 |
| 730 | 730 | ||
| 731 | #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | 731 | #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) |
| 732 | #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | 732 | #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) |
| @@ -764,8 +764,6 @@ struct cs35l41_private { · 31 unmodified lines | |||
| 764 | int irq; | 764 | int irq; |
| 765 | /* GPIO for /RST */ | 765 | /* GPIO for /RST */ |
| 766 | struct gpio_desc *reset_gpio; | 766 | struct gpio_desc *reset_gpio; |
| 767 | void (*otp_setup)(struct cs35l41_private *cs35l41, bool is_pre_setup, | ||
| 768 | unsigned int *freq); | ||
| 769 | }; | 767 | }; |
| 770 | 768 | ||
| 771 | int cs35l41_probe(struct cs35l41_private *cs35l41, | 769 | int cs35l41_probe(struct cs35l41_private *cs35l41, |
| @@ -539,3 +539,4 @@ module_platform_driver(rk817_codec_driver); · 538 unmodified lines | |||
| 539 | MODULE_DESCRIPTION("ASoC RK817 codec driver"); | 539 | MODULE_DESCRIPTION("ASoC RK817 codec driver"); |
| 540 | MODULE_AUTHOR("binyuan <kevan.lan@rock-chips.com>"); | 540 | MODULE_AUTHOR("binyuan <kevan.lan@rock-chips.com>"); |
| 541 | MODULE_LICENSE("GPL v2"); | 541 | MODULE_LICENSE("GPL v2"); |
| 542 | MODULE_ALIAS("platform:rk817-codec"); | ||
| @@ -2858,6 +2858,8 @@ int rt5682_register_dai_clks(struct rt5682_priv *rt5682) · 2857 unmodified lines | |||
| 2858 | 2858 | ||
| 2859 | for (i = 0; i < RT5682_DAI_NUM_CLKS; ++i) { | 2859 | for (i = 0; i < RT5682_DAI_NUM_CLKS; ++i) { |
| 2860 | struct clk_init_data init = { }; | 2860 | struct clk_init_data init = { }; |
| 2861 | struct clk_parent_data parent_data; | ||
| 2862 | const struct clk_hw *parent; | ||
| 2861 | 2863 | ||
| 2862 | dai_clk_hw = &rt5682->dai_clks_hw[i]; | 2864 | dai_clk_hw = &rt5682->dai_clks_hw[i]; |
| 2863 | 2865 | ||
| @@ -2865,17 +2867,17 @@ int rt5682_register_dai_clks(struct rt5682_priv *rt5682) · 1 unmodified line | |||
| 2865 | case RT5682_DAI_WCLK_IDX: | 2867 | case RT5682_DAI_WCLK_IDX: |
| 2866 | /* Make MCLK the parent of WCLK */ | 2868 | /* Make MCLK the parent of WCLK */ |
| 2867 | if (rt5682->mclk) { | 2869 | if (rt5682->mclk) { |
| 2868 | init.parent_data = &(struct clk_parent_data){ | 2870 | parent_data = (struct clk_parent_data){ |
| 2869 | .fw_name = "mclk", | 2871 | .fw_name = "mclk", |
| 2870 | }; | 2872 | }; |
| 2873 | init.parent_data = &parent_data; | ||
| 2871 | init.num_parents = 1; | 2874 | init.num_parents = 1; |
| 2872 | } | 2875 | } |
| 2873 | break; | 2876 | break; |
| 2874 | case RT5682_DAI_BCLK_IDX: | 2877 | case RT5682_DAI_BCLK_IDX: |
| 2875 | /* Make WCLK the parent of BCLK */ | 2878 | /* Make WCLK the parent of BCLK */ |
| 2876 | init.parent_hws = &(const struct clk_hw *){ | 2879 | parent = &rt5682->dai_clks_hw[RT5682_DAI_WCLK_IDX]; |
| 2877 | &rt5682->dai_clks_hw[RT5682_DAI_WCLK_IDX] | 2880 | init.parent_hws = &parent; |
| 2878 | }; | ||
| 2879 | init.num_parents = 1; | 2881 | init.num_parents = 1; |
| 2880 | break; | 2882 | break; |
| 2881 | default: | 2883 | default: |
| @@ -2693,6 +2693,8 @@ static int rt5682s_register_dai_clks(struct snd_soc_component *component) · 2692 unmodified lines | |||
| 2693 | 2693 | ||
| 2694 | for (i = 0; i < RT5682S_DAI_NUM_CLKS; ++i) { | 2694 | for (i = 0; i < RT5682S_DAI_NUM_CLKS; ++i) { |
| 2695 | struct clk_init_data init = { }; | 2695 | struct clk_init_data init = { }; |
| 2696 | struct clk_parent_data parent_data; | ||
| 2697 | const struct clk_hw *parent; | ||
| 2696 | 2698 | ||
| 2697 | dai_clk_hw = &rt5682s->dai_clks_hw[i]; | 2699 | dai_clk_hw = &rt5682s->dai_clks_hw[i]; |
| 2698 | 2700 | ||
| @@ -2700,17 +2702,17 @@ static int rt5682s_register_dai_clks(struct snd_soc_component *component) · 1 unmodified line | |||
| 2700 | case RT5682S_DAI_WCLK_IDX: | 2702 | case RT5682S_DAI_WCLK_IDX: |
| 2701 | /* Make MCLK the parent of WCLK */ | 2703 | /* Make MCLK the parent of WCLK */ |
| 2702 | if (rt5682s->mclk) { | 2704 | if (rt5682s->mclk) { |
| 2703 | init.parent_data = &(struct clk_parent_data){ | 2705 | parent_data = (struct clk_parent_data){ |
| 2704 | .fw_name = "mclk", | 2706 | .fw_name = "mclk", |
| 2705 | }; | 2707 | }; |
| 2708 | init.parent_data = &parent_data; | ||
| 2706 | init.num_parents = 1; | 2709 | init.num_parents = 1; |
| 2707 | } | 2710 | } |
| 2708 | break; | 2711 | break; |
| 2709 | case RT5682S_DAI_BCLK_IDX: | 2712 | case RT5682S_DAI_BCLK_IDX: |
| 2710 | /* Make WCLK the parent of BCLK */ | 2713 | /* Make WCLK the parent of BCLK */ |
| 2711 | init.parent_hws = &(const struct clk_hw *){ | 2714 | parent = &rt5682s->dai_clks_hw[RT5682S_DAI_WCLK_IDX]; |
| 2712 | &rt5682s->dai_clks_hw[RT5682S_DAI_WCLK_IDX] | 2715 | init.parent_hws = &parent; |
| 2713 | }; | ||
| 2714 | init.num_parents = 1; | 2716 | init.num_parents = 1; |
| 2715 | break; | 2717 | break; |
| 2716 | default: | 2718 | default: |
| @@ -3256,6 +3256,9 @@ static int wcd934x_compander_set(struct snd_kcontrol *kc, · 3255 unmodified lines | |||
| 3256 | int value = ucontrol->value.integer.value[0]; | 3256 | int value = ucontrol->value.integer.value[0]; |
| 3257 | int sel; | 3257 | int sel; |
| 3258 | 3258 | ||
| 3259 | if (wcd->comp_enabled[comp] == value) | ||
| 3260 | return 0; | ||
| 3261 | |||
| 3259 | wcd->comp_enabled[comp] = value; | 3262 | wcd->comp_enabled[comp] = value; |
| 3260 | sel = value ? WCD934X_HPH_GAIN_SRC_SEL_COMPANDER : | 3263 | sel = value ? WCD934X_HPH_GAIN_SRC_SEL_COMPANDER : |
| 3261 | WCD934X_HPH_GAIN_SRC_SEL_REGISTER; | 3264 | WCD934X_HPH_GAIN_SRC_SEL_REGISTER; |
| @@ -3279,10 +3282,10 @@ static int wcd934x_compander_set(struct snd_kcontrol *kc, · 17 unmodified lines | |||
| 3279 | case COMPANDER_8: | 3282 | case COMPANDER_8: |
| 3280 | break; | 3283 | break; |
| 3281 | default: | 3284 | default: |
| 3282 | break; | 3285 | return 0; |
| 3283 | } | 3286 | } |
| 3284 | 3287 | ||
| 3285 | return 0; | 3288 | return 1; |
| 3286 | } | 3289 | } |
| 3287 | 3290 | ||
| 3288 | static int wcd934x_rx_hph_mode_get(struct snd_kcontrol *kc, | 3291 | static int wcd934x_rx_hph_mode_get(struct snd_kcontrol *kc, |
| @@ -3326,6 +3329,31 @@ static int slim_rx_mux_get(struct snd_kcontrol *kc, · 37 unmodified lines | |||
| 3326 | return 0; | 3329 | return 0; |
| 3327 | } | 3330 | } |
| 3328 | 3331 | ||
| 3332 | static int slim_rx_mux_to_dai_id(int mux) | ||
| 3333 | { | ||
| 3334 | int aif_id; | ||
| 3335 | |||
| 3336 | switch (mux) { | ||
| 3337 | case 1: | ||
| 3338 | aif_id = AIF1_PB; | ||
| 3339 | break; | ||
| 3340 | case 2: | ||
| 3341 | aif_id = AIF2_PB; | ||
| 3342 | break; | ||
| 3343 | case 3: | ||
| 3344 | aif_id = AIF3_PB; | ||
| 3345 | break; | ||
| 3346 | case 4: | ||
| 3347 | aif_id = AIF4_PB; | ||
| 3348 | break; | ||
| 3349 | default: | ||
| 3350 | aif_id = -1; | ||
| 3351 | break; | ||
| 3352 | } | ||
| 3353 | |||
| 3354 | return aif_id; | ||
| 3355 | } | ||
| 3356 | |||
| 3329 | static int slim_rx_mux_put(struct snd_kcontrol *kc, | 3357 | static int slim_rx_mux_put(struct snd_kcontrol *kc, |
| 3330 | struct snd_ctl_elem_value *ucontrol) | 3358 | struct snd_ctl_elem_value *ucontrol) |
| 3331 | { | 3359 | { |
| @@ -3333,43 +3361,59 @@ static int slim_rx_mux_put(struct snd_kcontrol *kc, · 1 unmodified line | |||
| 3333 | struct wcd934x_codec *wcd = dev_get_drvdata(w->dapm->dev); | 3361 | struct wcd934x_codec *wcd = dev_get_drvdata(w->dapm->dev); |
| 3334 | struct soc_enum *e = (struct soc_enum *)kc->private_value; | 3362 | struct soc_enum *e = (struct soc_enum *)kc->private_value; |
| 3335 | struct snd_soc_dapm_update *update = NULL; | 3363 | struct snd_soc_dapm_update *update = NULL; |
| 3364 | struct wcd934x_slim_ch *ch, *c; | ||
| 3336 | u32 port_id = w->shift; | 3365 | u32 port_id = w->shift; |
| 3366 | bool found = false; | ||
| 3367 | int mux_idx; | ||
| 3368 | int prev_mux_idx = wcd->rx_port_value[port_id]; | ||
| 3369 | int aif_id; | ||
| 3337 | 3370 | ||
| 3338 | if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0]) | 3371 | mux_idx = ucontrol->value.enumerated.item[0]; |
| 3339 | return 0; | ||
| 3340 | 3372 | ||
| 3341 | wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; | 3373 | if (mux_idx == prev_mux_idx) |
| 3374 | return 0; | ||
| 3342 | 3375 | ||
| 3343 | switch (wcd->rx_port_value[port_id]) { | 3376 | switch(mux_idx) { |
| 3344 | case 0: | 3377 | case 0: |
| 3345 | list_del_init(&wcd->rx_chs[port_id].list); | 3378 | aif_id = slim_rx_mux_to_dai_id(prev_mux_idx); |
| 3346 | break; | 3379 | if (aif_id < 0) |
| 3347 | case 1: | 3380 | return 0; |
| 3348 | list_add_tail(&wcd->rx_chs[port_id].list, | 3381 | |
| 3349 | &wcd->dai[AIF1_PB].slim_ch_list); | 3382 | list_for_each_entry_safe(ch, c, &wcd->dai[aif_id].slim_ch_list, list) { |
| 3350 | break; | 3383 | if (ch->port == port_id + WCD934X_RX_START) { |
| 3351 | case 2: | 3384 | found = true; |
| 3352 | list_add_tail(&wcd->rx_chs[port_id].list, | 3385 | list_del_init(&ch->list); |
| 3353 | &wcd->dai[AIF2_PB].slim_ch_list); | 3386 | break; |
| 3354 | break; | 3387 | } |
| 3355 | case 3: | 3388 | } |
| 3356 | list_add_tail(&wcd->rx_chs[port_id].list, | 3389 | if (!found) |
| 3357 | &wcd->dai[AIF3_PB].slim_ch_list); | 3390 | return 0; |
| 3391 | |||
| 3358 | break; | 3392 | break; |
| 3359 | case 4: | 3393 | case 1 ... 4: |
| 3360 | list_add_tail(&wcd->rx_chs[port_id].list, | 3394 | aif_id = slim_rx_mux_to_dai_id(mux_idx); |
| 3361 | &wcd->dai[AIF4_PB].slim_ch_list); | 3395 | if (aif_id < 0) |
| 3396 | return 0; | ||
| 3397 | |||
| 3398 | if (list_empty(&wcd->rx_chs[port_id].list)) { | ||
| 3399 | list_add_tail(&wcd->rx_chs[port_id].list, | ||
| 3400 | &wcd->dai[aif_id].slim_ch_list); | ||
| 3401 | } else { | ||
| 3402 | dev_err(wcd->dev ,"SLIM_RX%d PORT is busy\n", port_id); | ||
| 3403 | return 0; | ||
| 3404 | } | ||
| 3362 | break; | 3405 | break; |
| 3406 | |||
| 3363 | default: | 3407 | default: |
| 3364 | dev_err(wcd->dev, "Unknown AIF %d\n", | 3408 | dev_err(wcd->dev, "Unknown AIF %d\n", mux_idx); |
| 3365 | wcd->rx_port_value[port_id]); | ||
| 3366 | goto err; | 3409 | goto err; |
| 3367 | } | 3410 | } |
| 3368 | 3411 | ||
| 3412 | wcd->rx_port_value[port_id] = mux_idx; | ||
| 3369 | snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id], | 3413 | snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id], |
| 3370 | e, update); | 3414 | e, update); |
| 3371 | 3415 | ||
| 3372 | return 0; | 3416 | return 1; |
| 3373 | err: | 3417 | err: |
| 3374 | return -EINVAL; | 3418 | return -EINVAL; |
| 3375 | } | 3419 | } |
| @@ -3815,6 +3859,7 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kc, · 439 unmodified lines | |||
| 3815 | struct soc_mixer_control *mixer = | 3859 | struct soc_mixer_control *mixer = |
| 3816 | (struct soc_mixer_control *)kc->private_value; | 3860 | (struct soc_mixer_control *)kc->private_value; |
| 3817 | int enable = ucontrol->value.integer.value[0]; | 3861 | int enable = ucontrol->value.integer.value[0]; |
| 3862 | struct wcd934x_slim_ch *ch, *c; | ||
| 3818 | int dai_id = widget->shift; | 3863 | int dai_id = widget->shift; |
| 3819 | int port_id = mixer->shift; | 3864 | int port_id = mixer->shift; |
| 3820 | 3865 | ||
| @@ -3822,17 +3867,32 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kc, · 1 unmodified line | |||
| 3822 | if (enable == wcd->tx_port_value[port_id]) | 3867 | if (enable == wcd->tx_port_value[port_id]) |
| 3823 | return 0; | 3868 | return 0; |
| 3824 | 3869 | ||
| 3825 | wcd->tx_port_value[port_id] = enable; | 3870 | if (enable) { |
| 3826 | 3871 | if (list_empty(&wcd->tx_chs[port_id].list)) { | |
| 3827 | if (enable) | 3872 | list_add_tail(&wcd->tx_chs[port_id].list, |
| 3828 | list_add_tail(&wcd->tx_chs[port_id].list, | 3873 | &wcd->dai[dai_id].slim_ch_list); |
| 3829 | &wcd->dai[dai_id].slim_ch_list); | 3874 | } else { |
| 3830 | else | 3875 | dev_err(wcd->dev ,"SLIM_TX%d PORT is busy\n", port_id); |
| 3831 | list_del_init(&wcd->tx_chs[port_id].list); | 3876 | return 0; |
| 3877 | } | ||
| 3878 | } else { | ||
| 3879 | bool found = false; | ||
| 3880 | |||
| 3881 | list_for_each_entry_safe(ch, c, &wcd->dai[dai_id].slim_ch_list, list) { | ||
| 3882 | if (ch->port == port_id) { | ||
| 3883 | found = true; | ||
| 3884 | list_del_init(&wcd->tx_chs[port_id].list); | ||
| 3885 | break; | ||
| 3886 | } | ||
| 3887 | } | ||
| 3888 | if (!found) | ||
| 3889 | return 0; | ||
| 3890 | } | ||
| 3832 | 3891 | ||
| 3892 | wcd->tx_port_value[port_id] = enable; | ||
| 3833 | snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update); | 3893 | snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update); |
| 3834 | 3894 | ||
| 3835 | return 0; | 3895 | return 1; |
| 3836 | } | 3896 | } |
| 3837 | 3897 | ||
| 3838 | static const struct snd_kcontrol_new aif1_slim_cap_mixer[] = { | 3898 | static const struct snd_kcontrol_new aif1_slim_cap_mixer[] = { |
| @@ -772,7 +772,8 @@ static int wsa881x_put_pa_gain(struct snd_kcontrol *kc, · 771 unmodified lines | |||
| 772 | 772 | ||
| 773 | usleep_range(1000, 1010); | 773 | usleep_range(1000, 1010); |
| 774 | } | 774 | } |
| 775 | return 0; | 775 | |
| 776 | return 1; | ||
| 776 | } | 777 | } |
| 777 | 778 | ||
| 778 | static int wsa881x_get_port(struct snd_kcontrol *kcontrol, | 779 | static int wsa881x_get_port(struct snd_kcontrol *kcontrol, |
| @@ -816,15 +817,22 @@ static int wsa881x_set_port(struct snd_kcontrol *kcontrol, · 37 unmodified lines | |||
| 816 | (struct soc_mixer_control *)kcontrol->private_value; | 817 | (struct soc_mixer_control *)kcontrol->private_value; |
| 817 | int portidx = mixer->reg; | 818 | int portidx = mixer->reg; |
| 818 | 819 | ||
| 819 | if (ucontrol->value.integer.value[0]) | 820 | if (ucontrol->value.integer.value[0]) { |
| 821 | if (data->port_enable[portidx]) | ||
| 822 | return 0; | ||
| 823 | |||
| 820 | data->port_enable[portidx] = true; | 824 | data->port_enable[portidx] = true; |
| 821 | else | 825 | } else { |
| 826 | if (!data->port_enable[portidx]) | ||
| 827 | return 0; | ||
| 828 | |||
| 822 | data->port_enable[portidx] = false; | 829 | data->port_enable[portidx] = false; |
| 830 | } | ||
| 823 | 831 | ||
| 824 | if (portidx == WSA881X_PORT_BOOST) /* Boost Switch */ | 832 | if (portidx == WSA881X_PORT_BOOST) /* Boost Switch */ |
| 825 | wsa881x_boost_ctrl(comp, data->port_enable[portidx]); | 833 | wsa881x_boost_ctrl(comp, data->port_enable[portidx]); |
| 826 | 834 | ||
| 827 | return 0; | 835 | return 1; |
| 828 | } | 836 | } |
| 829 | 837 | ||
| 830 | static const char * const smart_boost_lvl_text[] = { | 838 | static const char * const smart_boost_lvl_text[] = { |
| @@ -81,6 +81,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[] = { · 80 unmodified lines | |||
| 81 | .sof_fw_filename = "sof-cml.ri", | 81 | .sof_fw_filename = "sof-cml.ri", |
| 82 | .sof_tplg_filename = "sof-cml-da7219-max98390.tplg", | 82 | .sof_tplg_filename = "sof-cml-da7219-max98390.tplg", |
| 83 | }, | 83 | }, |
| 84 | { | ||
| 85 | .id = "ESSX8336", | ||
| 86 | .drv_name = "sof-essx8336", | ||
| 87 | .sof_fw_filename = "sof-cml.ri", | ||
| 88 | .sof_tplg_filename = "sof-cml-es8336.tplg", | ||
| 89 | }, | ||
| 84 | {}, | 90 | {}, |
| 85 | }; | 91 | }; |
| 86 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines); | 92 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines); |
| @@ -498,14 +498,16 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol, · 497 unmodified lines | |||
| 498 | struct session_data *session = &data->sessions[session_id]; | 498 | struct session_data *session = &data->sessions[session_id]; |
| 499 | 499 | ||
| 500 | if (ucontrol->value.integer.value[0]) { | 500 | if (ucontrol->value.integer.value[0]) { |
| 501 | if (session->port_id == be_id) | ||
| 502 | return 0; | ||
| 503 | |||
| 501 | session->port_id = be_id; | 504 | session->port_id = be_id; |
| 502 | snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update); | 505 | snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update); |
| 503 | } else { | 506 | } else { |
| 504 | if (session->port_id == be_id) { | 507 | if (session->port_id == -1 || session->port_id != be_id) |
| 505 | session->port_id = -1; | ||
| 506 | return 0; | 508 | return 0; |
| 507 | } | ||
| 508 | 509 | ||
| 510 | session->port_id = -1; | ||
| 509 | snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update); | 511 | snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update); |
| 510 | } | 512 | } |
| 511 | 513 | ||
| @@ -95,6 +95,7 @@ struct rk_i2s_tdm_dev { · 94 unmodified lines | |||
| 95 | spinlock_t lock; /* xfer lock */ | 95 | spinlock_t lock; /* xfer lock */ |
| 96 | bool has_playback; | 96 | bool has_playback; |
| 97 | bool has_capture; | 97 | bool has_capture; |
| 98 | struct snd_soc_dai_driver *dai; | ||
| 98 | }; | 99 | }; |
| 99 | 100 | ||
| 100 | static int to_ch_num(unsigned int val) | 101 | static int to_ch_num(unsigned int val) |
| @@ -1310,19 +1311,14 @@ static const struct of_device_id rockchip_i2s_tdm_match[] = { · 1209 unmodified lines | |||
| 1310 | {}, | 1311 | {}, |
| 1311 | }; | 1312 | }; |
| 1312 | 1313 | ||
| 1313 | static struct snd_soc_dai_driver i2s_tdm_dai = { | 1314 | static const struct snd_soc_dai_driver i2s_tdm_dai = { |
| 1314 | .probe = rockchip_i2s_tdm_dai_probe, | 1315 | .probe = rockchip_i2s_tdm_dai_probe, |
| 1315 | .playback = { | ||
| 1316 | .stream_name = "Playback", | ||
| 1317 | }, | ||
| 1318 | .capture = { | ||
| 1319 | .stream_name = "Capture", | ||
| 1320 | }, | ||
| 1321 | .ops = &rockchip_i2s_tdm_dai_ops, | 1316 | .ops = &rockchip_i2s_tdm_dai_ops, |
| 1322 | }; | 1317 | }; |
| 1323 | 1318 | ||
| 1324 | static void rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev *i2s_tdm) | 1319 | static int rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev *i2s_tdm) |
| 1325 | { | 1320 | { |
| 1321 | struct snd_soc_dai_driver *dai; | ||
| 1326 | struct property *dma_names; | 1322 | struct property *dma_names; |
| 1327 | const char *dma_name; | 1323 | const char *dma_name; |
| 1328 | u64 formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | | 1324 | u64 formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | |
| @@ -1337,19 +1333,33 @@ static void rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev *i2s_tdm) · 8 unmodified lines | |||
| 1337 | i2s_tdm->has_capture = true; | 1333 | i2s_tdm->has_capture = true; |
| 1338 | } | 1334 | } |
| 1339 | 1335 | ||
| 1336 | dai = devm_kmemdup(i2s_tdm->dev, &i2s_tdm_dai, | ||
| 1337 | sizeof(*dai), GFP_KERNEL); | ||
| 1338 | if (!dai) | ||
| 1339 | return -ENOMEM; | ||
| 1340 | |||
| 1340 | if (i2s_tdm->has_playback) { | 1341 | if (i2s_tdm->has_playback) { |
| 1341 | i2s_tdm_dai.playback.channels_min = 2; | 1342 | dai->playback.stream_name = "Playback"; |
| 1342 | i2s_tdm_dai.playback.channels_max = 8; | 1343 | dai->playback.channels_min = 2; |
| 1343 | i2s_tdm_dai.playback.rates = SNDRV_PCM_RATE_8000_192000; | 1344 | dai->playback.channels_max = 8; |
| 1344 | i2s_tdm_dai.playback.formats = formats; | 1345 | dai->playback.rates = SNDRV_PCM_RATE_8000_192000; |
| 1346 | dai->playback.formats = formats; | ||
| 1345 | } | 1347 | } |
| 1346 | 1348 | ||
| 1347 | if (i2s_tdm->has_capture) { | 1349 | if (i2s_tdm->has_capture) { |
| 1348 | i2s_tdm_dai.capture.channels_min = 2; | 1350 | dai->capture.stream_name = "Capture"; |
| 1349 | i2s_tdm_dai.capture.channels_max = 8; | 1351 | dai->capture.channels_min = 2; |
| 1350 | i2s_tdm_dai.capture.rates = SNDRV_PCM_RATE_8000_192000; | 1352 | dai->capture.channels_max = 8; |
| 1351 | i2s_tdm_dai.capture.formats = formats; | 1353 | dai->capture.rates = SNDRV_PCM_RATE_8000_192000; |
| 1354 | dai->capture.formats = formats; | ||
| 1352 | } | 1355 | } |
| 1356 | |||
| 1357 | if (i2s_tdm->clk_trcm != TRCM_TXRX) | ||
| 1358 | dai->symmetric_rate = 1; | ||
| 1359 | |||
| 1360 | i2s_tdm->dai = dai; | ||
| 1361 | |||
| 1362 | return 0; | ||
| 1353 | } | 1363 | } |
| 1354 | 1364 | ||
| 1355 | static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev *i2s_tdm, | 1365 | static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev *i2s_tdm, |
| @@ -1541,8 +1551,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev) · 185 unmodified lines | |||
| 1541 | spin_lock_init(&i2s_tdm->lock); | 1551 | spin_lock_init(&i2s_tdm->lock); |
| 1542 | i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data; | 1552 | i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data; |
| 1543 | 1553 | ||
| 1544 | rockchip_i2s_tdm_init_dai(i2s_tdm); | ||
| 1545 | |||
| 1546 | i2s_tdm->frame_width = 64; | 1554 | i2s_tdm->frame_width = 64; |
| 1547 | 1555 | ||
| 1548 | i2s_tdm->clk_trcm = TRCM_TXRX; | 1556 | i2s_tdm->clk_trcm = TRCM_TXRX; |
| @@ -1555,8 +1563,10 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev) · 6 unmodified lines | |||
| 1555 | } | 1563 | } |
| 1556 | i2s_tdm->clk_trcm = TRCM_RX; | 1564 | i2s_tdm->clk_trcm = TRCM_RX; |
| 1557 | } | 1565 | } |
| 1558 | if (i2s_tdm->clk_trcm != TRCM_TXRX) | 1566 | |
| 1559 | i2s_tdm_dai.symmetric_rate = 1; | 1567 | ret = rockchip_i2s_tdm_init_dai(i2s_tdm); |
| 1568 | if (ret) | ||
| 1569 | return ret; | ||
| 1560 | 1570 | ||
| 1561 | i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf"); | 1571 | i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf"); |
| 1562 | if (IS_ERR(i2s_tdm->grf)) | 1572 | if (IS_ERR(i2s_tdm->grf)) |
| @@ -1678,7 +1688,7 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev) · 115 unmodified lines | |||
| 1678 | 1688 | ||
| 1679 | ret = devm_snd_soc_register_component(&pdev->dev, | 1689 | ret = devm_snd_soc_register_component(&pdev->dev, |
| 1680 | &rockchip_i2s_tdm_component, | 1690 | &rockchip_i2s_tdm_component, |
| 1681 | &i2s_tdm_dai, 1); | 1691 | i2s_tdm->dai, 1); |
| 1682 | 1692 | ||
| 1683 | if (ret) { | 1693 | if (ret) { |
| 1684 | dev_err(&pdev->dev, "Could not register DAI\n"); | 1694 | dev_err(&pdev->dev, "Could not register DAI\n"); |
| @@ -20,8 +20,10 @@ static bool snd_soc_acpi_id_present(struct snd_soc_acpi_mach *machine) · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | if (comp_ids) { | 21 | if (comp_ids) { |
| 22 | for (i = 0; i < comp_ids->num_codecs; i++) { | 22 | for (i = 0; i < comp_ids->num_codecs; i++) { |
| 23 | if (acpi_dev_present(comp_ids->codecs[i], NULL, -1)) | 23 | if (acpi_dev_present(comp_ids->codecs[i], NULL, -1)) { |
| 24 | strscpy(machine->id, comp_ids->codecs[i], ACPI_ID_LEN); | ||
| 24 | return true; | 25 | return true; |
| 26 | } | ||
| 25 | } | 27 | } |
| 26 | } | 28 | } |
| 27 | 29 | ||
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) | 23 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) |
| 24 | #define IDISP_VID_INTEL 0x80860000 | 24 | #define IDISP_VID_INTEL 0x80860000 |
| 25 | #define CODEC_PROBE_RETRIES 3 | ||
| 25 | 26 | ||
| 26 | /* load the legacy HDA codec driver */ | 27 | /* load the legacy HDA codec driver */ |
| 27 | static int request_codec_module(struct hda_codec *codec) | 28 | static int request_codec_module(struct hda_codec *codec) |
| @@ -121,12 +122,15 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address, · 93 unmodified lines | |||
| 121 | u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) | | 122 | u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) | |
| 122 | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; | 123 | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; |
| 123 | u32 resp = -1; | 124 | u32 resp = -1; |
| 124 | int ret; | 125 | int ret, retry = 0; |
| 126 | |||
| 127 | do { | ||
| 128 | mutex_lock(&hbus->core.cmd_mutex); | ||
| 129 | snd_hdac_bus_send_cmd(&hbus->core, hda_cmd); | ||
| 130 | snd_hdac_bus_get_response(&hbus->core, address, &resp); | ||
| 131 | mutex_unlock(&hbus->core.cmd_mutex); | ||
| 132 | } while (resp == -1 && retry++ < CODEC_PROBE_RETRIES); | ||
| 125 | 133 | ||
| 126 | mutex_lock(&hbus->core.cmd_mutex); | ||
| 127 | snd_hdac_bus_send_cmd(&hbus->core, hda_cmd); | ||
| 128 | snd_hdac_bus_get_response(&hbus->core, address, &resp); | ||
| 129 | mutex_unlock(&hbus->core.cmd_mutex); | ||
| 130 | if (resp == -1) | 134 | if (resp == -1) |
| 131 | return -EIO; | 135 | return -EIO; |
| 132 | dev_dbg(sdev->dev, "HDA codec #%d probed OK: response: %x\n", | 136 | dev_dbg(sdev->dev, "HDA codec #%d probed OK: response: %x\n", |
| @@ -58,6 +58,13 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w) · 57 unmodified lines | |||
| 58 | return -EINVAL; | 58 | return -EINVAL; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | /* DAI already configured, reset it before reconfiguring it */ | ||
| 62 | if (sof_dai->configured) { | ||
| 63 | ret = hda_ctrl_dai_widget_free(w); | ||
| 64 | if (ret < 0) | ||
| 65 | return ret; | ||
| 66 | } | ||
| 67 | |||
| 61 | config = &sof_dai->dai_config[sof_dai->current_config]; | 68 | config = &sof_dai->dai_config[sof_dai->current_config]; |
| 62 | 69 | ||
| 63 | /* | 70 | /* |
| @@ -26,51 +26,162 @@ static const struct reg_default tegra186_dspk_reg_defaults[] = { · 25 unmodified lines | |||
| 26 | { TEGRA186_DSPK_CODEC_CTRL, 0x03000000 }, | 26 | { TEGRA186_DSPK_CODEC_CTRL, 0x03000000 }, |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | static int tegra186_dspk_get_control(struct snd_kcontrol *kcontrol, | 29 | static int tegra186_dspk_get_fifo_th(struct snd_kcontrol *kcontrol, |
| 30 | struct snd_ctl_elem_value *ucontrol) | 30 | struct snd_ctl_elem_value *ucontrol) |
| 31 | { | 31 | { |
| 32 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | 32 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); |
| 33 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | 33 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); |
| 34 | 34 | ||
| 35 | if (strstr(kcontrol->id.name, "FIFO Threshold")) | 35 | ucontrol->value.integer.value[0] = dspk->rx_fifo_th; |
| 36 | ucontrol->value.integer.value[0] = dspk->rx_fifo_th; | ||
| 37 | else if (strstr(kcontrol->id.name, "OSR Value")) | ||
| 38 | ucontrol->value.integer.value[0] = dspk->osr_val; | ||
| 39 | else if (strstr(kcontrol->id.name, "LR Polarity Select")) | ||
| 40 | ucontrol->value.integer.value[0] = dspk->lrsel; | ||
| 41 | else if (strstr(kcontrol->id.name, "Channel Select")) | ||
| 42 | ucontrol->value.integer.value[0] = dspk->ch_sel; | ||
| 43 | else if (strstr(kcontrol->id.name, "Mono To Stereo")) | ||
| 44 | ucontrol->value.integer.value[0] = dspk->mono_to_stereo; | ||
| 45 | else if (strstr(kcontrol->id.name, "Stereo To Mono")) | ||
| 46 | ucontrol->value.integer.value[0] = dspk->stereo_to_mono; | ||
| 47 | 36 | ||
| 48 | return 0; | 37 | return 0; |
| 49 | } | 38 | } |
| 50 | 39 | ||
| 51 | static int tegra186_dspk_put_control(struct snd_kcontrol *kcontrol, | 40 | static int tegra186_dspk_put_fifo_th(struct snd_kcontrol *kcontrol, |
| 52 | struct snd_ctl_elem_value *ucontrol) | 41 | struct snd_ctl_elem_value *ucontrol) |
| 53 | { | 42 | { |
| 54 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | 43 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); |
| 55 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | 44 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); |
| 56 | int val = ucontrol->value.integer.value[0]; | 45 | int value = ucontrol->value.integer.value[0]; |
| 57 | 46 | ||
| 58 | if (strstr(kcontrol->id.name, "FIFO Threshold")) | 47 | if (value == dspk->rx_fifo_th) |
| 59 | dspk->rx_fifo_th = val; | 48 | return 0; |
| 60 | else if (strstr(kcontrol->id.name, "OSR Value")) | 49 | |
| 61 | dspk->osr_val = val; | 50 | dspk->rx_fifo_th = value; |
| 62 | else if (strstr(kcontrol->id.name, "LR Polarity Select")) | 51 | |
| 63 | dspk->lrsel = val; | 52 | return 1; |
| 64 | else if (strstr(kcontrol->id.name, "Channel Select")) | 53 | } |
| 65 | dspk->ch_sel = val; | 54 | |
| 66 | else if (strstr(kcontrol->id.name, "Mono To Stereo")) | 55 | static int tegra186_dspk_get_osr_val(struct snd_kcontrol *kcontrol, |
| 67 | dspk->mono_to_stereo = val; | 56 | struct snd_ctl_elem_value *ucontrol) |
| 68 | else if (strstr(kcontrol->id.name, "Stereo To Mono")) | 57 | { |
| 69 | dspk->stereo_to_mono = val; | 58 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); |
| 59 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 60 | |||
| 61 | ucontrol->value.enumerated.item[0] = dspk->osr_val; | ||
| 70 | 62 | ||
| 71 | return 0; | 63 | return 0; |
| 72 | } | 64 | } |
| 73 | 65 | ||
| 66 | static int tegra186_dspk_put_osr_val(struct snd_kcontrol *kcontrol, | ||
| 67 | struct snd_ctl_elem_value *ucontrol) | ||
| 68 | { | ||
| 69 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 70 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 71 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 72 | |||
| 73 | if (value == dspk->osr_val) | ||
| 74 | return 0; | ||
| 75 | |||
| 76 | dspk->osr_val = value; | ||
| 77 | |||
| 78 | return 1; | ||
| 79 | } | ||
| 80 | |||
| 81 | static int tegra186_dspk_get_pol_sel(struct snd_kcontrol *kcontrol, | ||
| 82 | struct snd_ctl_elem_value *ucontrol) | ||
| 83 | { | ||
| 84 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 85 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 86 | |||
| 87 | ucontrol->value.enumerated.item[0] = dspk->lrsel; | ||
| 88 | |||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | static int tegra186_dspk_put_pol_sel(struct snd_kcontrol *kcontrol, | ||
| 93 | struct snd_ctl_elem_value *ucontrol) | ||
| 94 | { | ||
| 95 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 96 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 97 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 98 | |||
| 99 | if (value == dspk->lrsel) | ||
| 100 | return 0; | ||
| 101 | |||
| 102 | dspk->lrsel = value; | ||
| 103 | |||
| 104 | return 1; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int tegra186_dspk_get_ch_sel(struct snd_kcontrol *kcontrol, | ||
| 108 | struct snd_ctl_elem_value *ucontrol) | ||
| 109 | { | ||
| 110 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 111 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 112 | |||
| 113 | ucontrol->value.enumerated.item[0] = dspk->ch_sel; | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int tegra186_dspk_put_ch_sel(struct snd_kcontrol *kcontrol, | ||
| 119 | struct snd_ctl_elem_value *ucontrol) | ||
| 120 | { | ||
| 121 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 122 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 123 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 124 | |||
| 125 | if (value == dspk->ch_sel) | ||
| 126 | return 0; | ||
| 127 | |||
| 128 | dspk->ch_sel = value; | ||
| 129 | |||
| 130 | return 1; | ||
| 131 | } | ||
| 132 | |||
| 133 | static int tegra186_dspk_get_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 134 | struct snd_ctl_elem_value *ucontrol) | ||
| 135 | { | ||
| 136 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 137 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 138 | |||
| 139 | ucontrol->value.enumerated.item[0] = dspk->mono_to_stereo; | ||
| 140 | |||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int tegra186_dspk_put_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 145 | struct snd_ctl_elem_value *ucontrol) | ||
| 146 | { | ||
| 147 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 148 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 149 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 150 | |||
| 151 | if (value == dspk->mono_to_stereo) | ||
| 152 | return 0; | ||
| 153 | |||
| 154 | dspk->mono_to_stereo = value; | ||
| 155 | |||
| 156 | return 1; | ||
| 157 | } | ||
| 158 | |||
| 159 | static int tegra186_dspk_get_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 160 | struct snd_ctl_elem_value *ucontrol) | ||
| 161 | { | ||
| 162 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 163 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 164 | |||
| 165 | ucontrol->value.enumerated.item[0] = dspk->stereo_to_mono; | ||
| 166 | |||
| 167 | return 0; | ||
| 168 | } | ||
| 169 | |||
| 170 | static int tegra186_dspk_put_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 171 | struct snd_ctl_elem_value *ucontrol) | ||
| 172 | { | ||
| 173 | struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); | ||
| 174 | struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); | ||
| 175 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 176 | |||
| 177 | if (value == dspk->stereo_to_mono) | ||
| 178 | return 0; | ||
| 179 | |||
| 180 | dspk->stereo_to_mono = value; | ||
| 181 | |||
| 182 | return 1; | ||
| 183 | } | ||
| 184 | |||
| 74 | static int __maybe_unused tegra186_dspk_runtime_suspend(struct device *dev) | 185 | static int __maybe_unused tegra186_dspk_runtime_suspend(struct device *dev) |
| 75 | { | 186 | { |
| 76 | struct tegra186_dspk *dspk = dev_get_drvdata(dev); | 187 | struct tegra186_dspk *dspk = dev_get_drvdata(dev); |
| @@ -279,17 +390,19 @@ static const struct soc_enum tegra186_dspk_lrsel_enum = · 202 unmodified lines | |||
| 279 | static const struct snd_kcontrol_new tegrat186_dspk_controls[] = { | 390 | static const struct snd_kcontrol_new tegrat186_dspk_controls[] = { |
| 280 | SOC_SINGLE_EXT("FIFO Threshold", SND_SOC_NOPM, 0, | 391 | SOC_SINGLE_EXT("FIFO Threshold", SND_SOC_NOPM, 0, |
| 281 | TEGRA186_DSPK_RX_FIFO_DEPTH - 1, 0, | 392 | TEGRA186_DSPK_RX_FIFO_DEPTH - 1, 0, |
| 282 | tegra186_dspk_get_control, tegra186_dspk_put_control), | 393 | tegra186_dspk_get_fifo_th, tegra186_dspk_put_fifo_th), |
| 283 | SOC_ENUM_EXT("OSR Value", tegra186_dspk_osr_enum, | 394 | SOC_ENUM_EXT("OSR Value", tegra186_dspk_osr_enum, |
| 284 | tegra186_dspk_get_control, tegra186_dspk_put_control), | 395 | tegra186_dspk_get_osr_val, tegra186_dspk_put_osr_val), |
| 285 | SOC_ENUM_EXT("LR Polarity Select", tegra186_dspk_lrsel_enum, | 396 | SOC_ENUM_EXT("LR Polarity Select", tegra186_dspk_lrsel_enum, |
| 286 | tegra186_dspk_get_control, tegra186_dspk_put_control), | 397 | tegra186_dspk_get_pol_sel, tegra186_dspk_put_pol_sel), |
| 287 | SOC_ENUM_EXT("Channel Select", tegra186_dspk_ch_sel_enum, | 398 | SOC_ENUM_EXT("Channel Select", tegra186_dspk_ch_sel_enum, |
| 288 | tegra186_dspk_get_control, tegra186_dspk_put_control), | 399 | tegra186_dspk_get_ch_sel, tegra186_dspk_put_ch_sel), |
| 289 | SOC_ENUM_EXT("Mono To Stereo", tegra186_dspk_mono_conv_enum, | 400 | SOC_ENUM_EXT("Mono To Stereo", tegra186_dspk_mono_conv_enum, |
| 290 | tegra186_dspk_get_control, tegra186_dspk_put_control), | 401 | tegra186_dspk_get_mono_to_stereo, |
| 402 | tegra186_dspk_put_mono_to_stereo), | ||
| 291 | SOC_ENUM_EXT("Stereo To Mono", tegra186_dspk_stereo_conv_enum, | 403 | SOC_ENUM_EXT("Stereo To Mono", tegra186_dspk_stereo_conv_enum, |
| 292 | tegra186_dspk_get_control, tegra186_dspk_put_control), | 404 | tegra186_dspk_get_stereo_to_mono, |
| 405 | tegra186_dspk_put_stereo_to_mono), | ||
| 293 | }; | 406 | }; |
| 294 | 407 | ||
| 295 | static const struct snd_soc_component_driver tegra186_dspk_cmpnt = { | 408 | static const struct snd_soc_component_driver tegra186_dspk_cmpnt = { |
| @@ -424,46 +424,122 @@ static const struct snd_soc_dai_ops tegra_admaif_dai_ops = { · 423 unmodified lines | |||
| 424 | .trigger = tegra_admaif_trigger, | 424 | .trigger = tegra_admaif_trigger, |
| 425 | }; | 425 | }; |
| 426 | 426 | ||
| 427 | static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol, | 427 | static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol, |
| 428 | struct snd_ctl_elem_value *ucontrol) | 428 | struct snd_ctl_elem_value *ucontrol) |
| 429 | { | 429 | { |
| 430 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | 430 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); |
| 431 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); | ||
| 432 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; | ||
| 433 | |||
| 434 | ucontrol->value.enumerated.item[0] = | ||
| 435 | admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; | ||
| 436 | |||
| 437 | return 0; | ||
| 438 | } | ||
| 439 | |||
| 440 | static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 441 | struct snd_ctl_elem_value *ucontrol) | ||
| 442 | { | ||
| 443 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 444 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); | ||
| 445 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; | ||
| 446 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 447 | |||
| 448 | if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]) | ||
| 449 | return 0; | ||
| 450 | |||
| 451 | admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; | ||
| 452 | |||
| 453 | return 1; | ||
| 454 | } | ||
| 455 | |||
| 456 | static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 457 | struct snd_ctl_elem_value *ucontrol) | ||
| 458 | { | ||
| 459 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 460 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); | ||
| 461 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; | ||
| 462 | |||
| 463 | ucontrol->value.enumerated.item[0] = | ||
| 464 | admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]; | ||
| 465 | |||
| 466 | return 0; | ||
| 467 | } | ||
| 468 | |||
| 469 | static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 470 | struct snd_ctl_elem_value *ucontrol) | ||
| 471 | { | ||
| 472 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 473 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); | ||
| 431 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; | 474 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; |
| 475 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 476 | |||
| 477 | if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]) | ||
| 478 | return 0; | ||
| 479 | |||
| 480 | admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value; | ||
| 481 | |||
| 482 | return 1; | ||
| 483 | } | ||
| 484 | |||
| 485 | static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 486 | struct snd_ctl_elem_value *ucontrol) | ||
| 487 | { | ||
| 488 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 432 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); | 489 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); |
| 433 | long *uctl_val = &ucontrol->value.integer.value[0]; | 490 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; |
| 434 | 491 | ||
| 435 | if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) | 492 | ucontrol->value.enumerated.item[0] = |
| 436 | *uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; | 493 | admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]; |
| 437 | else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) | ||
| 438 | *uctl_val = admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]; | ||
| 439 | else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) | ||
| 440 | *uctl_val = admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]; | ||
| 441 | else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) | ||
| 442 | *uctl_val = admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]; | ||
| 443 | 494 | ||
| 444 | return 0; | 495 | return 0; |
| 445 | } | 496 | } |
| 446 | 497 | ||
| 447 | static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol, | 498 | static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol, |
| 448 | struct snd_ctl_elem_value *ucontrol) | 499 | struct snd_ctl_elem_value *ucontrol) |
| 449 | { | 500 | { |
| 450 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | 501 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); |
| 502 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); | ||
| 451 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; | 503 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; |
| 504 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 505 | |||
| 506 | if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]) | ||
| 507 | return 0; | ||
| 508 | |||
| 509 | admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value; | ||
| 510 | |||
| 511 | return 1; | ||
| 512 | } | ||
| 513 | |||
| 514 | static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 515 | struct snd_ctl_elem_value *ucontrol) | ||
| 516 | { | ||
| 517 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 452 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); | 518 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); |
| 453 | int value = ucontrol->value.integer.value[0]; | 519 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; |
| 454 | 520 | ||
| 455 | if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) | 521 | ucontrol->value.enumerated.item[0] = |
| 456 | admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; | 522 | admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]; |
| 457 | else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) | ||
| 458 | admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value; | ||
| 459 | else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) | ||
| 460 | admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value; | ||
| 461 | else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) | ||
| 462 | admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value; | ||
| 463 | 523 | ||
| 464 | return 0; | 524 | return 0; |
| 465 | } | 525 | } |
| 466 | 526 | ||
| 527 | static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 528 | struct snd_ctl_elem_value *ucontrol) | ||
| 529 | { | ||
| 530 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 531 | struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); | ||
| 532 | struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; | ||
| 533 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 534 | |||
| 535 | if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]) | ||
| 536 | return 0; | ||
| 537 | |||
| 538 | admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value; | ||
| 539 | |||
| 540 | return 1; | ||
| 541 | } | ||
| 542 | |||
| 467 | static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) | 543 | static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) |
| 468 | { | 544 | { |
| 469 | struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); | 545 | struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); |
| @@ -559,17 +635,21 @@ static const char * const tegra_admaif_mono_conv_text[] = { · 89 unmodified lines | |||
| 559 | } | 635 | } |
| 560 | 636 | ||
| 561 | #define TEGRA_ADMAIF_CIF_CTRL(reg) \ | 637 | #define TEGRA_ADMAIF_CIF_CTRL(reg) \ |
| 562 | NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1,\ | 638 | NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \ |
| 563 | tegra_admaif_get_control, tegra_admaif_put_control, \ | 639 | tegra210_admaif_pget_mono_to_stereo, \ |
| 640 | tegra210_admaif_pput_mono_to_stereo, \ | ||
| 564 | tegra_admaif_mono_conv_text), \ | 641 | tegra_admaif_mono_conv_text), \ |
| 565 | NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1,\ | 642 | NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \ |
| 566 | tegra_admaif_get_control, tegra_admaif_put_control, \ | 643 | tegra210_admaif_pget_stereo_to_mono, \ |
| 644 | tegra210_admaif_pput_stereo_to_mono, \ | ||
| 567 | tegra_admaif_stereo_conv_text), \ | 645 | tegra_admaif_stereo_conv_text), \ |
| 568 | NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \ | 646 | NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \ |
| 569 | tegra_admaif_get_control, tegra_admaif_put_control, \ | 647 | tegra210_admaif_cget_mono_to_stereo, \ |
| 648 | tegra210_admaif_cput_mono_to_stereo, \ | ||
| 570 | tegra_admaif_mono_conv_text), \ | 649 | tegra_admaif_mono_conv_text), \ |
| 571 | NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \ | 650 | NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \ |
| 572 | tegra_admaif_get_control, tegra_admaif_put_control, \ | 651 | tegra210_admaif_cget_stereo_to_mono, \ |
| 652 | tegra210_admaif_cput_stereo_to_mono, \ | ||
| 573 | tegra_admaif_stereo_conv_text) | 653 | tegra_admaif_stereo_conv_text) |
| 574 | 654 | ||
| 575 | static struct snd_kcontrol_new tegra210_admaif_controls[] = { | 655 | static struct snd_kcontrol_new tegra210_admaif_controls[] = { |
| @@ -193,6 +193,9 @@ static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol, · 192 unmodified lines | |||
| 193 | struct soc_mixer_control *mc = | 193 | struct soc_mixer_control *mc = |
| 194 | (struct soc_mixer_control *)kcontrol->private_value;; | 194 | (struct soc_mixer_control *)kcontrol->private_value;; |
| 195 | 195 | ||
| 196 | if (value == bytes_map[mc->reg]) | ||
| 197 | return 0; | ||
| 198 | |||
| 196 | if (value >= 0 && value <= 255) { | 199 | if (value >= 0 && value <= 255) { |
| 197 | /* update byte map and enable slot */ | 200 | /* update byte map and enable slot */ |
| 198 | bytes_map[mc->reg] = value; | 201 | bytes_map[mc->reg] = value; |
| @@ -511,8 +514,8 @@ static int tegra210_adx_platform_remove(struct platform_device *pdev) · 312 unmodified lines | |||
| 511 | static const struct dev_pm_ops tegra210_adx_pm_ops = { | 514 | static const struct dev_pm_ops tegra210_adx_pm_ops = { |
| 512 | SET_RUNTIME_PM_OPS(tegra210_adx_runtime_suspend, | 515 | SET_RUNTIME_PM_OPS(tegra210_adx_runtime_suspend, |
| 513 | tegra210_adx_runtime_resume, NULL) | 516 | tegra210_adx_runtime_resume, NULL) |
| 514 | SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | 517 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
| 515 | pm_runtime_force_resume) | 518 | pm_runtime_force_resume) |
| 516 | }; | 519 | }; |
| 517 | 520 | ||
| 518 | static struct platform_driver tegra210_adx_driver = { | 521 | static struct platform_driver tegra210_adx_driver = { |
| @@ -62,6 +62,7 @@ static int tegra_ahub_put_value_enum(struct snd_kcontrol *kctl, · 61 unmodified lines | |||
| 62 | unsigned int *item = uctl->value.enumerated.item; | 62 | unsigned int *item = uctl->value.enumerated.item; |
| 63 | unsigned int value = e->values[item[0]]; | 63 | unsigned int value = e->values[item[0]]; |
| 64 | unsigned int i, bit_pos, reg_idx = 0, reg_val = 0; | 64 | unsigned int i, bit_pos, reg_idx = 0, reg_val = 0; |
| 65 | int change = 0; | ||
| 65 | 66 | ||
| 66 | if (item[0] >= e->items) | 67 | if (item[0] >= e->items) |
| 67 | return -EINVAL; | 68 | return -EINVAL; |
| @@ -86,12 +87,14 @@ static int tegra_ahub_put_value_enum(struct snd_kcontrol *kctl, · 18 unmodified lines | |||
| 86 | 87 | ||
| 87 | /* Update widget power if state has changed */ | 88 | /* Update widget power if state has changed */ |
| 88 | if (snd_soc_component_test_bits(cmpnt, update[i].reg, | 89 | if (snd_soc_component_test_bits(cmpnt, update[i].reg, |
| 89 | update[i].mask, update[i].val)) | 90 | update[i].mask, |
| 90 | snd_soc_dapm_mux_update_power(dapm, kctl, item[0], e, | 91 | update[i].val)) |
| 91 | &update[i]); | 92 | change |= snd_soc_dapm_mux_update_power(dapm, kctl, |
| 93 | item[0], e, | ||
| 94 | &update[i]); | ||
| 92 | } | 95 | } |
| 93 | 96 | ||
| 94 | return 0; | 97 | return change; |
| 95 | } | 98 | } |
| 96 | 99 | ||
| 97 | static struct snd_soc_dai_driver tegra210_ahub_dais[] = { | 100 | static struct snd_soc_dai_driver tegra210_ahub_dais[] = { |
| @@ -222,6 +222,9 @@ static int tegra210_amx_put_byte_map(struct snd_kcontrol *kcontrol, · 221 unmodified lines | |||
| 222 | int reg = mc->reg; | 222 | int reg = mc->reg; |
| 223 | int value = ucontrol->value.integer.value[0]; | 223 | int value = ucontrol->value.integer.value[0]; |
| 224 | 224 | ||
| 225 | if (value == bytes_map[reg]) | ||
| 226 | return 0; | ||
| 227 | |||
| 225 | if (value >= 0 && value <= 255) { | 228 | if (value >= 0 && value <= 255) { |
| 226 | /* Update byte map and enable slot */ | 229 | /* Update byte map and enable slot */ |
| 227 | bytes_map[reg] = value; | 230 | bytes_map[reg] = value; |
| @@ -580,8 +583,8 @@ static int tegra210_amx_platform_remove(struct platform_device *pdev) · 352 unmodified lines | |||
| 580 | static const struct dev_pm_ops tegra210_amx_pm_ops = { | 583 | static const struct dev_pm_ops tegra210_amx_pm_ops = { |
| 581 | SET_RUNTIME_PM_OPS(tegra210_amx_runtime_suspend, | 584 | SET_RUNTIME_PM_OPS(tegra210_amx_runtime_suspend, |
| 582 | tegra210_amx_runtime_resume, NULL) | 585 | tegra210_amx_runtime_resume, NULL) |
| 583 | SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | 586 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
| 584 | pm_runtime_force_resume) | 587 | pm_runtime_force_resume) |
| 585 | }; | 588 | }; |
| 586 | 589 | ||
| 587 | static struct platform_driver tegra210_amx_driver = { | 590 | static struct platform_driver tegra210_amx_driver = { |
| @@ -156,51 +156,162 @@ static int tegra210_dmic_hw_params(struct snd_pcm_substream *substream, · 155 unmodified lines | |||
| 156 | return 0; | 156 | return 0; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static int tegra210_dmic_get_control(struct snd_kcontrol *kcontrol, | 159 | static int tegra210_dmic_get_boost_gain(struct snd_kcontrol *kcontrol, |
| 160 | struct snd_ctl_elem_value *ucontrol) | ||
| 161 | { | ||
| 162 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 163 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 164 | |||
| 165 | ucontrol->value.integer.value[0] = dmic->boost_gain; | ||
| 166 | |||
| 167 | return 0; | ||
| 168 | } | ||
| 169 | |||
| 170 | static int tegra210_dmic_put_boost_gain(struct snd_kcontrol *kcontrol, | ||
| 171 | struct snd_ctl_elem_value *ucontrol) | ||
| 172 | { | ||
| 173 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 174 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 175 | int value = ucontrol->value.integer.value[0]; | ||
| 176 | |||
| 177 | if (value == dmic->boost_gain) | ||
| 178 | return 0; | ||
| 179 | |||
| 180 | dmic->boost_gain = value; | ||
| 181 | |||
| 182 | return 1; | ||
| 183 | } | ||
| 184 | |||
| 185 | static int tegra210_dmic_get_ch_select(struct snd_kcontrol *kcontrol, | ||
| 186 | struct snd_ctl_elem_value *ucontrol) | ||
| 187 | { | ||
| 188 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 189 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 190 | |||
| 191 | ucontrol->value.enumerated.item[0] = dmic->ch_select; | ||
| 192 | |||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | static int tegra210_dmic_put_ch_select(struct snd_kcontrol *kcontrol, | ||
| 197 | struct snd_ctl_elem_value *ucontrol) | ||
| 198 | { | ||
| 199 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 200 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 201 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 202 | |||
| 203 | if (value == dmic->ch_select) | ||
| 204 | return 0; | ||
| 205 | |||
| 206 | dmic->ch_select = value; | ||
| 207 | |||
| 208 | return 1; | ||
| 209 | } | ||
| 210 | |||
| 211 | static int tegra210_dmic_get_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 212 | struct snd_ctl_elem_value *ucontrol) | ||
| 213 | { | ||
| 214 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 215 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 216 | |||
| 217 | ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo; | ||
| 218 | |||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 222 | static int tegra210_dmic_put_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 223 | struct snd_ctl_elem_value *ucontrol) | ||
| 224 | { | ||
| 225 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 226 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 227 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 228 | |||
| 229 | if (value == dmic->mono_to_stereo) | ||
| 230 | return 0; | ||
| 231 | |||
| 232 | dmic->mono_to_stereo = value; | ||
| 233 | |||
| 234 | return 1; | ||
| 235 | } | ||
| 236 | |||
| 237 | static int tegra210_dmic_get_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 238 | struct snd_ctl_elem_value *ucontrol) | ||
| 239 | { | ||
| 240 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 241 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 242 | |||
| 243 | ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono; | ||
| 244 | |||
| 245 | return 0; | ||
| 246 | } | ||
| 247 | |||
| 248 | static int tegra210_dmic_put_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 249 | struct snd_ctl_elem_value *ucontrol) | ||
| 250 | { | ||
| 251 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 252 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 253 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 254 | |||
| 255 | if (value == dmic->stereo_to_mono) | ||
| 256 | return 0; | ||
| 257 | |||
| 258 | dmic->stereo_to_mono = value; | ||
| 259 | |||
| 260 | return 1; | ||
| 261 | } | ||
| 262 | |||
| 263 | static int tegra210_dmic_get_osr_val(struct snd_kcontrol *kcontrol, | ||
| 160 | struct snd_ctl_elem_value *ucontrol) | 264 | struct snd_ctl_elem_value *ucontrol) |
| 161 | { | 265 | { |
| 162 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | 266 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); |
| 163 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | 267 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); |
| 164 | 268 | ||
| 165 | if (strstr(kcontrol->id.name, "Boost Gain Volume")) | 269 | ucontrol->value.enumerated.item[0] = dmic->osr_val; |
| 166 | ucontrol->value.integer.value[0] = dmic->boost_gain; | ||
| 167 | else if (strstr(kcontrol->id.name, "Channel Select")) | ||
| 168 | ucontrol->value.integer.value[0] = dmic->ch_select; | ||
| 169 | else if (strstr(kcontrol->id.name, "Mono To Stereo")) | ||
| 170 | ucontrol->value.integer.value[0] = dmic->mono_to_stereo; | ||
| 171 | else if (strstr(kcontrol->id.name, "Stereo To Mono")) | ||
| 172 | ucontrol->value.integer.value[0] = dmic->stereo_to_mono; | ||
| 173 | else if (strstr(kcontrol->id.name, "OSR Value")) | ||
| 174 | ucontrol->value.integer.value[0] = dmic->osr_val; | ||
| 175 | else if (strstr(kcontrol->id.name, "LR Polarity Select")) | ||
| 176 | ucontrol->value.integer.value[0] = dmic->lrsel; | ||
| 177 | 270 | ||
| 178 | return 0; | 271 | return 0; |
| 179 | } | 272 | } |
| 180 | 273 | ||
| 181 | static int tegra210_dmic_put_control(struct snd_kcontrol *kcontrol, | 274 | static int tegra210_dmic_put_osr_val(struct snd_kcontrol *kcontrol, |
| 182 | struct snd_ctl_elem_value *ucontrol) | 275 | struct snd_ctl_elem_value *ucontrol) |
| 183 | { | 276 | { |
| 184 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | 277 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); |
| 185 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | 278 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); |
| 186 | int value = ucontrol->value.integer.value[0]; | 279 | unsigned int value = ucontrol->value.enumerated.item[0]; |
| 187 | 280 | ||
| 188 | if (strstr(kcontrol->id.name, "Boost Gain Volume")) | 281 | if (value == dmic->osr_val) |
| 189 | dmic->boost_gain = value; | 282 | return 0; |
| 190 | else if (strstr(kcontrol->id.name, "Channel Select")) | 283 | |
| 191 | dmic->ch_select = ucontrol->value.integer.value[0]; | 284 | dmic->osr_val = value; |
| 192 | else if (strstr(kcontrol->id.name, "Mono To Stereo")) | 285 | |
| 193 | dmic->mono_to_stereo = value; | 286 | return 1; |
| 194 | else if (strstr(kcontrol->id.name, "Stereo To Mono")) | 287 | } |
| 195 | dmic->stereo_to_mono = value; | 288 | |
| 196 | else if (strstr(kcontrol->id.name, "OSR Value")) | 289 | static int tegra210_dmic_get_pol_sel(struct snd_kcontrol *kcontrol, |
| 197 | dmic->osr_val = value; | 290 | struct snd_ctl_elem_value *ucontrol) |
| 198 | else if (strstr(kcontrol->id.name, "LR Polarity Select")) | 291 | { |
| 199 | dmic->lrsel = value; | 292 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); |
| 293 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 294 | |||
| 295 | ucontrol->value.enumerated.item[0] = dmic->lrsel; | ||
| 200 | 296 | ||
| 201 | return 0; | 297 | return 0; |
| 202 | } | 298 | } |
| 203 | 299 | ||
| 300 | static int tegra210_dmic_put_pol_sel(struct snd_kcontrol *kcontrol, | ||
| 301 | struct snd_ctl_elem_value *ucontrol) | ||
| 302 | { | ||
| 303 | struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); | ||
| 304 | struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); | ||
| 305 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 306 | |||
| 307 | if (value == dmic->lrsel) | ||
| 308 | return 0; | ||
| 309 | |||
| 310 | dmic->lrsel = value; | ||
| 311 | |||
| 312 | return 1; | ||
| 313 | } | ||
| 314 | |||
| 204 | static const struct snd_soc_dai_ops tegra210_dmic_dai_ops = { | 315 | static const struct snd_soc_dai_ops tegra210_dmic_dai_ops = { |
| 205 | .hw_params = tegra210_dmic_hw_params, | 316 | .hw_params = tegra210_dmic_hw_params, |
| 206 | }; | 317 | }; |
| @@ -287,19 +398,22 @@ static const struct soc_enum tegra210_dmic_lrsel_enum = · 80 unmodified lines | |||
| 287 | 398 | ||
| 288 | static const struct snd_kcontrol_new tegra210_dmic_controls[] = { | 399 | static const struct snd_kcontrol_new tegra210_dmic_controls[] = { |
| 289 | SOC_SINGLE_EXT("Boost Gain Volume", 0, 0, MAX_BOOST_GAIN, 0, | 400 | SOC_SINGLE_EXT("Boost Gain Volume", 0, 0, MAX_BOOST_GAIN, 0, |
| 290 | tegra210_dmic_get_control, tegra210_dmic_put_control), | 401 | tegra210_dmic_get_boost_gain, |
| 402 | tegra210_dmic_put_boost_gain), | ||
| 291 | SOC_ENUM_EXT("Channel Select", tegra210_dmic_ch_enum, | 403 | SOC_ENUM_EXT("Channel Select", tegra210_dmic_ch_enum, |
| 292 | tegra210_dmic_get_control, tegra210_dmic_put_control), | 404 | tegra210_dmic_get_ch_select, tegra210_dmic_put_ch_select), |
| 293 | SOC_ENUM_EXT("Mono To Stereo", | 405 | SOC_ENUM_EXT("Mono To Stereo", |
| 294 | tegra210_dmic_mono_conv_enum, tegra210_dmic_get_control, | 406 | tegra210_dmic_mono_conv_enum, |
| 295 | tegra210_dmic_put_control), | 407 | tegra210_dmic_get_mono_to_stereo, |
| 408 | tegra210_dmic_put_mono_to_stereo), | ||
| 296 | SOC_ENUM_EXT("Stereo To Mono", | 409 | SOC_ENUM_EXT("Stereo To Mono", |
| 297 | tegra210_dmic_stereo_conv_enum, tegra210_dmic_get_control, | 410 | tegra210_dmic_stereo_conv_enum, |
| 298 | tegra210_dmic_put_control), | 411 | tegra210_dmic_get_stereo_to_mono, |
| 412 | tegra210_dmic_put_stereo_to_mono), | ||
| 299 | SOC_ENUM_EXT("OSR Value", tegra210_dmic_osr_enum, | 413 | SOC_ENUM_EXT("OSR Value", tegra210_dmic_osr_enum, |
| 300 | tegra210_dmic_get_control, tegra210_dmic_put_control), | 414 | tegra210_dmic_get_osr_val, tegra210_dmic_put_osr_val), |
| 301 | SOC_ENUM_EXT("LR Polarity Select", tegra210_dmic_lrsel_enum, | 415 | SOC_ENUM_EXT("LR Polarity Select", tegra210_dmic_lrsel_enum, |
| 302 | tegra210_dmic_get_control, tegra210_dmic_put_control), | 416 | tegra210_dmic_get_pol_sel, tegra210_dmic_put_pol_sel), |
| 303 | }; | 417 | }; |
| 304 | 418 | ||
| 305 | static const struct snd_soc_component_driver tegra210_dmic_compnt = { | 419 | static const struct snd_soc_component_driver tegra210_dmic_compnt = { |
| @@ -302,85 +302,235 @@ static int tegra210_i2s_set_tdm_slot(struct snd_soc_dai *dai, · 301 unmodified lines | |||
| 302 | return 0; | 302 | return 0; |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | static int tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, | 305 | static int tegra210_i2s_get_loopback(struct snd_kcontrol *kcontrol, |
| 306 | unsigned int ratio) | 306 | struct snd_ctl_elem_value *ucontrol) |
| 307 | { | 307 | { |
| 308 | struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 308 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); |
| 309 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 309 | 310 | ||
| 310 | i2s->bclk_ratio = ratio; | 311 | ucontrol->value.integer.value[0] = i2s->loopback; |
| 311 | 312 | ||
| 312 | return 0; | 313 | return 0; |
| 313 | } | 314 | } |
| 314 | 315 | ||
| 315 | static int tegra210_i2s_get_control(struct snd_kcontrol *kcontrol, | 316 | static int tegra210_i2s_put_loopback(struct snd_kcontrol *kcontrol, |
| 316 | struct snd_ctl_elem_value *ucontrol) | 317 | struct snd_ctl_elem_value *ucontrol) |
| 318 | { | ||
| 319 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 320 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 321 | int value = ucontrol->value.integer.value[0]; | ||
| 322 | |||
| 323 | if (value == i2s->loopback) | ||
| 324 | return 0; | ||
| 325 | |||
| 326 | i2s->loopback = value; | ||
| 327 | |||
| 328 | regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, I2S_CTRL_LPBK_MASK, | ||
| 329 | i2s->loopback << I2S_CTRL_LPBK_SHIFT); | ||
| 330 | |||
| 331 | return 1; | ||
| 332 | } | ||
| 333 | |||
| 334 | static int tegra210_i2s_get_fsync_width(struct snd_kcontrol *kcontrol, | ||
| 335 | struct snd_ctl_elem_value *ucontrol) | ||
| 317 | { | 336 | { |
| 318 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | 337 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); |
| 319 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | 338 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); |
| 320 | long *uctl_val = &ucontrol->value.integer.value[0]; | 339 | |
| 321 | 340 | ucontrol->value.integer.value[0] = i2s->fsync_width; | |
| 322 | if (strstr(kcontrol->id.name, "Loopback")) | ||
| 323 | *uctl_val = i2s->loopback; | ||
| 324 | else if (strstr(kcontrol->id.name, "FSYNC Width")) | ||
| 325 | *uctl_val = i2s->fsync_width; | ||
| 326 | else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) | ||
| 327 | *uctl_val = i2s->stereo_to_mono[I2S_TX_PATH]; | ||
| 328 | else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) | ||
| 329 | *uctl_val = i2s->mono_to_stereo[I2S_TX_PATH]; | ||
| 330 | else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) | ||
| 331 | *uctl_val = i2s->stereo_to_mono[I2S_RX_PATH]; | ||
| 332 | else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) | ||
| 333 | *uctl_val = i2s->mono_to_stereo[I2S_RX_PATH]; | ||
| 334 | else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) | ||
| 335 | *uctl_val = i2s->rx_fifo_th; | ||
| 336 | else if (strstr(kcontrol->id.name, "BCLK Ratio")) | ||
| 337 | *uctl_val = i2s->bclk_ratio; | ||
| 338 | 341 | ||
| 339 | return 0; | 342 | return 0; |
| 340 | } | 343 | } |
| 341 | 344 | ||
| 342 | static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol, | 345 | static int tegra210_i2s_put_fsync_width(struct snd_kcontrol *kcontrol, |
| 343 | struct snd_ctl_elem_value *ucontrol) | 346 | struct snd_ctl_elem_value *ucontrol) |
| 344 | { | 347 | { |
| 345 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | 348 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); |
| 346 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | 349 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); |
| 347 | int value = ucontrol->value.integer.value[0]; | 350 | int value = ucontrol->value.integer.value[0]; |
| 348 | 351 | ||
| 349 | if (strstr(kcontrol->id.name, "Loopback")) { | 352 | if (value == i2s->fsync_width) |
| 350 | i2s->loopback = value; | 353 | return 0; |
| 351 | 354 | ||
| 352 | regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, | 355 | i2s->fsync_width = value; |
| 353 | I2S_CTRL_LPBK_MASK, | ||
| 354 | i2s->loopback << I2S_CTRL_LPBK_SHIFT); | ||
| 355 | 356 | ||
| 356 | } else if (strstr(kcontrol->id.name, "FSYNC Width")) { | 357 | /* |
| 357 | /* | 358 | * Frame sync width is used only for FSYNC modes and not |
| 358 | * Frame sync width is used only for FSYNC modes and not | 359 | * applicable for LRCK modes. Reset value for this field is "0", |
| 359 | * applicable for LRCK modes. Reset value for this field is "0", | 360 | * which means the width is one bit clock wide. |
| 360 | * which means the width is one bit clock wide. | 361 | * The width requirement may depend on the codec and in such |
| 361 | * The width requirement may depend on the codec and in such | 362 | * cases mixer control is used to update custom values. A value |
| 362 | * cases mixer control is used to update custom values. A value | 363 | * of "N" here means, width is "N + 1" bit clock wide. |
| 363 | * of "N" here means, width is "N + 1" bit clock wide. | 364 | */ |
| 364 | */ | 365 | regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, |
| 365 | i2s->fsync_width = value; | 366 | I2S_CTRL_FSYNC_WIDTH_MASK, |
| 366 | 367 | i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); | |
| 367 | regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, | 368 | |
| 368 | I2S_CTRL_FSYNC_WIDTH_MASK, | 369 | return 1; |
| 369 | i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); | 370 | } |
| 370 | 371 | ||
| 371 | } else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) { | 372 | static int tegra210_i2s_cget_stereo_to_mono(struct snd_kcontrol *kcontrol, |
| 372 | i2s->stereo_to_mono[I2S_TX_PATH] = value; | 373 | struct snd_ctl_elem_value *ucontrol) |
| 373 | } else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) { | 374 | { |
| 374 | i2s->mono_to_stereo[I2S_TX_PATH] = value; | 375 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); |
| 375 | } else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) { | 376 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); |
| 376 | i2s->stereo_to_mono[I2S_RX_PATH] = value; | 377 | |
| 377 | } else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) { | 378 | ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_TX_PATH]; |
| 378 | i2s->mono_to_stereo[I2S_RX_PATH] = value; | 379 | |
| 379 | } else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) { | 380 | return 0; |
| 380 | i2s->rx_fifo_th = value; | 381 | } |
| 381 | } else if (strstr(kcontrol->id.name, "BCLK Ratio")) { | 382 | |
| 382 | i2s->bclk_ratio = value; | 383 | static int tegra210_i2s_cput_stereo_to_mono(struct snd_kcontrol *kcontrol, |
| 383 | } | 384 | struct snd_ctl_elem_value *ucontrol) |
| 385 | { | ||
| 386 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 387 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 388 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 389 | |||
| 390 | if (value == i2s->stereo_to_mono[I2S_TX_PATH]) | ||
| 391 | return 0; | ||
| 392 | |||
| 393 | i2s->stereo_to_mono[I2S_TX_PATH] = value; | ||
| 394 | |||
| 395 | return 1; | ||
| 396 | } | ||
| 397 | |||
| 398 | static int tegra210_i2s_cget_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 399 | struct snd_ctl_elem_value *ucontrol) | ||
| 400 | { | ||
| 401 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 402 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 403 | |||
| 404 | ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_TX_PATH]; | ||
| 405 | |||
| 406 | return 0; | ||
| 407 | } | ||
| 408 | |||
| 409 | static int tegra210_i2s_cput_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 410 | struct snd_ctl_elem_value *ucontrol) | ||
| 411 | { | ||
| 412 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 413 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 414 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 415 | |||
| 416 | if (value == i2s->mono_to_stereo[I2S_TX_PATH]) | ||
| 417 | return 0; | ||
| 418 | |||
| 419 | i2s->mono_to_stereo[I2S_TX_PATH] = value; | ||
| 420 | |||
| 421 | return 1; | ||
| 422 | } | ||
| 423 | |||
| 424 | static int tegra210_i2s_pget_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 425 | struct snd_ctl_elem_value *ucontrol) | ||
| 426 | { | ||
| 427 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 428 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 429 | |||
| 430 | ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_RX_PATH]; | ||
| 431 | |||
| 432 | return 0; | ||
| 433 | } | ||
| 434 | |||
| 435 | static int tegra210_i2s_pput_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 436 | struct snd_ctl_elem_value *ucontrol) | ||
| 437 | { | ||
| 438 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 439 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 440 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 441 | |||
| 442 | if (value == i2s->stereo_to_mono[I2S_RX_PATH]) | ||
| 443 | return 0; | ||
| 444 | |||
| 445 | i2s->stereo_to_mono[I2S_RX_PATH] = value; | ||
| 446 | |||
| 447 | return 1; | ||
| 448 | } | ||
| 449 | |||
| 450 | static int tegra210_i2s_pget_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 451 | struct snd_ctl_elem_value *ucontrol) | ||
| 452 | { | ||
| 453 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 454 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 455 | |||
| 456 | ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_RX_PATH]; | ||
| 457 | |||
| 458 | return 0; | ||
| 459 | } | ||
| 460 | |||
| 461 | static int tegra210_i2s_pput_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 462 | struct snd_ctl_elem_value *ucontrol) | ||
| 463 | { | ||
| 464 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 465 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 466 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 467 | |||
| 468 | if (value == i2s->mono_to_stereo[I2S_RX_PATH]) | ||
| 469 | return 0; | ||
| 470 | |||
| 471 | i2s->mono_to_stereo[I2S_RX_PATH] = value; | ||
| 472 | |||
| 473 | return 1; | ||
| 474 | } | ||
| 475 | |||
| 476 | static int tegra210_i2s_pget_fifo_th(struct snd_kcontrol *kcontrol, | ||
| 477 | struct snd_ctl_elem_value *ucontrol) | ||
| 478 | { | ||
| 479 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 480 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 481 | |||
| 482 | ucontrol->value.integer.value[0] = i2s->rx_fifo_th; | ||
| 483 | |||
| 484 | return 0; | ||
| 485 | } | ||
| 486 | |||
| 487 | static int tegra210_i2s_pput_fifo_th(struct snd_kcontrol *kcontrol, | ||
| 488 | struct snd_ctl_elem_value *ucontrol) | ||
| 489 | { | ||
| 490 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 491 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 492 | int value = ucontrol->value.integer.value[0]; | ||
| 493 | |||
| 494 | if (value == i2s->rx_fifo_th) | ||
| 495 | return 0; | ||
| 496 | |||
| 497 | i2s->rx_fifo_th = value; | ||
| 498 | |||
| 499 | return 1; | ||
| 500 | } | ||
| 501 | |||
| 502 | static int tegra210_i2s_get_bclk_ratio(struct snd_kcontrol *kcontrol, | ||
| 503 | struct snd_ctl_elem_value *ucontrol) | ||
| 504 | { | ||
| 505 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 506 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 507 | |||
| 508 | ucontrol->value.integer.value[0] = i2s->bclk_ratio; | ||
| 509 | |||
| 510 | return 0; | ||
| 511 | } | ||
| 512 | |||
| 513 | static int tegra210_i2s_put_bclk_ratio(struct snd_kcontrol *kcontrol, | ||
| 514 | struct snd_ctl_elem_value *ucontrol) | ||
| 515 | { | ||
| 516 | struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); | ||
| 517 | struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); | ||
| 518 | int value = ucontrol->value.integer.value[0]; | ||
| 519 | |||
| 520 | if (value == i2s->bclk_ratio) | ||
| 521 | return 0; | ||
| 522 | |||
| 523 | i2s->bclk_ratio = value; | ||
| 524 | |||
| 525 | return 1; | ||
| 526 | } | ||
| 527 | |||
| 528 | static int tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, | ||
| 529 | unsigned int ratio) | ||
| 530 | { | ||
| 531 | struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai); | ||
| 532 | |||
| 533 | i2s->bclk_ratio = ratio; | ||
| 384 | 534 | ||
| 385 | return 0; | 535 | return 0; |
| 386 | } | 536 | } |
| @@ -598,22 +748,28 @@ static const struct soc_enum tegra210_i2s_stereo_conv_enum = · 211 unmodified lines | |||
| 598 | tegra210_i2s_stereo_conv_text); | 748 | tegra210_i2s_stereo_conv_text); |
| 599 | 749 | ||
| 600 | static const struct snd_kcontrol_new tegra210_i2s_controls[] = { | 750 | static const struct snd_kcontrol_new tegra210_i2s_controls[] = { |
| 601 | SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_control, | 751 | SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_loopback, |
| 602 | tegra210_i2s_put_control), | 752 | tegra210_i2s_put_loopback), |
| 603 | SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0, tegra210_i2s_get_control, | 753 | SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0, |
| 604 | tegra210_i2s_put_control), | 754 | tegra210_i2s_get_fsync_width, |
| 755 | tegra210_i2s_put_fsync_width), | ||
| 605 | SOC_ENUM_EXT("Capture Stereo To Mono", tegra210_i2s_stereo_conv_enum, | 756 | SOC_ENUM_EXT("Capture Stereo To Mono", tegra210_i2s_stereo_conv_enum, |
| 606 | tegra210_i2s_get_control, tegra210_i2s_put_control), | 757 | tegra210_i2s_cget_stereo_to_mono, |
| 758 | tegra210_i2s_cput_stereo_to_mono), | ||
| 607 | SOC_ENUM_EXT("Capture Mono To Stereo", tegra210_i2s_mono_conv_enum, | 759 | SOC_ENUM_EXT("Capture Mono To Stereo", tegra210_i2s_mono_conv_enum, |
| 608 | tegra210_i2s_get_control, tegra210_i2s_put_control), | 760 | tegra210_i2s_cget_mono_to_stereo, |
| 761 | tegra210_i2s_cput_mono_to_stereo), | ||
| 609 | SOC_ENUM_EXT("Playback Stereo To Mono", tegra210_i2s_stereo_conv_enum, | 762 | SOC_ENUM_EXT("Playback Stereo To Mono", tegra210_i2s_stereo_conv_enum, |
| 610 | tegra210_i2s_get_control, tegra210_i2s_put_control), | 763 | tegra210_i2s_pget_mono_to_stereo, |
| 764 | tegra210_i2s_pput_mono_to_stereo), | ||
| 611 | SOC_ENUM_EXT("Playback Mono To Stereo", tegra210_i2s_mono_conv_enum, | 765 | SOC_ENUM_EXT("Playback Mono To Stereo", tegra210_i2s_mono_conv_enum, |
| 612 | tegra210_i2s_get_control, tegra210_i2s_put_control), | 766 | tegra210_i2s_pget_stereo_to_mono, |
| 767 | tegra210_i2s_pput_stereo_to_mono), | ||
| 613 | SOC_SINGLE_EXT("Playback FIFO Threshold", 0, 0, I2S_RX_FIFO_DEPTH - 1, | 768 | SOC_SINGLE_EXT("Playback FIFO Threshold", 0, 0, I2S_RX_FIFO_DEPTH - 1, |
| 614 | 0, tegra210_i2s_get_control, tegra210_i2s_put_control), | 769 | 0, tegra210_i2s_pget_fifo_th, tegra210_i2s_pput_fifo_th), |
| 615 | SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0, tegra210_i2s_get_control, | 770 | SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0, |
| 616 | tegra210_i2s_put_control), | 771 | tegra210_i2s_get_bclk_ratio, |
| 772 | tegra210_i2s_put_bclk_ratio), | ||
| 617 | }; | 773 | }; |
| 618 | 774 | ||
| 619 | static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = { | 775 | static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = { |
| @@ -192,24 +192,24 @@ static int tegra210_mixer_get_gain(struct snd_kcontrol *kcontrol, · 191 unmodified lines | |||
| 192 | return 0; | 192 | return 0; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static int tegra210_mixer_put_gain(struct snd_kcontrol *kcontrol, | 195 | static int tegra210_mixer_apply_gain(struct snd_kcontrol *kcontrol, |
| 196 | struct snd_ctl_elem_value *ucontrol) | 196 | struct snd_ctl_elem_value *ucontrol, |
| 197 | bool instant_gain) | ||
| 197 | { | 198 | { |
| 198 | struct soc_mixer_control *mc = | 199 | struct soc_mixer_control *mc = |
| 199 | (struct soc_mixer_control *)kcontrol->private_value; | 200 | (struct soc_mixer_control *)kcontrol->private_value; |
| 200 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | 201 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); |
| 201 | struct tegra210_mixer *mixer = snd_soc_component_get_drvdata(cmpnt); | 202 | struct tegra210_mixer *mixer = snd_soc_component_get_drvdata(cmpnt); |
| 202 | unsigned int reg = mc->reg, id; | 203 | unsigned int reg = mc->reg, id; |
| 203 | bool instant_gain = false; | ||
| 204 | int err; | 204 | int err; |
| 205 | 205 | ||
| 206 | if (strstr(kcontrol->id.name, "Instant Gain Volume")) | ||
| 207 | instant_gain = true; | ||
| 208 | |||
| 209 | /* Save gain value for specific MIXER input */ | 206 | /* Save gain value for specific MIXER input */ |
| 210 | id = (reg - TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_0) / | 207 | id = (reg - TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_0) / |
| 211 | TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_STRIDE; | 208 | TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_STRIDE; |
| 212 | 209 | ||
| 210 | if (mixer->gain_value[id] == ucontrol->value.integer.value[0]) | ||
| 211 | return 0; | ||
| 212 | |||
| 213 | mixer->gain_value[id] = ucontrol->value.integer.value[0]; | 213 | mixer->gain_value[id] = ucontrol->value.integer.value[0]; |
| 214 | 214 | ||
| 215 | err = tegra210_mixer_configure_gain(cmpnt, id, instant_gain); | 215 | err = tegra210_mixer_configure_gain(cmpnt, id, instant_gain); |
| @@ -221,6 +221,18 @@ static int tegra210_mixer_put_gain(struct snd_kcontrol *kcontrol, · 5 unmodified lines | |||
| 221 | return 1; | 221 | return 1; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | static int tegra210_mixer_put_gain(struct snd_kcontrol *kcontrol, | ||
| 225 | struct snd_ctl_elem_value *ucontrol) | ||
| 226 | { | ||
| 227 | return tegra210_mixer_apply_gain(kcontrol, ucontrol, false); | ||
| 228 | } | ||
| 229 | |||
| 230 | static int tegra210_mixer_put_instant_gain(struct snd_kcontrol *kcontrol, | ||
| 231 | struct snd_ctl_elem_value *ucontrol) | ||
| 232 | { | ||
| 233 | return tegra210_mixer_apply_gain(kcontrol, ucontrol, true); | ||
| 234 | } | ||
| 235 | |||
| 224 | static int tegra210_mixer_set_audio_cif(struct tegra210_mixer *mixer, | 236 | static int tegra210_mixer_set_audio_cif(struct tegra210_mixer *mixer, |
| 225 | struct snd_pcm_hw_params *params, | 237 | struct snd_pcm_hw_params *params, |
| 226 | unsigned int reg, | 238 | unsigned int reg, |
| @@ -388,7 +400,7 @@ ADDER_CTRL_DECL(adder5, TEGRA210_MIXER_TX5_ADDER_CONFIG); · 161 unmodified lines | |||
| 388 | SOC_SINGLE_EXT("RX" #id " Instant Gain Volume", \ | 400 | SOC_SINGLE_EXT("RX" #id " Instant Gain Volume", \ |
| 389 | MIXER_GAIN_CFG_RAM_ADDR((id) - 1), 0, \ | 401 | MIXER_GAIN_CFG_RAM_ADDR((id) - 1), 0, \ |
| 390 | 0x20000, 0, tegra210_mixer_get_gain, \ | 402 | 0x20000, 0, tegra210_mixer_get_gain, \ |
| 391 | tegra210_mixer_put_gain), | 403 | tegra210_mixer_put_instant_gain), |
| 392 | 404 | ||
| 393 | /* Volume controls for all MIXER inputs */ | 405 | /* Volume controls for all MIXER inputs */ |
| 394 | static const struct snd_kcontrol_new tegra210_mixer_gain_ctls[] = { | 406 | static const struct snd_kcontrol_new tegra210_mixer_gain_ctls[] = { |
| @@ -654,8 +666,8 @@ static int tegra210_mixer_platform_remove(struct platform_device *pdev) · 259 unmodified lines | |||
| 654 | static const struct dev_pm_ops tegra210_mixer_pm_ops = { | 666 | static const struct dev_pm_ops tegra210_mixer_pm_ops = { |
| 655 | SET_RUNTIME_PM_OPS(tegra210_mixer_runtime_suspend, | 667 | SET_RUNTIME_PM_OPS(tegra210_mixer_runtime_suspend, |
| 656 | tegra210_mixer_runtime_resume, NULL) | 668 | tegra210_mixer_runtime_resume, NULL) |
| 657 | SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | 669 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
| 658 | pm_runtime_force_resume) | 670 | pm_runtime_force_resume) |
| 659 | }; | 671 | }; |
| 660 | 672 | ||
| 661 | static struct platform_driver tegra210_mixer_driver = { | 673 | static struct platform_driver tegra210_mixer_driver = { |
| @@ -136,7 +136,7 @@ static int tegra210_mvc_put_mute(struct snd_kcontrol *kcontrol, · 135 unmodified lines | |||
| 136 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | 136 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); |
| 137 | struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); | 137 | struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); |
| 138 | unsigned int value; | 138 | unsigned int value; |
| 139 | u8 mute_mask; | 139 | u8 new_mask, old_mask; |
| 140 | int err; | 140 | int err; |
| 141 | 141 | ||
| 142 | pm_runtime_get_sync(cmpnt->dev); | 142 | pm_runtime_get_sync(cmpnt->dev); |
| @@ -148,15 +148,23 @@ static int tegra210_mvc_put_mute(struct snd_kcontrol *kcontrol, · 5 unmodified lines | |||
| 148 | if (err < 0) | 148 | if (err < 0) |
| 149 | goto end; | 149 | goto end; |
| 150 | 150 | ||
| 151 | mute_mask = ucontrol->value.integer.value[0]; | 151 | regmap_read(mvc->regmap, TEGRA210_MVC_CTRL, &value); |
| 152 | |||
| 153 | old_mask = (value >> TEGRA210_MVC_MUTE_SHIFT) & TEGRA210_MUTE_MASK_EN; | ||
| 154 | new_mask = ucontrol->value.integer.value[0]; | ||
| 155 | |||
| 156 | if (new_mask == old_mask) { | ||
| 157 | err = 0; | ||
| 158 | goto end; | ||
| 159 | } | ||
| 152 | 160 | ||
| 153 | err = regmap_update_bits(mvc->regmap, mc->reg, | 161 | err = regmap_update_bits(mvc->regmap, mc->reg, |
| 154 | TEGRA210_MVC_MUTE_MASK, | 162 | TEGRA210_MVC_MUTE_MASK, |
| 155 | mute_mask << TEGRA210_MVC_MUTE_SHIFT); | 163 | new_mask << TEGRA210_MVC_MUTE_SHIFT); |
| 156 | if (err < 0) | 164 | if (err < 0) |
| 157 | goto end; | 165 | goto end; |
| 158 | 166 | ||
| 159 | return 1; | 167 | err = 1; |
| 160 | 168 | ||
| 161 | end: | 169 | end: |
| 162 | pm_runtime_put(cmpnt->dev); | 170 | pm_runtime_put(cmpnt->dev); |
| @@ -195,7 +203,7 @@ static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol, · 32 unmodified lines | |||
| 195 | unsigned int reg = mc->reg; | 203 | unsigned int reg = mc->reg; |
| 196 | unsigned int value; | 204 | unsigned int value; |
| 197 | u8 chan; | 205 | u8 chan; |
| 198 | int err; | 206 | int err, old_volume; |
| 199 | 207 | ||
| 200 | pm_runtime_get_sync(cmpnt->dev); | 208 | pm_runtime_get_sync(cmpnt->dev); |
| 201 | 209 | ||
| @@ -207,10 +215,16 @@ static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol, · 5 unmodified lines | |||
| 207 | goto end; | 215 | goto end; |
| 208 | 216 | ||
| 209 | chan = (reg - TEGRA210_MVC_TARGET_VOL) / REG_SIZE; | 217 | chan = (reg - TEGRA210_MVC_TARGET_VOL) / REG_SIZE; |
| 218 | old_volume = mvc->volume[chan]; | ||
| 210 | 219 | ||
| 211 | tegra210_mvc_conv_vol(mvc, chan, | 220 | tegra210_mvc_conv_vol(mvc, chan, |
| 212 | ucontrol->value.integer.value[0]); | 221 | ucontrol->value.integer.value[0]); |
| 213 | 222 | ||
| 223 | if (mvc->volume[chan] == old_volume) { | ||
| 224 | err = 0; | ||
| 225 | goto end; | ||
| 226 | } | ||
| 227 | |||
| 214 | /* Configure init volume same as target volume */ | 228 | /* Configure init volume same as target volume */ |
| 215 | regmap_write(mvc->regmap, | 229 | regmap_write(mvc->regmap, |
| 216 | TEGRA210_MVC_REG_OFFSET(TEGRA210_MVC_INIT_VOL, chan), | 230 | TEGRA210_MVC_REG_OFFSET(TEGRA210_MVC_INIT_VOL, chan), |
| @@ -222,7 +236,7 @@ static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol, · 5 unmodified lines | |||
| 222 | TEGRA210_MVC_VOLUME_SWITCH_MASK, | 236 | TEGRA210_MVC_VOLUME_SWITCH_MASK, |
| 223 | TEGRA210_MVC_VOLUME_SWITCH_TRIGGER); | 237 | TEGRA210_MVC_VOLUME_SWITCH_TRIGGER); |
| 224 | 238 | ||
| 225 | return 1; | 239 | err = 1; |
| 226 | 240 | ||
| 227 | end: | 241 | end: |
| 228 | pm_runtime_put(cmpnt->dev); | 242 | pm_runtime_put(cmpnt->dev); |
| @@ -275,7 +289,7 @@ static int tegra210_mvc_get_curve_type(struct snd_kcontrol *kcontrol, · 46 unmodified lines | |||
| 275 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | 289 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); |
| 276 | struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); | 290 | struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); |
| 277 | 291 | ||
| 278 | ucontrol->value.integer.value[0] = mvc->curve_type; | 292 | ucontrol->value.enumerated.item[0] = mvc->curve_type; |
| 279 | 293 | ||
| 280 | return 0; | 294 | return 0; |
| 281 | } | 295 | } |
| @@ -285,7 +299,7 @@ static int tegra210_mvc_put_curve_type(struct snd_kcontrol *kcontrol, · 3 unmodified lines | |||
| 285 | { | 299 | { |
| 286 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | 300 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); |
| 287 | struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); | 301 | struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); |
| 288 | int value; | 302 | unsigned int value; |
| 289 | 303 | ||
| 290 | regmap_read(mvc->regmap, TEGRA210_MVC_ENABLE, &value); | 304 | regmap_read(mvc->regmap, TEGRA210_MVC_ENABLE, &value); |
| 291 | if (value & TEGRA210_MVC_EN) { | 305 | if (value & TEGRA210_MVC_EN) { |
| @@ -294,10 +308,10 @@ static int tegra210_mvc_put_curve_type(struct snd_kcontrol *kcontrol, · 2 unmodified lines | |||
| 294 | return -EINVAL; | 308 | return -EINVAL; |
| 295 | } | 309 | } |
| 296 | 310 | ||
| 297 | if (mvc->curve_type == ucontrol->value.integer.value[0]) | 311 | if (mvc->curve_type == ucontrol->value.enumerated.item[0]) |
| 298 | return 0; | 312 | return 0; |
| 299 | 313 | ||
| 300 | mvc->curve_type = ucontrol->value.integer.value[0]; | 314 | mvc->curve_type = ucontrol->value.enumerated.item[0]; |
| 301 | 315 | ||
| 302 | tegra210_mvc_reset_vol_settings(mvc, cmpnt->dev); | 316 | tegra210_mvc_reset_vol_settings(mvc, cmpnt->dev); |
| 303 | 317 | ||
| @@ -625,8 +639,8 @@ static int tegra210_mvc_platform_remove(struct platform_device *pdev) · 321 unmodified lines | |||
| 625 | static const struct dev_pm_ops tegra210_mvc_pm_ops = { | 639 | static const struct dev_pm_ops tegra210_mvc_pm_ops = { |
| 626 | SET_RUNTIME_PM_OPS(tegra210_mvc_runtime_suspend, | 640 | SET_RUNTIME_PM_OPS(tegra210_mvc_runtime_suspend, |
| 627 | tegra210_mvc_runtime_resume, NULL) | 641 | tegra210_mvc_runtime_resume, NULL) |
| 628 | SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | 642 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
| 629 | pm_runtime_force_resume) | 643 | pm_runtime_force_resume) |
| 630 | }; | 644 | }; |
| 631 | 645 | ||
| 632 | static struct platform_driver tegra210_mvc_driver = { | 646 | static struct platform_driver tegra210_mvc_driver = { |
| @@ -3244,46 +3244,107 @@ static int tegra210_sfc_init(struct snd_soc_dapm_widget *w, · 3243 unmodified lines | |||
| 3244 | return tegra210_sfc_write_coeff_ram(cmpnt); | 3244 | return tegra210_sfc_write_coeff_ram(cmpnt); |
| 3245 | } | 3245 | } |
| 3246 | 3246 | ||
| 3247 | static int tegra210_sfc_get_control(struct snd_kcontrol *kcontrol, | 3247 | static int tegra210_sfc_iget_stereo_to_mono(struct snd_kcontrol *kcontrol, |
| 3248 | struct snd_ctl_elem_value *ucontrol) | 3248 | struct snd_ctl_elem_value *ucontrol) |
| 3249 | { | 3249 | { |
| 3250 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | 3250 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); |
| 3251 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); | 3251 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); |
| 3252 | 3252 | ||
| 3253 | if (strstr(kcontrol->id.name, "Input Stereo To Mono")) | 3253 | ucontrol->value.enumerated.item[0] = sfc->stereo_to_mono[SFC_RX_PATH]; |
| 3254 | ucontrol->value.integer.value[0] = | ||
| 3255 | sfc->stereo_to_mono[SFC_RX_PATH]; | ||
| 3256 | else if (strstr(kcontrol->id.name, "Input Mono To Stereo")) | ||
| 3257 | ucontrol->value.integer.value[0] = | ||
| 3258 | sfc->mono_to_stereo[SFC_RX_PATH]; | ||
| 3259 | else if (strstr(kcontrol->id.name, "Output Stereo To Mono")) | ||
| 3260 | ucontrol->value.integer.value[0] = | ||
| 3261 | sfc->stereo_to_mono[SFC_TX_PATH]; | ||
| 3262 | else if (strstr(kcontrol->id.name, "Output Mono To Stereo")) | ||
| 3263 | ucontrol->value.integer.value[0] = | ||
| 3264 | sfc->mono_to_stereo[SFC_TX_PATH]; | ||
| 3265 | 3254 | ||
| 3266 | return 0; | 3255 | return 0; |
| 3267 | } | 3256 | } |
| 3268 | 3257 | ||
| 3269 | static int tegra210_sfc_put_control(struct snd_kcontrol *kcontrol, | 3258 | static int tegra210_sfc_iput_stereo_to_mono(struct snd_kcontrol *kcontrol, |
| 3270 | struct snd_ctl_elem_value *ucontrol) | 3259 | struct snd_ctl_elem_value *ucontrol) |
| 3271 | { | 3260 | { |
| 3272 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | 3261 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); |
| 3273 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); | 3262 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); |
| 3274 | int value = ucontrol->value.integer.value[0]; | 3263 | unsigned int value = ucontrol->value.enumerated.item[0]; |
| 3275 | 3264 | ||
| 3276 | if (strstr(kcontrol->id.name, "Input Stereo To Mono")) | 3265 | if (value == sfc->stereo_to_mono[SFC_RX_PATH]) |
| 3277 | sfc->stereo_to_mono[SFC_RX_PATH] = value; | 3266 | return 0; |
| 3278 | else if (strstr(kcontrol->id.name, "Input Mono To Stereo")) | 3267 | |
| 3279 | sfc->mono_to_stereo[SFC_RX_PATH] = value; | 3268 | sfc->stereo_to_mono[SFC_RX_PATH] = value; |
| 3280 | else if (strstr(kcontrol->id.name, "Output Stereo To Mono")) | 3269 | |
| 3281 | sfc->stereo_to_mono[SFC_TX_PATH] = value; | 3270 | return 1; |
| 3282 | else if (strstr(kcontrol->id.name, "Output Mono To Stereo")) | 3271 | } |
| 3283 | sfc->mono_to_stereo[SFC_TX_PATH] = value; | 3272 | |
| 3284 | else | 3273 | static int tegra210_sfc_iget_mono_to_stereo(struct snd_kcontrol *kcontrol, |
| 3274 | struct snd_ctl_elem_value *ucontrol) | ||
| 3275 | { | ||
| 3276 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 3277 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); | ||
| 3278 | |||
| 3279 | ucontrol->value.enumerated.item[0] = sfc->mono_to_stereo[SFC_RX_PATH]; | ||
| 3280 | |||
| 3281 | return 0; | ||
| 3282 | } | ||
| 3283 | |||
| 3284 | static int tegra210_sfc_iput_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 3285 | struct snd_ctl_elem_value *ucontrol) | ||
| 3286 | { | ||
| 3287 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 3288 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); | ||
| 3289 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 3290 | |||
| 3291 | if (value == sfc->mono_to_stereo[SFC_RX_PATH]) | ||
| 3285 | return 0; | 3292 | return 0; |
| 3286 | 3293 | ||
| 3294 | sfc->mono_to_stereo[SFC_RX_PATH] = value; | ||
| 3295 | |||
| 3296 | return 1; | ||
| 3297 | } | ||
| 3298 | |||
| 3299 | static int tegra210_sfc_oget_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 3300 | struct snd_ctl_elem_value *ucontrol) | ||
| 3301 | { | ||
| 3302 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 3303 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); | ||
| 3304 | |||
| 3305 | ucontrol->value.enumerated.item[0] = sfc->stereo_to_mono[SFC_TX_PATH]; | ||
| 3306 | |||
| 3307 | return 0; | ||
| 3308 | } | ||
| 3309 | |||
| 3310 | static int tegra210_sfc_oput_stereo_to_mono(struct snd_kcontrol *kcontrol, | ||
| 3311 | struct snd_ctl_elem_value *ucontrol) | ||
| 3312 | { | ||
| 3313 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 3314 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); | ||
| 3315 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 3316 | |||
| 3317 | if (value == sfc->stereo_to_mono[SFC_TX_PATH]) | ||
| 3318 | return 0; | ||
| 3319 | |||
| 3320 | sfc->stereo_to_mono[SFC_TX_PATH] = value; | ||
| 3321 | |||
| 3322 | return 1; | ||
| 3323 | } | ||
| 3324 | |||
| 3325 | static int tegra210_sfc_oget_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 3326 | struct snd_ctl_elem_value *ucontrol) | ||
| 3327 | { | ||
| 3328 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 3329 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); | ||
| 3330 | |||
| 3331 | ucontrol->value.enumerated.item[0] = sfc->mono_to_stereo[SFC_TX_PATH]; | ||
| 3332 | |||
| 3333 | return 0; | ||
| 3334 | } | ||
| 3335 | |||
| 3336 | static int tegra210_sfc_oput_mono_to_stereo(struct snd_kcontrol *kcontrol, | ||
| 3337 | struct snd_ctl_elem_value *ucontrol) | ||
| 3338 | { | ||
| 3339 | struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); | ||
| 3340 | struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); | ||
| 3341 | unsigned int value = ucontrol->value.enumerated.item[0]; | ||
| 3342 | |||
| 3343 | if (value == sfc->mono_to_stereo[SFC_TX_PATH]) | ||
| 3344 | return 0; | ||
| 3345 | |||
| 3346 | sfc->mono_to_stereo[SFC_TX_PATH] = value; | ||
| 3347 | |||
| 3287 | return 1; | 3348 | return 1; |
| 3288 | } | 3349 | } |
| 3289 | 3350 | ||
| @@ -3384,13 +3445,17 @@ static const struct soc_enum tegra210_sfc_mono_conv_enum = · 94 unmodified lines | |||
| 3384 | 3445 | ||
| 3385 | static const struct snd_kcontrol_new tegra210_sfc_controls[] = { | 3446 | static const struct snd_kcontrol_new tegra210_sfc_controls[] = { |
| 3386 | SOC_ENUM_EXT("Input Stereo To Mono", tegra210_sfc_stereo_conv_enum, | 3447 | SOC_ENUM_EXT("Input Stereo To Mono", tegra210_sfc_stereo_conv_enum, |
| 3387 | tegra210_sfc_get_control, tegra210_sfc_put_control), | 3448 | tegra210_sfc_iget_stereo_to_mono, |
| 3449 | tegra210_sfc_iput_stereo_to_mono), | ||
| 3388 | SOC_ENUM_EXT("Input Mono To Stereo", tegra210_sfc_mono_conv_enum, | 3450 | SOC_ENUM_EXT("Input Mono To Stereo", tegra210_sfc_mono_conv_enum, |
| 3389 | tegra210_sfc_get_control, tegra210_sfc_put_control), | 3451 | tegra210_sfc_iget_mono_to_stereo, |
| 3452 | tegra210_sfc_iput_mono_to_stereo), | ||
| 3390 | SOC_ENUM_EXT("Output Stereo To Mono", tegra210_sfc_stereo_conv_enum, | 3453 | SOC_ENUM_EXT("Output Stereo To Mono", tegra210_sfc_stereo_conv_enum, |
| 3391 | tegra210_sfc_get_control, tegra210_sfc_put_control), | 3454 | tegra210_sfc_oget_stereo_to_mono, |
| 3455 | tegra210_sfc_oput_stereo_to_mono), | ||
| 3392 | SOC_ENUM_EXT("Output Mono To Stereo", tegra210_sfc_mono_conv_enum, | 3456 | SOC_ENUM_EXT("Output Mono To Stereo", tegra210_sfc_mono_conv_enum, |
| 3393 | tegra210_sfc_get_control, tegra210_sfc_put_control), | 3457 | tegra210_sfc_oget_mono_to_stereo, |
| 3458 | tegra210_sfc_oput_mono_to_stereo), | ||
| 3394 | }; | 3459 | }; |
| 3395 | 3460 | ||
| 3396 | static const struct snd_soc_component_driver tegra210_sfc_cmpnt = { | 3461 | static const struct snd_soc_component_driver tegra210_sfc_cmpnt = { |
| @@ -3529,8 +3594,8 @@ static int tegra210_sfc_platform_remove(struct platform_device *pdev) · 132 unmodified lines | |||
| 3529 | static const struct dev_pm_ops tegra210_sfc_pm_ops = { | 3594 | static const struct dev_pm_ops tegra210_sfc_pm_ops = { |
| 3530 | SET_RUNTIME_PM_OPS(tegra210_sfc_runtime_suspend, | 3595 | SET_RUNTIME_PM_OPS(tegra210_sfc_runtime_suspend, |
| 3531 | tegra210_sfc_runtime_resume, NULL) | 3596 | tegra210_sfc_runtime_resume, NULL) |
| 3532 | SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | 3597 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
| 3533 | pm_runtime_force_resume) | 3598 | pm_runtime_force_resume) |
| 3534 | }; | 3599 | }; |
| 3535 | 3600 | ||
| 3536 | static struct platform_driver tegra210_sfc_driver = { | 3601 | static struct platform_driver tegra210_sfc_driver = { |
| @@ -3016,11 +3016,11 @@ static const struct snd_djm_ctl snd_djm_ctls_750mk2[] = { · 3015 unmodified lines | |||
| 3016 | 3016 | ||
| 3017 | 3017 | ||
| 3018 | static const struct snd_djm_device snd_djm_devices[] = { | 3018 | static const struct snd_djm_device snd_djm_devices[] = { |
| 3019 | SND_DJM_DEVICE(250mk2), | 3019 | [SND_DJM_250MK2_IDX] = SND_DJM_DEVICE(250mk2), |
| 3020 | SND_DJM_DEVICE(750), | 3020 | [SND_DJM_750_IDX] = SND_DJM_DEVICE(750), |
| 3021 | SND_DJM_DEVICE(750mk2), | 3021 | [SND_DJM_850_IDX] = SND_DJM_DEVICE(850), |
| 3022 | SND_DJM_DEVICE(850), | 3022 | [SND_DJM_900NXS2_IDX] = SND_DJM_DEVICE(900nxs2), |
| 3023 | SND_DJM_DEVICE(900nxs2) | 3023 | [SND_DJM_750MK2_IDX] = SND_DJM_DEVICE(750mk2), |
| 3024 | }; | 3024 | }; |
| 3025 | 3025 | ||
| 3026 | 3026 | ||
| @@ -83,6 +83,7 @@ struct btf_id { · 82 unmodified lines | |||
| 83 | int cnt; | 83 | int cnt; |
| 84 | }; | 84 | }; |
| 85 | int addr_cnt; | 85 | int addr_cnt; |
| 86 | bool is_set; | ||
| 86 | Elf64_Addr addr[ADDR_CNT]; | 87 | Elf64_Addr addr[ADDR_CNT]; |
| 87 | }; | 88 | }; |
| 88 | 89 | ||
| @@ -451,8 +452,10 @@ static int symbols_collect(struct object *obj) · 362 unmodified lines | |||
| 451 | * in symbol's size, together with 'cnt' field hence | 452 | * in symbol's size, together with 'cnt' field hence |
| 452 | * that - 1. | 453 | * that - 1. |
| 453 | */ | 454 | */ |
| 454 | if (id) | 455 | if (id) { |
| 455 | id->cnt = sym.st_size / sizeof(int) - 1; | 456 | id->cnt = sym.st_size / sizeof(int) - 1; |
| 457 | id->is_set = true; | ||
| 458 | } | ||
| 456 | } else { | 459 | } else { |
| 457 | pr_err("FAILED unsupported prefix %s\n", prefix); | 460 | pr_err("FAILED unsupported prefix %s\n", prefix); |
| 458 | return -1; | 461 | return -1; |
| @@ -568,9 +571,8 @@ static int id_patch(struct object *obj, struct btf_id *id) · 109 unmodified lines | |||
| 568 | int *ptr = data->d_buf; | 571 | int *ptr = data->d_buf; |
| 569 | int i; | 572 | int i; |
| 570 | 573 | ||
| 571 | if (!id->id) { | 574 | if (!id->id && !id->is_set) |
| 572 | pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name); | 575 | pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name); |
| 573 | } | ||
| 574 | 576 | ||
| 575 | for (i = 0; i < id->addr_cnt; i++) { | 577 | for (i = 0; i < id->addr_cnt; i++) { |
| 576 | unsigned long addr = id->addr[i]; | 578 | unsigned long addr = id->addr[i]; |
| @@ -48,7 +48,6 @@ FEATURE_TESTS_BASIC := \ · 47 unmodified lines | |||
| 48 | numa_num_possible_cpus \ | 48 | numa_num_possible_cpus \ |
| 49 | libperl \ | 49 | libperl \ |
| 50 | libpython \ | 50 | libpython \ |
| 51 | libpython-version \ | ||
| 52 | libslang \ | 51 | libslang \ |
| 53 | libslang-include-subdir \ | 52 | libslang-include-subdir \ |
| 54 | libtraceevent \ | 53 | libtraceevent \ |
| @@ -32,7 +32,6 @@ FILES= \ · 31 unmodified lines | |||
| 32 | test-numa_num_possible_cpus.bin \ | 32 | test-numa_num_possible_cpus.bin \ |
| 33 | test-libperl.bin \ | 33 | test-libperl.bin \ |
| 34 | test-libpython.bin \ | 34 | test-libpython.bin \ |
| 35 | test-libpython-version.bin \ | ||
| 36 | test-libslang.bin \ | 35 | test-libslang.bin \ |
| 37 | test-libslang-include-subdir.bin \ | 36 | test-libslang-include-subdir.bin \ |
| 38 | test-libtraceevent.bin \ | 37 | test-libtraceevent.bin \ |
| @@ -227,9 +226,6 @@ $(OUTPUT)test-libperl.bin: · 188 unmodified lines | |||
| 227 | $(OUTPUT)test-libpython.bin: | 226 | $(OUTPUT)test-libpython.bin: |
| 228 | $(BUILD) $(FLAGS_PYTHON_EMBED) | 227 | $(BUILD) $(FLAGS_PYTHON_EMBED) |
| 229 | 228 | ||
| 230 | $(OUTPUT)test-libpython-version.bin: | ||
| 231 | $(BUILD) | ||
| 232 | |||
| 233 | $(OUTPUT)test-libbfd.bin: | 229 | $(OUTPUT)test-libbfd.bin: |
| 234 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl | 230 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl |
| 235 | 231 | ||
| @@ -14,10 +14,6 @@ · 13 unmodified lines | |||
| 14 | # include "test-libpython.c" | 14 | # include "test-libpython.c" |
| 15 | #undef main | 15 | #undef main |
| 16 | 16 | ||
| 17 | #define main main_test_libpython_version | ||
| 18 | # include "test-libpython-version.c" | ||
| 19 | #undef main | ||
| 20 | |||
| 21 | #define main main_test_libperl | 17 | #define main main_test_libperl |
| 22 | # include "test-libperl.c" | 18 | # include "test-libperl.c" |
| 23 | #undef main | 19 | #undef main |
| @@ -177,7 +173,6 @@ · 153 unmodified lines | |||
| 177 | int main(int argc, char *argv[]) | 173 | int main(int argc, char *argv[]) |
| 178 | { | 174 | { |
| 179 | main_test_libpython(); | 175 | main_test_libpython(); |
| 180 | main_test_libpython_version(); | ||
| 181 | main_test_libperl(); | 176 | main_test_libperl(); |
| 182 | main_test_hello(); | 177 | main_test_hello(); |
| 183 | main_test_libelf(); | 178 | main_test_libelf(); |
| @@ -1,11 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | #include <Python.h> | ||
| 3 | |||
| 4 | #if PY_VERSION_HEX >= 0x03000000 | ||
| 5 | #error | ||
| 6 | #endif | ||
| 7 | |||
| 8 | int main(void) | ||
| 9 | { | ||
| 10 | return 0; | ||
| 11 | } | ||
| @@ -1,14 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef _LIBLOCKDEP_DEBUG_LOCKS_H_ | ||
| 3 | #define _LIBLOCKDEP_DEBUG_LOCKS_H_ | ||
| 4 | |||
| 5 | #include <stddef.h> | ||
| 6 | #include <linux/compiler.h> | ||
| 7 | #include <asm/bug.h> | ||
| 8 | |||
| 9 | #define DEBUG_LOCKS_WARN_ON(x) WARN_ON(x) | ||
| 10 | |||
| 11 | extern bool debug_locks; | ||
| 12 | extern bool debug_locks_silent; | ||
| 13 | |||
| 14 | #endif | ||
| @@ -1,12 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef _LIBLOCKDEP_LINUX_HARDIRQ_H_ | ||
| 3 | #define _LIBLOCKDEP_LINUX_HARDIRQ_H_ | ||
| 4 | |||
| 5 | #define SOFTIRQ_BITS 0UL | ||
| 6 | #define HARDIRQ_BITS 0UL | ||
| 7 | #define SOFTIRQ_SHIFT 0UL | ||
| 8 | #define HARDIRQ_SHIFT 0UL | ||
| 9 | #define hardirq_count() 0UL | ||
| 10 | #define softirq_count() 0UL | ||
| 11 | |||
| 12 | #endif | ||
| @@ -1,39 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_ | ||
| 3 | #define _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_ | ||
| 4 | |||
| 5 | # define lockdep_hardirq_context() 0 | ||
| 6 | # define lockdep_softirq_context(p) 0 | ||
| 7 | # define lockdep_hardirqs_enabled() 0 | ||
| 8 | # define lockdep_softirqs_enabled(p) 0 | ||
| 9 | # define lockdep_hardirq_enter() do { } while (0) | ||
| 10 | # define lockdep_hardirq_exit() do { } while (0) | ||
| 11 | # define lockdep_softirq_enter() do { } while (0) | ||
| 12 | # define lockdep_softirq_exit() do { } while (0) | ||
| 13 | # define INIT_TRACE_IRQFLAGS | ||
| 14 | |||
| 15 | # define stop_critical_timings() do { } while (0) | ||
| 16 | # define start_critical_timings() do { } while (0) | ||
| 17 | |||
| 18 | #define raw_local_irq_disable() do { } while (0) | ||
| 19 | #define raw_local_irq_enable() do { } while (0) | ||
| 20 | #define raw_local_irq_save(flags) ((flags) = 0) | ||
| 21 | #define raw_local_irq_restore(flags) ((void)(flags)) | ||
| 22 | #define raw_local_save_flags(flags) ((flags) = 0) | ||
| 23 | #define raw_irqs_disabled_flags(flags) ((void)(flags)) | ||
| 24 | #define raw_irqs_disabled() 0 | ||
| 25 | #define raw_safe_halt() | ||
| 26 | |||
| 27 | #define local_irq_enable() do { } while (0) | ||
| 28 | #define local_irq_disable() do { } while (0) | ||
| 29 | #define local_irq_save(flags) ((flags) = 0) | ||
| 30 | #define local_irq_restore(flags) ((void)(flags)) | ||
| 31 | #define local_save_flags(flags) ((flags) = 0) | ||
| 32 | #define irqs_disabled() (1) | ||
| 33 | #define irqs_disabled_flags(flags) ((void)(flags), 0) | ||
| 34 | #define safe_halt() do { } while (0) | ||
| 35 | |||
| 36 | #define trace_lock_release(x, y) | ||
| 37 | #define trace_lock_acquire(a, b, c, d, e, f, g) | ||
| 38 | |||
| 39 | #endif | ||
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | #include <assert.h> | 7 | #include <assert.h> |
| 8 | #include <linux/build_bug.h> | 8 | #include <linux/build_bug.h> |
| 9 | #include <linux/compiler.h> | 9 | #include <linux/compiler.h> |
| 10 | #include <linux/math.h> | ||
| 10 | #include <endian.h> | 11 | #include <endian.h> |
| 11 | #include <byteswap.h> | 12 | #include <byteswap.h> |
| 12 | 13 | ||
| @@ -14,8 +15,6 @@ · 1 unmodified line | |||
| 14 | #define UINT_MAX (~0U) | 15 | #define UINT_MAX (~0U) |
| 15 | #endif | 16 | #endif |
| 16 | 17 | ||
| 17 | #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) | ||
| 18 | |||
| 19 | #define PERF_ALIGN(x, a) __PERF_ALIGN_MASK(x, (typeof(x))(a)-1) | 18 | #define PERF_ALIGN(x, a) __PERF_ALIGN_MASK(x, (typeof(x))(a)-1) |
| 20 | #define __PERF_ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) | 19 | #define __PERF_ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) |
| 21 | 20 | ||
| @@ -52,15 +51,6 @@ · 30 unmodified lines | |||
| 52 | _min1 < _min2 ? _min1 : _min2; }) | 51 | _min1 < _min2 ? _min1 : _min2; }) |
| 53 | #endif | 52 | #endif |
| 54 | 53 | ||
| 55 | #ifndef roundup | ||
| 56 | #define roundup(x, y) ( \ | ||
| 57 | { \ | ||
| 58 | const typeof(y) __y = y; \ | ||
| 59 | (((x) + (__y - 1)) / __y) * __y; \ | ||
| 60 | } \ | ||
| 61 | ) | ||
| 62 | #endif | ||
| 63 | |||
| 64 | #ifndef BUG_ON | 54 | #ifndef BUG_ON |
| 65 | #ifdef NDEBUG | 55 | #ifdef NDEBUG |
| 66 | #define BUG_ON(cond) do { if (cond) {} } while (0) | 56 | #define BUG_ON(cond) do { if (cond) {} } while (0) |
| @@ -104,16 +94,6 @@ int scnprintf_pad(char * buf, size_t size, const char * fmt, ...); · 37 unmodified lines | |||
| 104 | 94 | ||
| 105 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) | 95 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) |
| 106 | 96 | ||
| 107 | /* | ||
| 108 | * This looks more complex than it should be. But we need to | ||
| 109 | * get the type for the ~ right in round_down (it needs to be | ||
| 110 | * as wide as the result!), and we want to evaluate the macro | ||
| 111 | * arguments just once each. | ||
| 112 | */ | ||
| 113 | #define __round_mask(x, y) ((__typeof__(x))((y)-1)) | ||
| 114 | #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) | ||
| 115 | #define round_down(x, y) ((x) & ~__round_mask(x, y)) | ||
| 116 | |||
| 117 | #define current_gfp_context(k) 0 | 97 | #define current_gfp_context(k) 0 |
| 118 | #define synchronize_rcu() | 98 | #define synchronize_rcu() |
| 119 | 99 | ||
| @@ -1,72 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef _LIBLOCKDEP_LOCKDEP_H_ | ||
| 3 | #define _LIBLOCKDEP_LOCKDEP_H_ | ||
| 4 | |||
| 5 | #include <sys/prctl.h> | ||
| 6 | #include <sys/syscall.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include <limits.h> | ||
| 9 | #include <linux/utsname.h> | ||
| 10 | #include <linux/compiler.h> | ||
| 11 | #include <linux/export.h> | ||
| 12 | #include <linux/kern_levels.h> | ||
| 13 | #include <linux/err.h> | ||
| 14 | #include <linux/rcu.h> | ||
| 15 | #include <linux/list.h> | ||
| 16 | #include <linux/hardirq.h> | ||
| 17 | #include <unistd.h> | ||
| 18 | |||
| 19 | #define MAX_LOCK_DEPTH 63UL | ||
| 20 | |||
| 21 | #define asmlinkage | ||
| 22 | #define __visible | ||
| 23 | |||
| 24 | #include "../../../include/linux/lockdep.h" | ||
| 25 | |||
| 26 | struct task_struct { | ||
| 27 | u64 curr_chain_key; | ||
| 28 | int lockdep_depth; | ||
| 29 | unsigned int lockdep_recursion; | ||
| 30 | struct held_lock held_locks[MAX_LOCK_DEPTH]; | ||
| 31 | gfp_t lockdep_reclaim_gfp; | ||
| 32 | int pid; | ||
| 33 | int state; | ||
| 34 | char comm[17]; | ||
| 35 | }; | ||
| 36 | |||
| 37 | #define TASK_RUNNING 0 | ||
| 38 | |||
| 39 | extern struct task_struct *__curr(void); | ||
| 40 | |||
| 41 | #define current (__curr()) | ||
| 42 | |||
| 43 | static inline int debug_locks_off(void) | ||
| 44 | { | ||
| 45 | return 1; | ||
| 46 | } | ||
| 47 | |||
| 48 | #define task_pid_nr(tsk) ((tsk)->pid) | ||
| 49 | |||
| 50 | #define KSYM_NAME_LEN 128 | ||
| 51 | #define printk(...) dprintf(STDOUT_FILENO, __VA_ARGS__) | ||
| 52 | #define pr_err(format, ...) fprintf (stderr, format, ## __VA_ARGS__) | ||
| 53 | #define pr_warn pr_err | ||
| 54 | #define pr_cont pr_err | ||
| 55 | |||
| 56 | #define list_del_rcu list_del | ||
| 57 | |||
| 58 | #define atomic_t unsigned long | ||
| 59 | #define atomic_inc(x) ((*(x))++) | ||
| 60 | |||
| 61 | #define print_tainted() "" | ||
| 62 | #define static_obj(x) 1 | ||
| 63 | |||
| 64 | #define debug_show_all_locks() | ||
| 65 | extern void debug_check_no_locks_held(void); | ||
| 66 | |||
| 67 | static __used bool __is_kernel_percpu_address(unsigned long addr, void *can_addr) | ||
| 68 | { | ||
| 69 | return false; | ||
| 70 | } | ||
| 71 | |||
| 72 | #endif | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | #ifndef _TOOLS_MATH_H | ||
| 2 | #define _TOOLS_MATH_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * This looks more complex than it should be. But we need to | ||
| 6 | * get the type for the ~ right in round_down (it needs to be | ||
| 7 | * as wide as the result!), and we want to evaluate the macro | ||
| 8 | * arguments just once each. | ||
| 9 | */ | ||
| 10 | #define __round_mask(x, y) ((__typeof__(x))((y)-1)) | ||
| 11 | #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) | ||
| 12 | #define round_down(x, y) ((x) & ~__round_mask(x, y)) | ||
| 13 | |||
| 14 | #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) | ||
| 15 | |||
| 16 | #ifndef roundup | ||
| 17 | #define roundup(x, y) ( \ | ||
| 18 | { \ | ||
| 19 | const typeof(y) __y = y; \ | ||
| 20 | (((x) + (__y - 1)) / __y) * __y; \ | ||
| 21 | } \ | ||
| 22 | ) | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #endif | ||
| @@ -1,4 +0,0 @@ | |||
| 1 | #ifndef _TOOLS_INCLUDE_LINUX_PROC_FS_H | ||
| 2 | #define _TOOLS_INCLUDE_LINUX_PROC_FS_H | ||
| 3 | |||
| 4 | #endif /* _TOOLS_INCLUDE_LINUX_PROC_FS_H */ | ||
| @@ -37,6 +37,4 @@ static inline bool arch_spin_is_locked(arch_spinlock_t *mutex) · 36 unmodified lines | |||
| 37 | return true; | 37 | return true; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | #include <linux/lockdep.h> | ||
| 41 | |||
| 42 | #endif | 40 | #endif |
| @@ -1,33 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef _LIBLOCKDEP_LINUX_STACKTRACE_H_ | ||
| 3 | #define _LIBLOCKDEP_LINUX_STACKTRACE_H_ | ||
| 4 | |||
| 5 | #include <execinfo.h> | ||
| 6 | |||
| 7 | struct stack_trace { | ||
| 8 | unsigned int nr_entries, max_entries; | ||
| 9 | unsigned long *entries; | ||
| 10 | int skip; | ||
| 11 | }; | ||
| 12 | |||
| 13 | static inline void print_stack_trace(struct stack_trace *trace, int spaces) | ||
| 14 | { | ||
| 15 | backtrace_symbols_fd((void **)trace->entries, trace->nr_entries, 1); | ||
| 16 | } | ||
| 17 | |||
| 18 | #define save_stack_trace(trace) \ | ||
| 19 | ((trace)->nr_entries = \ | ||
| 20 | backtrace((void **)(trace)->entries, (trace)->max_entries)) | ||
| 21 | |||
| 22 | static inline int dump_stack(void) | ||
| 23 | { | ||
| 24 | void *array[64]; | ||
| 25 | size_t size; | ||
| 26 | |||
| 27 | size = backtrace(array, 64); | ||
| 28 | backtrace_symbols_fd(array, size, 1); | ||
| 29 | |||
| 30 | return 0; | ||
| 31 | } | ||
| 32 | |||
| 33 | #endif | ||
| @@ -375,6 +375,7 @@ static int read_symbols(struct elf *elf) · 374 unmodified lines | |||
| 375 | return -1; | 375 | return -1; |
| 376 | } | 376 | } |
| 377 | memset(sym, 0, sizeof(*sym)); | 377 | memset(sym, 0, sizeof(*sym)); |
| 378 | INIT_LIST_HEAD(&sym->pv_target); | ||
| 378 | sym->alias = sym; | 379 | sym->alias = sym; |
| 379 | 380 | ||
| 380 | sym->idx = i; | 381 | sym->idx = i; |
| @@ -153,6 +153,10 @@ void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func) · 152 unmodified lines | |||
| 153 | !strcmp(func->name, "_paravirt_ident_64")) | 153 | !strcmp(func->name, "_paravirt_ident_64")) |
| 154 | return; | 154 | return; |
| 155 | 155 | ||
| 156 | /* already added this function */ | ||
| 157 | if (!list_empty(&func->pv_target)) | ||
| 158 | return; | ||
| 159 | |||
| 156 | list_add(&func->pv_target, &f->pv_ops[idx].targets); | 160 | list_add(&func->pv_target, &f->pv_ops[idx].targets); |
| 157 | f->pv_ops[idx].clean = false; | 161 | f->pv_ops[idx].clean = false; |
| 158 | } | 162 | } |
| @@ -271,8 +271,6 @@ endif · 270 unmodified lines | |||
| 271 | 271 | ||
| 272 | FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS) | 272 | FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS) |
| 273 | FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) | 273 | FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) |
| 274 | FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS) | ||
| 275 | FEATURE_CHECK_LDFLAGS-libpython-version := $(PYTHON_EMBED_LDOPTS) | ||
| 276 | 274 | ||
| 277 | FEATURE_CHECK_LDFLAGS-libaio = -lrt | 275 | FEATURE_CHECK_LDFLAGS-libaio = -lrt |
| 278 | 276 | ||
| @@ -528,3 +528,4 @@ · 527 unmodified lines | |||
| 528 | 446 common landlock_restrict_self sys_landlock_restrict_self | 528 | 446 common landlock_restrict_self sys_landlock_restrict_self |
| 529 | # 447 reserved for memfd_secret | 529 | # 447 reserved for memfd_secret |
| 530 | 448 common process_mrelease sys_process_mrelease | 530 | 448 common process_mrelease sys_process_mrelease |
| 531 | 449 common futex_waitv sys_futex_waitv | ||
| @@ -451,3 +451,4 @@ · 450 unmodified lines | |||
| 451 | 446 common landlock_restrict_self sys_landlock_restrict_self sys_landlock_restrict_self | 451 | 446 common landlock_restrict_self sys_landlock_restrict_self sys_landlock_restrict_self |
| 452 | # 447 reserved for memfd_secret | 452 | # 447 reserved for memfd_secret |
| 453 | 448 common process_mrelease sys_process_mrelease sys_process_mrelease | 453 | 448 common process_mrelease sys_process_mrelease sys_process_mrelease |
| 454 | 449 common futex_waitv sys_futex_waitv sys_futex_waitv | ||
| @@ -223,8 +223,6 @@ static unsigned int group(pthread_t *pth, · 222 unmodified lines | |||
| 223 | snd_ctx->out_fds[i] = fds[1]; | 223 | snd_ctx->out_fds[i] = fds[1]; |
| 224 | if (!thread_mode) | 224 | if (!thread_mode) |
| 225 | close(fds[0]); | 225 | close(fds[0]); |
| 226 | |||
| 227 | free(ctx); | ||
| 228 | } | 226 | } |
| 229 | 227 | ||
| 230 | /* Now we have all the fds, fork the senders */ | 228 | /* Now we have all the fds, fork the senders */ |
| @@ -241,8 +239,6 @@ static unsigned int group(pthread_t *pth, · 10 unmodified lines | |||
| 241 | for (i = 0; i < num_fds; i++) | 239 | for (i = 0; i < num_fds; i++) |
| 242 | close(snd_ctx->out_fds[i]); | 240 | close(snd_ctx->out_fds[i]); |
| 243 | 241 | ||
| 244 | free(snd_ctx); | ||
| 245 | |||
| 246 | /* Return number of children to reap */ | 242 | /* Return number of children to reap */ |
| 247 | return num_fds * 2; | 243 | return num_fds * 2; |
| 248 | } | 244 | } |
| @@ -820,7 +820,7 @@ static int __cmd_inject(struct perf_inject *inject) · 819 unmodified lines | |||
| 820 | inject->tool.ordered_events = true; | 820 | inject->tool.ordered_events = true; |
| 821 | inject->tool.ordering_requires_timestamps = true; | 821 | inject->tool.ordering_requires_timestamps = true; |
| 822 | /* Allow space in the header for new attributes */ | 822 | /* Allow space in the header for new attributes */ |
| 823 | output_data_offset = 4096; | 823 | output_data_offset = roundup(8192 + session->header.data_offset, 4096); |
| 824 | if (inject->strip) | 824 | if (inject->strip) |
| 825 | strip_init(inject); | 825 | strip_init(inject); |
| 826 | } | 826 | } |
| @@ -169,7 +169,9 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u · 168 unmodified lines | |||
| 169 | TEST_ASSERT_VAL("#num_dies", expr__parse(&num_dies, ctx, "#num_dies") == 0); | 169 | TEST_ASSERT_VAL("#num_dies", expr__parse(&num_dies, ctx, "#num_dies") == 0); |
| 170 | TEST_ASSERT_VAL("#num_cores >= #num_dies", num_cores >= num_dies); | 170 | TEST_ASSERT_VAL("#num_cores >= #num_dies", num_cores >= num_dies); |
| 171 | TEST_ASSERT_VAL("#num_packages", expr__parse(&num_packages, ctx, "#num_packages") == 0); | 171 | TEST_ASSERT_VAL("#num_packages", expr__parse(&num_packages, ctx, "#num_packages") == 0); |
| 172 | TEST_ASSERT_VAL("#num_dies >= #num_packages", num_dies >= num_packages); | 172 | |
| 173 | if (num_dies) // Some platforms do not have CPU die support, for example s390 | ||
| 174 | TEST_ASSERT_VAL("#num_dies >= #num_packages", num_dies >= num_packages); | ||
| 173 | 175 | ||
| 174 | /* | 176 | /* |
| 175 | * Source count returns the number of events aggregating in a leader | 177 | * Source count returns the number of events aggregating in a leader |
| @@ -109,6 +109,7 @@ static void load_runtime_stat(struct runtime_stat *st, struct evlist *evlist, · 108 unmodified lines | |||
| 109 | struct evsel *evsel; | 109 | struct evsel *evsel; |
| 110 | u64 count; | 110 | u64 count; |
| 111 | 111 | ||
| 112 | perf_stat__reset_shadow_stats(); | ||
| 112 | evlist__for_each_entry(evlist, evsel) { | 113 | evlist__for_each_entry(evlist, evsel) { |
| 113 | count = find_value(evsel->name, vals); | 114 | count = find_value(evsel->name, vals); |
| 114 | perf_stat__update_shadow_stats(evsel, count, 0, st); | 115 | perf_stat__update_shadow_stats(evsel, count, 0, st); |
| @@ -1,14 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | // Copyright (c) 2021 Facebook | ||
| 3 | |||
| 4 | #ifndef __BPERF_STAT_H | ||
| 5 | #define __BPERF_STAT_H | ||
| 6 | |||
| 7 | typedef struct { | ||
| 8 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | ||
| 9 | __uint(key_size, sizeof(__u32)); | ||
| 10 | __uint(value_size, sizeof(struct bpf_perf_event_value)); | ||
| 11 | __uint(max_entries, 1); | ||
| 12 | } reading_map; | ||
| 13 | |||
| 14 | #endif /* __BPERF_STAT_H */ | ||
| @@ -1,14 +1,23 @@ | |||
| 1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | // Copyright (c) 2021 Facebook | 2 | // Copyright (c) 2021 Facebook |
| 3 | #include <linux/bpf.h> | 3 | #include "vmlinux.h" |
| 4 | #include <linux/perf_event.h> | ||
| 5 | #include <bpf/bpf_helpers.h> | 4 | #include <bpf/bpf_helpers.h> |
| 6 | #include <bpf/bpf_tracing.h> | 5 | #include <bpf/bpf_tracing.h> |
| 7 | #include "bperf.h" | ||
| 8 | #include "bperf_u.h" | 6 | #include "bperf_u.h" |
| 9 | 7 | ||
| 10 | reading_map diff_readings SEC(".maps"); | 8 | struct { |
| 11 | reading_map accum_readings SEC(".maps"); | 9 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); |
| 10 | __uint(key_size, sizeof(__u32)); | ||
| 11 | __uint(value_size, sizeof(struct bpf_perf_event_value)); | ||
| 12 | __uint(max_entries, 1); | ||
| 13 | } diff_readings SEC(".maps"); | ||
| 14 | |||
| 15 | struct { | ||
| 16 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | ||
| 17 | __uint(key_size, sizeof(__u32)); | ||
| 18 | __uint(value_size, sizeof(struct bpf_perf_event_value)); | ||
| 19 | __uint(max_entries, 1); | ||
| 20 | } accum_readings SEC(".maps"); | ||
| 12 | 21 | ||
| 13 | struct { | 22 | struct { |
| 14 | __uint(type, BPF_MAP_TYPE_HASH); | 23 | __uint(type, BPF_MAP_TYPE_HASH); |
| @@ -1,10 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | // Copyright (c) 2021 Facebook | 2 | // Copyright (c) 2021 Facebook |
| 3 | #include <linux/bpf.h> | 3 | #include "vmlinux.h" |
| 4 | #include <linux/perf_event.h> | ||
| 5 | #include <bpf/bpf_helpers.h> | 4 | #include <bpf/bpf_helpers.h> |
| 6 | #include <bpf/bpf_tracing.h> | 5 | #include <bpf/bpf_tracing.h> |
| 7 | #include "bperf.h" | ||
| 8 | 6 | ||
| 9 | struct { | 7 | struct { |
| 10 | __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); | 8 | __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); |
| @@ -13,8 +11,19 @@ struct { · 2 unmodified lines | |||
| 13 | __uint(map_flags, BPF_F_PRESERVE_ELEMS); | 11 | __uint(map_flags, BPF_F_PRESERVE_ELEMS); |
| 14 | } events SEC(".maps"); | 12 | } events SEC(".maps"); |
| 15 | 13 | ||
| 16 | reading_map prev_readings SEC(".maps"); | 14 | struct { |
| 17 | reading_map diff_readings SEC(".maps"); | 15 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); |
| 16 | __uint(key_size, sizeof(__u32)); | ||
| 17 | __uint(value_size, sizeof(struct bpf_perf_event_value)); | ||
| 18 | __uint(max_entries, 1); | ||
| 19 | } prev_readings SEC(".maps"); | ||
| 20 | |||
| 21 | struct { | ||
| 22 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | ||
| 23 | __uint(key_size, sizeof(__u32)); | ||
| 24 | __uint(value_size, sizeof(struct bpf_perf_event_value)); | ||
| 25 | __uint(max_entries, 1); | ||
| 26 | } diff_readings SEC(".maps"); | ||
| 18 | 27 | ||
| 19 | SEC("raw_tp/sched_switch") | 28 | SEC("raw_tp/sched_switch") |
| 20 | int BPF_PROG(on_switch) | 29 | int BPF_PROG(on_switch) |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | // Copyright (c) 2020 Facebook | 2 | // Copyright (c) 2020 Facebook |
| 3 | #include <linux/bpf.h> | 3 | #include "vmlinux.h" |
| 4 | #include <bpf/bpf_helpers.h> | 4 | #include <bpf/bpf_helpers.h> |
| 5 | #include <bpf/bpf_tracing.h> | 5 | #include <bpf/bpf_tracing.h> |
| 6 | 6 | ||
| @@ -44,13 +44,16 @@ struct perf_event_attr; · 43 unmodified lines | |||
| 44 | /* perf sample has 16 bits size limit */ | 44 | /* perf sample has 16 bits size limit */ |
| 45 | #define PERF_SAMPLE_MAX_SIZE (1 << 16) | 45 | #define PERF_SAMPLE_MAX_SIZE (1 << 16) |
| 46 | 46 | ||
| 47 | /* number of register is bound by the number of bits in regs_dump::mask (64) */ | ||
| 48 | #define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64)) | ||
| 49 | |||
| 47 | struct regs_dump { | 50 | struct regs_dump { |
| 48 | u64 abi; | 51 | u64 abi; |
| 49 | u64 mask; | 52 | u64 mask; |
| 50 | u64 *regs; | 53 | u64 *regs; |
| 51 | 54 | ||
| 52 | /* Cached values/mask filled by first register access. */ | 55 | /* Cached values/mask filled by first register access. */ |
| 53 | u64 cache_regs[PERF_REGS_MAX]; | 56 | u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE]; |
| 54 | u64 cache_mask; | 57 | u64 cache_mask; |
| 55 | }; | 58 | }; |
| 56 | 59 | ||
| @@ -2321,6 +2321,7 @@ out: · 2320 unmodified lines | |||
| 2321 | #define FEAT_PROCESS_STR_FUN(__feat, __feat_env) \ | 2321 | #define FEAT_PROCESS_STR_FUN(__feat, __feat_env) \ |
| 2322 | static int process_##__feat(struct feat_fd *ff, void *data __maybe_unused) \ | 2322 | static int process_##__feat(struct feat_fd *ff, void *data __maybe_unused) \ |
| 2323 | {\ | 2323 | {\ |
| 2324 | free(ff->ph->env.__feat_env); \ | ||
| 2324 | ff->ph->env.__feat_env = do_read_string(ff); \ | 2325 | ff->ph->env.__feat_env = do_read_string(ff); \ |
| 2325 | return ff->ph->env.__feat_env ? 0 : -ENOMEM; \ | 2326 | return ff->ph->env.__feat_env ? 0 : -ENOMEM; \ |
| 2326 | } | 2327 | } |
| @@ -4124,6 +4125,7 @@ int perf_event__process_feature(struct perf_session *session, · 1797 unmodified lines | |||
| 4124 | struct perf_record_header_feature *fe = (struct perf_record_header_feature *)event; | 4125 | struct perf_record_header_feature *fe = (struct perf_record_header_feature *)event; |
| 4125 | int type = fe->header.type; | 4126 | int type = fe->header.type; |
| 4126 | u64 feat = fe->feat_id; | 4127 | u64 feat = fe->feat_id; |
| 4128 | int ret = 0; | ||
| 4127 | 4129 | ||
| 4128 | if (type < 0 || type >= PERF_RECORD_HEADER_MAX) { | 4130 | if (type < 0 || type >= PERF_RECORD_HEADER_MAX) { |
| 4129 | pr_warning("invalid record type %d in pipe-mode\n", type); | 4131 | pr_warning("invalid record type %d in pipe-mode\n", type); |
| @@ -4141,11 +4143,13 @@ int perf_event__process_feature(struct perf_session *session, · 11 unmodified lines | |||
| 4141 | ff.size = event->header.size - sizeof(*fe); | 4143 | ff.size = event->header.size - sizeof(*fe); |
| 4142 | ff.ph = &session->header; | 4144 | ff.ph = &session->header; |
| 4143 | 4145 | ||
| 4144 | if (feat_ops[feat].process(&ff, NULL)) | 4146 | if (feat_ops[feat].process(&ff, NULL)) { |
| 4145 | return -1; | 4147 | ret = -1; |
| 4148 | goto out; | ||
| 4149 | } | ||
| 4146 | 4150 | ||
| 4147 | if (!feat_ops[feat].print || !tool->show_feat_hdr) | 4151 | if (!feat_ops[feat].print || !tool->show_feat_hdr) |
| 4148 | return 0; | 4152 | goto out; |
| 4149 | 4153 | ||
| 4150 | if (!feat_ops[feat].full_only || | 4154 | if (!feat_ops[feat].full_only || |
| 4151 | tool->show_feat_hdr >= SHOW_FEAT_HEADER_FULL_INFO) { | 4155 | tool->show_feat_hdr >= SHOW_FEAT_HEADER_FULL_INFO) { |
| @@ -4154,8 +4158,9 @@ int perf_event__process_feature(struct perf_session *session, · 2 unmodified lines | |||
| 4154 | fprintf(stdout, "# %s info available, use -I to display\n", | 4158 | fprintf(stdout, "# %s info available, use -I to display\n", |
| 4155 | feat_ops[feat].name); | 4159 | feat_ops[feat].name); |
| 4156 | } | 4160 | } |
| 4157 | 4161 | out: | |
| 4158 | return 0; | 4162 | free_event_desc(ff.events); |
| 4163 | return ret; | ||
| 4159 | } | 4164 | } |
| 4160 | 4165 | ||
| 4161 | size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) | 4166 | size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) |
| @@ -1205,61 +1205,69 @@ out_no_progress: · 1204 unmodified lines | |||
| 1205 | 1205 | ||
| 1206 | static bool intel_pt_fup_event(struct intel_pt_decoder *decoder) | 1206 | static bool intel_pt_fup_event(struct intel_pt_decoder *decoder) |
| 1207 | { | 1207 | { |
| 1208 | enum intel_pt_sample_type type = decoder->state.type; | ||
| 1208 | bool ret = false; | 1209 | bool ret = false; |
| 1209 | 1210 | ||
| 1211 | decoder->state.type &= ~INTEL_PT_BRANCH; | ||
| 1212 | |||
| 1210 | if (decoder->set_fup_tx_flags) { | 1213 | if (decoder->set_fup_tx_flags) { |
| 1211 | decoder->set_fup_tx_flags = false; | 1214 | decoder->set_fup_tx_flags = false; |
| 1212 | decoder->tx_flags = decoder->fup_tx_flags; | 1215 | decoder->tx_flags = decoder->fup_tx_flags; |
| 1213 | decoder->state.type = INTEL_PT_TRANSACTION; | 1216 | decoder->state.type |= INTEL_PT_TRANSACTION; |
| 1214 | if (decoder->fup_tx_flags & INTEL_PT_ABORT_TX) | 1217 | if (decoder->fup_tx_flags & INTEL_PT_ABORT_TX) |
| 1215 | decoder->state.type |= INTEL_PT_BRANCH; | 1218 | decoder->state.type |= INTEL_PT_BRANCH; |
| 1216 | decoder->state.from_ip = decoder->ip; | ||
| 1217 | decoder->state.to_ip = 0; | ||
| 1218 | decoder->state.flags = decoder->fup_tx_flags; | 1219 | decoder->state.flags = decoder->fup_tx_flags; |
| 1219 | return true; | 1220 | ret = true; |
| 1220 | } | 1221 | } |
| 1221 | if (decoder->set_fup_ptw) { | 1222 | if (decoder->set_fup_ptw) { |
| 1222 | decoder->set_fup_ptw = false; | 1223 | decoder->set_fup_ptw = false; |
| 1223 | decoder->state.type = INTEL_PT_PTW; | 1224 | decoder->state.type |= INTEL_PT_PTW; |
| 1224 | decoder->state.flags |= INTEL_PT_FUP_IP; | 1225 | decoder->state.flags |= INTEL_PT_FUP_IP; |
| 1225 | decoder->state.from_ip = decoder->ip; | ||
| 1226 | decoder->state.to_ip = 0; | ||
| 1227 | decoder->state.ptw_payload = decoder->fup_ptw_payload; | 1226 | decoder->state.ptw_payload = decoder->fup_ptw_payload; |
| 1228 | return true; | 1227 | ret = true; |
| 1229 | } | 1228 | } |
| 1230 | if (decoder->set_fup_mwait) { | 1229 | if (decoder->set_fup_mwait) { |
| 1231 | decoder->set_fup_mwait = false; | 1230 | decoder->set_fup_mwait = false; |
| 1232 | decoder->state.type = INTEL_PT_MWAIT_OP; | 1231 | decoder->state.type |= INTEL_PT_MWAIT_OP; |
| 1233 | decoder->state.from_ip = decoder->ip; | ||
| 1234 | decoder->state.to_ip = 0; | ||
| 1235 | decoder->state.mwait_payload = decoder->fup_mwait_payload; | 1232 | decoder->state.mwait_payload = decoder->fup_mwait_payload; |
| 1236 | ret = true; | 1233 | ret = true; |
| 1237 | } | 1234 | } |
| 1238 | if (decoder->set_fup_pwre) { | 1235 | if (decoder->set_fup_pwre) { |
| 1239 | decoder->set_fup_pwre = false; | 1236 | decoder->set_fup_pwre = false; |
| 1240 | decoder->state.type |= INTEL_PT_PWR_ENTRY; | 1237 | decoder->state.type |= INTEL_PT_PWR_ENTRY; |
| 1241 | decoder->state.type &= ~INTEL_PT_BRANCH; | ||
| 1242 | decoder->state.from_ip = decoder->ip; | ||
| 1243 | decoder->state.to_ip = 0; | ||
| 1244 | decoder->state.pwre_payload = decoder->fup_pwre_payload; | 1238 | decoder->state.pwre_payload = decoder->fup_pwre_payload; |
| 1245 | ret = true; | 1239 | ret = true; |
| 1246 | } | 1240 | } |
| 1247 | if (decoder->set_fup_exstop) { | 1241 | if (decoder->set_fup_exstop) { |
| 1248 | decoder->set_fup_exstop = false; | 1242 | decoder->set_fup_exstop = false; |
| 1249 | decoder->state.type |= INTEL_PT_EX_STOP; | 1243 | decoder->state.type |= INTEL_PT_EX_STOP; |
| 1250 | decoder->state.type &= ~INTEL_PT_BRANCH; | ||
| 1251 | decoder->state.flags |= INTEL_PT_FUP_IP; | 1244 | decoder->state.flags |= INTEL_PT_FUP_IP; |
| 1252 | decoder->state.from_ip = decoder->ip; | ||
| 1253 | decoder->state.to_ip = 0; | ||
| 1254 | ret = true; | 1245 | ret = true; |
| 1255 | } | 1246 | } |
| 1256 | if (decoder->set_fup_bep) { | 1247 | if (decoder->set_fup_bep) { |
| 1257 | decoder->set_fup_bep = false; | 1248 | decoder->set_fup_bep = false; |
| 1258 | decoder->state.type |= INTEL_PT_BLK_ITEMS; | 1249 | decoder->state.type |= INTEL_PT_BLK_ITEMS; |
| 1259 | decoder->state.type &= ~INTEL_PT_BRANCH; | 1250 | ret = true; |
| 1251 | } | ||
| 1252 | if (decoder->overflow) { | ||
| 1253 | decoder->overflow = false; | ||
| 1254 | if (!ret && !decoder->pge) { | ||
| 1255 | if (decoder->hop) { | ||
| 1256 | decoder->state.type = 0; | ||
| 1257 | decoder->pkt_state = INTEL_PT_STATE_RESAMPLE; | ||
| 1258 | } | ||
| 1259 | decoder->pge = true; | ||
| 1260 | decoder->state.type |= INTEL_PT_BRANCH | INTEL_PT_TRACE_BEGIN; | ||
| 1261 | decoder->state.from_ip = 0; | ||
| 1262 | decoder->state.to_ip = decoder->ip; | ||
| 1263 | return true; | ||
| 1264 | } | ||
| 1265 | } | ||
| 1266 | if (ret) { | ||
| 1260 | decoder->state.from_ip = decoder->ip; | 1267 | decoder->state.from_ip = decoder->ip; |
| 1261 | decoder->state.to_ip = 0; | 1268 | decoder->state.to_ip = 0; |
| 1262 | ret = true; | 1269 | } else { |
| 1270 | decoder->state.type = type; | ||
| 1263 | } | 1271 | } |
| 1264 | return ret; | 1272 | return ret; |
| 1265 | } | 1273 | } |
| @@ -1608,7 +1616,16 @@ static int intel_pt_overflow(struct intel_pt_decoder *decoder) · 342 unmodified lines | |||
| 1608 | intel_pt_clear_tx_flags(decoder); | 1616 | intel_pt_clear_tx_flags(decoder); |
| 1609 | intel_pt_set_nr(decoder); | 1617 | intel_pt_set_nr(decoder); |
| 1610 | decoder->timestamp_insn_cnt = 0; | 1618 | decoder->timestamp_insn_cnt = 0; |
| 1611 | decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC; | 1619 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; |
| 1620 | decoder->state.from_ip = decoder->ip; | ||
| 1621 | decoder->ip = 0; | ||
| 1622 | decoder->pge = false; | ||
| 1623 | decoder->set_fup_tx_flags = false; | ||
| 1624 | decoder->set_fup_ptw = false; | ||
| 1625 | decoder->set_fup_mwait = false; | ||
| 1626 | decoder->set_fup_pwre = false; | ||
| 1627 | decoder->set_fup_exstop = false; | ||
| 1628 | decoder->set_fup_bep = false; | ||
| 1612 | decoder->overflow = true; | 1629 | decoder->overflow = true; |
| 1613 | return -EOVERFLOW; | 1630 | return -EOVERFLOW; |
| 1614 | } | 1631 | } |
| @@ -2666,6 +2683,8 @@ static int intel_pt_scan_for_psb(struct intel_pt_decoder *decoder); · 1051 unmodified lines | |||
| 2666 | /* Hop mode: Ignore TNT, do not walk code, but get ip from FUPs and TIPs */ | 2683 | /* Hop mode: Ignore TNT, do not walk code, but get ip from FUPs and TIPs */ |
| 2667 | static int intel_pt_hop_trace(struct intel_pt_decoder *decoder, bool *no_tip, int *err) | 2684 | static int intel_pt_hop_trace(struct intel_pt_decoder *decoder, bool *no_tip, int *err) |
| 2668 | { | 2685 | { |
| 2686 | *err = 0; | ||
| 2687 | |||
| 2669 | /* Leap from PSB to PSB, getting ip from FUP within PSB+ */ | 2688 | /* Leap from PSB to PSB, getting ip from FUP within PSB+ */ |
| 2670 | if (decoder->leap && !decoder->in_psb && decoder->packet.type != INTEL_PT_PSB) { | 2689 | if (decoder->leap && !decoder->in_psb && decoder->packet.type != INTEL_PT_PSB) { |
| 2671 | *err = intel_pt_scan_for_psb(decoder); | 2690 | *err = intel_pt_scan_for_psb(decoder); |
| @@ -2678,6 +2697,7 @@ static int intel_pt_hop_trace(struct intel_pt_decoder *decoder, bool *no_tip, in · 6 unmodified lines | |||
| 2678 | return HOP_IGNORE; | 2697 | return HOP_IGNORE; |
| 2679 | 2698 | ||
| 2680 | case INTEL_PT_TIP_PGD: | 2699 | case INTEL_PT_TIP_PGD: |
| 2700 | decoder->pge = false; | ||
| 2681 | if (!decoder->packet.count) { | 2701 | if (!decoder->packet.count) { |
| 2682 | intel_pt_set_nr(decoder); | 2702 | intel_pt_set_nr(decoder); |
| 2683 | return HOP_IGNORE; | 2703 | return HOP_IGNORE; |
| @@ -2705,18 +2725,21 @@ static int intel_pt_hop_trace(struct intel_pt_decoder *decoder, bool *no_tip, in · 21 unmodified lines | |||
| 2705 | if (!decoder->packet.count) | 2725 | if (!decoder->packet.count) |
| 2706 | return HOP_IGNORE; | 2726 | return HOP_IGNORE; |
| 2707 | intel_pt_set_ip(decoder); | 2727 | intel_pt_set_ip(decoder); |
| 2708 | if (intel_pt_fup_event(decoder)) | 2728 | if (decoder->set_fup_mwait || decoder->set_fup_pwre) |
| 2709 | return HOP_RETURN; | 2729 | *no_tip = true; |
| 2710 | if (!decoder->branch_enable) | 2730 | if (!decoder->branch_enable || !decoder->pge) |
| 2711 | *no_tip = true; | 2731 | *no_tip = true; |
| 2712 | if (*no_tip) { | 2732 | if (*no_tip) { |
| 2713 | decoder->state.type = INTEL_PT_INSTRUCTION; | 2733 | decoder->state.type = INTEL_PT_INSTRUCTION; |
| 2714 | decoder->state.from_ip = decoder->ip; | 2734 | decoder->state.from_ip = decoder->ip; |
| 2715 | decoder->state.to_ip = 0; | 2735 | decoder->state.to_ip = 0; |
| 2736 | intel_pt_fup_event(decoder); | ||
| 2716 | return HOP_RETURN; | 2737 | return HOP_RETURN; |
| 2717 | } | 2738 | } |
| 2739 | intel_pt_fup_event(decoder); | ||
| 2740 | decoder->state.type |= INTEL_PT_INSTRUCTION | INTEL_PT_BRANCH; | ||
| 2718 | *err = intel_pt_walk_fup_tip(decoder); | 2741 | *err = intel_pt_walk_fup_tip(decoder); |
| 2719 | if (!*err) | 2742 | if (!*err && decoder->state.to_ip) |
| 2720 | decoder->pkt_state = INTEL_PT_STATE_RESAMPLE; | 2743 | decoder->pkt_state = INTEL_PT_STATE_RESAMPLE; |
| 2721 | return HOP_RETURN; | 2744 | return HOP_RETURN; |
| 2722 | 2745 | ||
| @@ -2897,7 +2920,7 @@ static bool intel_pt_psb_with_fup(struct intel_pt_decoder *decoder, int *err) · 174 unmodified lines | |||
| 2897 | { | 2920 | { |
| 2898 | struct intel_pt_psb_info data = { .fup = false }; | 2921 | struct intel_pt_psb_info data = { .fup = false }; |
| 2899 | 2922 | ||
| 2900 | if (!decoder->branch_enable || !decoder->pge) | 2923 | if (!decoder->branch_enable) |
| 2901 | return false; | 2924 | return false; |
| 2902 | 2925 | ||
| 2903 | intel_pt_pkt_lookahead(decoder, intel_pt_psb_lookahead_cb, &data); | 2926 | intel_pt_pkt_lookahead(decoder, intel_pt_psb_lookahead_cb, &data); |
| @@ -2924,6 +2947,7 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder) · 20 unmodified lines | |||
| 2924 | if (err) | 2947 | if (err) |
| 2925 | return err; | 2948 | return err; |
| 2926 | next: | 2949 | next: |
| 2950 | err = 0; | ||
| 2927 | if (decoder->cyc_threshold) { | 2951 | if (decoder->cyc_threshold) { |
| 2928 | if (decoder->sample_cyc && last_packet_type != INTEL_PT_CYC) | 2952 | if (decoder->sample_cyc && last_packet_type != INTEL_PT_CYC) |
| 2929 | decoder->sample_cyc = false; | 2953 | decoder->sample_cyc = false; |
| @@ -2962,6 +2986,7 @@ next: · 32 unmodified lines | |||
| 2962 | 2986 | ||
| 2963 | case INTEL_PT_TIP_PGE: { | 2987 | case INTEL_PT_TIP_PGE: { |
| 2964 | decoder->pge = true; | 2988 | decoder->pge = true; |
| 2989 | decoder->overflow = false; | ||
| 2965 | intel_pt_mtc_cyc_cnt_pge(decoder); | 2990 | intel_pt_mtc_cyc_cnt_pge(decoder); |
| 2966 | intel_pt_set_nr(decoder); | 2991 | intel_pt_set_nr(decoder); |
| 2967 | if (decoder->packet.count == 0) { | 2992 | if (decoder->packet.count == 0) { |
| @@ -2999,7 +3024,7 @@ next: · 31 unmodified lines | |||
| 2999 | break; | 3024 | break; |
| 3000 | } | 3025 | } |
| 3001 | intel_pt_set_last_ip(decoder); | 3026 | intel_pt_set_last_ip(decoder); |
| 3002 | if (!decoder->branch_enable) { | 3027 | if (!decoder->branch_enable || !decoder->pge) { |
| 3003 | decoder->ip = decoder->last_ip; | 3028 | decoder->ip = decoder->last_ip; |
| 3004 | if (intel_pt_fup_event(decoder)) | 3029 | if (intel_pt_fup_event(decoder)) |
| 3005 | return 0; | 3030 | return 0; |
| @@ -3467,10 +3492,10 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder) · 461 unmodified lines | |||
| 3467 | decoder->set_fup_pwre = false; | 3492 | decoder->set_fup_pwre = false; |
| 3468 | decoder->set_fup_exstop = false; | 3493 | decoder->set_fup_exstop = false; |
| 3469 | decoder->set_fup_bep = false; | 3494 | decoder->set_fup_bep = false; |
| 3495 | decoder->overflow = false; | ||
| 3470 | 3496 | ||
| 3471 | if (!decoder->branch_enable) { | 3497 | if (!decoder->branch_enable) { |
| 3472 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; | 3498 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; |
| 3473 | decoder->overflow = false; | ||
| 3474 | decoder->state.type = 0; /* Do not have a sample */ | 3499 | decoder->state.type = 0; /* Do not have a sample */ |
| 3475 | return 0; | 3500 | return 0; |
| 3476 | } | 3501 | } |
| @@ -3485,7 +3510,6 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder) · 8 unmodified lines | |||
| 3485 | decoder->pkt_state = INTEL_PT_STATE_RESAMPLE; | 3510 | decoder->pkt_state = INTEL_PT_STATE_RESAMPLE; |
| 3486 | else | 3511 | else |
| 3487 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; | 3512 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; |
| 3488 | decoder->overflow = false; | ||
| 3489 | 3513 | ||
| 3490 | decoder->state.from_ip = 0; | 3514 | decoder->state.from_ip = 0; |
| 3491 | decoder->state.to_ip = decoder->ip; | 3515 | decoder->state.to_ip = decoder->ip; |
| @@ -3607,7 +3631,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder) · 115 unmodified lines | |||
| 3607 | } | 3631 | } |
| 3608 | 3632 | ||
| 3609 | decoder->have_last_ip = true; | 3633 | decoder->have_last_ip = true; |
| 3610 | decoder->pkt_state = INTEL_PT_STATE_NO_IP; | 3634 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; |
| 3611 | 3635 | ||
| 3612 | err = intel_pt_walk_psb(decoder); | 3636 | err = intel_pt_walk_psb(decoder); |
| 3613 | if (err) | 3637 | if (err) |
| @@ -3704,7 +3728,8 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder) · 90 unmodified lines | |||
| 3704 | 3728 | ||
| 3705 | if (err) { | 3729 | if (err) { |
| 3706 | decoder->state.err = intel_pt_ext_err(err); | 3730 | decoder->state.err = intel_pt_ext_err(err); |
| 3707 | decoder->state.from_ip = decoder->ip; | 3731 | if (err != -EOVERFLOW) |
| 3732 | decoder->state.from_ip = decoder->ip; | ||
| 3708 | intel_pt_update_sample_time(decoder); | 3733 | intel_pt_update_sample_time(decoder); |
| 3709 | decoder->sample_tot_cyc_cnt = decoder->tot_cyc_cnt; | 3734 | decoder->sample_tot_cyc_cnt = decoder->tot_cyc_cnt; |
| 3710 | intel_pt_set_nr(decoder); | 3735 | intel_pt_set_nr(decoder); |
| @@ -2565,6 +2565,7 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp) · 2564 unmodified lines | |||
| 2565 | ptq->sync_switch = false; | 2565 | ptq->sync_switch = false; |
| 2566 | intel_pt_next_tid(pt, ptq); | 2566 | intel_pt_next_tid(pt, ptq); |
| 2567 | } | 2567 | } |
| 2568 | ptq->timestamp = state->est_timestamp; | ||
| 2568 | if (pt->synth_opts.errors) { | 2569 | if (pt->synth_opts.errors) { |
| 2569 | err = intel_ptq_synth_error(ptq, state); | 2570 | err = intel_ptq_synth_error(ptq, state); |
| 2570 | if (err) | 2571 | if (err) |
| @@ -25,6 +25,9 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) · 24 unmodified lines | |||
| 25 | int i, idx = 0; | 25 | int i, idx = 0; |
| 26 | u64 mask = regs->mask; | 26 | u64 mask = regs->mask; |
| 27 | 27 | ||
| 28 | if ((u64)id >= PERF_SAMPLE_REGS_CACHE_SIZE) | ||
| 29 | return -EINVAL; | ||
| 30 | |||
| 28 | if (regs->cache_mask & (1ULL << id)) | 31 | if (regs->cache_mask & (1ULL << id)) |
| 29 | goto out; | 32 | goto out; |
| 30 | 33 | ||
| @@ -461,7 +461,7 @@ get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name) · 460 unmodified lines | |||
| 461 | struct tep_event *tp_format; | 461 | struct tep_event *tp_format; |
| 462 | 462 | ||
| 463 | tp_format = trace_event__tp_format_id(evsel->core.attr.config); | 463 | tp_format = trace_event__tp_format_id(evsel->core.attr.config); |
| 464 | if (!tp_format) | 464 | if (IS_ERR_OR_NULL(tp_format)) |
| 465 | return NULL; | 465 | return NULL; |
| 466 | 466 | ||
| 467 | evsel->tp_format = tp_format; | 467 | evsel->tp_format = tp_format; |
| @@ -15,7 +15,7 @@ int smt_on(void) · 14 unmodified lines | |||
| 15 | if (cached) | 15 | if (cached) |
| 16 | return cached_result; | 16 | return cached_result; |
| 17 | 17 | ||
| 18 | if (sysfs__read_int("devices/system/cpu/smt/active", &cached_result) > 0) | 18 | if (sysfs__read_int("devices/system/cpu/smt/active", &cached_result) >= 0) |
| 19 | goto done; | 19 | goto done; |
| 20 | 20 | ||
| 21 | ncpu = sysconf(_SC_NPROCESSORS_CONF); | 21 | ncpu = sysconf(_SC_NPROCESSORS_CONF); |
| @@ -69,6 +69,7 @@ KERNEL_INCLUDE := $(OUTPUT)include · 68 unmodified lines | |||
| 69 | ACPICA_INCLUDE := $(srctree)/../../../drivers/acpi/acpica | 69 | ACPICA_INCLUDE := $(srctree)/../../../drivers/acpi/acpica |
| 70 | CFLAGS += -D_LINUX -I$(KERNEL_INCLUDE) -I$(ACPICA_INCLUDE) | 70 | CFLAGS += -D_LINUX -I$(KERNEL_INCLUDE) -I$(ACPICA_INCLUDE) |
| 71 | CFLAGS += $(WARNINGS) | 71 | CFLAGS += $(WARNINGS) |
| 72 | MKDIR = mkdir | ||
| 72 | 73 | ||
| 73 | ifeq ($(strip $(V)),false) | 74 | ifeq ($(strip $(V)),false) |
| 74 | QUIET=@ | 75 | QUIET=@ |
| @@ -21,6 +21,7 @@ $(KERNEL_INCLUDE): · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | $(objdir)%.o: %.c $(KERNEL_INCLUDE) | 22 | $(objdir)%.o: %.c $(KERNEL_INCLUDE) |
| 23 | $(ECHO) " CC " $(subst $(OUTPUT),,$@) | 23 | $(ECHO) " CC " $(subst $(OUTPUT),,$@) |
| 24 | $(QUIET) $(MKDIR) -p $(objdir) 2>/dev/null | ||
| 24 | $(QUIET) $(CC) -c $(CFLAGS) -o $@ $< | 25 | $(QUIET) $(CC) -c $(CFLAGS) -o $@ $< |
| 25 | 26 | ||
| 26 | all: $(OUTPUT)$(TOOL) | 27 | all: $(OUTPUT)$(TOOL) |
| @@ -1,5 +1,8 @@ | |||
| 1 | #ifndef _LINUX_LOCKDEP_H | 1 | #ifndef _LINUX_LOCKDEP_H |
| 2 | #define _LINUX_LOCKDEP_H | 2 | #define _LINUX_LOCKDEP_H |
| 3 | |||
| 4 | #include <linux/spinlock.h> | ||
| 5 | |||
| 3 | struct lock_class_key { | 6 | struct lock_class_key { |
| 4 | unsigned int a; | 7 | unsigned int a; |
| 5 | }; | 8 | }; |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | |||
| 35 | .prog_type = BPF_PROG_TYPE_XDP, | 35 | .prog_type = BPF_PROG_TYPE_XDP, |
| 36 | }, | 36 | }, |
| 37 | { | 37 | { |
| 38 | "XDP pkt read, pkt_data' > pkt_end, good access", | 38 | "XDP pkt read, pkt_data' > pkt_end, corner case, good access", |
| 39 | .insns = { | 39 | .insns = { |
| 40 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | 40 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 41 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | 41 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, |
| @@ -87,6 +87,41 @@ · 45 unmodified lines | |||
| 87 | .prog_type = BPF_PROG_TYPE_XDP, | 87 | .prog_type = BPF_PROG_TYPE_XDP, |
| 88 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 88 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 89 | }, | 89 | }, |
| 90 | { | ||
| 91 | "XDP pkt read, pkt_data' > pkt_end, corner case +1, good access", | ||
| 92 | .insns = { | ||
| 93 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 94 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 95 | offsetof(struct xdp_md, data_end)), | ||
| 96 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 97 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9), | ||
| 98 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
| 99 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9), | ||
| 100 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 101 | BPF_EXIT_INSN(), | ||
| 102 | }, | ||
| 103 | .result = ACCEPT, | ||
| 104 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 105 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 106 | }, | ||
| 107 | { | ||
| 108 | "XDP pkt read, pkt_data' > pkt_end, corner case -1, bad access", | ||
| 109 | .insns = { | ||
| 110 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 111 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 112 | offsetof(struct xdp_md, data_end)), | ||
| 113 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 114 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 115 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
| 116 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 117 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 118 | BPF_EXIT_INSN(), | ||
| 119 | }, | ||
| 120 | .errstr = "R1 offset is outside of the packet", | ||
| 121 | .result = REJECT, | ||
| 122 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 123 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 124 | }, | ||
| 90 | { | 125 | { |
| 91 | "XDP pkt read, pkt_end > pkt_data', good access", | 126 | "XDP pkt read, pkt_end > pkt_data', good access", |
| 92 | .insns = { | 127 | .insns = { |
| @@ -106,16 +141,16 @@ · 13 unmodified lines | |||
| 106 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 141 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 107 | }, | 142 | }, |
| 108 | { | 143 | { |
| 109 | "XDP pkt read, pkt_end > pkt_data', bad access 1", | 144 | "XDP pkt read, pkt_end > pkt_data', corner case -1, bad access", |
| 110 | .insns = { | 145 | .insns = { |
| 111 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | 146 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 112 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | 147 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, |
| 113 | offsetof(struct xdp_md, data_end)), | 148 | offsetof(struct xdp_md, data_end)), |
| 114 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | 149 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), |
| 115 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | 150 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), |
| 116 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | 151 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), |
| 117 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | 152 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), |
| 118 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | 153 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6), |
| 119 | BPF_MOV64_IMM(BPF_REG_0, 0), | 154 | BPF_MOV64_IMM(BPF_REG_0, 0), |
| 120 | BPF_EXIT_INSN(), | 155 | BPF_EXIT_INSN(), |
| 121 | }, | 156 | }, |
| @@ -142,6 +177,42 @@ · 20 unmodified lines | |||
| 142 | .prog_type = BPF_PROG_TYPE_XDP, | 177 | .prog_type = BPF_PROG_TYPE_XDP, |
| 143 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 178 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 144 | }, | 179 | }, |
| 180 | { | ||
| 181 | "XDP pkt read, pkt_end > pkt_data', corner case, good access", | ||
| 182 | .insns = { | ||
| 183 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 184 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 185 | offsetof(struct xdp_md, data_end)), | ||
| 186 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 187 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 188 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | ||
| 189 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 190 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 191 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 192 | BPF_EXIT_INSN(), | ||
| 193 | }, | ||
| 194 | .result = ACCEPT, | ||
| 195 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 196 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 197 | }, | ||
| 198 | { | ||
| 199 | "XDP pkt read, pkt_end > pkt_data', corner case +1, good access", | ||
| 200 | .insns = { | ||
| 201 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 202 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 203 | offsetof(struct xdp_md, data_end)), | ||
| 204 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 205 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
| 206 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | ||
| 207 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 208 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
| 209 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 210 | BPF_EXIT_INSN(), | ||
| 211 | }, | ||
| 212 | .result = ACCEPT, | ||
| 213 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 214 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 215 | }, | ||
| 145 | { | 216 | { |
| 146 | "XDP pkt read, pkt_data' < pkt_end, good access", | 217 | "XDP pkt read, pkt_data' < pkt_end, good access", |
| 147 | .insns = { | 218 | .insns = { |
| @@ -161,16 +232,16 @@ · 13 unmodified lines | |||
| 161 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 232 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 162 | }, | 233 | }, |
| 163 | { | 234 | { |
| 164 | "XDP pkt read, pkt_data' < pkt_end, bad access 1", | 235 | "XDP pkt read, pkt_data' < pkt_end, corner case -1, bad access", |
| 165 | .insns = { | 236 | .insns = { |
| 166 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | 237 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 167 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | 238 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, |
| 168 | offsetof(struct xdp_md, data_end)), | 239 | offsetof(struct xdp_md, data_end)), |
| 169 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | 240 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), |
| 170 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | 241 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), |
| 171 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | 242 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), |
| 172 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | 243 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), |
| 173 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | 244 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6), |
| 174 | BPF_MOV64_IMM(BPF_REG_0, 0), | 245 | BPF_MOV64_IMM(BPF_REG_0, 0), |
| 175 | BPF_EXIT_INSN(), | 246 | BPF_EXIT_INSN(), |
| 176 | }, | 247 | }, |
| @@ -198,7 +269,43 @@ · 21 unmodified lines | |||
| 198 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 269 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 199 | }, | 270 | }, |
| 200 | { | 271 | { |
| 201 | "XDP pkt read, pkt_end < pkt_data', good access", | 272 | "XDP pkt read, pkt_data' < pkt_end, corner case, good access", |
| 273 | .insns = { | ||
| 274 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 275 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 276 | offsetof(struct xdp_md, data_end)), | ||
| 277 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 278 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 279 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | ||
| 280 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 281 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 282 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 283 | BPF_EXIT_INSN(), | ||
| 284 | }, | ||
| 285 | .result = ACCEPT, | ||
| 286 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 287 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 288 | }, | ||
| 289 | { | ||
| 290 | "XDP pkt read, pkt_data' < pkt_end, corner case +1, good access", | ||
| 291 | .insns = { | ||
| 292 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 293 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 294 | offsetof(struct xdp_md, data_end)), | ||
| 295 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 296 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
| 297 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | ||
| 298 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 299 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
| 300 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 301 | BPF_EXIT_INSN(), | ||
| 302 | }, | ||
| 303 | .result = ACCEPT, | ||
| 304 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 305 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 306 | }, | ||
| 307 | { | ||
| 308 | "XDP pkt read, pkt_end < pkt_data', corner case, good access", | ||
| 202 | .insns = { | 309 | .insns = { |
| 203 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | 310 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 204 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | 311 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, |
| @@ -250,6 +357,41 @@ · 45 unmodified lines | |||
| 250 | .prog_type = BPF_PROG_TYPE_XDP, | 357 | .prog_type = BPF_PROG_TYPE_XDP, |
| 251 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 358 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 252 | }, | 359 | }, |
| 360 | { | ||
| 361 | "XDP pkt read, pkt_end < pkt_data', corner case +1, good access", | ||
| 362 | .insns = { | ||
| 363 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 364 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 365 | offsetof(struct xdp_md, data_end)), | ||
| 366 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 367 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9), | ||
| 368 | BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1), | ||
| 369 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9), | ||
| 370 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 371 | BPF_EXIT_INSN(), | ||
| 372 | }, | ||
| 373 | .result = ACCEPT, | ||
| 374 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 375 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 376 | }, | ||
| 377 | { | ||
| 378 | "XDP pkt read, pkt_end < pkt_data', corner case -1, bad access", | ||
| 379 | .insns = { | ||
| 380 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 381 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 382 | offsetof(struct xdp_md, data_end)), | ||
| 383 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 384 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 385 | BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1), | ||
| 386 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 387 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 388 | BPF_EXIT_INSN(), | ||
| 389 | }, | ||
| 390 | .errstr = "R1 offset is outside of the packet", | ||
| 391 | .result = REJECT, | ||
| 392 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 393 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 394 | }, | ||
| 253 | { | 395 | { |
| 254 | "XDP pkt read, pkt_data' >= pkt_end, good access", | 396 | "XDP pkt read, pkt_data' >= pkt_end, good access", |
| 255 | .insns = { | 397 | .insns = { |
| @@ -268,15 +410,15 @@ · 12 unmodified lines | |||
| 268 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 410 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 269 | }, | 411 | }, |
| 270 | { | 412 | { |
| 271 | "XDP pkt read, pkt_data' >= pkt_end, bad access 1", | 413 | "XDP pkt read, pkt_data' >= pkt_end, corner case -1, bad access", |
| 272 | .insns = { | 414 | .insns = { |
| 273 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | 415 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 274 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | 416 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, |
| 275 | offsetof(struct xdp_md, data_end)), | 417 | offsetof(struct xdp_md, data_end)), |
| 276 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | 418 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), |
| 277 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | 419 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), |
| 278 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), | 420 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), |
| 279 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | 421 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6), |
| 280 | BPF_MOV64_IMM(BPF_REG_0, 0), | 422 | BPF_MOV64_IMM(BPF_REG_0, 0), |
| 281 | BPF_EXIT_INSN(), | 423 | BPF_EXIT_INSN(), |
| 282 | }, | 424 | }, |
| @@ -304,7 +446,41 @@ · 21 unmodified lines | |||
| 304 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 446 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 305 | }, | 447 | }, |
| 306 | { | 448 | { |
| 307 | "XDP pkt read, pkt_end >= pkt_data', good access", | 449 | "XDP pkt read, pkt_data' >= pkt_end, corner case, good access", |
| 450 | .insns = { | ||
| 451 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 452 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 453 | offsetof(struct xdp_md, data_end)), | ||
| 454 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 455 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 456 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), | ||
| 457 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 458 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 459 | BPF_EXIT_INSN(), | ||
| 460 | }, | ||
| 461 | .result = ACCEPT, | ||
| 462 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 463 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 464 | }, | ||
| 465 | { | ||
| 466 | "XDP pkt read, pkt_data' >= pkt_end, corner case +1, good access", | ||
| 467 | .insns = { | ||
| 468 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 469 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 470 | offsetof(struct xdp_md, data_end)), | ||
| 471 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 472 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
| 473 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), | ||
| 474 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
| 475 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 476 | BPF_EXIT_INSN(), | ||
| 477 | }, | ||
| 478 | .result = ACCEPT, | ||
| 479 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 480 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 481 | }, | ||
| 482 | { | ||
| 483 | "XDP pkt read, pkt_end >= pkt_data', corner case, good access", | ||
| 308 | .insns = { | 484 | .insns = { |
| 309 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | 485 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 310 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | 486 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, |
| @@ -359,7 +535,44 @@ · 48 unmodified lines | |||
| 359 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 535 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 360 | }, | 536 | }, |
| 361 | { | 537 | { |
| 362 | "XDP pkt read, pkt_data' <= pkt_end, good access", | 538 | "XDP pkt read, pkt_end >= pkt_data', corner case +1, good access", |
| 539 | .insns = { | ||
| 540 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 541 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 542 | offsetof(struct xdp_md, data_end)), | ||
| 543 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 544 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9), | ||
| 545 | BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), | ||
| 546 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 547 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9), | ||
| 548 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 549 | BPF_EXIT_INSN(), | ||
| 550 | }, | ||
| 551 | .result = ACCEPT, | ||
| 552 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 553 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 554 | }, | ||
| 555 | { | ||
| 556 | "XDP pkt read, pkt_end >= pkt_data', corner case -1, bad access", | ||
| 557 | .insns = { | ||
| 558 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 559 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 560 | offsetof(struct xdp_md, data_end)), | ||
| 561 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 562 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 563 | BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), | ||
| 564 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 565 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 566 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 567 | BPF_EXIT_INSN(), | ||
| 568 | }, | ||
| 569 | .errstr = "R1 offset is outside of the packet", | ||
| 570 | .result = REJECT, | ||
| 571 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 572 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 573 | }, | ||
| 574 | { | ||
| 575 | "XDP pkt read, pkt_data' <= pkt_end, corner case, good access", | ||
| 363 | .insns = { | 576 | .insns = { |
| 364 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | 577 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 365 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | 578 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, |
| @@ -413,6 +626,43 @@ · 47 unmodified lines | |||
| 413 | .prog_type = BPF_PROG_TYPE_XDP, | 626 | .prog_type = BPF_PROG_TYPE_XDP, |
| 414 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 627 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 415 | }, | 628 | }, |
| 629 | { | ||
| 630 | "XDP pkt read, pkt_data' <= pkt_end, corner case +1, good access", | ||
| 631 | .insns = { | ||
| 632 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 633 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 634 | offsetof(struct xdp_md, data_end)), | ||
| 635 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 636 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9), | ||
| 637 | BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), | ||
| 638 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 639 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9), | ||
| 640 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 641 | BPF_EXIT_INSN(), | ||
| 642 | }, | ||
| 643 | .result = ACCEPT, | ||
| 644 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 645 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 646 | }, | ||
| 647 | { | ||
| 648 | "XDP pkt read, pkt_data' <= pkt_end, corner case -1, bad access", | ||
| 649 | .insns = { | ||
| 650 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 651 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 652 | offsetof(struct xdp_md, data_end)), | ||
| 653 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 654 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 655 | BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), | ||
| 656 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 657 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 658 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 659 | BPF_EXIT_INSN(), | ||
| 660 | }, | ||
| 661 | .errstr = "R1 offset is outside of the packet", | ||
| 662 | .result = REJECT, | ||
| 663 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 664 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 665 | }, | ||
| 416 | { | 666 | { |
| 417 | "XDP pkt read, pkt_end <= pkt_data', good access", | 667 | "XDP pkt read, pkt_end <= pkt_data', good access", |
| 418 | .insns = { | 668 | .insns = { |
| @@ -431,15 +681,15 @@ · 12 unmodified lines | |||
| 431 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 681 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 432 | }, | 682 | }, |
| 433 | { | 683 | { |
| 434 | "XDP pkt read, pkt_end <= pkt_data', bad access 1", | 684 | "XDP pkt read, pkt_end <= pkt_data', corner case -1, bad access", |
| 435 | .insns = { | 685 | .insns = { |
| 436 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | 686 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 437 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | 687 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, |
| 438 | offsetof(struct xdp_md, data_end)), | 688 | offsetof(struct xdp_md, data_end)), |
| 439 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | 689 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), |
| 440 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | 690 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), |
| 441 | BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1), | 691 | BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1), |
| 442 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | 692 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6), |
| 443 | BPF_MOV64_IMM(BPF_REG_0, 0), | 693 | BPF_MOV64_IMM(BPF_REG_0, 0), |
| 444 | BPF_EXIT_INSN(), | 694 | BPF_EXIT_INSN(), |
| 445 | }, | 695 | }, |
| @@ -467,7 +717,41 @@ · 21 unmodified lines | |||
| 467 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 717 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 468 | }, | 718 | }, |
| 469 | { | 719 | { |
| 470 | "XDP pkt read, pkt_meta' > pkt_data, good access", | 720 | "XDP pkt read, pkt_end <= pkt_data', corner case, good access", |
| 721 | .insns = { | ||
| 722 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 723 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 724 | offsetof(struct xdp_md, data_end)), | ||
| 725 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 726 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 727 | BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1), | ||
| 728 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 729 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 730 | BPF_EXIT_INSN(), | ||
| 731 | }, | ||
| 732 | .result = ACCEPT, | ||
| 733 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 734 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 735 | }, | ||
| 736 | { | ||
| 737 | "XDP pkt read, pkt_end <= pkt_data', corner case +1, good access", | ||
| 738 | .insns = { | ||
| 739 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 740 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
| 741 | offsetof(struct xdp_md, data_end)), | ||
| 742 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 743 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
| 744 | BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1), | ||
| 745 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
| 746 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 747 | BPF_EXIT_INSN(), | ||
| 748 | }, | ||
| 749 | .result = ACCEPT, | ||
| 750 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 751 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 752 | }, | ||
| 753 | { | ||
| 754 | "XDP pkt read, pkt_meta' > pkt_data, corner case, good access", | ||
| 471 | .insns = { | 755 | .insns = { |
| 472 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | 756 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, |
| 473 | offsetof(struct xdp_md, data_meta)), | 757 | offsetof(struct xdp_md, data_meta)), |
| @@ -519,6 +803,41 @@ · 45 unmodified lines | |||
| 519 | .prog_type = BPF_PROG_TYPE_XDP, | 803 | .prog_type = BPF_PROG_TYPE_XDP, |
| 520 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 804 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 521 | }, | 805 | }, |
| 806 | { | ||
| 807 | "XDP pkt read, pkt_meta' > pkt_data, corner case +1, good access", | ||
| 808 | .insns = { | ||
| 809 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 810 | offsetof(struct xdp_md, data_meta)), | ||
| 811 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 812 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 813 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9), | ||
| 814 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
| 815 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9), | ||
| 816 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 817 | BPF_EXIT_INSN(), | ||
| 818 | }, | ||
| 819 | .result = ACCEPT, | ||
| 820 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 821 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 822 | }, | ||
| 823 | { | ||
| 824 | "XDP pkt read, pkt_meta' > pkt_data, corner case -1, bad access", | ||
| 825 | .insns = { | ||
| 826 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 827 | offsetof(struct xdp_md, data_meta)), | ||
| 828 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 829 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 830 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 831 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
| 832 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 833 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 834 | BPF_EXIT_INSN(), | ||
| 835 | }, | ||
| 836 | .errstr = "R1 offset is outside of the packet", | ||
| 837 | .result = REJECT, | ||
| 838 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 839 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 840 | }, | ||
| 522 | { | 841 | { |
| 523 | "XDP pkt read, pkt_data > pkt_meta', good access", | 842 | "XDP pkt read, pkt_data > pkt_meta', good access", |
| 524 | .insns = { | 843 | .insns = { |
| @@ -538,16 +857,16 @@ · 13 unmodified lines | |||
| 538 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 857 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 539 | }, | 858 | }, |
| 540 | { | 859 | { |
| 541 | "XDP pkt read, pkt_data > pkt_meta', bad access 1", | 860 | "XDP pkt read, pkt_data > pkt_meta', corner case -1, bad access", |
| 542 | .insns = { | 861 | .insns = { |
| 543 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | 862 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, |
| 544 | offsetof(struct xdp_md, data_meta)), | 863 | offsetof(struct xdp_md, data_meta)), |
| 545 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | 864 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 546 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | 865 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), |
| 547 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | 866 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), |
| 548 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | 867 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), |
| 549 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | 868 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), |
| 550 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | 869 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6), |
| 551 | BPF_MOV64_IMM(BPF_REG_0, 0), | 870 | BPF_MOV64_IMM(BPF_REG_0, 0), |
| 552 | BPF_EXIT_INSN(), | 871 | BPF_EXIT_INSN(), |
| 553 | }, | 872 | }, |
| @@ -574,6 +893,42 @@ · 20 unmodified lines | |||
| 574 | .prog_type = BPF_PROG_TYPE_XDP, | 893 | .prog_type = BPF_PROG_TYPE_XDP, |
| 575 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 894 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 576 | }, | 895 | }, |
| 896 | { | ||
| 897 | "XDP pkt read, pkt_data > pkt_meta', corner case, good access", | ||
| 898 | .insns = { | ||
| 899 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 900 | offsetof(struct xdp_md, data_meta)), | ||
| 901 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 902 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 903 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 904 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | ||
| 905 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 906 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 907 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 908 | BPF_EXIT_INSN(), | ||
| 909 | }, | ||
| 910 | .result = ACCEPT, | ||
| 911 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 912 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 913 | }, | ||
| 914 | { | ||
| 915 | "XDP pkt read, pkt_data > pkt_meta', corner case +1, good access", | ||
| 916 | .insns = { | ||
| 917 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 918 | offsetof(struct xdp_md, data_meta)), | ||
| 919 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 920 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 921 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
| 922 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | ||
| 923 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 924 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
| 925 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 926 | BPF_EXIT_INSN(), | ||
| 927 | }, | ||
| 928 | .result = ACCEPT, | ||
| 929 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 930 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 931 | }, | ||
| 577 | { | 932 | { |
| 578 | "XDP pkt read, pkt_meta' < pkt_data, good access", | 933 | "XDP pkt read, pkt_meta' < pkt_data, good access", |
| 579 | .insns = { | 934 | .insns = { |
| @@ -593,16 +948,16 @@ · 13 unmodified lines | |||
| 593 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 948 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 594 | }, | 949 | }, |
| 595 | { | 950 | { |
| 596 | "XDP pkt read, pkt_meta' < pkt_data, bad access 1", | 951 | "XDP pkt read, pkt_meta' < pkt_data, corner case -1, bad access", |
| 597 | .insns = { | 952 | .insns = { |
| 598 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | 953 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, |
| 599 | offsetof(struct xdp_md, data_meta)), | 954 | offsetof(struct xdp_md, data_meta)), |
| 600 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | 955 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 601 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | 956 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), |
| 602 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | 957 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), |
| 603 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | 958 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), |
| 604 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | 959 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), |
| 605 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | 960 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6), |
| 606 | BPF_MOV64_IMM(BPF_REG_0, 0), | 961 | BPF_MOV64_IMM(BPF_REG_0, 0), |
| 607 | BPF_EXIT_INSN(), | 962 | BPF_EXIT_INSN(), |
| 608 | }, | 963 | }, |
| @@ -630,7 +985,43 @@ · 21 unmodified lines | |||
| 630 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 985 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 631 | }, | 986 | }, |
| 632 | { | 987 | { |
| 633 | "XDP pkt read, pkt_data < pkt_meta', good access", | 988 | "XDP pkt read, pkt_meta' < pkt_data, corner case, good access", |
| 989 | .insns = { | ||
| 990 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 991 | offsetof(struct xdp_md, data_meta)), | ||
| 992 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 993 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 994 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 995 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | ||
| 996 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 997 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 998 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 999 | BPF_EXIT_INSN(), | ||
| 1000 | }, | ||
| 1001 | .result = ACCEPT, | ||
| 1002 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 1003 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 1004 | }, | ||
| 1005 | { | ||
| 1006 | "XDP pkt read, pkt_meta' < pkt_data, corner case +1, good access", | ||
| 1007 | .insns = { | ||
| 1008 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 1009 | offsetof(struct xdp_md, data_meta)), | ||
| 1010 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 1011 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 1012 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
| 1013 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | ||
| 1014 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 1015 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
| 1016 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 1017 | BPF_EXIT_INSN(), | ||
| 1018 | }, | ||
| 1019 | .result = ACCEPT, | ||
| 1020 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 1021 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 1022 | }, | ||
| 1023 | { | ||
| 1024 | "XDP pkt read, pkt_data < pkt_meta', corner case, good access", | ||
| 634 | .insns = { | 1025 | .insns = { |
| 635 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | 1026 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, |
| 636 | offsetof(struct xdp_md, data_meta)), | 1027 | offsetof(struct xdp_md, data_meta)), |
| @@ -682,6 +1073,41 @@ · 45 unmodified lines | |||
| 682 | .prog_type = BPF_PROG_TYPE_XDP, | 1073 | .prog_type = BPF_PROG_TYPE_XDP, |
| 683 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 1074 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 684 | }, | 1075 | }, |
| 1076 | { | ||
| 1077 | "XDP pkt read, pkt_data < pkt_meta', corner case +1, good access", | ||
| 1078 | .insns = { | ||
| 1079 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 1080 | offsetof(struct xdp_md, data_meta)), | ||
| 1081 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 1082 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 1083 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9), | ||
| 1084 | BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1), | ||
| 1085 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9), | ||
| 1086 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 1087 | BPF_EXIT_INSN(), | ||
| 1088 | }, | ||
| 1089 | .result = ACCEPT, | ||
| 1090 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 1091 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 1092 | }, | ||
| 1093 | { | ||
| 1094 | "XDP pkt read, pkt_data < pkt_meta', corner case -1, bad access", | ||
| 1095 | .insns = { | ||
| 1096 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 1097 | offsetof(struct xdp_md, data_meta)), | ||
| 1098 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 1099 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 1100 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 1101 | BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1), | ||
| 1102 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 1103 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 1104 | BPF_EXIT_INSN(), | ||
| 1105 | }, | ||
| 1106 | .errstr = "R1 offset is outside of the packet", | ||
| 1107 | .result = REJECT, | ||
| 1108 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 1109 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 1110 | }, | ||
| 685 | { | 1111 | { |
| 686 | "XDP pkt read, pkt_meta' >= pkt_data, good access", | 1112 | "XDP pkt read, pkt_meta' >= pkt_data, good access", |
| 687 | .insns = { | 1113 | .insns = { |
| @@ -700,15 +1126,15 @@ · 12 unmodified lines | |||
| 700 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 1126 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 701 | }, | 1127 | }, |
| 702 | { | 1128 | { |
| 703 | "XDP pkt read, pkt_meta' >= pkt_data, bad access 1", | 1129 | "XDP pkt read, pkt_meta' >= pkt_data, corner case -1, bad access", |
| 704 | .insns = { | 1130 | .insns = { |
| 705 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | 1131 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, |
| 706 | offsetof(struct xdp_md, data_meta)), | 1132 | offsetof(struct xdp_md, data_meta)), |
| 707 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | 1133 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), |
| 708 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | 1134 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), |
| 709 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | 1135 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), |
| 710 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), | 1136 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), |
| 711 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | 1137 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6), |
| 712 | BPF_MOV64_IMM(BPF_REG_0, 0), | 1138 | BPF_MOV64_IMM(BPF_REG_0, 0), |
| 713 | BPF_EXIT_INSN(), | 1139 | BPF_EXIT_INSN(), |
| 714 | }, | 1140 | }, |
| @@ -736,7 +1162,41 @@ · 21 unmodified lines | |||
| 736 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 1162 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 737 | }, | 1163 | }, |
| 738 | { | 1164 | { |
| 739 | "XDP pkt read, pkt_data >= pkt_meta', good access", | 1165 | "XDP pkt read, pkt_meta' >= pkt_data, corner case, good access", |
| 1166 | .insns = { | ||
| 1167 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 1168 | offsetof(struct xdp_md, data_meta)), | ||
| 1169 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 1170 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 1171 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 1172 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), | ||
| 1173 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 1174 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 1175 | BPF_EXIT_INSN(), | ||
| 1176 | }, | ||
| 1177 | .result = ACCEPT, | ||
| 1178 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 1179 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 1180 | }, | ||
| 1181 | { | ||
| 1182 | "XDP pkt read, pkt_meta' >= pkt_data, corner case +1, good access", | ||
| 1183 | .insns = { | ||
| 1184 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 1185 | offsetof(struct xdp_md, data_meta)), | ||
| 1186 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 1187 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 1188 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
| 1189 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), | ||
| 1190 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
| 1191 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 1192 | BPF_EXIT_INSN(), | ||
| 1193 | }, | ||
| 1194 | .result = ACCEPT, | ||
| 1195 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 1196 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 1197 | }, | ||
| 1198 | { | ||
| 1199 | "XDP pkt read, pkt_data >= pkt_meta', corner case, good access", | ||
| 740 | .insns = { | 1200 | .insns = { |
| 741 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | 1201 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, |
| 742 | offsetof(struct xdp_md, data_meta)), | 1202 | offsetof(struct xdp_md, data_meta)), |
| @@ -791,7 +1251,44 @@ · 48 unmodified lines | |||
| 791 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 1251 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 792 | }, | 1252 | }, |
| 793 | { | 1253 | { |
| 794 | "XDP pkt read, pkt_meta' <= pkt_data, good access", | 1254 | "XDP pkt read, pkt_data >= pkt_meta', corner case +1, good access", |
| 1255 | .insns = { | ||
| 1256 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 1257 | offsetof(struct xdp_md, data_meta)), | ||
| 1258 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 1259 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 1260 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9), | ||
| 1261 | BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), | ||
| 1262 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 1263 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9), | ||
| 1264 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 1265 | BPF_EXIT_INSN(), | ||
| 1266 | }, | ||
| 1267 | .result = ACCEPT, | ||
| 1268 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 1269 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 1270 | }, | ||
| 1271 | { | ||
| 1272 | "XDP pkt read, pkt_data >= pkt_meta', corner case -1, bad access", | ||
| 1273 | .insns = { | ||
| 1274 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 1275 | offsetof(struct xdp_md, data_meta)), | ||
| 1276 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 1277 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 1278 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7), | ||
| 1279 | BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), | ||
| 1280 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 1281 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7), | ||
| 1282 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 1283 | BPF_EXIT_INSN(), | ||
| 1284 | }, | ||
| 1285 | .errstr = "R1 offset is outside of the packet", | ||
| 1286 | .result = REJECT, | ||
| 1287 | .prog_type = BPF_PROG_TYPE_XDP, | ||
| 1288 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 1289 | }, | ||
| 1290 | { | ||
| 1291 | "XDP pkt read, pkt_meta' <= pkt_data, corner case, good access", | ||
| 795 | .insns = { | 1292 | .insns = { |
| 796 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | 1293 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, |
| 797 | offsetof(struct xdp_md, data_meta)), | 1294 | offsetof(struct xdp_md, data_meta)), |
| @@ -845,6 +1342,43 @@ · 47 unmodified lines | |||
| 845 | .prog_type = BPF_PROG_TYPE_XDP, | 1342 | .prog_type = BPF_PROG_TYPE_XDP, |
| 846 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 1343 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 847 | }, | 1344 | }, |
| 1345 | { | ||
| 1346 | "XDP pkt read, pkt_meta' <= pkt_data, corner case +1, good access", | ||
| 1347 | .insns = { | ||
| 1348 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 1349 | offsetof(struct xdp_md, data_meta)), | ||
| 1350 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)), | ||
| 1351 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
| 1352 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9), | ||
| 1353 | BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), | ||
| 1354 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
| 1355 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9), | ||
| 1356 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 1357 | BPF_EXIT_INSN(), | ||
| 1358 | }, | ||
| 1359 | .result = ACCEPT, | ||
| 1360 | .prog_type = BPF_PROG_TYPE_XDP, | ||
81 more 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 8 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 48 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 72 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 23 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 45 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 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 150 lines aren’t shown here.