We want the tty/serial fixes in here as well.
Unified · Split
| @@ -68,6 +68,8 @@ Jacob Shin <Jacob.Shin@amd.com> · 67 unmodified lines | ||
| 68 | 68 | James Bottomley <jejb@mulgrave.(none)> |
| 69 | 69 | James Bottomley <jejb@titanic.il.steeleye.com> |
| 70 | 70 | James E Wilson <wilson@specifix.com> |
| 71 | +James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com> | |
| 72 | +James Hogan <jhogan@kernel.org> <james@albanarts.com> | |
| 71 | 73 | James Ketrenos <jketreno@io.(none)> |
| 72 | 74 | Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com> |
| 73 | 75 | <javier@osg.samsung.com> <javier.martinez@collabora.co.uk> |
| @@ -127,7 +127,7 @@ Description: · 126 unmodified lines | ||
| 127 | 127 | |
| 128 | 128 | What; /sys/power/pm_trace_dev_match |
| 129 | 129 | Date: October 2010 |
| 130 | −Contact: James Hogan <james@albanarts.com> | |
| 130 | +Contact: James Hogan <jhogan@kernel.org> | |
| 131 | 131 | Description: |
| 132 | 132 | The /sys/power/pm_trace_dev_match file contains the name of the |
| 133 | 133 | device associated with the last PM event point saved in the RTC |
| @@ -39,8 +39,8 @@ up. · 38 unmodified lines | ||
| 39 | 39 | Although MT wq wasted a lot of resource, the level of concurrency |
| 40 | 40 | provided was unsatisfactory. The limitation was common to both ST and |
| 41 | 41 | MT wq albeit less severe on MT. Each wq maintained its own separate |
| 42 | −worker pool. A MT wq could provide only one execution context per CPU | |
| 43 | −while a ST wq one for the whole system. Work items had to compete for | |
| 42 | +worker pool. An MT wq could provide only one execution context per CPU | |
| 43 | +while an ST wq one for the whole system. Work items had to compete for | |
| 44 | 44 | those very limited execution contexts leading to various problems |
| 45 | 45 | including proneness to deadlocks around the single execution context. |
| 46 | 46 | |
| @@ -151,7 +151,7 @@ Application Programming Interface (API) · 104 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | ``alloc_workqueue()`` allocates a wq. The original |
| 153 | 153 | ``create_*workqueue()`` functions are deprecated and scheduled for |
| 154 | −removal. ``alloc_workqueue()`` takes three arguments - @``name``, | |
| 154 | +removal. ``alloc_workqueue()`` takes three arguments - ``@name``, | |
| 155 | 155 | ``@flags`` and ``@max_active``. ``@name`` is the name of the wq and |
| 156 | 156 | also used as the name of the rescuer thread if there is one. |
| 157 | 157 | |
| @@ -197,7 +197,7 @@ resources, scheduled and executed. · 39 unmodified lines | ||
| 197 | 197 | served by worker threads with elevated nice level. |
| 198 | 198 | |
| 199 | 199 | Note that normal and highpri worker-pools don't interact with |
| 200 | − each other. Each maintain its separate pool of workers and | |
| 200 | + each other. Each maintains its separate pool of workers and | |
| 201 | 201 | implements concurrency management among its workers. |
| 202 | 202 | |
| 203 | 203 | ``WQ_CPU_INTENSIVE`` |
| @@ -249,8 +249,8 @@ unbound worker-pools and only one work item could be active at any given · 45 unmodified lines | ||
| 249 | 249 | time thus achieving the same ordering property as ST wq. |
| 250 | 250 | |
| 251 | 251 | In the current implementation the above configuration only guarantees |
| 252 | −ST behavior within a given NUMA node. Instead alloc_ordered_queue should | |
| 253 | −be used to achieve system wide ST behavior. | |
| 252 | +ST behavior within a given NUMA node. Instead ``alloc_ordered_queue()`` should | |
| 253 | +be used to achieve system-wide ST behavior. | |
| 254 | 254 | |
| 255 | 255 | |
| 256 | 256 | Example Execution Scenarios |
| @@ -32,8 +32,6 @@ cpufreq-stats.txt - General description of sysfs cpufreq stats. · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | index.txt - File index, Mailing list and Links (this document) |
| 34 | 34 | |
| 35 | −intel-pstate.txt - Intel pstate cpufreq driver specific file. | |
| 36 | − | |
| 37 | 35 | pcc-cpufreq.txt - PCC cpufreq driver specific file. |
| 38 | 36 | |
| 39 | 37 | |
| @@ -344,3 +344,4 @@ Version History · 343 unmodified lines | ||
| 344 | 344 | (wrong raid10_copies/raid10_format sequence) |
| 345 | 345 | 1.11.1 Add raid4/5/6 journal write-back support via journal_mode option |
| 346 | 346 | 1.12.1 fix for MD deadlock between mddev_suspend() and md_write_start() available |
| 347 | +1.13.0 Fix dev_health status at end of "recover" (was 'a', now 'A') | |
| @@ -32,7 +32,7 @@ Example: · 31 unmodified lines | ||
| 32 | 32 | compatible = "st,stm32h743-rcc", "st,stm32-rcc"; |
| 33 | 33 | reg = <0x58024400 0x400>; |
| 34 | 34 | #reset-cells = <1>; |
| 35 | − #clock-cells = <2>; | |
| 35 | + #clock-cells = <1>; | |
| 36 | 36 | clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>; |
| 37 | 37 | |
| 38 | 38 | st,syscfg = <&pwrcfg>; |
| @@ -15,11 +15,14 @@ Required properties · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | compatible : Must be "ams,as3645a". |
| 17 | 17 | reg : The I2C address of the device. Typically 0x30. |
| 18 | +#address-cells : 1 | |
| 19 | +#size-cells : 0 | |
| 18 | 20 | |
| 19 | 21 | |
| 20 | −Required properties of the "flash" child node | |
| 21 | −============================================= | |
| 22 | +Required properties of the flash child node (0) | |
| 23 | +=============================================== | |
| 22 | 24 | |
| 25 | +reg: 0 | |
| 23 | 26 | flash-timeout-us: Flash timeout in microseconds. The value must be in |
| 24 | 27 | the range [100000, 850000] and divisible by 50000. |
| 25 | 28 | flash-max-microamp: Maximum flash current in microamperes. Has to be |
| @@ -33,20 +36,21 @@ ams,input-max-microamp: Maximum flash controller input current. The · 7 unmodified lines | ||
| 33 | 36 | and divisible by 50000. |
| 34 | 37 | |
| 35 | 38 | |
| 36 | −Optional properties of the "flash" child node | |
| 37 | −============================================= | |
| 39 | +Optional properties of the flash child node | |
| 40 | +=========================================== | |
| 38 | 41 | |
| 39 | 42 | label : The label of the flash LED. |
| 40 | 43 | |
| 41 | 44 | |
| 42 | −Required properties of the "indicator" child node | |
| 43 | −================================================= | |
| 45 | +Required properties of the indicator child node (1) | |
| 46 | +=================================================== | |
| 44 | 47 | |
| 48 | +reg: 1 | |
| 45 | 49 | led-max-microamp: Maximum indicator current. The allowed values are |
| 46 | 50 | 2500, 5000, 7500 and 10000. |
| 47 | 51 | |
| 48 | −Optional properties of the "indicator" child node | |
| 49 | −================================================= | |
| 52 | +Optional properties of the indicator child node | |
| 53 | +=============================================== | |
| 50 | 54 | |
| 51 | 55 | label : The label of the indicator LED. |
| 52 | 56 | |
| @@ -55,16 +59,20 @@ Example · 2 unmodified lines | ||
| 55 | 59 | ======= |
| 56 | 60 | |
| 57 | 61 | as3645a@30 { |
| 62 | + #address-cells: 1 | |
| 63 | + #size-cells: 0 | |
| 58 | 64 | reg = <0x30>; |
| 59 | 65 | compatible = "ams,as3645a"; |
| 60 | − flash { | |
| 66 | + flash@0 { | |
| 67 | + reg = <0x0>; | |
| 61 | 68 | flash-timeout-us = <150000>; |
| 62 | 69 | flash-max-microamp = <320000>; |
| 63 | 70 | led-max-microamp = <60000>; |
| 64 | 71 | ams,input-max-microamp = <1750000>; |
| 65 | 72 | label = "as3645a:flash"; |
| 66 | 73 | }; |
| 67 | − indicator { | |
| 74 | + indicator@1 { | |
| 75 | + reg = <0x1>; | |
| 68 | 76 | led-max-microamp = <10000>; |
| 69 | 77 | label = "as3645a:indicator"; |
| 70 | 78 | }; |
| @@ -16,11 +16,13 @@ Required Properties: · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | - clocks: |
| 18 | 18 | Array of clocks required for SDHC. |
| 19 | − Require at least input clock for Xenon IP core. | |
| 19 | + Require at least input clock for Xenon IP core. For Armada AP806 and | |
| 20 | + CP110, the AXI clock is also mandatory. | |
| 20 | 21 | |
| 21 | 22 | - clock-names: |
| 22 | 23 | Array of names corresponding to clocks property. |
| 23 | 24 | The input clock for Xenon IP core should be named as "core". |
| 25 | + The input clock for the AXI bus must be named as "axi". | |
| 24 | 26 | |
| 25 | 27 | - reg: |
| 26 | 28 | * For "marvell,armada-3700-sdhci", two register areas. |
| @@ -106,8 +108,8 @@ Example: · 79 unmodified lines | ||
| 106 | 108 | compatible = "marvell,armada-ap806-sdhci"; |
| 107 | 109 | reg = <0xaa0000 0x1000>; |
| 108 | 110 | interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH> |
| 109 | − clocks = <&emmc_clk>; | |
| 110 | − clock-names = "core"; | |
| 111 | + clocks = <&emmc_clk>,<&axi_clk>; | |
| 112 | + clock-names = "core", "axi"; | |
| 111 | 113 | bus-width = <4>; |
| 112 | 114 | marvell,xenon-phy-slow-mode; |
| 113 | 115 | marvell,xenon-tun-count = <11>; |
| @@ -126,8 +128,8 @@ Example: · 12 unmodified lines | ||
| 126 | 128 | interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH> |
| 127 | 129 | vqmmc-supply = <&sd_vqmmc_regulator>; |
| 128 | 130 | vmmc-supply = <&sd_vmmc_regulator>; |
| 129 | − clocks = <&sdclk>; | |
| 130 | − clock-names = "core"; | |
| 131 | + clocks = <&sdclk>, <&axi_clk>; | |
| 132 | + clock-names = "core", "axi"; | |
| 131 | 133 | bus-width = <4>; |
| 132 | 134 | marvell,xenon-tun-count = <9>; |
| 133 | 135 | }; |
| @@ -21,8 +21,9 @@ Required properties: · 20 unmodified lines | ||
| 21 | 21 | - main controller clock (for both armada-375-pp2 and armada-7k-pp2) |
| 22 | 22 | - GOP clock (for both armada-375-pp2 and armada-7k-pp2) |
| 23 | 23 | - MG clock (only for armada-7k-pp2) |
| 24 | −- clock-names: names of used clocks, must be "pp_clk", "gop_clk" and | |
| 25 | − "mg_clk" (the latter only for armada-7k-pp2). | |
| 24 | + - AXI clock (only for armada-7k-pp2) | |
| 25 | +- clock-names: names of used clocks, must be "pp_clk", "gop_clk", "mg_clk" | |
| 26 | + and "axi_clk" (the 2 latter only for armada-7k-pp2). | |
| 26 | 27 | |
| 27 | 28 | The ethernet ports are represented by subnodes. At least one port is |
| 28 | 29 | required. |
| @@ -78,8 +79,9 @@ Example for marvell,armada-7k-pp2: · 49 unmodified lines | ||
| 78 | 79 | cpm_ethernet: ethernet@0 { |
| 79 | 80 | compatible = "marvell,armada-7k-pp22"; |
| 80 | 81 | reg = <0x0 0x100000>, <0x129000 0xb000>; |
| 81 | − clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, <&cpm_syscon0 1 5>; | |
| 82 | − clock-names = "pp_clk", "gop_clk", "gp_clk"; | |
| 82 | + clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, | |
| 83 | + <&cpm_syscon0 1 5>, <&cpm_syscon0 1 18>; | |
| 84 | + clock-names = "pp_clk", "gop_clk", "gp_clk", "axi_clk"; | |
| 83 | 85 | |
| 84 | 86 | eth0: eth0 { |
| 85 | 87 | interrupts = <ICU_GRP_NSR 39 IRQ_TYPE_LEVEL_HIGH>, |
| @@ -4,6 +4,7 @@ The device node has following properties. · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | Required properties: |
| 6 | 6 | - compatible: should be "rockchip,<name>-gamc" |
| 7 | + "rockchip,rk3128-gmac": found on RK312x SoCs | |
| 7 | 8 | "rockchip,rk3228-gmac": found on RK322x SoCs |
| 8 | 9 | "rockchip,rk3288-gmac": found on RK3288 SoCs |
| 9 | 10 | "rockchip,rk3328-gmac": found on RK3328 SoCs |
| @@ -0,0 +1,28 @@ | ||
| 1 | +Binding for the Synopsys HSDK reset controller | |
| 2 | + | |
| 3 | +This binding uses the common reset binding[1]. | |
| 4 | + | |
| 5 | +[1] Documentation/devicetree/bindings/reset/reset.txt | |
| 6 | + | |
| 7 | +Required properties: | |
| 8 | +- compatible: should be "snps,hsdk-reset". | |
| 9 | +- reg: should always contain 2 pairs address - length: first for reset | |
| 10 | + configuration register and second for corresponding SW reset and status bits | |
| 11 | + register. | |
| 12 | +- #reset-cells: from common reset binding; Should always be set to 1. | |
| 13 | + | |
| 14 | +Example: | |
| 15 | + reset: reset@880 { | |
| 16 | + compatible = "snps,hsdk-reset"; | |
| 17 | + #reset-cells = <1>; | |
| 18 | + reg = <0x8A0 0x4>, <0xFF0 0x4>; | |
| 19 | + }; | |
| 20 | + | |
| 21 | +Specifying reset lines connected to IP modules: | |
| 22 | + ethernet@.... { | |
| 23 | + .... | |
| 24 | + resets = <&reset HSDK_V1_ETH_RESET>; | |
| 25 | + .... | |
| 26 | + }; | |
| 27 | + | |
| 28 | +The index could be found in <dt-bindings/reset/snps,hsdk-reset.h> | |
| @@ -8,6 +8,12 @@ Required properties: · 7 unmodified lines | ||
| 8 | 8 | the firmware event log |
| 9 | 9 | - linux,sml-size : size of the memory allocated for the firmware event log |
| 10 | 10 | |
| 11 | +Optional properties: | |
| 12 | + | |
| 13 | +- powered-while-suspended: present when the TPM is left powered on between | |
| 14 | + suspend and resume (makes the suspend/resume | |
| 15 | + callbacks do nothing). | |
| 16 | + | |
| 11 | 17 | Example (for OpenPower Systems with Nuvoton TPM 2.0 on I2C) |
| 12 | 18 | ---------------------------------------------------------- |
| 13 | 19 | |
| @@ -41,6 +41,8 @@ Required properties: · 40 unmodified lines | ||
| 41 | 41 | - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. |
| 42 | 42 | - "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART. |
| 43 | 43 | - "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART. |
| 44 | + - "renesas,scif-r8a77970" for R8A77970 (R-Car V3M) SCIF compatible UART. | |
| 45 | + - "renesas,hscif-r8a77970" for R8A77970 (R-Car V3M) HSCIF compatible UART. | |
| 44 | 46 | - "renesas,scif-r8a77995" for R8A77995 (R-Car D3) SCIF compatible UART. |
| 45 | 47 | - "renesas,hscif-r8a77995" for R8A77995 (R-Car D3) HSCIF compatible UART. |
| 46 | 48 | - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. |
| @@ -3,8 +3,8 @@ Device tree binding vendor prefix registry. Keep list in alphabetical order. · 2 unmodified lines | ||
| 3 | 3 | This isn't an exhaustive list, but you should add new prefixes to it before |
| 4 | 4 | using them to avoid name-space collisions. |
| 5 | 5 | |
| 6 | −abcn Abracon Corporation | |
| 7 | 6 | abilis Abilis Systems |
| 7 | +abracon Abracon Corporation | |
| 8 | 8 | actions Actions Semiconductor Co., Ltd. |
| 9 | 9 | active-semi Active-Semi International Inc |
| 10 | 10 | ad Avionic Design GmbH |
| @@ -675,7 +675,7 @@ sub-domain of the parent domain. · 674 unmodified lines | ||
| 675 | 675 | |
| 676 | 676 | Support for power domains is provided through the :c:member:`pm_domain` field of |
| 677 | 677 | |struct device|. This field is a pointer to an object of type |
| 678 | −|struct dev_pm_domain|, defined in :file:`include/linux/pm.h``, providing a set | |
| 678 | +|struct dev_pm_domain|, defined in :file:`include/linux/pm.h`, providing a set | |
| 679 | 679 | of power management callbacks analogous to the subsystem-level and device driver |
| 680 | 680 | callbacks that are executed for the given device during all power transitions, |
| 681 | 681 | instead of the respective subsystem-level callbacks. Specifically, if a |
| @@ -196,12 +196,13 @@ struct driver_attribute { · 195 unmodified lines | ||
| 196 | 196 | }; |
| 197 | 197 | |
| 198 | 198 | Device drivers can export attributes via their sysfs directories. |
| 199 | −Drivers can declare attributes using a DRIVER_ATTR macro that works | |
| 200 | −identically to the DEVICE_ATTR macro. | |
| 199 | +Drivers can declare attributes using a DRIVER_ATTR_RW and DRIVER_ATTR_RO | |
| 200 | +macro that works identically to the DEVICE_ATTR_RW and DEVICE_ATTR_RO | |
| 201 | +macros. | |
| 201 | 202 | |
| 202 | 203 | Example: |
| 203 | 204 | |
| 204 | −DRIVER_ATTR(debug,0644,show_debug,store_debug); | |
| 205 | +DRIVER_ATTR_RW(debug); | |
| 205 | 206 | |
| 206 | 207 | This is equivalent to declaring: |
| 207 | 208 | |
| @@ -41,6 +41,11 @@ Igor Mammedov (DFS support) · 40 unmodified lines | ||
| 41 | 41 | Jeff Layton (many, many fixes, as well as great work on the cifs Kerberos code) |
| 42 | 42 | Scott Lovenberg |
| 43 | 43 | Pavel Shilovsky (for great work adding SMB2 support, and various SMB3 features) |
| 44 | +Aurelien Aptel (for DFS SMB3 work and some key bug fixes) | |
| 45 | +Ronnie Sahlberg (for SMB3 xattr work and bug fixes) | |
| 46 | +Shirish Pargaonkar (for many ACL patches over the years) | |
| 47 | +Sachin Prabhu (many bug fixes, including for reconnect, copy offload and security) | |
| 48 | + | |
| 44 | 49 | |
| 45 | 50 | Test case and Bug Report contributors |
| 46 | 51 | ------------------------------------- |
| @@ -1,10 +1,14 @@ | ||
| 1 | −The CIFS VFS support for Linux supports many advanced network filesystem | |
| 2 | −features such as hierarchical dfs like namespace, hardlinks, locking and more. | |
| 1 | +This module supports the SMB3 family of advanced network protocols (as well | |
| 2 | +as older dialects, originally called "CIFS" or SMB1). | |
| 3 | + | |
| 4 | +The CIFS VFS module for Linux supports many advanced network filesystem | |
| 5 | +features such as hierarchical DFS like namespace, hardlinks, locking and more. | |
| 3 | 6 | It was designed to comply with the SNIA CIFS Technical Reference (which |
| 4 | 7 | supersedes the 1992 X/Open SMB Standard) as well as to perform best practice |
| 5 | 8 | practical interoperability with Windows 2000, Windows XP, Samba and equivalent |
| 6 | 9 | servers. This code was developed in participation with the Protocol Freedom |
| 7 | −Information Foundation. | |
| 10 | +Information Foundation. CIFS and now SMB3 has now become a defacto | |
| 11 | +standard for interoperating between Macs and Windows and major NAS appliances. | |
| 8 | 12 | |
| 9 | 13 | Please see |
| 10 | 14 | http://protocolfreedom.org/ and |
| @@ -15,30 +19,11 @@ for more details. · 4 unmodified lines | ||
| 15 | 19 | For questions or bug reports please contact: |
| 16 | 20 | sfrench@samba.org (sfrench@us.ibm.com) |
| 17 | 21 | |
| 22 | +See the project page at: https://wiki.samba.org/index.php/LinuxCIFS_utils | |
| 23 | + | |
| 18 | 24 | Build instructions: |
| 19 | 25 | ================== |
| 20 | −For Linux 2.4: | |
| 21 | −1) Get the kernel source (e.g.from http://www.kernel.org) | |
| 22 | −and download the cifs vfs source (see the project page | |
| 23 | −at http://us1.samba.org/samba/Linux_CIFS_client.html) | |
| 24 | −and change directory into the top of the kernel directory | |
| 25 | −then patch the kernel (e.g. "patch -p1 < cifs_24.patch") | |
| 26 | −to add the cifs vfs to your kernel configure options if | |
| 27 | −it has not already been added (e.g. current SuSE and UL | |
| 28 | −users do not need to apply the cifs_24.patch since the cifs vfs is | |
| 29 | −already in the kernel configure menu) and then | |
| 30 | −mkdir linux/fs/cifs and then copy the current cifs vfs files from | |
| 31 | −the cifs download to your kernel build directory e.g. | |
| 32 | − | |
| 33 | − cp <cifs_download_dir>/fs/cifs/* to <kernel_download_dir>/fs/cifs | |
| 34 | − | |
| 35 | −2) make menuconfig (or make xconfig) | |
| 36 | −3) select cifs from within the network filesystem choices | |
| 37 | −4) save and exit | |
| 38 | −5) make dep | |
| 39 | −6) make modules (or "make" if CIFS VFS not to be built as a module) | |
| 40 | − | |
| 41 | −For Linux 2.6: | |
| 26 | +For Linux: | |
| 42 | 27 | 1) Download the kernel (e.g. from http://www.kernel.org) |
| 43 | 28 | and change directory into the top of the kernel directory tree |
| 44 | 29 | (e.g. /usr/src/linux-2.5.73) |
| @@ -61,16 +46,13 @@ would simply type "make install"). · 16 unmodified lines | ||
| 61 | 46 | If you do not have the utility mount.cifs (in the Samba 3.0 source tree and on |
| 62 | 47 | the CIFS VFS web site) copy it to the same directory in which mount.smbfs and |
| 63 | 48 | similar files reside (usually /sbin). Although the helper software is not |
| 64 | −required, mount.cifs is recommended. Eventually the Samba 3.0 utility program | |
| 65 | −"net" may also be helpful since it may someday provide easier mount syntax for | |
| 66 | −users who are used to Windows e.g. | |
| 67 | − net use <mount point> <UNC name or cifs URL> | |
| 49 | +required, mount.cifs is recommended. Most distros include a "cifs-utils" | |
| 50 | +package that includes this utility so it is recommended to install this. | |
| 51 | + | |
| 68 | 52 | Note that running the Winbind pam/nss module (logon service) on all of your |
| 69 | 53 | Linux clients is useful in mapping Uids and Gids consistently across the |
| 70 | 54 | domain to the proper network user. The mount.cifs mount helper can be |
| 71 | −trivially built from Samba 3.0 or later source e.g. by executing: | |
| 72 | − | |
| 73 | − gcc samba/source/client/mount.cifs.c -o mount.cifs | |
| 55 | +found at cifs-utils.git on git.samba.org | |
| 74 | 56 | |
| 75 | 57 | If cifs is built as a module, then the size and number of network buffers |
| 76 | 58 | and maximum number of simultaneous requests to one server can be configured. |
| @@ -79,6 +61,18 @@ Changing these from their defaults is not recommended. By executing modinfo · 2 unmodified lines | ||
| 79 | 61 | on kernel/fs/cifs/cifs.ko the list of configuration changes that can be made |
| 80 | 62 | at module initialization time (by running insmod cifs.ko) can be seen. |
| 81 | 63 | |
| 64 | +Recommendations | |
| 65 | +=============== | |
| 66 | +To improve security the SMB2.1 dialect or later (usually will get SMB3) is now | |
| 67 | +the new default. To use old dialects (e.g. to mount Windows XP) use "vers=1.0" | |
| 68 | +on mount (or vers=2.0 for Windows Vista). Note that the CIFS (vers=1.0) is | |
| 69 | +much older and less secure than the default dialect SMB3 which includes | |
| 70 | +many advanced security features such as downgrade attack detection | |
| 71 | +and encrypted shares and stronger signing and authentication algorithms. | |
| 72 | +There are additional mount options that may be helpful for SMB3 to get | |
| 73 | +improved POSIX behavior (NB: can use vers=3.0 to force only SMB3, never 2.1): | |
| 74 | + "mfsymlinks" and "cifsacl" and "idsfromsid" | |
| 75 | + | |
| 82 | 76 | Allowing User Mounts |
| 83 | 77 | ==================== |
| 84 | 78 | To permit users to mount and unmount over directories they own is possible |
| @@ -98,9 +92,7 @@ and execution of suid programs on the remote target would be enabled · 13 unmodified lines | ||
| 98 | 92 | by default. This can be changed, as with nfs and other filesystems, |
| 99 | 93 | by simply specifying "nosuid" among the mount options. For user mounts |
| 100 | 94 | though to be able to pass the suid flag to mount requires rebuilding |
| 101 | −mount.cifs with the following flag: | |
| 102 | − | |
| 103 | − gcc samba/source/client/mount.cifs.c -DCIFS_ALLOW_USR_SUID -o mount.cifs | |
| 95 | +mount.cifs with the following flag: CIFS_ALLOW_USR_SUID | |
| 104 | 96 | |
| 105 | 97 | There is a corresponding manual page for cifs mounting in the Samba 3.0 and |
| 106 | 98 | later source tree in docs/manpages/mount.cifs.8 |
| @@ -189,18 +181,18 @@ applications running on the same server as Samba. · 82 unmodified lines | ||
| 189 | 181 | Use instructions: |
| 190 | 182 | ================ |
| 191 | 183 | Once the CIFS VFS support is built into the kernel or installed as a module |
| 192 | −(cifs.o), you can use mount syntax like the following to access Samba or Windows | |
| 193 | −servers: | |
| 184 | +(cifs.ko), you can use mount syntax like the following to access Samba or | |
| 185 | +Mac or Windows servers: | |
| 194 | 186 | |
| 195 | − mount -t cifs //9.53.216.11/e$ /mnt -o user=myname,pass=mypassword | |
| 187 | + mount -t cifs //9.53.216.11/e$ /mnt -o username=myname,password=mypassword | |
| 196 | 188 | |
| 197 | 189 | Before -o the option -v may be specified to make the mount.cifs |
| 198 | 190 | mount helper display the mount steps more verbosely. |
| 199 | 191 | After -o the following commonly used cifs vfs specific options |
| 200 | 192 | are supported: |
| 201 | 193 | |
| 202 | − user=<username> | |
| 203 | − pass=<password> | |
| 194 | + username=<username> | |
| 195 | + password=<password> | |
| 204 | 196 | domain=<domain name> |
| 205 | 197 | |
| 206 | 198 | Other cifs mount options are described below. Use of TCP names (in addition to |
| @@ -246,13 +238,16 @@ the Server's registry. Samba starting with version 3.10 will allow such · 39 unmodified lines | ||
| 246 | 238 | filenames (ie those which contain valid Linux characters, which normally |
| 247 | 239 | would be forbidden for Windows/CIFS semantics) as long as the server is |
| 248 | 240 | configured for Unix Extensions (and the client has not disabled |
| 249 | −/proc/fs/cifs/LinuxExtensionsEnabled). | |
| 250 | − | |
| 241 | +/proc/fs/cifs/LinuxExtensionsEnabled). In addition the mount option | |
| 242 | +"mapposix" can be used on CIFS (vers=1.0) to force the mapping of | |
| 243 | +illegal Windows/NTFS/SMB characters to a remap range (this mount parm | |
| 244 | +is the default for SMB3). This remap ("mapposix") range is also | |
| 245 | +compatible with Mac (and "Services for Mac" on some older Windows). | |
| 251 | 246 | |
| 252 | 247 | CIFS VFS Mount Options |
| 253 | 248 | ====================== |
| 254 | 249 | A partial list of the supported mount options follows: |
| 255 | − user The user name to use when trying to establish | |
| 250 | + username The user name to use when trying to establish | |
| 256 | 251 | the CIFS session. |
| 257 | 252 | password The user password. If the mount helper is |
| 258 | 253 | installed, the user will be prompted for password |
| @@ -1,4 +1,4 @@ | ||
| 1 | −Version 2.03 August 1, 2014 | |
| 1 | +Version 2.04 September 13, 2017 | |
| 2 | 2 | |
| 3 | 3 | A Partial List of Missing Features |
| 4 | 4 | ================================== |
| @@ -8,73 +8,69 @@ for visible, important contributions to this module. Here · 3 unmodified lines | ||
| 8 | 8 | is a partial list of the known problems and missing features: |
| 9 | 9 | |
| 10 | 10 | a) SMB3 (and SMB3.02) missing optional features: |
| 11 | − - RDMA | |
| 11 | + - RDMA (started) | |
| 12 | 12 | - multichannel (started) |
| 13 | 13 | - directory leases (improved metadata caching) |
| 14 | 14 | - T10 copy offload (copy chunk is only mechanism supported) |
| 15 | − - encrypted shares | |
| 16 | 15 | |
| 17 | 16 | b) improved sparse file support |
| 18 | 17 | |
| 19 | 18 | c) Directory entry caching relies on a 1 second timer, rather than |
| 20 | −using FindNotify or equivalent. - (started) | |
| 19 | +using Directory Leases | |
| 21 | 20 | |
| 22 | 21 | d) quota support (needs minor kernel change since quota calls |
| 23 | 22 | to make it to network filesystems or deviceless filesystems) |
| 24 | 23 | |
| 25 | −e) improve support for very old servers (OS/2 and Win9x for example) | |
| 26 | −Including support for changing the time remotely (utimes command). | |
| 24 | +e) Better optimize open to reduce redundant opens (using reference | |
| 25 | +counts more) and to improve use of compounding in SMB3 to reduce | |
| 26 | +number of roundtrips. | |
| 27 | 27 | |
| 28 | −f) hook lower into the sockets api (as NFS/SunRPC does) to avoid the | |
| 29 | −extra copy in/out of the socket buffers in some cases. | |
| 30 | − | |
| 31 | −g) Better optimize open (and pathbased setfilesize) to reduce the | |
| 32 | −oplock breaks coming from windows srv. Piggyback identical file | |
| 33 | −opens on top of each other by incrementing reference count rather | |
| 34 | −than resending (helps reduce server resource utilization and avoid | |
| 35 | −spurious oplock breaks). | |
| 36 | − | |
| 37 | −h) Add support for storing symlink info to Windows servers | |
| 38 | −in the Extended Attribute format their SFU clients would recognize. | |
| 39 | − | |
| 40 | −i) Finish inotify support so kde and gnome file list windows | |
| 28 | +f) Finish inotify support so kde and gnome file list windows | |
| 41 | 29 | will autorefresh (partially complete by Asser). Needs minor kernel |
| 42 | 30 | vfs change to support removing D_NOTIFY on a file. |
| 43 | 31 | |
| 44 | −j) Add GUI tool to configure /proc/fs/cifs settings and for display of | |
| 32 | +g) Add GUI tool to configure /proc/fs/cifs settings and for display of | |
| 45 | 33 | the CIFS statistics (started) |
| 46 | 34 | |
| 47 | −k) implement support for security and trusted categories of xattrs | |
| 35 | +h) implement support for security and trusted categories of xattrs | |
| 48 | 36 | (requires minor protocol extension) to enable better support for SELINUX |
| 49 | 37 | |
| 50 | −l) Implement O_DIRECT flag on open (already supported on mount) | |
| 38 | +i) Implement O_DIRECT flag on open (already supported on mount) | |
| 51 | 39 | |
| 52 | −m) Create UID mapping facility so server UIDs can be mapped on a per | |
| 40 | +j) Create UID mapping facility so server UIDs can be mapped on a per | |
| 53 | 41 | mount or a per server basis to client UIDs or nobody if no mapping |
| 54 | −exists. This is helpful when Unix extensions are negotiated to | |
| 55 | −allow better permission checking when UIDs differ on the server | |
| 56 | −and client. Add new protocol request to the CIFS protocol | |
| 57 | −standard for asking the server for the corresponding name of a | |
| 58 | −particular uid. | |
| 42 | +exists. Also better integration with winbind for resolving SID owners | |
| 43 | + | |
| 44 | +k) Add tools to take advantage of more smb3 specific ioctls and features | |
| 45 | + | |
| 46 | +l) encrypted file support | |
| 47 | + | |
| 48 | +m) improved stats gathering, tools (perhaps integration with nfsometer?) | |
| 59 | 49 | |
| 60 | −n) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too) | |
| 50 | +n) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed | |
| 51 | +file attribute via chflags) and improve user space tools for managing and | |
| 52 | +viewing them. | |
| 61 | 53 | |
| 62 | −o) mount check for unmatched uids | |
| 54 | +o) mount helper GUI (to simplify the various configuration options on mount) | |
| 63 | 55 | |
| 64 | −p) Add support for new vfs entry point for fallocate | |
| 56 | +p) autonegotiation of dialects (offering more than one dialect ie SMB3.02, | |
| 57 | +SMB3, SMB2.1 not just SMB3). | |
| 65 | 58 | |
| 66 | −q) Add tools to take advantage of cifs/smb3 specific ioctls and features | |
| 67 | −such as "CopyChunk" (fast server side file copy) | |
| 59 | +q) Allow mount.cifs to be more verbose in reporting errors with dialect | |
| 60 | +or unsupported feature errors. | |
| 68 | 61 | |
| 69 | −r) encrypted file support | |
| 62 | +r) updating cifs documentation, and user guid. | |
| 70 | 63 | |
| 71 | −s) improved stats gathering, tools (perhaps integration with nfsometer?) | |
| 64 | +s) Addressing bugs found by running a broader set of xfstests in standard | |
| 65 | +file system xfstest suite. | |
| 72 | 66 | |
| 73 | −t) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed | |
| 74 | −file attribute via chflags) | |
| 67 | +t) split cifs and smb3 support into separate modules so legacy (and less | |
| 68 | +secure) CIFS dialect can be disabled in environments that don't need it | |
| 69 | +and simplify the code. | |
| 75 | 70 | |
| 76 | −u) mount helper GUI (to simplify the various configuration options on mount) | |
| 71 | +u) Finish up SMB3.1.1 dialect support | |
| 77 | 72 | |
| 73 | +v) POSIX Extensions for SMB3.1.1 | |
| 78 | 74 | |
| 79 | 75 | KNOWN BUGS |
| 80 | 76 | ==================================== |
| @@ -1,24 +1,28 @@ | ||
| 1 | − This is the client VFS module for the Common Internet File System | |
| 2 | − (CIFS) protocol which is the successor to the Server Message Block | |
| 1 | + This is the client VFS module for the SMB3 NAS protocol as well | |
| 2 | + older dialects such as the Common Internet File System (CIFS) | |
| 3 | + protocol which was the successor to the Server Message Block | |
| 3 | 4 | (SMB) protocol, the native file sharing mechanism for most early |
| 4 | 5 | PC operating systems. New and improved versions of CIFS are now |
| 5 | 6 | called SMB2 and SMB3. These dialects are also supported by the |
| 6 | 7 | CIFS VFS module. CIFS is fully supported by network |
| 7 | − file servers such as Windows 2000, 2003, 2008 and 2012 | |
| 8 | + file servers such as Windows 2000, 2003, 2008, 2012 and 2016 | |
| 8 | 9 | as well by Samba (which provides excellent CIFS |
| 9 | − server support for Linux and many other operating systems), so | |
| 10 | + server support for Linux and many other operating systems), Apple | |
| 11 | + systems, as well as most Network Attached Storage vendors, so | |
| 10 | 12 | this network filesystem client can mount to a wide variety of |
| 11 | 13 | servers. |
| 12 | 14 | |
| 13 | 15 | The intent of this module is to provide the most advanced network |
| 14 | − file system function for CIFS compliant servers, including better | |
| 15 | − POSIX compliance, secure per-user session establishment, high | |
| 16 | − performance safe distributed caching (oplock), optional packet | |
| 16 | + file system function for SMB3 compliant servers, including advanced | |
| 17 | + security features, excellent parallelized high performance i/o, better | |
| 18 | + POSIX compliance, secure per-user session establishment, encryption, | |
| 19 | + high performance safe distributed caching (leases/oplocks), optional packet | |
| 17 | 20 | signing, large files, Unicode support and other internationalization |
| 18 | 21 | improvements. Since both Samba server and this filesystem client support |
| 19 | − the CIFS Unix extensions, the combination can provide a reasonable | |
| 20 | − alternative to NFSv4 for fileserving in some Linux to Linux environments, | |
| 21 | − not just in Linux to Windows environments. | |
| 22 | + the CIFS Unix extensions (and in the future SMB3 POSIX extensions), | |
| 23 | + the combination can provide a reasonable alternative to other network and | |
| 24 | + cluster file systems for fileserving in some Linux to Linux environments, | |
| 25 | + not just in Linux to Windows (or Linux to Mac) environments. | |
| 22 | 26 | |
| 23 | 27 | This filesystem has an mount utility (mount.cifs) that can be obtained from |
| 24 | 28 | |
| @@ -210,8 +210,11 @@ path as another overlay mount and it may use a lower layer path that is · 209 unmodified lines | ||
| 210 | 210 | beneath or above the path of another overlay lower layer path. |
| 211 | 211 | |
| 212 | 212 | Using an upper layer path and/or a workdir path that are already used by |
| 213 | −another overlay mount is not allowed and will fail with EBUSY. Using | |
| 213 | +another overlay mount is not allowed and may fail with EBUSY. Using | |
| 214 | 214 | partially overlapping paths is not allowed but will not fail with EBUSY. |
| 215 | +If files are accessed from two overlayfs mounts which share or overlap the | |
| 216 | +upper layer and/or workdir path the behavior of the overlay is undefined, | |
| 217 | +though it will not result in a crash or deadlock. | |
| 215 | 218 | |
| 216 | 219 | Mounting an overlay using an upper layer path, where the upper layer path |
| 217 | 220 | was previously used by another mounted overlay in combination with a |
| @@ -366,7 +366,8 @@ struct driver_attribute { · 365 unmodified lines | ||
| 366 | 366 | |
| 367 | 367 | Declaring: |
| 368 | 368 | |
| 369 | −DRIVER_ATTR(_name, _mode, _show, _store) | |
| 369 | +DRIVER_ATTR_RO(_name) | |
| 370 | +DRIVER_ATTR_RW(_name) | |
| 370 | 371 | |
| 371 | 372 | Creation/Removal: |
| 372 | 373 | |
| @@ -36,6 +36,7 @@ Supported adapters: · 35 unmodified lines | ||
| 36 | 36 | * Intel Gemini Lake (SOC) |
| 37 | 37 | * Intel Cannon Lake-H (PCH) |
| 38 | 38 | * Intel Cannon Lake-LP (PCH) |
| 39 | + * Intel Cedar Fork (PCH) | |
| 39 | 40 | Datasheets: Publicly available at the Intel website |
| 40 | 41 | |
| 41 | 42 | On Intel Patsburg and later chipsets, both the normal host SMBus controller |
| @@ -337,7 +337,7 @@ Examples for low-level BPF: · 336 unmodified lines | ||
| 337 | 337 | jeq #14, good /* __NR_rt_sigprocmask */ |
| 338 | 338 | jeq #13, good /* __NR_rt_sigaction */ |
| 339 | 339 | jeq #35, good /* __NR_nanosleep */ |
| 340 | − bad: ret #0 /* SECCOMP_RET_KILL */ | |
| 340 | + bad: ret #0 /* SECCOMP_RET_KILL_THREAD */ | |
| 341 | 341 | good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */ |
| 342 | 342 | |
| 343 | 343 | The above example code can be placed into a file (here called "foo"), and |
| @@ -1680,6 +1680,9 @@ accept_dad - INTEGER · 1679 unmodified lines | ||
| 1680 | 1680 | 2: Enable DAD, and disable IPv6 operation if MAC-based duplicate |
| 1681 | 1681 | link-local address has been found. |
| 1682 | 1682 | |
| 1683 | + DAD operation and mode on a given interface will be selected according | |
| 1684 | + to the maximum value of conf/{all,interface}/accept_dad. | |
| 1685 | + | |
| 1683 | 1686 | force_tllao - BOOLEAN |
| 1684 | 1687 | Enable sending the target link-layer address option even when |
| 1685 | 1688 | responding to a unicast neighbor solicitation. |
| @@ -1727,16 +1730,23 @@ suppress_frag_ndisc - INTEGER · 41 unmodified lines | ||
| 1727 | 1730 | |
| 1728 | 1731 | optimistic_dad - BOOLEAN |
| 1729 | 1732 | Whether to perform Optimistic Duplicate Address Detection (RFC 4429). |
| 1730 | − 0: disabled (default) | |
| 1731 | − 1: enabled | |
| 1733 | + 0: disabled (default) | |
| 1734 | + 1: enabled | |
| 1735 | + | |
| 1736 | + Optimistic Duplicate Address Detection for the interface will be enabled | |
| 1737 | + if at least one of conf/{all,interface}/optimistic_dad is set to 1, | |
| 1738 | + it will be disabled otherwise. | |
| 1732 | 1739 | |
| 1733 | 1740 | use_optimistic - BOOLEAN |
| 1734 | 1741 | If enabled, do not classify optimistic addresses as deprecated during |
| 1735 | 1742 | source address selection. Preferred addresses will still be chosen |
| 1736 | 1743 | before optimistic addresses, subject to other ranking in the source |
| 1737 | 1744 | address selection algorithm. |
| 1738 | − 0: disabled (default) | |
| 1739 | − 1: enabled | |
| 1745 | + 0: disabled (default) | |
| 1746 | + 1: enabled | |
| 1747 | + | |
| 1748 | + This will be enabled if at least one of | |
| 1749 | + conf/{all,interface}/use_optimistic is set to 1, disabled otherwise. | |
| 1740 | 1750 | |
| 1741 | 1751 | stable_secret - IPv6 address |
| 1742 | 1752 | This IPv6 address will be used as a secret to generate IPv6 |
| @@ -13,42 +13,42 @@ an example setup using a data-center-class switch ASIC chip. Other setups · 12 unmodified lines | ||
| 13 | 13 | with SR-IOV or soft switches, such as OVS, are possible. |
| 14 | 14 | |
| 15 | 15 | |
| 16 | − User-space tools | |
| 17 | − | |
| 18 | − user space | | |
| 19 | − +-------------------------------------------------------------------+ | |
| 20 | − kernel | Netlink | |
| 21 | − | | |
| 22 | − +--------------+-------------------------------+ | |
| 23 | − | Network stack | | |
| 24 | − | (Linux) | | |
| 25 | − | | | |
| 26 | − +----------------------------------------------+ | |
| 16 | + User-space tools | |
| 17 | + | |
| 18 | + user space | | |
| 19 | + +-------------------------------------------------------------------+ | |
| 20 | + kernel | Netlink | |
| 21 | + | | |
| 22 | + +--------------+-------------------------------+ | |
| 23 | + | Network stack | | |
| 24 | + | (Linux) | | |
| 25 | + | | | |
| 26 | + +----------------------------------------------+ | |
| 27 | 27 | |
| 28 | 28 | sw1p2 sw1p4 sw1p6 |
| 29 | − sw1p1 + sw1p3 + sw1p5 + eth1 | |
| 30 | − + | + | + | + | |
| 31 | − | | | | | | | | |
| 32 | − +--+----+----+----+-+--+----+---+ +-----+-----+ | |
| 33 | − | Switch driver | | mgmt | | |
| 34 | − | (this document) | | driver | | |
| 35 | − | | | | | |
| 36 | − +--------------+----------------+ +-----------+ | |
| 37 | − | | |
| 38 | − kernel | HW bus (eg PCI) | |
| 39 | − +-------------------------------------------------------------------+ | |
| 40 | − hardware | | |
| 41 | − +--------------+---+------------+ | |
| 42 | − | Switch device (sw1) | | |
| 43 | − | +----+ +--------+ | |
| 44 | − | | v offloaded data path | mgmt port | |
| 45 | − | | | | | |
| 46 | − +--|----|----+----+----+----+---+ | |
| 47 | − | | | | | | | |
| 48 | − + + + + + + | |
| 49 | − p1 p2 p3 p4 p5 p6 | |
| 50 | − | |
| 51 | − front-panel ports | |
| 29 | + sw1p1 + sw1p3 + sw1p5 + eth1 | |
| 30 | + + | + | + | + | |
| 31 | + | | | | | | | | |
| 32 | + +--+----+----+----+----+----+---+ +-----+-----+ | |
| 33 | + | Switch driver | | mgmt | | |
| 34 | + | (this document) | | driver | | |
| 35 | + | | | | | |
| 36 | + +--------------+----------------+ +-----------+ | |
| 37 | + | | |
| 38 | + kernel | HW bus (eg PCI) | |
| 39 | + +-------------------------------------------------------------------+ | |
| 40 | + hardware | | |
| 41 | + +--------------+----------------+ | |
| 42 | + | Switch device (sw1) | | |
| 43 | + | +----+ +--------+ | |
| 44 | + | | v offloaded data path | mgmt port | |
| 45 | + | | | | | |
| 46 | + +--|----|----+----+----+----+---+ | |
| 47 | + | | | | | | | |
| 48 | + + + + + + + | |
| 49 | + p1 p2 p3 p4 p5 p6 | |
| 50 | + | |
| 51 | + front-panel ports | |
| 52 | 52 | |
| 53 | 53 | |
| 54 | 54 | Fig 1. |
| @@ -75,6 +75,7 @@ show up in /proc/sys/kernel: · 74 unmodified lines | ||
| 75 | 75 | - reboot-cmd [ SPARC only ] |
| 76 | 76 | - rtsig-max |
| 77 | 77 | - rtsig-nr |
| 78 | +- seccomp/ ==> Documentation/userspace-api/seccomp_filter.rst | |
| 78 | 79 | - sem |
| 79 | 80 | - sem_next_id [ sysv ipc ] |
| 80 | 81 | - sg-big-buff [ generic SCSI device (sg) ] |
| @@ -87,11 +87,16 @@ Return values · 86 unmodified lines | ||
| 87 | 87 | A seccomp filter may return any of the following values. If multiple |
| 88 | 88 | filters exist, the return value for the evaluation of a given system |
| 89 | 89 | call will always use the highest precedent value. (For example, |
| 90 | −``SECCOMP_RET_KILL`` will always take precedence.) | |
| 90 | +``SECCOMP_RET_KILL_PROCESS`` will always take precedence.) | |
| 91 | 91 | |
| 92 | 92 | In precedence order, they are: |
| 93 | 93 | |
| 94 | −``SECCOMP_RET_KILL``: | |
| 94 | +``SECCOMP_RET_KILL_PROCESS``: | |
| 95 | + Results in the entire process exiting immediately without executing | |
| 96 | + the system call. The exit status of the task (``status & 0x7f``) | |
| 97 | + will be ``SIGSYS``, not ``SIGKILL``. | |
| 98 | + | |
| 99 | +``SECCOMP_RET_KILL_THREAD``: | |
| 95 | 100 | Results in the task exiting immediately without executing the |
| 96 | 101 | system call. The exit status of the task (``status & 0x7f``) will |
| 97 | 102 | be ``SIGSYS``, not ``SIGKILL``. |
| @@ -141,6 +146,15 @@ In precedence order, they are: · 43 unmodified lines | ||
| 141 | 146 | allow use of ptrace, even of other sandboxed processes, without |
| 142 | 147 | extreme care; ptracers can use this mechanism to escape.) |
| 143 | 148 | |
| 149 | +``SECCOMP_RET_LOG``: | |
| 150 | + Results in the system call being executed after it is logged. This | |
| 151 | + should be used by application developers to learn which syscalls their | |
| 152 | + application needs without having to iterate through multiple test and | |
| 153 | + development cycles to build the list. | |
| 154 | + | |
| 155 | + This action will only be logged if "log" is present in the | |
| 156 | + actions_logged sysctl string. | |
| 157 | + | |
| 144 | 158 | ``SECCOMP_RET_ALLOW``: |
| 145 | 159 | Results in the system call being executed. |
| 146 | 160 | |
| @@ -169,7 +183,41 @@ The ``samples/seccomp/`` directory contains both an x86-specific example · 22 unmodified lines | ||
| 169 | 183 | and a more generic example of a higher level macro interface for BPF |
| 170 | 184 | program generation. |
| 171 | 185 | |
| 186 | +Sysctls | |
| 187 | +======= | |
| 172 | 188 | |
| 189 | +Seccomp's sysctl files can be found in the ``/proc/sys/kernel/seccomp/`` | |
| 190 | +directory. Here's a description of each file in that directory: | |
| 191 | + | |
| 192 | +``actions_avail``: | |
| 193 | + A read-only ordered list of seccomp return values (refer to the | |
| 194 | + ``SECCOMP_RET_*`` macros above) in string form. The ordering, from | |
| 195 | + left-to-right, is the least permissive return value to the most | |
| 196 | + permissive return value. | |
| 197 | + | |
| 198 | + The list represents the set of seccomp return values supported | |
| 199 | + by the kernel. A userspace program may use this list to | |
| 200 | + determine if the actions found in the ``seccomp.h``, when the | |
| 201 | + program was built, differs from the set of actions actually | |
| 202 | + supported in the current running kernel. | |
| 203 | + | |
| 204 | +``actions_logged``: | |
| 205 | + A read-write ordered list of seccomp return values (refer to the | |
| 206 | + ``SECCOMP_RET_*`` macros above) that are allowed to be logged. Writes | |
| 207 | + to the file do not need to be in ordered form but reads from the file | |
| 208 | + will be ordered in the same way as the actions_avail sysctl. | |
| 209 | + | |
| 210 | + It is important to note that the value of ``actions_logged`` does not | |
| 211 | + prevent certain actions from being logged when the audit subsystem is | |
| 212 | + configured to audit a task. If the action is not found in | |
| 213 | + ``actions_logged`` list, the final decision on whether to audit the | |
| 214 | + action for that task is ultimately left up to the audit subsystem to | |
| 215 | + decide for all seccomp return values other than ``SECCOMP_RET_ALLOW``. | |
| 216 | + | |
| 217 | + The ``allow`` string is not accepted in the ``actions_logged`` sysctl | |
| 218 | + as it is not possible to log ``SECCOMP_RET_ALLOW`` actions. Attempting | |
| 219 | + to write ``allow`` to the sysctl will result in an EINVAL being | |
| 220 | + returned. | |
| 173 | 221 | |
| 174 | 222 | Adding architecture support |
| 175 | 223 | =========================== |
| @@ -352,6 +352,18 @@ L: linux-acpi@vger.kernel.org · 351 unmodified lines | ||
| 352 | 352 | S: Maintained |
| 353 | 353 | F: drivers/acpi/arm64 |
| 354 | 354 | |
| 355 | +ACPI PMIC DRIVERS | |
| 356 | +M: "Rafael J. Wysocki" <rjw@rjwysocki.net> | |
| 357 | +M: Len Brown <lenb@kernel.org> | |
| 358 | +R: Andy Shevchenko <andy@infradead.org> | |
| 359 | +R: Mika Westerberg <mika.westerberg@linux.intel.com> | |
| 360 | +L: linux-acpi@vger.kernel.org | |
| 361 | +Q: https://patchwork.kernel.org/project/linux-acpi/list/ | |
| 362 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm | |
| 363 | +B: https://bugzilla.kernel.org | |
| 364 | +S: Supported | |
| 365 | +F: drivers/acpi/pmic/ | |
| 366 | + | |
| 355 | 367 | ACPI THERMAL DRIVER |
| 356 | 368 | M: Zhang Rui <rui.zhang@intel.com> |
| 357 | 369 | L: linux-acpi@vger.kernel.org |
| @@ -2853,7 +2865,6 @@ S: Supported · 2495 unmodified lines | ||
| 2853 | 2865 | F: drivers/scsi/bnx2i/ |
| 2854 | 2866 | |
| 2855 | 2867 | BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER |
| 2856 | −M: Yuval Mintz <Yuval.Mintz@cavium.com> | |
| 2857 | 2868 | M: Ariel Elior <ariel.elior@cavium.com> |
| 2858 | 2869 | M: everest-linux-l2@cavium.com |
| 2859 | 2870 | L: netdev@vger.kernel.org |
| @@ -5248,7 +5259,8 @@ S: Maintained · 2388 unmodified lines | ||
| 5248 | 5259 | F: drivers/iommu/exynos-iommu.c |
| 5249 | 5260 | |
| 5250 | 5261 | EZchip NPS platform support |
| 5251 | −M: Noam Camus <noamc@ezchip.com> | |
| 5262 | +M: Elad Kanfi <eladkan@mellanox.com> | |
| 5263 | +M: Vineet Gupta <vgupta@synopsys.com> | |
| 5252 | 5264 | S: Supported |
| 5253 | 5265 | F: arch/arc/plat-eznps |
| 5254 | 5266 | F: arch/arc/boot/dts/eznps.dts |
| @@ -6643,8 +6655,8 @@ M: Alexander Aring <alex.aring@gmail.com> · 1388 unmodified lines | ||
| 6643 | 6655 | M: Stefan Schmidt <stefan@osg.samsung.com> |
| 6644 | 6656 | L: linux-wpan@vger.kernel.org |
| 6645 | 6657 | W: http://wpan.cakelab.org/ |
| 6646 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git | |
| 6647 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git | |
| 6658 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan.git | |
| 6659 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next.git | |
| 6648 | 6660 | S: Maintained |
| 6649 | 6661 | F: net/ieee802154/ |
| 6650 | 6662 | F: net/mac802154/ |
| @@ -6727,7 +6739,7 @@ F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt · 76 unmodified lines | ||
| 6727 | 6739 | F: drivers/auxdisplay/img-ascii-lcd.c |
| 6728 | 6740 | |
| 6729 | 6741 | IMGTEC IR DECODER DRIVER |
| 6730 | −M: James Hogan <james.hogan@imgtec.com> | |
| 6742 | +M: James Hogan <jhogan@kernel.org> | |
| 6731 | 6743 | S: Maintained |
| 6732 | 6744 | F: drivers/media/rc/img-ir/ |
| 6733 | 6745 | |
| @@ -7551,7 +7563,7 @@ F: arch/arm64/include/asm/kvm* · 817 unmodified lines | ||
| 7551 | 7563 | F: arch/arm64/kvm/ |
| 7552 | 7564 | |
| 7553 | 7565 | KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips) |
| 7554 | −M: James Hogan <james.hogan@imgtec.com> | |
| 7566 | +M: James Hogan <jhogan@kernel.org> | |
| 7555 | 7567 | L: linux-mips@linux-mips.org |
| 7556 | 7568 | S: Supported |
| 7557 | 7569 | F: arch/mips/include/uapi/asm/kvm* |
| @@ -8253,6 +8265,12 @@ L: libertas-dev@lists.infradead.org · 695 unmodified lines | ||
| 8253 | 8265 | S: Orphan |
| 8254 | 8266 | F: drivers/net/wireless/marvell/libertas/ |
| 8255 | 8267 | |
| 8268 | +MARVELL MACCHIATOBIN SUPPORT | |
| 8269 | +M: Russell King <rmk@armlinux.org.uk> | |
| 8270 | +L: linux-arm-kernel@lists.infradead.org | |
| 8271 | +S: Maintained | |
| 8272 | +F: arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts | |
| 8273 | + | |
| 8256 | 8274 | MARVELL MV643XX ETHERNET DRIVER |
| 8257 | 8275 | M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> |
| 8258 | 8276 | L: netdev@vger.kernel.org |
| @@ -8586,6 +8604,12 @@ M: Sean Wang <sean.wang@mediatek.com> · 327 unmodified lines | ||
| 8586 | 8604 | S: Maintained |
| 8587 | 8605 | F: drivers/media/rc/mtk-cir.c |
| 8588 | 8606 | |
| 8607 | +MEDIATEK PMIC LED DRIVER | |
| 8608 | +M: Sean Wang <sean.wang@mediatek.com> | |
| 8609 | +S: Maintained | |
| 8610 | +F: drivers/leds/leds-mt6323.c | |
| 8611 | +F: Documentation/devicetree/bindings/leds/leds-mt6323.txt | |
| 8612 | + | |
| 8589 | 8613 | MEDIATEK ETHERNET DRIVER |
| 8590 | 8614 | M: Felix Fietkau <nbd@openwrt.org> |
| 8591 | 8615 | M: John Crispin <john@phrozen.org> |
| @@ -8868,7 +8892,7 @@ F: Documentation/devicetree/bindings/media/meson-ao-cec.txt · 276 unmodified lines | ||
| 8868 | 8892 | T: git git://linuxtv.org/media_tree.git |
| 8869 | 8893 | |
| 8870 | 8894 | METAG ARCHITECTURE |
| 8871 | −M: James Hogan <james.hogan@imgtec.com> | |
| 8895 | +M: James Hogan <jhogan@kernel.org> | |
| 8872 | 8896 | L: linux-metag@vger.kernel.org |
| 8873 | 8897 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git |
| 8874 | 8898 | S: Odd Fixes |
| @@ -9337,7 +9361,7 @@ NETWORK BLOCK DEVICE (NBD) · 462 unmodified lines | ||
| 9337 | 9361 | M: Josef Bacik <jbacik@fb.com> |
| 9338 | 9362 | S: Maintained |
| 9339 | 9363 | L: linux-block@vger.kernel.org |
| 9340 | −L: nbd-general@lists.sourceforge.net | |
| 9364 | +L: nbd@other.debian.org | |
| 9341 | 9365 | F: Documentation/blockdev/nbd.txt |
| 9342 | 9366 | F: drivers/block/nbd.c |
| 9343 | 9367 | F: include/uapi/linux/nbd.h |
| @@ -11047,7 +11071,6 @@ S: Supported · 1703 unmodified lines | ||
| 11047 | 11071 | F: drivers/scsi/qedi/ |
| 11048 | 11072 | |
| 11049 | 11073 | QLOGIC QL4xxx ETHERNET DRIVER |
| 11050 | −M: Yuval Mintz <Yuval.Mintz@cavium.com> | |
| 11051 | 11074 | M: Ariel Elior <Ariel.Elior@cavium.com> |
| 11052 | 11075 | M: everest-linux-l2@cavium.com |
| 11053 | 11076 | L: netdev@vger.kernel.org |
| @@ -12915,9 +12938,9 @@ F: drivers/mmc/host/dw_mmc* · 1861 unmodified lines | ||
| 12915 | 12938 | SYNOPSYS HSDK RESET CONTROLLER DRIVER |
| 12916 | 12939 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
| 12917 | 12940 | S: Supported |
| 12918 | −F: drivers/reset/reset-hsdk-v1.c | |
| 12919 | −F: include/dt-bindings/reset/snps,hsdk-v1-reset.h | |
| 12920 | −F: Documentation/devicetree/bindings/reset/snps,hsdk-v1-reset.txt | |
| 12941 | +F: drivers/reset/reset-hsdk.c | |
| 12942 | +F: include/dt-bindings/reset/snps,hsdk-reset.h | |
| 12943 | +F: Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt | |
| 12921 | 12944 | |
| 12922 | 12945 | SYSTEM CONFIGURATION (SYSCON) |
| 12923 | 12946 | M: Lee Jones <lee.jones@linaro.org> |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 4 |
| 2 | 2 | PATCHLEVEL = 14 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc1 | |
| 4 | +EXTRAVERSION = -rc4 | |
| 5 | 5 | NAME = Fearless Coyote |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -1172,11 +1172,11 @@ headers_check: headers_install · 1164 unmodified lines | ||
| 1172 | 1172 | |
| 1173 | 1173 | PHONY += kselftest |
| 1174 | 1174 | kselftest: |
| 1175 | − $(Q)$(MAKE) -C tools/testing/selftests run_tests | |
| 1175 | + $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests run_tests | |
| 1176 | 1176 | |
| 1177 | 1177 | PHONY += kselftest-clean |
| 1178 | 1178 | kselftest-clean: |
| 1179 | − $(Q)$(MAKE) -C tools/testing/selftests clean | |
| 1179 | + $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests clean | |
| 1180 | 1180 | |
| 1181 | 1181 | PHONY += kselftest-merge |
| 1182 | 1182 | kselftest-merge: |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | 10 | #include <linux/mm_types.h> |
| 11 | +#include <linux/sched.h> | |
| 11 | 12 | |
| 12 | 13 | #include <asm/machvec.h> |
| 13 | 14 | #include <asm/compiler.h> |
| @@ -24,7 +24,7 @@ config ARC · 23 unmodified lines | ||
| 24 | 24 | select GENERIC_SMP_IDLE_THREAD |
| 25 | 25 | select HAVE_ARCH_KGDB |
| 26 | 26 | select HAVE_ARCH_TRACEHOOK |
| 27 | − select HAVE_FUTEX_CMPXCHG | |
| 27 | + select HAVE_FUTEX_CMPXCHG if FUTEX | |
| 28 | 28 | select HAVE_IOREMAP_PROT |
| 29 | 29 | select HAVE_KPROBES |
| 30 | 30 | select HAVE_KRETPROBES |
| @@ -6,8 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | # published by the Free Software Foundation. |
| 7 | 7 | # |
| 8 | 8 | |
| 9 | −UTS_MACHINE := arc | |
| 10 | − | |
| 11 | 9 | ifeq ($(CROSS_COMPILE),) |
| 12 | 10 | ifndef CONFIG_CPU_BIG_ENDIAN |
| 13 | 11 | CROSS_COMPILE := arc-linux- |
| @@ -44,7 +44,14 @@ · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | mmcclk: mmcclk { |
| 46 | 46 | compatible = "fixed-clock"; |
| 47 | − clock-frequency = <50000000>; | |
| 47 | + /* | |
| 48 | + * DW sdio controller has external ciu clock divider | |
| 49 | + * controlled via register in SDIO IP. It divides | |
| 50 | + * sdio_ref_clk (which comes from CGU) by 16 for | |
| 51 | + * default. So default mmcclk clock (which comes | |
| 52 | + * to sdk_in) is 25000000 Hz. | |
| 53 | + */ | |
| 54 | + clock-frequency = <25000000>; | |
| 48 | 55 | #clock-cells = <0>; |
| 49 | 56 | }; |
| 50 | 57 | |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | /dts-v1/; |
| 13 | 13 | |
| 14 | 14 | #include <dt-bindings/net/ti-dp83867.h> |
| 15 | +#include <dt-bindings/reset/snps,hsdk-reset.h> | |
| 15 | 16 | |
| 16 | 17 | / { |
| 17 | 18 | model = "snps,hsdk"; |
| @@ -57,10 +58,10 @@ · 39 unmodified lines | ||
| 57 | 58 | }; |
| 58 | 59 | }; |
| 59 | 60 | |
| 60 | − core_clk: core-clk { | |
| 61 | + input_clk: input-clk { | |
| 61 | 62 | #clock-cells = <0>; |
| 62 | 63 | compatible = "fixed-clock"; |
| 63 | − clock-frequency = <500000000>; | |
| 64 | + clock-frequency = <33333333>; | |
| 64 | 65 | }; |
| 65 | 66 | |
| 66 | 67 | cpu_intc: cpu-interrupt-controller { |
| @@ -102,6 +103,19 @@ · 35 unmodified lines | ||
| 102 | 103 | |
| 103 | 104 | ranges = <0x00000000 0xf0000000 0x10000000>; |
| 104 | 105 | |
| 106 | + cgu_rst: reset-controller@8a0 { | |
| 107 | + compatible = "snps,hsdk-reset"; | |
| 108 | + #reset-cells = <1>; | |
| 109 | + reg = <0x8A0 0x4>, <0xFF0 0x4>; | |
| 110 | + }; | |
| 111 | + | |
| 112 | + core_clk: core-clk@0 { | |
| 113 | + compatible = "snps,hsdk-core-pll-clock"; | |
| 114 | + reg = <0x00 0x10>, <0x14B8 0x4>; | |
| 115 | + #clock-cells = <0>; | |
| 116 | + clocks = <&input_clk>; | |
| 117 | + }; | |
| 118 | + | |
| 105 | 119 | serial: serial@5000 { |
| 106 | 120 | compatible = "snps,dw-apb-uart"; |
| 107 | 121 | reg = <0x5000 0x100>; |
| @@ -120,7 +134,17 @@ · 12 unmodified lines | ||
| 120 | 134 | |
| 121 | 135 | mmcclk_ciu: mmcclk-ciu { |
| 122 | 136 | compatible = "fixed-clock"; |
| 123 | − clock-frequency = <100000000>; | |
| 137 | + /* | |
| 138 | + * DW sdio controller has external ciu clock divider | |
| 139 | + * controlled via register in SDIO IP. Due to its | |
| 140 | + * unexpected default value (it should devide by 1 | |
| 141 | + * but it devides by 8) SDIO IP uses wrong clock and | |
| 142 | + * works unstable (see STAR 9001204800) | |
| 143 | + * So add temporary fix and change clock frequency | |
| 144 | + * from 100000000 to 12500000 Hz until we fix dw sdio | |
| 145 | + * driver itself. | |
| 146 | + */ | |
| 147 | + clock-frequency = <12500000>; | |
| 124 | 148 | #clock-cells = <0>; |
| 125 | 149 | }; |
| 126 | 150 | |
| @@ -141,6 +165,8 @@ · 14 unmodified lines | ||
| 141 | 165 | clocks = <&gmacclk>; |
| 142 | 166 | clock-names = "stmmaceth"; |
| 143 | 167 | phy-handle = <&phy0>; |
| 168 | + resets = <&cgu_rst HSDK_ETH_RESET>; | |
| 169 | + reset-names = "stmmaceth"; | |
| 144 | 170 | |
| 145 | 171 | mdio { |
| 146 | 172 | #address-cells = <1>; |
| @@ -105,7 +105,7 @@ CONFIG_NLS_ISO8859_1=y · 104 unmodified lines | ||
| 105 | 105 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
| 106 | 106 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 107 | 107 | CONFIG_STRIP_ASM_SYMS=y |
| 108 | −CONFIG_LOCKUP_DETECTOR=y | |
| 108 | +CONFIG_SOFTLOCKUP_DETECTOR=y | |
| 109 | 109 | CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 |
| 110 | 110 | # CONFIG_SCHED_DEBUG is not set |
| 111 | 111 | # CONFIG_DEBUG_PREEMPT is not set |
| @@ -104,7 +104,7 @@ CONFIG_NLS_ISO8859_1=y · 103 unmodified lines | ||
| 104 | 104 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
| 105 | 105 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 106 | 106 | CONFIG_STRIP_ASM_SYMS=y |
| 107 | −CONFIG_LOCKUP_DETECTOR=y | |
| 107 | +CONFIG_SOFTLOCKUP_DETECTOR=y | |
| 108 | 108 | CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 |
| 109 | 109 | # CONFIG_SCHED_DEBUG is not set |
| 110 | 110 | # CONFIG_DEBUG_PREEMPT is not set |
| @@ -107,7 +107,7 @@ CONFIG_NLS_ISO8859_1=y · 106 unmodified lines | ||
| 107 | 107 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
| 108 | 108 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 109 | 109 | CONFIG_STRIP_ASM_SYMS=y |
| 110 | −CONFIG_LOCKUP_DETECTOR=y | |
| 110 | +CONFIG_SOFTLOCKUP_DETECTOR=y | |
| 111 | 111 | CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 |
| 112 | 112 | # CONFIG_SCHED_DEBUG is not set |
| 113 | 113 | # CONFIG_DEBUG_PREEMPT is not set |
| @@ -84,5 +84,5 @@ CONFIG_TMPFS=y · 83 unmodified lines | ||
| 84 | 84 | CONFIG_NFS_FS=y |
| 85 | 85 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
| 86 | 86 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 87 | −CONFIG_LOCKUP_DETECTOR=y | |
| 87 | +CONFIG_SOFTLOCKUP_DETECTOR=y | |
| 88 | 88 | # CONFIG_DEBUG_PREEMPT is not set |
| @@ -63,6 +63,7 @@ CONFIG_MMC_SDHCI=y · 62 unmodified lines | ||
| 63 | 63 | CONFIG_MMC_SDHCI_PLTFM=y |
| 64 | 64 | CONFIG_MMC_DW=y |
| 65 | 65 | # CONFIG_IOMMU_SUPPORT is not set |
| 66 | +CONFIG_RESET_HSDK=y | |
| 66 | 67 | CONFIG_EXT3_FS=y |
| 67 | 68 | CONFIG_VFAT_FS=y |
| 68 | 69 | CONFIG_TMPFS=y |
| @@ -72,7 +73,7 @@ CONFIG_NLS_ISO8859_1=y · 3 unmodified lines | ||
| 72 | 73 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
| 73 | 74 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 74 | 75 | CONFIG_STRIP_ASM_SYMS=y |
| 75 | −CONFIG_LOCKUP_DETECTOR=y | |
| 76 | +CONFIG_SOFTLOCKUP_DETECTOR=y | |
| 76 | 77 | CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 |
| 77 | 78 | # CONFIG_SCHED_DEBUG is not set |
| 78 | 79 | # CONFIG_DEBUG_PREEMPT is not set |
| @@ -94,7 +94,7 @@ CONFIG_NLS_ISO8859_1=y · 93 unmodified lines | ||
| 94 | 94 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 95 | 95 | CONFIG_STRIP_ASM_SYMS=y |
| 96 | 96 | CONFIG_DEBUG_SHIRQ=y |
| 97 | −CONFIG_LOCKUP_DETECTOR=y | |
| 97 | +CONFIG_SOFTLOCKUP_DETECTOR=y | |
| 98 | 98 | CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 |
| 99 | 99 | # CONFIG_SCHED_DEBUG is not set |
| 100 | 100 | # CONFIG_DEBUG_PREEMPT is not set |
| @@ -98,7 +98,7 @@ CONFIG_NLS_ISO8859_1=y · 97 unmodified lines | ||
| 98 | 98 | # CONFIG_ENABLE_MUST_CHECK is not set |
| 99 | 99 | CONFIG_STRIP_ASM_SYMS=y |
| 100 | 100 | CONFIG_DEBUG_SHIRQ=y |
| 101 | −CONFIG_LOCKUP_DETECTOR=y | |
| 101 | +CONFIG_SOFTLOCKUP_DETECTOR=y | |
| 102 | 102 | CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 |
| 103 | 103 | # CONFIG_SCHED_DEBUG is not set |
| 104 | 104 | # CONFIG_DEBUG_PREEMPT is not set |
| @@ -98,6 +98,7 @@ · 97 unmodified lines | ||
| 98 | 98 | |
| 99 | 99 | /* Auxiliary registers */ |
| 100 | 100 | #define AUX_IDENTITY 4 |
| 101 | +#define AUX_EXEC_CTRL 8 | |
| 101 | 102 | #define AUX_INTR_VEC_BASE 0x25 |
| 102 | 103 | #define AUX_VOL 0x5e |
| 103 | 104 | |
| @@ -135,12 +136,12 @@ struct bcr_identity { · 31 unmodified lines | ||
| 135 | 136 | #endif |
| 136 | 137 | }; |
| 137 | 138 | |
| 138 | −struct bcr_isa { | |
| 139 | +struct bcr_isa_arcv2 { | |
| 139 | 140 | #ifdef CONFIG_CPU_BIG_ENDIAN |
| 140 | 141 | unsigned int div_rem:4, pad2:4, ldd:1, unalign:1, atomic:1, be:1, |
| 141 | − pad1:11, atomic1:1, ver:8; | |
| 142 | + pad1:12, ver:8; | |
| 142 | 143 | #else |
| 143 | − unsigned int ver:8, atomic1:1, pad1:11, be:1, atomic:1, unalign:1, | |
| 144 | + unsigned int ver:8, pad1:12, be:1, atomic:1, unalign:1, | |
| 144 | 145 | ldd:1, pad2:4, div_rem:4; |
| 145 | 146 | #endif |
| 146 | 147 | }; |
| @@ -263,13 +264,13 @@ struct cpuinfo_arc { · 116 unmodified lines | ||
| 263 | 264 | struct cpuinfo_arc_mmu mmu; |
| 264 | 265 | struct cpuinfo_arc_bpu bpu; |
| 265 | 266 | struct bcr_identity core; |
| 266 | − struct bcr_isa isa; | |
| 267 | + struct bcr_isa_arcv2 isa; | |
| 267 | 268 | const char *details, *name; |
| 268 | 269 | unsigned int vec_base; |
| 269 | 270 | struct cpuinfo_arc_ccm iccm, dccm; |
| 270 | 271 | struct { |
| 271 | 272 | unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, swape:1, pad1:2, |
| 272 | − fpu_sp:1, fpu_dp:1, pad2:6, | |
| 273 | + fpu_sp:1, fpu_dp:1, dual_iss_enb:1, dual_iss_exist:1, pad2:4, | |
| 273 | 274 | debug:1, ap:1, smart:1, rtt:1, pad3:4, |
| 274 | 275 | timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4; |
| 275 | 276 | } extn; |
| @@ -78,9 +78,6 @@ struct task_struct; · 77 unmodified lines | ||
| 78 | 78 | |
| 79 | 79 | #endif |
| 80 | 80 | |
| 81 | −#define copy_segments(tsk, mm) do { } while (0) | |
| 82 | −#define release_segments(mm) do { } while (0) | |
| 83 | − | |
| 84 | 81 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ret) |
| 85 | 82 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp) |
| 86 | 83 | |
| @@ -51,6 +51,7 @@ static const struct id_to_str arc_cpu_rel[] = { · 50 unmodified lines | ||
| 51 | 51 | { 0x51, "R2.0" }, |
| 52 | 52 | { 0x52, "R2.1" }, |
| 53 | 53 | { 0x53, "R3.0" }, |
| 54 | + { 0x54, "R4.0" }, | |
| 54 | 55 | #endif |
| 55 | 56 | { 0x00, NULL } |
| 56 | 57 | }; |
| @@ -62,6 +63,7 @@ static const struct id_to_str arc_cpu_nm[] = { · 5 unmodified lines | ||
| 62 | 63 | #else |
| 63 | 64 | { 0x40, "ARC EM" }, |
| 64 | 65 | { 0x50, "ARC HS38" }, |
| 66 | + { 0x54, "ARC HS48" }, | |
| 65 | 67 | #endif |
| 66 | 68 | { 0x00, "Unknown" } |
| 67 | 69 | }; |
| @@ -119,11 +121,11 @@ static void read_arc_build_cfg_regs(void) · 51 unmodified lines | ||
| 119 | 121 | struct bcr_generic bcr; |
| 120 | 122 | struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; |
| 121 | 123 | const struct id_to_str *tbl; |
| 124 | + struct bcr_isa_arcv2 isa; | |
| 122 | 125 | |
| 123 | 126 | FIX_PTR(cpu); |
| 124 | 127 | |
| 125 | 128 | READ_BCR(AUX_IDENTITY, cpu->core); |
| 126 | − READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa); | |
| 127 | 129 | |
| 128 | 130 | for (tbl = &arc_cpu_rel[0]; tbl->id != 0; tbl++) { |
| 129 | 131 | if (cpu->core.family == tbl->id) { |
| @@ -133,7 +135,7 @@ static void read_arc_build_cfg_regs(void) · 3 unmodified lines | ||
| 133 | 135 | } |
| 134 | 136 | |
| 135 | 137 | for (tbl = &arc_cpu_nm[0]; tbl->id != 0; tbl++) { |
| 136 | − if ((cpu->core.family & 0xF0) == tbl->id) | |
| 138 | + if ((cpu->core.family & 0xF4) == tbl->id) | |
| 137 | 139 | break; |
| 138 | 140 | } |
| 139 | 141 | cpu->name = tbl->str; |
| @@ -192,6 +194,14 @@ static void read_arc_build_cfg_regs(void) · 52 unmodified lines | ||
| 192 | 194 | cpu->bpu.full = bpu.ft; |
| 193 | 195 | cpu->bpu.num_cache = 256 << bpu.bce; |
| 194 | 196 | cpu->bpu.num_pred = 2048 << bpu.pte; |
| 197 | + | |
| 198 | + if (cpu->core.family >= 0x54) { | |
| 199 | + unsigned int exec_ctrl; | |
| 200 | + | |
| 201 | + READ_BCR(AUX_EXEC_CTRL, exec_ctrl); | |
| 202 | + cpu->extn.dual_iss_exist = 1; | |
| 203 | + cpu->extn.dual_iss_enb = exec_ctrl & 1; | |
| 204 | + } | |
| 195 | 205 | } |
| 196 | 206 | |
| 197 | 207 | READ_BCR(ARC_REG_AP_BCR, bcr); |
| @@ -205,18 +215,25 @@ static void read_arc_build_cfg_regs(void) · 7 unmodified lines | ||
| 205 | 215 | |
| 206 | 216 | cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt; |
| 207 | 217 | |
| 218 | + READ_BCR(ARC_REG_ISA_CFG_BCR, isa); | |
| 219 | + | |
| 208 | 220 | /* some hacks for lack of feature BCR info in old ARC700 cores */ |
| 209 | 221 | if (is_isa_arcompact()) { |
| 210 | − if (!cpu->isa.ver) /* ISA BCR absent, use Kconfig info */ | |
| 222 | + if (!isa.ver) /* ISA BCR absent, use Kconfig info */ | |
| 211 | 223 | cpu->isa.atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); |
| 212 | − else | |
| 213 | − cpu->isa.atomic = cpu->isa.atomic1; | |
| 224 | + else { | |
| 225 | + /* ARC700_BUILD only has 2 bits of isa info */ | |
| 226 | + struct bcr_generic bcr = *(struct bcr_generic *)&isa; | |
| 227 | + cpu->isa.atomic = bcr.info & 1; | |
| 228 | + } | |
| 214 | 229 | |
| 215 | 230 | cpu->isa.be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); |
| 216 | 231 | |
| 217 | 232 | /* there's no direct way to distinguish 750 vs. 770 */ |
| 218 | 233 | if (unlikely(cpu->core.family < 0x34 || cpu->mmu.ver < 3)) |
| 219 | 234 | cpu->name = "ARC750"; |
| 235 | + } else { | |
| 236 | + cpu->isa = isa; | |
| 220 | 237 | } |
| 221 | 238 | } |
| 222 | 239 | |
| @@ -232,10 +249,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) · 9 unmodified lines | ||
| 232 | 249 | "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", |
| 233 | 250 | core->family, core->cpu_id, core->chip_id); |
| 234 | 251 | |
| 235 | − n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s\n", | |
| 252 | + n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s%s%s\n", | |
| 236 | 253 | cpu_id, cpu->name, cpu->details, |
| 237 | 254 | is_isa_arcompact() ? "ARCompact" : "ARCv2", |
| 238 | − IS_AVAIL1(cpu->isa.be, "[Big-Endian]")); | |
| 255 | + IS_AVAIL1(cpu->isa.be, "[Big-Endian]"), | |
| 256 | + IS_AVAIL3(cpu->extn.dual_iss_exist, cpu->extn.dual_iss_enb, " Dual-Issue")); | |
| 239 | 257 | |
| 240 | 258 | n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ", |
| 241 | 259 | IS_AVAIL1(cpu->extn.timer0, "Timer0 "), |
| @@ -111,6 +111,13 @@ static void __init axs10x_early_init(void) · 110 unmodified lines | ||
| 111 | 111 | |
| 112 | 112 | axs10x_enable_gpio_intc_wire(); |
| 113 | 113 | |
| 114 | + /* | |
| 115 | + * Reset ethernet IP core. | |
| 116 | + * TODO: get rid of this quirk after axs10x reset driver (or simple | |
| 117 | + * reset driver) will be available in upstream. | |
| 118 | + */ | |
| 119 | + iowrite32((1 << 5), (void __iomem *) CREG_MB_SW_RESET); | |
| 120 | + | |
| 114 | 121 | scnprintf(mb, 32, "MainBoard v%d", mb_rev); |
| 115 | 122 | axs10x_print_board_ver(CREG_MB_VER, mb); |
| 116 | 123 | } |
| @@ -6,4 +6,5 @@ · 5 unmodified lines | ||
| 6 | 6 | # |
| 7 | 7 | |
| 8 | 8 | menuconfig ARC_SOC_HSDK |
| 9 | − bool "ARC HS Development Kit SOC" | |
| 9 | + bool "ARC HS Development Kit SOC" | |
| 10 | + select CLK_HSDK | |
| @@ -38,6 +38,42 @@ static void __init hsdk_init_per_cpu(unsigned int cpu) · 37 unmodified lines | ||
| 38 | 38 | #define CREG_PAE (CREG_BASE + 0x180) |
| 39 | 39 | #define CREG_PAE_UPDATE (CREG_BASE + 0x194) |
| 40 | 40 | |
| 41 | +#define CREG_CORE_IF_CLK_DIV (CREG_BASE + 0x4B8) | |
| 42 | +#define CREG_CORE_IF_CLK_DIV_2 0x1 | |
| 43 | +#define CGU_BASE ARC_PERIPHERAL_BASE | |
| 44 | +#define CGU_PLL_STATUS (ARC_PERIPHERAL_BASE + 0x4) | |
| 45 | +#define CGU_PLL_CTRL (ARC_PERIPHERAL_BASE + 0x0) | |
| 46 | +#define CGU_PLL_STATUS_LOCK BIT(0) | |
| 47 | +#define CGU_PLL_STATUS_ERR BIT(1) | |
| 48 | +#define CGU_PLL_CTRL_1GHZ 0x3A10 | |
| 49 | +#define HSDK_PLL_LOCK_TIMEOUT 500 | |
| 50 | + | |
| 51 | +#define HSDK_PLL_LOCKED() \ | |
| 52 | + !!(ioread32((void __iomem *) CGU_PLL_STATUS) & CGU_PLL_STATUS_LOCK) | |
| 53 | + | |
| 54 | +#define HSDK_PLL_ERR() \ | |
| 55 | + !!(ioread32((void __iomem *) CGU_PLL_STATUS) & CGU_PLL_STATUS_ERR) | |
| 56 | + | |
| 57 | +static void __init hsdk_set_cpu_freq_1ghz(void) | |
| 58 | +{ | |
| 59 | + u32 timeout = HSDK_PLL_LOCK_TIMEOUT; | |
| 60 | + | |
| 61 | + /* | |
| 62 | + * As we set cpu clock which exceeds 500MHz, the divider for the interface | |
| 63 | + * clock must be programmed to div-by-2. | |
| 64 | + */ | |
| 65 | + iowrite32(CREG_CORE_IF_CLK_DIV_2, (void __iomem *) CREG_CORE_IF_CLK_DIV); | |
| 66 | + | |
| 67 | + /* Set cpu clock to 1GHz */ | |
| 68 | + iowrite32(CGU_PLL_CTRL_1GHZ, (void __iomem *) CGU_PLL_CTRL); | |
| 69 | + | |
| 70 | + while (!HSDK_PLL_LOCKED() && timeout--) | |
| 71 | + cpu_relax(); | |
| 72 | + | |
| 73 | + if (!HSDK_PLL_LOCKED() || HSDK_PLL_ERR()) | |
| 74 | + pr_err("Failed to setup CPU frequency to 1GHz!"); | |
| 75 | +} | |
| 76 | + | |
| 41 | 77 | static void __init hsdk_init_early(void) |
| 42 | 78 | { |
| 43 | 79 | /* |
| @@ -52,6 +88,12 @@ static void __init hsdk_init_early(void) · 8 unmodified lines | ||
| 52 | 88 | |
| 53 | 89 | /* Really apply settings made above */ |
| 54 | 90 | writel(1, (void __iomem *) CREG_PAE_UPDATE); |
| 91 | + | |
| 92 | + /* | |
| 93 | + * Setup CPU frequency to 1GHz. | |
| 94 | + * TODO: remove it after smart hsdk pll driver will be introduced. | |
| 95 | + */ | |
| 96 | + hsdk_set_cpu_freq_1ghz(); | |
| 55 | 97 | } |
| 56 | 98 | |
| 57 | 99 | static const char *hsdk_compat[] __initconst = { |
| @@ -36,6 +36,8 @@ · 35 unmodified lines | ||
| 36 | 36 | phy1 = &usb1_phy; |
| 37 | 37 | ethernet0 = &cpsw_emac0; |
| 38 | 38 | ethernet1 = &cpsw_emac1; |
| 39 | + spi0 = &spi0; | |
| 40 | + spi1 = &spi1; | |
| 39 | 41 | }; |
| 40 | 42 | |
| 41 | 43 | cpus { |
| @@ -388,6 +388,7 @@ · 387 unmodified lines | ||
| 388 | 388 | pinctrl-0 = <&cpsw_default>; |
| 389 | 389 | pinctrl-1 = <&cpsw_sleep>; |
| 390 | 390 | status = "okay"; |
| 391 | + slaves = <1>; | |
| 391 | 392 | }; |
| 392 | 393 | |
| 393 | 394 | &davinci_mdio { |
| @@ -402,11 +403,6 @@ · 8 unmodified lines | ||
| 402 | 403 | phy-mode = "rmii"; |
| 403 | 404 | }; |
| 404 | 405 | |
| 405 | −&cpsw_emac1 { | |
| 406 | − phy_id = <&davinci_mdio>, <1>; | |
| 407 | − phy-mode = "rmii"; | |
| 408 | −}; | |
| 409 | − | |
| 410 | 406 | &phy_sel { |
| 411 | 407 | rmii-clock-ext; |
| 412 | 408 | }; |
| @@ -67,7 +67,10 @@ · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | usb1: ohci@00400000 { |
| 69 | 69 | num-ports = <3>; |
| 70 | − atmel,vbus-gpio = <&pioA PIN_PA10 GPIO_ACTIVE_HIGH>; | |
| 70 | + atmel,vbus-gpio = <0 /* &pioA PIN_PD20 GPIO_ACTIVE_HIGH */ | |
| 71 | + &pioA PIN_PA27 GPIO_ACTIVE_HIGH | |
| 72 | + 0 | |
| 73 | + >; | |
| 71 | 74 | pinctrl-names = "default"; |
| 72 | 75 | pinctrl-0 = <&pinctrl_usb_default>; |
| 73 | 76 | status = "okay"; |
| @@ -120,7 +123,7 @@ · 46 unmodified lines | ||
| 120 | 123 | pinctrl-names = "default"; |
| 121 | 124 | pinctrl-0 = <&pinctrl_mikrobus2_uart>; |
| 122 | 125 | atmel,use-dma-rx; |
| 123 | − atmel-use-dma-tx; | |
| 126 | + atmel,use-dma-tx; | |
| 124 | 127 | status = "okay"; |
| 125 | 128 | }; |
| 126 | 129 | |
| @@ -178,7 +181,7 @@ · 51 unmodified lines | ||
| 178 | 181 | uart4: serial@fc00c000 { |
| 179 | 182 | atmel,use-dma-rx; |
| 180 | 183 | atmel,use-dma-tx; |
| 181 | − pinctrl-name = "default"; | |
| 184 | + pinctrl-names = "default"; | |
| 182 | 185 | pinctrl-0 = <&pinctrl_mikrobus1_uart>; |
| 183 | 186 | status = "okay"; |
| 184 | 187 | }; |
| @@ -330,7 +333,7 @@ · 145 unmodified lines | ||
| 330 | 333 | }; |
| 331 | 334 | |
| 332 | 335 | pinctrl_led_gpio_default: led_gpio_default { |
| 333 | − pinmux = <PIN_PA27__GPIO>, | |
| 336 | + pinmux = <PIN_PA10__GPIO>, | |
| 334 | 337 | <PIN_PB1__GPIO>, |
| 335 | 338 | <PIN_PA31__GPIO>; |
| 336 | 339 | bias-pull-up; |
| @@ -396,7 +399,7 @@ · 59 unmodified lines | ||
| 396 | 399 | }; |
| 397 | 400 | |
| 398 | 401 | pinctrl_usb_default: usb_default { |
| 399 | − pinmux = <PIN_PA10__GPIO>, | |
| 402 | + pinmux = <PIN_PA27__GPIO>, | |
| 400 | 403 | <PIN_PD19__GPIO>; |
| 401 | 404 | bias-disable; |
| 402 | 405 | }; |
| @@ -520,17 +523,17 @@ · 117 unmodified lines | ||
| 520 | 523 | |
| 521 | 524 | red { |
| 522 | 525 | label = "red"; |
| 523 | − gpios = <&pioA PIN_PA27 GPIO_ACTIVE_LOW>; | |
| 526 | + gpios = <&pioA PIN_PA10 GPIO_ACTIVE_HIGH>; | |
| 524 | 527 | }; |
| 525 | 528 | |
| 526 | 529 | green { |
| 527 | 530 | label = "green"; |
| 528 | − gpios = <&pioA PIN_PB1 GPIO_ACTIVE_LOW>; | |
| 531 | + gpios = <&pioA PIN_PB1 GPIO_ACTIVE_HIGH>; | |
| 529 | 532 | }; |
| 530 | 533 | |
| 531 | 534 | blue { |
| 532 | 535 | label = "blue"; |
| 533 | − gpios = <&pioA PIN_PA31 GPIO_ACTIVE_LOW>; | |
| 536 | + gpios = <&pioA PIN_PA31 GPIO_ACTIVE_HIGH>; | |
| 534 | 537 | linux,default-trigger = "heartbeat"; |
| 535 | 538 | }; |
| 536 | 539 | }; |
| @@ -15,6 +15,13 @@ · 14 unmodified lines | ||
| 15 | 15 | compatible = "ti,da850-evm", "ti,da850"; |
| 16 | 16 | model = "DA850/AM1808/OMAP-L138 EVM"; |
| 17 | 17 | |
| 18 | + aliases { | |
| 19 | + serial0 = &serial0; | |
| 20 | + serial1 = &serial1; | |
| 21 | + serial2 = &serial2; | |
| 22 | + ethernet0 = ð0; | |
| 23 | + }; | |
| 24 | + | |
| 18 | 25 | soc@1c00000 { |
| 19 | 26 | pmx_core: pinmux@14120 { |
| 20 | 27 | status = "okay"; |
| @@ -1817,6 +1817,8 @@ · 1816 unmodified lines | ||
| 1817 | 1817 | clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; |
| 1818 | 1818 | ti,bit-shift = <24>; |
| 1819 | 1819 | reg = <0x1868>; |
| 1820 | + assigned-clocks = <&mcasp3_ahclkx_mux>; | |
| 1821 | + assigned-clock-parents = <&abe_24m_fclk>; | |
| 1820 | 1822 | }; |
| 1821 | 1823 | |
| 1822 | 1824 | mcasp3_aux_gfclk_mux: mcasp3_aux_gfclk_mux@1868 { |
| @@ -144,15 +144,6 @@ · 143 unmodified lines | ||
| 144 | 144 | io-channel-names = "temp", "bsi", "vbat"; |
| 145 | 145 | }; |
| 146 | 146 | |
| 147 | − rear_camera: camera@0 { | |
| 148 | − compatible = "linux,camera"; | |
| 149 | − | |
| 150 | − module { | |
| 151 | − model = "TCM8341MD"; | |
| 152 | − sensor = <&cam1>; | |
| 153 | − }; | |
| 154 | − }; | |
| 155 | − | |
| 156 | 147 | pwm9: dmtimer-pwm { |
| 157 | 148 | compatible = "ti,omap-dmtimer-pwm"; |
| 158 | 149 | #pwm-cells = <3>; |
| @@ -189,10 +180,8 @@ · 30 unmodified lines | ||
| 189 | 180 | clock-lanes = <1>; |
| 190 | 181 | data-lanes = <0>; |
| 191 | 182 | lane-polarity = <0 0>; |
| 192 | − clock-inv = <0>; | |
| 193 | 183 | /* Select strobe = <1> for back camera, <0> for front camera */ |
| 194 | 184 | strobe = <1>; |
| 195 | − crc = <0>; | |
| 196 | 185 | }; |
| 197 | 186 | }; |
| 198 | 187 | }; |
| @@ -267,15 +267,19 @@ · 266 unmodified lines | ||
| 267 | 267 | clock-frequency = <400000>; |
| 268 | 268 | |
| 269 | 269 | as3645a@30 { |
| 270 | + #address-cells = <1>; | |
| 271 | + #size-cells = <0>; | |
| 270 | 272 | reg = <0x30>; |
| 271 | 273 | compatible = "ams,as3645a"; |
| 272 | − flash { | |
| 274 | + flash@0 { | |
| 275 | + reg = <0x0>; | |
| 273 | 276 | flash-timeout-us = <150000>; |
| 274 | 277 | flash-max-microamp = <320000>; |
| 275 | 278 | led-max-microamp = <60000>; |
| 276 | − peak-current-limit = <1750000>; | |
| 279 | + ams,input-max-microamp = <1750000>; | |
| 277 | 280 | }; |
| 278 | − indicator { | |
| 281 | + indicator@1 { | |
| 282 | + reg = <0x1>; | |
| 279 | 283 | led-max-microamp = <10000>; |
| 280 | 284 | }; |
| 281 | 285 | }; |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | /dts-v1/; |
| 49 | 49 | #include "stm32f429.dtsi" |
| 50 | +#include "stm32f429-pinctrl.dtsi" | |
| 50 | 51 | #include <dt-bindings/input/input.h> |
| 51 | 52 | #include <dt-bindings/gpio/gpio.h> |
| 52 | 53 | |
| @@ -202,10 +203,8 @@ · 149 unmodified lines | ||
| 202 | 203 | stmpe1600: stmpe1600@42 { |
| 203 | 204 | compatible = "st,stmpe1600"; |
| 204 | 205 | reg = <0x42>; |
| 205 | − irq-gpio = <&gpioi 8 0>; | |
| 206 | − irq-trigger = <3>; | |
| 207 | 206 | interrupts = <8 3>; |
| 208 | − interrupt-parent = <&exti>; | |
| 207 | + interrupt-parent = <&gpioi>; | |
| 209 | 208 | interrupt-controller; |
| 210 | 209 | wakeup-source; |
| 211 | 210 | |
| @@ -0,0 +1,343 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2017 - Alexandre Torgue <alexandre.torgue@st.com> | |
| 3 | + * | |
| 4 | + * This file is dual-licensed: you can use it either under the terms | |
| 5 | + * of the GPL or the X11 license, at your option. Note that this dual | |
| 6 | + * licensing only applies to this file, and not this project as a | |
| 7 | + * whole. | |
| 8 | + * | |
| 9 | + * a) This file is free software; you can redistribute it and/or | |
| 10 | + * modify it under the terms of the GNU General Public License as | |
| 11 | + * published by the Free Software Foundation; either version 2 of the | |
| 12 | + * License, or (at your option) any later version. | |
| 13 | + * | |
| 14 | + * This file is distributed in the hope that it will be useful, | |
| 15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 | + * GNU General Public License for more details. | |
| 18 | + * | |
| 19 | + * Or, alternatively, | |
| 20 | + * | |
| 21 | + * b) Permission is hereby granted, free of charge, to any person | |
| 22 | + * obtaining a copy of this software and associated documentation | |
| 23 | + * files (the "Software"), to deal in the Software without | |
| 24 | + * restriction, including without limitation the rights to use, | |
| 25 | + * copy, modify, merge, publish, distribute, sublicense, and/or | |
| 26 | + * sell copies of the Software, and to permit persons to whom the | |
| 27 | + * Software is furnished to do so, subject to the following | |
| 28 | + * conditions: | |
| 29 | + * | |
| 30 | + * The above copyright notice and this permission notice shall be | |
| 31 | + * included in all copies or substantial portions of the Software. | |
| 32 | + * | |
| 33 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 34 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
| 35 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| 36 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
| 37 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
| 38 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 39 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 40 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 41 | + */ | |
| 42 | + | |
| 43 | +#include <dt-bindings/pinctrl/stm32f429-pinfunc.h> | |
| 44 | +#include <dt-bindings/mfd/stm32f4-rcc.h> | |
| 45 | + | |
| 46 | +/ { | |
| 47 | + soc { | |
| 48 | + pinctrl: pin-controller { | |
| 49 | + #address-cells = <1>; | |
| 50 | + #size-cells = <1>; | |
| 51 | + ranges = <0 0x40020000 0x3000>; | |
| 52 | + interrupt-parent = <&exti>; | |
| 53 | + st,syscfg = <&syscfg 0x8>; | |
| 54 | + pins-are-numbered; | |
| 55 | + | |
| 56 | + gpioa: gpio@40020000 { | |
| 57 | + gpio-controller; | |
| 58 | + #gpio-cells = <2>; | |
| 59 | + interrupt-controller; | |
| 60 | + #interrupt-cells = <2>; | |
| 61 | + reg = <0x0 0x400>; | |
| 62 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>; | |
| 63 | + st,bank-name = "GPIOA"; | |
| 64 | + }; | |
| 65 | + | |
| 66 | + gpiob: gpio@40020400 { | |
| 67 | + gpio-controller; | |
| 68 | + #gpio-cells = <2>; | |
| 69 | + interrupt-controller; | |
| 70 | + #interrupt-cells = <2>; | |
| 71 | + reg = <0x400 0x400>; | |
| 72 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOB)>; | |
| 73 | + st,bank-name = "GPIOB"; | |
| 74 | + }; | |
| 75 | + | |
| 76 | + gpioc: gpio@40020800 { | |
| 77 | + gpio-controller; | |
| 78 | + #gpio-cells = <2>; | |
| 79 | + interrupt-controller; | |
| 80 | + #interrupt-cells = <2>; | |
| 81 | + reg = <0x800 0x400>; | |
| 82 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOC)>; | |
| 83 | + st,bank-name = "GPIOC"; | |
| 84 | + }; | |
| 85 | + | |
| 86 | + gpiod: gpio@40020c00 { | |
| 87 | + gpio-controller; | |
| 88 | + #gpio-cells = <2>; | |
| 89 | + interrupt-controller; | |
| 90 | + #interrupt-cells = <2>; | |
| 91 | + reg = <0xc00 0x400>; | |
| 92 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOD)>; | |
| 93 | + st,bank-name = "GPIOD"; | |
| 94 | + }; | |
| 95 | + | |
| 96 | + gpioe: gpio@40021000 { | |
| 97 | + gpio-controller; | |
| 98 | + #gpio-cells = <2>; | |
| 99 | + interrupt-controller; | |
| 100 | + #interrupt-cells = <2>; | |
| 101 | + reg = <0x1000 0x400>; | |
| 102 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOE)>; | |
| 103 | + st,bank-name = "GPIOE"; | |
| 104 | + }; | |
| 105 | + | |
| 106 | + gpiof: gpio@40021400 { | |
| 107 | + gpio-controller; | |
| 108 | + #gpio-cells = <2>; | |
| 109 | + interrupt-controller; | |
| 110 | + #interrupt-cells = <2>; | |
| 111 | + reg = <0x1400 0x400>; | |
| 112 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOF)>; | |
| 113 | + st,bank-name = "GPIOF"; | |
| 114 | + }; | |
| 115 | + | |
| 116 | + gpiog: gpio@40021800 { | |
| 117 | + gpio-controller; | |
| 118 | + #gpio-cells = <2>; | |
| 119 | + interrupt-controller; | |
| 120 | + #interrupt-cells = <2>; | |
| 121 | + reg = <0x1800 0x400>; | |
| 122 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOG)>; | |
| 123 | + st,bank-name = "GPIOG"; | |
| 124 | + }; | |
| 125 | + | |
| 126 | + gpioh: gpio@40021c00 { | |
| 127 | + gpio-controller; | |
| 128 | + #gpio-cells = <2>; | |
| 129 | + interrupt-controller; | |
| 130 | + #interrupt-cells = <2>; | |
| 131 | + reg = <0x1c00 0x400>; | |
| 132 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOH)>; | |
| 133 | + st,bank-name = "GPIOH"; | |
| 134 | + }; | |
| 135 | + | |
| 136 | + gpioi: gpio@40022000 { | |
| 137 | + gpio-controller; | |
| 138 | + #gpio-cells = <2>; | |
| 139 | + interrupt-controller; | |
| 140 | + #interrupt-cells = <2>; | |
| 141 | + reg = <0x2000 0x400>; | |
| 142 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOI)>; | |
| 143 | + st,bank-name = "GPIOI"; | |
| 144 | + }; | |
| 145 | + | |
| 146 | + gpioj: gpio@40022400 { | |
| 147 | + gpio-controller; | |
| 148 | + #gpio-cells = <2>; | |
| 149 | + interrupt-controller; | |
| 150 | + #interrupt-cells = <2>; | |
| 151 | + reg = <0x2400 0x400>; | |
| 152 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOJ)>; | |
| 153 | + st,bank-name = "GPIOJ"; | |
| 154 | + }; | |
| 155 | + | |
| 156 | + gpiok: gpio@40022800 { | |
| 157 | + gpio-controller; | |
| 158 | + #gpio-cells = <2>; | |
| 159 | + interrupt-controller; | |
| 160 | + #interrupt-cells = <2>; | |
| 161 | + reg = <0x2800 0x400>; | |
| 162 | + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOK)>; | |
| 163 | + st,bank-name = "GPIOK"; | |
| 164 | + }; | |
| 165 | + | |
| 166 | + usart1_pins_a: usart1@0 { | |
| 167 | + pins1 { | |
| 168 | + pinmux = <STM32F429_PA9_FUNC_USART1_TX>; | |
| 169 | + bias-disable; | |
| 170 | + drive-push-pull; | |
| 171 | + slew-rate = <0>; | |
| 172 | + }; | |
| 173 | + pins2 { | |
| 174 | + pinmux = <STM32F429_PA10_FUNC_USART1_RX>; | |
| 175 | + bias-disable; | |
| 176 | + }; | |
| 177 | + }; | |
| 178 | + | |
| 179 | + usart3_pins_a: usart3@0 { | |
| 180 | + pins1 { | |
| 181 | + pinmux = <STM32F429_PB10_FUNC_USART3_TX>; | |
| 182 | + bias-disable; | |
| 183 | + drive-push-pull; | |
| 184 | + slew-rate = <0>; | |
| 185 | + }; | |
| 186 | + pins2 { | |
| 187 | + pinmux = <STM32F429_PB11_FUNC_USART3_RX>; | |
| 188 | + bias-disable; | |
| 189 | + }; | |
| 190 | + }; | |
| 191 | + | |
| 192 | + usbotg_fs_pins_a: usbotg_fs@0 { | |
| 193 | + pins { | |
| 194 | + pinmux = <STM32F429_PA10_FUNC_OTG_FS_ID>, | |
| 195 | + <STM32F429_PA11_FUNC_OTG_FS_DM>, | |
| 196 | + <STM32F429_PA12_FUNC_OTG_FS_DP>; | |
| 197 | + bias-disable; | |
| 198 | + drive-push-pull; | |
| 199 | + slew-rate = <2>; | |
| 200 | + }; | |
| 201 | + }; | |
| 202 | + | |
| 203 | + usbotg_fs_pins_b: usbotg_fs@1 { | |
| 204 | + pins { | |
| 205 | + pinmux = <STM32F429_PB12_FUNC_OTG_HS_ID>, | |
| 206 | + <STM32F429_PB14_FUNC_OTG_HS_DM>, | |
| 207 | + <STM32F429_PB15_FUNC_OTG_HS_DP>; | |
| 208 | + bias-disable; | |
| 209 | + drive-push-pull; | |
| 210 | + slew-rate = <2>; | |
| 211 | + }; | |
| 212 | + }; | |
| 213 | + | |
| 214 | + usbotg_hs_pins_a: usbotg_hs@0 { | |
| 215 | + pins { | |
| 216 | + pinmux = <STM32F429_PH4_FUNC_OTG_HS_ULPI_NXT>, | |
| 217 | + <STM32F429_PI11_FUNC_OTG_HS_ULPI_DIR>, | |
| 218 | + <STM32F429_PC0_FUNC_OTG_HS_ULPI_STP>, | |
| 219 | + <STM32F429_PA5_FUNC_OTG_HS_ULPI_CK>, | |
| 220 | + <STM32F429_PA3_FUNC_OTG_HS_ULPI_D0>, | |
| 221 | + <STM32F429_PB0_FUNC_OTG_HS_ULPI_D1>, | |
| 222 | + <STM32F429_PB1_FUNC_OTG_HS_ULPI_D2>, | |
| 223 | + <STM32F429_PB10_FUNC_OTG_HS_ULPI_D3>, | |
| 224 | + <STM32F429_PB11_FUNC_OTG_HS_ULPI_D4>, | |
| 225 | + <STM32F429_PB12_FUNC_OTG_HS_ULPI_D5>, | |
| 226 | + <STM32F429_PB13_FUNC_OTG_HS_ULPI_D6>, | |
| 227 | + <STM32F429_PB5_FUNC_OTG_HS_ULPI_D7>; | |
| 228 | + bias-disable; | |
| 229 | + drive-push-pull; | |
| 230 | + slew-rate = <2>; | |
| 231 | + }; | |
| 232 | + }; | |
| 233 | + | |
| 234 | + ethernet_mii: mii@0 { | |
| 235 | + pins { | |
| 236 | + pinmux = <STM32F429_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0>, | |
| 237 | + <STM32F429_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1>, | |
| 238 | + <STM32F429_PC2_FUNC_ETH_MII_TXD2>, | |
| 239 | + <STM32F429_PB8_FUNC_ETH_MII_TXD3>, | |
| 240 | + <STM32F429_PC3_FUNC_ETH_MII_TX_CLK>, | |
| 241 | + <STM32F429_PG11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN>, | |
| 242 | + <STM32F429_PA2_FUNC_ETH_MDIO>, | |
| 243 | + <STM32F429_PC1_FUNC_ETH_MDC>, | |
| 244 | + <STM32F429_PA1_FUNC_ETH_MII_RX_CLK_ETH_RMII_REF_CLK>, | |
| 245 | + <STM32F429_PA7_FUNC_ETH_MII_RX_DV_ETH_RMII_CRS_DV>, | |
| 246 | + <STM32F429_PC4_FUNC_ETH_MII_RXD0_ETH_RMII_RXD0>, | |
| 247 | + <STM32F429_PC5_FUNC_ETH_MII_RXD1_ETH_RMII_RXD1>, | |
| 248 | + <STM32F429_PH6_FUNC_ETH_MII_RXD2>, | |
| 249 | + <STM32F429_PH7_FUNC_ETH_MII_RXD3>; | |
| 250 | + slew-rate = <2>; | |
| 251 | + }; | |
| 252 | + }; | |
| 253 | + | |
| 254 | + adc3_in8_pin: adc@200 { | |
| 255 | + pins { | |
| 256 | + pinmux = <STM32F429_PF10_FUNC_ANALOG>; | |
| 257 | + }; | |
| 258 | + }; | |
| 259 | + | |
| 260 | + pwm1_pins: pwm@1 { | |
| 261 | + pins { | |
| 262 | + pinmux = <STM32F429_PA8_FUNC_TIM1_CH1>, | |
| 263 | + <STM32F429_PB13_FUNC_TIM1_CH1N>, | |
| 264 | + <STM32F429_PB12_FUNC_TIM1_BKIN>; | |
| 265 | + }; | |
| 266 | + }; | |
| 267 | + | |
| 268 | + pwm3_pins: pwm@3 { | |
| 269 | + pins { | |
| 270 | + pinmux = <STM32F429_PB4_FUNC_TIM3_CH1>, | |
| 271 | + <STM32F429_PB5_FUNC_TIM3_CH2>; | |
| 272 | + }; | |
| 273 | + }; | |
| 274 | + | |
| 275 | + i2c1_pins: i2c1@0 { | |
| 276 | + pins { | |
| 277 | + pinmux = <STM32F429_PB9_FUNC_I2C1_SDA>, | |
| 278 | + <STM32F429_PB6_FUNC_I2C1_SCL>; | |
| 279 | + bias-disable; | |
| 280 | + drive-open-drain; | |
| 281 | + slew-rate = <3>; | |
| 282 | + }; | |
| 283 | + }; | |
| 284 | + | |
| 285 | + ltdc_pins: ltdc@0 { | |
| 286 | + pins { | |
| 287 | + pinmux = <STM32F429_PI12_FUNC_LCD_HSYNC>, | |
| 288 | + <STM32F429_PI13_FUNC_LCD_VSYNC>, | |
| 289 | + <STM32F429_PI14_FUNC_LCD_CLK>, | |
| 290 | + <STM32F429_PI15_FUNC_LCD_R0>, | |
| 291 | + <STM32F429_PJ0_FUNC_LCD_R1>, | |
| 292 | + <STM32F429_PJ1_FUNC_LCD_R2>, | |
| 293 | + <STM32F429_PJ2_FUNC_LCD_R3>, | |
| 294 | + <STM32F429_PJ3_FUNC_LCD_R4>, | |
| 295 | + <STM32F429_PJ4_FUNC_LCD_R5>, | |
| 296 | + <STM32F429_PJ5_FUNC_LCD_R6>, | |
| 297 | + <STM32F429_PJ6_FUNC_LCD_R7>, | |
| 298 | + <STM32F429_PJ7_FUNC_LCD_G0>, | |
| 299 | + <STM32F429_PJ8_FUNC_LCD_G1>, | |
| 300 | + <STM32F429_PJ9_FUNC_LCD_G2>, | |
| 301 | + <STM32F429_PJ10_FUNC_LCD_G3>, | |
| 302 | + <STM32F429_PJ11_FUNC_LCD_G4>, | |
| 303 | + <STM32F429_PJ12_FUNC_LCD_B0>, | |
| 304 | + <STM32F429_PJ13_FUNC_LCD_B1>, | |
| 305 | + <STM32F429_PJ14_FUNC_LCD_B2>, | |
| 306 | + <STM32F429_PJ15_FUNC_LCD_B3>, | |
| 307 | + <STM32F429_PK0_FUNC_LCD_G5>, | |
| 308 | + <STM32F429_PK1_FUNC_LCD_G6>, | |
| 309 | + <STM32F429_PK2_FUNC_LCD_G7>, | |
| 310 | + <STM32F429_PK3_FUNC_LCD_B4>, | |
| 311 | + <STM32F429_PK4_FUNC_LCD_B5>, | |
| 312 | + <STM32F429_PK5_FUNC_LCD_B6>, | |
| 313 | + <STM32F429_PK6_FUNC_LCD_B7>, | |
| 314 | + <STM32F429_PK7_FUNC_LCD_DE>; | |
| 315 | + slew-rate = <2>; | |
| 316 | + }; | |
| 317 | + }; | |
| 318 | + | |
| 319 | + dcmi_pins: dcmi@0 { | |
| 320 | + pins { | |
| 321 | + pinmux = <STM32F429_PA4_FUNC_DCMI_HSYNC>, | |
| 322 | + <STM32F429_PB7_FUNC_DCMI_VSYNC>, | |
| 323 | + <STM32F429_PA6_FUNC_DCMI_PIXCLK>, | |
| 324 | + <STM32F429_PC6_FUNC_DCMI_D0>, | |
| 325 | + <STM32F429_PC7_FUNC_DCMI_D1>, | |
| 326 | + <STM32F429_PC8_FUNC_DCMI_D2>, | |
| 327 | + <STM32F429_PC9_FUNC_DCMI_D3>, | |
| 328 | + <STM32F429_PC11_FUNC_DCMI_D4>, | |
| 329 | + <STM32F429_PD3_FUNC_DCMI_D5>, | |
| 330 | + <STM32F429_PB8_FUNC_DCMI_D6>, | |
| 331 | + <STM32F429_PE6_FUNC_DCMI_D7>, | |
| 332 | + <STM32F429_PC10_FUNC_DCMI_D8>, | |
| 333 | + <STM32F429_PC12_FUNC_DCMI_D9>, | |
| 334 | + <STM32F429_PD6_FUNC_DCMI_D10>, | |
| 335 | + <STM32F429_PD2_FUNC_DCMI_D11>; | |
| 336 | + bias-disable; | |
| 337 | + drive-push-pull; | |
| 338 | + slew-rate = <3>; | |
| 339 | + }; | |
| 340 | + }; | |
| 341 | + }; | |
| 342 | + }; | |
| 343 | +}; | |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | /dts-v1/; |
| 49 | 49 | #include "stm32f429.dtsi" |
| 50 | +#include "stm32f429-pinctrl.dtsi" | |
| 50 | 51 | #include <dt-bindings/input/input.h> |
| 51 | 52 | |
| 52 | 53 | / { |
| @@ -0,0 +1,95 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2017 - Alexandre Torgue <alexandre.torgue@st.com> | |
| 3 | + * | |
| 4 | + * This file is dual-licensed: you can use it either under the terms | |
| 5 | + * of the GPL or the X11 license, at your option. Note that this dual | |
| 6 | + * licensing only applies to this file, and not this project as a | |
| 7 | + * whole. | |
| 8 | + * | |
| 9 | + * a) This file is free software; you can redistribute it and/or | |
| 10 | + * modify it under the terms of the GNU General Public License as | |
| 11 | + * published by the Free Software Foundation; either version 2 of the | |
| 12 | + * License, or (at your option) any later version. | |
| 13 | + * | |
| 14 | + * This file is distributed in the hope that it will be useful, | |
| 15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 | + * GNU General Public License for more details. | |
| 18 | + * | |
| 19 | + * Or, alternatively, | |
| 20 | + * | |
| 21 | + * b) Permission is hereby granted, free of charge, to any person | |
| 22 | + * obtaining a copy of this software and associated documentation | |
| 23 | + * files (the "Software"), to deal in the Software without | |
| 24 | + * restriction, including without limitation the rights to use, | |
| 25 | + * copy, modify, merge, publish, distribute, sublicense, and/or | |
| 26 | + * sell copies of the Software, and to permit persons to whom the | |
| 27 | + * Software is furnished to do so, subject to the following | |
| 28 | + * conditions: | |
| 29 | + * | |
| 30 | + * The above copyright notice and this permission notice shall be | |
| 31 | + * included in all copies or substantial portions of the Software. | |
| 32 | + * | |
| 33 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 34 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
| 35 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| 36 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
| 37 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
| 38 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 39 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 40 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 41 | + */ | |
| 42 | + | |
| 43 | +#include "stm32f4-pinctrl.dtsi" | |
| 44 | + | |
| 45 | +/ { | |
| 46 | + soc { | |
| 47 | + pinctrl: pin-controller { | |
| 48 | + compatible = "st,stm32f429-pinctrl"; | |
| 49 | + | |
| 50 | + gpioa: gpio@40020000 { | |
| 51 | + gpio-ranges = <&pinctrl 0 0 16>; | |
| 52 | + }; | |
| 53 | + | |
| 54 | + gpiob: gpio@40020400 { | |
| 55 | + gpio-ranges = <&pinctrl 0 16 16>; | |
| 56 | + }; | |
| 57 | + | |
| 58 | + gpioc: gpio@40020800 { | |
| 59 | + gpio-ranges = <&pinctrl 0 32 16>; | |
| 60 | + }; | |
| 61 | + | |
| 62 | + gpiod: gpio@40020c00 { | |
| 63 | + gpio-ranges = <&pinctrl 0 48 16>; | |
| 64 | + }; | |
| 65 | + | |
| 66 | + gpioe: gpio@40021000 { | |
| 67 | + gpio-ranges = <&pinctrl 0 64 16>; | |
| 68 | + }; | |
| 69 | + | |
| 70 | + gpiof: gpio@40021400 { | |
| 71 | + gpio-ranges = <&pinctrl 0 80 16>; | |
| 72 | + }; | |
| 73 | + | |
| 74 | + gpiog: gpio@40021800 { | |
| 75 | + gpio-ranges = <&pinctrl 0 96 16>; | |
| 76 | + }; | |
| 77 | + | |
| 78 | + gpioh: gpio@40021c00 { | |
| 79 | + gpio-ranges = <&pinctrl 0 112 16>; | |
| 80 | + }; | |
| 81 | + | |
| 82 | + gpioi: gpio@40022000 { | |
| 83 | + gpio-ranges = <&pinctrl 0 128 16>; | |
| 84 | + }; | |
| 85 | + | |
| 86 | + gpioj: gpio@40022400 { | |
| 87 | + gpio-ranges = <&pinctrl 0 144 16>; | |
| 88 | + }; | |
| 89 | + | |
| 90 | + gpiok: gpio@40022800 { | |
| 91 | + gpio-ranges = <&pinctrl 0 160 8>; | |
| 92 | + }; | |
| 93 | + }; | |
| 94 | + }; | |
| 95 | +}; | |
| @@ -47,7 +47,6 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | #include "skeleton.dtsi" |
| 49 | 49 | #include "armv7-m.dtsi" |
| 50 | −#include <dt-bindings/pinctrl/stm32f429-pinfunc.h> | |
| 51 | 50 | #include <dt-bindings/clock/stm32fx-clock.h> |
| 52 | 51 | #include <dt-bindings/mfd/stm32f4-rcc.h> |
| 53 | 52 | |
| @@ -591,302 +590,6 @@ · 537 unmodified lines | ||
| 591 | 590 | status = "disabled"; |
| 592 | 591 | }; |
| 593 | 592 | |
| 594 | − pinctrl: pin-controller { | |
| 595 | − #address-cells = <1>; | |
| 596 | − #size-cells = <1>; | |
| 597 | − compatible = "st,stm32f429-pinctrl"; | |
| 598 | − ranges = <0 0x40020000 0x3000>; | |
| 599 | − interrupt-parent = <&exti>; | |
| 600 | − st,syscfg = <&syscfg 0x8>; | |
| 601 | − pins-are-numbered; | |
| 602 | − | |
| 603 | − gpioa: gpio@40020000 { | |
| 604 | − gpio-controller; | |
| 605 | − #gpio-cells = <2>; | |
| 606 | − interrupt-controller; | |
| 607 | − #interrupt-cells = <2>; | |
| 608 | − reg = <0x0 0x400>; | |
| 609 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>; | |
| 610 | − st,bank-name = "GPIOA"; | |
| 611 | − }; | |
| 612 | − | |
| 613 | − gpiob: gpio@40020400 { | |
| 614 | − gpio-controller; | |
| 615 | − #gpio-cells = <2>; | |
| 616 | − interrupt-controller; | |
| 617 | − #interrupt-cells = <2>; | |
| 618 | − reg = <0x400 0x400>; | |
| 619 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOB)>; | |
| 620 | − st,bank-name = "GPIOB"; | |
| 621 | − }; | |
| 622 | − | |
| 623 | − gpioc: gpio@40020800 { | |
| 624 | − gpio-controller; | |
| 625 | − #gpio-cells = <2>; | |
| 626 | − interrupt-controller; | |
| 627 | − #interrupt-cells = <2>; | |
| 628 | − reg = <0x800 0x400>; | |
| 629 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOC)>; | |
| 630 | − st,bank-name = "GPIOC"; | |
| 631 | − }; | |
| 632 | − | |
| 633 | − gpiod: gpio@40020c00 { | |
| 634 | − gpio-controller; | |
| 635 | − #gpio-cells = <2>; | |
| 636 | − interrupt-controller; | |
| 637 | − #interrupt-cells = <2>; | |
| 638 | − reg = <0xc00 0x400>; | |
| 639 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOD)>; | |
| 640 | − st,bank-name = "GPIOD"; | |
| 641 | − }; | |
| 642 | − | |
| 643 | − gpioe: gpio@40021000 { | |
| 644 | − gpio-controller; | |
| 645 | − #gpio-cells = <2>; | |
| 646 | − interrupt-controller; | |
| 647 | − #interrupt-cells = <2>; | |
| 648 | − reg = <0x1000 0x400>; | |
| 649 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOE)>; | |
| 650 | − st,bank-name = "GPIOE"; | |
| 651 | − }; | |
| 652 | − | |
| 653 | − gpiof: gpio@40021400 { | |
| 654 | − gpio-controller; | |
| 655 | − #gpio-cells = <2>; | |
| 656 | − interrupt-controller; | |
| 657 | − #interrupt-cells = <2>; | |
| 658 | − reg = <0x1400 0x400>; | |
| 659 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOF)>; | |
| 660 | − st,bank-name = "GPIOF"; | |
| 661 | − }; | |
| 662 | − | |
| 663 | − gpiog: gpio@40021800 { | |
| 664 | − gpio-controller; | |
| 665 | − #gpio-cells = <2>; | |
| 666 | − interrupt-controller; | |
| 667 | − #interrupt-cells = <2>; | |
| 668 | − reg = <0x1800 0x400>; | |
| 669 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOG)>; | |
| 670 | − st,bank-name = "GPIOG"; | |
| 671 | − }; | |
| 672 | − | |
| 673 | − gpioh: gpio@40021c00 { | |
| 674 | − gpio-controller; | |
| 675 | − #gpio-cells = <2>; | |
| 676 | − interrupt-controller; | |
| 677 | − #interrupt-cells = <2>; | |
| 678 | − reg = <0x1c00 0x400>; | |
| 679 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOH)>; | |
| 680 | − st,bank-name = "GPIOH"; | |
| 681 | − }; | |
| 682 | − | |
| 683 | − gpioi: gpio@40022000 { | |
| 684 | − gpio-controller; | |
| 685 | − #gpio-cells = <2>; | |
| 686 | − interrupt-controller; | |
| 687 | − #interrupt-cells = <2>; | |
| 688 | − reg = <0x2000 0x400>; | |
| 689 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOI)>; | |
| 690 | − st,bank-name = "GPIOI"; | |
| 691 | − }; | |
| 692 | − | |
| 693 | − gpioj: gpio@40022400 { | |
| 694 | − gpio-controller; | |
| 695 | − #gpio-cells = <2>; | |
| 696 | − interrupt-controller; | |
| 697 | − #interrupt-cells = <2>; | |
| 698 | − reg = <0x2400 0x400>; | |
| 699 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOJ)>; | |
| 700 | − st,bank-name = "GPIOJ"; | |
| 701 | − }; | |
| 702 | − | |
| 703 | − gpiok: gpio@40022800 { | |
| 704 | − gpio-controller; | |
| 705 | − #gpio-cells = <2>; | |
| 706 | − interrupt-controller; | |
| 707 | − #interrupt-cells = <2>; | |
| 708 | − reg = <0x2800 0x400>; | |
| 709 | − clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOK)>; | |
| 710 | − st,bank-name = "GPIOK"; | |
| 711 | − }; | |
| 712 | − | |
| 713 | − usart1_pins_a: usart1@0 { | |
| 714 | − pins1 { | |
| 715 | − pinmux = <STM32F429_PA9_FUNC_USART1_TX>; | |
| 716 | − bias-disable; | |
| 717 | − drive-push-pull; | |
| 718 | − slew-rate = <0>; | |
| 719 | − }; | |
| 720 | − pins2 { | |
| 721 | − pinmux = <STM32F429_PA10_FUNC_USART1_RX>; | |
| 722 | − bias-disable; | |
| 723 | − }; | |
| 724 | − }; | |
| 725 | − | |
| 726 | − usart3_pins_a: usart3@0 { | |
| 727 | − pins1 { | |
| 728 | − pinmux = <STM32F429_PB10_FUNC_USART3_TX>; | |
| 729 | − bias-disable; | |
| 730 | − drive-push-pull; | |
| 731 | − slew-rate = <0>; | |
| 732 | − }; | |
| 733 | − pins2 { | |
| 734 | − pinmux = <STM32F429_PB11_FUNC_USART3_RX>; | |
| 735 | − bias-disable; | |
| 736 | − }; | |
| 737 | − }; | |
| 738 | − | |
| 739 | − usbotg_fs_pins_a: usbotg_fs@0 { | |
| 740 | − pins { | |
| 741 | − pinmux = <STM32F429_PA10_FUNC_OTG_FS_ID>, | |
| 742 | − <STM32F429_PA11_FUNC_OTG_FS_DM>, | |
| 743 | − <STM32F429_PA12_FUNC_OTG_FS_DP>; | |
| 744 | − bias-disable; | |
| 745 | − drive-push-pull; | |
| 746 | − slew-rate = <2>; | |
| 747 | − }; | |
| 748 | − }; | |
| 749 | − | |
| 750 | − usbotg_fs_pins_b: usbotg_fs@1 { | |
| 751 | − pins { | |
| 752 | − pinmux = <STM32F429_PB12_FUNC_OTG_HS_ID>, | |
| 753 | − <STM32F429_PB14_FUNC_OTG_HS_DM>, | |
| 754 | − <STM32F429_PB15_FUNC_OTG_HS_DP>; | |
| 755 | − bias-disable; | |
| 756 | − drive-push-pull; | |
| 757 | − slew-rate = <2>; | |
| 758 | − }; | |
| 759 | − }; | |
| 760 | − | |
| 761 | − usbotg_hs_pins_a: usbotg_hs@0 { | |
| 762 | − pins { | |
| 763 | − pinmux = <STM32F429_PH4_FUNC_OTG_HS_ULPI_NXT>, | |
| 764 | − <STM32F429_PI11_FUNC_OTG_HS_ULPI_DIR>, | |
| 765 | − <STM32F429_PC0_FUNC_OTG_HS_ULPI_STP>, | |
| 766 | − <STM32F429_PA5_FUNC_OTG_HS_ULPI_CK>, | |
| 767 | − <STM32F429_PA3_FUNC_OTG_HS_ULPI_D0>, | |
| 768 | − <STM32F429_PB0_FUNC_OTG_HS_ULPI_D1>, | |
| 769 | − <STM32F429_PB1_FUNC_OTG_HS_ULPI_D2>, | |
| 770 | − <STM32F429_PB10_FUNC_OTG_HS_ULPI_D3>, | |
| 771 | − <STM32F429_PB11_FUNC_OTG_HS_ULPI_D4>, | |
| 772 | − <STM32F429_PB12_FUNC_OTG_HS_ULPI_D5>, | |
| 773 | − <STM32F429_PB13_FUNC_OTG_HS_ULPI_D6>, | |
| 774 | − <STM32F429_PB5_FUNC_OTG_HS_ULPI_D7>; | |
| 775 | − bias-disable; | |
| 776 | − drive-push-pull; | |
| 777 | − slew-rate = <2>; | |
| 778 | − }; | |
| 779 | − }; | |
| 780 | − | |
| 781 | − ethernet_mii: mii@0 { | |
| 782 | − pins { | |
| 783 | − pinmux = <STM32F429_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0>, | |
| 784 | − <STM32F429_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1>, | |
| 785 | − <STM32F429_PC2_FUNC_ETH_MII_TXD2>, | |
| 786 | − <STM32F429_PB8_FUNC_ETH_MII_TXD3>, | |
| 787 | − <STM32F429_PC3_FUNC_ETH_MII_TX_CLK>, | |
| 788 | − <STM32F429_PG11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN>, | |
| 789 | − <STM32F429_PA2_FUNC_ETH_MDIO>, | |
| 790 | − <STM32F429_PC1_FUNC_ETH_MDC>, | |
| 791 | − <STM32F429_PA1_FUNC_ETH_MII_RX_CLK_ETH_RMII_REF_CLK>, | |
| 792 | − <STM32F429_PA7_FUNC_ETH_MII_RX_DV_ETH_RMII_CRS_DV>, | |
| 793 | − <STM32F429_PC4_FUNC_ETH_MII_RXD0_ETH_RMII_RXD0>, | |
| 794 | − <STM32F429_PC5_FUNC_ETH_MII_RXD1_ETH_RMII_RXD1>, | |
| 795 | − <STM32F429_PH6_FUNC_ETH_MII_RXD2>, | |
| 796 | − <STM32F429_PH7_FUNC_ETH_MII_RXD3>; | |
| 797 | − slew-rate = <2>; | |
| 798 | − }; | |
| 799 | − }; | |
| 800 | − | |
| 801 | − adc3_in8_pin: adc@200 { | |
| 802 | − pins { | |
| 803 | − pinmux = <STM32F429_PF10_FUNC_ANALOG>; | |
| 804 | − }; | |
| 805 | − }; | |
| 806 | − | |
| 807 | − pwm1_pins: pwm@1 { | |
| 808 | − pins { | |
| 809 | − pinmux = <STM32F429_PA8_FUNC_TIM1_CH1>, | |
| 810 | − <STM32F429_PB13_FUNC_TIM1_CH1N>, | |
| 811 | − <STM32F429_PB12_FUNC_TIM1_BKIN>; | |
| 812 | − }; | |
| 813 | − }; | |
| 814 | − | |
| 815 | − pwm3_pins: pwm@3 { | |
| 816 | − pins { | |
| 817 | − pinmux = <STM32F429_PB4_FUNC_TIM3_CH1>, | |
| 818 | − <STM32F429_PB5_FUNC_TIM3_CH2>; | |
| 819 | − }; | |
| 820 | − }; | |
| 821 | − | |
| 822 | − i2c1_pins: i2c1@0 { | |
| 823 | − pins { | |
| 824 | − pinmux = <STM32F429_PB9_FUNC_I2C1_SDA>, | |
| 825 | − <STM32F429_PB6_FUNC_I2C1_SCL>; | |
| 826 | − bias-disable; | |
| 827 | − drive-open-drain; | |
| 828 | − slew-rate = <3>; | |
| 829 | − }; | |
| 830 | − }; | |
| 831 | − | |
| 832 | − ltdc_pins: ltdc@0 { | |
| 833 | − pins { | |
| 834 | − pinmux = <STM32F429_PI12_FUNC_LCD_HSYNC>, | |
| 835 | − <STM32F429_PI13_FUNC_LCD_VSYNC>, | |
| 836 | − <STM32F429_PI14_FUNC_LCD_CLK>, | |
| 837 | − <STM32F429_PI15_FUNC_LCD_R0>, | |
| 838 | − <STM32F429_PJ0_FUNC_LCD_R1>, | |
| 839 | − <STM32F429_PJ1_FUNC_LCD_R2>, | |
| 840 | − <STM32F429_PJ2_FUNC_LCD_R3>, | |
| 841 | − <STM32F429_PJ3_FUNC_LCD_R4>, | |
| 842 | − <STM32F429_PJ4_FUNC_LCD_R5>, | |
| 843 | − <STM32F429_PJ5_FUNC_LCD_R6>, | |
| 844 | − <STM32F429_PJ6_FUNC_LCD_R7>, | |
| 845 | − <STM32F429_PJ7_FUNC_LCD_G0>, | |
| 846 | − <STM32F429_PJ8_FUNC_LCD_G1>, | |
| 847 | − <STM32F429_PJ9_FUNC_LCD_G2>, | |
| 848 | − <STM32F429_PJ10_FUNC_LCD_G3>, | |
| 849 | − <STM32F429_PJ11_FUNC_LCD_G4>, | |
| 850 | − <STM32F429_PJ12_FUNC_LCD_B0>, | |
| 851 | − <STM32F429_PJ13_FUNC_LCD_B1>, | |
| 852 | − <STM32F429_PJ14_FUNC_LCD_B2>, | |
| 853 | − <STM32F429_PJ15_FUNC_LCD_B3>, | |
| 854 | − <STM32F429_PK0_FUNC_LCD_G5>, | |
| 855 | − <STM32F429_PK1_FUNC_LCD_G6>, | |
| 856 | − <STM32F429_PK2_FUNC_LCD_G7>, | |
| 857 | − <STM32F429_PK3_FUNC_LCD_B4>, | |
| 858 | − <STM32F429_PK4_FUNC_LCD_B5>, | |
| 859 | − <STM32F429_PK5_FUNC_LCD_B6>, | |
| 860 | − <STM32F429_PK6_FUNC_LCD_B7>, | |
| 861 | − <STM32F429_PK7_FUNC_LCD_DE>; | |
| 862 | − slew-rate = <2>; | |
| 863 | − }; | |
| 864 | − }; | |
| 865 | − | |
| 866 | − dcmi_pins: dcmi@0 { | |
| 867 | − pins { | |
| 868 | − pinmux = <STM32F429_PA4_FUNC_DCMI_HSYNC>, | |
| 869 | − <STM32F429_PB7_FUNC_DCMI_VSYNC>, | |
| 870 | − <STM32F429_PA6_FUNC_DCMI_PIXCLK>, | |
| 871 | − <STM32F429_PC6_FUNC_DCMI_D0>, | |
| 872 | − <STM32F429_PC7_FUNC_DCMI_D1>, | |
| 873 | − <STM32F429_PC8_FUNC_DCMI_D2>, | |
| 874 | − <STM32F429_PC9_FUNC_DCMI_D3>, | |
| 875 | − <STM32F429_PC11_FUNC_DCMI_D4>, | |
| 876 | − <STM32F429_PD3_FUNC_DCMI_D5>, | |
| 877 | − <STM32F429_PB8_FUNC_DCMI_D6>, | |
| 878 | − <STM32F429_PE6_FUNC_DCMI_D7>, | |
| 879 | − <STM32F429_PC10_FUNC_DCMI_D8>, | |
| 880 | − <STM32F429_PC12_FUNC_DCMI_D9>, | |
| 881 | − <STM32F429_PD6_FUNC_DCMI_D10>, | |
| 882 | − <STM32F429_PD2_FUNC_DCMI_D11>; | |
| 883 | − bias-disable; | |
| 884 | − drive-push-pull; | |
| 885 | − slew-rate = <3>; | |
| 886 | − }; | |
| 887 | − }; | |
| 888 | − }; | |
| 889 | − | |
| 890 | 593 | crc: crc@40023000 { |
| 891 | 594 | compatible = "st,stm32f4-crc"; |
| 892 | 595 | reg = <0x40023000 0x400>; |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | /dts-v1/; |
| 49 | 49 | #include "stm32f429.dtsi" |
| 50 | +#include "stm32f469-pinctrl.dtsi" | |
| 50 | 51 | |
| 51 | 52 | / { |
| 52 | 53 | model = "STMicroelectronics STM32F469i-DISCO board"; |
| @@ -0,0 +1,96 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2017 - Alexandre Torgue <alexandre.torgue@st.com> | |
| 3 | + * | |
| 4 | + * This file is dual-licensed: you can use it either under the terms | |
| 5 | + * of the GPL or the X11 license, at your option. Note that this dual | |
| 6 | + * licensing only applies to this file, and not this project as a | |
| 7 | + * whole. | |
| 8 | + * | |
| 9 | + * a) This file is free software; you can redistribute it and/or | |
| 10 | + * modify it under the terms of the GNU General Public License as | |
| 11 | + * published by the Free Software Foundation; either version 2 of the | |
| 12 | + * License, or (at your option) any later version. | |
| 13 | + * | |
| 14 | + * This file is distributed in the hope that it will be useful, | |
| 15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 | + * GNU General Public License for more details. | |
| 18 | + * | |
| 19 | + * Or, alternatively, | |
| 20 | + * | |
| 21 | + * b) Permission is hereby granted, free of charge, to any person | |
| 22 | + * obtaining a copy of this software and associated documentation | |
| 23 | + * files (the "Software"), to deal in the Software without | |
| 24 | + * restriction, including without limitation the rights to use, | |
| 25 | + * copy, modify, merge, publish, distribute, sublicense, and/or | |
| 26 | + * sell copies of the Software, and to permit persons to whom the | |
| 27 | + * Software is furnished to do so, subject to the following | |
| 28 | + * conditions: | |
| 29 | + * | |
| 30 | + * The above copyright notice and this permission notice shall be | |
| 31 | + * included in all copies or substantial portions of the Software. | |
| 32 | + * | |
| 33 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 34 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
| 35 | + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| 36 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
| 37 | + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
| 38 | + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 39 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 40 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 41 | + */ | |
| 42 | + | |
| 43 | +#include "stm32f4-pinctrl.dtsi" | |
| 44 | + | |
| 45 | +/ { | |
| 46 | + soc { | |
| 47 | + pinctrl: pin-controller { | |
| 48 | + compatible = "st,stm32f469-pinctrl"; | |
| 49 | + | |
| 50 | + gpioa: gpio@40020000 { | |
| 51 | + gpio-ranges = <&pinctrl 0 0 16>; | |
| 52 | + }; | |
| 53 | + | |
| 54 | + gpiob: gpio@40020400 { | |
| 55 | + gpio-ranges = <&pinctrl 0 16 16>; | |
| 56 | + }; | |
| 57 | + | |
| 58 | + gpioc: gpio@40020800 { | |
| 59 | + gpio-ranges = <&pinctrl 0 32 16>; | |
| 60 | + }; | |
| 61 | + | |
| 62 | + gpiod: gpio@40020c00 { | |
| 63 | + gpio-ranges = <&pinctrl 0 48 16>; | |
| 64 | + }; | |
| 65 | + | |
| 66 | + gpioe: gpio@40021000 { | |
| 67 | + gpio-ranges = <&pinctrl 0 64 16>; | |
| 68 | + }; | |
| 69 | + | |
| 70 | + gpiof: gpio@40021400 { | |
| 71 | + gpio-ranges = <&pinctrl 0 80 16>; | |
| 72 | + }; | |
| 73 | + | |
| 74 | + gpiog: gpio@40021800 { | |
| 75 | + gpio-ranges = <&pinctrl 0 96 16>; | |
| 76 | + }; | |
| 77 | + | |
| 78 | + gpioh: gpio@40021c00 { | |
| 79 | + gpio-ranges = <&pinctrl 0 112 16>; | |
| 80 | + }; | |
| 81 | + | |
| 82 | + gpioi: gpio@40022000 { | |
| 83 | + gpio-ranges = <&pinctrl 0 128 16>; | |
| 84 | + }; | |
| 85 | + | |
| 86 | + gpioj: gpio@40022400 { | |
| 87 | + gpio-ranges = <&pinctrl 0 144 6>, | |
| 88 | + <&pinctrl 12 156 4>; | |
| 89 | + }; | |
| 90 | + | |
| 91 | + gpiok: gpio@40022800 { | |
| 92 | + gpio-ranges = <&pinctrl 3 163 5>; | |
| 93 | + }; | |
| 94 | + }; | |
| 95 | + }; | |
| 96 | +}; | |
| @@ -32,6 +32,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 · 31 unmodified lines | ||
| 32 | 32 | CONFIG_BLK_DEV_SD=y |
| 33 | 33 | # CONFIG_SCSI_LOWLEVEL is not set |
| 34 | 34 | CONFIG_ATA=y |
| 35 | +CONFIG_PATA_FTIDE010=y | |
| 35 | 36 | CONFIG_INPUT_EVDEV=y |
| 36 | 37 | CONFIG_KEYBOARD_GPIO=y |
| 37 | 38 | # CONFIG_INPUT_MOUSE is not set |
| @@ -55,8 +56,8 @@ CONFIG_LEDS_GPIO=y · 17 unmodified lines | ||
| 55 | 56 | CONFIG_LEDS_TRIGGERS=y |
| 56 | 57 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
| 57 | 58 | CONFIG_RTC_CLASS=y |
| 58 | −CONFIG_RTC_DRV_GEMINI=y | |
| 59 | 59 | CONFIG_DMADEVICES=y |
| 60 | +CONFIG_AMBA_PL08X=y | |
| 60 | 61 | # CONFIG_DNOTIFY is not set |
| 61 | 62 | CONFIG_TMPFS=y |
| 62 | 63 | CONFIG_TMPFS_POSIX_ACL=y |
| @@ -471,7 +471,7 @@ CONFIG_LCD_PLATFORM=m · 470 unmodified lines | ||
| 471 | 471 | CONFIG_LCD_TOSA=m |
| 472 | 472 | CONFIG_BACKLIGHT_PWM=m |
| 473 | 473 | CONFIG_BACKLIGHT_TOSA=m |
| 474 | −CONFIG_FRAMEBUFFER_CONSOLE=m | |
| 474 | +CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 475 | 475 | CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y |
| 476 | 476 | CONFIG_LOGO=y |
| 477 | 477 | CONFIG_SOUND=m |
| @@ -113,7 +113,7 @@ CONFIG_FB_PXA_PARAMETERS=y · 112 unmodified lines | ||
| 113 | 113 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
| 114 | 114 | CONFIG_BACKLIGHT_PWM=m |
| 115 | 115 | # CONFIG_VGA_CONSOLE is not set |
| 116 | −CONFIG_FRAMEBUFFER_CONSOLE=m | |
| 116 | +CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 117 | 117 | CONFIG_LOGO=y |
| 118 | 118 | CONFIG_SOUND=m |
| 119 | 119 | CONFIG_SND=m |
| @@ -112,7 +112,7 @@ CONFIG_FB_PXA=m · 111 unmodified lines | ||
| 112 | 112 | CONFIG_FB_PXA_PARAMETERS=y |
| 113 | 113 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
| 114 | 114 | # CONFIG_VGA_CONSOLE is not set |
| 115 | −CONFIG_FRAMEBUFFER_CONSOLE=m | |
| 115 | +CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 116 | 116 | CONFIG_LOGO=y |
| 117 | 117 | CONFIG_SOUND=m |
| 118 | 118 | CONFIG_SND=m |
| @@ -139,11 +139,10 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, · 138 unmodified lines | ||
| 139 | 139 | #define TIF_NEED_RESCHED 1 /* rescheduling necessary */ |
| 140 | 140 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ |
| 141 | 141 | #define TIF_UPROBE 3 /* breakpointed or singlestepping */ |
| 142 | −#define TIF_FSCHECK 4 /* Check FS is USER_DS on return */ | |
| 143 | −#define TIF_SYSCALL_TRACE 5 /* syscall trace active */ | |
| 144 | −#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */ | |
| 145 | −#define TIF_SYSCALL_TRACEPOINT 7 /* syscall tracepoint instrumentation */ | |
| 146 | −#define TIF_SECCOMP 8 /* seccomp syscall filtering active */ | |
| 142 | +#define TIF_SYSCALL_TRACE 4 /* syscall trace active */ | |
| 143 | +#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ | |
| 144 | +#define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ | |
| 145 | +#define TIF_SECCOMP 7 /* seccomp syscall filtering active */ | |
| 147 | 146 | |
| 148 | 147 | #define TIF_NOHZ 12 /* in adaptive nohz mode */ |
| 149 | 148 | #define TIF_USING_IWMMXT 17 |
| @@ -154,7 +153,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, · 4 unmodified lines | ||
| 154 | 153 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) |
| 155 | 154 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) |
| 156 | 155 | #define _TIF_UPROBE (1 << TIF_UPROBE) |
| 157 | −#define _TIF_FSCHECK (1 << TIF_FSCHECK) | |
| 158 | 156 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
| 159 | 157 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) |
| 160 | 158 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) |
| @@ -168,9 +166,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, · 7 unmodified lines | ||
| 168 | 166 | /* |
| 169 | 167 | * Change these and you break ASM code in entry-common.S |
| 170 | 168 | */ |
| 171 | −#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ | |
| 172 | − _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ | |
| 173 | − _TIF_FSCHECK) | |
| 169 | +#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ | |
| 170 | + _TIF_NOTIFY_RESUME | _TIF_UPROBE) | |
| 174 | 171 | |
| 175 | 172 | #endif /* __KERNEL__ */ |
| 176 | 173 | #endif /* __ASM_ARM_THREAD_INFO_H */ |
| @@ -70,8 +70,6 @@ static inline void set_fs(mm_segment_t fs) · 69 unmodified lines | ||
| 70 | 70 | { |
| 71 | 71 | current_thread_info()->addr_limit = fs; |
| 72 | 72 | modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER); |
| 73 | − /* On user-mode return, check fs is correct */ | |
| 74 | − set_thread_flag(TIF_FSCHECK); | |
| 75 | 73 | } |
| 76 | 74 | |
| 77 | 75 | #define segment_eq(a, b) ((a) == (b)) |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <asm/unistd.h> |
| 13 | 13 | #include <asm/ftrace.h> |
| 14 | 14 | #include <asm/unwind.h> |
| 15 | +#include <asm/memory.h> | |
| 15 | 16 | #ifdef CONFIG_AEABI |
| 16 | 17 | #include <asm/unistd-oabi.h> |
| 17 | 18 | #endif |
| @@ -48,12 +49,14 @@ ret_fast_syscall: · 30 unmodified lines | ||
| 48 | 49 | UNWIND(.fnstart ) |
| 49 | 50 | UNWIND(.cantunwind ) |
| 50 | 51 | disable_irq_notrace @ disable interrupts |
| 52 | + ldr r2, [tsk, #TI_ADDR_LIMIT] | |
| 53 | + cmp r2, #TASK_SIZE | |
| 54 | + blne addr_limit_check_failed | |
| 51 | 55 | ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing |
| 52 | − tst r1, #_TIF_SYSCALL_WORK | |
| 53 | − bne fast_work_pending | |
| 54 | − tst r1, #_TIF_WORK_MASK | |
| 56 | + tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK | |
| 55 | 57 | bne fast_work_pending |
| 56 | 58 | |
| 59 | + | |
| 57 | 60 | /* perform architecture specific actions before user return */ |
| 58 | 61 | arch_ret_to_user r1, lr |
| 59 | 62 | |
| @@ -76,16 +79,16 @@ ret_fast_syscall: · 16 unmodified lines | ||
| 76 | 79 | UNWIND(.cantunwind ) |
| 77 | 80 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 |
| 78 | 81 | disable_irq_notrace @ disable interrupts |
| 82 | + ldr r2, [tsk, #TI_ADDR_LIMIT] | |
| 83 | + cmp r2, #TASK_SIZE | |
| 84 | + blne addr_limit_check_failed | |
| 79 | 85 | ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing |
| 80 | − tst r1, #_TIF_SYSCALL_WORK | |
| 81 | − bne fast_work_pending | |
| 82 | − tst r1, #_TIF_WORK_MASK | |
| 86 | + tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK | |
| 83 | 87 | beq no_work_pending |
| 84 | 88 | UNWIND(.fnend ) |
| 85 | 89 | ENDPROC(ret_fast_syscall) |
| 86 | 90 | |
| 87 | 91 | /* Slower path - fall through to work_pending */ |
| 88 | −fast_work_pending: | |
| 89 | 92 | #endif |
| 90 | 93 | |
| 91 | 94 | tst r1, #_TIF_SYSCALL_WORK |
| @@ -111,6 +114,9 @@ ENTRY(ret_to_user) · 19 unmodified lines | ||
| 111 | 114 | ret_slow_syscall: |
| 112 | 115 | disable_irq_notrace @ disable interrupts |
| 113 | 116 | ENTRY(ret_to_user_from_irq) |
| 117 | + ldr r2, [tsk, #TI_ADDR_LIMIT] | |
| 118 | + cmp r2, #TASK_SIZE | |
| 119 | + blne addr_limit_check_failed | |
| 114 | 120 | ldr r1, [tsk, #TI_FLAGS] |
| 115 | 121 | tst r1, #_TIF_WORK_MASK |
| 116 | 122 | bne slow_work_pending |
| @@ -614,10 +614,6 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) · 613 unmodified lines | ||
| 614 | 614 | * Update the trace code with the current status. |
| 615 | 615 | */ |
| 616 | 616 | trace_hardirqs_off(); |
| 617 | − | |
| 618 | − /* Check valid user FS if needed */ | |
| 619 | − addr_limit_user_check(); | |
| 620 | − | |
| 621 | 617 | do { |
| 622 | 618 | if (likely(thread_flags & _TIF_NEED_RESCHED)) { |
| 623 | 619 | schedule(); |
| @@ -678,3 +674,9 @@ struct page *get_signal_page(void) · 54 unmodified lines | ||
| 678 | 674 | |
| 679 | 675 | return page; |
| 680 | 676 | } |
| 677 | + | |
| 678 | +/* Defer to generic check */ | |
| 679 | +asmlinkage void addr_limit_check_failed(void) | |
| 680 | +{ | |
| 681 | + addr_limit_user_check(); | |
| 682 | +} | |
| @@ -533,8 +533,8 @@ static void __init at91_pm_backup_init(void) · 532 unmodified lines | ||
| 533 | 533 | } |
| 534 | 534 | |
| 535 | 535 | pm_bu->suspended = 0; |
| 536 | − pm_bu->canary = virt_to_phys(&canary); | |
| 537 | − pm_bu->resume = virt_to_phys(cpu_resume); | |
| 536 | + pm_bu->canary = __pa_symbol(&canary); | |
| 537 | + pm_bu->resume = __pa_symbol(cpu_resume); | |
| 538 | 538 | |
| 539 | 539 | return; |
| 540 | 540 | |
| @@ -58,10 +58,10 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) · 57 unmodified lines | ||
| 58 | 58 | struct platform_device *pdev; |
| 59 | 59 | int res; |
| 60 | 60 | |
| 61 | − if (omap_hsmmc_done != 1) | |
| 61 | + if (omap_hsmmc_done) | |
| 62 | 62 | return; |
| 63 | 63 | |
| 64 | − omap_hsmmc_done++; | |
| 64 | + omap_hsmmc_done = 1; | |
| 65 | 65 | |
| 66 | 66 | for (; c->mmc; c++) { |
| 67 | 67 | pdev = c->pdev; |
| @@ -839,6 +839,7 @@ static struct omap_hwmod dra7xx_gpio1_hwmod = { · 838 unmodified lines | ||
| 839 | 839 | .name = "gpio1", |
| 840 | 840 | .class = &dra7xx_gpio_hwmod_class, |
| 841 | 841 | .clkdm_name = "wkupaon_clkdm", |
| 842 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 842 | 843 | .main_clk = "wkupaon_iclk_mux", |
| 843 | 844 | .prcm = { |
| 844 | 845 | .omap4 = { |
| @@ -50,17 +50,22 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables · 49 unmodified lines | ||
| 50 | 50 | KBUILD_CFLAGS += $(call cc-option, -mpc-relative-literal-loads) |
| 51 | 51 | KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) |
| 52 | 52 | |
| 53 | +KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) | |
| 54 | +KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) | |
| 55 | + | |
| 53 | 56 | ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) |
| 54 | 57 | KBUILD_CPPFLAGS += -mbig-endian |
| 55 | 58 | CHECKFLAGS += -D__AARCH64EB__ |
| 56 | 59 | AS += -EB |
| 57 | 60 | LD += -EB |
| 61 | +LDFLAGS += -maarch64linuxb | |
| 58 | 62 | UTS_MACHINE := aarch64_be |
| 59 | 63 | else |
| 60 | 64 | KBUILD_CPPFLAGS += -mlittle-endian |
| 61 | 65 | CHECKFLAGS += -D__AARCH64EL__ |
| 62 | 66 | AS += -EL |
| 63 | 67 | LD += -EL |
| 68 | +LDFLAGS += -maarch64linux | |
| 64 | 69 | UTS_MACHINE := aarch64 |
| 65 | 70 | endif |
| 66 | 71 | |
| @@ -168,7 +168,8 @@ · 167 unmodified lines | ||
| 168 | 168 | &sd_emmc_a { |
| 169 | 169 | status = "okay"; |
| 170 | 170 | pinctrl-0 = <&sdio_pins>; |
| 171 | − pinctrl-names = "default"; | |
| 171 | + pinctrl-1 = <&sdio_clk_gate_pins>; | |
| 172 | + pinctrl-names = "default", "clk-gate"; | |
| 172 | 173 | #address-cells = <1>; |
| 173 | 174 | #size-cells = <0>; |
| 174 | 175 | |
| @@ -194,7 +195,8 @@ · 19 unmodified lines | ||
| 194 | 195 | &sd_emmc_b { |
| 195 | 196 | status = "okay"; |
| 196 | 197 | pinctrl-0 = <&sdcard_pins>; |
| 197 | − pinctrl-names = "default"; | |
| 198 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 199 | + pinctrl-names = "default", "clk-gate"; | |
| 198 | 200 | |
| 199 | 201 | bus-width = <4>; |
| 200 | 202 | cap-sd-highspeed; |
| @@ -212,10 +214,10 @@ · 11 unmodified lines | ||
| 212 | 214 | &sd_emmc_c { |
| 213 | 215 | status = "okay"; |
| 214 | 216 | pinctrl-0 = <&emmc_pins>; |
| 215 | − pinctrl-names = "default"; | |
| 217 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 218 | + pinctrl-names = "default", "clk-gate"; | |
| 216 | 219 | |
| 217 | 220 | bus-width = <8>; |
| 218 | − cap-sd-highspeed; | |
| 219 | 221 | cap-mmc-highspeed; |
| 220 | 222 | max-frequency = <200000000>; |
| 221 | 223 | non-removable; |
| @@ -107,6 +107,9 @@ · 106 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | states = <3300000 0>, |
| 109 | 109 | <1800000 1>; |
| 110 | + | |
| 111 | + regulator-settling-time-up-us = <100>; | |
| 112 | + regulator-settling-time-down-us = <5000>; | |
| 110 | 113 | }; |
| 111 | 114 | |
| 112 | 115 | wifi_32k: wifi-32k { |
| @@ -250,7 +253,8 @@ · 137 unmodified lines | ||
| 250 | 253 | &sd_emmc_a { |
| 251 | 254 | status = "okay"; |
| 252 | 255 | pinctrl-0 = <&sdio_pins>, <&sdio_irq_pins>; |
| 253 | − pinctrl-names = "default"; | |
| 256 | + pinctrl-1 = <&sdio_clk_gate_pins>; | |
| 257 | + pinctrl-names = "default", "clk-gate"; | |
| 254 | 258 | #address-cells = <1>; |
| 255 | 259 | #size-cells = <0>; |
| 256 | 260 | |
| @@ -276,11 +280,16 @@ · 19 unmodified lines | ||
| 276 | 280 | &sd_emmc_b { |
| 277 | 281 | status = "okay"; |
| 278 | 282 | pinctrl-0 = <&sdcard_pins>; |
| 279 | − pinctrl-names = "default"; | |
| 283 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 284 | + pinctrl-names = "default", "clk-gate"; | |
| 280 | 285 | |
| 281 | 286 | bus-width = <4>; |
| 282 | 287 | cap-sd-highspeed; |
| 283 | − max-frequency = <100000000>; | |
| 288 | + sd-uhs-sdr12; | |
| 289 | + sd-uhs-sdr25; | |
| 290 | + sd-uhs-sdr50; | |
| 291 | + sd-uhs-sdr104; | |
| 292 | + max-frequency = <200000000>; | |
| 284 | 293 | disable-wp; |
| 285 | 294 | |
| 286 | 295 | cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; |
| @@ -294,10 +303,10 @@ · 7 unmodified lines | ||
| 294 | 303 | &sd_emmc_c { |
| 295 | 304 | status = "disabled"; |
| 296 | 305 | pinctrl-0 = <&emmc_pins>; |
| 297 | − pinctrl-names = "default"; | |
| 306 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 307 | + pinctrl-names = "default", "clk-gate"; | |
| 298 | 308 | |
| 299 | 309 | bus-width = <8>; |
| 300 | − cap-sd-highspeed; | |
| 301 | 310 | max-frequency = <200000000>; |
| 302 | 311 | non-removable; |
| 303 | 312 | disable-wp; |
| @@ -51,7 +51,7 @@ · 50 unmodified lines | ||
| 51 | 51 | / { |
| 52 | 52 | compatible = "nexbox,a95x", "amlogic,meson-gxbb"; |
| 53 | 53 | model = "NEXBOX A95X"; |
| 54 | − | |
| 54 | + | |
| 55 | 55 | aliases { |
| 56 | 56 | serial0 = &uart_AO; |
| 57 | 57 | }; |
| @@ -232,7 +232,8 @@ · 174 unmodified lines | ||
| 232 | 232 | &sd_emmc_a { |
| 233 | 233 | status = "okay"; |
| 234 | 234 | pinctrl-0 = <&sdio_pins>; |
| 235 | − pinctrl-names = "default"; | |
| 235 | + pinctrl-1 = <&sdio_clk_gate_pins>; | |
| 236 | + pinctrl-names = "default", "clk-gate"; | |
| 236 | 237 | #address-cells = <1>; |
| 237 | 238 | #size-cells = <0>; |
| 238 | 239 | |
| @@ -253,7 +254,8 @@ · 14 unmodified lines | ||
| 253 | 254 | &sd_emmc_b { |
| 254 | 255 | status = "okay"; |
| 255 | 256 | pinctrl-0 = <&sdcard_pins>; |
| 256 | − pinctrl-names = "default"; | |
| 257 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 258 | + pinctrl-names = "default", "clk-gate"; | |
| 257 | 259 | |
| 258 | 260 | bus-width = <4>; |
| 259 | 261 | cap-sd-highspeed; |
| @@ -271,10 +273,10 @@ · 11 unmodified lines | ||
| 271 | 273 | &sd_emmc_c { |
| 272 | 274 | status = "okay"; |
| 273 | 275 | pinctrl-0 = <&emmc_pins>; |
| 274 | − pinctrl-names = "default"; | |
| 276 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 277 | + pinctrl-names = "default", "clk-gate"; | |
| 275 | 278 | |
| 276 | 279 | bus-width = <8>; |
| 277 | − cap-sd-highspeed; | |
| 278 | 280 | cap-mmc-highspeed; |
| 279 | 281 | max-frequency = <200000000>; |
| 280 | 282 | non-removable; |
| @@ -50,7 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | / { |
| 51 | 51 | compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; |
| 52 | 52 | model = "Hardkernel ODROID-C2"; |
| 53 | − | |
| 53 | + | |
| 54 | 54 | aliases { |
| 55 | 55 | serial0 = &uart_AO; |
| 56 | 56 | }; |
| @@ -253,7 +253,8 @@ · 196 unmodified lines | ||
| 253 | 253 | &sd_emmc_b { |
| 254 | 254 | status = "okay"; |
| 255 | 255 | pinctrl-0 = <&sdcard_pins>; |
| 256 | − pinctrl-names = "default"; | |
| 256 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 257 | + pinctrl-names = "default", "clk-gate"; | |
| 257 | 258 | |
| 258 | 259 | bus-width = <4>; |
| 259 | 260 | cap-sd-highspeed; |
| @@ -271,10 +272,10 @@ · 11 unmodified lines | ||
| 271 | 272 | &sd_emmc_c { |
| 272 | 273 | status = "okay"; |
| 273 | 274 | pinctrl-0 = <&emmc_pins>; |
| 274 | − pinctrl-names = "default"; | |
| 275 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 276 | + pinctrl-names = "default", "clk-gate"; | |
| 275 | 277 | |
| 276 | 278 | bus-width = <8>; |
| 277 | − cap-sd-highspeed; | |
| 278 | 279 | max-frequency = <200000000>; |
| 279 | 280 | non-removable; |
| 280 | 281 | disable-wp; |
| @@ -194,7 +194,8 @@ · 193 unmodified lines | ||
| 194 | 194 | &sd_emmc_a { |
| 195 | 195 | status = "okay"; |
| 196 | 196 | pinctrl-0 = <&sdio_pins>; |
| 197 | − pinctrl-names = "default"; | |
| 197 | + pinctrl-1 = <&sdio_clk_gate_pins>; | |
| 198 | + pinctrl-names = "default", "clk-gate"; | |
| 198 | 199 | #address-cells = <1>; |
| 199 | 200 | #size-cells = <0>; |
| 200 | 201 | |
| @@ -220,10 +221,14 @@ · 19 unmodified lines | ||
| 220 | 221 | &sd_emmc_b { |
| 221 | 222 | status = "okay"; |
| 222 | 223 | pinctrl-0 = <&sdcard_pins>; |
| 223 | − pinctrl-names = "default"; | |
| 224 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 225 | + pinctrl-names = "default", "clk-gate"; | |
| 224 | 226 | |
| 225 | 227 | bus-width = <4>; |
| 226 | 228 | cap-sd-highspeed; |
| 229 | + sd-uhs-sdr12; | |
| 230 | + sd-uhs-sdr25; | |
| 231 | + sd-uhs-sdr50; | |
| 227 | 232 | max-frequency = <100000000>; |
| 228 | 233 | disable-wp; |
| 229 | 234 | |
| @@ -238,10 +243,10 @@ · 8 unmodified lines | ||
| 238 | 243 | &sd_emmc_c { |
| 239 | 244 | status = "okay"; |
| 240 | 245 | pinctrl-0 = <&emmc_pins>; |
| 241 | − pinctrl-names = "default"; | |
| 246 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 247 | + pinctrl-names = "default", "clk-gate"; | |
| 242 | 248 | |
| 243 | 249 | bus-width = <8>; |
| 244 | − cap-sd-highspeed; | |
| 245 | 250 | cap-mmc-highspeed; |
| 246 | 251 | max-frequency = <200000000>; |
| 247 | 252 | non-removable; |
| @@ -155,7 +155,8 @@ · 154 unmodified lines | ||
| 155 | 155 | &sd_emmc_a { |
| 156 | 156 | status = "okay"; |
| 157 | 157 | pinctrl-0 = <&sdio_pins &sdio_irq_pins>; |
| 158 | − pinctrl-names = "default"; | |
| 158 | + pinctrl-1 = <&sdio_clk_gate_pins>; | |
| 159 | + pinctrl-names = "default", "clk-gate"; | |
| 159 | 160 | #address-cells = <1>; |
| 160 | 161 | #size-cells = <0>; |
| 161 | 162 | |
| @@ -181,7 +182,8 @@ · 19 unmodified lines | ||
| 181 | 182 | &sd_emmc_b { |
| 182 | 183 | status = "okay"; |
| 183 | 184 | pinctrl-0 = <&sdcard_pins>; |
| 184 | − pinctrl-names = "default"; | |
| 185 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 186 | + pinctrl-names = "default", "clk-gate"; | |
| 185 | 187 | |
| 186 | 188 | bus-width = <4>; |
| 187 | 189 | cap-sd-highspeed; |
| @@ -198,10 +200,10 @@ · 10 unmodified lines | ||
| 198 | 200 | &sd_emmc_c { |
| 199 | 201 | status = "okay"; |
| 200 | 202 | pinctrl-0 = <&emmc_pins>; |
| 201 | − pinctrl-names = "default"; | |
| 203 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 204 | + pinctrl-names = "default", "clk-gate"; | |
| 202 | 205 | |
| 203 | 206 | bus-width = <8>; |
| 204 | − cap-sd-highspeed; | |
| 205 | 207 | cap-mmc-highspeed; |
| 206 | 208 | max-frequency = <200000000>; |
| 207 | 209 | non-removable; |
| @@ -392,6 +392,17 @@ · 391 unmodified lines | ||
| 392 | 392 | }; |
| 393 | 393 | }; |
| 394 | 394 | |
| 395 | + emmc_clk_gate_pins: emmc_clk_gate { | |
| 396 | + mux { | |
| 397 | + groups = "BOOT_8"; | |
| 398 | + function = "gpio_periphs"; | |
| 399 | + }; | |
| 400 | + cfg-pull-down { | |
| 401 | + pins = "BOOT_8"; | |
| 402 | + bias-pull-down; | |
| 403 | + }; | |
| 404 | + }; | |
| 405 | + | |
| 395 | 406 | nor_pins: nor { |
| 396 | 407 | mux { |
| 397 | 408 | groups = "nor_d", |
| @@ -430,6 +441,17 @@ · 32 unmodified lines | ||
| 430 | 441 | }; |
| 431 | 442 | }; |
| 432 | 443 | |
| 444 | + sdcard_clk_gate_pins: sdcard_clk_gate { | |
| 445 | + mux { | |
| 446 | + groups = "CARD_2"; | |
| 447 | + function = "gpio_periphs"; | |
| 448 | + }; | |
| 449 | + cfg-pull-down { | |
| 450 | + pins = "CARD_2"; | |
| 451 | + bias-pull-down; | |
| 452 | + }; | |
| 453 | + }; | |
| 454 | + | |
| 433 | 455 | sdio_pins: sdio { |
| 434 | 456 | mux { |
| 435 | 457 | groups = "sdio_d0", |
| @@ -442,6 +464,17 @@ · 6 unmodified lines | ||
| 442 | 464 | }; |
| 443 | 465 | }; |
| 444 | 466 | |
| 467 | + sdio_clk_gate_pins: sdio_clk_gate { | |
| 468 | + mux { | |
| 469 | + groups = "GPIOX_4"; | |
| 470 | + function = "gpio_periphs"; | |
| 471 | + }; | |
| 472 | + cfg-pull-down { | |
| 473 | + pins = "GPIOX_4"; | |
| 474 | + bias-pull-down; | |
| 475 | + }; | |
| 476 | + }; | |
| 477 | + | |
| 445 | 478 | sdio_irq_pins: sdio_irq { |
| 446 | 479 | mux { |
| 447 | 480 | groups = "sdio_irq"; |
| @@ -661,21 +694,21 @@ · 213 unmodified lines | ||
| 661 | 694 | |
| 662 | 695 | &sd_emmc_a { |
| 663 | 696 | clocks = <&clkc CLKID_SD_EMMC_A>, |
| 664 | − <&xtal>, | |
| 697 | + <&clkc CLKID_SD_EMMC_A_CLK0>, | |
| 665 | 698 | <&clkc CLKID_FCLK_DIV2>; |
| 666 | 699 | clock-names = "core", "clkin0", "clkin1"; |
| 667 | 700 | }; |
| 668 | 701 | |
| 669 | 702 | &sd_emmc_b { |
| 670 | 703 | clocks = <&clkc CLKID_SD_EMMC_B>, |
| 671 | − <&xtal>, | |
| 704 | + <&clkc CLKID_SD_EMMC_B_CLK0>, | |
| 672 | 705 | <&clkc CLKID_FCLK_DIV2>; |
| 673 | 706 | clock-names = "core", "clkin0", "clkin1"; |
| 674 | 707 | }; |
| 675 | 708 | |
| 676 | 709 | &sd_emmc_c { |
| 677 | 710 | clocks = <&clkc CLKID_SD_EMMC_C>, |
| 678 | − <&xtal>, | |
| 711 | + <&clkc CLKID_SD_EMMC_C_CLK0>, | |
| 679 | 712 | <&clkc CLKID_FCLK_DIV2>; |
| 680 | 713 | clock-names = "core", "clkin0", "clkin1"; |
| 681 | 714 | }; |
| @@ -123,7 +123,8 @@ · 122 unmodified lines | ||
| 123 | 123 | &sd_emmc_b { |
| 124 | 124 | status = "okay"; |
| 125 | 125 | pinctrl-0 = <&sdcard_pins>; |
| 126 | − pinctrl-names = "default"; | |
| 126 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 127 | + pinctrl-names = "default", "clk-gate"; | |
| 127 | 128 | |
| 128 | 129 | bus-width = <4>; |
| 129 | 130 | cap-sd-highspeed; |
| @@ -141,10 +142,10 @@ · 11 unmodified lines | ||
| 141 | 142 | &sd_emmc_c { |
| 142 | 143 | status = "okay"; |
| 143 | 144 | pinctrl-0 = <&emmc_pins>; |
| 144 | − pinctrl-names = "default"; | |
| 145 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 146 | + pinctrl-names = "default", "clk-gate"; | |
| 145 | 147 | |
| 146 | 148 | bus-width = <8>; |
| 147 | − cap-sd-highspeed; | |
| 148 | 149 | cap-mmc-highspeed; |
| 149 | 150 | max-frequency = <100000000>; |
| 150 | 151 | non-removable; |
| @@ -91,6 +91,9 @@ · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | states = <3300000 0>, |
| 93 | 93 | <1800000 1>; |
| 94 | + | |
| 95 | + regulator-settling-time-up-us = <200>; | |
| 96 | + regulator-settling-time-down-us = <50000>; | |
| 94 | 97 | }; |
| 95 | 98 | |
| 96 | 99 | vddio_boot: regulator-vddio_boot { |
| @@ -197,10 +200,14 @@ · 100 unmodified lines | ||
| 197 | 200 | &sd_emmc_b { |
| 198 | 201 | status = "okay"; |
| 199 | 202 | pinctrl-0 = <&sdcard_pins>; |
| 200 | − pinctrl-names = "default"; | |
| 203 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 204 | + pinctrl-names = "default", "clk-gate"; | |
| 201 | 205 | |
| 202 | 206 | bus-width = <4>; |
| 203 | 207 | cap-sd-highspeed; |
| 208 | + sd-uhs-sdr12; | |
| 209 | + sd-uhs-sdr25; | |
| 210 | + sd-uhs-sdr50; | |
| 204 | 211 | max-frequency = <100000000>; |
| 205 | 212 | disable-wp; |
| 206 | 213 | |
| @@ -215,10 +222,12 @@ · 8 unmodified lines | ||
| 215 | 222 | &sd_emmc_c { |
| 216 | 223 | status = "okay"; |
| 217 | 224 | pinctrl-0 = <&emmc_pins>; |
| 218 | − pinctrl-names = "default"; | |
| 225 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 226 | + pinctrl-names = "default", "clk-gate"; | |
| 219 | 227 | |
| 220 | 228 | bus-width = <8>; |
| 221 | 229 | cap-mmc-highspeed; |
| 230 | + mmc-ddr-3_3v; | |
| 222 | 231 | max-frequency = <50000000>; |
| 223 | 232 | non-removable; |
| 224 | 233 | disable-wp; |
| @@ -189,7 +189,8 @@ · 188 unmodified lines | ||
| 189 | 189 | &sd_emmc_a { |
| 190 | 190 | status = "okay"; |
| 191 | 191 | pinctrl-0 = <&sdio_pins>; |
| 192 | − pinctrl-names = "default"; | |
| 192 | + pinctrl-1 = <&sdio_clk_gate_pins>; | |
| 193 | + pinctrl-names = "default", "clk-gate"; | |
| 193 | 194 | #address-cells = <1>; |
| 194 | 195 | #size-cells = <0>; |
| 195 | 196 | |
| @@ -210,7 +211,8 @@ · 14 unmodified lines | ||
| 210 | 211 | &sd_emmc_b { |
| 211 | 212 | status = "okay"; |
| 212 | 213 | pinctrl-0 = <&sdcard_pins>; |
| 213 | − pinctrl-names = "default"; | |
| 214 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 215 | + pinctrl-names = "default", "clk-gate"; | |
| 214 | 216 | |
| 215 | 217 | bus-width = <4>; |
| 216 | 218 | cap-sd-highspeed; |
| @@ -228,10 +230,10 @@ · 11 unmodified lines | ||
| 228 | 230 | &sd_emmc_c { |
| 229 | 231 | status = "okay"; |
| 230 | 232 | pinctrl-0 = <&emmc_pins>; |
| 231 | − pinctrl-names = "default"; | |
| 233 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 234 | + pinctrl-names = "default", "clk-gate"; | |
| 232 | 235 | |
| 233 | 236 | bus-width = <8>; |
| 234 | − cap-sd-highspeed; | |
| 235 | 237 | cap-mmc-highspeed; |
| 236 | 238 | max-frequency = <200000000>; |
| 237 | 239 | non-removable; |
| @@ -95,7 +95,8 @@ · 94 unmodified lines | ||
| 95 | 95 | &sd_emmc_a { |
| 96 | 96 | status = "okay"; |
| 97 | 97 | pinctrl-0 = <&sdio_pins>; |
| 98 | − pinctrl-names = "default"; | |
| 98 | + pinctrl-1 = <&sdio_clk_gate_pins>; | |
| 99 | + pinctrl-names = "default", "clk-gate"; | |
| 99 | 100 | #address-cells = <1>; |
| 100 | 101 | #size-cells = <0>; |
| 101 | 102 | |
| @@ -116,7 +117,8 @@ · 14 unmodified lines | ||
| 116 | 117 | &sd_emmc_b { |
| 117 | 118 | status = "okay"; |
| 118 | 119 | pinctrl-0 = <&sdcard_pins>; |
| 119 | − pinctrl-names = "default"; | |
| 120 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 121 | + pinctrl-names = "default", "clk-gate"; | |
| 120 | 122 | |
| 121 | 123 | bus-width = <4>; |
| 122 | 124 | cap-sd-highspeed; |
| @@ -134,10 +136,10 @@ · 11 unmodified lines | ||
| 134 | 136 | &sd_emmc_c { |
| 135 | 137 | status = "okay"; |
| 136 | 138 | pinctrl-0 = <&emmc_pins>; |
| 137 | − pinctrl-names = "default"; | |
| 139 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 140 | + pinctrl-names = "default", "clk-gate"; | |
| 138 | 141 | |
| 139 | 142 | bus-width = <8>; |
| 140 | − cap-sd-highspeed; | |
| 141 | 143 | cap-mmc-highspeed; |
| 142 | 144 | max-frequency = <200000000>; |
| 143 | 145 | non-removable; |
| @@ -281,6 +281,17 @@ · 280 unmodified lines | ||
| 281 | 281 | }; |
| 282 | 282 | }; |
| 283 | 283 | |
| 284 | + emmc_clk_gate_pins: emmc_clk_gate { | |
| 285 | + mux { | |
| 286 | + groups = "BOOT_8"; | |
| 287 | + function = "gpio_periphs"; | |
| 288 | + }; | |
| 289 | + cfg-pull-down { | |
| 290 | + pins = "BOOT_8"; | |
| 291 | + bias-pull-down; | |
| 292 | + }; | |
| 293 | + }; | |
| 294 | + | |
| 284 | 295 | nor_pins: nor { |
| 285 | 296 | mux { |
| 286 | 297 | groups = "nor_d", |
| @@ -319,6 +330,17 @@ · 32 unmodified lines | ||
| 319 | 330 | }; |
| 320 | 331 | }; |
| 321 | 332 | |
| 333 | + sdcard_clk_gate_pins: sdcard_clk_gate { | |
| 334 | + mux { | |
| 335 | + groups = "CARD_2"; | |
| 336 | + function = "gpio_periphs"; | |
| 337 | + }; | |
| 338 | + cfg-pull-down { | |
| 339 | + pins = "CARD_2"; | |
| 340 | + bias-pull-down; | |
| 341 | + }; | |
| 342 | + }; | |
| 343 | + | |
| 322 | 344 | sdio_pins: sdio { |
| 323 | 345 | mux { |
| 324 | 346 | groups = "sdio_d0", |
| @@ -331,6 +353,17 @@ · 6 unmodified lines | ||
| 331 | 353 | }; |
| 332 | 354 | }; |
| 333 | 355 | |
| 356 | + sdio_clk_gate_pins: sdio_clk_gate { | |
| 357 | + mux { | |
| 358 | + groups = "GPIOX_4"; | |
| 359 | + function = "gpio_periphs"; | |
| 360 | + }; | |
| 361 | + cfg-pull-down { | |
| 362 | + pins = "GPIOX_4"; | |
| 363 | + bias-pull-down; | |
| 364 | + }; | |
| 365 | + }; | |
| 366 | + | |
| 334 | 367 | sdio_irq_pins: sdio_irq { |
| 335 | 368 | mux { |
| 336 | 369 | groups = "sdio_irq"; |
| @@ -603,21 +636,21 @@ · 266 unmodified lines | ||
| 603 | 636 | |
| 604 | 637 | &sd_emmc_a { |
| 605 | 638 | clocks = <&clkc CLKID_SD_EMMC_A>, |
| 606 | − <&xtal>, | |
| 639 | + <&clkc CLKID_SD_EMMC_A_CLK0>, | |
| 607 | 640 | <&clkc CLKID_FCLK_DIV2>; |
| 608 | 641 | clock-names = "core", "clkin0", "clkin1"; |
| 609 | 642 | }; |
| 610 | 643 | |
| 611 | 644 | &sd_emmc_b { |
| 612 | 645 | clocks = <&clkc CLKID_SD_EMMC_B>, |
| 613 | − <&xtal>, | |
| 646 | + <&clkc CLKID_SD_EMMC_B_CLK0>, | |
| 614 | 647 | <&clkc CLKID_FCLK_DIV2>; |
| 615 | 648 | clock-names = "core", "clkin0", "clkin1"; |
| 616 | 649 | }; |
| 617 | 650 | |
| 618 | 651 | &sd_emmc_c { |
| 619 | 652 | clocks = <&clkc CLKID_SD_EMMC_C>, |
| 620 | − <&xtal>, | |
| 653 | + <&clkc CLKID_SD_EMMC_C_CLK0>, | |
| 621 | 654 | <&clkc CLKID_FCLK_DIV2>; |
| 622 | 655 | clock-names = "core", "clkin0", "clkin1"; |
| 623 | 656 | }; |
| @@ -175,7 +175,8 @@ · 174 unmodified lines | ||
| 175 | 175 | &sd_emmc_b { |
| 176 | 176 | status = "okay"; |
| 177 | 177 | pinctrl-0 = <&sdcard_pins>; |
| 178 | − pinctrl-names = "default"; | |
| 178 | + pinctrl-1 = <&sdcard_clk_gate_pins>; | |
| 179 | + pinctrl-names = "default", "clk-gate"; | |
| 179 | 180 | |
| 180 | 181 | bus-width = <4>; |
| 181 | 182 | cap-sd-highspeed; |
| @@ -193,10 +194,10 @@ · 11 unmodified lines | ||
| 193 | 194 | &sd_emmc_c { |
| 194 | 195 | status = "okay"; |
| 195 | 196 | pinctrl-0 = <&emmc_pins>; |
| 196 | − pinctrl-names = "default"; | |
| 197 | + pinctrl-1 = <&emmc_clk_gate_pins>; | |
| 198 | + pinctrl-names = "default", "clk-gate"; | |
| 197 | 199 | |
| 198 | 200 | bus-width = <8>; |
| 199 | − cap-sd-highspeed; | |
| 200 | 201 | cap-mmc-highspeed; |
| 201 | 202 | max-frequency = <200000000>; |
| 202 | 203 | non-removable; |
| @@ -220,7 +220,6 @@ · 219 unmodified lines | ||
| 220 | 220 | pinctrl-names = "default"; |
| 221 | 221 | |
| 222 | 222 | bus-width = <8>; |
| 223 | − cap-sd-highspeed; | |
| 224 | 223 | cap-mmc-highspeed; |
| 225 | 224 | max-frequency = <200000000>; |
| 226 | 225 | non-removable; |
| @@ -254,7 +254,7 @@ · 253 unmodified lines | ||
| 254 | 254 | |
| 255 | 255 | ap_syscon: system-controller@6f4000 { |
| 256 | 256 | compatible = "syscon", "simple-mfd"; |
| 257 | − reg = <0x6f4000 0x1000>; | |
| 257 | + reg = <0x6f4000 0x2000>; | |
| 258 | 258 | |
| 259 | 259 | ap_clk: clock { |
| 260 | 260 | compatible = "marvell,ap806-clock"; |
| @@ -265,7 +265,7 @@ · 4 unmodified lines | ||
| 265 | 265 | compatible = "marvell,ap806-pinctrl"; |
| 266 | 266 | }; |
| 267 | 267 | |
| 268 | − ap_gpio: gpio { | |
| 268 | + ap_gpio: gpio@1040 { | |
| 269 | 269 | compatible = "marvell,armada-8k-gpio"; |
| 270 | 270 | offset = <0x1040>; |
| 271 | 271 | ngpios = <20>; |
| @@ -113,8 +113,7 @@ · 112 unmodified lines | ||
| 113 | 113 | compatible = "arm,cortex-a53", "arm,armv8"; |
| 114 | 114 | reg = <0x0 0x0>; |
| 115 | 115 | enable-method = "psci"; |
| 116 | − clocks = <&cru ARMCLKL>; | |
| 117 | − operating-points-v2 = <&cluster0_opp>; | |
| 116 | + | |
| 118 | 117 | #cooling-cells = <2>; /* min followed by max */ |
| 119 | 118 | }; |
| 120 | 119 | |
| @@ -123,8 +122,6 @@ · 2 unmodified lines | ||
| 123 | 122 | compatible = "arm,cortex-a53", "arm,armv8"; |
| 124 | 123 | reg = <0x0 0x1>; |
| 125 | 124 | enable-method = "psci"; |
| 126 | − clocks = <&cru ARMCLKL>; | |
| 127 | − operating-points-v2 = <&cluster0_opp>; | |
| 128 | 125 | }; |
| 129 | 126 | |
| 130 | 127 | cpu_l2: cpu@2 { |
| @@ -132,8 +129,6 @@ · 1 unmodified line | ||
| 132 | 129 | compatible = "arm,cortex-a53", "arm,armv8"; |
| 133 | 130 | reg = <0x0 0x2>; |
| 134 | 131 | enable-method = "psci"; |
| 135 | − clocks = <&cru ARMCLKL>; | |
| 136 | − operating-points-v2 = <&cluster0_opp>; | |
| 137 | 132 | }; |
| 138 | 133 | |
| 139 | 134 | cpu_l3: cpu@3 { |
| @@ -141,8 +136,6 @@ · 1 unmodified line | ||
| 141 | 136 | compatible = "arm,cortex-a53", "arm,armv8"; |
| 142 | 137 | reg = <0x0 0x3>; |
| 143 | 138 | enable-method = "psci"; |
| 144 | − clocks = <&cru ARMCLKL>; | |
| 145 | − operating-points-v2 = <&cluster0_opp>; | |
| 146 | 139 | }; |
| 147 | 140 | |
| 148 | 141 | cpu_b0: cpu@100 { |
| @@ -150,8 +143,7 @@ · 1 unmodified line | ||
| 150 | 143 | compatible = "arm,cortex-a53", "arm,armv8"; |
| 151 | 144 | reg = <0x0 0x100>; |
| 152 | 145 | enable-method = "psci"; |
| 153 | − clocks = <&cru ARMCLKB>; | |
| 154 | − operating-points-v2 = <&cluster1_opp>; | |
| 146 | + | |
| 155 | 147 | #cooling-cells = <2>; /* min followed by max */ |
| 156 | 148 | }; |
| 157 | 149 | |
| @@ -160,8 +152,6 @@ · 2 unmodified lines | ||
| 160 | 152 | compatible = "arm,cortex-a53", "arm,armv8"; |
| 161 | 153 | reg = <0x0 0x101>; |
| 162 | 154 | enable-method = "psci"; |
| 163 | − clocks = <&cru ARMCLKB>; | |
| 164 | − operating-points-v2 = <&cluster1_opp>; | |
| 165 | 155 | }; |
| 166 | 156 | |
| 167 | 157 | cpu_b2: cpu@102 { |
| @@ -169,8 +159,6 @@ · 1 unmodified line | ||
| 169 | 159 | compatible = "arm,cortex-a53", "arm,armv8"; |
| 170 | 160 | reg = <0x0 0x102>; |
| 171 | 161 | enable-method = "psci"; |
| 172 | − clocks = <&cru ARMCLKB>; | |
| 173 | − operating-points-v2 = <&cluster1_opp>; | |
| 174 | 162 | }; |
| 175 | 163 | |
| 176 | 164 | cpu_b3: cpu@103 { |
| @@ -178,62 +166,6 @@ · 1 unmodified line | ||
| 178 | 166 | compatible = "arm,cortex-a53", "arm,armv8"; |
| 179 | 167 | reg = <0x0 0x103>; |
| 180 | 168 | enable-method = "psci"; |
| 181 | − clocks = <&cru ARMCLKB>; | |
| 182 | − operating-points-v2 = <&cluster1_opp>; | |
| 183 | − }; | |
| 184 | − }; | |
| 185 | − | |
| 186 | − cluster0_opp: opp-table0 { | |
| 187 | − compatible = "operating-points-v2"; | |
| 188 | − opp-shared; | |
| 189 | − | |
| 190 | − opp00 { | |
| 191 | − opp-hz = /bits/ 64 <312000000>; | |
| 192 | − opp-microvolt = <950000>; | |
| 193 | − clock-latency-ns = <40000>; | |
| 194 | − }; | |
| 195 | − opp01 { | |
| 196 | − opp-hz = /bits/ 64 <408000000>; | |
| 197 | − opp-microvolt = <950000>; | |
| 198 | − }; | |
| 199 | − opp02 { | |
| 200 | − opp-hz = /bits/ 64 <600000000>; | |
| 201 | − opp-microvolt = <950000>; | |
| 202 | − }; | |
| 203 | − opp03 { | |
| 204 | − opp-hz = /bits/ 64 <816000000>; | |
| 205 | − opp-microvolt = <1025000>; | |
| 206 | − }; | |
| 207 | − opp04 { | |
| 208 | − opp-hz = /bits/ 64 <1008000000>; | |
| 209 | − opp-microvolt = <1125000>; | |
| 210 | − }; | |
| 211 | − }; | |
| 212 | − | |
| 213 | − cluster1_opp: opp-table1 { | |
| 214 | − compatible = "operating-points-v2"; | |
| 215 | − opp-shared; | |
| 216 | − | |
| 217 | − opp00 { | |
| 218 | − opp-hz = /bits/ 64 <312000000>; | |
| 219 | − opp-microvolt = <950000>; | |
| 220 | − clock-latency-ns = <40000>; | |
| 221 | − }; | |
| 222 | − opp01 { | |
| 223 | − opp-hz = /bits/ 64 <408000000>; | |
| 224 | − opp-microvolt = <950000>; | |
| 225 | − }; | |
| 226 | − opp02 { | |
| 227 | − opp-hz = /bits/ 64 <600000000>; | |
| 228 | − opp-microvolt = <950000>; | |
| 229 | − }; | |
| 230 | − opp03 { | |
| 231 | − opp-hz = /bits/ 64 <816000000>; | |
| 232 | − opp-microvolt = <975000>; | |
| 233 | − }; | |
| 234 | − opp04 { | |
| 235 | − opp-hz = /bits/ 64 <1008000000>; | |
| 236 | − opp-microvolt = <1050000>; | |
| 237 | 169 | }; |
| 238 | 170 | }; |
| 239 | 171 | |
| @@ -1629,9 +1629,9 @@ · 1628 unmodified lines | ||
| 1629 | 1629 | compatible = "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi"; |
| 1630 | 1630 | reg = <0x0 0xff960000 0x0 0x8000>; |
| 1631 | 1631 | interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH 0>; |
| 1632 | − clocks = <&cru SCLK_MIPIDPHY_REF>, <&cru PCLK_MIPI_DSI0>, | |
| 1633 | − <&cru SCLK_DPHY_TX0_CFG>; | |
| 1634 | − clock-names = "ref", "pclk", "phy_cfg"; | |
| 1632 | + clocks = <&cru SCLK_DPHY_PLL>, <&cru PCLK_MIPI_DSI0>, | |
| 1633 | + <&cru SCLK_DPHY_TX0_CFG>, <&cru PCLK_VIO_GRF>; | |
| 1634 | + clock-names = "ref", "pclk", "phy_cfg", "grf"; | |
| 1635 | 1635 | power-domains = <&power RK3399_PD_VIO>; |
| 1636 | 1636 | rockchip,grf = <&grf>; |
| 1637 | 1637 | status = "disabled"; |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | #ifndef __ASM_LINKAGE_H |
| 2 | 2 | #define __ASM_LINKAGE_H |
| 3 | 3 | |
| 4 | −#define __ALIGN .align 4 | |
| 5 | −#define __ALIGN_STR ".align 4" | |
| 4 | +#define __ALIGN .align 2 | |
| 5 | +#define __ALIGN_STR ".align 2" | |
| 6 | 6 | |
| 7 | 7 | #endif |
| @@ -95,16 +95,19 @@ · 94 unmodified lines | ||
| 95 | 95 | #define KERNEL_END _end |
| 96 | 96 | |
| 97 | 97 | /* |
| 98 | − * The size of the KASAN shadow region. This should be 1/8th of the | |
| 99 | − * size of the entire kernel virtual address space. | |
| 98 | + * KASAN requires 1/8th of the kernel virtual address space for the shadow | |
| 99 | + * region. KASAN can bloat the stack significantly, so double the (minimum) | |
| 100 | + * stack size when KASAN is in use. | |
| 100 | 101 | */ |
| 101 | 102 | #ifdef CONFIG_KASAN |
| 102 | 103 | #define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - 3)) |
| 104 | +#define KASAN_THREAD_SHIFT 1 | |
| 103 | 105 | #else |
| 104 | 106 | #define KASAN_SHADOW_SIZE (0) |
| 107 | +#define KASAN_THREAD_SHIFT 0 | |
| 105 | 108 | #endif |
| 106 | 109 | |
| 107 | −#define MIN_THREAD_SHIFT 14 | |
| 110 | +#define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT) | |
| 108 | 111 | |
| 109 | 112 | /* |
| 110 | 113 | * VMAP'd stacks are allocated at page granularity, so we must ensure that such |
| @@ -401,7 +401,7 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd) · 400 unmodified lines | ||
| 401 | 401 | /* Find an entry in the third-level page table. */ |
| 402 | 402 | #define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) |
| 403 | 403 | |
| 404 | −#define pte_offset_phys(dir,addr) (pmd_page_paddr(*(dir)) + pte_index(addr) * sizeof(pte_t)) | |
| 404 | +#define pte_offset_phys(dir,addr) (pmd_page_paddr(READ_ONCE(*(dir))) + pte_index(addr) * sizeof(pte_t)) | |
| 405 | 405 | #define pte_offset_kernel(dir,addr) ((pte_t *)__va(pte_offset_phys((dir), (addr)))) |
| 406 | 406 | |
| 407 | 407 | #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) |
| @@ -649,4 +649,4 @@ static int __init armv8_deprecated_init(void) · 648 unmodified lines | ||
| 649 | 649 | return 0; |
| 650 | 650 | } |
| 651 | 651 | |
| 652 | −late_initcall(armv8_deprecated_init); | |
| 652 | +core_initcall(armv8_deprecated_init); | |
| @@ -1307,4 +1307,4 @@ static int __init enable_mrs_emulation(void) · 1306 unmodified lines | ||
| 1307 | 1307 | return 0; |
| 1308 | 1308 | } |
| 1309 | 1309 | |
| 1310 | −late_initcall(enable_mrs_emulation); | |
| 1310 | +core_initcall(enable_mrs_emulation); | |
| @@ -321,6 +321,8 @@ void kernel_neon_end(void) · 320 unmodified lines | ||
| 321 | 321 | } |
| 322 | 322 | EXPORT_SYMBOL(kernel_neon_end); |
| 323 | 323 | |
| 324 | +#ifdef CONFIG_EFI | |
| 325 | + | |
| 324 | 326 | static DEFINE_PER_CPU(struct fpsimd_state, efi_fpsimd_state); |
| 325 | 327 | static DEFINE_PER_CPU(bool, efi_fpsimd_state_used); |
| 326 | 328 | |
| @@ -370,6 +372,8 @@ void __efi_fpsimd_end(void) · 43 unmodified lines | ||
| 370 | 372 | kernel_neon_end(); |
| 371 | 373 | } |
| 372 | 374 | |
| 375 | +#endif /* CONFIG_EFI */ | |
| 376 | + | |
| 373 | 377 | #endif /* CONFIG_KERNEL_MODE_NEON */ |
| 374 | 378 | |
| 375 | 379 | #ifdef CONFIG_CPU_PM |
| @@ -440,4 +444,4 @@ static int __init fpsimd_init(void) · 64 unmodified lines | ||
| 440 | 444 | |
| 441 | 445 | return 0; |
| 442 | 446 | } |
| 443 | −late_initcall(fpsimd_init); | |
| 447 | +core_initcall(fpsimd_init); | |
| @@ -384,6 +384,7 @@ ENTRY(kimage_vaddr) · 383 unmodified lines | ||
| 384 | 384 | * booted in EL1 or EL2 respectively. |
| 385 | 385 | */ |
| 386 | 386 | ENTRY(el2_setup) |
| 387 | + msr SPsel, #1 // We want to use SP_EL{1,2} | |
| 387 | 388 | mrs x0, CurrentEL |
| 388 | 389 | cmp x0, #CurrentEL_EL2 |
| 389 | 390 | b.eq 1f |
| @@ -751,10 +751,10 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, · 750 unmodified lines | ||
| 751 | 751 | */ |
| 752 | 752 | trace_hardirqs_off(); |
| 753 | 753 | |
| 754 | − /* Check valid user FS if needed */ | |
| 755 | − addr_limit_user_check(); | |
| 756 | − | |
| 757 | 754 | do { |
| 755 | + /* Check valid user FS if needed */ | |
| 756 | + addr_limit_user_check(); | |
| 757 | + | |
| 758 | 758 | if (thread_flags & _TIF_NEED_RESCHED) { |
| 759 | 759 | schedule(); |
| 760 | 760 | } else { |
| @@ -97,7 +97,7 @@ static void data_abort_decode(unsigned int esr) · 96 unmodified lines | ||
| 97 | 97 | (esr & ESR_ELx_SF) >> ESR_ELx_SF_SHIFT, |
| 98 | 98 | (esr & ESR_ELx_AR) >> ESR_ELx_AR_SHIFT); |
| 99 | 99 | } else { |
| 100 | − pr_alert(" ISV = 0, ISS = 0x%08lu\n", esr & ESR_ELx_ISS_MASK); | |
| 100 | + pr_alert(" ISV = 0, ISS = 0x%08lx\n", esr & ESR_ELx_ISS_MASK); | |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | pr_alert(" CM = %lu, WnR = %lu\n", |
| @@ -651,7 +651,7 @@ static const struct fault_info fault_info[] = { · 547 unmodified lines | ||
| 651 | 651 | { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 0 translation fault" }, |
| 652 | 652 | { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" }, |
| 653 | 653 | { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" }, |
| 654 | − { do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" }, | |
| 654 | + { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" }, | |
| 655 | 655 | { do_bad, SIGBUS, 0, "unknown 8" }, |
| 656 | 656 | { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" }, |
| 657 | 657 | { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" }, |
| @@ -92,9 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) · 91 unmodified lines | ||
| 92 | 92 | { |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | −#define copy_segments(tsk, mm) do { } while (0) | |
| 96 | −#define release_segments(mm) do { } while (0) | |
| 97 | − | |
| 98 | 95 | /* |
| 99 | 96 | * saved kernel SP and DP of a blocked thread. |
| 100 | 97 | */ |
| @@ -92,10 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) · 91 unmodified lines | ||
| 92 | 92 | extern asmlinkage void save_user_regs(struct user_context *target); |
| 93 | 93 | extern asmlinkage void *restore_user_regs(const struct user_context *target, ...); |
| 94 | 94 | |
| 95 | −#define copy_segments(tsk, mm) do { } while (0) | |
| 96 | −#define release_segments(mm) do { } while (0) | |
| 97 | −#define forget_segments() do { } while (0) | |
| 98 | − | |
| 99 | 95 | unsigned long get_wchan(struct task_struct *p); |
| 100 | 96 | |
| 101 | 97 | #define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) |
| @@ -194,6 +194,10 @@ config TIMER_DIVIDE · 193 unmodified lines | ||
| 194 | 194 | int "Timer divider (integer)" |
| 195 | 195 | default "128" |
| 196 | 196 | |
| 197 | +config CPU_BIG_ENDIAN | |
| 198 | + bool "Generate big endian code" | |
| 199 | + default n | |
| 200 | + | |
| 197 | 201 | config CPU_LITTLE_ENDIAN |
| 198 | 202 | bool "Generate little endian code" |
| 199 | 203 | default n |
| @@ -118,14 +118,6 @@ struct mm_struct; · 117 unmodified lines | ||
| 118 | 118 | /* Free all resources held by a thread. */ |
| 119 | 119 | extern void release_thread(struct task_struct *); |
| 120 | 120 | |
| 121 | −/* Copy and release all segment info associated with a VM */ | |
| 122 | −extern void copy_segments(struct task_struct *p, struct mm_struct * mm); | |
| 123 | −extern void release_segments(struct mm_struct * mm); | |
| 124 | − | |
| 125 | −/* Copy and release all segment info associated with a VM */ | |
| 126 | −#define copy_segments(p, mm) do { } while (0) | |
| 127 | −#define release_segments(mm) do { } while (0) | |
| 128 | − | |
| 129 | 121 | unsigned long get_wchan(struct task_struct *p); |
| 130 | 122 | #define KSTK_EIP(tsk) ((tsk)->thread.lr) |
| 131 | 123 | #define KSTK_ESP(tsk) ((tsk)->thread.sp) |
| @@ -114,6 +114,15 @@ static void set_eit_vector_entries(void) · 113 unmodified lines | ||
| 114 | 114 | _flush_cache_copyback_all(); |
| 115 | 115 | } |
| 116 | 116 | |
| 117 | +void abort(void) | |
| 118 | +{ | |
| 119 | + BUG(); | |
| 120 | + | |
| 121 | + /* if that doesn't kill us, halt */ | |
| 122 | + panic("Oops failed to kill thread"); | |
| 123 | +} | |
| 124 | +EXPORT_SYMBOL(abort); | |
| 125 | + | |
| 117 | 126 | void __init trap_init(void) |
| 118 | 127 | { |
| 119 | 128 | set_eit_vector_entries(); |
| @@ -131,9 +131,6 @@ static inline void release_thread(struct task_struct *dead_task) · 130 unmodified lines | ||
| 131 | 131 | { |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | −#define copy_segments(tsk, mm) do { } while (0) | |
| 135 | −#define release_segments(mm) do { } while (0) | |
| 136 | − | |
| 137 | 134 | /* |
| 138 | 135 | * Return saved PC of a blocked thread. |
| 139 | 136 | */ |
| @@ -39,7 +39,7 @@ config MICROBLAZE · 38 unmodified lines | ||
| 39 | 39 | # Endianness selection |
| 40 | 40 | choice |
| 41 | 41 | prompt "Endianness selection" |
| 42 | − default CPU_BIG_ENDIAN | |
| 42 | + default CPU_LITTLE_ENDIAN | |
| 43 | 43 | help |
| 44 | 44 | microblaze architectures can be configured for either little or |
| 45 | 45 | big endian formats. Be sure to select the appropriate mode. |
| @@ -7,6 +7,7 @@ generic-y += fcntl.h · 6 unmodified lines | ||
| 7 | 7 | generic-y += ioctl.h |
| 8 | 8 | generic-y += ioctls.h |
| 9 | 9 | generic-y += ipcbuf.h |
| 10 | +generic-y += kvm_para.h | |
| 10 | 11 | generic-y += mman.h |
| 11 | 12 | generic-y += msgbuf.h |
| 12 | 13 | generic-y += param.h |
| @@ -165,7 +165,7 @@ int dma_direct_mmap_coherent(struct device *dev, struct vm_area_struct *vma, · 164 unmodified lines | ||
| 165 | 165 | unsigned long attrs) |
| 166 | 166 | { |
| 167 | 167 | #ifdef CONFIG_MMU |
| 168 | − unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | |
| 168 | + unsigned long user_count = vma_pages(vma); | |
| 169 | 169 | unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; |
| 170 | 170 | unsigned long off = vma->vm_pgoff; |
| 171 | 171 | unsigned long pfn; |
| @@ -22,10 +22,10 @@ · 21 unmodified lines | ||
| 22 | 22 | #include "pci.h" |
| 23 | 23 | |
| 24 | 24 | static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); |
| 25 | −static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; | |
| 26 | −static unsigned ath79_pci_nr_irqs __initdata; | |
| 25 | +static const struct ath79_pci_irq *ath79_pci_irq_map; | |
| 26 | +static unsigned ath79_pci_nr_irqs; | |
| 27 | 27 | |
| 28 | −static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { | |
| 28 | +static const struct ath79_pci_irq ar71xx_pci_irq_map[] = { | |
| 29 | 29 | { |
| 30 | 30 | .slot = 17, |
| 31 | 31 | .pin = 1, |
| @@ -41,7 +41,7 @@ static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { · 9 unmodified lines | ||
| 41 | 41 | } |
| 42 | 42 | }; |
| 43 | 43 | |
| 44 | −static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { | |
| 44 | +static const struct ath79_pci_irq ar724x_pci_irq_map[] = { | |
| 45 | 45 | { |
| 46 | 46 | .slot = 0, |
| 47 | 47 | .pin = 1, |
| @@ -49,7 +49,7 @@ static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { · 1 unmodified line | ||
| 49 | 49 | } |
| 50 | 50 | }; |
| 51 | 51 | |
| 52 | −static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { | |
| 52 | +static const struct ath79_pci_irq qca955x_pci_irq_map[] = { | |
| 53 | 53 | { |
| 54 | 54 | .bus = 0, |
| 55 | 55 | .slot = 0, |
| @@ -64,7 +64,7 @@ static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { · 8 unmodified lines | ||
| 64 | 64 | }, |
| 65 | 65 | }; |
| 66 | 66 | |
| 67 | −int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | |
| 67 | +int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | |
| 68 | 68 | { |
| 69 | 69 | int irq = -1; |
| 70 | 70 | int i; |
| @@ -1377,29 +1377,32 @@ do { \ · 1376 unmodified lines | ||
| 1377 | 1377 | |
| 1378 | 1378 | #define __write_64bit_c0_split(source, sel, val) \ |
| 1379 | 1379 | do { \ |
| 1380 | + unsigned long long __tmp; \ | |
| 1380 | 1381 | unsigned long __flags; \ |
| 1381 | 1382 | \ |
| 1382 | 1383 | local_irq_save(__flags); \ |
| 1383 | 1384 | if (sel == 0) \ |
| 1384 | 1385 | __asm__ __volatile__( \ |
| 1385 | 1386 | ".set\tmips64\n\t" \ |
| 1386 | − "dsll\t%L0, %L0, 32\n\t" \ | |
| 1387 | + "dsll\t%L0, %L1, 32\n\t" \ | |
| 1387 | 1388 | "dsrl\t%L0, %L0, 32\n\t" \ |
| 1388 | − "dsll\t%M0, %M0, 32\n\t" \ | |
| 1389 | + "dsll\t%M0, %M1, 32\n\t" \ | |
| 1389 | 1390 | "or\t%L0, %L0, %M0\n\t" \ |
| 1390 | 1391 | "dmtc0\t%L0, " #source "\n\t" \ |
| 1391 | 1392 | ".set\tmips0" \ |
| 1392 | − : : "r" (val)); \ | |
| 1393 | + : "=&r,r" (__tmp) \ | |
| 1394 | + : "r,0" (val)); \ | |
| 1393 | 1395 | else \ |
| 1394 | 1396 | __asm__ __volatile__( \ |
| 1395 | 1397 | ".set\tmips64\n\t" \ |
| 1396 | − "dsll\t%L0, %L0, 32\n\t" \ | |
| 1398 | + "dsll\t%L0, %L1, 32\n\t" \ | |
| 1397 | 1399 | "dsrl\t%L0, %L0, 32\n\t" \ |
| 1398 | − "dsll\t%M0, %M0, 32\n\t" \ | |
| 1400 | + "dsll\t%M0, %M1, 32\n\t" \ | |
| 1399 | 1401 | "or\t%L0, %L0, %M0\n\t" \ |
| 1400 | 1402 | "dmtc0\t%L0, " #source ", " #sel "\n\t" \ |
| 1401 | 1403 | ".set\tmips0" \ |
| 1402 | − : : "r" (val)); \ | |
| 1404 | + : "=&r,r" (__tmp) \ | |
| 1405 | + : "r,0" (val)); \ | |
| 1403 | 1406 | local_irq_restore(__flags); \ |
| 1404 | 1407 | } while (0) |
| 1405 | 1408 | |
| @@ -618,8 +618,7 @@ static int mipspmu_event_init(struct perf_event *event) · 617 unmodified lines | ||
| 618 | 618 | return -ENOENT; |
| 619 | 619 | } |
| 620 | 620 | |
| 621 | − if ((unsigned int)event->cpu >= nr_cpumask_bits || | |
| 622 | − (event->cpu >= 0 && !cpu_online(event->cpu))) | |
| 621 | + if (event->cpu >= 0 && !cpu_online(event->cpu)) | |
| 623 | 622 | return -ENODEV; |
| 624 | 623 | |
| 625 | 624 | if (!atomic_inc_not_zero(&active_events)) { |
| @@ -32,13 +32,13 @@ · 31 unmodified lines | ||
| 32 | 32 | #define INTC PC104PLUS_INTC_IRQ |
| 33 | 33 | #define INTD PC104PLUS_INTD_IRQ |
| 34 | 34 | |
| 35 | −static char irq_tab_capcella[][5] __initdata = { | |
| 35 | +static char irq_tab_capcella[][5] = { | |
| 36 | 36 | [11] = { -1, INT1, INT1, INT1, INT1 }, |
| 37 | 37 | [12] = { -1, INT2, INT2, INT2, INT2 }, |
| 38 | 38 | [14] = { -1, INTA, INTB, INTC, INTD } |
| 39 | 39 | }; |
| 40 | 40 | |
| 41 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 41 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 42 | 42 | { |
| 43 | 43 | return irq_tab_capcella[slot][pin]; |
| 44 | 44 | } |
| @@ -147,7 +147,7 @@ static void qube_raq_via_board_id_fixup(struct pci_dev *dev) · 146 unmodified lines | ||
| 147 | 147 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, |
| 148 | 148 | qube_raq_via_board_id_fixup); |
| 149 | 149 | |
| 150 | −static char irq_tab_qube1[] __initdata = { | |
| 150 | +static char irq_tab_qube1[] = { | |
| 151 | 151 | [COBALT_PCICONF_CPU] = 0, |
| 152 | 152 | [COBALT_PCICONF_ETH0] = QUBE1_ETH0_IRQ, |
| 153 | 153 | [COBALT_PCICONF_RAQSCSI] = SCSI_IRQ, |
| @@ -156,7 +156,7 @@ static char irq_tab_qube1[] __initdata = { · 2 unmodified lines | ||
| 156 | 156 | [COBALT_PCICONF_ETH1] = 0 |
| 157 | 157 | }; |
| 158 | 158 | |
| 159 | −static char irq_tab_cobalt[] __initdata = { | |
| 159 | +static char irq_tab_cobalt[] = { | |
| 160 | 160 | [COBALT_PCICONF_CPU] = 0, |
| 161 | 161 | [COBALT_PCICONF_ETH0] = ETH0_IRQ, |
| 162 | 162 | [COBALT_PCICONF_RAQSCSI] = SCSI_IRQ, |
| @@ -165,7 +165,7 @@ static char irq_tab_cobalt[] __initdata = { · 2 unmodified lines | ||
| 165 | 165 | [COBALT_PCICONF_ETH1] = ETH1_IRQ |
| 166 | 166 | }; |
| 167 | 167 | |
| 168 | −static char irq_tab_raq2[] __initdata = { | |
| 168 | +static char irq_tab_raq2[] = { | |
| 169 | 169 | [COBALT_PCICONF_CPU] = 0, |
| 170 | 170 | [COBALT_PCICONF_ETH0] = ETH0_IRQ, |
| 171 | 171 | [COBALT_PCICONF_RAQSCSI] = RAQ2_SCSI_IRQ, |
| @@ -174,7 +174,7 @@ static char irq_tab_raq2[] __initdata = { · 2 unmodified lines | ||
| 174 | 174 | [COBALT_PCICONF_ETH1] = ETH1_IRQ |
| 175 | 175 | }; |
| 176 | 176 | |
| 177 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 177 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 178 | 178 | { |
| 179 | 179 | if (cobalt_board_id <= COBALT_BRD_ID_QUBE1) |
| 180 | 180 | return irq_tab_qube1[slot]; |
| @@ -43,7 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | */ |
| 44 | 44 | |
| 45 | 45 | #define MAX_SLOT_NUM 10 |
| 46 | −static unsigned char irq_map[][5] __initdata = { | |
| 46 | +static unsigned char irq_map[][5] = { | |
| 47 | 47 | [3] = {0, MARKEINS_PCI_IRQ_INTB, MARKEINS_PCI_IRQ_INTC, |
| 48 | 48 | MARKEINS_PCI_IRQ_INTD, 0,}, |
| 49 | 49 | [4] = {0, MARKEINS_PCI_IRQ_INTA, 0, 0, 0,}, |
| @@ -85,7 +85,7 @@ static void emma2rh_pci_host_fixup(struct pci_dev *dev) · 35 unmodified lines | ||
| 85 | 85 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH, |
| 86 | 86 | emma2rh_pci_host_fixup); |
| 87 | 87 | |
| 88 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 88 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 89 | 89 | { |
| 90 | 90 | return irq_map[slot][pin]; |
| 91 | 91 | } |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | /* South bridge slot number is set by the pci probe process */ |
| 20 | 20 | static u8 sb_slot = 5; |
| 21 | 21 | |
| 22 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 22 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 23 | 23 | { |
| 24 | 24 | int irq = 0; |
| 25 | 25 | |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #define INTB MACEPCI_SHARED0_IRQ |
| 22 | 22 | #define INTC MACEPCI_SHARED1_IRQ |
| 23 | 23 | #define INTD MACEPCI_SHARED2_IRQ |
| 24 | −static char irq_tab_mace[][5] __initdata = { | |
| 24 | +static char irq_tab_mace[][5] = { | |
| 25 | 25 | /* Dummy INT#A INT#B INT#C INT#D */ |
| 26 | 26 | {0, 0, 0, 0, 0}, /* This is placeholder row - never used */ |
| 27 | 27 | {0, SCSI0, SCSI0, SCSI0, SCSI0}, |
| @@ -39,7 +39,7 @@ static char irq_tab_mace[][5] __initdata = { · 11 unmodified lines | ||
| 39 | 39 | * irqs. I suppose a device without a pin A will thank us for doing it |
| 40 | 40 | * right if there exists such a broken piece of crap. |
| 41 | 41 | */ |
| 42 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 42 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 43 | 43 | { |
| 44 | 44 | return irq_tab_mace[slot][pin]; |
| 45 | 45 | } |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <asm/txx9/pci.h> |
| 32 | 32 | #include <asm/txx9/jmr3927.h> |
| 33 | 33 | |
| 34 | −int __init jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 34 | +int jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 35 | 35 | { |
| 36 | 36 | unsigned char irq = pin; |
| 37 | 37 | |
| @@ -23,7 +23,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) · 22 unmodified lines | ||
| 23 | 23 | return 0; |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 26 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 27 | 27 | { |
| 28 | 28 | return of_irq_parse_and_map_pci(dev, slot, pin); |
| 29 | 29 | } |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define PCID 7 |
| 31 | 31 | |
| 32 | 32 | /* all the pci device has the PCIA pin, check the datasheet. */ |
| 33 | −static char irq_tab[][5] __initdata = { | |
| 33 | +static char irq_tab[][5] = { | |
| 34 | 34 | /* INTA INTB INTC INTD */ |
| 35 | 35 | {0, 0, 0, 0, 0}, /* 11: Unused */ |
| 36 | 36 | {0, 0, 0, 0, 0}, /* 12: Unused */ |
| @@ -51,7 +51,7 @@ static char irq_tab[][5] __initdata = { · 14 unmodified lines | ||
| 51 | 51 | {0, 0, 0, 0, 0}, /* 27: Unused */ |
| 52 | 52 | }; |
| 53 | 53 | |
| 54 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 54 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 55 | 55 | { |
| 56 | 56 | int virq; |
| 57 | 57 | |
| @@ -32,7 +32,7 @@ static void print_fixup_info(const struct pci_dev *pdev) · 31 unmodified lines | ||
| 32 | 32 | pdev->vendor, pdev->device, pdev->irq); |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 35 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 36 | 36 | { |
| 37 | 37 | print_fixup_info(dev); |
| 38 | 38 | return dev->irq; |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | static char pci_irq[5] = { |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | −static char irq_tab[][5] __initdata = { | |
| 15 | +static char irq_tab[][5] = { | |
| 16 | 16 | /* INTA INTB INTC INTD */ |
| 17 | 17 | {0, 0, 0, 0, 0 }, /* 0: GT64120 PCI bridge */ |
| 18 | 18 | {0, 0, 0, 0, 0 }, /* 1: Unused */ |
| @@ -38,7 +38,7 @@ static char irq_tab[][5] __initdata = { · 19 unmodified lines | ||
| 38 | 38 | {0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */ |
| 39 | 39 | }; |
| 40 | 40 | |
| 41 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 41 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 42 | 42 | { |
| 43 | 43 | int virq; |
| 44 | 44 | virq = irq_tab[slot][pin]; |
| @@ -22,19 +22,19 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #include <asm/vr41xx/mpc30x.h> |
| 24 | 24 | |
| 25 | −static const int internal_func_irqs[] __initconst = { | |
| 25 | +static const int internal_func_irqs[] = { | |
| 26 | 26 | VRC4173_CASCADE_IRQ, |
| 27 | 27 | VRC4173_AC97_IRQ, |
| 28 | 28 | VRC4173_USB_IRQ, |
| 29 | 29 | }; |
| 30 | 30 | |
| 31 | −static const int irq_tab_mpc30x[] __initconst = { | |
| 31 | +static const int irq_tab_mpc30x[] = { | |
| 32 | 32 | [12] = VRC4173_PCMCIA1_IRQ, |
| 33 | 33 | [13] = VRC4173_PCMCIA2_IRQ, |
| 34 | 34 | [29] = MQ200_IRQ, |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 37 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 38 | 38 | { |
| 39 | 39 | if (slot == 30) |
| 40 | 40 | return internal_func_irqs[PCI_FUNC(dev->devfn)]; |
| @@ -47,7 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | #if defined(CONFIG_PMC_MSP7120_GW) |
| 49 | 49 | /* Garibaldi Board IRQ wiring to PCI slots */ |
| 50 | −static char irq_tab[][5] __initdata = { | |
| 50 | +static char irq_tab[][5] = { | |
| 51 | 51 | /* INTA INTB INTC INTD */ |
| 52 | 52 | {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ |
| 53 | 53 | {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ |
| @@ -86,7 +86,7 @@ static char irq_tab[][5] __initdata = { · 32 unmodified lines | ||
| 86 | 86 | #elif defined(CONFIG_PMC_MSP7120_EVAL) |
| 87 | 87 | |
| 88 | 88 | /* MSP7120 Eval Board IRQ wiring to PCI slots */ |
| 89 | −static char irq_tab[][5] __initdata = { | |
| 89 | +static char irq_tab[][5] = { | |
| 90 | 90 | /* INTA INTB INTC INTD */ |
| 91 | 91 | {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ |
| 92 | 92 | {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ |
| @@ -125,7 +125,7 @@ static char irq_tab[][5] __initdata = { · 32 unmodified lines | ||
| 125 | 125 | #else |
| 126 | 126 | |
| 127 | 127 | /* Unknown board -- don't assign any IRQs */ |
| 128 | −static char irq_tab[][5] __initdata = { | |
| 128 | +static char irq_tab[][5] = { | |
| 129 | 129 | /* INTA INTB INTC INTD */ |
| 130 | 130 | {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ |
| 131 | 131 | {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ |
| @@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) · 70 unmodified lines | ||
| 202 | 202 | * RETURNS: IRQ number |
| 203 | 203 | * |
| 204 | 204 | ****************************************************************************/ |
| 205 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 205 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 206 | 206 | { |
| 207 | 207 | #if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL) |
| 208 | 208 | printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n"); |
| @@ -36,7 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <asm/txx9/pci.h> |
| 37 | 37 | #include <asm/txx9/rbtx4927.h> |
| 38 | 38 | |
| 39 | −int __init rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 39 | +int rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 40 | 40 | { |
| 41 | 41 | unsigned char irq = pin; |
| 42 | 42 | |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <asm/txx9/pci.h> |
| 14 | 14 | #include <asm/txx9/rbtx4938.h> |
| 15 | 15 | |
| 16 | −int __init rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 16 | +int rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 17 | 17 | { |
| 18 | 18 | int irq = tx4938_pcic1_map_irq(dev, slot); |
| 19 | 19 | |
| @@ -40,7 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | * seem to be a documentation error. At least on my RM200C the Cirrus |
| 41 | 41 | * Logic CL-GD5434 VGA is device 3. |
| 42 | 42 | */ |
| 43 | −static char irq_tab_rm200[8][5] __initdata = { | |
| 43 | +static char irq_tab_rm200[8][5] = { | |
| 44 | 44 | /* INTA INTB INTC INTD */ |
| 45 | 45 | { 0, 0, 0, 0, 0 }, /* EISA bridge */ |
| 46 | 46 | { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ |
| @@ -57,7 +57,7 @@ static char irq_tab_rm200[8][5] __initdata = { · 10 unmodified lines | ||
| 57 | 57 | * |
| 58 | 58 | * The VGA card is optional for RM300 systems. |
| 59 | 59 | */ |
| 60 | −static char irq_tab_rm300d[8][5] __initdata = { | |
| 60 | +static char irq_tab_rm300d[8][5] = { | |
| 61 | 61 | /* INTA INTB INTC INTD */ |
| 62 | 62 | { 0, 0, 0, 0, 0 }, /* EISA bridge */ |
| 63 | 63 | { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ |
| @@ -69,7 +69,7 @@ static char irq_tab_rm300d[8][5] __initdata = { · 5 unmodified lines | ||
| 69 | 69 | { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */ |
| 70 | 70 | }; |
| 71 | 71 | |
| 72 | −static char irq_tab_rm300e[5][5] __initdata = { | |
| 72 | +static char irq_tab_rm300e[5][5] = { | |
| 73 | 73 | /* INTA INTB INTC INTD */ |
| 74 | 74 | { 0, 0, 0, 0, 0 }, /* HOST bridge */ |
| 75 | 75 | { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ |
| @@ -96,7 +96,7 @@ static char irq_tab_rm300e[5][5] __initdata = { · 20 unmodified lines | ||
| 96 | 96 | #define INTC PCIT_IRQ_INTC |
| 97 | 97 | #define INTD PCIT_IRQ_INTD |
| 98 | 98 | |
| 99 | −static char irq_tab_pcit[13][5] __initdata = { | |
| 99 | +static char irq_tab_pcit[13][5] = { | |
| 100 | 100 | /* INTA INTB INTC INTD */ |
| 101 | 101 | { 0, 0, 0, 0, 0 }, /* HOST bridge */ |
| 102 | 102 | { SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 }, /* SCSI */ |
| @@ -113,7 +113,7 @@ static char irq_tab_pcit[13][5] __initdata = { · 10 unmodified lines | ||
| 113 | 113 | { 0, INTA, INTB, INTC, INTD }, /* Slot 5 */ |
| 114 | 114 | }; |
| 115 | 115 | |
| 116 | −static char irq_tab_pcit_cplus[13][5] __initdata = { | |
| 116 | +static char irq_tab_pcit_cplus[13][5] = { | |
| 117 | 117 | /* INTA INTB INTC INTD */ |
| 118 | 118 | { 0, 0, 0, 0, 0 }, /* HOST bridge */ |
| 119 | 119 | { 0, INTB, INTC, INTD, INTA }, /* PCI Slot 9 */ |
| @@ -130,7 +130,7 @@ static inline int is_rm300_revd(void) · 10 unmodified lines | ||
| 130 | 130 | return (csmsr & 0xa0) == 0x20; |
| 131 | 131 | } |
| 132 | 132 | |
| 133 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 133 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 134 | 134 | { |
| 135 | 135 | switch (sni_brd_type) { |
| 136 | 136 | case SNI_BRD_PCI_TOWER_CPLUS: |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <asm/vr41xx/tb0219.h> |
| 25 | 25 | |
| 26 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 26 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 27 | 27 | { |
| 28 | 28 | int irq = -1; |
| 29 | 29 | |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <asm/vr41xx/giu.h> |
| 24 | 24 | #include <asm/vr41xx/tb0226.h> |
| 25 | 25 | |
| 26 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 26 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 27 | 27 | { |
| 28 | 28 | int irq = -1; |
| 29 | 29 | |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #include <asm/vr41xx/tb0287.h> |
| 24 | 24 | |
| 25 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 25 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 26 | 26 | { |
| 27 | 27 | unsigned char bus; |
| 28 | 28 | int irq = -1; |
| @@ -522,7 +522,7 @@ static int __init alchemy_pci_init(void) · 521 unmodified lines | ||
| 522 | 522 | arch_initcall(alchemy_pci_init); |
| 523 | 523 | |
| 524 | 524 | |
| 525 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 525 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 526 | 526 | { |
| 527 | 527 | struct alchemy_pci_context *ctx = dev->sysdata; |
| 528 | 528 | if (ctx && ctx->board_map_irq) |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/bcma/bcma.h> |
| 29 | 29 | #include <bcm47xx.h> |
| 30 | 30 | |
| 31 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 31 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 32 | 32 | { |
| 33 | 33 | return 0; |
| 34 | 34 | } |
| @@ -61,7 +61,7 @@ arch_initcall(lasat_pci_setup); · 60 unmodified lines | ||
| 61 | 61 | #define LASAT_IRQ_PCIC (LASAT_IRQ_BASE + 7) |
| 62 | 62 | #define LASAT_IRQ_PCID (LASAT_IRQ_BASE + 8) |
| 63 | 63 | |
| 64 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 64 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 65 | 65 | { |
| 66 | 66 | switch (slot) { |
| 67 | 67 | case 1: |
| @@ -361,7 +361,7 @@ static int mt7620_pci_probe(struct platform_device *pdev) · 360 unmodified lines | ||
| 361 | 361 | return 0; |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 364 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 365 | 365 | { |
| 366 | 366 | u16 cmd; |
| 367 | 367 | u32 val; |
| @@ -59,8 +59,7 @@ union octeon_pci_address { · 58 unmodified lines | ||
| 59 | 59 | } s; |
| 60 | 60 | }; |
| 61 | 61 | |
| 62 | −int __initconst (*octeon_pcibios_map_irq)(const struct pci_dev *dev, | |
| 63 | − u8 slot, u8 pin); | |
| 62 | +int (*octeon_pcibios_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); | |
| 64 | 63 | enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; |
| 65 | 64 | |
| 66 | 65 | /** |
| @@ -74,7 +73,7 @@ enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; · 7 unmodified lines | ||
| 74 | 73 | * as it goes through each bridge. |
| 75 | 74 | * Returns Interrupt number for the device |
| 76 | 75 | */ |
| 77 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 76 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 78 | 77 | { |
| 79 | 78 | if (octeon_pcibios_map_irq) |
| 80 | 79 | return octeon_pcibios_map_irq(dev, slot, pin); |
| @@ -181,7 +181,7 @@ static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) · 180 unmodified lines | ||
| 181 | 181 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 184 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 185 | 185 | { |
| 186 | 186 | u16 cmd; |
| 187 | 187 | int irq = -1; |
| @@ -564,7 +564,7 @@ err_put_intc_node: · 563 unmodified lines | ||
| 564 | 564 | return err; |
| 565 | 565 | } |
| 566 | 566 | |
| 567 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 567 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 568 | 568 | { |
| 569 | 569 | return of_irq_parse_and_map_pci(dev, slot, pin); |
| 570 | 570 | } |
| @@ -112,7 +112,7 @@ int __init tx4938_pciclk66_setup(void) · 111 unmodified lines | ||
| 112 | 112 | return pciclk; |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | −int __init tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
| 115 | +int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
| 116 | 116 | { |
| 117 | 117 | if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { |
| 118 | 118 | switch (slot) { |
| @@ -48,7 +48,7 @@ void __init tx4939_report_pci1clk(void) · 47 unmodified lines | ||
| 48 | 48 | ((pciclk + 50000) / 100000) % 10); |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | −int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
| 51 | +int tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
| 52 | 52 | { |
| 53 | 53 | if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4939_pcic1ptr) { |
| 54 | 54 | switch (slot) { |
| @@ -68,7 +68,7 @@ int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) · 13 unmodified lines | ||
| 68 | 68 | return -1; |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | −int __init tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 71 | +int tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 72 | 72 | { |
| 73 | 73 | int irq = tx4939_pcic1_map_irq(dev, slot); |
| 74 | 74 | |
| @@ -205,7 +205,7 @@ int xlp_socdev_to_node(const struct pci_dev *lnkdev) · 204 unmodified lines | ||
| 205 | 205 | return PCI_SLOT(lnkdev->devfn) / 8; |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 208 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 209 | 209 | { |
| 210 | 210 | struct pci_dev *lnkdev; |
| 211 | 211 | int lnkfunc, node; |
| @@ -315,7 +315,7 @@ static void xls_pcie_ack_b(struct irq_data *d) · 314 unmodified lines | ||
| 315 | 315 | } |
| 316 | 316 | } |
| 317 | 317 | |
| 318 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 318 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 319 | 319 | { |
| 320 | 320 | return get_irq_vector(dev); |
| 321 | 321 | } |
| @@ -1464,8 +1464,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port) · 1463 unmodified lines | ||
| 1464 | 1464 | * as it goes through each bridge. |
| 1465 | 1465 | * Returns Interrupt number for the device |
| 1466 | 1466 | */ |
| 1467 | −int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, | |
| 1468 | − u8 slot, u8 pin) | |
| 1467 | +int octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 1469 | 1468 | { |
| 1470 | 1469 | /* |
| 1471 | 1470 | * The EBH5600 board with the PCI to PCIe bridge mistakenly |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/smp.h> |
| 23 | 23 | #include <linux/interrupt.h> |
| 24 | 24 | |
| 25 | +#include <asm/setup.h> | |
| 26 | + | |
| 25 | 27 | #ifdef CONFIG_MIPS_MT_SMP |
| 26 | 28 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ |
| 27 | 29 | #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for call */ |
| @@ -386,9 +386,10 @@ int pcibios_plat_dev_init(struct pci_dev *dev) · 385 unmodified lines | ||
| 386 | 386 | return 0; |
| 387 | 387 | } |
| 388 | 388 | |
| 389 | −int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 389 | +static int (*txx9_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); | |
| 390 | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
| 390 | 391 | { |
| 391 | − return txx9_board_vec->pci_map_irq(dev, slot, pin); | |
| 392 | + return txx9_pci_map_irq(dev, slot, pin); | |
| 392 | 393 | } |
| 393 | 394 | |
| 394 | 395 | char * (*txx9_board_pcibios_setup)(char *str) __initdata; |
| @@ -424,5 +425,8 @@ char *__init txx9_pcibios_setup(char *str) · 29 unmodified lines | ||
| 424 | 425 | txx9_pci_err_action = TXX9_PCI_ERR_IGNORE; |
| 425 | 426 | return NULL; |
| 426 | 427 | } |
| 428 | + | |
| 429 | + txx9_pci_map_irq = txx9_board_vec->pci_map_irq; | |
| 430 | + | |
| 427 | 431 | return str; |
| 428 | 432 | } |
| @@ -59,10 +59,6 @@ void arch_cpu_idle(void) · 58 unmodified lines | ||
| 59 | 59 | } |
| 60 | 60 | #endif |
| 61 | 61 | |
| 62 | −void release_segments(struct mm_struct *mm) | |
| 63 | −{ | |
| 64 | −} | |
| 65 | − | |
| 66 | 62 | void machine_restart(char *cmd) |
| 67 | 63 | { |
| 68 | 64 | #ifdef CONFIG_KERNEL_DEBUGGER |
| @@ -112,14 +108,6 @@ void release_thread(struct task_struct *dead_task) · 43 unmodified lines | ||
| 112 | 108 | { |
| 113 | 109 | } |
| 114 | 110 | |
| 115 | −/* | |
| 116 | − * we do not have to muck with descriptors here, that is | |
| 117 | − * done in switch_mm() as needed. | |
| 118 | − */ | |
| 119 | −void copy_segments(struct task_struct *p, struct mm_struct *new_mm) | |
| 120 | −{ | |
| 121 | −} | |
| 122 | − | |
| 123 | 111 | /* |
| 124 | 112 | * this gets called so that we can store lazy state into memory and copy the |
| 125 | 113 | * current task into the new thread. |
| @@ -257,6 +257,18 @@ config PARISC_PAGE_SIZE_64KB · 256 unmodified lines | ||
| 257 | 257 | |
| 258 | 258 | endchoice |
| 259 | 259 | |
| 260 | +config PARISC_SELF_EXTRACT | |
| 261 | + bool "Build kernel as self-extracting executable" | |
| 262 | + default y | |
| 263 | + help | |
| 264 | + Say Y if you want to build the parisc kernel as a kind of | |
| 265 | + self-extracting executable. | |
| 266 | + | |
| 267 | + If you say N here, the kernel will be compressed with gzip | |
| 268 | + which can be loaded by the palo bootloader directly too. | |
| 269 | + | |
| 270 | + If you don't know what to do here, say Y. | |
| 271 | + | |
| 260 | 272 | config SMP |
| 261 | 273 | bool "Symmetric multi-processing support" |
| 262 | 274 | ---help--- |
| @@ -129,8 +129,13 @@ Image: vmlinux · 128 unmodified lines | ||
| 129 | 129 | bzImage: vmlinux |
| 130 | 130 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ |
| 131 | 131 | |
| 132 | +ifdef CONFIG_PARISC_SELF_EXTRACT | |
| 132 | 133 | vmlinuz: bzImage |
| 133 | 134 | $(OBJCOPY) $(boot)/bzImage $@ |
| 135 | +else | |
| 136 | +vmlinuz: vmlinux | |
| 137 | + @gzip -cf -9 $< > $@ | |
| 138 | +endif | |
| 134 | 139 | |
| 135 | 140 | install: |
| 136 | 141 | $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \ |
| @@ -15,7 +15,7 @@ targets += misc.o piggy.o sizes.h head.o real2.o firmware.o · 14 unmodified lines | ||
| 15 | 15 | KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER |
| 16 | 16 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
| 17 | 17 | KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks |
| 18 | −KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs | |
| 18 | +KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os | |
| 19 | 19 | ifndef CONFIG_64BIT |
| 20 | 20 | KBUILD_CFLAGS += -mfast-indirect-calls |
| 21 | 21 | endif |
| @@ -24,7 +24,8 @@ · 23 unmodified lines | ||
| 24 | 24 | /* Symbols defined by linker scripts */ |
| 25 | 25 | extern char input_data[]; |
| 26 | 26 | extern int input_len; |
| 27 | −extern __le32 output_len; /* at unaligned address, little-endian */ | |
| 27 | +/* output_len is inserted by the linker possibly at an unaligned address */ | |
| 28 | +extern __le32 output_len __aligned(1); | |
| 28 | 29 | extern char _text, _end; |
| 29 | 30 | extern char _bss, _ebss; |
| 30 | 31 | extern char _startcode_end; |
| @@ -280,6 +280,7 @@ void setup_pdc(void); /* in inventory.c */ · 279 unmodified lines | ||
| 280 | 280 | /* wrapper-functions from pdc.c */ |
| 281 | 281 | |
| 282 | 282 | int pdc_add_valid(unsigned long address); |
| 283 | +int pdc_instr(unsigned int *instr); | |
| 283 | 284 | int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); |
| 284 | 285 | int pdc_chassis_disp(unsigned long disp); |
| 285 | 286 | int pdc_chassis_warn(unsigned long *warn); |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | #ifndef __ASM_SMP_H |
| 2 | 2 | #define __ASM_SMP_H |
| 3 | 3 | |
| 4 | +extern int init_per_cpu(int cpuid); | |
| 4 | 5 | |
| 5 | 6 | #if defined(CONFIG_SMP) |
| 6 | 7 | |
| @@ -232,6 +232,26 @@ int pdc_add_valid(unsigned long address) · 231 unmodified lines | ||
| 232 | 232 | } |
| 233 | 233 | EXPORT_SYMBOL(pdc_add_valid); |
| 234 | 234 | |
| 235 | +/** | |
| 236 | + * pdc_instr - Get instruction that invokes PDCE_CHECK in HPMC handler. | |
| 237 | + * @instr: Pointer to variable which will get instruction opcode. | |
| 238 | + * | |
| 239 | + * The return value is PDC_OK (0) in case call succeeded. | |
| 240 | + */ | |
| 241 | +int __init pdc_instr(unsigned int *instr) | |
| 242 | +{ | |
| 243 | + int retval; | |
| 244 | + unsigned long flags; | |
| 245 | + | |
| 246 | + spin_lock_irqsave(&pdc_lock, flags); | |
| 247 | + retval = mem_pdc_call(PDC_INSTR, 0UL, __pa(pdc_result)); | |
| 248 | + convert_to_wide(pdc_result); | |
| 249 | + *instr = pdc_result[0]; | |
| 250 | + spin_unlock_irqrestore(&pdc_lock, flags); | |
| 251 | + | |
| 252 | + return retval; | |
| 253 | +} | |
| 254 | + | |
| 235 | 255 | /** |
| 236 | 256 | * pdc_chassis_info - Return chassis information. |
| 237 | 257 | * @result: The return buffer. |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/memblock.h> |
| 16 | 16 | #include <linux/seq_file.h> |
| 17 | 17 | #include <linux/kthread.h> |
| 18 | +#include <linux/initrd.h> | |
| 18 | 19 | |
| 19 | 20 | #include <asm/pdc.h> |
| 20 | 21 | #include <asm/pdcpat.h> |
| @@ -216,8 +217,16 @@ void __init pdc_pdt_init(void) · 195 unmodified lines | ||
| 216 | 217 | } |
| 217 | 218 | |
| 218 | 219 | for (i = 0; i < pdt_status.pdt_entries; i++) { |
| 220 | + unsigned long addr; | |
| 221 | + | |
| 219 | 222 | report_mem_err(pdt_entry[i]); |
| 220 | 223 | |
| 224 | + addr = pdt_entry[i] & PDT_ADDR_PHYS_MASK; | |
| 225 | + if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && | |
| 226 | + addr >= initrd_start && addr < initrd_end) | |
| 227 | + pr_crit("CRITICAL: initrd possibly broken " | |
| 228 | + "due to bad memory!\n"); | |
| 229 | + | |
| 221 | 230 | /* mark memory page bad */ |
| 222 | 231 | memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE); |
| 223 | 232 | } |
| @@ -146,7 +146,7 @@ void machine_power_off(void) · 145 unmodified lines | ||
| 146 | 146 | |
| 147 | 147 | /* prevent soft lockup/stalled CPU messages for endless loop. */ |
| 148 | 148 | rcu_sysrq_start(); |
| 149 | − lockup_detector_suspend(); | |
| 149 | + lockup_detector_soft_poweroff(); | |
| 150 | 150 | for (;;); |
| 151 | 151 | } |
| 152 | 152 | |
| @@ -317,7 +317,7 @@ void __init collect_boot_cpu_data(void) · 316 unmodified lines | ||
| 317 | 317 | * |
| 318 | 318 | * o Enable CPU profiling hooks. |
| 319 | 319 | */ |
| 320 | −int init_per_cpu(int cpunum) | |
| 320 | +int __init init_per_cpu(int cpunum) | |
| 321 | 321 | { |
| 322 | 322 | int ret; |
| 323 | 323 | struct pdc_coproc_cfg coproc_cfg; |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | #include <linux/export.h> |
| 39 | 39 | #include <linux/sched.h> |
| 40 | 40 | #include <linux/sched/clock.h> |
| 41 | +#include <linux/start_kernel.h> | |
| 41 | 42 | |
| 42 | 43 | #include <asm/processor.h> |
| 43 | 44 | #include <asm/sections.h> |
| @@ -48,6 +49,7 @@ · 4 unmodified lines | ||
| 48 | 49 | #include <asm/io.h> |
| 49 | 50 | #include <asm/setup.h> |
| 50 | 51 | #include <asm/unwind.h> |
| 52 | +#include <asm/smp.h> | |
| 51 | 53 | |
| 52 | 54 | static char __initdata command_line[COMMAND_LINE_SIZE]; |
| 53 | 55 | |
| @@ -115,7 +117,6 @@ void __init dma_ops_init(void) · 61 unmodified lines | ||
| 115 | 117 | } |
| 116 | 118 | #endif |
| 117 | 119 | |
| 118 | −extern int init_per_cpu(int cpuid); | |
| 119 | 120 | extern void collect_boot_cpu_data(void); |
| 120 | 121 | |
| 121 | 122 | void __init setup_arch(char **cmdline_p) |
| @@ -398,9 +399,8 @@ static int __init parisc_init(void) · 276 unmodified lines | ||
| 398 | 399 | } |
| 399 | 400 | arch_initcall(parisc_init); |
| 400 | 401 | |
| 401 | −void start_parisc(void) | |
| 402 | +void __init start_parisc(void) | |
| 402 | 403 | { |
| 403 | − extern void start_kernel(void); | |
| 404 | 404 | extern void early_trap_init(void); |
| 405 | 405 | |
| 406 | 406 | int ret, cpunum; |
| @@ -255,12 +255,11 @@ void arch_send_call_function_single_ipi(int cpu) · 254 unmodified lines | ||
| 255 | 255 | static void __init |
| 256 | 256 | smp_cpu_init(int cpunum) |
| 257 | 257 | { |
| 258 | − extern int init_per_cpu(int); /* arch/parisc/kernel/processor.c */ | |
| 259 | 258 | extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */ |
| 260 | 259 | extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */ |
| 261 | 260 | |
| 262 | 261 | /* Set modes and Enable floating point coprocessor */ |
| 263 | − (void) init_per_cpu(cpunum); | |
| 262 | + init_per_cpu(cpunum); | |
| 264 | 263 | |
| 265 | 264 | disable_sr_hashing(); |
| 266 | 265 | |
| @@ -817,7 +817,7 @@ void __init initialize_ivt(const void *iva) · 816 unmodified lines | ||
| 817 | 817 | u32 check = 0; |
| 818 | 818 | u32 *ivap; |
| 819 | 819 | u32 *hpmcp; |
| 820 | − u32 length; | |
| 820 | + u32 length, instr; | |
| 821 | 821 | |
| 822 | 822 | if (strcmp((const char *)iva, "cows can fly")) |
| 823 | 823 | panic("IVT invalid"); |
| @@ -827,6 +827,14 @@ void __init initialize_ivt(const void *iva) · 3 unmodified lines | ||
| 827 | 827 | for (i = 0; i < 8; i++) |
| 828 | 828 | *ivap++ = 0; |
| 829 | 829 | |
| 830 | + /* | |
| 831 | + * Use PDC_INSTR firmware function to get instruction that invokes | |
| 832 | + * PDCE_CHECK in HPMC handler. See programming note at page 1-31 of | |
| 833 | + * the PA 1.1 Firmware Architecture document. | |
| 834 | + */ | |
| 835 | + if (pdc_instr(&instr) == PDC_OK) | |
| 836 | + ivap[0] = instr; | |
| 837 | + | |
| 830 | 838 | /* Compute Checksum for HPMC handler */ |
| 831 | 839 | length = os_hpmc_size; |
| 832 | 840 | ivap[7] = length; |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/slab.h> |
| 15 | 15 | #include <linux/kallsyms.h> |
| 16 | 16 | #include <linux/sort.h> |
| 17 | +#include <linux/sched.h> | |
| 17 | 18 | |
| 18 | 19 | #include <linux/uaccess.h> |
| 19 | 20 | #include <asm/assembly.h> |
| @@ -279,6 +280,17 @@ static void unwind_frame_regs(struct unwind_frame_info *info) · 259 unmodified lines | ||
| 279 | 280 | |
| 280 | 281 | info->prev_sp = sp - 64; |
| 281 | 282 | info->prev_ip = 0; |
| 283 | + | |
| 284 | + /* The stack is at the end inside the thread_union | |
| 285 | + * struct. If we reach data, we have reached the | |
| 286 | + * beginning of the stack and should stop unwinding. */ | |
| 287 | + if (info->prev_sp >= (unsigned long) task_thread_info(info->t) && | |
| 288 | + info->prev_sp < ((unsigned long) task_thread_info(info->t) | |
| 289 | + + THREAD_SZ_ALGN)) { | |
| 290 | + info->prev_sp = 0; | |
| 291 | + break; | |
| 292 | + } | |
| 293 | + | |
| 282 | 294 | if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET))) |
| 283 | 295 | break; |
| 284 | 296 | info->prev_ip = tmp; |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/interrupt.h> |
| 18 | 18 | #include <linux/extable.h> |
| 19 | 19 | #include <linux/uaccess.h> |
| 20 | +#include <linux/hugetlb.h> | |
| 20 | 21 | |
| 21 | 22 | #include <asm/traps.h> |
| 22 | 23 | |
| @@ -261,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, · 238 unmodified lines | ||
| 261 | 262 | struct task_struct *tsk; |
| 262 | 263 | struct mm_struct *mm; |
| 263 | 264 | unsigned long acc_type; |
| 264 | − int fault; | |
| 265 | + int fault = 0; | |
| 265 | 266 | unsigned int flags; |
| 266 | 267 | |
| 267 | 268 | if (faulthandler_disabled()) |
| @@ -315,7 +316,8 @@ good_area: · 47 unmodified lines | ||
| 315 | 316 | goto out_of_memory; |
| 316 | 317 | else if (fault & VM_FAULT_SIGSEGV) |
| 317 | 318 | goto bad_area; |
| 318 | − else if (fault & VM_FAULT_SIGBUS) | |
| 319 | + else if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| | |
| 320 | + VM_FAULT_HWPOISON_LARGE)) | |
| 319 | 321 | goto bad_area; |
| 320 | 322 | BUG(); |
| 321 | 323 | } |
| @@ -352,8 +354,7 @@ bad_area: · 30 unmodified lines | ||
| 352 | 354 | |
| 353 | 355 | if (user_mode(regs)) { |
| 354 | 356 | struct siginfo si; |
| 355 | − | |
| 356 | − show_signal_msg(regs, code, address, tsk, vma); | |
| 357 | + unsigned int lsb = 0; | |
| 357 | 358 | |
| 358 | 359 | switch (code) { |
| 359 | 360 | case 15: /* Data TLB miss fault/Data page fault */ |
| @@ -386,6 +387,30 @@ bad_area: · 26 unmodified lines | ||
| 386 | 387 | si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR; |
| 387 | 388 | break; |
| 388 | 389 | } |
| 390 | + | |
| 391 | +#ifdef CONFIG_MEMORY_FAILURE | |
| 392 | + if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { | |
| 393 | + printk(KERN_ERR | |
| 394 | + "MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n", | |
| 395 | + tsk->comm, tsk->pid, address); | |
| 396 | + si.si_signo = SIGBUS; | |
| 397 | + si.si_code = BUS_MCEERR_AR; | |
| 398 | + } | |
| 399 | +#endif | |
| 400 | + | |
| 401 | + /* | |
| 402 | + * Either small page or large page may be poisoned. | |
| 403 | + * In other words, VM_FAULT_HWPOISON_LARGE and | |
| 404 | + * VM_FAULT_HWPOISON are mutually exclusive. | |
| 405 | + */ | |
| 406 | + if (fault & VM_FAULT_HWPOISON_LARGE) | |
| 407 | + lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); | |
| 408 | + else if (fault & VM_FAULT_HWPOISON) | |
| 409 | + lsb = PAGE_SHIFT; | |
| 410 | + else | |
| 411 | + show_signal_msg(regs, code, address, tsk, vma); | |
| 412 | + si.si_addr_lsb = lsb; | |
| 413 | + | |
| 389 | 414 | si.si_errno = 0; |
| 390 | 415 | si.si_addr = (void __user *) address; |
| 391 | 416 | force_sig_info(si.si_signo, &si, current); |
| @@ -138,10 +138,11 @@ CONFIG_FRAMEBUFFER_CONSOLE=y · 137 unmodified lines | ||
| 138 | 138 | CONFIG_LOGO=y |
| 139 | 139 | CONFIG_SOUND=m |
| 140 | 140 | CONFIG_SND=m |
| 141 | −CONFIG_SND_SEQUENCER=m | |
| 141 | +CONFIG_SND_OSSEMUL=y | |
| 142 | 142 | CONFIG_SND_MIXER_OSS=m |
| 143 | 143 | CONFIG_SND_PCM_OSS=m |
| 144 | −CONFIG_SND_SEQUENCER_OSS=y | |
| 144 | +CONFIG_SND_SEQUENCER=m | |
| 145 | +CONFIG_SND_SEQUENCER_OSS=m | |
| 145 | 146 | CONFIG_SND_POWERMAC=m |
| 146 | 147 | CONFIG_SND_AOA=m |
| 147 | 148 | CONFIG_SND_AOA_FABRIC_LAYOUT=m |
| @@ -64,11 +64,12 @@ CONFIG_LOGO=y · 63 unmodified lines | ||
| 64 | 64 | # CONFIG_LOGO_LINUX_CLUT224 is not set |
| 65 | 65 | CONFIG_SOUND=y |
| 66 | 66 | CONFIG_SND=y |
| 67 | −CONFIG_SND_SEQUENCER=y | |
| 67 | +CONFIG_SND_OSSEMUL=y | |
| 68 | 68 | CONFIG_SND_MIXER_OSS=y |
| 69 | 69 | CONFIG_SND_PCM_OSS=y |
| 70 | −CONFIG_SND_SEQUENCER_OSS=y | |
| 71 | 70 | # CONFIG_SND_VERBOSE_PROCFS is not set |
| 71 | +CONFIG_SND_SEQUENCER=y | |
| 72 | +CONFIG_SND_SEQUENCER_OSS=y | |
| 72 | 73 | # CONFIG_USB_SUPPORT is not set |
| 73 | 74 | CONFIG_RTC_CLASS=y |
| 74 | 75 | CONFIG_RTC_DRV_GENERIC=y |
| @@ -115,9 +115,10 @@ CONFIG_VGACON_SOFT_SCROLLBACK=y · 114 unmodified lines | ||
| 115 | 115 | CONFIG_LOGO=y |
| 116 | 116 | CONFIG_SOUND=y |
| 117 | 117 | CONFIG_SND=y |
| 118 | −CONFIG_SND_SEQUENCER=y | |
| 118 | +CONFIG_SND_OSSEMUL=y | |
| 119 | 119 | CONFIG_SND_MIXER_OSS=y |
| 120 | 120 | CONFIG_SND_PCM_OSS=y |
| 121 | +CONFIG_SND_SEQUENCER=y | |
| 121 | 122 | CONFIG_SND_SEQUENCER_OSS=y |
| 122 | 123 | CONFIG_SND_USB_AUDIO=y |
| 123 | 124 | CONFIG_SND_USB_USX2Y=y |
| @@ -227,11 +227,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y · 226 unmodified lines | ||
| 227 | 227 | CONFIG_LOGO=y |
| 228 | 228 | CONFIG_SOUND=m |
| 229 | 229 | CONFIG_SND=m |
| 230 | −CONFIG_SND_SEQUENCER=m | |
| 231 | −CONFIG_SND_SEQ_DUMMY=m | |
| 230 | +CONFIG_SND_OSSEMUL=y | |
| 232 | 231 | CONFIG_SND_MIXER_OSS=m |
| 233 | 232 | CONFIG_SND_PCM_OSS=m |
| 234 | −CONFIG_SND_SEQUENCER_OSS=y | |
| 233 | +CONFIG_SND_SEQUENCER=m | |
| 234 | +CONFIG_SND_SEQ_DUMMY=m | |
| 235 | +CONFIG_SND_SEQUENCER_OSS=m | |
| 235 | 236 | CONFIG_SND_DUMMY=m |
| 236 | 237 | CONFIG_SND_POWERMAC=m |
| 237 | 238 | CONFIG_SND_AOA=m |
| @@ -222,11 +222,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y · 221 unmodified lines | ||
| 222 | 222 | CONFIG_LOGO=y |
| 223 | 223 | CONFIG_SOUND=m |
| 224 | 224 | CONFIG_SND=m |
| 225 | −CONFIG_SND_SEQUENCER=m | |
| 226 | −CONFIG_SND_SEQ_DUMMY=m | |
| 225 | +CONFIG_SND_OSSEMUL=y | |
| 227 | 226 | CONFIG_SND_MIXER_OSS=m |
| 228 | 227 | CONFIG_SND_PCM_OSS=m |
| 229 | −CONFIG_SND_SEQUENCER_OSS=y | |
| 228 | +CONFIG_SND_SEQUENCER=m | |
| 229 | +CONFIG_SND_SEQ_DUMMY=m | |
| 230 | +CONFIG_SND_SEQUENCER_OSS=m | |
| 230 | 231 | CONFIG_SND_POWERMAC=m |
| 231 | 232 | CONFIG_SND_AOA=m |
| 232 | 233 | CONFIG_SND_AOA_FABRIC_LAYOUT=m |
| @@ -141,11 +141,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y · 140 unmodified lines | ||
| 141 | 141 | CONFIG_LOGO=y |
| 142 | 142 | CONFIG_SOUND=m |
| 143 | 143 | CONFIG_SND=m |
| 144 | −CONFIG_SND_SEQUENCER=m | |
| 145 | −CONFIG_SND_SEQ_DUMMY=m | |
| 144 | +CONFIG_SND_OSSEMUL=y | |
| 146 | 145 | CONFIG_SND_MIXER_OSS=m |
| 147 | 146 | CONFIG_SND_PCM_OSS=m |
| 148 | −CONFIG_SND_SEQUENCER_OSS=y | |
| 147 | +CONFIG_SND_SEQUENCER=m | |
| 148 | +CONFIG_SND_SEQ_DUMMY=m | |
| 149 | +CONFIG_SND_SEQUENCER_OSS=m | |
| 149 | 150 | CONFIG_HID_DRAGONRISE=y |
| 150 | 151 | CONFIG_HID_GYRATION=y |
| 151 | 152 | CONFIG_HID_TWINHAN=y |
| @@ -789,17 +789,18 @@ CONFIG_LOGO=y · 788 unmodified lines | ||
| 789 | 789 | # CONFIG_LOGO_LINUX_VGA16 is not set |
| 790 | 790 | CONFIG_SOUND=m |
| 791 | 791 | CONFIG_SND=m |
| 792 | −CONFIG_SND_SEQUENCER=m | |
| 793 | −CONFIG_SND_SEQ_DUMMY=m | |
| 792 | +CONFIG_SND_OSSEMUL=y | |
| 794 | 793 | CONFIG_SND_MIXER_OSS=m |
| 795 | 794 | CONFIG_SND_PCM_OSS=m |
| 796 | −CONFIG_SND_SEQUENCER_OSS=y | |
| 797 | 795 | CONFIG_SND_DYNAMIC_MINORS=y |
| 798 | 796 | # CONFIG_SND_SUPPORT_OLD_API is not set |
| 799 | 797 | CONFIG_SND_VERBOSE_PRINTK=y |
| 800 | 798 | CONFIG_SND_DEBUG=y |
| 801 | 799 | CONFIG_SND_DEBUG_VERBOSE=y |
| 802 | 800 | CONFIG_SND_PCM_XRUN_DEBUG=y |
| 801 | +CONFIG_SND_SEQUENCER=m | |
| 802 | +CONFIG_SND_SEQ_DUMMY=m | |
| 803 | +CONFIG_SND_SEQUENCER_OSS=m | |
| 803 | 804 | CONFIG_SND_DUMMY=m |
| 804 | 805 | CONFIG_SND_VIRMIDI=m |
| 805 | 806 | CONFIG_SND_MTPAV=m |
| @@ -79,11 +79,12 @@ CONFIG_FB=y · 78 unmodified lines | ||
| 79 | 79 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 80 | 80 | CONFIG_SOUND=y |
| 81 | 81 | CONFIG_SND=y |
| 82 | −CONFIG_SND_SEQUENCER=y | |
| 82 | +CONFIG_SND_OSSEMUL=y | |
| 83 | 83 | CONFIG_SND_MIXER_OSS=y |
| 84 | 84 | CONFIG_SND_PCM_OSS=y |
| 85 | −CONFIG_SND_SEQUENCER_OSS=y | |
| 86 | 85 | # CONFIG_SND_VERBOSE_PROCFS is not set |
| 86 | +CONFIG_SND_SEQUENCER=y | |
| 87 | +CONFIG_SND_SEQUENCER_OSS=y | |
| 87 | 88 | CONFIG_HID_APPLE=m |
| 88 | 89 | CONFIG_HID_WACOM=m |
| 89 | 90 | CONFIG_MMC=y |
| @@ -102,10 +102,10 @@ static void cpufeatures_flush_tlb(void) · 101 unmodified lines | ||
| 102 | 102 | case PVR_POWER8: |
| 103 | 103 | case PVR_POWER8E: |
| 104 | 104 | case PVR_POWER8NVL: |
| 105 | − __flush_tlb_power8(POWER8_TLB_SETS); | |
| 105 | + __flush_tlb_power8(TLB_INVAL_SCOPE_GLOBAL); | |
| 106 | 106 | break; |
| 107 | 107 | case PVR_POWER9: |
| 108 | − __flush_tlb_power9(POWER9_TLB_SETS_HASH); | |
| 108 | + __flush_tlb_power9(TLB_INVAL_SCOPE_GLOBAL); | |
| 109 | 109 | break; |
| 110 | 110 | default: |
| 111 | 111 | pr_err("unknown CPU version for boot TLB flush\n"); |
| @@ -1019,6 +1019,10 @@ int eeh_init(void) · 1018 unmodified lines | ||
| 1019 | 1019 | } else if ((ret = eeh_ops->init())) |
| 1020 | 1020 | return ret; |
| 1021 | 1021 | |
| 1022 | + /* Initialize PHB PEs */ | |
| 1023 | + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | |
| 1024 | + eeh_dev_phb_init_dynamic(hose); | |
| 1025 | + | |
| 1022 | 1026 | /* Initialize EEH event */ |
| 1023 | 1027 | ret = eeh_event_init(); |
| 1024 | 1028 | if (ret) |
| @@ -78,21 +78,3 @@ void eeh_dev_phb_init_dynamic(struct pci_controller *phb) · 77 unmodified lines | ||
| 78 | 78 | /* EEH PE for PHB */ |
| 79 | 79 | eeh_phb_pe_create(phb); |
| 80 | 80 | } |
| 81 | − | |
| 82 | −/** | |
| 83 | − * eeh_dev_phb_init - Create EEH devices for devices included in existing PHBs | |
| 84 | − * | |
| 85 | − * Scan all the existing PHBs and create EEH devices for their OF | |
| 86 | − * nodes and their children OF nodes | |
| 87 | − */ | |
| 88 | −static int __init eeh_dev_phb_init(void) | |
| 89 | −{ | |
| 90 | − struct pci_controller *phb, *tmp; | |
| 91 | − | |
| 92 | − list_for_each_entry_safe(phb, tmp, &hose_list, list_node) | |
| 93 | − eeh_dev_phb_init_dynamic(phb); | |
| 94 | − | |
| 95 | − return 0; | |
| 96 | −} | |
| 97 | − | |
| 98 | −core_initcall(eeh_dev_phb_init); | |
| @@ -624,5 +624,18 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs) · 623 unmodified lines | ||
| 624 | 624 | |
| 625 | 625 | long __machine_check_early_realmode_p9(struct pt_regs *regs) |
| 626 | 626 | { |
| 627 | + /* | |
| 628 | + * On POWER9 DD2.1 and below, it's possible to get a machine check | |
| 629 | + * caused by a paste instruction where only DSISR bit 25 is set. This | |
| 630 | + * will result in the MCE handler seeing an unknown event and the kernel | |
| 631 | + * crashing. An MCE that occurs like this is spurious, so we don't need | |
| 632 | + * to do anything in terms of servicing it. If there is something that | |
| 633 | + * needs to be serviced, the CPU will raise the MCE again with the | |
| 634 | + * correct DSISR so that it can be serviced properly. So detect this | |
| 635 | + * case and mark it as handled. | |
| 636 | + */ | |
| 637 | + if (SRR1_MC_LOADSTORE(regs->msr) && regs->dsisr == 0x02000000) | |
| 638 | + return 1; | |
| 639 | + | |
| 627 | 640 | return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table); |
| 628 | 641 | } |
| @@ -104,8 +104,10 @@ static unsigned long can_optimize(struct kprobe *p) · 103 unmodified lines | ||
| 104 | 104 | * and that can be emulated. |
| 105 | 105 | */ |
| 106 | 106 | if (!is_conditional_branch(*p->ainsn.insn) && |
| 107 | − analyse_instr(&op, ®s, *p->ainsn.insn)) | |
| 107 | + analyse_instr(&op, ®s, *p->ainsn.insn) == 1) { | |
| 108 | + emulate_update_regs(®s, &op); | |
| 108 | 109 | nip = regs.nip; |
| 110 | + } | |
| 109 | 111 | |
| 110 | 112 | return nip; |
| 111 | 113 | } |
| @@ -131,7 +131,7 @@ static void flush_tmregs_to_thread(struct task_struct *tsk) · 130 unmodified lines | ||
| 131 | 131 | * in the appropriate thread structures from live. |
| 132 | 132 | */ |
| 133 | 133 | |
| 134 | − if (tsk != current) | |
| 134 | + if ((!cpu_has_feature(CPU_FTR_TM)) || (tsk != current)) | |
| 135 | 135 | return; |
| 136 | 136 | |
| 137 | 137 | if (MSR_TM_SUSPENDED(mfmsr())) { |
| @@ -904,9 +904,6 @@ void __init setup_arch(char **cmdline_p) · 903 unmodified lines | ||
| 904 | 904 | #endif |
| 905 | 905 | #endif |
| 906 | 906 | |
| 907 | −#ifdef CONFIG_PPC_64K_PAGES | |
| 908 | − init_mm.context.pte_frag = NULL; | |
| 909 | −#endif | |
| 910 | 907 | #ifdef CONFIG_SPAPR_TCE_IOMMU |
| 911 | 908 | mm_iommu_init(&init_mm); |
| 912 | 909 | #endif |
| @@ -437,6 +437,7 @@ static inline int check_io_access(struct pt_regs *regs) · 436 unmodified lines | ||
| 437 | 437 | int machine_check_e500mc(struct pt_regs *regs) |
| 438 | 438 | { |
| 439 | 439 | unsigned long mcsr = mfspr(SPRN_MCSR); |
| 440 | + unsigned long pvr = mfspr(SPRN_PVR); | |
| 440 | 441 | unsigned long reason = mcsr; |
| 441 | 442 | int recoverable = 1; |
| 442 | 443 | |
| @@ -478,8 +479,15 @@ int machine_check_e500mc(struct pt_regs *regs) · 35 unmodified lines | ||
| 478 | 479 | * may still get logged and cause a machine check. We should |
| 479 | 480 | * only treat the non-write shadow case as non-recoverable. |
| 480 | 481 | */ |
| 481 | − if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS)) | |
| 482 | − recoverable = 0; | |
| 482 | + /* On e6500 core, L1 DCWS (Data cache write shadow mode) bit | |
| 483 | + * is not implemented but L1 data cache always runs in write | |
| 484 | + * shadow mode. Hence on data cache parity errors HW will | |
| 485 | + * automatically invalidate the L1 Data Cache. | |
| 486 | + */ | |
| 487 | + if (PVR_VER(pvr) != PVR_VER_E6500) { | |
| 488 | + if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS)) | |
| 489 | + recoverable = 0; | |
| 490 | + } | |
| 483 | 491 | } |
| 484 | 492 | |
| 485 | 493 | if (reason & MCSR_L2MMU_MHIT) { |
| @@ -310,9 +310,6 @@ static int start_wd_on_cpu(unsigned int cpu) · 309 unmodified lines | ||
| 310 | 310 | if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) |
| 311 | 311 | return 0; |
| 312 | 312 | |
| 313 | − if (watchdog_suspended) | |
| 314 | − return 0; | |
| 315 | − | |
| 316 | 313 | if (!cpumask_test_cpu(cpu, &watchdog_cpumask)) |
| 317 | 314 | return 0; |
| 318 | 315 | |
| @@ -358,36 +355,39 @@ static void watchdog_calc_timeouts(void) · 39 unmodified lines | ||
| 358 | 355 | wd_timer_period_ms = watchdog_thresh * 1000 * 2 / 5; |
| 359 | 356 | } |
| 360 | 357 | |
| 361 | −void watchdog_nmi_reconfigure(void) | |
| 358 | +void watchdog_nmi_stop(void) | |
| 362 | 359 | { |
| 363 | 360 | int cpu; |
| 364 | 361 | |
| 365 | − watchdog_calc_timeouts(); | |
| 366 | − | |
| 367 | 362 | for_each_cpu(cpu, &wd_cpus_enabled) |
| 368 | 363 | stop_wd_on_cpu(cpu); |
| 364 | +} | |
| 369 | 365 | |
| 366 | +void watchdog_nmi_start(void) | |
| 367 | +{ | |
| 368 | + int cpu; | |
| 369 | + | |
| 370 | + watchdog_calc_timeouts(); | |
| 370 | 371 | for_each_cpu_and(cpu, cpu_online_mask, &watchdog_cpumask) |
| 371 | 372 | start_wd_on_cpu(cpu); |
| 372 | 373 | } |
| 373 | 374 | |
| 374 | 375 | /* |
| 375 | − * This runs after lockup_detector_init() which sets up watchdog_cpumask. | |
| 376 | + * Invoked from core watchdog init. | |
| 376 | 377 | */ |
| 377 | −static int __init powerpc_watchdog_init(void) | |
| 378 | +int __init watchdog_nmi_probe(void) | |
| 378 | 379 | { |
| 379 | 380 | int err; |
| 380 | 381 | |
| 381 | − watchdog_calc_timeouts(); | |
| 382 | − | |
| 383 | − err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powerpc/watchdog:online", | |
| 384 | − start_wd_on_cpu, stop_wd_on_cpu); | |
| 385 | − if (err < 0) | |
| 382 | + err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, | |
| 383 | + "powerpc/watchdog:online", | |
| 384 | + start_wd_on_cpu, stop_wd_on_cpu); | |
| 385 | + if (err < 0) { | |
| 386 | 386 | pr_warn("Watchdog could not be initialized"); |
| 387 | − | |
| 387 | + return err; | |
| 388 | + } | |
| 388 | 389 | return 0; |
| 389 | 390 | } |
| 390 | −arch_initcall(powerpc_watchdog_init); | |
| 391 | 391 | |
| 392 | 392 | static void handle_backtrace_ipi(struct pt_regs *regs) |
| 393 | 393 | { |
| @@ -1121,6 +1121,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) · 1120 unmodified lines | ||
| 1121 | 1121 | BEGIN_FTR_SECTION |
| 1122 | 1122 | mtspr SPRN_PPR, r0 |
| 1123 | 1123 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) |
| 1124 | + | |
| 1125 | +/* Move canary into DSISR to check for later */ | |
| 1126 | +BEGIN_FTR_SECTION | |
| 1127 | + li r0, 0x7fff | |
| 1128 | + mtspr SPRN_HDSISR, r0 | |
| 1129 | +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) | |
| 1130 | + | |
| 1124 | 1131 | ld r0, VCPU_GPR(R0)(r4) |
| 1125 | 1132 | ld r4, VCPU_GPR(R4)(r4) |
| 1126 | 1133 | |
| @@ -1956,9 +1963,14 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX) · 829 unmodified lines | ||
| 1956 | 1963 | kvmppc_hdsi: |
| 1957 | 1964 | ld r3, VCPU_KVM(r9) |
| 1958 | 1965 | lbz r0, KVM_RADIX(r3) |
| 1959 | − cmpwi r0, 0 | |
| 1960 | 1966 | mfspr r4, SPRN_HDAR |
| 1961 | 1967 | mfspr r6, SPRN_HDSISR |
| 1968 | +BEGIN_FTR_SECTION | |
| 1969 | + /* Look for DSISR canary. If we find it, retry instruction */ | |
| 1970 | + cmpdi r6, 0x7fff | |
| 1971 | + beq 6f | |
| 1972 | +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) | |
| 1973 | + cmpwi r0, 0 | |
| 1962 | 1974 | bne .Lradix_hdsi /* on radix, just save DAR/DSISR/ASDR */ |
| 1963 | 1975 | /* HPTE not found fault or protection fault? */ |
| 1964 | 1976 | andis. r0, r6, (DSISR_NOHPTE | DSISR_PROTFAULT)@h |
| @@ -622,7 +622,7 @@ int kvmppc_xive_get_xive(struct kvm *kvm, u32 irq, u32 *server, · 621 unmodified lines | ||
| 622 | 622 | return -EINVAL; |
| 623 | 623 | state = &sb->irq_state[idx]; |
| 624 | 624 | arch_spin_lock(&sb->lock); |
| 625 | − *server = state->guest_server; | |
| 625 | + *server = state->act_server; | |
| 626 | 626 | *priority = state->guest_priority; |
| 627 | 627 | arch_spin_unlock(&sb->lock); |
| 628 | 628 | |
| @@ -1331,7 +1331,7 @@ static int xive_get_source(struct kvmppc_xive *xive, long irq, u64 addr) · 702 unmodified lines | ||
| 1331 | 1331 | xive->saved_src_count++; |
| 1332 | 1332 | |
| 1333 | 1333 | /* Convert saved state into something compatible with xics */ |
| 1334 | − val = state->guest_server; | |
| 1334 | + val = state->act_server; | |
| 1335 | 1335 | prio = state->saved_scan_prio; |
| 1336 | 1336 | |
| 1337 | 1337 | if (prio == MASKED) { |
| @@ -1507,7 +1507,6 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) · 169 unmodified lines | ||
| 1507 | 1507 | /* First convert prio and mark interrupt as untargetted */ |
| 1508 | 1508 | act_prio = xive_prio_from_guest(guest_prio); |
| 1509 | 1509 | state->act_priority = MASKED; |
| 1510 | − state->guest_server = server; | |
| 1511 | 1510 | |
| 1512 | 1511 | /* |
| 1513 | 1512 | * We need to drop the lock due to the mutex below. Hopefully |
| @@ -35,7 +35,6 @@ struct kvmppc_xive_irq_state { · 34 unmodified lines | ||
| 35 | 35 | struct xive_irq_data *pt_data; /* XIVE Pass-through associated data */ |
| 36 | 36 | |
| 37 | 37 | /* Targetting as set by guest */ |
| 38 | − u32 guest_server; /* Current guest selected target */ | |
| 39 | 38 | u8 guest_priority; /* Guest set priority */ |
| 40 | 39 | u8 saved_priority; /* Saved priority when masking */ |
| 41 | 40 | |
| @@ -944,9 +944,9 @@ NOKPROBE_SYMBOL(emulate_dcbz); · 943 unmodified lines | ||
| 944 | 944 | : "r" (addr), "i" (-EFAULT), "0" (err)) |
| 945 | 945 | |
| 946 | 946 | static nokprobe_inline void set_cr0(const struct pt_regs *regs, |
| 947 | − struct instruction_op *op, int rd) | |
| 947 | + struct instruction_op *op) | |
| 948 | 948 | { |
| 949 | − long val = regs->gpr[rd]; | |
| 949 | + long val = op->val; | |
| 950 | 950 | |
| 951 | 951 | op->type |= SETCC; |
| 952 | 952 | op->ccval = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); |
| @@ -1326,7 +1326,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, · 373 unmodified lines | ||
| 1326 | 1326 | case 13: /* addic. */ |
| 1327 | 1327 | imm = (short) instr; |
| 1328 | 1328 | add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); |
| 1329 | − set_cr0(regs, op, rd); | |
| 1329 | + set_cr0(regs, op); | |
| 1330 | 1330 | return 1; |
| 1331 | 1331 | |
| 1332 | 1332 | case 14: /* addi */ |
| @@ -1397,13 +1397,13 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, · 64 unmodified lines | ||
| 1397 | 1397 | |
| 1398 | 1398 | case 28: /* andi. */ |
| 1399 | 1399 | op->val = regs->gpr[rd] & (unsigned short) instr; |
| 1400 | − set_cr0(regs, op, ra); | |
| 1400 | + set_cr0(regs, op); | |
| 1401 | 1401 | goto logical_done_nocc; |
| 1402 | 1402 | |
| 1403 | 1403 | case 29: /* andis. */ |
| 1404 | 1404 | imm = (unsigned short) instr; |
| 1405 | 1405 | op->val = regs->gpr[rd] & (imm << 16); |
| 1406 | − set_cr0(regs, op, ra); | |
| 1406 | + set_cr0(regs, op); | |
| 1407 | 1407 | goto logical_done_nocc; |
| 1408 | 1408 | |
| 1409 | 1409 | #ifdef __powerpc64__ |
| @@ -1513,10 +1513,10 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, · 103 unmodified lines | ||
| 1513 | 1513 | op->type = COMPUTE + SETCC; |
| 1514 | 1514 | imm = 0xf0000000UL; |
| 1515 | 1515 | val = regs->gpr[rd]; |
| 1516 | − op->val = regs->ccr; | |
| 1516 | + op->ccval = regs->ccr; | |
| 1517 | 1517 | for (sh = 0; sh < 8; ++sh) { |
| 1518 | 1518 | if (instr & (0x80000 >> sh)) |
| 1519 | − op->val = (op->val & ~imm) | | |
| 1519 | + op->ccval = (op->ccval & ~imm) | | |
| 1520 | 1520 | (val & imm); |
| 1521 | 1521 | imm >>= 4; |
| 1522 | 1522 | } |
| @@ -1651,8 +1651,9 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, · 128 unmodified lines | ||
| 1651 | 1651 | goto arith_done; |
| 1652 | 1652 | |
| 1653 | 1653 | case 235: /* mullw */ |
| 1654 | − op->val = (unsigned int) regs->gpr[ra] * | |
| 1655 | − (unsigned int) regs->gpr[rb]; | |
| 1654 | + op->val = (long)(int) regs->gpr[ra] * | |
| 1655 | + (int) regs->gpr[rb]; | |
| 1656 | + | |
| 1656 | 1657 | goto arith_done; |
| 1657 | 1658 | |
| 1658 | 1659 | case 266: /* add */ |
| @@ -2526,7 +2527,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, · 867 unmodified lines | ||
| 2526 | 2527 | |
| 2527 | 2528 | logical_done: |
| 2528 | 2529 | if (instr & 1) |
| 2529 | − set_cr0(regs, op, ra); | |
| 2530 | + set_cr0(regs, op); | |
| 2530 | 2531 | logical_done_nocc: |
| 2531 | 2532 | op->reg = ra; |
| 2532 | 2533 | op->type |= SETREG; |
| @@ -2534,7 +2535,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, · 1 unmodified line | ||
| 2534 | 2535 | |
| 2535 | 2536 | arith_done: |
| 2536 | 2537 | if (instr & 1) |
| 2537 | − set_cr0(regs, op, rd); | |
| 2538 | + set_cr0(regs, op); | |
| 2538 | 2539 | compute_done: |
| 2539 | 2540 | op->reg = rd; |
| 2540 | 2541 | op->type |= SETREG; |
| @@ -361,9 +361,9 @@ static int change_page_attr(struct page *page, int numpages, pgprot_t prot) · 360 unmodified lines | ||
| 361 | 361 | break; |
| 362 | 362 | } |
| 363 | 363 | wmb(); |
| 364 | + local_irq_restore(flags); | |
| 364 | 365 | flush_tlb_kernel_range((unsigned long)page_address(start), |
| 365 | 366 | (unsigned long)page_address(page)); |
| 366 | − local_irq_restore(flags); | |
| 367 | 367 | return err; |
| 368 | 368 | } |
| 369 | 369 | |
| @@ -793,6 +793,11 @@ void perf_event_print_debug(void) · 792 unmodified lines | ||
| 793 | 793 | u32 pmcs[MAX_HWEVENTS]; |
| 794 | 794 | int i; |
| 795 | 795 | |
| 796 | + if (!ppmu) { | |
| 797 | + pr_info("Performance monitor hardware not registered.\n"); | |
| 798 | + return; | |
| 799 | + } | |
| 800 | + | |
| 796 | 801 | if (!ppmu->n_counter) |
| 797 | 802 | return; |
| 798 | 803 | |
| @@ -393,7 +393,13 @@ static void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val) · 392 unmodified lines | ||
| 393 | 393 | u64 pir = get_hard_smp_processor_id(cpu); |
| 394 | 394 | |
| 395 | 395 | mtspr(SPRN_LPCR, lpcr_val); |
| 396 | − opal_slw_set_reg(pir, SPRN_LPCR, lpcr_val); | |
| 396 | + | |
| 397 | + /* | |
| 398 | + * Program the LPCR via stop-api only if the deepest stop state | |
| 399 | + * can lose hypervisor context. | |
| 400 | + */ | |
| 401 | + if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) | |
| 402 | + opal_slw_set_reg(pir, SPRN_LPCR, lpcr_val); | |
| 397 | 403 | } |
| 398 | 404 | |
| 399 | 405 | /* |
| @@ -272,7 +272,15 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) · 271 unmodified lines | ||
| 272 | 272 | #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE |
| 273 | 273 | static unsigned long pnv_memory_block_size(void) |
| 274 | 274 | { |
| 275 | − return 256UL * 1024 * 1024; | |
| 275 | + /* | |
| 276 | + * We map the kernel linear region with 1GB large pages on radix. For | |
| 277 | + * memory hot unplug to work our memory block size must be at least | |
| 278 | + * this size. | |
| 279 | + */ | |
| 280 | + if (radix_enabled()) | |
| 281 | + return 1UL * 1024 * 1024 * 1024; | |
| 282 | + else | |
| 283 | + return 256UL * 1024 * 1024; | |
| 276 | 284 | } |
| 277 | 285 | #endif |
| 278 | 286 | |
| @@ -266,7 +266,6 @@ int dlpar_attach_node(struct device_node *dn, struct device_node *parent) · 265 unmodified lines | ||
| 266 | 266 | return rc; |
| 267 | 267 | } |
| 268 | 268 | |
| 269 | − of_node_put(dn->parent); | |
| 270 | 269 | return 0; |
| 271 | 270 | } |
| 272 | 271 | |
| @@ -462,15 +462,19 @@ static ssize_t dlpar_cpu_add(u32 drc_index) · 461 unmodified lines | ||
| 462 | 462 | } |
| 463 | 463 | |
| 464 | 464 | dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); |
| 465 | − of_node_put(parent); | |
| 466 | 465 | if (!dn) { |
| 467 | 466 | pr_warn("Failed call to configure-connector, drc index: %x\n", |
| 468 | 467 | drc_index); |
| 469 | 468 | dlpar_release_drc(drc_index); |
| 469 | + of_node_put(parent); | |
| 470 | 470 | return -EINVAL; |
| 471 | 471 | } |
| 472 | 472 | |
| 473 | 473 | rc = dlpar_attach_node(dn, parent); |
| 474 | + | |
| 475 | + /* Regardless we are done with parent now */ | |
| 476 | + of_node_put(parent); | |
| 477 | + | |
| 474 | 478 | if (rc) { |
| 475 | 479 | saved_rc = rc; |
| 476 | 480 | pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n", |
| @@ -226,8 +226,10 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) · 225 unmodified lines | ||
| 226 | 226 | return -ENOENT; |
| 227 | 227 | |
| 228 | 228 | dn = dlpar_configure_connector(drc_index, parent_dn); |
| 229 | − if (!dn) | |
| 229 | + if (!dn) { | |
| 230 | + of_node_put(parent_dn); | |
| 230 | 231 | return -ENOENT; |
| 232 | + } | |
| 231 | 233 | |
| 232 | 234 | rc = dlpar_attach_node(dn, parent_dn); |
| 233 | 235 | if (rc) |
| @@ -71,6 +71,8 @@ · 70 unmodified lines | ||
| 71 | 71 | #define RIWAR_WRTYP_ALLOC 0x00006000 |
| 72 | 72 | #define RIWAR_SIZE_MASK 0x0000003F |
| 73 | 73 | |
| 74 | +static DEFINE_SPINLOCK(fsl_rio_config_lock); | |
| 75 | + | |
| 74 | 76 | #define __fsl_read_rio_config(x, addr, err, op) \ |
| 75 | 77 | __asm__ __volatile__( \ |
| 76 | 78 | "1: "op" %1,0(%2)\n" \ |
| @@ -184,6 +186,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, · 107 unmodified lines | ||
| 184 | 186 | u8 hopcount, u32 offset, int len, u32 *val) |
| 185 | 187 | { |
| 186 | 188 | struct rio_priv *priv = mport->priv; |
| 189 | + unsigned long flags; | |
| 187 | 190 | u8 *data; |
| 188 | 191 | u32 rval, err = 0; |
| 189 | 192 | |
| @@ -197,6 +200,8 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, · 7 unmodified lines | ||
| 197 | 200 | if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) |
| 198 | 201 | return -EINVAL; |
| 199 | 202 | |
| 203 | + spin_lock_irqsave(&fsl_rio_config_lock, flags); | |
| 204 | + | |
| 200 | 205 | out_be32(&priv->maint_atmu_regs->rowtar, |
| 201 | 206 | (destid << 22) | (hopcount << 12) | (offset >> 12)); |
| 202 | 207 | out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); |
| @@ -213,6 +218,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, · 10 unmodified lines | ||
| 213 | 218 | __fsl_read_rio_config(rval, data, err, "lwz"); |
| 214 | 219 | break; |
| 215 | 220 | default: |
| 221 | + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); | |
| 216 | 222 | return -EINVAL; |
| 217 | 223 | } |
| 218 | 224 | |
| @@ -221,6 +227,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, · 2 unmodified lines | ||
| 221 | 227 | err, destid, hopcount, offset); |
| 222 | 228 | } |
| 223 | 229 | |
| 230 | + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); | |
| 224 | 231 | *val = rval; |
| 225 | 232 | |
| 226 | 233 | return err; |
| @@ -244,7 +251,10 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, · 17 unmodified lines | ||
| 244 | 251 | u8 hopcount, u32 offset, int len, u32 val) |
| 245 | 252 | { |
| 246 | 253 | struct rio_priv *priv = mport->priv; |
| 254 | + unsigned long flags; | |
| 247 | 255 | u8 *data; |
| 256 | + int ret = 0; | |
| 257 | + | |
| 248 | 258 | pr_debug |
| 249 | 259 | ("fsl_rio_config_write:" |
| 250 | 260 | " index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", |
| @@ -255,6 +265,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, · 4 unmodified lines | ||
| 255 | 265 | if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) |
| 256 | 266 | return -EINVAL; |
| 257 | 267 | |
| 268 | + spin_lock_irqsave(&fsl_rio_config_lock, flags); | |
| 269 | + | |
| 258 | 270 | out_be32(&priv->maint_atmu_regs->rowtar, |
| 259 | 271 | (destid << 22) | (hopcount << 12) | (offset >> 12)); |
| 260 | 272 | out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); |
| @@ -271,10 +283,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, · 10 unmodified lines | ||
| 271 | 283 | out_be32((u32 *) data, val); |
| 272 | 284 | break; |
| 273 | 285 | default: |
| 274 | − return -EINVAL; | |
| 286 | + ret = -EINVAL; | |
| 275 | 287 | } |
| 288 | + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); | |
| 276 | 289 | |
| 277 | − return 0; | |
| 290 | + return ret; | |
| 278 | 291 | } |
| 279 | 292 | |
| 280 | 293 | static void fsl_rio_inbound_mem_init(struct rio_priv *priv) |
| @@ -104,6 +104,8 @@ · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | #define DOORBELL_MESSAGE_SIZE 0x08 |
| 106 | 106 | |
| 107 | +static DEFINE_SPINLOCK(fsl_rio_doorbell_lock); | |
| 108 | + | |
| 107 | 109 | struct rio_msg_regs { |
| 108 | 110 | u32 omr; |
| 109 | 111 | u32 osr; |
| @@ -626,9 +628,13 @@ err_out: · 516 unmodified lines | ||
| 626 | 628 | int fsl_rio_doorbell_send(struct rio_mport *mport, |
| 627 | 629 | int index, u16 destid, u16 data) |
| 628 | 630 | { |
| 631 | + unsigned long flags; | |
| 632 | + | |
| 629 | 633 | pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n", |
| 630 | 634 | index, destid, data); |
| 631 | 635 | |
| 636 | + spin_lock_irqsave(&fsl_rio_doorbell_lock, flags); | |
| 637 | + | |
| 632 | 638 | /* In the serial version silicons, such as MPC8548, MPC8641, |
| 633 | 639 | * below operations is must be. |
| 634 | 640 | */ |
| @@ -638,6 +644,8 @@ int fsl_rio_doorbell_send(struct rio_mport *mport, · 3 unmodified lines | ||
| 638 | 644 | out_be32(&dbell->dbell_regs->oddatr, (index << 20) | data); |
| 639 | 645 | out_be32(&dbell->dbell_regs->odmr, 0x00000001); |
| 640 | 646 | |
| 647 | + spin_unlock_irqrestore(&fsl_rio_doorbell_lock, flags); | |
| 648 | + | |
| 641 | 649 | return 0; |
| 642 | 650 | } |
| 643 | 651 | |
| @@ -1402,6 +1402,14 @@ void xive_teardown_cpu(void) · 1401 unmodified lines | ||
| 1402 | 1402 | |
| 1403 | 1403 | if (xive_ops->teardown_cpu) |
| 1404 | 1404 | xive_ops->teardown_cpu(cpu, xc); |
| 1405 | + | |
| 1406 | +#ifdef CONFIG_SMP | |
| 1407 | + /* Get rid of IPI */ | |
| 1408 | + xive_cleanup_cpu_ipi(cpu, xc); | |
| 1409 | +#endif | |
| 1410 | + | |
| 1411 | + /* Disable and free the queues */ | |
| 1412 | + xive_cleanup_cpu_queues(cpu, xc); | |
| 1405 | 1413 | } |
| 1406 | 1414 | |
| 1407 | 1415 | void xive_kexec_teardown_cpu(int secondary) |
| @@ -431,7 +431,11 @@ static int xive_spapr_get_ipi(unsigned int cpu, struct xive_cpu *xc) · 430 unmodified lines | ||
| 431 | 431 | |
| 432 | 432 | static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc) |
| 433 | 433 | { |
| 434 | + if (!xc->hw_ipi) | |
| 435 | + return; | |
| 436 | + | |
| 434 | 437 | xive_irq_bitmap_free(xc->hw_ipi); |
| 438 | + xc->hw_ipi = 0; | |
| 435 | 439 | } |
| 436 | 440 | #endif /* CONFIG_SMP */ |
| 437 | 441 | |
| @@ -1507,7 +1507,9 @@ static inline pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, · 1506 unmodified lines | ||
| 1507 | 1507 | static inline void pmdp_invalidate(struct vm_area_struct *vma, |
| 1508 | 1508 | unsigned long addr, pmd_t *pmdp) |
| 1509 | 1509 | { |
| 1510 | − pmdp_xchg_direct(vma->vm_mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY)); | |
| 1510 | + pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); | |
| 1511 | + | |
| 1512 | + pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd); | |
| 1511 | 1513 | } |
| 1512 | 1514 | |
| 1513 | 1515 | #define __HAVE_ARCH_PMDP_SET_WRPROTECT |
| @@ -404,18 +404,6 @@ static inline void save_vector_registers(void) · 403 unmodified lines | ||
| 404 | 404 | #endif |
| 405 | 405 | } |
| 406 | 406 | |
| 407 | −static int __init topology_setup(char *str) | |
| 408 | −{ | |
| 409 | − bool enabled; | |
| 410 | − int rc; | |
| 411 | − | |
| 412 | − rc = kstrtobool(str, &enabled); | |
| 413 | − if (!rc && !enabled) | |
| 414 | − S390_lowcore.machine_flags &= ~MACHINE_FLAG_TOPOLOGY; | |
| 415 | − return rc; | |
| 416 | −} | |
| 417 | −early_param("topology", topology_setup); | |
| 418 | − | |
| 419 | 407 | static int __init disable_vector_extension(char *str) |
| 420 | 408 | { |
| 421 | 409 | S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX; |
| @@ -823,9 +823,12 @@ static int cpumsf_pmu_event_init(struct perf_event *event) · 822 unmodified lines | ||
| 823 | 823 | } |
| 824 | 824 | |
| 825 | 825 | /* Check online status of the CPU to which the event is pinned */ |
| 826 | − if ((unsigned int)event->cpu >= nr_cpumask_bits || | |
| 827 | − (event->cpu >= 0 && !cpu_online(event->cpu))) | |
| 828 | − return -ENODEV; | |
| 826 | + if (event->cpu >= 0) { | |
| 827 | + if ((unsigned int)event->cpu >= nr_cpumask_bits) | |
| 828 | + return -ENODEV; | |
| 829 | + if (!cpu_online(event->cpu)) | |
| 830 | + return -ENODEV; | |
| 831 | + } | |
| 829 | 832 | |
| 830 | 833 | /* Force reset of idle/hv excludes regardless of what the |
| 831 | 834 | * user requested. |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #include <linux/workqueue.h> |
| 10 | 10 | #include <linux/bootmem.h> |
| 11 | +#include <linux/uaccess.h> | |
| 12 | +#include <linux/sysctl.h> | |
| 11 | 13 | #include <linux/cpuset.h> |
| 12 | 14 | #include <linux/device.h> |
| 13 | 15 | #include <linux/export.h> |
| @@ -29,12 +31,20 @@ · 15 unmodified lines | ||
| 29 | 31 | #define PTF_VERTICAL (1UL) |
| 30 | 32 | #define PTF_CHECK (2UL) |
| 31 | 33 | |
| 34 | +enum { | |
| 35 | + TOPOLOGY_MODE_HW, | |
| 36 | + TOPOLOGY_MODE_SINGLE, | |
| 37 | + TOPOLOGY_MODE_PACKAGE, | |
| 38 | + TOPOLOGY_MODE_UNINITIALIZED | |
| 39 | +}; | |
| 40 | + | |
| 32 | 41 | struct mask_info { |
| 33 | 42 | struct mask_info *next; |
| 34 | 43 | unsigned char id; |
| 35 | 44 | cpumask_t mask; |
| 36 | 45 | }; |
| 37 | 46 | |
| 47 | +static int topology_mode = TOPOLOGY_MODE_UNINITIALIZED; | |
| 38 | 48 | static void set_topology_timer(void); |
| 39 | 49 | static void topology_work_fn(struct work_struct *work); |
| 40 | 50 | static struct sysinfo_15_1_x *tl_info; |
| @@ -59,11 +69,26 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) · 18 unmodified lines | ||
| 59 | 69 | cpumask_t mask; |
| 60 | 70 | |
| 61 | 71 | cpumask_copy(&mask, cpumask_of(cpu)); |
| 62 | − if (!MACHINE_HAS_TOPOLOGY) | |
| 63 | − return mask; | |
| 64 | − for (; info; info = info->next) { | |
| 65 | − if (cpumask_test_cpu(cpu, &info->mask)) | |
| 66 | − return info->mask; | |
| 72 | + switch (topology_mode) { | |
| 73 | + case TOPOLOGY_MODE_HW: | |
| 74 | + while (info) { | |
| 75 | + if (cpumask_test_cpu(cpu, &info->mask)) { | |
| 76 | + mask = info->mask; | |
| 77 | + break; | |
| 78 | + } | |
| 79 | + info = info->next; | |
| 80 | + } | |
| 81 | + if (cpumask_empty(&mask)) | |
| 82 | + cpumask_copy(&mask, cpumask_of(cpu)); | |
| 83 | + break; | |
| 84 | + case TOPOLOGY_MODE_PACKAGE: | |
| 85 | + cpumask_copy(&mask, cpu_present_mask); | |
| 86 | + break; | |
| 87 | + default: | |
| 88 | + /* fallthrough */ | |
| 89 | + case TOPOLOGY_MODE_SINGLE: | |
| 90 | + cpumask_copy(&mask, cpumask_of(cpu)); | |
| 91 | + break; | |
| 67 | 92 | } |
| 68 | 93 | return mask; |
| 69 | 94 | } |
| @@ -74,7 +99,7 @@ static cpumask_t cpu_thread_map(unsigned int cpu) · 4 unmodified lines | ||
| 74 | 99 | int i; |
| 75 | 100 | |
| 76 | 101 | cpumask_copy(&mask, cpumask_of(cpu)); |
| 77 | − if (!MACHINE_HAS_TOPOLOGY) | |
| 102 | + if (topology_mode != TOPOLOGY_MODE_HW) | |
| 78 | 103 | return mask; |
| 79 | 104 | cpu -= cpu % (smp_cpu_mtid + 1); |
| 80 | 105 | for (i = 0; i <= smp_cpu_mtid; i++) |
| @@ -184,10 +209,8 @@ static void topology_update_polarization_simple(void) · 103 unmodified lines | ||
| 184 | 209 | { |
| 185 | 210 | int cpu; |
| 186 | 211 | |
| 187 | − mutex_lock(&smp_cpu_state_mutex); | |
| 188 | 212 | for_each_possible_cpu(cpu) |
| 189 | 213 | smp_cpu_set_polarization(cpu, POLARIZATION_HRZ); |
| 190 | − mutex_unlock(&smp_cpu_state_mutex); | |
| 191 | 214 | } |
| 192 | 215 | |
| 193 | 216 | static int ptf(unsigned long fc) |
| @@ -223,7 +246,7 @@ int topology_set_cpu_management(int fc) · 29 unmodified lines | ||
| 223 | 246 | static void update_cpu_masks(void) |
| 224 | 247 | { |
| 225 | 248 | struct cpu_topology_s390 *topo; |
| 226 | − int cpu; | |
| 249 | + int cpu, id; | |
| 227 | 250 | |
| 228 | 251 | for_each_possible_cpu(cpu) { |
| 229 | 252 | topo = &cpu_topology[cpu]; |
| @@ -231,12 +254,13 @@ static void update_cpu_masks(void) · 1 unmodified line | ||
| 231 | 254 | topo->core_mask = cpu_group_map(&socket_info, cpu); |
| 232 | 255 | topo->book_mask = cpu_group_map(&book_info, cpu); |
| 233 | 256 | topo->drawer_mask = cpu_group_map(&drawer_info, cpu); |
| 234 | − if (!MACHINE_HAS_TOPOLOGY) { | |
| 257 | + if (topology_mode != TOPOLOGY_MODE_HW) { | |
| 258 | + id = topology_mode == TOPOLOGY_MODE_PACKAGE ? 0 : cpu; | |
| 235 | 259 | topo->thread_id = cpu; |
| 236 | 260 | topo->core_id = cpu; |
| 237 | − topo->socket_id = cpu; | |
| 238 | − topo->book_id = cpu; | |
| 239 | − topo->drawer_id = cpu; | |
| 261 | + topo->socket_id = id; | |
| 262 | + topo->book_id = id; | |
| 263 | + topo->drawer_id = id; | |
| 240 | 264 | if (cpu_present(cpu)) |
| 241 | 265 | cpumask_set_cpu(cpu, &cpus_with_topology); |
| 242 | 266 | } |
| @@ -254,6 +278,7 @@ static int __arch_update_cpu_topology(void) · 11 unmodified lines | ||
| 254 | 278 | struct sysinfo_15_1_x *info = tl_info; |
| 255 | 279 | int rc = 0; |
| 256 | 280 | |
| 281 | + mutex_lock(&smp_cpu_state_mutex); | |
| 257 | 282 | cpumask_clear(&cpus_with_topology); |
| 258 | 283 | if (MACHINE_HAS_TOPOLOGY) { |
| 259 | 284 | rc = 1; |
| @@ -263,6 +288,7 @@ static int __arch_update_cpu_topology(void) · 3 unmodified lines | ||
| 263 | 288 | update_cpu_masks(); |
| 264 | 289 | if (!MACHINE_HAS_TOPOLOGY) |
| 265 | 290 | topology_update_polarization_simple(); |
| 291 | + mutex_unlock(&smp_cpu_state_mutex); | |
| 266 | 292 | return rc; |
| 267 | 293 | } |
| 268 | 294 | |
| @@ -289,6 +315,11 @@ void topology_schedule_update(void) · 20 unmodified lines | ||
| 289 | 315 | schedule_work(&topology_work); |
| 290 | 316 | } |
| 291 | 317 | |
| 318 | +static void topology_flush_work(void) | |
| 319 | +{ | |
| 320 | + flush_work(&topology_work); | |
| 321 | +} | |
| 322 | + | |
| 292 | 323 | static void topology_timer_fn(unsigned long ignored) |
| 293 | 324 | { |
| 294 | 325 | if (ptf(PTF_CHECK)) |
| @@ -459,6 +490,12 @@ void __init topology_init_early(void) · 164 unmodified lines | ||
| 459 | 490 | struct sysinfo_15_1_x *info; |
| 460 | 491 | |
| 461 | 492 | set_sched_topology(s390_topology); |
| 493 | + if (topology_mode == TOPOLOGY_MODE_UNINITIALIZED) { | |
| 494 | + if (MACHINE_HAS_TOPOLOGY) | |
| 495 | + topology_mode = TOPOLOGY_MODE_HW; | |
| 496 | + else | |
| 497 | + topology_mode = TOPOLOGY_MODE_SINGLE; | |
| 498 | + } | |
| 462 | 499 | if (!MACHINE_HAS_TOPOLOGY) |
| 463 | 500 | goto out; |
| 464 | 501 | tl_info = memblock_virt_alloc(PAGE_SIZE, PAGE_SIZE); |
| @@ -474,12 +511,97 @@ out: · 9 unmodified lines | ||
| 474 | 511 | __arch_update_cpu_topology(); |
| 475 | 512 | } |
| 476 | 513 | |
| 514 | +static inline int topology_get_mode(int enabled) | |
| 515 | +{ | |
| 516 | + if (!enabled) | |
| 517 | + return TOPOLOGY_MODE_SINGLE; | |
| 518 | + return MACHINE_HAS_TOPOLOGY ? TOPOLOGY_MODE_HW : TOPOLOGY_MODE_PACKAGE; | |
| 519 | +} | |
| 520 | + | |
| 521 | +static inline int topology_is_enabled(void) | |
| 522 | +{ | |
| 523 | + return topology_mode != TOPOLOGY_MODE_SINGLE; | |
| 524 | +} | |
| 525 | + | |
| 526 | +static int __init topology_setup(char *str) | |
| 527 | +{ | |
| 528 | + bool enabled; | |
| 529 | + int rc; | |
| 530 | + | |
| 531 | + rc = kstrtobool(str, &enabled); | |
| 532 | + if (rc) | |
| 533 | + return rc; | |
| 534 | + topology_mode = topology_get_mode(enabled); | |
| 535 | + return 0; | |
| 536 | +} | |
| 537 | +early_param("topology", topology_setup); | |
| 538 | + | |
| 539 | +static int topology_ctl_handler(struct ctl_table *ctl, int write, | |
| 540 | + void __user *buffer, size_t *lenp, loff_t *ppos) | |
| 541 | +{ | |
| 542 | + unsigned int len; | |
| 543 | + int new_mode; | |
| 544 | + char buf[2]; | |
| 545 | + | |
| 546 | + if (!*lenp || *ppos) { | |
| 547 | + *lenp = 0; | |
| 548 | + return 0; | |
| 549 | + } | |
| 550 | + if (!write) { | |
| 551 | + strncpy(buf, topology_is_enabled() ? "1\n" : "0\n", | |
| 552 | + ARRAY_SIZE(buf)); | |
| 553 | + len = strnlen(buf, ARRAY_SIZE(buf)); | |
| 554 | + if (len > *lenp) | |
| 555 | + len = *lenp; | |
| 556 | + if (copy_to_user(buffer, buf, len)) | |
| 557 | + return -EFAULT; | |
| 558 | + goto out; | |
| 559 | + } | |
| 560 | + len = *lenp; | |
| 561 | + if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) | |
| 562 | + return -EFAULT; | |
| 563 | + if (buf[0] != '0' && buf[0] != '1') | |
| 564 | + return -EINVAL; | |
| 565 | + mutex_lock(&smp_cpu_state_mutex); | |
| 566 | + new_mode = topology_get_mode(buf[0] == '1'); | |
| 567 | + if (topology_mode != new_mode) { | |
| 568 | + topology_mode = new_mode; | |
| 569 | + topology_schedule_update(); | |
| 570 | + } | |
| 571 | + mutex_unlock(&smp_cpu_state_mutex); | |
| 572 | + topology_flush_work(); | |
| 573 | +out: | |
| 574 | + *lenp = len; | |
| 575 | + *ppos += len; | |
| 576 | + return 0; | |
| 577 | +} | |
| 578 | + | |
| 579 | +static struct ctl_table topology_ctl_table[] = { | |
| 580 | + { | |
| 581 | + .procname = "topology", | |
| 582 | + .mode = 0644, | |
| 583 | + .proc_handler = topology_ctl_handler, | |
| 584 | + }, | |
| 585 | + { }, | |
| 586 | +}; | |
| 587 | + | |
| 588 | +static struct ctl_table topology_dir_table[] = { | |
| 589 | + { | |
| 590 | + .procname = "s390", | |
| 591 | + .maxlen = 0, | |
| 592 | + .mode = 0555, | |
| 593 | + .child = topology_ctl_table, | |
| 594 | + }, | |
| 595 | + { }, | |
| 596 | +}; | |
| 597 | + | |
| 477 | 598 | static int __init topology_init(void) |
| 478 | 599 | { |
| 479 | 600 | if (MACHINE_HAS_TOPOLOGY) |
| 480 | 601 | set_topology_timer(); |
| 481 | 602 | else |
| 482 | 603 | topology_update_polarization_simple(); |
| 604 | + register_sysctl_table(topology_dir_table); | |
| 483 | 605 | return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); |
| 484 | 606 | } |
| 485 | 607 | device_initcall(topology_init); |
| @@ -56,13 +56,12 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, · 55 unmodified lines | ||
| 56 | 56 | static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, |
| 57 | 57 | unsigned long end, int write, struct page **pages, int *nr) |
| 58 | 58 | { |
| 59 | − unsigned long mask, result; | |
| 60 | 59 | struct page *head, *page; |
| 60 | + unsigned long mask; | |
| 61 | 61 | int refs; |
| 62 | 62 | |
| 63 | − result = write ? 0 : _SEGMENT_ENTRY_PROTECT; | |
| 64 | − mask = result | _SEGMENT_ENTRY_INVALID; | |
| 65 | − if ((pmd_val(pmd) & mask) != result) | |
| 63 | + mask = (write ? _SEGMENT_ENTRY_PROTECT : 0) | _SEGMENT_ENTRY_INVALID; | |
| 64 | + if ((pmd_val(pmd) & mask) != 0) | |
| 66 | 65 | return 0; |
| 67 | 66 | VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT)); |
| 68 | 67 | |
| @@ -136,10 +136,6 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned lo · 135 unmodified lines | ||
| 136 | 136 | /* Free all resources held by a thread. */ |
| 137 | 137 | extern void release_thread(struct task_struct *); |
| 138 | 138 | |
| 139 | −/* Copy and release all segment info associated with a VM */ | |
| 140 | −#define copy_segments(p, mm) do { } while(0) | |
| 141 | −#define release_segments(mm) do { } while(0) | |
| 142 | − | |
| 143 | 139 | /* |
| 144 | 140 | * FPU lazy state save handling. |
| 145 | 141 | */ |
| @@ -170,10 +170,6 @@ struct mm_struct; · 169 unmodified lines | ||
| 170 | 170 | /* Free all resources held by a thread. */ |
| 171 | 171 | extern void release_thread(struct task_struct *); |
| 172 | 172 | |
| 173 | −/* Copy and release all segment info associated with a VM */ | |
| 174 | −#define copy_segments(p, mm) do { } while (0) | |
| 175 | −#define release_segments(mm) do { } while (0) | |
| 176 | −#define forget_segments() do { } while (0) | |
| 177 | 173 | /* |
| 178 | 174 | * FPU lazy state save handling. |
| 179 | 175 | */ |
| @@ -43,9 +43,7 @@ enum { · 42 unmodified lines | ||
| 43 | 43 | GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4, |
| 44 | 44 | GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0, |
| 45 | 45 | |
| 46 | − /* Port H */ | |
| 47 | − GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4, | |
| 48 | − GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0, | |
| 46 | + /* Port H - Port H does not have a Data Register */ | |
| 49 | 47 | |
| 50 | 48 | /* Port I - not on device */ |
| 51 | 49 | |
| @@ -45,9 +45,7 @@ enum { · 44 unmodified lines | ||
| 45 | 45 | GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4, |
| 46 | 46 | GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0, |
| 47 | 47 | |
| 48 | − /* Port H */ | |
| 49 | − GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4, | |
| 50 | − GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0, | |
| 48 | + /* Port H - Port H does not have a Data Register */ | |
| 51 | 49 | |
| 52 | 50 | /* Port I - not on device */ |
| 53 | 51 | |
| @@ -67,7 +67,7 @@ enum { · 66 unmodified lines | ||
| 67 | 67 | GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0, |
| 68 | 68 | |
| 69 | 69 | /* PTQ */ |
| 70 | − GPIO_PTQ7, GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4, | |
| 70 | + GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4, | |
| 71 | 71 | GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0, |
| 72 | 72 | |
| 73 | 73 | /* PTR */ |
| @@ -40,7 +40,7 @@ enum { · 39 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | /* PTJ */ |
| 42 | 42 | GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3, |
| 43 | − GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, GPIO_PTJ7_RESV, | |
| 43 | + GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, | |
| 44 | 44 | |
| 45 | 45 | /* PTK */ |
| 46 | 46 | GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3, |
| @@ -48,7 +48,7 @@ enum { · 1 unmodified line | ||
| 48 | 48 | |
| 49 | 49 | /* PTL */ |
| 50 | 50 | GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3, |
| 51 | − GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, GPIO_PTL7_RESV, | |
| 51 | + GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, | |
| 52 | 52 | |
| 53 | 53 | /* PTM */ |
| 54 | 54 | GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3, |
| @@ -56,7 +56,7 @@ enum { · 1 unmodified line | ||
| 56 | 56 | |
| 57 | 57 | /* PTN */ |
| 58 | 58 | GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3, |
| 59 | − GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, GPIO_PTN7_RESV, | |
| 59 | + GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, | |
| 60 | 60 | |
| 61 | 61 | /* PTO */ |
| 62 | 62 | GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3, |
| @@ -68,7 +68,7 @@ enum { · 5 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | /* PTQ */ |
| 70 | 70 | GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3, |
| 71 | − GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, GPIO_PTQ7_RESV, | |
| 71 | + GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, | |
| 72 | 72 | |
| 73 | 73 | /* PTR */ |
| 74 | 74 | GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3, |
| @@ -409,5 +409,4 @@ CONFIG_CRYPTO_SEED=m · 408 unmodified lines | ||
| 409 | 409 | CONFIG_CRYPTO_SERPENT=m |
| 410 | 410 | CONFIG_CRYPTO_TEA=m |
| 411 | 411 | CONFIG_CRYPTO_TWOFISH=m |
| 412 | −CONFIG_CRYPTO_ZLIB=m | |
| 413 | 412 | CONFIG_CRYPTO_LZO=m |
| @@ -189,7 +189,6 @@ CONFIG_IP_NF_MATCH_ECN=m · 188 unmodified lines | ||
| 189 | 189 | CONFIG_IP_NF_MATCH_TTL=m |
| 190 | 190 | CONFIG_IP_NF_FILTER=y |
| 191 | 191 | CONFIG_IP_NF_TARGET_REJECT=y |
| 192 | −CONFIG_IP_NF_TARGET_ULOG=m | |
| 193 | 192 | CONFIG_IP_NF_MANGLE=m |
| 194 | 193 | CONFIG_IP_NF_TARGET_ECN=m |
| 195 | 194 | CONFIG_IP_NF_TARGET_TTL=m |
| @@ -521,7 +520,6 @@ CONFIG_CRYPTO_SEED=m · 325 unmodified lines | ||
| 521 | 520 | CONFIG_CRYPTO_SERPENT=m |
| 522 | 521 | CONFIG_CRYPTO_TEA=m |
| 523 | 522 | CONFIG_CRYPTO_TWOFISH=m |
| 524 | −CONFIG_CRYPTO_ZLIB=m | |
| 525 | 523 | CONFIG_CRYPTO_LZO=m |
| 526 | 524 | CONFIG_CRC_CCITT=m |
| 527 | 525 | CONFIG_CRC7=m |
| @@ -140,7 +140,7 @@ static int __init setup_maxnodemem(char *str) · 139 unmodified lines | ||
| 140 | 140 | { |
| 141 | 141 | char *endp; |
| 142 | 142 | unsigned long long maxnodemem; |
| 143 | − long node; | |
| 143 | + unsigned long node; | |
| 144 | 144 | |
| 145 | 145 | node = str ? simple_strtoul(str, &endp, 0) : INT_MAX; |
| 146 | 146 | if (node >= MAX_NUMNODES || *endp != ':') |
| @@ -58,11 +58,6 @@ static inline void release_thread(struct task_struct *task) · 57 unmodified lines | ||
| 58 | 58 | { |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | −static inline void mm_copy_segments(struct mm_struct *from_mm, | |
| 62 | − struct mm_struct *new_mm) | |
| 63 | −{ | |
| 64 | −} | |
| 65 | − | |
| 66 | 61 | #define init_stack (init_thread_union.stack) |
| 67 | 62 | |
| 68 | 63 | /* |
| @@ -98,7 +98,7 @@ static struct clocksource timer_clocksource = { · 97 unmodified lines | ||
| 98 | 98 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
| 99 | 99 | }; |
| 100 | 100 | |
| 101 | −static void __init timer_setup(void) | |
| 101 | +static void __init um_timer_setup(void) | |
| 102 | 102 | { |
| 103 | 103 | int err; |
| 104 | 104 | |
| @@ -132,5 +132,5 @@ void read_persistent_clock(struct timespec *ts) · 27 unmodified lines | ||
| 132 | 132 | void __init time_init(void) |
| 133 | 133 | { |
| 134 | 134 | timer_set_signal_handler(); |
| 135 | − late_time_init = timer_setup; | |
| 135 | + late_time_init = um_timer_setup; | |
| 136 | 136 | } |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #define s3 ((16 + 2 + (3 * 256)) * 4) |
| 34 | 34 | |
| 35 | 35 | /* register macros */ |
| 36 | −#define CTX %rdi | |
| 36 | +#define CTX %r12 | |
| 37 | 37 | #define RIO %rsi |
| 38 | 38 | |
| 39 | 39 | #define RX0 %rax |
| @@ -56,12 +56,12 @@ · 16 unmodified lines | ||
| 56 | 56 | #define RX2bh %ch |
| 57 | 57 | #define RX3bh %dh |
| 58 | 58 | |
| 59 | −#define RT0 %rbp | |
| 59 | +#define RT0 %rdi | |
| 60 | 60 | #define RT1 %rsi |
| 61 | 61 | #define RT2 %r8 |
| 62 | 62 | #define RT3 %r9 |
| 63 | 63 | |
| 64 | −#define RT0d %ebp | |
| 64 | +#define RT0d %edi | |
| 65 | 65 | #define RT1d %esi |
| 66 | 66 | #define RT2d %r8d |
| 67 | 67 | #define RT3d %r9d |
| @@ -120,13 +120,14 @@ · 52 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | ENTRY(__blowfish_enc_blk) |
| 122 | 122 | /* input: |
| 123 | − * %rdi: ctx, CTX | |
| 123 | + * %rdi: ctx | |
| 124 | 124 | * %rsi: dst |
| 125 | 125 | * %rdx: src |
| 126 | 126 | * %rcx: bool, if true: xor output |
| 127 | 127 | */ |
| 128 | − movq %rbp, %r11; | |
| 128 | + movq %r12, %r11; | |
| 129 | 129 | |
| 130 | + movq %rdi, CTX; | |
| 130 | 131 | movq %rsi, %r10; |
| 131 | 132 | movq %rdx, RIO; |
| 132 | 133 | |
| @@ -142,7 +143,7 @@ ENTRY(__blowfish_enc_blk) · 9 unmodified lines | ||
| 142 | 143 | round_enc(14); |
| 143 | 144 | add_roundkey_enc(16); |
| 144 | 145 | |
| 145 | − movq %r11, %rbp; | |
| 146 | + movq %r11, %r12; | |
| 146 | 147 | |
| 147 | 148 | movq %r10, RIO; |
| 148 | 149 | test %cl, %cl; |
| @@ -157,12 +158,13 @@ ENDPROC(__blowfish_enc_blk) · 8 unmodified lines | ||
| 157 | 158 | |
| 158 | 159 | ENTRY(blowfish_dec_blk) |
| 159 | 160 | /* input: |
| 160 | − * %rdi: ctx, CTX | |
| 161 | + * %rdi: ctx | |
| 161 | 162 | * %rsi: dst |
| 162 | 163 | * %rdx: src |
| 163 | 164 | */ |
| 164 | − movq %rbp, %r11; | |
| 165 | + movq %r12, %r11; | |
| 165 | 166 | |
| 167 | + movq %rdi, CTX; | |
| 166 | 168 | movq %rsi, %r10; |
| 167 | 169 | movq %rdx, RIO; |
| 168 | 170 | |
| @@ -181,7 +183,7 @@ ENTRY(blowfish_dec_blk) · 12 unmodified lines | ||
| 181 | 183 | movq %r10, RIO; |
| 182 | 184 | write_block(); |
| 183 | 185 | |
| 184 | − movq %r11, %rbp; | |
| 186 | + movq %r11, %r12; | |
| 185 | 187 | |
| 186 | 188 | ret; |
| 187 | 189 | ENDPROC(blowfish_dec_blk) |
| @@ -298,20 +300,21 @@ ENDPROC(blowfish_dec_blk) · 110 unmodified lines | ||
| 298 | 300 | |
| 299 | 301 | ENTRY(__blowfish_enc_blk_4way) |
| 300 | 302 | /* input: |
| 301 | − * %rdi: ctx, CTX | |
| 303 | + * %rdi: ctx | |
| 302 | 304 | * %rsi: dst |
| 303 | 305 | * %rdx: src |
| 304 | 306 | * %rcx: bool, if true: xor output |
| 305 | 307 | */ |
| 306 | − pushq %rbp; | |
| 308 | + pushq %r12; | |
| 307 | 309 | pushq %rbx; |
| 308 | 310 | pushq %rcx; |
| 309 | 311 | |
| 310 | − preload_roundkey_enc(0); | |
| 311 | − | |
| 312 | + movq %rdi, CTX | |
| 312 | 313 | movq %rsi, %r11; |
| 313 | 314 | movq %rdx, RIO; |
| 314 | 315 | |
| 316 | + preload_roundkey_enc(0); | |
| 317 | + | |
| 315 | 318 | read_block4(); |
| 316 | 319 | |
| 317 | 320 | round_enc4(0); |
| @@ -324,39 +327,40 @@ ENTRY(__blowfish_enc_blk_4way) · 6 unmodified lines | ||
| 324 | 327 | round_enc4(14); |
| 325 | 328 | add_preloaded_roundkey4(); |
| 326 | 329 | |
| 327 | − popq %rbp; | |
| 330 | + popq %r12; | |
| 328 | 331 | movq %r11, RIO; |
| 329 | 332 | |
| 330 | − test %bpl, %bpl; | |
| 333 | + test %r12b, %r12b; | |
| 331 | 334 | jnz .L__enc_xor4; |
| 332 | 335 | |
| 333 | 336 | write_block4(); |
| 334 | 337 | |
| 335 | 338 | popq %rbx; |
| 336 | − popq %rbp; | |
| 339 | + popq %r12; | |
| 337 | 340 | ret; |
| 338 | 341 | |
| 339 | 342 | .L__enc_xor4: |
| 340 | 343 | xor_block4(); |
| 341 | 344 | |
| 342 | 345 | popq %rbx; |
| 343 | − popq %rbp; | |
| 346 | + popq %r12; | |
| 344 | 347 | ret; |
| 345 | 348 | ENDPROC(__blowfish_enc_blk_4way) |
| 346 | 349 | |
| 347 | 350 | ENTRY(blowfish_dec_blk_4way) |
| 348 | 351 | /* input: |
| 349 | − * %rdi: ctx, CTX | |
| 352 | + * %rdi: ctx | |
| 350 | 353 | * %rsi: dst |
| 351 | 354 | * %rdx: src |
| 352 | 355 | */ |
| 353 | − pushq %rbp; | |
| 356 | + pushq %r12; | |
| 354 | 357 | pushq %rbx; |
| 355 | − preload_roundkey_dec(17); | |
| 356 | 358 | |
| 357 | − movq %rsi, %r11; | |
| 359 | + movq %rdi, CTX; | |
| 360 | + movq %rsi, %r11 | |
| 358 | 361 | movq %rdx, RIO; |
| 359 | 362 | |
| 363 | + preload_roundkey_dec(17); | |
| 360 | 364 | read_block4(); |
| 361 | 365 | |
| 362 | 366 | round_dec4(17); |
| @@ -373,7 +377,7 @@ ENTRY(blowfish_dec_blk_4way) · 10 unmodified lines | ||
| 373 | 377 | write_block4(); |
| 374 | 378 | |
| 375 | 379 | popq %rbx; |
| 376 | − popq %rbp; | |
| 380 | + popq %r12; | |
| 377 | 381 | |
| 378 | 382 | ret; |
| 379 | 383 | ENDPROC(blowfish_dec_blk_4way) |
| @@ -75,17 +75,17 @@ · 74 unmodified lines | ||
| 75 | 75 | #define RCD1bh %dh |
| 76 | 76 | |
| 77 | 77 | #define RT0 %rsi |
| 78 | −#define RT1 %rbp | |
| 78 | +#define RT1 %r12 | |
| 79 | 79 | #define RT2 %r8 |
| 80 | 80 | |
| 81 | 81 | #define RT0d %esi |
| 82 | −#define RT1d %ebp | |
| 82 | +#define RT1d %r12d | |
| 83 | 83 | #define RT2d %r8d |
| 84 | 84 | |
| 85 | 85 | #define RT2bl %r8b |
| 86 | 86 | |
| 87 | 87 | #define RXOR %r9 |
| 88 | −#define RRBP %r10 | |
| 88 | +#define RR12 %r10 | |
| 89 | 89 | #define RDST %r11 |
| 90 | 90 | |
| 91 | 91 | #define RXORd %r9d |
| @@ -197,7 +197,7 @@ ENTRY(__camellia_enc_blk) · 105 unmodified lines | ||
| 197 | 197 | * %rdx: src |
| 198 | 198 | * %rcx: bool xor |
| 199 | 199 | */ |
| 200 | − movq %rbp, RRBP; | |
| 200 | + movq %r12, RR12; | |
| 201 | 201 | |
| 202 | 202 | movq %rcx, RXOR; |
| 203 | 203 | movq %rsi, RDST; |
| @@ -227,13 +227,13 @@ ENTRY(__camellia_enc_blk) · 23 unmodified lines | ||
| 227 | 227 | |
| 228 | 228 | enc_outunpack(mov, RT1); |
| 229 | 229 | |
| 230 | − movq RRBP, %rbp; | |
| 230 | + movq RR12, %r12; | |
| 231 | 231 | ret; |
| 232 | 232 | |
| 233 | 233 | .L__enc_xor: |
| 234 | 234 | enc_outunpack(xor, RT1); |
| 235 | 235 | |
| 236 | − movq RRBP, %rbp; | |
| 236 | + movq RR12, %r12; | |
| 237 | 237 | ret; |
| 238 | 238 | ENDPROC(__camellia_enc_blk) |
| 239 | 239 | |
| @@ -248,7 +248,7 @@ ENTRY(camellia_dec_blk) · 8 unmodified lines | ||
| 248 | 248 | movl $24, RXORd; |
| 249 | 249 | cmovel RXORd, RT2d; /* max */ |
| 250 | 250 | |
| 251 | − movq %rbp, RRBP; | |
| 251 | + movq %r12, RR12; | |
| 252 | 252 | movq %rsi, RDST; |
| 253 | 253 | movq %rdx, RIO; |
| 254 | 254 | |
| @@ -271,7 +271,7 @@ ENTRY(camellia_dec_blk) · 16 unmodified lines | ||
| 271 | 271 | |
| 272 | 272 | dec_outunpack(); |
| 273 | 273 | |
| 274 | − movq RRBP, %rbp; | |
| 274 | + movq RR12, %r12; | |
| 275 | 275 | ret; |
| 276 | 276 | ENDPROC(camellia_dec_blk) |
| 277 | 277 | |
| @@ -433,7 +433,7 @@ ENTRY(__camellia_enc_blk_2way) · 155 unmodified lines | ||
| 433 | 433 | */ |
| 434 | 434 | pushq %rbx; |
| 435 | 435 | |
| 436 | − movq %rbp, RRBP; | |
| 436 | + movq %r12, RR12; | |
| 437 | 437 | movq %rcx, RXOR; |
| 438 | 438 | movq %rsi, RDST; |
| 439 | 439 | movq %rdx, RIO; |
| @@ -461,14 +461,14 @@ ENTRY(__camellia_enc_blk_2way) · 21 unmodified lines | ||
| 461 | 461 | |
| 462 | 462 | enc_outunpack2(mov, RT2); |
| 463 | 463 | |
| 464 | − movq RRBP, %rbp; | |
| 464 | + movq RR12, %r12; | |
| 465 | 465 | popq %rbx; |
| 466 | 466 | ret; |
| 467 | 467 | |
| 468 | 468 | .L__enc2_xor: |
| 469 | 469 | enc_outunpack2(xor, RT2); |
| 470 | 470 | |
| 471 | − movq RRBP, %rbp; | |
| 471 | + movq RR12, %r12; | |
| 472 | 472 | popq %rbx; |
| 473 | 473 | ret; |
| 474 | 474 | ENDPROC(__camellia_enc_blk_2way) |
| @@ -485,7 +485,7 @@ ENTRY(camellia_dec_blk_2way) · 10 unmodified lines | ||
| 485 | 485 | cmovel RXORd, RT2d; /* max */ |
| 486 | 486 | |
| 487 | 487 | movq %rbx, RXOR; |
| 488 | − movq %rbp, RRBP; | |
| 488 | + movq %r12, RR12; | |
| 489 | 489 | movq %rsi, RDST; |
| 490 | 490 | movq %rdx, RIO; |
| 491 | 491 | |
| @@ -508,7 +508,7 @@ ENTRY(camellia_dec_blk_2way) · 16 unmodified lines | ||
| 508 | 508 | |
| 509 | 509 | dec_outunpack2(); |
| 510 | 510 | |
| 511 | − movq RRBP, %rbp; | |
| 511 | + movq RR12, %r12; | |
| 512 | 512 | movq RXOR, %rbx; |
| 513 | 513 | ret; |
| 514 | 514 | ENDPROC(camellia_dec_blk_2way) |
| @@ -47,7 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | /********************************************************************** |
| 48 | 48 | 16-way AVX cast5 |
| 49 | 49 | **********************************************************************/ |
| 50 | −#define CTX %rdi | |
| 50 | +#define CTX %r15 | |
| 51 | 51 | |
| 52 | 52 | #define RL1 %xmm0 |
| 53 | 53 | #define RR1 %xmm1 |
| @@ -70,8 +70,8 @@ · 16 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | #define RTMP %xmm15 |
| 72 | 72 | |
| 73 | −#define RID1 %rbp | |
| 74 | −#define RID1d %ebp | |
| 73 | +#define RID1 %rdi | |
| 74 | +#define RID1d %edi | |
| 75 | 75 | #define RID2 %rsi |
| 76 | 76 | #define RID2d %esi |
| 77 | 77 | |
| @@ -226,7 +226,7 @@ · 148 unmodified lines | ||
| 226 | 226 | .align 16 |
| 227 | 227 | __cast5_enc_blk16: |
| 228 | 228 | /* input: |
| 229 | − * %rdi: ctx, CTX | |
| 229 | + * %rdi: ctx | |
| 230 | 230 | * RL1: blocks 1 and 2 |
| 231 | 231 | * RR1: blocks 3 and 4 |
| 232 | 232 | * RL2: blocks 5 and 6 |
| @@ -246,9 +246,11 @@ __cast5_enc_blk16: · 13 unmodified lines | ||
| 246 | 246 | * RR4: encrypted blocks 15 and 16 |
| 247 | 247 | */ |
| 248 | 248 | |
| 249 | − pushq %rbp; | |
| 249 | + pushq %r15; | |
| 250 | 250 | pushq %rbx; |
| 251 | 251 | |
| 252 | + movq %rdi, CTX; | |
| 253 | + | |
| 252 | 254 | vmovdqa .Lbswap_mask, RKM; |
| 253 | 255 | vmovd .Lfirst_mask, R1ST; |
| 254 | 256 | vmovd .L32_mask, R32; |
| @@ -283,7 +285,7 @@ __cast5_enc_blk16: · 28 unmodified lines | ||
| 283 | 285 | |
| 284 | 286 | .L__skip_enc: |
| 285 | 287 | popq %rbx; |
| 286 | − popq %rbp; | |
| 288 | + popq %r15; | |
| 287 | 289 | |
| 288 | 290 | vmovdqa .Lbswap_mask, RKM; |
| 289 | 291 | |
| @@ -298,7 +300,7 @@ ENDPROC(__cast5_enc_blk16) · 8 unmodified lines | ||
| 298 | 300 | .align 16 |
| 299 | 301 | __cast5_dec_blk16: |
| 300 | 302 | /* input: |
| 301 | − * %rdi: ctx, CTX | |
| 303 | + * %rdi: ctx | |
| 302 | 304 | * RL1: encrypted blocks 1 and 2 |
| 303 | 305 | * RR1: encrypted blocks 3 and 4 |
| 304 | 306 | * RL2: encrypted blocks 5 and 6 |
| @@ -318,9 +320,11 @@ __cast5_dec_blk16: · 13 unmodified lines | ||
| 318 | 320 | * RR4: decrypted blocks 15 and 16 |
| 319 | 321 | */ |
| 320 | 322 | |
| 321 | − pushq %rbp; | |
| 323 | + pushq %r15; | |
| 322 | 324 | pushq %rbx; |
| 323 | 325 | |
| 326 | + movq %rdi, CTX; | |
| 327 | + | |
| 324 | 328 | vmovdqa .Lbswap_mask, RKM; |
| 325 | 329 | vmovd .Lfirst_mask, R1ST; |
| 326 | 330 | vmovd .L32_mask, R32; |
| @@ -356,7 +360,7 @@ __cast5_dec_blk16: · 29 unmodified lines | ||
| 356 | 360 | |
| 357 | 361 | vmovdqa .Lbswap_mask, RKM; |
| 358 | 362 | popq %rbx; |
| 359 | − popq %rbp; | |
| 363 | + popq %r15; | |
| 360 | 364 | |
| 361 | 365 | outunpack_blocks(RR1, RL1, RTMP, RX, RKM); |
| 362 | 366 | outunpack_blocks(RR2, RL2, RTMP, RX, RKM); |
| @@ -372,12 +376,14 @@ ENDPROC(__cast5_dec_blk16) · 9 unmodified lines | ||
| 372 | 376 | |
| 373 | 377 | ENTRY(cast5_ecb_enc_16way) |
| 374 | 378 | /* input: |
| 375 | − * %rdi: ctx, CTX | |
| 379 | + * %rdi: ctx | |
| 376 | 380 | * %rsi: dst |
| 377 | 381 | * %rdx: src |
| 378 | 382 | */ |
| 379 | 383 | FRAME_BEGIN |
| 384 | + pushq %r15; | |
| 380 | 385 | |
| 386 | + movq %rdi, CTX; | |
| 381 | 387 | movq %rsi, %r11; |
| 382 | 388 | |
| 383 | 389 | vmovdqu (0*4*4)(%rdx), RL1; |
| @@ -400,18 +406,22 @@ ENTRY(cast5_ecb_enc_16way) · 16 unmodified lines | ||
| 400 | 406 | vmovdqu RR4, (6*4*4)(%r11); |
| 401 | 407 | vmovdqu RL4, (7*4*4)(%r11); |
| 402 | 408 | |
| 409 | + popq %r15; | |
| 403 | 410 | FRAME_END |
| 404 | 411 | ret; |
| 405 | 412 | ENDPROC(cast5_ecb_enc_16way) |
| 406 | 413 | |
| 407 | 414 | ENTRY(cast5_ecb_dec_16way) |
| 408 | 415 | /* input: |
| 409 | − * %rdi: ctx, CTX | |
| 416 | + * %rdi: ctx | |
| 410 | 417 | * %rsi: dst |
| 411 | 418 | * %rdx: src |
| 412 | 419 | */ |
| 413 | 420 | |
| 414 | 421 | FRAME_BEGIN |
| 422 | + pushq %r15; | |
| 423 | + | |
| 424 | + movq %rdi, CTX; | |
| 415 | 425 | movq %rsi, %r11; |
| 416 | 426 | |
| 417 | 427 | vmovdqu (0*4*4)(%rdx), RL1; |
| @@ -434,20 +444,22 @@ ENTRY(cast5_ecb_dec_16way) · 16 unmodified lines | ||
| 434 | 444 | vmovdqu RR4, (6*4*4)(%r11); |
| 435 | 445 | vmovdqu RL4, (7*4*4)(%r11); |
| 436 | 446 | |
| 447 | + popq %r15; | |
| 437 | 448 | FRAME_END |
| 438 | 449 | ret; |
| 439 | 450 | ENDPROC(cast5_ecb_dec_16way) |
| 440 | 451 | |
| 441 | 452 | ENTRY(cast5_cbc_dec_16way) |
| 442 | 453 | /* input: |
| 443 | − * %rdi: ctx, CTX | |
| 454 | + * %rdi: ctx | |
| 444 | 455 | * %rsi: dst |
| 445 | 456 | * %rdx: src |
| 446 | 457 | */ |
| 447 | 458 | FRAME_BEGIN |
| 448 | − | |
| 449 | 459 | pushq %r12; |
| 460 | + pushq %r15; | |
| 450 | 461 | |
| 462 | + movq %rdi, CTX; | |
| 451 | 463 | movq %rsi, %r11; |
| 452 | 464 | movq %rdx, %r12; |
| 453 | 465 | |
| @@ -483,23 +495,24 @@ ENTRY(cast5_cbc_dec_16way) · 29 unmodified lines | ||
| 483 | 495 | vmovdqu RR4, (6*16)(%r11); |
| 484 | 496 | vmovdqu RL4, (7*16)(%r11); |
| 485 | 497 | |
| 498 | + popq %r15; | |
| 486 | 499 | popq %r12; |
| 487 | − | |
| 488 | 500 | FRAME_END |
| 489 | 501 | ret; |
| 490 | 502 | ENDPROC(cast5_cbc_dec_16way) |
| 491 | 503 | |
| 492 | 504 | ENTRY(cast5_ctr_16way) |
| 493 | 505 | /* input: |
| 494 | − * %rdi: ctx, CTX | |
| 506 | + * %rdi: ctx | |
| 495 | 507 | * %rsi: dst |
| 496 | 508 | * %rdx: src |
| 497 | 509 | * %rcx: iv (big endian, 64bit) |
| 498 | 510 | */ |
| 499 | 511 | FRAME_BEGIN |
| 500 | − | |
| 501 | 512 | pushq %r12; |
| 513 | + pushq %r15; | |
| 502 | 514 | |
| 515 | + movq %rdi, CTX; | |
| 503 | 516 | movq %rsi, %r11; |
| 504 | 517 | movq %rdx, %r12; |
| 505 | 518 | |
| @@ -558,8 +571,8 @@ ENTRY(cast5_ctr_16way) · 52 unmodified lines | ||
| 558 | 571 | vmovdqu RR4, (6*16)(%r11); |
| 559 | 572 | vmovdqu RL4, (7*16)(%r11); |
| 560 | 573 | |
| 574 | + popq %r15; | |
| 561 | 575 | popq %r12; |
| 562 | − | |
| 563 | 576 | FRAME_END |
| 564 | 577 | ret; |
| 565 | 578 | ENDPROC(cast5_ctr_16way) |
| @@ -47,7 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | /********************************************************************** |
| 48 | 48 | 8-way AVX cast6 |
| 49 | 49 | **********************************************************************/ |
| 50 | −#define CTX %rdi | |
| 50 | +#define CTX %r15 | |
| 51 | 51 | |
| 52 | 52 | #define RA1 %xmm0 |
| 53 | 53 | #define RB1 %xmm1 |
| @@ -70,8 +70,8 @@ · 16 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | #define RTMP %xmm15 |
| 72 | 72 | |
| 73 | −#define RID1 %rbp | |
| 74 | −#define RID1d %ebp | |
| 73 | +#define RID1 %rdi | |
| 74 | +#define RID1d %edi | |
| 75 | 75 | #define RID2 %rsi |
| 76 | 76 | #define RID2d %esi |
| 77 | 77 | |
| @@ -264,15 +264,17 @@ · 186 unmodified lines | ||
| 264 | 264 | .align 8 |
| 265 | 265 | __cast6_enc_blk8: |
| 266 | 266 | /* input: |
| 267 | − * %rdi: ctx, CTX | |
| 267 | + * %rdi: ctx | |
| 268 | 268 | * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks |
| 269 | 269 | * output: |
| 270 | 270 | * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks |
| 271 | 271 | */ |
| 272 | 272 | |
| 273 | − pushq %rbp; | |
| 273 | + pushq %r15; | |
| 274 | 274 | pushq %rbx; |
| 275 | 275 | |
| 276 | + movq %rdi, CTX; | |
| 277 | + | |
| 276 | 278 | vmovdqa .Lbswap_mask, RKM; |
| 277 | 279 | vmovd .Lfirst_mask, R1ST; |
| 278 | 280 | vmovd .L32_mask, R32; |
| @@ -297,7 +299,7 @@ __cast6_enc_blk8: · 18 unmodified lines | ||
| 297 | 299 | QBAR(11); |
| 298 | 300 | |
| 299 | 301 | popq %rbx; |
| 300 | − popq %rbp; | |
| 302 | + popq %r15; | |
| 301 | 303 | |
| 302 | 304 | vmovdqa .Lbswap_mask, RKM; |
| 303 | 305 | |
| @@ -310,15 +312,17 @@ ENDPROC(__cast6_enc_blk8) · 6 unmodified lines | ||
| 310 | 312 | .align 8 |
| 311 | 313 | __cast6_dec_blk8: |
| 312 | 314 | /* input: |
| 313 | − * %rdi: ctx, CTX | |
| 315 | + * %rdi: ctx | |
| 314 | 316 | * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks |
| 315 | 317 | * output: |
| 316 | 318 | * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: decrypted blocks |
| 317 | 319 | */ |
| 318 | 320 | |
| 319 | − pushq %rbp; | |
| 321 | + pushq %r15; | |
| 320 | 322 | pushq %rbx; |
| 321 | 323 | |
| 324 | + movq %rdi, CTX; | |
| 325 | + | |
| 322 | 326 | vmovdqa .Lbswap_mask, RKM; |
| 323 | 327 | vmovd .Lfirst_mask, R1ST; |
| 324 | 328 | vmovd .L32_mask, R32; |
| @@ -343,7 +347,7 @@ __cast6_dec_blk8: · 18 unmodified lines | ||
| 343 | 347 | QBAR(0); |
| 344 | 348 | |
| 345 | 349 | popq %rbx; |
| 346 | − popq %rbp; | |
| 350 | + popq %r15; | |
| 347 | 351 | |
| 348 | 352 | vmovdqa .Lbswap_mask, RKM; |
| 349 | 353 | outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM); |
| @@ -354,12 +358,14 @@ ENDPROC(__cast6_dec_blk8) · 4 unmodified lines | ||
| 354 | 358 | |
| 355 | 359 | ENTRY(cast6_ecb_enc_8way) |
| 356 | 360 | /* input: |
| 357 | − * %rdi: ctx, CTX | |
| 361 | + * %rdi: ctx | |
| 358 | 362 | * %rsi: dst |
| 359 | 363 | * %rdx: src |
| 360 | 364 | */ |
| 361 | 365 | FRAME_BEGIN |
| 366 | + pushq %r15; | |
| 362 | 367 | |
| 368 | + movq %rdi, CTX; | |
| 363 | 369 | movq %rsi, %r11; |
| 364 | 370 | |
| 365 | 371 | load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
| @@ -368,18 +374,21 @@ ENTRY(cast6_ecb_enc_8way) · 2 unmodified lines | ||
| 368 | 374 | |
| 369 | 375 | store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
| 370 | 376 | |
| 377 | + popq %r15; | |
| 371 | 378 | FRAME_END |
| 372 | 379 | ret; |
| 373 | 380 | ENDPROC(cast6_ecb_enc_8way) |
| 374 | 381 | |
| 375 | 382 | ENTRY(cast6_ecb_dec_8way) |
| 376 | 383 | /* input: |
| 377 | − * %rdi: ctx, CTX | |
| 384 | + * %rdi: ctx | |
| 378 | 385 | * %rsi: dst |
| 379 | 386 | * %rdx: src |
| 380 | 387 | */ |
| 381 | 388 | FRAME_BEGIN |
| 389 | + pushq %r15; | |
| 382 | 390 | |
| 391 | + movq %rdi, CTX; | |
| 383 | 392 | movq %rsi, %r11; |
| 384 | 393 | |
| 385 | 394 | load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
| @@ -388,20 +397,22 @@ ENTRY(cast6_ecb_dec_8way) · 2 unmodified lines | ||
| 388 | 397 | |
| 389 | 398 | store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
| 390 | 399 | |
| 400 | + popq %r15; | |
| 391 | 401 | FRAME_END |
| 392 | 402 | ret; |
| 393 | 403 | ENDPROC(cast6_ecb_dec_8way) |
| 394 | 404 | |
| 395 | 405 | ENTRY(cast6_cbc_dec_8way) |
| 396 | 406 | /* input: |
| 397 | − * %rdi: ctx, CTX | |
| 407 | + * %rdi: ctx | |
| 398 | 408 | * %rsi: dst |
| 399 | 409 | * %rdx: src |
| 400 | 410 | */ |
| 401 | 411 | FRAME_BEGIN |
| 402 | − | |
| 403 | 412 | pushq %r12; |
| 413 | + pushq %r15; | |
| 404 | 414 | |
| 415 | + movq %rdi, CTX; | |
| 405 | 416 | movq %rsi, %r11; |
| 406 | 417 | movq %rdx, %r12; |
| 407 | 418 | |
| @@ -411,8 +422,8 @@ ENTRY(cast6_cbc_dec_8way) · 3 unmodified lines | ||
| 411 | 422 | |
| 412 | 423 | store_cbc_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
| 413 | 424 | |
| 425 | + popq %r15; | |
| 414 | 426 | popq %r12; |
| 415 | − | |
| 416 | 427 | FRAME_END |
| 417 | 428 | ret; |
| 418 | 429 | ENDPROC(cast6_cbc_dec_8way) |
| @@ -425,9 +436,10 @@ ENTRY(cast6_ctr_8way) · 6 unmodified lines | ||
| 425 | 436 | * %rcx: iv (little endian, 128bit) |
| 426 | 437 | */ |
| 427 | 438 | FRAME_BEGIN |
| 428 | − | |
| 429 | 439 | pushq %r12; |
| 440 | + pushq %r15 | |
| 430 | 441 | |
| 442 | + movq %rdi, CTX; | |
| 431 | 443 | movq %rsi, %r11; |
| 432 | 444 | movq %rdx, %r12; |
| 433 | 445 | |
| @@ -438,8 +450,8 @@ ENTRY(cast6_ctr_8way) · 4 unmodified lines | ||
| 438 | 450 | |
| 439 | 451 | store_ctr_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
| 440 | 452 | |
| 453 | + popq %r15; | |
| 441 | 454 | popq %r12; |
| 442 | − | |
| 443 | 455 | FRAME_END |
| 444 | 456 | ret; |
| 445 | 457 | ENDPROC(cast6_ctr_8way) |
| @@ -452,7 +464,9 @@ ENTRY(cast6_xts_enc_8way) · 6 unmodified lines | ||
| 452 | 464 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
| 453 | 465 | */ |
| 454 | 466 | FRAME_BEGIN |
| 467 | + pushq %r15; | |
| 455 | 468 | |
| 469 | + movq %rdi, CTX | |
| 456 | 470 | movq %rsi, %r11; |
| 457 | 471 | |
| 458 | 472 | /* regs <= src, dst <= IVs, regs <= regs xor IVs */ |
| @@ -464,6 +478,7 @@ ENTRY(cast6_xts_enc_8way) · 5 unmodified lines | ||
| 464 | 478 | /* dst <= regs xor IVs(in dst) */ |
| 465 | 479 | store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
| 466 | 480 | |
| 481 | + popq %r15; | |
| 467 | 482 | FRAME_END |
| 468 | 483 | ret; |
| 469 | 484 | ENDPROC(cast6_xts_enc_8way) |
| @@ -476,7 +491,9 @@ ENTRY(cast6_xts_dec_8way) · 6 unmodified lines | ||
| 476 | 491 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
| 477 | 492 | */ |
| 478 | 493 | FRAME_BEGIN |
| 494 | + pushq %r15; | |
| 479 | 495 | |
| 496 | + movq %rdi, CTX | |
| 480 | 497 | movq %rsi, %r11; |
| 481 | 498 | |
| 482 | 499 | /* regs <= src, dst <= IVs, regs <= regs xor IVs */ |
| @@ -488,6 +505,7 @@ ENTRY(cast6_xts_dec_8way) · 5 unmodified lines | ||
| 488 | 505 | /* dst <= regs xor IVs(in dst) */ |
| 489 | 506 | store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
| 490 | 507 | |
| 508 | + popq %r15; | |
| 491 | 509 | FRAME_END |
| 492 | 510 | ret; |
| 493 | 511 | ENDPROC(cast6_xts_dec_8way) |
| @@ -64,12 +64,12 @@ · 63 unmodified lines | ||
| 64 | 64 | #define RW2bh %ch |
| 65 | 65 | |
| 66 | 66 | #define RT0 %r15 |
| 67 | −#define RT1 %rbp | |
| 67 | +#define RT1 %rsi | |
| 68 | 68 | #define RT2 %r14 |
| 69 | 69 | #define RT3 %rdx |
| 70 | 70 | |
| 71 | 71 | #define RT0d %r15d |
| 72 | −#define RT1d %ebp | |
| 72 | +#define RT1d %esi | |
| 73 | 73 | #define RT2d %r14d |
| 74 | 74 | #define RT3d %edx |
| 75 | 75 | |
| @@ -177,13 +177,14 @@ ENTRY(des3_ede_x86_64_crypt_blk) · 101 unmodified lines | ||
| 177 | 177 | * %rsi: dst |
| 178 | 178 | * %rdx: src |
| 179 | 179 | */ |
| 180 | − pushq %rbp; | |
| 181 | 180 | pushq %rbx; |
| 182 | 181 | pushq %r12; |
| 183 | 182 | pushq %r13; |
| 184 | 183 | pushq %r14; |
| 185 | 184 | pushq %r15; |
| 186 | 185 | |
| 186 | + pushq %rsi; /* dst */ | |
| 187 | + | |
| 187 | 188 | read_block(%rdx, RL0, RR0); |
| 188 | 189 | initial_permutation(RL0, RR0); |
| 189 | 190 | |
| @@ -241,6 +242,8 @@ ENTRY(des3_ede_x86_64_crypt_blk) · 51 unmodified lines | ||
| 241 | 242 | round1(32+15, RL0, RR0, dummy2); |
| 242 | 243 | |
| 243 | 244 | final_permutation(RR0, RL0); |
| 245 | + | |
| 246 | + popq %rsi /* dst */ | |
| 244 | 247 | write_block(%rsi, RR0, RL0); |
| 245 | 248 | |
| 246 | 249 | popq %r15; |
| @@ -248,7 +251,6 @@ ENTRY(des3_ede_x86_64_crypt_blk) · 1 unmodified line | ||
| 248 | 251 | popq %r13; |
| 249 | 252 | popq %r12; |
| 250 | 253 | popq %rbx; |
| 251 | − popq %rbp; | |
| 252 | 254 | |
| 253 | 255 | ret; |
| 254 | 256 | ENDPROC(des3_ede_x86_64_crypt_blk) |
| @@ -432,13 +434,14 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) · 177 unmodified lines | ||
| 432 | 434 | * %rdx: src (3 blocks) |
| 433 | 435 | */ |
| 434 | 436 | |
| 435 | − pushq %rbp; | |
| 436 | 437 | pushq %rbx; |
| 437 | 438 | pushq %r12; |
| 438 | 439 | pushq %r13; |
| 439 | 440 | pushq %r14; |
| 440 | 441 | pushq %r15; |
| 441 | 442 | |
| 443 | + pushq %rsi /* dst */ | |
| 444 | + | |
| 442 | 445 | /* load input */ |
| 443 | 446 | movl 0 * 4(%rdx), RL0d; |
| 444 | 447 | movl 1 * 4(%rdx), RR0d; |
| @@ -520,6 +523,7 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) · 75 unmodified lines | ||
| 520 | 523 | bswapl RR2d; |
| 521 | 524 | bswapl RL2d; |
| 522 | 525 | |
| 526 | + popq %rsi /* dst */ | |
| 523 | 527 | movl RR0d, 0 * 4(%rsi); |
| 524 | 528 | movl RL0d, 1 * 4(%rsi); |
| 525 | 529 | movl RR1d, 2 * 4(%rsi); |
| @@ -532,7 +536,6 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) · 6 unmodified lines | ||
| 532 | 536 | popq %r13; |
| 533 | 537 | popq %r12; |
| 534 | 538 | popq %rbx; |
| 535 | − popq %rbp; | |
| 536 | 539 | |
| 537 | 540 | ret; |
| 538 | 541 | ENDPROC(des3_ede_x86_64_crypt_blk_3way) |
| @@ -89,7 +89,7 @@ · 88 unmodified lines | ||
| 89 | 89 | #define REG_RE %rdx |
| 90 | 90 | #define REG_RTA %r12 |
| 91 | 91 | #define REG_RTB %rbx |
| 92 | −#define REG_T1 %ebp | |
| 92 | +#define REG_T1 %r11d | |
| 93 | 93 | #define xmm_mov vmovups |
| 94 | 94 | #define avx2_zeroupper vzeroupper |
| 95 | 95 | #define RND_F1 1 |
| @@ -637,7 +637,6 @@ _loop3: · 541 unmodified lines | ||
| 637 | 637 | ENTRY(\name) |
| 638 | 638 | |
| 639 | 639 | push %rbx |
| 640 | − push %rbp | |
| 641 | 640 | push %r12 |
| 642 | 641 | push %r13 |
| 643 | 642 | push %r14 |
| @@ -673,7 +672,6 @@ _loop3: · 29 unmodified lines | ||
| 673 | 672 | pop %r14 |
| 674 | 673 | pop %r13 |
| 675 | 674 | pop %r12 |
| 676 | − pop %rbp | |
| 677 | 675 | pop %rbx |
| 678 | 676 | |
| 679 | 677 | ret |
| @@ -37,7 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #define REG_A %ecx |
| 38 | 38 | #define REG_B %esi |
| 39 | 39 | #define REG_C %edi |
| 40 | −#define REG_D %ebp | |
| 40 | +#define REG_D %r12d | |
| 41 | 41 | #define REG_E %edx |
| 42 | 42 | |
| 43 | 43 | #define REG_T1 %eax |
| @@ -74,10 +74,10 @@ · 30 unmodified lines | ||
| 74 | 74 | ENTRY(\name) |
| 75 | 75 | |
| 76 | 76 | push %rbx |
| 77 | − push %rbp | |
| 78 | 77 | push %r12 |
| 78 | + push %rbp | |
| 79 | + mov %rsp, %rbp | |
| 79 | 80 | |
| 80 | − mov %rsp, %r12 | |
| 81 | 81 | sub $64, %rsp # allocate workspace |
| 82 | 82 | and $~15, %rsp # align stack |
| 83 | 83 | |
| @@ -99,10 +99,9 @@ · 15 unmodified lines | ||
| 99 | 99 | xor %rax, %rax |
| 100 | 100 | rep stosq |
| 101 | 101 | |
| 102 | − mov %r12, %rsp # deallocate workspace | |
| 103 | − | |
| 104 | − pop %r12 | |
| 102 | + mov %rbp, %rsp # deallocate workspace | |
| 105 | 103 | pop %rbp |
| 104 | + pop %r12 | |
| 106 | 105 | pop %rbx |
| 107 | 106 | ret |
| 108 | 107 | |
| @@ -103,7 +103,7 @@ SRND = %rsi # clobbers INP · 102 unmodified lines | ||
| 103 | 103 | c = %ecx |
| 104 | 104 | d = %r8d |
| 105 | 105 | e = %edx |
| 106 | −TBL = %rbp | |
| 106 | +TBL = %r12 | |
| 107 | 107 | a = %eax |
| 108 | 108 | b = %ebx |
| 109 | 109 | |
| @@ -350,13 +350,13 @@ a = TMP_ · 240 unmodified lines | ||
| 350 | 350 | ENTRY(sha256_transform_avx) |
| 351 | 351 | .align 32 |
| 352 | 352 | pushq %rbx |
| 353 | − pushq %rbp | |
| 353 | + pushq %r12 | |
| 354 | 354 | pushq %r13 |
| 355 | 355 | pushq %r14 |
| 356 | 356 | pushq %r15 |
| 357 | − pushq %r12 | |
| 357 | + pushq %rbp | |
| 358 | + movq %rsp, %rbp | |
| 358 | 359 | |
| 359 | − mov %rsp, %r12 | |
| 360 | 360 | subq $STACK_SIZE, %rsp # allocate stack space |
| 361 | 361 | and $~15, %rsp # align stack pointer |
| 362 | 362 | |
| @@ -452,13 +452,12 @@ loop2: · 89 unmodified lines | ||
| 452 | 452 | |
| 453 | 453 | done_hash: |
| 454 | 454 | |
| 455 | − mov %r12, %rsp | |
| 456 | − | |
| 457 | − popq %r12 | |
| 455 | + mov %rbp, %rsp | |
| 456 | + popq %rbp | |
| 458 | 457 | popq %r15 |
| 459 | 458 | popq %r14 |
| 460 | 459 | popq %r13 |
| 461 | − popq %rbp | |
| 460 | + popq %r12 | |
| 462 | 461 | popq %rbx |
| 463 | 462 | ret |
| 464 | 463 | ENDPROC(sha256_transform_avx) |
| @@ -98,8 +98,6 @@ d = %r8d · 97 unmodified lines | ||
| 98 | 98 | e = %edx # clobbers NUM_BLKS |
| 99 | 99 | y3 = %esi # clobbers INP |
| 100 | 100 | |
| 101 | − | |
| 102 | −TBL = %rbp | |
| 103 | 101 | SRND = CTX # SRND is same register as CTX |
| 104 | 102 | |
| 105 | 103 | a = %eax |
| @@ -531,7 +529,6 @@ STACK_SIZE = _RSP + _RSP_SIZE · 425 unmodified lines | ||
| 531 | 529 | ENTRY(sha256_transform_rorx) |
| 532 | 530 | .align 32 |
| 533 | 531 | pushq %rbx |
| 534 | − pushq %rbp | |
| 535 | 532 | pushq %r12 |
| 536 | 533 | pushq %r13 |
| 537 | 534 | pushq %r14 |
| @@ -568,8 +565,6 @@ ENTRY(sha256_transform_rorx) · 30 unmodified lines | ||
| 568 | 565 | mov CTX, _CTX(%rsp) |
| 569 | 566 | |
| 570 | 567 | loop0: |
| 571 | − lea K256(%rip), TBL | |
| 572 | − | |
| 573 | 568 | ## Load first 16 dwords from two blocks |
| 574 | 569 | VMOVDQ 0*32(INP),XTMP0 |
| 575 | 570 | VMOVDQ 1*32(INP),XTMP1 |
| @@ -597,19 +592,19 @@ last_block_enter: · 21 unmodified lines | ||
| 597 | 592 | |
| 598 | 593 | .align 16 |
| 599 | 594 | loop1: |
| 600 | − vpaddd 0*32(TBL, SRND), X0, XFER | |
| 595 | + vpaddd K256+0*32(SRND), X0, XFER | |
| 601 | 596 | vmovdqa XFER, 0*32+_XFER(%rsp, SRND) |
| 602 | 597 | FOUR_ROUNDS_AND_SCHED _XFER + 0*32 |
| 603 | 598 | |
| 604 | − vpaddd 1*32(TBL, SRND), X0, XFER | |
| 599 | + vpaddd K256+1*32(SRND), X0, XFER | |
| 605 | 600 | vmovdqa XFER, 1*32+_XFER(%rsp, SRND) |
| 606 | 601 | FOUR_ROUNDS_AND_SCHED _XFER + 1*32 |
| 607 | 602 | |
| 608 | − vpaddd 2*32(TBL, SRND), X0, XFER | |
| 603 | + vpaddd K256+2*32(SRND), X0, XFER | |
| 609 | 604 | vmovdqa XFER, 2*32+_XFER(%rsp, SRND) |
| 610 | 605 | FOUR_ROUNDS_AND_SCHED _XFER + 2*32 |
| 611 | 606 | |
| 612 | − vpaddd 3*32(TBL, SRND), X0, XFER | |
| 607 | + vpaddd K256+3*32(SRND), X0, XFER | |
| 613 | 608 | vmovdqa XFER, 3*32+_XFER(%rsp, SRND) |
| 614 | 609 | FOUR_ROUNDS_AND_SCHED _XFER + 3*32 |
| 615 | 610 | |
| @@ -619,10 +614,11 @@ loop1: · 3 unmodified lines | ||
| 619 | 614 | |
| 620 | 615 | loop2: |
| 621 | 616 | ## Do last 16 rounds with no scheduling |
| 622 | − vpaddd 0*32(TBL, SRND), X0, XFER | |
| 617 | + vpaddd K256+0*32(SRND), X0, XFER | |
| 623 | 618 | vmovdqa XFER, 0*32+_XFER(%rsp, SRND) |
| 624 | 619 | DO_4ROUNDS _XFER + 0*32 |
| 625 | − vpaddd 1*32(TBL, SRND), X1, XFER | |
| 620 | + | |
| 621 | + vpaddd K256+1*32(SRND), X1, XFER | |
| 626 | 622 | vmovdqa XFER, 1*32+_XFER(%rsp, SRND) |
| 627 | 623 | DO_4ROUNDS _XFER + 1*32 |
| 628 | 624 | add $2*32, SRND |
| @@ -676,9 +672,6 @@ loop3: · 47 unmodified lines | ||
| 676 | 672 | ja done_hash |
| 677 | 673 | |
| 678 | 674 | do_last_block: |
| 679 | − #### do last block | |
| 680 | − lea K256(%rip), TBL | |
| 681 | − | |
| 682 | 675 | VMOVDQ 0*16(INP),XWORD0 |
| 683 | 676 | VMOVDQ 1*16(INP),XWORD1 |
| 684 | 677 | VMOVDQ 2*16(INP),XWORD2 |
| @@ -718,7 +711,6 @@ done_hash: · 33 unmodified lines | ||
| 718 | 711 | popq %r14 |
| 719 | 712 | popq %r13 |
| 720 | 713 | popq %r12 |
| 721 | − popq %rbp | |
| 722 | 714 | popq %rbx |
| 723 | 715 | ret |
| 724 | 716 | ENDPROC(sha256_transform_rorx) |
| @@ -95,7 +95,7 @@ SRND = %rsi # clobbers INP · 94 unmodified lines | ||
| 95 | 95 | c = %ecx |
| 96 | 96 | d = %r8d |
| 97 | 97 | e = %edx |
| 98 | −TBL = %rbp | |
| 98 | +TBL = %r12 | |
| 99 | 99 | a = %eax |
| 100 | 100 | b = %ebx |
| 101 | 101 | |
| @@ -356,13 +356,13 @@ a = TMP_ · 254 unmodified lines | ||
| 356 | 356 | ENTRY(sha256_transform_ssse3) |
| 357 | 357 | .align 32 |
| 358 | 358 | pushq %rbx |
| 359 | − pushq %rbp | |
| 359 | + pushq %r12 | |
| 360 | 360 | pushq %r13 |
| 361 | 361 | pushq %r14 |
| 362 | 362 | pushq %r15 |
| 363 | − pushq %r12 | |
| 363 | + pushq %rbp | |
| 364 | + mov %rsp, %rbp | |
| 364 | 365 | |
| 365 | − mov %rsp, %r12 | |
| 366 | 366 | subq $STACK_SIZE, %rsp |
| 367 | 367 | and $~15, %rsp |
| 368 | 368 | |
| @@ -462,13 +462,12 @@ loop2: · 93 unmodified lines | ||
| 462 | 462 | |
| 463 | 463 | done_hash: |
| 464 | 464 | |
| 465 | − mov %r12, %rsp | |
| 466 | − | |
| 467 | − popq %r12 | |
| 465 | + mov %rbp, %rsp | |
| 466 | + popq %rbp | |
| 468 | 467 | popq %r15 |
| 469 | 468 | popq %r14 |
| 470 | 469 | popq %r13 |
| 471 | − popq %rbp | |
| 470 | + popq %r12 | |
| 472 | 471 | popq %rbx |
| 473 | 472 | |
| 474 | 473 | ret |
| @@ -69,8 +69,9 @@ XFER = YTMP0 · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | BYTE_FLIP_MASK = %ymm9 |
| 71 | 71 | |
| 72 | −# 1st arg | |
| 73 | −CTX = %rdi | |
| 72 | +# 1st arg is %rdi, which is saved to the stack and accessed later via %r12 | |
| 73 | +CTX1 = %rdi | |
| 74 | +CTX2 = %r12 | |
| 74 | 75 | # 2nd arg |
| 75 | 76 | INP = %rsi |
| 76 | 77 | # 3rd arg |
| @@ -81,7 +82,7 @@ d = %r8 · 4 unmodified lines | ||
| 81 | 82 | e = %rdx |
| 82 | 83 | y3 = %rsi |
| 83 | 84 | |
| 84 | −TBL = %rbp | |
| 85 | +TBL = %rdi # clobbers CTX1 | |
| 85 | 86 | |
| 86 | 87 | a = %rax |
| 87 | 88 | b = %rbx |
| @@ -91,26 +92,26 @@ g = %r10 · 3 unmodified lines | ||
| 91 | 92 | h = %r11 |
| 92 | 93 | old_h = %r11 |
| 93 | 94 | |
| 94 | −T1 = %r12 | |
| 95 | +T1 = %r12 # clobbers CTX2 | |
| 95 | 96 | y0 = %r13 |
| 96 | 97 | y1 = %r14 |
| 97 | 98 | y2 = %r15 |
| 98 | 99 | |
| 99 | −y4 = %r12 | |
| 100 | − | |
| 101 | 100 | # Local variables (stack frame) |
| 102 | 101 | XFER_SIZE = 4*8 |
| 103 | 102 | SRND_SIZE = 1*8 |
| 104 | 103 | INP_SIZE = 1*8 |
| 105 | 104 | INPEND_SIZE = 1*8 |
| 105 | +CTX_SIZE = 1*8 | |
| 106 | 106 | RSPSAVE_SIZE = 1*8 |
| 107 | −GPRSAVE_SIZE = 6*8 | |
| 107 | +GPRSAVE_SIZE = 5*8 | |
| 108 | 108 | |
| 109 | 109 | frame_XFER = 0 |
| 110 | 110 | frame_SRND = frame_XFER + XFER_SIZE |
| 111 | 111 | frame_INP = frame_SRND + SRND_SIZE |
| 112 | 112 | frame_INPEND = frame_INP + INP_SIZE |
| 113 | −frame_RSPSAVE = frame_INPEND + INPEND_SIZE | |
| 113 | +frame_CTX = frame_INPEND + INPEND_SIZE | |
| 114 | +frame_RSPSAVE = frame_CTX + CTX_SIZE | |
| 114 | 115 | frame_GPRSAVE = frame_RSPSAVE + RSPSAVE_SIZE |
| 115 | 116 | frame_size = frame_GPRSAVE + GPRSAVE_SIZE |
| 116 | 117 | |
| @@ -576,12 +577,11 @@ ENTRY(sha512_transform_rorx) · 459 unmodified lines | ||
| 576 | 577 | mov %rax, frame_RSPSAVE(%rsp) |
| 577 | 578 | |
| 578 | 579 | # Save GPRs |
| 579 | − mov %rbp, frame_GPRSAVE(%rsp) | |
| 580 | − mov %rbx, 8*1+frame_GPRSAVE(%rsp) | |
| 581 | − mov %r12, 8*2+frame_GPRSAVE(%rsp) | |
| 582 | − mov %r13, 8*3+frame_GPRSAVE(%rsp) | |
| 583 | − mov %r14, 8*4+frame_GPRSAVE(%rsp) | |
| 584 | − mov %r15, 8*5+frame_GPRSAVE(%rsp) | |
| 580 | + mov %rbx, 8*0+frame_GPRSAVE(%rsp) | |
| 581 | + mov %r12, 8*1+frame_GPRSAVE(%rsp) | |
| 582 | + mov %r13, 8*2+frame_GPRSAVE(%rsp) | |
| 583 | + mov %r14, 8*3+frame_GPRSAVE(%rsp) | |
| 584 | + mov %r15, 8*4+frame_GPRSAVE(%rsp) | |
| 585 | 585 | |
| 586 | 586 | shl $7, NUM_BLKS # convert to bytes |
| 587 | 587 | jz done_hash |
| @@ -589,14 +589,17 @@ ENTRY(sha512_transform_rorx) · 1 unmodified line | ||
| 589 | 589 | mov NUM_BLKS, frame_INPEND(%rsp) |
| 590 | 590 | |
| 591 | 591 | ## load initial digest |
| 592 | − mov 8*0(CTX),a | |
| 593 | − mov 8*1(CTX),b | |
| 594 | − mov 8*2(CTX),c | |
| 595 | − mov 8*3(CTX),d | |
| 596 | − mov 8*4(CTX),e | |
| 597 | − mov 8*5(CTX),f | |
| 598 | − mov 8*6(CTX),g | |
| 599 | − mov 8*7(CTX),h | |
| 592 | + mov 8*0(CTX1), a | |
| 593 | + mov 8*1(CTX1), b | |
| 594 | + mov 8*2(CTX1), c | |
| 595 | + mov 8*3(CTX1), d | |
| 596 | + mov 8*4(CTX1), e | |
| 597 | + mov 8*5(CTX1), f | |
| 598 | + mov 8*6(CTX1), g | |
| 599 | + mov 8*7(CTX1), h | |
| 600 | + | |
| 601 | + # save %rdi (CTX) before it gets clobbered | |
| 602 | + mov %rdi, frame_CTX(%rsp) | |
| 600 | 603 | |
| 601 | 604 | vmovdqa PSHUFFLE_BYTE_FLIP_MASK(%rip), BYTE_FLIP_MASK |
| 602 | 605 | |
| @@ -652,14 +655,15 @@ loop2: · 49 unmodified lines | ||
| 652 | 655 | subq $1, frame_SRND(%rsp) |
| 653 | 656 | jne loop2 |
| 654 | 657 | |
| 655 | − addm 8*0(CTX),a | |
| 656 | − addm 8*1(CTX),b | |
| 657 | − addm 8*2(CTX),c | |
| 658 | − addm 8*3(CTX),d | |
| 659 | − addm 8*4(CTX),e | |
| 660 | − addm 8*5(CTX),f | |
| 661 | − addm 8*6(CTX),g | |
| 662 | − addm 8*7(CTX),h | |
| 658 | + mov frame_CTX(%rsp), CTX2 | |
| 659 | + addm 8*0(CTX2), a | |
| 660 | + addm 8*1(CTX2), b | |
| 661 | + addm 8*2(CTX2), c | |
| 662 | + addm 8*3(CTX2), d | |
| 663 | + addm 8*4(CTX2), e | |
| 664 | + addm 8*5(CTX2), f | |
| 665 | + addm 8*6(CTX2), g | |
| 666 | + addm 8*7(CTX2), h | |
| 663 | 667 | |
| 664 | 668 | mov frame_INP(%rsp), INP |
| 665 | 669 | add $128, INP |
| @@ -669,12 +673,11 @@ loop2: · 3 unmodified lines | ||
| 669 | 673 | done_hash: |
| 670 | 674 | |
| 671 | 675 | # Restore GPRs |
| 672 | − mov frame_GPRSAVE(%rsp) ,%rbp | |
| 673 | − mov 8*1+frame_GPRSAVE(%rsp) ,%rbx | |
| 674 | − mov 8*2+frame_GPRSAVE(%rsp) ,%r12 | |
| 675 | − mov 8*3+frame_GPRSAVE(%rsp) ,%r13 | |
| 676 | − mov 8*4+frame_GPRSAVE(%rsp) ,%r14 | |
| 677 | − mov 8*5+frame_GPRSAVE(%rsp) ,%r15 | |
| 676 | + mov 8*0+frame_GPRSAVE(%rsp), %rbx | |
| 677 | + mov 8*1+frame_GPRSAVE(%rsp), %r12 | |
| 678 | + mov 8*2+frame_GPRSAVE(%rsp), %r13 | |
| 679 | + mov 8*3+frame_GPRSAVE(%rsp), %r14 | |
| 680 | + mov 8*4+frame_GPRSAVE(%rsp), %r15 | |
| 678 | 681 | |
| 679 | 682 | # Restore Stack Pointer |
| 680 | 683 | mov frame_RSPSAVE(%rsp), %rsp |
| @@ -76,8 +76,8 @@ · 75 unmodified lines | ||
| 76 | 76 | #define RT %xmm14 |
| 77 | 77 | #define RR %xmm15 |
| 78 | 78 | |
| 79 | −#define RID1 %rbp | |
| 80 | −#define RID1d %ebp | |
| 79 | +#define RID1 %r13 | |
| 80 | +#define RID1d %r13d | |
| 81 | 81 | #define RID2 %rsi |
| 82 | 82 | #define RID2d %esi |
| 83 | 83 | |
| @@ -259,7 +259,7 @@ __twofish_enc_blk8: · 175 unmodified lines | ||
| 259 | 259 | |
| 260 | 260 | vmovdqu w(CTX), RK1; |
| 261 | 261 | |
| 262 | − pushq %rbp; | |
| 262 | + pushq %r13; | |
| 263 | 263 | pushq %rbx; |
| 264 | 264 | pushq %rcx; |
| 265 | 265 | |
| @@ -282,7 +282,7 @@ __twofish_enc_blk8: · 16 unmodified lines | ||
| 282 | 282 | |
| 283 | 283 | popq %rcx; |
| 284 | 284 | popq %rbx; |
| 285 | − popq %rbp; | |
| 285 | + popq %r13; | |
| 286 | 286 | |
| 287 | 287 | outunpack_blocks(RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2); |
| 288 | 288 | outunpack_blocks(RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2); |
| @@ -301,7 +301,7 @@ __twofish_dec_blk8: · 12 unmodified lines | ||
| 301 | 301 | |
| 302 | 302 | vmovdqu (w+4*4)(CTX), RK1; |
| 303 | 303 | |
| 304 | − pushq %rbp; | |
| 304 | + pushq %r13; | |
| 305 | 305 | pushq %rbx; |
| 306 | 306 | |
| 307 | 307 | inpack_blocks(RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2); |
| @@ -322,7 +322,7 @@ __twofish_dec_blk8: · 14 unmodified lines | ||
| 322 | 322 | vmovdqu (w)(CTX), RK1; |
| 323 | 323 | |
| 324 | 324 | popq %rbx; |
| 325 | − popq %rbp; | |
| 325 | + popq %r13; | |
| 326 | 326 | |
| 327 | 327 | outunpack_blocks(RA1, RB1, RC1, RD1, RK1, RX0, RY0, RK2); |
| 328 | 328 | outunpack_blocks(RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2); |
| @@ -4409,10 +4409,9 @@ static __init int fixup_ht_bug(void) · 4408 unmodified lines | ||
| 4409 | 4409 | return 0; |
| 4410 | 4410 | } |
| 4411 | 4411 | |
| 4412 | − if (lockup_detector_suspend() != 0) { | |
| 4413 | − pr_debug("failed to disable PMU erratum BJ122, BV98, HSD29 workaround\n"); | |
| 4414 | − return 0; | |
| 4415 | − } | |
| 4412 | + cpus_read_lock(); | |
| 4413 | + | |
| 4414 | + hardlockup_detector_perf_stop(); | |
| 4416 | 4415 | |
| 4417 | 4416 | x86_pmu.flags &= ~(PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED); |
| 4418 | 4417 | |
| @@ -4420,9 +4419,7 @@ static __init int fixup_ht_bug(void) · 1 unmodified line | ||
| 4420 | 4419 | x86_pmu.commit_scheduling = NULL; |
| 4421 | 4420 | x86_pmu.stop_scheduling = NULL; |
| 4422 | 4421 | |
| 4423 | − lockup_detector_resume(); | |
| 4424 | − | |
| 4425 | − cpus_read_lock(); | |
| 4422 | + hardlockup_detector_perf_restart(); | |
| 4426 | 4423 | |
| 4427 | 4424 | for_each_online_cpu(c) |
| 4428 | 4425 | free_excl_cntrs(c); |
| @@ -552,6 +552,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { · 551 unmodified lines | ||
| 552 | 552 | |
| 553 | 553 | X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_MOBILE, snb_cstates), |
| 554 | 554 | X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates), |
| 555 | + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_X, snb_cstates), | |
| 555 | 556 | |
| 556 | 557 | X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE, snb_cstates), |
| 557 | 558 | X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_DESKTOP, snb_cstates), |
| @@ -560,6 +561,9 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { · 2 unmodified lines | ||
| 560 | 561 | X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates), |
| 561 | 562 | |
| 562 | 563 | X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), |
| 564 | + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_DENVERTON, glm_cstates), | |
| 565 | + | |
| 566 | + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GEMINI_LAKE, glm_cstates), | |
| 563 | 567 | { }, |
| 564 | 568 | }; |
| 565 | 569 | MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match); |
| @@ -775,6 +775,9 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = { · 774 unmodified lines | ||
| 775 | 775 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_rapl_init), |
| 776 | 776 | |
| 777 | 777 | X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, hsw_rapl_init), |
| 778 | + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_DENVERTON, hsw_rapl_init), | |
| 779 | + | |
| 780 | + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GEMINI_LAKE, hsw_rapl_init), | |
| 778 | 781 | {}, |
| 779 | 782 | }; |
| 780 | 783 | |
| @@ -3462,7 +3462,7 @@ static struct intel_uncore_ops skx_uncore_iio_ops = { · 3461 unmodified lines | ||
| 3462 | 3462 | static struct intel_uncore_type skx_uncore_iio = { |
| 3463 | 3463 | .name = "iio", |
| 3464 | 3464 | .num_counters = 4, |
| 3465 | − .num_boxes = 5, | |
| 3465 | + .num_boxes = 6, | |
| 3466 | 3466 | .perf_ctr_bits = 48, |
| 3467 | 3467 | .event_ctl = SKX_IIO0_MSR_PMON_CTL0, |
| 3468 | 3468 | .perf_ctr = SKX_IIO0_MSR_PMON_CTR0, |
| @@ -3492,7 +3492,7 @@ static const struct attribute_group skx_uncore_format_group = { · 23 unmodified lines | ||
| 3492 | 3492 | static struct intel_uncore_type skx_uncore_irp = { |
| 3493 | 3493 | .name = "irp", |
| 3494 | 3494 | .num_counters = 2, |
| 3495 | − .num_boxes = 5, | |
| 3495 | + .num_boxes = 6, | |
| 3496 | 3496 | .perf_ctr_bits = 48, |
| 3497 | 3497 | .event_ctl = SKX_IRP0_MSR_PMON_CTL0, |
| 3498 | 3498 | .perf_ctr = SKX_IRP0_MSR_PMON_CTR0, |
| @@ -63,6 +63,14 @@ static bool test_intel(int idx) · 62 unmodified lines | ||
| 63 | 63 | case INTEL_FAM6_ATOM_SILVERMONT1: |
| 64 | 64 | case INTEL_FAM6_ATOM_SILVERMONT2: |
| 65 | 65 | case INTEL_FAM6_ATOM_AIRMONT: |
| 66 | + | |
| 67 | + case INTEL_FAM6_ATOM_GOLDMONT: | |
| 68 | + case INTEL_FAM6_ATOM_DENVERTON: | |
| 69 | + | |
| 70 | + case INTEL_FAM6_ATOM_GEMINI_LAKE: | |
| 71 | + | |
| 72 | + case INTEL_FAM6_XEON_PHI_KNL: | |
| 73 | + case INTEL_FAM6_XEON_PHI_KNM: | |
| 66 | 74 | if (idx == PERF_MSR_SMI) |
| 67 | 75 | return true; |
| 68 | 76 | break; |
| @@ -231,7 +231,7 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, · 230 unmodified lines | ||
| 231 | 231 | ksig->ka.sa.sa_restorer) |
| 232 | 232 | sp = (unsigned long) ksig->ka.sa.sa_restorer; |
| 233 | 233 | |
| 234 | − if (fpu->fpstate_active) { | |
| 234 | + if (fpu->initialized) { | |
| 235 | 235 | unsigned long fx_aligned, math_size; |
| 236 | 236 | |
| 237 | 237 | sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size); |
| @@ -218,10 +218,9 @@ static inline int alternatives_text_reserved(void *start, void *end) · 217 unmodified lines | ||
| 218 | 218 | #define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2, \ |
| 219 | 219 | output, input...) \ |
| 220 | 220 | { \ |
| 221 | − register void *__sp asm(_ASM_SP); \ | |
| 222 | 221 | asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\ |
| 223 | 222 | "call %P[new2]", feature2) \ |
| 224 | − : output, "+r" (__sp) \ | |
| 223 | + : output, ASM_CALL_CONSTRAINT \ | |
| 225 | 224 | : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ |
| 226 | 225 | [new2] "i" (newfunc2), ## input); \ |
| 227 | 226 | } |
| @@ -11,10 +11,12 @@ · 10 unmodified lines | ||
| 11 | 11 | # define __ASM_FORM_COMMA(x) " " #x "," |
| 12 | 12 | #endif |
| 13 | 13 | |
| 14 | −#ifdef CONFIG_X86_32 | |
| 14 | +#ifndef __x86_64__ | |
| 15 | +/* 32 bit */ | |
| 15 | 16 | # define __ASM_SEL(a,b) __ASM_FORM(a) |
| 16 | 17 | # define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(a) |
| 17 | 18 | #else |
| 19 | +/* 64 bit */ | |
| 18 | 20 | # define __ASM_SEL(a,b) __ASM_FORM(b) |
| 19 | 21 | # define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b) |
| 20 | 22 | #endif |
| @@ -132,4 +134,15 @@ · 111 unmodified lines | ||
| 132 | 134 | /* For C file, we already have NOKPROBE_SYMBOL macro */ |
| 133 | 135 | #endif |
| 134 | 136 | |
| 137 | +#ifndef __ASSEMBLY__ | |
| 138 | +/* | |
| 139 | + * This output constraint should be used for any inline asm which has a "call" | |
| 140 | + * instruction. Otherwise the asm may be inserted before the frame pointer | |
| 141 | + * gets set up by the containing function. If you forget to do this, objtool | |
| 142 | + * may print a "call without frame pointer save/setup" warning. | |
| 143 | + */ | |
| 144 | +register unsigned long current_stack_pointer asm(_ASM_SP); | |
| 145 | +#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) | |
| 146 | +#endif | |
| 147 | + | |
| 135 | 148 | #endif /* _ASM_X86_ASM_H */ |
| @@ -23,11 +23,9 @@ · 22 unmodified lines | ||
| 23 | 23 | /* |
| 24 | 24 | * High level FPU state handling functions: |
| 25 | 25 | */ |
| 26 | −extern void fpu__activate_curr(struct fpu *fpu); | |
| 27 | −extern void fpu__activate_fpstate_read(struct fpu *fpu); | |
| 28 | −extern void fpu__activate_fpstate_write(struct fpu *fpu); | |
| 29 | −extern void fpu__current_fpstate_write_begin(void); | |
| 30 | −extern void fpu__current_fpstate_write_end(void); | |
| 26 | +extern void fpu__initialize(struct fpu *fpu); | |
| 27 | +extern void fpu__prepare_read(struct fpu *fpu); | |
| 28 | +extern void fpu__prepare_write(struct fpu *fpu); | |
| 31 | 29 | extern void fpu__save(struct fpu *fpu); |
| 32 | 30 | extern void fpu__restore(struct fpu *fpu); |
| 33 | 31 | extern int fpu__restore_sig(void __user *buf, int ia32_frame); |
| @@ -120,20 +118,11 @@ extern void fpstate_sanitize_xstate(struct fpu *fpu); · 86 unmodified lines | ||
| 120 | 118 | err; \ |
| 121 | 119 | }) |
| 122 | 120 | |
| 123 | −#define check_insn(insn, output, input...) \ | |
| 124 | −({ \ | |
| 125 | − int err; \ | |
| 121 | +#define kernel_insn(insn, output, input...) \ | |
| 126 | 122 | asm volatile("1:" #insn "\n\t" \ |
| 127 | 123 | "2:\n" \ |
| 128 | − ".section .fixup,\"ax\"\n" \ | |
| 129 | − "3: movl $-1,%[err]\n" \ | |
| 130 | − " jmp 2b\n" \ | |
| 131 | − ".previous\n" \ | |
| 132 | − _ASM_EXTABLE(1b, 3b) \ | |
| 133 | − : [err] "=r" (err), output \ | |
| 134 | − : "0"(0), input); \ | |
| 135 | − err; \ | |
| 136 | −}) | |
| 124 | + _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_fprestore) \ | |
| 125 | + : output : input) | |
| 137 | 126 | |
| 138 | 127 | static inline int copy_fregs_to_user(struct fregs_state __user *fx) |
| 139 | 128 | { |
| @@ -153,20 +142,16 @@ static inline int copy_fxregs_to_user(struct fxregs_state __user *fx) · 13 unmodified lines | ||
| 153 | 142 | |
| 154 | 143 | static inline void copy_kernel_to_fxregs(struct fxregs_state *fx) |
| 155 | 144 | { |
| 156 | − int err; | |
| 157 | − | |
| 158 | 145 | if (IS_ENABLED(CONFIG_X86_32)) { |
| 159 | − err = check_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx)); | |
| 146 | + kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx)); | |
| 160 | 147 | } else { |
| 161 | 148 | if (IS_ENABLED(CONFIG_AS_FXSAVEQ)) { |
| 162 | − err = check_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx)); | |
| 149 | + kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx)); | |
| 163 | 150 | } else { |
| 164 | 151 | /* See comment in copy_fxregs_to_kernel() below. */ |
| 165 | − err = check_insn(rex64/fxrstor (%[fx]), "=m" (*fx), [fx] "R" (fx), "m" (*fx)); | |
| 152 | + kernel_insn(rex64/fxrstor (%[fx]), "=m" (*fx), [fx] "R" (fx), "m" (*fx)); | |
| 166 | 153 | } |
| 167 | 154 | } |
| 168 | − /* Copying from a kernel buffer to FPU registers should never fail: */ | |
| 169 | − WARN_ON_FPU(err); | |
| 170 | 155 | } |
| 171 | 156 | |
| 172 | 157 | static inline int copy_user_to_fxregs(struct fxregs_state __user *fx) |
| @@ -183,9 +168,7 @@ static inline int copy_user_to_fxregs(struct fxregs_state __user *fx) · 10 unmodified lines | ||
| 183 | 168 | |
| 184 | 169 | static inline void copy_kernel_to_fregs(struct fregs_state *fx) |
| 185 | 170 | { |
| 186 | − int err = check_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx)); | |
| 187 | − | |
| 188 | − WARN_ON_FPU(err); | |
| 171 | + kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx)); | |
| 189 | 172 | } |
| 190 | 173 | |
| 191 | 174 | static inline int copy_user_to_fregs(struct fregs_state __user *fx) |
| @@ -281,18 +264,13 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu) · 89 unmodified lines | ||
| 281 | 264 | * Use XRSTORS to restore context if it is enabled. XRSTORS supports compact |
| 282 | 265 | * XSAVE area format. |
| 283 | 266 | */ |
| 284 | −#define XSTATE_XRESTORE(st, lmask, hmask, err) \ | |
| 267 | +#define XSTATE_XRESTORE(st, lmask, hmask) \ | |
| 285 | 268 | asm volatile(ALTERNATIVE(XRSTOR, \ |
| 286 | 269 | XRSTORS, X86_FEATURE_XSAVES) \ |
| 287 | 270 | "\n" \ |
| 288 | − "xor %[err], %[err]\n" \ | |
| 289 | 271 | "3:\n" \ |
| 290 | − ".pushsection .fixup,\"ax\"\n" \ | |
| 291 | − "4: movl $-2, %[err]\n" \ | |
| 292 | − "jmp 3b\n" \ | |
| 293 | − ".popsection\n" \ | |
| 294 | − _ASM_EXTABLE(661b, 4b) \ | |
| 295 | − : [err] "=r" (err) \ | |
| 272 | + _ASM_EXTABLE_HANDLE(661b, 3b, ex_handler_fprestore)\ | |
| 273 | + : \ | |
| 296 | 274 | : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ |
| 297 | 275 | : "memory") |
| 298 | 276 | |
| @@ -336,7 +314,10 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate) · 37 unmodified lines | ||
| 336 | 314 | else |
| 337 | 315 | XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); |
| 338 | 316 | |
| 339 | − /* We should never fault when copying from a kernel buffer: */ | |
| 317 | + /* | |
| 318 | + * We should never fault when copying from a kernel buffer, and the FPU | |
| 319 | + * state we set at boot time should be valid. | |
| 320 | + */ | |
| 340 | 321 | WARN_ON_FPU(err); |
| 341 | 322 | } |
| 342 | 323 | |
| @@ -350,7 +331,7 @@ static inline void copy_xregs_to_kernel(struct xregs_state *xstate) · 7 unmodified lines | ||
| 350 | 331 | u32 hmask = mask >> 32; |
| 351 | 332 | int err; |
| 352 | 333 | |
| 353 | − WARN_ON(!alternatives_patched); | |
| 334 | + WARN_ON_FPU(!alternatives_patched); | |
| 354 | 335 | |
| 355 | 336 | XSTATE_XSAVE(xstate, lmask, hmask, err); |
| 356 | 337 | |
| @@ -365,12 +346,8 @@ static inline void copy_kernel_to_xregs(struct xregs_state *xstate, u64 mask) · 8 unmodified lines | ||
| 365 | 346 | { |
| 366 | 347 | u32 lmask = mask; |
| 367 | 348 | u32 hmask = mask >> 32; |
| 368 | − int err; | |
| 369 | − | |
| 370 | − XSTATE_XRESTORE(xstate, lmask, hmask, err); | |
| 371 | 349 | |
| 372 | − /* We should never fault when copying from a kernel buffer: */ | |
| 373 | − WARN_ON_FPU(err); | |
| 350 | + XSTATE_XRESTORE(xstate, lmask, hmask); | |
| 374 | 351 | } |
| 375 | 352 | |
| 376 | 353 | /* |
| @@ -526,37 +503,16 @@ static inline int fpregs_state_valid(struct fpu *fpu, unsigned int cpu) · 149 unmodified lines | ||
| 526 | 503 | */ |
| 527 | 504 | static inline void fpregs_deactivate(struct fpu *fpu) |
| 528 | 505 | { |
| 529 | − WARN_ON_FPU(!fpu->fpregs_active); | |
| 530 | − | |
| 531 | − fpu->fpregs_active = 0; | |
| 532 | 506 | this_cpu_write(fpu_fpregs_owner_ctx, NULL); |
| 533 | 507 | trace_x86_fpu_regs_deactivated(fpu); |
| 534 | 508 | } |
| 535 | 509 | |
| 536 | 510 | static inline void fpregs_activate(struct fpu *fpu) |
| 537 | 511 | { |
| 538 | − WARN_ON_FPU(fpu->fpregs_active); | |
| 539 | − | |
| 540 | − fpu->fpregs_active = 1; | |
| 541 | 512 | this_cpu_write(fpu_fpregs_owner_ctx, fpu); |
| 542 | 513 | trace_x86_fpu_regs_activated(fpu); |
| 543 | 514 | } |
| 544 | 515 | |
| 545 | −/* | |
| 546 | − * The question "does this thread have fpu access?" | |
| 547 | − * is slightly racy, since preemption could come in | |
| 548 | − * and revoke it immediately after the test. | |
| 549 | − * | |
| 550 | − * However, even in that very unlikely scenario, | |
| 551 | − * we can just assume we have FPU access - typically | |
| 552 | − * to save the FP state - we'll just take a #NM | |
| 553 | − * fault and get the FPU access back. | |
| 554 | − */ | |
| 555 | −static inline int fpregs_active(void) | |
| 556 | −{ | |
| 557 | − return current->thread.fpu.fpregs_active; | |
| 558 | −} | |
| 559 | − | |
| 560 | 516 | /* |
| 561 | 517 | * FPU state switching for scheduling. |
| 562 | 518 | * |
| @@ -571,14 +527,13 @@ static inline int fpregs_active(void) · 8 unmodified lines | ||
| 571 | 527 | static inline void |
| 572 | 528 | switch_fpu_prepare(struct fpu *old_fpu, int cpu) |
| 573 | 529 | { |
| 574 | − if (old_fpu->fpregs_active) { | |
| 530 | + if (old_fpu->initialized) { | |
| 575 | 531 | if (!copy_fpregs_to_fpstate(old_fpu)) |
| 576 | 532 | old_fpu->last_cpu = -1; |
| 577 | 533 | else |
| 578 | 534 | old_fpu->last_cpu = cpu; |
| 579 | 535 | |
| 580 | 536 | /* But leave fpu_fpregs_owner_ctx! */ |
| 581 | − old_fpu->fpregs_active = 0; | |
| 582 | 537 | trace_x86_fpu_regs_deactivated(old_fpu); |
| 583 | 538 | } else |
| 584 | 539 | old_fpu->last_cpu = -1; |
| @@ -595,7 +550,7 @@ switch_fpu_prepare(struct fpu *old_fpu, int cpu) · 10 unmodified lines | ||
| 595 | 550 | static inline void switch_fpu_finish(struct fpu *new_fpu, int cpu) |
| 596 | 551 | { |
| 597 | 552 | bool preload = static_cpu_has(X86_FEATURE_FPU) && |
| 598 | − new_fpu->fpstate_active; | |
| 553 | + new_fpu->initialized; | |
| 599 | 554 | |
| 600 | 555 | if (preload) { |
| 601 | 556 | if (!fpregs_state_valid(new_fpu, cpu)) |
| @@ -617,8 +572,7 @@ static inline void user_fpu_begin(void) · 15 unmodified lines | ||
| 617 | 572 | struct fpu *fpu = ¤t->thread.fpu; |
| 618 | 573 | |
| 619 | 574 | preempt_disable(); |
| 620 | − if (!fpregs_active()) | |
| 621 | − fpregs_activate(fpu); | |
| 575 | + fpregs_activate(fpu); | |
| 622 | 576 | preempt_enable(); |
| 623 | 577 | } |
| 624 | 578 | |
| @@ -68,6 +68,9 @@ struct fxregs_state { · 67 unmodified lines | ||
| 68 | 68 | /* Default value for fxregs_state.mxcsr: */ |
| 69 | 69 | #define MXCSR_DEFAULT 0x1f80 |
| 70 | 70 | |
| 71 | +/* Copy both mxcsr & mxcsr_flags with a single u64 memcpy: */ | |
| 72 | +#define MXCSR_AND_FLAGS_SIZE sizeof(u64) | |
| 73 | + | |
| 71 | 74 | /* |
| 72 | 75 | * Software based FPU emulation state. This is arbitrary really, |
| 73 | 76 | * it matches the x87 format to make it easier to understand: |
| @@ -290,36 +293,13 @@ struct fpu { · 216 unmodified lines | ||
| 290 | 293 | unsigned int last_cpu; |
| 291 | 294 | |
| 292 | 295 | /* |
| 293 | − * @fpstate_active: | |
| 296 | + * @initialized: | |
| 294 | 297 | * |
| 295 | − * This flag indicates whether this context is active: if the task | |
| 298 | + * This flag indicates whether this context is initialized: if the task | |
| 296 | 299 | * is not running then we can restore from this context, if the task |
| 297 | 300 | * is running then we should save into this context. |
| 298 | 301 | */ |
| 299 | − unsigned char fpstate_active; | |
| 300 | − | |
| 301 | − /* | |
| 302 | − * @fpregs_active: | |
| 303 | − * | |
| 304 | − * This flag determines whether a given context is actively | |
| 305 | − * loaded into the FPU's registers and that those registers | |
| 306 | − * represent the task's current FPU state. | |
| 307 | − * | |
| 308 | − * Note the interaction with fpstate_active: | |
| 309 | − * | |
| 310 | − * # task does not use the FPU: | |
| 311 | − * fpstate_active == 0 | |
| 312 | − * | |
| 313 | − * # task uses the FPU and regs are active: | |
| 314 | − * fpstate_active == 1 && fpregs_active == 1 | |
| 315 | − * | |
| 316 | − * # the regs are inactive but still match fpstate: | |
| 317 | − * fpstate_active == 1 && fpregs_active == 0 && fpregs_owner == fpu | |
| 318 | − * | |
| 319 | − * The third state is what we use for the lazy restore optimization | |
| 320 | − * on lazy-switching CPUs. | |
| 321 | − */ | |
| 322 | − unsigned char fpregs_active; | |
| 302 | + unsigned char initialized; | |
| 323 | 303 | |
| 324 | 304 | /* |
| 325 | 305 | * @state: |
| @@ -48,8 +48,12 @@ void fpu__xstate_clear_all_cpu_caps(void); · 47 unmodified lines | ||
| 48 | 48 | void *get_xsave_addr(struct xregs_state *xsave, int xstate); |
| 49 | 49 | const void *get_xsave_field_ptr(int xstate_field); |
| 50 | 50 | int using_compacted_format(void); |
| 51 | −int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, | |
| 52 | − void __user *ubuf, struct xregs_state *xsave); | |
| 53 | −int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, | |
| 54 | − struct xregs_state *xsave); | |
| 51 | +int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset, unsigned int size); | |
| 52 | +int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned int offset, unsigned int size); | |
| 53 | +int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf); | |
| 54 | +int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf); | |
| 55 | + | |
| 56 | +/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */ | |
| 57 | +extern int validate_xstate_header(const struct xstate_header *hdr); | |
| 58 | + | |
| 55 | 59 | #endif |
| @@ -88,7 +88,7 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, · 87 unmodified lines | ||
| 88 | 88 | bool kvm_para_available(void); |
| 89 | 89 | unsigned int kvm_arch_para_features(void); |
| 90 | 90 | void __init kvm_guest_init(void); |
| 91 | −void kvm_async_pf_task_wait(u32 token); | |
| 91 | +void kvm_async_pf_task_wait(u32 token, int interrupt_kernel); | |
| 92 | 92 | void kvm_async_pf_task_wake(u32 token); |
| 93 | 93 | u32 kvm_read_and_reset_pf_reason(void); |
| 94 | 94 | extern void kvm_disable_steal_time(void); |
| @@ -103,7 +103,7 @@ static inline void kvm_spinlock_init(void) · 8 unmodified lines | ||
| 103 | 103 | |
| 104 | 104 | #else /* CONFIG_KVM_GUEST */ |
| 105 | 105 | #define kvm_guest_init() do {} while (0) |
| 106 | −#define kvm_async_pf_task_wait(T) do {} while(0) | |
| 106 | +#define kvm_async_pf_task_wait(T, I) do {} while(0) | |
| 107 | 107 | #define kvm_async_pf_task_wake(T) do {} while(0) |
| 108 | 108 | |
| 109 | 109 | static inline bool kvm_para_available(void) |
| @@ -286,6 +286,32 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, · 285 unmodified lines | ||
| 286 | 286 | return __pkru_allows_pkey(vma_pkey(vma), write); |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | +/* | |
| 290 | + * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID | |
| 291 | + * bits. This serves two purposes. It prevents a nasty situation in | |
| 292 | + * which PCID-unaware code saves CR3, loads some other value (with PCID | |
| 293 | + * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if | |
| 294 | + * the saved ASID was nonzero. It also means that any bugs involving | |
| 295 | + * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger | |
| 296 | + * deterministically. | |
| 297 | + */ | |
| 298 | + | |
| 299 | +static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid) | |
| 300 | +{ | |
| 301 | + if (static_cpu_has(X86_FEATURE_PCID)) { | |
| 302 | + VM_WARN_ON_ONCE(asid > 4094); | |
| 303 | + return __sme_pa(mm->pgd) | (asid + 1); | |
| 304 | + } else { | |
| 305 | + VM_WARN_ON_ONCE(asid != 0); | |
| 306 | + return __sme_pa(mm->pgd); | |
| 307 | + } | |
| 308 | +} | |
| 309 | + | |
| 310 | +static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) | |
| 311 | +{ | |
| 312 | + VM_WARN_ON_ONCE(asid > 4094); | |
| 313 | + return __sme_pa(mm->pgd) | (asid + 1) | CR3_NOFLUSH; | |
| 314 | +} | |
| 289 | 315 | |
| 290 | 316 | /* |
| 291 | 317 | * This can be used from process context to figure out what the value of |
| @@ -296,10 +322,8 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, · 4 unmodified lines | ||
| 296 | 322 | */ |
| 297 | 323 | static inline unsigned long __get_current_cr3_fast(void) |
| 298 | 324 | { |
| 299 | − unsigned long cr3 = __pa(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd); | |
| 300 | − | |
| 301 | − if (static_cpu_has(X86_FEATURE_PCID)) | |
| 302 | − cr3 |= this_cpu_read(cpu_tlbstate.loaded_mm_asid); | |
| 325 | + unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm), | |
| 326 | + this_cpu_read(cpu_tlbstate.loaded_mm_asid)); | |
| 303 | 327 | |
| 304 | 328 | /* For now, be very restrictive about when this can be called. */ |
| 305 | 329 | VM_WARN_ON(in_nmi() || preemptible()); |
| @@ -179,7 +179,6 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) · 178 unmodified lines | ||
| 179 | 179 | u64 input_address = input ? virt_to_phys(input) : 0; |
| 180 | 180 | u64 output_address = output ? virt_to_phys(output) : 0; |
| 181 | 181 | u64 hv_status; |
| 182 | − register void *__sp asm(_ASM_SP); | |
| 183 | 182 | |
| 184 | 183 | #ifdef CONFIG_X86_64 |
| 185 | 184 | if (!hv_hypercall_pg) |
| @@ -187,7 +186,7 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) · 1 unmodified line | ||
| 187 | 186 | |
| 188 | 187 | __asm__ __volatile__("mov %4, %%r8\n" |
| 189 | 188 | "call *%5" |
| 190 | − : "=a" (hv_status), "+r" (__sp), | |
| 189 | + : "=a" (hv_status), ASM_CALL_CONSTRAINT, | |
| 191 | 190 | "+c" (control), "+d" (input_address) |
| 192 | 191 | : "r" (output_address), "m" (hv_hypercall_pg) |
| 193 | 192 | : "cc", "memory", "r8", "r9", "r10", "r11"); |
| @@ -202,7 +201,7 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) · 8 unmodified lines | ||
| 202 | 201 | |
| 203 | 202 | __asm__ __volatile__("call *%7" |
| 204 | 203 | : "=A" (hv_status), |
| 205 | − "+c" (input_address_lo), "+r" (__sp) | |
| 204 | + "+c" (input_address_lo), ASM_CALL_CONSTRAINT | |
| 206 | 205 | : "A" (control), |
| 207 | 206 | "b" (input_address_hi), |
| 208 | 207 | "D"(output_address_hi), "S"(output_address_lo), |
| @@ -224,12 +223,11 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) · 15 unmodified lines | ||
| 224 | 223 | static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) |
| 225 | 224 | { |
| 226 | 225 | u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT; |
| 227 | − register void *__sp asm(_ASM_SP); | |
| 228 | 226 | |
| 229 | 227 | #ifdef CONFIG_X86_64 |
| 230 | 228 | { |
| 231 | 229 | __asm__ __volatile__("call *%4" |
| 232 | − : "=a" (hv_status), "+r" (__sp), | |
| 230 | + : "=a" (hv_status), ASM_CALL_CONSTRAINT, | |
| 233 | 231 | "+c" (control), "+d" (input1) |
| 234 | 232 | : "m" (hv_hypercall_pg) |
| 235 | 233 | : "cc", "r8", "r9", "r10", "r11"); |
| @@ -242,7 +240,7 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) · 6 unmodified lines | ||
| 242 | 240 | __asm__ __volatile__ ("call *%5" |
| 243 | 241 | : "=A"(hv_status), |
| 244 | 242 | "+c"(input1_lo), |
| 245 | − "+r"(__sp) | |
| 243 | + ASM_CALL_CONSTRAINT | |
| 246 | 244 | : "A" (control), |
| 247 | 245 | "b" (input1_hi), |
| 248 | 246 | "m" (hv_hypercall_pg) |
| @@ -459,8 +459,8 @@ int paravirt_disable_iospace(void); · 458 unmodified lines | ||
| 459 | 459 | */ |
| 460 | 460 | #ifdef CONFIG_X86_32 |
| 461 | 461 | #define PVOP_VCALL_ARGS \ |
| 462 | − unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; \ | |
| 463 | − register void *__sp asm("esp") | |
| 462 | + unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; | |
| 463 | + | |
| 464 | 464 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS |
| 465 | 465 | |
| 466 | 466 | #define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) |
| @@ -480,8 +480,8 @@ int paravirt_disable_iospace(void); · 13 unmodified lines | ||
| 480 | 480 | /* [re]ax isn't an arg, but the return val */ |
| 481 | 481 | #define PVOP_VCALL_ARGS \ |
| 482 | 482 | unsigned long __edi = __edi, __esi = __esi, \ |
| 483 | − __edx = __edx, __ecx = __ecx, __eax = __eax; \ | |
| 484 | − register void *__sp asm("rsp") | |
| 483 | + __edx = __edx, __ecx = __ecx, __eax = __eax; | |
| 484 | + | |
| 485 | 485 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS |
| 486 | 486 | |
| 487 | 487 | #define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) |
| @@ -532,7 +532,7 @@ int paravirt_disable_iospace(void); · 44 unmodified lines | ||
| 532 | 532 | asm volatile(pre \ |
| 533 | 533 | paravirt_alt(PARAVIRT_CALL) \ |
| 534 | 534 | post \ |
| 535 | − : call_clbr, "+r" (__sp) \ | |
| 535 | + : call_clbr, ASM_CALL_CONSTRAINT \ | |
| 536 | 536 | : paravirt_type(op), \ |
| 537 | 537 | paravirt_clobber(clbr), \ |
| 538 | 538 | ##__VA_ARGS__ \ |
| @@ -542,7 +542,7 @@ int paravirt_disable_iospace(void); · 3 unmodified lines | ||
| 542 | 542 | asm volatile(pre \ |
| 543 | 543 | paravirt_alt(PARAVIRT_CALL) \ |
| 544 | 544 | post \ |
| 545 | − : call_clbr, "+r" (__sp) \ | |
| 545 | + : call_clbr, ASM_CALL_CONSTRAINT \ | |
| 546 | 546 | : paravirt_type(op), \ |
| 547 | 547 | paravirt_clobber(clbr), \ |
| 548 | 548 | ##__VA_ARGS__ \ |
| @@ -569,7 +569,7 @@ int paravirt_disable_iospace(void); · 20 unmodified lines | ||
| 569 | 569 | asm volatile(pre \ |
| 570 | 570 | paravirt_alt(PARAVIRT_CALL) \ |
| 571 | 571 | post \ |
| 572 | − : call_clbr, "+r" (__sp) \ | |
| 572 | + : call_clbr, ASM_CALL_CONSTRAINT \ | |
| 573 | 573 | : paravirt_type(op), \ |
| 574 | 574 | paravirt_clobber(clbr), \ |
| 575 | 575 | ##__VA_ARGS__ \ |
| @@ -100,19 +100,14 @@ static __always_inline bool should_resched(int preempt_offset) · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | #ifdef CONFIG_PREEMPT |
| 102 | 102 | extern asmlinkage void ___preempt_schedule(void); |
| 103 | −# define __preempt_schedule() \ | |
| 104 | −({ \ | |
| 105 | − register void *__sp asm(_ASM_SP); \ | |
| 106 | − asm volatile ("call ___preempt_schedule" : "+r"(__sp)); \ | |
| 107 | −}) | |
| 103 | +# define __preempt_schedule() \ | |
| 104 | + asm volatile ("call ___preempt_schedule" : ASM_CALL_CONSTRAINT) | |
| 108 | 105 | |
| 109 | 106 | extern asmlinkage void preempt_schedule(void); |
| 110 | 107 | extern asmlinkage void ___preempt_schedule_notrace(void); |
| 111 | −# define __preempt_schedule_notrace() \ | |
| 112 | −({ \ | |
| 113 | − register void *__sp asm(_ASM_SP); \ | |
| 114 | − asm volatile ("call ___preempt_schedule_notrace" : "+r"(__sp)); \ | |
| 115 | −}) | |
| 108 | +# define __preempt_schedule_notrace() \ | |
| 109 | + asm volatile ("call ___preempt_schedule_notrace" : ASM_CALL_CONSTRAINT) | |
| 110 | + | |
| 116 | 111 | extern asmlinkage void preempt_schedule_notrace(void); |
| 117 | 112 | #endif |
| 118 | 113 | |
| @@ -677,8 +677,6 @@ static inline void sync_core(void) · 676 unmodified lines | ||
| 677 | 677 | * Like all of Linux's memory ordering operations, this is a |
| 678 | 678 | * compiler barrier as well. |
| 679 | 679 | */ |
| 680 | − register void *__sp asm(_ASM_SP); | |
| 681 | − | |
| 682 | 680 | #ifdef CONFIG_X86_32 |
| 683 | 681 | asm volatile ( |
| 684 | 682 | "pushfl\n\t" |
| @@ -686,7 +684,7 @@ static inline void sync_core(void) · 1 unmodified line | ||
| 686 | 684 | "pushl $1f\n\t" |
| 687 | 685 | "iret\n\t" |
| 688 | 686 | "1:" |
| 689 | − : "+r" (__sp) : : "memory"); | |
| 687 | + : ASM_CALL_CONSTRAINT : : "memory"); | |
| 690 | 688 | #else |
| 691 | 689 | unsigned int tmp; |
| 692 | 690 | |
| @@ -703,7 +701,7 @@ static inline void sync_core(void) · 10 unmodified lines | ||
| 703 | 701 | "iretq\n\t" |
| 704 | 702 | UNWIND_HINT_RESTORE |
| 705 | 703 | "1:" |
| 706 | − : "=&r" (tmp), "+r" (__sp) : : "cc", "memory"); | |
| 704 | + : "=&r" (tmp), ASM_CALL_CONSTRAINT : : "cc", "memory"); | |
| 707 | 705 | #endif |
| 708 | 706 | } |
| 709 | 707 | |
| @@ -103,7 +103,6 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) · 102 unmodified lines | ||
| 103 | 103 | ({ \ |
| 104 | 104 | long tmp; \ |
| 105 | 105 | struct rw_semaphore* ret; \ |
| 106 | − register void *__sp asm(_ASM_SP); \ | |
| 107 | 106 | \ |
| 108 | 107 | asm volatile("# beginning down_write\n\t" \ |
| 109 | 108 | LOCK_PREFIX " xadd %1,(%4)\n\t" \ |
| @@ -114,7 +113,8 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) · 4 unmodified lines | ||
| 114 | 113 | " call " slow_path "\n" \ |
| 115 | 114 | "1:\n" \ |
| 116 | 115 | "# ending down_write" \ |
| 117 | − : "+m" (sem->count), "=d" (tmp), "=a" (ret), "+r" (__sp) \ | |
| 116 | + : "+m" (sem->count), "=d" (tmp), \ | |
| 117 | + "=a" (ret), ASM_CALL_CONSTRAINT \ | |
| 118 | 118 | : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \ |
| 119 | 119 | : "memory", "cc"); \ |
| 120 | 120 | ret; \ |
| @@ -158,17 +158,6 @@ struct thread_info { · 157 unmodified lines | ||
| 158 | 158 | */ |
| 159 | 159 | #ifndef __ASSEMBLY__ |
| 160 | 160 | |
| 161 | −static inline unsigned long current_stack_pointer(void) | |
| 162 | −{ | |
| 163 | − unsigned long sp; | |
| 164 | −#ifdef CONFIG_X86_64 | |
| 165 | − asm("mov %%rsp,%0" : "=g" (sp)); | |
| 166 | −#else | |
| 167 | − asm("mov %%esp,%0" : "=g" (sp)); | |
| 168 | −#endif | |
| 169 | − return sp; | |
| 170 | −} | |
| 171 | − | |
| 172 | 161 | /* |
| 173 | 162 | * Walks up the stack frames to make sure that the specified object is |
| 174 | 163 | * entirely contained by a single stack frame. |
| @@ -12,25 +12,22 @@ DECLARE_EVENT_CLASS(x86_fpu, · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | TP_STRUCT__entry( |
| 14 | 14 | __field(struct fpu *, fpu) |
| 15 | − __field(bool, fpregs_active) | |
| 16 | − __field(bool, fpstate_active) | |
| 15 | + __field(bool, initialized) | |
| 17 | 16 | __field(u64, xfeatures) |
| 18 | 17 | __field(u64, xcomp_bv) |
| 19 | 18 | ), |
| 20 | 19 | |
| 21 | 20 | TP_fast_assign( |
| 22 | 21 | __entry->fpu = fpu; |
| 23 | − __entry->fpregs_active = fpu->fpregs_active; | |
| 24 | − __entry->fpstate_active = fpu->fpstate_active; | |
| 22 | + __entry->initialized = fpu->initialized; | |
| 25 | 23 | if (boot_cpu_has(X86_FEATURE_OSXSAVE)) { |
| 26 | 24 | __entry->xfeatures = fpu->state.xsave.header.xfeatures; |
| 27 | 25 | __entry->xcomp_bv = fpu->state.xsave.header.xcomp_bv; |
| 28 | 26 | } |
| 29 | 27 | ), |
| 30 | − TP_printk("x86/fpu: %p fpregs_active: %d fpstate_active: %d xfeatures: %llx xcomp_bv: %llx", | |
| 28 | + TP_printk("x86/fpu: %p initialized: %d xfeatures: %llx xcomp_bv: %llx", | |
| 31 | 29 | __entry->fpu, |
| 32 | − __entry->fpregs_active, | |
| 33 | − __entry->fpstate_active, | |
| 30 | + __entry->initialized, | |
| 34 | 31 | __entry->xfeatures, |
| 35 | 32 | __entry->xcomp_bv |
| 36 | 33 | ) |
| @@ -166,11 +166,11 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) · 165 unmodified lines | ||
| 166 | 166 | ({ \ |
| 167 | 167 | int __ret_gu; \ |
| 168 | 168 | register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ |
| 169 | − register void *__sp asm(_ASM_SP); \ | |
| 170 | 169 | __chk_user_ptr(ptr); \ |
| 171 | 170 | might_fault(); \ |
| 172 | 171 | asm volatile("call __get_user_%P4" \ |
| 173 | − : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) \ | |
| 172 | + : "=a" (__ret_gu), "=r" (__val_gu), \ | |
| 173 | + ASM_CALL_CONSTRAINT \ | |
| 174 | 174 | : "0" (ptr), "i" (sizeof(*(ptr)))); \ |
| 175 | 175 | (x) = (__force __typeof__(*(ptr))) __val_gu; \ |
| 176 | 176 | __builtin_expect(__ret_gu, 0); \ |
| @@ -337,7 +337,7 @@ do { \ · 160 unmodified lines | ||
| 337 | 337 | _ASM_EXTABLE(1b, 4b) \ |
| 338 | 338 | _ASM_EXTABLE(2b, 4b) \ |
| 339 | 339 | : "=r" (retval), "=&A"(x) \ |
| 340 | − : "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1), \ | |
| 340 | + : "m" (__m(__ptr)), "m" __m(((u32 __user *)(__ptr)) + 1), \ | |
| 341 | 341 | "i" (errret), "0" (retval)); \ |
| 342 | 342 | }) |
| 343 | 343 | |
| @@ -113,10 +113,9 @@ extern struct { char _entry[32]; } hypercall_page[]; · 112 unmodified lines | ||
| 113 | 113 | register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ |
| 114 | 114 | register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ |
| 115 | 115 | register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ |
| 116 | − register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; \ | |
| 117 | − register void *__sp asm(_ASM_SP); | |
| 116 | + register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; | |
| 118 | 117 | |
| 119 | −#define __HYPERCALL_0PARAM "=r" (__res), "+r" (__sp) | |
| 118 | +#define __HYPERCALL_0PARAM "=r" (__res), ASM_CALL_CONSTRAINT | |
| 120 | 119 | #define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) |
| 121 | 120 | #define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) |
| 122 | 121 | #define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) |
| @@ -552,13 +551,13 @@ static inline void · 429 unmodified lines | ||
| 552 | 551 | MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, |
| 553 | 552 | struct desc_struct desc) |
| 554 | 553 | { |
| 555 | − u32 *p = (u32 *) &desc; | |
| 556 | − | |
| 557 | 554 | mcl->op = __HYPERVISOR_update_descriptor; |
| 558 | 555 | if (sizeof(maddr) == sizeof(long)) { |
| 559 | 556 | mcl->args[0] = maddr; |
| 560 | 557 | mcl->args[1] = *(unsigned long *)&desc; |
| 561 | 558 | } else { |
| 559 | + u32 *p = (u32 *)&desc; | |
| 560 | + | |
| 562 | 561 | mcl->args[0] = maddr; |
| 563 | 562 | mcl->args[1] = maddr >> 32; |
| 564 | 563 | mcl->args[2] = *p++; |
| @@ -763,6 +763,16 @@ static void init_amd_bd(struct cpuinfo_x86 *c) · 762 unmodified lines | ||
| 763 | 763 | } |
| 764 | 764 | } |
| 765 | 765 | |
| 766 | +static void init_amd_zn(struct cpuinfo_x86 *c) | |
| 767 | +{ | |
| 768 | + /* | |
| 769 | + * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects | |
| 770 | + * all up to and including B1. | |
| 771 | + */ | |
| 772 | + if (c->x86_model <= 1 && c->x86_mask <= 1) | |
| 773 | + set_cpu_cap(c, X86_FEATURE_CPB); | |
| 774 | +} | |
| 775 | + | |
| 766 | 776 | static void init_amd(struct cpuinfo_x86 *c) |
| 767 | 777 | { |
| 768 | 778 | early_init_amd(c); |
| @@ -791,6 +801,7 @@ static void init_amd(struct cpuinfo_x86 *c) · 22 unmodified lines | ||
| 791 | 801 | case 0x10: init_amd_gh(c); break; |
| 792 | 802 | case 0x12: init_amd_ln(c); break; |
| 793 | 803 | case 0x15: init_amd_bd(c); break; |
| 804 | + case 0x17: init_amd_zn(c); break; | |
| 794 | 805 | } |
| 795 | 806 | |
| 796 | 807 | /* Enable workaround for FXSAVE leak */ |
| @@ -21,14 +21,6 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | void __init check_bugs(void) |
| 23 | 23 | { |
| 24 | −#ifdef CONFIG_X86_32 | |
| 25 | − /* | |
| 26 | − * Regardless of whether PCID is enumerated, the SDM says | |
| 27 | − * that it can't be enabled in 32-bit mode. | |
| 28 | − */ | |
| 29 | − setup_clear_cpu_cap(X86_FEATURE_PCID); | |
| 30 | −#endif | |
| 31 | − | |
| 32 | 24 | identify_boot_cpu(); |
| 33 | 25 | |
| 34 | 26 | if (!IS_ENABLED(CONFIG_SMP)) { |
| @@ -904,6 +904,14 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) · 903 unmodified lines | ||
| 904 | 904 | |
| 905 | 905 | setup_force_cpu_cap(X86_FEATURE_ALWAYS); |
| 906 | 906 | fpu__init_system(c); |
| 907 | + | |
| 908 | +#ifdef CONFIG_X86_32 | |
| 909 | + /* | |
| 910 | + * Regardless of whether PCID is enumerated, the SDM says | |
| 911 | + * that it can't be enabled in 32-bit mode. | |
| 912 | + */ | |
| 913 | + setup_clear_cpu_cap(X86_FEATURE_PCID); | |
| 914 | +#endif | |
| 907 | 915 | } |
| 908 | 916 | |
| 909 | 917 | void __init early_cpu_init(void) |
| @@ -100,7 +100,7 @@ void __kernel_fpu_begin(void) · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | kernel_fpu_disable(); |
| 102 | 102 | |
| 103 | − if (fpu->fpregs_active) { | |
| 103 | + if (fpu->initialized) { | |
| 104 | 104 | /* |
| 105 | 105 | * Ignore return value -- we don't care if reg state |
| 106 | 106 | * is clobbered. |
| @@ -116,7 +116,7 @@ void __kernel_fpu_end(void) · 9 unmodified lines | ||
| 116 | 116 | { |
| 117 | 117 | struct fpu *fpu = ¤t->thread.fpu; |
| 118 | 118 | |
| 119 | − if (fpu->fpregs_active) | |
| 119 | + if (fpu->initialized) | |
| 120 | 120 | copy_kernel_to_fpregs(&fpu->state); |
| 121 | 121 | |
| 122 | 122 | kernel_fpu_enable(); |
| @@ -148,7 +148,7 @@ void fpu__save(struct fpu *fpu) · 25 unmodified lines | ||
| 148 | 148 | |
| 149 | 149 | preempt_disable(); |
| 150 | 150 | trace_x86_fpu_before_save(fpu); |
| 151 | − if (fpu->fpregs_active) { | |
| 151 | + if (fpu->initialized) { | |
| 152 | 152 | if (!copy_fpregs_to_fpstate(fpu)) { |
| 153 | 153 | copy_kernel_to_fpregs(&fpu->state); |
| 154 | 154 | } |
| @@ -189,10 +189,9 @@ EXPORT_SYMBOL_GPL(fpstate_init); · 34 unmodified lines | ||
| 189 | 189 | |
| 190 | 190 | int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) |
| 191 | 191 | { |
| 192 | − dst_fpu->fpregs_active = 0; | |
| 193 | 192 | dst_fpu->last_cpu = -1; |
| 194 | 193 | |
| 195 | − if (!src_fpu->fpstate_active || !static_cpu_has(X86_FEATURE_FPU)) | |
| 194 | + if (!src_fpu->initialized || !static_cpu_has(X86_FEATURE_FPU)) | |
| 196 | 195 | return 0; |
| 197 | 196 | |
| 198 | 197 | WARN_ON_FPU(src_fpu != ¤t->thread.fpu); |
| @@ -206,26 +205,14 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) · 7 unmodified lines | ||
| 206 | 205 | /* |
| 207 | 206 | * Save current FPU registers directly into the child |
| 208 | 207 | * FPU context, without any memory-to-memory copying. |
| 209 | − * In lazy mode, if the FPU context isn't loaded into | |
| 210 | − * fpregs, CR0.TS will be set and do_device_not_available | |
| 211 | − * will load the FPU context. | |
| 212 | 208 | * |
| 213 | − * We have to do all this with preemption disabled, | |
| 214 | − * mostly because of the FNSAVE case, because in that | |
| 215 | − * case we must not allow preemption in the window | |
| 216 | − * between the FNSAVE and us marking the context lazy. | |
| 217 | − * | |
| 218 | − * It shouldn't be an issue as even FNSAVE is plenty | |
| 219 | − * fast in terms of critical section length. | |
| 209 | + * ( The function 'fails' in the FNSAVE case, which destroys | |
| 210 | + * register contents so we have to copy them back. ) | |
| 220 | 211 | */ |
| 221 | − preempt_disable(); | |
| 222 | 212 | if (!copy_fpregs_to_fpstate(dst_fpu)) { |
| 223 | − memcpy(&src_fpu->state, &dst_fpu->state, | |
| 224 | − fpu_kernel_xstate_size); | |
| 225 | − | |
| 213 | + memcpy(&src_fpu->state, &dst_fpu->state, fpu_kernel_xstate_size); | |
| 226 | 214 | copy_kernel_to_fpregs(&src_fpu->state); |
| 227 | 215 | } |
| 228 | − preempt_enable(); | |
| 229 | 216 | |
| 230 | 217 | trace_x86_fpu_copy_src(src_fpu); |
| 231 | 218 | trace_x86_fpu_copy_dst(dst_fpu); |
| @@ -237,45 +224,48 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) · 5 unmodified lines | ||
| 237 | 224 | * Activate the current task's in-memory FPU context, |
| 238 | 225 | * if it has not been used before: |
| 239 | 226 | */ |
| 240 | −void fpu__activate_curr(struct fpu *fpu) | |
| 227 | +void fpu__initialize(struct fpu *fpu) | |
| 241 | 228 | { |
| 242 | 229 | WARN_ON_FPU(fpu != ¤t->thread.fpu); |
| 243 | 230 | |
| 244 | − if (!fpu->fpstate_active) { | |
| 231 | + if (!fpu->initialized) { | |
| 245 | 232 | fpstate_init(&fpu->state); |
| 246 | 233 | trace_x86_fpu_init_state(fpu); |
| 247 | 234 | |
| 248 | 235 | trace_x86_fpu_activate_state(fpu); |
| 249 | 236 | /* Safe to do for the current task: */ |
| 250 | − fpu->fpstate_active = 1; | |
| 237 | + fpu->initialized = 1; | |
| 251 | 238 | } |
| 252 | 239 | } |
| 253 | −EXPORT_SYMBOL_GPL(fpu__activate_curr); | |
| 240 | +EXPORT_SYMBOL_GPL(fpu__initialize); | |
| 254 | 241 | |
| 255 | 242 | /* |
| 256 | 243 | * This function must be called before we read a task's fpstate. |
| 257 | 244 | * |
| 258 | − * If the task has not used the FPU before then initialize its | |
| 259 | − * fpstate. | |
| 245 | + * There's two cases where this gets called: | |
| 246 | + * | |
| 247 | + * - for the current task (when coredumping), in which case we have | |
| 248 | + * to save the latest FPU registers into the fpstate, | |
| 249 | + * | |
| 250 | + * - or it's called for stopped tasks (ptrace), in which case the | |
| 251 | + * registers were already saved by the context-switch code when | |
| 252 | + * the task scheduled out - we only have to initialize the registers | |
| 253 | + * if they've never been initialized. | |
| 260 | 254 | * |
| 261 | 255 | * If the task has used the FPU before then save it. |
| 262 | 256 | */ |
| 263 | −void fpu__activate_fpstate_read(struct fpu *fpu) | |
| 257 | +void fpu__prepare_read(struct fpu *fpu) | |
| 264 | 258 | { |
| 265 | − /* | |
| 266 | − * If fpregs are active (in the current CPU), then | |
| 267 | − * copy them to the fpstate: | |
| 268 | − */ | |
| 269 | − if (fpu->fpregs_active) { | |
| 259 | + if (fpu == ¤t->thread.fpu) { | |
| 270 | 260 | fpu__save(fpu); |
| 271 | 261 | } else { |
| 272 | − if (!fpu->fpstate_active) { | |
| 262 | + if (!fpu->initialized) { | |
| 273 | 263 | fpstate_init(&fpu->state); |
| 274 | 264 | trace_x86_fpu_init_state(fpu); |
| 275 | 265 | |
| 276 | 266 | trace_x86_fpu_activate_state(fpu); |
| 277 | 267 | /* Safe to do for current and for stopped child tasks: */ |
| 278 | − fpu->fpstate_active = 1; | |
| 268 | + fpu->initialized = 1; | |
| 279 | 269 | } |
| 280 | 270 | } |
| 281 | 271 | } |
| @@ -283,17 +273,17 @@ void fpu__activate_fpstate_read(struct fpu *fpu) · 1 unmodified line | ||
| 283 | 273 | /* |
| 284 | 274 | * This function must be called before we write a task's fpstate. |
| 285 | 275 | * |
| 286 | − * If the task has used the FPU before then unlazy it. | |
| 276 | + * If the task has used the FPU before then invalidate any cached FPU registers. | |
| 287 | 277 | * If the task has not used the FPU before then initialize its fpstate. |
| 288 | 278 | * |
| 289 | 279 | * After this function call, after registers in the fpstate are |
| 290 | 280 | * modified and the child task has woken up, the child task will |
| 291 | 281 | * restore the modified FPU state from the modified context. If we |
| 292 | − * didn't clear its lazy status here then the lazy in-registers | |
| 282 | + * didn't clear its cached status here then the cached in-registers | |
| 293 | 283 | * state pending on its former CPU could be restored, corrupting |
| 294 | 284 | * the modifications. |
| 295 | 285 | */ |
| 296 | −void fpu__activate_fpstate_write(struct fpu *fpu) | |
| 286 | +void fpu__prepare_write(struct fpu *fpu) | |
| 297 | 287 | { |
| 298 | 288 | /* |
| 299 | 289 | * Only stopped child tasks can be used to modify the FPU |
| @@ -301,8 +291,8 @@ void fpu__activate_fpstate_write(struct fpu *fpu) · 1 unmodified line | ||
| 301 | 291 | */ |
| 302 | 292 | WARN_ON_FPU(fpu == ¤t->thread.fpu); |
| 303 | 293 | |
| 304 | − if (fpu->fpstate_active) { | |
| 305 | − /* Invalidate any lazy state: */ | |
| 294 | + if (fpu->initialized) { | |
| 295 | + /* Invalidate any cached state: */ | |
| 306 | 296 | __fpu_invalidate_fpregs_state(fpu); |
| 307 | 297 | } else { |
| 308 | 298 | fpstate_init(&fpu->state); |
| @@ -310,73 +300,10 @@ void fpu__activate_fpstate_write(struct fpu *fpu) · 1 unmodified line | ||
| 310 | 300 | |
| 311 | 301 | trace_x86_fpu_activate_state(fpu); |
| 312 | 302 | /* Safe to do for stopped child tasks: */ |
| 313 | − fpu->fpstate_active = 1; | |
| 303 | + fpu->initialized = 1; | |
| 314 | 304 | } |
| 315 | 305 | } |
| 316 | 306 | |
| 317 | −/* | |
| 318 | − * This function must be called before we write the current | |
| 319 | − * task's fpstate. | |
| 320 | − * | |
| 321 | − * This call gets the current FPU register state and moves | |
| 322 | − * it in to the 'fpstate'. Preemption is disabled so that | |
| 323 | − * no writes to the 'fpstate' can occur from context | |
| 324 | − * swiches. | |
| 325 | − * | |
| 326 | − * Must be followed by a fpu__current_fpstate_write_end(). | |
| 327 | − */ | |
| 328 | −void fpu__current_fpstate_write_begin(void) | |
| 329 | −{ | |
| 330 | − struct fpu *fpu = ¤t->thread.fpu; | |
| 331 | − | |
| 332 | − /* | |
| 333 | − * Ensure that the context-switching code does not write | |
| 334 | − * over the fpstate while we are doing our update. | |
| 335 | − */ | |
| 336 | − preempt_disable(); | |
| 337 | − | |
| 338 | − /* | |
| 339 | − * Move the fpregs in to the fpu's 'fpstate'. | |
| 340 | − */ | |
| 341 | − fpu__activate_fpstate_read(fpu); | |
| 342 | − | |
| 343 | − /* | |
| 344 | − * The caller is about to write to 'fpu'. Ensure that no | |
| 345 | − * CPU thinks that its fpregs match the fpstate. This | |
| 346 | − * ensures we will not be lazy and skip a XRSTOR in the | |
| 347 | − * future. | |
| 348 | − */ | |
| 349 | − __fpu_invalidate_fpregs_state(fpu); | |
| 350 | −} | |
| 351 | − | |
| 352 | −/* | |
| 353 | − * This function must be paired with fpu__current_fpstate_write_begin() | |
| 354 | − * | |
| 355 | − * This will ensure that the modified fpstate gets placed back in | |
| 356 | − * the fpregs if necessary. | |
| 357 | − * | |
| 358 | − * Note: This function may be called whether or not an _actual_ | |
| 359 | − * write to the fpstate occurred. | |
| 360 | − */ | |
| 361 | −void fpu__current_fpstate_write_end(void) | |
| 362 | −{ | |
| 363 | − struct fpu *fpu = ¤t->thread.fpu; | |
| 364 | − | |
| 365 | − /* | |
| 366 | − * 'fpu' now has an updated copy of the state, but the | |
| 367 | − * registers may still be out of date. Update them with | |
| 368 | − * an XRSTOR if they are active. | |
| 369 | − */ | |
| 370 | − if (fpregs_active()) | |
| 371 | − copy_kernel_to_fpregs(&fpu->state); | |
| 372 | − | |
| 373 | − /* | |
| 374 | − * Our update is done and the fpregs/fpstate are in sync | |
| 375 | − * if necessary. Context switches can happen again. | |
| 376 | − */ | |
| 377 | − preempt_enable(); | |
| 378 | −} | |
| 379 | − | |
| 380 | 307 | /* |
| 381 | 308 | * 'fpu__restore()' is called to copy FPU registers from |
| 382 | 309 | * the FPU fpstate to the live hw registers and to activate |
| @@ -389,7 +316,7 @@ void fpu__current_fpstate_write_end(void) · 6 unmodified lines | ||
| 389 | 316 | */ |
| 390 | 317 | void fpu__restore(struct fpu *fpu) |
| 391 | 318 | { |
| 392 | − fpu__activate_curr(fpu); | |
| 319 | + fpu__initialize(fpu); | |
| 393 | 320 | |
| 394 | 321 | /* Avoid __kernel_fpu_begin() right after fpregs_activate() */ |
| 395 | 322 | kernel_fpu_disable(); |
| @@ -414,15 +341,17 @@ void fpu__drop(struct fpu *fpu) · 18 unmodified lines | ||
| 414 | 341 | { |
| 415 | 342 | preempt_disable(); |
| 416 | 343 | |
| 417 | − if (fpu->fpregs_active) { | |
| 418 | − /* Ignore delayed exceptions from user space */ | |
| 419 | − asm volatile("1: fwait\n" | |
| 420 | − "2:\n" | |
| 421 | − _ASM_EXTABLE(1b, 2b)); | |
| 422 | − fpregs_deactivate(fpu); | |
| 344 | + if (fpu == ¤t->thread.fpu) { | |
| 345 | + if (fpu->initialized) { | |
| 346 | + /* Ignore delayed exceptions from user space */ | |
| 347 | + asm volatile("1: fwait\n" | |
| 348 | + "2:\n" | |
| 349 | + _ASM_EXTABLE(1b, 2b)); | |
| 350 | + fpregs_deactivate(fpu); | |
| 351 | + } | |
| 423 | 352 | } |
| 424 | 353 | |
| 425 | − fpu->fpstate_active = 0; | |
| 354 | + fpu->initialized = 0; | |
| 426 | 355 | |
| 427 | 356 | trace_x86_fpu_dropped(fpu); |
| 428 | 357 | |
| @@ -462,9 +391,11 @@ void fpu__clear(struct fpu *fpu) · 33 unmodified lines | ||
| 462 | 391 | * Make sure fpstate is cleared and initialized. |
| 463 | 392 | */ |
| 464 | 393 | if (static_cpu_has(X86_FEATURE_FPU)) { |
| 465 | − fpu__activate_curr(fpu); | |
| 394 | + preempt_disable(); | |
| 395 | + fpu__initialize(fpu); | |
| 466 | 396 | user_fpu_begin(); |
| 467 | 397 | copy_init_fpstate_to_fpregs(); |
| 398 | + preempt_enable(); | |
| 468 | 399 | } |
| 469 | 400 | } |
| 470 | 401 | |
| @@ -240,7 +240,7 @@ static void __init fpu__init_system_ctx_switch(void) · 239 unmodified lines | ||
| 240 | 240 | WARN_ON_FPU(!on_boot_cpu); |
| 241 | 241 | on_boot_cpu = 0; |
| 242 | 242 | |
| 243 | − WARN_ON_FPU(current->thread.fpu.fpstate_active); | |
| 243 | + WARN_ON_FPU(current->thread.fpu.initialized); | |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | 246 | /* |
| @@ -16,14 +16,14 @@ int regset_fpregs_active(struct task_struct *target, const struct user_regset *r · 15 unmodified lines | ||
| 16 | 16 | { |
| 17 | 17 | struct fpu *target_fpu = &target->thread.fpu; |
| 18 | 18 | |
| 19 | − return target_fpu->fpstate_active ? regset->n : 0; | |
| 19 | + return target_fpu->initialized ? regset->n : 0; | |
| 20 | 20 | } |
| 21 | 21 | |
| 22 | 22 | int regset_xregset_fpregs_active(struct task_struct *target, const struct user_regset *regset) |
| 23 | 23 | { |
| 24 | 24 | struct fpu *target_fpu = &target->thread.fpu; |
| 25 | 25 | |
| 26 | − if (boot_cpu_has(X86_FEATURE_FXSR) && target_fpu->fpstate_active) | |
| 26 | + if (boot_cpu_has(X86_FEATURE_FXSR) && target_fpu->initialized) | |
| 27 | 27 | return regset->n; |
| 28 | 28 | else |
| 29 | 29 | return 0; |
| @@ -38,7 +38,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, · 8 unmodified lines | ||
| 38 | 38 | if (!boot_cpu_has(X86_FEATURE_FXSR)) |
| 39 | 39 | return -ENODEV; |
| 40 | 40 | |
| 41 | − fpu__activate_fpstate_read(fpu); | |
| 41 | + fpu__prepare_read(fpu); | |
| 42 | 42 | fpstate_sanitize_xstate(fpu); |
| 43 | 43 | |
| 44 | 44 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
| @@ -55,7 +55,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, · 10 unmodified lines | ||
| 55 | 55 | if (!boot_cpu_has(X86_FEATURE_FXSR)) |
| 56 | 56 | return -ENODEV; |
| 57 | 57 | |
| 58 | − fpu__activate_fpstate_write(fpu); | |
| 58 | + fpu__prepare_write(fpu); | |
| 59 | 59 | fpstate_sanitize_xstate(fpu); |
| 60 | 60 | |
| 61 | 61 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
| @@ -89,10 +89,13 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset, · 27 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | xsave = &fpu->state.xsave; |
| 91 | 91 | |
| 92 | − fpu__activate_fpstate_read(fpu); | |
| 92 | + fpu__prepare_read(fpu); | |
| 93 | 93 | |
| 94 | 94 | if (using_compacted_format()) { |
| 95 | − ret = copyout_from_xsaves(pos, count, kbuf, ubuf, xsave); | |
| 95 | + if (kbuf) | |
| 96 | + ret = copy_xstate_to_kernel(kbuf, xsave, pos, count); | |
| 97 | + else | |
| 98 | + ret = copy_xstate_to_user(ubuf, xsave, pos, count); | |
| 96 | 99 | } else { |
| 97 | 100 | fpstate_sanitize_xstate(fpu); |
| 98 | 101 | /* |
| @@ -129,28 +132,29 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, · 30 unmodified lines | ||
| 129 | 132 | |
| 130 | 133 | xsave = &fpu->state.xsave; |
| 131 | 134 | |
| 132 | − fpu__activate_fpstate_write(fpu); | |
| 135 | + fpu__prepare_write(fpu); | |
| 133 | 136 | |
| 134 | − if (boot_cpu_has(X86_FEATURE_XSAVES)) | |
| 135 | − ret = copyin_to_xsaves(kbuf, ubuf, xsave); | |
| 136 | − else | |
| 137 | + if (using_compacted_format()) { | |
| 138 | + if (kbuf) | |
| 139 | + ret = copy_kernel_to_xstate(xsave, kbuf); | |
| 140 | + else | |
| 141 | + ret = copy_user_to_xstate(xsave, ubuf); | |
| 142 | + } else { | |
| 137 | 143 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xsave, 0, -1); |
| 138 | − | |
| 139 | − /* | |
| 140 | − * In case of failure, mark all states as init: | |
| 141 | − */ | |
| 142 | − if (ret) | |
| 143 | − fpstate_init(&fpu->state); | |
| 144 | + if (!ret) | |
| 145 | + ret = validate_xstate_header(&xsave->header); | |
| 146 | + } | |
| 144 | 147 | |
| 145 | 148 | /* |
| 146 | 149 | * mxcsr reserved bits must be masked to zero for security reasons. |
| 147 | 150 | */ |
| 148 | 151 | xsave->i387.mxcsr &= mxcsr_feature_mask; |
| 149 | − xsave->header.xfeatures &= xfeatures_mask; | |
| 152 | + | |
| 150 | 153 | /* |
| 151 | − * These bits must be zero. | |
| 154 | + * In case of failure, mark all states as init: | |
| 152 | 155 | */ |
| 153 | − memset(&xsave->header.reserved, 0, 48); | |
| 156 | + if (ret) | |
| 157 | + fpstate_init(&fpu->state); | |
| 154 | 158 | |
| 155 | 159 | return ret; |
| 156 | 160 | } |
| @@ -299,7 +303,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, · 142 unmodified lines | ||
| 299 | 303 | struct fpu *fpu = &target->thread.fpu; |
| 300 | 304 | struct user_i387_ia32_struct env; |
| 301 | 305 | |
| 302 | − fpu__activate_fpstate_read(fpu); | |
| 306 | + fpu__prepare_read(fpu); | |
| 303 | 307 | |
| 304 | 308 | if (!boot_cpu_has(X86_FEATURE_FPU)) |
| 305 | 309 | return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); |
| @@ -329,7 +333,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, · 23 unmodified lines | ||
| 329 | 333 | struct user_i387_ia32_struct env; |
| 330 | 334 | int ret; |
| 331 | 335 | |
| 332 | − fpu__activate_fpstate_write(fpu); | |
| 336 | + fpu__prepare_write(fpu); | |
| 333 | 337 | fpstate_sanitize_xstate(fpu); |
| 334 | 338 | |
| 335 | 339 | if (!boot_cpu_has(X86_FEATURE_FPU)) |
| @@ -369,7 +373,7 @@ int dump_fpu(struct pt_regs *regs, struct user_i387_struct *ufpu) · 33 unmodified lines | ||
| 369 | 373 | struct fpu *fpu = &tsk->thread.fpu; |
| 370 | 374 | int fpvalid; |
| 371 | 375 | |
| 372 | − fpvalid = fpu->fpstate_active; | |
| 376 | + fpvalid = fpu->initialized; | |
| 373 | 377 | if (fpvalid) |
| 374 | 378 | fpvalid = !fpregs_get(tsk, NULL, |
| 375 | 379 | 0, sizeof(struct user_i387_ia32_struct), |
| @@ -155,7 +155,8 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) · 154 unmodified lines | ||
| 155 | 155 | */ |
| 156 | 156 | int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) |
| 157 | 157 | { |
| 158 | − struct xregs_state *xsave = ¤t->thread.fpu.state.xsave; | |
| 158 | + struct fpu *fpu = ¤t->thread.fpu; | |
| 159 | + struct xregs_state *xsave = &fpu->state.xsave; | |
| 159 | 160 | struct task_struct *tsk = current; |
| 160 | 161 | int ia32_fxstate = (buf != buf_fx); |
| 161 | 162 | |
| @@ -170,13 +171,13 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) · 8 unmodified lines | ||
| 170 | 171 | sizeof(struct user_i387_ia32_struct), NULL, |
| 171 | 172 | (struct _fpstate_32 __user *) buf) ? -1 : 1; |
| 172 | 173 | |
| 173 | − if (fpregs_active() || using_compacted_format()) { | |
| 174 | + if (fpu->initialized || using_compacted_format()) { | |
| 174 | 175 | /* Save the live register state to the user directly. */ |
| 175 | 176 | if (copy_fpregs_to_sigframe(buf_fx)) |
| 176 | 177 | return -1; |
| 177 | 178 | /* Update the thread's fxstate to save the fsave header. */ |
| 178 | 179 | if (ia32_fxstate) |
| 179 | − copy_fxregs_to_kernel(&tsk->thread.fpu); | |
| 180 | + copy_fxregs_to_kernel(fpu); | |
| 180 | 181 | } else { |
| 181 | 182 | /* |
| 182 | 183 | * It is a *bug* if kernel uses compacted-format for xsave |
| @@ -189,7 +190,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) · 6 unmodified lines | ||
| 189 | 190 | return -1; |
| 190 | 191 | } |
| 191 | 192 | |
| 192 | − fpstate_sanitize_xstate(&tsk->thread.fpu); | |
| 193 | + fpstate_sanitize_xstate(fpu); | |
| 193 | 194 | if (__copy_to_user(buf_fx, xsave, fpu_user_xstate_size)) |
| 194 | 195 | return -1; |
| 195 | 196 | } |
| @@ -213,8 +214,11 @@ sanitize_restored_xstate(struct task_struct *tsk, · 17 unmodified lines | ||
| 213 | 214 | struct xstate_header *header = &xsave->header; |
| 214 | 215 | |
| 215 | 216 | if (use_xsave()) { |
| 216 | − /* These bits must be zero. */ | |
| 217 | − memset(header->reserved, 0, 48); | |
| 217 | + /* | |
| 218 | + * Note: we don't need to zero the reserved bits in the | |
| 219 | + * xstate_header here because we either didn't copy them at all, | |
| 220 | + * or we checked earlier that they aren't set. | |
| 221 | + */ | |
| 218 | 222 | |
| 219 | 223 | /* |
| 220 | 224 | * Init the state that is not present in the memory |
| @@ -223,7 +227,7 @@ sanitize_restored_xstate(struct task_struct *tsk, · 2 unmodified lines | ||
| 223 | 227 | if (fx_only) |
| 224 | 228 | header->xfeatures = XFEATURE_MASK_FPSSE; |
| 225 | 229 | else |
| 226 | − header->xfeatures &= (xfeatures_mask & xfeatures); | |
| 230 | + header->xfeatures &= xfeatures; | |
| 227 | 231 | } |
| 228 | 232 | |
| 229 | 233 | if (use_fxsr()) { |
| @@ -279,7 +283,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) · 49 unmodified lines | ||
| 279 | 283 | if (!access_ok(VERIFY_READ, buf, size)) |
| 280 | 284 | return -EACCES; |
| 281 | 285 | |
| 282 | − fpu__activate_curr(fpu); | |
| 286 | + fpu__initialize(fpu); | |
| 283 | 287 | |
| 284 | 288 | if (!static_cpu_has(X86_FEATURE_FPU)) |
| 285 | 289 | return fpregs_soft_set(current, NULL, |
| @@ -307,28 +311,29 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) · 21 unmodified lines | ||
| 307 | 311 | /* |
| 308 | 312 | * For 32-bit frames with fxstate, copy the user state to the |
| 309 | 313 | * thread's fpu state, reconstruct fxstate from the fsave |
| 310 | − * header. Sanitize the copied state etc. | |
| 314 | + * header. Validate and sanitize the copied state. | |
| 311 | 315 | */ |
| 312 | 316 | struct fpu *fpu = &tsk->thread.fpu; |
| 313 | 317 | struct user_i387_ia32_struct env; |
| 314 | 318 | int err = 0; |
| 315 | 319 | |
| 316 | 320 | /* |
| 317 | − * Drop the current fpu which clears fpu->fpstate_active. This ensures | |
| 321 | + * Drop the current fpu which clears fpu->initialized. This ensures | |
| 318 | 322 | * that any context-switch during the copy of the new state, |
| 319 | 323 | * avoids the intermediate state from getting restored/saved. |
| 320 | 324 | * Thus avoiding the new restored state from getting corrupted. |
| 321 | 325 | * We will be ready to restore/save the state only after |
| 322 | − * fpu->fpstate_active is again set. | |
| 326 | + * fpu->initialized is again set. | |
| 323 | 327 | */ |
| 324 | 328 | fpu__drop(fpu); |
| 325 | 329 | |
| 326 | 330 | if (using_compacted_format()) { |
| 327 | − err = copyin_to_xsaves(NULL, buf_fx, | |
| 328 | − &fpu->state.xsave); | |
| 331 | + err = copy_user_to_xstate(&fpu->state.xsave, buf_fx); | |
| 329 | 332 | } else { |
| 330 | − err = __copy_from_user(&fpu->state.xsave, | |
| 331 | − buf_fx, state_size); | |
| 333 | + err = __copy_from_user(&fpu->state.xsave, buf_fx, state_size); | |
| 334 | + | |
| 335 | + if (!err && state_size > offsetof(struct xregs_state, header)) | |
| 336 | + err = validate_xstate_header(&fpu->state.xsave.header); | |
| 332 | 337 | } |
| 333 | 338 | |
| 334 | 339 | if (err || __copy_from_user(&env, buf, sizeof(env))) { |
| @@ -339,7 +344,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) · 4 unmodified lines | ||
| 339 | 344 | sanitize_restored_xstate(tsk, &env, xfeatures, fx_only); |
| 340 | 345 | } |
| 341 | 346 | |
| 342 | − fpu->fpstate_active = 1; | |
| 347 | + fpu->initialized = 1; | |
| 343 | 348 | preempt_disable(); |
| 344 | 349 | fpu__restore(fpu); |
| 345 | 350 | preempt_enable(); |
| @@ -483,6 +483,30 @@ int using_compacted_format(void) · 482 unmodified lines | ||
| 483 | 483 | return boot_cpu_has(X86_FEATURE_XSAVES); |
| 484 | 484 | } |
| 485 | 485 | |
| 486 | +/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */ | |
| 487 | +int validate_xstate_header(const struct xstate_header *hdr) | |
| 488 | +{ | |
| 489 | + /* No unknown or supervisor features may be set */ | |
| 490 | + if (hdr->xfeatures & (~xfeatures_mask | XFEATURE_MASK_SUPERVISOR)) | |
| 491 | + return -EINVAL; | |
| 492 | + | |
| 493 | + /* Userspace must use the uncompacted format */ | |
| 494 | + if (hdr->xcomp_bv) | |
| 495 | + return -EINVAL; | |
| 496 | + | |
| 497 | + /* | |
| 498 | + * If 'reserved' is shrunken to add a new field, make sure to validate | |
| 499 | + * that new field here! | |
| 500 | + */ | |
| 501 | + BUILD_BUG_ON(sizeof(hdr->reserved) != 48); | |
| 502 | + | |
| 503 | + /* No reserved bits may be set */ | |
| 504 | + if (memchr_inv(hdr->reserved, 0, sizeof(hdr->reserved))) | |
| 505 | + return -EINVAL; | |
| 506 | + | |
| 507 | + return 0; | |
| 508 | +} | |
| 509 | + | |
| 486 | 510 | static void __xstate_dump_leaves(void) |
| 487 | 511 | { |
| 488 | 512 | int i; |
| @@ -867,7 +891,7 @@ const void *get_xsave_field_ptr(int xsave_state) · 378 unmodified lines | ||
| 867 | 891 | { |
| 868 | 892 | struct fpu *fpu = ¤t->thread.fpu; |
| 869 | 893 | |
| 870 | − if (!fpu->fpstate_active) | |
| 894 | + if (!fpu->initialized) | |
| 871 | 895 | return NULL; |
| 872 | 896 | /* |
| 873 | 897 | * fpu__save() takes the CPU's xstate registers |
| @@ -920,39 +944,130 @@ int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, · 46 unmodified lines | ||
| 920 | 944 | } |
| 921 | 945 | #endif /* ! CONFIG_ARCH_HAS_PKEYS */ |
| 922 | 946 | |
| 947 | +/* | |
| 948 | + * Weird legacy quirk: SSE and YMM states store information in the | |
| 949 | + * MXCSR and MXCSR_FLAGS fields of the FP area. That means if the FP | |
| 950 | + * area is marked as unused in the xfeatures header, we need to copy | |
| 951 | + * MXCSR and MXCSR_FLAGS if either SSE or YMM are in use. | |
| 952 | + */ | |
| 953 | +static inline bool xfeatures_mxcsr_quirk(u64 xfeatures) | |
| 954 | +{ | |
| 955 | + if (!(xfeatures & (XFEATURE_MASK_SSE|XFEATURE_MASK_YMM))) | |
| 956 | + return false; | |
| 957 | + | |
| 958 | + if (xfeatures & XFEATURE_MASK_FP) | |
| 959 | + return false; | |
| 960 | + | |
| 961 | + return true; | |
| 962 | +} | |
| 963 | + | |
| 923 | 964 | /* |
| 924 | 965 | * This is similar to user_regset_copyout(), but will not add offset to |
| 925 | 966 | * the source data pointer or increment pos, count, kbuf, and ubuf. |
| 926 | 967 | */ |
| 927 | −static inline int xstate_copyout(unsigned int pos, unsigned int count, | |
| 928 | − void *kbuf, void __user *ubuf, | |
| 929 | − const void *data, const int start_pos, | |
| 930 | − const int end_pos) | |
| 968 | +static inline void | |
| 969 | +__copy_xstate_to_kernel(void *kbuf, const void *data, | |
| 970 | + unsigned int offset, unsigned int size, unsigned int size_total) | |
| 931 | 971 | { |
| 932 | − if ((count == 0) || (pos < start_pos)) | |
| 933 | − return 0; | |
| 972 | + if (offset < size_total) { | |
| 973 | + unsigned int copy = min(size, size_total - offset); | |
| 934 | 974 | |
| 935 | − if (end_pos < 0 || pos < end_pos) { | |
| 936 | − unsigned int copy = (end_pos < 0 ? count : min(count, end_pos - pos)); | |
| 975 | + memcpy(kbuf + offset, data, copy); | |
| 976 | + } | |
| 977 | +} | |
| 937 | 978 | |
| 938 | − if (kbuf) { | |
| 939 | − memcpy(kbuf + pos, data, copy); | |
| 940 | − } else { | |
| 941 | − if (__copy_to_user(ubuf + pos, data, copy)) | |
| 942 | − return -EFAULT; | |
| 979 | +/* | |
| 980 | + * Convert from kernel XSAVES compacted format to standard format and copy | |
| 981 | + * to a kernel-space ptrace buffer. | |
| 982 | + * | |
| 983 | + * It supports partial copy but pos always starts from zero. This is called | |
| 984 | + * from xstateregs_get() and there we check the CPU has XSAVES. | |
| 985 | + */ | |
| 986 | +int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) | |
| 987 | +{ | |
| 988 | + unsigned int offset, size; | |
| 989 | + struct xstate_header header; | |
| 990 | + int i; | |
| 991 | + | |
| 992 | + /* | |
| 993 | + * Currently copy_regset_to_user() starts from pos 0: | |
| 994 | + */ | |
| 995 | + if (unlikely(offset_start != 0)) | |
| 996 | + return -EFAULT; | |
| 997 | + | |
| 998 | + /* | |
| 999 | + * The destination is a ptrace buffer; we put in only user xstates: | |
| 1000 | + */ | |
| 1001 | + memset(&header, 0, sizeof(header)); | |
| 1002 | + header.xfeatures = xsave->header.xfeatures; | |
| 1003 | + header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; | |
| 1004 | + | |
| 1005 | + /* | |
| 1006 | + * Copy xregs_state->header: | |
| 1007 | + */ | |
| 1008 | + offset = offsetof(struct xregs_state, header); | |
| 1009 | + size = sizeof(header); | |
| 1010 | + | |
| 1011 | + __copy_xstate_to_kernel(kbuf, &header, offset, size, size_total); | |
| 1012 | + | |
| 1013 | + for (i = 0; i < XFEATURE_MAX; i++) { | |
| 1014 | + /* | |
| 1015 | + * Copy only in-use xstates: | |
| 1016 | + */ | |
| 1017 | + if ((header.xfeatures >> i) & 1) { | |
| 1018 | + void *src = __raw_xsave_addr(xsave, 1 << i); | |
| 1019 | + | |
| 1020 | + offset = xstate_offsets[i]; | |
| 1021 | + size = xstate_sizes[i]; | |
| 1022 | + | |
| 1023 | + /* The next component has to fit fully into the output buffer: */ | |
| 1024 | + if (offset + size > size_total) | |
| 1025 | + break; | |
| 1026 | + | |
| 1027 | + __copy_xstate_to_kernel(kbuf, src, offset, size, size_total); | |
| 943 | 1028 | } |
| 1029 | + | |
| 1030 | + } | |
| 1031 | + | |
| 1032 | + if (xfeatures_mxcsr_quirk(header.xfeatures)) { | |
| 1033 | + offset = offsetof(struct fxregs_state, mxcsr); | |
| 1034 | + size = MXCSR_AND_FLAGS_SIZE; | |
| 1035 | + __copy_xstate_to_kernel(kbuf, &xsave->i387.mxcsr, offset, size, size_total); | |
| 1036 | + } | |
| 1037 | + | |
| 1038 | + /* | |
| 1039 | + * Fill xsave->i387.sw_reserved value for ptrace frame: | |
| 1040 | + */ | |
| 1041 | + offset = offsetof(struct fxregs_state, sw_reserved); | |
| 1042 | + size = sizeof(xstate_fx_sw_bytes); | |
| 1043 | + | |
| 1044 | + __copy_xstate_to_kernel(kbuf, xstate_fx_sw_bytes, offset, size, size_total); | |
| 1045 | + | |
| 1046 | + return 0; | |
| 1047 | +} | |
| 1048 | + | |
| 1049 | +static inline int | |
| 1050 | +__copy_xstate_to_user(void __user *ubuf, const void *data, unsigned int offset, unsigned int size, unsigned int size_total) | |
| 1051 | +{ | |
| 1052 | + if (!size) | |
| 1053 | + return 0; | |
| 1054 | + | |
| 1055 | + if (offset < size_total) { | |
| 1056 | + unsigned int copy = min(size, size_total - offset); | |
| 1057 | + | |
| 1058 | + if (__copy_to_user(ubuf + offset, data, copy)) | |
| 1059 | + return -EFAULT; | |
| 944 | 1060 | } |
| 945 | 1061 | return 0; |
| 946 | 1062 | } |
| 947 | 1063 | |
| 948 | 1064 | /* |
| 949 | 1065 | * Convert from kernel XSAVES compacted format to standard format and copy |
| 950 | − * to a ptrace buffer. It supports partial copy but pos always starts from | |
| 1066 | + * to a user-space buffer. It supports partial copy but pos always starts from | |
| 951 | 1067 | * zero. This is called from xstateregs_get() and there we check the CPU |
| 952 | 1068 | * has XSAVES. |
| 953 | 1069 | */ |
| 954 | −int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, | |
| 955 | − void __user *ubuf, struct xregs_state *xsave) | |
| 1070 | +int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) | |
| 956 | 1071 | { |
| 957 | 1072 | unsigned int offset, size; |
| 958 | 1073 | int ret, i; |
| @@ -961,7 +1076,7 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, · 2 unmodified lines | ||
| 961 | 1076 | /* |
| 962 | 1077 | * Currently copy_regset_to_user() starts from pos 0: |
| 963 | 1078 | */ |
| 964 | − if (unlikely(pos != 0)) | |
| 1079 | + if (unlikely(offset_start != 0)) | |
| 965 | 1080 | return -EFAULT; |
| 966 | 1081 | |
| 967 | 1082 | /* |
| @@ -977,8 +1092,7 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, · 9 unmodified lines | ||
| 977 | 1092 | offset = offsetof(struct xregs_state, header); |
| 978 | 1093 | size = sizeof(header); |
| 979 | 1094 | |
| 980 | − ret = xstate_copyout(offset, size, kbuf, ubuf, &header, 0, count); | |
| 981 | − | |
| 1095 | + ret = __copy_xstate_to_user(ubuf, &header, offset, size, size_total); | |
| 982 | 1096 | if (ret) |
| 983 | 1097 | return ret; |
| 984 | 1098 | |
| @@ -992,25 +1106,30 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, · 7 unmodified lines | ||
| 992 | 1106 | offset = xstate_offsets[i]; |
| 993 | 1107 | size = xstate_sizes[i]; |
| 994 | 1108 | |
| 995 | − ret = xstate_copyout(offset, size, kbuf, ubuf, src, 0, count); | |
| 1109 | + /* The next component has to fit fully into the output buffer: */ | |
| 1110 | + if (offset + size > size_total) | |
| 1111 | + break; | |
| 996 | 1112 | |
| 1113 | + ret = __copy_xstate_to_user(ubuf, src, offset, size, size_total); | |
| 997 | 1114 | if (ret) |
| 998 | 1115 | return ret; |
| 999 | − | |
| 1000 | − if (offset + size >= count) | |
| 1001 | − break; | |
| 1002 | 1116 | } |
| 1003 | 1117 | |
| 1004 | 1118 | } |
| 1005 | 1119 | |
| 1120 | + if (xfeatures_mxcsr_quirk(header.xfeatures)) { | |
| 1121 | + offset = offsetof(struct fxregs_state, mxcsr); | |
| 1122 | + size = MXCSR_AND_FLAGS_SIZE; | |
| 1123 | + __copy_xstate_to_user(ubuf, &xsave->i387.mxcsr, offset, size, size_total); | |
| 1124 | + } | |
| 1125 | + | |
| 1006 | 1126 | /* |
| 1007 | 1127 | * Fill xsave->i387.sw_reserved value for ptrace frame: |
| 1008 | 1128 | */ |
| 1009 | 1129 | offset = offsetof(struct fxregs_state, sw_reserved); |
| 1010 | 1130 | size = sizeof(xstate_fx_sw_bytes); |
| 1011 | 1131 | |
| 1012 | − ret = xstate_copyout(offset, size, kbuf, ubuf, xstate_fx_sw_bytes, 0, count); | |
| 1013 | − | |
| 1132 | + ret = __copy_xstate_to_user(ubuf, xstate_fx_sw_bytes, offset, size, size_total); | |
| 1014 | 1133 | if (ret) |
| 1015 | 1134 | return ret; |
| 1016 | 1135 | |
| @@ -1018,55 +1137,98 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, · 1 unmodified line | ||
| 1018 | 1137 | } |
| 1019 | 1138 | |
| 1020 | 1139 | /* |
| 1021 | − * Convert from a ptrace standard-format buffer to kernel XSAVES format | |
| 1022 | − * and copy to the target thread. This is called from xstateregs_set() and | |
| 1023 | − * there we check the CPU has XSAVES and a whole standard-sized buffer | |
| 1024 | − * exists. | |
| 1140 | + * Convert from a ptrace standard-format kernel buffer to kernel XSAVES format | |
| 1141 | + * and copy to the target thread. This is called from xstateregs_set(). | |
| 1025 | 1142 | */ |
| 1026 | −int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, | |
| 1027 | − struct xregs_state *xsave) | |
| 1143 | +int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf) | |
| 1028 | 1144 | { |
| 1029 | 1145 | unsigned int offset, size; |
| 1030 | 1146 | int i; |
| 1031 | − u64 xfeatures; | |
| 1032 | − u64 allowed_features; | |
| 1147 | + struct xstate_header hdr; | |
| 1033 | 1148 | |
| 1034 | 1149 | offset = offsetof(struct xregs_state, header); |
| 1035 | − size = sizeof(xfeatures); | |
| 1150 | + size = sizeof(hdr); | |
| 1036 | 1151 | |
| 1037 | − if (kbuf) { | |
| 1038 | − memcpy(&xfeatures, kbuf + offset, size); | |
| 1039 | − } else { | |
| 1040 | − if (__copy_from_user(&xfeatures, ubuf + offset, size)) | |
| 1041 | − return -EFAULT; | |
| 1152 | + memcpy(&hdr, kbuf + offset, size); | |
| 1153 | + | |
| 1154 | + if (validate_xstate_header(&hdr)) | |
| 1155 | + return -EINVAL; | |
| 1156 | + | |
| 1157 | + for (i = 0; i < XFEATURE_MAX; i++) { | |
| 1158 | + u64 mask = ((u64)1 << i); | |
| 1159 | + | |
| 1160 | + if (hdr.xfeatures & mask) { | |
| 1161 | + void *dst = __raw_xsave_addr(xsave, 1 << i); | |
| 1162 | + | |
| 1163 | + offset = xstate_offsets[i]; | |
| 1164 | + size = xstate_sizes[i]; | |
| 1165 | + | |
| 1166 | + memcpy(dst, kbuf + offset, size); | |
| 1167 | + } | |
| 1168 | + } | |
| 1169 | + | |
| 1170 | + if (xfeatures_mxcsr_quirk(hdr.xfeatures)) { | |
| 1171 | + offset = offsetof(struct fxregs_state, mxcsr); | |
| 1172 | + size = MXCSR_AND_FLAGS_SIZE; | |
| 1173 | + memcpy(&xsave->i387.mxcsr, kbuf + offset, size); | |
| 1042 | 1174 | } |
| 1043 | 1175 | |
| 1044 | 1176 | /* |
| 1045 | − * Reject if the user sets any disabled or supervisor features: | |
| 1177 | + * The state that came in from userspace was user-state only. | |
| 1178 | + * Mask all the user states out of 'xfeatures': | |
| 1179 | + */ | |
| 1180 | + xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR; | |
| 1181 | + | |
| 1182 | + /* | |
| 1183 | + * Add back in the features that came in from userspace: | |
| 1046 | 1184 | */ |
| 1047 | − allowed_features = xfeatures_mask & ~XFEATURE_MASK_SUPERVISOR; | |
| 1185 | + xsave->header.xfeatures |= hdr.xfeatures; | |
| 1048 | 1186 | |
| 1049 | − if (xfeatures & ~allowed_features) | |
| 1187 | + return 0; | |
| 1188 | +} | |
| 1189 | + | |
| 1190 | +/* | |
| 1191 | + * Convert from a ptrace or sigreturn standard-format user-space buffer to | |
| 1192 | + * kernel XSAVES format and copy to the target thread. This is called from | |
| 1193 | + * xstateregs_set(), as well as potentially from the sigreturn() and | |
| 1194 | + * rt_sigreturn() system calls. | |
| 1195 | + */ | |
| 1196 | +int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) | |
| 1197 | +{ | |
| 1198 | + unsigned int offset, size; | |
| 1199 | + int i; | |
| 1200 | + struct xstate_header hdr; | |
| 1201 | + | |
| 1202 | + offset = offsetof(struct xregs_state, header); | |
| 1203 | + size = sizeof(hdr); | |
| 1204 | + | |
| 1205 | + if (__copy_from_user(&hdr, ubuf + offset, size)) | |
| 1206 | + return -EFAULT; | |
| 1207 | + | |
| 1208 | + if (validate_xstate_header(&hdr)) | |
| 1050 | 1209 | return -EINVAL; |
| 1051 | 1210 | |
| 1052 | 1211 | for (i = 0; i < XFEATURE_MAX; i++) { |
| 1053 | 1212 | u64 mask = ((u64)1 << i); |
| 1054 | 1213 | |
| 1055 | − if (xfeatures & mask) { | |
| 1214 | + if (hdr.xfeatures & mask) { | |
| 1056 | 1215 | void *dst = __raw_xsave_addr(xsave, 1 << i); |
| 1057 | 1216 | |
| 1058 | 1217 | offset = xstate_offsets[i]; |
| 1059 | 1218 | size = xstate_sizes[i]; |
| 1060 | 1219 | |
| 1061 | − if (kbuf) { | |
| 1062 | − memcpy(dst, kbuf + offset, size); | |
| 1063 | − } else { | |
| 1064 | − if (__copy_from_user(dst, ubuf + offset, size)) | |
| 1065 | − return -EFAULT; | |
| 1066 | − } | |
| 1220 | + if (__copy_from_user(dst, ubuf + offset, size)) | |
| 1221 | + return -EFAULT; | |
| 1067 | 1222 | } |
| 1068 | 1223 | } |
| 1069 | 1224 | |
| 1225 | + if (xfeatures_mxcsr_quirk(hdr.xfeatures)) { | |
| 1226 | + offset = offsetof(struct fxregs_state, mxcsr); | |
| 1227 | + size = MXCSR_AND_FLAGS_SIZE; | |
| 1228 | + if (__copy_from_user(&xsave->i387.mxcsr, ubuf + offset, size)) | |
| 1229 | + return -EFAULT; | |
| 1230 | + } | |
| 1231 | + | |
| 1070 | 1232 | /* |
| 1071 | 1233 | * The state that came in from userspace was user-state only. |
| 1072 | 1234 | * Mask all the user states out of 'xfeatures': |
| @@ -1076,7 +1238,7 @@ int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, · 3 unmodified lines | ||
| 1076 | 1238 | /* |
| 1077 | 1239 | * Add back in the features that came in from userspace: |
| 1078 | 1240 | */ |
| 1079 | − xsave->header.xfeatures |= xfeatures; | |
| 1241 | + xsave->header.xfeatures |= hdr.xfeatures; | |
| 1080 | 1242 | |
| 1081 | 1243 | return 0; |
| 1082 | 1244 | } |
| @@ -64,7 +64,7 @@ static void call_on_stack(void *func, void *stack) · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | static inline void *current_stack(void) |
| 66 | 66 | { |
| 67 | − return (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1)); | |
| 67 | + return (void *)(current_stack_pointer & ~(THREAD_SIZE - 1)); | |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) |
| @@ -88,7 +88,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) · 17 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | /* Save the next esp at the bottom of the stack */ |
| 90 | 90 | prev_esp = (u32 *)irqstk; |
| 91 | − *prev_esp = current_stack_pointer(); | |
| 91 | + *prev_esp = current_stack_pointer; | |
| 92 | 92 | |
| 93 | 93 | if (unlikely(overflow)) |
| 94 | 94 | call_on_stack(print_stack_overflow, isp); |
| @@ -139,7 +139,7 @@ void do_softirq_own_stack(void) · 44 unmodified lines | ||
| 139 | 139 | |
| 140 | 140 | /* Push the previous esp onto the stack */ |
| 141 | 141 | prev_esp = (u32 *)irqstk; |
| 142 | − *prev_esp = current_stack_pointer(); | |
| 142 | + *prev_esp = current_stack_pointer; | |
| 143 | 143 | |
| 144 | 144 | call_on_stack(__do_softirq, isp); |
| 145 | 145 | } |
| @@ -299,7 +299,7 @@ static int __init create_setup_data_nodes(struct kobject *parent) · 298 unmodified lines | ||
| 299 | 299 | return 0; |
| 300 | 300 | |
| 301 | 301 | out_clean_nodes: |
| 302 | − for (j = i - 1; j > 0; j--) | |
| 302 | + for (j = i - 1; j >= 0; j--) | |
| 303 | 303 | cleanup_setup_data_node(*(kobjp + j)); |
| 304 | 304 | kfree(kobjp); |
| 305 | 305 | out_setup_data_kobj: |
| @@ -117,7 +117,11 @@ static struct kvm_task_sleep_node *_find_apf_task(struct kvm_task_sleep_head *b, · 116 unmodified lines | ||
| 117 | 117 | return NULL; |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | −void kvm_async_pf_task_wait(u32 token) | |
| 120 | +/* | |
| 121 | + * @interrupt_kernel: Is this called from a routine which interrupts the kernel | |
| 122 | + * (other than user space)? | |
| 123 | + */ | |
| 124 | +void kvm_async_pf_task_wait(u32 token, int interrupt_kernel) | |
| 121 | 125 | { |
| 122 | 126 | u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS); |
| 123 | 127 | struct kvm_task_sleep_head *b = &async_pf_sleepers[key]; |
| @@ -140,7 +144,10 @@ void kvm_async_pf_task_wait(u32 token) · 16 unmodified lines | ||
| 140 | 144 | |
| 141 | 145 | n.token = token; |
| 142 | 146 | n.cpu = smp_processor_id(); |
| 143 | − n.halted = is_idle_task(current) || preempt_count() > 1; | |
| 147 | + n.halted = is_idle_task(current) || | |
| 148 | + (IS_ENABLED(CONFIG_PREEMPT_COUNT) | |
| 149 | + ? preempt_count() > 1 || rcu_preempt_depth() | |
| 150 | + : interrupt_kernel); | |
| 144 | 151 | init_swait_queue_head(&n.wq); |
| 145 | 152 | hlist_add_head(&n.link, &b->list); |
| 146 | 153 | raw_spin_unlock(&b->lock); |
| @@ -268,7 +275,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) · 121 unmodified lines | ||
| 268 | 275 | case KVM_PV_REASON_PAGE_NOT_PRESENT: |
| 269 | 276 | /* page is swapped out by the host. */ |
| 270 | 277 | prev_state = exception_enter(); |
| 271 | − kvm_async_pf_task_wait((u32)read_cr2()); | |
| 278 | + kvm_async_pf_task_wait((u32)read_cr2(), !user_mode(regs)); | |
| 272 | 279 | exception_exit(prev_state); |
| 273 | 280 | break; |
| 274 | 281 | case KVM_PV_REASON_PAGE_READY: |
| @@ -263,7 +263,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, · 262 unmodified lines | ||
| 263 | 263 | sp = (unsigned long) ka->sa.sa_restorer; |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | − if (fpu->fpstate_active) { | |
| 266 | + if (fpu->initialized) { | |
| 267 | 267 | sp = fpu__alloc_mathframe(sp, IS_ENABLED(CONFIG_X86_32), |
| 268 | 268 | &buf_fx, &math_size); |
| 269 | 269 | *fpstate = (void __user *)sp; |
| @@ -279,7 +279,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, · 9 unmodified lines | ||
| 279 | 279 | return (void __user *)-1L; |
| 280 | 280 | |
| 281 | 281 | /* save i387 and extended state */ |
| 282 | − if (fpu->fpstate_active && | |
| 282 | + if (fpu->initialized && | |
| 283 | 283 | copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size) < 0) |
| 284 | 284 | return (void __user *)-1L; |
| 285 | 285 | |
| @@ -755,7 +755,7 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) · 469 unmodified lines | ||
| 755 | 755 | /* |
| 756 | 756 | * Ensure the signal handler starts with the new fpu state. |
| 757 | 757 | */ |
| 758 | − if (fpu->fpstate_active) | |
| 758 | + if (fpu->initialized) | |
| 759 | 759 | fpu__clear(fpu); |
| 760 | 760 | } |
| 761 | 761 | signal_setup_done(failed, ksig, stepping); |
| @@ -232,12 +232,6 @@ static void notrace start_secondary(void *unused) · 231 unmodified lines | ||
| 232 | 232 | */ |
| 233 | 233 | if (boot_cpu_has(X86_FEATURE_PCID)) |
| 234 | 234 | __write_cr4(__read_cr4() | X86_CR4_PCIDE); |
| 235 | − cpu_init(); | |
| 236 | − x86_cpuinit.early_percpu_clock_init(); | |
| 237 | − preempt_disable(); | |
| 238 | − smp_callin(); | |
| 239 | − | |
| 240 | − enable_start_cpu0 = 0; | |
| 241 | 235 | |
| 242 | 236 | #ifdef CONFIG_X86_32 |
| 243 | 237 | /* switch away from the initial page table */ |
| @@ -245,6 +239,13 @@ static void notrace start_secondary(void *unused) · 1 unmodified line | ||
| 245 | 239 | __flush_tlb_all(); |
| 246 | 240 | #endif |
| 247 | 241 | |
| 242 | + cpu_init(); | |
| 243 | + x86_cpuinit.early_percpu_clock_init(); | |
| 244 | + preempt_disable(); | |
| 245 | + smp_callin(); | |
| 246 | + | |
| 247 | + enable_start_cpu0 = 0; | |
| 248 | + | |
| 248 | 249 | /* otherwise gcc will move up smp_processor_id before the cpu_init */ |
| 249 | 250 | barrier(); |
| 250 | 251 | /* |
| @@ -142,7 +142,7 @@ void ist_begin_non_atomic(struct pt_regs *regs) · 141 unmodified lines | ||
| 142 | 142 | * from double_fault. |
| 143 | 143 | */ |
| 144 | 144 | BUG_ON((unsigned long)(current_top_of_stack() - |
| 145 | − current_stack_pointer()) >= THREAD_SIZE); | |
| 145 | + current_stack_pointer) >= THREAD_SIZE); | |
| 146 | 146 | |
| 147 | 147 | preempt_enable_no_resched(); |
| 148 | 148 | } |
| @@ -23,6 +23,7 @@ config KVM · 22 unmodified lines | ||
| 23 | 23 | depends on HIGH_RES_TIMERS |
| 24 | 24 | # for TASKSTATS/TASK_DELAY_ACCT: |
| 25 | 25 | depends on NET && MULTIUSER |
| 26 | + depends on X86_LOCAL_APIC | |
| 26 | 27 | select PREEMPT_NOTIFIERS |
| 27 | 28 | select MMU_NOTIFIER |
| 28 | 29 | select ANON_INODES |
| @@ -425,8 +425,10 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); · 424 unmodified lines | ||
| 425 | 425 | #op " %al \n\t" \ |
| 426 | 426 | FOP_RET |
| 427 | 427 | |
| 428 | −asm(".global kvm_fastop_exception \n" | |
| 429 | − "kvm_fastop_exception: xor %esi, %esi; ret"); | |
| 428 | +asm(".pushsection .fixup, \"ax\"\n" | |
| 429 | + ".global kvm_fastop_exception \n" | |
| 430 | + "kvm_fastop_exception: xor %esi, %esi; ret\n" | |
| 431 | + ".popsection"); | |
| 430 | 432 | |
| 431 | 433 | FOP_START(setcc) |
| 432 | 434 | FOP_SETCC(seto) |
| @@ -4102,10 +4104,12 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt) · 3669 unmodified lines | ||
| 4102 | 4104 | ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); |
| 4103 | 4105 | if (efer & EFER_LMA) { |
| 4104 | 4106 | u64 maxphyaddr; |
| 4105 | − u32 eax = 0x80000008; | |
| 4107 | + u32 eax, ebx, ecx, edx; | |
| 4106 | 4108 | |
| 4107 | − if (ctxt->ops->get_cpuid(ctxt, &eax, NULL, NULL, | |
| 4108 | − NULL, false)) | |
| 4109 | + eax = 0x80000008; | |
| 4110 | + ecx = 0; | |
| 4111 | + if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, | |
| 4112 | + &edx, false)) | |
| 4109 | 4113 | maxphyaddr = eax & 0xff; |
| 4110 | 4114 | else |
| 4111 | 4115 | maxphyaddr = 36; |
| @@ -5296,7 +5300,6 @@ static void fetch_possible_mmx_operand(struct x86_emulate_ctxt *ctxt, · 1184 unmodified lines | ||
| 5296 | 5300 | |
| 5297 | 5301 | static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)) |
| 5298 | 5302 | { |
| 5299 | − register void *__sp asm(_ASM_SP); | |
| 5300 | 5303 | ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF; |
| 5301 | 5304 | |
| 5302 | 5305 | if (!(ctxt->d & ByteOp)) |
| @@ -5304,7 +5307,7 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)) · 1 unmodified line | ||
| 5304 | 5307 | |
| 5305 | 5308 | asm("push %[flags]; popf; call *%[fastop]; pushf; pop %[flags]\n" |
| 5306 | 5309 | : "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags), |
| 5307 | − [fastop]"+S"(fop), "+r"(__sp) | |
| 5310 | + [fastop]"+S"(fop), ASM_CALL_CONSTRAINT | |
| 5308 | 5311 | : "c"(ctxt->src2.val)); |
| 5309 | 5312 | |
| 5310 | 5313 | ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK); |
| @@ -3837,7 +3837,7 @@ int kvm_handle_page_fault(struct kvm_vcpu *vcpu, u64 error_code, · 3836 unmodified lines | ||
| 3837 | 3837 | case KVM_PV_REASON_PAGE_NOT_PRESENT: |
| 3838 | 3838 | vcpu->arch.apf.host_apf_reason = 0; |
| 3839 | 3839 | local_irq_disable(); |
| 3840 | − kvm_async_pf_task_wait(fault_address); | |
| 3840 | + kvm_async_pf_task_wait(fault_address, 0); | |
| 3841 | 3841 | local_irq_enable(); |
| 3842 | 3842 | break; |
| 3843 | 3843 | case KVM_PV_REASON_PAGE_READY: |
| @@ -200,6 +200,8 @@ struct loaded_vmcs { · 199 unmodified lines | ||
| 200 | 200 | int cpu; |
| 201 | 201 | bool launched; |
| 202 | 202 | bool nmi_known_unmasked; |
| 203 | + unsigned long vmcs_host_cr3; /* May not match real cr3 */ | |
| 204 | + unsigned long vmcs_host_cr4; /* May not match real cr4 */ | |
| 203 | 205 | struct list_head loaded_vmcss_on_cpu_link; |
| 204 | 206 | }; |
| 205 | 207 | |
| @@ -600,8 +602,6 @@ struct vcpu_vmx { · 394 unmodified lines | ||
| 600 | 602 | int gs_ldt_reload_needed; |
| 601 | 603 | int fs_reload_needed; |
| 602 | 604 | u64 msr_host_bndcfgs; |
| 603 | − unsigned long vmcs_host_cr3; /* May not match real cr3 */ | |
| 604 | − unsigned long vmcs_host_cr4; /* May not match real cr4 */ | |
| 605 | 605 | } host_state; |
| 606 | 606 | struct { |
| 607 | 607 | int vm86_active; |
| @@ -2202,46 +2202,44 @@ static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) · 1594 unmodified lines | ||
| 2202 | 2202 | struct pi_desc old, new; |
| 2203 | 2203 | unsigned int dest; |
| 2204 | 2204 | |
| 2205 | − if (!kvm_arch_has_assigned_device(vcpu->kvm) || | |
| 2206 | − !irq_remapping_cap(IRQ_POSTING_CAP) || | |
| 2207 | − !kvm_vcpu_apicv_active(vcpu)) | |
| 2205 | + /* | |
| 2206 | + * In case of hot-plug or hot-unplug, we may have to undo | |
| 2207 | + * vmx_vcpu_pi_put even if there is no assigned device. And we | |
| 2208 | + * always keep PI.NDST up to date for simplicity: it makes the | |
| 2209 | + * code easier, and CPU migration is not a fast path. | |
| 2210 | + */ | |
| 2211 | + if (!pi_test_sn(pi_desc) && vcpu->cpu == cpu) | |
| 2212 | + return; | |
| 2213 | + | |
| 2214 | + /* | |
| 2215 | + * First handle the simple case where no cmpxchg is necessary; just | |
| 2216 | + * allow posting non-urgent interrupts. | |
| 2217 | + * | |
| 2218 | + * If the 'nv' field is POSTED_INTR_WAKEUP_VECTOR, do not change | |
| 2219 | + * PI.NDST: pi_post_block will do it for us and the wakeup_handler | |
| 2220 | + * expects the VCPU to be on the blocked_vcpu_list that matches | |
| 2221 | + * PI.NDST. | |
| 2222 | + */ | |
| 2223 | + if (pi_desc->nv == POSTED_INTR_WAKEUP_VECTOR || | |
| 2224 | + vcpu->cpu == cpu) { | |
| 2225 | + pi_clear_sn(pi_desc); | |
| 2208 | 2226 | return; |
| 2227 | + } | |
| 2209 | 2228 | |
| 2229 | + /* The full case. */ | |
| 2210 | 2230 | do { |
| 2211 | 2231 | old.control = new.control = pi_desc->control; |
| 2212 | 2232 | |
| 2213 | − /* | |
| 2214 | − * If 'nv' field is POSTED_INTR_WAKEUP_VECTOR, there | |
| 2215 | − * are two possible cases: | |
| 2216 | − * 1. After running 'pre_block', context switch | |
| 2217 | − * happened. For this case, 'sn' was set in | |
| 2218 | − * vmx_vcpu_put(), so we need to clear it here. | |
| 2219 | − * 2. After running 'pre_block', we were blocked, | |
| 2220 | − * and woken up by some other guy. For this case, | |
| 2221 | − * we don't need to do anything, 'pi_post_block' | |
| 2222 | − * will do everything for us. However, we cannot | |
| 2223 | − * check whether it is case #1 or case #2 here | |
| 2224 | − * (maybe, not needed), so we also clear sn here, | |
| 2225 | − * I think it is not a big deal. | |
| 2226 | − */ | |
| 2227 | − if (pi_desc->nv != POSTED_INTR_WAKEUP_VECTOR) { | |
| 2228 | − if (vcpu->cpu != cpu) { | |
| 2229 | − dest = cpu_physical_id(cpu); | |
| 2230 | − | |
| 2231 | − if (x2apic_enabled()) | |
| 2232 | − new.ndst = dest; | |
| 2233 | − else | |
| 2234 | − new.ndst = (dest << 8) & 0xFF00; | |
| 2235 | − } | |
| 2233 | + dest = cpu_physical_id(cpu); | |
| 2236 | 2234 | |
| 2237 | − /* set 'NV' to 'notification vector' */ | |
| 2238 | − new.nv = POSTED_INTR_VECTOR; | |
| 2239 | − } | |
| 2235 | + if (x2apic_enabled()) | |
| 2236 | + new.ndst = dest; | |
| 2237 | + else | |
| 2238 | + new.ndst = (dest << 8) & 0xFF00; | |
| 2240 | 2239 | |
| 2241 | − /* Allow posting non-urgent interrupts */ | |
| 2242 | 2240 | new.sn = 0; |
| 2243 | − } while (cmpxchg(&pi_desc->control, old.control, | |
| 2244 | − new.control) != old.control); | |
| 2241 | + } while (cmpxchg64(&pi_desc->control, old.control, | |
| 2242 | + new.control) != old.control); | |
| 2245 | 2243 | } |
| 2246 | 2244 | |
| 2247 | 2245 | static void decache_tsc_multiplier(struct vcpu_vmx *vmx) |
| @@ -5077,21 +5075,30 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu, · 2829 unmodified lines | ||
| 5077 | 5075 | int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR; |
| 5078 | 5076 | |
| 5079 | 5077 | if (vcpu->mode == IN_GUEST_MODE) { |
| 5080 | − struct vcpu_vmx *vmx = to_vmx(vcpu); | |
| 5081 | − | |
| 5082 | 5078 | /* |
| 5083 | − * Currently, we don't support urgent interrupt, | |
| 5084 | − * all interrupts are recognized as non-urgent | |
| 5085 | − * interrupt, so we cannot post interrupts when | |
| 5086 | − * 'SN' is set. | |
| 5079 | + * The vector of interrupt to be delivered to vcpu had | |
| 5080 | + * been set in PIR before this function. | |
| 5081 | + * | |
| 5082 | + * Following cases will be reached in this block, and | |
| 5083 | + * we always send a notification event in all cases as | |
| 5084 | + * explained below. | |
| 5085 | + * | |
| 5086 | + * Case 1: vcpu keeps in non-root mode. Sending a | |
| 5087 | + * notification event posts the interrupt to vcpu. | |
| 5087 | 5088 | * |
| 5088 | − * If the vcpu is in guest mode, it means it is | |
| 5089 | − * running instead of being scheduled out and | |
| 5090 | − * waiting in the run queue, and that's the only | |
| 5091 | − * case when 'SN' is set currently, warning if | |
| 5092 | − * 'SN' is set. | |
| 5089 | + * Case 2: vcpu exits to root mode and is still | |
| 5090 | + * runnable. PIR will be synced to vIRR before the | |
| 5091 | + * next vcpu entry. Sending a notification event in | |
| 5092 | + * this case has no effect, as vcpu is not in root | |
| 5093 | + * mode. | |
| 5094 | + * | |
| 5095 | + * Case 3: vcpu exits to root mode and is blocked. | |
| 5096 | + * vcpu_block() has already synced PIR to vIRR and | |
| 5097 | + * never blocks vcpu if vIRR is not cleared. Therefore, | |
| 5098 | + * a blocked vcpu here does not wait for any requested | |
| 5099 | + * interrupts in PIR, and sending a notification event | |
| 5100 | + * which has no effect is safe here. | |
| 5093 | 5101 | */ |
| 5094 | − WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc)); | |
| 5095 | 5102 | |
| 5096 | 5103 | apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec); |
| 5097 | 5104 | return true; |
| @@ -5169,12 +5176,12 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx) · 71 unmodified lines | ||
| 5169 | 5176 | */ |
| 5170 | 5177 | cr3 = __read_cr3(); |
| 5171 | 5178 | vmcs_writel(HOST_CR3, cr3); /* 22.2.3 FIXME: shadow tables */ |
| 5172 | − vmx->host_state.vmcs_host_cr3 = cr3; | |
| 5179 | + vmx->loaded_vmcs->vmcs_host_cr3 = cr3; | |
| 5173 | 5180 | |
| 5174 | 5181 | /* Save the most likely value for this task's CR4 in the VMCS. */ |
| 5175 | 5182 | cr4 = cr4_read_shadow(); |
| 5176 | 5183 | vmcs_writel(HOST_CR4, cr4); /* 22.2.3, 22.2.5 */ |
| 5177 | − vmx->host_state.vmcs_host_cr4 = cr4; | |
| 5184 | + vmx->loaded_vmcs->vmcs_host_cr4 = cr4; | |
| 5178 | 5185 | |
| 5179 | 5186 | vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ |
| 5180 | 5187 | #ifdef CONFIG_X86_64 |
| @@ -9036,7 +9043,6 @@ static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx) · 3855 unmodified lines | ||
| 9036 | 9043 | static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) |
| 9037 | 9044 | { |
| 9038 | 9045 | u32 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); |
| 9039 | − register void *__sp asm(_ASM_SP); | |
| 9040 | 9046 | |
| 9041 | 9047 | if ((exit_intr_info & (INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK)) |
| 9042 | 9048 | == (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR)) { |
| @@ -9065,7 +9071,7 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) · 22 unmodified lines | ||
| 9065 | 9071 | #ifdef CONFIG_X86_64 |
| 9066 | 9072 | [sp]"=&r"(tmp), |
| 9067 | 9073 | #endif |
| 9068 | − "+r"(__sp) | |
| 9074 | + ASM_CALL_CONSTRAINT | |
| 9069 | 9075 | : |
| 9070 | 9076 | [entry]"r"(entry), |
| 9071 | 9077 | [ss]"i"(__KERNEL_DS), |
| @@ -9265,15 +9271,15 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) · 193 unmodified lines | ||
| 9265 | 9271 | vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); |
| 9266 | 9272 | |
| 9267 | 9273 | cr3 = __get_current_cr3_fast(); |
| 9268 | − if (unlikely(cr3 != vmx->host_state.vmcs_host_cr3)) { | |
| 9274 | + if (unlikely(cr3 != vmx->loaded_vmcs->vmcs_host_cr3)) { | |
| 9269 | 9275 | vmcs_writel(HOST_CR3, cr3); |
| 9270 | − vmx->host_state.vmcs_host_cr3 = cr3; | |
| 9276 | + vmx->loaded_vmcs->vmcs_host_cr3 = cr3; | |
| 9271 | 9277 | } |
| 9272 | 9278 | |
| 9273 | 9279 | cr4 = cr4_read_shadow(); |
| 9274 | − if (unlikely(cr4 != vmx->host_state.vmcs_host_cr4)) { | |
| 9280 | + if (unlikely(cr4 != vmx->loaded_vmcs->vmcs_host_cr4)) { | |
| 9275 | 9281 | vmcs_writel(HOST_CR4, cr4); |
| 9276 | − vmx->host_state.vmcs_host_cr4 = cr4; | |
| 9282 | + vmx->loaded_vmcs->vmcs_host_cr4 = cr4; | |
| 9277 | 9283 | } |
| 9278 | 9284 | |
| 9279 | 9285 | /* When single-stepping over STI and MOV SS, we must clear the |
| @@ -9583,6 +9589,13 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) · 303 unmodified lines | ||
| 9583 | 9589 | |
| 9584 | 9590 | vmx->msr_ia32_feature_control_valid_bits = FEATURE_CONTROL_LOCKED; |
| 9585 | 9591 | |
| 9592 | + /* | |
| 9593 | + * Enforce invariant: pi_desc.nv is always either POSTED_INTR_VECTOR | |
| 9594 | + * or POSTED_INTR_WAKEUP_VECTOR. | |
| 9595 | + */ | |
| 9596 | + vmx->pi_desc.nv = POSTED_INTR_VECTOR; | |
| 9597 | + vmx->pi_desc.sn = 1; | |
| 9598 | + | |
| 9586 | 9599 | return &vmx->vcpu; |
| 9587 | 9600 | |
| 9588 | 9601 | free_vmcs: |
| @@ -9831,7 +9844,8 @@ static void vmx_inject_page_fault_nested(struct kvm_vcpu *vcpu, · 242 unmodified lines | ||
| 9831 | 9844 | |
| 9832 | 9845 | WARN_ON(!is_guest_mode(vcpu)); |
| 9833 | 9846 | |
| 9834 | − if (nested_vmx_is_page_fault_vmexit(vmcs12, fault->error_code)) { | |
| 9847 | + if (nested_vmx_is_page_fault_vmexit(vmcs12, fault->error_code) && | |
| 9848 | + !to_vmx(vcpu)->nested.nested_run_pending) { | |
| 9835 | 9849 | vmcs12->vm_exit_intr_error_code = fault->error_code; |
| 9836 | 9850 | nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI, |
| 9837 | 9851 | PF_VECTOR | INTR_TYPE_HARD_EXCEPTION | |
| @@ -11696,6 +11710,37 @@ static void vmx_enable_log_dirty_pt_masked(struct kvm *kvm, · 1858 unmodified lines | ||
| 11696 | 11710 | kvm_mmu_clear_dirty_pt_masked(kvm, memslot, offset, mask); |
| 11697 | 11711 | } |
| 11698 | 11712 | |
| 11713 | +static void __pi_post_block(struct kvm_vcpu *vcpu) | |
| 11714 | +{ | |
| 11715 | + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); | |
| 11716 | + struct pi_desc old, new; | |
| 11717 | + unsigned int dest; | |
| 11718 | + | |
| 11719 | + do { | |
| 11720 | + old.control = new.control = pi_desc->control; | |
| 11721 | + WARN(old.nv != POSTED_INTR_WAKEUP_VECTOR, | |
| 11722 | + "Wakeup handler not enabled while the VCPU is blocked\n"); | |
| 11723 | + | |
| 11724 | + dest = cpu_physical_id(vcpu->cpu); | |
| 11725 | + | |
| 11726 | + if (x2apic_enabled()) | |
| 11727 | + new.ndst = dest; | |
| 11728 | + else | |
| 11729 | + new.ndst = (dest << 8) & 0xFF00; | |
| 11730 | + | |
| 11731 | + /* set 'NV' to 'notification vector' */ | |
| 11732 | + new.nv = POSTED_INTR_VECTOR; | |
| 11733 | + } while (cmpxchg64(&pi_desc->control, old.control, | |
| 11734 | + new.control) != old.control); | |
| 11735 | + | |
| 11736 | + if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { | |
| 11737 | + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); | |
| 11738 | + list_del(&vcpu->blocked_vcpu_list); | |
| 11739 | + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); | |
| 11740 | + vcpu->pre_pcpu = -1; | |
| 11741 | + } | |
| 11742 | +} | |
| 11743 | + | |
| 11699 | 11744 | /* |
| 11700 | 11745 | * This routine does the following things for vCPU which is going |
| 11701 | 11746 | * to be blocked if VT-d PI is enabled. |
| @@ -11711,7 +11756,6 @@ static void vmx_enable_log_dirty_pt_masked(struct kvm *kvm, · 9 unmodified lines | ||
| 11711 | 11756 | */ |
| 11712 | 11757 | static int pi_pre_block(struct kvm_vcpu *vcpu) |
| 11713 | 11758 | { |
| 11714 | − unsigned long flags; | |
| 11715 | 11759 | unsigned int dest; |
| 11716 | 11760 | struct pi_desc old, new; |
| 11717 | 11761 | struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); |
| @@ -11721,34 +11765,20 @@ static int pi_pre_block(struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 11721 | 11765 | !kvm_vcpu_apicv_active(vcpu)) |
| 11722 | 11766 | return 0; |
| 11723 | 11767 | |
| 11724 | − vcpu->pre_pcpu = vcpu->cpu; | |
| 11725 | − spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock, | |
| 11726 | − vcpu->pre_pcpu), flags); | |
| 11727 | − list_add_tail(&vcpu->blocked_vcpu_list, | |
| 11728 | − &per_cpu(blocked_vcpu_on_cpu, | |
| 11729 | − vcpu->pre_pcpu)); | |
| 11730 | − spin_unlock_irqrestore(&per_cpu(blocked_vcpu_on_cpu_lock, | |
| 11731 | − vcpu->pre_pcpu), flags); | |
| 11768 | + WARN_ON(irqs_disabled()); | |
| 11769 | + local_irq_disable(); | |
| 11770 | + if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { | |
| 11771 | + vcpu->pre_pcpu = vcpu->cpu; | |
| 11772 | + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); | |
| 11773 | + list_add_tail(&vcpu->blocked_vcpu_list, | |
| 11774 | + &per_cpu(blocked_vcpu_on_cpu, | |
| 11775 | + vcpu->pre_pcpu)); | |
| 11776 | + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); | |
| 11777 | + } | |
| 11732 | 11778 | |
| 11733 | 11779 | do { |
| 11734 | 11780 | old.control = new.control = pi_desc->control; |
| 11735 | 11781 | |
| 11736 | − /* | |
| 11737 | − * We should not block the vCPU if | |
| 11738 | − * an interrupt is posted for it. | |
| 11739 | − */ | |
| 11740 | − if (pi_test_on(pi_desc) == 1) { | |
| 11741 | − spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock, | |
| 11742 | − vcpu->pre_pcpu), flags); | |
| 11743 | − list_del(&vcpu->blocked_vcpu_list); | |
| 11744 | − spin_unlock_irqrestore( | |
| 11745 | − &per_cpu(blocked_vcpu_on_cpu_lock, | |
| 11746 | − vcpu->pre_pcpu), flags); | |
| 11747 | − vcpu->pre_pcpu = -1; | |
| 11748 | − | |
| 11749 | − return 1; | |
| 11750 | − } | |
| 11751 | − | |
| 11752 | 11782 | WARN((pi_desc->sn == 1), |
| 11753 | 11783 | "Warning: SN field of posted-interrupts " |
| 11754 | 11784 | "is set before blocking\n"); |
| @@ -11770,10 +11800,15 @@ static int pi_pre_block(struct kvm_vcpu *vcpu) · 15 unmodified lines | ||
| 11770 | 11800 | |
| 11771 | 11801 | /* set 'NV' to 'wakeup vector' */ |
| 11772 | 11802 | new.nv = POSTED_INTR_WAKEUP_VECTOR; |
| 11773 | − } while (cmpxchg(&pi_desc->control, old.control, | |
| 11774 | − new.control) != old.control); | |
| 11803 | + } while (cmpxchg64(&pi_desc->control, old.control, | |
| 11804 | + new.control) != old.control); | |
| 11775 | 11805 | |
| 11776 | − return 0; | |
| 11806 | + /* We should not block the vCPU if an interrupt is posted for it. */ | |
| 11807 | + if (pi_test_on(pi_desc) == 1) | |
| 11808 | + __pi_post_block(vcpu); | |
| 11809 | + | |
| 11810 | + local_irq_enable(); | |
| 11811 | + return (vcpu->pre_pcpu == -1); | |
| 11777 | 11812 | } |
| 11778 | 11813 | |
| 11779 | 11814 | static int vmx_pre_block(struct kvm_vcpu *vcpu) |
| @@ -11789,44 +11824,13 @@ static int vmx_pre_block(struct kvm_vcpu *vcpu) · 9 unmodified lines | ||
| 11789 | 11824 | |
| 11790 | 11825 | static void pi_post_block(struct kvm_vcpu *vcpu) |
| 11791 | 11826 | { |
| 11792 | − struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); | |
| 11793 | − struct pi_desc old, new; | |
| 11794 | − unsigned int dest; | |
| 11795 | − unsigned long flags; | |
| 11796 | − | |
| 11797 | − if (!kvm_arch_has_assigned_device(vcpu->kvm) || | |
| 11798 | − !irq_remapping_cap(IRQ_POSTING_CAP) || | |
| 11799 | − !kvm_vcpu_apicv_active(vcpu)) | |
| 11827 | + if (vcpu->pre_pcpu == -1) | |
| 11800 | 11828 | return; |
| 11801 | 11829 | |
| 11802 | − do { | |
| 11803 | − old.control = new.control = pi_desc->control; | |
| 11804 | − | |
| 11805 | − dest = cpu_physical_id(vcpu->cpu); | |
| 11806 | − | |
| 11807 | − if (x2apic_enabled()) | |
| 11808 | − new.ndst = dest; | |
| 11809 | − else | |
| 11810 | − new.ndst = (dest << 8) & 0xFF00; | |
| 11811 | − | |
| 11812 | − /* Allow posting non-urgent interrupts */ | |
| 11813 | − new.sn = 0; | |
| 11814 | − | |
| 11815 | − /* set 'NV' to 'notification vector' */ | |
| 11816 | − new.nv = POSTED_INTR_VECTOR; | |
| 11817 | − } while (cmpxchg(&pi_desc->control, old.control, | |
| 11818 | − new.control) != old.control); | |
| 11819 | − | |
| 11820 | − if(vcpu->pre_pcpu != -1) { | |
| 11821 | − spin_lock_irqsave( | |
| 11822 | − &per_cpu(blocked_vcpu_on_cpu_lock, | |
| 11823 | − vcpu->pre_pcpu), flags); | |
| 11824 | − list_del(&vcpu->blocked_vcpu_list); | |
| 11825 | − spin_unlock_irqrestore( | |
| 11826 | − &per_cpu(blocked_vcpu_on_cpu_lock, | |
| 11827 | − vcpu->pre_pcpu), flags); | |
| 11828 | − vcpu->pre_pcpu = -1; | |
| 11829 | − } | |
| 11830 | + WARN_ON(irqs_disabled()); | |
| 11831 | + local_irq_disable(); | |
| 11832 | + __pi_post_block(vcpu); | |
| 11833 | + local_irq_enable(); | |
| 11830 | 11834 | } |
| 11831 | 11835 | |
| 11832 | 11836 | static void vmx_post_block(struct kvm_vcpu *vcpu) |
| @@ -11911,12 +11915,8 @@ static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq, · 78 unmodified lines | ||
| 11911 | 11915 | |
| 11912 | 11916 | if (set) |
| 11913 | 11917 | ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); |
| 11914 | − else { | |
| 11915 | − /* suppress notification event before unposting */ | |
| 11916 | − pi_set_sn(vcpu_to_pi_desc(vcpu)); | |
| 11918 | + else | |
| 11917 | 11919 | ret = irq_set_vcpu_affinity(host_irq, NULL); |
| 11918 | − pi_clear_sn(vcpu_to_pi_desc(vcpu)); | |
| 11919 | − } | |
| 11920 | 11920 | |
| 11921 | 11921 | if (ret < 0) { |
| 11922 | 11922 | printk(KERN_INFO "%s: failed to update PI IRTE\n", |
| @@ -7225,7 +7225,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · 7224 unmodified lines | ||
| 7225 | 7225 | int r; |
| 7226 | 7226 | sigset_t sigsaved; |
| 7227 | 7227 | |
| 7228 | − fpu__activate_curr(fpu); | |
| 7228 | + fpu__initialize(fpu); | |
| 7229 | 7229 | |
| 7230 | 7230 | if (vcpu->sigset_active) |
| 7231 | 7231 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); |
| @@ -114,7 +114,7 @@ void math_emulate(struct math_emu_info *info) · 113 unmodified lines | ||
| 114 | 114 | struct desc_struct code_descriptor; |
| 115 | 115 | struct fpu *fpu = ¤t->thread.fpu; |
| 116 | 116 | |
| 117 | − fpu__activate_curr(fpu); | |
| 117 | + fpu__initialize(fpu); | |
| 118 | 118 | |
| 119 | 119 | #ifdef RE_ENTRANT_CHECKING |
| 120 | 120 | if (emulating) { |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #include <linux/uaccess.h> |
| 3 | 3 | #include <linux/sched/debug.h> |
| 4 | 4 | |
| 5 | +#include <asm/fpu/internal.h> | |
| 5 | 6 | #include <asm/traps.h> |
| 6 | 7 | #include <asm/kdebug.h> |
| 7 | 8 | |
| @@ -78,6 +79,29 @@ bool ex_handler_refcount(const struct exception_table_entry *fixup, · 70 unmodified lines | ||
| 78 | 79 | } |
| 79 | 80 | EXPORT_SYMBOL_GPL(ex_handler_refcount); |
| 80 | 81 | |
| 82 | +/* | |
| 83 | + * Handler for when we fail to restore a task's FPU state. We should never get | |
| 84 | + * here because the FPU state of a task using the FPU (task->thread.fpu.state) | |
| 85 | + * should always be valid. However, past bugs have allowed userspace to set | |
| 86 | + * reserved bits in the XSAVE area using PTRACE_SETREGSET or sys_rt_sigreturn(). | |
| 87 | + * These caused XRSTOR to fail when switching to the task, leaking the FPU | |
| 88 | + * registers of the task previously executing on the CPU. Mitigate this class | |
| 89 | + * of vulnerability by restoring from the initial state (essentially, zeroing | |
| 90 | + * out all the FPU registers) if we can't restore from the task's FPU state. | |
| 91 | + */ | |
| 92 | +bool ex_handler_fprestore(const struct exception_table_entry *fixup, | |
| 93 | + struct pt_regs *regs, int trapnr) | |
| 94 | +{ | |
| 95 | + regs->ip = ex_fixup_addr(fixup); | |
| 96 | + | |
| 97 | + WARN_ONCE(1, "Bad FPU state detected at %pB, reinitializing FPU registers.", | |
| 98 | + (void *)instruction_pointer(regs)); | |
| 99 | + | |
| 100 | + __copy_kernel_to_fpregs(&init_fpstate, -1); | |
| 101 | + return true; | |
| 102 | +} | |
| 103 | +EXPORT_SYMBOL_GPL(ex_handler_fprestore); | |
| 104 | + | |
| 81 | 105 | bool ex_handler_ext(const struct exception_table_entry *fixup, |
| 82 | 106 | struct pt_regs *regs, int trapnr) |
| 83 | 107 | { |
| @@ -192,8 +192,7 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) · 191 unmodified lines | ||
| 192 | 192 | * 6. T1 : reaches here, sees vma_pkey(vma)=5, when we really |
| 193 | 193 | * faulted on a pte with its pkey=4. |
| 194 | 194 | */ |
| 195 | −static void fill_sig_info_pkey(int si_code, siginfo_t *info, | |
| 196 | − struct vm_area_struct *vma) | |
| 195 | +static void fill_sig_info_pkey(int si_code, siginfo_t *info, u32 *pkey) | |
| 197 | 196 | { |
| 198 | 197 | /* This is effectively an #ifdef */ |
| 199 | 198 | if (!boot_cpu_has(X86_FEATURE_OSPKE)) |
| @@ -209,7 +208,7 @@ static void fill_sig_info_pkey(int si_code, siginfo_t *info, · 9 unmodified lines | ||
| 209 | 208 | * valid VMA, so we should never reach this without a |
| 210 | 209 | * valid VMA. |
| 211 | 210 | */ |
| 212 | − if (!vma) { | |
| 211 | + if (!pkey) { | |
| 213 | 212 | WARN_ONCE(1, "PKU fault with no VMA passed in"); |
| 214 | 213 | info->si_pkey = 0; |
| 215 | 214 | return; |
| @@ -219,13 +218,12 @@ static void fill_sig_info_pkey(int si_code, siginfo_t *info, · 3 unmodified lines | ||
| 219 | 218 | * absolutely guranteed to be 100% accurate because of |
| 220 | 219 | * the race explained above. |
| 221 | 220 | */ |
| 222 | − info->si_pkey = vma_pkey(vma); | |
| 221 | + info->si_pkey = *pkey; | |
| 223 | 222 | } |
| 224 | 223 | |
| 225 | 224 | static void |
| 226 | 225 | force_sig_info_fault(int si_signo, int si_code, unsigned long address, |
| 227 | − struct task_struct *tsk, struct vm_area_struct *vma, | |
| 228 | − int fault) | |
| 226 | + struct task_struct *tsk, u32 *pkey, int fault) | |
| 229 | 227 | { |
| 230 | 228 | unsigned lsb = 0; |
| 231 | 229 | siginfo_t info; |
| @@ -240,7 +238,7 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long address, · 8 unmodified lines | ||
| 240 | 238 | lsb = PAGE_SHIFT; |
| 241 | 239 | info.si_addr_lsb = lsb; |
| 242 | 240 | |
| 243 | − fill_sig_info_pkey(si_code, &info, vma); | |
| 241 | + fill_sig_info_pkey(si_code, &info, pkey); | |
| 244 | 242 | |
| 245 | 243 | force_sig_info(si_signo, &info, tsk); |
| 246 | 244 | } |
| @@ -762,8 +760,6 @@ no_context(struct pt_regs *regs, unsigned long error_code, · 515 unmodified lines | ||
| 762 | 760 | struct task_struct *tsk = current; |
| 763 | 761 | unsigned long flags; |
| 764 | 762 | int sig; |
| 765 | − /* No context means no VMA to pass down */ | |
| 766 | − struct vm_area_struct *vma = NULL; | |
| 767 | 763 | |
| 768 | 764 | /* Are we prepared to handle this kernel fault? */ |
| 769 | 765 | if (fixup_exception(regs, X86_TRAP_PF)) { |
| @@ -788,7 +784,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, · 18 unmodified lines | ||
| 788 | 784 | |
| 789 | 785 | /* XXX: hwpoison faults will set the wrong code. */ |
| 790 | 786 | force_sig_info_fault(signal, si_code, address, |
| 791 | − tsk, vma, 0); | |
| 787 | + tsk, NULL, 0); | |
| 792 | 788 | } |
| 793 | 789 | |
| 794 | 790 | /* |
| @@ -806,7 +802,6 @@ no_context(struct pt_regs *regs, unsigned long error_code, · 11 unmodified lines | ||
| 806 | 802 | if (is_vmalloc_addr((void *)address) && |
| 807 | 803 | (((unsigned long)tsk->stack - 1 - address < PAGE_SIZE) || |
| 808 | 804 | address - ((unsigned long)tsk->stack + THREAD_SIZE) < PAGE_SIZE)) { |
| 809 | − register void *__sp asm("rsp"); | |
| 810 | 805 | unsigned long stack = this_cpu_read(orig_ist.ist[DOUBLEFAULT_STACK]) - sizeof(void *); |
| 811 | 806 | /* |
| 812 | 807 | * We're likely to be running with very little stack space |
| @@ -821,7 +816,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, · 8 unmodified lines | ||
| 821 | 816 | asm volatile ("movq %[stack], %%rsp\n\t" |
| 822 | 817 | "call handle_stack_overflow\n\t" |
| 823 | 818 | "1: jmp 1b" |
| 824 | − : "+r" (__sp) | |
| 819 | + : ASM_CALL_CONSTRAINT | |
| 825 | 820 | : "D" ("kernel stack overflow (page fault)"), |
| 826 | 821 | "S" (regs), "d" (address), |
| 827 | 822 | [stack] "rm" (stack)); |
| @@ -897,8 +892,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, · 69 unmodified lines | ||
| 897 | 892 | |
| 898 | 893 | static void |
| 899 | 894 | __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, |
| 900 | − unsigned long address, struct vm_area_struct *vma, | |
| 901 | − int si_code) | |
| 895 | + unsigned long address, u32 *pkey, int si_code) | |
| 902 | 896 | { |
| 903 | 897 | struct task_struct *tsk = current; |
| 904 | 898 | |
| @@ -946,7 +940,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, · 41 unmodified lines | ||
| 946 | 940 | tsk->thread.error_code = error_code; |
| 947 | 941 | tsk->thread.trap_nr = X86_TRAP_PF; |
| 948 | 942 | |
| 949 | − force_sig_info_fault(SIGSEGV, si_code, address, tsk, vma, 0); | |
| 943 | + force_sig_info_fault(SIGSEGV, si_code, address, tsk, pkey, 0); | |
| 950 | 944 | |
| 951 | 945 | return; |
| 952 | 946 | } |
| @@ -959,9 +953,9 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, · 6 unmodified lines | ||
| 959 | 953 | |
| 960 | 954 | static noinline void |
| 961 | 955 | bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, |
| 962 | − unsigned long address, struct vm_area_struct *vma) | |
| 956 | + unsigned long address, u32 *pkey) | |
| 963 | 957 | { |
| 964 | − __bad_area_nosemaphore(regs, error_code, address, vma, SEGV_MAPERR); | |
| 958 | + __bad_area_nosemaphore(regs, error_code, address, pkey, SEGV_MAPERR); | |
| 965 | 959 | } |
| 966 | 960 | |
| 967 | 961 | static void |
| @@ -969,6 +963,10 @@ __bad_area(struct pt_regs *regs, unsigned long error_code, · 1 unmodified line | ||
| 969 | 963 | unsigned long address, struct vm_area_struct *vma, int si_code) |
| 970 | 964 | { |
| 971 | 965 | struct mm_struct *mm = current->mm; |
| 966 | + u32 pkey; | |
| 967 | + | |
| 968 | + if (vma) | |
| 969 | + pkey = vma_pkey(vma); | |
| 972 | 970 | |
| 973 | 971 | /* |
| 974 | 972 | * Something tried to access memory that isn't in our memory map.. |
| @@ -976,7 +974,8 @@ __bad_area(struct pt_regs *regs, unsigned long error_code, · 1 unmodified line | ||
| 976 | 974 | */ |
| 977 | 975 | up_read(&mm->mmap_sem); |
| 978 | 976 | |
| 979 | − __bad_area_nosemaphore(regs, error_code, address, vma, si_code); | |
| 977 | + __bad_area_nosemaphore(regs, error_code, address, | |
| 978 | + (vma) ? &pkey : NULL, si_code); | |
| 980 | 979 | } |
| 981 | 980 | |
| 982 | 981 | static noinline void |
| @@ -1019,7 +1018,7 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code, · 36 unmodified lines | ||
| 1019 | 1018 | |
| 1020 | 1019 | static void |
| 1021 | 1020 | do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, |
| 1022 | − struct vm_area_struct *vma, unsigned int fault) | |
| 1021 | + u32 *pkey, unsigned int fault) | |
| 1023 | 1022 | { |
| 1024 | 1023 | struct task_struct *tsk = current; |
| 1025 | 1024 | int code = BUS_ADRERR; |
| @@ -1046,13 +1045,12 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, · 20 unmodified lines | ||
| 1046 | 1045 | code = BUS_MCEERR_AR; |
| 1047 | 1046 | } |
| 1048 | 1047 | #endif |
| 1049 | − force_sig_info_fault(SIGBUS, code, address, tsk, vma, fault); | |
| 1048 | + force_sig_info_fault(SIGBUS, code, address, tsk, pkey, fault); | |
| 1050 | 1049 | } |
| 1051 | 1050 | |
| 1052 | 1051 | static noinline void |
| 1053 | 1052 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, |
| 1054 | − unsigned long address, struct vm_area_struct *vma, | |
| 1055 | − unsigned int fault) | |
| 1053 | + unsigned long address, u32 *pkey, unsigned int fault) | |
| 1056 | 1054 | { |
| 1057 | 1055 | if (fatal_signal_pending(current) && !(error_code & PF_USER)) { |
| 1058 | 1056 | no_context(regs, error_code, address, 0, 0); |
| @@ -1076,9 +1074,9 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, · 17 unmodified lines | ||
| 1076 | 1074 | } else { |
| 1077 | 1075 | if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| |
| 1078 | 1076 | VM_FAULT_HWPOISON_LARGE)) |
| 1079 | − do_sigbus(regs, error_code, address, vma, fault); | |
| 1077 | + do_sigbus(regs, error_code, address, pkey, fault); | |
| 1080 | 1078 | else if (fault & VM_FAULT_SIGSEGV) |
| 1081 | − bad_area_nosemaphore(regs, error_code, address, vma); | |
| 1079 | + bad_area_nosemaphore(regs, error_code, address, pkey); | |
| 1082 | 1080 | else |
| 1083 | 1081 | BUG(); |
| 1084 | 1082 | } |
| @@ -1268,6 +1266,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, · 183 unmodified lines | ||
| 1268 | 1266 | struct mm_struct *mm; |
| 1269 | 1267 | int fault, major = 0; |
| 1270 | 1268 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
| 1269 | + u32 pkey; | |
| 1271 | 1270 | |
| 1272 | 1271 | tsk = current; |
| 1273 | 1272 | mm = tsk->mm; |
| @@ -1468,9 +1467,10 @@ good_area: · 194 unmodified lines | ||
| 1468 | 1467 | return; |
| 1469 | 1468 | } |
| 1470 | 1469 | |
| 1470 | + pkey = vma_pkey(vma); | |
| 1471 | 1471 | up_read(&mm->mmap_sem); |
| 1472 | 1472 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 1473 | − mm_fault_error(regs, error_code, address, vma, fault); | |
| 1473 | + mm_fault_error(regs, error_code, address, &pkey, fault); | |
| 1474 | 1474 | return; |
| 1475 | 1475 | } |
| 1476 | 1476 | |
| @@ -10,6 +10,8 @@ · 9 unmodified lines | ||
| 10 | 10 | * published by the Free Software Foundation. |
| 11 | 11 | */ |
| 12 | 12 | |
| 13 | +#define DISABLE_BRANCH_PROFILING | |
| 14 | + | |
| 13 | 15 | #include <linux/linkage.h> |
| 14 | 16 | #include <linux/init.h> |
| 15 | 17 | #include <linux/mm.h> |
| @@ -18,7 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #include <asm/cpufeature.h> /* boot_cpu_has, ... */ |
| 20 | 20 | #include <asm/mmu_context.h> /* vma_pkey() */ |
| 21 | −#include <asm/fpu/internal.h> /* fpregs_active() */ | |
| 22 | 21 | |
| 23 | 22 | int __execute_only_pkey(struct mm_struct *mm) |
| 24 | 23 | { |
| @@ -45,7 +44,7 @@ int __execute_only_pkey(struct mm_struct *mm) · 20 unmodified lines | ||
| 45 | 44 | */ |
| 46 | 45 | preempt_disable(); |
| 47 | 46 | if (!need_to_set_mm_pkey && |
| 48 | − fpregs_active() && | |
| 47 | + current->thread.fpu.initialized && | |
| 49 | 48 | !__pkru_allows_read(read_pkru(), execute_only_pkey)) { |
| 50 | 49 | preempt_enable(); |
| 51 | 50 | return execute_only_pkey; |
| @@ -126,8 +126,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, · 125 unmodified lines | ||
| 126 | 126 | * isn't free. |
| 127 | 127 | */ |
| 128 | 128 | #ifdef CONFIG_DEBUG_VM |
| 129 | − if (WARN_ON_ONCE(__read_cr3() != | |
| 130 | − (__sme_pa(real_prev->pgd) | prev_asid))) { | |
| 129 | + if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev, prev_asid))) { | |
| 131 | 130 | /* |
| 132 | 131 | * If we were to BUG here, we'd be very likely to kill |
| 133 | 132 | * the system so hard that we don't see the call trace. |
| @@ -172,7 +171,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, · 38 unmodified lines | ||
| 172 | 171 | */ |
| 173 | 172 | this_cpu_write(cpu_tlbstate.ctxs[prev_asid].tlb_gen, |
| 174 | 173 | next_tlb_gen); |
| 175 | − write_cr3(__sme_pa(next->pgd) | prev_asid); | |
| 174 | + write_cr3(build_cr3(next, prev_asid)); | |
| 176 | 175 | trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, |
| 177 | 176 | TLB_FLUSH_ALL); |
| 178 | 177 | } |
| @@ -192,7 +191,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, · 13 unmodified lines | ||
| 192 | 191 | * mapped in the new pgd, we'll double-fault. Forcibly |
| 193 | 192 | * map it. |
| 194 | 193 | */ |
| 195 | − unsigned int index = pgd_index(current_stack_pointer()); | |
| 194 | + unsigned int index = pgd_index(current_stack_pointer); | |
| 196 | 195 | pgd_t *pgd = next->pgd + index; |
| 197 | 196 | |
| 198 | 197 | if (unlikely(pgd_none(*pgd))) |
| @@ -216,12 +215,12 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, · 17 unmodified lines | ||
| 216 | 215 | if (need_flush) { |
| 217 | 216 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id); |
| 218 | 217 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); |
| 219 | − write_cr3(__sme_pa(next->pgd) | new_asid); | |
| 218 | + write_cr3(build_cr3(next, new_asid)); | |
| 220 | 219 | trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, |
| 221 | 220 | TLB_FLUSH_ALL); |
| 222 | 221 | } else { |
| 223 | 222 | /* The new ASID is already up to date. */ |
| 224 | − write_cr3(__sme_pa(next->pgd) | new_asid | CR3_NOFLUSH); | |
| 223 | + write_cr3(build_cr3_noflush(next, new_asid)); | |
| 225 | 224 | trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, 0); |
| 226 | 225 | } |
| 227 | 226 | |
| @@ -265,7 +264,7 @@ void initialize_tlbstate_and_flush(void) · 37 unmodified lines | ||
| 265 | 264 | !(cr4_read_shadow() & X86_CR4_PCIDE)); |
| 266 | 265 | |
| 267 | 266 | /* Force ASID 0 and force a TLB flush. */ |
| 268 | − write_cr3(cr3 & ~CR3_PCID_MASK); | |
| 267 | + write_cr3(build_cr3(mm, 0)); | |
| 269 | 268 | |
| 270 | 269 | /* Reinitialize tlbstate. */ |
| 271 | 270 | this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0); |
| @@ -284,9 +284,9 @@ static void emit_bpf_tail_call(u8 **pprog) · 283 unmodified lines | ||
| 284 | 284 | /* if (index >= array->map.max_entries) |
| 285 | 285 | * goto out; |
| 286 | 286 | */ |
| 287 | − EMIT4(0x48, 0x8B, 0x46, /* mov rax, qword ptr [rsi + 16] */ | |
| 287 | + EMIT2(0x89, 0xD2); /* mov edx, edx */ | |
| 288 | + EMIT3(0x39, 0x56, /* cmp dword ptr [rsi + 16], edx */ | |
| 288 | 289 | offsetof(struct bpf_array, map.max_entries)); |
| 289 | − EMIT3(0x48, 0x39, 0xD0); /* cmp rax, rdx */ | |
| 290 | 290 | #define OFFSET1 43 /* number of bytes to jump */ |
| 291 | 291 | EMIT2(X86_JBE, OFFSET1); /* jbe out */ |
| 292 | 292 | label1 = cnt; |
| @@ -1238,21 +1238,16 @@ static void __init xen_pagetable_cleanhighmap(void) · 1237 unmodified lines | ||
| 1238 | 1238 | * from _brk_limit way up to the max_pfn_mapped (which is the end of |
| 1239 | 1239 | * the ramdisk). We continue on, erasing PMD entries that point to page |
| 1240 | 1240 | * tables - do note that they are accessible at this stage via __va. |
| 1241 | − * For good measure we also round up to the PMD - which means that if | |
| 1241 | + * As Xen is aligning the memory end to a 4MB boundary, for good | |
| 1242 | + * measure we also round up to PMD_SIZE * 2 - which means that if | |
| 1242 | 1243 | * anybody is using __ka address to the initial boot-stack - and try |
| 1243 | 1244 | * to use it - they are going to crash. The xen_start_info has been |
| 1244 | 1245 | * taken care of already in xen_setup_kernel_pagetable. */ |
| 1245 | 1246 | addr = xen_start_info->pt_base; |
| 1246 | − size = roundup(xen_start_info->nr_pt_frames * PAGE_SIZE, PMD_SIZE); | |
| 1247 | + size = xen_start_info->nr_pt_frames * PAGE_SIZE; | |
| 1247 | 1248 | |
| 1248 | − xen_cleanhighmap(addr, addr + size); | |
| 1249 | + xen_cleanhighmap(addr, roundup(addr + size, PMD_SIZE * 2)); | |
| 1249 | 1250 | xen_start_info->pt_base = (unsigned long)__va(__pa(xen_start_info->pt_base)); |
| 1250 | −#ifdef DEBUG | |
| 1251 | − /* This is superfluous and is not necessary, but you know what | |
| 1252 | − * lets do it. The MODULES_VADDR -> MODULES_END should be clear of | |
| 1253 | − * anything at this stage. */ | |
| 1254 | − xen_cleanhighmap(MODULES_VADDR, roundup(MODULES_VADDR, PUD_SIZE) - 1); | |
| 1255 | −#endif | |
| 1256 | 1251 | } |
| 1257 | 1252 | #endif |
| 1258 | 1253 | |
| @@ -2220,7 +2215,7 @@ static void __init xen_write_cr3_init(unsigned long cr3) · 961 unmodified lines | ||
| 2220 | 2215 | * not the first page table in the page table pool. |
| 2221 | 2216 | * Iterate through the initial page tables to find the real page table base. |
| 2222 | 2217 | */ |
| 2223 | −static phys_addr_t xen_find_pt_base(pmd_t *pmd) | |
| 2218 | +static phys_addr_t __init xen_find_pt_base(pmd_t *pmd) | |
| 2224 | 2219 | { |
| 2225 | 2220 | phys_addr_t pt_base, paddr; |
| 2226 | 2221 | unsigned pmdidx; |
| @@ -208,11 +208,6 @@ struct mm_struct; · 207 unmodified lines | ||
| 208 | 208 | /* Free all resources held by a thread. */ |
| 209 | 209 | #define release_thread(thread) do { } while(0) |
| 210 | 210 | |
| 211 | −/* Copy and release all segment info associated with a VM */ | |
| 212 | −#define copy_segments(p, mm) do { } while(0) | |
| 213 | −#define release_segments(mm) do { } while(0) | |
| 214 | −#define forget_segments() do { } while (0) | |
| 215 | − | |
| 216 | 211 | extern unsigned long get_wchan(struct task_struct *p); |
| 217 | 212 | |
| 218 | 213 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) |
| @@ -854,6 +854,9 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) · 853 unmodified lines | ||
| 854 | 854 | |
| 855 | 855 | kobject_init(&q->kobj, &blk_queue_ktype); |
| 856 | 856 | |
| 857 | +#ifdef CONFIG_BLK_DEV_IO_TRACE | |
| 858 | + mutex_init(&q->blk_trace_mutex); | |
| 859 | +#endif | |
| 857 | 860 | mutex_init(&q->sysfs_lock); |
| 858 | 861 | spin_lock_init(&q->__queue_lock); |
| 859 | 862 | |
| @@ -815,10 +815,14 @@ int blk_mq_debugfs_register(struct request_queue *q) · 814 unmodified lines | ||
| 815 | 815 | goto err; |
| 816 | 816 | |
| 817 | 817 | /* |
| 818 | − * blk_mq_init_hctx() attempted to do this already, but q->debugfs_dir | |
| 818 | + * blk_mq_init_sched() attempted to do this already, but q->debugfs_dir | |
| 819 | 819 | * didn't exist yet (because we don't know what to name the directory |
| 820 | 820 | * until the queue is registered to a gendisk). |
| 821 | 821 | */ |
| 822 | + if (q->elevator && !q->sched_debugfs_dir) | |
| 823 | + blk_mq_debugfs_register_sched(q); | |
| 824 | + | |
| 825 | + /* Similarly, blk_mq_init_hctx() couldn't do this previously. */ | |
| 822 | 826 | queue_for_each_hw_ctx(q, hctx, i) { |
| 823 | 827 | if (!hctx->debugfs_dir && blk_mq_debugfs_register_hctx(q, hctx)) |
| 824 | 828 | goto err; |
| @@ -1911,11 +1911,11 @@ static void throtl_upgrade_state(struct throtl_data *td) · 1910 unmodified lines | ||
| 1911 | 1911 | |
| 1912 | 1912 | tg->disptime = jiffies - 1; |
| 1913 | 1913 | throtl_select_dispatch(sq); |
| 1914 | − throtl_schedule_next_dispatch(sq, false); | |
| 1914 | + throtl_schedule_next_dispatch(sq, true); | |
| 1915 | 1915 | } |
| 1916 | 1916 | rcu_read_unlock(); |
| 1917 | 1917 | throtl_select_dispatch(&td->service_queue); |
| 1918 | − throtl_schedule_next_dispatch(&td->service_queue, false); | |
| 1918 | + throtl_schedule_next_dispatch(&td->service_queue, true); | |
| 1919 | 1919 | queue_work(kthrotld_workqueue, &td->dispatch_work); |
| 1920 | 1920 | } |
| 1921 | 1921 | |
| @@ -154,7 +154,6 @@ static int bsg_prepare_job(struct device *dev, struct request *req) · 153 unmodified lines | ||
| 154 | 154 | failjob_rls_rqst_payload: |
| 155 | 155 | kfree(job->request_payload.sg_list); |
| 156 | 156 | failjob_rls_job: |
| 157 | − kfree(job); | |
| 158 | 157 | return -ENOMEM; |
| 159 | 158 | } |
| 160 | 159 | |
| @@ -208,20 +207,34 @@ static int bsg_init_rq(struct request_queue *q, struct request *req, gfp_t gfp) · 47 unmodified lines | ||
| 208 | 207 | struct bsg_job *job = blk_mq_rq_to_pdu(req); |
| 209 | 208 | struct scsi_request *sreq = &job->sreq; |
| 210 | 209 | |
| 210 | + /* called right after the request is allocated for the request_queue */ | |
| 211 | + | |
| 212 | + sreq->sense = kzalloc(SCSI_SENSE_BUFFERSIZE, gfp); | |
| 213 | + if (!sreq->sense) | |
| 214 | + return -ENOMEM; | |
| 215 | + | |
| 216 | + return 0; | |
| 217 | +} | |
| 218 | + | |
| 219 | +static void bsg_initialize_rq(struct request *req) | |
| 220 | +{ | |
| 221 | + struct bsg_job *job = blk_mq_rq_to_pdu(req); | |
| 222 | + struct scsi_request *sreq = &job->sreq; | |
| 223 | + void *sense = sreq->sense; | |
| 224 | + | |
| 225 | + /* called right before the request is given to the request_queue user */ | |
| 226 | + | |
| 211 | 227 | memset(job, 0, sizeof(*job)); |
| 212 | 228 | |
| 213 | 229 | scsi_req_init(sreq); |
| 230 | + | |
| 231 | + sreq->sense = sense; | |
| 214 | 232 | sreq->sense_len = SCSI_SENSE_BUFFERSIZE; |
| 215 | − sreq->sense = kzalloc(sreq->sense_len, gfp); | |
| 216 | − if (!sreq->sense) | |
| 217 | − return -ENOMEM; | |
| 218 | 233 | |
| 219 | 234 | job->req = req; |
| 220 | − job->reply = sreq->sense; | |
| 235 | + job->reply = sense; | |
| 221 | 236 | job->reply_len = sreq->sense_len; |
| 222 | 237 | job->dd_data = job + 1; |
| 223 | − | |
| 224 | − return 0; | |
| 225 | 238 | } |
| 226 | 239 | |
| 227 | 240 | static void bsg_exit_rq(struct request_queue *q, struct request *req) |
| @@ -252,6 +265,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name, · 24 unmodified lines | ||
| 252 | 265 | q->cmd_size = sizeof(struct bsg_job) + dd_job_size; |
| 253 | 266 | q->init_rq_fn = bsg_init_rq; |
| 254 | 267 | q->exit_rq_fn = bsg_exit_rq; |
| 268 | + q->initialize_rq_fn = bsg_initialize_rq; | |
| 255 | 269 | q->request_fn = bsg_request_fn; |
| 256 | 270 | |
| 257 | 271 | ret = blk_init_allocated_queue(q); |
| @@ -112,7 +112,7 @@ ssize_t part_stat_show(struct device *dev, · 111 unmodified lines | ||
| 112 | 112 | struct device_attribute *attr, char *buf) |
| 113 | 113 | { |
| 114 | 114 | struct hd_struct *p = dev_to_part(dev); |
| 115 | − struct request_queue *q = dev_to_disk(dev)->queue; | |
| 115 | + struct request_queue *q = part_to_disk(p)->queue; | |
| 116 | 116 | unsigned int inflight[2]; |
| 117 | 117 | int cpu; |
| 118 | 118 | |
| @@ -619,14 +619,14 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, · 618 unmodified lines | ||
| 619 | 619 | struct af_alg_ctx *ctx = ask->private; |
| 620 | 620 | struct af_alg_tsgl *sgl; |
| 621 | 621 | struct scatterlist *sg; |
| 622 | − unsigned int i, j; | |
| 622 | + unsigned int i, j = 0; | |
| 623 | 623 | |
| 624 | 624 | while (!list_empty(&ctx->tsgl_list)) { |
| 625 | 625 | sgl = list_first_entry(&ctx->tsgl_list, struct af_alg_tsgl, |
| 626 | 626 | list); |
| 627 | 627 | sg = sgl->sg; |
| 628 | 628 | |
| 629 | − for (i = 0, j = 0; i < sgl->cur; i++) { | |
| 629 | + for (i = 0; i < sgl->cur; i++) { | |
| 630 | 630 | size_t plen = min_t(size_t, used, sg[i].length); |
| 631 | 631 | struct page *page = sg_page(sg + i); |
| 632 | 632 | |
| @@ -1133,10 +1133,10 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg) · 1132 unmodified lines | ||
| 1133 | 1133 | { |
| 1134 | 1134 | if (!drbg) |
| 1135 | 1135 | return; |
| 1136 | − kzfree(drbg->V); | |
| 1137 | − drbg->Vbuf = NULL; | |
| 1138 | − kzfree(drbg->C); | |
| 1139 | − drbg->Cbuf = NULL; | |
| 1136 | + kzfree(drbg->Vbuf); | |
| 1137 | + drbg->V = NULL; | |
| 1138 | + kzfree(drbg->Cbuf); | |
| 1139 | + drbg->C = NULL; | |
| 1140 | 1140 | kzfree(drbg->scratchpadbuf); |
| 1141 | 1141 | drbg->scratchpadbuf = NULL; |
| 1142 | 1142 | drbg->reseed_ctr = 0; |
| @@ -66,7 +66,7 @@ void __init acpi_watchdog_init(void) · 65 unmodified lines | ||
| 66 | 66 | for (i = 0; i < wdat->entries; i++) { |
| 67 | 67 | const struct acpi_generic_address *gas; |
| 68 | 68 | struct resource_entry *rentry; |
| 69 | − struct resource res; | |
| 69 | + struct resource res = {}; | |
| 70 | 70 | bool found; |
| 71 | 71 | |
| 72 | 72 | gas = &entries[i].register_region; |
| @@ -743,17 +743,19 @@ static int ghes_proc(struct ghes *ghes) · 742 unmodified lines | ||
| 743 | 743 | } |
| 744 | 744 | ghes_do_proc(ghes, ghes->estatus); |
| 745 | 745 | |
| 746 | +out: | |
| 747 | + ghes_clear_estatus(ghes); | |
| 748 | + | |
| 749 | + if (rc == -ENOENT) | |
| 750 | + return rc; | |
| 751 | + | |
| 746 | 752 | /* |
| 747 | 753 | * GHESv2 type HEST entries introduce support for error acknowledgment, |
| 748 | 754 | * so only acknowledge the error if this support is present. |
| 749 | 755 | */ |
| 750 | − if (is_hest_type_generic_v2(ghes)) { | |
| 751 | − rc = ghes_ack_error(ghes->generic_v2); | |
| 752 | − if (rc) | |
| 753 | − return rc; | |
| 754 | − } | |
| 755 | −out: | |
| 756 | − ghes_clear_estatus(ghes); | |
| 756 | + if (is_hest_type_generic_v2(ghes)) | |
| 757 | + return ghes_ack_error(ghes->generic_v2); | |
| 758 | + | |
| 757 | 759 | return rc; |
| 758 | 760 | } |
| 759 | 761 | |
| @@ -1178,12 +1178,44 @@ dev_put: · 1177 unmodified lines | ||
| 1178 | 1178 | return ret; |
| 1179 | 1179 | } |
| 1180 | 1180 | |
| 1181 | +static bool __init iort_enable_acs(struct acpi_iort_node *iort_node) | |
| 1182 | +{ | |
| 1183 | + if (iort_node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { | |
| 1184 | + struct acpi_iort_node *parent; | |
| 1185 | + struct acpi_iort_id_mapping *map; | |
| 1186 | + int i; | |
| 1187 | + | |
| 1188 | + map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, iort_node, | |
| 1189 | + iort_node->mapping_offset); | |
| 1190 | + | |
| 1191 | + for (i = 0; i < iort_node->mapping_count; i++, map++) { | |
| 1192 | + if (!map->output_reference) | |
| 1193 | + continue; | |
| 1194 | + | |
| 1195 | + parent = ACPI_ADD_PTR(struct acpi_iort_node, | |
| 1196 | + iort_table, map->output_reference); | |
| 1197 | + /* | |
| 1198 | + * If we detect a RC->SMMU mapping, make sure | |
| 1199 | + * we enable ACS on the system. | |
| 1200 | + */ | |
| 1201 | + if ((parent->type == ACPI_IORT_NODE_SMMU) || | |
| 1202 | + (parent->type == ACPI_IORT_NODE_SMMU_V3)) { | |
| 1203 | + pci_request_acs(); | |
| 1204 | + return true; | |
| 1205 | + } | |
| 1206 | + } | |
| 1207 | + } | |
| 1208 | + | |
| 1209 | + return false; | |
| 1210 | +} | |
| 1211 | + | |
| 1181 | 1212 | static void __init iort_init_platform_devices(void) |
| 1182 | 1213 | { |
| 1183 | 1214 | struct acpi_iort_node *iort_node, *iort_end; |
| 1184 | 1215 | struct acpi_table_iort *iort; |
| 1185 | 1216 | struct fwnode_handle *fwnode; |
| 1186 | 1217 | int i, ret; |
| 1218 | + bool acs_enabled = false; | |
| 1187 | 1219 | |
| 1188 | 1220 | /* |
| 1189 | 1221 | * iort_table and iort both point to the start of IORT table, but |
| @@ -1203,6 +1235,9 @@ static void __init iort_init_platform_devices(void) · 13 unmodified lines | ||
| 1203 | 1235 | return; |
| 1204 | 1236 | } |
| 1205 | 1237 | |
| 1238 | + if (!acs_enabled) | |
| 1239 | + acs_enabled = iort_enable_acs(iort_node); | |
| 1240 | + | |
| 1206 | 1241 | if ((iort_node->type == ACPI_IORT_NODE_SMMU) || |
| 1207 | 1242 | (iort_node->type == ACPI_IORT_NODE_SMMU_V3)) { |
| 1208 | 1243 | |
| @@ -908,11 +908,12 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, · 907 unmodified lines | ||
| 908 | 908 | struct fwnode_handle *child) |
| 909 | 909 | { |
| 910 | 910 | const struct acpi_device *adev = to_acpi_device_node(fwnode); |
| 911 | − struct acpi_device *child_adev = NULL; | |
| 912 | 911 | const struct list_head *head; |
| 913 | 912 | struct list_head *next; |
| 914 | 913 | |
| 915 | 914 | if (!child || is_acpi_device_node(child)) { |
| 915 | + struct acpi_device *child_adev; | |
| 916 | + | |
| 916 | 917 | if (adev) |
| 917 | 918 | head = &adev->children; |
| 918 | 919 | else |
| @@ -922,8 +923,8 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, · 3 unmodified lines | ||
| 922 | 923 | goto nondev; |
| 923 | 924 | |
| 924 | 925 | if (child) { |
| 925 | − child_adev = to_acpi_device_node(child); | |
| 926 | − next = child_adev->node.next; | |
| 926 | + adev = to_acpi_device_node(child); | |
| 927 | + next = adev->node.next; | |
| 927 | 928 | if (next == head) { |
| 928 | 929 | child = NULL; |
| 929 | 930 | goto nondev; |
| @@ -941,8 +942,8 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, · 11 unmodified lines | ||
| 941 | 942 | const struct acpi_data_node *data = to_acpi_data_node(fwnode); |
| 942 | 943 | struct acpi_data_node *dn; |
| 943 | 944 | |
| 944 | − if (child_adev) | |
| 945 | − head = &child_adev->data.subnodes; | |
| 945 | + if (adev) | |
| 946 | + head = &adev->data.subnodes; | |
| 946 | 947 | else if (data) |
| 947 | 948 | head = &data->data.subnodes; |
| 948 | 949 | else |
| @@ -1293,3 +1294,16 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, · 344 unmodified lines | ||
| 1293 | 1294 | DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops); |
| 1294 | 1295 | DECLARE_ACPI_FWNODE_OPS(acpi_data_fwnode_ops); |
| 1295 | 1296 | const struct fwnode_operations acpi_static_fwnode_ops; |
| 1297 | + | |
| 1298 | +bool is_acpi_device_node(const struct fwnode_handle *fwnode) | |
| 1299 | +{ | |
| 1300 | + return !IS_ERR_OR_NULL(fwnode) && | |
| 1301 | + fwnode->ops == &acpi_device_fwnode_ops; | |
| 1302 | +} | |
| 1303 | +EXPORT_SYMBOL(is_acpi_device_node); | |
| 1304 | + | |
| 1305 | +bool is_acpi_data_node(const struct fwnode_handle *fwnode) | |
| 1306 | +{ | |
| 1307 | + return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &acpi_data_fwnode_ops; | |
| 1308 | +} | |
| 1309 | +EXPORT_SYMBOL(is_acpi_data_node); | |
| @@ -2217,7 +2217,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, · 2216 unmodified lines | ||
| 2217 | 2217 | debug_id, (u64)fda->num_fds); |
| 2218 | 2218 | continue; |
| 2219 | 2219 | } |
| 2220 | − fd_array = (u32 *)(parent_buffer + fda->parent_offset); | |
| 2220 | + fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset); | |
| 2221 | 2221 | for (fd_index = 0; fd_index < fda->num_fds; fd_index++) |
| 2222 | 2222 | task_close_fd(proc, fd_array[fd_index]); |
| 2223 | 2223 | } break; |
| @@ -2326,7 +2326,6 @@ static int binder_translate_handle(struct flat_binder_object *fp, · 102 unmodified lines | ||
| 2326 | 2326 | (u64)node->ptr); |
| 2327 | 2327 | binder_node_unlock(node); |
| 2328 | 2328 | } else { |
| 2329 | − int ret; | |
| 2330 | 2329 | struct binder_ref_data dest_rdata; |
| 2331 | 2330 | |
| 2332 | 2331 | binder_node_unlock(node); |
| @@ -2442,7 +2441,7 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda, · 109 unmodified lines | ||
| 2442 | 2441 | */ |
| 2443 | 2442 | parent_buffer = parent->buffer - |
| 2444 | 2443 | binder_alloc_get_user_buffer_offset(&target_proc->alloc); |
| 2445 | − fd_array = (u32 *)(parent_buffer + fda->parent_offset); | |
| 2444 | + fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset); | |
| 2446 | 2445 | if (!IS_ALIGNED((unsigned long)fd_array, sizeof(u32))) { |
| 2447 | 2446 | binder_user_error("%d:%d parent offset not aligned correctly.\n", |
| 2448 | 2447 | proc->pid, thread->pid); |
| @@ -2508,7 +2507,7 @@ static int binder_fixup_parent(struct binder_transaction *t, · 59 unmodified lines | ||
| 2508 | 2507 | proc->pid, thread->pid); |
| 2509 | 2508 | return -EINVAL; |
| 2510 | 2509 | } |
| 2511 | − parent_buffer = (u8 *)(parent->buffer - | |
| 2510 | + parent_buffer = (u8 *)((uintptr_t)parent->buffer - | |
| 2512 | 2511 | binder_alloc_get_user_buffer_offset( |
| 2513 | 2512 | &target_proc->alloc)); |
| 2514 | 2513 | *(binder_uintptr_t *)(parent_buffer + bp->parent_offset) = bp->buffer; |
| @@ -3083,6 +3082,7 @@ static void binder_transaction(struct binder_proc *proc, · 568 unmodified lines | ||
| 3083 | 3082 | err_dead_proc_or_thread: |
| 3084 | 3083 | return_error = BR_DEAD_REPLY; |
| 3085 | 3084 | return_error_line = __LINE__; |
| 3085 | + binder_dequeue_work(proc, tcomplete); | |
| 3086 | 3086 | err_translate_failed: |
| 3087 | 3087 | err_bad_object_type: |
| 3088 | 3088 | err_bad_offset: |
| @@ -913,6 +913,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, · 912 unmodified lines | ||
| 913 | 913 | struct binder_alloc *alloc; |
| 914 | 914 | uintptr_t page_addr; |
| 915 | 915 | size_t index; |
| 916 | + struct vm_area_struct *vma; | |
| 916 | 917 | |
| 917 | 918 | alloc = page->alloc; |
| 918 | 919 | if (!mutex_trylock(&alloc->mutex)) |
| @@ -923,16 +924,22 @@ enum lru_status binder_alloc_free_page(struct list_head *item, · 4 unmodified lines | ||
| 923 | 924 | |
| 924 | 925 | index = page - alloc->pages; |
| 925 | 926 | page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; |
| 926 | − if (alloc->vma) { | |
| 927 | + vma = alloc->vma; | |
| 928 | + if (vma) { | |
| 927 | 929 | mm = get_task_mm(alloc->tsk); |
| 928 | 930 | if (!mm) |
| 929 | 931 | goto err_get_task_mm_failed; |
| 930 | 932 | if (!down_write_trylock(&mm->mmap_sem)) |
| 931 | 933 | goto err_down_write_mmap_sem_failed; |
| 934 | + } | |
| 935 | + | |
| 936 | + list_lru_isolate(lru, item); | |
| 937 | + spin_unlock(lock); | |
| 932 | 938 | |
| 939 | + if (vma) { | |
| 933 | 940 | trace_binder_unmap_user_start(alloc, index); |
| 934 | 941 | |
| 935 | − zap_page_range(alloc->vma, | |
| 942 | + zap_page_range(vma, | |
| 936 | 943 | page_addr + alloc->user_buffer_offset, |
| 937 | 944 | PAGE_SIZE); |
| 938 | 945 | |
| @@ -950,13 +957,12 @@ enum lru_status binder_alloc_free_page(struct list_head *item, · 11 unmodified lines | ||
| 950 | 957 | |
| 951 | 958 | trace_binder_unmap_kernel_end(alloc, index); |
| 952 | 959 | |
| 953 | − list_lru_isolate(lru, item); | |
| 954 | − | |
| 960 | + spin_lock(lock); | |
| 955 | 961 | mutex_unlock(&alloc->mutex); |
| 956 | − return LRU_REMOVED; | |
| 962 | + return LRU_REMOVED_RETRY; | |
| 957 | 963 | |
| 958 | 964 | err_down_write_mmap_sem_failed: |
| 959 | − mmput(mm); | |
| 965 | + mmput_async(mm); | |
| 960 | 966 | err_get_task_mm_failed: |
| 961 | 967 | err_page_already_freed: |
| 962 | 968 | mutex_unlock(&alloc->mutex); |
| @@ -621,8 +621,11 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev, · 620 unmodified lines | ||
| 621 | 621 | static int ahci_pci_reset_controller(struct ata_host *host) |
| 622 | 622 | { |
| 623 | 623 | struct pci_dev *pdev = to_pci_dev(host->dev); |
| 624 | + int rc; | |
| 624 | 625 | |
| 625 | − ahci_reset_controller(host); | |
| 626 | + rc = ahci_reset_controller(host); | |
| 627 | + if (rc) | |
| 628 | + return rc; | |
| 626 | 629 | |
| 627 | 630 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { |
| 628 | 631 | struct ahci_host_priv *hpriv = host->private_data; |
| @@ -492,6 +492,7 @@ static const struct ich_laptop ich_laptop[] = { · 491 unmodified lines | ||
| 492 | 492 | { 0x27DF, 0x152D, 0x0778 }, /* ICH7 on unknown Intel */ |
| 493 | 493 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ |
| 494 | 494 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ |
| 495 | + { 0x24CA, 0x10CF, 0x11AB }, /* ICH4M on Fujitsu-Siemens Lifebook S6120 */ | |
| 495 | 496 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ |
| 496 | 497 | { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ |
| 497 | 498 | { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */ |
| @@ -3234,19 +3234,19 @@ static const struct ata_timing ata_timing[] = { · 3233 unmodified lines | ||
| 3234 | 3234 | }; |
| 3235 | 3235 | |
| 3236 | 3236 | #define ENOUGH(v, unit) (((v)-1)/(unit)+1) |
| 3237 | −#define EZ(v, unit) ((v)?ENOUGH(v, unit):0) | |
| 3237 | +#define EZ(v, unit) ((v)?ENOUGH(((v) * 1000), unit):0) | |
| 3238 | 3238 | |
| 3239 | 3239 | static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) |
| 3240 | 3240 | { |
| 3241 | − q->setup = EZ(t->setup * 1000, T); | |
| 3242 | − q->act8b = EZ(t->act8b * 1000, T); | |
| 3243 | − q->rec8b = EZ(t->rec8b * 1000, T); | |
| 3244 | − q->cyc8b = EZ(t->cyc8b * 1000, T); | |
| 3245 | − q->active = EZ(t->active * 1000, T); | |
| 3246 | − q->recover = EZ(t->recover * 1000, T); | |
| 3247 | − q->dmack_hold = EZ(t->dmack_hold * 1000, T); | |
| 3248 | − q->cycle = EZ(t->cycle * 1000, T); | |
| 3249 | − q->udma = EZ(t->udma * 1000, UT); | |
| 3241 | + q->setup = EZ(t->setup, T); | |
| 3242 | + q->act8b = EZ(t->act8b, T); | |
| 3243 | + q->rec8b = EZ(t->rec8b, T); | |
| 3244 | + q->cyc8b = EZ(t->cyc8b, T); | |
| 3245 | + q->active = EZ(t->active, T); | |
| 3246 | + q->recover = EZ(t->recover, T); | |
| 3247 | + q->dmack_hold = EZ(t->dmack_hold, T); | |
| 3248 | + q->cycle = EZ(t->cycle, T); | |
| 3249 | + q->udma = EZ(t->udma, UT); | |
| 3250 | 3250 | } |
| 3251 | 3251 | |
| 3252 | 3252 | void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, |
| @@ -647,18 +647,25 @@ static ssize_t charlcd_write(struct file *file, const char __user *buf, · 646 unmodified lines | ||
| 647 | 647 | static int charlcd_open(struct inode *inode, struct file *file) |
| 648 | 648 | { |
| 649 | 649 | struct charlcd_priv *priv = to_priv(the_charlcd); |
| 650 | + int ret; | |
| 650 | 651 | |
| 652 | + ret = -EBUSY; | |
| 651 | 653 | if (!atomic_dec_and_test(&charlcd_available)) |
| 652 | − return -EBUSY; /* open only once at a time */ | |
| 654 | + goto fail; /* open only once at a time */ | |
| 653 | 655 | |
| 656 | + ret = -EPERM; | |
| 654 | 657 | if (file->f_mode & FMODE_READ) /* device is write-only */ |
| 655 | − return -EPERM; | |
| 658 | + goto fail; | |
| 656 | 659 | |
| 657 | 660 | if (priv->must_clear) { |
| 658 | 661 | charlcd_clear_display(&priv->lcd); |
| 659 | 662 | priv->must_clear = false; |
| 660 | 663 | } |
| 661 | 664 | return nonseekable_open(inode, file); |
| 665 | + | |
| 666 | + fail: | |
| 667 | + atomic_inc(&charlcd_available); | |
| 668 | + return ret; | |
| 662 | 669 | } |
| 663 | 670 | |
| 664 | 671 | static int charlcd_release(struct inode *inode, struct file *file) |
| @@ -1105,14 +1105,21 @@ static ssize_t keypad_read(struct file *file, · 1104 unmodified lines | ||
| 1105 | 1105 | |
| 1106 | 1106 | static int keypad_open(struct inode *inode, struct file *file) |
| 1107 | 1107 | { |
| 1108 | + int ret; | |
| 1109 | + | |
| 1110 | + ret = -EBUSY; | |
| 1108 | 1111 | if (!atomic_dec_and_test(&keypad_available)) |
| 1109 | − return -EBUSY; /* open only once at a time */ | |
| 1112 | + goto fail; /* open only once at a time */ | |
| 1110 | 1113 | |
| 1114 | + ret = -EPERM; | |
| 1111 | 1115 | if (file->f_mode & FMODE_WRITE) /* device is read-only */ |
| 1112 | − return -EPERM; | |
| 1116 | + goto fail; | |
| 1113 | 1117 | |
| 1114 | 1118 | keypad_buflen = 0; /* flush the buffer on opening */ |
| 1115 | 1119 | return 0; |
| 1120 | + fail: | |
| 1121 | + atomic_inc(&keypad_available); | |
| 1122 | + return ret; | |
| 1116 | 1123 | } |
| 1117 | 1124 | |
| 1118 | 1125 | static int keypad_release(struct inode *inode, struct file *file) |
| @@ -166,11 +166,11 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu) · 165 unmodified lines | ||
| 166 | 166 | } |
| 167 | 167 | |
| 168 | 168 | #ifdef CONFIG_CPU_FREQ |
| 169 | −static cpumask_var_t cpus_to_visit; | |
| 170 | −static void parsing_done_workfn(struct work_struct *work); | |
| 171 | −static DECLARE_WORK(parsing_done_work, parsing_done_workfn); | |
| 169 | +static cpumask_var_t cpus_to_visit __initdata; | |
| 170 | +static void __init parsing_done_workfn(struct work_struct *work); | |
| 171 | +static __initdata DECLARE_WORK(parsing_done_work, parsing_done_workfn); | |
| 172 | 172 | |
| 173 | −static int | |
| 173 | +static int __init | |
| 174 | 174 | init_cpu_capacity_callback(struct notifier_block *nb, |
| 175 | 175 | unsigned long val, |
| 176 | 176 | void *data) |
| @@ -206,7 +206,7 @@ init_cpu_capacity_callback(struct notifier_block *nb, · 29 unmodified lines | ||
| 206 | 206 | return 0; |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | −static struct notifier_block init_cpu_capacity_notifier = { | |
| 209 | +static struct notifier_block init_cpu_capacity_notifier __initdata = { | |
| 210 | 210 | .notifier_call = init_cpu_capacity_callback, |
| 211 | 211 | }; |
| 212 | 212 | |
| @@ -232,7 +232,7 @@ static int __init register_cpufreq_notifier(void) · 19 unmodified lines | ||
| 232 | 232 | } |
| 233 | 233 | core_initcall(register_cpufreq_notifier); |
| 234 | 234 | |
| 235 | −static void parsing_done_workfn(struct work_struct *work) | |
| 235 | +static void __init parsing_done_workfn(struct work_struct *work) | |
| 236 | 236 | { |
| 237 | 237 | cpufreq_unregister_notifier(&init_cpu_capacity_notifier, |
| 238 | 238 | CPUFREQ_POLICY_NOTIFIER); |
| @@ -348,16 +348,15 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) · 347 unmodified lines | ||
| 348 | 348 | struct dma_coherent_mem *mem = rmem->priv; |
| 349 | 349 | int ret; |
| 350 | 350 | |
| 351 | − if (!mem) | |
| 352 | − return -ENODEV; | |
| 353 | − | |
| 354 | − ret = dma_init_coherent_memory(rmem->base, rmem->base, rmem->size, | |
| 355 | − DMA_MEMORY_EXCLUSIVE, &mem); | |
| 356 | − | |
| 357 | − if (ret) { | |
| 358 | − pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n", | |
| 359 | − &rmem->base, (unsigned long)rmem->size / SZ_1M); | |
| 360 | − return ret; | |
| 351 | + if (!mem) { | |
| 352 | + ret = dma_init_coherent_memory(rmem->base, rmem->base, | |
| 353 | + rmem->size, | |
| 354 | + DMA_MEMORY_EXCLUSIVE, &mem); | |
| 355 | + if (ret) { | |
| 356 | + pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n", | |
| 357 | + &rmem->base, (unsigned long)rmem->size / SZ_1M); | |
| 358 | + return ret; | |
| 359 | + } | |
| 361 | 360 | } |
| 362 | 361 | mem->use_dev_dma_pfn_offset = true; |
| 363 | 362 | rmem->priv = mem; |
| @@ -868,7 +868,8 @@ static ssize_t driver_override_store(struct device *dev, · 867 unmodified lines | ||
| 868 | 868 | struct platform_device *pdev = to_platform_device(dev); |
| 869 | 869 | char *driver_override, *old, *cp; |
| 870 | 870 | |
| 871 | − if (count > PATH_MAX) | |
| 871 | + /* We need to keep extra room for a newline */ | |
| 872 | + if (count >= (PAGE_SIZE - 1)) | |
| 872 | 873 | return -EINVAL; |
| 873 | 874 | |
| 874 | 875 | driver_override = kstrndup(buf, count, GFP_KERNEL); |
| @@ -1860,10 +1860,13 @@ void device_pm_check_callbacks(struct device *dev) · 1859 unmodified lines | ||
| 1860 | 1860 | { |
| 1861 | 1861 | spin_lock_irq(&dev->power.lock); |
| 1862 | 1862 | dev->power.no_pm_callbacks = |
| 1863 | − (!dev->bus || pm_ops_is_empty(dev->bus->pm)) && | |
| 1864 | − (!dev->class || pm_ops_is_empty(dev->class->pm)) && | |
| 1863 | + (!dev->bus || (pm_ops_is_empty(dev->bus->pm) && | |
| 1864 | + !dev->bus->suspend && !dev->bus->resume)) && | |
| 1865 | + (!dev->class || (pm_ops_is_empty(dev->class->pm) && | |
| 1866 | + !dev->class->suspend && !dev->class->resume)) && | |
| 1865 | 1867 | (!dev->type || pm_ops_is_empty(dev->type->pm)) && |
| 1866 | 1868 | (!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) && |
| 1867 | − (!dev->driver || pm_ops_is_empty(dev->driver->pm)); | |
| 1869 | + (!dev->driver || (pm_ops_is_empty(dev->driver->pm) && | |
| 1870 | + !dev->driver->suspend && !dev->driver->resume)); | |
| 1868 | 1871 | spin_unlock_irq(&dev->power.lock); |
| 1869 | 1872 | } |
| @@ -1581,6 +1581,9 @@ static int _opp_set_availability(struct device *dev, unsigned long freq, · 1580 unmodified lines | ||
| 1581 | 1581 | |
| 1582 | 1582 | opp->available = availability_req; |
| 1583 | 1583 | |
| 1584 | + dev_pm_opp_get(opp); | |
| 1585 | + mutex_unlock(&opp_table->lock); | |
| 1586 | + | |
| 1584 | 1587 | /* Notify the change of the OPP availability */ |
| 1585 | 1588 | if (availability_req) |
| 1586 | 1589 | blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ENABLE, |
| @@ -1589,8 +1592,12 @@ static int _opp_set_availability(struct device *dev, unsigned long freq, · 2 unmodified lines | ||
| 1589 | 1592 | blocking_notifier_call_chain(&opp_table->head, |
| 1590 | 1593 | OPP_EVENT_DISABLE, opp); |
| 1591 | 1594 | |
| 1595 | + dev_pm_opp_put(opp); | |
| 1596 | + goto put_table; | |
| 1597 | + | |
| 1592 | 1598 | unlock: |
| 1593 | 1599 | mutex_unlock(&opp_table->lock); |
| 1600 | +put_table: | |
| 1594 | 1601 | dev_pm_opp_put_opp_table(opp_table); |
| 1595 | 1602 | return r; |
| 1596 | 1603 | } |
| @@ -277,11 +277,11 @@ void dev_pm_qos_constraints_destroy(struct device *dev) · 276 unmodified lines | ||
| 277 | 277 | mutex_unlock(&dev_pm_qos_sysfs_mtx); |
| 278 | 278 | } |
| 279 | 279 | |
| 280 | −static bool dev_pm_qos_invalid_request(struct device *dev, | |
| 281 | − struct dev_pm_qos_request *req) | |
| 280 | +static bool dev_pm_qos_invalid_req_type(struct device *dev, | |
| 281 | + enum dev_pm_qos_req_type type) | |
| 282 | 282 | { |
| 283 | − return !req || (req->type == DEV_PM_QOS_LATENCY_TOLERANCE | |
| 284 | − && !dev->power.set_latency_tolerance); | |
| 283 | + return type == DEV_PM_QOS_LATENCY_TOLERANCE && | |
| 284 | + !dev->power.set_latency_tolerance; | |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | 287 | static int __dev_pm_qos_add_request(struct device *dev, |
| @@ -290,7 +290,7 @@ static int __dev_pm_qos_add_request(struct device *dev, · 2 unmodified lines | ||
| 290 | 290 | { |
| 291 | 291 | int ret = 0; |
| 292 | 292 | |
| 293 | − if (!dev || dev_pm_qos_invalid_request(dev, req)) | |
| 293 | + if (!dev || !req || dev_pm_qos_invalid_req_type(dev, type)) | |
| 294 | 294 | return -EINVAL; |
| 295 | 295 | |
| 296 | 296 | if (WARN(dev_pm_qos_request_active(req), |
| @@ -17,7 +17,7 @@ if BLK_DEV · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | config BLK_DEV_NULL_BLK |
| 19 | 19 | tristate "Null test block driver" |
| 20 | − depends on CONFIGFS_FS | |
| 20 | + select CONFIGFS_FS | |
| 21 | 21 | |
| 22 | 22 | config BLK_DEV_FD |
| 23 | 23 | tristate "Normal floppy disk support" |
| @@ -342,7 +342,7 @@ static long __brd_direct_access(struct brd_device *brd, pgoff_t pgoff, · 341 unmodified lines | ||
| 342 | 342 | |
| 343 | 343 | if (!brd) |
| 344 | 344 | return -ENODEV; |
| 345 | − page = brd_insert_page(brd, PFN_PHYS(pgoff) / 512); | |
| 345 | + page = brd_insert_page(brd, (sector_t)pgoff << PAGE_SECTORS_SHIFT); | |
| 346 | 346 | if (!page) |
| 347 | 347 | return -ENOSPC; |
| 348 | 348 | *kaddr = page_address(page); |
| @@ -67,10 +67,8 @@ struct loop_device { · 66 unmodified lines | ||
| 67 | 67 | struct loop_cmd { |
| 68 | 68 | struct kthread_work work; |
| 69 | 69 | struct request *rq; |
| 70 | − union { | |
| 71 | − bool use_aio; /* use AIO interface to handle I/O */ | |
| 72 | − atomic_t ref; /* only for aio */ | |
| 73 | − }; | |
| 70 | + bool use_aio; /* use AIO interface to handle I/O */ | |
| 71 | + atomic_t ref; /* only for aio */ | |
| 74 | 72 | long ret; |
| 75 | 73 | struct kiocb iocb; |
| 76 | 74 | struct bio_vec *bvec; |
| @@ -820,9 +820,13 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx, · 819 unmodified lines | ||
| 820 | 820 | * appropriate. |
| 821 | 821 | */ |
| 822 | 822 | ret = nbd_handle_cmd(cmd, hctx->queue_num); |
| 823 | + if (ret < 0) | |
| 824 | + ret = BLK_STS_IOERR; | |
| 825 | + else if (!ret) | |
| 826 | + ret = BLK_STS_OK; | |
| 823 | 827 | complete(&cmd->send_complete); |
| 824 | 828 | |
| 825 | − return ret < 0 ? BLK_STS_IOERR : BLK_STS_OK; | |
| 829 | + return ret; | |
| 826 | 830 | } |
| 827 | 831 | |
| 828 | 832 | static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, |
| @@ -1194,6 +1198,12 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, · 365 unmodified lines | ||
| 1194 | 1198 | if (!capable(CAP_SYS_ADMIN)) |
| 1195 | 1199 | return -EPERM; |
| 1196 | 1200 | |
| 1201 | + /* The block layer will pass back some non-nbd ioctls in case we have | |
| 1202 | + * special handling for them, but we don't so just return an error. | |
| 1203 | + */ | |
| 1204 | + if (_IOC_TYPE(cmd) != 0xab) | |
| 1205 | + return -EINVAL; | |
| 1206 | + | |
| 1197 | 1207 | mutex_lock(&nbd->config_lock); |
| 1198 | 1208 | |
| 1199 | 1209 | /* Don't allow ioctl operations on a nbd device that was created with |
| @@ -766,27 +766,6 @@ static void zram_slot_unlock(struct zram *zram, u32 index) · 765 unmodified lines | ||
| 766 | 766 | bit_spin_unlock(ZRAM_ACCESS, &zram->table[index].value); |
| 767 | 767 | } |
| 768 | 768 | |
| 769 | −static bool zram_same_page_read(struct zram *zram, u32 index, | |
| 770 | − struct page *page, | |
| 771 | − unsigned int offset, unsigned int len) | |
| 772 | −{ | |
| 773 | − zram_slot_lock(zram, index); | |
| 774 | − if (unlikely(!zram_get_handle(zram, index) || | |
| 775 | − zram_test_flag(zram, index, ZRAM_SAME))) { | |
| 776 | − void *mem; | |
| 777 | − | |
| 778 | − zram_slot_unlock(zram, index); | |
| 779 | − mem = kmap_atomic(page); | |
| 780 | − zram_fill_page(mem + offset, len, | |
| 781 | − zram_get_element(zram, index)); | |
| 782 | − kunmap_atomic(mem); | |
| 783 | − return true; | |
| 784 | − } | |
| 785 | − zram_slot_unlock(zram, index); | |
| 786 | − | |
| 787 | − return false; | |
| 788 | −} | |
| 789 | − | |
| 790 | 769 | static void zram_meta_free(struct zram *zram, u64 disksize) |
| 791 | 770 | { |
| 792 | 771 | size_t num_pages = disksize >> PAGE_SHIFT; |
| @@ -884,11 +863,20 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, · 91 unmodified lines | ||
| 884 | 863 | zram_slot_unlock(zram, index); |
| 885 | 864 | } |
| 886 | 865 | |
| 887 | − if (zram_same_page_read(zram, index, page, 0, PAGE_SIZE)) | |
| 888 | − return 0; | |
| 889 | − | |
| 890 | 866 | zram_slot_lock(zram, index); |
| 891 | 867 | handle = zram_get_handle(zram, index); |
| 868 | + if (!handle || zram_test_flag(zram, index, ZRAM_SAME)) { | |
| 869 | + unsigned long value; | |
| 870 | + void *mem; | |
| 871 | + | |
| 872 | + value = handle ? zram_get_element(zram, index) : 0; | |
| 873 | + mem = kmap_atomic(page); | |
| 874 | + zram_fill_page(mem, PAGE_SIZE, value); | |
| 875 | + kunmap_atomic(mem); | |
| 876 | + zram_slot_unlock(zram, index); | |
| 877 | + return 0; | |
| 878 | + } | |
| 879 | + | |
| 892 | 880 | size = zram_get_obj_size(zram, index); |
| 893 | 881 | |
| 894 | 882 | src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); |
| @@ -455,7 +455,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, · 454 unmodified lines | ||
| 455 | 455 | goto out; |
| 456 | 456 | } |
| 457 | 457 | |
| 458 | − msleep(TPM_TIMEOUT); /* CHECK */ | |
| 458 | + tpm_msleep(TPM_TIMEOUT); | |
| 459 | 459 | rmb(); |
| 460 | 460 | } while (time_before(jiffies, stop)); |
| 461 | 461 | |
| @@ -970,7 +970,7 @@ int tpm_do_selftest(struct tpm_chip *chip) · 508 unmodified lines | ||
| 970 | 970 | dev_info( |
| 971 | 971 | &chip->dev, HW_ERR |
| 972 | 972 | "TPM command timed out during continue self test"); |
| 973 | − msleep(delay_msec); | |
| 973 | + tpm_msleep(delay_msec); | |
| 974 | 974 | continue; |
| 975 | 975 | } |
| 976 | 976 | |
| @@ -985,7 +985,7 @@ int tpm_do_selftest(struct tpm_chip *chip) · 8 unmodified lines | ||
| 985 | 985 | } |
| 986 | 986 | if (rc != TPM_WARN_DOING_SELFTEST) |
| 987 | 987 | return rc; |
| 988 | − msleep(delay_msec); | |
| 988 | + tpm_msleep(delay_msec); | |
| 989 | 989 | } while (--loops > 0); |
| 990 | 990 | |
| 991 | 991 | return rc; |
| @@ -1085,7 +1085,7 @@ again: · 93 unmodified lines | ||
| 1085 | 1085 | } |
| 1086 | 1086 | } else { |
| 1087 | 1087 | do { |
| 1088 | − msleep(TPM_TIMEOUT); | |
| 1088 | + tpm_msleep(TPM_TIMEOUT); | |
| 1089 | 1089 | status = chip->ops->status(chip); |
| 1090 | 1090 | if ((status & mask) == mask) |
| 1091 | 1091 | return 0; |
| @@ -1150,7 +1150,7 @@ int tpm_pm_suspend(struct device *dev) · 58 unmodified lines | ||
| 1150 | 1150 | */ |
| 1151 | 1151 | if (rc != TPM_WARN_RETRY) |
| 1152 | 1152 | break; |
| 1153 | − msleep(TPM_TIMEOUT_RETRY); | |
| 1153 | + tpm_msleep(TPM_TIMEOUT_RETRY); | |
| 1154 | 1154 | } |
| 1155 | 1155 | |
| 1156 | 1156 | if (rc) |
| @@ -50,7 +50,8 @@ enum tpm_const { · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | enum tpm_timeout { |
| 52 | 52 | TPM_TIMEOUT = 5, /* msecs */ |
| 53 | − TPM_TIMEOUT_RETRY = 100 /* msecs */ | |
| 53 | + TPM_TIMEOUT_RETRY = 100, /* msecs */ | |
| 54 | + TPM_TIMEOUT_RANGE_US = 300 /* usecs */ | |
| 54 | 55 | }; |
| 55 | 56 | |
| 56 | 57 | /* TPM addresses */ |
| @@ -527,6 +528,12 @@ int tpm_pm_resume(struct device *dev); · 470 unmodified lines | ||
| 527 | 528 | int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, |
| 528 | 529 | wait_queue_head_t *queue, bool check_cancel); |
| 529 | 530 | |
| 531 | +static inline void tpm_msleep(unsigned int delay_msec) | |
| 532 | +{ | |
| 533 | + usleep_range(delay_msec * 1000, | |
| 534 | + (delay_msec * 1000) + TPM_TIMEOUT_RANGE_US); | |
| 535 | +}; | |
| 536 | + | |
| 530 | 537 | struct tpm_chip *tpm_chip_find_get(int chip_num); |
| 531 | 538 | __must_check int tpm_try_get_ops(struct tpm_chip *chip); |
| 532 | 539 | void tpm_put_ops(struct tpm_chip *chip); |
| @@ -899,7 +899,7 @@ static int tpm2_do_selftest(struct tpm_chip *chip) · 898 unmodified lines | ||
| 899 | 899 | if (rc != TPM2_RC_TESTING) |
| 900 | 900 | break; |
| 901 | 901 | |
| 902 | − msleep(delay_msec); | |
| 902 | + tpm_msleep(delay_msec); | |
| 903 | 903 | } |
| 904 | 904 | |
| 905 | 905 | return rc; |
| @@ -665,7 +665,7 @@ static const struct dev_pm_ops crb_pm = { · 664 unmodified lines | ||
| 665 | 665 | SET_RUNTIME_PM_OPS(crb_pm_runtime_suspend, crb_pm_runtime_resume, NULL) |
| 666 | 666 | }; |
| 667 | 667 | |
| 668 | −static struct acpi_device_id crb_device_ids[] = { | |
| 668 | +static const struct acpi_device_id crb_device_ids[] = { | |
| 669 | 669 | {"MSFT0101", 0}, |
| 670 | 670 | {"", 0}, |
| 671 | 671 | }; |
| @@ -32,26 +32,70 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | static const char tpm_ibmvtpm_driver_name[] = "tpm_ibmvtpm"; |
| 34 | 34 | |
| 35 | −static struct vio_device_id tpm_ibmvtpm_device_table[] = { | |
| 35 | +static const struct vio_device_id tpm_ibmvtpm_device_table[] = { | |
| 36 | 36 | { "IBM,vtpm", "IBM,vtpm"}, |
| 37 | 37 | { "", "" } |
| 38 | 38 | }; |
| 39 | 39 | MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table); |
| 40 | 40 | |
| 41 | 41 | /** |
| 42 | + * | |
| 43 | + * ibmvtpm_send_crq_word - Send a CRQ request | |
| 44 | + * @vdev: vio device struct | |
| 45 | + * @w1: pre-constructed first word of tpm crq (second word is reserved) | |
| 46 | + * | |
| 47 | + * Return: | |
| 48 | + * 0 - Success | |
| 49 | + * Non-zero - Failure | |
| 50 | + */ | |
| 51 | +static int ibmvtpm_send_crq_word(struct vio_dev *vdev, u64 w1) | |
| 52 | +{ | |
| 53 | + return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, w1, 0); | |
| 54 | +} | |
| 55 | + | |
| 56 | +/** | |
| 57 | + * | |
| 42 | 58 | * ibmvtpm_send_crq - Send a CRQ request |
| 43 | 59 | * |
| 44 | 60 | * @vdev: vio device struct |
| 45 | − * @w1: first word | |
| 46 | − * @w2: second word | |
| 61 | + * @valid: Valid field | |
| 62 | + * @msg: Type field | |
| 63 | + * @len: Length field | |
| 64 | + * @data: Data field | |
| 65 | + * | |
| 66 | + * The ibmvtpm crq is defined as follows: | |
| 67 | + * | |
| 68 | + * Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
| 69 | + * ----------------------------------------------------------------------- | |
| 70 | + * Word0 | Valid | Type | Length | Data | |
| 71 | + * ----------------------------------------------------------------------- | |
| 72 | + * Word1 | Reserved | |
| 73 | + * ----------------------------------------------------------------------- | |
| 74 | + * | |
| 75 | + * Which matches the following structure (on bigendian host): | |
| 76 | + * | |
| 77 | + * struct ibmvtpm_crq { | |
| 78 | + * u8 valid; | |
| 79 | + * u8 msg; | |
| 80 | + * __be16 len; | |
| 81 | + * __be32 data; | |
| 82 | + * __be64 reserved; | |
| 83 | + * } __attribute__((packed, aligned(8))); | |
| 84 | + * | |
| 85 | + * However, the value is passed in a register so just compute the numeric value | |
| 86 | + * to load into the register avoiding byteswap altogether. Endian only affects | |
| 87 | + * memory loads and stores - registers are internally represented the same. | |
| 47 | 88 | * |
| 48 | 89 | * Return: |
| 49 | − * 0 -Sucess | |
| 90 | + * 0 (H_SUCCESS) - Success | |
| 50 | 91 | * Non-zero - Failure |
| 51 | 92 | */ |
| 52 | −static int ibmvtpm_send_crq(struct vio_dev *vdev, u64 w1, u64 w2) | |
| 93 | +static int ibmvtpm_send_crq(struct vio_dev *vdev, | |
| 94 | + u8 valid, u8 msg, u16 len, u32 data) | |
| 53 | 95 | { |
| 54 | − return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, w1, w2); | |
| 96 | + u64 w1 = ((u64)valid << 56) | ((u64)msg << 48) | ((u64)len << 32) | | |
| 97 | + (u64)data; | |
| 98 | + return ibmvtpm_send_crq_word(vdev, w1); | |
| 55 | 99 | } |
| 56 | 100 | |
| 57 | 101 | /** |
| @@ -109,8 +153,6 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) · 51 unmodified lines | ||
| 109 | 153 | static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) |
| 110 | 154 | { |
| 111 | 155 | struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); |
| 112 | − struct ibmvtpm_crq crq; | |
| 113 | − __be64 *word = (__be64 *)&crq; | |
| 114 | 156 | int rc, sig; |
| 115 | 157 | |
| 116 | 158 | if (!ibmvtpm->rtce_buf) { |
| @@ -137,10 +179,6 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) · 20 unmodified lines | ||
| 137 | 179 | spin_lock(&ibmvtpm->rtce_lock); |
| 138 | 180 | ibmvtpm->res_len = 0; |
| 139 | 181 | memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count); |
| 140 | − crq.valid = (u8)IBMVTPM_VALID_CMD; | |
| 141 | − crq.msg = (u8)VTPM_TPM_COMMAND; | |
| 142 | − crq.len = cpu_to_be16(count); | |
| 143 | − crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle); | |
| 144 | 182 | |
| 145 | 183 | /* |
| 146 | 184 | * set the processing flag before the Hcall, since we may get the |
| @@ -148,8 +186,9 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) · 1 unmodified line | ||
| 148 | 186 | */ |
| 149 | 187 | ibmvtpm->tpm_processing_cmd = true; |
| 150 | 188 | |
| 151 | − rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]), | |
| 152 | − be64_to_cpu(word[1])); | |
| 189 | + rc = ibmvtpm_send_crq(ibmvtpm->vdev, | |
| 190 | + IBMVTPM_VALID_CMD, VTPM_TPM_COMMAND, | |
| 191 | + count, ibmvtpm->rtce_dma_handle); | |
| 153 | 192 | if (rc != H_SUCCESS) { |
| 154 | 193 | dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); |
| 155 | 194 | rc = 0; |
| @@ -182,15 +221,10 @@ static u8 tpm_ibmvtpm_status(struct tpm_chip *chip) · 26 unmodified lines | ||
| 182 | 221 | */ |
| 183 | 222 | static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm) |
| 184 | 223 | { |
| 185 | − struct ibmvtpm_crq crq; | |
| 186 | − u64 *buf = (u64 *) &crq; | |
| 187 | 224 | int rc; |
| 188 | 225 | |
| 189 | − crq.valid = (u8)IBMVTPM_VALID_CMD; | |
| 190 | − crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE; | |
| 191 | − | |
| 192 | − rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), | |
| 193 | − cpu_to_be64(buf[1])); | |
| 226 | + rc = ibmvtpm_send_crq(ibmvtpm->vdev, | |
| 227 | + IBMVTPM_VALID_CMD, VTPM_GET_RTCE_BUFFER_SIZE, 0, 0); | |
| 194 | 228 | if (rc != H_SUCCESS) |
| 195 | 229 | dev_err(ibmvtpm->dev, |
| 196 | 230 | "ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc); |
| @@ -210,15 +244,10 @@ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm) · 13 unmodified lines | ||
| 210 | 244 | */ |
| 211 | 245 | static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm) |
| 212 | 246 | { |
| 213 | − struct ibmvtpm_crq crq; | |
| 214 | − u64 *buf = (u64 *) &crq; | |
| 215 | 247 | int rc; |
| 216 | 248 | |
| 217 | − crq.valid = (u8)IBMVTPM_VALID_CMD; | |
| 218 | − crq.msg = (u8)VTPM_GET_VERSION; | |
| 219 | − | |
| 220 | − rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), | |
| 221 | − cpu_to_be64(buf[1])); | |
| 249 | + rc = ibmvtpm_send_crq(ibmvtpm->vdev, | |
| 250 | + IBMVTPM_VALID_CMD, VTPM_GET_VERSION, 0, 0); | |
| 222 | 251 | if (rc != H_SUCCESS) |
| 223 | 252 | dev_err(ibmvtpm->dev, |
| 224 | 253 | "ibmvtpm_crq_get_version failed rc=%d\n", rc); |
| @@ -238,7 +267,7 @@ static int ibmvtpm_crq_send_init_complete(struct ibmvtpm_dev *ibmvtpm) · 13 unmodified lines | ||
| 238 | 267 | { |
| 239 | 268 | int rc; |
| 240 | 269 | |
| 241 | − rc = ibmvtpm_send_crq(ibmvtpm->vdev, INIT_CRQ_COMP_CMD, 0); | |
| 270 | + rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_COMP_CMD); | |
| 242 | 271 | if (rc != H_SUCCESS) |
| 243 | 272 | dev_err(ibmvtpm->dev, |
| 244 | 273 | "ibmvtpm_crq_send_init_complete failed rc=%d\n", rc); |
| @@ -258,7 +287,7 @@ static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm) · 13 unmodified lines | ||
| 258 | 287 | { |
| 259 | 288 | int rc; |
| 260 | 289 | |
| 261 | − rc = ibmvtpm_send_crq(ibmvtpm->vdev, INIT_CRQ_CMD, 0); | |
| 290 | + rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD); | |
| 262 | 291 | if (rc != H_SUCCESS) |
| 263 | 292 | dev_err(ibmvtpm->dev, |
| 264 | 293 | "ibmvtpm_crq_send_init failed rc=%d\n", rc); |
| @@ -340,15 +369,10 @@ static int tpm_ibmvtpm_suspend(struct device *dev) · 75 unmodified lines | ||
| 340 | 369 | { |
| 341 | 370 | struct tpm_chip *chip = dev_get_drvdata(dev); |
| 342 | 371 | struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); |
| 343 | − struct ibmvtpm_crq crq; | |
| 344 | − u64 *buf = (u64 *) &crq; | |
| 345 | 372 | int rc = 0; |
| 346 | 373 | |
| 347 | − crq.valid = (u8)IBMVTPM_VALID_CMD; | |
| 348 | − crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND; | |
| 349 | − | |
| 350 | − rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), | |
| 351 | − cpu_to_be64(buf[1])); | |
| 374 | + rc = ibmvtpm_send_crq(ibmvtpm->vdev, | |
| 375 | + IBMVTPM_VALID_CMD, VTPM_PREPARE_TO_SUSPEND, 0, 0); | |
| 352 | 376 | if (rc != H_SUCCESS) |
| 353 | 377 | dev_err(ibmvtpm->dev, |
| 354 | 378 | "tpm_ibmvtpm_suspend failed rc=%d\n", rc); |
| @@ -191,7 +191,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) · 190 unmodified lines | ||
| 191 | 191 | /* check the status-register if wait_for_bit is set */ |
| 192 | 192 | if (status & 1 << wait_for_bit) |
| 193 | 193 | break; |
| 194 | − msleep(TPM_MSLEEP_TIME); | |
| 194 | + tpm_msleep(TPM_MSLEEP_TIME); | |
| 195 | 195 | } |
| 196 | 196 | if (i == TPM_MAX_TRIES) { /* timeout occurs */ |
| 197 | 197 | if (wait_for_bit == STAT_XFE) |
| @@ -226,7 +226,7 @@ static void tpm_wtx(struct tpm_chip *chip) · 28 unmodified lines | ||
| 226 | 226 | wait_and_send(chip, TPM_CTRL_WTX); |
| 227 | 227 | wait_and_send(chip, 0x00); |
| 228 | 228 | wait_and_send(chip, 0x00); |
| 229 | − msleep(TPM_WTX_MSLEEP_TIME); | |
| 229 | + tpm_msleep(TPM_WTX_MSLEEP_TIME); | |
| 230 | 230 | } |
| 231 | 231 | |
| 232 | 232 | static void tpm_wtx_abort(struct tpm_chip *chip) |
| @@ -237,7 +237,7 @@ static void tpm_wtx_abort(struct tpm_chip *chip) · 4 unmodified lines | ||
| 237 | 237 | wait_and_send(chip, 0x00); |
| 238 | 238 | wait_and_send(chip, 0x00); |
| 239 | 239 | number_of_wtx = 0; |
| 240 | − msleep(TPM_WTX_MSLEEP_TIME); | |
| 240 | + tpm_msleep(TPM_WTX_MSLEEP_TIME); | |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | 243 | static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) |
| @@ -51,7 +51,7 @@ static int wait_startup(struct tpm_chip *chip, int l) · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | if (access & TPM_ACCESS_VALID) |
| 53 | 53 | return 0; |
| 54 | − msleep(TPM_TIMEOUT); | |
| 54 | + tpm_msleep(TPM_TIMEOUT); | |
| 55 | 55 | } while (time_before(jiffies, stop)); |
| 56 | 56 | return -1; |
| 57 | 57 | } |
| @@ -117,7 +117,7 @@ again: · 59 unmodified lines | ||
| 117 | 117 | do { |
| 118 | 118 | if (check_locality(chip, l)) |
| 119 | 119 | return l; |
| 120 | − msleep(TPM_TIMEOUT); | |
| 120 | + tpm_msleep(TPM_TIMEOUT); | |
| 121 | 121 | } while (time_before(jiffies, stop)); |
| 122 | 122 | } |
| 123 | 123 | return -1; |
| @@ -164,7 +164,7 @@ static int get_burstcount(struct tpm_chip *chip) · 40 unmodified lines | ||
| 164 | 164 | burstcnt = (value >> 8) & 0xFFFF; |
| 165 | 165 | if (burstcnt) |
| 166 | 166 | return burstcnt; |
| 167 | − msleep(TPM_TIMEOUT); | |
| 167 | + tpm_msleep(TPM_TIMEOUT); | |
| 168 | 168 | } while (time_before(jiffies, stop)); |
| 169 | 169 | return -EBUSY; |
| 170 | 170 | } |
| @@ -396,7 +396,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) · 225 unmodified lines | ||
| 396 | 396 | priv->irq = irq; |
| 397 | 397 | chip->flags |= TPM_CHIP_FLAG_IRQ; |
| 398 | 398 | if (!priv->irq_tested) |
| 399 | − msleep(1); | |
| 399 | + tpm_msleep(1); | |
| 400 | 400 | if (!priv->irq_tested) |
| 401 | 401 | disable_interrupts(chip); |
| 402 | 402 | priv->irq_tested = true; |
| @@ -105,6 +105,7 @@ err: · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | return ret; |
| 107 | 107 | } |
| 108 | +EXPORT_SYMBOL_GPL(clk_bulk_prepare); | |
| 108 | 109 | |
| 109 | 110 | #endif /* CONFIG_HAVE_CLK_PREPARE */ |
| 110 | 111 | |
| @@ -315,13 +315,13 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { · 314 unmodified lines | ||
| 315 | 315 | RK2928_CLKGATE_CON(10), 8, GFLAGS), |
| 316 | 316 | |
| 317 | 317 | GATE(SCLK_PVTM_CORE, "clk_pvtm_core", "xin24m", 0, |
| 318 | − RK2928_CLKGATE_CON(10), 8, GFLAGS), | |
| 318 | + RK2928_CLKGATE_CON(10), 0, GFLAGS), | |
| 319 | 319 | GATE(SCLK_PVTM_GPU, "clk_pvtm_gpu", "xin24m", 0, |
| 320 | − RK2928_CLKGATE_CON(10), 8, GFLAGS), | |
| 320 | + RK2928_CLKGATE_CON(10), 1, GFLAGS), | |
| 321 | 321 | GATE(SCLK_PVTM_FUNC, "clk_pvtm_func", "xin24m", 0, |
| 322 | − RK2928_CLKGATE_CON(10), 8, GFLAGS), | |
| 322 | + RK2928_CLKGATE_CON(10), 2, GFLAGS), | |
| 323 | 323 | GATE(SCLK_MIPI_24M, "clk_mipi_24m", "xin24m", CLK_IGNORE_UNUSED, |
| 324 | − RK2928_CLKGATE_CON(10), 8, GFLAGS), | |
| 324 | + RK2928_CLKGATE_CON(2), 15, GFLAGS), | |
| 325 | 325 | |
| 326 | 326 | COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0, |
| 327 | 327 | RK2928_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 6, DFLAGS, |
| @@ -541,7 +541,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { · 213 unmodified lines | ||
| 541 | 541 | GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), |
| 542 | 542 | GATE(0, "pclk_mipiphy", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 0, GFLAGS), |
| 543 | 543 | |
| 544 | − GATE(0, "pclk_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 2, GFLAGS), | |
| 544 | + GATE(0, "pclk_pmu", "pclk_pmu_pre", 0, RK2928_CLKGATE_CON(9), 2, GFLAGS), | |
| 545 | 545 | GATE(0, "pclk_pmu_niu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 3, GFLAGS), |
| 546 | 546 | |
| 547 | 547 | /* PD_MMC */ |
| @@ -577,6 +577,8 @@ static const char *const rk3128_critical_clocks[] __initconst = { · 29 unmodified lines | ||
| 577 | 577 | "aclk_peri", |
| 578 | 578 | "hclk_peri", |
| 579 | 579 | "pclk_peri", |
| 580 | + "pclk_pmu", | |
| 581 | + "sclk_timer5", | |
| 580 | 582 | }; |
| 581 | 583 | |
| 582 | 584 | static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np) |
| @@ -294,6 +294,18 @@ static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] = { · 293 unmodified lines | ||
| 294 | 294 | #define PLL_ENABLED (1 << 31) |
| 295 | 295 | #define PLL_LOCKED (1 << 29) |
| 296 | 296 | |
| 297 | +static void exynos4_clk_enable_pll(u32 reg) | |
| 298 | +{ | |
| 299 | + u32 pll_con = readl(reg_base + reg); | |
| 300 | + pll_con |= PLL_ENABLED; | |
| 301 | + writel(pll_con, reg_base + reg); | |
| 302 | + | |
| 303 | + while (!(pll_con & PLL_LOCKED)) { | |
| 304 | + cpu_relax(); | |
| 305 | + pll_con = readl(reg_base + reg); | |
| 306 | + } | |
| 307 | +} | |
| 308 | + | |
| 297 | 309 | static void exynos4_clk_wait_for_pll(u32 reg) |
| 298 | 310 | { |
| 299 | 311 | u32 pll_con; |
| @@ -315,6 +327,9 @@ static int exynos4_clk_suspend(void) · 15 unmodified lines | ||
| 315 | 327 | samsung_clk_save(reg_base, exynos4_save_pll, |
| 316 | 328 | ARRAY_SIZE(exynos4_clk_pll_regs)); |
| 317 | 329 | |
| 330 | + exynos4_clk_enable_pll(EPLL_CON0); | |
| 331 | + exynos4_clk_enable_pll(VPLL_CON0); | |
| 332 | + | |
| 318 | 333 | if (exynos4_soc == EXYNOS4210) { |
| 319 | 334 | samsung_clk_save(reg_base, exynos4_save_soc, |
| 320 | 335 | ARRAY_SIZE(exynos4210_clk_save)); |
| @@ -43,7 +43,7 @@ static int numachip2_set_next_event(unsigned long delta, struct clock_event_devi · 42 unmodified lines | ||
| 43 | 43 | return 0; |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | −static struct clock_event_device numachip2_clockevent = { | |
| 46 | +static const struct clock_event_device numachip2_clockevent __initconst = { | |
| 47 | 47 | .name = "numachip2", |
| 48 | 48 | .rating = 400, |
| 49 | 49 | .set_next_event = numachip2_set_next_event, |
| @@ -36,8 +36,8 @@ static u64 notrace integrator_read_sched_clock(void) · 35 unmodified lines | ||
| 36 | 36 | return -readl(sched_clk_base + TIMER_VALUE); |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | −static int integrator_clocksource_init(unsigned long inrate, | |
| 40 | − void __iomem *base) | |
| 39 | +static int __init integrator_clocksource_init(unsigned long inrate, | |
| 40 | + void __iomem *base) | |
| 41 | 41 | { |
| 42 | 42 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; |
| 43 | 43 | unsigned long rate = inrate; |
| @@ -106,6 +106,22 @@ static const struct of_device_id whitelist[] __initconst = { · 105 unmodified lines | ||
| 106 | 106 | * platforms using "operating-points-v2" property. |
| 107 | 107 | */ |
| 108 | 108 | static const struct of_device_id blacklist[] __initconst = { |
| 109 | + { .compatible = "calxeda,highbank", }, | |
| 110 | + { .compatible = "calxeda,ecx-2000", }, | |
| 111 | + | |
| 112 | + { .compatible = "marvell,armadaxp", }, | |
| 113 | + | |
| 114 | + { .compatible = "nvidia,tegra124", }, | |
| 115 | + | |
| 116 | + { .compatible = "st,stih407", }, | |
| 117 | + { .compatible = "st,stih410", }, | |
| 118 | + | |
| 119 | + { .compatible = "sigma,tango4", }, | |
| 120 | + | |
| 121 | + { .compatible = "ti,am33xx", }, | |
| 122 | + { .compatible = "ti,am43", }, | |
| 123 | + { .compatible = "ti,dra7", }, | |
| 124 | + | |
| 109 | 125 | { } |
| 110 | 126 | }; |
| 111 | 127 | |
| @@ -190,7 +190,7 @@ static int ti_cpufreq_setup_syscon_register(struct ti_cpufreq_data *opp_data) · 189 unmodified lines | ||
| 190 | 190 | |
| 191 | 191 | static const struct of_device_id ti_cpufreq_of_match[] = { |
| 192 | 192 | { .compatible = "ti,am33xx", .data = &am3x_soc_data, }, |
| 193 | − { .compatible = "ti,am4372", .data = &am4x_soc_data, }, | |
| 193 | + { .compatible = "ti,am43", .data = &am4x_soc_data, }, | |
| 194 | 194 | { .compatible = "ti,dra7", .data = &dra7_soc_data }, |
| 195 | 195 | {}, |
| 196 | 196 | }; |
| @@ -104,13 +104,13 @@ static int __init arm_idle_init(void) · 103 unmodified lines | ||
| 104 | 104 | ret = dt_init_idle_driver(drv, arm_idle_state_match, 1); |
| 105 | 105 | if (ret <= 0) { |
| 106 | 106 | ret = ret ? : -ENODEV; |
| 107 | − goto out_fail; | |
| 107 | + goto init_fail; | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | ret = cpuidle_register_driver(drv); |
| 111 | 111 | if (ret) { |
| 112 | 112 | pr_err("Failed to register cpuidle driver\n"); |
| 113 | − goto out_fail; | |
| 113 | + goto init_fail; | |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | /* |
| @@ -149,6 +149,8 @@ static int __init arm_idle_init(void) · 32 unmodified lines | ||
| 149 | 149 | } |
| 150 | 150 | |
| 151 | 151 | return 0; |
| 152 | +init_fail: | |
| 153 | + kfree(drv); | |
| 152 | 154 | out_fail: |
| 153 | 155 | while (--cpu >= 0) { |
| 154 | 156 | dev = per_cpu(cpuidle_devices, cpu); |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | config CRYPTO_DEV_FSL_CAAM |
| 2 | 2 | tristate "Freescale CAAM-Multicore driver backend" |
| 3 | 3 | depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE |
| 4 | + select SOC_BUS | |
| 4 | 5 | help |
| 5 | 6 | Enables the driver module for Freescale's Cryptographic Accelerator |
| 6 | 7 | and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). |
| @@ -141,10 +142,6 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API · 134 unmodified lines | ||
| 141 | 142 | To compile this as a module, choose M here: the module |
| 142 | 143 | will be called caamrng. |
| 143 | 144 | |
| 144 | −config CRYPTO_DEV_FSL_CAAM_IMX | |
| 145 | − def_bool SOC_IMX6 || SOC_IMX7D | |
| 146 | − depends on CRYPTO_DEV_FSL_CAAM | |
| 147 | − | |
| 148 | 145 | config CRYPTO_DEV_FSL_CAAM_DEBUG |
| 149 | 146 | bool "Enable debug output in CAAM driver" |
| 150 | 147 | depends on CRYPTO_DEV_FSL_CAAM |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/device.h> |
| 8 | 8 | #include <linux/of_address.h> |
| 9 | 9 | #include <linux/of_irq.h> |
| 10 | +#include <linux/sys_soc.h> | |
| 10 | 11 | |
| 11 | 12 | #include "compat.h" |
| 12 | 13 | #include "regs.h" |
| @@ -19,6 +20,8 @@ bool caam_little_end; · 6 unmodified lines | ||
| 19 | 20 | EXPORT_SYMBOL(caam_little_end); |
| 20 | 21 | bool caam_dpaa2; |
| 21 | 22 | EXPORT_SYMBOL(caam_dpaa2); |
| 23 | +bool caam_imx; | |
| 24 | +EXPORT_SYMBOL(caam_imx); | |
| 22 | 25 | |
| 23 | 26 | #ifdef CONFIG_CAAM_QI |
| 24 | 27 | #include "qi.h" |
| @@ -28,19 +31,11 @@ EXPORT_SYMBOL(caam_dpaa2); · 3 unmodified lines | ||
| 28 | 31 | * i.MX targets tend to have clock control subsystems that can |
| 29 | 32 | * enable/disable clocking to our device. |
| 30 | 33 | */ |
| 31 | −#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX | |
| 32 | 34 | static inline struct clk *caam_drv_identify_clk(struct device *dev, |
| 33 | 35 | char *clk_name) |
| 34 | 36 | { |
| 35 | − return devm_clk_get(dev, clk_name); | |
| 37 | + return caam_imx ? devm_clk_get(dev, clk_name) : NULL; | |
| 36 | 38 | } |
| 37 | −#else | |
| 38 | −static inline struct clk *caam_drv_identify_clk(struct device *dev, | |
| 39 | − char *clk_name) | |
| 40 | −{ | |
| 41 | − return NULL; | |
| 42 | −} | |
| 43 | −#endif | |
| 44 | 39 | |
| 45 | 40 | /* |
| 46 | 41 | * Descriptor to instantiate RNG State Handle 0 in normal mode and |
| @@ -430,6 +425,10 @@ static int caam_probe(struct platform_device *pdev) · 383 unmodified lines | ||
| 430 | 425 | { |
| 431 | 426 | int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN; |
| 432 | 427 | u64 caam_id; |
| 428 | + static const struct soc_device_attribute imx_soc[] = { | |
| 429 | + {.family = "Freescale i.MX"}, | |
| 430 | + {}, | |
| 431 | + }; | |
| 433 | 432 | struct device *dev; |
| 434 | 433 | struct device_node *nprop, *np; |
| 435 | 434 | struct caam_ctrl __iomem *ctrl; |
| @@ -451,6 +450,8 @@ static int caam_probe(struct platform_device *pdev) · 15 unmodified lines | ||
| 451 | 450 | dev_set_drvdata(dev, ctrlpriv); |
| 452 | 451 | nprop = pdev->dev.of_node; |
| 453 | 452 | |
| 453 | + caam_imx = (bool)soc_device_match(imx_soc); | |
| 454 | + | |
| 454 | 455 | /* Enable clocking */ |
| 455 | 456 | clk = caam_drv_identify_clk(&pdev->dev, "ipg"); |
| 456 | 457 | if (IS_ERR(clk)) { |
| @@ -67,6 +67,7 @@ · 66 unmodified lines | ||
| 67 | 67 | */ |
| 68 | 68 | |
| 69 | 69 | extern bool caam_little_end; |
| 70 | +extern bool caam_imx; | |
| 70 | 71 | |
| 71 | 72 | #define caam_to_cpu(len) \ |
| 72 | 73 | static inline u##len caam##len ## _to_cpu(u##len val) \ |
| @@ -154,13 +155,10 @@ static inline u64 rd_reg64(void __iomem *reg) · 81 unmodified lines | ||
| 154 | 155 | #else /* CONFIG_64BIT */ |
| 155 | 156 | static inline void wr_reg64(void __iomem *reg, u64 data) |
| 156 | 157 | { |
| 157 | −#ifndef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX | |
| 158 | − if (caam_little_end) { | |
| 158 | + if (!caam_imx && caam_little_end) { | |
| 159 | 159 | wr_reg32((u32 __iomem *)(reg) + 1, data >> 32); |
| 160 | 160 | wr_reg32((u32 __iomem *)(reg), data); |
| 161 | − } else | |
| 162 | −#endif | |
| 163 | − { | |
| 161 | + } else { | |
| 164 | 162 | wr_reg32((u32 __iomem *)(reg), data >> 32); |
| 165 | 163 | wr_reg32((u32 __iomem *)(reg) + 1, data); |
| 166 | 164 | } |
| @@ -168,41 +166,40 @@ static inline void wr_reg64(void __iomem *reg, u64 data) · 1 unmodified line | ||
| 168 | 166 | |
| 169 | 167 | static inline u64 rd_reg64(void __iomem *reg) |
| 170 | 168 | { |
| 171 | −#ifndef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX | |
| 172 | − if (caam_little_end) | |
| 169 | + if (!caam_imx && caam_little_end) | |
| 173 | 170 | return ((u64)rd_reg32((u32 __iomem *)(reg) + 1) << 32 | |
| 174 | 171 | (u64)rd_reg32((u32 __iomem *)(reg))); |
| 175 | − else | |
| 176 | −#endif | |
| 177 | − return ((u64)rd_reg32((u32 __iomem *)(reg)) << 32 | | |
| 178 | − (u64)rd_reg32((u32 __iomem *)(reg) + 1)); | |
| 172 | + | |
| 173 | + return ((u64)rd_reg32((u32 __iomem *)(reg)) << 32 | | |
| 174 | + (u64)rd_reg32((u32 __iomem *)(reg) + 1)); | |
| 179 | 175 | } |
| 180 | 176 | #endif /* CONFIG_64BIT */ |
| 181 | 177 | |
| 178 | +static inline u64 cpu_to_caam_dma64(dma_addr_t value) | |
| 179 | +{ | |
| 180 | + if (caam_imx) | |
| 181 | + return (((u64)cpu_to_caam32(lower_32_bits(value)) << 32) | | |
| 182 | + (u64)cpu_to_caam32(upper_32_bits(value))); | |
| 183 | + | |
| 184 | + return cpu_to_caam64(value); | |
| 185 | +} | |
| 186 | + | |
| 187 | +static inline u64 caam_dma64_to_cpu(u64 value) | |
| 188 | +{ | |
| 189 | + if (caam_imx) | |
| 190 | + return (((u64)caam32_to_cpu(lower_32_bits(value)) << 32) | | |
| 191 | + (u64)caam32_to_cpu(upper_32_bits(value))); | |
| 192 | + | |
| 193 | + return caam64_to_cpu(value); | |
| 194 | +} | |
| 195 | + | |
| 182 | 196 | #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT |
| 183 | −#ifdef CONFIG_SOC_IMX7D | |
| 184 | −#define cpu_to_caam_dma(value) \ | |
| 185 | − (((u64)cpu_to_caam32(lower_32_bits(value)) << 32) | \ | |
| 186 | − (u64)cpu_to_caam32(upper_32_bits(value))) | |
| 187 | −#define caam_dma_to_cpu(value) \ | |
| 188 | − (((u64)caam32_to_cpu(lower_32_bits(value)) << 32) | \ | |
| 189 | − (u64)caam32_to_cpu(upper_32_bits(value))) | |
| 190 | −#else | |
| 191 | −#define cpu_to_caam_dma(value) cpu_to_caam64(value) | |
| 192 | −#define caam_dma_to_cpu(value) caam64_to_cpu(value) | |
| 193 | −#endif /* CONFIG_SOC_IMX7D */ | |
| 197 | +#define cpu_to_caam_dma(value) cpu_to_caam_dma64(value) | |
| 198 | +#define caam_dma_to_cpu(value) caam_dma64_to_cpu(value) | |
| 194 | 199 | #else |
| 195 | 200 | #define cpu_to_caam_dma(value) cpu_to_caam32(value) |
| 196 | 201 | #define caam_dma_to_cpu(value) caam32_to_cpu(value) |
| 197 | −#endif /* CONFIG_ARCH_DMA_ADDR_T_64BIT */ | |
| 198 | − | |
| 199 | −#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX | |
| 200 | −#define cpu_to_caam_dma64(value) \ | |
| 201 | − (((u64)cpu_to_caam32(lower_32_bits(value)) << 32) | \ | |
| 202 | − (u64)cpu_to_caam32(upper_32_bits(value))) | |
| 203 | −#else | |
| 204 | −#define cpu_to_caam_dma64(value) cpu_to_caam64(value) | |
| 205 | −#endif | |
| 202 | +#endif /* CONFIG_ARCH_DMA_ADDR_T_64BIT */ | |
| 206 | 203 | |
| 207 | 204 | /* |
| 208 | 205 | * jr_outentry |
| @@ -386,7 +386,7 @@ static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm) · 385 unmodified lines | ||
| 386 | 386 | struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); |
| 387 | 387 | struct safexcel_crypto_priv *priv = ctx->priv; |
| 388 | 388 | struct skcipher_request req; |
| 389 | − struct safexcel_inv_result result = { 0 }; | |
| 389 | + struct safexcel_inv_result result = {}; | |
| 390 | 390 | int ring = ctx->base.ring; |
| 391 | 391 | |
| 392 | 392 | memset(&req, 0, sizeof(struct skcipher_request)); |
| @@ -419,7 +419,7 @@ static int safexcel_ahash_exit_inv(struct crypto_tfm *tfm) · 418 unmodified lines | ||
| 419 | 419 | struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); |
| 420 | 420 | struct safexcel_crypto_priv *priv = ctx->priv; |
| 421 | 421 | struct ahash_request req; |
| 422 | − struct safexcel_inv_result result = { 0 }; | |
| 422 | + struct safexcel_inv_result result = {}; | |
| 423 | 423 | int ring = ctx->base.ring; |
| 424 | 424 | |
| 425 | 425 | memset(&req, 0, sizeof(struct ahash_request)); |
| @@ -1756,9 +1756,9 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc, · 1755 unmodified lines | ||
| 1756 | 1756 | req_ctx->swinit = 0; |
| 1757 | 1757 | } else { |
| 1758 | 1758 | desc->ptr[1] = zero_entry; |
| 1759 | − /* Indicate next op is not the first. */ | |
| 1760 | − req_ctx->first = 0; | |
| 1761 | 1759 | } |
| 1760 | + /* Indicate next op is not the first. */ | |
| 1761 | + req_ctx->first = 0; | |
| 1762 | 1762 | |
| 1763 | 1763 | /* HMAC key */ |
| 1764 | 1764 | if (ctx->keylen) |
| @@ -1769,7 +1769,7 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc, · 4 unmodified lines | ||
| 1769 | 1769 | |
| 1770 | 1770 | sg_count = edesc->src_nents ?: 1; |
| 1771 | 1771 | if (is_sec1 && sg_count > 1) |
| 1772 | − sg_copy_to_buffer(areq->src, sg_count, edesc->buf, length); | |
| 1772 | + sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length); | |
| 1773 | 1773 | else |
| 1774 | 1774 | sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count, |
| 1775 | 1775 | DMA_TO_DEVICE); |
| @@ -3057,7 +3057,8 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, · 1281 unmodified lines | ||
| 3057 | 3057 | t_alg->algt.alg.hash.final = ahash_final; |
| 3058 | 3058 | t_alg->algt.alg.hash.finup = ahash_finup; |
| 3059 | 3059 | t_alg->algt.alg.hash.digest = ahash_digest; |
| 3060 | − t_alg->algt.alg.hash.setkey = ahash_setkey; | |
| 3060 | + if (!strncmp(alg->cra_name, "hmac", 4)) | |
| 3061 | + t_alg->algt.alg.hash.setkey = ahash_setkey; | |
| 3061 | 3062 | t_alg->algt.alg.hash.import = ahash_import; |
| 3062 | 3063 | t_alg->algt.alg.hash.export = ahash_export; |
| 3063 | 3064 | |
| @@ -361,12 +361,12 @@ static const struct fpga_manager_ops altera_cvp_ops = { · 360 unmodified lines | ||
| 361 | 361 | .write_complete = altera_cvp_write_complete, |
| 362 | 362 | }; |
| 363 | 363 | |
| 364 | −static ssize_t show_chkcfg(struct device_driver *dev, char *buf) | |
| 364 | +static ssize_t chkcfg_show(struct device_driver *dev, char *buf) | |
| 365 | 365 | { |
| 366 | 366 | return snprintf(buf, 3, "%d\n", altera_cvp_chkcfg); |
| 367 | 367 | } |
| 368 | 368 | |
| 369 | −static ssize_t store_chkcfg(struct device_driver *drv, const char *buf, | |
| 369 | +static ssize_t chkcfg_store(struct device_driver *drv, const char *buf, | |
| 370 | 370 | size_t count) |
| 371 | 371 | { |
| 372 | 372 | int ret; |
| @@ -378,7 +378,7 @@ static ssize_t store_chkcfg(struct device_driver *drv, const char *buf, · 5 unmodified lines | ||
| 378 | 378 | return count; |
| 379 | 379 | } |
| 380 | 380 | |
| 381 | −static DRIVER_ATTR(chkcfg, 0600, show_chkcfg, store_chkcfg); | |
| 381 | +static DRIVER_ATTR_RW(chkcfg); | |
| 382 | 382 | |
| 383 | 383 | static int altera_cvp_probe(struct pci_dev *pdev, |
| 384 | 384 | const struct pci_device_id *dev_id); |
| @@ -636,7 +636,194 @@ static void gfx_v6_0_tiling_mode_table_init(struct amdgpu_device *adev) · 635 unmodified lines | ||
| 636 | 636 | NUM_BANKS(ADDR_SURF_2_BANK); |
| 637 | 637 | for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) |
| 638 | 638 | WREG32(mmGB_TILE_MODE0 + reg_offset, tilemode[reg_offset]); |
| 639 | − } else if (adev->asic_type == CHIP_OLAND || adev->asic_type == CHIP_HAINAN) { | |
| 639 | + } else if (adev->asic_type == CHIP_OLAND) { | |
| 640 | + tilemode[0] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | | |
| 641 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 642 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 643 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | | |
| 644 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 645 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 646 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 647 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4); | |
| 648 | + tilemode[1] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | | |
| 649 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 650 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 651 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | | |
| 652 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 653 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 654 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 655 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4); | |
| 656 | + tilemode[2] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | | |
| 657 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 658 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 659 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | |
| 660 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 661 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 662 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 663 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4); | |
| 664 | + tilemode[3] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | | |
| 665 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 666 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 667 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | | |
| 668 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 669 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 670 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 671 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4); | |
| 672 | + tilemode[4] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | | |
| 673 | + ARRAY_MODE(ARRAY_1D_TILED_THIN1) | | |
| 674 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 675 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | | |
| 676 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 677 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 678 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | |
| 679 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 680 | + tilemode[5] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | | |
| 681 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 682 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 683 | + TILE_SPLIT(split_equal_to_row_size) | | |
| 684 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 685 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 686 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | |
| 687 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 688 | + tilemode[6] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | | |
| 689 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 690 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 691 | + TILE_SPLIT(split_equal_to_row_size) | | |
| 692 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 693 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 694 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | |
| 695 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 696 | + tilemode[7] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | | |
| 697 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 698 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 699 | + TILE_SPLIT(split_equal_to_row_size) | | |
| 700 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 701 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 702 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 703 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4); | |
| 704 | + tilemode[8] = MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | | |
| 705 | + ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | | |
| 706 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 707 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | | |
| 708 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 709 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 710 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | |
| 711 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 712 | + tilemode[9] = MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | | |
| 713 | + ARRAY_MODE(ARRAY_1D_TILED_THIN1) | | |
| 714 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 715 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | | |
| 716 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 717 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 718 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | |
| 719 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 720 | + tilemode[10] = MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | | |
| 721 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 722 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 723 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | |
| 724 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 725 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 726 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 727 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4); | |
| 728 | + tilemode[11] = MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | | |
| 729 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 730 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 731 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | |
| 732 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 733 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 734 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | |
| 735 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 736 | + tilemode[12] = MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | | |
| 737 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 738 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 739 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | | |
| 740 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 741 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 742 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | |
| 743 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 744 | + tilemode[13] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 745 | + ARRAY_MODE(ARRAY_1D_TILED_THIN1) | | |
| 746 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 747 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | | |
| 748 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 749 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 750 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | |
| 751 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 752 | + tilemode[14] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 753 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 754 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 755 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | |
| 756 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 757 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 758 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 759 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 760 | + tilemode[15] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 761 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 762 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 763 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | |
| 764 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 765 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 766 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | |
| 767 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 768 | + tilemode[16] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 769 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 770 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 771 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | | |
| 772 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 773 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 774 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | |
| 775 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 776 | + tilemode[17] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 777 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 778 | + PIPE_CONFIG(ADDR_SURF_P4_8x16) | | |
| 779 | + TILE_SPLIT(split_equal_to_row_size) | | |
| 780 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 781 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 782 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | |
| 783 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 784 | + tilemode[21] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 785 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 786 | + PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | | |
| 787 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | |
| 788 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 789 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | | |
| 790 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 791 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 792 | + tilemode[22] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 793 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 794 | + PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | | |
| 795 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | |
| 796 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 797 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 798 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | | |
| 799 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4); | |
| 800 | + tilemode[23] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 801 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 802 | + PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | | |
| 803 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | | |
| 804 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 805 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 806 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | | |
| 807 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 808 | + tilemode[24] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 809 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 810 | + PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | | |
| 811 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | | |
| 812 | + NUM_BANKS(ADDR_SURF_16_BANK) | | |
| 813 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 814 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | |
| 815 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2); | |
| 816 | + tilemode[25] = MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | | |
| 817 | + ARRAY_MODE(ARRAY_2D_TILED_THIN1) | | |
| 818 | + PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | | |
| 819 | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) | | |
| 820 | + NUM_BANKS(ADDR_SURF_8_BANK) | | |
| 821 | + BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | | |
| 822 | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | | |
| 823 | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1); | |
| 824 | + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) | |
| 825 | + WREG32(mmGB_TILE_MODE0 + reg_offset, tilemode[reg_offset]); | |
| 826 | + } else if (adev->asic_type == CHIP_HAINAN) { | |
| 640 | 827 | tilemode[0] = MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | |
| 641 | 828 | ARRAY_MODE(ARRAY_2D_TILED_THIN1) | |
| 642 | 829 | PIPE_CONFIG(ADDR_SURF_P2) | |
| @@ -892,6 +892,8 @@ static int kfd_ioctl_get_tile_config(struct file *filep, · 891 unmodified lines | ||
| 892 | 892 | int err = 0; |
| 893 | 893 | |
| 894 | 894 | dev = kfd_device_by_id(args->gpu_id); |
| 895 | + if (!dev) | |
| 896 | + return -EINVAL; | |
| 895 | 897 | |
| 896 | 898 | dev->kfd2kgd->get_tile_config(dev->kgd, &config); |
| 897 | 899 | |
| @@ -292,7 +292,10 @@ static int create_signal_event(struct file *devkfd, · 291 unmodified lines | ||
| 292 | 292 | struct kfd_event *ev) |
| 293 | 293 | { |
| 294 | 294 | if (p->signal_event_count == KFD_SIGNAL_EVENT_LIMIT) { |
| 295 | − pr_warn("Signal event wasn't created because limit was reached\n"); | |
| 295 | + if (!p->signal_event_limit_reached) { | |
| 296 | + pr_warn("Signal event wasn't created because limit was reached\n"); | |
| 297 | + p->signal_event_limit_reached = true; | |
| 298 | + } | |
| 296 | 299 | return -ENOMEM; |
| 297 | 300 | } |
| 298 | 301 | |
| @@ -183,8 +183,8 @@ static void uninitialize(struct kernel_queue *kq) · 182 unmodified lines | ||
| 183 | 183 | { |
| 184 | 184 | if (kq->queue->properties.type == KFD_QUEUE_TYPE_HIQ) |
| 185 | 185 | kq->mqd->destroy_mqd(kq->mqd, |
| 186 | − NULL, | |
| 187 | − false, | |
| 186 | + kq->queue->mqd, | |
| 187 | + KFD_PREEMPT_TYPE_WAVEFRONT_RESET, | |
| 188 | 188 | QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS, |
| 189 | 189 | kq->queue->pipe, |
| 190 | 190 | kq->queue->queue); |
| @@ -210,6 +210,11 @@ static int acquire_packet_buffer(struct kernel_queue *kq, · 19 unmodified lines | ||
| 210 | 210 | uint32_t wptr, rptr; |
| 211 | 211 | unsigned int *queue_address; |
| 212 | 212 | |
| 213 | + /* When rptr == wptr, the buffer is empty. | |
| 214 | + * When rptr == wptr + 1, the buffer is full. | |
| 215 | + * It is always rptr that advances to the position of wptr, rather than | |
| 216 | + * the opposite. So we can only use up to queue_size_dwords - 1 dwords. | |
| 217 | + */ | |
| 213 | 218 | rptr = *kq->rptr_kernel; |
| 214 | 219 | wptr = *kq->wptr_kernel; |
| 215 | 220 | queue_address = (unsigned int *)kq->pq_kernel_addr; |
| @@ -219,11 +224,10 @@ static int acquire_packet_buffer(struct kernel_queue *kq, · 3 unmodified lines | ||
| 219 | 224 | pr_debug("wptr: %d\n", wptr); |
| 220 | 225 | pr_debug("queue_address 0x%p\n", queue_address); |
| 221 | 226 | |
| 222 | − available_size = (rptr - 1 - wptr + queue_size_dwords) % | |
| 227 | + available_size = (rptr + queue_size_dwords - 1 - wptr) % | |
| 223 | 228 | queue_size_dwords; |
| 224 | 229 | |
| 225 | − if (packet_size_in_dwords >= queue_size_dwords || | |
| 226 | − packet_size_in_dwords >= available_size) { | |
| 230 | + if (packet_size_in_dwords > available_size) { | |
| 227 | 231 | /* |
| 228 | 232 | * make sure calling functions know |
| 229 | 233 | * acquire_packet_buffer() failed |
| @@ -233,6 +237,14 @@ static int acquire_packet_buffer(struct kernel_queue *kq, · 3 unmodified lines | ||
| 233 | 237 | } |
| 234 | 238 | |
| 235 | 239 | if (wptr + packet_size_in_dwords >= queue_size_dwords) { |
| 240 | + /* make sure after rolling back to position 0, there is | |
| 241 | + * still enough space. | |
| 242 | + */ | |
| 243 | + if (packet_size_in_dwords >= rptr) { | |
| 244 | + *buffer_ptr = NULL; | |
| 245 | + return -ENOMEM; | |
| 246 | + } | |
| 247 | + /* fill nops, roll back and start at position 0 */ | |
| 236 | 248 | while (wptr > 0) { |
| 237 | 249 | queue_address[wptr] = kq->nop_packet; |
| 238 | 250 | wptr = (wptr + 1) % queue_size_dwords; |
| @@ -521,6 +521,7 @@ struct kfd_process { · 520 unmodified lines | ||
| 521 | 521 | struct list_head signal_event_pages; |
| 522 | 522 | u32 next_nonsignal_event_id; |
| 523 | 523 | size_t signal_event_count; |
| 524 | + bool signal_event_limit_reached; | |
| 524 | 525 | }; |
| 525 | 526 | |
| 526 | 527 | /** |
| @@ -143,7 +143,6 @@ int pqm_create_queue(struct process_queue_manager *pqm, · 142 unmodified lines | ||
| 143 | 143 | int num_queues = 0; |
| 144 | 144 | struct queue *cur; |
| 145 | 145 | |
| 146 | − memset(&q_properties, 0, sizeof(struct queue_properties)); | |
| 147 | 146 | memcpy(&q_properties, properties, sizeof(struct queue_properties)); |
| 148 | 147 | q = NULL; |
| 149 | 148 | kq = NULL; |
| @@ -551,12 +551,15 @@ static const struct etnaviv_gem_ops etnaviv_gem_shmem_ops = { · 550 unmodified lines | ||
| 551 | 551 | void etnaviv_gem_free_object(struct drm_gem_object *obj) |
| 552 | 552 | { |
| 553 | 553 | struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); |
| 554 | + struct etnaviv_drm_private *priv = obj->dev->dev_private; | |
| 554 | 555 | struct etnaviv_vram_mapping *mapping, *tmp; |
| 555 | 556 | |
| 556 | 557 | /* object should not be active */ |
| 557 | 558 | WARN_ON(is_active(etnaviv_obj)); |
| 558 | 559 | |
| 560 | + mutex_lock(&priv->gem_lock); | |
| 559 | 561 | list_del(&etnaviv_obj->gem_node); |
| 562 | + mutex_unlock(&priv->gem_lock); | |
| 560 | 563 | |
| 561 | 564 | list_for_each_entry_safe(mapping, tmp, &etnaviv_obj->vram_list, |
| 562 | 565 | obj_node) { |
| @@ -445,8 +445,10 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, · 444 unmodified lines | ||
| 445 | 445 | cmdbuf->user_size = ALIGN(args->stream_size, 8); |
| 446 | 446 | |
| 447 | 447 | ret = etnaviv_gpu_submit(gpu, submit, cmdbuf); |
| 448 | − if (ret == 0) | |
| 449 | − cmdbuf = NULL; | |
| 448 | + if (ret) | |
| 449 | + goto out; | |
| 450 | + | |
| 451 | + cmdbuf = NULL; | |
| 450 | 452 | |
| 451 | 453 | if (args->flags & ETNA_SUBMIT_FENCE_FD_OUT) { |
| 452 | 454 | /* |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/clk.h> |
| 15 | 15 | #include <linux/component.h> |
| 16 | 16 | #include <linux/iopoll.h> |
| 17 | +#include <linux/irq.h> | |
| 17 | 18 | #include <linux/mfd/syscon.h> |
| 18 | 19 | #include <linux/of_device.h> |
| 19 | 20 | #include <linux/of_gpio.h> |
| @@ -168,23 +168,19 @@ static struct drm_driver exynos_drm_driver = { · 167 unmodified lines | ||
| 168 | 168 | static int exynos_drm_suspend(struct device *dev) |
| 169 | 169 | { |
| 170 | 170 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 171 | − struct drm_connector *connector; | |
| 172 | − struct drm_connector_list_iter conn_iter; | |
| 171 | + struct exynos_drm_private *private = drm_dev->dev_private; | |
| 173 | 172 | |
| 174 | 173 | if (pm_runtime_suspended(dev) || !drm_dev) |
| 175 | 174 | return 0; |
| 176 | 175 | |
| 177 | − drm_connector_list_iter_begin(drm_dev, &conn_iter); | |
| 178 | − drm_for_each_connector_iter(connector, &conn_iter) { | |
| 179 | − int old_dpms = connector->dpms; | |
| 180 | − | |
| 181 | − if (connector->funcs->dpms) | |
| 182 | − connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF); | |
| 183 | − | |
| 184 | − /* Set the old mode back to the connector for resume */ | |
| 185 | − connector->dpms = old_dpms; | |
| 176 | + drm_kms_helper_poll_disable(drm_dev); | |
| 177 | + exynos_drm_fbdev_suspend(drm_dev); | |
| 178 | + private->suspend_state = drm_atomic_helper_suspend(drm_dev); | |
| 179 | + if (IS_ERR(private->suspend_state)) { | |
| 180 | + exynos_drm_fbdev_resume(drm_dev); | |
| 181 | + drm_kms_helper_poll_enable(drm_dev); | |
| 182 | + return PTR_ERR(private->suspend_state); | |
| 186 | 183 | } |
| 187 | − drm_connector_list_iter_end(&conn_iter); | |
| 188 | 184 | |
| 189 | 185 | return 0; |
| 190 | 186 | } |
| @@ -192,22 +188,14 @@ static int exynos_drm_suspend(struct device *dev) · 1 unmodified line | ||
| 192 | 188 | static int exynos_drm_resume(struct device *dev) |
| 193 | 189 | { |
| 194 | 190 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 195 | − struct drm_connector *connector; | |
| 196 | − struct drm_connector_list_iter conn_iter; | |
| 191 | + struct exynos_drm_private *private = drm_dev->dev_private; | |
| 197 | 192 | |
| 198 | 193 | if (pm_runtime_suspended(dev) || !drm_dev) |
| 199 | 194 | return 0; |
| 200 | 195 | |
| 201 | − drm_connector_list_iter_begin(drm_dev, &conn_iter); | |
| 202 | − drm_for_each_connector_iter(connector, &conn_iter) { | |
| 203 | − if (connector->funcs->dpms) { | |
| 204 | − int dpms = connector->dpms; | |
| 205 | − | |
| 206 | − connector->dpms = DRM_MODE_DPMS_OFF; | |
| 207 | − connector->funcs->dpms(connector, dpms); | |
| 208 | − } | |
| 209 | − } | |
| 210 | − drm_connector_list_iter_end(&conn_iter); | |
| 196 | + drm_atomic_helper_resume(drm_dev, private->suspend_state); | |
| 197 | + exynos_drm_fbdev_resume(drm_dev); | |
| 198 | + drm_kms_helper_poll_enable(drm_dev); | |
| 211 | 199 | |
| 212 | 200 | return 0; |
| 213 | 201 | } |
| @@ -202,6 +202,7 @@ struct drm_exynos_file_private { · 201 unmodified lines | ||
| 202 | 202 | */ |
| 203 | 203 | struct exynos_drm_private { |
| 204 | 204 | struct drm_fb_helper *fb_helper; |
| 205 | + struct drm_atomic_state *suspend_state; | |
| 205 | 206 | |
| 206 | 207 | struct device *dma_dev; |
| 207 | 208 | void *mapping; |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <drm/drm_crtc_helper.h> |
| 19 | 19 | #include <drm/exynos_drm.h> |
| 20 | 20 | |
| 21 | +#include <linux/console.h> | |
| 22 | + | |
| 21 | 23 | #include "exynos_drm_drv.h" |
| 22 | 24 | #include "exynos_drm_fb.h" |
| 23 | 25 | #include "exynos_drm_fbdev.h" |
| @@ -285,3 +287,21 @@ void exynos_drm_output_poll_changed(struct drm_device *dev) · 261 unmodified lines | ||
| 285 | 287 | |
| 286 | 288 | drm_fb_helper_hotplug_event(fb_helper); |
| 287 | 289 | } |
| 290 | + | |
| 291 | +void exynos_drm_fbdev_suspend(struct drm_device *dev) | |
| 292 | +{ | |
| 293 | + struct exynos_drm_private *private = dev->dev_private; | |
| 294 | + | |
| 295 | + console_lock(); | |
| 296 | + drm_fb_helper_set_suspend(private->fb_helper, 1); | |
| 297 | + console_unlock(); | |
| 298 | +} | |
| 299 | + | |
| 300 | +void exynos_drm_fbdev_resume(struct drm_device *dev) | |
| 301 | +{ | |
| 302 | + struct exynos_drm_private *private = dev->dev_private; | |
| 303 | + | |
| 304 | + console_lock(); | |
| 305 | + drm_fb_helper_set_suspend(private->fb_helper, 0); | |
| 306 | + console_unlock(); | |
| 307 | +} | |
| @@ -21,6 +21,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev); · 20 unmodified lines | ||
| 21 | 21 | void exynos_drm_fbdev_fini(struct drm_device *dev); |
| 22 | 22 | void exynos_drm_fbdev_restore_mode(struct drm_device *dev); |
| 23 | 23 | void exynos_drm_output_poll_changed(struct drm_device *dev); |
| 24 | +void exynos_drm_fbdev_suspend(struct drm_device *drm); | |
| 25 | +void exynos_drm_fbdev_resume(struct drm_device *drm); | |
| 24 | 26 | |
| 25 | 27 | #else |
| 26 | 28 | |
| @@ -39,6 +41,14 @@ static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev) · 12 unmodified lines | ||
| 39 | 41 | |
| 40 | 42 | #define exynos_drm_output_poll_changed (NULL) |
| 41 | 43 | |
| 44 | +static inline void exynos_drm_fbdev_suspend(struct drm_device *drm) | |
| 45 | +{ | |
| 46 | +} | |
| 47 | + | |
| 48 | +static inline void exynos_drm_fbdev_resume(struct drm_device *drm) | |
| 49 | +{ | |
| 50 | +} | |
| 51 | + | |
| 42 | 52 | #endif |
| 43 | 53 | |
| 44 | 54 | #endif |
| @@ -944,22 +944,27 @@ static bool hdmi_mode_fixup(struct drm_encoder *encoder, · 943 unmodified lines | ||
| 944 | 944 | struct drm_device *dev = encoder->dev; |
| 945 | 945 | struct drm_connector *connector; |
| 946 | 946 | struct drm_display_mode *m; |
| 947 | + struct drm_connector_list_iter conn_iter; | |
| 947 | 948 | int mode_ok; |
| 948 | 949 | |
| 949 | 950 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
| 950 | 951 | |
| 951 | − list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | |
| 952 | + drm_connector_list_iter_begin(dev, &conn_iter); | |
| 953 | + drm_for_each_connector_iter(connector, &conn_iter) { | |
| 952 | 954 | if (connector->encoder == encoder) |
| 953 | 955 | break; |
| 954 | 956 | } |
| 957 | + if (connector) | |
| 958 | + drm_connector_get(connector); | |
| 959 | + drm_connector_list_iter_end(&conn_iter); | |
| 955 | 960 | |
| 956 | − if (connector->encoder != encoder) | |
| 961 | + if (!connector) | |
| 957 | 962 | return true; |
| 958 | 963 | |
| 959 | 964 | mode_ok = hdmi_mode_valid(connector, adjusted_mode); |
| 960 | 965 | |
| 961 | 966 | if (mode_ok == MODE_OK) |
| 962 | − return true; | |
| 967 | + goto cleanup; | |
| 963 | 968 | |
| 964 | 969 | /* |
| 965 | 970 | * Find the most suitable mode and copy it to adjusted_mode. |
| @@ -979,6 +984,9 @@ static bool hdmi_mode_fixup(struct drm_encoder *encoder, · 13 unmodified lines | ||
| 979 | 984 | } |
| 980 | 985 | } |
| 981 | 986 | |
| 987 | +cleanup: | |
| 988 | + drm_connector_put(connector); | |
| 989 | + | |
| 982 | 990 | return true; |
| 983 | 991 | } |
| 984 | 992 | |
| @@ -197,78 +197,65 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu, · 196 unmodified lines | ||
| 197 | 197 | static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset, |
| 198 | 198 | void *p_data, unsigned int bytes) |
| 199 | 199 | { |
| 200 | − unsigned int bar_index = | |
| 201 | − (rounddown(offset, 8) % PCI_BASE_ADDRESS_0) / 8; | |
| 202 | 200 | u32 new = *(u32 *)(p_data); |
| 203 | 201 | bool lo = IS_ALIGNED(offset, 8); |
| 204 | 202 | u64 size; |
| 205 | 203 | int ret = 0; |
| 206 | 204 | bool mmio_enabled = |
| 207 | 205 | vgpu_cfg_space(vgpu)[PCI_COMMAND] & PCI_COMMAND_MEMORY; |
| 206 | + struct intel_vgpu_pci_bar *bars = vgpu->cfg_space.bar; | |
| 208 | 207 | |
| 209 | − if (WARN_ON(bar_index >= INTEL_GVT_PCI_BAR_MAX)) | |
| 210 | − return -EINVAL; | |
| 211 | − | |
| 208 | + /* | |
| 209 | + * Power-up software can determine how much address | |
| 210 | + * space the device requires by writing a value of | |
| 211 | + * all 1's to the register and then reading the value | |
| 212 | + * back. The device will return 0's in all don't-care | |
| 213 | + * address bits. | |
| 214 | + */ | |
| 212 | 215 | if (new == 0xffffffff) { |
| 213 | − /* | |
| 214 | − * Power-up software can determine how much address | |
| 215 | − * space the device requires by writing a value of | |
| 216 | − * all 1's to the register and then reading the value | |
| 217 | − * back. The device will return 0's in all don't-care | |
| 218 | − * address bits. | |
| 219 | − */ | |
| 220 | − size = vgpu->cfg_space.bar[bar_index].size; | |
| 221 | − if (lo) { | |
| 222 | − new = rounddown(new, size); | |
| 223 | − } else { | |
| 224 | − u32 val = vgpu_cfg_space(vgpu)[rounddown(offset, 8)]; | |
| 225 | − /* for 32bit mode bar it returns all-0 in upper 32 | |
| 226 | − * bit, for 64bit mode bar it will calculate the | |
| 227 | − * size with lower 32bit and return the corresponding | |
| 228 | − * value | |
| 216 | + switch (offset) { | |
| 217 | + case PCI_BASE_ADDRESS_0: | |
| 218 | + case PCI_BASE_ADDRESS_1: | |
| 219 | + size = ~(bars[INTEL_GVT_PCI_BAR_GTTMMIO].size -1); | |
| 220 | + intel_vgpu_write_pci_bar(vgpu, offset, | |
| 221 | + size >> (lo ? 0 : 32), lo); | |
| 222 | + /* | |
| 223 | + * Untrap the BAR, since guest hasn't configured a | |
| 224 | + * valid GPA | |
| 229 | 225 | */ |
| 230 | − if (val & PCI_BASE_ADDRESS_MEM_TYPE_64) | |
| 231 | − new &= (~(size-1)) >> 32; | |
| 232 | − else | |
| 233 | − new = 0; | |
| 234 | − } | |
| 235 | − /* | |
| 236 | − * Unmapp & untrap the BAR, since guest hasn't configured a | |
| 237 | − * valid GPA | |
| 238 | − */ | |
| 239 | − switch (bar_index) { | |
| 240 | − case INTEL_GVT_PCI_BAR_GTTMMIO: | |
| 241 | 226 | ret = trap_gttmmio(vgpu, false); |
| 242 | 227 | break; |
| 243 | − case INTEL_GVT_PCI_BAR_APERTURE: | |
| 228 | + case PCI_BASE_ADDRESS_2: | |
| 229 | + case PCI_BASE_ADDRESS_3: | |
| 230 | + size = ~(bars[INTEL_GVT_PCI_BAR_APERTURE].size -1); | |
| 231 | + intel_vgpu_write_pci_bar(vgpu, offset, | |
| 232 | + size >> (lo ? 0 : 32), lo); | |
| 244 | 233 | ret = map_aperture(vgpu, false); |
| 245 | 234 | break; |
| 235 | + default: | |
| 236 | + /* Unimplemented BARs */ | |
| 237 | + intel_vgpu_write_pci_bar(vgpu, offset, 0x0, false); | |
| 246 | 238 | } |
| 247 | − intel_vgpu_write_pci_bar(vgpu, offset, new, lo); | |
| 248 | 239 | } else { |
| 249 | − /* | |
| 250 | − * Unmapp & untrap the old BAR first, since guest has | |
| 251 | − * re-configured the BAR | |
| 252 | − */ | |
| 253 | − switch (bar_index) { | |
| 254 | − case INTEL_GVT_PCI_BAR_GTTMMIO: | |
| 255 | − ret = trap_gttmmio(vgpu, false); | |
| 240 | + switch (offset) { | |
| 241 | + case PCI_BASE_ADDRESS_0: | |
| 242 | + case PCI_BASE_ADDRESS_1: | |
| 243 | + /* | |
| 244 | + * Untrap the old BAR first, since guest has | |
| 245 | + * re-configured the BAR | |
| 246 | + */ | |
| 247 | + trap_gttmmio(vgpu, false); | |
| 248 | + intel_vgpu_write_pci_bar(vgpu, offset, new, lo); | |
| 249 | + ret = trap_gttmmio(vgpu, mmio_enabled); | |
| 256 | 250 | break; |
| 257 | − case INTEL_GVT_PCI_BAR_APERTURE: | |
| 258 | − ret = map_aperture(vgpu, false); | |
| 251 | + case PCI_BASE_ADDRESS_2: | |
| 252 | + case PCI_BASE_ADDRESS_3: | |
| 253 | + map_aperture(vgpu, false); | |
| 254 | + intel_vgpu_write_pci_bar(vgpu, offset, new, lo); | |
| 255 | + ret = map_aperture(vgpu, mmio_enabled); | |
| 259 | 256 | break; |
| 260 | − } | |
| 261 | − intel_vgpu_write_pci_bar(vgpu, offset, new, lo); | |
| 262 | − /* Track the new BAR */ | |
| 263 | − if (mmio_enabled) { | |
| 264 | − switch (bar_index) { | |
| 265 | − case INTEL_GVT_PCI_BAR_GTTMMIO: | |
| 266 | − ret = trap_gttmmio(vgpu, true); | |
| 267 | − break; | |
| 268 | − case INTEL_GVT_PCI_BAR_APERTURE: | |
| 269 | − ret = map_aperture(vgpu, true); | |
| 270 | − break; | |
| 271 | − } | |
| 257 | + default: | |
| 258 | + intel_vgpu_write_pci_bar(vgpu, offset, new, lo); | |
| 272 | 259 | } |
| 273 | 260 | } |
| 274 | 261 | return ret; |
| @@ -299,10 +286,7 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, · 24 unmodified lines | ||
| 299 | 286 | } |
| 300 | 287 | |
| 301 | 288 | switch (rounddown(offset, 4)) { |
| 302 | − case PCI_BASE_ADDRESS_0: | |
| 303 | − case PCI_BASE_ADDRESS_1: | |
| 304 | − case PCI_BASE_ADDRESS_2: | |
| 305 | − case PCI_BASE_ADDRESS_3: | |
| 289 | + case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5: | |
| 306 | 290 | if (WARN_ON(!IS_ALIGNED(offset, 4))) |
| 307 | 291 | return -EINVAL; |
| 308 | 292 | return emulate_pci_bar_write(vgpu, offset, p_data, bytes); |
| @@ -344,7 +328,6 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu, · 35 unmodified lines | ||
| 344 | 328 | struct intel_gvt *gvt = vgpu->gvt; |
| 345 | 329 | const struct intel_gvt_device_info *info = &gvt->device_info; |
| 346 | 330 | u16 *gmch_ctl; |
| 347 | − int i; | |
| 348 | 331 | |
| 349 | 332 | memcpy(vgpu_cfg_space(vgpu), gvt->firmware.cfg_space, |
| 350 | 333 | info->cfg_space_size); |
| @@ -371,13 +354,13 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu, · 20 unmodified lines | ||
| 371 | 354 | */ |
| 372 | 355 | memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_1, 0, 4); |
| 373 | 356 | memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_3, 0, 4); |
| 357 | + memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_4, 0, 8); | |
| 374 | 358 | memset(vgpu_cfg_space(vgpu) + INTEL_GVT_PCI_OPREGION, 0, 4); |
| 375 | 359 | |
| 376 | − for (i = 0; i < INTEL_GVT_MAX_BAR_NUM; i++) { | |
| 377 | − vgpu->cfg_space.bar[i].size = pci_resource_len( | |
| 378 | − gvt->dev_priv->drm.pdev, i * 2); | |
| 379 | − vgpu->cfg_space.bar[i].tracked = false; | |
| 380 | − } | |
| 360 | + vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].size = | |
| 361 | + pci_resource_len(gvt->dev_priv->drm.pdev, 0); | |
| 362 | + vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size = | |
| 363 | + pci_resource_len(gvt->dev_priv->drm.pdev, 2); | |
| 381 | 364 | } |
| 382 | 365 | |
| 383 | 366 | /** |
| @@ -839,7 +839,6 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, · 838 unmodified lines | ||
| 839 | 839 | pipe); |
| 840 | 840 | int position; |
| 841 | 841 | int vbl_start, vbl_end, hsync_start, htotal, vtotal; |
| 842 | − bool in_vbl = true; | |
| 843 | 842 | unsigned long irqflags; |
| 844 | 843 | |
| 845 | 844 | if (WARN_ON(!mode->crtc_clock)) { |
| @@ -922,8 +921,6 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, · 76 unmodified lines | ||
| 922 | 921 | |
| 923 | 922 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
| 924 | 923 | |
| 925 | − in_vbl = position >= vbl_start && position < vbl_end; | |
| 926 | − | |
| 927 | 924 | /* |
| 928 | 925 | * While in vblank, position will be negative |
| 929 | 926 | * counting up towards 0 at vbl_end. And outside |
| @@ -606,11 +606,6 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, · 605 unmodified lines | ||
| 606 | 606 | connector->encoder->base.id, |
| 607 | 607 | connector->encoder->name); |
| 608 | 608 | |
| 609 | − /* ELD Conn_Type */ | |
| 610 | − connector->eld[5] &= ~(3 << 2); | |
| 611 | − if (intel_crtc_has_dp_encoder(crtc_state)) | |
| 612 | − connector->eld[5] |= (1 << 2); | |
| 613 | − | |
| 614 | 609 | connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; |
| 615 | 610 | |
| 616 | 611 | if (dev_priv->display.audio_codec_enable) |
| @@ -1163,6 +1163,13 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, · 1162 unmodified lines | ||
| 1163 | 1163 | is_hdmi = is_dvi && (child->common.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0; |
| 1164 | 1164 | is_edp = is_dp && (child->common.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR); |
| 1165 | 1165 | |
| 1166 | + if (port == PORT_A && is_dvi) { | |
| 1167 | + DRM_DEBUG_KMS("VBT claims port A supports DVI%s, ignoring\n", | |
| 1168 | + is_hdmi ? "/HDMI" : ""); | |
| 1169 | + is_dvi = false; | |
| 1170 | + is_hdmi = false; | |
| 1171 | + } | |
| 1172 | + | |
| 1166 | 1173 | info->supports_dvi = is_dvi; |
| 1167 | 1174 | info->supports_hdmi = is_hdmi; |
| 1168 | 1175 | info->supports_dp = is_dp; |
| @@ -216,7 +216,7 @@ static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) · 215 unmodified lines | ||
| 216 | 216 | |
| 217 | 217 | mask = DC_STATE_DEBUG_MASK_MEMORY_UP; |
| 218 | 218 | |
| 219 | − if (IS_BROXTON(dev_priv)) | |
| 219 | + if (IS_GEN9_LP(dev_priv)) | |
| 220 | 220 | mask |= DC_STATE_DEBUG_MASK_CORES; |
| 221 | 221 | |
| 222 | 222 | /* The below bit doesn't need to be cleared ever afterwards */ |
| @@ -1655,7 +1655,8 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, · 1654 unmodified lines | ||
| 1655 | 1655 | out: |
| 1656 | 1656 | if (ret && IS_GEN9_LP(dev_priv)) { |
| 1657 | 1657 | tmp = I915_READ(BXT_PHY_CTL(port)); |
| 1658 | − if ((tmp & (BXT_PHY_LANE_POWERDOWN_ACK | | |
| 1658 | + if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK | | |
| 1659 | + BXT_PHY_LANE_POWERDOWN_ACK | | |
| 1659 | 1660 | BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED) |
| 1660 | 1661 | DRM_ERROR("Port %c enabled but PHY powered down? " |
| 1661 | 1662 | "(PHY_CTL %08x)\n", port_name(port), tmp); |
| @@ -12359,7 +12359,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) · 12358 unmodified lines | ||
| 12359 | 12359 | struct drm_crtc_state *old_crtc_state, *new_crtc_state; |
| 12360 | 12360 | struct drm_crtc *crtc; |
| 12361 | 12361 | struct intel_crtc_state *intel_cstate; |
| 12362 | − bool hw_check = intel_state->modeset; | |
| 12363 | 12362 | u64 put_domains[I915_MAX_PIPES] = {}; |
| 12364 | 12363 | unsigned crtc_vblank_mask = 0; |
| 12365 | 12364 | int i; |
| @@ -12376,7 +12375,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) · 10 unmodified lines | ||
| 12376 | 12375 | |
| 12377 | 12376 | if (needs_modeset(new_crtc_state) || |
| 12378 | 12377 | to_intel_crtc_state(new_crtc_state)->update_pipe) { |
| 12379 | − hw_check = true; | |
| 12380 | 12378 | |
| 12381 | 12379 | put_domains[to_intel_crtc(crtc)->pipe] = |
| 12382 | 12380 | modeset_get_crtc_power_domains(crtc, |
| @@ -14030,7 +14028,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, · 1647 unmodified lines | ||
| 14030 | 14028 | |
| 14031 | 14029 | if (mode_cmd->handles[i] != mode_cmd->handles[0]) { |
| 14032 | 14030 | DRM_DEBUG_KMS("bad plane %d handle\n", i); |
| 14033 | − return -EINVAL; | |
| 14031 | + goto err; | |
| 14034 | 14032 | } |
| 14035 | 14033 | |
| 14036 | 14034 | stride_alignment = intel_fb_stride_alignment(fb, i); |
| @@ -208,12 +208,6 @@ static const struct bxt_ddi_phy_info glk_ddi_phy_info[] = { · 207 unmodified lines | ||
| 208 | 208 | }, |
| 209 | 209 | }; |
| 210 | 210 | |
| 211 | −static u32 bxt_phy_port_mask(const struct bxt_ddi_phy_info *phy_info) | |
| 212 | −{ | |
| 213 | − return (phy_info->dual_channel * BIT(phy_info->channel[DPIO_CH1].port)) | | |
| 214 | − BIT(phy_info->channel[DPIO_CH0].port); | |
| 215 | −} | |
| 216 | − | |
| 217 | 211 | static const struct bxt_ddi_phy_info * |
| 218 | 212 | bxt_get_phy_list(struct drm_i915_private *dev_priv, int *count) |
| 219 | 213 | { |
| @@ -313,7 +307,6 @@ bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, · 93 unmodified lines | ||
| 313 | 307 | enum dpio_phy phy) |
| 314 | 308 | { |
| 315 | 309 | const struct bxt_ddi_phy_info *phy_info; |
| 316 | − enum port port; | |
| 317 | 310 | |
| 318 | 311 | phy_info = bxt_get_phy_info(dev_priv, phy); |
| 319 | 312 | |
| @@ -335,19 +328,6 @@ bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, · 15 unmodified lines | ||
| 335 | 328 | return false; |
| 336 | 329 | } |
| 337 | 330 | |
| 338 | − for_each_port_masked(port, bxt_phy_port_mask(phy_info)) { | |
| 339 | − u32 tmp = I915_READ(BXT_PHY_CTL(port)); | |
| 340 | − | |
| 341 | − if (tmp & BXT_PHY_CMNLANE_POWERDOWN_ACK) { | |
| 342 | − DRM_DEBUG_DRIVER("DDI PHY %d powered, but common lane " | |
| 343 | − "for port %c powered down " | |
| 344 | − "(PHY_CTL %08x)\n", | |
| 345 | − phy, port_name(port), tmp); | |
| 346 | − | |
| 347 | − return false; | |
| 348 | − } | |
| 349 | − } | |
| 350 | − | |
| 351 | 331 | return true; |
| 352 | 332 | } |
| 353 | 333 | |
| @@ -892,8 +892,6 @@ static void intel_dsi_disable(struct intel_encoder *encoder, · 891 unmodified lines | ||
| 892 | 892 | struct intel_crtc_state *old_crtc_state, |
| 893 | 893 | struct drm_connector_state *old_conn_state) |
| 894 | 894 | { |
| 895 | − struct drm_device *dev = encoder->base.dev; | |
| 896 | − struct drm_i915_private *dev_priv = dev->dev_private; | |
| 897 | 895 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); |
| 898 | 896 | enum port port; |
| 899 | 897 | |
| @@ -902,15 +900,6 @@ static void intel_dsi_disable(struct intel_encoder *encoder, · 2 unmodified lines | ||
| 902 | 900 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); |
| 903 | 901 | intel_panel_disable_backlight(old_conn_state); |
| 904 | 902 | |
| 905 | − /* | |
| 906 | − * Disable Device ready before the port shutdown in order | |
| 907 | − * to avoid split screen | |
| 908 | − */ | |
| 909 | − if (IS_BROXTON(dev_priv)) { | |
| 910 | − for_each_dsi_port(port, intel_dsi->ports) | |
| 911 | − I915_WRITE(MIPI_DEVICE_READY(port), 0); | |
| 912 | − } | |
| 913 | − | |
| 914 | 903 | /* |
| 915 | 904 | * According to the spec we should send SHUTDOWN before |
| 916 | 905 | * MIPI_SEQ_DISPLAY_OFF only for v3+ VBTs, but field testing |
| @@ -30,6 +30,21 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "intel_drv.h" |
| 31 | 31 | #include "i915_drv.h" |
| 32 | 32 | |
| 33 | +static void intel_connector_update_eld_conn_type(struct drm_connector *connector) | |
| 34 | +{ | |
| 35 | + u8 conn_type; | |
| 36 | + | |
| 37 | + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || | |
| 38 | + connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | |
| 39 | + conn_type = DRM_ELD_CONN_TYPE_DP; | |
| 40 | + } else { | |
| 41 | + conn_type = DRM_ELD_CONN_TYPE_HDMI; | |
| 42 | + } | |
| 43 | + | |
| 44 | + connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] &= ~DRM_ELD_CONN_TYPE_MASK; | |
| 45 | + connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= conn_type; | |
| 46 | +} | |
| 47 | + | |
| 33 | 48 | /** |
| 34 | 49 | * intel_connector_update_modes - update connector from edid |
| 35 | 50 | * @connector: DRM connector device to use |
| @@ -44,6 +59,8 @@ int intel_connector_update_modes(struct drm_connector *connector, · 8 unmodified lines | ||
| 44 | 59 | ret = drm_add_edid_modes(connector, edid); |
| 45 | 60 | drm_edid_to_eld(connector, edid); |
| 46 | 61 | |
| 62 | + intel_connector_update_eld_conn_type(connector); | |
| 63 | + | |
| 47 | 64 | return ret; |
| 48 | 65 | } |
| 49 | 66 | |
| @@ -1699,6 +1699,8 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) · 1698 unmodified lines | ||
| 1699 | 1699 | if (!panel->backlight.max) |
| 1700 | 1700 | return -ENODEV; |
| 1701 | 1701 | |
| 1702 | + panel->backlight.min = get_backlight_min_vbt(connector); | |
| 1703 | + | |
| 1702 | 1704 | val = bxt_get_backlight(connector); |
| 1703 | 1705 | val = intel_panel_compute_brightness(connector, val); |
| 1704 | 1706 | panel->backlight.level = clamp(val, panel->backlight.min, |
| @@ -1735,6 +1737,8 @@ cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) · 30 unmodified lines | ||
| 1735 | 1737 | if (!panel->backlight.max) |
| 1736 | 1738 | return -ENODEV; |
| 1737 | 1739 | |
| 1740 | + panel->backlight.min = get_backlight_min_vbt(connector); | |
| 1741 | + | |
| 1738 | 1742 | val = bxt_get_backlight(connector); |
| 1739 | 1743 | val = intel_panel_compute_brightness(connector, val); |
| 1740 | 1744 | panel->backlight.level = clamp(val, panel->backlight.min, |
| @@ -2782,6 +2782,9 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume · 2781 unmodified lines | ||
| 2782 | 2782 | |
| 2783 | 2783 | /* 6. Enable DBUF */ |
| 2784 | 2784 | gen9_dbuf_enable(dev_priv); |
| 2785 | + | |
| 2786 | + if (resume && dev_priv->csr.dmc_payload) | |
| 2787 | + intel_csr_load_program(dev_priv); | |
| 2785 | 2788 | } |
| 2786 | 2789 | |
| 2787 | 2790 | #undef CNL_PROCMON_IDX |
| @@ -509,23 +509,25 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, · 508 unmodified lines | ||
| 509 | 509 | .y2 = qfb->base.height |
| 510 | 510 | }; |
| 511 | 511 | |
| 512 | − if (!old_state->fb) { | |
| 513 | − qxl_io_log(qdev, | |
| 514 | − "create primary fb: %dx%d,%d,%d\n", | |
| 515 | − bo->surf.width, bo->surf.height, | |
| 516 | − bo->surf.stride, bo->surf.format); | |
| 512 | + if (old_state->fb) { | |
| 513 | + qfb_old = to_qxl_framebuffer(old_state->fb); | |
| 514 | + bo_old = gem_to_qxl_bo(qfb_old->obj); | |
| 515 | + } else { | |
| 516 | + bo_old = NULL; | |
| 517 | + } | |
| 517 | 518 | |
| 518 | − qxl_io_create_primary(qdev, 0, bo); | |
| 519 | − bo->is_primary = true; | |
| 519 | + if (bo == bo_old) | |
| 520 | 520 | return; |
| 521 | 521 | |
| 522 | − } else { | |
| 523 | − qfb_old = to_qxl_framebuffer(old_state->fb); | |
| 524 | − bo_old = gem_to_qxl_bo(qfb_old->obj); | |
| 522 | + if (bo_old && bo_old->is_primary) { | |
| 523 | + qxl_io_destroy_primary(qdev); | |
| 525 | 524 | bo_old->is_primary = false; |
| 526 | 525 | } |
| 527 | 526 | |
| 528 | − bo->is_primary = true; | |
| 527 | + if (!bo->is_primary) { | |
| 528 | + qxl_io_create_primary(qdev, 0, bo); | |
| 529 | + bo->is_primary = true; | |
| 530 | + } | |
| 529 | 531 | qxl_draw_dirty_fb(qdev, qfb, bo, 0, 0, &norect, 1, 1); |
| 530 | 532 | } |
| 531 | 533 | |
| @@ -534,13 +536,15 @@ static void qxl_primary_atomic_disable(struct drm_plane *plane, · 2 unmodified lines | ||
| 534 | 536 | { |
| 535 | 537 | struct qxl_device *qdev = plane->dev->dev_private; |
| 536 | 538 | |
| 537 | − if (old_state->fb) | |
| 538 | − { struct qxl_framebuffer *qfb = | |
| 539 | + if (old_state->fb) { | |
| 540 | + struct qxl_framebuffer *qfb = | |
| 539 | 541 | to_qxl_framebuffer(old_state->fb); |
| 540 | 542 | struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj); |
| 541 | 543 | |
| 542 | − qxl_io_destroy_primary(qdev); | |
| 543 | − bo->is_primary = false; | |
| 544 | + if (bo->is_primary) { | |
| 545 | + qxl_io_destroy_primary(qdev); | |
| 546 | + bo->is_primary = false; | |
| 547 | + } | |
| 544 | 548 | } |
| 545 | 549 | } |
| 546 | 550 | |
| @@ -698,14 +702,15 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane, · 151 unmodified lines | ||
| 698 | 702 | struct drm_gem_object *obj; |
| 699 | 703 | struct qxl_bo *user_bo; |
| 700 | 704 | |
| 701 | − if (!plane->state->fb) { | |
| 702 | − /* we never executed prepare_fb, so there's nothing to | |
| 705 | + if (!old_state->fb) { | |
| 706 | + /* | |
| 707 | + * we never executed prepare_fb, so there's nothing to | |
| 703 | 708 | * unpin. |
| 704 | 709 | */ |
| 705 | 710 | return; |
| 706 | 711 | } |
| 707 | 712 | |
| 708 | − obj = to_qxl_framebuffer(plane->state->fb)->obj; | |
| 713 | + obj = to_qxl_framebuffer(old_state->fb)->obj; | |
| 709 | 714 | user_bo = gem_to_qxl_bo(obj); |
| 710 | 715 | qxl_bo_unpin(user_bo); |
| 711 | 716 | } |
| @@ -1663,7 +1663,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, · 1662 unmodified lines | ||
| 1663 | 1663 | radeon_agp_suspend(rdev); |
| 1664 | 1664 | |
| 1665 | 1665 | pci_save_state(dev->pdev); |
| 1666 | − if (freeze && rdev->family >= CHIP_CEDAR) { | |
| 1666 | + if (freeze && rdev->family >= CHIP_CEDAR && !(rdev->flags & RADEON_IS_IGP)) { | |
| 1667 | 1667 | rdev->asic->asic_reset(rdev, true); |
| 1668 | 1668 | pci_restore_state(dev->pdev); |
| 1669 | 1669 | } else if (suspend) { |
| @@ -26,7 +26,7 @@ config DRM_SUN4I_HDMI_CEC · 25 unmodified lines | ||
| 26 | 26 | bool "Allwinner A10 HDMI CEC Support" |
| 27 | 27 | depends on DRM_SUN4I_HDMI |
| 28 | 28 | select CEC_CORE |
| 29 | − depends on CEC_PIN | |
| 29 | + select CEC_PIN | |
| 30 | 30 | help |
| 31 | 31 | Choose this option if you have an Allwinner SoC with an HDMI |
| 32 | 32 | controller and want to use CEC. |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <drm/drm_connector.h> |
| 16 | 16 | #include <drm/drm_encoder.h> |
| 17 | 17 | |
| 18 | −#include <media/cec.h> | |
| 18 | +#include <media/cec-pin.h> | |
| 19 | 19 | |
| 20 | 20 | #define SUN4I_HDMI_CTRL_REG 0x004 |
| 21 | 21 | #define SUN4I_HDMI_CTRL_ENABLE BIT(31) |
| @@ -302,26 +302,29 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, · 301 unmodified lines | ||
| 302 | 302 | hdmi->mod_clk = devm_clk_get(dev, "mod"); |
| 303 | 303 | if (IS_ERR(hdmi->mod_clk)) { |
| 304 | 304 | dev_err(dev, "Couldn't get the HDMI mod clock\n"); |
| 305 | − return PTR_ERR(hdmi->mod_clk); | |
| 305 | + ret = PTR_ERR(hdmi->mod_clk); | |
| 306 | + goto err_disable_bus_clk; | |
| 306 | 307 | } |
| 307 | 308 | clk_prepare_enable(hdmi->mod_clk); |
| 308 | 309 | |
| 309 | 310 | hdmi->pll0_clk = devm_clk_get(dev, "pll-0"); |
| 310 | 311 | if (IS_ERR(hdmi->pll0_clk)) { |
| 311 | 312 | dev_err(dev, "Couldn't get the HDMI PLL 0 clock\n"); |
| 312 | − return PTR_ERR(hdmi->pll0_clk); | |
| 313 | + ret = PTR_ERR(hdmi->pll0_clk); | |
| 314 | + goto err_disable_mod_clk; | |
| 313 | 315 | } |
| 314 | 316 | |
| 315 | 317 | hdmi->pll1_clk = devm_clk_get(dev, "pll-1"); |
| 316 | 318 | if (IS_ERR(hdmi->pll1_clk)) { |
| 317 | 319 | dev_err(dev, "Couldn't get the HDMI PLL 1 clock\n"); |
| 318 | − return PTR_ERR(hdmi->pll1_clk); | |
| 320 | + ret = PTR_ERR(hdmi->pll1_clk); | |
| 321 | + goto err_disable_mod_clk; | |
| 319 | 322 | } |
| 320 | 323 | |
| 321 | 324 | ret = sun4i_tmds_create(hdmi); |
| 322 | 325 | if (ret) { |
| 323 | 326 | dev_err(dev, "Couldn't create the TMDS clock\n"); |
| 324 | − return ret; | |
| 327 | + goto err_disable_mod_clk; | |
| 325 | 328 | } |
| 326 | 329 | |
| 327 | 330 | writel(SUN4I_HDMI_CTRL_ENABLE, hdmi->base + SUN4I_HDMI_CTRL_REG); |
| @@ -362,7 +365,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, · 34 unmodified lines | ||
| 362 | 365 | ret = sun4i_hdmi_i2c_create(dev, hdmi); |
| 363 | 366 | if (ret) { |
| 364 | 367 | dev_err(dev, "Couldn't create the HDMI I2C adapter\n"); |
| 365 | − return ret; | |
| 368 | + goto err_disable_mod_clk; | |
| 366 | 369 | } |
| 367 | 370 | |
| 368 | 371 | drm_encoder_helper_add(&hdmi->encoder, |
| @@ -422,6 +425,10 @@ err_cleanup_connector: · 53 unmodified lines | ||
| 422 | 425 | drm_encoder_cleanup(&hdmi->encoder); |
| 423 | 426 | err_del_i2c_adapter: |
| 424 | 427 | i2c_del_adapter(hdmi->i2c); |
| 428 | +err_disable_mod_clk: | |
| 429 | + clk_disable_unprepare(hdmi->mod_clk); | |
| 430 | +err_disable_bus_clk: | |
| 431 | + clk_disable_unprepare(hdmi->bus_clk); | |
| 425 | 432 | return ret; |
| 426 | 433 | } |
| 427 | 434 | |
| @@ -434,6 +441,8 @@ static void sun4i_hdmi_unbind(struct device *dev, struct device *master, · 6 unmodified lines | ||
| 434 | 441 | drm_connector_cleanup(&hdmi->connector); |
| 435 | 442 | drm_encoder_cleanup(&hdmi->encoder); |
| 436 | 443 | i2c_del_adapter(hdmi->i2c); |
| 444 | + clk_disable_unprepare(hdmi->mod_clk); | |
| 445 | + clk_disable_unprepare(hdmi->bus_clk); | |
| 437 | 446 | } |
| 438 | 447 | |
| 439 | 448 | static const struct component_ops sun4i_hdmi_ops = { |
| @@ -63,6 +63,6 @@ DEFINE_EVENT(register_access, sor_readl, · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | /* This part must be outside protection */ |
| 65 | 65 | #undef TRACE_INCLUDE_PATH |
| 66 | −#define TRACE_INCLUDE_PATH . | |
| 66 | +#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/tegra | |
| 67 | 67 | #define TRACE_INCLUDE_FILE trace |
| 68 | 68 | #include <trace/define_trace.h> |
| @@ -533,6 +533,7 @@ · 532 unmodified lines | ||
| 533 | 533 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 |
| 534 | 534 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 |
| 535 | 535 | #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 |
| 536 | +#define USB_DEVICE_ID_IDEACOM_IDC6680 0x6680 | |
| 536 | 537 | |
| 537 | 538 | #define USB_VENDOR_ID_ILITEK 0x222a |
| 538 | 539 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 |
| @@ -660,6 +661,7 @@ · 121 unmodified lines | ||
| 660 | 661 | #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 |
| 661 | 662 | #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 |
| 662 | 663 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 |
| 664 | +#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 | |
| 663 | 665 | |
| 664 | 666 | #define USB_VENDOR_ID_LG 0x1fd2 |
| 665 | 667 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 |
| @@ -930,6 +930,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 929 unmodified lines | ||
| 930 | 930 | field->application != HID_DG_PEN && |
| 931 | 931 | field->application != HID_DG_TOUCHPAD && |
| 932 | 932 | field->application != HID_GD_KEYBOARD && |
| 933 | + field->application != HID_GD_SYSTEM_CONTROL && | |
| 933 | 934 | field->application != HID_CP_CONSUMER_CONTROL && |
| 934 | 935 | field->application != HID_GD_WIRELESS_RADIO_CTLS && |
| 935 | 936 | !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && |
| @@ -1419,6 +1420,12 @@ static const struct hid_device_id mt_devices[] = { · 483 unmodified lines | ||
| 1419 | 1420 | USB_VENDOR_ID_ALPS_JP, |
| 1420 | 1421 | HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, |
| 1421 | 1422 | |
| 1423 | + /* Lenovo X1 TAB Gen 2 */ | |
| 1424 | + { .driver_data = MT_CLS_WIN_8_DUAL, | |
| 1425 | + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, | |
| 1426 | + USB_VENDOR_ID_LENOVO, | |
| 1427 | + USB_DEVICE_ID_LENOVO_X1_TAB) }, | |
| 1428 | + | |
| 1422 | 1429 | /* Anton devices */ |
| 1423 | 1430 | { .driver_data = MT_CLS_EXPORT_ALL_INPUTS, |
| 1424 | 1431 | MT_USB_DEVICE(USB_VENDOR_ID_ANTON, |
| @@ -436,17 +436,24 @@ static int rmi_post_resume(struct hid_device *hdev) · 435 unmodified lines | ||
| 436 | 436 | if (!(data->device_flags & RMI_DEVICE)) |
| 437 | 437 | return 0; |
| 438 | 438 | |
| 439 | − ret = rmi_reset_attn_mode(hdev); | |
| 439 | + /* Make sure the HID device is ready to receive events */ | |
| 440 | + ret = hid_hw_open(hdev); | |
| 440 | 441 | if (ret) |
| 441 | 442 | return ret; |
| 442 | 443 | |
| 444 | + ret = rmi_reset_attn_mode(hdev); | |
| 445 | + if (ret) | |
| 446 | + goto out; | |
| 447 | + | |
| 443 | 448 | ret = rmi_driver_resume(rmi_dev, false); |
| 444 | 449 | if (ret) { |
| 445 | 450 | hid_warn(hdev, "Failed to resume device: %d\n", ret); |
| 446 | − return ret; | |
| 451 | + goto out; | |
| 447 | 452 | } |
| 448 | 453 | |
| 449 | − return 0; | |
| 454 | +out: | |
| 455 | + hid_hw_close(hdev); | |
| 456 | + return ret; | |
| 450 | 457 | } |
| 451 | 458 | #endif /* CONFIG_PM */ |
| 452 | 459 | |
| @@ -337,8 +337,8 @@ static void drop_ref(struct hidraw *hidraw, int exists_bit) · 336 unmodified lines | ||
| 337 | 337 | kfree(hidraw); |
| 338 | 338 | } else { |
| 339 | 339 | /* close device for last reader */ |
| 340 | − hid_hw_power(hidraw->hid, PM_HINT_NORMAL); | |
| 341 | 340 | hid_hw_close(hidraw->hid); |
| 341 | + hid_hw_power(hidraw->hid, PM_HINT_NORMAL); | |
| 342 | 342 | } |
| 343 | 343 | } |
| 344 | 344 | } |
| @@ -543,7 +543,8 @@ static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size) · 542 unmodified lines | ||
| 543 | 543 | { |
| 544 | 544 | /* the worst case is computed from the set_report command with a |
| 545 | 545 | * reportID > 15 and the maximum report length */ |
| 546 | − int args_len = sizeof(__u8) + /* optional ReportID byte */ | |
| 546 | + int args_len = sizeof(__u8) + /* ReportID */ | |
| 547 | + sizeof(__u8) + /* optional ReportID byte */ | |
| 547 | 548 | sizeof(__u16) + /* data register */ |
| 548 | 549 | sizeof(__u16) + /* size of the report */ |
| 549 | 550 | report_size; /* report */ |
| @@ -99,6 +99,7 @@ static const struct hid_blacklist { · 98 unmodified lines | ||
| 99 | 99 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, |
| 100 | 100 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, |
| 101 | 101 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, |
| 102 | + { USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680, HID_QUIRK_MULTI_INPUT }, | |
| 102 | 103 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007, HID_QUIRK_ALWAYS_POLL }, |
| 103 | 104 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, |
| 104 | 105 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET }, |
| @@ -668,8 +668,10 @@ static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev) · 667 unmodified lines | ||
| 668 | 668 | |
| 669 | 669 | /* Try to find an already-probed interface from the same device */ |
| 670 | 670 | list_for_each_entry(data, &wacom_udev_list, list) { |
| 671 | − if (compare_device_paths(hdev, data->dev, '/')) | |
| 671 | + if (compare_device_paths(hdev, data->dev, '/')) { | |
| 672 | + kref_get(&data->kref); | |
| 672 | 673 | return data; |
| 674 | + } | |
| 673 | 675 | } |
| 674 | 676 | |
| 675 | 677 | /* Fallback to finding devices that appear to be "siblings" */ |
| @@ -766,6 +768,9 @@ static int wacom_led_control(struct wacom *wacom) · 90 unmodified lines | ||
| 766 | 768 | if (!wacom->led.groups) |
| 767 | 769 | return -ENOTSUPP; |
| 768 | 770 | |
| 771 | + if (wacom->wacom_wac.features.type == REMOTE) | |
| 772 | + return -ENOTSUPP; | |
| 773 | + | |
| 769 | 774 | if (wacom->wacom_wac.pid) { /* wireless connected */ |
| 770 | 775 | report_id = WAC_CMD_WL_LED_CONTROL; |
| 771 | 776 | buf_size = 13; |
| @@ -567,8 +567,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) · 566 unmodified lines | ||
| 567 | 567 | keys = data[9] & 0x07; |
| 568 | 568 | } |
| 569 | 569 | } else { |
| 570 | − buttons = ((data[6] & 0x10) << 10) | | |
| 571 | − ((data[5] & 0x10) << 9) | | |
| 570 | + buttons = ((data[6] & 0x10) << 5) | | |
| 571 | + ((data[5] & 0x10) << 4) | | |
| 572 | 572 | ((data[6] & 0x0F) << 4) | |
| 573 | 573 | (data[5] & 0x0F); |
| 574 | 574 | } |
| @@ -1227,11 +1227,17 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) · 652 unmodified lines | ||
| 1227 | 1227 | continue; |
| 1228 | 1228 | |
| 1229 | 1229 | if (range) { |
| 1230 | + /* Fix rotation alignment: userspace expects zero at left */ | |
| 1231 | + int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]); | |
| 1232 | + rotation += 1800/4; | |
| 1233 | + if (rotation > 899) | |
| 1234 | + rotation -= 1800; | |
| 1235 | + | |
| 1230 | 1236 | input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); |
| 1231 | 1237 | input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); |
| 1232 | − input_report_abs(pen_input, ABS_TILT_X, frame[7]); | |
| 1233 | − input_report_abs(pen_input, ABS_TILT_Y, frame[8]); | |
| 1234 | − input_report_abs(pen_input, ABS_Z, get_unaligned_le16(&frame[9])); | |
| 1238 | + input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]); | |
| 1239 | + input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]); | |
| 1240 | + input_report_abs(pen_input, ABS_Z, rotation); | |
| 1235 | 1241 | input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); |
| 1236 | 1242 | } |
| 1237 | 1243 | input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); |
| @@ -1319,12 +1325,19 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom) · 81 unmodified lines | ||
| 1319 | 1325 | unsigned char *data = wacom->data; |
| 1320 | 1326 | |
| 1321 | 1327 | int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01); |
| 1322 | − int ring = data[285]; | |
| 1323 | − int prox = buttons | (ring & 0x80); | |
| 1328 | + int ring = data[285] & 0x7F; | |
| 1329 | + bool ringstatus = data[285] & 0x80; | |
| 1330 | + bool prox = buttons || ringstatus; | |
| 1331 | + | |
| 1332 | + /* Fix touchring data: userspace expects 0 at left and increasing clockwise */ | |
| 1333 | + ring = 71 - ring; | |
| 1334 | + ring += 3*72/16; | |
| 1335 | + if (ring > 71) | |
| 1336 | + ring -= 72; | |
| 1324 | 1337 | |
| 1325 | 1338 | wacom_report_numbered_buttons(pad_input, 9, buttons); |
| 1326 | 1339 | |
| 1327 | − input_report_abs(pad_input, ABS_WHEEL, (ring & 0x80) ? (ring & 0x7f) : 0); | |
| 1340 | + input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0); | |
| 1328 | 1341 | |
| 1329 | 1342 | input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0); |
| 1330 | 1343 | input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); |
| @@ -1616,6 +1629,20 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) · 285 unmodified lines | ||
| 1616 | 1629 | return 0; |
| 1617 | 1630 | } |
| 1618 | 1631 | |
| 1632 | +static int wacom_offset_rotation(struct input_dev *input, struct hid_usage *usage, | |
| 1633 | + int value, int num, int denom) | |
| 1634 | +{ | |
| 1635 | + struct input_absinfo *abs = &input->absinfo[usage->code]; | |
| 1636 | + int range = (abs->maximum - abs->minimum + 1); | |
| 1637 | + | |
| 1638 | + value += num*range/denom; | |
| 1639 | + if (value > abs->maximum) | |
| 1640 | + value -= range; | |
| 1641 | + else if (value < abs->minimum) | |
| 1642 | + value += range; | |
| 1643 | + return value; | |
| 1644 | +} | |
| 1645 | + | |
| 1619 | 1646 | int wacom_equivalent_usage(int usage) |
| 1620 | 1647 | { |
| 1621 | 1648 | if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) { |
| @@ -1898,6 +1925,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field · 276 unmodified lines | ||
| 1898 | 1925 | unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); |
| 1899 | 1926 | int i; |
| 1900 | 1927 | bool is_touch_on = value; |
| 1928 | + bool do_report = false; | |
| 1901 | 1929 | |
| 1902 | 1930 | /* |
| 1903 | 1931 | * Avoid reporting this event and setting inrange_state if this usage |
| @@ -1912,6 +1940,29 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field · 8 unmodified lines | ||
| 1912 | 1940 | } |
| 1913 | 1941 | |
| 1914 | 1942 | switch (equivalent_usage) { |
| 1943 | + case WACOM_HID_WD_TOUCHRING: | |
| 1944 | + /* | |
| 1945 | + * Userspace expects touchrings to increase in value with | |
| 1946 | + * clockwise gestures and have their zero point at the | |
| 1947 | + * tablet's left. HID events "should" be clockwise- | |
| 1948 | + * increasing and zero at top, though the MobileStudio | |
| 1949 | + * Pro and 2nd-gen Intuos Pro don't do this... | |
| 1950 | + */ | |
| 1951 | + if (hdev->vendor == 0x56a && | |
| 1952 | + (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ | |
| 1953 | + hdev->product == 0x357 || hdev->product == 0x358)) { /* Intuos Pro 2 */ | |
| 1954 | + value = (field->logical_maximum - value); | |
| 1955 | + | |
| 1956 | + if (hdev->product == 0x357 || hdev->product == 0x358) | |
| 1957 | + value = wacom_offset_rotation(input, usage, value, 3, 16); | |
| 1958 | + else if (hdev->product == 0x34d || hdev->product == 0x34e) | |
| 1959 | + value = wacom_offset_rotation(input, usage, value, 1, 2); | |
| 1960 | + } | |
| 1961 | + else { | |
| 1962 | + value = wacom_offset_rotation(input, usage, value, 1, 4); | |
| 1963 | + } | |
| 1964 | + do_report = true; | |
| 1965 | + break; | |
| 1915 | 1966 | case WACOM_HID_WD_TOUCHRINGSTATUS: |
| 1916 | 1967 | if (!value) |
| 1917 | 1968 | input_event(input, usage->type, usage->code, 0); |
| @@ -1945,10 +1996,14 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field · 27 unmodified lines | ||
| 1945 | 1996 | value, i); |
| 1946 | 1997 | /* fall through*/ |
| 1947 | 1998 | default: |
| 1999 | + do_report = true; | |
| 2000 | + break; | |
| 2001 | + } | |
| 2002 | + | |
| 2003 | + if (do_report) { | |
| 1948 | 2004 | input_event(input, usage->type, usage->code, value); |
| 1949 | 2005 | if (value) |
| 1950 | 2006 | wacom_wac->hid_data.pad_input_event_flag = true; |
| 1951 | − break; | |
| 1952 | 2007 | } |
| 1953 | 2008 | } |
| 1954 | 2009 | |
| @@ -2086,22 +2141,34 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field · 131 unmodified lines | ||
| 2086 | 2141 | wacom_wac->hid_data.tipswitch |= value; |
| 2087 | 2142 | return; |
| 2088 | 2143 | case HID_DG_TOOLSERIALNUMBER: |
| 2089 | − wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); | |
| 2090 | − wacom_wac->serial[0] |= (__u32)value; | |
| 2144 | + if (value) { | |
| 2145 | + wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); | |
| 2146 | + wacom_wac->serial[0] |= (__u32)value; | |
| 2147 | + } | |
| 2091 | 2148 | return; |
| 2149 | + case HID_DG_TWIST: | |
| 2150 | + /* | |
| 2151 | + * Userspace expects pen twist to have its zero point when | |
| 2152 | + * the buttons/finger is on the tablet's left. HID values | |
| 2153 | + * are zero when buttons are toward the top. | |
| 2154 | + */ | |
| 2155 | + value = wacom_offset_rotation(input, usage, value, 1, 4); | |
| 2156 | + break; | |
| 2092 | 2157 | case WACOM_HID_WD_SENSE: |
| 2093 | 2158 | wacom_wac->hid_data.sense_state = value; |
| 2094 | 2159 | return; |
| 2095 | 2160 | case WACOM_HID_WD_SERIALHI: |
| 2096 | − wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); | |
| 2097 | − wacom_wac->serial[0] |= ((__u64)value) << 32; | |
| 2098 | − /* | |
| 2099 | − * Non-USI EMR devices may contain additional tool type | |
| 2100 | − * information here. See WACOM_HID_WD_TOOLTYPE case for | |
| 2101 | − * more details. | |
| 2102 | − */ | |
| 2103 | − if (value >> 20 == 1) { | |
| 2104 | − wacom_wac->id[0] |= value & 0xFFFFF; | |
| 2161 | + if (value) { | |
| 2162 | + wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); | |
| 2163 | + wacom_wac->serial[0] |= ((__u64)value) << 32; | |
| 2164 | + /* | |
| 2165 | + * Non-USI EMR devices may contain additional tool type | |
| 2166 | + * information here. See WACOM_HID_WD_TOOLTYPE case for | |
| 2167 | + * more details. | |
| 2168 | + */ | |
| 2169 | + if (value >> 20 == 1) { | |
| 2170 | + wacom_wac->id[0] |= value & 0xFFFFF; | |
| 2171 | + } | |
| 2105 | 2172 | } |
| 2106 | 2173 | return; |
| 2107 | 2174 | case WACOM_HID_WD_TOOLTYPE: |
| @@ -2205,7 +2272,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, · 97 unmodified lines | ||
| 2205 | 2272 | input_report_key(input, wacom_wac->tool[0], prox); |
| 2206 | 2273 | if (wacom_wac->serial[0]) { |
| 2207 | 2274 | input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); |
| 2208 | − input_report_abs(input, ABS_MISC, id); | |
| 2275 | + input_report_abs(input, ABS_MISC, prox ? id : 0); | |
| 2209 | 2276 | } |
| 2210 | 2277 | |
| 2211 | 2278 | wacom_wac->hid_data.tipswitch = false; |
| @@ -2216,6 +2283,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, · 4 unmodified lines | ||
| 2216 | 2283 | if (!prox) { |
| 2217 | 2284 | wacom_wac->tool[0] = 0; |
| 2218 | 2285 | wacom_wac->id[0] = 0; |
| 2286 | + wacom_wac->serial[0] = 0; | |
| 2219 | 2287 | } |
| 2220 | 2288 | } |
| 2221 | 2289 | |
| @@ -936,14 +936,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) · 935 unmodified lines | ||
| 936 | 936 | |
| 937 | 937 | void vmbus_hvsock_device_unregister(struct vmbus_channel *channel) |
| 938 | 938 | { |
| 939 | − mutex_lock(&vmbus_connection.channel_mutex); | |
| 940 | − | |
| 941 | 939 | BUG_ON(!is_hvsock_channel(channel)); |
| 942 | 940 | |
| 943 | 941 | channel->rescind = true; |
| 944 | 942 | vmbus_device_unregister(channel->device_obj); |
| 945 | − | |
| 946 | − mutex_unlock(&vmbus_connection.channel_mutex); | |
| 947 | 943 | } |
| 948 | 944 | EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister); |
| 949 | 945 | |
| @@ -170,6 +170,10 @@ static void fcopy_send_data(struct work_struct *dummy) · 169 unmodified lines | ||
| 170 | 170 | out_src = smsg_out; |
| 171 | 171 | break; |
| 172 | 172 | |
| 173 | + case WRITE_TO_FILE: | |
| 174 | + out_src = fcopy_transaction.fcopy_msg; | |
| 175 | + out_len = sizeof(struct hv_do_fcopy); | |
| 176 | + break; | |
| 173 | 177 | default: |
| 174 | 178 | out_src = fcopy_transaction.fcopy_msg; |
| 175 | 179 | out_len = fcopy_transaction.recv_len; |
| @@ -630,7 +630,7 @@ static int xgene_hwmon_probe(struct platform_device *pdev) · 629 unmodified lines | ||
| 630 | 630 | sizeof(struct slimpro_resp_msg) * ASYNC_MSG_FIFO_SIZE, |
| 631 | 631 | GFP_KERNEL); |
| 632 | 632 | if (rc) |
| 633 | − goto out_mbox_free; | |
| 633 | + return -ENOMEM; | |
| 634 | 634 | |
| 635 | 635 | INIT_WORK(&ctx->workq, xgene_hwmon_evt_work); |
| 636 | 636 | |
| @@ -646,7 +646,8 @@ static int xgene_hwmon_probe(struct platform_device *pdev) · 9 unmodified lines | ||
| 646 | 646 | if (IS_ERR(ctx->mbox_chan)) { |
| 647 | 647 | dev_err(&pdev->dev, |
| 648 | 648 | "SLIMpro mailbox channel request failed\n"); |
| 649 | − return -ENODEV; | |
| 649 | + rc = -ENODEV; | |
| 650 | + goto out_mbox_free; | |
| 650 | 651 | } |
| 651 | 652 | } else { |
| 652 | 653 | struct acpi_pcct_hw_reduced *cppc_ss; |
| @@ -654,7 +655,8 @@ static int xgene_hwmon_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 654 | 655 | if (device_property_read_u32(&pdev->dev, "pcc-channel", |
| 655 | 656 | &ctx->mbox_idx)) { |
| 656 | 657 | dev_err(&pdev->dev, "no pcc-channel property\n"); |
| 657 | − return -ENODEV; | |
| 658 | + rc = -ENODEV; | |
| 659 | + goto out_mbox_free; | |
| 658 | 660 | } |
| 659 | 661 | |
| 660 | 662 | cl->rx_callback = xgene_hwmon_pcc_rx_cb; |
| @@ -662,7 +664,8 @@ static int xgene_hwmon_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 662 | 664 | if (IS_ERR(ctx->mbox_chan)) { |
| 663 | 665 | dev_err(&pdev->dev, |
| 664 | 666 | "PPC channel request failed\n"); |
| 665 | − return -ENODEV; | |
| 667 | + rc = -ENODEV; | |
| 668 | + goto out_mbox_free; | |
| 666 | 669 | } |
| 667 | 670 | |
| 668 | 671 | /* |
| @@ -675,13 +678,13 @@ static int xgene_hwmon_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 675 | 678 | if (!cppc_ss) { |
| 676 | 679 | dev_err(&pdev->dev, "PPC subspace not found\n"); |
| 677 | 680 | rc = -ENODEV; |
| 678 | − goto out_mbox_free; | |
| 681 | + goto out; | |
| 679 | 682 | } |
| 680 | 683 | |
| 681 | 684 | if (!ctx->mbox_chan->mbox->txdone_irq) { |
| 682 | 685 | dev_err(&pdev->dev, "PCC IRQ not supported\n"); |
| 683 | 686 | rc = -ENODEV; |
| 684 | − goto out_mbox_free; | |
| 687 | + goto out; | |
| 685 | 688 | } |
| 686 | 689 | |
| 687 | 690 | /* |
| @@ -696,14 +699,14 @@ static int xgene_hwmon_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 696 | 699 | } else { |
| 697 | 700 | dev_err(&pdev->dev, "Failed to get PCC comm region\n"); |
| 698 | 701 | rc = -ENODEV; |
| 699 | − goto out_mbox_free; | |
| 702 | + goto out; | |
| 700 | 703 | } |
| 701 | 704 | |
| 702 | 705 | if (!ctx->pcc_comm_addr) { |
| 703 | 706 | dev_err(&pdev->dev, |
| 704 | 707 | "Failed to ioremap PCC comm region\n"); |
| 705 | 708 | rc = -ENOMEM; |
| 706 | − goto out_mbox_free; | |
| 709 | + goto out; | |
| 707 | 710 | } |
| 708 | 711 | |
| 709 | 712 | /* |
| @@ -143,6 +143,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { · 142 unmodified lines | ||
| 143 | 143 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1), |
| 144 | 144 | .driver_data = (kernel_ulong_t)0, |
| 145 | 145 | }, |
| 146 | + { | |
| 147 | + /* Lewisburg PCH */ | |
| 148 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6), | |
| 149 | + .driver_data = (kernel_ulong_t)0, | |
| 150 | + }, | |
| 146 | 151 | { |
| 147 | 152 | /* Gemini Lake */ |
| 148 | 153 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), |
| @@ -158,6 +163,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { · 9 unmodified lines | ||
| 158 | 163 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), |
| 159 | 164 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
| 160 | 165 | }, |
| 166 | + { | |
| 167 | + /* Cedar Fork PCH */ | |
| 168 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1), | |
| 169 | + .driver_data = (kernel_ulong_t)&intel_th_2x, | |
| 170 | + }, | |
| 161 | 171 | { 0 }, |
| 162 | 172 | }; |
| 163 | 173 | |
| @@ -1119,7 +1119,7 @@ void stm_source_unregister_device(struct stm_source_data *data) · 1118 unmodified lines | ||
| 1119 | 1119 | |
| 1120 | 1120 | stm_source_link_drop(src); |
| 1121 | 1121 | |
| 1122 | − device_destroy(&stm_source_class, src->dev.devt); | |
| 1122 | + device_unregister(&src->dev); | |
| 1123 | 1123 | } |
| 1124 | 1124 | EXPORT_SYMBOL_GPL(stm_source_unregister_device); |
| 1125 | 1125 | |
| @@ -131,6 +131,7 @@ config I2C_I801 · 130 unmodified lines | ||
| 131 | 131 | Gemini Lake (SOC) |
| 132 | 132 | Cannon Lake-H (PCH) |
| 133 | 133 | Cannon Lake-LP (PCH) |
| 134 | + Cedar Fork (PCH) | |
| 134 | 135 | |
| 135 | 136 | This driver can also be built as a module. If so, the module |
| 136 | 137 | will be called i2c-i801. |
| @@ -68,6 +68,7 @@ · 67 unmodified lines | ||
| 68 | 68 | * Gemini Lake (SOC) 0x31d4 32 hard yes yes yes |
| 69 | 69 | * Cannon Lake-H (PCH) 0xa323 32 hard yes yes yes |
| 70 | 70 | * Cannon Lake-LP (PCH) 0x9da3 32 hard yes yes yes |
| 71 | + * Cedar Fork (PCH) 0x18df 32 hard yes yes yes | |
| 71 | 72 | * |
| 72 | 73 | * Features supported by this driver: |
| 73 | 74 | * Software PEC no |
| @@ -204,6 +205,7 @@ · 130 unmodified lines | ||
| 204 | 205 | |
| 205 | 206 | /* Older devices have their ID defined in <linux/pci_ids.h> */ |
| 206 | 207 | #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 |
| 208 | +#define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df | |
| 207 | 209 | #define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df |
| 208 | 210 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 |
| 209 | 211 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 |
| @@ -1025,6 +1027,7 @@ static const struct pci_device_id i801_ids[] = { · 815 unmodified lines | ||
| 1025 | 1027 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) }, |
| 1026 | 1028 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS) }, |
| 1027 | 1029 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS) }, |
| 1030 | + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CDF_SMBUS) }, | |
| 1028 | 1031 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMBUS) }, |
| 1029 | 1032 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) }, |
| 1030 | 1033 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) }, |
| @@ -1513,6 +1516,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) · 482 unmodified lines | ||
| 1513 | 1516 | case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS: |
| 1514 | 1517 | case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS: |
| 1515 | 1518 | case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS: |
| 1519 | + case PCI_DEVICE_ID_INTEL_CDF_SMBUS: | |
| 1516 | 1520 | case PCI_DEVICE_ID_INTEL_DNV_SMBUS: |
| 1517 | 1521 | case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS: |
| 1518 | 1522 | priv->features |= FEATURE_I2C_BLOCK_READ; |
| @@ -1459,6 +1459,6 @@ static struct platform_driver img_scb_i2c_driver = { · 1458 unmodified lines | ||
| 1459 | 1459 | }; |
| 1460 | 1460 | module_platform_driver(img_scb_i2c_driver); |
| 1461 | 1461 | |
| 1462 | −MODULE_AUTHOR("James Hogan <james.hogan@imgtec.com>"); | |
| 1462 | +MODULE_AUTHOR("James Hogan <jhogan@kernel.org>"); | |
| 1463 | 1463 | MODULE_DESCRIPTION("IMG host I2C driver"); |
| 1464 | 1464 | MODULE_LICENSE("GPL v2"); |
| @@ -627,6 +627,7 @@ static const struct dev_pm_ops sprd_i2c_pm_ops = { · 626 unmodified lines | ||
| 627 | 627 | |
| 628 | 628 | static const struct of_device_id sprd_i2c_of_match[] = { |
| 629 | 629 | { .compatible = "sprd,sc9860-i2c", }, |
| 630 | + {}, | |
| 630 | 631 | }; |
| 631 | 632 | |
| 632 | 633 | static struct platform_driver sprd_i2c_driver = { |
| @@ -215,7 +215,7 @@ struct stm32f7_i2c_dev { · 214 unmodified lines | ||
| 215 | 215 | unsigned int msg_num; |
| 216 | 216 | unsigned int msg_id; |
| 217 | 217 | struct stm32f7_i2c_msg f7_msg; |
| 218 | − struct stm32f7_i2c_setup *setup; | |
| 218 | + struct stm32f7_i2c_setup setup; | |
| 219 | 219 | struct stm32f7_i2c_timings timing; |
| 220 | 220 | }; |
| 221 | 221 | |
| @@ -265,7 +265,7 @@ static struct stm32f7_i2c_spec i2c_specs[] = { · 43 unmodified lines | ||
| 265 | 265 | }, |
| 266 | 266 | }; |
| 267 | 267 | |
| 268 | −struct stm32f7_i2c_setup stm32f7_setup = { | |
| 268 | +static const struct stm32f7_i2c_setup stm32f7_setup = { | |
| 269 | 269 | .rise_time = STM32F7_I2C_RISE_TIME_DEFAULT, |
| 270 | 270 | .fall_time = STM32F7_I2C_FALL_TIME_DEFAULT, |
| 271 | 271 | .dnf = STM32F7_I2C_DNF_DEFAULT, |
| @@ -537,7 +537,7 @@ static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev *i2c_dev) · 265 unmodified lines | ||
| 537 | 537 | writel_relaxed(timing, i2c_dev->base + STM32F7_I2C_TIMINGR); |
| 538 | 538 | |
| 539 | 539 | /* Enable I2C */ |
| 540 | − if (i2c_dev->setup->analog_filter) | |
| 540 | + if (i2c_dev->setup.analog_filter) | |
| 541 | 541 | stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, |
| 542 | 542 | STM32F7_I2C_CR1_ANFOFF); |
| 543 | 543 | else |
| @@ -887,22 +887,19 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) · 343 unmodified lines | ||
| 887 | 887 | } |
| 888 | 888 | |
| 889 | 889 | setup = of_device_get_match_data(&pdev->dev); |
| 890 | − i2c_dev->setup->rise_time = setup->rise_time; | |
| 891 | − i2c_dev->setup->fall_time = setup->fall_time; | |
| 892 | − i2c_dev->setup->dnf = setup->dnf; | |
| 893 | − i2c_dev->setup->analog_filter = setup->analog_filter; | |
| 890 | + i2c_dev->setup = *setup; | |
| 894 | 891 | |
| 895 | 892 | ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-rising-time-ns", |
| 896 | 893 | &rise_time); |
| 897 | 894 | if (!ret) |
| 898 | − i2c_dev->setup->rise_time = rise_time; | |
| 895 | + i2c_dev->setup.rise_time = rise_time; | |
| 899 | 896 | |
| 900 | 897 | ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-falling-time-ns", |
| 901 | 898 | &fall_time); |
| 902 | 899 | if (!ret) |
| 903 | − i2c_dev->setup->fall_time = fall_time; | |
| 900 | + i2c_dev->setup.fall_time = fall_time; | |
| 904 | 901 | |
| 905 | − ret = stm32f7_i2c_setup_timing(i2c_dev, i2c_dev->setup); | |
| 902 | + ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup); | |
| 906 | 903 | if (ret) |
| 907 | 904 | goto clk_free; |
| 908 | 905 | |
| @@ -1451,6 +1451,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, · 1450 unmodified lines | ||
| 1451 | 1451 | if (hwif_init(hwif) == 0) { |
| 1452 | 1452 | printk(KERN_INFO "%s: failed to initialize IDE " |
| 1453 | 1453 | "interface\n", hwif->name); |
| 1454 | + device_unregister(hwif->portdev); | |
| 1454 | 1455 | device_unregister(&hwif->gendev); |
| 1455 | 1456 | ide_disable_port(hwif); |
| 1456 | 1457 | continue; |
| @@ -56,6 +56,7 @@ static int __init ide_scan_pcidev(struct pci_dev *dev) · 55 unmodified lines | ||
| 56 | 56 | { |
| 57 | 57 | struct list_head *l; |
| 58 | 58 | struct pci_driver *d; |
| 59 | + int ret; | |
| 59 | 60 | |
| 60 | 61 | list_for_each(l, &ide_pci_drivers) { |
| 61 | 62 | d = list_entry(l, struct pci_driver, node); |
| @@ -63,10 +64,14 @@ static int __init ide_scan_pcidev(struct pci_dev *dev) · 1 unmodified line | ||
| 63 | 64 | const struct pci_device_id *id = |
| 64 | 65 | pci_match_id(d->id_table, dev); |
| 65 | 66 | |
| 66 | − if (id != NULL && d->probe(dev, id) >= 0) { | |
| 67 | − dev->driver = d; | |
| 68 | − pci_dev_get(dev); | |
| 69 | − return 1; | |
| 67 | + if (id != NULL) { | |
| 68 | + pci_assign_irq(dev); | |
| 69 | + ret = d->probe(dev, id); | |
| 70 | + if (ret >= 0) { | |
| 71 | + dev->driver = d; | |
| 72 | + pci_dev_get(dev); | |
| 73 | + return 1; | |
| 74 | + } | |
| 70 | 75 | } |
| 71 | 76 | } |
| 72 | 77 | } |
| @@ -179,6 +179,7 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); · 178 unmodified lines | ||
| 179 | 179 | /** |
| 180 | 180 | * ide_pci_enable - do PCI enables |
| 181 | 181 | * @dev: PCI device |
| 182 | + * @bars: PCI BARs mask | |
| 182 | 183 | * @d: IDE port info |
| 183 | 184 | * |
| 184 | 185 | * Enable the IDE PCI device. We attempt to enable the device in full |
| @@ -189,9 +190,10 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); · 4 unmodified lines | ||
| 189 | 190 | * Returns zero on success or an error code |
| 190 | 191 | */ |
| 191 | 192 | |
| 192 | −static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d) | |
| 193 | +static int ide_pci_enable(struct pci_dev *dev, int bars, | |
| 194 | + const struct ide_port_info *d) | |
| 193 | 195 | { |
| 194 | − int ret, bars; | |
| 196 | + int ret; | |
| 195 | 197 | |
| 196 | 198 | if (pci_enable_device(dev)) { |
| 197 | 199 | ret = pci_enable_device_io(dev); |
| @@ -216,18 +218,6 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d) · 18 unmodified lines | ||
| 216 | 218 | goto out; |
| 217 | 219 | } |
| 218 | 220 | |
| 219 | − if (d->host_flags & IDE_HFLAG_SINGLE) | |
| 220 | − bars = (1 << 2) - 1; | |
| 221 | − else | |
| 222 | − bars = (1 << 4) - 1; | |
| 223 | − | |
| 224 | − if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { | |
| 225 | − if (d->host_flags & IDE_HFLAG_CS5520) | |
| 226 | − bars |= (1 << 2); | |
| 227 | − else | |
| 228 | − bars |= (1 << 4); | |
| 229 | − } | |
| 230 | − | |
| 231 | 221 | ret = pci_request_selected_regions(dev, bars, d->name); |
| 232 | 222 | if (ret < 0) |
| 233 | 223 | printk(KERN_ERR "%s %s: can't reserve resources\n", |
| @@ -403,6 +393,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) · 169 unmodified lines | ||
| 403 | 393 | /** |
| 404 | 394 | * ide_setup_pci_controller - set up IDE PCI |
| 405 | 395 | * @dev: PCI device |
| 396 | + * @bars: PCI BARs mask | |
| 406 | 397 | * @d: IDE port info |
| 407 | 398 | * @noisy: verbose flag |
| 408 | 399 | * |
| @@ -411,7 +402,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) · 2 unmodified lines | ||
| 411 | 402 | * and enables it if need be |
| 412 | 403 | */ |
| 413 | 404 | |
| 414 | −static int ide_setup_pci_controller(struct pci_dev *dev, | |
| 405 | +static int ide_setup_pci_controller(struct pci_dev *dev, int bars, | |
| 415 | 406 | const struct ide_port_info *d, int noisy) |
| 416 | 407 | { |
| 417 | 408 | int ret; |
| @@ -420,7 +411,7 @@ static int ide_setup_pci_controller(struct pci_dev *dev, · 2 unmodified lines | ||
| 420 | 411 | if (noisy) |
| 421 | 412 | ide_setup_pci_noise(dev, d); |
| 422 | 413 | |
| 423 | − ret = ide_pci_enable(dev, d); | |
| 414 | + ret = ide_pci_enable(dev, bars, d); | |
| 424 | 415 | if (ret < 0) |
| 425 | 416 | goto out; |
| 426 | 417 | |
| @@ -428,16 +419,20 @@ static int ide_setup_pci_controller(struct pci_dev *dev, · 1 unmodified line | ||
| 428 | 419 | if (ret < 0) { |
| 429 | 420 | printk(KERN_ERR "%s %s: error accessing PCI regs\n", |
| 430 | 421 | d->name, pci_name(dev)); |
| 431 | − goto out; | |
| 422 | + goto out_free_bars; | |
| 432 | 423 | } |
| 433 | 424 | if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */ |
| 434 | 425 | ret = ide_pci_configure(dev, d); |
| 435 | 426 | if (ret < 0) |
| 436 | − goto out; | |
| 427 | + goto out_free_bars; | |
| 437 | 428 | printk(KERN_INFO "%s %s: device enabled (Linux)\n", |
| 438 | 429 | d->name, pci_name(dev)); |
| 439 | 430 | } |
| 440 | 431 | |
| 432 | + goto out; | |
| 433 | + | |
| 434 | +out_free_bars: | |
| 435 | + pci_release_selected_regions(dev, bars); | |
| 441 | 436 | out: |
| 442 | 437 | return ret; |
| 443 | 438 | } |
| @@ -540,13 +535,28 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, · 96 unmodified lines | ||
| 540 | 535 | { |
| 541 | 536 | struct pci_dev *pdev[] = { dev1, dev2 }; |
| 542 | 537 | struct ide_host *host; |
| 543 | − int ret, i, n_ports = dev2 ? 4 : 2; | |
| 538 | + int ret, i, n_ports = dev2 ? 4 : 2, bars; | |
| 544 | 539 | struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL }; |
| 545 | 540 | |
| 541 | + if (d->host_flags & IDE_HFLAG_SINGLE) | |
| 542 | + bars = (1 << 2) - 1; | |
| 543 | + else | |
| 544 | + bars = (1 << 4) - 1; | |
| 545 | + | |
| 546 | + if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { | |
| 547 | + if (d->host_flags & IDE_HFLAG_CS5520) | |
| 548 | + bars |= (1 << 2); | |
| 549 | + else | |
| 550 | + bars |= (1 << 4); | |
| 551 | + } | |
| 552 | + | |
| 546 | 553 | for (i = 0; i < n_ports / 2; i++) { |
| 547 | − ret = ide_setup_pci_controller(pdev[i], d, !i); | |
| 548 | − if (ret < 0) | |
| 554 | + ret = ide_setup_pci_controller(pdev[i], bars, d, !i); | |
| 555 | + if (ret < 0) { | |
| 556 | + if (i == 1) | |
| 557 | + pci_release_selected_regions(pdev[0], bars); | |
| 549 | 558 | goto out; |
| 559 | + } | |
| 550 | 560 | |
| 551 | 561 | ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]); |
| 552 | 562 | } |
| @@ -554,7 +564,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, · 1 unmodified line | ||
| 554 | 564 | host = ide_host_alloc(d, hws, n_ports); |
| 555 | 565 | if (host == NULL) { |
| 556 | 566 | ret = -ENOMEM; |
| 557 | − goto out; | |
| 567 | + goto out_free_bars; | |
| 558 | 568 | } |
| 559 | 569 | |
| 560 | 570 | host->dev[0] = &dev1->dev; |
| @@ -576,7 +586,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, · 15 unmodified lines | ||
| 576 | 586 | * do_ide_setup_pci_device() on the first device! |
| 577 | 587 | */ |
| 578 | 588 | if (ret < 0) |
| 579 | − goto out; | |
| 589 | + goto out_free_bars; | |
| 580 | 590 | |
| 581 | 591 | /* fixup IRQ */ |
| 582 | 592 | if (ide_pci_is_in_compatibility_mode(pdev[i])) { |
| @@ -589,6 +599,13 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, · 6 unmodified lines | ||
| 589 | 599 | ret = ide_host_register(host, d, hws); |
| 590 | 600 | if (ret) |
| 591 | 601 | ide_host_free(host); |
| 602 | + else | |
| 603 | + goto out; | |
| 604 | + | |
| 605 | +out_free_bars: | |
| 606 | + i = n_ports / 2; | |
| 607 | + while (i--) | |
| 608 | + pci_release_selected_regions(pdev[i], bars); | |
| 592 | 609 | out: |
| 593 | 610 | return ret; |
| 594 | 611 | } |
| @@ -257,7 +257,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, · 256 unmodified lines | ||
| 257 | 257 | unsigned int vref_mv) |
| 258 | 258 | { |
| 259 | 259 | struct ad7793_state *st = iio_priv(indio_dev); |
| 260 | − int i, ret = -1; | |
| 260 | + int i, ret; | |
| 261 | 261 | unsigned long long scale_uv; |
| 262 | 262 | u32 id; |
| 263 | 263 | |
| @@ -266,7 +266,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, · 2 unmodified lines | ||
| 266 | 266 | return ret; |
| 267 | 267 | |
| 268 | 268 | /* reset the serial interface */ |
| 269 | − ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret)); | |
| 269 | + ret = ad_sd_reset(&st->sd, 32); | |
| 270 | 270 | if (ret < 0) |
| 271 | 271 | goto out; |
| 272 | 272 | usleep_range(500, 2000); /* Wait for at least 500us */ |
| @@ -177,6 +177,34 @@ out: · 176 unmodified lines | ||
| 177 | 177 | } |
| 178 | 178 | EXPORT_SYMBOL_GPL(ad_sd_read_reg); |
| 179 | 179 | |
| 180 | +/** | |
| 181 | + * ad_sd_reset() - Reset the serial interface | |
| 182 | + * | |
| 183 | + * @sigma_delta: The sigma delta device | |
| 184 | + * @reset_length: Number of SCLKs with DIN = 1 | |
| 185 | + * | |
| 186 | + * Returns 0 on success, an error code otherwise. | |
| 187 | + **/ | |
| 188 | +int ad_sd_reset(struct ad_sigma_delta *sigma_delta, | |
| 189 | + unsigned int reset_length) | |
| 190 | +{ | |
| 191 | + uint8_t *buf; | |
| 192 | + unsigned int size; | |
| 193 | + int ret; | |
| 194 | + | |
| 195 | + size = DIV_ROUND_UP(reset_length, 8); | |
| 196 | + buf = kcalloc(size, sizeof(*buf), GFP_KERNEL); | |
| 197 | + if (!buf) | |
| 198 | + return -ENOMEM; | |
| 199 | + | |
| 200 | + memset(buf, 0xff, size); | |
| 201 | + ret = spi_write(sigma_delta->spi, buf, size); | |
| 202 | + kfree(buf); | |
| 203 | + | |
| 204 | + return ret; | |
| 205 | +} | |
| 206 | +EXPORT_SYMBOL_GPL(ad_sd_reset); | |
| 207 | + | |
| 180 | 208 | static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, |
| 181 | 209 | unsigned int mode, unsigned int channel) |
| 182 | 210 | { |
| @@ -17,6 +17,8 @@ · 16 unmodified lines | ||
| 17 | 17 | * MCP3204 |
| 18 | 18 | * MCP3208 |
| 19 | 19 | * ------------ |
| 20 | + * 13 bit converter | |
| 21 | + * MCP3301 | |
| 20 | 22 | * |
| 21 | 23 | * Datasheet can be found here: |
| 22 | 24 | * http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf mcp3001 |
| @@ -96,7 +98,7 @@ static int mcp320x_channel_to_tx_data(int device_index, · 73 unmodified lines | ||
| 96 | 98 | } |
| 97 | 99 | |
| 98 | 100 | static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, |
| 99 | − bool differential, int device_index) | |
| 101 | + bool differential, int device_index, int *val) | |
| 100 | 102 | { |
| 101 | 103 | int ret; |
| 102 | 104 | |
| @@ -117,19 +119,25 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, · 14 unmodified lines | ||
| 117 | 119 | |
| 118 | 120 | switch (device_index) { |
| 119 | 121 | case mcp3001: |
| 120 | − return (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); | |
| 122 | + *val = (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); | |
| 123 | + return 0; | |
| 121 | 124 | case mcp3002: |
| 122 | 125 | case mcp3004: |
| 123 | 126 | case mcp3008: |
| 124 | − return (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); | |
| 127 | + *val = (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); | |
| 128 | + return 0; | |
| 125 | 129 | case mcp3201: |
| 126 | − return (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); | |
| 130 | + *val = (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); | |
| 131 | + return 0; | |
| 127 | 132 | case mcp3202: |
| 128 | 133 | case mcp3204: |
| 129 | 134 | case mcp3208: |
| 130 | − return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); | |
| 135 | + *val = (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); | |
| 136 | + return 0; | |
| 131 | 137 | case mcp3301: |
| 132 | − return sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12); | |
| 138 | + *val = sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | |
| 139 | + | adc->rx_buf[1], 12); | |
| 140 | + return 0; | |
| 133 | 141 | default: |
| 134 | 142 | return -EINVAL; |
| 135 | 143 | } |
| @@ -150,12 +158,10 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, · 14 unmodified lines | ||
| 150 | 158 | switch (mask) { |
| 151 | 159 | case IIO_CHAN_INFO_RAW: |
| 152 | 160 | ret = mcp320x_adc_conversion(adc, channel->address, |
| 153 | − channel->differential, device_index); | |
| 154 | − | |
| 161 | + channel->differential, device_index, val); | |
| 155 | 162 | if (ret < 0) |
| 156 | 163 | goto out; |
| 157 | 164 | |
| 158 | − *val = ret; | |
| 159 | 165 | ret = IIO_VAL_INT; |
| 160 | 166 | break; |
| 161 | 167 | |
| @@ -312,6 +318,7 @@ static int mcp320x_probe(struct spi_device *spi) · 150 unmodified lines | ||
| 312 | 318 | indio_dev->name = spi_get_device_id(spi)->name; |
| 313 | 319 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 314 | 320 | indio_dev->info = &mcp320x_info; |
| 321 | + spi_set_drvdata(spi, indio_dev); | |
| 315 | 322 | |
| 316 | 323 | chip_info = &mcp320x_chip_infos[spi_get_device_id(spi)->driver_data]; |
| 317 | 324 | indio_dev->channels = chip_info->channels; |
| @@ -1666,7 +1666,7 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev) · 1665 unmodified lines | ||
| 1666 | 1666 | |
| 1667 | 1667 | num_channels = of_property_count_u32_elems(node, "st,adc-channels"); |
| 1668 | 1668 | if (num_channels < 0 || |
| 1669 | − num_channels >= adc_info->max_channels) { | |
| 1669 | + num_channels > adc_info->max_channels) { | |
| 1670 | 1670 | dev_err(&indio_dev->dev, "Bad st,adc-channels?\n"); |
| 1671 | 1671 | return num_channels < 0 ? num_channels : -EINVAL; |
| 1672 | 1672 | } |
| @@ -52,7 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | #define ADS1015_CFG_COMP_QUE_MASK GENMASK(1, 0) |
| 54 | 54 | #define ADS1015_CFG_COMP_LAT_MASK BIT(2) |
| 55 | −#define ADS1015_CFG_COMP_POL_MASK BIT(2) | |
| 55 | +#define ADS1015_CFG_COMP_POL_MASK BIT(3) | |
| 56 | 56 | #define ADS1015_CFG_COMP_MODE_MASK BIT(4) |
| 57 | 57 | #define ADS1015_CFG_DR_MASK GENMASK(7, 5) |
| 58 | 58 | #define ADS1015_CFG_MOD_MASK BIT(8) |
| @@ -1017,10 +1017,12 @@ static int ads1015_probe(struct i2c_client *client, · 958 unmodified lines | ||
| 1017 | 1017 | |
| 1018 | 1018 | switch (irq_trig) { |
| 1019 | 1019 | case IRQF_TRIGGER_LOW: |
| 1020 | − cfg_comp |= ADS1015_CFG_COMP_POL_LOW; | |
| 1020 | + cfg_comp |= ADS1015_CFG_COMP_POL_LOW << | |
| 1021 | + ADS1015_CFG_COMP_POL_SHIFT; | |
| 1021 | 1022 | break; |
| 1022 | 1023 | case IRQF_TRIGGER_HIGH: |
| 1023 | − cfg_comp |= ADS1015_CFG_COMP_POL_HIGH; | |
| 1024 | + cfg_comp |= ADS1015_CFG_COMP_POL_HIGH << | |
| 1025 | + ADS1015_CFG_COMP_POL_SHIFT; | |
| 1024 | 1026 | break; |
| 1025 | 1027 | default: |
| 1026 | 1028 | return -EINVAL; |
| @@ -887,21 +887,27 @@ static int twl4030_madc_probe(struct platform_device *pdev) · 886 unmodified lines | ||
| 887 | 887 | |
| 888 | 888 | /* Enable 3v1 bias regulator for MADC[3:6] */ |
| 889 | 889 | madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1"); |
| 890 | − if (IS_ERR(madc->usb3v1)) | |
| 891 | − return -ENODEV; | |
| 890 | + if (IS_ERR(madc->usb3v1)) { | |
| 891 | + ret = -ENODEV; | |
| 892 | + goto err_i2c; | |
| 893 | + } | |
| 892 | 894 | |
| 893 | 895 | ret = regulator_enable(madc->usb3v1); |
| 894 | − if (ret) | |
| 896 | + if (ret) { | |
| 895 | 897 | dev_err(madc->dev, "could not enable 3v1 bias regulator\n"); |
| 898 | + goto err_i2c; | |
| 899 | + } | |
| 896 | 900 | |
| 897 | 901 | ret = iio_device_register(iio_dev); |
| 898 | 902 | if (ret) { |
| 899 | 903 | dev_err(&pdev->dev, "could not register iio device\n"); |
| 900 | − goto err_i2c; | |
| 904 | + goto err_usb3v1; | |
| 901 | 905 | } |
| 902 | 906 | |
| 903 | 907 | return 0; |
| 904 | 908 | |
| 909 | +err_usb3v1: | |
| 910 | + regulator_disable(madc->usb3v1); | |
| 905 | 911 | err_i2c: |
| 906 | 912 | twl4030_madc_set_current_generator(madc, 0, 0); |
| 907 | 913 | err_current_generator: |
| @@ -463,8 +463,17 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable) · 462 unmodified lines | ||
| 463 | 463 | u8 drdy_mask; |
| 464 | 464 | struct st_sensor_data *sdata = iio_priv(indio_dev); |
| 465 | 465 | |
| 466 | − if (!sdata->sensor_settings->drdy_irq.addr) | |
| 466 | + if (!sdata->sensor_settings->drdy_irq.addr) { | |
| 467 | + /* | |
| 468 | + * there are some devices (e.g. LIS3MDL) where drdy line is | |
| 469 | + * routed to a given pin and it is not possible to select a | |
| 470 | + * different one. Take into account irq status register | |
| 471 | + * to understand if irq trigger can be properly supported | |
| 472 | + */ | |
| 473 | + if (sdata->sensor_settings->drdy_irq.addr_stat_drdy) | |
| 474 | + sdata->hw_irq_trigger = enable; | |
| 467 | 475 | return 0; |
| 476 | + } | |
| 468 | 477 | |
| 469 | 478 | /* Enable/Disable the interrupt generator 1. */ |
| 470 | 479 | if (sdata->sensor_settings->drdy_irq.ig1.en_addr > 0) { |
| @@ -310,8 +310,10 @@ static ssize_t iio_debugfs_read_reg(struct file *file, char __user *userbuf, · 309 unmodified lines | ||
| 310 | 310 | ret = indio_dev->info->debugfs_reg_access(indio_dev, |
| 311 | 311 | indio_dev->cached_reg_addr, |
| 312 | 312 | 0, &val); |
| 313 | − if (ret) | |
| 313 | + if (ret) { | |
| 314 | 314 | dev_err(indio_dev->dev.parent, "%s: read failed\n", __func__); |
| 315 | + return ret; | |
| 316 | + } | |
| 315 | 317 | |
| 316 | 318 | len = snprintf(buf, sizeof(buf), "0x%X\n", val); |
| 317 | 319 | |
| @@ -315,6 +315,10 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { · 314 unmodified lines | ||
| 315 | 315 | }, |
| 316 | 316 | }, |
| 317 | 317 | }, |
| 318 | + .drdy_irq = { | |
| 319 | + /* drdy line is routed drdy pin */ | |
| 320 | + .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, | |
| 321 | + }, | |
| 318 | 322 | .multi_read_bit = true, |
| 319 | 323 | .bootime = 2, |
| 320 | 324 | }, |
| @@ -573,7 +573,7 @@ static int bmp280_chip_config(struct bmp280_data *data) · 572 unmodified lines | ||
| 573 | 573 | u8 osrs = BMP280_OSRS_TEMP_X(data->oversampling_temp + 1) | |
| 574 | 574 | BMP280_OSRS_PRESS_X(data->oversampling_press + 1); |
| 575 | 575 | |
| 576 | − ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS, | |
| 576 | + ret = regmap_write_bits(data->regmap, BMP280_REG_CTRL_MEAS, | |
| 577 | 577 | BMP280_OSRS_TEMP_MASK | |
| 578 | 578 | BMP280_OSRS_PRESS_MASK | |
| 579 | 579 | BMP280_MODE_MASK, |
| @@ -174,6 +174,7 @@ static void stm32_timer_stop(struct stm32_timer_trigger *priv) · 173 unmodified lines | ||
| 174 | 174 | clk_disable(priv->clk); |
| 175 | 175 | |
| 176 | 176 | /* Stop timer */ |
| 177 | + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); | |
| 177 | 178 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); |
| 178 | 179 | regmap_write(priv->regmap, TIM_PSC, 0); |
| 179 | 180 | regmap_write(priv->regmap, TIM_ARR, 0); |
| @@ -715,8 +716,9 @@ static ssize_t stm32_count_set_preset(struct iio_dev *indio_dev, · 535 unmodified lines | ||
| 715 | 716 | if (ret) |
| 716 | 717 | return ret; |
| 717 | 718 | |
| 719 | + /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ | |
| 720 | + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); | |
| 718 | 721 | regmap_write(priv->regmap, TIM_ARR, preset); |
| 719 | − regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); | |
| 720 | 722 | |
| 721 | 723 | return len; |
| 722 | 724 | } |
| @@ -100,6 +100,8 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) · 99 unmodified lines | ||
| 100 | 100 | if (ret) |
| 101 | 101 | goto pid_query_error; |
| 102 | 102 | |
| 103 | + nlmsg_end(skb, nlh); | |
| 104 | + | |
| 103 | 105 | pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n", |
| 104 | 106 | __func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name); |
| 105 | 107 | |
| @@ -170,6 +172,8 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) · 64 unmodified lines | ||
| 170 | 172 | &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR); |
| 171 | 173 | if (ret) |
| 172 | 174 | goto add_mapping_error; |
| 175 | + | |
| 176 | + nlmsg_end(skb, nlh); | |
| 173 | 177 | nlmsg_request->req_buffer = pm_msg; |
| 174 | 178 | |
| 175 | 179 | ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); |
| @@ -246,6 +250,8 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) · 70 unmodified lines | ||
| 246 | 250 | &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR); |
| 247 | 251 | if (ret) |
| 248 | 252 | goto query_mapping_error; |
| 253 | + | |
| 254 | + nlmsg_end(skb, nlh); | |
| 249 | 255 | nlmsg_request->req_buffer = pm_msg; |
| 250 | 256 | |
| 251 | 257 | ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); |
| @@ -308,6 +314,8 @@ int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client) · 56 unmodified lines | ||
| 308 | 314 | if (ret) |
| 309 | 315 | goto remove_mapping_error; |
| 310 | 316 | |
| 317 | + nlmsg_end(skb, nlh); | |
| 318 | + | |
| 311 | 319 | ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); |
| 312 | 320 | if (ret) { |
| 313 | 321 | skb = NULL; /* skb is freed in the netlink send-op handling */ |
| @@ -597,6 +597,9 @@ static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid) · 596 unmodified lines | ||
| 597 | 597 | &mapping_num, IWPM_NLA_MAPINFO_SEND_NUM); |
| 598 | 598 | if (ret) |
| 599 | 599 | goto mapinfo_num_error; |
| 600 | + | |
| 601 | + nlmsg_end(skb, nlh); | |
| 602 | + | |
| 600 | 603 | ret = rdma_nl_unicast(skb, iwpm_pid); |
| 601 | 604 | if (ret) { |
| 602 | 605 | skb = NULL; |
| @@ -678,6 +681,8 @@ int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid) · 75 unmodified lines | ||
| 678 | 681 | if (ret) |
| 679 | 682 | goto send_mapping_info_unlock; |
| 680 | 683 | |
| 684 | + nlmsg_end(skb, nlh); | |
| 685 | + | |
| 681 | 686 | iwpm_print_sockaddr(&map_info->local_sockaddr, |
| 682 | 687 | "send_mapping_info: Local sockaddr:"); |
| 683 | 688 | iwpm_print_sockaddr(&map_info->mapped_sockaddr, |
| @@ -432,8 +432,10 @@ int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev) · 431 unmodified lines | ||
| 432 | 432 | atomic_set(&qp->qp_sec->error_list_count, 0); |
| 433 | 433 | init_completion(&qp->qp_sec->error_complete); |
| 434 | 434 | ret = security_ib_alloc_security(&qp->qp_sec->security); |
| 435 | − if (ret) | |
| 435 | + if (ret) { | |
| 436 | 436 | kfree(qp->qp_sec); |
| 437 | + qp->qp_sec = NULL; | |
| 438 | + } | |
| 437 | 439 | |
| 438 | 440 | return ret; |
| 439 | 441 | } |
| @@ -3869,15 +3869,15 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file, · 3868 unmodified lines | ||
| 3869 | 3869 | resp.raw_packet_caps = attr.raw_packet_caps; |
| 3870 | 3870 | resp.response_length += sizeof(resp.raw_packet_caps); |
| 3871 | 3871 | |
| 3872 | − if (ucore->outlen < resp.response_length + sizeof(resp.xrq_caps)) | |
| 3872 | + if (ucore->outlen < resp.response_length + sizeof(resp.tm_caps)) | |
| 3873 | 3873 | goto end; |
| 3874 | 3874 | |
| 3875 | − resp.xrq_caps.max_rndv_hdr_size = attr.xrq_caps.max_rndv_hdr_size; | |
| 3876 | − resp.xrq_caps.max_num_tags = attr.xrq_caps.max_num_tags; | |
| 3877 | − resp.xrq_caps.max_ops = attr.xrq_caps.max_ops; | |
| 3878 | − resp.xrq_caps.max_sge = attr.xrq_caps.max_sge; | |
| 3879 | − resp.xrq_caps.flags = attr.xrq_caps.flags; | |
| 3880 | − resp.response_length += sizeof(resp.xrq_caps); | |
| 3875 | + resp.tm_caps.max_rndv_hdr_size = attr.tm_caps.max_rndv_hdr_size; | |
| 3876 | + resp.tm_caps.max_num_tags = attr.tm_caps.max_num_tags; | |
| 3877 | + resp.tm_caps.max_ops = attr.tm_caps.max_ops; | |
| 3878 | + resp.tm_caps.max_sge = attr.tm_caps.max_sge; | |
| 3879 | + resp.tm_caps.flags = attr.tm_caps.flags; | |
| 3880 | + resp.response_length += sizeof(resp.tm_caps); | |
| 3881 | 3881 | end: |
| 3882 | 3882 | err = ib_copy_to_udata(ucore, &resp, resp.response_length); |
| 3883 | 3883 | return err; |
| @@ -1646,7 +1646,7 @@ static bool is_valid_mcast_lid(struct ib_qp *qp, u16 lid) · 1645 unmodified lines | ||
| 1646 | 1646 | */ |
| 1647 | 1647 | if (!ib_query_qp(qp, &attr, IB_QP_STATE | IB_QP_PORT, &init_attr)) { |
| 1648 | 1648 | if (attr.qp_state >= IB_QPS_INIT) { |
| 1649 | − if (qp->device->get_link_layer(qp->device, attr.port_num) != | |
| 1649 | + if (rdma_port_get_link_layer(qp->device, attr.port_num) != | |
| 1650 | 1650 | IB_LINK_LAYER_INFINIBAND) |
| 1651 | 1651 | return true; |
| 1652 | 1652 | goto lid_check; |
| @@ -1655,7 +1655,7 @@ static bool is_valid_mcast_lid(struct ib_qp *qp, u16 lid) · 2 unmodified lines | ||
| 1655 | 1655 | |
| 1656 | 1656 | /* Can't get a quick answer, iterate over all ports */ |
| 1657 | 1657 | for (port = 0; port < qp->device->phys_port_cnt; port++) |
| 1658 | − if (qp->device->get_link_layer(qp->device, port) != | |
| 1658 | + if (rdma_port_get_link_layer(qp->device, port) != | |
| 1659 | 1659 | IB_LINK_LAYER_INFINIBAND) |
| 1660 | 1660 | num_eth_ports++; |
| 1661 | 1661 | |
| @@ -93,11 +93,13 @@ struct bnxt_re_dev { · 92 unmodified lines | ||
| 93 | 93 | struct ib_device ibdev; |
| 94 | 94 | struct list_head list; |
| 95 | 95 | unsigned long flags; |
| 96 | −#define BNXT_RE_FLAG_NETDEV_REGISTERED 0 | |
| 97 | −#define BNXT_RE_FLAG_IBDEV_REGISTERED 1 | |
| 98 | −#define BNXT_RE_FLAG_GOT_MSIX 2 | |
| 99 | −#define BNXT_RE_FLAG_RCFW_CHANNEL_EN 8 | |
| 100 | −#define BNXT_RE_FLAG_QOS_WORK_REG 16 | |
| 96 | +#define BNXT_RE_FLAG_NETDEV_REGISTERED 0 | |
| 97 | +#define BNXT_RE_FLAG_IBDEV_REGISTERED 1 | |
| 98 | +#define BNXT_RE_FLAG_GOT_MSIX 2 | |
| 99 | +#define BNXT_RE_FLAG_HAVE_L2_REF 3 | |
| 100 | +#define BNXT_RE_FLAG_RCFW_CHANNEL_EN 4 | |
| 101 | +#define BNXT_RE_FLAG_QOS_WORK_REG 5 | |
| 102 | +#define BNXT_RE_FLAG_TASK_IN_PROG 6 | |
| 101 | 103 | struct net_device *netdev; |
| 102 | 104 | unsigned int version, major, minor; |
| 103 | 105 | struct bnxt_en_dev *en_dev; |
| @@ -108,6 +110,8 @@ struct bnxt_re_dev { · 4 unmodified lines | ||
| 108 | 110 | |
| 109 | 111 | struct delayed_work worker; |
| 110 | 112 | u8 cur_prio_map; |
| 113 | + u8 active_speed; | |
| 114 | + u8 active_width; | |
| 111 | 115 | |
| 112 | 116 | /* FP Notification Queue (CQ & SRQ) */ |
| 113 | 117 | struct tasklet_struct nq_task; |
| @@ -259,14 +259,9 @@ int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num, · 258 unmodified lines | ||
| 259 | 259 | port_attr->sm_sl = 0; |
| 260 | 260 | port_attr->subnet_timeout = 0; |
| 261 | 261 | port_attr->init_type_reply = 0; |
| 262 | − /* call the underlying netdev's ethtool hooks to query speed settings | |
| 263 | − * for which we acquire rtnl_lock _only_ if it's registered with | |
| 264 | − * IB stack to avoid race in the NETDEV_UNREG path | |
| 265 | − */ | |
| 266 | − if (test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) | |
| 267 | − if (ib_get_eth_speed(ibdev, port_num, &port_attr->active_speed, | |
| 268 | − &port_attr->active_width)) | |
| 269 | − return -EINVAL; | |
| 262 | + port_attr->active_speed = rdev->active_speed; | |
| 263 | + port_attr->active_width = rdev->active_width; | |
| 264 | + | |
| 270 | 265 | return 0; |
| 271 | 266 | } |
| 272 | 267 | |
| @@ -319,6 +314,7 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num, · 46 unmodified lines | ||
| 319 | 314 | struct bnxt_re_gid_ctx *ctx, **ctx_tbl; |
| 320 | 315 | struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev); |
| 321 | 316 | struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl; |
| 317 | + struct bnxt_qplib_gid *gid_to_del; | |
| 322 | 318 | |
| 323 | 319 | /* Delete the entry from the hardware */ |
| 324 | 320 | ctx = *context; |
| @@ -328,11 +324,25 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num, · 3 unmodified lines | ||
| 328 | 324 | if (sgid_tbl && sgid_tbl->active) { |
| 329 | 325 | if (ctx->idx >= sgid_tbl->max) |
| 330 | 326 | return -EINVAL; |
| 327 | + gid_to_del = &sgid_tbl->tbl[ctx->idx]; | |
| 328 | + /* DEL_GID is called in WQ context(netdevice_event_work_handler) | |
| 329 | + * or via the ib_unregister_device path. In the former case QP1 | |
| 330 | + * may not be destroyed yet, in which case just return as FW | |
| 331 | + * needs that entry to be present and will fail it's deletion. | |
| 332 | + * We could get invoked again after QP1 is destroyed OR get an | |
| 333 | + * ADD_GID call with a different GID value for the same index | |
| 334 | + * where we issue MODIFY_GID cmd to update the GID entry -- TBD | |
| 335 | + */ | |
| 336 | + if (ctx->idx == 0 && | |
| 337 | + rdma_link_local_addr((struct in6_addr *)gid_to_del) && | |
| 338 | + ctx->refcnt == 1 && rdev->qp1_sqp) { | |
| 339 | + dev_dbg(rdev_to_dev(rdev), | |
| 340 | + "Trying to delete GID0 while QP1 is alive\n"); | |
| 341 | + return -EFAULT; | |
| 342 | + } | |
| 331 | 343 | ctx->refcnt--; |
| 332 | 344 | if (!ctx->refcnt) { |
| 333 | − rc = bnxt_qplib_del_sgid(sgid_tbl, | |
| 334 | − &sgid_tbl->tbl[ctx->idx], | |
| 335 | − true); | |
| 345 | + rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del, true); | |
| 336 | 346 | if (rc) { |
| 337 | 347 | dev_err(rdev_to_dev(rdev), |
| 338 | 348 | "Failed to remove GID: %#x", rc); |
| @@ -816,6 +826,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp) · 477 unmodified lines | ||
| 816 | 826 | |
| 817 | 827 | kfree(rdev->sqp_ah); |
| 818 | 828 | kfree(rdev->qp1_sqp); |
| 829 | + rdev->qp1_sqp = NULL; | |
| 830 | + rdev->sqp_ah = NULL; | |
| 819 | 831 | } |
| 820 | 832 | |
| 821 | 833 | if (!IS_ERR_OR_NULL(qp->rumem)) |
| @@ -1436,11 +1448,14 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, · 614 unmodified lines | ||
| 1436 | 1448 | qp->qplib_qp.modify_flags |= |
| 1437 | 1449 | CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; |
| 1438 | 1450 | qp->qplib_qp.path_mtu = __from_ib_mtu(qp_attr->path_mtu); |
| 1451 | + qp->qplib_qp.mtu = ib_mtu_enum_to_int(qp_attr->path_mtu); | |
| 1439 | 1452 | } else if (qp_attr->qp_state == IB_QPS_RTR) { |
| 1440 | 1453 | qp->qplib_qp.modify_flags |= |
| 1441 | 1454 | CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; |
| 1442 | 1455 | qp->qplib_qp.path_mtu = |
| 1443 | 1456 | __from_ib_mtu(iboe_get_mtu(rdev->netdev->mtu)); |
| 1457 | + qp->qplib_qp.mtu = | |
| 1458 | + ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); | |
| 1444 | 1459 | } |
| 1445 | 1460 | |
| 1446 | 1461 | if (qp_attr_mask & IB_QP_TIMEOUT) { |
| @@ -1551,43 +1566,46 @@ int bnxt_re_query_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, · 104 unmodified lines | ||
| 1551 | 1566 | { |
| 1552 | 1567 | struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); |
| 1553 | 1568 | struct bnxt_re_dev *rdev = qp->rdev; |
| 1554 | − struct bnxt_qplib_qp qplib_qp; | |
| 1569 | + struct bnxt_qplib_qp *qplib_qp; | |
| 1555 | 1570 | int rc; |
| 1556 | 1571 | |
| 1557 | − memset(&qplib_qp, 0, sizeof(struct bnxt_qplib_qp)); | |
| 1558 | − qplib_qp.id = qp->qplib_qp.id; | |
| 1559 | − qplib_qp.ah.host_sgid_index = qp->qplib_qp.ah.host_sgid_index; | |
| 1572 | + qplib_qp = kzalloc(sizeof(*qplib_qp), GFP_KERNEL); | |
| 1573 | + if (!qplib_qp) | |
| 1574 | + return -ENOMEM; | |
| 1575 | + | |
| 1576 | + qplib_qp->id = qp->qplib_qp.id; | |
| 1577 | + qplib_qp->ah.host_sgid_index = qp->qplib_qp.ah.host_sgid_index; | |
| 1560 | 1578 | |
| 1561 | − rc = bnxt_qplib_query_qp(&rdev->qplib_res, &qplib_qp); | |
| 1579 | + rc = bnxt_qplib_query_qp(&rdev->qplib_res, qplib_qp); | |
| 1562 | 1580 | if (rc) { |
| 1563 | 1581 | dev_err(rdev_to_dev(rdev), "Failed to query HW QP"); |
| 1564 | − return rc; | |
| 1582 | + goto out; | |
| 1565 | 1583 | } |
| 1566 | − qp_attr->qp_state = __to_ib_qp_state(qplib_qp.state); | |
| 1567 | − qp_attr->en_sqd_async_notify = qplib_qp.en_sqd_async_notify ? 1 : 0; | |
| 1568 | − qp_attr->qp_access_flags = __to_ib_access_flags(qplib_qp.access); | |
| 1569 | − qp_attr->pkey_index = qplib_qp.pkey_index; | |
| 1570 | − qp_attr->qkey = qplib_qp.qkey; | |
| 1584 | + qp_attr->qp_state = __to_ib_qp_state(qplib_qp->state); | |
| 1585 | + qp_attr->en_sqd_async_notify = qplib_qp->en_sqd_async_notify ? 1 : 0; | |
| 1586 | + qp_attr->qp_access_flags = __to_ib_access_flags(qplib_qp->access); | |
| 1587 | + qp_attr->pkey_index = qplib_qp->pkey_index; | |
| 1588 | + qp_attr->qkey = qplib_qp->qkey; | |
| 1571 | 1589 | qp_attr->ah_attr.type = RDMA_AH_ATTR_TYPE_ROCE; |
| 1572 | − rdma_ah_set_grh(&qp_attr->ah_attr, NULL, qplib_qp.ah.flow_label, | |
| 1573 | − qplib_qp.ah.host_sgid_index, | |
| 1574 | − qplib_qp.ah.hop_limit, | |
| 1575 | − qplib_qp.ah.traffic_class); | |
| 1576 | − rdma_ah_set_dgid_raw(&qp_attr->ah_attr, qplib_qp.ah.dgid.data); | |
| 1577 | − rdma_ah_set_sl(&qp_attr->ah_attr, qplib_qp.ah.sl); | |
| 1578 | − ether_addr_copy(qp_attr->ah_attr.roce.dmac, qplib_qp.ah.dmac); | |
| 1579 | − qp_attr->path_mtu = __to_ib_mtu(qplib_qp.path_mtu); | |
| 1580 | − qp_attr->timeout = qplib_qp.timeout; | |
| 1581 | − qp_attr->retry_cnt = qplib_qp.retry_cnt; | |
| 1582 | − qp_attr->rnr_retry = qplib_qp.rnr_retry; | |
| 1583 | − qp_attr->min_rnr_timer = qplib_qp.min_rnr_timer; | |
| 1584 | − qp_attr->rq_psn = qplib_qp.rq.psn; | |
| 1585 | − qp_attr->max_rd_atomic = qplib_qp.max_rd_atomic; | |
| 1586 | − qp_attr->sq_psn = qplib_qp.sq.psn; | |
| 1587 | − qp_attr->max_dest_rd_atomic = qplib_qp.max_dest_rd_atomic; | |
| 1588 | − qp_init_attr->sq_sig_type = qplib_qp.sig_type ? IB_SIGNAL_ALL_WR : | |
| 1589 | − IB_SIGNAL_REQ_WR; | |
| 1590 | − qp_attr->dest_qp_num = qplib_qp.dest_qpn; | |
| 1590 | + rdma_ah_set_grh(&qp_attr->ah_attr, NULL, qplib_qp->ah.flow_label, | |
| 1591 | + qplib_qp->ah.host_sgid_index, | |
| 1592 | + qplib_qp->ah.hop_limit, | |
| 1593 | + qplib_qp->ah.traffic_class); | |
| 1594 | + rdma_ah_set_dgid_raw(&qp_attr->ah_attr, qplib_qp->ah.dgid.data); | |
| 1595 | + rdma_ah_set_sl(&qp_attr->ah_attr, qplib_qp->ah.sl); | |
| 1596 | + ether_addr_copy(qp_attr->ah_attr.roce.dmac, qplib_qp->ah.dmac); | |
| 1597 | + qp_attr->path_mtu = __to_ib_mtu(qplib_qp->path_mtu); | |
| 1598 | + qp_attr->timeout = qplib_qp->timeout; | |
| 1599 | + qp_attr->retry_cnt = qplib_qp->retry_cnt; | |
| 1600 | + qp_attr->rnr_retry = qplib_qp->rnr_retry; | |
| 1601 | + qp_attr->min_rnr_timer = qplib_qp->min_rnr_timer; | |
| 1602 | + qp_attr->rq_psn = qplib_qp->rq.psn; | |
| 1603 | + qp_attr->max_rd_atomic = qplib_qp->max_rd_atomic; | |
| 1604 | + qp_attr->sq_psn = qplib_qp->sq.psn; | |
| 1605 | + qp_attr->max_dest_rd_atomic = qplib_qp->max_dest_rd_atomic; | |
| 1606 | + qp_init_attr->sq_sig_type = qplib_qp->sig_type ? IB_SIGNAL_ALL_WR : | |
| 1607 | + IB_SIGNAL_REQ_WR; | |
| 1608 | + qp_attr->dest_qp_num = qplib_qp->dest_qpn; | |
| 1591 | 1609 | |
| 1592 | 1610 | qp_attr->cap.max_send_wr = qp->qplib_qp.sq.max_wqe; |
| 1593 | 1611 | qp_attr->cap.max_send_sge = qp->qplib_qp.sq.max_sge; |
| @@ -1596,7 +1614,9 @@ int bnxt_re_query_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, · 2 unmodified lines | ||
| 1596 | 1614 | qp_attr->cap.max_inline_data = qp->qplib_qp.max_inline_data; |
| 1597 | 1615 | qp_init_attr->cap = qp_attr->cap; |
| 1598 | 1616 | |
| 1599 | − return 0; | |
| 1617 | +out: | |
| 1618 | + kfree(qplib_qp); | |
| 1619 | + return rc; | |
| 1600 | 1620 | } |
| 1601 | 1621 | |
| 1602 | 1622 | /* Routine for sending QP1 packets for RoCE V1 an V2 |
| @@ -1908,6 +1928,7 @@ static int bnxt_re_build_atomic_wqe(struct ib_send_wr *wr, · 305 unmodified lines | ||
| 1908 | 1928 | switch (wr->opcode) { |
| 1909 | 1929 | case IB_WR_ATOMIC_CMP_AND_SWP: |
| 1910 | 1930 | wqe->type = BNXT_QPLIB_SWQE_TYPE_ATOMIC_CMP_AND_SWP; |
| 1931 | + wqe->atomic.cmp_data = atomic_wr(wr)->compare_add; | |
| 1911 | 1932 | wqe->atomic.swap_data = atomic_wr(wr)->swap; |
| 1912 | 1933 | break; |
| 1913 | 1934 | case IB_WR_ATOMIC_FETCH_AND_ADD: |
| @@ -3062,7 +3083,7 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr) · 1148 unmodified lines | ||
| 3062 | 3083 | return rc; |
| 3063 | 3084 | } |
| 3064 | 3085 | |
| 3065 | − if (mr->npages && mr->pages) { | |
| 3086 | + if (mr->pages) { | |
| 3066 | 3087 | rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res, |
| 3067 | 3088 | &mr->qplib_frpl); |
| 3068 | 3089 | kfree(mr->pages); |
| @@ -1161,6 +1161,8 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) · 1160 unmodified lines | ||
| 1161 | 1161 | } |
| 1162 | 1162 | } |
| 1163 | 1163 | set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); |
| 1164 | + ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, | |
| 1165 | + &rdev->active_width); | |
| 1164 | 1166 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_PORT_ACTIVE); |
| 1165 | 1167 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_GID_CHANGE); |
| 1166 | 1168 | |
| @@ -1255,10 +1257,14 @@ static void bnxt_re_task(struct work_struct *work) · 88 unmodified lines | ||
| 1255 | 1257 | else if (netif_carrier_ok(rdev->netdev)) |
| 1256 | 1258 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, |
| 1257 | 1259 | IB_EVENT_PORT_ACTIVE); |
| 1260 | + ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, | |
| 1261 | + &rdev->active_width); | |
| 1258 | 1262 | break; |
| 1259 | 1263 | default: |
| 1260 | 1264 | break; |
| 1261 | 1265 | } |
| 1266 | + smp_mb__before_atomic(); | |
| 1267 | + clear_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags); | |
| 1262 | 1268 | kfree(re_work); |
| 1263 | 1269 | } |
| 1264 | 1270 | |
| @@ -1317,6 +1323,11 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, · 52 unmodified lines | ||
| 1317 | 1323 | break; |
| 1318 | 1324 | |
| 1319 | 1325 | case NETDEV_UNREGISTER: |
| 1326 | + /* netdev notifier will call NETDEV_UNREGISTER again later since | |
| 1327 | + * we are still holding the reference to the netdev | |
| 1328 | + */ | |
| 1329 | + if (test_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags)) | |
| 1330 | + goto exit; | |
| 1320 | 1331 | bnxt_re_ib_unreg(rdev, false); |
| 1321 | 1332 | bnxt_re_remove_one(rdev); |
| 1322 | 1333 | bnxt_re_dev_unreg(rdev); |
| @@ -1335,6 +1346,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, · 12 unmodified lines | ||
| 1335 | 1346 | re_work->vlan_dev = (real_dev == netdev ? |
| 1336 | 1347 | NULL : netdev); |
| 1337 | 1348 | INIT_WORK(&re_work->work, bnxt_re_task); |
| 1349 | + set_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags); | |
| 1338 | 1350 | queue_work(bnxt_re_wq, &re_work->work); |
| 1339 | 1351 | } |
| 1340 | 1352 | } |
| @@ -1375,6 +1387,22 @@ err_netdev: · 34 unmodified lines | ||
| 1375 | 1387 | |
| 1376 | 1388 | static void __exit bnxt_re_mod_exit(void) |
| 1377 | 1389 | { |
| 1390 | + struct bnxt_re_dev *rdev; | |
| 1391 | + LIST_HEAD(to_be_deleted); | |
| 1392 | + | |
| 1393 | + mutex_lock(&bnxt_re_dev_lock); | |
| 1394 | + /* Free all adapter allocated resources */ | |
| 1395 | + if (!list_empty(&bnxt_re_dev_list)) | |
| 1396 | + list_splice_init(&bnxt_re_dev_list, &to_be_deleted); | |
| 1397 | + mutex_unlock(&bnxt_re_dev_lock); | |
| 1398 | + | |
| 1399 | + list_for_each_entry(rdev, &to_be_deleted, list) { | |
| 1400 | + dev_info(rdev_to_dev(rdev), "Unregistering Device"); | |
| 1401 | + bnxt_re_dev_stop(rdev); | |
| 1402 | + bnxt_re_ib_unreg(rdev, true); | |
| 1403 | + bnxt_re_remove_one(rdev); | |
| 1404 | + bnxt_re_dev_unreg(rdev); | |
| 1405 | + } | |
| 1378 | 1406 | unregister_netdevice_notifier(&bnxt_re_netdev_notifier); |
| 1379 | 1407 | if (bnxt_re_wq) |
| 1380 | 1408 | destroy_workqueue(bnxt_re_wq); |
| @@ -107,6 +107,9 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req, · 106 unmodified lines | ||
| 107 | 107 | return -EINVAL; |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | + if (test_bit(FIRMWARE_TIMED_OUT, &rcfw->flags)) | |
| 111 | + return -ETIMEDOUT; | |
| 112 | + | |
| 110 | 113 | /* Cmdq are in 16-byte units, each request can consume 1 or more |
| 111 | 114 | * cmdqe |
| 112 | 115 | */ |
| @@ -226,6 +229,7 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, · 113 unmodified lines | ||
| 226 | 229 | /* timed out */ |
| 227 | 230 | dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x timedout (%d)msec", |
| 228 | 231 | cookie, opcode, RCFW_CMD_WAIT_TIME_MS); |
| 232 | + set_bit(FIRMWARE_TIMED_OUT, &rcfw->flags); | |
| 229 | 233 | return rc; |
| 230 | 234 | } |
| 231 | 235 | |
| @@ -162,8 +162,9 @@ struct bnxt_qplib_rcfw { · 161 unmodified lines | ||
| 162 | 162 | unsigned long *cmdq_bitmap; |
| 163 | 163 | u32 bmap_size; |
| 164 | 164 | unsigned long flags; |
| 165 | −#define FIRMWARE_INITIALIZED_FLAG 1 | |
| 165 | +#define FIRMWARE_INITIALIZED_FLAG BIT(0) | |
| 166 | 166 | #define FIRMWARE_FIRST_FLAG BIT(31) |
| 167 | +#define FIRMWARE_TIMED_OUT BIT(3) | |
| 167 | 168 | wait_queue_head_t waitq; |
| 168 | 169 | int (*aeq_handler)(struct bnxt_qplib_rcfw *, |
| 169 | 170 | struct creq_func_event *); |
| @@ -2333,9 +2333,14 @@ static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb) · 2332 unmodified lines | ||
| 2333 | 2333 | unsigned int stid = GET_TID(rpl); |
| 2334 | 2334 | struct c4iw_listen_ep *ep = get_ep_from_stid(dev, stid); |
| 2335 | 2335 | |
| 2336 | + if (!ep) { | |
| 2337 | + pr_debug("%s stid %d lookup failure!\n", __func__, stid); | |
| 2338 | + goto out; | |
| 2339 | + } | |
| 2336 | 2340 | pr_debug("%s ep %p\n", __func__, ep); |
| 2337 | 2341 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); |
| 2338 | 2342 | c4iw_put_ep(&ep->com); |
| 2343 | +out: | |
| 2339 | 2344 | return 0; |
| 2340 | 2345 | } |
| 2341 | 2346 | |
| @@ -2594,9 +2599,9 @@ fail: · 252 unmodified lines | ||
| 2594 | 2599 | c4iw_put_ep(&child_ep->com); |
| 2595 | 2600 | reject: |
| 2596 | 2601 | reject_cr(dev, hwtid, skb); |
| 2602 | +out: | |
| 2597 | 2603 | if (parent_ep) |
| 2598 | 2604 | c4iw_put_ep(&parent_ep->com); |
| 2599 | −out: | |
| 2600 | 2605 | return 0; |
| 2601 | 2606 | } |
| 2602 | 2607 | |
| @@ -3457,7 +3462,7 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) · 854 unmodified lines | ||
| 3457 | 3462 | cm_id->provider_data = ep; |
| 3458 | 3463 | goto out; |
| 3459 | 3464 | } |
| 3460 | − | |
| 3465 | + remove_handle(ep->com.dev, &ep->com.dev->stid_idr, ep->stid); | |
| 3461 | 3466 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, |
| 3462 | 3467 | ep->com.local_addr.ss_family); |
| 3463 | 3468 | fail2: |
| @@ -1066,6 +1066,8 @@ static int read_idle_sma(struct hfi1_devdata *dd, u64 *data); · 1065 unmodified lines | ||
| 1066 | 1066 | static int thermal_init(struct hfi1_devdata *dd); |
| 1067 | 1067 | |
| 1068 | 1068 | static void update_statusp(struct hfi1_pportdata *ppd, u32 state); |
| 1069 | +static int wait_phys_link_offline_substates(struct hfi1_pportdata *ppd, | |
| 1070 | + int msecs); | |
| 1069 | 1071 | static int wait_logical_linkstate(struct hfi1_pportdata *ppd, u32 state, |
| 1070 | 1072 | int msecs); |
| 1071 | 1073 | static void log_state_transition(struct hfi1_pportdata *ppd, u32 state); |
| @@ -8238,6 +8240,7 @@ static irqreturn_t general_interrupt(int irq, void *data) · 7166 unmodified lines | ||
| 8238 | 8240 | u64 regs[CCE_NUM_INT_CSRS]; |
| 8239 | 8241 | u32 bit; |
| 8240 | 8242 | int i; |
| 8243 | + irqreturn_t handled = IRQ_NONE; | |
| 8241 | 8244 | |
| 8242 | 8245 | this_cpu_inc(*dd->int_counter); |
| 8243 | 8246 | |
| @@ -8258,9 +8261,10 @@ static irqreturn_t general_interrupt(int irq, void *data) · 14 unmodified lines | ||
| 8258 | 8261 | for_each_set_bit(bit, (unsigned long *)®s[0], |
| 8259 | 8262 | CCE_NUM_INT_CSRS * 64) { |
| 8260 | 8263 | is_interrupt(dd, bit); |
| 8264 | + handled = IRQ_HANDLED; | |
| 8261 | 8265 | } |
| 8262 | 8266 | |
| 8263 | − return IRQ_HANDLED; | |
| 8267 | + return handled; | |
| 8264 | 8268 | } |
| 8265 | 8269 | |
| 8266 | 8270 | static irqreturn_t sdma_interrupt(int irq, void *data) |
| @@ -9413,7 +9417,7 @@ static void set_qsfp_int_n(struct hfi1_pportdata *ppd, u8 enable) · 1146 unmodified lines | ||
| 9413 | 9417 | write_csr(dd, dd->hfi1_id ? ASIC_QSFP2_MASK : ASIC_QSFP1_MASK, mask); |
| 9414 | 9418 | } |
| 9415 | 9419 | |
| 9416 | −void reset_qsfp(struct hfi1_pportdata *ppd) | |
| 9420 | +int reset_qsfp(struct hfi1_pportdata *ppd) | |
| 9417 | 9421 | { |
| 9418 | 9422 | struct hfi1_devdata *dd = ppd->dd; |
| 9419 | 9423 | u64 mask, qsfp_mask; |
| @@ -9443,6 +9447,13 @@ void reset_qsfp(struct hfi1_pportdata *ppd) · 23 unmodified lines | ||
| 9443 | 9447 | * for alarms and warnings |
| 9444 | 9448 | */ |
| 9445 | 9449 | set_qsfp_int_n(ppd, 1); |
| 9450 | + | |
| 9451 | + /* | |
| 9452 | + * After the reset, AOC transmitters are enabled by default. They need | |
| 9453 | + * to be turned off to complete the QSFP setup before they can be | |
| 9454 | + * enabled again. | |
| 9455 | + */ | |
| 9456 | + return set_qsfp_tx(ppd, 0); | |
| 9446 | 9457 | } |
| 9447 | 9458 | |
| 9448 | 9459 | static int handle_qsfp_error_conditions(struct hfi1_pportdata *ppd, |
| @@ -10305,6 +10316,7 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason) · 856 unmodified lines | ||
| 10305 | 10316 | { |
| 10306 | 10317 | struct hfi1_devdata *dd = ppd->dd; |
| 10307 | 10318 | u32 previous_state; |
| 10319 | + int offline_state_ret; | |
| 10308 | 10320 | int ret; |
| 10309 | 10321 | |
| 10310 | 10322 | update_lcb_cache(dd); |
| @@ -10326,28 +10338,11 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason) · 15 unmodified lines | ||
| 10326 | 10338 | ppd->offline_disabled_reason = |
| 10327 | 10339 | HFI1_ODR_MASK(OPA_LINKDOWN_REASON_TRANSIENT); |
| 10328 | 10340 | |
| 10329 | − /* | |
| 10330 | − * Wait for offline transition. It can take a while for | |
| 10331 | − * the link to go down. | |
| 10332 | − */ | |
| 10333 | − ret = wait_physical_linkstate(ppd, PLS_OFFLINE, 10000); | |
| 10334 | − if (ret < 0) | |
| 10335 | − return ret; | |
| 10336 | − | |
| 10337 | − /* | |
| 10338 | − * Now in charge of LCB - must be after the physical state is | |
| 10339 | − * offline.quiet and before host_link_state is changed. | |
| 10340 | − */ | |
| 10341 | − set_host_lcb_access(dd); | |
| 10342 | − write_csr(dd, DC_LCB_ERR_EN, ~0ull); /* watch LCB errors */ | |
| 10343 | − | |
| 10344 | − /* make sure the logical state is also down */ | |
| 10345 | − ret = wait_logical_linkstate(ppd, IB_PORT_DOWN, 1000); | |
| 10346 | − if (ret) | |
| 10347 | − force_logical_link_state_down(ppd); | |
| 10348 | − | |
| 10349 | − ppd->host_link_state = HLS_LINK_COOLDOWN; /* LCB access allowed */ | |
| 10341 | + offline_state_ret = wait_phys_link_offline_substates(ppd, 10000); | |
| 10342 | + if (offline_state_ret < 0) | |
| 10343 | + return offline_state_ret; | |
| 10350 | 10344 | |
| 10345 | + /* Disabling AOC transmitters */ | |
| 10351 | 10346 | if (ppd->port_type == PORT_TYPE_QSFP && |
| 10352 | 10347 | ppd->qsfp_info.limiting_active && |
| 10353 | 10348 | qsfp_mod_present(ppd)) { |
| @@ -10364,6 +10359,30 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason) · 10 unmodified lines | ||
| 10364 | 10359 | } |
| 10365 | 10360 | } |
| 10366 | 10361 | |
| 10362 | + /* | |
| 10363 | + * Wait for the offline.Quiet transition if it hasn't happened yet. It | |
| 10364 | + * can take a while for the link to go down. | |
| 10365 | + */ | |
| 10366 | + if (offline_state_ret != PLS_OFFLINE_QUIET) { | |
| 10367 | + ret = wait_physical_linkstate(ppd, PLS_OFFLINE, 30000); | |
| 10368 | + if (ret < 0) | |
| 10369 | + return ret; | |
| 10370 | + } | |
| 10371 | + | |
| 10372 | + /* | |
| 10373 | + * Now in charge of LCB - must be after the physical state is | |
| 10374 | + * offline.quiet and before host_link_state is changed. | |
| 10375 | + */ | |
| 10376 | + set_host_lcb_access(dd); | |
| 10377 | + write_csr(dd, DC_LCB_ERR_EN, ~0ull); /* watch LCB errors */ | |
| 10378 | + | |
| 10379 | + /* make sure the logical state is also down */ | |
| 10380 | + ret = wait_logical_linkstate(ppd, IB_PORT_DOWN, 1000); | |
| 10381 | + if (ret) | |
| 10382 | + force_logical_link_state_down(ppd); | |
| 10383 | + | |
| 10384 | + ppd->host_link_state = HLS_LINK_COOLDOWN; /* LCB access allowed */ | |
| 10385 | + | |
| 10367 | 10386 | /* |
| 10368 | 10387 | * The LNI has a mandatory wait time after the physical state |
| 10369 | 10388 | * moves to Offline.Quiet. The wait time may be different |
| @@ -10396,6 +10415,9 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason) · 26 unmodified lines | ||
| 10396 | 10415 | & (HLS_DN_POLL | HLS_VERIFY_CAP | HLS_GOING_UP)) { |
| 10397 | 10416 | /* went down while attempting link up */ |
| 10398 | 10417 | check_lni_states(ppd); |
| 10418 | + | |
| 10419 | + /* The QSFP doesn't need to be reset on LNI failure */ | |
| 10420 | + ppd->qsfp_info.reset_needed = 0; | |
| 10399 | 10421 | } |
| 10400 | 10422 | |
| 10401 | 10423 | /* the active link width (downgrade) is 0 on link down */ |
| @@ -12804,6 +12826,39 @@ static int wait_physical_linkstate(struct hfi1_pportdata *ppd, u32 state, · 2402 unmodified lines | ||
| 12804 | 12826 | return 0; |
| 12805 | 12827 | } |
| 12806 | 12828 | |
| 12829 | +/* | |
| 12830 | + * wait_phys_link_offline_quiet_substates - wait for any offline substate | |
| 12831 | + * @ppd: port device | |
| 12832 | + * @msecs: the number of milliseconds to wait | |
| 12833 | + * | |
| 12834 | + * Wait up to msecs milliseconds for any offline physical link | |
| 12835 | + * state change to occur. | |
| 12836 | + * Returns 0 if at least one state is reached, otherwise -ETIMEDOUT. | |
| 12837 | + */ | |
| 12838 | +static int wait_phys_link_offline_substates(struct hfi1_pportdata *ppd, | |
| 12839 | + int msecs) | |
| 12840 | +{ | |
| 12841 | + u32 read_state; | |
| 12842 | + unsigned long timeout; | |
| 12843 | + | |
| 12844 | + timeout = jiffies + msecs_to_jiffies(msecs); | |
| 12845 | + while (1) { | |
| 12846 | + read_state = read_physical_state(ppd->dd); | |
| 12847 | + if ((read_state & 0xF0) == PLS_OFFLINE) | |
| 12848 | + break; | |
| 12849 | + if (time_after(jiffies, timeout)) { | |
| 12850 | + dd_dev_err(ppd->dd, | |
| 12851 | + "timeout waiting for phy link offline.quiet substates. Read state 0x%x, %dms\n", | |
| 12852 | + read_state, msecs); | |
| 12853 | + return -ETIMEDOUT; | |
| 12854 | + } | |
| 12855 | + usleep_range(1950, 2050); /* sleep 2ms-ish */ | |
| 12856 | + } | |
| 12857 | + | |
| 12858 | + log_state_transition(ppd, read_state); | |
| 12859 | + return read_state; | |
| 12860 | +} | |
| 12861 | + | |
| 12807 | 12862 | #define CLEAR_STATIC_RATE_CONTROL_SMASK(r) \ |
| 12808 | 12863 | (r &= ~SEND_CTXT_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK) |
| 12809 | 12864 | |
| @@ -204,6 +204,7 @@ · 203 unmodified lines | ||
| 204 | 204 | #define PLS_OFFLINE_READY_TO_QUIET_LT 0x92 |
| 205 | 205 | #define PLS_OFFLINE_REPORT_FAILURE 0x93 |
| 206 | 206 | #define PLS_OFFLINE_READY_TO_QUIET_BCC 0x94 |
| 207 | +#define PLS_OFFLINE_QUIET_DURATION 0x95 | |
| 207 | 208 | #define PLS_POLLING 0x20 |
| 208 | 209 | #define PLS_POLLING_QUIET 0x20 |
| 209 | 210 | #define PLS_POLLING_ACTIVE 0x21 |
| @@ -722,7 +723,7 @@ void handle_link_downgrade(struct work_struct *work); · 512 unmodified lines | ||
| 722 | 723 | void handle_link_bounce(struct work_struct *work); |
| 723 | 724 | void handle_start_link(struct work_struct *work); |
| 724 | 725 | void handle_sma_message(struct work_struct *work); |
| 725 | −void reset_qsfp(struct hfi1_pportdata *ppd); | |
| 726 | +int reset_qsfp(struct hfi1_pportdata *ppd); | |
| 726 | 727 | void qsfp_event(struct work_struct *work); |
| 727 | 728 | void start_freeze_handling(struct hfi1_pportdata *ppd, int flags); |
| 728 | 729 | int send_idle_sma(struct hfi1_devdata *dd, u64 message); |
| @@ -204,7 +204,10 @@ done_asic: · 203 unmodified lines | ||
| 204 | 204 | return ret; |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | −/* magic character sequence that trails an image */ | |
| 207 | +/* magic character sequence that begins an image */ | |
| 208 | +#define IMAGE_START_MAGIC "APO=" | |
| 209 | + | |
| 210 | +/* magic character sequence that might trail an image */ | |
| 208 | 211 | #define IMAGE_TRAIL_MAGIC "egamiAPO" |
| 209 | 212 | |
| 210 | 213 | /* EPROM file types */ |
| @@ -250,6 +253,7 @@ static int read_partition_platform_config(struct hfi1_devdata *dd, void **data, · 39 unmodified lines | ||
| 250 | 253 | { |
| 251 | 254 | void *buffer; |
| 252 | 255 | void *p; |
| 256 | + u32 length; | |
| 253 | 257 | int ret; |
| 254 | 258 | |
| 255 | 259 | buffer = kmalloc(P1_SIZE, GFP_KERNEL); |
| @@ -262,15 +266,21 @@ static int read_partition_platform_config(struct hfi1_devdata *dd, void **data, · 6 unmodified lines | ||
| 262 | 266 | return ret; |
| 263 | 267 | } |
| 264 | 268 | |
| 265 | − /* scan for image magic that may trail the actual data */ | |
| 266 | − p = strnstr(buffer, IMAGE_TRAIL_MAGIC, P1_SIZE); | |
| 267 | − if (!p) { | |
| 269 | + /* config partition is valid only if it starts with IMAGE_START_MAGIC */ | |
| 270 | + if (memcmp(buffer, IMAGE_START_MAGIC, strlen(IMAGE_START_MAGIC))) { | |
| 268 | 271 | kfree(buffer); |
| 269 | 272 | return -ENOENT; |
| 270 | 273 | } |
| 271 | 274 | |
| 275 | + /* scan for image magic that may trail the actual data */ | |
| 276 | + p = strnstr(buffer, IMAGE_TRAIL_MAGIC, P1_SIZE); | |
| 277 | + if (p) | |
| 278 | + length = p - buffer; | |
| 279 | + else | |
| 280 | + length = P1_SIZE; | |
| 281 | + | |
| 272 | 282 | *data = buffer; |
| 273 | − *size = p - buffer; | |
| 283 | + *size = length; | |
| 274 | 284 | return 0; |
| 275 | 285 | } |
| 276 | 286 | |
| @@ -930,15 +930,8 @@ static int assign_ctxt(struct hfi1_filedata *fd, struct hfi1_user_info *uinfo) · 929 unmodified lines | ||
| 930 | 930 | switch (ret) { |
| 931 | 931 | case 0: |
| 932 | 932 | ret = setup_base_ctxt(fd, uctxt); |
| 933 | − if (uctxt->subctxt_cnt) { | |
| 934 | − /* | |
| 935 | − * Base context is done (successfully or not), notify | |
| 936 | − * anybody using a sub-context that is waiting for | |
| 937 | − * this completion. | |
| 938 | − */ | |
| 939 | − clear_bit(HFI1_CTXT_BASE_UNINIT, &uctxt->event_flags); | |
| 940 | − wake_up(&uctxt->wait); | |
| 941 | − } | |
| 933 | + if (ret) | |
| 934 | + deallocate_ctxt(uctxt); | |
| 942 | 935 | break; |
| 943 | 936 | case 1: |
| 944 | 937 | ret = complete_subctxt(fd); |
| @@ -1305,25 +1298,25 @@ static int setup_base_ctxt(struct hfi1_filedata *fd, · 360 unmodified lines | ||
| 1305 | 1298 | /* Now allocate the RcvHdr queue and eager buffers. */ |
| 1306 | 1299 | ret = hfi1_create_rcvhdrq(dd, uctxt); |
| 1307 | 1300 | if (ret) |
| 1308 | − return ret; | |
| 1301 | + goto done; | |
| 1309 | 1302 | |
| 1310 | 1303 | ret = hfi1_setup_eagerbufs(uctxt); |
| 1311 | 1304 | if (ret) |
| 1312 | − goto setup_failed; | |
| 1305 | + goto done; | |
| 1313 | 1306 | |
| 1314 | 1307 | /* If sub-contexts are enabled, do the appropriate setup */ |
| 1315 | 1308 | if (uctxt->subctxt_cnt) |
| 1316 | 1309 | ret = setup_subctxt(uctxt); |
| 1317 | 1310 | if (ret) |
| 1318 | − goto setup_failed; | |
| 1311 | + goto done; | |
| 1319 | 1312 | |
| 1320 | 1313 | ret = hfi1_alloc_ctxt_rcv_groups(uctxt); |
| 1321 | 1314 | if (ret) |
| 1322 | − goto setup_failed; | |
| 1315 | + goto done; | |
| 1323 | 1316 | |
| 1324 | 1317 | ret = init_user_ctxt(fd, uctxt); |
| 1325 | 1318 | if (ret) |
| 1326 | − goto setup_failed; | |
| 1319 | + goto done; | |
| 1327 | 1320 | |
| 1328 | 1321 | user_init(uctxt); |
| 1329 | 1322 | |
| @@ -1331,12 +1324,22 @@ static int setup_base_ctxt(struct hfi1_filedata *fd, · 1 unmodified line | ||
| 1331 | 1324 | fd->uctxt = uctxt; |
| 1332 | 1325 | hfi1_rcd_get(uctxt); |
| 1333 | 1326 | |
| 1334 | − return 0; | |
| 1327 | +done: | |
| 1328 | + if (uctxt->subctxt_cnt) { | |
| 1329 | + /* | |
| 1330 | + * On error, set the failed bit so sub-contexts will clean up | |
| 1331 | + * correctly. | |
| 1332 | + */ | |
| 1333 | + if (ret) | |
| 1334 | + set_bit(HFI1_CTXT_BASE_FAILED, &uctxt->event_flags); | |
| 1335 | 1335 | |
| 1336 | −setup_failed: | |
| 1337 | − /* Set the failed bit so sub-context init can do the right thing */ | |
| 1338 | − set_bit(HFI1_CTXT_BASE_FAILED, &uctxt->event_flags); | |
| 1339 | − deallocate_ctxt(uctxt); | |
| 1336 | + /* | |
| 1337 | + * Base context is done (successfully or not), notify anybody | |
| 1338 | + * using a sub-context that is waiting for this completion. | |
| 1339 | + */ | |
| 1340 | + clear_bit(HFI1_CTXT_BASE_UNINIT, &uctxt->event_flags); | |
| 1341 | + wake_up(&uctxt->wait); | |
| 1342 | + } | |
| 1340 | 1343 | |
| 1341 | 1344 | return ret; |
| 1342 | 1345 | } |
| @@ -68,7 +68,7 @@ · 67 unmodified lines | ||
| 68 | 68 | /* |
| 69 | 69 | * Code to adjust PCIe capabilities. |
| 70 | 70 | */ |
| 71 | −static int tune_pcie_caps(struct hfi1_devdata *); | |
| 71 | +static void tune_pcie_caps(struct hfi1_devdata *); | |
| 72 | 72 | |
| 73 | 73 | /* |
| 74 | 74 | * Do all the common PCIe setup and initialization. |
| @@ -351,7 +351,7 @@ int pcie_speeds(struct hfi1_devdata *dd) · 276 unmodified lines | ||
| 351 | 351 | */ |
| 352 | 352 | int request_msix(struct hfi1_devdata *dd, u32 msireq) |
| 353 | 353 | { |
| 354 | − int nvec, ret; | |
| 354 | + int nvec; | |
| 355 | 355 | |
| 356 | 356 | nvec = pci_alloc_irq_vectors(dd->pcidev, 1, msireq, |
| 357 | 357 | PCI_IRQ_MSIX | PCI_IRQ_LEGACY); |
| @@ -360,12 +360,7 @@ int request_msix(struct hfi1_devdata *dd, u32 msireq) · 2 unmodified lines | ||
| 360 | 360 | return nvec; |
| 361 | 361 | } |
| 362 | 362 | |
| 363 | − ret = tune_pcie_caps(dd); | |
| 364 | − if (ret) { | |
| 365 | − dd_dev_err(dd, "tune_pcie_caps() failed: %d\n", ret); | |
| 366 | − pci_free_irq_vectors(dd->pcidev); | |
| 367 | − return ret; | |
| 368 | − } | |
| 363 | + tune_pcie_caps(dd); | |
| 369 | 364 | |
| 370 | 365 | /* check for legacy IRQ */ |
| 371 | 366 | if (nvec == 1 && !dd->pcidev->msix_enabled) |
| @@ -502,7 +497,7 @@ uint aspm_mode = ASPM_MODE_DISABLED; · 130 unmodified lines | ||
| 502 | 497 | module_param_named(aspm, aspm_mode, uint, S_IRUGO); |
| 503 | 498 | MODULE_PARM_DESC(aspm, "PCIe ASPM: 0: disable, 1: enable, 2: dynamic"); |
| 504 | 499 | |
| 505 | −static int tune_pcie_caps(struct hfi1_devdata *dd) | |
| 500 | +static void tune_pcie_caps(struct hfi1_devdata *dd) | |
| 506 | 501 | { |
| 507 | 502 | struct pci_dev *parent; |
| 508 | 503 | u16 rc_mpss, rc_mps, ep_mpss, ep_mps; |
| @@ -513,22 +508,14 @@ static int tune_pcie_caps(struct hfi1_devdata *dd) · 4 unmodified lines | ||
| 513 | 508 | * Turn on extended tags in DevCtl in case the BIOS has turned it off |
| 514 | 509 | * to improve WFR SDMA bandwidth |
| 515 | 510 | */ |
| 516 | − ret = pcie_capability_read_word(dd->pcidev, | |
| 517 | − PCI_EXP_DEVCTL, &ectl); | |
| 518 | − if (ret) { | |
| 519 | − dd_dev_err(dd, "Unable to read from PCI config\n"); | |
| 520 | − return ret; | |
| 521 | − } | |
| 522 | − | |
| 523 | − if (!(ectl & PCI_EXP_DEVCTL_EXT_TAG)) { | |
| 511 | + ret = pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL, &ectl); | |
| 512 | + if ((!ret) && !(ectl & PCI_EXP_DEVCTL_EXT_TAG)) { | |
| 524 | 513 | dd_dev_info(dd, "Enabling PCIe extended tags\n"); |
| 525 | 514 | ectl |= PCI_EXP_DEVCTL_EXT_TAG; |
| 526 | 515 | ret = pcie_capability_write_word(dd->pcidev, |
| 527 | 516 | PCI_EXP_DEVCTL, ectl); |
| 528 | − if (ret) { | |
| 529 | − dd_dev_err(dd, "Unable to write to PCI config\n"); | |
| 530 | − return ret; | |
| 531 | − } | |
| 517 | + if (ret) | |
| 518 | + dd_dev_info(dd, "Unable to write to PCI config\n"); | |
| 532 | 519 | } |
| 533 | 520 | /* Find out supported and configured values for parent (root) */ |
| 534 | 521 | parent = dd->pcidev->bus->self; |
| @@ -536,15 +523,22 @@ static int tune_pcie_caps(struct hfi1_devdata *dd) · 1 unmodified line | ||
| 536 | 523 | * The driver cannot perform the tuning if it does not have |
| 537 | 524 | * access to the upstream component. |
| 538 | 525 | */ |
| 539 | − if (!parent) | |
| 540 | − return -EINVAL; | |
| 526 | + if (!parent) { | |
| 527 | + dd_dev_info(dd, "Parent not found\n"); | |
| 528 | + return; | |
| 529 | + } | |
| 541 | 530 | if (!pci_is_root_bus(parent->bus)) { |
| 542 | 531 | dd_dev_info(dd, "Parent not root\n"); |
| 543 | − return -EINVAL; | |
| 532 | + return; | |
| 533 | + } | |
| 534 | + if (!pci_is_pcie(parent)) { | |
| 535 | + dd_dev_info(dd, "Parent is not PCI Express capable\n"); | |
| 536 | + return; | |
| 537 | + } | |
| 538 | + if (!pci_is_pcie(dd->pcidev)) { | |
| 539 | + dd_dev_info(dd, "PCI device is not PCI Express capable\n"); | |
| 540 | + return; | |
| 544 | 541 | } |
| 545 | − | |
| 546 | − if (!pci_is_pcie(parent) || !pci_is_pcie(dd->pcidev)) | |
| 547 | − return -EINVAL; | |
| 548 | 542 | rc_mpss = parent->pcie_mpss; |
| 549 | 543 | rc_mps = ffs(pcie_get_mps(parent)) - 8; |
| 550 | 544 | /* Find out supported and configured values for endpoint (us) */ |
| @@ -590,8 +584,6 @@ static int tune_pcie_caps(struct hfi1_devdata *dd) · 39 unmodified lines | ||
| 590 | 584 | ep_mrrs = max_mrrs; |
| 591 | 585 | pcie_set_readrq(dd->pcidev, ep_mrrs); |
| 592 | 586 | } |
| 593 | − | |
| 594 | − return 0; | |
| 595 | 587 | } |
| 596 | 588 | |
| 597 | 589 | /* End of PCIe capability tuning */ |
| @@ -790,7 +790,9 @@ static int tune_active_qsfp(struct hfi1_pportdata *ppd, u32 *ptr_tx_preset, · 789 unmodified lines | ||
| 790 | 790 | * reuse of stale settings established in our previous pass through. |
| 791 | 791 | */ |
| 792 | 792 | if (ppd->qsfp_info.reset_needed) { |
| 793 | − reset_qsfp(ppd); | |
| 793 | + ret = reset_qsfp(ppd); | |
| 794 | + if (ret) | |
| 795 | + return ret; | |
| 794 | 796 | refresh_qsfp_cache(ppd, &ppd->qsfp_info); |
| 795 | 797 | } else { |
| 796 | 798 | ppd->qsfp_info.reset_needed = 1; |
| @@ -201,7 +201,6 @@ enum init_completion_state { · 200 unmodified lines | ||
| 201 | 201 | CEQ_CREATED, |
| 202 | 202 | ILQ_CREATED, |
| 203 | 203 | IEQ_CREATED, |
| 204 | − INET_NOTIFIER, | |
| 205 | 204 | IP_ADDR_REGISTERED, |
| 206 | 205 | RDMA_DEV_REGISTERED |
| 207 | 206 | }; |
| @@ -1504,23 +1504,40 @@ static void i40iw_add_hte_node(struct i40iw_cm_core *cm_core, · 1503 unmodified lines | ||
| 1504 | 1504 | } |
| 1505 | 1505 | |
| 1506 | 1506 | /** |
| 1507 | − * listen_port_in_use - determine if port is in use | |
| 1508 | − * @port: Listen port number | |
| 1507 | + * i40iw_port_in_use - determine if port is in use | |
| 1508 | + * @port: port number | |
| 1509 | + * @active_side: flag for listener side vs active side | |
| 1509 | 1510 | */ |
| 1510 | −static bool i40iw_listen_port_in_use(struct i40iw_cm_core *cm_core, u16 port) | |
| 1511 | +static bool i40iw_port_in_use(struct i40iw_cm_core *cm_core, u16 port, bool active_side) | |
| 1511 | 1512 | { |
| 1512 | 1513 | struct i40iw_cm_listener *listen_node; |
| 1514 | + struct i40iw_cm_node *cm_node; | |
| 1513 | 1515 | unsigned long flags; |
| 1514 | 1516 | bool ret = false; |
| 1515 | 1517 | |
| 1516 | − spin_lock_irqsave(&cm_core->listen_list_lock, flags); | |
| 1517 | − list_for_each_entry(listen_node, &cm_core->listen_nodes, list) { | |
| 1518 | − if (listen_node->loc_port == port) { | |
| 1519 | − ret = true; | |
| 1520 | − break; | |
| 1518 | + if (active_side) { | |
| 1519 | + /* search connected node list */ | |
| 1520 | + spin_lock_irqsave(&cm_core->ht_lock, flags); | |
| 1521 | + list_for_each_entry(cm_node, &cm_core->connected_nodes, list) { | |
| 1522 | + if (cm_node->loc_port == port) { | |
| 1523 | + ret = true; | |
| 1524 | + break; | |
| 1525 | + } | |
| 1526 | + } | |
| 1527 | + if (!ret) | |
| 1528 | + clear_bit(port, cm_core->active_side_ports); | |
| 1529 | + spin_unlock_irqrestore(&cm_core->ht_lock, flags); | |
| 1530 | + } else { | |
| 1531 | + spin_lock_irqsave(&cm_core->listen_list_lock, flags); | |
| 1532 | + list_for_each_entry(listen_node, &cm_core->listen_nodes, list) { | |
| 1533 | + if (listen_node->loc_port == port) { | |
| 1534 | + ret = true; | |
| 1535 | + break; | |
| 1536 | + } | |
| 1521 | 1537 | } |
| 1538 | + spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); | |
| 1522 | 1539 | } |
| 1523 | − spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); | |
| 1540 | + | |
| 1524 | 1541 | return ret; |
| 1525 | 1542 | } |
| 1526 | 1543 | |
| @@ -1868,7 +1885,7 @@ static int i40iw_dec_refcnt_listen(struct i40iw_cm_core *cm_core, · 341 unmodified lines | ||
| 1868 | 1885 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); |
| 1869 | 1886 | |
| 1870 | 1887 | if (listener->iwdev) { |
| 1871 | − if (apbvt_del && !i40iw_listen_port_in_use(cm_core, listener->loc_port)) | |
| 1888 | + if (apbvt_del && !i40iw_port_in_use(cm_core, listener->loc_port, false)) | |
| 1872 | 1889 | i40iw_manage_apbvt(listener->iwdev, |
| 1873 | 1890 | listener->loc_port, |
| 1874 | 1891 | I40IW_MANAGE_APBVT_DEL); |
| @@ -2247,21 +2264,21 @@ static void i40iw_rem_ref_cm_node(struct i40iw_cm_node *cm_node) · 372 unmodified lines | ||
| 2247 | 2264 | if (cm_node->listener) { |
| 2248 | 2265 | i40iw_dec_refcnt_listen(cm_core, cm_node->listener, 0, true); |
| 2249 | 2266 | } else { |
| 2250 | − if (!i40iw_listen_port_in_use(cm_core, cm_node->loc_port) && | |
| 2251 | − cm_node->apbvt_set) { | |
| 2267 | + if (!i40iw_port_in_use(cm_core, cm_node->loc_port, true) && cm_node->apbvt_set) { | |
| 2252 | 2268 | i40iw_manage_apbvt(cm_node->iwdev, |
| 2253 | 2269 | cm_node->loc_port, |
| 2254 | 2270 | I40IW_MANAGE_APBVT_DEL); |
| 2255 | − i40iw_get_addr_info(cm_node, &nfo); | |
| 2256 | − if (cm_node->qhash_set) { | |
| 2257 | − i40iw_manage_qhash(cm_node->iwdev, | |
| 2258 | − &nfo, | |
| 2259 | − I40IW_QHASH_TYPE_TCP_ESTABLISHED, | |
| 2260 | − I40IW_QHASH_MANAGE_TYPE_DELETE, | |
| 2261 | − NULL, | |
| 2262 | − false); | |
| 2263 | − cm_node->qhash_set = 0; | |
| 2264 | − } | |
| 2271 | + cm_node->apbvt_set = 0; | |
| 2272 | + } | |
| 2273 | + i40iw_get_addr_info(cm_node, &nfo); | |
| 2274 | + if (cm_node->qhash_set) { | |
| 2275 | + i40iw_manage_qhash(cm_node->iwdev, | |
| 2276 | + &nfo, | |
| 2277 | + I40IW_QHASH_TYPE_TCP_ESTABLISHED, | |
| 2278 | + I40IW_QHASH_MANAGE_TYPE_DELETE, | |
| 2279 | + NULL, | |
| 2280 | + false); | |
| 2281 | + cm_node->qhash_set = 0; | |
| 2265 | 2282 | } |
| 2266 | 2283 | } |
| 2267 | 2284 | |
| @@ -3255,7 +3272,8 @@ static void i40iw_init_tcp_ctx(struct i40iw_cm_node *cm_node, · 987 unmodified lines | ||
| 3255 | 3272 | tcp_info->snd_mss = cpu_to_le32(((u32)cm_node->tcp_cntxt.mss)); |
| 3256 | 3273 | if (cm_node->vlan_id < VLAN_TAG_PRESENT) { |
| 3257 | 3274 | tcp_info->insert_vlan_tag = true; |
| 3258 | − tcp_info->vlan_tag = cpu_to_le16(cm_node->vlan_id); | |
| 3275 | + tcp_info->vlan_tag = cpu_to_le16(((u16)cm_node->user_pri << I40IW_VLAN_PRIO_SHIFT) | | |
| 3276 | + cm_node->vlan_id); | |
| 3259 | 3277 | } |
| 3260 | 3278 | if (cm_node->ipv4) { |
| 3261 | 3279 | tcp_info->src_port = cpu_to_le16(cm_node->loc_port); |
| @@ -3737,10 +3755,8 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 475 unmodified lines | ||
| 3737 | 3755 | struct sockaddr_in *raddr; |
| 3738 | 3756 | struct sockaddr_in6 *laddr6; |
| 3739 | 3757 | struct sockaddr_in6 *raddr6; |
| 3740 | − bool qhash_set = false; | |
| 3741 | − int apbvt_set = 0; | |
| 3742 | − int err = 0; | |
| 3743 | − enum i40iw_status_code status; | |
| 3758 | + int ret = 0; | |
| 3759 | + unsigned long flags; | |
| 3744 | 3760 | |
| 3745 | 3761 | ibqp = i40iw_get_qp(cm_id->device, conn_param->qpn); |
| 3746 | 3762 | if (!ibqp) |
| @@ -3789,32 +3805,6 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 42 unmodified lines | ||
| 3789 | 3805 | cm_info.user_pri = rt_tos2priority(cm_id->tos); |
| 3790 | 3806 | i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB, "%s TOS:[%d] UP:[%d]\n", |
| 3791 | 3807 | __func__, cm_id->tos, cm_info.user_pri); |
| 3792 | − if ((cm_info.ipv4 && (laddr->sin_addr.s_addr != raddr->sin_addr.s_addr)) || | |
| 3793 | − (!cm_info.ipv4 && memcmp(laddr6->sin6_addr.in6_u.u6_addr32, | |
| 3794 | − raddr6->sin6_addr.in6_u.u6_addr32, | |
| 3795 | − sizeof(laddr6->sin6_addr.in6_u.u6_addr32)))) { | |
| 3796 | − status = i40iw_manage_qhash(iwdev, | |
| 3797 | − &cm_info, | |
| 3798 | − I40IW_QHASH_TYPE_TCP_ESTABLISHED, | |
| 3799 | − I40IW_QHASH_MANAGE_TYPE_ADD, | |
| 3800 | − NULL, | |
| 3801 | − true); | |
| 3802 | − if (status) | |
| 3803 | − return -EINVAL; | |
| 3804 | − qhash_set = true; | |
| 3805 | − } | |
| 3806 | − status = i40iw_manage_apbvt(iwdev, cm_info.loc_port, I40IW_MANAGE_APBVT_ADD); | |
| 3807 | − if (status) { | |
| 3808 | − i40iw_manage_qhash(iwdev, | |
| 3809 | − &cm_info, | |
| 3810 | − I40IW_QHASH_TYPE_TCP_ESTABLISHED, | |
| 3811 | − I40IW_QHASH_MANAGE_TYPE_DELETE, | |
| 3812 | − NULL, | |
| 3813 | − false); | |
| 3814 | − return -EINVAL; | |
| 3815 | − } | |
| 3816 | − | |
| 3817 | − apbvt_set = 1; | |
| 3818 | 3808 | cm_id->add_ref(cm_id); |
| 3819 | 3809 | cm_node = i40iw_create_cm_node(&iwdev->cm_core, iwdev, |
| 3820 | 3810 | conn_param->private_data_len, |
| @@ -3822,17 +3812,40 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 1 unmodified line | ||
| 3822 | 3812 | &cm_info); |
| 3823 | 3813 | |
| 3824 | 3814 | if (IS_ERR(cm_node)) { |
| 3825 | − err = PTR_ERR(cm_node); | |
| 3826 | − goto err_out; | |
| 3815 | + ret = PTR_ERR(cm_node); | |
| 3816 | + cm_id->rem_ref(cm_id); | |
| 3817 | + return ret; | |
| 3818 | + } | |
| 3819 | + | |
| 3820 | + if ((cm_info.ipv4 && (laddr->sin_addr.s_addr != raddr->sin_addr.s_addr)) || | |
| 3821 | + (!cm_info.ipv4 && memcmp(laddr6->sin6_addr.in6_u.u6_addr32, | |
| 3822 | + raddr6->sin6_addr.in6_u.u6_addr32, | |
| 3823 | + sizeof(laddr6->sin6_addr.in6_u.u6_addr32)))) { | |
| 3824 | + if (i40iw_manage_qhash(iwdev, &cm_info, I40IW_QHASH_TYPE_TCP_ESTABLISHED, | |
| 3825 | + I40IW_QHASH_MANAGE_TYPE_ADD, NULL, true)) { | |
| 3826 | + ret = -EINVAL; | |
| 3827 | + goto err; | |
| 3828 | + } | |
| 3829 | + cm_node->qhash_set = true; | |
| 3827 | 3830 | } |
| 3828 | 3831 | |
| 3832 | + spin_lock_irqsave(&iwdev->cm_core.ht_lock, flags); | |
| 3833 | + if (!test_and_set_bit(cm_info.loc_port, iwdev->cm_core.active_side_ports)) { | |
| 3834 | + spin_unlock_irqrestore(&iwdev->cm_core.ht_lock, flags); | |
| 3835 | + if (i40iw_manage_apbvt(iwdev, cm_info.loc_port, I40IW_MANAGE_APBVT_ADD)) { | |
| 3836 | + ret = -EINVAL; | |
| 3837 | + goto err; | |
| 3838 | + } | |
| 3839 | + } else { | |
| 3840 | + spin_unlock_irqrestore(&iwdev->cm_core.ht_lock, flags); | |
| 3841 | + } | |
| 3842 | + | |
| 3843 | + cm_node->apbvt_set = true; | |
| 3829 | 3844 | i40iw_record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord); |
| 3830 | 3845 | if (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO && |
| 3831 | 3846 | !cm_node->ord_size) |
| 3832 | 3847 | cm_node->ord_size = 1; |
| 3833 | 3848 | |
| 3834 | − cm_node->apbvt_set = apbvt_set; | |
| 3835 | − cm_node->qhash_set = qhash_set; | |
| 3836 | 3849 | iwqp->cm_node = cm_node; |
| 3837 | 3850 | cm_node->iwqp = iwqp; |
| 3838 | 3851 | iwqp->cm_id = cm_id; |
| @@ -3840,11 +3853,9 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 1 unmodified line | ||
| 3840 | 3853 | |
| 3841 | 3854 | if (cm_node->state != I40IW_CM_STATE_OFFLOADED) { |
| 3842 | 3855 | cm_node->state = I40IW_CM_STATE_SYN_SENT; |
| 3843 | − err = i40iw_send_syn(cm_node, 0); | |
| 3844 | − if (err) { | |
| 3845 | − i40iw_rem_ref_cm_node(cm_node); | |
| 3846 | − goto err_out; | |
| 3847 | − } | |
| 3856 | + ret = i40iw_send_syn(cm_node, 0); | |
| 3857 | + if (ret) | |
| 3858 | + goto err; | |
| 3848 | 3859 | } |
| 3849 | 3860 | |
| 3850 | 3861 | i40iw_debug(cm_node->dev, |
| @@ -3853,9 +3864,10 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 2 unmodified lines | ||
| 3853 | 3864 | cm_node->rem_port, |
| 3854 | 3865 | cm_node, |
| 3855 | 3866 | cm_node->cm_id); |
| 3867 | + | |
| 3856 | 3868 | return 0; |
| 3857 | 3869 | |
| 3858 | −err_out: | |
| 3870 | +err: | |
| 3859 | 3871 | if (cm_info.ipv4) |
| 3860 | 3872 | i40iw_debug(&iwdev->sc_dev, |
| 3861 | 3873 | I40IW_DEBUG_CM, |
| @@ -3867,22 +3879,10 @@ err_out: · 5 unmodified lines | ||
| 3867 | 3879 | "Api - connect() FAILED: dest addr=%pI6", |
| 3868 | 3880 | cm_info.rem_addr); |
| 3869 | 3881 | |
| 3870 | − if (qhash_set) | |
| 3871 | − i40iw_manage_qhash(iwdev, | |
| 3872 | − &cm_info, | |
| 3873 | − I40IW_QHASH_TYPE_TCP_ESTABLISHED, | |
| 3874 | − I40IW_QHASH_MANAGE_TYPE_DELETE, | |
| 3875 | − NULL, | |
| 3876 | − false); | |
| 3877 | − | |
| 3878 | − if (apbvt_set && !i40iw_listen_port_in_use(&iwdev->cm_core, | |
| 3879 | − cm_info.loc_port)) | |
| 3880 | − i40iw_manage_apbvt(iwdev, | |
| 3881 | − cm_info.loc_port, | |
| 3882 | − I40IW_MANAGE_APBVT_DEL); | |
| 3882 | + i40iw_rem_ref_cm_node(cm_node); | |
| 3883 | 3883 | cm_id->rem_ref(cm_id); |
| 3884 | 3884 | iwdev->cm_core.stats_connect_errs++; |
| 3885 | − return err; | |
| 3885 | + return ret; | |
| 3886 | 3886 | } |
| 3887 | 3887 | |
| 3888 | 3888 | /** |
| @@ -71,6 +71,9 @@ · 70 unmodified lines | ||
| 71 | 71 | #define I40IW_HW_IRD_SETTING_32 32 |
| 72 | 72 | #define I40IW_HW_IRD_SETTING_64 64 |
| 73 | 73 | |
| 74 | +#define MAX_PORTS 65536 | |
| 75 | +#define I40IW_VLAN_PRIO_SHIFT 13 | |
| 76 | + | |
| 74 | 77 | enum ietf_mpa_flags { |
| 75 | 78 | IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ |
| 76 | 79 | IETF_MPA_FLAGS_CRC = 0x40, /* receive Markers */ |
| @@ -411,6 +414,8 @@ struct i40iw_cm_core { · 334 unmodified lines | ||
| 411 | 414 | spinlock_t ht_lock; /* manage hash table */ |
| 412 | 415 | spinlock_t listen_list_lock; /* listen list */ |
| 413 | 416 | |
| 417 | + unsigned long active_side_ports[BITS_TO_LONGS(MAX_PORTS)]; | |
| 418 | + | |
| 414 | 419 | u64 stats_nodes_created; |
| 415 | 420 | u64 stats_nodes_destroyed; |
| 416 | 421 | u64 stats_listen_created; |
| @@ -48,7 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | * @wqe: cqp wqe for header |
| 49 | 49 | * @header: header for the cqp wqe |
| 50 | 50 | */ |
| 51 | −static inline void i40iw_insert_wqe_hdr(u64 *wqe, u64 header) | |
| 51 | +void i40iw_insert_wqe_hdr(u64 *wqe, u64 header) | |
| 52 | 52 | { |
| 53 | 53 | wmb(); /* make sure WQE is populated before polarity is set */ |
| 54 | 54 | set_64bit_val(wqe, 24, header); |
| @@ -99,8 +99,6 @@ static struct notifier_block i40iw_net_notifier = { · 98 unmodified lines | ||
| 99 | 99 | .notifier_call = i40iw_net_event |
| 100 | 100 | }; |
| 101 | 101 | |
| 102 | −static atomic_t i40iw_notifiers_registered; | |
| 103 | − | |
| 104 | 102 | /** |
| 105 | 103 | * i40iw_find_i40e_handler - find a handler given a client info |
| 106 | 104 | * @ldev: pointer to a client info |
| @@ -1376,11 +1374,20 @@ error: · 1269 unmodified lines | ||
| 1376 | 1374 | */ |
| 1377 | 1375 | static void i40iw_register_notifiers(void) |
| 1378 | 1376 | { |
| 1379 | − if (atomic_inc_return(&i40iw_notifiers_registered) == 1) { | |
| 1380 | − register_inetaddr_notifier(&i40iw_inetaddr_notifier); | |
| 1381 | − register_inet6addr_notifier(&i40iw_inetaddr6_notifier); | |
| 1382 | − register_netevent_notifier(&i40iw_net_notifier); | |
| 1383 | − } | |
| 1377 | + register_inetaddr_notifier(&i40iw_inetaddr_notifier); | |
| 1378 | + register_inet6addr_notifier(&i40iw_inetaddr6_notifier); | |
| 1379 | + register_netevent_notifier(&i40iw_net_notifier); | |
| 1380 | +} | |
| 1381 | + | |
| 1382 | +/** | |
| 1383 | + * i40iw_unregister_notifiers - unregister tcp ip notifiers | |
| 1384 | + */ | |
| 1385 | + | |
| 1386 | +static void i40iw_unregister_notifiers(void) | |
| 1387 | +{ | |
| 1388 | + unregister_netevent_notifier(&i40iw_net_notifier); | |
| 1389 | + unregister_inetaddr_notifier(&i40iw_inetaddr_notifier); | |
| 1390 | + unregister_inet6addr_notifier(&i40iw_inetaddr6_notifier); | |
| 1384 | 1391 | } |
| 1385 | 1392 | |
| 1386 | 1393 | /** |
| @@ -1400,6 +1407,11 @@ static enum i40iw_status_code i40iw_save_msix_info(struct i40iw_device *iwdev, · 13 unmodified lines | ||
| 1400 | 1407 | u32 i; |
| 1401 | 1408 | u32 size; |
| 1402 | 1409 | |
| 1410 | + if (!ldev->msix_count) { | |
| 1411 | + i40iw_pr_err("No MSI-X vectors\n"); | |
| 1412 | + return I40IW_ERR_CONFIG; | |
| 1413 | + } | |
| 1414 | + | |
| 1403 | 1415 | iwdev->msix_count = ldev->msix_count; |
| 1404 | 1416 | |
| 1405 | 1417 | size = sizeof(struct i40iw_msix_vector) * iwdev->msix_count; |
| @@ -1462,12 +1474,6 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev) · 56 unmodified lines | ||
| 1462 | 1474 | if (!iwdev->reset) |
| 1463 | 1475 | i40iw_del_macip_entry(iwdev, (u8)iwdev->mac_ip_table_idx); |
| 1464 | 1476 | /* fallthrough */ |
| 1465 | − case INET_NOTIFIER: | |
| 1466 | − if (!atomic_dec_return(&i40iw_notifiers_registered)) { | |
| 1467 | − unregister_netevent_notifier(&i40iw_net_notifier); | |
| 1468 | − unregister_inetaddr_notifier(&i40iw_inetaddr_notifier); | |
| 1469 | − unregister_inet6addr_notifier(&i40iw_inetaddr6_notifier); | |
| 1470 | − } | |
| 1471 | 1477 | /* fallthrough */ |
| 1472 | 1478 | case PBLE_CHUNK_MEM: |
| 1473 | 1479 | i40iw_destroy_pble_pool(dev, iwdev->pble_rsrc); |
| @@ -1550,7 +1556,7 @@ static enum i40iw_status_code i40iw_setup_init_state(struct i40iw_handler *hdl, · 76 unmodified lines | ||
| 1550 | 1556 | |
| 1551 | 1557 | status = i40iw_save_msix_info(iwdev, ldev); |
| 1552 | 1558 | if (status) |
| 1553 | − goto exit; | |
| 1559 | + return status; | |
| 1554 | 1560 | iwdev->hw.dev_context = (void *)ldev->pcidev; |
| 1555 | 1561 | iwdev->hw.hw_addr = ldev->hw_addr; |
| 1556 | 1562 | status = i40iw_allocate_dma_mem(&iwdev->hw, |
| @@ -1667,8 +1673,6 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client) · 110 unmodified lines | ||
| 1667 | 1673 | break; |
| 1668 | 1674 | iwdev->init_state = PBLE_CHUNK_MEM; |
| 1669 | 1675 | iwdev->virtchnl_wq = alloc_ordered_workqueue("iwvch", WQ_MEM_RECLAIM); |
| 1670 | − i40iw_register_notifiers(); | |
| 1671 | − iwdev->init_state = INET_NOTIFIER; | |
| 1672 | 1676 | status = i40iw_add_mac_ip(iwdev); |
| 1673 | 1677 | if (status) |
| 1674 | 1678 | break; |
| @@ -2018,6 +2022,8 @@ static int __init i40iw_init_module(void) · 343 unmodified lines | ||
| 2018 | 2022 | i40iw_client.type = I40E_CLIENT_IWARP; |
| 2019 | 2023 | spin_lock_init(&i40iw_handler_lock); |
| 2020 | 2024 | ret = i40e_register_client(&i40iw_client); |
| 2025 | + i40iw_register_notifiers(); | |
| 2026 | + | |
| 2021 | 2027 | return ret; |
| 2022 | 2028 | } |
| 2023 | 2029 | |
| @@ -2029,6 +2035,7 @@ static int __init i40iw_init_module(void) · 5 unmodified lines | ||
| 2029 | 2035 | */ |
| 2030 | 2036 | static void __exit i40iw_exit_module(void) |
| 2031 | 2037 | { |
| 2038 | + i40iw_unregister_notifiers(); | |
| 2032 | 2039 | i40e_unregister_client(&i40iw_client); |
| 2033 | 2040 | } |
| 2034 | 2041 | |
| @@ -59,6 +59,8 @@ enum i40iw_status_code i40iw_sc_mr_fast_register(struct i40iw_sc_qp *qp, · 58 unmodified lines | ||
| 59 | 59 | struct i40iw_fast_reg_stag_info *info, |
| 60 | 60 | bool post_sq); |
| 61 | 61 | |
| 62 | +void i40iw_insert_wqe_hdr(u64 *wqe, u64 header); | |
| 63 | + | |
| 62 | 64 | /* HMC/FPM functions */ |
| 63 | 65 | enum i40iw_status_code i40iw_sc_init_iw_hmc(struct i40iw_sc_dev *dev, |
| 64 | 66 | u8 hmc_fn_id); |
| @@ -123,12 +123,11 @@ static void i40iw_puda_post_recvbuf(struct i40iw_puda_rsrc *rsrc, u32 wqe_idx, · 122 unmodified lines | ||
| 123 | 123 | get_64bit_val(wqe, 24, &offset24); |
| 124 | 124 | |
| 125 | 125 | offset24 = (offset24) ? 0 : LS_64(1, I40IWQPSQ_VALID); |
| 126 | − set_64bit_val(wqe, 24, offset24); | |
| 127 | 126 | |
| 128 | 127 | set_64bit_val(wqe, 0, buf->mem.pa); |
| 129 | 128 | set_64bit_val(wqe, 8, |
| 130 | 129 | LS_64(buf->mem.size, I40IWQPSQ_FRAG_LEN)); |
| 131 | − set_64bit_val(wqe, 24, offset24); | |
| 130 | + i40iw_insert_wqe_hdr(wqe, offset24); | |
| 132 | 131 | } |
| 133 | 132 | |
| 134 | 133 | /** |
| @@ -409,9 +408,7 @@ enum i40iw_status_code i40iw_puda_send(struct i40iw_sc_qp *qp, · 274 unmodified lines | ||
| 409 | 408 | set_64bit_val(wqe, 8, LS_64(info->len, I40IWQPSQ_FRAG_LEN)); |
| 410 | 409 | set_64bit_val(wqe, 16, header[0]); |
| 411 | 410 | |
| 412 | − /* Ensure all data is written before writing valid bit */ | |
| 413 | − wmb(); | |
| 414 | − set_64bit_val(wqe, 24, header[1]); | |
| 411 | + i40iw_insert_wqe_hdr(wqe, header[1]); | |
| 415 | 412 | |
| 416 | 413 | i40iw_debug_buf(qp->dev, I40IW_DEBUG_PUDA, "PUDA SEND WQE", wqe, 32); |
| 417 | 414 | i40iw_qp_post_wr(&qp->qp_uk); |
| @@ -539,7 +536,7 @@ static enum i40iw_status_code i40iw_puda_qp_wqe(struct i40iw_sc_dev *dev, struct · 121 unmodified lines | ||
| 539 | 536 | LS_64(2, I40IW_CQPSQ_QP_NEXTIWSTATE) | |
| 540 | 537 | LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID); |
| 541 | 538 | |
| 542 | − set_64bit_val(wqe, 24, header); | |
| 539 | + i40iw_insert_wqe_hdr(wqe, header); | |
| 543 | 540 | |
| 544 | 541 | i40iw_debug_buf(cqp->dev, I40IW_DEBUG_PUDA, "PUDA CQE", wqe, 32); |
| 545 | 542 | i40iw_sc_cqp_post_sq(cqp); |
| @@ -655,7 +652,7 @@ static enum i40iw_status_code i40iw_puda_cq_wqe(struct i40iw_sc_dev *dev, struct · 109 unmodified lines | ||
| 655 | 652 | LS_64(1, I40IW_CQPSQ_CQ_ENCEQEMASK) | |
| 656 | 653 | LS_64(1, I40IW_CQPSQ_CQ_CEQIDVALID) | |
| 657 | 654 | LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID); |
| 658 | − set_64bit_val(wqe, 24, header); | |
| 655 | + i40iw_insert_wqe_hdr(wqe, header); | |
| 659 | 656 | |
| 660 | 657 | i40iw_debug_buf(dev, I40IW_DEBUG_PUDA, "PUDA CQE", |
| 661 | 658 | wqe, I40IW_CQP_WQE_SIZE * 8); |
| @@ -160,7 +160,7 @@ int i40iw_inetaddr_event(struct notifier_block *notifier, · 159 unmodified lines | ||
| 160 | 160 | return NOTIFY_DONE; |
| 161 | 161 | |
| 162 | 162 | iwdev = &hdl->device; |
| 163 | − if (iwdev->init_state < INET_NOTIFIER) | |
| 163 | + if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) | |
| 164 | 164 | return NOTIFY_DONE; |
| 165 | 165 | |
| 166 | 166 | netdev = iwdev->ldev->netdev; |
| @@ -217,7 +217,7 @@ int i40iw_inet6addr_event(struct notifier_block *notifier, · 50 unmodified lines | ||
| 217 | 217 | return NOTIFY_DONE; |
| 218 | 218 | |
| 219 | 219 | iwdev = &hdl->device; |
| 220 | − if (iwdev->init_state < INET_NOTIFIER) | |
| 220 | + if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) | |
| 221 | 221 | return NOTIFY_DONE; |
| 222 | 222 | |
| 223 | 223 | netdev = iwdev->ldev->netdev; |
| @@ -266,7 +266,7 @@ int i40iw_net_event(struct notifier_block *notifier, unsigned long event, void * · 42 unmodified lines | ||
| 266 | 266 | if (!iwhdl) |
| 267 | 267 | return NOTIFY_DONE; |
| 268 | 268 | iwdev = &iwhdl->device; |
| 269 | − if (iwdev->init_state < INET_NOTIFIER) | |
| 269 | + if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) | |
| 270 | 270 | return NOTIFY_DONE; |
| 271 | 271 | p = (__be32 *)neigh->primary_key; |
| 272 | 272 | i40iw_copy_ip_ntohl(local_ipaddr, p); |
| @@ -826,12 +826,14 @@ static int i40iw_query_qp(struct ib_qp *ibqp, · 825 unmodified lines | ||
| 826 | 826 | attr->cap.max_inline_data = I40IW_MAX_INLINE_DATA_SIZE; |
| 827 | 827 | attr->cap.max_send_sge = I40IW_MAX_WQ_FRAGMENT_COUNT; |
| 828 | 828 | attr->cap.max_recv_sge = I40IW_MAX_WQ_FRAGMENT_COUNT; |
| 829 | + attr->port_num = 1; | |
| 829 | 830 | init_attr->event_handler = iwqp->ibqp.event_handler; |
| 830 | 831 | init_attr->qp_context = iwqp->ibqp.qp_context; |
| 831 | 832 | init_attr->send_cq = iwqp->ibqp.send_cq; |
| 832 | 833 | init_attr->recv_cq = iwqp->ibqp.recv_cq; |
| 833 | 834 | init_attr->srq = iwqp->ibqp.srq; |
| 834 | 835 | init_attr->cap = attr->cap; |
| 836 | + init_attr->port_num = 1; | |
| 835 | 837 | return 0; |
| 836 | 838 | } |
| 837 | 839 | |
| @@ -1027,7 +1029,19 @@ int i40iw_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 189 unmodified lines | ||
| 1027 | 1029 | iwqp->hw_tcp_state = I40IW_TCP_STATE_CLOSED; |
| 1028 | 1030 | iwqp->last_aeq = I40IW_AE_RESET_SENT; |
| 1029 | 1031 | spin_unlock_irqrestore(&iwqp->lock, flags); |
| 1032 | + i40iw_cm_disconn(iwqp); | |
| 1030 | 1033 | } |
| 1034 | + } else { | |
| 1035 | + spin_lock_irqsave(&iwqp->lock, flags); | |
| 1036 | + if (iwqp->cm_id) { | |
| 1037 | + if (atomic_inc_return(&iwqp->close_timer_started) == 1) { | |
| 1038 | + iwqp->cm_id->add_ref(iwqp->cm_id); | |
| 1039 | + i40iw_schedule_cm_timer(iwqp->cm_node, | |
| 1040 | + (struct i40iw_puda_buf *)iwqp, | |
| 1041 | + I40IW_TIMER_TYPE_CLOSE, 1, 0); | |
| 1042 | + } | |
| 1043 | + } | |
| 1044 | + spin_unlock_irqrestore(&iwqp->lock, flags); | |
| 1031 | 1045 | } |
| 1032 | 1046 | } |
| 1033 | 1047 | return 0; |
| @@ -778,13 +778,13 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, · 777 unmodified lines | ||
| 778 | 778 | } |
| 779 | 779 | |
| 780 | 780 | if (MLX5_CAP_GEN(mdev, tag_matching)) { |
| 781 | − props->xrq_caps.max_rndv_hdr_size = MLX5_TM_MAX_RNDV_MSG_SIZE; | |
| 782 | − props->xrq_caps.max_num_tags = | |
| 781 | + props->tm_caps.max_rndv_hdr_size = MLX5_TM_MAX_RNDV_MSG_SIZE; | |
| 782 | + props->tm_caps.max_num_tags = | |
| 783 | 783 | (1 << MLX5_CAP_GEN(mdev, log_tag_matching_list_sz)) - 1; |
| 784 | − props->xrq_caps.flags = IB_TM_CAP_RC; | |
| 785 | − props->xrq_caps.max_ops = | |
| 784 | + props->tm_caps.flags = IB_TM_CAP_RC; | |
| 785 | + props->tm_caps.max_ops = | |
| 786 | 786 | 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz); |
| 787 | − props->xrq_caps.max_sge = MLX5_TM_MAX_SGE; | |
| 787 | + props->tm_caps.max_sge = MLX5_TM_MAX_SGE; | |
| 788 | 788 | } |
| 789 | 789 | |
| 790 | 790 | if (field_avail(typeof(resp), cqe_comp_caps, uhw->outlen)) { |
| @@ -3837,11 +3837,13 @@ static int delay_drop_debugfs_init(struct mlx5_ib_dev *dev) · 3046 unmodified lines | ||
| 3837 | 3837 | if (!dbg) |
| 3838 | 3838 | return -ENOMEM; |
| 3839 | 3839 | |
| 3840 | + dev->delay_drop.dbg = dbg; | |
| 3841 | + | |
| 3840 | 3842 | dbg->dir_debugfs = |
| 3841 | 3843 | debugfs_create_dir("delay_drop", |
| 3842 | 3844 | dev->mdev->priv.dbg_root); |
| 3843 | 3845 | if (!dbg->dir_debugfs) |
| 3844 | − return -ENOMEM; | |
| 3846 | + goto out_debugfs; | |
| 3845 | 3847 | |
| 3846 | 3848 | dbg->events_cnt_debugfs = |
| 3847 | 3849 | debugfs_create_atomic_t("num_timeout_events", 0400, |
| @@ -3865,8 +3867,6 @@ static int delay_drop_debugfs_init(struct mlx5_ib_dev *dev) · 17 unmodified lines | ||
| 3865 | 3867 | if (!dbg->timeout_debugfs) |
| 3866 | 3868 | goto out_debugfs; |
| 3867 | 3869 | |
| 3868 | − dev->delay_drop.dbg = dbg; | |
| 3869 | − | |
| 3870 | 3870 | return 0; |
| 3871 | 3871 | |
| 3872 | 3872 | out_debugfs: |
| @@ -4174,9 +4174,9 @@ err_bfreg: · 301 unmodified lines | ||
| 4174 | 4174 | err_uar_page: |
| 4175 | 4175 | mlx5_put_uars_page(dev->mdev, dev->mdev->priv.uar); |
| 4176 | 4176 | |
| 4177 | −err_cnt: | |
| 4178 | − mlx5_ib_cleanup_cong_debugfs(dev); | |
| 4179 | 4177 | err_cong: |
| 4178 | + mlx5_ib_cleanup_cong_debugfs(dev); | |
| 4179 | +err_cnt: | |
| 4180 | 4180 | if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) |
| 4181 | 4181 | mlx5_ib_dealloc_counters(dev); |
| 4182 | 4182 | |
| @@ -50,13 +50,9 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, · 49 unmodified lines | ||
| 50 | 50 | { |
| 51 | 51 | unsigned long tmp; |
| 52 | 52 | unsigned long m; |
| 53 | − int i, k; | |
| 54 | − u64 base = 0; | |
| 55 | − int p = 0; | |
| 56 | − int skip; | |
| 57 | − int mask; | |
| 58 | − u64 len; | |
| 59 | − u64 pfn; | |
| 53 | + u64 base = ~0, p = 0; | |
| 54 | + u64 len, pfn; | |
| 55 | + int i = 0; | |
| 60 | 56 | struct scatterlist *sg; |
| 61 | 57 | int entry; |
| 62 | 58 | unsigned long page_shift = umem->page_shift; |
| @@ -76,33 +72,24 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, · 13 unmodified lines | ||
| 76 | 72 | m = find_first_bit(&tmp, BITS_PER_LONG); |
| 77 | 73 | if (max_page_shift) |
| 78 | 74 | m = min_t(unsigned long, max_page_shift - page_shift, m); |
| 79 | − skip = 1 << m; | |
| 80 | − mask = skip - 1; | |
| 81 | − i = 0; | |
| 75 | + | |
| 82 | 76 | for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) { |
| 83 | 77 | len = sg_dma_len(sg) >> page_shift; |
| 84 | 78 | pfn = sg_dma_address(sg) >> page_shift; |
| 85 | − for (k = 0; k < len; k++) { | |
| 86 | − if (!(i & mask)) { | |
| 87 | − tmp = (unsigned long)pfn; | |
| 88 | − m = min_t(unsigned long, m, find_first_bit(&tmp, BITS_PER_LONG)); | |
| 89 | − skip = 1 << m; | |
| 90 | − mask = skip - 1; | |
| 91 | − base = pfn; | |
| 92 | − p = 0; | |
| 93 | − } else { | |
| 94 | − if (base + p != pfn) { | |
| 95 | − tmp = (unsigned long)p; | |
| 96 | − m = find_first_bit(&tmp, BITS_PER_LONG); | |
| 97 | − skip = 1 << m; | |
| 98 | − mask = skip - 1; | |
| 99 | − base = pfn; | |
| 100 | − p = 0; | |
| 101 | − } | |
| 102 | − } | |
| 103 | − p++; | |
| 104 | − i++; | |
| 79 | + if (base + p != pfn) { | |
| 80 | + /* If either the offset or the new | |
| 81 | + * base are unaligned update m | |
| 82 | + */ | |
| 83 | + tmp = (unsigned long)(pfn | p); | |
| 84 | + if (!IS_ALIGNED(tmp, 1 << m)) | |
| 85 | + m = find_first_bit(&tmp, BITS_PER_LONG); | |
| 86 | + | |
| 87 | + base = pfn; | |
| 88 | + p = 0; | |
| 105 | 89 | } |
| 90 | + | |
| 91 | + p += len; | |
| 92 | + i += len; | |
| 106 | 93 | } |
| 107 | 94 | |
| 108 | 95 | if (i) { |
| @@ -47,7 +47,8 @@ enum { · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | #define MLX5_UMR_ALIGN 2048 |
| 49 | 49 | |
| 50 | −static int clean_mr(struct mlx5_ib_mr *mr); | |
| 50 | +static int clean_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr); | |
| 51 | +static int dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr); | |
| 51 | 52 | static int mr_cache_max_order(struct mlx5_ib_dev *dev); |
| 52 | 53 | static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr); |
| 53 | 54 | |
| @@ -1270,8 +1271,9 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, · 1216 unmodified lines | ||
| 1270 | 1271 | |
| 1271 | 1272 | err = mlx5_ib_update_xlt(mr, 0, ncont, page_shift, |
| 1272 | 1273 | update_xlt_flags); |
| 1274 | + | |
| 1273 | 1275 | if (err) { |
| 1274 | − mlx5_ib_dereg_mr(&mr->ibmr); | |
| 1276 | + dereg_mr(dev, mr); | |
| 1275 | 1277 | return ERR_PTR(err); |
| 1276 | 1278 | } |
| 1277 | 1279 | } |
| @@ -1356,7 +1358,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 78 unmodified lines | ||
| 1356 | 1358 | err = mr_umem_get(pd, addr, len, access_flags, &mr->umem, |
| 1357 | 1359 | &npages, &page_shift, &ncont, &order); |
| 1358 | 1360 | if (err < 0) { |
| 1359 | − clean_mr(mr); | |
| 1361 | + clean_mr(dev, mr); | |
| 1360 | 1362 | return err; |
| 1361 | 1363 | } |
| 1362 | 1364 | } |
| @@ -1410,7 +1412,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 47 unmodified lines | ||
| 1410 | 1412 | if (err) { |
| 1411 | 1413 | mlx5_ib_warn(dev, "Failed to rereg UMR\n"); |
| 1412 | 1414 | ib_umem_release(mr->umem); |
| 1413 | − clean_mr(mr); | |
| 1415 | + clean_mr(dev, mr); | |
| 1414 | 1416 | return err; |
| 1415 | 1417 | } |
| 1416 | 1418 | } |
| @@ -1469,9 +1471,8 @@ mlx5_free_priv_descs(struct mlx5_ib_mr *mr) · 52 unmodified lines | ||
| 1469 | 1471 | } |
| 1470 | 1472 | } |
| 1471 | 1473 | |
| 1472 | −static int clean_mr(struct mlx5_ib_mr *mr) | |
| 1474 | +static int clean_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) | |
| 1473 | 1475 | { |
| 1474 | − struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device); | |
| 1475 | 1476 | int allocated_from_cache = mr->allocated_from_cache; |
| 1476 | 1477 | int err; |
| 1477 | 1478 | |
| @@ -1507,10 +1508,8 @@ static int clean_mr(struct mlx5_ib_mr *mr) · 29 unmodified lines | ||
| 1507 | 1508 | return 0; |
| 1508 | 1509 | } |
| 1509 | 1510 | |
| 1510 | −int mlx5_ib_dereg_mr(struct ib_mr *ibmr) | |
| 1511 | +static int dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) | |
| 1511 | 1512 | { |
| 1512 | − struct mlx5_ib_dev *dev = to_mdev(ibmr->device); | |
| 1513 | − struct mlx5_ib_mr *mr = to_mmr(ibmr); | |
| 1514 | 1513 | int npages = mr->npages; |
| 1515 | 1514 | struct ib_umem *umem = mr->umem; |
| 1516 | 1515 | |
| @@ -1539,7 +1538,7 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr) · 22 unmodified lines | ||
| 1539 | 1538 | } |
| 1540 | 1539 | #endif |
| 1541 | 1540 | |
| 1542 | − clean_mr(mr); | |
| 1541 | + clean_mr(dev, mr); | |
| 1543 | 1542 | |
| 1544 | 1543 | if (umem) { |
| 1545 | 1544 | ib_umem_release(umem); |
| @@ -1549,6 +1548,14 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr) · 3 unmodified lines | ||
| 1549 | 1548 | return 0; |
| 1550 | 1549 | } |
| 1551 | 1550 | |
| 1551 | +int mlx5_ib_dereg_mr(struct ib_mr *ibmr) | |
| 1552 | +{ | |
| 1553 | + struct mlx5_ib_dev *dev = to_mdev(ibmr->device); | |
| 1554 | + struct mlx5_ib_mr *mr = to_mmr(ibmr); | |
| 1555 | + | |
| 1556 | + return dereg_mr(dev, mr); | |
| 1557 | +} | |
| 1558 | + | |
| 1552 | 1559 | struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, |
| 1553 | 1560 | enum ib_mr_type mr_type, |
| 1554 | 1561 | u32 max_num_sg) |
| @@ -3232,7 +3232,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, · 3231 unmodified lines | ||
| 3232 | 3232 | mr->ibmr.iova); |
| 3233 | 3233 | set_wqe_32bit_value(wqe->wqe_words, |
| 3234 | 3234 | NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX, |
| 3235 | − mr->ibmr.length); | |
| 3235 | + lower_32_bits(mr->ibmr.length)); | |
| 3236 | 3236 | set_wqe_32bit_value(wqe->wqe_words, |
| 3237 | 3237 | NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX, 0); |
| 3238 | 3238 | set_wqe_32bit_value(wqe->wqe_words, |
| @@ -3274,7 +3274,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, · 35 unmodified lines | ||
| 3274 | 3274 | mr->npages * 8); |
| 3275 | 3275 | |
| 3276 | 3276 | nes_debug(NES_DBG_IW_TX, "SQ_REG_MR: iova_start: %llx, " |
| 3277 | − "length: %d, rkey: %0x, pgl_paddr: %llx, " | |
| 3277 | + "length: %lld, rkey: %0x, pgl_paddr: %llx, " | |
| 3278 | 3278 | "page_list_len: %u, wqe_misc: %x\n", |
| 3279 | 3279 | (unsigned long long) mr->ibmr.iova, |
| 3280 | 3280 | mr->ibmr.length, |
| @@ -252,7 +252,10 @@ static int ocrdma_get_mbx_errno(u32 status) · 251 unmodified lines | ||
| 252 | 252 | case OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES: |
| 253 | 253 | err_num = -EAGAIN; |
| 254 | 254 | break; |
| 255 | + default: | |
| 256 | + err_num = -EFAULT; | |
| 255 | 257 | } |
| 258 | + break; | |
| 256 | 259 | default: |
| 257 | 260 | err_num = -EFAULT; |
| 258 | 261 | } |
| @@ -387,7 +387,7 @@ struct qedr_qp { · 386 unmodified lines | ||
| 387 | 387 | u8 wqe_size; |
| 388 | 388 | |
| 389 | 389 | u8 smac[ETH_ALEN]; |
| 390 | − u16 vlan_id; | |
| 390 | + u16 vlan; | |
| 391 | 391 | int rc; |
| 392 | 392 | } *rqe_wr_id; |
| 393 | 393 | |
| @@ -105,7 +105,7 @@ void qedr_ll2_complete_rx_packet(void *cxt, · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | qp->rqe_wr_id[qp->rq.gsi_cons].rc = data->u.data_length_error ? |
| 107 | 107 | -EINVAL : 0; |
| 108 | − qp->rqe_wr_id[qp->rq.gsi_cons].vlan_id = data->vlan; | |
| 108 | + qp->rqe_wr_id[qp->rq.gsi_cons].vlan = data->vlan; | |
| 109 | 109 | /* note: length stands for data length i.e. GRH is excluded */ |
| 110 | 110 | qp->rqe_wr_id[qp->rq.gsi_cons].sg_list[0].length = |
| 111 | 111 | data->length.data_length; |
| @@ -694,6 +694,7 @@ int qedr_gsi_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) · 582 unmodified lines | ||
| 694 | 694 | struct qedr_cq *cq = get_qedr_cq(ibcq); |
| 695 | 695 | struct qedr_qp *qp = dev->gsi_qp; |
| 696 | 696 | unsigned long flags; |
| 697 | + u16 vlan_id; | |
| 697 | 698 | int i = 0; |
| 698 | 699 | |
| 699 | 700 | spin_lock_irqsave(&cq->cq_lock, flags); |
| @@ -712,9 +713,14 @@ int qedr_gsi_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) · 12 unmodified lines | ||
| 712 | 713 | wc[i].wc_flags |= IB_WC_GRH | IB_WC_IP_CSUM_OK; |
| 713 | 714 | ether_addr_copy(wc[i].smac, qp->rqe_wr_id[qp->rq.cons].smac); |
| 714 | 715 | wc[i].wc_flags |= IB_WC_WITH_SMAC; |
| 715 | − if (qp->rqe_wr_id[qp->rq.cons].vlan_id) { | |
| 716 | + | |
| 717 | + vlan_id = qp->rqe_wr_id[qp->rq.cons].vlan & | |
| 718 | + VLAN_VID_MASK; | |
| 719 | + if (vlan_id) { | |
| 716 | 720 | wc[i].wc_flags |= IB_WC_WITH_VLAN; |
| 717 | − wc[i].vlan_id = qp->rqe_wr_id[qp->rq.cons].vlan_id; | |
| 721 | + wc[i].vlan_id = vlan_id; | |
| 722 | + wc[i].sl = (qp->rqe_wr_id[qp->rq.cons].vlan & | |
| 723 | + VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; | |
| 718 | 724 | } |
| 719 | 725 | |
| 720 | 726 | qedr_inc_sw_cons(&qp->rq); |
| @@ -416,9 +416,34 @@ static inline enum ib_wc_status pvrdma_wc_status_to_ib( · 415 unmodified lines | ||
| 416 | 416 | return (enum ib_wc_status)status; |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | −static inline int pvrdma_wc_opcode_to_ib(int opcode) | |
| 420 | −{ | |
| 421 | − return opcode; | |
| 419 | +static inline int pvrdma_wc_opcode_to_ib(unsigned int opcode) | |
| 420 | +{ | |
| 421 | + switch (opcode) { | |
| 422 | + case PVRDMA_WC_SEND: | |
| 423 | + return IB_WC_SEND; | |
| 424 | + case PVRDMA_WC_RDMA_WRITE: | |
| 425 | + return IB_WC_RDMA_WRITE; | |
| 426 | + case PVRDMA_WC_RDMA_READ: | |
| 427 | + return IB_WC_RDMA_READ; | |
| 428 | + case PVRDMA_WC_COMP_SWAP: | |
| 429 | + return IB_WC_COMP_SWAP; | |
| 430 | + case PVRDMA_WC_FETCH_ADD: | |
| 431 | + return IB_WC_FETCH_ADD; | |
| 432 | + case PVRDMA_WC_LOCAL_INV: | |
| 433 | + return IB_WC_LOCAL_INV; | |
| 434 | + case PVRDMA_WC_FAST_REG_MR: | |
| 435 | + return IB_WC_REG_MR; | |
| 436 | + case PVRDMA_WC_MASKED_COMP_SWAP: | |
| 437 | + return IB_WC_MASKED_COMP_SWAP; | |
| 438 | + case PVRDMA_WC_MASKED_FETCH_ADD: | |
| 439 | + return IB_WC_MASKED_FETCH_ADD; | |
| 440 | + case PVRDMA_WC_RECV: | |
| 441 | + return IB_WC_RECV; | |
| 442 | + case PVRDMA_WC_RECV_RDMA_WITH_IMM: | |
| 443 | + return IB_WC_RECV_RDMA_WITH_IMM; | |
| 444 | + default: | |
| 445 | + return IB_WC_SEND; | |
| 446 | + } | |
| 422 | 447 | } |
| 423 | 448 | |
| 424 | 449 | static inline int pvrdma_wc_flags_to_ib(int flags) |
| @@ -823,12 +823,18 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) · 822 unmodified lines | ||
| 823 | 823 | wc->status != IB_WC_WR_FLUSH_ERR) { |
| 824 | 824 | struct ipoib_neigh *neigh; |
| 825 | 825 | |
| 826 | − if (wc->status != IB_WC_RNR_RETRY_EXC_ERR) | |
| 827 | − ipoib_warn(priv, "failed cm send event (status=%d, wrid=%d vend_err %x)\n", | |
| 828 | − wc->status, wr_id, wc->vendor_err); | |
| 826 | + /* IB_WC[_RNR]_RETRY_EXC_ERR error is part of the life cycle, | |
| 827 | + * so don't make waves. | |
| 828 | + */ | |
| 829 | + if (wc->status == IB_WC_RNR_RETRY_EXC_ERR || | |
| 830 | + wc->status == IB_WC_RETRY_EXC_ERR) | |
| 831 | + ipoib_dbg(priv, | |
| 832 | + "%s: failed cm send event (status=%d, wrid=%d vend_err 0x%x)\n", | |
| 833 | + __func__, wc->status, wr_id, wc->vendor_err); | |
| 829 | 834 | else |
| 830 | − ipoib_dbg(priv, "failed cm send event (status=%d, wrid=%d vend_err %x)\n", | |
| 831 | − wc->status, wr_id, wc->vendor_err); | |
| 835 | + ipoib_warn(priv, | |
| 836 | + "%s: failed cm send event (status=%d, wrid=%d vend_err 0x%x)\n", | |
| 837 | + __func__, wc->status, wr_id, wc->vendor_err); | |
| 832 | 838 | |
| 833 | 839 | spin_lock_irqsave(&priv->lock, flags); |
| 834 | 840 | neigh = tx->neigh; |
| @@ -1000,19 +1000,6 @@ static inline int update_parent_pkey(struct ipoib_dev_priv *priv) · 999 unmodified lines | ||
| 1000 | 1000 | */ |
| 1001 | 1001 | priv->dev->broadcast[8] = priv->pkey >> 8; |
| 1002 | 1002 | priv->dev->broadcast[9] = priv->pkey & 0xff; |
| 1003 | − | |
| 1004 | − /* | |
| 1005 | − * Update the broadcast address in the priv->broadcast object, | |
| 1006 | − * in case it already exists, otherwise no one will do that. | |
| 1007 | − */ | |
| 1008 | − if (priv->broadcast) { | |
| 1009 | − spin_lock_irq(&priv->lock); | |
| 1010 | − memcpy(priv->broadcast->mcmember.mgid.raw, | |
| 1011 | − priv->dev->broadcast + 4, | |
| 1012 | − sizeof(union ib_gid)); | |
| 1013 | − spin_unlock_irq(&priv->lock); | |
| 1014 | − } | |
| 1015 | − | |
| 1016 | 1003 | return 0; |
| 1017 | 1004 | } |
| 1018 | 1005 | |
| @@ -2180,6 +2180,7 @@ static struct net_device *ipoib_add_port(const char *format, · 2179 unmodified lines | ||
| 2180 | 2180 | { |
| 2181 | 2181 | struct ipoib_dev_priv *priv; |
| 2182 | 2182 | struct ib_port_attr attr; |
| 2183 | + struct rdma_netdev *rn; | |
| 2183 | 2184 | int result = -ENOMEM; |
| 2184 | 2185 | |
| 2185 | 2186 | priv = ipoib_intf_alloc(hca, port, format); |
| @@ -2279,7 +2280,8 @@ register_failed: · 93 unmodified lines | ||
| 2279 | 2280 | ipoib_dev_cleanup(priv->dev); |
| 2280 | 2281 | |
| 2281 | 2282 | device_init_failed: |
| 2282 | − free_netdev(priv->dev); | |
| 2283 | + rn = netdev_priv(priv->dev); | |
| 2284 | + rn->free_rdma_netdev(priv->dev); | |
| 2283 | 2285 | kfree(priv); |
| 2284 | 2286 | |
| 2285 | 2287 | alloc_mem_failed: |
| @@ -2328,7 +2330,7 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data) · 42 unmodified lines | ||
| 2328 | 2330 | return; |
| 2329 | 2331 | |
| 2330 | 2332 | list_for_each_entry_safe(priv, tmp, dev_list, list) { |
| 2331 | − struct rdma_netdev *rn = netdev_priv(priv->dev); | |
| 2333 | + struct rdma_netdev *parent_rn = netdev_priv(priv->dev); | |
| 2332 | 2334 | |
| 2333 | 2335 | ib_unregister_event_handler(&priv->event_handler); |
| 2334 | 2336 | flush_workqueue(ipoib_workqueue); |
| @@ -2350,10 +2352,15 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data) · 15 unmodified lines | ||
| 2350 | 2352 | unregister_netdev(priv->dev); |
| 2351 | 2353 | mutex_unlock(&priv->sysfs_mutex); |
| 2352 | 2354 | |
| 2353 | − rn->free_rdma_netdev(priv->dev); | |
| 2355 | + parent_rn->free_rdma_netdev(priv->dev); | |
| 2356 | + | |
| 2357 | + list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { | |
| 2358 | + struct rdma_netdev *child_rn; | |
| 2354 | 2359 | |
| 2355 | − list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) | |
| 2360 | + child_rn = netdev_priv(cpriv->dev); | |
| 2361 | + child_rn->free_rdma_netdev(cpriv->dev); | |
| 2356 | 2362 | kfree(cpriv); |
| 2363 | + } | |
| 2357 | 2364 | |
| 2358 | 2365 | kfree(priv); |
| 2359 | 2366 | } |
| @@ -141,14 +141,17 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) · 140 unmodified lines | ||
| 141 | 141 | return restart_syscall(); |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | − priv = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name); | |
| 145 | − if (!priv) { | |
| 144 | + if (!down_write_trylock(&ppriv->vlan_rwsem)) { | |
| 146 | 145 | rtnl_unlock(); |
| 147 | 146 | mutex_unlock(&ppriv->sysfs_mutex); |
| 148 | − return -ENOMEM; | |
| 147 | + return restart_syscall(); | |
| 149 | 148 | } |
| 150 | 149 | |
| 151 | − down_write(&ppriv->vlan_rwsem); | |
| 150 | + priv = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name); | |
| 151 | + if (!priv) { | |
| 152 | + result = -ENOMEM; | |
| 153 | + goto out; | |
| 154 | + } | |
| 152 | 155 | |
| 153 | 156 | /* |
| 154 | 157 | * First ensure this isn't a duplicate. We check the parent device and |
| @@ -175,8 +178,11 @@ out: · 20 unmodified lines | ||
| 175 | 178 | rtnl_unlock(); |
| 176 | 179 | mutex_unlock(&ppriv->sysfs_mutex); |
| 177 | 180 | |
| 178 | − if (result) { | |
| 179 | − free_netdev(priv->dev); | |
| 181 | + if (result && priv) { | |
| 182 | + struct rdma_netdev *rn; | |
| 183 | + | |
| 184 | + rn = netdev_priv(priv->dev); | |
| 185 | + rn->free_rdma_netdev(priv->dev); | |
| 180 | 186 | kfree(priv); |
| 181 | 187 | } |
| 182 | 188 | |
| @@ -204,7 +210,12 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) · 21 unmodified lines | ||
| 204 | 210 | return restart_syscall(); |
| 205 | 211 | } |
| 206 | 212 | |
| 207 | − down_write(&ppriv->vlan_rwsem); | |
| 213 | + if (!down_write_trylock(&ppriv->vlan_rwsem)) { | |
| 214 | + rtnl_unlock(); | |
| 215 | + mutex_unlock(&ppriv->sysfs_mutex); | |
| 216 | + return restart_syscall(); | |
| 217 | + } | |
| 218 | + | |
| 208 | 219 | list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) { |
| 209 | 220 | if (priv->pkey == pkey && |
| 210 | 221 | priv->child_type == IPOIB_LEGACY_CHILD) { |
| @@ -224,7 +235,10 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) · 13 unmodified lines | ||
| 224 | 235 | mutex_unlock(&ppriv->sysfs_mutex); |
| 225 | 236 | |
| 226 | 237 | if (dev) { |
| 227 | − free_netdev(dev); | |
| 238 | + struct rdma_netdev *rn; | |
| 239 | + | |
| 240 | + rn = netdev_priv(dev); | |
| 241 | + rn->free_rdma_netdev(priv->dev); | |
| 228 | 242 | kfree(priv); |
| 229 | 243 | return 0; |
| 230 | 244 | } |
| @@ -154,7 +154,7 @@ static void iser_dump_page_vec(struct iser_page_vec *page_vec) · 153 unmodified lines | ||
| 154 | 154 | { |
| 155 | 155 | int i; |
| 156 | 156 | |
| 157 | − iser_err("page vec npages %d data length %d\n", | |
| 157 | + iser_err("page vec npages %d data length %lld\n", | |
| 158 | 158 | page_vec->npages, page_vec->fake_mr.length); |
| 159 | 159 | for (i = 0; i < page_vec->npages; i++) |
| 160 | 160 | iser_err("vec[%d]: %llx\n", i, page_vec->pages[i]); |
| @@ -237,9 +237,15 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file) · 236 unmodified lines | ||
| 237 | 237 | EXPORT_SYMBOL_GPL(input_ff_erase); |
| 238 | 238 | |
| 239 | 239 | /* |
| 240 | − * flush_effects - erase all effects owned by a file handle | |
| 240 | + * input_ff_flush - erase all effects owned by a file handle | |
| 241 | + * @dev: input device to erase effect from | |
| 242 | + * @file: purported owner of the effects | |
| 243 | + * | |
| 244 | + * This function erases all force-feedback effects associated with | |
| 245 | + * the given owner from specified device. Note that @file may be %NULL, | |
| 246 | + * in which case all effects will be erased. | |
| 241 | 247 | */ |
| 242 | −static int flush_effects(struct input_dev *dev, struct file *file) | |
| 248 | +int input_ff_flush(struct input_dev *dev, struct file *file) | |
| 243 | 249 | { |
| 244 | 250 | struct ff_device *ff = dev->ff; |
| 245 | 251 | int i; |
| @@ -255,6 +261,7 @@ static int flush_effects(struct input_dev *dev, struct file *file) · 9 unmodified lines | ||
| 255 | 261 | |
| 256 | 262 | return 0; |
| 257 | 263 | } |
| 264 | +EXPORT_SYMBOL_GPL(input_ff_flush); | |
| 258 | 265 | |
| 259 | 266 | /** |
| 260 | 267 | * input_ff_event() - generic handler for force-feedback events |
| @@ -343,7 +350,7 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) · 82 unmodified lines | ||
| 343 | 350 | mutex_init(&ff->mutex); |
| 344 | 351 | |
| 345 | 352 | dev->ff = ff; |
| 346 | − dev->flush = flush_effects; | |
| 353 | + dev->flush = input_ff_flush; | |
| 347 | 354 | dev->event = input_ff_event; |
| 348 | 355 | __set_bit(EV_FF, dev->evbit); |
| 349 | 356 | |
| @@ -98,14 +98,15 @@ static int uinput_request_reserve_slot(struct uinput_device *udev, · 97 unmodified lines | ||
| 98 | 98 | uinput_request_alloc_id(udev, request)); |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | −static void uinput_request_done(struct uinput_device *udev, | |
| 102 | − struct uinput_request *request) | |
| 101 | +static void uinput_request_release_slot(struct uinput_device *udev, | |
| 102 | + unsigned int id) | |
| 103 | 103 | { |
| 104 | 104 | /* Mark slot as available */ |
| 105 | − udev->requests[request->id] = NULL; | |
| 106 | − wake_up(&udev->requests_waitq); | |
| 105 | + spin_lock(&udev->requests_lock); | |
| 106 | + udev->requests[id] = NULL; | |
| 107 | + spin_unlock(&udev->requests_lock); | |
| 107 | 108 | |
| 108 | − complete(&request->done); | |
| 109 | + wake_up(&udev->requests_waitq); | |
| 109 | 110 | } |
| 110 | 111 | |
| 111 | 112 | static int uinput_request_send(struct uinput_device *udev, |
| @@ -138,20 +139,22 @@ static int uinput_request_send(struct uinput_device *udev, · 26 unmodified lines | ||
| 138 | 139 | static int uinput_request_submit(struct uinput_device *udev, |
| 139 | 140 | struct uinput_request *request) |
| 140 | 141 | { |
| 141 | − int error; | |
| 142 | + int retval; | |
| 142 | 143 | |
| 143 | − error = uinput_request_reserve_slot(udev, request); | |
| 144 | − if (error) | |
| 145 | − return error; | |
| 144 | + retval = uinput_request_reserve_slot(udev, request); | |
| 145 | + if (retval) | |
| 146 | + return retval; | |
| 146 | 147 | |
| 147 | − error = uinput_request_send(udev, request); | |
| 148 | − if (error) { | |
| 149 | − uinput_request_done(udev, request); | |
| 150 | − return error; | |
| 151 | − } | |
| 148 | + retval = uinput_request_send(udev, request); | |
| 149 | + if (retval) | |
| 150 | + goto out; | |
| 152 | 151 | |
| 153 | 152 | wait_for_completion(&request->done); |
| 154 | − return request->retval; | |
| 153 | + retval = request->retval; | |
| 154 | + | |
| 155 | + out: | |
| 156 | + uinput_request_release_slot(udev, request->id); | |
| 157 | + return retval; | |
| 155 | 158 | } |
| 156 | 159 | |
| 157 | 160 | /* |
| @@ -169,7 +172,7 @@ static void uinput_flush_requests(struct uinput_device *udev) · 11 unmodified lines | ||
| 169 | 172 | request = udev->requests[i]; |
| 170 | 173 | if (request) { |
| 171 | 174 | request->retval = -ENODEV; |
| 172 | − uinput_request_done(udev, request); | |
| 175 | + complete(&request->done); | |
| 173 | 176 | } |
| 174 | 177 | } |
| 175 | 178 | |
| @@ -230,6 +233,18 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) · 54 unmodified lines | ||
| 230 | 233 | return uinput_request_submit(udev, &request); |
| 231 | 234 | } |
| 232 | 235 | |
| 236 | +static int uinput_dev_flush(struct input_dev *dev, struct file *file) | |
| 237 | +{ | |
| 238 | + /* | |
| 239 | + * If we are called with file == NULL that means we are tearing | |
| 240 | + * down the device, and therefore we can not handle FF erase | |
| 241 | + * requests: either we are handling UI_DEV_DESTROY (and holding | |
| 242 | + * the udev->mutex), or the file descriptor is closed and there is | |
| 243 | + * nobody on the other side anymore. | |
| 244 | + */ | |
| 245 | + return file ? input_ff_flush(dev, file) : 0; | |
| 246 | +} | |
| 247 | + | |
| 233 | 248 | static void uinput_destroy_device(struct uinput_device *udev) |
| 234 | 249 | { |
| 235 | 250 | const char *name, *phys; |
| @@ -297,6 +312,12 @@ static int uinput_create_device(struct uinput_device *udev) · 61 unmodified lines | ||
| 297 | 312 | dev->ff->playback = uinput_dev_playback; |
| 298 | 313 | dev->ff->set_gain = uinput_dev_set_gain; |
| 299 | 314 | dev->ff->set_autocenter = uinput_dev_set_autocenter; |
| 315 | + /* | |
| 316 | + * The standard input_ff_flush() implementation does | |
| 317 | + * not quite work for uinput as we can't reasonably | |
| 318 | + * handle FF requests during device teardown. | |
| 319 | + */ | |
| 320 | + dev->flush = uinput_dev_flush; | |
| 300 | 321 | } |
| 301 | 322 | |
| 302 | 323 | error = input_register_device(udev->dev); |
| @@ -939,7 +960,7 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, · 636 unmodified lines | ||
| 939 | 960 | } |
| 940 | 961 | |
| 941 | 962 | req->retval = ff_up.retval; |
| 942 | − uinput_request_done(udev, req); | |
| 963 | + complete(&req->done); | |
| 943 | 964 | goto out; |
| 944 | 965 | |
| 945 | 966 | case UI_END_FF_ERASE: |
| @@ -955,7 +976,7 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, · 9 unmodified lines | ||
| 955 | 976 | } |
| 956 | 977 | |
| 957 | 978 | req->retval = ff_erase.retval; |
| 958 | − uinput_request_done(udev, req); | |
| 979 | + complete(&req->done); | |
| 959 | 980 | goto out; |
| 960 | 981 | } |
| 961 | 982 | |
| @@ -598,7 +598,7 @@ static int elan_i2c_write_fw_block(struct i2c_client *client, · 597 unmodified lines | ||
| 598 | 598 | } |
| 599 | 599 | |
| 600 | 600 | /* Wait for F/W to update one page ROM data. */ |
| 601 | − msleep(20); | |
| 601 | + msleep(35); | |
| 602 | 602 | |
| 603 | 603 | error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); |
| 604 | 604 | if (error) { |
| @@ -278,7 +278,7 @@ config EXYNOS_IOMMU_DEBUG · 277 unmodified lines | ||
| 278 | 278 | config IPMMU_VMSA |
| 279 | 279 | bool "Renesas VMSA-compatible IPMMU" |
| 280 | 280 | depends on ARM || IOMMU_DMA |
| 281 | − depends on ARCH_RENESAS || COMPILE_TEST | |
| 281 | + depends on ARCH_RENESAS || (COMPILE_TEST && !GENERIC_ATOMIC64) | |
| 282 | 282 | select IOMMU_API |
| 283 | 283 | select IOMMU_IO_PGTABLE_LPAE |
| 284 | 284 | select ARM_DMA_USE_IOMMU |
| @@ -373,7 +373,8 @@ config MTK_IOMMU_V1 · 88 unmodified lines | ||
| 373 | 373 | config QCOM_IOMMU |
| 374 | 374 | # Note: iommu drivers cannot (yet?) be built as modules |
| 375 | 375 | bool "Qualcomm IOMMU Support" |
| 376 | − depends on ARCH_QCOM || COMPILE_TEST | |
| 376 | + depends on ARCH_QCOM || (COMPILE_TEST && !GENERIC_ATOMIC64) | |
| 377 | + depends on HAS_DMA | |
| 377 | 378 | select IOMMU_API |
| 378 | 379 | select IOMMU_IO_PGTABLE_LPAE |
| 379 | 380 | select ARM_DMA_USE_IOMMU |
| @@ -874,7 +874,7 @@ static bool copy_device_table(void) · 873 unmodified lines | ||
| 874 | 874 | hi = readl(iommu->mmio_base + MMIO_DEV_TABLE_OFFSET + 4); |
| 875 | 875 | entry = (((u64) hi) << 32) + lo; |
| 876 | 876 | if (last_entry && last_entry != entry) { |
| 877 | − pr_err("IOMMU:%d should use the same dev table as others!/n", | |
| 877 | + pr_err("IOMMU:%d should use the same dev table as others!\n", | |
| 878 | 878 | iommu->index); |
| 879 | 879 | return false; |
| 880 | 880 | } |
| @@ -882,7 +882,7 @@ static bool copy_device_table(void) · 1 unmodified line | ||
| 882 | 882 | |
| 883 | 883 | old_devtb_size = ((entry & ~PAGE_MASK) + 1) << 12; |
| 884 | 884 | if (old_devtb_size != dev_table_size) { |
| 885 | − pr_err("The device table size of IOMMU:%d is not expected!/n", | |
| 885 | + pr_err("The device table size of IOMMU:%d is not expected!\n", | |
| 886 | 886 | iommu->index); |
| 887 | 887 | return false; |
| 888 | 888 | } |
| @@ -890,7 +890,7 @@ static bool copy_device_table(void) · 1 unmodified line | ||
| 890 | 890 | |
| 891 | 891 | old_devtb_phys = entry & PAGE_MASK; |
| 892 | 892 | if (old_devtb_phys >= 0x100000000ULL) { |
| 893 | − pr_err("The address of old device table is above 4G, not trustworthy!/n"); | |
| 893 | + pr_err("The address of old device table is above 4G, not trustworthy!\n"); | |
| 894 | 894 | return false; |
| 895 | 895 | } |
| 896 | 896 | old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB); |
| @@ -901,7 +901,7 @@ static bool copy_device_table(void) · 4 unmodified lines | ||
| 901 | 901 | old_dev_tbl_cpy = (void *)__get_free_pages(gfp_flag, |
| 902 | 902 | get_order(dev_table_size)); |
| 903 | 903 | if (old_dev_tbl_cpy == NULL) { |
| 904 | − pr_err("Failed to allocate memory for copying old device table!/n"); | |
| 904 | + pr_err("Failed to allocate memory for copying old device table!\n"); | |
| 905 | 905 | return false; |
| 906 | 906 | } |
| 907 | 907 | |
| @@ -497,7 +497,7 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) · 496 unmodified lines | ||
| 497 | 497 | #define dmar_parse_one_rhsa dmar_res_noop |
| 498 | 498 | #endif |
| 499 | 499 | |
| 500 | −static void __init | |
| 500 | +static void | |
| 501 | 501 | dmar_table_print_dmar_entry(struct acpi_dmar_header *header) |
| 502 | 502 | { |
| 503 | 503 | struct acpi_dmar_hardware_unit *drhd; |
| @@ -245,7 +245,7 @@ static void __arm_v7s_free_table(void *table, int lvl, · 244 unmodified lines | ||
| 245 | 245 | static void __arm_v7s_pte_sync(arm_v7s_iopte *ptep, int num_entries, |
| 246 | 246 | struct io_pgtable_cfg *cfg) |
| 247 | 247 | { |
| 248 | − if (!(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) | |
| 248 | + if (cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA) | |
| 249 | 249 | return; |
| 250 | 250 | |
| 251 | 251 | dma_sync_single_for_device(cfg->iommu_dev, __arm_v7s_dma_addr(ptep), |
| @@ -371,7 +371,8 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, · 370 unmodified lines | ||
| 371 | 371 | int ret; |
| 372 | 372 | |
| 373 | 373 | spin_lock_irqsave(&dom->pgtlock, flags); |
| 374 | − ret = dom->iop->map(dom->iop, iova, paddr, size, prot); | |
| 374 | + ret = dom->iop->map(dom->iop, iova, paddr & DMA_BIT_MASK(32), | |
| 375 | + size, prot); | |
| 375 | 376 | spin_unlock_irqrestore(&dom->pgtlock, flags); |
| 376 | 377 | |
| 377 | 378 | return ret; |
| @@ -157,10 +157,7 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) · 156 unmodified lines | ||
| 157 | 157 | |
| 158 | 158 | err = of_iommu_xlate(info->dev, &iommu_spec); |
| 159 | 159 | of_node_put(iommu_spec.np); |
| 160 | − if (err) | |
| 161 | − return err; | |
| 162 | − | |
| 163 | − return info->np == pdev->bus->dev.of_node; | |
| 160 | + return err; | |
| 164 | 161 | } |
| 165 | 162 | |
| 166 | 163 | const struct iommu_ops *of_iommu_configure(struct device *dev, |
| @@ -1042,7 +1042,7 @@ static int get_cpu_number(struct device_node *dn) · 1041 unmodified lines | ||
| 1042 | 1042 | { |
| 1043 | 1043 | const __be32 *cell; |
| 1044 | 1044 | u64 hwid; |
| 1045 | − int i; | |
| 1045 | + int cpu; | |
| 1046 | 1046 | |
| 1047 | 1047 | cell = of_get_property(dn, "reg", NULL); |
| 1048 | 1048 | if (!cell) |
| @@ -1056,9 +1056,9 @@ static int get_cpu_number(struct device_node *dn) · 7 unmodified lines | ||
| 1056 | 1056 | if (hwid & ~MPIDR_HWID_BITMASK) |
| 1057 | 1057 | return -1; |
| 1058 | 1058 | |
| 1059 | − for (i = 0; i < num_possible_cpus(); i++) | |
| 1060 | − if (cpu_logical_map(i) == hwid) | |
| 1061 | − return i; | |
| 1059 | + for_each_possible_cpu(cpu) | |
| 1060 | + if (cpu_logical_map(cpu) == hwid) | |
| 1061 | + return cpu; | |
| 1062 | 1062 | |
| 1063 | 1063 | return -1; |
| 1064 | 1064 | } |
| @@ -173,7 +173,9 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map) · 172 unmodified lines | ||
| 173 | 173 | { |
| 174 | 174 | struct its_cmd_info info = { |
| 175 | 175 | .cmd_type = MAP_VLPI, |
| 176 | − .map = map, | |
| 176 | + { | |
| 177 | + .map = map, | |
| 178 | + }, | |
| 177 | 179 | }; |
| 178 | 180 | |
| 179 | 181 | /* |
| @@ -189,7 +191,9 @@ int its_get_vlpi(int irq, struct its_vlpi_map *map) · 9 unmodified lines | ||
| 189 | 191 | { |
| 190 | 192 | struct its_cmd_info info = { |
| 191 | 193 | .cmd_type = GET_VLPI, |
| 192 | − .map = map, | |
| 194 | + { | |
| 195 | + .map = map, | |
| 196 | + }, | |
| 193 | 197 | }; |
| 194 | 198 | |
| 195 | 199 | return irq_set_vcpu_affinity(irq, &info); |
| @@ -205,7 +209,9 @@ int its_prop_update_vlpi(int irq, u8 config, bool inv) · 9 unmodified lines | ||
| 205 | 209 | { |
| 206 | 210 | struct its_cmd_info info = { |
| 207 | 211 | .cmd_type = inv ? PROP_UPDATE_AND_INV_VLPI : PROP_UPDATE_VLPI, |
| 208 | − .config = config, | |
| 212 | + { | |
| 213 | + .config = config, | |
| 214 | + }, | |
| 209 | 215 | }; |
| 210 | 216 | |
| 211 | 217 | return irq_set_vcpu_affinity(irq, &info); |
| @@ -169,20 +169,19 @@ static void gic_mask_irq(struct irq_data *d) · 168 unmodified lines | ||
| 169 | 169 | { |
| 170 | 170 | unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); |
| 171 | 171 | |
| 172 | − write_gic_rmask(BIT(intr)); | |
| 172 | + write_gic_rmask(intr); | |
| 173 | 173 | gic_clear_pcpu_masks(intr); |
| 174 | 174 | } |
| 175 | 175 | |
| 176 | 176 | static void gic_unmask_irq(struct irq_data *d) |
| 177 | 177 | { |
| 178 | − struct cpumask *affinity = irq_data_get_affinity_mask(d); | |
| 179 | 178 | unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); |
| 180 | 179 | unsigned int cpu; |
| 181 | 180 | |
| 182 | − write_gic_smask(BIT(intr)); | |
| 181 | + write_gic_smask(intr); | |
| 183 | 182 | |
| 184 | 183 | gic_clear_pcpu_masks(intr); |
| 185 | − cpu = cpumask_first_and(affinity, cpu_online_mask); | |
| 184 | + cpu = cpumask_first(irq_data_get_effective_affinity_mask(d)); | |
| 186 | 185 | set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); |
| 187 | 186 | } |
| 188 | 187 | |
| @@ -420,13 +419,17 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, · 231 unmodified lines | ||
| 420 | 419 | irq_hw_number_t hw, unsigned int cpu) |
| 421 | 420 | { |
| 422 | 421 | int intr = GIC_HWIRQ_TO_SHARED(hw); |
| 422 | + struct irq_data *data; | |
| 423 | 423 | unsigned long flags; |
| 424 | 424 | |
| 425 | + data = irq_get_irq_data(virq); | |
| 426 | + | |
| 425 | 427 | spin_lock_irqsave(&gic_lock, flags); |
| 426 | 428 | write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); |
| 427 | 429 | write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); |
| 428 | 430 | gic_clear_pcpu_masks(intr); |
| 429 | 431 | set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); |
| 432 | + irq_data_update_effective_affinity(data, cpumask_of(cpu)); | |
| 430 | 433 | spin_unlock_irqrestore(&gic_lock, flags); |
| 431 | 434 | |
| 432 | 435 | return 0; |
| @@ -645,7 +648,7 @@ static int __init gic_of_init(struct device_node *node, · 212 unmodified lines | ||
| 645 | 648 | |
| 646 | 649 | /* Find the first available CPU vector. */ |
| 647 | 650 | i = 0; |
| 648 | − reserved = (C_SW0 | C_SW1) >> __fls(C_SW0); | |
| 651 | + reserved = (C_SW0 | C_SW1) >> __ffs(C_SW0); | |
| 649 | 652 | while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", |
| 650 | 653 | i++, &cpu_vec)) |
| 651 | 654 | reserved |= BIT(cpu_vec); |
| @@ -684,11 +687,11 @@ static int __init gic_of_init(struct device_node *node, · 32 unmodified lines | ||
| 684 | 687 | |
| 685 | 688 | gicconfig = read_gic_config(); |
| 686 | 689 | gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; |
| 687 | − gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS); | |
| 690 | + gic_shared_intrs >>= __ffs(GIC_CONFIG_NUMINTERRUPTS); | |
| 688 | 691 | gic_shared_intrs = (gic_shared_intrs + 1) * 8; |
| 689 | 692 | |
| 690 | 693 | gic_vpes = gicconfig & GIC_CONFIG_PVPS; |
| 691 | − gic_vpes >>= __fls(GIC_CONFIG_PVPS); | |
| 694 | + gic_vpes >>= __ffs(GIC_CONFIG_PVPS); | |
| 692 | 695 | gic_vpes = gic_vpes + 1; |
| 693 | 696 | |
| 694 | 697 | if (cpu_has_veic) { |
| @@ -767,7 +770,7 @@ static int __init gic_of_init(struct device_node *node, · 72 unmodified lines | ||
| 767 | 770 | for (i = 0; i < gic_shared_intrs; i++) { |
| 768 | 771 | change_gic_pol(i, GIC_POL_ACTIVE_HIGH); |
| 769 | 772 | change_gic_trig(i, GIC_TRIG_LEVEL); |
| 770 | − write_gic_rmask(BIT(i)); | |
| 773 | + write_gic_rmask(i); | |
| 771 | 774 | } |
| 772 | 775 | |
| 773 | 776 | for (i = 0; i < gic_vpes; i++) { |
| @@ -825,7 +825,6 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count) · 824 unmodified lines | ||
| 825 | 825 | isdn_net_local *lp; |
| 826 | 826 | struct ippp_struct *is; |
| 827 | 827 | int proto; |
| 828 | − unsigned char protobuf[4]; | |
| 829 | 828 | |
| 830 | 829 | is = file->private_data; |
| 831 | 830 | |
| @@ -839,24 +838,28 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count) · 7 unmodified lines | ||
| 839 | 838 | if (!lp) |
| 840 | 839 | printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n"); |
| 841 | 840 | else { |
| 842 | − /* | |
| 843 | − * Don't reset huptimer for | |
| 844 | − * LCP packets. (Echo requests). | |
| 845 | − */ | |
| 846 | − if (copy_from_user(protobuf, buf, 4)) | |
| 847 | − return -EFAULT; | |
| 848 | − proto = PPP_PROTOCOL(protobuf); | |
| 849 | − if (proto != PPP_LCP) | |
| 850 | − lp->huptimer = 0; | |
| 841 | + if (lp->isdn_device < 0 || lp->isdn_channel < 0) { | |
| 842 | + unsigned char protobuf[4]; | |
| 843 | + /* | |
| 844 | + * Don't reset huptimer for | |
| 845 | + * LCP packets. (Echo requests). | |
| 846 | + */ | |
| 847 | + if (copy_from_user(protobuf, buf, 4)) | |
| 848 | + return -EFAULT; | |
| 849 | + | |
| 850 | + proto = PPP_PROTOCOL(protobuf); | |
| 851 | + if (proto != PPP_LCP) | |
| 852 | + lp->huptimer = 0; | |
| 851 | 853 | |
| 852 | − if (lp->isdn_device < 0 || lp->isdn_channel < 0) | |
| 853 | 854 | return 0; |
| 855 | + } | |
| 854 | 856 | |
| 855 | 857 | if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) && |
| 856 | 858 | lp->dialstate == 0 && |
| 857 | 859 | (lp->flags & ISDN_NET_CONNECTED)) { |
| 858 | 860 | unsigned short hl; |
| 859 | 861 | struct sk_buff *skb; |
| 862 | + unsigned char *cpy_buf; | |
| 860 | 863 | /* |
| 861 | 864 | * we need to reserve enough space in front of |
| 862 | 865 | * sk_buff. old call to dev_alloc_skb only reserved |
| @@ -869,11 +872,21 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count) · 6 unmodified lines | ||
| 869 | 872 | return count; |
| 870 | 873 | } |
| 871 | 874 | skb_reserve(skb, hl); |
| 872 | − if (copy_from_user(skb_put(skb, count), buf, count)) | |
| 875 | + cpy_buf = skb_put(skb, count); | |
| 876 | + if (copy_from_user(cpy_buf, buf, count)) | |
| 873 | 877 | { |
| 874 | 878 | kfree_skb(skb); |
| 875 | 879 | return -EFAULT; |
| 876 | 880 | } |
| 881 | + | |
| 882 | + /* | |
| 883 | + * Don't reset huptimer for | |
| 884 | + * LCP packets. (Echo requests). | |
| 885 | + */ | |
| 886 | + proto = PPP_PROTOCOL(cpy_buf); | |
| 887 | + if (proto != PPP_LCP) | |
| 888 | + lp->huptimer = 0; | |
| 889 | + | |
| 877 | 890 | if (is->debug & 0x40) { |
| 878 | 891 | printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len); |
| 879 | 892 | isdn_ppp_frame_log("xmit", skb->data, skb->len, 32, is->unit, lp->ppp_slot); |
| @@ -112,6 +112,10 @@ · 111 unmodified lines | ||
| 112 | 112 | #define AS_PEAK_mA_TO_REG(a) \ |
| 113 | 113 | ((min_t(u32, AS_PEAK_mA_MAX, a) - 1250) / 250) |
| 114 | 114 | |
| 115 | +/* LED numbers for Devicetree */ | |
| 116 | +#define AS_LED_FLASH 0 | |
| 117 | +#define AS_LED_INDICATOR 1 | |
| 118 | + | |
| 115 | 119 | enum as_mode { |
| 116 | 120 | AS_MODE_EXT_TORCH = 0 << AS_CONTROL_MODE_SETTING_SHIFT, |
| 117 | 121 | AS_MODE_INDICATOR = 1 << AS_CONTROL_MODE_SETTING_SHIFT, |
| @@ -491,10 +495,29 @@ static int as3645a_parse_node(struct as3645a *flash, · 373 unmodified lines | ||
| 491 | 495 | struct device_node *node) |
| 492 | 496 | { |
| 493 | 497 | struct as3645a_config *cfg = &flash->cfg; |
| 498 | + struct device_node *child; | |
| 494 | 499 | const char *name; |
| 495 | 500 | int rval; |
| 496 | 501 | |
| 497 | − flash->flash_node = of_get_child_by_name(node, "flash"); | |
| 502 | + for_each_child_of_node(node, child) { | |
| 503 | + u32 id = 0; | |
| 504 | + | |
| 505 | + of_property_read_u32(child, "reg", &id); | |
| 506 | + | |
| 507 | + switch (id) { | |
| 508 | + case AS_LED_FLASH: | |
| 509 | + flash->flash_node = of_node_get(child); | |
| 510 | + break; | |
| 511 | + case AS_LED_INDICATOR: | |
| 512 | + flash->indicator_node = of_node_get(child); | |
| 513 | + break; | |
| 514 | + default: | |
| 515 | + dev_warn(&flash->client->dev, | |
| 516 | + "unknown LED %u encountered, ignoring\n", id); | |
| 517 | + break; | |
| 518 | + } | |
| 519 | + } | |
| 520 | + | |
| 498 | 521 | if (!flash->flash_node) { |
| 499 | 522 | dev_err(&flash->client->dev, "can't find flash node\n"); |
| 500 | 523 | return -ENODEV; |
| @@ -534,11 +557,10 @@ static int as3645a_parse_node(struct as3645a *flash, · 33 unmodified lines | ||
| 534 | 557 | of_property_read_u32(flash->flash_node, "voltage-reference", |
| 535 | 558 | &cfg->voltage_reference); |
| 536 | 559 | |
| 537 | − of_property_read_u32(flash->flash_node, "peak-current-limit", | |
| 560 | + of_property_read_u32(flash->flash_node, "ams,input-max-microamp", | |
| 538 | 561 | &cfg->peak); |
| 539 | 562 | cfg->peak = AS_PEAK_mA_TO_REG(cfg->peak); |
| 540 | 563 | |
| 541 | − flash->indicator_node = of_get_child_by_name(node, "indicator"); | |
| 542 | 564 | if (!flash->indicator_node) { |
| 543 | 565 | dev_warn(&flash->client->dev, |
| 544 | 566 | "can't find indicator node\n"); |
| @@ -721,6 +743,7 @@ static int as3645a_remove(struct i2c_client *client) · 176 unmodified lines | ||
| 721 | 743 | as3645a_set_control(flash, AS_MODE_EXT_TORCH, false); |
| 722 | 744 | |
| 723 | 745 | v4l2_flash_release(flash->vf); |
| 746 | + v4l2_flash_release(flash->vfind); | |
| 724 | 747 | |
| 725 | 748 | led_classdev_flash_unregister(&flash->fled); |
| 726 | 749 | led_classdev_unregister(&flash->iled_cdev); |
| @@ -64,7 +64,7 @@ EXPORT_SYMBOL(closure_put); · 63 unmodified lines | ||
| 64 | 64 | void __closure_wake_up(struct closure_waitlist *wait_list) |
| 65 | 65 | { |
| 66 | 66 | struct llist_node *list; |
| 67 | − struct closure *cl; | |
| 67 | + struct closure *cl, *t; | |
| 68 | 68 | struct llist_node *reverse = NULL; |
| 69 | 69 | |
| 70 | 70 | list = llist_del_all(&wait_list->list); |
| @@ -73,7 +73,7 @@ void __closure_wake_up(struct closure_waitlist *wait_list) · 2 unmodified lines | ||
| 73 | 73 | reverse = llist_reverse_order(list); |
| 74 | 74 | |
| 75 | 75 | /* Then do the wakeups */ |
| 76 | − llist_for_each_entry(cl, reverse, list) { | |
| 76 | + llist_for_each_entry_safe(cl, t, reverse, list) { | |
| 77 | 77 | closure_set_waiting(cl, 0); |
| 78 | 78 | closure_sub(cl, CLOSURE_WAITING + 1); |
| 79 | 79 | } |
| @@ -149,5 +149,6 @@ static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | extern atomic_t dm_global_event_nr; |
| 151 | 151 | extern wait_queue_head_t dm_global_eventq; |
| 152 | +void dm_issue_global_event(void); | |
| 152 | 153 | |
| 153 | 154 | #endif |
| @@ -2466,6 +2466,7 @@ static int crypt_ctr_cipher_old(struct dm_target *ti, char *cipher_in, char *key · 2465 unmodified lines | ||
| 2466 | 2466 | kfree(cipher_api); |
| 2467 | 2467 | return ret; |
| 2468 | 2468 | } |
| 2469 | + kfree(cipher_api); | |
| 2469 | 2470 | |
| 2470 | 2471 | return 0; |
| 2471 | 2472 | bad_mem: |
| @@ -2584,6 +2585,10 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar · 112 unmodified lines | ||
| 2584 | 2585 | ti->error = "Invalid feature value for sector_size"; |
| 2585 | 2586 | return -EINVAL; |
| 2586 | 2587 | } |
| 2588 | + if (ti->len & ((cc->sector_size >> SECTOR_SHIFT) - 1)) { | |
| 2589 | + ti->error = "Device size is not multiple of sector_size feature"; | |
| 2590 | + return -EINVAL; | |
| 2591 | + } | |
| 2587 | 2592 | cc->sector_shift = __ffs(cc->sector_size) - SECTOR_SHIFT; |
| 2588 | 2593 | } else if (!strcasecmp(opt_string, "iv_large_sectors")) |
| 2589 | 2594 | set_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags); |
| @@ -477,9 +477,13 @@ static int remove_all(struct file *filp, struct dm_ioctl *param, size_t param_si · 476 unmodified lines | ||
| 477 | 477 | * Round up the ptr to an 8-byte boundary. |
| 478 | 478 | */ |
| 479 | 479 | #define ALIGN_MASK 7 |
| 480 | +static inline size_t align_val(size_t val) | |
| 481 | +{ | |
| 482 | + return (val + ALIGN_MASK) & ~ALIGN_MASK; | |
| 483 | +} | |
| 480 | 484 | static inline void *align_ptr(void *ptr) |
| 481 | 485 | { |
| 482 | − return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK); | |
| 486 | + return (void *)align_val((size_t)ptr); | |
| 483 | 487 | } |
| 484 | 488 | |
| 485 | 489 | /* |
| @@ -505,7 +509,7 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_ · 19 unmodified lines | ||
| 505 | 509 | struct hash_cell *hc; |
| 506 | 510 | size_t len, needed = 0; |
| 507 | 511 | struct gendisk *disk; |
| 508 | − struct dm_name_list *nl, *old_nl = NULL; | |
| 512 | + struct dm_name_list *orig_nl, *nl, *old_nl = NULL; | |
| 509 | 513 | uint32_t *event_nr; |
| 510 | 514 | |
| 511 | 515 | down_write(&_hash_lock); |
| @@ -516,17 +520,15 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_ · 4 unmodified lines | ||
| 516 | 520 | */ |
| 517 | 521 | for (i = 0; i < NUM_BUCKETS; i++) { |
| 518 | 522 | list_for_each_entry (hc, _name_buckets + i, name_list) { |
| 519 | − needed += sizeof(struct dm_name_list); | |
| 520 | − needed += strlen(hc->name) + 1; | |
| 521 | − needed += ALIGN_MASK; | |
| 522 | − needed += (sizeof(uint32_t) + ALIGN_MASK) & ~ALIGN_MASK; | |
| 523 | + needed += align_val(offsetof(struct dm_name_list, name) + strlen(hc->name) + 1); | |
| 524 | + needed += align_val(sizeof(uint32_t)); | |
| 523 | 525 | } |
| 524 | 526 | } |
| 525 | 527 | |
| 526 | 528 | /* |
| 527 | 529 | * Grab our output buffer. |
| 528 | 530 | */ |
| 529 | − nl = get_result_buffer(param, param_size, &len); | |
| 531 | + nl = orig_nl = get_result_buffer(param, param_size, &len); | |
| 530 | 532 | if (len < needed) { |
| 531 | 533 | param->flags |= DM_BUFFER_FULL_FLAG; |
| 532 | 534 | goto out; |
| @@ -549,11 +551,16 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_ · 16 unmodified lines | ||
| 549 | 551 | strcpy(nl->name, hc->name); |
| 550 | 552 | |
| 551 | 553 | old_nl = nl; |
| 552 | − event_nr = align_ptr(((void *) (nl + 1)) + strlen(hc->name) + 1); | |
| 554 | + event_nr = align_ptr(nl->name + strlen(hc->name) + 1); | |
| 553 | 555 | *event_nr = dm_get_event_nr(hc->md); |
| 554 | 556 | nl = align_ptr(event_nr + 1); |
| 555 | 557 | } |
| 556 | 558 | } |
| 559 | + /* | |
| 560 | + * If mismatch happens, security may be compromised due to buffer | |
| 561 | + * overflow, so it's better to crash. | |
| 562 | + */ | |
| 563 | + BUG_ON((char *)nl - (char *)orig_nl != needed); | |
| 557 | 564 | |
| 558 | 565 | out: |
| 559 | 566 | up_write(&_hash_lock); |
| @@ -1621,7 +1628,8 @@ static int target_message(struct file *filp, struct dm_ioctl *param, size_t para · 1061 unmodified lines | ||
| 1621 | 1628 | * which has a variable size, is not used by the function processing |
| 1622 | 1629 | * the ioctl. |
| 1623 | 1630 | */ |
| 1624 | −#define IOCTL_FLAGS_NO_PARAMS 1 | |
| 1631 | +#define IOCTL_FLAGS_NO_PARAMS 1 | |
| 1632 | +#define IOCTL_FLAGS_ISSUE_GLOBAL_EVENT 2 | |
| 1625 | 1633 | |
| 1626 | 1634 | /*----------------------------------------------------------------- |
| 1627 | 1635 | * Implementation of open/close/ioctl on the special char |
| @@ -1635,12 +1643,12 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags) · 7 unmodified lines | ||
| 1635 | 1643 | ioctl_fn fn; |
| 1636 | 1644 | } _ioctls[] = { |
| 1637 | 1645 | {DM_VERSION_CMD, 0, NULL}, /* version is dealt with elsewhere */ |
| 1638 | − {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS, remove_all}, | |
| 1646 | + {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, remove_all}, | |
| 1639 | 1647 | {DM_LIST_DEVICES_CMD, 0, list_devices}, |
| 1640 | 1648 | |
| 1641 | − {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_create}, | |
| 1642 | − {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_remove}, | |
| 1643 | − {DM_DEV_RENAME_CMD, 0, dev_rename}, | |
| 1649 | + {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_create}, | |
| 1650 | + {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_remove}, | |
| 1651 | + {DM_DEV_RENAME_CMD, IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_rename}, | |
| 1644 | 1652 | {DM_DEV_SUSPEND_CMD, IOCTL_FLAGS_NO_PARAMS, dev_suspend}, |
| 1645 | 1653 | {DM_DEV_STATUS_CMD, IOCTL_FLAGS_NO_PARAMS, dev_status}, |
| 1646 | 1654 | {DM_DEV_WAIT_CMD, 0, dev_wait}, |
| @@ -1869,6 +1877,9 @@ static int ctl_ioctl(struct file *file, uint command, struct dm_ioctl __user *us · 222 unmodified lines | ||
| 1869 | 1877 | unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS)) |
| 1870 | 1878 | DMERR("ioctl %d tried to output some data but has IOCTL_FLAGS_NO_PARAMS set", cmd); |
| 1871 | 1879 | |
| 1880 | + if (!r && ioctl_flags & IOCTL_FLAGS_ISSUE_GLOBAL_EVENT) | |
| 1881 | + dm_issue_global_event(); | |
| 1882 | + | |
| 1872 | 1883 | /* |
| 1873 | 1884 | * Copy the results back to userland. |
| 1874 | 1885 | */ |
| @@ -3238,7 +3238,7 @@ static int raid_map(struct dm_target *ti, struct bio *bio) · 3237 unmodified lines | ||
| 3238 | 3238 | if (unlikely(bio_end_sector(bio) > mddev->array_sectors)) |
| 3239 | 3239 | return DM_MAPIO_REQUEUE; |
| 3240 | 3240 | |
| 3241 | − mddev->pers->make_request(mddev, bio); | |
| 3241 | + md_handle_request(mddev, bio); | |
| 3242 | 3242 | |
| 3243 | 3243 | return DM_MAPIO_SUBMITTED; |
| 3244 | 3244 | } |
| @@ -3297,11 +3297,10 @@ static const char *__raid_dev_status(struct raid_set *rs, struct md_rdev *rdev, · 52 unmodified lines | ||
| 3297 | 3297 | static sector_t rs_get_progress(struct raid_set *rs, |
| 3298 | 3298 | sector_t resync_max_sectors, bool *array_in_sync) |
| 3299 | 3299 | { |
| 3300 | − sector_t r, recovery_cp, curr_resync_completed; | |
| 3300 | + sector_t r, curr_resync_completed; | |
| 3301 | 3301 | struct mddev *mddev = &rs->md; |
| 3302 | 3302 | |
| 3303 | 3303 | curr_resync_completed = mddev->curr_resync_completed ?: mddev->recovery_cp; |
| 3304 | − recovery_cp = mddev->recovery_cp; | |
| 3305 | 3304 | *array_in_sync = false; |
| 3306 | 3305 | |
| 3307 | 3306 | if (rs_is_raid0(rs)) { |
| @@ -3330,9 +3329,11 @@ static sector_t rs_get_progress(struct raid_set *rs, · 22 unmodified lines | ||
| 3330 | 3329 | } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
| 3331 | 3330 | r = curr_resync_completed; |
| 3332 | 3331 | else |
| 3333 | − r = recovery_cp; | |
| 3332 | + r = mddev->recovery_cp; | |
| 3334 | 3333 | |
| 3335 | − if (r == MaxSector) { | |
| 3334 | + if ((r == MaxSector) || | |
| 3335 | + (test_bit(MD_RECOVERY_DONE, &mddev->recovery) && | |
| 3336 | + (mddev->curr_resync_completed == resync_max_sectors))) { | |
| 3336 | 3337 | /* |
| 3337 | 3338 | * Sync complete. |
| 3338 | 3339 | */ |
| @@ -3892,7 +3893,7 @@ static void raid_resume(struct dm_target *ti) · 553 unmodified lines | ||
| 3892 | 3893 | |
| 3893 | 3894 | static struct target_type raid_target = { |
| 3894 | 3895 | .name = "raid", |
| 3895 | − .version = {1, 12, 1}, | |
| 3896 | + .version = {1, 13, 0}, | |
| 3896 | 3897 | .module = THIS_MODULE, |
| 3897 | 3898 | .ctr = raid_ctr, |
| 3898 | 3899 | .dtr = raid_dtr, |
| @@ -52,6 +52,12 @@ static struct workqueue_struct *deferred_remove_workqueue; · 51 unmodified lines | ||
| 52 | 52 | atomic_t dm_global_event_nr = ATOMIC_INIT(0); |
| 53 | 53 | DECLARE_WAIT_QUEUE_HEAD(dm_global_eventq); |
| 54 | 54 | |
| 55 | +void dm_issue_global_event(void) | |
| 56 | +{ | |
| 57 | + atomic_inc(&dm_global_event_nr); | |
| 58 | + wake_up(&dm_global_eventq); | |
| 59 | +} | |
| 60 | + | |
| 55 | 61 | /* |
| 56 | 62 | * One of these is allocated per bio. |
| 57 | 63 | */ |
| @@ -1865,9 +1871,8 @@ static void event_callback(void *context) · 1807 unmodified lines | ||
| 1865 | 1871 | dm_send_uevents(&uevents, &disk_to_dev(md->disk)->kobj); |
| 1866 | 1872 | |
| 1867 | 1873 | atomic_inc(&md->event_nr); |
| 1868 | − atomic_inc(&dm_global_event_nr); | |
| 1869 | 1874 | wake_up(&md->eventq); |
| 1870 | − wake_up(&dm_global_eventq); | |
| 1875 | + dm_issue_global_event(); | |
| 1871 | 1876 | } |
| 1872 | 1877 | |
| 1873 | 1878 | /* |
| @@ -2283,6 +2288,7 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table) · 409 unmodified lines | ||
| 2283 | 2288 | } |
| 2284 | 2289 | |
| 2285 | 2290 | map = __bind(md, table, &limits); |
| 2291 | + dm_issue_global_event(); | |
| 2286 | 2292 | |
| 2287 | 2293 | out: |
| 2288 | 2294 | mutex_unlock(&md->suspend_lock); |
| @@ -266,6 +266,37 @@ static DEFINE_SPINLOCK(all_mddevs_lock); · 265 unmodified lines | ||
| 266 | 266 | * call has finished, the bio has been linked into some internal structure |
| 267 | 267 | * and so is visible to ->quiesce(), so we don't need the refcount any more. |
| 268 | 268 | */ |
| 269 | +void md_handle_request(struct mddev *mddev, struct bio *bio) | |
| 270 | +{ | |
| 271 | +check_suspended: | |
| 272 | + rcu_read_lock(); | |
| 273 | + if (mddev->suspended) { | |
| 274 | + DEFINE_WAIT(__wait); | |
| 275 | + for (;;) { | |
| 276 | + prepare_to_wait(&mddev->sb_wait, &__wait, | |
| 277 | + TASK_UNINTERRUPTIBLE); | |
| 278 | + if (!mddev->suspended) | |
| 279 | + break; | |
| 280 | + rcu_read_unlock(); | |
| 281 | + schedule(); | |
| 282 | + rcu_read_lock(); | |
| 283 | + } | |
| 284 | + finish_wait(&mddev->sb_wait, &__wait); | |
| 285 | + } | |
| 286 | + atomic_inc(&mddev->active_io); | |
| 287 | + rcu_read_unlock(); | |
| 288 | + | |
| 289 | + if (!mddev->pers->make_request(mddev, bio)) { | |
| 290 | + atomic_dec(&mddev->active_io); | |
| 291 | + wake_up(&mddev->sb_wait); | |
| 292 | + goto check_suspended; | |
| 293 | + } | |
| 294 | + | |
| 295 | + if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) | |
| 296 | + wake_up(&mddev->sb_wait); | |
| 297 | +} | |
| 298 | +EXPORT_SYMBOL(md_handle_request); | |
| 299 | + | |
| 269 | 300 | static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) |
| 270 | 301 | { |
| 271 | 302 | const int rw = bio_data_dir(bio); |
| @@ -285,23 +316,6 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) · 13 unmodified lines | ||
| 285 | 316 | bio_endio(bio); |
| 286 | 317 | return BLK_QC_T_NONE; |
| 287 | 318 | } |
| 288 | −check_suspended: | |
| 289 | − rcu_read_lock(); | |
| 290 | − if (mddev->suspended) { | |
| 291 | − DEFINE_WAIT(__wait); | |
| 292 | − for (;;) { | |
| 293 | − prepare_to_wait(&mddev->sb_wait, &__wait, | |
| 294 | − TASK_UNINTERRUPTIBLE); | |
| 295 | − if (!mddev->suspended) | |
| 296 | − break; | |
| 297 | − rcu_read_unlock(); | |
| 298 | − schedule(); | |
| 299 | − rcu_read_lock(); | |
| 300 | − } | |
| 301 | − finish_wait(&mddev->sb_wait, &__wait); | |
| 302 | − } | |
| 303 | − atomic_inc(&mddev->active_io); | |
| 304 | − rcu_read_unlock(); | |
| 305 | 319 | |
| 306 | 320 | /* |
| 307 | 321 | * save the sectors now since our bio can |
| @@ -310,20 +324,14 @@ check_suspended: · 2 unmodified lines | ||
| 310 | 324 | sectors = bio_sectors(bio); |
| 311 | 325 | /* bio could be mergeable after passing to underlayer */ |
| 312 | 326 | bio->bi_opf &= ~REQ_NOMERGE; |
| 313 | − if (!mddev->pers->make_request(mddev, bio)) { | |
| 314 | − atomic_dec(&mddev->active_io); | |
| 315 | − wake_up(&mddev->sb_wait); | |
| 316 | − goto check_suspended; | |
| 317 | − } | |
| 327 | + | |
| 328 | + md_handle_request(mddev, bio); | |
| 318 | 329 | |
| 319 | 330 | cpu = part_stat_lock(); |
| 320 | 331 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
| 321 | 332 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors); |
| 322 | 333 | part_stat_unlock(); |
| 323 | 334 | |
| 324 | − if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) | |
| 325 | − wake_up(&mddev->sb_wait); | |
| 326 | − | |
| 327 | 335 | return BLK_QC_T_NONE; |
| 328 | 336 | } |
| 329 | 337 | |
| @@ -439,16 +447,22 @@ static void md_submit_flush_data(struct work_struct *ws) · 109 unmodified lines | ||
| 439 | 447 | struct mddev *mddev = container_of(ws, struct mddev, flush_work); |
| 440 | 448 | struct bio *bio = mddev->flush_bio; |
| 441 | 449 | |
| 450 | + /* | |
| 451 | + * must reset flush_bio before calling into md_handle_request to avoid a | |
| 452 | + * deadlock, because other bios passed md_handle_request suspend check | |
| 453 | + * could wait for this and below md_handle_request could wait for those | |
| 454 | + * bios because of suspend check | |
| 455 | + */ | |
| 456 | + mddev->flush_bio = NULL; | |
| 457 | + wake_up(&mddev->sb_wait); | |
| 458 | + | |
| 442 | 459 | if (bio->bi_iter.bi_size == 0) |
| 443 | 460 | /* an empty barrier - all done */ |
| 444 | 461 | bio_endio(bio); |
| 445 | 462 | else { |
| 446 | 463 | bio->bi_opf &= ~REQ_PREFLUSH; |
| 447 | − mddev->pers->make_request(mddev, bio); | |
| 464 | + md_handle_request(mddev, bio); | |
| 448 | 465 | } |
| 449 | − | |
| 450 | − mddev->flush_bio = NULL; | |
| 451 | − wake_up(&mddev->sb_wait); | |
| 452 | 466 | } |
| 453 | 467 | |
| 454 | 468 | void md_flush_request(struct mddev *mddev, struct bio *bio) |
| @@ -692,6 +692,7 @@ extern void md_stop_writes(struct mddev *mddev); · 691 unmodified lines | ||
| 692 | 692 | extern int md_rdev_init(struct md_rdev *rdev); |
| 693 | 693 | extern void md_rdev_clear(struct md_rdev *rdev); |
| 694 | 694 | |
| 695 | +extern void md_handle_request(struct mddev *mddev, struct bio *bio); | |
| 695 | 696 | extern void mddev_suspend(struct mddev *mddev); |
| 696 | 697 | extern void mddev_resume(struct mddev *mddev); |
| 697 | 698 | extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, |
| @@ -811,6 +811,14 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh · 810 unmodified lines | ||
| 811 | 811 | spin_unlock(&head->batch_head->batch_lock); |
| 812 | 812 | goto unlock_out; |
| 813 | 813 | } |
| 814 | + /* | |
| 815 | + * We must assign batch_head of this stripe within the | |
| 816 | + * batch_lock, otherwise clear_batch_ready of batch head | |
| 817 | + * stripe could clear BATCH_READY bit of this stripe and | |
| 818 | + * this stripe->batch_head doesn't get assigned, which | |
| 819 | + * could confuse clear_batch_ready for this stripe | |
| 820 | + */ | |
| 821 | + sh->batch_head = head->batch_head; | |
| 814 | 822 | |
| 815 | 823 | /* |
| 816 | 824 | * at this point, head's BATCH_READY could be cleared, but we |
| @@ -818,8 +826,6 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh · 1 unmodified line | ||
| 818 | 826 | */ |
| 819 | 827 | list_add(&sh->batch_list, &head->batch_list); |
| 820 | 828 | spin_unlock(&head->batch_head->batch_lock); |
| 821 | − | |
| 822 | − sh->batch_head = head->batch_head; | |
| 823 | 829 | } else { |
| 824 | 830 | head->batch_head = head; |
| 825 | 831 | sh->batch_head = head->batch_head; |
| @@ -4599,7 +4605,8 @@ static void break_stripe_batch_list(struct stripe_head *head_sh, · 3773 unmodified lines | ||
| 4599 | 4605 | |
| 4600 | 4606 | set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS | |
| 4601 | 4607 | (1 << STRIPE_PREREAD_ACTIVE) | |
| 4602 | − (1 << STRIPE_DEGRADED)), | |
| 4608 | + (1 << STRIPE_DEGRADED) | | |
| 4609 | + (1 << STRIPE_ON_UNPLUG_LIST)), | |
| 4603 | 4610 | head_sh->state & (1 << STRIPE_INSYNC)); |
| 4604 | 4611 | |
| 4605 | 4612 | sh->check_state = head_sh->check_state; |
| @@ -6568,14 +6575,17 @@ static ssize_t · 1962 unmodified lines | ||
| 6568 | 6575 | raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len) |
| 6569 | 6576 | { |
| 6570 | 6577 | struct r5conf *conf; |
| 6571 | − unsigned long new; | |
| 6578 | + unsigned int new; | |
| 6572 | 6579 | int err; |
| 6573 | 6580 | struct r5worker_group *new_groups, *old_groups; |
| 6574 | 6581 | int group_cnt, worker_cnt_per_group; |
| 6575 | 6582 | |
| 6576 | 6583 | if (len >= PAGE_SIZE) |
| 6577 | 6584 | return -EINVAL; |
| 6578 | − if (kstrtoul(page, 10, &new)) | |
| 6585 | + if (kstrtouint(page, 10, &new)) | |
| 6586 | + return -EINVAL; | |
| 6587 | + /* 8192 should be big enough */ | |
| 6588 | + if (new > 8192) | |
| 6579 | 6589 | return -EINVAL; |
| 6580 | 6590 | |
| 6581 | 6591 | err = mddev_lock(mddev); |
| @@ -245,5 +245,5 @@ module_init(ir_sharp_decode_init); · 244 unmodified lines | ||
| 245 | 245 | module_exit(ir_sharp_decode_exit); |
| 246 | 246 | |
| 247 | 247 | MODULE_LICENSE("GPL"); |
| 248 | −MODULE_AUTHOR("James Hogan <james.hogan@imgtec.com>"); | |
| 248 | +MODULE_AUTHOR("James Hogan <jhogan@kernel.org>"); | |
| 249 | 249 | MODULE_DESCRIPTION("Sharp IR protocol decoder"); |
| @@ -219,8 +219,17 @@ int cxllib_handle_fault(struct mm_struct *mm, u64 addr, u64 size, u64 flags) · 218 unmodified lines | ||
| 219 | 219 | |
| 220 | 220 | down_read(&mm->mmap_sem); |
| 221 | 221 | |
| 222 | − for (dar = addr; dar < addr + size; dar += page_size) { | |
| 223 | − if (!vma || dar < vma->vm_start || dar > vma->vm_end) { | |
| 222 | + vma = find_vma(mm, addr); | |
| 223 | + if (!vma) { | |
| 224 | + pr_err("Can't find vma for addr %016llx\n", addr); | |
| 225 | + rc = -EFAULT; | |
| 226 | + goto out; | |
| 227 | + } | |
| 228 | + /* get the size of the pages allocated */ | |
| 229 | + page_size = vma_kernel_pagesize(vma); | |
| 230 | + | |
| 231 | + for (dar = (addr & ~(page_size - 1)); dar < (addr + size); dar += page_size) { | |
| 232 | + if (dar < vma->vm_start || dar >= vma->vm_end) { | |
| 224 | 233 | vma = find_vma(mm, addr); |
| 225 | 234 | if (!vma) { |
| 226 | 235 | pr_err("Can't find vma for addr %016llx\n", addr); |
| @@ -1634,8 +1634,6 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, · 1633 unmodified lines | ||
| 1634 | 1634 | } |
| 1635 | 1635 | |
| 1636 | 1636 | mqrq->areq.mrq = &brq->mrq; |
| 1637 | − | |
| 1638 | − mmc_queue_bounce_pre(mqrq); | |
| 1639 | 1637 | } |
| 1640 | 1638 | |
| 1641 | 1639 | static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, |
| @@ -1829,7 +1827,6 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) · 187 unmodified lines | ||
| 1829 | 1827 | brq = &mq_rq->brq; |
| 1830 | 1828 | old_req = mmc_queue_req_to_req(mq_rq); |
| 1831 | 1829 | type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; |
| 1832 | − mmc_queue_bounce_post(mq_rq); | |
| 1833 | 1830 | |
| 1834 | 1831 | switch (status) { |
| 1835 | 1832 | case MMC_BLK_SUCCESS: |
| @@ -1286,6 +1286,23 @@ out_err: · 1285 unmodified lines | ||
| 1286 | 1286 | return err; |
| 1287 | 1287 | } |
| 1288 | 1288 | |
| 1289 | +static void mmc_select_driver_type(struct mmc_card *card) | |
| 1290 | +{ | |
| 1291 | + int card_drv_type, drive_strength, drv_type; | |
| 1292 | + | |
| 1293 | + card_drv_type = card->ext_csd.raw_driver_strength | | |
| 1294 | + mmc_driver_type_mask(0); | |
| 1295 | + | |
| 1296 | + drive_strength = mmc_select_drive_strength(card, | |
| 1297 | + card->ext_csd.hs200_max_dtr, | |
| 1298 | + card_drv_type, &drv_type); | |
| 1299 | + | |
| 1300 | + card->drive_strength = drive_strength; | |
| 1301 | + | |
| 1302 | + if (drv_type) | |
| 1303 | + mmc_set_driver_type(card->host, drv_type); | |
| 1304 | +} | |
| 1305 | + | |
| 1289 | 1306 | static int mmc_select_hs400es(struct mmc_card *card) |
| 1290 | 1307 | { |
| 1291 | 1308 | struct mmc_host *host = card->host; |
| @@ -1341,6 +1358,8 @@ static int mmc_select_hs400es(struct mmc_card *card) · 49 unmodified lines | ||
| 1341 | 1358 | goto out_err; |
| 1342 | 1359 | } |
| 1343 | 1360 | |
| 1361 | + mmc_select_driver_type(card); | |
| 1362 | + | |
| 1344 | 1363 | /* Switch card to HS400 */ |
| 1345 | 1364 | val = EXT_CSD_TIMING_HS400 | |
| 1346 | 1365 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; |
| @@ -1374,23 +1393,6 @@ out_err: · 27 unmodified lines | ||
| 1374 | 1393 | return err; |
| 1375 | 1394 | } |
| 1376 | 1395 | |
| 1377 | −static void mmc_select_driver_type(struct mmc_card *card) | |
| 1378 | −{ | |
| 1379 | − int card_drv_type, drive_strength, drv_type; | |
| 1380 | − | |
| 1381 | − card_drv_type = card->ext_csd.raw_driver_strength | | |
| 1382 | − mmc_driver_type_mask(0); | |
| 1383 | − | |
| 1384 | − drive_strength = mmc_select_drive_strength(card, | |
| 1385 | − card->ext_csd.hs200_max_dtr, | |
| 1386 | − card_drv_type, &drv_type); | |
| 1387 | − | |
| 1388 | − card->drive_strength = drive_strength; | |
| 1389 | − | |
| 1390 | − if (drv_type) | |
| 1391 | − mmc_set_driver_type(card->host, drv_type); | |
| 1392 | −} | |
| 1393 | − | |
| 1394 | 1396 | /* |
| 1395 | 1397 | * For device supporting HS200 mode, the following sequence |
| 1396 | 1398 | * should be done before executing the tuning process. |
| @@ -23,8 +23,6 @@ · 22 unmodified lines | ||
| 23 | 23 | #include "core.h" |
| 24 | 24 | #include "card.h" |
| 25 | 25 | |
| 26 | −#define MMC_QUEUE_BOUNCESZ 65536 | |
| 27 | − | |
| 28 | 26 | /* |
| 29 | 27 | * Prepare a MMC request. This just filters out odd stuff. |
| 30 | 28 | */ |
| @@ -150,26 +148,6 @@ static void mmc_queue_setup_discard(struct request_queue *q, · 119 unmodified lines | ||
| 150 | 148 | queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); |
| 151 | 149 | } |
| 152 | 150 | |
| 153 | −static unsigned int mmc_queue_calc_bouncesz(struct mmc_host *host) | |
| 154 | −{ | |
| 155 | − unsigned int bouncesz = MMC_QUEUE_BOUNCESZ; | |
| 156 | − | |
| 157 | − if (host->max_segs != 1 || (host->caps & MMC_CAP_NO_BOUNCE_BUFF)) | |
| 158 | − return 0; | |
| 159 | − | |
| 160 | − if (bouncesz > host->max_req_size) | |
| 161 | − bouncesz = host->max_req_size; | |
| 162 | − if (bouncesz > host->max_seg_size) | |
| 163 | − bouncesz = host->max_seg_size; | |
| 164 | − if (bouncesz > host->max_blk_count * 512) | |
| 165 | − bouncesz = host->max_blk_count * 512; | |
| 166 | − | |
| 167 | − if (bouncesz <= 512) | |
| 168 | − return 0; | |
| 169 | − | |
| 170 | − return bouncesz; | |
| 171 | −} | |
| 172 | − | |
| 173 | 151 | /** |
| 174 | 152 | * mmc_init_request() - initialize the MMC-specific per-request data |
| 175 | 153 | * @q: the request queue |
| @@ -184,26 +162,9 @@ static int mmc_init_request(struct request_queue *q, struct request *req, · 8 unmodified lines | ||
| 184 | 162 | struct mmc_card *card = mq->card; |
| 185 | 163 | struct mmc_host *host = card->host; |
| 186 | 164 | |
| 187 | − if (card->bouncesz) { | |
| 188 | − mq_rq->bounce_buf = kmalloc(card->bouncesz, gfp); | |
| 189 | − if (!mq_rq->bounce_buf) | |
| 190 | − return -ENOMEM; | |
| 191 | − if (card->bouncesz > 512) { | |
| 192 | − mq_rq->sg = mmc_alloc_sg(1, gfp); | |
| 193 | − if (!mq_rq->sg) | |
| 194 | − return -ENOMEM; | |
| 195 | − mq_rq->bounce_sg = mmc_alloc_sg(card->bouncesz / 512, | |
| 196 | − gfp); | |
| 197 | − if (!mq_rq->bounce_sg) | |
| 198 | − return -ENOMEM; | |
| 199 | − } | |
| 200 | − } else { | |
| 201 | − mq_rq->bounce_buf = NULL; | |
| 202 | − mq_rq->bounce_sg = NULL; | |
| 203 | − mq_rq->sg = mmc_alloc_sg(host->max_segs, gfp); | |
| 204 | − if (!mq_rq->sg) | |
| 205 | − return -ENOMEM; | |
| 206 | − } | |
| 165 | + mq_rq->sg = mmc_alloc_sg(host->max_segs, gfp); | |
| 166 | + if (!mq_rq->sg) | |
| 167 | + return -ENOMEM; | |
| 207 | 168 | |
| 208 | 169 | return 0; |
| 209 | 170 | } |
| @@ -212,13 +173,6 @@ static void mmc_exit_request(struct request_queue *q, struct request *req) · 2 unmodified lines | ||
| 212 | 173 | { |
| 213 | 174 | struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req); |
| 214 | 175 | |
| 215 | − /* It is OK to kfree(NULL) so this will be smooth */ | |
| 216 | − kfree(mq_rq->bounce_sg); | |
| 217 | − mq_rq->bounce_sg = NULL; | |
| 218 | − | |
| 219 | − kfree(mq_rq->bounce_buf); | |
| 220 | − mq_rq->bounce_buf = NULL; | |
| 221 | − | |
| 222 | 176 | kfree(mq_rq->sg); |
| 223 | 177 | mq_rq->sg = NULL; |
| 224 | 178 | } |
| @@ -265,18 +219,11 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, · 40 unmodified lines | ||
| 265 | 219 | if (mmc_can_erase(card)) |
| 266 | 220 | mmc_queue_setup_discard(mq->queue, card); |
| 267 | 221 | |
| 268 | − card->bouncesz = mmc_queue_calc_bouncesz(host); | |
| 269 | − if (card->bouncesz) { | |
| 270 | − blk_queue_max_hw_sectors(mq->queue, card->bouncesz / 512); | |
| 271 | − blk_queue_max_segments(mq->queue, card->bouncesz / 512); | |
| 272 | − blk_queue_max_segment_size(mq->queue, card->bouncesz); | |
| 273 | − } else { | |
| 274 | − blk_queue_bounce_limit(mq->queue, limit); | |
| 275 | − blk_queue_max_hw_sectors(mq->queue, | |
| 276 | − min(host->max_blk_count, host->max_req_size / 512)); | |
| 277 | − blk_queue_max_segments(mq->queue, host->max_segs); | |
| 278 | − blk_queue_max_segment_size(mq->queue, host->max_seg_size); | |
| 279 | − } | |
| 222 | + blk_queue_bounce_limit(mq->queue, limit); | |
| 223 | + blk_queue_max_hw_sectors(mq->queue, | |
| 224 | + min(host->max_blk_count, host->max_req_size / 512)); | |
| 225 | + blk_queue_max_segments(mq->queue, host->max_segs); | |
| 226 | + blk_queue_max_segment_size(mq->queue, host->max_seg_size); | |
| 280 | 227 | |
| 281 | 228 | sema_init(&mq->thread_sem, 1); |
| 282 | 229 | |
| @@ -365,56 +312,7 @@ void mmc_queue_resume(struct mmc_queue *mq) · 82 unmodified lines | ||
| 365 | 312 | */ |
| 366 | 313 | unsigned int mmc_queue_map_sg(struct mmc_queue *mq, struct mmc_queue_req *mqrq) |
| 367 | 314 | { |
| 368 | − unsigned int sg_len; | |
| 369 | − size_t buflen; | |
| 370 | − struct scatterlist *sg; | |
| 371 | 315 | struct request *req = mmc_queue_req_to_req(mqrq); |
| 372 | − int i; | |
| 373 | − | |
| 374 | − if (!mqrq->bounce_buf) | |
| 375 | − return blk_rq_map_sg(mq->queue, req, mqrq->sg); | |
| 376 | − | |
| 377 | − sg_len = blk_rq_map_sg(mq->queue, req, mqrq->bounce_sg); | |
| 378 | − | |
| 379 | − mqrq->bounce_sg_len = sg_len; | |
| 380 | − | |
| 381 | − buflen = 0; | |
| 382 | − for_each_sg(mqrq->bounce_sg, sg, sg_len, i) | |
| 383 | − buflen += sg->length; | |
| 384 | − | |
| 385 | − sg_init_one(mqrq->sg, mqrq->bounce_buf, buflen); | |
| 386 | − | |
| 387 | − return 1; | |
| 388 | −} | |
| 389 | − | |
| 390 | −/* | |
| 391 | − * If writing, bounce the data to the buffer before the request | |
| 392 | − * is sent to the host driver | |
| 393 | − */ | |
| 394 | −void mmc_queue_bounce_pre(struct mmc_queue_req *mqrq) | |
| 395 | −{ | |
| 396 | − if (!mqrq->bounce_buf) | |
| 397 | − return; | |
| 398 | − | |
| 399 | − if (rq_data_dir(mmc_queue_req_to_req(mqrq)) != WRITE) | |
| 400 | − return; | |
| 401 | − | |
| 402 | − sg_copy_to_buffer(mqrq->bounce_sg, mqrq->bounce_sg_len, | |
| 403 | − mqrq->bounce_buf, mqrq->sg[0].length); | |
| 404 | −} | |
| 405 | − | |
| 406 | −/* | |
| 407 | − * If reading, bounce the data from the buffer after the request | |
| 408 | − * has been handled by the host driver | |
| 409 | − */ | |
| 410 | −void mmc_queue_bounce_post(struct mmc_queue_req *mqrq) | |
| 411 | −{ | |
| 412 | − if (!mqrq->bounce_buf) | |
| 413 | − return; | |
| 414 | − | |
| 415 | − if (rq_data_dir(mmc_queue_req_to_req(mqrq)) != READ) | |
| 416 | − return; | |
| 417 | 316 | |
| 418 | − sg_copy_from_buffer(mqrq->bounce_sg, mqrq->bounce_sg_len, | |
| 419 | − mqrq->bounce_buf, mqrq->sg[0].length); | |
| 317 | + return blk_rq_map_sg(mq->queue, req, mqrq->sg); | |
| 420 | 318 | } |
| @@ -49,9 +49,6 @@ enum mmc_drv_op { · 48 unmodified lines | ||
| 49 | 49 | struct mmc_queue_req { |
| 50 | 50 | struct mmc_blk_request brq; |
| 51 | 51 | struct scatterlist *sg; |
| 52 | − char *bounce_buf; | |
| 53 | − struct scatterlist *bounce_sg; | |
| 54 | − unsigned int bounce_sg_len; | |
| 55 | 52 | struct mmc_async_req areq; |
| 56 | 53 | enum mmc_drv_op drv_op; |
| 57 | 54 | int drv_op_result; |
| @@ -81,11 +78,8 @@ extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, · 23 unmodified lines | ||
| 81 | 78 | extern void mmc_cleanup_queue(struct mmc_queue *); |
| 82 | 79 | extern void mmc_queue_suspend(struct mmc_queue *); |
| 83 | 80 | extern void mmc_queue_resume(struct mmc_queue *); |
| 84 | − | |
| 85 | 81 | extern unsigned int mmc_queue_map_sg(struct mmc_queue *, |
| 86 | 82 | struct mmc_queue_req *); |
| 87 | −extern void mmc_queue_bounce_pre(struct mmc_queue_req *); | |
| 88 | −extern void mmc_queue_bounce_post(struct mmc_queue_req *); | |
| 89 | 83 | |
| 90 | 84 | extern int mmc_access_rpmb(struct mmc_queue *); |
| 91 | 85 | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | comment "MMC/SD/SDIO Host Controller Drivers" |
| 6 | 6 | |
| 7 | 7 | config MMC_DEBUG |
| 8 | − bool "MMC host drivers debugginG" | |
| 8 | + bool "MMC host drivers debugging" | |
| 9 | 9 | depends on MMC != n |
| 10 | 10 | help |
| 11 | 11 | This is an option for use by developers; most people should |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * |
| 8 | 8 | * Copyright (C) 2016 Cavium Inc. |
| 9 | 9 | */ |
| 10 | +#include <linux/device.h> | |
| 10 | 11 | #include <linux/dma-mapping.h> |
| 11 | 12 | #include <linux/interrupt.h> |
| 12 | 13 | #include <linux/mmc/mmc.h> |
| @@ -149,8 +150,11 @@ error: · 136 unmodified lines | ||
| 149 | 150 | for (i = 0; i < CAVIUM_MAX_MMC; i++) { |
| 150 | 151 | if (host->slot[i]) |
| 151 | 152 | cvm_mmc_of_slot_remove(host->slot[i]); |
| 152 | − if (host->slot_pdev[i]) | |
| 153 | + if (host->slot_pdev[i]) { | |
| 154 | + get_device(&host->slot_pdev[i]->dev); | |
| 153 | 155 | of_platform_device_destroy(&host->slot_pdev[i]->dev, NULL); |
| 156 | + put_device(&host->slot_pdev[i]->dev); | |
| 157 | + } | |
| 154 | 158 | } |
| 155 | 159 | clk_disable_unprepare(host->clk); |
| 156 | 160 | return ret; |
| @@ -1038,7 +1038,7 @@ int cvm_mmc_of_slot_probe(struct device *dev, struct cvm_mmc_host *host) · 1037 unmodified lines | ||
| 1038 | 1038 | */ |
| 1039 | 1039 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | |
| 1040 | 1040 | MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_POWER_OFF_CARD | |
| 1041 | − MMC_CAP_3_3V_DDR | MMC_CAP_NO_BOUNCE_BUFF; | |
| 1041 | + MMC_CAP_3_3V_DDR; | |
| 1042 | 1042 | |
| 1043 | 1043 | if (host->use_sg) |
| 1044 | 1044 | mmc->max_segs = 16; |
| @@ -531,8 +531,7 @@ static int meson_mmc_clk_init(struct meson_host *host) · 530 unmodified lines | ||
| 531 | 531 | div->shift = __ffs(CLK_DIV_MASK); |
| 532 | 532 | div->width = __builtin_popcountl(CLK_DIV_MASK); |
| 533 | 533 | div->hw.init = &init; |
| 534 | − div->flags = (CLK_DIVIDER_ONE_BASED | | |
| 535 | − CLK_DIVIDER_ROUND_CLOSEST); | |
| 534 | + div->flags = CLK_DIVIDER_ONE_BASED; | |
| 536 | 535 | |
| 537 | 536 | clk = devm_clk_register(host->dev, &div->hw); |
| 538 | 537 | if (WARN_ON(IS_ERR(clk))) |
| @@ -717,6 +716,22 @@ static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode, · 178 unmodified lines | ||
| 717 | 716 | static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) |
| 718 | 717 | { |
| 719 | 718 | struct meson_host *host = mmc_priv(mmc); |
| 719 | + int ret; | |
| 720 | + | |
| 721 | + /* | |
| 722 | + * If this is the initial tuning, try to get a sane Rx starting | |
| 723 | + * phase before doing the actual tuning. | |
| 724 | + */ | |
| 725 | + if (!mmc->doing_retune) { | |
| 726 | + ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); | |
| 727 | + | |
| 728 | + if (ret) | |
| 729 | + return ret; | |
| 730 | + } | |
| 731 | + | |
| 732 | + ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->tx_clk); | |
| 733 | + if (ret) | |
| 734 | + return ret; | |
| 720 | 735 | |
| 721 | 736 | return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); |
| 722 | 737 | } |
| @@ -746,6 +761,11 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 23 unmodified lines | ||
| 746 | 761 | case MMC_POWER_UP: |
| 747 | 762 | if (!IS_ERR(mmc->supply.vmmc)) |
| 748 | 763 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); |
| 764 | + | |
| 765 | + /* Reset phases */ | |
| 766 | + clk_set_phase(host->rx_clk, 0); | |
| 767 | + clk_set_phase(host->tx_clk, 270); | |
| 768 | + | |
| 749 | 769 | break; |
| 750 | 770 | |
| 751 | 771 | case MMC_POWER_ON: |
| @@ -759,8 +779,6 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 7 unmodified lines | ||
| 759 | 779 | host->vqmmc_enabled = true; |
| 760 | 780 | } |
| 761 | 781 | |
| 762 | − /* Reset rx phase */ | |
| 763 | − clk_set_phase(host->rx_clk, 0); | |
| 764 | 782 | break; |
| 765 | 783 | } |
| 766 | 784 | |
| @@ -702,11 +702,7 @@ static int pxamci_probe(struct platform_device *pdev) · 701 unmodified lines | ||
| 702 | 702 | |
| 703 | 703 | pxamci_init_ocr(host); |
| 704 | 704 | |
| 705 | − /* | |
| 706 | − * This architecture used to disable bounce buffers through its | |
| 707 | − * defconfig, now it is done at runtime as a host property. | |
| 708 | − */ | |
| 709 | − mmc->caps = MMC_CAP_NO_BOUNCE_BUFF; | |
| 705 | + mmc->caps = 0; | |
| 710 | 706 | host->cmdat = 0; |
| 711 | 707 | if (!cpu_is_pxa25x()) { |
| 712 | 708 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; |
| @@ -392,6 +392,7 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = { · 391 unmodified lines | ||
| 392 | 392 | |
| 393 | 393 | enum { |
| 394 | 394 | INTEL_DSM_FNS = 0, |
| 395 | + INTEL_DSM_V18_SWITCH = 3, | |
| 395 | 396 | INTEL_DSM_DRV_STRENGTH = 9, |
| 396 | 397 | INTEL_DSM_D3_RETUNE = 10, |
| 397 | 398 | }; |
| @@ -557,6 +558,19 @@ static void intel_hs400_enhanced_strobe(struct mmc_host *mmc, · 159 unmodified lines | ||
| 557 | 558 | sdhci_writel(host, val, INTEL_HS400_ES_REG); |
| 558 | 559 | } |
| 559 | 560 | |
| 561 | +static void sdhci_intel_voltage_switch(struct sdhci_host *host) | |
| 562 | +{ | |
| 563 | + struct sdhci_pci_slot *slot = sdhci_priv(host); | |
| 564 | + struct intel_host *intel_host = sdhci_pci_priv(slot); | |
| 565 | + struct device *dev = &slot->chip->pdev->dev; | |
| 566 | + u32 result = 0; | |
| 567 | + int err; | |
| 568 | + | |
| 569 | + err = intel_dsm(intel_host, dev, INTEL_DSM_V18_SWITCH, &result); | |
| 570 | + pr_debug("%s: %s DSM error %d result %u\n", | |
| 571 | + mmc_hostname(host->mmc), __func__, err, result); | |
| 572 | +} | |
| 573 | + | |
| 560 | 574 | static const struct sdhci_ops sdhci_intel_byt_ops = { |
| 561 | 575 | .set_clock = sdhci_set_clock, |
| 562 | 576 | .set_power = sdhci_intel_set_power, |
| @@ -565,6 +579,7 @@ static const struct sdhci_ops sdhci_intel_byt_ops = { · 2 unmodified lines | ||
| 565 | 579 | .reset = sdhci_reset, |
| 566 | 580 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
| 567 | 581 | .hw_reset = sdhci_pci_hw_reset, |
| 582 | + .voltage_switch = sdhci_intel_voltage_switch, | |
| 568 | 583 | }; |
| 569 | 584 | |
| 570 | 585 | static void byt_read_dsm(struct sdhci_pci_slot *slot) |
| @@ -466,6 +466,7 @@ static int xenon_probe(struct platform_device *pdev) · 465 unmodified lines | ||
| 466 | 466 | { |
| 467 | 467 | struct sdhci_pltfm_host *pltfm_host; |
| 468 | 468 | struct sdhci_host *host; |
| 469 | + struct xenon_priv *priv; | |
| 469 | 470 | int err; |
| 470 | 471 | |
| 471 | 472 | host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata, |
| @@ -474,6 +475,7 @@ static int xenon_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 474 | 475 | return PTR_ERR(host); |
| 475 | 476 | |
| 476 | 477 | pltfm_host = sdhci_priv(host); |
| 478 | + priv = sdhci_pltfm_priv(pltfm_host); | |
| 477 | 479 | |
| 478 | 480 | /* |
| 479 | 481 | * Link Xenon specific mmc_host_ops function, |
| @@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 491 | 493 | if (err) |
| 492 | 494 | goto free_pltfm; |
| 493 | 495 | |
| 496 | + priv->axi_clk = devm_clk_get(&pdev->dev, "axi"); | |
| 497 | + if (IS_ERR(priv->axi_clk)) { | |
| 498 | + err = PTR_ERR(priv->axi_clk); | |
| 499 | + if (err == -EPROBE_DEFER) | |
| 500 | + goto err_clk; | |
| 501 | + } else { | |
| 502 | + err = clk_prepare_enable(priv->axi_clk); | |
| 503 | + if (err) | |
| 504 | + goto err_clk; | |
| 505 | + } | |
| 506 | + | |
| 494 | 507 | err = mmc_of_parse(host->mmc); |
| 495 | 508 | if (err) |
| 496 | − goto err_clk; | |
| 509 | + goto err_clk_axi; | |
| 497 | 510 | |
| 498 | 511 | sdhci_get_of_property(pdev); |
| 499 | 512 | |
| @@ -502,11 +515,11 @@ static int xenon_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 502 | 515 | /* Xenon specific dt parse */ |
| 503 | 516 | err = xenon_probe_dt(pdev); |
| 504 | 517 | if (err) |
| 505 | − goto err_clk; | |
| 518 | + goto err_clk_axi; | |
| 506 | 519 | |
| 507 | 520 | err = xenon_sdhc_prepare(host); |
| 508 | 521 | if (err) |
| 509 | − goto err_clk; | |
| 522 | + goto err_clk_axi; | |
| 510 | 523 | |
| 511 | 524 | pm_runtime_get_noresume(&pdev->dev); |
| 512 | 525 | pm_runtime_set_active(&pdev->dev); |
| @@ -527,6 +540,8 @@ remove_sdhc: · 14 unmodified lines | ||
| 527 | 540 | pm_runtime_disable(&pdev->dev); |
| 528 | 541 | pm_runtime_put_noidle(&pdev->dev); |
| 529 | 542 | xenon_sdhc_unprepare(host); |
| 543 | +err_clk_axi: | |
| 544 | + clk_disable_unprepare(priv->axi_clk); | |
| 530 | 545 | err_clk: |
| 531 | 546 | clk_disable_unprepare(pltfm_host->clk); |
| 532 | 547 | free_pltfm: |
| @@ -538,6 +553,7 @@ static int xenon_remove(struct platform_device *pdev) · 5 unmodified lines | ||
| 538 | 553 | { |
| 539 | 554 | struct sdhci_host *host = platform_get_drvdata(pdev); |
| 540 | 555 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 556 | + struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); | |
| 541 | 557 | |
| 542 | 558 | pm_runtime_get_sync(&pdev->dev); |
| 543 | 559 | pm_runtime_disable(&pdev->dev); |
| @@ -546,7 +562,7 @@ static int xenon_remove(struct platform_device *pdev) · 2 unmodified lines | ||
| 546 | 562 | sdhci_remove_host(host, 0); |
| 547 | 563 | |
| 548 | 564 | xenon_sdhc_unprepare(host); |
| 549 | − | |
| 565 | + clk_disable_unprepare(priv->axi_clk); | |
| 550 | 566 | clk_disable_unprepare(pltfm_host->clk); |
| 551 | 567 | |
| 552 | 568 | sdhci_pltfm_free(pdev); |
| @@ -83,6 +83,7 @@ struct xenon_priv { · 82 unmodified lines | ||
| 83 | 83 | unsigned char bus_width; |
| 84 | 84 | unsigned char timing; |
| 85 | 85 | unsigned int clock; |
| 86 | + struct clk *axi_clk; | |
| 86 | 87 | |
| 87 | 88 | int phy_type; |
| 88 | 89 | /* |
| @@ -129,50 +129,6 @@ static int tmio_mmc_next_sg(struct tmio_mmc_host *host) · 128 unmodified lines | ||
| 129 | 129 | |
| 130 | 130 | #define CMDREQ_TIMEOUT 5000 |
| 131 | 131 | |
| 132 | −#ifdef CONFIG_MMC_DEBUG | |
| 133 | − | |
| 134 | −#define STATUS_TO_TEXT(a, status, i) \ | |
| 135 | − do { \ | |
| 136 | − if ((status) & TMIO_STAT_##a) { \ | |
| 137 | − if ((i)++) \ | |
| 138 | − printk(KERN_DEBUG " | "); \ | |
| 139 | − printk(KERN_DEBUG #a); \ | |
| 140 | − } \ | |
| 141 | − } while (0) | |
| 142 | − | |
| 143 | −static void pr_debug_status(u32 status) | |
| 144 | −{ | |
| 145 | − int i = 0; | |
| 146 | − | |
| 147 | − pr_debug("status: %08x = ", status); | |
| 148 | − STATUS_TO_TEXT(CARD_REMOVE, status, i); | |
| 149 | − STATUS_TO_TEXT(CARD_INSERT, status, i); | |
| 150 | − STATUS_TO_TEXT(SIGSTATE, status, i); | |
| 151 | − STATUS_TO_TEXT(WRPROTECT, status, i); | |
| 152 | − STATUS_TO_TEXT(CARD_REMOVE_A, status, i); | |
| 153 | − STATUS_TO_TEXT(CARD_INSERT_A, status, i); | |
| 154 | − STATUS_TO_TEXT(SIGSTATE_A, status, i); | |
| 155 | − STATUS_TO_TEXT(CMD_IDX_ERR, status, i); | |
| 156 | − STATUS_TO_TEXT(STOPBIT_ERR, status, i); | |
| 157 | − STATUS_TO_TEXT(ILL_FUNC, status, i); | |
| 158 | − STATUS_TO_TEXT(CMD_BUSY, status, i); | |
| 159 | − STATUS_TO_TEXT(CMDRESPEND, status, i); | |
| 160 | − STATUS_TO_TEXT(DATAEND, status, i); | |
| 161 | − STATUS_TO_TEXT(CRCFAIL, status, i); | |
| 162 | − STATUS_TO_TEXT(DATATIMEOUT, status, i); | |
| 163 | − STATUS_TO_TEXT(CMDTIMEOUT, status, i); | |
| 164 | − STATUS_TO_TEXT(RXOVERFLOW, status, i); | |
| 165 | − STATUS_TO_TEXT(TXUNDERRUN, status, i); | |
| 166 | − STATUS_TO_TEXT(RXRDY, status, i); | |
| 167 | − STATUS_TO_TEXT(TXRQ, status, i); | |
| 168 | − STATUS_TO_TEXT(ILL_ACCESS, status, i); | |
| 169 | − printk("\n"); | |
| 170 | −} | |
| 171 | − | |
| 172 | −#else | |
| 173 | −#define pr_debug_status(s) do { } while (0) | |
| 174 | −#endif | |
| 175 | − | |
| 176 | 132 | static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) |
| 177 | 133 | { |
| 178 | 134 | struct tmio_mmc_host *host = mmc_priv(mmc); |
| @@ -762,9 +718,6 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid) · 583 unmodified lines | ||
| 762 | 718 | status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS); |
| 763 | 719 | ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask; |
| 764 | 720 | |
| 765 | − pr_debug_status(status); | |
| 766 | − pr_debug_status(ireg); | |
| 767 | − | |
| 768 | 721 | /* Clear the status except the interrupt status */ |
| 769 | 722 | sd_ctrl_write32_as_16_and_16(host, CTL_STATUS, TMIO_MASK_IRQ); |
| 770 | 723 | |
| @@ -581,6 +581,14 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent, · 580 unmodified lines | ||
| 581 | 581 | slave->mtd.erasesize = parent->erasesize; |
| 582 | 582 | } |
| 583 | 583 | |
| 584 | + /* | |
| 585 | + * Slave erasesize might differ from the master one if the master | |
| 586 | + * exposes several regions with different erasesize. Adjust | |
| 587 | + * wr_alignment accordingly. | |
| 588 | + */ | |
| 589 | + if (!(slave->mtd.flags & MTD_NO_ERASE)) | |
| 590 | + wr_alignment = slave->mtd.erasesize; | |
| 591 | + | |
| 584 | 592 | tmp = slave->offset; |
| 585 | 593 | remainder = do_div(tmp, wr_alignment); |
| 586 | 594 | if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { |
| @@ -363,7 +363,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc, · 362 unmodified lines | ||
| 363 | 363 | size += (req->ecc.strength + 1) * sizeof(u16); |
| 364 | 364 | /* Reserve space for mu, dmu and delta. */ |
| 365 | 365 | size = ALIGN(size, sizeof(s32)); |
| 366 | − size += (req->ecc.strength + 1) * sizeof(s32); | |
| 366 | + size += (req->ecc.strength + 1) * sizeof(s32) * 3; | |
| 367 | 367 | |
| 368 | 368 | user = kzalloc(size, GFP_KERNEL); |
| 369 | 369 | if (!user) |
| @@ -707,7 +707,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) · 706 unmodified lines | ||
| 707 | 707 | } |
| 708 | 708 | res = clk_prepare_enable(host->clk); |
| 709 | 709 | if (res) |
| 710 | − goto err_exit1; | |
| 710 | + goto err_put_clk; | |
| 711 | 711 | |
| 712 | 712 | nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl; |
| 713 | 713 | nand_chip->dev_ready = lpc32xx_nand_device_ready; |
| @@ -814,6 +814,7 @@ err_exit3: · 100 unmodified lines | ||
| 814 | 814 | dma_release_channel(host->dma_chan); |
| 815 | 815 | err_exit2: |
| 816 | 816 | clk_disable_unprepare(host->clk); |
| 817 | +err_put_clk: | |
| 817 | 818 | clk_put(host->clk); |
| 818 | 819 | err_exit1: |
| 819 | 820 | lpc32xx_wp_enable(host); |
| @@ -2668,7 +2668,7 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len, · 2667 unmodified lines | ||
| 2668 | 2668 | static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, |
| 2669 | 2669 | struct mtd_oob_ops *ops) |
| 2670 | 2670 | { |
| 2671 | − int chipnr, realpage, page, blockmask, column; | |
| 2671 | + int chipnr, realpage, page, column; | |
| 2672 | 2672 | struct nand_chip *chip = mtd_to_nand(mtd); |
| 2673 | 2673 | uint32_t writelen = ops->len; |
| 2674 | 2674 | |
| @@ -2704,7 +2704,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, · 29 unmodified lines | ||
| 2704 | 2704 | |
| 2705 | 2705 | realpage = (int)(to >> chip->page_shift); |
| 2706 | 2706 | page = realpage & chip->pagemask; |
| 2707 | − blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; | |
| 2708 | 2707 | |
| 2709 | 2708 | /* Invalidate the page cache, when we write to the cached page */ |
| 2710 | 2709 | if (to <= ((loff_t)chip->pagebuf << chip->page_shift) && |
| @@ -1784,7 +1784,7 @@ spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, · 1783 unmodified lines | ||
| 1784 | 1784 | * @nor: pointer to a 'struct spi_nor' |
| 1785 | 1785 | * @addr: offset in the SFDP area to start reading data from |
| 1786 | 1786 | * @len: number of bytes to read |
| 1787 | − * @buf: buffer where the SFDP data are copied into | |
| 1787 | + * @buf: buffer where the SFDP data are copied into (dma-safe memory) | |
| 1788 | 1788 | * |
| 1789 | 1789 | * Whatever the actual numbers of bytes for address and dummy cycles are |
| 1790 | 1790 | * for (Fast) Read commands, the Read SFDP (5Ah) instruction is always |
| @@ -1829,6 +1829,36 @@ read_err: · 38 unmodified lines | ||
| 1829 | 1829 | return ret; |
| 1830 | 1830 | } |
| 1831 | 1831 | |
| 1832 | +/** | |
| 1833 | + * spi_nor_read_sfdp_dma_unsafe() - read Serial Flash Discoverable Parameters. | |
| 1834 | + * @nor: pointer to a 'struct spi_nor' | |
| 1835 | + * @addr: offset in the SFDP area to start reading data from | |
| 1836 | + * @len: number of bytes to read | |
| 1837 | + * @buf: buffer where the SFDP data are copied into | |
| 1838 | + * | |
| 1839 | + * Wrap spi_nor_read_sfdp() using a kmalloc'ed bounce buffer as @buf is now not | |
| 1840 | + * guaranteed to be dma-safe. | |
| 1841 | + * | |
| 1842 | + * Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp() | |
| 1843 | + * otherwise. | |
| 1844 | + */ | |
| 1845 | +static int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr, | |
| 1846 | + size_t len, void *buf) | |
| 1847 | +{ | |
| 1848 | + void *dma_safe_buf; | |
| 1849 | + int ret; | |
| 1850 | + | |
| 1851 | + dma_safe_buf = kmalloc(len, GFP_KERNEL); | |
| 1852 | + if (!dma_safe_buf) | |
| 1853 | + return -ENOMEM; | |
| 1854 | + | |
| 1855 | + ret = spi_nor_read_sfdp(nor, addr, len, dma_safe_buf); | |
| 1856 | + memcpy(buf, dma_safe_buf, len); | |
| 1857 | + kfree(dma_safe_buf); | |
| 1858 | + | |
| 1859 | + return ret; | |
| 1860 | +} | |
| 1861 | + | |
| 1832 | 1862 | struct sfdp_parameter_header { |
| 1833 | 1863 | u8 id_lsb; |
| 1834 | 1864 | u8 minor; |
| @@ -2101,7 +2131,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, · 266 unmodified lines | ||
| 2101 | 2131 | bfpt_header->length * sizeof(u32)); |
| 2102 | 2132 | addr = SFDP_PARAM_HEADER_PTP(bfpt_header); |
| 2103 | 2133 | memset(&bfpt, 0, sizeof(bfpt)); |
| 2104 | − err = spi_nor_read_sfdp(nor, addr, len, &bfpt); | |
| 2134 | + err = spi_nor_read_sfdp_dma_unsafe(nor, addr, len, &bfpt); | |
| 2105 | 2135 | if (err < 0) |
| 2106 | 2136 | return err; |
| 2107 | 2137 | |
| @@ -2127,6 +2157,15 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, · 19 unmodified lines | ||
| 2127 | 2157 | params->size = bfpt.dwords[BFPT_DWORD(2)]; |
| 2128 | 2158 | if (params->size & BIT(31)) { |
| 2129 | 2159 | params->size &= ~BIT(31); |
| 2160 | + | |
| 2161 | + /* | |
| 2162 | + * Prevent overflows on params->size. Anyway, a NOR of 2^64 | |
| 2163 | + * bits is unlikely to exist so this error probably means | |
| 2164 | + * the BFPT we are reading is corrupted/wrong. | |
| 2165 | + */ | |
| 2166 | + if (params->size > 63) | |
| 2167 | + return -EINVAL; | |
| 2168 | + | |
| 2130 | 2169 | params->size = 1ULL << params->size; |
| 2131 | 2170 | } else { |
| 2132 | 2171 | params->size++; |
| @@ -2243,7 +2282,7 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, · 110 unmodified lines | ||
| 2243 | 2282 | int i, err; |
| 2244 | 2283 | |
| 2245 | 2284 | /* Get the SFDP header. */ |
| 2246 | − err = spi_nor_read_sfdp(nor, 0, sizeof(header), &header); | |
| 2285 | + err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(header), &header); | |
| 2247 | 2286 | if (err < 0) |
| 2248 | 2287 | return err; |
| 2249 | 2288 | |
| @@ -1100,6 +1100,10 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, · 1099 unmodified lines | ||
| 1100 | 1100 | }; |
| 1101 | 1101 | int i, err; |
| 1102 | 1102 | |
| 1103 | + /* DSA and CPU ports have to be members of multiple vlans */ | |
| 1104 | + if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) | |
| 1105 | + return 0; | |
| 1106 | + | |
| 1103 | 1107 | if (!vid_begin) |
| 1104 | 1108 | return -EOPNOTSUPP; |
| 1105 | 1109 | |
| @@ -3947,7 +3951,9 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev) · 2841 unmodified lines | ||
| 3947 | 3951 | if (chip->irq > 0) { |
| 3948 | 3952 | if (chip->info->g2_irqs > 0) |
| 3949 | 3953 | mv88e6xxx_g2_irq_free(chip); |
| 3954 | + mutex_lock(&chip->reg_lock); | |
| 3950 | 3955 | mv88e6xxx_g1_irq_free(chip); |
| 3956 | + mutex_unlock(&chip->reg_lock); | |
| 3951 | 3957 | } |
| 3952 | 3958 | } |
| 3953 | 3959 | |
| @@ -51,6 +51,10 @@ · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | #define AQ_CFG_SKB_FRAGS_MAX 32U |
| 53 | 53 | |
| 54 | +/* Number of descriptors available in one ring to resume this ring queue | |
| 55 | + */ | |
| 56 | +#define AQ_CFG_RESTART_DESC_THRES (AQ_CFG_SKB_FRAGS_MAX * 2) | |
| 57 | + | |
| 54 | 58 | #define AQ_CFG_NAPI_WEIGHT 64U |
| 55 | 59 | |
| 56 | 60 | #define AQ_CFG_MULTICAST_ADDRESS_MAX 32U |
| @@ -119,6 +119,35 @@ int aq_nic_cfg_start(struct aq_nic_s *self) · 118 unmodified lines | ||
| 119 | 119 | return 0; |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | +static int aq_nic_update_link_status(struct aq_nic_s *self) | |
| 123 | +{ | |
| 124 | + int err = self->aq_hw_ops.hw_get_link_status(self->aq_hw); | |
| 125 | + | |
| 126 | + if (err) | |
| 127 | + return err; | |
| 128 | + | |
| 129 | + if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) | |
| 130 | + pr_info("%s: link change old %d new %d\n", | |
| 131 | + AQ_CFG_DRV_NAME, self->link_status.mbps, | |
| 132 | + self->aq_hw->aq_link_status.mbps); | |
| 133 | + | |
| 134 | + self->link_status = self->aq_hw->aq_link_status; | |
| 135 | + if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) { | |
| 136 | + aq_utils_obj_set(&self->header.flags, | |
| 137 | + AQ_NIC_FLAG_STARTED); | |
| 138 | + aq_utils_obj_clear(&self->header.flags, | |
| 139 | + AQ_NIC_LINK_DOWN); | |
| 140 | + netif_carrier_on(self->ndev); | |
| 141 | + netif_tx_wake_all_queues(self->ndev); | |
| 142 | + } | |
| 143 | + if (netif_carrier_ok(self->ndev) && !self->link_status.mbps) { | |
| 144 | + netif_carrier_off(self->ndev); | |
| 145 | + netif_tx_disable(self->ndev); | |
| 146 | + aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN); | |
| 147 | + } | |
| 148 | + return 0; | |
| 149 | +} | |
| 150 | + | |
| 122 | 151 | static void aq_nic_service_timer_cb(unsigned long param) |
| 123 | 152 | { |
| 124 | 153 | struct aq_nic_s *self = (struct aq_nic_s *)param; |
| @@ -131,26 +160,13 @@ static void aq_nic_service_timer_cb(unsigned long param) · 6 unmodified lines | ||
| 131 | 160 | if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY)) |
| 132 | 161 | goto err_exit; |
| 133 | 162 | |
| 134 | − err = self->aq_hw_ops.hw_get_link_status(self->aq_hw); | |
| 135 | − if (err < 0) | |
| 163 | + err = aq_nic_update_link_status(self); | |
| 164 | + if (err) | |
| 136 | 165 | goto err_exit; |
| 137 | 166 | |
| 138 | − self->link_status = self->aq_hw->aq_link_status; | |
| 139 | − | |
| 140 | 167 | self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, |
| 141 | 168 | self->aq_nic_cfg.is_interrupt_moderation); |
| 142 | 169 | |
| 143 | − if (self->link_status.mbps) { | |
| 144 | − aq_utils_obj_set(&self->header.flags, | |
| 145 | − AQ_NIC_FLAG_STARTED); | |
| 146 | − aq_utils_obj_clear(&self->header.flags, | |
| 147 | − AQ_NIC_LINK_DOWN); | |
| 148 | − netif_carrier_on(self->ndev); | |
| 149 | − } else { | |
| 150 | − netif_carrier_off(self->ndev); | |
| 151 | − aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN); | |
| 152 | − } | |
| 153 | − | |
| 154 | 170 | memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); |
| 155 | 171 | memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); |
| 156 | 172 | for (i = AQ_DIMOF(self->aq_vec); i--;) { |
| @@ -214,7 +230,6 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, · 57 unmodified lines | ||
| 214 | 230 | SET_NETDEV_DEV(ndev, dev); |
| 215 | 231 | |
| 216 | 232 | ndev->if_port = port; |
| 217 | − ndev->min_mtu = ETH_MIN_MTU; | |
| 218 | 233 | self->ndev = ndev; |
| 219 | 234 | |
| 220 | 235 | self->aq_pci_func = aq_pci_func; |
| @@ -241,7 +256,6 @@ err_exit: · 20 unmodified lines | ||
| 241 | 256 | int aq_nic_ndev_register(struct aq_nic_s *self) |
| 242 | 257 | { |
| 243 | 258 | int err = 0; |
| 244 | − unsigned int i = 0U; | |
| 245 | 259 | |
| 246 | 260 | if (!self->ndev) { |
| 247 | 261 | err = -EINVAL; |
| @@ -263,8 +277,7 @@ int aq_nic_ndev_register(struct aq_nic_s *self) · 15 unmodified lines | ||
| 263 | 277 | |
| 264 | 278 | netif_carrier_off(self->ndev); |
| 265 | 279 | |
| 266 | − for (i = AQ_CFG_VECS_MAX; i--;) | |
| 267 | − aq_nic_ndev_queue_stop(self, i); | |
| 280 | + netif_tx_disable(self->ndev); | |
| 268 | 281 | |
| 269 | 282 | err = register_netdev(self->ndev); |
| 270 | 283 | if (err < 0) |
| @@ -283,6 +296,7 @@ int aq_nic_ndev_init(struct aq_nic_s *self) · 12 unmodified lines | ||
| 283 | 296 | self->ndev->features = aq_hw_caps->hw_features; |
| 284 | 297 | self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; |
| 285 | 298 | self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN; |
| 299 | + self->ndev->max_mtu = self->aq_hw_caps.mtu - ETH_FCS_LEN - ETH_HLEN; | |
| 286 | 300 | |
| 287 | 301 | return 0; |
| 288 | 302 | } |
| @@ -318,12 +332,8 @@ struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev) · 29 unmodified lines | ||
| 318 | 332 | err = -EINVAL; |
| 319 | 333 | goto err_exit; |
| 320 | 334 | } |
| 321 | − if (netif_running(ndev)) { | |
| 322 | − unsigned int i; | |
| 323 | − | |
| 324 | − for (i = AQ_CFG_VECS_MAX; i--;) | |
| 325 | − netif_stop_subqueue(ndev, i); | |
| 326 | − } | |
| 335 | + if (netif_running(ndev)) | |
| 336 | + netif_tx_disable(ndev); | |
| 327 | 337 | |
| 328 | 338 | for (self->aq_vecs = 0; self->aq_vecs < self->aq_nic_cfg.vecs; |
| 329 | 339 | self->aq_vecs++) { |
| @@ -383,16 +393,6 @@ err_exit: · 53 unmodified lines | ||
| 383 | 393 | return err; |
| 384 | 394 | } |
| 385 | 395 | |
| 386 | −void aq_nic_ndev_queue_start(struct aq_nic_s *self, unsigned int idx) | |
| 387 | −{ | |
| 388 | − netif_start_subqueue(self->ndev, idx); | |
| 389 | −} | |
| 390 | − | |
| 391 | −void aq_nic_ndev_queue_stop(struct aq_nic_s *self, unsigned int idx) | |
| 392 | −{ | |
| 393 | − netif_stop_subqueue(self->ndev, idx); | |
| 394 | −} | |
| 395 | − | |
| 396 | 396 | int aq_nic_start(struct aq_nic_s *self) |
| 397 | 397 | { |
| 398 | 398 | struct aq_vec_s *aq_vec = NULL; |
| @@ -451,10 +451,6 @@ int aq_nic_start(struct aq_nic_s *self) · 52 unmodified lines | ||
| 451 | 451 | goto err_exit; |
| 452 | 452 | } |
| 453 | 453 | |
| 454 | − for (i = 0U, aq_vec = self->aq_vec[0]; | |
| 455 | − self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) | |
| 456 | − aq_nic_ndev_queue_start(self, i); | |
| 457 | − | |
| 458 | 454 | err = netif_set_real_num_tx_queues(self->ndev, self->aq_vecs); |
| 459 | 455 | if (err < 0) |
| 460 | 456 | goto err_exit; |
| @@ -463,6 +459,8 @@ int aq_nic_start(struct aq_nic_s *self) · 2 unmodified lines | ||
| 463 | 459 | if (err < 0) |
| 464 | 460 | goto err_exit; |
| 465 | 461 | |
| 462 | + netif_tx_start_all_queues(self->ndev); | |
| 463 | + | |
| 466 | 464 | err_exit: |
| 467 | 465 | return err; |
| 468 | 466 | } |
| @@ -475,6 +473,7 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, · 6 unmodified lines | ||
| 475 | 473 | unsigned int nr_frags = skb_shinfo(skb)->nr_frags; |
| 476 | 474 | unsigned int frag_count = 0U; |
| 477 | 475 | unsigned int dx = ring->sw_tail; |
| 476 | + struct aq_ring_buff_s *first = NULL; | |
| 478 | 477 | struct aq_ring_buff_s *dx_buff = &ring->buff_ring[dx]; |
| 479 | 478 | |
| 480 | 479 | if (unlikely(skb_is_gso(skb))) { |
| @@ -485,6 +484,7 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, · 4 unmodified lines | ||
| 485 | 484 | dx_buff->len_l4 = tcp_hdrlen(skb); |
| 486 | 485 | dx_buff->mss = skb_shinfo(skb)->gso_size; |
| 487 | 486 | dx_buff->is_txc = 1U; |
| 487 | + dx_buff->eop_index = 0xffffU; | |
| 488 | 488 | |
| 489 | 489 | dx_buff->is_ipv6 = |
| 490 | 490 | (ip_hdr(skb)->version == 6) ? 1U : 0U; |
| @@ -504,6 +504,7 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, · 13 unmodified lines | ||
| 504 | 504 | if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) |
| 505 | 505 | goto exit; |
| 506 | 506 | |
| 507 | + first = dx_buff; | |
| 507 | 508 | dx_buff->len_pkt = skb->len; |
| 508 | 509 | dx_buff->is_sop = 1U; |
| 509 | 510 | dx_buff->is_mapped = 1U; |
| @@ -532,40 +533,46 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, · 22 unmodified lines | ||
| 532 | 533 | |
| 533 | 534 | for (; nr_frags--; ++frag_count) { |
| 534 | 535 | unsigned int frag_len = 0U; |
| 536 | + unsigned int buff_offset = 0U; | |
| 537 | + unsigned int buff_size = 0U; | |
| 535 | 538 | dma_addr_t frag_pa; |
| 536 | 539 | skb_frag_t *frag = &skb_shinfo(skb)->frags[frag_count]; |
| 537 | 540 | |
| 538 | 541 | frag_len = skb_frag_size(frag); |
| 539 | − frag_pa = skb_frag_dma_map(aq_nic_get_dev(self), frag, 0, | |
| 540 | − frag_len, DMA_TO_DEVICE); | |
| 541 | 542 | |
| 542 | − if (unlikely(dma_mapping_error(aq_nic_get_dev(self), frag_pa))) | |
| 543 | − goto mapping_error; | |
| 543 | + while (frag_len) { | |
| 544 | + if (frag_len > AQ_CFG_TX_FRAME_MAX) | |
| 545 | + buff_size = AQ_CFG_TX_FRAME_MAX; | |
| 546 | + else | |
| 547 | + buff_size = frag_len; | |
| 548 | + | |
| 549 | + frag_pa = skb_frag_dma_map(aq_nic_get_dev(self), | |
| 550 | + frag, | |
| 551 | + buff_offset, | |
| 552 | + buff_size, | |
| 553 | + DMA_TO_DEVICE); | |
| 554 | + | |
| 555 | + if (unlikely(dma_mapping_error(aq_nic_get_dev(self), | |
| 556 | + frag_pa))) | |
| 557 | + goto mapping_error; | |
| 544 | 558 | |
| 545 | − while (frag_len > AQ_CFG_TX_FRAME_MAX) { | |
| 546 | 559 | dx = aq_ring_next_dx(ring, dx); |
| 547 | 560 | dx_buff = &ring->buff_ring[dx]; |
| 548 | 561 | |
| 549 | 562 | dx_buff->flags = 0U; |
| 550 | − dx_buff->len = AQ_CFG_TX_FRAME_MAX; | |
| 563 | + dx_buff->len = buff_size; | |
| 551 | 564 | dx_buff->pa = frag_pa; |
| 552 | 565 | dx_buff->is_mapped = 1U; |
| 566 | + dx_buff->eop_index = 0xffffU; | |
| 567 | + | |
| 568 | + frag_len -= buff_size; | |
| 569 | + buff_offset += buff_size; | |
| 553 | 570 | |
| 554 | − frag_len -= AQ_CFG_TX_FRAME_MAX; | |
| 555 | − frag_pa += AQ_CFG_TX_FRAME_MAX; | |
| 556 | 571 | ++ret; |
| 557 | 572 | } |
| 558 | − | |
| 559 | − dx = aq_ring_next_dx(ring, dx); | |
| 560 | − dx_buff = &ring->buff_ring[dx]; | |
| 561 | − | |
| 562 | − dx_buff->flags = 0U; | |
| 563 | − dx_buff->len = frag_len; | |
| 564 | − dx_buff->pa = frag_pa; | |
| 565 | − dx_buff->is_mapped = 1U; | |
| 566 | − ++ret; | |
| 567 | 573 | } |
| 568 | 574 | |
| 575 | + first->eop_index = dx; | |
| 569 | 576 | dx_buff->is_eop = 1U; |
| 570 | 577 | dx_buff->skb = skb; |
| 571 | 578 | goto exit; |
| @@ -602,7 +609,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) · 30 unmodified lines | ||
| 602 | 609 | unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs; |
| 603 | 610 | unsigned int tc = 0U; |
| 604 | 611 | int err = NETDEV_TX_OK; |
| 605 | − bool is_nic_in_bad_state; | |
| 606 | 612 | |
| 607 | 613 | frags = skb_shinfo(skb)->nr_frags + 1; |
| 608 | 614 | |
| @@ -613,13 +619,10 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) · 4 unmodified lines | ||
| 613 | 619 | goto err_exit; |
| 614 | 620 | } |
| 615 | 621 | |
| 616 | − is_nic_in_bad_state = aq_utils_obj_test(&self->header.flags, | |
| 617 | − AQ_NIC_FLAGS_IS_NOT_TX_READY) || | |
| 618 | − (aq_ring_avail_dx(ring) < | |
| 619 | − AQ_CFG_SKB_FRAGS_MAX); | |
| 622 | + aq_ring_update_queue_state(ring); | |
| 620 | 623 | |
| 621 | − if (is_nic_in_bad_state) { | |
| 622 | − aq_nic_ndev_queue_stop(self, ring->idx); | |
| 624 | + /* Above status update may stop the queue. Check this. */ | |
| 625 | + if (__netif_subqueue_stopped(self->ndev, ring->idx)) { | |
| 623 | 626 | err = NETDEV_TX_BUSY; |
| 624 | 627 | goto err_exit; |
| 625 | 628 | } |
| @@ -631,9 +634,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) · 5 unmodified lines | ||
| 631 | 634 | ring, |
| 632 | 635 | frags); |
| 633 | 636 | if (err >= 0) { |
| 634 | − if (aq_ring_avail_dx(ring) < AQ_CFG_SKB_FRAGS_MAX + 1) | |
| 635 | − aq_nic_ndev_queue_stop(self, ring->idx); | |
| 636 | − | |
| 637 | 637 | ++ring->stats.tx.packets; |
| 638 | 638 | ring->stats.tx.bytes += skb->len; |
| 639 | 639 | } |
| @@ -693,16 +693,9 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) · 53 unmodified lines | ||
| 693 | 693 | |
| 694 | 694 | int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu) |
| 695 | 695 | { |
| 696 | − int err = 0; | |
| 697 | − | |
| 698 | − if (new_mtu > self->aq_hw_caps.mtu) { | |
| 699 | − err = -EINVAL; | |
| 700 | − goto err_exit; | |
| 701 | − } | |
| 702 | 696 | self->aq_nic_cfg.mtu = new_mtu; |
| 703 | 697 | |
| 704 | −err_exit: | |
| 705 | − return err; | |
| 698 | + return 0; | |
| 706 | 699 | } |
| 707 | 700 | |
| 708 | 701 | int aq_nic_set_mac(struct aq_nic_s *self, struct net_device *ndev) |
| @@ -905,9 +898,7 @@ int aq_nic_stop(struct aq_nic_s *self) · 196 unmodified lines | ||
| 905 | 898 | struct aq_vec_s *aq_vec = NULL; |
| 906 | 899 | unsigned int i = 0U; |
| 907 | 900 | |
| 908 | − for (i = 0U, aq_vec = self->aq_vec[0]; | |
| 909 | − self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) | |
| 910 | − aq_nic_ndev_queue_stop(self, i); | |
| 901 | + netif_tx_disable(self->ndev); | |
| 911 | 902 | |
| 912 | 903 | del_timer_sync(&self->service_timer); |
| 913 | 904 | |
| @@ -83,8 +83,6 @@ struct net_device *aq_nic_get_ndev(struct aq_nic_s *self); · 82 unmodified lines | ||
| 83 | 83 | int aq_nic_init(struct aq_nic_s *self); |
| 84 | 84 | int aq_nic_cfg_start(struct aq_nic_s *self); |
| 85 | 85 | int aq_nic_ndev_register(struct aq_nic_s *self); |
| 86 | −void aq_nic_ndev_queue_start(struct aq_nic_s *self, unsigned int idx); | |
| 87 | −void aq_nic_ndev_queue_stop(struct aq_nic_s *self, unsigned int idx); | |
| 88 | 86 | void aq_nic_ndev_free(struct aq_nic_s *self); |
| 89 | 87 | int aq_nic_start(struct aq_nic_s *self); |
| 90 | 88 | int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb); |
| @@ -104,6 +104,38 @@ int aq_ring_init(struct aq_ring_s *self) · 103 unmodified lines | ||
| 104 | 104 | return 0; |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | +static inline bool aq_ring_dx_in_range(unsigned int h, unsigned int i, | |
| 108 | + unsigned int t) | |
| 109 | +{ | |
| 110 | + return (h < t) ? ((h < i) && (i < t)) : ((h < i) || (i < t)); | |
| 111 | +} | |
| 112 | + | |
| 113 | +void aq_ring_update_queue_state(struct aq_ring_s *ring) | |
| 114 | +{ | |
| 115 | + if (aq_ring_avail_dx(ring) <= AQ_CFG_SKB_FRAGS_MAX) | |
| 116 | + aq_ring_queue_stop(ring); | |
| 117 | + else if (aq_ring_avail_dx(ring) > AQ_CFG_RESTART_DESC_THRES) | |
| 118 | + aq_ring_queue_wake(ring); | |
| 119 | +} | |
| 120 | + | |
| 121 | +void aq_ring_queue_wake(struct aq_ring_s *ring) | |
| 122 | +{ | |
| 123 | + struct net_device *ndev = aq_nic_get_ndev(ring->aq_nic); | |
| 124 | + | |
| 125 | + if (__netif_subqueue_stopped(ndev, ring->idx)) { | |
| 126 | + netif_wake_subqueue(ndev, ring->idx); | |
| 127 | + ring->stats.tx.queue_restarts++; | |
| 128 | + } | |
| 129 | +} | |
| 130 | + | |
| 131 | +void aq_ring_queue_stop(struct aq_ring_s *ring) | |
| 132 | +{ | |
| 133 | + struct net_device *ndev = aq_nic_get_ndev(ring->aq_nic); | |
| 134 | + | |
| 135 | + if (!__netif_subqueue_stopped(ndev, ring->idx)) | |
| 136 | + netif_stop_subqueue(ndev, ring->idx); | |
| 137 | +} | |
| 138 | + | |
| 107 | 139 | void aq_ring_tx_clean(struct aq_ring_s *self) |
| 108 | 140 | { |
| 109 | 141 | struct device *dev = aq_nic_get_dev(self->aq_nic); |
| @@ -113,23 +145,28 @@ void aq_ring_tx_clean(struct aq_ring_s *self) · 3 unmodified lines | ||
| 113 | 145 | struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; |
| 114 | 146 | |
| 115 | 147 | if (likely(buff->is_mapped)) { |
| 116 | − if (unlikely(buff->is_sop)) | |
| 148 | + if (unlikely(buff->is_sop)) { | |
| 149 | + if (!buff->is_eop && | |
| 150 | + buff->eop_index != 0xffffU && | |
| 151 | + (!aq_ring_dx_in_range(self->sw_head, | |
| 152 | + buff->eop_index, | |
| 153 | + self->hw_head))) | |
| 154 | + break; | |
| 155 | + | |
| 117 | 156 | dma_unmap_single(dev, buff->pa, buff->len, |
| 118 | 157 | DMA_TO_DEVICE); |
| 119 | − else | |
| 158 | + } else { | |
| 120 | 159 | dma_unmap_page(dev, buff->pa, buff->len, |
| 121 | 160 | DMA_TO_DEVICE); |
| 161 | + } | |
| 122 | 162 | } |
| 123 | 163 | |
| 124 | 164 | if (unlikely(buff->is_eop)) |
| 125 | 165 | dev_kfree_skb_any(buff->skb); |
| 126 | − } | |
| 127 | −} | |
| 128 | 166 | |
| 129 | −static inline unsigned int aq_ring_dx_in_range(unsigned int h, unsigned int i, | |
| 130 | − unsigned int t) | |
| 131 | −{ | |
| 132 | − return (h < t) ? ((h < i) && (i < t)) : ((h < i) || (i < t)); | |
| 167 | + buff->pa = 0U; | |
| 168 | + buff->eop_index = 0xffffU; | |
| 169 | + } | |
| 133 | 170 | } |
| 134 | 171 | |
| 135 | 172 | #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) |
| @@ -65,7 +65,7 @@ struct __packed aq_ring_buff_s { · 64 unmodified lines | ||
| 65 | 65 | }; |
| 66 | 66 | union { |
| 67 | 67 | struct { |
| 68 | − u32 len:16; | |
| 68 | + u16 len; | |
| 69 | 69 | u32 is_ip_cso:1; |
| 70 | 70 | u32 is_udp_cso:1; |
| 71 | 71 | u32 is_tcp_cso:1; |
| @@ -77,8 +77,10 @@ struct __packed aq_ring_buff_s { · 5 unmodified lines | ||
| 77 | 77 | u32 is_cleaned:1; |
| 78 | 78 | u32 is_error:1; |
| 79 | 79 | u32 rsvd3:6; |
| 80 | + u16 eop_index; | |
| 81 | + u16 rsvd4; | |
| 80 | 82 | }; |
| 81 | − u32 flags; | |
| 83 | + u64 flags; | |
| 82 | 84 | }; |
| 83 | 85 | }; |
| 84 | 86 | |
| @@ -94,6 +96,7 @@ struct aq_ring_stats_tx_s { · 9 unmodified lines | ||
| 94 | 96 | u64 errors; |
| 95 | 97 | u64 packets; |
| 96 | 98 | u64 bytes; |
| 99 | + u64 queue_restarts; | |
| 97 | 100 | }; |
| 98 | 101 | |
| 99 | 102 | union aq_ring_stats_s { |
| @@ -147,6 +150,9 @@ struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, · 47 unmodified lines | ||
| 147 | 150 | int aq_ring_init(struct aq_ring_s *self); |
| 148 | 151 | void aq_ring_rx_deinit(struct aq_ring_s *self); |
| 149 | 152 | void aq_ring_free(struct aq_ring_s *self); |
| 153 | +void aq_ring_update_queue_state(struct aq_ring_s *ring); | |
| 154 | +void aq_ring_queue_wake(struct aq_ring_s *ring); | |
| 155 | +void aq_ring_queue_stop(struct aq_ring_s *ring); | |
| 150 | 156 | void aq_ring_tx_clean(struct aq_ring_s *self); |
| 151 | 157 | int aq_ring_rx_clean(struct aq_ring_s *self, |
| 152 | 158 | struct napi_struct *napi, |
| @@ -59,12 +59,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget) · 58 unmodified lines | ||
| 59 | 59 | if (ring[AQ_VEC_TX_ID].sw_head != |
| 60 | 60 | ring[AQ_VEC_TX_ID].hw_head) { |
| 61 | 61 | aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]); |
| 62 | − | |
| 63 | − if (aq_ring_avail_dx(&ring[AQ_VEC_TX_ID]) > | |
| 64 | − AQ_CFG_SKB_FRAGS_MAX) { | |
| 65 | − aq_nic_ndev_queue_start(self->aq_nic, | |
| 66 | − ring[AQ_VEC_TX_ID].idx); | |
| 67 | − } | |
| 62 | + aq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]); | |
| 68 | 63 | was_tx_cleaned = true; |
| 69 | 64 | } |
| 70 | 65 | |
| @@ -364,6 +359,7 @@ void aq_vec_add_stats(struct aq_vec_s *self, · 293 unmodified lines | ||
| 364 | 359 | stats_tx->packets += tx->packets; |
| 365 | 360 | stats_tx->bytes += tx->bytes; |
| 366 | 361 | stats_tx->errors += tx->errors; |
| 362 | + stats_tx->queue_restarts += tx->queue_restarts; | |
| 367 | 363 | } |
| 368 | 364 | } |
| 369 | 365 | |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | #include "../aq_common.h" |
| 18 | 18 | |
| 19 | −#define HW_ATL_B0_MTU_JUMBO (16000U) | |
| 19 | +#define HW_ATL_B0_MTU_JUMBO 16352U | |
| 20 | 20 | #define HW_ATL_B0_MTU 1514U |
| 21 | 21 | |
| 22 | 22 | #define HW_ATL_B0_TX_RINGS 4U |
| @@ -351,8 +351,7 @@ int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self) · 350 unmodified lines | ||
| 351 | 351 | break; |
| 352 | 352 | |
| 353 | 353 | default: |
| 354 | − link_status->mbps = 0U; | |
| 355 | − break; | |
| 354 | + return -EBUSY; | |
| 356 | 355 | } |
| 357 | 356 | } |
| 358 | 357 | |
| @@ -432,6 +432,27 @@ static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv) · 431 unmodified lines | ||
| 432 | 432 | netif_dbg(priv, hw, priv->netdev, "updated MIB counters\n"); |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | +static void bcm_sysport_update_tx_stats(struct bcm_sysport_priv *priv, | |
| 436 | + u64 *tx_bytes, u64 *tx_packets) | |
| 437 | +{ | |
| 438 | + struct bcm_sysport_tx_ring *ring; | |
| 439 | + u64 bytes = 0, packets = 0; | |
| 440 | + unsigned int start; | |
| 441 | + unsigned int q; | |
| 442 | + | |
| 443 | + for (q = 0; q < priv->netdev->num_tx_queues; q++) { | |
| 444 | + ring = &priv->tx_rings[q]; | |
| 445 | + do { | |
| 446 | + start = u64_stats_fetch_begin_irq(&priv->syncp); | |
| 447 | + bytes = ring->bytes; | |
| 448 | + packets = ring->packets; | |
| 449 | + } while (u64_stats_fetch_retry_irq(&priv->syncp, start)); | |
| 450 | + | |
| 451 | + *tx_bytes += bytes; | |
| 452 | + *tx_packets += packets; | |
| 453 | + } | |
| 454 | +} | |
| 455 | + | |
| 435 | 456 | static void bcm_sysport_get_stats(struct net_device *dev, |
| 436 | 457 | struct ethtool_stats *stats, u64 *data) |
| 437 | 458 | { |
| @@ -439,11 +460,16 @@ static void bcm_sysport_get_stats(struct net_device *dev, · 1 unmodified line | ||
| 439 | 460 | struct bcm_sysport_stats64 *stats64 = &priv->stats64; |
| 440 | 461 | struct u64_stats_sync *syncp = &priv->syncp; |
| 441 | 462 | struct bcm_sysport_tx_ring *ring; |
| 463 | + u64 tx_bytes = 0, tx_packets = 0; | |
| 442 | 464 | unsigned int start; |
| 443 | 465 | int i, j; |
| 444 | 466 | |
| 445 | − if (netif_running(dev)) | |
| 467 | + if (netif_running(dev)) { | |
| 446 | 468 | bcm_sysport_update_mib_counters(priv); |
| 469 | + bcm_sysport_update_tx_stats(priv, &tx_bytes, &tx_packets); | |
| 470 | + stats64->tx_bytes = tx_bytes; | |
| 471 | + stats64->tx_packets = tx_packets; | |
| 472 | + } | |
| 447 | 473 | |
| 448 | 474 | for (i = 0, j = 0; i < BCM_SYSPORT_STATS_LEN; i++) { |
| 449 | 475 | const struct bcm_sysport_stats *s; |
| @@ -461,12 +487,13 @@ static void bcm_sysport_get_stats(struct net_device *dev, · 11 unmodified lines | ||
| 461 | 487 | continue; |
| 462 | 488 | p += s->stat_offset; |
| 463 | 489 | |
| 464 | − if (s->stat_sizeof == sizeof(u64)) | |
| 490 | + if (s->stat_sizeof == sizeof(u64) && | |
| 491 | + s->type == BCM_SYSPORT_STAT_NETDEV64) { | |
| 465 | 492 | do { |
| 466 | 493 | start = u64_stats_fetch_begin_irq(syncp); |
| 467 | 494 | data[i] = *(u64 *)p; |
| 468 | 495 | } while (u64_stats_fetch_retry_irq(syncp, start)); |
| 469 | − else | |
| 496 | + } else | |
| 470 | 497 | data[i] = *(u32 *)p; |
| 471 | 498 | j++; |
| 472 | 499 | } |
| @@ -1716,27 +1743,12 @@ static void bcm_sysport_get_stats64(struct net_device *dev, · 1243 unmodified lines | ||
| 1716 | 1743 | { |
| 1717 | 1744 | struct bcm_sysport_priv *priv = netdev_priv(dev); |
| 1718 | 1745 | struct bcm_sysport_stats64 *stats64 = &priv->stats64; |
| 1719 | − struct bcm_sysport_tx_ring *ring; | |
| 1720 | − u64 tx_packets = 0, tx_bytes = 0; | |
| 1721 | 1746 | unsigned int start; |
| 1722 | − unsigned int q; | |
| 1723 | 1747 | |
| 1724 | 1748 | netdev_stats_to_stats64(stats, &dev->stats); |
| 1725 | 1749 | |
| 1726 | − for (q = 0; q < dev->num_tx_queues; q++) { | |
| 1727 | − ring = &priv->tx_rings[q]; | |
| 1728 | − do { | |
| 1729 | − start = u64_stats_fetch_begin_irq(&priv->syncp); | |
| 1730 | − tx_bytes = ring->bytes; | |
| 1731 | − tx_packets = ring->packets; | |
| 1732 | − } while (u64_stats_fetch_retry_irq(&priv->syncp, start)); | |
| 1733 | − | |
| 1734 | − stats->tx_bytes += tx_bytes; | |
| 1735 | − stats->tx_packets += tx_packets; | |
| 1736 | − } | |
| 1737 | − | |
| 1738 | − stats64->tx_bytes = stats->tx_bytes; | |
| 1739 | − stats64->tx_packets = stats->tx_packets; | |
| 1750 | + bcm_sysport_update_tx_stats(priv, &stats->tx_bytes, | |
| 1751 | + &stats->tx_packets); | |
| 1740 | 1752 | |
| 1741 | 1753 | do { |
| 1742 | 1754 | start = u64_stats_fetch_begin_irq(&priv->syncp); |
| @@ -750,6 +750,10 @@ int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, · 749 unmodified lines | ||
| 750 | 750 | { |
| 751 | 751 | int rc = 0; |
| 752 | 752 | |
| 753 | + if (!is_classid_clsact_ingress(cls_flower->common.classid) || | |
| 754 | + cls_flower->common.chain_index) | |
| 755 | + return -EOPNOTSUPP; | |
| 756 | + | |
| 753 | 757 | switch (cls_flower->command) { |
| 754 | 758 | case TC_CLSFLOWER_REPLACE: |
| 755 | 759 | rc = bnxt_tc_add_flow(bp, src_fid, cls_flower); |
| @@ -1278,7 +1278,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) · 1277 unmodified lines | ||
| 1278 | 1278 | |
| 1279 | 1279 | ret = cnic_alloc_dma(dev, kwq_16_dma, pages, 0); |
| 1280 | 1280 | if (ret) |
| 1281 | − return -ENOMEM; | |
| 1281 | + goto error; | |
| 1282 | 1282 | |
| 1283 | 1283 | n = CNIC_PAGE_SIZE / CNIC_KWQ16_DATA_SIZE; |
| 1284 | 1284 | for (i = 0, j = 0; i < cp->max_cid_space; i++) { |
| @@ -374,8 +374,8 @@ struct bufdesc_ex { · 373 unmodified lines | ||
| 374 | 374 | #define FEC_ENET_TS_AVAIL ((uint)0x00010000) |
| 375 | 375 | #define FEC_ENET_TS_TIMER ((uint)0x00008000) |
| 376 | 376 | |
| 377 | −#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII | FEC_ENET_TS_TIMER) | |
| 378 | −#define FEC_NAPI_IMASK (FEC_ENET_MII | FEC_ENET_TS_TIMER) | |
| 377 | +#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII) | |
| 378 | +#define FEC_NAPI_IMASK FEC_ENET_MII | |
| 379 | 379 | #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF)) |
| 380 | 380 | |
| 381 | 381 | /* ENET interrupt coalescing macro define */ |
| @@ -1559,14 +1559,14 @@ fec_enet_collect_events(struct fec_enet_private *fep, uint int_events) · 1558 unmodified lines | ||
| 1559 | 1559 | if (int_events == 0) |
| 1560 | 1560 | return false; |
| 1561 | 1561 | |
| 1562 | − if (int_events & FEC_ENET_RXF) | |
| 1562 | + if (int_events & FEC_ENET_RXF_0) | |
| 1563 | 1563 | fep->work_rx |= (1 << 2); |
| 1564 | 1564 | if (int_events & FEC_ENET_RXF_1) |
| 1565 | 1565 | fep->work_rx |= (1 << 0); |
| 1566 | 1566 | if (int_events & FEC_ENET_RXF_2) |
| 1567 | 1567 | fep->work_rx |= (1 << 1); |
| 1568 | 1568 | |
| 1569 | − if (int_events & FEC_ENET_TXF) | |
| 1569 | + if (int_events & FEC_ENET_TXF_0) | |
| 1570 | 1570 | fep->work_tx |= (1 << 2); |
| 1571 | 1571 | if (int_events & FEC_ENET_TXF_1) |
| 1572 | 1572 | fep->work_tx |= (1 << 0); |
| @@ -1604,8 +1604,8 @@ fec_enet_interrupt(int irq, void *dev_id) · 31 unmodified lines | ||
| 1604 | 1604 | } |
| 1605 | 1605 | |
| 1606 | 1606 | if (fep->ptp_clock) |
| 1607 | − fec_ptp_check_pps_event(fep); | |
| 1608 | − | |
| 1607 | + if (fec_ptp_check_pps_event(fep)) | |
| 1608 | + ret = IRQ_HANDLED; | |
| 1609 | 1609 | return ret; |
| 1610 | 1610 | } |
| 1611 | 1611 | |
| @@ -37,20 +37,15 @@ static bool hnae3_client_match(enum hnae3_client_type client_type, · 36 unmodified lines | ||
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | static int hnae3_match_n_instantiate(struct hnae3_client *client, |
| 40 | − struct hnae3_ae_dev *ae_dev, | |
| 41 | − bool is_reg, bool *matched) | |
| 40 | + struct hnae3_ae_dev *ae_dev, bool is_reg) | |
| 42 | 41 | { |
| 43 | 42 | int ret; |
| 44 | 43 | |
| 45 | − *matched = false; | |
| 46 | − | |
| 47 | 44 | /* check if this client matches the type of ae_dev */ |
| 48 | 45 | if (!(hnae3_client_match(client->type, ae_dev->dev_type) && |
| 49 | 46 | hnae_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))) { |
| 50 | 47 | return 0; |
| 51 | 48 | } |
| 52 | − /* there is a match of client and dev */ | |
| 53 | − *matched = true; | |
| 54 | 49 | |
| 55 | 50 | /* now, (un-)instantiate client by calling lower layer */ |
| 56 | 51 | if (is_reg) { |
| @@ -69,7 +64,6 @@ int hnae3_register_client(struct hnae3_client *client) · 12 unmodified lines | ||
| 69 | 64 | { |
| 70 | 65 | struct hnae3_client *client_tmp; |
| 71 | 66 | struct hnae3_ae_dev *ae_dev; |
| 72 | − bool matched; | |
| 73 | 67 | int ret = 0; |
| 74 | 68 | |
| 75 | 69 | mutex_lock(&hnae3_common_lock); |
| @@ -86,7 +80,7 @@ int hnae3_register_client(struct hnae3_client *client) · 10 unmodified lines | ||
| 86 | 80 | /* if the client could not be initialized on current port, for |
| 87 | 81 | * any error reasons, move on to next available port |
| 88 | 82 | */ |
| 89 | − ret = hnae3_match_n_instantiate(client, ae_dev, true, &matched); | |
| 83 | + ret = hnae3_match_n_instantiate(client, ae_dev, true); | |
| 90 | 84 | if (ret) |
| 91 | 85 | dev_err(&ae_dev->pdev->dev, |
| 92 | 86 | "match and instantiation failed for port\n"); |
| @@ -102,12 +96,11 @@ EXPORT_SYMBOL(hnae3_register_client); · 9 unmodified lines | ||
| 102 | 96 | void hnae3_unregister_client(struct hnae3_client *client) |
| 103 | 97 | { |
| 104 | 98 | struct hnae3_ae_dev *ae_dev; |
| 105 | − bool matched; | |
| 106 | 99 | |
| 107 | 100 | mutex_lock(&hnae3_common_lock); |
| 108 | 101 | /* un-initialize the client on every matched port */ |
| 109 | 102 | list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) { |
| 110 | − hnae3_match_n_instantiate(client, ae_dev, false, &matched); | |
| 103 | + hnae3_match_n_instantiate(client, ae_dev, false); | |
| 111 | 104 | } |
| 112 | 105 | |
| 113 | 106 | list_del(&client->node); |
| @@ -124,7 +117,6 @@ int hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo) · 10 unmodified lines | ||
| 124 | 117 | const struct pci_device_id *id; |
| 125 | 118 | struct hnae3_ae_dev *ae_dev; |
| 126 | 119 | struct hnae3_client *client; |
| 127 | − bool matched; | |
| 128 | 120 | int ret = 0; |
| 129 | 121 | |
| 130 | 122 | mutex_lock(&hnae3_common_lock); |
| @@ -151,13 +143,10 @@ int hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo) · 20 unmodified lines | ||
| 151 | 143 | * initialize the figure out client instance |
| 152 | 144 | */ |
| 153 | 145 | list_for_each_entry(client, &hnae3_client_list, node) { |
| 154 | − ret = hnae3_match_n_instantiate(client, ae_dev, true, | |
| 155 | − &matched); | |
| 146 | + ret = hnae3_match_n_instantiate(client, ae_dev, true); | |
| 156 | 147 | if (ret) |
| 157 | 148 | dev_err(&ae_dev->pdev->dev, |
| 158 | 149 | "match and instantiation failed\n"); |
| 159 | − if (matched) | |
| 160 | − break; | |
| 161 | 150 | } |
| 162 | 151 | } |
| 163 | 152 | |
| @@ -175,7 +164,6 @@ void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo) · 11 unmodified lines | ||
| 175 | 164 | const struct pci_device_id *id; |
| 176 | 165 | struct hnae3_ae_dev *ae_dev; |
| 177 | 166 | struct hnae3_client *client; |
| 178 | − bool matched; | |
| 179 | 167 | |
| 180 | 168 | mutex_lock(&hnae3_common_lock); |
| 181 | 169 | /* Check if there are matched ae_dev */ |
| @@ -187,12 +175,8 @@ void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo) · 5 unmodified lines | ||
| 187 | 175 | /* check the client list for the match with this ae_dev type and |
| 188 | 176 | * un-initialize the figure out client instance |
| 189 | 177 | */ |
| 190 | − list_for_each_entry(client, &hnae3_client_list, node) { | |
| 191 | − hnae3_match_n_instantiate(client, ae_dev, false, | |
| 192 | − &matched); | |
| 193 | − if (matched) | |
| 194 | − break; | |
| 195 | − } | |
| 178 | + list_for_each_entry(client, &hnae3_client_list, node) | |
| 179 | + hnae3_match_n_instantiate(client, ae_dev, false); | |
| 196 | 180 | |
| 197 | 181 | ae_algo->ops->uninit_ae_dev(ae_dev); |
| 198 | 182 | hnae_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0); |
| @@ -212,7 +196,6 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) · 13 unmodified lines | ||
| 212 | 196 | const struct pci_device_id *id; |
| 213 | 197 | struct hnae3_ae_algo *ae_algo; |
| 214 | 198 | struct hnae3_client *client; |
| 215 | − bool matched; | |
| 216 | 199 | int ret = 0; |
| 217 | 200 | |
| 218 | 201 | mutex_lock(&hnae3_common_lock); |
| @@ -246,13 +229,10 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) · 27 unmodified lines | ||
| 246 | 229 | * initialize the figure out client instance |
| 247 | 230 | */ |
| 248 | 231 | list_for_each_entry(client, &hnae3_client_list, node) { |
| 249 | − ret = hnae3_match_n_instantiate(client, ae_dev, true, | |
| 250 | − &matched); | |
| 232 | + ret = hnae3_match_n_instantiate(client, ae_dev, true); | |
| 251 | 233 | if (ret) |
| 252 | 234 | dev_err(&ae_dev->pdev->dev, |
| 253 | 235 | "match and instantiation failed\n"); |
| 254 | − if (matched) | |
| 255 | − break; | |
| 256 | 236 | } |
| 257 | 237 | |
| 258 | 238 | out_err: |
| @@ -270,7 +250,6 @@ void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev) · 11 unmodified lines | ||
| 270 | 250 | const struct pci_device_id *id; |
| 271 | 251 | struct hnae3_ae_algo *ae_algo; |
| 272 | 252 | struct hnae3_client *client; |
| 273 | − bool matched; | |
| 274 | 253 | |
| 275 | 254 | mutex_lock(&hnae3_common_lock); |
| 276 | 255 | /* Check if there are matched ae_algo */ |
| @@ -279,12 +258,8 @@ void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev) · 2 unmodified lines | ||
| 279 | 258 | if (!id) |
| 280 | 259 | continue; |
| 281 | 260 | |
| 282 | − list_for_each_entry(client, &hnae3_client_list, node) { | |
| 283 | − hnae3_match_n_instantiate(client, ae_dev, false, | |
| 284 | − &matched); | |
| 285 | − if (matched) | |
| 286 | − break; | |
| 287 | − } | |
| 261 | + list_for_each_entry(client, &hnae3_client_list, node) | |
| 262 | + hnae3_match_n_instantiate(client, ae_dev, false); | |
| 288 | 263 | |
| 289 | 264 | ae_algo->ops->uninit_ae_dev(ae_dev); |
| 290 | 265 | hnae_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0); |
| @@ -49,7 +49,17 @@ · 48 unmodified lines | ||
| 49 | 49 | #define HNAE3_CLASS_NAME_SIZE 16 |
| 50 | 50 | |
| 51 | 51 | #define HNAE3_DEV_INITED_B 0x0 |
| 52 | −#define HNAE_DEV_SUPPORT_ROCE_B 0x1 | |
| 52 | +#define HNAE3_DEV_SUPPORT_ROCE_B 0x1 | |
| 53 | +#define HNAE3_DEV_SUPPORT_DCB_B 0x2 | |
| 54 | + | |
| 55 | +#define HNAE3_DEV_SUPPORT_ROCE_DCB_BITS (BIT(HNAE3_DEV_SUPPORT_DCB_B) |\ | |
| 56 | + BIT(HNAE3_DEV_SUPPORT_ROCE_B)) | |
| 57 | + | |
| 58 | +#define hnae3_dev_roce_supported(hdev) \ | |
| 59 | + hnae_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B) | |
| 60 | + | |
| 61 | +#define hnae3_dev_dcb_supported(hdev) \ | |
| 62 | + hnae_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_DCB_B) | |
| 53 | 63 | |
| 54 | 64 | #define ring_ptr_move_fw(ring, p) \ |
| 55 | 65 | ((ring)->p = ((ring)->p + 1) % (ring)->desc_num) |
| @@ -366,12 +376,12 @@ struct hnae3_ae_algo { · 310 unmodified lines | ||
| 366 | 376 | struct hnae3_tc_info { |
| 367 | 377 | u16 tqp_offset; /* TQP offset from base TQP */ |
| 368 | 378 | u16 tqp_count; /* Total TQPs */ |
| 369 | − u8 up; /* user priority */ | |
| 370 | 379 | u8 tc; /* TC index */ |
| 371 | 380 | bool enable; /* If this TC is enable or not */ |
| 372 | 381 | }; |
| 373 | 382 | |
| 374 | 383 | #define HNAE3_MAX_TC 8 |
| 384 | +#define HNAE3_MAX_USER_PRIO 8 | |
| 375 | 385 | struct hnae3_knic_private_info { |
| 376 | 386 | struct net_device *netdev; /* Set by KNIC client when init instance */ |
| 377 | 387 | u16 rss_size; /* Allocated RSS queues */ |
| @@ -379,6 +389,7 @@ struct hnae3_knic_private_info { · 1 unmodified line | ||
| 379 | 389 | u16 num_desc; |
| 380 | 390 | |
| 381 | 391 | u8 num_tc; /* Total number of enabled TCs */ |
| 392 | + u8 prio_tc[HNAE3_MAX_USER_PRIO]; /* TC indexed by prio */ | |
| 382 | 393 | struct hnae3_tc_info tc_info[HNAE3_MAX_TC]; /* Idx of array is HW TC */ |
| 383 | 394 | |
| 384 | 395 | u16 num_tqps; /* total number of TQPs in this handle */ |
| @@ -238,7 +238,7 @@ struct hclge_tqp_map { · 237 unmodified lines | ||
| 238 | 238 | u8 rsv[18]; |
| 239 | 239 | }; |
| 240 | 240 | |
| 241 | −#define HCLGE_VECTOR_ELEMENTS_PER_CMD 11 | |
| 241 | +#define HCLGE_VECTOR_ELEMENTS_PER_CMD 10 | |
| 242 | 242 | |
| 243 | 243 | enum hclge_int_type { |
| 244 | 244 | HCLGE_INT_TX, |
| @@ -252,8 +252,12 @@ struct hclge_ctrl_vector_chain { · 7 unmodified lines | ||
| 252 | 252 | #define HCLGE_INT_TYPE_S 0 |
| 253 | 253 | #define HCLGE_INT_TYPE_M 0x3 |
| 254 | 254 | #define HCLGE_TQP_ID_S 2 |
| 255 | −#define HCLGE_TQP_ID_M (0x3fff << HCLGE_TQP_ID_S) | |
| 255 | +#define HCLGE_TQP_ID_M (0x7ff << HCLGE_TQP_ID_S) | |
| 256 | +#define HCLGE_INT_GL_IDX_S 13 | |
| 257 | +#define HCLGE_INT_GL_IDX_M (0x3 << HCLGE_INT_GL_IDX_S) | |
| 256 | 258 | __le16 tqp_type_and_id[HCLGE_VECTOR_ELEMENTS_PER_CMD]; |
| 259 | + u8 vfid; | |
| 260 | + u8 rsv; | |
| 257 | 261 | }; |
| 258 | 262 | |
| 259 | 263 | #define HCLGE_TC_NUM 8 |
| @@ -266,7 +270,8 @@ struct hclge_tx_buff_alloc { · 6 unmodified lines | ||
| 266 | 270 | |
| 267 | 271 | struct hclge_rx_priv_buff { |
| 268 | 272 | __le16 buf_num[HCLGE_TC_NUM]; |
| 269 | − u8 rsv[8]; | |
| 273 | + __le16 shared_buf; | |
| 274 | + u8 rsv[6]; | |
| 270 | 275 | }; |
| 271 | 276 | |
| 272 | 277 | struct hclge_query_version { |
| @@ -684,6 +689,7 @@ struct hclge_reset_tqp_queue { · 411 unmodified lines | ||
| 684 | 689 | #define HCLGE_DEFAULT_TX_BUF 0x4000 /* 16k bytes */ |
| 685 | 690 | #define HCLGE_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */ |
| 686 | 691 | #define HCLGE_DEFAULT_DV 0xA000 /* 40k byte */ |
| 692 | +#define HCLGE_DEFAULT_NON_DCB_DV 0x7800 /* 30K byte */ | |
| 687 | 693 | |
| 688 | 694 | #define HCLGE_TYPE_CRQ 0 |
| 689 | 695 | #define HCLGE_TYPE_CSQ 1 |
| @@ -46,17 +46,7 @@ static const struct pci_device_id ae_algo_pci_tbl[] = { · 45 unmodified lines | ||
| 46 | 46 | {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), 0}, |
| 47 | 47 | {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), 0}, |
| 48 | 48 | {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), 0}, |
| 49 | − /* Required last entry */ | |
| 50 | − {0, } | |
| 51 | −}; | |
| 52 | − | |
| 53 | −static const struct pci_device_id roce_pci_tbl[] = { | |
| 54 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA), 0}, | |
| 55 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA_MACSEC), 0}, | |
| 56 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), 0}, | |
| 57 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), 0}, | |
| 58 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), 0}, | |
| 59 | − /* Required last entry */ | |
| 49 | + /* required last entry */ | |
| 60 | 50 | {0, } |
| 61 | 51 | }; |
| 62 | 52 | |
| @@ -894,7 +884,7 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev) · 831 unmodified lines | ||
| 894 | 884 | hdev->num_tqps = __le16_to_cpu(req->tqp_num); |
| 895 | 885 | hdev->pkt_buf_size = __le16_to_cpu(req->buf_size) << HCLGE_BUF_UNIT_S; |
| 896 | 886 | |
| 897 | − if (hnae_get_bit(hdev->ae_dev->flag, HNAE_DEV_SUPPORT_ROCE_B)) { | |
| 887 | + if (hnae3_dev_roce_supported(hdev)) { | |
| 898 | 888 | hdev->num_roce_msix = |
| 899 | 889 | hnae_get_field(__le16_to_cpu(req->pf_intr_vector_number), |
| 900 | 890 | HCLGE_PF_VEC_NUM_M, HCLGE_PF_VEC_NUM_S); |
| @@ -1063,9 +1053,9 @@ static int hclge_configure(struct hclge_dev *hdev) · 162 unmodified lines | ||
| 1063 | 1053 | hdev->base_tqp_pid = 0; |
| 1064 | 1054 | hdev->rss_size_max = 1; |
| 1065 | 1055 | hdev->rx_buf_len = cfg.rx_buf_len; |
| 1066 | − for (i = 0; i < ETH_ALEN; i++) | |
| 1067 | − hdev->hw.mac.mac_addr[i] = cfg.mac_addr[i]; | |
| 1056 | + ether_addr_copy(hdev->hw.mac.mac_addr, cfg.mac_addr); | |
| 1068 | 1057 | hdev->hw.mac.media_type = cfg.media_type; |
| 1058 | + hdev->hw.mac.phy_addr = cfg.phy_addr; | |
| 1069 | 1059 | hdev->num_desc = cfg.tqp_desc_num; |
| 1070 | 1060 | hdev->tm_info.num_pg = 1; |
| 1071 | 1061 | hdev->tm_info.num_tc = cfg.tc_num; |
| @@ -1454,7 +1444,11 @@ static bool hclge_is_rx_buf_ok(struct hclge_dev *hdev, u32 rx_all) · 382 unmodified lines | ||
| 1454 | 1444 | tc_num = hclge_get_tc_num(hdev); |
| 1455 | 1445 | pfc_enable_num = hclge_get_pfc_enalbe_num(hdev); |
| 1456 | 1446 | |
| 1457 | − shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_DV; | |
| 1447 | + if (hnae3_dev_dcb_supported(hdev)) | |
| 1448 | + shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_DV; | |
| 1449 | + else | |
| 1450 | + shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_NON_DCB_DV; | |
| 1451 | + | |
| 1458 | 1452 | shared_buf_tc = pfc_enable_num * hdev->mps + |
| 1459 | 1453 | (tc_num - pfc_enable_num) * hdev->mps / 2 + |
| 1460 | 1454 | hdev->mps; |
| @@ -1495,6 +1489,16 @@ int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 tx_size) · 34 unmodified lines | ||
| 1495 | 1489 | struct hclge_priv_buf *priv; |
| 1496 | 1490 | int i; |
| 1497 | 1491 | |
| 1492 | + /* When DCB is not supported, rx private | |
| 1493 | + * buffer is not allocated. | |
| 1494 | + */ | |
| 1495 | + if (!hnae3_dev_dcb_supported(hdev)) { | |
| 1496 | + if (!hclge_is_rx_buf_ok(hdev, rx_all)) | |
| 1497 | + return -ENOMEM; | |
| 1498 | + | |
| 1499 | + return 0; | |
| 1500 | + } | |
| 1501 | + | |
| 1498 | 1502 | /* step 1, try to alloc private buffer for all enabled tc */ |
| 1499 | 1503 | for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { |
| 1500 | 1504 | priv = &hdev->priv_buf[i]; |
| @@ -1510,6 +1514,11 @@ int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 tx_size) · 9 unmodified lines | ||
| 1510 | 1514 | priv->wl.high = 2 * hdev->mps; |
| 1511 | 1515 | priv->buf_size = priv->wl.high; |
| 1512 | 1516 | } |
| 1517 | + } else { | |
| 1518 | + priv->enable = 0; | |
| 1519 | + priv->wl.low = 0; | |
| 1520 | + priv->wl.high = 0; | |
| 1521 | + priv->buf_size = 0; | |
| 1513 | 1522 | } |
| 1514 | 1523 | } |
| 1515 | 1524 | |
| @@ -1522,8 +1531,15 @@ int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 tx_size) · 6 unmodified lines | ||
| 1522 | 1531 | for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { |
| 1523 | 1532 | priv = &hdev->priv_buf[i]; |
| 1524 | 1533 | |
| 1525 | − if (hdev->hw_tc_map & BIT(i)) | |
| 1526 | − priv->enable = 1; | |
| 1534 | + priv->enable = 0; | |
| 1535 | + priv->wl.low = 0; | |
| 1536 | + priv->wl.high = 0; | |
| 1537 | + priv->buf_size = 0; | |
| 1538 | + | |
| 1539 | + if (!(hdev->hw_tc_map & BIT(i))) | |
| 1540 | + continue; | |
| 1541 | + | |
| 1542 | + priv->enable = 1; | |
| 1527 | 1543 | |
| 1528 | 1544 | if (hdev->tm_info.hw_pfc_map & BIT(i)) { |
| 1529 | 1545 | priv->wl.low = 128; |
| @@ -1616,6 +1632,10 @@ static int hclge_rx_priv_buf_alloc(struct hclge_dev *hdev) · 86 unmodified lines | ||
| 1616 | 1632 | cpu_to_le16(true << HCLGE_TC0_PRI_BUF_EN_B); |
| 1617 | 1633 | } |
| 1618 | 1634 | |
| 1635 | + req->shared_buf = | |
| 1636 | + cpu_to_le16((hdev->s_buf.buf_size >> HCLGE_BUF_UNIT_S) | | |
| 1637 | + (1 << HCLGE_TC0_PRI_BUF_EN_B)); | |
| 1638 | + | |
| 1619 | 1639 | ret = hclge_cmd_send(&hdev->hw, &desc, 1); |
| 1620 | 1640 | if (ret) { |
| 1621 | 1641 | dev_err(&hdev->pdev->dev, |
| @@ -1782,18 +1802,22 @@ int hclge_buffer_alloc(struct hclge_dev *hdev) · 160 unmodified lines | ||
| 1782 | 1802 | return ret; |
| 1783 | 1803 | } |
| 1784 | 1804 | |
| 1785 | − ret = hclge_rx_priv_wl_config(hdev); | |
| 1786 | − if (ret) { | |
| 1787 | − dev_err(&hdev->pdev->dev, | |
| 1788 | − "could not configure rx private waterline %d\n", ret); | |
| 1789 | − return ret; | |
| 1790 | − } | |
| 1805 | + if (hnae3_dev_dcb_supported(hdev)) { | |
| 1806 | + ret = hclge_rx_priv_wl_config(hdev); | |
| 1807 | + if (ret) { | |
| 1808 | + dev_err(&hdev->pdev->dev, | |
| 1809 | + "could not configure rx private waterline %d\n", | |
| 1810 | + ret); | |
| 1811 | + return ret; | |
| 1812 | + } | |
| 1791 | 1813 | |
| 1792 | − ret = hclge_common_thrd_config(hdev); | |
| 1793 | − if (ret) { | |
| 1794 | − dev_err(&hdev->pdev->dev, | |
| 1795 | − "could not configure common threshold %d\n", ret); | |
| 1796 | − return ret; | |
| 1814 | + ret = hclge_common_thrd_config(hdev); | |
| 1815 | + if (ret) { | |
| 1816 | + dev_err(&hdev->pdev->dev, | |
| 1817 | + "could not configure common threshold %d\n", | |
| 1818 | + ret); | |
| 1819 | + return ret; | |
| 1820 | + } | |
| 1797 | 1821 | } |
| 1798 | 1822 | |
| 1799 | 1823 | ret = hclge_common_wl_config(hdev); |
| @@ -2582,6 +2606,7 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev) · 782 unmodified lines | ||
| 2582 | 2606 | u16 tc_valid[HCLGE_MAX_TC_NUM]; |
| 2583 | 2607 | u16 tc_size[HCLGE_MAX_TC_NUM]; |
| 2584 | 2608 | u32 *rss_indir = NULL; |
| 2609 | + u16 rss_size = 0, roundup_size; | |
| 2585 | 2610 | const u8 *key; |
| 2586 | 2611 | int i, ret, j; |
| 2587 | 2612 | |
| @@ -2596,7 +2621,13 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev) · 8 unmodified lines | ||
| 2596 | 2621 | for (j = 0; j < hdev->num_vmdq_vport + 1; j++) { |
| 2597 | 2622 | for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++) { |
| 2598 | 2623 | vport[j].rss_indirection_tbl[i] = |
| 2599 | − i % hdev->rss_size_max; | |
| 2624 | + i % vport[j].alloc_rss_size; | |
| 2625 | + | |
| 2626 | + /* vport 0 is for PF */ | |
| 2627 | + if (j != 0) | |
| 2628 | + continue; | |
| 2629 | + | |
| 2630 | + rss_size = vport[j].alloc_rss_size; | |
| 2600 | 2631 | rss_indir[i] = vport[j].rss_indirection_tbl[i]; |
| 2601 | 2632 | } |
| 2602 | 2633 | } |
| @@ -2613,42 +2644,32 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev) · 10 unmodified lines | ||
| 2613 | 2644 | if (ret) |
| 2614 | 2645 | goto err; |
| 2615 | 2646 | |
| 2647 | + /* Each TC have the same queue size, and tc_size set to hardware is | |
| 2648 | + * the log2 of roundup power of two of rss_size, the acutal queue | |
| 2649 | + * size is limited by indirection table. | |
| 2650 | + */ | |
| 2651 | + if (rss_size > HCLGE_RSS_TC_SIZE_7 || rss_size == 0) { | |
| 2652 | + dev_err(&hdev->pdev->dev, | |
| 2653 | + "Configure rss tc size failed, invalid TC_SIZE = %d\n", | |
| 2654 | + rss_size); | |
| 2655 | + ret = -EINVAL; | |
| 2656 | + goto err; | |
| 2657 | + } | |
| 2658 | + | |
| 2659 | + roundup_size = roundup_pow_of_two(rss_size); | |
| 2660 | + roundup_size = ilog2(roundup_size); | |
| 2661 | + | |
| 2616 | 2662 | for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { |
| 2617 | − if (hdev->hw_tc_map & BIT(i)) | |
| 2618 | − tc_valid[i] = 1; | |
| 2619 | − else | |
| 2620 | − tc_valid[i] = 0; | |
| 2663 | + tc_valid[i] = 0; | |
| 2621 | 2664 | |
| 2622 | − switch (hdev->rss_size_max) { | |
| 2623 | − case HCLGE_RSS_TC_SIZE_0: | |
| 2624 | − tc_size[i] = 0; | |
| 2625 | − break; | |
| 2626 | − case HCLGE_RSS_TC_SIZE_1: | |
| 2627 | − tc_size[i] = 1; | |
| 2628 | − break; | |
| 2629 | − case HCLGE_RSS_TC_SIZE_2: | |
| 2630 | − tc_size[i] = 2; | |
| 2631 | − break; | |
| 2632 | − case HCLGE_RSS_TC_SIZE_3: | |
| 2633 | − tc_size[i] = 3; | |
| 2634 | − break; | |
| 2635 | − case HCLGE_RSS_TC_SIZE_4: | |
| 2636 | − tc_size[i] = 4; | |
| 2637 | − break; | |
| 2638 | − case HCLGE_RSS_TC_SIZE_5: | |
| 2639 | − tc_size[i] = 5; | |
| 2640 | − break; | |
| 2641 | − case HCLGE_RSS_TC_SIZE_6: | |
| 2642 | − tc_size[i] = 6; | |
| 2643 | − break; | |
| 2644 | − case HCLGE_RSS_TC_SIZE_7: | |
| 2645 | − tc_size[i] = 7; | |
| 2646 | − break; | |
| 2647 | − default: | |
| 2648 | − break; | |
| 2649 | − } | |
| 2650 | − tc_offset[i] = hdev->rss_size_max * i; | |
| 2665 | + if (!(hdev->hw_tc_map & BIT(i))) | |
| 2666 | + continue; | |
| 2667 | + | |
| 2668 | + tc_valid[i] = 1; | |
| 2669 | + tc_size[i] = roundup_size; | |
| 2670 | + tc_offset[i] = rss_size * i; | |
| 2651 | 2671 | } |
| 2672 | + | |
| 2652 | 2673 | ret = hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset); |
| 2653 | 2674 | |
| 2654 | 2675 | err: |
| @@ -2679,7 +2700,11 @@ int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector_id, · 24 unmodified lines | ||
| 2679 | 2700 | hnae_get_bit(node->flag, HNAE3_RING_TYPE_B)); |
| 2680 | 2701 | hnae_set_field(req->tqp_type_and_id[i], HCLGE_TQP_ID_M, |
| 2681 | 2702 | HCLGE_TQP_ID_S, node->tqp_index); |
| 2703 | + hnae_set_field(req->tqp_type_and_id[i], HCLGE_INT_GL_IDX_M, | |
| 2704 | + HCLGE_INT_GL_IDX_S, | |
| 2705 | + hnae_get_bit(node->flag, HNAE3_RING_TYPE_B)); | |
| 2682 | 2706 | req->tqp_type_and_id[i] = cpu_to_le16(req->tqp_type_and_id[i]); |
| 2707 | + req->vfid = vport->vport_id; | |
| 2683 | 2708 | |
| 2684 | 2709 | if (++i >= HCLGE_VECTOR_ELEMENTS_PER_CMD) { |
| 2685 | 2710 | req->int_cause_num = HCLGE_VECTOR_ELEMENTS_PER_CMD; |
| @@ -2763,8 +2788,12 @@ static int hclge_unmap_ring_from_vector( · 77 unmodified lines | ||
| 2763 | 2788 | hnae_get_bit(node->flag, HNAE3_RING_TYPE_B)); |
| 2764 | 2789 | hnae_set_field(req->tqp_type_and_id[i], HCLGE_TQP_ID_M, |
| 2765 | 2790 | HCLGE_TQP_ID_S, node->tqp_index); |
| 2791 | + hnae_set_field(req->tqp_type_and_id[i], HCLGE_INT_GL_IDX_M, | |
| 2792 | + HCLGE_INT_GL_IDX_S, | |
| 2793 | + hnae_get_bit(node->flag, HNAE3_RING_TYPE_B)); | |
| 2766 | 2794 | |
| 2767 | 2795 | req->tqp_type_and_id[i] = cpu_to_le16(req->tqp_type_and_id[i]); |
| 2796 | + req->vfid = vport->vport_id; | |
| 2768 | 2797 | |
| 2769 | 2798 | if (++i >= HCLGE_VECTOR_ELEMENTS_PER_CMD) { |
| 2770 | 2799 | req->int_cause_num = HCLGE_VECTOR_ELEMENTS_PER_CMD; |
| @@ -2778,7 +2807,7 @@ static int hclge_unmap_ring_from_vector( · 7 unmodified lines | ||
| 2778 | 2807 | } |
| 2779 | 2808 | i = 0; |
| 2780 | 2809 | hclge_cmd_setup_basic_desc(&desc, |
| 2781 | − HCLGE_OPC_ADD_RING_TO_VECTOR, | |
| 2810 | + HCLGE_OPC_DEL_RING_TO_VECTOR, | |
| 2782 | 2811 | false); |
| 2783 | 2812 | req->int_vector_id = vector_id; |
| 2784 | 2813 | } |
| @@ -3665,6 +3694,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) · 880 unmodified lines | ||
| 3665 | 3694 | { |
| 3666 | 3695 | #define HCLGE_VLAN_TYPE_VF_TABLE 0 |
| 3667 | 3696 | #define HCLGE_VLAN_TYPE_PORT_TABLE 1 |
| 3697 | + struct hnae3_handle *handle; | |
| 3668 | 3698 | int ret; |
| 3669 | 3699 | |
| 3670 | 3700 | ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_VLAN_TYPE_VF_TABLE, |
| @@ -3674,8 +3704,11 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) · 3 unmodified lines | ||
| 3674 | 3704 | |
| 3675 | 3705 | ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_VLAN_TYPE_PORT_TABLE, |
| 3676 | 3706 | true); |
| 3707 | + if (ret) | |
| 3708 | + return ret; | |
| 3677 | 3709 | |
| 3678 | − return ret; | |
| 3710 | + handle = &hdev->vport[0].nic; | |
| 3711 | + return hclge_set_port_vlan_filter(handle, htons(ETH_P_8021Q), 0, false); | |
| 3679 | 3712 | } |
| 3680 | 3713 | |
| 3681 | 3714 | static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu) |
| @@ -3920,8 +3953,7 @@ static int hclge_init_client_instance(struct hnae3_client *client, · 238 unmodified lines | ||
| 3920 | 3953 | goto err; |
| 3921 | 3954 | |
| 3922 | 3955 | if (hdev->roce_client && |
| 3923 | − hnae_get_bit(hdev->ae_dev->flag, | |
| 3924 | − HNAE_DEV_SUPPORT_ROCE_B)) { | |
| 3956 | + hnae3_dev_roce_supported(hdev)) { | |
| 3925 | 3957 | struct hnae3_client *rc = hdev->roce_client; |
| 3926 | 3958 | |
| 3927 | 3959 | ret = hclge_init_roce_base_info(vport); |
| @@ -3944,8 +3976,7 @@ static int hclge_init_client_instance(struct hnae3_client *client, · 16 unmodified lines | ||
| 3944 | 3976 | |
| 3945 | 3977 | break; |
| 3946 | 3978 | case HNAE3_CLIENT_ROCE: |
| 3947 | − if (hnae_get_bit(hdev->ae_dev->flag, | |
| 3948 | − HNAE_DEV_SUPPORT_ROCE_B)) { | |
| 3979 | + if (hnae3_dev_roce_supported(hdev)) { | |
| 3949 | 3980 | hdev->roce_client = client; |
| 3950 | 3981 | vport->roce.client = client; |
| 3951 | 3982 | } |
| @@ -4057,7 +4088,6 @@ static void hclge_pci_uninit(struct hclge_dev *hdev) · 105 unmodified lines | ||
| 4057 | 4088 | static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) |
| 4058 | 4089 | { |
| 4059 | 4090 | struct pci_dev *pdev = ae_dev->pdev; |
| 4060 | − const struct pci_device_id *id; | |
| 4061 | 4091 | struct hclge_dev *hdev; |
| 4062 | 4092 | int ret; |
| 4063 | 4093 | |
| @@ -4072,10 +4102,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) · 8 unmodified lines | ||
| 4072 | 4102 | hdev->ae_dev = ae_dev; |
| 4073 | 4103 | ae_dev->priv = hdev; |
| 4074 | 4104 | |
| 4075 | − id = pci_match_id(roce_pci_tbl, ae_dev->pdev); | |
| 4076 | − if (id) | |
| 4077 | − hnae_set_bit(ae_dev->flag, HNAE_DEV_SUPPORT_ROCE_B, 1); | |
| 4078 | − | |
| 4079 | 4105 | ret = hclge_pci_init(hdev); |
| 4080 | 4106 | if (ret) { |
| 4081 | 4107 | dev_err(&pdev->dev, "PCI init failed\n"); |
| @@ -4138,12 +4164,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) · 56 unmodified lines | ||
| 4138 | 4164 | return ret; |
| 4139 | 4165 | } |
| 4140 | 4166 | |
| 4141 | − ret = hclge_rss_init_hw(hdev); | |
| 4142 | − if (ret) { | |
| 4143 | − dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret); | |
| 4144 | − return ret; | |
| 4145 | − } | |
| 4146 | − | |
| 4147 | 4167 | ret = hclge_init_vlan_config(hdev); |
| 4148 | 4168 | if (ret) { |
| 4149 | 4169 | dev_err(&pdev->dev, "VLAN init fail, ret =%d\n", ret); |
| @@ -4156,6 +4176,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) · 6 unmodified lines | ||
| 4156 | 4176 | return ret; |
| 4157 | 4177 | } |
| 4158 | 4178 | |
| 4179 | + ret = hclge_rss_init_hw(hdev); | |
| 4180 | + if (ret) { | |
| 4181 | + dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret); | |
| 4182 | + return ret; | |
| 4183 | + } | |
| 4184 | + | |
| 4159 | 4185 | setup_timer(&hdev->service_timer, hclge_service_timer, |
| 4160 | 4186 | (unsigned long)hdev); |
| 4161 | 4187 | INIT_WORK(&hdev->service_task, hclge_service_task); |
| @@ -176,7 +176,6 @@ struct hclge_pg_info { · 175 unmodified lines | ||
| 176 | 176 | struct hclge_tc_info { |
| 177 | 177 | u8 tc_id; |
| 178 | 178 | u8 tc_sch_mode; /* 0: sp; 1: dwrr */ |
| 179 | − u8 up; | |
| 180 | 179 | u8 pgid; |
| 181 | 180 | u32 bw_limit; |
| 182 | 181 | }; |
| @@ -197,6 +196,7 @@ struct hclge_tm_info { · 14 unmodified lines | ||
| 197 | 196 | u8 num_tc; |
| 198 | 197 | u8 num_pg; /* It must be 1 if vNET-Base schd */ |
| 199 | 198 | u8 pg_dwrr[HCLGE_PG_NUM]; |
| 199 | + u8 prio_tc[HNAE3_MAX_USER_PRIO]; | |
| 200 | 200 | struct hclge_pg_info pg_info[HCLGE_PG_NUM]; |
| 201 | 201 | struct hclge_tc_info tc_info[HNAE3_MAX_TC]; |
| 202 | 202 | enum hclge_fc_mode fc_mode; |
| @@ -477,6 +477,7 @@ struct hclge_vport { · 274 unmodified lines | ||
| 477 | 477 | u8 rss_hash_key[HCLGE_RSS_KEY_SIZE]; /* User configured hash keys */ |
| 478 | 478 | /* User configured lookup table entries */ |
| 479 | 479 | u8 rss_indirection_tbl[HCLGE_RSS_IND_TBL_SIZE]; |
| 480 | + u16 alloc_rss_size; | |
| 480 | 481 | |
| 481 | 482 | u16 qs_offset; |
| 482 | 483 | u16 bw_limit; /* VSI BW Limit (0 = disabled) */ |
| @@ -128,9 +128,7 @@ static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id) · 127 unmodified lines | ||
| 128 | 128 | { |
| 129 | 129 | u8 tc; |
| 130 | 130 | |
| 131 | − for (tc = 0; tc < hdev->tm_info.num_tc; tc++) | |
| 132 | − if (hdev->tm_info.tc_info[tc].up == pri_id) | |
| 133 | − break; | |
| 131 | + tc = hdev->tm_info.prio_tc[pri_id]; | |
| 134 | 132 | |
| 135 | 133 | if (tc >= hdev->tm_info.num_tc) |
| 136 | 134 | return -EINVAL; |
| @@ -158,7 +156,7 @@ static int hclge_up_to_tc_map(struct hclge_dev *hdev) · 21 unmodified lines | ||
| 158 | 156 | |
| 159 | 157 | hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PRI_TO_TC_MAPPING, false); |
| 160 | 158 | |
| 161 | − for (pri_id = 0; pri_id < hdev->tm_info.num_tc; pri_id++) { | |
| 159 | + for (pri_id = 0; pri_id < HNAE3_MAX_USER_PRIO; pri_id++) { | |
| 162 | 160 | ret = hclge_fill_pri_array(hdev, pri, pri_id); |
| 163 | 161 | if (ret) |
| 164 | 162 | return ret; |
| @@ -280,11 +278,11 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev, · 115 unmodified lines | ||
| 280 | 278 | |
| 281 | 279 | shap_cfg_cmd->pg_id = pg_id; |
| 282 | 280 | |
| 283 | − hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, IR_B, ir_b); | |
| 284 | − hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, IR_U, ir_u); | |
| 285 | − hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, IR_S, ir_s); | |
| 286 | − hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, BS_B, bs_b); | |
| 287 | − hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, BS_S, bs_s); | |
| 281 | + hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_B, ir_b); | |
| 282 | + hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_U, ir_u); | |
| 283 | + hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_S, ir_s); | |
| 284 | + hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, BS_B, bs_b); | |
| 285 | + hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, BS_S, bs_s); | |
| 288 | 286 | |
| 289 | 287 | return hclge_cmd_send(&hdev->hw, &desc, 1); |
| 290 | 288 | } |
| @@ -307,11 +305,11 @@ static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev, · 16 unmodified lines | ||
| 307 | 305 | |
| 308 | 306 | shap_cfg_cmd->pri_id = pri_id; |
| 309 | 307 | |
| 310 | − hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, IR_B, ir_b); | |
| 311 | − hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, IR_U, ir_u); | |
| 312 | − hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, IR_S, ir_s); | |
| 313 | − hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, BS_B, bs_b); | |
| 314 | − hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, BS_S, bs_s); | |
| 308 | + hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_B, ir_b); | |
| 309 | + hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_U, ir_u); | |
| 310 | + hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_S, ir_s); | |
| 311 | + hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, BS_B, bs_b); | |
| 312 | + hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, BS_S, bs_s); | |
| 315 | 313 | |
| 316 | 314 | return hclge_cmd_send(&hdev->hw, &desc, 1); |
| 317 | 315 | } |
| @@ -397,6 +395,7 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) · 79 unmodified lines | ||
| 397 | 395 | kinfo->num_tqps / kinfo->num_tc); |
| 398 | 396 | vport->qs_offset = hdev->tm_info.num_tc * vport->vport_id; |
| 399 | 397 | vport->dwrr = 100; /* 100 percent as init */ |
| 398 | + vport->alloc_rss_size = kinfo->rss_size; | |
| 400 | 399 | |
| 401 | 400 | for (i = 0; i < kinfo->num_tc; i++) { |
| 402 | 401 | if (hdev->hw_tc_map & BIT(i)) { |
| @@ -404,16 +403,17 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) · 1 unmodified line | ||
| 404 | 403 | kinfo->tc_info[i].tqp_offset = i * kinfo->rss_size; |
| 405 | 404 | kinfo->tc_info[i].tqp_count = kinfo->rss_size; |
| 406 | 405 | kinfo->tc_info[i].tc = i; |
| 407 | − kinfo->tc_info[i].up = hdev->tm_info.tc_info[i].up; | |
| 408 | 406 | } else { |
| 409 | 407 | /* Set to default queue if TC is disable */ |
| 410 | 408 | kinfo->tc_info[i].enable = false; |
| 411 | 409 | kinfo->tc_info[i].tqp_offset = 0; |
| 412 | 410 | kinfo->tc_info[i].tqp_count = 1; |
| 413 | 411 | kinfo->tc_info[i].tc = 0; |
| 414 | − kinfo->tc_info[i].up = 0; | |
| 415 | 412 | } |
| 416 | 413 | } |
| 414 | + | |
| 415 | + memcpy(kinfo->prio_tc, hdev->tm_info.prio_tc, | |
| 416 | + FIELD_SIZEOF(struct hnae3_knic_private_info, prio_tc)); | |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | 419 | static void hclge_tm_vport_info_update(struct hclge_dev *hdev) |
| @@ -435,12 +435,15 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev) · 15 unmodified lines | ||
| 435 | 435 | for (i = 0; i < hdev->tm_info.num_tc; i++) { |
| 436 | 436 | hdev->tm_info.tc_info[i].tc_id = i; |
| 437 | 437 | hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR; |
| 438 | − hdev->tm_info.tc_info[i].up = i; | |
| 439 | 438 | hdev->tm_info.tc_info[i].pgid = 0; |
| 440 | 439 | hdev->tm_info.tc_info[i].bw_limit = |
| 441 | 440 | hdev->tm_info.pg_info[0].bw_limit; |
| 442 | 441 | } |
| 443 | 442 | |
| 443 | + for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) | |
| 444 | + hdev->tm_info.prio_tc[i] = | |
| 445 | + (i >= hdev->tm_info.num_tc) ? 0 : i; | |
| 446 | + | |
| 444 | 447 | hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; |
| 445 | 448 | } |
| 446 | 449 | |
| @@ -976,6 +979,10 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev) · 529 unmodified lines | ||
| 976 | 979 | if (ret) |
| 977 | 980 | return ret; |
| 978 | 981 | |
| 982 | + /* Only DCB-supported dev supports qset back pressure setting */ | |
| 983 | + if (!hnae3_dev_dcb_supported(hdev)) | |
| 984 | + return 0; | |
| 985 | + | |
| 979 | 986 | for (i = 0; i < hdev->tm_info.num_tc; i++) { |
| 980 | 987 | ret = hclge_tm_qs_bp_cfg(hdev, i); |
| 981 | 988 | if (ret) |
| @@ -94,10 +94,10 @@ struct hclge_bp_to_qs_map_cmd { · 93 unmodified lines | ||
| 94 | 94 | u32 rsvd1; |
| 95 | 95 | }; |
| 96 | 96 | |
| 97 | −#define hclge_tm_set_feild(dest, string, val) \ | |
| 97 | +#define hclge_tm_set_field(dest, string, val) \ | |
| 98 | 98 | hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \ |
| 99 | 99 | (HCLGE_TM_SHAP_##string##_LSH), val) |
| 100 | −#define hclge_tm_get_feild(src, string) \ | |
| 100 | +#define hclge_tm_get_field(src, string) \ | |
| 101 | 101 | hnae_get_field((src), (HCLGE_TM_SHAP_##string##_MSK), \ |
| 102 | 102 | (HCLGE_TM_SHAP_##string##_LSH)) |
| 103 | 103 | |
| @@ -41,11 +41,16 @@ static struct hnae3_client client; · 40 unmodified lines | ||
| 41 | 41 | static const struct pci_device_id hns3_pci_tbl[] = { |
| 42 | 42 | {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_GE), 0}, |
| 43 | 43 | {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE), 0}, |
| 44 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA), 0}, | |
| 45 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA_MACSEC), 0}, | |
| 46 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), 0}, | |
| 47 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), 0}, | |
| 48 | − {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), 0}, | |
| 44 | + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA), | |
| 45 | + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, | |
| 46 | + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA_MACSEC), | |
| 47 | + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, | |
| 48 | + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), | |
| 49 | + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, | |
| 50 | + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), | |
| 51 | + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, | |
| 52 | + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), | |
| 53 | + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, | |
| 49 | 54 | /* required last entry */ |
| 50 | 55 | {0, } |
| 51 | 56 | }; |
| @@ -1348,6 +1353,7 @@ static int hns3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 1296 unmodified lines | ||
| 1348 | 1353 | } |
| 1349 | 1354 | |
| 1350 | 1355 | ae_dev->pdev = pdev; |
| 1356 | + ae_dev->flag = ent->driver_data; | |
| 1351 | 1357 | ae_dev->dev_type = HNAE3_DEV_KNIC; |
| 1352 | 1358 | pci_set_drvdata(pdev, ae_dev); |
| 1353 | 1359 | |
| @@ -2705,10 +2711,11 @@ static void hns3_init_mac_addr(struct net_device *netdev) · 1351 unmodified lines | ||
| 2705 | 2711 | eth_hw_addr_random(netdev); |
| 2706 | 2712 | dev_warn(priv->dev, "using random MAC address %pM\n", |
| 2707 | 2713 | netdev->dev_addr); |
| 2708 | − /* Also copy this new MAC address into hdev */ | |
| 2709 | − if (h->ae_algo->ops->set_mac_addr) | |
| 2710 | − h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr); | |
| 2711 | 2714 | } |
| 2715 | + | |
| 2716 | + if (h->ae_algo->ops->set_mac_addr) | |
| 2717 | + h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr); | |
| 2718 | + | |
| 2712 | 2719 | } |
| 2713 | 2720 | |
| 2714 | 2721 | static void hns3_nic_set_priv_ops(struct net_device *netdev) |
| @@ -402,7 +402,7 @@ static int mal_poll(struct napi_struct *napi, int budget) · 401 unmodified lines | ||
| 402 | 402 | unsigned long flags; |
| 403 | 403 | |
| 404 | 404 | MAL_DBG2(mal, "poll(%d)" NL, budget); |
| 405 | − again: | |
| 405 | + | |
| 406 | 406 | /* Process TX skbs */ |
| 407 | 407 | list_for_each(l, &mal->poll_list) { |
| 408 | 408 | struct mal_commac *mc = |
| @@ -451,7 +451,6 @@ static int mal_poll(struct napi_struct *napi, int budget) · 42 unmodified lines | ||
| 451 | 451 | spin_lock_irqsave(&mal->lock, flags); |
| 452 | 452 | mal_disable_eob_irq(mal); |
| 453 | 453 | spin_unlock_irqrestore(&mal->lock, flags); |
| 454 | − goto again; | |
| 455 | 454 | } |
| 456 | 455 | mc->ops->poll_tx(mc->dev); |
| 457 | 456 | } |
| @@ -333,7 +333,7 @@ · 332 unmodified lines | ||
| 333 | 333 | #define MVPP2_GMAC_INBAND_AN_MASK BIT(0) |
| 334 | 334 | #define MVPP2_GMAC_FLOW_CTRL_MASK GENMASK(2, 1) |
| 335 | 335 | #define MVPP2_GMAC_PCS_ENABLE_MASK BIT(3) |
| 336 | −#define MVPP2_GMAC_PORT_RGMII_MASK BIT(4) | |
| 336 | +#define MVPP2_GMAC_INTERNAL_CLK_MASK BIT(4) | |
| 337 | 337 | #define MVPP2_GMAC_DISABLE_PADDING BIT(5) |
| 338 | 338 | #define MVPP2_GMAC_PORT_RESET_MASK BIT(6) |
| 339 | 339 | #define MVPP2_GMAC_AUTONEG_CONFIG 0xc |
| @@ -676,6 +676,7 @@ enum mvpp2_tag_type { · 336 unmodified lines | ||
| 676 | 676 | #define MVPP2_PRS_RI_L3_MCAST BIT(15) |
| 677 | 677 | #define MVPP2_PRS_RI_L3_BCAST (BIT(15) | BIT(16)) |
| 678 | 678 | #define MVPP2_PRS_RI_IP_FRAG_MASK 0x20000 |
| 679 | +#define MVPP2_PRS_RI_IP_FRAG_TRUE BIT(17) | |
| 679 | 680 | #define MVPP2_PRS_RI_UDF3_MASK 0x300000 |
| 680 | 681 | #define MVPP2_PRS_RI_UDF3_RX_SPECIAL BIT(21) |
| 681 | 682 | #define MVPP2_PRS_RI_L4_PROTO_MASK 0x1c00000 |
| @@ -792,6 +793,7 @@ struct mvpp2 { · 110 unmodified lines | ||
| 792 | 793 | struct clk *pp_clk; |
| 793 | 794 | struct clk *gop_clk; |
| 794 | 795 | struct clk *mg_clk; |
| 796 | + struct clk *axi_clk; | |
| 795 | 797 | |
| 796 | 798 | /* List of pointers to port structures */ |
| 797 | 799 | struct mvpp2_port **port_list; |
| @@ -2315,7 +2317,7 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto, · 1517 unmodified lines | ||
| 2315 | 2317 | (proto != IPPROTO_IGMP)) |
| 2316 | 2318 | return -EINVAL; |
| 2317 | 2319 | |
| 2318 | − /* Fragmented packet */ | |
| 2320 | + /* Not fragmented packet */ | |
| 2319 | 2321 | tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, |
| 2320 | 2322 | MVPP2_PE_LAST_FREE_TID); |
| 2321 | 2323 | if (tid < 0) |
| @@ -2334,8 +2336,12 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto, · 12 unmodified lines | ||
| 2334 | 2336 | MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); |
| 2335 | 2337 | mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT, |
| 2336 | 2338 | MVPP2_PRS_IPV4_DIP_AI_BIT); |
| 2337 | − mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_MASK, | |
| 2338 | − ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK); | |
| 2339 | + mvpp2_prs_sram_ri_update(&pe, ri, ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK); | |
| 2340 | + | |
| 2341 | + mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, | |
| 2342 | + MVPP2_PRS_TCAM_PROTO_MASK_L); | |
| 2343 | + mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, | |
| 2344 | + MVPP2_PRS_TCAM_PROTO_MASK); | |
| 2339 | 2345 | |
| 2340 | 2346 | mvpp2_prs_tcam_data_byte_set(&pe, 5, proto, MVPP2_PRS_TCAM_PROTO_MASK); |
| 2341 | 2347 | mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT); |
| @@ -2346,7 +2352,7 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto, · 4 unmodified lines | ||
| 2346 | 2352 | mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4); |
| 2347 | 2353 | mvpp2_prs_hw_write(priv, &pe); |
| 2348 | 2354 | |
| 2349 | − /* Not fragmented packet */ | |
| 2355 | + /* Fragmented packet */ | |
| 2350 | 2356 | tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, |
| 2351 | 2357 | MVPP2_PE_LAST_FREE_TID); |
| 2352 | 2358 | if (tid < 0) |
| @@ -2358,8 +2364,11 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto, · 5 unmodified lines | ||
| 2358 | 2364 | pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0; |
| 2359 | 2365 | mvpp2_prs_sram_ri_update(&pe, ri, ri_mask); |
| 2360 | 2366 | |
| 2361 | − mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, MVPP2_PRS_TCAM_PROTO_MASK_L); | |
| 2362 | − mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, MVPP2_PRS_TCAM_PROTO_MASK); | |
| 2367 | + mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_TRUE, | |
| 2368 | + ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK); | |
| 2369 | + | |
| 2370 | + mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, 0x0); | |
| 2371 | + mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, 0x0); | |
| 2363 | 2372 | |
| 2364 | 2373 | /* Update shadow table and hw entry */ |
| 2365 | 2374 | mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4); |
| @@ -4591,7 +4600,6 @@ static void mvpp2_port_mii_gmac_configure(struct mvpp2_port *port) · 2225 unmodified lines | ||
| 4591 | 4600 | val |= MVPP2_GMAC_INBAND_AN_MASK | MVPP2_GMAC_PCS_ENABLE_MASK; |
| 4592 | 4601 | } else if (phy_interface_mode_is_rgmii(port->phy_interface)) { |
| 4593 | 4602 | val &= ~MVPP2_GMAC_PCS_ENABLE_MASK; |
| 4594 | − val |= MVPP2_GMAC_PORT_RGMII_MASK; | |
| 4595 | 4603 | } |
| 4596 | 4604 | writel(val, port->base + MVPP2_GMAC_CTRL_2_REG); |
| 4597 | 4605 | |
| @@ -7496,7 +7504,7 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv, · 2898 unmodified lines | ||
| 7496 | 7504 | /* Ports initialization */ |
| 7497 | 7505 | static int mvpp2_port_probe(struct platform_device *pdev, |
| 7498 | 7506 | struct device_node *port_node, |
| 7499 | − struct mvpp2 *priv) | |
| 7507 | + struct mvpp2 *priv, int index) | |
| 7500 | 7508 | { |
| 7501 | 7509 | struct device_node *phy_node; |
| 7502 | 7510 | struct phy *comphy; |
| @@ -7670,7 +7678,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, · 167 unmodified lines | ||
| 7670 | 7678 | } |
| 7671 | 7679 | netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr); |
| 7672 | 7680 | |
| 7673 | − priv->port_list[id] = port; | |
| 7681 | + priv->port_list[index] = port; | |
| 7674 | 7682 | return 0; |
| 7675 | 7683 | |
| 7676 | 7684 | err_free_port_pcpu: |
| @@ -7963,6 +7971,18 @@ static int mvpp2_probe(struct platform_device *pdev) · 286 unmodified lines | ||
| 7963 | 7971 | err = clk_prepare_enable(priv->mg_clk); |
| 7964 | 7972 | if (err < 0) |
| 7965 | 7973 | goto err_gop_clk; |
| 7974 | + | |
| 7975 | + priv->axi_clk = devm_clk_get(&pdev->dev, "axi_clk"); | |
| 7976 | + if (IS_ERR(priv->axi_clk)) { | |
| 7977 | + err = PTR_ERR(priv->axi_clk); | |
| 7978 | + if (err == -EPROBE_DEFER) | |
| 7979 | + goto err_gop_clk; | |
| 7980 | + priv->axi_clk = NULL; | |
| 7981 | + } else { | |
| 7982 | + err = clk_prepare_enable(priv->axi_clk); | |
| 7983 | + if (err < 0) | |
| 7984 | + goto err_gop_clk; | |
| 7985 | + } | |
| 7966 | 7986 | } |
| 7967 | 7987 | |
| 7968 | 7988 | /* Get system's tclk rate */ |
| @@ -8005,16 +8025,19 @@ static int mvpp2_probe(struct platform_device *pdev) · 36 unmodified lines | ||
| 8005 | 8025 | } |
| 8006 | 8026 | |
| 8007 | 8027 | /* Initialize ports */ |
| 8028 | + i = 0; | |
| 8008 | 8029 | for_each_available_child_of_node(dn, port_node) { |
| 8009 | − err = mvpp2_port_probe(pdev, port_node, priv); | |
| 8030 | + err = mvpp2_port_probe(pdev, port_node, priv, i); | |
| 8010 | 8031 | if (err < 0) |
| 8011 | 8032 | goto err_mg_clk; |
| 8033 | + i++; | |
| 8012 | 8034 | } |
| 8013 | 8035 | |
| 8014 | 8036 | platform_set_drvdata(pdev, priv); |
| 8015 | 8037 | return 0; |
| 8016 | 8038 | |
| 8017 | 8039 | err_mg_clk: |
| 8040 | + clk_disable_unprepare(priv->axi_clk); | |
| 8018 | 8041 | if (priv->hw_version == MVPP22) |
| 8019 | 8042 | clk_disable_unprepare(priv->mg_clk); |
| 8020 | 8043 | err_gop_clk: |
| @@ -8052,6 +8075,7 @@ static int mvpp2_remove(struct platform_device *pdev) · 31 unmodified lines | ||
| 8052 | 8075 | aggr_txq->descs_dma); |
| 8053 | 8076 | } |
| 8054 | 8077 | |
| 8078 | + clk_disable_unprepare(priv->axi_clk); | |
| 8055 | 8079 | clk_disable_unprepare(priv->mg_clk); |
| 8056 | 8080 | clk_disable_unprepare(priv->pp_clk); |
| 8057 | 8081 | clk_disable_unprepare(priv->gop_clk); |
| @@ -139,7 +139,7 @@ TRACE_EVENT(mlx5_fs_del_fg, · 138 unmodified lines | ||
| 139 | 139 | {MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO, "NEXT_PRIO"} |
| 140 | 140 | |
| 141 | 141 | TRACE_EVENT(mlx5_fs_set_fte, |
| 142 | − TP_PROTO(const struct fs_fte *fte, bool new_fte), | |
| 142 | + TP_PROTO(const struct fs_fte *fte, int new_fte), | |
| 143 | 143 | TP_ARGS(fte, new_fte), |
| 144 | 144 | TP_STRUCT__entry( |
| 145 | 145 | __field(const struct fs_fte *, fte) |
| @@ -149,7 +149,7 @@ TRACE_EVENT(mlx5_fs_set_fte, · 3 unmodified lines | ||
| 149 | 149 | __field(u32, action) |
| 150 | 150 | __field(u32, flow_tag) |
| 151 | 151 | __field(u8, mask_enable) |
| 152 | − __field(bool, new_fte) | |
| 152 | + __field(int, new_fte) | |
| 153 | 153 | __array(u32, mask_outer, MLX5_ST_SZ_DW(fte_match_set_lyr_2_4)) |
| 154 | 154 | __array(u32, mask_inner, MLX5_ST_SZ_DW(fte_match_set_lyr_2_4)) |
| 155 | 155 | __array(u32, mask_misc, MLX5_ST_SZ_DW(fte_match_set_misc)) |
| @@ -291,7 +291,7 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv) · 290 unmodified lines | ||
| 291 | 291 | priv->fs.vlan.filter_disabled = false; |
| 292 | 292 | if (priv->netdev->flags & IFF_PROMISC) |
| 293 | 293 | return; |
| 294 | − mlx5e_del_any_vid_rules(priv); | |
| 294 | + mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); | |
| 295 | 295 | } |
| 296 | 296 | |
| 297 | 297 | void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv) |
| @@ -302,7 +302,7 @@ void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv) · 4 unmodified lines | ||
| 302 | 302 | priv->fs.vlan.filter_disabled = true; |
| 303 | 303 | if (priv->netdev->flags & IFF_PROMISC) |
| 304 | 304 | return; |
| 305 | − mlx5e_add_any_vid_rules(priv); | |
| 305 | + mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); | |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | 308 | int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto, |
| @@ -184,7 +184,6 @@ static void mlx5e_update_sw_counters(struct mlx5e_priv *priv) · 183 unmodified lines | ||
| 184 | 184 | struct mlx5e_sw_stats temp, *s = &temp; |
| 185 | 185 | struct mlx5e_rq_stats *rq_stats; |
| 186 | 186 | struct mlx5e_sq_stats *sq_stats; |
| 187 | − u64 tx_offload_none = 0; | |
| 188 | 187 | int i, j; |
| 189 | 188 | |
| 190 | 189 | memset(s, 0, sizeof(*s)); |
| @@ -199,6 +198,7 @@ static void mlx5e_update_sw_counters(struct mlx5e_priv *priv) · 8 unmodified lines | ||
| 199 | 198 | s->rx_lro_bytes += rq_stats->lro_bytes; |
| 200 | 199 | s->rx_csum_none += rq_stats->csum_none; |
| 201 | 200 | s->rx_csum_complete += rq_stats->csum_complete; |
| 201 | + s->rx_csum_unnecessary += rq_stats->csum_unnecessary; | |
| 202 | 202 | s->rx_csum_unnecessary_inner += rq_stats->csum_unnecessary_inner; |
| 203 | 203 | s->rx_xdp_drop += rq_stats->xdp_drop; |
| 204 | 204 | s->rx_xdp_tx += rq_stats->xdp_tx; |
| @@ -229,14 +229,11 @@ static void mlx5e_update_sw_counters(struct mlx5e_priv *priv) · 24 unmodified lines | ||
| 229 | 229 | s->tx_queue_dropped += sq_stats->dropped; |
| 230 | 230 | s->tx_xmit_more += sq_stats->xmit_more; |
| 231 | 231 | s->tx_csum_partial_inner += sq_stats->csum_partial_inner; |
| 232 | − tx_offload_none += sq_stats->csum_none; | |
| 232 | + s->tx_csum_none += sq_stats->csum_none; | |
| 233 | + s->tx_csum_partial += sq_stats->csum_partial; | |
| 233 | 234 | } |
| 234 | 235 | } |
| 235 | 236 | |
| 236 | − /* Update calculated offload counters */ | |
| 237 | − s->tx_csum_partial = s->tx_packets - tx_offload_none - s->tx_csum_partial_inner; | |
| 238 | − s->rx_csum_unnecessary = s->rx_packets - s->rx_csum_none - s->rx_csum_complete; | |
| 239 | − | |
| 240 | 237 | s->link_down_events_phy = MLX5_GET(ppcnt_reg, |
| 241 | 238 | priv->stats.pport.phy_counters, |
| 242 | 239 | counter_set.phys_layer_cntrs.link_down_events); |
| @@ -3333,8 +3330,8 @@ static int mlx5e_handle_feature(struct net_device *netdev, · 3090 unmodified lines | ||
| 3333 | 3330 | |
| 3334 | 3331 | err = feature_handler(netdev, enable); |
| 3335 | 3332 | if (err) { |
| 3336 | − netdev_err(netdev, "%s feature 0x%llx failed err %d\n", | |
| 3337 | − enable ? "Enable" : "Disable", feature, err); | |
| 3333 | + netdev_err(netdev, "%s feature %pNF failed, err %d\n", | |
| 3334 | + enable ? "Enable" : "Disable", &feature, err); | |
| 3338 | 3335 | return err; |
| 3339 | 3336 | } |
| 3340 | 3337 | |
| @@ -627,6 +627,7 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, · 626 unmodified lines | ||
| 627 | 627 | |
| 628 | 628 | if (lro) { |
| 629 | 629 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 630 | + rq->stats.csum_unnecessary++; | |
| 630 | 631 | return; |
| 631 | 632 | } |
| 632 | 633 | |
| @@ -644,7 +645,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, · 11 unmodified lines | ||
| 644 | 645 | skb->csum_level = 1; |
| 645 | 646 | skb->encapsulation = 1; |
| 646 | 647 | rq->stats.csum_unnecessary_inner++; |
| 648 | + return; | |
| 647 | 649 | } |
| 650 | + rq->stats.csum_unnecessary++; | |
| 648 | 651 | return; |
| 649 | 652 | } |
| 650 | 653 | csum_none: |
| @@ -68,6 +68,7 @@ struct mlx5e_sw_stats { · 67 unmodified lines | ||
| 68 | 68 | u64 rx_xdp_drop; |
| 69 | 69 | u64 rx_xdp_tx; |
| 70 | 70 | u64 rx_xdp_tx_full; |
| 71 | + u64 tx_csum_none; | |
| 71 | 72 | u64 tx_csum_partial; |
| 72 | 73 | u64 tx_csum_partial_inner; |
| 73 | 74 | u64 tx_queue_stopped; |
| @@ -108,6 +109,7 @@ static const struct counter_desc sw_stats_desc[] = { · 34 unmodified lines | ||
| 108 | 109 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_drop) }, |
| 109 | 110 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx) }, |
| 110 | 111 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_full) }, |
| 112 | + { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_none) }, | |
| 111 | 113 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_partial) }, |
| 112 | 114 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_partial_inner) }, |
| 113 | 115 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_stopped) }, |
| @@ -339,6 +341,7 @@ struct mlx5e_rq_stats { · 225 unmodified lines | ||
| 339 | 341 | u64 packets; |
| 340 | 342 | u64 bytes; |
| 341 | 343 | u64 csum_complete; |
| 344 | + u64 csum_unnecessary; | |
| 342 | 345 | u64 csum_unnecessary_inner; |
| 343 | 346 | u64 csum_none; |
| 344 | 347 | u64 lro_packets; |
| @@ -363,6 +366,7 @@ static const struct counter_desc rq_stats_desc[] = { · 18 unmodified lines | ||
| 363 | 366 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, packets) }, |
| 364 | 367 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, bytes) }, |
| 365 | 368 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete) }, |
| 369 | + { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary) }, | |
| 366 | 370 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary_inner) }, |
| 367 | 371 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_none) }, |
| 368 | 372 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, xdp_drop) }, |
| @@ -392,6 +396,7 @@ struct mlx5e_sq_stats { · 23 unmodified lines | ||
| 392 | 396 | u64 tso_bytes; |
| 393 | 397 | u64 tso_inner_packets; |
| 394 | 398 | u64 tso_inner_bytes; |
| 399 | + u64 csum_partial; | |
| 395 | 400 | u64 csum_partial_inner; |
| 396 | 401 | u64 nop; |
| 397 | 402 | /* less likely accessed in data path */ |
| @@ -408,6 +413,7 @@ static const struct counter_desc sq_stats_desc[] = { · 10 unmodified lines | ||
| 408 | 413 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_bytes) }, |
| 409 | 414 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_inner_packets) }, |
| 410 | 415 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_inner_bytes) }, |
| 416 | + { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial) }, | |
| 411 | 417 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) }, |
| 412 | 418 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, nop) }, |
| 413 | 419 | { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_none) }, |
| @@ -1317,6 +1317,69 @@ static bool csum_offload_supported(struct mlx5e_priv *priv, u32 action, u32 upda · 1316 unmodified lines | ||
| 1317 | 1317 | return true; |
| 1318 | 1318 | } |
| 1319 | 1319 | |
| 1320 | +static bool modify_header_match_supported(struct mlx5_flow_spec *spec, | |
| 1321 | + struct tcf_exts *exts) | |
| 1322 | +{ | |
| 1323 | + const struct tc_action *a; | |
| 1324 | + bool modify_ip_header; | |
| 1325 | + LIST_HEAD(actions); | |
| 1326 | + u8 htype, ip_proto; | |
| 1327 | + void *headers_v; | |
| 1328 | + u16 ethertype; | |
| 1329 | + int nkeys, i; | |
| 1330 | + | |
| 1331 | + headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers); | |
| 1332 | + ethertype = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ethertype); | |
| 1333 | + | |
| 1334 | + /* for non-IP we only re-write MACs, so we're okay */ | |
| 1335 | + if (ethertype != ETH_P_IP && ethertype != ETH_P_IPV6) | |
| 1336 | + goto out_ok; | |
| 1337 | + | |
| 1338 | + modify_ip_header = false; | |
| 1339 | + tcf_exts_to_list(exts, &actions); | |
| 1340 | + list_for_each_entry(a, &actions, list) { | |
| 1341 | + if (!is_tcf_pedit(a)) | |
| 1342 | + continue; | |
| 1343 | + | |
| 1344 | + nkeys = tcf_pedit_nkeys(a); | |
| 1345 | + for (i = 0; i < nkeys; i++) { | |
| 1346 | + htype = tcf_pedit_htype(a, i); | |
| 1347 | + if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 || | |
| 1348 | + htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP6) { | |
| 1349 | + modify_ip_header = true; | |
| 1350 | + break; | |
| 1351 | + } | |
| 1352 | + } | |
| 1353 | + } | |
| 1354 | + | |
| 1355 | + ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); | |
| 1356 | + if (modify_ip_header && ip_proto != IPPROTO_TCP && ip_proto != IPPROTO_UDP) { | |
| 1357 | + pr_info("can't offload re-write of ip proto %d\n", ip_proto); | |
| 1358 | + return false; | |
| 1359 | + } | |
| 1360 | + | |
| 1361 | +out_ok: | |
| 1362 | + return true; | |
| 1363 | +} | |
| 1364 | + | |
| 1365 | +static bool actions_match_supported(struct mlx5e_priv *priv, | |
| 1366 | + struct tcf_exts *exts, | |
| 1367 | + struct mlx5e_tc_flow_parse_attr *parse_attr, | |
| 1368 | + struct mlx5e_tc_flow *flow) | |
| 1369 | +{ | |
| 1370 | + u32 actions; | |
| 1371 | + | |
| 1372 | + if (flow->flags & MLX5E_TC_FLOW_ESWITCH) | |
| 1373 | + actions = flow->esw_attr->action; | |
| 1374 | + else | |
| 1375 | + actions = flow->nic_attr->action; | |
| 1376 | + | |
| 1377 | + if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) | |
| 1378 | + return modify_header_match_supported(&parse_attr->spec, exts); | |
| 1379 | + | |
| 1380 | + return true; | |
| 1381 | +} | |
| 1382 | + | |
| 1320 | 1383 | static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, |
| 1321 | 1384 | struct mlx5e_tc_flow_parse_attr *parse_attr, |
| 1322 | 1385 | struct mlx5e_tc_flow *flow) |
| @@ -1378,6 +1441,9 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, · 55 unmodified lines | ||
| 1378 | 1441 | return -EINVAL; |
| 1379 | 1442 | } |
| 1380 | 1443 | |
| 1444 | + if (!actions_match_supported(priv, exts, parse_attr, flow)) | |
| 1445 | + return -EOPNOTSUPP; | |
| 1446 | + | |
| 1381 | 1447 | return 0; |
| 1382 | 1448 | } |
| 1383 | 1449 | |
| @@ -1564,7 +1630,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, · 180 unmodified lines | ||
| 1564 | 1630 | break; |
| 1565 | 1631 | default: |
| 1566 | 1632 | err = -EOPNOTSUPP; |
| 1567 | − goto out; | |
| 1633 | + goto free_encap; | |
| 1568 | 1634 | } |
| 1569 | 1635 | fl4.flowi4_tos = tun_key->tos; |
| 1570 | 1636 | fl4.daddr = tun_key->u.ipv4.dst; |
| @@ -1573,7 +1639,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, · 2 unmodified lines | ||
| 1573 | 1639 | err = mlx5e_route_lookup_ipv4(priv, mirred_dev, &out_dev, |
| 1574 | 1640 | &fl4, &n, &ttl); |
| 1575 | 1641 | if (err) |
| 1576 | − goto out; | |
| 1642 | + goto free_encap; | |
| 1577 | 1643 | |
| 1578 | 1644 | /* used by mlx5e_detach_encap to lookup a neigh hash table |
| 1579 | 1645 | * entry in the neigh hash table when a user deletes a rule |
| @@ -1590,7 +1656,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, · 10 unmodified lines | ||
| 1590 | 1656 | */ |
| 1591 | 1657 | err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); |
| 1592 | 1658 | if (err) |
| 1593 | − goto out; | |
| 1659 | + goto free_encap; | |
| 1594 | 1660 | |
| 1595 | 1661 | read_lock_bh(&n->lock); |
| 1596 | 1662 | nud_state = n->nud_state; |
| @@ -1630,8 +1696,9 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, · 33 unmodified lines | ||
| 1630 | 1696 | |
| 1631 | 1697 | destroy_neigh_entry: |
| 1632 | 1698 | mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); |
| 1633 | −out: | |
| 1699 | +free_encap: | |
| 1634 | 1700 | kfree(encap_header); |
| 1701 | +out: | |
| 1635 | 1702 | if (n) |
| 1636 | 1703 | neigh_release(n); |
| 1637 | 1704 | return err; |
| @@ -1668,7 +1735,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, · 30 unmodified lines | ||
| 1668 | 1735 | break; |
| 1669 | 1736 | default: |
| 1670 | 1737 | err = -EOPNOTSUPP; |
| 1671 | − goto out; | |
| 1738 | + goto free_encap; | |
| 1672 | 1739 | } |
| 1673 | 1740 | |
| 1674 | 1741 | fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tun_key->tos), tun_key->label); |
| @@ -1678,7 +1745,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, · 3 unmodified lines | ||
| 1678 | 1745 | err = mlx5e_route_lookup_ipv6(priv, mirred_dev, &out_dev, |
| 1679 | 1746 | &fl6, &n, &ttl); |
| 1680 | 1747 | if (err) |
| 1681 | − goto out; | |
| 1748 | + goto free_encap; | |
| 1682 | 1749 | |
| 1683 | 1750 | /* used by mlx5e_detach_encap to lookup a neigh hash table |
| 1684 | 1751 | * entry in the neigh hash table when a user deletes a rule |
| @@ -1695,7 +1762,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, · 10 unmodified lines | ||
| 1695 | 1762 | */ |
| 1696 | 1763 | err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); |
| 1697 | 1764 | if (err) |
| 1698 | − goto out; | |
| 1765 | + goto free_encap; | |
| 1699 | 1766 | |
| 1700 | 1767 | read_lock_bh(&n->lock); |
| 1701 | 1768 | nud_state = n->nud_state; |
| @@ -1736,8 +1803,9 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, · 34 unmodified lines | ||
| 1736 | 1803 | |
| 1737 | 1804 | destroy_neigh_entry: |
| 1738 | 1805 | mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); |
| 1739 | −out: | |
| 1806 | +free_encap: | |
| 1740 | 1807 | kfree(encap_header); |
| 1808 | +out: | |
| 1741 | 1809 | if (n) |
| 1742 | 1810 | neigh_release(n); |
| 1743 | 1811 | return err; |
| @@ -1791,6 +1859,7 @@ vxlan_encap_offload_err: · 47 unmodified lines | ||
| 1791 | 1859 | } |
| 1792 | 1860 | } |
| 1793 | 1861 | |
| 1862 | + /* must verify if encap is valid or not */ | |
| 1794 | 1863 | if (found) |
| 1795 | 1864 | goto attach_flow; |
| 1796 | 1865 | |
| @@ -1817,6 +1886,8 @@ attach_flow: · 20 unmodified lines | ||
| 1817 | 1886 | *encap_dev = e->out_dev; |
| 1818 | 1887 | if (e->flags & MLX5_ENCAP_ENTRY_VALID) |
| 1819 | 1888 | attr->encap_id = e->encap_id; |
| 1889 | + else | |
| 1890 | + err = -EAGAIN; | |
| 1820 | 1891 | |
| 1821 | 1892 | return err; |
| 1822 | 1893 | |
| @@ -1934,6 +2005,10 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, · 111 unmodified lines | ||
| 1934 | 2005 | |
| 1935 | 2006 | return -EINVAL; |
| 1936 | 2007 | } |
| 2008 | + | |
| 2009 | + if (!actions_match_supported(priv, exts, parse_attr, flow)) | |
| 2010 | + return -EOPNOTSUPP; | |
| 2011 | + | |
| 1937 | 2012 | return err; |
| 1938 | 2013 | } |
| 1939 | 2014 | |
| @@ -193,6 +193,7 @@ mlx5e_txwqe_build_eseg_csum(struct mlx5e_txqsq *sq, struct sk_buff *skb, struct · 192 unmodified lines | ||
| 193 | 193 | sq->stats.csum_partial_inner++; |
| 194 | 194 | } else { |
| 195 | 195 | eseg->cs_flags |= MLX5_ETH_WQE_L4_CSUM; |
| 196 | + sq->stats.csum_partial++; | |
| 196 | 197 | } |
| 197 | 198 | } else |
| 198 | 199 | sq->stats.csum_none++; |
| @@ -71,11 +71,11 @@ int mlx5_fpga_access_reg(struct mlx5_core_dev *dev, u8 size, u64 addr, · 70 unmodified lines | ||
| 71 | 71 | return 0; |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | −int mlx5_fpga_caps(struct mlx5_core_dev *dev, u32 *caps) | |
| 74 | +int mlx5_fpga_caps(struct mlx5_core_dev *dev) | |
| 75 | 75 | { |
| 76 | 76 | u32 in[MLX5_ST_SZ_DW(fpga_cap)] = {0}; |
| 77 | 77 | |
| 78 | − return mlx5_core_access_reg(dev, in, sizeof(in), caps, | |
| 78 | + return mlx5_core_access_reg(dev, in, sizeof(in), dev->caps.fpga, | |
| 79 | 79 | MLX5_ST_SZ_BYTES(fpga_cap), |
| 80 | 80 | MLX5_REG_FPGA_CAP, 0, 0); |
| 81 | 81 | } |
| @@ -65,7 +65,7 @@ struct mlx5_fpga_qp_counters { · 64 unmodified lines | ||
| 65 | 65 | u64 rx_total_drop; |
| 66 | 66 | }; |
| 67 | 67 | |
| 68 | −int mlx5_fpga_caps(struct mlx5_core_dev *dev, u32 *caps); | |
| 68 | +int mlx5_fpga_caps(struct mlx5_core_dev *dev); | |
| 69 | 69 | int mlx5_fpga_query(struct mlx5_core_dev *dev, struct mlx5_fpga_query *query); |
| 70 | 70 | int mlx5_fpga_ctrl_op(struct mlx5_core_dev *dev, u8 op); |
| 71 | 71 | int mlx5_fpga_access_reg(struct mlx5_core_dev *dev, u8 size, u64 addr, |
| @@ -139,8 +139,7 @@ int mlx5_fpga_device_start(struct mlx5_core_dev *mdev) · 138 unmodified lines | ||
| 139 | 139 | if (err) |
| 140 | 140 | goto out; |
| 141 | 141 | |
| 142 | − err = mlx5_fpga_caps(fdev->mdev, | |
| 143 | − fdev->mdev->caps.hca_cur[MLX5_CAP_FPGA]); | |
| 142 | + err = mlx5_fpga_caps(fdev->mdev); | |
| 144 | 143 | if (err) |
| 145 | 144 | goto out; |
| 146 | 145 | |
| @@ -293,6 +293,9 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, · 292 unmodified lines | ||
| 293 | 293 | } |
| 294 | 294 | |
| 295 | 295 | if (fte->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { |
| 296 | + int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev, | |
| 297 | + log_max_flow_counter, | |
| 298 | + ft->type)); | |
| 296 | 299 | int list_size = 0; |
| 297 | 300 | |
| 298 | 301 | list_for_each_entry(dst, &fte->node.children, node.list) { |
| @@ -305,12 +308,17 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, · 6 unmodified lines | ||
| 305 | 308 | in_dests += MLX5_ST_SZ_BYTES(dest_format_struct); |
| 306 | 309 | list_size++; |
| 307 | 310 | } |
| 311 | + if (list_size > max_list_size) { | |
| 312 | + err = -EINVAL; | |
| 313 | + goto err_out; | |
| 314 | + } | |
| 308 | 315 | |
| 309 | 316 | MLX5_SET(flow_context, in_flow_context, flow_counter_list_size, |
| 310 | 317 | list_size); |
| 311 | 318 | } |
| 312 | 319 | |
| 313 | 320 | err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); |
| 321 | +err_out: | |
| 314 | 322 | kvfree(in); |
| 315 | 323 | return err; |
| 316 | 324 | } |
| @@ -52,6 +52,7 @@ enum fs_flow_table_type { · 51 unmodified lines | ||
| 52 | 52 | FS_FT_FDB = 0X4, |
| 53 | 53 | FS_FT_SNIFFER_RX = 0X5, |
| 54 | 54 | FS_FT_SNIFFER_TX = 0X6, |
| 55 | + FS_FT_MAX_TYPE = FS_FT_SNIFFER_TX, | |
| 55 | 56 | }; |
| 56 | 57 | |
| 57 | 58 | enum fs_flow_table_op_mod { |
| @@ -260,4 +261,14 @@ void mlx5_cleanup_fs(struct mlx5_core_dev *dev); · 202 unmodified lines | ||
| 260 | 261 | #define fs_for_each_dst(pos, fte) \ |
| 261 | 262 | fs_list_for_each_entry(pos, &(fte)->node.children) |
| 262 | 263 | |
| 264 | +#define MLX5_CAP_FLOWTABLE_TYPE(mdev, cap, type) ( \ | |
| 265 | + (type == FS_FT_NIC_RX) ? MLX5_CAP_FLOWTABLE_NIC_RX(mdev, cap) : \ | |
| 266 | + (type == FS_FT_ESW_EGRESS_ACL) ? MLX5_CAP_ESW_EGRESS_ACL(mdev, cap) : \ | |
| 267 | + (type == FS_FT_ESW_INGRESS_ACL) ? MLX5_CAP_ESW_INGRESS_ACL(mdev, cap) : \ | |
| 268 | + (type == FS_FT_FDB) ? MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, cap) : \ | |
| 269 | + (type == FS_FT_SNIFFER_RX) ? MLX5_CAP_FLOWTABLE_SNIFFER_RX(mdev, cap) : \ | |
| 270 | + (type == FS_FT_SNIFFER_TX) ? MLX5_CAP_FLOWTABLE_SNIFFER_TX(mdev, cap) : \ | |
| 271 | + (BUILD_BUG_ON_ZERO(FS_FT_SNIFFER_TX != FS_FT_MAX_TYPE))\ | |
| 272 | + ) | |
| 273 | + | |
| 263 | 274 | #endif |
| @@ -572,12 +572,13 @@ void mlx5_rdma_netdev_free(struct net_device *netdev) · 571 unmodified lines | ||
| 572 | 572 | { |
| 573 | 573 | struct mlx5e_priv *priv = mlx5i_epriv(netdev); |
| 574 | 574 | const struct mlx5e_profile *profile = priv->profile; |
| 575 | + struct mlx5_core_dev *mdev = priv->mdev; | |
| 575 | 576 | |
| 576 | 577 | mlx5e_detach_netdev(priv); |
| 577 | 578 | profile->cleanup(priv); |
| 578 | 579 | destroy_workqueue(priv->wq); |
| 579 | 580 | free_netdev(netdev); |
| 580 | 581 | |
| 581 | − mlx5e_destroy_mdev_resources(priv->mdev); | |
| 582 | + mlx5e_destroy_mdev_resources(mdev); | |
| 582 | 583 | } |
| 583 | 584 | EXPORT_SYMBOL(mlx5_rdma_netdev_free); |
| @@ -109,7 +109,7 @@ static int mlx5_device_enable_sriov(struct mlx5_core_dev *dev, int num_vfs) · 108 unmodified lines | ||
| 109 | 109 | mlx5_core_warn(dev, |
| 110 | 110 | "failed to restore VF %d settings, err %d\n", |
| 111 | 111 | vf, err); |
| 112 | − continue; | |
| 112 | + continue; | |
| 113 | 113 | } |
| 114 | 114 | } |
| 115 | 115 | mlx5_core_dbg(dev, "successfully enabled VF* %d\n", vf); |
| @@ -2723,6 +2723,7 @@ static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp, · 2722 unmodified lines | ||
| 2723 | 2723 | mlxsw_sp_nexthop_rif_fini(nh); |
| 2724 | 2724 | break; |
| 2725 | 2725 | case MLXSW_SP_NEXTHOP_TYPE_IPIP: |
| 2726 | + mlxsw_sp_nexthop_rif_fini(nh); | |
| 2726 | 2727 | mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh); |
| 2727 | 2728 | break; |
| 2728 | 2729 | } |
| @@ -2742,7 +2743,11 @@ static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp, · 13 unmodified lines | ||
| 2742 | 2743 | router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, |
| 2743 | 2744 | MLXSW_SP_L3_PROTO_IPV4)) { |
| 2744 | 2745 | nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; |
| 2745 | − return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); | |
| 2746 | + err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); | |
| 2747 | + if (err) | |
| 2748 | + return err; | |
| 2749 | + mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common); | |
| 2750 | + return 0; | |
| 2746 | 2751 | } |
| 2747 | 2752 | |
| 2748 | 2753 | nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; |
| @@ -4009,7 +4014,11 @@ static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp, · 1260 unmodified lines | ||
| 4009 | 4014 | router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, |
| 4010 | 4015 | MLXSW_SP_L3_PROTO_IPV6)) { |
| 4011 | 4016 | nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; |
| 4012 | − return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); | |
| 4017 | + err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); | |
| 4018 | + if (err) | |
| 4019 | + return err; | |
| 4020 | + mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common); | |
| 4021 | + return 0; | |
| 4013 | 4022 | } |
| 4014 | 4023 | |
| 4015 | 4024 | nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; |
| @@ -5068,6 +5077,7 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, · 1052 unmodified lines | ||
| 5068 | 5077 | vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN); |
| 5069 | 5078 | if (IS_ERR(vr)) |
| 5070 | 5079 | return ERR_CAST(vr); |
| 5080 | + vr->rif_count++; | |
| 5071 | 5081 | |
| 5072 | 5082 | err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index); |
| 5073 | 5083 | if (err) |
| @@ -5099,7 +5109,6 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, · 25 unmodified lines | ||
| 5099 | 5109 | |
| 5100 | 5110 | mlxsw_sp_rif_counters_alloc(rif); |
| 5101 | 5111 | mlxsw_sp->router->rifs[rif_index] = rif; |
| 5102 | − vr->rif_count++; | |
| 5103 | 5112 | |
| 5104 | 5113 | return rif; |
| 5105 | 5114 | |
| @@ -5110,6 +5119,7 @@ err_fid_get: · 4 unmodified lines | ||
| 5110 | 5119 | kfree(rif); |
| 5111 | 5120 | err_rif_alloc: |
| 5112 | 5121 | err_rif_index_alloc: |
| 5122 | + vr->rif_count--; | |
| 5113 | 5123 | mlxsw_sp_vr_put(vr); |
| 5114 | 5124 | return ERR_PTR(err); |
| 5115 | 5125 | } |
| @@ -5124,7 +5134,6 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) · 8 unmodified lines | ||
| 5124 | 5134 | mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif); |
| 5125 | 5135 | vr = &mlxsw_sp->router->vrs[rif->vr_id]; |
| 5126 | 5136 | |
| 5127 | − vr->rif_count--; | |
| 5128 | 5137 | mlxsw_sp->router->rifs[rif->rif_index] = NULL; |
| 5129 | 5138 | mlxsw_sp_rif_counters_free(rif); |
| 5130 | 5139 | ops->deconfigure(rif); |
| @@ -5132,6 +5141,7 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) · 1 unmodified line | ||
| 5132 | 5141 | /* Loopback RIFs are not associated with a FID. */ |
| 5133 | 5142 | mlxsw_sp_fid_put(fid); |
| 5134 | 5143 | kfree(rif); |
| 5144 | + vr->rif_count--; | |
| 5135 | 5145 | mlxsw_sp_vr_put(vr); |
| 5136 | 5146 | } |
| 5137 | 5147 | |
| @@ -88,6 +88,8 @@ static void emac_set_msglevel(struct net_device *netdev, u32 data) · 87 unmodified lines | ||
| 88 | 88 | static int emac_get_sset_count(struct net_device *netdev, int sset) |
| 89 | 89 | { |
| 90 | 90 | switch (sset) { |
| 91 | + case ETH_SS_PRIV_FLAGS: | |
| 92 | + return 1; | |
| 91 | 93 | case ETH_SS_STATS: |
| 92 | 94 | return EMAC_STATS_LEN; |
| 93 | 95 | default: |
| @@ -100,6 +102,10 @@ static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data) · 6 unmodified lines | ||
| 100 | 102 | unsigned int i; |
| 101 | 103 | |
| 102 | 104 | switch (stringset) { |
| 105 | + case ETH_SS_PRIV_FLAGS: | |
| 106 | + strcpy(data, "single-pause-mode"); | |
| 107 | + break; | |
| 108 | + | |
| 103 | 109 | case ETH_SS_STATS: |
| 104 | 110 | for (i = 0; i < EMAC_STATS_LEN; i++) { |
| 105 | 111 | strlcpy(data, emac_ethtool_stat_strings[i], |
| @@ -230,6 +236,27 @@ static int emac_get_regs_len(struct net_device *netdev) · 124 unmodified lines | ||
| 230 | 236 | return EMAC_MAX_REG_SIZE * sizeof(u32); |
| 231 | 237 | } |
| 232 | 238 | |
| 239 | +#define EMAC_PRIV_ENABLE_SINGLE_PAUSE BIT(0) | |
| 240 | + | |
| 241 | +static int emac_set_priv_flags(struct net_device *netdev, u32 flags) | |
| 242 | +{ | |
| 243 | + struct emac_adapter *adpt = netdev_priv(netdev); | |
| 244 | + | |
| 245 | + adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE); | |
| 246 | + | |
| 247 | + if (netif_running(netdev)) | |
| 248 | + return emac_reinit_locked(adpt); | |
| 249 | + | |
| 250 | + return 0; | |
| 251 | +} | |
| 252 | + | |
| 253 | +static u32 emac_get_priv_flags(struct net_device *netdev) | |
| 254 | +{ | |
| 255 | + struct emac_adapter *adpt = netdev_priv(netdev); | |
| 256 | + | |
| 257 | + return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0; | |
| 258 | +} | |
| 259 | + | |
| 233 | 260 | static const struct ethtool_ops emac_ethtool_ops = { |
| 234 | 261 | .get_link_ksettings = phy_ethtool_get_link_ksettings, |
| 235 | 262 | .set_link_ksettings = phy_ethtool_set_link_ksettings, |
| @@ -253,6 +280,9 @@ static const struct ethtool_ops emac_ethtool_ops = { · 17 unmodified lines | ||
| 253 | 280 | |
| 254 | 281 | .get_regs_len = emac_get_regs_len, |
| 255 | 282 | .get_regs = emac_get_regs, |
| 283 | + | |
| 284 | + .set_priv_flags = emac_set_priv_flags, | |
| 285 | + .get_priv_flags = emac_get_priv_flags, | |
| 256 | 286 | }; |
| 257 | 287 | |
| 258 | 288 | void emac_set_ethtool_ops(struct net_device *netdev) |
| @@ -551,6 +551,28 @@ static void emac_mac_start(struct emac_adapter *adpt) · 550 unmodified lines | ||
| 551 | 551 | mac &= ~(HUGEN | VLAN_STRIP | TPAUSE | SIMR | HUGE | MULTI_ALL | |
| 552 | 552 | DEBUG_MODE | SINGLE_PAUSE_MODE); |
| 553 | 553 | |
| 554 | + /* Enable single-pause-frame mode if requested. | |
| 555 | + * | |
| 556 | + * If enabled, the EMAC will send a single pause frame when the RX | |
| 557 | + * queue is full. This normally leads to packet loss because | |
| 558 | + * the pause frame disables the remote MAC only for 33ms (the quanta), | |
| 559 | + * and then the remote MAC continues sending packets even though | |
| 560 | + * the RX queue is still full. | |
| 561 | + * | |
| 562 | + * If disabled, the EMAC sends a pause frame every 31ms until the RX | |
| 563 | + * queue is no longer full. Normally, this is the preferred | |
| 564 | + * method of operation. However, when the system is hung (e.g. | |
| 565 | + * cores are halted), the EMAC interrupt handler is never called | |
| 566 | + * and so the RX queue fills up quickly and stays full. The resuling | |
| 567 | + * non-stop "flood" of pause frames sometimes has the effect of | |
| 568 | + * disabling nearby switches. In some cases, other nearby switches | |
| 569 | + * are also affected, shutting down the entire network. | |
| 570 | + * | |
| 571 | + * The user can enable or disable single-pause-frame mode | |
| 572 | + * via ethtool. | |
| 573 | + */ | |
| 574 | + mac |= adpt->single_pause_mode ? SINGLE_PAUSE_MODE : 0; | |
| 575 | + | |
| 554 | 576 | writel_relaxed(csr1, adpt->csr + EMAC_EMAC_WRAPPER_CSR1); |
| 555 | 577 | |
| 556 | 578 | writel_relaxed(mac, adpt->base + EMAC_MAC_CTRL); |
| @@ -876,7 +898,8 @@ static void emac_mac_rx_descs_refill(struct emac_adapter *adpt, · 319 unmodified lines | ||
| 876 | 898 | |
| 877 | 899 | curr_rxbuf->dma_addr = |
| 878 | 900 | dma_map_single(adpt->netdev->dev.parent, skb->data, |
| 879 | − curr_rxbuf->length, DMA_FROM_DEVICE); | |
| 901 | + adpt->rxbuf_size, DMA_FROM_DEVICE); | |
| 902 | + | |
| 880 | 903 | ret = dma_mapping_error(adpt->netdev->dev.parent, |
| 881 | 904 | curr_rxbuf->dma_addr); |
| 882 | 905 | if (ret) { |
| @@ -443,6 +443,9 @@ static void emac_init_adapter(struct emac_adapter *adpt) · 442 unmodified lines | ||
| 443 | 443 | |
| 444 | 444 | /* default to automatic flow control */ |
| 445 | 445 | adpt->automatic = true; |
| 446 | + | |
| 447 | + /* Disable single-pause-frame mode by default */ | |
| 448 | + adpt->single_pause_mode = false; | |
| 446 | 449 | } |
| 447 | 450 | |
| 448 | 451 | /* Get the clock */ |
| @@ -363,6 +363,9 @@ struct emac_adapter { · 362 unmodified lines | ||
| 363 | 363 | bool tx_flow_control; |
| 364 | 364 | bool rx_flow_control; |
| 365 | 365 | |
| 366 | + /* True == use single-pause-frame mode. */ | |
| 367 | + bool single_pause_mode; | |
| 368 | + | |
| 366 | 369 | /* Ring parameter */ |
| 367 | 370 | u8 tpd_burst; |
| 368 | 371 | u8 rfd_burst; |
| @@ -51,10 +51,7 @@ struct rmnet_walk_data { · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | static int rmnet_is_real_dev_registered(const struct net_device *real_dev) |
| 53 | 53 | { |
| 54 | − rx_handler_func_t *rx_handler; | |
| 55 | − | |
| 56 | − rx_handler = rcu_dereference(real_dev->rx_handler); | |
| 57 | − return (rx_handler == rmnet_rx_handler); | |
| 54 | + return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler; | |
| 58 | 55 | } |
| 59 | 56 | |
| 60 | 57 | /* Needs rtnl lock */ |
| @@ -2135,11 +2135,12 @@ static int rtl8139_poll(struct napi_struct *napi, int budget) · 2134 unmodified lines | ||
| 2135 | 2135 | if (likely(RTL_R16(IntrStatus) & RxAckBits)) |
| 2136 | 2136 | work_done += rtl8139_rx(dev, tp, budget); |
| 2137 | 2137 | |
| 2138 | − if (work_done < budget && napi_complete_done(napi, work_done)) { | |
| 2138 | + if (work_done < budget) { | |
| 2139 | 2139 | unsigned long flags; |
| 2140 | 2140 | |
| 2141 | 2141 | spin_lock_irqsave(&tp->lock, flags); |
| 2142 | − RTL_W16_F(IntrMask, rtl8139_intr_mask); | |
| 2142 | + if (napi_complete_done(napi, work_done)) | |
| 2143 | + RTL_W16_F(IntrMask, rtl8139_intr_mask); | |
| 2143 | 2144 | spin_unlock_irqrestore(&tp->lock, flags); |
| 2144 | 2145 | } |
| 2145 | 2146 | spin_unlock(&tp->rx_lock); |
| @@ -139,40 +139,52 @@ rocker_tlv_start(struct rocker_desc_info *desc_info) · 138 unmodified lines | ||
| 139 | 139 | int rocker_tlv_put(struct rocker_desc_info *desc_info, |
| 140 | 140 | int attrtype, int attrlen, const void *data); |
| 141 | 141 | |
| 142 | −static inline int rocker_tlv_put_u8(struct rocker_desc_info *desc_info, | |
| 143 | − int attrtype, u8 value) | |
| 142 | +static inline int | |
| 143 | +rocker_tlv_put_u8(struct rocker_desc_info *desc_info, int attrtype, u8 value) | |
| 144 | 144 | { |
| 145 | − return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &value); | |
| 145 | + u8 tmp = value; /* work around GCC PR81715 */ | |
| 146 | + | |
| 147 | + return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &tmp); | |
| 146 | 148 | } |
| 147 | 149 | |
| 148 | −static inline int rocker_tlv_put_u16(struct rocker_desc_info *desc_info, | |
| 149 | − int attrtype, u16 value) | |
| 150 | +static inline int | |
| 151 | +rocker_tlv_put_u16(struct rocker_desc_info *desc_info, int attrtype, u16 value) | |
| 150 | 152 | { |
| 151 | − return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &value); | |
| 153 | + u16 tmp = value; | |
| 154 | + | |
| 155 | + return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &tmp); | |
| 152 | 156 | } |
| 153 | 157 | |
| 154 | −static inline int rocker_tlv_put_be16(struct rocker_desc_info *desc_info, | |
| 155 | − int attrtype, __be16 value) | |
| 158 | +static inline int | |
| 159 | +rocker_tlv_put_be16(struct rocker_desc_info *desc_info, int attrtype, __be16 value) | |
| 156 | 160 | { |
| 157 | − return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &value); | |
| 161 | + __be16 tmp = value; | |
| 162 | + | |
| 163 | + return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &tmp); | |
| 158 | 164 | } |
| 159 | 165 | |
| 160 | −static inline int rocker_tlv_put_u32(struct rocker_desc_info *desc_info, | |
| 161 | − int attrtype, u32 value) | |
| 166 | +static inline int | |
| 167 | +rocker_tlv_put_u32(struct rocker_desc_info *desc_info, int attrtype, u32 value) | |
| 162 | 168 | { |
| 163 | − return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &value); | |
| 169 | + u32 tmp = value; | |
| 170 | + | |
| 171 | + return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &tmp); | |
| 164 | 172 | } |
| 165 | 173 | |
| 166 | −static inline int rocker_tlv_put_be32(struct rocker_desc_info *desc_info, | |
| 167 | − int attrtype, __be32 value) | |
| 174 | +static inline int | |
| 175 | +rocker_tlv_put_be32(struct rocker_desc_info *desc_info, int attrtype, __be32 value) | |
| 168 | 176 | { |
| 169 | − return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &value); | |
| 177 | + __be32 tmp = value; | |
| 178 | + | |
| 179 | + return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &tmp); | |
| 170 | 180 | } |
| 171 | 181 | |
| 172 | −static inline int rocker_tlv_put_u64(struct rocker_desc_info *desc_info, | |
| 173 | − int attrtype, u64 value) | |
| 182 | +static inline int | |
| 183 | +rocker_tlv_put_u64(struct rocker_desc_info *desc_info, int attrtype, u64 value) | |
| 174 | 184 | { |
| 175 | − return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &value); | |
| 185 | + u64 tmp = value; | |
| 186 | + | |
| 187 | + return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &tmp); | |
| 176 | 188 | } |
| 177 | 189 | |
| 178 | 190 | static inline struct rocker_tlv * |
| @@ -511,6 +511,7 @@ static struct platform_driver dwc_eth_dwmac_driver = { · 510 unmodified lines | ||
| 511 | 511 | .remove = dwc_eth_dwmac_remove, |
| 512 | 512 | .driver = { |
| 513 | 513 | .name = "dwc-eth-dwmac", |
| 514 | + .pm = &stmmac_pltfr_pm_ops, | |
| 514 | 515 | .of_match_table = dwc_eth_dwmac_match, |
| 515 | 516 | }, |
| 516 | 517 | }; |
| @@ -83,6 +83,117 @@ struct rk_priv_data { · 82 unmodified lines | ||
| 83 | 83 | (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ |
| 84 | 84 | ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) |
| 85 | 85 | |
| 86 | +#define RK3128_GRF_MAC_CON0 0x0168 | |
| 87 | +#define RK3128_GRF_MAC_CON1 0x016c | |
| 88 | + | |
| 89 | +/* RK3128_GRF_MAC_CON0 */ | |
| 90 | +#define RK3128_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) | |
| 91 | +#define RK3128_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) | |
| 92 | +#define RK3128_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) | |
| 93 | +#define RK3128_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) | |
| 94 | +#define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) | |
| 95 | +#define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) | |
| 96 | + | |
| 97 | +/* RK3128_GRF_MAC_CON1 */ | |
| 98 | +#define RK3128_GMAC_PHY_INTF_SEL_RGMII \ | |
| 99 | + (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8)) | |
| 100 | +#define RK3128_GMAC_PHY_INTF_SEL_RMII \ | |
| 101 | + (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8)) | |
| 102 | +#define RK3128_GMAC_FLOW_CTRL GRF_BIT(9) | |
| 103 | +#define RK3128_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) | |
| 104 | +#define RK3128_GMAC_SPEED_10M GRF_CLR_BIT(10) | |
| 105 | +#define RK3128_GMAC_SPEED_100M GRF_BIT(10) | |
| 106 | +#define RK3128_GMAC_RMII_CLK_25M GRF_BIT(11) | |
| 107 | +#define RK3128_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) | |
| 108 | +#define RK3128_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) | |
| 109 | +#define RK3128_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) | |
| 110 | +#define RK3128_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) | |
| 111 | +#define RK3128_GMAC_RMII_MODE GRF_BIT(14) | |
| 112 | +#define RK3128_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) | |
| 113 | + | |
| 114 | +static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv, | |
| 115 | + int tx_delay, int rx_delay) | |
| 116 | +{ | |
| 117 | + struct device *dev = &bsp_priv->pdev->dev; | |
| 118 | + | |
| 119 | + if (IS_ERR(bsp_priv->grf)) { | |
| 120 | + dev_err(dev, "Missing rockchip,grf property\n"); | |
| 121 | + return; | |
| 122 | + } | |
| 123 | + | |
| 124 | + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, | |
| 125 | + RK3128_GMAC_PHY_INTF_SEL_RGMII | | |
| 126 | + RK3128_GMAC_RMII_MODE_CLR); | |
| 127 | + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0, | |
| 128 | + DELAY_ENABLE(RK3128, tx_delay, rx_delay) | | |
| 129 | + RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) | | |
| 130 | + RK3128_GMAC_CLK_TX_DL_CFG(tx_delay)); | |
| 131 | +} | |
| 132 | + | |
| 133 | +static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) | |
| 134 | +{ | |
| 135 | + struct device *dev = &bsp_priv->pdev->dev; | |
| 136 | + | |
| 137 | + if (IS_ERR(bsp_priv->grf)) { | |
| 138 | + dev_err(dev, "Missing rockchip,grf property\n"); | |
| 139 | + return; | |
| 140 | + } | |
| 141 | + | |
| 142 | + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, | |
| 143 | + RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE); | |
| 144 | +} | |
| 145 | + | |
| 146 | +static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) | |
| 147 | +{ | |
| 148 | + struct device *dev = &bsp_priv->pdev->dev; | |
| 149 | + | |
| 150 | + if (IS_ERR(bsp_priv->grf)) { | |
| 151 | + dev_err(dev, "Missing rockchip,grf property\n"); | |
| 152 | + return; | |
| 153 | + } | |
| 154 | + | |
| 155 | + if (speed == 10) | |
| 156 | + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, | |
| 157 | + RK3128_GMAC_CLK_2_5M); | |
| 158 | + else if (speed == 100) | |
| 159 | + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, | |
| 160 | + RK3128_GMAC_CLK_25M); | |
| 161 | + else if (speed == 1000) | |
| 162 | + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, | |
| 163 | + RK3128_GMAC_CLK_125M); | |
| 164 | + else | |
| 165 | + dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); | |
| 166 | +} | |
| 167 | + | |
| 168 | +static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) | |
| 169 | +{ | |
| 170 | + struct device *dev = &bsp_priv->pdev->dev; | |
| 171 | + | |
| 172 | + if (IS_ERR(bsp_priv->grf)) { | |
| 173 | + dev_err(dev, "Missing rockchip,grf property\n"); | |
| 174 | + return; | |
| 175 | + } | |
| 176 | + | |
| 177 | + if (speed == 10) { | |
| 178 | + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, | |
| 179 | + RK3128_GMAC_RMII_CLK_2_5M | | |
| 180 | + RK3128_GMAC_SPEED_10M); | |
| 181 | + } else if (speed == 100) { | |
| 182 | + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, | |
| 183 | + RK3128_GMAC_RMII_CLK_25M | | |
| 184 | + RK3128_GMAC_SPEED_100M); | |
| 185 | + } else { | |
| 186 | + dev_err(dev, "unknown speed value for RMII! speed=%d", speed); | |
| 187 | + } | |
| 188 | +} | |
| 189 | + | |
| 190 | +static const struct rk_gmac_ops rk3128_ops = { | |
| 191 | + .set_to_rgmii = rk3128_set_to_rgmii, | |
| 192 | + .set_to_rmii = rk3128_set_to_rmii, | |
| 193 | + .set_rgmii_speed = rk3128_set_rgmii_speed, | |
| 194 | + .set_rmii_speed = rk3128_set_rmii_speed, | |
| 195 | +}; | |
| 196 | + | |
| 86 | 197 | #define RK3228_GRF_MAC_CON0 0x0900 |
| 87 | 198 | #define RK3228_GRF_MAC_CON1 0x0904 |
| 88 | 199 | |
| @@ -1313,6 +1424,7 @@ static int rk_gmac_resume(struct device *dev) · 1224 unmodified lines | ||
| 1313 | 1424 | static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); |
| 1314 | 1425 | |
| 1315 | 1426 | static const struct of_device_id rk_gmac_dwmac_match[] = { |
| 1427 | + { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, | |
| 1316 | 1428 | { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, |
| 1317 | 1429 | { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, |
| 1318 | 1430 | { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, |
| @@ -296,6 +296,7 @@ static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode) · 295 unmodified lines | ||
| 296 | 296 | { |
| 297 | 297 | void __iomem *ioaddr = hw->pcsr; |
| 298 | 298 | unsigned int pmt = 0; |
| 299 | + u32 config; | |
| 299 | 300 | |
| 300 | 301 | if (mode & WAKE_MAGIC) { |
| 301 | 302 | pr_debug("GMAC: WOL Magic frame\n"); |
| @@ -306,6 +307,12 @@ static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode) · 4 unmodified lines | ||
| 306 | 307 | pmt |= power_down | global_unicast | wake_up_frame_en; |
| 307 | 308 | } |
| 308 | 309 | |
| 310 | + if (pmt) { | |
| 311 | + /* The receiver must be enabled for WOL before powering down */ | |
| 312 | + config = readl(ioaddr + GMAC_CONFIG); | |
| 313 | + config |= GMAC_CONFIG_RE; | |
| 314 | + writel(config, ioaddr + GMAC_CONFIG); | |
| 315 | + } | |
| 309 | 316 | writel(pmt, ioaddr + GMAC_PMT); |
| 310 | 317 | } |
| 311 | 318 | |
| @@ -315,6 +315,7 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, · 314 unmodified lines | ||
| 315 | 315 | { .compatible = "allwinner,sun8i-h3-emac" }, |
| 316 | 316 | { .compatible = "allwinner,sun8i-v3s-emac" }, |
| 317 | 317 | { .compatible = "allwinner,sun50i-a64-emac" }, |
| 318 | + {}, | |
| 318 | 319 | }; |
| 319 | 320 | |
| 320 | 321 | /* If phy-handle property is passed from DT, use it as the PHY */ |
| @@ -150,6 +150,8 @@ struct netvsc_device_info { · 149 unmodified lines | ||
| 150 | 150 | u32 num_chn; |
| 151 | 151 | u32 send_sections; |
| 152 | 152 | u32 recv_sections; |
| 153 | + u32 send_section_size; | |
| 154 | + u32 recv_section_size; | |
| 153 | 155 | }; |
| 154 | 156 | |
| 155 | 157 | enum rndis_device_state { |
| @@ -76,9 +76,6 @@ static struct netvsc_device *alloc_net_device(void) · 75 unmodified lines | ||
| 76 | 76 | net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT; |
| 77 | 77 | net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT; |
| 78 | 78 | |
| 79 | − net_device->recv_section_size = NETVSC_RECV_SECTION_SIZE; | |
| 80 | − net_device->send_section_size = NETVSC_SEND_SECTION_SIZE; | |
| 81 | − | |
| 82 | 79 | init_completion(&net_device->channel_init_wait); |
| 83 | 80 | init_waitqueue_head(&net_device->subchan_open); |
| 84 | 81 | INIT_WORK(&net_device->subchan_work, rndis_set_subchannel); |
| @@ -262,7 +259,7 @@ static int netvsc_init_buf(struct hv_device *device, · 177 unmodified lines | ||
| 262 | 259 | int ret = 0; |
| 263 | 260 | |
| 264 | 261 | /* Get receive buffer area. */ |
| 265 | − buf_size = device_info->recv_sections * net_device->recv_section_size; | |
| 262 | + buf_size = device_info->recv_sections * device_info->recv_section_size; | |
| 266 | 263 | buf_size = roundup(buf_size, PAGE_SIZE); |
| 267 | 264 | |
| 268 | 265 | net_device->recv_buf = vzalloc(buf_size); |
| @@ -344,7 +341,7 @@ static int netvsc_init_buf(struct hv_device *device, · 75 unmodified lines | ||
| 344 | 341 | goto cleanup; |
| 345 | 342 | |
| 346 | 343 | /* Now setup the send buffer. */ |
| 347 | − buf_size = device_info->send_sections * net_device->send_section_size; | |
| 344 | + buf_size = device_info->send_sections * device_info->send_section_size; | |
| 348 | 345 | buf_size = round_up(buf_size, PAGE_SIZE); |
| 349 | 346 | |
| 350 | 347 | net_device->send_buf = vzalloc(buf_size); |
| @@ -848,7 +848,9 @@ static int netvsc_set_channels(struct net_device *net, · 847 unmodified lines | ||
| 848 | 848 | device_info.num_chn = count; |
| 849 | 849 | device_info.ring_size = ring_size; |
| 850 | 850 | device_info.send_sections = nvdev->send_section_cnt; |
| 851 | + device_info.send_section_size = nvdev->send_section_size; | |
| 851 | 852 | device_info.recv_sections = nvdev->recv_section_cnt; |
| 853 | + device_info.recv_section_size = nvdev->recv_section_size; | |
| 852 | 854 | |
| 853 | 855 | rndis_filter_device_remove(dev, nvdev); |
| 854 | 856 | |
| @@ -963,7 +965,9 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) · 108 unmodified lines | ||
| 963 | 965 | device_info.ring_size = ring_size; |
| 964 | 966 | device_info.num_chn = nvdev->num_chn; |
| 965 | 967 | device_info.send_sections = nvdev->send_section_cnt; |
| 968 | + device_info.send_section_size = nvdev->send_section_size; | |
| 966 | 969 | device_info.recv_sections = nvdev->recv_section_cnt; |
| 970 | + device_info.recv_section_size = nvdev->recv_section_size; | |
| 967 | 971 | |
| 968 | 972 | rndis_filter_device_remove(hdev, nvdev); |
| 969 | 973 | |
| @@ -1485,7 +1489,9 @@ static int netvsc_set_ringparam(struct net_device *ndev, · 515 unmodified lines | ||
| 1485 | 1489 | device_info.num_chn = nvdev->num_chn; |
| 1486 | 1490 | device_info.ring_size = ring_size; |
| 1487 | 1491 | device_info.send_sections = new_tx; |
| 1492 | + device_info.send_section_size = nvdev->send_section_size; | |
| 1488 | 1493 | device_info.recv_sections = new_rx; |
| 1494 | + device_info.recv_section_size = nvdev->recv_section_size; | |
| 1489 | 1495 | |
| 1490 | 1496 | netif_device_detach(ndev); |
| 1491 | 1497 | was_opened = rndis_filter_opened(nvdev); |
| @@ -1934,7 +1940,9 @@ static int netvsc_probe(struct hv_device *dev, · 442 unmodified lines | ||
| 1934 | 1940 | device_info.ring_size = ring_size; |
| 1935 | 1941 | device_info.num_chn = VRSS_CHANNEL_DEFAULT; |
| 1936 | 1942 | device_info.send_sections = NETVSC_DEFAULT_TX; |
| 1943 | + device_info.send_section_size = NETVSC_SEND_SECTION_SIZE; | |
| 1937 | 1944 | device_info.recv_sections = NETVSC_DEFAULT_RX; |
| 1945 | + device_info.recv_section_size = NETVSC_RECV_SECTION_SIZE; | |
| 1938 | 1946 | |
| 1939 | 1947 | nvdev = rndis_filter_device_add(dev, &device_info); |
| 1940 | 1948 | if (IS_ERR(nvdev)) { |
| @@ -160,15 +160,6 @@ config MDIO_XGENE · 159 unmodified lines | ||
| 160 | 160 | |
| 161 | 161 | endif |
| 162 | 162 | |
| 163 | −menuconfig PHYLIB | |
| 164 | − tristate "PHY Device support and infrastructure" | |
| 165 | − depends on NETDEVICES | |
| 166 | − select MDIO_DEVICE | |
| 167 | − help | |
| 168 | − Ethernet controllers are usually attached to PHY | |
| 169 | − devices. This option provides infrastructure for | |
| 170 | − managing PHY devices. | |
| 171 | − | |
| 172 | 163 | config PHYLINK |
| 173 | 164 | tristate |
| 174 | 165 | depends on NETDEVICES |
| @@ -179,6 +170,15 @@ config PHYLINK · 4 unmodified lines | ||
| 179 | 170 | configuration links, PHYs, and Serdes links with MAC level |
| 180 | 171 | autonegotiation modes. |
| 181 | 172 | |
| 173 | +menuconfig PHYLIB | |
| 174 | + tristate "PHY Device support and infrastructure" | |
| 175 | + depends on NETDEVICES | |
| 176 | + select MDIO_DEVICE | |
| 177 | + help | |
| 178 | + Ethernet controllers are usually attached to PHY | |
| 179 | + devices. This option provides infrastructure for | |
| 180 | + managing PHY devices. | |
| 181 | + | |
| 182 | 182 | if PHYLIB |
| 183 | 183 | |
| 184 | 184 | config SWPHY |
| @@ -373,7 +373,8 @@ void phy_ethtool_ksettings_get(struct phy_device *phydev, · 372 unmodified lines | ||
| 373 | 373 | cmd->base.port = PORT_BNC; |
| 374 | 374 | else |
| 375 | 375 | cmd->base.port = PORT_MII; |
| 376 | − | |
| 376 | + cmd->base.transceiver = phy_is_internal(phydev) ? | |
| 377 | + XCVR_INTERNAL : XCVR_EXTERNAL; | |
| 377 | 378 | cmd->base.phy_address = phydev->mdio.addr; |
| 378 | 379 | cmd->base.autoneg = phydev->autoneg; |
| 379 | 380 | cmd->base.eth_tp_mdix_ctrl = phydev->mdix_ctrl; |
| @@ -879,7 +879,7 @@ void phy_attached_print(struct phy_device *phydev, const char *fmt, ...) · 878 unmodified lines | ||
| 879 | 879 | { |
| 880 | 880 | const char *drv_name = phydev->drv ? phydev->drv->name : "unbound"; |
| 881 | 881 | char *irq_str; |
| 882 | − char irq_num[4]; | |
| 882 | + char irq_num[8]; | |
| 883 | 883 | |
| 884 | 884 | switch(phydev->irq) { |
| 885 | 885 | case PHY_POLL: |
| @@ -44,7 +44,7 @@ static int xgmiitorgmii_read_status(struct phy_device *phydev) · 43 unmodified lines | ||
| 44 | 44 | priv->phy_drv->read_status(phydev); |
| 45 | 45 | |
| 46 | 46 | val = mdiobus_read(phydev->mdio.bus, priv->addr, XILINX_GMII2RGMII_REG); |
| 47 | − val &= XILINX_GMII2RGMII_SPEED_MASK; | |
| 47 | + val &= ~XILINX_GMII2RGMII_SPEED_MASK; | |
| 48 | 48 | |
| 49 | 49 | if (phydev->speed == SPEED_1000) |
| 50 | 50 | val |= BMCR_SPEED1000; |
| @@ -120,7 +120,7 @@ struct ppp { · 119 unmodified lines | ||
| 120 | 120 | int n_channels; /* how many channels are attached 54 */ |
| 121 | 121 | spinlock_t rlock; /* lock for receive side 58 */ |
| 122 | 122 | spinlock_t wlock; /* lock for transmit side 5c */ |
| 123 | − int *xmit_recursion __percpu; /* xmit recursion detect */ | |
| 123 | + int __percpu *xmit_recursion; /* xmit recursion detect */ | |
| 124 | 124 | int mru; /* max receive unit 60 */ |
| 125 | 125 | unsigned int flags; /* control bits 64 */ |
| 126 | 126 | unsigned int xstate; /* transmit state bits 68 */ |
| @@ -1496,11 +1496,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, · 1495 unmodified lines | ||
| 1496 | 1496 | switch (tun->flags & TUN_TYPE_MASK) { |
| 1497 | 1497 | case IFF_TUN: |
| 1498 | 1498 | if (tun->flags & IFF_NO_PI) { |
| 1499 | − switch (skb->data[0] & 0xf0) { | |
| 1500 | − case 0x40: | |
| 1499 | + u8 ip_version = skb->len ? (skb->data[0] >> 4) : 0; | |
| 1500 | + | |
| 1501 | + switch (ip_version) { | |
| 1502 | + case 4: | |
| 1501 | 1503 | pi.proto = htons(ETH_P_IP); |
| 1502 | 1504 | break; |
| 1503 | − case 0x60: | |
| 1505 | + case 6: | |
| 1504 | 1506 | pi.proto = htons(ETH_P_IPV6); |
| 1505 | 1507 | break; |
| 1506 | 1508 | default: |
| @@ -54,11 +54,19 @@ static int is_wireless_rndis(struct usb_interface_descriptor *desc) · 53 unmodified lines | ||
| 54 | 54 | desc->bInterfaceProtocol == 3); |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | +static int is_novatel_rndis(struct usb_interface_descriptor *desc) | |
| 58 | +{ | |
| 59 | + return (desc->bInterfaceClass == USB_CLASS_MISC && | |
| 60 | + desc->bInterfaceSubClass == 4 && | |
| 61 | + desc->bInterfaceProtocol == 1); | |
| 62 | +} | |
| 63 | + | |
| 57 | 64 | #else |
| 58 | 65 | |
| 59 | 66 | #define is_rndis(desc) 0 |
| 60 | 67 | #define is_activesync(desc) 0 |
| 61 | 68 | #define is_wireless_rndis(desc) 0 |
| 69 | +#define is_novatel_rndis(desc) 0 | |
| 62 | 70 | |
| 63 | 71 | #endif |
| 64 | 72 | |
| @@ -150,7 +158,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) · 85 unmodified lines | ||
| 150 | 158 | */ |
| 151 | 159 | rndis = (is_rndis(&intf->cur_altsetting->desc) || |
| 152 | 160 | is_activesync(&intf->cur_altsetting->desc) || |
| 153 | − is_wireless_rndis(&intf->cur_altsetting->desc)); | |
| 161 | + is_wireless_rndis(&intf->cur_altsetting->desc) || | |
| 162 | + is_novatel_rndis(&intf->cur_altsetting->desc)); | |
| 154 | 163 | |
| 155 | 164 | memset(info, 0, sizeof(*info)); |
| 156 | 165 | info->control = intf; |
| @@ -547,6 +556,7 @@ static const struct driver_info wwan_info = { · 390 unmodified lines | ||
| 547 | 556 | #define REALTEK_VENDOR_ID 0x0bda |
| 548 | 557 | #define SAMSUNG_VENDOR_ID 0x04e8 |
| 549 | 558 | #define LENOVO_VENDOR_ID 0x17ef |
| 559 | +#define LINKSYS_VENDOR_ID 0x13b1 | |
| 550 | 560 | #define NVIDIA_VENDOR_ID 0x0955 |
| 551 | 561 | #define HP_VENDOR_ID 0x03f0 |
| 552 | 562 | #define MICROSOFT_VENDOR_ID 0x045e |
| @@ -737,6 +747,15 @@ static const struct usb_device_id products[] = { · 184 unmodified lines | ||
| 737 | 747 | .driver_info = 0, |
| 738 | 748 | }, |
| 739 | 749 | |
| 750 | +#if IS_ENABLED(CONFIG_USB_RTL8152) | |
| 751 | +/* Linksys USB3GIGV1 Ethernet Adapter */ | |
| 752 | +{ | |
| 753 | + USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM, | |
| 754 | + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | |
| 755 | + .driver_info = 0, | |
| 756 | +}, | |
| 757 | +#endif | |
| 758 | + | |
| 740 | 759 | /* ThinkPad USB-C Dock (based on Realtek RTL8153) */ |
| 741 | 760 | { |
| 742 | 761 | USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM, |
| @@ -1265,30 +1265,45 @@ static int lan78xx_ethtool_get_eeprom(struct net_device *netdev, · 1264 unmodified lines | ||
| 1265 | 1265 | struct ethtool_eeprom *ee, u8 *data) |
| 1266 | 1266 | { |
| 1267 | 1267 | struct lan78xx_net *dev = netdev_priv(netdev); |
| 1268 | + int ret; | |
| 1269 | + | |
| 1270 | + ret = usb_autopm_get_interface(dev->intf); | |
| 1271 | + if (ret) | |
| 1272 | + return ret; | |
| 1268 | 1273 | |
| 1269 | 1274 | ee->magic = LAN78XX_EEPROM_MAGIC; |
| 1270 | 1275 | |
| 1271 | − return lan78xx_read_raw_eeprom(dev, ee->offset, ee->len, data); | |
| 1276 | + ret = lan78xx_read_raw_eeprom(dev, ee->offset, ee->len, data); | |
| 1277 | + | |
| 1278 | + usb_autopm_put_interface(dev->intf); | |
| 1279 | + | |
| 1280 | + return ret; | |
| 1272 | 1281 | } |
| 1273 | 1282 | |
| 1274 | 1283 | static int lan78xx_ethtool_set_eeprom(struct net_device *netdev, |
| 1275 | 1284 | struct ethtool_eeprom *ee, u8 *data) |
| 1276 | 1285 | { |
| 1277 | 1286 | struct lan78xx_net *dev = netdev_priv(netdev); |
| 1287 | + int ret; | |
| 1288 | + | |
| 1289 | + ret = usb_autopm_get_interface(dev->intf); | |
| 1290 | + if (ret) | |
| 1291 | + return ret; | |
| 1278 | 1292 | |
| 1279 | − /* Allow entire eeprom update only */ | |
| 1280 | − if ((ee->magic == LAN78XX_EEPROM_MAGIC) && | |
| 1281 | − (ee->offset == 0) && | |
| 1282 | − (ee->len == 512) && | |
| 1283 | − (data[0] == EEPROM_INDICATOR)) | |
| 1284 | − return lan78xx_write_raw_eeprom(dev, ee->offset, ee->len, data); | |
| 1293 | + /* Invalid EEPROM_INDICATOR at offset zero will result in a failure | |
| 1294 | + * to load data from EEPROM | |
| 1295 | + */ | |
| 1296 | + if (ee->magic == LAN78XX_EEPROM_MAGIC) | |
| 1297 | + ret = lan78xx_write_raw_eeprom(dev, ee->offset, ee->len, data); | |
| 1285 | 1298 | else if ((ee->magic == LAN78XX_OTP_MAGIC) && |
| 1286 | 1299 | (ee->offset == 0) && |
| 1287 | 1300 | (ee->len == 512) && |
| 1288 | 1301 | (data[0] == OTP_INDICATOR_1)) |
| 1289 | − return lan78xx_write_raw_otp(dev, ee->offset, ee->len, data); | |
| 1302 | + ret = lan78xx_write_raw_otp(dev, ee->offset, ee->len, data); | |
| 1303 | + | |
| 1304 | + usb_autopm_put_interface(dev->intf); | |
| 1290 | 1305 | |
| 1291 | − return -EINVAL; | |
| 1306 | + return ret; | |
| 1292 | 1307 | } |
| 1293 | 1308 | |
| 1294 | 1309 | static void lan78xx_get_strings(struct net_device *netdev, u32 stringset, |
| @@ -2434,7 +2449,6 @@ static int lan78xx_reset(struct lan78xx_net *dev) · 1139 unmodified lines | ||
| 2434 | 2449 | /* LAN7801 only has RGMII mode */ |
| 2435 | 2450 | if (dev->chipid == ID_REV_CHIP_ID_7801_) |
| 2436 | 2451 | buf &= ~MAC_CR_GMII_EN_; |
| 2437 | − buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; | |
| 2438 | 2452 | ret = lan78xx_write_reg(dev, MAC_CR, buf); |
| 2439 | 2453 | |
| 2440 | 2454 | ret = lan78xx_read_reg(dev, MAC_TX, &buf); |
| @@ -613,6 +613,7 @@ enum rtl8152_flags { · 612 unmodified lines | ||
| 613 | 613 | #define VENDOR_ID_MICROSOFT 0x045e |
| 614 | 614 | #define VENDOR_ID_SAMSUNG 0x04e8 |
| 615 | 615 | #define VENDOR_ID_LENOVO 0x17ef |
| 616 | +#define VENDOR_ID_LINKSYS 0x13b1 | |
| 616 | 617 | #define VENDOR_ID_NVIDIA 0x0955 |
| 617 | 618 | |
| 618 | 619 | #define MCU_TYPE_PLA 0x0100 |
| @@ -5316,6 +5317,7 @@ static const struct usb_device_id rtl8152_table[] = { · 4697 unmodified lines | ||
| 5316 | 5317 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, |
| 5317 | 5318 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, |
| 5318 | 5319 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, |
| 5320 | + {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, | |
| 5319 | 5321 | {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, |
| 5320 | 5322 | {} |
| 5321 | 5323 | }; |
| @@ -632,6 +632,10 @@ static const struct usb_device_id products [] = { · 631 unmodified lines | ||
| 632 | 632 | /* RNDIS for tethering */ |
| 633 | 633 | USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), |
| 634 | 634 | .driver_info = (unsigned long) &rndis_info, |
| 635 | +}, { | |
| 636 | + /* Novatel Verizon USB730L */ | |
| 637 | + USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1), | |
| 638 | + .driver_info = (unsigned long) &rndis_info, | |
| 635 | 639 | }, |
| 636 | 640 | { }, // END |
| 637 | 641 | }; |
| @@ -3396,9 +3396,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev) · 3395 unmodified lines | ||
| 3396 | 3396 | |
| 3397 | 3397 | MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); |
| 3398 | 3398 | |
| 3399 | −#ifdef CONFIG_PM | |
| 3400 | − | |
| 3401 | −static int ath10k_pci_pm_suspend(struct device *dev) | |
| 3399 | +static __maybe_unused int ath10k_pci_pm_suspend(struct device *dev) | |
| 3402 | 3400 | { |
| 3403 | 3401 | struct ath10k *ar = dev_get_drvdata(dev); |
| 3404 | 3402 | int ret; |
| @@ -3414,7 +3412,7 @@ static int ath10k_pci_pm_suspend(struct device *dev) · 9 unmodified lines | ||
| 3414 | 3412 | return ret; |
| 3415 | 3413 | } |
| 3416 | 3414 | |
| 3417 | −static int ath10k_pci_pm_resume(struct device *dev) | |
| 3415 | +static __maybe_unused int ath10k_pci_pm_resume(struct device *dev) | |
| 3418 | 3416 | { |
| 3419 | 3417 | struct ath10k *ar = dev_get_drvdata(dev); |
| 3420 | 3418 | int ret; |
| @@ -3433,7 +3431,6 @@ static int ath10k_pci_pm_resume(struct device *dev) · 12 unmodified lines | ||
| 3433 | 3431 | static SIMPLE_DEV_PM_OPS(ath10k_pci_pm_ops, |
| 3434 | 3432 | ath10k_pci_pm_suspend, |
| 3435 | 3433 | ath10k_pci_pm_resume); |
| 3436 | −#endif | |
| 3437 | 3434 | |
| 3438 | 3435 | static struct pci_driver ath10k_pci_driver = { |
| 3439 | 3436 | .name = "ath10k_pci", |
| @@ -980,7 +980,7 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, · 979 unmodified lines | ||
| 980 | 980 | |
| 981 | 981 | eth_broadcast_addr(params_le->bssid); |
| 982 | 982 | params_le->bss_type = DOT11_BSSTYPE_ANY; |
| 983 | − params_le->scan_type = 0; | |
| 983 | + params_le->scan_type = BRCMF_SCANTYPE_ACTIVE; | |
| 984 | 984 | params_le->channel_num = 0; |
| 985 | 985 | params_le->nprobes = cpu_to_le32(-1); |
| 986 | 986 | params_le->active_time = cpu_to_le32(-1); |
| @@ -988,12 +988,9 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, · 1 unmodified line | ||
| 988 | 988 | params_le->home_time = cpu_to_le32(-1); |
| 989 | 989 | memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le)); |
| 990 | 990 | |
| 991 | − /* if request is null exit so it will be all channel broadcast scan */ | |
| 992 | − if (!request) | |
| 993 | − return; | |
| 994 | − | |
| 995 | 991 | n_ssids = request->n_ssids; |
| 996 | 992 | n_channels = request->n_channels; |
| 993 | + | |
| 997 | 994 | /* Copy channel array if applicable */ |
| 998 | 995 | brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n", |
| 999 | 996 | n_channels); |
| @@ -1030,16 +1027,8 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, · 30 unmodified lines | ||
| 1030 | 1027 | ptr += sizeof(ssid_le); |
| 1031 | 1028 | } |
| 1032 | 1029 | } else { |
| 1033 | − brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids); | |
| 1034 | − if ((request->ssids) && request->ssids->ssid_len) { | |
| 1035 | − brcmf_dbg(SCAN, "SSID %s len=%d\n", | |
| 1036 | − params_le->ssid_le.SSID, | |
| 1037 | − request->ssids->ssid_len); | |
| 1038 | − params_le->ssid_le.SSID_len = | |
| 1039 | − cpu_to_le32(request->ssids->ssid_len); | |
| 1040 | − memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid, | |
| 1041 | − request->ssids->ssid_len); | |
| 1042 | − } | |
| 1030 | + brcmf_dbg(SCAN, "Performing passive scan\n"); | |
| 1031 | + params_le->scan_type = BRCMF_SCANTYPE_PASSIVE; | |
| 1043 | 1032 | } |
| 1044 | 1033 | /* Adding mask to channel numbers */ |
| 1045 | 1034 | params_le->channel_num = |
| @@ -3162,6 +3151,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, · 2116 unmodified lines | ||
| 3162 | 3151 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |
| 3163 | 3152 | s32 status; |
| 3164 | 3153 | struct brcmf_escan_result_le *escan_result_le; |
| 3154 | + u32 escan_buflen; | |
| 3165 | 3155 | struct brcmf_bss_info_le *bss_info_le; |
| 3166 | 3156 | struct brcmf_bss_info_le *bss = NULL; |
| 3167 | 3157 | u32 bi_length; |
| @@ -3181,11 +3171,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, · 13 unmodified lines | ||
| 3181 | 3171 | |
| 3182 | 3172 | if (status == BRCMF_E_STATUS_PARTIAL) { |
| 3183 | 3173 | brcmf_dbg(SCAN, "ESCAN Partial result\n"); |
| 3174 | + if (e->datalen < sizeof(*escan_result_le)) { | |
| 3175 | + brcmf_err("invalid event data length\n"); | |
| 3176 | + goto exit; | |
| 3177 | + } | |
| 3184 | 3178 | escan_result_le = (struct brcmf_escan_result_le *) data; |
| 3185 | 3179 | if (!escan_result_le) { |
| 3186 | 3180 | brcmf_err("Invalid escan result (NULL pointer)\n"); |
| 3187 | 3181 | goto exit; |
| 3188 | 3182 | } |
| 3183 | + escan_buflen = le32_to_cpu(escan_result_le->buflen); | |
| 3184 | + if (escan_buflen > BRCMF_ESCAN_BUF_SIZE || | |
| 3185 | + escan_buflen > e->datalen || | |
| 3186 | + escan_buflen < sizeof(*escan_result_le)) { | |
| 3187 | + brcmf_err("Invalid escan buffer length: %d\n", | |
| 3188 | + escan_buflen); | |
| 3189 | + goto exit; | |
| 3190 | + } | |
| 3189 | 3191 | if (le16_to_cpu(escan_result_le->bss_count) != 1) { |
| 3190 | 3192 | brcmf_err("Invalid bss_count %d: ignoring\n", |
| 3191 | 3193 | escan_result_le->bss_count); |
| @@ -3202,9 +3204,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, · 10 unmodified lines | ||
| 3202 | 3204 | } |
| 3203 | 3205 | |
| 3204 | 3206 | bi_length = le32_to_cpu(bss_info_le->length); |
| 3205 | − if (bi_length != (le32_to_cpu(escan_result_le->buflen) - | |
| 3206 | − WL_ESCAN_RESULTS_FIXED_SIZE)) { | |
| 3207 | − brcmf_err("Invalid bss_info length %d: ignoring\n", | |
| 3207 | + if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { | |
| 3208 | + brcmf_err("Ignoring invalid bss_info length: %d\n", | |
| 3208 | 3209 | bi_length); |
| 3209 | 3210 | goto exit; |
| 3210 | 3211 | } |
| @@ -45,6 +45,11 @@ · 44 unmodified lines | ||
| 45 | 45 | #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff |
| 46 | 46 | #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 |
| 47 | 47 | |
| 48 | +/* scan type definitions */ | |
| 49 | +#define BRCMF_SCANTYPE_DEFAULT 0xFF | |
| 50 | +#define BRCMF_SCANTYPE_ACTIVE 0 | |
| 51 | +#define BRCMF_SCANTYPE_PASSIVE 1 | |
| 52 | + | |
| 48 | 53 | #define BRCMF_WSEC_MAX_PSK_LEN 32 |
| 49 | 54 | #define BRCMF_WSEC_PASSPHRASE BIT(0) |
| 50 | 55 | |
| @@ -2167,7 +2167,7 @@ out: · 2166 unmodified lines | ||
| 2167 | 2167 | * 1. We are not using a unified image |
| 2168 | 2168 | * 2. We are using a unified image but had an error while exiting D3 |
| 2169 | 2169 | */ |
| 2170 | − set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); | |
| 2170 | + set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); | |
| 2171 | 2171 | set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status); |
| 2172 | 2172 | /* |
| 2173 | 2173 | * When switching images we return 1, which causes mac80211 |
| @@ -1546,6 +1546,11 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, · 1545 unmodified lines | ||
| 1546 | 1546 | struct iwl_mvm_mc_iter_data *data = _data; |
| 1547 | 1547 | struct iwl_mvm *mvm = data->mvm; |
| 1548 | 1548 | struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd; |
| 1549 | + struct iwl_host_cmd hcmd = { | |
| 1550 | + .id = MCAST_FILTER_CMD, | |
| 1551 | + .flags = CMD_ASYNC, | |
| 1552 | + .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | |
| 1553 | + }; | |
| 1549 | 1554 | int ret, len; |
| 1550 | 1555 | |
| 1551 | 1556 | /* if we don't have free ports, mcast frames will be dropped */ |
| @@ -1560,7 +1565,10 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, · 8 unmodified lines | ||
| 1560 | 1565 | memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); |
| 1561 | 1566 | len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); |
| 1562 | 1567 | |
| 1563 | − ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd); | |
| 1568 | + hcmd.len[0] = len; | |
| 1569 | + hcmd.data[0] = cmd; | |
| 1570 | + | |
| 1571 | + ret = iwl_mvm_send_cmd(mvm, &hcmd); | |
| 1564 | 1572 | if (ret) |
| 1565 | 1573 | IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret); |
| 1566 | 1574 | } |
| @@ -1635,6 +1643,12 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw, · 68 unmodified lines | ||
| 1635 | 1643 | if (!cmd) |
| 1636 | 1644 | goto out; |
| 1637 | 1645 | |
| 1646 | + if (changed_flags & FIF_ALLMULTI) | |
| 1647 | + cmd->pass_all = !!(*total_flags & FIF_ALLMULTI); | |
| 1648 | + | |
| 1649 | + if (cmd->pass_all) | |
| 1650 | + cmd->count = 0; | |
| 1651 | + | |
| 1638 | 1652 | iwl_mvm_recalc_multicast(mvm); |
| 1639 | 1653 | out: |
| 1640 | 1654 | mutex_unlock(&mvm->mutex); |
| @@ -2563,7 +2577,7 @@ static void iwl_mvm_purge_deferred_tx_frames(struct iwl_mvm *mvm, · 922 unmodified lines | ||
| 2563 | 2577 | * queues, so we should never get a second deferred |
| 2564 | 2578 | * frame for the RA/TID. |
| 2565 | 2579 | */ |
| 2566 | − iwl_mvm_start_mac_queues(mvm, info->hw_queue); | |
| 2580 | + iwl_mvm_start_mac_queues(mvm, BIT(info->hw_queue)); | |
| 2567 | 2581 | ieee80211_free_txskb(mvm->hw, skb); |
| 2568 | 2582 | } |
| 2569 | 2583 | } |
| @@ -3975,6 +3989,43 @@ out_unlock: · 1405 unmodified lines | ||
| 3975 | 3989 | return ret; |
| 3976 | 3990 | } |
| 3977 | 3991 | |
| 3992 | +static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop) | |
| 3993 | +{ | |
| 3994 | + if (drop) { | |
| 3995 | + if (iwl_mvm_has_new_tx_api(mvm)) | |
| 3996 | + /* TODO new tx api */ | |
| 3997 | + WARN_ONCE(1, | |
| 3998 | + "Need to implement flush TX queue\n"); | |
| 3999 | + else | |
| 4000 | + iwl_mvm_flush_tx_path(mvm, | |
| 4001 | + iwl_mvm_flushable_queues(mvm) & queues, | |
| 4002 | + 0); | |
| 4003 | + } else { | |
| 4004 | + if (iwl_mvm_has_new_tx_api(mvm)) { | |
| 4005 | + struct ieee80211_sta *sta; | |
| 4006 | + int i; | |
| 4007 | + | |
| 4008 | + mutex_lock(&mvm->mutex); | |
| 4009 | + | |
| 4010 | + for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) { | |
| 4011 | + sta = rcu_dereference_protected( | |
| 4012 | + mvm->fw_id_to_mac_id[i], | |
| 4013 | + lockdep_is_held(&mvm->mutex)); | |
| 4014 | + if (IS_ERR_OR_NULL(sta)) | |
| 4015 | + continue; | |
| 4016 | + | |
| 4017 | + iwl_mvm_wait_sta_queues_empty(mvm, | |
| 4018 | + iwl_mvm_sta_from_mac80211(sta)); | |
| 4019 | + } | |
| 4020 | + | |
| 4021 | + mutex_unlock(&mvm->mutex); | |
| 4022 | + } else { | |
| 4023 | + iwl_trans_wait_tx_queues_empty(mvm->trans, | |
| 4024 | + queues); | |
| 4025 | + } | |
| 4026 | + } | |
| 4027 | +} | |
| 4028 | + | |
| 3978 | 4029 | static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, |
| 3979 | 4030 | struct ieee80211_vif *vif, u32 queues, bool drop) |
| 3980 | 4031 | { |
| @@ -3985,7 +4036,12 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, · 4 unmodified lines | ||
| 3985 | 4036 | int i; |
| 3986 | 4037 | u32 msk = 0; |
| 3987 | 4038 | |
| 3988 | − if (!vif || vif->type != NL80211_IFTYPE_STATION) | |
| 4039 | + if (!vif) { | |
| 4040 | + iwl_mvm_flush_no_vif(mvm, queues, drop); | |
| 4041 | + return; | |
| 4042 | + } | |
| 4043 | + | |
| 4044 | + if (vif->type != NL80211_IFTYPE_STATION) | |
| 3989 | 4045 | return; |
| 3990 | 4046 | |
| 3991 | 4047 | /* Make sure we're done with the deferred traffic before flushing */ |
| @@ -661,7 +661,8 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, · 660 unmodified lines | ||
| 661 | 661 | (lq_sta->tx_agg_tid_en & BIT(tid)) && |
| 662 | 662 | (tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) { |
| 663 | 663 | IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid); |
| 664 | − rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta); | |
| 664 | + if (rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta) == 0) | |
| 665 | + tid_data->state = IWL_AGG_QUEUED; | |
| 665 | 666 | } |
| 666 | 667 | } |
| 667 | 668 | |
| @@ -672,11 +672,12 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, · 671 unmodified lines | ||
| 672 | 672 | * If there was a significant jump in the nssn - adjust. |
| 673 | 673 | * If the SN is smaller than the NSSN it might need to first go into |
| 674 | 674 | * the reorder buffer, in which case we just release up to it and the |
| 675 | − * rest of the function will take of storing it and releasing up to the | |
| 676 | − * nssn | |
| 675 | + * rest of the function will take care of storing it and releasing up to | |
| 676 | + * the nssn | |
| 677 | 677 | */ |
| 678 | 678 | if (!iwl_mvm_is_sn_less(nssn, buffer->head_sn + buffer->buf_size, |
| 679 | − buffer->buf_size)) { | |
| 679 | + buffer->buf_size) || | |
| 680 | + !ieee80211_sn_less(sn, buffer->head_sn + buffer->buf_size)) { | |
| 680 | 681 | u16 min_sn = ieee80211_sn_less(sn, nssn) ? sn : nssn; |
| 681 | 682 | |
| 682 | 683 | iwl_mvm_release_frames(mvm, sta, napi, buffer, min_sn); |
| @@ -555,7 +555,7 @@ static int iwl_mvm_lmac_scan_abort(struct iwl_mvm *mvm) · 554 unmodified lines | ||
| 555 | 555 | struct iwl_host_cmd cmd = { |
| 556 | 556 | .id = SCAN_OFFLOAD_ABORT_CMD, |
| 557 | 557 | }; |
| 558 | − u32 status; | |
| 558 | + u32 status = CAN_ABORT_STATUS; | |
| 559 | 559 | |
| 560 | 560 | ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); |
| 561 | 561 | if (ret) |
| @@ -1285,7 +1285,7 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm, · 1284 unmodified lines | ||
| 1285 | 1285 | { |
| 1286 | 1286 | struct iwl_mvm_add_sta_cmd cmd; |
| 1287 | 1287 | int ret; |
| 1288 | − u32 status; | |
| 1288 | + u32 status = ADD_STA_SUCCESS; | |
| 1289 | 1289 | |
| 1290 | 1290 | lockdep_assert_held(&mvm->mutex); |
| 1291 | 1291 | |
| @@ -2385,8 +2385,10 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, · 1093 unmodified lines | ||
| 2385 | 2385 | if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) |
| 2386 | 2386 | return -EINVAL; |
| 2387 | 2387 | |
| 2388 | − if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) { | |
| 2389 | − IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n", | |
| 2388 | + if (mvmsta->tid_data[tid].state != IWL_AGG_QUEUED && | |
| 2389 | + mvmsta->tid_data[tid].state != IWL_AGG_OFF) { | |
| 2390 | + IWL_ERR(mvm, | |
| 2391 | + "Start AGG when state is not IWL_AGG_QUEUED or IWL_AGG_OFF %d!\n", | |
| 2390 | 2392 | mvmsta->tid_data[tid].state); |
| 2391 | 2393 | return -ENXIO; |
| 2392 | 2394 | } |
| @@ -281,6 +281,7 @@ struct iwl_mvm_vif; · 280 unmodified lines | ||
| 281 | 281 | * These states relate to a specific RA / TID. |
| 282 | 282 | * |
| 283 | 283 | * @IWL_AGG_OFF: aggregation is not used |
| 284 | + * @IWL_AGG_QUEUED: aggregation start work has been queued | |
| 284 | 285 | * @IWL_AGG_STARTING: aggregation are starting (between start and oper) |
| 285 | 286 | * @IWL_AGG_ON: aggregation session is up |
| 286 | 287 | * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the |
| @@ -290,6 +291,7 @@ struct iwl_mvm_vif; · 3 unmodified lines | ||
| 290 | 291 | */ |
| 291 | 292 | enum iwl_mvm_agg_state { |
| 292 | 293 | IWL_AGG_OFF = 0, |
| 294 | + IWL_AGG_QUEUED, | |
| 293 | 295 | IWL_AGG_STARTING, |
| 294 | 296 | IWL_AGG_ON, |
| 295 | 297 | IWL_EMPTYING_HW_QUEUE_ADDBA, |
| @@ -529,6 +529,7 @@ int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state) · 528 unmodified lines | ||
| 529 | 529 | |
| 530 | 530 | lockdep_assert_held(&mvm->mutex); |
| 531 | 531 | |
| 532 | + status = 0; | |
| 532 | 533 | ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP, |
| 533 | 534 | CTDP_CONFIG_CMD), |
| 534 | 535 | sizeof(cmd), &cmd, &status); |
| @@ -564,8 +564,8 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, · 563 unmodified lines | ||
| 564 | 564 | case NL80211_IFTYPE_AP: |
| 565 | 565 | case NL80211_IFTYPE_ADHOC: |
| 566 | 566 | /* |
| 567 | − * Handle legacy hostapd as well, where station will be added | |
| 568 | − * only just before sending the association response. | |
| 567 | + * Non-bufferable frames use the broadcast station, thus they | |
| 568 | + * use the probe queue. | |
| 569 | 569 | * Also take care of the case where we send a deauth to a |
| 570 | 570 | * station that we don't have, or similarly an association |
| 571 | 571 | * response (with non-success status) for a station we can't |
| @@ -573,9 +573,9 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, · 1 unmodified line | ||
| 573 | 573 | * Also, disassociate frames might happen, particular with |
| 574 | 574 | * reason 7 ("Class 3 frame received from nonassociated STA"). |
| 575 | 575 | */ |
| 576 | − if (ieee80211_is_probe_resp(fc) || ieee80211_is_auth(fc) || | |
| 577 | − ieee80211_is_deauth(fc) || ieee80211_is_assoc_resp(fc) || | |
| 578 | − ieee80211_is_disassoc(fc)) | |
| 576 | + if (ieee80211_is_mgmt(fc) && | |
| 577 | + (!ieee80211_is_bufferable_mmpdu(fc) || | |
| 578 | + ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc))) | |
| 579 | 579 | return mvm->probe_queue; |
| 580 | 580 | if (info->hw_queue == info->control.vif->cab_queue) |
| 581 | 581 | return mvmvif->cab_queue; |
| @@ -115,6 +115,8 @@ int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) · 114 unmodified lines | ||
| 115 | 115 | |
| 116 | 116 | vif = qtnf_netdev_get_priv(wdev->netdev); |
| 117 | 117 | |
| 118 | + qtnf_scan_done(vif->mac, true); | |
| 119 | + | |
| 118 | 120 | if (qtnf_cmd_send_del_intf(vif)) |
| 119 | 121 | pr_err("VIF%u.%u: failed to delete VIF\n", vif->mac->macid, |
| 120 | 122 | vif->vifid); |
| @@ -335,6 +337,8 @@ static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev) · 214 unmodified lines | ||
| 335 | 337 | struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); |
| 336 | 338 | int ret; |
| 337 | 339 | |
| 340 | + qtnf_scan_done(vif->mac, true); | |
| 341 | + | |
| 338 | 342 | ret = qtnf_cmd_send_stop_ap(vif); |
| 339 | 343 | if (ret) { |
| 340 | 344 | pr_err("VIF%u.%u: failed to stop AP operation in FW\n", |
| @@ -570,8 +574,6 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device *dev, · 229 unmodified lines | ||
| 570 | 574 | !qtnf_sta_list_lookup(&vif->sta_list, params->mac)) |
| 571 | 575 | return 0; |
| 572 | 576 | |
| 573 | − qtnf_scan_done(vif->mac, true); | |
| 574 | − | |
| 575 | 577 | ret = qtnf_cmd_send_del_sta(vif, params); |
| 576 | 578 | if (ret) |
| 577 | 579 | pr_err("VIF%u.%u: failed to delete STA %pM\n", |
| @@ -1134,8 +1136,9 @@ void qtnf_virtual_intf_cleanup(struct net_device *ndev) · 556 unmodified lines | ||
| 1134 | 1136 | } |
| 1135 | 1137 | |
| 1136 | 1138 | vif->sta_state = QTNF_STA_DISCONNECTED; |
| 1137 | − qtnf_scan_done(mac, true); | |
| 1138 | 1139 | } |
| 1140 | + | |
| 1141 | + qtnf_scan_done(mac, true); | |
| 1139 | 1142 | } |
| 1140 | 1143 | |
| 1141 | 1144 | void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif) |
| @@ -34,6 +34,9 @@ static inline void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted) · 33 unmodified lines | ||
| 34 | 34 | .aborted = aborted, |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | + if (timer_pending(&mac->scan_timeout)) | |
| 38 | + del_timer_sync(&mac->scan_timeout); | |
| 39 | + | |
| 37 | 40 | mutex_lock(&mac->mac_lock); |
| 38 | 41 | |
| 39 | 42 | if (mac->scan_req) { |
| @@ -345,8 +345,6 @@ qtnf_event_handle_scan_complete(struct qtnf_wmac *mac, · 344 unmodified lines | ||
| 345 | 345 | return -EINVAL; |
| 346 | 346 | } |
| 347 | 347 | |
| 348 | − if (timer_pending(&mac->scan_timeout)) | |
| 349 | − del_timer_sync(&mac->scan_timeout); | |
| 350 | 348 | qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED); |
| 351 | 349 | |
| 352 | 350 | return 0; |
| @@ -661,14 +661,18 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) · 660 unmodified lines | ||
| 661 | 661 | struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); |
| 662 | 662 | dma_addr_t txbd_paddr, skb_paddr; |
| 663 | 663 | struct qtnf_tx_bd *txbd; |
| 664 | + unsigned long flags; | |
| 664 | 665 | int len, i; |
| 665 | 666 | u32 info; |
| 666 | 667 | int ret = 0; |
| 667 | 668 | |
| 669 | + spin_lock_irqsave(&priv->tx0_lock, flags); | |
| 670 | + | |
| 668 | 671 | if (!qtnf_tx_queue_ready(priv)) { |
| 669 | 672 | if (skb->dev) |
| 670 | 673 | netif_stop_queue(skb->dev); |
| 671 | 674 | |
| 675 | + spin_unlock_irqrestore(&priv->tx0_lock, flags); | |
| 672 | 676 | return NETDEV_TX_BUSY; |
| 673 | 677 | } |
| 674 | 678 | |
| @@ -717,8 +721,10 @@ tx_done: · 42 unmodified lines | ||
| 717 | 721 | dev_kfree_skb_any(skb); |
| 718 | 722 | } |
| 719 | 723 | |
| 720 | − qtnf_pcie_data_tx_reclaim(priv); | |
| 721 | 724 | priv->tx_done_count++; |
| 725 | + spin_unlock_irqrestore(&priv->tx0_lock, flags); | |
| 726 | + | |
| 727 | + qtnf_pcie_data_tx_reclaim(priv); | |
| 722 | 728 | |
| 723 | 729 | return NETDEV_TX_OK; |
| 724 | 730 | } |
| @@ -1247,6 +1253,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 522 unmodified lines | ||
| 1247 | 1253 | strcpy(bus->fwname, QTN_PCI_PEARL_FW_NAME); |
| 1248 | 1254 | init_completion(&bus->request_firmware_complete); |
| 1249 | 1255 | mutex_init(&bus->bus_lock); |
| 1256 | + spin_lock_init(&pcie_priv->tx0_lock); | |
| 1250 | 1257 | spin_lock_init(&pcie_priv->irq_lock); |
| 1251 | 1258 | spin_lock_init(&pcie_priv->tx_reclaim_lock); |
| 1252 | 1259 | |
| @@ -34,6 +34,8 @@ struct qtnf_pcie_bus_priv { · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | /* lock for tx reclaim operations */ |
| 36 | 36 | spinlock_t tx_reclaim_lock; |
| 37 | + /* lock for tx0 operations */ | |
| 38 | + spinlock_t tx0_lock; | |
| 37 | 39 | u8 msi_enabled; |
| 38 | 40 | int mps; |
| 39 | 41 | |
| @@ -1417,6 +1417,15 @@ static int btt_claim_class(struct device *dev) · 1416 unmodified lines | ||
| 1417 | 1417 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); |
| 1418 | 1418 | struct nd_namespace_index *nsindex; |
| 1419 | 1419 | |
| 1420 | + /* | |
| 1421 | + * If any of the DIMMs do not support labels the only | |
| 1422 | + * possible BTT format is v1. | |
| 1423 | + */ | |
| 1424 | + if (!ndd) { | |
| 1425 | + loop_bitmask = 0; | |
| 1426 | + break; | |
| 1427 | + } | |
| 1428 | + | |
| 1420 | 1429 | nsindex = to_namespace_index(ndd, ndd->ns_current); |
| 1421 | 1430 | if (nsindex == NULL) |
| 1422 | 1431 | loop_bitmask |= 1; |
| @@ -134,8 +134,6 @@ static inline bool nvme_req_needs_retry(struct request *req) · 133 unmodified lines | ||
| 134 | 134 | return false; |
| 135 | 135 | if (nvme_req(req)->status & NVME_SC_DNR) |
| 136 | 136 | return false; |
| 137 | − if (jiffies - req->start_time >= req->timeout) | |
| 138 | − return false; | |
| 139 | 137 | if (nvme_req(req)->retries >= nvme_max_retries) |
| 140 | 138 | return false; |
| 141 | 139 | return true; |
| @@ -2138,7 +2136,7 @@ static umode_t nvme_ns_attrs_are_visible(struct kobject *kobj, · 1996 unmodified lines | ||
| 2138 | 2136 | struct nvme_ns *ns = nvme_get_ns_from_dev(dev); |
| 2139 | 2137 | |
| 2140 | 2138 | if (a == &dev_attr_uuid.attr) { |
| 2141 | − if (uuid_is_null(&ns->uuid) || | |
| 2139 | + if (uuid_is_null(&ns->uuid) && | |
| 2142 | 2140 | !memchr_inv(ns->nguid, 0, sizeof(ns->nguid))) |
| 2143 | 2141 | return 0; |
| 2144 | 2142 | } |
| @@ -2590,7 +2588,7 @@ static void nvme_async_event_work(struct work_struct *work) · 445 unmodified lines | ||
| 2590 | 2588 | container_of(work, struct nvme_ctrl, async_event_work); |
| 2591 | 2589 | |
| 2592 | 2590 | spin_lock_irq(&ctrl->lock); |
| 2593 | − while (ctrl->event_limit > 0) { | |
| 2591 | + while (ctrl->state == NVME_CTRL_LIVE && ctrl->event_limit > 0) { | |
| 2594 | 2592 | int aer_idx = --ctrl->event_limit; |
| 2595 | 2593 | |
| 2596 | 2594 | spin_unlock_irq(&ctrl->lock); |
| @@ -2677,7 +2675,8 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, · 80 unmodified lines | ||
| 2677 | 2675 | /*FALLTHRU*/ |
| 2678 | 2676 | case NVME_SC_ABORT_REQ: |
| 2679 | 2677 | ++ctrl->event_limit; |
| 2680 | − queue_work(nvme_wq, &ctrl->async_event_work); | |
| 2678 | + if (ctrl->state == NVME_CTRL_LIVE) | |
| 2679 | + queue_work(nvme_wq, &ctrl->async_event_work); | |
| 2681 | 2680 | break; |
| 2682 | 2681 | default: |
| 2683 | 2682 | break; |
| @@ -2692,7 +2691,7 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, · 8 unmodified lines | ||
| 2692 | 2691 | nvme_queue_scan(ctrl); |
| 2693 | 2692 | break; |
| 2694 | 2693 | case NVME_AER_NOTICE_FW_ACT_STARTING: |
| 2695 | − schedule_work(&ctrl->fw_act_work); | |
| 2694 | + queue_work(nvme_wq, &ctrl->fw_act_work); | |
| 2696 | 2695 | break; |
| 2697 | 2696 | default: |
| 2698 | 2697 | dev_warn(ctrl->device, "async event result %08x\n", result); |
| @@ -565,6 +565,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 564 unmodified lines | ||
| 565 | 565 | opts->queue_size = NVMF_DEF_QUEUE_SIZE; |
| 566 | 566 | opts->nr_io_queues = num_online_cpus(); |
| 567 | 567 | opts->reconnect_delay = NVMF_DEF_RECONNECT_DELAY; |
| 568 | + opts->kato = NVME_DEFAULT_KATO; | |
| 568 | 569 | |
| 569 | 570 | options = o = kstrdup(buf, GFP_KERNEL); |
| 570 | 571 | if (!options) |
| @@ -655,21 +656,22 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 84 unmodified lines | ||
| 655 | 656 | goto out; |
| 656 | 657 | } |
| 657 | 658 | |
| 658 | − if (opts->discovery_nqn) { | |
| 659 | − pr_err("Discovery controllers cannot accept keep_alive_tmo != 0\n"); | |
| 660 | − ret = -EINVAL; | |
| 661 | − goto out; | |
| 662 | − } | |
| 663 | − | |
| 664 | 659 | if (token < 0) { |
| 665 | 660 | pr_err("Invalid keep_alive_tmo %d\n", token); |
| 666 | 661 | ret = -EINVAL; |
| 667 | 662 | goto out; |
| 668 | − } else if (token == 0) { | |
| 663 | + } else if (token == 0 && !opts->discovery_nqn) { | |
| 669 | 664 | /* Allowed for debug */ |
| 670 | 665 | pr_warn("keep_alive_tmo 0 won't execute keep alives!!!\n"); |
| 671 | 666 | } |
| 672 | 667 | opts->kato = token; |
| 668 | + | |
| 669 | + if (opts->discovery_nqn && opts->kato) { | |
| 670 | + pr_err("Discovery controllers cannot accept KATO != 0\n"); | |
| 671 | + ret = -EINVAL; | |
| 672 | + goto out; | |
| 673 | + } | |
| 674 | + | |
| 673 | 675 | break; |
| 674 | 676 | case NVMF_OPT_CTRL_LOSS_TMO: |
| 675 | 677 | if (match_int(args, &token)) { |
| @@ -762,8 +764,6 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 86 unmodified lines | ||
| 762 | 764 | uuid_copy(&opts->host->id, &hostid); |
| 763 | 765 | |
| 764 | 766 | out: |
| 765 | − if (!opts->discovery_nqn && !opts->kato) | |
| 766 | − opts->kato = NVME_DEFAULT_KATO; | |
| 767 | 767 | kfree(options); |
| 768 | 768 | return ret; |
| 769 | 769 | } |
| @@ -1376,7 +1376,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) · 1375 unmodified lines | ||
| 1376 | 1376 | if (atomic_read(&op->state) == FCPOP_STATE_ABORTED) |
| 1377 | 1377 | status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1); |
| 1378 | 1378 | else if (freq->status) |
| 1379 | − status = cpu_to_le16(NVME_SC_FC_TRANSPORT_ERROR << 1); | |
| 1379 | + status = cpu_to_le16(NVME_SC_INTERNAL << 1); | |
| 1380 | 1380 | |
| 1381 | 1381 | /* |
| 1382 | 1382 | * For the linux implementation, if we have an unsuccesful |
| @@ -1404,7 +1404,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) · 21 unmodified lines | ||
| 1404 | 1404 | */ |
| 1405 | 1405 | if (freq->transferred_length != |
| 1406 | 1406 | be32_to_cpu(op->cmd_iu.data_len)) { |
| 1407 | − status = cpu_to_le16(NVME_SC_FC_TRANSPORT_ERROR << 1); | |
| 1407 | + status = cpu_to_le16(NVME_SC_INTERNAL << 1); | |
| 1408 | 1408 | goto done; |
| 1409 | 1409 | } |
| 1410 | 1410 | result.u64 = 0; |
| @@ -1421,7 +1421,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) · 10 unmodified lines | ||
| 1421 | 1421 | freq->transferred_length || |
| 1422 | 1422 | op->rsp_iu.status_code || |
| 1423 | 1423 | sqe->common.command_id != cqe->command_id)) { |
| 1424 | − status = cpu_to_le16(NVME_SC_FC_TRANSPORT_ERROR << 1); | |
| 1424 | + status = cpu_to_le16(NVME_SC_INTERNAL << 1); | |
| 1425 | 1425 | goto done; |
| 1426 | 1426 | } |
| 1427 | 1427 | result = cqe->result; |
| @@ -1429,7 +1429,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) · 1 unmodified line | ||
| 1429 | 1429 | break; |
| 1430 | 1430 | |
| 1431 | 1431 | default: |
| 1432 | − status = cpu_to_le16(NVME_SC_FC_TRANSPORT_ERROR << 1); | |
| 1432 | + status = cpu_to_le16(NVME_SC_INTERNAL << 1); | |
| 1433 | 1433 | goto done; |
| 1434 | 1434 | } |
| 1435 | 1435 | |
| @@ -1989,16 +1989,17 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, · 553 unmodified lines | ||
| 1989 | 1989 | * as well as those by FC-NVME spec. |
| 1990 | 1990 | */ |
| 1991 | 1991 | WARN_ON_ONCE(sqe->common.metadata); |
| 1992 | − WARN_ON_ONCE(sqe->common.dptr.prp1); | |
| 1993 | − WARN_ON_ONCE(sqe->common.dptr.prp2); | |
| 1994 | 1992 | sqe->common.flags |= NVME_CMD_SGL_METABUF; |
| 1995 | 1993 | |
| 1996 | 1994 | /* |
| 1997 | − * format SQE DPTR field per FC-NVME rules | |
| 1998 | − * type=data block descr; subtype=offset; | |
| 1999 | − * offset is currently 0. | |
| 1995 | + * format SQE DPTR field per FC-NVME rules: | |
| 1996 | + * type=0x5 Transport SGL Data Block Descriptor | |
| 1997 | + * subtype=0xA Transport-specific value | |
| 1998 | + * address=0 | |
| 1999 | + * length=length of the data series | |
| 2000 | 2000 | */ |
| 2001 | − sqe->rw.dptr.sgl.type = NVME_SGL_FMT_OFFSET; | |
| 2001 | + sqe->rw.dptr.sgl.type = (NVME_TRANSPORT_SGL_DATA_DESC << 4) | | |
| 2002 | + NVME_SGL_FMT_TRANSPORT_A; | |
| 2002 | 2003 | sqe->rw.dptr.sgl.length = cpu_to_le32(data_len); |
| 2003 | 2004 | sqe->rw.dptr.sgl.addr = 0; |
| 2004 | 2005 | |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <linux/mm.h> |
| 25 | 25 | #include <linux/module.h> |
| 26 | 26 | #include <linux/mutex.h> |
| 27 | +#include <linux/once.h> | |
| 27 | 28 | #include <linux/pci.h> |
| 28 | 29 | #include <linux/poison.h> |
| 29 | 30 | #include <linux/t10-pi.h> |
| @@ -93,7 +94,7 @@ struct nvme_dev { · 63 unmodified lines | ||
| 93 | 94 | struct mutex shutdown_lock; |
| 94 | 95 | bool subsystem; |
| 95 | 96 | void __iomem *cmb; |
| 96 | − dma_addr_t cmb_dma_addr; | |
| 97 | + pci_bus_addr_t cmb_bus_addr; | |
| 97 | 98 | u64 cmb_size; |
| 98 | 99 | u32 cmbsz; |
| 99 | 100 | u32 cmbloc; |
| @@ -540,6 +541,20 @@ static void nvme_dif_complete(u32 p, u32 v, struct t10_pi_tuple *pi) · 440 unmodified lines | ||
| 540 | 541 | } |
| 541 | 542 | #endif |
| 542 | 543 | |
| 544 | +static void nvme_print_sgl(struct scatterlist *sgl, int nents) | |
| 545 | +{ | |
| 546 | + int i; | |
| 547 | + struct scatterlist *sg; | |
| 548 | + | |
| 549 | + for_each_sg(sgl, sg, nents, i) { | |
| 550 | + dma_addr_t phys = sg_phys(sg); | |
| 551 | + pr_warn("sg[%d] phys_addr:%pad offset:%d length:%d " | |
| 552 | + "dma_address:%pad dma_length:%d\n", | |
| 553 | + i, &phys, sg->offset, sg->length, &sg_dma_address(sg), | |
| 554 | + sg_dma_len(sg)); | |
| 555 | + } | |
| 556 | +} | |
| 557 | + | |
| 543 | 558 | static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req) |
| 544 | 559 | { |
| 545 | 560 | struct nvme_iod *iod = blk_mq_rq_to_pdu(req); |
| @@ -622,19 +637,10 @@ static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req) · 76 unmodified lines | ||
| 622 | 637 | return BLK_STS_OK; |
| 623 | 638 | |
| 624 | 639 | bad_sgl: |
| 625 | − if (WARN_ONCE(1, "Invalid SGL for payload:%d nents:%d\n", | |
| 626 | − blk_rq_payload_bytes(req), iod->nents)) { | |
| 627 | − for_each_sg(iod->sg, sg, iod->nents, i) { | |
| 628 | − dma_addr_t phys = sg_phys(sg); | |
| 629 | − pr_warn("sg[%d] phys_addr:%pad offset:%d length:%d " | |
| 630 | − "dma_address:%pad dma_length:%d\n", i, &phys, | |
| 631 | − sg->offset, sg->length, | |
| 632 | − &sg_dma_address(sg), | |
| 633 | − sg_dma_len(sg)); | |
| 634 | − } | |
| 635 | − } | |
| 640 | + WARN(DO_ONCE(nvme_print_sgl, iod->sg, iod->nents), | |
| 641 | + "Invalid SGL for payload:%d nents:%d\n", | |
| 642 | + blk_rq_payload_bytes(req), iod->nents); | |
| 636 | 643 | return BLK_STS_IOERR; |
| 637 | − | |
| 638 | 644 | } |
| 639 | 645 | |
| 640 | 646 | static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, |
| @@ -1220,7 +1226,7 @@ static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq, · 579 unmodified lines | ||
| 1220 | 1226 | if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz)) { |
| 1221 | 1227 | unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth), |
| 1222 | 1228 | dev->ctrl.page_size); |
| 1223 | − nvmeq->sq_dma_addr = dev->cmb_dma_addr + offset; | |
| 1229 | + nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset; | |
| 1224 | 1230 | nvmeq->sq_cmds_io = dev->cmb + offset; |
| 1225 | 1231 | } else { |
| 1226 | 1232 | nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), |
| @@ -1313,11 +1319,11 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) · 86 unmodified lines | ||
| 1313 | 1319 | if (result < 0) |
| 1314 | 1320 | goto release_cq; |
| 1315 | 1321 | |
| 1322 | + nvme_init_queue(nvmeq, qid); | |
| 1316 | 1323 | result = queue_request_irq(nvmeq); |
| 1317 | 1324 | if (result < 0) |
| 1318 | 1325 | goto release_sq; |
| 1319 | 1326 | |
| 1320 | − nvme_init_queue(nvmeq, qid); | |
| 1321 | 1327 | return result; |
| 1322 | 1328 | |
| 1323 | 1329 | release_sq: |
| @@ -1464,6 +1470,7 @@ static int nvme_pci_configure_admin_queue(struct nvme_dev *dev) · 140 unmodified lines | ||
| 1464 | 1470 | return result; |
| 1465 | 1471 | |
| 1466 | 1472 | nvmeq->cq_vector = 0; |
| 1473 | + nvme_init_queue(nvmeq, 0); | |
| 1467 | 1474 | result = queue_request_irq(nvmeq); |
| 1468 | 1475 | if (result) { |
| 1469 | 1476 | nvmeq->cq_vector = -1; |
| @@ -1520,7 +1527,7 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev) · 50 unmodified lines | ||
| 1520 | 1527 | resource_size_t bar_size; |
| 1521 | 1528 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
| 1522 | 1529 | void __iomem *cmb; |
| 1523 | − dma_addr_t dma_addr; | |
| 1530 | + int bar; | |
| 1524 | 1531 | |
| 1525 | 1532 | dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ); |
| 1526 | 1533 | if (!(NVME_CMB_SZ(dev->cmbsz))) |
| @@ -1533,7 +1540,8 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev) · 6 unmodified lines | ||
| 1533 | 1540 | szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz)); |
| 1534 | 1541 | size = szu * NVME_CMB_SZ(dev->cmbsz); |
| 1535 | 1542 | offset = szu * NVME_CMB_OFST(dev->cmbloc); |
| 1536 | − bar_size = pci_resource_len(pdev, NVME_CMB_BIR(dev->cmbloc)); | |
| 1543 | + bar = NVME_CMB_BIR(dev->cmbloc); | |
| 1544 | + bar_size = pci_resource_len(pdev, bar); | |
| 1537 | 1545 | |
| 1538 | 1546 | if (offset > bar_size) |
| 1539 | 1547 | return NULL; |
| @@ -1546,12 +1554,11 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev) · 6 unmodified lines | ||
| 1546 | 1554 | if (size > bar_size - offset) |
| 1547 | 1555 | size = bar_size - offset; |
| 1548 | 1556 | |
| 1549 | − dma_addr = pci_resource_start(pdev, NVME_CMB_BIR(dev->cmbloc)) + offset; | |
| 1550 | − cmb = ioremap_wc(dma_addr, size); | |
| 1557 | + cmb = ioremap_wc(pci_resource_start(pdev, bar) + offset, size); | |
| 1551 | 1558 | if (!cmb) |
| 1552 | 1559 | return NULL; |
| 1553 | 1560 | |
| 1554 | − dev->cmb_dma_addr = dma_addr; | |
| 1561 | + dev->cmb_bus_addr = pci_bus_address(pdev, bar) + offset; | |
| 1555 | 1562 | dev->cmb_size = size; |
| 1556 | 1563 | return cmb; |
| 1557 | 1564 | } |
| @@ -2156,7 +2163,6 @@ static void nvme_reset_work(struct work_struct *work) · 598 unmodified lines | ||
| 2156 | 2163 | if (result) |
| 2157 | 2164 | goto out; |
| 2158 | 2165 | |
| 2159 | − nvme_init_queue(dev->queues[0], 0); | |
| 2160 | 2166 | result = nvme_alloc_admin_tags(dev); |
| 2161 | 2167 | if (result) |
| 2162 | 2168 | goto out; |
| @@ -942,7 +942,12 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work) · 941 unmodified lines | ||
| 942 | 942 | } |
| 943 | 943 | |
| 944 | 944 | changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); |
| 945 | − WARN_ON_ONCE(!changed); | |
| 945 | + if (!changed) { | |
| 946 | + /* state change failure is ok if we're in DELETING state */ | |
| 947 | + WARN_ON_ONCE(ctrl->ctrl.state != NVME_CTRL_DELETING); | |
| 948 | + return; | |
| 949 | + } | |
| 950 | + | |
| 946 | 951 | ctrl->ctrl.nr_reconnects = 0; |
| 947 | 952 | |
| 948 | 953 | nvme_start_ctrl(&ctrl->ctrl); |
| @@ -962,7 +967,7 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work) · 13 unmodified lines | ||
| 962 | 967 | struct nvme_rdma_ctrl *ctrl = container_of(work, |
| 963 | 968 | struct nvme_rdma_ctrl, err_work); |
| 964 | 969 | |
| 965 | − nvme_stop_ctrl(&ctrl->ctrl); | |
| 970 | + nvme_stop_keep_alive(&ctrl->ctrl); | |
| 966 | 971 | |
| 967 | 972 | if (ctrl->ctrl.queue_count > 1) { |
| 968 | 973 | nvme_stop_queues(&ctrl->ctrl); |
| @@ -390,10 +390,10 @@ static void __nvmet_req_complete(struct nvmet_req *req, u16 status) · 389 unmodified lines | ||
| 390 | 390 | if (status) |
| 391 | 391 | nvmet_set_status(req, status); |
| 392 | 392 | |
| 393 | − /* XXX: need to fill in something useful for sq_head */ | |
| 394 | − req->rsp->sq_head = 0; | |
| 395 | − if (likely(req->sq)) /* may happen during early failure */ | |
| 396 | − req->rsp->sq_id = cpu_to_le16(req->sq->qid); | |
| 393 | + if (req->sq->size) | |
| 394 | + req->sq->sqhd = (req->sq->sqhd + 1) % req->sq->size; | |
| 395 | + req->rsp->sq_head = cpu_to_le16(req->sq->sqhd); | |
| 396 | + req->rsp->sq_id = cpu_to_le16(req->sq->qid); | |
| 397 | 397 | req->rsp->command_id = req->cmd->common.command_id; |
| 398 | 398 | |
9 more lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 27 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 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 190 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 85 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 61 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 55 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 82 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 28 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 23 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 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 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 280 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 828 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 513 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 43 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 49 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 887 lines aren’t shown here.
This diff is large: its 241 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 60 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 30 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 45 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 9 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 53 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 44 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 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 55 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 235 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 518 lines aren’t shown here.
This diff is large: its 697 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 259 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 277 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
File mode changed from 100644 to 100755.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 897 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.